亚洲精品久久久中文字幕-亚洲精品久久片久久-亚洲精品久久青草-亚洲精品久久婷婷爱久久婷婷-亚洲精品久久午夜香蕉

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

近5年133個(gè)Java面試問(wèn)題列表

瀏覽:72日期:2022-09-05 17:34:32

Java 面試隨著時(shí)間的改變而改變。在過(guò)去的日子里,當(dāng)你知道 String 和 StringBuilder 的區(qū)別就能讓你直接進(jìn)入第二輪面試,但是現(xiàn)在問(wèn)題變得越來(lái)越高級(jí),面試官問(wèn)的問(wèn)題也更深入。 在我初入職場(chǎng)的時(shí)候,類似于 Vector 與 Array 的區(qū)別、HashMap 與 Hashtable 的區(qū)別是最流行的問(wèn)題,只需要記住它們,就能在面試中獲得更好的機(jī)會(huì),但這種情形已經(jīng)不復(fù)存在。如今,你將會(huì)被問(wèn)到許多 Java 程序員都沒(méi)有看過(guò)的領(lǐng)域,如 NIO,設(shè)計(jì)模式,成熟的單元測(cè)試,或者那些很難掌握的知識(shí),如并發(fā)、算法、數(shù)據(jù)結(jié)構(gòu)及編碼。

由于我喜歡研究面試題,因此我已經(jīng)收集了許多的面試問(wèn)題,包括許多許多不同的主題。我已經(jīng)為這眾多的問(wèn)題準(zhǔn)備一段時(shí)間了,現(xiàn)在我將它們分享給你們。這里面不但包含經(jīng)典的面試問(wèn)題,如線程、集合、equals 和 hashcode、socket,而且還包含了 NIO、數(shù)組、字符串、Java 8 等主題。

該列表包含了入門(mén)級(jí) Java 程序員和多年經(jīng)驗(yàn)的高級(jí)開(kāi)發(fā)者的問(wèn)題。無(wú)論你是 1、2、3、4、5、6、7、8、9 還是 10 年經(jīng)驗(yàn)的開(kāi)發(fā)者,你都能在其中找到一些有趣的問(wèn)題。這里包含了一些超級(jí)容易回答的問(wèn)題,同時(shí)包含經(jīng)驗(yàn)豐富的 Java 程序員也會(huì)棘手的問(wèn)題。

當(dāng)然你們也是非常幸運(yùn)的,當(dāng)今有許多好的書(shū)來(lái)幫助你準(zhǔn)備 Java 面試,其中有一本我覺(jué)得特別有用和有趣的是 Markham 的 Java 程序面試揭秘(Java Programming Interview Exposed)。 這本書(shū)會(huì)告訴你一些 Java 和 JEE 面試中最重要的主題,即使你不是準(zhǔn)備 Java 面試,也值得一讀。

該問(wèn)題列表特別長(zhǎng),我們有各個(gè)地方的問(wèn)題,所以,答案必須要短小、簡(jiǎn)潔、干脆,不拖泥帶水。因此,除了這一個(gè)段落,你只會(huì)聽(tīng)到問(wèn)題與答案,再無(wú)其他內(nèi)容,沒(méi)有反饋,也沒(méi)有評(píng)價(jià)。為此,我已經(jīng)寫(xiě)好了一些博文,在這些文章中你可以找到我對(duì)某些問(wèn)題的觀點(diǎn),如我為什么喜歡這個(gè)問(wèn)題,這個(gè)問(wèn)題的挑戰(zhàn)是什么?期望從面試者那獲取到什么樣的答案?

這個(gè)列表有一點(diǎn)不同,我鼓勵(lì)你采用類似的方式去分享問(wèn)題和答案,這樣容易溫習(xí)。我希望這個(gè)列表對(duì)面試官和候選人都有很好的用處,面試官可以對(duì)這些問(wèn)題上做一些改變以獲取新奇和令人驚奇的元素,這對(duì)一次好的面試來(lái)說(shuō)非常重要。而候選者,可以擴(kuò)展和測(cè)試 Java 程序語(yǔ)言和平臺(tái)關(guān)鍵領(lǐng)域的知識(shí)。2015 年,會(huì)更多的關(guān)注并發(fā)概念,JVM 內(nèi)部,32 位 JVM 和 64 JVM的區(qū)別,單元測(cè)試及整潔的代碼。我確信,如果你讀過(guò)這個(gè)龐大的 Java 面試問(wèn)題列表,無(wú)論是電話面試還是面對(duì)面的面試,你都能有很好的表現(xiàn)。

 Java 面試中的重要話題

除了你看到的驚人的問(wèn)題數(shù)量,我也盡量保證質(zhì)量。我不止一次分享各個(gè)重要主題中的問(wèn)題,也確保包含所謂的高級(jí)話題,這些話題很多程序員不喜歡準(zhǔn)備或者直接放棄,因?yàn)樗麄兊墓ぷ鞑粫?huì)涉及到這些。Java NIO 和 JVM 底層就是最好的例子。你也可以將設(shè)計(jì)模式劃分到這一類中,但是越來(lái)越多有經(jīng)驗(yàn)的程序員了解 GOF 設(shè)計(jì)模式并應(yīng)用這些模式。我也盡量在這個(gè)列表中包含 2015 年最新的面試問(wèn)題,這些問(wèn)題可能是來(lái)年關(guān)注的核心。為了給你一個(gè)大致的了解,下面列出這份 Java 面試問(wèn)題列表包含的主題:

多線程,并發(fā)及線程基礎(chǔ)數(shù)據(jù)類型轉(zhuǎn)換的基本原則垃圾回收(GC)Java 集合框架數(shù)組字符串GOF 設(shè)計(jì)模式SOLID (單一功能、開(kāi)閉原則、里氏替換、接口隔離以及依賴反轉(zhuǎn))設(shè)計(jì)原則抽象類與接口Java 基礎(chǔ),如 equals 和 hashcode泛型與枚舉Java IO 與 NIO常用網(wǎng)絡(luò)協(xié)議Java 中的數(shù)據(jù)結(jié)構(gòu)和算法正則表達(dá)式JVM 底層Java 最佳實(shí)踐JDBCDate, Time 與 CalendarJava 處理 XMLJUnit編程

 120 大 Java 面試題及答案

現(xiàn)在是時(shí)候給你展示我近 5 年從各種面試中收集來(lái)的 120 個(gè)問(wèn)題了。我確定你在自己的面試中見(jiàn)過(guò)很多這些問(wèn)題,很多問(wèn)題你也能正確回答。

多線程、并發(fā)及線程的基礎(chǔ)問(wèn)題

1)Java 中能創(chuàng)建 volatile 數(shù)組嗎?能,Java 中可以創(chuàng)建 volatile 類型數(shù)組,不過(guò)只是一個(gè)指向數(shù)組的引用,而不是整個(gè)數(shù)組。我的意思是,如果改變引用指向的數(shù)組,將會(huì)受到 volatile 的保護(hù),但是如果多個(gè)線程同時(shí)改變數(shù)組的元素,volatile 標(biāo)示符就不能起到之前的保護(hù)作用了。

2)volatile 能使得一個(gè)非原子操作變成原子操作嗎?一個(gè)典型的例子是在類中有一個(gè) long 類型的成員變量。如果你知道該成員變量會(huì)被多個(gè)線程訪問(wèn),如計(jì)數(shù)器、價(jià)格等,你最好是將其設(shè)置為 volatile。為什么?因?yàn)?Java 中讀取 long 類型變量不是原子的,需要分成兩步,如果一個(gè)線程正在修改該 long 變量的值,另一個(gè)線程可能只能看到該值的一半(前 32 位)。但是對(duì)一個(gè) volatile 型的 long 或 double 變量的讀寫(xiě)是原子。

