陪产假:第 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 上玩得非常开心。
11 月的大部分时间里,我会在等待三个月大的孩子夜间第一次醒来前的几个小时里独处,这段时间可能是在我们哄他入睡后的 1-4 小时内的任何时候。在这段时间里,很难集中精力编程,因为我白天已经很累,而且随时可能被打断,但这却是做 fuzz testing 的绝佳时机。Fuzzing 所需的专注度相对较低,因为主要是反复尝试把环境搭建起来。
对 openc2e 进行 Fuzzing
Nix 让搭建 fuzz testing 工作流变得很容易,而我觉得全世界还没有意识到这一点。
一天晚上,我读了一篇关于 对 Facebook 发布的一个随机开源工具进行 fuzzing 的博文,于是我 花了一个小时用 Nix 复现了那个 fuzzing 工作流。
几天后的晚上,我花了几个小时 为 openc2e 编写了一个 fuzzer,它是 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。但它很值得进行 fuzzing,因为如果你安装了第三方扩展,它会解析不受信任的第三方代码。
我从对 CAOS 语言的词法分析器进行 fuzzing 开始,立刻就发现了一堆崩溃。

在 fuzzing 开始的一分钟内,我就在 openc2e 中发现了 20 个不同的崩溃。
其中一个崩溃仅仅是因为一个未闭合的双引号,这证实了我的猜测:从来没有人对这段代码进行过 fuzzing。
* The following line crashes openc2e's CAOS lexer.
"
我提交了一个 包含单元测试来演示修复的 pull request,以修复最简单的崩溃,但这个项目处于半废弃状态,所以可能要过一段时间才能让我的所有修复都被合并。不过我希望他们最终能抽时间来审查,因为我觉得我的 PR 很不错。
Fuzzing 意味着你可以为所欲为
用 Nix 进行 fuzzing 最有趣的一点是,你可以随意摆弄底层项目而不会打扰到任何人。
当我尝试对 openc2e 进行 fuzzing 时,我意识到我想链接的代码被编译进了一个不便于链接的目标文件中。我正想着如何链接这段代码时,突然意识到我完全可以在自己的仓库中 给它们的 Makefile 打补丁,想怎么改就怎么改。
通常,当我为一个开源项目做贡献时,如果我想做一个重大的改动,比如把一个私有库改为公开,我得花很多时间去理解它一开始为什么是私有的,然后再向维护者说明为什么导出这个库是合理的。但对于 fuzzing,我只是在自己的沙盒里折腾,可以随意摆弄任何东西。
组装我的新开发台式机
我正计划对自己的软件开发习惯进行一次重大转变:像一个普通人那样写代码。
大约从 10 年前开始,我发现在 Linux 上开发软件更容易,但我仍然更喜欢把 Windows 作为主力操作系统。我的解决方法是在 Windows 台式机上通过 VirtualBox 运行 Linux 虚拟机。我为每个项目使用单独的虚拟机,以避免依赖冲突(例如,我的 Python 2 项目搞乱我的 Python 3 项目)。
2017 年,我厌倦了每次重启 Windows 系统时都得重启所有虚拟机,于是 搭建了我的第一台 homelab 虚拟机服务器。
到 2019 年,我已经完全通过 VS Code 和 Remote SSH 进行开发,这在大多数情况下都有效,但偶尔也会因为这种不常见的方式而出现问题。
然后,在过去的一年里发生了两个变化:
- 我意识到我想要的所有软件在 Linux 上几乎都有了。我对 Microsoft 日益侵入性的遥测和 Windows 中的广告越来越感到厌烦,所以我准备切换到 Linux。
- 自从我发现了 Nix 中的 per-project environments 之后,我就不再使用按项目划分的虚拟机,而是在一个安装了 Nix 的 Debian 虚拟机中进行所有开发。
这两个变化意味着我不再需要虚拟机服务器或 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% 但价格只有顶级产品 50% 或更低的产品。
最大的奢侈是显示器。这是一台荒唐的 49 英寸超宽 OLED 显示器:

49 英寸的 Samsung Odyssey G9 是我新台式机中最大的奢侈品。
我清楚地记得 11 岁时的喜悦,那时我的父亲从 CompUSA 回来,递给我一个装有当时能买到的最大显示器的盒子,那大概是一台 17 英寸的 CRT 显示器。“考虑到你盯着显示器的时间,”他解释道,“我们不如投资一台好的。” 需要说明的是,我的父母都是程序员,从小我就把大部分空闲时间花在电脑前。
从那以后,我就一直用父亲的逻辑来为购买高端显示器辩护,而且效果一直很好。我每年在电脑前要待 2500 个小时。按每小时计算,高端显示器的成本几乎可以忽略不计。
而且,自从我在 5120x1440px 分辨率下体验过 Hacker News 后,就再也回不去了。

只有在 5120x1400px 分辨率下浏览过 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 上运行简单服务 的快速教程。
经验教训
- 允许你对其他项目应用自定义补丁的工作流会带来一种自由的愉悦感。
- 你可以为所欲为,因为这些改动只影响你自己。而且如果你的工作流让打补丁变得容易,你就不会有构建特殊版本代码的负担。
下月目标
- 完成 《重构英语》 的两个章节。
- 与设计师合作完成 《重构英语》 的封面设计。
随机一篇博客