叮~五一勞動節也不要忘記學習呦!

叮~五一勞動節也不要忘記學習呦!

面試題一

為什麼使用ConcurrentHashMap而不是HashMap或Hashtable?

HashMap的缺點:主要是多線程同時put時,如果同時觸發了rehash操作,會導致HashMap中的鏈表中出現循環節點,進而使得後面get的時候,會死循環,CPU達到100%,所以在併發情況下不能使用HashMap。讓HashMap同步:Map m = Collections.synchronizeMap(hashMap);而Hashtable雖然是同步的,使用synchronized來保證線程安全,但在線程競爭激烈的情況下HashTable的效率非常低下。因為當一個線程訪問HashTable的同步方法時,其他線程訪問HashTable的同步方法時,可能會進入阻塞或輪詢狀態。如線程1使用put進行添加元素,線程2不但不能使用put方法添加元素,並且也不能使用get方法來獲取元素,所以競爭越激烈效率越低。

ConcurrentHashMap的原理:

HashTable容器在競爭激烈的併發環境下表現出效率低下的原因在於所有訪問HashTable的線程都必須競爭同一把鎖,那假如容器裡有多把鎖,每一把鎖用於鎖容器其中一部分數據,那麼當多線程訪問容器裡不同數據段的數據時,線程間就不會存在鎖競爭,從而可以有效的提高併發訪問效率,這就是ConcurrentHashMap所使用的鎖分段技術,首先將數據分成一段一段的存儲,然後給每一段數據配一把鎖,當一個線程佔用鎖訪問其中一個段數據的時候,其他段的數據也能被其他線程訪問。

ConcurrentHashMap的結構:

ConcurrentHashMap是由Segment數組結構和HashEntry數組結構組成。Segment是一種可重入互斥鎖ReentrantLock,在ConcurrentHashMap裡扮演鎖的角色,HashEntry則用於存儲鍵值對數據。一個ConcurrentHashMap裡包含一個Segment數組,Segment的結構和HashMap類似,是一種數組和鏈表結構, 一個Segment裡包含一個HashEntry數組,每個HashEntry是一個鏈表結構的元素,當對某個HashEntry數組的數據進行修改時,必須首先獲得它對應的Segment鎖。

ConcurrentHashMap的構造、get、put操作:

構造函數:傳入參數分別為 1、初始容量,默認16 2、裝載因子 裝載因子用於rehash的判定,就是當ConcurrentHashMap中的元素大於裝載因子*最大容量時進行擴容,默認0.75 3、併發級別 這個值用來確定Segment的個數,Segment的個數是大於等於concurrencyLevel的第一個2的n次方的數。比如,如果concurrencyLevel為12,13,14,15,16這些數,則Segment的數目為16(2的4次方)。默認值為static final int DEFAULT_CONCURRENCY_LEVEL = 16;。理想情況下ConcurrentHashMap的真正的併發訪問量能夠達到concurrencyLevel,因為有concurrencyLevel個Segment,假如有concurrencyLevel個線程需要訪問Map,並且需要訪問的數據都恰好分別落在不同的Segment中,則這些線程能夠無競爭地自由訪問(因為他們不需要競爭同一把鎖),達到同時訪問的效果。這也是為什麼這個參數起名為“併發級別”的原因。

面試題二

HashMap的工作原理

HashMap維護了一個Entry數組,Entry內部類有key,value,hash和next四個字段,其中next也是一個Entry類型。可以將Entry數組理解為一個個的散列桶。每一個桶實際上是一個單鏈表。當執行put操作時,會根據key的hashcode定位到相應的桶。遍歷單鏈表檢查該key是否已經存在,如果存在,覆蓋該value,反之,新建一個新的Entry,並放在單鏈表的頭部。當通過傳遞key調用get方法時,它再次使用key.hashCode()來找到相應的散列桶,然後使用key.equals()方法找出單鏈表中正確的Entry,然後返回它的值。

面試題三

Map、Set、List、Queue、Stack的特點與用法

Set集合類似於一個罐子,"丟進"Set集合裡的多個對象之間沒有明顯的順序。 List集合代表元素有序、可重複的集合,集合中每個元素都有其對應的順序索引。 Stack是Vector提供的一個子類,用於模擬"棧"這種數據結構(LIFO後進先出) Queue用於模擬"隊列"這種數據結構(先進先出 FIFO)。 Map用於保存具有"映射關係"的數據,因此Map集合裡保存著兩組值。


分享到:


相關文章: