Skip to content

DRAFT 毕业六年,我对软件开发理解的变化

约 3042 字大约 10 分钟

2025-06-02

前言

六年前,当我通过校招拿到offer,即将进入企业“真刀实枪”地对自己学生时代掌握的软件开发技能实践一番时,我也曾幻想过所谓“企业级项目”会有多么先进和高级。

当时 SpringBoot 刚火不久,SpringCloud 还是非常新鲜而与时俱进的技术,在去公司报道的前一天晚上,我还在因为我没有掌握 SpringCloud 里面的部分概念而担心自己会不会无法胜任工作。然而,这种担心完全是多余的。因为事实完全与我想象的相反,这里不但没有最前沿的技术,还充斥着各种因历史原因而堆积成的“屎山代码”(有技术上的,也有业务上的)。我看到的,不是什么厉害的黑科技,而是连大学课堂都早已不教的古董玩意儿(是的,这里面竟然还有 JSP 和 Java 6)。

就在我准备提桶跑路的时候,我想既然来都来了,不妨再待待看,因为我发现这里的项目虽然技术栈落后,但却能活过五年甚至十年。我想这里面一定有它的过人之处,于是我选择了留下来探究一番,看看有什么玄机,没曾想,这一待,就是六年。

六年过去,当然,当年那些老旧的技术框架,都已被我们逐步替换成了更新的技术,但距离业界前沿,也始终审慎地保持着几年的距离。

回顾这六年的工程实践历程,我发现自己对软件开发的理解跟大学刚毕业时有了很大变化,这一篇就来讲讲我当下的理解。

稳定才是硬道理

企业项目的最终目的是帮企业赚钱,并且是稳定持续地赚钱。

多年后,我终于意识到,当初这些令我震惊的维护了十年以上的古董项目,其真正过人之处不在于技术,而在于从当年随着经济腾飞而一路高歌猛进的业务增长当中。只要业务是持续赚钱的,那老板们唯一的希望就是不要在系统上出现差错,“稳定才是硬道理”。

刚毕业的年轻人经常陷入“唯技术至上”的误区中,常有如“我要用最牛逼的技术来重构这堆破烂”这样比较中二的幻想。然而,重构除了带来风险和意外之外,并无太多收益。当然,我并不是反对重构,而是反对在项目正在快速迭代且最赚钱的时候随便乱动,反对没有计划拍脑袋式地所谓“随手优化”。

除非是到了不得不动刀子的时候(比如旧技术无法满足业务、性能、安全等方面的要求,或者是老板哪天突然灵光一现),否则不要轻举妄动。

一个值得我们思考的问题是,最好的重构就是不要重构。在项目初期,就应该保持良好的编程习惯,减少未来重构的频次,如果我们的项目有良好的可维护性,那么就能减少很多不必要的重构。但是现实情况是,多数项目我们几乎都是中途接手,在此之前就已经是“屎山代码”了,很多人干脆放弃治疗,继续堆料,导致恶性循环。

不要小看这件事带来的负面影响,这不仅仅是使项目变得难以维护,增加重构成本的问题,更重要的是,它带来开发团队整体素质的降低,有品位的人一旦受不了会选择离开,而留下来的都是觉得无所谓的成员,长此以往,埋坑暴雷只是时间问题。

那如何权衡技术追求和业务稳定呢?我们在实践中探索的一个可行方案是:在增量迭代的过程中,采用抽丝剥茧的方式逐步将老古董替换为新技术,而不是一上来就把汽车引擎替换成飞机发动机。

而如何说服老板们,让他们认为这是一件必要值得付出的事,是令无论国内国外的工程师们都头疼了几十年的问题。或许这时候我们可以借鉴伟人的思想,大声喊出:“为了稳定而不稳定,是软件开发在发展过程中所不可避免的”。

之后,是得到老板的赞许还是铁拳,就看你的造化了。

一成不变的东西是没有的……为了进攻而防御,为了前进而后退,为了向正面而向侧面,为了走直路而走弯路,是许多事物在发展过程中所不可避免的现象。

—— 《毛泽东选集·卷I》(中国革命战争的战略问题(1936年12月))

安全第一

许多开源项目的缺点是只管功能实现,而不顾软件的安全性,导致漏洞频出,坑坏了众多使用者,例如我曾经每个月都要为某个JSON序列化开源组件打升级补丁。但还好它们是开源项目,尚能被及时报告并修复,而企业内部项目就很难说了。

软件开发,特别是企业软件开发,安全应该放在第一位。所有开发者都要学会防御性编程,不仅要防错误输入,边界条件,更重要的是防恶意输入

