更新時(shí)間:2019-10-16 11:02:08 來源:動(dòng)力節(jié)點(diǎn) 瀏覽2975次
在掌握了Java技術(shù)之后,面試就成為馬上要面臨的問題了。面對面試官的問題,提前做好準(zhǔn)備能夠有助于你的臨場發(fā)揮,以下是一些Java面試中高頻出現(xiàn)的一些問題,有一部分是沒有固定答案的,希望能夠?qū)Υ蠹矣兴鶐椭?/p>
BIO、NIO和AIO的區(qū)別
JavaBIO:同步并阻塞,服務(wù)器實(shí)現(xiàn)模式為一個(gè)連接一個(gè)線程,即客戶端有連接請求時(shí)服務(wù)器端就需要啟動(dòng)一個(gè)線程進(jìn)行處理,如果這個(gè)連接不做任何事情會(huì)造成不必要的線程開銷,當(dāng)然可以通過線程池機(jī)制改善。
JavaNIO:同步非阻塞,服務(wù)器實(shí)現(xiàn)模式為一個(gè)請求一個(gè)線程,即客戶端發(fā)送的連接請求都會(huì)注冊到多路復(fù)用器上,多路復(fù)用器輪詢到連接有I/O請求時(shí)才啟動(dòng)一個(gè)線程進(jìn)行處理。
JavaAIO:異步非阻塞,服務(wù)器實(shí)現(xiàn)模式為一個(gè)有效請求一個(gè)線程,客戶端的I/O請求都是由OS先完成了再通知服務(wù)器應(yīng)用去啟動(dòng)線程進(jìn)行處理。
NIO比BIO的改善之處是把一些無效的連接擋在了啟動(dòng)線程之前,減少了這部分資源的浪費(fèi)(因?yàn)槲覀兌贾烂縿?chuàng)建一個(gè)線程,就要為這個(gè)線程分配一定的內(nèi)存空間)
AIO比NIO的進(jìn)一步改善之處是將一些暫時(shí)可能無效的請求擋在了啟動(dòng)線程之前,比如在NIO的處理方式中,當(dāng)一個(gè)請求來的話,開啟線程進(jìn)行處理,但這個(gè)請求所需要的資源還沒有就緒,此時(shí)必須等待后端的應(yīng)用資源,這時(shí)線程就被阻塞了。
適用場景分析:
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)使用過,后來放棄。
Java中常說的堆和棧,分別是什么數(shù)據(jù)結(jié)構(gòu);另外,為什么要分為堆和棧來存儲數(shù)據(jù)
棧是一種具有后進(jìn)先出性質(zhì)的數(shù)據(jù)結(jié)構(gòu),也就是說后存放的先取,先存放的后取。
堆是一種經(jīng)過排序的樹形數(shù)據(jù)結(jié)構(gòu),每個(gè)結(jié)點(diǎn)都有一個(gè)值。通常我們所說的堆的數(shù)據(jù)結(jié)構(gòu),是指二叉堆。堆的特點(diǎn)是根結(jié)點(diǎn)的值最小(或最大),且根結(jié)點(diǎn)的兩個(gè)子樹也是一個(gè)堆。由于堆的這個(gè)特性,常用來實(shí)現(xiàn)優(yōu)先隊(duì)列,堆的存取是隨意的。
為什么要?jiǎng)澐侄押蜅?/strong>
1、從軟件設(shè)計(jì)的角度看,棧代表了處理邏輯,而堆代表了數(shù)據(jù)。這樣分開,使得處理邏輯更為清晰。
2、堆與棧的分離,使得堆中的內(nèi)容可以被多個(gè)棧共享。一方面這種共享提供了一種有效的數(shù)據(jù)交互方式(如:共享內(nèi)存),另一方面,堆中的共享常量和緩存可以被所有棧訪問,節(jié)省了空間。
3、棧因?yàn)檫\(yùn)行時(shí)的需要,比如保存系統(tǒng)運(yùn)行的上下文,需要進(jìn)行地址段的劃分。由于棧只能向上增長,因此就會(huì)限制住棧存儲內(nèi)容的能力。而堆不同,堆中的對象是可以根據(jù)需要?jiǎng)討B(tài)增長的,因此棧和堆的拆分,使得動(dòng)態(tài)增長成為可能,相應(yīng)棧中只需記錄堆中的一個(gè)地址即可。
4、體現(xiàn)了Java面向?qū)ο筮@一核心特點(diǎn)(也可以繼續(xù)說一些自己的理解)。
為什么要用線程池
那先要明白什么是線程池
線程池是指在初始化一個(gè)多線程應(yīng)用程序過程中創(chuàng)建一個(gè)線程集合,然后在需要執(zhí)行新的任務(wù)時(shí)重用這些線程而不是新建一個(gè)線程。
使用線程池的好處
1、線程池改進(jìn)了一個(gè)應(yīng)用程序的響應(yīng)時(shí)間。由于線程池中的線程已經(jīng)準(zhǔn)備好且等待被分配任務(wù),應(yīng)用程序可以直接拿來使用而不用新建一個(gè)線程。
2、線程池節(jié)省了CLR為每個(gè)短生存周期任務(wù)創(chuàng)建一個(gè)完整的線程的開銷并可以在任務(wù)完成后回收資源。
3、線程池根據(jù)當(dāng)前在系統(tǒng)中運(yùn)行的進(jìn)程來優(yōu)化線程時(shí)間片。
4、線程池允許我們開啟多個(gè)任務(wù)而不用為每個(gè)線程設(shè)置屬性。
5、線程池允許我們?yōu)檎趫?zhí)行的任務(wù)的程序參數(shù)傳遞一個(gè)包含狀態(tài)信息的對象引用。
6、線程池可以用來解決處理一個(gè)特定請求最大線程數(shù)量限制問題。
Msyql優(yōu)化經(jīng)驗(yàn)
1、對查詢進(jìn)行優(yōu)化,應(yīng)盡量避免全表掃描,首先應(yīng)考慮在where及orderby涉及的列上建立索引。
2、應(yīng)盡量避免在where子句中使用!=或<>操作符,否則引擎將放棄使用索引而進(jìn)行全表掃描。
3、盡量使用數(shù)字型字段,若只含數(shù)值信息的字段盡量不要設(shè)計(jì)為字符型,這會(huì)降低查詢和連接的性能,并會(huì)增加存儲開銷。這是因?yàn)橐嬖谔幚聿樵兒瓦B接時(shí)會(huì)逐個(gè)比較字符串中每一個(gè)字符,而對于數(shù)字型而言只需要比較一次就夠了。
4、任何地方都不要使用select*fromt,用具體的字段列表代替“*”,不要返回用不到的任何字段。
5、避免頻繁創(chuàng)建和刪除臨時(shí)表,以減少系統(tǒng)表資源的消耗。諸如此類,等等等等......
相關(guān)Java面試題推薦
相關(guān)閱讀
初級 202925
初級 203221
初級 202629
初級 203743