經過半年的沉澱,加上對MySQL,redis和分散式這塊的補齊,終於開始重拾面試信心,再次出征。
鵝廠
面試職位:go後端開發工程師,接受從Java轉語言
都知道鵝廠是cpp的主戰場,而以cpp為背景的工程師大都對os,network這塊要求特別高,不像是Java這種偏重業務層的語言,之前面試Java的公司側重還是在資料結構、網路、框架、資料庫和分散式。所以OS這塊吃的虧比較大
一面基礎技術面
電話面試,隨便問了些技術問題,最後還問了個LeetCode裡面medium級別的演算法題,偏簡單
- redis有沒有用過,常用的資料結構以及在業務中使用的場景,redis的hash怎麼實現的,rehash過程講一下和JavaHashMap的rehash有什麼區別?redis cluster有沒有了解過,怎麼做到高可用的?redis的持久化機制,為啥不能用redis做專門的持久化資料庫儲存?
- 了不瞭解tcp/udp,說下兩者的定義,tcp為什麼要三次握手和四次揮手?tcp怎麼保證有序傳輸的,講下tcp的快速重傳和擁塞機制,知不知道time_wait狀態,這個狀態出現在什麼地方,有什麼用?(參考quic)
- 知道udp是不可靠的傳輸,如果你來設計一個基於udp差不多可靠的演算法,怎麼設計?
- http與https有啥區別?說下https解決了什麼問題,怎麼解決的?說下https的握手過程。
- 看你專案裡面用了etcd,講解下etcd幹什麼用的,怎麼保證高可用和一致性?
- 既然你提到了raft演算法,講下raft演算法的基本流程?raft演算法裡面如果出現腦裂怎麼處理?有沒有了解過paxos和zookeeper的zab演算法,他們之前有啥區別?
- 你們後端用什麼資料庫做持久化的?有沒有用到分庫分表,怎麼做的?
- 索引的常見實現方式有哪些,有哪些區別?MySQL的儲存引擎有哪些,有哪些區別?InnoDB使用的是什麼方式實現索引,怎麼實現的?說下聚簇索引和非聚簇索引的區別?
- 有沒有了解過協程?說下協程和執行緒的區別?
- 演算法題一個,劍指offer第51題,陣列中的重複數字?
自己的回答情況,redis這塊沒啥問題,具體rehash有印象是漸進式的,但是具體原理可能答的有點出入。tcp的time_wait這塊答的不是很好,之前沒有了解過quic機制的實現,所以問可靠性udp的時候,基本上腦子裡就照著tcp的實現在說。https這塊沒啥說的,之前專案裡面有用到類似的東西,研究的比較清楚了。raft演算法這個因為剛好在刷6.824(才刷到lab2。。。),答的也湊合,不過paxos和zab演算法確實不熟悉,直接說不會。MySQL這塊很熟了,包括索引,鎖,事務機制以及mvcc等等,沒啥說的,都已經補齊了。協程和執行緒,主要說了go程和Java執行緒的區別以及go程的排程模型。面試官提示沒有提到執行緒的有核心態的切換,go程只在使用者態排程。最後一個演算法題,首先說使用HashMap來做,說空間複雜度能不能降到O(1),後面想了大概5min才想出來原地置換的思路。
二面專案技術面
- 主要針對自己最熟悉的專案,畫出專案的架構圖,主要的資料表結構,專案中使用到的技術點,專案的總峰值qps,時延,以及有沒有分析過時延出現的耗時分別出現在什麼地方,專案有啥改進的地方沒有?
- 如果請求出現問題沒有響應,如何定位問題,說下思路?
- tcp 粘包問題怎麼處理?
- 問了下快取更新的模式,以及會出現的問題和應對思路?
- 除了公司專案之外,業務有沒有研究過知名專案或做出過貢獻?
基本都沒有啥問題,除了面試官說專案經驗稍弱之外,其餘還不錯。
三面綜合技術面
這面面的是陣腳大亂,面試官採用刨根問底的方式提問,終究是面試經驗不夠,導致面試的節奏有點亂。 舉個例子:
其中有個題是go程和執行緒有什麼區別?
答:1 起一個go程大概只需要4kb的記憶體,起一個Java執行緒需要1.5MB的記憶體;go程的排程在使用者態非常輕量,Java執行緒的切換成本比較高。接著問為啥成本比較高?因為Java執行緒的排程需要在使用者態和核心態切換所以成本高?為啥在使用者態和核心態之間切換排程成本比較高?簡單說了下核心態和使用者態的定義。接著問,還是沒有明白為啥成本高?心裡瞬間崩潰,沒完沒了了呀,OS這塊依舊是痛呀,支支吾吾半天放棄了。
後面所有的提問都是這種模式,結果回答的節奏全無,感覺被套路了。大多度都能回答個一二甚至是一二三,但是再往後或者再深入的OS層面就GG了。
後面問了下專案過程中遇到的最大的挑戰,以及時怎麼解決的?
後面還問了一個問題定位的問題,伺服器CPU 100%怎麼定位?可能是由於平時定位業務問題的思維定勢,加之處於矇蔽狀態,隨口就是:先檢視監控皮膚看有無突發流量異常,接著檢視業務日誌是否有異常,針對CPU100%那個時間段,取一個典型業務流程的日誌檢視。最後才提到使用top
命令來監控看是哪個程式佔用到100%。果然陣腳大亂,張口就來,捂臉。。。
本來正確的思路應該是先用top
定位出問題的程式,再用top
定位到出問題的執行緒,再列印執行緒堆疊檢視執行情況,這個流程換平時肯定能答出來,但是,但是沒有但是。還是得好好總結。
最後問了一個系統設計題目(朋友圈的設計),白板上面畫出系統的架構圖,主要的表結構和講解主要的業務流程,如果使用者變多流量變大,架構將怎麼擴充套件,怎樣應對?
這個答的也有點亂,直接上來自顧自的用了一個通用的架構,感覺毫無亮點。後面反思應該先定位業務的特點,這個業務明顯是讀多寫少,然後和麵試官溝通一期剛開始的方案的使用者量,效能要求,單機目標qps是什麼等等?在明確系統的特點和約束之後再來設計,而不是一開始就是用典型網際網路的那種通用架構自顧自己搞自己的方案。
3天后收到簡訊被拒
總結
- tcp/udp,http和https還有網路這塊(各種網路模型,已經select,poll和epoll)一定要非常熟悉
- 一定要有拿的出手的專案經驗,而且要能夠講清楚,講清楚專案中取捨,設計模型和資料表
- 分散式要非常熟悉
- 常見問題定位一定要有思路
- 作業系統,還是作業系統,重要的事情說三遍
- 系統設計,思路,思路,思路,一定要思路清晰,一定要總結下系統設計的流程
- 一點很重要的心得,平時blog和專欄看的再多,如果沒有自己的思考不過是過眼雲煙,根本不會成為自己的東西,就像核心態和使用者態,平常也看過,但是沒細想,突然要自己說,還真說不出來,這就很尷尬了。勿以浮沙築高臺,基礎這種東西還是需要時間去慢慢打牢,多去思考和總結。
相關資料補充學習:
某東南亞網際網路公司
一面技術面
先筆試演算法題,LeetCode medium難度,然後綜合問了下騰訊一面二面類似的問題+一個最熟悉的專案
二面研發經理綜合面試
綜合聊了下熟悉的技術,遇到了最難的問題,講解一下專案的流程和架構