计算机很难:与David Heinemeier Hansson一起构建软件

2020-10-15 05:48:50

如果你要总结整个软件开发的努力,你会说:‘项目延误了,而且被取消了’。

我们已经走到了电脑很难的尽头。在几次关于软件的各个组件是如何形成的对话之后-从打印机驱动程序到密码散列-我想以构建软件产品的哲学来结束。

这可能有点尴尬,但即使在这个行业工作了几年,我也从来不明白为什么科技公司会如此痴迷于速度。这种痴迷已经融入了软件的语言中,在软件中,工作周期被称为冲刺,进度的衡量标准被称为速度。但是,快速交付软件真的那么重要吗?我不知道。我自己不构建软件,但我每天都在排除故障,天哪,我有时真希望工程师们工作得慢一点。

我把我关于构建软件方法论的问题带给了一个对这个话题有过激烈辩论的人。David Heinemeier Hansson创建了Ruby on rails,是Basecamp的联合创始人和CTO,也是Rework等商业书籍的作者。他还以直言不讳地反对行业趋势而闻名,无论这些趋势是技术趋势,比如微服务的日益流行,还是机构趋势,比如风险投资成为科技行业发展业务的默认方式。我们讨论了今天软件是如何构建的,这对构建人员意味着什么,以及如何构建它。

Wojtek Borowicz:软件方法论本身就是一个行业。有Scrum、敏捷、教练、书籍等等。但是你和你在大本营的团队不遵循这些做法。为什么?

DHH:首先,我们的软件开发方法很大程度上受到了敏捷宣言和敏捷价值观的启发。与其说它是受到敏捷实践的启发,不如说它是今天存在的。

很多敏捷软件方法论都专注于产品开发领域,而这些领域并不是难点所在。它们太多地是关于程序结构的。在大多数情况下,软件本质上是不可预测的、不可知的和不可成形的。它几乎就像一种气体。它可以从相同的基本理念适用于各种不同的开口。试图估计一个特性需要多长时间的想法是行不通的,因为你不知道你在构建什么,而且人类在估计任何东西方面都很糟糕。软件开发的历史是一个延迟或取消的项目。如果你要总结整个软件开发的努力,你会说:‘项目延误了,而且被取消了’。可以说,计划工作是行不通的。

我们在大本营的所作所为,我们选择了塑造,很简单,因为那是我们发现艰苦工作的地方。我们试图只接受核心约束,即不可能预先准确地指定软件应该做什么。您只能发现软件应该在约束范围内做什么。但这也不像我们遵循的想法,那就是事情做完了就做了。这是对产品管理思想的绝对放弃。相反,我们说的是:不做估计,做预算。整顿的核心是预算。不是一件事要花多长时间,而是什么东西有价值。因为一件事可能需要一周或四个月。它值多少钱?

有些东西可能值得整个工作周期-这通常是极限-对我们来说,这是六周。这就是我们所说的大批量。或者它的价值可能会低于这个数字。可能只有一周,也可能是两周。那只是一小批。这采用了模糊的项目声明“让我们添加特性A”,将其置于约束之下,并将计算出实现的任务委托给做这项工作的人。这是这里的关键洞察力。如果你有一个大问题的定义和一个固定的边界,你给有创造力的、聪明的人在这些条件下提出解决方案的自由,他们会做出令他们非常自豪的出色工作。

2001年,一个由17名男性(是的,没有女性)组成的小组发表了一份文件,为未来20年的软件开发设定了方向。他们的敏捷宣言规定了敏捷软件开发的原则。这些想法是基本的(例如:‘工作软件是进步的主要衡量标准’和‘简单性是必不可少的’),但它们催生了敏捷教练、顾问和作者的整个宇宙。

那么,这些方法的问题在于他们过于关注评估,而这在软件中是不可能的?

我会走得更远,说这种估计是胡说八道。即使是在处理固定输入时,它也是如此不精确,以至于毫无用处。但你不是。在看到软件之前,没有人能够准确地描述软件应该做什么。那种认为我们可以在开始工作之前先发制人地描述某事应该做什么的想法是胡说八道。敏捷在某种程度上接受了这样的想法,即你需要运行软件来获得反馈,但是敏捷的现代实现并没有接受他们自己教给我们的课程。

