Java面试题体系
一、面向对象
1. 面向过程与面向对象
- 面向过程:注重事情的每一个步骤及顺序
- 面向对象:更注重事情有哪些参与者(对象)、及各自需要做什么
- 比如:洗衣机洗衣服
- 面向过程会将任务拆解成一系列的步骤(函数)
- 面向对象会拆出人和洗衣机两个对象
- 人:打开洗衣机 放衣服 放洗衣粉
- 洗衣机:清洗 烘干
- 面向过程比较直接高效,面向对象更易于复用、扩展和维护
2. 面向对象三大特性
- 封装
- 明确标识出允许外部使用的所有成员函数和数据项
- 内部细节对外部调用透明,外部调用无需修改或者关心内部实现
- javabean的属性私有,提供getset对外访问,因为属性的赋值或者获取逻辑只能由javabean本身觉得。而不能由外部胡乱修改。
- orm 框架
- 操作数据库,不需要关心连接如何建立、sql是如何执行的,只需要引入mybatis,调方法即可
- 继承
- 继承基类的方法,并做出自己的改变和/或扩展
- 子类共性的方法或者属性直接使用父类的,而不需要自己再定义,只需扩展自己个性化的
- 多态
- 基于对象所属类的不同,外部对同一个方法的调用,实际执行的逻辑不同。
- 继承,方法重写,父类引用指向子类对象
- 父类类型 变量名 = new 子类对象;
- 无法调用子类特有的功能
二、JDK、JRE、JVM 三者区别和联系
- JDK:
- Java Development Kit
- Java开发工具
- JRE:
- Java Runtime Environnement
- Java 运行时环境
- JVM:
- Java Virtual Machine
- Java 虚拟机

三、==和equals
- ==
- 对比的是栈中的值,基本数据类型是变量值,引用类型是堆中内存对象的地址
- equals
- object中默认也是采用==比较,通常会重写

- ==必须是同一个房子,equals房子长得一样就行
四、final
1. 简述 final 作用
- 最终的
- 修饰类:表示类不可被继承
- 修饰方法:表示方法不可被子类覆盖(重写),但是可以重载
- 修饰变量:表示变量一旦被赋值就不可以更改它的值
- 修饰成员变量
- 如果final修饰的是类变量,只能在静态初始化块中指定初始值或者声明该类遍历时指定初始值
- 如果final修饰的是成员变量,可以在非静态初始化块、声明该变量或者构造器中执行初始值
- 修饰局部变量
- 系统不会为局部变量进行初始化,局部变量必须由程序员显示初始化。因此使用final修饰局部变量时,即可以在定义时指定默认值(后面的代码不能对变量再赋值),也可以不指定默认值,而在后面的代码中对final变量赋处置(仅一次)
- 修饰基本类型数据和引用类型数据
- 如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改
- 如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象。但是引用的值是可变的。
public class FinalReferenceTest {
public static void main() {
final int[] iArr = {1, 2, 3, 4};
iArr[2] = -3;
iArr = null;
final Person p = new Person(25);
p.setAge(24);
p = null;
}
}
2. 为什么局部内部类和匿名内部类只能访问局部 final 变量?
public class Test {
public static void main(String[] args) {
}
public void test(final int b) {
final int a = 10;
new Thread() {
public void run() {
System.out.println(a);
System.out.println(b);
};
}.start();
}
}
- 编译之后会生成两个class文件,Test.class,Test1.class
- 内部类和外部类是处于同一个级别的,内部类不会因为定义在方法中就会随着方法的执行完毕就被销毁。
- 这里就会产生问题:当外部类的方法结束时,局部变量就会被销毁了,但是内部类对象可能还存在(只有没有人再引用它时,才会死亡)。这里就出现了一个矛盾:内部类对象访问了一个不存在的变量。为了解决这个问题,就将局部变量复制了一份作为内部类的成员变量,这样当局部变量死亡后,内部类仍可以访问它,实际访问的是局部变量的"copy",这样就好像延长了局部变量的生命周期。
- 将局部变量复制为内部类的成员变量时,必须保证这两个变量是一样的,也就是如果我们在内部类中修改了成员变量,方法中的局部变量也得跟着改变,怎么解决问题呢?
- 就将局部变量设置为final,对它初始化后,我就不让你再去修改这个变量,就保证了内部类的成员变量和方法的局部变量的一致性。这实际上也是一种妥协。使得局部变量与内部类内建立的拷贝保持一致。