矽谷程式設計師求職指北:準備篇(連載1)
作為一個cs留學生,在求職季節,我面試過幾乎美國所有最熱門的公司,最後也順利拿到了Google、Facebook等大部分公司的offer。在公司分佈上,既有FLAG等一線巨頭,也有Wework等當紅獨角獸公司,還有一些剛起步的創業公司;在城市分佈上,它們在東岸的紐約、西岸的矽谷和西雅圖,都是科技公司最聚集的地方;在流程上,既有簡歷都不過關的時候,也有據offer後被對方團隊強烈挽留的時候。
所以,這段求職經歷給了我很多不同的體驗,我想在這篇文章中跟你分享一下,在美國找一份軟體工程師工作是怎麼樣的體驗,以及如何準備這些公司的面試。

1、準備篇:厚積而薄發
臺上一分鐘,臺下十年功。這句話用來形容面試非常貼切。
很多人的關注點在短短的幾十分鐘面試過程,去研究“面試技巧”,比如說怎麼觀察面試官的臉色、怎麼隨機應變、有什麼流程套路等等。這些東西雖然重要(這篇文章後面也會講到),但也沒那麼重要,其實更重要的是在面試之前,你是否做了充足的準備。
首先說點 抽象層面 的東西。
在面試一個候選人的時候,對於能力的要求重要性大概是這樣的:智商 > 情商 > 經驗(知識和技能),這是對於應屆畢業生的考察。而如果是對於有工作經驗的人(社招),或者對創業型小公司來說,重要性排序可能就是這樣的了:經驗(知識和技能)> 智商 > 情商。當然這裡說的是美國,所以還有一個必備的條件,就是“工作簽證”,沒有合法的工作身份,就算你是比爾蓋茨般的神童,也沒有哪個公司敢招你。
怎麼理解這三個能力?
智商。 並不是說需要你有愛因斯坦一樣爆表的IQ,這裡指的是:是否具有 從事軟體開發工作所需要的正常智商水平 ,畢竟軟體開發也是一個腦力密集型行業。怎麼考察智商呢?不是給你做一個IQ測試,而是通過學校背景、成績、過往專案、面試表現,看出候選人的資質如何。在專業的計算機競賽中有不錯成績的同學,更能反映了他們從事這個職業的天賦。所以像ACM等競賽獲獎的人,往往被各大企業瘋搶。Google的招聘哲學就是,把全世界最聰明的人招募進來,然後再開始想要做什麼產品。蘋果創始人喬布斯也說:我一直在找最聰明的人,和他們共事。在錢最多的兩個行業:計算機和金融,對頂尖人才的渴望都是一樣的。
情商。 程式設計師給人的印象是不善言辭,甚至有點一根筋,那為什麼要求他們有情商呢?有的人會說,你看那微信之父張小龍、谷歌創始人謝爾蓋,不都是羞澀的極客嗎?首先你得有人家那天賦異稟,看這篇文章的,應該都是平常百姓的孩子,一個凡人。然後他們只是在公眾媒體少曝光,並不代表他們私下也是書呆子一個。其實 優秀的程式設計師,一定也是一個優秀的溝通者 ,他們能快速地理解產品需求,跟團隊打好配合,最終交付一個高質量的產品。企業希望招聘的人,是一個團隊協作者,他能和團隊相互促進,面對困難能尋找幫助,也能及時幫助同事, 首先是群體中的一個人,然後才是一個軟體工程師 。在面試中,面試官會丟擲許多“行為問題”(Behavior questions),比如說:你遇到的最大困難是什麼?有沒有主導過一個專案?通過你的回答,面試官可以判斷你未來是不是一個好相處的同事,畢竟大家每天抬頭不見低頭見,選對人很重要。
經驗。 近年來,對經驗的要求是越來越高了,隨便一個招聘啟事,都寫著需要至少一年或三年以上工作經歷。 經驗,代表的是候選人具有充分的知識儲備和程式設計技能,在工作崗位上能迅速上手 。Google、Facebook這樣的大廠對經驗的要求並不高(但不是不要求),因為大廠有財力、耐心來慢慢培養新人。而中小型企業尤其看中候選人的經驗,需要來到就能幹活的人,要不然公司很快就倒閉了。比如說他們招聘一個做ios開發的工程師,而你的簡歷上相關的經驗,沒有正式工作經歷,他們根本不會考慮你。對應屆畢業生,這個要求很殘酷,畢竟在一直校園裡,哪有什麼經驗。不過呢,機會是留給有準備的人的,實習、課程專案、業餘專案都是積累經驗的渠道。
抽象的說完,再來說具體是怎麼準備的。
第一,基礎知識。 我們常說“他是科班計算機出身”,這“尊貴”的“科班”頭銜意味著什麼呢?就是紮實的基本功。
簡單來說,計算機基礎知識包括:一門熟悉的語言、計算機組成原理、作業系統、計算機網路、資料庫系統。網易公開課給計算機專業專門建立了一套系統的課程(不是廣告啊喂!),我引用他們的課程的設計,來說明一個合格的程式設計師應該具備哪些知識。
圖上的每一個課程都可以學上大半年,是不是看著都很絕望呢。不過好訊息是,理論歸理論,這裡我們說的是面試,其實並不會真的考察到這麼多知識。按我的經歷,正常的軟體工程師面試,能考到的知識就是:對一門程式語言的熟悉程度(Java/Python/JavaScript等)、網路常識、資料庫常識、系統設計常識,不會再深入了。
簡單舉個幾個栗子,對於程式語言,可能會問到:Java的抽象類和介面有啥區別呀?對於網路常識,可能問到:TCP三次握手是啥?SSL又是啥呀?對於資料庫,可能會問到:SQL和NO-SQL的區別是什麼?
考察的都是基本的常識,好好上課、好好做作業,這些知識都自然而然印在腦子上了。對於非“科班”的同學,也不必覺得毫無機會,只要認真掌握了這些知識,面試官都是一視同仁的。轉專業過來的程式設計師多著去了,他們都能在矽谷找到一份非常不錯的工作。

