1. 常見的集合有哪些?
- 答案
-
Collection接口的子接口包括:Set接口和List接口
-
Map接口的實(shí)現(xiàn)類主要有:HashMap、TreeMap、Hashtable、ConcurrentHashMap以及Properties等
-
Set接口的實(shí)現(xiàn)類主要有:HashSet、TreeSet、LinkedHashSet等
-
List接口的實(shí)現(xiàn)類主要有:ArrayList、LinkedList、Stack以及Vector等
-
2. 常見的集合底層實(shí)現(xiàn)
-
答案
ArrayList底層是數(shù)組。
LinkedList底層是雙向鏈表。
HashMap底層與HashTable原理相同,Java 8版本以后如果同一位置哈希沖突大于8則鏈表變成紅黑樹。
HashTable底層是鏈地址法組成的哈希表(即數(shù)組+單項(xiàng)鏈表組成)。
HashSet底層是HashMap。
LinkedHashMap底層修改自HashMap,包含一個維護(hù)插入順序的雙向鏈表。
TreeMap底層是紅黑樹。
LinkedHashSet底層是LinkedHashMap。
TreeSet底層是TreeMap。
3. HashMap與HashTable的區(qū)別?
-
答案
HashMap沒有考慮同步,是線程不安全的;Hashtable使用了synchronized關(guān)鍵字,是線程安全的;
HashMap允許K / V都為null;后者K / V都不允許為null。
4. ConcurrentHashMap和Hashtable的區(qū)別?
-
答案
ConcurrentHashMap結(jié)合了HashMap和HashTable二者的優(yōu)勢。HashMap沒有考慮同步,HashTable考慮了同步的問題。但是HashTable在每次同步執(zhí)行時都要鎖住整個結(jié)構(gòu)。ConcurrentHashMap鎖的方式是稍微細(xì)粒度的。
5. ConcurrentHashMap實(shí)現(xiàn)原理
-
答案
**JDK1.7 : 【數(shù)組(Segment) + 數(shù)組(HashEntry) + 鏈表(HashEntry節(jié)點(diǎn))】
**ConcurrentHashMap(分段鎖) 對整個桶數(shù)組進(jìn)行了分割分段(Segment),每一把鎖只鎖容器其中一部分?jǐn)?shù)據(jù),多線程訪問容器里不同數(shù)據(jù)段的數(shù)據(jù),就不會存在鎖競爭,提高并發(fā)訪問率。Segment是一種可重入鎖ReentrantLock,在ConcurrentHashMap里扮演鎖的角色,
HashEntry則用于存儲鍵值對數(shù)據(jù)。JDK1.8 : Node數(shù)組+鏈表 / 紅黑樹
利用CAS+Synchronized來保證并發(fā)更新的安全,底層依然采用數(shù)組+鏈表+紅黑樹的存儲結(jié)構(gòu)。
6. ArrayList和Vector的區(qū)別?
-
答案
Vector是線程安全的,ArrayList是線程不安全的。
Vector在數(shù)據(jù)滿時增長為原來的兩倍,而ArrayList在數(shù)據(jù)量達(dá)到容量的一半時,增長為原容量的1.5倍。
7. ArrayList和LinkedList的區(qū)別?
-
答案
LinkedList基于雙向鏈表的數(shù)據(jù)結(jié)構(gòu);ArrayList基于動態(tài)數(shù)組的數(shù)據(jù)結(jié)構(gòu)。
LinkedList在插入和刪除數(shù)據(jù)時效率更高,ArrayList查詢效率更高。
8. HashMap默認(rèn)的初始化長度是多少?
-
答案
在JDK中默認(rèn)長度是16,并且默認(rèn)長度和擴(kuò)容后的長度都必須是2的冪。
9. 談?wù)剬ashMap構(gòu)造方法中初始容量、加載因子的理解
-
答案
初始容量代表了哈希表中桶的初始數(shù)量,即Entry<K,V>[] table數(shù)組的初始長度。
加載因子是哈希表在其容量自動增加之前可以達(dá)到多滿的一種飽和度百分比,其衡量了一個散列表的空間的使用程度,負(fù)載因子越大表示散列表的裝填程度越高,反之愈小。
10. Java集合框架是什么?說出一些集合框架的優(yōu)點(diǎn)?
-
答案
每種編程語言中都有集合,最初的Java版本包含幾種集合類:Vector、Stack、HashTable和Array。隨著集合的廣泛使用,Java1.2提出了囊括所有集合接口、實(shí)現(xiàn)和算法的集合框架。在保證線程安全的情況下使用泛型和并發(fā)集合類,Java已經(jīng)經(jīng)歷了很久。它還包括在Java并發(fā)包中,阻塞接口以及它們的實(shí)現(xiàn)。集合框架的部分優(yōu)點(diǎn)如下:
(1)使用核心集合類降低開發(fā)成本,而非實(shí)現(xiàn)我們自己的集合類。
(2)隨著使用經(jīng)過嚴(yán)格測試的集合框架類,代碼質(zhì)量會得到提高。
(3)通過使用JDK附帶的集合類,可以降低代碼維護(hù)成本。
(4)復(fù)用性和可操作性。
11. 集合框架中的泛型有什么優(yōu)點(diǎn)?
-
答案
Java1.5引入了泛型,所有的集合接口和實(shí)現(xiàn)都大量地使用它。泛型允許我們?yōu)榧咸峁┮粋€可以容納的對象類型,因此,如果你添加其它類型的任何元素,它會在編譯時報(bào)錯。這避免了在運(yùn)行時出現(xiàn)ClassCastException,因?yàn)槟銓诰幾g時得到報(bào)錯信息。泛型也使得代碼整潔,我們不需要使用顯式轉(zhuǎn)換和instanceOf操作符。它也給運(yùn)行時帶來好處,因?yàn)椴粫a(chǎn)生類型檢查的字節(jié)碼指令。
12. 為何Collection不從Cloneable和Serializable接口繼承?
-
答案
Collection接口指定一組對象,對象即為它的元素。如何維護(hù)這些元素由Collection的具體實(shí)現(xiàn)決定。例如,一些如List的Collection實(shí)現(xiàn)允許重復(fù)的元素,而其它的如Set就不允許。很多Collection實(shí)現(xiàn)有一個公有的clone方法。然而,把它放到集合的所有實(shí)現(xiàn)中也是沒有意義的。這是因?yàn)镃ollection是一個抽象表現(xiàn)。重要的是實(shí)現(xiàn)。
當(dāng)與具體實(shí)現(xiàn)打交道的時候,克隆或序列化的語義和含義才發(fā)揮作用。所以,具體實(shí)現(xiàn)應(yīng)該決定如何對它進(jìn)行克隆或序列化,或它是否可以被克隆或序列化。
在所有的實(shí)現(xiàn)中授權(quán)克隆和序列化,最終導(dǎo)致更少的靈活性和更多的限制。特定的實(shí)現(xiàn)應(yīng)該決定它是否可以被克隆和序列化。
13. Iterator是什么?
-
答案
Iterator接口提供遍歷任何Collection的接口。我們可以從一個Collection中使用迭代器方法來獲取迭代器實(shí)例。迭代器取代了Java集合框架中的Enumeration。迭代器允許調(diào)用者在迭代過程中移除元素。
14. Iterator和Listiterator之間有什么區(qū)別?
-
答案
(1)我們可以使用Iterator來遍歷Set和List集合,而ListIterator只能遍歷List。
(2)Iterator只可以向前遍歷,而LIstIterator可以雙向遍歷。
(3)ListIterator從Iterator接口繼承,然后添加了一些額外的功能,比如添加一個元素、替換一個元素、獲取前面或后面元素的索引位置。
15. fail-fast與fail-safe有什么區(qū)別?
-
答案
Iterator的fail-fast屬性與當(dāng)前的集合共同起作用,因此它不會受到集合中任何改動的影響。Java.util包中的所有集合類都被設(shè)計(jì)為fail-fast的,而java.util.concurrent中的集合類都為fail-safe的。Fail-fast迭代器拋出ConcurrentModificationException,而fail-safe迭代器從不拋出ConcurrentModificationException。
16. hashCode()和equals()方法有何重要性?
-
答案
HashMap使用Key對象的hashCode()和equals()方法去決定key-value對的索引。當(dāng)我們試著從HashMap中獲取值的時候,這些方法也會被用到。如果這些方法沒有被正確地實(shí)現(xiàn),在這種情況下,兩個不同Key也許會產(chǎn)生相同的hashCode()和equals()輸出,HashMap將會認(rèn)為它們是相同的,然后覆蓋它們,而非把它們存儲到不同的地方。同樣的,所有不允許存儲重復(fù)數(shù)據(jù)的集合類都使用hashCode()和equals()去查找重復(fù),所以正確實(shí)現(xiàn)它們非常重要。
equals()和hashCode()的實(shí)現(xiàn)應(yīng)該遵循以下規(guī)則:(1)如果o1.equals(o2),那么o1.hashCode() == o2.hashCode()總是為true的。
(2)如果o1.hashCode() == o2.hashCode(),并不意味著o1.equals(o2)會為true。
17. 我們能否使用任何類作為Map的key?
-
答案
我們可以使用任何類作為Map的key,然而在使用它們之前,需要考慮以下幾點(diǎn):
-
如果類重寫了equals()方法,它也應(yīng)該重寫hashCode()方法。
-
類的所有實(shí)例需要遵循與equals()和hashCode()相關(guān)的規(guī)則。請參考之前提到的這些規(guī)則。
-
如果一個類沒有使用equals(),你不應(yīng)該在hashCode()中使用它。
-
用戶自定義key類的最佳實(shí)踐是使之為不可變的,這樣,hashCode()值可以被緩存起來,擁有更好的性能。不可變的類也可以確保hashCode()和equals()在未來不會改變,這樣就會解決與可變相關(guān)的問題了。
-
18. 如何決定選用HashMap還是TreeMap?
-
答案
對于在Map中插入、刪除和定位元素這類操作,HashMap是最好的選擇。然而,假如你需要對一個有序的key集合進(jìn)行遍歷,TreeMap是更好的選擇?;谀愕腸ollection的大小,也許向HashMap中添加元素會更快,將map換為TreeMap進(jìn)行有序key的遍歷。
19. 哪些集合類提供對元素的隨機(jī)訪問?
-
答案
ArrayList、HashMap、TreeMap和HashTable類提供對元素的隨機(jī)訪問。
20. BlockingQueue是什么?
強(qiáng)引用
這種引用屬于最普通最強(qiáng)硬的一種存在,只有在和 GC Roots 斷絕關(guān)系時,才會被消掉。
軟引用
軟引用用于維護(hù)一些可有可無的對象。在內(nèi)存足夠的時候,軟引用對象不會被回收,只有在內(nèi)
存不足時,系統(tǒng)則會回收軟引用對象,如果回收了軟引用對象之后仍然沒有足夠的內(nèi)存,才會
拋出內(nèi)存溢出異常。
可以看到,這種特性非常適合用在緩存技術(shù)上。比如網(wǎng)頁緩存、圖片緩存等。
軟引用可以和一個引用隊(duì)列(ReferenceQueue)聯(lián)合使用,如果軟引用所引用的對象被垃圾
回收,Java 虛擬機(jī)就會把這個軟引用加入到與之關(guān)聯(lián)的引用隊(duì)列中。
弱引用
弱引用對象相比較軟引用,要更加無用一些,它擁有更短的生命周期。當(dāng)JVM進(jìn)行垃圾回收
時,無論內(nèi)存是否充足,都會回收被弱引用關(guān)聯(lián)的對象。弱引用擁有更短的生命周期,在 Java
中,用 java.lang.ref.WeakReference 類來表示。它的應(yīng)用場景和軟引用類似,可以在一些對
內(nèi)存更加敏感的系統(tǒng)里采用。
虛引用
這是一種形同虛設(shè)的引用,在現(xiàn)實(shí)場景中用的不是很多。虛引用必須和引用隊(duì)列
(ReferenceQueue)聯(lián)合使用。如果一個對象僅持有虛引用,那么它就和沒有任何引用一
樣,在任何時候都可能被垃圾回收。實(shí)際上,虛引用的 get,總是返回 null。
Java.util.concurrent.BlockingQueue是一個隊(duì)列,在進(jìn)行檢索或移除一個元素的時候,它會等待隊(duì)列變?yōu)榉强眨划?dāng)在添加一個元素時,它會等待隊(duì)列中的可用空間。BlockingQueue接口是Java集合框架的一部分,主要用于實(shí)現(xiàn)生產(chǎn)者-消費(fèi)者模式。我們不需要擔(dān)心等待生產(chǎn)者有可用的空間,或消費(fèi)者有可用的對象,因?yàn)樗荚贐lockingQueue的實(shí)現(xiàn)類中被處理了。
Java提供了集中BlockingQueue的實(shí)現(xiàn),比如ArrayBlockingQueue、LinkedBlockingQueue、PriorityBlockingQueue、SynchronousQueue等。
經(jīng)常和線程池中的workQueue夢幻聯(lián)動。
21. Collections類是什么?
-
答案
Java.util.Collections是一個工具類僅包含靜態(tài)方法,它們操作或返回集合。它包含操作集合的多態(tài)算法,返回一個由指定集合支持的新集合和其它一些內(nèi)容。這個類包含集合框架算法的方法,比如折半搜索、排序、混編和逆序等。
22. Comparable和Comparator接口有何區(qū)別?
-
答案
Comparable和Comparator接口被用來對對象集合或者數(shù)組進(jìn)行排序。
Comparable接口被用來提供對象的自然排序,我們可以使用它來提供基于單個邏輯的排序。
Comparable接口實(shí)際上是出自java.lang包,它有一個compareTo(Object obj)方法用來排序。Comparator接口被用來提供不同的排序算法,我們可以選擇需要使用的Comparator來對給定的對象集合進(jìn)行排序。
Comparator接口實(shí)際上是出自java.util包,它有一個compare(Object obj1, Object obj2)方法用來排序。
本文摘自 :https://www.cnblogs.com/