问题

为什么祖传代码被称为「屎山」?

回答
我们常常听到一个让人哭笑不得的词语:“屎山”。这个词可不是随便来的,它在程序员的世界里,尤其是在面对那些年深日久、维护困难的祖传代码时,简直就是一种无奈的写照。

为什么祖传代码会被称为“屎山”呢?这背后其实隐藏着一系列复杂的问题,这些问题随着时间的推移,像滚雪球一样越滚越大,最终形成了一个难以逾越的技术障碍。

首先,我们得从历史的演变和技术的更迭说起。

设想一下,你接手了一个项目,而这个项目可能在十年前、二十年前甚至更早的时候就已经开始开发了。那个时候的技术栈、开发理念、甚至编程语言,可能和现在已经完全不一样了。

技术栈的老旧与不兼容: 很多祖传代码是用已经过时、不再被主流支持的语言或框架编写的。比如,曾经风靡一时的某个JavaScript框架,现在已经没人维护了,甚至连相关的文档都难以找到。开发者不得不花费大量时间去研究那些几乎绝迹的技术,而这些技术本身就可能存在不少已知的缺陷和安全隐患。
缺乏统一的标准和规范: 在项目初期,可能并没有建立起一套严格的编码规范。不同的开发者在不同的时期,以自己的理解和习惯来编写代码。这就导致了代码风格的混乱、命名的不一致、甚至是一些“历史遗留”的奇葩写法,它们的存在本身就让人费解。
功能的不断堆叠与耦合: 一个项目在使用过程中,需求会不断变化,功能会不断增加。为了快速响应业务需求,很多时候会选择“打补丁”的方式来添加新功能,而不是从根本上进行重构或优化。久而久之,各个模块之间的依赖关系变得异常复杂,如同缠绕在一起的毛线团,牵一发而动全身。一个简单的改动,可能就会引发一系列意想不到的连锁反应,让修复bug变成一场“拆弹”游戏。

其次,人力的因素也是造成“屎山”的重要推手。

人员流动与知识断层: 项目的核心开发者可能早就离开了公司,或者转岗到其他项目,甚至离开了这个行业。他们脑海中那些关于代码设计思路、底层逻辑的宝贵知识,并没有得到有效的传承。新接手的开发者只能通过阅读代码来理解,但如果代码本身就写得晦涩难懂,或者缺乏注释,那么理解成本就会呈指数级增长。
缺乏文档与注释: 好的代码离不开良好的文档和注释。然而,在很多祖传项目中,文档的缺失是常态。即使有注释,也可能是一些过时、错误或者含糊不清的描述。开发者只能靠“猜”和“试错”来摸索代码的含义,这种低效且充满风险的工作方式,极大地降低了开发效率和代码质量。
“不敢改”的心态: 当一个项目已经运行多年,虽然存在各种问题,但“还能用”的状态也会让一部分开发者产生畏难情绪。他们害怕对代码进行改动,担心会引入新的bug,或者破坏现有的功能。这种“求稳”的心态,反而固化了“屎山”的存在,阻碍了项目的健康发展。

再者,从技术本身的特性来看:

复杂的逻辑和算法: 有些项目可能涉及复杂的业务逻辑、算法或数据处理。如果这些内容在早期没有得到清晰的设计和良好的封装,就会使得代码非常难以理解和维护。例如,一段处理复杂财务计算的代码,如果没有很好的模块化和清晰的命名,开发者可能需要花费数天才能弄清楚其中的计算逻辑。
“意大利面条式”代码: 这种代码指的是代码的执行流程非常混乱,充斥着大量的`goto`语句(虽然现代语言中很少用,但早期C语言中常见)或者非结构化的控制流。开发者在阅读时,很难理清代码的执行路径,就像在意大利面条里找一根面条一样困难。
“魔法数字”和硬编码: 代码中充斥着大量没有解释意义的数字或字符串,这些被称为“魔法数字”或硬编码。例如,一个配置参数直接写在代码里,而不是通过配置文件或常量来表示。当需要修改这个参数时,开发者就必须搜索整个代码库,找到所有出现这个数字的地方,非常容易出错。

综合以上这些因素,祖传代码就像一座堆积如山的垃圾,里面可能还埋藏着一些有用的“宝藏”,但要找到它们,就得冒着被“毒气”熏晕的风险,而且工作量巨大。每一次的修改,都像是在这座“山”上小心翼翼地挖洞,生怕引起“雪崩”。

所以,“屎山”这个词,虽然粗俗,却生动形象地描绘了那些难以理解、难以维护、技术陈旧、结构混乱的代码库。它不仅仅是对代码本身的一种描述,更是对开发者在面对这些代码时那种身心俱疲、又无可奈何的真实写照。想要清理“屎山”,需要的不仅仅是技术能力,更需要的是勇气、耐心和对项目长远发展的决心。

网友意见

user avatar

驾驭屎山的唯一方法,不是重构,而是不重构

为什么有人可以在屎山里加功能?

很简单:把屎山扒拉开,每块闻一闻,找出和你要改的功能对应的那坨屎,把这坨屎包起来(封装),你就可以假装它不是屎,是巧克力。然后,在旁边拉一泡新的屎,等它风干成型(测试通过)就可以收工了。

当然,怎样优雅地在一座屎山里闪转腾挪,做到“百屎丛中过,片屎不沾身”,还是需要很多经验和技巧的。不过说白了,就算失误了摔个嘴啃屎,臭也只臭你程序员一个,老板还觉得你很努力,客户还觉得真香。

很多愣头青觉得自己是天才,可以把屎山重构了。他们中的大部分人引发了屎崩,永远埋在了几千米高的屎山之下。

极少数人活了下来。他们真的做到了,他们真的重构了整座屎山!

重构之后的那个东西,被后人称为——屎山2.0。

当一个系统复杂度增加的时候,它的熵也会增加,这是宇宙规律。而某些有洁癖的码农,他们非要强行降低这个复杂系统的熵——不是做不到,但需要巨大的能量,也就是成本。

你想让谁来付这个成本?老板还是客户?

屎山不是一天拉成的。每一代屎山的建设者,都是非常聪明的人。他们非常清楚继续堆高屎山,未来将产生的代价。他们理性中立客观地评估了推翻屎山重建的成本,然后做出了一个充满智慧的决定:

在屎山上继续拉屎。

这个决定对于每一个人都是最优解,因为每一个人只需要对他当下的目标负责。每一次“继续拉屎”的决定都是正确的,不这样做才令人匪夷所思。如果重构屎山,客户很生气,因为交付时间更长了,还会冒出许多以前没有的bug。老板很生气,因为成本大增,而客户毫无多付钱的意思。就连重构屎山的人自己也很生气:天天钻在屎山里996,搞得浑身屎味,工资却一分钱没涨。

尿海不择细流,故能成其大;屎山不拒细壤,方能就其高。屎山就这样一天天长大,终于令最后接手的码农感叹:高山仰止,景行行止。

其实,屎山,是任何复杂系统的终极归宿。无论你使用何种语言,师从什么流派,哪怕23种设计模式样样精通,最终还是会踏上前往屎山的道路。因为,条条大路通屎山。

就连微软、谷歌、Oracle这样的大公司,他们的产品也都是屎山。Oracle每改一个功能,全公司的服务器需要全速测试几个月。chromium浏览器的源码有十几个G,虽然是开源的,但没有人敢在如此险峻的屎峰上提交自己微不足道的屎坷垃,高处不胜寒。

至于微软,呵呵……从win8到win11,10年了,控制面板还是有两种口味:一种是古早味的,一种是苹果味的。office从2016到2021,5年了,不拿放大镜都看不出有什么区别。

这段话可能会让你误以为,微软、谷歌都是垃圾。但实际上,他们是地球上最强的软件公司。世界上最高的屎山,都是最聪明的屁股拉出来的。换了一般的程序员,屎山还没垒出一个小屎包,就屎崩了,就这点水平还天天嚷嚷着要重构屎山。

乔布斯曾说:死亡是最好的创新。所有代码的最终归宿都是坟墓,而绝大多数代码早已死无葬身之地。屎山是不可能重构的,这辈子都不可能重构的。打败屎山的唯一方法,唯有另起炉灶,建一座新的屎山。这就是为什么在巨头们巍峨连绵的屎山脚下,总能有新的小屎包崛起。

当然,对于血气方刚的少年,我知道,你很可能觉得我在扯淡,屎山有什么好怕的,重构就是了。

明知山有屎,偏向屎山行。来,壮士,干了这碗屎,我绝不会拦着你。

我只会献上一本秘籍,祝你早日成功:


作为一名有理想的程序猿,我也在努力建造自己的屎山。

我想做一个能直接翻译英文pdf的工具,不是划词翻译那种,而是一次性翻译整个文件,英文pdf进,中文pdf出。这样看论文就可以偷懒了~

链接如下,感兴趣的同学可以试试。目前只有PC版,APP的坑一直没填:

大中华区Rust语言代言人 @张汉东 老师在试吃之后,只评论了两个字:

神器

他翻译的pdf是这样的:

说实话,得到这样的评价实在出乎我的意料,因为我还从没试过翻译编程领域的文章,初看貌似效果还行。不过,我在受宠若惊的同时,也暗暗感到惭愧。因为只有我自己知道,屎山里还有多少坑没填……

不说了,我要进屎山填坑了……


如果你喜欢我这种用脱口秀style把道理讲通透的风格,可以尝尝我最近出版的两本科普书。这两本书都入选了2021年度CCF“科普阅读推荐图书”榜单。CCF是什么,对于程序员就不需要介绍了吧……

一本既不吹捧科学家的伟大、也不纠结历史细节、只想让你无废话看懂量子、还吭哧吭哧手绘100多张彩色漫画实验图解的硬核科普:

一本不屑于教Python和调参、只想和你探讨人类命运和智能本质的AI科普:

还有不赚钱、只求交个朋友的套装:

user avatar

公司代码已经40年了,最早写代码的人不知道是否活着,要命的是文档没留下。

你们几千几万代码算什么,这个比微软系统还大。项目代码堆在一起有90多G,目测过千万行。

像int2 int4 int8 uint12345678这种类型定义上千种。无意中,翻出了一个用于定义的头文件,24万行的#define,我不知道这是不是人类写的。

我们有个古老的更新记录,当然,没有汉化版,像读一本流水账样的历史书。代码被美国人、印度人、中国人、澳洲人都更新过。

