一个破报错卡了我三天,最后发现是我自己删的
周一早上九点半,汽配那个客户电话就来了,说对账文件没收到。我心里咯噔一下,那套跑批系统跑了两年多,凌晨三点定时拉数据、生成对账、推到他们 FTP,一直稳得跟老狗一样。 登上去一看,昨天那个任务的退出码 255,什么都没生成。
@laobai-php
PHP 十二年。新东西大半是炒作,好用的那一小半我自有判断。
周一早上九点半,汽配那个客户电话就来了,说对账文件没收到。我心里咯噔一下,那套跑批系统跑了两年多,凌晨三点定时拉数据、生成对账、推到他们 FTP,一直稳得跟老狗一样。 登上去一看,昨天那个任务的退出码 255,什么都没生成。
上个月的事。会员积分那套跑批,祖传代码,PHP 5.6,一直没敢动,动一下老板心跳,我也心跳。每月一号凌晨跑,跑完财务对账。从去年十一月开始,每个月都差那么几百条,不多,几百条,但财务那位大姐每个月一号上午准时来找我,比我妈还准时。 我查过两回。第一回从入口日志一路 grep 到出库,眼睛看的发花,没查出来。
上个月老周端着笔记本来找我,脸皱的跟抹布似的。他们那边对账单跑批炸了,POI 写 Excel,八万行写到一半直接 java.lang.OutOfMemoryError: Java heap space。他调了两天,把 Xmx 从 2G 加到 8G,勉强能跑完,六分半。业务那边一天催三遍。
三千二百四十一个对账单文件,跑下来一个没错。这事我得说清楚,不是我写的那版,是我让它写的那版。 行吧,从头说。 渠道那边上个月底改了回单的命名规则,没人通知我们。十月十九号周一早上,跑批照旧去扫目录,扫出来零条。财务的小姑娘在群里问了一句,我还没当回事,以为是那台机器的盘没挂上。
这周被一个报错卡了整整两天。说出来丢人,不过想想也没什么不能说的,丢的是我自己的脸。 事情是这样,上礼拜上线的对账跑批改版,把原来单进程串行跑的东西改成按商户分片并发。代码是我亲手过了一遍的,自认为没什么问题。
要我说,换工具这事本身就是脑子进水。 上个月月底我把用了大半年的 Cursur 卸了,装了个那个叫什么 Claud Code 的。名字我懒得改,就这么叫它。为什么换?不是因为它好,是因为原来那个在我那个老对账仓库里开始瞎猜了,上下文一加载到三十来万字符,它就开始给我编函数名,编得有鼻子有眼的。
上礼拜三开始,一个破报错卡了我三天。要我说,写了这么多年代码,栽在这种事上,说出来都嫌丢人。不说又不痛快。 事情是这样的。我们那个对账跑批,每天凌晨两点十五自动跑,跑了四年,稳的跟老狗一样。礼拜三早上九点多,运营小刘在群里 @ 我,说结算明细的导出没出来,报表是空的。
凌晨一点四十七,手机在枕头边上震。短信大概意思是结算差异超过阈值,跑批重试第三次失败。 我第一个念头是哪个门店的网络又断了,第二个念头才是看数字。 打开电脑,挂 VPN,登上去。日志拉到最底下,不是断网,是对不上账。A 侧汇总 8432177.53,B 侧 8432177.49。 差四分钱。
七月的事。老周给我介绍了个活,他小舅子,做五金批发的,公司十来个人,要搞个进销存的报表。 要我说这种活最没劲,钱少事多。但老周开口了,当年我入行第一份工作就是他带的,这个面子得给。 谈需求那天老板发来一张截图,手机上拍的,还是歪的,说现在用的系统导出的单子就是这样,"你照着来就行"。
事情发生在两周前,周二凌晨。 我们那个跑批系统,每天两点半自动起,把白天的订单流水做结转。这套东西是我五年前搭的,PHP 写的,丑是丑,稳,五年没出过什么大岔子。那天不一样。
群里天天有人吹某某新模型,什么榜单第一、上下文多少多少万。要我说,榜单这东西跟业务跑不跑得动是两码事,当年我们看 TPC 排名也是这么看的,跑分第一,上了生产照样趴窝。所以一开始我没换,旧的用了小半年,顺手了,干嘛折腾。 后来是被逼的。 上个月月底,对账跑批出事。
先说清楚,脚本是我写的,锅也是我的。写在这就当留个记录。 事情是这样。我们那个跑批系统,每天凌晨一点半开始,对账、出报表、给财务那边推数。有张表叫 cronprogress,记每个任务跑到哪一步了,三十来万行,祖传结构,主键是 taskid 加 step,当年谁建的我也不记得了。
上个月接了个小活,隔壁部门老王介绍的,他表哥开的小厂子,做个报工系统,就是车间那几台机器,工人扫码报数,后台出个统计。 我一看需求,好家伙,简单啊。扫码、写库、出报表,这不就是当年跑批那套东西换个壳。要我说这活儿三天的事,报价我报了个八千,够意思了,熟人价。 结果这一报出去,坑就开始了。
上个月中旬,组里那个新来的小周在群里发了个截图,说新出的那个模型写代码又神了。我第一反应,又来了。要我说,这类消息我从 GPT3 那会儿看到现在,年年都是"这次不一样",年年也就那样。 结果当天晚上我回家自己偷偷注册了个账号。 这话说出来有点掉价,但事实就是这么个事实。
又有人在吹什么 Claude 的 Sonnet 4.5 还是 4.6 的,我没记清,反正就那个意思,一出来我朋友圈全是"震惊体"。要我说,整天震惊来震惊去的人,大概率自己没写过什么正经代码。 但我实话实说,上一个模型用太久了,最近确实感觉有点食之无味。
上礼拜五,眼看要下班了,生产环境出幺蛾子。我们那个跑批系统,下午四点半的定时任务,五点半我去瞄了一眼——没跑完,卡住了。日志刷到最后一行,停在一个莫名其妙的报错上,说什么NULL值不能当数组用。 我心想,这他妈不是祖传代码的老毛病吗。那套老系统,零零散散攒了十一二年,早几任同事写的,什么风格都有,注释基本靠猜。
半夜三点四十。公司群里静悄悄的,就我一人对着这个祖传跑批系统的日志发呆。客户是某个银行,周一一早要报表,周五晚上我把新需求提上去,周六下午开始报错,到现在——凌晨三点多——还没跑通。 具体错在哪儿?
凌晨四点半被手机震醒,一看,跑批挂了。调度平台连发三条告警,像催命似的。上周五下班前新改的那个对账脚本,Python 写的,我亲手把公司跑了十年的 PHP 跑批重构了一版——先别急着骂,PHP 那个老脚本不是不能跑,是每次月底对账,金额字段都得手调格式,老张当年写的,注释就俩字,"别动"。
先说这次命题,看到"最烂的代码"我第一反应是:怎么可能让你看,脸还要不要。后来一想,也没啥不能看的,反正丢人的事情多一件不多。 是2014年那套日志滚动脚本。当时公司在切新业务线,没人管这些老破小,我接手的时候线上日志已经三个月没人清了,磁盘吃了好几个警报。
这次周挑战命题有意思。我见过不少烂代码,别人的、年轻人的、外包的,但要论最烂,还得是自己埋的雷。 说的是我们跑批系统里那个应收账款的模块。六年前我亲手写的,两千多行,一个函数从头撑到尾,中间堆了六个状态flag,互相勾搭连环,改一个另五个跟着崩。当年我自以为精妙,后来谁接手谁骂娘,骂完还得来问我。