MoreRSS

site iconmaxOS修改

前用户体验设计师,经济学出身,对UI/UX设计充满热情。
请复制 RSS 到你的阅读器,或快速订阅到 :

Inoreader Feedly Follow Feedbin Local Reader

maxOS的 RSS 预览

从 Scrum 到 Linear Method:重塑我们的开发流程

2024-12-25 22:42:15

从 Scrum 到 Linear Method:重塑我们的开发流程

过去 5 年,我们团队一直都在使用 Jira 来实践 Scrum。Jira 的难用是众所周知的,但作为产品经理我也理解为什么 Jira 这么难用。2B 尤其是面向大型企业客户的产品,最终形态都是像 Jira 或者 Salesforce 那样。体验极差,但是灵活性非常高,面对大型客户,每家公司都有自己的工作流,这种定制的工作流本来就不够 SaaS,所以为了满足这种需求,产品只能做到非常灵活,一个极端就是直接提供 API,让客户自己随便玩。但是并非所有人都有了编程经验,于是不会编程的用户便想要一些简单的规则引擎,规则引擎本身是一个非常复杂的任务;但规则引擎并不难解决所有问题,总会有一些高级用户会提出来为什么不增加这样或那样的规则,甚至为什么不直接增加一个可以运行代码的节点。灵活性不是一个简单的问题。不过这是另一个话题了。

但对于我们团队来说,我们不需要非常灵活的东西,他会让事情变得复杂,我们只需要简单的看板,可以统计 Velocity,可以无限嵌套子任务的工具。某次网上冲浪期间发现了 Linear,但一开始并没有直接使用,我的第一印象是“这不就是一个速度更快、更简单的 Jira 吗”,并不觉得有什么颠覆性的东西。一年之后我又无意间读到了 Linear Method,然后才开始入坑,也才慢慢理解了 Linear 背后设计意图。Shape Up 也是同理,只是 Basecamp 的理念可能过于先进,我到现在也没有完全吃透。

在使用 Linear 的同时,我们结合 Linear MethodShape Up,对我们的开发流程进行了重塑,尝试解决我们在 Scrum 中遇到的问题。实践了快一年,并非所有的问题都得以解决,但我个人的感受是整体项目的交付速度提升至少有 20%。有必要总结一下我们这一年的经验。

在使用 Jira 和 Scrum 的时候,开发团队每 2 周进行一个 Sprint,每个 Sprint 的最后一天我们会做 Sprint Review 和 Retrospective 以及 Planning。Sprint Review 就是把团队的交付的内容和 Stakeholders 同步,通常我们会测试环境 Demo 即将上线的新功能。Demo 完成后 Stakeholders 会提出一些问题或者建议,随后是 Retro,主要是回顾团队协作的情况。紧跟着就是 Planning,产品经理讲述下个 Sprint 的项目。Planning 之后是 Grooming,开发团队对项目进行拆解,将每个项目拆分成开发任务并评估出故事点,评估完成后 Scrum Master 会根据团队过去的 Velocity 给出最终的交付物。

这里存在几个问题:

  1. 故事点估算的交付周期几乎不起作用,很少会按时交付。
  2. 所有人都显得很忙碌,工程师总是在写代码,修 bug,对于项目价值以及原因并不理解。
  3. Sprint 不停的冲刺,团队很少能够审视过去做过的项目是否真的有价值。
  4. Sprint 目标确定后,极少有空间去修复技术债务。
  5. Sprint 开始的时候,往往技术方案还不是很确定,Sprint 冲刺的过程中存在着大量的不确定性。
  6. 如果项目出现风险,导致无法在 Sprint 结束的时候上线,结果就是延期到下个 Sprint,完全不够敏捷。
  7. 设计师应该在 Scrum 中的哪个阶段参与?如何参与?

过去,我们在 Scrum 的框架中打了很多补丁,效果并不理想,反而徒增了许多工作量。当时我们并没有意识到或许换一种工作流可能就可以很好的解决。其实也不用替换掉整个工作流,只需要少许改动就可以解决很多问题,这个改动就是在 Cycle1 之间引入了 Cooldown。我们参考 Basecamp 的 Shape Up 方法,并结合自身实践,将 Cycle 的长度设置为 3 周,在 Cycle 与 Cycle 之间增加 1 周的 Cooldown。

Cycle 中要做的事情与 Sprint 并没有太大的变化,主要是关注交付。我们保留了每天早上的站会,花 5–10 分钟来同步项目进展,主要目的是发现风险点。如果开发的过程中发现了新的不确定因素,团队成员会在站会上提出来,如果影响到项目的交付,我们会尝试调整项目的 Scope,或者安排更多的人力。风险确认之后,我们也会发布 Linear 的 Project Updates,内容会同步到 Stakeholders 所在的 Slack Channel,确保所有人都了解项目情况。

持续冲刺最大的问题就是很少去反思之前做过的项目,开发也没有时间去做性能优化,解决技术债,而这些问题在 Cooldown 中都有一定的缓解。在 Cooldown 中,我们主要关注以下事项:

  1. 回顾上上个 Cycle 的结果:分析每个项目是否达成了预期的目标。
  2. 制定下个 Cycle 的计划:结合之前项目的经验和数据,制定下个 Cycle 的计划。
  3. 明确方案和拆分任务:确定下个 Cycle 的计划后,开发团队会进行技术调研,确定技术方案 ,然后根据方案拆分出开发任务。
  4. 评估开发任务的故事点:开发会对每一个具体的开发任务给出相应的故事点,根据整个项目的故事点总数,我们可以预估下个 Cycle 的交付物。
  5. 优化和修复:优化上个 Cycle 中出现的问题,或者修复 Bug,为下一个 Cycle 的顺利进行做准备。

整个 Cooldown 从周一到周五大概会这样安排大概是这个样子:

周一:开会的一天

周一大部分时间都在「开会」。主要在做的事情实际上就是回顾之前的项目,然后计划下个项目。

1. 回顾会议

回顾会议由产品经理来同步上上个 Cycle 交付的项目的数据。通常我们的项目分成两种:一种是功能交付;另一种是试验一些新的想法。前者通常关心的是用户使用情况;我们团队做的比较多的是后者,后者我们会将每个项目的结果分成 3 种:

  1. 符合预期(Validated):即项目结果达成了我们最初设定的指标,并总结原因。
  2. 不符合预期(Invalidated):即项目结果没有达成最初设定的指标,然后分析原因可能是什么。
  3. 没有结论(Inconclusive):这个比较复杂,虽然指标可能符合预期或者不符合,但因为有其他因素的干扰,导致无法判断是否是因为这个项目导致的结果。

同样,针对 3 种结果,也会有 3 种不同的行动项:

  1. Validated:通常下一步行动是进一步优化,或者进行规模化。
  2. Invalidated:则会进一步讨论是否需要继续,或者放弃。通常一个项目会对应一个目标,而达成目标的方式通常有很多种,每一个项目通常我们会选择其中一种来做尝试,如果这种方法被证实为无效,我们可以会继续评估是否这个目标还值得去做,如果值得,那么再考虑其他方式。而如果已经没有新的想法了,则暂时放弃。有些放弃的项目也会需求下线之前的项目,清理代码。
  3. Inconclusive:与 Invalidated 的类似,不同的是当中有试验初期未被考虑的因素出现,这个因素对试验的结果产生了一定的影响。那么无论结果是符合预期还是不符合,都不能作为确定的事情,我们需要考虑这个新的因素后重新设计试验,然后重新评估项目是否还有机会成功,如果有,那么稍微调整下再继续观察。如果考虑到新的因素之后,原有的项目已经无法奏效,那么就像相当于是 Invalidated 了。

2. Planning 会议

Planning 主要是产品经理向团队介绍接下来一个 Cycle 的目标和方案。我个人很喜欢 Shape Up 中写 Pitch 的方法,不过对于并不是所有产品经理都能够写出合格的 Pitch,因此也暂时没有在团队内部推广。Planning 实际上会过 3 种项目:

  1. 产品经理原本安排在下个 Cycle 要做的事情。
  2. 回顾议会中,如果有提出新的想法,产品经理也可能会安排到下个 Cycle 中。
  3. Linear Triage 中所有的项目:Cycle 的过程中如果有任何新的想法,通常都会先进入 Triage 中,每次 Planning 的时候我们都会一条一条的 Walkthrough,如果决定不做的就会直接 Cancel 掉,决定要做的就会尝试安排到下个 Cycle 中。如果 Cycle 没有空余的时间,则会 Snooze 推迟到下下个 Cycle 再讨论。

3. Retrospective 会议

这个是从 Scrum 中延续下来的会议,这个会议与项目无关,主要关注的是团队协作流程中的问题。通常会议上我们会收集团队成员的反馈,大家回顾项目进行中碰到的阻力,跨团队协作、文档、做事方式等等,把所有认为不合理的地方都记录下来。会议中我们会讨论这些问题,并且商讨出一个可行的解决方案写入下个 Cycle 的行动项目 。会议结束后,每个行动项目都会有一个 Owner 来追踪。实际上,我们现在的项目运作流程就是在这个会议中讨论出来的。

周二到周四:Shaping

这几天相当于 Shape Up 中的 Shaping 过程(虽然并不完全相同),Shaping 主要达成几个目标:

  1. 目的是明确交付项目所需的具体内容,也就是 Definition of Done。
  2. 明确投入的成本,也就是 Shape Up 中提到的 Appetite。在《RICE 框架》中有提到一种衡量 ROI 的方法,讲道理应该遵守这种规则来设定 Appetite。
  3. 分析技术可行性,调研技术方案。
  4. 然后拆分技术任务,并评估点数。

