阿里云「飞天发布时刻」2024来啦!新产品、新特性、新能力、新方案,等你来探~ 了解详情
写点什么

这活儿干不下去了:十几年积累的 300 万行代码,领导要全部“快速”重写,我直接辞职了

  • 2024-04-09
    北京
  • 本文字数:9893 字

    阅读完需:约 32 分钟

大小:4.69M时长:27:20
这活儿干不下去了:十几年积累的 300 万行代码,领导要全部“快速”重写,我直接辞职了

在追求商业利益的同时,必须重视代码质量和技术文化的建设,才能避免重蹈覆辙。


LinkedIn 作为全球最大的职业社交平台,拥有数亿用户,其代码库规模也是相当庞大。2019 年时,其前端代码量就达到了 200 万行,构建时间长达 17 分钟。后端还有支持 LinkedIn 功能、广告销售平台等数以千计的服务。如此庞大的代码量,给维护和更新带来了巨大的挑战。


更糟糕的是,由于长期以来为了快速推出新功能而忽视代码质量,导致系统问题频出,开发团队疲于应付:无论在 QA 环节上付出多少努力,都不可能彻底消除隐患。而且,LinkedIn 技术架构一度还停留在比较早期的阶段,比如使用 Ember.js 框架。


作为 LinkedIn 官网的技术负责人,Chris Krycho 在这里工作了将近五年,致力于更新 LinkedIn 代码库。Chris 表示 LinkedIn 是“世界上最大的 Ember.js 用户”,但他认为 Ember.js 并不是最佳解决方案。

为解决这些问题,他制定了一个迁移方案,计划将代码从 Ember.js 迁移到 React。另外 LinkedIn 公司还有一些政策限制,例如涉及多个团队的流程不能占用超过 10% 的开发时间。那么,如何在不违反 10% 规则的情况下,迁移包含了 300 万行代码的系统呢?


Chris 认为他的方案是一个可行的渐进式重构计划,不过需要“三到五年。而三年甚至还是非常乐观的估计。” 该计划同样需要开发自动化工具,但不会影响到业务的正常运行,“产品团队将永远不必真正停下来”。


与此同时,公司内部另一个团队提出了一个大爆炸式的替代方案:“重写移动端和桌面端应用”。与 Chris 的五年计划相比,后者却能投领导所好。“我的提议落选了”,但 Chris 认为公司没有重视代码质量和技术债务问题,并暗示替代方案仍然可能会重蹈覆辙,再次陷入技术债务的泥潭。


最终,因为对公司技术文化的失望,Chris Krycho 选择离开了 LinkedIn。



对于 Chris Krycho 描述的问题,一位网友用了一次性账号做了如下评论:“我是一位在 LinkedIn 工作多年的工程师。虽然没有与 Chris 合作过,但我完全理解并认同文中所表达的挫败感。如今,LinkedIn 的管理模式已变得愈发自上而下...... 为了尽快交付功能,LinkedIn 内部弥漫着一种急功近利的氛围。这种浮躁的心态导致了大量技术债务的积累,速度与质量之间的平衡荡然无存。新功能的开发往往忽略边缘情况,留下许多漏洞和缺陷。尽管承诺会进行修复,但最终却不了了之。高层只知道我们上线了新功能,没人告诉他们这些功能烂到根本无法使用。在绩效考核的压力下,工程师们只能忍气吞声,疲于奔命地完成一项项任务。他们无暇顾及代码的质量和可维护性,长此以往,技术债务只会越积越厚。”


下面我们来一起看看 Chris Krycho 的自述:


几百万行代码是怎么堆出来的


2019 年 1 月末,我正式加入 LinkedIn 公司。


