如何阅读程序源代码?

2023-05-16

文章目录

    • 1 我为什么阅读源码
    • 2 阅读源码的好处
    • 3 阅读源码的困难
    • 4 阅读源码的步骤
    • 5 阅读源码的方法

1 我为什么阅读源码

我开始阅读源码是在进行互联网开发的第八九个年头。在此之前,我做过校园网站,接过网站开发的私活,进行过理论算法相关的研究,也设计开发了许多系统。我对我做过的系统都比较有信心,它们也都运行的不错,但是一个疑问却在我的心头逐渐浮现:我的架构和世界最优良架构之间的差距到底有多大?

阅读开源项目的源码能给我答案。

许多优秀的开源项目历经数千开发者的数万次提交,被数亿用户使用。这些项目从可扩展性、可靠性、可用性等各个角度考量,都是十分优良的。通过阅读这些项目的源码能让我找到自己在软件设计和开发上的不足。

于是我开始了我的源码阅读计划。

2 阅读源码的好处

阅读源码的好处很多,而且已经成为共识。光靠铺天盖地的源码阅读活动就能感知一二,虽然我觉着那些活动都太过浮躁,主要是个噱头,学不到啥。

但是不可否认,阅读源码的好处极多,包括但不限于:

  • 透彻地理解项目的实现原理
  • 接触到成熟和先进的架构方案
  • 学习到可靠与巧妙的实施技巧
  • 发现自身知识盲点,提升自身知识储备

所以,我有些后悔,我觉着我应该更早地开始源码阅读。我推荐进行源码阅读的时机是:学会编程语言的基本知识,并做过少量项目之后。

我们知道,学编程的过程中在不断接收新的知识,进步很快。刚开始做项目时,进入实践领域,进步很快然后就到了平台期,可能几年下来都是重复的增删改查,毫无进步。这段平台期实际是进行源码阅读的良好时机,能让你的技术持续进步。

3 阅读源码的困难

当我们阅读一份源码时,需要面对的困难通常有:

  • 难以归纳的凌乱文件
  • 稀奇古怪的类型组织
  • 混乱不堪的逻辑跳转
  • 不明其意的方法变量
  • ……

所以很多人即使知道阅读源码的好处,也坚持不下来。就因为以上困难难以克服。

而阅读源码的难,是正常的。

3.1 时间维度带来的困难

从时间维度上看,每一个优秀的工程项目都经历了从雏形到成熟的曲折演化过程。而整个过程都会被映射到一个时间点上,肯定很难。

于是有人提出了“阅读源码时,从第一次提交开始阅读”的主意。我要说一下,这是错误的!

这是一种纸上谈兵式的错误,提出这种方法的人肯定没怎么读过源码。事实上,我也有过这种想法,然后在实践中很快被抛弃了。

如果一个项目只经过了几次提交,这种方法获取可行。而一个优秀的通常有几千上万次提交,将这几千上万次提交都读完,工作量要比把当前最新版本的代码读完难的多得多!因为其时间维度的复杂度比空间维度复杂度大得多了。

我用下面的图片展示了项目发展的过程,一个项目从版本1到版本n,逐渐完善。版本1一般是最简单最基础的,但是,要想从版本1读起,一直读到版本n,可能要阅读几千个版本。难度极大,远不如直接去读版本n。

img

还有,许多项目的第一次提交并不是只有几行代码的init项目,往往第一次提交就是几百个类。而且,初期的代码组织还比较混乱。毕竟,作者也不知道该项目能火,往往比较随意。

更别说,历史提交中还夹杂很多的Bug、回退、依赖包升级等等。想要把每次Bug、回退、依赖包升级所产生的历史背景都搞清楚,这几乎是不可能的任务。

3.2 空间维度的困难

每一个优秀的工程项目都凝聚了众多开发者的缜密思维逻辑,而这些逻辑都被投射到了平面的代码上。这使得阅读源码的过程成了逆推开发者思维逻辑的过程,显然,逆推是很难的。

不过,这方面的困难真有解决方案:详细了解开源项目的功能,然后自己琢磨该如何实现

这样,就将逆推 的过程转化为了 正向推导+验证 的过程,这样就相对简单了。

但无论如何,阅读源码总不会太简单。于是有人说读懂源码比编写源码更为困难,想必也是有一定道理的。

4 阅读源码的步骤

