美國大學 Computer Science - 教了什麼 ?

在四年制的美國大學資工系 Computer Science Major 到底都教了些什麼,而又能學到什麼呢?四年的時間不長也不短,但剛好適合讓人入門一項新的技術。而美國的大學最不同的就是入學前不需要選定專業,這讓還有志向的學生能夠在第一年的大學生活中體驗不同科系的樂趣。

美國大學 Computer Science - 教了什麼 ?

在四年制的美國大學資工系 Computer Science Major 到底都教了些什麼,而又能學到什麼呢?四年的時間不長也不短,但剛好適合讓人入門一項新的技術。而美國的大學最不同的就是入學前不需要選定專業,這讓還有志向的學生能夠在第一年的大學生活中體驗不同科系的樂趣。

這系列文章會分成兩個部分,分別是以我的經驗來分享四年的 CS 大學裡學校 (1) 教了什麼(2) 沒教什麼,而如果後面還有想分享的我會繼續補上。這一篇則會專注在美國大學資工專業到底都教了什麼

CS 技能天賦圖

University of California, Santa Cruz 舊版 Computer Science Curriculum Chart,這只是大概而已,實際上還有更多課程和選擇!

我覺得大學的升學之路大多數都非常相似,就和玩網路遊戲一樣。就是每一學期升一個等級,然後得到一些技能點數,然後根據需求分配點數給各項技能,慢慢的建立起自己的技能樹。下面用我以前的學校來介紹一下遊戲規則。

上課升等的遊戲

一年有三個學期,而每一個新的學期學生可以選擇 15-22 個技能點數值得課程。普通課程要 5 點,小型實驗課程只要兩點。如果上一學期成績優秀則可以申請得到高於 22 學分的技能點數,但學校會根據成績來批准學生的要求。

選擇職業 - 完成所有入門課程後被學校認可為 CS 專業成為 CS 初階生。
      ↓
CS 初階生 - 學生可以開始學習初階技能,並且在完成所有初階技能後進階。
      ↓
CS 中階生 - 學生可以學習所有中階技能,並且在完成多數中階技能後進階。
      ↓
CS 高階生 - 學生必須習得規定高階技能,並選擇兩條畢業路線。
      ↓ ⇢ 完成一個專案
      ↓ ⇢ 完成一篇論文
CS 畢業生 - 畢業後可以選擇多條路線
      ⇢ 繼續研讀
           ⌙→ 研究生 Master
           ⌙→ 博士生 PhD
      ⇢ 面試獲得轉職機會
           ⌙→ 前端工程師
           ⌙→ 後端工程師
           ⌙→ 系統工程師
           ...... (各種不同類型的 Software Engineer)

特別可以注意的一點是,在美國大學無論時長,只要在完成畢業要求後申請畢業就能獲得畢業證書。所以常聽到有人 2-3 年就畢業獲得學位,也聽過有人過了 6 年還沒取得畢業資格。

💡畢業不過就是獲得了最基本的工程師資格、取得了和各個公司面試的機會。但每個人的在學時所點的技能天賦圖除了路線不同外,技能質量也會不所同,還有人可以近乎點滿所有技能,甚至開拓額外隱藏技能等等。簡單來說單單一張畢業證書在職場上是沒有什麼競爭力的,除非是史丹佛或哈佛之類的畢業生。

課程內容 Curriculum

因為這篇的主旨是美國大學資工專業到底都教了什麼,所以接下來要大致分類各項技能的內容啦!

技能介紹課

在進入入門技能之前,我們學校有一堂超級無敵簡單的零基礎課程。雖然還是要學一點點編程,但比起說是編程更像是畫圖。我們那時候學了一個叫做 Processing 的東西,當時只知道就是用來畫圖和做簡單動畫的。後來學到中階技能後才知道這到底是什麼。課程內容就是講述電腦的歷史一些簡單又重要的知識像是霍夫曼編碼 Huffman coding、做幾個簡單的遊戲專案像是圈圈擦擦。

入門技能

入門技能是在還沒有成為 CS 專業時就可以學習的課程,其用意是在確認學生真的對 CS 有興趣。課程難度其實對毫無 CS 經驗的學生來說是非常不容易的,但對已經有基本功的人來說並沒有什麼難度。我的學校甚至把入門路線分成了三條,(1) 兩堂超級入門課 + 一堂中等課 (2) 兩堂課中等課 (3) 一堂超級濃縮困難課。選擇路線 ③ 繼本上就是一學期把其餘人一年的課程內容都上完。

