作者李运华,阿里游戏资深软件工程师

有的人想成为大牛,却不曾为此努力。有的人辛苦耕耘,却收获寥寥。很多时候,你跟成功的差距并不是能力,也不是运气,或许只是正确的方法?这是一篇不鸡汤的成功学指南,如果你相信且愿意坚持尝试,未必帮不到你!

一篇不鸡汤的成功学实践_软件工程师

一碗有勺子的鸡汤

我工作已经将近 12 年了(其实 12 年才混到这个地步,天资实在是一般),在华为做了 5 年,在 UC 做了 6 年,现在主要负责阿里游戏的中间件和组件的架构设计和实现,包括用户消息推送、系统异步通知系统等等。

同时我还带了三四十人的研发团队,除了工作以外,我也喜欢写博客,是 CSDN、云栖的社区之星和博客专家,InfoQ 的签约作者。

总体上来说,我现在虽然还算不上业界顶级的大牛,但在公司也算一头小牛了,今天我的分享将综合自己的成长经历给大家谈一谈怎么样成为一个大牛。我现在还在业界的大牛路上狂奔,但我觉得这些经验和技巧应该是每个同学都可以用到自己的日常工作和生活当中的。

一鸣惊人背后是 1 万小时的不断练习

如何成为大牛?这个问题之前有很多人问我:你是怎么成为技术上的一个大牛的?

最开始的时候我也经常跟他们讲你要去看看某某某开发方案,深入学习 UNIX 的开发等等这些“术”的东西,后来我在思考,是否有成为一种大牛的“道”上面的东西,也就是说不管你做产品、做运营、做运维、程序员还是测试,通过这个方式都能够成为一个大牛呢?

通过寻找和思考,后来真的让我找到了应用到所有行业、所有职业我称之为成为大牛的一个道,这是 1 万小时理论。

我先简单介绍一下 1 万小时理论,我最初看到 1 万小时理论是从《异类》这本书知道的,这是很出名的书,它非常有意思,我建议所有同学都去看一下,它分析了很多成功人士背后一些我们通常情况下不了解或没看到的一些现象,得出一些比较令人震撼的结论,其中有一个理论就是 1 万小时理论。

它里面有举了一些例子,比如说莫扎特,大家都知道他是音乐神童,6 岁就开始作曲了,你看完这本书就知道他真正出人头地是 20 多岁的时候,也就是说他虽然 6 岁开始作曲,但他当时作的曲也是比较不好的。

所以《异类》这本书里面提到了 1 万小时的理论,它对我是很有帮助的,成为世界上顶级的专家唯一的方法就是 1 万小时持续不断地进行练习,大家要特别注意“唯一”,也就是说绝大部分专业是没有什么天才的,所谓的天才只是他一鸣惊人之后我们才这样觉得,在他成为天才之前至少要经过 1 万小时持续不断的练习。

我第一次看到 1 万小时的理论,觉得没什么神奇的,我算了算,我工作五年就会成为业界顶级的专家了,但想想这是不可能的,为什么呢?我反思了一下我自己的工作状态,对于大部分人来说每天的工作很多时候是重复劳动,虽然我们一天工作 8 小时,但是只是重复以往的经验,并没有刻意去训练提升自己。

有一个笑话是有一个 10 年工作经验的人去面试,面试完了之后面试官跟他说其实你只有 1 年工作经验,你把它重复了 9 年。

对于 1 万小时理论来说如果你深入思考其实它并没有那么简单,这意味着什么呢?意味着你每天要花 3 小时时间用于提升自己的技能,这样一直做,要持续大约 10 年时间。大家想想每天持续十年去做一件事情去提升自己,有几个能做到,所以我们看到虽然有些人工作了 10 年,但是也不一定能成为业界的专家。

为什么我要强调每天 3 小时?持续 10 年提升自己,你不能把你重复的工作算进去,你要在专业广度和深度上面不断扩展,才能业界一个顶尖的大牛或者专家。

举一个例子,一个小孩子每天唱《两只老虎》,唱 10 年,你觉得他会成为周杰伦吗?肯定不会。当然 1 万小时理论不适合一些领域,尤其是不适合炒股,特别是中国的股市,如果你花 1 万小时去炒股,可能会倾家荡产。

