写代码不是唯一重要的事
引言
前两天跟一个刚入行的小兄弟吃饭,他跟我说最近在公司可忙了,每天疯狂写代码,需求文档看都不看,测试用例也不管,全部丢给测试团队。我问他为什么这么做,他说:“我工资是写代码发的,又不是写文档发的,把代码写完就行了呗。”
听完我差点把嘴里的可乐喷出来。这兄弟的想法可能代表了不少刚入行的新人——觉得只要代码写得快、写得猛,就是好工程师。但实际上,干了这么多年,我越来越觉得,写代码可能只占了程序员工作的三分之一,甚至更少。
今天想跟你们聊聊,除了写代码,还有哪些事情其实一样重要,甚至更加重要。
读代码的时间可能比写代码还多
很多人觉得自己是“写代码的”,但实际情况是,你一天当中可能有大半时间是在读代码。
一个新需求来了,你得先看看现有的代码是怎么实现的;接手一个老项目,你得先读懂别人写的代码才能下手;排查一个 bug,你得顺着调用链一层一层往下读;甚至你自己写的代码,过俩月回来维护,也得重新读一遍。
我之前带过一个项目,有个同事写代码那叫一个风骚,各种奇技淫巧,变量名都是 a、b、c,函数长度几百行,一个函数干了七八件事。代码是能跑,但没人敢改。后来有一次我让他维护自己的代码,他看了半天说:“这谁写的?”我说就是你啊,他自己都笑了。
所以我一直觉得,可读性才是第一位的代码质量。你写代码的时候,要想着三个月后的自己可能完全忘了这茬,要想着接手的同事可能是个刚入职的新人。代码是写给人看的,顺手让机器能跑那是基本要求。
怎么做到可读?很简单:
# 好的命名
def calculate_user_total_order_amount(user_id):
total = 0
orders = get_orders_by_user(user_id)
for order in orders:
total += order.amount
return total
糟糕的命名
def calc(u):
t = 0
o = get_o(u)
for i in o:
t += i.a
return t
多写几行注释,多拆几个函数,命名取得有意义一点,真的能省很多事。
沟通能力真的能救命
程序员这个群体吧,有时候挺奇怪的。技术上牛得不行,但一跟人说话就犯怵。我见过太多技术大牛,因为沟通问题把自己坑惨的。
最典型的就是需求评审会。产品经理讲完一个需求,技术大牛也不提问,也不确认,回到工位就开始闷头写。写到最后发现理解错了,又要重做,浪费两三周时间。这种事情我见过太多了,每次都替他们心疼。
还有跟测试团队的沟通。发现了 bug,测试报上来,有些程序员直接来一句“不可能,我这没问题”,然后就不理人家了。结果呢?最后发现真的是 bug,还得低三下四去找测试改 bug 描述。
其实好好说话真的没那么难。需求不确定就多问几句,确认清楚了再动手;发现 bug 了态度好一点,大家都是打工的,互相理解一下;甚至日常跟同事交流,语气也稍微软一点,你会发现世界都美好了很多。
我之前带过一个团队,有个技术一般的同学,但特别会沟通。需求有疑问第一时间跟产品确认,遇到技术难点主动找架构师讨论,代码 review 的时候也虚心接受意见。虽然技术不是最强的,但项目从来没延期过,团队里大家都喜欢跟他合作。后来他升职速度比很多技术大牛都快。
你说沟通重要不重要?
文档是给未来的自己擦屁股
提到文档,很多程序员第一反应就是:“写那玩意儿干嘛?代码都写不完。”
但你想想看,过两个月回头看自己写的代码,是不是有时候也想不起来当时为啥要这么写?更别说是别人写的代码了。
我之前接手过一个没有人维护的系统,代码倒是能跑,但没有任何文档。数据库表结构没有注释,接口没有说明,部署流程没有文档,新人来了完全无从下手。后来我花了两周时间才把整个系统搞明白,期间还踩了好几个坑。
从那以后我就养成了一个习惯:重要的代码一定要写文档,复杂的逻辑一定要留注释。不是为了别人,是为了自己。
而且文档不只是写给自己看的。你写的接口别人要用吧?你搭的系统别人要接吧?你设计的方案别人要评审吧?这个时候,一份清晰的文档能省多少事,真的只有经历过的人才能懂。
我现在写文档一般包括这些内容:
- 接口说明:参数、返回值、错误码、业务场景
- 部署文档:环境依赖、配置项、部署步骤
- 架构设计:整体结构、模块划分、数据流向
- 常见问题:容易踩的坑、注意事项
别嫌麻烦,真的有用。
测试不只是测试工程师的事
很多程序员觉得测试是测试团队的事,自己写完代码往测试一交就行了。这种想法真的要不得。
且不说测试团队能不能覆盖所有场景,就算能,等 bug 反馈回来再改,沟通成本、时间成本都很高。更重要的是,有些 bug 等到测试阶段才发现,修复起来可能涉及到架构层面的改动,代价很大。
我自己现在养成的习惯是,代码写完先自己跑一遍,核心逻辑一定要写单元测试。不是说要达到 100% 覆盖率,但关键路径一定要覆盖到。这样至少能保证自己改代码的时候心里有底,不至于改坏了自己都不知道。
而且写测试的过程其实也是重新审视代码的过程。很多时候写着写着就会发现,咦,这个逻辑好像不太对?或者这个函数太长了,测都不好测,得拆一拆。
# 简单的单元测试示例
def test_calculate_discount():
# 测试正常情况
assert calculate_discount(100, 0.1) == 10
# 测试边界情况
assert calculate_discount(0, 0.1) == 0
# 测试异常情况
try:
calculate_discount(-100, 0.1)
assert False, "应该抛出异常"
except ValueError:
pass
写测试不耽误时间,反而能帮你发现很多问题。这买卖划算。
理解业务才能写出有用的代码
最后一点,也是我觉得最重要的一点:你得懂你写的代码是干嘛用的。
很多程序员觉得自己是搞技术的,业务是产品经理的事,跟自己没关系。这种想法大错特错。
你写一个电商系统,得懂什么是 SKU,什么是库存锁定,什么是优惠券叠加规则;你写一个金融系统,得懂什么是年化收益率,什么是风险控制;你写一个社交系统,得懂什么是关系链,什么是feed流。
不懂业务,你写出来的代码可能功能上没问题,但完全解决不了实际问题。产品说要一个“实时库存”,你搞了个每天凌晨同步的,结果订单都下完了库存还没更新,这不是搞笑吗?
而且懂业务的人,在技术方案设计的时候能考虑得更周全。比如一个接口现在并发不高,但业务上马上要做活动,并发可能涨十倍,你在设计的时候就应该考虑到这一点,而不是等出问题再重构。
怎么懂业务?多和产品经理聊,多看需求文档,多参与业务讨论。技术是手段,业务是目的搞清楚目的,手段才能用对。
结尾
说了这么多,其实就想说一句话:程序员的工作不只是写代码。
沟通、文档、测试、业务理解,这些看起来“不重要”的事情,其实都是程序员核心能力的一部分。一个优秀的工程师,不仅仅是代码写得好,更重要的是能跟团队协作、能维护好代码、能理解业务需求。
当然,我不是说代码不重要。代码是基本功,基本功必须要扎实。但在这个基础上,多关注一些“代码之外”的事情,你会发现自己的路越走越宽。
好了,今天就聊到这里。希望对你们有帮助。我们下次见。
写代码不是唯一重要的事
本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
评论交流
欢迎留下你的想法