在github上读优秀的开源项目,不要一行行扫过去,非常低效,因为很多项目不是demo,有的项目动辄10几万行,你不可能一下子读完。按照下面这5步走,也许会事半功倍。
1.先看README,把项目跑起来
找到 README, README里面一般会包括项目的简介,项目需要的环境,启动方式等,有些会包含项目的目录结构。读完README,你就能知道这个项目做了一件什么事,可以把代码拉到本地,然后把需要的环境装好,试着把项目跑起来。
2.从一条完整的执行链开始,了解模块之间的依赖关系
项目跑起来之后,你大概应该能回答项目的模块组成,并且可以找到某个模块所在的项目目录,接下来就是弄清楚模块之间的依赖关系,我更推荐从一个实际功能入手,比如说一个Agent项目,你发一个提示词给它,它做了哪些事,中间有哪些过程,结果返回了什么,这里虽然只有一个功能,但是这个核心功能一般都会有好几个模块联动,首先是入口,就是输入的地方,从这里切入,你就能找到它调用的模块,从而 知道模块之间怎么依赖的。其他功能也是如此,先在产品层了解,再回看源码中底层模块之间的依赖关系。
3.拆解具体实现
知道了模块之间的依赖关系,这个时候一般还是不知道具体是怎么实现的,这就来到了非常重要的一步,那就是拆解某个功能具体的内部实现,比如说,一条调用链路中,涉及多个模块的多个函数,一个函数可能会调用多个函数,每个函数有相应的输入输出,中间过程会有条件分支、循环、状态变化、错误处理,并且各种数据类型也都有相应的类型,这些都是具体的实现部分,第一次看肯定是非常陌生的。最好从某个入口函数开始,看看输入时接受了哪些参数,参数的类型可以先放一放,因为参数类型之间可能也会有依赖,如果这个时候直接钻进参数类型中去,看的会很乱。不如先把调用链路弄清楚,看看它是如何实现整个过程的,再具体去看每一个调用函数中的数据参数类型以及参数类型之间的依赖。有很多人会刚开始就去一行一行地看数据模型的参数类型,这样看代码效率很低,因为就算你花了大量时间来看参数类型,你有可能也不知道项目到底干了些啥事。应该反过来,从整体到局部,这样会更加清晰。
4.复述和总结
经过前3步,对于项目的了解应该有个七七八八了,有很多人到这就结束了,但我们要做的还远不止这些,一个优秀的的开源项目,可以学习的点有很多,如果你只是看完了,而没有经过大脑的深度加工,那么学习这些又有什么意义呢?后面别人问你具体实现,你也答不出来,只能说个七七八八,应付一下面试还行,但想要做点什么完全不行,结果就是后面入职了可能又回炉重造了。所以这个时候我们可以把之前看过的源码进行一个总结,首先是看看能不能复述,如果不能,那就继续深入某个核心部分,再看具体实现,看不懂的话,那就去补一下基础,这样又可以学到很多。
5.基于开源项目进行二次开发
学习完一个开源项目后,你会知道具体的实现和它的用途,这个时候你也许会想,我能用它做些什么?应付面试?只是当一个搬运工?这些当然可以,不过最好的是你可以在它的基础上再做些什么,我们看有很多产品都借鉴了优秀的开源项目,并且可能一个产品借鉴了多个开源项目,比如 Node.js 就是 v8、libuv等多个开源项目的结合,如果你能借鉴某个开源项目进行二创,或许会比你从0开始造轮子更好。
当然,要仔细讲的话,上面的5步也许都可以专门出一篇文章,后面看看有没有时间总结一下吧。