有效复习与刻意练习

你应该有这样的经验。前两个礼拜,刚拜了某大师的实战班,学到顶尖框架。结果现在全忘光了。

或者是明明上个礼拜,才在喜马拉雅上听完课程,现在也什么也不记得了。

如何有效保存知识

在上一章我们谈过,美国学者艾德格‧戴尔(Edgar Dale)提出了「学习金字塔」(Cone of Learning)的理论:

在初次学习两个星期后,透过阅读学习能够记住内容的10%;透过听讲学习能够记住内容的20%;透过图片学习能够记住内容的30%;透过影像、展览、示范、现场观摩来学习能够记住50%;参与讨论、提问、发言来学习能够记住70%;做报告、教学、模拟体验、实际操作能够记住90%。

也谈过艾賓浩斯遺忘曲線

心理学家赫尔曼·艾宾浩斯通过自己的实验提出。在这一实验中,艾宾浩斯使用了一些毫无意义的字母组合。通过记忆这些字母组合,并在一系列时间间隔后检查遗忘率。

有效复习与刻意练习 - 图1

  • 20分后,42%被遗忘掉,58%被记住。
  • 1小时后,56%被遗忘掉,44%被记住。
  • 1天后,74%被遗忘掉,26%被记住。
  • 1周后,77%被遗忘掉,23%被记住。
  • 1个月后,79%被遗忘掉,21%被记住。

知识如果知识没有在短时间再度被利用的话,蒸发掉是必然的结果。

要如何保存当初这些费尽功夫学习来的知识呢?

有三个方法:有效复习,刻意练习以及养成习惯。

我们会在这一章介绍如何「有效复习」以及「刻意练习」。

有效复习

有效复习的关键,是得在你还记得大部分内容的情况下,进行第一次的复习。

一般来说,如果是刚读完一本书,我建议读者得在读完该本书的 45 分钟进行第一次输出。

而如果是刚学完一个技能或套路,建议在 1-3 天之内,进行第一次的套路练习。

读完书后的复习

读完书的复习诀窍。并不是试图死记硬背书里面的关键知识点,那样太辛苦,也不切实际。

所谓复习,应该是记下你看完这本书后的总结看法。

比如我在每读完一本书之后,必定在极速读书法的总结区,看著誊下的 16 格关键字,总结出我自己对这本书的 3-5 个心得看法。

其实使用完极速读书法的好处,并不单单只是降低读书所需要的时间。而是我在读完两本书后,看著这两张极速读书法的笔记,跨界碰撞出新的火花。这是以往单独看完两本书,很难有的事情。

而且,在看完两本以上的书时,我甚至会文思泉涌,进而写出一长篇的心得。

其实我在写这本书时进度很快,全拜这件事的累积。现在才有那么多过去的材料可以整理。

别担心到时候写不出心得。说也神奇,其实我只要接连读完两本书(或者是一本份量很足的书)之后,总会有冲动一吐而快,下笔灵感源源不绝。倾刻就是数千字。

分享给旁人,能更强化记忆

另外,更加强化记忆的方式,是写完总结后,再找旁人实际口头分享一遍。

进行口头分享,以及没有口头分享的差别。我认为记忆强化程度至少强了不只三倍。

如果真找不到旁人,我建议你开直播,没有人看也没关系,就稍微聊一下你刚刚的心得。

再度进行口头重述我个人认为有几个好处:

记忆其实不是以「输入」为基础,而是建立在「输出」之上。

每一次当我们输出的时候,才真正开始产生「长期记忆」。因此,在读书完之后,我必定会进行至少一遍的输出。而这次的输出,因为我是边整理边写,所以也算一次「输入+再输出」的过程。

口头分享,是以声音方式传播,口头分享我刚学习的内容,也算一次「输入+再输出」。(声音上的)

再者,每次我分享给其他人刚学到的东西,总会意外得到一些其他的惊喜,更加再次分享的动力。比如读者的留言里面,常会出现括:称赞,相关资源,疑惑,反馈。当然这里面也不是反对意见。

这些反应对我来说像是「开到隐藏宝箱」,非常乐意下次再做同样的事情。我们也会在本书「习惯与上瘾」的相关章节,持续继续探讨相关议题。

学完技能后的强化技巧

我在职业生涯初期,自认为是个比较笨拙的人。很多时候师傅讲一遍,我还是听不懂。很怕再度被骂。后来我养成了一个习惯,就是每学刚学会一样东西,我都会按照师傅的套路,至少再重玩 2-3 遍。确保我真的懂了。

因为,新手是很容易骄傲自大的。看师傅做觉得很简单,而且步骤单纯,以为自己也能马上学会。

其实真不是这样的。实际做下去就会发现自己其实做起东卡西卡,还常掉到坑里面去。甚至还要边做边想。

