<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          【知乎問(wèn)題】如何讓不懂編程的人感受到編程的魅力?

          共 15740字,需瀏覽 32分鐘

           ·

          2020-08-22 00:51

          知乎問(wèn)題:如何讓不懂編程的人感受到編程的魅力?

          鏈接:https://www.zhihu.com/question/406408447

          Part 0. 前言

          問(wèn)一個(gè)類似的問(wèn)題:「如何讓不懂籃球的人感受到籃球的樂(lè)趣?」

          img

          很明顯,答案取決于人。

          對(duì)于某些人來(lái)說(shuō),編碼可能是乏味而艱巨的,但對(duì)于有些人則是非常有趣且有益的。

          通常情況下,編寫好代碼之后,我們很難評(píng)判編碼的過(guò)程是無(wú)聊還是有趣的。

          但是我們可以通過(guò)更好地了解 「計(jì)算機(jī)編程是什么」,因此您可以自己來(lái)評(píng)判這是否讓你感到樂(lè)趣。

          就當(dāng)代的發(fā)展水平來(lái)說(shuō),只要有電的東西就會(huì)涉及到編碼;

          Part 1. 計(jì)算機(jī)發(fā)展簡(jiǎn)史 | 解決實(shí)際的問(wèn)題

          img
          • 原文地址:「MoreThanJava」計(jì)算機(jī)發(fā)展史—從織布機(jī)到IBM

          一切的開端 | 織布機(jī)

          衣食住行是人類的基本需求,世界各地都有紡織和織機(jī)的發(fā)明。

          如何提升紡織的效率,成為一個(gè)很重要的課題。

          img

          紡織的原理

          「針織物」 不同,「機(jī)織物」 由兩條或兩組以上的相互垂直的兩個(gè)系統(tǒng)紗線或絲線構(gòu)成,縱向的紗線經(jīng)紗,橫向的紗線緯紗。

          通過(guò)兩條線不同規(guī)律的交錯(cuò),就會(huì)形成不同的顏色和排列的變化,也就會(huì)帶來(lái)不同的紋樣。

          img
          • 圖片引用自:https://www.sohu.com/a/301616592_99894978

          最原始的織機(jī)是手動(dòng)完成的。

          后來(lái)人們發(fā)現(xiàn),織物紋樣的變化總是按照一定規(guī)律排列完成的,到了戰(zhàn)國(guó)時(shí)期,就發(fā)明了 多綜式提花織機(jī),通過(guò) 綜框 來(lái)完成這一項(xiàng)工作:

          img

          這或許就是最原始的 編碼:通過(guò)把 提起規(guī)律相同的經(jīng)紗 穿入 同一個(gè)綜框的綜絲 中,來(lái)達(dá)到當(dāng)某一個(gè)綜框提起時(shí) (通過(guò)腳踏板完成),表達(dá)某一個(gè)特定紋路的線被提起,也就完成了 特定紋路的編織,加快了工作效率。

          織布機(jī)的更進(jìn)一步 | 束綜提花織機(jī)

          不過(guò)采用綜框也有一個(gè)明顯的限制,那就是 無(wú)法織出比較復(fù)雜的紋樣,因?yàn)榧y樣復(fù)雜則代表著需要更多的經(jīng)緯紗以及經(jīng)紗提升的規(guī)律更復(fù)雜,意味著可能引入成百上千次緯紗才能完成一個(gè)循環(huán)。

          如果仍然采用綜框控制紗線提升,則可能需要成百上千個(gè)綜框,這在機(jī)械上實(shí)現(xiàn)是非常困難的,因此便有了 束綜提花織機(jī)。

          img

          束綜提花織機(jī)沒(méi)有綜框,而是被 設(shè)計(jì)成兩層,每一根經(jīng)紗會(huì)穿入綜絲中實(shí)現(xiàn) 單獨(dú)的控制,上層 的人將需要提起的經(jīng)紗提起,而 下層 的人則再經(jīng)紗提起后通過(guò)梭子將緯紗送入織口,并用打緯裝置將引入的緯紗打牢。

          然而通常來(lái)說(shuō),這類織機(jī)上會(huì)有成千上萬(wàn)根緯紗,紋樣復(fù)雜,于是聰明的老祖宗們發(fā)明了 花本

          img

          簡(jiǎn)單來(lái)說(shuō),花本存儲(chǔ)了紋樣信息。

          圖中花本的豎線連接穿入了經(jīng)紗的綜絲,橫線存儲(chǔ)了每一次引入緯紗時(shí)提花信息,當(dāng)豎線越過(guò)橫線覆蓋在橫線前方時(shí),表明對(duì)應(yīng)的經(jīng)紗要被提起。

          這就有點(diǎn)兒 編碼規(guī)則 的意思。

          會(huì)說(shuō)話的「機(jī)器」 | 雅卡爾織布機(jī)

          上面說(shuō)到的束綜提花織機(jī)雖然是一大進(jìn)步,但可想而知的是,它仍然效率緩慢并且織布工人的勞動(dòng)量非常大,也非常辛苦。

          時(shí)間來(lái)到 18 世紀(jì)的歐洲。1725 年,布喬 開拓性的使用 打孔紙帶 來(lái)控制經(jīng)線的提起和放下,從而讓織出花樣成為一種半自動(dòng)化的工作:

          img

          歷史上第一次,機(jī)器能夠讀出存儲(chǔ)介質(zhì)中的內(nèi)容,并且照其行事。

          在布喬提出構(gòu)想 65 后的 1790 年,約瑟夫·瑪麗·雅卡爾 根據(jù)前人的成果設(shè)計(jì)了新式織機(jī),最終于 1805 年完成了首臺(tái) 自動(dòng)提花織機(jī)

          img

          雅卡爾將 穿孔紙帶 改進(jìn)為 穿孔卡片,根據(jù)紋樣圖案在卡片上打孔,通過(guò)孔的有無(wú) 帶動(dòng)一系列機(jī)械運(yùn)動(dòng)裝置來(lái) 控制經(jīng)紗的提升,一張卡片對(duì)應(yīng)循環(huán)內(nèi)一次引緯時(shí)經(jīng)紗提升的信息,引緯完成后,可通過(guò)腳踏板控制卡孔卡片轉(zhuǎn)動(dòng),下一張卡片翻轉(zhuǎn)至工作位置以控制新一次引緯的提花。

          雅卡爾織機(jī)大幅度節(jié)省了時(shí)間和工作量 (全自動(dòng)且效率是之前的二十五倍),而且只需一位工人,很快就被廣泛使用在工廠生產(chǎn)中,雅卡爾也榮獲了拿破侖授予的榮譽(yù)勛章。

          穿孔卡片控制織物紋樣的設(shè)計(jì)成為了程序設(shè)計(jì)思想的萌芽,為信息技術(shù)的發(fā)展開展了一條新的道路。

          程序設(shè)計(jì)思想開始萌芽 | 差分機(jī)

          img

          時(shí)間來(lái)到 19 世紀(jì)初,法國(guó)人 巴貝奇 (Chanles Badbbage) 在賈卡織機(jī)的啟發(fā)下,設(shè)計(jì)并制造了 差分機(jī)

          故事背景

          18 世紀(jì)末,法國(guó)政府在開創(chuàng)米制之后,決定在數(shù)學(xué)中統(tǒng)一采用十進(jìn)制,竟奇葩地想把原本 90 度的直角劃分成 100 度、把原本 60 秒的 1 分鐘劃分成 100 秒,盡管從現(xiàn)在看來(lái)這樣的想法絕逼是一種倒退,但他們?cè)诋?dāng)時(shí)真就實(shí)施了。這一改制帶來(lái)的不光是人們?cè)谑褂脮r(shí)直觀上的別扭,原本制作好的數(shù)學(xué)用表 (如三角函數(shù)表) 都需要全部重制。

          法國(guó)政府將這項(xiàng)喪心病狂的工程交給了 數(shù)學(xué)家普羅尼 (Gaspard de Prony),普羅尼正頭疼著要如何才能完成這項(xiàng)艱巨的任務(wù),突然想起著名經(jīng)濟(jì)學(xué)家 亞當(dāng)·斯密 *(Adam Smith)*的那本《富國(guó)論》,他決定采用書中提出的 勞動(dòng)分工 的做法,將制表的工作人員分成三組:

          • 第一組 由五六名牛逼的數(shù)學(xué)家組成,他們負(fù)責(zé)制定運(yùn)算中所需的公式;
          • 第二組 由九到十個(gè)擅長(zhǎng)數(shù)學(xué)的人組成,他們負(fù)責(zé)計(jì)算出一些關(guān)鍵數(shù)據(jù),并把第一組制定好的公式進(jìn)行簡(jiǎn)化;
          • 第三組 由約一百名計(jì)算人員組成,他們利用第二組提供的關(guān)鍵數(shù)據(jù)和公式,做最簡(jiǎn)單的加減操作就能得出最終結(jié)果。

          第三組的工作簡(jiǎn)單到什么程度,就是他們甚至都不知道自己正在算什么玩意兒,事實(shí)上他們的文化程度大部分都不高,里頭好多都是理發(fā)師、失業(yè)人員什么的??梢娂幢阄拿ざ寄芡瓿傻挠?jì)算,在那個(gè)時(shí)代還是得依靠人力去做。

          而為了保證用表的正確性,普羅尼要求 每個(gè)數(shù)至少算兩遍,并且 要在法國(guó)的不同地點(diǎn)用不同的方法計(jì)算。這項(xiàng)勞民傷財(cái)?shù)墓こ陶M(jìn)行了十年才完成,然而不幸的是,最終的表里仍然有錯(cuò)。說(shuō)到這一點(diǎn),可以說(shuō),那個(gè)時(shí)代基本沒(méi)有一版數(shù)學(xué)用表是完全正確的,有些版本甚至錯(cuò)誤百出,要知道數(shù)學(xué)用表出錯(cuò)有時(shí)后果會(huì)很嚴(yán)重,比如航海表一出錯(cuò)就可能直接導(dǎo)致船毀人亡。

          巴貝奇 在了解到普羅尼的事跡后淚流滿面,決心要做一套完全正確的數(shù)學(xué)用表,為達(dá)目的,他嘗試了各種減少錯(cuò)誤的手段,比如調(diào)整紙張和墨水的顏色以提高數(shù)字的識(shí)別度,直接拿現(xiàn)有的多個(gè)版本的表進(jìn)行謄抄、比對(duì)、讓不同人員反復(fù)校對(duì),在 1827 年出版了一個(gè)版本,結(jié)果里頭還是有錯(cuò)。只要是人為的就沒(méi)有完美的,巴貝奇徹底跪了,他發(fā)誓要造一臺(tái)機(jī)器,讓機(jī)器去生產(chǎn)數(shù)學(xué)表。

          這就是史上著名的 差分機(jī) 了。

          倫敦科學(xué)博物館·差分機(jī)設(shè)計(jì)圖紙&半成品:

          img

          第一臺(tái)真正意義上的電腦 | 分析機(jī)

          盡管沒(méi)能親手實(shí)現(xiàn)差分機(jī),但巴貝奇并不會(huì)氣餒,或者說(shuō)他本來(lái)就是根本停不下來(lái)的那種人。明知實(shí)現(xiàn)不了,巴貝奇仍在一刻不停地改進(jìn)著自己的設(shè)計(jì),直到有一天,他構(gòu)思出了一種空前的機(jī)器——分析機(jī),正式成為現(xiàn)代計(jì)算機(jī)史上的第一位偉大先驅(qū)。(Father of computing)

          1834 年,分析機(jī)概念誕生之際,巴貝奇自己都為之感到無(wú)比震驚。在此之前,任何一臺(tái)計(jì)算機(jī)器都只能完成其被預(yù)定賦予的計(jì)算任務(wù),要么是簡(jiǎn)單的加減乘除,要么像差分機(jī)那樣只能做差分運(yùn)算,它們都屬于 calculator,而分析機(jī)才是真正的 computer,它不局限于特定功能,而竟然是可編程的,可以用來(lái) 計(jì)算任意函數(shù)——現(xiàn)代人無(wú)論如何也無(wú)法想象在一坨齒輪上寫程序是怎樣一種體驗(yàn)吧!

          巴貝奇設(shè)計(jì)的分析機(jī)主要包括三大部分:

          1. 用于存儲(chǔ)數(shù)據(jù)的計(jì)數(shù)裝置,巴貝奇稱之為 “倉(cāng)庫(kù)”(store),相當(dāng)于現(xiàn)在 CPU 中的存儲(chǔ)器,這部分是從差分機(jī)上的計(jì)數(shù)裝置改進(jìn)而來(lái)的,我們很容易想象它的模樣;
          2. 專門負(fù)責(zé)四則運(yùn)算的裝置,巴貝奇稱之為 “工廠”(mill),相當(dāng)于現(xiàn)在 CPU 中的運(yùn)算器,這部分的結(jié)構(gòu)相對(duì)復(fù)雜,巴貝奇針對(duì)乘除法還做了一些優(yōu)化;
          3. 控制操作順序、選擇所需處理的數(shù)據(jù)和輸出結(jié)果的裝置,巴貝奇沒(méi)有起名字,由于其呈桶狀,我們可以叫它 “控制桶”,控制桶顯然相當(dāng)于現(xiàn)在 CPU 中的控制器。

          以上三部分,加上巴貝奇并沒(méi)有疏漏的輸入輸出設(shè)備,我們驚訝地發(fā)現(xiàn),分析機(jī)的組成部分和現(xiàn)在馮·諾依曼架構(gòu)所要求的五大部件一模一樣!

          巴貝奇另一大了不起的創(chuàng)舉就是將 穿孔卡片(punched card) 引入了計(jì)算機(jī)器領(lǐng)域,用于控制數(shù)據(jù)輸入和計(jì)算,從那時(shí)起,到第一臺(tái)電子計(jì)算機(jī)誕生為止,期間幾乎所有的數(shù)字計(jì)算機(jī)都使用了穿孔卡片。

          img

          整個(gè)分析機(jī)就是在類似這樣的齒輪和拉桿作用下實(shí)現(xiàn)可編程運(yùn)算的:先從數(shù)據(jù)卡片讀入數(shù)據(jù)到存儲(chǔ)器,再將存儲(chǔ)器中的數(shù)據(jù)傳輸?shù)竭\(yùn)算器,運(yùn)算器算完后又將數(shù)據(jù)傳回存儲(chǔ)器。

          可惜的是,巴貝奇窮其一生也沒(méi)能真正把分析機(jī)做出來(lái),留給后世的又是一臺(tái)模型機(jī)和兩千多張圖紙,以及這樣一段遺言:

          「如果一個(gè)人不因我一生的借鑒而卻步,仍然一往直前制成一臺(tái)本身具有全部數(shù)學(xué)分析能力的機(jī)器……那么我愿將我的聲譽(yù)毫不吝嗇地讓給他,因?yàn)橹挥兴軌蛲耆斫馕业姆N種努力以及這些努力所得成果的真正價(jià)值。」

          倫敦科學(xué)博物館·分析機(jī)設(shè)計(jì)圖紙&模型機(jī):

          img

          穿孔時(shí)代的到來(lái) | 制表機(jī)

          1790 年開始,美國(guó)每 10 進(jìn)行一次人口普查。百年間,隨著人口繁衍和移民的增多,從 1790 年的 400 萬(wàn)不到,到 1880 年的 5000 多萬(wàn),人口總數(shù)呈爆炸式地增長(zhǎng)。

          1790~1880 年美國(guó)人口增長(zhǎng)曲線

          不像現(xiàn)在這個(gè)的互聯(lián)網(wǎng)時(shí)代,人一出生,各種信息就已經(jīng)電子化、登記好了,甚至還能數(shù)據(jù)挖掘,你無(wú)法想象,在那個(gè)計(jì)算設(shè)備簡(jiǎn)陋得基本只能靠手搖進(jìn)行四則運(yùn)算的 19 世紀(jì),千萬(wàn)級(jí)的人口統(tǒng)計(jì)就已經(jīng)成了當(dāng)時(shí)政府的 “不能承受之重”。

          1880 年開始的第 10 次人口普查,歷時(shí) 8 年才最終完成,也就是說(shuō),他們?cè)谛菹赡曛缶鸵_始第 11 次普查了,而這一次普查,需要的時(shí)間恐怕要超過(guò) 10 年,那第 12次、13 次呢?本來(lái)就是 10 年一次的統(tǒng)計(jì),如果每次耗時(shí)都在 10 年以上,這件事情就變得沒(méi)有意義了。

          這可愁煞了當(dāng)時(shí)的人口調(diào)查辦公室,他們決定面向全社會(huì)招標(biāo),尋求能減輕手工勞動(dòng)、提高統(tǒng)計(jì)效率的發(fā)明。正所謂機(jī)會(huì)都是給有準(zhǔn)備的人的,一位畢業(yè)于哥倫比亞大學(xué)的年輕人 赫爾曼·霍爾瑞斯 (Herman Hollerith) 帶著他在 1884 年申請(qǐng)的專利從眾多方案中脫穎而出。

          img

          制表機(jī)

          他發(fā)明的機(jī)器叫 制表機(jī) (tabulator/tabulating machine),顧名思義,就是專門用來(lái)制作數(shù)據(jù)統(tǒng)計(jì)表的機(jī)器。制表機(jī)主要由示數(shù)裝置、穿孔機(jī)、讀卡裝置和分類箱組成。

          示數(shù)裝置包含 4 行、10 列共 40 個(gè)示數(shù)表盤,每個(gè)盤面被均勻地分成 100 格,并裝有兩根指針,和鐘表十分相像,“分針” 轉(zhuǎn)一圈可計(jì) 100,“時(shí)針” 轉(zhuǎn)一圈則計(jì) 10000??梢?,整個(gè)示數(shù)裝置可以表達(dá)很龐大的數(shù)據(jù)。

          img

          制表機(jī)的工作是圍繞穿孔卡片展開的:操作員先使用穿孔機(jī)制作穿孔卡片,再使用讀卡裝置識(shí)別卡片上的信息,機(jī)器自動(dòng)完成統(tǒng)計(jì)并在示數(shù)表盤上實(shí)時(shí)顯示結(jié)果,最后,將卡片投入分類箱的某一格中,進(jìn)行分類存放,以供下次統(tǒng)計(jì)使用。

          穿孔卡片的應(yīng)用

          此前的某一天,霍爾瑞斯正在火車站排隊(duì)檢票,目光不經(jīng)意落到檢票員手中咔咔直響的打孔機(jī)上。他發(fā)現(xiàn),檢票員會(huì)特意根據(jù)乘客的性別和年齡段,在車票的不同地方打孔。越來(lái)越多的人過(guò)檢,他進(jìn)一步確認(rèn)了這個(gè)規(guī)律。一個(gè)靈感朝他襲來(lái):如果有一張更大的卡,上面有更多的位置可以打孔,就可以用來(lái)表示更多的身份信息,包括國(guó)籍、人種、性別、生日等等。

          這就是用在 1890 年人口普查中的穿孔卡片,一張卡片記錄一個(gè)居民的信息??ㄆO(shè)計(jì)長(zhǎng)約 18.73cm,寬約 8.26cm,正好是當(dāng)時(shí)一張美元紙幣的尺寸,因?yàn)榛魻柸鹚怪苯佑秘?cái)政部裝錢的盒子來(lái)裝卡片。

          img

          卡片設(shè)有 300 多個(gè)孔位,與雅卡爾和巴貝奇的做法一樣,靠每個(gè)孔位打孔與否來(lái)表示信息。盡管這種形式頗有幾分二進(jìn)制的意味,但當(dāng)時(shí)的設(shè)計(jì)還遠(yuǎn)不夠成熟,并沒(méi)有用到二進(jìn)制真正的價(jià)值。舉個(gè)例子,我們現(xiàn)在一般用 1 位數(shù)據(jù)就可以表示性別,比如 1 表示男性,0 表示女性,而霍爾瑞斯在卡片上用了兩個(gè)孔位,表示男性就其中一處打孔,表示女性就在另一處打孔。其實(shí)性別還湊合,表示日期時(shí)浪費(fèi)得就多了,12 個(gè)月需要 12 個(gè)孔位,而常規(guī)的二進(jìn)制編碼只需要 4 位。當(dāng)然,這樣的局限也與制表機(jī)中簡(jiǎn)單的電路實(shí)現(xiàn)有關(guān)。

          細(xì)心的讀者可能發(fā)現(xiàn)卡片的右下角被切掉了,那不是殘缺,而是為了避免放反而專門設(shè)計(jì)的,和現(xiàn)在的二維碼只有 3 個(gè)角是一個(gè)道理。

          這類實(shí)用的細(xì)節(jié)設(shè)計(jì)在穿孔機(jī)上表現(xiàn)得更為出色。下圖為一位操作員正在使用穿孔機(jī)給卡片打孔的情景,她并不需要在卡片上吃力地搜尋孔位,而是直接對(duì)著孔距更大的操作面板打孔,一根杠桿將兩者的孔位一一對(duì)應(yīng)。操作面板還做成了弧形,頗有一分如今人體工程學(xué)鍵盤的風(fēng)姿。

          img

          在制表機(jī)前,穿孔卡片(或紙帶)多用于存儲(chǔ)指令而不是數(shù)據(jù)。比較有代表性的,一是雅卡爾提花機(jī),用穿孔卡片控制經(jīng)線提沉;二是自動(dòng)鋼琴,用穿孔紙帶控制琴鍵壓放。美劇《西部世界》中,每次故事循環(huán)的開始,都會(huì)給一個(gè)自動(dòng)鋼琴的特寫,彈奏起看似寧?kù)o安逸、實(shí)則詭異違和的背景樂(lè)。

          是霍爾瑞斯將穿孔卡片作為 數(shù)據(jù)存儲(chǔ)介質(zhì) 開來(lái),并開啟了一個(gè)嶄新的 數(shù)據(jù)處理紀(jì)元。后來(lái)人們也把這類卡片稱為霍爾瑞斯卡片,穿孔卡片和穿孔紙帶作為輸入輸出載體,統(tǒng)治了計(jì)算領(lǐng)域整整一個(gè)世紀(jì)。

          單元記錄時(shí)代

          在制表機(jī)的高效運(yùn)轉(zhuǎn)下,1890 年的人口普查只花了 6 年時(shí)間。1896 年,霍爾瑞斯成立制表機(jī)公司(The Tabulating Machine Company)并不斷改進(jìn)自己的產(chǎn)品,先后與英國(guó)、意大利、德國(guó)、俄羅斯、澳大利亞、加拿大、法國(guó)、挪威、美國(guó)波多黎各、古巴、菲律賓等多個(gè)國(guó)家和地區(qū)合作開展了人口普查。

          1914 年,制表機(jī)公司每天生產(chǎn)的穿孔卡片多達(dá) 200 萬(wàn)張。不多久,一些競(jìng)爭(zhēng)對(duì)手逐漸起家,歷史迎來(lái)了繁榮的數(shù)據(jù)處理時(shí)代。它們的產(chǎn)品也不再局限于人口普查,逐漸擴(kuò)展到會(huì)計(jì)、庫(kù)存管理等一些同樣需要跟大數(shù)據(jù)打交道的領(lǐng)域,這些機(jī)器作為制表機(jī)的后裔被統(tǒng)稱為單元記錄設(shè)備(unit record equipment)。

          圍繞穿孔卡片的制卡、讀卡、數(shù)據(jù)處理和卡片分類是它們的標(biāo)準(zhǔn)功能,穿孔機(jī)、讀卡器、分類器是它們的標(biāo)準(zhǔn)配置。這些部件的自動(dòng)化程度越來(lái)越高,比如手動(dòng)的讀卡裝置很快被自動(dòng)讀卡機(jī)所取代,讀卡速度從每分鐘 100 張逐步提高至每分鐘 2000 張。隨著識(shí)別精度的提高,卡片的孔距也越來(lái)越小,具有 80~90 列孔位的卡片成為主流,有些卡片的孔位甚至多達(dá) 130 列。

          20 世紀(jì)典型的 80 系穿孔卡片

          機(jī)器的功能也逐漸強(qiáng)大,不再只是簡(jiǎn)單地統(tǒng)計(jì)穿孔數(shù)目,減法、乘法等運(yùn)算能力陸續(xù)登場(chǎng)。1928 年,哥倫比亞大學(xué)的科學(xué)家們甚至用單元記錄設(shè)備計(jì)算月球的運(yùn)行軌跡,他們?cè)?50 萬(wàn)張卡片上打了 2000 萬(wàn)個(gè)孔,彰顯著單元記錄設(shè)備的無(wú)限潛力。

          機(jī)器的電路實(shí)現(xiàn)越來(lái)越復(fù)雜,但同時(shí)也越來(lái)越通用。1890 年所用的那臺(tái)制表機(jī)的 線路是固定的,遇到新的統(tǒng)計(jì)任務(wù),改造起來(lái)十分麻煩。

          1906 年,霍爾瑞斯便引入了接插線板(plugboard)——一塊布滿導(dǎo)電孔的板卡,可通過(guò)改變導(dǎo)線插腳在板上的位置改變線路邏輯。試想一下,接插線板的內(nèi)部已經(jīng)布好了具有各種功能的線路,但它們都處在斷開狀態(tài),各自連接著接插線板上的某兩個(gè)孔位,像一窩嗷嗷待哺的小鳥長(zhǎng)大著嘴巴,外部的導(dǎo)線就像美味的蟲子,當(dāng)蟲子的頭尾分別與小鳥的上喙和下喙接觸,線路就被導(dǎo)通,這只小鳥就開始工作了。如此,每次使用就可以激活不同的 “小鳥”,從而完成不同的任務(wù)。這已經(jīng)是一種可編程性的體現(xiàn)。

          img

          1911 年,制表機(jī)公司與另外 3 家公司合并成立 CTR 公司 (Computing-Tabulating-Recording Company),制表機(jī)公司作為其子公司繼續(xù)運(yùn)營(yíng)到 1933 年。

          1924 年,CTR 更名為 國(guó)際商業(yè)機(jī)器公司International Business Machines Corporation),就是現(xiàn)在大名鼎鼎的 IBM 公司。可見,在如今眾多年輕的 IT 公司中,擁有百年歷史的 IBM 是位當(dāng)之無(wú)愧的前輩,它完整地參與和見證了整個(gè)現(xiàn)代計(jì)算機(jī)的發(fā)展史。IBM 保持了制表機(jī)公司在單元記錄市場(chǎng)的龍頭地位,到 1955 年,其每天生產(chǎn)的穿孔卡片多達(dá) 7250 萬(wàn)張。

          1937 年開始,單元記錄設(shè)備逐步電子化,與電子計(jì)算機(jī)的界線漸漸模糊,并最終為后者讓路。隨著 1976 年 IBM 一型最核心的單元記錄產(chǎn)品的停產(chǎn),短暫的單元記錄時(shí)代也宣告謝幕,它仿佛是電子計(jì)算時(shí)代來(lái)臨前的預(yù)演和鋪墊,許多設(shè)計(jì)被沿用下來(lái),比如穿孔卡片和接插線板。

          有趣的是,即使電子計(jì)算機(jī)逐漸普及,許多機(jī)構(gòu)由于用慣了單元記錄設(shè)備,遲遲不愿更換,少數(shù)機(jī)構(gòu)甚至一直用到了 21 世紀(jì)。

          一句話總結(jié)

          編程能夠幫助我們解決一些非常實(shí)際的問(wèn)題,用一種非??岬姆绞?。

          img

          感興趣也可以擴(kuò)展閱讀一下:改變世界的代碼行

          Part 2. 二進(jìn)制和 CPU 原理 | 編碼中蘊(yùn)藏的智慧

          img
          • 原文地址:「MoreThanJava」一文了解二進(jìn)制和CPU工作原理

          原來(lái),我們是這樣計(jì)數(shù)的

          在討論「二進(jìn)制」和「CPU 如何工作」之前,我們先來(lái)討論一下我們生活中最稀疏平常的 數(shù)字,我們與之頻繁地打交道:一個(gè)約定的時(shí)間、一件商品的價(jià)格、一個(gè)人的身高....卻很少有人細(xì)細(xì)想過(guò),這些數(shù)字是如何表達(dá)出來(lái)的?為什么你理所當(dāng)然地把 1024 理解為「一千零二十四」而不是別的含義?

          也許你從未想過(guò),在這簡(jiǎn)單的記數(shù)中,沉淀著人類的大智慧。

          一進(jìn)制計(jì)數(shù)法

          早在數(shù)字的概念產(chǎn)生之前,人類就學(xué)會(huì)了使用樹枝、石子、貝殼等自然界隨處可見的小物件表示獵物的、果實(shí)的、部落人口的數(shù)量。比如在某個(gè)角落堆上一堆石子,每打到 1 只獵物,就扔 1 顆石子進(jìn)去,每吃掉 2 只獵物,就從中取走 2 顆石子。他們并不在意石子的總數(shù),只是時(shí)不時(shí)地瞅一眼,心底大致有數(shù)。

          其實(shí)這是一種最樸素的記數(shù)方式,數(shù)學(xué)家稱之為 一進(jìn)制記數(shù)法(unary numeral system)。我們把它符號(hào)化一下,比如用斜杠 / 來(lái)表示:

          • 1 就是 /;
          • 2 就是 //;
          • 4 就是 ////

          好像沒(méi)毛病,我們平時(shí)掰手指用的就是這種記數(shù)法,但數(shù)字一大,場(chǎng)面就要失控了。

          符值相加記數(shù)法

          為了解決記錄大數(shù)的問(wèn)題,于是我們得發(fā)明一些其他符號(hào)來(lái)表示更大的數(shù)值,比如用橫杠 -表示 10,用十字 + 表示 100。那么:

          • 16 就是 -//////;
          • 32 就是 ---//;
          • 128 就是 +--////////;

          漂亮....這種靠符號(hào)類型和符號(hào)數(shù)量表示數(shù)字的方法被稱為 符值相加記數(shù)法(sign-value notation),古埃及和古羅馬用的都是它,只不過(guò)符號(hào)各不相同。

          古埃及的記數(shù)符號(hào):

          1101001000100001000001000000

          1024 在古埃及就寫作:

          img

          你會(huì)發(fā)現(xiàn),符值相加記數(shù)法的一大優(yōu)點(diǎn)是,符號(hào)的順序可以任意打亂,數(shù)字含義不受影響。我國(guó)藏族曾用石子表示 1、木棍表示 10、果核表示 100、蠶豆表示 1000、瓦片表示 10000,那么,當(dāng)你把 1 顆蠶豆、2 根木棍和 4 顆石子胡亂地攥在手里,別人依然知道它們是 1024

          古羅馬的做法略有不同,他們對(duì)五進(jìn)制情有獨(dú)鐘:

          1510501005001000
          IVXLCDM

          這些符號(hào)沿用至今,想必大家(至少對(duì)前 3 個(gè))都比較熟悉,許多鐘表仍保留著使用羅馬數(shù)字的習(xí)慣,1~12 分別表示為:I、IIIII、IV、V、VIVII、VIII、IXX、XIXII。你會(huì)發(fā)現(xiàn),羅馬記數(shù)法是符值相加記數(shù)法的變種,因?yàn)樗还狻赶嗉印梗€「相減」。這種方式就不允許符號(hào)亂序了,IVVI 表示的是不同的數(shù)字。

          那羅馬人何苦要使用這種更復(fù)雜的記數(shù)法呢?無(wú)非是為了讀寫方便。同樣表示 9,IXVIIII 更簡(jiǎn)潔。

          其實(shí)有一種更好使的方法——用另外一些列符號(hào)來(lái)表示符號(hào)的數(shù)量。比如用 A 表示 1 個(gè)符號(hào),用 B 表示 2 個(gè)符號(hào),以此類推,用 I 表示 9 個(gè)符號(hào)。

          如此,上文表示 256++-----////// 就可以寫作 B+E-F/。你一定感覺(jué)莫名其妙,這種寫法哪里方便了。其實(shí)中文的數(shù)字表示就是這種形式,只不過(guò)我們用得太習(xí)慣了,以至于沒(méi)有發(fā)現(xiàn)。

          在中文中,個(gè)、 代替了 /、-、+,而 、、 代替了 A、B、C256 就寫作 二百五十六個(gè),個(gè) 比較累贅,我們通常把它省略了。

          其實(shí)像日語(yǔ)、英語(yǔ)用的也同樣是這種記數(shù)法,簡(jiǎn)潔、優(yōu)雅。

          美中不足的是,這種形式雖便于讀寫,卻不便于計(jì)算。中國(guó)古人為算籌和算盤這類經(jīng)典算具搭建起廣闊的舞臺(tái),卻沒(méi)給筆算留出一席之地。想象一下,如果讓你把這些漢字寫在草稿紙上,列個(gè)豎式,你的內(nèi)心一定非常別扭。

          位值制記數(shù)法

          公元5世紀(jì),印度數(shù)學(xué)家阿耶波多(Aryabhata 476–550)創(chuàng)立了現(xiàn)在廣泛使用的 位值制記數(shù)法(positional notation/place-value notation),該記數(shù)法使用的主要符號(hào),是同為印度人發(fā)明的阿拉伯?dāng)?shù)字:0、1、23、45、6、78、9。

          與符值相加記數(shù)法類比,位值制中的 12、3 代替的是 AB、C,那 /、-、+呢?是 靠阿拉伯?dāng)?shù)字的位置來(lái)表示的。眾所周知,最右位相當(dāng)于 /,次右位相當(dāng)于 -。靠每個(gè)位置上的數(shù)值來(lái)表示數(shù)字,故名位值制。

          嚴(yán)謹(jǐn)?shù)臄?shù)學(xué)家用一種多項(xiàng)式高度概括了位值制記數(shù)法的本質(zhì),在十進(jìn)制中,這個(gè)多項(xiàng)式是這樣的:

          img
          img

          這是一個(gè) n 位十進(jìn)制數(shù),ai 就是第 i 位上的數(shù)值。為便于直觀理解,舉個(gè) 1024 的例子吧:

          img

          由于我們熟悉了十進(jìn)制,這樣費(fèi)心費(fèi)力的展開可能會(huì)讓你覺(jué)得好笑,但當(dāng)我們把它推廣到其他進(jìn)制時(shí),這個(gè)多項(xiàng)式的價(jià)值就體現(xiàn)了出來(lái)。n 位 b 進(jìn)制數(shù)的位值制表示:

          img
          img

          1024 用二進(jìn)制怎么表示?

          img

          因此,1024 的二進(jìn)制寫作 10000000000。

          除了最普遍的十進(jìn)制和計(jì)算機(jī)中的二進(jìn)制,常見的還有七進(jìn)制(如 17 天)、十二進(jìn)制(如 112 個(gè)月)、十六進(jìn)制(如古代 116 兩)、六十進(jìn)制(如六十甲子)等等,只要有意義,任何進(jìn)制都可以為你所用。

          為什么使用二進(jìn)制

          至此,你對(duì)「二進(jìn)制」或許不再那么陌生,它僅僅是數(shù)制的一種而已。

          可為什么一定是二進(jìn)制呢?使用人類習(xí)慣的十進(jìn)制不好嗎?

          理由一:物理上易于實(shí)現(xiàn)

          計(jì)算機(jī)依靠電力工作,這也就意味著需要將數(shù)字信號(hào)映射到電信號(hào),實(shí)現(xiàn)這種映射最簡(jiǎn)單的方法是:

          • 0 - 沒(méi)有電(0 V)
          • 1 - 有點(diǎn)(5 V)

          二進(jìn)制在技術(shù)上最容易實(shí)現(xiàn)。這是因?yàn)榫哂袃煞N 穩(wěn)定狀態(tài) 的物理器件很多,如門電路的導(dǎo)通與截止、電壓的高與低等,而它們恰好可以對(duì)應(yīng)表示 “1” 和 “0” 這兩個(gè)數(shù)碼。假如采用十進(jìn)制,那么就要制造具有 10穩(wěn)定狀態(tài) 的物理電路,而這是非常困難的。

          理由二:機(jī)器可靠性高

          為什么使用更復(fù)雜的數(shù)字系統(tǒng)是一個(gè)問(wèn)題?

          假設(shè)我們使用三元(3 位數(shù)字)數(shù)字系統(tǒng)涉及計(jì)算機(jī),如果我們具有從 0 V5 V 的電壓,那么我們可以進(jìn)行以下的映射:

          • 0 - 0 V;
          • 1 - 2.5 V;
          • 2 - 5 V;
          img
          • 圖片來(lái)源:https://pmihaylov.com/intro-binary-numbers/

          看起來(lái)合理吧?但是,想象一下,我以 2.5 V 的電壓發(fā)送了一個(gè)數(shù)字。但是由于電路中的一些噪聲,我在輸出端得到 2.3 V 的電壓,因此將其視為 0。結(jié)果是?

          有人給我發(fā)送了 1,但我將其視為 0。數(shù)據(jù)丟失可是一個(gè)非常嚴(yán)重的問(wèn)題。

          使用二進(jìn)制則可靠得多,由于電壓的高和低、電流的有和無(wú)等都是一種 質(zhì)的變化,兩種物理狀態(tài)穩(wěn)定、分明,因此,二進(jìn)制碼傳輸?shù)目垢蓴_能力強(qiáng),鑒別信息的可靠性高。

          為什么計(jì)算機(jī)系統(tǒng)必須有時(shí)鐘

          img
          • 圖片來(lái)源:http://programmedlessons.org/Java9/chap02/ch02_11.html

          建立數(shù)字系統(tǒng)的目的是 僅在某些時(shí)間點(diǎn)測(cè)試開/關(guān)(二進(jìn)制)值,這使電線(或其他設(shè)備)有時(shí)間更換。這就是計(jì)算機(jī)系統(tǒng)有時(shí)鐘的原因。

          時(shí)鐘會(huì)周期性地進(jìn)行信號(hào)的測(cè)量,圖中所示的 T1 和 T2 就是可以測(cè)量信號(hào)的時(shí)間點(diǎn)。

          時(shí)鐘利用所有這些時(shí)間點(diǎn)來(lái)保持同步。更快的時(shí)鐘意味著每秒可以對(duì)電線進(jìn)行更多次測(cè)試,并且整個(gè)系統(tǒng)運(yùn)行得更快。2 GHz 處理器每秒檢查二進(jìn)制值 20 億次。在這些時(shí)間之間,允許值改變并穩(wěn)定下來(lái)。處理器芯片速度越快,每秒可以測(cè)試的次數(shù)就越多,每秒可以做出的決策就越多。

          理由三:運(yùn)算規(guī)則簡(jiǎn)單

          數(shù)學(xué)推導(dǎo)已經(jīng)證明,對(duì) N 進(jìn)制數(shù)進(jìn)行算術(shù)求和或求積運(yùn)算,其運(yùn)算規(guī)則各有 N(N+1)/2種。如采用十進(jìn)制,則 N=10,就有 55 種求和或求積的運(yùn)算規(guī)則;而采用二進(jìn)制,則 N=2,僅有 3 種求和或求積的運(yùn)算規(guī)則,以上面提到的加法為例:

          0+0=0,0+1=1?(1+0=1),1+1=10

          因而可以大大簡(jiǎn)化運(yùn)算器等物理器件的設(shè)計(jì)。

          理由四:邏輯判斷方便

          采用二進(jìn)制后,僅有的兩個(gè)符號(hào) “1”“0” 正好可以與邏輯命題的兩個(gè)值 “真” 和 “假” 相對(duì)應(yīng),能夠方便地使用邏輯代數(shù)這一有力工具來(lái)分析和設(shè)計(jì)計(jì)算機(jī)的邏輯電路。

          雖然在 1950 年代就造出了更加高效的三元計(jì)算機(jī),但在效率和復(fù)雜度的取舍上,始終抵不過(guò)二進(jìn)制。二進(jìn)制仍然在當(dāng)今世界中長(zhǎng)期存在。

          CPU 的實(shí)際工作方式簡(jiǎn)單演示

          上面我們了解到計(jì)算機(jī)以二進(jìn)制的形式運(yùn)行,它們只有兩種狀態(tài):開(1)和關(guān)(0),為了執(zhí)行二進(jìn)制計(jì)算,我們需要采用一種特殊的電子元器件,稱為 「晶體管」。暫時(shí)我們把它理解為一種開關(guān)吧,通電就打開,沒(méi)電流通過(guò)就關(guān)閉。

          利用「開關(guān)」搭建邏輯電路

          我們知道,給電燈通上電,它就會(huì)亮:

          img

          于是,結(jié)合上開關(guān),我們就能搭建出最基礎(chǔ)的 與門或門。

          與門

          img

          該電路的邏輯是:只有當(dāng) A 和 B 同時(shí)開啟時(shí),LED 燈才會(huì)亮,也就是認(rèn)為輸出 1,我們可以利用電信號(hào)來(lái)簡(jiǎn)單模擬一下:

          ABY
          000
          100
          010
          111

          或門

          img

          該電路的邏輯是:當(dāng) A 或者 B 開啟時(shí),LED 燈就會(huì)亮,也就是認(rèn)為輸出 1,我們可以利用電信號(hào)來(lái)簡(jiǎn)單模擬一下:

          ABY
          000
          101
          011
          111

          其他門

          類似地,我們可以借助更多的電子元器件來(lái)創(chuàng)造出基礎(chǔ)的 7 種邏輯門電路:

          img
          • 圖片來(lái)源:https://www.zhihu.com/question/348237008/answer/843382847 | @Zign

          這里需要特別提一下 異或門,我們需要先知道有一種電子元器件可以利用電氣特性對(duì) 輸入取反,也就是說(shuō)輸入 1 則輸出 0,輸入 0 則輸出 1,那么我們就可以 簡(jiǎn)單模擬 出異或門邏輯電路(實(shí)際會(huì)更復(fù)雜些,這里僅展示出異或的意思):

          img

          A'B' 分別表示 AB 開關(guān)的反值,從圖中我們很容易知道只有當(dāng) A、B 只存在一個(gè)輸入 1 時(shí),整個(gè)電路才會(huì)輸出 1。

          利用邏輯門制作簡(jiǎn)單加法器演示

          OK,上面我們了解到我們能夠利用 "開關(guān)" 來(lái)模擬邏輯的運(yùn)算,我們接下來(lái)試著還原一個(gè)簡(jiǎn)單的加法運(yùn)算器是如何實(shí)現(xiàn)的:

          img

          僅需兩個(gè)門,就可以完成基本的二進(jìn)制加法運(yùn)算。上圖是利用 logic.ly 創(chuàng)建的半加法器,A、B 相當(dāng)于使我們計(jì)算的兩個(gè)數(shù),最后一塊相當(dāng)于是我們的數(shù)顯芯片,它的功能是根據(jù)輸入顯示數(shù)字,從上到下的引腳(也就是圖中輸入的地方,通常我們這樣稱呼)分別對(duì)應(yīng)了 20=1、21=2、22=423=8 的輸入,沒(méi)有任何輸入時(shí)顯示為 0,如果 引腳 1(對(duì)應(yīng) 20=1)像上圖一樣有輸入,則顯示 0 + 1 = 1。

          我們來(lái)理解一下上方的電路:

          • 如果僅打開一個(gè)輸入,但不同時(shí)打開兩個(gè)輸入,則此處的 XOR 門(異或門)將打開,此時(shí)對(duì)應(yīng)輸入 引腳 1,顯示 數(shù)字 1(類似于 1 + 0 和 0 + 1);
          • 如果兩個(gè)輸入均打開,則 AND 門(與門)將打開,此時(shí)對(duì)應(yīng)輸入 引腳 2,顯示 數(shù)字 2(類似于 1 + 1);
          • 如果沒(méi)有輸入,則 AND 門和 XOR 門都保持關(guān)閉,此時(shí)顯示 數(shù)字 0(類似于 0 + 0);

          因此,如果兩個(gè)都打開,則 XOR 保持關(guān)閉,并且 AND 門打開,得出正確的答案為 2

          img

          但這只是最基礎(chǔ)的半加法運(yùn)算器,不是太有用,因?yàn)樗荒芙鉀Q最簡(jiǎn)單的數(shù)學(xué)問(wèn)題之一。但如果我們把它們兩個(gè)與另一個(gè)輸入連接,就會(huì)得到一個(gè)完整的加法器:

          img

          仔細(xì)思考幾遍,你就會(huì)得知這個(gè)三個(gè)輸入的加法器已經(jīng)可以計(jì)算 3 個(gè)二進(jìn)制數(shù)字的加法運(yùn)算了,我們?nèi)绶ㄅ谥疲梢酝ㄟ^(guò)連接更多的"進(jìn)位"來(lái)使這個(gè)加法器能夠運(yùn)算更多的數(shù),這當(dāng)然也意味著這個(gè)計(jì)算鏈條更長(zhǎng)。

          大多數(shù)其他數(shù)學(xué)運(yùn)算都可以加法完成。乘法只是重復(fù)加法,減法可以通過(guò)一些奇特的位反轉(zhuǎn)來(lái)完成,而除法只是重復(fù)減法。并且,盡管所有現(xiàn)代計(jì)算機(jī)都具有基于硬件的解決方案以加快更復(fù)雜的操作,但從技術(shù)上講,您可以使用完整的加法器來(lái)完成全部操作。

          一句話總結(jié)

          編碼伴隨探索和學(xué)習(xí)新知的過(guò)程,如果愿意,我們能從中獲取很多類似于解出一道數(shù)學(xué)題的樂(lè)趣。

          img

          Part 3. 機(jī)器指令到高級(jí)語(yǔ)言 | 站在先驅(qū)巨人的肩膀

          img

          機(jī)器指令

          我們已經(jīng)了解了 二進(jìn)制和 CPU 的基本原理,知道了程序運(yùn)行時(shí),CPU 每秒數(shù)以億次、十億次、百億次地震蕩著時(shí)鐘,同步執(zhí)行著微小的 「電子操作」,例如:從內(nèi)存讀取一個(gè)字節(jié)的數(shù)據(jù)到 CPU 又或者判斷字節(jié)中的某一位是 0 還是 1。

          CPU 本身有一組 規(guī)定好的 可以執(zhí)行的 「基本動(dòng)作」(被稱為 機(jī)器指令):

          1. 讀取指令;2. 執(zhí)行指令;3. 寫寄存器;

          這幾乎就是 CPU 工作的全部了。 這些動(dòng)作雖然每次只能執(zhí)行一次,但是每秒可以執(zhí)行數(shù)十億次,這個(gè)數(shù)量級(jí)的「小操作」累加成為一個(gè)大的「有用的操作」。

          處理器所做的一切都是基于這些微小的操作!幸運(yùn)的是,我們已經(jīng)不再需要了解這些操作的詳細(xì)信息就可以編寫和使用各類程序。諸如 Java 這一類的 「高級(jí)語(yǔ)言」目的 就是 將這些微小的電子操作組織成由人類可讀的「程序語(yǔ)言」表示的大型有用單元。

          盡管機(jī)器語(yǔ)言有一些反人類,但至少我們可以用它來(lái)來(lái)編寫代碼了,如:

          00000001?00000010?00000001
          00000100?00000100?00000000

          似乎看著這一段兒代碼有點(diǎn)迷糊,并且 可讀性太差了

          如此你就會(huì)感知到 上個(gè)世紀(jì) 的程序員使用 打孔卡片

          img

          使用 紙帶

          img

          甚至是 直接插拔線路 or 按下開關(guān)

          img

          是一件多么硬核的事情...

          匯編語(yǔ)言

          PU 的指令都是 二進(jìn)制 的,這顯然對(duì)于人類來(lái)說(shuō)是 不可讀 的。為了解決二進(jìn)制指令的可讀性問(wèn)題,工程師將那些指令寫成了 八進(jìn)制。二進(jìn)制轉(zhuǎn)八進(jìn)制是輕而易舉的,但是八進(jìn)制的可讀性也不行。

          很自然地,最后還是用文字表達(dá),加法指令寫成 ADD。內(nèi)存地址也不再直接引用,而是 用標(biāo)簽 表示。

          這樣的話,就多出一個(gè)步驟,要把這些文字指令翻譯成二進(jìn)制,這個(gè)步驟就稱為 assembling,完成這個(gè)步驟的程序就叫做 assembler。它處理的文本,自然就叫做 aseembly code。標(biāo)準(zhǔn)化以后,稱為 assembly language,縮寫為 asm,中文譯為 匯編語(yǔ)言。

          匯編語(yǔ)言演示

          舉個(gè)簡(jiǎn)單的例子,我們需要計(jì)算:

          (1?+?4)?*?2?+?3

          我們按照 「后綴表示法」 進(jìn)行一下轉(zhuǎn)換:

          1,4,+,2,*,3,+

          我們平常使用的方法是 「中綴表示法」,也就是把計(jì)算符號(hào)放中間,例如 1 + 3,后綴則是把符號(hào)放最后,例如 1, 3, +

          這樣做的好處是沒(méi)有先乘除后加減的影響,也沒(méi)有括號(hào),直接運(yùn)算就行了。(例如 1, 3, +,先把 13 保存起來(lái)碰到 + 知道是加法則直接相加)

          OK,我們從頭開始使用匯編語(yǔ)言來(lái)編寫一下程序,首先第一步:把 1 保存起來(lái)(放入寄存器):

          MOV??1

          之后是 4, +,那就直接加一下:

          ADD?4

          然后是 2, *,那就直接乘一下(SHL 是向左移動(dòng)一位的意思,二進(jìn)制中左移一個(gè)單位就相當(dāng)于乘以 2,例如 01 表示 1,而 10 則表示 2):

          SHL?0

          最后是 3, +,再加一下:

          ADD?3

          完整程序如下:

          MOV??1
          ADD??4
          SHL??0
          ADD??3

          這似乎看起來(lái)比 00001111 這樣的二進(jìn)制要好上太多了!程序員們感動(dòng)到落淚:

          img

          高級(jí)語(yǔ)言

          擺脫了 二進(jìn)制,我們有了更可讀的 匯編語(yǔ)言,但仍然十分繁瑣和復(fù)雜,每一條匯編指令代表一個(gè)基本操作,例如:「從內(nèi)存 x 位置獲取一個(gè)數(shù)字并放入寄存器 A」、「將寄存器 A 中的數(shù)字添加到寄存器 B 的數(shù)字上」。這樣的編程風(fēng)格既費(fèi)時(shí)又容易出錯(cuò),并且一旦出錯(cuò)還很難發(fā)現(xiàn)。

          例如,我們來(lái)看一看 「1969 年阿波羅 11號(hào)登月計(jì)劃」 用來(lái) 防止登月艙計(jì)算機(jī)耗盡自身資源的 BAILOUT 代碼:

          POODOO????INHINT
          ????CA??Q
          ????TS??ALMCADR
          ?
          ????TC??BANKCALL
          ????CADR??VAC5STOR??#?STORE?ERASABLES?FOR?DEBUGGING?PURPOSES.
          ?
          ????INDEX??ALMCADR
          ????CAF??0
          ABORT2????TC??BORTENT
          ?
          OCT77770??OCT??77770????#?DONT?MOVE
          ????CA??V37FLBIT??#?IS?AVERAGE?G?ON
          ????MASK??FLAGWRD7
          ????CCS??A
          ????TC??WHIMPER?-1??#?YES.??DONT?DO?POODOO.??DO?BAILOUT.
          ?
          ????TC??DOWNFLAG
          ????ADRES??STATEFLG
          ?
          ????TC??DOWNFLAG
          ????ADRES??REINTFLG
          ?
          ????TC??DOWNFLAG
          ????ADRES??NODOFLAG
          ?
          ????TC??BANKCALL
          ????CADR??MR.KLEAN
          ????TC??WHIMPER
          • 出處:改變世界的代碼行 - https://www.infoq.cn/article/5CaYH8NbS6BmptWKRgkX

          似乎不太容易讀的樣子...

          阿波羅登月計(jì)劃的源代碼在 Github 上已經(jīng)公開,有興趣的可以去下方鏈接膜拜一下(可以去感受一下當(dāng)時(shí)程序員的工程能力):

          • https://github.com/chrislgarry/Apollo-11

          另外附一下當(dāng)時(shí)代碼的設(shè)計(jì)負(fù)責(zé)人 Margaret Heafield Hamilton(女程序員)和完成的堆起來(lái)跟人一樣高的代碼量:

          第一個(gè)高級(jí)語(yǔ)言:FORTRAN

          當(dāng) John Backus1950 年以一名科學(xué)程序員的身份加入 IBM 時(shí),已經(jīng)可以使用諸如 ADD 之類的助記詞代替數(shù)字代碼來(lái)編寫程序,也就是我們的匯編語(yǔ)言。這使編程變得容易一些,但是即使是一個(gè)簡(jiǎn)單的程序也需要數(shù)十次操作,并且仍然很難找到錯(cuò)誤。

          巴克斯認(rèn)為,應(yīng)該有可能創(chuàng)建一種編程語(yǔ)言,使一系列計(jì)算可以用類似于數(shù)學(xué)符號(hào)的形式來(lái)表達(dá)。然后,使用特定的翻譯程序(以今天的術(shù)語(yǔ)來(lái)說(shuō)是編譯器)可以將其轉(zhuǎn)換為計(jì)算機(jī)可以理解的數(shù)字代碼。

          Backus 在 1953 年向他的經(jīng)理提出了這個(gè)想法。他得到了預(yù)算,并被鼓勵(lì)雇用一個(gè)小團(tuán)隊(duì)來(lái)測(cè)試該想法的可行性。三年后,該團(tuán)隊(duì)發(fā)布了一本手冊(cè),其中描述了 IBM Mathematical Formula Translating System(簡(jiǎn)稱 FORTRAN)。不久之后, IBM 向 IBM 704 的用戶提供了第一個(gè) FORTRAN 編譯器。

          FORTRAN 之父

          Backus 和他的團(tuán)隊(duì)創(chuàng)造了世界上第一種高級(jí)編程語(yǔ)言。科學(xué)家和工程師將不再需要將其程序編寫為數(shù)字代碼或冗長(zhǎng)的助記符

          FORTRAN 代碼演示

          下面演示計(jì)算并輸出 8 * 6 的代碼實(shí)例:

          program?VF0944
          implicit?none

          integer?a,?b,?c
          a=?8
          b=?6
          c=?a*b

          print?*,?'Hello?World,?a,?b,?c=?',?a,?b,?c
          end?program?VF0944

          對(duì)比匯編代碼,是不是看上去要清晰(人類可讀)多了呢?

          FORTRAN 的意義

          FORTRAN 的問(wèn)世在計(jì)算機(jī)史上具有劃時(shí)代的意義,它使計(jì)算機(jī)語(yǔ)言從原始的低級(jí)匯編語(yǔ)言走出來(lái),進(jìn)入了更高的境界,使得 計(jì)算機(jī)語(yǔ)言不再是計(jì)算機(jī)專家的專利,使廣大的工程技術(shù)人員有了進(jìn)行計(jì)算機(jī)編程的手段。

          由此計(jì)算機(jī)更快地深入到了社會(huì)之中,它在工業(yè)部門中初露頭角,更是在火箭、導(dǎo)彈、人造地球衛(wèi)星的設(shè)計(jì)中大顯身手,因此有人稱 FORTRAN 語(yǔ)言使計(jì)算機(jī)的工業(yè)應(yīng)用成了可能,是推動(dòng)第二次世界大戰(zhàn)以后西方工業(yè)經(jīng)濟(jì)復(fù)蘇和進(jìn)入第二次工業(yè)革命的無(wú)形力量,是 "看不見的蒸汽機(jī)"。

          一句話總結(jié)

          計(jì)算機(jī)先驅(qū)們已經(jīng)為我們架設(shè)好了計(jì)算機(jī)的世界,站在先驅(qū)巨人們的肩膀,我們?nèi)缃窈苋菀滓部梢钥吹酶吆透h(yuǎn)。


          Part 4. 構(gòu)建自己獨(dú)有的程序(世界)

          img
          • 圖片來(lái)源自:https://www.infoq.cn/article/5CaYH8NbS6BmptWKRgkX

          編碼的樂(lè)趣有很多,把自己的想法動(dòng)手實(shí)踐就是其中一個(gè)。

          例如網(wǎng)友玩兒游戲活動(dòng)需要不停點(diǎn)鼠標(biāo),于是寫了一個(gè)鼠標(biāo)連點(diǎn)器:

          img

          例如給自己心愛的妹子寫一個(gè)戀愛紀(jì)念網(wǎng)站:

          img

          例如給 FlappyBird 加一個(gè)強(qiáng)化學(xué)習(xí)算法讓它自己學(xué)習(xí)如何飛行:(圖示已經(jīng)能自己飛 4527步了)

          img

          例如網(wǎng)友自己寫的文言文語(yǔ)言:(使用文言文寫代碼)

          //?HelloWorld?程序演示
          吾有一數(shù)。曰三。名之曰「甲」。
          為是「甲」遍。
          ?吾有一言。曰「「問(wèn)天地好在?!埂埂?。
          云云。

          運(yùn)行輸出:

          問(wèn)天地好在。
          問(wèn)天地好在。
          問(wèn)天地好在。

          一句話總結(jié)

          我們可以動(dòng)手通過(guò)編程把我們的很多想法付諸于實(shí)現(xiàn) (前提是不斷探索和學(xué)習(xí)),并在迎接挑戰(zhàn)和最終實(shí)現(xiàn)的過(guò)程中獲得無(wú)限的樂(lè)趣。

          img

          小總結(jié)

          總體而言,IT 是令人興奮的。

          素有「軟件吞噬世界」的說(shuō)法,我們也正生活在計(jì)算機(jī)當(dāng)?shù)赖氖澜纭?/p>

          并且編程并不是每個(gè)人都具備的技能,借助技術(shù),一切皆有可能,并且現(xiàn)在互聯(lián)網(wǎng)時(shí)代比以往都更有機(jī)會(huì)學(xué)習(xí)和創(chuàng)建「自己的世界」。

          最后

          文章有幫助可以點(diǎn)個(gè)「在看」或「分享」,都是支持,我都喜歡!

          我是 Guide 哥,Java后端開發(fā),會(huì)一點(diǎn)前端知識(shí),喜歡烹飪,自由的少年。一個(gè)三觀比主角還正的技術(shù)人。我們下期再見!


          往期推薦



          來(lái)吧!手寫一個(gè) RPC 框架。畢設(shè)/項(xiàng)目經(jīng)驗(yàn)穩(wěn)了!

          我在華為外包一年的經(jīng)歷分享。

          內(nèi)卷嚴(yán)重?加班多?給幾條程序員都適用的建議

          要想提高代碼質(zhì)量,請(qǐng)把這5本書籍至少看 3 遍!

          后端程序員必備的 Linux 基礎(chǔ)知識(shí)+常見命令(近萬(wàn)字總結(jié))

          瀏覽 62
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产无圣光 | 风流老熟女一区二区三区 | 日欧美视频在线 | 亚洲精品水蜜桃 | 亚州性爱|