Java面试笔试高频问题详解
一、静态变量和实例变量有啥不一样
区别角度 | 静态变量 | 实例变量 |
---|
内存分配 | 类第一次加载时分配内存,位于方法区 | 对象实例化时分配内存,位于堆中 |
生存周期 | 类加载后一直存在,几乎不被垃圾回收 | 取决于对象生命周期,对象失去引用后可被垃圾回收 |
调用方式 | 使用类名直接访问(类名.静态变量名) | 需要通过对象实例访问(对象实例.实例变量名) |
所属关系 | 属于类对象,所有实例共享 | 属于具体类实例化后的对象,各对象独立拥有 |
共享方式 | 全局唯一一份,写操作会影响其他访问 | 对象独占,只有对象的持有者才可以进行实例变量的读写访问 |
访问限制 | 静态成员不能访问非静态成员 | 非静态成员可以访问静态成员 |
二、==
、equals
和 hashCode
到底有啥不同
区别角度 | == | equals | hashCode |
---|
作用 | 比较两个对象的内存地址是否相同 | 比较两个对象的值是否相同 | 返回对象的哈希码,用于哈希集合中快速定位对象 |
使用场景 | 判断两个引用是否指向同一个对象 | 判断两个对象的值是否相等 | 在哈希表中用于快速定位对象 |
相互关系 | 如果两个对象equals 相等,它们的hashCode 必须相等;反之不一定成立 | 如果两个对象equals 不相等,它们的hashCode 可能相等,也可能不等 | 如果两个对象hashCode 相等,它们的equals 不一定相等;反之一定不相等 |
三、深复制和浅复制有啥区别
区别角度 | 浅复制 | 深复制 |
---|
复制范围 | 只复制对象本身,不复制引用对象 | 完全复制对象及其引用的所有对象 |
对象关联 | 复制后的对象与原对象共享引用对象 | 复制后的对象与原对象无关联 |
实现难度 | 实现简单,Java默认提供clone() 方法 | 实现复杂,通常需要手动实现或借助工具(如JSON序列化与反序列化) |
内存占用 | 内存占用相对较小,因为共享引用对象 | 内存占用较大,因为完全复制了所有对象 |
使用场景 | 对象之间可以共享引用对象,且不需要完全独立时使用 | 需要完全独立的对象副本,且不希望对象之间有任何关联时使用 |
四、this
和 super
关键字有啥不一样
区别角度 | this | super |
---|
作用 | 代表当前实例对象 | 代表父类对象 |
访问属性/方法 | 访问本类属性或方法,若本类无则查找父类 | 直接访问父类属性或方法 |
构造方法使用 | 构造方法中调用本类其他构造器,必须位于首行 | 构造方法中调用父类构造器,必须位于首行 |
特殊用法 | 可作为方法返回值返回当前对象 | 无此类用法 |
五、Java代码执行顺序示例
class C1 {
static { System.out.println("C1A"); }
{ System.out.println("C1B"); }
public C1() { System.out.println("C1C"); }
}
class C2 extends C1 {
static { System.out.println("C2A"); }
{ System.out.println("C2B"); }
public C2() { System.out.println("C2C"); }
}
public class Main {
public static void main(String[] args) {
new C2();
}
}
执行结果:C1A C2A C1B C1C C2B C2C
六、为啥浮点型计算不精确,咋整
1. 原因
2. 解决办法
- 用
BigDecimal
来计算,它能精确到小数点后很多位。
七、Java虚拟机(JVM)是啥玩意儿
1. 类加载子系统
2. 运行时数据区
- 线程共享区:堆(存对象)和方法区(存类信息)。
- 线程私有区:虚拟机栈(存方法调用信息)、程序计数器(记录执行位置)、本地方法栈(存本地方法调用信息)。
3. 执行引擎
八、Java垃圾回收算法有啥
1. 标记-清除算法
2. 复制算法
- 把内存分成两块,用一块,回收时复制存活对象到另一块。
3. 标记-整理算法
- 标记垃圾对象,把存活对象往一边挪,清理边界外的垃圾。
九、Java内存泄露有啥场景
1. 静态集合类
2. 未释放的连接/IO
3. 不合理的变量作用域
4. 未设置过期的缓存
5. 交叉引用/循环引用
6. 单例模式