【Java純干貨知識(shí)匯總|面試必備】

基礎(chǔ)知識(shí)

String 是最基本的數(shù)據(jù)類型嗎?

答:不是浑劳。Java中的基本數(shù)據(jù)類型只有8個(gè):byte阱持、short、int魔熏、long衷咽、float、double蒜绽、char镶骗、boolean;除了基本類型(primitive type)躲雅,剩下的都是引用類型(reference type)鼎姊,Java 5以后引入的枚舉類型也算是一種比較特殊的引用類型。

訪問修飾符public,private,protected,以及不寫(默認(rèn))時(shí)的區(qū)別吏夯?

答:

類的成員不寫訪問修飾時(shí)默認(rèn)為default此蜈。默認(rèn)對(duì)于同一個(gè)包中的其他類相當(dāng)于公開(public),對(duì)于不是同一個(gè)包中的其他類相當(dāng)于私有(private)噪生。受保護(hù)(protected)對(duì)子類相當(dāng)于公開裆赵,對(duì)不是同一包中的沒有父子關(guān)系的類相當(dāng)于私有。Java中跺嗽,外部類的修飾符只能是public或默認(rèn)战授,類的成員(包括內(nèi)部類)的修飾符可以是以上四種页藻。

switch 是否能作用在byte 上,是否能作用在long 上植兰,是否能作用在String上份帐?

答:在Java 5以前,switch(expr)中楣导,expr只能是byte废境、short、char筒繁、int噩凹。從Java 5開始,Java中引入了枚舉類型毡咏,expr也可以是enum類型驮宴,從Java 7開始,expr還可以是字符串(String)呕缭,但是長(zhǎng)整型(long)在目前所有的版本中都是不可以的堵泽。

構(gòu)造器(constructor)是否可被重寫(override)?

答:構(gòu)造器不能被繼承恢总,因此不能被重寫迎罗,但可以被重載。

兩個(gè)對(duì)象值相同(x.equals(y) == true)离熏,但卻可有不同的hash code佳谦,這句話對(duì)不對(duì)戴涝?

答:不對(duì)滋戳,如果兩個(gè)對(duì)象x和y滿足x.equals(y) == true,它們的哈希碼(hash code)應(yīng)當(dāng)相同啥刻。Java對(duì)于eqauls方法和hashCode方法是這樣規(guī)定的:(1)如果兩個(gè)對(duì)象相同(equals方法返回true)奸鸯,那么它們的hashCode值一定要相同;(2)如果兩個(gè)對(duì)象的hashCode相同可帽,它們并不一定相同娄涩。當(dāng)然,你未必要按照要求去做映跟,但是如果你違背了上述原則就會(huì)發(fā)現(xiàn)在使用容器時(shí)蓄拣,相同的對(duì)象可以出現(xiàn)在Set集合中,同時(shí)增加新元素的效率會(huì)大大下降(對(duì)于使用哈希存儲(chǔ)的系統(tǒng)努隙,如果哈希碼頻繁的沖突將會(huì)造成存取性能急劇下降)球恤。

補(bǔ)充:關(guān)于equals和hashCode方法,很多Java程序都知道荸镊,但很多人也就是僅僅知道而已咽斧,在Joshua Bloch的大作《Effective Java》(很多軟件公司堪置,《Effective Java》、《Java編程思想》以及《重構(gòu):改善既有代碼質(zhì)量》是Java程序員必看書籍张惹,如果你還沒看過舀锨,那就趕緊去亞馬遜買一本吧)中是這樣介紹equals方法的:首先equals方法必須滿足自反性(x.equals(x)必須返回true)、對(duì)稱性(x.equals(y)返回true時(shí)宛逗,y.equals(x)也必須返回true)坎匿、傳遞性(x.equals(y)和y.equals(z)都返回true時(shí),x.equals(z)也必須返回true)和一致性(當(dāng)x和y引用的對(duì)象信息沒有被修改時(shí)雷激,多次調(diào)用x.equals(y)應(yīng)該得到同樣的返回值)碑诉,而且對(duì)于任何非null值的引用x,x.equals(null)必須返回false侥锦。實(shí)現(xiàn)高質(zhì)量的equals方法的訣竅包括:1. 使用==操作符檢查"參數(shù)是否為這個(gè)對(duì)象的引用"进栽;2. 使用instanceof操作符檢查"參數(shù)是否為正確的類型";3. 對(duì)于類中的關(guān)鍵屬性恭垦,檢查參數(shù)傳入對(duì)象的屬性是否與之相匹配快毛;4. 編寫完equals方法后,問自己它是否滿足對(duì)稱性番挺、傳遞性唠帝、一致性;5. 重寫equals時(shí)總是要重寫hashCode玄柏;6. 不要將equals方法參數(shù)中的Object對(duì)象替換為其他的類型襟衰,在重寫時(shí)不要忘掉@Override注解。

是否可以繼承String類粪摘?

答:String 類是final類瀑晒,不可以被繼承。

補(bǔ)充:繼承String本身就是一個(gè)錯(cuò)誤的行為徘意,對(duì)String類型最好的重用方式是關(guān)聯(lián)關(guān)系(Has-A)和依賴關(guān)系(Use-A)而不是繼承關(guān)系(Is-A)苔悦。

當(dāng)一個(gè)對(duì)象被當(dāng)作參數(shù)傳遞到一個(gè)方法后,此方法可改變這個(gè)對(duì)象的屬性椎咧,并可返回變化后的結(jié)果玖详,那么這里到底是值傳遞還是引用傳遞?

答:是值傳遞勤讽。Java語言的方法調(diào)用只支持參數(shù)的值傳遞蟋座。

Java中沒有傳引用實(shí)在是非常的不方便,這一點(diǎn)在Java 8中仍然沒有得到改進(jìn)脚牍,正是如此在Java編寫的代碼中才會(huì)出現(xiàn)大量的Wrapper類(將需要通過方法調(diào)用修改的引用置于一個(gè)Wrapper類中向臀,再將Wrapper對(duì)象傳入方法),這樣的做法只會(huì)讓代碼變得臃腫莫矗,尤其是讓從C和C++轉(zhuǎn)型為Java程序員的開發(fā)者無法容忍飒硅。

String和StringBuilder砂缩、StringBuffer的區(qū)別?

答:Java平臺(tái)提供了兩種類型的字符串:String和StringBuffer/StringBuilder三娩,它們可以儲(chǔ)存和操作字符串庵芭。其中String是只讀字符串,也就意味著String引用的字符串內(nèi)容是不能被改變的雀监。而StringBuffer/StringBuilder類表示的字符串對(duì)象可以直接進(jìn)行修改双吆。StringBuilder是Java 5中引入的,它和StringBuffer的方法完全相同会前,區(qū)別在于它是在單線程環(huán)境下使用的好乐,因?yàn)樗乃蟹矫娑紱]有被synchronized修飾,因此它的效率也比StringBuffer要高瓦宜。

面試題:華為的面試題中曾經(jīng)問過這樣一個(gè)問題 - "為什么不能根據(jù)返回類型來區(qū)分重載"蔚万,因?yàn)橹剌d是編譯時(shí)的多態(tài),相同方法临庇,調(diào)用無法知道返回值類型是個(gè)啥反璃。但是,在Class文件可以共存假夺,Java文件不行淮蜈,這是Java虛擬機(jī)規(guī)范和Java語言規(guī)范的不同。

描述一下JVM加載class文件的原理機(jī)制已卷?

