Java面試中,遇到這類面試題最吃虧!

從你接觸 Java開發到如今,你對 Java最直觀的印象是什麼呢?是它宣傳的 「Compile once, run anywhere」,仍是目前看已經有些過於形式主義的語法呢?你對於 Java平臺到底瞭解到什麼程度?請你先停下來總結思考一下。java

今天要問你的問題是,談談你對 Java平臺的理解?「Java是解釋執行」,這句話正確嗎?程序員

典型回答面試

Java自己是一種面向對象的語言,最顯著的特性有兩個方面:安全

一是所謂的「一次編譯,處處執行」(Compile once, run anywhere),可以很是容易地得到跨平臺能力;性能優化

另外就是垃圾收集(GC, Garbage Collection),Java經過垃圾收集器(Garbage Collector)回收分配內存,大部分狀況下,程序員不須要本身操心內存的分配和回收。服務器

咱們平常會接觸到 JRE(Java Runtime Environment)或者 JDK(Java Development Kit)。 JRE,也就是 Java運行環境,包含了 JVM和 Java類庫,以及一些模塊等。而 JDK能夠看做是 JRE的一個超集,提供了更多工具,好比編譯器、各類診斷工具等。網絡

對於「Java是解釋執行」這句話,這個說法不太準確。架構

咱們開發的 Java的源代碼,首先經過 Javac編譯成爲字節碼(bytecode),而後,在運行時,經過 Java虛擬機(JVM)內嵌的解釋器將字節碼轉換成爲最終的機器碼。可是常見的 JVM,好比咱們大多數狀況使用的 Oracle JDK提供的 Hospot JVM,都提供了 JIT(Just-In-Time)編譯器,也就是一般所說的動態編譯器,JIT可以在運行時將熱點代碼編譯成機器碼,這種狀況下部分熱點代碼就屬於編譯執行,而不是解釋執行了。併發

考點分析分佈式

其實這個問題,問得有點籠統。題目自己是很是開放的,每每考察的是多個方面,好比,基礎知識理解是否很清楚;是否掌握 Java平臺主要模塊和運行原理等。不少面試者會在這種問題上吃虧,稍微緊張了一下,不知道從何提及,就給出個很簡略的回答。

對於這類籠統的問題,你須要儘可能表現出本身的思惟深刻並系統化,Java知識理解得也比較全面,必定要避免讓面試官以爲你是個「知其然不知其因此然」的人。畢竟明白基本組成和機制,是平常工做中進行問題診斷或者性能調優等不少事情的基礎,相信沒有招聘方會不喜歡「熱愛學習和思考」的面試者。

即便感受本身的回答不是很是完善,也不用擔憂。我我的以爲這種籠統的問題,有時候回答得稍微片面也很正常,大多數有經驗的面試官,不會由於一道題就對面試者輕易地下結論。一般會盡可能引導面試者,把他的真實水平展示出來,這種問題就是作個開場熱身,面試官常常會根據你的回答擴展相關問題。

知識擴展

迴歸正題,對於 Java平臺的理解,能夠從不少方面簡明扼要地談一下,例如:Java語言特性,包括泛型、Lambda等語言特性;基礎類庫,包括集合、IO/NIO、網絡、併發、安全等基礎類庫。對於咱們平常工做應用較多的類庫,面試前能夠系統化總結一下,有助於臨場發揮。

或者談談 JVM的一些基礎概念和機制,好比 Java的類加載機制,經常使用版本 JDK(如 JDK 8)內嵌的 Class-Loader,例如 Bootstrap、 Application和 Extension Class-loader;類加載大體過程:加載、驗證、連接、初始化(這裏參考了周志明的《深刻理解 Java虛擬機》,很是棒的 JVM上手書籍);自定義 Class-Loader等。還有垃圾收集的基本原理,最多見的垃圾收集器,如 SerialGC、Parallel GC、 CMS、 G1等,對於適用於什麼樣的工做負載最好也內心有數。這些都是能夠擴展開的領域,我會在後面的專欄對此進行更系統的介紹。

固然還有 JDK包含哪些工具或者 Java領域內其餘工具等,如編譯器、運行時環境、安全工具、診斷和監控工具等。這些基本工具是平常工做效率的保證,對於咱們工做在其餘語言平臺上,一樣有所幫助,不少都是舉一反三的。

