極客時間專欄陳皓《左耳聽風》筆記二

專欄《高效學習系列》精華筆記程序員

主動學習與被動學習

你聽別人講,或是本身看書,或是讓別人演示給你,這些都不能讓你真正得到學習能力,由於你是在被別人灌輸,在聽別人說。算法

只有你開始本身思考,開始本身總結和概括,開始找人交流討論,開始踐行,並開始對外輸出,你纔會掌握到真正的學習能力。編程

學習不是努力讀更多的書,盲目追求閱讀的速度和數量,這會讓人產生低層次的勤奮和成長的感受,這只是在使蠻力。要思辨,要踐行,要總結和概括,不然,你只是在機械地重複某件事,而不會有質的成長的。框架

深度學習十分重要

應該怎樣進行深度學習呢?下面幾點是關鍵。機器學習

  • 高質量的信息源和第一手的知識。
  • 把知識連成地圖,將本身的理解反述出來。
  • 不斷地反思和思辨,與不一樣年齡段的人討論。
  • 觸類旁通,並踐行之,把知識轉換成技能。

換言之,學習有三個步驟工具

  • 知識採集。信息源是很是重要的,獲取信息源頭、破解表面信息的內在本質、多方數據印證,是這個步驟的關鍵。
  • 知識縫合。所謂縫合就是把信息組織起來,成爲結構體的知識。這裏,鏈接記憶,邏輯推理,知識梳理是很重要的三部分。
  • 技能轉換。經過觸類旁通、實踐和練習,以及傳授教導,把知識轉化成本身的技能。這種技能可讓你進入更高的階層。

我以爲這是任何人都是能夠作到的,就是看你想不想作了。性能

學習是爲了找到方法和原理

學習不只僅是爲了找到答案,而更是爲了找到方法。只有掌握解題的思路和方法,你纔算得上擁有解決問題的能力。學習

學習不只僅是爲了知道,而更是爲了思考和理解。在學習的過程當中,咱們不是爲了知道某個事的表面是什麼,而是要經過表象去探索其內在的本質和原理。測試

在學習的過程當中,咱們要不斷地問本身,這個技術出現的初衷是什麼?是要解決什麼樣的問題?爲何那個問題要用這種方法解?爲何不能用別的方法解?爲何不能簡單一些?……spa

擁有正確的學習觀念:學習不只僅是爲了找到答案,而更是爲了找到方法;學習不只僅是爲了知道,而更是爲了思考和理解;學習不只僅是爲了開拓眼界,而更是爲了找到本身的未知,爲了瞭解本身;學習不只僅是爲了成長,而更是爲了改變本身,改變本身的思考方式,改變本身的思惟方式,改變本身與生俱來的那些垃圾和低效的算法。

端正的學習態度和正確的學習觀念,是高效學習的第一步,擁有這二者必定可讓你事半功倍。

挑選知識和信息源

若是你以爲用百度搜中文關鍵詞就能夠找到本身想要的知識,那麼你必定遠遠落後於這個時代了。若是你用 Google 英文關鍵詞能夠找到本身想要的知識,那麼你算是能跟得上這個時代。若是你能在社區裏跟社區裏的大牛交流獲得答案,那麼你算是領先於這個時代了。

你的信息源要有下面幾個特質。

  • 應該是第一手資料,不是被別人理解過、消化過的二手資料。尤爲對於知識性的東西來講,更是這樣。應該是原汁原味的,不該該是被添油加醋的。
  • 應該是有佐證、有數據、有引用的,或是有權威人士或大公司生產系統背書的資料。應該是被時間和實踐檢驗過的,或是當心求證過的,不是拍腦殼野路子或是道聽途說出來的資料。
  • 應該是加入了一些本身的經驗和思考,能夠引起人深思的,是所謂信息的密集很大的文章。

注重基礎和原理

我說過,不少人並非學得不夠快,而他們的基礎真的不行。基礎不行,會影響你對事物的理解,甚至會讓你不能理解爲何是這樣。當你對事物的出現有不理解的東西時,一般來講,是由於你的基礎知識沒有跟上。

使用知識圖

畫知識圖的方式可讓你從一個技術最重要最主幹的地方出發開始遍歷全部的技術細節,也就是畫地圖的方式。若是你不想在知識的海洋中迷路,你須要有一份地圖,因此,學習並非爲了要記憶那些知識點,而是爲了要找到一個知識的地圖,你在這個地圖上能經過關鍵路徑找到你想要的答案。

系統地學習

