1. 程式人生 > >歲月劃過生命線(從0到阿里)

歲月劃過生命線(從0到阿里)

    從來沒有想到自己的求職之路會這麼順利, 第一次投阿里就拿到了offer, 以前一直都是做好被刷的準備的...

3月31號晚上收到了來自阿里的正式offer, 簽下錄取意向書, 粗略算了一下, 從2012年9月份正式入學進入計算機繫到2015年3月簽下阿里offer, 大約兩年半的時間, 這期間有很多人值得感謝: 磊哥, 立萍, 宋藝, 興華老師... 發生了很多事兒: 從最初的懵懵懂懂到後來的立志進入像阿里一樣的一線網際網路企業, 從對計算機一竅不通到有自己的目標和興趣愛好, 從不知道技術部落格是啥到個人部落格的訪問量超過40W...  也學習了很多內容: C++, Linux, 資料結構與演算法, 計算機網路(TCP/IP), 作業系統(OS)...


磊哥一直想讓我寫下這次面試的經過, 同時也記錄一下這一年來準備招聘的過程, 很多有意思的事兒如果現在不寫下來以後很快就忘了, 何況看了這麼多的面試經驗, 現在到了"回饋社會”的時候了, 但是一直拖著不知道怎麼開始, 這一拖就到了5月份, 這篇部落格陸陸續續寫了半個多月, 感覺今天應該告一段落了, 不然總有新的東西加進來,這篇部落格是永遠寫不完的...

由於很多朋友和大神學弟對我找工作的準備過程以及面試經歷比較感興趣, 我就分別談一下自己的這兩段經歷吧:

養兵千日

我是在2013年11月份中旬遇到磊哥的, 當時磊哥剛剛拿下阿里巴巴的offer, 意氣風發, 我越俎代庖請磊哥給我們這些學弟學妹做交流講座的詳細經過在我的另一篇部落格《我的2013 -歲月劃過生命線》(

連結)有詳細的記錄, 在此我就不再贅述了, 不過後來我又找了磊哥好幾次, 聊了很多, 也收穫很多, 下定決心一定要進入阿里之類的一線網際網路公司, 後來磊哥也一直鼓勵並幫助我進入阿里, 因此, 我一直把磊哥當成為命裡的貴人.

我的準備工作大致分為五方面內容: C++, Linux, 資料結構與演算法, 計算機網路(TCP/IP)和作業系統. 如果一個本科生能夠把這五方面的基礎打得比較堅實再加上稍稍一點兒運氣, 拿下網際網路的offer是不在話下的, 另外如果你實力夠強的話, 那僅需的一點兒運氣也是不需要的, 在此我引用671學長的一句關於面試的經典: ”面試 = 運氣*(50-n)/100 + 實力*(50+n)/100, n=f(x),x即實力,n與x成正比關係,這就意味著: 你實力越強,對運氣的依賴性越低,所以實力才是非常重要的一個環節.”, 下面分別介紹一下我所準備的五方面內容:

C++:

C++被我稱之為飛機中的戰鬥機, 我對C++是情有獨鍾的, 他功能非常強大, 尤其是其與Linux作業系統結合, C++靈活的語法, 再加上Linux強大的平臺支援, 讓人感覺有種手握核武器的感覺[不過今天(4月28號)獲悉自己在阿里實習被分派到了YunOS手機作業系統部門, 以後要主攻Java了...], 這方面我讀過的經典的書有《C++ Primer》,《Effective C++》,《深度探索C++物件模型》與《STL原始碼剖析》,其實在面試阿里的時候《STL原始碼剖析》這本書是還暫時未讀完,而且我的簡歷上面也沒寫我讀過STL原始碼, 但是面試官仍然問了很多這方面的內容,如:關聯容器的典型實現原理, vector/list的實現, 迭代器失效的問題, string的三種實現方式等, 面試官對STL實現的看重可見一斑; 另外《深度探索C++物件模型》也是面試官常問的內容之一,像虛擬函式的實現機制, 過載的實現原理什麼的都是常問的, 在網上流傳著一段關於本書的書評, 感覺比較有意思(連結); 《Effective C++》中的內容在我面試時沒怎麼問到, 但是我個人感覺trains技法是比較難,而且屬於比較重要且常用的內容, 因此大家也需要悉心準備一下. 這方面的書要多讀幾遍, 不要異想天開的認為這些書只讀一邊就能夠完全理解, 經典之所以叫經典, 就是無論你第幾次讀都能找到新感覺!

