成為前端工程師的四週年回顧

我也不知道為什麼開頭要放這張,請大家自己藍色窗簾

如果你覺得這個標題似曾相識,這很正常。會寫這篇文章是因為之前看到 Lin Simon 寫了這篇:成為 UI/UX 設計師的三週年回顧

看了看時間,發現自己居然也要入行四年了!剛好最近面臨一個人生的轉折點,想說可以趁著這個機會,好好地把自己這四年的心得記錄起來。

原本想要下個不同的標題,但想了許久之後還是覺得這個標題最貼切,因此就直接用這個標題致敬原文章了。

這一篇會著重在這四年來的工作經歷以及心路歷程,文章很長,真的很長。

再次提醒,真的很長。可以把它當成故事來看就好,不要預期可以從中獲得什麼。若是你對更早以前的事(關於我如何學程式)也有興趣,可參考《自學、哲學、講學:我的程式之路》

2015 年 3 月:求職初體驗

還記得在找第一份工作的時候,我在 104 上面投了七十間公司,最後去了十五間公司面試。現在挺懷念以前瘋狂面試的那段時光,連續兩個禮拜的時間幾乎天天排滿。最滿可以排到早上一間下午兩間,剛開始覺得挺有趣,但到了後來只覺得累,發現面試也是很耗體力的。

我那時是抱持著這樣的一個想法在面試的:

說不定這是我第一次也是最後一次面試這麼多間了,因為過兩三年後搞不好我變得超厲害,都是公司主動來找我,不是我主動去找公司。

雖然說這個想法看起來很有自信,但我那時其實處在一個自我矛盾的情況之中。

一方面我覺得自己是厲害的,我對自己的能力是有自信的。雖然說不是相關科系畢業甚至連大學都沒念完,但我有自信我比一堆本科系畢業的學生更有能力。因為我寫程式寫了十年,寫過後端、前端也寫過 Mobile App,總覺得要上手一個新的技術並不是難事,只是時間問題。

但另一方面我覺得自己是很弱的,我幾乎不理解底層概念。作業系統、網路 TCP/IP、計算機組織,這些本科系的問題一問我就倒,大概只有演算法與資料結構勉強還行。雖然說寫程式寫了很久,但大多數只是自己做好玩的,完整度依舊比不上業界的專案,規模也相差許多。

當你懂的東西愈多,不懂的也會愈多。

而且那時我的朋友們都還在唸書,沒人可以跟我討論多少是合理的薪水範圍。我只能根據長期在 PTT 潛水的結果跟之前實習的公司願意開給我的薪水自己決定。

最後的結論是月薪 40k,我覺得大概值這個價。現在回頭看來簡直太低估自己,有些朋友聽到我入行時拿這個價錢還嚇了一跳,跟我說怎麼可能。但沒辦法,自己的個性就是這樣,寧可低估也不願意高估的後果就是如此。

在面試了許多公司拿到一些 offer 之後,我選擇了最想加入的一間:遊戲酒吧,那時的薪水是 38k * 13。

2015 年 4 月 13 日:正式入行

會選這間公司的原因有幾個。第一,離家超近。我家住秀朗橋頭,公司在新店慈濟醫院附近,我騎車只要過個橋就快到了,大概五分鐘就能到公司,真的超近。

最後一關跟 CEO 面試時他問我想加入的理由,我也跟他說了這個,還直接對著窗外指給他看:你看,那棟是我家,很近吧!

第二,環境。這邊指的環境有兩個,第一個是實體的環境,辦公室走一個工業風,我超喜歡,入職以後都會給朋友看辦公室的照片。

第二個指的是公司的氛圍,在面試第一關的時候與一個附中學長聊得滿開心的,第二關跟 CTO 也聊得很不錯,整個公司看起來就是一間很不錯的新創,非常合我的胃口。在我的想像中新創就是比較自由,不會有大公司的那些包袱,無論是管理風格或者是做人處事都會更輕鬆一點,而這間看起來就是這樣。

第三個原因是技術,他們願意讓我進去以後學習 Node.js。那時候我的技術棧是 PHP 跟 Android,Node.js 正紅而且很潮,身為盲目追求流行的人當然想學一下。如果可以邊上班邊學新的技術,那就太棒了。

綜合以上三個理由,遊戲酒吧成了我正式入行第一間公司,現在回頭來看,我做了一個很不錯的選擇。

入職以後的生活跟我想像中的差不多,公司平均年齡挺年輕的,而且毫不意外的我是全技術組或甚至是全公司年紀最小的正職員工(雖然看臉完全看不出來)。公司環境優美氣氛佳,員工相處融洽,上班時也沒什麼太大壓力,工時也完全正常。

喔對了,忘記跟大家先介紹一下遊戲酒吧到底在做什麼。

我們的商業模式滿特別的,簡單來說就是發掘有潛力但已經過了高峰的遊戲,改頭換面以後重新上架,靠我們公司的行銷與營運團隊延長一款遊戲的生命週期。

例如說現在有款遊戲 A,上架了半年之後新用戶愈來愈少,開發商決定把資源投注在其他新的遊戲,因此遊戲 A 就頓時失去目光,成了遇不到伯樂的千里馬。這時候遊戲酒吧若覺得這款遊戲其實有機會,只是缺少了適當的行銷跟營運,就會去跟公司談合作,讓遊戲 A 換個名字之後重新在 Google Play 上架,乍看之下就是個新的遊戲,但遊戲內容完全一樣。

接著就是我們公司來維持這個遊戲的營運,會員跟金流系統都是走我們的,而營收會跟原公司拆成,這種模式叫做「聯運」,聯合營運,第一次聽到的時候我覺得超級特別,原來還有這種方式。

而這邊的遊戲主要指的是在 Google Play 上的手機遊戲,為什麼沒有 iOS 呢?因為 iOS 的政策較嚴,只是改名的話會被擋上架,所以只能做政策寬鬆的 Google Play。網頁遊戲也有做,但數量比較少。