在學習某個技術的時候,可使用一個學習模板。只有把這個學習模板中的內容都填實了,我才罷休。這個模板以下。

  1. 這個技術出現的背景、初衷和要達到什麼樣的目標或是要解決什麼樣的問題。這個問題很是關鍵,也就是說,你在學習一個技術的時候,須要知道這個技術的成因和目標,也就是這個技術的靈魂。若是不知道這些的話,那麼你會看不懂這個技術的一些設計理念。
  2. 這個技術的優點和劣勢分別是什麼,或者說,這個技術的 trade-off 是什麼。任何技術都有其好壞,在解決一個問題的時候,也會帶來新的問題。另外,通常來講,任何設計都有 trade-off(要什麼和不要什麼),因此,你要清楚這個技術的優點和劣勢,以及帶來的挑戰。
  3. 這個技術適用的場景。任何技術都有其適用的場景,離開了這個場景,這個技術可能會有不少槽點,因此學習技術不但要知道這個技術是什麼,還要知道其適用的場景。沒有任何一個技術是普適的。注意,所謂場景通常分別兩個,一個是業務場景,一個是技術場景。
  4. 技術的組成部分和關鍵點。這是技術的核心思想和核心組件了,也是這個技術的靈魂所在了。學習技術的核心部分是快速掌握的關鍵。
  5. 技術的底層原理和關鍵實現。任何一個技術都有其底層的關鍵基礎技術,這些關鍵技術頗有可能也是其它技術的關鍵基礎技術。因此,學習這些關鍵的基礎底層技術,可讓你將來很快地掌握其它技術。能夠參看我在 CoolShell 上寫的 Docker 底層技術那一系列文章。
  6. 已有的實現和它之間的對比。通常來講,任何一個技術都會有不一樣的實現,不一樣的實現都會有不一樣的側重。學習不一樣的實現,可讓你獲得不一樣的想法和思路,對於開闊思惟,深刻細節是很是重要的。

基本上來講,若是你按照我上面所提的這 6 大點來學習一門技術,你必定會學習到技術的精髓,並且學習的高度在一開始就超過不少人了。若是你能這樣堅持 2-3 年,我相信你必定會在某個領域成爲煊赫一時的佼佼者。

觸類旁通

我認爲,人與人最大的差異就是觸類旁通的能力。那些聰明的或者是有經驗的人觸類旁通起來真是太使人驚歎。

我以爲一我的的觸類旁通能力,能夠分解成以下三種基本能力。

  • 聯想能力。這種能力的鍛鍊須要你平時就在不停地思考同一個事物的不一樣的用法,或是聯想與之有關的別的事物。對於軟件開發和技術學習也同樣。
  • 抽象能力。抽象能力是觸類旁通的基本技能。平時你解決問題的時候,若是你能對這個問題進行抽象,你就能夠得到更多的表現形式。抽象能力須要找到解決問題的通用模型,好比數學就是對現實世界的一種抽象。只要咱們能把現實世界的各類問題創建成數據模型(如,創建各類維度的向量),咱們就能夠用數學來求解,這也是機器學習的本質。
  • 自省能力。所謂自省能力就是本身找本身的難看。當你獲得一個解的時候,要站在本身的對立面來找這個解的漏洞。有點像左右手互博。這種本身和本身辯論的能力又叫思辨能力。將本身分裂成正反方,左右方,甚至多方,站在不一樣的立場上來和本身辯論,從而作到不漏過一個 case,從而得到完整全面的問題分析能力。

在這方面,我對本身的訓練以下。

  1. 對於一個場景,製造出各類不一樣的問題或難題。
  2. 對於一個問題,努力尋找儘量多的解,並比較這些解的優劣。
  3. 對於一個解,努力尋找各類不一樣的測試案例,以圖讓其健壯。

老實說,要得到這三種能力,除了你要很喜歡思考和找其它人來辯論或討論之外,還要看你本身是否真的善於思考,是否有好奇心,是否喜歡打破沙鍋問到底,是否喜歡關注細節,作事是否定真,是否嚴謹……

概括和總結

對本身的知識進行總結和概括是提升學習能力的一個很是重要的手段。這是把一個複雜問題用簡單的語言來描述的能力。

咱們把學到的東西用本身的語言和理解從新組織並表達出來,本質上是對信息進行消化和再加工的過程,這個過程可能會有信息損失,但也可能會有新信息加入,本質上是信息重構的過程。咱們積累的知識越多,在知識間進行聯繫和區辨的能力就越強,對知識進行總結和概括也就越輕鬆。而想要提升總結概括的能力,首先要多閱讀,多積累素材,擴大本身的知識面,多和別人討論,多思辨,從而見多識廣。

