1.為什麼treeify_threshold要是8?
treefy是有成本的,新增或刪除元素時有額外的操作,同時treenode是普通node體積的二倍,因而需要乙個平衡點。
隨機hashcode下符合泊松分布,
* 0: 0.60653066
* 1: 0.30326533
* 2: 0.07581633
* 3: 0.01263606
* 4: 0.00157952
* 5: 0.00015795
* 6: 0.00001316
* 7: 0.00000094
* 8: 0.00000006
乙個桶內8個元素的概率為一億分之六;
當情況發生時,說明hashcode設計的不合理,此時會有大量碰撞,這種情況下維護樹就是有必要的。
這個值越小,樹化的影響就越強力,當小於8時,就可能導致頻繁的樹化,增加維護成本。
普通node內部維護的屬性有:
int hash,
k key,
v val,
nodenext
treenode維護的屬性有:
int hash,
k key,
v val,
nodenext
以及treenodeparent;
treenodeleft;
treenoderight;
treenodeprev;
大約是普通node大小的2倍
2.為什麼put方法中的hash值要再進行一次加工,為何要使用 ( h = k.hashcode() ) ^ ( h >>> 16 ) 操作?
計算桶位置的方法為 (tab.length - 1) & hash
一般來說,hashmap的長度不會過大,不會超過65536(1 << 16),只有hash的低16(左右)位參與計算,如果直接將 k.hashcode() 當作hash進行位置計算的話,
則其中的高16(左右)位資訊並未參與計算,而 ( h = k.hashcode() ) ^ ( h >>> 16 ) 演算法將高16位中的資訊加以利用,得出低16位更加隨機的hash,
從而使桶的分布更佳均勻,使用^運算而不是&或者|,是因為^不會使結果有概率上的偏向性。
tab.length固定為2的次方,二進位制即為最高位有效位為1,
其餘位均為0的數字,tab.length - 1即為所有有效位均為1的二進位制數字.
hash對其求&,則獲得的值x >= 0 且x <= tab.length - 1,共 tab.length 個,且分布完全依賴於hash的與tab.length - 1位數相同的低位。
3.擴容時擴大多少,為什麼?
容量擴大為原來的二倍( oldcap << 1 ),該方法配合尋桶演算法 hash & (newcap - 1) 使用,
使得擴容後元素在新陣列中分布均勻(newcap - 1二進位制最高有效位對應的hash相應的位如果為1,則桶位置下標為(原來的下表 + oldcap),若為0,則桶位置不變,
0,1是依賴於hashcode的,隨機的,所以理論上是均勻的)
關於hashmap的一些操作
兩個hashmap比對值然後把相同的值儲存到list裡 for entryentry map.entryset public static mapdothing mapmap else return map3 public static void removenullvalue map map pr...
關於LINUX驅動的一些疑問
1,像字元裝置混雜裝置,都只註冊乙個裝置就ok了,為了什麼都的驅動除了註冊裝置還要註冊驅動。而驅動結構體裡面一般都有probe函式。2.平台分驅動註冊和裝置註冊這個我是知道的,註冊完了會呼叫驅動結構體裡面的probe函式,好像真正的驅動都是在裝置結構體裡面完成了,話有裝置 節點的生成。3,除了這些,...
關於WiMax認證的一些疑問
使用x supplicant和openssl來實現eap tls的認證方式。在認證完成之前,並沒有獲得ip,那麼eap tls如何實現的呢?沒有ip就可以通訊?x supplicant呼叫openssl來幹什麼?只是呼叫openssl的x.509函式來對radius伺服器的證書進行驗證嗎?李春平說 ...