揭秘Uber史上最大规模工程组织变革

2021-12-31 11:19:09 浏览数 (1)

作者 | Gergely Orosz

译者 | 核子可乐

策划 | 刘燕

回顾那场对 Uber 工程文化影响深远的变革。

2014 年春天,Uber 公司首席产品官 Jeff Holden 给技术团队发出了一封电子邮件。

这封邮件中讨论的变革将彻底改变 Uber 的工程动作方式并塑造未来几年的新型文化。

但这封“雷霆万钧”的邮件,却有着相当平淡的开头:

经过对内部大规模的数据收集、思考与讨论之后,我们决定将公司整体划分为项目(Programs)与平台(Platforms)两大版块。请参考邮件附件,了解您自己身处项目团队还是平台团队、特别是在新团队中的职能定位。”

而这时候距离 Uber 招聘第一位全职工程师才刚刚过去三年。这时候 Uber 已经拥有 100 多名工程师、10 位产品经理(PM)和 15 名设计师。几乎所有工程团队都在独立运作,各自拥有不同的发展路线图和项目。

此次调整代表着 Uber 的一次早期演变,也宣告着 Uber 将正式告别以往聚集员工、交付项目、完成拆分再转移到下一个项目这种过于粗放的工程运作模式。

这份邮件解释了现有组织结构将经历怎样的转变:十余个团队将被划分为 16 个项目团队加 11 个平台团队,每位员工都将归属于其中一支平台或项目团队。

但大多数团队人手仍然不足,需要再额外雇用 100 多位面向工程、产品和设计岗位的新增人员。新团队将按重要性排名,例如,负责增加司机供应的团队,在优先级排名方面就远高于扩大乘客需求的团队。

这封邮件宣示的是 Uber 有史以来规模最大的一次工程组织变革: 建立跨职能项目团队,同时引入平台团队的概念。

截至目前,Uber 的运营仍然遵循着这波变革的路线,即一支团队要么属于项目团队、要么属于平台团队。

但到底是怎么划分的,又有什么意义?我们不妨先从这两类团队的定义入手。

项目团队

项目团队(在其他公司里通常被称为产品团队)占全体工程人员的 60% 到 70%,他们围绕一个使命进行组织,负责快速执行并优化产品创新。

项目团队具有如下特征:

  • 长期存在:并非针对短期项目所组建,而是围绕着司机体验、市场效率或者亚太地区业务增长等目标而建立。各个团队拥有明确定义的发展使命。
  • 跨职能特性:每个团队都拥有必要的人员配备,所以各团队内既有工程师、也有非技术人员。团队中通常有一名产品经理、一名数据科学家甚至是一名业务运营人员。就连工程工作本身也具有跨职能属性,大多数团队都设有后端和本地移动工程师,部分团队甚至拥有网络工程师。各团队分别负责Rider、Driver 或者 Eats 等具体应用功能。要构建和运行功能,当然需要构建并维护相应的后端系统和客户端代码。
  • 外部客户:项目团队会直接与外部客户合作,交付供他们使用的功能。客户涵盖的不只是 Riders、Drivers、Eaters 或者 Couriers(骑手、司机、食客、配送员),同时也包括公司内部的运营、客户支持或会计人员,外加货运客户、Jumper 自行车骑手等其他小体量领域的客户。
  • 关注商业使命:各个项目团队都专注于推动业务发展。例如,如果业务发生巨大变化、特别是不再需要关注增长,那么相应团队也将解散转移。随着时间推移,项目团队也一直在变化、一直在成长。当然,也有部分团队因为没能达到预期的快速增长目标而提前解散。Uber Rush 就是典型案例,由于一直无法达成预期增速,团队只能宣布撤销。在加入 Uber 时,我曾在一个项目团队工作过很长时间,当时主要负责乘客付款功能。我们的使命就是为所有自行车骑手提供顺畅的支付体验。在刚刚接手时,团队是一个由 8 名原生移动与后端工程师组成的跨职能部门。

当然,此外还有产品经理、数据科学家、设计师以及产品运营人员等成员。在使命调整之前,这支团队曾经扩大到拥有约 12 名工程师。

我们的客户就是使用 Uber 应用的自行车骑手。我们会通过吸引新客户、增加总订单量以及成本节约等指标衡量自身业务的影响。这些指标会随着各个计划周期而变化,旨在适应 Uber 公司的现阶段业务诉求。

