你必須理解的計算機核心概念
計算機學科中有很多概念, 例如編碼(原碼,補碼,反碼), 虛擬內存, 文件, IO, 編譯,鏈接,分組交換,關系, 事務,范式, Hash, 加密。。。等等,本文試圖講一下最重要的核心集合,從這個集合當中就可以變換出計算機編程的各種魔法。
1 馮·諾依曼結構計算機的原理
所有的計算機語言,不管是Java, Python, Go, C, C++, PHP...... , 無論你在TIOBE上是排行***還是排行第100, 無論看起來多么花哨,功能多么強大,用起來多么舒服, 最終都要變成基本的二進制指令,老老實實地在馮·諾依曼結構計算機上按規矩執行。
這里是根, 我們看到的、用到的都是這棵樹上的花和枝葉。
作為志向遠大的、有著強烈好奇心的年輕人, 難道你不想到根部來看一看?
作為最基本的要求, 必須要了解CPU和內存這倆哥們是怎么親密無間工作的: CPU從內存取出指令,進行譯碼和執行,執行時從內存中取出數據放到寄存器中, 進行計算, 然后把結果寫回到內存。如果是跳轉指令, CPU則取出跳轉目的地的指令繼續執行。
如此簡單的過程,竟然組成了多姿多彩的電腦世界: 你可以聽音樂,玩游戲、上網聊天、用Word來寫文檔..... 當然看起來微不足道的一個操作,進入到CPU和內存中都可能需要成千上萬條指令來完成。
這些基本的指令組成了順序、循環、分支等基本的程序結構,形成了更為強大的編程語言的基礎。
CPU和內存、硬盤等設備的速度不匹配,是馮·諾依曼結構計算機的一個核心問題,為了解決這個問題,科學家們絞盡腦汁,想盡了辦法, 又引出了一堆概念: 緩存,DMA, 同步,異步,阻塞....
2 進程和線程
這倆家伙的重要性不言而喻,因為你寫的所有的程序要么會成為一個獨立的進程去執行,要么是被一個進程中的線程收編,沒有例外 。
幾乎所有的編程語言都會涉及到對多進程或者多線程編程的支持, 特別是多線程的并發編程, 所以你必須得搞明白它的本質是什么。
進程是對一個運行中的程序的抽象,沒有這個概念,我們是無法實現一邊聽歌、一邊上網的愜意生活。
對于CPU來講, 它只是“渾渾噩噩”地從某個地方取指令,譯碼執行,但是它不會意識到在某一刻整個世界已經變了天, 它執行的程序已經發生了切換,另外一個程序(準確地講叫進程)已經成功地搶班奪權。
每個進程都有一個被操作系統老大維護的進程控制塊, 里邊保存了這個進程在運行時的重要信息,是進程能來回切換的重要保證。
而線程則寄居于進程之內 , 共享進程提供福利(代碼和數據)的同時, 還擁有自己的一畝三分地。
線程的出現,提升了系統的性能、吞吐量和響應性。 但是多進程/多線程編程也帶來了一系列問題: 同步,通信,鎖, 死鎖。。。
3 虛擬內存
有了物理內存, 為啥還有虛擬內存?
一個重要的原因就是給各位進程先生提供一個由虛擬地址組成的獨立王國, 給他們造成一種假象: 我最重要,我是獨占內存的!
每個人在自己的獨立王國里鬧騰,就不會互相打架, 治安也就有了保證。
但是在虛擬地址王國里做不了什么事情,指令必須在物理內存中才能被執行, 操作系統老大用盡渾身解數,把每個進程的虛擬地址映射到實際地址上去,表面上不動聲色,背后絕對驚心動魄,分段,分頁,頁表,還要動用CPU的TLB來加速。
程序并不是像你想象的那樣,一下子全部裝載到內存的, 而是慢慢地, 用到的時候才進行裝載。
進程一條普通指令的執行, 其實有一大家子在鞍前馬后地忙碌著, 而進程幾乎渾然不覺,真是太幸福了。
4 網絡的核心概念
上面所說的都局限于一臺計算機, 然而一張大網早已經把這些孤島聯系在一起。
這張大網就你我的周圍, 我們都變成了它的一個節點。
大網的設計非常有趣,沒有一個中心的節點,某幾個甚至某一片節點陣亡都沒有關系,大網繼續生存,提供服務。
作為碼農我們要理解的核心概念是: 分組交換, TCP/IP參考模型, socket , http(s)。
你也許沒有想到,你上網玩游戲,聽音樂,看這篇文章,其中的數據并不是一下子全發給你的, 而是被切分成適合網絡傳輸的小塊,給每個小塊編上號, 每個小塊都獨立地走相同甚至不同的網絡路徑, 到達你這里,重新排序,組合,然后才展示給你, 這就是分組交換。
使用分組交換可以充分的利用網絡帶寬: 在你不使用的間隙,別人也可以利用。
但是一個很明顯的問題就是分組數據丟失了怎么辦? 如何檢測, 怎么重發,如何緩存已經收到分組數據等一系列煩人的問題接踵而來。 這就是TCP要干的事情。
如果你能體會到TCP是在端系統實現的,中間節點一無所知,我想你就Get到了分組交換和分層的真諦。
TCP/IP參考模型定義了5層: 應用層,傳輸層,網絡層,鏈路層,物理層。你一定得理解所謂的分層只不過是把你的數據層層包裝而已,在傳輸的過程層中每到一個節點都會拆開某一層的包裝,查看一下數據, 然后再次包裝,轉發出去,直到終點。
也許你不愿意了解底層煩人的細節, 但是一定要理解socket和http(s) , 這哥倆最貼近我們碼農的日常生活,我們經常直接和他們對話,利用他們收發數據, 所以花點經歷好好學學吧。
5 Hash 和 RSA
如果說Https是網絡安全通信的一大基石, 那Hash和RSA 則是基石的基石。
為了保證消息在傳輸過程中的私密性, 完整性,不可偽造性,這哥倆可以說是功不可沒。
其實不僅僅是Https , 在各種軟硬件平臺上都能看到他們勤奮的身影, 例如SSO, SSH, JWT ..... 所以非常值得你投入精力去學習。
RSA最為美妙之處就是有一對兒鑰匙, 一個是私有的、保密的, 另外一個是公有的, 誰都可以知道, 這對于之前的對稱密鑰是個極大的顛覆, 誰能想到原先需要保密的密鑰竟然可以公開呢!
更有意思的是私鑰加密的數據只有相應的公鑰才能解開, 反之亦然,這確實是很漂亮的概念。
RSA的概念很簡單, 但是為了實現真正的安全消息傳輸,作為***步必須得有數據簽名做保證, 你需要理解如何對消息用Hash形成摘要,然后用私鑰簽名,又是如何驗證這個簽名的, 理解了這一點,很多東西都迎刃而解。
【本文為51CTO專欄作者“劉欣”的原創稿件,轉載請通過作者微信公眾號coderising獲取授權】