入門技能的主要內容就是基礎的 編程 Programing 和簡單的 資料結構Data Structure。根據時代、選課、和學校的不同,教授的編程語言也不太一樣。像是2014年時大多數學校都是用 Java 來教課的,但近年來大多數學校慢慢改成 Python 為主了,畢竟比較容易上手而且用途廣泛不局限於 CS 專業。

在這幾堂課的學習過程中,如果是零 CS 基礎的學生,我印象中會學習到:
基本的編程語言,我們學校是 Java、Python、或 C++
常見的資料結構像是 哈希表Hashmap、陣列 Array、鏈表 Linked List,和一些衍生結構 Stack & Queue 等等。
各種排序算法 Sorting Algorithm,Bubble Sort、Quick Sort、Merge Sort... 一大堆,還有像是 二分查找算法 Binary Search 等等
使用終端機 Terminal 學習到簡單的 Linux 系統指令
   - 切換目錄(就像打開資料夾一樣)
   - 文件的編輯、創建、刪除
   - 遠端登入
   - ...... 各種基本上你已經用點腦做過的東西,只是用終端機看起來很厲害而已。
下面放個短片,有興趣可以看看上面說的都是幹嘛的!

入門課程中還會有一堂課程被稱作是“勸退課程”,以我們學校來說就是入門路線中必經的最後一堂課 Data Structure。實話說真的不難,但是如果不認真學的話是會很容易被當的那種課。

這段時間學的入門技能真的非常基本,但對毫無基礎的人來說可能像是碰見新大陸一樣什麼都沒聽過。這些技能是未來課程和工作的基底,內容都算是 Software Engineer 的常識。

初階技能

在和學校申報轉業 Declare Major 後,則正式進入了 CS 專業的學習路程。以我們學校來說,初階的課程開始有許多的先修課 prerequisite 要求,像是修某堂課前必需先完成微積分、離散數學等等。而課程內容則開始包括一些基本的抽象資料型別 Abstract Data Type電腦架構 Computer Architecture、彙編語言 Assembly 等等。

Discrete Math 曾經的作業已經一頭霧水了...現在突然覺得以前的自己好像滿厲害的!

數學方面 微積分 就不用我多做說明了,但 離散數學 Discrete Math 就不一定是大家都聽過的了。這堂課的內容不少,要學 概率、組合分析、數學歸納法(proof by induction)等等。反正都是一些數學和證明之類的,我覺得如果高中數學有好好學,至少在機率方面不會有大問題。

以前邏輯運算的作業

Assembly Language 彙編語言 就是完全一個新世界了!和入門時學的高階語言不同,像 Assembly 這種低階語言是用於底層硬件操作等等的。我覺得這語言和 Python 那種語言不同的最大點就是難寫,簡單的東西 Python 只要兩三行,但 Assembly 卻要十幾二十行,只能說專門寫 Assembly 的人真厲害。課程中除了要學 Assembly 外,還要學一些 邏輯閘、集成電路組建等等,作業則是用模擬器用各種邏輯做出一些小程序。在這堂課中我才認識到原來我們的電腦軟體也不過是些相較複雜的電路而已!

Computer Architecture 電腦架構 是一門我沒有好好學,至今仍感到後悔的其中一堂課。內容是教一些像是 CPU、Memory 等等的底層內容,這對未來在 System Engineering 有關的內容非常相關。

以前課堂的 PowerPoint

初階技能中我認為最重要的就是 抽象資料型別 Abstract Data Type 了!因為絕大多數的面試考題都和這堂課的內容有關。學習內容有各種不同的抽象資料型別像是用初級技能中學過的 陣列 Array 或 鏈表 Linked List 來表示一個抽象的 樹狀資料型別 Tree,還要學習如何算出算法的 時間複雜度 Time Complexity。這些都是面試時 100% 會遇到的問題。

中階技能

這裡的技能開始有很多分枝,而且內容對沒有 CS 背景的人會感到生澀,所以這裡不會介紹所有課程內容係項,只選幾門我認為比較大眾的來說說。
Agile Development 會學的 Kanban Board