我之前工作过的初创公司都有一套相对标准且比较完善的整体后端,再加上数据库、配套服务之类。但在进入 LinkedIn 之后,我发现:第一,大部分工程师其实是在前端客户端应用上工作,而且前端中的代码行数比我之前负责过的项目的整体业务代码还要多。后端里也运行着数以千计的服务,这些可怕的 API 服务器让我之前见识过的任何项目在体量上都相形见绌。而且这还只是一个 API 服务器,也就是大家熟悉的 LinkedIn.com 客户端。我们还有广告销售平台、LinkedIn Learning,等等。所以刚入职那段时间,我就是在从震惊到再一次震惊之间逐渐了解 LinkedIn 这家公司及其项目的庞大体量。


其实我之前工作过的公司已经有一款……至少在当时的我看来非常庞大的应用程序了,足足有 15 万行代码。但在看到 LinkedIn 前端的时候,它有 200 万行……几乎相当于我之前项目的 20 倍大小,新构建需要 17 分钟。


我所在的团队被称为基础设施团队,但这并不代表我们负责建立服务器,实际工作更接近工程支持或者说开发者体验。我的职责就是让 LinkedIn 的庞大桌面应用程序前端更易于使用。


每个季度,都有 150 到 200 名工程师要对应用程序提交更新,大家可以想象一下这是什么概念。将来的代码行越来越多,我们该怎么在这种横跨几十个团队、数百名工程师的情况下打造出真正有凝聚力的产品?


刚开始我实在有点不知所措。虽然如此巨大的项目本身就很酷,但我感觉无从下手。而且在这样的规模之下,一切技术债务和技术改进都将比无限放大——成功则是巨大的成功,失败也是巨大的失败。所以大家可以想见,对于 200 万行代码,任何小小的技术债在乘以这个数字后都将无比夸张。


维护大型遗留代码库的挑战


我在 LinkedIn 协助推进的第一个重大改变,就是引入了 JavaScript 类。JavaScript 本身已经引入了类,但当时他们使用的是 Ember 框架,而且需要对代码进行谨慎更新。


起初我们要做的就是在这 200 万行代码中改变类的编写方式,把原本直接将对象传递至函数,改变成使用 class foo 扩展子类 bar 或者超类 bar。


为了能在如此庞大的规模下完成迁移,整个过程必须尽量自动化,否则单靠人力永远做不完。毕竟手动重写 200 万行代码想想就令人胆寒,哪怕是昼夜不休的铁人,整个工程也需要连续几个月的时间。而且我们也不可能让产品团队放下手头的工作,全部跑去为原有 JS 代码添加漂亮的新语法。哪怕这能带来性能优势,哪怕能改善最终用户的体验,我们也得考虑实现成本的问题。


说起产品团队,虽然我们团队致力于改善开发者体验,但还需要其他团队的协助。也就是说无论怎样的优化和调整,我们首先得取得忙于交付功能的产品团队的认可。


LinkedIn 在这方面的流程其实还比较完善,随时随地都有某种程度的修改在进行当中。关于大规模技术投资的争论可以追溯到 2010 年代初,当时 LinkedIn 的整体架构已经达到了规模扩张的极限,因此不得不转向面向服务架构——也就是微服务架构的早期雏形。当时的用户规模还仅是目前的十分之一,产品团队几乎是整整停摆了一年,专门跑去研究架构转换。后来他们心有余悸地表示,永远不想再来一次了。确实,对于任何一家企业,把手头的工作放掉一年确实成本太高。


所以我们就建立起一套针对此类横向串连的制度,之所以强调横向,就是因为有些工作需要跨越大量团队,得逐一说服相关负责人才可能执行。还有专门的委员会负责对全公司的员工进行审查,确保大家都能保持一定的参与度水平。这些团队一般也就能承诺拿出 10% 的时间和精力来配合,所以哪怕我们的技术方案再先进、再精妙,产品团队也绝对不可能 100% 投入进来,再次放下手头的所有事务。


我们会尽量以自动化形式操作,在对方的代码库上运行和测试。我们会非常友善地跟对方沟通,比如询问对方能否理解添加后的输出结果、当前提案是否合适进行合并等等。总之,直接把结果递交给产品团队的负责人,肯定比要求对方替我们做测试和评估要简单得多。