Linux:

關於Linux部分是值得大書特書的, 我感覺這次之所以面試這麼順利, 很大一部分是Linux幫了我的忙. 我個人把Linux的內容分為兩部分:一是Linux開發環境,一是Linux程式設計:

1) Linux開發環境: 在這部分我認為最主要的是學習Linux這個作業系統平臺的思想(Linux很多方面都與Windows有所不同, 如一切皆檔案等), 以及使自己適應Linux的命令列,其他的都是次要的. 因此這方面的內容是比較好學的. 這方面比較重點的內容是: Linux常用命令, Vi/Vim使用, 軟體管理, 使用者管理, 許可權管理, 程序管理, Shell程式設計以及常用開發工具(如gcc/g++, gdb, make)的使用等. 這方面的內容我比較推薦兩本比較經典的書《鳥哥的Linux私房菜》,《Linux Shell指令碼攻略》, 但是對於這種實踐性課程,光看書是不夠的,而且有時僅僅看書是很枯燥的,因此我在此給大家推薦一部”李明Linux視訊教程”(連結),大家結合著書與視訊練習, 不會感到枯燥; 李明老師對於Linux無論是基礎知識還是高階應用的功力都十分精湛,聽課時既能學到知識又能拓寬視野, 因此這部視訊我看了兩遍, 而Linux的筆記就寫了兩遍, 我把所有的聽課時的筆記都整理髮布到了部落格上(連結); 我原來看的是第一版的視訊, 系統是基於CentOS 5.5的,後來李明老師又出了第二版, 當然第二版增加了很多內容, 組織也更加清晰合理, 總的說第二版是比第一版更好的, 但是珠玉在前, 我仍然是對第一版情有獨鍾, 因此第二版僅挑著第一版照顧不到的內容看了看. 

另-建議各位讀者朋友: 在剛剛開始學習Linux時, 最好在電腦中只裝一個Linux, Ubuntu也好, CentOS也罷(不過我個人還是比較推薦使用Ubuntu作為桌面作業系統), 此時最好完全摒棄Windows的觀念, 日常只用Linux, 最多不超過一個月就開始對Linux與命令列有感覺了!

2)Linux程式設計: 這部分當然還是首推W.Richard Stevens的三部書了,《Unix 環境高階程式設計》, 《Unix網路程式設計-卷I-聯網套接字》,《Unix網路程式設計-卷II-程序間通訊》, 但是這三本書內容深刻, 而且卷帙浩繁, 組織龐大. 俗話說"沒有三兩三, 休想過樑山”, 沒有非常熟練的Linux/Unix作業系統基礎, 沒有一定的Linux程式設計基礎, 這三本書是不容易讀懂的, 因此在這三部饕餮盛宴之前, 我首先推薦一碟開胃小菜《Linux程式設計》. 但是這四部書的內容並不一定需要全部讀完的, 《Linux程式設計》中有三分之一的內容是不需要讀的(像終端控制, gtk/gnome程式設計什麼的), APUE的重點是前18章, UNP卷I重點是TCP與UDP程式設計的內容, UNP卷II主要講解System V與Posix兩種IPC程序間通訊的方式, 但是這兩種IPC方式的內容大致是想通的, 像兩者都有共享記憶體, 訊號量, 訊息佇列等, 因此學會Linux/Unix程式設計的思想與原理就好, API的具體用法多查一下MAN手冊就好了, 有了這些基礎之後我建議再讀一讀遊雙老師的《高效能Linux伺服器程式設計》, 這本書深入淺出的講述了編寫Linux伺服器程式的理論基礎與實踐經驗, 而且還介紹瞭如何編寫伺服器的測試程式以及開發Linux伺服器程式的常用工具等很有實際意義的內容, 非常值得一讀; 而且這部書還重點介紹了Linux中的重型武器Epool, 並與select/pool進行了應用層與理論層的對比, 這是APUE與UNP所不具備的, 且這也是面試的重點之一! 對於學有餘力的朋友我在推薦一部Linux與C++程式設計領域的神作《Linux多執行緒服務端程式設計 -使用Muduo網路庫》, 陳碩老師在書中不僅介紹了使用C++進行Linux分散式網路伺服器程式設計的常用技法, 而且還總結了使用C++進行程式設計的經驗教訓, 而且這些問題還都是面試時常考的(像string的幾種實現模式等), 無奈本人兩方面的基礎較淺, 只能挑著一些比較簡單的主題研讀一番..

