我在7月底暫停了Android模擬面試(模擬面試:一天一面)砾省,有幾個原因:
- 面試者的群體和我預(yù)估的不大一樣,我的面試側(cè)重點和套路需要改進(jìn);
- 有點乏了,需要休息一段時間(每天堅持在一個時間段出現(xiàn)也是個體力活)腐泻;
- 需要反省和學(xué)習(xí)一下別的面試官的方式;
正好在這個時間段有一些知名公司要在成都建研發(fā)中心队询,我計劃去面試幾家派桩。合適的話也是一個機(jī)會,如果恰巧能找到一個適合自己發(fā)揮的平臺也是極好的蚌斩。再說這段時間老面試別人铆惑,也該讓自己也體驗一下作為面試者的心態(tài)和感受了。
所以送膳,這一篇的面試題和大家談?wù)勎疑现苊嬖嚸缊F(tuán)被問到的Java基礎(chǔ)題鸭津。
面試題:說說Java的內(nèi)存模型
說實話,把我問的有點“蒙”肠缨,確實知道一二,但在工作中很少總結(jié)這個方面盏阶,以前也專門看過晒奕,但那又是太遙遠(yuǎn)的事情了。硬著頭皮把一些想法和記憶說了出來名斟。
有讀者會納悶了脑慧,這樣的題都能“嚇蒙”你?
面試官不一定是最好的面試者砰盐,就像教練不一定非要是世界冠軍闷袒。
面試官的套路和我預(yù)想的不一樣,沒有關(guān)注項目經(jīng)驗岩梳、管理和架構(gòu)設(shè)計囊骤,上來就Java基礎(chǔ)到Androd基礎(chǔ)晃择,而且極其細(xì)致。
Java的內(nèi)存模型
Java開發(fā)人員并不需要像C/C++開發(fā)人員也物,需要時刻注意內(nèi)存的分配和釋放宫屠,而是全權(quán)交給虛擬機(jī)(JVM)去管理,自然關(guān)于內(nèi)存管理或是內(nèi)存的模型滑蚯、結(jié)構(gòu)對Java開發(fā)來說就是一個“黑箱”浪蹂。
兩眼一抹黑似乎也不影響寫Java的代碼。但我也說過告材,了解一些內(nèi)部的機(jī)制或者是自己認(rèn)為不重要的東西坤次,也許會很有幫助。
最簡單的斥赋,我們也應(yīng)該了解Java的堆和棧缰猴。而我們所謂的內(nèi)存管理,基本上指對堆內(nèi)存的管理灿渴,那堆內(nèi)存在JVM的內(nèi)存結(jié)構(gòu)中的那個位置呢洛波?
什么是JVM內(nèi)存
Java源代碼文件(.java)會被Java編譯器編譯為字節(jié)碼文件(.class),然后由JVM中的類加載器加載各個類的字節(jié)碼文件骚露,加載完畢之后蹬挤,交由JVM執(zhí)行引擎執(zhí)行。
JVM在執(zhí)行Java程序的過程中會把它所管理的內(nèi)存劃分為若干個不同的數(shù)據(jù)區(qū)域棘幸。
JVM會用一段空間來存儲程序執(zhí)行期間需要用到的數(shù)據(jù)和相關(guān)信息焰扳,這段空間一般被稱作為Runtime Data Area(運行時數(shù)據(jù)區(qū)),也就是我們常說的JVM內(nèi)存误续。
了解清楚JVM的內(nèi)存結(jié)構(gòu)會更有助于我們理解Java的內(nèi)存模型吨悍。
我們可以把上圖的“運行時數(shù)據(jù)區(qū)”分為線程私有和共享數(shù)據(jù)區(qū)兩大類。其中線程私有的數(shù)據(jù)區(qū)包含程序計數(shù)器蹋嵌、虛擬機(jī)棧育瓜、本地方法區(qū),所有線程共享的數(shù)據(jù)區(qū)包含Java堆栽烂、方法區(qū)躏仇,在方法區(qū)內(nèi)有一個常量池。
程序計數(shù)器(PC Register)
記錄正在執(zhí)行的虛擬機(jī)字節(jié)碼的地址腺办。和計算機(jī)組成原理中提到的程序計數(shù)器PC概念類似焰手,是線程私有的,用來記錄當(dāng)前執(zhí)行的字節(jié)碼位置怀喉。虛擬機(jī)棧(JVM Stack)
也就是我們常常所說的棧书妻。
方法執(zhí)行的內(nèi)存區(qū),每個方法執(zhí)行時會在虛擬機(jī)棧中創(chuàng)建棧幀躬拢。虛擬機(jī)棧的生命周期與線程相同躲履,每個方法(不包含native方法)執(zhí)行的同時都會創(chuàng)建一個棧幀結(jié)構(gòu)见间,方法執(zhí)行過程,對應(yīng)著虛擬機(jī)棧的入棧到出棧的過程崇呵。
本地方法棧(Native Method Stack)
本地方法棧則為虛擬機(jī)使用到的Native方法提供內(nèi)存空間缤剧。Java堆(Heap)
Java堆一般是JVM管理的內(nèi)存中最大的一塊,堆在主內(nèi)存中域慷,是被所有線程共享的一塊內(nèi)存區(qū)域荒辕,其隨著JVM的創(chuàng)建而創(chuàng)建,是用來存儲對象本身的以及數(shù)組犹褒,同時JAVA堆也是GC管理的主要區(qū)域抵窒。方法區(qū)(Method Area)
主要存放的是已被虛擬機(jī)加載的類信息、常量叠骑、靜態(tài)變量李皇、編譯器編譯后的代碼等數(shù)據(jù)。常量池(Runtime Constant Pool)
存放編譯器生成的各種字面量和符號引用宙枷,是方法區(qū)的一部分掉房。
內(nèi)存模型
Java內(nèi)存模型即Java Memory Model,簡稱JMM慰丛。JMM定義了Java 虛擬機(jī)(JVM)在計算機(jī)內(nèi)存(RAM)中的工作方式卓囚。Java線程之間的通信由JMM控制,JMM決定一個線程對共享變量的寫入何時對另一個線程可見诅病。
從抽象的角度來看哪亿,JMM定義了線程和主內(nèi)存之間的抽象關(guān)系:線程之間的共享變量存儲在主內(nèi)存(上面提到的Java堆內(nèi)存)中,每個線程都有一個私有的本地內(nèi)存贤笆,本地內(nèi)存中存儲了該線程以讀/寫共享變量的副本蝇棉。
在命令式編程中,線程之間的通信機(jī)制有兩種:共享內(nèi)存和消息傳遞芥永。
Java內(nèi)存模型與上面提到的JVM運行時數(shù)據(jù)區(qū)(JVM Runtime Data Areas)兩個概念容易混淆篡殷。JVM 運行時數(shù)據(jù)區(qū)定義了JVM運行期內(nèi)存的管理劃分,而Java內(nèi)存模型定義了程序中各個共享變量的訪問規(guī)則埋涧。
自己的面試總結(jié)
關(guān)于Java的內(nèi)存模型贴唇,我覺得對于Android應(yīng)用開發(fā)比較有益的就是:更容易理解線程安全和并發(fā)編程的問題。而后面面試官確實也問到了線程安全飞袋,可能這也是一個組合套路吧。
面試完后链患,雖然有很多題答得都不是很理想巧鸭,不過對于我這樣的“過來人”來說,很清楚面試時你回答的內(nèi)容并不是最重要的(大多數(shù)時候)麻捻。重要的是什么纲仍?看完這個系列的讀者應(yīng)該心里有數(shù)呀袱。
附上自己的面試總結(jié):
Java部分準(zhǔn)備不充分。
在面試前我對這個職位的信息收集并不充分郑叠,我的側(cè)重點在Android的項目框架和技術(shù)管理上夜赵。但美團(tuán)一面的面試官視乎是比較重基礎(chǔ)知識,而且每個點都問得比較仔細(xì)乡革。沒有問面試官的姓名寇僧。
下來都不好和面試官做朋友,不是嗎沸版?萬一以后是同事嘁傀,還不知道對方是誰也有點尷尬。以前有過视粮,和一個同事處了一段時間了细办,他才告訴我之前是他面的我。表達(dá)了一些負(fù)面信息蕾殴。
解釋了一些不足的地方笑撞,個人一直不喜歡“強(qiáng)調(diào)”負(fù)面信息,在我的一些表達(dá)中钓觉,還是不自覺的先抑后揚了茴肥,不過好在面試官視乎不太在意。
“標(biāo)準(zhǔn)答案”
標(biāo)準(zhǔn)答案為何打引號议谷,請關(guān)注Android面試一天一題(Day 43:設(shè)計模式)的說明炉爆。
面試題:Java的內(nèi)存模型
標(biāo)準(zhǔn)答案:Java內(nèi)存模型即Java Memory Model,簡稱JMM卧晓。JMM定義了Java 虛擬機(jī)(JVM)在計算機(jī)內(nèi)存(RAM)中的工作方式芬首。程序中的變量存儲在主內(nèi)存中,每個線程擁有自己的工作內(nèi)存并存放變量的拷貝逼裆,線程讀寫自己的工作內(nèi)存郁稍,通過主內(nèi)存進(jìn)行變量的交互。JMM就是規(guī)定了工作內(nèi)存和主內(nèi)存之間變量訪問的細(xì)節(jié)胜宇,通過保障原子性耀怜、有序性、可見性來實現(xiàn)線程的有效協(xié)同和數(shù)據(jù)的安全桐愉。
面試題:JVM如何判斷一個對象實例是否應(yīng)該被回收财破?
標(biāo)準(zhǔn)答案: 垃圾回收器會建立有向圖的方式進(jìn)行內(nèi)存管理,通過GC Roots來往下遍歷从诲,當(dāng)發(fā)現(xiàn)有對象處于不可達(dá)狀態(tài)的時候左痢,就會對其標(biāo)記為不可達(dá),以便于后續(xù)的GC回收。
面試題:說說JVM的垃圾回收策略俊性。
標(biāo)準(zhǔn)答案: JVM采用分代垃圾回收略步。在JVM的內(nèi)存空間中把堆空間分為年老代和年輕代。將大量創(chuàng)建了沒多久就會消亡的對象存儲在年輕代定页,而年老代中存放生命周期長久的實例對象趟薄。
相關(guān)面試題:
Android面試一天一題(Day 37:一套高級工程師的面試題)