我们整整花了 18 个月时间才完成 Ember 的替换工作。



其实大部分工作在六个月内就已经完成了,但这是那种典型的长尾项目,所以我们不得不一再推迟交付日期。期间由于 CEO 本人的否决,我们尝试推出新产品的提议没能通过,这也给另一个团队造成了不小的打击。毕竟在公司里,没人能跟 CEO 正面对抗。所以说技术主动性确实重要,但效果也着实有限,至少我们不可能光靠自己的道理就压倒 CEO 的判断。


问题太多,TypeScript 是救星吗?


跟大多数公司一样,LinkedIn 也有针对此类异常的错误日志记录。初创公司普遍会使用扫描工具来提取这些记录,但 LinkedIn 拥有自己的内部基础设施,毕竟我们的业务规模太大了,每个小时都会冒出大量错误。


其实我并没有讽刺 LinkedIn 的意思,而是在严肃认真地讨论这个问题。在认真观察软件之后,我发现 LinkedIn 的很多既有软件都很糟糕。而之所以会闹出问题,往往不是因为工程师们漠不关心,而是至少两种结构因素协同影响的结果。其一就是很多朋友都经历过的情况:我们的业务大船已经启航,这时候再想要调头就相当困难了。有些工程师总想把功能打磨再打磨,但实际上我们往往另无选择,时间到了就得把哪怕还不成熟的产品推向市场。


但这并不一定是坏事,毕竟灵活机动才是维持业务运转的诀窍。可质量上的妥协确实存在,再加上缺少足够强大的工程文化来消解,最终这种支离破碎感就开始体现在用户体验层面。虽然这在短期之内并不一定会拖垮 LinkedIn,但从长远来看必然有损公司的市场形象。


其二,哪怕我们已经尽了最大的努力,最终也仍有可能遇上各种稀奇古怪的代码问题。我们的冒烟测试可能发现不了问题,QA 也有可能无法察觉,但就是这个毫不起眼的隐患点没准会在用户数量突破十亿的瞬间突然爆发。


实际上在我离职的时候,LinkedIn 已经拥有十亿用户,而业务整体 repo 共有 320 万行代码——其中一半是测试代码,一半是生产代码。到了这个规模,无论我们在 QA 环节上付出多少努力,都不可能彻底消除隐患。总会有大家以为没问题、但实际有问题的部分,总会存在测试过程中意想不到的路径和组合在现实中引发故障。


所以最终肯定会有故障出现,也许是页面挂起,也许是界面白屏了,也可能是移动端应用重载。反正用户们已经习惯了,重启或者刷新一下就是。毕竟奇奇怪怪的状态 bug 总会出现,而先关闭再重新打开确实能解决很多问题。


但 JavaScript 引发的错误太多了,有些错误是无法捕捉的,我们只能尽力而为。在这个过程中,我们不禁思考如果用 TypeScript 结果会不会更好些。


TypeScript 很复杂,JavaScript 也很复杂,但我们至少可以搞清楚如果真的进行整体迁移,那些有多少种错误类别不会再出现在我们的日志当中?面对每天数以百万计的错误条目,我们也会将其转化为实际可操作的数字,比如思考能不能想办法把应用程序的日志记录量减少四分之一。


没错,能减少 25% 就算成功。实际比例可能更高,但低限就是四分之一。


TypeScript 曾有一句口号,“我们是可扩展的 JavaScript”。


面对这几百万行代码和所有这些错误,LinkedIn 很明显需要借助 TypeScript 的扩展性优势。


转向 TypeScript 的迁移计划


所以,我们开始提交申请,尝试转向 TypeScript。好消息是上头表示支持,同意以分步方式完成向 TypeScript 的迁移。之前已经有很多代码库完成了迁移。但坏消息是,产品团队能够承受的 10% 时间预算不足以全面完成这项工作,这是一项相当艰巨的任务。因此,我们跳过了横向串连,选择以自下而上的方式推动这场变革。


