對話高博(一)| 機器碼、Pascal,以及計算機學習的分形(圖靈訪談)

盼盼姐發表於2016-01-26

高博,1983年生,上海交通大學電腦科學與工程專業本科、軟體工程碩士。現任博曉文化傳媒集團總裁,香港衛視科教臺臺長。職場經歷豐富,曾在數家世界500強IT和網際網路企業打造明星團隊。專業興趣包括軟體測試及大規模自動化、持續交付和基礎演算法研究。業餘愛好寫作和翻譯,2009年至今翻譯超過100萬字,包括圖靈獎作者高德納作品《研究之美》和布魯克斯作品《設計原本》、Jolt生產力大獎作品《元素模式》等,並以譯作《資訊簡史》獲中國國家圖書館第九屆文津獎。

enter image description here

你小時候是怎麼學習計算機的?

我從4歲時就開始學習使用計算機進行程式設計,我當時學的語言叫Algo-60,這個語言就是現在的Pascal和C的前身,Algo-60的設計者N. Wirth也是Pascal的設計者。當時的計算機和現在非常的不一樣,我們現在完全在使用軟體進行計算機的各種配置,這種配置程式在Windows作業系統裡被叫作控制皮膚(control panel)。但是對於當時的計算機(我見過的型號叫709)而言,控制皮膚是真正的硬體操作檯,上面有各種扳手和旋鈕。現在很少有人見過、甚至聽說過什麼是穿紙帶。紙帶其實就相當於現在的機器碼,而機器碼就是010101。這些早年的經歷,特別是從高階語言編譯成低階指令,並且實實在在地變成紙帶上的物理小孔的經歷,對我今後的計算機學習在原理認識的幫助是很大的。4歲的這一年我還接觸到了一個極其重要的東西,就是Internet,當時當然沒有全球資訊網,一切都是Telnet(FTP不知道當時有沒有,反正我是沒有用過的),我當時對於遠端控制這件事簡直覺得神奇極了,但是上機時間前後加起來也就是半小時不到,大概是怕我這個小孩子把昂貴的裝置弄壞了吧。所以,這些印象真的是寶貴極了,我也因此感覺自己是非常幸運的,能夠這麼早地接觸到真正的計算機和Internet。

我在上小學的時候,計算機已經進入了大規模積體電路時代。這個時候絕大多數的家庭還負擔不起購置一臺計算機的費用,更不用說我所在的那個小縣城了。我卻幸運地得到了一臺當時廣告做得鋪天蓋地的小霸王學習機,使用硬卡提供了最簡單的一些軟體,並帶有10K不到的記憶體。但是學習機很快就完全無法滿足我的要求了,尤其是我當時就早已見過真正的計算機是什麼樣子。1995年,我在上初一的時候第一次接觸了PC,我在宿州市輕工業學校見到了PC和DOS,還有西山DOS中文系統。我已經提前看到了一些書,但上機以後才能體會到書上講的東西是多麼有意思。當時我還一點DOS命令都不會,只能請機房工作人員幫我執行起西山DOS進入中文介面,然後啟動WPS來編輯文件。我記得很清楚,當時的輸入法已經有了強大的聯想功能。安徽省宿城第一中學是我係統地學習程式設計的發端,我在那裡比較系統和深入地學習了Pascal語言。

從你的角度上說,你建議別人如何系統地學習計算機?

從我個人的學習經歷來講,我感覺一個人在學習資料結構和演算法之前,真的應該先掌握至少一門程式設計語言。通過程式設計語言,就可以知道怎麼樣地和計算機的細部打交道。在學習程式設計語言的時候,有好幾項基礎內容是需要很多練習才能掌握的,就拿迴圈來說,很多人實際上就卡在這個環節上,想象不出來迴圈變數應該怎麼樣寫成一個迴圈體中的不變式。而跨不過這道坎,不能熟練地寫出迴圈結構,簡直就不可能寫出任何有意義的程式來了。所以現在的計算機教育中的一個很大的問題在於,教育者們已經忘記了當年自己是怎麼樣從不懂到懂的一個經歷,在一些他們自以為重要的問題上花了大量的問題,而在最簡單最基礎的內容上,卻存在著極其重大的缺失,這讓學生痛苦萬分——正如IT教育家侯捷所說,勿在浮砂築高臺。你連while迴圈都不會寫,怎麼可能寫出二叉查詢樹的遍歷程式呢?而考試中如果這樣的一個學生真的寫出了正確答案,除了死記硬背還有什麼可能呢?

