<audio id="audio" title="98 | 高效学习：深度，归纳和坚持实践" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/b6/3a/b6427beebb4a62407ff7f68b9524f53a.mp3"></audio>

# 系统地学习

在学习某个技术的时候，我除了会用到上篇文章中提到的知识图，还会问自己很多个为什么。于是，我形成了一个更高层的知识脑图。下面我把这这个方法分享出来。当然学习一门技术时，Go语言也好，Docker也好，我都有一个学习模板。只有把这个学习模板中的内容都填实了，我才罢休。这个模板如下。

<li>
**这个技术出现的背景、初衷和要达到什么样的目标或是要解决什么样的问题**。这个问题非常关键，也就是说，你在学习一个技术的时候，需要知道这个技术的成因和目标，也就是这个技术的灵魂。如果不知道这些的话，那么你会看不懂这个技术的一些设计理念。
</li>
<li>
**这个技术的优势和劣势分别是什么，或者说，这个技术的trade-off是什么**。任何技术都有其好坏，在解决一个问题的时候，也会带来新的问题。另外，一般来说，任何设计都有trade-off（要什么和不要什么），所以，你要清楚这个技术的优势和劣势，以及带来的挑战。
</li>
<li>
**这个技术适用的场景**。任何技术都有其适用的场景，离开了这个场景，这个技术可能会有很多槽点，所以学习技术不但要知道这个技术是什么，还要知道其适用的场景。没有任何一个技术是普适的。注意，所谓场景一般分别两个，一个是业务场景，一个是技术场景。
</li>
<li>
**技术的组成部分和关键点**。这是技术的核心思想和核心组件了，也是这个技术的灵魂所在了。学习技术的核心部分是快速掌握的关键。
</li>
<li>
**技术的底层原理和关键实现**。任何一个技术都有其底层的关键基础技术，这些关键技术很有可能也是其它技术的关键基础技术。所以，学习这些关键的基础底层技术，可以让你未来很快地掌握其它技术。可以参看我在CoolShell上写的Docker底层技术那一系列文章。
</li>
<li>
**已有的实现和它之间的对比**。一般来说，任何一个技术都会有不同的实现，不同的实现都会有不同的侧重。学习不同的实现，可以让你得到不同的想法和思路，对于开阔思维，深入细节是非常重要的。
</li>

基本上来说，如果你按照我上面所提的这6大点来学习一门技术，你一定会学习到技术的精髓，而且学习的高度在一开始就超过很多人了。如果你能这样坚持2-3年，我相信你一定会在某个领域成为炙手可热的佼佼者。

# 举一反三

举一反三的道理人人都知道，所以，在这里我并不想讨论为什么要举一反三，而是想讨论如何才能有举一反三的能力。我认为，人与人最大的差别就是举一反三的能力。那些聪明的或者是有经验的人举一反三起来真是太令人惊叹。

我觉得一个人的举一反三能力，可以分解成如下三种基本能力。

<li>
**联想能力**。这种能力的锻炼需要你平时就在不停地思考同一个事物的不同的用法，或是联想与之有关的其他事物。对于软件开发和技术学习也一样。
</li>
<li>
**抽象能力**。抽象能力是举一反三的基本技能。平时你解决问题的时候，如果你能对这个问题进行抽象，你就可以获得更多的表现形式。抽象能力需要找到解决问题的通用模型，比如数学就是对现实世界的一种抽象。只要我们能把现实世界的各种问题建立成数据模型（如，建立各种维度的向量），我们就可以用数学来求解，这也是机器学习的本质。
</li>
<li>
**自省能力**。所谓自省能力就是自己找自己的难看。当你得到一个解的时候，要站在自己的对立面来找这个解的漏洞。有点像左右手互博。这种自己和自己辩论的能力又叫思辨能力。将自己分裂成正反方，左右方，甚至多方，站在不同的立场上来和自己辩论，从而做到不漏过一个case，从而获得完整全面的问题分析能力。
</li>

在这方面，我对自己的训练如下。

