HashMap的面試題你能回答幾個?

2021-08-11 09:56:34 字數 1907 閱讀 5764

1.hashmap用什麼資料結構實現的?

答:陣列。什麼樣的陣列?答:node table這樣的。node是什麼?答:看下圖:

也就是說這個陣列每個元素都是個單向鍊錶。

2.hashmap的get過程是?

答:先得到key的hash值,再把這個hash值與length-1按位與(取餘),得到table陣列的下標。取出這個下標值的key,與傳入的key比較,如果相同那就是這個了。如果不同呢,那就沿著這個單向鍊錶向後找,直到找到或找到結束也找不到。

等等,這個hash值與length-1按位與就是等同取餘麼?為什麼?

答:是的,因為這個length是有特點的,是2的n次方,length-1就是二進位制全部為1。那麼乙個數的二進位制按位與這些全為1的位,就會得到與這些全為1的位對齊的另乙個數,如(15&6=1111&0110=6=0110)。而這個數正好是取2的n次的餘數(6%15=6=15&6)。 至於為什麼這個length是2的n次方,下面的問題會回答 。貼下原始碼:

3.hashmap初始化傳入的容量引數的值就是hashmap實際分配的空間麼?

答:不是。那是什麼呢?是比傳入容量引數值大的最小的2的n次方,比如傳入6,實際分配8。看下計算容量的原始碼。雖然這裡原始碼計算的值只是threshold,而沒有**說明它是實際值,但本文最後的原始碼可以說明它就是實際值。

看到這個這個tablesizefor方法,那麼規則的1、2、4、8、16,是不是有點蒙。演算法長成這樣,是畫畫麼?先了解下基礎知識,乙個整形由4個位元組構成,那它轉為二進位制應該是32(4*8)位。但這是有符號的,其實正數和負數各佔一半,也就是說各有2的31次方,最高位是符號位。我們這裡是無符號操作就不用管這個符號了。上面的無符號右移16位就可以覆蓋32位,16就是這麼來的。其實這5個》(無符號右移)是為了把cap-1的最高二進位制位及其後面的位都置成1。

最高二進位制位是什麼意思呢? 乙個整形轉為二進位制後,最左邊的那位一定是1,前面補的0不能算哈,這個最左的1就是最高二進位制位。

按上面的演算法,第一次無符號右移1位再和原二進位制按位或,至少把最左邊和次最左邊的兩個位置為1了吧。那第二次再只移一位就沒意義了,因為前兩位都是1了,不需計算了,所以第二次是右移2位,這樣就有4個1了。同理4位變8位,8位變16位,最後16位變32位,實際是只有31位(最前的是符號位)。這樣就把cap-1變為乙個從其二進位制形式的最高位到0位全為1的二進位制數了,而這個二進位制數正好是比cap-1大一點的那個2的n次方的數-1(如2的3次方減1就是1000-1=0111=7)。

最後一行再+1就是2的n次方了(7+1=8=2的3次方).而第一行的n=cap-1,這也就是防止傳入引數就是2的n次的情況(如8的二進位制是1000),再把這個最高二進位制位的後面都置成1,最後再加1就變成16了。這就不是與傳入引數最接近的2的n次方了。

這裡也就回答了為什麼map.length是2的n次方了,後面擴容的機制會證明它總是保持著2的n次方。

4.hashmap擴容機制是什麼,什麼時候擴,每次擴多少?

答:在put時,容量不夠用的時候。因為每個元素都是乙個單向鍊錶,所以map裡放的實際數量總是大於等於申請的空間。那麼容量不夠用就是實際存放的數量等於申請的空間大小的時候。看下原始碼put->putval:

上面我們已經知道,hashmap的實際容量是2的n次方了。那麼擴容也就是原來的容量*2,也就是擴到2的n+1次方。建構函式裡有個載入因子(loadfactor),我曾經以為擴容就是擴這個數(預設0.75)+1倍,看到這裡的原始碼才發現錯了。這個載入因子只是計算下乙個2的n次用的中間變數。預設的是0.75,那計算下乙個2的n次方的基準值就是old*2*0.75,那麼下乙個2的n次方就是比這個基準值大的最少值(old*2)。如下圖:

從上面**可以看出,這個擴容**是相當精妙的,更多有意思的地方,請同學自行debug。

最後感謝海生和我討論這些問題,打賞的錢分他1/3。

這樣的面試題,你能回答幾個

1 了解hbase麼,為什麼儲存速度快?2理解spring麼,它的aop實現是基於什麼原理,bean的初始化過程是那些 涉及具體的源 在bean factory初始化前 執行中,初始化後想做些事情。該怎麼做?3 struts1和strus2的區別,strust2關於 thredlocal是什麼,st...

你必須知道的HashMap面試題

hashmap基於hash原理,通過put 和get 方法儲存和獲取元素。它內部使用陣列 鍊錶或紅黑樹的結構,通過hash運算找到bucket位置來儲存entey物件,通過equals 方法找到正確的鍵值對。hashmap使用鏈位址法來解決hash碰撞問題,當發生碰撞時,物件會儲存在鍊錶的下乙個節點...

微軟的面試題(相當經典)你們能回答幾個?

第一組 1.為什麼下水道的蓋子是圓的?2.中國有多少輛汽車?3.將汽車鑰匙插入車門,向哪個方向旋轉就可以開啟車鎖?4.如果你要去掉中國的34個省 含自治區 直轄市和港澳特區及台灣省 中的任何乙個,你會去掉哪乙個,為什麼?5.多少個加油站才能滿足中國的所有汽車?6.想象你站在鏡子前,請問,為什麼鏡子中...