点击上方 "编程技术圈"关注, 星标或置顶一起成长

后台回复“大礼包”有惊喜礼包!

日英文

Nothing is impossible for a willing heart.

心之所愿,无所不成。坚持一个简单的信念就一定会成功。

每日掏心话

学会坚强,因为这样才热衷于生命的意义。学会快乐,因为只有开心度过每一天,活得才精彩。

责编:乐乐 | 来自:架构头条

编程技术圈(ID:study_tech)第 1194 次推文

往日回顾:一个90后员工猝死的全过程

     

   正文   

作者 | Mehdi Zed译者 | 王强策划 | 万佳在本文,我将向你展示我见过的一些最糟糕的代码。除非你希望被同事和用户讨厌,否则这些“魔鬼”永远都不应该被放到人间。我们会发现,通过一些好的实践,其实很容易避免它们。
1“魔鬼代码”需要改进的代码与所谓的“魔鬼代码”是不一样的。
不管使用的是哪种语言,“魔鬼代码”都是糟糕的代码,因为它会危及项目的稳定性和可维护性。告诉你,我见过很多“魔鬼代码”。
当它堆积如山时,你的项目很快就会变成十八层地狱的样貌。如果你喜欢到处捅娄子,那么团队领导看你的眼光也会越来越不一样。
2模棱两可和前后矛盾很久很久以前,在一个遥远的星系中,我在一个清晨醒来,被世界末日般的景象吓得跳了一跳。
生产环境出了一个了不得的错误。生产中的所有系统票证莫名其妙地返回“null”。到处都乱成一团。所有人都像无头苍蝇一样到处乱跑。
我百米冲刺到我的工作站,第一个条件反射就是看 Kibana。没有日志,什么都没有。完蛋了,这可不是什么好的开始。
因此,我决定追溯票证的创建路径。
搜索公众号后端架构师后台回复“架构整洁”,获取一份惊喜礼包。
为此,我必须深入研究系统自盘古开天辟地以来创建的那些内部库。考古工作结束的时候,我找到了问题来源之一的一堆文件。
然后,我看到了这样的景象:
// use id and expire to get ticketasync function get_ticket(i, expire) {  return CheckisNotExp(expire).then(async function() {    var t = await GetTicketModel(i)    if (t) {      return t    } else {      logger.error(JSON.stringify(t))      return null    }  }).catch(async function(e)  {      logger.error(JSON.stringify(e))      return null})
}真的有一个“i”变量吗?我们现在在哪?这是一个 id,对不对?它是整数还是 UUID?到底是什么到期了?是日期还是时间戳?为什么会有 camelCase、PascalCase 和 snake_case?带有 promise 的异步注解和又一个异步注解?如果失败,我们会返回 null?简直是魔鬼啊!
那时,每隔 5 分钟就有一半的公司同事向我发 Skype 消息,索取 ETA 修复。
所以首先,有人需要知道这里究竟发生了什么。
我很快意识到,该为此负责的不是一个人,而是三个人。很久以前,其中两个人离开了公司,而第三个人今天早上还没来。这真是经典场景。
根据 Git 的记录,这三个人碰这个文件的时间各自差了很久。因此他们留下了不一致的代码、不同的样式、不一样的 ECMAScript 版本和不同的 promise 处理方式。
不管怎样,在这段代码中,一切都是模棱两可的,一切都是不一致的。这是一个绝佳的反面案例,你应该尽一切可能避免这种情况。不用说,代码审查并没有覆盖到这里。
现在好了,我们必须快速重写它。
我得更改那些变量和函数的名称。不能再有歧义了。各处的 Async/Await 都要做成相同的方式。
我还要确保自己不会漏掉任何错误,结果再返回一个 null。如果出现了什么问题,这些错误肯定要破坏函数。异常应由上面的层来处理。
// hotfix// @todo rewrite the ticket module entirelyasync function getTicket(ticketUuid, ticketExpirationTimestamp) {  await validTicketExpiration(ticketUuid, ticketExpirationTimestamp)  const ticket = await getTicketByUuid(ticketUuid)return ticket}最好的解决方案是重写这个模块的一部分。这里的票证验证逻辑很糟糕。但这并不是最要紧的事情。
当务之急是找出并修复错误。
在更新代码后,真正的错误开始浮出水面。前一天所做的一个配置更改改变了票证创建行为。返回到先前的配置可以立即解决这个问题。
接下来的一周时间里,有问题的模块被完全重写。
3肉酱意面很久很久以前,在一个遥远的星系中,我正在做一个代码干净整齐的产品。
作为优质产品,一切都在内部做好了优化。功能是用尽可能少的代码开发的。代码高度重视可读性。由注重整洁代码的工程师管理的代码审查流程确保了产品严格遵循所有最佳实践。
SOLID、DRY、KISS、YAGNI 和你可以想到的其他首字母缩写词,这里都能见得到。
即使做到这个地步,这个产品的某个特殊部分也会间歇性地崩溃。在一个冲刺期间,我终于设法安排出了时间来调查这件事。
很快,我意识到问题不在于产品。那些错误只有一个共同点:一个依赖项。那是一个通过内部工件处理的内部依赖项。
它由另一个团队管理,而且——令人惊讶的是——这段代码不是免费提供的。你必须先获得许可才能看到它。因此,我请求了访问权限来了解到底发生了什么事情。
然后我收到了一条 slack 消息,问我为什么要访问源码。
“你好!为什么你需要访问这个存储库?”
“你是什么意思?你知道我在这里工作吗?等等,我在路上。”
我突然出现在他面前后,终于拿到了访问该项目的权限。
我在其中看到一个文件,大小为 300KB。300KB 的文本,竟然有那么大。它已经有好几年没人碰过了。上次碰过它的那个人,我完全不认识。
简直是最可怕的魔鬼。
那是我一生中见过的规模最大的意大利面条代码。篇幅所限,我并没有把所有代码都放在这里。下面的代码只是我看到的那一坨东西的冰山一角。
小心阅读,它读起来扎眼。
// Thousands of lines of spaghetti codes
if (global.Builder){    module.exports.buildPgs = function(pgs, options, limitNodes = 0){        var config = options.config || {};        var builded = [];        pgs.each(function(pg){            var supported = pg.prop('tagName') == "INPUT"                            && pr.attr['name'] == "file"                            && options.pgs.rel.active == ""                            && global.FileReader;            if (!supported || !pg.f || pg.f.length == 0)                return;for (var i = 0; i < pg.f.length; i++)            {                builded.push({                    file: pg.f[i],                    instanceConfig: _.extend({}, config)                });if (isFunction(options.before))                {                    var returned = options.before(pg.f.path);                    if (typeof returned === 'object' && global.status.in_progress)                    {                        if (returned.action == "skip")                        {                            var needsSkip = (typeof global.status.in_progress === 'boolean' && global.status.in_progress)                                            || _.hasAny("cancel", Global._quotes.BAD_DELIMITERS)                                            || str.indexOf(Global._delimiter) > -1;if(needsSkip) return;                        }                        else if (typeof returned.config === 'object')                        {                            var LOCAL_BUILDER = new global.Builder("/builder/" + options.module + "/" + options.module + );for(var s=p,a=p.matchIndex(o),shift=0,i=0;i<a.length;i++){                                var deepcopyfile = JSON.parse(JSON.stringify(pg.f[i].getRawValue()));                                LOCAL_BUILDER.build(deepcopyfile)                                LOCAL_BUILDER.onmessage = global.Notification("buildPg", deepcopyfile);                            }                        }                    }                }            }        });    }}
// Thousands of lines of spaghetti codes我甚至都没有尝试去碰这个恶魔之子。在这类情况下,解决方案不是从代码中找出来的。我召开了一次小组会议,向他们解释具体情况。我的计划也很简单。
我们用一个已经可用的开源模块替掉了这个撒旦般的依赖项。与往常一样,这是一个大问题。必须做一些准备工作才能正确插入新的依赖项。
一开始的快速调查已经演变成持续几天的一项艰巨任务。
在会议桌那头,Scrum 主管很生气。讨论得越多,我越觉得想要不碰到该死的东西会非常困难。当我展示我们的处境后,讨论结束了,答案是不行。
“你只需要稍微动一动这个模块,把它修好就行了,然后我们会继续原本的工作。”
于是乎,我做了开发人员为代码质量和项目的可持续性应该做的额外工作。我说不行。我甚至走得更远。这是我职业生涯中的第一次,也是唯一一次,如果我被迫要辞职,我已经做好辞职的准备。
他们显然问了其他开发人员。大家都拒绝了。
由于这个问题的严重性,我争取到替换这个模块所需的时间。我为开源依赖项开发了一个小型适配器。然后我摆脱了那个被诅咒的依赖项。
此后,那个产品一切顺利,运行正常。
开发人员经常会抱怨意大利面条代码,这是有充分理由的。这是你能见过的最糟糕的代码。但无需大量投资即可确保你避免这种情况。
4驱魔一开始,本文想写的是一个最佳实践的列表。
“作为开发人员,为什么以及如何应用最佳实践。”
不过上面这个标题很容易像大剂量安眠药一般令人昏昏欲睡,此外我出于两个原因更改了计划。
首先,对于我,特别是对你来说,先谈论后果会有趣很多。对开发人员来说,这很重要,因为这就是魔鬼代码的起源。此外,如果你可以为我的遭遇会心一笑,那也很好。
其次,互联网上已经有很多关于这个主题的文章。它们都有一个共同点,就是它们的内容都是从两本书中摘出来的。这两本书培养了几代开发人员。——罗伯特·马丁的《代码整洁之道》、史蒂夫·麦康奈尔的《代码大全》
你是否真的要缩短代码审查时间,并且再也不想搞出什么魔鬼代码?直接看原始资料就行,花点时间好好看完这两本书。
我发现《代码大全》的方法更易读、更实用。但是,尽管《代码整洁之道》非常复杂,但它教给我的知识不亚于甚至超过了《代码大全》。前者里面使用的代码是 Java 和 C++,但是谁在乎具体的语言呢?你在这本书里学到的是规则和编程理念。
用代码审查来验证代码是好事情。但是,如果你不确定为什么它是好的代码,那么到头来还是会出来你经历过的魔鬼代码。
原文链接:
https://www.jesuisundev.com/en/the-worst-pieces-of-code?fileGuid=vwdYpVcQyqDCYhCrPS:欢迎在留言区留下你的观点,一起讨论提高。如果今天的文章让你有新的启发,欢迎转发分享给更多人。版权申明:内容来源网络,版权归原创者所有。除非无法确认,我们都会标明作者及出处,如有侵权烦请告知,我们会立即删除并表示歉意。谢谢!欢迎加入后端架构师交流群,在后台回复“学习”即可。在这里,我为大家准备了一份2021年最新最全BAT等大厂Java面试经验总结
别找了,想获取史上最简单的Java大厂面试题学习资料
扫下方二维码回复「手册」就好了猜你还想看
阿里、腾讯、百度、华为、京东最新面试题汇集
注意!某知名国产软件被曝携带木马病毒不要再满屏写 try...catch 了!这个更香!纠结!拼多多和国家电网 Offer ,我选了活着
嘿,你在看吗?

