Java面試經典題解析——談談你對Java平臺的理解?

2021-02-23 InfoQ

點擊關注 InfoQ,置頂公眾號

接收程式設計師的技術早餐

從你接觸 Java開發到現在,你對 Java最直觀的印象是什麼呢?是它宣傳的 「Compile once, run anywhere」,還是目前看已經有些過於形式主義的語法呢?你對於 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核心技術 36講》

回歸正題,對於 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核心技術 36講》

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

眾所周知,我們通常把 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庫。

jaotc --output libHelloWorld.so HelloWorld.classjaotc --output libjava.base.so --module java.base

然後,在啟動時直接指定就可以了。

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經典面試題深度解析?推薦關注《Java核心技術 36講》。專欄重點圍繞「術」與「道」,為你講解 Java面試的核心知識點。就算你暫時不需要準備面試,照樣可以通過這個專欄,提升 Java技能。

福利一:限時優惠價¥45,原價¥68(5月 12日恢復原價)

福利二:每邀請一位好友購買,你可獲得 18元現金返現,多邀多得,上不封頂,立即提現(提現流程:極客時間公眾號 -我的 -現金獎勵提現)

點擊下圖,微信支付,立即成功訂閱。

點「閱讀原文」,試讀或訂閱專欄。

相關焦點

  • 50道Java集合經典面試題(收藏版)
    前言來了來了,50道Java集合面試題也來啦~ 已經上傳github:https://github.com/whx123/JavaHome1.hashset保證元素不重複~ (這個面試官很可能會問什麼原理,這個跟HashMap有關的哦)HashSet,需要談談它倆hashcode()和equles()哦~實際是基於HashMap實現的,HashSet 底層使用HashMap來保存所有元素的看看它的add方法吧~ public boolean
  • 一道面試題考驗了你對Java的理解程度
    簡介最近看到一篇文章,關於一道面試題,先看一下題目,如下:public static void main(String[] args
  • 尚矽谷Java視頻教程_Java面試題第一季
    網際網路寒冬來臨,打鐵還需自身硬,嘟嘟這裡分享一套最新Java面試題視頻,祝你更上一層樓。
  • 【Java面試系列】Java面試題基礎系列212道(上)
    1.Java面試題1、面向對象的特徵有哪些方面?
  • 面試乾貨 | Java 能否自定義一個類叫 java.lang.System?
    博客地址:https://blog.csdn.net/m0_43452671緣起:一個面試題最近在上下班地鐵刷博客,無意刷到一個面試題,號稱很多程式設計師的烈士公墓:java 能否自己寫一個類叫 java.lang.System博主也提供了相關的答案:一般情況下是不可以的,但是可以通過特殊的處理來達到目的,這個特殊的處理就是自己寫個類加載器來加載自己寫的這個 j
  • 連載 Java面試題全集(六)
    答:問題1:創建java.util.Calendar 實例,調用其get()方法傳入不同的參數即可獲得參數所對應的值。Java 8中可以使用java.time.LocalDateTimel來獲取,代碼如下所示。
  • Java面試題全集 第二彈(史上最強)
    提示:如果不能給出此題的正確答案,說明之前第21題Java類加載機制還沒有完全理解,趕緊再看看吧。13、數據類型之間的轉換:- 如何將字符串轉換為基本數據類型?- 如何將基本數據類型轉換為字符串?面試題:2005年摩託羅拉的面試中曾經問過這麼一個問題「If a process reports a stack overflow run-time error, what’s the most possible cause?」
  • Java經典面試題 Java中char所佔字節
    首先大家看一下這個Java面試題        在Java語言中,字符串「Java程式設計師」在內存中所佔用的字節數是:()。
  • Java 最常見的 200+ 面試題全解析
    第二:這只是經驗的高度提煉,讓那些原本就掌握了技術卻不知道怎麼表達的人,學會如何在面試中展示自己。第三:如果只是死記硬背這些面試題,只要面試官再深入問糾一下,也可對這個人有一個準確的認識,之前說的「幫人作弊」的事就不存在了。
  • Java經典面試題:一個線程兩次調用start()方法會出現什麼情況?
    今天想和大家深入聊聊線程,相信大家對於線程這個概念都不陌生,它是Java並發的基礎元素,理解、操縱、診斷線程是Java工程師的必修課,但是你真的掌握線程了嗎?以下內容來自從我的專欄--《Java核心技術36講》,每一道Java經典面試題,從「典型回答」、「考點分析」、「知識擴展」三方面剖析這道題的來龍去脈及知識要點。
  • 從面試題中看Java的Reference(引用)
    話不多說,進入正題:常見的面試中會有這麼一道題,「談談強引用、 軟引用、 弱引用、虛引用」。A:強引用,通過new出來的都是強引用Q:那弱引用呢?A:通過WeakReference構造出的,不再有強引用...Q:那軟引用呢,這些引用間的區別是什麼?A:...面到這個階段這就比較尷尬了。
  • 【每日一題】(42題)談談你對Http2.0的理解?
    往期「每日一題」1、JavaScript && ES6•第 41 題:【每日一題】(41題)JS代碼到底是如何被壓縮的?•第 40 題:【每日一題】(40題)關於script標籤,你可能不知道的地方?•第 39 題:【每日一題】(39題)談談JS的函數擴展?•第 30 題:【每日一題】(30題)面試官:ES6的解構賦值的理解?
  • Java面試必會真題(附詳細解析)
    除了掌握紮實的專業技能之外,你還需要一本《Java程式設計師面試寶典》才能在萬千面試者中殺出重圍,成功拿下offer。小編特意整理了當下熱點的多線程、Spring部分面試真題及解析分享給大家,希望大家都能順利通過面試,拿下高薪。趕緊碼住吧!
  • 死磕一道面試題引發的對Java內存模型的一點疑問,第四部.
    死磕一道面試題引發的對Java內存模型的一點疑問,第四部。第一部在這裡 一道面試題引發的對Java內存模型的一點疑問?[1]第二部在這裡一道面試題引發的對Java內存模型的一點疑問,第二部[2]第三部在這裡一道面試題引發的對Java內存模型的一點疑問,第三部[3]。
  • 阿里面試真題:談談Java類文件結構
    一 概述在 Java 中,JVM 可以理解的代碼就叫做字節碼(即擴展名為 .class 的文件),它不面向任何特定的處理器,只面向虛擬機。
  • 【都給你總結好了!】你必須掌握的 21 個 Java 核心技術!
    我在面試有超過3年Java經驗的開發者的時候, JVM幾乎就是一個必問的問題了。當然JVM不是唯一決定技術能力好壞的面試問題,但是可以佐證java開發能力的高低。集合框架這個是一個需要多加掌握的部分,做java開發,可以說沒有不用到集合框架的,這很重要,這裡整理的Java集合面試題及答案你必須都要清楚。
  • java面試——SpringMVC面試題集錦
    →[設為星標⭐]♪ 點擊上方綠標 收聽java面試——SpringMVC面試題集錦1、講下SpringMvc的核心入口類是什麼,Struts1,Struts2的分別是什麼SpringMvc覺得本文對你有幫助?請分享給更多人關注「全棧開發者社區」加星標,提升全棧技能本公眾號會不定期給大家發福利,包括送書、學習資源等,敬請期待吧!
  • 【Android工程師面試必考】NDK與遊戲開發面試題 不看後悔!
    Android開發工程師面試時必然會遇到筆試的環節,極客學院為大家嘔心瀝血整理了Android開發工程師的經典筆試題目!
  • 你有真正理解 Java 的類加載機制嗎?| 原力計劃
    點進文章的盆友不如先來做一道非常常見的面試題,如果你能做出來,可能你早已掌握並理解了Java的類加載機制,若結果出乎你的意料,那就很有必要來了解了解Java的類加載機制了。其實上面程序並不是關鍵,可能真的難不倒各位,不妨做下面一道面試題可好?如果下面這道面試題都做對了,那沒錯了,這篇文章你就不用看了,真的。
  • Java面試常被問到的題目+解答
    第二,staticnestedclass和innerclass的不同,說得越多越好(面試題有的很籠統)。static nested class 指靜態嵌套類,或稱嵌套類,是C++中常用的說法,inner class指內部類,是JAVA中的說法。內部類是一個類內部類的統稱,具體分為四種:成員類,靜態成員類,局部類,匿名類。其中匿名類是局部類的特殊情況。