我在初中三年學習中,下了狠功夫來了解Pascal和C程式設計語言,還有DOS作業系統。我在為了資訊學競賽的專項訓練中,準備是不足的。所以在初中時代表宿州市參加了幾次省級資訊學競賽,卻一次獎項也沒有拿到。但是隻要做出一道題並驗證通過,我就感覺到有一種實實在在的欣喜,因為我感覺我寫出來的程式可讀性會比較好一點,結構也比較合理,可惜這些可能都不是資訊學競賽要的,後者主要需要的是程式能夠在規定的時間內給出符合格式的結果,所以無疑地對於演算法的優化才是重點和核心。

在我上初中的那個年代,鋪天蓋地地分發和使用的,都是DOS作業系統,後面出了Windows 3.0以後又全都是16位的Windows了(還專門出了個簡體中文版的Windows 3.2)。這個時期Linux可以說是完全沒有任何滲透率的,我肯定是在2000年上了大學以後才第一次聽說了Linux作業系統。如果是現在開始學習程式設計,尤其是小孩子想要開始學習的話,我是非常非常推薦使用Raspberry Pi和上面執行的Debian Linux發行版本的。原因在於,Linux天生是個現代作業系統,再少的系統資源上它也天然地具有現代記憶體管理機制和多工等,不像DOS,它上面的限制實在是太多了。分配超過640KB記憶體就要採用很複雜的層機制,多工更是隻能採用迂迴的辦法做出非常蹩腳的實現。作業系統所在的層次是包括硬體抽象的,它的設計直接決定了上層應用的諸多限制條件。我在想,如果我當年第一次接觸的就是Linux作業系統,我建立起來的計算機基本觀念會有多麼大的不同!

你的第一臺計算機是什麼樣的?

我的父母在1995年就為我買了人生第一臺真正的計算機,是一臺486DX。這臺計算機配置了1M記憶體(單位真的是M),504MB硬碟。這個配置當然是非常低了,在當時卻是相當先進的。可圈可點之處在於,它配置了一臺當時非常少見的彩色CRT顯示器。這是很捨得的投資。另一方面,它在計算和儲存上簡直是最小化的配置,也無意之間讓我不可能把大量的精力花在當時對計算和儲存資源要求較高的電腦遊戲上,而只能是潛心研究程式設計,到了2000年我上大學前夕我還在用這臺計算機,不過記憶體被加到了4M,執行Turbo Pascal和Turbo C是綽綽有餘了。可是這臺計算機在計算和儲存方面給我帶來的心理陰影也是巨大的,現在我在購置計算機的時候總是拼命選CPU最快的、儲存最大的,而且總是會不斷地購買大容量儲存,可以看作是這段生活的一個對潛意識的影響。

你高中轉學到了上海吧?這段經歷對你學習計算機有什麼幫助?

我上高中以後是作為一個比較活躍的計算機興趣小組的發起人和組織者來推進計算機學習和研究的。而我的高中生活的大背景則切換到了國際大都市上海,在這裡可以更容易地找到一起學習和討論的同學,而不像在小城市那邊始終都是那麼幾個人。1996年底我接觸到了全球資訊網,也隨即接觸到了HTML和JavaScript,我可能是國內最早接觸到JavaScript的一批人。但我還在上高中,如果當時就創業真的難以想象會怎麼樣吧。這個時候Windows作業系統已經開始爆發流行了,所以幾乎一夜之間我學的關於DOS程式設計的東西完全落伍了。時代的發展是非常殘酷的,但是在上大學之前,我對這個就有很深的感觸了。所以在此後的學習中,我極力去避免和任何軟體平臺和框架繫結,因為這些東西都是歷史的產物,也會隨著歷史的發展而消失。此前為資訊學競賽而準備的程式設計功底,可能唯一能看得到的回報就是得了一個市級競賽的獎項,在高考材料裡面算得一個亮點,讓我被上海交通大學錄取到了電腦科學與技術專業。

大學期間你是如何學習計算機的?

我在上大學之前,就已經感覺到自己應該投入更多的精力在一些研究“軟體生產”上面,而不是在研究“程式設計技法”上面。上大學以後,我也確實更多地在投身入這個方面的研究。我可能是小時候寫了太多程式碼了,所以我非常明白,想把程式碼寫正確,和期望一致是一件多麼困難的事情。而任何一種要交付給客戶甚至大眾使用的軟體,它們背後要下的功夫都是非常可觀的。

從程式碼到能夠交付的軟體,背後要付出的努力都有哪些?

