人类真正的道德自觉是不可能的,就像他们不可能拔着自己的头发离开大地。-- 刘慈欣《三体》

本文是我们 lotus 源码研究系列 的第一篇,今天我们先调整好心态,顺便给大家分享一个我个人是如何研究一个新的项目, 或者说是如何学习一门新的技能的。

拿到一个陌生的项目,或者说进入一个陌生的领域,当然,能到行家给自己讲讲是最省时省力的办法了, 但是不见得每个人都有这个条件,普通人只能自己自学。 而作为职场人员遇到的更常见的情况是,你的老板不会给你太多时间学习,这也是一般公司为什么不喜欢招新手的原因。

今天我们就以如何快速上手 Filecion 源码开发为例,谈谈我们是如何快速投入 Lotus 源码开发的。

总体来说很简单,就是分为两步:前期准备和代码实战。

前期准备

前期准备主要分两个方面:

  1. 项目的前期准备主要是要了解项目的背景,它想要解决一个什么问题(它是用来干嘛的), 当前的项目架构,开发进度是怎样等等。
  2. 去 github 上找到项目源码,如果有用到自己不会的编程语言,就需要做些编程语言学习准备,开发工具等。如果有 Slack 技术频道,也可以加入以便跟进最新的开发和网友测试动态。
  3. 阅读正统文献 在前期准备中,一件最最最重要,但是又通常最容易被大多数人忽略的事情是:阅读正统文献。 具体到 Filecoin 这个项目,就是阅读 【Filecoin 白皮书】和 【官方快速开始文档】。 很多人都不愿意去读,因为看着那几十页的白皮书以及这么多文档就头大,加上这些文档都是英文的,就更不愿意去看了,觉得耽误时间。他们宁愿到 Slack 上去其他开发者。 殊不知,阅读正统文献才是最节省时间的,因为它能让你快速构建关于这个项目的知识体系, 虽然官方文档可能也有错误的地方,因为项目在修改,有些文档没有来得及更新。 但是即使这样,我们依然要从正统的文档入手,因为它后面的研究基准线,你后面所有的研究只需要在基准线上做修改即可。这样至少可以保证你不会偏差太远。

我们虽然从 2018年年底就开始接触 Filecoin 了,但是真正开始 Filecoin 源码修改也就几个月前的事情。那个时候其实我们对于 Filecoin 也只懂点皮毛。 因为此前我们主要的精力都在开发我们 GammaOS 运维监控系统上。

从我们开始下决心改 Lotus 源码,到第一版调度改出来,测试完,不到2个星期。

我记得我们当时是把 Filecoin 英文版的白皮书打印了2份,我们 2 个开发人员每人一份,一字不漏的读完, 然后各自把自己对于白皮书的理解通过白板讲述一遍,然后相互补充对方的信息,做到信息对称,然后才开始动手改代码。

  1. 学习相关的编程语言 跟 lotus 开发相关的语言的主要有 2 种:rustgolang。对于编程语言这块我的建议是:如果你只有其他语言的编程经验,那么你不需要做过多的准备,你应该直接上手,在实战中学习,根据我的经验,这是最直接和高效方法。 我还花了几天时间学习了 golang 语言, 而我另一位同事(来自谷歌的大神)则是直接开始改源码, 虽然此前他从来都没有写过一行 golang 代码,但是对他来说居然毫无阻碍,很快就在顺利调试了。 让我佩服的目瞪口呆,也看到了我们之间的差距,明白了深厚的计算机底层功底对开发来说是多么的重要。

事实上,你的所有准备都不可能完全充分,如果你想想准备充分才开始行动,那么,你大概率上永远都没有机会行动。 借用经济学上的“边际分析”来说就是:你应该在“准备”所花费的代价正好等于准备所能带来的收益的时候,停止准备。 然而在实际操作的过程中还要根据具体任务的时间调整你的准备时间,比如你投入 1 倍的时间准备能把项目做到 80 分,投入 3 倍的时间准备能把项目做到 90 分。 如果时间充裕,而你对这个项目要求又极高的话,那么这个准备时间就是值得投入的。

然而现实生活中很多时候是你还想继续准备,但是已经没有时间了。发射窗口已经到了,项目不能再拖了。我认为截止日期的一个最大的作用,就是防止有人准备过度。 现在 IT 行业流行的敏捷开发,讲究小步快跑,快速迭代,那么你就不需要做太充分的准备,应该先出一个版本,后期再根据需求慢慢完善。

通常,高手都对边界都非常敏感,所以你很少看到他们纠结是该多准备一段时间,还是现在马上开干。

这里顺便提一下,一般高效率的人,动脑的时间肯定是多于动手的时间的。比如我们公司一个写成程序很厉害的同事,拿到一个项目,他一般都是花 70% 的时间构思,20% 的时间写代码,10% 的时间修改 Bug。不过后面那 10% 的时间通常没有花费到 5%,他写的程序 Bug 率极低。对此我也深有体会,事实上我基本也是这样的工作模式 o( ̄︶ ̄)o。

实战操作

在我看来,上机实战有 2 个目的:

  1. 在实战的过程中,修正我们对文档的理解偏差。 通常比较新的项目我们只能阅读一手英文文档(强烈推荐),如果英文阅读能力差的也可以其他人翻译的二手文档。 不管哪种,都会出现一定程度上的认知偏误和信息部队称。 即使你的英语非常厉害,读懂了字面意思,但是对一些概念和流程还是会有模棱两可的地方。 这个时候,通过调试代码能够让你更好地理解一些概念模型,以及整个项目的架构和业务流程。从而修正我们的基准线。
  2. 完成老板安排的任务。 这个非常重要,因为这是研究的目的。 有的时候我们做事常常把手段和目的搞反了。比如有的人每天把自己投入到无休止的加班,应酬之中,并口口声声说自己上班是为了自己家人能过上幸福的生活,但是到头来却把家里搞得怨声载道。殊不知工作只是手段,幸福生活才是目的。你的工作已经让让你的家人离幸福生活越来越远了,你却还坚持认为自己努力工作是为了让家人过上幸福的生活,这个不是掩耳盗铃吗?讲回到正题,时刻记得自己的目的(初衷)能够在关键时刻提醒你:暂停深入,回收成果。有的时候我们研究代码容易走火入魔,觉得官方写的代码,这里也不好,那里也不好,就想全删了重写,这样就陷入了为了改进技术而改进技术了,而我们改进技术其实是为了解决现有问题。这个时候你只要一想到老板给你安排的任务是:根据当前咱们遇到的调度问题,改一版适合我们任务调度机制。你就能收住重写的冲动,老老实实把这个阶段的研究先“变现”。事实上这也是最高效的做法,你改的东西需要要线上实测之后,根据实测的结果再确定下一步的优化方案。

总结一下今天说的内容:

开始 Lotus 源码开发之前我们需要做一定的准备,主要是阅读白皮书和官方文档来了解整个系统的架构,工作原理,流程以及一些技术名字。 同时我们又不要准备的太过充分,应该快速投入实战开发,简单而又直接的攻击目标。

最后,今天是 2020 农历除夕之夜,希望大家在新的一年身体健康,一切顺利,活在当下,做一个自由的人。