前兩天給小學妹闡述了一下本校電腦科學與技術專業本科生需要掌握的知識體系。自覺比較有道理,整理一下發上來。適合的閱讀對象:剛進入電腦系,對整個電腦科學技術的知識體系尚未瞭解的同學。本校學生獲益尤大。
整個電腦科學就像人一樣,有兩條腿。一條叫做數學(基礎),一條叫做物理(基礎)。數學主要指的是數理邏輯。其中比較重要的是形式邏輯系統、Turing論題和Churcher論題。形式邏輯系統用邏輯的方法描述這個世界,在寥寥數條公理和推斷規則之上構築了整個邏輯系統、數論系統乃至電腦科學。Turing論題是電腦科學的基礎,它點出了形式邏輯系統的威力:只要是人能計算的,機器都能用形式邏輯的規則進行計算。並且它提出了一種實現的方法,就是Turing機。Churcher論題指出了形式邏輯系統的不足:人能證明的,機器不一定能證明。更準確的說是,在形式邏輯系統中,不存在一種通用的演算法,能判斷所有命題的真假。這就是電腦科學的數學基礎。
而電腦技術的物理基礎就是數字邏輯電路。這裡不說類比電路啊電磁學啊,因為感覺和“邏輯”聯絡不是很大。首先數字電路中給出了邏輯的電路實現,比如如何?這樣的電路——僅當兩輸入均為高電平時輸出為高電平——即與門。然後數字電路給出了組合邏輯的設計方法。這直接使算數邏輯單位(ALU)的設計成為可能。最後,數字電路給出了時序邏輯的設計方法,典型的結果就是寄存器、計數器的出現,使得時序控製成為可能。
但僅僅是數學和物理遠不足以構成電腦科學與技術這樣龐大複雜的知識體系。從曆史的角度來看,對計算能力的渴求直接造就了電腦的出現。什麼是電腦?高效完成計算的機器。為了實現用機器來高效計算這個目標,我們至少需要解決兩個問題:首先,如何和機器溝通,亦即如何讓它明白自己應當做什麼,這就是軟體知識系統的起源。然後,機器自身如何運作,這就是硬體知識系統的起源。再後來,隨著時代的進一步發展,又誕生了很多對計算能力也有需求的新的科學分支,於是如何應用電腦的科學也就應運而生了。下面將從硬體、軟體、應用這三個層次,自底向上分析電腦科學技術的知識架構。
數字電路已經實現了ALU、寄存器(儲存空間)等等基本組件。下一個問題就是如何用這些組件構成一個能完成高效計算的機器。現代常用電腦的體繫結構是由馮.諾依曼同學指定的,稱為馮.諾依曼結構。這位同學把整個電腦拆成了5大塊:運算器、控制器、儲存空間、輸出裝置和輸出裝置。電腦採用2進位。指令和資料以同等的地位存放在儲存空間裡。電腦進行計算時,控制器負責全域的調度,先去儲存空間拿指令,然後根據指令的內容(比如要求計算a + b)去儲存空間取運算元(比如取回a和b)。隨後將運算元(a和b)和操作類別(加法)送給運算器,運算器算啊算啊,算好了再根據控制器的指示把結果(a + b的和)送回儲存空間。這就是電腦中最簡單的工作流程。關於電腦究竟是怎麼幹活的,在電腦群組成原理這門課中進行介紹。這門課程不僅介紹了整個電腦系統的組成,而且分別詳細介紹了各個組件的工作原理,比如匯流排、儲存空間等等。最後,還會涉及到CPU的設計等問題。
在科大,硬體實驗也是硬體學習不可或缺的組成部分。數字電路實驗主要給同學們一個實踐基本的電路設計方法的機會。現代的電路設計不像以前畫電路圖,然後手工蝕刻那樣麻煩,而是採用硬體描述語言(HDL)的方式。在電腦上敲敲代碼,告訴電腦你想設計一個什麼樣的電路,電腦就會自動進行綜合、布線,最終將結果燒到FPGA或者CPLD這樣的晶片裡就可以直接用了。數字電路實驗就是讓同學們體驗一下這樣的過程,瞭解HDL和FPGA的基本使用方法。至於電腦群組成原理實驗,主要是讓同學們利用HDL設計電腦的各個部分,如寄存器堆、時序控制組件、SRAM、程式計數器等等。最後設計一個簡單的8指令CPU。至於更複雜CPU——比如16指令、32指令乃至相容8086指令集的CPU——的設計,留到CPU設計與測試這門課中講解。
有了電腦群組成原理的基礎,電腦就可以造出來了。更高一層的課程是將原理拓展到實踐——微機原理。這門課程以現代常用的x86架構為例,介紹8086處理器典型的指令,讓人和電腦的互動在現實中成為可能。在這門課裡,將會教授如何通過機器語言和組合語言和電腦進行最底層的溝通,讓電腦按照人的指令進行計算。可以說,到了這門科學發展起來的時候,電腦已經進入實用的階段了。
一門科學不涉及定量的數學計算,自稱“科學”時總是沒有什麼底氣。本科階段接觸的硬體方面的頂級課程——電腦體繫結構——就給了硬體科學這樣的底氣。這門課從數學的角度介紹了量化評量電腦效能的方法,並且從不同的角度給出了最佳化電腦性的手段:指令集的合理設計、流水線技術、快取的合理設定等等。至此,本科階段學習的硬體課程告一段落。
下面介紹軟體方面的知識。這一部分對於非電腦科學與技術專業,比如電腦應用、電腦工程甚至非電腦專業的同學來說就相對熟悉了。在介紹整個知識體系之前,我們先來看一下典型的軟體開發的流程:
拿到一個軟體開發工作單位——往小了說比如就是平時上課的一個project,第一步就是需求分析:分析這個程式的輸入是什麼、輸出是什麼,輸出和輸入之間滿足怎樣的數學關係。在確定了需求以後,需要進行的就是演算法分析:分析這個問題如何進行求解。根據典型的演算法設計思想,結合既有的常用演算法確定適用於這個問題的演算法——是用最土的深搜,廣搜,還是動態規劃、貪心,或者更進階的A*搜尋、子句歸結等等。確定了演算法之後,就需要根據設定的演算法來確定演算法實現的基礎——資料結構。比如演算法只要求對相鄰元素的訪問但是插入刪除操作頻繁,採用鏈表就好;要求對線性元素的隨機訪問,就需要順序表或者雜湊表等等。在確定了資料結構以後,不要忘了對整個軟體的架構進行驗證:根據演算法劃分的模組是否足夠合理,它們能否正常配合工作?因為整個程式的架構一旦到了實際編碼階段很難再更改,所以在編碼前應當專門留心思考。接下來的工作就簡單了:實際編碼、調試、測試等等。當然,以上的各步之間順序是可以更改的,比如Thinking in C++就建議在設計程式前先編寫測試代碼,而軟體工程則要求在整個開發過程中維護開發文檔等等。
從軟體開發的任務出發,就可以很容易的領會到軟體科學的體系架構了。首先,我們需要有一種進階語言來與電腦進行符合人類思維的交流。在它的基礎上,就可以實現資料結構,從而為演算法的實現打好基礎。資料結構之上自然是演算法。再往上是一些架構性的程式設計思想和規範,比如物件導向的思想、軟體工程的思想等等。軟體科學到此似乎就比較完善了。但是不要忘了進階語言下面還有支撐它的基礎:編譯器和作業系統。這兩門課:編譯原理和作業系統就成為了溝通軟體和硬體之間的橋樑。
至於電腦應用,涉及到的領域就太多了。舉例來說,人工智慧、數字訊號處理、電腦網路、作業系統等等等等。這裡將作業系統也列為電腦的應用,是因為它的實現也用到了很多電腦科學的知識,比如演算法、圖論等等,也是需要下層知識的支撐的。每一門領域中,又各自有它自己的數學作為基礎:比如人工智慧需要形式邏輯,數字訊號處理需要資訊理論、積分變換和採樣理論,電腦網路對機率論的應用較多等等。因此,電腦應用可以分為兩層,下層是數學,上層則是各個具體的學科。
到這裡,整個電腦科學技術的知識系統基本上闡述完了。用圖來表示的話大概是下面這個樣子:
再觀察可以發現,在整個體系中,數學貫穿了始終。可以說,數學是電腦科學技術的靈魂,紮實的數學基礎對於這個專業的學生來說是相當大的優勢。