1. 程式人生 > >對找工作功不可沒——評《深入理解計算機系統》

對找工作功不可沒——評《深入理解計算機系統》

引子:

在我剛剛進入中科院計算所讀研的時候,同宿舍的師兄便向我推薦了一本《深入理解計算機系統》,這本書從一個程式設計師的視角詳細剖析了整個計算機系統,涵蓋了組成原理、組合語言、體系結構、作業系統、網路等計算機基礎知識。

由於時間所限,我並沒有立刻閱讀,而是將其列入了找工作前的複習書單。2010年8月,我用了一個月的時間讀完了這本書的原版《Computer System:A programmer’s perspective》。後來的事實證明,讀完這本書對我找工作的歷程幫助很大。

正文:
在閱讀的過程中,我對該書的各個章節做了一些標註,以備將來重新翻閱的時候參考。這些標註主要從兩個角度進行,一是對我找工作應試(包括筆試和麵試)有沒有用,二是對我自身的技術提高有沒有用,所以分為應試和修煉兩個指標,參照流行的打分標準將其分為從★到★★★★★五個等級。
在找工作順利結束之後,我又回顧了一下之前的標註,結合自己的筆試、面試經歷,重新修訂了一下。其中應試指標的評分主要是以我的求職目標(網際網路行業偏演算法的軟體工程師)為參照,和其他職位的要求會有些出入。

第一章 計算機系統漫遊 A Tour of Computer System
本章對計算機系統做了一個總體的介紹,用簡單明瞭的語言概括了一些後續章節將要重點展開的概念。
應試 ★★:在筆試中可能會碰到一些整體上的概念題。
修煉 ★:屬於計算機最基本的概念。

第二章 資訊的表示和處理 Representing and Manipulating Information
本章介紹了資訊在計算機中的表示形式,重點講述整數和浮點數的表示形式。
應試 ★:應試中很少會考到。
修煉 ★★★:有很多人可能寫了多年的程式碼都不知道浮點數是如何用那4(8)個位元組儲存的,不知道其實表示式(x-y<0)並不能替代(x<y)

第三章 程式的機器級表示 Machine-Level Representation of Program
本章其實就是組合語言課程的複習。
應試:重要程度依賴於求職目標,如果是和我一樣偏演算法的工程師,組合語言是不會考到的。
修煉 ★★★★★:理解組合語言和暫存器結構是後面很多內容的基礎。

第四章 處理器體系結構 Processor Architecture
本章其實就是計算機體系結構課程的內容。主要介紹的內容有處理器結構,各種邏輯閘、功能單元,指令集;指令的執行,指令執行的流水線等。
應試 ★: 對於軟體相關職位來說,很少會考到這麼底層的東西的。
修煉 ★★★: 對於從事軟體層面的技術人員來說,不用深入,但是也應該理解,知道是怎麼回事。

第五章 優化程式效能 Optimizing Program Performance
本章講述如何優化程式的執行效率,包括程式碼的優化,編譯器的優化,以及CPU級別的優化。
5.1-5.6節 主要介紹了幾種能有效提高程式碼效能的方法。
應試 ★★★★: 經常會有一些讓你尋找程式瑕疵的問題,如果你能看出程式碼在哪些細節上可以優化,必定能加分不少。
修煉 ★★★★★: 你當然需要知道編譯器在什麼層面上能自動幫你優化程式碼,在編譯器無法優化時你自己又如何在小細節上進行優化。
5.7節以後 主要介紹了CPU級別的優化,微指令的概念,功能單元上微指令的並行,程式分支的預測等。
應試 ★: 對於軟體相關職位來說,基本不會考這些東西的。
修煉 ★★★: 不用深入,但是應該知道並能夠理解。

第六章 儲存器層次結構 The Memory Hierarchy
本章詳細介紹了計算機系統中的儲存結構。

6.1 介紹了不同種類的儲存裝置以及對應的存取資料的方式。
應試和修煉 ★: 很少會考到,瞭解一下即可。
6.2-6.7 介紹了儲存裝置的組織形式,著重介紹了Cache及其工作方式,程式是如何和cache打交道的,不同的迴圈巢狀順序、遍歷方向等對cache命中的影響。
應試 ★★★★: 在面試中,經常會考到跟cache相關的題目;修改迴圈巢狀順序以提高cache命中率也是一些程式改錯題的高階玩法。
修煉 ★★★★: 儲存結構和cache是計算機中很基礎也很重要的概念。