我初期也被这样骄傲的自己整过。所以我后来在学会之后,一定重新练习这个套路至少 2-3 遍,弄通我卡住的地方。确保重现这些基础套路时,能够一次过。

所以,我在后续自费上课进修之后。都会习惯性的在回家后的 1-2 周。会按照上课老师教的套路,来回至少练个两遍,确认自己真的学会。

甚至,我还会在练习完之后,将这套技能写下一份自己看的懂得 STEP BY STEP。不但确保自己当下学会,还确保以后真的不小心忘掉时,还能够无脑找回进度。

我自己在研发出新框架后,也会用相同的方式,保存自己的进度。去确保我不会失去这个技能,甚至重做一两遍打磨自己新发明的套路,确保自己不会忘记,以及检视还有没有可以优化的地方。

各位现在在看的这本书,实际上就是我的「极速写书法」的第二本练习作。(上一本书「闪电式开发」在 30 天内写完)

这次这一本书应该会更快。因为写完一本书,该踩的坑也踩了一轮,这本书写做进度明显比上一本快上许多。

保存超长以及超难的技能的进度

前面提的两个技巧,都是比较短的。不是读完一本书,就是学完一个短课。

但有时候,我们要学的是一整套功夫,比如说学会一套新程式语言,用这套新程式语言写一套 App。

这个过程既长又难,还涉及到中间很多要查很多资料。那么这样的题目,要怎么练习与复习。

在上一章,我提到了我是无师自通一门新领域的。

这里我要分享我在程序员时代学习新技能的一个方法。展示怎么攻克这个大难题的。

而这个学习方法,也广为我公司同事所用,成为他们进步的很好的一个方法。

这个方法有几个要点

  1. 随时随地备份进度
  2. 记录错误比记录对的更重要
  3. 把挑战分为小关卡
  4. 不贪心,一次只挑战一关

Step 1 : 随时随地备份进度

我们常在写代码时,备份进度的工具,就是 Git。Git 被称为是程序员的时光机。

我会用 Git 做几件事情:

  • 储存每次做功能的进度
  • 开实验分支,玩烂了也能回溯
  • 在 Github 可以检视功能代码的变化

这样我在开发时,就可以安心的犯错。也可以记下自己代码每一步骤的变化。

Step 2: 切分任务粒度

我在学习时,会用一套项目管理工具 Redmine。利用它的「树状 ticket 系统」去规划练习粒度。

这张图是我当时要学一门手机语言,写一个 App 的范例图片。

有效复习与刻意练习 - 图2

我运用的方法如下:

  1. 大致切出第一层,我觉得我想要练习的主题
  2. 然后中间要是有遇到难题,大概 30 分钟解不开,我就会「放弃」,然后开另外一张票,隔天心情比较好再回来学
  3. 中间我要是觉得「有个功能实在太棒了」,我应该可以来做。忍住,开出另外一张票,下周再来做。
  4. 每一张 Ticket 我拿来记几个东西:
    • 我这次找到了哪些 link(几乎是一 google 到一个疑似可以用的资源,就 copy 一份)
    • 这次这个功能写了哪些 code。 (是的,我不止 git 记了一份,redmine 上还复制了一份)
    • 这次我做了哪些改动
    • 我之前的「错误做法」,为什么错了。bug 的原因是?
    • 为了解 bug 所找到的 stackoverflow 资源

每一个 redmine ticket 其实就是一个小任务。我将 redmine 当成任务笔记,将练习当中的每个步骤记的详尽。 (不是指笔记做得好,而是指这当中的过程,我把每一步几乎都录下来)

这样做的好处是:

  • 我不会中途被相关的支线任务带分心,而会全神专注在我当初想练的主题上
  • 我不会被鬼打墙的 bug 打击到自信心全无。反正只是支线任务,了不起今天不解了。
  • 我不会被自己一时的成就产生的「傲慢感」带歪带进坑了。忘记当初学习这个技能的目的是什么
  • 当我们在学程式以及 debug 时,会查很多资料开非常多的网页。关掉 Chrome 就忘记原先在哪里找到的。笔记里面也没有。于是以后要重现步骤时,就坑到自己。
  • 把每一步执行的动作,包括 bug 与错误讯息,也都录下来。bug 的产生以及解法,其实是「重要的知识」。因为一般人「往往偏好只会保留正确的结果」,而不会保留当初 debug 的结果。然后下次自己还是会掉进同样的坑里面。

Step 3:挑选适当难度的题目,确保熟悉基本工具,谨慎推进

在自学过程中保持一定的「成就感」是很重要的。因此就算我的编程基础够,在学新项目时,我也不会试图一开始就打王。反而会给自己布置适当的难度。

假设练习作业,是刻出一个讨论版

