hashMap

咱們都知道哪裏要用HashMap,知道Hashtable和HashMap之間的區別,那麼爲什麼這道面試題如此特殊呢?是由於這道題考察的深度很深。這題常常出如今高級或中高級面試中。投資銀行更喜歡問這個問題,甚至會要求你實現HashMap來考察你的編程能力。ConcurrentHashMap和其它同步集合的引入讓這道題變得更加複雜。面試

 

1. 什麼是HashMap?編程

HashMap能夠接受null鍵值,而Hashtable則不能。HashMap是非synchronized,所以HashMap也很快。以及HashMap儲存的是鍵值對。數組

 

2. 你知道HashMap和get()方法的工做原理嗎?多線程

HashMap是基於hashing的原理,咱們使用put(key, value)存儲對象到HashMap中,使用get(key)從HashMap中獲取對象。當咱們給put()方法傳遞鍵和值時,咱們先對鍵調用hashCode()方法,返回的hashCode用於找到bucket位置來儲存Entry對象。線程

這裏關鍵點在於指出,HashMap是在bucket中儲存鍵對象和值對象,做爲Map.Entry。這一點有助於理解獲取對象的邏輯。若是你沒有意識到這一點,或者錯誤的認爲僅僅只在bucket中存儲值的話,你將不會回答如何從HashMap中獲取對象的邏輯。這個答案至關的正確,也顯示出面試者確實知道hashing以及HashMap的工做原理。code

 

3. 當兩個對象的hashcode相同會發生什麼?對象

這個問題是關於HashMap中的碰撞探測(collision detection),由於hashcode相同,因此它們的bucket位置相同,‘碰撞’會發生。由於HashMap使用LinkedList存儲對象,這個Entry(包含有鍵值對的Map.Entry對象)會存儲在LinkedList中。索引

這個答案很是的合理,雖然有不少種處理碰撞的方法,這種方法是最簡單的,也正是HashMap的處理方法。get

 

4. 若是兩個鍵的hashcode相同,你如何獲取值對象?同步

當咱們調用get()方法,HashMap會使用鍵對象的hashcode找到bucket位置,獲取值對象。若是兩個值對象存儲在一個bucket中,將會遍歷LinkedList直到調用keys.equals()方法去找到LinkedList中正確的節點,最終找到要找的值對象。(當程序經過 key 取出對應 value 時,系統只要先計算出該 key 的 hashCode() 返回值,在根據該 hashCode 返回值找出該 key 在 table 數組中的索引,而後取出該索引處的 Entry,最後返回該 key 對應的 value 便可。)

 

5. 若是HashMap的大小超過了負載因子(load factor)定義的容量,怎麼辦?

當一個map填滿了75%的bucket時候,和其它集合類(如ArrayList等)同樣,將會建立原來HashMap大小的兩倍的bucket數組,來從新調整map的大小,並將原來的對象放入新的bucket數組中。這個過程叫做rehashing,由於它調用hash方法找到新的bucket位置。

 

6. 從新調整HashMap大小存在什麼問題嗎?

當從新調整HashMap大小的時候,確實存在條件競爭,由於若是兩個線程都發現HashMap須要從新調整大小了,它們會同時試着調整大小。在調整大小的過程當中,存儲在LinkedList中的元素的次序會反過來,由於移動到新的bucket位置的時候,HashMap並不會將元素放在LinkedList的尾部,而是放在頭部,這是爲了不尾部遍歷(tail traversing)。若是條件競爭發生了,那麼就死循環了。這個時候,你能夠質問面試官,爲何這麼奇怪,要在多線程的環境下使用HashMap呢?

相關文章
相關標籤/搜索