【思考】学习源码的三重境界

记得刚工作那会儿,看ART或者Binder的源码就像看天书一样,完全没有头绪。Binder还好一点,有许多相关的博客和书籍可以参考。而ART完全是摸黑,因为当时市面上没有任何一本介绍ART的书籍,只能从JVM的知识体系中找一些参考。

曾国藩曾用"结硬寨,打呆仗"六个字总结自己的治军方略,这六个字对于源码学习也同样适用。当一个知识缺乏外界参考时,反复地阅读源码也许是最好的办法。这让我想起之前和小米某位前辈的一次聊天,他说自己在职业早期凭借一招便树立了自己的技术招牌:当时从事的工作经常会碰到复杂的底层问题,而这些问题的调试严重依赖GDB的使用,因此他把厚厚的GDB官方手册从头到尾读了好多遍,烂熟于心,之后在复杂问题的调试时大放异彩,为人所知。这个观点我深刻认同,因为在学习这条路上,不走捷径就是最好的捷径。

在我看来,学习源码是一个漫长且艰辛的过程。随着时间的推移,方法和认知也会发生改变。以下便是我在学习源码的三个不同阶段的认知。

第一重境界:看山是山。

"看山是山",强调的是理解知识的细节,是"知其然"的过程。这一阶段的典型特征是在写博客时喜欢贴大段的源码,譬如我早期的博客。这就好比导游领着大家前往一座漂亮的宫殿,介绍着里面的每一处细节,让大家知道柱子是柱子,窗户是窗户。

这个过程从"不知"到"知",因此会有强烈的收获感,但同时也是局限的。我们可以拿着源码跟别人辩论:看,代码就是这么设计的。但如果别人反问我们:为什么要这么设计呢?我们多半会哑口无言。

第二重境界:看山不是山。

"看山不是山",具有两个维度的含义。一是跳出细节,从宏观的维度思考每一处的关联,以及为什么要这么设计;二是用历史的眼光来看待源码,了解它变化的过程,而不是单一孤立地局限在某个版本。它强调的是理解设计者的意图,以及冲破权威,思考设计者可能犯的错误。这一阶段是"知其所以然"的过程。前几年开始,我在写博客的时候就刻意去减少贴源码的行为,而是通过框图的形式来展开描述。这样会逼迫我去结构化地总结知识,并尽量用清晰明了的语言讲述出来。这个阶段,我们会慢慢感觉到很多代码的设计模式其实都脱胎于实际生活,以及算法在其中的重要性。

这里提两个技巧,能够帮助我们更快地理解设计背后的原因。一是借助cs.android.com,通过git blame和git history找到某一个机制引入的具体改动。接着在android-review.googlesource.com上查找这笔改动提交时的commit message和具体的讨论,帮助我们了解设计者的设计初衷。二是通过git history可以查看提交者的邮箱,如果有更进一步的问题,可以直接邮件联系原作者,而不用在那里猜测设计者的意图。

第三重境界:看山不如上山。

马克思曾说过:哲学家们只是用不同的方式解释世界,而问题在于改变世界。对于源码学习,最好的方式一定是在实践中学习,这是我近一年来才有的感悟。理解和学习其实是个被动的过程,缺乏实际的检验机制;而当我们主动去写一些新的代码、新的框架时,如果知识理解不到位,代码的运行就会有问题,因此这样的反馈机制可以帮助我们正确且深入地理解知识。

举两个例子。

一个是我之前给ART主线贡献的JNI优化,开发过程中碰到的问题有二十多个。有些问题报出来时自己都绝望了,因为根据当时对于源码的理解觉得不可能发生,而谷歌从有限的错误log中也看不出问题所在。硬着头皮一步步地去调试、比对、阅读源码,最后发现其实是自己理解的不够全面,忽略了某些情况的考虑。像这样的实践过程常常会陷入到无助的情绪中,但我一般都劝自己:今天解决不了,说不明明天就想通了。神奇的是,这样的心理暗示往往会有不错的效果。

另一个是我最近在弄的ART Java Hook方案。关于ART Java Hook,我几年前就有关注,但只局限在一些博客的阅读上,理解非常肤浅。最近之所以动手写一套,一是因为自己感兴趣,二是因为有朋友说他们有这样的诉求,目前市面上的ART Java Hook都不够稳定。写的过程中我重点参考了epic和pine的源码,也仔细学习了SandHook、FastHook、YAHFA的原理文章。在它们的基础上,叠加上我对于ART的理解,便产生出很多新的想法和思路。其中有些想法是朦胧的,为了验证是否可行,我需要再去研究ART源码中一些特定的细节,以及ART中优化对Hook方案可能产生的影响。总之,写一套可用的方案或许不难,但写一套考虑全面、具有较高稳定性和兼容性的方案比较难。后者需要对ART内部很多机制有细致的了解,而不仅仅是一个大致的概念。这个过程其实也是逼迫自己去加深源码理解的过程。

后记

如今的互联网资料众多,大多数人学习新知识时习惯从书籍、博客、视频入手,但我强烈建议大家也去看看源码。从这些优秀开源项目的源码中,我们可以学习到优秀的框架、精湛的算法以及优美的写法。孔子有云,见贤思齐焉,长期地从这些优秀项目中汲取养分,相信对于我们自身的能力提升也大有裨益。

相关推荐
BoomHe1 小时前
Now in Android 架构模式全面分析
android·android jetpack
二流小码农8 小时前
鸿蒙开发:上传一张参考图片便可实现页面功能
android·ios·harmonyos
鹏程十八少9 小时前
4.Android 30分钟手写一个简单版shadow, 从零理解shadow插件化零反射插件化原理
android·前端·面试
Kapaseker9 小时前
一杯美式搞定 Kotlin 空安全
android·kotlin
三少爷的鞋10 小时前
Android 协程时代,Handler 应该退休了吗?
android
火柴就是我1 天前
让我们实现一个更好看的内部阴影按钮
android·flutter
阿懂在掘金1 天前
defineModel 是进步还是边界陷阱?双数据源组件的选择逻辑
vue.js·源码阅读
砖厂小工1 天前
用 GLM + OpenClaw 打造你的 AI PR Review Agent — 让龙虾帮你审代码
android·github
张拭心1 天前
春节后,有些公司明确要求 AI 经验了
android·前端·人工智能
张拭心1 天前
Android 17 来了!新特性介绍与适配建议
android·前端