3)volatile 修飾符的有過(guò)什么實(shí)踐?一種實(shí)踐是用 volatile 修飾 long 和 double 變量,使其能按原子類型來(lái)讀寫(xiě)。double 和 long 都是64位寬,因此對(duì)這兩種類型的讀是分為兩部分的,第一次讀取第一個(gè) 32 位,然后再讀剩下的 32 位,這個(gè)過(guò)程不是原子的,但 Java 中 volatile 型的 long 或 double 變量的讀寫(xiě)是原子的。volatile 修復(fù)符的另一個(gè)作用是提供內(nèi)存屏障(memory barrier),例如在分布式框架中的應(yīng)用。簡(jiǎn)單的說(shuō),就是當(dāng)你寫(xiě)一個(gè) volatile 變量之前,Java 內(nèi)存模型會(huì)插入一個(gè)寫(xiě)屏障(write barrier),讀一個(gè) volatile 變量之前,會(huì)插入一個(gè)讀屏障(read barrier)。意思就是說(shuō),在你寫(xiě)一個(gè) volatile 域時(shí),能保證任何線程都能看到你寫(xiě)的值,同時(shí),在寫(xiě)之前,也能保證任何數(shù)值的更新對(duì)所有線程是可見(jiàn)的,因?yàn)閮?nèi)存屏障會(huì)將其他所有寫(xiě)的值更新到緩存。

4)volatile 類型變量提供什么保證?(答案)volatile 變量提供順序和可見(jiàn)性保證,例如,JVM 或者 JIT為了獲得更好的性能會(huì)對(duì)語(yǔ)句重排序,但是 volatile 類型變量即使在沒(méi)有同步塊的情況下賦值也不會(huì)與其他語(yǔ)句重排序。 volatile 提供 happens-before 的保證,確保一個(gè)線程的修改能對(duì)其他線程是可見(jiàn)的。某些情況下,volatile 還能提供原子性,如讀 64 位數(shù)據(jù)類型,像 long 和 double 都不是原子的,但 volatile 類型的 double 和 long 就是原子的。

5) 10 個(gè)線程和 2 個(gè)線程的同步代碼,哪個(gè)更容易寫(xiě)?從寫(xiě)代碼的角度來(lái)說(shuō),兩者的復(fù)雜度是相同的,因?yàn)橥酱a與線程數(shù)量是相互獨(dú)立的。但是同步策略的選擇依賴于線程的數(shù)量,因?yàn)樵蕉嗟木€程意味著更大的競(jìng)爭(zhēng),所以你需要利用同步技術(shù),如鎖分離,這要求更復(fù)雜的代碼和專業(yè)知識(shí)。

6)你是如何調(diào)用 wait()方法的?使用 if 塊還是循環(huán)?為什么?(答案)wait() 方法應(yīng)該在循環(huán)調(diào)用,因?yàn)楫?dāng)線程獲取到 CPU 開(kāi)始執(zhí)行的時(shí)候,其他條件可能還沒(méi)有滿足,所以在處理前,循環(huán)檢測(cè)條件是否滿足會(huì)更好。下面是一段標(biāo)準(zhǔn)的使用 wait 和 notify 方法的代碼:

// The standard idiom for using the wait methodsynchronized (obj) {while (condition does not hold)obj.wait(); // (Releases lock, and reacquires on wakeup)... // Perform action appropriate to condition}

參見(jiàn) Effective Java 第 69 條,獲取更多關(guān)于為什么應(yīng)該在循環(huán)中來(lái)調(diào)用 wait 方法的內(nèi)容。

7)什么是多線程環(huán)境下的偽共享(false sharing)?偽共享是多線程系統(tǒng)(每個(gè)處理器有自己的局部緩存)中一個(gè)眾所周知的性能問(wèn)題。偽共享發(fā)生在不同處理器的上的線程對(duì)變量的修改依賴于相同的緩存行,如下圖所示:

近5年133個(gè)Java面試問(wèn)題列表

有經(jīng)驗(yàn)程序員的 Java 面試題

偽共享問(wèn)題很難被發(fā)現(xiàn),因?yàn)榫€程可能訪問(wèn)完全不同的全局變量,內(nèi)存中卻碰巧在很相近的位置上。如其他諸多的并發(fā)問(wèn)題,避免偽共享的最基本方式是仔細(xì)審查代碼,根據(jù)緩存行來(lái)調(diào)整你的數(shù)據(jù)結(jié)構(gòu)。

8)什么是 Busy spin?我們?yōu)槭裁匆褂盟緽usy spin 是一種在不釋放 CPU 的基礎(chǔ)上等待事件的技術(shù)。它經(jīng)常用于避免丟失 CPU 緩存中的數(shù)據(jù)(如果線程先暫停,之后在其他CPU上運(yùn)行就會(huì)丟失)。所以,如果你的工作要求低延遲,并且你的線程目前沒(méi)有任何順序,這樣你就可以通過(guò)循環(huán)檢測(cè)隊(duì)列中的新消息來(lái)代替調(diào)用 sleep() 或 wait() 方法。它唯一的好處就是你只需等待很短的時(shí)間,如幾微秒或幾納秒。LMAX 分布式框架是一個(gè)高性能線程間通信的庫(kù),該庫(kù)有一個(gè) BusySpinWaitStrategy 類就是基于這個(gè)概念實(shí)現(xiàn)的,使用 busy spin 循環(huán) EventProcessors 等待屏障。

9)Java 中怎么獲取一份線程 dump 文件?在 Linux 下,你可以通過(guò)命令 kill -3 PID (Java 進(jìn)程的進(jìn)程 ID)來(lái)獲取 Java 應(yīng)用的 dump 文件。在 Windows 下,你可以按下 Ctrl + Break 來(lái)獲取。這樣 JVM 就會(huì)將線程的 dump 文件打印到標(biāo)準(zhǔn)輸出或錯(cuò)誤文件中,它可能打印在控制臺(tái)或者日志文件中,具體位置依賴應(yīng)用的配置。如果你使用Tomcat。

10)Swing 是線程安全的?(答案)不是,Swing 不是線程安全的。你不能通過(guò)任何線程來(lái)更新 Swing 組件,如 JTable、JList 或 JPanel,事實(shí)上,它們只能通過(guò) GUI 或 AWT 線程來(lái)更新。這就是為什么 Swing 提供 invokeAndWait() 和 invokeLater() 方法來(lái)獲取其他線程的 GUI 更新請(qǐng)求。這些方法將更新請(qǐng)求放入 AWT 的線程隊(duì)列中,可以一直等待,也可以通過(guò)異步更新直接返回結(jié)果。你也可以在參考答案中查看和學(xué)習(xí)到更詳細(xì)的內(nèi)容。

11)什么是線程局部變量?(答案)線程局部變量是局限于線程內(nèi)部的變量,屬于線程自身所有,不在多個(gè)線程間共享。Java 提供 ThreadLocal 類來(lái)支持線程局部變量,是一種實(shí)現(xiàn)線程安全的方式。但是在管理環(huán)境下(如 web 服務(wù)器)使用線程局部變量的時(shí)候要特別小心,在這種情況下,工作線程的生命周期比任何應(yīng)用變量的生命周期都要長(zhǎng)。任何線程局部變量一旦在工作完成后沒(méi)有釋放,Java 應(yīng)用就存在內(nèi)存泄露的風(fēng)險(xiǎn)。

12)用 wait-notify 寫(xiě)一段代碼來(lái)解決生產(chǎn)者-消費(fèi)者問(wèn)題?(答案)請(qǐng)參考答案中的示例代碼。只要記住在同步塊中調(diào)用 wait() 和 notify()方法,如果阻塞,通過(guò)循環(huán)來(lái)測(cè)試等待條件。

13) 用 Java 寫(xiě)一個(gè)線程安全的單例模式(Singleton)?(答案)請(qǐng)參考答案中的示例代碼,這里面一步一步教你創(chuàng)建一個(gè)線程安全的 Java 單例類。當(dāng)我們說(shuō)線程安全時(shí),意思是即使初始化是在多線程環(huán)境中,仍然能保證單個(gè)實(shí)例。Java 中,使用枚舉作為單例類是最簡(jiǎn)單的方式來(lái)創(chuàng)建線程安全單例模式的方式。

14)Java 中 sleep 方法和 wait 方法的區(qū)別?(答案)雖然兩者都是用來(lái)暫停當(dāng)前運(yùn)行的線程,但是 sleep() 實(shí)際上只是短暫停頓,因?yàn)樗粫?huì)釋放鎖,而 wait() 意味著條件等待,這就是為什么該方法要釋放鎖,因?yàn)橹挥羞@樣,其他等待的線程才能在滿足條件時(shí)獲取到該鎖。

15)什么是不可變對(duì)象(immutable object)?Java 中怎么創(chuàng)建一個(gè)不可變對(duì)象?(答案)不可變對(duì)象指對(duì)象一旦被創(chuàng)建,狀態(tài)就不能再改變。任何修改都會(huì)創(chuàng)建一個(gè)新的對(duì)象,如 String、Integer及其它包裝類。詳情參見(jiàn)答案,一步一步指導(dǎo)你在 Java 中創(chuàng)建一個(gè)不可變的類。

