一年回顧

距離上次寫這篇近年常被問到如何學習 C++也過了將近兩年了,世界上也發生了不小的變革,最讓人興奮的莫過於 ChatGPT 的問世,這東西拿來伴讀的效果奇佳,以前看不太懂或是作者寫得太抽象的東西只能草草讀過,現代只要問它或跟它討論,學習死角可以說幾乎完完全全被堵上了。真好奇未來的學生靠這種東西能變得多強?又或者只是把它當成一個更容易打混摸魚輕鬆過大學生活的工具?善用它的人到底能多快拿到博士學位?未來突然變得讓人期待了起來,與此同時也讓我個人的學習慾望大增,有時還真想辭職回學校重新當學生或者在家自學兩年重新充電一下。

雖然上面是這麼說,但 ChatGPT 其實算是很講究使用技巧的,沒有適當的提示詞基本上很難和你進行有深度的技術討論。每次輸入一長串當然也很麻煩,所以 ChatGPT 從某次更新開始就可以輸入關於自己的資訊、希望它如何回答這兩個欄位,後來又慢慢發展成可以自訂 GPTs。網路上有琳瑯滿目的教學,坊間也有五花八門的書籍在講怎麼用好 ChatGPT,這邊就不再廢話。總而言之,給它提的問題越空泛,它回答的答案也越空泛,不指引它往某個特定領域去思考,它也幾乎不太可能抽取相關知識來加以回應。換句話說,提問者本身具備的知識量還是至關重要,豐富個人的知識儲備量還是不可或缺的。舉例來說,如果你想請它寫一段程式,沒有相關提示詞,它絕對不會依照你腦中所想把程式組織好給你。想跟它討論分散式架構設計,沒有良好的引導,它也幾乎不可能主動提出諸如 Majority QuorumPaxosSaga Pattern 等等的建議給使用者。如何有效駕馭 ChatGPT 來使自己倍速成長,成為了這一年來理工學生和工程師們的重要課題,沒能善用它加強自己的人肯定是會被時代洪流所淹沒。

其實從五年前轉來朋友開的 Fintech 公司後就一直面臨一個問題,這種純軟公司需要的和以往專精單一領域不同,需要廣泛涉獵許多領域的知識,總而言之我從 1998 到 2018 這 20 年間專心累積的 compiler 領域知識在此處是幾乎派不上用場的。隨著強者同事 xnum 的加入,也被迫進行了各方各面的學習,在他來之前原本以為只要會 gRPC 和 Docker 就夠了,他來以後又引進了 nats streaming server、TiDB、Kubernetes 以及 HA 架構的設計,坦白說要同時學會他帶進來的這些東西,又要跟上近年快速演化的 C++,又要推進工作進度,這五年的人生可說過得跟以前讀國中時白天上學、晚上補習、深夜寫作業和複習已經差不了多遠了,很難談得上還能有什麼額外休閒娛樂可以從事。

在這廣泛學習和專精學習同等重要的行業,過往那種 top-down 式的學習方法已經不敷使用了。top-down 的學習方法是從小到大學校教給我們的方法,方便有組織並系統化的吸收一門新知。但在這種行業裡,雖然系統化學習也是有它的重要性在,但工作上面臨的迫切性,往往使得這種學習方法難以立即派上用場。有時我們需要的只是相當片段而零碎的知識,只為了解決我們正遭遇的困難。這裡講的當然不單是指去 Google 搜尋、問 ChatGPT 或者去 Stack Overflow 上面抄答案這種事,還包括了在面對一本從未閱讀過的書籍卻沒有充足時間從頭到尾閱讀它,只能把現在正面臨的問題相關的章節挑出來讀並且加以運用的情況。在這樣的情境下所獲得知識,往往會是非常片段且零碎的,而且很容易一學完就忘。這種現象週而復始,很容易讓自己覺得這幾年在虛度光陰,特別是我這種以專精少數知識起家的類型,更容易感受到自己這幾年學得雜而不精。

