0 前言
本文以十進制整數爲例,使用2個最簡單的表達式char a = -20;
和char c = a + b;
,爲你深入淺出地講解計算機思維,力求將抽象的計算機思維具象化講解,同時,我將爲你描述一個宏大的計算機世界的藍圖。
計算機思維與核心思想概要:
- 人類世界與計算機世界的通道:編碼與譯碼
- 計算機處理信息的本質:二進制信息的運算
- 現實世界向計算機世界的映射:二進制信息運算的原則
- 人類與計算機鬥爭的勝利與妥協:分而治之、抽象思想與分析程序行爲、分工協作
爲了避免內容的冗雜,本文只談及十進制整數和二進制數,力求使用最淺顯易懂的知識,講清楚高深的計算機思維。
1 人類世界與計算機世界的通道:編碼與譯碼
本小節,從最簡單的十進制整數與二進制數的相互轉化,來解釋編碼與譯碼。
1.1 一段簡單的C語言代碼
你需要使用VS 2017進行單步調試和查看內存。
補充鏈接:使用VS 2017進行單步調試和查看內存
這裏我們用char
代表能夠存儲一字節大小的機器數的容器,並不使用其字符的功能。
你可以想象,這是一個char類型的容器,能夠存儲8位二進制數。
以下是我們即將展開講解的C語言代碼:
#include <stdio.h>
#include <Windows.h>
int main() {
char a = -20;
unsigned char b = -20;
system("pause");
return 0;
}
1.2 查看變量的內存情況
首先,我們查看一下數據a
和b
在內存中的情況,這個時候,計算機已經完成了十進制整數到二進制的轉換,內存中存儲的是對應的二進制信息,通常採用十六進制表示。
變量a在內存的情況:
變量b在內存的情況:
如果你不知道如何查看變量地址的話,可以通過C語言中的&a
和&b
,輸出到控制檯來查看。
我們可以看見,不管是帶符號的變量a還是不帶符號的變量b,將-20
賦值給它們,存儲到內存中的,都是十六進制的ec
,也就是二進制的11101100
。
這裏表明,計算機是先將-20
轉換爲11101100
,然後再放入變量中的。
我們查看一下【局部變量】:
這裏表明:
- a和b的二進制信息是完全一樣的
- 他們輸出到屏幕的數據類型和十進制數值不一樣的
這是爲什麼呢?
1.3 計算機編碼:從十進制到二進制
我們再看下面的圖
首先,我來解釋一下從通過鍵盤輸入到存儲存儲器的過程
- 從屏幕鍵入
-20
,計算機先進行編碼,變成了二進制的11101100
- 再將二進制信息,存儲了變量a和b中。其中,變量a和b分別是帶符號和不帶符號的
char
類型數據
這裏有兩個不同顏色的盒子
- 它們分別代表
char
類型和unsigned char
類型 - 他們分別被打上了標籤
a
和b
- 他們都存入了二進制信息
11101100
1.4 計算機譯碼:從二進制到十進制
下面我來講解一下,從二進制信息到輸出十進制的過程。
儘管a和b兩個盒子中的二進制信息完全一樣,但是你要清楚,這只是在計算機世界完全一樣,在人類世界中,二進制信息的含義應該是:二進制信息的含義 = 位 + 上下文,所謂上下文,就是二進制信息所處的環境。
參考學習:《深入理解計算機系統》的1.1節
也就是說【11101100
+ 數據類型】,通過這兩個條件,才能正確得到現實世界中,二進制信息的含義,這裏我們將二進制,以十進制形式進行輸出。
- 對於變量a,以帶符號的十進制形式輸出,因爲它被轉換爲二進制之前,就是帶符號的十進制數。
- 對於變量b,以無符號的十進制形式輸出,因爲它被轉換爲二進制之前,就是無符號的十進制數。
這裏我們需要強調的是,對於十進制與二進制的相互轉換,大多情況下,是怎麼進去的,就要怎麼回來,除非特殊需求,比如需要將十進制數轉換爲字符輸出,這也是允許的。
1.5 小結
本節我爲你展示了兩個過程
- 十進制 --> 二進制,這個過程叫編碼
- 二進制 --> 十進制,這個過程叫譯碼
計算機的外部設備,鼠標、鍵盤、音響和顯示器等等,這些都是從人類世界進入計算機世界的入口。
人類通過這些外部設備輸入信息(十進制數、文字、圖片、視頻、音頻……),由計算機進行編碼,以二進制數的形式進入計算機世界,你也可以理解爲入鄉隨俗。
這些二進制數在計算機的世界裏遨遊,有些二進制數是數據,有些是指令,這些指令是計算機世界的指揮者,他們指揮着數據工作,這些數據可能進行加法工作,可能進行乘法工作……
當這些二進制數,完成了他們的探索使命,就要回到人類世界,這個時候,他們將會通過計算機進行譯碼,恢復他們在人類世界的本來面貌。
你可以想象,一架宇宙飛船,從人類世界,通過蟲洞進入計算機世界,在完成任務後,又通過蟲洞返回人類世界。
2 計算機處理信息的本質:二進制信息的運算
2.1 體驗計算機的二進制運算
我們把上一小節的代碼,再加上一行代碼char c = a + b;
char a = -20;
unsigned char b = -20;
char c = a + b;
我們查看一下內存和局部變量:
可以得知,變量c
對應的十六進制是d8
,二進制是11011000
,又因爲它是char類型,因此二進制信息對應的十進制信息是 -40。
這裏你是不是有疑問?試想,如果是按照十進制進行相加-20 + 236
,肯定不等於-40
,並且,一個char類型的數和一個unsigned char類型的數據,不同的數據類型相加,又是怎麼進行的呢?
這裏,也就可以談及我們的要點,信息處理的本質,是二進制信息的運算。我們所有的信息,都是先轉換成二進制信息,再進行相關運算,運算結束後再根據其上下文,返回對應的結果。
我們根據這個過程,再來審視一下剛纔的例子:
- 將
a
和b
的內部是二進制信息,將它們進行加法運算,得到結果 - 將結果放進容器
c
中 c
中的二進制信息,再由計算機譯碼,轉換爲十進制輸出到屏幕
如果我們將最後一條加法改成unsigned char c = a + b;
,c的結果將會是216
,具體過程留給讀者思考。
需要注意的是,這裏我舉這個例子,只是爲了說明本文的觀點,事實上,C語言編程中,非常不建議將無符號與有符號數混合運算,因爲那樣得到的結果很可能令人費解,可能也沒有什麼現實含義。
2.2 小結
本小節爲你講述了這些內容:
- 對於
char a = -20;
,計算機先將-20以補碼的方式轉換爲二進制信息11101100
,在將其放入變量a所對應的內存中。 - 對於
char c = a + b;
,計算機會在CPU中,會進行如下過程- 將a和b的二進制信息進行加法運算
- 將得到的結果放進變量c所對應的內存中
- 再轉換爲十進制顯示到屏幕上
在計算機的世界裏,只有二進制數,這些二進制數,在計算機世界中,按照人類設定的規則不斷地運算,完成任務後,又以原本的身份回到人類世界。
這,就是計算機處理數據的本質,計算機按照人類設定的規則進行二進制運算。
推薦閱讀《編碼:隱匿在計算機軟硬件背後的語言》
3 人類世界向計算機世界的映射:二進制信息運算的原則
計算機是人類發明的工具,是人類智能的延伸,因此,計算機世界的運算法則,要遵從人類世界的運算法則,才能更好地爲人類服務。
例如人類世界中,1+2 = 3
,那麼在計算機世界中,0001 + 0010
也要等於0011
。
無論是加減乘除法,還是其他種種,都有遵循這個原則,這樣人類才能更方便地利用計算機解決現實問題。
因此,二進制數本質上就是現實世界在計算機世界的映射,它具備現實世界的含義。他們之間實現映射的通道是編碼與譯碼。
我給出你一個表格,做個對比,讓你清晰地感受這種映射。
人類世界 | 計算機世界 |
---|---|
領導者 | 控制器 |
基層員工 | 運算器 |
能源物質 | 數據 |
給你解釋一下:
- 控制器在CPU內,能夠指揮計算機怎樣工作
- 運算器在CPU內,能夠進行數據的運算
- 數據在計算機存儲器(內存、硬盤等)中四處遊走
給你推薦一個動畫,能夠讓你清晰感受到:人類是高維生物,而計算機世界是人類創造的一個新的世界,這個世界是人類世界的映射,它爲人類世界工作和服務。
推薦動畫:《瑞克和莫蒂》第二季第六集:電池微世界
4 人類與計算機鬥爭的勝利與妥協
自從計算機被髮明以來,人類與計算機一直在進行着永無休止的鬥爭,不斷進行着碰撞與融合。
計算機是人造的產物,它是人類思維的產物,但是隨着它的不斷髮展,其複雜性成指數級上升,獨立的個體已經很難去控制它,因此,爲了充分利用計算機來爲人類造福,人類又發明了很多方法去控制它,去約束它。
計算機誕生以來,形成了很多的分支領域,也誕生了很多優秀的理論,這些都讓人類能夠更好地控制計算機,爲人類造福,例如軟件工程中的瀑布模型及其衍生模型、敏捷開發方法;又例如當今時代的火熱技術人工智能、大數據;又例如面向未來的量子計算機……
人類在這場沒有硝煙的戰爭中,有勝利,也有妥協。
4.1 人類的勝利
人類在這場戰爭中,充分發揮自身的智能,成功地使用分而治之的哲學思想和邏輯抽象的數學思想,戰勝了複雜的計算機!
4.1.1 分而治之思想的應用
根據本文的核心理念,這裏我只使用文章開始提及的簡單表達式,來爲你講解分而治之思想的實際應用,然後給到你該思想的本質內核。
對於表達式char a = 3;
,我們可以將其分開看待:
- 3轉換爲二進制,看作
0011
- char看作某種類型的容器
- a看作容器的標籤
這樣,你就可以將這個表達式看成:將0011
放進貼着標籤a的char類型的容器中。
這個簡單問題,可能沒有讓你感受到複雜問題的簡化,你可以想象一個需要你解決的問題:讓你開發一款操作系統,這個問題足夠複雜,但是其開發過程的各個環節,都滲透着分而治之的思想,我想你應該清楚它的重要性了。
該思想能夠讓複雜性問題簡單化,讓很難被解決的問題得以解決,事實上,人類面對大規模問題,都會採取這樣的思想:軟件工程的分工協作、硬件編程的層次建模……它有大量的應用場景,這個思想對讀者來說,是年金,它每年都會給讀者分紅,時間越久,利息越多。
4.1.2 分而治之思想的本質
Divide et impera ——拉丁語,意爲“分而治之”,引自Machiavelli的一句政治箴言,1532
分而治之的思想本質,就是拆解與轉化:
- 將大問題拆解爲小問題
- 將小問題拆解爲更小的問題
- 將更小地問題轉化已知的被解決過了的問題
Critical thinking(批判性思維)的相關資料指出:所謂創造,就是將已知的產物以全新的方式結合起來。
而分而治之的思想,正是通過問題拆解,轉爲已知,再綜合結果的方式,實現了創造。
如果蛋糕太大一口吃不下,那就先切開它!然後一快一快吃下它!
期待你遇到大規模問題不要驚慌失措,你可以先拆解他、再轉化它、最後綜合起來,幾乎任何問題都可以被解決。
4.1.3 抽象與實現
邏輯抽象是人類智能的體現,它是計算機所不具備的,面對一個複雜的問題,我們可以對其進行不同層次的抽象、建模,這些行爲的進行,可以在人的腦子中,也可以在紙面上,或者在其他工具上。
根據抽象得到的結果,人類再使用計算機這個得力助手去實現它,這樣就能真正地解決現實問題。
計算機領域的抽象與實現,可以是 [數據結構] 的抽象數據類型;可以是 [Verilog HDL] 的層次建模思想;可以是軟件工程的UML建模……
抽象與實現的思想,其實滲透到了人類生活的各個領域,期待你能夠以這樣的方式去重新審視這個世界。
4.2 人類的妥協
人類不會向計算機屈服,但是面對一些挑戰,也不得不做出適當的妥協讓步,這也是爲了更好的應用計算機高效率地解決現實問題。
4.2.1 分析計算機行爲快速搞定bug
當程序沒有按照你預期的結果執行,不要懊惱,不要悲傷,更不要想着:“爲什麼它沒有按照我想的去做?”
這樣的想法,只會讓你更加懊惱和沮喪,你應該想的是:是不是我哪裏沒有描述清楚,所以它沒有做好事情?
你應該做的是:按照程序執行的行爲,使用單步調試/斷點調試,逐一分析,直到找到問題根源。
計算機是個聽話的孩子,它只會按照你告訴它的去執行,因此,如果它出錯了,一定是你指揮失誤,你只需要分析它的每一步行爲,就能夠以最快的速度找到錯誤,解決bug。
這是計算機歷史上,導致計算機崩潰的一隻蟲子(bug),讓我們一起,按照程序的行爲,找到它,消滅它!
4.2.2 大規模項目的分工協作
隨着計算機的不斷髮展,大規模複雜問題開始出現,獨立的個體可以寫出一個小程序,但是面對大規模問題,人類就如同《焦油坑》裏的動物一樣,不斷掙扎,但是越掙扎,反而越痛苦。
直到軟件工程出現,人類開始學會分工協作,共同應對棘手的“焦油坑”,成立了“外科手術隊伍”,具備瞭解決大規模問題的能力。
推薦閱讀:《人月神話》
你將會更加直觀地感受到人類與計算機的鬥爭,比如焦油坑、外科手術隊伍……
5 期待你更好地在計算機世界遨遊
本文從一個最簡單的表達式出發,爲你描述了人類世界與計算機世界的宏大藍圖;給你講述了重要的計算機思維,並將其具象化表達;給你講解了重要的破解複雜問題的方法和適當妥協讓步的策略。
計算機是人類智慧的延伸,是人類得力的工具,是人類的 “外包大腦”,永遠記住,你不是程序員,不要當程序員,你是解決問題的人,你要利用人類特有的智能,這,纔是你與計算機的不同,你能做到計算機做不到的事情,你要充分利用計算機這個得力工具去解決問題,不要被其反噬控制。
期待此文,能夠爲你帶來全新的計算機世界觀,讓你更好地開啓計算機旅程。
聲明:
- 本文大部分圖片均爲自己製作,一些圖片是我購買的具備個人版權的圖片,還有極少數素材來源於網絡,侵刪。
- 本文中,部分的類比和比喻,伴有科幻主義色彩,非技術部分的內容可能並非嚴謹的科學事實,請勿惡意揣測,謝謝。
- 本文涉及的技術,爲了方便你理解,採用了簡化模型,並未展現完整的技術細節,技術細節你可以從我推薦的書籍中學到。