平台团队

平台团队为项目团队提供构建块,后者则负责将这些构建块转化为实际业务影响。项目建立在平台之上,平台确保项目能够顺畅运行。各个平台团队均具有以下特征:

  • 专注于技术任务: 平台专注于各类技术目标,例如扩展关键区域、实现性能或可用性目标,或者建立起易于扩展和维护的架构,并为多个团队和区域提供服务等。
  • 专业且较少跨职能: 由于平台团队专注于解决技术问题,所以几乎没必要引入跨职能结构。平台团队通常只面向一个领域或者堆栈,大多数团队也只有面向特定堆栈的工程师。后期,部分平台团队也开始与技术产品经理(TPM)或者产品经理合作,但这种情况在早期非常少见。
  • 客户主要是内部工程团队: 平台团队的大多数客户是其他项目团队的工程师,极少数情况下也可能是使用该平台的业务人员。正因为如此,大多数平台团队才只吸纳工程师成员。当然,也有少数平台团队会直接为外部工程客户提供服务,例如交付开发 SDK 的团队。
  • 供多个“垂直”领域(项目或平台)使用:每个平台都面向多个客户,平台团队在建立任何功能时都必须考虑到这个硬性前提。如果某项服务或功能只供单一项目使用,那么其就该归为项目团队所有、而非平台团队。随着我所在的团队在Uber 内部不断发展壮大,我最终拆分了这个平台团队,建立起支付 Web 平台与支付移动平台两个新团队。这些团队掌握着支付构建块,供 Uber的其他团队利用这些构建块快速发布 Web 或移动支付功能。

对于包括我自己在内的大部分工程领导者来说,建立平台团队往往极具挑战。最重要的当然不是控制员工人数,而是如何提前为团队配备必要的人手;此外,衡量平台团队是否成功的定义往往也比项目团队更模糊、更复杂。

共享项目 / 平台特性

虽然项目和平台团队各自负责解决不同需求,但双方仍具有以下几个共同点:

  • 单一经理面向所有工程师: 团队中的每位工程师,无论他们熟悉哪种堆栈或专业方向如何,都向同一位团队工程经理汇报。工程团队是一个紧密耦合的单元。
  • 谁构建、谁拥有: 无论团队构建出怎样的成果,他们都需要保证成果质量、随叫随到并有责任维持一切正常运作。于是,平台团队和项目团队都需要随叫随到、准备解决成果中出现的问题。
  • 质量标准保持统一: 无论身在哪个团队,我们都需要遵循相同的质量标准。代码必须经过测试并接受功能监控。很多人都惊讶地发现,Uber 的平台团队会在几乎一切方案中添加遥测机制,而且往往能比客户更早知道自己的系统何时出现问题。例如,开发者体验团队会收到持续集成(CI)服务发回的问题警报,并在工程师实际上报问题前就开展深入调查。
  • 无需许可即可构建: 即使不是平台团队的成员,大家也可以随意创建新的服务、模块或者可重用组件。很多平台其实就是项目团队开发成果的延伸。这类新建平台要么发展成新的独立平台团队,要么就是被移交给负责该领域的平台团队。
  • 项目团队地随着成长而发展成更多项目与平台团队。 作为项目与平台方法的自然结果,项目团队会不断成长并分化出更多项目或平台团队。平台团队往往掌握着跨项目的共享功能与责任,而这种“分化”也成为 Uber 组织大多数部门的自然过程。所有这些特性都与团队自治有关。团队自治与工程自治正是硅谷企业探索出的核心要诀,同时也是传统企业难以理解和实现的精要所在。

尽力而为的先遣队

Uber 在推进组织变革方面一直遵循大胆、果断的行事风格。 相较于更稳妥的逐区域渐进式变革,Uber 领导层直接公布部门拆分的明确日期,并将每支团队视为一支独立的先遣队。

这有点像《星际迷航》中各支先遣小队如何从企业号飞船前往行星表面。在各自迁移至项目与平台团队的同时,Uber 公司也将总部搬到旧金山的市场街,标志着与过去的自己彻底道别。

很明显,Uber 希望能在各支先遣队完成人员充实之前抢先重组。这意味着部分团队仍将以骨干成员的身份运作,尽可能早一步为招聘 / 留任工作厘清思路。