從以上內容就可以看出來技術組要負責哪些東西,第一個當然是主要的會員與金流系統,還有官方網頁的維護。第二個則是 Android SDK,要提供給遊戲開發商串接我們的會員與金流系統。第三個是其他額外的服務,例如說我們自己的追蹤系統、推播系統、後台系統跟對外的活動網頁。

我其實忘記一開始是負責什麼了,可能是活動網頁吧?只記得進去時前兩週都在看 Node.js 相關的東西,當個薪水小偷。其他時間慢慢學習如何維護 Android SDK,要拿去給廠商串接,有技術問題也要試著解決。

後來公司想要做一個以玩家為主的聊天軟體 Poke,因此就專職做 Android 開發,與另外一個同事合作。體驗到想要做個「穩定」的聊天軟體真的靠北難,光是訊息收發這一塊就可以搞很久。魔鬼真的是藏在細節裡,每天都有一堆重要的小細節要處理。

開發了兩三個月後,產品還是定位不明(這之前就一再討論過了),覺得價值不大,於是專案就被砍了。後來另一位負責 Android 的同事跑去放了個長假,回來後我就被主管找進會議室,得知了他要離職的消息。

那時候我學到兩件事:

  1. 如果不是固定在做 1 on 1 的公司,當主管找你談話時,一定是有什麼事情要發生(例如說有人要離職了)
  2. 有時放長假是離職的前兆,可能是想在離職前把年假都用掉

同事走後,維護 Android SDK 的重責大任就交給我了,而那時我對這套系統已經有一定的熟悉程度,決定把看不順眼的地方都改一改。

第一,那時候每來一個新廠商就要重新編譯一個 jar 檔,因為要在裡面 hardcoded 一些 key(api key 之類的)。我原本提議說這些 key 可以寫在後端,啟動時再 call API 去拿,但若是碰到網路情況不好之類的情形會導致 SDK 無法啟動,體驗很差,因此這條路行不通。

後來跟另一個同事討論過後,想到 jar 檔其實就只是一個壓縮檔而已,可以把 jar 解壓縮之後把專門放這些 key 的資源換掉再重新壓縮回去,就不用重新編譯,節省了許多時間。

而且一但這樣做之後,就可以寫一個後台系統,讓營運人員只要填寫必要的 key(或甚至根本不用填,由系統自動產生)就能自動產生 SDK 並交給廠商,完全不需要技術組的介入。

我們那時有個最終的夢想,是遊戲廠商幾乎不用串接 SDK,我們就能自動把 SDK 接上去。原理是反編譯 apk 之後覆蓋相關的 function call,所以也花了不少時間研究反編譯跟重新打包,是一段很有趣的經歷,那時也寫了這篇文章:人人都會的 Android Apk 反編譯

第二,當時很大的一個困擾是當我們想更新 SDK 時,需要超級多時間。不是我們的時間,而是廠商的時間。廠商要再排時間串接新的 SDK,儘管 API 都沒變,還是需要再測試一遍,小廠還行,大廠的話要等到兩三個月後,等到頭髮都白了。

我跟另一個同事花了些時間研究了現成的解決方案,最後實作出了一套簡單的熱更新系統。原理是把程式邏輯包成 dex 檔,在程式執行時從 Server 把 dex 檔下載並載入之後執行,因此只要我們更新 dex 檔,SDK 的邏輯就會自動更新。

有了這套熱更新系統以後,廠商只要串一次新的 SDK,之後想要埋點或者是更改邏輯、修 bug 都可以不透過他們,只要我們這邊自己處理即可,節省了許多時間。

第三,文件及教育訓練。有了許多與廠商交手的經驗之後,就會知道哪些問題最容易被提出,因此我更新了 SDK 的技術文件,把這些常見問題都加上去。碰到問題時在常見問題裡面就能夠找到解答,完全不需要問到我。

再者,除了我以外,第一線會接觸到廠商的其實是營運的同事們。最常見的狀況就是當問題發生時,他們分不清楚是廠商的問題、後端的問題還是 Android SDK 的問題。這很合理,因為他們不是工程師,所以通常都透過我來轉介到正確的人。

但時間久了以後我也慢慢可以歸納出問題類型,因此寫了一份文件,只要照著上面的指示通常就能知道問題出在哪,也幫他們科普了 SDK、API 這些名詞,希望能讓他們對這些東西有最基本的理解。

甚至還跟同事合作在公司內部開了課,教一些最基礎的程式相關概念,這堂課就是我在 Hahow 所開設的線上課程的前身。

我那時不覺得自己做了什麼了不起的事,只是很直覺地把重複性的東西自動化跟標準化,工程師不就是這樣嗎?同樣的 function 寫了兩次以後就要抽出來變成一個,冗餘的 code 就是要重構寫得更漂亮。

一直到後來我才發現,這些我覺得沒什麼的事才是重要的事。時間就是資源,節省了時間就增加了更多可利用的資源,從這些重複性極高的事情中解放以後,工程師就有更多時間去做其他更有價值的事。

我的工作表現反映在績效上面,主管對我讚譽有加,認為我超出了她的期待,不只是改善我自己負責的東西,也讓技術組的整體氛圍變得更好。

績效則反映在薪水上,滿三個月時調薪到 43k,領年終時也拿了三四個月;待滿一年時調到 55k,看到調過的薪水我嚇了一跳:「哇,原來月薪五萬就是這種感覺嗎…」,還因為績效很好被公司送了一張去東京的來回機票做為獎勵。

每次看到這麼一大塊綠地都會覺得很像電影場景,很不真實

解決了 Android SDK 的問題以後,開始負責一個公司內部的廣告相關系統,前後端分離,採用正開始展露頭角的 React + Redux(好像還在 0.14 版的時候),從那之後就奠定了自己想走前端的這個方向。

