你的 AI 代码写得像垃圾吗?(教你如何改进)

BBetter Stack
컴퓨터/소프트웨어경영/리더십AI/미래기술

Transcript

00:00:00今天,我想聊聊 CRAP。别误会,我指的不是那个意思。我说的是
00:00:05缩写词,它代表变更风险反模式索引(Change Risk Anti-Patterns Index)。它的设计初衷是为了找出
00:00:12代码中那些高风险函数,即那些复杂度极高但测试不足的部分。这并不是一个特别
00:00:18新鲜的概念,但最近引起了我的注意,这要归功于
00:00:24Alexander Prokhoranko 发布的一个名为 Cargo CRAP 的包,它能识别 Rust 代码中的这些关键函数。
00:00:31CRAP 指标的最初构想来自 Alberto Savoia 和 Bob Evans,他们在
00:00:372007 年尝试自动化开发者测试工具时发明了这个指标。但 Alexander
00:00:44最近通过撰写这篇深刻的博客文章,重新点燃了人们对这个被遗忘指标的关注,
00:00:49并且提到在当今几乎所有代码都由 AI 代理编写的情况下,扫描代码库中的这些隐患
00:00:55比以往任何时候都更加重要。这是一个非常酷的概念,我们将会在
00:01:01今天的视频中详细探讨。让我们深入了解一下。为了理解它为什么重要,我们来看一下
00:01:11屏幕上的这个函数。它处理多步数据转换,其中包含深度嵌套的匹配
00:01:16语句、几个循环和大量的错误处理路径。因此,它的圈复杂度相当高,约为 15。
00:01:24如果你不熟悉“圈复杂度”这个术语,它基本上是一种衡量
00:01:30数据通过代码时可能采取多少条不同路径的花哨说法。每次你编写一个 if 语句
00:01:36或者 match、while 循环或 catch 块,你就在制造分叉,分叉越多,
00:01:43复杂度分数就越高。人类大脑就越难理清函数中每一个可能的执行结果。
00:01:51这就是为什么我们尽可能尝试将函数拆分为更小的任务。
00:01:57对于屏幕上的这个函数,复杂度为 15 意味着有 15 条完全独立的路径
00:02:04可以让这段逻辑从头执行到尾。现在,如果该函数被单元测试完全覆盖,
00:02:09它的 CRAP 分数仍为 15。它很复杂,但很安全,因为我们在验证其行为。
00:02:16当我们运行 Alexander 的工具 CargoCrap 时,这正是我们所期望看到的。这里显示分数是 13,
00:02:23而不是 15。可能是因为该库没有把错误处理程序考虑在内。
00:02:27不过没关系,15 和 13 很接近。所以这个工具基本上在执行我们预期的操作。
00:02:33但让我们看看如果有人删除了这些测试,或者 AI 代理从零开始生成了这个函数
00:02:39并完全跳过了编写测试会发生什么。在这个例子中,我只是注释掉了我的测试。
00:02:45如果我们再次运行 CargoCrap,分数突然飙升到了 100 以上。
00:02:51它使用一个简单的公式来计算风险,平衡了圈复杂度、
00:02:57代码中线性执行路径的数量与测试覆盖率。
00:03:03如果我们看这个函数,C 是函数的圈复杂度,COV 是测试覆盖率,
00:03:10表现为 0 到 1 之间的小数。该数学公式会重罚缺乏测试的复杂代码。
00:03:17所以如果你的覆盖率是 100%,公式的第一部分就会降为 0,
00:03:23而你的 CRAP 分数就等于你的圈复杂度。
00:03:26但如果覆盖率下降,左侧的三次方指数会导致风险分数飞速增长。
00:03:33复杂度为 10 且覆盖率为 0 的函数,其 CRAP 分数为 110。
00:03:39这很好,因为如果你希望代码库中,比如,
00:03:43没有任何函数的圈复杂度超过 5,那么这就是你需要关注的基准指标。
00:03:49如果任何函数的复杂度高于 5,你就知道这是需要注意的区域。
00:03:55通常你会允许更高的复杂度。CargoCrap 的默认值设为 30。
00:04:00但我只是说你可以根据自己的意愿来设定这个指标。
00:04:05所以基本上,这是一个值得关注的折中指标。
00:04:09在 AI 生成代码的时代,这变得至关重要。
00:04:13因为 AI 代理非常擅长吐出这些高度复杂、语法正确的代码块,
00:04:20处理你甚至都没想到的边缘情况,但它们在编写有意义、稳健的集成测试方面非常糟糕,
00:04:25除非明确被要求这样做。
00:04:30所以像 CargoCrap 这样的工具旨在运行完所有单元测试后,作为第二次检查来评估整体代码质量。
00:04:37所以它基本上充当了技术债务的热图,直接指向最可能在重构过程中损坏的代码。
00:04:39这也特别有帮助,如果你想保持代码库结构良好,以防需要让新工程师加入团队的话。
00:04:44我们从传闻中了解到,如果我们不注意的话,现在这些 AI 生成的代码会让代码库变得多么混乱。
00:04:47而且有时这些 AI 代理还会倾向于在多个文件中复制同一个函数。
00:04:52所以我认为像这样的工具,更重要的是像这样的方法,在现代编码环境中是非常值得了解的,
00:04:56这样我们才能保持代码质量。
00:05:02提出这一方法的同一批作者也为 Java 发布了 CRAP 指标工具。
00:05:06说实话,直到最近阅读 Alexander 的博客文章,我甚至都不知道这个指标。
00:05:13所以我很感谢他的工具让我注意到了这一被遗忘已久的工程实践。
00:05:19而且我相信其他编程语言也会从这样的工具中受益。
00:05:24所以如果你在空闲时间考虑构建一个有趣的项目,
00:05:30去读读 Alberto Savoia 的原创文章,并为另一种编程语言构建一个这样的工具,
00:05:34因为它对很多开发者来说可能是一个非常有用的实用程序。
00:05:40好了,各位,这就是 CRAP 的核心内容。
00:05:44这听起来很有趣。
00:05:48总之,还有哪些我们应该在代理编码新时代给予更多关注的、被遗忘的工程实践或指标呢?
00:05:53请在下方的评论区告诉我们。
00:05:57各位,如果你喜欢这类技术解析,
00:05:58请猛戳视频下方的点赞按钮让我知道。
00:06:01也别忘了订阅我们的频道。
00:06:02我是来自 BetterStack 的 Andrus,我们下期视频再见。
00:06:08我们下期视频再见。
00:06:13好了,今天的视频就到这里。
00:06:15各位,如果你们喜欢这类技术解析,
00:06:18请在视频下方点赞让我知道。
00:06:21总之,有哪些其他被遗忘已久的工程实践或指标,
00:06:24是我们应该在这个代理编码的新时代多加关注的呢?
00:06:28请在下方评论区告诉我们。

