2022 轉職前端的海外求職與面試心得 (Amazon 與 ByteDance/TikTok 等)

2023年3月15日

💎 加入 E+ 成長計畫 與超過 300+ 位軟體工程師一同在社群中成長,並且獲得更多的軟體工程學習資源

嗨,相信妳會點入這篇文章,可能是因為妳看到轉職前端的標題,也可能是有海外求職的打算。在往下讀之前請先讓我介紹自己,以及說說這篇心得會談些什麼。假如妳有覺得符合妳的需求再往下讀,可能比較不會浪費時間 (因為文章會有點長 XD)。

我的背景是大學讀文組,在 2020 年初透過 Alpha Camp 的實戰課程轉職軟體業 (Alpha Camp 是一個線上 coding bootcamp,詳見此)。2021 年時,在有約一年半開發經驗時首次海外求職 (心得詳見去年寫的這兩篇文章,《2021 轉職前端工程師的海外求職 (德荷英日新) 心得 I — coding bootcamp 之後的能力養成篇》《2021 轉職前端工程師的海外求職 (德荷英日新) 心得 II — 找工作與面試篇》)

去年後來去了一間在柏林的新創公司,不過在待了一年後因為一些原因,所以決定換工作 (詳見這篇反思)。今年 (2022 年中旬) 算是帶著兩年半經驗展開第二波海外求職之旅。今年這篇文章會先聊申請與準備概要,接著會分享實際的面試經驗。這篇適合的讀者,可能是 2 - 3 年經驗的中階工程師。如果是剛從 coding bootcamp 出來的工程師,我會比較推薦讀我去年寫的那兩篇。

求職歷程概述

雖說我先前在德國的公司,但今年德國的大公司反而都沒有拿到任何面試 (例如 SAP、DeliveryHero 等)。另外就是,在德國或歐洲的軟體工程師工作機會很多,但是大公司的機會沒有比較多 (雖然有不少各行各業的大公司,但多數都不是以軟體為主),畢竟大公司也就只有那幾間。所以我這次主要還是透過 LinkedIn 搜尋,然後被轉去各大公司的招募官網自己投遞。而我的投法,基本上是不看地點,覺得適切的職位就申請;因為對我來說,這階段的目標是先進大廠,任何地點的大廠都可以。

而我這次自身經驗是有拿到 Amazon (英國倫敦)、Booking.com (荷蘭)、Twitch (APAC 遠端)、ByteDance/TikTok (新加坡)、Shopee (新加坡) 等大公司的 OA 或面試。最後有錄取 Amazon 與 ByteDance/TikTok。

從結果而論,雖然我有錄取 FAANG 公司,也錄取目前世界最大獨角獸公司,但連面試都沒發給我的公司不勝枚舉 (基本上你想得到的國際軟體大公司我都投了)。這讓我深刻體會到,在不穩定的大環境下求職,真的蠻大一部分的因素不在自己的掌握中。舉例來說,今年新加坡我也有投 Foodpanda,然後連面試都沒有拿到,而在我投的當週,就看到他們新加坡辦公室大裁員。而新加坡 Shopee 雖然有拿到面試,但 OA 與一面結束後,等了快三週沒收到回覆,然後就看到新聞報導出他們大裁員 (九月底時),所以就沒有後續。

因此,很可能不是因為個人的學經歷、面試表現導致沒拿到面試或沒錄取;申請者能做的,就是把履歷編修到最好、面試準備充足,然後在機會來的時候,用盡全力把握住。

準備過程

這次我的準備分成兩個部分,一部分是加強前端,因為 ByteDance 類的公司在這部分會問得很深入。我是直接找考古題,可以去稀土掘金上面找,或是上網搜「字節跳動面經」等面試心得。前端除了知識點外,也很常考前端白板題。前端白板題基本上就是能夠自己寫出各類效用函式 (例如 debouncecurrydeepClone 等等),以及能自己寫出 Promise.all 這類方法。假如不知道怎麼寫的話,我在準備這次面試時,有整理了最常考的手寫題與解答,歡迎參考《前端面試 — 常考的 JavaScript 手寫題總彙整》

除此之外,我也有特別針對各個過去有使用過的函式庫,去了解背後實作的原理。我去年就有被問到 Redux 的效能問題以及如何改善,假如沒有理解 Redux 是如何被實作出來,就沒辦法跟面試官深度討論如何改善其效能。這個準備方向也讓我今年在面試,被問到 React Query 背後如何實作時,有辦法跟面試官有一定深度的討論。