如何找到 10000 小时?

碎片化时间管理

1 万小时理论听起来好像很简单,每天持续 3 小时,也不难,但实际上真正做起来是很难的,就像我们互联网的人加班加成狗,感觉身体天天被掏空,时间从哪来,这是一个现实问题,不要说每天抽 3 个小时提升自己,每天抽 1 个小时陪女朋友或者找女朋友的时间都不够。具体怎么做?

首先是找到 3 个 30 分钟:

  1. 第一个 30 分钟就是早上的 30 分钟,假设你习惯 8 点起床,明天你把闹钟改成 7 点半,这就多了半个小时。

  2. 第二个 30 分钟是睡觉前的 30 分钟,假设你习惯玩游戏到 12 点,明天晚上你玩游戏就玩到 11 点半。

  3. 第三个 30 分钟就是上班到你座位上的 30 分钟,有的同学担心说我这 30 分钟会不会影响我这一天的工作效率,可能加班完不成,还让我挤出 30 分钟来,这不用担心,从我的经历来看挤 30 分钟不会影响你整体的工作效率,持续一两年,你会发现自己的收益非常大。

第二点是利用或节省路途时间

我们每天上下班都是一两个小时,比如像我这种,怎么去利用时间呢?

首先是可以利用上下班路上的时间去看书、听书,也是可以做的。如果你觉得上班路上是不能看书的,或者是不可能学习的,比如你坐广州的 3 号线,这是举世闻名的挤得要命的,不要说看书了,把手伸出去都不知道去哪了,那就建议大家搬到离公司近一点位置,虽然每个月多几百块钱的房租,但是你要相信这个投资节省下来的时间用于提升自己,它最终的收益是 10 倍回报都不止的。

第三点是周末 4 小时

周末还是不用怎么加班的,周末用于放松、睡觉、看电影、娱乐,你也可以在周末里面规定自己挤出 4 个小时,也就是每天 2 个小时,这样算下来,一天大概就两个多小时,再加上你在工作中的积累,每天 3 小时也不是很难。

接下来讲一下我是怎么做的,我现在有 2 个小孩,而且我住的比较远,应该在座的比我忙的也不会很多,看一下我是怎么做的,我是坐广州的四号线,坐四号线每天来回可以看一个小时的书,每天早晚 30 分钟,周末 4 小时,有的同学可能会有疑问,周末肯定要带小孩玩,自己也要休息,哪里有 4 个小时,其实只要你去找,时间都会有的,我找的方法就是当我小孩睡觉的时候,因为小孩子睡觉一般要睡三四个小时,大人一般睡一个小时、半个小时就差不多了,所以通过这种方式,大家可以看到 2015 年我一共看了 84 本书,有专业的,也有非专业的,人文社科、历史这些都有。

不过特别提醒一下对于男程序员来说有一个时间千万不能少,就是陪女朋友的时间,因为对程序员来说找女朋友不容易,别看了这篇文章回去之后女朋友也不要了,就天天回去提升,这也不是我们想要的生活。

10000 小时理论如何轻松落地?

虽然理论上很简单,但真正要落地实行也并不那么容易,实行 10000 小时理论的关键在于坚持,我认为坚持的关键在于自己对于所从事的事业是否有“激情和兴趣”。这点当然是核心,但如果只靠激情支撑,持续 10 年也确实有挑战,正如一个朋友在分享会后问我的“要持续 10 年才能成为大牛啊,时间好长啊”!

如果说做一件事要 10 年后才能修成正果,估计很多朋友就会放弃了,毕竟像唐僧那么坚定的信仰者总是少数,大部分凡夫俗子都还是需要持续不断的激励才能有动力去做一件事,因为我们的大脑在进化的过程中已经形成了需要持续不断的奖励才能保持兴奋的机制,也就是说相对于在第 10 年给一个大奖励,还不如每年给一个小奖励。

那如何才能在 10 年漫长的路上让我们持续的坚持下去呢?答案其实就是首富的话:“先定一个能达到的小目标”!我们来看如何将“10 年成为大牛”这个目标分解为一个个能达到的小目标。我将这个方法归纳为“三段分解法”,即:将一个宏大或者长远的目标经过 3 次分解,得到一个个短期内能达到的小目标。具体的分解方法如下。

