说说编程语言学习
2021年02月16日 星期二, 发表于 东莞,中国
如果你对本文有任何的建议或者疑问, 可以在 这里提issues
从过去的学习经验出发,说说学习编程语言,一家之言,欢迎讨论。
看到很多同学每次入门一种新的编程语言的时候都喜欢买一本或者几本语法书来啃,仿佛啃完语法就有神功护体,万事大吉。实际并非如此,从前我学习总会有一个不得深意的感觉,总感觉自己无法入门,在一次和同事的交谈中我突然间意识到问题所在,学一门新技术要先搞明白这门技术为什么出现,解决了什么问题,而不只是知道它如何使用。
对于编程语言的学习更是如此,要首先理解这门编程语言的设计哲学(这句话可能听上去感觉很虚),再去系统地学习,往往会比只看语法有更深的理解。言归正传,如果把一门编程语言庖丁解牛,会分成以下几个大块:
- Ecosystem:重点关注编程语言的标准组织或者社区如何运营,是否有使用专门的语言增强子集
- Language Core:重点关注编程语言的Specification/Standard,SDK,运行时是如何发布的以及编程语言对应的编程语言对应的编译器/汇编器/链接器的使用和发展
- Framework:重点关注多线程编程,网络编程,事件调度,内存管理等编程框架
- Library:重点关注编程语言的标准库,典型的支撑库是如何使用以及发展
- Tools:重点关注开发工具,调试定位,构建,单元测试,静态&动态检查工具
但是对于不同目的的学习,每个部分的重要性不尽相同,一般工作中学习一门新语言都是为了开发,那么可以把重点放在语言核心和框架上,而对于语言洞察类工作,则需要从以上各个角度去了解和分析。
掌握一门编程语言的关键在于理解该语言的语言特性实现,只有如此,才可以透过现象看本质,所谓的“语言特性”,则指以下:
- 变量定义
- 算术运算
- for循环语言,while循环语句
- 函数定义,函数调用
- 递归
- 静态类型系统
- 类型推导
- lambda函数
- 面向对象
- 垃圾回收
- 指针算术
- goto语言,等等
任何一种编程语言,都是各种特性的组合,而每一种语言中必然有一套通用的特性。例如变量,函数,整数和浮点数运算等等。只有通过某些语言掌握了这些特性的根本概念,才可以随时把这些知识应用到其他语言上。很多同学会纠结于是编程语言太难导致大家写不出来好的代码,但是可能真相是如果你不能用任何一门语言里面的基本特性写出好的代码,那你换成另外一种语言也无济于事。打个比方,抱怨C++没有提供GC,写出了生命周期管理混乱的代码,就算换了用Go语言也同样会写出生命周期混乱的代码,徒增GC压力。所以从来就不是语言的问题,而是人的问题。
用垠神的话说“只有实现了各种语言特性,你才能完全地拥有它们,成为它们的主人。否则你就知识它们的使用者,你会被语言的设计者牵着鼻子走。” 这个话说得比较极端,如果不是PL狂热粉,应该也没有几个人会去动手实现语言特性(除了上课写作业以外),但是道理却是对的,就算你不动手去写,你也得知道是怎么实现的,才可以做到“不被浮云遮望眼”。
在语言特性之后,可以进一步去学习该编程语言的类型系统,对象模型以及内存模型,这种基础的知识可能会让你更进一步地理解很多困惑,推荐一下冯老师的程序设计语言概念(iLearing)。
以C++为例,应该如何学习C++,类似地,我们先看一下C++全景图
C++的主要关注点是系统编程、嵌入式系统、资源受限系统以及大型系统。它支持:
- 多范式语言:支持过程式,面向对象,函数式,泛型编程
- 系统编程语言:兼容C语言,可以直接操作硬件,并且语言实现零成本抽象
- 高度抽象的语言:高层次的类/泛型等抽象类型,低层次的指针和void*底层类型
- 丰富的语言库:容器和算法、文件系统、正则表达式、线程、日期、范围等库
C++是一个庞大武器库,所以在学习C++的时候不要希望一口吃掉所有东西,最好的方法是按开发需要来选择武器,在使用的过程中深入理解,但是也注意不要拿着2021的武器写着2003的代码。。。
几个建议:
- 把时间投入到关键特性的学习中
- 追本溯源,不要道听途说
- 重视语言特性,而不是语法
一些入口:
1、宝藏:https://en.cppreference.com/w/cpp
2、祖师爷的主页:https://www.stroustrup.com/
3、官方 CppCoreGuidelines :https://github.com/isocpp/CppCoreGuidelines