也在那時期寫了一些與 redux 或是工作內容相關的文章,像是《Promise, generator, async與ES6》《redux 簡介》《redux的middleware詳解》《快速取得 apk 相關資訊》《資料庫的好夥伴:Redis》《與 DDoS 奮戰:nginx, iptables 與 fail2ban》等等。

在遊戲酒吧將近這一年半的時光裡面,我學到了很多。對我來說最重要的是擴展知識的廣度。在加入以前,我甚至連 ssh 都不知道是什麼。因為以前只會租虛擬主機,用 ftp 把 php 檔丟到上面,從來都沒有自己連接過主機。

但是在這邊除了前後端跟 Mobile 都有幾分涉獵以外,在伺服器的架構上也多了幾分理解,知道什麼是 cluster、load balance,也體驗部署了 node.js 的專案。從現在看來,我依舊覺得這是一段很棒的經歷,給了我足夠的經驗與養分,讓我往下一個階段發展。

在我入行的第一年,我缺的不是實力,是舞台。感謝遊戲酒吧給了我一個很適合的舞台,讓我展現能力。

2016 年 8 月:重返學校

2016 年 7 月底,我離職了。最主要的原因是我打算復學回去唸書。

當初決定休學時,我以為我一輩子都不會再回去唸書,但沒想到休學了兩年以後,讓我找到了一個理由。

出社會之後我意識到了一件事。若是你不主動參加任何活動,你是認識不了新朋友的。而且這種活動的目的通常就是讓你認識新朋友。

但學校不一樣,學校是一個能夠最自然讓你交朋友的環境,你們可能同系、可能同組或是同社團,不用刻意的團康活動或是尷尬的大家好,合作久了,自然就成了朋友。

在遊戲酒吧工作的時候,其實我偶爾還會回學校去幫忙一個專案:InfoPlat,他們想做一些跟台大相關的資訊平台。看到在找人的訊息以後就決定要加入這團隊,一方面是這跟我還在學校時想做的東西很像,另一方面也是想說可以維持著跟台大的連結,假裝自己還是個學生。

最後由一些背景不同,但大部分是工程師與設計師組成的團隊,與台大的不一樣思考社合作。我們跑了一遍 design thinking 的流程,試圖做出一個厲害的產品。

雖然最後產出的結果不算成功,中間也經歷了許多調整,但我很喜歡合作的過程:「阿,原來跟志同道合的朋友們合作是這種感覺」,也就是因為體驗到了這種感覺,成了我復學的契機。

我復學不是為了畢業,我也沒打算畢業,我只是想報名資訊種子跟創創學程而已。

這兩個東西對我來說滿類似的,我懶得詳細介紹了,有興趣的可以自己去找資料。總而言之,都是讓我有一個機會可以跟其他人合作一些專案,是我滿嚮往的環境。而且我也很期待我的背景 — — 一個有實戰經驗的工程師 — — 能夠帶給團隊什麼樣的改變。

原本想說這兩個計劃的申請我應該都輕鬆上才對,結果資訊種子連面試機會都沒有,創創學程備取一。原因可能是我太荏懶,報名表都隨意填填,沒有把自己的優勢顯示出來。或者也有可能我表現出來了,但不是這個計畫想要的。

七月底離職以後,就等著九月中的開學以及九月初三天兩夜的「創創達人營」,說穿了就是創創學程的迎新活動。

原本我以為就這樣了,從社會人士回歸到學生身份更有感觸一點,知道自己在學校時真正想要的是什麼,而不是像以前還在學時那樣得過且過(但我覺得得過且過也沒什麼不好就是了)。

但是,就在八月中的時候,我收到了一封來自 Garena 新加坡的 Facebook 訊息(對,是用 Facebook 傳的)。

內容大意就是:

安安,這裡是 Garena,我們是總部在新加坡,但在東南亞各地都有分公司的新創獨角獸,旗下主要的產品有蝦皮跟遊戲代理(英雄聯盟),這裡有 80 幾個工程師,都有很紮實的基礎,有些比過 IOI、ACM ICPC 還拿過牌。

公司還在持續擴張中,有興趣來試試看嗎?你應該認識的 OO 跟 XX 之前才來公司參觀過。

收到訊息以後,我驚訝了兩次。

第一次是:為什麼找上我?根據在訊息裡面的敘述,他提到的人是平常有在打程式競賽的學弟,後來發現其他朋友也有收到訊息,而在訊息裡其實也有提及找上我是因為我 2009 年的時候有比過程式競賽(這部分可參考:自學、哲學、講學:我的程式之路(中)),可是那已經是好幾年前的事了。

第二次驚訝則是:Garena 居然是聽起來這麼厲害的一間公司?在這之前我對它的印象只有英雄聯盟代理商,其餘一無所知,從來沒想過我居然會有覺得 Garena 厲害的一天。

但我回絕了。我說我比程式競賽的時候已經是好幾年前的事了,之後都沒有再碰過。想找這類人的話可能找錯人了,我雖然還是工程師,但是能力跟他們差得遠了。雖然我對 Garena 很有興趣,但怕自己能力不符。

那時對方聽完之後回了一句:「那你要先面試看看嗎?」

我就說:「好」

那一刻我領悟到一件事。在找工作的時候,不要自己把自己刷掉。若是不敢投的原因是覺得自己能力不足,背後的可能有兩個:實力夠但自信不足、實力真的不夠。

但我要怎麼驗證到底是哪個?

我無從驗證。

一但拒絕了面試的邀請,我就永遠不會知道答案是什麼。所以沒什麼好不答應的。若是我真的沒實力,在面試時對方自己會把我刷掉;若其實是自信問題,那我就賺到了,證明我其實比我想像中的更有能力。