一段分解:分解“等级”

10 年成为大牛的目标虽然比较长远比较宏大,但并不意味着在没有成为大牛前,我们一直都是菜鸟。从菜鸟到大牛的过程中,中间其实有几个关键的里程碑,这些里程碑就是我们的一段目标。

以技术人员为例,技术人员典型的发展路径基本上都是下面的这个模式:

1) 0 ~ 1 年:菜鸟,需要别人手把手来教

2)1 ~ 3 年:初级,需要别人带你做

3)3 ~ 5 年:高级,能独当一面,可以带初级技术人员了

4)5 ~ 8 年:资深,能独挡多面

5)8 ~ 10 年:大牛,统筹规划,高屋建瓴

通过上面的分解我们可以看到,虽然说 10 年才能成为大牛,但是 3 年就可以达到初级水平,5 年就可以达到高级水平,8 年就可以达到资深水平,在这个过程中我们一直在成长和提升,而不是说没有成为大牛就是菜鸟;并且对于很多朋友来说,如果目标不是像首富那样要赚就赚 1 亿,能达到高级或者资深水平,其实已经可以过得比较滋润了。

通过这种分解方法,再核对一下自己目前所处的位置,然后先瞄准下一个目标,全力以赴其实也就 2 ~ 3 年时间,这样来看一段目标其实是比较容易达成的。这种目标分解的方法除了适合技术人员外,其它很多领域也都适应,比如说产品人员、运营人员、甚至公务员!

二段分解:分解“技能”

经过一段分解后,明确自己目前所处的位置和下一个目标,接下来就要看这个一段目标如何实现了。虽然说每个一段目标持续时间在 2~3 年,但 3 年时间说长不长,说短也不短,如果没有好好利用,可能到了 2 年多的时候回头一看,好像什么都没达成,还是原地踏步。因此,为了更好的利用这 3 年时间,我们需要进一步分解,这就是“二段分解”。

一段分解的维度是等级,二段分解的维度则不一样,不能再分等级了,否则等级太细就没法区别了。二段分解的维度变成了“技能”,即:为了达到一段目标,我需要具备什么样的技能。

还是以技术人员为例,假设经过自我评估,认为自己目前处于初级阶段,而且初级阶段的事情已经做得比较顺手和熟练了,那么下一个一段目标自然就是达到“高级”水平。“高级”与“初级”相比,有哪些不同的技能要求呢?

这就需要我们根据各自不同的行业和方向详细列出来了,如果自己想不出来,网上有很多资料都可以搜索到,最方便的就是到一个招聘网站,多看看几个招聘需求的描述,然后归纳总结一下。

我们随便到网上搜索一个,例如拉勾网上滴滴的“高级 Java 开发工程师”招聘:

一篇不鸡汤的成功学实践_软件工程师_02

多看几个类似的职位招聘,基本上我们就能明白“高级 Java 开发工程师”的一些基本要求。当然实际上的技能要求比招聘需求的描述还要更加细致,我个人的习惯是将这些要求整理为一个思维导图,详细列出每个技术点。例如:

一篇不鸡汤的成功学实践_软件工程师_03

注意:以上这个图只是示例,并不是说所有 Java 高级工程师都一定是这个要求,例如互联网行业和电信行业的要求不一样)

有了这样一个思维导图后,我们就可以开始真正进行二段分解了,分解的方法很简单:哪里不懂补哪里!例如:我感觉目前我的数据库水平一般,仅仅会写 CRUD 语句,其它的东西都不懂,那我就开始专攻数据库这一部分,经过一段时间的专攻来提升自己的水平。

二段目标持续时间一般建议是 6 个月,既不能太短也不能太长。太短容易让人陷入为了目标而做的误区,没有真正得到有效提升;时间太长的话,3 年时间又不够完成其它目标了,例如要是我定一个目标说 2 年提升数据库,那操作系统怎么办?网络怎么办?……等等。以 6 个月为一个周期,基本上刚刚好。

经过分解,最终的二段目标可以分解为如下的几个更小的目标:

1)2016.06 ~ 2017.01:提升数据库水平

2)2017.01 ~ 2017.06:提升 Linux 水平

3)2017.06 ~ 2017.12:提升网络和网络编程水平

