Paternity Leave: Month 4

Michael Lynch

育嬰假:第 4 個月

一句話總結

我得停止拖延了。

本月亮點

  • 我找到了各種方法來拖延寫書。
  • 我開心地對開源專案做 fuzz testing(模糊測試),玩得很盡興。
  • 我為軟體開發挑選了一台全新高階桌機的零組件。

目標成績

每個月月初,我都會宣告當月想完成的事。以下是本月的達成狀況:

享受家庭時光

  • 結果:持續享受家庭時光。
  • 評分:A

在這段自主安排的育嬰假期間,我持續在家庭時光與個人及專業專案之間取得平衡,並樂在其中。

完成並發表 Refactoring English(《重構英文》) 的一個章節

  • 結果:有撰寫章節,但沒有發表任何內容。
  • 評分:D

我當初設定這個目標時低估了難度。好幾年前我就開始寫其中一個章節,之後斷斷續續回頭修改。在我的記憶中,那個章節已經完成了 80%,但這次重新檢視時,感覺更像是只完成了 20%。

我把章節推進到大約 60% 的進度,但並沒有像原本可以那樣專注。

我得停止拖延寫書這件事

也許我需要新字型

我開始撰寫書的第一章,卻一直被網站平庸的設計分心。

我的書籍網站使用的是我自己做的一個簡單設計主題,基本上就是 Bootstrap 的預設 CSS 加上一些自行調整的樣式。我說不上來具體哪裡有問題,但整體看起來就是不太對勁。

我開始瀏覽自己喜歡的部落格和網站,並試著把他們的字型套用到我的網站上:

在書籍網站上看起來最適合的字型是 Concourse,這讓我進一步探索了 馬修·巴特里克 的所有字型。這是我第一次購買字型,而不是使用 Google Fonts 上的免費字型。我將 Concourse 用於標題,Heliotrope 用於內文。

我將 《重構英文》 網站的字型更換為 ConcourseHeliotrope

好看的字型帶來的差異讓我大吃一驚。感覺像作弊一樣,我完全不需要做其他設計更動,網站看起來就好了三倍。

也許我需要一個封面

換上漂亮的新字型後,我開始思考書籍封面的事。我本來就打算在出版前委託設計封面,既然如此,不如現在就著手。如果有一個好看的封面,會吸引更多人感興趣。於是,我寫了一份 封面設計規格說明,並聘請了一位設計師來執行。

也許我該回到之前的點子

幾天後,我收到一位讀者的來信,詢問是否可以付費取得 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(模糊測試器)openc2eCreatures 遊戲系列的開源重製版。

openc2eCreatures 遊戲系列的開源重製版。

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 來開發,雖然大致上可行,但這種作法有點非主流,偶爾還是會出些問題。

接著,在過去一年中發生了兩個變化:

  1. 我發現自己想要的軟體幾乎在 Linux 上都有了。Microsoft 在 Windows 中日益侵擾的遙測與廣告讓我越來越受不了,所以我已經準備好要跳槽到 Linux。
  2. 自從發現 Nix 中的 per-project environments(單專案環境) 後,我就不再使用 per-project VMs,而是全部在安裝了 Nix 的單一 Debian VM 中開發。

這兩個變化意味著我不再需要 VM 伺服器或 Windows 桌機。我打算整合成單一一台跑 Linux 的桌機,並安裝 NixOS,因為過去幾個月來我在 Framework 13 筆電 上使用 NixOS 的體驗很不錯。

我用一種經濟上負責任的選擇——把兩台機器縮減為一台——來說服自己在新系統上超額花費是合理的:

零組件舊桌機新桌機
CPUIntel Core i7-4790KRyzen 9 7950X
主機板ASRock X99 Extreme4Gigabyte X870 Aorus Elite
顯示卡ASUS GeForce GTX 970 STRIX 4GBMSI RTX 4060 Ventus 2X 8GB
記憶體G.SKILL Ripjaws 4 32GB DDR4G.Skill Trident Z5 RGB 64GB DDR5
儲存裝置Samsung 980 PRO 2 TBCrucial T705 2TB
機殼Cooler Master HAF 912Fractal Design Define 7 Compact
電源供應器Corsair HX750i 750WSilverStone Platinum PS-ST55F-PT 550W
CPU 散熱器Noctua NH-U9DXi4Noctua NH-U12S redux
螢幕LG 34UMP95 34"Samsung Odyssey OLED G9 49" Ultrawide
螢幕支架AmazonBasics Monitor ArmErgotron 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,它完全符合我的需求。它讓我透過圖形介面定義區域,然後就能用快捷鍵或滑鼠把視窗停靠到那些區域。

以下是我的四個區域:

  1. 1000x1440px - 主要 VS Code 視窗
  2. 1000x1440px - 次要 VS Code 視窗
  3. 1560x1440px - 主要網頁瀏覽器視窗
  4. 1560x1440px - 次要網頁瀏覽器視窗

我通常只會停靠網頁瀏覽器和 VS Code 視窗,其他的一律當作短暫使用的浮動視窗。

把 VS Code 限制在 1000px 寬度很有幫助,因為我偏好只開啟編輯窗格。如果有更多空間,我就會不小心一直開著檔案總管之類的其他面板。但在 1000px 下,我偶爾還是會打開側邊面板,但會明顯感覺到佔位,提醒自己用完就關掉,回到專注於主編輯窗格的狀態。

VS Code 開啟側邊面板(左)與僅開啟編輯器(右)的對比

我原本也不覺得自己會在意 OLED 與 LED 的清晰度差異,但實際上我很欣賞其中的不同。黑色更黑,讓畫面感覺更銳利。

同樣地,我原本也不覺得自己會在意更新率,但我確實注意到 60 Hz 與 120 Hz 的差異。這台螢幕支援 240 Hz,但 Windows 不知為何沒有顯示這個選項,所以我打算切換到 NixOS 後再來研究看看。

總結

完成了什麼?

  • 清理了部落格大量的樣板與 CSS 程式碼,並重新整理了 首頁
  • 為新的主力桌機工作站挑選並訂購了零組件。
  • 《重構英文》 處理設計相關元素。
  • 發布了一篇關於 如何在 NixOS 上運行簡易服務 的快速教學。

經驗教訓

  • 能讓你對其他專案套用自訂 patch 的工作流程,會帶來一種愉快的自由感。
    • 你可以為所欲為,因為這些更動只會影響你自己。而如果工作流程讓 patch 變得容易,你就不會覺得打造一個特殊版本的程式碼是種負擔。

下個月的目標

  • 完成 《重構英文》 的兩個章節。
  • 與設計師合作完成 《重構英文》 的封面設計。

原文由 Michael Lynch 發布

本文章由 muse-spark-1.2-contributor 進行翻譯