2025 年 11 月记事板

12 日

晚上课上来写一点吧,有必要稍微给近期做的一些事情做一个总结。

体测

前阵子去体测了一下,总体来说成绩是三年来最好的,除了 1km。

测了测身高,看来我是超不过一米八了。这个身高就很尴尬,别人问的时候不好意思讲一米八,实话实说后别人又会说没一米八吗。背也好酸。

体重可喜可贺减小了一点。不过带来的连锁效应是 BMI 差点拿不了满分了。

除了 1km 外的成绩全都是三次体测以来最好的。1km 我是真没法子了,叹息。不过饶是如此,成绩也是比大一的要好。

但这次体测我也验证了一件事情,确实计时偏少,而且其实都不能叫「偏」,因为照我的计时起码少了十秒,跟我一年前的计算是一个量级的(很难想象我要用「量级」形容)。不太可能是因为从最后一个出发的人开始计时导致的,因为我是从人群中间出发的,而上一次人比较少在比较前面。但我也懒得计较这么多了,毕竟体测成绩能高一点。

引体在体测前两周吧开始复健,拉了十个后就没力气了。而后几天手臂都非常非常酸痛,一直到体测那周初,于是我只好把一阶段体测从原定的周三改到了周六,而周日就是二阶段(两个跑步)。

问了问顾问,这个是「延迟性肌肉酸痛」,属于是长时不锻炼的正常现象。了解后感觉我后面跑步前都要拉几下引体了,总不能每次都是提前一两周复健吧。然后果然逐渐好了,于是体测前几天基本上就是每天来拉 15 个。

体测的时候拉了 25 个。跟之前想的一样,想尽可能多拉几个看看能不能多加分。然后到 24 后已经基本没力了,但也是为「凑整」凑了个 25,这个是真拼尽全力的一击。

然后我想了解一下能加多少分,总不能是无限度的吧?就去查了一下,也是我体测以来第一次查询计分。震惊地了解到,居然多拉一个加 1 分,上限居然有 10 分之多?!顿时感觉自己亏了好多分。

虽说我现在拼尽全力也就 25 个,但我不觉得 30 个是什么难事,只不过需要更早一点的复健罢了。这真是亏炸了,我要之前知道能加这么多,那肯定每次提前一个月开始练,爽爽加满。

上面还说到改期,因为周日是二阶段跑步,而周内又要上课,就选定了周六。结果周六那天体测后我再看一遍,发现报成鼓楼的了……不仅是鼓楼的,还是二阶段跑步……

也管不了这么多了,测都测完了。而且跟去年一样,我直接拿身份证去刷了,应该问题不大吧?应该……

现在每天都会看看体测成绩,二阶段跑步很快就出了,但现在一阶段还是没有,有点担心。

按键

最近一直在写 Focust,因为待会要写到,想从按键角度了解一下,于是看了看 showKeyboard 数据。

有点意外地发现,10.2 的时候 J 以 8097 的次数拿下了第一,打破了此前 AppsKey 保持了半年多的数据,也成为第一个破 8k 的键。

真没想到,一年前的时候还在「惆怅」谁能破 6k,一年后 J 就破了 8k 了,真没有上限的吗?那我倒要看看是谁先能将 1w 这个标靶射落。

J 也算是彻彻底底雪耻了,一年前被 DownCtrl 羞辱,半年前被 AppsKey 羞辱,而现在它终于重夺第一的桂冠,也成为了 8k 里程碑的开拓者,成就了 6k, 7k 滑铁卢后的凯旋门。

也是一年多没聊聊按键世界了,现在一看才发现 J 家族已经这么强大了吗,现在的总额是 73w,牢牢坐稳第一家族的位置。

而之前提及的第一家族 Space 已经没落了,甚至不如 L

当初同一个层级的 CtrlShift 家族现在也依旧是相爱相杀,分别是 56w 和 55w,位居第二三。还有一个 50w 家族便是 J 的秦晋之好——K 了,以 50w 的资产堪堪进入第二集团。