16)我們能創(chuàng)建一個(gè)包含可變對(duì)象的不可變對(duì)象嗎?是的,我們是可以創(chuàng)建一個(gè)包含可變對(duì)象的不可變對(duì)象的,你只需要謹(jǐn)慎一點(diǎn),不要共享可變對(duì)象的引用就可以了,如果需要變化時(shí),就返回原對(duì)象的一個(gè)拷貝。最常見(jiàn)的例子就是對(duì)象中包含一個(gè)日期對(duì)象的引用。

數(shù)據(jù)類型和 Java 基礎(chǔ)面試問(wèn)題

17)Java 中應(yīng)該使用什么數(shù)據(jù)類型來(lái)代表價(jià)格?(答案)如果不是特別關(guān)心內(nèi)存和性能的話,使用BigDecimal,否則使用預(yù)定義精度的 double 類型。

18)怎么將 byte 轉(zhuǎn)換為 String?(答案)可以使用 String 接收 byte[] 參數(shù)的構(gòu)造器來(lái)進(jìn)行轉(zhuǎn)換,需要注意的點(diǎn)是要使用的正確的編碼,否則會(huì)使用平臺(tái)默認(rèn)編碼,這個(gè)編碼可能跟原來(lái)的編碼相同,也可能不同。

19)Java 中怎樣將 bytes 轉(zhuǎn)換為 long 類型?這個(gè)問(wèn)題你來(lái)回答 :-)

20)我們能將 int 強(qiáng)制轉(zhuǎn)換為 byte 類型的變量嗎?如果該值大于 byte 類型的范圍,將會(huì)出現(xiàn)什么現(xiàn)象?是的,我們可以做強(qiáng)制轉(zhuǎn)換,但是 Java 中 int 是 32 位的,而 byte 是 8 位的,所以,如果強(qiáng)制轉(zhuǎn)化是,int 類型的高 24 位將會(huì)被丟棄,byte 類型的范圍是從 -128 到 128。

21)存在兩個(gè)類,B 繼承 A,C 繼承 B,我們能將 B 轉(zhuǎn)換為 C 么?如 C = (C) B;(answer答案)

22)哪個(gè)類包含 clone 方法?是 Cloneable 還是 Object?(答案)java.lang.Cloneable 是一個(gè)標(biāo)示性接口,不包含任何方法,clone 方法在 object 類中定義。并且需要知道 clone() 方法是一個(gè)本地方法,這意味著它是由 c 或 c++ 或 其他本地語(yǔ)言實(shí)現(xiàn)的。

23)Java 中 ++ 操作符是線程安全的嗎?(答案)23)不是線程安全的操作。它涉及到多個(gè)指令,如讀取變量值,增加,然后存儲(chǔ)回內(nèi)存,這個(gè)過(guò)程可能會(huì)出現(xiàn)多個(gè)線程交差。

24)a = a + b 與 a += b 的區(qū)別(答案)+= 隱式的將加操作的結(jié)果類型強(qiáng)制轉(zhuǎn)換為持有結(jié)果的類型。如果兩這個(gè)整型相加,如 byte、short 或者 int,首先會(huì)將它們提升到 int 類型,然后在執(zhí)行加法操作。如果加法操作的結(jié)果比 a 的最大值要大,則 a+b 會(huì)出現(xiàn)編譯錯(cuò)誤,但是 a += b 沒(méi)問(wèn)題,如下:byte a = 127;byte b = 127;b = a + b; // error : cannot convert from int to byteb += a; // ok(譯者注:這個(gè)地方應(yīng)該表述的有誤,其實(shí)無(wú)論 a+b 的值為多少,編譯器都會(huì)報(bào)錯(cuò),因?yàn)?a+b 操作會(huì)將 a、b 提升為 int 類型,所以將 int 類型賦值給 byte 就會(huì)編譯出錯(cuò))

25)我能在不進(jìn)行強(qiáng)制轉(zhuǎn)換的情況下將一個(gè) double 值賦值給 long 類型的變量嗎?(答案)不行,你不能在沒(méi)有強(qiáng)制類型轉(zhuǎn)換的前提下將一個(gè) double 值賦值給 long 類型的變量,因?yàn)?double 類型的范圍比 long 類型更廣,所以必須要進(jìn)行強(qiáng)制轉(zhuǎn)換。

26)3*0.1 == 0.3 將會(huì)返回什么?true 還是 false?(答案)false,因?yàn)橛行└↑c(diǎn)數(shù)不能完全精確的表示出來(lái)。

27)int 和 Integer 哪個(gè)會(huì)占用更多的內(nèi)存?(答案)Integer 對(duì)象會(huì)占用更多的內(nèi)存。Integer 是一個(gè)對(duì)象,需要存儲(chǔ)對(duì)象的元數(shù)據(jù)。但是 int 是一個(gè)原始類型的數(shù)據(jù),所以占用的空間更少。

28)為什么 Java 中的 String 是不可變的(Immutable)?(answer答案)Java 中的 String 不可變是因?yàn)?Java 的設(shè)計(jì)者認(rèn)為字符串使用非常頻繁,將字符串設(shè)置為不可變可以允許多個(gè)客戶端之間共享相同的字符串。更詳細(xì)的內(nèi)容參見(jiàn)答案。

29)我們能在 Switch 中使用 String 嗎?(answer答案)從 Java 7 開(kāi)始,我們可以在 switch case 中使用字符串,但這僅僅是一個(gè)語(yǔ)法糖。內(nèi)部實(shí)現(xiàn)在 switch 中使用字符串的 hash code。

30)Java 中的構(gòu)造器鏈?zhǔn)鞘裁矗?answer答案)當(dāng)你從一個(gè)構(gòu)造器中調(diào)用另一個(gè)構(gòu)造器,就是Java 中的構(gòu)造器鏈。這種情況只在重載了類的構(gòu)造器的時(shí)候才會(huì)出現(xiàn)。

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

31)64 位 JVM 中,int 的長(zhǎng)度是多數(shù)?Java 中,int 類型變量的長(zhǎng)度是一個(gè)固定值,與平臺(tái)無(wú)關(guān),都是 32 位。意思就是說(shuō),在 32 位 和 64 位 的Java 虛擬機(jī)中,int 類型的長(zhǎng)度是相同的。

32)Serial 與 Parallel GC之間的不同之處?(答案)Serial 與 Parallel 在GC執(zhí)行的時(shí)候都會(huì)引起 stop-the-world。它們之間主要不同 serial 收集器是默認(rèn)的復(fù)制收集器,執(zhí)行 GC 的時(shí)候只有一個(gè)線程,而 parallel 收集器使用多個(gè) GC 線程來(lái)執(zhí)行。

33)32 位和 64 位的 JVM,int 類型變量的長(zhǎng)度是多數(shù)?(答案)32 位和 64 位的 JVM 中,int 類型變量的長(zhǎng)度是相同的,都是 32 位或者 4 個(gè)字節(jié)。

34)Java 中 WeakReference 與 SoftReference的區(qū)別?(答案)雖然 WeakReference 與 SoftReference 都有利于提高 GC 和 內(nèi)存的效率,但是 WeakReference ,一旦失去最后一個(gè)強(qiáng)引用,就會(huì)被 GC 回收,而軟引用雖然不能阻止被回收,但是可以延遲到 JVM 內(nèi)存不足的時(shí)候。

35)WeakHashMap 是怎么工作的?(答案)WeakHashMap 的工作與正常的 HashMap 類似,但是使用弱引用作為 key,意思就是當(dāng) key 對(duì)象沒(méi)有任何引用時(shí),key/value 將會(huì)被回收。

36)JVM 選項(xiàng) -XX:+UseCompressedOops 有什么作用?為什么要使用?(答案)當(dāng)你將你的應(yīng)用從 32 位的 JVM 遷移到 64 位的 JVM 時(shí),由于對(duì)象的指針從 32 位增加到了 64 位,因此堆內(nèi)存會(huì)突然增加,差不多要翻倍。這也會(huì)對(duì) CPU 緩存(容量比內(nèi)存小很多)的數(shù)據(jù)產(chǎn)生不利的影響。因?yàn)椋w移到 64 位的 JVM 主要?jiǎng)訖C(jī)在于可以指定最大堆大小,通過(guò)壓縮 OOP 可以節(jié)省一定的內(nèi)存。通過(guò) -XX:+UseCompressedOops 選項(xiàng),JVM 會(huì)使用 32 位的 OOP,而不是 64 位的 OOP。