下圖是我總結的一個相對寬泛的藍圖供你參考。

再也不擴展了,回到前面問到的解釋執行和編譯執行的問題。有些面試官喜歡在特定問題上「刨根問底兒」,由於這是進一步瞭解面試者對知識掌握程度的有效方法,我稍微深刻探討一下。

衆所周知,咱們一般把 Java分爲編譯期和運行時。這裏說的 Java的編譯和 C/C++是有着不一樣的意義的,Javac的編譯,編譯 Java源碼生成「.class」文件裏面實際是字節碼,而不是能夠直接執行的機器碼。Java經過字節碼和 Java虛擬機(JVM)這種跨平臺的抽象,屏蔽了操做系統和硬件的細節,這也是實現「一次編譯,處處執行」的基礎。

在運行時,JVM會經過類加載器(Class-Loader)加載字節碼,解釋或者編譯執行。就像我前面提到的,主流 Java版本中,如 JDK 8實際是解釋和編譯混合的一種模式,即所謂的混合模式(-Xmixed)。一般運行在 server模式的 JVM,會進行上萬次調用以收集足夠的信息進行高效的編譯,client模式這個門限是 1500次。Oracle Hotspot JVM內置了兩個不一樣的 JIT compiler,C1對應前面說的 client模式,適用於對於啓動速度敏感的應用,好比普通 Java桌面應用;C2對應 server模式,它的優化是爲長時間運行的服務器端應用設計的。默認是採用所謂的分層編譯(TieredCompilation)。這裏再也不展開更多 JIT的細節,不必一會兒就鑽進去,我會在後面介紹分層編譯的內容。

Java虛擬機啓動時,能夠指定不一樣的參數對運行模式進行選擇。 好比,指定「-Xint」,就是告訴 JVM只進行解釋執行,不對代碼進行編譯,這種模式拋棄了 JIT可能帶來的性能優點。畢竟解釋器(interpreter)是逐條讀入,逐條解釋運行的。與其相對應的,還有一個「-Xcomp」參數,這是告訴 JVM關閉解釋器,不要進行解釋執行,或者叫做最大優化級別。那你可能會問這種模式是否是最高效啊?簡單說,還真未必。「-Xcomp」會致使 JVM啓動變慢很是多,同時有些 JIT編譯器優化方式,好比分支預測,若是不進行 profiling,每每並不能進行有效優化。

除了咱們平常最多見的 Java使用模式,其實還有一種新的編譯方式,即所謂的 AOT(Ahead-of-Time Compilation),直接將字節碼編譯成機器代碼,這樣就避免了 JIT預熱等各方面的開銷,好比 Oracle JDK 9就引入了實驗性的 AOT特性,而且增長了新的 jaotc工具。利用下面的命令把某個類或者某個模塊編譯成爲 AOT庫。

 
  1. jaotc --output libHelloWorld.so HelloWorld.class 
  2. jaotc --output libjava.base.so --module java.base 

而後,在啓動時直接指定就能夠了。

 
  1. java -XX:AOTLibrary=./libHelloWorld.so,./libjava.base.so HelloWorld 

並且,Oracle JDK支持分層編譯和 AOT協做使用,這二者並非二選一的關係。若是你有興趣,能夠參考相關文檔:http://openjdk.java.net/jeps/295。AOT也不只僅是隻有這一種方式,業界早就有第三方工具(如 GCJ、Excelsior JET)提供相關功能。

另外,JVM做爲一個強大的平臺,不只僅只有 Java語言能夠運行在 JVM上,本質上合規的字節碼均可以運行,Java語言自身也爲此提供了便利,咱們能夠看到相似 Clojure、Scala、Groovy、JRuby、Jython等大量 JVM語言,活躍在不一樣的場景。

今天,我簡單介紹了一下 Java平臺相關的一些內容,目的是提綱挈領地構建一個總體的印象,包括 Java語言特性、 核心類庫與經常使用第三方類庫、Java虛擬機基本原理和相關工具,但願對你有所幫助。

在此我向你們推薦一個Java高級羣 :725633148 裏面會分享一些資深架構師錄製的視頻錄像:(有Spring,MyBatis,Netty源碼分析,高併發、高性能、分佈式、微服務架構的原理,JVM性能優化、分佈式架構)等這些成爲架構師必備的知識體系 進羣立刻免費領取,目前受益良多!

相關文章
相關標籤/搜索