Key Takeaway

利用 CRAP 指标评估代码的圈复杂度与测试覆盖率,能有效识别 AI 生成代码中缺乏测试且极易出错的高风险模块。

Highlights

  • CRAP(变更风险反模式索引)通过结合圈复杂度与测试覆盖率来量化代码的潜在维护风险。

  • 圈复杂度衡量代码执行路径的数量,包括 if、match、while 等控制流结构每增加一个分支,复杂度得分即增加。

  • CRAP 分数的计算公式是 $CRAP = C^2 cdot (1 - COV)^3 + C$,其中 $C$ 为圈复杂度,$COV$ 为测试覆盖率(0-1 之间)。

  • 完全覆盖(覆盖率 100%)的函数,其 CRAP 分数等同于其圈复杂度。

  • 当圈复杂度为 10 且测试覆盖率为 0 时,CRAP 分数会飙升至 110,这标志着代码存在极高的重构风险。

  • 使用 CargoCrap 等自动化工具可充当代码质量检查的最后一道防线,并作为识别技术债务的热图。

Timeline

理解 CRAP 指标的定义与意义

  • CRAP 指标旨在识别代码中复杂度极高且测试不足的高风险函数。
  • 该指标由 Alberto Savoia 和 Bob Evans 在 2007 年提出。
  • AI 辅助编程的普及使得自动扫描代码库中的隐患变得更加重要。

CRAP 代表变更风险反模式索引(Change Risk Anti-Patterns Index)。该概念最初旨在自动化开发者测试工具,近期因 Cargo CRAP 等工具对 Rust 代码的支持而重新受到关注。在当前 AI 代理大量生成代码的背景下,监控代码库风险具有现实意义。

圈复杂度与风险评估机制

  • 圈复杂度衡量数据通过代码时可能采取的独立路径数量。
  • if、match、while 或 catch 块都会增加路径数量,从而提升复杂度得分。
  • 当函数缺乏单元测试时,CRAP 分数会根据复杂度进行指数级加权。

圈复杂度提供了一种衡量函数逻辑路径的方法。以一个拥有 15 条独立路径的函数为例,若测试覆盖率不足,风险分数会显著增加。CargoCrap 等工具通过比对实际测试覆盖情况,实时计算并反馈代码的风险等级。

数学计算公式与质量控制

  • CRAP 分数通过 $C^2 cdot (1 - COV)^3 + C$ 的公式计算。
  • 100% 的测试覆盖率会将公式第一项归零,使风险得分最低。
  • 开发团队通常将 CRAP 分数的关注阈值设定在 30 左右。

该公式对低测试覆盖率的复杂函数进行重罚。随着代码覆盖率从 100% 下降,公式中的三次方指数项会导致风险值急剧攀升。这种数学模型为团队设定了客观的代码质量基准,帮助开发者确定哪些区域需要优先重构。

在 AI 编码时代的应用场景

  • AI 代理倾向于编写复杂逻辑但往往忽略完善的集成测试。
  • CRAP 分析工具可作为单元测试之后的补充质量检查手段。
  • 该指标可生成技术债务热图,为团队维护与新成员接入提供参考。

AI 能够快速生成语法正确的复杂代码,但常缺乏稳健的测试用例。将 CRAP 分析集成到开发流程中,能够有效量化潜在的技术债务。这种做法不仅能降低代码重构时的损坏风险,还能在 AI 频繁复制函数时保持代码库的结构清晰。

Community Posts

No posts yet. Be the first to write about this video!

Write about this video