軟體不僅僅包括“程式碼”,程式碼是一種靜態的、一旦寫完就不再改變的事物。而程式碼執行起來才是真正的考驗開始之時。而這個“執行”,學問就大了。任何程式碼都要經過編譯、連結以後才能夠載入和執行,這個過程就涉及到庫程式碼、他人撰寫的程式碼,軟體的編譯器和連結器、軟體的軟執行環境(主要是作業系統,但有些系統軟體或專用環境軟體需要考慮更多)、硬體驅動和硬體裝置。所有的這一切,都必須在適切的版本、正確的配置以及抽象層次之間緊齧的配合之下,才能夠達到“執行起來”這個最簡單的目的。而執行起來以後,是否能達成和期望相符的執行結果、互動體驗和效能指標,則是每一個細節議題都可以寫成厚厚的一大本書的了。

在這其中,有無數的思想和方法論在碰撞,而且會催生很多完整的所謂軟體過程、表示、工具的成套設施,從任何一個方面研究下去,都會發現有很多有價值的內容。所有軟體工程的基本思想都無外乎“提供一個封裝好的抽象層”,把一些細節隱藏起來,作為一個美好的抽象概念暴露出來,讓下游的軟體工程師能夠按照一個預先設定的概念集以事先規定的方式使用自己習慣的軟體工具來撰寫程式碼,而把這些隱藏好的細節照顧起來,以適當的方式給下游的程式設計師以他所在的語境的抽象語言描寫的反饋。其實任何軟體說到底都是機器程式碼的執行,在這個最底層的層次上,沒有任何祕密可言,容不得任何錯誤。一切脫離機器碼層次的概念都是更高層的概念,對機器而言都是毫無意義的,都是為了人類方便理解機器執行機制而設定的抽象層。但是絕大多數的程式設計師,對於機器執行機制的理解,也最多隻能達到從最頂層的抽象向下探究的兩到三個層次而已。

計算機執行機制的不同層次之間是否有哪些共通的東西?

電腦科學的研究和學習有著分形(fractal)的特性。無論在哪個層次上做研究,使用的理論和數學工具都是相似的,其中極有意思的是基本演算法和基礎資料結構在各個層次上都發揮著作用,並且上一個層次和下一個層次之間還有差異性,有的時候這種差異性會給人以上一層次之一沙會是下一層次之一世界的奇妙層次感,更讓身處其境的研究者感覺到選擇之無止境。當然,每一個層次又有每一個層次的獨特技巧,研究底層技術的研究者會更注意效率和簡潔性,而研究上層技術的研究者則更會注意概念完整性和一致性。研究中間層技術的研究性則會產生大量的工具類方法和產品,可是它卻又是變化最活躍的層次,並且要對上下游的技術都有完整成熟的理解才能被學術和工業界接受,而高階程式設計語言就恰恰處於這個層次,所以在這個領域裡起的紛爭也就最多。但我反過來要講的是,往往我們要搞好這個層次,就非要往上下游的層次去多學一些東西才好,上游是科學理論和方法論,比如數理邏輯、離散數學、設計模式等,下游就是程式設計的機器細節。不過,任何層次上,都不能離於演算法與資料結構,尤其是基本演算法和基礎資料結構,這方面的訓練真的是千變萬化而又樂趣無窮的,生活中到處都是能夠拿來做演算法和資料結構訓練的實際問題。

人在軟體開發中的作用是什麼?

任何問題到最後都會落實為人的問題,計算機的問題也會落實到研究者和程式設計師的身上。這兩者的關係是難分難解的,哪怕是一個簡單到10行以內的程式碼可以解決的問題,它也一定有設計、有實現、有驗證,也一定有理論價值和工程價值。計算機就是這樣的一個領域,如果止步於第一步,也一樣可以產生一定的結果,但是深究下去就會發現無處不可擴充、無處不可優化,這也是為什麼同樣功能的軟體,它的成本可以是成百上千倍的差距。大量的功夫是花在人們不能一眼看到的地方的,人們的觀感和體驗好一分,後面需要付出的研究和工程代價可能是難以想像地大。這些觀念,都必須在程式設計師的最開始階段的培養和訓練上,就要施加影響,讓所有的程式設計師都明白,做事最快的方法是什麼,但什麼是值得繼續深入下去分解成更細的工作,然後在這些方面追求卓越表現。

所有和IT相關的職業,都毫無疑義地需要了解一線生產者,也就是做程式碼撰寫、程式碼測試、持續整合的工程師們的工作細節的人來擔當,而這樣的人可以成長到各個方向去,成為產品、運維、甚至市場銷售的人才,而只學了工業設計、營銷理論或是其他專業知識的人,如果沒有通過自學對於IT專業領域的理解達到一定的深度,則至多隻能做配合的工作,如果一家以IT產品和服務為核心的企業不是按這個原則來招聘,那末必然會發生嚴重的問題。

對話高博(二)| 換工作這件事


更多精彩,加入圖靈訪談微信!

相關文章