37)怎樣通過(guò) Java 程序來(lái)判斷 JVM 是 32 位 還是 64 位?(答案)你可以檢查某些系統(tǒng)屬性如 sun.arch.data.model 或 os.arch 來(lái)獲取該信息。

38)32 位 JVM 和 64 位 JVM 的最大堆內(nèi)存分別是多數(shù)?(答案)理論上說(shuō)上 32 位的 JVM 堆內(nèi)存可以到達(dá) 2^32,即 4GB,但實(shí)際上會(huì)比這個(gè)小很多。不同操作系統(tǒng)之間不同,如 Windows 系統(tǒng)大約 1.5 GB,Solaris 大約 3GB。64 位 JVM允許指定最大的堆內(nèi)存,理論上可以達(dá)到 2^64,這是一個(gè)非常大的數(shù)字,實(shí)際上你可以指定堆內(nèi)存大小到 100GB。甚至有的 JVM,如 Azul,堆內(nèi)存到 1000G 都是可能的。

39)JRE、JDK、JVM 及 JIT 之間有什么不同?(答案)JRE 代表 Java 運(yùn)行時(shí)(Java run-time),是運(yùn)行 Java 引用所必須的。JDK 代表 Java 開(kāi)發(fā)工具(Java development kit),是 Java 程序的開(kāi)發(fā)工具,如 Java 編譯器,它也包含 JRE。JVM 代表 Java 虛擬機(jī)(Java virtual machine),它的責(zé)任是運(yùn)行 Java 應(yīng)用。JIT 代表即時(shí)編譯(Just In Time compilation),當(dāng)代碼執(zhí)行的次數(shù)超過(guò)一定的閾值時(shí),會(huì)將 Java 字節(jié)碼轉(zhuǎn)換為本地代碼,如,主要的熱點(diǎn)代碼會(huì)被準(zhǔn)換為本地代碼,這樣有利大幅度提高 Java 應(yīng)用的性能。

近5年133個(gè)Java面試問(wèn)題列表

3 年工作經(jīng)驗(yàn)的 Java 面試題

40)解釋 Java 堆空間及 GC?(答案)當(dāng)通過(guò) Java 命令啟動(dòng) Java 進(jìn)程的時(shí)候,會(huì)為它分配內(nèi)存。內(nèi)存的一部分用于創(chuàng)建堆空間,當(dāng)程序中創(chuàng)建對(duì)象的時(shí)候,就從對(duì)空間中分配內(nèi)存。GC 是 JVM 內(nèi)部的一個(gè)進(jìn)程,回收無(wú)效對(duì)象的內(nèi)存用于將來(lái)的分配。

近5年133個(gè)Java面試問(wèn)題列表

JVM 底層面試題及答案

41)你能保證 GC 執(zhí)行嗎?(答案)不能,雖然你可以調(diào)用 System.gc() 或者 Runtime.gc(),但是沒(méi)有辦法保證 GC 的執(zhí)行。

42)怎么獲取 Java 程序使用的內(nèi)存?堆使用的百分比?可以通過(guò) java.lang.Runtime 類中與內(nèi)存相關(guān)方法來(lái)獲取剩余的內(nèi)存,總內(nèi)存及最大堆內(nèi)存。通過(guò)這些方法你也可以獲取到堆使用的百分比及堆內(nèi)存的剩余空間。Runtime.freeMemory() 方法返回剩余空間的字節(jié)數(shù),Runtime.totalMemory() 方法總內(nèi)存的字節(jié)數(shù),Runtime.maxMemory() 返回最大內(nèi)存的字節(jié)數(shù)。

43)Java 中堆和棧有什么區(qū)別?(答案)JVM 中堆和棧屬于不同的內(nèi)存區(qū)域,使用目的也不同。棧常用于保存方法幀和局部變量,而對(duì)象總是在堆上分配。棧通常都比堆小,也不會(huì)在多個(gè)線程之間共享,而堆被整個(gè) JVM 的所有線程共享。

近5年133個(gè)Java面試問(wèn)題列表

關(guān)于內(nèi)存的的面試問(wèn)題和答案Java 基本概念面試題

44)“a==b”和”a.equals(b)”有什么區(qū)別?(答案)如果 a 和 b 都是對(duì)象,則 a==b 是比較兩個(gè)對(duì)象的引用,只有當(dāng) a 和 b 指向的是堆中的同一個(gè)對(duì)象才會(huì)返回 true,而 a.equals(b) 是進(jìn)行邏輯比較,所以通常需要重寫(xiě)該方法來(lái)提供邏輯一致性的比較。例如,String 類重寫(xiě) equals() 方法,所以可以用于兩個(gè)不同對(duì)象,但是包含的字母相同的比較。

45)a.hashCode() 有什么用?與 a.equals(b) 有什么關(guān)系?(答案)hashCode() 方法是相應(yīng)對(duì)象整型的 hash 值。它常用于基于 hash 的集合類,如 Hashtable、HashMap、LinkedHashMap等等。它與 equals() 方法關(guān)系特別緊密。根據(jù) Java 規(guī)范,兩個(gè)使用 equal() 方法來(lái)判斷相等的對(duì)象,必須具有相同的 hash code。

46)final、finalize 和 finally 的不同之處?(答案)final 是一個(gè)修飾符,可以修飾變量、方法和類。如果 final 修飾變量,意味著該變量的值在初始化后不能被改變。finalize 方法是在對(duì)象被回收之前調(diào)用的方法,給對(duì)象自己最后一個(gè)復(fù)活的機(jī)會(huì),但是什么時(shí)候調(diào)用 finalize 沒(méi)有保證。finally 是一個(gè)關(guān)鍵字,與 try 和 catch 一起用于異常的處理。finally 塊一定會(huì)被執(zhí)行,無(wú)論在 try 塊中是否有發(fā)生異常。

47)Java 中的編譯期常量是什么?使用它又什么風(fēng)險(xiǎn)?公共靜態(tài)不可變(public static final )變量也就是我們所說(shuō)的編譯期常量,這里的 public 可選的。實(shí)際上這些變量在編譯時(shí)會(huì)被替換掉,因?yàn)榫幾g器知道這些變量的值,并且知道這些變量在運(yùn)行時(shí)不能改變。這種方式存在的一個(gè)問(wèn)題是你使用了一個(gè)內(nèi)部的或第三方庫(kù)中的公有編譯時(shí)常量,但是這個(gè)值后面被其他人改變了,但是你的客戶端仍然在使用老的值,甚至你已經(jīng)部署了一個(gè)新的jar。為了避免這種情況,當(dāng)你在更新依賴 JAR 文件時(shí),確保重新編譯你的程序。

Java 集合框架的面試題

這部分也包含數(shù)據(jù)結(jié)構(gòu)、算法及數(shù)組的面試問(wèn)題

48) List、Set、Map 和 Queue 之間的區(qū)別(答案)List 是一個(gè)有序集合,允許元素重復(fù)。它的某些實(shí)現(xiàn)可以提供基于下標(biāo)值的常量訪問(wèn)時(shí)間,但是這不是 List 接口保證的。Set 是一個(gè)無(wú)序集合。

49)poll() 方法和 remove() 方法的區(qū)別?poll() 和 remove() 都是從隊(duì)列中取出一個(gè)元素,但是 poll() 在獲取元素失敗的時(shí)候會(huì)返回空,但是 remove() 失敗的時(shí)候會(huì)拋出異常。

50)Java 中 LinkedHashMap 和 PriorityQueue 的區(qū)別是什么?(答案)PriorityQueue 保證最高或者最低優(yōu)先級(jí)的的元素總是在隊(duì)列頭部,但是 LinkedHashMap 維持的順序是元素插入的順序。當(dāng)遍歷一個(gè) PriorityQueue 時(shí),沒(méi)有任何順序保證,但是 LinkedHashMap 課保證遍歷順序是元素插入的順序。

