1、hashmap的初始容量為什麼為2^n ?
目的:減少hash衝突
tab[
(n -1)
& hash]
jdk1.8使用該**來獲取陣列元素,不僅效率高,而且可以保證陣列不越界,讓元素分布盡可能均勻。
為了保證這些優勢,所以hashmap的容量要為2^n。
2、載入因子loadfactor為什麼是0.75 ?
負載因子loadfactor是和擴容機制有關的,是乙個擴容的閾值,意思是如果當前容器的使用度,達到了我們設定的最大值,就要開始執行擴容操作。3、jdk1.8做了哪些優化 ?
1、底層資料結構的變化4、hashmap獲取結點的步驟2、插入元素的方式
3、雜湊表為空時的操作
4、hash函式的變化
5、擴容策略
1、根據hash得出陣列下標索引。2、根據索引獲得索引位置所對應的鍵值對鍊錶/紅黑樹。
3、遍歷鍵值對鍊錶/紅黑樹,根據key找到對應的entry結點。
4、返回該結點。
final node
getnode
(int hash, object key)
while
((e = e.next)
!= null);}
}return null;
}
5、hashmap是執行緒安全的 ?
hashmap顯然不是執行緒安全的。主要是由於其在put過程中的擴容導致的,當然如果只是單純的取數在jdk1.8是執行緒安全的。
在多執行緒情況下,比如有兩個執行緒a和b,首先a希望插入乙個key-value對到hashmap中,首先需要計算記錄所要落到的桶的索引座標,然後獲取到該桶裡面的煉表頭結點,此時執行緒a的時間片用完了,而此時執行緒b被排程得以執行,和執行緒a一樣執行,只不過執行緒b成功將記錄插到了桶裡面,假設執行緒a插入的記錄計算出來的桶索引和執行緒b要插入的記錄計算出來的桶索引是一樣的,那麼當執行緒b成功插入之後,執行緒a再次被排程執行時,它依然持有過期的煉表頭但是它對此一無所知,以至於它認為它應該這樣做,如此一來就覆蓋了執行緒b插入的記錄,這樣執行緒b插入的記錄就憑空消失了,造成了資料不一致的行為。
6、hashmap與concurrenthashmap的區別 ?
hashmap執行緒不安全但效率高,concurrenthashmap執行緒安全但是效率比hashmap要低,concurrenthashmap會有更多的變數來支援執行緒安全所需要的樂觀鎖,在put方法中也加入了synchronized**塊鎖住了當前的節點頭使其只能乙個執行緒訪問,在擴容時其他執行緒新增元素會被擱置並且協助進行擴容,並宣告自己正在處理哪個位置。
7、concurrenthashmap如何實現執行緒安全 ?
通過樂觀鎖與synchronized來實現執行緒安全,在初始化陣列與空節點新增元素的時候使用樂觀鎖來實現執行緒安全,在給非空節點新增元素的時候會使用synchronized**塊鎖住當前節點頭從而實現執行緒安全,而在擴容的時候會將轉移後的節點單獨儲存起來以便於在擴容中的put與get操作,如果put需要操作的元素還沒有轉移完成則會被擱置等待轉移完成,被擱置的執行緒也會被分配到轉移資料的任務從而協助擴容。
thank you.
mysql必知必會 mysql必知必會(四)
十四 理解子查詢 1 通過子查詢過濾 這本書在所有的章節都關連到了資料庫表,訂單資料是儲存在兩個表中,orders表儲存著 訂單號碼 顧客id和訂單日期。個人的訂單列表關連著orderitems表,訂單表沒有儲存顧客資訊,它只是儲存著顧客id,這實際的顧客資訊是儲存在customers表中。現在假設...
mysql的必知必會 mysql 必知必會 筆記
好久沒有寫了。1 show columns from table 等同於describe table顯示的是表的結構。而select from table 則顯示的是整個表中插入的資料。2 select distinct c1,c2 from table除非列不相同,否則所有行將被檢索出來,即不能對...
C 必知必會
條款2 多型 2 條款3 設計模式 5 條款4 stl 8 條款5 引用是別名而非指標 10 條款6 陣列形參 13 條款7 常量指標與指向常量的指標 16 條款8 指向指標的指標 19 條款9 新式轉型操作符 21 條款10 常量成員函式的含義 25 條款11 編譯器會在類中放東西 29 條款12...