阅读源码推荐按照下面的步骤进行:

  1. 了解项目的背景。这相当于了解了项目的需求。
  2. 充分了解项目的功能,并熟练使用。我们说过,将“逆推”的过程转化为“正向推导+验证”的过程是阅读源码的一个重要方法。而了解项目的功能是这个方法的基础。
  3. 调试代码。通过断点调试,掌握整个代码的流程走向、主次关系、依赖关系。
  4. 划分源码。根据每个包、模块的功能不同,将源码划分为几个部分。
  5. 由底层到上层,逐个击破。先阅读不依赖其他模块的,或者依赖其他模块比较少的基础模块。然后逐步上移,完成整个项目源码的阅读。
  6. 横向总结。在由底层到上层阅读完成后,横向以功能点为维度串联源码的实现逻辑。

一般情况下,一个项目的源码要在3~4个月左右读完。否则,可能读到后面的,已经忘记前面的功能了。

当然越快越好,但考虑到我猿们还要加班,时间太短了不太现实。

5 阅读源码的方法

有人说读懂源码比编写源码更为困难,不无道理。而源码阅读和软件开发一样,是一个非常综合的能力,没有一个万全之法。但有很多不错的方法。

例如一些常用的方法:

  • 调试追踪:多数情况下,当我们对某些变量的含义产生疑惑时,借助开发工具的调试功能直接查看变量值的变化是一个非常好的方法。而且该方法还能指引代码逻辑的跳转过程,对于理解源码极为有用。
  • 归类总结:优秀的源码都遵循一定的设计规则,这些规则可能是项目间通用的,也可能是项目内独有的。在源码阅读的过程中将这些设计规则总结出来,将会使得源码阅读的过程越来越顺畅。
  • 上下文整合:有些对象、属性、方法等仅仅通过自身很难判断其作用和实现。此时可以结合其调用的上下文,查看对象何时被引用、属性怎样被赋值、方法为何被调用,这对于了解它们的作用和实现很有帮助。
  • 类别阅读:如果存在实现某功能的两条或者多条路径,可以类别阅读,找出他们处理逻辑的不同。
  • ……

还有很多方法,不再一一介绍。因为没有实在的源码案例,光介绍显得很浮。

如果大家真的决定阅读源码,开始提升自己架构能力和编程能力的新阶段,可以阅读《通用源码阅读指导书——MyBatis源码详解》。

是一本以MyBatis源码为材料,详细介绍源码阅读相关方法和技巧的源码阅读指导书籍。

该书以实际开源项目MyBatis为例,详细介绍了源码阅读的经验和方法。在源码阅读中,透彻分析了相关的背景知识、组织方式、逻辑结构、实现细节。在本书的讲解中,不漏过每一个类,不跳过每一个难点,做到深浅一致。并对这些源码阅读方法进行了进一步的总结整理。

阅读源码会使你有很大的提升,但是这个过程也确实需要你沉下心来慢慢进行。

但我保证,只要你读完一个项目的源码,就会收获巨大。

最后,用书籍前言中的一句话结尾。

