【真相】大廠招人不怕花錢的原因竟然是。。。
??點擊“博文視點Broadview”,獲取更多書訊

互聯(lián)網(wǎng)大廠是很多開發(fā)人員所向往的公司,但大家應(yīng)該都聽過關(guān)于大廠面試候選人的一句調(diào)侃的話,“面試造火箭,工作擰螺絲”。這雖然有一點兒夸張的成分,不過也確實描述得比較形象。
在面試中,尤其是頂級互聯(lián)網(wǎng)大廠的面試,對技術(shù)的考查往往都很深。但是到了工作中,可能確實又需要花不少時間在寫各種各樣的重復(fù) CRUD 上。
那為啥會出現(xiàn)這種情況,是大廠閑得沒事非得為難候選人嗎?

其實不是,這是因為扎實的底層功力確實對大廠來說很重要。
互聯(lián)網(wǎng)大廠區(qū)別于小公司的一個業(yè)務(wù)特點就是海量請求,隨便一個業(yè)界第二梯隊的App,每天的后端接口請求數(shù)過億很常見,更不用提微信、淘寶等頭部應(yīng)用了。
在這種量級的用戶請求下,業(yè)務(wù)能7×24小時穩(wěn)定地提供服務(wù)就非常重要了。哪怕服務(wù)故障出現(xiàn)十分鐘,對業(yè)務(wù)造成的損失可能都是不容小覷的。
所以在大廠中,你寫出來的程序不是能跑起來就行了,是必須能夠穩(wěn)定運行。
程序在運行期間可能會無法避免地遭遇各種線上問題。應(yīng)用都是跑在硬件、操作系統(tǒng)之上的,因此線上的很多問題都和底層相關(guān)。如果遇到線上問題,你是否有能力快速排查和處理?例如有的時候線上訪問超時是因為TCP的全連接隊列滿導(dǎo)致的。如果你對這類底層的知識了解得不夠,則根本無法應(yīng)對。
另外,大廠招聘高水平程序員的目的可能不僅僅是能快速處理問題,甚至希望程序員能在寫代碼之前就做出預(yù)判,從而避免出故障。不知道你所在的團隊是否進行過Code Review(代碼評審,簡稱CR)。往往新手程序員自我感覺良好、覺得寫得還不錯的代碼給資深程序員看一眼就能發(fā)現(xiàn)很多上線后可能會出現(xiàn)的問題。
大廠在招人上是不怕花錢的,最怕的是業(yè)務(wù)不穩(wěn)定和不可靠。如果以很低的價錢招來水平一般的程序員,結(jié)果導(dǎo)致業(yè)務(wù)三天兩頭出問題,給業(yè)務(wù)收入造成損失,那可就得不償失了。
所以,要想進大廠,扎實的內(nèi)功是不可或缺的。
那是不是說已經(jīng)工作了,或者已經(jīng)進入大廠了,扎實的內(nèi)功、能力就可有可無了呢?答案當(dāng)然是否定的,工作以后內(nèi)功也同樣的重要!
拿后端開發(fā)崗來舉例。初接觸后端開發(fā)的朋友會覺得,這個方向太容易了。我剛接觸后端開發(fā)的時候也有這種錯覺。我剛畢業(yè)做Windows下的C++開發(fā)的時候,項目里的代碼編譯完生成的工程都是幾個GB的,但是轉(zhuǎn)到后端后發(fā)現(xiàn),一個服務(wù)端接口可能100行代碼就搞定了。
由于看上去的這種“簡單性”,許多工作三年左右的后端開發(fā)人員會陷入一個成長瓶頸,手頭的東西感覺已經(jīng)特別熟練了,編程語言、框架、MySQL、Nginx、Redis都用得很溜,總感覺自己沒有啥新東西可以學(xué)習(xí)了。
他們真的已經(jīng)掌握所有了嗎?其實不然,當(dāng)他們遇到一些線上的問題時,排查和定位手段又極其有限,很難承擔(dān)得起線上問題緊急救火的重要責(zé)任。當(dāng)程序性能出現(xiàn)瓶頸的時候,只是在網(wǎng)上搜幾篇帖子,盲人摸象式地試一試,各個一知半解的內(nèi)核參數(shù)調(diào)一調(diào),對關(guān)鍵技術(shù)缺乏足夠深的認知。
反觀另外一些工作經(jīng)驗豐富的高級技術(shù)人員,他們一般對底層有著深刻的理解。當(dāng)線上服務(wù)出現(xiàn)問題的時候,都能快速發(fā)現(xiàn)關(guān)鍵問題所在。就算是真的遇到了棘手的問題,他們也有能力潛入底層,比如內(nèi)核源碼,去找答案,看看底層到底是怎么干的,為啥會出現(xiàn)這種問題。
所以大廠不僅僅是在招聘時考察應(yīng)聘者,在內(nèi)部的晉升選拔中也同樣注重考察開發(fā)人員對于底層的理解以及性能把控的能力。一個人的內(nèi)功深淺,決定了他是否具備基本的問題排查以及性能調(diào)優(yōu)能力。內(nèi)功指的就是當(dāng)年你曾經(jīng)學(xué)過的操作系統(tǒng)、網(wǎng)絡(luò)、硬件等知識?;ヂ?lián)網(wǎng)的服務(wù)都是跑在這些基礎(chǔ)設(shè)施之上的,只有你對它們有深刻的理解,才能夠源源不斷想到新的性能分析和調(diào)優(yōu)辦法。
所以說,扎實的內(nèi)功并不是通過大廠面試以后就沒有用了,而是會貫穿你整個職業(yè)生涯。
之前網(wǎng)絡(luò)曾爆炒一篇標(biāo)題為“互聯(lián)網(wǎng)不需要中年人”的文章,瘋狂渲染35歲碼農(nóng)的前程問題,制造焦慮。
本來我覺得這件事情應(yīng)該只是媒體博眼球的一個炒作行為而已,不過恰恰兩三年前我們團隊擴充,需要招聘一些級別高一點兒的開發(fā)人員,之后使我對此話題有了些其他想法。那段時間我面試了七十多人,其中有很多工作七八年以上的。
我面試的這些人里,有這么一部分人雖然已經(jīng)工作了七八年以上,但是所有的經(jīng)驗都集中在手頭的那點兒項目的業(yè)務(wù)邏輯上。對他們稍微深入問一點兒性能相關(guān)的問題都沒有好的思路,技術(shù)能力并沒有隨著工作年限的增?而增?。換句話說,他們并不是有七八年經(jīng)驗,而是把兩三年的經(jīng)驗用了七八年而已。
和這些人交流后,我發(fā)現(xiàn)共同的原因就是他們絕大部分的時間都是在處理各種各樣的業(yè)務(wù)邏輯和bug,沒有時間和精力去提升自己的底層技術(shù)能力,真遇到線上問題也沒有耐心鉆研下去,隨便在網(wǎng)上搜幾篇文章都試一試,哪個碰對了就算完事,或者干脆把故障拋給運維人員去解決,導(dǎo)致技術(shù)水平一直原地踏步,并沒有隨著工作年限而同步增長。我從那以后也確實認識到,碼農(nóng)圈里可能真的有中年焦慮存在。
那是不是說這種焦慮就真的無解了呢?答案肯定是“不是”。至少我面試過的這些人里還有一部分很優(yōu)秀,不但業(yè)務(wù)經(jīng)驗豐富,而且技術(shù)能力出眾,目前都發(fā)揮著重要作用。你也可以看看你們公司的高級別技術(shù)人員,甚至業(yè)界的各位技術(shù)大牛,相信他們會長期是你們公司甚至業(yè)界的中流砥柱。
那么工作了多年的這兩類人中,差異如此巨大的原因是什么呢?我思考了很多,也和很多人都討論過這個問題。最后得出的結(jié)論就是大牛們的技術(shù)積累是隨著工作年限的增長而逐漸增長的,尤其是內(nèi)功,和普通的開發(fā)人員相差巨大。
大牛們對底層的理解都相當(dāng)深刻。深厚的內(nèi)功知識又使得他們學(xué)習(xí)起新技術(shù)來非???。舉個例子,在初級開發(fā)人員眼里,可能Java的NIO和Golang的net包是兩個完全不同的東西,所以學(xué)習(xí)起來需要分別花費不少精力。但在底層知識深厚的人眼里,它們兩個只不過是對epoll的不同封裝方式,就像只換了一身衣服,理解起來自然就輕松得多。
如此良性迭代下去,技術(shù)好的和普通的開發(fā)人員相比,整體技術(shù)水平差距越拉越大。普通開發(fā)人員越來越焦慮,甚至開始擔(dān)心技術(shù)水平被剛畢業(yè)的年輕人趕超。
內(nèi)功,它不幫你掌握最新的開發(fā)語言,不教會你時髦的框架,也不會帶你走進火熱的人工智能,但是我相信它是你成為“大?!钡谋亟?jīng)之路。
我簡單列一下修煉內(nèi)功的好處。
1)更順利地通過大廠的面試。大廠的面試對技術(shù)的考查比較底層,而網(wǎng)上的很多答案層次都還比較淺。拿三次握手舉例,一般網(wǎng)上的答案只說到了初步的狀態(tài)流轉(zhuǎn)。其實三次握手中包含了非常多的關(guān)鍵技術(shù)點,比如全連接隊列、半連接隊列、防syn flood攻擊、隊列溢出丟包、超時重發(fā)等深層的知識。再拿epoll舉例,如果你熟悉它的內(nèi)部實現(xiàn)方式,理解它的紅黑樹和就緒隊列,就知道它高性能的根本原因是讓進程大部分時間都在處理用戶工作,而不是頻繁地切換上下文。如果你的內(nèi)功能深入觸達這些底層原理,一定會為你的面試加分不少。
2)為性能優(yōu)化提供充足的“彈藥”。目前大公司內(nèi)部對于高級和高級以上工程師晉升時考核的重要指標(biāo)之一就是性能優(yōu)化。在對內(nèi)核缺乏認識的時候,大家的優(yōu)化方式一般都是盲人摸象式的,手段非常有限,做法很片面。當(dāng)你對網(wǎng)絡(luò)整體收發(fā)包的過程理解了以后,對網(wǎng)絡(luò)在CPU、內(nèi)存等方面的開銷的理解將會很深刻。這會對你分析項目中的性能瓶頸所在提供極大的幫助,從而為你的項目性能優(yōu)化提供充足的“彈藥”。
3)內(nèi)功方面的技術(shù)生命周期長。Linux操作系統(tǒng)1991年就發(fā)布了,現(xiàn)在還是發(fā)展得如火如荼。對于作者 Linus,我覺得他也有年齡焦慮,但他可能焦慮的是找不到接班人。反觀應(yīng)用層的一些技術(shù),尤其是很多的框架,生命周期能超過十年我就已經(jīng)覺得它很牛了。如果你的精力全部押寶在這些生命周期很短的技術(shù)上,你說能不焦慮嗎!所以我覺得戒掉浮躁,踏踏實實練好內(nèi)功是你對抗焦慮的解藥之一。
4)內(nèi)功深厚的人理解新技術(shù)非???。不用說業(yè)界的各位“大?!绷耍湍梦易约簛砼e兩個小例子。我其實沒怎么翻過Kafka的源碼,但是當(dāng)我研究完了內(nèi)核是如何讀取文件的、內(nèi)核處理網(wǎng)絡(luò)包的整體過程后,就“秒懂”了Kafka在網(wǎng)絡(luò)這塊為啥性能表現(xiàn)很突出了。還有,當(dāng)我理解了epoll的內(nèi)部實現(xiàn)以后,回頭再看Golang的net包,才切切實實看懂了絕頂精妙的對網(wǎng)絡(luò)IO的封裝。所以你真的弄懂了Linux內(nèi)核的話,再看應(yīng)用層的各種新技術(shù)就猶如戴了透視鏡一般,直接看到骨骼。
5)內(nèi)核提供了優(yōu)秀系統(tǒng)設(shè)計的實例。Linux作為一個經(jīng)過千錘百煉的系統(tǒng),其中蘊含了大量的世界頂級的設(shè)計和實現(xiàn)方案。平時我們在自己的業(yè)務(wù)開發(fā)中,在編碼之前也需要先進行設(shè)計。比如我在剛工作的時候負責(zé)數(shù)據(jù)采集任務(wù)調(diào)度,其中的實現(xiàn)就部分參考了操作系統(tǒng)進程調(diào)度方案。再比如,如何在管理海量連接的情況下仍然能高效發(fā)現(xiàn)某一條連接上的IO事件,epoll內(nèi)部的“紅黑樹 + 隊列”組合可以給你提供一個很好的參考。這種例子還有很多很多??傊绻軐?Linux的某些優(yōu)秀實現(xiàn)搬到你的系統(tǒng)中,會極大提升你的項目的實現(xiàn)水平。
時髦的東西終究會過時,但扎實的內(nèi)功將會伴隨你一生。只有具備了深厚的內(nèi)功底蘊,你才能在發(fā)展的道路上走得更穩(wěn)、走得更遠。
平時大家都是用各種語言進行業(yè)務(wù)邏輯的代碼編寫,無論你用的是PHP、Go,還是Java,都屬于應(yīng)用層的范疇。但是應(yīng)用層是建立在物理層和內(nèi)核層之上的。我把在應(yīng)用層的技術(shù)能力稱為外功,把 Linux 內(nèi)核、設(shè)備物理結(jié)構(gòu)方面的技術(shù)能力稱為內(nèi)功。前面已經(jīng)說了,無論是在職業(yè)生涯的哪個階段,扎實的內(nèi)功都很重要。
那好,既然內(nèi)功如此重要,那就找一些底層相關(guān)的資料加強學(xué)習(xí)就行了。但很遺憾,我覺得目前市面上的技術(shù)資料在內(nèi)功方向上存在一些不足。
先說網(wǎng)上的技術(shù)文章。目前網(wǎng)上的技術(shù)文章、博客非常多。大家遇到問題往往先去搜一下。但是你有沒有發(fā)現(xiàn),網(wǎng)上入門級資料一搜一大把,而內(nèi)功深厚、能深入底層原理的文章卻十分匱乏。
比如,現(xiàn)在的互聯(lián)網(wǎng)應(yīng)用大部分都是通過TCP連接來工作的,那么一臺機器最多能撐多少個TCP 連接?按道理說,整個業(yè)界都在講高并發(fā),這應(yīng)該算是很入門的一個問題了。但當(dāng)年我產(chǎn)生這個疑問的時候,在搜索引擎上搜了個遍也沒找到令我滿意的答案。后來我干脆自己動手,花了一個多月時間邊做測試,邊扒內(nèi)核源碼,才算是把問題徹底搞明白了。
再比如,大部分的開發(fā)人員都搞過網(wǎng)絡(luò)相關(guān)的開發(fā)。那么一個網(wǎng)絡(luò)包是如何從網(wǎng)卡到達你的進程的?這個問題表面上看起來簡單,但實際上很多性能優(yōu)化方案都和這個接收過程有關(guān),能不能深度理解這個過程決定了你在網(wǎng)絡(luò)性能上有多少優(yōu)化措施可用。例如多隊列網(wǎng)卡的優(yōu)化方案是在硬中斷這一步開始將工作分散在多個 CPU 核上,進而提升性能的。我?guī)啄昵跋氚堰@個問題徹底搞清楚,幾乎搜遍了互聯(lián)網(wǎng),翻遍了各種經(jīng)典書都沒能找到想要的答案。
還比如,網(wǎng)上搜到的三次握手的技術(shù)文章都是在說一些簡單的內(nèi)容,客戶端如何發(fā)起 SYN 握手進入 SYN_SENT 狀態(tài),服務(wù)端響應(yīng)SYN并回復(fù) SYNACK,然后進入 SYN_RECV……諸如此類。但實際上,三次握手的過程執(zhí)行了很多內(nèi)核操作,比如客戶端端口選擇、重傳定時器啟動、半連接隊列的添加和刪除、全連接隊列的添加和刪除。線上的很多問題都是因為三次握手中的某一個環(huán)節(jié)出問題導(dǎo)致的,能否深度理解這個過程直接決定你是否有在線上快速消滅或者避免此類問題的能力。網(wǎng)上能深入介紹三次握手的文章太少了。
你可能會說,網(wǎng)上的文章不足夠好,不是還有好多經(jīng)典書嗎?首先我得說,計算機類的一些經(jīng)典的書確實很不錯,值得你去看,但是這里面存在幾個問題。
一是底層的書都寫得比較深奧難懂,你看起來需要花費大量的時間。假如你已經(jīng)工作了,很難有這么大塊的時間去啃。比如我剛開始深入探尋網(wǎng)絡(luò)實現(xiàn)的時候,買來了《深入理解Linux內(nèi)核》《深入理解Linux網(wǎng)絡(luò)技術(shù)內(nèi)幕》等幾本書,利用工作之余斷斷續(xù)續(xù)花了將近一年時間才算理解了一個大概。
另外一個問題就是當(dāng)你真正在工作中遇到一些困惑的時候,會發(fā)現(xiàn)很難有一本經(jīng)典書能直接給你答案。比如在《深入理解 Linux 網(wǎng)絡(luò)技術(shù)內(nèi)幕》這本書里介紹了內(nèi)核中各個組件,如網(wǎng)卡設(shè)備、鄰居子系統(tǒng)、路由等,把相關(guān)源碼都講了一遍。但是看完之后我還是不清楚一個包到底是如何從網(wǎng)卡到應(yīng)用程序的,一臺服務(wù)器到底能支持多少個TCP連接。
還有個問題就是計算機技術(shù)不同于其他學(xué)科,除理論外對實踐也有比較高的要求。如果只是停留在經(jīng)典書里的理論階段,實際上很多問題根本就不能理解到位。這些書往往又缺乏和實際工作相關(guān)的動手實驗。比如對于一臺服務(wù)器到底能支持多少個TCP連接這個問題,我自己就是在做了很多次的實驗以后才算比較清晰地理解了。還有就是如果沒有真正動過手,那你將來對線上的性能優(yōu)化也就無從談起了。
總的來說,看這些經(jīng)典書不失為一個辦法,但考量時間的花費和對工作問題的精準(zhǔn)處理,我感覺效率比較低。所以鑒于此,我決定輸出一些內(nèi)容,也就有了《深入理解Linux網(wǎng)絡(luò):修煉底層內(nèi)功,掌握高性能原理》這本書的問世。