项目先遣队。在开展项目与平台团队重组时,相当一部分团队出现了人员配备不足的问题。也有部分员工被标记为“TBH”(待聘用)。

在我看来,Uber 能够成功完成重组要归功于几大原因:

首先,工程技术管理层非常清楚根据之前的招聘预测与投资规模,人员招聘不会出现什么大问题。因此在决定扩张之前,他们肯定已经与招聘人员充分沟通,确保他们理解招聘目标、成本预算等信息。

更重要的是,Uber 的领导层还必须对业务的持续增长、特别是最终超越现有结构抱有坚定的信心。做出如此重大的改变势必在短期之内影响简略,但团队会快速恢复活力并以更高的效率继续大步迈进。

事实证明,Uber 高管对于业务增长的信心是正确的。Uber 公司的拼车业务不仅一路飙升,还在 2014 年夏天启动了 Uber Eats 业务、2017 年上线 Uber Freight,后续几项新业务也纷纷取得成功。

解决旧结构带来的老问题

在变革之前,Uber 采取的是典型的功能性组织结构,包括工程、产品管理、业务运营、设计与数据科学等部门,各个部门都通过自己的团队保持运营。工程师们按团队分组,且各团队均不包含来自其他学科(如产品管理或设计)的人员。

当时的工程团队分为 Rider Operations、Driver Operations、Dispatch 和 Mobile 几大块,但并没有专门的产品经理或其他职能责任。产品经理大多充当项目的拥有者,并且经常与多个团队相互配合。

我个人将这种方式称为“基于项目的方法”,一般更强调稳定的工程团队组成。虽有好处,但这种结构也让项目夺取了工作方式与组织方式的主导权。

这种基于项目的方法当然有很多优点:

  1. 响应时间。 每当有新机会或出现新威胁时,我们都可以组建起新项目加以解决,不需要太多协调努力。
  2. 灵活性。 就算管理者不知道接下来会出现哪种类型的工作内容,基于项目的结构在短期内也足以应付下来。Uber 早期的发展经历已经证实了这种灵活性优势。当时我们并不清楚接下来的重点是应对外部事件、把握新机会还是执行现有计划,那保持固有结构肯定是最安全的办法。
  3. 规划和结构性成本较低。 各团队实际上是通过项目进行自我组织,共同应对企业面临的最大挑战。只要整个体系运作良好,似乎就没必要给规划和组织团队额外增加工作负担。但随着业务发展,基于项目的方法也开始暴露出众多缺点。对当时的 Uber 来说,问题主要有以下几个方面:

业务持续发展,难以确定优先级次序:

初期由于团队规模较小且优先事项不明,所以基于项目的结构没什么问题。但后来 Uber 的业务开始愈发复杂化,Driver 和 Rider 应用的上线以及众多新功能的加入带来了我们之前根本无法想象的复杂应用结构。

让人头痛的不只是应用程序功能;业务运营团队需要在不同城市推广更多一次性计划。而财务、法务等部门也有自己的项目需要完成。对几十个项目进行快速排序变得越来越困难。

很多跨职能项目一亮相就是 MVP,后来却无人问津:

不少项目在刚确定时份量极重,但在启动工作完成后初始团队会立即放手移交;作为接手者的工程团队虽然充当了名义上的拥有者,但移动工程师、产品经理或业务运营人员往往更关注下一个项目。于是很多之前的投入就打了水漂。

可以看到,由于跨职能工作总是“临时”进行,所以难以保证项目的“后续维护”。这一点在涉及移动工程师的业务中体现得尤其明显,毕竟他们自己都不知道接下来会被叫去支援哪些团队。

新项目的启动变得愈发难以协调:

基于项目的方法虽然提出了“配合合适的人员随时启动项目”这种看似美好的理论,但现实远远没那么简单。

每个项目都需要具备特定技能和领域经验的人员,包括移动工程师、设计师或者业务运营人员。但这些人往往归属于其他项目,而这位有空、那位在忙的协调缺少让“随时启动项目”变成了“总也启动不了项目”。另外,同一拨成员身兼多个项目往往让人精神错乱、注意力难以集中。

孤岛项目越来越多,跨职能项目越来越少:

由于跨团队项目的启动步履维艰,公司内部对于跨职能项目的协调能力也就越来越弱。例如,由于所有移动工程师都归属于移动团队,其他部门发现很难“预约”到移动工程师,于是大多数人开始尽可能去除涉及移动元素的功能。

而这时候的 Uber 已经到了发展的紧要关头,必须保证优先启动最匹配业务需求的项目——为此,他们必须解决阻碍前进的潜在问题。

最重要的业务目标一定具有跨职能属性:

Uber 意识到,单纯交付“简单”且孤立的项目并不符合客户和企业自身的利益。

Uber 需要降低跨职能工作的实施门槛。项目团队通过逻辑分组重新在企业内部定义了优先事项,而 Uber 则承诺为这些团队长期提供人员配备。平台团队专为支持项目团队而生,确保他们能够专注于自己的业务使命,并在共享的平台之上各自衍生出不同的发展方向。

由此引发的新问题

但天底下没有免费的午餐,组织结构转型也是如此。每次结构变化在解决部分问题的同时,也会引发新的问题。Uber 的结构变革在刚开始就带来了不少明显的新问题,也有一些问题在随后的运营中陆续涌现。

“双重报告”:

如今,每个团队都有了自己的产品经理、设计师、业务运营及其他职能角色;但原有报告结构并没有变化,于是团队成员只能打两份报告,一份给团队内领导、一份给职能部门领导。

工程技术领域之外出现了严重的“双重报告”问题。每个团队都有了自己的产品经理、设计师、业务运营及其他职能角色;但原有报告结构并没有变化,于是团队成员只能打两份报告,一份给团队内领导、一份给职能部门领导。

可以看到,这样的新制度下每位设计师都对应一名设计经理,而设计师自己又需要与每天合作的跨职能团队成员交代情况。这就引发了“双重报告”结构。看似问题很大,但这已经比过去的结构好得多——以往,设计师需要向对设计一无所知的项目负责人报告,后者很容易提出一些完全外行的“指导意见”。这种状况不仅会给项目带来混乱,同时也使得设计师没法获得专业指导、阻碍其职业发展规划。

于是双重报告结构继续存在,但职能部门的负责人需要密切关注下属们参与的各个项目。这种变化确实让职能经理们的工作更加困难,但同时也维持了团队组成的稳定性,让他们真正理解了自己的专业到底在如何发挥实际作用、铺设出一条更具前瞻性的职业发展轨迹。

应对意外变化时灵活性较差:

在基于项目的时代下,大家可以轻松应对意外变化:马上组建新的项目团队。但在项目团队与平台团队稳定区分的现在,应对意外变得更加复杂。

这种意外响应灵活性的下降其实是权衡后的结果,所以我们才说体量较小的初创企业在适应并改变工作方式方面更具优势。初创公司可以随心所欲地适应,而科技巨头则需要时间推动大规模重组。

应对新事件的常见办法就是建立专门的新团队,或者重组现有团队。建立新团队、选调部分老员工、再招聘几名新员工,这明显是破坏性最小的方法。至于更复杂的状况,企业可能需要进行更全面的重组。而 Uber 显然选择了后一种方法,划分项目与平台团队,以一着险棋在市场竞争中占据了主动。

部分团队产生思维惯性,开始做低优先级工作:

在项目加平台的双轨时代中,每个团队都具有明确的愿景和使命。但如果这些愿景和使命对企业不再重要,又会怎样?从宏观角度来看,公司当然希望能把人员转移到其他更重要的工作当中。

要解决这个问题,领导层会定期审查每支团队是否有必要存在。Uber 的方法就是开展季度性项目与平台团队审查。在审查中,领导们会关注各团队的影响、发展路线图以及如果团队不存在会造成哪些影响。

我发现 Uber 在自我审查方面做得确实很好,特别是擅长考量项目团队的存在意义。当团队的影响力下降时,领导层要么调整团队的资源配置(让部分成员转出去做其他工作)、要么直接解散团队并为成员们指定新的探索领域。

企业适应商业环境变化的方式决定了自身成败,这也是我在 Uber 看到的客观现实。这家以“快速行动”和“领先于竞争对手”为目标的公司确实很善于果断裁撤掉不再重要的团队,同时建立起更具现实意义的新团队。

