第262期 | 如何快速且深入地学习一门新技术?
你好,这里是卖桃者说。今天是五一长假的最后一天,你还在听卖桃者说吗?
之前的精选都是极客时间的专栏,今天我想给你推荐极客时间的另一个产品:每日一课。
每日一课是一款“问题驱动”的问答类视频内容产品,我们希望通过一个10分钟左右的视频,帮助你解决工作中的疑难杂症,正常更新频率为每周4个。你可以把它看成视频类的 Stack Overflow。
另外,每日一课中还包含了极客邦科技主办的 QCon 全球软件开发大会、ArchSummit 全球架构师峰会等技术会议中的部分演讲视频。目前已经累计更新了 800+ 视频, 邀请了 500+ 国内外业界领袖和知名技术专家为大家上课。
今天,我给你挑选了颜群老师讲述的一个主题“如何快速且深入地学习一门新技术?”,这也是很多新入行的程序员最头疼的问题。
颜群是阿里云云栖认证专家兼特邀技术专家,对技术和学习有深刻的认知。
老师讲述中有涉及到代码的地方,你可以点击文稿查看代码。不过为了更好的学习效果,我推荐你直接观看文稿中的视频,会更清晰、更直观。
你好,我是颜群。
软件开发正处于快速发展的时代,新技术层出不穷,已有技术也在频繁更新。甚至有人调侃地说“新技术出现的速度,远大于个人的学习速度”。那么,在这个日新月异的互联网时代,软件开发者们,应该如何保持自己的竞争力呢?今天,我们就来聊聊,如何快速且深入地学习一门新技术。
大家可能都知道,英语考试中,有一个经典的题型叫“完形填空”。在我上高中的时候,英语老师就告诉我“在做完形填空之前,一定要先花1分钟左右的时间,快速地把整篇文章阅读一遍。这样就会对全文的内容有一个大致的了解。之后再去做题,准确率就会提高不少”。
我认为,这种做英语完形填空的方法,也同样适用于学习软件技术。我们在学习某一个新技术时,也应该先快速地去了解这个新技术的大致情况,之后再仔细地研究这个新技术到底包含了哪些内容,也就是从整体深入到细节。
例如,Java基础中的JDBC、Web前端中的HTML、框架技术中的Netty等,这些技术都有一个特点就是:可以遵循一定的“套路”去编写。因此,我认为好的学习方法应该是,先不管三七二十一,快速地去了解一下具体的“套路”是什么,然后再深入研究“套路”中的每一步到底是什么意思,这样才能高效地学习一门新技术。
比如HTML,不管你要布局什么样的页面,你都得先把<html>、<head>、<body>等标签搭一遍,之后才能编写你想要实现的代码。
再比如JDBC,无论你是要进行什么样的数据访问操作,每次都得先加载驱动;然后获取连接对象;之后是创建一个操作对象;最后再处理结果。可能细节上会稍有不同,但整体的流程一定是这么几步。
再看一下Netty,虽然Netty的实现要稍微复杂一些,但是每次的开发步骤也都几乎是一致的。基本上你只要编写过一次Netty,下次再编写时,就可以把上次的代码结构先复制过来,然后修改业务逻辑就行了。你看,不论是前端技术、基础技术,还是框架技术,是不是都存在着我们刚才说的“套路”呢?
这说明了什么呢?至少说明了一件事儿,在学习新技术之前,我们一定得先宏观地、全局性地了解一下技术全貌,这样才能清晰地了解哪些是技术重点,哪些仅仅是“套路”而已。
那么这时你可能会问了,我该如何快速地浏览技术全貌呢?这其实是“快速阅读”的理论知识了,推荐大家可以通过快速地、跳跃性地查阅资料的方式,看下新技术的实现流程大致是什么样子的。具体细节,你可以查阅技术官网、看书、看博客、看教学视频等等各种方式都行,重点看那些反复出现的重复代码。一般而言,那些重复频率较多的代码,就是这个新技术的基础代码结构了。
好,在对一个新技术有了宏观的认识后,接下来就可以正式进入深度学习阶段了。一般而言,我们可以通过文档等资料,轻松地实现一个入门级别的Hello World程序。接着就可以不断地丰富这个Hello World,并让它最终变成一个丰富的案例库了。
现在,就拿我自己学习Netty的亲身经历来讲一下。先说说我当时所面临的一个情况吧,以前,我在做一个项目时,用到了一些NIO和网络编程技术,但由于项目交付的时间很紧,并且相关的代码量也不是特别多,所以当时我就没有多想,直接手写了与项目相关的NIO和网络编程技术。
后来,在那个项目刚刚发布第一版之后,为了找到一些后续版本在性能方面的改进思路,我就上网搜索了一下项目中经常使用到的一些NIO API,然后发现在很多出现NIO的页面中,都能看到“Netty”字样的相关词条。显然,Netty与NIO之间必然有着很大关系。于是我就顺手查了下关于“Netty”的简介,发现它是一款“高性能的、基于NIO的网络编程框架”。当时就很自然地有了一个想法,以前做项目时,手写的NIO和网络编程,好像就可以用Netty来替代。
于是,为了验证这个想法到底是不是真的可行,我就在之后的一段时间开始了关于Netty的学习。由于当时刚刚才做完项目,身体比较疲惫,就采用了看视频的方式,以便于减轻自己的脑力开销。当时我找了一个评价不错的视频,用倍速播放、跳跃性拉进度条的方式,用2个小时大致地看了看那套视频的核心内容。然后得到了一个心得:Netty的Hello World,并不像其他技术那么简单,但和其他技术一样,有着标准的代码编写模板和编写流程。
具体来说,几乎每次在编写Netty代码时,我们都需要经过这么几步:通过一个类似server()的方法,将Netty的流程组织起来,然后调用自定义初始化器,接着再在自定义初始化器中根据业务需求,加入一些Netty内置的处理器。对于那些Netty没有提供的处理器,就编写自定义处理器去解决。最后再在自定义处理器中,实现具体的处理逻辑就可以了。
public static void server() {
...
ServerBootstrap serverBootstrap = new ServerBootstrap();
ChannelFuture channelFuture = serverBootstrap
.group(...)
.channel(NioServerSocketChannel.class)
.childHandler(自定义初始化器).bind(端口号).sync();
channelFuture.channel().closeFuture().sync();
...
}
//自定义初始化器
public class MyNettyServerInitializer extends ... {
protected void initChannel(SocketChannel sc)throws Exception{
ChannelPipeline pipeline=sc.pipeline();
pipeline.addLast(netty内置处理器);
pipeline.addLast(自定义处理器);
}
}
//自定义处理器
public class MyNettyServerHandler extends ... {
@Override
protected void channelRead0(ChannelHandlerContext ctx, HttpObject msg){
业务逻辑
}
}
有了这种对Netty的整体认识后,我就能很轻松地实现一个基于CS架构的Hello World了。Hello World实现之后,心里就消除了对Netty的陌生感,并且有了一定的成就感。
但Hello World仅仅算作是一个快速入门,要想真正地掌握Netty,必然还得进行深入的学习。那么该如何深入呢?我认为,通过案例来倒逼对理论的理解,是一个很好的方法。于是,我就正式地开始了对Netty案例库的搭建,我先是把这个Hello World,扩展成了一个点对点通信的demo,成功之后,再把它升级成了一个聊天室案例。做完后,还给它加上了心跳监测机制,并结合Protobuf组件实现了一个RPC功能。
像这样,我每次只实现一个很小的功能模块,但随着持续的积累,这个Hello World,就会变成一个包含了Netty各种功能的案例库。当这个案例库编写完成时,我对Netty就已经很熟悉了。