原本不抱任何期待的我,通過了一面、二面甚至是三面。部分應該歸功於儘管是新加坡公司,面試卻是全中文的,讓我跟面試官的溝通沒有語言障礙,才會如此順利。

我把面試題目寫在這:記一次軟體工程師面試心得 ,有興趣可以看看。

三面已經面到大主管了,照理來說是最後一關,面完之後其實挺緊張的。剛好那時候也到了參加創創達人營的時間,我就想說真剛好,可以讓我們有個機會放鬆,去玩個幾天回來應該就會有結果了。反正上了就去,沒上的話就維持原訂計畫。

結果營隊的第一天,HR 就寫信跟我說他們那邊還要再進行一輪面試,而且想要盡快。我回信說我在參加一個營隊可能不太方便,但對方說只要大概一小時就好,晚上也行,希望能盡快把這面試搞定。

迫於無奈之下我跟隊輔借了筆電,在其他人還在玩培養向心力的活動的時候,我在其中一個小房間跟 Garena 進行最後一關的面試。

現在想想還是滿好笑的,怎麼會在一個這麼奇妙的情況下面試?而且最後一關問了滿多東西,面了大概一個半小時。

面完之後覺得通體舒暢,終於面完了。那時覺得自己表現不錯,已經半個人在新加坡了,雖然說一直告訴自己得失心不要太重,但做不到啊!

過了幾個小時,到了晚上八點,我已經忘記那時候在進行什麼活動了,發現手機震動之後我拿起來看。看了 Android 的通知列,是一封新信,標題是:「Offer letter for Hu Li from Garena」。

我轉過頭去跟我隔壁的同學說:「欸欸,我錄取了,我又要再休學一次了,大家掰掰」

我想回學校,但是老天爺不讓我回,因為我要去新加坡了。

2016 年 9 月:學校掰,新加坡嗨

一直到很後來我才知道,當初第三面的確就是最後一面,會有第四面是因為蝦皮看到我的履歷有興趣也想面面看,所以第四面的面試官是蝦皮的技術負責人。

都還沒開學,連教室都還沒踏進去過,我就先回學校的各處室又辦了一次休學。這次休學,我是沒有打算再復學的。

前面有提到我想復學的理由,但跟這理由比起來,去新加坡工作的機會更吸引我,我一點猶豫都沒有,就決定要去工作了。

我想去海外工作嗎?想,而且之前就想,我相信很多人也一樣嚮往去海外工作。但我覺得自己還不夠格。以我原本的規劃,大概在台灣再待個兩三年,把英文練好一點之後才能達到出國工作的基本門檻。語言都搞不定,談什麼出國工作。

但神奇的事發生了,居然有一間在新加坡的公司找上我,而且面試還全中文,最後還錄取了!天上掉下來的機會,怎麼可能不拿。想回學校隨時可以回去,但去海外工作可不是說想去就能去的。

這次的歷程又讓我反思了一次自己是不是應該加強自己的自信,總覺得自信好像跟不上實力。但我依舊處於矛盾當中,一方面覺得自己實力不錯,但看看那些我覺得實力真的不錯的人,卻覺得自己還差得遠呢。

儘管如此,我還是有了一些轉變。

我不再是那個別人找你面試卻自覺實力不夠還婉拒的人。對自己能力的判斷是會被自信影響的,一點都不客觀。雖然讓別人來面試你也不一定客觀,但至少是另外一種反映自身能力的管道。

以前的我是:「我不夠好,不投了」;現在的我是:「我可能不夠好,但幹嘛不投?投了又沒有損失,我擔心自己會不會錄取幹嘛?反正不行的話公司會把我刷掉,沒必要自己先刷掉自己」

去海外工作,我唯一擔心的事情是工作簽證會不會因為學歷問題而過不了,因為我知道有些工作簽證是會考量學歷、經歷跟薪水的,等了大概一個月以後拿到了新加坡的工作簽證(SP),放下了心中的大石頭。

至於薪水的部分直接從上一份的 55k 變兩倍,原來年薪百萬是這種感覺。

2016 年 10 月:第一次在海外工作

海外工作最麻煩的住宿問題在公司協助下輕鬆搞定,住在公司提供的「要錢的」宿舍。簡單來說就是公司當二房東,租房子之後轉租給你,對員工來說挺方便的,想走就走完全不用綁約。

在上班前我對公司有一些期待,我想說公司這麼大工程師這麼多,應該會被分到一個專做前端的 team,可能有五六個人還有一個很強的 team lead,有些人資深有些資淺,而我是資淺的那一個,可以從其他人身上學到很多。

進去之後發現這只是我單方面的想像而已,我被分到了一個 Garena 的全新產品:Garena LIVE。用一句話來解釋,就是 Garena 想做自己的 Twitch — — 遊戲直播平台。

Garena LIVE 現在的長相

這個專案有一個 PM、一個設計師、一個後端工程師與一個前端工程師,那個前端工程師就是我。專案的雛型已經有了,主要功能都做好了,是一個從泰國被調來新加坡的工程師完成的。

而我要做的事情就是跟他交接,他一個月後就要回去泰國了。儘管到了大公司,但我的職責依舊沒變,還是一人前端團隊,一個人搞定所有前端的東西,跟想像中的完全不一樣。

這邊得到的啟示是儘管是大公司,還是要看你在哪個 team。每一個 team 都不一樣,環境還是有可能跟你待在新創公司一樣。不過如果去蝦皮的話,好像就真的是我想像的那樣。

沒有前端團隊,就繼續當一人戰隊吧,一個人也可以學到很多。而且這個專案會對我的履歷很加分,怎麼看都是利多。

儘管之後團隊變大,補了兩個後端也補上一個 PM,但依舊維持著大概五個人左右的規模,而前端始終只有我一個,我連代理人都沒有。所以每當我回台灣休假的時候,整個專案的前端就停擺了,完全沒辦法修 bug 或是加新功能。