Uber 目前的竞争对手主要是那些仍以项目为核心的初创公司,后者的运营思路跟过去的 Uber 很像。这些初创企业能够以惊人的速度对新的市场机会、监管变化或竞争关系做出反应。Uber 则需要保持自身灵活性,同时以新结构解决传统基于项目方法中的种种痛点。

谁来决定该建立哪些团队?:

在 Uber 决定启动项目与平台重组时,所有团队都已得到明确定义。季度审查则负责确定各团队是否还有存在的必要。如果没有,则可能缩小团队规模甚至将其解散。

但这些决定由谁来做出?决策流程是怎样的?谁对资金拥有最终决定权?毕竟在 Uber 这样一家快速发展的企业中,总会有游离于常规评判标准的新团队和新思路。

答案是,做出决策的是技术领导团队。他们会收集建议和商业案例,再由 CPO(首席产品官)决定项目团队、CTO 决定平台团队。随着时间推移和 Uber 的发展,这种决策权会被逐步下放到部门负责人手中。

改革成效

如今距 Uber 的项目平台拆分计划已经过去七年多了,这场变革让企业获得了良好的运作态势与竞争活力。

纵观整个 Uber 职业生涯,我发现平台团队确实能够跟上用户增长、项目团队也能随时获得成果交付。

现在的 Uber 仍在遵循平台 - 项目拆分理念,而且在持续发展中逐渐形成了“在大初创公司中建立小初创公司”的良好文化。

对于每项新倡议,公司会先设立一个小型项目团队,成员们尽可能利用现有平台以低成本方式做出试水。如果小团队取得成功,规模就能持续扩大并最终发展成常规的项目团队。在进一步发展后,他们可能拆分成两个项目团队、四个、六个,之后又孕育出一个新的平台团队……周而复始。

将三到四成工程人力资源划拨给平台工程无疑是一项巨大的投资。任何商业人士都很难想象这样的配置思路,毕竟这意味着短期内能够交付的功能将减少三到四成。

然而,Uber 的平台团队又分为三种类型,而且各自服务于不同的客户群体:

  • 基础设施类平台:Uber 的第一批平台团队,他们为大部分工程技术团队提供基础服务,具体涵盖存储、计算、移动等平台。
  • 开发者平台: 这是一种值得关注的特殊基础设施平台,相关团队的使命在于提高整个公司的工程师与工程团队效率。他们掌握着 CI/CD 系统、控制不同平台上的开发者体验,并不断研究创新方法以帮助工程师们更高效地交付成果、获取反馈并缩短功能迭代周期。
  • 面向客户型平台:这是一种不太常见的特殊平台案例,相关团队负责为内部、非技术客户以及包括工程师在内的外部客户提供服务。相关示例包括通信平台,会以“低代码”方式向客户和业务用户提供消息传递功能。另外,负责开发Uber Developer SDK 的团队也属于这一类,负责向外部开发者提供服务。
  • 产品平台: 从多个项目团队的实际需求演变而来。例如,小费和评分平台团队就源自众多项目团队对这类功能的共通需求。他们开发出的产品能够供 Driver、Eats 乃至 Freight 等团队共同使用,只是不同团队的实际用例略有区别。如果我们把大多数工程师都投入产品领域,而不像 Uber 这样高度重视基础设计,结果又会如何?

在我看来,架构、可扩展性和技术债务会很快给工程团队带来巨大压力,导致他们被迫采取计划外迁移来解决底层系统问题。更重要的是,工程技术人员的流失问题会相当严重,毕竟谁愿意待在一家部门间互不关心、松散无序的企业里?

平台团队的概念当然不是 Uber 的专利,不少快速增长的组织在特定领域都建立有专门的平台团队。我坚定认为平台才是一切技术组织稳定扩展的关键,也是他们不断突破效率极限的必要前提。

平台团队之我见

我跟平台团队合作过多年,也参与过多个平台的创建过程,观察到其中数十个团队的运作状态。下面我想聊聊自己对于平台团队的一点看法。

平台团队的部署不够直观。 从商业角度来看,平台团队似乎缺乏现实意义。

“我们为什么要把两成到四成的工程师投入到客户永远接触不到的工作当中?更离谱的是,我为什么要让最优秀的工程师参与这部分工作?”

这个问题是大部分企业在组建平台团队时做出的普遍反应。确实,平台团队在小型组织内毫无意义,对那些现有结构比较稳定而且业务增长幅度不大的组织同样没什么吸引力。