第三集团就差远了,而且硬要算的话应该就只要 1 的 39w 和 BackSpace 的 37w。再往后就是 I 的 30w 与 L 的 29w,加上 Space 的 27w 与 Enter 的 25w。这些就是 25w+ 的了(U 有 24.7w,D 更是有 24.9w,非常接近了)。

其他的就没啥好说的了,没有非常突出的、能破之前纪录的成绩。像是应用什么的就不提了,因为 Scoop 的原因,也没法看总额。

另外挺意外 10.2 助力 J 登顶的,于是看了看那天我做了些什么:原来是在写编译原理实验,那天交了有几十次吧。不过还是有点夸张啊。

另外对比一下鼠标这块:右键 20w,左键 176w(其实说 176.999w),下滑滚轮 583w,上滑滚轮 177w。

Focust

一个晚上没能写完啊……因为写到一半之前遇到的一个窗口冻结问题又来了,结果去看日志发现日志丢了,没能找详细日志排查,又去折腾了点别的修复,心累……

13 日

Focust

那今天继续来写吧,虽然摆了大半个晚上时间已经所剩无几了。

从程序员日的 10.24 我写下下面两段话以来,已经过去差不多三周了。而这三周以来,除了刚开始在探索其他方向(试了试其他 GUI 框架),后面回归 Tauri 方案并不断迭代完善与代码审查没有提交,以及刚开始那周周末摆了两天啥事没做外,每天都有 commit,而且均摊下来有日均 10+ commits。

  • 然后最后想到又是月底了,高级请求才用了 30% 左右吧,于是 Focust 走起!
  • 现在效果真不错了,还是用 Tauri 方案,VC 了一晚上,到现在可以正常打开设置界面了,而且挺美观的,还得是 Web,同时还加了不少测试,都能通过了,感觉可以继续推进 Focust 了。但这周不能继续弄了,必须要正事搞完才能继续。

这三周以来也真的是像是找到目标一样非常投入,几乎无时不刻不开着 VS Code 在写代码,即便是到这周也是如此。在写 Focust 前我基本上又回归了开摆的状况,每天就是混日子般度过。

洗完澡回来困了,一直在摆了,看来今晚又写不了多少了。

沉迷 coding 到连着三周的课上都一直在写了,一点课没听。本来 Focust 刚重启的时候我差不多把近期的事情做完了,因此倒也比较闲,有机会全身心投入 Focust。结果到现在已经倒欠不少事情了,尤其是期中已过,临近期末,按理来说我应该准备 Anki 了。

虽然本来这学期也没咋听课,但课上好歹会跟着进度搞笔记、审查一下内容的,结果现在也是没怎么做。

但不得不说,这也许是我大二以来最为投入的一个项目了,没有其他的约束,完全是在按照自己的设想、期望去做一件事情,不是功利、被迫的。这的的确确让我感到非常充实与愉悦。

像是 AI 写作业什么的我虽然身体已经屈服了,但心理上仍有点抗拒。而去实现自己的想法则完全不会有这样的顾虑,有的只是自己的想法在逐渐变成现实的欣喜与激动。

这也是跟目的有关。像作业什么的目的并不是单纯地完成一份作业而已,而是从中学到点什么,不一定是知识,也可能是期末考点。

而一个我自己的想法、灵感,目的就是将其变成一个真正的产出。不管是什么方式,好用的就够了。

而这个灵感其实并不久远,就在暑假。暑假刚开始确实是摆了,但我也雄起过几天。打算好好改一改习惯,健康生活一点。

于是我意外了解到了 Stretchly 这个软件。简而言之就是一个定期让你从屏幕中脱离出来休息的软件。虽然说我后面没怎么用,但那几天还是有稍微遵循一下子的,只是后面就萎了。

本来也没什么想法,但是我感觉这个 Stretchly 有一些不好用的地方。

例如说我任务管理器打开,发现居然即便在后台,Stretchly 都要占据 100M+ 的内存。于是去看了一眼,果然是 Electron。

