那是裴衍之团队的办公区域。
她没有再看第二眼,转身走向地铁站。
手机在公事包里震了一下。她拿出来看,是何悦发的消息。
“程姐,到家了吗?”
她回了两个字:“路上。”
何悦秒回:“注意安全。”
然后又发了一条:“程姐,我问你一个问题你别生气哈。你跟裴哥真的只是不熟吗?因为我刚才去倒水的时候看到他的工位灯也亮著,他好像也没走。就觉得好巧哦。”
程司白把手机萤幕按掉,没有回。
地铁进站的时候,风从隧道里吹出来,把她的头发吹乱了。她站在月台上,看著列车的灯光从远处一点一点靠近,像一个正在收敛的级数——无限逼近,但永远不会真正到达。
她想,她和裴衍之就是这样。
无限逼近过一次,然后发散掉了。
现在又开始逼近了。
但她不知道这次会不会收敛。
陆维安在公司楼下的便利店门口等著,手里拎著两杯咖啡,看到裴衍之从大厅出来的时候迎上去,把其中一杯递给他。
“裴哥,怎么样?”
裴衍之接过咖啡,没有喝。纸杯的温度透过杯壁传到指尖,有点烫。
“被否了。”
两个字说出来的时候,他的声音很平静,平静得像在说今天的天气。陆维安愣了一下,咖啡举到一半停在嘴边。
“不是吧?那个方案我们做了三个月,唐总不是说很满意吗?”
“唐总满意没用。”裴衍之推开玻璃门走进大楼,“架构组有意见。”
他没有说“程司白有意见”。他不想在任何人面前提这个名字。
电梯里只有他们两个人。陆维安站在他旁边,时不时偷看他一眼,欲言又止的样子让裴衍之想起三年前的自己——那时候他也是这样,想问又不敢问,想靠近又不敢靠近。
“裴哥,架构组那边是谁在负责评审啊?”陆维安终于忍不住问了。
“程司白。”
陆维安“啊”了一声,表情变得有点微妙。“就是那个……出了名难搞的程司白?架构组唯一的女核心?”
“嗯。”
“听说她特别严格,上次有个项目被她连否了三次,那个负责人差点辞职。”陆维安说完意识到这话不太对,赶紧补了一句,“但裴哥你的方案肯定没问题,她可能就是……要求比较高。”
裴衍之没有接话。
电梯到了十五楼,门打开的时候他听见陆维安在身后小声说了一句“裴哥加油”,语气里带著一种真诚的、不掺杂任何东西的善意。他觉得有点好笑——陆维安这个人什么都好,就是太年轻,太容易把复杂的事情想简单。
他回到工位的时候,萤幕已经暗了。他移动滑鼠,萤幕亮起来,桌面上还是那份方案文档,最后一页停留在签署页。
“感谢架构组的支持,期待合作。”
这行字他写的时候想了很多。他想她看到这行字的时候会不会想起什么,会不会在某个瞬间觉得这三个字不只是在说方案。但写完之后他又觉得自己很蠢——程司白不是那种会读弦外之音的人,她只看字面意思,只看可验证的事实,只看能证明的东西。
她从来不看那些不能证明的。
比如他写这行字的时候,手在发抖。
三年前的那个周六,他记得每一个细节。
那天他在家写程式码,写到一半觉得有点饿,就去厨房煮了一碗面。面煮好的时候手机响了,他以为是她发来的消息——他们约好了明天去书店,她可能会问几点出发。
他拿起手机,萤幕上显示她的名字。
“我们分手吧。”
他盯著这四个字看了大概十秒,然后以为自己在做梦。他揉了揉眼睛,又看了一遍。还是这四个字。
他回了一个“???”。
然后她发了第二条。
“裴衍之,我们不合适。你太感性了,我不需要。”
这条消息他看了很久,久到面凉了,坨在碗里变成了一团糊状的东西。他坐在餐桌前,手机放在桌上,萤幕的光照著他的脸。
他想不通。
昨天他们还好好的。她给他发了一篇论文,说这篇写得不错,他回说明天见面聊。她回了一个“嗯”。那个“嗯”没有句号,是她放松的时候才会用的语气。他还截了图。
怎么今天就变成“我们不合适”了?
他打了一行字:“你怎么了?发生什么事了?”
没有发送。删掉。
又打了一行:“如果你是在开玩笑,这个玩笑不好笑。”
没有发送。删掉。
又打了一行:“我们见面谈谈好吗?”
这条发出去了。
没有回应。
他又打了一条:“程司白,你在哪?我去找你。”
没有回应。
他打了电话。响了三声,被挂断了。
再打。关机了。
那天晚上他没有睡,坐在客厅里反反复复地看他们的聊天记录,从第一条翻到最后一条。第一条是她发的,那时候他们还不熟,她问他一个技术问题,语气很正式,开头写著“裴衍之你好”,结尾写著“谢谢”。最后一条是她发的“我们分手吧”。
中间的几千条讯息里,她说过很多话。她说他写的方案有逻辑漏洞,说他做的饭太咸了,说他讲的笑话一点都不好笑。她也说过谢谢他陪她走那段路,说过注意休息,说过早点睡。
但他翻遍了所有的讯息,没有找到她说过“我喜欢你”。
不是因为她不喜欢。是因为她说不出来。
他知道的。
第二天他又打了一次电话,还是关机。第三天也是。第四天也是。
到了第五天,他不再打了。
他坐在电脑前,打开一个新的程式码档案,写了一行注释。那行注释他现在还记得,因为那个档案他一直没有删,每次换电脑都会拷贝过去,像某种仪式。
那行注释写的是:“// 她不要你了。”
他盯著这行字看了很久,然后把它删掉了。他觉得自己很可笑——一个成年人,被分手了还要写注释来提醒自己,像一个没长大的小孩。
他最后给她发了一条讯息。
“好,不打扰了。”
这四个字他写了半个小时。写了删,删了写,反反复复,像一个死循环。他本来想写很多话,想问她为什么,想说他还喜欢她,想说他愿意改,想说她不喜欢他感性他可以变得更理性,想说很多很多。
但最后他只写了这四个字。
因为他知道,程司白决定的事情,不会改变。
她就像一段写好的程式码,编译通过了就不会再改。逻辑清晰,没有歧义,没有例外。他不在她的逻辑里,所以她把他删掉了。
就这么简单。
离职的决定是他在被分手之后第三个月做的。
那三个月里他每天都去上班,坐在程司白曾经坐过的工位旁边——她离职比他早,分手之后的第二周就办了手续,去了另一家公司。他不知道她去了哪里,也没有去打听。他告诉自己不要去打听。
但每天早上坐到工位上的时候,他还是会习惯性地转头看一眼旁边那个空著的位置。
桌上什么都没有了。她的马克杯、她的笔记本、她那盆从来不浇水也不会死的仙人掌,全部都带走了。只剩一个萤幕支架留下来,孤零零地立在桌面上,像一个被遗忘的数据结构,占著内存但没有任何指针指向它。
他觉得自己就像那个萤幕支架。
还在运行,但已经没有人需要了。
离职之后他创办了一家小公司,做技术咨询。说是公司,其实就是他自己一个人,在家里客厅写程式码,接一些零零碎碎的项目。那段时间他写了很多程式码,什么类型的都有——前端、后端、资料库、运维,能接的都接。不是因为缺钱,是因为他发现只要手在键盘上,脑子就不会去想别的事情。
但他发现自己有一个毛病。
每次写到需要用到“共识”这个词的时候,他会停下来。
不是刻意的。就是手指会悬在键盘上方,打不出来。共识算法、共识机制、达成共识——这些词他以前天天用,现在变成了一个障碍,像一段语法错误的代码,编译器报错,但他不知道怎么修。
他试过强迫自己打出来,打完之后盯著萤幕看,觉得这两个字长得很奇怪。共——识。明明是两个很正常的字,他却觉得它们在发光,刺眼的那种。
后来他干脆不用了。写文档的时候用“一致性协议”代替,写代码的时候用“agree”代替。他把“共识”这个词从他的词典里删掉了,就像程司白从他的生活里删掉了一样。
公司做了两年,被一家大公司收购了。收购之后他本来可以拿著钱去做点别的事情,但那家大公司的技术总监看了他写的程式码之后说了一句话:“你这个人写代码很有结构感,但缺乏野心。你明明可以做得更好,为什么总是在安全区里打转?”
他当时没有回答。但他知道为什么。
因为他怕了。
他怕走出安全区,怕再犯一次错,怕再被人说“你不够理性”。所以他把自己关在一个小小的、可控的系统里,不做任何可能失败的事情,不投入任何可能失去的感情,不靠近任何可能让他心软的人。
他把自己变成了一个足够理性的人。
就像她希望的那样。
回归职场之后他进了现在这家公司,从应用层的工程师做起,一步一步做到业务中台的负责人。他以为自己已经好了——能正常工作、正常社交、正常地跟同事开玩笑。他甚至开始觉得“共识”这两个字没那么刺眼了。
然后他收到了项目评审的通知。
架构组负责人:程司白。
他看到这个名字的时候,手指在滑鼠上停了大概十秒。然后他点开通知,关掉,打开方案文档开始修改。他改了很多地方,把每一个可能被质疑的细节都补上了证明和数据,附录加了七页,测试报告写了一万两千字。
他告诉自己这是因为他想要方案通过。
但他知道不是。
他是不想让她觉得,这三年他一点进步都没有。
会议室里她说“好久不见”的时候,他的第一反应是想问她这三年过得好不好。
这个念头在脑子里停留了零点几秒,然后被他压下去了。
不能问。不能表现出任何多余的东西。她说了不熟,那就是不熟。她要的是理性的合作,不是感性的寒暄。
所以他回了“好久不见”,语气平静,像在确认一个事实。然后走出电梯,靠在墙上闭了一下眼睛,让那三个字在心脏里转了一圈,再把它们压回去。
他很擅长做这件事了。
压回去。
萤幕右下角弹出一条消息。
裴衍之移动滑鼠点开,是唐嘉树发来的。
“衍之,我知道你们的过去。但这个项目需要你们合作。你能做到吗?”
他看著这行字,想起三年前唐嘉树跟他说过几乎一样的话。那时候他刚被分手,状态很差,唐嘉树找他谈话,说“如果你撑不住,可以休息一段时间”。他说不用。唐嘉树看著他,说了一句“你知道吗,有时候理性不是唯一的答案”。
他当时没有理解这句话。
现在他理解了。但他不确定自己同意。
他打字回复:“能。”
一个字,够了。
唐嘉树没有再回。
裴衍之把聊天视窗关掉,打开项目管理系统,准备把今天的评审意见整理成文档。页面加载的时候,右上角弹出一封新邮件的提示。
发件人:程司白。
他的手指在滑鼠上停了一下。
点开。
邮件内容很简短,没有一个多余的字。
“裴衍之,明天上午九点,会议室三,讨论共识算法选型。请准备Paxos方案的边缘场景测试数据。——程司白”
他看著这封邮件,从头到尾读了三遍。
第一遍看内容。第二遍看语气。第三遍看签名。
签名只有名字,没有职位,没有问候,没有“发送自iPhone”之类的废话。干净俐落,像她写的程式码。
但他注意到一个细节。
她写的是“共识算法选型”,不是“技术方案评审”,也不是“问题复盘”。选型意味著还有选择的空间,意味著她的态度从“否决”变成了“讨论”。
这是一个很小的变化。小到可能连她自己都没有意识到。
但他意识到了。
他回了一封邮件:“收到。明天见。”
发送之后他把邮件关掉,打开文档开始整理测试数据。萤幕上密密麻麻的数字和图表在他眼前闪过,他一个一个地看,一个一个地核对,确保每一个数据都准确无误。
窗外的天已经完全黑了。办公区里只剩下他一个人,键盘的声音在安静的空气里显得很响,哒哒哒哒,像一段稳定的心跳。
他不知道自己还要工作多久。也许到深夜,也许到凌晨。他不累,甚至觉得有点清醒——那种只有在深夜才会出现的、万籁俱寂的清醒。
手机震了一下。
他拿起来看,是何悦在群组里发的消息。群组名字叫“干饭小分队”,是他们平时约午饭用的。何悦发了一张照片,是便利店的关东煮,配文:“加班狗的晚餐。”
陆维安回了一个哭泣的表情。
然后何悦又发了一条:“你们猜我刚才看到谁了?程姐还在公司,一个人坐在工位上发呆。好心疼。”
陆维安回:“你心疼什么?”
何悦:“你不懂。”
然后群组就安静了。
裴衍之把手机翻过去,萤幕朝下扣在桌上。
他不想看。他不想知道她还在公司,不想知道她一个人在工位上发呆,不想知道她是不是也在想什么。
因为如果他想这些,他就没有办法继续做一个“够理性”的人。
他打开文档,继续整理数据。
萤幕上是一张系统延迟分布图,横轴是时间,纵轴是延迟。曲线在三百毫秒的位置上波动,偶尔有一个尖峰,但整体保持平稳。
他盯著这条曲线,忽然想起她以前说过的一句话。
那是他们还在谈恋爱的时候,有一次她盯著系统的监控画面看了很久,然后说:“你看这个曲线,多稳定。如果人跟人之间的关系也能用数据监控就好了,波动超过阈值就自动报警,该重启的重启,该降级的降级。”
他当时说:“那我们的关系现在是什么状态?”
她想了想,说:“正常运行。”
他问:“有没有报警?”
她说:“没有。”
他问:“那你开心吗?”
她没有回答。
现在想起来,那个时候可能已经在报警了。只是她没有告诉他,他也没有看到。
明天上午九点,会议室三。
他关掉文档,关掉电脑,拿起外套走出办公室。
经过走廊的时候他经过那面贴满技术海报的墙。海报上写著那行字:“分布式系统的最终一致性:理论与实践。”
最终一致性。
他想,如果人与人之间也有最终一致性,那他们现在算什么状态?
是正在同步,还是永远不会同步?
电梯到了一楼,门打开。大厅里很安静,保全在前台后面打瞌睡。他走出大楼,夜风吹过来,带著十一月的凉意。
他抬头看了一眼。
十五楼的灯还亮著。
他看了大概三秒,然后低下头,走向停车场。
车钥匙在手心里冰凉,他握紧了一下,又松开。
三年了。他以为自己已经把所有的情绪都压好了,压到最深的地方,用理性盖上盖子,用工作压住,用时间封死。
但今天在会议室里,她站起来说“我有问题”的时候,那个盖子被掀开了一条缝。
他闻到了里面那些东西的味道。
还是原来的味道。
会议室三的门在八点五十八分被打开。
程司白第一个到,坐在靠窗的位置,面前摊著笔记本,旁边放著一台笔记型电脑。她把投影机打开,萤幕上显示著她昨晚准备到凌晨两点的简报——第一页是一张性能对比图,Raft变体算法的数据用蓝色标注,每一项指标都比Paxos高出百分之十五到二十。
九点整,裴衍之推门进来。
他手里拎著一台笔记型电脑和一个文件夹,文件夹鼓鼓的,里面塞满了打印出来的测试报告。他看了一眼会议室里的座位,选择了离程司白最远的那个位置——长方形会议桌的对角线,中间隔著六把空椅子和一台投影机。
何悦跟在他后面进来的,手里端著两杯咖啡,一杯放在自己面前,一杯推到程司白手边。她坐下来的时候打开笔记本,手指放在键盘上,一副准备速记的样子。
陆维安最后一个到,抱著一台笔记型电脑气喘吁吁地冲进来,在裴衍之旁边坐下。
“开始吧。”程司白没有寒暄,直接点开简报的第一页。
萤幕上出现一张架构图,节点之间用箭头连接,每一个箭头上都标注著数据流向和时延参数。图的右下角写著一行字:Raft变体——优化后的领导者选举机制。
“这是我提出的方案。”程司白站起来,走到投影幕前,手里握著翻页笔,“基于Raft的共识算法变体,主要优化了两个方面。第一,领导者选举的超时机制从固定值改为动态调整,根据网络延迟实时计算最优超时窗口。第二,日志复制阶段引入并行写入,吞吐量提升百分之二十三。”
她点了一下翻页笔,萤幕切换到第二页。
“测试数据。在同样的硬件配置下,我的方案吞吐量每秒一万五千笔交易,延迟两百二十毫秒。比公司现有系统提升百分之二十二的性能。”
她把翻页笔放在桌上,转头看向裴衍之。
“裴衍之,你的方案数据是多少?”
裴衍之没有立刻回答。他打开自己的笔记型电脑,调出一份文档,萤幕上是一张密密麻麻的测试报告。
“每秒一万两千笔交易,延迟三百毫秒。”他的声音很平,“但我的方案在稳定性测试中波动幅度不超过百分之五,你的方案呢?”
“百分之八。”程司白说,“但这是因为测试环境的网络有波动,在实际生产环境中——”
“实际生产环境的网络波动只会更大,不会更小。”裴衍之打断她,“百分之八的波动意味著在高峰期你的系统可能会出现百分之十五到二十的性能抖动。这个风险你考虑过吗?”
“考虑过。”程司白翻到简报的第三页,萤幕上出现一张网络抖动模拟图,“我在三种不同的网络条件下做了模拟测试。即使在最坏的情况下——跨洲网络延迟五百毫秒、丢包率百分之一——系统的吞吐量仍然维持在一万两千笔交易以上,延迟控制在四百毫秒以内。这个数据仍然优于你的方案。”
“但稳定性呢?”裴衍之站起来,走到投影幕前,离她很近,近到她能闻到他衬衫上洗衣液的味道——和三年前一样,某个不太常见的牌子,闻起来像柠檬和雪松。
“你的方案在网络波动的时候,领导者选举的频率会增加多少?”
程司白后退半步,把翻页笔从桌上拿起来。“频率增加百分之三十。”
“百分之三十。”裴衍之重复了一遍这个数字,“也就是说,在高峰期你的系统每十秒就要重新选举一次领导者。每次选举期间系统不可用,客户端会收到超时错误。你觉得业务方能接受吗?”
“选举过程只持续一到两秒,影响范围——”
“一到两秒在分布式系统里是很长的时间。”裴衍之的声音不大,但每一个字都很清楚,“用户点击一个按钮等两秒没有反应,就会刷新页面。刷新页面就会重复提交。重复提交就会产生脏数据。脏数据——”
“脏数据可以通过幂等性设计来解决。”程司白的手指在翻页笔上敲了一下,“我在方案第五章写了幂等性的具体实现——”
“你的幂等性方案依赖于客户端生成全局唯一的请求ID。”裴衍之翻开自己带来的文件夹,抽出一页纸,“但你们架构组上个季度的技术评审中明确指出,现有的客户端无法保证请求ID的全局唯一性。你用一个无法保证的前提来解决脏数据问题,这不是架构设计,这是论文写作。”
会议室的温度骤降了五度。
何悦的手指停在键盘上,不敢动。她偷偷看了一眼陆维安,陆维安正盯著萤幕上的测试报告发呆,脸上写满了“我为什么要在这里”。
程司白沉默了两秒。
这两秒里会议室里只有空调的嗡嗡声。她看著裴衍之,裴衍之看著她。两个人的目光在空中撞上,没有闪躲,也没有退让。
“你说得对。”程司白先开口了,“幂等性方案的确依赖于客户端支持。这是我考虑不周。”
她说这话的时候语气很平静,没有任何被戳穿的窘迫。何悦在心里暗暗佩服——程姐被当面指出方案漏洞还能这么冷静,换成她早就红脸了。
“但你的方案也有漏洞。”程司白翻开自己的笔记本,念出她昨晚写好的问题清单,“Paxos在提案者并发的情况下,活锁概率是多少?你的文档说小于百分之零点一,但这个数字是怎么算出来的?你有数学证明吗?”
裴衍之的手指在文件夹的边缘敲了一下。“有。证明在附录B。”
“附录B我看了。”程司白抬起头,“你的证明假设了提案者的数量不超过三个。但在实际生产环境中,业务中台对接的服务节点有十七个。当十七个节点同时提案的时候,你的活锁概率还是百分之零点一吗?”
裴衍之没有立刻回答。
他翻开文件夹,找到附录B那一页,从头到尾看了一遍。然后合上文件夹。
“不是。”他说,“十七个节点的情况下,活锁概率会上升到百分之二点三。”
“百分之二点三。”程司白重复这个数字,“也就是说每一百次提案,就有两到三次会因为活锁导致延迟增加。你觉得业务方能接受吗?”
她把他的问题原封不动地还给了他。
何悦在键盘上敲了四个字:“程姐反杀。”然后迅速删掉。
陆维安终于忍不住了,举起手想说话。
“那个——”
裴衍之和程司白同时转头看他。
陆维安的手举在半空中,看了看裴衍之,又看了看程司白,把举著的手放下来,改成摸了摸后脑勺。
“没事,我就是想说……要不要先喝口水?”
没有人理他。
“百分之二点三的活锁概率,可以通过业务层的重试机制来解决。”裴衍之重新把目光转回程司白脸上,“用户感知到的延迟最多增加一百毫秒,不会影响体验。”
“那你刚才说的一到两秒的选举延迟呢?”程司白说,“你的选举延迟影响用户体验,我的选举延迟也影响用户体验。我们扯平了。”
“不一样。”裴衍之说,“你的选举发生频率是我的十倍。”
“但我的单次选举时间是你的五分之一。”程司白说,“算下来系统不可用的总时间,我的方案比你的少百分之五十。”
“你怎么算的?”
“用数学。”
这三个字落地的时候,会议室的气氛达到了一个新的低点。
何悦在桌子底下给陆维安发了一条消息:“我们要不要出去?”
陆维安的手机震了一下,他低头看了一眼,然后抬头看了看何悦,轻轻点了点头。
但两个人都没有动。因为唐嘉树推门进来了。
技术总监手里端著一杯茶,慢悠悠地走进来,看了一眼投影幕上的架构图,又看了一眼站在投影幕两侧的程司白和裴衍之,最后把茶杯放在桌上。
“吵完了?”
没有人说话。
“没吵完的话继续,我在旁边听。”唐嘉树拉开一把椅子坐下,喝了一口茶,“吵完了的话我来说两句。”
程司白走回自己的位置坐下。裴衍之也回到座位上。
唐嘉树放下茶杯,目光在两个人脸上轮流停了一下。
“你们两个的方案我大概听明白了。程司白的方案性能好,但稳定性有风险。裴衍之的方案稳定,但性能不够。对吧?”
两个人同时点头。
“那就简单了。”唐嘉树站起来,“两个方案都做。两周之后给测试数据对比。哪个好就用哪个。”
“唐总——”程司白开口。
“没有商量。”唐嘉树打断她,“项目不能因为你们的技术分歧卡住。两周时间够不够?”
程司白看了裴衍之一眼。他也正在看她。
“够。”两个人同时说。
唐嘉树点了点头,端著茶杯走出会议室。门关上的时候,何悦终于松了一口气,开始收拾东西。陆维安合上笔记型电脑,站起来准备走。
“何悦,你先出去。”程司白说。
何悦愣了一下,看了看程司白的表情,又看了看裴衍之的表情,然后拉著陆维安快步走出会议室。门在他们身后关上。
会议室里只剩下两个人。
程司白站在窗边,裴衍之站在会议桌的另一端。窗外的阳光透过百叶窗照进来,在地上投下一条一条的光影,正好把两个人隔开。