Facebook Software Engineer Interview

先說一下結論,我人在台灣,去年年尾開始面試美國 Facebook 的 Software Engineer ,今年初拿到 offer ,最近剛確認抽到工作簽證 H-1B,接下來一切順利的話十月就會到加州總部上班。

對我的背景有興趣請直接參考 Linkedin ,就不多說明了。這篇文章主要想解釋一下我經歷的 hiring process (每次都要解釋很麻煩),還有一些準備的心得,有興趣的人可以參考,也希望有志到美國科技公司工作但沒有任何概念的人心裡有個底。應該會寫得非常瑣碎,因為這其實也是我的筆記,希望自己將來需要再經歷一次求職時能夠快速找回準備面試的心情。

準備海外面試很辛苦,除了英文以外,資訊來源不多、身邊的人不了解自己在做什麼,光是支援系統就差很多。我很幸運有個在美國念書工作的學姊丹,從她在找工作時就和我分享很多想法,即使如此當自己實際開始準備也還是有很多手足無措,過程中靠她幫了很多忙。有人理解自己的壓力是很大的幫助,因此歡迎正在準備面試的人連絡我,但我很懶惰,不歡迎伸手牌,除非你是我朋友,否則希望做過一點功課再來。

也先打個預防針,我只面過這一家美國公司,沒在美國念過書,接觸各種資訊的來源有限,大多資訊來自個人經驗、丹的傾囊相授以及 Google ;實際上我對於所有事情的了解都很少,這裡全部是我個人的想法,是不是有用就請大家自行判斷了。

另外,如果有人有興趣投歐美新加坡的 Facebook 的 mobile, front-end 相關職缺,也歡迎來信,雖然還沒正式進去,但有機會的話我可以把你介紹給在裡面的朋友。

以下正文