答:JVM中類的裝載是由類加載器(ClassLoader)和它的子類來實(shí)現(xiàn)的梧田,Java中的類加載器是一個(gè)重要的Java運(yùn)行時(shí)系統(tǒng)組件,它負(fù)責(zé)在運(yùn)行時(shí)查找和裝入類文件中的類侧蘸。由于Java的跨平臺(tái)性裁眯,經(jīng)過編譯的Java源程序并不是一個(gè)可執(zhí)行程序,而是一個(gè)或多個(gè)類文件闺魏。當(dāng)Java程序需要使用某個(gè)類時(shí)未状,JVM會(huì)確保這個(gè)類已經(jīng)被加載、連接(驗(yàn)證析桥、準(zhǔn)備和解析)和初始化。類的加載是指把類的.class文件中的數(shù)據(jù)讀入到內(nèi)存中艰垂,通常是創(chuàng)建一個(gè)字節(jié)數(shù)組讀入.class文件泡仗,然后產(chǎn)生與所加載類對(duì)應(yīng)的Class對(duì)象。加載完成后猜憎,Class對(duì)象還不完整娩怎,所以此時(shí)的類還不可用。當(dāng)類被加載后就進(jìn)入連接階段胰柑,這一階段包括驗(yàn)證截亦、準(zhǔn)備(為靜態(tài)變量分配內(nèi)存并設(shè)置默認(rèn)的初始值)和解析(將符號(hào)引用替換為直接引用)三個(gè)步驟爬泥。最后JVM對(duì)類進(jìn)行初始化,包括:1)如果類存在直接的父類并且這個(gè)類還沒有被初始化崩瓤,那么就先初始化父類袍啡;2)如果類中存在初始化語句,就依次執(zhí)行這些初始化語句却桶。類的加載是由類加載器完成的境输,類加載器包括:根加載器(BootStrap)、擴(kuò)展加載器(Extension)颖系、系統(tǒng)加載器(System)和用戶自定義類加載器(java.lang.ClassLoader的子類)嗅剖。從Java 2(JDK 1.2)開始,類加載過程采取了父親委托機(jī)制(PDM)嘁扼。PDM更好的保證了Java平臺(tái)的安全性信粮,在該機(jī)制中,JVM自帶的Bootstrap是根加載器趁啸,其他的加載器都有且僅有一個(gè)父類加載器蒋院。類的加載首先請(qǐng)求父類加載器加載,父類加載器無能為力時(shí)才由其子類加載器自行加載莲绰。JVM不會(huì)向Java程序提供對(duì)Bootstrap的引用欺旧。下面是關(guān)于幾個(gè)類加載器的說明:

Bootstrap:一般用本地代碼實(shí)現(xiàn),負(fù)責(zé)加載JVM基礎(chǔ)核心類庫(kù)(rt.jar)蛤签;

Extension:從java.ext.dirs系統(tǒng)屬性所指定的目錄中加載類庫(kù)辞友,它的父加載器是Bootstrap;System:又叫應(yīng)用類加載器震肮,其父類是Extension称龙。它是應(yīng)用最廣泛的類加載器。它從環(huán)境變量classpath或者系統(tǒng)屬性java.class.path所指定的目錄中記載類戳晌,是用戶自定義加載器的默認(rèn)父加載

抽象類(abstract class)和接口(interface)有什么異同鲫尊?

答:抽象類和接口都不能夠?qū)嵗梢远x抽象類和接口類型的引用沦偎。一個(gè)類如果繼承了某個(gè)抽象類或者實(shí)現(xiàn)了某個(gè)接口都需要對(duì)其中的抽象方法全部進(jìn)行實(shí)現(xiàn)疫向,否則該類仍然需要被聲明為抽象類。接口比抽象類更加抽象豪嚎,因?yàn)槌橄箢愔锌梢远x構(gòu)造器搔驼,可以有抽象方法和具體方法,而接口中不能定義構(gòu)造器而且其中的方法全部都是抽象方法侈询。抽象類中的成員可以是private舌涨、默認(rèn)、protected扔字、public的囊嘉,而接口中的成員全都是public的温技。抽象類中可以定義成員變量,而接口中定義的成員變量實(shí)際上都是常量扭粱。有抽象方法的類必須被聲明為抽象類舵鳞,而抽象類未必要有抽象方法。

靜態(tài)嵌套類(Static Nested Class)和內(nèi)部類(Inner Class)的不同焊刹?

答:Static Nested Class是被聲明為靜態(tài)(static)的內(nèi)部類系任,它可以不依賴于外部類實(shí)例被實(shí)例化。而通常的內(nèi)部類需要在外部類實(shí)例化后才能實(shí)例化

Java 中會(huì)存在內(nèi)存泄漏嗎虐块,請(qǐng)簡(jiǎn)單描述俩滥。

答:理論上Java因?yàn)橛欣厥諜C(jī)制(GC)不會(huì)存在內(nèi)存泄露問題(這也是Java被廣泛使用于服務(wù)器端編程的一個(gè)重要原因);然而在實(shí)際開發(fā)中贺奠,可能會(huì)存在無用但可達(dá)的對(duì)象霜旧,這些對(duì)象不能被GC回收,因此也會(huì)導(dǎo)致內(nèi)存泄露的發(fā)生儡率。例如Hibernate的Session(一級(jí)緩存)中的對(duì)象屬于持久態(tài)挂据,垃圾回收器是不會(huì)回收這些對(duì)象的,然而這些對(duì)象中可能存在無用的垃圾對(duì)象儿普,如果不及時(shí)關(guān)閉(close)或清空(flush)一級(jí)緩存就可能導(dǎo)致內(nèi)存泄露

抽象的(abstract)方法是否可同時(shí)是靜態(tài)的(static),是否可同時(shí)是本地方法(native)崎逃,是否可同時(shí)被synchronized修飾?

答:都不能眉孩。抽象方法需要子類重寫个绍,而靜態(tài)的方法是無法被重寫的,因此二者是矛盾的浪汪。本地方法是由本地代碼(如C代碼)實(shí)現(xiàn)的方法巴柿,而抽象方法是沒有實(shí)現(xiàn)的,也是矛盾的死遭。synchronized和方法的實(shí)現(xiàn)細(xì)節(jié)有關(guān)广恢,抽象方法不涉及實(shí)現(xiàn)細(xì)節(jié),因此也是相互矛盾的呀潭。

闡述靜態(tài)變量和實(shí)例變量的區(qū)別钉迷。

答:靜態(tài)變量是被static修飾符修飾的變量,也稱為類變量蜗侈,它屬于類篷牌,不屬于類的任何一個(gè)對(duì)象,一個(gè)類不管創(chuàng)建多少個(gè)對(duì)象踏幻,靜態(tài)變量在內(nèi)存中有且僅有一個(gè)拷貝;實(shí)例變量必須依存于某一實(shí)例戳杀,需要先創(chuàng)建對(duì)象然后通過對(duì)象才能訪問到它该面。靜態(tài)變量可以實(shí)現(xiàn)讓多個(gè)對(duì)象共享內(nèi)存夭苗。

是否可以從一個(gè)靜態(tài)(static)方法內(nèi)部發(fā)出對(duì)非靜態(tài)(non-static)方法的調(diào)用?

答:不可以隔缀,靜態(tài)方法只能訪問靜態(tài)成員题造,因?yàn)榉庆o態(tài)方法的調(diào)用要先創(chuàng)建對(duì)象,在調(diào)用靜態(tài)方法時(shí)可能對(duì)象并沒有被初始化猾瘸。

如何實(shí)現(xiàn)對(duì)象克陆缗狻?

答:有兩種方式: ??1). 實(shí)現(xiàn)Cloneable接口并重寫Object類中的clone()方法牵触; ??2). 實(shí)現(xiàn)Serializable接口淮悼,通過對(duì)象的序列化和反序列化實(shí)現(xiàn)克隆,可以實(shí)現(xiàn)真正的深度克隆

GC是什么揽思?為什么要有GC袜腥?

答:GC是垃圾收集的意思,內(nèi)存處理是編程人員容易出現(xiàn)問題的地方钉汗,忘記或者錯(cuò)誤的內(nèi)存回收會(huì)導(dǎo)致程序或系統(tǒng)的不穩(wěn)定甚至崩潰羹令,Java提供的GC功能可以自動(dòng)監(jiān)測(cè)對(duì)象是否超過作用域從而達(dá)到自動(dòng)回收內(nèi)存的目的,Java語言沒有提供釋放已分配內(nèi)存的顯示操作方法损痰。Java程序員不用擔(dān)心內(nèi)存管理福侈,因?yàn)槔占鲿?huì)自動(dòng)進(jìn)行管理。要請(qǐng)求垃圾收集卢未,可以調(diào)用下面的方法之一:System.gc() 或Runtime.getRuntime().gc() 肪凛,但JVM可以屏蔽掉顯示的垃圾回收調(diào)用。垃圾回收可以有效的防止內(nèi)存泄露尝丐,有效的使用可以使用的內(nèi)存显拜。垃圾回收器通常是作為一個(gè)單獨(dú)的低優(yōu)先級(jí)的線程運(yùn)行,不可預(yù)知的情況下對(duì)內(nèi)存堆中已經(jīng)死亡的或者長(zhǎng)時(shí)間沒有使用的對(duì)象進(jìn)行清除和回收爹袁,程序員不能實(shí)時(shí)的調(diào)用垃圾回收器對(duì)某個(gè)對(duì)象或所有對(duì)象進(jìn)行垃圾回收远荠。在Java誕生初期,垃圾回收是Java最大的亮點(diǎn)之一失息,因?yàn)榉?wù)器端的編程需要有效的防止內(nèi)存泄露問題譬淳,然而時(shí)過境遷,如今Java的垃圾回收機(jī)制已經(jīng)成為被詬病的東西盹兢。移動(dòng)智能終端用戶通常覺得iOS的系統(tǒng)比Android系統(tǒng)有更好的用戶體驗(yàn)邻梆,其中一個(gè)深層次的原因就在于Android系統(tǒng)中垃圾回收的不可預(yù)知性。