在 Garena 的這一年是我首次專注在前端開發上,完全不用理會其他的事情。由於是一個人負責整個專案,因此前端技術上的成長較快,最大的收獲是對 React + Redux 的熟悉度比之前高了幾個檔次,但也很快地碰到了瓶頸。

一個人的好處就是想玩什麼沒人管你,你今天想用最新最潮的 library 也行,寫一堆爛 code 也可以,也不會有其他人看到你的 code。壞處就是雖然自由度極高,但久了之後會開始懷疑自己:「這樣做真的好嗎?有沒有更好的做法?」、「我寫的 code 真的可以嗎?會不會其實都是爛 code」。

沒有團隊的後果就是如此,沒有人跟你討論或比較,完全不知道自己現在的能力到哪。很快地察覺到這件事情以後,我開始加強自己對「深度」的要求。若是碰到問題,就要盡可能追根究底,試圖完全搞懂問題的成因與解法。理解得越透徹,能力就越強。

例如說在被公司的資安部門告知有安全漏洞之後,花了點時間研究 CSRF,寫了《讓我們來談談 CSRF》;測試的時候發現 Cookie 居然怎麼寫都寫不進去,在網路上也搜不到相關問題,只好去找 Chromium 的原始碼來看,寫了《我遇過的最難的 Cookie 問題》

其他像是《該來理解 JavaScript 的原型鍊了》《直播協定 hls 筆記》《輕鬆理解 Ajax 與跨來源請求》《循序漸進理解 HTTP Cache 機制》也是在類似的背景之下產出的文章。在工作時碰到困難,深入研究並解決,整理想法之後寫下心得。

這段期間自己的自信心其實也有慢慢提升。自己一個人負責這樣不小的專案也沒問題,寫出來的文章也受到好評,好像比自己想像中還要厲害一點。

除了技術能力以外,也更認識了自己一些。

入職大約八九個月之後,我有了想離開的念頭。原因有幾個,第一個是成長曲線大幅減緩。因為專案已經過了最前面那段衝刺期,現在逐漸穩定,除了要修 bug 以及加一些小功能以外,短期內不會有大改版。依舊能學到東西,但我覺得能學到的不多。

第二個原因很真實,是薪水。原本來這邊的時候我想說虛心學習,畢竟我也沒有多厲害,薪水的部分就沒那麼在意。可是來了之後發現自己把一個專案扛起來,這整個平台的前端就靠我一個人獨立開發,似乎比預期的厲害,而且我的重要性應該是不小的。

若是能夠獨立負責一整個專案的話,我覺得薪水拿低了。再怎麼想都應該要多個至少 20% 才對。

第三個原因是語言,在 Garena 裡面我大約八成的時間講中文,兩成的時間講英文。是很舒適沒錯,但這不是長久之計。若是想要爬得更高看得更遠,英文能力是不可或缺的。因此我希望可以找到一個全英文的環境,強迫自己進步。

綜合以上幾個原因,我決定在新加坡尋找新的機會。我超級緊張,因為這次不一樣了,這次的面試會是全英文的,也要寫一份全英文的履歷。

2017 年 9 月:第一次在海外找工作

那時候原本的目標是一些小有名氣的新創公司,例如說 RedMart、Carousell、Zendesk 與 Stripe 等等。

但有些沒開缺,有些覺得可以晚點再投,最後在 hired.com 上面放了履歷,也親自投了 Stripe。

有關於這段經歷,我之前寫了一篇長文:《我與 Stripe :一段愛與夢想的故事》,這邊就不再贅述了。

雖然說還是對全英文面試感到害怕,但整個過程比我想像中的順利,我的英文好像也沒有差到哪裡去,至少在面試時是能夠溝通的。

最後成功拿到了一間跨國新創 Eatigo的 offer,職位是資深前端工程師,薪水比之前多了 30%,是個我很滿意的薪水。

拿到 offer 以後向 Garena 提了離職,雖然公司一再挽留但我心意已決,就算公司之後要上市可能會有股票可以拿,我也沒有想要留下來的打算。對我來說,成長空間才是最重要的,而Eatigo 的環境更適合讓我快速成長。

離職後回台灣放了兩週的假,再回去時就要迎接新的挑戰了。新的職位、新的環境,以及新的同事們。

2017 年 11 月:全英文工作環境的挑戰

先來簡單介紹一下 Eatigo 在做什麼以及技術部門在幹嘛。簡單來說就是一個餐廳訂位服務,與其他人的差別是在我們網站上訂位可以有折扣。你不用先付款、不用買任何券,只要訂位,然後去餐廳吃飯就好了。在結帳的時候就能獲得折扣,依據時段的不同,最高可以打到五折。

網站介面,右邊紅色那塊就是讓你選時段與折扣用的。

想知道更多資訊的話可以參考我之前寫過的:《東南亞吃飯省錢必備神器:Eatigo》

Eatigo 的技術部門分成兩塊,其中一塊在曼谷,那邊有 Android 與 iOS team、設計師、PM 與 QA。另外一塊在新加坡,這邊有後端、前端(網頁前端)、DevOps 跟 CTO。

我也不知道為什麼要分成兩塊,但總之就是這樣了。新加坡辦公室大概 30 人左右,就是個新創小公司,整個 Eatigo 大概 200 多個人,在東南亞各地基本上都有辦公室。

新加坡技術部門的組成也是滿多元的,印度、印尼、中國、緬甸、韓國、菲律賓、白俄羅斯、烏克蘭,都來自各個不同的地方,我可能是整個公司唯一一個台灣人。

剛進公司的時候,第一個碰到的障礙就是語言。雖然說在面試時認知到自己英文沒有想像中的差,可是面試畢竟是一對一又在密閉空間,可以很專心地與對方溝通。日常生活不是這樣的,辦公室隨意聊天、中午吃飯時坐一桌討論文化差異,你要排除周遭的環境音以及雜音,並且在不同人身上切換注意力,英聽能力瞬間降低 50 %。