根據我的了解,美國科技公司的招聘流程大概是這樣:

  • 內部推薦或是海投(海投被連絡上的機率非常小)
  • 被 recruiter 連絡
  • 和 recruiter 簡單 phone interview
  • 一到兩場 technical phone interview ,通常考一兩題程式題
  • 一到兩場 onsite interview ,一場可能有很多輪不同主題
  • Wait for result
  • Congratulations! or sorry :(

通常是在這上面有一些變化,我的流程差不多就是這樣。

選 team 部分, Facebook 有個知名的方式 Bootcamp program ,每個新進的 engineer 要先經過六週的洗禮,在六週內了解公司內不同 project 和 codebases ,甚至接受任務、實際 fix some bugs 。 Bootcamp 結束後,每個人可以選擇想要加入的 team 。因為所有 engineer 之後都會經過這個過程,所以一開始拿到 offer 時的頭銜都是 Software Engineer 。雖然如此,招聘時還是會有特定方向,我投的是 iOS Engineer ,所有面試過程中的問題和 coding 都是以作為 iOS Engineer 的角色來準備和回答。

我的申請流程從去年十月底開始,當時得知 Facebook 有一場亞洲區招募,會到亞洲進行 onsite interview ,主要是 mobile 相關職缺。主要資訊來源是在加州 Facebook 工作的學長。

Timeline 大致是這樣

10/28 PST 是這次招募的 deadline ,當天下午送出 referral

11/3 收到 recruiter 的訊息

11/4 和 recruiter 第一次通話,最後問我 11/21 以後可以的日期和時段

11/9 敲定 phone Interview 時間

12/6 Phone Interview

12/15 收到 recruiter 通知通過 phone Interview ,並於當天下午通話說明 onsite 相關細節,並確認二月初 onsite

1/17 敲定 onsite interview 日期 ,各個部門開始聯絡我處理飯店機票報帳事宜

2/5 飛往新加坡

2/6 Onsite interview ,隔天飛回台灣

2/17 Recruiter 通知 offer got ,問我想要去美國的哪個 office

2/24 簽 offer ,開始準備 H1-B 申請資料

4/1 確認送出 H-1B petition

4/25 收到 H1-B receipt ,暗示我有被抽到

5/27 收到 H1-B approval

面試準備過程心得

參考閱讀

參考網站

準備面試:履歷

我自己從以前就一直使用單頁式英文簡歷,也斷斷續續有在更新、或是有幫忙看別人履歷的經驗,雖然不是說真的寫多好,但也還算小有經驗。
我不打算鉅細靡遺教學要怎麼寫履歷,這種事情讓 Google 來教就好。這邊說一些我覺得重要的心態和 tips 。

我認為寫履歷前應該思考的事情是:如果我是 recruiter ,看履歷時會想看什麼?怎麼樣的履歷我會覺得是好的?

換位思考對我來說一直都滿難的,雖然有時候能夠因此找到自己的盲點,但大多時候還是很茫然。也因此寫履歷給別人看很重要,只有自己看的話常常會寫出自我感覺良好的東西,不管是整體或是句子的文法方面。我請好幾個朋友幫忙看過,常常從別人的問題裡得到一些 insights ,當別人問說「你這句話是這個意思嗎?」「你這裡寫這個要做什麼?」,才能更意識到自己的履歷在別人眼裡看起來是這個樣子啊。當然也有時會自我感覺良好地覺得你看不懂是你不懂啦!總之得到 insights 以後還是要努力去客觀消化。

接下來提供一些我看履歷時重視的點,當然都不完全客觀,更多是我的個人偏好,我假想自己是 recruiter 時希望看到這些,因此寫出這些。 Recruiter 百百種,每個人想的也不太一樣,並沒有一個標準答案。

格式部分

  • 排版乾淨明確,可以一眼看到重要的點有哪些
  • 愈重要的東西放愈前面
  • 時態統一,關於時態要過去式還是現在式,有幾種不同的說法,例如:
    • 全部過去式
    • 全部現在式
    • 現在工作用現在式、過去工作用過去式
    • 過去完成的事情用過去式、達成的成就用現在式

不管哪種時態用法,至少選一種有邏輯的方式,不要讓人看得很混亂。

內容部分

CC189 書中建議的書寫方式是 "Accomplished X by implementing Y which led to Z" ,寫清楚目的、方法和結果,結果最好能以數據化方式呈現。例如:

  • 「我改寫了公司網站的前端」
  • 「我用某某技術改寫公司網站的前端、並使瀏覽人次上升 10 %」

前者看完只會想說:「喔。」後者看起來有說服力多了吧!

另外,「愈重要的東西放愈前面」在這邊也適用,一句話最重要的部分最好放前面一點,例如 “Use Python to implement something” 建議改成 “Implement something using Python” ,畢竟這句話裡最重要的應該是 implement something 而不是 use Python 。這個原則也可以反過來操作,希望哪一點特別被關注、就放前面一點,像上面那個例子,假如希望被關注的是 Python 技能,也許可以考慮把 Python 在前面。

就像我前面說的一樣,寫完履歷最好拿給別人看一下,別人看不懂也沒關係,再改就好了,現在做什麼都要 agile 一下,寫履歷也是個一次一次往前推進的過程。

投履歷

就我所知想得到美國公司的面試機會,有人幫忙內部推薦的成功機會還是大一些,自己上網投 20 家都不一定有一家被看見。以公司的角度來看這樣的作法很合理,每天接到的來路不明申請這麼多,要花多少時間人力才能一個個篩選?內部推薦至少已經經過自己員工的第一階段篩選了,成功機會大一些。recruit 一個人的成本是很高的,我們想要成功拿到 offer ,公司也想要成功 hire 到對的人。另外,內部推薦的好處還有有人可以追蹤目前狀態,不會像海投一樣老是石沈大海。

所以如果有朋友在想去的公司裡,最好是請朋友 refer 。網路上也可以找到一些中國論壇提供一整套找工作支援,從履歷、面試準備、到找人 refer 都有,如果真的沒有朋友支援,可以試著找找看。不過找陌生人 refer 的風險對於自己和對方而言都大一點,畢竟你們不了解彼此;就我所知 refer 並不是單純附上履歷就好, refer 的人還是要填一些背景資料,例如怎麼認識、共事經驗、對這個人的看法等等。這部份也是要看運氣、看碰到的人願意幫忙多少,有些人會直接把表單丟給你填,有些人會幫忙修改。

準備面試: Recruiter Interview

履歷送出去後,幸運的話會接到 recruiter 的聯繫。通常會問一些背景資料、做些簡單的自我介紹,雖然 recruiter 通常沒有技術背景,還是可能被問一些基本的技術題。如果沒什麼問題的話, recruiter 會說明招募流程、並安排 phone interview 。

我一開始收到 recruiter 的信,回信以後隔天就接到電話,直接開始聊、被問問題,表現得不太好, recruiter 跟我說我可能不夠 qualified ,但還是願意幫我安排面試試試看。事後丹告訴我說最好是先約好再開始,即使他直接打來,也可以和他說現在不方便、約個時間聊,才不會這麼措手不及。好好提出需求,recruiter 基本上都願意幫忙,畢竟他也想成功 hire 你啊(業績啊!)。

準備面試:Phone Interview

Phone interview 敲定後,有大約一個月的準備時間。Phone Interview 通常是一兩題 coding ,也就是 LeetCode 上的演算法類型題。面試方式視公司而定,一般大多是 online coding ,使用一個 collaborative editor 邊向 interviewer 解釋邊寫給他看。

一般來說一場面試的進行大概是這樣:

  • warm up ,聊聊相關背景、問一些基本知識
  • 進入正題
  • 提問時間

所以準備問題也很重要!根據 CC189 所說,可以問的問題的類型包括:

Genuine Questions: These are the questions you actually want to know

Insightful Questions: These questions are designed to demonstrate your deep knowledge of programming or technologies

Passion Questions: These questions are designed to demonstrate your passion for technology

總之要先準備一些自己關心的問題用來問,才不會在 interviewer 問有沒有問題時腦袋一片空白。一些比較常見的問題:

  • What’s a typical day of this job?
  • How do they work with each other?
  • What do you enjoy most about working here?

接下來進入正題,關於 coding 解題流程網路上有很多資料,我的方法參考自這個網站 HiredInTech’s Training Camp for Coding Interviews,整理一下大概的流程是:

  • 問問題、釐清題目
  • 問問題過程中了解 constraints 、列出 test cases
  • 開始解釋可以用什麼演算法、計算 time complexity
    • 如果一開始只能想到很暴力的解也沒關係,先講出來,爭取時間也尋找靈感,記得說明自己知道這個不夠好,要繼續想有沒有更好的
  • 覺得演算法夠好了以後開始寫
  • 寫的過程最好可以說明自己在幹嘛
  • 寫完拿幾個前面列的 test cases 來跑跑看

準備 coding interview 的方法百百種,每個人都應該評估自己的狀況適合什麼,這邊分享一些準備時的心路歷程。

一般最常聽到別人說的準備方式就是刷題,把 LeetCode 的題目來回刷幾遍,刷到很熟悉。如果是以前的我準備面試,可能也會選擇這個方法,看起來簡單有效。

我很慶幸在自己準備面試前,曾經旁觀過丹的準備過程,接收很多她對於準備面試的想法。於是我也開始思考,刷題真的是最有效的方法嗎?從刷題的過程中我想要得到什麼?多半是對題目熟悉度、敏感度,就像小時候大考前狂做考古題一樣。但這些是面試裡最重要的部份嗎?

平心而論我很喜歡解題,但後來發現喜歡解題更多是自我安慰的成就感,看著完成題數一點點增加也會有小小的踏實感。

但其實對於題型慢慢熟悉以後,繼續解題的效果就有限了。 Coding interview 需要的不只是解題能力,我認為同樣重要的是解題過程以及溝通能力。想想如果自己是 intervierer 在 interview 一個人,會想要看到什麼?看對方獨自埋頭苦思解出題目嗎?或是想聽他說出他的解題思路?

退一百萬步想,就算練習再充分,還是有機會遇上解不開的超級難題,這時你會希望自己埋頭苦思最後發現完全解不開(或是方向完全錯誤), time’s up! 還是希望 interviewer 至少知道你思考了哪些錯誤的方向、甚至因此提示正確的方向?就像小時候解數學題,如果只寫答案,錯了就是錯了,老師甚至不知道你懂到哪裡;但如果寫下解題過程,老師就可以了解你大致上明白,只是某個地方出了小錯。

解題能力可以靠著刷題來訓練,其他部分呢?思考至此,我明白自己需要練習的地方是能夠邊解題邊說出思路。再加上刷題是個漫漫長路,我明白自己耐性有限,我無法像很多人一樣日夜刷題,也很容易忘記刷過的題目。要記住這些題目對我來說 effort 太大、時間也不夠。

最後我的練習方法大致是:去找別人分享的面經(考古題),針對那些題目來練習解題、練習講解,模擬自己正在進行 coding interview,這是對我而言比較有效率的作法。我還是有練習解題,但不是寫完所以題目,只寫別人整理的高頻題。

分享這些並不是認為自己的練習方法多好、別人刷題都是笨蛋,我知道很多人能夠靠刷題來得到 offer ,但我做不到、時間也不允許,我認為大家都可以試著找出適合自己當下情況的方法。

在準備過程中其實我也一直有修正,例如原本想要天天和別人練習解題,但壓力太大了,早上練習後那一整天都變成廢物,後來就放棄這件事。但有跟人一起練習過還是很重要,丹指出很多我說詞上可以改進的地方,對我實際上陣很有幫助。

另外一件事是我面試語言用 Swift ,但其實有一段時間沒寫了,練習時也順便記語法,把一些常用 function 另外整理成一份 note 以便面試時偷看(反正是線上)。不過其實語法不算是重點,表明忘記語法時大多能通融,知道概念就好(像是 C++ 的 string.at() 在 Java 是 String.charAt() )。當然一些基礎語法能記住還是最好。

還有簡單準備的是一個比較特別的部分,一些常用數學的英文說法XDD 誰知道 C5 取 2 的英文怎麼講啊!(我已經不記得了)還有排列、組合之類的,練習時發現就可以稍微記錄一下。

我的 phone interview 時間在台灣時間早上八點(加州時間下午四點),我提早一個小時起床 warm up ,不過和我約好要陪我 warm up 的人在加州的丹睡過頭,我只好對著電腦自言自語來讓腦袋清醒。

Interviewer 先和我聊了十分鐘左右,問我 iOS 相關經驗、還有一些 iOS 相關基本題。接下來寫了兩題 coding 題,不過第二題最後來不及寫完。

準備面試:Onsite Interview

等了十天左右,通過 phone interview ,接下來就是 onsite interview 了。很快就半敲定 onsite interview 日期會在大約一個半月後。我的 onsite interview 內容是一個下午總共四場,由四個不同的 interviewer 主持,類型有 coding, system design and conversation 。

由於是亞洲區招募,我飛到新加坡去進行 onsite interview ,飛去新加坡的一切花費都由公司提供,因此收據都要留好。這些地方也讓人很深刻感受到美國公司有多尊重 candidate,即使我可能不會被錄取。而因為 hiring 成本很高,每個階段都會好好篩選人,也不會故意刁難人,畢竟他們已經在 candidate 身上花了這麼多錢,是真的很希望能夠順利 hire 到這個人。

聽過有些台灣公司在履歷階段不嚴格把關,喜歡隨便叫人去公司面試,最後發現經歷根本不適合,除了浪費彼此時間外也浪費 candidate 的交通成本;也聽過有公司招募海外 new grad (尚未畢業)叫人家自費買機票飛回來面試。幸好我沒有遇過這樣的公司,但這方面台灣公司還是有很長的路要走啊。

面試是下午開始,我前一晚抵達新加坡,住在 office 附近的飯店,可以充分休息後再戰。面試的會議室有一個大大的白板和大大的落地窗。

建議面試前如果有先拿到 interviewer 的名字,可以先去偷估狗一下,了解對方的背景也好準備要問的問題。

Coding

Coding 和 phone interview 同樣類型,差別在從線上變成白板,所以這部份我進行的練習比較少,只特別多練習在白板上寫 code 的手感、還有多記住語法(因為不能偷查)。

要注意的是白板上無法輕易 insert code ,開始寫之前最好注意一下,空間也有限,雖然它看起來很大,但白板最上面......我根本就寫不到啊!

好處是在白板上能表達的事情比較多,例如在解釋演算法、解 tree 的題目時,可以用畫的還是比較方便(BTW 準備 phone interview 時我有稍微練習在 editor 上畫 tree,真的很難畫)。

Coding 的準備還算容易, system design 和 conversation 讓我非常苦手,難以練習。

System Design

這部份我參考同一個網站的 system design 部分:HiredInTech’s Training Camp for Coding Interviews

解題過程基本上和 coding interview 的概念一樣:

  • 釐清題目、了解 constraints 和 use cases
  • 提出 abstract design
  • 解釋這個 design 的 bottleneck 在哪裡
  • scale the abstract design

聽起來很抽象,我也覺得很抽象。
如果有過自己開發過專案 from scratch 的經驗,應該會比較了解這邊要問的是什麼,我雖然有過一些經驗,但沒有題目還是很難練習。

尤其 system design 比起 coding 有更多的 trade-offs , depends on 各種時空背景,
換成面試當下,這些背景條件都是由 interviewer 提供,就表示這個面試非常 depends on 和 interviewer 的互動。

網路上流傳的經典題是設計一個 URL shortener ,但我面試 iOS developer ,題目偏向 app design ,我覺得上面的流程有點難完全應用,主要有用到的大概只有「先釐清題目再開始設計」這個概念。

因為太沒方向了,我做的練習大致上是回頭思考自己過去開發過哪些 app 、怎麼開始、遇到過哪些問題、怎麼解決。這裡的準備工作對我來說很依靠經驗,練習中我大概列出我設計 app 時的大方向:

  • Layer: presentation layer, business layer and service layer
  • 除了上述三層以外,還有 data model
  • 有哪些 service :一般會有 web service & data storage service
  • Web service 相關
    • 如何實作 async requests
    • 資料交換機制(我常用 RESTful API)
    • 資料交換格式(我常用 JSON)
    • 如何實作 session (例如登入)
  • Data storage 相關
    • 有哪些資料必須存下來
    • cache
  • Presentation 相關
    • 怎麼更新資料
    • 怎麼用 UITableView 顯示列表資料

準備這些資料以後,接下來就是找一些題目來練習怎麼順利講出來。有人討論也許會比較容易練習,但這部份我實在太迷茫,練習過一次十分混亂就有點不好意思,後來大多還是自己練習。

Conversation

Conversation 是我最不拿手的部份,一來英文不夠好、二來不習慣回想、三來不擅長表達。丹給我的建議是,想想如果我是 interviewer ,我想知道關於對方的什麼事、會問什麼問題來得到想要的資訊、期待得到什麼回答?想像我是 interviewer 的話會想聽到什麼?Put yourself in the shoes of the interviewer.

可以參考 HiredInTech’s Training Camp for Coding Interviews 。這個我沒有細看,不過這個網站其他部分寫很好,所以這部份應該也值得參考。

這部份的準備對我來說最辛苦也痛苦,根據網路上一些教戰守則,我列出自己工作以後的年表,列出參與過哪些專案,慢慢回想專案內容是什麼、我做了什麼、發生哪些事,想起一些當年做的很好的事、也想起一些當年後悔沒做好的事。

某個想不起來在哪看到的文章建議針對每個參與過的專案,列出這些事情:

  • Nature
  • Backstory
  • Problem & how to solve
  • What I have learned
  • Technically challenging

CC189 則建議針對專案列出這些:

  • Most challenging
  • What you learned
  • Most interesting
  • Hardest bug
  • Enjoyed most
  • Conflicts with teammates

要參考哪個都行,裡面其實也有些概念是重複的,可以盡量多想一些事情來放進這些點裡面。列出事情以後,它們就是素材了。

首先,從這些素材中選擇一些來組成自己的自我介紹,自我介紹最好可以在 30 秒到 1 分鐘完成,就像傳說中的 Elevator Pitch 一樣,挑選重要的事情來吸引對方注意,細節都可以留待最後看對方有沒有興趣繼續聽,甚至可以直接問對方想不想聽。

接下來準備一些經典問題的回答,例如:

  • Why do you want to be an iOS engineer?
  • Why do you want to work here?

準備回答內容時也練習不斷去猜想 interviewer 想得到什麼答案。因為不是所有問題都能預測,所以把素材們記下來,練習遇到什麼問題都能挑出東西來回答、甚至把問題轉個方向回答,轉到自己準備過的方向去。有時 interviewer 也只是想聽聽你怎麼解釋一些事情而已,與其發楞,想辦法拗到能解釋的方向吧。

這些地方需要的就是大量練習,最好和別人練習,和丹練習時她也讓我發現開始面試前先和別人簡單用英文聊聊天很重要,放鬆心情、習慣使用英文,接下來會比較順利。

話雖這麼說,我這場面試還是爆了QQ

後續

Onsite interview 結束後癱軟一晚,就飛回台灣、放鬆等待結果,等待期間處理一下報帳問題。

據說 Facebook 通常一週左右就會通知結果,我等了十天左右收到 offer 。一般來說拿到 offer 才是 neogotiation 的開始,但我沒有這方面的經驗,問了學長他表示 package 很合理,考慮兩三天也就樂得直接接受了。

確定接受 offer 以後也快三月了,馬上開始跑申請 H-1B 簽證的流程。美國 H-1B 簽證一次三年、可以延長到最多六年,每年 4/1 開始接受申請並進行抽籤,所以三月就會開始收集申請資料。四月底開始陸續通知結果,只會通知有抽到的,所以等到最後都沒有才能確定沒抽到。確定抽到以後會開始處理申請,成功以後 10/1 生效。

公司這邊委託律師事務所來辦理簽證,三月間事務所的人負責向我收集資料、並更新近況。今年碰上川普取消 H-1B Premium Processing ,原本事務所告知我通知日期會延後、可能五月底以後才會開始知道抽籤結果。但我運氣不錯,四月底就收到通知說抽到了!

接下來就是等待簽證生效、搬家去加州了。 Facebook 會 cover 我的 relocation 相關花費、也會關照我一開始的住宿,以前聽到矽谷大公司這麼照顧員工覺得很神奇,現在還是覺得很神奇。當然在飛去加州前還要通過 AIT 面試、和 Facebook 討論我的 relocation package ,出國真的是各種雜工啊。


如果有人耐心看到這裡,謝謝你~~,我自己都不見得這麼有耐心~~。我花了很多時間翻看那段日子的日記,努力回憶並記錄下來這些,可能不一定有用,但如果能對任何人有任何一點點的幫助,我會很開心。

雖然看起來我很幸運,第一次投美國公司就上了,但其實我在愛爾蘭打工度假期間投過不少公司,幾乎全部都被拒絕,也累積過不少被拒經驗。當初要投 Facebook 時也很擔心,如果進不了下一關怎麼辦?如果害推薦我的人顏面掃地怎麼辦?最重要的大概還是調整心態,知道自己有很多地方不足也不要害怕,誠實面對它然後加強它或是放棄它吧。

講得這麼厲害,想到要去美國還是有點緊張,雖然有過在愛爾蘭生活的經驗,但畢竟當時都在耍廢,現在可是直接去開始工作了,實在擔心壓力很大。面試結束只是一切的開始,希望可以順利活下去啊!

聽說 Facebook 有名的壓力山大,最近在研究要住哪裡的時候看到這篇:I am moving from NYC to SF to work for Facebook at their Menlo Park office. What neighborhood should I live in? What are some general tips/advice? - Quora

裡面的回答提到:

Facebook will keep you working most of the day and night.

豪抖啊~~~~~~~~~~