这里我来做个小总结,关于我自身学习Netty的流程,再来简单梳理和回顾下,希望大家可以从中获得些许启发,一定程度上帮助你最终找到一种适合你自己的学习方法:我在准备升级项目时,发现可以用Netty改进;然后通过快速学习两小时,了解了Netty的整体流程;接着,再从Hello World开始,逐步积累了Netty案例库,最后,当案例库搭建完成的时候,我也在大脑里形成了自己对Netty的思维框架图。
好,相信通过前面的讲解,你已经清楚了如何快速掌握一门新技术的方法了。但还有两个重要的问题需要解决:一个是,对知识的掌握的足够吗?另一个是,刚学会的新技术,会不会很快又给忘掉了?
我觉得,这其实可以借鉴我们上学时的方法:考试。考试是检验知识掌握程度和是否遗忘的最好方式了。但要想真的落实自己给自己“考试”这件事儿,也是很困难的,谁来出题?谁来阅卷?所以,我们得把“考试”的方法,换个方式体现出来。
这里我建议的一个方式就是做微服务案例。可以先用每个新技术搭建一个独立的微服务,然后再把由各个不同技术搭建的微服务,整合起来。举个例子,当你学完SSH时,就用SSH搭建一个“用户管理”的微服务;当你学完SSM时,再用SSM搭建一个“支付结算的微服务”;当你学完Spring全家桶时,再用Spring系列技术搭建一个“购物微服务”,等等。
同时,当你每搭建一个微服务之后,还需要把这个微服务,通过RPC技术和其他微服务整合起来。例如,用Spring全家桶开发的“购物微服务”,调用SSH搭建的“用户管理微服务”,再用这个“用户管理微服务”远程调用SSM搭建的“支付结算微服务”,也就是将所有的技术都整合在同一个案例中。

