天天看點

JVM&NIO&HashMap簡單問

JVM&NIO&HashMap簡單問

背景:前幾天在網上看到關于JVM&NIO&HashMap的一些連環炮的面試題,整理下以備不時之需。

一、JVM

Java的虛拟機的面試内容主要包括GC、類加載機制和記憶體三大部分。如下是一個一個GC部分簡單的連環炮:

問:

什麼時候一個對象會被GC?

答:

當沒有任何對象的引用指向該對象時 + 在下次垃圾回收周期來到時,對象才會被回收。

又問:

為什麼要在這種時候對象才會被GC?

因為JVM會自動回收沒有被引用的對象來釋放空間,進而解決記憶體不足問題。

GC政策都有哪些分類?

1、标記-清除算法。

2、複制算法。

3、标記整理算法。

這些政策分别都有什麼優勢and劣勢?都适用于什麼場景?

1、标記-清除算法采用從根集合進行掃描,對存活的對象進行标記,标記完畢後再掃描整個空間中未被标記的對象,對其進行直接回收。其不需要進行對象的移動,并且僅對不存活的對象進行處理,在存活的對象比較多的情況下極為高效,但由于标記-清除算法隻回收不存活的對象,并沒有對還存活的對象進行整理,是以會導緻記憶體碎片。

JVM&NIO&HashMap簡單問

2、複制算法将記憶體劃分為兩個分區,使用此算法時,所有動态配置設定的對象都隻能配置設定在其中一個區間(活動區間),而另外一個區間(空間區間)則是空閑區間。其采用從根集合掃描,将存活的對象複制到空閑區間,當掃描完畢活動區間後,會将活動區間一次性全部回收,此時原本的空閑區間變成了活動區間,下次GC的時候又會重複剛才的操作,以此循環。另外,複制算法在存活對象比較少的時候,極為高效,但是帶來的成本是犧牲一半的記憶體空間用于進行對象的移動,是以複制算法的使用場景必須是對象的存活率非常低才行,而且最重要的是我們需要克服50%記憶體的浪費。

JVM&NIO&HashMap簡單問

3、标記整理算法采用标記-清除算法一樣的方式進行對象的标記、清除,但在回收不存活的對象占用的空間後,會将所有存活的對象往左端空閑空間移動,并更新對應的指針,其算法是在标記-清除算法之上,又進行了對象的移動排序整理,是以成本更高,但卻解決了記憶體碎片的問題。

JVM&NIO&HashMap簡單問

4、JVM為了優化記憶體的回收,采用的是分代回收的方式,對于新生代記憶體的回收(Minor GC)主要采用複制算法;而對于老年代的回收(Major GC),大多采用标記整理算法。

在 Java 中,堆被劃分成兩個不同的區域:新生代 ( Young )、老年代 ( Old );新生代 ( Young ) 又被劃分為三個區域:Eden、From Survivor、To Survivor;堆大小 = 新生代 + 老年代。其中,堆的大小可以通過參數 –Xms、-Xmx 來指定。

二、NIO

簡單介紹下IO包和NIO包中的内容:

IO包:

1、按照資料流的方向不同可以分為:輸入流(InputStream,Reader)和輸出流(OutputStream,Writer)。

2、按照處理資料機關不同可以分為:位元組流(InputStream,OutputStream)和字元流(Reader,Writer)。

3、按照實作功能不同可以分為:節點流(四大基礎流...)和處理流(就是在節點流外面再套一層,比如BufferedReader,BufferedWriter...)。

注:這裡的輸入和輸出都是針對程式本身而言,而位元組和字元就是一個是8位的二進制,另一個是16位的二進制;而節點流和處理流的差別就在于傳資料的機關不同。

NIO:

首先NIO模型要熟悉,特别是其中的selector一定要非常清楚它的職責和實作原理。其實NIO的核心是IO線程池,一定要記住這個關鍵點。面試官可能也會問你IO包的設計模式(裝飾器模式),為什麼要這樣設計?

NIO簡介:Non-blocking I/O 或 New I/O;非阻塞IO,作為原始IO的補充,為了應對高性能高并發的應用場景。

NIO詳解:https://blog.csdn.net/qq_28303495/article/details/89514690

三、Java的資料結構相關的類實作原理

比如LinkedList,ArrayList,HashMap,TreeMap這一類的,以下簡單模拟一個資料結構的連環炮。

HashMap是不是有序的?

答:

HashMap是無序集合。

有沒有有順序的Map實作類?

TreeMap和LinkedHashMap。

TreeMap和LinkedHashMap是如何保證它的順序的?

LinkedHashMap内部增加了一個連結清單,用于存放元素的順序,其是根據元素增加或者通路的先後順序進行排序的;TreeMap它實作了SortedMap接口,可以對元素進行排序,其是根據元素的Key進行排序的,也就是基于元素的固有順序(由Comparator或者Comparable确定)。

你覺得它們兩個哪個的有序實作比較好?

分需求和場景考慮吧:

TreeMap取出來的是排序後的鍵值對,如果按自然順序或自定義順序周遊鍵,那麼TreeMap會更好;如果需要輸出的順序和輸入的順序形同,那麼用LinkedHashMap比較好;

适可而止 見好就收

繼續閱讀