文章目录
  1. 1. 编程语言的学习困境
  2. 2. 编程语言应该从哪些角度来看
    1. 2.1. 从语言发展的角度
    2. 2.2. 编程语言有哪些维度
      1. 2.2.1. 语言的基本要素
        1. 2.2.1.1. 语言编译特性
          1. 2.2.1.1.1. 语言编译、解释类型
          2. 2.2.1.1.2. 运行时特性
        2. 2.2.1.2. 内存管理
      2. 2.2.2. 面向对象部分
        1. 2.2.2.1. 面向对象语言基础
        2. 2.2.2.2. 继承
          1. 2.2.2.2.1. 单根继承
          2. 2.2.2.2.2. 多重继承
        3. 2.2.2.3. 异常处理
        4. 2.2.2.4. 并发机制
      3. 2.2.3. 其他编程语言范式
        1. 2.2.3.1. meta programming
          1. 2.2.3.1.1. introspect
          2. 2.2.3.1.2. reflection
          3. 2.2.3.1.3. dynamic AST modification
        2. 2.2.3.2. Aspect oriented programming
  3. 3. 如何学习编程语言
    1. 3.1. 抓住语言发展的主线
    2. 3.2. 知识与动手相结合
    3. 3.3. 总结属于自己的工程规范
  4. 4. 参考

编程语言的学习困境

  • 编程语言这么多我该学那个?
  • 编程语言有那么多知识点记不住怎么办?
  • 看到大神写的代码寥寥几行就解决问题性能还好,这是怎么做到的?

编程语言应该从哪些角度来看

从语言发展的角度

从语言范式发展的角度, 编程语言主要经历了3个范式阶段:

  • 面向过程的语言
    面向过程的语言主要是解决之前语言结构化的问题, 毕竟写出来的代码最终还是由程序员来维护,正常的人类思维还是偏爱结构化和线性逻辑。
    这个阶段的语言以C语言为代表。

  • 面向对象的语言
    面向对象的语言主要是解决之前语言逻辑重用的问题,实际生活中很多事物是类似的,如果按照面向过程的语言来处理就会有很多重复自己(Repeat yourself)的代码存在,这会使得后期的维护变得困难。
    所以C++通过运用面向对象语言的 封装 继承 多态 解决了之前C语言之前存在的问题‘;
    然而后续又因为C和C++将内存管理的自由度完全交给程序员来做,人非圣贤孰能无过,所以又出现程序内存管理的问题(主要是指针问题)。
    Java通过引入中间层JVM,在源代码与机器码之间抽象出一个Java字节码,使得Java支持了跨平台,同时将内存的管理也交给了JVM,让程序员可以更多的去关注业务逻辑。
    所以这个阶段的语言以C++、Java为代表。

  • 面向函数的语言
    面向函数的语言特性是想通过消除变量的可变性的方式解决面向对象语言中的竞争问题、死锁问题、并发问题。
    函数式编程的核心关键词是不可变性,通过不可变性消除多线程、多处理器引发的并发问题。
    这个可行么?如果在存储能力和计算能力足够强大的情况下是可行的。
    换句话说,回归到现实来看,这样的假设和理想状态可能还是在未来的某一天。
    当存储和计算能力达到足够大的情况下,可以通过事件溯源(不记录中间状态,只记录事务记录)达成获取具体状态的目的。以查询银行账户的余额这个例子来说,事件溯源的主张是只存储账户事务记录(如:账户存入、取出事务记录)而不存储具体状态(如:账户余额),每次需要获取具体状态的时候,通过计算全部交易事务记录进行累计就可以获得。这个主张在现在的计算水平下是不是不可思议?但是如果存储能力足够大(接近无限),计算能力足够强(超出现在的技术能力)似乎也是一种解决方案。我们发现在这样的模式下对数据的CRUD的操作就只剩下CR了,自然完美规避了更新和删除引发的并发问题。所以,小结一下,如果在存储能力足够大、计算能力(CPU、内存)足够强的前提下,应用程序是可以用完全不可变、纯函数式的编程范式来编程。
    但是很不幸,目前还没有达成纯函数式编程的客观条件。

编程语言有哪些维度

语言的基本要素

基本语法行为要素:

  • 顺序结构
  • 分支结构
  • 循环结构
  • 间接转移
语言编译特性
语言编译、解释类型
  • VM字节码与optcode
  • AOT
  • JIT

stackexchange - How does the Python Runtime actually work?

运行时特性
  • 方法调用类型及实现细节
内存管理
  • 内存模型
  • 内存管理优化

面向对象部分

面向对象语言基础
  • 数据类型
  • 对象内存模型
继承
单根继承
  • 如何实现多态

  • Override 与 overwrite的区别

  • 方法调用的JVM细节

多重继承
  • 多重继承的问题

  • 如何解决这个问题

异常处理
并发机制
  • lock

  • Feture

  • Coroutine

其他编程语言范式

meta programming
introspect
reflection
  • 反射实现的内部机制
dynamic AST modification

The Art of Metaprogramming in Java

Aspect oriented programming

Wikipedia - AOP
Spring
Spring Python
bitbucket - aspect.py

如何学习编程语言

抓住语言发展的主线

正如之前提到的,抓住编程语言从 C -> C++ -> Java 这样一条主线,同时再看一个解释型语言的语言特性就可以抓住实际工程中编程语言使用的主线。
在学习这些语言的过程中形成自己对编程语言范式的总结,结合实际工程和领域知识的需要,按照MECE原则进行拆分和罗列,从而形成自己的知识结构。

知识与动手相结合

遗忘是人类正常的生理反应,在漫长的人类进化过程中形成了自动遗忘痛苦的经历的机制,如果对于学习的内容没有兴趣,那么学习的过程就是一个反人类的过程。
所以如何高效的学习知识呢?

  • 寻找知识的落地场景,培养学习兴趣
  • 建立心理构型,刻意练习
  • 遵循学习金字塔,变被动学习为主动学习

总结属于自己的工程规范

之前的过程实际上是在经历将现有的知识转化为实践;
实践的过程中会在工程和自我的知识体系方面有新的理解,进一步将这些理解转化为方法论才有可能在这个过程中有新的维度突破。

参考

文章目录
  1. 1. 编程语言的学习困境
  2. 2. 编程语言应该从哪些角度来看
    1. 2.1. 从语言发展的角度
    2. 2.2. 编程语言有哪些维度
      1. 2.2.1. 语言的基本要素
        1. 2.2.1.1. 语言编译特性
          1. 2.2.1.1.1. 语言编译、解释类型
          2. 2.2.1.1.2. 运行时特性
        2. 2.2.1.2. 内存管理
      2. 2.2.2. 面向对象部分
        1. 2.2.2.1. 面向对象语言基础
        2. 2.2.2.2. 继承
          1. 2.2.2.2.1. 单根继承
          2. 2.2.2.2.2. 多重继承
        3. 2.2.2.3. 异常处理
        4. 2.2.2.4. 并发机制
      3. 2.2.3. 其他编程语言范式
        1. 2.2.3.1. meta programming
          1. 2.2.3.1.1. introspect
          2. 2.2.3.1.2. reflection
          3. 2.2.3.1.3. dynamic AST modification
        2. 2.2.3.2. Aspect oriented programming
  3. 3. 如何学习编程语言
    1. 3.1. 抓住语言发展的主线
    2. 3.2. 知识与动手相结合
    3. 3.3. 总结属于自己的工程规范
  4. 4. 参考