走廊的声控灯暗了下去。陈默在黑暗里站了两秒,等眼睛适应。
工位区还亮着一盏台灯。灯罩压得很低,光晕圈出一小块桌面。
王涛趴在电脑前。屏幕蓝光映着他侧脸,下巴上冒出青黑的胡茬。
键盘敲击声又密又急,像雨点砸在铁皮上。
陈默放轻脚步走过去。桌上摊着本《分布式系统设计》,书页边缘卷得像咸菜。旁边摆着半个冷掉的汉堡,包装纸渗出发黄的油渍。
屏幕上是队列服务的配置界面。参数密密麻麻,光标在某个输入框里快速闪烁。
王涛没抬头。他盯着屏幕,嘴唇无声地翕动,像在默念什么。
陈默看见他左手小指在抽搐。一下,又一下,关节绷得发白。
“还不走?”陈默开口。
王涛肩膀猛地一抖。他转过头,眼睛里有血丝,瞳孔因为突然聚焦而收缩。
“陈哥。”他嗓音沙哑,“你还没回?”
“马上。”陈默看了眼屏幕,“配置调完了?”
“快了。”王涛转回去,鼠标滚轮飞快地上下滚动,“我在想内存队列的监控项,要不要加个……”
他话没说完,打了个哈欠。嘴巴张得很大,能看见后槽牙。
陈默闻到空气里有速溶咖啡的焦苦味。王涛手边那个马克杯已经见了底,杯壁糊着深褐色的垢。
“明天再弄。”陈默说,“沈总立的军令状,不是让你今晚就拼命的。”
王涛手指停在键盘上。他盯着屏幕,喉结滚了滚。
“我知道。”他说,“但我得先把架子搭稳。张猛那边同步链路优化得差不多了,我不能拖后腿。”
他说“拖后腿”时,声音压得很低。
窗外又过去一辆车。车灯的光扫过天花板,留下一道转瞬即逝的白痕。
陈默拉开旁边工位的椅子坐下。椅面冰凉,透过裤子布料渗进来。
“你之前那个全异步方案。”他顿了顿,“是不是参考了‘星海’的开源项目?”
王涛身体僵了一下。他没转头,但后颈的肌肉绷紧了。
“嗯。”声音闷闷的,“他们那套设计很漂亮。”
“但‘星海’是百人团队在维护。”陈默说,“他们有专门的队列运维组,三班倒盯着。”
王涛不说话了。他手指无意识地按着退格键,光标在输入框里一下下后退。
屏幕上的配置参数被删掉一行。
“我改过了。”王涛终于说,“轻量队列的方案,是我重新设计的。跟‘星海’不一样。”
他说得很快,像在辩解。
陈默没接话。他看见王涛右手手背上有个圆形的烫伤疤,颜色比周围皮肤深。大概是哪天泡面洒了。
台灯的镇流器发出细微的嗡鸣。那声音很低,但持续不断,钻进耳朵里就赶不走。
“回去吧。”陈默站起来,“睡一觉,脑子清醒了再改。”
王涛还是没动。他盯着被删掉的那行参数,眉头拧成疙瘩。
“陈哥。”他忽然说,“你是不是觉得……我扛不住?”
问题来得突然。空气静了一瞬。
陈默看向他。王涛侧脸绷着,下颌线咬得很紧,像在等一个判决。
“军令状是你自己应的。”陈默说,“扛不扛得住,你自己最清楚。”
王涛扯了扯嘴角,想笑又不像。“也是。”
他终于关掉配置界面。屏幕暗下去,映出他疲惫的脸。
“那我走了。”他站起来,膝盖撞到桌腿,发出咚的一声。
他没喊疼,弯腰抓起背包。拉链卡住了,他用力扯了两下,金属齿咬合的声音很刺耳。
陈默看着他走向门口。背影在昏暗的走廊里晃了晃,消失在转角。
工位区彻底空了。只剩那盏台灯还亮着,光晕孤零零地圈着桌面。
陈默走过去,按掉开关。
黑暗涌上来。
他回到自己临时的住处时,已经快十二点。是老小区的一居室,墙上贴着发黄的墙纸,边缘卷起,露出底下灰扑扑的腻子。
钥匙插进锁孔,转了半圈就卡住。陈默用了点力,才拧开。
屋里冷得像冰窖。暖气片早就坏了,房东一直拖着没修。
他脱掉外套搭在椅背上,打开笔记本电脑。屏幕亮起的光是屋里唯一的光源。
系统界面自动弹出来。团队状态栏里,王涛名字后面的黄色叹号还在。
陈默点进去。详情更新了一行:“持续高强度工作超过14小时,疲劳指数上升。失误概率预估:18。”
概率数字是灰色的,后面跟着一个小问号图标。
他尝试点那个问号。界面弹出一行提示:“非直接技术风险推演,置信度较低。建议结合实际观察。”
陈默盯着那行字看了几秒。他想起晚上开会时,系统对王涛心态的预警也是“短期输出可能不稳定”,很模糊。
系统在技术方案推演上精确到毫秒,但在人身上,就像隔着一层毛玻璃。
他关掉界面,打开项目进度表。张猛负责的同步链路优化显示绿色,已完成百分之八十。王涛的队列模块是黄色,百分之四十。
小主,这个章节后面还有哦,请点击下一页继续阅读,后面更精彩!
进度条旁边有个小备注:“今日提交三次代码,均未通过自动化测试。”
陈默点开详情。三次失败都是同一个原因:内存队列的初始化参数错误,导致服务启动后立刻崩溃。
提交时间分别是晚上八点、十点、十一点半。
一次比一次晚。
他往后靠在椅背上。椅背发出不堪重负的咯吱声。
窗外有野猫在叫。声音拖得很长,像婴儿哭。
第二天早上七点半,陈默到公司时,王涛已经在了。
他坐在工位里,面前摆着两个空咖啡罐。头发乱糟糟地翘着,眼睛肿得像核桃。
“早。”王涛哑着嗓子说,手指还在敲键盘。
陈默闻到空气里有薄荷糖的味道。很冲,盖不住隔夜的口气。
“通宵了?”陈默问。
“没,四点回去躺了会儿。”王涛揉了揉太阳穴,“刚把昨晚那个参数 bug 修了。测试过了。”
他说得轻描淡写,但敲键盘的手指在发抖。不是冷,是肌肉过度疲劳后的生理反应。
李薇和张猛前后脚进来。李薇拎着豆浆和包子,塑料袋窸窣响。张猛还是那件灰色卫衣,袖子挽到手肘。
“王涛你这……”张猛看见王涛的样子,话说到一半咽回去,皱了皱眉。
“没事。”王涛抢先说,“队列服务调通了,等会儿可以联调。”
他说着就要站起来,腿一软,又坐回椅子上。椅轮向后滑了半米,撞到隔板。
咚的一声闷响。
李薇放下豆浆,小声问:“你要不……先去睡会儿?联调我们可以先准备。”
“不用。”王涛抓着桌沿站起来,这次稳住了,“早弄完早踏实。”
他说完就往会议室走。脚步有点飘,像踩在棉花上。
张猛看向陈默,眼神里带着询问。陈默摇了摇头。
联调安排在九点。会议室的白板已经擦干净,画上了新的数据流向图。
王涛把笔记本接上投影。屏幕亮起,队列服务的监控面板跳出来。绿色指标一行行滚动,看起来很健康。
“我先跑个 deo。”王涛清了清嗓子,声音还是很哑。
他点开测试脚本。命令行窗口弹出,日志开始刷屏。
前几行正常。队列启动,生产者投递消息,消费者接收处理。延迟数字很低,都在毫秒级。
王涛肩膀松了一些。他舔了舔干裂的嘴唇,手指在触摸板上滑动。
到第一百条消息时,日志突然卡住。
光标停在那里,一动不动。
会议室安静得能听见空调送风声。王涛脸上的血色一点点褪下去。
他按了下刷新。没反应。又按了强制终止快捷键。
命令行窗口还是僵着。
“我看看。”张猛站起来,走到王涛电脑前。他俯身看了眼进程管理器,“队列服务进程还在,但 cpu 占用零。死锁了。”
王涛没说话。他盯着屏幕,呼吸变得很急,胸口起伏明显。
李薇调出自己的监控工具。她快速敲了几个命令,屏幕跳出堆栈信息。
“你看这里。”她指着一段代码,“内存队列的锁获取顺序有问题。生产者拿到锁a等锁b,消费者拿了锁b等锁a。”
典型的死锁场景。教科书里都写过。
王涛肩膀塌了下去。他伸手抓了抓头发,手指扯下来几根,自己都没察觉。
“这个锁顺序……”他声音发虚,“我昨晚改参数时调整过,可能……可能没测全。”
陈默看着投影上的堆栈信息。那行出错的代码后面,跟着提交记录的时间戳:凌晨三点二十。
“先恢复吧。”陈默开口,“用昨天的稳定版本。”
王涛机械地点点头。他退出死锁的测试环境,切回代码仓库。手指在触摸板上划了好几次,才点中正确的版本标签。
回滚,重启。
这次服务正常跑起来了。监控面板上绿色指标重新开始滚动。
但会议室里的气氛已经变了。
张猛坐回椅子上,抱起胳膊。他没看王涛,盯着投影上的监控图表,嘴角抿得很紧。
李薇小声叹了口气,关掉堆栈信息窗口。她端起已经凉了的豆浆,喝了一口,又放下。
王涛还站着。他盯着重新运行的服务,眼神有点空,像没聚焦。
“继续。”陈默说。
后续的联调走得很顺。张猛的同步链路表现稳定,王涛的队列在回滚版本后也没再出问题。数据从一端流到另一端,延迟控制在预期内。
但王涛每次操作前都会停顿一下。点鼠标前停顿,输命令前停顿,甚至说话前也要吸一口气。
像怕再出错。
中午吃饭时,王涛没去。他说不饿,趴在工位上补觉。
陈默和李薇、张猛坐在楼下的快餐店。塑料桌椅油腻腻的,桌角贴着褪色的菜单。
“他这样不行。”张猛夹了块红烧肉,没吃,放在米饭上,“才第一天正式开发,就搞出死锁。后面压力更大,怎么办?”
李薇用筷子戳着碗里的青菜。“他太急了。那个锁顺序的问题,明明写个单元测试就能发现。”
小主,这个章节后面还有哦,请点击下一页继续阅读,后面更精彩!
“他写了。”陈默说,“但昨晚提交前,他把测试用例注释掉了。提交记录里有。”
张猛筷子停住。“为什么?”
“测试没通过。”陈默喝了口汤,汤很咸,齁嗓子,“他想先调通主流程,测试回头补。”
张猛把筷子啪一声拍在桌上。邻桌的人看过来,他又压低声音:“这是胡来。基础的质量红线都能踩?”
李薇没说话。她看着碗里被戳烂的青菜,慢慢摇了摇头。
窗外有外卖电动车疾驰而过,轮胎碾过积水,溅起一片泥点。
“陈哥。”张猛转向陈默,“你得跟他谈谈。再这么下去,队列模块真会出大事。沈总的军令状可不是闹着玩的。”
陈默没立刻回答。他看向窗外,对面写字楼的玻璃幕墙反射着惨白的天光。
“晚上我找他。”他说。
回到公司时,王涛已经醒了。他正在工位上啃面包,面包屑掉在键盘缝里。
看见陈默,他立刻坐直,把面包塞回塑料袋。
“陈哥。”他嘴里还含着食物,发音含糊。
“晚上加个班。”陈默说,“把队列的单元测试补全。我跟你一起。”
王涛愣了一下,随即点头。“好。”
他眼里那点空茫的神色褪去一些,换成一种紧绷的专注。像终于等来了明确的指令。
下午的工作平静许多。王涛没再碰核心代码,专心写测试用例。键盘声规律了很多,一下,一下,带着思考的间隙。
陈默在自己工位上处理邮件。有一封是孙姐发来的,关于服务器采购的报价单。数字比预期高百分之十五。
他回复让孙姐再谈。敲完发送键时,听见王涛那边传来很小的欢呼声。
“这个边界条件终于过了。”王涛自言自语,声音里带着疲惫的兴奋。
陈默看了眼时间,下午四点。窗外的天色开始发灰,云层压得很低。
傍晚六点,其他人陆续下班。李薇走前小声跟陈默说:“别让他熬太晚。”
张猛拍了拍陈默的肩膀,没说话。
公司里又剩下他们两个人。王涛写完最后一组测试用例,运行,全绿。
他长长吐出一口气,身体向后瘫进椅子里。椅背发出咯吱的呻吟。
“总算……”他闭了闭眼,“陈哥,谢谢。”
陈默合上笔记本。“测试覆盖率多少了?”
“百分之八十五。”王涛睁开眼,“核心模块能到九十。”
“可以了。”陈默站起来,“今天到此为止。”
王涛却没动。他盯着电脑屏幕,监控面板上的指标还在平稳滚动。绿色,全是绿色。
“陈哥。”他忽然开口,“我是不是……挺让你失望的?”
问题又问了一遍。这次声音很平静,没有昨晚那种紧绷。
陈默重新坐下。塑料椅子发出轻微的摩擦声。
“技术上的错误谁都会犯。”他说,“但跳过测试,这是态度问题。”
王涛低下头。他看着自己的手,手背上那个烫伤疤在灯光下很明显。
“我知道。”他声音低下去,“我就是……太想证明这个方案能成。怕慢了,怕拖后腿,怕你们觉得我选一步是错的。”
他说得断断续续,像在拆解一团乱麻。
“沈总立军令状的时候,我其实有点慌。但慌完又觉得,这是个机会。我得做到完美,不能出一丁点岔子。”
“所以你熬夜改参数,跳测试。”陈默接上。
“嗯。”王涛扯了扯嘴角,笑得难看,“结果越急越错。”
窗外彻底黑透了。路灯一盏盏亮起来,昏黄的光晕在玻璃上晕开。
陈默沉默了一会儿。他想起系统里那个灰色的概率数字,百分之十八,后面跟着“置信度较低”。
现在他知道了,系统没推演错,只是不够具体。具体的错误是死锁,是跳过的测试,是凌晨三点二十那个鲁莽的提交。
“王涛。”陈默开口,“公司现在还小,容错率低。一次线上故障,可能就丢一个客户。沈总立军令状,不是要逼死你,是得把规矩立清楚。”
王涛点头,点得很用力。
“规矩就是质量红线不能踩。”陈默继续说,“测试必须过,代码必须审。工期紧张可以调整排期,但不能牺牲质量。”
“我明白。”王涛抬起头,眼睛在灯光下很亮,“以后不会了。”
他说得很认真。但陈默看见他放在膝盖上的手,手指无意识地蜷缩又松开,像在模拟敲键盘。
有些习惯,不是一句话就能改掉的。
陈默没再说什么。他站起来,关掉自己工位的灯。
“回去吧。明天开始,每天下班前把测试报告发群里。我和张猛会看。”
王涛愣了一下,随即点头。“好。”
这是多一层监督。他没反对。
两人一起下楼。电梯里镜子映出他们疲惫的脸。王涛眼眶下乌青很重,陈默下巴上也冒出了胡茬。
走出大楼时,风刮过来,带着深夜的寒意。
王涛裹紧外套,忽然说:“陈哥,其实我今天……接到个电话。”
陈默看向他。
“猎头打的。”王涛说得很快,像怕自己后悔,“说有个大厂在招分布式系统专家,开的薪水很高。”
他顿了顿,补了一句:“我没答应。就是……跟你说一声。”
陈默点点头。“知道了。”
他没问细节,也没说挽留的话。只是拍了拍王涛的肩膀,手掌落下去时,感觉到对方绷紧的肌肉。
“路上小心。”陈默说。
王涛嗯了一声,转身朝地铁站走。背影在路灯下拉得很长,渐渐融进夜色里。
陈默站在原地,摸出手机。屏幕亮起,系统界面又自动弹出来。
团队状态栏里,王涛名字后面的黄色叹号还在。但旁边多了个新图标:一个小小的信封。
点开,是条简短记录:“外部接触事件。成员忠诚度波动,当前稳定。”
波动幅度没有数字,只有一个向上的箭头,颜色是浅黄。
陈默关掉手机。屏幕暗下去,映出他平静的脸。
风更大了,吹得路边树叶哗啦作响。远处写字楼的灯光又灭了几盏,黑夜吞没了更多角落。
他站了一会儿,直到手指冻得发僵,才转身走向另一个方向。
夜还很长。隐患已经埋下,在看不见的地方悄悄滋长。