51)ArrayList 與 LinkedList 的不區(qū)別?(答案)最明顯的區(qū)別是 ArrrayList 底層的數(shù)據(jù)結(jié)構(gòu)是數(shù)組,支持隨機(jī)訪問(wèn),而 LinkedList 的底層數(shù)據(jù)結(jié)構(gòu)書(shū)鏈表,不支持隨機(jī)訪問(wèn)。使用下標(biāo)訪問(wèn)一個(gè)元素,ArrayList 的時(shí)間復(fù)雜度是 O(1),而 LinkedList 是 O(n)。更多細(xì)節(jié)的討論參見(jiàn)答案。

52)用哪兩種方式來(lái)實(shí)現(xiàn)集合的排序?(答案)你可以使用有序集合,如 TreeSet 或 TreeMap,你也可以使用有順序的的集合,如 list,然后通過(guò) Collections.sort() 來(lái)排序。

53)Java 中怎么打印數(shù)組?(answer答案)你可以使用 Arrays.toString() 和 Arrays.deepToString() 方法來(lái)打印數(shù)組。由于數(shù)組沒(méi)有實(shí)現(xiàn) toString() 方法,所以如果將數(shù)組傳遞給 System.out.println() 方法,將無(wú)法打印出數(shù)組的內(nèi)容,但是 Arrays.toString() 可以打印每個(gè)元素。

54)Java 中的 LinkedList 是單向鏈表還是雙向鏈表?(答案)是雙向鏈表,你可以檢查 JDK 的源碼。在 Eclipse,你可以使用快捷鍵 Ctrl + T,直接在編輯器中打開(kāi)該類。

55)Java 中的 TreeMap 是采用什么樹(shù)實(shí)現(xiàn)的?(答案)Java 中的 TreeMap 是使用紅黑樹(shù)實(shí)現(xiàn)的。

56) Hashtable 與 HashMap 有什么不同之處?(答案)這兩個(gè)類有許多不同的地方,下面列出了一部分:a) Hashtable 是 JDK 1 遺留下來(lái)的類,而 HashMap 是后來(lái)增加的。b)Hashtable 是同步的,比較慢,但 HashMap 沒(méi)有同步策略,所以會(huì)更快。c)Hashtable 不允許有個(gè)空的 key,但是 HashMap 允許出現(xiàn)一個(gè) null key。更多的不同之處參見(jiàn)答案。

57)Java 中的 HashSet,內(nèi)部是如何工作的?(answer答案)HashSet 的內(nèi)部采用 HashMap來(lái)實(shí)現(xiàn)。由于 Map 需要 key 和 value,所以所有 key 的都有一個(gè)默認(rèn) value。類似于 HashMap,HashSet 不允許重復(fù)的 key,只允許有一個(gè)null key,意思就是 HashSet 中只允許存儲(chǔ)一個(gè) null 對(duì)象。

58)寫(xiě)一段代碼在遍歷 ArrayList 時(shí)移除一個(gè)元素?(答案)該問(wèn)題的關(guān)鍵在于面試者使用的是 ArrayList 的 remove() 還是 Iterator 的 remove()方法。這有一段示例代碼,是使用正確的方式來(lái)實(shí)現(xiàn)在遍歷的過(guò)程中移除元素,而不會(huì)出現(xiàn) ConcurrentModificationException 異常的示例代碼。

59)我們能自己寫(xiě)一個(gè)容器類,然后使用 for-each 循環(huán)碼?可以,你可以寫(xiě)一個(gè)自己的容器類。如果你想使用 Java 中增強(qiáng)的循環(huán)來(lái)遍歷,你只需要實(shí)現(xiàn) Iterable 接口。如果你實(shí)現(xiàn) Collection 接口,默認(rèn)就具有該屬性。

60)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.7private static final int DEFAULT_CAPACITY = 10; //from HashMap.java JDK 7static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16

61)有沒(méi)有可能兩個(gè)不相等的對(duì)象有有相同的 hashcode?有可能,兩個(gè)不相等的對(duì)象可能會(huì)有相同的 hashcode 值,這就是為什么在 hashmap 中會(huì)有沖突。相等 hashcode 值的規(guī)定只是說(shuō)如果兩個(gè)對(duì)象相等,必須有相同的hashcode 值,但是沒(méi)有關(guān)于不相等對(duì)象的任何規(guī)定。

62)兩個(gè)相同的對(duì)象會(huì)有不同的的 hash code 嗎?不能,根據(jù) hash code 的規(guī)定,這是不可能的。

63)我們可以在 hashcode() 中使用隨機(jī)數(shù)字嗎?(答案)不行,因?yàn)閷?duì)象的 hashcode 值必須是相同的。參見(jiàn)答案獲取更多關(guān)于 Java 中重寫(xiě) hashCode() 方法的知識(shí)。

64)Java 中,Comparator 與 Comparable 有什么不同?(答案)Comparable 接口用于定義對(duì)象的自然順序,而 comparator 通常用于定義用戶定制的順序。Comparable 總是只有一個(gè),但是可以有多個(gè) comparator 來(lái)定義對(duì)象的順序。

65)為什么在重寫(xiě) equals 方法的時(shí)候需要重寫(xiě) hashCode 方法?(答案)因?yàn)橛袕?qiáng)制的規(guī)范指定需要同時(shí)重寫(xiě) hashcode 與 equal 是方法,許多容器類,如 HashMap、HashSet 都依賴于 hashcode 與 equals 的規(guī)定。

Java IO 和 NIO 的面試題

IO 是 Java 面試中一個(gè)非常重要的點(diǎn)。你應(yīng)該很好掌握 Java IO,NIO,NIO2 以及與操作系統(tǒng),磁盤(pán) IO 相關(guān)的基礎(chǔ)知識(shí)。下面是 Java IO 中經(jīng)常問(wèn)的問(wèn)題。

66)在我 Java 程序中,我有三個(gè) socket,我需要多少個(gè)線程來(lái)處理?

67)Java 中怎么創(chuàng)建 ByteBuffer?

68)Java 中,怎么讀寫(xiě) ByteBuffer ?

69)Java 采用的是大端還是小端?

70)ByteBuffer 中的字節(jié)序是什么?

71)Java 中,直接緩沖區(qū)與非直接緩沖器有什么區(qū)別?(答案)

72)Java 中的內(nèi)存映射緩存區(qū)是什么?(answer答案)

73)socket 選項(xiàng) TCP NO DELAY 是指什么?

74)TCP 協(xié)議與 UDP 協(xié)議有什么區(qū)別?(answer答案)

75)Java 中,ByteBuffer 與 StringBuffer有什么區(qū)別?(答案)

Java 最佳實(shí)踐的面試問(wèn)題

包含 Java 中各個(gè)部分的最佳實(shí)踐,如集合,字符串,IO,多線程,錯(cuò)誤和異常處理,設(shè)計(jì)模式等等。

76)Java 中,編寫(xiě)多線程程序的時(shí)候你會(huì)遵循哪些最佳實(shí)踐?(答案)這是我在寫(xiě)Java 并發(fā)程序的時(shí)候遵循的一些最佳實(shí)踐:a)給線程命名,這樣可以幫助調(diào)試。b)最小化同步的范圍,而不是將整個(gè)方法同步,只對(duì)關(guān)鍵部分做同步。c)如果可以,更偏向于使用 volatile 而不是 synchronized。d)使用更高層次的并發(fā)工具,而不是使用 wait() 和 notify() 來(lái)實(shí)現(xiàn)線程間通信,如 BlockingQueue,CountDownLatch 及 Semeaphore。e)優(yōu)先使用并發(fā)集合,而不是對(duì)集合進(jìn)行同步。并發(fā)集合提供更好的可擴(kuò)展性。

77)說(shuō)出幾點(diǎn) Java 中使用 Collections 的最佳實(shí)踐(答案)這是我在使用 Java 中 Collectionc 類的一些最佳實(shí)踐:a)使用正確的集合類,例如,如果不需要同步列表,使用 ArrayList 而不是 Vector。b)優(yōu)先使用并發(fā)集合,而不是對(duì)集合進(jìn)行同步。并發(fā)集合提供更好的可擴(kuò)展性。c)使用接口代表和訪問(wèn)集合,如使用List存儲(chǔ) ArrayList,使用 Map 存儲(chǔ) HashMap 等等。d)使用迭代器來(lái)循環(huán)集合。e)使用集合的時(shí)候使用泛型。

