1. 程式人生 > >Java面試02|Java集合

Java面試02|Java集合

策略 prot -1 ins return object true 實現 pac

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上擴展的。

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;  
            }  
        }  

  

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());  
                }  
            }  
        }  

輸出如下:

key=7,value=7  
key=8,value=8  
key=9,value=9  
key=11,value=11  
key=12,value=12  
key=13,value=13  
key=14,value=14  
key=15,value=15  
key=10,value=10  

 

Java面試02|Java集合