# 程序员寓言集

---

## 借条

村口有一座桥，是老王在赶工期时搭的。他没时间打地基，就找了几根圆木架上去，桥面铺得平整，踩上去甚至有点弹性，像是特意设计的缓冲。验收那天，甲方走过桥，很满意，说这桥比隔壁村的还稳。

老王在心里给自己记了一笔账：地基，欠着。

后来老王升了职，调去了别的村子修别的桥。桥还在，车马照常经过，只是每年汛期，村里都要派两个人去桥墩边守着，盯梢似的听水声。没人知道具体在防什么，只是老守夜人说，这桥"有点意思，得看着"。

第十一年，一辆运货的马车照常经过，桥没塌在那天，塌在第二天凌晨，压根没人在场。村里翻出旧账本，想找当年是谁修的桥，翻到最后一页，只写着一行小字：赶工期，地基后补。

后补的那部分，从来没有人补过。利息滚了十一年，本金早就记不清是谁欠的了，但账，村里所有人一起还了。

---

## 大坝

工程师老周在河边造了一座水坝，坝身厚得像座山，能扛住百年一遇的洪水。设计图纸上写着最大流量的三倍冗余，钢筋用量是隔壁镇同类工程的两倍，工期因此拖了八个月。

镇长来看进度，问他为什么这么厚。老周说，万一发洪水呢。

镇长又问，历史记录里这条河发过洪水吗。老周想了想，说，没有，但万一呢。

大坝造好那年，河水一如既往地温顺，绕着坝基打了个转，从旁边的旧河道流走了——旧河道比坝址低两米，洪水从来就没打算走这条路。老周没算错任何一个数字，他只是从没问过，水会不会来，往哪儿去，什么时候。

镇上后来把这座坝当作景点，导游词是这么讲的："这是我们镇最坚固的建筑，修给一场从未到来的洪水。"

孩子们喜欢在坝顶上跑来跑去，觉得很好玩，没人告诉他们，坝下面本来是要过河的路，现在得绕八里地。

---

## 帐篷

工地上支了顶帐篷，工头说，先凑合两天，等正式宿舍盖好就拆。帐篷是蓝色的，塑料布的那种，钉子钉得很随意，四个角高低不平，风一吹哗啦哗啦响。

两天过去，正式宿舍的图纸还没批下来。工头往帐篷里加了张桌子，说再凑合几天。

三个月后，帐篷里通了电，架了空调外机，工头往帐篷四周砌了圈砖，说好歹挡挡风。半年后，帐篷升级成了"临时办公区"，钉在告示牌上，字体是正式的，配了编号。

三年后，新来的工人问，那个蓝色的帐篷是干什么用的。老工人说，那是临时的，等正式宿舍盖好就拆。

新工人又问，正式宿舍什么时候盖。老工人说，你问的这个问题，我十年前也问过。

蓝帐篷至今立在那里，四个角依然高低不平，只是砖已经砌到了齐腰高，谁也不再提"拆"这个字，它现在有自己的门牌号，物业费也是按正式建筑收的。

---

## 推倒重来的人

镇上有个木匠，叫老赵，见谁的家具都要摇头。张家的柜子，他说，这榫卯结构不对，早晚要散架，得整个拆了重做。李家的桌子，他说，这木料选得不行，将就用是能用，可惜了，要是我来做，肯定比这好。

老赵手艺是真的好，这点没人否认。但凡他真动手做的东西，确实漂亮，严丝合缝，摸上去都是舒服的。

问题是老赵从没做完过一件"重做"的家具。张家的柜子他拆到一半，说这年头的木料跟他想的不一样，得先去山里选新料，一去就是半年。李家的桌子他量了尺寸、画了图纸、订了新工具，然后镇上来了个更有意思的活，他就搁下了。

这些年，村里被老赵判了"死刑"又晾在半路的家具，堆了半间仓库：缺一条腿的柜子，只有图纸没有实物的桌子，量好尺寸从没裁过的木料。张家最后自己找了个普通木匠，把柜子榫卯重新紧了紧，用到现在，将就，但一直在用。

老赵路过时还是会摇头，说这修得不彻底，要是他来，肯定推倒重来。张家现在学乖了，笑笑，不接话。

---

## 九个妇人

工期紧，包工头急了，把原本三个月的活儿，喊来九个人，说一个月就能干完。逻辑很简单：三个人干三个月，那九个人干一个月，人多力量大。

活是砌一堵需要严丝合缝、一气呵成的墙，因为砂浆有固化时间，前一段没干透，后一段就接不上茬。九个人挤在同一段墙基前，反而互相绊脚，你等我的浆干，我等你的活干完，工头在旁边急得直转圈，又找了三个人来帮忙。

墙没有提前一个月砌完，反而比原计划的三个月还多花了两周——十二个人分派任务、对接进度、开会协调所花的时间，比三个人踏踏实实干活还长。

工头后来跟人念叨这事，说人多了怎么反而慢了。旁边一个老瓦匠抽着烟说：一个女人怀胎十月生一个孩子，你找九个女人来，一个月能生出来吗？

工头没说话，墙修好了，只是没人再提当初那句"人多力量大"。

---

## 打地鼠

系统上线那晚，出了个 bug，用户下单后收不到确认短信。值班的小林两点被叫醒，查了半小时，发现是短信队列的一个字段被写错了，改了一行代码，发布，短信恢复正常，小林松了口气，回去睡觉。

四点，报警又响了。这次是订单状态没同步，一查，是小林改的那行代码影响了另一个消费者，那个消费者原来依赖那个字段的旧值做判断。小林改回来，同时加了个特判，绕开短信那边的问题，再发布。

