面試彙總7.15
1.請解釋為什麼集合類沒有實現Cloneable和Serializable介面?
克隆(cloning)或者是序列化(serialization)的語義和含義是跟具體的實現相關的。因此,應該由集合類的具體實現來決定如何被克隆或者是序列化。
實現Serializable序列化的作用:將物件的狀態儲存在儲存媒體中以便可以在以後重寫創建出完全相同的副本;按值將物件從一個從一個應用程式域發向另一個應用程式域。
實現 Serializable介面的作用就是可以把物件存到位元組流,然後可以恢復。所以你想如果你的物件沒有序列化,怎麼才能進行網路傳輸呢?要網路傳輸就得轉為位元組流,所以在分散式應用中,你就得實現序列化。如果你不需要分散式應用,那就沒必要實現實現序列化。
2. 請說明Java集合類框架的基本介面有哪些?
集合類介面指定了一組叫做元素的物件。集合類介面的每一種具體的實現類都可以選擇以它自己的方式對元素進行儲存和排序。有的集合類允許重複的鍵,有些不允許。
Java集合類提供了一套設計良好的支援對一組物件進行操作的介面和類。Java集合類裡面最基本的介面有:
Collection:代表一組物件,每一個物件都是它的子元素。
Set:不包含重複元素的Collection。
List:有順序的collection,並且可以包含重複元素。
Map:可以把鍵(key)對映到值(value)的物件,鍵不能重複。
3. 請解釋一下TreeMap?
TreeMap是一個有序的key-value集合,基於紅黑樹(Red-Black tree)的 NavigableMap實現。該對映根據其鍵的自然順序進行排序,或者根據建立對映時提供的 Comparator進行排序,具體取決於使用的構造方法。
TreeMap的特性:
根節點是黑色
每個節點都只能是紅色或者黑色
每個葉節點(NIL節點,空節點)是黑色的。
如果一個節點是紅色的,則它兩個子節點都是黑色的,也就是說在一條路徑上不能出現兩個紅色的節點。
從任一節點到其每個葉子的所有路徑都包含相同數目的黑色節點。
4. 請說明ArrayList是否會越界?
ArrayList是實現了基於動態陣列的資料結構,而LinkedList是基於連結串列的資料結構2. 對於隨機訪問get和set,ArrayList要優於LinkedList,因為LinkedList要移動指標;ArrayList併發add()可能出現數組下標越界異常。
5. 請你說明concurrenthashmap有什麼優勢以及1.7和1.8區別?
Concurrenthashmap執行緒安全的,1.7是在jdk1.7中採用Segment+HashEntry的方式進行實現的,lock加在Segment上面。1.7size計算是先採用不加鎖的方式,連續計算元素的個數,最多計算3次:1、如果前後兩次計算結果相同,則說明計算出來的元素個數是準確的;2、如果前後兩次計算結果都不同,則給每個Segment進行加鎖,再計算一次元素的個數;
1.8中放棄了Segment臃腫的設計,取而代之的是採用Node+CAS+Synchronized來保證併發安全進行實現,1.8中使用一個volatile型別的變數baseCount記錄元素的個數,當插入新資料或則刪除資料時,會通過addCount()方法更新baseCount,通過累加baseCount和CounterCell陣列中的數量,即可得到元素的總個數;
6. 請你說明一下concurrenthashmap鎖加在那些地方?
加在每個Segment上面。
7. 請你解釋HashMap的容量是2的n次冪?
負載因子預設是0.75, 2^n是為了讓雜湊更加均勻,例如出現極端情況都雜湊在陣列中的一個下標,那麼hashmap會由O(1)複雜退化為O(n)的。
8. 請你簡單介紹一下ArrayList和LinkedList的區別,並說明如果一直在list的尾部新增元素,用那種方法效率高?
ArrayList採用陣列陣列實現的,查詢效率比LinkedList高。LinkedList採用雙向連結串列實現的,插入和刪除的效率比ArrayList要高。一直在list的尾部新增元素,LinkedList效率要高。
9. 如果hashMap的key是一個自定義的類,怎麼辦?
使用HashMap,如果key是自定義的類,就必須重寫hashcode()和equals()。
10. 請你解釋一下HashMap具體如何實現?
Hashmap基於陣列實現的,通過對key的hashcode & 陣列的長度得到在陣列中位置,如當前陣列有元素,則陣列當前元素next指向要插入的元素,這樣來解決hash衝突的,形成了拉鍊式的結構。put時在多執行緒情況下,會形成環從而導致死迴圈。陣列長度一般是2n,從0開始編號,所以hashcode & (2n-1),(2n-1)每一位都是1,這樣會讓雜湊均勻。需要注意的是,HashMap在JDK1.8的版本中引入了紅黑樹結構做優化,當連結串列元素個數大於等於8時,連結串列轉換成樹結構;若桶中連結串列元素個數小於等於6時,樹結構還原成連結串列。因為紅黑樹的平均查詢長度是log(n),長度為8的時候,平均查詢長度為3,如果繼續使用連結串列,平均查詢長度為8/2=4,這才有轉換為樹的必要。連結串列長度如果是小於等於6,6/2=3,雖然速度也很快的,但是轉化為樹結構和生成樹的時間並不會太短。還有選擇6和8,中間有個差值7可以有效防止連結串列和樹頻繁轉換。假設一下,如果設計成連結串列個數超過8則連結串列轉換成樹結構,連結串列個數小於8則樹結構轉換成連結串列,如果一個HashMap不停的插入、刪除元素,連結串列個數在8左右徘徊,就會頻繁的發生樹轉連結串列、連結串列轉樹,效率會很低。
11. 請你說明一下Map和ConcurrentHashMap的區別?
hashmap是執行緒不安全的,put時在多執行緒情況下,會形成環從而導致死迴圈。CoucurrentHashMap是執行緒安全的,採用分段鎖機制,減少鎖的粒度。