对于开发来说,Planning 的项目可以分成两种状态:

  1. 我们知道怎么做,整个项目基本确定,需要用到的数据、服务、设计都是比较确定的。
  2. 项目看起来具备可行性,但还没有具体的实施方案,其中又可以分成以下几种状态:
  3. 不知道用什么技术来实现;
  4. 知道用什么技术来实现,但对该技术不熟悉;
  5. 技术都比较了解,但是有外部依赖性,可能需要依赖外部团队。

对于 2.1 和 2.2,工程师首先会调研技术方案,技术方案调研完成的标准是用简单的脚本构建了原本的需求,其中的代码质量可能无法到达 Ready for Production 的水平,但是基本的流程跑通了,也大概知道有哪些坑以及要做什么事情。确定这些之后就可以对项目进行拆解。

2.3 产品经理和工程师也会找对应的团队去沟通,如果其他团队可以在 Cycle 内提供支持,那么首先要做的就是协商接口协议和大致的时间,然后各自按照协议进行开发。团队确定协议后也会先拆解项目。

也时候也会出现一种情况,就是到 Cooldown 结束的时候也没确定技术方案。这个时候有两个选择:

  1. 暂停该项目,等待下个 Cycle 的时候再决定是否要继续,因为成本比较高。
  2. 把技术调研本身作为一个任务放进 Cycle 中,这种情况下该项目通常不会作为交付目标,而是如果有空余时间才会去做。

把技术调研放进 Cycle 的另外一个问题是 Story Point 无法确定。我们之前有出现过整个 Cycle 都是在做调研,尝试过很多方案,最终还是没有找到合适的方案。最大的问题是没有制定一个「止损」,我们现在通常会给一个固定的时间来做技术调研,通常是 1–2 天,如果 2 天之后没有任何进展,可以会先暂停调研,转而投入更确定的项目中。

从 Scrum 到 Linear Method:重塑我们的开发流程

Shape Up 中有个 Hill 的概念,技术调研就像是在爬一个山坡,爬到山顶意味着技术调研已经结束,方案已经很明确了。Linear 没有向 Basecamp 的 Hill 的概念,所以我们为进入 Cycle 中的调研任务定了一些规则。由于调研任务很难评估时间,所以我们会在调研任务一开始的时候确定一个最大时间,也就是根据项目本身的价值,我们最多还愿意投入多少的时间来做技术调研,通常是 1–3 天。然后我们每天会评估前一天调研的情况,通常在最大时间达到的时候会有几种结果:

  1. 方案已经明确:这是最理想的情况,接下来就是做任务拆解,但不一定需要在这个 Cycle 进行开发。
  2. 方向已经明确,但具体的技术细节还要在调研:这种时候我们通常会在给出 1 天的时间,一天之后在进入这个评估流程。
  3. 方向依然不明确:这种时候我们会暂定调研,转化把人力投入到已经确定的项目中。

周五:评估故事点的艺术

周五也是 Cooldown 的最后一天,在下周一的时候就会直接进入 Cycle 中, 因此周五最主要的事情就是确定下个 Cycle 的交付物(Scope)。 最初我们按照 Scrum 的 方式来评估点数,整个评估过程需要所有参与的工程师 一起,所有人 同时评估一个项目,评估的结果通常会有些出入,有些人的点数多,有些人认为的少,然后讨论为什面会有出入,通常是一些背景知识的差异,或者有些人想到一些 边缘情况,所有信息都聊清楚之后,最终达成一致。这种方法的结果是没有问题的,但是效率非常低下,因为每一个项目大家都要讨论很久,结果就是一个点数评估要好几个小时才能完成。

我们的解决方案是制作了一个评估点数的标准,每种类型的任务都有相对应的点数,例如对于前端来说,最简单的需求莫过于改文案,所以一个改文案的 Issue 就是 1 个 Story point;比改文案稍微复杂的就是改个 CSS 属性,改颜色,调整字号什么的,它比改文案复杂的点在于有时候你的修改可能不生效,CSS 覆盖什么的,所以可能会需要找一下在哪里改。以此类推,我们使用斐波那契数列来制作了一个 Cheatsheet 帮助工程师评估每个 Issue 的点数。整个项目的点数就是把所有 Subtask 的点数加起来。

我见过一些团队会被所有做过的任务都进行归纳,然后给每种类型的任务都给一个固定的点数,每个点数下面 也都会链接到一些典型的任务上。这样做唯一的问题也是效率,回顾过去做过的所有任务并分类归纳并不是一件轻松的事情。对比我们现在的做法是,先定义一些我们经常被碰到任务,作为一个锚点,然后遇到新类型的时候,会临时评估一个点数,到 Cycle Retro 的时候我们会重新调整下点数标准。效果也很不错,从最开始到现在基本已经稳定,中间值有过一次比较大的调整,是因为有一些新的任务比我们定义的 3 个点大,但是比 5 个点小。于是我们把所有的 5 个点之后任务都统一往后挪了一位,对应的 Cycle Velocity 也给这膨胀了。

另外就是评估点数的标准描述上,最开始我们定义的锚点就是“1 点:修改文案”这种比较清晰的,但是对所有任务类型清晰的分类和归纳依然是个体力活,所有基本上在 3 个点往后的,如果实在难以分类,我们就用很模糊的语言来表达,有几个案例可以感受下:

  • 5 个点有个类型是“写一个全新的、简单的 UI 组件”,意思是一个 Subtask 需要写一个之前没有的 UI 组件,但是这个组件很简单,简单就是一个很主观的词,但团队内部慢慢的就会达成共识,虽然没有文本说明。大家对简单的共识可能就有几个条件:没有动画、只有简单的交互(点击),甚至没有交互,所以大家一看到就知道这是一个简单的组件。
  • 8 个点也有个标准是写复杂的新组件,复杂意味着可能有多个交互方式,内部元素也比较多,但是大概看一眼也都知道应该怎么写。
  • 13 个点也有个写组件的,是复杂的带动画的 UI 组件:动画通常调试起来比较复杂,所以只是给一个组件加动画本身就是 5 个点。
  • 21 个点同样有一个是创建新的

在说一个拆任务的粒度,通常我们希望是越细越好,所有的故事点就是针对最小粒度的任务做的。举个例子,前面提到的 复杂的带动画的 UI 组件,有些组件本身和动画并不耦合,这种时候就应该拆分成两个任务:1 个写复杂组件的任务(8 个点) + 1 个给组件加动画的任务(5 个点);也有些组件 UI 和动画的耦合比较深,两个必须一起做才行,这个时候才会保留 1 个任务给 13 个点。

评估点数之后就是确定 Cycle 的 Scope,根据过往的 Cycle 数据我们已经大致知道在一整个 Cycle 中团队能够交付 600 个故事点,虽然每个人的数字都会有一些差异。但团队整体基本上就是在这个数字附近波动。在 Linear 中我们把所有要做的项目和任务都放进下个 Cycle 中就可以看到总体的点数了。通常为了预防一些未知的事情,我们会保留 20% 的冗余点数,也就是其中 80% 的点数是必须交付的,项目中有一些 Nice to have 的就会放在冗余里面,也就是能交付最好,如果有意外发生,不交付也行。

固定时间,动态范围

前面提到在 Scrum 中我们会遇到一个问题,如果 Sprint Goal 无法达成时应该怎么做?以前的做法是,那就延期到下个 Sprint 中。而在 Shape Up 中有一个原则我觉得可以非常好的解决这个问题:

Fixed time, variable scope.

在 Scrum 中我认为的一个 Sprint 的定义是至少一次的发布周期,Cycle 同样也是,每个 Cycle 3 周意味着 3 周内我们要进行至少一次发布。发布不是没做完就直接上线,而是功能是完整的,但可能体验不是很好,甚至在某些边缘场景中会有 bug 存在,并且 bug 是已知的,我们称之为 Release with bugs。最根本的原因就是 Cycle 就一定要交付,而且交付物是可用的,即使有 bug 也不影响主流程。这也符合 Agile 本身所推崇的持续交付。从客户和项目 Stakeholder 的角度来看也更容易接受,通常这两者,Cycle 结束交付相当于团队的一个 Commitment,如果时间到了没有交付,客户和 Stakeholder 会降低对团队的信任,无论如何解释,而如果交付了,但是带有 bug,这个时候大家都会表示理解,毕竟不是不能用。而 Cooldown 的过程中我们就会修补之前提到的问题。

作为买家,我自然也不喜欢这种交付方式,最明显的案例就是游戏行业,我们已经看到过很多刚发布的时候一堆问题, 然后慢慢改进的游戏,Cycberpunk 2077、无人深空这种。我的看法是 2C 产品最核心的就是体验,如果体验没有只有功能,这种产品市面上有大把,用户和玩家不需要这种;而在 2B 里面功能显然更重要一些,体验显然地位比较低,看看 Salesforce 和 Jira。另一方面 2B 涉及到的 Stakeholder 比较多,可能上下游的团队都已经准备好了,那么 Release with bug 显然好过什么都不交付。而拆解出什么是核心功能、什么是主流程对于产品经理显然有一些要求。

举个例子,例如我们的项目是做注册登录,目标就是让用户可以注册并且登录到我们系统中。往大了说就是一个账号体系,最终一定会非常复杂,但是 3 周内我们能做什么呢?最基本的邮箱注册和登录一定是要有的。找回密码呢?自然也非常重要,但不一定要体现在产品功能上,意思是你的 UI 上有“找回密码”这个按钮,但是用户按下之后是 Contact support,然后 Support 可以 联系开发团队后台修改什么的,虽然加到了人力成本,但是作为 Edge case 来说,风险可以接受。