当然,二段分解目标并不是一成不变的,很多时候需要根据我们工作的内容进行调整。例如老大正好安排我来负责优化系统性能,降低机器负载,那么我完全可以将“提升 Linux 水平”安排到“提升数据库水平”之前。

三段分解:分解“行动”

二段分解得到技能的小目标后,接下来的关键就是要实现这个目标,这就是三段分解的主要目的,即:将技能目标分解为具体要做的事情,然后按照计划执行。

比如说我的二段目标是“提升 Linux 水平”,那怎么样才能提升呢?可以上网搜索(知乎是个好地方),也可以去问有经验的朋友。明确要做的事情后,三段分解需要将二段分解的 6 个月目标更加细化,分为 1 个月或者两个月一个目标。

以我当时加入 UC 的情况为例,我在华为的时候是在 Windows 平台上用 VC6 进行开发,而到了 UC 的时候是在 Linux 平台上用 C++ 开发,我当时定了“提升 Linux 水平”的目标,然后通过上网查,找别人问等方法,最终将这个目标分解为几个步骤:

1)1 个月:通读《UNIX 环境高级编程》

2)1 个月:通读《Linux 系统编程》

3)2 个月:通读《UNIX 网络编程卷1》

4)1 个月:Linux 常用命令实战:tcpdump、ps、top 等

通过这种方法,将 6 个月的目标又进一步分解为 1 个月的目标,实施起来就简单多了,每 1 ~ 2 个月专注一个具体目标,每次完成后都很有成就感,既感觉自己的水平有了提升,又佩服自己能够坚持按计划按目标完成任务,双重奖赏让自己更有动力进行下一个目标。

我大约花了 2 年的时间将 Linux、网络、MySQL 三个重点技能从一无所知提升到高级的水平,很多同事都问我之前在华为是不是就是做这方面的,因为他们觉得短时间能达到这个水平是不太可能的。

综合前面的分析,我们将三段分解提炼一下:一段分解“等级”,二段分解“技能”,三段分解“行动”。通过前面我们的案例就可以看出,原本一个宏大的“10 年成为技术大牛”的目标,经过三段分解,最终得到的是 1 ~ 2 个月可执行的具体行动,通过这种一步一个脚印的行动,最终就可以达成“10 年成为技术大牛”的目标。

天天写业务代码,如何成为技术大牛?

几个典型的误区

拜大牛为师

知乎上有人认为想成为技术大牛最简单直接、快速有效的方式是“拜团队技术大牛为师”,让他们平时给你开小灶,给你分配一些有难度的任务。我个人是反对这种方法的,主要的原因有几个:

  • 大牛很忙,不太可能单独给你开小灶,更不可能每天都给你开 1 个小时的小灶;而且一个团队里面,如果大牛平时经常给你开小灶,难免会引起其他团队成员的疑惑,我个人认为如果团队里的大牛如果真正有心的话,多给团队培训是最好的。然而做过培训的都知道,准备一场培训是很耗费时间的,课件和材料至少 2 个小时(还不能是碎片时间),讲解 1 个小时,大牛们一个月做一次培训已经是很高频了。

  • 因为第一个原因,所以一般要找大牛,都是带着问题去请教或者探讨。因为回答或者探讨问题无需太多的时间,更多的是靠经验和积累,这种情况下大牛们都是很乐意的,毕竟影响力是大牛的一个重要指标嘛。然而也要特别注意:如果经常问那些书本或者 google 能够很容易查到的知识,大牛们也会很不耐烦的,毕竟时间宝贵。经常有网友问我诸如“jvm 的-Xmn 参数如何配置”这类问题,我都是直接回答“请直接去 google”,因为这样的问题实在是太多了,如果自己不去系统学习,每个都要问是非常浪费自己和别人的时间的。

  • 大牛不多,不太可能每个团队都有技术大牛,只能说团队里面会有比你水平高的人,即使他每天给你开小灶,最终你也只能提升到他的水平;而如果是跨团队的技术大牛,由于工作安排和分配的原因,直接请教和辅导的机会是比较少的,单凭参加几次大牛的培训,是不太可能就成为技术大牛的。

