版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
53道Java線程面試題
下面是Java線程相關(guān)的熱門面試題,你可以用它來好好打算面試。
線程是操作系統(tǒng)能夠進(jìn)行運(yùn)算調(diào)度的最小單位,它被包含在進(jìn)程之中,是
進(jìn)程中的實(shí)際運(yùn)作單位。程序員可以通過它進(jìn)行多處理器編程,你可以運(yùn)
用多線程對運(yùn)算密集型任務(wù)提速。比如,假如一個(gè)線程完成一個(gè)任務(wù)要100
毫秒,那么用十個(gè)線程完成改任務(wù)只需10毫秒。Java在語言層面對多線
程供應(yīng)了卓越的支持,它也是一個(gè)很好的賣點(diǎn)。
線程是進(jìn)程的子集,一個(gè)進(jìn)程可以有很多線程,每條線程并行執(zhí)行不同的
任務(wù)。不同的進(jìn)程運(yùn)用不同的內(nèi)存空間,而全部的線程共享一片相同的內(nèi)
存空間。別把它和棧內(nèi)存搞混,每個(gè)線程都擁有單獨(dú)的棧內(nèi)存用來存儲本
地?cái)?shù)據(jù)。
在語言層面有兩種方式。java.lang.Thread類的實(shí)例就是一個(gè)線程但是
它須要調(diào)用接口來執(zhí)行,由于線程類本身就是調(diào)用的Runnable接口所以
你可以繼承java.lang.Thread類或者干脆調(diào)用Runnable接口來重寫
run()方法實(shí)現(xiàn)線程。
這個(gè)問題是上題的后續(xù),大家都知道我們可以通過繼承Thread類或者調(diào)
用Runnable接口來實(shí)現(xiàn)線程,問題是,那個(gè)方法更好呢?什么狀況下運(yùn)
用它?這個(gè)問題很簡潔回答,假如你知道Java不支持類的多重繼承,但
允許你調(diào)用多個(gè)接口。所以假如你要繼承其他類,當(dāng)然是調(diào)用Runnable
接口好了。
這個(gè)問題常常被問到,但還是能從今區(qū)分出面試者對Java線程模型的理
解程度。start。方法被用來啟動(dòng)新創(chuàng)建的線程,而且start。內(nèi)部調(diào)用了
run()方法,這和干脆調(diào)用run()方法的效果不一樣。當(dāng)你調(diào)用run()方法
的時(shí)候,只會是在原來的線程中調(diào)用,沒有新的線程啟動(dòng),start。方法
才會啟動(dòng)新線程。
Runnable和Callable都代表那些要在不同的線程中執(zhí)行的任務(wù)°Runnable
從JDKL0起先就有了,Callable是在JDK1.5增加的。它們的主要區(qū)分是
Callable的call()方法可以返回值和拋出異樣,而Runnable的run()
方法沒有這些功能。Callable可以返回裝載有計(jì)算結(jié)果的Future對象。
CyclicBarrier和CountDownLatch都可以用來讓一組線程等待其它線
程。與CyclicBarrier不同的是,CountdownLatch不能重新運(yùn)用。
Java內(nèi)存模型規(guī)定和指引Java程序在不同的內(nèi)存架構(gòu)、CPU和操作系統(tǒng)
間有確定性地行為。它在多線程的狀況下尤其重要。Java內(nèi)存模型對一個(gè)
線程所做的變動(dòng)能被其它線程可見供應(yīng)了保證,它們之間是先行發(fā)生關(guān)系。
這個(gè)關(guān)系定義了一些規(guī)則讓程序員在并發(fā)編程時(shí)思路更清楚。比如,先行
發(fā)生關(guān)系確保了:
.線程內(nèi)的代碼能夠按先后依次執(zhí)行,這被稱為程序次序規(guī)則。
.對于同一個(gè)鎖,一個(gè)解鎖操作確定要發(fā)生在時(shí)間上后發(fā)生的另一個(gè)鎖
定操作之前,也叫做管程鎖定規(guī)則。
?前一個(gè)對volatile的寫操作在后一個(gè)volatile的讀操作之前,也叫
volatile變量規(guī)則。
?一個(gè)線程內(nèi)的任何操作必需在這個(gè)線程的start。調(diào)用之后,也叫作
線程啟動(dòng)規(guī)則。
?一個(gè)線程的全部操作都會在線程終止之前,線程終止規(guī)則。
.一個(gè)對象的終結(jié)操作必需在這個(gè)對象構(gòu)造完成之后,也叫對象終結(jié)規(guī)
則。
?可傳遞性
我劇烈建議大家閱讀《Java并發(fā)編程實(shí)踐》第十六章來加深對Java內(nèi)存
模型的理解。
volatile是一個(gè)特別的修飾符,只有成員變量才能運(yùn)用它。在Java并發(fā)
程序缺少同步類的狀況下,多線程對成員變量的操作對其它線程是透亮的。
volatile變量可以保證下一個(gè)讀取操作會在前一個(gè)寫操作之后發(fā)生,就是
上一題的volatile變量規(guī)則。
假如你的代碼所在的進(jìn)程中有多個(gè)線程在同時(shí)運(yùn)行,而這些線程可能會同
時(shí)運(yùn)行這段代碼。假如每次運(yùn)行結(jié)果和單線程運(yùn)行的結(jié)果是一樣的,而且
其他的變量的值也和預(yù)期的是一樣的,就是線程平安的6—個(gè)線程平安的
計(jì)數(shù)器類的同一個(gè)實(shí)例對象在被多個(gè)線程運(yùn)用的狀況下也不會出現(xiàn)計(jì)算
失誤。很明顯你可以將集合類分成兩組,線程平安和非線程平安的。Vector
是用同步方法來實(shí)現(xiàn)線程平安的,而和它相像的ArrayList不是線程平安
的。
競態(tài)條件會導(dǎo)致程序在并發(fā)狀況下出現(xiàn)一些bugso多線程對一些資源的競
爭的時(shí)候就會產(chǎn)生競態(tài)條件,假如首先要執(zhí)行的程序競爭失敗排到后面執(zhí)
行了,那么整個(gè)程序就會出現(xiàn)一些不確定的bugs。這種bugs很難發(fā)覺而
且會重復(fù)出現(xiàn),因?yàn)榫€程間的隨機(jī)競爭。
Java供應(yīng)了很豐富的API但沒有為停止線程供應(yīng)APLJDK1.0原來有一
些像stop。,suspend()和resume。的限制方法但是由于潛在的死鎖威
逼因此在后續(xù)的JDK版本中他們被棄用了,之后JavaAPI的設(shè)計(jì)者就沒
有供應(yīng)一個(gè)兼容且線程平安的方法來停止一個(gè)線程。當(dāng)run()或者callO
方法執(zhí)行完的時(shí)候線程會自動(dòng)結(jié)束,假如要手動(dòng)結(jié)束一個(gè)線程,你可以用
volatile布爾變量來退出run()方法的循環(huán)或者是取消任務(wù)來中斷線程。
這是我在一次面試中遇到的一個(gè)很刁鉆的Java面試題,簡潔的說,假如
異樣沒有被捕獲該線程將會停止執(zhí)行。
Thread.UncaughtExceptionHandler是用于處理未捕獲異樣造成線程突然
中斷狀況的一個(gè)內(nèi)嵌接口。當(dāng)一個(gè)未捕獲異樣將造成線程中斷的時(shí)候JVM
會運(yùn)用Thread.getUncaughtExceptionHandler()來查詢線程的
UncaughtExceptionHandler并將線程和異樣作為參數(shù)傳遞給handler的
uncaughtException()方法進(jìn)行處理。
你可以通過共享對象來實(shí)現(xiàn)這個(gè)目的,或者是運(yùn)用像堵塞隊(duì)列這樣并發(fā)的
數(shù)據(jù)結(jié)構(gòu)。這篇教程《Java線程間通信》(涉與到在兩個(gè)線程間共享對象)
用wait和notify方法實(shí)現(xiàn)了生產(chǎn)者消費(fèi)者模型。
這又是一個(gè)刁鉆的問題,因?yàn)槎嗑€程可以等待單監(jiān)控鎖,JavaAPI的設(shè)
計(jì)人員供應(yīng)了一些方法當(dāng)?shù)却龡l件變更的時(shí)候通知它們,但是這些方法沒
有完全實(shí)現(xiàn)。notify。方法不能喚醒某個(gè)具體的線程,所以只有一個(gè)線程
在等待的時(shí)候它才有用武之地。而notifyAUO喚醒全部線程并允許他們
爭奪鎖確保了至少有一個(gè)線程能接著運(yùn)行。
這是個(gè)設(shè)計(jì)相關(guān)的問題,它考察的是面試者對現(xiàn)有系統(tǒng)和一些普遍存在但
看起來不合理的事物的看法?;卮疬@些問題的時(shí)候,你要說明為什么把這
些方法放在Object類里是有意義的,還有不把它放在Thread類里的緣由。
一個(gè)很明顯的緣由是JAVA供應(yīng)的鎖是對象級的而不是線程級的,每個(gè)對
象都有鎖,通過線程獲得。假如線程須要等待某些鎖那么調(diào)用對象中的
wait。方法就有意義了。假如wait。方法定義在Thread類中,線程正在
等待的是哪個(gè)鎖就不明顯了。簡潔的說,由于wait,notify和notifyAll
都是鎖級別的操作,所以把他們定義在Object類中因?yàn)殒i屬于對象。
ThreadLocal是Java里一種特別的變量。每個(gè)線程都有一個(gè)ThreadLocal
就是每個(gè)線程都擁有了自己獨(dú)立的一個(gè)變量,競爭條件被徹底消退了。它
是為創(chuàng)建代價(jià)昂揚(yáng)的對象獲得線程平安的好方法,比如你可以用
ThreadLocal讓SimpleDateFormat變成線程平安的,因?yàn)槟莻€(gè)類創(chuàng)建代價(jià)
昂揚(yáng)且每次調(diào)用都須要?jiǎng)?chuàng)建不同的實(shí)例所以不值得在局部范圍運(yùn)用它,假
如為每個(gè)線程供應(yīng)一個(gè)自己獨(dú)有的變量拷貝,將大大提高效率。首先,通
過復(fù)用削減了代價(jià)昂揚(yáng)的對象的創(chuàng)建個(gè)數(shù)。其次,你在沒有運(yùn)用高代價(jià)的
同步或者不變性的狀況下獲得了線程平安。線程局部變量的另一個(gè)不錯(cuò)的
例子是ThreadLocalRandom類,它在多線程環(huán)境中削減了創(chuàng)建代價(jià)昂揚(yáng)的
Random對象的個(gè)數(shù)。
在Java并發(fā)程序中FutureTask表示一個(gè)可以取消的異步運(yùn)算。它有啟動(dòng)
和取消運(yùn)算、查詢運(yùn)算是否完成和取回運(yùn)算結(jié)果等方法。只有當(dāng)運(yùn)算完成
的時(shí)候結(jié)果才能取回,假如運(yùn)算尚未完成get方法將會堵塞。一個(gè)
FutureTask對象可以對調(diào)用了Callable和Runnable的對象進(jìn)行包裝,由
于FutureTask也是調(diào)用了Runnable接口所以它可以提交給Executor來
執(zhí)行。
inlerrupledO和islnlerrupled()的主耍區(qū)分是前者會將中斷狀態(tài)
清除而后者不會。Java多線程的中斷機(jī)制是用內(nèi)部標(biāo)識來實(shí)現(xiàn)的,調(diào)用
Thread,interrupt()來中斷一個(gè)線程就會設(shè)置中斷標(biāo)識為true。當(dāng)中斷線
程調(diào)用靜態(tài)方法Thread,interrupted。來檢查中斷狀態(tài)時(shí),中斷狀態(tài)會被
清零。而非靜態(tài)方法islnterrupted。用來查詢其它線程的中斷狀態(tài)且不
會變更中斷狀態(tài)標(biāo)識。簡潔的說就是任何拋出InterruptedException異
樣的方法都會將中斷狀態(tài)清零。無論如何,一個(gè)線程的中斷狀態(tài)有有可能
被其它線程調(diào)用中斷來變更。
主要是因?yàn)镴avaAPI強(qiáng)制要求這樣做,假如你不這么做,你的代碼會拋
出HlegalMonitorStateException異樣。還有一個(gè)緣由是為了避開wait
和notify之間產(chǎn)生競態(tài)條件。
處于等待狀態(tài)的線程可能會收到錯(cuò)誤警報(bào)和偽喚醒,假如不在循環(huán)中檢查
等待條件,程序就會在沒有滿足結(jié)束條件的狀況下退出。因此,當(dāng)一個(gè)等
待線程醒來時(shí),不能認(rèn)為它原來的等待狀態(tài)仍舊是有效的,在notify。
方法調(diào)用之后和等待線程醒來之前這段時(shí)間它可能會變更。這就是在循環(huán)
中運(yùn)用wait。方法效果更好的緣由,你可以在Eclipse中創(chuàng)建模板調(diào)用
wait和notify試一試。假如你想了解更多關(guān)于這個(gè)問題的內(nèi)容,我舉薦
你閱讀《EffectiveJava》這本書中的線程和同步章節(jié)。
同步集合與并發(fā)集合都為多線程和并發(fā)供應(yīng)了合適的線程平安的集合,不
過并發(fā)集合的可擴(kuò)展性更高。在Javal.5之前程序員們只有同步集合來用
且在多線程并發(fā)的時(shí)候會導(dǎo)致爭用,阻礙了系統(tǒng)的擴(kuò)展性。Java5介紹了
并發(fā)集合像ConcurrentHashMap,不僅供應(yīng)線程平安還用鎖分別和內(nèi)部分
區(qū)等現(xiàn)代技術(shù)提高了可擴(kuò)展性。
為什么把這個(gè)問題歸類在多線程和并發(fā)面試題里?因?yàn)闂J且粔K和線程
緊密相關(guān)的內(nèi)存區(qū)域。每個(gè)線程都有自己的棧內(nèi)存,用于存儲本地變量,
方法參數(shù)和棧調(diào)用,一個(gè)線程中存儲的變量對其它線程是不行見的。而堆
是全部線程共享的一片公用內(nèi)存區(qū)域。對象都在堆里創(chuàng)建,為了提升效率
線程會從堆中弄一個(gè)緩存到自己的棧,假如多個(gè)線程運(yùn)用該變量就可能引
發(fā)問題,這時(shí)volatile變量就可以發(fā)揮作用了,它要求線程從主存中讀
取變量的值。
創(chuàng)建線程要花費(fèi)昂貴的資源和時(shí)間,假如任務(wù)來了才創(chuàng)建線程那么響應(yīng)時(shí)
間會變長,而且一個(gè)進(jìn)程能創(chuàng)建的線程數(shù)有限。為了避開這些問題,在程
序啟動(dòng)的時(shí)候就創(chuàng)建若干線程來響應(yīng)處理,它們被稱為線程池,里面的線
程叫工作線程。從JDK1.5起先,JavaAPI供應(yīng)了Executor框架讓你可以
創(chuàng)建不同的線程池。比如單線程池,每次處理一個(gè)任務(wù);數(shù)目固定的線程
池或者是緩存線程池(一個(gè)適合很多生存期短的任務(wù)的程序的可擴(kuò)展線程
池)。
在現(xiàn)實(shí)中你解決的很多線程問題都屬于生產(chǎn)者消費(fèi)者模型,就是一個(gè)線程
生產(chǎn)任務(wù)供其它線程進(jìn)行消費(fèi),你必需知道怎么進(jìn)行線程間通信來解決這
個(gè)問題。比較低級的方法是用wait和notify來解決這個(gè)問題,比較贊的
方法是用Semaphore或者BlockingQueue來實(shí)現(xiàn)生產(chǎn)者消費(fèi)者模型,這
篇教程有實(shí)現(xiàn)它。
Java多線程中的死鎖
死鎖是指兩個(gè)或兩個(gè)以上的進(jìn)程在執(zhí)行過程中,因爭奪資源而造成的一種
相互等待的現(xiàn)象,若無外力作用,它們都將無法推動(dòng)下去。這是一個(gè)嚴(yán)峻
的問題,因?yàn)樗梨i會讓你的程序掛起無法完成任務(wù),死鎖的發(fā)生必需滿足
以下四個(gè)條件:
?互斥條件:一個(gè)資源每次只能被一個(gè)進(jìn)程運(yùn)用。
?懇求與保持條件:一個(gè)進(jìn)程因懇求資源而堵塞時(shí),對已獲得的資源保
持不放。
?不剝奪條件:進(jìn)程已獲得的資源,在末運(yùn)用完之前,不能強(qiáng)行剝奪。
?循環(huán)等待條件:若干進(jìn)程之間形成一種頭尾相接的循環(huán)等待資源關(guān)系。
避開死鎖最簡潔的方法就是阻擋循環(huán)等待條件,將系統(tǒng)中全部的資源設(shè)置
標(biāo)記位、排序,規(guī)定全部的進(jìn)程申請資源必需以確定的依次(升序或降序)
做操作來避開死鎖。
這是上題的擴(kuò)展,活鎖和死鎖類似,不同之處在于處于活鎖的線程或進(jìn)程
的狀態(tài)是不斷變更的,活鎖可以認(rèn)為是一種特別的饑餓。一個(gè)現(xiàn)實(shí)的活鎖
例子是兩個(gè)人在狹小的走廊遇到,兩個(gè)人都試著避讓對方好讓彼此通過,
但是因?yàn)楸茏尩姆较蚨家粯訉?dǎo)致最終誰都不能通過走廊。簡潔的說就是,
活鎖和死鎖的主要區(qū)分是前者進(jìn)程的狀態(tài)可以變更但是卻不能接著執(zhí)行。
我始終不知道我們竟然可以檢測一個(gè)線程是否擁有鎖,直到我參與了一次
電話面試。在中有一個(gè)方法叫holdsLock(),它返回true假如當(dāng)且僅當(dāng)當(dāng)
前線程擁有某個(gè)具體對象的鎖。
對于不同的操作系統(tǒng),有多種方法來獲得Java進(jìn)程的線程堆棧。當(dāng)你獲
得線程堆棧時(shí),JVM會把全部線程的狀態(tài)存到日志文件或者輸出到限制臺。
在Windows你可以運(yùn)用Ctrl+Break組合鍵來獲得線程堆棧,Linux下用
kill-3吩咐。你也可以用jstack這個(gè)工具來獲得,它對線程id進(jìn)行操
作,你可以用jps這個(gè)工具找到ido
這個(gè)問題很簡潔,-Xss參數(shù)用來限制線程的堆棧大小。你可以查看JVM
配置列表來了解這個(gè)參數(shù)的更多信息。
Java在過去很長一段時(shí)間只能通過synchronized關(guān)鍵字來實(shí)現(xiàn)互斥,它
有一些缺點(diǎn)。比如你不能擴(kuò)展鎖之外的方法或者塊邊界,嘗試獲得鎖時(shí)不
能中途取消等。Java5通過Lock接口供應(yīng)了更困難的限制來解決這些問
題。ReentrantLock類實(shí)現(xiàn)了Lock,它擁有與synchronized相同的并
發(fā)性和內(nèi)存語義且它還具有可擴(kuò)展性。
在多線程中有多種方法讓線程按特定依次執(zhí)行,你可以用線程類的joinO
方法在一個(gè)線程中啟動(dòng)另一個(gè)線程,另外一個(gè)線程完成該線程接著執(zhí)行。
為了確保三個(gè)線程的依次你應(yīng)當(dāng)先啟動(dòng)最終一個(gè)(T3調(diào)用T2,T2調(diào)用T1),
這樣T1就會先完成而T3最終完成。
Yield方法可以暫停當(dāng)前正在執(zhí)行的線程對象,讓其它有相同優(yōu)先級的線
程執(zhí)行。它是一個(gè)靜態(tài)方法而且只保證當(dāng)前線程放棄CPU占用而不能保證
使其它線程確定能占用CPU,執(zhí)行yield。的線程有可能在進(jìn)入到暫停狀
態(tài)后立刻又被執(zhí)行。
ConcurrentHashMap把實(shí)際map劃分成若干部分來實(shí)現(xiàn)它的可擴(kuò)展性和線
程平安。這種劃分是運(yùn)用并發(fā)度獲得的,它是Concu門'entHashMap類構(gòu)造
函數(shù)的一個(gè)可選參數(shù),默認(rèn)值為16,這樣在多線程狀況下就能避開爭用。
Java中的Semaphore是一種新的同步類,它是一個(gè)計(jì)數(shù)信號。從概念上講,
從概念上講,信號量維護(hù)了一個(gè)許可集合。如有必要,在許可可用前會堵
塞每一個(gè)acquire(),然后再獲得該許可。每個(gè)release。添加一個(gè)許可,
從而可能釋放一個(gè)正在堵塞的獲得者。但是,不運(yùn)用實(shí)際的許可對象,
Semaphore只對可用許可的號碼進(jìn)行計(jì)數(shù),并實(shí)行相應(yīng)的行動(dòng)。信號量常
常用于多線程的代碼中,比如數(shù)據(jù)庫連接池。
這個(gè)問題問得很狡猾,很多程序員會認(rèn)為該任務(wù)會堵塞直到線程池隊(duì)列有
空位。事實(shí)上假如一個(gè)任務(wù)不能被調(diào)度執(zhí)行那么ThreadPoolExecutor's
submit()方法將會拋出一個(gè)RejectedExecutionException異樣。
兩個(gè)方法都可以向線程池提交任務(wù),execute。方法的返回類型是void,
它定義在Executor接口中,而submit()方法可以返回持有計(jì)算結(jié)果的
Future對象,它定義在ExecutorService接口中,它擴(kuò)展了Executor接
口,其它線程池類像ThreadPoolExecutor和
ScheduledThreadPoolExecutor都有這些方法。
堵塞式方法是指程序會始終等待該方法完成期間不做其他事情,
ServerSocket的accept()方法就是始終等待客戶端連接。這里的堵塞是
指調(diào)用結(jié)果返回之前,當(dāng)前線程會被掛起,直到得到結(jié)果之后才會返回。
此外,還有異步和非堵塞式方法在任務(wù)完成前就返回。
你可以很確定的給出回答,Swing不是線程平安的,但是你應(yīng)當(dāng)說明這么
回答的緣由即便面試官?zèng)]有問你為什么。當(dāng)我們說swing不是線程平安的
常常提到它的組件,這些組件不能在多線程中進(jìn)行修改,全部對GUI組件
的更新都要在AWT線程中完成,而Swing供應(yīng)了同步和異步兩種回調(diào)方法
來進(jìn)行更新。
這兩個(gè)方法是SwingAPI供應(yīng)應(yīng)Java開發(fā)者用來從當(dāng)前線程而不是事務(wù)
派發(fā)線程更新GUI組件用的。InvokeAndWait()同步更新GUI組件,比如
一個(gè)進(jìn)度條,一旦進(jìn)度更新了,進(jìn)度條也要做出相應(yīng)變更。假如進(jìn)度被多
個(gè)線程跟蹤,那么就調(diào)用invokeAndWaitO方法懇求事務(wù)派發(fā)線程對組件
進(jìn)行相應(yīng)更新。而invokeLaterO方法是異步調(diào)用更新組件的。
這個(gè)問題又提到了swing和線程平安,雖然組件不是線程平安的但是有一
些方法是可以被多線程平安調(diào)用的,比如repaint(),revalidateO。
JTextComponent的setText()方法和JTextArea的insert()和append()
方法也是線程平安的。
這個(gè)問題看起來和多線程沒什么關(guān)系,但不變性有助于簡化已經(jīng)很困難
的并發(fā)程序。Immutable對象可以在沒有同步的狀況下共享,降低了對該
對象進(jìn)行并發(fā)訪問時(shí)的同步化開銷??墒荍ava沒有?Immutable這個(gè)注解
符,要?jiǎng)?chuàng)建不行變類,要實(shí)現(xiàn)下面幾個(gè)步驟:通過構(gòu)造方法初始化全部成
員、對變量不要供應(yīng)setter方法、將全部的成員聲明為私有的,這樣就
不允許干脆訪問這些成員、在getter方法中,不要干脆返回對象本身,
而是克隆對象,并返回對象的拷貝。
一般而言,讀寫鎖是用來提升并發(fā)程序性能的鎖分別技術(shù)的成果。Java中
的ReadWriteLock是Java5中新增的一個(gè)接口,一個(gè)ReadWriteLock維
護(hù)一對關(guān)聯(lián)的鎖,一個(gè)用于只讀操作一個(gè)用于寫。在沒有寫線程的狀況下
一個(gè)讀鎖可能會同時(shí)被多個(gè)讀線程持有。寫鎖是獨(dú)占的,你可以運(yùn)用JDK
中的ReentrantReadWriteLock來實(shí)現(xiàn)這個(gè)規(guī)則,它最多支持65535個(gè)寫
鎖和65535個(gè)讀鎖。
忙循環(huán)就是程序員用循環(huán)讓一個(gè)線程等待,不像傳統(tǒng)方法wait(),sleep()
或yieldO它們都放棄了CPU限制,而忙循環(huán)不會放棄CPU,它就是在運(yùn)
行一個(gè)空循環(huán)。這么做的目的是為了保留CPU緩存,在多核系統(tǒng)中,一個(gè)
等待線程醒來的時(shí)候可能會在另一個(gè)內(nèi)核運(yùn)行,這樣會重建緩存。為了避
開重建緩存和削減等待重建的時(shí)間就可以運(yùn)用它了。
這是個(gè)好玩的問題。首先,volatile變量和atomic變量看起來很像,
但功能卻不一樣。Volatile變量可以確保先行關(guān)系,即寫操作會發(fā)生在后
續(xù)的讀操作之前,但它并不能保證原子性。例如用volatile修飾count
變量那么count++操作就不是原子性的。而Atomiclntcger類供應(yīng)的
atomic方法可以讓這種操作具有原子性如getAndlncrement()方法會原子
性的進(jìn)行增量操作把當(dāng)前值加一,其它數(shù)據(jù)類型和引用變量也可以進(jìn)行相
像操作。
這個(gè)問題坑了很多Java程序員,若你能想到鎖是否釋放這條線索來回答
還有點(diǎn)希望答對。無論你的同步塊是正常還是異樣退出的,里面的線程都
會釋放鎖,所以對比鎖接口我更喜愛同步塊,因?yàn)樗挥梦一ㄙM(fèi)精力去釋
放鎖,該功能可以在finallyblock里釋放鎖實(shí)現(xiàn)。
這個(gè)問題在Java面試中常常被問到,但是面試官對回答此問題的滿足度
僅為50%。一半的人寫不出雙檢鎖還有一半的人說不出它的隱患和Javal.5
是如何對它修正的。它其實(shí)是一個(gè)用來創(chuàng)建線程平安的單例的老方法,當(dāng)
單例實(shí)例第一次被創(chuàng)建時(shí)它試圖用單個(gè)鎖進(jìn)行性能優(yōu)化,但是由于太過于
困難在JDKL4中它是失敗的,我個(gè)人也不喜愛它。無論如何,即便你也
不喜愛它但是還是要了解一下,因?yàn)樗31粏柕健?/p>
這是上面那個(gè)問題的后續(xù),假如你不喜愛雙檢鎖而面試官問了創(chuàng)建
Singleton類的替代方法,你可以利用JVM的類加載和靜態(tài)變量初始化特
征來創(chuàng)建Singleton實(shí)例,或者是利用枚舉類型來創(chuàng)建Singleton,我很
喜愛用這種方法。
這種問題我最喜愛了,我信任你在寫并發(fā)代碼來提升性能的時(shí)候也會遵循
某些最佳實(shí)踐。以下三條最佳實(shí)踐我覺得大多數(shù)Java程序員都應(yīng)當(dāng)遵循:
?給你的線程起個(gè)有意義的名字。
這樣可以便利找bug或追蹤。OrderProcessor,QuoteProcessoror
TradeProcessor這種名字比Thread-1.Thread-2andThread-3好
多了,給線程起一個(gè)和它要完成的任務(wù)相關(guān)的名字,全部的主要框架
甚至JDK都遵循這個(gè)最佳實(shí)踐。
?避開鎖定和縮小同步的范圍
鎖花費(fèi)的代價(jià)昂揚(yáng)且上下文切換更耗費(fèi)時(shí)間空間,試試最低限度的運(yùn)
用同步和鎖,縮小臨界區(qū)。因此相對于同步方法我更喜愛同步塊,它
給我擁有對鎖的確定限制權(quán)。
?多用同步類少用wait和notify
首先,CountDownLatch,Semaphore,CyclicBarrier和Exchanger這
些同步類簡化了編碼操作,而用wait和notify很難實(shí)現(xiàn)對困難限制
流的限制。其次,這些類是由最好的企業(yè)編寫和維護(hù)在后續(xù)的JDK中
它們還會不斷優(yōu)化和完善,運(yùn)用這些更高等級的同步工具你的程序可
以不費(fèi)吹灰之力獲得優(yōu)化。
?多用并發(fā)集合少用同步集合
這是另外一個(gè)簡潔遵循且受益巨大的最佳實(shí)踐,并發(fā)集合比同步集合
的可擴(kuò)展性更好,所以在并發(fā)編程時(shí)運(yùn)用并發(fā)集合效果更好。假如下
一次你須要用到map,你應(yīng)當(dāng)首先想到用ConcurrentHashMapo
這個(gè)問題就像是如何強(qiáng)制進(jìn)行Java垃圾回收,目前還沒有覺得方法,雖
然你可以運(yùn)用System.gc()來進(jìn)行垃圾回收,但是不保證能勝利。在Java
里面沒有方法強(qiáng)制啟動(dòng)一個(gè)線程,它是被線程調(diào)度器限制著且Java沒有
公布相關(guān)的APT。
forkjoin框架是JDK7中出現(xiàn)的一款高效的工具,Java開發(fā)人員可以通
過它充分利用現(xiàn)代服務(wù)器上的多處理器。它是特地為了那些可以遞歸劃分
成很多子模塊設(shè)計(jì)的,目的是將全部可用的處理實(shí)力用來提升程序的性能。
forkjoin框架一個(gè)巨大的優(yōu)勢是它運(yùn)用了工作竊取算法,可以完成更多
任務(wù)的工作線程可以從其它線程中竊取任務(wù)來執(zhí)行。
Java程序中wait和sleep都會造成某種形式的暫停,它們可以滿足不同
的須要。wait。方法用于線程間通信,假如等待條件為真且其它線程被喚
醒時(shí)它會釋放鎖,而sleepO方法僅僅釋放CPU資源或者讓當(dāng)前線程停止
執(zhí)行一段時(shí)間,但不會釋放鎖。
2023年ssm面試題
1.很新的面試題
2.很全的面試題
3.很重點(diǎn)的面試題框架
Struts2與Strutsl的面試題
###1.Struts2與Strutsl的聯(lián)系與區(qū)分?為什么要用Struts2?
strutsl與struts2都是mvc框架的經(jīng)典實(shí)現(xiàn)模式。
Struts2不是從Strutsl升級而來,而是由WebWork改名而來,而WebW
ork只是Xwork加了很多WEB攔截器而已
區(qū)分:
1.核心限制器改成了過濾器(過濾器比Servlet的級別要高,因?yàn)槌?/p>
序運(yùn)行時(shí)是先進(jìn)入過濾器再進(jìn)入Servlet)
2.strutsl嚴(yán)峻依靠于Servlet(因?yàn)樘^于依靠于api的Servle
tRequest與ServletResponse的兩個(gè)參數(shù)),
struts2就則脫離了Servlet的API。
3.管理Action時(shí)strutsl是單例模式,struts2是每個(gè)懇求產(chǎn)生一個(gè)
實(shí)例。
4.在表達(dá)式的支持上struts2不僅有jstL還有功能更加強(qiáng)大的ogn
1表達(dá)式。
5.strutsl的類型轉(zhuǎn)換是單向的(頁面到ActionForm),struts2是雙向
的(頁面到Action再到頁面回顯)
6.校驗(yàn),strutsl沒有針對具體方法的校驗(yàn),struts2供應(yīng)了指定某個(gè)
方法進(jìn)行效驗(yàn),還有框架校驗(yàn)。
7.struts2供應(yīng)了攔截器,利用攔截器可以在訪問Action之前或之后
增加如權(quán)限攔截等功能。
8.struts2供應(yīng)了全局范圍,包范圍,Action范圍的國際化資源文件
管理實(shí)現(xiàn)。
9.struts2支持多種視圖類型
###2.Struts2的核心是什么,體現(xiàn)了什么思想?
Struts2的核心是攔截器,基本上核心功能都是由攔截器完成,攔截器
的實(shí)現(xiàn)體現(xiàn)了A0P(面對切面編程)思想
###3.為何繼承ActionSupport
因?yàn)锳ctionSupport實(shí)現(xiàn)了Action接口,供應(yīng)了國際化,校驗(yàn)的功能。
ActionSupport實(shí)現(xiàn)了國際化功能:因?yàn)樗?yīng)了一個(gè)getText(Stri
ngkey)方法實(shí)現(xiàn)國際化,該方法從資源文件上獲得國際化信息。
Action接口供應(yīng)了五個(gè)常量(success,error,login,input,none)o
(s?k,ses,er?(r)n?n
###4.模型驅(qū)動(dòng)與屬性驅(qū)動(dòng)是什么模型驅(qū)動(dòng)運(yùn)用時(shí)留意什么問題
答:模型驅(qū)動(dòng)與屬性驅(qū)動(dòng)都是用來封裝數(shù)據(jù)的。
1.模型驅(qū)動(dòng):在實(shí)現(xiàn)類中實(shí)現(xiàn)ModelDriven〈T>接口運(yùn)用泛型把屬性類
封裝起來,重寫getModel。方法,然后在實(shí)現(xiàn)類里創(chuàng)建一個(gè)屬性類的實(shí)例,
2.屬性驅(qū)動(dòng):在實(shí)現(xiàn)類里定義屬性,生成get與set方法,通過屬性
來拿值。
###5.Struts2是怎樣進(jìn)行值封裝的?
struts2的值封裝事實(shí)上是采納了ognl表達(dá)式.
###6.Struts2如何進(jìn)行校驗(yàn)
1.每個(gè)Action類有一個(gè)校驗(yàn)文件,命名Action類名-validation,xm
1,且與Action類同書目,這是對action里面全部的方法進(jìn)行校驗(yàn)。
2.對Action里面的指定方法做校驗(yàn)運(yùn)用Action的類名-訪問路徑一方
法名-validation.xml。
在效驗(yàn)文件里又分為兩種:
字段校驗(yàn):字段用什么校驗(yàn)器來校驗(yàn)。
非字段校驗(yàn):是用校驗(yàn)器校驗(yàn)什么字段。
###7.談?wù)凷truts2的國際化
在struts2中是運(yùn)用了攔截器來實(shí)現(xiàn)國際化。
具體是先配置屬性文件,格式是文件名.語言—國家名.properties,然
后放的位置有Action同包位置,
package位置,全局位置(要在常量里面配置),然后頁面通過s:text
或者key屬性去訪問
###8?0GNL是什么你在項(xiàng)目中如何運(yùn)用它
0GNL是:對象圖形導(dǎo)航語言。
在struts2中的作用:
ognl的實(shí)現(xiàn)關(guān)系:ActionConctxt。
ognl3個(gè)常用的符號#$%
#
1構(gòu)造map,list集合。2取ognl上下文的值。3用來過濾集合。
$
1在校驗(yàn)框架中取資源文件中的值。
2可以在配置文件中傳遞參數(shù)。
%
運(yùn)用百分號可以進(jìn)行轉(zhuǎn)義。
###9.Strust2如何訪問ServletAPI
1:通過ActionContext可以獲得request,application,session
三個(gè)作用域(struts2事實(shí)上是通過適配器
來把servlet的api轉(zhuǎn)換為一個(gè)map,并把這些map放在ActionCont
ext里面)。2:通過ActionContext的子類ServletActionContext去獲
得原滋原味的API。
3:可以通過實(shí)現(xiàn)ServlctRequcstAware接口,重寫里面的sctServle
tRequest方法可以獲
得request,事實(shí)上是通過set的依靠注入。
###10.什么是攔截器說說Struts2用攔截器來干什么說出6個(gè)攔截
器來
說明:在訪問類的某個(gè)方法或者屬性之前執(zhí)行,攔截的是Action的懇
求,進(jìn)行攔截然后在方法的執(zhí)行前或者之后加入某些操作。
作用:國際化,權(quán)限,效驗(yàn)等與源代碼無關(guān)的操作。
攔截器:
國際化,表單重復(fù)提交,類型轉(zhuǎn)換,自動(dòng)裝配,數(shù)據(jù)封裝,異樣處理,
模型驅(qū)動(dòng),懇求參數(shù),處理類型轉(zhuǎn)換錯(cuò)誤,日志攔截器.
###11.如何實(shí)現(xiàn)自定義攔截器?須要留意什么?
實(shí)現(xiàn):
1.可以實(shí)現(xiàn)Interceptor接口,重寫dolntercept方法指定某個(gè)方法
進(jìn)行攔截,或者繼承AbstractInterceptor類,重寫intercept方法。
2.在xml配置文件中定義自定義攔截器,然后注入到攔截器棧中,再
把攔截器引用到action中。
3.可以配置到某個(gè)action單獨(dú)運(yùn)用,也可以配置到包下面的全部act
ion運(yùn)用。留意:
要把默認(rèn)的攔截器棧重新引用,否則會被覆蓋。
###12.ActionContext是用來干什么的
ActionContext是Action的上下文。
###13.為什么要繼承默認(rèn)的包?
因?yàn)樵赟trtus2里面默認(rèn)有很多的常量,攔截器,還有一些bean,假如
繼承默認(rèn)的包,這些默認(rèn)值和常量就會繼承過來,
###14.常見的有哪幾種結(jié)果集類型?
dispatcher:指得是轉(zhuǎn)發(fā),默認(rèn)的結(jié)果集類型
redirect:重定向,
redirectAction:重定向到一個(gè)Action
stream:是返回一個(gè)流,一般用在文件下載上面
###15.開發(fā)項(xiàng)目時(shí)struts2在頁面怎樣拿值?
從值棧中或者是ognl的上下文
###16.怎么樣用Struts2進(jìn)行文件的上傳或者下載
上傳:
1.在jsp用了s:file標(biāo)簽,把s:from的enctype屬性設(shè)置為multip
art/form-data
2.在action里面定義三個(gè)字段Filefile,String[file]Content!
ype,String[file]FileName
3.用輸出流轉(zhuǎn)化成硬盤上面的文件
下載:
1.在struts,xml中配置result為stream的類型
2.在action定義四個(gè)屬性,默認(rèn)的有個(gè)是InputStream的類型叫inp
utStream的,從硬盤上面讀取文件到這個(gè)流賦值即可.
contentType;contentLength;contentDisposition;inputstream;
###17.簡潔講下struts里面的標(biāo)簽,說不少于5個(gè)
s:if
s:form
s:url
s:property
s:iterater
###18.默認(rèn)struts2里面的標(biāo)簽取值都是從那里取值的
默認(rèn)都是從0GNL值棧里面取值的
###19.ValueStack分為那兩部分,組成部分是什么,分別怎么訪問
分為:
對象棧和ContextMap
訪問:
1.對象棧前臺可以干脆訪問
2.ContextMap訪問的時(shí)候前面加#
###20.標(biāo)簽<s:property)和el表達(dá)式有什么區(qū)分,
相同:
都可以從值棧里面取值
區(qū)分:
el表達(dá)式只能取屬性有g(shù)etset方法的簡潔數(shù)據(jù)類型
s:property標(biāo)簽:取得數(shù)組的一些方法等困難數(shù)據(jù)對象類型
###21.說下重復(fù)提交的解決思路,Struts2是怎么樣解決重復(fù)提交的
1.在頁面表單域加入一個(gè)隱藏的s:token字段,然后在session里面也
加入同樣的值
2.當(dāng)用戶第一次懇求的時(shí)候,把request的值和session對比,相同就
通過懇求,執(zhí)行下面攔截器,并且移除Session里面的值
3.假如其次次懇求時(shí)候,Session已經(jīng)沒有這個(gè)值,那么就阻斷當(dāng)前懇
求,定位重復(fù)提交Struts2是通過s:token標(biāo)簽來完成重復(fù)提交思路的
spring的面試題部分
Spring的aop你怎樣實(shí)現(xiàn)?
用動(dòng)態(tài)代理和cglib實(shí)現(xiàn),有接口的用動(dòng)態(tài)代理,無接口的用cglib
###2.Spring在SSH起什么作用
為大部分框架供應(yīng)模版,常見的核心類供應(yīng)初始化,并且整合三層框架
###3.Spring容器內(nèi)部怎么實(shí)現(xiàn)的
內(nèi)部用Map實(shí)現(xiàn),或者說HashMap
###4.怎么樣理解TOC與A0P
I0C是一種限制反轉(zhuǎn)的思想,降低了對象的耦合度,A0P是面對切面編
程,非侵入式編程,實(shí)現(xiàn)了非業(yè)務(wù)性編程(公共功能),譬如日志,權(quán)限,事務(wù)
等等
###5.Spring的事務(wù),事務(wù)的作用。
Spring里面的事務(wù)分為編程式事務(wù)和聲明式事務(wù),一般用聲明式事務(wù),
用來限制數(shù)據(jù)操作的完整性,一樣性
###6.Spring的IOC和AOP你在項(xiàng)目中是怎么運(yùn)用的?
IOC主要來解決對象之間的依靠問題,把全部的bear.的依靠關(guān)系通過
配置文件或者注解關(guān)聯(lián)起來,降低了耦合度,AOP一般用來整合框架時(shí)候都
可以用得到,
事務(wù)用的最多,還有個(gè)別日志,權(quán)限功能也可以用到
###7Spring主要運(yùn)用了什么模式?
工廠模式一>每個(gè)Bean的創(chuàng)建通過方法
單例模式一>默認(rèn)的每個(gè)Bean的作用域都是單例
代理模式一>關(guān)于AOP的實(shí)現(xiàn)是通過代理,體現(xiàn)代理模式
###8.Springbean的作用域.
Scope作用域有4種,常見的有單例或者多例,默認(rèn)是單例
###9.Spring的事務(wù)是如何配置的?
1.先配置事務(wù)管理器TransactionManager,不同的框架有不同屬性
2.再配置事務(wù)通知和屬性,通過tx:advice
3.配置<aop:config),設(shè)置那些方法或者類須要加入事務(wù)
###10.Spring的配置文件最好運(yùn)用什么文件?
xml,因?yàn)樗亲詈啙?最流行的數(shù)據(jù)格式
###11.你運(yùn)用過Spring中的哪些技術(shù)?
bean的管理,AOP技術(shù),I0C技術(shù),事務(wù)等
###12.為什么要用Spring
降低對象耦合度,讓代碼更加清楚,供應(yīng)一些常見的模版
###13.說下Spring的注解
1.bean的標(biāo)記注解
?Component通用注解?Repository長久層注解?Service業(yè)務(wù)層注
解?Controller:表現(xiàn)層注解
2.bean的自動(dòng)裝配注解
稱
?AutoWired默認(rèn)是依據(jù)類型裝配,假如有多個(gè)類型實(shí)現(xiàn)可以用Quali
fier來指定名
?Resource默認(rèn)是依據(jù)名稱來裝配,是JDK里面自帶的注解,默認(rèn)狀況
下用@AutoWired注解
###15.寫過類似SpringA0P的操作嗎?
簡潔的寫過,譬如前置通知,后置通知的方法,環(huán)繞通知,事務(wù)就是典型
的A0P的實(shí)現(xiàn)
###16.Spring中的AOP在你項(xiàng)目中是怎么運(yùn)用的,用在哪里?
Struts2和Hibernate整合時(shí)候都可以用得到,事務(wù)用的最多,還有個(gè)
別日志,權(quán)限功能也可以用到
###17.Spring的事務(wù)(傳播屬性,隔離級別)。
七大傳播屬性,四大隔離級別
###19,SpringDI的幾種方式
setter注入和構(gòu)造器注入,一般用setter注入
###20.依靠注入的原理
就是通過反射機(jī)制生成想要的對象注入
###21.說一下整合Spring的核心監(jiān)聽器。
這個(gè)是在SSH整合的時(shí)候運(yùn)用,是整個(gè)WEB項(xiàng)目啟動(dòng)的時(shí)候初始化Spr
ing的容器.具體是在web.xml里面配置的ContextLoaderListener
Spring配置文件中的核心是個(gè)監(jiān)聽器,是用來初始化Spring的容器
###22.Spring你們?yōu)槭裁从门渲梦募贿\(yùn)用注解?
配置文件耦合度低,簡潔維護(hù),尤其是在切面或者事務(wù)的時(shí)候,只配置
一次就可以讓很多代碼擁有事務(wù),
###23.Spring和Hibernate的事務(wù)有什么區(qū)分?
Spring的事務(wù)供應(yīng)了統(tǒng)一的事務(wù)處理機(jī)制,包含了JDBC,Hibernate,I
Batis等事務(wù)實(shí)現(xiàn),而Hibernate只處理自己事務(wù)
###24.Struts2與Spring整合先啟動(dòng)那個(gè)容器。
先啟動(dòng)監(jiān)聽器,因?yàn)橄纫跏蓟萜?初始化容器了以后Action才能
從容器里面獲得
###26.讓你寫Spring的容器,你是怎樣實(shí)現(xiàn)的?
我們可以寫一個(gè)HashMap,假如并發(fā)考慮的話要寫并發(fā)的Map,把bean
的名字放在map的key,bean的實(shí)現(xiàn)map的value
###27.談?wù)凷pring的IOC和AOP,假如不用Spring,怎么去實(shí)現(xiàn)這兩
個(gè)技術(shù)。
ioc用反射實(shí)現(xiàn),AOP用動(dòng)態(tài)代理實(shí)現(xiàn)
###28.Spring事務(wù)和Hibernate事務(wù)的操作上面的區(qū)分?
hibernate的事務(wù)只能手動(dòng)顯示代碼的方式限制創(chuàng)建事務(wù)與提交事務(wù)
以與回滾。
Spring可以通過配置文件設(shè)定一類class事務(wù)的創(chuàng)建與提交以與回滾,
也可以顯示代碼方式限制。
###29.講下Spring的七大事務(wù)傳播
有七個(gè),常用有兩個(gè)REQUIERD,REQUIRED_NEW,REQUIERD表示兩個(gè)事
務(wù)的方法調(diào)用的時(shí)候,前面的時(shí)候和后面的合并成一個(gè)事務(wù),REQUIRED_NE
W是重啟一個(gè)事務(wù),各干各的
###30.在同一進(jìn)程里,有A,B兩個(gè)方法都對不同的表進(jìn)行更新數(shù)據(jù),
假如A方法出異樣了,若要B方法執(zhí)行,怎樣配置事務(wù)級別,若不要B方
法執(zhí)行,又該怎樣配置?
前者用REQUIRED_NEW,后者用REQUIRED
###31.事務(wù)并發(fā)會引起什么問題,怎么解決
事務(wù)并發(fā)會引起臟讀,幻讀,不行重復(fù)讀等問題,設(shè)定事務(wù)的隔離級別
就可以解決
###32.事務(wù)的隔離級別
Spring定義有四種,但是常見的是READ_C0MMIT,Oralce有兩種實(shí)現(xiàn),M
YSql有四種
###33.Spring的I0C容器與工廠類有什么區(qū)分?
IOC(InversionofControl)對Bean的限制實(shí)力更強(qiáng),能限制對象自
動(dòng)注入,還可以限制生命周期,而工廠類只是簡潔的創(chuàng)建一個(gè)對象,沒有什
么限制實(shí)力
###34.事務(wù)的平安問題:鎖機(jī)制的實(shí)現(xiàn)原理與在項(xiàng)目中的運(yùn)用
鎖有悲觀鎖和樂觀鎖,悲觀鎖一般假設(shè)每個(gè)人都會修改數(shù)據(jù),默認(rèn)狀況
下把數(shù)據(jù)都鎖住,影響性能,但平安性高.
樂觀鎖是假設(shè)每個(gè)人都只讀下數(shù)據(jù),不會修改數(shù)據(jù),性能比較高,但是
平安性較低,一般通過增加類似于版本限制里面版本號來解決問題
###35.講下BeanFactory和ApplicationContext的區(qū)分
BeanFactory是Spring容器頂級核心接口,比較早,但功能比較少,get
Bean就是BeanFactory定義的,
ApplicationContext是Spring里面的另外一個(gè)容器頂級接口,它繼承
于BeanFactory,但是供應(yīng)的功能譬如校驗(yàn),國際化,監(jiān)聽,
對Bean的管理功能比較多,一般運(yùn)用ApplicationContext
講下SpringMvc和Strutsl,Struts2的比較的優(yōu)勢
性能上Struts1>SpringMvc>Struts2開發(fā)速度上SpringMvc和Strut
s2差不多,比Strutsl要高
講下SpringMvc的核心入口類是什么,Strutsl,Struts2
的分別是什么
SpringMvc的是DispatchServlet,Strutsl的是ActionServlet,Stru
ts2的是StrutsPrepareAndExecuteFilter
###f-sm-3.SpringMvc的限制器是不是單例模式,假如是,有什么問
題,怎么解決
是單例模式,所以在多線程訪問的時(shí)候有線程平安問題,不要用同步,
會影響性能的,解決方案是在限制器里面不能寫字段
SpingMvc中的限制器的注解一般用那個(gè),有沒有別的注
解可以替代
一般用?Controller注解,表示是表現(xiàn)層,不能用用別的注解代替.
?RequestMapping注解用在類上面有什么作用
用于類上,表示類中的全部響應(yīng)懇求的方法都是以該地址作為父路徑。
###f-sm-6.怎么樣把某個(gè)懇求映射到特定的方法上面
干脆在方法上面加上注解@RequestMapping,并且在這個(gè)注解里面寫上
要攔截的路徑假如在攔截懇求中,我想攔截get方式提交的
方法,怎么配置
springMVC模式的面試題部分
可以在@RequestMapping注解里面加上method=RequestMethod.GET
###f-sm-8.假如在攔截懇求中,我想攔截提交參數(shù)中包含〃type二test
〃字符串,怎么配置
可以在?RequestMapping注解里面加上params="type=test”
###f-sm-9.我想在攔截的方法里面得到從前臺傳入的參數(shù),怎么得到
干脆在形參里面聲明這個(gè)參數(shù)就可以,但必需名字和傳過來的參數(shù)一
樣
###f-sm-10.假如前臺有很多個(gè)參數(shù)傳入,并且這些參數(shù)都是一個(gè)對
象的,那么怎么樣快速得到這個(gè)對象
干脆在方法中聲明這個(gè)對象,SpringMvc就自動(dòng)會把屬性賦值到這個(gè)
對象里面1.怎么樣在方法里面得到Request,或者Session
干脆在方法的形參中聲明request,SpringMvc就自動(dòng)把request對象
傳入
###f-sm-12.SpringMvc中函數(shù)的返回值是什么.
返回值可以有很多類型,有String,ModelAndView,List,Set等,一般
用String比較好,假如是AJAX懇求,返回的可以是一個(gè)集合
SpringMvc怎么處理返回值的
SpringMvc依據(jù)配置文件中InternalResourceViewResolver(內(nèi)部資
源視圖解析器)的前綴和后綴,用前綴+返回值+后綴組成完整的返回值
mf-sm-14.SpringMVC怎么樣設(shè)定重定向和轉(zhuǎn)發(fā)的
在返回值前面加〃forward:"就可以讓結(jié)果轉(zhuǎn)發(fā),譬如“forward:user.d
o?name=method4/,在返回值前面加〃redirect:〃就可以讓返回值重定向,
譬如"redirect:://uu456SpringMvc用什么
對象從后臺向前臺傳遞數(shù)據(jù)的
通過ModelMap對象,可以在這個(gè)對象里面用addAttributeO方法,把
對象加到里面,前臺就可以通過el表達(dá)式拿到
###f-sm-16.SpringMvc中有個(gè)類把視圖和數(shù)據(jù)都合并的一起的,叫
什么
ModelAndView
###f-sm-17.怎么樣把數(shù)據(jù)放入Session里面
可以聲明一個(gè)request,或者session先拿到session,然后就可以放入
數(shù)據(jù),或者可以在類上面加上@SessionAttributes注解,
里面包含的字符串就是要放入session里面的key
SpringMvc怎么和AJAX相互調(diào)用的
通過Jackson框架就可以把Java里面的對象干脆轉(zhuǎn)化成Js可以識別
的Json對象具體步驟如下:
1.力口入Jackson,jar
2.在配置文件中配置json的映射
3.在接受Ajax方法里面可以干脆返回Object,List等,但方法前面要
加上@ResponseBody注解
###f-sm-19.當(dāng)一個(gè)方法向AJAX返回特別對象,譬如Object,List等,
須要做什么處理
要加上@ResponseBody注解
###f-sm-20.SpringMvc里面攔截器是怎么寫的
有兩種寫法,一種是實(shí)現(xiàn)接口,另外一種是繼承適配器類,然后在Spri
ngMvc的配置文件中配置攔截器即可:
<!一配置SpringMvc的攔截器一><mvc:interceptors><!一配置
一個(gè)攔截器的Bean就可以了默認(rèn)是對全部懇求都攔截一
<beanid二〃mylnterceptor"class=zzcom.et.action.MyHandlerlnter
ceptorz"></bean>
<!一只針對部分懇求攔截一><mvc:interceptor><mvc:mappingp
ath="z/modelMap.do,z/><beanclass="zcom.et.action.MyHandlerlnter
ceptorAdapter^/></mvc:interceptor></mvc:interceptors>
講下SpringMvc的執(zhí)行流程
系統(tǒng)啟動(dòng)的時(shí)候依據(jù)配置文件創(chuàng)建spring的容器,首先是發(fā)送
懇求到核心限制器DispatcherServlet,spring容器通過映射器去找尋業(yè)
務(wù)限制器,
運(yùn)用適配器找到相應(yīng)的業(yè)務(wù)類,在進(jìn)業(yè)務(wù)類時(shí)進(jìn)行數(shù)據(jù)封裝,在封裝
前可能會涉與到類型轉(zhuǎn)換,執(zhí)行完業(yè)務(wù)類后運(yùn)用ModelAndView進(jìn)行視圖
轉(zhuǎn)發(fā),
數(shù)據(jù)放在model中,用map傳遞數(shù)據(jù)進(jìn)行頁面顯示。
###1.講下MyBatis和Hibernate的區(qū)分?
MyBatis是JDBC的輕量級封裝,把Sql和java代碼獨(dú)立出來,性能相
對比較高,寫SQL語句相對于比較敏捷,并且簡潔調(diào)試,一般用在大型項(xiàng)目
中.
Hibernate是JDBC的重量級封裝,開發(fā)速度比較快,但是性能比較低,
調(diào)試不便利,一般適合對進(jìn)度要求的比較高的中小型項(xiàng)目
###2.什么是MyBatis的接口綁定,有什么好處
接口映射就是在IBatis中隨意定義接口,然后把接口里面的方法和SQ
L語句綁定,我們干脆調(diào)用接口方法就可以,
這樣比起原來了SqlSession供應(yīng)的方法我們可以有更加敏捷的選擇
和設(shè)置.
###3.接口綁定有幾種實(shí)現(xiàn)方式,分別是怎么實(shí)現(xiàn)的?
接口綁定有兩種實(shí)現(xiàn)方式,一種是通過注解綁定,就是在接口的方法上
面加上@SelectMyBatis的面試題部分
?Update等注解里面包含Sql語句來綁定,另外一種就是通過xml里面
寫SQL來綁定,在這種狀況下,
要指定xml映射文件里面的namespace必需為接口的全路徑名.
###4.什么狀況下用注解綁定,什么狀況下用xml綁定
當(dāng)Sql語句比較簡潔時(shí)候,用注解綁定,當(dāng)SQL語句匕較困難時(shí)候,用x
ml綁定,一般用xml綁定的比較多
###5.MyBatis實(shí)現(xiàn)一對一有幾種方式?具體怎么操作的
有聯(lián)合查詢和嵌套查詢,聯(lián)合查詢是幾個(gè)表聯(lián)合查詢,只查詢一次,通
過在resultMap里面配置association節(jié)點(diǎn)配置一對一的類就可以完成;
嵌套查詢是先查一個(gè)表,依據(jù)這個(gè)表里面的結(jié)果的外鍵id,去再另外
一個(gè)表里面查詢數(shù)據(jù),也是通過association配置,但另外一個(gè)表的查詢通
過select屬性配置
###6.假如要查詢的表名和返回的實(shí)體Bean對象不一樣,那你是怎么
處理的?
在MyBatis里面最主要最敏捷的的一個(gè)映射對象的ResultMap,在它里
面可以映射鍵值對,默認(rèn)里面有id節(jié)點(diǎn),result節(jié)點(diǎn),它可以映射表里面
的列名和對象里面的字段名.并且在一對一,一對多的狀況下結(jié)果集也確
定要用ResultMap
MyBatis里面的動(dòng)態(tài)Sql是怎么設(shè)定的?用什么語法?
MyBatis里面的動(dòng)態(tài)Sql一般是通過if節(jié)點(diǎn)來實(shí)現(xiàn),通過0GNL語法來
實(shí)現(xiàn),但是假如要寫的完整,必需協(xié)作where,trim節(jié)點(diǎn),
where節(jié)點(diǎn)是推斷包含節(jié)點(diǎn)有內(nèi)容就插入where,否則不插入,trim節(jié)
點(diǎn)是用來推斷假如動(dòng)態(tài)語句是以and或or起先,那么會自動(dòng)把這個(gè)and或
者or取掉
###8.MyBatis在核心處理類叫什么
MyBatis里面的核心處理類叫做SqlSession
###9.IBatis和MyBatis在細(xì)微環(huán)節(jié)上的不同有哪些
在sql里面變量命名有原來的#變量#變成了#{變量}原來的$變量
$變成了${變量},原來在sql節(jié)點(diǎn)里面的class都換名字交type
原來的queryForObjectqueryForList變成了selectOneselectLis
t
原來的別名設(shè)置在映射文件里面放在了核心配置文件里
###10.講下MyBatis的緩存
MyBatis的緩存分為一級緩存和二級緩存,一級緩存放在session里面,
默認(rèn)就有,二級緩存放在它的命名空間里,
默認(rèn)是打開的,運(yùn)用二級緩存屬性類須要實(shí)現(xiàn)Serializable序列化接
口(可用來保存對象的狀態(tài)),可在它的映射文件中配置<cache/>
###11.MyBatis(IBatis)的好處是什么
ibatis把sql語句從Java源程序中獨(dú)立出來,放在單獨(dú)的XML文件
中編寫,給程序的
維護(hù)帶來了很大便利。
ibatis封裝了底層JDBCAPT的調(diào)用細(xì)微環(huán)節(jié),并能自動(dòng)將結(jié)果集轉(zhuǎn)
換成JavaBean對象,大大簡化了Java數(shù)據(jù)庫編程的重復(fù)工作。
因?yàn)镮batis須要程序員自己去編寫sql語句,程序員可以結(jié)合數(shù)據(jù)庫
自身的特點(diǎn)敏捷限制sql語句,
因此能夠?qū)崿F(xiàn)比hibernate等全自動(dòng)orm框架更高的查詢效率,能夠
完成困難查詢。###12.MyBatis里面怎么處理分頁
用插件分頁
###13,MyBatis里面怎么樣獲得剛插入的主鍵
把insert節(jié)點(diǎn)的useGeneratedKeys=true設(shè)置先生成主鍵,然后keyP
roperty=〃id〃,把生成的主鍵指向?qū)傩?
###1.為什么要用自定義標(biāo)簽?
①Jsp中寫代碼比較混亂,難以維護(hù)
②把一些重復(fù)的功能都抽取出來,便利復(fù)用。
###2.自定義標(biāo)簽分為幾個(gè)步驟.
1.編寫標(biāo)簽處理器類(SimpleTagSupport的實(shí)現(xiàn)類)
重寫doTagO
2.編寫標(biāo)簽庫文件(WEBTNF/xxx.tld)
整個(gè)文件的定義:〈short-name)<uri>
標(biāo)簽的定義:<tag>
3.在jsp頁面運(yùn)用標(biāo)簽:
導(dǎo)入標(biāo)簽庫(xxx.tld/)
運(yùn)用標(biāo)簽
###3.自定義標(biāo)簽類要繼承哪個(gè)類?
SimpleTagSupport類
sim?pietags?'p?rt
###4.怎么配置自定義標(biāo)簽的屬性
在.tld文件<tag>標(biāo)簽中添加〈attribute》,
通過<name>標(biāo)簽設(shè)定自定義標(biāo)簽的標(biāo)簽名。JSTL&EL的面試題部分
###5.為什么要用EL表達(dá)式,有什么好處
1.在頁面中用js腳本和jsp表達(dá)式來獲得數(shù)據(jù)顯示比較麻煩
a:須要條件推斷
b:可能須要強(qiáng)轉(zhuǎn)
2.好處是EL表達(dá)式簡潔易用,默認(rèn)可訪問全部的JSP隱藏對象。
###6.EL表達(dá)式的語法是什么?
美元符號加大括號-->${EL表達(dá)式}
###7.EL有哪兩種訪問格式,有什么區(qū)分?
EL供應(yīng)”和“兩種運(yùn)算符來存取數(shù)據(jù)。
當(dāng)要存取的屬性名稱中包含一些特別字符,如.或一等并非字母或
數(shù)字的符號,就確定要運(yùn)用例如:
${user.My-Name}應(yīng)當(dāng)改為${user[z,My-Name,z]}
假如要?jiǎng)討B(tài)取值時(shí),就可以用“[]“來做,而”?“無法做到動(dòng)態(tài)取
值。例如:${sessionScope.user[data]}中data是一個(gè)變量。
nuns,EL表達(dá)式中有哪些隱藏對象,舉幾個(gè)例子?
pageContext:JSP頁面的上下文
param:參數(shù)
paramValues:參數(shù)值
header:頭信息
headerValues:頭的值
cookie:緩存
initParam:初始化參數(shù)
###9.EL表達(dá)式中怎么樣拿到request,session里面的值?
例:
可以通過它的隱藏對象RequestScope來獲得到Request范圍的屬性名
稱所對應(yīng)的值??梢酝ㄟ^它的隱藏對象sessionScope來獲得到session
范圍的屬性名稱所對應(yīng)的值。
###10.EL表達(dá)式怎么樣拿到用戶懇求的參數(shù)?
可以用${param,name}來獲得用戶懇求的參數(shù)
###1LEL表達(dá)式怎么樣得到上下文路徑?
${pageContext.request.contextPath)
###12.EL表達(dá)式怎么樣拿到request?
RequestScope
###13.JSTL全稱是什么?
java服務(wù)器頁面標(biāo)準(zhǔn)標(biāo)簽庫
(JavaServerPagesStandardTagLibrary)
###14.JSTL是怎么運(yùn)用的?
將jstl.jar、standard,jar復(fù)制到Tomcat的WEB-INF\lib中.若
要在JSP網(wǎng)頁中運(yùn)用JSTL時(shí),確定要先做下面這行聲明:<%?tagli
bprefix=〃c〃uri=z,://java.sun/jsp/jstl/core〃%>
主要供應(yīng)應(yīng)JavaWeb開發(fā)人員一個(gè)標(biāo)準(zhǔn)通用的標(biāo)簽函數(shù)庫。Web程
序開發(fā)人員能夠利用JSTL和EL來開發(fā)Web程序,
取代傳統(tǒng)干脆在頁面上嵌入Java程序(Scripting)的做法,以提高
程序可讀性、維護(hù)性和便利性。
###15,JSTL分為幾個(gè)標(biāo)簽庫?
①核心標(biāo)簽庫
②國際化標(biāo)簽庫
③數(shù)據(jù)庫標(biāo)簽庫
@XML標(biāo)簽庫
⑤函數(shù)標(biāo)簽庫
###16.JSTL里面推斷標(biāo)簽是什么?
1.<c:i
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 建筑工地安全責(zé)任協(xié)議(2025年高空作業(yè))
- 中學(xué)教育教學(xué)成果獎(jiǎng)勵(lì)制度
- 養(yǎng)老院消防安全管理制度
- 養(yǎng)老院安全管理制度
- 企業(yè)內(nèi)部審計(jì)與合規(guī)制度
- 先進(jìn)封裝行業(yè)深度:發(fā)展趨勢、競爭格局、市場空間、產(chǎn)業(yè)鏈及相關(guān)公司深度梳理-
- 老年終末期尿失禁皮膚保護(hù)隨訪管理方案
- 2025年阜新市太平區(qū)公益性崗位招聘真題
- 摩托車裝調(diào)工常識水平考核試卷含答案
- 我國上市公司環(huán)境信息披露水平的多維度實(shí)證剖析與提升路徑研究
- 2026中國電信四川公用信息產(chǎn)業(yè)有限責(zé)任公司社會成熟人才招聘備考題庫完整參考答案詳解
- 2026年黃委會事業(yè)單位考試真題
- 供水管網(wǎng)及配套設(shè)施改造工程可行性研究報(bào)告
- 微電影投資合作協(xié)議書
- 壓鑄鋁合金熔煉改善
- 排水管道溝槽土方開挖專項(xiàng)方案
- JJG 196-2006常用玻璃量器
- GB/T 5277-1985緊固件螺栓和螺釘通孔
- GB/T 32451-2015航天項(xiàng)目管理
- GB/T 12229-2005通用閥門碳素鋼鑄件技術(shù)條件
- 畜禽養(yǎng)殖業(yè)污染防治技術(shù)規(guī)范
評論
0/150
提交評論