另一部分則是資料結構與演算法白板題。去年我在準備時,先讀過一次《Cracking the Coding Interview》,然後還看完 AlgoExpert 上的 160 題演算法題。也因為去年有花這些時間打基礎,我今年就沒有再用那兩個資源,而是直接買 LeetCode Premium 來刷。會買 Premium 主要兩個原因,一個是可以看到公司的標籤,這點是基於我去年的慘痛教訓,去年面 Shopee 新加坡被問到的演算法題,是該公司在 LeetCode 上的高頻題,結果我沒刷到,當下寫不出來,面試就掛掉了。另一個買 Premium 原因是跑程式碼比較快,寫錯了重跑也不會有冷卻時間,畢竟時間就是金錢,這點我覺得很有價值。

對於我去年寫的資料結構與演算法準備心得,今年的我仍然會推薦 Google 工程師 NeetCode 的頻道 (它現在有出付費課程,但我覺得免費的 NeetCode 150 就非常足夠)。今年我額外推薦 Netflix 的資深工程師 ThePrimeagen 在 Frontend Masters 上面開的演算法課程《The Last Algorithms Course You’ll Need》。Frontend Masters 其他課程要訂閱費才能看,但這堂課是完全免費的 (非常佛心)。我覺得跟著 ThePrimeagen 的思考脈絡,會對資料結構與演算法有新的一層理解,所以很推薦要打底的人可以上。

在練習刷題時,一定要練習邊寫邊講 (think aloud)。溝通思路可說是跟解題一樣重要 (這篇文章提到,題有解出來以為會過面試,結果後來沒過,因為被認為溝通太差)。剛好 ExplainThis 的另一個共筆作者也有在準備刷題,所以我們每週末都會約一次幫彼此模擬面試。在實際面試前,我刷了約兩個月,總共刷了快三百題 (幾乎平均一天五題),其中一半以上是 Medium,次之是 Easy,Hard 沒有寫太多。

最後,我在這次的準備過程中,也陸續整理了一些筆記,有興趣的人可以逛逛本站 explainthis.io (未來會持續新增,歡迎關注)。以下分享各間公司的面試心得。

ByteDance/TikTok

ByteDance 是我最早面試的大廠,我面的是 TikTok 某個組的前端職位。這次面試下來,對 ByteDance 的印象就是效率非常驚人、速度非常快,早上投履歷,下午收到面試邀約。每一輪也都是結束不到一小時,就收到下一輪的面試邀約。如果沒有特別排比較晚的面試時間,ByteDance 應該可以在兩週內完成面試。ByteDance 已經是十萬人以上規模的公司,還能維持這種效率與速度,怪不得底下的產品這幾年海放競爭對手 (例如 TikTok 最近搞得 Snap 與 Meta 股價慘慘慘)。因為 ByteDance 在面試部分沒特別簽保密條款,加上網上多半也都直接分享題目,這邊我也直接把遇到的提列出來。

一面 (資深工程師)

一開始先請我自我介紹,我有分享我轉職的過程,有被問「決定轉工程師後,為什麼轉職前端? 」。接著針對履歷提問主要是針對過往專案與產品提問 (對過去用過的技術務必要好好複習),以及有問「做過最有挑戰的專案」。

履歷提問完後就是一連串的知識問答題。先從 React 開始問,先問了用過哪些 Hooks,然後追問 useEffect 的實作 (如網上的面經,在面 ByteDance 這類大廠,不能只會用某個東西,還需要能說出背後是如何實踐的),具體追問了 dependency array 用途、背後機制,然後追問為什麼 dependency array 是空的時候只會在 component mount 時執行、後面不執行? 如果 dependency array 傳入物件或陣列會怎麼樣? 如果傳入 ref 會如何? 然後問 useLayoutEffectuseEffect 差別?分別適合的場景為何?

React 問完後問了比較基礎的網路問題,主要針對 HTTP 提問,後面有追問 HTTP caching 的機制。追問 eTagLast Modified 哪個優先? 為什麼? 追問 304 的 response body 是什麼? 為什麼是如此? (這題算陷阱題,因為 304 沒有 response body,關於 HTTP caching 的題目,可參考這篇)。

