大家好,我是程序员鱼皮。上周二晚上我直播带大家学习了一个 GitHub 上不错的开源聊天室项目 MallChat
,大家表示学到了很多,所以我专门剪出了一期项目导学视频,分享给大家: https://www.bilibili.com/video/BV1Q142147yk
在讲解项目的过程中,我发现很多同学并不清楚如何快速学习项目、以及如何快速阅读源码。今天这篇文章,我就带大家领悟这些技能,以后再自学项目会轻松很多~
如何快速学习项目?
1、初步了解项目
打开一个 GitHub 上的开源项目后,第一件事就是去看项目的 README.md 介绍文档,可以速览一遍看看有没有帮助你学习的内容,比如技术选型、功能介绍、如何快速启动项目、架构设计、注意事项等等。
以 MallChat 聊天室为例:https://github.com/zongzibinbin/MallChat ,项目介绍文档中包含对核心功能的介绍,可以看看有没有自己感兴趣的功能:
如果是公司内部的项目、或者比较成熟的开源项目,还会有 Wiki 文档,往往对项目的介绍会更加详细,但暂时不用通篇阅读,关注 “快速启动项目” 或者 “项目结构介绍” 的部分即可。
像我如果决心要学一个新的项目,除了 GitHub 官方文档外,还会在网上搜集一些相关资料,整理到自己的文档中,便于后续学习时能快速找到。
2、了解项目结构
看完项目介绍文档后,建议先从上帝视角整体了解项目的结构,比如项目分为哪些模块、每个模块大致有哪些文件、文件命名规则如何等等,但不用进一步理解模块(或目录)内部的组织和实现方式。尤其对于复杂的微服务项目来说,这样做可以快速帮你定位到学习重点。
大多数情况下,大家应该都是把项目代码下载到本地来学习。但如果你只是为了快速了解项目,并不打算深入学习,其实有更高效的方式。
比如在 GitHub 仓库的主页按 。
句号键,就能快速进入网页版的代码编辑器,跟本地浏览项目的体验几乎一致:
对于有一定经验的开发者,一般会先查找关键文件,比如前端项目找 package.json
(Node.js)、Java 项目找 pom.xml
(Maven)或 build.gradle
(Gradle)、Python 项目找 requirements.txt
或 setup.py
等,这些文件通常包含项目依赖和配置信息。如果项目是比较规范的,一般通过依赖和配置信息就能快速理解项目结构了。
举个例子,看到 aop 依赖,就知道项目用到了切面;看到 freemarker 依赖,就知道项目资源目录中会有 FTL 模板文件;看到 Redisson,就知道会有初始化 Redisson 客户端的配置类,这些就是积累经验的重要性了。
3、运行项目
如果要正式学习项目,先不要急着去阅读源码,而是要先把项目在本地成功运行,便于后续边调试边学习。
运行项目的步骤很简单,用 git clone
命令将项目复制到你的电脑,然后根据 README 文件或其他文档中的指示,安装项目的必要依赖项、修改本地运行配置、并最终运行项目。
虽然步骤很简单,但现实往往是大家把项目拉到本地后各种各样的报错信息,所以运行项目时要格外注重以下几点:
-
确保自己系统环境和项目要求一致,比如注意下前端 Node.js 和后端 JDK 版本要求。
-
确保项目依赖的版本和项目要求一致,比如后端依赖的 MySQL 和 Redis 版本。对于这种主流的技术,一般情况下只要别用太新的版本,基本不会影响项目的运行。
-
修改本地运行配置为自己的,比如数据库账号、密码等,而且要格外注意不要读取错了配置文件,否则可能改了半天还在疑惑 “怎么配置没生效呢”?
遇到报错是很正常的,因为不是所有的开源项目都做到了 “易用易上手”,遇到报错时,我们只要定位到关键报错信息,然后顺藤摸瓜找到对应的文件去修改即可。实在搞不定,这不还有搜索引擎和 AI 么?
这里分享一个常用的快速运行项目的技巧。有的时候项目用到了很多依赖(比如 MallChat 中用了 MinIO、RocketMQ 等),但是我们本地并没有安装这些依赖,导致项目无法启动。如下图,因为我没安装 RocketMQ,导致启动时连接 RocketMQ 报错:
要想启动项目,传统方法就是自己安装所有依赖,但如果项目只有一个不起眼的位置用到了某个依赖,其实花时间去安装性价比不高。这时,我们可以用一种更简单的方法,直接禁用掉用到这些依赖的 Bean 加载。
比如在启动类加上 exclude
,就能快速禁用某些依赖的自动加载,示例代码如下:
@SpringBootApplication(exclude = {RocketMQAutoConfiguration.class})
但是,禁用了 RocketMQ Bean 的初始化后,如果有代码用到了这个 Bean,就会因为缺失依赖的 Bean 而报错。这种情况下,可以使用 @Lazy
注解对 Bean 进行懒加载,用到的时候才会加载,启动项目时就不会报错了~ 示例代码如下:
public class MQProducer {
@Autowired
@Lazy
private RocketMQTemplate rocketMQTemplate;
}
4、了解业务流程和库表设计
在阅读代码学习前,最好先整体了解项目的业务流程和库表设计,有助于明确后续阅读源码时的顺序和学习方向。
核心业务流程可以通过阅读文档、或者自己体验系统的方式来了解。比如对于聊天室系统,核心业务流程就是:用户登录 => 用户上线 => 添加好友 => 创建房间 => 加入房间 => 发送消息 => 消息审核 => 其他用户接收消息 => 回复消息。
了解项目的库表设计也是有技巧的,比起直接看 SQL 文件,一般我会先在本地初始化数据库,然后通过可视化图表来查看。
如图,表之间的关系一目了然!比如房间又分为单聊和群聊,一个房间内有多个会话和消息:
5、阅读代码
刚开始阅读代码时,不要急着一行代码一行代码地按照顺序去阅读,而是要先整体理解每个目录的 作用和目录内部的文件组织形式 ,但暂时不必深入理解具体的实现方式。
举个例子,对于 MallChat 项目,你要先能明确红字中的信息:
查看某个目录内部的文件组织形式时,有一个小技巧。可以直接在 IDEA 中右键点击某个包,查看 UML 结构图:
通过结构图,我们可以速览类之间的关系。比如下图中,工厂创建策略、两个具体策略继承了抽象策略类:
之后,你就可以找到感兴趣的项目核心功能模块进行学习了,分享几个学习技巧:
1)如果想快速学习某个功能的实现,建议是通过文档等方式 先了解业务流程 ,再学习源码。学习源码时,建议使用 Debug 模式启动项目,通过接口文档(或前端)发送请求,完整地分析一个请求的处理流程。
可以通过 IDEA 的 Endpoints 功能快速查看项目中的接口,并定位到源码:
2)如果想快速了解单个文件的核心结构(比如方法和属性),可以使用 IDEA 的 Structure
功能,如图:
3)可以通过 Call Hierarchy 功能查看方法、类或变量在程序中被调用的层次结构和关系。比如下图我查看了 doMark
方法的调用者视图,可以看到哪些方法调用了它,便于快速理解代码之间的交互,不用自己一层一层点进去看了。
4)可以通过 Find Usages 功能快速查看一个方法或者类在项目中所有的使用位置:
5)当然,对于复杂的功能,单独看代码可能是理解不了的,这时就需要搭配文档和代码注释了。什么?没有文档?!不写注释?!那就直接通过 Git 版本控制工具找到原作者去询问吧。
6、理解项目开发流程和规范
在你熟悉了项目后,就可以尝试参与开发了。可以先通过 阅读项目的贡献指南或开发文档 来理解项目的开发流程、开发规范等,跟项目的其他开发者保持一致。如果有疑惑,可以看看别人的代码中是怎么做的,有样学样就行;实在不确定的话,最好是提前询问,不要提交一堆不符合规范的代码,再被别人打回来,浪费彼此的时间。
7、参与项目
最后,学习开源项目最好的方式就是亲身参与项目的开发,这也是我一直建议大家做的,不仅能提升能力、也能给自己的简历加分。
其实参与开源项目没有那么困难,可以先在项目的 Issues 部分查看别人反馈的 Bug,并且帮忙修复,熟悉整个参与开源项目的流程。之后还可以 跟作者沟通 并尝试添加新功能、进行优化等。
如果想让你贡献的代码更快被作者接受,就一定要做好沟通!因为我自己也有很多开源项目,也有小伙伴给我贡献过代码,但不可能所有的代码都接受。因为每个人关于项目的想法是不同的,在没有跟作者交流的情况下,可能你做的功能对项目并没有帮助、超出了项目的规划,反而会让项目更加复杂。团队开发也是一样,大家要一起评审需求,确保需求是有价值的、和项目定位是匹配的,而不是谁想加功能就加功能。
OK,以上就是本期分享,原创不易,有帮助的话还请点赞支持哦!