但技术几乎痴迷于速度。如果你想要专注于速度,但又不能相信估计,那该怎么做呢?

我们谈论的是进步和速度。这实际上是两件不同的事情。你可以试着越来越快地做事情,然后意识到你实际上并没有走得更远。对我们来说,锻炼身体的兴趣是走得更远。它的最终目标是提供有意义的大批量工作,让客户和实施者感到自豪和高兴。而试图将反馈环路缩小到不可能的小并不能改善这一点。有一种观点认为持续的反馈是一件好事。是的,出于某种原因!我不想因为我的所作所为而不断地被评价。例如,我们不做短跑。按照Scrum和其他方法论的要求,每两周重新安排一次工作是一种完全令人压抑和混乱的工作方式,它只会让每个人精疲力竭,实际上不会带来任何成果。大多数人不可能在两周内提供真正的大功能。

真正的魔力在于将你的心态从估计转变为预算。别想着做一件事要花多长时间。想想你愿意付出多长时间。这就颠覆了整个想法。它让需求浮动。模糊的项目定义实际上更切合实际。高度具体的项目定义通常很快就会误入歧途。足够模糊的定义为从事这项工作的人提供了创造性和选择性。当你考虑到这两件事时,你就赋予了这些人权力,让他们能够做他们认为他们能做的最好的工作,而不仅仅是遵循规范。

整个敏捷叛逆都是关于拒绝大的、前期的设计。但我认为敏捷还没有得出足够的结论。它想:“我们不想要大的前期设计。”我们只想要一些前期的设计。那也好不到哪里去。很多软件方法论都是短视地关注实现的技术需求。但软件领域的艰苦工作是弄清楚它应该做什么,而不是如何让它工作。有一个关于10倍程序员的神话。但这并不是那些在实现问题时表现出色的程序员。10x程序员是重述问题的程序员。

当团队被捆绑在两周的周期、评估和规范工作中时,代码和决策的质量会受到影响吗?

当然。但更重要的是。它导致了-我的意思是有点油嘴滑舌的方式,但不是那种油嘴滑舌的人类痛苦。在这样的制度下工作的人只会被吃掉,然后被吐出来。每两周不断地重新评估你正在做的每件事,因为那是新的冲刺周期开始的时候-它进行得真的很快,无处可去。

这就是我们不做日常单口相声的原因。这种不断的搅动,在非常紧的皮带上绕着圈子转。我认为这实际上是不人道的。雅居乐再次表示:‘嘿,你知道吗?你试图预先计划的那个为期两年的软件项目?那完全是个胡说八道的主意。这太离谱了。是的,当然!但是,最近实践的敏捷方法论矫枉过正,走得太短了。它说,每天两周的单口相声就是这个神奇的循环。不是的。人们需要放松一下。一些自主权。一些空间。

通过广泛的实验,我们发现大约六个星期给了我们足够的呼吸和思考的空间。而且,只要你设定了界限,你最终就会取得进步,即使每天看起来并不一定是这样。您可能会看到在反馈循环方面受到非常严格约束的团队中有更多的活动。他们在疯狂地搅拌,但最终没有取得更多进展。有时候,速度最快的球队看起来非常冷静。他们并不是经常在某些方法论的跑步机上或在一些程序时钟上走走停停!丁!丁!每隔五秒。

你认为你的塑造方法能在更大的组织中奏效吗?一个拥有500或5000名工程师而不是50名工程师的公司?

首先,您不应该从能够从5个人扩展到5000人的角度来考虑软件方法论。试图把5000人作为一个单位来计划工作是徒劳无益的,而且不管怎样,没有人会真正做到这一点。更有趣的方法是:对于任何公司来说,一般来说,合适的团队限制是多少?比方说,500人的大公司就是100个5人的团队。这就是你进行比较的方式。

这并不是说六周是一个对每个人都有效的神奇数字。我认为它实际上可以在数量惊人的情况下工作,远远超过两周的方法。它要慷慨得多。而且更现实的是你可以运送所有的东西。但是,如果您不能在六周内交付完整的功能,那么您的反馈循环仍然太短。如果我不能在我的周期内完成整个事情,从开始到实现,再到发货,那么我的周期太短了。

