日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > java >内容正文

java

【Java自顶向下】ConcurrentHashMap面试题(2021最新版)

發(fā)布時(shí)間:2025/3/20 java 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Java自顶向下】ConcurrentHashMap面试题(2021最新版) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

          • 1 ConcurrentHashMap默認(rèn)初始容量是多少?
          • 2 ConCurrentHashmap 的key,value是否可以為null。
          • 3 ConCurrentHashmap 每次擴(kuò)容是原來容量的幾倍
          • 4 ConCurrentHashmap的數(shù)據(jù)結(jié)構(gòu)是怎么樣的?(后面會(huì)具體分析它的put方法)
          • 5 存儲(chǔ)在ConCurrentHashmap中每個(gè)節(jié)點(diǎn)是什么樣的,有哪些變量
          • 6 ConCurrentHashmap的put過程是怎樣的?
          • 7 java1.8中ConCurrentHashmap節(jié)點(diǎn)是尾插還是頭插?
          • 8 java1.8中,ConCurrentHashmap什么情況下鏈表才會(huì)轉(zhuǎn)換成紅黑樹進(jìn)行存儲(chǔ)?
          • 9 java1.8中,ConCurrentHashmap的get過程是怎樣的?
          • 10 java1.8中,ConCurrentHashmap是如何計(jì)算它的size大小的?
          • 11 ConcurrentHashMap有哪些構(gòu)造函數(shù)?
          • 12 ConcurrentHashMap使用什么技術(shù)來保證線程安全?
          • 13 ConcurrentHashMap的get方法是否要加鎖,為什么?
          • 14 ConcurrentHashMap迭代器是強(qiáng)一致性還是弱一致性?HashMap呢?
          • 15 ConcurrentHashMap1.7和1.8的區(qū)別

1 ConcurrentHashMap默認(rèn)初始容量是多少?

從下面ConcurrentHashMap類的靜態(tài)變量可以看出它的初始容量為16

2 ConCurrentHashmap 的key,value是否可以為null。

不行 如果key或者value為null會(huì)拋出空指針異常

3 ConCurrentHashmap 每次擴(kuò)容是原來容量的幾倍

2倍 在transfer方法里面會(huì)創(chuàng)建一個(gè)原數(shù)組的倆倍的node數(shù)組來存放原數(shù)據(jù)。

4 ConCurrentHashmap的數(shù)據(jù)結(jié)構(gòu)是怎么樣的?(后面會(huì)具體分析它的put方法)

在java1.8中,它是一個(gè)數(shù)組+鏈表+紅黑樹的數(shù)據(jù)結(jié)構(gòu)。

5 存儲(chǔ)在ConCurrentHashmap中每個(gè)節(jié)點(diǎn)是什么樣的,有哪些變量

它是實(shí)現(xiàn)Map.Entry<K,V>接口。里面存放了hash,key,value,以及next節(jié)點(diǎn)。它的value和next節(jié)點(diǎn)是用volatile進(jìn)行修飾,可以保證多線程之間的可見性。

6 ConCurrentHashmap的put過程是怎樣的?

整體流程跟HashMap比較類似,大致是以下幾步:

(1)如果桶數(shù)組未初始化,則初始化;

(2)如果待插入的元素所在的桶為空,則嘗試把此元素直接插入到桶的第一個(gè)位置;

(3)如果正在擴(kuò)容,則當(dāng)前線程一起加入到擴(kuò)容的過程中;

(4)如果待插入的元素所在的桶不為空且不在遷移元素,則鎖住這個(gè)桶(分段鎖);

(5)如果當(dāng)前桶中元素以鏈表方式存儲(chǔ),則在鏈表中尋找該元素或者插入元素;

(6)如果當(dāng)前桶中元素以紅黑樹方式存儲(chǔ),則在紅黑樹中尋找該元素或者插入元素;

(7)如果元素存在,則返回舊值;

(8)如果元素不存在,整個(gè)Map的元素個(gè)數(shù)加1,并檢查是否需要擴(kuò)容;

添加元素操作中使用的鎖主要有(自旋鎖 + CAS + synchronized + 分段鎖)。

7 java1.8中ConCurrentHashmap節(jié)點(diǎn)是尾插還是頭插?

尾插法,見上述put方法。

8 java1.8中,ConCurrentHashmap什么情況下鏈表才會(huì)轉(zhuǎn)換成紅黑樹進(jìn)行存儲(chǔ)?

