软件工程是关于管理复杂性
关于软件工程存在一种误解,人工智能使这种误解日益明显:我们倾向于将编写代码与构建软件混为一谈。它们在某些方面有重叠,但并不是同一件事。编写代码意味着将一个想法转换为计算机可以执行的指令。构建软件意味着决定哪些指令应该存在,如何相互作用,哪些约束条件重要,决策的成本是多少,可以考虑哪些权衡是可以接受的,以及所产生的系统如何在不崩溃于自身的约束和局限之下演化。让我们从基本的前提开始:人工智能是一个必不可少的工具,因为它在第一个问题上表现得非常出色。而第二个问题才是真正的软件工程开始的地方。困难的部分从来不是输入代码。考虑一个相对普通的工程需求。我们需要处理传入事件并更新一些数据。在技术讨论中,这些是一些首先出现的问题:我们是否应该同步处理它们?我们应该将它们放入队列中吗?我们需要确保处理一次还是至少一次?系统是否能容忍最终一致性?当处理在途中失败时会发生什么?我们应该重试吗?多少次?如果消费者三小时内不可用,会发生什么?事件是否需要保持顺序?我们今天预计会有多少流量?两年后呢?如果事件被处理两次有什么后果?……等等。这些问题与语法几乎没有关系。编程语言的选择是重要的,因为它影响团队的流畅性、团队的表现、系统的性能、安全性、可维护性、工具支持和操作特性,但它并没有回答根本性的问题。困难的部分在于选择反映正确妥协的一组架构。因此,几乎没有一种普遍正确的答案。一个问题可以有N种完全不同的正确解决方案。这在软件存在于企业内部时尤其明显。想象两个公司要求其工程团队构建看起来完全相同的功能。他们的需求在纸面上看似相同。但:公司A有500名用户,而公司B有2000万。公司A可能有三名工程师维护系统,而公司B可能有200名。一个可能需要强一致性,因为错误会带来严重的财务后果。另一个可能乐意接受最终一致性,以换取可用性和吞吐量。一个公司可能需要在三周内交付。另一个可能希望系统在十五年内保持运行。一个可能已经有Kafka、Kubernetes、PostgreSQL、可观察性基础设施以及经验丰富的分布式系统工程师。另一个可能只有一个应用服务器和由四个开发者维护的PostgreSQL数据库。对一个公司的技术上令人印象深刻的解决方案,对另一个公司可能是一个不负责任的解决方案。这就是为什么架构不能被简化成询问:实现X的最佳方法是什么?正确的问题通常更接近于:考虑到这些约束条件、这个团队、这个业务、这个基础设施、这个预算、这些风险以及产品的预期演变,今天实现X的最合适方法是什么?这实际上是一个根本不同的问题。人工智能生成解决方案。工程师负责权衡。由于人工智能在软件组织中的采用,这一区别变得越来越重要。人工智能对软件开发非常有用。我们将其用作加速器:生成样板代码、探索API、提出实现方案、寻找潜在错误、解释不熟悉的代码、生成测试、比较方法,或者仅仅减少将想法转化为可工作代码所需的机械工作量。但有一种危险的倾向是将这种能力扩展到更广泛的领域:将工程判断本身委托给人工智能。你可以:给一个AI模型一个需求并要求它设计系统,“没有错误”:它会设计一个。问它选择数据库:它会选择一个。询问是否应该引入队列、微服务、缓存、CQRS、事件源、Kubernetes、Redis或其他抽象:它会给你一个答案。然而,答案的存在并不意味着潜在的工程问题已经解决。真正的问题是,正确的决策依赖于上下文,通常需要分析、理解和评估大量的上下文,这可能需要数小时、数天,甚至数周的时间,常常涉及同一组织内的多个部门,并且经常留下难以正式化的灰色区域,这在未来需要变更时可能成为一个挑战。这就是现实世界的运作方式:部分上下文存在于文档中。很多并不存在。它存在于与客户的对话中,存在于产品的历史中。
本站免费、广告极少。如果觉得有帮助,可以请我们喝杯咖啡 —— 任何金额都对持续运营有实际帮助。
☕请我喝杯咖啡