何謂工程師?為什麼所有軟體工程師都該學資料結構與演算法、計算機架構、作業系統?


大資工時代,所有人都一窩蜂轉行、跨行進資工領域,尤其是這陣子人工智慧話題被炒起來,好像人人都該懂機器學習、深度學習。市面上產品好像都該有個「智慧」當作前墜,智慧手環、智慧眼鏡、智慧監控系統等等。而幾年前則是雲端技術很紅,所有東西都該加個雲。區塊鏈也被當作明日之星,各種公有鏈、私有鏈的新創如雨後春筍。再加上網頁前端、後端、手機 APP等人才需求本來就大,可以說資工領域的市場需求已經被捧到了極高點。

因為市場需求大,前景看好,所以很多人半路出家改當軟體工程師,這邊廣義包含各種程式開發的人才。國民教育都把資訊科學列為必修了,代表已經是全民皆碼農的時代。連非工程職位的業務、PM、顧問好像都必須會寫個 Python 才夠生存。

通常轉行來當軟體工程師的人大概分兩種,一種是去像是資策會的程式訓練班,再來就是自學摸索。不管哪一種,學習方法通常就是稍微懂點程式概念,然後開始用套件、工具,善用工具之後能開發出像樣的東西。以前端開發為例,只要會寫程式(HTML、CSS、JavaScript),然後會用前端框架(Angular、React),會改模板(Bootstrap、Ant Design),會用第三方函式庫(D3.js、Three.js),知道怎麼串接 API,差不多就合格了。剛剛說的這些東西基本上學習曲線不算陡,藉由程式訓練班或是自學都不會太難入門,學完之後大概也能找到 Junior 等級的軟體工程師職位,月薪大概介於 3–4 萬左右。

何謂工程

但你會發現我剛剛描述的內容有個共通點,就是都在使用工具,舉個例子形容的話,跟工匠、工人的感覺差不多。我沒有要歧視行業的意思,只是我相信:

轉行進軟體產業的人絕不該滿足於當個小小碼農

對於非本科生,該思考的是跟本科生的差別到底是甚麼?為甚麼叫做台大資訊工程學系交大資訊科學與工程研究所?顧名思義,資訊既是科學也是工程,科學的部分我們先不管,那是給 Google、Facebook 的資訊科學家和大學教授來煩惱,我們先著重工程的本質,我們來看看維基百科的定義:

工程,是通過研究與實踐應用數學、自然科學、社會學等基礎學科的知識,來達到改良各行業中現有材料、建築、機械、儀器、系統、化學和加工步驟的設計和應用方式一門學科。實踐與研究工程學的人叫做工程師。

你懂了嗎?那甚麼是軟體工程師?跟軟體工匠的差別在哪?

我根據上面對工程的定義來幫軟體工程師定義:

軟體工程師,是通過研究與應用資訊科學、計算機科學等資訊工程學門中的知識,來達到改良資訊產業中包含網頁前後端開發、機器學習、雲端應用、物聯網的設計和應用方式的一門學科。實踐與研究軟體工程的人,是為軟體工程師。

工程更簡單的定義就是運用科學來解決問題,軟體工程師如果欠缺基本的資訊科學知識,像是演算法、網路、數學等,當在工作上遇到更困難的問題時,恐怕就會缺乏解決問題的能力。但半路出家的工程師可想而知不會有跟資工系同學一樣的大學課程訓練。

工程的訓練又分兩部分,一部分是工程知識,一部分是工程素養。工程知識就是各種基礎科學、工程學的學習。工程素養可以理解成解決問題的能力更為重要,能洞察問體關鍵點、找到可行解決方案、分析不同策略好壞、將概念轉變成實務等等,一般工程科系的學生,透過大學課程和專題,通常可以訓練出還行的能力。不過這部分恐怕也不是三言兩語能說輕的,我這邊不多著墨。

必修三門課

我猜大家也很忙,通常也不可能真的去把資工系必修都去學一下,所以我列出三門我認為非常重要的資工必修課,任何軟體工程師都該修習過。絕對不是學業、社團、愛情,雖然他們很重要。分別是資料結構與演算法 (Data Structure and Algorithm, DSA)計算機結構 (Computer Architecture)作業系統 (Operation System)。如果你真的沒什麼時間,那最起碼 DSA 是最基本的;如果你還有更多時間,那我會說計算機網路、系統程式設計懂一下比較好,剩下就是你需要甚麼特別去學就行了,比方說走後端工程,那麼資料庫系統恐怕就是必帶了。

好的。我光鋪陳就花了一千五百字,接下來要進入重點了,所以為甚麼這三門最重要呢?

先以頂尖大學的資工研究所修業條件作為例證:

交大資科工所:

由本所規定之委員會審查該生之演算法概論、作業系統概論、計算機組織等三科是否修過大學部水準之課程。若有不足者,必須於畢業前完成補修通過大學部課程或選修通過研所相關課程;未完成者不能畢業。

台大資工所:

除資訊工程、資訊科學、資訊管理、資訊教育等系大學部畢業之學生,必須補修下列科目:(2 選 1:演算法設計與分析、自動機與形式語言)、作業系統、(2 選 1:計算機結構、數位系統與實驗)

可以看到我提出的三門課在台大和交大都列在非本科生需要補修的課程中。代表他們認為資工碩士生可以甚麼都不會,但這幾門課就是必須會!

資料結構與演算法