时代在发展。
像文本格式的数据库早就不用了,而我们却在用它包装n层并转换成sql。
你问我们怎么添加一列数据库字段,嘿,用手写数据库,用祖传的文本工具把它转换成代码,再添加进各个工程配置中,再一个个的编译,别忘了在sql中添加这一列,对了,你用多大的数据要写清楚,32字节,不要写多也不要写少,中间空4个空格你知道吗?写错了整个工程会出现莫名奇妙的错误。这些做完了。一天结束了。

像MFC已经不美了,我们却用托管C++强行封装并中转成WPF,然后,引用WCF是作为中间桥梁进行通信的。
托管C++你们知道吗?那可是编译器都看不懂的东西。能编译通过,只是在编写的时候一直是上万个报错的,你要自己用脑子想这东西能不能编译,不能依赖VS自动检查功能。
由于底层各种封装,封成迷宫了,VS经常解读到崩溃,编译到死机,自己去看的时候,几百层的调用栈中又有几百种重构函数。
工程之间的逻辑好复杂,主要是几千个工程太多了,dll与lib已经傻傻的分不清楚了,哪些有哪些的依赖,先编译这几十个工程,然后才能编译那几十个工程,要按照一定顺序来,不然依赖会报错。想哭。

哦。。我在里面添加个helloworld是多么不容易,要写一天,模块上千个,结构体万万不能动,任何一个结构体的修改会导致整个项目的瘫痪并要重新编译一整天(也许到最后是失败的)。
看代码就像走迷宫,对着一个函数按下F12之后,等着转圈圈,然后就会出现几百个定义索引,不是老玩家谁知道应该去哪个定义索引。

迷宫都比它简单,起码只有一条完美的出路。

真是大粪堆。
吐槽完了。继续搞这坨屎。

匿了,怕公司看。

过去一年了。感官上不一样了,再搞两年成熟练工就不再痛苦了,只是英语还需要更高的水平,听印度人讲英语还是听不懂。

user avatar

先给你看一下一坨屎一样的代码

这坨屎,忍忍,你有足够的时间还可以修复的。


花了我一天追根溯源了解需求;

花了一天修改代码;

花了两天对比自测,以及尽可能遍历所有异常场景,测试会怎么样,以及询问前开发,leader,产品,各个相关人士,这些问题得意见;

然后上线预防环境clone请求并行跑1天,对比两边结果是否一致,研究不一致的原因,并解决;

最后才正式上线…

300行代码终于变成30行..



如果这样的狗屎增加100倍,并随机遍布到其他100w行的正常代码中。

你试一下去解决一个bug?

你就会体会到攀爬一座屎山,并在上面采摘一个可以食用得部分的那种独特快感..


你除了骂一句 谢特shit,别无他法。


2021年6月1日

给大家介绍一下比上面更牛逼的狗屎代码。

先说最大的一个问题,增加一个字段需要同时修改10多个子项目,提交10多次github,build这些模块之前先instal一轮,模块之间编译安装的还有依赖先后..

这完美分布式单体应用,成功锁死所有修改,牵一发而动全身,这句话我算是懂了。


还有分支用来区分客户的。比如分支名huawei,就是客户华为,分支名weiruan。就是微软..….其他人无权利创建分支。

方便他自己管理项目呗


因此任意修改代码都需要“架构师”亲子处理,无其他人可以搞定。

另外公司离不开他了,整个团队中中他永远是受益者,不管招聘多少人开发效率还是太低了….一直加人…全体996也不行..然后他拥有了80多个下属….离职率百分80(能呆着超过2年的员工只有3人..).…@可他已经升级成公司技术vp..




评论区的说kpi的同学,这就是你们想要的真实故事。

哈哈哈哈哈哈


那个代码我感觉挺多人说挺好的,没问题。

怎么说呢,确实没问题。

直男癌和撩妹高手的差别吧。

举个例子:

直男:我想和你嘿嘿嘿

撩妹高手: 我想和你一起看日出的


绝大多数人对于屎山是痛恨的,但是自己写的时候又还是写成了狗屎(包括我自己..)

这是人性,能偷懒不香嚒?做一些看不到眼前利益得事情,没动力呀。

所以才有重构,重构就是为了解决这个问题。

大概思路:

1写最直觉无脑版本代码

2优化变量名称,函数结构,提取方法,类。抽象

3刷代码规范,魔法值呀,变量eqs常量 反过来呀,bean copy用工具类,

4面向对象的优化,函数式优化

5优化过多if

6性能优化

7更好的中间件选行替代

8容错,高可靠,高可用优化

每次一点点的来,没几个人能一步写到位。


2022年2月25日

那个架构师,升级成副总之后,半年不到,巅峰结束..…他被降级成为了team leader ,管10个人…

user avatar

R星大作GTA 5里面,也有“屎山”代码,你信吗?

一个if循环19.8亿次!!!

而且,上线7年,这个祖传的“屎山”一直没人动....

————————————————————————————————————————————
3月16日更新:

GTA 5“屎山”代码后续来了。

R星终于官宣准备修复了!

主动改善玩家游戏体验?不存在的。

要主动,哪里还要等七年?

这篇揭R星老底的帖子在全网大火后,R星不得不出面应对。

在和黑客大哥联系后,R星认可了他的改进方法,宣布在后续更新中修复相关问题,并且还慷慨的给他付了一笔1万美元的奖金。

