返回随笔Java全栈
完成ENGINEERING NOTE

Java基础 面试速查表

覆盖 Java 平台无关性、JVM/JRE/JDK、对象模型、内存管理、克隆与常见基础知识的面试速查记录。

Java面试

概念


Java的特点

  1. 面向对象
  2. 平台无关性
  3. 内存管理

Java的优势和劣势是什么?

  • 优势: 跨平台、面向对象、优秀的社区生态、自动垃圾回收机制、安全性。
  • 劣势: 速度比原生语言慢、JVM对资源有限的环境不友好、面向对象过于严格。

Java为什么可以跨平台

因为由Java运行依托的JVM有不同平台的版本,Java编译生成的字节码文件可以直接在JVM上运行。

JVM、JRE、JDK区别和关系

  • JVM:Java虚拟机,负责将Java字节码翻译成机器码并运行程序。提供内存管理、垃圾回收等机制,使得Java可以跨平台。
  • JRE:Java运行时环境,包括一组类库和JVM。
  • JDK:包含了Java运行、编译的所有环境。包括类库,JVM、Java编译器(javac)和Java调试器(jbd)等等。

Java为什么解释和编译都有?

Java经过编译后生成字节码文件,再由JVM解释字节码文件运行。

数据类型


八种基本数据类型

  • 数值型:整数:byte(8)、short(16)、int(32)、long(64) 浮点型:float(32)、double(64)
  • 字符型:char(2)
  • 布尔型:boolean(无明确上限) 引用数据类型:class、interface和数组

数据类型的转换方式

  • 隐式类型转换:当目标类型大于原类型时,会自动转换,如int转换为long
  • 显式类型转换:int = (long) long
  • 字符串转换:可以将字符串转换为其他数据类型。可以使用包装类下的方法,如Integer.parseInt()
  • 数值之间的转换:可以使用包装类中的方法将字符型转换为整型。

类型转换会出现什么问题

  • 数据丢失
  • 数据溢出
  • 精度丢失
  • 类型不匹配

为什么用BigDecimal不用double

double会出现精度丢失的问题,在牵扯金钱计算的时候,都使用BigDecimal BigDecimal使用字符串创建,不能使用double创建。

装箱和拆箱是什么

基本数据类型和对应的包装类之间进行转化的过程。

  • 自动装箱发生的时间:赋值、方法调用
  • 自动装箱的弊端:在循环中进行自动装箱会创建多余的对象,影响程序的性能

为什么Java要有Integer

  • 能够将数据和处理这些数据的方法结合在一起。例如Integer可以用parseint来处理字符串转换。
  • Java中的绝大部分方法都只能处理类型,例如不能给List传入int参数。
  • Java中基本类型和引用类型不能直接转换,必须使用包装类包装才能转换。
  • 集合中只能储存包装类。

Integer缓存

在Integer类内部有一个缓存池,用来存储-128到127的数据。当用到这些数据时,会直接从内存中取出,不需要新建对象。

面向对象


怎么理解面向对象

面向对象是将现实生活中的事物抽象为对象。对象拥有属性(字段)和行为(方法) Java面向对象的三大特性:封装、继承、多态

  • 封装:只能通过对象提供的方法与外界交互。
  • 继承:继承可以使子类复用父类方法。是代码重用的重要手段。
  • 多态:可以使不同类的对象对同一操作做出反应,包括重载和重写。

多态体现在哪里

  • 方法重写
  • 方法重载
  • 接口与实现
  • 向上转型和向下转型

面向对象的六大设计原则

  • 单一职责原则
  • 开放封闭原则
  • 里氏替换原则
  • 接口隔离原则
  • 依赖倒置原则
  • 最少知识原则

重载和重写的区别

  • 重载:在一个类中,可以有多个同名的方法,它们的参数列表不同。
  • 重写:在子类中可以重写父类的方法。但是方法名、参数列表和返回类型必须和父类一致。

抽象类和普通类的区别

  • 抽象类不能被实例化。
  • 普通类必须有方法实现,抽象类可以没有。

抽象类和接口的区别

  • 抽象类可以有成员变量,构造方法和具体方法。
  • 接口只能有常量和抽象方法。 区别:
  • 一个类只能继承一个抽象类,但是可以继承多个接口
  • 接口只能有方法定义,不能有实现。抽象类可以有默认方法。
  • 接口成员变量默认为public static final,必须有初值,不能被修改。成员方法为public、abstarct的。 抽象类中的成员变量可以被重新定义。

接口中可以定义哪些方法

抽象(abstract)、默认、静态(static)、私有(private)方法。、 私有方法只能在接口内部访问,不能被实现类访问。

Java中的静态变量和静态方法