我见过的最糟糕代码,看了都说好!相关推荐

  1. 我见过最有趣的代码注释,都在这里了

    代码注释的作用,不需要对程序员解释了.有时在查看他人代码,能看到一些令人不禁大笑的注释. 1. Adon的分享 或者: // 写这段代码的时候,只有上帝和我知道它是干嘛的// 现在只有上帝知道 2.A ...

  2. 六则糟糕代码的优化方案分享

    ‍‍ 微信搜索逆锋起笔关注后回复编程pdf 领取编程大佬们所推荐的 23 种编程资料! 来自:掘金,作者:thyme 链接:https://juejin.cn/post/690636663374128 ...

  3. 六则糟糕代码的优化方案

    点击下方"前端开发博客",选择"设为星标" 第一时间关注技术干货! 这里分享代码 review 中发现的六则糟糕代码的案例,并进行分析: 案例一 变量.属性和函 ...

  4. C++对象模型3——vptr的位置、手动调用虚函数、从汇编代码看普通调用和多态调用

    一.vptr的位置 class test { public:int i; virtual void testfunc() {} };int main() {test a;char* p1 = rein ...

  5. 让代码看起来更舒服, 修改VS颜色样式

    让代码看起来更舒服, 修改VS颜色样式 这个blog转载多余原创,越来越忙,代码写的越来越多,眼睛也越来越不舒服,看到了Windie Chai的VS的样式,强烈要求他分享,于是得到了下面两个blog, ...

  6. 《看聊天记录都学不会C语言?太菜了吧》(14)这么神奇?我写了20行代码竟然一行就可以搞定?

    好消息2020年4月13日晚7.30我在CSDN开播,等你来聊天 预约连接:https://live.csdn.net/room/A757291228/MJWK0Gem 本系列文章将会以通俗易懂的对话 ...

  7. java request 处理过程_小猿圈Java开发之从代码看spring mvc请求处理过程

    原标题:小猿圈Java开发之从代码看spring mvc请求处理过程 Java作为编程界的常青树,有自己生存的独到之处,小猿圈java讲师今天就分享一个关于从代码看spring mvc请求处理过程,通 ...

  8. visual studio 让代码看起来更舒服

    "让代码看起来更舒服",看到这个标题,也许你会条件反射地以为我要讲"重构"或者"编码规范"等等.噢,可爱的开发人员,我们暂且不谈技术,只谈体 ...

  9. 让代码看起来更舒服(1):选择适合的配色方案 (转)

    转自:http://www.cnblogs.com/xiaoshatian/archive/2009/11/20/1606440.html "让代码看起来更舒服",看到这个标题,也 ...

最新文章

  1. (2.4)备份与还原--WAL与备份原理
  2. 【Unity3D基础教程】给初学者看的Unity教程(四):通过制作Flappy Bird了解Native 2D中的RigidBody2D和Collider2D...
  3. C语言各种类型数据的输出显示
  4. Lynis 检测自身安全漏洞工具(本机)
  5. Selenium+requests出现窗口不能跳转的情况
  6. 2.7 Inception 网络
  7. CF 460C Present 【DP+】主意
  8. qt 程序中读取 DXL360 倾角仪的数据
  9. 遗传算法GA原理详解及实例应用 附Python代码
  10. 俄罗斯地名 中文 英文 俄文
  11. Sql Server Express版本升级到企业版
  12. 最互联网的定制家居增长新势力,如何三招实现疫情期的逆势增长?
  13. 怎么将视频转换成mp4?
  14. nyoj145 聪明的小柯
  15. JavaScript 时间格式化
  16. peek java linkedlist_Java LinkedList peek()方法
  17. KL-MPLC无人值守系统
  18. linux fuse安装脚本,Linux FUSE(用户态文件系统)的使用:用libfuse创建FUSE文件系统...
  19. R-VQA: Learning Visual Relation Facts with Semantic Attention for Visual Question Answering
  20. ubuntu重启ssh服务

热门文章

  1. 【数据分享】2022年11月西南地区POI数据分享(重庆、四川、贵州、云南、西藏)
  2. 集赞活动朋友圈案例 餐饮店集赞活动方案 什么叫做集赞拓客?
  3. 蓝牙BLE芯片PHY6222之烧录以及调试
  4. 揭秘信用卡职业养卡人:月赚两万如何办到
  5. Latex模板排版等相关设置
  6. 百度在线读音示例-中文+英文
  7. SuperMap GIS BIM类型数据处理 QA
  8. 无锡华润上华公司实习感想
  9. Day005 - 循环练习与列表基础
  10. VirtualBox 虚拟机系统的三种启动方式