8道Java经典面试题
Java 基礎(chǔ)?1、談?wù)勀銓?Java 平臺的理解?“Java 是解釋執(zhí)行”,這句話正確嗎?
考點(diǎn)分析:
對于這類籠統(tǒng)的問題,你需要盡量表現(xiàn)出自己的思維深入并系統(tǒng)化,Java 知識理解得也比較全面,一定要避免讓面試官覺得你是個(gè)“知其然不知其所以然”的人。 畢竟明白基本組成和機(jī)制,是日常工作中進(jìn)行問題診斷或者性能調(diào)優(yōu)等很多事情的基礎(chǔ),相信沒有招聘方會不喜歡“熱愛學(xué)習(xí)和思考”的面試者。
回歸正題,對于 Java 平臺的理解,可以從很多方面簡明扼要地談一下,例如:Java 語言特性,包括泛型、Lambda 等語言特性;基礎(chǔ)類庫,包括集合、IO/NIO、網(wǎng)絡(luò)、并發(fā)、安全等基礎(chǔ)類庫。對于我們?nèi)粘9ぷ鲬?yīng)用較多的類庫,面試前可以系統(tǒng)化總結(jié)一下,有助于臨場發(fā)揮。
下圖是我總結(jié)的一個(gè)相對寬泛的藍(lán)圖供你參考。
?
?2、請對比 Exception 和 Error,另外,運(yùn)行時(shí)異常與一般異常有什么區(qū)別?
考點(diǎn)分析:
分析 Exception 和 Error 的區(qū)別,是從概念角度考察了 Java 處理機(jī)制。總的來說,還處于理解的層面,面試者只要闡述清楚就好了。
我們在日常編程中,如何處理好異常是比較考驗(yàn)功底的,我覺得需要掌握兩個(gè)方面。
第一,理解 Throwable、Exception、Error 的設(shè)計(jì)和分類。 比如,掌握那些應(yīng)用最為廣泛的子類,以及如何自定義異常等。
很多面試官會進(jìn)一步追問一些細(xì)節(jié),比如,你了解哪些 Error、Exception 或者 RuntimeException?我畫了一個(gè)簡單的類圖,并列出來典型例子,可以給你作為參考,至少做到基本心里有數(shù)。
第二,理解 Java 語言中操作 Throwable 的元素和實(shí)踐。 掌握最基本的語法是必須的,如 try-catch-finally 塊,throw、throws 關(guān)鍵字等。與此同時(shí),也要懂得如何處理典型場景。
?3、談?wù)?Java 反射機(jī)制,動態(tài)代理是基于什么原理?
考點(diǎn)分析:
這個(gè)題目給我的第一印象是稍微有點(diǎn)誘導(dǎo)的嫌疑,可能會下意識地以為動態(tài)代理就是利用反射機(jī)制實(shí)現(xiàn)的,這么說也不算錯(cuò)但稍微有些不全面。功能才是目的,實(shí)現(xiàn)的方法有很多。
總的來說,這道題目考察的是 Java 語言的另外一種基礎(chǔ)機(jī)制: 反射,它就像是一種魔法,引入運(yùn)行時(shí)自省能力,賦予了 Java 語言令人意外的活力,通過運(yùn)行時(shí)操作元數(shù)據(jù)或?qū)ο?#xff0c;Java 可以靈活地操作運(yùn)行時(shí)才能確定的信息。 而動態(tài)代理,則是延伸出來的一種廣泛應(yīng)用于產(chǎn)品開發(fā)中的技術(shù),很多繁瑣的重復(fù)編程,都可以被動態(tài)代理機(jī)制優(yōu)雅地解決。
從考察知識點(diǎn)的角度,這道題涉及的知識點(diǎn)比較龐雜,所以面試官能夠擴(kuò)展或者深挖的內(nèi)容非常多,比如:
-
考察你對反射機(jī)制的了解和掌握程度。
-
動態(tài)代理解決了什么問題,在你業(yè)務(wù)系統(tǒng)中的應(yīng)用場景是什么?
-
JDK 動態(tài)代理在設(shè)計(jì)和實(shí)現(xiàn)上與 cglib 等方式有什么不同,進(jìn)而如何取舍?
?4、Java 提供了哪些 IO 方式? NIO 如何實(shí)現(xiàn)多路復(fù)用?
在實(shí)際面試中,從傳統(tǒng) IO 到 NIO、NIO 2,其中有很多地方可以擴(kuò)展開來,考察點(diǎn)涉及方方面面,比如:
-
基礎(chǔ) API 功能與設(shè)計(jì), InputStream/OutputStream 和 Reader/Writer 的關(guān)系和區(qū)別。
-
NIO、NIO 2 的基本組成。
-
給定場景,分別用不同模型實(shí)現(xiàn),分析 BIO、NIO 等模式的設(shè)計(jì)和實(shí)現(xiàn)原理。
-
NIO 提供的高性能數(shù)據(jù)操作方式是基于什么原理,如何使用?
-
或者,從開發(fā)者的角度來看,你覺得 NIO 自身實(shí)現(xiàn)存在哪些問題?有什么改進(jìn)的想法嗎?
IO 的內(nèi)容比較多,專欄一講很難能夠說清楚。IO 不僅僅是多路復(fù)用,NIO 2 也不僅僅是異步 IO,尤其是數(shù)據(jù)操作部分,會在專欄下一講詳細(xì)分析。
?5、如何保證容器是線程安全的?ConcurrentHashMap 如何實(shí)現(xiàn)高效地線程安全?
典型回答:
Java 提供了不同層面的線程安全支持。在傳統(tǒng)集合框架內(nèi)部,除了 Hashtable 等同步容器,還提供了所謂的同步包裝器(Synchronized Wrapper),我們可以調(diào)用 Collections 工具類提供的包裝方法,來獲取一個(gè)同步的包裝容器(如 Collections.synchronizedMap),但是它們都是利用非常粗粒度的同步方式,在高并發(fā)情況下,性能比較低下。
另外,更加普遍的選擇是利用并發(fā)包提供的線程安全容器類,它提供了:
-
各種并發(fā)容器,比如 ConcurrentHashMap、CopyOnWriteArrayList。
-
各種線程安全隊(duì)列(Queue/Deque),如 ArrayBlockingQueue、SynchronousQueue。
-
各種有序容器的線程安全版本等。
具體保證線程安全的方式,包括有從簡單的 synchronize 方式,到基于更加精細(xì)化的,比如基于分離鎖實(shí)現(xiàn)的 ConcurrentHashMap 等并發(fā)實(shí)現(xiàn)等。具體選擇要看開發(fā)的場景需求,總體來說,并發(fā)包內(nèi)提供的容器通用場景,遠(yuǎn)優(yōu)于早期的簡單同步實(shí)現(xiàn)。
?6、談?wù)劷涌诤统橄箢愑惺裁磪^(qū)別?
考點(diǎn)分析:
這是個(gè)非常高頻的 Java 面向?qū)ο蠡A(chǔ)問題,看起來非常簡單的問題,如果面試官稍微深入一些,你會發(fā)現(xiàn)很多有意思的地方,可以從不同角度全面地考察你對基本機(jī)制的理解和掌握。
比如:
-
對于 Java 的基本元素的語法是否理解準(zhǔn)確。 能否定義出語法基本正確的接口、抽象類或者相關(guān)繼承實(shí)現(xiàn),涉及重載(Overload)、重寫(Override)更是有各種不同的題目。
-
在軟件設(shè)計(jì)開發(fā)中妥善地使用接口和抽象類。 你至少知道典型應(yīng)用場景,掌握基礎(chǔ)類庫重要接口的使用;掌握設(shè)計(jì)方法,能夠在 review 代碼的時(shí)候看出明顯的不利于未來維護(hù)的設(shè)計(jì)。
-
掌握 Java 語言特性演進(jìn)。 現(xiàn)在非常多的框架已經(jīng)是基于 Java 8,并逐漸支持更新版本,掌握相關(guān)語法,理解設(shè)計(jì)目的是很有必要的。
Java 進(jìn)階?7、synchronized 底層如何實(shí)現(xiàn)?什么是鎖的升級、降級?
考點(diǎn)分析:
今天的問題主要是考察你對 Java 內(nèi)置鎖實(shí)現(xiàn)的掌握,也是并發(fā)的經(jīng)典題目。我在前面給出的典型回答,涵蓋了一些基本概念。如果基礎(chǔ)不牢,有些概念理解起來就比較晦澀,我建議還是盡量理解和掌握,即使有不懂的也不用擔(dān)心,在后續(xù)學(xué)習(xí)中還會逐步加深認(rèn)識。
我個(gè)人認(rèn)為,能夠基礎(chǔ)性地理解這些概念和機(jī)制,其實(shí)對于大多數(shù)并發(fā)編程已經(jīng)足夠了,畢竟大部分工程師未必會進(jìn)行更底層、更基礎(chǔ)的研發(fā),很多時(shí)候解決的是知道與否,真正的提高還要靠實(shí)踐踩坑。
后面我會進(jìn)一步分析:
-
從源碼層面,稍微展開一些 synchronized 的底層實(shí)現(xiàn),并補(bǔ)充一些上面答案中欠缺的細(xì)節(jié),有同學(xué)反饋這部分容易被問到。如果你對 Java 底層源碼有興趣,但還沒有找到入手點(diǎn),這里可以成為一個(gè)切入點(diǎn)。
-
理解并發(fā)包中 java.util.concurrent.lock 提供的其他鎖實(shí)現(xiàn),畢竟 Java 可不是只有 ReentrantLock 一種顯式的鎖類型,我會結(jié)合代碼分析其使用。
?8、synchronized 和 ReentrantLock 有什么區(qū)別?有人說 synchronized 最慢,這話靠譜嗎?
考點(diǎn)分析:
今天的題目是考察并發(fā)編程的常見基礎(chǔ)題,我給出的典型回答算是一個(gè)相對全面的總結(jié)。
對于并發(fā)編程,不同公司或者面試官面試風(fēng)格也不一樣,有個(gè)別大廠喜歡一直追問你相關(guān)機(jī)制的擴(kuò)展或者底層,有的喜歡從實(shí)用角度出發(fā),所以你在準(zhǔn)備并發(fā)編程方面需要一定的耐心。
我認(rèn)為,鎖作為并發(fā)的基礎(chǔ)工具之一,你至少需要掌握:
-
理解什么是線程安全。
-
synchronized、ReentrantLock 等機(jī)制的基本使用與案例。
更近一步,你還需要:
-
掌握 synchronized、ReentrantLock 底層實(shí)現(xiàn);理解鎖膨脹、降級;理解偏斜鎖、自旋鎖、輕量級鎖、重量級鎖等概念。
-
掌握并發(fā)包中 java.util.concurrent.lock 各種不同實(shí)現(xiàn)和案例分析。
典型回答:
synchronized 是 Java 內(nèi)建的同步機(jī)制,所以也有人稱其為 Intrinsic Locking,它提供了互斥的語義和可見性,當(dāng)一個(gè)線程已經(jīng)獲取當(dāng)前鎖時(shí),其他試圖獲取的線程只能等待或者阻塞在那里。
在 Java 5 以前,synchronized 是僅有的同步手段,在代碼中, synchronized 可以用來修飾方法,也可以使用在特定的代碼塊兒上,本質(zhì)上 synchronized 方法等同于把方法全部語句用 synchronized 塊包起來。
ReentrantLock,通常翻譯為再入鎖,是 Java 5 提供的鎖實(shí)現(xiàn),它的語義和 synchronized 基本相同。再入鎖通過代碼直接調(diào)用 lock() 方法獲取,代碼書寫也更加靈活。與此同時(shí),ReentrantLock 提供了很多實(shí)用的方法,能夠?qū)崿F(xiàn)很多 synchronized 無法做到的細(xì)節(jié)控制,比如可以控制 fairness,也就是公平性,或者利用定義條件等。但是,編碼中也需要注意,必須要明確調(diào)用 unlock() 方法釋放,不然就會一直持有該鎖。
synchronized 和 ReentrantLock 的性能不能一概而論,早期版本 synchronized 在很多場景下性能相差較大,在后續(xù)版本進(jìn)行了較多改進(jìn),在低競爭場景中表現(xiàn)可能優(yōu)于 ReentrantLock。
轉(zhuǎn)載于:https://www.cnblogs.com/davidwang456/articles/9212160.html
總結(jié)
以上是生活随笔為你收集整理的8道Java经典面试题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Hook原理
- 下一篇: 轻量级微服务架构实践之路