如果你从事的是本地应用程序开发,这方面的名声很差,可能六周的时间还不够。也许你需要更多一点。也可能不是。这取决于你是否能装运你想装运的东西。但整个行业已经聚集在一起,认为‘哦,两周是一个很棒的时间框架’。什么?我们怎么会这么肯定呢?即使对于一家拥有5000名员工的公司来说,六周也是一个更现实的起点。

您还谈到了软件开发中出现的其他趋势,如微服务和无服务器或测试驱动开发。在软件工程领域有没有什么趋势让你觉得很吸引人呢?

这是个很难回答的问题。把我不喜欢的狗屎都挑出来要容易得多。

显然,我有点偏见,因为我在推动这些事情。我正在实现Ruby on rails and Shape Up,我将与您分享我认为应该如何进行软件开发的事情。这并不意味着没有其他方法可以做到这一点。有各种各样的技术堆栈和Web开发方法让我笑了。我很高兴看到我们在JavaScript开发方面取得的进步。在前端发生的升级在原子层面上很棒。我认为我们误入歧途的地方在于分子水平。人们在前端采用的框架和方法不是很好,但我认为支撑技术改进的是代码转换器、多重填充和JavaScript版本的核心进展。

我们在网络上所做的很多事情都是与25年前的基本原理一起工作的。发生的核心创新更多的是认识到应该把重点放在哪里,什么是重要的,什么是推动的。例如,Web行业的方法认为前端开发应该通过JSON,其中服务器端只负责生成API,然后API返回JSON,这是一种糟糕的迂回做法。我们应该重新拥抱HTML。将HTML放在我们工作的中心,通过网络发送HTML,这样我们就可以在第一次加载时返回完整格式的Web文档,然后还可以通过HTML进行后续的水化或更新。

我想回到微服务部门。我早些时候采访的一位工程师谈到它们是对单一软件变得太复杂而无法维护的回应。你对微服务有什么不满?

让我们从前提开始。单片软件变得如此复杂…。这“变成”了什么?这是不是刚刚发生在我们身上?我们是完全无辜的旁观者吗?复杂性就这样压在我们身上,而我们却无能为力?这是一个我们需要驳斥的狗屁假设。彻头彻尾的胡说八道。你不必让复杂性压倒你。你自己选择吧。一旦你选择了被复杂性淹没,那么一个自然的反应就是试着把这些复杂性塞进更多不同的盒子里,因为你就是不能一下子处理所有的事情,对吗?不对!。先把这该死的事处理好。为什么事情会这么复杂?它们一定要这么复杂吗?它们能不能不那么复杂呢?在我看来,答案是:是的,他们不必这么复杂。是啊,我们可以做点什么。不,这并不意味着我们就得投降。

我想在这里解决根本原因。Web开发在很大程度上应该比以往任何时候都要简单。我们在压缩大量领域的概念开销方面取得了巨大的进步,这些领域过去非常复杂,人们需要非常仔细地考虑。不知何故,人们仍然以单一的应用程序结束,复杂性使他们不堪重负,这是他们自己制造的野兽。他们的回答是:“我们可以把复杂性放在哪里?”而不是试图思考我们能做些什么。不如我们把讨论集中在为什么我们首先会有复杂性呢?

开发人员谈论偶然的和固有的复杂性。意外的复杂性存在于实现中,固有的复杂性就是我们工作的领域的复杂性。大多数Web应用程序的固有复杂性与以往一样。我们倒退的地方是引入了大量的意外复杂性。如果您无法控制单片应用程序的复杂性,究竟是什么让您认为您有能力在现在必须交互和处理网络不可靠、重试、两阶段提交以及所有这些在处理方法调用、参数和运行单个进程的基础知识时根本不存在的服务群中分配这种复杂性。在复杂性级别上,几乎没有比分发应用程序更糟糕的危害了。您甚至可以处理最小的问题,一旦您分发了它,它的复杂性就会增加一个数量级。

其他行业甚至政界人士都将科技视为创新的源泉。与此同时,我越来越多地听到开发人员说,整个领域从根本上来说都是坏的…。