第二,資料結構與演算法。 前面說的智商,具體來說是做程式設計師需要的智商,主要體現在這資料結構和演算法掌握上。計算機屆有個著名的公式:程式=資料結構+演算法,一段程式程式碼在做的事情,一是怎麼儲存資料,二是怎麼操作這些資料,最終產生想要的結果。
80%的面試內容,都是在考察演算法。有一個網站,是北美找工作必不可少的,叫Leetcode,是一個集合了900多道演算法題目的網站。使用者可以線上提交自己寫的答案,Leetcode給出測試結果,以及你的演算法耗時和排名。題目來源是各大公司的真實面試題,從不同渠道洩露出來後,被放在了Leetcode網站上。
我剛來美國留學的時候,經常會聽到一個詞叫“刷題”,一直不明白什麼意思,慢慢了解之後才知道說的就是到Leetcode上做題。 這些題目幾乎覆蓋了所有可能在面試中碰到的演算法題目,所以如果想要找一份好工作的話,把網站上的大部分題目做完、做熟是基本要求 。
在刷題之前,應該系統地學習資料結構知識,掌握常見的資料結構,例如陣列、二叉樹、連結串列、雜湊表、二分查詢、深度優先搜尋、廣度優先搜尋等等,不然面對Leetcode的題目會覺得一頭霧水。在這裡推薦一本普林斯頓大學出版的《演算法》( Algorithms, 4th Edition ),一本紅皮書,內容通俗易懂,還配套了線上網站和免費視訊講解,非常良心。
除了Leetcode,也有其他選擇,例如中文版的Lintcode、HackerRank(很多公司用它做OA,類似筆試)。不過按照大多數人的經歷,美國科技公司的面試,有leetcode就夠了。
“刷題刷到什麼程度才能去面試啊?”,這是一個經常被問到的問題。對於平常人家孩子來說(ACM大神請回避),當然是越多越好,刷完最棒。但是Leetcode這些年來孜孜不倦地新增新題,以前只有200多道,一個多月就刷完了,現在已經有了900多道,而且越來越難,臣妾們都紛紛表示刷不動了。
所以刷完是不太可能了,只能挑重點來刷。好在Leetcode已經給大家分好了類,分為話題tag和公司tag,並且給出了這道題被面試問到的頻率。不過是要付費的,160刀一年,畢竟充錢才會讓你變得更強。對於Google這樣的神級公司,刷題數量是沒上限的,大部分進Google的中國學生,都把所有leetcode題目刷完且熟練掌握。而對於其他大部分公司, 把經典、高頻的三四百道題目掌握好,應付面試已經綽綽有餘 。
刷演算法題是準備面試中最重要的一步,也是最費時間精力的一步。業界有不少聲音批判這種“應試般”的面試方法,但是不可否認的是,它是目前最高效率篩選合適人才的方法。能把各種演算法題目解出來的人,都符合以下一個或多個特質:1) 非常聰明 ,對演算法題舉一反三,沒有不會做的題目;2) 非常努力 ,把900多道演算法題研究透徹,沒有一年左右的時間是不可能的,這麼專注、勤奮的人,是一個不能錯過的潛力股;3) 基本功非常紮實 ,踏踏實實地刷了那麼多演算法題的人,熟悉地掌握了各種資料結構,知道怎麼寫出高效率的程式碼,放到工業界環境,就是一個優秀的程式設計師。
對於這些人才,企業難倒放著不要,去招只會誇誇其談但程式碼都不會寫的人?因此,演算法面試依然會成為企業的主要面試方式, 好好準備演算法是求職的第一要務 。