超级新手状态

  • 做一个「单一功能」,CRUD (创建,读取,更新,删除)的练习。
  • 先做 R 再做 C 再做 D 再做 U。
  • 完整把这个动作做完一遍,搞懂怎么样让这个项目跑得的基本因素与语法。

新手状态

除了原先的基本功能外。

我会加上「非常基本」的延伸功能

  • 登入系统
  • 套上 CSS 设计
  • 部署

到这里的进度。起码可以让一个新手至少可以熟练这个系统的最基本工具,而不太容易绊倒。

然后,我会在这步。从最从头,练习 2-3 遍。并且写一个完全照著小抄走贴代码,完全不出会出错的 step by step 教程。确保我已经把到这里的道路踩稳了。

中手状态

基于新手的小套路,我会:

  • 再加上 开发者认为的 10 个重要核心功能
  • 至少加入 3 个外挂套件
  • 至少界接一个第三方服务(学会读懂领域内相关文件)

之所以会采用这样的学习法,是因为我自己过去被骄傲的自己整过太多次。带徒弟时也看到新手会在刚做出一个小项目的下一秒,因为对自己信心太过爆棚,去挑战魔王级难度。结果绕进大弯路,还严重打击自己自信心。

很多人可能觉得这样重复练 3-5 遍的方式很烦。但是我被自己整过太多遍了,所以在学习新技能时,我反而非常保守,非常耐心。也就是这样,我学新技能时,学得很快很稳,反而最后能够活下来。

Step 4:将笔记整理成技术文章进行发表

在学完这整套技术后,我会在适当时机,把过去的这些草稿笔记,重新整理输出成一篇技术文件。视情节发布给同事或给部落格读者。六年来,我在博客上的许多技术文章系列,非常完整,就是靠这个方式累积出来的。

这样的好处是,我不会在暴力瞎折腾后,忘记我当初是怎么搞出来的。

而且做出来的东西总有办法交接给其他人接手。

如果我要交接给同事我自己刚写完的东西:

  • 我会在拉 pull request 时,附上快速的一篇 Getting Started(如何开始) 。

如果是要教同事一个完全新的技术:

  • 我会至少做一份 Step by Step 的新手教程(完全可重制我当前进度),让想学的人,透过教程带练至少一次快速冲到新手等级。

因为当初我在做实验或探索时,redmine 上的纪录就记得很全。日后我在重新翻找 redmine 的杂乱无章的连结以及错误讯息的时候,练习当下的记忆瞬间就会被唤醒。甚至有时候上面还可以翻出当时随手记下的的 tips 与 example 可以直接拿来用。

这个方法让我在程序员时代就受用无穷。

所以,这个方法甚至演变成了我创业公司李的开发 Team 内规。我甚至在同事新人时期,就强迫他们开发功能时,一定要边开发边贴 LOG 在 redmine 上。这样日后自己在找开发信息时,就非常快。以后自己要是想写指南,也能不费吹灰之力。

过去很多人误认我对发表技术文章有著执著与狂热。因为没人会主动整理那么多技术教程,以及写的那么 User Friendly。但其实说穿了。这只是我工作上习惯的副产品而已。

这只是一个小习惯,但却让我这一生受用无穷:

  1. 对于曾经学习过的技术,我的输出非常稳定,基本上不可能犯错误,甚至输出速度可以到达肌肉记忆的阶段
  2. 对于曾经踩过的坑,后面很难再踢到过。就算踢到过,看著过去的笔记,也可以瞬间秒解。有时候甚至在网上 Google 到的解法或大全,竟然是自己写的(汗…)
  3. 不想做重复性工作。打开过去自己整理的 SOP,无脑的复制贴上就做完,轻松愉快。
  4. 真的再不想做,可以把 SOP 丢给 Junior 工程师让他照做,解放自己的时间,拿去做其他事。
  5. 批量生产跟自己有相同技能的人,与过去的自己愉快协作。我看到外面许多大师,不喜欢分享独门技能给其他人。但是我不这么看,你得把技能教给其他人,自己才可以去玩新的东西。而且让新手与我有同样的作事习惯,这实在太爽了。有那么多影分身不好吗?
  6. 我当时整理的这些 SOP 与教程,做的太完整了太容易上手了(我整理的教材,基本上学了之后可以将两年的摸索时间,降低到 3 个月)。导致于后来竟然可以直接商品化,让我直接脱离领薪水的程序员阶级。

如何「刻意练习」

Anders Ericsson 曾经写过一本在学习圈相当有名的书,名字叫「刻意练习」。

<<刻意练习>> 整本书可以总结归纳成两个重点:

  1. 创建有效的心理表征是专家和一般人的主要区别;
  2. 世界上没有天才,潜力是可以开发的,并且要大量的刻意练习。