其他问题

到这里,我们使用 Linear Method 最关键的部分就已经说完了,其实就是引入了 Cooldown,而 Cycle 当中做的事情和 Sprint 本身没有区别。

关于交付

这个时候可能有几个问题,同样是 4 周,我们现在的方法只有 3 周实在写代码,另外一周更多的时候是在写文档;而在 Sprint 中,代码就是文档,有 4 周的时间都是再写代码,前者交付的产品应该会比后者少才对。

话虽如此,直接写代码的前提是你的知道你要写什么,虽然 Agile 宣扬拥抱变化,但是需求天天改 Agile 祖师爷来了也没用。拥抱变化是指对趋势和方向的变化,即如果之前的路走错了,下一次改就行了,其核心是通过学习,不断的提升认知,不断了解什么是“正确”的方向,然后不断的调整;而不是天天改需求,改需求意味着根本不知道方向是什么,只是在原地打转而已。

延期的问题其实也是 Sprint 过程中经常发生不确定性,这些不确定性导致的延期。基本上这种不确定可以分成两类:

  1. 需求的不确定
  2. 技术方案的不确定

这两个问题在 Cooldown 的过程中都有一定程度的解决。但在 Cycle 进行了一半产品经理要改需求,这种事情也拦不住,我们还是回到最开始的原则「Fixed time, variable scope」,时间就这么多,要改动也是可以,但是改动后的版本也要能保证按期交付,交付后可以在打 Patch 来进一步优化。

如果说连方向都变了,整个项目都需要推倒重来,我到目前还没有这种经历,但是我们的预案是会立即停止 Cycle,重新进入 Cooldown 阶段,重新评估项目。这种情况发生的时候,相当于 Cycle 的目标已经发生了变化,那么继续原来的 Cycle 就是没有意义的。

关于故事点

Some teams try to attach estimates to their tasks or scopes to report status. The problem with estimates is they have a very different meaning depending on the nature of the work being estimated.

一些团队会估算任务或范围来做报告状态。估算的问题在于,它们的含义因所估算工作的性质而有很大不同。

Shape Up 并不使用故事点,转而使用 Hill 来作为状态,我并未尝试过这种方式,一方面在 Linear 中没有这样的概念,比较难以实施,另外所有人需要转变思路。我们也不确定这样做是否值得,我们唯一对故事点的抱怨是估算花费了太多的时间,而这个问题已被解决。有了故事点,很大程度上可以帮助我们更好的跟踪项目动态。

故事点的意义在于让我们可以知道团队在一个 Cycle 内的工作容量,从而预估交付物,给利益相关方承诺。虽然并不是完美,但就我们使用的情况来看,问题也不大。

以下是我们在不同时间团队的 Cycle Velocity,你可以看到故事点可能会随着 Cycle 的进行而波动,实际上就是中途发现了不确定。但是我们的交付进度(蓝色实线)基本上是贴着 Linear 的预测(蓝色虚线,只是线性的平均线而已)在进行,基本上说明项目没有问题。

如果蓝色实线距离蓝色虚线有比较大的距离,那么意味着项目可能会延期,这个时候项目的 Lead 通常会发布 Project Updates 来报告项目状态为 At Risk,此时我们会有几个预案:

  1. At Risk:通常意味着增加人手可以解决,我们可以暂停优先级较低的项目,而让临时增加人手来解决。
  2. At Risk:如果实在没有人手,那么再次思考 Scope 能否继续缩小。
  3. Off Track:意味着没救了,无论如何 都不可能按时交付了。这个是最差的情况,我们也出现过 2–3 次。只能提前和 Stakeholder 沟通,达成一致。
从 Scrum 到 Linear Method:重塑我们的开发流程
Cycle 当中点数上涨也是正常,我们预留了一部分的冗余空间来应付不确定性
从 Scrum 到 Linear Method:重塑我们的开发流程
最初的大幅波动是不小把第一周 Cooldown 也算进 Cycle 了。

关于设计

遗憾的是我们依然没有解决设计师应该如何参与的问题。理论上 Shaping 的过程就是设计师和工程师通常参与 Shaping,搞清楚要做什么,然而我很少遇到能和工程师配合很好的设计师。这不一定是设计师的问题,在一些公司,设计师是一种资源,需要的时候得去申请。这种情况下,设计师调过来也只是完成一些任务,他不会尝试去理解你的项目目标、背景、所处的状态,只是来完成任务而已。当然并不是所有人都这样,但毕竟能够深入理解项目并负责人的是少数。我的项目中尽量不使用设计师,多数时候与设计师沟通要消耗不少时间,有这些时间我自己都把 Demo 写好了。这其实是敏捷(Agile)的另外一层问题,在一个公司当中,只有一个团队和项目敏捷是不够的,外部资源总会成为 Blocker,解决的方案就是让整个公司、整个组织都变得敏捷起来。

我的多数项目中,我自己承担了设计师的角色,从设计师和开发的沟通来看,相比较使用 Figma,我更喜欢用 React 来做设计(直接写代码)。原因是很多时候 Figma 做不到我想要的效果,尤其是要做非常灵活的组件的时候,例如按钮的颜色继承父级组件的颜色,这种情况在 Figma 中需要设计师手动标记,而开发常常会忘记去看这些标记。

对我来说 Figma 还不够灵活,我的习惯是,在做设计的时候,第一版基本上是不会做组件的,先把页面画出来。随着页面的增加,会出现很多重复的组件,这个时候我才开始做组件,然后把页面上重复的地方全部替换成组件。随着项目继续推进,有些组件就需要根据一些参数/变量来自动调整,这个时候需要回去改组件,同时再调整所有用到该组件的地方,很多时候要把组件的宽高一个个全部调整一次,基本上就是个体力活。虽然在写代码也是相同的流程,但是代码的行为比 Figma 调整 Responsive 更加可预测,所以改动起来也会更容易。

在与开发的配合中,我尝试过两种方式,我们目前的几乎所有的项目都使用 Radix ThemeTailwind

第一种做法是,我会在 Shaping 的过程中会有一个草图(通常使用 ExcaliDraw),工程师就可以根据草图来直接开发,有些地方可能需要工程师自己发挥,因为有 Radix 组件,多数时候都不会太差。开发完成后,我会先验收功能,没有问题我会在对 UI 做一些微调,然后就可以上线了。

第二种做法是,我先写 UI 和交互,只设计前端的逻辑,以及一些 Mock 的数据,并没有真正和后端交互。然后工程师会在此基础之上加上后端的数据。这种流程比较复杂的时候,用代码直接开发 Demo 有另外一个好处,每一次开发完成后我自己会先用一次,总是会发现一些不合理的地方,然后重新调整。用 Figma 当然也可以做一些流程,模拟点击来尝试,但和真正在前端 Mock 数据来使用时完全不同的。

对于一些需要复杂流程的我会选择第二种,如果只是一个做内容展示的页面,则使用第一种。


回到正题,以上就是我们过去一年使用 Linear 并且结合 Shape Up 和 Linear Method 调整后的实践经验,其中不可避免地带有我们团队的历史因素,例如团队成员配合默契,使得 Story Point 的标准即使相对宽松也不会影响最终交付。我们没有完全投入到 Shape Up 或者 Linear Method 中,而是结合自身情况进行调整。没有必要为了改变而改变,只有当现有流程出现问题时,我们才会考虑引入新的方法。我们也深知,没有一套方法可以完美适配所有团队。最佳实践,唯有在实践中根据自身情况不断微调、优化才能得到。


  1. Cycle 或者 Sprint 对我来说都是一个周期的单位。Linear Method 不适用 Sprint 是认为 Sprint 有冲刺和意思,而 Cycle 的重点是交付价值,而不是冲刺交付具体的工作量。我个人到无所谓。 ↩︎

Issue #10 - 通过 Zapier 聊聊 Product-Led SEO

2024-06-23 15:16:51

Zapier 每个月有超过 6百万 的自然搜索流量,帮助 Zapier 成功的流量策略,被称为 Product-Led SEO。这里的 Product 指的是产品本身,Product-Led SEO 就是指通过产品本身的功能作为核心关键词,通过程序化的方式来拓展关键词,构建起大量的页面的方式来做 SEO。

Zapier 最初的业务很简单,用户在软件界面中简单的几步操作,就可以实现多个产品的对接。在 Zapier 出现之前,如果你想要对接不同的软件,那你可以写个脚本,通过调用不同软件的 API,并将其部署在服务器上来实现最终的对接。而 Zapier 相当于是把「写脚本」这件事情变成了可以通过「用户界面」来直接配置,并且无需部署,可以直接运行在 Zapier 的服务器上,明显降低对接不同软件之间的成本。

Zapier 的核心能力显而易见,就是「集成/对接」(Integrate/Connect),而这个词也正好就是 Zapier Product-Led SEO 中最主要的关键词。Zapier 的目标客户就是那些需要对接不同软件的人,而这些人在搜索引擎上通过会搜索诸如「如何对接 A 和 B」这样的内容。而 Zapier 就利用自身已经对接的软件,通过程序快速生成了大量的「对接 A 和 B」的页面。如今在 Google 上搜索有关两个产品之间的对接,Zapier 的结果总会出现在头部。

Product-Led SEO 的最主要的特征是可规模化,也就是说可以通过程序的方式来快速生成大量的相关的页面来做关键词排名,这种方式称之为程序化 SEO(Programmatic SEO)。程序化 SEO 结合了产品核心功能作为关键词就是所谓的 Product-Led SEO。

