转:如何学习一门程序语言

url: http://mp.weixin.qq.com/s/I3poFjvVi31rWyzLhtDcVA

避免看到最后说我诓你,这篇其实应该是《我是如何学习一门程序语言的》。

对我而言,不同的语言,学习的方法似乎也不太一样。

最早的时候都是在学校里学的,比如 Fortran、C、C++、Java、OCaml 等。通过正式的课程去学习一门语言,方式会比较固定和统一,都是上课、做作业、以及编程作业。这种方式通常可以比较系统地了解语言各方面的特性,而实际实践还是要看各人的机遇和选择。所以有一些语言,上完课之后,却是很少再用了。

离开学校后,很多工作中再接触到的语言就属于自学了。总的说来有三点感触。

一是不要为了学习一门语言而学习。至少你知道自己在不远的将来有很大可能性会用再去学。因为学了一门语言而不去实践,除了对语言特性能有些了解,其实不会有什么用。因为很多东西肯定会忘掉。这有的时候和一门说话的语言一样。大学的时候觉得好玩学了日语和德语,然而从来没有真正的应用场景,所以都忘的差不多了。都不好意思跟别人说我学过。不过以后需要用的时候可能学起来还是比从头开始快些吧。

二是不同语言别人口中的学习的难度和你自己学起来觉得的难度会很不一样。原因就在于你已经熟悉掌握的语言其实是你的底子。比如一个已经熟悉 OO 编程的人,再学另一门 OO 语言就会相对轻松;一个已经熟悉函数式编程的人,再学习另一门函数式语言也会比从没接触过的人容易的多。

但这仅限于相对轻松。每门语言都还是有很多区别于同类语言的特性。还有很多语言,是综合了多个类型语言的特性,再做了不同的权衡。即使是看似语法很相近的语言,可能实际使用起来却又有很大的区别。一个众而周知的例子就是 C++ 和 Java。二者都是典型的 OO 语言,然而使用起来很多思维方式却是有着极大的差异。因此,学习一门语言很忌讳肤浅的觉得 “这个和我知道的 X 语言差不多”,然后想当然的在使用中套用一些 X 语言的思维。

三是因为工作时候学习语言通常都是边用边学。一方面,这比在学校时候能够学的更快,因为你有使用的场景,可以不断练习。而且周围很多高手可以讨论,还有别人的代码可以参考,更容易积累实战经验。而另一方面,直接上手没有系统学习很容易想当然,很容易以偏概全。这又必须在工作以外自己主动学习理论知识来弥补。

说几个我工作中学习语言的例子。

首先说 Scala。需要用 Scala 的时候,是一个别组的项目有特别紧的 Deadline,我因为一向比较 “手快” 且对业务逻辑比较熟,所以被借调过去帮忙。那时候我并没有学过 Scala,但是因为时间关系,必须立马上手。好在面向对象语言和函数式设计语言我都有比较好的底子。所以在已有代码库的基础上写一些新的函数,而不需要我去写架构代码,总的来说还是比较轻松的。

但是用 Scala 写 Spark 相关的代码,逻辑正确是不够的,一定要对代码执行的性能有所考虑。比如需要知道一些常见函数大概的时间代价,例如 group by 和 order by 其实都是比较昂贵的,应该避免一些不必要的频繁使用。而有些操作又是相当低代价,可以随意使用。另一个就是 Lambda 嵌套使用过程中语言的一些局限性等。好在组里当时有几个 Scala 比较熟的,所以一些不规范或者低效的使用方式,在 Code Review 中也会被指出。所以,几个月后,虽然用 Scala 也写了不少代码,过程中也了解了很多这样的易出错的地方,但是感觉如果不是因为是在一个协作的过程中有人帮忙,这种裸上写代码的方式还是可能引起一些性能上自己没有意识到的问题。

再说说 Ruby 以及 Rails。Ruby 是语言,Rails 是框架,但是实际工作中极大多数时候 Ruby 都是在 Rails 下使用的。因此放到一起说。Ruby 语言语法简单、使用灵活,看似好学,其实又是最难学的语言之一。因为总和其配对的 Rails 中的 Magic 太多。很多在别的语言上挺有造诣的朋友,对这门语言/框架自学和速成都遇到一些困难。Ruby / Rails 其实是我最精通的语言/框架之一,却也是我学习的时间最长的语言/框架之一。一来在 Square 的时候 Rails 就是主要(语言)架构,且公司有很多 Rails 的专家大牛,所以给了我一个极好的学习氛围。且 Airbnb 也是重度使用 Rails。二来因为常用,所以自己也愿意额外下功夫,整个 RailsCast 几百段教学录像,当时借用每天上下班坐车的时间都看完了。一些 Rails 的论坛也常常关注。所以对于 Rails,虽然坑很多,但是自己还是有信心能避开大部分常见的问题。之前的一篇《聊聊 Ruby on Rails》也写过一些心得体会。

最后说说几种前端语言、框架、和库的学习,例如 JavaScript,Ember,React 等。我在学校的时候其实从来没有碰过前端。后来因为工作需要才去学的这几种。前端语言和后端语言差异还是蛮大的,尤其是语法上。如果一点底子都没有,加上 Html,CSS 等,其实有时候读懂代码都费劲。所以直接上手写几乎是没有可能了。

当时一开始是找的 W3School 上的一些教程类文档,完整地过了一篇,不算很长,看起来倒也挺快。看完读代码问题就不算太大。然后白天看看公司的代码库,写一些简单的代码练手。一有空,就拿语言的官方文档边看边抄。什么意思呢?就是从头细读,遇到能立马理解体会的,根据熟悉程度,或快或慢,一带而过。遇到有点不知其所以然,或者虽然理解了,但是觉得自己没有深刻体会的的,就做笔记摘录下来。这样有一些在实践的过程中慢慢又会遇到,通过实际场景就会更深刻地理解。不时再温习一遍自己的笔记,觉得已经熟悉掌握的就划掉。学和练交替,等到笔记上半懂不懂的内容全部被 Mark 了,基本也算学的差不离了。

大致就是如此吧。

最后说一下,语言毕竟只是工具。精通一门语言最多算是优势,从长久的职业生涯来说,只能算技能之一。简历上多列几门语言也不见得就在找工作的时候一定有优势。有一定的语言功底,每种典型的语言类型都能熟悉或精通一门。然后在需要的时候再去学,学习的过程中能做到不想当然,不套用定式。

其实没有绝对好或者绝对不好的语言,因为每种语言都是为了一些特定场景设计的。脱离了这些场景,就总有用起来比较尴尬的情况。多了解语言的特性,在使用过程中能做到扬长避短,大部分时候就足够了。当然,如果是项目里负责语言架构的技术人员,那又另说了。