综合上述的几个原因,我认为对于大部分人来说,要想成为技术大牛,首先还是要明白“主要靠自己”这个道理,不要期望有个像武功师傅一样的大牛手把手一步一步的教你。适当的时候可以通过请教大牛或者和大牛探讨来提升自己,但大部分时间还是自己系统性、有针对性的提升。

业务代码一样很牛逼

知乎上有的回答认为写业务代码一样可以很牛逼,理由是业务代码一样可以有各种技巧,例如可以使用封装和抽象使得业务代码更具可扩展性,可以通过和产品多交流以便更好的理解和实现业务,日志记录好了问题定位效率可以提升 10 倍……等等。

业务代码一样有技术含量,这点是肯定的,业务代码中的技术是每个程序员的基础,但只是掌握了这些技巧,并不能成为技术大牛,就像游戏中升级打怪一样,开始打小怪,经验值很高,越到后面经验值越少,打小怪已经不能提升经验值了,这个时候就需要打一些更高级的怪,刷一些有挑战的副本了,没看到哪个游戏只要一直打小怪就能升到顶级的。

成为技术大牛的路也是类似的,你要不断的提升自己的水平,然后面临更大的挑战,通过应对这些挑战从而使自己水平更上一级,然后如此往复,最终达到技术大牛甚至业界大牛的境界,写业务代码只是这个打怪升级路上的一个挑战而已,而且我认为是比较初级的一个挑战。

所以我认为:业务代码都写不好的程序员肯定无法成为技术大牛,但只把业务代码写好的程序员也还不能成为技术大牛。

上班太忙没时间自己学习

很多人认为自己没有成为技术大牛并不是自己不聪明,也不是自己不努力,而是中国的这个环境下,技术人员加班都太多了,导致自己没有额外的时间进行学习。

这个理由有一定的客观性,毕竟和欧美相比,我们的加班确实要多一些,但这个因素只是一个需要克服的问题,并不是不可逾越的鸿沟,毕竟我们身边还是有那么多的大牛也是在中国这个环境成长起来的。

我认为有几个误区导致了这种看法的形成:

1)上班做的都是重复工作,要想提升必须自己额外去学习

形成这个误区的主要原因还是在于认为“写业务代码是没有技术含量的”,而我现在上班就是写业务代码,所以我在工作中不能提升。

2)学习需要大段的连续时间

很多人以为要学习就要像学校上课一样,给你一整天时间来上课才算学习,而我们平时加班又比较多,周末累的只想睡懒觉,或者只想去看看电影打打游戏来放松,所以就没有时间学习了。

正确的做法正好相反:

首先我们应该在工作中学习和提升,因为学以致用或者有实例参考,学习的效果是最好的;其次工作后学习不需要大段时间,而是要挤出时间,利用时间碎片来学习。(参照前文 10000 小时理论)

正确的做法

Do more

做的更多,做的比你主管安排给你的任务更多。

我在 HW 的时候,负责一个版本的开发,这个版本的工作量大约是 2000 行左右,但是我除了做完这个功能,还将关联的功能全部掌握清楚了,代码(大约 10000 行)也全部看了一遍,做完这个版本后,我对这个版本相关的整套业务全部很熟悉了。经过一两次会议后,大家发现我对这块掌握最熟了,接下来就有趣了:产品讨论需求找我、测试有问题也找我、老大对外支撑也找我;后来,不是我负责的功能他们也找我,即使我当时不知道,我也会看代码或者找文档帮他们回答……最后我就成了我这个系统的“专家”了。虽然这个时候我还是做业务的,还是写业务代码,但是我已经对整个业务都很熟悉了。

以上只是一个简单的例子,其实就是想说:要想有机会,首先你得从人群中冒出来,要想冒出来,你就必须做到与众不同,要做到与众不同,你就要做得更多!

怎么做得更多呢?可以从以下几个方面着手:

1)熟悉更多业务,不管是不是你负责的;熟悉更多代码,不管是不是你写的

这样做有很多好处,举几个简单的例子:

  • 需求分析的时候更加准确,能够在需求阶段就识别风险、影响、难点

  • 问题处理的时候更加快速,因为相关的业务和代码都熟悉,能够快速的判断问题可能的原因并进行排查处理

  • 方案设计的时候考虑更加周全,由于有对全局业务的理解,能够设计出更好的方案