我曾经在我任职的部门中担任过一年的“安全责任人”,统筹所有系统的信息安全事项,当时见识过各式各样的软件漏洞,也相对全面地了解过公司、监管部门等相关的信息安全要求。可以说,现在绝大多数的软件开发从业者,对信息安全的意识还十分薄弱。中大型公司还有专门的信息安全团队在帮你挡刀,对于一般的企业、个人项目、开源项目,更多时候只能依赖开发者的个人意识了。

作为软件开发从业者,平时多了解信息安全知识、熟悉各种常见漏洞和规避方法、研发流程中“左移”安全测试,都是一节又一节的必修课。这一点可以参考我之前写的 数说安全开发 一文。

要不要尝试前沿技术

我绝对是“改革创新派”。

我始终觉得,学习和探索前沿技术,始终保持对技术最纯粹的热爱是我们技术人基本的素养。

确实,前沿技术带来了效率的革新,性能的提升,好处颇多,但是它唯一的问题在于还没有被业界充分地验证,代价是潜在的不稳定因素。例如,应该还没有哪个公司敢在核心业务系统中使用 java 21 的虚拟线程吧,也没有哪个公司敢把重要生产系统100%使用AI编程,没有人知道使用了之后可能会出现什么问题。

因此,不建议在关键业务系统中使用最前沿技术,但是鼓励可以在非关键系统中去尝试,作为技术储备,一旦时机成熟,就可以快速大规模推广,这不KPI就来了嘛。

当然,那些至今不敢在生产系统中使用如 Java 8 的 lambda表达式、函数式编程的“固步自封派”,是要坚决抵制的。

不要炫技

除非你正在开发一个对性能要求极高的软件,必须在编程中用各种“奇技淫巧”来提高一丝丝性能,否则强烈不建议写极致而难以读懂的代码,这将带来维护性灾难。

如果必须使用“奇技淫巧”,则请务必写清楚注释,写明这块代码的故事,为什么这样做,你 trade-off 过程的思考。几年后,会有人感谢你的,那个人也许就是你自己。是的,我经常感谢三年前的自己,尽管当年我并不知道自己要维护一个项目长达五年。

程序写出来是给人看的,附带能在机器上运行。

——《计算机程序的结构与解释》

业务理解 > 沉迷技术

你要解决一个什么样的问题,你对这个事情怎么理解,决定了你会写出什么样的代码。例如,如果你对利率、收益率、年化、等额本金、等额本息这些概念一无所知,那你就写不出一个“贷款计算器”小程序。

部分程序员常常以钻研过 Spring Framework 等源码为荣,对技术实现细节了如指掌,但却从来不过问它们为什么这么设计?是为了解决什么问题?他知道在Spring框架中可以用构造器注入、域注入、setter注入 三种方法来注入一个对象,但从来不关心为什么要“依赖注入”?在我过去几年的职业生涯中,我听过太多 “大家都这么写,那我也这样写” 的话了,很少有人能问一句 why 。

另一个常见的问题是,部分程序员只会静静等待产品经理“发号施令”,产品经理让他实现什么他就实现什么,全然不愿去了解整个项目的业务背景,以至于无法从更大的视角去理解整个业务是怎样运转的,也就无从判断需求的合理性和价值点,因此常常做出来的东西要么不符合实际(当然这个锅产品经理也有一半),要么勉强能用,但不是最适合。

程序员天然的一个优势就是,如果一个项目迭代了很多年,那么整个公司可能只有程序员是对业务如何运转是最了如指掌的,因为只要他们愿意,他们可以追溯到任何一个动作。

对业务问题有深刻理解,然后用最 fit 的代码去解决它,这正是工程师的价值。这可比默写出单例模式的四种写法重要也有趣得多了,因为你在探索一个更大更真实的世界,而不是拘泥到技术细节中去。

保持好玩

我个人觉得,做技术保持好玩的心态是相当重要的。我很庆幸自己当初是因为“好玩”和“热爱”进入这个行业,因此对“写代码”这件事至今还觉得挺酷、挺好玩。

前段时间跟一些前辈聊,普遍听到的说法是到了他们这个年纪,早已磨灭了对技术的热情,但为了生活养家不得不在这个行业混下去,能干一天是一天。我深知软件开发这个行业,如果没有一腔热血和激情,哪怕坚持下去,内心也是痛苦的。

只有拥有好玩的心态的人,才会写出好玩的代码,最重要的是,这个过程也才会是好玩的。

也许几年后,我对技术的热情也会消失殆尽,但是我希望所有做技术的朋友(包括我自己)不要放弃对现实世界的探索,将技术热情转换为生活热情,永远保持好玩。这样,哪怕有一天不在这个行业了,也能带着这份“好玩”去探索更大的世界。

Be curious and however difficult life may seem, there is always something you can do and succeed at.

-- Stephen William Hawking

贡献者: jerrysheh