1. 对于一个场景，制造出各种不同的问题或难题。
1. 对于一个问题，努力寻找尽可能多的解，并比较这些解的优劣。
1. 对于一个解，努力寻找各种不同的测试案例，以图让其健壮。

老实说，要获得这三种能力，除了你要很喜欢思考和找其它人来辩论或讨论以外，还要看你自己是否真的善于思考，是否有好奇心，是否喜欢打破沙锅问到底，是否喜欢关注细节，做事是否认真，是否严谨……

这一系列的能力最终能构建出你强大的思考力，而这个思考力会直接转换成你的求知和学习能力。其实，我也是在不断地加强自己的这些能力。

# 总结和归纳

对自己的知识进行总结和归纳是提高学习能力的一个非常重要的手段。这是把一个复杂问题用简单的语言来描述的能力。就像我小时候上学时，老师让我们写文章的中心思想一样。这种总结和归纳能力会让你更好地掌握和使用知识。

也就是说，我们把学到的东西用自己的语言和理解重新组织并表达出来，本质上是对信息进行消化和再加工的过程，这个过程可能会有信息损失，但也可能会有新信息加入，本质上是信息重构的过程。

**我们积累的知识越多，在知识间进行联系和区辨的能力就越强，对知识进行总结和归纳也就越轻松**。而想要提高总结归纳的能力，首先要多阅读，多积累素材，扩大自己的知识面，多和别人讨论，多思辨，从而见多识广。

不过，我们需要注意的是，如果只学了部分知识或者还没有学透，就开始对知识进行总结归纳，那么总结归纳出来的知识结构也只能是混乱和幼稚的。因此，**学习的开始阶段，可以不急于总结归纳，不急于下判断，做结论，而应该保留部分知识的不确定性，保持对知识的开放状态**。当对整个知识的理解更深入，自己站的位置更高以后，总结和归纳才会更有条理。总结归纳更多是在复习中对知识的回顾和重组，而不是一边学习一边就总结归纳。

我们来总结一下做总结归纳的方法：**把你看到和学习到的信息，归整好，排列好，关联好，总之把信息碎片给结构化掉，然后在结构化的信息中，找到规律，找到相通之处，找到共同之处，进行简化、归纳和总结，最终形成一种套路，一种模式，一种通用方法**。

要训练自己这方面的能力，你需要多看一些经典的方法论图书，看看别人是怎样总结和归纳知识的。你可以在一开始模仿并把自己的理解的知识给写出来，写博客会是一种很好的方式。另外一种更好的方式是讲一遍给别人听。总之，你需要把你总结归纳的知识公开出来，给别人看，接受别人的批评和反馈，这样你才能成长得更快。其实，我也在锻炼这样的能力。

