程序员普遍有个毛病:爱写不爱读。

写代码的时候特别有成就感,屏幕上的字符一个个蹦出来,手指在键盘上飞舞,觉得自己正在”创造”。读代码的时候就开始烦躁,特别是读别人的代码——这写的是什么东西,为什么这样命名,为什么这里要绕一圈——越读越气,越气越读不进去。

但现实是工作中80%的时间在读代码,不是写代码。接手一个项目,先要读。排查一个bug,要读相关的代码。code review别人的代码,也要读。读代码是基础能力,但大多数人对它重视不够。

读代码为什么难

读代码比写代码难,因为你要跟上另一个人的思路,而这个思路往往是不完整的。

写代码的人知道自己想做什么,所以写出来的东西往往是”结论”,中间省略了推导过程。读代码的人没有这个推导过程,只能从结论反推,难度自然更大。

还有一个问题是上下文缺失。代码写出来的时候附带的上下文——为什么要这样做、当时的权衡是什么、有没有更好的方案——在代码本身里是看不到的。读代码的人只能靠猜。

解决这个问题的办法是,找写代码的人聊。如果找不到,就找测试代码、提交记录、设计文档。这些东西能帮你补充上下文。

从哪里开始读

面对一个陌生的代码库,正确的做法不是从上往下、从第一行开始读。这样效率很低,而且容易迷失。

正确的做法是,从入口开始。

这个”入口”可能是main函数,可能是某个API endpoint,可能是页面的初始化逻辑。找到入口,顺着调用链往下走,碰到不懂的模块再深入去看那个模块的内部。

这样做的好处是,你能先对整个系统有个宏观的印象,知道各个部分是怎么串起来的。细节可以在需要的时候再去抠。

另一个有效的策略是,先找”关键路径”。对于一个功能来说,核心逻辑往往只有一条路径,其他的都是边界处理、日志、监控这些”非关键”的东西。先把核心路径搞清楚,再去处理细节,效率会高很多。

读代码的工具

好的工具能大幅提升读代码的效率。

IDE的”跳转到定义”和”查找引用”是最基本的。学会用快捷键,熟练到不用思考的程度,这能让你在代码里”飞”起来。

如果你接手的是一个前端项目,Chrome DevTools的Network面板和Sources面板能帮你理解代码运行时的情况。很多时候静态代码读不懂的,运行时一看就明白了。

还有一个技巧是,用git blame看代码的历史。某段代码被修改过几次,分别是谁改的,改了什么。这能帮你理解代码的演变过程,也能找到写这段代码的当事人。

# 查看某个文件每行的最后修改者和时间
git blame filename

# 只看某个函数的修改历史
git log -p --follow -S "function_name"

怎么才算读懂了

衡量你有没有读懂一段代码,有个简单标准:能不能删掉它。

如果你能把某段代码注释掉或者删掉,然后预测系统会有什么反应,并且这个预测是正确的,那你就是真的懂了。如果你删掉之后发现系统报错了,但你不理解为什么报错,那就还没懂。

这个标准有点极端,但很有效。

另一个标准是,能不能向别人解释这段代码在做什么。不是背诵代码,而是用你自己的话解释它的逻辑和目的。如果你能做到这一步,说明你对这段代码的理解已经到了可以动它的程度。

心态问题

最后说一个心态问题。

读别人代码的时候,很容易进入一种”审判模式”:这写的什么垃圾代码,怎么可以这样,为什么不用更优雅的方式。

这种心态会阻碍你理解代码。

实际上,任何代码的存在都有它的原因。可能当时时间紧,可能当时只有这个方案可用,可能代码经过多轮修改已经不是最初的样子了。带着”这段代码一定有它的道理”的心态去读,比带着”这代码有问题”的心态去读,效果会好很多。

当然,如果你读完发现确实是垃圾代码,那至少你是在理解的基础上做出的判断,这比不了解就喷要强。

读代码这件事,练多了就有感觉了。关键是要愿意花时间在上面,而不是只愿意写不愿意读。

种下你的想法

在花园里留下一条评论,和这篇文章一起生长。

COMMENTS