为什么 Product-Led SEO 会起作用?主要是和 Google 的 E-E-A-T 策略有关,其中第二 E 代表着专业度(Expertise),而 A 代表了权威性(Authoritativeness)。这两个的意思是页面的内容本身是否足够专业(如果是文章还要考虑作者),并且发布这篇文章的网站在这个话题(Topic)上是否足够权威。举个例子,一个非常专业美食博主,在自己的美食博客里发布一篇有关健身减脂的文章,即使文章本身可能足够专业,但你也会怀疑博主突然发这样一篇文章是否有广告嫌疑,Google 也是如此。

Zapier 本身的主营业务就是做软件集成,所以在「集成」这个词上就天然的具有权威性。类似的案例非常多,例如在 Google 搜索 Email Marketing,头部的结果基本上总是 Mailchimp, Hubspot, Brevo 这几个主营业务就是 Email Marketing 的网站。虽然作为一个搜索引擎的用户,我并不喜欢这种结果,原因是大部分内容都是千篇一律,而真正的干货文章可能是在某个从业多年的人的博客或者 Substack 上,但是头部的企业网站可以凭借更好的域名权威性来以及大量的内容输出,来获得更好的排名。另外,根据我个人的经验,这其实是可以作弊的,Google 其实并不是真的「理解」这个网站的业务,如果某个网站有很多有关某个话题的内容,那么 Google 可能会认为你的网站就是干这个的,从而提升改网站在相应话题中的权威性,也就是 SEO 的马太效应。企业博客可以雇佣大量自由写手来撰写大量关于某个话题的内容,而个人博主则没有这个能力,于是我们看到的结果就是大量的排名很高的 SEO 软文,而真正的干货却难觅踪迹。

Product-Led SEO 的一个好处是流量的质量得以保证,这也是我认为 Product-Led SEO 和 Programmatic SEO 最大的区别。如果一个网站主要是依赖流量的多少来赚钱(例如广告展示),而不关注流量质量,通过程序可以快速生成大量的页面来做排名就足够了,什么关键词流量高就做什么关键词,而无需关心来的都是些什么人。但如果是通过出售产品来赚钱,流量的多少自然也重要,但更关键的是流量的质量。那么如何评价流量的质量呢?对于类似于企业官网这种无需登录就可以公开访问的网站来说,我们很难直接知道访问网站的人都是什么类型的人、有什么诉求,是否符合产品的 ICP。虽然 GA 提供类兴趣爱好等标记,但只有在投放 Google 广告的时候才会有所帮助。B2B 领域有一些公司(例如 Clearbit)可以提供通过访客 IP 来识别 这个人可能来自哪个公司的,但一般来说价格不菲,而且即便所在企业符合 ICP,访客本身也未必符合 Buyer Persona,而后者几乎没有方法可以在匿名的情况下获知。低成本并且高效的方式就是通过页面关键词,例如你写了一篇如何运营网店的文章,有个人通过搜索引擎进来到这篇文章,虽然 Google 不会直接告诉我们「这个人」的搜索关键词具体是什么(如果是通过搜索引擎广告进来就可以知道关键词),但是根据文章内容也能猜出个大概,访客大概率是从事和网店运营相关的工作。

对于 Zapier 来说,如果一个人搜索 A 集成 B,或者如何集成 A 和 B 这样的关键词,那么这些人大概率就是目标客户。Zapier 就顺着这个关键词,自动生成了很多 Connect A and B 这种页面,如今 Zapier 已经支持 7,000 多个 App,这些 App 两两组合就可以生成 24M 的页面,而且边际成本很低,每新增一个 App,这个 App 就可以自然的与库里的所有 App 对接,就相当于新增了 7,000 多个页面。

如果我们看 SEMRush 的数据,Zapier 的流量差不多是在 2015 年左右才开始有起色,而 Zapier 成立于 2012 年,Product-Led SEO 的策略差不多是在 2013 年的时候开始做,所以问题出在哪里?

和所有的 Programmatic SEO 的方式一样,Product-Led SEO 需要时间才能起作用,Zapier 2012 年才成立,域名也是全新的域名,最初虽然页面数量不多,但 Google 对于新网站通常都会持怀疑态度,不会给很高的排名,需要时间才能验证。我自己也做过类似的项目,2023 年初的时候我们用一个全新的域名来做 Product-Led SEO,起初的一年每个月的流量都少的可怜。不过我们也没有花太多的成本来维护,直到今年 3 月的时候我们重新审查了这个项目,反思是不是我们那里做错了,或者说会不会这个域名已经被 Google 拉黑了,于是我们决定等到 5 月份的时候再看看情况,如果不好转的话就换域名或者干脆放弃。巧的是在 4 月底的时候流量突然发生了很大的增长,很难说清楚原因,因为当中我们其实没做什么,唯一可见的影响就是 Google 在 4 月份完成新 Core update(核心算法的更新),以及之后 Spam 内容检测的更新,之后流量大涨,月活直接是之前的 100 多倍,而此时距离项目上线已经过去 15 个月了。我的一个猜测是这可能就是 Google 给一个全新域名的一段时间的试用期,过了之后 Google 才认可这个域名。


Product-Led SEO 并不适合所有产品,它取决于产品核心功能的这个关键词的拓展性。Integrate, reviews, email template 这类型就很好扩展,xxx reviews 可以是任意店铺、网站、软件等等,G2, Trustpilot 就是利用 Review 这个关键词来做 Product-Led SEO。同样 xxx email template 可以是节日、风格、场景等等,很多邮件营销工具(Camppaign Monitor)和设计工具(Canvas)就利用 template 这个词做了大量的页面。如果产品的核心能力恰好是可以拓展的,Product-Led SEO 自然是最好的选择,虽然它不像看起来得那么简单,Product-Led SEO 最大的成本其实在于背后的基础设施,想象下如果你有 24M 个页面内容需要维护的时候,系统会变得多么复杂。一旦你成功的构建了 Product-Led SEO,网站相当于构建了一道 SEO 的护城河,其他人也可以复制你的策略,但是在域名的权威性等等方面,他们也需要花很多时间去积累,而 SEO 的马太效应会让已经成功的网站活得更好的排名。

反脆弱:从不确定性中获益

2024-06-13 22:19:05

TL;DR

反脆弱:从不确定性中获益

黑天鹅事件的风险很大,并且不可预测,因此我们不应该去寻找预测黑天鹅事件的方式,而应该去适应有黑天鹅事件的环境,适应的方式就是利用反脆弱性来构筑越来越强韧的事物。


黑天鹅:如何应对不可预知的未来》主要介绍了为什么黑天鹅事件不能被预测,但在书中作者 Nassim Nicholas Taleb 并没有给出如何应对黑天鹅事件的答案。之后出版的《反脆弱 : 从不确定性中获益》中,Taleb 才真正给出了答案,他认为应对黑天鹅事件最佳的方案就是提升反脆弱性。所以这篇文章我从自己的角度来解释下什么是反脆弱性,以及反脆弱性的作用机制。

Taleb 把事物分成三类:

  • 脆弱类:脆弱的事物喜欢安宁的环境,无法应对环境的变化,对黑天鹅事件几乎没有抵抗力;
  • 强韧类:强韧的事物并不太在意环境,它有足够大的防御力,黑天鹅事件可能会对它造成影响,但是影响不大;
  • 反脆弱类:反脆弱的事物则从混乱中成长,反脆弱的事物不但不会被黑天鹅摧毁,反而会从中受益。

虽然 Taleb 没有解释,但我认为这三种类型的事物是一个层层递进的关系。用一个 RPG 游戏中的角色来举例,脆弱的角色血量只有 1,只要受到的伤害大于 1,它就会直接死亡;强韧的角色血量有 100,如果受到的伤害小于 100,他只会受伤,但并不致命,如果受到大于 100 的伤害,强韧的角色也会死亡;反脆弱的角色则首先有一定的强韧性,血量也有 100,与强韧的角色一样,他可以承受 100 以下的伤害,虽然也会受伤,但是每次战斗结束后,反脆弱的角色的等级会提升,血量也会 +10。意味着只要杀不死他,那么每次战斗都会提升它的经验,让它变得更强。简单理解反脆弱就是「不断的打怪升级,然后挑战更高等级的怪」,如此循环下去。

反脆弱就是进步

我们在此不妨作一个大胆的猜想,任何有生命的物体在一定程度上都具有反脆弱性。

生命,或者我们说的大自然无疑是反脆弱的最佳例证。地球 45 亿的历史中,生命也存在了 38 亿年,这期间主要经历了 5 次物种大灭绝,大灭绝主要是由于外部环境的变化而导致。不过大灭绝不仅没有导致生命的终结,反而令生命更加的多样。从更长的视角来看,物种灭绝实际上淘汰了那些无法适应环境的生物,留下了能够应付更复杂环境的生物,准确来说是「基因」,更强韧的基因得以保留,基因不断突变、遗传,每一代新的物种都强于之前的物种,使得生命作为了更大的群体的强韧性得以提升。但对于个体来说,进化的代价也是非常巨大。对于群体来说,只要代价可以被承受,结果总是美好的。

反脆弱:从不确定性中获益

反脆弱不是一种结果/状态,而是一个持续学习的过程,不断提升的强韧性是反脆弱的结果。如果我们把生物进化当做是学习的过程,那么进化使得基因「学到了」什么行得通、什么行不通,当基因「发现」眼睛有助于生存的时候,没有眼睛的生物就逐渐被淘汰,有眼睛的生物越来越多样。人类学习知识依赖于我们过去的经验,我们所经历的越多,经验就越多,也就知道了什么行得通、什么行不通。

