# 简介

  • 程序:本质上是一组计算机指令代码,能让计算机执行某种操作。
  • 编程:泛指编写计算机程序的过程。
    • 编写程序代码之后,再执行程序代码,即可控制计算机完成某些任务。
  • 编程语言:泛指可用于编写程序代码的语言。

# 语言分类

# 机器、汇编、高级

将编程语言根据可读性分类:

  • 机器语言
    • :由二进制代码 1 和 0 组成,几乎没有可读性。
    • 能直接被计算机识别、执行,但是不能移植到不同操作系统上运行。
  • 汇编语言
    • :用助记符编写程序,又称为符号语言。有基本的可读性,但是仍然难以记忆。
    • 汇编语言编写的代码要通过汇编(即翻译)转换成机器语言才能运行。
  • 高级语言
    • :模仿自然语言的语法进行编程,可读性好。
    • 与高级语言相比,机器语言和汇编语言都是低级语言。

# 编译、解释、脚本

将编程语言根据运行方式分类:

  • 编译型语言
    • :代码通过编译器(先翻译再执行)转换成机器语言之后才能运行。比如 C、C++ 语言。
    • 程序在编译之后几乎不能移植。
  • 解释型语言
    • :代码不需要编译,在运行时才通过解释器(边翻译边执行)转换成机器语言。比如 Java、C# 语言。
    • 程序容易移植到不同平台。
  • 脚本语言
    • :属于解释型语言、动态语言。比如 Shell、Python 语言。
    • 可以不编译就即时执行代码,可以逐行执行代码,便于调试。
    • 一般而言,编译型语言、解释型语言、脚本语言的运行速度、效率依次递减。
    • 脚本语言刚诞生时功能简单,如今已经进化得像编译型语言一样功能强大。而且现在计算机硬件性能提升了很多,使用脚本语言也可以达到很好的性能。

# GPL、DSL

将编程语言根据使用场景分类:

  • 通用编程语言(General Purpose Language ,GPL)
  • 领域特定语言(Domain Specific Language , DSL)
    • 主要用于(甚至只能用于)某个领域,但在该领域的使用效果很可能比通用编程语言更好。
    • 比如用于描述 Web 页面的 HTML、CSS 语言,用于数据库结构化查询的 SQL 语言,用于匹配字符串的正则表达式,用于 Linux 终端操作的 Shell 语言。

# 语法分类

# 弱类型、强类型

根据是否自动转换数据类型来分类:

  • 弱类型
    • :支持自动转换数据类型。
    • 例如在 C 语言中:
      float x = 1;
      
  • 强类型
    • :不支持自动转换数据类型。
    • 强类型并不是绝对的的概念,一个编程语言可能同时具有强类型、弱类型的语法。比如在 Python 中:
      >>> x = 1
      >>> x = '1.0'   # 同一个变量可以执行不同类型的赋值,这是因为改变了变量引用的对象,体现了 Python 是动态类型语言
      >>> 1 + '1.0'   # 不同类型的值不支持混合运算,体现了 Python 是弱类型语言,但用户可以重载 __add__() 方法来实现混合运算
      TypeError: unsupported operand type(s) for +: 'int' and 'str'
      

# 静态类型、动态类型

根据编译时是否检查数据类型来分类:

  • 静态类型语言(statically typed language)
    • :在程序编译之后,变量的数据类型不能再改变。
    • 通常在程序编译时就检查数据类型,如果数据类型不符合要求,则中断编译,并报错。
  • 动态类型语言(dynamically typed language)
    • :在程序编译之后,变量的数据类型可以改变。
    • 通常在程序运行时才检查数据类型,如果数据类型不符合要求,可能会报错,也可能不会发现。
    • 优点:使用变量时可以很灵活。
    • 缺点:容易忽视数据类型的错误。

# 静态编程、动态编程

