學習內核的好處不少,在學習過程當中不只能夠夯實大量理論基礎,還能夠學習到不少編碼慣用法,提高學習能力和分析能力。node
1、確立高度,明確目標linux
在學習內核過程當中最容易犯的錯誤,也是很是難掌握的實際上是你站在一個什麼樣的高度上去學習。站什麼樣的高度去學習也與自身的能力相關,因此這個問題其實更可能是在新開始學習的學習者感到很是痛苦的一件事。一方面又但願本身能學懂,可是又不知道如何開始入手。編程
我列舉幾個常見的例子:網絡
(1) 一開始就看源碼,最開始我也作過這種事,內核有什麼都不知道,結果就想着啃0.11的內核,結果很顯然,2天立馬放棄,徹底看不懂。架構
(2) 翻開書從第一頁開始往下啃,若是這本書比較薄還好,若是比較厚,好比《深刻Linux內核架構》,那看2天也得放棄。函數
(3) 不喜歡看目錄,不喜歡快速瀏覽,就想着一個一個字眼的往下摳。若是自己有必定基礎,看的時候還不會以爲膩,可是很快就發現,看了半天,什麼都沒有記住。學習
還有不少相似的問題,這些都是咱們平時學習的時候特別容易出現的一些誤區。這些其實都是沒有正確審視本身的能力,胡亂挑選高度致使。編碼
高度越高,也就是越偏向於理解各類抽象概念,傾向於構建對總體結構的一個認知,忽略一些沒必要要細節,不關心技術實現手段。高度越低,也就是越偏向於對使用技術的選擇,傾向於代碼實現的各個細節,可是前提通常會在某個抽象的概念領域內進行各類細節性的討論。spa
咱們的大腦更傾向於理解抽象的內容,可是在行動時,咱們卻更傾向於去把握細節性的內容。結果致使的內容就是,咱們老是但願經過學習細節來構造對抽象概念的理解,最後被細節性內容中各類噪聲干擾思緒,產生一種「這東西好難」的錯覺。在理解了這點,那高度對咱們的行爲有和指導意義也就呼之欲出了?
以讀書爲例。站的越高,意味着本身看的內容越粗糙,也就是看書的時候不會去逐字逐句的看,而是一個章節一個章節的看,極端的狀況就是隻看目錄,在這個過程當中主要集中精力構建總體結構,對核心的概念進行抽象。這時候學的內容都相對錶面,可是好處就是對之後的學習有很強的指導意義,缺點很明顯,會讓人底氣不足,並且在達到必定程度後,很容易到達瓶頸,發覺怎麼看都看不懂了。站的越低,意味着本身看的內容很細緻,看書的時候就是一個個字眼的扣,極端狀況就是開始閱讀源碼,去看開源社區的各類問題。可是就像詩句說的,站的越低,也就常有一種「不識廬山真面目,只緣身在此山中」的感受。這種狀況下特別容易被各類細節干擾,例如爲何要有這些參數,爲何這裏須要判斷這個條件等等這些細枝末節的問題。設計
之前對一篇博文印象很深入,做者理解的學習曲線劃分紅了兩個比較大的過程,上升的過程就是一個不斷學習積累的過程,而平緩沒有增加的過程則是對以前積累到飽和的知識進行消化的過程。我將這個學習過程進行進一步的劃分,我以爲在學習積累的前半部分應該以偏向學習抽象概念爲主,而後半部分應該偏向學習實現細節。
因此我的的心得是從高到低的學習,在一個新的學習階段,應該先多花點時間學習一些概念化的內容,這時候切忌去看具體的實現,而是多考慮如何在大腦中構建各類抽象模型
對總體的架構有所概念了,而後開始學習一些細節性的內容,好比開始看些源碼,摳寫書上的字眼,讀讀一些具體的博客什麼的。
2、學習小Tips
不要從第一頁開始翻 不要一頁一頁的翻
若是開始看代碼,必定要記住,本身已經站在一個很是底層的高度度了,可以有能力閱讀代碼,就意味着你必須對總體的結構有比較清晰的認識,若是你都不知道這個結構,那看代碼爲時太早。
不管是什麼樣的代碼,其實思路都很相似,即便Linux內核是用C這種面相過程的語言編寫,可是這麼多年發展下來,Linux內核已經帶有了大量面對對象編程的特色。
在看代碼的時候也是有兩種不一樣的高度能夠選擇,我先解釋其中最細緻的一種:
一個函數寫下來常常上百行,可是你須要一行一行的看麼?確定不能,那清晰認識一個函數的結構就很重要。
一個函數就是爲了解決一個問題,函數名基本都能說明其功能,函數參數是輸入,返回值就是輸出,函數體就是總體的執行邏輯。在函數體內部,也基本都是相似的邏輯,先是對各類輸入參數進行檢查,而後書寫功能邏輯,而後構造輸出的結果。因此一個函數寫下來老是這樣的一種結構。
輸出結果 函數名(輸入)
{
if (輸入的參數有問題)
{
異常處理,跳出
}
準備參數
功能邏輯
構造輸出結果
返回輸出結果
}
一個函數其實就是一個方法,閱讀的難度比書寫的難度要低,書寫代碼須要考慮的問題很是多,可是在閱讀代碼的時候問題就簡單不少,不少書寫代碼過程當中須要考慮的問題在閱讀代碼的過程當中就不須要考慮 。
閱讀代碼還有不少技巧,例如如何在帶有goto語句的代碼中快速理解邏輯,如何界定那些註釋是能夠忽略的,如何將一些代碼邏輯當作一塊總體內容,什麼時候應該跳到更深的一層函數閱讀等等。這些都須要平時的經驗積累。
看代碼有一個粒度問題,咱們不能一行一行的看,也不能一個一個函數的看,我以前提到了,Linux內核有大量面向對象編程的影子,因此在看大量代碼的時候,必須學會面向對象編程的思惟模式。這樣對本身在大量代碼閱讀中提供大量參考意見。
或許有人會告訴你,面向對象編程就是弄明白什麼是對象、如何寫一個class就能夠了。確實,學習面向對象編程,弄明白對象是基礎,不過我以爲能夠再拔高一點,理解一些更抽象的概念,在這些抽象概念的指導下去學習,能夠有更多的指導意義。
若是可以理解上述的這幾個抽象,那在大量代碼中如何遊刃有餘就相對容易了,有一個簡單的套路:
(1) 在較高的角度,弄明白一個系統爲了解決什麼問題,應該有哪些抽象
(2) 在對總體結構有所瞭解之後,花心思看看這些抽象對應的領域模型,由於通常狀況領域模型很龐大,因此看的時候也須要有步驟的進行拆解學習。
(3) 在對領域模型有所瞭解後,開始看領域驅動類,想明白爲何會有這些操做。
(4) 在上述準備好後,就能夠花費一些時間去看各個函數的具體實現,而且在看的過程當中多思考領域模型爲何這麼設計。