写点什么

听起来不错但几乎行不通的系统理念

  • 2025-03-05
    北京
  • 本文字数:3557 字

    阅读完需:约 12 分钟

大小:1.65M时长:09:35
听起来不错但几乎行不通的系统理念

本文最初发布于 Steven Sinofsky 的博客 Hardcore Software。



@Martin_Casado在 X 上发表了一些经验之谈,他经常这么做: 



他问还有什么,我就快速列了一个清单并回复了他。下面我将具体说下为什么清单上的内容行不通。工程学也是一门社会科学,什么可行/什么不可行要视具体情况而定。生活中有一个教训是,每当你对工程师(或在 X 上发帖)说某样东西行不通时,往往很快就会遇到证明它行不通的挑战。这就是为什么大部分工程管理(和软件架构)都是 “经验法则”和惨痛教训的结合。

 

在我的清单上,每一条都是以“让我们(let's just) ”开头的,因为每当有人说“让我们”的时候,接下来的事情其复杂度十次有九次会超出在场所有人的想象。我说“十次有九次”是根据经验。我在下面举了两个例子,但每一个例子,我可能都经历过五六次。

 

那么,为什么下面这些 “几乎从未奏效 ”呢?

 


让我们使它可插拔。当你非常确定一种实现方式行不通时,你就会想:“我知道了,我们可以让开发人员或其他人沿用相同的架构,然后再插入一个新的实现”。然后,每个调用应用程序接口的人就都会神奇地获得一些改进或新功能,而无需做任何修改。有句老话说,“API 是行为而不是头文件/文档”。几乎没有任何东西的可插拔性可以达到 “正好可用”的程度。现代软件中最具可插拔性的组件可能是设备驱动程序,它们使现代计算机得以问世,但运行起来却非常糟糕。它们要么已被禁用,要么已被十年来现代计算机自己构建的驱动程序所取代。真正可插拔的唯一方法是,在设计主要实现的同时设计出第二个实现。这样至少可以证明它可以插拔一次。

 

让我们添加一个 API。无数的产品/公司都会在取得了一定程度的成功后决定,“我们需要成为一个平台并拥有自己的开发人员”,然后很快就有了 API。提供 API 有多方面的问题。首先,作为一个 API 提供者本身就是一整套的理念和技能,你需要不断地牺牲兼容性和互操作性来换取新特性,因为如果你受限于遗留行为或性能特性,你的 API 就无法演进了。更重要的是,你提供了 API 并不意味着任何人想使用它。几乎每一个新 API 的出现都是因为合作方/产品需要新特性,但又不想把它们放在足够优先的位置(市场太小,太垂直,太特定于领域等)。理论上,API 会被“传播”给该领域的一些合作伙伴。事实证明,这些人并不是坐在那里等着你填补产品缺失的功能。他们也有自己的业务和客户,他们不想购买另一种产品来解决他们的问题,拥有一个 API——成为一个平台——是一件有实际需求的很严肃的事情。构建平台是有魔力的,但很少有平台是通过简单地“提供一些 API“实现的。即使提供了,它为第三方提供经济基础的机会也很渺茫。这个过程困难重重,很难获得回报。

 

让我们再抽象一次。传奇人物 Butler Lampson(曾供职于施乐公司、麻省理工学院、微软公司等)是我共事过的最睿智的计算机科学家之一。他曾经说过:“计算机科学中的所有问题都可以通过另一个间接层来解决”(这是一个众所周知的 “软件工程基本定理”)。这是真理——真正的真理。这一条为什么会失效呢?有两点。首先,工程师往往事先就知道这一点,所以他们过早地在架构中加入了抽象。Windows NT 中充斥着大量从未真正使用过的抽象概念,这主要是因为在真正计划使用它们之前,它们就已经存在了。相比之下,在 Mac OS 的进化过程中,那些看似奇怪的抽象概念在两个版本之后派上了用场,因为当时就是有计划的。其次,事后添加的抽象会变得非常难以维护、难以保证安全、难以进行性能优化。因此,最终会有太多的代码无法使用新增的抽象。这样,维护工作就会变得非常令人头疼。

 

让我们把它变成异步的。在计算机科学前 25 年的大部分时间里,人们都在研究如何让事物异步运行。如果你是 20 世纪 80 年代的研究生,你会在整门课程中讨论哲学家用餐、生产者-消费者或理发师睡觉。对于大多数工程师来说,当今世界已经将这个问题抽象化了,他们只需按照数据层面的规则进行操作即可。但在用户体验层面,人们仍然希望能够完成更多的工作,永远不让人等待。在抽象这个问题上,Web 框架已经做了大量的工作。但是,一旦你跳出框架或数据层,认为你可以自己管理异步,那么你十有八九会做得很好,除了一年后会出现一个你永远无法重现的 Bug。希望那不是个损坏数据的问题,到时候记得我提醒过你。

 

让我们稍后再添加访问控制吧。当我们在研究生院讨论哲学家用筷子的问题时,我们还讨论了在系统中实现访问控制的具体位置。如今的世界比那个从理论上争论访问控制的时代要复杂得多,因为系统在不断地受到攻击。当然,每个人都知道系统从一开始就必须是安全的,但由于上市速度太快,几乎没有一个系统从一开始就充分考虑了访问控制/安全模型。除非从一开始就从客户和对手的角度考虑问题,否则几乎不可能设计出恰当的产品访问控制。无论快慢,你要么会失败,要么需要重写产品,对包括客户在内的每个人来说,这都将是一次可怕的经历。

 

让我们同步数据吧。在这个拥有多种设备、SaaS 应用程序或数据存储的世界里,听到有人在讨论过程中说“我们为什么不直接同步数据呢”是一件超级常见的事。@ROzzie(Ray Ozzie)从 Plato 产品起步,发明了 Lotus Notes 以及 Groove 和 Talko,并领导组建了微软 Azure 。他是客户端/服务器和数据同步领域的先驱。他有一句至理名言:“同步是一个难题”。在计算机科学中,“难题”意味着超级困难,充满挑战,而且只有经历过才能知道。对于一个语义完整的事务型数据存储来说,这个问题就已经够难了,一旦涉及到同步 blob 或非结构化数据,或者更糟,涉及到某种数据转换,那么这个问题很快就会变得非常困难。几乎从来没有人想把解决方案建立在同步数据的基础上。这就是为什么有价值数十亿美元的公司在做同步。

 

让我们实现跨平台吧。在我的计算机生涯中,我一直在进行这样的辩论。每次提到这个问题,就会有人给我看他们写的一些东西,他们认为这些东西在跨平台方面非常 “棒”,或者有人告诉我 Unity 和游戏的事。真正聪明的人认为,他们可以直接说 “Web”。我明白,但我仍然是对的。当你致力于开发跨平台产品时,无论你多么以客户为中心,无论你的初衷有多好,你都是在致力于构建一个操作系统、一个云服务提供程序或一个浏览器。尽管你认为自己是在打造自己的东西,但承诺跨平台实质上就是通过 “增加一个间接层”(见上文 Butler Lampson 的论述)来打造上面这三种东西中的一种。你以为你可以做一个可插拔的平台(见上文)。但在这方面,一个反复出现的现实情况是,它只在两种情况下运行良好。在平台刚刚出现的时候——比如云是计算和简单存储的时候——跨平台是可行的,再就是作为两个玩家之上的抽象层来做这件简单的事情时。当你的应用/产品新而简单时,它是有效的。当你偏离了底层平台,或者当你构建的功能在每个目标上的表现大相径庭时,这两种方法都会失效。对我来说,最 “有名 ”的例子是微软放弃开发 Mac 软件,这正是因为用相同的代码开发出同时适用于 Mac 和 Windows 的 Office 太难了——要知道,微软之所以存在,其根本原因在于它的业务是开发跨平台应用程序。当一个操作系统的 API 只有 100 页文档,而且每个操作系统都是从 CP/M 衍生而来的时候,这种做法是行得通的。我们在 1998 年创建了 Office 代码的分支,从此再也没有回头。每天使用 Mac Office 时,我都会发现,即使到了今天,跨平台是不可能做得很好的。如果想了解我对这一点的更多看法,请参阅:https://medium.learningbyshipping.com/divergent-thoughts-on-cross-platform-updated-68a925a45a83

 

让我们 “转为本地”吧。由于跨平台只在少数情况下有效,所以框架和 API 抽象提供的最常见的解决方案之一就是 “转为本地”。其思想是,平台进化或添加框架/抽象没有或尚未公开的特性,这可能是因为它必须为尚未具备该能力的其他目标构建一个完整的实现。纸面上听起来,这确实不错,但十有八九也行不通。原因很简单。你所使用的框架或 API 会对一些本地平台能力做抽象,并始终保持一些状态,或缓存它所创建的抽象中正在发生的事情。当你调用底层的本地平台时,就会混入框架不知道的数据结构和状态。许多框架都提供了精心设计的机制,以便将数据或状态信息从“转为本地”的代码交换回框架。这可以起到一点作用,但在一个自动内存管理的世界里,这只是一种类似于 malloc/free 的解决方案,我相信如今没有人会支持这种架构。

 

对于上述这些点,我是一直都持强烈的“反对”态度呢?当然不是。是否可以选择这些方法,它们行得通吗?当然可以。在某些情况下,这些方法可能会起作用。但在大多数情况下,你并不需要它们,而且还有更好的方法。始终遵循第一性原则解决问题,不要一味追求容易失败的软件模式。

 

声明:本文为 InfoQ 翻译,未经许可禁止转载。

 

原文链接:https://hardcoresoftware.learningbyshipping.com/p/225-systems-ideas-that-sound-good

2025-03-05 18:164959

评论

发布
暂无评论

YashanDB 部署报错:YAS-05721 节点名非法怎么办?

数据库砖家

数据库

天翼云助力中国交建,引领交通基建迈入数智新时代!

天翼云开发者社区

交通 大模型 数智化转型

联想携手ISV“行业私厨”,让智能体落地实践端上行业“餐桌”

脑极体

AI

Blender 入门教程(三):骨骼绑定

北桥苏

建模 blender

HyperMesh视觉控制

智造软件

仿真软件 Hypermesh hyperworks

数据中心里的AI:从幕后工具到智能大脑的蜕变

ScaleFlux

旧貌换新颜:闪迪创作者系列助力修复师用视频为古书画按下‘重启键’

极客天地

【HarmonyOS 5】App Linking 应用间跳转详解

深海的鲸同学 luvi

鸿蒙 HarmonyOS HarmonyOS NEXT 实践分享

YashanDB 如何限制用户连接数?三步搞定!

数据库砖家

数据库

如何检测网站是否支持IPv6?有哪些指标?

国科云

国产操作系统定义以及品牌汇总

行云管家

信创 国产化 国产操作系统

《算法导论(第4版)》阅读笔记:p59-p75

codists

算法

YashanDB|使用触发器复制 varchar(4000 char) 数据出现乱码问题的处理方案

数据库砖家

数据库

【等保问题解答】信息系统安全等级保护三级一年几次?有法律依据吗?

行云管家

网络安全 等保 等级保护 等保测评

原生 Android App 开发的优势

北京木奇移动技术有限公司

软件外包公司 APP外包公司 APP开发公司

为开源鸿蒙开发者而生,开鸿Bot系列今日预售启动

科技热闻

京东拍立淘图片搜索 API 接入实践:从图像识别到商品匹配的技术实现

tbapi

京东API 京东图片搜索接口 京东拍立淘API 京东图片API

【HarmonyOS NEXT】多目标产物构建实践

深海的鲸同学 luvi

YashanDB|YMP 报错“OCI 版本为空或架构不一致”?一文快速排查

数据库砖家

数据库

YashanDB|使用 leading hint 优化 SQL 报 YAS-04522 错误的应对方法

数据库砖家

数据库

YashanDB 使用 leading hint 报错 YAS-04522?当前版本不支持该写法

数据库砖家

数据库

SDP架构在零信任中的实践

天翼云开发者社区

安全 零信任 sdp

CodeBuddy暴改漏洞实录

VyrnSynx

CodeBuddy首席试玩官

YashanDB 报错 YAS-07301:通过 dblink 查询 Oracle 超时?可能是系统资源瓶颈

数据库砖家

数据库

YashanDB 单机部署时报错:prohibited operation?

数据库砖家

数据库

高性能、高可用的 Lustre 解决方案:使用 xiRAID 4.1 在双节点共享 NVMe 环境下

Sergey Platonov

性能测试 Lustre 高可用性 安装指南

BOM都没整明白,就别抱怨生产一团糟了!

积木链小链

数字化转型 BOM 智能制造 生产管理

捷报!天翼云CTyunOS系统入选中央国家机关采购名单!

天翼云开发者社区

操作系统 天翼云 CTyunOS系统

Android App 的上线流程

北京木奇移动技术有限公司

软件外包公司 APP外包公司 APP开发公司

KET口语考试APP的开发

北京木奇移动技术有限公司

软件外包公司 APP外包公司 KET口语考试

YashanDB 启动报错:control file 版本不兼容,怎么处理?

数据库砖家

数据库

听起来不错但几乎行不通的系统理念_技术选型_Steven Sinofsky_InfoQ精选文章