驾驭屎山的唯一方法,不是重构,而是不重构。
为什么有人可以在屎山里加功能?
很简单:把屎山扒拉开,每块闻一闻,找出和你要改的功能对应的那坨屎,把这坨屎包起来(封装),你就可以假装它不是屎,是巧克力。然后,在旁边拉一泡新的屎,等它风干成型(测试通过)就可以收工了。
当然,怎样优雅地在一座屎山里闪转腾挪,做到“百屎丛中过,片屎不沾身”,还是需要很多经验和技巧的。不过说白了,就算失误了摔个嘴啃屎,臭也只臭你程序员一个,老板还觉得你很努力,客户还觉得真香。
很多愣头青觉得自己是天才,可以把屎山重构了。他们中的大部分人引发了屎崩,永远埋在了几千米高的屎山之下。
极少数人活了下来。他们真的做到了,他们真的重构了整座屎山!
重构之后的那个东西,被后人称为——屎山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科普:
还有不赚钱、只求交个朋友的套装:
公司代码已经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之后,等着转圈圈,然后就会出现几百个定义索引,不是老玩家谁知道应该去哪个定义索引。
迷宫都比它简单,起码只有一条完美的出路。
真是大粪堆。
吐槽完了。继续搞这坨屎。
匿了,怕公司看。
过去一年了。感官上不一样了,再搞两年成熟练工就不再痛苦了,只是英语还需要更高的水平,听印度人讲英语还是听不懂。
先给你看一下一坨屎一样的代码
这坨屎,忍忍,你有足够的时间还可以修复的。
花了我一天追根溯源了解需求;
花了一天修改代码;
花了两天对比自测,以及尽可能遍历所有异常场景,测试会怎么样,以及询问前开发,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个人…
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 https://github.com/tostercx/GTAO_Booster_PoC
之后,把dll文件粘贴到游戏根目录下就OK!
博客原文
https://nee.lv/2021/02/28/How-I-cut-GTA-Online-loading-times-by-70/
Github地址:
https://github.com/tostercx/GTAO_Booster_PoC
看着难受,又不能改它,只要一动,山就塌了,将自己深埋屎下,臭不可闻。
就像你有几栋楼,几百个房间,手上拿着一串没有备注的钥匙,一个一个房间试,你以为你打开了,却没想,门后还有一道门。
当你费劲心思解决了所有门,你又发现,钥匙断了。
你完全不明白为什么要这样设计,那么愚蠢,当你有了个新想法,忙碌之后,又发现自己写的更蠢。
不要试图去理解它,改变它。
这是神圣的传火,让你的下一任有点事情做。
直到改出了 bug,才知道原来某行代码是干这个用的
n天后,我擦,那行代码不止干了这个
又n天后,我擦,这种代码不止一行
又n天后,妈的,老子也搞上去了几行
说到祖传代码不得不提当年在移动的一段经历。
我刚入职第一天,旁边的妹纸告诉我,你是今年第五个负责这个模块的,心里凉了半截,这TMD才七月份啊,听她说最长的干了两个月。
我就不信那个邪,页面交互一般,后端不也就增删改查?能难到哪里去。看了代码才知道,too young,too simple。里面最老的代码是09年那会的,直到现在一直在维护,今刚好十周年庆典,我光荣接盘,这大概就是代码届的接盘侠吧,现在用的还是jdk1.6,不分什么前端后端,页面都是用Java写的,最坑的是里面的js,有四五个公用的js文件,大概几万行代码,注释掉的代码占三分之二,大概是我这么多年见过最多的注释了,是谁说注释多的代码质量高的?出来,我不打死他。
说来也怪,两个月了还没给我安排需求,就是来的那个礼拜说了句让我看代码,每天早上一杯咖啡,页面点一点,心情好就看看代码,日子过得很是惬意,这大概就是程序的春天吧!真不知道前面那四个哥们放着这大好的日子不过,咋跑了呢?
一天中午,项目经理喊我,问我代码看得怎么样了?从项目架构说到业务逻辑,其实有个屁的架构,随便扯了五六分钟,项目经理笑了笑,点了点头,很是满意的样子。
“小李,这有有个bug,你去修一下“
“嗯嗯,没问题“意料之中,毕竟也快两个月了。
“下个月初,你争取弄完哈“说话的时候十七八号的样子。
“没问题。“
开始写代码了,带着一丝激动,毕竟两个多月没操练了,也带着一丝胆怯,因为是个人都能看出来这是是否能顺利转正的关键一战。
两个多月来,最认真的看了一天代码,我在哪里?我是谁?我在干什么?是哪个智障写的函数,十几个行参,变量命名汉语拼音占了一大半,我严重怀疑这是小学生写的代码,还智障一样的不分前后鼻音,小学语文老师怕是后勤老师教的(真不是看不起后勤老师),函数内部无止境的递归调用,本以为快结束了又来个回掉函数,一个函数有800多行。果然出来混还是要还的,过了两个月的春天,一下子跌进了冰窖。
这样的日子浑浑噩噩的过了七八天,招我进去的那个技术老鸟实在不忍心,过来指点我。
“小伙子,你这样看代码,估计明年春天也搞不定,你这个bug,是第三个人上线的时候写出来的,你重点看下他提交代码的部分“
一语惊醒梦中人,只能用这最白痴的办法了。
看了三天,终于找到问题所在,花了十分钟,搞定。然后技术经理核查了我两个小时代码才放心让我上线。
后面有一次和项目经理吃饭,“小李,前面四个人都跑路了,我就看好你,你知道为什么当初你刚来那两个月,我啥也没让你干?我是怕你一开始就做需求,扛不住跑路。”
“经理,那代码那么老了,怎么不重构一下“
“上一次重构代码的项目经理已经被大老板开了“
之所以被成为屎山,因为你一碰,就会屎山爆发,那画面……不忍直视!
当你看到祖传代码时:
当你尝试改动时,只删了一行代码时,可能会发生下面这种情况
有句话,说的非常好:祖传代码就像一座很大的屎山,你见过的最大的山,每次你想修正一个bug,你的工作就是爬到屎山的正中心去!
有一天,有几条虫子,干扰了老板赚钱,老板希望你能抓住它们。
你带着年轻的锐气,青春的活力,学艺多年积累的程序设计艺术,打开了公司的代码仓库。
远看,似乎一个运转的机器,巨大的代码堆积在一起形成了大致的轮廓,蠕动着前进。
凑近了一看,在不净的框架中,乱码般的语句在运转,像生了麻风病的蛞蝓一样在喷吐,粘稠的水在流动,而穿着格子衫的人群则在焰柱旁围成了一个半圆,这就是码农的仪式。他们环绕着那不可名状植物,不断的伸手进去拨弄,又不断的掏出一些东西填上去,使他对的更高,为了防止到他,又掏出黏糊糊的糊糊,用力的涂抹,试图把它们黏在一起。
这是一个前人留下的屎堆起来的一个克苏鲁缝合怪,看起来摇摇欲坠,有无数的虫子爬来爬去。但勉强堆起了山一样的形体,蠕动着为老板赚钱。
你满心热血,要对这座山进行清理,使它成为一个鲁棒的钢铁巨兽,可以随时更换最新的部件,奔腾如飞,坚固异常,带着兄弟们走向人生巅峰。
你经过缜密的分析,顺着虫子留下的痕迹,终于找到了问题的源头,发现一坨很多年前某码农因为时代局限或者水平有限拉的陈年旧屎,你觉得只要对它改良一下,梳理清楚结构,加强判断与容错,就可以变化成一个钢铁部件,让这坨怪物离巨兽更近一步。
你用力的挖掘其中的信息,却发现,事情没有那么简单,这一坨实际上不是孤立的一坨,而是和整个山体融合在一起。或者说,这座山实际上是一坨坨粘稠滑腻的克苏鲁,通过无数的触角和粘液连接在了一起,这些克苏鲁伸出无数的触角,伸进这座山体中未知的角落。
有看起来结构相同,但是出现了几十上百次的重复逻辑。有无数道不知道伸向何处的判断分支。有七零八落到处都是又无法解释的神秘数字。有从表面直接伸向最底层的神秘调用。还有猜不出,看不懂,无法预计什么时候会触发,什么时候会爆发的无数定时器。还有无数神秘的线程在独立的挂在那里,猜不出哪个什么时候会忽然启动,什么时候会忽然挂起,什么时候会忽然互相抢资源而死锁,哪些资源会莫名其妙的被改动。神秘的链接,神秘的任务队列,神秘的池,神秘的环形缓存,神秘的堆栈。
他们耦合在一起,互相支撑,构成了一坨更大的克苏鲁屎怪,缓慢的蠕动。
你极其困难的清理和修改了其中的一点点内容,让这一点点的内容脱离出耦合态,看起来清晰一点。结果,忽然屎山对面十万八千行外,你永远意想不到的一块功能,忽然挂了。一个你完全在工作上没接触过的同事,通过他的盘查,发现是他维护的一个函数/方法、类、线程、内存块,池,和你改动的部分是深度耦合的,你的解耦导致了难以理解的错误使他们的部分产生了错误。于是你被骂了,你只能再退一步,在一个更小的范围内进行调整,但是发现,虫子不止是由这一块构成的,于是你追踪者虫子的足迹,去改良一个一个的模块。
在经历了一轮又一轮的批评,几乎结识了全公司所有模块的负责人之后,你终于抓住了一条虫子。但是在这个漫长的过程中,你早已忘却初心。在无数次的赶工加班熬夜的迷糊中,被同事老板挨骂后的愤懑中,表白失败/和女朋友吵架/发现自己头顶有点绿的低落中;无数次当做临时代码写下,计划单元测试完成后就重写却忘记的过程中,因为偷懒或者不舍得打断思路而而懒得抽出轮子而产生的超大代码块中。
留下了无数看起来结构相同,但是出现了几十上百次的重复逻辑。无数道不知道伸向何处的判断分支。大量的无法解释的神秘数字。从表面直接伸向最底层的神秘调用。猜不出,看不懂,无法预计什么时候会触发,什么时候会爆发的无数定时器。无数猜不出哪个什么时候会忽然启动,什么时候会忽然挂起,什么时候会忽然互相抢资源而死锁,莫名其妙改动资源的神秘线程。神秘的链接,神秘的任务队列,神秘的池,神秘的环形缓存,神秘的堆栈。
你要抓的哪条虫子确实抓出来了。然而,在你没看到的地方,随着运转,更多的新的虫子正在茁壮的成长。
这时,你突然发现你的脚抽不出来了,几条触手顺着你的腿向上攀延,你的手被深深地吸入泥沼一样的屎山,你使尽全力想要抽出胳膊,但越是挣扎,陷得越深,仿佛屎山中心有一个冰冷的黑洞,要将所有接近的物体吞噬殆尽。你的精气在一点点流失,一种极度的疲惫,但是又释然的感觉涌了上来。此刻,你觉得舒适又满足,渐渐地闭上了双眼,你甘愿奉献头发与生命,将自己化作一块补丁,维系着系统的苟延残喘。它再也没法离开你了,你和你的头发,成了它的一部分。
不知道过了多久。终于又有一条虫子在运行中暴露,干扰了老板赚钱。
老板又安排了一个年轻人来抓住这条虫子。这个年轻人带着锐气,青春和活力来到这座山前。
看到这摇摇欲坠的克苏鲁大山,不仅倒吸一口冷气。
“oh shit ! shit mountain !”
一个很浅显的道理,世界上任何东西用久了都会坏,任何东西都有设计寿命,并且为了达到或者延长设计寿命需要投入资本去维护。
但是这个道理很多软件开发团队的管理者完全不明白。一个东西开发出来之后不再维护,那么迟早是会变成一个年久失修的机器不断地出现小毛病和大毛病直到无法使用。
很多祖传代码缺乏持续的维护,也早早就超出了设计的寿命,使得他们根本无法继续正常运转也无法维护,这是一个客观规律,和程序员是不是负责任,文档、注释或者代码质量并没有关系。当然,一个质量好的软件系统他的寿命会更长一些,但迟早也会变成一堆垃圾。
更何况,我们开发的软件永远是解决眼下的问题,而不是面向未来编程。信息产业发展的如此迅猛,每五到十年软件开发中要解决的主要矛盾就会发生变化。过去的代码所解决的问题在当下根本就不存在,甚至于十几年后的从业人员根本无法理解十几年前软件开发中的主要矛盾。所以看懂代码更加成为一件不可能的事情。
通常来说,超过五年没有维护和重构的代码,没有继续维护的价值……超过十五年没有维护和重构的代码,没有使用的价值……
那不就是屎山?