為什麼原始碼分析味同嚼蠟?淺析技術寫作中的思維誤區

doodlewind發表於2017-11-21

優秀的技術社群每天都會生產出不少乾貨內容,《XX 框架原始碼分析》就是其中的一類。然而,這類文章往往叫好不叫座,人氣常常不如《手把手教你 XX》。真的是我們太浮躁了嗎?本文希望用另一種角度看待這個問題。

從大學教材到技術寫作

中國的大學課堂以照本宣科而著稱,而各個學校自己編寫的大學教材也是出了名的枯燥無味。那麼,一本爛教材一般滿足什麼條件呢?這裡隨便列出幾個:

  1. 講述的主題本身很複雜,很難脫離課本自學。
  2. 課程內容明明早有更好的經典國外教材,卻偏要自己重寫一套。
  3. 幾乎不講每個章節的意義,上來就是大段大段枯燥的定理、證明。
  4. 帶了一大堆習題卻不給答案。
  5. 小出版社沒有什麼審校,有各種明顯的錯漏。

然後讓我們對比一下,一篇冷門的《XX 框架原始碼分析》又滿足什麼條件呢?

  1. 分析的框架本身很複雜。
  2. 這個框架已經被人分析過很多遍了。
  3. 上來就是大段大段的程式碼。
  4. 某些關鍵的地方被略過了,貼完原始碼還是讀不懂。
  5. 排版措辭混亂。

看到了嗎,這完全一一對應啊!非要說二者有什麼不同的話,可能就是爛教材收錢而爛文章免費了吧。

技術文章的價值觀

能寫原始碼分析文章的同學,多半是有不少靠譜乾貨的,我也絕不是說原始碼分析的文章都是垃圾。在此,我們不妨換個問題考慮一下,即為什麼中國的大學教材會遭人唾棄

沒有對比,就沒有傷害。讓我們看看高等教育發達的美帝,其本科理工教材的行文方式是怎樣的吧:

  1. 告訴讀者,這門課要做什麼,要解決什麼問題。
  2. 用大段的文字描述,向讀者展示如何一步步庖丁解牛地分解問題。
  3. 給出一些公式和推導過程,講解如何(在簡單情形下)解決問題的原理。

把美帝教材與天朝教材的編寫思路相對比,我們就可以總結出二者在價值觀上的偏差了:

  • 天朝:以規範為本的價值觀,關注如何系統、結構地陳列知識
  • 美帝:以讀者為本的價值觀,關注如何讓讀者理解知識

這就是差別所在:許多【技術乾貨】和中國的大學教材一樣,並沒有把將知識傳達給讀者作為第一訴求,而是花大量篇幅貼出程式碼,告訴你【這個很複雜,我讀懂了!】。然而,即便是矽谷的白板技術面試,程式碼量也不會超過 50 行,動輒幾十上百行美其名曰【完整示例】的原始碼,沒有讀過的讀者真的能在短短的幾分鐘閱讀時間裡看懂嗎?

然而,拜【先贊後看】的商業互吹風氣所賜,沒看懂這類文章的新手同學多半不敢把看不懂的責任歸結到文章的行文思路上,而只會自卑地認為自己【水平不夠】。於是,新人們為了提升水平,也投入到了原始碼閱讀的大軍裡來,在歷經困難後終於獲得了成長,寫出了一篇對同樣框架同樣原始碼的同樣分析,想要屠龍的勇士也終於變成了龍。

所以,許多讓人感覺晦澀的技術文章,其問題可能並非出在所介紹的技術內容本身,而是出在更基本的行文思路上。除了上面提及的原始碼解析類文章,類似的技術內容還包括:

  • 寫給自己看的 Debug 筆記,裡頭都是各種業務細節的流水賬。
  • 介紹某個技術點的技術分享 PPT,上來就講一堆高階特性,生怕別人覺得深度不夠。
  • 描述模組介面的文件,不講自己的特性和概況,直接就丟個【呼叫示例】把 API 調個遍。
  • ……

