來自:碼農翻身(微訊號:coderising)
很多人工作後痛感計算機基礎知識的缺乏, 那計算機基礎知識都有哪些呢?
我覺得首先計算機專業的那六大件:組成原理,作業系統,資料庫,編譯原理,計算機網路,資料結構(這個說太多遍了,這次不再講了), 其次還得加上分散式的基礎知識, 因為現在的系統都變成分散式的了。
如果你是做應用層開發的,那幾門課程中的有些內容和日常工作關聯度不大,我挑那些最重要的來說一說,也算是一個最小集合吧!
如果你不是做作業系統/驅動程式的,直接和硬體打交道的機會很少,因為作業系統已經把他們遮蔽掉了,提供了抽象的API給我們使用。
但是還必須理解馮諾依曼體系的結構,CPU和記憶體,硬碟,各種外設之間的關係,暫存器、快取等知識。
CPU有哪些指令,如何執行這些指令,如果實現陣列,結構體,函式呼叫,這就涉及到彙編的知識。
像原碼,反碼,補碼,定點數、浮點數的表示和運算也是程式設計中必備的知識,幾乎每種語言都要涉及。
現在很多語言都是在虛擬機器上執行的,你只要是瞭解了計算機的組成原理,再去看哪些虛擬機器,就會發現概念都是相通的。
另外CPU中的快取,快取一致性協議,DMA的非同步思想都會在應用層中有所體現。
如果能找一本書,盡可能多的囊括這些知識的話,我覺得還是神書《深入理解計算機系統》的前4章, 我之前還對它寫過一個書評,在這裡:為什麼說《深入理解計算機系統》是一本神書?
《編碼》是一個更加科普性,但是也更加有趣的講組成原理的書。
作業系統是比較枯燥的, 站在應用層的角度,我認為重點是掌握作業系統對外提供的抽象,包括行程、執行緒,檔案,虛擬記憶體,以及行程間的通訊問題。
幾乎所有的程式語言都會涉及到對多行程或者多執行緒程式設計的支援, 特別是多執行緒的併發程式設計,所以必須得搞明白他們的本質是什麼,執行緒都有哪些實現方式(對以後學習各種語言和併發模型有極大好處)。得真正地體會到“行程是資源分配的最小單位,執行緒是排程的最小單位。” 這句話的含義。
幾乎所有的程式語言都會涉及到鎖和死鎖,最好在最底層理解鎖是怎麼實現的。
需要理解虛擬記憶體和物理記憶體直接的關係,分段和分頁,檔案系統的基本原理。
對於行程的排程,頁面分配/置換演演算法,磁碟的排程演演算法,I/O系統,我認為優先順序比較低。
我認為必須要理解的是這些:
什麼分組交換
TCP可靠性傳輸原理,TCP/IP的協議細節, 三次握手,四次揮手,TCP狀態轉換。
幾個重要的協議DHCP,UDP, ARP, DNS。
能夠說出一個客戶端如何在接入網路以後,透過這些協議,跨域網路和伺服器通訊的。
和應用層結合非常緊密的Socket知識和網路安全(對稱加密,非對稱加密,Hash, 數字簽名,以及集大成者Https)
至於網路層的路由選擇演演算法,鏈路層的各種協議,我認為優先順序比較低。
還有一個重要的知識點,一般的網路書都沒提,就是I/O多路復用,涉及到同步/非同步,阻塞/非阻塞,select/epoll ,這個是很多軟體的基礎,在《Unix網路程式設計》,《深入理解計算機系統》中有講述。
以上這些知識,在你學習Redis ,Ngnix, Tomcat, LVS等軟體時將有極大的幫助。
這個和日常工作結合極其緊密,不用我再多說,包括最基本的SQL,各種正規化,事務及其隔離級別,事務的實現方式,索引及其實現方式,B+樹等等。
你這一輩子也許都不會去寫一個編譯器,但是很有可能會利用現成的工具去生成/操作一個抽象語法樹(AST),甚至可以會寫一個DSL(領域特定語言)。所以你得理解詞法分析、語法分析、語意分析,中間程式碼生成,程式碼最佳化這個基本編譯的過程。
學習了編譯與原理,會對語言的一些設計有更深的理解,比如LISP。
由於現在的系統慢慢地變成了分散式, 所以又擴展出了很多相關基礎知識需要學習:
資料複製與一致性:
CAP理論, BASE原則,冪等性, 2PC, TCC
Paxos , Raft , Gossip
資料分片和路由:
Hash分片:Hash取模(實際中非常常見的演演算法), 虛擬桶(Redis使用),一致性Hash(memcached使用)
範圍分片
最後想說的是,不能帶著特別功利的目的去學習這些基礎,不能想著立刻、馬上就應用到實戰中,從中獲益。更重要的理解掌握它們背後的思想,有一天你會發現:奧,這個問題我在哪裡見過,可以用類似的辦法來解決啊!
朋友會在“發現-看一看”看到你“在看”的內容