此外还有一些功能,是只有贡献者才能进行设置,这我也有点不爽。但后面好像搜源码得知了在哪里,然后可以轻松地通过 Ctrl + Shift + I 打开控制台修改元素显示出来。不过其实我也没有试用那些选项。

此外还有后面我还摸索出一个作弊机制,即便是暑假后期还一直开着这个软件,即便开了严格模式,依旧一弹出休息我就能秒关掉(有 Focus 那味了)。这个方式就是 Win + L 进入锁屏,然后再快速输入 PIN 回来。刚刚试了一下 Focust,不会。不过这个行为似乎可以通过 Stretchly 设置修改?但我也没试过。

然后还有就是计划了,我感觉 Stretchly 没有计划这个,也是一个缺陷。即便我个人用不到,但我想到了这应该是一个挺重要的思路。

同时我又想到,休息提醒是动态的,但我可能也需要一个静态时间的提醒。而这也就孵化成了 Focust 的 Attention 概念。

于是在我亲自体会到了这些缺陷后,突然便灵光一闪——我要自己写一个这样的软件,同时框架就定为我草草听说过的 Tauri——而这,也便是 Focust 的最初灵感由来。

14 日

Focust

灵感迸发的时候的感觉,就跟当初 AntsVsSomeBees 想到用 Web GUI 一样,是豁然开朗、柳暗花明。

翻了一下,正式开始写代码与构思是在 7.10,正好是 Git 那篇博文后一天,无缝衔接一件颇有意义的事情。

当然我在上个月最后的记事中也提过,一开始还没怎么用助理。我都是先写个 prompt 给顾问让它进行技术选型与提供代码架构。然后翻了一下最早的 prompt:

……我想用 Rust 重写并增强一下 Stretchly 这个休息时间提醒应用程序作为一个个人实践的练习品……

……目前的技术选型是 Tauri 框架 + TypeScript + Vue。前端工具我用的是 Bun……

……具体而言,我首先希望能够复刻 Stretchly 的全部功能,然后对一些功能进行改进。例如说 Stretchly 仅支持几种主题色,我想支持更自定义的(更自由的主题色选取、可以使用图片或者图片文件夹,甚至可以使用图源如必应等);还比如说 Stretchly 不支持设置多种「计划」,例如某个时段开启,这样就不用手动关闭了,而我想支持多种计划,可以在不同时间段配置不同的一些设置如休息时间等……

我是一个比较喜欢使用新技术的人,因此在很多个人甚至我主导的团队作业中都会用比较新的工具。