这种依赖于过往经验的学习方式不可避免的会遇到「休谟问题」,但似乎也没有更好的方式。科学也没有一成不变的理论,曾经人们以为牛顿理论就可以解释这个世界的一切,爱因斯坦提出了相对论,接着人们又认为物理学已经不会再所有建树的时候,量子力学有出现了。即使是科学,也是在不断的犯错,不断的修正。因此也就不难理解张小龙说的那句「我所说的都是错的」。

反脆弱的前提是冗余

经验的积累需要大量的实验,而实验的问题是大部份的实验都是「失败」的,而失败是需要付出成本的。对于大自然来说,这种成本就是物种灭绝,如果自然一开始只有一个物种,那么一次灭绝就是毁灭性的,更不用说从中学习什么经验。但是如果大自然拥有大量的物种(实际上也是如此),那么几个物种的灭绝听起来很残酷,但对于大自然作为一个整体实际上是有帮助的。大量的物种,实际上就是一种冗余。

反脆弱性……其实只是某种形式的冗余。

在我看来,冗余并不能直接带来反脆弱性,但是冗余为反脆弱提供了前提——强韧性。备份是一种常见的冗余方式,生活中我们常见的是数据备份。我个人的数据至少会有 3 份拷贝,笔记本中有一份完整的拷贝,台式机中有一份完整的拷贝,服务器也有 2 份完整的拷贝。设备之间通过服务器来进行同步,服务器也会自己备份一次。备份的好处显而易见,在没有备份的时候,我的数据是脆弱的,任何意外所导致的设备或者硬盘损坏,数据就彻底丢失了。而备份的存在扩大了数据的强韧性,如果某一台设备损坏或故障,其他设备中依然有数据。虽然设备损坏本身确实也造成了伤害,但对最核心的数据却影响不大。

而在软件架构中,相对于部署在一台机器上的系统,分布式(去中心化)的系统也同样具有强韧性,也就是软件工程中常说的 robust。分布式的系统有会多个节点部署在不同的地区,即便某些节点遭遇了问题可能会宕机,或者当地的网络出现了问题导致服务无法访问,这都不会影响其他地方的正常访问。

冗余和分布式系统将原本由一个单一个体组成的系统,变成了由多个个体组成的群体。群体意味着即使当中的部分个体遭遇崩溃,也不会导致集体的崩溃。从个体到集体的转变,实际上增加了整个体统的强韧性。

个体的脆弱性与群体的强韧性

进化最有趣的一面是,它是依赖反脆弱性实现的;它喜欢压力、随机性、不确定性和混乱——而个体生物则相对脆弱,基因库正是利用冲击来确保优胜劣汰,提高整体的适应力。

首先需要澄清「个体」和「群体」的概念,「个体」是相对于「整体」而言的,并不是一个绝对的实体。例如一个人,相对于人体内的每个细胞而言,人是群体,细胞是个体;相对于家族、社会而言,人是个体,家族、社会是群体。个体的脆弱性也是相对于群体的强韧性而言,并不是说作为一个人,我们是脆弱的,而是相对于整个人类来说,一个人是脆弱的。也恰好是个体的脆弱性与冗余的存在,让群体显得强韧,也是群体反脆弱性的前提。

一个系统内部的某些部分可能必须是脆弱的,这样才能使整个系统具有反脆弱性。

这种观点很像传统集体主义的价值观,在集体遭遇风险的时候,集体会要求个体要顾全大局,牺牲自己来保全群体的利益。事实上两者是有差异的,自然进化本身并没有预设的目的,因此也就不会要求个体去做什么事情,它是一个通过自然选择、遗传变异等过程发生的现象。这些机制使得生物种类能够适应其环境,增强生存和繁衍的能力。自然的这种优胜劣汰与集体主义的不同之处在于,优胜劣汰并不是自然要求个体的牺牲,而是在环境变化中,个体为了适应环境自发的响应,这种响应体现了个体的自由意志,而非群体的要求。

由于大量的个体的存在,当灾难发生的时候,每个个体都可以根据实际情况来作出不同的反应,有些反应成功的抵御了灾难,有些则不。对于没有成功抵御灾难的个体而言,面临的可能是毁灭,但我们不能说他们是失败的,从那些被摧毁的个体角度来看确实如此,但是从群体的角度来看则不。每次失败对于群体来说都是宝贵的经验,正如 Thomas A. Edison 所说「I have not failed. I’ve just found 10,000 ways that won’t work.」这些经验被群体内的其他个体所了解、学习,使得群体内的其他个体的强韧性得以提升,从而使得整个群体的强韧性进一步提升,这便是群体能够反脆弱的原因。群体越大、个体越多,所产生的经验就会越多样,知识就会越多样,群体的进化才会更快。

这也就不难理解为什么大厂会引入末位淘汰机制,因为脆弱的个体被淘汰了,留下的都是强韧的个体,因此群体整体变得更强韧了。唯一不同的是,末位淘汰是自上而下的。如何评价「末位」也是个问题,大自然显然更加残酷,大自然淘汰的不是某个个体生物,而是一个物种,无法适应环境变化的物种会被直接淘汰,但这种淘汰不是大自然做出的选择,而是物种无法应对环境变化的结果。

杀不死我的,使我更强大。
杀得死我的,使其他人更强大。

自下而上的多样性

正是因为个体的自由意志,当风险来临的时候,个体能够根据自身的情况来作出反应,加上足够多的数量,我们才能看到更多样的结果。如果反脆弱是个体自由意志的体现,也意味着反脆弱必须是自下而上的。为什么「自上而下」行不通呢?其原因和《为什么伟大不能被计划》一样,因为进化本身是不确定的事情,没有人知道应该怎么做,即便是开明的「自上而下」。自上而下本质上是一种计划,而计划本身就是「反多样性的」,计划是基于我们已知的信息来做决定,包括已知的已知和已知的未知,而进化更多时候是关于未知的未知。任何事物一旦被设计、被计划或者被控制,它的结果就不可能是多样性,即使这种目标被定义成「提升系统的多样性」,也只是一个伪目标。并不是说「计划」没有意义,只是在「创新」上不行,当 OpenAI 发布了 ChatGPT 之后,很多公司都开始「计划」自己的 AI 能力,当目标已经很明确的时候,计划就是最高效的方式。

那些在公司里制定政策的人(如脆弱推手格林斯潘)由于有一个先进的数据采集部门的支持,因此得到了很多“及时”的信息,结果却往往反应过度,将噪声当作信号,格林斯潘甚至会关注克利夫兰真空吸尘器的销售状况的波动,“以便掌握经济的确切走向”,当然,他的微观管理将美国经济拖入混乱的泥潭。

多样性和新颖性实际上是相同的意思,任何对创新的探索、对整体反脆弱的提升,都建立在个体的自由探索之上,那么群体是否为个体提供了自由探索的环境才决定了群体能否获得真正的多样性和创新性。

反脆弱需要随机波动性

除了大量的个体、自由意志,反脆弱还需要风险,这个风险,自然就是环境所带来的。反脆弱需要风险,其实就是人们常说的「走出舒适圈」。

反脆弱:从不确定性中获益

这个漫画本身并没有错,它确实反应了「走出舒适圈」可能发生的后果,但走出舒适圈并不代表「走进死亡圈」。我们需要风险,不代表要去拥抱所有的风险,而是选择那些「杀不死你的」风险。

你怎么创新?首先,尝试惹上麻烦。我的意思是严重的但并不致命的麻烦。

之所以需要风险,是因为风险(压力)会引起个体的「过度反应」,逐步累积的过度反应才是反脆弱的核心机制。健身增肌就是一个很好的例子,撸铁之所以能够增加肌肉,基本原理也是过度反应,被称之为「肌肉超量恢复」。当进行重量训练时,肌肉纤维(特别是肌肉的快速收缩纤维)会经历微小的撕裂或损伤,这种微损伤是超量恢复过程的触发因素。在力量训练后,肌肉细胞通过增加蛋白质合成来修复和增强肌肉纤维,以应对未来的压力。如果我们保持同样的运动强度,那么肌肉在适应这种强度之后也就不会再增加,如果我们增加运动强度,肌肉需要重新适应新的压力,继续生长。健身增肌最基本的原则就是「渐进式超负荷」,渐进式意味着要持续不断的训练;超负荷意味着每次的训练量要大于上一次,这样能够保持肌肉量不断的提升。

那么为什么个体会过度反应呢?一个可能的猜测是 Richard Dawkins 在《自私的基因》中所提到的「时滞性」,也就是延迟。这里的「延迟」指的是个体接收到压力的信息,然后作出反应来应对,以及应对方法的反馈,这几个步骤是存在延迟的。

基因是通过控制蛋白质的合成来发挥作用的,这本来是操纵世界的一种强有力的手段,但必须假以时日才能见到成效。 关于行为的最重要的一点是行为的快速性,用以测定行为的时间单位不是几个月而是几秒或几分之一秒。 基因并没有这样快的反应时间。基因只能竭尽所能事先部署一切。

在这种情况下,事先准备超量的肌肉和刚好够用的肌肉相比,前者在遇到危险情况的时候能够增加存活率,基因也倾向于「过度反应」。延迟造成的过度反应在现实社会中也非常常见,金融市场也是如此,当某个公司因为季度财报不达预期的时候,市场可能会发生大量的抛售该公司股票的行为,股价随即下跌,并且跌破能够反应公司真是价值的区间,但随后又会慢慢恢复能够反应公司真实价值的范围内。

