改进您的调试方法,以获得更好的软件应用程序(&Sounder Sleep - ð´)
#javascript #网络开发人员 #编程 #调试

splash image

哈佛大学II机电计算机的日志中的一页,其特征是从设备上卸下的死飞蛾,并带有“发现[A]错误的第一个实际情况”,1947年9月9日。

介绍

在开发应用程序的过程中,将不可避免地引入错误(i代码,因此我可能会创建bugs 〜Descartes)。可以出于多种原因引入虫子,例如逻辑错误,对要求的误解,缺乏测试,紧迫的截止日期或类似于违规的人类的简单性。但是,知道错误是不可避免的,我们可以使用工具来武装自己在野外释放之前快速识别和解决软件错误的工具。

许多人认为他们已经知道有关查找和修复错误的所有知识,或者调试可能是事后的想法,因为他们认为该功能开发应该优先。现实情况是,以偶然的,无效的方法进行调试是太普遍了。随意的方法可能导致挫败感和浪费时间,实际上可以阻止您为用户创作新功能。

gif of bugs

随意调试方法可能导致

在这篇文章中,我们将分解您在开发软件应用程序时可以采用的调试以及一种方法。此外,我们将在您可能不知道的调试工具箱中添加更多工具。我们还将回顾一些有趣的错误案例研究,并指出作者如何在其方法中采用一些调试技术。这篇文章对编程概念有所了解。

什么是调试?

如果我们接受不可避免地创建软件会导致错误的创建,那么我们必须接受软件开发中所花费的某些时间必须分配以维护和调试现有代码。

catching a bug in animal crossing

我抓了一个错误!

调试是定位,识别和修复错误的过程。即使测试可能会揭示错误的存在,但它也不会告诉我们确切的错误是什么或如何修复代码。通常,开发人员将以次优的方式进行调试:在代码库中随机打开文件,以期找出问题的来源;以看似随机的方式更改代码线,并重新启动服务器,希望其更改已解决问题;或更糟糕的是,被瘫痪在以为不应进一步触摸该代码的情况下担心其他意想不到的后果。

为什么调试很重要?

拥有出色的软件带来了巨大的责任。这对我们的用户不利于发货,因为这些错误可能导致意外的结果。根据您正在运营的行业,软件错误可能会导致财务损失,声誉损失,用户失去信任或人身伤害,或者他们可以因造成安全漏洞而臭名昭著。

以下著名错误证明了在将错误挤压给用户之前挤压错误的重要性:

  • NASA MARS Polar Lander - 登陆器被摧毁,因为其飞行软件误入了由存放的腿部部署而引起的振动,以证明该车辆已降落,并关闭了距火星表面40米的发动机。到目前为止,登陆者已经走了大约7950万英里,直到最后崩溃并失败。这导致了1.75亿美元的财务损失和失败的任务。
  • therac-25 - 一台计算机控制的放射治疗机,由于多个软件错误,它不正确地施用了大量的过量辐射,从而导致几名患者死亡。对工程师过度自信的潜在致命危险的典型案例研究。
  • Knight Capital Group - 骑士资本系统由于触发有缺陷的代码的重新利用软件标志而错误地执行了贸易订单。这导致亏损4.4亿美元。
  • 丢失了口袋妖怪 - 一种小故障pokémon物种存在于poké©mon红色和蓝色中,可以通过执行一系列看似无关的动作来遇到。捕获此魔鬼可能会破坏游戏的数据。

catching MISSIGNO in Pokemon

此错误可以被利用为重复项目并修改游戏行为

A 调试方法

下面,我将分解我的个人调试方法。我依靠我在其他工程学科中学到的原则,与其他开发人员配对的多年观察,并利用如何提高故障排除技能的资源。

重要的是要注意,这篇文章假设我们尚未阻止并检测到具有错误处理,测试,刺激,静态类型检查,正确的代码格式和其他辅助工具的某些软件错误。

我喜欢在调试时遵循科学方法:

  1. 进行观察
  2. 收集信息
  3. 做一个假设
  4. 检验我的假设
  5. 分析我的测试是否工作
  6. 重复直到修复错误
  7. ???
  8. 利润

对于第1步,进行观察,我首先检查是否仍然存在buggy行为,或者实际上是所有错误报告中的错误,或者用户可能是错误的不准确地报告问题。有时,我会选择一个错误票,但是当我去验证错误行为时,该错误已经被其他工作确定了。重要的是要验证行为是否在不必要的解决方案上花费时间之前仍然存在。如果仍然存在越野车行为,我会验证它也发生在我的本地开发环境中。这有助于消除仅由于环境配置差异而导致生产中可能存在的任何细微问题。

meme pic

我发现大部分工作应在步骤2中完成:收集信息。这是知道您可以使用哪些工具的地方,包括:

作为开发人员,我们很幸运,有多种工具可以帮助我们进行数据收集。辩论者,日志和其他开发工具都应被利用来追踪有关该错误的尽可能多的信息。他们确实可以帮助缩小问题的范围。我会恳请任何阅读此帖子的人更深入地探索这些工具,因为不断进行更新以改善开发人员的体验。关于您可能使用的任何开发工具,有大量资源可用。这些工具将在整个职业生涯中为您提供帮助,因此,学习良好的时间是您的时间非常好!

