【決戰西二旗】|【乾貨】聊聊後端面試的常見問題和一些思考
0.前言
之前寫了一些具體知識點的相關文章,本次聊聊面試實戰。
面試是為了查漏補缺、明確學習方向和斬獲offer,所以寫一些自己以及好朋友們遇到過的面試題、以及個人對面試的一些看法。
題目主要來自百度、阿里、騰訊、微博、搜狗、FunPlus、高德、滴滴、快手、曠視、360、迅雷、獵豹、TME等公司。
由於時間原因做到100%完整描述不太可能,但是基本上也都達意了,有一定的參考價值。
1.修煉心法
-
不打無準備之仗
知己知彼百戰不殆,面試之前需要在拉勾、BOSS直聘上大致瞭解一下招聘崗位的工作描述,不排除一些公司虛張聲勢寫些個根本用不著的玩意,所以如果覺得崗位對口卻匹配度低,也不必緊張試試再說。
內推是瞭解崗位要求的重要渠道,不過從經驗看如果不是內推人本組的招聘崗位,很難做到深入細緻的瞭解,總起來說這樣的內推和線上投遞差別並不太大,不要以為內推就穩了,否則筆者內推獎金早拿到手軟了。
另外相同崗位不同級別考察的側重點也有很大區別,因此要根據意向崗位級別在深度和廣度上進行差異化準備。
-
面試官什麼路子
一百場面試就有一百種側重點,但並不能都算得上高質量的面試,知乎上有關於高質量面試的話題,感興趣可以看看。
作為主導者的面試官,個人認為最重要的原則是:明確在招崗位的職責內容,並以此為出發點對候選人進行考察,一般來說候選人過往經歷和在招崗位很相似的情況比較少,在此情況下就要從候選人的基礎是否紮實、學習能力如何等方面來衡量候選人快速適應新崗位內容的能力。
舉個例子:"並不一定要把1TB的硬碟裝滿才能證明這個硬碟是1TB的"
因此很多時候面試就像是一場證明500GB硬碟具備1TB空間的過程,至於測試手段是否科學就是面試官需要拿捏的了,如果面試官都不清楚自己問這個問題究竟是為了考察什麼,那麼這就是一場低質量的面試,所以對於候選人來說成敗與否都不用在意,畢竟這種糊塗面試官如果以後作為同事也是件很糟糕的事情。
-
做個合格的面試者
候選人無法左右面試官的問題,但是對於非大神面試者還是要做到幾點,來提高面試成功率,包括但不限於:
-
珍惜機會切忌裸面
毫無準備地去面試既浪費自己的時間也浪費面試官的時間,任何事情都有機會成本,重要的是現在大廠都有自己的人才庫體系,如果一年半載後再投,上次裸面的評價都依然還在,新的面試官對候選人的印象會大打折扣,甚至不給面試機會,所以要珍惜面試機會,裸面的面試者並不少見,問幾個問題就GameOver了,場面也十分尷尬。
-
理清思路清晰表達
在面試官表述了問題之後,就算問題在射程範圍內也不要急於回答,先理清楚條件,如有疑問立即求證,確定問題所有條件再做解答。在筆者作為面試官時比較看重這一點,因為這種性格在工作中是非常可貴的,很多時候你會遇到很多模糊需求,如果不反覆確定就按照你以為的開幹,只能是緣木求魚,最終delay掉需求。
-
拓展思維勇敢作答
對於大部分面試者來說,遇到沒見過的題目也不必慌張要冷靜分析當前問題中的難點,進而結合自己的實際經驗和知識儲備來提出你的分析和解決方案,縱然短時間內很難提出最優方案,或許可以很接近答案了,但是也不要胡說,否則只能讓人覺得你膽大心更大,具備刪庫跑路的潛力。
-
相信自己信心滿滿
時常出現面試者去二三線廠面試,最後給的評價很低,完全與其本人技術實力不匹配,之後短時間內反手拿了BAT的offer,所以任何時候都不要妄自菲薄,要無條件相信自己。我對此深有體會,筆者本碩都非CS專業且有一定跨度,遙想當年校招隔壁實驗室一起打球的CS碩們收割大廠offer,我這邊就算小公司也會被鄙視一通,所以無論現境如何,堅定信念、找準方向、持續發力、總會有所斬獲。
2.實戰題目
由於筆者以及好朋友們大都是Linux C/C++/Python/Go技術棧,所以實戰題目也是圍繞這個技術棧展開的,其他語言棧的大神可以選擇性閱讀無語言差異的共性問題,比如MySQL、Redis、Linux系統等。
-
題目分類
Linux C/C++技術棧的題目一般包括但不限於以下幾大類:
-
程式語言
-
資料結構和演算法
-
資料庫儲存
-
Linux系統
-
開源元件
-
工程設計
-
題目彙總
按照上面分類來歸納一些大廠的問題,更能看到各個分類下的熱門問題,從而更好地把握面試方向。
-
程式語言
-
闡述如何設計一個C++類?實現String類。
-
談談對C++虛擬函式機制的理解。
-
STL的Vector原理及迭代器失效的理解。
-
設計一個C++HashMap類。
-
使用C++實現一個堆的模板類。
-
寫一個巨集定義比較函式並解釋巨集展開過程。
-
談談std::move的理解和使用。
-
malloc的記憶體可以用delete釋放嗎?原因?
-
簡述C++11的新特性以及解決了什麼問題。
-
STL的Map原理、插入和刪除複雜度分析。
-
STL的Map基於紅黑樹實現的原因,為什麼不選擇雜湊表?
-
為什麼需要虛析構?虛析構和普通解構函式的區別是什麼?
-
說明C++物件的記憶體佈局模型。
-
聊聊C++臨時物件和右值引用,寫個例子。
-
使用C++寫一個高效的多維矩陣乘法。
-
談談對智慧指標的認識並實現一個智慧指標類。
-
STL中Map的查詢時[]和find區別是什麼?哪個更快?
-
實現memcpy函式效率儘可能高。
-
嘗試實現C/C++中常用字串庫函式。
-
談談C++中強制型別轉換的原理和使用,寫個例子。
-
談談C++的設計模式,重點介紹下單例模式、工程模式等。
-
資料結構和演算法
-
求二叉樹節點和為N的所有路徑。
-
實現二叉樹的映象。
-
實現兩棵二叉樹相加生成一棵新的二叉樹。
-
實現單鏈表的遞迴逆置和非遞迴逆置。
-
二分查詢變種問題。
-
二叉樹的後序非遞迴遍歷。
-
兩個無序整型陣列交換元素使得兩陣列和差距最小。
-
給定整型陣列和目標數輸出陣列所有兩數之和為目標數的組合。
-
找到帶權重二叉樹中從根到葉子的最大和路徑。
-
最長公共子序列LCS問題。
-
二叉樹中找到指定兩個節點最近公共祖先。
-
實現堆排序求Top10資料。
-
實現最小棧。
-
簡述並嘗試設計一個布隆過濾器。
-
外排序的基本實現過程。
-
常見排序演算法的效能對比。
-
快速排序的非遞迴實現
注:關於資料結構和演算法的網站和書籍非常多,並且這個分類也是面試中變幻最大的,這裡就不展開了。
對於資料結構和演算法能力的切實提高,可以刷LeetCode、《演算法導論》、《程式設計之法》、《程式設計珠璣》、《程式設計師面試金典》(注意不是寶典)、《程式設計師程式碼面試指南》等書籍,很多公眾號或者書籍的作用是對知識點進行梳理歸納總結,沒有捷徑,只有自己動手多練多寫才能真正成為自己的硬實力。
筆者認為雖然資料結構和演算法的題目比較繁雜,但是掌握常見資料結構(陣列、連結串列、棧、佇列、樹等)的基本特性和實現方法,再結合二分、遞迴、回溯、貪心、動態規劃等演算法思想,很多問題都可以回答得比較接近正確答案,資料結構做骨架、演算法是靈魂,務必多練多寫找到感覺。
堅持每天刷leetcode是個好辦法,但是對於在職人員來說996已經快被搞死了,LeetCode每日一題確實有些困難,況且刷LeetCode的重點在於一題N解,多個角度多種方法解題,不過還是那句話:"種一棵樹的最好時間是十年前,而後是現在"。
-
資料庫儲存
-
談談對於Redis的底層資料結構的理解。
-
跳錶瞭解嗎?Redis的zset實現原理以及為什麼不用紅黑樹。
-
Redis哨兵原理以及叢集版故障轉移過程。
-
基於Redis實現分散式鎖。
-
Redis漸進式Rehash的實現原理。
-
Redis和LevelDB的區別以及LevelDB的LSM樹和WAL原理。
-
Redis主從同步的實現原理和過程、產生資料丟失的原因。
-
MyISAM和InnoDB的區別。
-
MySQL索引原理和優化。
-
Redis叢集版如何實現一致性Hash演算法的。
-
Redis的單執行緒網路框架原理和混合持久化機制。
-
類Redis資料庫Pika瞭解嗎?基本設計架構是什麼?
-
如何設計一個快取系統以及快取擊穿的解決方案?
-
一致性協議raft/paxos/2pc/3pc基本原理。
-
Redis的Gossip協議原理。
-
Redis4.0+版本的BIO執行緒原理和使用。
-
簡述如何自己實現一個NoSQL,需要考慮什麼。
-
Linux系統
-
LVS實現負載均衡的原理。
-
簡述Linux記憶體管理原理以及夥伴演算法和Slab演算法。
-
select和epoll的對比以及epoll實現的底層原理和資料結構。
-
epoll的LT模式和ET模式下讀寫操作,實現一下ET模式的read/write。
-
使用C++簡單實現一個生產者消費者模型。
-
Linux虛擬記憶體和實體記憶體的區別與聯絡
-
如何使用gdb除錯多程序、多執行緒程式。
-
談談C10K和C10M問題及大致實現思路。
-
Linux地址複用和埠複用的使用。
-
談談Reactor和Proactor模式區別與聯絡。
-
嘗試基於epoll實現一個高併發網路框架。
-
Nginx的基本原理以及負載均衡實現方法。
-
談談Linux伺服器記憶體/cpu/磁碟/網路頻寬的監控命令和問題排查。
-
談談CAP理論以及分散式一致性演算法。
-
瞭解CpuCache嗎,如何據此來優化程式碼。
-
讀寫鎖、RCU鎖、自旋鎖的對比以及設計讀優先/寫優先的讀寫鎖
-
自己設計實現一個簡單的讀寫鎖。
-
談談grpc的使用以及brpc的對比。
-
對比協程和進執行緒,重點說明系統開銷差異和各自優缺點。
-
談談對執行緒同步和多執行緒安全的理解。
-
Https的C/S互動過程、http1.0/2.0/3.0的對比。
-
多程序通訊的方法和對比。
-
多執行緒同步的實現和執行緒安全。
-
實現一個基於LRU的本地快取。
-
TCP/IP的擁塞控制原理和缺陷、BBR演算法對比。
-
使用Python實現多程序和多執行緒以及談談對GIL的理解。
-
網路攻擊有哪些?簡述DDos、CC攻擊。
-
對比記憶體分配malloc/tcmalloc/ptmalloc。
-
Protobuf協議的簡單原理和使用。
-
Coredump的常見原因。
-
死鎖的原理以及寫一個死鎖。
-
MapReduce的基本原理、寫個簡單的map和reduce的程式。
-
同步非同步阻塞非阻塞IO的理解。
-
git的基本原理以及常用命令。
-
區域性性hash演算法simhash的原理。
-
服務端長短連線的區別、優勢和場景。
-
如何避免多執行緒的虛假喚醒問題。
-
實現簡單的執行緒池和連線池。
-
實現一個可以完成C10K+的TCP網路框架。
-
嘗試多種方法實現一個守護程序,2 magic fork瞭解嗎?
-
驚群問題知道嗎?Nginx是如何解決的?
-
談談對服務治理和服務發現的理解。
-
微服務接觸過嗎?談談對微服務的理解。
-
服務非同步化程式設計瞭解過嗎?
-
開源元件
-
常用的MQ有哪些以及各自的對比和場景
-
Kafka的基本原理和實現要點
-
libevent/libuv的基本原理和使用
-
Boost.Asio的原理和使用
-
微信協程庫libco原理和使用
-
DPDK的基本原理和使用者態協議棧的概念
-
Redis和Memcached對比
-
RPC框架對比:brpc/grpc/thrift
-
STL原始碼的理解和閱讀分析
-
Nginx的架構、原理、使用
注:開源元件的問題一般都比較寬泛,因此沒有列舉太多具體問題。
開源元件的準備重在基本原理和架構的理解,面試官不希望候選人對開源元件的使用是完全的拿來主義和黑盒子式API呼叫,其次是從開源元件中獲得解決問題的思想和套路。
因為日常工作場景有很多共性問題,可以借鑑開源元件的經驗進行遷移解決,都是要站在巨人的肩膀上的,牛頓都站了,你何必要閉門造車呢?
-
工程設計
-
資訊流推薦中會生成大量點選率文章,設計一個程式實現即時排序,返回熱門文章。
-
詞庫每個詞都有根據點選率來計算的熱度,實現一個系統,支援字首匹配並且返回Top10的熱詞。
-
設計一個支援千萬級文章相似度去重的程式,來實現抄襲、洗稿文章的識別,時間ms級,準確率不低於95%。
-
小記憶體機器有兩個檔案A和B,分別存放5億條均長64位元組的url,試著找到A和B中所有重複的url。
-
嘗試實現一個簡單的音樂推薦系統,可以不涉及具體演算法,主要說明工程部分即可。
-
設計一個黑詞服務實現黃反、指令詞、敏感詞等過濾功能,耗時ms級。
工程設計題目一般會是面試官日常遇到的典型問題,型別很多,但是系統設計類問題經常和海量資料問題、堆排序等一起出現。
對於此類問題,重要的是明確功能點、找準解題方向、拆解子問題、分步驟合併、各個擊破、先實現再提優化方案,以此原則來解決工程設計問題,基本上就很接近答案了。
3.小結和感慨
題目很多並且沒有給出解答,除了工程設計題,其他題目在網上都可以找到解答,但是本號會在後續文章中對上述問題各個擊破,建立完整分類的體系,敬請期待。
2018下半年以及整個2019一直被認為是寒冬時期,也總能聽到裁員或者公司倒閉的一些訊息,有校招生比offer也有剛畢業的應屆生被裁,有套現離場的也有昨天還在熬夜加班優化程式碼,次日被裁的,還有甚囂塵上的35歲失業問題,林林總總。
無論如何作為求職者和在職者都要坦然面對,市場波動在所難免,我們能做的只有:擁抱變化 時刻準備