9999个数字
终端的滚动条终于停下来的时候,天已经快亮了。
屏幕上幽暗的光打在键盘上,我揉了揉干涩的眼睛,点开了本地的输出文件夹。小电拼的代码跑完了最后一行,在这个漫长的深夜里,它悄无声息地吐出了9,999个数字的截图。我拖动着鼠标,一张张滑过去,心里那种熟悉的疲惫感又涌了上来。跑是跑出来了,但它们都没有找到那个正确的数字。
图像的边缘有些模糊,有一些因为渲染延迟出现了残影,还有一些甚至只截到了半个字符。质量不合格,意味着这九千多次的自动化操作全部作废,需要重新写脚本去复检。我靠在椅背上,没有觉得特别沮丧,只是平静地把文件夹打包,关掉了终端。
大四的收尾期,大概就是由这些细碎的失败和无休止的重构拼凑起来的。
以前我总觉得写代码是一件非黑即白的事情,跑通了就是赢了,报错了就是输了。在广州商学院的这几年,我几乎是用一种近乎执拗的姿态在对待这些非黑即白的东西。一个民办三本的学校背景,常常会让身处其中的人产生两种截然不同的状态:要么彻底躺平,要么卯足了劲去抓住些什么。我选了后者。
教务系统里那个4.02的绩点,两次国家奖学金的证书,还有那几个国二的竞赛奖项,曾经是我用来构建自我认同的砖瓦。在那些为了打比赛熬过的夜里,在图书馆闭馆时的音乐声中,这些确定的荣誉给了我很大的安全感。但现在,当毕业的倒计时真正开始跳动,面对一堆待重组的烂代码,那些外在的标签突然变得很轻。机器是诚实的,它不管你拿过几个奖,也不管你来自哪里,逻辑不闭环,边界条件没考虑清楚,它就只给你输出一堆不能用的废图。
关掉显示器,我起身去客厅倒水,脚下突然踩到了一团软绵绵的东西。
借着窗外透进来的路灯光,我低头一看,是一只不知道什么时候掉在地上的袜子。我爸正好起夜,趿拉着拖鞋路过客厅,看着我弯腰捡袜子的动作,打着哈欠随口说了一句,我们家大概是有什么传统,袜子乱丢这个毛病是你从你妈那里继承来的。
他进屋关上了门,留下我拿着杯子站在饮水机前,听着水流下落的轻微声响,觉得有些好笑。
软件工程里有一整套严密的体系去讲述面向对象、讲述继承和多态。在代码的世界里,父类的方法被子类重写,属性被严格地封装,哪怕少写了一个分号,编译器都会毫不留情地抛出异常。但在现实的家庭生活里,基因和习惯的继承却是以这种毫无逻辑、甚至有些滑稽的方式呈现的。
生活不是IDE,它没有严格的代码检查工具。它允许你把袜子丢在沙发缝里,允许代码跑出9,999个错误结果,也允许一个快毕业的软件工程学生在凌晨的客厅里端着水杯发呆。这种容错率,在某种程度上消解了我刚才面对那些废弃截图时的焦虑。
回到房间,桌角的那块墨水屏突然安静地全刷了一下,黑白翻转的瞬间,发出了微弱的电流声。
现在做墨水屏的设备越来越多了,以前那种只属于少数极客圈子里的折腾,似乎也开始慢慢出圈。我看着它屏幕上渐渐浮现出的画面,想起了最近一直在收尾的那个开源项目,InkTime。
它其实就是一个可以自托管的墨水屏电子相框。做这个东西的初衷并不复杂,甚至带着一点私心。在这个数字时代,我们制造了太多的数据垃圾。我的手机相册里存了几万张照片,从按下快门的那一刻起,它们中的绝大多数就被丢进了数字黑洞,再也没有被翻看过。
那些拿奖时站在台上的瞬间、写出第一个完美接口的深夜留念、或者某天下午我妈留在茶几上的一盘切好的水果,都被同等地压缩成了冰冷的数据块,躺在硬盘的某个扇区里沉睡。
InkTime的想法很简单,它试图用一种很慢的方式,去对抗这种遗忘。我给它写了一套逻辑,接入AI去分析和理解你的照片库。AI会在后台静默地运转,识别照片里的场景、人物、光影,甚至尝试去读懂画面里的情绪,然后为每一张照片评估出一个「值得回忆度」。
每天到了特定的时间,它会从「历史上的今天」里,挑出得分最高、最值得被记住的那一张,推送到这块不发光的屏幕上。
我把它的软硬件都开源了。在写Readme文档的时候,我一直在想,技术到底应该以什么样的姿态介入我们原本就足够琐碎的生活。LCD和OLED屏幕太亮了,刷新率太高,它们总是在用鲜艳的色彩和无休止的红点催促你往下看,去获取新的信息,去产生新的焦虑。
但墨水屏不一样。它很迟钝。它刷新的时候会缓慢地闪烁,像是在费力地回忆什么。而一旦画面定格,哪怕拔掉电源,那个画面也会一直留在那里。这很像记忆本身的质感,有些褪色,没有那么高的饱和度,但足够持久。
AI在代码里计算着权重,去揣测哪一个瞬间对苏增烨来说是最重要的。也许是四年前刚踏入广商校园的那张略带青涩的军训照,也许是备战国奖时桌面上散落的算法草稿纸,又或者是某次旅行中随意拍下的一片树叶。它希望让那些沉睡的记忆重新被看见,而不是被新的数据覆盖。
在这样一个大模型满天飞、算力过剩的时代,用最前沿的AI技术去驱动一块最原始、最迟钝的屏幕,仅仅为了每天展示一张旧照片。这看起来像是一种资源的浪费,但在我眼里,这大概是技术能给出的最温柔的解法。
外面的天已经彻底亮了。广州的清晨总是带着一点湿润的雾气,远处的马路上开始有了车流的白噪音。大四的宿舍楼安静得有些空荡,考研的同学去图书馆占座了,找工作的同学大概还在修改简历,剩下的人在梦里逃避着即将到来的社会时钟。
我重新坐回电脑前,把那个跑出9,999张废图的脚本拖进编辑器。指尖敲击键盘的声音在房间里回荡,我开始写复检的逻辑。先用OpenCV做一次边缘检测,过滤掉那些残影,再加一个简单的OCR去识别字符的完整度。思路其实很清晰,只是需要时间去一点点实现和测试。
生活和写代码真的很像,大部分时间都不是在创造奇迹,而是在修补和重构。
前几年的我总是急于求成,想要用完美的绩点和一堆奖项来证明自己的不可替代。但在这个漫长的大四收尾期,在这个被代码、家人和细碎日常填满的清晨,我反倒觉得平静了很多。那种因为出身普通而自带的紧绷感,好像随着这些跑废的数据和静静刷新的墨水屏,一点点消散了。
没有什么是一劳永逸的。荣誉最终会变成相册里的一张旧照片,也许在未来的某一天,会被InkTime重新推送到我面前,提醒我曾经有过那样一段专注的日子。而那些像是从我妈那里继承来的乱丢袜子的习惯,大概还会跟着我很久,成为我生活里无法被重构的bug。
电脑风扇的转速又提了上来,新的一轮数据处理正在排队。我喝完杯子里的最后一口水,检查了一遍新加的函数,然后敲下了回车键。
终端的滚动条再次开始跳动,一行行日志快速划过。我没有再盯着屏幕看,而是转头看向了桌角的墨水屏。上面是一张很久以前拍的风景照,黑白的像素点安静地定格在那里。慢慢来吧,这九千多张图总会复检完的,那个正确的数字,也总会跑出来的。
