Java開發工程師最新面試題庫系列——集合部分(附答案)

黎久桐槐發表於2021-02-15
集合

如果你有更好的想法請在評論區留下您的答案,一起交流討論

  1. 說說常見的集合有哪些?

    答:主要分List、Set、Map、Queue四類,其中包含ArrayList、LinkedList、HashSet、TreeSet、HashMap

  2. Comparable和Comparator介面的區別?

    答:其兩者的目的都是讓物件可比。第一種將需要比較的類可實現Comparable並重寫comparaTo方法制定比較規制,如此讓類本身具備可比性,無需依賴其他第三方類。第二種為需要比較的類再定義一個比較類,該類需要基礎Comparator介面實現compara方法傳入倆個需要物件的進行比較,該方法需要依賴第三方類。

  3. 集合使用泛型有什麼優點?

    答:泛型允許我們為集合提供一個可以容納的物件型別,因此,如果你新增其它型別的任何元素,它會在編譯時報錯。這避免了在執行時出現ClassCastException,因為你將會在編譯時得到報錯資訊。

  4. List、Set、Map之間的區別是什麼?

    答:

    特性不同
    • List 有序可重複
    • Set 無序不可重複
    • Map KV形式儲存,無序Key不可重複
  5. 為什麼Map介面不繼承Collection介面?

    答:Map提供的是鍵值對對映(即Key和value的對映),而collection提供的是一組資料(並不是鍵值對對映)。如果map繼承了collection介面,那麼所有實現了map介面的類到底是用map的鍵值對對映資料還是用collection的一組資料呢(就我們平常所用的hashMap、hashTable、treeMap等都是鍵值對,所以它繼承collection完全沒意義),而且map如果繼承了collection介面的話還違反了物件導向的介面分離原則。

  6. 常用的執行緒安全的Map有哪些?

    答:HashTable,ConcurrentHashMap

  7. HashMap和Hashtable有什麼區別?

    答:

    • HashMap的Key和Value都可以為Null,而HashTable的Key和Value都不能
    • HashMap的執行緒不安全效率高,HashTable的執行緒安全效率低
    • HashMap繼承的是AbstractMap,HashTable繼承的是Dictionary介面
  8. HashMap和TreeMap怎麼選?

    答:存放的資料需要排序選擇TreeMap,不需要排序選擇HashMap,而且可以根據HashMap空間的使用,對初始容量和負載因子進行調優。

  9. HashMap的資料結構是什麼?

    答:陣列+連結串列/紅黑樹,一般稱為“連結串列雜湊”

  10. HashMap在JDK 8中有哪些改變?

    答:JDK8之前HashMap採用的資料結構為陣列+連結串列,JDK8之後HashMap採用陣列+連結串列/紅黑樹。增加紅黑樹來優化連結串列過長時帶來的查詢效能消耗;

    發生Hash衝突時

    JDK7:插入連結串列的頭部,頭插法
    JDK8:插入連結串列的尾部,尾插法

  11. HashMap是怎麼解決Hash衝突的?

    答:

    1. 開放地址法:將雜湊演算法算出來的hash通過位移操作符向後位移,使存放地址向後移位,如果還在衝突就繼續移位
    2. 拉鍊發:在相同的雜湊位置處生產一個連結串列,鏈在衝突位置的後面
    3. 在Hash:重新計算Hash
    4. 建立公共溢位區
  12. HashMap是怎麼擴容的?

    答:當儲存的資料量達到總容量的負載因子大小(預設0.75)時開始擴容。擴容會建立當前陣列大小的兩倍,再將原來的資料重新進行hash計算儲存位置,由此可見HashMap擴容對效能的消耗比較嚴重

  13. HashMap如何實現同步?

    答:

    • Collections.synchronizedMap(HashMap物件)將HashMap轉變為執行緒安全的
    • HashMap進行寫操作的步驟寫在synchronized同步程式碼塊中
    • 用lock
      lock.lock();
      Value = map.get(key);
      lock.unlock();
  14. ConcurrentHashMap的資料結構是什麼?

    答:CurrentHashMap的結構是Segment陣列的意義就是將一個大的table分割成多個小的table來進行加鎖,也就是上面的提到的鎖分離技術,而每一個Segment元素儲存的是HashEntry陣列+連結串列,這個和HashMap的資料儲存結構一樣。

  15. ArrayList是執行緒安全的嗎?

    答:執行緒不安全

  16. 常用執行緒安全的List集合有哪些?

    答:Vector、以及通過java.util.Collections.SynchronizedList將任何List轉換為執行緒安全、CopyOnWriteArrayList複製寫入,新增元素時先加鎖並且複製一份原來的List再新增元素,最後釋放鎖。

  17. 迴圈刪除List集合可能會發生什麼異常?

    答:會導致陣列元素位移,造成元素誤刪。解決辦法是倒著刪除或者使用迭代器遍歷時刪除

  18. ArrayList和LinkedList有什麼區別?

    答:資料結構不同,ArrayList底層採用陣列,查詢快增加或刪除慢(涉及到資料元素位移)。LinkedList底層採用連結串列結構,查詢慢,增加刪除快

  19. ArrayList和Vector有什麼區別?

    答:ArrayList執行緒不安全效率高,Vector執行緒安全效率低

  20. 什麼是CopyOnWriteArrayList?

    答:CopyOnWriteArrayList是ArrayList的一個執行緒安全的變體,其中所有可變操作(add、set等等)都是通過對底層陣列進行一次新的複製來實現的。相比較於ArrayList它的寫操作要慢一些,因為它需要例項的快照。

    CopyOnWriteArrayList中寫操作需要大面積複製陣列,所以效能肯定很差,但是讀操作因為操作的物件和寫操作不是同一個物件,讀之間也不需要加鎖,讀和寫之間的同步處理只是在寫完後通過一個簡單的"="將引用指向新的陣列物件上來,這個幾乎不需要時間,

  21. 什麼是fail-safe?

    答:當我們對集合結構上做出改變的時候,fail-fast機制就會丟擲異常。但是,對於採用fail-safe機制來說,就不會丟擲異常

    這是因為,當集合的結構被改變的時候,fail-safe機制會在複製原集合的一份資料出來,然後在複製的那份資料遍歷。

  22. 什麼是fail-fast?

    答:fail-fast的字面意思是“快速失敗”。當我們在遍歷集合元素的時候,經常會使用迭代器,但在迭代器遍歷元素的過程中,如果集合的結構被改變的話,就會丟擲異常,防止繼續遍歷。這就是所謂的快速失敗機制。fail-fast,即快速失敗機制,它是java集合中的一種錯誤檢測機制,當多個執行緒(單個執行緒也是可以滴),在結構上對集合進行改變時,就有可能會產生fail-fast機制。

  23. fail-fast和fail-safe有什麼區別?

    答:

    fail-safe機制

    fail-safe任何對集合結構的修改都會在一個複製的集合上進行修改,因此不會丟擲ConcurrentModificationException

    fail-safe機制有兩個問題

    (1)需要複製集合,產生大量的無效物件,開銷大

    (2)無法保證讀取的資料是目前原始資料結構中的資料。

    fail-fast機制

    fail-fast機制在遍歷一個集合時,當集合結構被修改,會丟擲Concurrent Modification Exception。

    fail-fast會在以下兩種情況下丟擲ConcurrentModificationException

    (1)單執行緒環境

    集合被建立後,在遍歷它的過程中修改了結構。

    注意 remove()方法會讓expectModcount和modcount 相等,所以是不會丟擲這個異常。

    (2)多執行緒環境

    當一個執行緒在遍歷這個集合,而另一個執行緒對這個集合的結構進行了修改。

  24. HashSet的底層實現原理是什麼?

    答:HashSet底層依賴與HashMap進行資料儲存,HashSet的元素就是HashMap中的Key,而Value則為Null

  25. 怎麼確保一個集合不能被修改?

    答:兩種實現方式,Collections. unmodifiableCollection(Collection c) 方法建立的集合(

    最終會返回一個由Collections.UnmodifiableCollection類,該類對所有的寫操作都進行了重寫覆蓋,使其丟擲UnsupportedOperationException異常),和使用Arrays.asList建立的集合(返回了一個Arrays的靜態內部類ArrayList,原理與Collections.UnmodifiableCollection差不多)。

相關文章