補(bǔ)充:垃圾回收機(jī)制有很多種绎秒,包括:分代復(fù)制垃圾回收浦妄、標(biāo)記垃圾回收、增量垃圾回收等方式。標(biāo)準(zhǔn)的Java進(jìn)程既有棧又有堆剂娄。棧保存了原始型局部變量蠢涝,堆保存了要?jiǎng)?chuàng)建的對(duì)象。Java平臺(tái)對(duì)堆內(nèi)存回收和再利用的基本算法被稱為標(biāo)記和清除阅懦,但是Java對(duì)其進(jìn)行了改進(jìn)和二,采用“分代式垃圾收集”。這種方法會(huì)跟Java對(duì)象的生命周期將堆內(nèi)存劃分為不同的區(qū)域耳胎,在垃圾收集過程中惯吕,可能會(huì)將對(duì)象移動(dòng)到不同區(qū)域:

伊甸園(Eden):這是對(duì)象最初誕生的區(qū)域,并且對(duì)大多數(shù)對(duì)象來說怕午,這里是它們唯一存在過的區(qū)域废登。

幸存者樂園(Survivor):從伊甸園幸存下來的對(duì)象會(huì)被挪到這里。

終身頤養(yǎng)園(Tenured):這是足夠老的幸存對(duì)象的歸宿诗轻。年輕代收集(Minor-GC)過程是不會(huì)觸及這個(gè)地方的钳宪。當(dāng)年輕代收集不能把對(duì)象放進(jìn)終身頤養(yǎng)園時(shí),就會(huì)觸發(fā)一次完全收集(Major-GC)扳炬,這里可能還會(huì)牽扯到壓縮吏颖,以便為大對(duì)象騰出足夠的空間。

與垃圾回收相關(guān)的JVM參數(shù):

一個(gè)".java"源文件中是否可以包含多個(gè)類(不是內(nèi)部類)恨樟?有什么限制半醉?

答:可以,但一個(gè)源文件中最多只能有一個(gè)公開類(public class)而且文件名必須和公開類的類名完全保持一致

Java 中的final關(guān)鍵字有哪些用法?

答:(1)修飾類:表示該類不能被繼承;(2)修飾方法:表示方法不能被重寫掉盅;(3)修飾變量:表示變量只能一次賦值以后值不能被修改(常量)凡怎。

Error和Exception有什么區(qū)別殷蛇?

答:Error表示系統(tǒng)級(jí)的錯(cuò)誤和程序不必處理的異常,是恢復(fù)不是不可能但很困難的情況下的一種嚴(yán)重問題;比如內(nèi)存溢出,不可能指望程序能處理這樣的情況逊抡;Exception表示需要捕捉或者需要程序進(jìn)行處理的異常,是一種設(shè)計(jì)或?qū)崿F(xiàn)問題零酪;也就是說冒嫡,它表示如果程序運(yùn)行正常,從不會(huì)發(fā)生的情況四苇。

Java使用異常來表示錯(cuò)誤孝凌,并通過try ... catch捕獲異常;Java的異常是class月腋,并且從Throwable繼承蟀架;Error是無需捕獲的嚴(yán)重錯(cuò)誤瓣赂,Exception是應(yīng)該捕獲的可處理的錯(cuò)誤;RuntimeException無需強(qiáng)制捕獲辜窑,非RuntimeException(Checked Exception)需強(qiáng)制捕獲钩述,或者用throws聲明寨躁;不推薦捕獲了異常但不進(jìn)行任何處理穆碎。

try{}里有一個(gè)return語句,那么緊跟在這個(gè)try后的finally{}里的代碼會(huì)不會(huì)被執(zhí)行职恳,什么時(shí)候被執(zhí)行所禀,在return前還是后?

答:會(huì)執(zhí)行,在finally塊中改變r(jià)eturn的值對(duì)返回值沒有任何影響放钦,而對(duì)引用類型的數(shù)據(jù)會(huì)有影響色徘。

列出一些你常見的運(yùn)行時(shí)異常?

答:

ArithmeticException(算術(shù)異常)

ClassCastException (類轉(zhuǎn)換異常)

IllegalArgumentException (非法參數(shù)異常)

IndexOutOfBoundsException (下標(biāo)越界異常)

NullPointerException (空指針異常)

SecurityException (安全異常)

ClassNotFoundException(指定類不存在)

ArrayIndexOutOfBoundsException(數(shù)據(jù)下標(biāo)越界)

List操禀、Set褂策、Map是否繼承自Collection接口?

答:List颓屑、Set 是斤寂,Map 不是。Map是鍵值對(duì)映射容器揪惦,與List和Set有明顯的區(qū)別遍搞,而Set存儲(chǔ)的零散的元素且不允許有重復(fù)元素(數(shù)學(xué)中的集合也是如此),List是線性結(jié)構(gòu)的容器器腋,適用于按數(shù)值索引訪問元素的情形溪猿。

Collection和Collections的區(qū)別?

答:Collection是一個(gè)接口纫塌,它是Set诊县、List等容器的父接口;Collections是個(gè)一個(gè)工具類措左,提供了一系列的靜態(tài)方法來輔助容器操作依痊,這些方法包括對(duì)容器的搜索、排序媳荒、線程安全化等等抗悍。

Thread類的sleep()方法和對(duì)象的wait()方法都可以讓線程暫停執(zhí)行,它們有什么區(qū)別?

答:sleep()方法(休眠)是線程類(Thread)的靜態(tài)方法钳枕,調(diào)用此方法會(huì)讓當(dāng)前線程暫停執(zhí)行指定的時(shí)間缴渊,將執(zhí)行機(jī)會(huì)(CPU)讓給其他線程,但是對(duì)象的鎖依然保持鱼炒,因此休眠時(shí)間結(jié)束后會(huì)自動(dòng)恢復(fù)(線程回到就緒狀態(tài)衔沼,請(qǐng)參考第66題中的線程狀態(tài)轉(zhuǎn)換圖)。wait()是Object類的方法,調(diào)用對(duì)象的wait()方法導(dǎo)致當(dāng)前線程放棄對(duì)象的鎖(線程暫停執(zhí)行)指蚁,進(jìn)入對(duì)象的等待池(wait pool)菩佑,只有調(diào)用對(duì)象的notify()方法(或notifyAll()方法)時(shí)才能喚醒等待池中的線程進(jìn)入等鎖池(lock pool),如果線程重新獲得對(duì)象的鎖就可以進(jìn)入就緒狀態(tài)凝化。

線程的sleep()方法和yield()方法有什么區(qū)別稍坯?

答:① sleep()方法給其他線程運(yùn)行機(jī)會(huì)時(shí)不考慮線程的優(yōu)先級(jí),因此會(huì)給低優(yōu)先級(jí)的線程以運(yùn)行的機(jī)會(huì)搓劫;yield()方法只會(huì)給相同優(yōu)先級(jí)或更高優(yōu)先級(jí)的線程以運(yùn)行的機(jī)會(huì)瞧哟;② 線程執(zhí)行sleep()方法后轉(zhuǎn)入阻塞(blocked)狀態(tài),而執(zhí)行yield()方法后轉(zhuǎn)入就緒(ready)狀態(tài)枪向;③ sleep()方法聲明拋出InterruptedException勤揩,而yield()方法沒有聲明任何異常;④ sleep()方法比yield()方法(跟操作系統(tǒng)CPU調(diào)度相關(guān))具有更好的可移植性秘蛔。

簡(jiǎn)述synchronized 和java.util.concurrent.locks.Lock的異同陨亡?

答:Lock是Java 5以后引入的新的API,和關(guān)鍵字synchronized相比主要相同點(diǎn):Lock 能完成synchronized所實(shí)現(xiàn)的所有功能深员;主要不同點(diǎn):Lock有比synchronized更精確的線程語義和更好的性能负蠕,而且不強(qiáng)制性的要求一定要獲得鎖。synchronized會(huì)自動(dòng)釋放鎖辨液,而Lock一定要求程序員手工釋放虐急,并且最好在finally 塊中釋放(這是釋放外部資源的最好的地方)。

