资讯详情

程序员思维模式 - 主调试循环

文章目录

  • 主调试循环
  • 在图层中进行验证
  • 优化循环时间
  • 为什么快速循环更好?
  • 短循环时间通用吗?
  • 一些综合测试是必要的
  • 复杂性会导致测试验证循环吗?
  • 临时救援环境
  • 结论

仅通过测试验证基本上是在仪器上驾驶飞机,而不是看挡风玻璃。视觉飞行和肌肉记忆飞行与仪器的结合既高效又安全。你不太可能误撞山。

当你编码了十多年,可能很难重新捕捉初学者的想法,并向新手解释如何像程序员一样思考。我记得在大学里,当我编码的时间相对较短时,有一件事在我的脑海中结晶了编写代码背后的思维过程——你可以称之为程序员哲学。我正在帮助一个朋友完成计算机科学101的任务。他们完全不熟悉编码。在这里插入图片描述

他们从头到尾在纸上写了一个完整的解决方案——也许是100行代码。然后,他们将其全部输入文本编辑器并操作它。你认为发生了什么?他们犯了大约1000个语法错误。这时,他们来找我,感觉自己撞上了一堵砖墙。在同一节课上,我一直坐在他们旁边——但至关重要的是,我已经编码了一段时间。我已经内化了编写代码的基本思维过程,没有必要清楚地表达它。我们的老师没有教这个思维过程。

主调试循环

然后,我必须向我的朋友解释的是我现在要称之为“主调试循环”的思维过程。假设他们成功地学会了编码,我相信这是一种自然的思维方式。它涉及将问题分解成非常小的部分。一次编写1-3行代码就够小了。每次你写一个小块,你都会操作程序。通常它不起作用,然后你再试一次。慢慢地,你积累了你已经说服自己有效的代码。您可以迭代构建整个解决方案。

关键是双重:你正在逐渐建立,你正在验证你的进步。随着经验的积累,你将在一个越来越复杂的系统中工作。但这种心态可以扩展到任何复杂的问题——你只需要更多地分解它们。

这是主调试循环。编写代码,操作代码。操作代码是验证。

在图层中进行验证

什么是验证?以下是我称之为应用程序验证的示例。在Web在开发过程中,您需要编写几行代码,保存文件并刷新浏览器。然后,您手动与页面/应用程序交互,查看刚刚更改的内容是否有效。对可能只是在测试快乐路径,或者你目前正在实现的边缘情况。其何其他类型的开发过程都是相似的,但具体细节看起来不同。

测试验证不会发生在应用程序中。相反,您可以对刚刚编写的代码操作进行一组综合断言。这是测试驱动开发的最佳实践。TDD 与应用程序验证相结合。在实践中(与严格)TDD相反,我的观察是,开发人员在短循环中工作,验证应用程序,然后快速遵循单元测试覆盖率。

另一层验证是自动集成测试,使用Selenium应用层验证或使用其他工具Postman进行API层验证。您可能还需要进行详细的手动测试,可能是专门的 QA 工程师。最后,您可以中可以使用功能门控进行验证。所有这些验证层都与音乐会一起工作,以确保质量。编写代码时,通常使用应用程序中的验证和/或测试验证,因为它们要快得多。

优化循环时间

主调试循环每小时可执行数百次。思考和输入代码是自然的瓶颈——毕竟,你比电脑慢得多。在理想情况下,运行代码以验证您刚刚编写的内容是即时的。在我的编码生涯的大部分时间里,平均运行一小块代码需要5秒。开销是由于文件系统中延迟注册文件已更新、运行时加载更改以及您自己的“人工时间”(与新更新的应用程序交互以运行更改并查看结果)造成的。

计算机的循环时间部分根据语言、框架和应用程序本身而变化。操作前不需要编译脚本语言。某些类型的编码自然或多或少涉及人际交往。例如,刷新 Web 与应用程序相比,操作控制台的命令往往涉及更少的人为延迟。然而,由于主调试周期对开发人员的工作流至关重要,语言和框架作者有很大的动机来优化它。开发人员发人员优化应用程序。

为什么快速循环更好?

在我看来,慢循环时间让人想起了我职业生涯中最糟糕的调试噩梦,我称之为盲飞。最坏的情况有两个属性:它们不能可靠地再现,每次都需要很长时间才能复制。对于调试,非再现本身会导致不可接受的慢循环时间。如果你想部署到生产环境中,看看它是否有效,或者你必须多次操作代码来检查它是否失败,这是最糟糕的慢循环时间计划。

很容易看出这种极端情况是如何导致开发缓慢和低质量输出的。

相比之下,我对心流的一些最积极的记忆唤起了与持续流畅对话的感觉。就像来回对话一样,你正在通过合作得出结论。您正在验证代码的速度几乎与您可以想到和输入的速度相同。对我来说,即使是10秒的延迟也会破坏这个过程。