第三,經驗積累。 面試過程中,我跟很多HR或者招人的經理(Hiring manager)聊過,一段正式的相關工作經歷,是簡歷上最有價值的地方,其次是實習經歷。 他們對經驗的重視程度是這樣的:全職相關工作 >> 實習 >> 課程(課外)專案 > 學校課程 。
從身邊的案例來看,具有正式工作經驗的人,能夠非常容易得到面試機會,甚至被獵頭、HR“求著”來面試。雖然大家都說現在是網際網路的寒冬,但是一個具有幾年全職工作經驗的人,放在美國科技就業市場,依然是非常搶手的人才。所以,如果是工作之後再過來留學的人,起碼在找工作的起點上,就領先一步了。
然後是實習經歷,也非常重要,它代表著你在工業環境中受過正規的訓練,能過適應、迅速上手工作環境。有美國名企的實習經歷,也能很容易地拿到其他名企的面試機會。在國內的實習經歷,就要看當時的HR或者面試官是否知道這家公司了,比如說BAT這種世界級的網際網路企業,知道的人會多一些。其實就是光環效應,如果面試官知道這家企業,並且認為這家企業在某個領域做得還不錯,那麼自然對面試者也多看幾眼。
所以,有心找工作的同學,還是在大學期間爭取到更好的公司實習一下吧。
如果實習經歷也沒有呢,那隻能自己多努力做一些有質量的專案了。它可以是給開源專案貢獻程式碼,也可以是一些課程專案。我認識的一些同學,給某個開源專案貢獻過程式碼,也被合併到該專案的程式碼庫了,有這樣的經歷,可以在面試中吹上好一會兒了,拿到面試甚至offer的機率都很大,因為它體現了你的綜合能力。
課程專案是每個學生都可以有的經歷,美國大學基本上都是選修制度,也就是自己可以選擇課程來上。在選擇的時候,最好選擇對工作有幫助的“硬核”課程,比如說我所在的CMU就有一門課叫雲端計算(Cloud Computing),內容都是工業界非常流行的一些技術棧,然後結合了很多實際的專案,邊學邊做。這門課非常辛苦,是CMU最難的課程之一,然而經過這個課程的洗禮之後,可以招架住絕大部分面試內容了,畢竟都是你自己親自做過的專案,聊起來也特別帶感。
最後,有同學會問,工作經驗沒有、實習沒有、課程專案也沒有,怎麼辦?嗯,那麼,同學你是真心找工作的嗎,家裡有礦的吧。