網路問題後換 JavaScript 題。這時就開啟了線上 IDE (ByteDance 用自家的 Lark,裡面可以一邊視訊一邊用線上 IDE,很方便)。進到 IDE 後,面試官先貼了一段程式碼,要我在不執行的狀況下,說出程式碼的輸出是什麼 。基本上熟悉 Event Loop 與 Micro-task、Macro-task 運作,這題都能答對 (詳見這篇)。判讀題我有順利答對,於是接著進到 JavaScript 白板題,是要實作出 lodash 的 .get ,我也順利寫出來 (有興趣的可以看 《請實現 Lodash 的 .get()》

總的來說是密度很高的一場面試,60 分鐘問好問滿,有過往經歷問題、有知識類問題 (JavaScript、React、網路題都包含) 以及有手寫類的白板題,算是很全面的一場面試。

二面 (團隊的用人主管)

自我介紹後,針對履歷提出一些技術討論,有特別問我過去寫單元測試、E2E 測試的經驗。接著就進到知識類的問題,包含問了 JavaScript 中 Map 物件與一般物件有什麼差別?都是鍵值對,為什麼已經有了物件,後面還需要加入 Map? (這篇寫很清楚推薦讀讀)

接著問了前端的各種趨勢類問題 (我講了蠻多最近社群討論熱烈的 Solid、Fresh、Qwik 等,以及他們解決了哪些其他前端框架遇到的問題)。然後因為我是寫 React,被問到對 React 18 的理解。知識類的題告一段落後,最後由一題白板題結尾,是一題 LeetCode Medium 難度的字串處理,花了二十分鐘左右順利寫出來。

三面 (整個大組的技術主管)

這個面試跟前沒兩關不太一樣,沒有自我介紹,一開始就直接來一題 LeetCode Medium,基本上是 3Sum 的變化題。因為是很熟的題型,所以我蠻快就解完了。解完後問 React 的問題,主要問 React Fiber 是為了解決什麼過去的問題? 是如何實作的? 因為這題算是高頻考古題,所以也有順利答出來。接著問網路題,也是 HTTP 不過是針對 HTTPs 的 s 問,也是題高頻考古題。最後有一題前端的系統設計題,花了二十分鐘左右討論如何設計一個 Typeahead 的前端。

三場技術面試下來,覺得 ByteDance 的面試真的很扎實,基本上每一關都有前端題與演算法題,而且三關著重的方向都稍有不同;三關下來從 JavaScript、React、CS 知識點,到前端的趨勢與系統設計,幾乎涵蓋了各類題型。

四面 (人資)

順利通過三關技術面試後,最後進到人資關。這關是由我面試的組的 HRBP 來面。HRBP 有再介紹一下 ByteDance 的文化、我面的組在做的事。網路上也有不少人資關被刷掉的經歷分享,所以這關也不能掉以輕心,各類行為面試的問題要好好準備。人資問的問題背後主要是看跟 ByteDance 文化的契合度,所以事先讀一下公司文化會很有幫助。

在人資面之後一週後收到錄取通知。TA 也在通知時跟我說三輪技術面試的面試官分別給的反饋,三輪的反饋都蠻一致的,對我的溝通能力、前端知識掌握度、實際寫程式能力 (白板題) 三輪都是正面評價。但其中兩個面試官有提到因為我過去沒有實際做過大規模的產品,所以在經驗這塊他們會覺得還需要多累積。這個反饋其實正是我今年想要申請大廠的主要原因,我轉工程師兩年半來,做過最大的產品用戶量級也不過日活二十萬; TikTok 這種破億用戶量級的產品,真的是我缺少的經驗。

Amazon

Amazon 我這次是海投數個不同辦公室,結果唯一兩個拿到 OA 與面試的,都在英國,一個是在愛丁堡辦公室,另一個是倫敦辦公室。有趣的是,一個是先 OA 後,沒有 Phone Screen 直接 virtual onsite,另一個則是先 Phone Screen 後,沒有 OA 直接進 virtual onsite。virtual onsite 都是五輪的車輪戰,可以選一天面完,或分成兩個半天。因為我先前有連續面試經驗,所以我很清楚一天三場面試是我的極限,所以我都選分兩天。

特別備註,我投的都是前端工程師 (Front End Engineer 簡稱 FEE),而不是常見的軟體開發工程師 (Software Development Engineer 簡稱 SDE)。 我在倫敦辦公室的 Phone Screen 輪有稍微跟面試官聊到,他說 SDE 基本上是全端,而 FEE 就是專注在前端。在 Amazon 這兩者是有機會在內部申請轉換的,那個面試官當初就是 SDE 進到 Amazon,但做了幾年後想專注在前端,就轉成 FEE。

面試的部分 SDE 跟 FEE 有些部分一樣,但另一些地方不同。同樣的地方是每輪都有一半是會問他們的 Leadership Principles 問題,也都會考資料結構與演算法。不同的地方是,FEE 可能會針對前端的知識點與實作來考。舉例來說,在網路上有找到別人的面經是要當場實作一個元件。另外就是系統設計的部分,SDE 會考設計一個 Twitter,但是 FEE 則會是設計一個 Twitter 的前端 (想了解更多的話,非常推薦這篇談論前端系統設計的概覽)。

愛丁堡辦公室 OA

這次遇到的 OA 是兩題 LeetCode Medium 難度的題。第一題我是用 Quick Select 來解;另一題是二維陣列題目,這題可以 BFS 也可以 DFS,我是用 BFS 解。有趣的是,這個 OA 除了解題,還要妳用文字寫下思路,以及分析時間與空間複雜度。

話說在 LeetCode 的討論區中,很多人會回報自己 OA 遇到的題目,舉例來說,在討論區搜尋 Amazon Online Assessment 可以看到我遇到的這兩題,過去都有人回報有遇到。假如妳有拿到 Amazon 的 OA,推薦先去練習 LeetCode 討論區被回報的題目,很可能會有一樣的。特別注意,Amazon OA 是用 HackerRank,所以題目描述都很長,因此蠻推薦做之前先到 HackerRank 熟悉一下它們的題目描述方式以及平台的操作 。

倫敦辦公室 Phone Screen

剛剛結束 Amazon 倫敦的 Phone Screen 輪,前面先是兩題 Leadership Principles (LP) 題 (Amazon 的模式似乎都是這樣),然後面試官都會一直追問。我先前就有在網路看到說,面 Amazon 在這部分一定要做足準備。實際面完的經驗是覺得,不能只練習網路上找得到的題目,還需要練習後面的追問。

接著是兩題白板題,大概都是 LeetCode Easy 到 Medium 的程度。之前在網路上看到 Google 面試是直接用 Google doc (而不是線上 IDE),Amazon 的 Phone Screen 也是蠻類似的,就是一個類似記事本的,然後沒有任何功能。這兩題都沒有實際跑結果,感覺是以看思考過程為主 (先前面 ByteDance,因為就是實際在一個線上 IDE 所以都會實際跑面試官給的測試案例)。因為兩題白板都沒有太難,我都有順利寫出來 (起碼面試官說邏輯沒問題)。

這場 Phone Screen 讓我意識到我之前太依賴 IDE 的方便了 (因為我 LeetCode 有買 Premium,所以變得平常刷題也像是在 IDE 上寫),所以這場之後在為實際面試準備時,我都先練習在 Google doc 上面。

Virtual Onsite

在分別通過前面輪次後,我申請的兩個團隊的招募協調員 (Recruitment Coordinator) 分別跟我約時間。但在喬時間的過程,他們內部似乎發現我同時在面兩個團隊,所以後來就來信跟我說其中一個的最後一輪會取消,不用面兩次,而是假如沒取消的那個有面過的話,最後會再分別跟兩個團隊的 Hiring Manager 談要選擇進哪個團隊。必須說 Amazon 的招募員真的蠻雷的,敲定好面試的日期後,到面試前一天晚上才來信告知確切時間……。不過 Amazon 的每個面試官都非常專業,面試體驗非常之好。

雖說我是面 FEE,但面試只有一關是由 Amazon 的 FEE 面,兩關是 SDE,一關是 SDM 來面。因為有簽面試的保密條款,不能分享詳細遇到的題目,以下僅分享每一關的經驗。

一面

面試官是 SDE,但他說他現在有約一半時間會做前端的東西,所以也會幫忙面 FEE。如同網路上看到幾乎所有 Amazon 的 onsite 面試經驗,果不其然一開始就來了兩題 LP 題。接著進到前端實作,要做某個元件,可以用任何技術或框架 (我用 React)。雖然不能說實際做什麼元件,不過假如網路上找的元件類題目都練過 (例如 Menu、Carousel、Accordion 等等等),這關就不會是太大問題。

我特別喜歡這關面試的地方在於,實作完後接著有一連串的追問,讓前端面試變得很有脈絡。雖然不能說被追問了什麼題目,但假如上面我提到準備 ByteDance 的前端知識點都夠熟,這些問題一定回答得出來。不過 ByteDance 在問的時候都是很獨立的問題,例如上面提到我在 ByteDance 面試有被問「一般物件跟 Map 有什麼差別」,假如只是這樣獨立問,我覺得在準備上就會有點像在背誦。但假如是寫了某個元件,然後用到了物件,這時被問為什麼不用 Map,然後兩者間有什麼區別,我覺得就會有脈絡許多。

二面

面試官是 FEE。也是一開始就兩題 LP 題,然後進到前端白板題。跟上一關不同,這關是比較偏向寫演算法,但不是傳統 LeetCode 那類的,而是像要寫出某個框架提供的 API (某個函式),算是我過去沒碰過的題型。如果要具體準備這類問題,可能可以多去看一些套件或框架的原始碼,看看那些平常很常用到的 API 背後是如何實作的。我這關表現的沒第一關好,雖然最後有寫出來,但上一關有被問到如何優化程式碼,這關則是寫完後時間就到,沒有時間去優化解法。

三面

面試官是 SDE,他說他很喜歡 React 所以工作上也會去做前端的東西,但因為想讓自己比較有彈性,所以沒有轉成 FEE,而是持續做 SDE。這關是很傳統的資料結構與演算法題。當然前面也是先來個兩題 LP 題,講完後就進到算法的題目。一開始第一題是蠻中規中矩,用 DFS 或 BFS 就可以解的題目。解完後被問延伸問題,是要用 topological sort 來解。剛好我在面試前兩週有刷了 LeetCode 上面的 Course Schedule 系列題,所以被問到延伸題時,就覺得題型很熟悉。只能說 Blind 75 這類經典題一定要每個題型都刷,對於各種類型與模式有概念,起碼在面試時能有個底來面對變化題。

另外,因為不會執行程式,所以寫完後,面試官都有請我用測試資料口頭走過一次我的演算法。在這種類型的面試,對自己寫的邏輯一定要夠清楚,不能像平常寫程式會依賴 debugger。面完後覺得好險前面有 Phone Screen 輪,讓我意識到要練習用這種形式。

四面

面試官是 SDM,也是用人主管 (hiring manager)。這關是唯一沒有寫程式的,但有類似前端系統設計的題目 (只是不是傳統類型的)。一開始面試官先連續三題 LP 題 (將近三十分鐘)。接著是問類似系統設計的問題,會說是類似,是因為跟在網路上看到的題不太一樣,但某些部分又一樣。

因為不能提細節,只能說如果要準備這關,我會推薦多了解千萬日活用戶級別的產品,在前端的部分要怎麼確保低延遲 (low latenecy)、高可用 (high availability)、高可靠 (high reliability)、安全性 (security),以及在千萬日活用戶級別的產品上一個前端的功能,要怎麼規劃整個流程等等。

這邊蠻推薦大家可以平常多去看各家大廠是如何做事的,因為我這個 Loop Interview 是面 Amazon 的倫敦辦公室,我在面試前有用平常吃飯時間爬他們的各種東西,然後就看到 YouTube 上的這個介紹倫敦辦公室的影片。影片中有提到為了確保高可用性,Amazon 在上一個功能前,前端會測試幾百種不同裝置,確保都是可用的。因為看過那個影片,我在回答可用性的部分,有提了一個類似的作法,從反應上來看,面試官似乎對我的回答很滿意,那時我心裡暗自竊喜「畢竟這就是你們的作法呀 XDD」

面試後也是約一週左右收到結果,聽到招募員說恭喜時,真的是又驚又喜;跟 ByteDance 不同,Amazon 的招募員說沒辦法給每關的具體反饋,不過有說每關的面試官反饋都很正面。以前都是看別人轉職後進到 FAANG 公司的分享文,沒想到轉職兩年半後,我也能聽到 FAANG 公司的招募員跟我說恭喜錄取。如上面提到,因為我本來是同時有拿到兩個組的 onsite,所以後續還分別跟不同的用人主管聊,聊完後選完組,招募員才會發正式的 offer,然後談薪水。在跟 Amazon 談薪水時,有成功爭取到提高 offer,相關經驗都記錄在《拿到 offer 後談薪水 — 讓我多談 35% 的談薪筆記》

Twitch

我是在找新加坡的職缺時看到的,不是一般的前端職缺,職位的名稱是叫 Software Development Engineer, Customer Success。雖然是申請新加坡的職缺,但時面試都是跟美國那邊的人面。同樣是在亞洲區的缺,比起前面提到 ByteDance 的神速,Twitch 的動作就慢了不少,每一輪幾乎都是等一到兩週才通知結果。

一面 (人資)

這關基本上都是問求職動機、過去經歷。人資也有更詳細介紹這職位,我聽下來感覺是介於 Software Development Engineer 與 Customer Sucess Engineer 之間的工作。工作內容以前端為重,但也會有牽涉到後端的部分,所以職位還是歸在 SDE。在更深入瞭解後,人資有再向我確認有想申請,然後說後續會再聯繫。

二面 (資深工程師)

二面一開始也是問過去經歷,問題包含過去做過最讓自己引以為傲的專案、解決溝通衝突的經驗等等。特別注意,因為這個職位不是純開發,而是有部分時間要直接跟客戶合作,協助客戶整合 Amazon IVS 的服務 (這個職位在 Twitch,但產品是 Amazon IVS)。

接著問了不同程式語言的使用經驗 (直譯語言、編譯語言),也問了不同瀏覽器的差異 (例如不同瀏覽器的引擎之間的差異),然後也問了前端效能優化問題。最後以一題白板題收尾,easy 到 medium,搭配 Stack 這個資料結構就可以蠻容易解掉。

二面後一週收到沒有進到下一輪的通知,不確定原因是什麼,畢竟二面不論在行為面試或技術面試,我覺得表現的都還不錯,不會比我面 ByteDance 或 Amazon 還差,特別是效能優化題我覺得講得夠深夠廣、白板題解得很順。但面試就是這樣,總有各種原因導致沒辦法往下一階段邁進。

Shopee

假如你有讀過我去年的面試經驗文,應該會看到去年我在 Shopee 二面的時候,在一題設計 LRU Cache 的資料結構題炸掉。今年想說再挑戰一次,投了履歷後也順利拿到面試。跟去年一樣先從 OA 開始,然後三輪技術面。我順利的通過前兩關,只是面到一半時,Shopee 似乎就大裁員,雖然感覺他們最近不太會招人,不過還是分享一下我前兩關被問到的題目。

OA

字串長度要如何取得

  • 這題是單選題,選項中有各種語言的語法,要選出 JavaScript 的
  • 相信寫 JavaScript 的人應該不會選錯,這邊附上 MDN 的文件當參考

考 JavaScript 的物件觀念 (題目中的值不一樣,但概念一樣)

const x = { a: 20, b: 22 };
const y = x;

y.a = 30;
delete y.b;

console.log(x.a, x.b); // 30, undefined

考陣列基礎概念 (題目中的值不一樣,但概念一樣)

var a = [];
a.push("b");
a[20] = 22;
a[20] = undefined;

console.log(a.length); // 21,因為有 index 0 到 index 20,共 21 個

考字串基礎概念 (題目中的值不一樣,但概念一樣)

a = "explain this";
a[0] = "i";

console.log(a[0]); // 'e' 因為 'explain this' 這字串的值本身沒辦法改

手寫題一:寫一個函式轉換以下資料格式 (題目中的值不一樣,但概念一樣)


輸入:
{
  scheme: "https",
  domain: "www.explainthis.io",
  path: "item/search",
  queryParams: {
    page: 1,
    keyword: "shoes"
  }
}

輸出:
https://www.explainthis.io/items/search?page=1&keyword=shoes

輸入:
{
  scheme: "https",
  domain: "www.explainthis.io",
}

輸出:
https://www.explainthis.io

最後一題跟我去年蝦皮 OA 被問到的一模一樣,是網路上找得到的 Maximum sum of non-leaf nodes among all levels of the given binary tree

一面

一開始先請我介紹自己,接著就針對我的履歷開始問問題。因為我在上一間公司與上上一間公司,分別有用過 React Query 跟 Redux,就被問了這兩個工具做狀態管理的差異相關問題,有被追問這兩個工具要如何做選擇。回答完後被接著追問 React Query 是如何實作的。這邊要感謝先前在前端版看到有版大分享的《了解 SWR 的運作機制,How this async state manager works》一文,先前在理解這類套件的背後的實作時,這篇算是很清楚好懂的入門。

然後面試官接著問說「既然我們都聊到 cache,不如就來實作一個吧」。然後就開啟線上編輯器,進到手寫題的部分。這次的手寫題第一題,是我去年 Shopee 一面的 cache 題進化版。簡單來說,需要寫出一個 cached 的函式,下面這個是我去年面試時寫出來的,而去年的題目也就停在這邊。

function cached(fn) {
  const cache = {};

  return (...args) => {
    const key = JSON.stringify(args);

    if (key in cache) {
      return cache[key];
    } else {
      const val = fn(...args);
      cache[key] = val;
      return val;
    }
  };
}

上面這個寫法會有個問題,就是假如今天傳進來的引數是有函式的,用這個方法就會出錯。今年這一題的其中一個測試案例,就是有函式作為引數的 (但去年沒有)。那要怎麼解決這問題呢? 我當時提說可以透過深比較 (deep equal) 來解決。面試官說,的確是一個解法,那不如你就寫一個深比較吧。於是我又繼續往下寫了一個深比較的函式,才順利通過這一題 (有興趣了解怎麼寫的人,蠻推薦這個影片的)。只能說,lodash 有提供的效用函式,手寫題真的是前端面試必練的。

接著進到第二題,是要寫一個改良版的 Promise.allPromise.all 會要等到所有的實現,因此它的瓶頸會是最晚回來的那個,如果最慢那個拖很久,其他的也會要跟著等。但是這個改良版想做到的,是不要等全部實現,但又要做到有順序性的回傳結果。因為我先前練習過 Promise.allPromise.race 等題目的手寫,所以遇到這個變化題時,還算有辦法應付。只能說許多 JavaScript 提供的方便東西,平時還是需要懂背後如何實踐,不然面試被問時,我在想如果我先前沒練習過相似的東西,應該很難在二十分鐘想出來又寫出來。

二面

去年我 Shopee 掛在二面,今年還想說把去年沒寫出來的 LRU cache 寫個五遍,把 Doubly Linked List 的操作與題目都練很熟。結果一面之後 Shopee 新加坡就裁員。必須說,去年跟今年面試起來 Shopee 新加坡的面試算蠻有鑑別度的。不過現實世界就是只有技術沒有用,如果沒有永續的商業模式,最終還是撐不起一家企業。

Booking.com

OA

時間有 100 分鐘,要用 Vanilla JS 寫一個能做到 CRUD 的前端 (類似 Todo List)。因為我過去兩年都寫 React,所以 Vanilla JS 變的不太熟,雖然題目很簡單,但我的程式碼寫得很亂,被刷掉我也覺得合情合理。有要申請 Booking.com 的人,如果平常工作上都用框架,申請前要先好好補強 Vanilla JS,才不會跟我一樣簡單的東西還寫得很亂。

Datafold

如開頭提到,我今年的目標是進大廠,所以會面試 Datafold 其實是個意料之外的事,因為 Datafold 目前是在 A 輪融資階段。會接觸到 Datafold,是因為在歐洲有個很有名的軟體工程作家 Gergely Orosz (很推薦大家追蹤他) 經營一個叫 Pragmatic Engineer 的網站,而該網站有個 Talent Collective 的人才庫。你可以申請讓自己的履歷被登入在人才庫,然後該作家精挑細選的公司如果覺得你是適合他們的人才,就會主動聯繫你。被聯繫後你可以選擇要不要跟他們面試。

Datafold 就是他們的人資透過那個人才庫聯繫我。雖然我今年求職目標是大公司,但因為 Datafold 是 YC 孵化的公司,加上創辦人本身是技術背景且有大廠經驗,加上職位是全球遠端 + 美國薪水 (Datafold 前端工程師開的年薪是底薪 11 萬到 20 萬美元之間,基本上對於我的年資來說,是比各間大廠在歐洲區的薪水都還高)。總之因為這些條件,讓我覺得是個值得一試的機會,所以就面了。而這也是我今年唯一面的一間新創公司。

一面 (人資)

都是問過去經驗為主,假如有準備 behavior interview 應該這輪不會有太大問題。有被問到對於下一份工作的看法,因為 Datafold 算仍在新創階段,所以可能講的方向要偏向那方面一點 (例如想要在迭代快一點的環境,想要有更大的影響力不想在大公司當小螺絲釘云云)。

二面 (工程主管)

也都是以過去經驗為主,會針對履歷上的技術點多挖一點。一面跟二面雖然都是問過去經驗,但二面會比較是技術類的經驗,例如會針對過去寫測試的經驗問 (例如問單元測試、E2E 測試的概念與我過去實作的經驗等)。這關也會有一大部分時間讓候選人問問題,我覺得整個面試有很雙向的感覺 (就是真的深聊去了解彼此適不適合)。

三面 (資深前端工程師)

這關是技術面試,一開始先針對履歷問,因為這關是我面完 Amazon 隔週面的,所以剛準備完 Amazon LP 題,在這關的履歷問題就答的特別深入,感覺面試官覺得我分享的故事很不錯。LP 完之後是一個 code review 問題。

四面 (技術長)

這關也是技術面試,是我當工程師以來,最特別的一場技術面試。在一開始簡單自我介紹後,被問到 React Hook 的問題,我概略地分享我的想法後,面試官就問說「你有想過怎麼實現 React 的這些 Hook 嗎?」,這時我就先舉 useState 為例,然後講了一下我會如何實現;初步說完,面試官就說「不然我們來實際寫一下吧」,這時我心裡想,沒想到這麼硬,要當場寫出 React Hook。

這時面試官竟然分享了自己的畫面,我一時納悶他為何分享畫面,原來要寫的人不是我是他。這真的是非常非常特別的面試,因為過去每場我遇過的技術面試,都是作為候選人的我寫,沒想到竟然會遇到一場是面試官寫。總之我們就花了約五十分鐘開始 pair programming。在過程中每寫完一個段落,面試官就會提問題,例如「如果我們有多個 useState 要如何確保在重新渲染時,原本的值會被記得且不會亂掉」,然後我就回答我的想法,就在這樣一來一往中,把 useState 實現出來。

回頭看,我覺得我非常非常喜歡這場面試。因為是面試官寫,某種程度上我的臨場壓力小了非常多;但同時因為過程中面試官會一直提問,所以他也能有效考察我對 JavaScript 與 React 的理解,以及我的思考。過去很常聽人說把面試當成 pair programming,這場面試真的是我面過各類面試中,最有 pair programming 感覺的了。

同時這個面試方式也讓我強烈感受到這個技術長的實力,作為一間做 data 產品的公司,該技術長的強項不是前端,但通過他的提問,我可以很直接感受到他如何思考,讓我有「厲害的工程師,即使不是自己最常碰的領域,還是可以透過思考讓自己在該領域有一定深度」的讚嘆;以及他實際在寫時,我看他寫的程式碼,就覺得他寫得真好。總之在這個互動過程後,我最直接的想法是「要是我跟著這個人一起工作,我一定能成長很多」。必須說,如果往後有人問我理想的面試形式,我絕對會提跟 Datafold 的這一場。

面試小結

前端工程各家大廠面試都不太一樣,但如果用最高標準來準備每個面向,那不管遇到哪類都不怕。前端知識點用 ByteDance 的標準,在面對其他間的前端知識問題就覺得相對容易;刷題用 FAANG 的標準,在面其他公司時的刷題就覺得相對容易。

當然,用高標準來準備不是件輕鬆的事,特別是對前端工程師來說,深入的知識點、刷題在工作上很常沒有直接的應用性,很可能在準備時就覺得「反正工作上用不到」就不讀或不刷;然而就像運動員需要有大量而枯燥乏味的體能與重量訓練,才有辦法在自己的專項上有好的基礎,準備面試過程讀到比較深的東西時,如果願意直球面對,把那些深入的知識點搞懂、把那些艱澀的題刷過,在面試時就能夠比別的候選人有更紮實的基礎、更突出的表現。

寫在最後,感謝的話

和去年的文章結尾一樣,最後免不了要說感謝的話。在準備面試上,真的是依靠前人們在網路上的分享,才讓我能比較有方向性地準備。寫這篇文也是希望能夠回饋社群,讓未來要面試的人有更多資料點能參考。當然如上面提到,很多時候大環境影響的因素更大,所以我的經驗也不必然適用正在面試的妳/你,在閱讀後還請多斟酌是否參考。

感謝讀到最後的妳/你,也祝正在準備面試的每位開發者,都能在準備的過程中一步步踏實地向前邁進,最終拿到自己心中理想的機會 🙂

🧵 如果你想收到最即時的內容更新,可以在 FacebookInstagram 上追蹤我們