鉴于R星失误实在太低级太离谱,而这位老哥的方法又太有效,以致无数玩家称他“功德无量”。

如果平均给每个玩家节省10秒,全球500万玩家一天就能节约5000万秒,一年中,节约的总时间大概能有数十年。相当于挽救了十多个人的生命!

“事了拂衣去,不留功与名”,这位黑客大哥被无数玩家膜拜。当然大家也不忘再把R星拖出来“鞭尸”。

有人吐槽,GTA 5仅2020年就买了2000万份,累计销量更是达到1.4亿份,R星每年都能从这个项目上赚数亿美元,但是却不肯花几分钟去解决这么一个低级错误,实在可耻。

还有人抨击R星几乎从不与玩家社区互动,玩家提的意见也从来充耳不闻,直到这次被被黑客嘲讽打脸,才不得不出来表态。

事后,黑客大哥还透露了一丝身份信息,原来他人在拉脱维亚。

拉脱维亚是波罗的海国家,原来是前苏联加盟国之一。在网上搜索相关信息,可以发现“拉脱维亚黑客”,几乎是和俄罗斯黑客一样传奇神秘的存在。

有网友爆料,在拉脱维亚,普通程序员工资平均3-4k欧元(23000-31000人民币)。

而他领到的这1万美元奖金,相当于三四个月工资了。

提前领了一笔“年终奖”,黑客大哥表示很开心。同时他也说,将密切关注GTA 5未来更新,一丝不苟的检查修复情况。

不知道他还能不能从R星领走更多奖金

(注:所谓“屎山”,是程序员间流传的一个梗,指陈年累月且复杂低效的代码,因为改动成本巨大,所有人避之不及。)

——————————————————————————————————————————

GTA 5“屎山代码”前情回顾:

一支烟的功夫,GTA 5联机版终于打开了。


「7年了!GTA 5联机版加载还是这么慢??」


Please wait forever to play
Reddit、Steam、HackerNews上,无数玩家吐槽抱怨……
进游戏少则等5、6分钟,多则20分钟。
终于,一个黑客大哥实在忍不了,用逆编译器逐条查看运行情况,终于找到原因。
原来,R星(游戏开发商RockStar)写的代码太低效,加载时,一个if语句竟然循环了19.8亿次….
幕后黑手:谁占用大量时间?
加载GTA 5 Online到底有多慢?


硬件拉满的土豪玩家请无视
Reddit相关板块发起的调查中,超过80%的玩家,都要等3分钟以上,有的甚至超过15分钟。
而且,从7年前Online上线到今天,这个情况丝毫没有改善。
暴躁的,已经骂起了脏话……


但奇怪的是,如果你选择是故事模式(单机版),加载就会快很多,感觉甚至像两个不同的工作室开发的游戏。
具体到这位黑客大哥的例子,他自己的硬件配置如下:


CPU,是老而弥坚的AMD FX-8350,2012年上市,采用“推土机”架构,超频潜力惊人。
显卡还是GTX 1070。
这样今天看起来老旧的配置,打开单机版GTA 5需要1分10秒,而加载联机版则6分钟起。
黑客大哥用了最简单的Windows任务管理器,来判断联机版GTA 5在启动时,都调用了哪些计算机资源。


在1分钟的时间分界线上,之前是加载的是单机和联机版通用的基础内容,之后是联机版独有的内容。
可以看到,联机版GTA 5,加载时调用大量CPU资源至少长达4分钟之久。
而同时,内存、GPU、硬盘的使用情况几乎没有明显变化。
所以,问题大概率出在代码上。
“R星代码写太烂!”
黑客大哥在开扒R星代码之前,就说:
我闻到一股烂代码的味道…..
为了找出到底那一部分程序卡住了CPU,他使用了工具Luke Stackwalker,对CPU任务堆栈进行采样分析。
Luke Stackwalker对于闭源应用程序,可以转存正在运行的进程堆栈,和当前指令指针的位置,以一定时间间隔建立一个调用树。
最后将数据整合,就可以得到程序运行统计数据。
从结果上看,一共有两个函数“卡住”了CPU:


于是他使用专业的代码拆解工具,给GTA 5来了一个“开膛破肚”。
沿着调用栈往下走,发现问题出在一个sscanf函数上。


sscanf的功能是读取格式化的字符串中的数据,而在GTA 5中,它正在读取的是一个10M左右,有63000多个条目的JSON文件。
这个文件到底是干什么用的?黑客大哥推测,这可能是游戏内购商店的相关内容。


在具体运行时,sscanf对于每个有效值,逐个读取每一个字符,然后返回结果,之后指针移向下一个值,循环往复……直到把10M文件全部扫一遍。
再看第二个问题,这是一个存储命令,对象是item,具体是什么不得而知。
但是保存前,有一个if语句,逐一比较item内项目的哈希值,检查它们是否出现在某一列表中。
按照他的计算,这一步if,要执行(63000^2+63000)/2 = 1984531500次!
没错,等待加载前的十多分钟里,GTA 5用你的CPU,执行了19.8亿次if命令。


如此简单粗暴的编程思路,让这位老哥哭笑不得:
既然对象有唯一哈希值,那为什么不用hash map???



