網(wǎng)易資深Java開(kāi)發(fā)面試經(jīng)驗(yàn)

網(wǎng)易資深Java開(kāi)發(fā)面試經(jīng)驗(yàn)

天津卓眾教育      2022-04-18 12:35:01     18

網(wǎng)易資深Java開(kāi)發(fā)面試經(jīng)驗(yàn),  List和Set比較,各自的子類比較  對(duì)比一:Arraylist與LinkedList的比較  1、ArrayList是實(shí)現(xiàn)了基于動(dòng)態(tài)數(shù)組的數(shù)據(jù)結(jié)構(gòu),

課程價(jià)格 請(qǐng)咨詢

上課時(shí)段: 授課校區(qū):

詳細(xì)介紹



  List和Set比較,各自的子類比較


  對(duì)比一:Arraylist與linkedList的比較


  1、ArrayList是實(shí)現(xiàn)了基于動(dòng)態(tài)數(shù)組的數(shù)據(jù)結(jié)構(gòu),因?yàn)榈刂愤B續(xù),一旦數(shù)據(jù)存儲(chǔ)好了,查詢操作效率會(huì)比較高(在內(nèi)存里是連著放的)。


  2、因?yàn)榈刂愤B續(xù),ArrayList要移動(dòng)數(shù)據(jù),所以插入和刪除操作效率比較低。


  3、linkedList基于鏈表的數(shù)據(jù)結(jié)構(gòu),地址是任意的,所以在開(kāi)辟內(nèi)存空間的時(shí)候不需要等一個(gè)連續(xù)的地址,對(duì)于新增和刪除操作add和remove,LinedList比較占優(yōu)勢(shì)。


  4、因?yàn)閘inkedList要移動(dòng)指針,所以查詢操作性能比較低。


  適用場(chǎng)景分析:


  當(dāng)需要對(duì)數(shù)據(jù)進(jìn)行對(duì)此訪問(wèn)的情況下選用ArrayList,當(dāng)需要對(duì)數(shù)據(jù)進(jìn)行多次增加刪除修改時(shí)采用linkedList。


  對(duì)比二:ArrayList與Vector的比較


  1、Vector的方法都是同步的,是線程安全的,而ArrayList的方法不是,由于線程的同步必然要影響性能。因此,ArrayList的性能比Vector好。


  2、當(dāng)Vector或ArrayList中的元素超過(guò)它的初始大小時(shí),Vector會(huì)將它的容量翻倍,而ArrayList只增加50%的大小,這樣。ArrayList就有利于節(jié)約內(nèi)存空間。


  3、大多數(shù)情況不使用Vector,因?yàn)樾阅懿缓茫撬С志€程的同步,即某一時(shí)刻只有一個(gè)線程能夠?qū)慥ector,避免多線程同時(shí)寫(xiě)而引起的不一致性。


  4、Vector可以設(shè)置增長(zhǎng)因子,而ArrayList不可以。


  適用場(chǎng)景分析:


  1、Vector是線程同步的,所以它也是線程安全的,而ArrayList是線程異步的,是不安全的。如果不考慮到線程的安全因素,一般用ArrayList效率比較高。


  2、如果集合中的元素的數(shù)目大于目前集合數(shù)組的長(zhǎng)度時(shí),在集合中使用數(shù)據(jù)量比較大的數(shù)據(jù),用Vector有一定的優(yōu)勢(shì)。


  對(duì)比三:HashSet與TreeSet的比較


  1.TreeSet是二叉樹(shù)實(shí)現(xiàn)的,Treeset中的數(shù)據(jù)是自動(dòng)排好序的,不允許放入null值。


  2.HashSet是哈希表實(shí)現(xiàn)的,HashSet中的數(shù)據(jù)是無(wú)序的,可以放入null,但只能放入一個(gè)null,兩者中的值都不能重復(fù),就如數(shù)據(jù)庫(kù)中唯一約束。


  3.HashSet要求放入的對(duì)象必須實(shí)現(xiàn)HashCode()方法,放入的對(duì)象,是以hashcode碼作為標(biāo)識(shí)的,而具有相同內(nèi)容的String對(duì)象,hashcode是一樣,所以放入的內(nèi)容不能重復(fù)。但是同一個(gè)類的對(duì)象可以放入不同的實(shí)例。


  適用場(chǎng)景分析:


  HashSet是基于Hash算法實(shí)現(xiàn)的,其性能通常都優(yōu)于TreeSet。我們通常都應(yīng)該使用HashSet,在我們需要排序的功能時(shí),我們才使用TreeSet。


  HashMap和ConcurrentHashMap的區(qū)別


  1、HashMap不是線程安全的,而ConcurrentHashMap是線程安全的。


  2、ConcurrentHashMap采用鎖分段技術(shù),將整個(gè)Hash桶進(jìn)行了分段segment,也就是將這個(gè)大的數(shù)組分成了幾個(gè)小的片段segment,而且每個(gè)小的片段segment上面都有鎖存在,那么在插入元素的時(shí)候就需要先找到應(yīng)該插入到哪一個(gè)片段segment,然后再在這個(gè)片段上面進(jìn)行插入,而且這里還需要獲取segment鎖。


  3、ConcurrentHashMap讓鎖的粒度更精細(xì)一些,并發(fā)性能更好。


  JVM的內(nèi)存結(jié)構(gòu)


  根據(jù)JVM規(guī)范,JVM內(nèi)存共分為虛擬機(jī)棧、堆、方法區(qū)、程序計(jì)數(shù)器、本地方法棧五個(gè)部分。


  1、Java虛擬機(jī)棧:


  線程私有;每個(gè)方法在執(zhí)行的時(shí)候會(huì)創(chuàng)建一個(gè)棧幀,存儲(chǔ)了局部變量表,操作數(shù)棧,動(dòng)態(tài)連接,方法返回地址等;每個(gè)方法從調(diào)用到執(zhí)行完畢,對(duì)應(yīng)一個(gè)棧幀在虛擬機(jī)棧中的入棧和出棧。


  2、堆:


  線程共享;被所有線程共享的一塊內(nèi)存區(qū)域,在虛擬機(jī)啟動(dòng)時(shí)創(chuàng)建,用于存放對(duì)象實(shí)例。


  3、方法區(qū):


  線程共享;被所有線程共享的一塊內(nèi)存區(qū)域;用于存儲(chǔ)已被虛擬機(jī)加載的類信息,常量,靜態(tài)變量等。


  4、程序計(jì)數(shù)器:


  線程私有;是當(dāng)前線程所執(zhí)行的字節(jié)碼的行號(hào)指示器,每條線程都要有一個(gè)獨(dú)立的程序計(jì)數(shù)器,這類內(nèi)存也稱為“線程私有”的內(nèi)存。


  5、本地方法棧:


  線程私有;主要為虛擬機(jī)使用到的Native方法服務(wù)。


  強(qiáng)引用,軟引用和弱引用的區(qū)別


  強(qiáng)引用:


  只有這個(gè)引用被釋放之后,對(duì)象才會(huì)被釋放掉,只要引用存在,垃圾回收器永遠(yuǎn)不會(huì)回收,這是最常見(jiàn)的New出來(lái)的對(duì)象。


  軟引用:


  內(nèi)存溢出之前通過(guò)代碼回收的引用。軟引用主要用戶實(shí)現(xiàn)類似緩存的功能,在內(nèi)存足夠的情況下直接通過(guò)軟引用取值,無(wú)需從繁忙的真實(shí)來(lái)源查詢數(shù)據(jù),提升速度;當(dāng)內(nèi)存不足時(shí),自動(dòng)刪除這部分緩存數(shù)據(jù),從真正的來(lái)源查詢這些數(shù)據(jù)。


  弱引用:


  第二次垃圾回收時(shí)回收的引用,短時(shí)間內(nèi)通過(guò)弱引用取對(duì)應(yīng)的數(shù)據(jù),可以取到,當(dāng)執(zhí)行過(guò)第二次垃圾回收時(shí),將返回null。弱引用主要用于監(jiān)控對(duì)象是否已經(jīng)被垃圾回收器標(biāo)記為即將回收的垃圾,可以通過(guò)弱引用的isEnQueued方法返回對(duì)象是否被垃圾回收器標(biāo)記。


  springmvc的核心是什么,請(qǐng)求的流程是怎么處理的,控制反轉(zhuǎn)怎么實(shí)現(xiàn)的


  核心:


  控制反轉(zhuǎn)和面向切面


  請(qǐng)求處理流程:


  1、首先用戶發(fā)送請(qǐng)求到前端控制器,前端控制器根據(jù)請(qǐng)求信息(如URL)來(lái)決定選擇哪一個(gè)頁(yè)面控制器進(jìn)行處理并把請(qǐng)求委托給它,即以前的控制器的控制邏輯部分;


  2、頁(yè)面控制器接收到請(qǐng)求后,進(jìn)行功能處理,首先需要收集和綁定請(qǐng)求參數(shù)到一個(gè)對(duì)象,并進(jìn)行驗(yàn)證,然后將命令對(duì)象委托給業(yè)務(wù)對(duì)象進(jìn)行處理;處理完畢后返回一個(gè)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文件,這個(gè)xml配置了bean的id和class。


  spring中默認(rèn)的bean為單實(shí)例模式,通過(guò)bean的class引用反射機(jī)制可以創(chuàng)建這個(gè)實(shí)例。


  因此,spring框架通過(guò)反射替我們創(chuàng)建好了實(shí)例并且替我們維護(hù)他們。


  A需要引用B類,spring框架就會(huì)通過(guò)xml把B實(shí)例的引用傳給了A的成員變量。


  BIO、NIO和AIO的區(qū)別


  JavaBIO:同步并阻塞,服務(wù)器實(shí)現(xiàn)模式為一個(gè)連接一個(gè)線程,即客戶端有連接請(qǐng)求時(shí)服務(wù)器端就需要啟動(dòng)一個(gè)線程進(jìn)行處理,如果這個(gè)連接不做任何事情會(huì)造成不必要的線程開(kāi)銷,當(dāng)然可以通過(guò)線程池機(jī)制改善。


  JavaNIO:同步非阻塞,服務(wù)器實(shí)現(xiàn)模式為一個(gè)請(qǐng)求一個(gè)線程,即客戶端發(fā)送的連接請(qǐng)求都會(huì)注冊(cè)到多路復(fù)用器上,多路復(fù)用器輪詢到連接有I/O請(qǐng)求時(shí)才啟動(dòng)一個(gè)線程進(jìn)行處理。


  JavaAIO:異步非阻塞,服務(wù)器實(shí)現(xiàn)模式為一個(gè)有效請(qǐng)求一個(gè)線程,客戶端的I/O請(qǐng)求都是由OS先完成了再通知服務(wù)器應(yīng)用去啟動(dòng)線程進(jìn)行處理。


  NIO比BIO的改善之處是把一些無(wú)效的連接擋在了啟動(dòng)線程之前,減少了這部分資源的浪費(fèi)(因?yàn)槲覀兌贾烂縿?chuàng)建一個(gè)線程,就要為這個(gè)線程分配一定的內(nèi)存空間)


  AIO比NIO的進(jìn)一步改善之處是將一些暫時(shí)可能無(wú)效的請(qǐng)求擋在了啟動(dòng)線程之前,比如在NIO的處理方式中,當(dāng)一個(gè)請(qǐng)求來(lái)的話,開(kāi)啟線程進(jìn)行處理,但這個(gè)請(qǐng)求所需要的資源還沒(méi)有就緒,此時(shí)必須等待后端的應(yīng)用資源,這時(shí)線程就被阻塞了。


  適用場(chǎng)景分析:


  BIO方式適用于連接數(shù)目比較小且固定的架構(gòu),這種方式對(duì)服務(wù)器資源要求比較高,并發(fā)局限于應(yīng)用中,JDK1.4以前的唯一選擇,但程序直觀簡(jiǎn)單易理解,如之前在Apache中使用。


  NIO方式適用于連接數(shù)目多且連接比較短(輕操作)的架構(gòu),比如聊天服務(wù)器,并發(fā)局限于應(yīng)用中,編程比較復(fù)雜,JDK1.4開(kāi)始支持,如在Nginx,Netty中使用。


  AIO方式使用于連接數(shù)目多且連接比較長(zhǎng)(重操作)的架構(gòu),比如相冊(cè)服務(wù)器,充分調(diào)用OS參與并發(fā)操作,編程比較復(fù)雜,JDK7開(kāi)始支持,在成長(zhǎng)中,Netty曾經(jīng)使用過(guò),后來(lái)放棄。


  為什么要用線程池


  那先要明白什么是線程池


  線程池是指在初始化一個(gè)多線程應(yīng)用程序過(guò)程中創(chuàng)建一個(gè)線程集合,然后在需要執(zhí)行新的任務(wù)時(shí)重用這些線程而不是新建一個(gè)線程。


  使用線程池的好處


  1、線程池改進(jìn)了一個(gè)應(yīng)用程序的響應(yīng)時(shí)間。由于線程池中的線程已經(jīng)準(zhǔn)備好且等待被分配任務(wù),應(yīng)用程序可以直接拿來(lái)使用而不用新建一個(gè)線程。


  2、線程池節(jié)省了CLR為每個(gè)短生存周期任務(wù)創(chuàng)建一個(gè)完整的線程的開(kāi)銷并可以在任務(wù)完成后回收資源。


  3、線程池根據(jù)當(dāng)前在系統(tǒng)中運(yùn)行的進(jìn)程來(lái)優(yōu)化線程時(shí)間片。


  4、線程池允許我們開(kāi)啟多個(gè)任務(wù)而不用為每個(gè)線程設(shè)置屬性。


  5、線程池允許我們?yōu)檎趫?zhí)行的任務(wù)的程序參數(shù)傳遞一個(gè)包含狀態(tài)信息的對(duì)象引用。


  6、線程池可以用來(lái)解決處理一個(gè)特定請(qǐng)求最大線程數(shù)量限制問(wèn)題。


  什么是線程死鎖?死鎖如何產(chǎn)生?如何避免線程死鎖?


  死鎖的介紹:


  線程死鎖是指由于兩個(gè)或者多個(gè)線程互相持有對(duì)方所需要的資源,導(dǎo)致這些線程處于等待狀態(tài),無(wú)法前往執(zhí)行。當(dāng)線程進(jìn)入對(duì)象的synchronized代碼塊時(shí),便占有了資源,直到它退出該代碼塊或者調(diào)用wait方法,才釋放資源,在此期間,其他線程將不能進(jìn)入該代碼塊。當(dāng)線程互相持有對(duì)方所需要的資源時(shí),會(huì)互相等待對(duì)方釋放資源,如果線程都不主動(dòng)釋放所占有的資源,將產(chǎn)生死鎖。


  死鎖的產(chǎn)生的一些特定條件:


  1、互斥條件:進(jìn)程對(duì)于所分配到的資源具有排它性,即一個(gè)資源只能被一個(gè)進(jìn)程占用,直到被該進(jìn)程釋放。


  2、請(qǐng)求和保持條件:一個(gè)進(jìn)程因請(qǐng)求被占用資源而發(fā)生阻塞時(shí),對(duì)已獲得的資源保持不放。


  3、不剝奪條件:任何一個(gè)資源在沒(méi)被該進(jìn)程釋放之前,任何其他進(jìn)程都無(wú)法對(duì)他剝奪占用。


  4、循環(huán)等待條件:當(dāng)發(fā)生死鎖時(shí),所等待的進(jìn)程必定會(huì)形成一個(gè)環(huán)路(類似于死循環(huán)),造成永久阻塞。


  如何避免:


  1、加鎖順序:


  當(dāng)多個(gè)線程需要相同的一些鎖,但是按照不同的順序加鎖,死鎖就很容易發(fā)生。如果能確保所有的線程都是按照相同的順序獲得鎖,那么死鎖就不會(huì)發(fā)生。當(dāng)然這種方式需要你事先知道所有可能會(huì)用到的鎖,然而總有些時(shí)候是無(wú)法預(yù)知的。


  2、加鎖時(shí)限:


  加上一個(gè)超時(shí)時(shí)間,若一個(gè)線程沒(méi)有在給定的時(shí)限內(nèi)成功獲得所有需要的鎖,則會(huì)進(jìn)行回退并釋放所有已經(jīng)獲得的鎖,然后等待一段隨機(jī)的時(shí)間再重試。但是如果有非常多的線程同一時(shí)間去競(jìng)爭(zhēng)同一批資源,就算有超時(shí)和回退機(jī)制,還是可能會(huì)導(dǎo)致這些線程重復(fù)地嘗試但卻始終得不到鎖。


  3、死鎖檢測(cè):


  死鎖檢測(cè)即每當(dāng)一個(gè)線程獲得了鎖,會(huì)在線程和鎖相關(guān)的數(shù)據(jù)結(jié)構(gòu)中(map、graph等等)將其記下。除此之外,每當(dāng)有線程請(qǐng)求鎖,也需要記錄在這個(gè)數(shù)據(jù)結(jié)構(gòu)中。死鎖檢測(cè)是一個(gè)更好的死鎖預(yù)防機(jī)制,它主要是針對(duì)那些不可能實(shí)現(xiàn)按序加鎖并且鎖超時(shí)也不可行的場(chǎng)景。


以上就是天津卓眾教育java學(xué)院小編分享的“ 網(wǎng)易資深Java開(kāi)發(fā)面試經(jīng)驗(yàn)”的內(nèi)容,希望能夠幫助到大家,更多java最新面試題請(qǐng)繼續(xù)關(guān)注天津卓眾教育java學(xué)院官網(wǎng),每天會(huì)有精彩內(nèi)容分享與你。


相關(guān)面試題推薦


最新最全java面試題及答案(從初級(jí)到高級(jí))


Java程序員必備,中級(jí)面試總結(jié)建議收藏


史上最全的中高級(jí)JAVA工程師面試題及答案匯總


10道中高級(jí)Java面試題詳解,弄懂offer拿到手軟


java程序員常見(jiàn)面試題及答案


培訓(xùn)啦提醒您:交易時(shí)請(qǐng)核實(shí)對(duì)方資質(zhì),對(duì)于過(guò)大宣傳或承諾需謹(jǐn)慎!任何要求預(yù)付定金、匯款等方式均存在風(fēng)險(xiǎn),謹(jǐn)防上當(dāng)。