程序 = 數據結構 + 算法《禪與計算機程序設計藝術》 / 陳光劍 程序 = 數據結構 + 算法 參考資料 《禪與計算機程序設計藝術》 / 陳光劍

程序 = 數據結構 + 算法

“數據結構和算法是過去 50 年來最重要的發明之一,它們是軟件工程師需要了解的基礎工具。” 《Think Data Structures: Algorithms and Information Retrieval in Java》(Allen B.Downey)

基本數據類型

道生一,一生二,二生三,三生萬物。

在計算機程序設計的世界裏,先有基本數據類型,複合組裝成複雜對象類型,不同對象之間再進行交互操作,進而形成豐富多彩的虛擬世界。

其實,這個過程中的原理,跟現實世界是一樣的。我們人類的腦子裏對這個世界的認知,恐怕沒有人敢說他真正懂得這個世界本來的樣子。僅僅是量子物理的世界跟廣義相對論的時空世界,就把這個地球上絕大部分人的腦袋弄迷糊。

我們的數字計算機的世界,是簡化了的物理世界——在這個世界裏,任何事物的存在,都可以用0和1來表達——清楚簡單、準確無誤。任何數據結構模型,都是清晰可見的。

我們這裏講的數據結構,對應的是抽象數據類型、類、模型、實體等這些的概念,是數據的邏輯模型,不是數據的物理模型。

如果不瞭解計算機相關的知識和思想,可能很難明白計算機的工作原理。因爲,經歷從各層硬件到各層軟件的層層抽象後,計算機內部已經複雜得讓人難以想象。

比如芯片,指甲蓋兒那麼大,卻有幾億甚至幾十億個晶體管電子器件,每個晶體管電子器件的電流和電壓,在1秒內,能變化幾億甚至幾十億次。學過排列組合的朋友,應該知道,芯片內部每時每刻的狀態數量,是一個天文數字。

再比如操作系統。大概有10G的源代碼,一Byte一個字符,也就是說有超過100億個字符,每行按標準80字符來算的話,超過1億行。WinXP系統有2億行。Android系統爲例,少說點也有1億行代碼。假設一本書有500頁 (正反算兩頁,這已經是一本很厚的書了), 書的單面印50行代碼,那麼一本書就能印刷25000行代碼。如果把操作系統的代碼都印刷在書上,那就是4000本書。

當我們拿着手機,聊微信、逛淘寶、刷抖音時,我們是否意識到發生了什麼呢?

通過手機app、中間件、操作系統、驅動程序,我們在操縱着手機芯片中的電壓和電流,操縱着芯片中的無數分子中的原子中的電子。

我們還利用了麥克斯韋電磁場理論,通過電磁場和電磁波的方式,遠程操縱着馬化騰的服務器、馬雲的服務器、張一鳴的服務器的芯片中的無數分子中的原子中的電子。我們用的電,來自幾千公里之外的發電廠,通過一百年前特斯拉發明的交流電系統傳輸到我們房子裏面的電路插座……真有點武俠小說的感覺,手指在手機上輕輕一滑,世界各地的計算機芯片中的電子爲之一振。

是的,從微觀層面講,那些電子在雜亂無章地“亂竄”,充滿着不確定性。但是,通過抽象,我們擁有了宏觀層面確定的歐姆定律、基爾霍夫定律。然而,電流電壓依然會存在上下輕微波動,並不準確,於是通過再次抽象,我們擁有了確定的與或非門電路;通過再次抽象,我們擁有了確定的芯片;通過再次抽象,我們擁有了確定的驅動程序、操作系統、中間件;最後,我們擁有了確定的、帶功能意義的應用程序/app, 於是乎,我們滑動着手機,玩着,樂着。

計算機,從頂層的應用程序往下看,處處都有抽象,處處都是編碼和轉換。我們沒有辦法,也沒有必要弄清計算機的每個細節,但只要把握住了計算機的工作原理,弄清一些核心概念,還是能在一定抽象度上搞懂計算機。

抽象,是計算機科學和技術中最重要的思想,沒有之一。抽象的重要性,在操作系統中的體現尤爲明顯。

通過層層抽象,我們纔可以輕鬆地聊微信、逛淘寶、刷抖音, 而最背後的最底層,不過是芯片中的電子在“亂竄”而已。

萬物皆數:Number

畢達哥拉斯:數是宇宙萬物的本原

畢達哥拉斯(Pythagoras,約公元前580年~約前500(490)年)古希臘數學家、哲學家。