還有要習慣大家的口音,所以口音這件事情也是花了不少時間,基本上每天聽就會慢慢習慣了。對我來說這邊的額外福利是免費的英文聽力與口說課程,就算我沒有刻意做什麼,英文能力也會慢慢提升,環境就是這麼神奇的一個東西。

進來之後的工作內容跟之前面試時講得差不多,Eatigo 正在把整個平台砍掉重練。現在的版本是很久以前外包又自己接回來的,後端是 PHP,前端就是 jQuery 跟一堆雜七雜八的 library。這套系統已經用三四年了,我覺得比較像是當時的一個 MVP,所以許多東西都為了速度沒有考慮維護性,導致維護困難,要加新功能也超級困難。

因此公司決定把整個專案砍掉重練,後端用 Golang,前端用 React,連 Mobile App 都要打掉重做。所以就是一次大翻新,全部東西都要換掉。我進去的時候後端大概有五個工程師,前端三個,iOS 跟 Android 應該各兩個,現在也是維持差不多的人數。

你可能會以為前端要負責的只有訂位的那個網站,那你就太天真了。除了這個以外,還要有一個給內部員工使用的後台,可以管理使用者、餐廳等等的資料。也要有一個給餐廳用的網站,讓餐廳可以看到今天的訂單資訊;最後還有一個給 finance team 用的系統,讓他們可以產生發票跟收據,處理跟帳務有關的事情。

因此前端的工作就是要翻新這四個系統。不過後來因為時程上的因素,公司選擇把內部後台留給我們自己開發,其他三個專案都外包出去再接回來。

前端包含我一共三個人,只有我的職稱是 senior,其他兩個人都是一般的 engineer,以對 React 的經驗來說,我的確比其他兩個人多了一些。不過大多數的決策我們都會互相討論,不會因為誰比較資深就一定聽誰的。

剛加入的前幾個月都在做公司的後台系統,起頭是最難的。有一大堆東西需要討論跟決定,而且有些較基礎的東西一但定了,以後就比較難改動了。

那時我正好在研究 redux-observable,之前看到 Netflix 的人講這套以後就覺得要找個機會來試試,跟同事討論過後把這套帶進來。

另外也帶了 Prettier,不然光是討論 coding style 的規範就要討論半天,直接交給 Prettier + ESLint 做決定就好,可以省很多時間。

就這樣做著做著,CTO 覺得我還滿不錯的,就在我過試用期後沒多久,在其中一次的 one on one 問了我這個問題:「你有興趣接前端的 team lead 嗎?有的話我就慢慢把這個職位交給你,之後就由你負責前端 team」

當下內心第一個反應是:「蛤?真的要交給我嗎?我不行吧!」

以技術來看的話我覺得 ok,但是 team lead 這個職位除了技術,還需要具備良好的溝通能力。如果是講中文的話我一定毫不猶豫答應,但講英文的話我就退卻三步了。

說到底,還是語言的問題。從我出國到新加坡工作開始,語言就是一直纏繞著我的一個問題,一直到現在也還是。

但儘管如此,我的心態已經轉變了。還記得我面試 Garena 後得到的心得嗎?當機會來臨時,先說 yes 就對了,到時候真的做不來再說。

「好,我願意試試看。」

2018 年 3 月:從恐懼到不安,再到幻震

願意試試看是一回事,但是恐懼依然存在著,不會因為你鼓起勇氣接下這個職位就消失。

跟原本的職位比起來,team lead 要多做些什麼事呢?

  1. 有新功能的時候要跟 PM 先開會,討論規格並安排時程
  2. 安排前端的時程並為其負責
  3. 把 ticket 分給同事,決定分工
  4. 每兩週與 PM 開一次 sprint planning meeting,決定這個 sprint 要做什麼
  5. 每兩週與 PM 開一次 grooming meeting,來討論 backlog 裡面的 ticket

其實我覺得比起我認知的 team lead,在職務上會比較像是 senior engineer + project manager。在專案的部分做比較多事情,招聘、管人什麼的好像都不關我的事。每間公司的職稱跟職務都不太一樣,至少我的是這樣。

總之在這個職位上,溝通的部分會比以前多很多,我就是前端組的窗口,有什麼事情都會先來找我。如果只論溝通能力我覺得我很 ok,但溝通這件事情無法只看溝通能力,還需要看語言能力,別人講的你聽不懂、你講的別人聽不懂,再怎麼會溝通也是枉然。

何況 PM 在曼谷,透過語音及視訊溝通,英聽能力再掉 20%,只剩下八成的功力。

在接下這個職位後不久,主管派我去曼谷出了一趟差,主要去那邊稍微認識一下同事以及跟 CPO 討論前端的時程,這是我人生中第一次出差。

但這次出差也是夠衰的了,飛機抵達曼谷時就覺得耳朵很奇怪,怎麼左耳聽到的東西都被蒙上一層薄紗。而且這狀況不像以往打個呵欠之類的就解除了,我試了無數個方法都沒有用。

因此在跟同事溝通時儘管面對面,依舊是以一個聽力減弱三成的狀況在溝通,要超級無敵專心才能進入狀況。

一直到三天後出差回來,這狀況都沒有好轉。後來去看醫生,說我有點感冒鼻塞的時候搭飛機,因為巴拉巴拉的關係總之耳朵被一些東西塞住,過兩三個禮拜就會好了。

雖然說現在講得雲淡風輕,但那時候心理壓力真的不小,主因就是覺得自己英文溝通會有問題,害怕開會聽不懂對方說的話,對開會這件事情感到恐懼。如果有其他同事在還好,真的聽不懂的話同事也會幫忙,但如果只有我一個人就沒辦法了。

