53道Java線程面試題_第1頁
53道Java線程面試題_第2頁
53道Java線程面試題_第3頁
53道Java線程面試題_第4頁
53道Java線程面試題_第5頁
已閱讀5頁,還剩50頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論