程知予站直身体,走进会议室,在他对面坐下来。两个人隔著一张桌子,中间是跑著日志的电脑萤幕和两杯已经凉掉的水。
“成本的事我来谈。”她说,“但顾行之,我要你一句话——如果追加预算,你能保证系统在两周内上线吗?”
他看著她,没有马上回答。程知予知道他在做判断——不是技术上的判断,是承诺的判断。工程师不轻易给承诺,因为变数太多,任何一个环节出问题都会影响时间表。
“能。”他说。
一个字。跟那天在厨房说“是真的”一样的语气。
程知予点了一下头,正要站起来,他又开口了。
“但你得答应我一件事。”
她停住。“什么事?”
“上线那天,你能不能请我吃顿饭?”他的语气很轻,像是在说一个不重要的小事,但他放在键盘上的手指没有动——他没有在打程式码,他在等她回答。“不是便利店的,不是便当,是——坐下来好好吃的那种。”
程知予看著他。他的表情很平静,但耳朵的颜色出卖了他——从耳尖开始,慢慢变红,蔓延到耳廓。
她没有马上回答。她故意多等了三秒,看著他的耳朵从粉红变成浅红。
“好。”她说。
他的嘴角动了一下,没有笑出来,但眼睛里的光亮了一下。
“但有一个条件。”她补了一句。
“什么条件?”
“饭钱你出。”
他终于笑了。不是那种压抑的、克制的笑,是真的被逗到了,嘴角往上翘,眼角弯起来,整个人从严肃的技术顾问变回那天在厨房里跟她抢锅铲的人。
“好。我出。”
程知予站起来,走到门口,回头看了他一眼。他已经转回去看日志了,但手指没有在键盘上——他双手交叉放在桌上,对著萤幕发呆,嘴角还挂著那个笑。
她走出会议室,脚步比平时轻了一点。
走到走廊转角的时候,她停下来,靠著墙,拿出手机。打开跟顾行之的聊天窗口,打了一行字:
“你刚才耳朵红了。”
发出去。已读。对方正在输入的指示灯亮了很久——大概有二十秒。
最后跳出来一行字:
“你刚才答应了。”
程知予看著这行字,笑了一下。她把对话框往上滑,看到这几天的讯息记录——便利贴的照片、蛋塔的照片、她说“不准现在回”的命令、他说“反正我已经等了七年了”的坦白。
她把萤幕按掉,放进口袋。
走廊上的感应灯灭了,她站在原地,在黑暗里站了三秒,然后往前走了一步,灯又亮了。
程知予用了两天时间做完安全评估报告。不是因为她动作慢,是因为她知道这份报告要说服的不是周明远一个人——他要拿这份报告去跟总部要预算,每一个数字都必须经得起质疑。
她把报告分成三个部分。第一部分是技术架构对比,把合规科技升级前后的技术参数全部列出来,对照行业标准和监管要求,每一项都标注了数据来源。第二部分是成本效益分析,追加预算的投入产出比,用三种不同的测算模型交叉验证。第三部分是风险评估,如果不追加预算的风险敞口有多大,如果追加预算能覆盖多少风险。
每一个数字她都核对了两遍。第一遍是昨天晚上在办公室做的,第二遍是今天早上五点起来做的。中间睡了四个小时,但咖啡喝了很多,精神比她预想的好。
周五下午两点,她走进周明远的办公室。他正在看一份合约,看到她进来,把合约阖上,往椅背一靠。
“报告好了?”
“好了。”她把报告放在他面前,没有坐下,站在办公桌对面。
周明远翻开第一页,扫了一眼目录,然后翻到第二部分。他看得很慢,每一页大概停留一分钟左右,期间没有提问,没有皱眉,表情平静得像在看一份普通的业务报表。
程知予站在那里,双手自然下垂,没有靠在椅背上,没有倚著桌子。这是一种习惯——汇报的时候站著,让对方坐著,姿态上先把主动权交出去,但内容上不留余地。
五分钟后,周明远抬起头。
“你的测算模型用了三个假设。第一个是业务增长率,第二个是监管处罚概率,第三个是系统使用年限。这三个假设如果有一个不成立,你的投入产出比就要重新算。”
这是第一个质疑。程知予准备过。
“业务增长率我用的是公司未来三年的保守预测值,不是乐观值,是财务部给出的最低增长情景。监管处罚概率我参考了去年同业的处罚数据,总共二十三家同行,被罚的有六家,概率百分之二十六。我取的是这个数值,没有打折。系统使用年限我按三年摊提,但硬体安全模组的实际使用年限是五年,我的测算是偏保守的。”
周明远没有点头也没有摇头,翻到第三部分。
“风险敞口你算了两种情况——被监管处罚和业务中断。但你有没有考虑第三种情况:数据泄露导致的商誉损失?”
“考虑了。”程知予翻到报告的附录部分,“附录三是我做的商誉损失敏感度分析。假设数据泄露事件发生后,股价下跌幅度在百分之三到百分之八之间,对应的市值损失换算成现金,大概是追加预算的十二倍到三十二倍。这个倍数我写在注释里了,没有放在正文,因为商誉损失的估算变数太多,我不想让它稀释正文的核心论证。”
周明远看了她一眼。那个眼神她读得懂——不是赞赏,是确认。确认她有没有想到这一层。
“第三个问题。”他阖上报告。“你怎么说服总部?他们不看技术参数,不看敏感度分析,他们只看一个东西——这个钱花下去,能不能少出事。”
“能。”程知予说,“硬体安全模组上线之后,系统的安全层级会从四点三提升到四点七。四点七是什么概念?去年行业内没有一家公司在这个层级以上发生过数据泄露事件。这个数据我也写在报告里了,第四页。”
周明远沉默了大概二十秒。程知予没有催促,没有补充,没有试图用更多的数据填满这段沉默。
他拿起笔,在报告的最后一页签了字。
“拿去财务部。我跟他们打过招呼了。”
程知予拿起报告,转身要走。
“程知予。”周明远叫住她。
她停下来。
“你刚才站了十五分钟,一口水都没喝。”
“……我在汇报。”
“下次坐下说。”他低下头继续看合约,语气像在说一件不重要的小事。“我又不会吃了你。”
程知予走出办公室,在走廊上深吸了一口气。她低头看了一眼手里的报告,最后一页上周明远的签名字迹很潦草,但她认得出来——他签合约的时候字迹是工整的,越是不确定的决定,字迹越潦草。这次潦草的程度介于“有点犹豫”和“就这样吧”之间。
够了。
她把报告送到财务部,回到小会议室。顾行之不在,林一桐一个人对著萤幕发呆。
“他人呢?”
“去机房了。硬体安全模组的测试环境出了点问题,他去调。”林一桐抬头看她,“程律师,预算下来了吗?”
“签了。”
林一桐握了一下拳头,幅度很小,但看得出来是真的高兴。“太好了。学长这几天一直在算成本,他说如果预算下不来,他就要想办法用软体方案补硬体方案的效果,但那样性能会掉百分之八。”
程知予没有接话。她想起顾行之那天说“安全层级确实可以再提高一级”的时候,语气平静得像在说一个普通的技术选项,没有提到他已经在算软体补偿方案的事。
预算下来之后,顾行之团队进入全力冲刺模式。
硬体安全模组的部署比预想的复杂。原本的架构是纯软体方案,现在要加入硬体设备,整个数据流向要重新调整,认证机制要重写,测试用例要全部更新。顾行之把任务拆成十七个子模块,分配给团队三个人,自己扛了其中七个。
程知予每天陪到深夜。不是因为工作需要——合规审查的部分在白天的对接会上已经完成了——而是因为她觉得应该在。
她的理由是:系统上线前有任何合规问题,她可以第一时间处理。这个理由很正当,经得起任何人追问。
周一到周三,三天的时间,两个人形成了固定的节奏。白天正常对接,晚上七点叫外卖,八点吃完继续工作,十点左右会议室只剩他们两个人——林一桐和另一个工程师会在十点前离开,顾行之让他们先走,说剩下的他自己来。
周一晚上,程知urer在改合规文档,顾行之在写程式码。两个人坐在会议桌的两端,中间隔著四张椅子的距离。会议室里只有键盘的声音和她翻页的声音。
“你文档里第三页的条文引述有误。”他头也没抬。
“哪里?”
“数据安全法第二十一条,你引的是旧版。去年十二月修订过,新增了第三款。”
程知予翻到第三页,对照手机上的法条数据库。他说得对。她引的是旧版。
“你怎么知道数据安全法的修订内容?”
“上周看的。系统合规审查会用到,我先读了。”
程知予在文档上画了一条红线,标注修改。她抬头看他,他正在敲键盘,萤幕上的程式码一行一行地往下跑。会议室的白光灯照在他脸上,眼镜反射出萤幕的蓝光,表情很专注。
她低下头继续改文档。
周二晚上,外卖叫的是附近一家面馆的牛肉面。程知予吃到一半发现碗里多了一颗卤蛋——她不记得自己有加点。她看了一眼顾行之的碗,他的面里没有蛋。
“你蛋给我干嘛?”
“不喜欢吃蛋。”
“你便当里每天都放玉子烧。”
他沉默了一秒。“……那是切碎的,看不出来是蛋。”
程知予没有拆穿这个逻辑漏洞。她把卤蛋咬了一口,继续吃面。
周三晚上,顾行之敲完最后一行程式码,阖上笔电,靠在椅背上说了句:“基本稳了。”
程知予从合规文档里抬起头。“什么?”
“硬体模组的所有测试都过了。性能指标比预期好百分之十二。”他揉了揉手腕,语气很轻,但嘴角有一点往上翘。“剩下的就是整合测试和回归测试,三天够了。”
程知予靠回椅背,呼了一口气。她没有意识到自己一直在绷著——肩膀是耸起来的,背是僵的,连咬笔盖的频率都比平时高。听到这句话的时候,她才感觉身体慢慢松下来。
“喝这个。”顾行之站起来,从背包里拿出一个保温杯,放在她面前。
她打开盖子,里面的液体是淡褐色的,冒著热气,闻起来有红枣和冰糖的味道。
“银耳汤?”
“嗯。早上出门前煮的,闷到现在应该够烂了。”
程知予喝了一口。温的,甜度刚好,银耳煮到软烂,入口即化。她没有问他为什么会在早上出门前煮银耳汤,也没有问这个保温杯是什么时候装进背包的。
“这几天辛苦了。”他说。
“你也辛苦了。”
两个人对坐著,中间隔著两台笔电、一个保温杯、一份吃到一半的外卖和一堆散落的文件。会议室的灯照在每样东西上面,没有阴影,没有暧昧的光线,但程知予觉得这个画面比任何刻意营造的氛围都好看。
“我们能不能别这么客气?”他问。
程知予又喝了一口银耳汤。“那你想要我怎么说?”
他看著她,眼神很认真,但嘴角那个弧度出卖了他。“说‘顾行之,你真厉害’。”
程知予差点呛到。她捂住嘴,咳了两声,瞪了他一眼。
“你幼不幼稚?”
“不幼稚。”他靠在椅背上,双手交叉放在脑后,姿态很放松,但眼睛一直看著她。“从大三开始,我就想听你说这句话。”
“你大三的时候我又不认识你。”
“所以我才想听啊。不认识的人说你厉害,比认识的人说更有说服力。”
“这是什么逻辑?”
“工程师的逻辑。盲测比对照组可信度更高。”
程知予把保温杯放下,拿起桌上的笔,在合规文档的空白处写了几个字,然后把文档转过去给他看。
上面写著:“顾行之,你真厉害。”
她的字迹很工整,横竖撇捺都在该在的位置上,但“厉”字的最后一笔稍微往上翘了一点——那是她写字的时候在忍笑的痕迹。
顾行之看著那行字,没有说话。他伸手把文档转回来,看著那行字大概五秒,然后把文档阖上,放在自己的笔电旁边。
“你干嘛?”她问。
“留著。”
“那是合规文档。”
“我把那页撕下来,其他的还你。”
“顾行之——”
“开玩笑的。”他把文档推回来,但手指在桌面上多停了一秒。“我拍照就好。”
他真的拿出手机,翻开文档到那一页,拍了一张照片。动作很快,像是怕她反悔。
程知予看著他拍照的样子,没有阻止。她低下头继续喝银耳汤,汤已经不烫了,温温的,比刚打开的时候更好喝。
“程知予。”他叫她。
“嗯。”
“你知道我为什么想听这句话吗?”
“因为你幼稚。”
他笑了一下,没有反驳。“因为从大三开始,我就在想——如果有一天我能站在你面前,让你觉得我做了一件厉害的事,那就够了。”
程知予的手指在保温杯的杯壁上轻轻转了一圈。杯壁上有水珠,是热气凝结的,她的指尖划过去,留下一道干净的痕迹。
“现在呢?”她问,“够了吗?”
他看著她,没有马上回答。会议室很安静,冷气运转的声音嗡嗡的,像背景白噪音。
“不够。”他说。“但没关系。我还有时间。”
程知予把保温杯放下,站起来,开始收拾桌上的文件。她把合规文档叠好,放进背包,把外卖的碗筷收进袋子里,把散落的笔一支一支放回笔筒。
顾行之坐在原位,看著她收拾。他没有帮忙,也没有说话,只是看著。
她收拾完,背上背包,走到门口。
“明天几点?”她问。
“早上九点。最后一轮整合测试。”
“我八点半到。”
“不用那么早——”
“我八点半到。”她重复了一遍,语气不重,但没有商量的余地。
他点了点头。
程知予打开门,走出去。走了几步,又折回来,探头进会议室。
“顾行之。”
“嗯?”
“你今天写的程式码,我看不懂。”
“嗯。”
“但我知道写得很好。”
她说完就走了。这次没有折回来。
走廊上的感应灯一盏一盏亮起来,她的脚步声在空荡荡的走廊上回响。走到电梯口的时候,手机震了。
“你刚才说的话,我拍照了。”
她回:“那是合规文档的一部分,有著作权。”
“著作权归你。使用权归我。”
程知予站在电梯里,看著这行字,笑了。电梯门打开,她走进大厅,夜风从玻璃门的缝隙里钻进来,吹在她的脸上。
她拿出手机,又看了一眼那条讯息。然后她按掉萤幕,把手机握在手心里,走进夜风里。
晚上十点,最后一轮测试启动。
程知予坐在小会议室的角落,面前摊著合规审查的最终确认清单。四十七个检查项,她已经勾了四十六个,剩最后一个——系统整合测试通过。她看了一眼萤幕上的测试进度条,百分之三十一。顾行之坐在她对面,笔电连著三台测试伺服器的监控画面,数据流在萤幕上跑成一条一条的曲线,绿色的,代表正常。
林一桐和另一个工程师在隔壁机房盯著硬体模组的状态灯,每隔半小时回报一次。十一点的时候林一桐发来讯息:“硬体运行正常,温度稳定在五十二度。”顾行之回了一个“好”,继续盯著萤幕。
会议室很安静。冷气在十点半自动关了——大楼的中央空调定时关闭,程知予审过这个合规项目,她知道。但今晚她不觉得热,大概是因为专注。测试进度跑到百分之六十七的时候,她站起来倒了两杯水,一杯放在顾行之面前,一杯自己喝。
“谢了。”他头也没抬。
十一点四十分,进度百分之百。第一轮测试全部通过。程知予在清单上写了“第一轮通过”,看了眼时间,觉得今天可能不用通宵。顾行之没有放松的表情,他盯著监控画面看了大概三十秒,然后切到另一个页面——日志分析系统。
“怎么了?”她问。
“等一下。我再确认一轮。”
他没有解释。程知予没有追问。她坐下来,打开手机看了一眼讯息,没有重要的,把手机翻过去扣在桌上。
十二点二十分,顾行之开始跑第二轮测试。这次不是例行测试,是他手动调整了参数之后的压力加强版——并发请求量比正常峰值高百分之三十。程知予不懂技术细节,但她看得懂他脸上的表情。嘴唇抿成一条线,眉头微微皱起来,手指在键盘上的速度比白天快了一倍。
十二点五十分,测试跑到百分之百。所有请求都返回了正常回应,没有超时,没有错误码。但顾行之没有停下来。他打开日志系统,逐条检查回应时间。
凌晨一点零三分,他找到了问题。
“这里。”他把萤幕转向她,指著一行日志。“数据同步延迟。正常情况下应该是两百毫秒以内,这几笔跑到了一点二秒。虽然没超时,但延迟波动太大,上线之后如果量再大一点,可能会出问题。”
程知予凑过去看著萤幕。日志上的数字她大部分看不懂,但她看得懂他的判断——不是猜测,是确诊。他知道问题在哪里,也知道怎么解决。
“要多久?”
“一个小时。”他已经在开新的终端视窗了,“你先休息。”
“我帮你做什么?”
他抬头看她,犹豫了一下。“帮我看另一台机器的日志。搜关键字‘sync_latency’,把出现时间记下来。”
“好。”
她搬了张椅子坐到他旁边。两台笔电并排,他负责修复,她负责记录。会议室里只剩键盘的声音和她报时间的声音——“零一点零七分三十二秒”“零一点零八分十五秒”“零一点零九分零一秒”——他的手指在键盘上敲,她的手指在笔记本上写,节奏像两台同步运行的机器。
凌晨两点零八分,他敲下最后一行指令,重新跑了一次压力测试。这次所有的回应时间都在两百毫秒以内,日志上没有“sync_latency”的警告。他盯著萤幕看了三分钟,然后靠回椅背,闭了一下眼睛。
“好了。”声音很哑。
程知予把笔记本阖上,也靠回椅背。两个人在会议桌的两端,隔著四张椅子的距离,同时呼了一口气。
“接下来呢?”她问。
“跑自动化测试。大概两个小时。”他睁开眼睛,揉了揉眉心。“不用盯著,让它自己跑就行。”
“那你睡觉。”
“你呢?”
“我等你。”
他看了她一眼,没有说“你不用等”,也没有说“你先回去”。他只是把椅子往旁边挪了一点,让出桌面上的一块空间,说:“趴一下。两个小时之后我叫你。”
程知予没有跟他争。她把手臂交叉放在桌上,头枕上去。桌面有点凉,手臂的温度贴上去之后慢慢变暖。她闭上眼睛,听到冷气停止之后会议室的寂静,听到他键偶尔敲一下的声音,听到他自己的呼吸声。
她以为自己不会睡著。太紧张了,系统明天上线,还有一个测试周期要跑,合规清单还差最后一项。但身体比意志诚实——连续一周的加班、今天十六个小时的工作、凌晨两点的大脑,已经不给她选择的余地。
半梦半醒之间,她感觉有人站起来。脚步声很轻,走到她旁边,停住。空气里多了一层重量——他在把外套披在她肩上。布料有点粗,但内衬是软的,还带著他的体温。
她没有睁眼。意识在清醒和睡眠之间摇摆,像一条船在水面上晃。她能听到自己的呼吸声,能感觉到外套的领口蹭到她的脖子,能闻到洗衣液的味道——跟之前一样的牌子。
然后她听到他坐下来。不是回到对面,是坐在她旁边。椅子被拉近的声音,布料摩擦的声音,然后安静。
“程知予。”
他叫她名字的方式跟白天不一样。白天的“程知予”是三个字,干净利落,像在叫同事。现在的三个字,每个字之间多了一个呼吸的间隔,像在念一句不想让别人听到的话。
“我喜欢你很久了。”
她的心跳在胸腔里撞了一下,力道大到她怀疑他听得到。
“从你站在模拟法庭上说‘我反对’那天开始。”
安静。会议室里只剩下测试伺服器风扇的声音和他的呼吸声。她没有睁眼。不是因为还在睡,是因为不知道睁开眼睛之后该说什么。她的手指在外套底下微微收紧,指甲压进掌心,用疼痛确认自己不是在作梦。
“那天下课之后我去找你,想跟你说一句话。但你走太快了,我没追上。”他的声音很轻,像是在自言自语,不是在对她说。“后来的七年,我每次觉得自己做了点什么的时候,都会想——如果现在站在她面前,够不够资格。”
他停了一下。程知予听到他推了一下眼镜的声音——手指碰到镜框的那种轻微的声响。
“后来我想通了。这不是资格的问题。是勇气的问题。”
她感觉到他在看她。不是那种快速的瞥一眼,是一直在看。她的后颈有一点发麻,但她没有动。
“所以现在我有勇气了。”他说,声音更轻了,轻到几乎被风扇的声音盖过去。“就这样。”
然后他站起来,把披在她肩上的外套拢了拢。手指没有碰到她的肩膀,但他调整外套的时候,指节的温度隔著布料传过来,温温的。
“没关系,你不用回答。我就是想让你知道。”
脚步声往门口的方向移动。她听到他拉开门,走出去,轻轻带上。门关上的那一刻,会议室彻底安静了。
程知予睁开眼睛。
桌上的笔电萤幕还亮著,测试进度跑到百分之四十三。对面的椅子被推歪了,比原来的位置靠近她大概五十公分。她的心跳还是很快,快到她不得不深呼吸了两次才让它慢下来。
她坐直身体,外套从肩上滑下来一半。她伸手接住,布料在她手心里皱成一团。她把外套放在桌上,站起来,走到门口。
走廊上的灯亮著,但没有人在。
她站在门口,握著门把,站了大概一分钟。然后她走回会议室,坐下来,把手机拿起来。萤幕上没有新讯息。她打开跟顾行之的聊天窗口,输入栏里打了两个字,删掉。打了四个字,又删掉。
最后她把萤幕按掉,把手机放回口袋。
测试进度跑到百分之六十七。她拿起笔,在合规清单的最后一项旁边写了两个字:“待确认”。写完之后她又觉得不对,把“待确认”划掉,写了“测试中”。然后又觉得这两个字也不对。
她把笔放下,趴在桌上。这次不是因为累,是因为她需要一个姿势来消化刚才听到的那些话。脸埋在手臂里,呼吸在自己的体温里循环,心跳声在耳膜上打鼓。