畢達哥拉斯出生在愛琴海中的薩摩斯島(今希臘東部小島)的貴族家庭,自幼聰明好學,曾在名師門下學習幾何學、自然科學和哲學。因爲嚮往東方的智慧,畢達哥拉斯經過萬水千山,遊歷了當時世界上兩個文化水準極高的文明古國——巴比倫和印度,以及埃及(有爭議),吸收了美索不達米亞文明和印度文明的文化。後來他到意大利的南部傳授數學及宣傳他的哲學思想,並和他的信徒們組成了一個所謂“畢達哥拉斯學派”的政治和宗教團體。

畢達哥拉斯學派認爲數是宇宙萬物的本原。研究數學的目的並不在於使用而是爲了探索自然的奧祕。

事物的性質是由某種數量關係決定的,萬物按照一定的數量比例而構成和諧的秩序。從三個蘋果等事物中抽象出了五這個數。

這在今天看來很平常的事,但在當時的哲學和實用數學界,這算是一個巨大的進步。在實用數學方面,它使得算術成爲可能。在哲學方面,這個發現促使人們相信數是構成實物世界的基礎。

數制

1.十進制數(Decimal)

十進制數是人們十分熟悉的計數體制,它的數碼是用0、1、2、3、4、5、6、7、8、9十個數字符號來表示,基數是10,進位規律是“逢十進一”。

爲什麼現代人普遍使用十進制?
在人類發展史上,並不是所有人都選擇了十進制。古巴比倫人用的是60進制,瑪雅人用的是20進制。羅馬人的計數系統乾脆就沒有進制。古埃及也有類似的情況。所以並不存在什麼十進制的必然性。
回頭去看歷史的話,十進制的計數系統在現代佔據統治地位很大程度上是歷史的偶然。現代的這套“阿拉伯數字”的計數系統其實是古印度人的發明。來自中亞的伊斯蘭化的突厥人征服了印度,把印度納入到了伊斯蘭世界。然後阿拉伯人又在長期的征服與貿易的過程中把這套計數系統傳播到了世界各地。如果當初佔據亞歐交通樞紐的不是阿拉伯人,或者當時巴布爾沒有打下印度,那完全有可能我們今天用的計數方式不是十進制,而是十二進制,二十進制或是六十進制之類的。至於說十進制的來源是十根手指頭,這隻能說是一種可能的猜測。

2.二進制數(Binary)

與十進制數類似,二進制數的數碼是用0、1兩個數字符號來表示,基數爲2,進位規律是“逢二進一”。

數字電子電路中,邏輯門的實現直接應用了二進制。現代的計算機和依賴計算機的設備裏都用到二進制。每個數字稱爲一個比特(Bit,Binary digit)。

3.八進制數(Octonary)

在八進制數中,它的數碼是用0、1、2、3、4、5、6、7八個數字符號來表示,基數是8,進位規律是“逢八進一”。

4.十六進制數(Hexadecimal)

在十六進制數中,它的數碼是用0、1、2、3、4、5、6、7、8、9、A、B、C、D、E、F十六個數字和字母符號來表示,基數是16,進位規律是逢十六進一。

二進制數、八進制數、十六進制數和十進制數之間的對應關係:

關於有理數、無理數、實數、複數等概念,比如說無限不循環小數,計算機無能爲力,沒有辦法準確表達,只能儘量逼近,近似數值計算。這也是計算機程序設計與純粹數學理論之間的鴻溝。這就好比是,量子力學的理論多麼優美,廣義相對論的思想多麼宏大,但是,人類就是沒辦法把兩種理論統一放到同一個宇宙體系中。這難道是理想與現實的永恆的裂縫?

計算機世界爲什麼選擇了二進制?

早期的機械式和繼電式計算機都用具有10個穩定狀態的基本元件來表示十進制數據位0,1,2,…,9。一個數據的各個數據位是按10的指數順序排列的。例如,從0v到9v, 總共有10個電壓位,由於電子線路器件的原因及其內部複雜性,如果一根電線的電壓值是7.49v, 那麼,請問,它表示的是數字7還是數字8呢?這就尷尬了。

但是,要求處理機的基本電子元件具有10個穩定狀態比較困難,十進制運算器邏輯線路也比較複雜。從萊布尼茨到布爾,再到香農,都在苦苦探索着。最後探索出了解決之道:可以使用二進制來計算,然後用電路來實現二進制計算。

用電路來實現二進制表示和二進制計算,我們今天看起來似乎很簡單,但探索出這條路,並不容易。萊布尼茨發明了二進制,但他在做自己的乘法器時,並沒有意識到二進制的重要性。萊布尼茨終生未婚,在科學和哲學史上,他真可謂是百科全書式的人物。