和學習Linux開發環境一樣, 我也比較推薦在學習Linux程式設計時不要僅僅看書, 我在剛剛開始學習Linux程式設計時, 由於大三課程較緊, 因此只是讀書很少實踐, 到後來感覺這樣學習效果很差, 到後來在我準備自己的面試專案MyHttpd的時候竟然不敢動手去寫, 因此在這兒我著重推薦C++教程網的兩部視訊"Linux系統程式設計”與"Linux網路程式設計”, 後來我結合視訊與書籍, 不斷的去實踐, 並將重要的內容總結成部落格並發表出來(連結); 當然C++教程網也出了很多其他內容的視訊, 像"跟我一起學C++”, "自己動手寫FTP”等,內容很充實, 能夠學到的知識很多, 但是都是價格不菲, 而且我只看了系統程式設計與網路程式設計部分, 因此其他的我不便推薦, 希望以後有時間能夠把C++教程網的視訊都能夠學完, 到時候自己的程式設計功力肯定能夠提升一個層次. 還有就是現在傳智播客也開設了C++課程, 我在淘寶上買了他們那邊第三期和第四期的視訊,而且我也仔細學習了他們的Linux基礎程式設計與Linux高階程式設計的視訊教程,但是說實話真是乏善可陳,而且有很多內容我感覺傳智播客的老師是在學了C++教程網的視訊再現炒現賣給他們學生上課的, 因此在此我並不推薦看這些視訊(由於我拿不出法律可依的證據, 只是對比他們兩方的授課內容相似, 即使錯誤之處亦相同, 因此如果不相信的朋友就權當我是在意淫吧).

資料結構與演算法

這方面我準備的時間最長, 花費的心血較多, 從2012年入學直到現在(2015年5月份)我都一直在持續不斷的補充自己資料結構與演算法方面的知識. 這方面我感覺比較經典的書是《資料結構與演算法-維斯(C++版)》和《演算法導論》, 維斯的書非常的棒, 無論是理論還是實踐都有非常多的亮點, 而且這部書還有C語言版與Java版,總有一款適合你(*^_^*); 《演算法導論》大名鼎鼎,其內容就不用我贅述了, 而且我也只讀了部分的內容, 像連結串列,樹,圖,紅黑樹等,在此也是沒有資格推薦的.

面試時連結串列,樹, 排序與Hash的內容考察較多, 尤其是與STL的內部實現相結合來考察(既考察了C++常用技法, 又考察了資料結構與演算法的內容,一舉兩得). 關於資料結構與演算法部分的面試,有三部書不得不推薦一下《劍指offer》,《程式設計之美》和《程式設計珠璣》, 還有一個網站LeetCode(連結). 這些內容都是都是我從很多面經中總結出來的, 尤其是LeetCode, 裡面一些很讚的面試真題, 沒事的時候建議刷一下.