78)說(shuō)出至少 5 點(diǎn)在 Java 中使用線程的最佳實(shí)踐。(答案)這個(gè)問(wèn)題與之前的問(wèn)題類似,你可以使用上面的答案。對(duì)線程來(lái)說(shuō),你應(yīng)該:a)對(duì)線程命名b)將線程和任務(wù)分離,使用線程池執(zhí)行器來(lái)執(zhí)行 Runnable 或 Callable。c)使用線程池

79)說(shuō)出 5 條 IO 的最佳實(shí)踐(答案)IO 對(duì) Java 應(yīng)用的性能非常重要。理想情況下,你不應(yīng)該在你應(yīng)用的關(guān)鍵路徑上避免 IO 操作。下面是一些你應(yīng)該遵循的 Java IO 最佳實(shí)踐:a)使用有緩沖區(qū)的 IO 類,而不要單獨(dú)讀取字節(jié)或字符。b)使用 NIO 和 NIO2c)在 finally 塊中關(guān)閉流,或者使用 try-with-resource 語(yǔ)句。d)使用內(nèi)存映射文件獲取更快的 IO。

80)列出 5 個(gè)應(yīng)該遵循的 JDBC 最佳實(shí)踐(答案)有很多的最佳實(shí)踐,你可以根據(jù)你的喜好來(lái)例舉。下面是一些更通用的原則:a)使用批量的操作來(lái)插入和更新數(shù)據(jù)b)使用 PreparedStatement 來(lái)避免 SQL 異常,并提高性能。c)使用數(shù)據(jù)庫(kù)連接池d)通過(guò)列名來(lái)獲取結(jié)果集,不要使用列的下標(biāo)來(lái)獲取。

81)說(shuō)出幾條 Java 中方法重載的最佳實(shí)踐?(答案)下面有幾條可以遵循的方法重載的最佳實(shí)踐來(lái)避免造成自動(dòng)裝箱的混亂。a)不要重載這樣的方法:一個(gè)方法接收 int 參數(shù),而另個(gè)方法接收 Integer 參數(shù)。b)不要重載參數(shù)數(shù)量一致,而只是參數(shù)順序不同的方法。c)如果重載的方法參數(shù)個(gè)數(shù)多于 5 個(gè),采用可變參數(shù)。

Date、Time 及 Calendar 的面試題

82)在多線程環(huán)境下,SimpleDateFormat 是線程安全的嗎?(答案)不是,非常不幸,DateFormat 的所有實(shí)現(xiàn),包括 SimpleDateFormat 都不是線程安全的,因此你不應(yīng)該在多線程序中使用,除非是在對(duì)外線程安全的環(huán)境中使用,如將SimpleDateFormat 限制在 ThreadLocal 中。如果你不這么做,在解析或者格式化日期的時(shí)候,可能會(huì)獲取到一個(gè)不正確的結(jié)果。因此,從日期、時(shí)間處理的所有實(shí)踐來(lái)說(shuō),我強(qiáng)力推薦 joda-time 庫(kù)。

83)Java 中如何格式化一個(gè)日期?如格式化為 ddMMyyyy 的形式?(答案)Java 中,可以使用 SimpleDateFormat 類或者 joda-time 庫(kù)來(lái)格式日期。DateFormat 類允許你使用多種流行的格式來(lái)格式化日期。參見(jiàn)答案中的示例代碼,代碼中演示了將日期格式化成不同的格式,如 dd-MM-yyyy 或 ddMMyyyy。

84)Java 中,怎么在格式化的日期中顯示時(shí)區(qū)?(答案)

85)Java 中 java.util.Date 與 java.sql.Date 有什么區(qū)別?(答案)

86)Java 中,如何計(jì)算兩個(gè)日期之間的差距?(程序)

87)Java 中,如何將字符串 YYYYMMDD 轉(zhuǎn)換為日期?(答案)

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

89)如何測(cè)試靜態(tài)方法?(答案)可以使用 PowerMock 庫(kù)來(lái)測(cè)試靜態(tài)方法。

90)怎么利用 JUnit 來(lái)測(cè)試一個(gè)方法的異常?(答案)

91)你使用過(guò)哪個(gè)單元測(cè)試庫(kù)來(lái)測(cè)試你的 Java 程序?(答案)

92)@Before 和 @BeforeClass 有什么區(qū)別?(答案)

編程和代碼相關(guān)的面試題

93)怎么檢查一個(gè)字符串只包含數(shù)字?(解決方案)

94)Java 中如何利用泛型寫(xiě)一個(gè) LRU 緩存?(答案<)

95)寫(xiě)一段 Java 程序?qū)?byte 轉(zhuǎn)換為 long?(答案)

96)在不使用 StringBuffer 的前提下,怎么反轉(zhuǎn)一個(gè)字符串?(解決方案)

97)Java 中,怎么獲取一個(gè)文件中單詞出現(xiàn)的最高頻率?(解決方案)

98)如何檢查出兩個(gè)給定的字符串是反序的?(解決方案)

99)Java 中,怎么打印出一個(gè)字符串的所有排列?(解決方案)

100)Java 中,怎樣才能打印出數(shù)組中的重復(fù)元素?(解決方案)

101)Java 中如何將字符串轉(zhuǎn)換為整數(shù)?(解決方案)

102)在沒(méi)有使用臨時(shí)變量的情況如何交換兩個(gè)整數(shù)變量的值?(解決方案)

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

這部分包含 Java 面試過(guò)程中關(guān)于 SOLID 的設(shè)計(jì)原則,OOP 基礎(chǔ),如類,對(duì)象,接口,繼承,多態(tài),封裝,抽象以及更高級(jí)的一些概念,如組合、聚合及關(guān)聯(lián)。也包含了 GOF 設(shè)計(jì)模式的問(wèn)題。

103)接口是什么?為什么要使用接口而不是直接使用具體類?接口用于定義 API。它定義了類必須得遵循的規(guī)則。同時(shí),它提供了一種抽象,因?yàn)榭蛻舳酥皇褂媒涌冢@樣可以有多重實(shí)現(xiàn),如 List 接口,你可以使用可隨機(jī)訪問(wèn)的ArrayList,也可以使用方便插入和刪除的 LinkedList。接口中不允許寫(xiě)代碼,以此來(lái)保證抽象,但是 Java 8 中你可以在接口聲明靜態(tài)的默認(rèn)方法,這種方法是具體的。

104)Java 中,抽象類與接口之間有什么不同?(答案)Java 中,抽象類和接口有很多不同之處,但是最重要的一個(gè)是 Java 中限制一個(gè)類只能繼承一個(gè)類,但是可以實(shí)現(xiàn)多個(gè)接口。抽象類可以很好的定義一個(gè)家族類的默認(rèn)行為,而接口能更好的定義類型,有助于后面實(shí)現(xiàn)多態(tài)機(jī)制。關(guān)于這個(gè)問(wèn)題的討論請(qǐng)查看答案。

105)除了單例模式,你在生產(chǎn)環(huán)境中還用過(guò)什么設(shè)計(jì)模式?這需要根據(jù)你的經(jīng)驗(yàn)來(lái)回答。一般情況下,你可以說(shuō)依賴注入,工廠模式,裝飾模式或者觀察者模式,隨意選擇你使用過(guò)的一種即可。不過(guò)你要準(zhǔn)備回答接下的基于你選擇的模式的問(wèn)題。

106)你能解釋一下里氏替換原則嗎?(答案)

107) 什么情況下會(huì)違反迪米特法則?為什么會(huì)有這個(gè)問(wèn)題?(答案)迪米特法則建議“只和朋友說(shuō)話,不要陌生人說(shuō)話”,以此來(lái)減少類之間的耦合。

108)適配器模式是什么?什么時(shí)候使用?適配器模式提供對(duì)接口的轉(zhuǎn)換。如果你的客戶端使用某些接口,但是你有另外一些接口,你就可以寫(xiě)一個(gè)適配去來(lái)連接這些接口。

109)什么是“依賴注入”和“控制反轉(zhuǎn)”?為什么有人使用?(答案)

110)抽象類是什么?它與接口有什么區(qū)別?你為什么要使用過(guò)抽象類?(答案)

111)構(gòu)造器注入和 setter 依賴注入,那種方式更好?(答案)每種方式都有它的缺點(diǎn)和優(yōu)點(diǎn)。構(gòu)造器注入保證所有的注入都被初始化,但是 setter 注入提供更好的靈活性來(lái)設(shè)置可選依賴。如果使用 XML 來(lái)描述依賴,Setter 注入的可讀寫(xiě)會(huì)更強(qiáng)。經(jīng)驗(yàn)法則是強(qiáng)制依賴使用構(gòu)造器注入,可選依賴使用 setter 注入。