压力在这里未必是一个很好的表述,没有人喜欢压力,更准确地说,「过度反应」是个体对外界刺激的反应,这个刺激源自环境的变化。我们都喜欢岁月静好,但现实却总是在随机波动,而反脆弱也需要这种波动。

当你脆弱的时候,你往往倾向于墨守成规,尽量减少变化——因为变化往往弊大于利。这就是为什么脆弱的事物需要明确的预测方法,反过来说,预测体系带来的只能是脆弱性。

反脆弱的风险

前面提到反脆弱是一个过程,更准确来说是一个不断重复且波动的过程,如果我们用冗余来代表强韧性,那么随着时间的增加,冗余的总量是在增加,但是短期内因为压力导致个体的牺牲,冗余会降低。

反脆弱:从不确定性中获益

从数学上来这个图形近似一个正弦函数,经济学中的康德拉季耶夫长波(即资本主义经济展示出约50到60年的长周期波动)也与之类似。当压力来临的时候,导致个体的「牺牲」,此时整体的冗余会降低;个体的过度反应会创造更多的冗余来应对未来的压力,此时整体的冗余上升;新的压力又会导致冗余的降低;个体继续过度反应创造更多的冗余。如此往复。

这里存在两个成本:

  1. 压力导致个体牺牲的成本
  2. 个体过度反应所需要的时间成本

这些成本同样也是风险,首先,前面也说过,过大的压力可能导致所有的个体牺牲,也就不会存在后续的增长;其次,个体的过度反应的时间如果太长,无法赶在下一次压力来临之前准备好,那么同样可能会导致冗余持续减少,并最终归零。

第一个问题,如果有得选,尽可能的避开过大的风险,选择能够承受的风险。第二个问题,则是学习的速度,相对于下一次风险降临的时间而言,只要个体「过度反应」的速度更快,那么就可以避免冗余归零。但现实中我们无法预测风险何时降临,于是只能说「越快越好」。

我们再回头看前面的整个过程,其实可以分成三个阶段:

  1. 压力产生;
  2. 个体因无法预测未来的压力,因此选择过度反应产生更多冗余;
  3. 新的压力产生,个体根据压力反馈的调整策略,此时可能有几种情况:
    1. 冗余完全可以应付新的压力,那么个体不会过度反应,并且预计未来的压力也是如此,也不创造新的冗余;
    2. 冗余完全刚好可以应付新的压力,个体预计未来的压力可能也是如此,于是只会补充失去的冗余;
    3. 冗余无法应付新的压力,个体继续过度反应创造更多的冗余,并且假设下一次的压力会更大。

我们可以把这个过程抽象成:1. 个体根据压力假设未来可能发生的压力;2. 根据对未来的假设来作出反应; 3. 当新的压力产生时,根据新的压力调整策略。这个过程基本上就是「问题的认知与表述、实验数据的收集、假说的构成与测试。」也就是说常说的「科学方法」。

前面我们一直把一个个体的「牺牲」当作是某种实验,就如同科学实验一样,不幸的是实验的成功率总是很低。也就意味着大量的实验,需要大量的时间来验证。「科学方法」实际上就是一种学习的过程,经常有人问我有什么捷径可以快速学习某种技能,入门确实有不少捷径可走,但是要精通,除了不断的练习和失败之外,似乎没有别无他法,所以时间成本实际上才是最大的成本。

鼓励失败的文化

美国的资产很简单,就是在冒险和运用可选择性方面,这是一种卓越的能力,即参与到合理的试错活动中,失败了也不觉得耻辱,而是重新来过,再次失败,再次重来。而现代日本则恰好相反,失败给人带来耻辱,导致人们想方设法地隐藏风险,不管是金融风险还是核电风险;创造很小的收益,却要坐在火药桶上,这种态度与他们尊敬失败英雄的传统,以及虽败犹荣的观念,形成了奇怪的对比。

当我们把反脆弱这个议题放在人类社会的时候,就不得不受到文化的影响。多样性需要大量的实验,而实验就不可避免的存在大量的「失败」,文化对待失败的方式会影响个体的风险承担能力、创新的意愿。传统的东方文化强调群体和谐与社会稳定,个人的行为被期望符合社会和家庭的期待。在这些文化中,失败有时被视为给家庭或个人名誉带来负面影响的事件。西方文化通常被认为更加强调个人主义和个人成就,失败往往被看作是学习和成长的机会。在商业环境中,特别是在像硅谷这样的创新热点,失败甚至被视为一种荣誉,因为它被视为尝试和创新的标志。

我时常也会经常恐惧失败,担心自己把事情搞砸。

这种恐惧源于对未知的忌惮,以及社会对失败的普遍负面的看法。而恐惧本身又反过来增加了决策中的不确定,从而形成一种恶性循环。

而事实是「失败不等于个人能力的体现」,反过来,我们也不应该将「成功」当作是一件事情的目标,取而代之的应该是「学习」。

这样一来原本的「失败」也变成了一种进步,我们的目的不再是为了成功,而为了学习,而学习最终会指引我们成功。

另一方面,我们也应该对那些经历过失败的人给予最大的敬意,正是因为他们的失败,我们无须再去冒相同的风险,我们从他们的失败中收获了教训。Tabel 提议美国应该有一个创业者日,纪念那些创业失败的人,是他们失败的经验,构成了美国商业的成功。


让我简单概括下上面的观点:黑天鹅事件风险大且不可预测,因此我们不应该去寻找预测黑天鹅事件的方式,而应该去适应有黑天鹅事件的世界。适应的方式就是利用反脆弱性来构筑越来越强韧的事物。事物的强韧实际上就是冗余的多少,冗余越多,事物越强韧,越能够应付更大的风险。反脆弱性通过个体的过度反应来创造冗余,因为时滞性的问题,当风险发生时,个体倾向于创造更多的冗余来应付未来的风险。我们可以利用这种机制来主动的去寻找合适的风险,来提升自身的强韧性。

个体是脆弱的,群体是强韧的,而个体与群体是相对的概念。作为一个人,我们即是个体又是整体。作为个体,我们是脆弱的,应该尽可能避免无法承受的风险,同时加入一个群体,学习其他个体的经验来提升自己的强韧性。作为一个整体,我们可以利用这种机制来强身健体,同样,我们脑海中的知识(文化)也是个体,也可以利用相同的机制来获得提升。

如果你只想记住一句话,请记住「渐进式超负荷」。

黑天鹅:如何应对不可预知的未来

2024-05-18 12:47:51

TL;DR

黑天鹅:如何应对不可预知的未来

黑天鹅事件是指那些难以预测但是冲击性极大的事件。难以预测的主要原因是:1)现实是非线性的,极小的变动都可能会产生巨大的影响;2)人类的认知偏误,导致我们会忽略黑天鹅事件发生的信号;3)我们的社会「并不鼓励」预防灾难,因为灾后救助的行为更容易获得认可和奖励。人类最大的问题在于我们以为我们能够预测黑天鹅事件(未来)


黑天鹅理论并不是一个新的概念,人们多多少少都了解这个概念,Nassim Nicholas Taleb 在《黑天鹅:如何应对不可预知的未来》中提出并定义了「黑天鹅事件」:

  1. 它具有意外性,即它在通常的预期之外,也就是在过去没有任何能够确定它发生的可能性的证据。
  2. 它会产生极端影响。
  3. 虽然它具有意外性,但人的本性促使我们在事后为它的发生编造理由,并且使它变得可解释和可预测。

概括起来就是:稀有性、极大的冲击性和事后(而不是事前)可预测性。

生活在 2024 年的我们对于这个概念一点都不陌生,我们经历了 2019 年灾难性的 COVID-19,又在 2023 年经历了可能会是改变人类历史进程的 ChatGPT 发布,这些都是黑天鹅事件,两者都具有意外性,都产生非常大的影响,这种影响并不总是负面的,ChatGPT 就是正面的例子。在本书中,作者要强调的是「我们表现得就好像我们能够预测历史事件,甚至更糟的是,我们以为能够改变历史进程。既然黑天鹅事件是不可预测的,我们就需要适应它们的存在(而不是天真地试图预测它们)」重点在于解释了为什么黑天鹅事件是不可预测的,至于如何适应黑天鹅,作者在这本书中并没有给出答案。

作者认为黑天鹅事件之所以不能被预测主要是认知偏误

  1. 我们只关注从已观察到的事物中预先挑选出来的那部分,从它推及未观察到的部分证实谬误
  2. 我们用那些符合我们对明显模式的偏好的故事欺骗自己:叙述谬误。
  3. 我们假装黑天鹅现象不存在:人类的本性不习惯黑天鹅现象。
  4. 我们所看到的并不一定是全部。历史把黑天鹅现象隐藏起来,使我们对这些事件发生的概率产生错误的观念:沉默的证据造成的认知扭曲。
  5. 我们“犯过滤性错误”:我们只关注一些有明确定义的不确定性现象,一些特定的黑天鹅现象(而不关注那些不太容易想到的)。

我想从另外一个角度来解释为什么黑天鹅事件不可预测,总结下有三个关键点:

  1. 非线性系统:我们生活的世界是一个混沌系统(复杂系统),也就决定了我们几乎不能预测未来。
  2. 认知偏差:我们的大脑对世界进行了高度抽象,抽象意味着会忽略很多细节,而关注发生概率更到的事件,这也是为什么我们会对黑天鹅事件视而不见,因为我们从内心里觉得这件事情不会发生。
  3. 社会奖励机制:包括对预防性措施和前瞻性思维的不足重视,社会奖励机制往往偏向于对已发生事件的响应而非预防未发生事件。

非线性系统