多數元件具有兩個穩定狀態,二進制運算也比較簡單,而且能節省設備,二進制與處理機邏輯運算能協調一致,且便於用邏輯代數簡化處理機邏輯設計。二進制遂得到廣泛應用。

邏輯代數

布爾創建了邏輯代數,也稱布爾代數,在很大程度上, 爲後來的電路設計及其簡化,做出了很大的貢獻。現在很多編程語言中都內部了布爾類型,以紀念這位先驅。

布爾代數起源於數學領域,是一個用於集合運算和邏輯運算的公式:〈B,∨,∧,¬ 〉。其中B爲一個非空集合,∨,∧爲定義在B上的兩個二元運算,¬爲定義在B上的一個一元運算。
通過布爾代數進行集合運算可以獲取到不同集合之間的交集、並集或補集,進行邏輯運算可以對不同集合進行與、或、非。

20世紀以來,邏輯代數一直是數字電路設計的基礎,並且所有現代編程語言提供支持。幾乎所有現代通用計算機都用二值布爾邏輯做運算;也就是說它們的電路是二值布爾邏輯的物理表示。幾種表示方式:導線上電壓的高低,磁性存儲設備中磁疇的方向,打孔卡或紙帶上的洞,等等。

用電路來實現二進制

香農,正是香農,最先洞察到了開關係統和布爾邏輯之間的關係,並發表了論文《繼電器和開關電路的符號化分析》,可以說,這篇文論讓人們意識到,可以用電路來實現二進制表示和二進制計算。香農活到了二十一世紀,當他看着這個世界,因爲他的貢獻而變得如此美好時,內心一定是很欣慰的。

1938年香農在MIT獲得電氣工程碩士學位,碩士論文題目是《A Symbolic Analysis of Relay and Switching Circuits》(繼電器與開關電路的符號分析)。當時他已經注意到電話交換電路與布爾代數之間的類似性,即把布爾代數的“真”與“假”和電路系統的“開”與“關”對應起來,並用1和0表示。於是他用布爾代數分析並優化開關電路,這就奠定了數字電路的理論基礎。哈佛大學的Howard Gardner教授說,“這可能是本世紀最重要、最著名的一篇碩士論文。”

邏輯門

邏輯門是在集成電路上的基本組件。簡單的邏輯門可由晶體管組成。這些晶體管的組合可以使代表兩種信號的高低電平在通過它們之後產生高電平或者低電平的信號。高、低電平可以分別代表邏輯上的“真”與“假”或二進制當中的1和0,從而實現邏輯運算。通常組合使用實現更爲複雜的邏輯運算。一些廠商通過邏輯門的組合生產一些實用、小型、集成的產品,例如可編程邏輯器件FPGA等。

二進制與字符表達

字符信息的表示

1.字符編碼

目前主要用ASCII碼(American Standard Code for Information Interchange),即美國標準信息交換碼,已被國際標準化組織ISO(International Organization for Standardization)定爲國際標準。ASCII碼採用一個字節(8個二進制位)表示一個字符,ASCII碼分爲標準ASCII碼和擴展ASCII碼。

標準ASCII碼的最高位爲0,其範圍用二進制表示爲00000000 ~ 01111111,用十六進制表示爲00 ~ 7F,用十進制表示爲0 ~ 127,共128個編碼。在128個編碼中,有34個控制字符,52個英文大小寫字母,10個數字(0~9),32個字符和運算符(見 書本P19 表1-5標準ASCII碼錶)。

2.漢字編碼

爲了能在計算機中處理漢字,就必須對漢字進行編碼,但漢字都有自己的形狀,其基本字符較多,用一個字節編碼顯然是不夠的。目前的漢字編碼方案大多都採用兩個字節,例如我國制定的“中華人民共和國國家標準信息交換漢字編碼”(GB2312-80),簡稱國標碼。在GB2312-80中規定用兩個字節即16位二進制代碼表示一個漢字,並且每個字節的高位規定爲1,這樣只可以表示128 × 128=16384個漢字。

漢字輸入碼,又稱“外部碼”,簡稱“外碼”,指用戶從鍵盤上輸入代表漢字的編碼。爲了能直接使用西文標準鍵盤進行漢字輸入,必須爲漢字設計相應的編碼方法。

區位碼是一種最通用的漢字輸入碼。它是根據國標GB2312-80將6763個漢字和一些常用的圖形符號組成一個94×94的矩陣,即有94行和94列。每一行稱爲一個區,每一列稱爲一個位,區號與位號組合在一起稱爲區位碼(區位號),它可準確確定某一漢字或圖形符號。如漢字“啊”位於16區第01位,則“啊”字的區位碼爲:區號+位號,即1601。