最後關於”資料結構與演算法”的學習, 我建議最好在網上找些這方面的視訊結合著書看, 因為這部分比較費腦子, 書看累了的時候就可以看些視訊, 敲敲程式碼, 幫助消化.而且在我看來, 一個準備在IT領域有所作為的程式設計師/工程師, 資料結構與演算法的是無論何時都是不能放下的, 在這兒我推薦一篇Google工程師的部落格, 我記得當時我看完之後頗受感染, 不知道大家有什麼感受(連結).

計算機網路(TCP/IP)

關於TCP/IP,面試的時候問得頗多, 類似TCP的11種狀態, TIME_WAIT狀態的原因, TCP三次握手的原因等. 可以看出網路層與傳輸層(重點是TCP)的內容是重點, 如果按照優先順序對TCP/IP進行排序的話, 應該是傳輸層>網路層>鏈路層, 關於計算機網路, 我看的書有《計算機網路(謝希仁著)》與《計算機網路聯考複習指導(王道)》,《TCP/IP詳解-卷I》只挑了重點的幾章內容(本來是打算把這整本書仔細研讀一遍的, 但由於時間不足, 這個願望一直未能實現, 打算等到在阿里實習結束,本科畢業之前一定好好的把這部經典讀完). 在面試結束後的一個月內, 我自己根據這次面試的經過以及結合自己讀到的面經的內容, 自己總結了四篇TCP/IP的部落格, 個人感覺有志於進入網際網路公司的讀者朋友可以讀一下(連結).

作業系統(OS)

關於作業系統, 重點在於程序管理與記憶體管理這兩章, 再加上SPOOLing等一些零零碎碎的內容. 作業系統我感覺比較不錯的書籍有《現代作業系統》,《作業系統聯考複習指導(王道)》與《計算機作業系統(湯子瀛)》;《現代作業系統》我只看了有限的幾章,《作業系統聯考複習指導(王道)》我讀了兩遍, 估計大家也看出來了, 這本書與前面提到的《計算機網路聯考複習指導(王道)》都是考研書, 但是但是考研類的書往往對課本內容的重點總結的比較精確. 像這本作業系統, 我就感覺對OS重點總結是比較精確, 當然經過壓縮之後有些問題也是有些闡述不明(像記憶體管理中的頁式管理和段頁式管理等), 但其他的內容感覺總結的確實是挺到位的(因此我的幾篇作業系統的部落格就是以王道的書為藍本,再結合面試中常考的知識點寫成的, 不過現在還未發表, 因為排版整理的工作還未完成, 不過他們會最終發到這個目錄下面:連結). 最後一本書是我們的上課時的課本,個人感覺這本書還是挺靠譜的, 但是有些內容有些囉嗦, 學院派氣味很濃, 有些問題本來舉個例子就可以闡明的卻用了一大段晦澀難懂的描述性文字, 讓人似懂非懂. 

我學習作業系統與計算機網路的有一點心得是: 感覺兩者很類似, 都是內容很零碎, 但又都不很難; 因此, 他們的學習最好與系統程式設計/網路程式設計結合起來學習, 這樣就會有一番更深深的體會.

另-如果大家對Linux核心比較感興趣而且實力足夠的話,建議讀一下《Linux核心的設計與實現》或《Linux核心原始碼情景剖析》,前者內容較難, 我只讀了有限的幾章, 而後者的總頁數超過1000頁, 這兩部書有很大的毅力來讀的...

用兵一時

3月7號(2015年)磊哥把我的簡歷推到YunOS, 3月12(週二)晚七點參加一面, 3月13(週三)下午三點參加二面, 隔了一週3月20號(週三)晚八點參加三面, 3月24號(週日)參加四面, 3月30號收到offer.