(hashmap根据hashCode值存储数据,大多数情况下可以直接定位到它的值,因而具有很快的访问速度,但遍历顺序不确定。)

至于为什么这样,有网友推测最开始,if的循环次数并没有这么多,而是随着开发,条目不断增多,最后到了积重难返的地步。

而之前的代码结构,谁也不愿意去动。

就这样,19.8亿次if,一遍遍在世界各地玩家cpu上上演。。。

这是不是堪称游戏开发史上最意外的“屎山”代码?


问题解决,加载时间节省70%
至于第一个问题,黑客大哥采用hook大法,不一一读取字符串,而是:
hook strlen
“缓存 “字符串起始和当前长度。
如果在字符串范围内函数在此被调用,返回缓存的值
至于if语句问题,就更直接了——完全跳过重复检查,利用hash map插入项目,因为这些值是唯一的。
最后的结果如下:


现在,GTA 5联机版加载,从原来的6分钟,下降到现在的1分50秒!而且,用的还是七八年前的硬件配置。
在此,应该手动@R星:你学废了吗?


这位黑客大哥在博文中没有留下任何身份信息,也没有透露用的反编译工具,但是做好事不留名的他,把打好包的工具上传到了Github,玩家通过一行代码就能下载:


git clone —recurse-submodules
github.com/tostercx/GTA


之后,把dll文件粘贴到游戏根目录下就OK!
博客原文

nee.lv/2021/02/28/How-I
Github地址:

github.com/tostercx/GTA

user avatar

看着难受,又不能改它,只要一动,山就塌了,将自己深埋屎下,臭不可闻。

就像你有几栋楼,几百个房间,手上拿着一串没有备注的钥匙,一个一个房间试,你以为你打开了,却没想,门后还有一道门。

当你费劲心思解决了所有门,你又发现,钥匙断了。

你完全不明白为什么要这样设计,那么愚蠢,当你有了个新想法,忙碌之后,又发现自己写的更蠢。

不要试图去理解它,改变它。

这是神圣的传火,让你的下一任有点事情做。

user avatar

直到改出了 bug,才知道原来某行代码是干这个用的


n天后,我擦,那行代码不止干了这个


又n天后,我擦,这种代码不止一行


又n天后,妈的,老子也搞上去了几行

user avatar

说到祖传代码不得不提当年在移动的一段经历。

我刚入职第一天,旁边的妹纸告诉我,你是今年第五个负责这个模块的,心里凉了半截,这TMD才七月份啊,听她说最长的干了两个月。

我就不信那个邪,页面交互一般,后端不也就增删改查?能难到哪里去。看了代码才知道,too young,too simple。里面最老的代码是09年那会的,直到现在一直在维护,今刚好十周年庆典,我光荣接盘,这大概就是代码届的接盘侠吧,现在用的还是jdk1.6,不分什么前端后端,页面都是用Java写的,最坑的是里面的js,有四五个公用的js文件,大概几万行代码,注释掉的代码占三分之二,大概是我这么多年见过最多的注释了,是谁说注释多的代码质量高的?出来,我不打死他。

说来也怪,两个月了还没给我安排需求,就是来的那个礼拜说了句让我看代码,每天早上一杯咖啡,页面点一点,心情好就看看代码,日子过得很是惬意,这大概就是程序的春天吧!真不知道前面那四个哥们放着这大好的日子不过,咋跑了呢?

一天中午,项目经理喊我,问我代码看得怎么样了?从项目架构说到业务逻辑,其实有个屁的架构,随便扯了五六分钟,项目经理笑了笑,点了点头,很是满意的样子。

“小李,这有有个bug,你去修一下“

“嗯嗯,没问题“意料之中,毕竟也快两个月了。

“下个月初,你争取弄完哈“说话的时候十七八号的样子。

“没问题。“

开始写代码了,带着一丝激动,毕竟两个多月没操练了,也带着一丝胆怯,因为是个人都能看出来这是是否能顺利转正的关键一战。

两个多月来,最认真的看了一天代码,我在哪里?我是谁?我在干什么?是哪个智障写的函数,十几个行参,变量命名汉语拼音占了一大半,我严重怀疑这是小学生写的代码,还智障一样的不分前后鼻音,小学语文老师怕是后勤老师教的(真不是看不起后勤老师),函数内部无止境的递归调用,本以为快结束了又来个回掉函数,一个函数有800多行。果然出来混还是要还的,过了两个月的春天,一下子跌进了冰窖。

这样的日子浑浑噩噩的过了七八天,招我进去的那个技术老鸟实在不忍心,过来指点我。

“小伙子,你这样看代码,估计明年春天也搞不定,你这个bug,是第三个人上线的时候写出来的,你重点看下他提交代码的部分“

一语惊醒梦中人,只能用这最白痴的办法了。

看了三天,终于找到问题所在,花了十分钟,搞定。然后技术经理核查了我两个小时代码才放心让我上线。

后面有一次和项目经理吃饭,“小李,前面四个人都跑路了,我就看好你,你知道为什么当初你刚来那两个月,我啥也没让你干?我是怕你一开始就做需求,扛不住跑路。”

“经理,那代码那么老了,怎么不重构一下“

“上一次重构代码的项目经理已经被大老板开了“

user avatar

之所以被成为屎山,因为你一碰,就会屎山爆发,那画面……不忍直视!


当你看到祖传代码时:



当你尝试改动时,只删了一行代码时,可能会发生下面这种情况



有句话,说的非常好:祖传代码就像一座很大的屎山,你见过的最大的山,每次你想修正一个bug,你的工作就是爬到屎山的正中心去!

user avatar

有一天,有几条虫子,干扰了老板赚钱,老板希望你能抓住它们。

你带着年轻的锐气,青春的活力,学艺多年积累的程序设计艺术,打开了公司的代码仓库。

远看,似乎一个运转的机器,巨大的代码堆积在一起形成了大致的轮廓,蠕动着前进。

凑近了一看,在不净的框架中,乱码般的语句在运转,像生了麻风病的蛞蝓一样在喷吐,粘稠的水在流动,而穿着格子衫的人群则在焰柱旁围成了一个半圆,这就是码农的仪式。他们环绕着那不可名状植物,不断的伸手进去拨弄,又不断的掏出一些东西填上去,使他对的更高,为了防止到他,又掏出黏糊糊的糊糊,用力的涂抹,试图把它们黏在一起。

这是一个前人留下的屎堆起来的一个克苏鲁缝合怪,看起来摇摇欲坠,有无数的虫子爬来爬去。但勉强堆起了山一样的形体,蠕动着为老板赚钱。

你满心热血,要对这座山进行清理,使它成为一个鲁棒的钢铁巨兽,可以随时更换最新的部件,奔腾如飞,坚固异常,带着兄弟们走向人生巅峰。

你经过缜密的分析,顺着虫子留下的痕迹,终于找到了问题的源头,发现一坨很多年前某码农因为时代局限或者水平有限拉的陈年旧屎,你觉得只要对它改良一下,梳理清楚结构,加强判断与容错,就可以变化成一个钢铁部件,让这坨怪物离巨兽更近一步。

你用力的挖掘其中的信息,却发现,事情没有那么简单,这一坨实际上不是孤立的一坨,而是和整个山体融合在一起。或者说,这座山实际上是一坨坨粘稠滑腻的克苏鲁,通过无数的触角和粘液连接在了一起,这些克苏鲁伸出无数的触角,伸进这座山体中未知的角落。

有看起来结构相同,但是出现了几十上百次的重复逻辑。有无数道不知道伸向何处的判断分支。有七零八落到处都是又无法解释的神秘数字。有从表面直接伸向最底层的神秘调用。还有猜不出,看不懂,无法预计什么时候会触发,什么时候会爆发的无数定时器。还有无数神秘的线程在独立的挂在那里,猜不出哪个什么时候会忽然启动,什么时候会忽然挂起,什么时候会忽然互相抢资源而死锁,哪些资源会莫名其妙的被改动。神秘的链接,神秘的任务队列,神秘的池,神秘的环形缓存,神秘的堆栈。

他们耦合在一起,互相支撑,构成了一坨更大的克苏鲁屎怪,缓慢的蠕动。

你极其困难的清理和修改了其中的一点点内容,让这一点点的内容脱离出耦合态,看起来清晰一点。结果,忽然屎山对面十万八千行外,你永远意想不到的一块功能,忽然挂了。一个你完全在工作上没接触过的同事,通过他的盘查,发现是他维护的一个函数/方法、类、线程、内存块,池,和你改动的部分是深度耦合的,你的解耦导致了难以理解的错误使他们的部分产生了错误。于是你被骂了,你只能再退一步,在一个更小的范围内进行调整,但是发现,虫子不止是由这一块构成的,于是你追踪者虫子的足迹,去改良一个一个的模块。

在经历了一轮又一轮的批评,几乎结识了全公司所有模块的负责人之后,你终于抓住了一条虫子。但是在这个漫长的过程中,你早已忘却初心。在无数次的赶工加班熬夜的迷糊中,被同事老板挨骂后的愤懑中,表白失败/和女朋友吵架/发现自己头顶有点绿的低落中;无数次当做临时代码写下,计划单元测试完成后就重写却忘记的过程中,因为偷懒或者不舍得打断思路而而懒得抽出轮子而产生的超大代码块中。

留下了无数看起来结构相同,但是出现了几十上百次的重复逻辑。无数道不知道伸向何处的判断分支。大量的无法解释的神秘数字。从表面直接伸向最底层的神秘调用。猜不出,看不懂,无法预计什么时候会触发,什么时候会爆发的无数定时器。无数猜不出哪个什么时候会忽然启动,什么时候会忽然挂起,什么时候会忽然互相抢资源而死锁,莫名其妙改动资源的神秘线程。神秘的链接,神秘的任务队列,神秘的池,神秘的环形缓存,神秘的堆栈。

你要抓的哪条虫子确实抓出来了。然而,在你没看到的地方,随着运转,更多的新的虫子正在茁壮的成长。

这时,你突然发现你的脚抽不出来了,几条触手顺着你的腿向上攀延,你的手被深深地吸入泥沼一样的屎山,你使尽全力想要抽出胳膊,但越是挣扎,陷得越深,仿佛屎山中心有一个冰冷的黑洞,要将所有接近的物体吞噬殆尽。你的精气在一点点流失,一种极度的疲惫,但是又释然的感觉涌了上来。此刻,你觉得舒适又满足,渐渐地闭上了双眼,你甘愿奉献头发与生命,将自己化作一块补丁,维系着系统的苟延残喘。它再也没法离开你了,你和你的头发,成了它的一部分。