然而,雜而不精也是自己的價值,最重要的是怎麼把它有效地重新組織整理。寫筆記這種事,從早期寫 blog 到改用 Evernote、Notion、HackMD 等筆記軟體或網站,大多還是脫不了腦中得先想好標題跟大綱再一層一層寫下去的做法,這些仍然還是 top-down 的記法,說實話要組織這些零碎知識還是很困難的。我在去年八月用累積的特休出國幫朋友忙的時候,在那邊學到了一套 bottom-up 的組織方式,稱為卡片盒筆記法 (Zettelkasten),並在那邊學習了 Obsidian 這套軟體的使用,回國後也接觸了 Heptabase。這套筆記方法是起源自德國的一名社會學家,他厲害的地方不只是一生當中寫了 70 多本書和 400 多篇論文,領域還從社會學跨到了生物學、數學、電腦科學等等,可見這方法的確有它的過人之處。近半年來也讀遍了這套筆記法的書,甚至也買了課程,看看其它人對於這套方法和自己有什麼不同的見解。雖然推廣這些方法的人大多是文組的,所以他們給的建議很難直接套用在軟體工程師身上,但要轉換思路並不困難。

簡而言之,這套方法需要時常記錄自己一閃而過的靈感,將它寫成靈感筆記。而獲取靈感的方式,就是每天寫工作日誌,並在一天工作結束前進行整理,順便看看還有沒有其它發想。平時閱讀網路上一些文章、從 YouTube 學一些新知,或是讀書 (無論整本或片段),也可以寫成文獻筆記。最後就是每天也要撥出時間,將靈感筆記和文獻筆記轉化成一張一張的小卡片,把它們轉化成永久筆記,這其中最重要的一點,就是要用自己的話寫出來,而不像是文獻筆記大多只是在做摘錄而已。隨著研究目標和工作目標的逐步設定,可以建立索引筆記來慢慢歸納整理這些散落在四處的卡片,而卡片和卡片之間也會因為知識的交集而彼此產生連結,運用 Obsidian 的 Canvas 或 Heptabase 的 Whiteboard,可以將這些卡片及卡片之間的連結視覺化,建立出專屬於自己的知識藍圖。這種白板的一個典型例子,可以參考 Heptabase 創辦人詹雨安分享出來的 Whiteboard

這種卡片視覺化的功能相當好用。以我個人的用法來說,它可以在替專案或自己的研究主題、學習目標等設定一個 milestone 後,開始把過去所寫的卡片拖進來組織,並透過網路搜尋或和 ChatGPT 討論,把欠缺的知識都整理出來開成一張一張的空白卡片,這樣就能透過逐步完成這些卡片來一步一步往目標邁進,這和遊戲裡把技能樹慢慢點亮是很相似的,只是現在連技能樹都要自己造而已。此時的方向雖然會暫時回歸 top-down,但實質上把自己已寫好的卡片組織起來的過程仍是 bottom-up 的。如果是買課程學這套方法,因為開課的老師大多是文青,會以發表文章或出書為前提來整理知識當作示範,運用方法會稍有不同,但大原則其實也沒差太多。

因為朋友開的這間公司實在是太小間,加上人才也相當難以招募,技術上許多大大小小的事都還是需要我親自處理,學的東西非常發散,工作時間也非常長,所以我從一開始寫卡片到可以開始讓它們之間產生諸多連結這一步,就花上了整整四個月的時間。其中也得花上大把時間把 Evernote、Notion、HackMD 上以前寫的筆記以文獻筆記的方式匯入卡片盒,然後重新把它們轉化成永久筆記,以卡片的形式加入我的知識藍圖當中。畢竟也不可能漫無目的在做這件事,這樣做起來會很痛苦,都是等用到這些知識才開始將這些古老筆記重新卡片化,所以整體來說也是花上了不少時間。以最近讀的 C++ 軟體設計這本書來說,它光是前 30 頁的內容就讓我有了契機把近 20 年讀的軟體開發和架構設計等古老筆記重新卡片化,不得不說這作者 Klaus Iglberger 是個相當有料的人物。