这么做,一方面,可以通过动手开发的方式来做项目,对已掌握的技术进行查漏补缺。因为,在开发这些微服务案例的同时,你就会清晰地了解到这些技术中,哪些是重点,哪些是次重点,哪些是自己学的时候遗漏掉的内容,从而可以解决刚才第一点里提到的,有关于知识掌握得够不够的问题。
另一方面,这种微服务项目,可以保持我们对所有技术的新鲜度。例如,SSH搭建的微服务,可能是你半年前就实现好了的,但你现在用SSM调用SSH时,就必然会涉及到一些对SSH代码的联调操作,而在这个联调的过程中,你也会自然而然地对半年前的SSH项目,进行一次复习。因此,这也可以解决刚才第二个“防止遗忘”的问题。
到这里,相信大家已经掌握了一种持续学习的方法了。最后再与大家探讨一下,如何学习难点技术。我们可以将难点技术分为两类,一类是偏理论型的,一类是偏实战型的。先看看第一类,也就是对于偏理论型的难点技术,该如何去学习。
像数据结构和算法、设计模式,以及架构设计等等,都是较为难理解的偏理论型技术,这些也经常成为初级开发者进阶路上的绊脚石。那么如何才能顺利地跨越这些障碍呢?
我认为可以采用“先拆解目标,再集中消化”的学习方式来学习这类技术。举个例子,对于算法、设计模式等较为难理解的技术来说,尽量不要想着花一周或者一个月,就把它们彻底搞懂。而应该先计算一下学习的知识数量,然后碎片化地学习。再举个例子,假设你想要学习算法,那就得先计算一下一共有多少个算法需要学。
比如有30个,那就再把这些算法,根据难易程度进行排序,然后从简单的学习,慢慢过渡到较难的算法。至于哪些算法简单,哪些又比较难,相信大家通过搜索引擎就可以轻松地得到结论了。当有了难易程度的排序后,再用碎片化时间,将那30个算法逐个攻破。
比如,在上下班的地铁上、晚餐后的半小时,或者睡前的一段时间,利用一些碎片化的时间去学习某个算法,将业余时间进行合理地安排和规划,其实碎片化的时间很容易减轻自己学习上的畏难情绪。而且,我们每天的碎片化时间其实是很多的,如果真的能够被高效利用起来,相信你一定能在不知不觉中,攻克掉很多难点。
当你感觉自己对技术内容理解得差不多的时候,再用一个比较集中的时间,把它彻底消化掉。之后,再学习下一个。
好,刚才说的是如何学习偏理论型的难点技术。接下来再来聊聊如何学习偏实践型的难点技术。这里称为“实践”,是因为有些技术,必须借助于开发工具,来追踪代码或者调试才能掌握的。就比如说,阅读一个框架的源代码,就是偏实践型技术的一个典型代表了。
对于偏实践型技术的学习,最主要的就是“要在实践前,心里已经对实践的内容有了清晰的理论基础,要把动手实践仅仅看成是一种揭晓谜底的感觉”。这里给大家还原一下我学习MyBatis框架源码时的情况。
当时在阅读MyBatis源码之前,我已经对MyBatis的应用非常熟悉了,因此清晰地知道MyBatis的执行是怎样的,也就是需要先经过“获取SqlSessionFactory对象” 和“获取SqlSession对象”这两步。所以,我的思路就是:先写一个最简单的MyBatis程序,然后分析这两步源码的底层,到底是怎么执行的。这其实也就是我刚才提到的,我在读MyBatis之前,已经知道了MyBatis大致的执行步骤,现在仅仅是想通过阅读源码,亲眼见一下底层到底是怎么写的而已。
于是,我通过debug进入源码,也就是打开了“获取SqlSession对象”的底层源码,然后随着debug的步骤,依次进入了build()、parse()、parseConfiguration()等方法,并在parseConfiguration()方法中,看到了typeAliases、plugins、environments、mappers等名字,显然这些名字就是我们最常用mapper配置文件中的标签名。
结合MyBatis的基础知识,很容易知道,MyBatis的底层,是通过parseConfiguration()方法在解析mapper配置文件,因此我们就只需要深入研究parseConfiguration()的每一步实现,就能知道MyBatis对于解析mapper配置文件的底层源码实现了。
当然,考虑到每个人对技术基础的掌握情况是不一样的,每门技术也有很大程度的不同,所以不同的人在学习不同的技术时,可能会存在着或多或少的个性化差异。但我相信学习新技术的整体思路是一样的,就是先快速地进行整体阅读,然后再逐步积累、逐步深入,可以说,这一定是一套很不错的较为有体系的方法论。
好,那么到现在,如何学习难点技术的方法也讲完了。现在,再给大家介绍一个关于营造学习气氛的方法。很多时候,开发者在学习时都是很孤独的,都是一个人趴在电脑前。一定程度上来讲,个人学习的气氛就没有团体的好。大家想想,是不是在高中的自习室,或者大学图书馆里的学习气氛,就感觉要好很多呢。所以,如果你有很多志同道合的朋友,可以邀请他们一起共同学习。
但如果不方便,你也可以注册一个微信公众号,或者技术博客,再或者将自己学习的项目部署在云端,然后开放给大家一起访问。
总之,就是要想办法,将自己的学习成果分享出来,让大家一起来阅读,或者说监督你的学习。并且你也可以通过“留言”功能,与大家互动。如果你是讲师,那么可以把一些学到的东西录制成视频,然后发布出去。
坚持这样做,除了能够营造出自学的气氛以外,还可以将自己学到的技术沉淀下来,慢慢地,也会为自己吸引到一批技术爱好者,从而提升自己的影响力。是不是一举多得呢?
好,今天的分享到这里就结束了,在学习新技术时,我们可以先快速地了解技术的宏观内容,然后从Hello World开始,逐步地搭建一个案例库,从而掌握技术的广度和深度。
当案例库搭建完以后,再通过微服务技术和其他技术进行整合,形成一张更大的知识网络,从而让自己长期接触到这些技术,防止遗忘。此外,对于偏理论型的难点技术,建议大家“分而治之”,用碎片化的时间逐个攻破,减少自己对难点的恐惧心理;而对于偏实践型的难点技术,需要在实践前,心里已经对实践的内容有了清晰的理论基础。最后,建议大家将自己学到的技术分享出去,做好技术沉淀的同时,也能不断提升自己的知名度。

目前每日一课已经有 800 多个类似的视频,采用的学习方式是订阅制,如果你感兴趣,可以先订阅一个月试试学习效果。同样,我为你申请了优惠口令,具体使用方式参见文稿。
卖桃者说,明天见。
- 优惠口令:meiriyike
- 适用栏目:每日一课
- 使用规则:立减 10 元(满 20 元可用)
- 有效期:5 月 5 日 00:00 - 5 月 31 日 24:00
(编辑:夏天)