第七章 連結 Linking
顧名思義,本章詳細講解了程式的連結過程,主要分為靜態連結和動態連結,以及連結過程中使用到的技術如符號解析、重定位等。
應試 ★★:知道一些基本概念即可。
修煉 ★★★★★:一個軟體工程師應該懂得自己寫出來的程式是怎麼成為一個可執行檔案的,有的時候,你很可能會被一個連結錯誤折磨好幾天。

第八章 異常控制流 Exceptional Control Flow
顧名思義,本章主要講解異常控制,不過這裡的“異常”並不是Java或者C++裡狹義的異常,而是一個廣義的“Exceptions”的概念,包括中斷(Interrupt),陷阱(Trap),錯誤(Falut),中止(Abort)等。本章同時引入了程序的概念,介紹了程序級別的 Exception:訊號(signal)以及作業系統處理這個異常的手段–上下文切換(context switch)。
應試 ★★: 主要掌握程序的概念即可。
修煉 ★★★: 知道異常控制流是怎麼回事,使用者程式和系統互動(如系統呼叫)的原理和方式即可,不用太深入。

第九章 虛擬儲存器 Virtual Memory
非常重要的一章,虛擬儲存機制是計算機實現多工的一項重要技術。計算機正是通過時間片技術使得每個程序在執行時彷彿獨佔CPU,進而又通過虛擬儲存機制使得每一個程序在執行時彷彿獨佔記憶體。
10.1介紹了虛擬地址和實體地址,CPU進行定址操作產生的是虛擬地址,通過儲存管理單元(memory management unit)轉換為實際的實體記憶體地址。
10.3~10.5講述了虛擬儲存機制的優點:使得記憶體可以作為硬碟的cache;能夠更方便的管理記憶體;能更好的提供記憶體保護機制。
10.6 介紹了虛擬地址如何轉換為實體地址。
10.7 很精彩的一節,通過Intel Pentium和Linux的例項講述了整個儲存管理機制。記得以前上作業系統課的時候,各種理論、機制學了一大堆,但就是不知道實際的作業系統到底用的哪套方法,而本節內容正是通過例項讓你對剛學的理論機制有一個直觀的瞭解。
10.8~10.10 講述了儲存對映(Memory Mapping)、動態記憶體分配和垃圾回收機制。
10.11 很實用的一節,列舉了一些C程式設計中容易犯的記憶體引用錯誤。
應試 ★★★★★: 本章內容是作業系統課程的重點內容,如果考作業系統,幾乎肯定會考到;10.11節的知識也能幫你應對一些程式挑錯題。
修煉 ★★★★★: 作業系統中重要的基礎內容,即使你只使用Java這樣的高階程式語言,至少也應該弄懂垃圾回收機制吧。

第十章 系統級I/O System-Level I/O
介紹類Unix系統下的I/O讀寫,主要介紹系統層面的I/O介面。由於我們日常程式設計所用的I/O介面都是各種高階語言提供的經過封裝的標準介面,故而如果不進行底層開發的話這部分知識不是必須的,我便跳過沒讀。

第十一章 網路程式設計 Network Progranmming
本章簡單介紹了網路模型,TCP/IP協議,類Unix系統的socket介面等。
應試和修煉 ★★: 因為篇幅限制,本章只做了簡單講解,要掌握網路程式設計知識還需要參考專門的網路技術書籍。

第十二章 併發程式設計 Concurrent Programming
本章簡單介紹了併發程式設計的內容,主要包括:
1.程序級別的併發,各子程序擁有不同的虛擬地址空間,需要IPC(InterProcess Communication)機制共享資料,切換開銷大。
2.I/O複用,事件驅動,單程序執行,共享虛擬地址空間,併發效果不理想。
3.執行緒,介於上述兩種中間,各子執行緒共享程序的虛擬地址空間,切換開銷較小。
另外介紹了併發程式設計中訪問共享變數的訊號量機制,並給出了4類容易引起執行緒不安全的函式。
應試 ★★: 除應聘相關職位外,併發程式設計考的比較少,不過需要清楚鎖機制和訊號量機制等。
修煉 ★★★: 多執行緒程式在現今的開發中還是很常見的,但是本章介紹的比較簡單,需要參考另外專門的書籍。

總的來說,我覺得這本書很適合在找工作之前讀一讀,因為從網上流傳的各種筆試和麵試題中,我們就能看出各大IT公司在招聘工程師的時候是很看重基礎知識的,而對於像我這樣上了三年研究

生的同學來說,很多知識由於長時間沒用早就忘了,所以需再要再複習一下。但是我們可能沒有時間按照課程一門一門地去複習,即使一門一門去看了,也不一定能把知識都聯絡起來,而這本書正好提供了這樣一個視角,從程式設計師的角度把計算機專業最重要的基礎知識都串了起來,形成了一個完整的計算機系統的概念。