Java常考面試題(五)

一杯涼茶發表於2016-11-17

      序言

         好好努力。

                                                                        ---WH

 

 

一、Iterator和ListIterator的區別是什麼?

      自我解答:

            Iterator是針對所有collection來使用的,而看名字ListIterator,顧名思義,就是給list集合特有的,增加了其他專有的方法吧。

      參考答案:

            下面列出了他們的區別:
              Iterator可用來遍歷Set和List集合,但是ListIterator只能用來遍歷List。
              Iterator對集合只能是前向遍歷,ListIterator既可以前向也可以後向。
              ListIterator繼承了Iterator介面,幷包含其他的功能,比如:增加元素,替換元素,獲取前一個和後一個元素的索引,等等。

 

      自我評價:

            首先第一映像,我只看過Iterator,第二個ListIterator我是沒聽過的,但是通過這麼久的學習,我可以看出,ListIterator就是隻能給list集合用,而不是給其他集合,

            1、Iterator:是介面,能給所有的集合使用

            2、ListIterator:也是介面,繼承了Iterator介面,同時肯定對Iterator介面中的方法進行了增強

                ·ListIterator只能對list集合迭代,

                ·ListIterator不僅能向後迭代,也能想前迭代

                ·ListIterator還能增加元素和刪除元素,並且還能獲得前一個元素和後一個元素

             

        注意:使用Iterator迭代的時候需要注意幾個問題

           1、xx.next(); 每次使用這個,就會往後面推一位,也就是索引會往後移一位,

             2、xx.hasNext(); 當檢測到後面沒有值了,返回false,但是指向器還是會往後面移一位。指向最後一位的後一位,這也是在ListIterator發現的,使用Iterator沒有這個考慮,無所謂,因為只有ListIterator才有往前迭代的方法,所以才有前面這一大堆話。

           3、ListIterator使用xx.add();在當前索引的後面增加,不是替代當前索引的值

             4、ListIterator使用xx.set(E);將當前索引的值給替換成我們給定的值

 

 

二、快速失敗(fail-fast)和安全失敗(fail-safe)的區別是什麼?

      自我解答:

            這個沒接觸過。。。

      參考答案:

            Iterator的安全失敗是基於對底層集合做拷貝,因此,它不受源集合上修改的影響。

            java.util包下面的所有的集合類都是快速失敗的,快速失敗的迭代器會丟擲ConcurrentModificationException異常

            java.util.concurrent包下面的所有的類都是安全失敗的。,而安全失敗的迭代器永遠不會丟擲這樣的異常。

 

      自我評價:

            先說一下,這個題目花了我兩個多小時,才徹底弄明白,但是還是很有效果的,比如,我檢視了Iterator實現的原始碼,和之前看ArrayList原始碼時不懂得地方都弄清楚了,Iterator實現的原理和ArrayList原始碼分析我會在別的文章中寫出來,到時候可以看看。現在來解決這個問題

            1、fail-fast 和 fail-safe 這兩個針對的是Iterator,

            2、fail-fast:快速失敗,在那些不是執行緒安全的集合使用Iterator時發生的問題,因為在迭代的時候,有別的執行緒對集合內部的構造進行了改變,比如,add、delete這類操作,都會使之發生快速失敗。

            3、fail-safe:安全失敗,線上程安全的集合中發生上面的問題,就會出現該fail-safe了。

              因為我明白了其中到底發生了什麼,所以,寫上面的文字,我知道意思,可能大家有點不理解,可以先了解一下fail-fast是什麼,推薦博文:http://blog.csdn.net/chenssy/article/details/38151189  這裡面就詳細講解了fail-fast是什麼, 建議先觀看arrayList原始碼,在其中重點了解Iterator的實現,還有modCount是什麼,知道了這些,結合這篇博文和我說的,差不多就瞭解啦。

 

 


3、Java中的HashMap的工作原理是什麼?

    自我解答:

         使用陣列儲存鍵值資料,每個陣列中的位置又是一個連結串列。

    參考答案:

         HashMap的底層是用hash陣列和單向連結串列實現的 ,當呼叫put方法是,首先計算key的hashcode,定位到合適的陣列索引,然後再在該索引上的單向連結串列進行迴圈遍歷用equals比較key是否存在,如果存在則用新的value覆蓋原值,如果沒有則在鏈頭儲存該值。HashMap的兩個重要屬性是容量capacity和載入因子loadfactor,預設值分佈為16和0.75,當容器中的元素個數大於 capacity*loadfactor時,容器會進行擴容resize 為2n,在初始化Hashmap時可以對著兩個值進行修改,負載因子0.75被證明為是效能比較好的取值,通常不會修改,那麼只有初始容量capacity會導致頻繁的擴容行為,這是非常耗費資源的操作,所以,如果事先能估算出容器所要儲存的元素數量,最好在初始化時修改預設容量capacity,以防止頻繁的resize操作影響效能。

 

    自我評價:

           1、沒搞清楚hashMap的儲存結構,雖然看了原始碼,但還是模模糊糊,現在差不多知道了

         2、hashMap是用hash表和單向連結串列來實現儲存資料的,具體模型如下,並且在hashmap中有一個內部類entry,它有四個屬性V、K、next、hash,我們放入的key和value會分別放入entry的K、V中,所以存放的都市entry物件。

                    

        3、首先將key通過hash演算法算出hashcode值,

        4、通過hashcode值找到在hash陣列中對應的位置,然後通過equals方法,遍歷單向連結串列,看有沒有相同的key值,如果有,則替換key所對應的value值,如果沒有,將該資料插入連結串列的開始。

 

四、hashCode()和equals()方法的重要性體現在什麼地方?

    自我解答:

        這個問題可以看我那邊hashcode詳解的文章,因為有hashCode()和equals()兩個方法,使對資料的查詢的效率變得很高,比如set集合中,就用到了這兩個方法,不可以存放相同的值,這裡就得到了體現

    

    參考答案:

        Java中的HashMap使用hashCode()和equals()方法來確定鍵值對的索引,當根據鍵獲取值的時候也會用到這兩個方法。如果沒有正確的實現這兩個方法,兩個不同的鍵可能會有相同的hash值,因此,可能會被集合認為是相等的。而且,這兩個方法也用來發現重複元素。所以這兩個方法的實現對HashMap的精確性和正確性是至關重要的。  

 

    自我評價:

        差不多就是這樣,就解釋一下大概的情況,舉個例子,差不多了。

 

五、HashMap和Hashtable有什麼區別?

    自我解答:

        hashMap是Hashtable的父類,hashtable是執行緒安全的,而hashmap不是。

 

    參考答案:

        HashMap和Hashtable都實現了Map介面,因此很多特性非常相似。但是,他們有以下不同點:
        HashMap允許鍵和值是null,而Hashtable不允許鍵或者值是null。
        Hashtable是同步的,而HashMap不是。因此,HashMap更適合於單執行緒環境,而Hashtable適合於多執行緒環境。
        HashMap提供了可供應用迭代的鍵的集合,因此,HashMap是快速失敗的。另一方面,Hashtable提供了對鍵的列舉(Enumeration)。
        一般認為Hashtable是一個遺留的類。

 

    自我評價:

        map的各種繼承關係模糊了,

        1、hashMap的子類是linkedHashMap

        2、hashTable和hashMap的關係就好像arrayList和Vector的關係差不多

        3、hashTable是同步的,而hashMap是非同步的,也就是一個執行緒安全一個執行緒不安全

        4、hashMap的key值可以為null 而hashTable不可以

        5、具體的可以去看collections集合的那篇總結文章

 

相關文章