之前我曾制定过一项计划,让 LinkedIn 摆脱 Ember 并全面转向 React。事情一开始很顺利,但随着项目的推进,新的问题又来了。我们的高层领导表示 LinkedIn 的迁移成本太高。虽然我们聊了很多也做了很多,但现在的重点就是让基础设施团队尽一切办法降低迁移工作的成本。


总之成本还是太高,而这笔成本主要来自公司对于产品发布速度的高期待。


而在我们看来,产品发布速度的下降在很大程度恰恰源自这款应用程序中的 300 万行代码,它们已经使用了 7 年,其中积累了相当多的债务——技术债务和产品债务都有。


随着时间推移,产品的发布速度只会越来越慢,永远保持早期的快速发布几乎就不可能。哪怕只是一丁点调整,也可能给用户体验带来巨大破坏。也正因为如此,产品设计工作也变得困难重重,因为在这样的规模下,开发团队很难搞清哪些地方能改、如何适应原有产品。


但无论如何,领导层那边给出的指示就是尽可能降低迁移成本。所以问题就很明确了:想办法以低成本方式将 300 万行 Ember 代码转换成 React 代码。


既要开展大规模迁移,又要保证在迁移过程中不拖慢其他团队的开发速度。这确实是个大难题。


两个不同的重构计划


既需要大规模重写,又限于领导的这些条件,于是我们想到一种策略,应该能够满足领导层的要求,粗略估计大约需要三到五年时间,哪怕最乐观的情况也得三年时间。


我们的想法是在自动化方面多下功夫,尽可能减少需要由产品团队承担的工作。当时的思路是对具体工作进行排序,并多种方式将其拆分成块、按线索组合,这样就能一次解决一条线上的所有问题,然后再处理下一条线索。


另外还有些任务可以并行执行。对于那些没有明确排序、难以具体分块的工作,并行化能帮助我们高效调整构建管线、更改数据层、更改路由层、为响应式系统找到可操作的路由与视图层迁移路径,最后再把响应系统中的视图层从 Ember 迁出。


最后一步才是迁入 React,整个过程都靠编写的自动化工具实现。这就是我们的基本思路。如我所说,三到五年对应着巨大的工作量,但这能保证产品团队不会受到重大影响、至少不会像之前那样彻底停摆。

这是一项艰巨的任务,就像在汽车行驶过程中一点点更换零件、再造车体一样。尽管困难重重,但三到五年也确实能够做成很多事情。


与此同时,另一团队(我们称之为 Fingerguns 团队)出手了,当时他们也有一项计划,打算解决类似的问题,但思路不同。他们采用的是一种“重写移动和桌面应用程序”大爆炸式重写提案。


在我看来,双方最大的共识就是工程主管和高层团队都不希望迁移影响到产品发布速度。我们要如何更快地交付功能和思路?我们要如何快速迭代?我们该如何将想法快速转化成 A/B 测试?我们能不能把几个月的计划缩短到几个礼拜?毕竟在项目敲定的时候,时间已经过去几个月了。但他们也知道,我们的堆栈存在严重分裂:我们既掌握着庞大的桌面堆栈,也有截然不同的移动 Web 堆栈。我们的 iOS 和 Android 版应用更新周期很长。能不能让一切都运转得更快些?


回想起来,当初领导层一直提醒我们要注意迁移疲劳问题。但迁移疲劳只是表象,各方真正关心的还是能不能加快迭代速度、尝试新想法,并在想法不够好或者无法马上发挥作用时及时放弃。而迁移可能会阻碍这一切,毕竟他们的工程师往往需要把 10%、20% 甚至 25% 的时间和精力花费在迁移上,而不是他们最关心的功能迭代上。而我们提出的计划并没能解决这个最大的痛点。


所以,在这种形势下,另一个团队的表现在全 LinkedIn 之内引起了轰动。Finger Gun 模式就像是在用手势指挥和调度千军万马——不纠结于具体问题,单纯指引各方投入行动。


