USC 課業

前言

離上一篇網誌距也已經過了三年。三年來,在美國留學生活工作留下許多深刻的回憶和經驗,我想將這部分的心路歷程分享給每一個人。我將以下主題逐一寫成網誌,希望你們喜歡,歡迎轉載註明出處。

  • USC課業
  • 洛杉磯生活
  • 找工求職1 校園活動
  • 找工求職2 實力成長
  • 找工求職3 面試流程
  • 找工求職4 實際面試

讓我們從 USC 課業開始吧!

南加大CS的課程很有趣,不但給予身為CS人基礎知識外,也能提供時下火紅領域的進階概念。可是如果問我這些課程對找工作有沒有幫助,我會說有,但是不那麼顯而易見。這篇文章我想透過經歷、見解、事後回顧,給予 USC 的課程中肯且有用的評價。

碩一學習了 Algorithm Analysis, AI, Web Technology and Robotics。碩二學習了 Software Engineering, Machine Learning, Web Search Engine and Information Retrieval。碩一集中學習基礎知識,選 Robotics 是因為學程特殊原因,其他三門課都算 CS 基礎知識。碩二則是開始選修其他較為專業課程,加上心思得多放一些在面試刷題上,所以我只選了三門課。讓我一一介紹我上過的課程。

Analysis of Algorithm

我很喜歡 Analysis of Algorithm,因為以前我寫程式並不在意執行效率的問題,而且現今大部分的演算法都有library支援,所以很少需要去思考這部分。這門課帶你拋開程式碼,用紙筆來思考現實中的問題如何用演算解決,分析演算法的每個步驟如何執行需要多少空間和時間。這門課同時也是跟軟體工程師面試最直接相關的課程,因為面試中也是需要當下用程式解決面試官提出的問題,在白板上分析和討論解法優劣。不過老實說許多進階的演算法,我們多數用在面試的題目上而已。拿來工作上活用的,不容易是貪婪、divide and conquer、動態規劃、network flow,而大多會是字串處理、資料結構、search,這些一般人能理解的的方法來處理。

Web Technology

這門課帶我們做完一系列網路應用相關的作業。網頁框架,後端程式,使用雲端服務,寫 mobile app。雖然聽上去是一套完整的訓練,可是因為時間的關係,每一個部分都只能點到為止。這門課結束後我感到害怕,因為我沒有感受到我獲得一個帶著走的技能。至今我不會說我懂得網頁前端,php 和 node.js 該怎麼寫以及 server 該怎麼架對我仍然不是那麼清晰。雲端服務千百種我們用了其中一種,我們只按了 “Deploy” 按鈕上傳 server side code,剩下全權交給服務商,我感到一知半解。用 Swift 寫 iOS App,可是都在透過 CocoaPod 使用 dependencies 上的 functions。Xcode 上粗略練習 MVC 架構,也不知道交出去的那套是否經得起考驗。儘管如此,這樣一套課程學下來算是帶你一窺網路服務系統架構。我記得面試時被問到系統設計。面試官要我說說像 Uber的叫車服務該怎麼設計。我們討論一些需求,然後我用這門課教的內容給出大致上的架構,加上一些想像的 Components 拼湊出一個我也不知道能不能動的東西 (XD),也算是避免一問三不知的窘境。

Foundations of Artificial Intelligence

AI 稍微好一些。一開始學搜尋演算法,接著講 Minimax Tree 系列,不過最後你也只會記得他們而已,因為接下來教的是邏輯表達式和各類學習模型。如果我們不走向研究,通常這兩者不太有活用的機會。這門課唯一有趣的地方是作業,助教群使用線上批改系統驗證我們作業正確度,同時也舉行淘汰賽 PK 學生之間的 Minimax Tree。以前我未曾想過程式作業可以被這樣活用,也因此我花了點時間仔細理解 Minimax 和 alpha-beta prunning 希望爭取好成績。可惜第一輪就被淘汰了。儘管如此,那一次的作業讓我印象深刻,也使我花上時間仔細研究它。之後拿改良版的成果幸運爭取到助教職缺。

Robotics

