愿为科技 Java开发工程师 一面

1. Java中深拷贝与浅拷贝的本质区别?如何通过序列化实现深拷贝?

思路

先明确“引用拷贝”和“对象拷贝”的核心差异,再讲序列化深拷贝的原理和步骤。

回答示例

本质区别

维度

浅拷贝

深拷贝

核心逻辑

仅拷贝对象本身,引用类型字段仍指向原对象

拷贝对象及所有引用类型字段的底层对象

数据独立性

引用字段修改会影响原对象

所有字段修改与原对象完全隔离

实现方式

重写clone()(实现Cloneable)

序列化/反序列化、递归拷贝引用字段

序列化实现深拷贝

核心原理:将对象转为字节流(序列化),再从字节流重建对象(反序列化),重建的对象是全新实例,所有引用字段也会重新创建。

public static <T> T deepCopy(T obj) throws Exception {
    // 序列化
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    ObjectOutputStream oos = new ObjectOutputStream(bos);
    oos.writeObject(obj);
    
    // 反序列化
    ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
    ObjectInputStream ois = new ObjectInputStream(bis);
    return (T) ois.readObject();
}

前提:对象及所有引用字段必须实现Serializable接口。

2. ArrayList与Vector在扩容策略和线程安全机制上的差异?

思路

分“扩容”和“线程安全”两个维度对比,突出Vector的“同步方法”和ArrayList的“手动加锁”差异。

回答示例

1. 扩容策略差异

维度

ArrayList

Vector

默认初始容量

10(JDK8懒加载,首次add初始化)

10(创建时直接初始化)

扩容公式

新容量 = 旧容量 + (旧容量 >> 1)(1.5倍)

新容量 = 旧容量 × 2(默认,可指定扩容增量)

扩容触发

add时size == elementData.length

同ArrayList,但扩容倍数更高

2. 线程安全机制差异

  • Vector:所有核心方法(add/get/remove)加synchronized修饰,是方法级全局锁,线程安全但并发效率低;
  • ArrayList:无任何同步机制,线程不安全;需手动通过Collections.synchronizedList()包装(底层也是加全局锁),或使用CopyOnWriteArrayList

核心总结:Vector是“低效的线程安全”,ArrayList是“高效的线程不安全”。

3. TreeMap插入元素时,如何通过compareTo()维持红黑树有序性?

思路

围绕“比较-插入-平衡”的核心流程,解释compareTo()在节点定位和冲突处理中的作用。

回答示例

TreeMap底层是红黑树(有序的平衡二叉树),依赖Comparable接口的compareTo()维持有序性,核心流程:

  1. 节点定位
  2. 插入节点:找到空位置后插入新节点,标记为红色;
  3. 红黑树平衡:插入后若违反红黑树规则(如连续红节点),触发旋转/变色,保证树的有序性和平衡性。

补充:若key未实现Comparable,需在TreeMap构造时传入Comparator,替代compareTo()完成比较。

4. HashMap执行put()时,计算桶位置的核心公式是什么?

思路

区分JDK1.7和1.8的公式差异,突出1.8对哈希值的优化(减少碰撞)。

回答示例

核心公式(JDK1.8)

桶位置 = (数组长度 - 1) & (key的hash值)

完整哈希计算逻辑:

  1. 计算key的hashCode()(记为h);
  2. 对h做扰动处理:hash = h ^ (h >>> 16)(将高16位与低16位异或,减少哈希碰撞);
  3. 计算桶位置:index = (n - 1) & hash(n为数组长度,必须是2的幂,保证&等价于取模,效率更高)。

JDK1.7差异:

  • 扰动次数更多(4次异或移位):hash = h ^ (h >>> 20) ^ (h >>> 12)
  • 桶位置公式相同,但未引入红黑树,仅用链表处理冲突。

核心优化:JDK1.8减少扰动次数,同时用红黑树优化大链表查询。

5. 线程从NEW到TERMINATED状态的完整生命周期流转?

思路

按“新建→就绪→运行→阻塞→死亡”的核心流程,明确各状态的触发条件和流转关系。

回答示例

线程的6

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

本专栏在精不在多,内容分为八股文、大厂真实面经,面试通过后将offer和面试题私发给我,可退还专栏的收益部分费用。欢迎大家共建专栏

全部评论

相关推荐

评论
点赞
1
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务