我去名企面试跑错楼层,帮一位老工程师改了4小时代码,临走他合上电脑:“小伙子,面试不用去了,明天9点来我这报到”

分享至



面试通知截图的右侧被裁掉了一截,陈川盯着“8层东区”找了半天,直到八楼走廊尽头那扇掉漆的门被他推开,才发现里面不像招聘区。四张工位空着三张,纸箱堆到窗边,两台旧显示器同时亮着,其中一台接连弹出两条拣货指令:同一订单,同一货架,同样的数量。

坐在屏幕前的老人没问他找谁,只把椅子往旁边一推:“这段锁,你敢不敢动?”

陈川的手已经碰到背包肩带,却没有接键盘。他看见桌下连着设备网关,先问:“出口能断吗?我不知道这条指令会不会真发到仓库。”

老人抬眼看了他一下,切断设备出口,又把程序切进离线环境:“现在呢?”

“让我先把它稳定弄坏一次。”陈川坐下时,手机上的面试签到提醒还剩二十七分钟。

老人姓顾,只报了这一个字。他把半年来的故障记录拖到桌面:程序从消息队列领取任务,先查任务是否处理过,再写入领取状态。日志里偶尔有两条线程在同一毫秒通过检查,但复查时怎么也撞不上。维护组为此加过重试、延时和第二层校验,测试都绿,夜班仍会隔几周冒出一张重复清单。

陈川没有先改锁。他复制了一条订单消息,做成两条同时抵达的请求,又在检查完成后插入一个只供测试使用的等待点。第一次回放,两条线程都停在“未领取”;他放开等待点,两边先后写入状态,两条拣货指令随即并排出现。

顾衡问:“为什么在这里停?”

“不是觉得这里可疑,是要证明两边能同时看见旧状态。”陈川把回放恢复到初始位置,“如果只靠多跑几遍碰运气,修完也不知道是不是运气好。”

第二次、第三次,重复指令都准时出现。陈川看了一眼手机,签到只剩九分钟。他把测试脚本保存好,起身说自己走错楼层,十八楼还有面试。

顾衡看见他透明文件袋里的学生求职证,确认他是来参加校招面试的,却指向刚才那两行状态:“你已经证明它会坏,准备怎么收?”

这个问题让陈川停住了。他知道再不走就肯定迟到,可屏幕上的旧代码把“检查”和“写入”分成两个动作,像一道已经看见缺口却没有合上的门。他给招聘联系人拨电话,没人接,只能发去一句说明,请求延迟签到。随后他坐回去,把任务领取改成带条件的原子更新:只有状态仍为未领取时才能成功写入,受影响行数为零的线程直接退出。

回放第一次通过,两条请求只生成一条指令。陈川刚松开键盘,顾衡便问:“凭什么说修好了?”

“不能凭这一次。”陈川把并发数提到十,又加入随机延迟。连续三轮没有重复,但第四轮出现了任务一直停在领取中的情况。他原本已经把背包拉到脚边,看见失败标记,又把包推了回去。

顾衡没有给答案,只问:“你这次把哪两个结果混成一个了?”

陈川重新看受影响行数,发现数据库超时也被当成了竞争失败。前者意味着结果未知,不能直接丢弃;后者才代表任务已被别的线程领取。他拆开异常分支,给未知结果增加状态复核,并保留可恢复标记。测试再跑,一条任务没有重复,却在模拟断电后无法重新领取。

十二点过后,办公室外渐渐安静。顾衡从抽屉里拿出两盒冷饭,只问陈川吃不吃。陈川摇头,给人事又打了一次电话。这回对方接了,听完面试信息和姓名,只说上午面试已结束,面试官下午另有安排,不能补场。

电话挂断后,陈川盯着熄下去的手机屏幕,半晌才说:“我本来是来应聘新平台开发的。”

“现在走,还赶得上后悔。”顾衡把一盒饭推到他手边,“但这条恢复路径没闭合。”