如果将 <<异类>> 一书这一本书的论点:成为专家需要一万小时的努力,摆在一起看。

你会发现:

一个领域有那么多从业人员,但最后只有 1% 的人,最后成为了专家。所以,养成一个专家,也不是靠盲目乱练,必须得经过刻意的练习。

那么什么是「刻意练习」呢?书中提到「刻意练习」有三个步骤:

  • 有目的的训练:确定小目标不断改进、专注、及时反馈、跳出“舒适区”,做不擅长的事。
  • 把复杂问题组成一个个认知模块。
  • 明确高绩效的目标,即应该实现哪方面能力的提升。

即便如此,大家还是一头雾水。

到底「刻意练习」的标准是什么?

这个问题,其实我曾经答过同事。这个题目应该订为「你的拿手绝技是什么?」

你的拿手绝技是什么?— 追求最终 10 倍速的改进

其实我在二十几岁时,跟普通人没什么两样,也算所谓的斜杠青年。东会一点,西会一点。写程式会一点,专案管理会一点,写作会一点,什么都会一点。不知道自己该扮演什么角色。以及往哪里去。

但是我后来发现这样下去不行,感觉斜杠青年很牛逼,但其实也一事无成,定位混乱。样样通样样松。

我在家想了很久,决定给自己立下一个原则:「学习可以学得既广且杂,但是做事时,在自己会的领域,得要有可以瞬间出手把事情摆平的水准」唯有这样,斜杠这个字,才不会变成负面形容词。

也就是,在我自己有兴趣并且自信的领域,我强迫自己要树立一个最低的闪电式出手水平,并且持续精进到短时间不可能再快。

比如说我当初还是 Rails 程序员时,就觉得自己应该要把开发水平练到至少可以一天做出一个小网站出来。 这件事,是有可能做到的。勤「练」,或者是写自动产生器,应该都是可以做的。

  • 程式码熟练度可以练
  • 切架构感可以练
  • 写 User Story 可以练

练到听到一个 idea ,几分钟之内就可以要知道自己预计可以花多久时间写完。一天可以有多少进度,三天可以有多少进度,一个礼拜有多少进步,一个月有多少进度。甚至预估是多少时间,做的时候就是多少时间。只准提前完成,不能 delay 任何一日。

这是我当时要求自己的水准,因为我认为当「职业程序员」就应该有这种水平。我在2009年,当时程序员第三年就有这种功力。所以后来在 2012 年拿下 Facebook Hackathon 冠军,代码能写那么快,抓时程那么准,真不是侥幸,那已经是直觉反应等级的。

我在项目管理上,以及写文章对自己也有相同要求。

如果公司要开发一个大项目,我能不能听完需求后,马上用一张纸,就把人数、资源、时程、风险列出来。而且随时可以按照需求调整调度。我认为这是自己身为技术总监应该要有的职业水准。

在写作上。如果要抢发一篇文章。能不能给定一个题目。一小时至少写 2000 字出来不用查文献。我认为这是一个职业博客写手应该要有的水准。

后来,我甚至更变态的在增长领域,开发出三小时写 Landing Page(正常团队要做两周)的套路。

也在长篇写作领域,能够逆向开发出一个月写出一本书(一般作者写一本非理论书籍,要至少4-10个月以上)的框架。

诸如这类不可思议的极限输出效率。

机会只掌握在有职业输出水平的工作者身上

其实这些成果不是不可思议,而是对自己的基本要求。我认为身为「职业选手」,应该要对于自己的职业技能,出手程度有信心而且输出稳定。这样在关键机会时,你就可以打下成果。

甚至不只是在关键机会,而是在日常做事时,可以随时就有成果。就会有自信克服面前各种障碍。或者有头绪去解未知的挑战。

专家的水平是能够逆向找到万物的基本公式

很多人可能会认为将「瞬间出手」当作「最低水平」这种要求,实在太过严苛。

这一点都不严苛。大家会感到严苛的原因是,很少人这样做。但是真没你想像的那样辛苦。

这世界上会进行第一遍复盘的人,只有 10%。会进行第二遍复盘的人,又只有 10%。所以当你练到第三遍时,其实你的水准已经晋级同领域里的 0.1 %。

一件事情练到三遍,五遍,并且能够肌肉记忆扫除了所有实做上的坑后。你会开始发现万物都是有套路的。而用上这个套路,可能就已经比你第一次做的时候要快上 3-5 倍了。而练到这里,甚至都跟「跨出舒适区」无关,还是始终很舒适。

而在多深入几次实做场景,并且找寻科学依据倒推背后原理,还会开始发现些套路背后的道理。甚至可以推到最后简简单单一两条的公式。比如要写出吸睛的 Landing Page,背后的原理其实就是针对生物学的三个简单直觉问题而已。

这才是所谓的「刻意练习」。