開始來到進階的課程。Robotics 是在 CS 系上是一門很玄的課,因為通常CS的課要求的背景知識是單純的邏輯,而這門課要求的是一定程度的數學。課堂上用到線性代數,矩陣微分,偏微分,Jacobian,用這些數學來計算機器手臂關節角度與手指端在空間中的關係。除此之外,還有介紹機械控制模型,帶你用實驗室做好的 framework 粗略寫寫邏輯來控制機器人的關節。這是我無法跟過往的經驗產稱連結的內容,坐在教室座位上我鴨子聽雷。老實說我的微積分基礎不好,以前大學時全校有微積分百名榜我從來也沒進入過。頓時間,我不理解我坐在教室用意何在。支撐我早上起了大早進教室上課的是一個可愛的女同學,還有期待可以進一步交往的心情。雖然說這門課對於培養軟體工程師的技能幫助不大,卻也讓我被迫花了些時間複習數學。秉持著數學練好對寫程式沒有壞處的想法,最後還是乖乖修完這門課。不得不說,練習數學對我的幫助很大,正好幫助我之後 ML 的課程。

Machine Learning

機器學習是當代顯學,這年頭的 CS 畢業生似乎手中拿不出一個 Learning Model 都不像從 CS 畢業的人。現在聽起來蠻可笑的,但我那時候的確覺得身為 CS 的人 Machine Learning 該好好學。大學時上過 Machine Learning,也做了一個影像辨識的 Project。可是充其量我對這領域的知識侷限在 matlab 上的 neural network library,其餘一概不懂。選擇這門課一方面是跟風,另一方面是想將過去的知識漏洞補齊。

CS 的 Machine Learning
十分偏重數學理論,許多常見的模型都可以用數學描述是如何最小化誤差來達到學習的效果。比起單純的使用各種 libaray 我十分喜歡這門課帶我們深刻理解背後含義的教學方式。學習的過程雖然得辛苦地沒日沒夜跟數學奮戰,一下機率統計,一下線性代數偏微分,但是,幸虧之前 Robotics 的課有先對我的數學訓練一番,否則我真的會有點吃不消的。然而,能夠有人帶著了解困擾許久的問題是一件很難得而且美好的事!在上這門課的時候,我有個小野心。當時的我希望有機會可以在某個地方試著當Machine Learning的助教,挑戰看看我是否有能力去帶著一群人理解這個領域的奧妙。有了這個動機,我更努力的學習。除了盡可能弄懂所有作業與考試中的題目,釐清背後的邏輯,也去了解程式作業,熟悉課堂中的模型是怎麼透過 numpy 實作出來的。這門課讓我大開眼界的地方就是程式作業,雖然我們只要填上挖空的部分,但是整體的 python 架構看起來是那麼的清晰簡潔。我還記得 neural network 的 forward/ back propagation 寫的非常好。上這門課除了了解 ML 數學含義外,也學習不少python技巧。

Software Engineering

軟體工程是一門深奧的學問,但是我感覺幾乎不可能在學校學好。舉個例子,讓程式可以Demo 與讓程式可以持續運行半年不出問題絕對是兩回事。許多軟體工程的知識和前人累積的智慧,大多用來解決架構龐大和需要維護的產品。如果將它們應用在學生 project 很容易拖慢進度,因為學生不需要在 Demo 後繼續對程式負責,學生可以用 Fast&Dirty 實作方式快速完成作業,以便爭取到更多自由時間。