前面說過, 我從來沒有想到這次面試會這麼順利, 很早以前我就做好了前幾家面試會被打擊的準備, 而且這次面試又是這麼倉促, 從簡歷推上去到真正面試只有三四天的準備時間, 還要一直提心吊膽不知道啥時候一個電話打來就要面試,終於在磊哥的一頓催促之下, 阿里那邊的人在我返校之後的第五天晚上,開始了面試:

一面:

一面問得問題有: (1)TCP三次握手過程, 與為啥需要採用三次握手; (2)TCP TIME_WAIT狀態的原因; (3)C++ 虛擬函式機制(C++物件模型); (4)C++ Static關鍵字; (5)Select/Poll/Epoll的異同(使用與內部實現方面); (6)C++迭代器失效問題(iterator原理); (7)map/set容器的實現原理(紅黑樹知識+STL容器內部原理);

前面的這幾個問題比較簡單, 回答的都比較流暢, 估計面試官打算在最後一題發難吧, 最後一個系統設計題難度陡然提高, 一下子就沒了感覺, 題的內容是 "現在有兩塊記憶體, 一塊10G設名為A, 一塊20G設名為B, 現在A中資料已滿, 但還有新的資料到來, 因此只能轉向B寫入, 但是還需要把A中的內容做資料遷移, 移動到B, 那麼現在問題來了: 如何保證在不打斷新資料寫入的前提下, 將記憶體A中的資料完整的遷移到B, 即不能出現在A中資料遷移完成之前B記憶體滿了或者打斷新資料輸入的情況”, 這個問題糾纏了十多分鐘, 我嘗試了從資料結構和作業系統的角度去解決這個問題, 但都被面試官否決了, 直到現在這道題我仍然不知道該如何解決.

二面:

二面問得問題有: (1)我的部落格的訪問量的問題(估計是暖場吧); (2)Linux 夥伴堆演算法(slab)實現的原理, 以及與普通記憶體分配相比有什麼優勢(Linux核心); (3)Linux 高併發的實現, 執行緒池的實現思想, 怎樣處理高併發(根據專案來問); (4) Linux 寫一個併發測試程式; (5) 如何實現一個String, 他的記憶體是長什麼樣的(STL內部實現);

記得當時二面面試官打電話過來的時候還在上課, 跟老師匆匆說明情況之後就找了一間空教室開始面試. 與一面面試官的和藹不同, 二面面試官剛開始問得問題就咄咄逼人(相對較難),而且在我回答問題時還曾經不止一次被他打斷. 由於題目相對較難(也可能是我自己水平不足)感覺需要思考一段時間才能回答, 而且有好幾個問題是我以前沒有接觸過的(像題目2, 題目4, 題目5), 我只能憑自己的理解去回答, 面試還未結束, 我就感覺這次面試的結果有點兒懸, 可能過不了這一關了... 但當時心裡倒是很坦然, 由於剛開始就沒有打算能夠通過, 因此也就沒有那種"天生我材必有用”或那種"此處不留爺,自有留爺處,處處不留爺, 爺去投八路”的氣概,只是覺得過不了就過不了,大不了從頭再來.面試到最後, 我問面試官是哪個部門的, 回答說是"阿里雲·雲端計算”部門,突然感覺今天被虐成渣不怨了, 心想如果這次面試通不過, 下次直接投雲端計算部門, 不投YunOS了, 後來跟同學說起這個想法,他說我是被虐瘋了.

二面結束之後給磊哥發了一簡訊, 跟他說今天面試感覺不是太好.估計通不過了, 磊哥卻說面試應該不會就此停下, 但是可能會中間再加一輪技術面, 由原來的三面變成四面.  原因是在我一面快結束時問了一下面試官對我的評價, 面試官除了說我真正的專案經驗不足之外又說"大三能夠有這樣的紮實的基礎已經相當不錯了”, 褒獎之意溢於言表, 估計面試官給的評價應該不錯, 因此如果二面面試官給箇中評的話,那我就應該能夠順利的進入HR終面, 但如果是差評的話, 那就估計還要再加一輪技術面, 給出一個最終的技術評價.果不其然, 在等了一週之後, 三面來了...