根据程序在编译后能否改变来分类:

  • 静态编程语言(dynamic programming language)
    • :在程序编译时确定了程序结构,不能改变。
    • 大多是静态类型语言。
  • 动态编程语言(dynamic programming language)
    • :在程序运行时可以改变程序结构,比如改变函数、改变代码。
    • 大多是动态类型语言。
    • 鸭子类型(duck typing):如果一只鸟走起来像鸭子,游起来像鸭子,叫起来也像鸭子,那它就是一只鸭子。
      • 鸭子类型体现了动态语言的特点 —— 只要一个类提供了鸭子类该有的属性和方法 walk()、swim()、quack() ,就可以将它当做一个鸭子类使用。

# 编程范式

编程范式(Programming Paradigms):泛指编写代码的风格。有的编程语言的语法较自由,支持多种编程范式;有的编程语言的语法较严格,只支持特定的编程范式。

# 面向过程编程

:Process-oriented Programming 。指按解决问题的步骤一步步编写代码。

  • 优点:流程简单、稳定。
  • 缺点:前后代码高度耦合,可扩展性差。

# 面向对象编程

:Object Oriented Programming(OOP)。指将代码封装成类,抽象化。

  • 优点:能大大提高代码的复用性,便于编写大型程序。
  • 缺点:一个类下的各个方法之间容易耦合,有继承关系的类之间容易耦合。因此维护一个类的成本比维护一个函数大很多。

# 结构化编程

:Structured Programming 。指编程时采用顺序、选择、循环、递归等控制结构,自顶向下,逐步设计。

  • 将一个语句块视作一个语句处理。
  • 是对面向过程编程的改进,使流程更清晰。

# 函数式编程

:Functional Programming 。编写函数时像编写数学函数,主要考虑给定输入参数时返回什么值,不会主动影响函数外部,不会影响程序的行为。

  • 使函数高度解耦,常用于声明式编程。

# 命令式编程

:Imperative Programming 。主要考虑让程序执行什么操作,从而得到某种结果。

  • 代码面向过程,很流程化,可扩展性差。
  • 例如脚本语言。

# 声明式编程

:Declarative Programming 。主要描述想得到什么结果,不考虑程序的具体操作。

  • 例如 SQL 语言、正则表达式。

# 符号式编程

:Symbolic Programming 。可以定义实现某种功能的表达式。

  • 与函数相比,这样的代码更接近数学表达式,更直观。
  • 例如 Lisp 语言中用表达式 (+ 1 2) 来求和,而不是函数 sum(1, 2)

# 元编程

:Meta Programming 。指程序运行时可以修改自己或其它程序的代码。

  • 所有编译器、解释器、DSL 都属于元编程,一般语言的反射、泛型也属于元编程。

# 相关概念

# 耦合度

:Coupling ,指程序或代码之间联系的紧密程度,影响到它们能否独立运行。

  • 比如程序 A 运行时需要调用程序 B ,代码 A 运行时需要读取代码 B 中的变量。
  • 在模块化编程时,应该尽量降低耦合度,便于随时更换模块,提高可扩展性。

# 语法糖

:Syntactic Sugar 。泛指一些提升代码的可读性的语法,但不一定能优化程序的运行效率。

  • 例如 Python 中的列表生成式。

# API、ABI

  • API(Application Programming Interface ,程序编程接口)

    • 指一个程序提供的某个接口,可供其它程序在代码中调用,用于实现某种功能。例如:
      • 一个 C 语言程序可以在头文件中声明函数形式的 API ,供其它程序调用。
      • 一个 Web 服务器可以提供 HTTP 形式的 API ,供其它程序发出 HTTP 请求来调用。
    • 如果一个程序提供了某个 API ,另一个程序也提供了相同的 ABI ,则其它程序可以通过相同的方式(比如用同一段代码)与这两个程序交互,称为兼容。
  • ABI(Application Binary Interface ,程序二进制接口)

    • 是比 API 更底层的概念,主要考虑编译成二进制形式的应用程序,如何与编译器、操作系统等底层软件交互。例如:
      • 调用函数时是通过寄存器还是别的方式传递参数。
      • 如何管理堆栈。
      • 如何传递异常。
    • 如果某两个操作系统的 ABI 兼容,则可以将其中一个操作系统上的二进制程序,拷贝到另一个操作系统上运行。