Java中有幾種類型的流滔迈?

答:字節(jié)流和字符流止吁。字節(jié)流繼承于InputStream、OutputStream燎悍,字符流繼承于Reader敬惦、Writer

事務(wù)的ACID是指什么?

答:

原子性(Atomic):事務(wù)中各項(xiàng)操作谈山,要么全做要么全不做俄删,任何一項(xiàng)操作的失敗都會(huì)導(dǎo)致整個(gè)事務(wù)的失敗奏路;

一致性(Consistent):事務(wù)結(jié)束后系統(tǒng)狀態(tài)是一致的畴椰;

隔離性(Isolated):并發(fā)執(zhí)行的事務(wù)彼此無法看到對(duì)方的中間狀態(tài);

持久性(Durable):事務(wù)完成后所做的改動(dòng)都會(huì)被持久化鸽粉,即使發(fā)生災(zāi)難性的失敗斜脂。通過日志和同步備份可以在故障發(fā)生后重建數(shù)據(jù)。

補(bǔ)充:關(guān)于事務(wù)触机,在面試中被問到的概率是很高的帚戳,可以問的問題也是很多的玷或。首先需要知道的是,只有存在并發(fā)數(shù)據(jù)訪問時(shí)才需要事務(wù)片任。當(dāng)多個(gè)事務(wù)訪問同一數(shù)據(jù)時(shí)偏友,可能會(huì)存在5類問題,包括3類數(shù)據(jù)讀取問題(臟讀对供、不可重復(fù)讀和幻讀)和2類數(shù)據(jù)更新問題(第1類丟失更新和第2類丟失更新)位他。

獲得一個(gè)類的類對(duì)象有哪些方式?

答:

方法1:類型.class犁钟,例如:String.class

方法2:對(duì)象.getClass()棱诱,例如:"hello".getClass()

方法3:Class.forName(),例如:Class.forName("java.lang.String")

如何通過反射創(chuàng)建對(duì)象涝动?

答:

方法1:通過類對(duì)象調(diào)用newInstance()方法,例如:String.class.newInstance()

方法2:通過類對(duì)象的getConstructor()或getDeclaredConstructor()方法獲得構(gòu)造器(Constructor)對(duì)象并調(diào)用其newInstance()方法創(chuàng)建對(duì)象炬灭,例如:String.class.getConstructor(String.class).newInstance("Hello"

什么是UML醋粟?

答:UML是統(tǒng)一建模語言(Unified Modeling Language)的縮寫,它發(fā)表于1997年重归,綜合了當(dāng)時(shí)已經(jīng)存在的面向?qū)ο蟮慕UZ言米愿、方法和過程,是一個(gè)支持模型化和軟件系統(tǒng)開發(fā)的圖形化語言鼻吮,為軟件開發(fā)的所有階段提供模型化和可視化支持育苟。使用UML可以幫助溝通與交流,輔助應(yīng)用設(shè)計(jì)和文檔的生成椎木,還能夠闡釋系統(tǒng)的結(jié)構(gòu)和行為违柏。

UML中有哪些常用的圖?

答:UML定義了多種圖形化的符號(hào)來描述軟件系統(tǒng)部分或全部的靜態(tài)結(jié)構(gòu)和動(dòng)態(tài)結(jié)構(gòu)香椎,包括:用例圖(use case diagram)漱竖、類圖(class diagram)、時(shí)序圖(sequence diagram)畜伐、協(xié)作圖(collaboration diagram)馍惹、狀態(tài)圖(statechart diagram)、活動(dòng)圖(activity diagram)玛界、構(gòu)件圖(component diagram)万矾、部署圖(deployment diagram)等。在這些圖形化符號(hào)中慎框,有三種圖最為重要良狈,分別是:用例圖(用來捕獲需求,描述系統(tǒng)的功能鲤脏,通過該圖可以迅速的了解系統(tǒng)的功能模塊及其關(guān)系)们颜、類圖(描述類以及類與類之間的關(guān)系吕朵,通過該圖可以快速了解系統(tǒng))、時(shí)序圖(描述執(zhí)行特定任務(wù)時(shí)對(duì)象之間的交互關(guān)系以及執(zhí)行順序窥突,通過該圖可以了解對(duì)象能接收的消息也就是說對(duì)象能夠向外界提供的服務(wù))努溃。

Java Web方面

闡述Servlet和CGI的區(qū)別?

答:Servlet與CGI的區(qū)別在于Servlet處于服務(wù)器進(jìn)程中,它通過多線程方式運(yùn)行其service()方法阻问,一個(gè)實(shí)例可以服務(wù)于多個(gè)請(qǐng)求梧税,并且其實(shí)例一般不會(huì)銷毀,而CGI對(duì)每個(gè)請(qǐng)求都產(chǎn)生新的進(jìn)程称近,服務(wù)完成后就銷毀第队,所以效率上低于Servlet。

補(bǔ)充:Sun Microsystems公司在1996年發(fā)布Servlet技術(shù)就是為了和CGI進(jìn)行競(jìng)爭(zhēng)刨秆,Servlet是一個(gè)特殊的Java程序凳谦,一個(gè)基于Java的Web應(yīng)用通常包含一個(gè)或多個(gè)Servlet類。Servlet不能夠自行創(chuàng)建并執(zhí)行衡未,它是在Servlet容器中運(yùn)行的尸执,容器將用戶的請(qǐng)求傳遞給Servlet程序,并將Servlet的響應(yīng)回傳給用戶缓醋。通常一個(gè)Servlet會(huì)關(guān)聯(lián)一個(gè)或多個(gè)JSP頁(yè)面如失。以前CGI經(jīng)常因?yàn)樾阅荛_銷上的問題被詬病,然而Fast CGI早就已經(jīng)解決了CGI效率上的問題送粱,所以面試的時(shí)候大可不必信口開河的詬病CGI褪贵,事實(shí)上有很多你熟悉的網(wǎng)站都使用了CGI技術(shù)。

Servlet接口中有哪些方法抗俄?

答:Servlet接口定義了5個(gè)方法脆丁,其中前三個(gè)方法與Servlet生命周期相關(guān):

void init(ServletConfig config) throws ServletException

void service(ServletRequest req, ServletResponse resp) throws ServletException, java.io.IOException

void destory()

java.lang.String getServletInfo()

ServletConfig getServletConfig()

Web容器加載Servlet并將其實(shí)例化后,Servlet生命周期開始橄镜,容器運(yùn)行其init()方法進(jìn)行Servlet的初始化偎快;請(qǐng)求到達(dá)時(shí)調(diào)用Servlet的service()方法,service()方法會(huì)根據(jù)需要調(diào)用與請(qǐng)求對(duì)應(yīng)的doGet或doPost等方法洽胶;當(dāng)服務(wù)器關(guān)閉或項(xiàng)目被卸載時(shí)服務(wù)器會(huì)將Servlet實(shí)例銷毀晒夹,此時(shí)會(huì)調(diào)用Servlet的destroy()方法

轉(zhuǎn)發(fā)(forward)和重定向(redirect)的區(qū)別?

答:forward是容器中控制權(quán)的轉(zhuǎn)向姊氓,是服務(wù)器請(qǐng)求資源丐怯,服務(wù)器直接訪問目標(biāo)地址的URL,把那個(gè)URL 的響應(yīng)內(nèi)容讀取過來翔横,然后把這些內(nèi)容再發(fā)給瀏覽器读跷,瀏覽器根本不知道服務(wù)器發(fā)送的內(nèi)容是從哪兒來的,所以它的地址欄中還是原來的地址禾唁。redirect就是服務(wù)器端根據(jù)邏輯效览,發(fā)送一個(gè)狀態(tài)碼无切,告訴瀏覽器重新去請(qǐng)求那個(gè)地址,因此從瀏覽器的地址欄中可以看到跳轉(zhuǎn)后的鏈接地址丐枉,很明顯redirect無法訪問到服務(wù)器保護(hù)起來資源哆键,但是可以從一個(gè)網(wǎng)站redirect到其他網(wǎng)站。forward更加高效瘦锹,所以在滿足需要時(shí)盡量使用forward(通過調(diào)用RequestDispatcher對(duì)象的forward()方法籍嘹,該對(duì)象可以通過ServletRequest對(duì)象的getRequestDispatcher()方法獲得),并且這樣也有助于隱藏實(shí)際的鏈接弯院;在有些情況下辱士,比如需要訪問一個(gè)其它服務(wù)器上的資源,則必須使用重定向(通過HttpServletResponse對(duì)象調(diào)用其sendRedirect()方法實(shí)現(xiàn))听绳。