鏈表長(zhǎng)度大于8。數(shù)組長(zhǎng)度大于64。從put源碼和以下源碼可以看出:并非一開始就創(chuàng)建紅黑樹結(jié)構(gòu),如果當(dāng)前Node數(shù)組長(zhǎng)度小于閾值MIN_TREEIFY_CAPACITY,默認(rèn)為64,先通過擴(kuò)大數(shù)組容量為原來的兩倍以緩解單個(gè)鏈表元素過大的性能問題。

9 java1.8中,ConCurrentHashmap的get過程是怎樣的?

1、計(jì)算 hash 值
2、根據(jù) hash 值找到數(shù)組對(duì)應(yīng)位置: (n - 1) & h
3、根據(jù)該位置處結(jié)點(diǎn)性質(zhì)進(jìn)行相應(yīng)查找

如果該位置為 null,那么直接返回 null 就可以了
如果該位置處的節(jié)點(diǎn)剛好就是我們需要的,返回該節(jié)點(diǎn)的值即可

如果該位置節(jié)點(diǎn)的 hash 值小于 0,說明正在擴(kuò)容,或者是紅黑樹,后面我們?cè)俳榻B find 方法如果以上 3 條都不滿足,那就是鏈表,進(jìn)行遍歷比對(duì)即可

10 java1.8中,ConCurrentHashmap是如何計(jì)算它的size大小的?

對(duì)于size的計(jì)算,在擴(kuò)容和addCount()方法就已經(jīng)有處理了,可以注意一下Put函數(shù),里面就有addCount()函數(shù)。

11 ConcurrentHashMap有哪些構(gòu)造函數(shù)?

一共有五個(gè),作用及代碼如下:

//無參構(gòu)造函數(shù)public ConcurrentHashMap() {}//可傳初始容器大小的構(gòu)造函數(shù)public ConcurrentHashMap(int initialCapacity) {if (initialCapacity < 0)throw new IllegalArgumentException();int cap = ((initialCapacity >= (MAXIMUM_CAPACITY >>> 1)) ?MAXIMUM_CAPACITY :tableSizeFor(initialCapacity + (initialCapacity >>> 1) + 1));this.sizeCtl = cap;}//可傳入map的構(gòu)造函數(shù)public ConcurrentHashMap(Map<? extends K, ? extends V> m) {this.sizeCtl = DEFAULT_CAPACITY;putAll(m);}//可設(shè)置閾值和初始容量public ConcurrentHashMap(int initialCapacity, float loadFactor) {this(initialCapacity, loadFactor, 1);}//可設(shè)置初始容量和閾值和并發(fā)級(jí)別public ConcurrentHashMap(int initialCapacity,float loadFactor, int concurrencyLevel) {if (!(loadFactor > 0.0f) || initialCapacity < 0 || concurrencyLevel <= 0)throw new IllegalArgumentException();if (initialCapacity < concurrencyLevel) // Use at least as many binsinitialCapacity = concurrencyLevel; // as estimated threadslong size = (long)(1.0 + (long)initialCapacity / loadFactor);int cap = (size >= (long)MAXIMUM_CAPACITY) ?MAXIMUM_CAPACITY : tableSizeFor((int)size);this.sizeCtl = cap;}
12 ConcurrentHashMap使用什么技術(shù)來保證線程安全?

jdk1.7:Segment+HashEntry來進(jìn)行實(shí)現(xiàn)的;

jdk1.8:放棄了Segment臃腫的設(shè)計(jì),采用Node+CAS+Synchronized來保證線程安全;

13 ConcurrentHashMap的get方法是否要加鎖,為什么?

不需要,get方法采用了unsafe方法,來保證線程安全。

14 ConcurrentHashMap迭代器是強(qiáng)一致性還是弱一致性?HashMap呢?

弱一致性,HashMap強(qiáng)一直性。

ConcurrentHashMap可以支持在迭代過程中,向map添加新元素,而HashMap則拋出了ConcurrentModificationException,因?yàn)镠ashMap包含一個(gè)修改計(jì)數(shù)器,當(dāng)你調(diào)用他的next()方法來獲取下一個(gè)元素時(shí),迭代器將會(huì)用到這個(gè)計(jì)數(shù)器。

15 ConcurrentHashMap1.7和1.8的區(qū)別

jdk1.8的實(shí)現(xiàn)降低鎖的粒度,jdk1.7鎖的粒度是基于Segment的,包含多個(gè)HashEntry,而jdk1.8鎖的粒度就是Node

數(shù)據(jù)結(jié)構(gòu):jdk1.7 Segment+HashEntry;jdk1.8 數(shù)組+鏈表+紅黑樹+CAS+synchronized

總結(jié)

以上是生活随笔為你收集整理的【Java自顶向下】ConcurrentHashMap面试题(2021最新版)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。