112)依賴注入和工程模式之間有什么不同?(答案)雖然兩種模式都是將對(duì)象的創(chuàng)建從應(yīng)用的邏輯中分離,但是依賴注入比工程模式更清晰。通過(guò)依賴注入,你的類就是 POJO,它只知道依賴而不關(guān)心它們?cè)趺传@取。使用工廠模式,你的類需要通過(guò)工廠來(lái)獲取依賴。因此,使用 DI 會(huì)比使用工廠模式更容易測(cè)試。關(guān)于這個(gè)話題的更詳細(xì)討論請(qǐng)參見(jiàn)答案。

113)適配器模式和裝飾器模式有什么區(qū)別?(答案)雖然適配器模式和裝飾器模式的結(jié)構(gòu)類似,但是每種模式的出現(xiàn)意圖不同。適配器模式被用于橋接兩個(gè)接口,而裝飾模式的目的是在不修改類的情況下給類增加新的功能。

114)適配器模式和代理模式之前有什么不同?(答案)這個(gè)問(wèn)題與前面的類似,適配器模式和代理模式的區(qū)別在于他們的意圖不同。由于適配器模式和代理模式都是封裝真正執(zhí)行動(dòng)作的類,因此結(jié)構(gòu)是一致的,但是適配器模式用于接口之間的轉(zhuǎn)換,而代理模式則是增加一個(gè)額外的中間層,以便支持分配、控制或智能訪問(wèn)。

115)什么是模板方法模式?(答案)模板方法提供算法的框架,你可以自己去配置或定義步驟。例如,你可以將排序算法看做是一個(gè)模板。它定義了排序的步驟,但是具體的比較,可以使用 Comparable 或者其語(yǔ)言中類似東西,具體策略由你去配置。列出算法概要的方法就是眾所周知的模板方法。

116)什么時(shí)候使用訪問(wèn)者模式?(答案)訪問(wèn)者模式用于解決在類的繼承層次上增加操作,但是不直接與之關(guān)聯(lián)。這種模式采用雙派發(fā)的形式來(lái)增加中間層。

117)什么時(shí)候使用組合模式?(答案)組合模式使用樹(shù)結(jié)構(gòu)來(lái)展示部分與整體繼承關(guān)系。它允許客戶端采用統(tǒng)一的形式來(lái)對(duì)待單個(gè)對(duì)象和對(duì)象容器。當(dāng)你想要展示對(duì)象這種部分與整體的繼承關(guān)系時(shí)采用組合模式。

118)繼承和組合之間有什么不同?(答案)雖然兩種都可以實(shí)現(xiàn)代碼復(fù)用,但是組合比繼承共靈活,因?yàn)榻M合允許你在運(yùn)行時(shí)選擇不同的實(shí)現(xiàn)。用組合實(shí)現(xiàn)的代碼也比繼承測(cè)試起來(lái)更加簡(jiǎn)單。

119)描述 Java 中的重載和重寫(xiě)?(答案)重載和重寫(xiě)都允許你用相同的名稱來(lái)實(shí)現(xiàn)不同的功能,但是重載是編譯時(shí)活動(dòng),而重寫(xiě)是運(yùn)行時(shí)活動(dòng)。你可以在同一個(gè)類中重載方法,但是只能在子類中重寫(xiě)方法。重寫(xiě)必須要有繼承。

120)Java 中,嵌套公共靜態(tài)類與頂級(jí)類有什么不同?(答案)類的內(nèi)部可以有多個(gè)嵌套公共靜態(tài)類,但是一個(gè) Java 源文件只能有一個(gè)頂級(jí)公共類,并且頂級(jí)公共類的名稱與源文件名稱必須一致。

121) OOP 中的 組合、聚合和關(guān)聯(lián)有什么區(qū)別?(答案)如果兩個(gè)對(duì)象彼此有關(guān)系,就說(shuō)他們是彼此相關(guān)聯(lián)的。組合和聚合是面向?qū)ο笾械膬煞N形式的關(guān)聯(lián)。組合是一種比聚合更強(qiáng)力的關(guān)聯(lián)。組合中,一個(gè)對(duì)象是另一個(gè)的擁有者,而聚合則是指一個(gè)對(duì)象使用另一個(gè)對(duì)象。如果對(duì)象 A 是由對(duì)象 B 組合的,則 A 不存在的話,B一定不存在,但是如果 A 對(duì)象聚合了一個(gè)對(duì)象 B,則即使 A 不存在了,B 也可以單獨(dú)存在。

122)給我一個(gè)符合開(kāi)閉原則的設(shè)計(jì)模式的例子?(答案)開(kāi)閉原則要求你的代碼對(duì)擴(kuò)展開(kāi)放,對(duì)修改關(guān)閉。這個(gè)意思就是說(shuō),如果你想增加一個(gè)新的功能,你可以很容易的在不改變已測(cè)試過(guò)的代碼的前提下增加新的代碼。有好幾個(gè)設(shè)計(jì)模式是基于開(kāi)閉原則的,如策略模式,如果你需要一個(gè)新的策略,只需要實(shí)現(xiàn)接口,增加配置,不需要改變核心邏輯。一個(gè)正在工作的例子是 Collections.sort() 方法,這就是基于策略模式,遵循開(kāi)閉原則的,你不需為新的對(duì)象修改 sort() 方法,你需要做的僅僅是實(shí)現(xiàn)你自己的 Comparator 接口。

123)抽象工廠模式和原型模式之間的區(qū)別?(答案)

124)什么時(shí)候使用享元模式?(答案)享元模式通過(guò)共享對(duì)象來(lái)避免創(chuàng)建太多的對(duì)象。為了使用享元模式,你需要確保你的對(duì)象是不可變的,這樣你才能安全的共享。JDK 中 String 池、Integer 池以及 Long 池都是很好的使用了享元模式的例子。

Java 面試中其他各式各樣的問(wèn)題

這部分包含 Java 中關(guān)于 XML 的面試題,JDBC 面試題,正則表達(dá)式面試題,Java 錯(cuò)誤和異常及序列化面試題

125)嵌套靜態(tài)類與頂級(jí)類有什么區(qū)別?(答案)一個(gè)公共的頂級(jí)類的源文件名稱與類名相同,而嵌套靜態(tài)類沒(méi)有這個(gè)要求。一個(gè)嵌套類位于頂級(jí)類內(nèi)部,需要使用頂級(jí)類的名稱來(lái)引用嵌套靜態(tài)類,如 HashMap.Entry 是一個(gè)嵌套靜態(tài)類,HashMap 是一個(gè)頂級(jí)類,Entry是一個(gè)嵌套靜態(tài)類。

126)你能寫(xiě)出一個(gè)正則表達(dá)式來(lái)判斷一個(gè)字符串是否是一個(gè)數(shù)字嗎?(解決方案)一個(gè)數(shù)字字符串,只能包含數(shù)字,如 0 到 9 以及 +、- 開(kāi)頭,通過(guò)這個(gè)信息,你可以下一個(gè)如下的正則表達(dá)式來(lái)判斷給定的字符串是不是數(shù)字。

127)Java 中,受檢查異常 和 不受檢查異常的區(qū)別?(答案)受檢查異常編譯器在編譯期間檢查。對(duì)于這種異常,方法強(qiáng)制處理或者通過(guò) throws 子句聲明。其中一種情況是 Exception 的子類但不是 RuntimeException 的子類。非受檢查是 RuntimeException 的子類,在編譯階段不受編譯器的檢查。

128)Java 中,throw 和 throws 有什么區(qū)別?(答案)throw 用于拋出 java.lang.Throwable 類的一個(gè)實(shí)例化對(duì)象,意思是說(shuō)你可以通過(guò)關(guān)鍵字 throw 拋出一個(gè) Error 或者 一個(gè)Exception,如:throw new IllegalArgumentException(“size must be multiple of 2″)

而throws 的作用是作為方法聲明和簽名的一部分,方法被拋出相應(yīng)的異常以便調(diào)用者能處理。Java 中,任何未處理的受檢查異常強(qiáng)制在 throws 子句中聲明。

