更新時間:2019-09-19 14:22:32 來源:動力節(jié)點(diǎn) 瀏覽2997次
List和Set比較,各自的子類比較
對比一:Arraylist與LinkedList的比較
1、ArrayList是實(shí)現(xiàn)了基于動態(tài)數(shù)組的數(shù)據(jù)結(jié)構(gòu),因?yàn)榈刂愤B續(xù),一旦數(shù)據(jù)存儲好了,查詢操作效率會比較高(在內(nèi)存里是連著放的)。
2、因?yàn)榈刂愤B續(xù),ArrayList要移動數(shù)據(jù),所以插入和刪除操作效率比較低。
3、LinkedList基于鏈表的數(shù)據(jù)結(jié)構(gòu),地址是任意的,所以在開辟內(nèi)存空間的時候不需要等一個連續(xù)的地址,對于新增和刪除操作add和remove,LinedList比較占優(yōu)勢。
4、因?yàn)長inkedList要移動指針,所以查詢操作性能比較低。
適用場景分析:
當(dāng)需要對數(shù)據(jù)進(jìn)行對此訪問的情況下選用ArrayList,當(dāng)需要對數(shù)據(jù)進(jìn)行多次增加刪除修改時采用LinkedList。
對比二:ArrayList與Vector的比較
1、Vector的方法都是同步的,是線程安全的,而ArrayList的方法不是,由于線程的同步必然要影響性能。因此,ArrayList的性能比Vector好。
2、當(dāng)Vector或ArrayList中的元素超過它的初始大小時,Vector會將它的容量翻倍,而ArrayList只增加50%的大小,這樣。ArrayList就有利于節(jié)約內(nèi)存空間。
3、大多數(shù)情況不使用Vector,因?yàn)樾阅懿缓?,但是它支持線程的同步,即某一時刻只有一個線程能夠?qū)慥ector,避免多線程同時寫而引起的不一致性。
4、Vector可以設(shè)置增長因子,而ArrayList不可以。
適用場景分析:
1、Vector是線程同步的,所以它也是線程安全的,而ArrayList是線程異步的,是不安全的。如果不考慮到線程的安全因素,一般用ArrayList效率比較高。
2、如果集合中的元素的數(shù)目大于目前集合數(shù)組的長度時,在集合中使用數(shù)據(jù)量比較大的數(shù)據(jù),用Vector有一定的優(yōu)勢。
對比三:HashSet與TreeSet的比較
1.TreeSet是二叉樹實(shí)現(xiàn)的,Treeset中的數(shù)據(jù)是自動排好序的,不允許放入null值。
2.HashSet是哈希表實(shí)現(xiàn)的,HashSet中的數(shù)據(jù)是無序的,可以放入null,但只能放入一個null,兩者中的值都不能重復(fù),就如數(shù)據(jù)庫中唯一約束。
3.HashSet要求放入的對象必須實(shí)現(xiàn)HashCode()方法,放入的對象,是以hashcode碼作為標(biāo)識的,而具有相同內(nèi)容的String對象,hashcode是一樣,所以放入的內(nèi)容不能重復(fù)。但是同一個類的對象可以放入不同的實(shí)例。
適用場景分析:
HashSet是基于Hash算法實(shí)現(xiàn)的,其性能通常都優(yōu)于TreeSet。我們通常都應(yīng)該使用HashSet,在我們需要排序的功能時,我們才使用TreeSet。
HashMap和ConcurrentHashMap的區(qū)別
1、HashMap不是線程安全的,而ConcurrentHashMap是線程安全的。
2、ConcurrentHashMap采用鎖分段技術(shù),將整個Hash桶進(jìn)行了分段segment,也就是將這個大的數(shù)組分成了幾個小的片段segment,而且每個小的片段segment上面都有鎖存在,那么在插入元素的時候就需要先找到應(yīng)該插入到哪一個片段segment,然后再在這個片段上面進(jìn)行插入,而且這里還需要獲取segment鎖。
3、ConcurrentHashMap讓鎖的粒度更精細(xì)一些,并發(fā)性能更好。
JVM的內(nèi)存結(jié)構(gòu)
根據(jù)JVM規(guī)范,JVM內(nèi)存共分為虛擬機(jī)棧、堆、方法區(qū)、程序計數(shù)器、本地方法棧五個部分。
1、Java虛擬機(jī)棧:
線程私有;每個方法在執(zhí)行的時候會創(chuàng)建一個棧幀,存儲了局部變量表,操作數(shù)棧,動態(tài)連接,方法返回地址等;每個方法從調(diào)用到執(zhí)行完畢,對應(yīng)一個棧幀在虛擬機(jī)棧中的入棧和出棧。
2、堆:
線程共享;被所有線程共享的一塊內(nèi)存區(qū)域,在虛擬機(jī)啟動時創(chuàng)建,用于存放對象實(shí)例。
3、方法區(qū):
線程共享;被所有線程共享的一塊內(nèi)存區(qū)域;用于存儲已被虛擬機(jī)加載的類信息,常量,靜態(tài)變量等。
4、程序計數(shù)器:
線程私有;是當(dāng)前線程所執(zhí)行的字節(jié)碼的行號指示器,每條線程都要有一個獨(dú)立的程序計數(shù)器,這類內(nèi)存也稱為“線程私有”的內(nèi)存。
5、本地方法棧:
線程私有;主要為虛擬機(jī)使用到的Native方法服務(wù)。
強(qiáng)引用,軟引用和弱引用的區(qū)別
強(qiáng)引用:
只有這個引用被釋放之后,對象才會被釋放掉,只要引用存在,垃圾回收器永遠(yuǎn)不會回收,這是最常見的New出來的對象。
軟引用:
內(nèi)存溢出之前通過代碼回收的引用。軟引用主要用戶實(shí)現(xiàn)類似緩存的功能,在內(nèi)存足夠的情況下直接通過軟引用取值,無需從繁忙的真實(shí)來源查詢數(shù)據(jù),提升速度;當(dāng)內(nèi)存不足時,自動刪除這部分緩存數(shù)據(jù),從真正的來源查詢這些數(shù)據(jù)。
弱引用:
第二次垃圾回收時回收的引用,短時間內(nèi)通過弱引用取對應(yīng)的數(shù)據(jù),可以取到,當(dāng)執(zhí)行過第二次垃圾回收時,將返回null。弱引用主要用于監(jiān)控對象是否已經(jīng)被垃圾回收器標(biāo)記為即將回收的垃圾,可以通過弱引用的isEnQueued方法返回對象是否被垃圾回收器標(biāo)記。
springmvc的核心是什么,請求的流程是怎么處理的,控制反轉(zhuǎn)怎么實(shí)現(xiàn)的
核心:
控制反轉(zhuǎn)和面向切面
請求處理流程:
1、首先用戶發(fā)送請求到前端控制器,前端控制器根據(jù)請求信息(如URL)來決定選擇哪一個頁面控制器進(jìn)行處理并把請求委托給它,即以前的控制器的控制邏輯部分;
2、頁面控制器接收到請求后,進(jìn)行功能處理,首先需要收集和綁定請求參數(shù)到一個對象,并進(jìn)行驗(yàn)證,然后將命令對象委托給業(yè)務(wù)對象進(jìn)行處理;處理完畢后返回一個ModelAndView(模型數(shù)據(jù)和邏輯視圖名);
3、前端控制器收回控制權(quán),然后根據(jù)返回的邏輯視圖名,選擇相應(yīng)的視圖進(jìn)行渲染,并把模型數(shù)據(jù)傳入以便視圖渲染;
4、前端控制器再次收回控制權(quán),將響應(yīng)返回給用戶。
控制反轉(zhuǎn)如何實(shí)現(xiàn):
我們每次使用spring框架都要配置xml文件,這個xml配置了bean的id和class。
spring中默認(rèn)的bean為單實(shí)例模式,通過bean的class引用反射機(jī)制可以創(chuàng)建這個實(shí)例。
因此,spring框架通過反射替我們創(chuàng)建好了實(shí)例并且替我們維護(hù)他們。
A需要引用B類,spring框架就會通過xml把B實(shí)例的引用傳給了A的成員變量。
BIO、NIO和AIO的區(qū)別
JavaBIO:同步并阻塞,服務(wù)器實(shí)現(xiàn)模式為一個連接一個線程,即客戶端有連接請求時服務(wù)器端就需要啟動一個線程進(jìn)行處理,如果這個連接不做任何事情會造成不必要的線程開銷,當(dāng)然可以通過線程池機(jī)制改善。
JavaNIO:同步非阻塞,服務(wù)器實(shí)現(xiàn)模式為一個請求一個線程,即客戶端發(fā)送的連接請求都會注冊到多路復(fù)用器上,多路復(fù)用器輪詢到連接有I/O請求時才啟動一個線程進(jìn)行處理。
JavaAIO:異步非阻塞,服務(wù)器實(shí)現(xiàn)模式為一個有效請求一個線程,客戶端的I/O請求都是由OS先完成了再通知服務(wù)器應(yīng)用去啟動線程進(jìn)行處理。
NIO比BIO的改善之處是把一些無效的連接擋在了啟動線程之前,減少了這部分資源的浪費(fèi)(因?yàn)槲覀兌贾烂縿?chuàng)建一個線程,就要為這個線程分配一定的內(nèi)存空間)
AIO比NIO的進(jìn)一步改善之處是將一些暫時可能無效的請求擋在了啟動線程之前,比如在NIO的處理方式中,當(dāng)一個請求來的話,開啟線程進(jìn)行處理,但這個請求所需要的資源還沒有就緒,此時必須等待后端的應(yīng)用資源,這時線程就被阻塞了。
適用場景分析:
BIO方式適用于連接數(shù)目比較小且固定的架構(gòu),這種方式對服務(wù)器資源要求比較高,并發(fā)局限于應(yīng)用中,JDK1.4以前的唯一選擇,但程序直觀簡單易理解,如之前在Apache中使用。
NIO方式適用于連接數(shù)目多且連接比較短(輕操作)的架構(gòu),比如聊天服務(wù)器,并發(fā)局限于應(yīng)用中,編程比較復(fù)雜,JDK1.4開始支持,如在Nginx,Netty中使用。
AIO方式使用于連接數(shù)目多且連接比較長(重操作)的架構(gòu),比如相冊服務(wù)器,充分調(diào)用OS參與并發(fā)操作,編程比較復(fù)雜,JDK7開始支持,在成長中,Netty曾經(jīng)使用過,后來放棄。
為什么要用線程池
那先要明白什么是線程池
線程池是指在初始化一個多線程應(yīng)用程序過程中創(chuàng)建一個線程集合,然后在需要執(zhí)行新的任務(wù)時重用這些線程而不是新建一個線程。
使用線程池的好處
1、線程池改進(jìn)了一個應(yīng)用程序的響應(yīng)時間。由于線程池中的線程已經(jīng)準(zhǔn)備好且等待被分配任務(wù),應(yīng)用程序可以直接拿來使用而不用新建一個線程。
2、線程池節(jié)省了CLR為每個短生存周期任務(wù)創(chuàng)建一個完整的線程的開銷并可以在任務(wù)完成后回收資源。
3、線程池根據(jù)當(dāng)前在系統(tǒng)中運(yùn)行的進(jìn)程來優(yōu)化線程時間片。
4、線程池允許我們開啟多個任務(wù)而不用為每個線程設(shè)置屬性。
5、線程池允許我們?yōu)檎趫?zhí)行的任務(wù)的程序參數(shù)傳遞一個包含狀態(tài)信息的對象引用。
6、線程池可以用來解決處理一個特定請求最大線程數(shù)量限制問題。
以上就是動力節(jié)點(diǎn)java培訓(xùn)機(jī)構(gòu)小編為大家介紹的“Java高級面試題和答案解析,看看你都會了嗎?”的內(nèi)容,希望對大家有幫助,更多java最新資訊請繼續(xù)關(guān)注動力節(jié)點(diǎn)java培訓(xùn)機(jī)構(gòu)官網(wǎng),每天會有精彩內(nèi)容分享與你。
相關(guān)閱讀

初級 202925

初級 203221

初級 202629

初級 203743