不,不。这源于一种误解,即大多数软件开发都是工程化的。我不相信这是真的。当你从一个工程师的角度来看软件开发时,是的,事情看起来很糟糕。然后工程师会说:‘嗯,你们的规格真的很宽松。您的容差是未定义的。所有这些事情,所有的工程评估,诸如此类。这是对什么是软件开发的根本误解。软件开发不是与搭建桥梁相同意义上的工程。它们不仅仅是同一根学科的不同分支。

许多软件工程师所从事的整个自我厌恶是完全没有生产力的,而且永远不会得到解决。这个想法认为软件开发是一个年轻的行业,如果我们再给它30年的国际标准化组织合规性或任何严格的要求,我们就会得出一个浪漫化的工程概念,他们在航空航天、电梯或桥梁…中都有这样的概念。不,我们不是。这是一个根本不同的领域,需要完全不同的方法。

我们已经有了很多答案。我们只是害怕拥抱他们。例如,在传统工程中,估算是一个很大的部分。事情都是根据预估和关键路径图运行的,因为这就是建造摩天大楼的简单方式。浇注混凝土后,你不需要重新配置塔架的运行方式。软件开发完全不是这样的。软件在很多方面都更接近于写作、游戏制作和电影的创作过程。你设计未知事物的经历,直到你看到它才知道它是好是坏。

看看电影制作。我们拍电影已经有一百年的历史了。我们还没有弄清楚创作过程吗?不!我们没有。你可以选择一个很棒的导演,一个很棒的演员,但仍然可以拍一部很烂的电影。与建筑相比,大体上来说,如果你有一个伟大的建筑师,一个伟大的工程公司,一个伟大的总承包商,你会得到一座可以正常工作的建筑。你可能会犯一些小错误,但基本结构将是健全的,除非有人犯了一个完全疏忽的错误。在电影制作中,在音乐中,在软件中,事情总是失败的。即使知道如何构建东西的技术的优秀人员聚集在一起,致力于某件事情,他们最终仍然会失败。

工程师们对另一件事非常感兴趣,那就是他们对编程语言的选择。有好的语言和坏的语言吗?

是的,对一个人来说。一种编程语言对个人来说可能更好,也可能更糟。我认为客观上他们也可以变得更好或更差,但这种讨论几乎没有什么意思。对我来说,有趣的讨论是关于个人真相的。

例如,关于编程语言好与坏的长期争论之一是您应该使用静态类型还是动态类型,还是应该使用强类型语言还是弱类型语言。在Ruby中,您没有静态类型的语言,而且有一类重构或错误是该方法不能很好地处理的。另一方面,您有一些类似Java的东西,仅举一个最强类型语言的标准示例,它以不同的方式工作。对于不同的人,不同的大脑,不同的语言要么跟他们说话,要么不跟他们说话。当你观察学习方式时,你会发现这是相似的。有些人是视觉学习,有些人是听觉学习,这些风格对个人来说是绝对正确或绝对错误的。如果你是一个视觉学习者,试着用听觉或触觉的方式学习对你来说是行不通的。对我来说,Ruby是一种比我尝试过的任何其他编程语言都优越得多的编程语言,因为它非常适合我的大脑。

我们应该审视和接受来自不同大脑的个人真理,但我们不应该回避不同大脑类型的人,他们在争论什么是更好的,什么是更坏的。意见冲突有巨大的价值。即使你有一个人,像我一样,说Ruby是有史以来最伟大的语言,而另一个人说Java是有史以来最伟大的语言。这些都是我们应该拥抱的东西。就像原子相互撞击一样。然后我们得到了光明,我们获得了能量,我们获得了兴奋。这很好!工程师是如此他妈的回避冲突,以至于他们无法接受两个意见相左的人而不后退,然后去“取舍”!权衡一下!这要看情况!这就像哭叔叔一样,我认为这是一种完全适得其反的学习、灵感和任何事情的方式。

当我讨论软件开发以及我的选择和意见时,我会满怀信心地去做,相信什么对我是正确的。观众可以决定他们更像谁。他们可以自己试一试。他们可以看到我提出的关于我和Ruby Res恋情的争论。

.