如何深入学习一种编程语言?

结合自己学习、带实习生的一些经验总结的学习一门编程语言的切入方向。


本文可以作为学习语言的路书,当然只能作为指导原则,细节还需要参照具体语言决定。也可以作为自查工具,看看自己还有那些漏掉的地方。
基本上参考了一下几年来我接触到的几种语言的特性:JavaScript, Node.js, Golang, Java, Python。

总结的不完善,将来想到的时候再补充吧。

学习新语言的步骤

  1. 平台与特性
  2. 包管理机制
  3. 数据与运算
  4. 流程与控制
  5. 内建工具和包装类型
  6. 封装和抽象
  7. 测试与异常
  8. 扩展

平台与特性

  • 平台的设计
    • 面向领域
    • 性能
  • 语言特性
    • 编译型,解释型
    • 静态类型 / 动态类型
    • 强类型 / 弱类型
    • 函数式 / 过程式 / 对象式

语言的设计领域决定了其使用成本,比如开发 Web 项目,使用 Go,Node.js 等内置 HTTP API 的语言肯定要比 C++ 一类的语言使用成本更低。当然,像是 Java 这种有完善的 HTTP 开发框架,开发效率也会很高。

性能比较好理解,通常来说,语言越高级越自动化,性能相对越差。这里提供一个 Debian 团队的语言 Benchmark 项目的 连接 , 这里记录了大部分语言的 benchmark 信息。可以作为理解语言定位的参考。

编译(解释)方式、动态 / 静态、强 / 弱类型等语言特性很大程度上影响了该语言的程序设计思想。当我选用 Node.js 开发项目时,我可以相对随意的设计和运行程序。但是 Java 或者 C 就相对严肃,我需要严格的按照范式进行,否则根本跑不起来。

不是所有的特性每种语言都有完整的支持,没有的或者没有写到的也不用奇怪。

包管理机制

个人觉得包管理机制因该优先于语法学习。个人也推崇自顶向下的学习理念。
只有宏观了解代码运行和组织方式之后,再深入微观才能有比较好的理解。

  • 包管理工具
  • 第三方仓库的查询,安装
  • 私有仓库的使用方法

不管会不会 Nodejs 都值得一试的 Nodejs 的包管理器:NPM

数据与运算

这里语言的基础语法层面的知识,是熟练使用的前提。通常来说,各种语言在这个领域类似但是不相同。
需要注意的点如下

  • 基础语法
    • 语言结构
      • 文件命名,语句写法
      • 标识符:大小写敏感
  • 数据与表示
    • 数据的类型
      • 基础类型:默认值 字节数 取值范围
        • 数字型:short, int, long, float, double
        • 非数字型:byte, boolean, char
      • 高级类型
        • 字符类型:string
          • 操作:连接,查找,替换,trim, 大小写转换,split, 模版替换
        • 包装类型:基础类型的衍生
      • 基础类型转换
        • 隐式转换
          • number 转: string boolean byte char
          • string 转: number boolean byte char
          • byte 转: string char
          • char 转: string int
        • 显式转换
      • 集合类型
        • 枚举,bitSet (位集), vector (向量), stack, array, map, slice
          • 多维,遍历,查找,排序,比较,删除,插入,过滤
    • 数据的表示
      • 变量,常量
      • 语法:声明,声明并赋值
      • 作用域
        • 范围:全局,局部,模块作用域
        • 闭包
      • 转义: \t \b 后退符 \n 换行符 \r 回车符 \f 换页符 \' \" \\
  • 数据的计算
    • 运算
      • 运算符号
        • 算数运算:+ - * / % ++ --
        • 关系元算:== != > < >= <=
        • 位运算: & | ^(异或) ~(按位取反) << >> >>>
        • 逻辑运算: && || !
        • 赋值运算: = += -= *= /= %= <<= >>= &= ^= |=
        • 三元运算符: ?:
        • 类型运算符: instanceof
      • 运算符优先级
        • 以 java 为例,优先级按顺序展开:
          • 后缀: () [] . (点操作符)
          • 一元: ++ -- +(正号) -(负号) ~ !
          • 乘性: * / %
          • 加性: + -
          • 位移: >> >>> <<
          • 关系: > >= < <=
          • 相等: == !=
          • 按位与 & > 按位异或 ^ > 按位或 |
          • 逻辑与 && > 逻辑或 ||
          • 条件: ? :
          • 赋值: = += -= *= /= %= >>= <<= &= ^= |=
          • 逗号: ,