然而只要稍稍轉變行文的價值導向,按照讀者的閱讀理解方式梳理一下,它們都很容易變成高質量、能讓讀者從中學到知識的乾貨:

  • 把流水賬按照多問問幾個 Why 的方式來總結,就是非常有借鑑意義的 Case Study;把其中業務性內容剝離,就是節約後來者時間的踩坑指南。
  • 把分享 PPT 整屏整屏的程式碼換成直觀的圖示與原理性的虛擬碼,就是圖文並茂的入坑指南(Facebook 當年講 React 時,記得那個 PPT 只有寥寥幾行程式碼)。
  • 把內部不敢見光的技術文件按照特性、示例、API 的流程講一遍,就是達到開源級別的靠譜文件了。
  • ……

價值觀上哪怕是簡單的改進,最終產出的內容往往都會有很大的不同。我個人的例子是:同樣是開發模擬器的總結,第一次寫 實現 Chip8 彙編模擬器 的時候,主題就是【我這個東西很厲害呢】,這時的內容就是典型的技術流水賬;而過了一段時間成長後,改進的 如何用 3KB 不到的 JavaScript 實現微機模擬器 就是一篇旨在分享,希望能夠讓新人看懂的教程了。歡迎對照它們各自的行文方式,這樣就能對文章的可讀性做出評價啦。

原始碼分析的套路與意義

上面介紹的是【轉換價值導向】的概念。對許多技術文章,理清思路就能夠很大地改善閱讀體驗了,不過對於原始碼解析類的文章,個人還有個大膽的想法:即它們的編寫難度可能並沒有標題看起來的那麼大,對新手向的讀者也缺乏實際的用處

這裡我提出一種演算法,能夠輕鬆地完成對任意框架的原始碼分析

  1. 框架都會把底層複雜 API 封裝起來,在原始碼裡找到某個調這類 API 的地方。這種地方隨便搜尋一下,到處都是。
  2. 在這裡加一行 throw 一個異常,執行框架來讓它報錯。
  3. 找到錯誤堆疊裡的全部函式,把它們的順序反過來,依次複製到你的《XX 原始碼分析》中,並把註釋翻譯成中文

三步搞定!雖然這個演算法十分荒唐而無聊,但筆者確實見過一些文章,寫得就像是通過這個方式堆砌出來的一樣。程式碼的藝術在於化繁為簡,而這樣的內容卻是在化繁為繁,讀起來難受也是再正常不過的了。

另外,由於程式碼天生的特殊性,最好的程式碼閱讀器恐怕不是技術社群的 App,而是強大的 IDE。原始碼分析的文章能夠拿來下斷點除錯、能夠拿來 mock 測試、能夠拿來看執行時變數內容嗎?有原始碼本身就足夠了吧。

這就造成了一個尷尬的結果,即我們在想要了解程式碼的實現細節時,第一選擇往往不是其他人寫的原始碼分析文章。比如,在之前編寫 Chip-8 模擬器的時候,我發現語言文件中的某一條指令語焉不詳。這時我首先想到去參考的,是前人實現過的 Java 版專案原始碼,而不是找一篇《模擬器原始碼分析》來讀。既然多數情況下原始碼本身已經是 Single Source of Truth,二手材料的優先順序還會很高嗎?

不過,對原始碼的解析難道就一無是處了嗎?這個想法就更加錯誤了。閱讀原始碼的能力絕對算是開發同學的硬技能,那麼在什麼場合會用到對原始碼的解析呢?我倒是發現在一個場合它非常適合:寫 Pull Request 描述的時候

在向社群提交 PR 的時候,我們一般會說明【要解決什麼問題、什麼程式碼引起了問題、解決方案是什麼】的三部曲,這時候閱讀者都是已有背景知識的維護者,故而這些資訊非常有助於 PR 的討論與合併。

回想一下,中國的大學教材也不是一無是處吧?它們在考前複習的時候可方便了呢。原始碼解析類的文章就像是這樣的提綱,需要給已經讀懂過一次的人,才能發揮出最大的價值。

總結

鑑於上文中看起來批評了不少內容,故而有必要在最後澄清本文的主題:

  • 許多技術文章絕不是乾貨不夠,而是乾貨太乾,以至於閱讀起來十分乏味。
  • 對行文思路簡單的改變,都能很大程度地改善閱讀體驗。
  • 原始碼分析類的內容更適合作為 Pull Request 的討論描述,而非讓新人【理解框架原理】。

最後對於可能的質疑,作者個人的 Github 裡有不少槽點很高的玩具原始碼,吐槽請不要客氣?…

相關文章