乍听之下我简直要气炸了,但我很快意识到,由于我们习惯于支持十几位工程师,所以并不清楚跟上百名、甚至是几千工程师打交道究竟是怎么一回事。我压根不觉得自己能够指挥全局,要求各团队放下手里的工作,重新开始参与到一个庞大的项目当中,再用这种方式满足各方对于速度的极致追求。


Finger Gun 团队的高级工程师 Jim 倒是非常乐观,他跟我在软件工程的理解方面甚至可以说是截然不同。而对于我提交的五年计划,领导们很不喜欢。这个计划表面是从 Ember 迁移至 React,但问题背后的核心在于应该如何改造一切,确保业务的运行速度能够加快、推动 LinkedIn 能够更快实施变革。而高管团队有需要达成的指标,他们面对市场压力,还要考虑微软那边的回报要求。


一次宕机事故,以及深层次的问题


随后一次圣诞假期,公司网站出了问题,LinkedIn 的大部分用户在长达 20 分钟的时间里无法正常访问内容,连 LinkedIn.com 的页面都刷不出来。在接下来的三个月中,我得持续跟进这项工作,搞清楚到底是哪里出了问题。


事故的原因是预渲染服务中的内存泄漏,再加上一个自动进程,该进程会在服务器使用内存过多时重启服务器。由于配置错误,导致过多的服务器同时重启,进而导致剩余的服务器也发生故障。


实际上我们设计了一套系统,提示内存用量已经超过上限,这时候重启设备就能解决问题。暂时算是应付过去了,但这并不是根本的解决办法。另外还有一项设置,决定我们同时最多能接受重启多少个容器。这项设置来自 YAML 配置文件中的一个键。不知道什么时候有人为其设置了相应的值,值本身倒是合法的,但对实际系统需求来讲可能设置不当。具体来讲,这个数值大约是正在运行的全部服务的总数。由于各服务的容器几乎同时启动,收到到的请求数量也大致相同,所以它们的内存占用量也基本上是在同步增长。


这种情况的发生频率开始上升,而且逐渐逼近用户和 LinkedIn 都无法接受的地步。刚开始只是某个长周末或者因特定原因引发的暂停,但最终这个配置错误到了临爆点上——于是所有服务器开始同时重启。结果大家可以想象,LinkedIn 的所有服务都不再响应用户们的请求。这是一种会迅速蔓延的问题,最终压垮了整个 LinkedIn 平台。


部分服务器离线会给其他设备增加压力,于是后者接收到的流量更大、内存使用量也随之增高。重启和负载转移反复进行,直到整个数据中心都离线了。在后台我们还有一个用于规模调整的进程,我们想的是应该尽量减少整个机群的 CPU 和内存使用量、避免过度配置。毕竟考虑到 LinkedIn 的设施基本盘那么大,应该能够周转得过来。但事实证明,这些预想相互交织最终酿成了大祸。规模调整降低了设施的容量上限,而内存泄漏又拉高了资源需求量,突然之间资源用量到突破了上限,只剩下我们一脸无奈。


当时我和一群工程师们站在机房里,说起我们需要更好的警报系统和更全面的可观察设置。当然,还有更强的设施弹性,毕竟节点服务器的离线不应该把管理该进程的主机进程也拖入崩溃。相反,我们应该针对此类警报终止节点进程并进行重启,这样我们就不需要关闭容器,从而彻底避免整体宕机的再次发生。


我从这次事故当中总结出了不少改进基础设施的经验:故障终究会出现,人类就是会犯错误。世上没有不中断的系统,也没有不崩溃的项目。这就是我对软件工程的看法。无论是编程失误还是黑客攻击,工程师们在设计自己的系统时不可能完美无瑕,我们交付的每款产品都或多或少存在缺陷。


而解决的关键就是建立起多层弹性,确保我们能够发现问题,以安全的方式修复错误,同时通过警报向管理员发出问题提示。


