软件开发中的“司机式”知识:当开发者听起来很聪明却缺乏深刻理解
Source: Dev.to
我们都曾是那种在会议上自信地抛出 “事件驱动架构” 或 “CQRS 模式” 之类术语,却暗自希望没人让我们解释这些到底是什么意思的开发者。我也不例外。
司机的故事
一位著名科学家有一位司机,负责把他送到全国各地的演讲现场。经过数月反复听同一场演讲,司机把演讲稿逐字背了下来。一天他开玩笑说:“我自己也能来讲这场演讲!”科学家觉得有趣,就让他试一试。
司机完美呈现,掌声雷动。
然后有人提出了后续问题。
司机僵住了。
这就是我们在软件开发中所说的 “司机知识”——它无处不在。
你认识这样的人。也许你曾是这样的人。
“我们需要 微服务!事件溯源!Kubernetes!”
“为什么?”
“因为……那是成功公司在用的?”
为什么“酷”词汇可能是陷阱
- Netflix 使用微服务,因为他们有数百名开发者和数百万用户。
- 您的内部工具只有 三名开发者 和 200 名用户。
- 您可能需要一个 组织良好的单体应用,而不是分布式的噩梦。
但 “微服务” 在 LinkedIn 个人资料上听起来更酷。
Source: …
实际案例
我曾与一位能够构建精美 React 应用的开发者合作——真的非常令人印象深刻。但我们的 Node.js 后端开始随机卡死。
"It's probably the async calls," I suggested.
Blank stare.
"How do promises work?" I asked.
More blank stares.
他们已经构建了两年的异步应用,却不明白 async 实际意味着什么。框架隐藏了所有复杂性——直到它不再隐藏。
“复制粘贴”循环
- 生产环境崩溃。
- 你在 Google 上搜索错误,找到 Stack Overflow 的答案,复制‑粘贴解决方案,推送到生产环境。
- 它起作用了!发布吧!
- 三个月后,同样的 bug 在不同的条件下再次出现。
- 团队中没有人明白最初的修复为何会起作用。
- 再次回到 Stack Overflow 寻找补丁。
这就是 legacy codebases 诞生的方式。
“Uber” 心态
“让我们像 Uber 那样构建我们的系统吧!”
“我们有 Uber 那样的问题吗?”
“嗯…没有。我们最多只有 10 个并发用户。”
“我们有 Uber 那样的工程团队吗?”
“没有,只有我们三个人。”
“那为什么——”
“因为这是最佳实践。”
我们喜欢盲目复制大公司的做法,而不去问自己是否真的需要。就像买一辆半挂卡车,却只需要搬一张沙发。
为什么会这样
- 变化的速度 – 上周的热门框架是这周的遗留代码。我们记忆而不是理解。
- 冒名顶替综合症 – 其他人似乎全都懂,于是我们用复杂的词汇装作懂。
- 面试压力 – “在白板上翻转二叉树”考的是记忆,而不是理解。
- 残酷的截止日期 – “这为什么有效?”需要我们没有的时间。“它有效吗?”是明天要发布时唯一重要的。
- 工具优先思维 – 编程训练营在第三周就教 React。没有人教浏览器到底是怎么工作的。
我懂的。我也经历过。我们都经历过。
痛苦的后果
- 凌晨 3 点的生产事故 – 你复制的解决方案崩溃了。你根本不知道原因。曾经帮你解决问题的 Stack Overflow 回答现在也帮不上忙。
- 性能灾难 – 你被要求使用的 ORM 最终导致 每次页面加载 1,000 次数据库调用。你不知道 ORM 会这么做,因为你从未学过 SQL。
- 过度设计的混乱 – 八个微服务相互通信,部署需要三个小时,调试必须检查多个系统的日志。你们三人的团队花在 DevOps 上的时间比在功能开发上还多。
- 安全漏洞 – 你在不了解 token 的情况下复制了一个认证模式。你的应用已经泄露用户会话长达六个月。
这些并非假设,它们每天都在发生。
在实现任何东西之前,请暂停并思考
- 这个解决方案存在的原因是什么?
- 它在解决什么问题?
- 有哪些替代方案?
- 如果我弄错了,会导致什么出错?
如果你无法回答这些问题,你可能正处于 chauffeur mode。
基础优先于框架
学习 HTTP 基础可能没有学习最新的 JavaScript 框架那么吸引人,但 框架会变,基础不会变。
- 数据库 – 了解它们的实际工作原理。
- 网络 – 理解 OSI 模型、TCP/IP、延迟。
- 内存 – 知道垃圾回收和内存分配如何影响性能。
这些知识会相互叠加。每当你使用新工具时,因为已经掌握了其底层原理,学习起来会更轻松。
实践练习
- Express – 使用原始的 Node.js
http处理程序构建一个 Web 服务器。 - Redux – 从零实现一个简单的状态管理。
- Authentication – 自己动手编写一个基本的 JWT 生成器/验证器。
你会更加欣赏框架为你做了什么,同时也能在它们出现问题时快速定位并修复。
拥抱 “我不知道”
在下次会议中,当有人询问你不懂的事情时,试着说:
“我不知道。能解释一下吗?”
房间里有一半的人也不知道;他们只是更善于隐藏。
优秀的团队 奖励好奇心 而非虚假的自信。如果你的团队惩罚“我不知道”,那你就在错误的团队里。
教会学习
- 依赖注入? 试着向初级开发者解释它。
- 不能不敷衍解释吗? 说明你还没有真正理解它。
教学会迫使你组织思路,寻找简单的例子,并回答意想不到的问题。这是发现知识盲点的最快方式。
结束语
我写这篇文章是因为我需要阅读它。
上个月,我在代码审查中自信地推荐了一种缓存策略。有人让我 e…
(故事还在继续,但重点很明确:保持质疑,保持学习,别再假装自己掌握所有答案。)
解释驱逐策略
我……做不到。
我读过相关内容。我用过它。我会拼写 “LRU cache”。但我实际上并不理解它是如何工作的。
我一直在当司机。
于是我闭嘴,回去真正学会了它,然后再回到讨论中。这让我感到谦卑,也很必要。
你不需要从第一原理去理解所有东西。那是不可能的。
关键是要认识到自己是在使用 chauffeur 知识 还是 真正的理解——并且诚实地面对自己拥有的是哪一种。
- 有时 chauffeur 知识也没问题。如果你在快速原型开发,直接复制 Stack Overflow 上的解决方案。交付它。以后再学习。
- 但当你在构建重要的东西——人们依赖的、需要扩展的、你将维护多年的系统时,就需要放慢脚步,真正理解自己在做什么。
如果你读到这里并想,“天哪,这就是我”——很好。这说明你有足够的自我意识去采取行动。
我合作过的最差的开发者并不是拥有 chauffeur 知识的那类,而是那些拒绝承认自己只懂表面的人。
我合作过的最好的开发者呢?他们经常说 “我不知道”。然后去学习,回来后教会我们其他人。
做第二种人。
P.S. – 如果你在阅读时想 “我应该把这条发到 Slack”,但担心团队会觉得你在点名批评… 那是想太多了。直接分享吧。最需要这条信息的开发者可能并未意识到这与他们有关。已经意识到的,早就在行动了。