計算機上的全部程序和數據都是由一個一個位(即比特,bit)構成。而每一個比特只有0與1兩種狀態,通常8個位被組成一組,稱爲字節(即byte)。
系統中的全部信息——包括磁盤文件、內存中的程序、內存中存放的用戶數據以及網絡上傳送的數據,都是由一串比特表示的,而區分這些數據對象的惟一方法是咱們讀到這些數據對象的上下文。
例如,在不一樣上下文中,一個一樣的字節序列可能表示爲一個整數、浮點數、字符串或者機器指令。
做爲一名程序員,咱們不該知足於表面的數據,而應該深刻底層,真正瞭解數據在機器上的表示方法 。例如:整數和浮點數在實際上在機器上的表達方式與咱們的經驗實際上是不一樣的,它們是對真值的有限近似值。有時候會有意想不到的行爲表現。html
一個程序能從能夠被人理解的高級程序設計語言(例如C語言)到機器語言,是因爲編譯系統的做用。
以gcc爲例,編譯系統(compilation system)由預處理器(cpp)、編譯器(ccl)、彙編器(as)和連接器(id)構成。程序員
預處理器根據以字符#開頭的命令,修改原始的C程序,把預處理指令通過處理插入程序文本中,獲得的另外一個C程序以.i做爲後綴。編程
編譯器將C程序文本文件翻譯成爲彙編語言程序文本文件,以.s做爲後綴。
彙編語言是很是有用的,由於它爲不一樣高級語言的不一樣編譯器提供了通用的輸出語言。(例如:C編譯器和Fortran編譯器殘剩的輸出文件都是同樣的彙編語言)緩存
接下來,彙編器將.s翻譯成爲機器語言指令,把這些指令打包成一種叫作可重定位目標程序的格式,並將結果保存在目標文件.o格式的文件中。
.o格式的文件爲二進制文件。安全
若是程序使用了庫函數,例如printf,那麼連接器將把已經處理好的printf.o合併到現有文件中。
最終的到了一個可執行目標文件。網絡
對於新手來講,不瞭解編譯系統並不會影響到咱們的編程,可是,瞭解編譯系統對咱們在實際編程是有很大幫助的,具體以下。數據結構
1.瞭解程序的底層表示,可以在必定方面幫助咱們選擇更好的編程方法。併發
2.理解連接時發生的錯誤,編寫大型程序時容易出現沒法解析的指令,瞭解編譯系統能進一步瞭解有關全局變量和局部變量。函數
3.避免安全漏洞,學習安全編程的第一步就是理解數據和控制信息存儲在程序棧上的方式會引發的後果。性能
貫穿整個系統的是一組電子管道,稱做總線,他攜帶的信息字節並負責在各個部件傳遞。一般總線傳送定長的字節塊。
I/O設備即輸入輸出設備是系統與外部世界的通道。常見的輸入設備爲鼠標、鍵盤,輸出設備用顯示器、打印機、硬盤等。每一個I/O設備都經過一個控制器或適配器與I/O總線相連。
主存是一個臨時存儲設備,在處理器執行程序時,用來存放程序和程序處理的數據。從物理上來講由一組動態隨機存儲器DRAM芯片組成。
簡稱CPU,是解釋和執行存儲在存儲在主存中指令的引擎。處理器的核心爲PC(指令寄存器),它始終指向某一條指令的地址。ALU(算術邏輯單元)用來執行一些算術與邏輯運算。
(注:通常的書都把外存(磁盤,硬盤)單獨拿出來講,本書直接把其歸爲I/O設備中的輸出設備,也有必定道理)
根據機械原理,較大的存儲設備要比較小的存儲設備運行得慢,而快速設備的造價遠比低速設備要高,因此主存比寄存器存儲器的存取速度要慢不少。
爲了解決這一問題,系統設計者在主存中放入了高速緩存存儲器,做爲信息的臨時集結區域,存放近期可能會須要的信息。
高速緩存分三級,從L1到L3,存取速度遞減,存儲大小遞增。
大多數內存操做都能在快速的高速緩存中完成,這大大加快了系統的速度。
而做爲一個程序員,若是能意識到高速緩存的做用,可以利用高速緩存將程序的性能提升一個數量級。
根據上面提到的高速緩存思想,咱們意識到不一樣的存儲器在性能上有所差別,通常在同一個計算機中,計算機的存儲設備的層次結構以下圖所示。
存儲器層次結構的主要思想是上一層的存儲器做爲第一層存儲器的高速緩存。好比說L1是L2的高速緩存。
除了一些能提升程序性能的細節,咱們在編寫程序時並不會接觸到硬件,應用程序與硬件之間的軟件咱們叫作操做系統。
操做系統有兩個基本功能:
1.防止硬件被失控的應用程序濫用;
2.嚮應用程序提供簡單一致的機制來控制複雜而又一般大不相同的低級硬件設備。
而上面所提到的簡單一致的機制即爲操做系統對硬件的抽象。
分別爲:
文件——操做系統對I/O設備的抽象表示(應該主要是指外存);
虛擬內存——操做系統對主存和磁盤I/O設備的抽象表示;
進程——操做系統對處理器、主存和I/O設備的抽象表示;
應用程序在現代操做系統中運行時,操做系統會提供一種假象,就好像系統上只有這個程序在運行。程序看上去是獨佔地使用處理器,主存和I/O設備。
進程是操做系統對一個正在運行的抽象打的一種抽象。在一個系統上能夠同時運行多個進程,而每一個進程都好像在獨佔地使用硬件。而併發運行,則是說一個進程的指令和另外一個進程的指令是交錯執行的。CPU在多個進程中的交錯執行咱們稱爲上下文切換。
實現進程這個抽象概念須要低級硬件和操做系統軟件之間的緊密合做,進程是計算機科學中最重要和最成功的概念之一。
在現代操做系統中,一個進程實際上能夠由多個稱爲線程的執行單元組成,每一個線程都運行在進程的上下文中,並共享一樣的代碼和全局數據。
虛擬內存是一個抽象概念,它爲每一個進程提供了一個假象,每一個進程都在獨佔地使用主存。每一個進程看到的內存都是一致的,稱爲虛擬內存空間。以下圖所示(圖中地址是從下往上增大的)
下面是各個分區的簡單描述:
對於全部進程來講,代碼是從同一固定地址開始的,緊接着的是和全局變量相對應的數據位置。
代碼和數據區後是運行時堆,當調用malloc,free(C),new,delete(C++)時,堆能夠動態地擴展和收縮。
大約在地址空間中間部分是一塊用來存放像C標準庫和數學庫這樣的共享庫的代碼和數據區域。
位於用戶虛擬地址空間頂部的是用戶棧,編譯器用它來實現函數調用。和堆同樣,用戶棧在程序執行期間能夠動態地擴展和收縮
地址空間頂部的區域是爲內核保留的。不容許應用程序讀寫這個區域的內容或者直接調用內核代碼定義的函數。
虛擬內存的運做是很是複雜的。基本思想是吧一個進程虛擬內存的內容存儲在磁盤上,而後主存做爲磁盤的高速緩存。
文件就是字節序列,僅此而已。每一個I/O設備,包括磁盤、鍵盤、顯示器,甚至網絡,均可以當作是文件。系統中的全部輸入輸出都是經過使用一小組稱爲Unix I/O的系統函數調用讀寫文件來實現的。
文件這個簡單而精緻的概念是很是強大的,由於它想應用程序提供了一個統一的視圖,來看待系統中含有的全部各式各樣的I/O設備。例如處理磁盤文件內容時,程序員無須瞭解具體的磁盤技術。
(這裏書中簡單的提到了網絡,但只是大體說了一下網絡傳輸文件的方式和方法,沒什麼實質的乾貨,遂略過,在後面具體說的時候再仔細研究)
當咱們對系統的某個部分加速時,其對系統總體性能的影響取決於該部分的重要性和加速程度。若系統執行某應用程序須要時間爲Told。假設系統某部分所需執行時間與改時間的比例爲α,而該部分性能提高比例爲k。即該部分初始所需時間爲αTold,如今所需時間爲(αTold)/k。所以,總的執行時間爲:
看不懂,暫略。
抽象是計算機科學中最爲重要的概念之一。例如爲一組函數規定一個簡單的應用程序接口(API)就是一個很好的編程習慣,調用API的程序員無須瞭解函數是怎麼實現的,只須要用這樣函數來完成本身的程序便可。
(關於抽象,有時間我會具體寫一篇博客來梳理一遍計算機從硬件到軟件的一層一層抽象)。
這一章主要把本書的主要內容概述了一遍,同時也是對整個計算機系統的概述,由於我在讀這本書時只有C語言和數據結構的基礎,因此初次讀到處碰壁,讀哪哪都不懂,感受本身是否是讀這本書讀的太早了,後來在知乎上看到一位網友說這本書不是讓人一遍讀完的,這本書是須要你在碰壁時放下書去學習,回過頭來發現能看懂時繼續讀,直到把計算機專業的全部課程學完,這本書也就讀完了。才感受恍然大悟。 這裏要向和我同樣的初學者推薦一個視頻課程: [Crash Course:Computer Science]open.163.com/movie/2018/5/M/S/MDGEPAQ4K_MDGET74MS.html 這個系列視頻並無教咱們編程,而是從計算機的歷史入手,把計算機全部的基礎專業課概述了一遍,甚至還有幾乎全部計算機科學的研究方向的概述:人工智能,計算機圖形學,計算機視覺等等。。十分詳盡,配的動畫也頗有趣,是讀這本書的一個好向導。 借一位知乎網友對這本書的描述:「這是一份地圖,不是一個世界」。但願能在這份地圖的指引下,把計算機科學的世界完整地走一遍。