最近收到不少讀者留言,關於怎麼學「作業系統」和「計算機網路」的留言,小林寫這一塊的內容也有半年多了,啃非常多的書,也看了很多視訊,有好的有差的,今天就掏心掏肺地分享給大家。
作業系統和計算機網路有多重要呢?如果沒有作業系統,我們的手機和電腦可以說是廢鐵了,自然它們都沒有使用價值了,另外如果沒有計算機網路,我們的手機和電腦就是一座「孤島」了,孤島的世界很單調,也沒有什麼色彩,也正是因為計算機網路,才創造出這麼豐富多彩的網際網路世界。
身為程式設計師的我們,那更應該深刻理解和掌握它們,雖然我們日常 CURD
的工作中,即使不熟悉它們,也不妨礙我們寫程式碼,但是當出現問題時,沒有這些基礎知識,你是無厘頭的,根本沒有思路下手,這時候和別人差距就顯現出來了,可以說是程式設計師之間的分水嶺。
事實上,我們工作中會有大量的時間都是在排查和解決問題,編碼的時間其實比較少,如果計算機基礎學的很紮實,雖然不敢保證我們能 100% 解決,但是至少遇到問題時,我們有一個排查的方向,或者直接就定位到問題所在,然後再一步一步嘗試解決,解決了問題,自然就體現了我們自身的實力和價值,職場也會越走越遠。
我自己工作中就深刻體會到了它們多重要性,我最近專案就遇到 TCP 比較底層的問題,我們的一個 Web 服務執行久之後,就無法與使用者端正常建立連線了,使用 tcpdump 抓包發現 TCP 三次握手過程中,伺服器端把使用者端握手過程中最後 1 個 ack 給丟掉了。
剛開始覺得非常的莫名奇妙,後面想起自己寫過一篇 TCP 半連線和全連線佇列的文章,就往這個方向排查問題,於是執行 netstat -s 命令檢視 TCP error 相關的資訊,發現 TCP 全連線佇列溢位了,接著再通過 ss -lnt 命令進一步確認,當前 TCP 全連線佇列確實超過了 TCP 全連線佇列最大值,這個問題就很快定位出來了。
另外,當 TCP 全連線佇列溢位後,由於 tcp_abort_on_overflow
核心引數預設為 0,所以伺服器端會丟掉使用者端發過來的 ack,如果你把該引數設定為 1,那現象將變成,伺服器端會給使用者端傳送 RST 報文,廢棄掉連線。
那要擴大全連線佇列也不難,TCP 全連線佇列最大值取決於 somaxconn 和 backlog 之間的最小值,也就是 min(somaxconn, backlog)
,其中 somaxconn 是核心引數,而 backlog 是我們程式 listen 方法中指定的引數。
上面這個小例子,很明顯是無法通過看應用層的程式碼來解決的,必須瞭解 TCP 的機制,才能找到解決之道。
鋪墊了那麼多,接下里進入正題。
計算機網路相比作業系統好學非常多,因為計算機網路不抽象,你要想知道網路中的細節,你都可以通過抓包來分析,而且不管是手機、個人電腦和伺服器,它們所使用的計算網路協定是一致的。
也就是說,計算機網路不會因為裝置的不同而不同,大家都遵循這一套「規則」來相互通訊,這套規則就是 TCP/IP 網路模型。
TCP/IP 網路參考模型共有 4
層,其中需要我們熟練掌握的是應用層、傳輸層和網路層,至於網路介面層(資料鏈路層和物理層)我們只需要做簡單的瞭解就可以了。
對於應用層,當然重點要熟悉最常見的 HTTP 和 HTTPS,傳輸層 TCP 和 UDP 都要熟悉,網路層要熟悉 IPv4,IPv6 可以做簡單點了解。
我覺得學習一個東西,就從我們常見的事情開始著手。
比如, ping 命令可以說在我們判斷網路環境的時候,最常使用的了,你可以先把你電腦 ping 你舍友或同事的電腦的過程中發生的事情都搞明白,這樣就基本知道一個封包是怎麼轉發的了,於是你就知道了網路層、資料鏈路層和物理層之間是如何工作,如何相互配合的了。
搞明白了 ping 過程,我相信你學起 HTTP 請求過程的時候,會很快就能掌握了,因為網路層以下的工作方式,你在學習 ping 的時候就已經明白了,這時就只需要認真掌握傳輸層中的 TCP 和應用層中的 HTTP 協定,就能搞明白存取網頁的整個過程了,這也是面試常見的題目了,畢竟它能考察你網路知識的全面性。
重中之重的知識就是 TCP 了,TCP 不管是建立連線、斷開連線的過程,還是資料傳輸的過程,都不能放過,針對資料可靠傳輸的特性,又可以拆解為超時重新、流量控制、滑動視窗、擁塞控制等等知識點,學完這些只能算對 TCP 有個「感性」的認識,另外我們還得知道 Linux 提供的 TCP 核心的引數的作用,這樣才能從容地應對工作中遇到的問題。
接下來,推薦我看過並覺得不錯的計算機網路相關的書籍和視訊。
此係列針對沒有任何計算機基礎的朋友,如果已經對計算機輕車熟路的大佬,也不要忽略,不妨看看我推薦的正確嗎。
如果你要入門 HTTP,首先最好書籍就是《圖解 HTTP》了,作者真的做到完完全全的「圖解」,小林的圖解功夫還是從這裡偷學到不少,書籍不厚,相信優秀的你,幾天就可以看完了。
如果要入門 TCP/IP 網路模型,我推薦的是《圖解 TCP/IP》,這本書也是以大量的圖文來介紹了 TCP/IP 網路模式的每一層,但是這個書籍的順序不是從「應用層 —> 物理層」,而是從「物理層 -> 應用層」順序開始講的,這一點我覺得不太好,這樣一上來就把最枯燥的部分講了,很容易就被勸退了,所以我建議先跳過前面幾個章節,先看網路層和傳輸層的章節,然後再回頭看前面的這幾個章節。
另外,你想了解網路是怎麼傳輸,那我推薦《網路是怎樣連線的》,這本書相對比較全面的把存取一個網頁的發生的過程講解了一遍,其中關於電信等運營商是怎麼傳輸的,這部分你可以跳過,當然你感興趣也可以看,只是我覺得沒必要看。
如果你覺得書籍過於枯燥,你可以結合 B 站《計算機網路微課堂》視訊一起學習,這個視訊是湖南科技大學老師製作的,PPT 的動圖是我見過做的最用心的了,一看就懂的佳作。
B 站視訊地址:https://www.bilibili.com/video/BV1c4411d7jb?p=1
看完入門系列,相信你對計算機網路已經有個大體的認識了,接下來我們也不能放慢腳步,快馬加鞭,藉此機會繼續深入學習,因為隱藏在背後的細節還是很多的。
對於 TCP/IP 網路模型深入學習的話,推薦《計算機網路 - 自頂向下方法》,這本書是從我們最熟悉 HTTP 開始說起,一層一層的說到最後物理層的,有種挖地洞的感覺,這樣的內容編排順序相對是比較合理的。
但如果要深入 TCP,前面的這些書還遠遠不夠,賦有計算機網路聖經的之說的《TCP/IP 詳解 卷一:協定》這本書,是進一步深入學習的好資料,這本書的作者用各種實驗的方式來細說各種協定,但不得不說,這本書真的很枯燥,當時我也啃的很難受,但是它品質是真的很高,這本書我只看了 TCP 部分,其他部分你可以選擇性看,但是你一定要過幾遍這本書的 TCP 部分,涵蓋的內容非常全且細。
要說我看過最好的 TCP 資料,那必定是《The TCP/IP GUIDE》這本書了,目前只有英文版本的,而且有個專門的網址可以白嫖看這本書的內容,圖片都是彩色,看起來很舒服很鮮明,小林之前寫的 TCP 文章不少案例和圖片都是參考這裡的,這本書精華部分就是把 TCP 滑動視窗和流量控制說的超級明白,很可惜擁塞控制部分說的不多。
白嫖站點:http://www.tcpipguide.com/free/t_TCPSlidingWindowAcknowledgmentSystemForDataTranspo-6.htm
當然,計算機網路最牛逼的資料,那必定 RFC 檔案,它可以稱為計算機網路世界的「法規」,也是最新、最權威和最正確的地方了,困惑大家的 TCP 為什麼三次握手和四次揮手,其實在 RFC 檔案幾句話就說明白了。
TCP 協定的 RFC 檔案:https://datatracker.ietf.org/doc/rfc1644/
在學習書籍資料的時候,不管是 TCP、UDP、ICMP、DNS、HTTP、HTTPS 等協定,最好都可以親手嘗試抓資料包,接著可以用 Wireshark 工具看每一個資料包文的資訊,這樣你會覺得計算機網路沒有想象中那麼抽象了,因為它們被你「抓」出來了,並毫無保留地顯現在你面前了,於是你就可以肆無忌憚地「扒開」它們,看清它們每一個頭資訊。
那在這裡,我也給你推薦 2 本關於 Wireshark 網路分析的書,這兩本書都是同一個作者,書中的案例都是源於作者工作中的實際的案例,作者的文筆相當有趣,看起來堪比小說一樣爽,相信你不用一個星期 2 本都能看完了。
作業系統真的可以說是 Super Man
,它為了我們做了非常厲害的事情,以至於我們根本察覺不到,只有通過學習它,我們才能深刻體會到它的精妙之處,甚至會被電腦科學家設計思想所震撼,有些思想實際上也是可以應用於我們工作開發中。
作業系統比較重要的四大模組,分別是記憶體管理、程序管理、檔案系統管理、輸入輸出裝置管理。這是我學習作業系統的順序,也是我推薦給大家的學習順序,因為記憶體管理不僅是最重要、最難的模組,也是和其他模組關聯性最大的模組,先把它搞定,後續的模組學起來我認為會相對輕鬆一些。
學習的過程中,你可能會遇到很多「虛擬」的概念,比如虛擬記憶體、虛擬檔案系統,實際上它們的本質上都是一樣的,都是向下遮蔽差異,向上提供統一的東西,以方便我們程式設計師使用。
還有,你也遇到各種各樣的排程演演算法,在這裡你可以看到資料結構與演演算法的魅力,重要的是我們要理解為什麼要提出那麼多排程演演算法,你當然可以說是為了更快更有效率,但是因什麼問題而因此引入新演演算法的這個過程,更是我們重點學習的地方。
你也會開始明白程序與執行緒最大的區別在於上下文切換過程中,執行緒不用切換虛擬記憶體,因為同一個程序內的執行緒都是共用虛擬記憶體空間的,執行緒就單這一點不用切換,就相比程序上下文切換的效能開銷減少了很多。由於虛擬記憶體與實體記憶體的對映關係需要查詢頁表,頁表的查詢是很慢的過程,因此會把常用的地址對映關係快取在 TLB 裡的,這樣便可以提高頁表的查詢速度,如果發生了程序切換,那 TLB 快取的地址對映關係就會失效,快取失效就意味著命中率降低,於是虛擬地址轉為實體地址這一過程就會很慢。
你也開始不會傻傻的認為 read 或 write 之後資料就直接寫到硬碟了,更不會覺得多次操作 read 或 write 方法效能會很低,因為你發現作業系統會有個「磁碟高速緩衝區」,它已經幫我們做了快取的工作,它會預讀資料、快取最近存取的資料,以及使用 I/O 排程演演算法來合併和排隊磁碟排程 I/O,這些都是為了減少作業系統對磁碟的存取頻率。
……
還有太多太多了,我在這裡就不贅述了,剩下的就交給你們在學習作業系統的途中去探索和發現了。
還有一點需要注意,學作業系統的時候,不要誤以為它是在說 Linux 作業系統,這也是我初學的時候犯的一個錯誤,作業系統是集合大多數作業系統實現的思想,跟實際具體實現的 Linux 作業系統多少都會有點差別,如果要想 Linux 作業系統的具體實現方式,可以選擇看 Linux 核心相關的資料,但是在這之前你先掌握了作業系統的基本知識,這樣學起來才能事半功倍。
對於沒學過作業系統的小白,我建議學的時候,不要直接悶頭看書。相信我,你不用幾分鐘就會打退堂鼓,然後就把厚厚的書拿去墊顯示器了,從此再無後續,畢竟直接看書太特喵的枯燥了,當然不如用來墊顯示器玩遊戲來著香。
B 站關於作業系統課程資源很多,我在裡面也看了不同老師講的課程,覺得比較好的入門級課程是《作業系統 - 清華大學》,該課程由清華大學老師向勇和陳渝授課,雖然我們上不了清華大學,但是至少我們可以在網上選擇聽清華大學的課嘛。課程授課的順序,就如我前面推薦的學習順序:「記憶體管理 -> 程序管理 -> 檔案系統管理 -> 輸入輸出裝置管理」。
B 站清華大學作業系統視訊地址:https://www.bilibili.com/video/BV1js411b7vg?from=search&seid=2361361014547524697
該清華大學的視訊教學搭配的書應該是《現代作業系統》,你可以視訊和書籍兩者結合一起學,比如看完視訊的記憶體管理,然後就看書上對應的章節,這樣相比直接啃書相對會比較好。
清華大學的作業系統視訊課講的比較精煉,涉及到的內容沒有那麼細,《作業系統 - 哈工大》李治軍老師授課的視訊課程相對就會比較細節,老師會用 Linux 核心程式碼的角度帶你進一步理解作業系統,也會用生活小例子幫助你理解。
B 站哈工大作業系統視訊地址:https://www.bilibili.com/video/BV1d4411v7u7?from=search&seid=2361361014547524697
《現代作業系統》這本書我感覺缺少比較多細節,說的還是比較籠統,而且書也好無聊。
推薦一個說的更細的作業系統書 —— 《作業系統導論》,這本書不僅告訴你 What,還會告訴你 How,書的內容都是循序漸進,層層遞進的,閱讀起來還是覺得挺有意思的,這本書的記憶體管理和並行這兩個部分說的很棒,這本書的中文版本我也沒找到資源,不過微信讀書可以免費看這本書。
當然,少不了這本被稱為神書的《深入理解計算機系統》,豆瓣評分高達 9.8
分,這本書嚴格來說不算作業系統書,它是以程式設計師視角理解計算機系統,不只是涉及到作業系統,還涉及到了計算機組成、C 語言、組合語言等知識,是一本綜合性比較強的書。
它告訴我們計算機是如何設計和工作的,作業系統有哪些重點,它們的作用又是什麼,這本書的目標其實便是要講清楚原理,但並不會把某個話題挖掘地過於深入,過於細節。看看這本書後,我們就可以對計算機系統各元件的工作方式有了理性的認識。在一定程度上,其實它是在鍛鍊一種思維方式 —— 計算思維。
好了,小林本次的分享就到這裡了,不知道推薦的書和視訊是否和你的「口味」,同時也歡迎你在留言區裡分享你是怎麼學習它們的,又有什麼好書推薦給大家呢?