如何準備Java面試?如何把面試官的提問引導到自己準備好的範圍內?
Java能力和麵試能力,這是兩個方面的技能,可以這樣說,如果不準備,一些大神或許也能通過面試,但能力和工資有可能被低估。再仔細分析下原因,面試中問的問題,雖然在職位介紹裡已經給出了範圍,但針對每個點,面試官的問題是隨機想的,甚至同一個面試官在兩場相似的面試裡,提的問題也未必一樣。
也就是說,如果讓面試官自由提問,那麼一旦問到你不熟悉的點,你可能就答不上,如果運氣不好,再外加上不知道面試引導技巧等因素,真有可能面試官的提問全落在你不熟悉的範圍內,這樣就非常可惜了。與其這樣,還不如事先準備外帶面試引導,這樣或許你的能力未必行,但你可以儘可能地通過引導展示你的亮點,從而提升面試通過的可能性。在本文裡,就將講述事先準備java亮點和麵試中引導面試官提問的技巧。
1 根據職位介紹微調簡歷,這關係到能否有面試機會
雖然這點和本文的主題無關,但如果沒有面試機會,那甚至無法展示引導技能,所以還是來囉嗦一下。篩選簡歷的人,除了會看學歷專業等硬條件外,更會看相關經驗的商業專案經驗,這在職位介紹上一定能體現出來,比如初級開發,一般需要SSM等框架的1年經驗,高階開發一般需要3年,再外帶些諸如Netty,資料庫調優等方面的技能。
如果看到一份簡歷上,沒有明顯的相關商業專案經驗(學習專案不算),那麼這份簡歷甚至沒面試機會,這就是為什麼很多初級開發簡歷大多石沉大海的原因。其實職位介紹上提到的技能,甚至很多初級開發應該也有專案經驗,但這些人就不寫清楚,這可能只能怪自己了。這塊給出的經驗如下。
1 簡歷上多積累商業專案經驗,而且裡面用到的技術儘可能是Java的,如果你可以湊出半年商業專案經驗,那絕別寫5個月。如果是畢業生缺乏商業專案經驗,也得多找些學習專案寫到簡歷上,至於幫老師乾的專案以及實習專案,那當商業專案寫。
2 一般職位介紹裡,大多提到SSM,Oracle等技術,這些技術在你的專案裡,至少應該用過其它類似吧,那麼別客氣,這些技術關鍵字儘可能地出現在你簡歷中的專案介紹裡,比如人家要有Oracle經驗,你哪怕是有MySQL,也寫上,不寫就說明你沒資料庫開發經驗,寫了就算有相關經驗,類似技術點也照此辦理。
3 每份工作的技術要求一定不同,那麼你在投簡歷前,一定得微調,在你專案裡做過的前提下,儘可能在你這份簡歷中,體現出相關技術。
一般對出初級開發,如果沒至少半年Java(可能再具體下是SSM等框架)商業專案經驗,而且簡歷裡看不到職位介紹裡出現的資料庫,框架等技能關鍵字,這份簡歷基本沒機會,高階開發一般是要3年相關經驗。
這裡不提倡編專案,也不提倡編技術,即你專案裡沒用到的技術你寫到簡歷中,但話說回來,一般公司要求的技術都很普通,你在專案裡哪怕沒做過,好歹同事有人做過,你可以看下相關程式碼,或者你參與過除錯此類問題。所以哪怕是初級開發,你的技能應該能對上大多數職位介紹,如果對不上就學,也應該很快能對上,只要你的簡歷上有足夠的java商業專案經驗,而且出現大多數技術關鍵字,至少能有面試機會。
2 結合專案和線上問題,優先準備分散式元件的亮點
面試一般從介紹專案開始,在我的如何在面試中介紹自己的專案經驗這篇博文裡,給出了相關內容,但本文的主題是事先準備外帶面試時引導,那麼在面試前,該如何準備亮點呢?先從最值錢的分散式元件亮點準備起。
比如可以準備通過看日誌,解決過redis,dubbo等方面的線上問題。這塊其實連初級開發也有機會接觸,比如Dubbo方面,超時時間沒設好,比如設了10秒,平時沒事,但一旦訂單模組調風控模組出錯,過了10秒再返回出錯,這樣導致整條(基於http的)鏈路長時間保持,累計起來就導致資源耗盡最終系統崩潰,或者redis超時時間沒設或設定很長(1個星期),導致redis的內容在記憶體中快取過多,導致OOM問題。這些問題,哪怕是初級開發,應該也有機會接觸。
這方面該怎麼準備? 1 簡歷上寫上在專案裡用過Redis或Dubbo元件,並排查過類似問題 2 看些基本的redis和dubbo介面方法 3 尤其看些可能導致問題點的配置,比如超時時間怎麼設 4 複習下linux命令,瞭解如何通過linux命令看日誌排查問題。
上述是最基本的,如果有MyCAT,Netty,Kafka方面的經驗,比如Mycat分庫欄位怎麼設,解決過Netty半包和粘包問題,Kakfa解決過因訊息重發而導致的不冪等問題,你都可以寫到簡歷上作為亮點。但本文給出的保本技能亮點,比如redis和dubbo超時而導致的問題排查,應該大家都有機會接觸。
3 別光背題,要結合專案講,最好結合你解決過的線上問題講
網上有不少分散式(以及其它方面)的面試題,比如netty或dubbo底層細節問題,這些有用,但如果你背熟了,面試裡最多得到的評價是“瞭解分散式元件理論”,聊勝於無,如果對於要有分散式元件經驗的工作,你就懸了。對於分散式元件,大家實現該如何準備呢?(其實後文提到的亮點也一樣)
1 一定要應用在專案裡,因為面試官只關心對應的商業專案經驗,比如你的dubbo是用在訂單系統調會員系統方法裡,你的mycat,netty等是用在什麼場景,這點簡歷上未必能體現出,但面試時一定要說,這樣能證明你用過。
2 分析問題的能力優於開發能力,所以你最好再結合一個場景說明,比如在專案介紹時,你外帶一句,dubbo方面我解決過因超時而導致的問題,然後等面試官來問,問的時候,你大致說下,然後面試官看你對linux看日誌的命令,以及dubbo關於超時時間的配置以及問題上下文說得沒毛病,那麼應該也就信了。
3 這時可以再結合一些面試題準備下細節,比如看netty堆外記憶體,執行緒模型,redis資料結構。有些面試官聽你說出解決問題的說辭,可能就不問了,有些可能會再問些底層問題,那麼你這時候再說下。
這裡大家可以對比下兩種表現方式,一種是什麼也不準備,或者只准備背網上的題目局,等面試官問,那麼面試官一定不客氣,想到哪問哪,比如netty會問很細,你平時的專案經驗未必涵蓋到,如果你再無法結合應用講清楚,那面試官可能認為你只有理論經驗。另一種是專案介紹時丟擲,而且找機會通過解決過的實際問題丟擲,外帶稍微瞭解下細節,這樣不僅能很容易讓面試官感覺你有實際專案經驗,更能展示“看日誌解決實際問題”的能力。兩者差別一看就知道,更何況其實只要方法得到,準備其實也不難。
4 準備資料庫調優和虛擬機器調優及排查oom問題的說辭
按值錢的技能排序,對於一般的初級和高階開發而言,除了分散式元件,下面就是調優方面的能力了,具體可以是分散式調優,這之前講過, 還有資料庫調優和虛擬機器調優。同樣除了在簡歷上明寫之外,還該做哪些準備呢?
資料庫跳調優方面。
1 熟悉索引,包括索引結構,複合索引和回表,這塊應該大家都會說,同樣要結合專案案例說。
2 單機版,通過看執行計劃,調優SQL語句,這塊怎麼準備?專案中,會在linux上設定,如果有超過10秒的SQL就打印出來,然後通過執行計劃看耗時點,比如大多是走全表掃描,或者有了索引沒用到,或者子sql運行了多次,再往深講就是Oracle裡連線方式不對。你通過執行計劃看到問題所在後,就對應修改,比如建複合索引,或者通過with語句把子查詢提取出來。
總之這裡你得體現出通過日誌看長sql,以及通過執行計劃看耗時點。至於如何修改,大多數候選人都能說,但你更知道前兩點, 就比別人強了。
3 如果你感覺還有能力,可以再講些MyCAT分庫分表和redis方面的調優能力,畢竟這塊涉及到分散式元件。這方面可以準備的專案說辭是:比如業務請求裡,會經常用公司ID向風控模組看風險情況,那麼就可以用ID做鍵,風控欄位做值,另外再把null放到鍵裡,以放快取擊穿。另外對於一個千萬級別的大表,你可以用ID作為分表字段,分10個表,根據最後一位的值定位到具體的表。同時排查所有的SQL語句,把一些可能全表關聯的SQL語句,比如帶group by和多表關聯,或者用Java業務寫,或者優化。同時再網上看些面試題準備些相關MyCAT和Redis的語法說辭。這樣你會額外增加“分散式效能調優”方面的經驗。
在虛擬機器方面,我另外有篇博文:在面試中如何展示虛擬機器和記憶體調優技能,大家可以照著準備,總之也是先結合專案展開,然後圍繞虛擬機器結構展開調優技能,再可以照這篇文章內部類、final與垃圾回收,面試時你一說,面試官就知道,進一步展示你的能力,同時再能照如下的範例,說出你解決過的OOM問題。
第一步,發現系統很卡,或者日誌裡頻繁出現OOM異常。第二步,用dump檔案看OOM時的記憶體映象,看的工具可以是JMAT。這兩個步驟是通用的。
第三,通過dump檔案,再結合日誌上下文,發現了OOM的原因,比較簡單的原因是Redis快取超時時間過長,或者是ThreadLocal裡的物件用好沒remove(這塊還涉及到弱引用,大家可以自己去查,本文不展開),或者建立執行緒池時,等待佇列設定成了無界,或者你在mybatis裡,where條件都是帶if的,即如果傳入id和name再拼裝where id = xxx之類的語句,在一種場景裡,都沒傳條件,所以where後面不帶條件,把資料庫裡記錄全撈出來了,導致OOM。
如果你再經歷過,甚至可以說到Netty堆外記憶體管理不善而導致的問題,如果能說到這個程度,甚至面試架構師都行。
第四是解決,發現問題後,對症下藥解決就很容易,比如降低Redis超時時間,或者修改好對應的程式碼。但既然你說是根據線上問題排查出來的,那麼就得說如何解決,善始善終。總之這裡是結合線上問題發現的,所以就別說些因Connection物件沒關閉,大的HashMap用好沒clear之類的問題了,倒不是這些原因不會引發OOM問題,而是這些問題大多會在上線前測試階段解決掉了,你再把它們說成線上問題,可能會暴露你們專案組能力不行。
5 java核心方面,準備集合,執行緒和異常處理等方面的亮點
通過上述分散式元件和調優方面的說辭,你展示的能力已經比別人強很多了,雖然相比之下,java核心方面的能力屬於單機版的技能,但畢竟屬於基礎技能,你除了基本問題之外,也得適當準備亮點。如下給出些同樣適用於初級開發的亮點。
1 集合方面,可以準備下HashMap和hashcode的底層程式碼,同樣可以準備下ArrayList和快速失效(fast fail)的底層程式碼,然後再進一步看下ConcurrentHashMap的讀寫併發管理部分的程式碼,因為其中包含volatile,散列表資料結構和執行緒併發部分的技能,而且jdk1.7和1.8 ConcurrentHashMap的底層程式碼實現起來還不同,你如果找到機會通過這個物件展示多執行緒併發和資料結構的能力,或許Java核心方面,面試官就不問別的問題了。
2 執行緒方面,準備下鎖,volatile,執行緒池和ThreadLocal的說辭,具體通過ConcurrentHashMap瞭解下鎖(1.7)版本和synchronized+volatile(1.8版本)的用法,以及ThreadLocal裡可能引發記憶體洩漏的問題,這些點網上都有,本文就不展開了,其實也未必多,能講清楚就行了。
3 異常方面,準備下你在專案裡的異常處理方法實踐說辭,比如儘量縮小try...catch的範圍,finally從句裡放釋放資源的程式碼,catch裡應儘量處理異常,先用IOException等專業異常處理,再用Exception兜底,以及儘量縮小異常的影響範圍,別讓程式一遇異常就崩。
Java核心方面,其實還有很多可以挖掘的點,比如String, final關鍵字等,而且Java核心方面,網上面試題太多了,這裡就不再展開了。同樣這裡要結合專案案例,比如在測試階段發現了因為遍歷集合而導致的問題,同時展開快速失效,或者在壓測階段發現因HashMap在高併發場景下丟資料所以用ConcurrentHashMap,同時展示其中的volatile和併發等細節。
其實上述技能不復雜,初級開發照樣能說,但涉及到了底層程式碼,尤其ThreadLocal還涉及到弱引用和OOM問題,更能體現實力,哪怕你經驗未必比人家多,但你面試時能結合底層程式碼展示,想都不用想,面試官一定看好你。
6 介紹專案時,丟擲準備過的亮點,別展開
上文裡給出的是面試準備的技巧,按值錢角度分析,講了分散式元件、資料庫和JVM調優以及Java核心方面的技能,更重要的是,你是結合實際專案準備的。
臺上一分鐘臺下一年功,如果準備得當,面試時你就可以發揮了。先是在自我介紹環節,你除了介紹基本情況學校學歷外,還可以綜合說明,比如用過Redis元件,有過資料庫和JVM調優經驗,有過壓測經驗(下文會講),有過排查OOM方面問題的經驗等,總之別客氣,準備了就說。
然後進入到專案介紹環節,除了介紹專案背景,開發情況以外,你再結合業務說,這裡給出若干說辭範例。
1 這個專案裡,我們用到了Dubbo作為模組間的呼叫,我除了寫程式碼外,還解決過因dubbo超時也引發的問題(別展開)
2 在資料庫方面,我除了實現技能外,還做了資料庫調優,具體用過索引,執行計劃,redis快取和MyCAT分庫分表,最後兩點自己斟酌。
3 在專案裡,每個請求我們會用一個執行緒處理,其中用到了ThreadLocal物件(結合業務引出ThreadLocal),對此我還解決過因ThreadLocal和執行緒池設定不當而引發的OOM問題。同時這裡可以丟擲準備過的其它OOM問題說辭。
4 在這個專案裡,我參與過壓測,並在壓測過程中解決過 OOM問題,並通過看日誌優化程式碼,從而改善了系統的響應時間。
5 在這個專案裡,我會結合Cat系統監控長SQL問題,一旦出現,我會通過看Linux日誌排查問題。(展示看日誌排查問題的能力,同時可以進一步展示你準備過的技能)。
大家可以看到,上述結合專案丟擲的亮點時沒有展開,因為這時屬於專案介紹階段,如果展開的話可能會讓面試官感覺你條理不清晰,而且丟擲的亮點都是屬於分散式和調優等高階技能。對一些Java核心方面的單機版技能,別人或許當成寶,你可能都掌握的值錢技能太多,都不算什麼了。當然,後面有機會,你還是要展示Java核心部分的亮點,只是優先講更值錢的。
7 回答技術問題後,可以引導到你準備過的亮點上
你介紹專案時,由於已經丟擲了足夠多的亮點,所以後面面試官自然而然就會往這方面提問,這樣就達到了引導效果。比如聽你講到Redis快取,自然就會問了, 問題無非是怎麼用?這你可以結合你的專案實際說,底層細節,這塊網上資料太多。也就是說,通過專案介紹,你可以把面試官引導你準備好的話題上,這還不算,在回答問題的時候,你照樣還能引導,如下給出些引導的技巧。
1 比如你在回答redis相關問題時,如果之前你沒機會講“排查因超時時間過長而引發的OOM問題”,那麼還可以展開說,對redis,我還解決過xx問題,面試官自然會問了,然後再展開。
2 當你回答好redis問題後,可以再“順口”說句,在我們專案裡,除了redis外,還用過dubbo元件,結果過因dubbo超時時間過長而導致的問題。然後面試官自然就會問到這塊了,你同樣可以準備些dubbo底層細節的問題,這方面也很多資料。
3 在回答好任何資料庫相關的問題,比如索引,JDBC等,你順口說句,我在專案裡,還通過執行計劃(或Mycat)優化過SQL技能,然後然開。
4 在回答好任何集合(如ArrayList)方面問題時,你可以說,在遍歷集合的時候,我們專案裡會非常小心快速失效問題,然後展開。
5 在回答好任何執行緒記憶體模型,或被問到volatile相關問題時,你就說,我知道ConcurrentHashMap裡用到volatile,我能具體說下嗎?再結合這個物件,擴充套件到 執行緒併發話題,而且這還是結合底層程式碼講的。
6 被問到任何異常處理問題,比如執行期異常,如何自定義異常,那麼再引導到異常處理最佳實踐。
7 從ThreadLocal,引出底層的Weak引用話題,再引出JVM結構以及OOM調優方面的話題。
寫到這裡我都懶得再寫了,在上文裡,我已經列出了很多亮點,它們兩兩橫向關聯,你說好一個再關聯另外一個,足以能全方面展示技能。但在擴充套件時你需要注意,萬一面試官沒接嘴問,你就要立即停止,或者另外找機會再引導,這時如果再說下去,就屬於自說自話了。而且儘量不露痕跡地引導,比如上文給出的範例中,引導的話術大多是,除了xx技術,我們專案裡還用到了xx(關聯性很強)技術,然後坐等面試官來問。
也就是說,遇到一些不大自主思考的面試官,你甚至可以通過事先準備外帶面試引導,控制面試全程節奏,哪怕是遇到一些大廠的面試官,你同樣可以據此把問題引導你熟悉的範圍,最多就再根據網上面試題再準備些(dubbo,執行緒模型等的)細節問題,畢竟人的思維方式的很相似的,聽到你“隨口”這樣一說,很有可能就“接茬”向下提問了。
8 更可以引導到壓測和排查線上問題經驗等的值錢話題
比起分散式實踐技能,更值錢的是壓測和排查線上問題和專案上線方面的經驗,這在面試時非常容易引導,也就是一兩句話的事,比如你隨口一說:“在這個專案裡我做過壓測,而且有過根據壓測結果調優系統的經驗 ”,或者說,在dubbo等方面,我排查過線上問題。自然前提是你要做過,等到面試官提問時,壓測方面你可以給出如下的說辭。
1 你參與全鏈路壓測,即相應的同學坐一起,用jmeter發請求,用zabbix監控cpu記憶體指標,同時看日誌監控問題。
2 壓測是用測試環境,當然你也可以說是線上環境,如果是線上環境的話,更要監控,一旦出現CPU等負載過高,立即終止。
3 比如用Jmeter發500個執行緒,每個執行緒起5個交易,這些交易用2秒做完,那麼每秒的壓力是1250。
4 最關鍵的是,你要根據壓測結果改善效能,比如通過壓測,發現了執行緒池設定引數時,把等待佇列設成了無界,或者有模組IO物件沒關,或者ArrayList沒clear,從而導致了OOM,或者發現高併發場景資料庫方面出現了長SQL,然後用執行計劃分析,再解決,或者發現了系統日誌本來是同步輸出的,從而導致效能瓶頸,最後改成非同步日誌。或者發現數據庫是瓶頸,所以再引入MyCAT和Redis
總之,壓測說辭方面,面試官更關注你分析問題和解決問題的經驗,至於發現和解決的問題,只要能說得過去就行了,況且你還能借此展示分散式和調優方面的技能。而排查線上問題方面的經驗,你可以用如下的步驟給出說辭。
1 如何發現?無非是通過CAT監控發現長SQL,或者通過Kibana等工具發現。或者可以說是先期業務埋點,發現交易異常時拋提示。
2 發現問題後你的態度,通過手機發現問題後,你第一時間看,哪怕不在你的範圍內,你第一時間上報。
3 如何排查問題:通過linux命令看日誌,或者通過dump看OOM的映象。
4 分析原因,藉此你可以展示上文給出的亮點技能,以及對應解決。
話說回來,哪怕是初級開發,也有資格參與壓測,平時也一定會遇到線上問題,你如果面試時不說,面試官自然不知道,但這塊你絕對是大有可為的。
9 總結:總是先找實踐機會再提升技能,程式設計師總該挑戰更高階的職位
總結下,本文的主題包括兩個,第一結合自身實際,面試前挖掘亮點,第二面試時通過引導,儘量把問題引向自己熟悉的範圍。實踐起來,技術要結合專案,而且最好再結合你排查和解決過的線上問題,同時回答好一個問題後,再把問題引向同類以及調優方面的話題。
比如Redis,當你結合專案,壓測和線上問題,講述基本用法和解決過的問題後,面試官可能再會問資料結構,高可用叢集和事務方面的問題,這些問題就可以事先準備了,而且話說出來,對於初級開發,你說好第一部分的說辭,哪怕細節問題沒回答上,面試官雖然無法給出“深入瞭解Redis細節”的評價,但至少能給出“在專案裡用過Redis和排查過Redis相關問題”的評價,如果你再結合專案,如本文所示,全面展示調優,Java核心等方面的技能,那麼你面試資深高階開發也夠了,面試初級開發真就綽綽有餘了,如果經驗再豐富些,再去面試小公司的職位,更有些委屈了。
當你按本文所述,準備好相應技能,然後再通過一些面試實踐變成麵霸後,很有可能你面臨的不是要面試什麼公司的問題,而是“面試通過後能不能適應更高階職位”的問題。不過總是先有實踐機會再提升,比如當你是初級開發時,從事第一份高階開發工作時一定很吃力,甚至還會看人臉色,但如果你不追求更高階的崗位,一直陷入低階職位的舒適區不可自拔時,你的競爭力也會逐月下降。
所以到了必要的時候,你總得根據本文給出到的建議,不斷挑戰更高階的職位。況且,本文在開篇時就提到,技術能力和麵試能力是兩個方面,而本文給出面試技巧,都是靠平時技能積累,本文給出的面試建議,能幫助大家更好地在面試中展示亮點。
希望本文不僅能幫到大家更好地挖掘自己專案經驗,更能幫到大家高效地找到自己心儀的工作,最後感謝大家看完長文,本文寫了有5個小時,如果大家感覺可以,請多多點贊,有問題也可以多寫評論。
版權說明:
如果要轉載本文,請先徵得本人同意。
&n