14 | Bug的反复出现:重蹈覆辙与吸取教训
该思维导图由 AI 生成,仅供参考
1. 重蹈覆辙
1.1 粗心大意
- 深入了解
- 翻译
- 解释
- 总结
程序员在编程过程中常常会犯一些形态各异但本质重复的错误,导致一些 Bug 反复出现。这些错误主要包括粗心大意、认知偏差和熵增问题。粗心大意导致低级错误的出现,而认知偏差可能导致对 API 定义和实现的误解,最终引发 Bug。另外,随着程序规模和复杂度的增加,熵增问题也会导致程序修改或功能添加时更容易引发未知的 Bug。为了避免重蹈覆辙,程序员可以通过反思和吸取教训来提高编程质量,控制程序系统整体的“熵”增加,从而减少 Bug 的出现。 在编程过程中,程序员可以通过开发规范、代码风格、流程约束、代码评审和工具检查等工程手段来避免粗心大意导致的错误。对于认知偏差,团队和技术手段可以帮助纠偏,同时静态代码扫描工具也提供了优化实践,通过它们的提示来发现认知产生碰撞纠偏。而熵增问题则可以通过更新流行的架构模式来解决,比如微服务架构可以将系统的熵增问题局部化在小服务中,并及时重构优化,降低熵的水平。 为了修正真正的错误,需要更深刻地认识问题的本质,构造一个鼓励修正错误的环境。在大韩航空的例子中,作者指出了权力距离对错误修正的影响,强调了建立有利于程序员及时暴露并修正错误的低权力距离文化氛围的重要性。同时,需要站在更高的维度去考虑问题,规则、流程或评价体系的制定对于错误是否以及何时被暴露,如何被修正有着决定性的影响。 总之,程序员需要不断提升方法,同时创造一个鼓励修正错误的环境,以避免重蹈覆辙。文章通过实例和理论分析,为读者提供了深入的思考和行动指南。
《程序员进阶攻略》,新⼈⾸单¥68
全部留言(22)
- 最新
- 精选
- third心得如下: 1.bug本质上是无法避免的,最好的办法不是不犯错,而是少犯错误,犯错之后尽快改正。最快的成长方法是不退步 2.bug的反复出现,有三个重要原因,粗心大意,认知偏差,熵增问题 3.认知偏差是错误的最大来源,思想错误,行动又怎么会正确呢? 4.熵增问题,是随着复杂增高,而必然有更高概率发生bug 5.应对这些问题,我们要从各方面吸取教训,其中最重要的是优化方法和塑造环境。 6.粗心大意,可以通过流程和工具来减少,建议补充代码单元测试 7.认知偏差,可以通过团队和技术手段来纠偏 8.熵增问题,通过业界不断迭代更新流行的框架模式来解决。 9.塑造环境,塑造一个正视错误,改正错误的环境
作者回复: 👍,总结的比我详细😊
2018-09-0329 - 钱世界是不完美的,人是这个世界的极小部分,人也是不完美的,如果想使人做的事情趋近于完美,那就需要集体的智慧了。之于编程一套好的流程能扼杀许多的Bug,自测、测试(包括:测试环境联调、预发布环境联通等)、代码review,上线前准备、上线中自验、上线后产品及业务验证等如果都做到位了,至少能保证主流程没问题,对于性能有要求的可以加上性能测试。现在我们基本是这么玩的,另外,就是各种监控和日志的加持啦!
作者回复: 流程本身就是环境的产物,对于软件开发而言,每个公司估计流程都不会完全一样
2018-09-039 - softtwilight胡大看问题的角度真是独特,而且深刻
作者回复: ^_^,这也是可以培养和训练的
2018-09-035 - 李正阳Lee看到塑造犯错环境这节,想起了桥水基金创始人达利欧对待犯错的态度。 他允许员工犯错,强调每个人应反思错误,不容许一错再错。并在公司内部建立了一个“错误日志”,用来记录每人犯过的错误和造成的不良后果,这样可以追根溯源,系统化的解决问题。 我们技术人也可以建立自己或团队的“错误日志”,在错误中成长。
作者回复: 恩,不错的主意
2018-09-044 - 阿信程序之术这部分 笔记 (期待支持markdown) # 总览 主要是讲解程序员技能的锤炼。 主线:设计、开发、bug处理 (按正常的功能开发流程介绍的) * 设计 * 认知设计。架构与实现,他们的连接与分界;框架和模式的区别 * 如何来设计。从哪些维度来思考(多维度视图) * 编码 * 工业级编码包含哪些内容 (功能、控制、运维) * 编码的两种方式:粗放和精益 * 编码的态度:炫技和克制 * 编码的三阶段:调试、编码、运行 * bug处理 * bug按特性进行的分类以及各分类介绍。空间特性和时间特性 * bug出现的原因分析,以及降低bug的方法 # 05 架构与实现:它们的连接与分界 架构:做的是顶层设计,技术、框架选型,边界划分。熵尽量小。设计和实现做取舍 实现:交付代码,尽量简。围绕架构做的程序时间。 连接: 架构师:关注系统边界、关键点、战略性细节点 # 07 多维与视图:系统设计的思考维度与展现视图 理解或表现系统的视角。 组成视图:描述组成系统的子系统、服务、组件。便于总体了解系统服务组成,以及其职能。服务切分原则:高内聚,职能单一;正交化,同一个功能只有一个服 务提供 交互视图:系统组成部分中各部分的依赖、被依赖关系。整体的流转。 部署视图:系统如何来部署的。关于服务、中间件、使用者之间的网络传输,确认IO瓶颈,从高维度看系统设计的合理性 流程视图:功能逻辑流 状态视图:状态的变化流 我的理解:组成、交互、部署视图,适合描述顶层设计。流程、状态视图,适合描述具体的功能 # 08 代码与分类:工业级编程代码的分类与特征 总结: 对于最终需要交付运行的程序代码, 从代码的用途(or使用场景)上将作者代码分为三种:功能代码、控制代码、运维代码。 功能代码,满足于用户需求,为实现特定的业务功能而开发。 控制代码,对代码执行流的控制,如并行、异步、限流、熔断、超时控制等。RPC、中间件、代理服务器等,应该是对代码执行流的控制。控制代码的需求,是从众多(已有的或预见的)功能开发中提炼而来,基于一些共性的特征抽取。源于功能而高于功能。 运维代码,用于解决运行过程中出现的问题,或者为解决问题提供必要的信息。 结合工作,我们做的防重组件,是控制代码。基于pinpoint实现链路跟踪,是对业界已有的运维代码成果的使用 # 09 精益与粗放,编程的两种思路与方式 介绍编程的两种思路,完美型和现实型。 看这篇文章,脑海中想到了两件事情,一是卖油翁的故事;二是态度(吴军老师写的)一书中提到的一些观点:最好是更好的敌人(或者说进步一点比什么都不做好)、做事情时境界要高。 陶器制作第一组的同学,可以说是熟能生巧;陶器制作第二组的同学以及课程设计的同学,境界是比较高的,但在其事情落地上执行方式有点问题,因为没有找到完美的方案而踌躇不前,最终没有输出满意的成果。 套用到我们自身的工作,以及绝大多数程序员身上,大量的开发(+用心理解)可以提升我们的水平,我们要求输出的成果有deadline,设计时我们格局可以大一些,考虑后来的扩展,实现时可以分步来执行,多次的改进让我们朝着目标前进,甚至超过原有心中的完美方案。 # 10 炫技与克制:代码的两种味道与态度 炫技:能简单处理的采用了复杂的方式 克制:不随性。第一层意思是采用了简单的方案处理合适的问题;第二层意思是看到不好的代码、设计,克制立刻修改的冲动,了解整个逻辑后,在合适的时机进行重构。 # 11 三阶段进化:调试,编写与运行代码 介绍的是两种写代码的方式:一是走一步算一步,边写边调;二是先整理清楚整个思路,然后再动手。 # 12、13、14 bug分析 技术性bug,根据特征分为两类: 空间:环境过敏 时间:周期规律 环境过敏,像人到一个新环境过敏一样,程序运行在不同的环境,因为环境的差异而导致程序运行遇到问题。如磁盘故障,网络带宽低等,原本(在次品正常、网络带宽高机器上)运行正常的程序,运行出现了问题。 bug出现的原因分类: 粗心大意 认知偏差,和理解需求出现了偏差 熵增问题 (系统复杂度变高) 降低bug出现次数的方法: 粗心大意,可以通过流程和工具减少; 认知偏差,可以通过团队和技术手段来纠偏 熵增问题,重构,如使用业界更好的模式、框架等来降低复杂度 塑造环境。塑造一个正视错误、改正错误的环境。
作者回复: 👍,学习心得感悟可以快速记录在这里,总结整理还是汇总到一个自己专用的笔记软件方便些
2019-03-133 - Frank.w总是粗心大意导致出现bug,甚至一些低级的条件语句发生错误。 自我总结: 1. 做好单元测试。 2.做好代码走查,在写完代码后,在今进行从新构思审查。 3.对于代码改动影响的所有代码进行测试。 4.提交测试,同时提交改动范围,改动代码所影响的所有功能。
作者回复: 可复用的单元测试会拯救未来的你^_^
2019-07-282 - 湮汐我和胡老师一样,也被线程池池误导过。我也以为先创建线程到max,然后再进入队列,事实上和我们想的正好相反。而我总结了一下,我们之所以被误导,也是有原因的:数据库连接池就是先创建连接到max,如果没有可用连接时,就等待maxWait时间直到有空闲连接或抛出异常。 在学习的时候虽然有“触类旁通”,但是有时候确实会有一些细节不一样,没有去踩过这个坑,自然就会想当然了。 出错一直都是正常的,一定要敢于面对自己的错误,并且纠正自己的错误。
作者回复: 嗯,惯性思维也容易导致犯错
2018-09-272 - 艾尔欧唯伊我最近面试遇到这个问题,我就说错了。后来继续解释的时候发现说不通了,回来一看,发现之前理解的都是错的
作者回复: 所以要多交流才能发现自己的认知偏差,面试也算一种特殊的交流
2018-09-032 - 艾尔欧唯伊线程池那个认知偏差真是一样一样的啊。。。
作者回复: 听说不少人都掉过这个坑……
2018-09-0322 - 海盗船长才看了几篇,就能感觉到胡大是个喜欢看书的人
作者回复: 嗯,第一爱好是读书^_^
2020-10-141