我知道台灣多數人才還是集中在半導體業和系統廠,在這些地方的工作內容常是封閉而單調的,所以雖然說現在大多數的知識早已整理在筆記軟體上而不是 blog,還是在這分享最近學到的這套卡片盒筆記法給看到的有緣人去學習。實際上這套方法就算沒有特地學過,我相信一些人仍然以類似的方式在組織自己的知識,像我老婆這種是以圖像思考為主的藝術細胞類型,就會用 eagle 這種軟體去組織它的知識 (更早期她還會使用 Stickies),她聽我描述完卡片盒筆記法以後,就發現其實她老早就有類似的做法在整理自己的知識了。換句話說,其實不侷限於 Obsidian 和 Heptabase,任何筆記軟體都有辦法實現卡片盒筆記法的精神,這也包括了 Notion。只是真要我推薦,我還是建議使用 Obsidian 或 Heptabase,早點轉換,長痛不如短痛。至於何者比較好用,就看個人習慣還有工作場所的網路限制是怎樣了。如果是沒錢的窮學生,那其實也沒什麼選擇,因為 Heptabase 要錢,只能選免費的 Obsidian。對於不想花錢或是不確定自己能不能用好卡片盒筆記法的,也是可以從 Obsidian 開始入門,反正在兩者之間轉換也沒太困難。

回到 C++ 的學習上,寫完上次那篇近年常被問到如何學習 C++的不久後,因為有非本科系背景的 junior engineer 加入,讓我深刻體認到對於 C++ Core Guideline 的瞭解還是有相當的重要性在。但由於它的內容沒有那麼平易近人,我會建議讀 Beautiful C++: 30 Core Guidelines for Writing Clean, Safe, and Fast CodeC++ Core Guidelines Explained: Best Practices for Modern C++ 這兩本書開始入門。當然現在又有了 ChatGPT,所以其實就算直接硬啃 C++ Core Guideline,也早就不是那麼枯燥乏味了。這些原文書都有電子版可以購買,但如果要讀實體書,因為低頭讀書還頗傷脖子的,可以考慮買一種落地帶輪子的閱讀架,這樣讀起來會輕鬆很多,不然忍著痠痛在讀書,效果肯定會大打折扣。當然因為我們理工的書籍動輒千頁,選購的時候要記得是可以放厚重書本的,只能夾住薄薄雜誌的那種不行。看是要選國產的這款全方位移動式調整型閱讀架或是對岸的云之爵落地读书架這類的都行。對岸這款我沒用過,只是做功課的時候有逛到而已,有燈的款式能不能吃台灣的 110V 我就不知道了。我這裡光照充足,所以其實也不會用那種帶燈的款式。但是要注意,讀紙本書的照度建議至少是 600 lux 以上,太暗會很不自覺地讀不太下去,不單是對眼睛健康有影響而已。我發現很多人長大以後變得不愛閱讀,很多時候不是因為年紀大了退化所造成,而是長大以後的住處沒有像學生時期一樣有充足的照明設備可以好好讀書。特別是那種出身富裕,小時候家庭提供的環境超棒,書原本能讀很好的,長大到外地租房子工作,房東提供的照明跟垃圾一樣,或者自己買了間房,自己搞出來的照明跟垃圾一樣,導致自己閱讀能力斷崖式下墜,這些都有可能是主因。這邊只是做個簡單建議,實際上真要講究的話還有色溫等等,極端情況下可能還需要用白熾燈而不是 LED 燈。如果發現自己的閱讀續航力、集中力和吸收力跟光源很有關係,建議多做一點相關功課去解決,不要因為這種小事讓自己的知識停滯不前,不然下一代靠 ChatGPT 無死角學習上來的應屆畢業生可能真的會全方位碾壓你。

