小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

java面試題 --- 集合

 貪挽懶月 2022-06-20 發(fā)布于廣東

1. java 集合你了解嗎?

  • java 集合最頂層接口是 Collection 和 Map;
  • Collection 有三個(gè)核心接口,分別是 List,Set,Queue;
  • List 是有序可重復(fù)的,它的主要實(shí)現(xiàn)類有 ArrayList、LinkedList 和 Vector;
  • ArrayList 是數(shù)組實(shí)現(xiàn)的,查詢快增刪慢線程不安全;
  • LinkedList 是鏈表實(shí)現(xiàn)的,查詢慢增刪快線程不安全;
  • Vector 相當(dāng)于線程安全的 ArrayList;
  • Set 是無序不重復(fù)的,它的主要實(shí)現(xiàn)類有 HashSet、TreeSet 和 LinkedHashSet,它們分別是用對(duì)應(yīng)的 Map 實(shí)現(xiàn)的,比如 HashSet 就是用 HashMap實(shí)現(xiàn)的,注意 TreeSet 是有序的;
  • Queue 是隊(duì)列,主要有阻塞隊(duì)列 BlockingQueue。Map 的主要實(shí)現(xiàn)類有 HashMap、LinkedHashMap、HashTable 和 TreeMap。

2. 什么是集合的快速失敗機(jī)制?

  • 集合內(nèi)部會(huì)維護(hù)一個(gè) modCount 變量,遍歷的時(shí)候,會(huì)判斷 modCount 變量的值是否等于期望值,不等就會(huì)報(bào)并發(fā)修改異常。

3. 用 for 循環(huán)遍歷集合的同時(shí)移除元素可以嗎?

  • 不可以,會(huì)報(bào)并發(fā)修改異常。要邊遍歷邊移除元素,只能用迭代器。

4. HashMap 底層是用什么實(shí)現(xiàn)的?

  • jdk1.7 的 HashMap 采用拉鏈法,數(shù)組加鏈表實(shí)現(xiàn)的;
  • jdk1.8 的 HashMap 采用了數(shù)組加鏈表加紅黑樹實(shí)現(xiàn)。

5. HashMap (jdk1.8) 怎么初始化的?

  • 如果調(diào)用的是無參構(gòu)造,不會(huì)立即初始化數(shù)組,要等 put 元素時(shí)才會(huì)初始化一個(gè)長(zhǎng)度為 16 的數(shù)組;
  • 如果調(diào)用的是帶參構(gòu)造,就會(huì)將數(shù)組長(zhǎng)度初始化為最接近傳入?yún)?shù)的 2 的 n 次冪,比如傳入的是 6,那就初始化為 8。

6. HashMap (jdk1.8) 怎么計(jì)算索引的?

  • 首先會(huì)對(duì) key 的 hashCode 值的高十六位與低十六位做一個(gè)異或 (^) 運(yùn)算,這樣做是為了讓 key 的整個(gè) hashCode 都能參與接下來的計(jì)算,減少 hash 碰撞的概率,且異或運(yùn)算得到 0 和 1 的概率一樣,不會(huì)影響數(shù)據(jù)分布;
  • 接著拿到剛才計(jì)算出來的值,和數(shù)組長(zhǎng)度減一之后的值進(jìn)行與 (&) 運(yùn)算,就得到了索引。

7. HashMap (jdk1.8) 計(jì)算索引時(shí)為什么用與 (&) 操作?

  • 正常情況計(jì)算索引應(yīng)該是 hashCode 值對(duì)數(shù)組長(zhǎng)度取模,即求余,但是取模運(yùn)算的效率不高,所以改用與 (&) 操作。

8. HashMap (jdk1.8) 數(shù)組長(zhǎng)度為什么是 2 的 n 次冪?

  • 只有當(dāng)數(shù)組長(zhǎng)度為 2 的 n 次冪時(shí),hashCode 值與 (&) 數(shù)組長(zhǎng)度減一的計(jì)算結(jié)果才會(huì)和 hashCode 值對(duì)數(shù)組長(zhǎng)度取模的計(jì)算結(jié)果才會(huì)一致;
  • 同時(shí) 2 的 n 次冪減一的二進(jìn)制是若干個(gè) 1,和奇數(shù)計(jì)算最后結(jié)果是奇數(shù),和偶數(shù)計(jì)算的結(jié)果是偶數(shù),如果最后一位是 0,那么不管和奇數(shù)還是偶數(shù)進(jìn)行與 (&) 計(jì)算的結(jié)果都是偶數(shù),不能保證散列分布均勻。