雖然底層的知識如此重要,但這類知識有個共同的特點就是很枯燥。那如何才能把枯燥的底層講好呢?這個問題我思考過很多很多次。
2012年我在騰訊工作期間,在內(nèi)部KM技術(shù)論壇上發(fā)表過一篇文章,叫作《Linux文件系統(tǒng)十問》(這篇文章現(xiàn)在在外網(wǎng)還能搜到,因為被搬運了很多次)。
當(dāng)時寫作的背景是“老大”分配給我一個任務(wù),把所有合作方提供的數(shù)據(jù)里的圖片文件都下載并保存起來。我把在工作中產(chǎn)生的幾個疑問進行了追根溯源,找到答案以后寫成文章發(fā)表了出來。比如文件名到底存在了什么地方,一個空文件到底占不占用磁盤空間,Linux目錄下子目錄太多會有什么問題,等等。這篇文章發(fā)表出來以后,竟然在全騰訊公司內(nèi)部傳播開了,反響很大,最后成為了騰訊KM當(dāng)年的年度熱文。
為什么我的一篇簡單的Linux文件系統(tǒng)的文章能得到這么強烈的回響?后來我在羅輯思維的一期節(jié)目里找到了答案。節(jié)目中說最好的學(xué)習(xí)方式就是你自己要產(chǎn)生一些問題,帶著這些問題去知識的海洋里尋找答案,當(dāng)答案找到的時候,也就是你真正掌握了這些知識的時候。經(jīng)過這個過程掌握的知識是最深刻的,和你自身的融合程度也是最高的,能完全內(nèi)化到你的能力體系中。
換到讀者的角度來考慮也是一樣的。其實讀者并不是對底層知識感興趣,而是對解決工作中的實際問題興趣很大。這篇文章其實并不是在講文件系統(tǒng),而是在講開發(fā)過程中可能會遇到的問題。我只是把文件系統(tǒng)知識當(dāng)成工具,用它來解決掉這些實際問題而已。
所以我在本書的創(chuàng)作過程中,一直貫穿的是這個思路:以和工作相關(guān)的實際的問題為核心。
在每一章中,我并不會一開始就給你灌輸軟中斷、epoll、socket 內(nèi)核對象等內(nèi)核網(wǎng)絡(luò)模塊的知識,我也覺得這些很乏味,而是每章先拋出幾個和開發(fā)工作相關(guān)的實際問題,然后圍繞這幾個問題展開探尋。是的,我用的詞不是“學(xué)習(xí)”,而是“探尋”。和學(xué)習(xí)相比,探尋更強調(diào)對要解惑的問題的好奇心,更有意思。
雖然本書中會涉及很多的源碼,但這里先強調(diào)一下,這并不是一本源碼解析的書。大家學(xué)習(xí)的真正目的是理解和解決項目實踐相關(guān)的問題,進而提高駕馭手頭工作的能力,而源碼只是我們達成目的的工具和途徑而已。
本書并不是一本計算機網(wǎng)絡(luò)的入門書,閱讀本書需要你具備起碼的計算機網(wǎng)絡(luò)知識。它適合以下讀者:
想通過提升自己的網(wǎng)絡(luò)內(nèi)功而進大廠的讀者。
不滿足于只學(xué)習(xí)網(wǎng)絡(luò)協(xié)議,也想理解它是怎么實現(xiàn)的讀者。
雖有幾年開發(fā)工作經(jīng)驗,但對網(wǎng)絡(luò)開銷把握不準(zhǔn)的開發(fā)人員。
想做網(wǎng)絡(luò)性能優(yōu)化,但沒有成體系的理論指導(dǎo)的讀者。
維護各種高并發(fā)服務(wù)器的運維人員。
掃碼了解本書詳情!

如果喜歡本文 歡迎 在看丨留言丨分享至朋友圈 三連 熱文推薦
▼點擊閱讀原文,了解本書詳情~