而 Finger Gun 模式下“重写移动和桌面应用程序”的方案解决不了这些问题,而且可能会重复同样的问题。他们承诺,虽然短期内会降低速度,但从长远来看会大大提高速度 。但关键的是,它并没有承诺改善代码质量或开发人员体验。我并不真正相信它会带来速度上的提升,也没办法修复了足够多的问题,让系统稳定下来。


但面对问题,上级领导想要的只是尽快让事情过去。这就再次回归了关于速度的争端,总之现在的例会氛围越来越紧张了。


谁该为问题负责?


我们的例会越来越多了,领导层总在询问项目状态如何、在哪些方面取得了进展。于是我们需要整理更多报告、告诉高管团队我们取得了哪些进展,还得及时反馈团队需要哪些帮助。


而 Finger Gun 团队的负责人接管了事件响应工作。他又拉来了一大堆新成员。这些都是出色的员工,但他们的介入其实反映出领导们的态度:我不相信你能解决这个问题,我也不相信你说出的答案,所以我叫来其他人取代你。


Finger Gun 团队的高级工程师 Jim 当时在电话会议上公开表面了这样的态度,随后情况开始一路走低。Jim 当时直接问:代码审查为什么没有发现问题?而我的回答是,就是没发现,而且以后也不可能发现。人就是种会犯错的生物,但他们会学着做得更好。更具体地讲,假设当时审查员刚好是位新手,而这条 PR 是由某位非常资深的 SRE(站点可靠性工程师)提交的,你猜会不会被快速通过?


审查员为什么要质疑这个值合不合理?很多东西看起来就是合理的,只有在极端条件下运行时才会出问题。所以对于任何一套工程系统,我们真正能够把握的就是它当下能不能运转、其中的进程能不能运转、特定的工具能不能运转。无论是高级工程师,还是刚刚入职的技术新人,他们的心情都会有高潮、有低谷,所以对于他们编写的成果最合理的预期,也就是当下能够运转。


工作仍在推进,但压力却越来越大。Finger Gun 小组根本就不清楚问题的范围,只会问,“那为什么这个问题还没有解决?”“高管们对目前的进展速度不满意。”


当然不可能满意了,因为你们已经积累了整整七年的技术债和弹性缺失,而我们正在努力修复。换句话说,我们需要在三个月之内弥补七年来的疏漏。这样的进展已经相当不错了,至少我自己这么认为。我记得我还跟自己的前上司强调过,这应该是我这辈子参与过的最疯狂的项目。当时 Finger Gun 经理进来说我的工作做得不够好,因为修复的速度不符合领导的预期。那一刻我感觉他们对于这种规模的工程项目缺乏敬畏,意识不到其中的问题有多难解决。


我们有无穷无尽的内存漏洞问题需要修复,而这种特定内存泄漏的根源,就在于它们都在引用同一个核心对象。所以哪怕是修复了其中一个,也无法改变系统的整体行为。这种感觉太难受了。


而且我们还同时启动了替代实验,大家尝试之后觉得效果不错,应该可以解决问题。可那帮工程师就像听不懂人话一样,只会反问“那又怎样?”


团队重组:输在了人际关系上?


大约就在同一时间,他的团队通过重组恶意兼并了我的团队。他成了我上司的上司。这样倒好,如果他是我的直属经理,我很可能会当场辞职。


现在想想,人就是在不同的位置上学到各种新东西的。


有篇文章提到,“在高级工程或者经理层级上,根本就不存在纯粹的行政或者技术问题,一切都是行政与技术的杂糅。”


是的,一切都是行政与技术的杂糅,而我们需要确定其中的边界在哪里。到底偏向行政方面,还是技术方面,或者是二者特定比例的结合?我到底该做什么来解决这个问题?


Finger Gun 的计划开始取得进展、吸引关注,而且范围仍在不断扩大。当前的工作就是重写移动端和桌面端应用程序。“我们打算重新考虑 LinkedIn 的产品构建方式”,这无疑令人兴奋。而且必须承认一点,就是在面对相同问题时,我和我的团队输了,Finger Gun 团队那边赢了。


