本帖最后由 laocuo1142 于 2024-3-6 09:58 编辑
有时候,也许你刚换了一份新工作,也许刚换了一个团队,也许团队中某个有经验的人刚离开,这时需要你来继承一个旧的 C++ 代码库:这个代码库既庞大又复杂,还很特别,经常以各种有趣的方式崩溃。一句话概括来说:它充满了各种遗留问题。
尽管如此,Bug 仍需要修复,奇怪的功能也还需要添加,你无法完全忽视或直接干脆让它消失——这个代码库很重要,至少对给你发工资的人来说是这样,所以它对你也很重要。
不过你不用担心,因为我在很多地方都有过同样的经历,有一种方法,它不会让你太痛苦,能让你真正修复 Bug、添加功能,甚至有朝一**还有望能重写它。
因此,接下来请和我一起回忆一下哪些方法对我有用,哪些方法绝对要避免。
我先声明一下,我并不讨厌 C++,它只是碰巧成为了人们滥用的语言之一,并导致了很多可怕的混乱。可怜的 C++ 只是受害者,C++ 委员会将在 C++45 中修复它,不用担心……跑题了,让我们回到眼前的话题。
下面是需要采取的步骤概述:
只对代码和构建系统做最小的改动,最好是不做改动,让它在本地运行。即使你十分手痒,也不要进行大的重构!
拿出“电锯”,“锯掉”一切和公司/开源项目宣传和销售特性无关的一切
通过添加 CI、linters、fuzzing、自动格式化等功能,让项目步入 21 世纪
最后,可以对代码进行小规模的增量修改,不断重复,直到你不再每天晚上都被应用被黑客入侵的噩梦惊醒。
如果可以的话,考虑用一种内存安全语言重写部分代码。
总体目标就是:花费最少的精力,使项目在安全性、开发人员体验、正确性和性能方面达到可接受的状态——记住这一点很重要,整个过程与“干净的代码”、使用新的热门语言特性等都无关。
好了,让我们开始吧!顺便说一下,本文所有内容都适用于纯 C 代码库或 C 和 C++ 混合代码库,如果你是这样的人,请继续阅读!
1
获得支持
你以为我会上来就比较不同的杀毒程序、编译标志或构建系统吗?不,在我们做任何工作之前,都要与人交谈,对吗?
软件工程必须是一种可持续的实践,而不是几个月或几年后就会倦怠。我们不可能在下班后或各种死亡行程中,独自一人完成这项工作!我们需要说服人们支持这项工作,让他们理解我们在做什么,以及为什么。这包括每个人:你的老板、同事,甚至是非技术人员。这样就算你去度假,回来后就会发现,当你不在办公室时,人们还在继续这项工作。
所有这一切只意味着:用一些简单的事实、合适的解决方案和一个时间表,以外行也能够听懂的方式解释问题。下面我给你简单举几个例子:
嘿,老板,上一个员工花了 3 周时间才编写好代码并做出了第一个贡献。如果我们能花最少的精力,在几分钟内完成,那不是很好吗?
嘿,老板,我快速组装了一个简单的 Fuzzing 设置,结果几秒内就让应用崩溃了 253 次。我想知道,如果有人在生产过程中对我们的应用进行这样的测试,会发生什么情况?
嘿,老板,最近修复几个紧急 Bug 花了几个人和两个星期的时间才部署到生产环境中,因为这个应用只能在一台服务器上构建,而这台服务器使用的是早在 8 年前就停止支持的旧操作系统了。哦,顺便说一下,一旦这台服务器死机,我们就再也无法进行部署了。如果能在便宜的云实例上构建我们的应用,那该多好啊?
嘿,老板,我们在生产中遇到了一个影响用户的隐秘 Bug,花了几周时间才发现并修复,原来是由于未定义的行为(“代码中很难察觉的问题”)破坏了数据。而当我在代码上运行这个行业标准的 linter(”发现代码中问题的程序”)时,它能立即发现这个问题。我建议,我们应该在每次修改代码时都运行这个工具!
嘿,老板,一年一度的审计就要到了,上次审计花了 7 个月才通过,因为审计员对他们所看到的不满意,这次我有办法让审计更顺利。
嘿,老板,刚刚新闻上说有一个安全 Bug,它可以解密加密数据并窃取机密,我认为我们可能会受到影响,但我不确定,因为我们用的加密库是手工制作的(”复制粘贴”),上面有一些未经任何人审查的改动。我们应该清理并设置一些功能,以便在出现影响我们的漏洞时自动发出警报。
相反,以下是你记得一定要避免的说法:
我们没有用最新的 C++ 标准,我认为应该停止所有工作,留两周时间来升级。不过我也不知道会有什么东西被破坏,因为我们没有测试。
我打算在一个单独的分支上修改项目中的很多东西,并为此工作数月。我相信它肯定会在某个时候被合并的!
我们打算从头开始重写这个项目,这需要几周的时间。
我们将改进代码库,但不知道何时能完成,也不知道具体要做什么。
好了,假设现在你已经得到了所有重要人物的支持,我们来回顾一下这个过程:
每一次改变都是小规模、渐进式的。应用程序之前能运行,之后也能运行。测试通过后,测试人员很满意,也没有任何更改被绕过。
如果需要紧急修复 Bug,可以照常进行,没有任何阻碍。
每项变更都是可衡量的改进,可以向非专家解释和演示。
如果整个工作不得不暂停或完全停止(因为优先级转移、预算原因等),与开始工作前相比,总体上仍有净收益(而且这种收益在某种程度上是可衡量的)。
根据我的经验,采用这种方法,你可以让每个人都满意,并能真正完成需要做的改进工作。
好了,让我们言归正传吧!
|