育嬰假:第 4 個月
一句話總結
我得停止拖延了。
本月亮點
- 我找到了各種方法來拖延寫書。
- 我開心地對開源專案做 fuzz testing(模糊測試),玩得很盡興。
- 我為軟體開發挑選了一台全新高階桌機的零組件。
目標成績
每個月月初,我都會宣告當月想完成的事。以下是本月的達成狀況:
享受家庭時光
- 結果:持續享受家庭時光。
- 評分:A
在這段自主安排的育嬰假期間,我持續在家庭時光與個人及專業專案之間取得平衡,並樂在其中。
完成並發表 Refactoring English(《重構英文》) 的一個章節
- 結果:有撰寫章節,但沒有發表任何內容。
- 評分:D
我當初設定這個目標時低估了難度。好幾年前我就開始寫其中一個章節,之後斷斷續續回頭修改。在我的記憶中,那個章節已經完成了 80%,但這次重新檢視時,感覺更像是只完成了 20%。
我把章節推進到大約 60% 的進度,但並沒有像原本可以那樣專注。
我得停止拖延寫書這件事
也許我需要新字型
我開始撰寫書的第一章,卻一直被網站平庸的設計分心。

我的書籍網站使用的是我自己做的一個簡單設計主題,基本上就是 Bootstrap 的預設 CSS 加上一些自行調整的樣式。我說不上來具體哪裡有問題,但整體看起來就是不太對勁。
我開始瀏覽自己喜歡的部落格和網站,並試著把他們的字型套用到我的網站上:
- Jonas Hietala(喬納斯·希塔拉) 使用 Concourse 和 Century Supra,這兩款是由 Matthew Butterick(馬修·巴特里克) 設計的付費字型。
- Xe Iaso(希·艾亞索) 使用 Iosevka Aile Iaso,結果發現這是一款她自己設計的字型。
- fasterthanlime 使用 Atkinson Hyperlegible,這款字型由 Braille Institute 免費提供,因為它對視障者十分友善。
在書籍網站上看起來最適合的字型是 Concourse,這讓我進一步探索了 馬修·巴特里克 的所有字型。這是我第一次購買字型,而不是使用 Google Fonts 上的免費字型。我將 Concourse 用於標題,Heliotrope 用於內文。


我將 《重構英文》 網站的字型更換為 Concourse 與 Heliotrope
好看的字型帶來的差異讓我大吃一驚。感覺像作弊一樣,我完全不需要做其他設計更動,網站看起來就好了三倍。
也許我需要一個封面
換上漂亮的新字型後,我開始思考書籍封面的事。我本來就打算在出版前委託設計封面,既然如此,不如現在就著手。如果有一個好看的封面,會吸引更多人感興趣。於是,我寫了一份 封面設計規格說明,並聘請了一位設計師來執行。
也許我該回到之前的點子
幾天後,我收到一位讀者的來信,詢問是否可以付費取得 Hit the Front Page of Hacker News(《登上 Hacker News 首頁》) 中尚未完成的課程。我把兩堂全新未發布的課程和舊版課程的連結寄給他,他似乎對內容很滿意。這讓我開始思考,或許該暫停 《重構英文》,先完成 《登上 Hacker News 首頁》 的重製版。
也許我該專心一點
到了這個時候,我發現自己一直在找各種事情做,就是不去寫書。
很容易分心,因為完成這本書感覺是個遙遠的目標。而且因為這是一本關於寫作的書,我總覺得自己的文字必須完美,結果就卡在對每個字句的反覆雕琢上。
我想,一旦發表第一個試讀章節並看到讀者的回饋,我會對這本書更有感覺。在那之前,我就先硬著頭皮繼續推進,直到完成為止。
Fuzzing 超好玩
儘管有上一節提到的狀況,上個月我在 fuzz testing 上還是玩得很開心。
在十一月的大部分時間裡,我在等待三個月大的寶寶半夜第一次醒來前,會有幾個小時的獨處時間,可能是把他哄睡後的一到四小時之間。在那段時間裡,很難專心寫程式,因為整天已經很累,而且隨時可能被打斷,但這卻是做 fuzz test 的絕佳時機。Fuzzing 需要的專注度相對較低,因為大部分時間只是在反覆嘗試把環境架起來。
對 openc2e 進行 Fuzzing
Nix 讓設定 fuzz testing 工作流程變得非常容易,我覺得大家還沒有意識到這點。
有一晚,我讀到一篇關於 針對 Facebook 發布的某個隨機開源工具程式進行 fuzzing 的文章,於是 花了一個小時用 Nix 重現了那個 fuzzing 工作流程。
幾天後的一個晚上,我花了幾個小時 為 openc2e 撰寫一個 fuzzer(模糊測試器),openc2e 是 Creatures 遊戲系列的開源重製版。