但我愿意接受这样的现实。毕竟我确实没能说服领导层,对方甚至没有耐心认真听我做的讲述。或者说,除了我对项目本身表现出的热情之外,他们根本不知道我在说些什么。我想让 LinkedIn 再次伟大———这个很好;但我们需要解决这些问题才能实现——哦,你不想听……


在跟经理的沟通中,他曾提醒我“你太理想主义了,你对业务不够关注,最好能调整一下价值观。”当时我完全无法理解,因为你说的都是社交、都是行政,但我聊的可是纯技术。


可现在我理解了,因为我开始明白对方的立场。每个职位都有不同的立场,出发点上的差异决定了大家不可能处在同一频道。


这活儿干不下去了,我辞职了


我们在代码库里遇到的很多问题,都源自对速度的过度强调。因此哪怕发现了问题,出于对影响进度的担忧,管理层都会把压力传递给工程部门。而我们面前就只有两个选项:要么想办法修复,要么直接跳过。

这两种都可以,但管理者压根不想做选择,他们只想知道下一项功能什么时候能发布、还能不能再快一点。当速度成为压倒其他一切的核心驱动因素和价值取向时,我们就必然陷入这样的境地:刚开始项目推进速度很快,但越往后越维持不住,最终陷入债务的泥潭。


实际上,这在拥有漫长历史的代码库来说是种常见的通病。很多管理者只知道不断扩展资产,但却不重视投入和改进,于是最终一切只会回到原点。我看到的很多申报内容都在强调如何尽可能提高速度,但却没有对遗留的问题做出解释,甚至不提后续该如何收拾残局。


而我一直在思考这些问题,想要尽量以平和的方式陈述这么干可能引发的后果。虽然期间也发现过一些有趣的技术方向,但我最终还是感到身心俱疲,并决定辞去这份工作。总之在那段时间,我开始出现偏头痛和严重的胃痛,没办法正常运动,随时情绪崩溃并陷入恐慌。那些日子真的太可怕了。


其实我很清楚如果坚守在 LinkedIn,接下来的情况会如何发展。我要么留在那个随时可能给我的精神施以沉重一击的环境,要么就彻底摆烂,像具行尸走肉般按照上级下达的指示做事。前者可能摧毁我的身心,后者则会让工作变得枯燥乏味、毫无乐趣可言。


按前面那种方式,我当然可以试着用自己的小桨划水,让这艘泰坦尼克号改变航向。但这几乎不可能成功,奋力抗争之下只会闹得自己遍体鳞伤。


如果是后一种,那我埋头划船就好,根本不用考虑这艘巨轮是不是正驶向冰山。那座冰山就是规模扩展,这是 LinkedIn 终将面对的难题,而公司的基础设施根本就没有为此做好准备。


我最终选择了放弃。


这段经历让我学到了很多,至少让我了解到为一家科技大厂工作,尝试把 300 万行代码迁移至 TypeScript 到底是怎么回事。现在我可以转去做点别的事情,保存自己的精力或者说生命力。至少这样我用不着每天压抑自己的情绪,或者随时随地陷入崩溃。


人的一生如白驹过隙,我不想把宝贵的几年时间浪费在自己根本不认同的工作方式上。请大家千万不要误会,我的离开不是出于怨恨、恶意或者其他负面原因,单纯是因为大家对人生的理解有所不同。


也许 LinkedIn 的某些角落还残存着我所认同的、不那么让人反感的价值观,但很遗憾那并不是主流,我也无力改变。


参考链接:

https://devclass.com/2024/03/06/modernizing-legacy-code-at-linkedin-how-big-bang-versus-gradual-approach-caused-conflict/

https://corecursive.com/leaving-linkedin-with-chris-krycho/

https://www.youtube.com/watch?v=UOw7TydAT_s

https://www.reddit.com/r/programming/comments/1b69ntl/leaving_linkedin_choosing_engineering_excellence/