get和post請(qǐng)求的區(qū)別颂碘?

答:①get請(qǐng)求用來從服務(wù)器上獲得資源,而post是用來向服務(wù)器提交數(shù)據(jù)辫红;②get將表單中數(shù)據(jù)按照name=value的形式凭涂,添加到action 所指向的URL 后面,并且兩者使用"?"連接贴妻,而各個(gè)變量之間使用"&"連接;post是將表單中的數(shù)據(jù)放在HTTP協(xié)議的請(qǐng)求頭或消息體中蝙斜,傳遞到action所指向URL名惩;③get傳輸?shù)臄?shù)據(jù)要受到URL長(zhǎng)度限制(1024字節(jié));而post可以傳輸大量的數(shù)據(jù)孕荠,上傳文件通常要使用post方式娩鹉;④使用get時(shí)參數(shù)會(huì)顯示在地址欄上,如果這些數(shù)據(jù)不是敏感數(shù)據(jù)稚伍,那么可以使用get弯予;對(duì)于敏感數(shù)據(jù)還是應(yīng)用使用post;⑤get使用MIME類型application/x-www-form-urlencoded的URL編碼(也叫百分號(hào)編碼)文本的格式傳遞參數(shù)个曙,保證被傳送的參數(shù)由遵循規(guī)范的文本組成锈嫩,例如一個(gè)空格的編碼是"%20"。

什么是Web Service(Web服務(wù))垦搬?

答:從表面上看呼寸,Web Service就是一個(gè)應(yīng)用程序,它向外界暴露出一個(gè)能夠通過Web進(jìn)行調(diào)用的API猴贰。這就是說对雪,你能夠用編程的方法透明的調(diào)用這個(gè)應(yīng)用程序,不需要了解它的任何細(xì)節(jié)米绕,跟你使用的編程語言也沒有關(guān)系瑟捣。例如可以創(chuàng)建一個(gè)提供天氣預(yù)報(bào)的Web Service馋艺,那么無論你用哪種編程語言開發(fā)的應(yīng)用都可以通過調(diào)用它的API并傳入城市信息來獲得該城市的天氣預(yù)報(bào)。之所以稱之為Web Service迈套,是因?yàn)樗贖TTP協(xié)議傳輸數(shù)據(jù)捐祠,這使得運(yùn)行在不同機(jī)器上的不同應(yīng)用無須借助附加的、專門的第三方軟件或硬件交汤,就可相互交換數(shù)據(jù)或集成雏赦。

補(bǔ)充:這里必須要提及的一個(gè)概念是SOA(Service-Oriented Architecture,面向服務(wù)的架構(gòu))芙扎,SOA是一種思想星岗,它將應(yīng)用程序的不同功能單元通過中立的契約聯(lián)系起來,獨(dú)立于硬件平臺(tái)戒洼、操作系統(tǒng)和編程語言俏橘,使得各種形式的功能單元能夠更好的集成。顯然圈浇,Web Service是SOA的一種較好的解決方案寥掐,它更多的是一種標(biāo)準(zhǔn),而不是一種具體的技術(shù)磷蜀。

JVM 底層 與 GC(Garbage Collection) 的面試問題

Java中的引用類型

JRE JDK JVM JIT的區(qū)別

內(nèi)存的的面試問題和答案

final召耘、finalize 和 finally 的不同之處?

Java 中的編譯期常量是什么褐隆?使用它又什么風(fēng)險(xiǎn)污它?

公共靜態(tài)不可變(public static final )變量也就是我們所說的編譯期常量,這里的 public 可選的庶弃。

Java 集合框架的面試題

List衫贬、Set、Map 和 Queue 之間的區(qū)別

從數(shù)據(jù)結(jié)構(gòu)角度看集合的區(qū)別有如下:

動(dòng)態(tài)數(shù)組:ArrayList 內(nèi)部是動(dòng)態(tài)數(shù)組歇攻,HashMap 內(nèi)部的鏈表數(shù)組也是動(dòng)態(tài)擴(kuò)展的固惯,ArrayDeque 和 PriorityQueue 內(nèi)部也都是動(dòng)態(tài)擴(kuò)展的數(shù)組。鏈表:LinkedList 是用雙向鏈表實(shí)現(xiàn)的缴守,HashMap 中映射到同一個(gè)鏈表數(shù)組的鍵值對(duì)是通過單向鏈表鏈接起來的葬毫,LinkedHashMap 中每個(gè)元素還加入到了一個(gè)雙向鏈表中以維護(hù)插入或訪問順序。哈希表:HashMap 是用哈希表實(shí)現(xiàn)的斧散,HashSet, LinkedHashSet 和 LinkedHashMap 基于 HashMap供常,內(nèi)部當(dāng)然也是哈希表。排序二叉樹:TreeMap 是用紅黑樹(基于排序二叉樹)實(shí)現(xiàn)的鸡捐,TreeSet 內(nèi)部使用 TreeMap栈暇,當(dāng)然也是紅黑樹,紅黑樹能保持元素的順序且綜合性能很高箍镜。堆:PriorityQueue 是用堆實(shí)現(xiàn)的源祈,堆邏輯上是樹煎源,物理上是動(dòng)態(tài)數(shù)組,堆可以高效地解決一些其他數(shù)據(jù)結(jié)構(gòu)難以解決的問題香缺。循環(huán)數(shù)組:ArrayDeque 是用循環(huán)數(shù)組實(shí)現(xiàn)的手销,通過對(duì)頭尾變量的維護(hù),實(shí)現(xiàn)了高效的隊(duì)列操作图张。位向量:EnumSet 是用位向量實(shí)現(xiàn)的锋拖,對(duì)于只有兩種狀態(tài)且需要進(jìn)行集合運(yùn)算的數(shù)據(jù)使用位向量進(jìn)行表示、位運(yùn)算進(jìn)行處理祸轮,精簡(jiǎn)且高效

Java 中怎么打印數(shù)組兽埃?(answer答案)

你可以使用 Arrays.toString() 和 Arrays.deepToString() 方法來打印數(shù)組。由于數(shù)組沒有實(shí)現(xiàn) toString() 方法适袜,所以如果將數(shù)組傳遞給 System.out.println() 方法柄错,將無法打印出數(shù)組的內(nèi)容,但是 Arrays.toString() 可以打印每個(gè)元素苦酱。

ArrayList 和 HashMap 的默認(rèn)大小是多數(shù)售貌?

在 Java 7 中,ArrayList 的默認(rèn)大小是 10 個(gè)元素疫萤,HashMap 的默認(rèn)大小是16個(gè)元素(必須是2的冪)颂跨。這就是 Java 7 中 ArrayList 和 HashMap 類的代碼片段:

// from ArrayList.java JDK 1.7

private static final int DEFAULT_CAPACITY = 10;

//from HashMap.java JDK 7

static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16

Java 中,Comparator 與 Comparable 有什么不同扯饶?

Comparable 接口用于定義對(duì)象的自然順序毫捣,而 comparator 通常用于定義用戶定制的順序。Comparable 總是只有一個(gè)帝际,但是可以有多個(gè) comparator 來定義對(duì)象的順序。

Java IO 和 NIO 的面試題

Date饶辙、Time 及 Calendar 的面試題

Java 中 java.util.Date 與 java.sql.Date 有什么區(qū)別蹲诀?

java.sql.Date是針對(duì)SQL語句使用的,它只包含日期而沒有時(shí)間部分,它們都有g(shù)etTime方法返回毫秒數(shù)弃揽,自然就可以直接構(gòu)建脯爪。java.util.Date 是 java.sql.Date 的父類,前者是常用的表示時(shí)間的類矿微,我們通常格式化或者得到當(dāng)前時(shí)間都是用他痕慢,后者之后在讀寫數(shù)據(jù)庫(kù)的時(shí)候用他,因?yàn)镻reparedStament的setDate()的第2參數(shù)和ResultSet的getDate()方法的第2個(gè)參數(shù)都是java.sql.Date涌矢。

單元測(cè)試 JUnit 面試題

如何測(cè)試靜態(tài)方法掖举?

可以使用 PowerMock 庫(kù)來測(cè)試靜態(tài)方法。