流程与控制

  • 循环
    • 条件循环: for wihle
    • 迭代器
    • 中断 break
    • 跳过 continue
  • 分支
    • 两个出口的分支: if
    • 多个出口的分支: if switch—case
  • 暂停
  • 阻塞(等待)

内建工具和包装类型

这部分是常见的自带的库的用法,写的不完善,可以根据需要参考语言文档按需选择。

  • number 包装类型
    • Short Integer Long Byte Double Float
  • Math 计算工具
    • 数值计算: abs ceil (上取整) floor rint (最接近的整数) round min max exp (e 的 a 次方) pow (a 的 b 次方) sqrt
    • 三角函数: sin cos tan acos atan atan2 toDegrees toRadians
    • 其他: random
  • Charactor 类
    • 转义字符
    • 操作: isLetter isDigit isWhitespace isUpperCase isLowerCase toString
  • String StringBuffer StringBuilder
    • 连接 查找 替换 trim 大小写转换 substring split
  • Date 的使用
    • 时间戳 时区转化 格式化 比较 计算
    • 用 string 转换
    • 格式化编码
      • G 纪元标记 AD
      • y 四位年份 2001
      • M 月份 July or 07
      • d 一个月的日期 10
      • h A.M./P.M. (1~12) 格式小时 12
      • H 一天中的小时 (0~23) 22
      • m 分钟数 30
      • s 秒数 55
      • S 毫秒数 234
      • E 星期几 Tuesday
      • D 一年中的日子 360
      • F 一个月中第几周的周几 2 (second Wed. in July)
      • w 一年中第几周 40
      • W 一个月中第几周 1
      • a A.M./P.M. 标记 PM
      • k 一天中的小时 (1~24) 24
      • K A.M./P.M. (0~11) 格式小时 10
      • z 时区 Eastern Standard Time
      • ‘ 文字定界符 Delimiter
      • “ 单引号 `
  • 正则表达式
    • match
      • 一般字符 . \d \D \s \S \w \W
      • 不可见字符 ^ $ \f 换页符 \n \r \t \v \b 字符边界 \B 非边界
      • 其他
        • \cx 控制符(\cm 表示 ctrl+M)
        • \xn 十六进制字符:"\x41"匹配"A
        • \num 匹配重复次数: "(.)\1"匹配两个连续的相同字符
        • \un 匹配十六进制unicode字符: \u00A9 匹配版权符号©
      • 组合 x|y [xyz] [^xyz] [a-z] [^a-z] (pattern)
    • count: * + ? {n} {n,} {n,m}
    • 模式
      • ? 表示非贪心,如 *? +? {n}? {n,}? {n,m}?
      • (?:pattern) 匹配但是不捕获 industr(?:y|ies) 是比 ‘industry|industries’ 更经济的表达式
      • (?=pattern) 匹配 pattern 结尾的表达式
        • Windows (?=95|98|NT|2000) 匹配”Windows 2000” 中的”Windows”
        • 不匹配”Windows 3.1” 中的”Windows”
      • (?!pattern) 匹配不以 pattern 结尾的表达式
        • Windows (?!95|98|NT|2000) 匹配”Windows 3.1” 中的 “Windows”
        • 不匹配”Windows 2000” 中的”Windows”
  • 流处理
  • 文件处理
  • IO
  • 控制台交互
  • socket

封装和抽象

  • method
    • 声明
    • 调用
  • 对象
  • 模块
  • 面向对象设计
    • 继承
    • 多态
    • 接口
  • 范型:描述算法忽略类型的工具,描述时忽略类型,使用算法时来再来确定类型

对于静态类型的语言来说,没有范型简直就是灾难。说的就是你: Go。

测试与异常

  • 测试方法(单元测试)
  • 同步异常
  • 异步异常

功能扩展

  • 序列化
  • 多线程
  • 文档提取
  • 代码混淆
  • 语言风格