img

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何阅读程序源代码? 的相关文章

  • 电脑关机或重启C盘数据被清空还原问题

    电脑关机后清空数据是因为电脑装有还原精灵 xff0c 可以下载冰点破坏工具 还原精灵破坏工具 硬盘保护卡破坏工具来取消数据的清空 电脑重启不还原 xff0c 方法如下 xff1a 方案一 一般情况下可以用带FDISK的启动盘启动电脑 xff
  • 敏捷教练的十种能力

    1 具备神奇的 读懂一个房间 的能力 只要走进一个房间 xff0c 就能判断出不在的过程中 xff0c 房间里发生了什么事情 xff0c 能立即读出空气中蕴含的情绪 xff0c 从而判断是否一切正常 xff1b 2 关心人本身胜过关心产品
  • Java数组之二分法查找数

    数组的二分法查找数据 使用前提 xff1a 查找的数组必须是有序的 span class token keyword public span span class token keyword class span span class to
  • MQ 队列管理器常见错误解析

    消息管理器无法连接到目标队列管理器 请确保以下事项 xff1a 在 消息管理器 队列管理器定义中所定义的端口与通道侦听器使用的端口相匹配 WebSphere MQ 队列管理器通道侦听器已启动 WebSphere MQ 队列管理器命令服务器已
  • 【简单理解】ubuntu中的sudo和su

    参考 xff1a https blog csdn net liberty12345678 article details 87686284 https cloud tencent com developer article 1721753
  • 那些女程序员们的故事

    点击上方蓝字 关注我们 xff0c 和小伙伴一起聊技术 xff01 程序媛是程序员大军中一道美丽的风景线 xff0c 今天的这篇文章就选取了一些女程序员们的故事 xff0c 希望当所有人了解了他们的经历后 xff0c 能让这个 重男轻女 的
  • 直播分享丨前沿技术讲习班:知识图谱前沿技术与应用(CIPS ATT27)

    本文转载自公众号 xff1a 智源社区助手 作为大数据时代重要的知识表示方式 xff0c 知识图谱是人工智能领域构建和应用知识的新阶段 xff0c 它能够更好地实现大规模数据的认知与推理 同时 xff0c 知识图谱和深度学习相互协作 xff
  • 图谱实战 | 京东基于时序知识图谱的问答系统

    转载公众号 DataFunSummit 分享嘉宾 xff1a 商超博士 京东硅谷研究院 研究员 编辑整理 xff1a 张存旺 北航杭州创新研究院 出品平台 xff1a DataFunTalk 导读 xff1a 本文将分享Temporal K
  • 肖仰华 | 基于知识图谱的问答系统

    本文转载自公众号知识工场 本文整理自复旦大学知识工场肖仰华教授在VLDB 2017 会议上的论文报告 xff0c 题目为 KBQA Learning Question Answering over QA Corpora and Knowle
  • 研讨会 | 知识图谱前沿技术课程暨学术研讨会(武汉大学站)

    知识图谱作为大数据时代重要的知识表示方式之一 xff0c 已经成为人工智能领域的一个重要支撑 4月 28日 xff0c 武汉大学信息集成与应用实验室 与 复旦大学知识工场实验室 联合举办 知识图谱前沿技术课程暨学术研讨会 xff0c 将结合
  • jdbc中Statement和PreparedStatement有什么区别?哪个性能更好?

    Statement和PreparedStatement的功能主要是对sql语句的执行 区别 xff08 1 xff09 Statement每执行一条sql语句就需要生成一条执行计划 xff0c 执行100条就需要100条执行计划Prepar
  • redis的特性

    redis的特性 承接上文redis入门篇 xff0c 本文具体介绍一下redis的特性 xff0c 以及与另外一个nosql数据库memcached的对比 一 redis的优点 根据上文 xff0c 我们知道redis的如下特性成为了他的
  • Ubuntu22.04安装windows字体

    找到C Windows目录 xff0c 将其中的Fonts文件夹拷贝至ubuntu中 将该文件夹放至ubuntu的 usr share fonts目录下面 xff0c 可用下列命令 span class token function sud
  • 阿里巴巴笔试题选解

    阿里巴巴笔试题选解 9月22日 xff0c 阿里巴巴北邮站 小题 xff1a 1 有三个结点 xff0c 可以构成多少种二叉树形结构 xff1f 2 一副牌52 张 去掉大小王 xff0c 从中抽取两张牌 xff0c 一红一黑的概率是多少
  • ActiveMQ与Logback日志组件SLF4J冲突导致日志不输出

    ActiveMQ与Logback中的SLF4J日志组件冲突导致日志不输出 xff0c 控制台提示 Class path contains multiple SLF4J bindings 的解决方案 近期码的时候发现logback的组件日志都
  • 腾讯2014软件开发笔试题目

    腾讯2014软件开发笔试题目 9月21日 xff0c 腾讯2014软件开发校招 简答题 广州 简答题 xff1a 1 请设计一个排队系统 xff0c 能够让每个进入队伍的用户都能看到自己在 中所处的位置和变化 队伍可能随时有人加入和退出 x
  • C++ 进程间通信详解

    一 xff0c C 43 43 常用进程间通信 管道 Pipe xff1a 管道可用于具有亲缘关系进程间的通信 xff0c 允许一个进程和另一个与它有共同祖先的进程之间进行通信 命名管道 named pipe xff1a 命名管道克服了管道
  • OTA系统包的制作和测试方法

    OTA有两种制作方案 整包升级 xff0c 以及差分包升级 整包升级 完整的升级文件aosp XXXX XXX ota 01 20 010 00 00 zip 差异包 将第一个ota整包升级包和第二个ota整包升级包 xff0c 执行 bu
  • JAVA日记之javaJDK原生简单爬虫

    java原生爬虫 指定一个种子url放入到队列中 从队列中获取某个URL 使用HTTP协议发起网络请求 在发起网络请求的过程中 xff0c 需要将域名转化成IP地址 xff0c 也就是域名解析 得到服务器的响应 xff0c 此时是二进制的输
  • idea中修改自定义maven打包参数,打成一个大的jar

    解决idea打包只会把项目本身打成一个jar的问题 加上这条指令 clean package spring boot repackage Dmaven test skip 61 true f pom xml 在maven命令单这个里会生成新

随机推荐