1. 程式人生 > >Java面試題總結-Day4

Java面試題總結-Day4

Java面試題總結-Day4

Table of Contents

1 ArrayList和LinkedList區別

1.1 是否執行緒安全

  • ArrayList和LinkedList都是不同步的,也就是不保證執行緒安全.

1.2 底層資料結構

  • ArrayList底層使用的是Object陣列.
  • LinkedList底層使用的是雙向迴圈連結串列資料結構.

1.3 插入和刪除是否受元素位置的影響

  • ArrayList採用陣列儲存,所以插入和刪除元素的時間複雜度受元素位置的影響.
    • 執行 add(E e) 方法的時候,ArrayList會預設在將指定的元素追加到此列表的末尾,這種情況下時間複雜度就是 \(O(1)\)
    • 如果要在指定位置i插入和刪除元素的話 add(intindex, E element) ,時間複雜度就是 \(O(n-i)\).因為在進行上述操作時候集合中第i和第i個元素之後的(n-i)個元素都要執行向後位/向前移一位的操作.
  • LinkedList採用連結串列儲存,所以插入,刪除元素時間複雜度不受元素位置的影響,都是近似 \(O(1)\) ,而陣列近似為 \(O(n)\)

1.4 是否支援快速隨機訪問

  • 快速隨機訪問就是通過元素的序號快速獲得元素物件(對應於 get(intIndex) 方法)
  • LinkeList不支援高效的隨機元素訪問,而ArrayList實現了RandomAccess介面,所以有隨機訪問的能力.

1.5 記憶體空間佔用

  • ArrayList的空間浪費主要體現在list列表的結尾會預留一定的容量空間.
  • LinkedList的空間話費則體現在它每一個元素都需要消耗比ArrayList更多的空間(因為要存放直接後繼和直接前驅以及資料).

2 ArrayList和Vector的區別

  • Vector類的所有方法都是同步的.可以由兩個執行緒安全地訪問同一個Vector物件,但是一個執行緒訪問Vector的話程式碼要在同步操作上耗費大量的時間.
  • ArrayList不是同步的,在不需要保證執行緒安全時建議使用ArrayList

3 HashMap的底層實現

3.1 JDK1.8之前的實現方法

  • JDK1.8之前HashMap由 陣列+連結串列 組成的("連結串列雜湊"即陣列和連結串列的組合體).
  • 陣列是HashMap的主體,連結串列則是為了解決雜湊衝突而存在的.(HashMap採用拉鍊法"鏈地址法"解決衝突)
  • 如果定位到的陣列位置不含連結串列(當前entry的next指向null),那麼對於查詢,新增等操作很快,僅需一次定址即可.
  • 如果定位的陣列包含連結串列,對於新增操作,其時間複雜度依然為 \(O(1)\) ,因為最新的Entry會插入連結串列頭部,即需要簡單改變引用鏈即可以.
  • 對於查詢操作來講,就需要遍歷連結串列,然後通過key物件equals方法逐一對比查詢.

3.2 JDK1.8以後的實現方法

  • JDK1.8之後在解決雜湊衝突時有了較大的變化,當連結串列長度大於閥值(預設是8)時,將連結串列轉化為紅黑樹,以減少搜尋時間.
  • TreeMap,TreeSet以及JDK1.8知乎的HashMap底層都用了紅黑樹.紅黑樹就是為了接二覺二叉查詢樹的缺陷,因為二叉查詢樹在某些情況下會退化為一個線性結構

4 HashMap和HashTable的區別

4.1 是否執行緒安全

  • HashMap是非執行緒安全的.
  • HashTable是執行緒安全的.

4.2 效率

  • 因為執行緒安全的問題,HashMap要比HashTable效率高一些.
  • 另外,HashTable基本被淘汰,不要在程式碼中使用它.

4.3 對Null key和Null value的支援

  • HashMap中,null可以作為鍵,這樣的鍵只有一個,可以由一個或多個鍵所對應的值為null.
  • HashTable中put進的鍵值只要有一個null,直接丟擲NullPointeerException.

4.4 初始容量大小和每次擴容大小的不同

  • 建立時不指定初值,HashTable預設的初始大小為11,之後每次擴充,容量會變為原來的2n+1.
  • HashMap預設的初始大小為16.之後每次擴充,容量變為原來的2倍.
  • 建立時候如果給定了容量初始值,那麼HashTable會直接使用你給定的大小,而HashMap會將其擴充為2的冪次方大小.

4.5 HashMap的長度為什麼是2的冪次方

  • 為了能讓HashMap存取高效,儘量較少碰撞,也就是要儘量把資料分配均勻,每個連結串列/紅黑樹長度大致相同.這個實現就是把資料存到哪個連結串列/紅黑樹中的演算法.

4.5.1 該演算法的設計

  • 位運算操作比取餘操作更快.
  • 取餘操作中如果除數是2的冪次則等價於其除數-1的與操作,也就是說 \(hash % length == hash & (length - 1)\) 的前提是length是2的n次方.
  • 所以HashMap的長度是2的冪次方.

Date: 2018-11-03 09:42

Author: devinkin

Created: 2018-11-03 六 09:42

Validate