Java经典面试题(3)

1. Java 中 HashMap 的底层数据结构是什么?JDK8 之后有哪些重要改进?​

答案:​

HashMap 的底层数据结构在 JDK7 及之前是数组 + 链表,JDK8 引入了红黑树优化。具体实现:​

  • 数组(Bucket 数组):存储链表 / 红黑树的头节点,初始容量为 16(默认),必须是 2 的幂次​
  • 链表:解决哈希冲突,存储哈希值相同的键值对​
  • 红黑树(JDK8+):当链表长度超过阈值(默认 8)且数组容量≥64 时,链表转换为红黑树,将最坏查找复杂度从 O (n) 降至 O (log n)​

改进意义:​

  • 优化极端情况下(大量哈希冲突)的性能,红黑树在高频查找场景表现更优​
  • 引入树化和退化机制(当节点数≤6 时恢复链表),平衡空间与时间复杂度​

2. 哈希冲突是什么?Java 中如何解决哈希冲突?​

答案:​

哈希冲突是指不同键通过哈希函数计算出相同索引值的现象。Java 中主要通过以下方式解决:​

  1. 链地址法(Separate Chaining)​
  • HashMap/ConcurrentHashMap 的核心方案,每个数组位置维护一个链表(或红黑树)​
  • JDK8 后链表长度≥8 且容量≥64 时树化,提升冲突节点的查找效率​
  1. 开放地址法(Open Addressing)​
  • 未被 Java 集合框架采用,常见于其他哈希表实现(如线性探测、二次探测)​
  • 缺点:易产生聚集效应,导致性能下降​
  1. 哈希函数优化​
  • 通过扰动函数(如 JDK8 前的hashCode() ^ (hashCode() >>> 16))提升哈希值分布均匀性​
  • 重写hashCode()时遵循均匀散列原则(如字符串采用 31 作为乘数)​

3. 负载因子(Load Factor)的作用是什么?为什么默认值是 0.75?​

答案:​

负载因子是衡量 HashMap 满载程度的参数,计算公式:​

负载因子 = 已存储元素数 / 数组容量​

当该值超过阈值时触发扩容(扩容阈值 = 数组容量 × 负载因子)。​

默认 0.75 的原因:​

  • 性能与空间平衡:0.75 是经过大量测试的最优解,在冲突概率和空间利用率间取得平衡​
  • 若设为 1.0:空间利用率高,但哈希冲突概率大幅增加,链表长度变长​
  • 若设为 0.5:冲突概率降低,但扩容频繁,空间浪费严重​
  • 数学证明:根据 Knuth 的《计算机程序设计艺术》,负载因子 0.75 时,链地址法的查找性能接近常数时间​

4. HashMap 的 put () 方法执行流程是怎样的?(结合源码分析)​

答案:​

JDK8 中put(K key, V value)核心流程(简化版):​

  1. 计算哈希值:通过key.hashCode()和扰动函数生成哈希码h​
  1. 确定数组索引:i = (n - 1) & h(n 为数组容量,保证索引在合法范围)​
  1. 处理桶内元素:​
  • 若桶为空:直接创建 Node 节点放入​
  • 若桶为红黑树:执行树插入逻辑​
  • 若桶为链表:​
  • 遍历链表查找相同键,存在则更新值​
  • 不存在则插入链表尾部(JDK7 及之前是头部插入,可能导致逆序问题)​
  1. 链表转红黑树:若链表长度≥8 且数组容量≥64,触发树化​
  1. 扩容检查:若元素数量超过扩容阈值,执行扩容(容量翻倍,元素重新哈希)​

关键点:​

  • 扰动函数(hash()方法)的作用是让高低位字节参与运算,减少哈希冲突​
  • 索引计算使用&位运算而非取模,提升效率(要求容量为 2 的幂次)​

5. HashMap 和 Hashtable 的主要区别有哪些?​

答案:​

特性​

HashMap​

Hashtable​

线程安全​

非线程安全(适用于单线程环境)​

线程安全(通过 Synchronized 方法锁)​

null 键值支持​

允许 1 个 null 键,多个 null 值​

不允许 null 键或 null 值​

初始容量 / 负载因子​

默认 16/0.75,可自定义​

默认 11/0.75,扩容为 2n+1​

迭代器​

fail-fast 机制(遍历时修改可能抛异常)​

枚举器(Enumeration),不支持快速失败​

性能​

更高(无锁开销,JDK8 后优化显著)​

较低(方法级锁粒度粗)​

使用场景:​

  • HashMap:高性能的单线程场景(如本地缓存、临时数据存储)​
  • Hashtable:过时方案,仅建议在遗留系统中使用,新场景优先选择 ConcurrentHashMap

你可能感兴趣的:(java,开发语言)