如果你在Coolshell上看过我写的《[TCP的那些事儿](https://coolshell.cn/?s=TCP%E7%9A%84%E9%82%A3%E4%BA%9B%E4%BA%8B%E5%84%BF)》，你就能知道我对《TCP/IP详解》这本这么厚的书以及一些日常工作经验的总结，我写成了两篇比较简单的博客。你需要像我一样扩大自己的知识面，然后学会写博客，就能慢慢地拥有这种能力了。这种将信息删减、精炼和归纳的方法，可以让你的学习能力得到快速的提升。当你这么做的时候，一方面是在锻炼你抓重点的能力，另一方面是在锻炼你化繁为简的能力。这两种能力都是让你高效学习的能力。

最后，还想说一下，一般来说，拥有这样能力的人，都需要有在更高的维度上思考问题的能力。比如一些名人的金句，就是这种能力的体现。这种能力需要你非常深入的思考，需要你的阅历和经验，当然，和聪明人在一起也是提升这种能力的最有效的选择。

# 实践出真知

所谓实践出真知，也就是学以致用，不然只是纸上谈兵，误国误民。只有实践过，你才能对学到的东西有更深的体会。就像我看 《Effective C++》和《More Effective C++》这两本书一样，一开始看的时候，我被作者的那种翻来覆去不断找到答案又否定自己的求知精神所折服。但是，作者的这种思维方式只有在我有了很多的实践和经验（错误）后，才能够真正地体会为什么是这样的。

这两书不厚，但是，我看了十多年，书中的很多章节我都可以背出来，但是我想得到的不是这些知识，而是这种思维方式，这需要我去做很多的编程工作才能真正明白，才会有斯科特·迈耶斯（Scott Meyers）那样的思维方式，这才是最宝贵的。

另外，实践出真知也就是英文中的 Eat your own dog food。吃自己的狗粮，你才能够有最真实的体会。那些大公司里的开发人员，写完代码，自己不测试，自己也不运维，我实在不知道他们怎么可能明白什么是好的设计，好的软件？不吃自己的狗粮，不养自己的孩子，他们就不会有痛苦，没有痛苦，就不会想改进，没有改进的诉求也就不会有学习的动力，没有学习，就不会进步，没有进步就只会开发很烂的软件……不断地恶性循环下去。

实践是很累很痛苦的事，但只有痛苦才会让人反思，而反思则是学习和改变自己的动力。Grow up through the pain， 是非常有道理的。

# 坚持不懈

坚持不懈是一句正确的废话。前段时间，我在我的读者群中发起了一个名为ARTS的活动。每人每周写一个ARTS：Algorithm 是一道算法题，Review是读一篇英文文章，Technique/Tips是分享一个小技术，Share是分享一个观点。我希望大家可以坚持一年，但是我也相信，能够坚持下来的人一定很少，绝大多数人都是虎头蛇尾的，但是我依然相信会有人坚持下来的。

坚持是一件反人性的事，所以，它才难能可贵，也更有价值。我从2003年写blog到今天15年了，看书学习写代码，我都会一点一点的坚持。人不怕笨，怕的是懒，怕的是找到各种理由放弃。

这里，我想鼓励一下你。现在很多国外的在线视频课都是3-5分钟一节课，一共20节课，总时长不到两个小时。然而，你会发现，能坚持看完的不到千分之一。当年Leetcode只有151道题的时候，一共有十几万人上来做题，但全部做完的只有十几个，万分之一。所以，只要你能坚持，就可以超过这个世界上绝大多数人。想一想，如果全中国有100万个程序员，只要你能坚持学习技术2-3年，你就可以超过至少99万人了（可能还更多）。

当然，坚持也不是要苦苦地坚持，有循环有成就感的坚持才是真正可以持续的。所以，**一方面你要把你的坚持形成成果晒出来，让别人来给你点赞，另一方面，你还要把坚持变成一种习惯，就像吃饭喝水一样，你感觉不到太多的成本付出。只有做到这两点，你才能够真正坚持**。

希望我的这些话可以让你有足够的动力坚持下去。

# 小结

总结一下今天的内容。我分享了系统学习、举一反三、总结归纳、实践出真知和坚持不懈等几个方面的内容。

<li>
在系统学习中，我给出了我学习时用的学习模板，它不但有助于你学习到技术的精髓，更能帮你提升你的学习高度。坚持几年，你一定能在某个领域成为炙手可热的佼佼者。
</li>
<li>
在举一反三中，我分享了如何获得这种能力的方法。
</li>
<li>
在总结和归纳中，我指出，积累的知识越多，在知识间进行联系和区辨的能力越强，总结归纳的能力越强，进而逐渐形成在更高维度上思考问题的能力。
</li>
<li>
在实践出真知中，我阐明了实践的重要性，并认为，只有实践过，才能对学到的东西有更深的体会。
</li>
<li>
最后，我强调，虽然学习方法很重要，但坚持不懈更为重要，并给出了怎样做才能让自己对学习这件反人类的事儿坚持不懈。
</li>

下篇文章中，我将分享一些学习技巧，也是我这么多年来行之有效的。希望对你有帮助。

下面是《高效学习》系列文章的目录。

- [端正学习态度](https://time.geekbang.org/column/article/14271)
- [源头、原理和知识地图](https://time.geekbang.org/column/article/14321)
- [深度，归纳和坚持实践](https://time.geekbang.org/column/article/14360)
- [如何学习和阅读代码](https://time.geekbang.org/column/article/14380)
- [面对枯燥和量大的知识](https://time.geekbang.org/column/article/14389)