關(guān)于 OOP 和設(shè)計(jì)模式的面試題

接口是什么娜庇?為什么要使用接口而不是直接使用具體類塔次?

接口用于定義 API方篮。它定義了類必須得遵循的規(guī)則。同時(shí)励负,它提供了一種抽象藕溅,因?yàn)榭蛻舳酥皇褂媒涌冢@樣可以有多重實(shí)現(xiàn)继榆,如 List 接口巾表,你可以使用可隨機(jī)訪問的 ArrayList,也可以使用方便插入和刪除的 LinkedList略吨。接口中不允許寫代碼集币,以此來保證抽象,但是 Java 8 中你可以在接口聲明靜態(tài)的默認(rèn)方法晋南,這種方法是具體的惠猿。

Java 中,抽象類與接口之間有什么不同负间?

Java 中偶妖,抽象類和接口有很多不同之處,但是最重要的一個(gè)是 Java 中限制一個(gè)類只能繼承一個(gè)類政溃,但是可以實(shí)現(xiàn)多個(gè)接口趾访。抽象類可以很好的定義一個(gè)家族類的默認(rèn)行為,而接口能更好的定義類型董虱,有助于后面實(shí)現(xiàn)多態(tài)機(jī)制扼鞋。

Java中CyclicBarrier 和 CountDownLatch有什么不同?

CyclicBarrier 和 CountDownLatch 都可以用來讓一組線程等待其它線程愤诱。與 CyclicBarrier 不同的是云头,CountdownLatch 不能重新使用。

如何避免死鎖淫半?

死鎖是指兩個(gè)或兩個(gè)以上的進(jìn)程在執(zhí)行過程中溃槐,因爭(zhēng)奪資源而造成的一種互相等待的現(xiàn)象,若無外力作用科吭,它們都將無法推進(jìn)下去昏滴。這是一個(gè)嚴(yán)重的問題,因?yàn)樗梨i會(huì)讓你的程序掛起無法完成任務(wù)对人,死鎖的發(fā)生必須滿足以下四個(gè)條件:互斥條件:一個(gè)資源每次只能被一個(gè)進(jìn)程使用谣殊。請(qǐng)求與保持條件:一個(gè)進(jìn)程因請(qǐng)求資源而阻塞時(shí),對(duì)已獲得的資源保持不放牺弄。不剝奪條件:進(jìn)程已獲得的資源姻几,在末使用完之前,不能強(qiáng)行剝奪。循環(huán)等待條件:若干進(jìn)程之間形成一種頭尾相接的循環(huán)等待資源關(guān)系鲜棠。最簡(jiǎn)單的方法就是阻止循環(huán)等待條件肌厨,將系統(tǒng)中所有的資源設(shè)置標(biāo)志位、排序豁陆,規(guī)定所有的進(jìn)程申請(qǐng)資源必須以一定的順序(升序或降序)做操作來避免死鎖柑爸。這篇教程有代碼示例和避免死鎖的討論細(xì)節(jié)。

Java中活鎖和死鎖有什么區(qū)別盒音?

這是上題的擴(kuò)展表鳍,活鎖和死鎖類似,不同之處在于處于活鎖的線程或進(jìn)程的狀態(tài)是不斷改變的祥诽,活鎖可以認(rèn)為是一種特殊的饑餓譬圣。一個(gè)現(xiàn)實(shí)的活鎖例子是兩個(gè)人在狹小的走廊碰到,兩個(gè)人都試著避讓對(duì)方好讓彼此通過雄坪,但是因?yàn)楸茏尩姆较蚨家粯訉?dǎo)致最后誰都不能通過走廊厘熟。簡(jiǎn)單的說就是,活鎖和死鎖的主要區(qū)別是前者進(jìn)程的狀態(tài)可以改變但是卻不能繼續(xù)執(zhí)行维哈。

怎么檢測(cè)一個(gè)線程是否擁有鎖绳姨?

在java.lang.Thread中有一個(gè)方法叫holdsLock(),它返回true如果當(dāng)且僅當(dāng)當(dāng)前線程擁有某個(gè)具體對(duì)象的鎖

JVM中哪個(gè)參數(shù)是用來控制線程的棧堆棧小阔挠,

-Xss參數(shù)用來控制線程的堆棧大小

Java中synchronized 和 ReentrantLock 有什么不同飘庄?

Java在過去很長(zhǎng)一段時(shí)間只能通過synchronized關(guān)鍵字來實(shí)現(xiàn)互斥,它有一些缺點(diǎn)购撼。比如你不能擴(kuò)展鎖之外的方法或者塊邊界跪削,嘗試獲取鎖時(shí)不能中途取消等。Java 5 通過Lock接口提供了更復(fù)雜的控制來解決這些問題迂求。 ReentrantLock 類實(shí)現(xiàn)了 Lock碾盐,它擁有與 synchronized 相同的并發(fā)性和內(nèi)存語義且它還具有可擴(kuò)展性。

Thread類中的yield方法有什么作用

Yield方法可以暫停當(dāng)前正在執(zhí)行的線程對(duì)象揩局,讓其它有相同優(yōu)先級(jí)的線程執(zhí)行廓旬。它是一個(gè)靜態(tài)方法而且只保證當(dāng)前線程放棄CPU占用而不能保證使其它線程一定能占用CPU,執(zhí)行yield()的線程有可能在進(jìn)入到暫停狀態(tài)后馬上又被執(zhí)行谐腰。

Java中ConcurrentHashMap的并發(fā)度是什么?

ConcurrentHashMap把實(shí)際map劃分成若干部分來實(shí)現(xiàn)它的可擴(kuò)展性和線程安全涩盾。這種劃分是使用并發(fā)度獲得的十气,它是ConcurrentHashMap類構(gòu)造函數(shù)的一個(gè)可選參數(shù),默認(rèn)值為16春霍,這樣在多線程情況下就能避免爭(zhēng)用砸西。

框架內(nèi)容

Hibernate中SessionFactory是線程安全的嗎?Session是線程安全的嗎(兩個(gè)線程能夠共享同一個(gè)Session嗎)?

答:SessionFactory對(duì)應(yīng)Hibernate的一個(gè)數(shù)據(jù)存儲(chǔ)的概念芹枷,它是線程安全的衅疙,可以被多個(gè)線程并發(fā)訪問。SessionFactory一般只會(huì)在啟動(dòng)的時(shí)候構(gòu)建鸳慈。對(duì)于應(yīng)用程序饱溢,最好將SessionFactory通過單例模式進(jìn)行封裝以便于訪問。Session是一個(gè)輕量級(jí)非線程安全的對(duì)象(線程間不能共享session)走芋,它表示與數(shù)據(jù)庫(kù)進(jìn)行交互的一個(gè)工作單元绩郎。Session是由SessionFactory創(chuàng)建的,在任務(wù)完成之后它會(huì)被關(guān)閉翁逞。Session是持久層服務(wù)對(duì)外提供的主要接口肋杖。Session會(huì)延遲獲取數(shù)據(jù)庫(kù)連接(也就是在需要的時(shí)候才會(huì)獲取)挖函。為了避免創(chuàng)建太多的session状植,可以使用ThreadLocal將session和當(dāng)前線程綁定在一起,這樣可以讓同一個(gè)線程獲得的總是同一個(gè)session怨喘。Hibernate 3中SessionFactory的getCurrentSession()方法就可以做到津畸。

什么是IoC和DI?DI是如何實(shí)現(xiàn)的哲思?

答:IoC叫控制反轉(zhuǎn)洼畅,是Inversion of Control的縮寫,DI(Dependency Injection)叫依賴注入棚赔,是對(duì)IoC更簡(jiǎn)單的詮釋帝簇。控制反轉(zhuǎn)是把傳統(tǒng)上由程序代碼直接操控的對(duì)象的調(diào)用權(quán)交給容器靠益,通過容器來實(shí)現(xiàn)對(duì)象組件的裝配和管理丧肴。所謂的"控制反轉(zhuǎn)"就是對(duì)組件對(duì)象控制權(quán)的轉(zhuǎn)移,從程序代碼本身轉(zhuǎn)移到了外部容器胧后,由容器來創(chuàng)建對(duì)象并管理對(duì)象之間的依賴關(guān)系芋浮。IoC體現(xiàn)了好萊塢原則 - "Don’t call me, we will call you"。依賴注入的基本原則是應(yīng)用組件不應(yīng)該負(fù)責(zé)查找資源或者其他依賴的協(xié)作對(duì)象壳快。配置對(duì)象的工作應(yīng)該由容器負(fù)責(zé)纸巷,查找資源的邏輯應(yīng)該從應(yīng)用組件的代碼中抽取出來,交給容器來完成眶痰。DI是對(duì)IoC更準(zhǔn)確的描述瘤旨,即組件之間的依賴關(guān)系由容器在運(yùn)行期決定,形象的來說竖伯,即由容器動(dòng)態(tài)的將某種依賴關(guān)系注入到組件之中存哲。