國家標準GB2312-80中的漢字代碼除了十進制形式的區位碼外,還有一種十六進制形式的編碼,稱爲國標碼。國標碼是不同漢字信息系統之間進行漢字交換時所使用的編碼,它的編碼值不同於區位碼,其值是分別對區號、位號增加32(十六進制數20H)。

漢字機內碼也稱“機內碼”,簡稱“內碼”,指計算機內部存儲、處理加工和傳輸漢字時所用的由0和1符號組成的代碼。機內碼可以通過區位碼計算出來,其值是分別對區號、位號增加160(十六進制數A0H)。

3.漢字字庫

對於每一個漢字,在計算機內都有對應的字形碼和漢字模型(也稱字模),所有字模的集合構成了字“模庫”,簡稱“字庫”。漢字在輸出時,要先找到用於輸出的字形碼或字模,再將字模輸出形成漢字。

漢字字形的構成方法有向量法(也稱矢量法、輪廓字形)、點陣法。

4.漢字處理流程

漢字通過輸入設備將外碼送入計算機,再由漢字處理系統將其轉換成內碼進行存儲、處理、加工和傳送,當需要輸出時再由漢字處理系統調用字庫中漢字的字形碼得到輸出漢字的結果

編碼與映射的思想

數組與鏈表:Array 與 List

映射表:HashMap

樹與網絡結構

無窮大是什麼?

0 代表的概念

在物理世界無窮存在嗎?

計算機二進制簡史

1911年:6月15日,華爾街金融投資家弗林特(C.Flent)投資霍列瑞斯的製表機公司,成立了全新的CTR公司,但公司創立之初並沒有涉足任何電子領域,反而生產諸如碎紙機或者土豆削皮機之類的產品。

1912年:美國青年發明家德•福雷斯特(L.De Forest)在帕洛阿託小鎮首次發現了電子管的放大作用,爲電子工業奠定了基礎,而今日的帕洛阿託小鎮也已成爲硅谷的中心地帶。

1913年:麻省理工學院教授萬•布什(V.Bush)領導製造了模擬計算機“微分分析儀”。機器採用一系列電機驅動,利用齒輪轉動的角度來模擬計算結果。

1924年:硅谷之父特曼擔任斯坦福大學教授,對創建HP、成立斯坦福工業園區起到決定性作用

2月,由霍列瑞斯創辦的製表機公司幾經演變,最終更名爲國際商用機器公司,即我們今天看到的IBM。

1935年:IBM製造了IBM601穿孔卡片式計算機,該計算機能夠在一秒鐘內計算出乘法運算。

1936年:阿蘭.圖靈發表論文《論可計算數及其在判定問題中的應用》,首次闡明瞭現代電腦原理,從理論上證明了現代通用計算機存在的可能性,圖靈把人在計算時所做的工作分解成簡單的動作,與人的計算類似,機器需要:(1)存儲器,用於貯存計算結果;(2)一種語言,表示運算和數字;(3)掃描;(4)計算意向,即在計算過程中下一步打算做什麼;(5)執行下一步計算。具體到一步計算,則分成:(1)改變數字可符號;(2)掃描區改變,如往左進位和往右添位等;(3)改變計算意向等。整個計算過程採用了二進位制,這就是後來人們所稱的“圖靈機”。

20多歲的德國工程師楚澤(K.Zuse)研製出了機械可編程計算機Z1,並採用了二進制形式,其理論基礎即來源於布爾代數

1937年:11月,美國AT&T貝爾實驗室研究人員斯蒂比茲(G. Stibitz)製造了電磁式數字計算機“Model-K”。

1938年:克勞德•艾爾伍德•香農(Claude Elwood Shannon)發表了著名論文《繼電器和開關電路的符號分析》,首次用布爾代數對開關電路進行了相關的分析,並證明了可以通過繼電器電路來實現布爾代數的邏輯運算,同時明確地給出了實現加,減,乘,除等運算的電子電路的設計方法。這篇論文成爲開關電路理論的開端。

1939年:元旦,美國斯坦福大學研究生比爾•休利特(B.Hewllet)和戴維•帕卡德(D.Packard)正式簽署企業合夥協議,創辦了Hewllet-Packard(HP)公司,即國內通稱的惠普公司。

9月,貝爾實驗室研製出M-1型計算機。

10月,約翰.阿塔納索夫(John Vincent Atanasoff(1903-1995))製造了後來舉世聞名的ABC計算機的第一臺樣機,並提出了計算機的三條原則,(1)以二進制的邏輯基礎來實現數字運算,以保證精度; (2)利用電子技術來實現控制,邏輯運算和算術運算,以保證計算速度; (3)採用把計算功能和二進制數更新存貯的功能相分離的結構。這就是著名的計算機三原則。