六点，第三个报警：库存扣减重复了两次。追根溯源，是那个"特判"里少考虑了一种并发场景，恰好被凌晨的补偿任务触发。

小林已经不困了，处于一种诡异的清醒状态。他盯着监控大盘，忽然觉得自己不是在修 bug，是在一个游乐场里打地鼠——锤子落下去，这只鼠进洞了，另一只从旁边的洞口冒了出来，甚至怀疑是同一只，绕到了背后。

八点，天亮，第四个 bug 冒头的时候，产品经理发来消息："问一下，加个新功能大概什么时候能排上？"

小林看着这条消息，第一次认真地思考了退出这个行业的可能性，然后关掉聊天窗口，继续打地鼠。

---

## 打磨匠

雕匠陈师傅接了个活，给庙里刻一尊佛像，工期两个月。他每天雕一点，反复端详，觉得眉心的弧度不够慈悲，重刻；衣纹的褶皱不够自然，重刻；佛像的手指比例，他觉得差了那么一丝，又重刻。

两个月到了，佛像雕了三分之二，陈师傅说，快了，再给我半个月，一定精益求精。

半个月又半个月，庙里换了三次主持，都来看过陈师傅的活，都点头说手艺是真好，然后婉转地问一句，什么时候能完工。陈师傅说，快了，这个耳垂的弧度还差一点。

庙会那天要开光，佛像还差最后一道打磨没做完，主持没办法，只好先把这尊未完工的佛像请上台座，用红布把有瑕疵的那个角落遮住。开光仪式照常举行，香客络绎不绝，没有一个人发现那处被遮住的瑕疵，也没有一个人问起。

陈师傅站在人群后面，看着自己耗时四个月、仍未完工的作品被无数人跪拜、上香、许愿，忽然明白了一件事：他一直以为自己在追求完美，其实他只是害怕那个作品被交出去以后，就再也不属于他了。

红布后面的那道瑕疵，后来再没人去补。

---

## 图纸上的墙

一家建筑公司要盖一栋写字楼，负责设计的建筑师从没来过工地，图纸都是通过邮件传给三个不同的施工队：地基队、结构队、水电队。三个队伍分处三个不同的分包公司，平时只在每周一次的视频会议上打个照面。

楼盖起来之后，大家发现一件怪事：整栋楼里，凡是需要地基队和结构队配合的地方，衔接处都特别粗糙，缝隙用水泥草草糊住；凡是结构队和水电队交界的地方，管线绕了很大的圈子，明明直线三米能到的地方，绕了十几米。

后来有个从外地来考察的工程师看了图纸，又看了实物，说了句大实话：这栋楼的结构，长得跟你们三个施工队之间的关系一模一样——凡是两拨人碰头开会才能解决的地方，就是整栋楼最丑、最绕、最经不起推敲的地方。

公司高层开会讨论要不要调整施工队的分工，讨论了三周，因为负责讨论"要不要调整分工"的，又是三个不同部门的人，谁也说服不了谁，最后不了了之。

那栋楼现在还在，粗糙的接缝处后来贴了瓷砖，看不出来了，但电梯还是要绕那十几米的弯，每天准时把所有人绕进去，再绕出来。

---

## 起名字

新来的实习生要给一个变量起名字，那个变量存的是"用户上次登录之后、到现在为止、排除掉被删除的、且已经通过审核的、非草稿状态的消息数量"。

他盯着这个变量看了十分钟，敲下的第一版名字是 `msgCount`。改完之后，他自己都不信，第二天团队里另一个人问这个变量是干嘛的，他解释了一大段，对方说，那这名字取得也太不讲究了。

他改成了 `unreadValidMsgCountSinceLastLogin`，写完自己念了一遍，感觉像在念一份判决书。有人路过看了一眼，说这也太长了吧，看着都喘不过气。

他又改成 `pendingMsgNum`，觉得简洁多了，直到三周后，另一个同事在这个变量旁边写了一个新函数，管它叫 `pendingMsg`，两个名字看起来像双胞胎，实际上一个指的是"待审核"，一个指的是"未读"，谁都不知道谁是谁。

实习期结束那天，他在交接文档里认真写下一句话："以后起名字，宁可长一点、丑一点，也别让人猜。"

他自己也知道，这句话是留给下一个要起名字的人的，而下一个人，大概率也不会看这份文档。

---

## 在我机器上是好的

测试环境挂了，开发老孙的电脑却运行得好好的。他把自己的屏幕分享出来，功能演示得行云流水，登录、下单、支付，一气呵成，全程零报错。

"你看，"他说，"在我机器上是好的。"

运维小声问了一句，你的机器上，数据库版本是多少。老孙说，不知道，反正一直没换过，从我入职那天到现在。

测试环境的数据库，三个月前升级过一个小版本。老孙的本地环境，因为他嫌升级麻烦，一直用着两年前装的那个。这两年里，操作系统打了十七个补丁，Node 版本停在他觉得"用着顺手"的那个小版本，还有一个环境变量，是他三年前为了debug另一个问题临时加的，加完就忘了，一直留在他的 `.bashrc` 里，从没告诉过任何人。

后来这事上了升级会的复盘，老孙认真地说，以后我一定注意环境一致性。会开完，他打开自己的电脑，看着那个跑了两年、如今已成为团队里唯一一台"活化石"机器，认真思考了一下要不要重装，最后决定，先不动，等这个迭代忙完再说。

他心里知道，"等这个迭代忙完"，是一句从来不会兑现的承诺，就像他机器上那个已经没人记得起因的环境变量一样，会一直留在那里，直到下一次没人能解释的报错发生。