看上面的 prompt,除了图源没有实现外,其他基本上都是完美实现了。图源这个要实现应该问题也不大,只不过我翻了一下最早的数据结构提交,那会虽然标注了图源,但实际数据结构中并没有涵盖。我想可能也是想先实现比较基础、简单的,这个可以作为后续扩展。当然现在我有点累了,短时间内不想加新功能了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#[derive(Serialize, Deserialize, Debug, Clone)]
pub enum BackgroundSource {
Solid(String),
ImagePath(String),
ImageFolder(String),
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct ThemeSettings {
pub background: BackgroundSource, // Background source type, e.g., Solid, ImagePath, ImageFolder, ImageProvider
pub text_color: HexColor, // Hex color code for text, e.g., "#FFFFFF"
pub blur_radius: u8, // Radius in pixels for background blur
pub opacity: f32, // Opacity level from 0.0 to 1.0
pub font_size: u8, // Font size in pixels
pub font_family: FontFamily, // Font family name, e.g., "Arial", "Roboto"
}

这里就不讨论技术细节了,我有时间的话会另开一篇博文,记录一下 Focust 迭代过程中的一些事情。我觉得还是有必要记录一下的,纸上谈兵与实操真的是完全不同,只有实际投入去完成一个项目,才能体会到教程、顾问参考中不会涉及到的一些方面。

虽然说像找到了方向一般,但其实并没有这么顺利。否则的话,那不应该是暑假就搞出来了吗?为何等三个多月后的十月底,进度才突飞猛进?

一个原因当然是因为当时太摆了,在「看票」。但主要原因其实是我推进不下去了。要不然的话也不会 7.16 完成了暑假的最后一次提交了。

刚开始肯定是先实现一下后端,而后端的调度器也是重中之重。我在有了构思后的第一想法就是构造一个调度器,动态地计算出下一次事件的时间,然后等待到那时候再触发。而不是一个轮询检查,像 Stretchly 那样。

因此我一开始也主要投入在调度器上,咨询了顾问很多细节,最终搓出来一个非常初期、简陋的调度器。

现在看来的话这个调度器其实设计得非常的粗糙、简陋、耦合。它将大小休息、提醒与系统通知这四个事件在一个调度器中进行了调度,然而休息与提醒本来是两个差异很大的事情:休息是动态计算的时间,可能会被推迟、因暂停而重置、跳过等等,但不管如何,提醒都是一个确定的时间。这注定了它们在调度逻辑上的差异。因此在一开始将它们视为等同并一同进行调度,其实是一个挺差劲的设计。

但我也觉得不应该苛责,在当时我是真沉浸在「这真是一个绝妙的设计」的泡泡当中,感觉对比一个 setInterval 不要太叼了。真正意识到这种耦合的设计的缺陷的时候,是在我不断完善调度器、尝试添加新功能的时候注意到了。而在这种情况下我意识到了这个问题,并当机立断进行了重构,这也便够了。

过早优化是万恶之源。虽然说这其实是设计上的缺陷,但如果一直在不停地尝试完善设计,而原地踏步,那其实反而局限了视野。我受到的历练确实不够多,因此一开始没能觉察出设计上的缺陷,同时身处信息茧房当中,顾问也不会提及相关的事情。这个是没办法在起点就发现的,我必须真正将其应用,才能意识到问题。

写到这里,我想到最初的 prompt 还有这么一句:

但是毕竟我没有相关经验,我有设计不足恐惧症——总想在设计阶段尽善尽美,唯恐后面需要大规模重构——需要你给予我详细的开发指引,告诉我该如何一步一步完成,包括但不限于前期设计规划以及实际开发过程。最好是有具体的安排表,同时每个步骤都清晰、详尽地说明。

四个月后再看到这一句着实是有点感叹。这三周已经见证了我好几次大规模重构。确实,这让我身心俱疲,加上基础功能已经完善了,也打算逐渐从中抽身了。但也不得不说,我也好几次感叹新设计的精妙之处。

顾问是怎么回复的呢?

……但解决它的最好方法不是在开始前就设计出完美的系统(这几乎不可能),而是设计一个有良好扩展性的核心,然后通过迭代去完善它。

完成比完美更重要,尤其是对于个人项目,一个拥有 80% 功能的、已完成的应用,远比一个停留在设计阶段的、100% 完美的「空中楼阁」更有价值。

根本原因在于,你正在尝试在脑海中一次性构建并连接整个复杂的系统。你看到了调度器、状态、配置、UI 之间的所有依赖关系,这让你感觉无从下手,因为任何一点的改动都可能影响全局。解决方案不是做一个更庞大、更复杂的计划,恰恰相反,是将问题分解到极致,并采用「积木式」的开发策略。

另外 7.12 的时候我也对整个项目的架构感到有一些恐惧,认为有很多地方都困扰着我,「总感觉实现正在看的这个要先额外实现其他的」。从而向顾问发问「如何在实际写代码之前进行详细规划设计呢?」。而下面是顾问的回答:

这种「感觉要实现 A,就得先完成 B 和 C」的困境,通常被称为「依赖地狱」或「分析瘫痪」(Analysis Paralysis)。

根本原因在于,你正在尝试在脑海中一次性构建并连接整个复杂的系统。你看到了调度器、状态、配置、UI 之间的所有依赖关系,这让你感觉无从下手,因为任何一点的改动都可能影响全局。

解决方案不是做一个更庞大、更复杂的计划,恰恰相反,是将问题分解到极致,并采用「积木式」的开发策略。

现在看来确实是至理箴言,但我当时虽然看进去了,却不太能理解。最初我不断打补丁、完善的调度器核心设计,在现在的我看来简直跟垃圾没什么两样,这想必是当时的我难以预见的。

但我要是一直死死地抱着那个垃圾不放,只是一直在上面细致地进行雕琢,也不会有现在的 Focust 了。

这不是说现在的 Focust 就是一块璞玉,恰恰相反,在未来的我看来这可能还是跟垃圾没什么两样。但是它跟最初的垃圾比起来,那就是它是一个完成品,是一个真正能解决我需求的垃圾,一个垃圾的完成品总比一个垃圾的设计好。

我最初的思维困境其实源自一个错误的认识,那就是一个好的成品必须源自一个好的设计。当然,这一定程度上没错。但是谁也没有预知未来的能力,我也经验尚浅,无法预知未来可能的拓展与修改,而这些都是需要在实践中积累的。因此好设计就够了,它用不着足够好、非常好,它只需要好到能启动就够了。

实际上一个好的成品源自一个垃圾的成品,一个垃圾的成品源自一个垃圾的设计,而停留在思路与稿纸的设计都是垃圾。一个好的设计应当是好的产品反过来印证的。

应该说多亏了助理。如果不是助理的帮助的话,我应该还在不断给调度器修修补补。这个垃圾的框架、能够让我在上面进行迭代的垃圾,就是由助理搭建的。

那么来看看我在完成调度器的基本实现后,进行了怎样的修修补补吧。不过最初的修修补补其实大多发生在提交之前,因为我想提交一个「完美的最终版本」,所以下面只能记录提交之后的了:

  1. 给命令加了个 Deref trait 实现,就不用 .0 了。
  2. 自这个开始,下面都是这学期开始后的了:修复了 Clippy 警告。
  3. 将事件解耦了,这是隐约感知到了调度器的耦合,但没完全意识到,想着是将事件的来源拆分出来,但还是共用一个调度器。
  4. 加测试。

当然,这期间其实还涉及了别的一些地方的小打小闹。不过比较令我惊讶的可能是一开始我其实就支持了 User Idle,也就是空闲时间检测。也许是因为在设计之初我就觉得有点棘手了,因此在最开始我就了解了一下解决方案,并写了一个 spawn_idle_monitor_task,作为一个异步任务检查。当然这个我没啥好的解决方法,只能轮询了,毕竟也没事件,只是将轮询间隔设置为了 10s,而不是像 Stretchly 用的 1s。因为我感觉这个有点误差没啥区别,平均也就多个 5s。而你空闲五分钟(默认设置)跟空闲五分五秒还是十秒,其实没啥差别。而这个随便写的 monitor 也在后续我支持 DND 与应用排除后,变成了 Monitor 模块。

感觉要是不细谈代码细节方面的事情的话,也没啥好说的了。那就这样吧,有时间回顾一下。

闲人

感觉我这个大学上的真对不起学费,明明学费是其他专业的两倍,结果给自己越学越闲了。

没错,这学期再创新纪录了,峰值只有 23 节课时一周(还只会持续一周),而现在正是课时最少的时候,并一直会持续到期末,只有 17 课时一周。

这固然跟我提前修了《机器学习》有关,但即便算上去,那还是少之又少。因此我感觉跟其他同学,甚至是同专业(不同校)的其他同学相比,我真可谓是一个闲人了。

另外说起来,上周机器学习课的时候,我没去上课,结果辅导员签到,让我首次登上了未签到人员名单中。看起来是直接拿着学院名册点名的,说起来去年上课的时候我也是跟着他们一起签到的。为了避免出什么意外,私戳辅导员解释了一下。结果第二天辅导员气势汹汹地私聊问我怎么没去上课,要做出解释什么的,吓我一大跳。一点进去,撤回了……

不过刚开学的时候倒不是这样的,那会峰值是有 29 节课时的,这是我退了两节课后的成果。

一开始不太懂啊,专业选修就全点上了呗。结果上了一周统计了一下期末,没把我吓死,居然有这么多期末(但好像没大一的时候多?那时候真超人啊)。而且算了算学分,发现似乎超学分了,加上还有项目压力什么的,我就果不其然怂了。

然后详细介绍了一下情况,跟顾问商量,最终退了一门课——《移动互联网应用开发》。退的理由倒也很朴素,有期末 + 项目,而且是鸿蒙应用开发。

说实话我一开始选这个课一个原因确实是想学习一点移动应用开发的知识,不过鸿蒙开发这个确实是让我有点望而却步了。

首先我肯定是支持进行鸿蒙开发的,需要开辟一个新的、自主的应用生态。但我是一个懒鬼啊,我畏难,尤其是这种文档、社区、经验、基础设施等什么的都不齐全的,确实是让我退缩了。

加上其实我没有非常大的动力进行,你像 Tauri 我也是硬着上了,这是因为 Focust 是我所欲。但我没啥移动应用开发的需求,我手机基本上是基础设施,已经够用了,并不需要额外的扩展什么的,同时我也没用鸿蒙,那就更没有什么动力去开发了。

让我比较意外的是,我把这个跟顾问讲后它没有顺着我,而是坚定的让我退掉。

与此同时,有一些顾问还建议我退掉第二门课——《人机交互系统》。当时一口气问了好几个顾问,基本上是异口同声说退掉《移动互联网应用开发》,但同时有一些顾问还建议退掉《人机交互设计》。

这也是一个项目 + 期末的。与前者不同是的,这个我半毛钱兴趣都没有,但按老师的说法,可以复用之前的项目。因此第一轮退课的时候我只退了前者,还是留着这个。

但最终还是退掉了。因为我对软工二的作品非常不满意,可以说完全是我随便糊弄的,即便花了不少时间精力在上面,但确实是没怎么用心。当然是因为我对这个项目不感兴趣,真的是一点爱都见不到。

因此我后面思考了一下,想直接复用应该是做不到的,很可能需要大规模重构。那还是算了吧,相当于把已经埋了的大便再刨出来塞嘴里再消化一遍,然后再拉一坨消化得更完全的大便。于是就退了。

这也就是为啥我这学期这么闲的原因了。

当然,那专业选修学分呢?根据我的计算,退了这两门后还差 4 分(不算那个 6,只算 18 那部分。6 那个已经拿 3 了,要拿也只有下个学期)。说实话,我后悔这个暑假没去上暑期了,要上了首先暑假不会那么摆,其次那就只差 3 学分了,只需要一门课就够了。而现在这个情况,想要两个半学期的课难度是比较高的,那最少也是一个完整的课再加一门别的了,保险一点的话下学期完成,那就是多了一门。所以现在就是非常后悔,没有计算一下。

看自己这般计算,全然没了大一时的随然,也是心中不免有些酸涩。但这又何尝不算是一种成长呢?

日本

这部分是在写开发记录的时候,去洗澡的时候偶然想到的。

最近日本很跳呐。真的感觉历史大事在逐渐大踏步而来了。

小时候的我似乎在日记本上提到过「安倍」。不过当时的我显然是不知道什么更多的内容,最多知道他是个日本首相。甚至当时其实我似乎是读成了 péi,甚至好像还写错了?(安培哭死)。

现在想来时间节点大概是 2013 年,钓鱼岛争议吧?我比较主动去了解世界政治,大概不是高中那也得是初中了。但是一个 8 岁左右的小孩也能对安倍这个人留下印象并记录到日记当中,着实让我有些吃惊。尤其是对比当时,U 型锁、砸日产车,而现在却是攻守之势异也,十三年河西都算不上。

又回想起 2022,安倍遇刺的时候。那时我应该是高二,记得似乎还在十几楼的宿舍收拾东西吧,似乎是准备回家还是怎的?然后同学突然就说,「安倍遇刺了」。当时我记得是小小惊讶了一下,但还是非常平静,停下收拾的行动,掏出手机开始看新闻。如果没记错的话,当时同学间似乎还笑着说「没有生还的风险吧」,后面果然就死了。到现在也三年多了,安倍都两岁大了。

不是怜悯日本,不是惋惜安倍,只是感叹时间飞逝,不管是我个人的、还是国家的。