中階技能開始所學習的東西都開始變得越來越有專業性了。內容包括 編譯器開放 Compiler Design、敏捷 Agile Development、演算法解析 Analysis of Algorithm、作業系統  Operating System 等等許多。但雖說是具有專業性,但其實現在許多工作並不會要求員工具備這些技能,即便如此我依舊認為這些仍然是作為一個優秀的 CS 工程師所的必備知識。換句話說,這些技能大多數對未來職業的選擇沒有太直接的關係,但精通它們的優點會更容易體現在許多職業的發展上。舉個例子,同樣是寫軟體的兩人,當東西出了問題並且問題不是在代碼上,而是更加裏層的東西像是作業系統上時,這些技能包準能讓你在團隊裡一鳴驚人 😏。

編譯器開放 Compiler Design 這堂課以我的角度來說就是一個字~「難」。內容就是教授如何將我們平時寫好的高階語言 (C++, Java, ...) 翻譯成機器讀得懂的代碼。我記得當時考完了期中考試,公佈成績後雖然是 A+ 但我憑良心講,我非常認真地聽課,也去了每一個課後輔導,但自己真的還是沒理解多少內容。當時坐我旁邊的那兩個學生就在那竊竊私語說到:「這課也不怎麼樣,我覺得挺簡單的」。於是我偷偷的撇了一眼那兩人的考卷... 這不是只有個 B 和 B+ 而已嗎,他們哪來的自信?只能說對於這項技能是我學藝不精,至今尚且未能參透其中奧妙。

演算法解析 Analysis of Algorithm 是一門極其重要的課,各種理論知識以及著名演算法等著你一一了解。從各種 圖算法 Graphing Algorithm 到理解 動態編程 Dynamic Algorithm,許多對未來寫軟體時會有大幫助的東西都會在這堂課中學到。舉列來說 Google Interview 裡常碰到的題目,像是寫一個算法找出圖中某一點的所有相近色塊,這時就要考你對圖算法中 DFS 這種基本算法有沒有辦法靈活運用了。這是一門非常有深度的課,但也是我有史以來最認真的一堂課。當時班上居然有一位長得非常楚楚動人的學姊,所以這一堂課成為我大學生涯中唯一一堂出席全滿的電腦課!所以 A+ 也是運氣運氣。

作業系統  Operating System 這堂課就是在教大家平時使用的 Mac OSX 、Windows、和 Linux 這些作業系統的運作原理了。其中會教各種 Process 進程、Thread 線程、File System 資料系統 的運作原理等等。這門課我們學校是直接拿 Stanford 同名課程的教材來用的,我那時也是學的頭有點痛,所以只能說 Stanford 學生還是挺厲害的。現在回想起來當時真該好好磨練一下這項技能,雖然 A- 也是個不錯的成績,但這項技能對我目前的工作內容有極大的額外幫助,若時能再更努力一些也許現在就會更好了!

高階技能

那時上網頁開發時的作品

到了高階技能時,技能的內容與未來職業的發展開始有了比較直接的關係。這些技能雖說和職業路線已經扯上邊了,雖然沒接觸過的人肯定是會覺得稍微有些生澀的,不過這一些技能是 CS 學習路程中最讓人感到有趣的!這些課程有像是 Mobile Application Design 手機 App 開發、Web Application Design 網頁開發、Machine Learning 機器學習、Artificial Intelligent 人工智能、以及各個中階技能的進階課程等等,課程的數量多到上不完。這些課程的內容許多都是可以滿足畢業要求的,而且在學習的途中許多人也可以發掘出更適合自己未來的職業道路。所以與其說是高階技能,也可以稱作職業入門技能

這些課程的內容大概也不用多做說明了,就是大家比較常聽到的工作內容了。比較值得一提的是這些內容雖然是有比較重的工作性質,但內容還是偏向基礎與介紹。想要更加深入的理解各項技術的內容,還是必須繼續研讀或是在職場上闖一翻。


結語

到這邊大概介紹了在美國大學 CS 四年的課綱裡到底都教了些什麼。說真的學校能教給學生的很多,但卻偏偏不夠多讓人在職場上出類拔萃。學校能給的東西大多數都是基本功,即便是非常好的大學也一樣。四年的時間裡學校能教的不多,更多是取決於學生本身能夠吸收多少。

我是小貓貓工程師,
期待下次繼續與你分享,
美國大學 CS 有關的各種大小事。