五点零四分,整层楼的灯开始一盏接一盏地灭。保洁阿姨推着清洁车走过工位,拖把在地上留下湿印子。拐角的感应灯随着她脚步亮一下,又暗了。陈峰没动,手指还在键盘上敲字,电脑右下角的时间变成了17:05。
他听见电梯“叮”了一声,有人进去,门关上,楼层往下走。接着另一部电梯启动,走廊尽头防火门被推开又关上。办公室安静下来,只有空调吹风的声音,还有他敲键盘的响动。
泡面桶放在显示器旁边,红烧牛肉味已经闻不到了,汤面上浮着一点油花。早上灌的保温杯还剩半杯水,早就凉了。他拧开盖喝了一口,放下杯子,戴上耳机。播放列表停在一首老歌,前奏是吉他声,他没换歌,把音量调到刚好能听清。
屏幕上是项目最后一块代码,函数有三层,接口还没通。他盯着光标闪的位置,右手食指在空格键上点了两下。左手伸进背包侧袋,摸出保温杯,又喝了口凉水。
肩膀有点僵。他往后靠了靠,双手举过头顶拉了一下,骨头发出咔哒声。低头转了转脖子,活动手腕,手指张开握紧三次。做完这些,他坐正身子,把泡面桶往边上挪了挪,腾出鼠标的地方。
时间到了晚上八点十七分,楼下车子少了。他去接水机换了一包新泡面,这次是酸菜牛肉味。热水倒进去,他站着等了三分钟,一边看面饼变软,一边揉太阳穴。回到座位后先吃了几口,面有点坨,他吃得很快,吃完把桶盖扣好,扔进垃圾桶。
九点四十三分,主流程第一次跑通。他点下运行,本地服务启动,页面加载出来,表单提交和数据显示都正常。但他没放松,打开测试文档,一条条核对。第十一条卡住了——用户权限改了,历史记录没更新。
他皱眉,摘下耳机,打开日志文件。一行行找请求头,比时间戳。发现是缓存问题:旧权限存在session里,刷新页面没重载。他回到代码,在登录的地方加了一句强制清空,保存,重启服务。
十一点零二分,第二次全流程测试开始。这次他没吃东西,从抽屉拿了一包薄荷糖,剥一颗含嘴里。凉意冲上来,脑子清楚了些。他看着页面跳转,用笔在便签上做记号。全部走完,系统弹出绿色提示:“所有测试项通过”。
他靠在椅背上,长长呼出一口气,胸口那股闷气终于散了。但还没完。他知道上线前还得测异常情况,就做了几组极端数据:超长用户名、空内容提交、多人同时操作……一个个试。
凌晨两点十五分,城市彻底安静。窗外只剩零星路灯和对面楼几个亮着的窗。他眼睛发干,眨一下觉得累,但手还在动。最后一次失败是因为数据库连接不够,压力测试时崩了。他调大参数,加上自动回收,再跑,稳住了。
三点四十分,最后一轮验证完成。屏幕上那个绿色“全部通过”静静待着。他看了十几秒,没动,也没笑,只是把手从键盘拿开,平放在桌边。
泡面桶早扔了,保温杯空了,耳机线挂在椅子扶手上。他抬头看天花板,又低头看自己的手——指甲边裂了,右手食指因为一直敲键盘有点酸。他动了动手指,确认还能动,然后慢慢抬起右手,轻轻碰了下右耳的小痣,像是在告诉自己:真的做成了。
窗外天色变了。不是亮,是黑得淡了些,楼缝间的天空泛出青灰色。远处有环卫车发动的声音,低低响一下,又停了。他没看手机,也不知几点,只觉得全身像被掏空,累得很踏实。
他把代码提交到主分支,写上备注:“v1.0 完整功能闭环,测试通过。” 然后退出开发环境,关掉所有窗口。电脑屏幕黑下去的一瞬,他眨了眨眼,适应黑暗。
工位还是老样子:连帽卫衣搭在椅背,工装裤口袋里塞着螺丝刀和伞,桌上只有电脑、空杯和几张写满字的便签。他没收拾,也没起身,就坐在那儿,手放在膝盖上,看着黑掉的显示器。
屏幕映出他的脸:头发乱翘,眼下有黑影,嘴角有一点往上扬。很小,不细看看不见。但他知道他在笑。
城市还没醒。楼下街道空着,红绿灯自己切换,没人看,也没车过。他坐着不动,也不关灯。办公室只剩他这里亮着,像夜里唯一睁着眼的人。
他想起白天听的那首歌,记不住词,只记得一句:“事成了,就别问值不值。”
现在他觉得,好像也不用问了。
他伸手把耳机摘下来,轻轻放在键盘右边。然后缓缓吐出一口气,肩膀彻底松了下来。
显示器忽然闪了一下,屏保出来了,是一张旧电吉他的照片,琴身上贴着“已没收”的标签。他看了两秒,没动,也没关。
窗外,天边的青灰慢慢变浅,像墨水被稀释。一辆早班车驶过路口,车灯扫过玻璃,一闪而过。
他仍坐着,手搭在椅背,眼睛闭了一下,再睁开时,目光落在屏幕上那行绿色测试结果上。
字很清楚。
他点点头。