資料結構與演算法(DSA) 非常重要,可以說是老生常談了。它是所有資工系學生大一的必修,可想而知重要性。甚至不需要說,大家也會被迫瞭他很重要,因為只要對工程師能力有點要求的公司,通常都會考「白板題」,也就是讓你在白板上解決面試官提出的問題。通常就是問一些 DSA 的問題,比方實現 quick sort、解決八皇后問題、路徑規劃等。

有個最經典的例子,告訴我們 DSA 真的很重要:

<雖然我們公司 90%的工程師都用你開發的工具,但我們還是不聘用你>

事實上,你寫的程式碼好壞也直接取決於你對 DSA 是否熟悉。在寫程式的時候,必須有能力判斷該使用哪種資料結構和演算法,時間與空間不可兼得,當你為了縮短時間,往往代表你需要花費更多記憶體,反之亦然。同時,你也必須盡可能讓你的程式碼是最佳解,最省時間或最省空間,如果沒有 DSA 的知識,往往程式碼就會毫無效率。在一般小型應用可能無所謂,但一旦到大系統,每次運算差 10ms,一百萬次的執行就會差 166 分鐘,想想假設你是 Facebook 的工程師,每天使用者的請求(Request)以數十數億計算,那更是差多少?

DSA 作為最基礎的學問,在各種情景都會用到,但如何應用又是另外一回事。例如字串比對就有非常多演算法,根據被比對的字串長度、拿來比對的字串長度、需不需要同時知道比對成功的位子、還是只要知道裡面比對成功的子字串數量、記憶體空間有沒有被限制,隨著不同的條件,每個 DSA 都會有它自己的優劣勢,要怎樣選擇用哪種,以及分析採用之後的效能,就是工程素養的部分了。

作業系統

作業系統(OS)比軟體還要底層,我們的各種應用程式、執行序都是建立在作業系統之上。作業系統會負責幫忙做程序排程、記憶體控管、檔案系統、網路通訊等非常底層東西。

通常我們寫程式,通常不用去管上述的那些雜事。例如你只要讓你的程式跑起來,作業系統會自己幫你安排它的排程,根據你程式需要的記憶體幫你從系統中安排記憶體位置。但是這是小程式的形況,寫大型程式完就不是這麼回事了。

大型應用程式,包含各種大型框架,例如網頁瀏覽器、資料庫系統、Angular 框架,都會應用到作業系統中的概念。以資料庫系統來說,DB 的資料要怎樣儲存、每個使用者在操作 DB 時的 query 要怎麼安排執行順序、使用者使用 DB 時的資料快取機制,這些東西通通會用到跟作業系統一樣的概念。所以可以說,大型軟體系統其實就是 OS 的縮影,小型軟體則處處可見 OS 概念的蹤跡。

作業系統除了讓我們了解到 Linux、Windows 是怎麼動的之外,更重要的是它實作的各種機制,往往在軟體開發上都會用到,概念都是一脈相承。所以軟體工程師如果不懂 OS,要怎麼開發軟體呢?

計算機架構

計算機架構全名應該是計算機結構與架構(Computer Organisation and Architecture, COA)。滿有趣的是,台大叫做計算機架構,交大叫做計算機結構,不過其實教的東西都一樣。但其實結構跟架構還是有點區分。

像是 Intel 和 AMD ,它們都是使用 x86 架構的處理器,但是兩家公司對架構實作細節可能會不一樣,也就是結構上不同。市面上還有其他架構像是 x64、MIPS、Risc-V 等,都是用同一套結構理論,也就是都是由 ALU、記憶體、暫存器等零件組成。

計算機架構的層級又比 OS 更低了,已經屬於硬體理論的層次。但它也一樣很重要,因為任何程式執行往往要考慮計算機的架構。

計算機架構包含 CPU、GPU、記憶體等,例如為甚麼數字比對比字串比對還要快?因為暫存器只能存放數字,所以字串要比對的話,必須先轉換成數字,放到暫存器,然後才能比對。相較於數字直接放到暫存器來說,當然就比較慢了。還有像是循環展開(loop unrolling )為甚麼能加速迴圈執行的速度?還有像是為甚麼深度學習要交給 GPU 來算?以及為甚麼 Google 不用 GPU 開發自己的 TPU 來做深度學習。這些其實都跟計算機架構有關。

計算機架構對於軟體工程師來說,可能懂計算機裡面的設計是怎樣不是很重要,但了解程式如何寫可以讓它在現行架構可以跑最快卻是很關鍵的議題。

結論

相信大家已經能了解為甚麼我認為這三門課是所有軟體工程師都該具備的必修課。軟體工程真的與這三門課習習相關。

所以有句話是:

資料結構與演算法解決不了的問題,交給作業系統來處理。作業系統也解決不了的問題,從計算機架構來想辦法。

軟體工程絕對不是堆堆積木用用工具,那樣只是碼農。軟體工程真正來說是門藝術,我們透過各種理論想辦法讓程式可以跑得最快,突破原本的效能瓶頸。學會這三門課的你,已經成為計算機最速傳說!

最後引用 Vgod 的話勉勵大家:

「如果以蓋大樓來形容這個概念,把砌磚作為一種技能,把蓋大樓作為一種知識。我想可以這麼講:如果你早就知道你喜歡砌磚,很會砌磚,就直接去砌磚吧。如果你的夢想是蓋大樓,你要學的東西還很多,那讀大學是你最好的途徑。不是每個人都要蓋大樓,靠砌磚就可以賺錢了,砌的好還可以賺很多錢,大家搶著要。」 — Vgod