2)熟悉端到端

比如说你负责 web 后台开发,但实际上用户发起一个 http 请求,要经过很多中间步骤才到你的服务器(例如浏览器缓存、DNS、nginx 等),服务器一般又会经过很多处理才到你写的那部分代码(路由、权限等)这整个流程中的很多系统或者步骤,绝大部分人是不可能去参与写代码的,但掌握了这些知识对你的综合水平有很大作用,例如方案设计、线上故障处理这些更加有含金量的技术工作都需要综合技术水平。

“系统性”、“全局性”、“综合性”这些字眼看起来比较虚,但其实都是技术大牛的必备的素质,要达到这样的境界,必须去熟悉更多系统、业务、代码。

3)自学

一般在比较成熟的团队,由于框架或者组件已经进行了大量的封装,写业务代码所用到的技术确实也比较少,但我们要明白“唯一不变的只有变化”,框架有可能要改进,组件可能要替换,现有技术可能已经无法满足业务需求,或者你换了一家公司,新公司既没有组件也没有框架,要你从头开始来做。这些都是机会,也是挑战,而机会和挑战只会分配给有准备的人,所以这种情况下我们更加需要自学更多东西,因为真正等到要用的时候再来学已经没有时间了。

以 java 为例,大部分业务代码就是 if-else 加个数据库操作,但我们完全可以自己学些更多 java 的知识,例如垃圾回收,调优,网络编程等,这些可能暂时没用,但真要用的时候,不是 google 一下就可以了,这个时候谁已经掌握了相关知识和技能,机会就是谁的。

以垃圾回收为例,我自己平时就抽时间学习了这些知识,学了 1 年都没用上,但后来用上了几次,每次都解决了卡死的大问题,而有的同学,写了几年的 java 代码,对于 stop-the-world 是什么概念都不知道,更不用说去优化了。

特别是很多开源软件,更加需要自己平时去自学,例如 Nginx、Redis、Mongodb、ElasticSearch 等,在合适的时机引入这些技术,能够带来很大的价值。

Do better

要知道这个世界上没有完美的东西,你负责的系统和业务,总有不合理和可以改进的地方,这些“不合理”和“可改进”的地方,都是更高级别的怪物,打完后能够增加更多的经验值。识别出这些地方,并且给出解决方案,然后向主管提出,一次不行两次,多提几次,只要有一次落地了,这就是你的机会。

例如:

重复代码太多,是否可以引入设计模式

系统性能一般,可否进行优化?

目前是单机,如果做成双机是否更好?

版本开发质量不高,是否引入高效的单元测试和集成测试方案?

目前的系统太庞大,是否可以通过重构和解耦改为 3 个系统?

阿里中间件有一些系统感觉我们也可以用,是否可以引入 ?

只要你去想,其实总能发现可以改进的地方的;如果你觉得系统哪里都没有改进的地方,那就说明你的水平还不够,可以多学习相关技术,多看看业界其它公司怎么做,BAT 都怎么做。

我 2013 年调配到九游,刚开始接手了一个简单的后台系统,每天就是配合前台做数据增删改查,看起来完全没意思,是吧?如果只做这些确实没意思,但我们接手后做了很多事情:

  • 解耦,将一个后台拆分为 2 个后台,提升可扩展性和稳定性;

  • 双机,将单机改为双机系统,提高可靠性;

  • 优化,将原来一个耗时 5 小时的接口优化为耗时 5 分钟

还有其它很多优化,后来我们这个组承担了更多的系统,后来这个小组 5 个人,负责了 6 个系统。

Do exercise

在做职业等级沟通的时候,发现有很多同学确实也在尝试 Do more、Do better,但在执行的过程中,几乎每个人都遇到同一个问题:光看不用效果很差,怎么办?

例如:

  • 学习了 jvm 的垃圾回收,但是线上比较少出现 FGC 导致的卡顿问题,就算出现了,恢复业务也是第一位的,不太可能线上出现问题然后让每个同学都去练一下手,那怎么去实践这些 jvm 的知识和技能呢?

  • Netty 我也看了,也了解了 Reactor 的原理,但是我不可能参与 Netty 开发,怎么去让自己真正掌握 Reactor 异步模式呢?

  • 看了《高性能 MySQL》,但是线上的数据库都是 DBA 管理的,测试环境的数据库感觉又是随便配置的,我怎么去验证这些技术呢?

  • 框架封装了 DAL 层,数据库的访问我们都不需要操心,我们怎么去了解分库分表实现?

