[面試原題]java
[題目一] Java的HashMap是如何工做的?面試
[正確答案]算法
博爲峯小博老師:數組
HashMap是一個針對數據結構的鍵值,每一個鍵都會有相應的值,關鍵是識別這樣的值。緩存
HashMap 基於 hashing 原理,咱們經過 put ()和 get ()方法儲存和獲取對象。當咱們將鍵值對傳遞給 put ()方法時,它調用鍵對象的 hashCode ()方法來計算 hashcode,讓後找到 bucket 位置來儲存值對象。當獲取對象時,經過鍵對象的 equals ()方法找到正確的鍵值對,而後返回值對象。HashMap 使用 LinkedList 來解決碰撞問題,當發生碰撞了,對象將會儲存在 LinkedList 的下一個節點中。 HashMap 在每一個 LinkedList 節點中儲存鍵值對對象。安全
[正確答案]數據結構
博爲峯小博老師:多線程
快速失敗的Java迭代器可能會引起ConcurrentModifcationException在底層集合迭代過程當中被修改。故障安全做爲發生在實例中的一個副本迭代是不會拋出任何異常的。快速失敗的故障安全範例定義了當遭遇故障時系統是如何反應的。例如,用於失敗的快速迭代器ArrayList和用於故障安全的迭代器ConcurrentHashMap。併發
[正確答案]性能
在問題二中咱們看到ConcurrentHashMap被做爲故障安全迭代器的一個實例,它容許完整的併發檢索和更新。當有大量的併發更新時,ConcurrentHashMap此時能夠被使用。這很是相似於Hashtable,但ConcurrentHashMap不鎖定整個表來提供併發,因此從這點上ConcurrentHashMap的性能彷佛更好一些。因此當有大量更新時ConcurrentHashMap應該被使用。
[題目四] List怎麼實現了最快插入?
[正確答案]
LinkedList和ArrayList是另個不一樣變量列表的實現。ArrayList的優點在於動態的增加數組,很是適合初始時總長度未知的狀況下使用。LinkedList的優點在於在中間位置插入和刪除操做,速度是最快的。
LinkedList實現了List接口,容許null元素。此外LinkedList提供額外的get,remove,insert方法在LinkedList的首部或尾部。這些操做使LinkedList可被用做堆棧(stack),隊列(queue)或雙向隊列(deque)。
ArrayList實現了可變大小的數組。它容許全部元素,包括null。 每一個ArrayList實例都有一個容量(Capacity),即用於存儲元素的數組的大小。這個容量可隨着不斷添加新元素而自動增長,可是增加算法並無定義。當須要插入大量元素時,在插入前能夠調用ensureCapacity方法來增長ArrayList的容量以提升插入效率。
[題目五] 如何保證一個集合線程安全?
[正確答案]
Vector, Hashtable, Properties 和 Stack 都是同步的類,因此它們都線程安全的,能夠被使用在多線程環境中
. 使用Collections.synchronizedList(list)) 方法,能夠保證 list 類是線程安全的
· 使用java.util.Collections.synchronizedSet() 方法能夠保證 set 類是線程安全的
[題目六] hashCode()和equals()方法有何重要性?
[正確答案]
HashMap使用Key對象的hashCode()和equals()方法去決定key-value對的索引。當咱們試着從HashMap中獲取值的時候,這些方法也會被用到。若是這些方法沒有被正確地實現,在這種狀況下,兩個不一樣Key也許會產生相同的hashCode()和equals()輸出,HashMap將會認爲它們是相同的,而後覆蓋它們,而非把它們存儲到不一樣的地方。一樣的,全部不容許存儲重複數據的集合類都使用hashCode()和equals()去查找重複,因此正確實現它們很是重要。equals()和hashCode()的實現應該遵循如下規則:
1.若是o1.equals(o2),那麼o1.hashCode() == o2.hashCode()老是爲true的。
2.若是o1.hashCode() == o2.hashCode(),並不意味着o1.equals(o2)會爲true。
[題目七] 可否使用任何類做爲Map的key?
[正確答案]
咱們可使用任何類做爲Map的key,然而在使用它們以前,須要考慮如下幾點:
(1)若是類重寫了equals()方法,它也應該重寫hashCode()方法。
(2)類的全部實例須要遵循與equals()和hashCode()相關的規則。請參考以前提到的這些規則。
(3)若是一個類沒有使用equals(),你不該該在hashCode()中使用它。
(4)用戶自定義key類的最佳實踐是使之爲不可變的,這樣,hashCode()值能夠被緩存起來,擁有更好的性能。不可變的類也能夠確保hashCode()和equals()在將來不會改變,這樣就會解決與可變相關的問題了。
這就是爲什麼String和Integer被做爲HashMap的key大量使用。
[題目八] 咱們如何對一組對象進行排序?
[正確答案]
若是咱們須要對一個對象數組進行排序,咱們可使用Arrays.sort()方法。若是咱們須要排序一個對象列表,咱們可使用Collection.sort()方法。兩個類都有用於天然排序(使用Comparable)或基於標準的排序(使用Comparator)的重載方法sort()。Collections內部使用數組排序方法,全部它們二者都有相同的性能,只是Collections須要花時間將列表轉換爲數組。
[題目九] 併發集合類是什麼?
[正確答案]
Java1.5併發包(java.util.concurrent)包含線程安全集合類,容許在迭代時修改集合。迭代器被設計爲fail-fast的,會拋出ConcurrentModificationException。一部分類爲:CopyOnWriteArrayList、 ConcurrentHashMap、CopyOnWriteArraySet。
[題目十] 隊列和棧是什麼,列出它們的區別?
[正確答案]
棧和隊列二者都被用來預存儲數據。java.util.Queue是一個接口,它的實現類在Java併發包中。隊列容許先進先出(FIFO)檢索元素,但並不是老是這樣。Deque接口容許從兩端檢索元素。
棧與隊列很類似,但它容許對元素進行後進先出(LIFO)進行檢索。
Stack是一個擴展自Vector的類,而Queue是一個接口。