9. HashMap (jdk1.8) 計(jì)算拿到索引后直接把元素存在那個(gè)位置嗎?

  • 拿到索引后,先判斷索引位置是否有元素,如果沒有,直接把元素放到索引位置;
  • 如果有,判斷 key 是否一樣,如果一樣,新值覆蓋舊值;
  • 如果不一樣,就在此處生成鏈表,元素存到鏈表中。

10. HashMap (jdk1.8) 什么時(shí)候生成紅黑樹?

  • 當(dāng)鏈表長(zhǎng)度達(dá)到 8,且數(shù)組長(zhǎng)度達(dá)到 64 的時(shí)候,就會(huì)生成紅黑樹;
  • 當(dāng)紅黑樹節(jié)點(diǎn)少于 6 個(gè)的時(shí)候,又會(huì)將紅黑樹轉(zhuǎn)回鏈表。

11. HashMap (jdk1.8) 數(shù)組什么時(shí)候擴(kuò)容?

  • 擴(kuò)容因子是 0.75,當(dāng)數(shù)組中元素個(gè)數(shù)達(dá)到數(shù)組長(zhǎng)度的 3/4 時(shí)就擴(kuò)容,擴(kuò)容為原來的兩倍。

12. HashMap (jdk1.8) 數(shù)組擴(kuò)容后數(shù)據(jù)怎么轉(zhuǎn)移?

  • 如果原先數(shù)組那位位置的元素是單個(gè)元素或者紅黑樹,那就放到 hash 與 (&) 新數(shù)組長(zhǎng)度減一的位置;
  • 如果是鏈表,那就判斷 hash 與 (&) 舊數(shù)組長(zhǎng)度是否為 0,如果是,就放在原來索引處,如果不是,就放在原來索引加上舊數(shù)組長(zhǎng)度處。

13. 既然 HashMap (jdk1.8) 不安全,那并發(fā)情況下用什么?

  • 用 ConcurrentHashMap。

14. ConcurrentHashMap 的底層你知道嗎?

  • jdk1.7 的 ConcurrentHashMap 底層是 Segment 數(shù)組,Segment 數(shù)組存放的元素是 HashEntry 數(shù)組,HashEntry 數(shù)組存放的元素是鏈表。每次鎖住一個(gè) Segment,保證安全性的同時(shí)提高了并發(fā)性,這就是鎖分段機(jī)制;
  • jdk1.8 的 ConcurrentHashMap 的底層是數(shù)組加鏈表加紅黑樹,用 Synchronized 和 CAS 來保證線程安全。

15. ArrayList 的 elementData 為什么用 transient 修飾?

  • 加上 transient 就不會(huì)直接序列化整個(gè)數(shù)組,序列化的時(shí)候只序列化數(shù)組中存的元素,而不是整個(gè)數(shù)組,既加快了序列化速度也減小了序列化后文件的大小。

16. List 和 Set 如何選用?

  • List 支持隨機(jī)快速訪問,支持用索引獲取元素,Set 不支持。所以如果增刪操作比較多,適合用 Set,查詢操作比較多,適合用 List;
  • List 是有序可重復(fù)的,而 Set 是無序不重復(fù)的。所以可以根據(jù)存入的元素是否需要順序、是否可以重復(fù)來決定用什么。

17. HashSet 如何保證元素不重復(fù)?

  • HashSet 底層是 HashMap,HashSet 存儲(chǔ)的元素就存放在 HashMap 的 key 中,HashMap 的 key 是否相同是先比較 hashCode 值再用 equals 方法比較。

18. 為什么 String、Integer 適合作為 HashMap 的 key?

  • 因?yàn)?String 和 Integer 都是 final 類型的,能夠保證 hash 值的不可更改性;
  • String 和 Integer 已經(jīng)重寫了 hashCode 方法和 equals 方法,可以保證計(jì)算的準(zhǔn)確性。

掃描二維碼

    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多