咱們須要注意的是,若是隻學了部分知識或者尚未學透,就開始對知識進行總結概括,那麼總結概括出來的知識結構也只能是混亂和幼稚的。所以,學習的開始階段,能夠不急於總結概括,不急於下判斷,作結論,而應該保留部分知識的不肯定性,保持對知識的開放狀態。當對整個知識的理解更深刻,本身站的位置更高之後,總結和概括纔會更有條理。總結概括更可能是在複習中對知識的回顧和重組,而不是一邊學習一邊就總結概括。

作總結概括的方法:把你看到和學習到的信息,歸整好,排列好,關聯好,總之把信息碎片給結構化掉,而後在結構化的信息中,找到規律,找到相通之處,找到共同之處,進行簡化、概括和總結,最終造成一種套路,一種模式,一種通用方法。

要訓練本身這方面的能力,你須要多看一些經典的方法論圖書,看看別人是怎樣總結和概括知識的。你能夠在一開始模仿並把本身的理解的知識給寫出來,寫博客會是一種很好的方式。另一種更好的方式是講一遍給別人聽。總之,你須要把你總結概括的知識公開出來,給別人看,接受別人的批評和反饋,這樣你才能成長得更快。其實,我也在鍛鍊這樣的能力。

讀文檔仍是讀代碼

書和文檔是人對人說的話,代碼是人對機器說的話(注:代碼中有一部份邏輯是控制流程的邏輯,不是業務邏輯)。因此,

  1. 若是你想知道人爲何要這麼搞,那麼應該去看書(像 Effective C++、Code Complete、Design Pattern、Thinking in Java 等),看文檔。
  2. 若是你要知道讓機器幹了什麼?那你應該看代碼!(就像 Linus 去看 zlib 的代碼來找性能問題。)

所以,我認爲都比較重要,關鍵看你的目的是什麼了。

若是你想了解一種思想,一種方法,一種原理,一種思路,一種經驗,恐怕,讀書和讀文檔會更有效率一些,由於其中會有做者的思路描述。像 Effective C++ 之類的書,裏面有不少對不一樣用法和設計的推敲,TCP/IP 詳解裏面也會有對 TCP 算法好壞的比較……這些思惟方式能讓你對技術的把握力更強,而光看代碼很難達到這種級別。(如今你知道什麼樣的書是好書了吧 ;-))

若是你想了解的就是具體細節,好比某協程的實現,某個模塊的性能,某個算法的實現,那麼你仍是要去讀代碼的,由於代碼中會有更具體的處理(尤爲是對於一些 edge case 或是代碼技巧方面的內容)。

從學習的過程當中,咱們來分析一下看代碼和看書這兩個活動。人對新事物的學習過程基本都是從「感性認識」到「理性認識」的。

若是你是個新手,那應該多讀代碼,多動手寫代碼,由於你須要的是「感性認識」,這個時候「理性認識」你體會不到。一是由於,你沒有切身的感覺,即使告訴你 Why 你也體會不到。另外一方面,這個階段,你要的不是作漂亮,而是作出來。因此,在新手階段,你會喜歡 GitHub 這樣的東西。

若是你是個老手,你有多年的「感性認識」了,那麼你的成長鬚要更多的「理性認識」。由於這個階段,一方面,你會不知足於作出來,你會想去作更牛更漂亮的東西;另外一方面,你知道的越多,你的問題也越多,你迫切地須要知道 Why!這時,你須要大量地找牛人交流(讀牛人的書,是一種特殊的人與人的交流),因此,這個階段,你會喜歡讀好的書和文章。

然而,對於計算機行業這個技術創新能力超強、技術種類繁多的行業來講,咱們每一個人都既是新手,也是老手。

如何閱讀源代碼

在閱讀代碼以前,我建議你須要有下面的這些前提再去閱讀代碼,這樣你讀起代碼來會很順暢。

  • 基礎知識。相關的語言和基礎技術的知識。
  • 軟件功能。你先要知道這個軟件完成的是什麼樣的功能,有哪些特性,哪些配置項。你先要讀一遍用戶手冊,而後讓軟件跑起來,本身先用一下感覺一下。
  • 相關文檔。讀一下相關的內部文檔,Readme 也好,Release Notes 也好,Design 也好,Wiki 也好,這些文檔可讓你明白整個軟件的方方面面。若是你的軟件沒有文檔,那麼,你只能期望這個軟件的原做者還在,並且他還樂於交流。
  • 代碼的組織結構。也就是代碼目錄中每一個目錄是什麼樣的功能,每一個文檔是幹什麼的。若是你要讀的程序是在某種標準的框架下組織的,好比:Java 的 Spring 框架,那麼恭喜你,這些代碼不難讀了。

