​《如何高效学习》是一本主张通过整体性学习的方法来提高学习效率的书。书中结合信息的几种不同类型(随意的、观点的、过程的、具体的、抽象的),从信息的获取、理解、拓展、纠错和应用这几个逐步深入的层次,提出了如何高效学习的假说,指出了不少具有实用价值的方法,例如快速阅读、笔记流、比喻内化、图表、纠错和项目应用等。

刚看这本书的时候,我是一口气大约在一个多小时快读完的,记了十几条笔记。后面两天都回头来翻一番书后的总结和自己的笔记,每次都有些新的感想。这里尤其想整理的是:这本书给自己在阅读代码方面的几点启迪。

整体性学习与理解业务逻辑

在《如何高效学习》这本书中,整体性学习是指遵循书中建议的信息获取、理解、拓展、纠错和应用的具体步骤,以达到对信息的内化、融会贯通和灵活应用的方法。其实这里的信息不仅仅可以指书本上的信息,还可以是某个软件项目上的信息:它包括用户需求、业务流程、系统设计和软件实现。不对这些全面的获取和深入的理解,不可能理解了后面的系统设计,更别提软件实现了。笔者最近学习一个分布式存储系统的时候,就在这里走了弯路。我当时在对系统的整体模块有了大概的了解之后,就开始看模块介绍文档,然后马上开始话费大量时间阅读代码。最后花了一两周时间,对系统整体的业务的理解仍然少得可怜,并且看过的模块里面仍然有很多怎么也看不懂的代码。现在想来,正确的做法应该是先了解整个系统的功能、特点和接口,然后深入学习去理解它的主要业务操作的原理和流程,代码的阅读应该放在最后。

比喻、类比和关联

比喻这种方法受到《如何高效学习》的强烈推崇,因为它能够深入浅出地描述问题、说透问题。而类比则是建立横向联系的必经之路,它能够把所学习的知识和其他已知的关联起来,这是一个加深理解和记忆的过程。比如当时学习分布式存储系统的时候,对复制组放置的逻辑一直模糊,直到最近细读ceph, 读到里面介绍PG和OSD的关系的时候,才彻底清晰起来。而这一环节,其实在之前做某款文件系统的时候有接触过的,单就是没有和分布式里面的存储资源的划分和分配关联起来。而之所以没有本能地关联起来,根本还是在于对于一个存储系统的几个关键功能、模块的理解还没有内化。

结构、模型和高速公路

《如何高效学习》这本书中提出了关于学习的“结构”、“模型”和“高速公路”的三个概念,分别用来比喻已建立紧密联系的一系列知识、简化了的并且做了快照之后的结构以及结构和结构之间的联系。落实到存储系统方面,它的“结构”不外乎包括前端接入、逻辑地址映射、物理地址映射、后端写入四个部分,实现地址映射的“模型”则主要包括hash、索引,后端写入的模型通常是一部非阻塞IO模型。而连接存储系统和分布式的“高速公路”就是支持一致性协议的和业务无关的接口库。

勤于应用和熟能生巧

高效学习中最关键的步骤就是:将所学的知识用到实际中去。因为如果你能发现知识在你生活中的价值,知识就与你产生了紧密的联系。想想大学的那些布尔代数、离散数学、线性代数和微积分,它们可怜地在你的记忆里蒙上了一层厚厚的灰尘,以至于你都快认不出它们了。写一个算法,里面的全排序是否是必需,优先级队列是不是就够了?另外,算法的正确性如何证明?这些好像听起来有些困难。根本原因还是你没有把它们真正用起来过。以自己为例,不知道看了多少遍《深入理解Linux内核》,却很少用到在最近的工作当中去。而我们对C/C++/Java/Python等则一目了然,只因为它简单么?每次想到这些问题,才感觉到自己在日常工作中的深入思考之少!

不过言归正传,还是先回到阅读代码方面的“应用”。在这里,业务逻辑相当于“原理”,而代码的实现则相当于“应用”,所以理解了原理,迅速找到相应代码的实现能加深对系统的理解,而修改相应的代码乃至重构才是熟悉代码的不二法门。

读书笔记和代码笔记

《高效学习》这本书建议随身带上一个小本子和笔,便于随时记录信息中的关键、难点、重点,而非信息的主要内容。代码阅读也是如此,目的不是归纳出流程,而是理解逻辑。因此,同样也可以随时记录看不懂模块的所在层次、功能、关键逻辑和重要函数。特别需要针对不懂的函数和功能,确定到底是算法不懂,还是业务不懂。如果是算法,回去搞明白相应模块的算法原理;如果是业务,退一步从上层看看之前的业务逻辑的理解是否有偏差。