静态意味着它是和类本身关联的,而不是和类的对象关联的。它们在内存中只存在一份, 可以通过类本身调用,被类的所有实例共享。 静态方法不能访问非静态的成员变量和方法。但可以直接调用其他静态变量和静态方法。静态方法不能被重写,但可以被隐藏。

关键字


Java中final关键字的作用是什么

  • 修饰类时:这个类不能被继承
  • 修饰变量时:常量,不能修改
  • 修饰方法:不能被子类重写

深拷贝与浅拷贝


深拷贝和浅拷贝的区别

  • 浅拷贝只赋值对象中的值类型字段,对于引用字段,不会创建一个新的对象。
  • 深拷贝既赋值值类型字段,也会重新创建一个新的对象。

深拷贝的三种实现方法

  • 实现Cloneable()接口并重写clone()方法

public class ClassB implements Cloneable{ private int b; private ClassA cla;

@Override
protected Object clone() throws CloneNotSupportedException {
    ClassB clonedClass = (ClassB) super.clone();
    clonedClass.cla = (ClassA) cla.clone();
    return clonedClass;
}

}

public class ClassA implements Cloneable{ private int a;

@Override
protected Object clone() throws CloneNotSupportedException {
    return super.clone();
}

} ```

  • 使用序列化和反序列化
  • 手动递归复制

对象


Java创建对象有几种方式

  • 通过new创建
  • 通过反射机制创建 可以通过反射获取类名,然后调用newInstance()获取
  • 通过clone()方法获取
  • 通过反序列化获取

New出的对象什么时候回收

Java垃圾回收器会周期性地检测不再被引用的对象。

  • 使用计数器检测对象是否被引用。
  • 使用可达性分析算法,分析一个对象是否可达。

如何获得私有对象

  • 如果类遵循了良好的代码规范的话,可以使用getter方法获取对象。
  • 可以通过反射方法绕过private获取对象。

反射


反射机制是指在运行过程中,可以获得并调用一个类的所有字段和方法,同时可以获得他的类名、包名、父类等等。

  • 运行时类信息访问:可以在运行时获得类的类名、包名、父类等等
  • 动态对象创建:即使不知道具体类名,也可以通过Class的newInstance创建对象
  • 动态方法调用:可以调用对象的私有方法。
  • 访问和修改字段值:可以访问并修改字段值,即使是私有的。

异常


Java异常的分类

Java异常主要有两部分:Error和Exception

  • 错误Error:这是指运行环境的错误,程序不应该捕获这类错误。错误是无法处理的严重错误。
  • 异常Exception:表示程序本身可以处理的错误。
    • 非运行时异常:在编译期就应该捕获并抛出的异常,比如类不存在
    • 运行时异常:在运行期捕获的异常,如数组越界

Java的异常处理

  • 使用try-catch块处理异常。
try {
        //可能抛出异常的代码
        } catch(ExceptionType1 e) {
            //异常类型1的处理
        } catch(ExceptionType2 e) {
            //异常类型2的处理
        } catch(ExceptionType3 e) {
            //异常类型3的处理
        } finally {
            //可选的finally块,用于定义无论是否发生异常都会执行的代码
}
  • 使用throw语句手动抛出异常。
throw new Exception();
  • 使用throws关键字:如果不想在方法内部处理异常,可以使用throws关键字将异常传递给调用者处理。
public void method() throws Exception {
}
  • finally块:无论是否发生异常都会执行的代码块。

Object


==和equal有什么区别

  • 对于字符串对象,==对比的是两个变量在内存中的首地址,属于数值比较。对于非字符串对象,两者效果是相同的。
  • equals比较的内容,比较两个字符串的内容是否相等。

hashCode和equal方法有什么关系

  • 一致性:如果a.equal(b),则两个对象的hashcode一定相等。
  • 非一致性:如果两个对象的hashcode相等,a.equal(b)不一定为true。

String、StringBuffer、StringBuilder

  • String线程安全,因为每次修改都会创建一个新的对象。但是开销最大。
  • StringBuilder非线程安全。可以直接修改,不会创建新对象,适合单线程使用。性能开销最小。
  • StringBuffer线程安全,可以直接修改。性能开销比StringBuilder大,因为增加了线程安全机制。

Java8新特性


Lambda表达式

Lambda用于创建匿名函数,有两种表示方法。

  • (parameters) -> expression 表达式的值作为返回值
  • (parameters) → { statements; } 需要在statments中手动return Lambda可以使代码更加清晰明了,但是过多使用lambda会增加调试困难。

Stream API

流API提供了一种高效处理集合对象的方式,包括过滤、映射、排序等。

Stream流的并行API是什么

是ParallelStream。并行流将元数据拆分成数个小任务多线程进行流操作,操作结束之后将结果合并。底层是使用通用的fork/join池来进行的。