如何从零开始学一门程序语言?

今天一大早排队挂号给孩子看病,耽搁了,现在才发。

说实话,『能花钱的,就不要花时间』是篇即兴之作,本该随着时间被有限的听众渐渐淡忘。但没想到前有 @老赵 微博转发,后有知乎日报鼎力提携,这篇文章火得一塌糊涂,一下子把我推到了风口浪尖。我其实想委婉地表达一个意思:程序员的时间很宝贵,只要有能用合理价格买来的用来提高效率的产品和服务,就不要花时间找免费或廉价的替代品。但显然还是被不少人误读。不少人质疑的焦点放在了:『你是有钱了,可我们是屌丝,买不起正版软件,正版图书,盗版不也一样用么?』我没想到随手举的一个买正版软件,kindle图书的例子引起这么大反响,可这争论似乎偏离了我文章的主旨 —— 正版盗版之争不是该文讨论的重点。其实每个人心里应该都有一杆天平,左边放着『合理的价格』,右边是你的时间。天平怎么调整,在乎你,不在乎我的几行文字。

程序君再次重申,『程序人生』传递的是作者个人当下的思想,你可以不信,但切不可全信。:)

善者不辩。程序君修行还不够啊。:(

言归正传。

最近的留言中,『如何从零开始学一门程序语言?』这个问题问到的频次最多。我本不该回答,因为我不在行 —— 我现在已经回想不起十几年前究竟是怎么学第一门(有实际意义的)语言的。而我现在学习一门新语言的经验对入门者来说也许并不合适。

仔细想了想,还是决定赶鸭子上架,说说看。Again,绝对个人意见,望能抛砖引玉。首先,『兴趣是最好的老师』这样类似的话我先晾到一边,你自己补。这些东西一讲你都知道,看完你除了能点个赞之外,似乎还是对学程序语言没感觉。而且这种话说给学习任何东西似乎都有效。

如何选择语言?

我的第一门实用型的语言是Visual Basic。看了一段时间的windows编程,在各种句柄,消息循环以及繁复的MFC中迷失后,VB让我见识到了简单,直接了当,以及文档(MSDN)的重要性。学习的门槛是个大问题,有些语言(及其背后的框架)没有一定的基础最好不要碰。

当然,语言总是在发展,现在在dotnet框架下的VB已经失去了那种简单直接的美。

第一门语言最好选择带如下属性的语言:

  • 1. 语法简单,结构明晰,写出来的代码相对简洁明了
  • 2. 有完善的生态系统,尤其是文档
  • 3. 语言最好提供REPL(Read-Evaluate-Print-Loop)和introspection
  • 4. 开源社区(如github)有足够多的样本代码
  • 5. ...

以python为例,稍微解释一下第三条。python的shell(python或ipython)提供了一个语法和库函数的试验场,对初学这门语言来说帮助很大。想弄通python的数据结构,在shell下练习半小时基本就懂了。另外,在shell里随时可以对任何函数,类库做introspection(内省)—— 通过 helpdirtypeinspect(库)等深入到被调者内部了解其行为,这就进一步降低了初学者的门槛。写C代码的时候,遇到不太明白怎么使用的函数时,要么看其源码,要么找文档,但在python里,方便的内省工具可以随时随地帮助你。

补充一句,这两个语言没有可比性,我仅仅拿来举个例子。也许有人会说我可以用gdb做内省啊,但那已经不是一个层面的解决之道,也不是初学者入门时能掌握的。

第一条不用太解释,没人一开始就喜欢复杂吧?第二条和第四条当你学习时,有什么参考资料,及当你遇到问题时,可以寻求到什么帮助。你可以从某语言的官网上了解其社区文档的完备性,从stackoverflow和github上了解其生态系统和社区力量的强弱。

如果非要让我很主观地推荐,第一门语言我推荐python,它满足上面的所有要求(ruby,scala等也都可以考虑)。

看到这,也许你会问,有REPL岂不是不把大多数static typing的语言给排除在外了?对!

因为标题是从零开始学,学的过程中的互动(和shell),学习者不断构建信心很重要。compiler介入只会给这个阶段的学习带来不必要的负担。

如何学习?

学一门语言,要从语言的历史思想入手。

从语言的历史中,我们可以了解到语言诞生时的各种因素,以及在之后发展过程中的种种选择。除此之外,你要了解大概该语言的社区中在时间轴上都出过什么样的产品。这些都会加深你对语言的理解和认同感。

学习语言的思想(哲学)很重要,这体现在语言的设计,语法,甚至整个社区的行为。将一个数字转化成字符串,在python里你大概会这么做:

In [1]: str(10)
Out[1]: '10'

但在ruby里你应该这么做:

irb(main):001:0> 10.to_s
=> "10"

如果你将其视为语法而死记硬背,那事倍功半。ruby的哲学是,纯粹的OO,告诉object做什么事,而非对object做什么事。

对比ruby和python两种语言很有意思。ruby作者从smalltalk和perl的影响很大,所以ruby里一切都是对象(smalltalk),做一件事可以有多种方法(perl)。ruby的作者赋予了ruby灵活的控制权,让你可以改变系统的行为(比如可以open一个类库中的class修订),又有点像lisp。

python从Abc这门教学语言(Algol)中繁衍出来,对纯粹的OO并不感冒,因此代码可以混用面向过程和面向对象。也许是教学语言的基因,python强调做一件事用一种最清晰的方式完成("There should be one - and preferably only one - obvious way to do it."),所以社区里有人说某个实现是"pythonic",说明这个实现清晰,简洁,符合python之道。当然python还吸收了很多其它语言的优点,如list comprehension(haskell),applying function to list(lisp)等等。

了解了历史和思想,你会对语言的行为有一个比较合理的解释,学习起来也比较容易举一反三。当然作为第一门语言,你肯定不知道那么多其它语言的名字,很多我也不知道,但可以wiki一下,当拓展/延伸阅读了。

之后就是看文档书籍,看各种网上的视频教程来学习语言的语法和各种库。这个阶段比较枯燥(REPL能稍稍降低这种枯燥)。不要看教科书学语言,教科书上的习题大多和生活中的问题无关,不要试图去写什么鸽笼问题,八皇后的代码。你在学程序语言,不是在做思维训练或是数学。

注意选择书籍的时候尽量选择该语言作者(或者名家)的书,比如ruby该看『松本行弘的程序世界』,python的 "Programming Python"(python作者做的序),erlang看 "Programming erlang - software for a concurreny world",等等,他们会将很多知识和思想汇入书中。

另外还有一本无关语言,但关于编程要义的书非常值得一看:『冒号课堂』。国内的作者多写点这样的书,少做点语法介绍、类库介绍的大砖头,将是中文图书的幸事。

过了语法关之后,有两个学习方法:

  • 以练代学
  • 和社区互动
  • 以教代学

以练代学是找个有意思的项目,甩开膀子边写代码边学。驾校里永远无法让你真正学会开车,但你上路后的一周内,你就基本掌握了驾驶的全部技巧;每天都在各种复杂路况上开一个月,你就是老手了。学语言也是这个理。

学习的过程中总有困惑,多在google groups和stackoverflow里面寻找答案。如果实在找不到,用符合社区标准的方式发问。这也是一个累积经验的过程。

以练代学的基础上,最好教一个不会但又想学的人这门语言,或者找一些志同道合的人一起学。有时候我们的思维会受定势的影响,过滤好多头脑中的『傻』问题。别人一个看上去很简单的问题也许会重新触动你的神经,让你好好思索那些被自己视为『简单』的问题的答案。

不过,教别人某门语言的机会不常见,但在社区里看看别人有什么问题,尝试回答,也实践了以教代学。

如何进阶?

当你基本能比较随手用某个语言写出简单的应用后,你该考虑回过头来补补那些之前忽略的环节,重新审视这门语言:

  • 它的类型系统有什么特点?
  • 内存管理模型是什么样的?
  • 语言和库分别有什么并发的手段?
  • 对范型的支持?
  • 异常处理的机制和社区约定俗成的方式是什么?
  • 对OOP都有哪些支持?
  • 对FP都有哪些支持?
  • 如何进行元编程?
  • 与其他语言的互操作(比如C)是怎么样的?
  • 语言有什么天然的限制?
  • ...

在这个审视的过程中,不断把基础知识补齐 —— 这些都是快速掌握下一门语言的基础。

你也许还应该找些比较有意思的源代码,看看别的程序员都是怎么写代码的。读优秀的代码就像读一本好书,仔细咂吧,其乐无穷。

代码写累了,看看名家的书,修炼一下思想。『黑客与画家』,『松本行弘的程序世界』,『程序员修炼之道』等一众书都可看看。

比如说程序员修炼之道里写到:

You shouldn't be wedded to any particular technology, but have a broad enough background and experience base to allow you to choose good solutions in particular situations.

我觉得这就是做软件应该有的态度 —— 没有最完美的语言,只有最合适的工具。

结语

说了这么多,似乎跟没说一样。学习语言本就是一个因人而异的东西,没有放之四海皆准的教条。还是那句话:修行靠个人!


原文发布于微信公众号 - 程序人生(programmer_life)

原文发表时间:2014-03-09

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏韩伟的专栏

你真的理解数码技术吗?(一)

第1章 以数字为语言 知识,是人类得以进化到地球生物链顶端的最重要武器。 在远古的地球上,人类为了捕猎动物聚在一起,通过各种奇奇怪怪的大呼小叫和指手画脚来商量战...

29340
来自专栏编程

C语言编程怎么培养编程思维?没思路?我来带你找自己的思路

编程思维,可以说是一种感觉吧。培养编程思维,就是培养自己解决问题的能力,这种感觉可以帮助你更快找到问题点,对症下药。 1.要【会学】C语言 跟着老师或者自学学完...

37650
来自专栏牛客网

成都银联面经

13240
来自专栏Android开发实战

浮躁的社会浮躁的你,浮躁的程序员哪里才是你的归属地。

其实最开始听到这个词的时候我是拒绝的。因为我觉得我话挺多的,无论和谁,只要唠开了,就能滔滔不绝的唠下去:

13950
来自专栏程序员互动联盟

【答疑释惑第四十一讲】自学的工作好找吗?要熟练几门语言

疑惑一 自学的工作好找吗?要熟练几门语言(好困惑,求解)? 有些自学的小伙伴不自信,认为所谓的野路子不行,甚至对自学方法也持怀疑态度,其实我作为过来人,想对对他...

35890
来自专栏java系列博客

java程序员必读书单

40840
来自专栏鸿的学习笔记

关于最近读的书的一些瞎扯

最近两个月是真的忙,忙的公众号都没有坚持更新了。现在我又回来了。在此准备瞎扯几句,顺便推荐下自己的最近读过的书,

8820
来自专栏PPV课数据科学社区

如果大数据是任何东西……If Big Data Is Anything at All, This Is It

除了我们几个人是第一次听说过“大数据”这个词,我们是在信息技术厂商开着的营销活动以宣传自己的产品和服务的背景下听到它的。正是这种营销活动使得“大数据”这个词取得...

33280
来自专栏程序员互动联盟

为什么C++是最难学的编程语言?

很多已经做了几年的C++程序员已经很自信觉得这门编程语言算是熟悉阶段了,但是当重新对这门语言来个彻底大扫除的时候发现,又有新的语法出现,最糟糕的是之前掌握的很多...

29830
来自专栏Python小屋

Python+numpy实现蒙特卡罗方法估计圆周率近似值

问题描述:使用蒙特卡罗方法估计圆周率近似值,具体描述详见以前发的文章 蒙特.卡罗方法求解圆周率近似值原理与Python实现

12920

扫码关注云+社区

领取腾讯云代金券