线性函数指的是只有一个变量的函数,例如 y=2x,线性函数在直角坐标中的图形是一条直线。在 y=2x 这个函数中,y 会随着 x 的增加而增加,缩小而缩小,哪怕我们对 x 的测量有一定的误差,对结果的影响也都是有限的。例如当 x=9.8 的时候,我们四舍五入的认为 x=10,对结果的误差也就只有 0.4。

黑天鹅:如何应对不可预知的未来
三个线性函数的图形都是直线。红色与蓝色直线的斜率相同。红色与绿色直线的y-截距相同。

非线性函数则意味着在直角坐标系中的,函数的图形不是直线,可能是曲线,甚至不是连续的。指数函数就是一个典型的非线性函数,非线性函数意味着 x 作为输入的变化,可能会对 y 产生很大的影响。例如 y=2x,如果 x 依然是 9.8,但是我们四舍五入到 10,那么测量结果将相差 132.6。(210 - 29.8 = 132.6)

黑天鹅:如何应对不可预知的未来
y=b^x 对各种底数b的图像,分别为绿色的10、红色的𝑒、蓝色的2和青色的12。

现实世界中的复杂系统通常是非线性的,每天早上我都会关注天气,你应该也有注意到,天气预报中,时间越长就越不准确,即便是当天的预报很多时候也是不准确的,望着窗外下雨的街道,天气 App 却告诉我今天不会下雨,只是阴天。现实世界中的许多系统(如气候系统、生态系统、经济系统等)表现出强烈的非线性特征,即输入变化的微小差异有时会导致输出的极大差异,这是混沌的典型标志,这也就是著名的「蝴蝶效应」。

黑天鹅事件经常发生的很突然,但其背后的原因往往是多种因素长时间积累的结果。而混沌系统的预测却需要非常精确的初始数值和函数,即使理论上存在能够完全描述系统的函数,实际上我们无法获取所有这些信息,或者即使获取到全部信息,也可能因为需要的信息量非常巨大导致无法有效的处理。也正因如此,黑天鹅事件是无法被预测的。

认知偏差

认知偏差是人类自己主动忽略黑天鹅事件发生前的各种信号。黑天鹅事件并不像太阳东升西落一样每天都会发生,它发生的频率很低,导致我们对相关事件的记载也就比较少,相关的理论也不够多。而每天都会发生的事情,因为案例多、研究多,我们经常会看到相关的信息,这些信息也会强化我们的认知,认为与之相对的事情都不会发生,这种认知模式并非一种缺陷,而是在漫长的演化中形成的。

想象一下你现在要过马路,路上有两辆车正在行驶,其中一辆在你离很远的地方,而另一辆则要近很多,你会关注哪一辆车。我们几乎不需要思考就能得出结论,应该关注距离较近的车,从概率上来说它更有可能造成危险。注意力对于人类来说是稀缺的资源,而通过逻辑推理来计算结果就需要消耗大量的注意力,这也导致我们其实无法关注太多的事情,在处理危机的时候我们倾向于关注更重要的(发生概率更高)的事情。

在《思考,快与慢》中,Daniel Kahnema 介绍了人类大脑运行的两种模式:

  • 系统 1 的运行是无意识且快速的,不怎么费脑力,没有感觉,完全处于自主控制状态。
  • 系统 2 将注意力转移到需要费脑力的大脑活动上来,例如复杂的运算。系统 2 的运行通常与行为、选择和专注等主观体验相关联。

系统 2 的运行需要消耗大量的注意力,人脑实际上更倾向于使用系统 1 来处理日常事件,直到遇到系统 1 无法处理的事情的时候才会调用系统 2。例如当有物体超我们飞过来的时候,我们无须调用系统 2 去计算这个物体的初速度和飞行路线等等,只需要系统 1 我们就可以快速做出闪躲的动作。这种快速反应在我们遇到危险的时候能够显著提升我们的生存机率。Malcolm Gladwell 在他的书《异类:不一样的成功启示录》提出了一万小时理论,这一理论认为要在某个领域达到专家水平,通常需要大约一万小时的刻意练习,该理论正是基于系统 1 的学习模式。系统 1 通过反复的经验和模式识别,将复杂的信息和任务简化为直觉反应,我们将这一过程称之为「抽象」。而抽象就意味着关注事件的共同点,而忽略一些细节上的差异,不幸的是黑天鹅事件往往隐藏在被忽略的细节中。

Taleb 在书中所提到两种谬误又会强化这种模式。系统 1 有证实偏见的倾向,即倾向于寻找和重视支持我们现有信念和假设的信息,忽视或否定与之相反的信息。而恰恰又是因为我们会容易找到经常发生的事情的资料,而那些被忽略的细节却鲜有人关注,也难以找到与之相关的信息,这种现实情况又强化了我们的偏见(幸存者偏差)。这在面对黑天鹅事件时尤为明显,因为这些事件通常与我们的常规经验和信念不符,系统 1 会自动忽略或低估其可能性。

18 世纪苏格兰哲学家 David Hume 质疑了这种基于经验的推理过程的合理性,他认为从过去事件的发生归纳出未来事件将如何发生,并没有逻辑上的必然性。也就是说,仅仅因为某件事情在过去发生过很多次,并不意味着它在未来也必然发生。Hume 说得没错,遗憾的是他并没有给出问题的答案。

社会奖励机制

社会奖励机制也是影响我们预测和预防黑天鹅事件的原因,预防性措施(如完善的公共卫生基础设施、库存疫苗和防护设备等)如果成功,就不会有显著的「成果」展示给公众和决策者。预防的成功往往意味着「没有灾难发生」,这使得这些措施难以获得社会的广泛认可和奖励。在 COVID-19 之前,许多公共卫生专家和组织曾多次警告全球应对大规模流行病的准备不足。然而,这些预警和预防措施在当时并未受到足够的重视和投入。相反,当疫情爆发后,救治患者、疫苗研发和抗疫措施得到了巨大的资金支持和社会认可。对预防措施的投入不足也导致人们没有足够的动力去做预防。


现实的非线性、人类的认知偏差和社会奖励机制都指向了同一个结果——黑天鹅事件的不可预测性。但这并不代表我们什么也不能做,Taleb 在本书中没有给出答案,但是在后续出版的《反脆弱 : 从不确定性中获益》中给出了答案,他把事物分成三类:

  • 脆弱类:脆弱的事物喜欢安宁的环境
  • 强韧类:强韧的事物并不太在意环境
  • 反脆弱类:反脆弱的事物则从混乱中成长

脆弱的事物喜欢稳定的环境,无法应对环境的变化,因此对黑天鹅事件几乎没有抵抗力;强韧类的事物有足够大的防御力,黑天鹅事件可能会对它造成影响,但是影响不大;而反脆弱类的事物则喜欢变化,反脆弱的事物不但不会被黑天鹅摧毁,反而会从中受益。而我们要构建的,正是反脆弱性的事物。

反脆弱的事物恰如尼采的那句名言:

What does not kill me makes me stronger

The Man Who Killed Google Search

2024-05-12 22:56:55

The Man Who Killed Google Search
Wanna listen to this story instead? Check out this week’s Better Offline podcast, “The Man That Destroyed Google Search,” available on Apple Podcasts, Spotify, and anywhere else you get your podcasts. This is the story of how Google Search died, and the people responsible for killing it. The story…

这个人是 Prabhakar Raghavan,在加入 Google 之前,Prabhakar Raghavan 在 Yahoo Lab 工作,在把 Yahoo 干黄了之后加入了 Google。2020 年之前他在 Google 广告部门,广告是 Google 的主要收入,搜索广告占 Google 整体营收的 56%。2018 年 Q3 开始,Google 广告收入的增长率首次开始下滑,一个原因是「搜索次数」这个关键指标的下降。而作为当时 Google search 部门的老大,Ben Gomes 认为这个指标无法反映出 Google 搜索质量的提升,因为搜索质量的提升最直接的表现就是用户通过更少的搜索次数就可以找到需要的内容。这种质量的提升直接威胁到广告的营收。

Google ad revenue

于是在 2019 年 2 月的时候 Prabhakar Raghavan 提出了一个 Code Yellow(意味着最高优先级)项目,致力于解决广告收入的下降。他的方案非常简单粗暴,虽然没有明确的证据,但是 2019 年 3 月的 Google Core Update 看起来是一次回滚,在此之前 Google 的算法主要在打击垃圾内容,19 年 3 月份更新之后很多在之前被 Google 打击的内容又重新出现了。Prabhakar Raghavan 还提出了很多降低搜索质量来提升广告收入的方式,例如关闭拼写修正这些功能,让用户多搜索几次。2020 年 Prabhakar Raghavan 取代 Ben Gomes 成为 Google search 和 Google ads 的老大,在此之前搜索部门和广告部门是相互独立的。

如今 Google 依然有 90% 的市场占有率,排名第二的 Bing 仅有 3%,而在搜索结果上,Google 其实已经足够优秀,Bing 几乎不可能超越,这也导致 Google 其实并没有动力去不断的提升搜索质量,只要稍微比 Bing 好就行。以前做产品的时候经常会有人问,如果用户体验和商业增长相冲突的时候我们如何抉择?绝大多数时候人们会选择商业增长,我们也看到很多产品商业化之后已经不是原来的样子了,知乎就是很明显的例子。以前,可能 Apple 是唯一一个会选择用户体验的公司,而在乔布斯离开之后的 Apple 也开始变得平庸,如今的 Apple 已然不能代表业界用户体验最好的公司了。

Issue #9 - 有关产品创新

2024-01-28 19:52:06