陈川掰开一次性筷子:“先闭合。”

下午的测试不再只是并发领取。陈川把断电点分别放在写入前、写入后和指令生成后,逐一确认恢复时该重试还是该终止。顾衡每次只追问依据:为什么这一处能重放,为什么那一处必须查执行记录,为什么不用更简单的进程锁。陈川答不出来时就撤回修改,重新造失败用例;能答出来时,也要让回放结果替他说话。

最后一次测试开始时,窗外已经偏暗。两条并行请求同时进入,只有一条取得领取资格;模拟断电后,未知状态被复核,已生成的指令没有再发,未生成的任务则被安全接回。陈川连续回放二十轮,屏幕右上角再没有跳出第二张清单。困扰维护组半年的偶发错误,第一次在同一套脚本里稳定出现,又稳定消失。

陈川看了眼时间,距离他推门已经过去四个小时。他把修改说明和失败用例路径写进提交记录,没有越过权限合并代码,然后站起来:“顾老师,设备出口还断着。改动也没进正式分支,您找组里的人复核吧。”

顾衡拿起他放在桌角的透明文件袋,重新核对先前见过的学生求职证。照片旁印着当天校招面试的信息。顾衡问:“你原先约的是维护组吗?”

“不是。我连楼层都看错了。”

顾衡当着他的面拨通人事电话,报出一个专项招聘编号,让对方核对剩余名额。电话那头确认名额已获批,但要求候选人次日带齐材料正式办理。顾衡开了免提,等陈川听清,才把手机扣回桌面。

陈川没有立刻答应:“这个组缺的是维护旧系统的人?”

“缺的是敢证明系统会怎么坏,也肯为恢复结果负责的人。”顾衡合上电脑,看着他说:“小伙子,面试不用去了,明天9点来我这报到”

走出八楼时,陈川才看见电梯指示牌背面的纸条:维护组五天后撤编。他回头望向那扇掉漆的门,终于明白那个专项名额为什么空到了今天。

周二八点五十七分,陈川抱着电脑和办好的入职材料回到八楼。昨天空着的三张工位已经拆掉一张,墙边纸箱贴着“归档”“报废”和“移交”三种标签,剩下的人正把旧系统资料装箱。顾衡替他签完直属负责人栏,只说四天后维护组撤编,今天先接交接。

陈川刚坐上最后一个空工位,一摞故障单便落在键盘旁。递单子的女人叫罗敏,负责仓库夜班支持。她看了一眼他的新工牌:“昨天改四小时代码,就占了组里最后一个名额。那这张你来。”

最上面一张只写了九个字:断网恢复后偶尔多单。附件却有七十多页,时间、仓库和操作员记录互相对不上。陈川问:“有实际处理过程吗?”

“都在纸里。真到夜里,没人按你测试脚本的顺序出故障。”罗敏把一串测试库凭据压在掌心,没有交给他,“能看懂再说。”

陈川没争辩。他把故障单按动作重排:扫描员提交任务,仓库短时断网,手持终端提示失败,操作员再次提交,网络恢复后出现两张清单。他删掉无法验证的情绪描述,把每一步改成输入、断点和可观察结果,又把三份时间矛盾的记录标出来,请罗敏判断现场究竟先重连还是先重按。

罗敏起初只站着回答,答到第三处却拉来椅子。她告诉陈川,夜班人员看到终端转圈超过五秒就会连续点两次;有些仓库的网关恢复后还会补发本地缓存,工单里所谓“一次提交”未必只产生一次入口请求。

陈川据此把用例拆成两组:同一消息的并发领取,验证昨天改过的旧锁;同一业务在断线后重新提交,则必须跨过消息入口,验证上下游如何识别它们是不是同一件事。他没有把第二组硬塞进昨天的结论,只在交接表上标成待联合确认。

罗敏看完,把掌心下的凭据推过去:“测试库给你。别动共享基线,自己建用例集。”