閱讀代碼的方法以下。

  • 通常採用自頂向下,從整體到細節的「剝洋蔥皮」的讀法。
  • 畫圖是必要的,程序流程圖,調用時序圖,模塊組織圖……
  • 代碼邏輯歸一下類,排除雜音,主要邏輯纔會更清楚。
  • debug 跟蹤一下代碼是瞭解代碼在執行中發生了什麼的最好方式。

對了,閱讀代碼你須要一個很好的 IDE。我記得之前讀 C 和 C++ 代碼時,有一個叫 source insight 的工具就大大提升了個人代碼閱讀效率。說白了就是能夠查看代碼間相互的調用 reference 的工具,這方面 Visual Studio 作得是很是好的。

如何面對枯燥的知識

若是你發現有些知識太過於枯燥,那麼能夠經過下面的方法解決。

  • 這個知識對於你來講來過高級了,你可能不知道能用在什麼地方。
  • 人的認知是從感性認識向理性認識轉化的,因此,你可能要先去找一下應用場景,學點更實用的,再回來學理論。
  • 學習須要有反饋,有成就感,帶着相關問題去學習會更好。
  • 固然,找到牛人來給你講解,也是一個很不錯的手段。

如何面對大量知識

我給你的建議是,一點一點學,一口一口吃。你可使用我前面說過的那些方法,注重基礎,畫知識圖,多問爲何,多動手,而後堅持住,哪怕你每週就學一個知識點,你一年也能夠學到 50 個知識點。只要你在進步,總有一天能夠把這些知識學到手的。

固然,你的目的不是學完這些知識,由於學無止境,你永遠也學不完,因此你在學習時,必定不要學在表面上,必定要學到本質,學到原理上,那些東西是不容易變的,也是經得住時間考驗的。把學習當成投資,這是這個世界上回報最好的投資。

帶着問題去學習,帶着要解決的東西去學習,帶着挑戰去學習,因而每當你解決了一個問題,作了一個功能,完成了一個挑戰,你就會感到興奮和有成就感。這樣,你也就找到了源源不斷的學習驅動力。

把你學習的心得、過程、筆記、代碼分享出來,找到和你一同窗習的人,由於一我的長跑很辛苦,有人同行就會好不少,就算沒有人同行,你的讀者,你的觀衆也會爲你鼓勵叫好,這些也是讓你持續前行的動力。

其它幾個實用的技巧:

  • 用不一樣的方式來學習同一個東西。好比:經過看書,聽課,建立腦圖,寫博客,講課,解決實際問題,等等。
  • 不要被打斷。被打斷簡直就是學習的天敵,因此,你在學習的時候,最好把手機設置成勿擾模式放在一邊,而後把電腦上的全部通知也關掉,最好到一個別人找不到你的地方。
  • 總結壓縮信息。當你得到太多的信息時,你須要有一個「壓縮算法」。我經常使用的壓縮算法是隻關心關鍵點,因此,你須要使用表格、圖示、筆記或者腦圖來幫助你壓縮信息。
  • 把未知關聯到已知。把你新學的知識點關聯到已知的事物上來。好比,你在學習 Go 語言,你就把一些知識關聯到本身已經學過的語言上好比 C 和 Java。經過類比,你會學得更紮實,也會思考得更多。
  • 用教的方式來學習。你想一想,若是你過幾天要在公開場合對不少人講一個技術,那麼這個壓力會讓你學得更好。由於要教給別人,因此,這麼高的標準須要你不但要把本身已掌握的東西學好,還要把周邊的也一併學了,纔可能作到百問不倒。你纔敢去教別人,不是麼?(試試教 6 歲的孩子編程,若是你掌握了這種技能,那麼你必定是把知識吃得很是透徹了。)
  • 學以至用。把學到的東西用起來,沒有什麼比用起來能讓你的知識更鞏固的了。在實踐中,你纔會有更爲真實的體會,你纔會遇到很是細節和很是具體的問題,這些都會讓你從新思考,或深化學習。
  • 不要記憶。聰明的人不會記憶知識的,他們會找方法,那些能夠推導出知識或答案的方法。這也是爲何外國人特別喜歡方法論。
  • 多犯錯誤。犯錯會讓你學獲得更多,經過錯誤總結教訓,你會比沒有犯過錯的人體會得更深。可是千萬不要犯低級錯誤,也不要同一個錯誤犯兩次。

推薦閱讀:

相關文章
相關標籤/搜索