诸如此类问题还有很多,我这里分享一下个人的经验,其实就是 3 个词:learning、trying、teaching!

1)Learning

这个是第一阶段,看书、google、看视频、看别人的博客都可以,但要注意一点是“系统化”,特别是一些基础性的东西,例如 JVM 原理、Java 编程、网络编程,HTTP 协议。。。。。。等等,这些基础技术不能只通过 google 或者博客学习,我的做法一般是先完整的看完一本书全面的了解,然后再通过 google、视频、博客去有针对性的查找一些有疑问的地方,或者一些技巧。

2)Trying

这个步骤就是解答前面提到的很多同学的疑惑的关键点,形象来说就是“自己动手丰衣足食”,也就是自己去尝试搭建一些模拟环境,自己写一些测试程序。例如:

  • Jvm 垃圾回收:可以自己写一个简单的测试程序,分配内存不释放,然后调整各种 jvm 启动参数,再运行的过程中使用 jstack、jstat 等命令查看 jvm 的堆内存分布和垃圾回收情况。这样的程序写起来很简单,简单一点的就几行,复杂一点的也就几十行。

  • Reactor 原理:自己真正去尝试写一个 Reactor 模式的 Demo,不要以为这个很难,最简单的 Reactor 模式代码量(包括注释)不超过 200 行(可以参考 Doug Lee 的 PPT)。自己写完后,再去看看 netty 怎么做,一对比理解就更加深刻了。

  • MySQL:既然有线上的配置可以参考,那可以直接让 DBA 将线上配置发给我们(注意去掉敏感信息),直接学习;然后自己搭建一个 MySQL 环境,用线上的配置启动;要知道很多同学用了很多年 MySQL,但是连个简单的 MySQL 环境都搭不起来。

  • 框架封装了 DAL 层:可以自己用 JDBC 尝试去写一个分库分表的简单实现,然后与框架的实现进行对比,看看差异在哪里。

  • 用浏览器的工具查看 HTTP 缓存实现,看看不同种类的网站,不同类型的资源,具体是如何控制缓存的;也可以自己用 Python 写一个简单的 HTTP 服务器,模拟返回各种 HTTP Headers 来观察浏览器的反应。

还有很多方法,这里就不一一列举,简单来说,就是要将学到的东西真正试试,才能理解更加深刻,印第安人有一句谚语:I hear and I forget. I see and I remember. I do and I understand,而且“试试”其实可以比较简单,很多时候我们都可以自己动手做。

当然,如果能够在实际工作中使用,效果会更好,毕竟实际的线上环境和业务复杂度不是我们写个模拟程序就能够模拟的,但这样的机会可遇不可求,大部分情况我们还真的只能靠自己模拟,然后等到真正业务要用的时候,能够信手拈来。

3)Teaching

一般来说,经过 Learning 和 Trying,能掌握 70% 左右,但要真正掌握,我觉得一定要做到能够跟别人讲清楚。因为在讲的时候,我们既需要将一个知识点系统化,也需要考虑各种细节,这会促使我们进一步思考和学习。同时,讲出来后看或者听的人可以有不同的理解,或者有新的补充,这相当于继续完善了整个知识技能体系。

这样的例子很多,包括我自己写博客的时候经常遇到,本来我觉得自己已经掌握很全面了,但一写就发现很多点没考虑到;组内培训的时候也经常看到,有的同学写了 PPT,但是讲的时候,大家一问,或者一讨论,就会发现很多点还没有讲清楚,或者有的点其实是理解错了。写 PPT、讲 PPT、讨论 PPT,这个流程全部走一遍,基本上对一个知识点掌握就比较全面了。

后记

成为技术大牛梦想虽然很美好,但是要付出很多,不管是 Do more 还是 Do better 还是 Do exercise,都需要花费时间和精力,这个过程中可能很苦逼,也可能很枯燥,这里我想特别强调一下:前面我讲的都是一些方法论的东西,但真正起决定作用的,其实还是我们对技术的热情和兴趣!