Spring中Bean的作用域有哪些因宇?

答:在Spring的早期版本中,僅有兩個(gè)作用域:singleton和prototype祟偷,前者表示Bean以單例的方式存在察滑;后者表示每次從容器中調(diào)用Bean時(shí),都會(huì)返回一個(gè)新的實(shí)例修肠,prototype通常翻譯為原型贺辰。

補(bǔ)充:設(shè)計(jì)模式中的創(chuàng)建型模式中也有一個(gè)原型模式,原型模式也是一個(gè)常用的模式氛赐,例如做一個(gè)室內(nèi)設(shè)計(jì)軟件魂爪,所有的素材都在工具箱中,而每次從工具箱中取出的都是素材對(duì)象的一個(gè)原型艰管,可以通過對(duì)象克隆來實(shí)現(xiàn)原型模式滓侍。

Spring 2.x中針對(duì)WebApplicationContext新增了3個(gè)作用域,分別是:request(每次HTTP請(qǐng)求都會(huì)創(chuàng)建一個(gè)新的Bean)牲芋、session(同一個(gè)HttpSession共享同一個(gè)Bean撩笆,不同的HttpSession使用不同的Bean)和globalSession(同一個(gè)全局Session共享一個(gè)Bean)。

說明:?jiǎn)卫J胶驮湍J蕉际侵匾脑O(shè)計(jì)模式缸浦。一般情況下夕冲,無狀態(tài)或狀態(tài)不可變的類適合使用單例模式。在傳統(tǒng)開發(fā)中裂逐,由于DAO持有Connection這個(gè)非線程安全對(duì)象因而沒有使用單例模式歹鱼;但在Spring環(huán)境下,所有DAO類對(duì)可以采用單例模式卜高,因?yàn)镾pring利用AOP和Java API中的ThreadLocal對(duì)非線程安全的對(duì)象進(jìn)行了特殊處理弥姻。

解釋一下什么叫AOP(面向切面編程)?

答:AOP(Aspect-Oriented Programming)指一種程序設(shè)計(jì)范型掺涛,該范型以一種稱為切面(aspect)的語言構(gòu)造為基礎(chǔ)庭敦,切面是一種新的模塊化機(jī)制,用來描述分散在對(duì)象薪缆、類或方法中的橫切關(guān)注點(diǎn)(crosscutting concern)秧廉。"橫切關(guān)注"是會(huì)影響到整個(gè)應(yīng)用程序的關(guān)注功能,它跟正常的業(yè)務(wù)邏輯是正交的拣帽,沒有必然的聯(lián)系疼电,但是幾乎所有的業(yè)務(wù)邏輯都會(huì)涉及到這些關(guān)注功能。通常减拭,事務(wù)澜沟、日志、安全性等關(guān)注就是應(yīng)用中的橫切關(guān)注功能峡谊。

你如何理解AOP中的連接點(diǎn)(Joinpoint)、切點(diǎn)(Pointcut)、增強(qiáng)(Advice)既们、引介(Introduction)濒析、織入(Weaving)、切面(Aspect)這些概念啥纸?

答:

連接點(diǎn)(Joinpoint):程序執(zhí)行的某個(gè)特定位置(如:某個(gè)方法調(diào)用前号杏、調(diào)用后,方法拋出異常后)斯棒。一個(gè)類或一段程序代碼擁有一些具有邊界性質(zhì)的特定點(diǎn)盾致,這些代碼中的特定點(diǎn)就是連接點(diǎn)。Spring僅支持方法的連接點(diǎn)荣暮。

切點(diǎn)(Pointcut):如果連接點(diǎn)相當(dāng)于數(shù)據(jù)中的記錄庭惜,那么切點(diǎn)相當(dāng)于查詢條件,一個(gè)切點(diǎn)可以匹配多個(gè)連接點(diǎn)穗酥。Spring AOP的規(guī)則解析引擎負(fù)責(zé)解析切點(diǎn)所設(shè)定的查詢條件护赊,找到對(duì)應(yīng)的連接點(diǎn)。

增強(qiáng)(Advice):增強(qiáng)是織入到目標(biāo)類連接點(diǎn)上的一段程序代碼砾跃。Spring提供的增強(qiáng)接口都是帶方位名的骏啰,如:BeforeAdvice、AfterReturningAdvice抽高、ThrowsAdvice等判耕。很多資料上將增強(qiáng)譯為“通知”,這明顯是個(gè)詞不達(dá)意的翻譯翘骂,讓很多程序員困惑了許久壁熄。

說明: Advice在國(guó)內(nèi)的很多書面資料中都被翻譯成"通知",但是很顯然這個(gè)翻譯無法表達(dá)其本質(zhì)雏胃,有少量的讀物上將這個(gè)詞翻譯為"增強(qiáng)"请毛,這個(gè)翻譯是對(duì)Advice較為準(zhǔn)確的詮釋,我們通過AOP將橫切關(guān)注功能加到原有的業(yè)務(wù)邏輯上瞭亮,這就是對(duì)原有業(yè)務(wù)邏輯的一種增強(qiáng)方仿,這種增強(qiáng)可以是前置增強(qiáng)、后置增強(qiáng)统翩、返回后增強(qiáng)仙蚜、拋異常時(shí)增強(qiáng)和包圍型增強(qiáng)。

引介(Introduction):引介是一種特殊的增強(qiáng)厂汗,它為類添加一些屬性和方法委粉。這樣,即使一個(gè)業(yè)務(wù)類原本沒有實(shí)現(xiàn)某個(gè)接口娶桦,通過引介功能贾节,可以動(dòng)態(tài)的未該業(yè)務(wù)類添加接口的實(shí)現(xiàn)邏輯汁汗,讓業(yè)務(wù)類成為這個(gè)接口的實(shí)現(xiàn)類。

織入(Weaving):織入是將增強(qiáng)添加到目標(biāo)類具體連接點(diǎn)上的過程栗涂,AOP有三種織入方式:①編譯期織入:需要特殊的Java編譯期(例如AspectJ的ajc)知牌;②裝載期織入:要求使用特殊的類加載器,在裝載類的時(shí)候?qū)︻愡M(jìn)行增強(qiáng)斤程;③運(yùn)行時(shí)織入:在運(yùn)行時(shí)為目標(biāo)類生成代理實(shí)現(xiàn)增強(qiáng)角寸。Spring采用了動(dòng)態(tài)代理的方式實(shí)現(xiàn)了運(yùn)行時(shí)織入,而AspectJ采用了編譯期織入和裝載期織入的方式忿墅。

切面(Aspect):切面是由切點(diǎn)和增強(qiáng)(引介)組成的扁藕,它包括了對(duì)橫切關(guān)注功能的定義,也包括了對(duì)連接點(diǎn)的定義疚脐。

補(bǔ)充:代理模式是GoF提出的23種設(shè)計(jì)模式中最為經(jīng)典的模式之一亿柑,代理模式是對(duì)象的結(jié)構(gòu)模式,它給某一個(gè)對(duì)象提供一個(gè)代理對(duì)象亮曹,并由代理對(duì)象控制對(duì)原對(duì)象的引用橄杨。簡(jiǎn)單的說,代理對(duì)象可以完成比原對(duì)象更多的職責(zé)照卦,當(dāng)需要為原對(duì)象添加橫切關(guān)注功能時(shí)式矫,就可以使用原對(duì)象的代理對(duì)象。我們?cè)诖蜷_Office系列的Word文檔時(shí)役耕,如果文檔中有插圖采转,當(dāng)文檔剛加載時(shí),文檔中的插圖都只是一個(gè)虛框占位符瞬痘,等用戶真正翻到某頁(yè)要查看該圖片時(shí)故慈,才會(huì)真正加載這張圖,這其實(shí)就是對(duì)代理模式的使用框全,代替真正圖片的虛框就是一個(gè)虛擬代理察绷;Hibernate的load方法也是返回一個(gè)虛擬代理對(duì)象,等用戶真正需要訪問對(duì)象的屬性時(shí)津辩,才向數(shù)據(jù)庫(kù)發(fā)出SQL語句獲得真實(shí)對(duì)象拆撼。