尽管如此,基于一个无法证明的假设,断言较短的循环时间更好 - 为了在一定的工作范围内运行更多的循环,每个时间段都会导致更高的输出和/或更高的质量。我相信这是真的,但我承认,随着循环时间的缓慢,整体吞吐量和质量可能会达到或更高。

短循环时间通用吗?

循环时间不能保证很短 - 事实上,技术熵会施加恒定的压力来增加循环时间。开发人员需要花费大量的时间来确保测试套件继续快速运行,应用程序快速重新加载代码,UX为开发人员提供快速重载和验证的能力(在面向用户的应用上)。

鉴于新项目经常从母语和框架中继承小代码库上的短循环时间,到目前为止,在我的小型初创企业职业生涯中,我们的循环时间往往很短也就不足为奇了。我们必须花精力来保持它们很短,但我们通常可以这样做。

然而,我已经看到,在较大的代码库中,较大的团队和较短的循环时间不是给定的。也许随着复杂性的扩大,保持较短循环时间的成本太高了?无论原因是什么,一旦循环时间达到中断点,开发人员自然会寻求更短的循环,如切换到测试验证。在极端情况下,您可能根本不在应用程序中验证,并相信您的测试正在验证正确性。

对我来说,撤退到测试验证似乎很危险 - 但即使他们没有完全验证,开发人员也会做他们需要做的事情来保持循环时间短。

一些综合测试是必要的

在发布代码之前的某个时间,如果代码在完全集成的环境中运行,则运输错误的风险将大大提高。这可能看起来像是在编写代码时验证应用程序中的详细手动测试或生产中的门控验证。仅在综合方案中验证并不能提供与同时运行所有内容相同的信心。最终集成后有多少个单独开发的组件不能正常工作?即使界面完全匹配,也会发生这种情况 - 组合通常仍然是错误的。

这个星球上没有一个QA人员将容忍将某些东西运输到生产环境,而不是以用户体验的方式运行 - 集成在一起。

仅通过测试验证基本上是在仪器上驾驶飞机,而不是看挡风玻璃。视觉飞行和肌肉记忆飞行与仪器的结合既高效又安全。你不太可能误撞山。

复杂性会导致测试验证循环吗?

当您拥有复杂的系统和大型代码库时,很难保持较短的循环时间。重新加载热量本身可能需要10秒以上的时间来加载和重新编译大型代码库。脚本语言在这方面有优势,但它有自己的非正交成本。如果框架需要翻译,甚至脚本语言也可能有不可接受的延迟。

面向服务的系统结构给调试循环带来了独特的优势和挑战。一方面,您大部分时间都在处理单独的、较小的代码库。热负载时间较短。另一方面,由服务和外部数据存储组成的应用程序非常复杂,需要大量的计算资源。它甚至不可能在当地运行。

在实践中,我注意到大型代码库、服务系统结构和以测试验证为主要调试循环的撤退之间存在相关性。

临时救援环境

过渡环境就像生产的微型版本。它应该设置所有相同的服务和相同的基本网络架构。它只是被大大缩小了。通常,它有相同的数据存储和架构,但数据集完全不同。暂存与生产完全隔离;您不能与任何服务的生产版本或生产数据存储通信。

根据产品领域的敏感性,您可以将生产数据完全或清理到临时存储。在许多领域,从安全的角度来看,这是不可能的,所以你需要创建虚假的测试数据,整个工程团队使用相同的测试数据集和数据存储。您开始有最喜欢的测试用户和记录,并可以在应用程序中快速启动它们。

过渡环境有很多用途 - 但它们如何帮助开发人员保持在应用程序内验证流程中?智能业务路由可以帮助解决本地机器资源问题,并减轻维护本地数据集的负担。缺点是它要求开发人员具有与分期的有效互联网连接。

前提是将开发服务与临时存储联系起来,并通过正常的临时存储服务图路验证请求— 目前正在开发的一两个服务除外。临时存储网络拓扑将服务调用图的各个部分从云中的临时存储环境返回开发盒,可以通过 VPN。这听起来很复杂,但这种动态路由是服务感知路由网格框架(如linkerd)标准功能。

结论

在主调试循环中,从应用程序验证到测试验证会导致质量下降、速度减慢和上下文切换。

从系统到测试验证需要做很多工作来抵消。维护较短的调试周期很快成为某人或某人团队的全职工作。然而,即使只有50名工程师,我的组织也选择支付费用。随着人员和代码库规模的扩大,成本可能会呈指数级增长。在这种情况下我希望大规模的公司几乎普遍生活在缓慢的调试周期和测试验证的首要地位。

标签: 连接器挂钩

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台