我与代码的“孽缘”:从 Hello World 到祖传屎山

3 阅读7分钟

一个普通程序员的十年血泪史,笑中带泪,泪中带Bug

一切从那个“Hello World”开始

那年我十八岁,刚进大学,第一堂编程课。老师敲下两行代码:

python

print("Hello World")

屏幕亮了,我觉得自己像《黑客帝国》里的尼奥——掌握了世界的真理。那时候的我天真地以为,程序员就是一群用键盘演奏交响乐的人。

后来才知道,真实的日常是:键盘是用来Ctrl+C/Ctrl+V的,交响乐是不存在的,有的只是产品经理的“这个需求很简单”

第一次“生产事故”:我删了半个数据库

大二实习,老板让我维护一个老项目。我打开数据库管理工具,发现有张表叫 user,里面全是测试数据。我心想:清掉吧,反正没用。

执行 DELETE FROM user; 回车,瞬间响应。

成就感满满。

五分钟后,老板走过来:“小张,为什么所有用户都登不上去了?”

我:“……啊?”

后来我才知道,那张 user 表,就是生产环境的用户表。测试数据混在真实数据里,只是因为前人懒得建测试库。而我的 DELETE 语句,没有写 WHERE 条件

幸运的是,前一天刚好有备份。不幸的是,恢复备份花了两小时,老板全程站在我身后,一言不发。

那是我第一次理解什么叫“汗流浃背”。从那以后,我在任何数据库工具里执行任何删除操作前,都会先写 WHERE 1=0 测试三遍,再把 DELETE 改成 SELECT * 确认一百遍。

PTSD,是程序员最好的老师。

那个让我怀疑人生的Bug

工作第二年,遇到一个Bug:用户上传的图片,偶尔会莫名其妙旋转90度。

我查了一天,不是代码问题。两天,不是。三天,开始怀疑自己。第四天,我怀疑人生。

第五天,我突然发现——这些旋转的图片,全部来自iPhone手机。进一步查资料才知道,iPhone拍照时会记录一个“方向”EXIF信息,很多网页浏览器会忽略它,但某些底层库会严格按这个信息来渲染。

解决方案:读取EXIF,手动校正方向。

六行代码,解决了五天的噩梦。

那天我对着屏幕笑了很久,觉得自己像个傻X。同时也悟出一个道理:不是你菜,是你不知道你不知道什么。

产品经理与“五彩斑斓的黑”

有一次,产品经理跑来提需求:“我要这个按钮在用户鼠标移上去的时候,慢慢变大,然后变红,再变蓝,最后弹一下。”

我:“你确定?”

他:“确定,这是最新设计趋势。”

我花了一小时,用CSS动画实现了:鼠标悬停,按钮放大(transform scale),变红(transition),变蓝(keyframes),最后加一个弹性缓动。完美还原。

产品经理看了:“不对,感觉不对。”

我:“哪里不对?”

他:“说不上来,但是颜色不够‘高级’。”

那天我给他看了色轮、RGB、HSL、十六进制、Material Design、苹果人机界面指南……最后他说:“要不还是用原来的灰色吧。”

灰色,永远的神。

“重启大法”救我狗命

有一次线上服务突然接口超时,所有请求卡住。我看了日志、看了监控、看了配置、看了代码,一切正常。服务器CPU 20%,内存40%,网络流量平稳。但就是超时。

重启,就好了。

至今我不知道为什么。那台服务器后来也没再出过同样的问题。

重启,解决不了所有问题,但能解决你不知道原因的问题。

祖传代码的“惊喜”

现在的项目是一个2015年诞生的老系统,经过7任程序员的手。每一任都在上面留下了自己的痕迹,就像考古地层一样清晰。

  • 第一层(2015):远古纯PHP,面向过程,一个文件几千行。
  • 第二层(2017):加上了命名空间和类,但仍然有远古文件被include
  • 第三层(2019):引入了Laravel框架,但只用在部分模块,导致框架和原生代码互相调用。
  • 第四层(2021):开始出现微服务,一个请求要经过5个服务。
  • 第五层(2023):也就是我。我每天的工作就是在这些“地层”之间打洞,试图让新功能跑起来。

有一天我发现一个函数叫getUserInfo(), 里面竟然返回了订单列表。旁边的注释写着:“// 临时修复,因为前端要一次拿到”。日期:2017-03-15。

六年了,这个“临时”还在。

更绝的是,我还找到一个变量叫$a123,没有任何注释。我全局搜索了一下,它出现了47次,用在不同的地方。我花了整整一天才搞清楚它到底是干什么的——最后发现它什么也没干,只是前一个人写到一半废弃的逻辑,忘了删。

注释是写给自己的墓志铭,变量名是写给人间的遗书。

不得不说的“厕所文化”

我们团队有个不成文的规矩:棘手的问题,去厕所蹲一会儿。

不是因为厕所里有灵感,而是因为厕所里没有电脑。当你面对一个Bug盯了两个小时眼冒金星的时候,离开座位,去厕所放空五分钟,回来往往一眼就能看出问题。

我管这叫排泄驱动开发(Excretion-Driven Development, EDD)。

最夸张的一次,同事在厕所蹲了半小时,出来直接跑到工位改了一行代码,Bug解决了。他说是在刷短视频时突然想通的。所以严格来说,那是短视频驱动开发。

快乐其实很简单

写了这么多年代码,我越来越觉得,这个职业的快乐很“廉价”:

  • 一个难缠的Bug终于解决了,那种“啊哈!”的时刻。
  • 部署脚本一次性成功跑通,所有绿灯亮起。
  • 优化后的接口响应时间从2秒变成20毫秒。
  • 用户在评论区说“这个功能真好用”。
  • 周五下午,没有紧急需求。

但也很有分量。

有一次,我们给一个偏远山区的学校做了一个教学管理系统,那边网络很差,页面加载要十几秒。我花了两个周末重构了前端,做离线缓存、图片懒加载、异步分块传输,最后把首屏时间压到了1.5秒以内。

后来我收到那个学校老师发来的一段视频:孩子们在电脑前,屏幕上的页面“唰”地一下就出来了,他们“哇”地一声笑出来。

那一刻我对着手机屏幕,笑得像个傻子。

代码不是诗,但你可以用它写诗。

写在最后

前段时间有人问我:“做程序员后悔吗?”

我想了想说:后悔没早点学会用Git。  第一年工作全靠zip文件备份,v1_final_真的最终版_打死不改_最终版2.zip 这种噩梦不想再经历第二次了。

至于编程本身,不后悔。虽然它让我发际线后移、腰椎间盘突出、每天和产品经理斗智斗勇、在祖传屎山里挣扎求生……

但它也让我学会了:

  • 解决问题的方法论:分而治之、抽象、复用。
  • 逻辑思维的肌肉记忆:写代码久了,连买菜都会下意识地给菜谱写流程图。
  • 对不确定性的敬畏:你以为它没问题,它就会出问题。你以为它一定出问题,它反而好好的。
  • 还有最重要的一点——永远要对下一段代码保持好奇。

因为下一个Bug,可能就是你写过最有趣的故事。

(就像我现在写这篇文章,写完发现有一个错别字,去编辑修改了,然后等人工审核通过……)


如果你也在写代码,欢迎评论区分享你的“有趣”经历。
记住:没有一个Bug是熬夜解决不了的,如果有,那就加一行 console.log