我的答案是:掌握学习新编程语言的能力。
授之以鱼不如授之以渔
对于一个编程老手来说,学习新的编程语言应该很容易。他们只需要一个周末甚至是几个小时就可以开始用新学的编程语言写代码了。优秀的程序员可以为了完成某个任务使用任何一门编程语言。毕竟,编程语言只是工具。
话是没错,不过更重要的你要学会“如何学习新的编程语言”,而不只是学会某一门具体的语言。要掌握“学会所有编程语言”的能力,你不需要是一个天才,你要做的是掌握编程语言的核心知识,并知道所以,代码实际上就是你传达给人类和计算机的“消息”。这也是在设计和实现编程语言时需要考虑的权衡点。因为:一些最佳实践。
下面让我来具体解释一下。
如果把编程语言比作汽车
要记住,编程语言只是工具,它们也是由程序员发明出来的。世界上有几千种编程语言,其中只有 20 多种在 IT 界里被广泛使用。如果你稍微想一想,就会发现这些编程语言有一些共同点。
我们以汽车为例,世界上有很牌子的汽车。有些车子紧凑但动力十足,有些车子笨重开得慢,不同牌子的车子具有不同的驾驶体验。
如果你知道怎么开其中一种车型,也就知道怎么开其他大部分车型,尽管它们的牌子不一样。
为什么这么说呢?因为不同牌子的车子有一些共同点——它们都有发动机和轮胎。它们的作用都是一样的:把你送到目的地。
编程语言的作用是帮助程序员表达想法。
为什么会有这么多编程语言
编程语言是一种表达工具,包含了两个方面:
向其他程序员表达想法,这样别人就可以了解你写的代码,并一起参与代码维护。
把你的想法传达给计算机(通过编译器或者解释器),让计算机执行你的指令。
添加图片注释,不超过 140 字(可选)
所以,代码实际上就是你传达给人类和计算机的“消息”。这也是在设计和实现编程语言时需要考虑的权衡点。因为:
硬件和计算机语言在发展演化。一般来说,编程语言应该越来越容易使用,在表达想法方面越来越强大。
随着计算机应用越来越广泛,越来越多的领域需要使用计算机,于是不同的编程语言被发明出来,用于解决不同领域的问题。
不同的编程语言代表了不同的思维风格。
不同的编程语言有不同的语法和特性,但它们都是图灵完备的。通俗地说就是:所有的编程语言都可以用来实现任意一种算法。
当然,你不需要学会所有的编程语言,但学会的编程语言越多,就越容易为要完成的任务选择合适的语言。
编程语言基础
几乎所有的编程语言都包含了几类元素,它们都与“抽象”有关:
数据类型和数据抽象;
控制流程和控制抽象;
底层抽象;
对特定领域的补充和抽象。
编程语言有很多公共特性,因此,我们能够学会所有编程语言的主要原因是:编程语言的概念其实是很有限的。常用的编程语言概念不会超过 15 个:
过程;
递归;
静态类型;
动态类型;
类型推断;
lambda 表达式;
面向对象;
垃圾回收;
指针;
连续性;
元编程;
宏;
异常。
编程语言的概念基本上是不怎么变的,就像设计原则一样。
编程语言的作者们相互借鉴想法,只是实现不一样罢了。有时候,我们可以说语言 C 是语言 A 和 B 的儿子,那么整个编程语言的家谱可能像这样:
所以,代码实际上就是你传达给人类和计算机的“消息”。这也是在设计和实现编程语言时需要考虑的权衡点。因为:
硬件和计算机语言在发展演化。一般来说,编程语言应该越来越容易使用,在表达想法方面越来越强大。
随着计算机应用越来越广泛,越来越多的领域需要使用计算机,于是不同的编程语言被发明出来,用于解决不同领域的问题。
不同的编程语言代表了不同的思维风格。
不同的编程语言有不同的语法和特性,但它们都是图灵完备的。通俗地说就是:所有的编程语言都可以用来实现任意一种算法。
当然,你不需要学会所有的编程语言,但学会的编程语言越多,就越容易为要完成的任务选择合适的语言。
编程语言基础
几乎所有的编程语言都包含了几类元素,它们都与“抽象”有关:
数据类型和数据抽象;
控制流程和控制抽象;
底层抽象;
对特定领域的补充和抽象。
编程语言有很多公共特性,因此,我们能够学会所有编程语言的主要原因是:编程语言的概念其实是很有限的。常用的编程语言概念不会超过 15 个:
过程;
递归;
静态类型;
动态类型;
类型推断;
lambda 表达式;
面向对象;
垃圾回收;
指针;
连续性;
元编程;
宏;
异常。
编程语言的概念基本上是不怎么变的,就像设计原则一样。
编程语言的作者们相互借鉴想法,只是实现不一样罢了。有时候,我们可以说语言 C 是语言 A 和 B 的儿子,那么整个编程语言的家谱可能像这样:
添加图片注释,不超过 140 字(可选)
理解好这些概念,不仅可以帮你快速学会编程语言,还会让你写出更好的代码。例如,函数式编程语言和过程式编程语言的代码风格和抽象方式是非常不一样的,如果没有领会到它的重点,可能就写不好代码。
专注在语言概念上,而不是语法
添加图片注释,不超过 140 字(可选)
因此,我们要学习编程语言概念,但该怎么学呢?
我建议去了解某个语言概念或特性要解决的问题是什么,它有哪些好处和不足,而且最好可以知道它是怎么实现的。
我们以 GC 为例,那么第一问题就是:GC 是什么东西?
在网上搜一下,可以找到这个维基百科的解释。GC 是用来解决内存管理问题的,可以减少程序的内存错误。有了 GC,代码写起来更容易了,因为我们不需要手动管理内存,但这是以牺牲性能为代价的。如果你的编程语言使用了 GC,要注意 GC 是如何帮你处理内存的。
随后,你需要知道 GC 的工作原理。它们使用了什么算法?GC 有很多种,而且它们的种类还在不断发展演化中。
开始学习新的编程语言正是学习编程语言概念的一个好时机。例如,如果 Ruby 是你的第一门面向对象编程语言,就可以借这个机会深入了解一下面向对象编程的优点和不足。
对面向对象编程有了很好的理解,再去学习其他面向对象编程语言就会容易得多。
自己发明或实现一门编程语言
添加图片注释,不超过 140 字(可选)
如果语法不是很复杂,要实现一门编程语言并不需要做太多工作。可以看看这个项目,任何一门语言都可以被用来实现 Lisp。8cc 是 C 语言的一个编译器,如果你想自己写一个编译器,可以参考这个项目。
除了这些,还有一些书可以看:
《编程语言要领》介绍了很多种解释器,《编程语言编译器实践》也是一本适合用来学习编程语言的书。
学习一门新语言的步骤
如果你遵循以下这些步骤,就可以快速“学会所有的编程语言”。
第一步:理解这门语言的设计理念和通用的语言特性
例如,如果你要学 Ruby,那就先看一下 Ruby 有什么特别的?
Ruby 是一门开源的动态编程语言,专注易用性和效率。它的语法很优雅,代码读起来很自然,写起来也很自然。
让我们更深入地看一下:
About Ruby
那么,在学习 Ruby 之前,需要了解的重点是:
Ruby 专注于易用性和效率,代码容易阅读;
Ruby 是解释执行的,所以使用了 GC,也就是说对于某些任务,性能可能会是个问题;
在 Ruby 中,所有东西都是对象,所以它是面向对象编程语言,而且是纯面向对象的;
Ruby 很灵活,我们可以重新定义它的一些东西。
了解这门语言最重要的特性,包括它的优点和不足。
第二步:通过教程或书籍学习语法和最佳实践
在第二步,你需要掌握语法、基本的 IO、调试工具和单元测试。
如果你刚开始学习编程,最好找那种“权威指南”之类的书籍,比如语言作者写的书,或者在网上书店搜索这门编程语言,找到好评如潮的书。
如果你是个编程老手,只需要找一些简单的指南或示例代码就可以了,可以看看这个。
记住,在学习语法时,你需要动手写代码,不要只是拷贝黏贴。你可以在这个网站上练习写代码,有人会审阅你的代码,并免费为你提供建议。
第三步:使用新学的语言写更多的代码
现在,你需要使用新学的语言开始一个项目,包括与这门语言有关的生态系统、工具和库。你可以从简单的开始,比如一个猜数字小游戏、简单的网上书店或者 TODO 应用程序。在 GitHub 上可以找到很多类似的项目。
第四步:了解语言的实现细节
这一步并非都是必需的。不过,有追求的程序员对编程语言的实现细节会感兴趣。有时候,因为对编程语言的实现细节不是很了解,容易写出 bug。
那么,我应该先学哪一门语言?
好吧,现在我们来回答这个问题。这个问题的答案取决于很多因素,但简单地说就是:
1:有人教你吗?或者说你在上编程语言课程吗?
如果你的老师要你学习 C 语言,那么 C 语言就是你的第一门需要学习的编程语言,因为有人教你,你还有同学,学习起来会更容易。
2:你打算用它来做什么?
如果你要开发 Web 应用程序,就学习 JavaScript/Python/Ruby。如果你要开发游戏,就学习 C++。如果你要处理数据,就学习 Python/R 语言。如果你要开发 Android App,就学 Java/Kotlin。
3:你需要用它来找工作吗?
如果是这样,按照岗位的要求来学就好了。
哪一种编程语言是最好的?
添加图片注释,不超过 140 字(可选)
这个也取决于实际情况。每一门编程语言都有自己的优点和不足。适合用来处理所有任务的编程语言是不存在的。如果存在,我们只需要学习一门就够了,不是吗?记住,这个世界上没有万灵丹。
对于我个人而言,我最喜欢的语言是 C 语言 /Ruby/Lua/OCaml。
有人说,在掌握 5 门编程语言之前,不要把自己当成高级程序员。当正如之前所说的,不要专注于学习更多的编程语言,而是试着学习更多的编程语言概念和设计原则。
如果你在工作中使用的是结构化的编程语言,为什么不试着学习一门函数式编程语言?如果你的语言是动态类型的,为什么不试着学习一门静态类型的语言?