1940年:9月,貝爾實驗室在美國達特默思大學演示M—1型機。他們用電報線把安置在校園內的M—1型機和相連,當場把一個數學問題打印出來並傳輸到紐約,M—1型機在達特默思大學的成功表演,首次實現了人類對計算機進行的遠距離控制的夢想。

控制論之父維納提出了計算機五原則,(1)不是模擬式,而是數字式;(2)由電子元件構成,儘量減少機械部件;(3)採用二進制,而不是十進制;(4)內部存放計算表;(5)在計算機內部存貯數據。

1941年:楚澤完成了Z3計算機的研製工作,這是第一臺可編程的電子計算機。可處理7位指數、14位小數。使用了大量的真空管。每秒種能作3到4次加法運算,一次乘法需要3到5秒。

1942年:時任美國依阿華州立大學數學物理教授的阿塔納索夫(John V. Atanasoff)與研究生貝瑞(Clifford Berry)組裝了著名的ABC(Atanasoff-Berry Computer)計算機,共使用了300多個電子管,這也是世界上第一臺具有現代計算機雛形的計算機。但是由於美國政府正式參加第二次世界大戰,致使該計算機並沒有真正投入運行。

1943年:貝爾實驗室把U型繼電器裝入計算機設備中,製成了M—2型機,這是最早的編程計算機之一。此後的兩年中,貝爾實驗室相繼研製成功了M-3和M-4型計算機,但都與M-2型類似,只是存儲器容量更大了一些。

10月,綽號爲“巨人”的用來破譯德軍密碼的計算機在英國佈雷契萊莊園製造成功,此後又製造多臺,爲第二次世界大戰的勝利立下了汗馬功勞。

1944年:8月7日,由IBM出資,美國人霍德華•艾肯(H.Aiken)負責研製的馬克1號計算機在哈佛大學正式運行,它裝備了15萬個元件和長達800公里的電線, 每分鐘能夠進行200次以上運算。女數學家格雷斯•霍波(G.Hopper)爲它編制了計算程序,並聲明該計算機可以進行微分方程的求解。馬克1號計算機的問世不但實現了巴貝奇的夙願,而且也代表着自帕斯卡計算機問世以來機械計算機和電動計算機的最高水平。

1946年:2月14日,美國賓夕法尼亞大學摩爾學院教授莫契利(J. Mauchiy)和埃克特(J.Eckert)共同研製成功了ENIAC (Electronic Numerical Integrator And Computer):計算機。這臺計算機總共安裝了17468只電子管,7200個二極管,70000多電阻器,10000多 只電容器和6000只繼電器,電路的焊接點多達50萬個,機器被安裝在一排2.75米高的金屬櫃裏,佔地面積爲170平方米左右,總重量達 到30噸,其運算速度達到每秒鐘5000次加法,可以在3/1000秒時間內做完兩個10位數乘法。

參考資料

https://www.zhihu.com/question/282808055/answer/973929755
https://baike.baidu.com/item/%E4%BA%8C%E8%BF%9B%E5%88%B6/361457
https://blog.csdn.net/stpeace/article/details/103317663
https://blog.csdn.net/h_kingone/article/details/108749215

物理學史
計算機歷史
半導體物理學
半導體器件物理

《禪與計算機程序設計藝術》 / 陳光劍 目錄

第一性原理

什麼是禪?

什麼是計算機?

什麼是程序設計?

什麼是藝術?

宇宙之起源

物質之形成

半導體材料

納米光刻

二極管、三極管

太極陰陽與二進制

布爾代數與數字邏輯系統

模擬電子電路系統

信號與處理

信息論

圖靈機模型

馮諾依曼模型

計算機演化史

什麼是編程?

編程語言進化史

程序 = 數據結構 + 算法

模型關係思維

真理與模型

建築工程、機械工程、電氣工程與軟件工程

CPU架構設計

緩存思想

計算機科學中的中間層理論

從01機器碼到彙編指令到高級編程語言:一切皆是映射

美妙的遞歸

用計算機畫一張分形圖

分層思想

硬件驅動

操作系統

通信原理:TCP/IP 與 HTTP 協議、WIFI無線協議

互聯網簡史

數據的存儲:從ROM、RAM到寄存器到L1/L2 Cache 再到磁盤文件

索引原理:來自大自然的啓示 Tree 結構

人類社會數字化

人工智能

虛擬現實

技術、藝術與禪道

// TODO ...... 待續


《禪與計算機程序設計藝術》 / 陳光劍

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章