戰戰兢兢地過了三個月左右,慢慢步上軌道,發現自己對開會這件事情也很習慣了。而且 team lead 才需要開的每日例會,前端通常都沒什麼問題要反映,因此我的台詞萬年不變:「nothing from my side, that’s all」

從那之後,原本的恐懼變成了不安,程度減輕許多。開會時還是會有些許不安,但已經逐漸習慣這種感覺。

在後台系統差不多完成以後,我們開始接手外包寫的程式碼。老實說品質不是很好,而且有超級多的細節都忽略掉,還有很多一看就知道對 React 不熟才會寫出來的程式碼。

我跟同事們花了許多時間在重構上面,反正本來就有 bug 要修,就邊修邊重構。之前在 PTT 聽到一句話很中肯:「很多工程師只會重建,不會重構」。有時候重構不一定要全部需求凍結,只為了排一段時間給你專門重構。從日常的修 bug 開始,就可以慢慢把看不順眼的小地方改掉,就算只是一個 function 也行。

就這樣慢慢改著,專案也變得愈來愈穩定,從外包寫的程式碼裡面我也學到滿多的。雖然案子是同一間公司做的,但是負責的人不一樣,因此不同專案的 style 跟使用的技術也不同。

就是在這時候我把 redux-thunk、redux-observable 跟 redux-saga 這三套的差異跟用法都搞懂了,因為這三種方式我都看過也用過。雖然我一開始支持 redux-observable,但我最喜歡的其實是 redux-saga。

當初回台灣講的 ModernWeb 題目,靈感就是來自於工作

看了這四個 React + Redux 的專案之後,對這套東西的熟悉度又上了一個層級,慢慢摸索出 Best Practice,也開始研究一些比較底層的東西,用到的 library 如果出問題也不會懼怕,直接去找原始碼來看就好。

另一方面,也接觸到了很潮的 PWA,理解了背後的原理以及應該如何實作。雖然看起來不難,但實際上很多眉眉角角。也因為要處理 SEO 問題實作了 Server Side Rendering,在增進效能上也花了不少心力。

雖然說現在的專案還是有許多改進空間,但能變成現在這樣子已經很不容易了。

2018 年 8 月,新的平台正式上線,舊系統慢慢淘汰,全面轉移到新系統上面,而我們前端負責的四個網站也一次上線,終於完成了一個里程碑。

經歷過一兩個月的動蕩期之後,產品漸漸穩定下來,不知不覺我擔任 team lead 這個職位已經半年左右了。這時候的感覺已經從不安變成了幻震。

什麼是幻震?人生三大錯覺:他喜歡我、我能反殺、手機震動。你以為手機有在震動卻沒有,這就叫做幻震。

換句話說,我還是偶爾會覺得自己好像溝通很差,但實際開會過後又覺得好像沒有。還是有一點不安的成份在,不過程度又減輕許多,頻率就跟感受到幻震差不多。

大概是同一時間,我開始思考離開新加坡之後要幹嘛。

咦?跳太快了嗎?怎麼突然就提到要離開新加坡了?

打從兩年前還在台灣等工作簽證的時候,我就做好這個決定了。我原本就沒有打算在新加坡待太久。至少一年,至多兩年,這是我原本的計畫。

每個人在工作上追求的東西都不同,我追求的是新鮮感。在新加坡待一陣子之後,我想去其他國家看看。就這樣一個國家待個一兩年,然後前往下一個國家。邊工作邊旅遊,我是這樣打算的。

當初在 Garena 想離職時,直接離開新加坡也是一個在考慮的選項,但那時想說先找工作好了,找到就繼續待著順便練英文,後來就跑去 Eatigo 了。

如今 Eatigo 也待了快一年,改版也完成的差不多了。雖然說平時不怎麼出門,但對新加坡也有一定的熟悉程度,可以來想想下一個地方要去哪了。那時最想去的其實是日本 Indeed,就是開頭的 Simon 大大工作的那間,不然的話日本 Line 也可以,想說去那邊順便學日文。去不了日本的話,也想試試看英國,這都是選項之一。

無論如何,離開新加坡是一定的,只是我還沒想好之後要做什麼而已。大概九月十月的時候,我就跟主管告知這件事了:「安安,我明年一月要離職了,但我不是要跳槽,我要回台灣了。我之後想去其他國家工作,會先回台灣休息一陣子再決定要去哪裡」

主管有點嚇到,畢竟通常沒什麼人會這麼早講。有些人可能會覺得我很傻,這麼早提的話,bonus 不就沒得領嗎?薪水也不會加,搞不好公司還提前一步把你 fire 掉。

第一,我對公司有一定的重要性,不可能把我提前 fire 掉,反而還會希望我多留久一點。

第二,績效獎金的依據應該是去年的績效,而不是我還會在這裡待多久,這是誠信跟道德的問題。當然,這不受法律規範,公司可以因為我要離職就大幅減少給我的獎金,但我同時也能認清這間公司。

第三,我已經確定要離職了,我覺得越早講越好,公司可以提前做準備開始找人跟規劃之後的時程。而且一但提了,我自己也沒有回頭路了,我還滿喜歡做這種事的。

總之主管聽到以後說他知道了,感謝我這麼早說(提前三個月),讓他們可以提早做準備。

後來經過幾次溝通,公司希望我能再多待一陣子,而且四月發獎金,到那時再走是雙贏的局面。我同意了,所以四月是我在新加坡的最後一個月。

離職以後我到底要幹嘛呢?那時候我有幾個選項在猶豫著:

  1. 試試看去日本工作,投投看 Line 與 Indeed。
  2. 抽英國打工度假簽證,就算沒抽到也可以試試看有沒有公司願意直接辦工作簽。
  3. 挑戰 Google、Facebook 等等這些大魔王
  4. 回台灣創業,專注做程式教學
  5. 面試 ALPHACamp 課程總監職位
  6. 到處出國旅遊好好放個長假
  7. 閉關修煉一年,好好補強自己的技術