对于第3步,做出假设,消除您对程序的运作方式的任何假设很重要。提出关于该错误根本原因的假设应涉及清晰的思考。随机猜测这里不会有帮助,因此请务必退后一步,并使用您在上一步中收集的所有信息来做出明智的决定。真正棘手的错误,尤其是那些缺乏错误消息的错误,可能需要通过明智的反复试验来解决。

another meme

步骤3,简要
做出假设

提出假设后,您可以进入步骤4,测试假设:您可以在怀疑包含该错误的代码库中缩小范围。然后,您可以在可疑的代码区域之前添加调试器语句,以介绍变量和函数如何运行,评论或修改代码的特定部分,或创建解释该行为的单位或集成测试,并重新运行测试套件。

与步骤2(收集信息)一起,我相信步骤5,分析您的测试是否有效,其次是重要的。经过修改的代码库部分后,您应该检查更改。仔细的分析可以帮助您确定该错误是否隔离到代码库的这一部分,还是在代码库其他部分的类似区域中存在错误行为。如果尽管您进行了更改,但仍存在越野车行为,则需要循环返回步骤1并重复此过程。

在各种错误上执行这些步骤后,当您遇到任何新问题时,您将自动开始循环通过这些步骤。这可以帮助您解决报告的错误,但也可以在将其投入到代码库之前,在捕获错误之前有助于捕获错误。

这种方法的好处是,在配对编程时也可以使用它。在问题上有多种眼睛并通过这些步骤进行循环可以帮助您更快地发现问题。我发现,要求对每个人配对阈值的时候是不同的,但是要利用队友和他们的知识很重要。您可以问自己谁最后一次从事此功能,或者谁对此功能了解很多,并且可以提供更多的见解?

其他提示和技巧

除了我喜欢使用的方法外,我还喜欢牢记以下内容:

  • 首先检查简单快捷的东西,即使看起来不太可能。例如,我的服务器是否正在运行,我是否检查了正确的文件,打字稿服务器是否需要快速重新启动?我保存了更改吗?
  • 根据错误的类型,我的监视器上是否有相关的屏幕? Chrome Dev工具是否打开,我的终端是否打开,是否打开任何后端日志,相关开发工具是否打开(例如,React Dev Tools,Redux Dev工具)?
  • 这是一个渲染问题(React/CSS)还是逻辑问题(JS/TS)?两个都?
  • 这是前端问题还是后端问题?两个都?
  • 这个错误已经存在了多长时间?我经常喜欢使用git -bisect检测哪个提交引入错误。
  • 确保读取/浏览整个错误消息。但是,日志通常包含很多噪音。
  • 错误消息是线索但不是福音,它们可能会产生误导。例如,错误消息传递可能是不正确的,以前的开发人员可能无法正确更新它,或者错误可能来自上游。错误消息可能是红色的鲱鱼,因此将其视为重要。
  • 其他人是否经历过这个问题?使用关键搜索术语检查堆栈溢出和GitHub问题。
  • 在任何可能被忽略的相关文档中是否有任何特殊说明?
  • 使用编辑器的折叠/展开功能来最大程度地减少大脑在通过文件中浏览时必须处理的代码噪声量。
  • 有时散步,带着新鲜的眼睛回来,带来新的见解。同样,当您离开机器时,那些尤里卡!
  • 利用“rubber duck” debugging-向无生命的对象(或愿意的同事)逐步解释问题。当您提供信息时,您可能会发现错误或可以重新评估思维的地方。
  • 您是否尝试过询问ChatGPT?尽管仍处于新生阶段,但它可以作为某些问题的快速入门。 (免责声明:确保验证其结果是正确且准确的。)
  • 您是否尝试将其再次关闭?在您经历了非确定性行为的极少数情况下,它可能不是您,而是宇宙:The Universe is Hostile to Computers

chatting with ChatGPT

询问有关CORS问题的CHATGPT

Crash Bandicoot:案例研究

Crash Bandicoot Game Cover

罪魁祸首

在此post中,关于碰撞Bandicoot 1中的存储卡错误,作者描述了它们如何缩小问题:

关于您唯一可以做到的想法调试时唯一可以做的事情是划分和征服:继续删除越来越多的错误程序的代码,直到您留下相对较小的东西仍然展示的东西问题。您一直将零件雕刻出去,直到剩下的唯一的东西就是错误的位置。

我反复返回测试程序,试图检测到计时器设置为1KHz时发生的错误的某些模式。最终,我注意到有人在使用PS1控制器时发生错误。既然我很少这样做 - 为什么在测试负载/保存代码时会与控制器一起玩?我没有注意到它。但是有一天,其中一位艺术家正在等我完成测试。它失败了。 “等等,什么?嘿,再做一次!”

回顾

总而言之,如果您从这篇文章中删除任何东西,那就让我们这样做:调试是一项技能,可以改善。通过使用有条理的结构化方法,您可以改善检测和解决错误的速度。这样做将为您的用户提供更愉快的开发体验和更强大的应用程序。

愉快的编码!