侧边栏壁纸
  • 累计撰写 793 篇文章
  • 累计创建 1 个标签
  • 累计收到 1 条评论
标签搜索

目 录CONTENT

文章目录

源码阅读技巧

Dettan
2021-04-10 / 0 评论 / 0 点赞 / 205 阅读 / 2,592 字
温馨提示:
本文最后更新于 2022-07-23,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

1.
先让项目可以跑起来(很重要的一点
2.
debug
3.
打印日志以及修改log4j日志级别
4.
查看调用栈
5.
全文搜索
6.
大胆猜测再验证

A、代码要解决的问题是什么?
B 、代码是如何实现的?


自顶向下的分析
在拿到一份源码时(假设你已经学会如何使用这个框架),我们第一件要做的事情是思考如果让我们来设计这个框架,我们会怎样设计,应该分成哪几个模块,模块之间如何耦合,如何让用户使用起来很简单的同时又可以扩展自己的功能等等。 当我们仔细分析一波后,会逐渐明白这个框架的设计难点、关键节点、核心等等。例如要我们设计一个加载图片的框架,那第一个想到的肯定就是缓存(内存缓存、磁盘缓存等等)、加载源(HTTP、File、Resource 等等)、格式转换等等这些要点,然后我们带着这些问题去看框架,效率自然就高了很多。


1.有好的IDE,建立符号表
2.能够调试
3.阅读文档和API
4.看commit和前期规模不大时的文档
5.根据某一个需求,一直调试下去

带着目的阅读代码
阅读代码最怕陷进去,源代码从头读到尾,结果看的云里雾里的。
最重要的是带着目的阅读。搞清楚为什么要阅读代码?你要学习架构、学习业务、学习模式、学习编码风格、学习类库还是什么?
设置一些小目标,这可以让你进阶得更快。


阅读代码理应具备立体感。也就说,我们需要从整体的角度去审视代码。
所以,我们不妨对代码做些调查。譬如看官网介绍,也可以参考维基百科。
总之一定要了解主要功能,被应用于哪些项目,其实这就是弄清代码的一个背景问题。


在面向对象的语言中,静态读代码,在遇到接口或者继承的情形下,会发现一个接口或者父类有多个实现,就不知道当前的代码走哪个类,这时最好把代码运行起来,准备动态调试的方式来

源码中,每个类和接口都是有说明和描述的,因此可以借助这个来增强你的理解和对该对象的认识。另外要梳理清楚整个项目的架构设计和背后的道理。

读源码要到达的效果
熟悉源码后,如果评估自己对源码学习的效果,可以通过以下指标来衡量:
清楚源码的设计架构
清楚源码的优势和使用到的技术亮点
清楚源码特有的核心领域对象
清楚源码的调用联。
最后,能够把源码中的优势技巧灵活运用到实际项目中。



自顶向下的分析
在拿到一份源码时(假设你已经学会如何使用这个框架),我们第一件要做的事情是思考如果让我们来设计这个框架,我们会怎样设计,应该分成哪几个模块,模块之间如何耦合,如何让用户使用起来很简单的同时又可以扩展自己的功能等等。当我们仔细分析一波后,会逐渐明白这个框架的设计难点、关键节点、核心等等。例如要我们设计一个加载图片的框架,那第一个想到的肯定就是缓存(内存缓存、磁盘缓存等等)、加载源(HTTP、File、Resource 等等)、格式转换等等这些要点,然后我们带着这些问题去看框架,效率自然就高了很多。用宏观角度去分析代码细节,自顶向下缕清关系。
模块划分
用模块化思维分析。其实通过上面的思考,我们已经能大概的给这个框架分出几个模块了,例如:缓存模块、加载模块、图片处理模块等等。然后我们开始看代码,一个优秀的框架都会有很清晰的模块划分,我们先根据模块来看,因为包是按照模块划分的,所以可以根据分包来了解框架中的模块,下面看一下 Glide 框架源码的包划分:
分包结构
第一个 load 包肯定是加载相关的东西,例如图片请求的执行、数据解码。request 包应该是请求封装模块,我们发起一个请求时应该会通过这个包下面的类进行包装。signature 叫签名,大概是关于请求标识、资源标识相关的?我们可以先这么理解。util 是工具包,放一些全局共用的工具类。其它的可以自己理解。到了这里我们已经能对这个框架有个粗浅的认识了。
另外,要相对模块划分有更深的了解,我们光看这个还是不行的,需要看一些代码才能更深入的了解,例如根据我们平时使用的方式,来看整个图片加载的流程是怎样的,每个流程负责什么任务,这样可以加深对模块的认识。
下面我们就可以按照模块来学习源码了,例如先学习 request 包下面的代码,明白请求是如何创建的等等,阅读源码时一定要时刻保持着清醒的头脑,千万不可迷失在层层的嵌套调用关系中。有一点需要注意:千万不可急于求成,看不明白的就放在后面看,先看能看明白的。
流程分析
了解一套图片加载的请求流程比较重要,我们通过分析这些流程能明白每个模块之间的关系。如果看过一些代码已经知道,模块之间都是使用接口耦合,每个接口又有很多实现类,具体的实现类要在代码运行时才能知道,所以想要找到一个方法具体的实现也是一件比较麻烦的事情。除了通过调试可以很方便的看到调用流程之外我这里再给一个技巧:关键点打印方法调用栈。打印方法调用栈的代码如下:
StringBuilder traceBuilder = new StringBuilder();
for(StackTraceElement e : Thread.currentThread().getStackTrace()){
    traceBuilder.append(e.toString());
    traceBuilder.append("\n");
}
Log.d(TAG, traceBuilder.toString());
搞懂流程之后可以画一个流程图出来,例如下面这样:
加载流程
当然了想要画出这样的流程图是需要时间的, 不是很轻易的就能完成,需要对源码有了一定的了解之后才行。
类分析
类分析是指我们在实际阅读源码时针对同一个家族的类的分析。类与类之间肯定会有这很多复杂的联系,我们在阅读时想要理清楚可以借助一些工具,例如自动生成 UML 类图的插件。效果如下:
UML 图
这里用的是 Android Studio 中的 simpleUML 插件来生成的,直接搜索安装即可。有了这种工具我们的效率将会事半功倍。
其实阅读源码最重要的技巧就是:死磕。没有什么特别的方法可以让你在很快的时间内对一个框架了如指掌,想要学好必须多花点时间仔细阅读,看得多了,自然就一回生二回熟了。




jdk源码阅读方法以及经验
1.
你可以build 一个fast debug版本,然后使用debugger去调试你的程序,这样对程序是怎么调用的有很直观的视图。
2.
看jdk里面的regression tests,里面有很多例子。其次,
3.
openjdk提供了netbean的jdk project,你可以很容易用netbean调试openjdk。
4.
jdk有很多native的程序,还有makefile,有空也值得阅读。
5.
阅读jdk源码最好才用模块的分割方法。比如这些天你只关注java.util.collection,你需要先了解算法这些基本知识,比如hashmap里面的allocation,capacity的概念,红黑树,二项堆。这样看程序就事半功倍。
6.
如果是看API,最好先百度哪些类满足你的要求的,直接看你需要的使用的类就可以了,看完父类看子类,不必要全部都去看,也没有那个时间,
7.
如果是看源码,你需要知道这个源码实现的功能是什么,先阅读实体类,再通过程序演示,去阅读源码,类似于按功能模块进行阅读,最好不要从头开始读,也不知道哪里是头,最好是边阅读边做必要的注释。
8.
工程我都是用Eclipse来阅读的,按CTRL+左键就能跳到函数,类的定义文件那里。如果你能找到一个熟悉这份源码的人,有人带你过一遍就最简单不过了。
9.
如果是javaweb工程,先看实体类,再看框架配置文件,再根据功能分模块看
0

评论区