# 有哪些HashMap面試專題
## 目錄
1. [HashMap核心原理](#1-hashmap核心原理)
2. [哈希沖突解決](#2-哈希沖突解決)
3. [擴容機制](#3-擴容機制)
4. [線程安全問題](#4-線程安全問題)
5. [JDK8優化](#5-jdk8優化)
6. [常見面試題](#6-常見面試題)
7. [性能調優](#7-性能調優)
---
## 1. HashMap核心原理
### 1.1 數據結構
HashMap采用 **數組+鏈表+紅黑樹**(JDK8+)的復合結構:
- **數組(桶數組)**:存儲鏈表頭節點或紅黑樹根節點
- **鏈表**:解決哈希沖突(拉鏈法)
- **紅黑樹**:當鏈表長度≥8且桶數組長度≥64時轉換
```java
// JDK8中的Node定義
static class Node<K,V> implements Map.Entry<K,V> {
final int hash;
final K key;
V value;
Node<K,V> next; // 鏈表指針
}
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
^ (h >>> 16)減少哈希碰撞| 條件 | 閾值 |
|---|---|
| 鏈表轉紅黑樹 | TREEIFY_THRESHOLD=8 |
| 紅黑樹轉鏈表 | UNTREEIFY_THRESHOLD=6 |
| 最小樹化容量 | MIN_TREEIFY_CAPACITY=64 |
為什么閾值是8?
根據泊松分布,哈希沖突達到8的概率僅為0.00000006,樹化是極端情況的兜底策略
if ((e.hash & oldCap) == 0) {
// 保持原索引
} else {
// 新索引 = 原索引 + oldCap
}
| 方案 | 實現原理 | 適用場景 |
|---|---|---|
| Hashtable | 全表synchronized | 不推薦 |
| Collections.synchronizedMap | 包裝器模式 | 低并發 |
| ConcurrentHashMap | 分段鎖/CAS | 高并發 |
| 操作 | JDK7 | JDK8 |
|---|---|---|
| get | O(n)最壞 | O(logn)最壞 |
| put | 頭插法 | 尾插法 |
| 擴容 | 全量rehash | 位置預測 |
HashMap的底層數據結構?
為什么重寫equals必須重寫hashCode?
HashMap為什么線程不安全?
負載因子為什么默認0.75?
// JDK8的putVal核心邏輯
final V putVal(int hash, K key, V value, boolean onlyIfAbsent) {
// 1. 檢查桶數組是否初始化
// 2. 計算桶下標:(n-1) & hash
// 3. 處理空桶情況
// 4. 處理鏈表/紅黑樹插入
// 5. 檢查擴容閾值
}
// 預期存儲100個元素時
new HashMap<>(128); // 100/0.75=133,取2^n的128
HashMap的面試考察點集中在:
1. 數據結構設計
2. 哈希沖突解決方案
3. 擴容機制與性能優化
4. 線程安全替代方案
5. JDK版本演進差異
掌握這些核心要點,能應對90%以上的HashMap相關面試問題。 “`
注:本文實際約2800字,完整3050字版本需要補充更多代碼示例和性能測試數據。如需擴展特定章節,可提供具體方向要求。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。