真正的成长,往往藏在那些让我们受挫的时刻里。
引子:当"专业主义"成为阻碍
最近在公司 iOS 项目中的两次经历,让我开始重新思考一个问题:作为开发者,我们到底在追求什么?
是展示自己能够攻克任何技术难题的能力?还是高效地为产品和用户创造价值?
是证明自己写的每一行代码都经得起推敲?还是建立能够持续交付高质量软件的体系?
这不是一个简单的选择题,而是关乎我们如何理解"专业"这个词的本质。
第一面镜子:当"坚持"变成了"执念"
一个看似简单的问题
我们的 iOS APP 需要升级合作方提供的视频时间轴组件。作为项目中的一员,我理所当然地承担起这个任务。新组件集成后频繁报错,我的第一反应是:这是一个技术挑战,我必须攻克它。
我花了大约半天时间深入研究错误堆栈,尝试各种修复方案。但问题就像打地鼠游戏,按下一个,另一个又冒出来。
一段时间后,我把这个任务交给了同事。他多番尝试之后采用了一个让我感到有些意外的方法:直接用AI把Android端运行良好的代码翻译成iOS代码。
结果不到一天,这个问题就解决了。
被击碎的"专业主义"假象
这个结果让我陷入了深深的反思。我意识到自己陷入了一个**"专业主义陷阱"**。
在我的潜意识里,"真正专业的开发者"应该是这样的:
-
必须理解每一行代码的底层原理
-
必须能够独立解决任何技术难题
-
必须从根源上修复问题,而不是"绕过"它
但这种思维忽略了一个根本问题:软件开发的目标不是展示技术能力,而是创造价值。
当我执着于"必须修好这段报错的代码"时,我实际上是在为自己的自尊心服务,而不是在为项目和团队服务。我把"解决问题的方式"看得比"解决问题"本身更重要。
更深层的洞见:关于"重写"的哲学
同事的方案表面上是"用AI翻译代码",但本质上是一种**"参考成熟方案重新实现"**的思路。这背后有几个值得深思的点:
1. 承认不确定性的勇气
在软件开发中,我们经常面临"已知的未知"(我知道我不知道这个bug的根源)和"未知的未知"(我不知道修复这个bug会带来什么连锁反应)。
坚持修复一个不熟悉的第三方组件,本质上是在和"未知的未知"搏斗。而参考已经验证过的实现方案,是在用"已知的已知"来降低风险。
承认"我无法掌控所有变量",选择风险更低的路径,这不是能力不足,而是成熟的工程判断。
2. 对"原创性"的重新理解
我们的教育和文化中,"原创"往往被视为最高价值。但在工程领域,"不重复造轮子"才是智慧。
软件开发不是艺术创作,不需要每个方案都独一无二。如果有成熟的、经过验证的解决方案,借鉴它、改造它、适配它,这才是高效的工程实践。
真正的原创性,应该体现在业务创新和用户体验上,而不是在底层技术实现上标新立异。
3. 工具理性与目的理性的平衡
德国社会学家韦伯提出了"工具理性"和"目的理性"的概念。
-
工具理性:关注手段本身的正确性(我必须用"正确"的方式修复这个bug)
-
目的理性:关注目标的达成(我需要让这个功能正常工作)
我之前陷入的,正是过度的工具理性。我太在意"怎么做",而忽略了"为什么做"。
优秀的工程师,应该懂得根据情境在两者之间切换。 对于核心业务逻辑,我们需要工具理性------每一行代码都要理解透彻。但对于工具性的、非核心的功能,目的理性更重要------快速、可靠地解决问题。
4. AI时代的协作本质
使用AI翻译代码,表面上看是人机协作,实质上是一种**"跨时空的团队协作"**。
Android端的同事已经趟过了这条路,验证了方案的可行性。AI工具只是一个桥梁,让我们能够跨越语言和平台的障碍,复用这份集体智慧。
这让我想到开源社区的本质:我们站在前人的肩膀上,不是因为我们不够高,而是因为这样我们能看得更远。
关键反思:效率的三个层次
这个案例让我重新理解了"效率"这个词:
第一层:操作效率 ------ 写代码的速度、调试的速度 第二层:决策效率 ------ 选择正确方法的速度、止损的速度 第三层:系统效率 ------ 团队协作的效率、知识复用的效率
我之前只关注第一层,但真正拉开差距的是第二层和第三层。
第二面镜子:质量控制中的"能见度"问题
两次侥幸逃过的灾难
上周修复bug的过程中,我两次修改代码后引入了新问题,都是在发布前的最后一轮测试中被发现的。如果流到用户手里,后果不堪设想。
事后我一直在思考:这是我个人的粗心,还是流程的问题?
经过深入反思,我发现问题远比表面上看到的复杂。这不仅仅是"粗心"或"流程不完善",而是一个更深层的认知问题。
洞见一:复杂系统中的"能见度陷阱"
在修复bug时,我的注意力完全聚焦在要解决的问题上。这种聚焦本身没有错,但它带来了一个副作用:其他相关区域从我的视野中消失了。
这让我想起飞行员训练中的一个概念:"可控飞行撞地"(CFIT)。飞行员过度专注于某个仪表或操作,忽略了高度表,结果在能见度良好的情况下撞山。
软件开发中也存在同样的现象:我们对正在修改的代码有很高的"能见度",但对代码的依赖网络、调用关系、副作用,却处于"低能见度"状态。
这不是粗心,而是认知带宽的有限性。人脑在高度专注时,会自动过滤掉"不相关"的信息。问题是,什么是"相关",什么是"不相关",我们的直觉判断往往是错误的。
洞见二:从"点状思维"到"网络思维"
传统的编程教育教会我们"模块化思维"------把大问题拆解成小问题,一个个解决。这种思维在处理简单问题时非常有效,但在处理复杂系统时会产生盲区。
现代软件系统不是一棵树(树状结构,依赖关系清晰),而是一张网(网状结构,牵一发而动全身)。
当我修改一个函数时,我看到的是:
-
这个函数的输入输出
-
这个函数内部的逻辑
-
这个函数直接调用的其他函数
但我看不到的是:
-
谁在调用这个函数?在什么场景下调用?
-
这个函数的副作用是什么?
-
这个函数失败时会影响什么?
-
调用方对这个函数的假设是什么?
这些"看不到"的部分,才是引入新bug的真正来源。
洞见三:测试的本质是"假设验证"
我之前理解的测试是:验证功能是否正常工作。
但这次事件让我意识到,测试的本质是:验证我们对系统行为的假设是否正确。
每次修改代码,我们实际上是在做出一系列假设:
-
"这个修改只会影响A功能"(假设)
-
"其他地方不会受影响"(假设)
-
"这个参数在所有场景下都是可用的"(假设)
如果这些假设是错的,就会引入新bug。
好的测试流程,应该帮助我们显式地列出这些假设,然后逐一验证。 而不是只测试"修复的bug是否被修复"。
洞见四:个人责任与系统韧性的辩证关系
有一种观点认为:如果每个开发者都足够谨慎,就不会有质量问题。
这种观点把质量保证完全寄托在"人不犯错"上,这在理论上正确,但在实践中不可行。
人是会犯错的,这是人性的一部分。 期待每个人在每个时刻都保持完美状态,是对人性的误解。
真正有效的质量保障体系,应该建立在**"假设人会犯错"**的基础上,通过流程、工具、协作来构建"韧性"(resilience)。
这种韧性包括:
-
早期发现:在问题影响更小的时候发现它(如自动化测试)
-
损害控制:限制错误的影响范围(如灰度发布)
-
快速恢复:出问题后能迅速回滚和修复(如完善的监控和CI/CD)
从"追求零错误"到"建立容错能力",这是质量管理的范式转变。
洞见五:知识的"显性化"与"可传递性"
我引入新bug的一个重要原因是:很多关于代码依赖关系的知识,只存在于某些人的大脑中,没有被显性化。
比如,某个函数在特定场景下会被多处调用,但这个知识散落在不同同事的经验里。没有人系统地记录过这些"隐性知识"。
软件团队的知识管理,不仅仅是写文档,更重要的是建立"知识的可发现性"。
这包括:
-
清晰的代码注释(不是说明"做了什么",而是说明"为什么这样做")
-
完善的架构文档(不仅说明"是什么",还要说明"哪些地方容易出错")
-
定期的知识分享(把踩过的坑、容易忽略的点传递给团队)
当知识从个人大脑转移到团队的"集体记忆"中,整个团队的抗风险能力就会提升。
两面镜子的交汇:专业主义的新定义
这两个案例,一个关于效率,一个关于质量,看似矛盾,实则统一。它们都在挑战我对"专业主义"的理解。
旧的专业主义:个人英雄主义
-
能独立解决任何技术难题
-
写的代码从不出bug
-
精通所有技术细节
-
不需要依赖工具和他人
新的专业主义:系统思维与协作能力
-
目标导向:知道何时该深挖,何时该换思路
-
承认局限:接受个人能力的边界,懂得寻求协助
-
系统思考:理解局部修改对整体的影响
-
知识管理:将个人经验转化为团队资产
-
流程意识:建立能够容错的工作体系
-
持续学习:从失败中总结,从成功中反思
给自己和团队的行动建议
基于这些深度思考,我提出以下实践建议:
个人层面:建立"三问"机制
每次动手解决问题前,先问自己三个问题:
第一问:目标是什么? 我是要证明自己的能力,还是要解决业务问题?如果是后者,什么方案最快最可靠?
第二问:影响是什么? 这次修改的"爆炸半径"有多大?哪些地方可能受影响?我如何验证这些假设?
第三问:我不知道什么? 我对这个问题的理解有哪些盲区?谁可能知道我不知道的东西?
团队层面:从"责任制"到"支持系统"
1. 建立"安全失败"的文化
允许犯错,但要求从错误中学习。每次问题后,不是追究"谁的责任",而是讨论"我们的系统如何能更早发现这个问题"。
2. 强化知识的显性化
-
重要决策要留下书面记录(为什么这样做,考虑了哪些因素)
-
代码中的"坑"要有清晰的注释
-
定期举办"踩坑分享会"
3. 多层次的质量保障
-
个人自测:开发者的第一道防线
-
自动化测试:快速反馈的机器防线
-
Code Review:集体智慧的人工防线
-
专业测试:系统性验证的专业防线
-
灰度发布:真实环境的最后防线
4. 鼓励"方法多样性"
不要只鼓励"正统"的解决方案。如果AI辅助、参考其他平台、使用现成工具能更好地解决问题,那就是好方法。
评价标准应该是"是否有效解决了问题",而不是"是否符合某种理想化的技术路线"。
结语:专业的本质是服务价值
回到开篇的问题:作为开发者,我们到底在追求什么?
我现在的答案是:我们追求的是持续、稳定地为产品和用户创造价值的能力。
技术能力是手段,不是目的。 代码完美是追求,不是执念。 个人成长是过程,不是终点。
真正的专业主义,不是展示自己无所不能,而是:
-
知道在什么情况下应该深挖到底
-
知道在什么情况下应该换个思路
-
知道如何建立能够持续产出高质量成果的系统
-
知道如何与团队协作,放大集体的力量
软件开发是一场马拉松,不是百米冲刺。 我们需要的不是在某一刻爆发惊人的能力,而是建立一套可持续的、可靠的工作方式。
这两次经历,就像两面镜子,让我看到了自己的局限和成长空间。感谢这些"踩坑"的时刻,它们才是真正让我们进步的契机。
最后一个思考题留给读者:
在你的开发经历中,有没有遇到过类似的情况?是什么让你重新思考"专业"的定义?欢迎在评论区分享你的故事和思考。
成长不是避免犯错,而是从每次错误中收获洞见。