上午十一点,第一组回放全部通过。罗敏又从夜班记录里挑出三个最乱的仓库动作,陈川逐个做成可执行步骤。到下午,她撤掉了故障单上那句“无法复现”,改为“现场习惯已纳入恢复用例”,并主动留下来协助迁移预演。

预演在四点开始。新平台负责人梁绍带着两名工程师来到八楼,开口先问交付材料是否齐全。他把全量迁移日期写在白板上:周末零点,所有仓库统一切换。维护组撤编前必须签完旧系统责任边界,否则日期无法进入事业部排期。

顾衡没有接那叠确认单,只让罗敏连上模拟仓库。第一批连续请求顺利通过,新平台生成任务,旧系统领取并下发,回执也正常返回。梁绍敲了敲白板:“报告里已经跑过这些,今天只是交接确认。”

陈川问:“断线重发那组也在预演范围里吗?”

梁绍翻了下日程:“回退和异常网络不属于本次上线验收。先证明主流程,其他情况上线后观察。”

罗敏没等顾衡表态,已经拔掉模拟网关的网络线。终端上的任务停在发送中。五秒后,她按照夜班习惯再次点击提交,再插回网线。新平台先后显示两次受理,旧系统屏幕随即吐出两张拣货清单,订单号、货位和数量完全相同,只有任务编号末尾不同。

打印机滚轮还在转,屋里的人都停了手。陈川先按下模拟设备的暂停键,确认两张清单没有进入真实出口,随后给用例标记失败。昨天刚修好的锁没有报冲突:对旧系统来说,这是两个从未处理过的新任务。

梁绍把两张纸并在一起看了一眼:“上游第一次响应慢,用户重复提交而已。旧系统既然知道订单号相同,就该自己拦住。”

陈川指着屏幕:“昨天的锁按任务编号领取。现在两个编号不同,它不会把它们视为同一任务。要判断责任,得先看入口为什么给同一业务换号。”

“接口定义里,任务编号就是唯一标识。”梁绍从文件夹抽出一页旧系统缺陷确认单,“所以现在表现出来的是旧端幂等不足。维护组今晚签字,我们明天继续排其他项,别让一次非范围测试拖住全量上线。”

罗敏刚认可陈川的用例,此刻却先看向顾衡。那页确认单一旦签下,迁移前产生的重复任务就会被定为旧系统缺陷;四天后维护组撤编,留下的人仍要背着结论处理夜班事故。

顾衡没有讨论责任,只说:“先留住现场。预演环境、消息和两张清单都不要清。”

梁绍看了眼时间:“测试资源六点回收。你们可以记录结果,没必要占着整套环境。”

陈川接过确认单,看到签字栏已经替维护组留好位置。他把笔帽拔开,笔尖停在纸面上方,却没有落下:“现在签,只能证明结果出在旧端,不能证明原因属于旧端。”

梁绍说:“你入职第一天,还不熟悉双方验收历史。”

“所以我不写结论。”陈川盖回笔帽,把确认单压在两张拣货清单下面,“我只确认预演失败,责任等入口记录和执行记录对上再定。”

顾衡随即在预演表上写下“暂停清场”,而不是在缺陷确认单上签名。梁绍提醒他,全量上线日期已经报给事业部,拖过今晚就可能影响维护组的交接评价。顾衡只回了一句:“日期不能替日志作证。”

六点前,罗敏把模拟终端和两张纸质清单封存在工位侧柜,陈川保存了自己权限内的旧端执行时间,但入口记录归新平台,完整消息队列日志又只有运维能导出。他们守住了现场,却还没有守住结论。

梁绍带人离开时,把缺陷确认单留在桌上:“九点前给我签好的版本。测试环境不能因为一个新人一直占用。”

门合上后,罗敏把测试库的组内权限正式加给陈川,又发给他值班运维的联系方式:“我收回早上那句话。你不只会做演示。入口日志我没权限,但值班的人见过这次预演,他或许肯作见证。”

