爲了可以在面試回答中優雅而不失體面回答面試考點,該文章借鑑了不一樣平臺對知識點的描述。node
HashMap 是一種存取高效但不保證有序的經常使用容器。它的數據結構爲「數組+鏈表」,是解決哈希衝突的產物,也就是咱們常說的鏈地址法。它實現了Map 接口採用K-V 鍵值對存儲數據,並實現了淺拷貝和序列化。面試
HashMap 的默認初始大小爲16,初始化大小必須爲2的冪,最大大小爲2的30次方。數組中存儲的鏈表節點Entry 類實現於Map.Entry 接口,它實現了對節點的通用操做。HashMap 的閾值默認爲「容量*0.75f」,當存儲節點數量超過該值,則對map 進行擴容處理。算法
HashMap 提供了4種構造方法,分別是默認構造方法;能夠指定初始容量的構造方法;能夠指定初始容量和閾值的構造方法以及基於一個Map 的構造方法。雖然是構造函數,可是真正的初始化都是在第一次添加操做裏面實現的。數組
在第一次添加操做中,HashMap 會先判斷存儲數組有沒有初始化,若是沒有先進行初始化操做,初始化過程當中會取比用戶指定的容量大的最近的2 的冪次方數做爲數組的初始容量,並更新擴容的閾值。安全
接着添加操做講吧。添加操做的執行流程爲:數據結構
獲取節點的操做和添加差很少,也是併發
HashMap 的其餘操做大同小異,再講講HashMap1.7 的問題還有1.7 和1.8 的差異。函數
HashMap 是一個併發不安全的容器,在迭代操做是採用的是fast-fail 機制;在併發添加操做中會出現丟失更新的問題;由於採用頭插法在併發擴容時會產生環形鏈表的問題,致使CPU 到達100%,甚至宕機。工具
解決併發問題能夠採用.net
Hash1.7 和1.8 最大的不一樣在於1.8 採用了「數組+鏈表+紅黑樹」的數據結構,在鏈表長度超過8 時,把鏈表轉化成紅黑樹來解決HashMap 因鏈表變長而查詢變慢的問題;其次
回答順序:數據結構+繼承結構+基本字段+構造方法+添加操做+擴容操做+獲取操做+併發問題+與1.8的區別
HashMap 做爲最基本的容器,它自己的設計與1.7 1.8的差別性致使HashMap 成爲面試中最最高頻的考點。因此掌握HashMap 勢在必行,可是想要在各類寬泛的回答中脫穎而出,就必須對hashMap 來龍去脈瞭然於胸。
這些問題都要圍繞一個點來回答:減小哈希衝突。
(1)容量必須爲2 的冪是爲了增長取值的可能性。
2 的n次冪轉化爲二進制爲1後面n個0,在計算下標的時候是hash&(length - 1),也就是&(n-1)個1:初始容量爲4->100,length-1 -> 11。全部的二進制爲都爲1有什麼好處?
能夠看出&1保證了取值的平均。若是某一位爲0 ,好比最後一位,那麼它&出來下標就必定是個偶數,減小了HashMap 數組一半的取值,大大增長了衝突的可能。
(2)負載因子爲0.75f 是空間與時間的均衡
(3)hash() 的意義在於使hash 結果不一樣 hash 算法的好壞直接影響hash 結構的效率,壞的hash 算法極端狀況下可能會使hash 結構的存取效率從O(1)退化到O(n)。1.8 之因此把9 次擾動降到2 次,是出於計算效率的考慮。
int 和 String 的好處在於hash 出來的值不會改變。若是是一個對象,那麼他們可能會由於內部引用的改變而hashCode 值的改變,會致使存儲重複的數據或找不到數據的狀況。
不只僅是HashMap 的東西,根據你的回答,面試官會引出不少其餘的問題,因此你在本身設計回答的過程當中能夠有意識引導面試官問出你熟悉的內容,安排的明明白白。
這篇文章更多的是HashMap 面試怎麼答,以及須要注意的知識點,但願對你有所幫助。
HashMap 的東西太多,因我的能力有限不能一一道全,後面若是變強了我會從新補全
推薦一篇關於HashMap 1.8 的比較好的博客: HashMap 1.8 重大更新