天天看點

卷妹帶你回顧Java基礎(一)每日更新Day6

卷妹帶你回顧Java基礎(一)每日更新Day6

👩‍💻部落格首頁:京與舊鋪的部落格首頁

✨歡迎關注🖱點贊🎀收藏⭐留言✒

🔮本文由京與舊鋪原創

😘系列專欄:java學習

👕參考網站:牛客網

💻首發時間:🎞2022年8月9日🎠

🎨你做三四月的事,八九月就會有答案,一起加油吧

🀄如果覺得部落客的文章還不錯的話,請三連支援一下部落客哦

🎧最後的話,作者是一個新人,在很多方面還做的不好,歡迎大佬指正,一起學習哦,沖沖沖

💬推薦一款模拟面試、刷題神器👉​​點選進入網站​​

🛒導航小助手🎪

文章目錄

  • ​​卷妹帶你回顧Java基礎(一)每日更新Day6​​
  • ​​🛒導航小助手🎪​​
  • ​​2.21 請介紹TreeMap的底層原理​​
  • ​​2.24 ArrayList和LinkedList有什麼差別?​​
  • ​​2.25 有哪些線程安全的List?​​
  • ​​2.26 介紹一下ArrayList的資料結構?​​
  • ​​2.27 談談CopyOnWriteArrayList的原理​​
  • ​​2.28 說一說TreeSet和HashSet的差別​​
  • ​​2.29 說一說HashSet的底層結構​​

2.21 請介紹TreeMap的底層原理

參考答案

TreeMap基于紅黑樹(Red-Black tree)實作。映射根據其鍵的自然順序進行排序,或者根據建立映射時提供的 Comparator 進行排序,具體取決于使用的構造方法。TreeMap的基本操作containsKey、get、put、remove方法,它的時間複雜度是log(N)。

TreeMap包含幾個重要的成員變量:root、size、comparator。其中root是紅黑樹的根節點。它是Entry類型,Entry是紅黑樹的節點,它包含了紅黑樹的6個基本組成:key、value、left、right、parent和color。Entry節點根據根據Key排序,包含的内容是value。Entry中key比較大小是根據比較器comparator來進行判斷的。size是紅黑樹的節點個數。

2.24 ArrayList和LinkedList有什麼差別?

參考答案

  1. ArrayList的實作是基于數組,LinkedList的實作是基于雙向連結清單;
  2. 對于随機通路ArrayList要優于LinkedList,ArrayList可以根據下标以O(1)時間複雜度對元素進行随機通路,而LinkedList的每一個元素都依靠位址指針和它後一個元素連接配接在一起,查找某個元素的時間複雜度是O(N);
  3. 對于插入和删除操作,LinkedList要優于ArrayList,因為當元素被添加到LinkedList任意位置的時候,不需要像ArrayList那樣重新計算大小或者是更新索引;
  4. LinkedList比ArrayList更占記憶體,因為LinkedList的節點除了存儲資料,還存儲了兩個引用,一個指向前一個元素,一個指向後一個元素。

2.25 有哪些線程安全的List?

參考答案

  1. Vector

    Vector是比較古老的API,雖然保證了線程安全,但是由于效率低一般不建議使用。

  2. Collections.SynchronizedList

    SynchronizedList是Collections的内部類,Collections提供了synchronizedList方法,可以将一個線程不安全的List包裝成線程安全的List,即SynchronizedList。它比Vector有更好的擴充性和相容性,但是它所有的方法都帶有同步鎖,也不是性能最優的List。

  3. CopyOnWriteArrayList

    CopyOnWriteArrayList是Java 1.5在java.util.concurrent包下增加的類,它采用複制底層數組的方式來實作寫操作。當線程對此類集合執行讀取操作時,線程将會直接讀取集合本身,無須加鎖與阻塞。當線程對此類集合執行寫入操作時,集合會在底層複制一份新的數組,接下來對新的數組執行寫入操作。由于對集合的寫入操作都是對數組的副本執行操作,是以它是線程安全的。在所有線程安全的List中,它是性能最優的方案。

2.26 介紹一下ArrayList的資料結構?

參考答案

ArrayList的底層是用數組來實作的,預設第一次插入元素時建立大小為10的數組,超出限制時會增加50%的容量,并且資料以 System.arraycopy() 複制到新的數組,是以最好能給出數組大小的預估值。

按數組下标通路元素的性能很高,這是數組的基本優勢。直接在數組末尾加入元素的性能也高,但如果按下标插入、删除元素,則要用 System.arraycopy() 來移動部分受影響的元素,性能就變差了,這是基本劣勢。

2.27 談談CopyOnWriteArrayList的原理

參考答案

CopyOnWriteArrayList是Java并發包裡提供的并發類,簡單來說它就是一個線程安全且讀操作無鎖的ArrayList。正如其名字一樣,在寫操作時會複制一份新的List,在新的List上完成寫操作,然後再将原引用指向新的List。這樣就保證了寫操作的線程安全。

CopyOnWriteArrayList允許線程并發通路讀操作,這個時候是沒有加鎖限制的,性能較高。而寫操作的時候,則首先将容器複制一份,然後在新的副本上執行寫操作,這個時候寫操作是上鎖的。結束之後再将原容器的引用指向新容器。注意,在上鎖執行寫操作的過程中,如果有需要讀操作,會作用在原容器上。是以上鎖的寫操作不會影響到并發通路的讀操作。

  • 優點:讀操作性能很高,因為無需任何同步措施,比較适用于讀多寫少的并發場景。在周遊傳統的List時,若中途有别的線程對其進行修改,則會抛出ConcurrentModificationException異常。而CopyOnWriteArrayList由于其"讀寫分離"的思想,周遊和修改操作分别作用在不同的List容器,是以在使用疊代器進行周遊時候,也就不會抛出ConcurrentModificationException異常了。
  • 缺點:一是記憶體占用問題,畢竟每次執行寫操作都要将原容器拷貝一份,資料量大時,對記憶體壓力較大,可能會引起頻繁GC。二是無法保證明時性,Vector對于讀寫操作均加鎖同步,可以保證讀和寫的強一緻性。而CopyOnWriteArrayList由于其實作政策的原因,寫和讀分别作用在新老不同容器上,在寫操作執行過程中,讀不會阻塞但讀取到的卻是老容器的資料。

2.28 說一說TreeSet和HashSet的差別

參考答案

HashSet、TreeSet中的元素都是不能重複的,并且它們都是線程不安全的,二者的差別是:

  1. HashSet中的元素可以是null,但TreeSet中的元素不能是null;
  2. HashSet不能保證元素的排列順序,而TreeSet支援自然排序、定制排序兩種排序的方式;
  3. HashSet底層是采用哈希表實作的,而TreeSet底層是采用紅黑樹實作的。

2.29 說一說HashSet的底層結構