对于不少开源软件来讲,若是咱们把它做为咱们业务系统的重要组成部分之一,真正地用于生产,仅仅知道如何使用是远远不够的,你必须掌握它的实现原理和不少细节,这样才能找到最佳的使用姿式,当你的系统出现问题时,你才有可能基于它的实现原理,再根据一些现象来排查问题缘由。git
掌握这些开源软件的最佳方式就是去学习它的源代码。不少同窗跟我说:“我也很想去看一些开源软件的代码,也尝试去看过,可是面对上千个源码文件,几十万行代码,彻底不知道从哪儿入手啊。”程序员
今天咱们就针对这个状况来聊一聊,学习开源软件的代码该如何入手。github
有一点我提早说明一下,对于这节课里面涉及到的一些名词,我会直接使用英文,主要目的是方便你直接对应到那些开源软件英文官网上的标题。面试
学习源代码应该从哪儿入手呢?最佳的方式就是先看它的文档。架构
经过看文档,你能够快速地掌握这个软件总体的结构,它有哪些功能特性,它涉及到的关键技术、实现原理和它的生态系统等等。在掌握了这些以后,你对它有个总体的了解,而后再去看它的源代码,就不会再有那种盲人摸象找不到头绪的感受了。ide
首先强调一点是,你必须去看这些开源软件官方网站上的文档,尽可能不要去网上搜一些翻译的中文文档。为何呢?学习
由于这些开源软件,特别是一些社区活跃的软件,它的迭代是很快的,即便是自带官方中文翻译的项目,它的中文文档不少都会落后于英文版,你能看到的中文版本不少时候都已通过时了。那非官方的翻译,问题可能就不止是过期的问题了,可能还会出现一些错漏的地方。因此,最好仍是直接来看官方的英文文档。网站
若是说你的英文阅读水平确实有限,直接阅读英文文档有困难或者看得很是慢,怎么办?你仍是要按照我接下来告诉你的方法去看它的英文官网,即便阅读大段的技术文章有困难,网站的标题你总能看懂吧?找到你须要阅读的文章后,你能够在网上搜一下对应的中文版本,先看一遍中文版,而后再对着英文原版过一遍,弥补中文版可能过期或翻译不许确的问题。ui
开源社区通过这么多年的发展,它已经造成一个相对比较成熟的文化。每一个开源软件,代码如何管理、社区成员如何沟通、如何协做这些都已经造成了一个比较固定的套路。大多数开源软件,它的官网和技术文档也是有一个相对比较固定的结构的。翻译
接下来咱们以Kafka 的官网为例子,来讲下怎么来看它的文档。
若是说你对这个项目彻底不了解,没用过这个软件,你首先须要看的文档是Quick Start,按照 Quick Start 中的指导快速把它的环境搭起来,把它运行起来,这样你会对这个项目有个感性认识,也便于你在后续深刻学习的时候“跑”一些例子。
而后你须要找一下它的Introduction,通常里面会有项目的基本介绍。这里面很重要的一点是,你须要找到这个项目用到的一些基本概念或者名词的介绍文档,在 Kafka 的文档中,
这些内容就在 Introduction 里面,好比 Topic、Producer、 Consumer、Partition 这些概念在 Kafka 中表明的含义。
有些开源项目会单独有一个 Basic Concepts 文档来说这些基础概念。这个文档很是重要,由于这些开源社区的开发者都有个很很差的爱好:发明概念。不少开源项目都会本身创造一些名词或者概念,了解这些基本概念才有可能看懂它项目的其余文档。
对项目有个基本的了解以后呢,接下来你能够看一下它的使用场景、功能特性以及相关的生态系统的介绍。在 Kafka 中功能相关的内容在Use cases和EcoSystem两篇文章中,有些项目中会有相似名为 Features 的文档介绍功能和特性。
其中项目的生态系统,也就是 EcoSystem,通常会介绍它这个项目适用的一些典型的使用场景,在某个场景下适合与哪些其余的系统一块儿来配合使用等。若是说你的系统不是特别特殊或者说冷门的话,你大几率能够在 EcoSystem 里面找到和你相似的场景,能够少走不少的弯路。
你在读完上面这些文档以后,对这个项目的总体应该会有一个比较全面的了解了,好比说:
对这些问题有一个初步的答案以后,接下来你就能够去深刻学习它的实现原理了。这是否是意味着,你能够当即去看它的源码呢?这样作或许可行,但并非最好的方法。
你知道大部分开源项目都是怎么诞生的吗?通常来讲是这样的:某个大学或者大厂的科学家,某天脑海里忽然出现了一个改变世界的想法,科学家们会基于这个想法作一些深刻的研究,而后写了一篇论文在某个学术期刊或者会议上发表。论文发表后在业内得到不少的赞,这时候就轮到像 Google、Facebook 这样的大厂出手了:这个论文颇有价值,不如咱们把它实现出来吧?一个开源项目就这样诞生了。
因此,对于这样的开源项目,它背后的这篇论文就是整个项目的灵魂,你若是能把这篇论文看完而且理解透了,这个项目的实现原理也就清楚了。
学习完项目灵魂,就能够开始阅读源码了。
须要注意的是,你在读源码的时候,千万不要上来就找 main 方法这样泛泛地去看,为何?你能够想一下,一篇文章,它是一个线性结构,你从前日后读就好了。一本书呢?若是咱们看目录的话,能够认为是个树状结构,但大多数的书的内容仍是按照线性结构来组织的,你能够从前日后读,也能够经过目录跳着读。
那程序的源代码是什么结构?那是一个网状结构,关系错综复杂,因此这种结构是很是不适合人类去阅读的。你若是是泛泛去读源代码,很容易迷失在这个代码织成的网里面。那怎么办?
我推荐你们阅读源码的方式是,带着问题去读源码,最好是带着问题的答案去读源码。你每次读源码以前,肯定一个具体的问题,好比:
相似这种很是细粒度的问题,粒度细到每一个问题的答案就是一两个流程就能够回答,这样就能够了。若是说你就想学习一下源代码,或者说提不出这些问题怎么办呢?答案仍是,看文档。
肯定问题后,先不要着急看源代码,而是应该先找一下是否有对应的实现文档,通常来讲,核心功能都会有专门的文档来讲明它的实现原理,好比在 Kafka 的文档中,DESIGN和IMPLEMENTATION两个章节中,介绍了 Kafka 不少功能的实现原理和细节。一些更细节的非核心的功能不必定有专门的文档来讲明,可是咱们能够去找一找是否有对应的Improvement Proposal。(Kafka 的全部 Improvement Proposals 在这里。)
这个 Improvement Proposal 是什么呢?你能够认为它是描述一个新功能的文档,通常开源项目须要增长一个新的功能或者特性的时候,都会建立一个 Improvement Proposal,通常标题都是"xIP- 新功能名称",其中 IP 就是 Improvement Proposal 的缩写,x 通常就是这个开源项目的名称的首字母,好比 Kafka 中 Improvement Proposal 的标题就都是以KIP 来开头。
每一个 Improvement Proposal 都是有固定格式的,通常要说明为何须要增长这个功能,会对系统产生那些影响和改变,还有咱们最关心的设计和实现原理的简述。
你读完讲解实现的文档再去看源代码,也就是我刚刚说的,不仅是带着问题去读,而是带着答案去读源码。这样你在读源码的时候,不只仅是更容易理解源代码,还能够把更多的精力放在一些实现细节上,这样阅读源码的效果会更好。
使用这种以问题为阅读单元的方式来读源代码,你每次只要花很短的时间,阅读不多的一部分源码,就能解决一个问题,获得一些收获。这种方式实际上是经过一个一个的问题,在网状的源代码中,每次去读几个点组成的那一两条线。随着你经过阅读源码了解的问题愈来愈多,你对项目源码的理解也会愈来愈全面和深刻。
若是你想了解一个开源项目,学习它的代码,最佳的切入点就是去读它的官方文档,这些文档里面,最重要的灵魂就是项目背后的那篇论文,它通常是这个开源项目的理论基础。
在阅读源码的时候呢,最佳的方式是带着问题去阅读,最好是带着问题的答案去读,这样难度低、周期短、收获快。不要想着必定要从整体上去全面掌握一个项目的全部源代码,也没有必要。