在面試中如何展示虛擬機器和記憶體調優技能
最近看到我的博文裡,最近面試java後端開發的感受:如果就以平時專案經驗來面試,通過估計很難——再論面試前的準備 ,這篇博文,推薦數最多,77推薦0反對,所以能看出面試類文章還是非常受歡迎的。而且,在這個寒冬中,我們更得不斷提升自己的能力,所以這次,我就針對上述博文中的“虛擬機器描述”這個點擴展出去,具體講些在面試中展示虛擬機器記憶體調優能力的話術。
在面試中展示出這個技能有什麼好處?初學者或初級程式設計師在面試時如果能證明自己具有這方面的能力,這相當有利,因為這是針對5年左右相關經驗的高階程式設計師的要求。如果在面試時面試官主動問及這方面的問題,大家可以按照如下的思路由淺入深地依次闡述,如果沒問,大家也可以用到下面提及的方法毫無痕跡地(不突兀不顯擺)展示自己這方面的能力。
1從虛擬機器體系結構引出記憶體管理的話題
如果面試官有直接問,“你是否瞭解虛擬機器體系結構”,那麼大家可以先畫出虛擬機器的各部件,隨後依次說明各部分的作用。
其實面試官也知道這部分對專案開發的幫助並不大,所以大家不用過於深入,比如可以不用深入回答.class位元組碼檔案的結構和類載入器的流程。但大家一定得總結性地說出靜態資料、基本資料型別和引用等資料的儲存位置,這部分的內容在博文裡和我的書裡講過。這樣就能引出後面的關於“記憶體”的話題。
如果面試官沒有問及虛擬機器體系結構的問題,那麼也不要緊,畢竟這塊知識點實用性一般,說出來屬於錦上添花。但大家應當通過後文部分給出的方法,找機會引出“記憶體“這個話題。
2 如何自然地引出記憶體管理的話題
一般來說,大多數面試官會問垃圾回收的流程,這樣大家就有機會通過堆結構說出垃圾回收的流程,進而展示自己記憶體調優方面的能力。
或者大家可以更保險點,在簡歷的最近專案介紹里加上類似這樣描述,“這個專案的記憶體要求比較高,雖然在專案裡分配的物件不少,但這個專案只被分配了1G記憶體,所以在這個專案裡,我實踐了一些定位排查記憶體問題的技能,也做了些調優的工作“,這樣面試官見到簡歷的描述,就會自然而然地提問了。
更穩妥的方法是,在面試中總會有“專案介紹”這個環節,面試官會讓候選人介紹最近的(或最拿得出手)的一個專案,這樣大家就可以順勢說出剛才已經給出的描述。
或者,大家可以在回答資料庫或集合等方面的問題時引出這個話題,比如回答完JDBC問題後,大家可以說一句,“用好的Connection物件我們會及時關閉,否則它所佔用的記憶體物件無法被GC回收”,或者在談及List等集合型別時,同時多說一句,“用好的集合物件我們會及時clear掉,否則這個集合也會對一些物件產生強引用,這樣就會延遲物件的回收時間”。
總之,記憶體調優這方面的能力不說出來未免有些可惜,大家可以根據上述的描述舉一反三,在面試中找一切可以的機會引入這個話題。
不過這裡也請大家注意些技巧,別自說自話地一股腦地全說,這樣反而過猶不及。打個非常不恰當的比方,就像釣魚,大家可以先下個餌,比如在介紹專案時先粗略地提到自己做過這方面的事情,但先別說具體的,等面試官主動問了,再具體地按下文給出的思路一一展開。
萬一面試官在大家的再三暗示下還是沒介面繼續問(雖然這種可能性非常小),那說明面試官真的對此沒興趣,或者說你應聘的公司對此沒需求,那麼大家就只能此打住了。
3 根據堆區結構,闡述垃圾回收的流程
在找到合適的機會後,大家可以先從堆的結構入手,進而詳細說明垃圾回收的流程。比如大家被問到,你對Java中的垃圾回收機制瞭解多少?或者當你說出在專案裡你做過記憶體調優,面試官進一步讓你說出細節,那麼大家可以按次序說出如下的要點。
1 可以先說下,new出來的物件都放在堆區裡。
2 可以說下堆的結構,比如堆裡分年輕區,年老區和持久區,年輕區裡還分伊甸區和兩個緩衝區,持久區主要存放的是Java類資訊或在程式碼裡通過import引入的類資訊,垃圾回收流程主要涉及到的是年輕和年老區。
3 可以說下垃圾回收的一般流程,比如什麼時候會觸發輕量級回收,什麼時候會觸發Full GC。
4 可以說下虛擬機器是憑什麼判斷物件可以被回收(物件上沒有強引用,則會在下次GC流程時被回收),也可以說下“引用計數法”和“根搜尋演算法”以及它們的差別。
5 可以說下,程式設計師可以通過System.gc()來啟動Full GC,但Full GC並不是在呼叫和這個方法後就啟動。不過根據實踐,兩者的時間間隔不會太長。
在說完上述要點後,大家最後一定得引出下一個“記憶體調優”這個話題,比如可以說,“雖然說Java虛擬機器能自動回收記憶體,但在平時寫程式碼時,我們會遵循一些要點來提升記憶體效能,在專案裡,我們還會監控記憶體使用量,而且我在專案裡也有過排查OOM問題的經驗“。這樣的話就能進一步展示自己的“調優和排查”能力。
4 再進一步說明如何寫出高效能的程式碼
這裡來總結一下要點,在面試時,大家可以在閱讀 Java核心技術及面試指南 中的 相關內容,在此基礎上自行展開敘述。
1 物理物件(比如Connectio或IO)用好之後得及時close。
2 大的物件用好後應當及時設定成null,以撤銷強引用。
3 集合物件用好後應當及時clear。
4 儘量別頻繁地使用String(或其它不變類)物件,這樣容易產生記憶體碎片。
5 儘可能地使用軟和弱引用,因為這樣能提早物件的被回收時間。
6 不建議重寫finalize方法。
7 可以通過調整命令列引數來調整堆記憶體的效能,但同時請注意,在專案裡一般只會修改-Xms或-Xmx引數,或者再加一些日誌列印和儲存Dump檔案的引數。在修改其它引數時,專案組一般會很慎重,所以大家可以說自己瞭解其它的引數,但如果沒有十足的把握,別說自己在專案裡調整過類似於“設定年輕區與年老區的比值”等容易產生記憶體問題的引數。
解決問題相對容易,但定位問題就相對難了,所以建議大家可以再進一步展示自己“監控、定位和調優”方面的能力,比如可以通過如下的敘述引入到這個話題,“除了這些程式碼上的技巧外,我們在專案上線後還必須監控記憶體使用量,一旦發生OOM或Stop The World等問題,我們得通過一定的方法來定位問題點,從而再用剛才提到的技巧來優化記憶體”。
5 最後展示監控、定位和調優方面的綜合能力
在面試時,面試官是沒法當場給出一個實際的問題讓大家來現場解決,只要候選人敘述得不離譜,一些要點能說上來,一般就會認為候選人具備這方面的能力。
這塊大家說下,比如通過JConsole確認有記憶體問題,通過MAT檔案Dump檔案來檢視OOM的現場,從而再通過GC日誌和程式碼裡輸出的記憶體使用量來定位問題點。在面試前,建議大家多看一些GC日誌檔案和Dump檔案,這樣在敘述時就更會胸有成竹了。
而且,可以準備一兩個通過MAT等工具排查解決實際OOM的案例,這樣說服力就更強了。
通過閱讀這部分的內容,大家一定能體會到,“記憶體監控、定位和調優”方面的能力並不難學,也不難準備面試中的說辭,而且在面試中,最多用上五分鐘就能把這部分的知識點說全,但大家一旦按上述思路展示出了這方面能力,那麼很大程度能改變面試官對你的評價。
根據我們的面試經驗,初級程式設計師的平均能力其實差不了多少,在很多時候我們是無法取捨的。比如我們要從10個人裡招5個人進來,除去特別好的(一般2個)和特別差的(一般也是2個),有6個人的綜合能力(包括學校背景工作背景專案經驗和麵試結果)是差不多的,也就是說我們很難從這6個人裡挑選出3個人。
這時,如果這6人中誰有類似於記憶體調優(或者之前提到的設計模式)等方面的加分項,那麼就一定會優先考慮這個人,這就是本文給大家的幫助。
6 總結,求推薦
在本人寫的 Java Web輕量級開發面試教程 和 Java核心技術及面試指南 這兩本書裡,有不少類似本文的話術,此外我們也知道,靠話術無法從本質上提升自己的能力,所以在這兩本書裡,更多的是對Java核心技術和Web框架技術的歸納。
本文是從諸多面試案例中歸納而來,所以自認為多少對大家有所幫助。而且年末清閒,正是知識進補的大好時光。
這裡首先預祝各位讀完本文的勤奮的讀者技術不斷提升,再祝福各位都身體健康(我深有體會,身體好什麼都好)。最後再次感謝大家讀完本文。
關於轉載有如下的說明。
1 本文可轉載,無需告知,轉載時請用連結 的方式,給出原文出處,別簡單地通過文字方式給出,同時寫明原作者是hsm_computer。
2 在轉載時,請原文轉載 ,如要在轉載修改本文,請事先告知,謝絕在轉載時通過修改本文達到有利於轉載者的目的。