声明:本文为 InfoQ 翻译整理,未经许可禁止转载。

2024-04-09 18:175993

评论

发布
暂无评论

Orillusion引擎开源一周,荣登Github Trending榜单

Orillusion

开源 3D 渲染引擎 元宇宙 #WebGPU

Prompt工程师指南[从基础到进阶篇]:用于开发和优化提示,以有效地使用语言模型(LMs)进行各种应用和研究主题

汀丶人工智能

人工智能 自然语言处理 ChatGPT prompt learning

AI DevOps | ChatGPT 与研发效能、效率提升(中)

laofo

DevOps 研发效能 ChatGPT

Unity3D 对接 workerman 实现联机游戏

北桥苏

php socket Gateway Unity3D workerman

Tensorflow.js 多分类,机器学习区分企鹅种类

北桥苏

JavaScript 深度学习 tensorflow

2023大厂Java面试题汇总,作为 Java 程序员必须要掌握的技术栈

采菊东篱下

java面试

ui设计软件Sketch 96.3中文激活版~ 支持m1

真大的脸盆

Mac ui设计 矢量设计

workerman 自定义的协议如何解决粘包拆包

北桥苏

php Unity3D workerman GatewayWorker

KubeCon EU 2023 落幕,哪些技术趋势值得关注?

SEAL安全

云原生 KubeCON FinOps 平台工程

用 Tensorflow.js 做了一个动漫分类的功能(一)

北桥苏

JavaScript tensorflow

Prompt learning 教学[最终篇]:Chatgpt使用场景推荐、优秀学习资料推荐、AI工具推荐

汀丶人工智能

人工智能 自然语言处理 ChatGPT 人工智能ChatGPT 吗? prompt learning

Nacos必知必会:这些知识点你一定要掌握!

王中阳Go

Go 微服务 nacos 服务治理 配置管理

MySql 索引的失效与优化

Andy

聊一聊模板方法模式

设计模式 模板方法模式

用友BIP成功入围工信部《2022年信息技术应用创新解决方案》

用友BIP

C语言编程-程序结构

智趣匠

C语言 结构 三周年连更

Zabbix电话短信报警技巧

外滩运维专家

zabbix电话报警 zabbix短信报警 zabbix飞书报警 zabbix钉钉报警 zabbix微信报警

Java Web实战 | 设计一个监听器

TiAmo

JDBC 事件监听 监听

CSS小技巧之圆形虚线边框

南城FE

CSS css3 前端开发

你管这破玩意叫缓存穿透?还是缓存击穿?

Java你猿哥

redis 缓存 缓存穿透 缓存击穿 缓存雪崩

从原理到实战,手把手教你在项目中使用RabbitMQ

Java你猿哥

Java ssm RabbitMQ 消息队列 RabbitMQ延时队列

史上最全Java面试八股文,整整1658页!带你轻松应对各种面试题

架构师之道

Java 面试

探索将大语言模型用作推荐系统

Baihai IDP

人工智能 推荐系统 企业号 5 月 PK 榜 大语言模型 LLMs

Java面试通关:阿里内部实战模拟面试精讲题库,竟被上传GitHub!

Java你猿哥

Java redis JVM java面试 Java基础知识点

如何使用Go语言实现LSP原则

Jack

杭钢集团:以用友iuap为数智底座的数智化转型之路

用友BIP

Tensorflow.js 对视频 / 直播人脸检测和特征点收集

北桥苏

JavaScript tensorflow

Django笔记二十八之数据库查询优化汇总

Hunter熊

Python django 查询优化

Nautilus Chain 或成未来最好的链上隐私生态

西柚子

实力入选!赛格导航荣获“深圳知名品牌”

科技热闻

Tensorflow.js 视频图片多目标检测

北桥苏

JavaScript 深度学习 tensorflow

这活儿干不下去了:十几年积累的 300 万行代码,领导要全部“快速”重写,我直接辞职了_工程化_核子可乐_InfoQ精选文章