TL;DR

Issue #9 - 有关产品创新

首先我们需要理解这个世界,理解当中不合理的存在,然后尝试去对抗和改变这种不合理。这种力量源于不断的质疑,并有勇气从根本上重塑现有的系统和流程。最重要的是,不要对这个世界妥协。


一次与朋友聊天的时候聊到如何发现产品的机会点,我当时并没有答案,但我也一直在思考这些问题。我想从两个我最近使用的产品说起,一个是 Linear,一个是 Vercel。

Linear 是一个项目管理工具,对标 Jira。我很早就知道并且尝试过 Linear,但一直没有用起来,很大的原因是我当时并不认为它和 Jira 有什么区别,除了明显感觉到的「快」之外。Linear 的「快」让我都怀疑这真的是一个网页应用吗,Jira 同样也是网页应用。这点算是 Linear 向客户传递产品价值时并没有说的很清楚。但从能力上来对比 Linear 和 Jira,后者显然更强大,我想不到有什么理由我会需要用到 Linear。至于说速度,因为 Jira 功能更多,更复杂,也让我觉得它「慢」是有慢的道理的。因为 Jira 复杂,面向大客户,有很多复杂的逻辑在里面,所以它就应该慢。这种把复杂和慢捆绑起来的想法,在我看来就是理所当然。我虽然不清楚这背后的技术原理,但乍一听也合乎逻辑。我回头去看我们自己的产品也是非常复杂,同样也很慢,所以似乎也说得通?

「慢」如果是形容一个人,我们可能说是效率低下,但是对于复杂产品怎么就成了理所当然呢。「慢」的软件显然也会让使用的人慢下来。举个例子,在 Jira 里面,如果你是用 Scrum 类似的产品开发流程,上个 Sprint 里面没有完成的任务是需要继续放在下个 Sprint 里面,这点 Jira 已经自动化了。但是有些任务在上个 Sprint 已经消耗了一部分点数,但 Jira 的逻辑是只有当任务被完成之后才会记录点数。因此那些还在进行中但没有做完的任务就被算作是没有做,显然不合理,当然有 Workaround,我们可以修改这些任务的故事点,然后关闭它们,在新的 Sprint 里面在复制一批一摸一样的,然后重新估算点数即可。整个操作可能要花费半个小时的时间,而类似的操作在 Jira 里面非常的常见,并且每个操作都要等个 1–2 分钟,但是每天都这样做会浪费大量的时间。这当中有很多操作本来就不是必须的,只是因为 Jira 无法满足我们的需求,而不得不去做的 Workaround。另外一种方式就是我们改变行事方式,适应 Jira 所谓的流程来进行产品开发,但这根本就是要人命,人怎么能去适应软件呢?软件应该适应人才对,所有好的软件应该就是非常直觉的。

Jira 的「慢」逐渐成为一种麻烦,而麻烦会让本来不愿意去做的事情变得更不想做。项目管理这件事情在软件开发中本就不是重点,我们的目标是交付产品。项目管理是一种需要管理可能出现的风险而不得不引入的事情,它是额外的负担,在经济学中被称之为「交易成本」。项目管理虽不可避免的,但应该最小化。一个配合密切的团队也需要项目管理,但只需付出很少的成本就可以让整个项目跑的很好。

Usually, every team and company started with a quite casual way of managing work, but later needed some tracking system, and often ended up using something like JIRA. I could see how the team motivation sank and how much time the team wasted arguing against it. Eventually, people give up, since they have to use something and there aren’t any great options really.1

Linear 实际上就是在降低交易成本,而这种交易成本虽然我最初也知晓,但因为习惯了 Jira,认为复杂性带来的交易成本是理所当然,也就没有去深究。倘若我最初不接受这种设定,并努力对抗这种「理所当然」,我们应该是可以发现更好的方案。我庆幸最终发现了 Linear 的价值,倘若 Linear 这款软件不存在,我不确定我能否像这些开发者一样,打破这种固有的认知,设计出一个和 Linear 一样的产品。

我一直认为,一个好的软件的设计者,或者说最初发起这个产品的人,一定是在这个行业里有过多年的经验,他很清楚行业中存在的交易成本,并且有能力去跌幅这种固有的流程,这样的产品应该就是一个伟大的产品。但反过来想,行业中多年的经验是否会习惯了所谓的「理所当然」,让他即便知道问题也不会做出改变呢,我没有答案。不过有一点我可以确认的是,一个外行大概是不能设计出一个好的产品的。

这里的另外一个问题是为什么 Linear 不是由 Jira 创造出来的?难道 Atlassian 内部没有人觉得 Jira 已经变得非常难用了吗?Clayton M. Christensen 在《创新者的窘境》这本书中已经给出了答案,它们过于专注于当前客户的需求和现有市场的利润模式,从而忽视了新兴市场和技术的发展。


第二个我想聊的产品是 Vercel,与 Linear 类似,我也是很早就知道了 Vercel,但从来没有机会去尝试。在我看来,像 AWS 这样的 IaaS 平台很成熟,功能也很强大,为什么我还要用 Vercel 呢?一个偶然的机会让我对 Vercel 的「快」印象深刻。我们的一些合作伙伴使用 Gatsby 作为前端并部署在 Vercel 上,同样使用 Gatsby 的我们,网站速度虽然也很快,但当我打开合作伙伴的网站时能够很清晰的感觉到它们的速度更快。一番研究之后发现它们的网站是部署在 Vercel 上,而我们用的是 Cloudflare,对比之下,从客户端请求到 CDN 的时间,Vercel 是 27ms,而 Cloudflare 是 103ms,我们对此都非常吃惊,我的经验告诉我 Cloudflare 提供了非常专业并且非常强大的 CDN 服务,居然跟 Vercel 有这么大的差距。虽然我产生了一个想法,就是把博客部署在 Vercel 上,我倒是要看看到底有多快。一番折腾之后终于有了结果,不过这次让我感到惊艳的地方不是速度,而是整个的部署体验。

先说一下我们当前的部署流程,首先需要把代码从一个分支合并到发布的分支,当 PR 合并之后才能进行部署。部署的时候工程师需要去到另外一个系统里面进行操作,这个发布系统有自己的版本和标签体系,因此工程师要仔细的对比这上面最新的版本是不是 GitHub 上刚刚合并的,如果不是那就要想办法了,或者刷新试试看。确认没有问题就可以点击部署了,然后是 20–30 分钟的等待。因为没有通知,工程师不定时的上去看看状态。等发布成功之后,工程师会通知设计师和产品经理去某个环境验收,然后丢出一个网址。设计师和产品经理打开网页,发现问题之后一边截图一边在 Slack 里面 @ 工程师哪里有问题,如果问题比较多的时候干脆直接开一个 Google Sheet 把截图都放进去,然后再加一列来标记工程师是否修复了这个问题。然后不断的重复上面这个过程。这当中没有一个人是快乐的,每个人都很痛苦,设计师很痛苦,工程师很痛苦,产品经理也很痛苦,但是有什么好的解决方案吗?我们尝试过去做一些改进,但是这个框架就是那样,最终大家还是只能痛苦着。

Vercel 的整个流程也是从一个 PR 开始。当一个 PR 被创建的时候,Vercel 就会进行部署,当部署完成后 Vercel bot 会在 PR 下面 comment 部署情况和预览的网址,在预览环境中,设计师可以直接在网页上 comment 某个元素,comment 的数量同样会同步到 PR 中,如果有尚未处理的 comment,那么 PR 就不能合并。再也不需要在 Slack 里面 @ 人,再也没有 Google Sheet 了,所有的操作都那么的直觉。用完之后我的感觉就是,产品验收流程就应该是这样。

这不仅仅是一个工具上的变化,而是整个工作流程都被简化了。我虽然不是工程师却也能感觉到原本流程中的痛苦,如果你问我应该如何优化整个流程的话,我未必能够想到像 Vercel 这样的方案。或许是因为在这个系统中待久了,觉得很多东西理所当然,在思考解决方案的时候也会被这些理所当然所束缚。就好像当福特问他的客户想要什么时,他们可能会说更快的马。而我可能希望更快的 CI。能够提出最佳解决方案的人首先深知其中的问题,不是表面的问题,而是挖掘到问题的第一性原理。从那里开始思考解决方案。

有时候解决方案不是一个软件/工具那么简单,有时候还需要思维上的改变。前面提到 Linear 在价值传递上不明显,从我个人选择 Linear 的过程来看,这个价值并不仅仅是 Linear 这个工具,还包括 Linear Method 所提到的软件开发方式。因为 Jira 慢这个件事情也不是一天两天了,我最初意识到我们需要优化我们一直使用的 Scrum 流程,在《Scrum is a Cancer》介绍了背后的思考,而新的方式更接近于 Linear Method,这个时候我才发现 Jira 已经无法满足我们的方法,然后尝试去使用 Linear。在用了 2 Sprint(6 周)之后才算真正认识到了 Linear 的价值所在。


对人来说,包容可能是一种美德,它们代表着理解和耐心。但在软件设计中,包容会成为创新的障碍。它们束缚了我们的想象力,限制了我们探索新可能性的能力。软件的创新恰恰源于对现状的不满。首先我们需要理解这个世界,理解当中不合理的存在,然后尝试去对抗和改变这种不合理。这种力量源于不断的质疑,并有勇气从根本上重塑现有的系统和流程。最重要的是,不要对这个世界妥协。

We believe people with passion can change the world.2

  1. Starting Linear by Karri Saarinen, CEO & Founder of Linear ↩︎
  2. Steve Jobs most innovative speech - YouTube ↩︎