這門課編排上並不是那麼容易學習到軟體工程的精髓。課堂開始班上的人會先分組,接著會有業界的導師們來帶著我們一起完成某項專案,同時 USC 的老師和助教們從旁協助我們按照進度完成專案項目,也在課堂上講授軟體工程學問。乍看之下沒什麼問題,卻隱藏一些缺點。

  1. 導師傾向讓我們完成一個新的專案,而不是維護舊有的程式庫。新專案的好處是導師們不用冒險承擔學生搞壞現有系統,卻損失閱讀程式碼從並中抽絲剝繭出背後邏輯的機會。閱讀程式很重要,因為任何軟體工程師的起頭都是閱讀他人的程式碼。少了這個步驟,工程師不容易深入理解系統的全貌。也更別說發現系統的問題,進而提出方法改善。軟體工程是為了解決前人留下來程式難以被重複使用的問題,開發新專案不容易見到效果。
  2. 團體作業容易只有少數人出力。這是學生時代一直都有的問題。大學時,我在電腦攻擊與防禦課也曾經是掛名組員。不是每個人都有辦法適應同一門課並且學習。原因很多,有好的,有壞的。有人想學不得要領,有人只會紙上談兵,也有人無心課業只求 Pass。這些人組隊攻克團體作業,接著壓力都擔到少數人身上,最後沒有人學到如何團隊合作,少數玩家單打獨鬥。
  3. 難以運用軟體工程方法或感受它的效益,稍微深入探討一番。課堂上教的方法,例如敏捷開發、時間估計、Design Pattern、Testing Coverage,等等,都是蠻常見的方法。只可惜場景換成學生專案會變一個樣。計畫討論熱絡,只有少數人開發,沒時間做測試,不知道怎麼Review,敏捷開發變成持續開發直到demo。接著,時間估計是個難題,只有在對專案內容有一定的了解後,估計才有意義,然而這不容易。如果是一個已知的領域,我們可能只要計算寫程式時間,如果是未知領域,我們得囊括資料搜集、學習、實驗、實作、測試。每一個步驟都是未知數,得需要對自己的能力有相當的掌握才行。除此之外,Design Pattern 最好的學習方式是丟給你一個凌亂的 legacy codebase,你就會體會到它的重要性。Design Pattern 提供一種約定俗成物件導向設計的方法,教我們如何運用繼承和實作介面。它使得程式碼實作上有共同語言,使得前人的程式碼容易被理解。然而當開發者只有少數人時,程式生命不長時,他的重要性也就下降。大家在意的更多是讓程式動起來,而非乾淨整潔易於理解。最後,Testing Coverage 就別說了,沒有測試,哪來的涵蓋率可以討論。

說了這麼多,我可以感覺到目前 USC 的軟體工程課仍然有實驗性質。尋找不同的業界導師、嘗試不同的軟體工程方法,對一門需要存在幾十年的課程來說不斷的嘗試沒有問題。可是對於學生,我們很難學到軟體工程的奧妙之處。一來學生專案很難有軟體工程存在的必要,二來歷年課程好壞不一,很大程度決定於合作業界導師和組員。當然這門課也是有優點的,正因為帶有實驗性質,我們可以多方嘗試錯誤。例如,一週懶得打程式拖慢進度、隨便跟組員鬧不合、不交報告等教授來催、開會不到或維持靜音、隨便估計時間、不做測試、對 code review 吹毛求疵、當掛名組員、用爛英文言之無物,等等。我很感謝教授跟我說,身為學生現在犯錯不會有人說什麼,同時也點醒我以後進入業界別人可不會這麼想。當時我跟教授起衝突,教授卻不放在心上,反而跟我闡明道理。對我來說,是這堂課最珍貴的地方了。

Web Search Engine and Information Retrieval

這是我在 USC 最後一學期修的最後一門課。老實說我對他的記憶不深,在眾多課程中它屬於涼課。印象中作業有交、考試有到,就能過,選這門課的原因是想多花點時間刷題準備面試。我記得課程內容還算有趣,教授除了自己的講義外,會拿 stanford 的講義、論文、網誌、影片做補充材料。作業部份有寫爬蟲抓網頁、使用搜尋引擎 library,是個練習java和php的好時機。我當時懶惰用肉眼檢查搜尋後網頁顯示的結果,就用 php 寫了 script 驗證。雖然不在評分項目內,寫著玩也挺有趣的。此外,考試部分盡量背就是了沒什麼訣竅。總體而言是個評分標準不高,內容卻豐富的課,很值得佛系學習。

結語

USC 課程多樣,有基礎,有進階。因為評分標準不苛刻(似乎除了database例外?),只要花時間通常會有不錯的成績。也因為學習材料豐富可以由學生自主學習想學多深,我覺得在 USC 念 CS Master 可以自由規劃學習步調,讓我有充足的時間準備面試。課業和找工上時間分配有足夠的彈性。

課程多樣之下,選擇變得很重要。選課前得多方打聽前人的經驗,選擇適合你節奏的課程。同時保留一些彈性,因為有的時候課程會不如預期,甚至會覺得像是學費丟進水裡。我很幸運,這七堂課我都有充分利用它們的優勢來安排節奏,讓我實力迅速成長,對於找工作、撰寫履歷、練習面試都有很好的效果。