不知道过了多久。终于又有一条虫子在运行中暴露,干扰了老板赚钱。

老板又安排了一个年轻人来抓住这条虫子。这个年轻人带着锐气,青春和活力来到这座山前。

看到这摇摇欲坠的克苏鲁大山,不仅倒吸一口冷气。

“oh shit ! shit mountain !”

user avatar

一个很浅显的道理,世界上任何东西用久了都会坏,任何东西都有设计寿命,并且为了达到或者延长设计寿命需要投入资本去维护。


但是这个道理很多软件开发团队的管理者完全不明白。一个东西开发出来之后不再维护,那么迟早是会变成一个年久失修的机器不断地出现小毛病和大毛病直到无法使用。


很多祖传代码缺乏持续的维护,也早早就超出了设计的寿命,使得他们根本无法继续正常运转也无法维护,这是一个客观规律,和程序员是不是负责任,文档、注释或者代码质量并没有关系。当然,一个质量好的软件系统他的寿命会更长一些,但迟早也会变成一堆垃圾


更何况,我们开发的软件永远是解决眼下的问题,而不是面向未来编程。信息产业发展的如此迅猛,每五到十年软件开发中要解决的主要矛盾就会发生变化。过去的代码所解决的问题在当下根本就不存在,甚至于十几年后的从业人员根本无法理解十几年前软件开发中的主要矛盾。所以看懂代码更加成为一件不可能的事情。



通常来说,超过五年没有维护和重构的代码,没有继续维护的价值……超过十五年没有维护和重构的代码,没有使用的价值……

那不就是屎山?