openc2e 是 Creatures 遊戲系列的開源重製版。
1996 年推出的原版 Creatures 遊戲包含一套自訂的腳本語言及對應的虛擬機器。這個語言叫做 Creatures Agent Object Script (CAOS),它讓玩家可以為遊戲製作自訂擴充內容。
CAOS 是一種低階語言,看起來有點像組合語言:
SETS VA00 "he"
ADDS VA00 "llo"
DBG: ASRT VA00 eq "hello"
愛好者們已在 openc2e 中重新實作了 CAOS 直譯器,我懷疑從來沒有人對它做過 fuzzing。但它很值得拿來 fuzz,因為如果你安裝擴充套件,它會解析來自不受信任的第三方程式碼。
我先從針對 CAOS 語言的 lexer(詞法分析器) 進行 fuzzing,結果馬上就發現一堆當機。

僅僅 fuzzing 一分鐘,我就在 openc2e 中發現了 20 個不同的當機。
其中一個當機僅僅是因為一個沒有結尾的雙引號,這證實了我的懷疑:從來沒有人對這段程式碼做過 fuzzing。
* The following line crashes openc2e's CAOS lexer.
"
我提交了一個 pull request 來修復最簡單的當機,並附上單元測試來展示修復方式,但這個專案已處於半荒廢狀態,所以可能要過一段時間才能讓所有修復被合併。我希望他們最終能抽空審查,因為我覺得這個 PR 還滿不錯的。
Fuzzing 意味著你可以為所欲為
用 Nix 做 fuzzing 最有趣的一點,就是你可以隨意擺弄底層專案,而不會打擾到任何人。
當我嘗試對 openc2e 做 fuzzing 時,我發現我想連結的程式碼被編譯成一個不利於連結的物件。我還在煩惱該怎麼連結時,突然意識到我可以直接 在自己的 repo 裡 patch 他們的 Makefile,想怎麼改就怎麼改。
通常,當我對一個開源專案做出貢獻時,如果想做像把私有函式庫轉為公開這類大幅度的更動,我得花很多時間去理解它一開始為何被設為私有,然後再向維護者說明為何將其公開是合理的。但在做 fuzzing 時,我只是在自己的沙盒裡玩,可以隨心所欲地亂搞。
打造我的新開發用桌機
我正計畫對自己的軟體開發習慣做一次大幅度的轉變:我要重新像個正常人那樣寫程式了。
大約從 10 年前開始,我發現用 Linux 開發軟體比較容易,但主要作業系統仍偏好 Windows。我的解法是在 Windows 桌機上用 VirtualBox 跑 Linux VM。我為每個專案建立獨立的 VM,以避免依賴衝突(例如我的 Python 2 專案搞亂 Python 3 專案)。
到了 2017 年,我厭倦了每次重開 Windows 系統就得把所有 VM 全部重開,於是 打造了我的第一台 homelab VM 伺服器。
到 2019 年,我已經完全改用 VS Code 搭配 Remote SSH 來開發,雖然大致上可行,但這種作法有點非主流,偶爾還是會出些問題。
接著,在過去一年中發生了兩個變化:
- 我發現自己想要的軟體幾乎在 Linux 上都有了。Microsoft 在 Windows 中日益侵擾的遙測與廣告讓我越來越受不了,所以我已經準備好要跳槽到 Linux。
- 自從發現 Nix 中的 per-project environments(單專案環境) 後,我就不再使用 per-project VMs,而是全部在安裝了 Nix 的單一 Debian VM 中開發。
這兩個變化意味著我不再需要 VM 伺服器或 Windows 桌機。我打算整合成單一一台跑 Linux 的桌機,並安裝 NixOS,因為過去幾個月來我在 Framework 13 筆電 上使用 NixOS 的體驗很不錯。
我用一種經濟上負責任的選擇——把兩台機器縮減為一台——來說服自己在新系統上超額花費是合理的:
| 零組件 | 舊桌機 | 新桌機 |
|---|---|---|
| CPU | Intel Core i7-4790K | Ryzen 9 7950X |
| 主機板 | ASRock X99 Extreme4 | Gigabyte X870 Aorus Elite |
| 顯示卡 | ASUS GeForce GTX 970 STRIX 4GB | MSI RTX 4060 Ventus 2X 8GB |
| 記憶體 | G.SKILL Ripjaws 4 32GB DDR4 | G.Skill Trident Z5 RGB 64GB DDR5 |
| 儲存裝置 | Samsung 980 PRO 2 TB | Crucial T705 2TB |
| 機殼 | Cooler Master HAF 912 | Fractal Design Define 7 Compact |
| 電源供應器 | Corsair HX750i 750W | SilverStone Platinum PS-ST55F-PT 550W |
| CPU 散熱器 | Noctua NH-U9DXi4 | Noctua NH-U12S redux |
| 螢幕 | LG 34UMP95 34" | Samsung Odyssey OLED G9 49" Ultrawide |
| 螢幕支架 | AmazonBasics Monitor Arm | Ergotron HX HD |
在我的工作流程中,磁碟往往是最常遇到的瓶頸,所以我在這部分選了最頂級的,雖然感覺有點奢侈。我只需要一顆系統碟就好,因為大部分資料都在我的 儲存伺服器 上。
CPU 速度很快,但不是最頂級的。買 CPU 時,我會看跑分,盡量挑效能達到頂規 80% 到 90%,但價格只有頂規一半或更少的產品。
最奢侈的是螢幕。這是一台誇張的 49 吋超寬 OLED:

49 吋的 Samsung Odyssey G9 是我的新桌機中最奢侈的部分。
我清楚記得 11 歲時的那份喜悅:爸爸從 CompUSA 帶回一個箱子,裡面是當時市面上最大的螢幕之一,大概是一台 17 吋的 CRT。他解釋說:「考慮到你會花這麼多時間盯著螢幕,我們不如投資一台好一點的。」補充一下,我的父母都是程式設計師,從小我就把大部分空閒時間花在電腦前。
從那之後,我就一直用爸爸的邏輯來合理化購買高階螢幕的花費,而且效果一直很好。我一年在電腦前要花 2500 小時,以每小時成本來算,高階螢幕的花費根本微不足道。
更何況,既然已經體驗過在 5120x1440 解析度下瀏覽 Hacker News,就再也回不去了。

沒用 5120x1440 解析度瀏覽過 Hacker News,就不算真正逛過 Hacker News。
學會使用超寬螢幕
我的新電腦零組件還沒全部到齊,但我已經先把新螢幕架起來了。我很快就意識到,需要一套新的桌面視窗管理策略。
我的舊螢幕是 34 吋,我大多用 Win+Left / Win+Right 把視窗貼齊到桌面的一半寬度。有了新螢幕的 5120px 寬度,我想一次貼齊兩個以上的視窗。
我試過 Komorebi,但覺得太複雜。接著我找到了 Fancy Zones,它完全符合我的需求。它讓我透過圖形介面定義區域,然後就能用快捷鍵或滑鼠把視窗停靠到那些區域。
以下是我的四個區域:
- 1000x1440px - 主要 VS Code 視窗
- 1000x1440px - 次要 VS Code 視窗
- 1560x1440px - 主要網頁瀏覽器視窗
- 1560x1440px - 次要網頁瀏覽器視窗
我通常只會停靠網頁瀏覽器和 VS Code 視窗,其他的一律當作短暫使用的浮動視窗。
把 VS Code 限制在 1000px 寬度很有幫助,因為我偏好只開啟編輯窗格。如果有更多空間,我就會不小心一直開著檔案總管之類的其他面板。但在 1000px 下,我偶爾還是會打開側邊面板,但會明顯感覺到佔位,提醒自己用完就關掉,回到專注於主編輯窗格的狀態。


VS Code 開啟側邊面板(左)與僅開啟編輯器(右)的對比
我原本也不覺得自己會在意 OLED 與 LED 的清晰度差異,但實際上我很欣賞其中的不同。黑色更黑,讓畫面感覺更銳利。
同樣地,我原本也不覺得自己會在意更新率,但我確實注意到 60 Hz 與 120 Hz 的差異。這台螢幕支援 240 Hz,但 Windows 不知為何沒有顯示這個選項,所以我打算切換到 NixOS 後再來研究看看。
總結
完成了什麼?
- 清理了部落格大量的樣板與 CSS 程式碼,並重新整理了 首頁。
- 為新的主力桌機工作站挑選並訂購了零組件。
- 為 《重構英文》 處理設計相關元素。
- 發布了一篇關於 如何在 NixOS 上運行簡易服務 的快速教學。
經驗教訓
- 能讓你對其他專案套用自訂 patch 的工作流程,會帶來一種愉快的自由感。
- 你可以為所欲為,因為這些更動只會影響你自己。而如果工作流程讓 patch 變得容易,你就不會覺得打造一個特殊版本的程式碼是種負擔。
下個月的目標
- 完成 《重構英文》 的兩個章節。
- 與設計師合作完成 《重構英文》 的封面設計。
隨機一篇部落格