陈川看着两个不同的任务编号,把夜班交接用例补上最后一个观察项:断线重发后,上游是否沿用业务身份。刚修好的路径没有重新坏掉;这一次,重复任务绕开了它。

值班运维周启赶到八楼时已经六点二十。他先看暂停清场的预演表,又查看陈川的账号:“你只有测试执行和旧端只读权限。入口日志属于新平台项目,我不能直接导给你。”

梁绍的消息紧跟着弹进预演群:环境六点半释放,维护组只需提交失败截图,不得擅自扩大验收范围。陈川没有要求周启破例,而是把两张拣货清单摊开:“我不申请项目数据的持有权。请你作为运维见证人,按预演编号导出入口记录,生成只读副本,保留在审计库。我们只核对时间、业务号和任务号。”

周启仍没有动:“谁批准延长保留?”

顾衡把自己签过的暂停清场表递给他:“预演负责人可以申请事故留存,责任我担。副本不出审计库。”

周启核对签名后才锁定环境快照。他刚开始导出,梁绍便折返回来,身后还跟着测试经理。他没有碰运维终端,只把回收通知放到桌上:“保留原始日志会占用明早的预演槽位。失败现象已经确认,继续查不改变旧系统执行了两次的事实。”

“会改变这两次执行分别收到了什么。”陈川打开旧端只读日志。第一张清单对应任务标识T731,第二张对应T894;两条记录都显示首次领取成功,受影响行数均为一。旧锁没有被同一个任务突破两次,而是各自正确地接收了一个从未见过的新任务。

梁绍指着相同的订单号:“那更说明旧端没有业务去重。”

陈川没有反驳这句话。他把昨天的修复用例和今天的预演用例并排展示:“旧端确实只按任务标识防重,这是现状。现在要确认的是,新平台把断线重发定义为新业务,还是同一业务的重试。如果接口允许重试换号,旧端就需要新增业务幂等;如果接口约定沿用原号,那就是上游没有履约。两种都能修,但不能在日志出来前只签一种。”

入口记录导到百分之八十时,测试环境开始自动回收,旧端连接先变成灰色。罗敏立刻按住模拟终端,没有再次点击。周启切换到审计通道,说明环境可以释放,已锁定的副本不会随实例清理。梁绍能结束预演,却不能越过运维删除事故留存。

六点三十二分,环境状态变为已回收。周启在审计库打开副本,只投屏三列必要字段。第一条入口记录的业务号是O55821,任务号T731;网络中断后,客户端携带同一个业务号重发,新平台却生成了任务号T894。两次下发间隔十一秒,载荷中的货位和数量完全一致。

罗敏把现场故障单上的动作逐项对照:等待五秒、再次点击、网络恢复、缓存补发。除了仓库名称是模拟值,路径与夜班记录吻合。所谓非范围内的特殊回退,不需要机房故障或人工切换,一次普通仓库断线就足以触发。

梁绍沉默片刻,说:“新平台每次受理生成新任务号,是为了避免旧任务状态污染。这是设计,不是故障。旧端应该按业务号补一道锁。”

“可以补。”陈川说,“但在补之前全量上线,同一订单就可能产生多个合法任务号。昨天那份并发修复挡不住它,双方各自的通过报告也挡不住。”

测试经理调出验收目录,发现样本全部是连续成功请求,没有一项覆盖断线后的重发。新平台报告证明单次受理能生成任务,旧系统报告证明同一任务不会重复领取,两份报告都合格,却没有证明它们在恢复路径上对“同一件事”的定义相同。

梁绍把话题转回确认单:“这仍然是旧端能力缺口。顾老师在接口验收时已经确认过任务编号规则。”

他从文件夹里拿出一页验收材料,页尾确实有顾衡的签名。签署日期在两个月前,确认项写着“任务标识全局唯一,旧端以任务标识作为幂等依据”。梁绍把纸推到陈川面前:“你要追联合责任,先问你的直属负责人为什么签了。”

