Java面試02|Java集合

Java中一般接觸到的集合如下圖:

關於Java中併發集合有:

(1)CouncurrentHashMap

(2)CopyOnWriteArrayList

(3)LinkedBlockingQueue

(4)ArrayBlockingQueue 

這些的適用場景及其實現原理是必須要掌握的。

 

1、Hash的死鎖原因

 

參考:HashMap 死鎖分析 http://github.thinkingbar.com/hashmap-infinite-loop/

 

2、關於ConcurrentHashMap相關的問題

ConcurrentHashMap的1.7與1.8的實現差別很大,可以參考文章:

(1)談談ConcurrentHashMap1.7和1.8的不同實現 http://www.jianshu.com/p/e694f1e868ec 

(2)https://zhuanlan.zhihu.com/p/21673805

 

下面關於ConcurrentHashMap必須要知道的幾個問題:

(1)ConcurrentHashMap的鎖分段技術。

(2)ConcurrentHashMap的讀是否要加鎖,爲什麼。

(3)ConcurrentHashMap的迭代器是強一致性的迭代器還是弱一致性的迭代器。

 迭代器在遍歷底層數組。在遍歷過程中,如果已經遍歷的數組上的內容變化了,迭代器不會拋出ConcurrentModificationException異常。如果未遍歷的數組上的內容發生了變化,則有可能反映到迭代過程中。這就是ConcurrentHashMap迭代器弱一致的表現

 

ConcurrentHashMap的結構大概如下所示。

 

 

3、LinkedHashMap的應用

 

LinkedHashMap維護着一個運行於所有條目的雙重鏈接列表。此鏈接列表定義了迭代順序,該迭代順序可以是插入順序(insert-order)或者是訪問順序,其中默認的迭代訪問順序就是插入順序,即可以按插入的順序遍歷元素。基於LinkedHashMap的訪問順序的特點,可構造一個LRU(Least Recently Used)最近最少使用簡單緩存。也有一些開源的緩存產品如ehcache的淘汰策略(LRU)就是在LinkedHashMap上擴展的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public  class  LruCache<K, V>  extends  LinkedHashMap<K, V> { 
             /** 最大容量 */ 
             private  int  maxCapacity; 
          
             public  LruCache( int  maxCapacity) { 
                 super ( 16 0 .75f,  true ); 
                 this .maxCapacity = maxCapacity; 
            
          
             public  int  getMaxCapacity() { 
                 return  this .maxCapacity; 
            
          
             public  void  setMaxCapacity( int  maxCapacity) { 
                 this .maxCapacity = maxCapacity; 
            
          
             /**
              * 當列表中的元素個數大於指定的最大容量時,返回true,並將最老的元素刪除。
              */ 
             @Override 
             protected  boolean  removeEldestEntry(java.util.Map.Entry<K, V> eldest) { 
                 if  ( super .size() > maxCapacity) { 
                     return  true
                
                 return  false
            
        

  

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public  class  LruCacheTest { 
          
             public  static  void  main(String[] args) { 
                 LruCache<String, Object> cache =  new  LruCache<String, Object>( 10 ); 
          
                 for  ( int  i =  1 ; i <=  15 ; i++) { 
                     cache.put(i +  "" , i); 
                
          
                 // 此時訪問指定KEY的元素 
                 cache.get( "10" ); 
          
                 Iterator<Entry<String, Object>> iterator = cache.entrySet().iterator(); 
                 for  (; iterator.hasNext();) { 
                     Entry<String, Object> entry = iterator.next(); 
                     System.out.println( "key="  + entry.getKey() +  ",value="  + entry.getValue()); 
                
            
        

輸出如下:

            
        

輸出如下:

1
2
3
相關文章
相關標籤/搜索