129)Java 中,Serializable 與 Externalizable 的區(qū)別?(答案)Serializable 接口是一個(gè)序列化 Java 類的接口,以便于它們可以在網(wǎng)絡(luò)上傳輸或者可以將它們的狀態(tài)保存在磁盤(pán)上,是 JVM 內(nèi)嵌的默認(rèn)序列化方式,成本高、脆弱而且不安全。Externalizable 允許你控制整個(gè)序列化過(guò)程,指定特定的二進(jìn)制格式,增加安全機(jī)制。

130)Java 中,DOM 和 SAX 解析器有什么不同?(答案)DOM 解析器將整個(gè) XML 文檔加載到內(nèi)存來(lái)創(chuàng)建一棵 DOM 模型樹(shù),這樣可以更快的查找節(jié)點(diǎn)和修改 XML 結(jié)構(gòu),而 SAX 解析器是一個(gè)基于事件的解析器,不會(huì)將整個(gè) XML 文檔加載到內(nèi)存。由于這個(gè)原因,DOM 比 SAX 更快,也要求更多的內(nèi)存,不適合于解析大 XML 文件。

131)說(shuō)出 JDK 1.7 中的三個(gè)新特性?(答案)雖然 JDK 1.7 不像 JDK 5 和 8 一樣的大版本,但是,還是有很多新的特性,如 try-with-resource 語(yǔ)句,這樣你在使用流或者資源的時(shí)候,就不需要手動(dòng)關(guān)閉,Java 會(huì)自動(dòng)關(guān)閉。Fork-Join 池某種程度上實(shí)現(xiàn) Java 版的 Map-reduce。允許 Switch 中有 String 變量和文本。菱形操作符(<>)用于類型推斷,不再需要在變量聲明的右邊申明泛型,因此可以寫(xiě)出可讀寫(xiě)更強(qiáng)、更簡(jiǎn)潔的代碼。另一個(gè)值得一提的特性是改善異常處理,如允許在同一個(gè) catch 塊中捕獲多個(gè)異常。

132)說(shuō)出 5 個(gè) JDK 1.8 引入的新特性?(答案)Java 8 在 Java 歷史上是一個(gè)開(kāi)創(chuàng)新的版本,下面 JDK 8 中 5 個(gè)主要的特性:Lambda 表達(dá)式,允許像對(duì)象一樣傳遞匿名函數(shù)Stream API,充分利用現(xiàn)代多核 CPU,可以寫(xiě)出很簡(jiǎn)潔的代碼Date 與 Time API,最終,有一個(gè)穩(wěn)定、簡(jiǎn)單的日期和時(shí)間庫(kù)可供你使用擴(kuò)展方法,現(xiàn)在,接口中可以有靜態(tài)、默認(rèn)方法。重復(fù)注解,現(xiàn)在你可以將相同的注解在同一類型上使用多次。

133)Java 中,Maven 和 ANT 有什么區(qū)別?(答案)雖然兩者都是構(gòu)建工具,都用于創(chuàng)建 Java 應(yīng)用,但是 Maven 做的事情更多,在基于“約定優(yōu)于配置”的概念下,提供標(biāo)準(zhǔn)的Java 項(xiàng)目結(jié)構(gòu),同時(shí)能為應(yīng)用自動(dòng)管理依賴(應(yīng)用中所依賴的 JAR 文件),Maven 與 ANT 工具更多的不同之處請(qǐng)參見(jiàn)答案。

這就是所有的面試題,如此之多,是不是?我可以保證,如果你能回答列表中的所有問(wèn)題,你就可以很輕松的應(yīng)付任何核心 Java 或者高級(jí) Java 面試。雖然,這里沒(méi)有涵蓋 Servlet、JSP、JSF、JPA,JMS,EJB 及其它 Java EE 技術(shù),也沒(méi)有包含主流的框架如 Spring MVC,Struts 2.0,Hibernate,也沒(méi)有包含 SOAP 和 RESTful web service,但是這份列表對(duì)做 Java 開(kāi)發(fā)的、準(zhǔn)備應(yīng)聘 Java web 開(kāi)發(fā)職位的人還是同樣有用的,因?yàn)樗械?Java 面試,開(kāi)始的問(wèn)題都是 Java 基礎(chǔ)和 JDK API 相關(guān)的。如果你認(rèn)為我這里有任何應(yīng)該在這份列表中而被我遺漏了的 Java 流行的問(wèn)題,你可以自由的給我建議。我的目的是從最近的面試中創(chuàng)建一份最新的、最優(yōu)的 Java 面試問(wèn)題列表。

 Java EE 相關(guān)的面試題

為了做 Java EE 的朋友,這里列出了一些 web 開(kāi)發(fā)的特定問(wèn)題,你們可以用來(lái)準(zhǔn)備 JEE 部分的面試:

10 大 Spring 框架面試題及答案(參見(jiàn))10 個(gè)非常好的 XML 面試問(wèn)題(Java 程序員)(參見(jiàn))20 個(gè)非常好的設(shè)計(jì)模式面試問(wèn)題(參見(jiàn))10個(gè)最流行的 Struts 面試題(Java 開(kāi)發(fā)者)(參見(jiàn))20 個(gè) Tibco Rendezvous 及 EMS 的面試題(更多)10 個(gè)最頻繁被問(wèn)到的 Servlet 面試問(wèn)題及答案(參見(jiàn))20 個(gè) jQuery 面試問(wèn)題(Java Web 開(kāi)發(fā)者)(列表)10 個(gè)非常好的 Oracle 面試問(wèn)題(Java 開(kāi)發(fā)者)(參見(jiàn))10 大 來(lái)自 J2EE 面試中的 JSP 問(wèn)題(更多)12 個(gè)很好的 RESTful Web Services 面試問(wèn)題(參見(jiàn))10 大 EJB 面試問(wèn)題及答案(參見(jiàn))10 大 JMS 及 MQ 系列面試題及答案(列表)10 個(gè)非常好 Hibernate 面試問(wèn)題(Java EE 開(kāi)發(fā)者)(參見(jiàn))10 個(gè)非常好的 JDBC 面試題(Java 開(kāi)發(fā)者)(參見(jiàn))15 個(gè) Java NIO 和網(wǎng)絡(luò)面試題及答案(參見(jiàn))10 大 XSLT 面試題及答案(更多)15 個(gè)來(lái)自 Java 面試的數(shù)據(jù)結(jié)構(gòu)和算法問(wèn)題(參見(jiàn))10 大 Java 面試難題及答案(參見(jiàn))40 個(gè)核心 Java 移動(dòng)開(kāi)發(fā)面試題及答案(列表)

推薦給 Java 面試者的書(shū)籍如果你正為 Java 面試尋找好的準(zhǔn)備,你可以看一下下面的書(shū)籍,這些書(shū)籍包含了理論及編碼的相關(guān)問(wèn)題Markham 的 Java 編程面試揭秘(參見(jiàn))破解編碼面試:150 個(gè)編程問(wèn)題及解答(參見(jiàn))程序面試揭秘:尋找下一份工作的秘密(參見(jiàn))

原文鏈接: javarevisited 翻譯: ImportNew

標(biāo)簽: Java
相關(guān)文章:
主站蜘蛛池模板: 中国国产一国产一级毛片视频 | 国产又色又爽在线观看 | 一级做a爱免费观看视频 | 污网站大全 | 亚洲精品色一区二区三区 | 国产精品一区二区在线播放 | 一级片视频网站 | 亚州综合激情另类久久久 | 久久久久久国产精品三级 | 一级毛片特级毛片免费的 | 日本hdxxxxx护士免费的 | 中文字幕一区在线播放 | 国产精品jizz观看 | 啪啪网站在线观看 | 国内精品视频一区二区三区 | 在线国产一区二区三区 | 国产极品美女网站在线观看 | 亚洲 欧美 精品 中文第三 | 欧美性视频一区二区三区 | 欧美日韩一区在线观看 | 成人黄色激情网站 | 成人性视频在线三级 | 欧美人在线一区二区三区 | 污污的网站免费观看 | 99热这里只有精品国产免费 | 成人羞羞视频在线看网址 | 午夜精品一区二区三区免费视频 | 日韩一区国产二区欧美三 | 韩国一级黄色录像 | 一区亚洲| 成人精品视频一区二区三区尤物 | 九九热精品国产 | 青青操手机看 | 欧美三级欧美做a爱 | a级一片 | 亚洲精品视频在线播放 | 精品国产福利在线 | 欧美大黄视频 | 国产一级视频久久 | 国产黄色大全 | 激情在线播放免费视频高清 |