平台团队能够提高组织效率。 如果标准化确实对组织整体有利,那么平台团队的存在能够减少重复工作、推动方法标准化。例如,后端安全平台团队能够帮助我们对企业内的安全漏洞开展全面检查,同时有助于发现重复消耗资源、或者与既定原则相冲突的安全方法。

在平台团队落实到位后,我们能够更轻松地减少重复工作。平台团队的使命是为使用他们服务的客户获益,包括让产品团队将精力集中在产品身上,同时也让平台自身变得更加灵活、更好地为更多客户服务。

对于快速扩张的业务组织,平台团队必须存在。 如果您的业务已经超越了几十名工程师能够承受的极限,而且业务在客户群体、产品类别及流程复杂性等方面快速升级时,大家就必须建立起自己的平台团队。

平台团队满足的是那些非功能性需求,例如系统可靠性、更高的负载处理能力以及更稳定的产品支持能力等等。

这种非功能性其实非常重要,但却往往被决策者所忽视。具体包括:

  • 可靠性(正常运行时间、存储可靠性、数据持久性等)
  • 延迟(系统响应时间、UI 延迟等)
  • 性能(系统、UI 等)
  • 客户端非功能性约束(内存使用、应用程序占用空间等)
  • 合规性
  • 安全性
  • 开发者体验(编译 / 测试 / 部署时长、CI 周围时间、开发者工具使用体验)组织结构越复杂,就越是需要由专门的非功能性团队帮助其他团队获得这种共通的日常运作基础。

产品平台团队在业务扩展方面与基础设施平台团队同等重要。随着产品覆盖区间的拓展、特别是逐步拆分为多支产品团队,企业当然需要将通用功能和服务转移到各个新的产品平台团队。如“事后总结”部分所述,Uber 的通信平台团队也正是由此衍生而来。

平台团队会带来新的痛点。 我当然承认平台团队带来的巨大帮助,但平台团队的出现也给组织带来不少新挑战。受篇幅所限,这里我只简单谈谈几个值得关注的问题:

  • 难以定义并衡量团队目标与关键结果。 对平台团队产出的准确衡量要远比衡量常规项目团队更难。项目团队基本都有自己的一套相关业务指标,但平台团队就没那么单纯。另外,平台团队的发展周期也大多更高,所以在目标反馈上也比项目团队更慢。
  • 容易出现倚老卖老、思维固化的情况。 平台团队往往需要同时面对多个工程团队,而且会在整个公司内部产生影响。在这样的团队中工作,工程师们若不 需要跟实际业务相关者打交道,毕竟他们的“客户”主要是其他工程师。这听起来很好,但却容易让成员们骄傲自满、目空一切,反而有碍于大多数团队成员的职业发展。
  • 平台团队容易“替客户做决定”。 平台团队必须权衡自身决定与客户决定之间的关系。例如,平台团队既需要稳定投资并控制技术债务,同时也要及时拿出有利于客户团队的新功能。但也有部分平台团队坚持优先处理自己认为重要的工作、甚至可能破坏客户团队利益,这种倾向非常危险。
  • 保持与客户的顺畅沟通。 我发现不少平台团队开发的确实是客户想要的功能,但在实际发布后结果却令人失望——客户这时候才意识到自己并不想要这个功能,也不想承担后续维护成本。于是,如何与客户保持开放畅通的反馈循环就成为新建平台团队面临的一大挑战。

这还只是产品与平台议题的冰山一角

我特别关注产品和平台的议题,而本文所涉及的也只是 Uber 在项目与平台转型工作中的冰山一角。

这里要感谢各位 Uber 高管和行业资深人士提供的帮助,特别是:

  • Ganesh Srinivasan——Uber 公司前工程技术副总裁,在公司只有 5 位移动工程师时创立了 Uber 移动平台团队。我们探讨了快速行动为何如此重要,以及他对其他一些平台方案的看法。
  • Adam Rogal——Uber 公司前任移动平台团队负责人。他目前担任 Doordash 公司开发者平台总监。我们讨论了平台、开发者生产力以及二者之间的联系。
  • 其他关于平台工程的主题。感谢各位朋友的耐心阅读,也期待您能分享自己的观点与意见。

原文链接:

https://newsletter.pragmaticengineer.com/p/program-platform-split-uber

0 人点赞