
image.png
- hashSet底層實現(xiàn)?
hashSet底層實現(xiàn)用的hashMap,存入的值都在key里面,value存放的是一個固定值
// Dummy value to associate with an Object in the backing Map private static final Object PRESENT = new Object();
- 為什么內(nèi)置HashMap
hashMap是基于數(shù)組和鏈表的數(shù)據(jù)結(jié)構(gòu),是考慮時間和空間的的因素后比較優(yōu)秀的一種實現(xiàn),能重用為啥要單獨自己搞
- 說下HashMap的數(shù)據(jù)結(jié)構(gòu)
數(shù)組加鏈表+紅黑樹
- 為什么loalFactor是0.75
太高了增加時間成本,比如1,說明會產(chǎn)生很多碰撞,鏈表已經(jīng)很長了;太低,空間利用率不夠;
另外這個值是坐著根據(jù)泊松分布計算后綜合考慮的,泊松分布是離散隨機分布的一種,通常被使用在估算在 一段特定時間/空間內(nèi)發(fā)生成功事件的數(shù)量的概率。
設(shè)置成0.75有一個好處,那就是0.75正好是3/4,而capacity又是2的冪。所以,兩個數(shù)的乘積都是整數(shù)。
- 為什么要高位參與運算
增加 hash 值的任意性;
- 高位運算的步驟:是無符號右移16位,低位擠走,高位補0,高位參與運算,這樣算出來的結(jié)果實質(zhì)是高區(qū)與低區(qū)的二進制特征混合到低區(qū);
- 假設(shè)數(shù)組槽的大小是16,(n - 1) = 15那么他的二進制是 0000 0000 0000 0000 0000 0000 0000 1111;
- 那么計算該hashCode屬于哪個槽位是用的代碼 (n - 1) & hash;由于這個 (n - 1)的高位都是0,所以和hash的高位&的時候,hashCode的高位有細微變化是體現(xiàn)不出來的,因為和0 &運算的結(jié)果都是0;
- 所以這種情況很容易產(chǎn)生沖突,所以高位參與地位運算的精髓就是,讓高位的細微變動能導(dǎo)致不同的結(jié)果,這樣hash的結(jié)果更加均勻
- 為什么高位參加運算的時候使用的是異或^,而不是與&
(^ 為按位異或,即轉(zhuǎn)成二進制后,相異為1,相同為0);異或運算能更好的保留各部分的特征,如果采用 & 運算計算出來的值會向 1 靠攏,采用 | 運算計算出來的值會向 0 靠攏;因為右移了16,高位是0,&之后還是0,那右移了個寂寞
- ConcurrentHashMap的get方法有鎖么
只有在get方法,如果此時結(jié)構(gòu)是紅黑樹,這個時候在進行樹查找時會判斷這個樹是否在變色,會進行讀寫鎖的判斷
- ConcurrentHashMap的get是強一致性么?為什么是弱一致性
不是,雖然Node的數(shù)組table被volatile修飾,但是這樣只是代表table的引用地址如果被修改,其他線程可以立馬看到,并不代表table里的數(shù)據(jù)被修改立馬可以看到。
- happens-before 是什么?
前一個操作的結(jié)果可以被后續(xù)的操作獲取。講白點就是前面一個操作把變量a賦值為1,那后面一個操作肯定能知道a已經(jīng)變成了1。