除了唸書之外,現代化工具的使用也是需要下一番苦心。和我共事過的應該都知道,在來這間公司以前我一直是用接近純文字編輯器在寫 C++ 的,不是 vim 也不是 emacs,就只是 joe 這個只有簡單 syntax highlight 功能的編輯器。這一方面也是受到 xnum 這位有為年輕人的刺激,在一年多前我也改用了潮到出水的 zsh + tmux + vim 環境,搭配 YouCompleteMe 這個 plugin,結合 clangd、clang-format 和 clang-tidy 搞出了很多只有在 IDE 環境才有的一些功能。當然如果想結合 GitHub Copilot 來開發的話,這些東西也適用在 NeoVim。整合 clang-tidy 可以即時在 vim 裡檢查你的程式碼是否符合一些規範,這其中也包含了 C++ Core Guideline 的諸多條款,但因為公司近一年開始走向高頻交易系統開發,有些東西是無法完全遵守的,所以會根據實際狀況調整專案根目錄的 .clang-tidy 檔的內容加以因應。如果是用 GUI 的 editor 在開發的,像是 Eclipse-based 或 Visual Studio Code,應該也是有整合這些 clang tools 的方法,有興趣的可以自行研究。另一方面,在 git 的 hook 裡掛上 clang-tidy 做原始碼檢查,其實也可以省下不少人工 code review 的麻煩,太基本的東西沒遵守,靠這種自動化機制去打槍就好了。

至於我個人後續是否還會繼續留在目前這間公司,我自己的心情也是相當複雜。畢竟公司太小,加上很多地方還是要每一行 code 都得親自來寫,想認真去鑽研軟體架構設計,又或者是為了開發高頻交易系統去深究伺服器 CPU 的 microarchitecture 以及整天和效能分析器泡在一起做實驗,甚至是去認真摸 Vitis HLSXilinx Alveo Platforms 上搞好 FPGA 版的高頻交易系統,在近期來看都還算是相當遙遠。畢竟又是純軟又是金融,公司位置又不在熱門地段,可說是在工程師鄙視鏈的底層,光是會想來面試的通常就離即戰力非常遙遠。真說要去帶毫無經驗的新人,工作進度又時常全部壓在我一人身上,不是那麼有時間去充當 mentor 的角色。我也不再年輕,沒辦法持續以前醒 24 小時睡 12 小時那種一天 36 小時制的生活方式。現在只能靠工作 4 小時休息 1 小時、循環 4 次後睡 4 小時的方式來達成一天有 8 小時休息時間和 16 小時工作及學習的目標。坊間的書籍,對於這種狀況要長成小型團隊幾乎都沒什麼著墨,也許這邊算是比較極端的狀況吧,又或者是其實根本沒有公司從這種條件下獲得真正的成功。家裡的人也一再提醒我 45 歲之前要盡早安定下來,我現在已經是 42 歲不是 24 歲,心態不能再這麼年輕,一直去這些還沒發跡的公司慢慢陪人家吃苦和試誤了。

家人的看法倒還是其次,正如同我一開始說的,ChatGPT 的問世會讓未來的學習毫無死角,它激發了我極大的學習和實驗慾望。要是這間公司最終讓我覺得它會阻礙我個人的成長,那我或許會毅然決然選擇離開吧。目前看起來還有很多能做的嘗試跟努力還沒做,只是時間不夠多而已,所以姑且還是會給這公司一點時間。透過卡片盒筆記法可以確保並觀察到自己的成長,但正因為如此,我也深感自己進步的速度還是不夠快,花了太多時間在原本可以分工完成的實作細節裡。不過大家都是 20 多年的老朋友,我也是秉持著能幫就幫的心態繼續待著,但如果最終這會讓我被時代的洪流淹沒,再也追不上年輕人,譬如有天被年輕人輕易超越到看不見他的車尾燈,那我也只能跟他們說抱歉了。