Spring MVC的工作原理是怎樣的?

答:Spring MVC的工作原理如下圖所示:

① 客戶端的所有請(qǐng)求都交給前端控制器DispatcherServlet來處理喘沿,它會(huì)負(fù)責(zé)調(diào)用系統(tǒng)的其他模塊來真正處理用戶的請(qǐng)求淆院。

② DispatcherServlet收到請(qǐng)求后舅桩,將根據(jù)請(qǐng)求的信息(包括URL印屁、HTTP協(xié)議方法兴想、請(qǐng)求頭、請(qǐng)求參數(shù)窄赋、Cookie等)以及HandlerMapping的配置找到處理該請(qǐng)求的Handler(任何一個(gè)對(duì)象都可以作為請(qǐng)求的Handler)哟冬。

③在這個(gè)地方Spring會(huì)通過HandlerAdapter對(duì)該處理器進(jìn)行封裝楼熄。

④ HandlerAdapter是一個(gè)適配器,它用統(tǒng)一的接口對(duì)各種Handler中的方法進(jìn)行調(diào)用浩峡。

⑤ Handler完成對(duì)用戶請(qǐng)求的處理后孝赫,會(huì)返回一個(gè)ModelAndView對(duì)象給DispatcherServlet,ModelAndView顧名思義红符,包含了數(shù)據(jù)模型以及相應(yīng)的視圖的信息。

⑥ ModelAndView的視圖是邏輯視圖伐债,DispatcherServlet還要借助ViewResolver完成從邏輯視圖到真實(shí)視圖對(duì)象的解析工作预侯。

⑦ 當(dāng)?shù)玫秸嬲囊晥D對(duì)象后,DispatcherServlet會(huì)利用視圖對(duì)象對(duì)模型數(shù)據(jù)進(jìn)行渲染峰锁。

⑧ 客戶端得到響應(yīng)萎馅,可能是一個(gè)普通的HTML頁(yè)面,也可以是XML或JSON字符串虹蒋,還可以是一張圖片或者一個(gè)PDF文件糜芳。

闡述Spring框架中Bean的生命周期?

答:

① Spring IoC容器找到關(guān)于Bean的定義并實(shí)例化該Bean魄衅。

② Spring IoC容器對(duì)Bean進(jìn)行依賴注入峭竣。

③ 如果Bean實(shí)現(xiàn)了BeanNameAware接口,則將該Bean的id傳給setBeanName方法晃虫。

④ 如果Bean實(shí)現(xiàn)了BeanFactoryAware接口皆撩,則將BeanFactory對(duì)象傳給setBeanFactory方法。

⑤ 如果Bean實(shí)現(xiàn)了BeanPostProcessor接口哲银,則調(diào)用其postProcessBeforeInitialization方法扛吞。

⑥ 如果Bean實(shí)現(xiàn)了InitializingBean接口,則調(diào)用其afterPropertySet方法荆责。

⑦ 如果有和Bean關(guān)聯(lián)的BeanPostProcessors對(duì)象滥比,則這些對(duì)象的postProcessAfterInitialization方法被調(diào)用。

⑧ 當(dāng)銷毀Bean實(shí)例時(shí)做院,如果Bean實(shí)現(xiàn)了DisposableBean接口盲泛,則調(diào)用其destroy方法。

在Web項(xiàng)目中如何獲得Spring的IoC容器山憨?

答:

WebApplicationContext ctx =

WebApplicationContextUtils.getWebApplicationContext(servletContext);

并發(fā)

什么是線程死鎖?如何避免死鎖?

多個(gè)線程同時(shí)被阻塞查乒,它們中的一個(gè)或者全部都在等待某個(gè)資源被釋放。由于線程被無限期地阻塞郁竟,因此程序不可能正常終止玛迄。

如下圖所示,線程 A 持有資源 2棚亩,線程 B 持有資源 1蓖议,他們同時(shí)都想申請(qǐng)對(duì)方的資源虏杰,所以這兩個(gè)線程就會(huì)互相等待而進(jìn)入死鎖狀態(tài)。

死鎖必須具備以下四個(gè)條件:

互斥條件:該資源任意一個(gè)時(shí)刻只由一個(gè)線程占用勒虾。

請(qǐng)求與保持條件:一個(gè)進(jìn)程因請(qǐng)求資源而阻塞時(shí)纺阔,對(duì)已獲得的資源保持不放。

不剝奪條件 : 線程已獲得的資源在末使用完之前不能被其他線程強(qiáng)行剝奪修然,只有自己使用完畢后才釋放資源笛钝。

循環(huán)等待條件 : 若干進(jìn)程之間形成一種頭尾相接的循環(huán)等待資源關(guān)系。

說說 JDK1.6 之后的synchronized 關(guān)鍵字底層做了哪些優(yōu)化愕宋,可以詳細(xì)介紹一下這些優(yōu)化嗎

JDK1.6 對(duì)鎖的實(shí)現(xiàn)引入了大量的優(yōu)化玻靡,如偏向鎖、輕量級(jí)鎖中贝、自旋鎖囤捻、適應(yīng)性自旋鎖、鎖消除邻寿、鎖粗化等技術(shù)來減少鎖操作的開銷蝎土。鎖主要存在四種狀態(tài),依次是:無鎖狀態(tài)绣否、偏向鎖狀態(tài)誊涯、輕量級(jí)鎖狀態(tài)、重量級(jí)鎖狀態(tài)枝秤,他們會(huì)隨著競(jìng)爭(zhēng)的激烈而逐漸升級(jí)醋拧。注意鎖可以升級(jí)不可降級(jí),這種策略是為了提高獲得鎖和釋放鎖的效率淀弹。

好啦丹壕,整理出來大概就是這些了,對(duì)面試題還有疑問的可以私信我交流哦薇溃。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末菌赖,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子沐序,更是在濱河造成了極大的恐慌琉用,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,490評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件策幼,死亡現(xiàn)場(chǎng)離奇詭異邑时,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)特姐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門晶丘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事浅浮∧” “怎么了?”我有些...
    開封第一講書人閱讀 165,830評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵滚秩,是天一觀的道長(zhǎng)专执。 經(jīng)常有香客問我,道長(zhǎng)郁油,這世上最難降的妖魔是什么本股? 我笑而不...
    開封第一講書人閱讀 58,957評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮桐腌,結(jié)果婚禮上痊末,老公的妹妹穿的比我還像新娘。我一直安慰自己哩掺,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,974評(píng)論 6 393
  • 文/花漫 我一把揭開白布涩笤。 她就那樣靜靜地躺著嚼吞,像睡著了一般。 火紅的嫁衣襯著肌膚如雪蹬碧。 梳的紋絲不亂的頭發(fā)上舱禽,一...
    開封第一講書人閱讀 51,754評(píng)論 1 307
  • 那天,我揣著相機(jī)與錄音恩沽,去河邊找鬼誊稚。 笑死,一個(gè)胖子當(dāng)著我的面吹牛罗心,可吹牛的內(nèi)容都是我干的里伯。 我是一名探鬼主播,決...
    沈念sama閱讀 40,464評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼渤闷,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼疾瓮!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起飒箭,我...
    開封第一講書人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤狼电,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后弦蹂,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體肩碟,經(jīng)...
    沈念sama閱讀 45,847評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,995評(píng)論 3 338
  • 正文 我和宋清朗相戀三年凸椿,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了削祈。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,137評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡削饵,死狀恐怖岩瘦,靈堂內(nèi)的尸體忽然破棺而出未巫,到底是詐尸還是另有隱情,我是刑警寧澤启昧,帶...
    沈念sama閱讀 35,819評(píng)論 5 346
  • 正文 年R本政府宣布叙凡,位于F島的核電站,受9級(jí)特大地震影響密末,放射性物質(zhì)發(fā)生泄漏握爷。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,482評(píng)論 3 331
  • 文/蒙蒙 一严里、第九天 我趴在偏房一處隱蔽的房頂上張望新啼。 院中可真熱鬧,春花似錦刹碾、人聲如沸燥撞。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽物舒。三九已至,卻和暖如春戏锹,著一層夾襖步出監(jiān)牢的瞬間冠胯,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工锦针, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留荠察,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,409評(píng)論 3 373
  • 正文 我出身青樓奈搜,卻偏偏與公主長(zhǎng)得像悉盆,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子馋吗,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,086評(píng)論 2 355