Programming Languages
软件如何把人逼疯
软件把速度、金钱、复杂性、抽象和几乎无限的可变性揉在一起,让组织不断拉动本不必拉动的杠杆。作者主张以分寸感和耐心抵抗无休止的迭代、重构与转向。
我有个小小的个人理论:软件会把人逼疯。
不是霍华德·休斯那种“每三十分钟洗一次手”的疯,而是说,围绕软件形成的种种条件,似乎格外容易让原本正常的人失去分寸感。
我从足够多的角度、看过足够多次这种事,因此不认为这完全是性格问题。
软件把速度、金钱、复杂性、抽象,以及几乎可以无限反悔的自由结合在了一起。单独来看,这些东西都完全可以应付;可一旦放到一起,就会产生一些非常怪异的副作用。
剥掉品牌包装和架构图之后,大多数软件都无聊得惊人:这里一个表单,那里一个 API 端点,再撒上一些权限、计算和工作流,某处放个数据库。也许为了扩展某个功能再加一条队列——或者只是因为你想冒点险。
话可能不好听,但大多数软件归根结底仍然只是一张美化过的电子表格。
然而不知怎么,生产这些东西的过程,却能把再普通不过的成年人变成二流邦德反派。项目永远推进得不够快;计划必须足够灵活,随时响应突然的变化;每一个新功能都会成为那个扭转乾坤的关键功能——当然,绝不是上个 Sprint 里本该扭转乾坤的那一个。
总会冒出新的担忧:它到底能不能用、能不能扩展、我们是不是跑得不够快,或者我们是不是根本应该去做另一件事。
“可以”如何变成“应该”
软件的古怪之处在于,许多想法在技术上确实可行。这恰恰是问题的一部分:从想法到实现之间几乎没有天然阻力。如果你在盖房子,而有人在框架施工到一半时决定把厨房挪到房子的另一头,所有人都会立即明白这个决定是有代价的。
木料已经锯好,管道已经铺设,人们必须把固定好的东西拆掉。代价如此具象,没有人能假装它不存在。但在软件里,这种代价藏在人们的脑袋中,也藏在那些通常本来就很难理清的系统里。
在软件中“挪动厨房”,看起来可能只是一个“简单修复”。工作仍然昂贵,只不过实际成本悄悄累积在别处:上下文切换、回归风险和架构侵蚀共同带来势能流失、假设被遗忘,以及没完没了的“对齐”会议。
无论实际复杂度如何,因为看不到灰尘和碎料,人们很容易假装这项变更是免费的——这里说的是 free as in beer。更糟的是,修改软件有时真的很便宜。
一个有用的调整可能真的只需一小时;另一个看起来同样简单的请求,却可能波及整个系统并引发故障。这种不透明会养成一个危险习惯:每一个“很酷的点子”、每一个“很快就能做完”的东西,都会被塞进路线图,而且往往还很紧急。
有人在会议上冒出一个想法,而从想法到现实之间通常几乎没有阻力。能不能让这个页面换一种工作方式?能不能改变商业模式、追逐另一个客户群、引入一套新工作流,或者自建事件系统?
答案几乎总是某种形式的:“当然,可以。”
最终,“可以”会变成“应该”,“应该”又会变成“为什么还没做完?”软件就是从这里开始对人的大脑产生奇怪影响的。因为一切都能快速变动,于是一切都变得紧急;又因为理论上的收益可能极其巨大,于是每个决定都开始显得事关战略。
每项技术选择也会变成意识形态之争,因为同一个问题往往有几十种看起来都合理的解法。每一次放缓都开始像一场危机,因为某个地方的某个人据说跑得更快。这个行业几乎没有什么天然机制,会告诉人们什么时候已经足够了。
软件也没有一个真正明确的“完成”定义——我不太情愿地分享一段《社交网络》的片段,它很好地体现了这种态度。
木匠最终会放下锤子,因为柜子已经存在了;但软件永远可以继续改进。按钮可以更好,查询可以更快,抽象可以更干净,新用户引导可以转化更多人,基础设施可以扩展得更远。产品可以进入邻近市场,定价可以改变,整家公司也可以突然认定自己发现了一个利润更丰厚的方向。
重点是:只要你愿意,总有下一根杠杆就在手边。
被杠杆包围的组织
我认为,这正是软件组织如此神经质的原因之一:它们被杠杆包围,而被杠杆包围的人最终总会开始拉动它们。
有时,人们拉动杠杆是因为确实出了问题。另一些时候,则是因为他们害怕,因为董事会想要增长,因为竞争对手发布了什么,因为这个月的数据没有变化,或者因为没人知道还能做什么。
创始人每隔几天就改变方向,会被神化为“响应市场”;经理不断催促所有人加速,会被视为执行力强;工程师引入好几个新的基础设施组件,也许会因为考虑到扩展性而受到称赞。产品团队因为转化率略有下降就重做一个原本能用的界面,叫作迭代;公司因为另一个赛道突然流行,就抛弃原有身份,叫作转型。
这些说法有一部分之所以存在,是因为背后的动机确实合理。有些时候你应该快速行动,有些时候你应该转型,也有些时候架构确实需要改变。软件的危险之处,在于我们太容易把“存在一个可以采取的行动”,误认为“确实有必要采取这个行动”。
如果这些还不够糟,金钱又给整件事浇上了汽油。
几乎没有哪个行业能让一小群人坐在一个房间里,敲上几年键盘——或者现在,指挥几个智能体——就有可能做出价值数亿美元的东西。这种可能性改变了原本平凡工作的情绪分量,至少对非书呆子来说,那些工作本来平淡无奇。
你会看到一群理智的人为了一个按钮争论整整一小时,因为在对话深处,这个按钮已经与未来的一大笔钱连在了一起。
一旦如此,正常判断就会被扔去喂狼。工作不再关乎这个按钮是否真的连接着某种有用的东西,而是开始承载人们对公司未来的一切期望。
复杂性带来的重要感
复杂性也会涌进同一个缺口。软件特别擅长让复杂性显得重要,因为复杂系统能让普通问题看起来更加严肃。
一个把记录存进数据库并允许用户编辑的无聊应用,听起来并不特别了不起;而一个带有服务网格和实时同步层的分布式事件驱动平台,听起来就像你在建造北美防空司令部(NORAD)。
有时你确实需要那个复杂的东西。但大多数时候,你可能并不需要。复杂系统却能提供简单系统无法提供的心理奖赏:人们可以设计、争论、掌控、优化、重写、画图、跑基准测试,并反复谈论它们。
复杂性创造工作,工作制造重要感,重要感又带来地位。很快,系统的一部分存在意义变成了支撑组织,而组织的一部分存在意义又变成了支撑系统。整件事形成自我强化,而身处其中的人很难察觉。
我怀疑,这一切之下还藏着更深的吸引力。软件给了我们非同寻常的控制感,因为代码是少数几个你可以足够精确地描述需求,并让机器可靠照做的地方之一。现实世界远没有这么配合。
现实既混乱又顽固,软件则给我们一种印象:任何混乱——无论是技术上的还是概念上的——都只是一个等待调试的问题。
于是,我们也开始尝试调试软件周围的一切。增长太慢,就修改漏斗;客户感到困惑,就重新设计产品;开发太慢,就改变流程;流程太慢,就更换工具。公司遇到困难,就重组;如果重组后仍然困难——而且还依赖风险投资——也许就来一次转型。
永远还有下一个变量可以操控。
最终,公司本身也开始被当作软件:永远可变、永远未完成,也永远只差一次重构就能正常运转。疯狂真正扎根于此,因为没有人肯让任何东西保持原样。
让已经有效的东西继续运转
不去碰某些东西,是一种被低估的工程能力。职业生涯走到某个阶段,你会开始明白:很多好工作,恰恰来自拒绝触碰那些已经在履行职责的东西。数据库并不总要替换,框架通常没有问题,新用户引导也不需要这周再改版一次。
架构不需要预先设想十亿用户,路线图也不必因为有人看了一条推文就改变。产品不需要变成平台,公司不需要每个季度都重新发现自己的身份。有时,东西只需要待在那里,好好运转。
客户往往需要时间才能找到一个产品,工程师需要时间才能理解一个系统,企业也需要时间才能真正成为企业。这听起来并不特别深刻,但软件文化对耐心有着惊人的敌意。耐心看起来很像无所作为,而在一个痴迷于速度的行业里,无所作为很难自圆其说。
于是,我们转而制造活动。我们发布、迭代、优化、转型、平台迁移、重新思考、再次发明,直到最初的问题几乎被后来堆上去的一切彻底掩埋。几年后,又有人悄悄提出重建最初那个简单的东西——而且常常把自己的自以为是,说成引导他获得这一洞见的智慧之光。
我不认为答案是为了慢而慢。那不过是另一种意识形态,而软件行业已经有太多意识形态了——愿上帝救救我们。答案在于分寸。
所谓分寸,就是明白:不是每个问题都关乎生死,不是每个想法都属于路线图,也不是每层抽象都有存在的价值。它意味着接受:不是每次放缓都需要干预,不是每个竞争对手都值得在意,也不是每个软件都必须成为平台。它还意味着记住:不是每家公司都需要追求统治世界。
我要再说一次:尽管有所有这些装饰,大多数软件仍然只是一张美化过的电子表格。这不是侮辱。电子表格很有用,而真正有用的软件,已经足够好了。
如果我们记得自己真正做的是什么,也许所有人都会理智一点:我们是在建造工具,让自己和其他人的生活更轻松,而不是在“玛格丽塔小镇”里虚度光阴,不停摆弄那些根本不需要摆弄的破玩意儿。