三面:

在三面正式開始之前, 我先問了一句是技術面還是HR面, "是技術面”. 內心頓時緊張起來,但面試官告訴我不用緊張,放鬆就好,只是聊一下我這邊的具體情況, 果然三面30多分鐘基本上都是處於比較輕鬆的氛圍之中. 問得問題有:我常用的資料結構有哪些, 對未來有什麼打算, 對杭州有什麼印象, 有沒有女朋友, 有沒有在杭州長期居住的打算,如果我去杭州的話, 我女朋友怎麼辦等等, 由於面試官很健談, 後來又聊起了邏輯思維與追求完美的話題, 總的來說, 這一面並不如前兩面那樣技術氛圍濃厚, 面試官也特別和藹(由於面試官在正式面試之前曾經放過我鴿子, 面試開始時面試官竟然還不住給我道歉,真是受寵若驚了...), 後來面試官把他的兩個聯絡方式都留給了我, 讓我有什麼就可以直接聯絡他, 後來在收到offer後聯絡團隊時還跟面試官通過幾次電話, 求面試官老師幫忙, 面試官老師在百忙之中還幫我聯絡HR , 告訴我該如何更快的融入團隊.. 說實話, 真的非常感謝這位面試官.

四面:

四面是HR面, 萬萬沒想到的是HR老師竟然在周天下午打電話過來, 當時剛剛打完羽毛球, 上氣不接下氣的接了HR的電話, 然後直接開始面試. 這次面試基本沒問技術方面的問題, 由於我說了我的部落格, 因此HR老師也看了一下我的部落格, 見訪問量還比較高, 我謙虛的說"可能是由於寫的東西都比較基礎, 因此看的人比較多吧O(∩_∩)O~~”; 然後又問到為什麼不打算讀研了; 在大學期間遇到的最大的困難是什麼, 是怎麼解決的; 除了上課,在大學裡其他的時間都在幹嘛等等. 總的來說, 這次面試雖然不涉及技術, 但大部分問題都是不太好答的, 因此, 在此建議大家在日常生活中對生活對一些思考, 不僅僅是為了應付HR, 更要活的明白一些.

四面結束之後, 自我感覺不錯, 果不其然在第二週的週一, 收到offer通知, 知道自己的阿里面試算是可以告一段落了.

最後再說一下: 在每次面試快要結束時, 面試官都會讓你問他/她一個或幾個問題, 或者你自己主動問個問題, 在這兒我比較推薦的一個問題是"在您看來, 在阿里(當然是目標公司)如果要勝任一份工程師的工作, 他/她需要怎麼樣的能力或素質, 或者說如果我還想繼續應聘這個工作, 我還需要做那些努力”, 這個問題暗含了三層意思:一是對我這次面試結果的詢問, 二是我該如何努力彌補自己的不足,三是表達了你對這份工作的渴望,希望能夠勝任或者獲得這份工作. 我在四次面試中都主動或被動的問到了這個問題, 四面的面試官各自給出了自己的答案, 雖然答案各異, 但是綜合起來能夠得出一個對自己綜合評價,同時,也能夠知道為接下來迎接下一輪面試或者參加工作該做哪方面的努力, 因此我感覺這個問題還是比較好的.

真正開始

不出意外7月份就要去杭州了, 由於得知自己進入的是YunOS手機作業系統團隊, 師兄給出的建議是學習一下Java以及Android的內容, 因此需要把接下來這兩個月的學習規劃一下了, 這兩個月的學習我將其劃分為三個方面: Java, 資料結構與演算法(Java), Android程式設計.

最後, 還有幸到今年山東ACM省賽上當了一把裁判, 開了眼界, 也圓了自己在三年之前”到ACM賽場打一場醬油”的心願...

    以後的路還很長, 人生之路才剛剛開頭, 走出大學, 才算真正的開始...