每一個選項我都覺得很不錯,而且我也都能接受,但就是沒辦法下定決心專注在某一個選項。

當我想說自己實力不夠,應該要閉關修煉的時候,又會想到之前面試 Garena 的故事,搞不好是因為自己信心不足,應該直接去面試看看。

當我想出國旅遊放假的時候,會想到 Indeed 的前端缺可不是時時刻刻開著的,搞不好錯過這次要再等個一兩年,機會是不等人的。

當我想著做 A,就會想到放棄 B 的機會成本,於是遲遲無法下定決心。

幸好元旦那天掉下一個大禮,讓我不用自己做選擇。

2019 年 1 月:早起的鳥兒有機票買

2019 年 1 月 1 號早上九點,跨年夜哪都沒去,待在家睡覺的我依照慣例在這時間醒來。躺在床上滑了一下手機,看到平時就有在追蹤的粉絲專頁發出的貼文,説國泰航空有 Bug 票,越南飛美國的商務跟頭等艙只要 1000 美金。

以前聽過許多買 bug 票爽爽玩的故事,現在終於要被我碰到了嗎!雖然說航空公司不一定會承認,但有試有機會。於是我從床上跳起來打開電腦,買了一張六月的河內到紐約的商務艙(因為沒有頭等艙)。

過了三十分鐘,發現這個票價還在,而且一堆網友買到頭等艙,我心裡想說:「不對啊,那我怎麼只買商務」,於是買了第二張機票,七月的河內飛舊金山頭等艙。

這個 bug 票跟以前的都不一樣,大概持續了半天才被關掉,一大堆網友都買到了。更令人驚訝的是過了幾天,國泰航空居然承認了!

既然七月都要去美國了,那不如整個下半年都去旅遊吧!就因為這張 bug 票讓我下定了決心,最後選擇了:「到處出國旅遊好好放個長假」這條路。

在猶豫不決的時候,你需要的不是理性,是衝動。如果這個決定有明顯的優劣之分,你的理性早就幫你做決定了。之所以會猶豫這麼久,就是因為這些選項的價值都差不多,因此需要的是衝動。

只要一個衝動就可以幫助你做決定,做完決定以後就不要去想其他的路了,因為你已經決定了。

「當初如果…」都與你無關,因為沒有如果。

三個關鍵字貫穿四年職涯:實力、溝通、自信

故事說完了,我沒有預期你會在故事裡獲得什麼。聽個故事而已,沒有得到什麼也無所謂,但接下來我想分享一些我自己的心得。

實力

實力會說話,在工程師的世界尤其如此。

這邊說的實力我指的是技術能力,這是工程師的根本。我同意除了技術能力以外,其他能力也是重要的,但沒有技術能力的工程師不是工程師。

技術能力是工程師的基礎,也是自信的來源。如果沒有持續進步,那就是退步。我的技術能力在開始工作以後成長幅度才開始增大,因為在工作上你不得不把 bug 解掉,碰到的專案規模跟自己的 side project 也完全不同。

我一直都相信是金子總會發光,有實力的人才不會被埋沒。尤其是在這個網路時代,你可以利用各種方式讓其他人看見你。

無論我之後是繼續當個工程師還是慢慢走向管理職,都不能忘記技術能力是工程師之本。要讓別人服你靠的不是名氣、經歷或是學歷,而是能力。

溝通

技術能力很重要,但溝通也同等重要。不只要學會講,也要學會聽。我每次在 ticket 裡面回覆問題時都盡量寫得詳細,雖然乍看之下耗時,但其實是最節省時間的方法。若是講得不清不楚,還要再等對方回覆看不懂的地方,然後你再講得更清楚,那為什麼不一開始就講清楚就好。

若是在專案開發上碰到我覺得不合理的地方,我會直接說出我的理由以及我建議的解法,但要不要採用我交給 PM 來決定,因為我覺得那是他們的專業。

我覺得很多問題不是產品問題也不是技術問題,是溝通問題,溝通的兩方根本沒有在同一頁上。你講你的他講他的,最後各自堅持自己的想法互不退讓。但重點是,你們其實是有共識的,只是溝通的方式或是方向讓雙方都感受不到這件事。

想改善的話可以在網路上開始免費教一些新手或者是回答問題,你只要能夠理解問題以及用他聽得懂的方法回答,你就成功一半了。

自信

自信真的是靠北難掌握的一個東西。

2019 年 4 月:新的開始

就在上週五,我正式從 Eatigo 離職。一年半的時光經歷了不少事情,也從中學到很多。

最後一天跟同事聚餐的合照

在前天的時候我也從新加坡離開了,現在人已經在台灣,下次再與新加坡見面不知道會是何時。

我對於即將開始的旅遊計畫有點期待,卻也有點擔心。一年沒碰任何程式的話,應該會生疏不少,而且也不知道世界現在變得怎麼樣了。

但沒關係,那之後再說吧。有實力的人是不會被埋沒的。

最後稍微附上我的旅遊行程(詳細行程我還沒排好…好麻煩)。

如果你剛好在同一時間也在那個地方的話,歡迎私訊我,我們可以吃個飯聊聊天之類的:

2019–05–08 ~ 2019–05–31 日本(到處跑)
2019–06–10 ~ 2019–06–24 紐約
2019–06–25 ~ 2019–06–26 河內
2019–06–27 ~ 2019–07–14 舊金山
2019–09–02 ~ 2019–09–08 阿布達比
2019–09–08 ~ 2019–10–13 歐洲(法國、義大利、西班牙、德國)
2019–10–13 ~ 2019–10–26 韓國(首爾、釜山)

不知道未來四年會變成什麼樣子,我一點想像都沒有——這才是最有趣的地方。