在 2019 年 6 月結束在 LINE TV 為期將近一年的實習,也是我轉入資工領域後的第一份軟體工程 (Software Engineering) 實習。[1]
在實習開始之前,只是會寫一點程式的我完全無法想像原來軟體工程的世界是這麼廣大而有趣,而這一年給了我非常多的機會去實際探索這個新世界。
最實際的例子是,在實習之前,我看到像 Ronald 大大寫的這篇介紹後端架構的文章,可能是像看到外星文字一樣的茫然。但在開始實習之後,我像是學會使用字典一樣能夠翻譯外星文字,並慢慢後能理解各種服務的功能以及為什麼要這樣架構。就算遇到更陌生的新技術,也知道要怎麼下關鍵字去學。
從實習結束的當下回頭看,這一年好像進到了一個精神時光屋,出來後看到的軟體世界都不一樣了。比當初多懂了一些,但也更知道自己不懂的有多無涯無盡。
以下就紀錄在 LINE TV 的這一年學到的事。[2]
目錄
- 在 LINE TV 所做的事
- 實作是比較簡單的事
- 勇於要求去解決問題
- 做筆記當作人腦的快取
- 對新手工程師最好的學習環境
- 致謝
在 LINE TV 所做的事
首先不免俗地,還是要先簡單介紹一下在 LINE TV 所做的事。
在 LINE TV 這一年主要待在 Backend Team,負責 Backend Feature 的開發以及 Infrastructure、DevOps 的研究與優化,但在離開前最後一個禮拜也不小心用 React 幫忙寫了一個前端的 Mobile Web 的頁面。零零總總加起來經手了約十個不同的專案。
主要使用的語言為 JavaScript (Node.js),但根據不同的使用場景也會用到 Go、Python、Shell Script。
在雲端服務部分主要使用 AWS,在這裡主要有機會玩到的服務有 EC2、S3、Lambda Function、KMS、SQS、API Gateway、CloudFront 等。
在新技術部分,在接觸 DevOps 與 Infra 相關的技術時從零開始新學了 Drone、Docker、Kubernetes、Helm、istio、EFK Log Stack (Elasticsearch + Fluentd + Kibana)。因為在學的時候覺得 Docker 與 Kubernetes 實在是太好玩了,因此順便產出了 Docker 與 Kubernetes 的一系列教學文章。[3] 除此之外,更多的是學習如何用各種技術以及方法去建構能夠承載高流量的服務。
接下來就紀錄在 LINE TV 實習時以及實習結束後的幾個想法。
實作是比較簡單的事
剛進到 LINE TV 接到的第一個 Backend Feature 是實作一個金流訂單的付款與驗證系統。整體的架構是由資深工程師川哥設計,出好一個大概的 Spec 之後,就由我與另一位工程師俊緯實作。大致上的實作是用 Message Queue (AWS SQS) 儲存資訊,再透過類似 Scheduler 的方式去處理加密、扣款、驗證、更新資料庫。
實作這些東西本身不難,因此某天我完成實作後因為好奇加上永遠都想要多學一點的個性,就跑去問了川哥兩個問題:
- 為什麼要選擇這樣實作?
- 這個背後的架構是怎麼樣被設計出來的?
不問還好,一問就突然一發不可收拾,川哥開始搬出有著各種奇怪命名的後端整體架構圖 aka Phoenix。[4] 儘管接近下班時間,川哥還是不厭其煩地開始跟我分享圖中的 Anubis 系統、Sphinx 系統在架構裡是扮演什麼樣的角色(這些怪奇的神話命名們是屬於川哥的浪漫)。接著 Android 後端雙棲資深工程師卡特以及我的主管 Wei 也一同加入分享,隨著他們的講解以及我因為聽不懂又提出的更多問題,我理解了為什麼要用 Scheduler,而不用 SQS 加上 Lamda Function Trigger,為什麼一定要加上一層 Redis 等等原先藏在心中的疑惑,原來這些設計都是需要考量高流量 (High Traffic) 的狀況。
還記得那天聽完講解後,晚上下班我就像身上的某個開關被打開一樣,覺得能夠設計一個可以承受高流量的系統架構也太難太好玩了。於是下班馬上就直奔咖啡廳,開始瘋狂的把今天聽到講解中有提到但我那時候還不夠了解的名詞全部查了一遍,然後慢慢研究這些設計背後所遵循的原則。
事後回想,那天的發問就像是一個幫我打開新世界的鑰匙,讓我能夠初窺軟體工程的世界,從一個只會寫程式(還寫得不是很好)的新手轉變成一個學徒心態的軟體工程師。如果只知道把設計好的架構實作出來,而不能清楚知道為何這樣設計,這樣不僅能學的東西變少,也錯過了能夠培養自己成為軟體架構師能力的機會。只是當一個好的建築工人是沒辦法成為建築師的。
實作是比較簡單的事,而背後的為什麼和架構才是真正有趣的地方
那天的發問讓我在之後學習時,慢慢養成習慣去想「每個架構設計背後是為什麼這樣設計」以及「這些架構背後所遵循的原則」。在同事們的耳濡目染之下,我也漸漸能歸納出一些原則,例如:要盡可能減少需要維護的狀態、設計 Server 服務應該讓邏輯越靜態越好、要限制流量去避免資料庫在短時間內一次湧進太多操作等等。
而這些經驗也在之後輪到我負責設計架構時,開始會去思考自己的機制設計以及工具選擇背後的原因,就像當初我問川哥一樣反問自己。無獨有偶,之後去 Grindr 實習時,我的 Mentor Jack 大大也常跟我說:「對自己的每個設計選擇都要能解釋為什麼」。
勇於要求去解決問題
若要說在 LINE TV 最印象深刻的一個專案,應該就屬自己因為想要解決一個觀察到的問題,因此提案並為公司打造的一套全新的 API Document System。
還記得是在進入公司幾個月後,我在日常開發時覺得原本溝通 API 設計的方式和現有的系統都還有進步的空間,於是主動跑去跟我的主管 Wei 提到想來研究一下有沒有好一點的解決方案,Wei 也就放手讓我在手邊工作告一段落後去研究。
第一步我先找了市面上做得比較好的 Public API Document。藉由研究像是 Stripe 以及 Docker 的 API Document,我開始對好的 API Document 長什麼樣子比較有概念。
接著第二步開始研究市面上現有用來建立 API Document 的工具,分別是 api-doc、api-blueprint、Raml、Swagger。四種工具都研究加上嘗試過後,我自己就做了評估並產出 POC (Proof of Concept) 拿去跟 Senior 討論了我的想法,並決定最後要來使用 Swagger。
第三步是在工程師們開會的時候用簡報分享對 API Document 的看法以及這些研究最後的總結。為了讓導入 Swagger 更無痛,還順便寫了一份 Swagger API 的簡易教學,這份教學產出的 API Document 現在還可以在這裡的 Live Demo看到。
決定完工具後,就到了最後一步:架構設計與實作。因為是只開放給公司內部的 API Document,所以經過了各式各樣的嘗試後,決定用 S3 + API Gateway + Lambda 配上了 IP Restriction 完成 Hosting 跟身份驗證。再加上手癢寫了一個小 Plugin,讓 API Document 在產出靜態 HTML 時能在頁面上嵌入一個表單,讓使用者可以直接在網站針對特定 API 發問題,然後串到 Slack Bot 上做通知,就完成了全新的 API Document System。
事後回想,正因為這個專案是我主動跟主管提到「我觀察到了一個問題並想要試著解決看看」,因此我在做評估時有機會換位從更高一層去思考這個問題有沒有被解決的價值。在確認需求後,還要更謹慎去想如何解決這個問題以及要如何說服主管採取我提出的解決方案。
在這個的過程中透過之前所學,去一直問自己為什麼,也讓我最後對自己提出的方案能夠有比較深的理解。而因為我能夠負責到整個專案,因此也有機會去練習到完整的架構設計以及實作。如果我當初沒有主動要求去解決問題,也許我很難有機會這麼深入地從無到有去完成一個專案。
做筆記當作人腦的快取
做為一個菜鳥軟體工程師,除了一直反問自己為什麼,以及主動去要求解決問題外,我覺得另一項對我幫助很大的就是不停地做筆記。之前在貝殼放大以及 AppWorks 時,我就一直花很多時間在做筆記這件事上,但每次做筆記的目標都有所不同。
在貝殼學行銷時,做筆記是為了跟自己的學習有互動,把看文章或是上課的所學的輸入消化,輸出成自己的文字。在 AppWorks 時,做筆記的動力是為了追上當時筆記能力超強的實習生 Thomas,尋找自己的成長痛,練習強迫自己即時中翻英,用最有效率的方式馬上吸收再產出別人也能看懂的筆記。
在 LINE TV 時,因為不再是純粹聽講或是看書模式的學習,筆記反而更多的是在記錄自己做專案時的學習軌跡。作為一個新手工程師,我覺得記錄自己是如何解決問題是很有幫助的。在寫程式時很多時候會重複遇到類似的問題,有些解法繁雜或沒辦法用大腦記住,這時我們可以透過筆記很快的找到當初有效的解法,而不用重新丟到 Google 去 Stack Overflow Driven Development (SODD)。
舉例來說,在 JavaScript 裡面給定一大堆 key name 要建立一個 Object,就可以視有沒有給對應的 value 來用 array.reduce
或是 Object.fromEntries
處理:
// Method 1
const keys = ["key1", "key2", "key3"];
const obj = keys.reduce((accumulator, currentValue) => {
accumulator[currentValue] = undefined;
return accumulator;
}, {});
// Method 2
const keys = [["key1", "value1"], ["key2", "value2"], ["key3", "value3"]];
const obj = Object.fromEntries(keys);
又或是有預先宣告過的變數,想要用物件解構去賦值,可以用小括號完成解構:
let cat, dog, mouse;
let obj = { cat: "meow", dog: "woof", mouse: "squeak" };
({ cat, dog, mouse } = obj);
工程師的大腦容量有限,而需要記的指令、工具、解法太多,透過筆記可以做為我們大腦以及 Google 之間的快取 (Cache),就像作業系統一樣,增加往後存取解法的效率。
具體來說,只要開始一個新的專案,我就會新增一個資料夾專門放關於該專案的筆記以及各種當時參考資源的整理。像是在做金流訂單的付款與驗證系統時,我就筆記了當初川哥回應我問題的各種解答、當初的架構圖、以及實作上有什麼是在 Code Review 討論到可以修正的。而在做 CDN 優化時,我就把我看文件理解完的重點記下來,這樣之後要處理類似問題的時候就不用在回去重讀整份文件,只要看自己消化過的版本就好。
除此之外,我也會偷偷筆記所有同事跟我分享的小撇步或是秘招,像是俊緯會教我各種 git 的神奇語法、卡特教我直接透過改 etc/hosts
去測試 CORS、阿詹教我他都是怎麼在一個全新的 React 專案裡 trace code 的等等,這些東西集合起來久而久之就變成了我自己寫程式的筆記資料庫。
筆記除了幫助自己學習以及作為下次遇到相同問題的 Cache 以外,有時候還可以順便幫助到別人。舉例來說,在研究 Docker 和 Kubernetes 時,我當初順手做的筆記最後加上整理產出的教學文章,現在莫名累積超過 10 萬觀看。[3] 而我能夠在過了將近一年後還能回頭寫這篇文章,也是因為當初對自己的學習有些紀錄。
如果需要更多寫筆記與文章的理由,詳細可以參考這篇有名的 Learn in Public。[5]
對新手工程師最好的學習環境
我覺得在學習階段,對新手工程師最好的學習環境包含兩個條件:有人願意讓你嘗試以及有人願意讓你問。而在 LINE TV,這兩個條件都太極端的好。
從前面的段落應該可以看出來,我的主管 Wei 真的給了我非常非常非常多的信任與機會去學習新的技術與處理陌生的問題。不只每次 1 on 1 都會解答我各種天馬行空營運、產業、帶人、技術還有架構的問題、跟我討論我想學習的方向、讓我參加各種 AWS 和 LINE 的拜拜活動、還超級信任我敢放手給我權限玩公司的各種資源。Wei 讓我感覺到他很在乎我的成長,也因此我在 LINE TV 的這一年才可以肆無忌憚的最大化我的學習。
除了放手信任我以外,在 LINE TV 還有一群非常願意讓我問問題以及跟我分享的前輩們。感謝 Wei、川哥、卡特、Ray、Joel、阿詹、Linda、秀雯,不只願意讓我問笨問題,還超級願意教我各種技術和非技術的事情。到現在還能清楚記得每次川哥用大會議室的螢幕跟我一步步講解他是怎麼用 Helm 去管理公司全部的後端專案、各種川式浪漫的命名、istio 的前景。有一次 Wei 還訂大會議室專門讓川哥解答我研究 DevOps 後的相關問題,會議完也讓我能夠順手產出講解上版更新流程的內部文件。
而除了資深前輩們以外,更可遇不可求的是與其他的 Junior 一起學習的環境。感謝從同時進公司就一直很照顧我的俊緯,實習生聽團附中好夥伴思淇、後來的生力軍 Brad 和郁潔。
致謝
能夠來到 LINE TV 實習真的是很幸福以及幸運的事。還記得是大三下離開 AppWorks 後某次跟前老闆 Enid 聊到近況提到自己休學失敗,還在邊讀書邊找實習,結果隔幾天 Enid 就丟訊息來問我對 CHOCOLABS 的後端有沒有興趣。雖然那時候對後端的了解可以算是零,但抱持著先多嘗試的心態就答應了。把履歷給了 Wei 後就開始一個禮拜瘋狂惡補後端,最後幸運被收留。
當初因為想要多先看看希望在一年內實習兩家,所以還對實習要待上一年有點疑慮,但現在來看能夠在這待這麼久真的是物超所值(也感謝當初 Ryan 對於我疑慮的建議,真是處處被 AppWorks 凱瑞)。
在 LINE TV Backend Team 的這一年我從會寫一點程式的菜鳥開始學習成為一個好的軟體工程師。即使結束實習後去了 Grindr 又回到老本行寫前端,在 LINE TV 學到的收穫還是讓我處處受用。
感謝 Enid 當初的牽線,沒有 Enid 的介紹我當初就不會來到 LINE TV。感謝我的老闆 Wei 在各方面的用心與照顧,感謝川哥、卡特、Ray、Joel、阿詹、Linda、秀雯讓我總是有無數的東西可以學習,感謝俊緯、思淇、Brad、郁潔可以一起奮鬥過 Junior 階段。在 Backend Team 的這一年有大家真好!
最後的最後,分享紀錄是為了能夠讓人有個參考,如果幸運的話希望能夠幫助到人。如果有任何我可以幫助到你或是你剛好想接觸這些領域需要參考一些其他心得的,隨時歡迎訊息我 Facebook 或 Twitter!
備註
[1] 關於之前實習的心得紀錄請見:
[2] LINE TV 前身為 CHOCO TV,是台灣新創團隊巧克科技新媒體 CHOCO Media Entertainment(舊稱 CHOCOLABS)底下的一個產品。在我加入後的三個月(2018 年 11 月)獲 LINE 投資並與 LINE TV 整併。在文章中為避免不必要的混淆皆以 LINE TV 代稱 CHOCO Media Entertainment。
[3] Docker 與 Kubernetes 系列教學文章:
- 〈Docker 基礎教學與介紹 101〉
- 〈Kubernetes 基礎教學(一)原理介紹〉
- 〈Kubernetes 基礎教學(二)實作範例〉
- 〈Kubernetes 基礎教學(三)Helm 介紹與建立 Chart〉
[4] 後來才知道大名鼎鼎的 The Phoenix Project,不知道川哥是否是因此命名
[5] 關於這個作者的簡介可以參考:Hi, I’m swyx