第4章 格物致知:如何拓展技术技能
截至目前,我已经罗列了一长串的待拓展的技术技能,你现在可能急于想知道,你将如何拓展所有这些技能,以及这个过程需要耗费多长时间。
好吧,先不用担心时间的长短,只要你是一名软件开发者,你就一直都在拓展自己的技术技能。因此,就把拓展技能这件事看作是一次旅行吧,别当作是目的地。你会一直优秀下去,只要你愿意。
在很长一段时间里,我都在错误地拓展自己的技术技能。后来,在三年的时间里,我在Pluralsight创建了超过50门高级技术培训课程,我自己也学会了如何以飞快的速度自学技术技能并且教会别人。
回首往昔,我曾经以为,学习一门技术的最好方法就是拿起一本大部头的参考书,一口气从头读到尾。我读了太多大部头的书,每一本都有800多页,但这样的经历并没有给我带来多少好处,除了我的手臂可能会因为长期搬运这些大部头而长粗长壮。
我不想让你犯相同的错误,如果你已经如此,我会告诉你有一个更好的方法。
学习如何快速学习
在我们开始学习技术技能之前,我认为有必要花点儿时间讨论一下如何事半功倍地快速学习、如何触类旁通地自学。
在本篇的第5章中,我们将更深层次地讨论自学的主题。但是,这里我想快速向你介绍一下基础知识,并且讨论一下我用来快速学习任何东西的方法。
如前所述,我曾经花费大量时间学习和教授各种技术,乐此不疲。我在几个星期内学会了一门编程语言,旋即开始讲授关于它们的课程。在这个过程中,我开发了一个可靠的方法来学习任何我需要去学习的东西。
与其说是我有意为之,还不如说是被逼出来的。我不得不摸索出一种快速、高效的学习方法才能够以快速高效的方式工作,而且,顺理成章地,我摸索出的学习模式也促使我的学习效率越来越高。
在这里我只想介绍一些有关这种学习方法的基础信息,完整的内容我已经整理成《软技能:代码之外的生存指南》一书的一部分,题为“十步学习法”。
基本过程
“十步学方法”的基本思想很简单。从本质上讲,你要先确认你想要学习什么,即明确学习的范围。针对你确定的学习主题,你需要获取足够多的信息以纵览全局;然后,把主题聚焦到一个足够小的范围之内,这样你才能专心致志地去钻研,心无旁骛地去研修。
然后,你需要确定学习目标,即你需要明确你想学什么以及为什么要学,更为重要地,你将用哪些指标来确认自己确实已经学会了这些内容。人们都喜欢学习新东西,但是太多太多的人并没有合理的办法来衡量自己到底是学会了还是没学会。
在确定了学习目标之后,你就可以开始着手搜集学习资源了。
我的建议是:不要总是从头到尾阅读一本书,相反,你需要收集多种资源,其中可能包括书、博客、播客、杂志、视频课程和教程、专家专栏等。然后,你利用其中的一部分资源创建一个切实可行的学习计划。你可以利用收集到的资源,创建一个系统的而又井然有序的学习计划来研修你想要学的东西。例如,你可以应用你找到的某一本书的目录,来辅助确定你打算学习的内容的顺序和重要性。基本上,针对你的学习主题的所有内容,你需要确定一个学习的顺序。
然后,你就可以沉浸其中了。根据你的学习计划,开始学习关于你的主题的每一个模块。而对于每一个模块,你可以采用“学-做-学”的顺序来学习——学习一点内容,保证学到的内容足够完成一些实践任务;然后开始做一些实践演练,然后再回到内容当中,继续深入学习以便于能够解决你在实践当中遇到的任何问题。基本上,“做中学”的时候我们都会很专注。关于这一点我们一会儿再谈。
“学-做-学”的关键在于:开始的时候学习的东西不要贪多。相反,你要在自己演练的时候利用自然的好奇心来驱动你的学习。然后,带着你在实践中积累的经验和遇到的问题,再回到书本上,仔细研读这些学习资料。这样的学习方法会自然而然地引导你去寻找真正重要的东西。
在学习的时候,如果案头摆满一大堆材料,那么我们将面临一个大难题:我们不知道什么是重要的。通过实践,我们可以自己找到问题、自己解决问题,我们学到的东西才可以历久弥坚。
最后,把你学到的东西教给别人。把你学到的东西教给谁、怎么教,这些无关紧要。如果你不介意,你讲给你的狗或者院子里的松鼠听都可以。重要的是,你以某种方式重组你头脑中的知识,形成自己的思想,并且拿出来与外界交流。
如此这般。这个过程正是把学到的知识转化成为自己的理解的过程。这里我们罗列的学习知识的基本步骤,你可以应用于任何你想快速学习的东西上。
如果你想看一个更具体、更全面的示例,Simple Programmer网站上提供了一些文字资料和视频:“快速学习任何东西的十步学习法”。
现在,我们来重点谈一谈学习与技术技能拓展。
做中学
我笃信,从实践中学到的东西才是最好的东西;而且,当学习技术技能时,在实践中学习也是第一要务。
对大多数的技术技能而言,读读书本文字、看看视频教程这种简单粗糙的方法是不可能学会的。用这种方法学习,对于一项特定的技术、一门编程语言或者一种工具你只能略懂皮毛,只有在自己用过它并用它解决过实际问题之后,你才会摆脱略知一二的粗浅境地。
在第3章中,我谈道:每一件事都需要书本知识以外的更多实践,才能够获得真正的能力。
对学习编程语言而言,“做中学”的作用更是不言而喻的——只阅读一些语法你能真正学会如何利用源代码控制吗?
如果你从未犯过把文件合并到错误的分支上或签出源代码的错误版本这样的错误,又或者你从未实际利用源代码的版本历史来确认bug是从哪里引入的,你是不会真正明白如何利用源代码控制的——你只是自认为你明白了。(即使你现在还不明白如何利用源代码控制,也不用担心。)
我不是已经承诺在本书第三篇“关于软件开发你需要知道些什么”中会教你所有这些技术技能吗?现在你在阅读本书时,难道不是抱着想学点东西的目的吗?是的,没问题。但关键在于,学习并不止步于此。
你可以读我的话,并粗略理解我在这里谈论的一个话题。但在某些时候,你需要放下本书,立即采取一些切实可行的行动,这才是积极学习你所读到的内容的做法(至少是针对我们在这里讨论的技术技能学习方面)。
如何做中学
尽管你会觉得我又是对显而易见的内容翻来覆去反复强调,但我还是要告诉你如何真正做到“做中学”——你就把下面的内容看作对自己已经知道的事情的提醒吧。
无论何时,当你尝试要学习一项技术技能时,首先要明确的就是用它将帮助你做什么。如果你对这项技能没有直接的需求,你甚至会质疑“我为什么要学它”。相信我,如果把大量的时间都浪费在学习永远不会在现实世界中用到的技术技能上,我会很内疚的,这一点都不好笑。
如果你对某项技术有直接的应用需求,你对学习这项技术就拥有了真正的诉求,你学习它的时候也会感觉更轻松一些。
我敢肯定,如果拥有真正的应用诉求,你就会如饥似渴地学习,就像你在驾机飞上蓝天之前一定要学会跳伞一样。
但是,如果你没有迫切的需要该怎么办?如果某一种技术技能,只会在你找到一份工作之后才会被用到,这时又该怎么办?在这种情况下,你需要人为制造一个使用这种技能的理由——创造一个目标。
做中学的示例
让我们看一个真实的例子。假设你想了解关系型数据库,你想学会如何使用它们。你可以试着读一个数据库的使用说明,抱着随便玩玩的心态运行一些查询——嗯,这可能会有点儿效果。
如果你的目标是创建一个数据库来存储自己的一组电影,那该怎么办呢?如果你的目标是查询这个数据库,插入新电影,删除老电影,更新标题……又该怎么办呢?如果你想要创建一个简单的应用程序,让你拥有访问数据库的权限并完成所有这些操作,那该怎么办呢?好了,学习的目标有了,学习的路径也有了。现在你有工作要做了。
你如何学习关系型数据库?你阅读书籍,或者查看视频教程,寻找你需要知道的用于解决实际问题的具体信息。然后,你需要实际创建一个数据库,并且实际使用这个数据库(而不只是作为一项练习)。这才算是有了真正的目标。
想一想,当你以这种方式工作和学习时,你会掌握多少信息啊。
做中学,不亦乐乎?
我是怎样教别人技术技能的
正如我前面提到的,我曾经教过相当多的技术技能,覆盖多个技术领域。因此,我认为,如果你了解了我如何教别人技术技能,使学习这些技能的过程更加轻松,对你会有所启发的。这样,你就可以在自己教他们的时候应用这个方法。同意吗?
当我教技术技能的时候,我想要给人们带来的最大回报就是:我不想让他们感到厌烦,让一些无关紧要的学习内容变成他们的沉重包袱,我也不想教他们自己都可以学会的东西,让他们感觉味同嚼蜡。相反,我会把重点放在教那些能够立刻产生价值的东西,当他们需要深入研究一个话题的时候,我会给学生们必要的资源去实践我所说的“及时学习”。
当我教一项技术技能时,我主要尝试教会别人三件事。
●总体格局:你能用这项技术做什么。
●如何开始。
●你需要知道的只有20%是最有效的。
下面让我们把每件事都分别描述一下。
总体格局:你能用这项技术做什么
我总是喜欢从总体格局开始。
我相信谷歌能够解决你的大部分问题,但是如果你连问题到底是什么都不知道,就算是把谷歌摆在你面前你也不能搜索到结果。因此,我会先教我的学生关于一项特定技术的总体格局是怎样的,以及应用这项技术能够做什么。
总体格局这一块的介绍不需要特别详细。我并不会向你展示如何使用这项技术完成所有事情,我只是给你一个快速的指导,概要介绍一下这项技术最有价值的地方。
例如,对于一门编程语言,我可能会介绍它的历史以及它的主要用途;然后,我可能会介绍它的所有结构和特性——特别是独有的特性;最后,我可能会介绍它包含的各种类型的标准库,并介绍这些库所涵盖的内容以及你可以使用它们做什么。整个过程中,我的想法就是给你完整的格局,但却不深入细枝末节当中。
你总是可以自己查找你感兴趣的所有事物的细节。在这一步,我想消除所有“对未知的未知”,我要确保你已经知晓你对哪些东西一无所知,这样当你需要了解它时,你可以知道在哪里找到答案。
我的目标是:你不会说“哦,我不知道X能做这个。”而是说“我知道X能做到这一点。虽然我现在不确定该怎样去做,但是马上我会弄清楚的。”
想象一下,如果对电动打磨机或者刳刨这类工具都一无所知的话,怎么学会木工?你并不需要知道如何使用这些工具,但是如果连它们的存在都不知道,学习木工就是无稽之谈了。
如何开始
接下来我喜欢教学生如何开始。这通常是学习一项技术最难的部分——它是“做”的前奏,所以我想尽量让它变得不那么苦不堪言。
我会向每一位学生演示如何下载他们需要的东西,如何安装它,如何创建自己的第一个项目,以及如何编译他们自己写出来的代码。一旦能够克服这个障碍,接下来他们就可以随心所欲地使用这项技术实际构建一些东西。
如果让这个门槛看起来高不可攀,那么很可能有人就会转而捧起一本教科书或者观看视频教程,放弃真正的实践与操作。
你可以在自己学习的过程中充分利用这一方法,确保你在学习过程的早期就把注意力集中在发现如何开始应用一项特定的技术技能上。找一些专门展示如何开始动手做的教程或指南,你就可以从那里汲取到营养。
你需要知道的只有20%是最有效的
最后,我会试着引导学生明确:他们将会将80%或更多的时间用在关于一项技术的20%信息。
在生活中,几乎所有的事物都服从所谓的“二八原则”,即20%的东西产生80%的结果。学习一项技术技能的关键就是弄清楚那20%是什么。一项技术的20%就可以应对80%的工作场景,你能学会那20%吗?
实际上,“二八原则”的重要性主要还不是体现在理论上,如何践行“二八原则”才是至关重要的。许多书,甚至许多视频教程,都像参考手册一样写得面面俱到,并没有特别强调什么是技术的关键20%,而那20%才是最重要的。
如果你正在积极主动地应用一项技术,你很快就会发现应用场合最多的关键内容是什么,因为对这些内容了解不透彻的话将是极其痛苦的。
让我们回到之前的关系型数据库的示例。如果你透彻了解关系型数据库,你会发现,怎样编写SELECT语句十有八九就是那20%的关键内容。如果你只是读一本关于SQL的书,那么你可能会对选择、插入、更新、删除、索引以及其他各种各样的数据库功能给予同等的重视程度。但是,如果你真的尝试创建一个数据库并且使用它,那么你就会执行大量的SELECT语句,你就会很快发现,你需要学习如何连接数据表。
与其浪费时间去学习有关关系型数据库的所有知识,不如把精力聚焦在学习如何编写SELECT语句、如何连接数据表等20%的关键内容上。这就是“做”如此重要的原因。
“做”还可以通过追随专家的身影实现:像学徒一样辅助他们,近距离观察他们如何工作。通过观察使用你正在拓展的技术技能的人,观察他们的20%是什么,你就可以快速了解你需要知道的东西。这也是为什么岗位培训尤其卓有成效的原因。
阅读专家写的东西
关于如何拓展某项技术技能我的最后一项建议是:热衷于阅读那些这项技术技能的专家所撰写的文章。
当我学习技术的时候,我每天花大约30分钟阅读与我正在学习的主题有关的各种博客。当我想深入了解C++的时候,我天天都泡在Scott Meyers的Effective C++这本书中。
只是听取专家对某一主题的见解就能让你深刻领悟,而一个人冥思苦想却让自己时时陷入死胡同。这样的经历肯定屡见不鲜。
理解编程语言的语法、掌握如何使用某个框架是一回事,而深刻领会这方面的习惯用法是另一回事。
去研究专家是如何把你想要学的技术能力灵活地运用在现实世界中的,去阅读专家对一项复杂的技术技能的观点和评论,会加深你自己的理解和认知。
重要的事情说三遍:实践,实践,实践
希望我已经给了你一些学习和进一步拓展技术技能的有用技巧。至少,你应该对这一点铭记于心:通过实践来学习某项技术技能是至关重要的。你还应该非常清楚,你需要一个切实可行的学习计划和一个定义明确的目标——“我到底想学什么”。
现在,我只想强调一点——实践。拓展任何技术技能都需要时间。为了能对某项技能了然于胸,你必须要多多实践。
试着不要为学习某项技能的漫漫长路而感到沮丧(漫漫长路很多时候也只是表象),尤其是当你觉得自己没有取得任何进展的时候。只要你有明确的目标,肯投入时间切实执行自己制订的计划,结果一定是技能傍身。
坚持下去,相信“精诚所至,金石为开”。