罗敏下意识看向顾衡。她刚才还准备以为证据已经足够,没想到接口页上的签名把问题重新压回维护组。陈川没有替顾衡解释,也没有把那页纸推开。他先核对版本号,发现它与今天预演使用的接口主版本一致。

顾衡拿起验收页看了很久:“签名是真的。验收时我确认了每个任务号唯一,也确认旧端按任务号防重。”

梁绍说:“那今晚的确认单可以签了。”

“不能。”顾衡把验收页放回桌面,“我签过什么,就承担什么。但这页只说明两个系统怎样使用任务号,没有说明同一业务重试时能不能换号。”

陈川沿着验收目录查找引用附件,任务标识规则后面标了一个变更记录编号,但他的权限打不开。他请周启只确认记录是否存在,不查看内容。周启在配置库中查到该编号,状态显示已归档,更新时间晚于顾衡签署验收页三周。

梁绍伸手合上投屏窗口:“变更记录不在今晚预演范围。环境已经释放,排查到此结束。”

周启没有继续展示内容,却把记录编号和更新时间写进审计副本说明。陈川也没有猜测里面改过什么,只在预演结论中写下能够由现有证据支持的三件事:两次执行对应两个不同任务标识;两个标识来自同一业务的断线重发;顾衡签署的验收页未覆盖重试是否换号。

他把结论念完,将缺陷确认单退回梁绍:“联合接口是否允许生成第二个编号,需要查变更记录和当时的通知。查清之前,我不会签单方责任。”

测试经理看过审计副本编号,也把自己的签字笔收了起来:“预演失败事实成立,责任项暂停。周四夜间上线评审前补查接口变更。”

梁绍脸色沉了下来:“因此耽误排期,由谁负责?”

顾衡在暂停栏签下自己的名字:“验收遗漏先算我的。全量上线不能拿没测过的恢复路径作前提。”

这不是替维护组洗清责任。顾衡签过的页面仍在,旧系统缺少业务级幂等也是事实;但梁绍要求当晚落定的单方缺陷,被两个编号和一份晚于验收的变更记录挡住了。争论从“旧锁为什么失效”,转成了“联合接口何时改变、由谁确认”。

周启完成只读副本封存,把审计编号分别发给双方负责人。罗敏收起纸质清单,第一次没有把最难的夜班问题留给顾衡,而是对陈川说:“明天查变更通知,我跟你一起。现场哪些断线算普通情况,我来列。”

办公室只剩最后一排灯亮着。陈川把顾衡签过的验收页复印件夹进交接用例。

梁绍离开后,顾衡把那页验收复印件抽出来,想先去找测试经理。陈川却按住文件夹:“顾老师,我要看的不是结论,是您当时实际跑过的原始用例。”

顾衡的手停了一下:“原始包在归档盘里,明早调。今晚先把补验申请送上去,免得窗口被占。”

“申请里补什么?”陈川追问,“断线、超时、客户端重发、平台重试,还是把这些全写成回退场景?范围不清,梁绍明天还能说我们临时加项。”

顾衡把复印件从他手下抽出来:“先申请,再从经验里挑最可能出问题的路径。窗口只有一晚,不能什么都测。”

“可您上次也是凭经验挑了顺序样本。”陈川没有松口,“如果这次还先下判断再找用例,只会换一种方式漏掉同一件事。”

办公室里只剩机箱风扇的响声。罗敏把已经收好的清单重新放回桌面,没有插话。她知道顾衡返聘后替维护组挡过多少次仓促签字,也知道陈川这句话正好落在他那张真实签名上。

顾衡看着陈川,语气沉了些:“你觉得我会替梁绍留口子?”

“我觉得您签字时漏了恢复路径。”陈川把复印件转向顾衡,“刚才您已经承认只确认过任务号唯一。要补验,就得从原用例缺了什么开始,不能靠您的判断替原始材料补记忆。”

付费解锁全篇
购买本篇
《购买须知》  支付遇到问题 提交反馈
相关推荐
无障碍浏览 进入关怀版