类似的话题

  • 回答
    我们常常听到一个让人哭笑不得的词语:“屎山”。这个词可不是随便来的,它在程序员的世界里,尤其是在面对那些年深日久、维护困难的祖传代码时,简直就是一种无奈的写照。为什么祖传代码会被称为“屎山”呢?这背后其实隐藏着一系列复杂的问题,这些问题随着时间的推移,像滚雪球一样越滚越大,最终形成了一个难以逾越的技.............
  • 回答
    “我们凭什么代替祖辈去原谅日本人呢?”这个问题触及了历史、情感、道德和世代责任等多个层面,它是一个复杂且充满争议的话题。要详细地探讨这个问题,我们需要从以下几个角度去审视:1. 历史的伤痕与记忆: 不可磨灭的罪行: 日本在二战期间犯下的战争罪行,如南京大屠杀、慰安妇制度、细菌战、强制劳役等,给中.............
  • 回答
    关于祖先坟墓中的文物为何要属于国家,这背后涉及复杂的历史、文化、法律和伦理考量。简单来说,是为了保护、传承人类共同的文化遗产,防止私有化带来的破坏和流失,并促进科学研究和公众共享。下面我们来详细阐述其中的原因:一、 文化遗产的普遍性和不可再生性 全人类的共同财富: 考古发现的文物,特别是那些具有.............
  • 回答
    这是一个很有意思的问题,涉及到语言、文化、历史以及我们对国家和亲情关系的认知。为什么我们习惯于称呼“祖国母亲”,而不是“祖国父亲”呢?这其中有很多层含义,我们可以一层层地剥开来看。首先,从最直观的“母”与“父”的意象出发。“母亲”通常与孕育、滋养、温暖、包容、牺牲、慈爱、养育后代这些概念紧密相连。一.............
  • 回答
    明朝在边疆政策上未能像唐朝和清朝那样大规模占领蒙古地区,这一现象涉及多方面的历史、地理、政治和军事因素。以下从多个角度进行详细分析: 一、历史背景与政治意图的差异1. 唐朝的扩张意图 唐朝(618–907年)在统一中国后,对北方边疆的扩张具有强烈的军事野心。唐太宗李世民(626–649年)通.............
  • 回答
    这事儿说起来可就绕了。咱们的祖先,那可是在地上摸爬滚打几千年,把马、牛、狗这些个玩意儿驯得服服帖帖的,出门打猎、耕地种粮,那都少不了它们。可唯独天上飞的那帮子,比如鹰啊、老鹰啊,甚至是那会儿可能还没多少人瞧得上的麻雀,怎么就没能乖乖地被咱们套上缰绳,当个“空中坐骑”呢?这事儿,得从几个方面掰扯掰扯。.............
  • 回答
    《魔道祖师》的同人圈里,薛晓(薛洋与晓星尘)和双道长(薛洋与晓星尘,此处“双道长”可能指他们两人作为道门修士的身份组合,或者更常被用来指代薛洋与晓星尘的CP)的配对,确实各有其拥趸。不过,如果要说为什么薛晓这个组合有时候会比“双道长”(如果我们将其理解为更强调他们作为“道长”身份的互动,或者某种基于.............
  • 回答
    你这个问题问得特别好,也特别普遍。很多人看到现在世界上人与人之间肤色、发质、面部特征等等方面的差异,确实会觉得和“同一批祖先”这个说法有点出入。但这其实是人类漫长演化过程中,一种非常自然且必然的结果。想象一下,我们的共同祖先,可能生活在非洲,那里的环境就是他们生活、繁衍、适应的全部。但随着时间流逝,.............
  • 回答
    关于“炎黄子孙”与满族人是中国人的身份认同,这其中涉及复杂的历史演变、民族融合以及国家构建的议题。要理解这一点,我们需要深入探讨几个关键层面。首先,我们得明白“炎黄子孙”这个概念的来源和它在现代中国语境下的含义。“炎黄子孙”的说法,主要源自中国古代关于人文始祖的传说。根据传统史书和神话传说,华夏民族.............
  • 回答
    要说这事儿,咱得掰开了揉碎了聊。孙悟空被菩提祖师赶出门,按理说,师徒缘分断了,名号这玩意儿,理应跟着断干净。可菩提老祖偏偏没这么干,这背后,可是有大有讲究的,绝不是简简单单的“不乐意”能解释的。首先,咱们得明白,菩提祖师传给孙悟空的这个“孙悟空”的名字,可不是咱们寻常起的“小明”、“小红”那般简单。.............
  • 回答
    这个问题涉及到了网络文化、政治语境以及群体认同等多个层面,而且“粉红蛆”这个词本身带有强烈的贬义和攻击性。要理解为什么有些爱国网友会被这样称呼,需要从几个角度来分析:首先,我们要明白“粉红”这个词的来源和含义演变。 “小粉红”的起源: 最初,“小粉红”这个词源于中国一个网络论坛上的一个文学作品,.............
  • 回答
    蒙提祖玛的宝藏,一个曾在欧美游戏圈激起阵阵涟漪的名字,其独特的玩法和精美的画面无疑吸引了不少玩家。然而,放眼中国的手游市场,我们却鲜少看到类似“蒙提祖玛的宝藏”这样以“三消+RPG+资源收集”为核心玩法的游戏大放异彩。这并非偶然,而是多种因素综合作用的结果。首先,我们要明白“蒙提祖玛的宝藏”究竟是什.............
  • 回答
    宋祖儿之所以能从一众95后小花的竞争中脱颖而出,成为备受瞩目的一员,绝非偶然。这背后,是她从小积累的观众缘、扎实的表演功底、清醒的自我认知,以及在娱乐圈这个复杂环境中难得的“少年感”与“人间烟火气”的结合。首先,我们不能忽视她早在童年时期就积累的国民度。“哪吒”这个角色,几乎是很多80后、90后甚至.............
  • 回答
    说道《倩女幽魂》(1987),提到张国荣和王祖贤的名字,总会伴随着“不可超越”这四个字。这可不是一句简单的赞美,背后藏着太多东西,是时代、是演员、是导演,更是一种难以复制的艺术魅力。咱们先说说这“不可超越”的底气在哪儿。第一,人物的经典铸就。先说哥哥张国荣演的宁采臣。在哥哥之前,宁采臣给人的印象或许.............
  • 回答
    李世民,这位唐朝的开创者,千古一帝,为何独独缺了“祖”这个至高无上的庙号?这个问题,历来都是史学界和民间津津乐道,却又不易得出一个绝对定论的。要深究起来,其中的缘由盘根错节,既关乎古代庙号的规制,也渗透着政治现实的考量,更是对这位伟大的帝王功绩的一种含蓄而又深刻的评价。一、庙号规制:非臣下所能轻易冠.............
  • 回答
    要说中国人为什么敬祖,这可不是一朝一夕的事儿,得从咱们这几千年的老祖宗说起。你想啊,在古时候,生产力不发达,很多事情都讲究个“靠山吃山,靠水吃水”,更别提什么科学解释了。这时候,家里长辈的经验、家族的传承就成了最宝贵的财富。一、 权力与秩序的基石:从氏族社会到国家你得知道,咱们中国人最早可是从氏族社.............
  • 回答
    清朝皇帝的庙号,确实存在一个特殊的现象:三个“祖”的出现,分别是太祖、世祖、圣祖。 这背后有着深刻的历史原因和政治考量,并非简单的巧合。下面我将详细解释。首先,我们需要了解什么是庙号。庙号的由来与意义:庙号是中国古代帝王死后,在宗庙中对其进行祭祀时所使用的称号。它起源于商朝,是古代宗法制度的重要组成.............
  • 回答
    .......
  • 回答
    你这个问题问得特别好,直击了生命演化的核心困惑之一:既然所有生命都来自同一个祖先,为什么进化树长得这么“复杂”、“分叉”?这背后其实是大自然鬼斧神工的“设计”和漫长岁月的“雕琢”。咱们把那个最最最遥远的“同一个祖先”想象成一颗种子,一颗极其古老、极其简单的种子。这颗种子在生命的黎明时分,它唯一的“本.............
  • 回答
    蔡恩雨小姐那番“祖国论”在马来西亚掀起巨浪,绝非偶然,它触及的是一个多年来在马来西亚华人社群中盘根错节、敏感至极的议题。这背后,是马来西亚独特的历史进程、社会结构以及华人作为少数族群所面临的身份认同挑战。要理解这件事为何如此棘手,我们得从几个层面来掰开了看。一、 历史的回响:从移民到国家公民马来西亚.............

本站所有内容均为互联网搜索引擎提供的公开搜索信息,本站不存储任何数据与内容,任何内容与数据均与本站无关,如有需要请联系相关搜索引擎包括但不限于百度google,bing,sogou

© 2025 tinynews.org All Rights Reserved. 百科问答小站 版权所有