HashMap 面试全攻略

HashMap 面试全攻略(Java)

面试问 HashMap,本质就是在问:你到底懂不懂数据结构 + 并发 + JDK 演进

这份文档就是冲着"高级 / 资深 Java 面试"来的。


1. HashMap 是什么?

  • 基于 数组 + 链表 + 红黑树 的 Key-Value 数据结构
  • 非线程安全
  • 允许 null keynull value
  • JDK 1.8 之后:链表长度 ≥ 8 且数组长度 ≥ 64 → 链表转红黑树

2. HashMap 的核心数据结构

text 复制代码
Node<K,V>[] table

JDK 1.7

复制代码
数组 + 链表(头插法)

JDK 1.8

复制代码
数组 + 链表 + 红黑树(尾插法)

3. put() 底层流程(高频)

  1. 判断 table 是否为空 → resize
  2. 计算 hash
  3. (n - 1) & hash 定位桶位
  4. 桶为空 → 直接插入
  5. 桶不为空:
    • key 相同 → 覆盖
    • 链表 → 尾插
    • 判断是否树化
  6. 判断是否需要扩容

👉 面试金句

HashMap 的性能核心在于 hash 的均匀性 + 扩容成本控制


4. hash 为什么要高 16 位异或?

java 复制代码
hash = h ^ (h >>> 16)

原因

  • HashMap 的数组长度较小
  • 直接取低位容易冲突
  • 高低位混合,减少 hash 冲突

5. resize 扩容机制(必问)

  • 默认容量:16
  • 扩容因子:0.75
  • 扩容后容量:2 倍

JDK 1.8 的优化点

  • 不再重新 hash
  • 利用 (hash & oldCap) 判断新位置
text 复制代码
0 → 原位置
1 → 原位置 + oldCap

👉 扩容时间复杂度:O(n)


6. 为什么负载因子是 0.75?

权衡三点:

  • 空间利用率
  • 冲突概率
  • resize 成本

0.75 是 经验最优解,不是拍脑袋


7. 链表转红黑树的条件

同时满足:

  • 链表长度 ≥ 8
  • table.length ≥ 64

否则:优先扩容而不是树化

👉 这是为了避免小数组下树化带来的额外性能损耗


8. 为什么 JDK 1.7 用头插法,1.8 改成尾插?

JDK 1.7 问题

  • 扩容时可能 链表成环
  • 多线程 put → 死循环 100% CPU

JDK 1.8 改进

  • 尾插法
  • 扩容时顺序不变
  • 解决死循环问题(但依然不线程安全)

9. HashMap 为什么线程不安全?

典型问题

  1. 数据覆盖
  2. resize 并发导致数据丢失
  3. size 不准
  4. JDK 1.7 死循环

👉 面试官想听的是:结构性原因,不是"没加锁"


10. HashMap vs ConcurrentHashMap

对比点 HashMap ConcurrentHashMap
线程安全
锁粒度 CAS + synchronized
性能 略低
null key 支持 不支持

11. equals & hashCode 的关系(送分题)

规则:

  • equals 相等 → hashCode 必须相等
  • hashCode 相等 → equals 不一定相等

👉 写自定义 key 必须 重写 hashCode + equals


12. 常见面试连环追问

Q1:HashMap 查找复杂度?

  • 理想:O(1)
  • 最坏(链表):O(n)
  • 红黑树:O(log n)

Q2:为什么容量必须是 2 的幂?

  • (n - 1) & hash 等价于 % n
  • 位运算更快
  • 分布更均匀

Q3:Hash 冲突怎么解决?

  • 拉链法
  • 树化

13. 高频面试总结(直接背)

  • HashMap 本质是 空间换时间
  • JDK 1.8 的核心升级是:
    • 红黑树
    • 尾插法
    • 高效 resize
  • 面试重点永远在:
    • put / get
    • resize
    • 并发问题

14. 一句话总结(终极)

HashMap 的精髓不是 API,而是 在冲突、扩容、并发之间做工程权衡


相关推荐
2601_94986836几秒前
Flutter for OpenHarmony 电子合同签署App实战 - 数据持久化实现
java·数据库·flutter
码农阿豪6 分钟前
基于Milvus与混合检索的云厂商文档智能问答系统:Java SpringBoot全栈实现
java·spring boot·milvus
阿蒙Amon9 分钟前
C#每日面试题-Task和Thread的区别
java·面试·c#
索荣荣17 分钟前
Java异步编程终极实战指南
java·开发语言
shehuiyuelaiyuehao18 分钟前
11String类型知识点
java·开发语言
毕设源码-赖学姐18 分钟前
【开题答辩全过程】以 基于Java的图书馆座位预约管理系统设计为例,包含答辩的问题和答案
java·开发语言
zhougl99622 分钟前
Java Object.clone() 浅拷贝与深拷贝全解析
java·开发语言
余瑜鱼鱼鱼23 分钟前
线程池总结
java·开发语言
w_t_y_y27 分钟前
工具Cursor(三)MCP(3)常用的三方MCP Tools
java
what丶k28 分钟前
你应该更新的 Java 知识:Record 特性深度解析
java·开发语言