AICon 上海站|日程100%上线,解锁Al未来! 了解详情
写点什么

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

  • 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:164891

评论

发布
暂无评论

物联网平台简介——产品功能类

阿里云AIoT

大数据 安全 物联网平台 物联网 IoT

leetcode 105. Construct Binary Tree from Preorder and Inorder Traversal 从前序与中序遍历序列构造二叉树(中等)

okokabcd

LeetCode 算法与数据结构

VoneBaaS平台让区块链服务触手可得

旺链科技

区块链 产业区块链 VoneBaaS 企业号九月金秋榜

Docker 的快速入门

Docker 9月月更

从 OLAP 到指标中台 SaaS,关键指标赋能业务管理

Kyligence

OLAP Kyligence 数据管理 指标中台

kubectl 插件推荐: kubectl-watch

云原生技术社区

k8s 插件 kubectl kubectl插件 kubectl-watch

一张图读懂「融云一站式全生态出海解决方案」

融云 RongCloud

白皮书 社交网络

多标签用户画像分析跑得快的关键在哪里?

跳楼梯企鹅

上海UI设计培训哪家好

小谷哥

开发者有话说|从心出发

胖虎不秃头

个人成长

总结了一些vue相关的题目,话说今年前端面试难度好大

bb_xiaxia1998

Vue 前端

前端面试5家公司,被经常问到的vue面试题

bb_xiaxia1998

Vue 前端

【IT运维】如何有效保障服务器账号密码安全?

行云管家

运维 IT运维 行云管家 账号安全

在西安参加Java培训学费多少钱?

小谷哥

web前端培训班哪家比较好

小谷哥

大企业为什么都在用钉钉?

ToB行业头条

面试突击85:为什么事务@Transactional会失效?

Java快了!

【等保小知识】等级保护单项测评包括哪些项目?

行云管家

等保 等级保护 等级测评

IM跨平台技术学习(二):Electron初体验(快速开始、跨进程通信、打包、踩坑等)

JackJiang

即时通讯IM

经典再升级 | 尚硅谷电商数仓5.0视频教程发布

小谷哥

直播预告 | 乘云而上,企业海量数据如何「丝滑」地迁移上云?

京东科技开发者

云服务 数据迁移 资讯 京东云 企业云

技术分享| 快对讲融合视频监控功能设计

anyRTC开发者

监控 音视频 调度 快对讲 GB28181

Kyligence 入选 Gartner 指标中台创新洞察报告

Kyligence

指标管理 指标中台 数据分析管理

Java进阶(三十五)java int与Integer的区别

No Silver Bullet

Java int 9月月更 Integer

小程序容器怎样让移动研发效率提升

Geek_99967b

小程序

微信小程序开发|宿主环境详解

陈橘又青

9月月更

EMQX Kubernetes Operator:快速体验EMQX 5.0云原生特性

EMQ映云科技

云原生 物联网 IoT emqx 9月月更

居家办公第一天,摔了31次鼠标

科技怪咖

物联网平台功能介绍——产品功能类

阿里云AIoT

大数据 物联网平台 物联网 IoT 设备管理

对于epoll实现原理的理解

C++后台开发

后台开发 linux开发 epoll select C++开发

UI设计培训需要学习哪些技术?

小谷哥

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