学习一门语言的基础,也就是语法本身,不代表你掌握了这门语言。学习一门语言应该是学习它所代表的完整的生态环境和在各个应用场景下最合适的组合。同样的,笔者大大小小算是用过七八门语言,当然,你为了学习而去学习,用语言的数量标榜自己是毫无意义的。但是,每个语言都有其特性,就像才接触Python时候它的弱类型、快速开发的便捷以及后面应用到大型程序开发时候的代码混乱都给我留下了深刻的印象。往往说一门语言不好是因为你没学到家,但是就所处的技能水准和应用场景而言各个语言还是各有其优势的。笔者看现有的很多教程,以Java为例,它的讲解方式以及应用示例都是基于JDK本身和Java语言本身的特点的。那么笔者自己总结的这份所谓的编程语言的知识结构图或者拓扑图,是会抽象了各个语言的特性而形成。唔,譬如笔者最早是在JavaScript中,在用jQuery的时候接触到了Promise的概念,后来在Java、在Swift中都发现了类似的,但不一定叫这个名字的用法或者第三方类库,那么我们在做笔记时,首先要知道,你现在所学的,是应该放在哪一部分。
学习一门语言呢,肯定首先要去学习它的语法基础,那学习语法基础的时候,我们要掌握哪几个方面呢,笔者大概归类到入门概述、Quick Start、数据结构、流程控制与异常处理、函数、模块与组件、类与对象以及IO这几个部分。
在这里你要了解这门语言的由来,它的特点,它的基本面貌。譬如你要了解下它各个版本迭代的特点。就像Java 8提出之后,你需要专门的对于Java8的语法特性进行一些了解,但是对于某个具体的语法知识点还是应该放到对应的语法讲解的位置。譬如Java8里面提出了函数式接口,那这部分具体的讲解还是应该放置到接口那一部分。
其次呢,你还要在这边了解基本的注释与代码分割的规范,就好像笔者初学Python的时候,这货没有大括号,用的是缩进分割的方法,让才从C++/Java走过来的笔者一顿酸爽。
接下来,在入门概述这边,你还要放外部资料的链接。你不可能把全部的你看到的资料转化为自己的笔记,那么你需要把所有的你看到的有价值的参考资料地址存放在这里。笔者大概分为了:
Tutorial & Docs:入门教程和指导相关
Practice&Tips:实践、小贴士相关,就好像Github上流行的awesome-系列,就要把链接放这
Forum&Lessons:一些论坛和在线的视频教程地址
Blog&News:博客和资讯
Book&Resources:参考的书籍啊、资源啊放这里
Quick Start
学习一门语言的时候,你肯定会写HelloWorld,笔者在上面强调过,做笔记的一个目的就是在未来某天你可能全部忘记的时候能够以最快的速度学会,那么你再次学习的时候肯定会去继续写HelloWorld。在这一部门,你需要知道怎么搭建开发环境,特别推荐是也要学下怎么使用Docker去搭建开发环境。接下来呢,你要学下构建工具和依赖管理工具。在早年,笔者才学Java,还不知道用Maven的时候,那个时候根本分不清什么构建啊、依赖管理的概念,每次要用jar包了只能手动拖拽,真心呵呵哒。当然,一门优秀的编程语言一定要有其对应的构建与依赖管理工具,这样才能促进整个社区的活跃与交流。然后你要看看怎么进行代码部署,就好像Python的Notebook、Swift的PlayGround这些个神奇的东西,还是非常好用的。
最后呢,还要看看常用的IDE,不过笔者目前基本上就用的是Atom加上Jetbrains(感恩)这一个系列。唔,之前看到很多大牛喜欢用Sublime啊Vim来写代码,我表示,这个逼还是不要装的好。
学完了HelloWorld,我们就要来看看数据结构了,这是一个编程语言的基石所在。那么不论哪一种语言,它会提供给我们哪些知识呢。
(1)首先是知道怎么去定义变量与常量。就好像JavaScript里面的var、let,以及未来Java里面会加入的val,变量定义的方式也是有很多种的。还有就是要了解下系统的内置的常量,这个在使用PHP进行开发的时候比较用得上。接下来,要看看这个变量是怎么赋值的,是必须单个赋值还是能够链式赋值,或者是像JavaScript这样还能支持解构赋值。最后呢,这一部分还要看看你怎么进行类型、格式判断的,好比instanceof啊typeof这些操作符,都是在这里介绍的。
(2)然后呢要看看一些基本的数据类型。首先是数值类型,是分为了整型、浮点型还是像OJC这样的全是NSNumber,还要看看原始类型和非原始类型的区别。如果是数值的话,还要看看怎么获取随机数、怎么进行科学计算、怎么进行类型转换。接下来,还要看看空类型、布尔类型、可选类型和枚举类型是怎么定义的。
(3)接下来呢,看看字符串类型是怎么用的。字符串也是每个语言必备的,说难不难,说简单吧,那么多用法呢。基本上就要看看它是怎么创建增删、怎么索引遍历、怎么进行类型编码还有些像反向啊之类的基本操作。这里面也会有很多小的知识点,譬如Java里面字符串是不可变类型,譬如PHP里面你连接字符串不能用加号。
(4)然后呢,就要看看结构体是怎么定义的了,这个在Swift里面还是挺重要的,不过在有些语言里就没有。
(5)下面就要看看基本的时间日期类型,这里还会涉及到时区转换啊、日历啊等等方面。基本上各个语言的时间日期,要么是原生提供的不错,要么就会有第三方类库支持,譬如JavaScript中的Moment.js,还是很不错的。
(6)上面讲的几个数据类型都还好,现在开始就要了解高级复杂数据类型,也就是所谓的集合了。笔者把集合分为了序列类型与键值索引两大部分,譬如分别对应Java中的List和Map。这边也是要了解集合的创建增删、索引遍历、类型转换还有排序啊、查找啊等等高级用法。
(7)最后在这里还要学学不可变数据,这一点在函数式编程里面很流行,就好像Facebook提供的Immutable.js这个类库,还是很不错的。
接下来就要看看流程控制与异常处理方面的知识了,首先要知道运算符相关,像逻辑运算符啊、加减运算符啊还有运算符重载(运算符重载是能用于数据分析计算的语言的一个重要优势)。然后要看看怎么进行分支选择的,也就是常见的if、switch语句,在Swift中还有guarantee这样好用的语句。接下来就要看看怎么进行常见的循环了,最经典的肯定就是for循环,之后各个语言也都各有扩充,像什么for-in、for-of、forEach循环,它们都是属于循环遍历。还有就是while以及do-while这种变种。
看完了循环下面继续看看流程控制,就像break、continue这种,还有goto这样可以随便乱跳的语句。下面要继续了解些作用域相关的知识,像JavaScript里面,一不小心就全局作用域了。然后还有关于迭代器的知识,在很多语言里迭代器和生成器是密不可分的,而在Java里面迭代器是一个接口。迭代器放在流程控制里也是因为一般来说迭代器也是用于循环的。
最后,我们要来看看异常处理,包括怎么定义异常、怎么抛出异常,还有怎么用try-catch-finally这种形式来捕获和处理异常。Swift里面提供了try?的用法,也是非常Sweet。
接下来我们继续学习函数的概念,唔,像Java这种完全的OO的语言,是没有函数的,里面只有方法,这也是它经常被诟病的地方,老说别的语言HelloWorld就一行,但是Java里面要写好多行。在这里笔者是把包括方法啊、函数都放在这边介绍。
(1)函数定义
首先呢要来看看函数是怎么定义的,不同的语言里定义方式有区别有交集。像有什么func、function、define等等N多不同的关键字。要注意下这个函数是不是需要返回值的,像Java里面没有返回值就是void,而Swift里面可以写可以不写,还有很多弱类型语言里没有返回值。另外还要看看怎么定义函数变量,这个和闭包经常放在一起使用。
(2)参数调用
看完了定义再看看参数定义和调用方式。参数的话需要了解下有没有默认参数和外部参数。笔者刚接触OJC的时候,它的外部参数确实大大提高了可读性,后来Swift继承并且发扬光大了。下面就要看看不定参数,譬如怎么在Java里面定义不定参数。最后,要看看引用传值和复制传值的区别,在有些语言里还存在有in-out这样的关键字。
(3)匿名函数/Lambda/闭包
Java8里面引入了Lambda的用法,Lambda本身也是函数式编程的一枚标杆,是一种设计模式吧。这里要看看Lambda怎么用,像有的语言里是->,有的是=>,这个要区分下。还有就是看看闭包怎么定义,Swift里面提供了一个尾随闭包的调用方式,非常方便。
(4)生成器
生成器、yield,最早笔者是在Python中接触到的,现在看ES里面也引入了这个概念。生成器一般和迭代器搭配在一起使用,不过也可以用来编写异步代码。
(5)装饰器
装饰器感觉有点像AOP的概念,笔者也是在Python和Angular2中接触到的。
(6)函数柯里化和反柯里化
在计算机科学中,柯里化(英语:Currying),又译为卡瑞化或加里化,是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函 数,并且返回接受余下的参数而且返回结果的新函数的技术。这个技术由 Christopher Strachey 以逻辑学家哈斯凯尔·加里命名的,尽管它是 Moses Schönfinkel 和 Gottlob Frege 发明的。这是来自维基百科的名词解释。顾名思义,柯里化其实本身是固定一个可以预期的参数,并返回一个特定的函数,处理批特定的需求。这增加了函数的适用 性,但同时也降低了函数的适用范围。笔者在JavaScript与Scala会比较常用这个特性,这里以JavaScript为例说明柯里化的核心思想。
这里主要学习下模块化的概念,譬如Java、C#里面都会存在有命名空间,而Swift里是全局命名空间。还有像ES6里,这个export、import关键字到底是咋用的。
笔者还真没接触过Lisp、Haskell这样纯函数式语言,基本上都是OO的吧。那么类与对象也就是非常重要的一个部分。
(1)类的定义
怎么定义类、怎么用public、private、protected或者类似的方法来划分可见域、怎么来划分属性。像Swift里面还有延迟加载啊、属性监控啊等等。怎么来定义方法(和上面的函数一起看)。
(2)对象
怎么初始化对象,有的语言里有new,有的没有。怎么实践单例模式。还有就是this或者self这样类似的用法到底干啥的,像JavaScript里面,因为最早的时候没有OO的概念,各种自定义的对象,这时候this的用法也就非常的杂乱。还有就是对象属于哪个类型进行的判断,这一点和变量章节有所重复。
(3)继承
怎么继承一个对象,还有就是继承之后的方法对于访问的父类中的属性啊、重载啊咋搞的,这个在Java面试题里面经常碰到。
(4)抽象类、接口/协议与委托
怎么定义抽象类或者接口,在Swift和OJC中是协议的概念,还有就是譬如Java中的怎么定义一个注解。
(5)内部类
这个在Java中用的比较多,又分为静态内部类、成员内部类、局部内部类以及匿名内部类。
(6)反射与类装载
这里介绍基本的输入输出的方法,包括控制台的输入输出、参数的处理、文件基本的读写,还有像Java里面繁多的什么字节流、字符流啊进行介绍。
学完了语法基础,那我们的笔记就要进入其他的具体的应用了,这里又分为Advanced、Storage、TestRelease、SysProc这几个部分。
在这里就要进行泛型编程、内存管理、序列化和反序列化、编程规范和代码风格以及由该语言实现的算法的学习。
本部分主要介绍网络访问、网络调用相关。包括了NetworkManagement(网络管理)、Socket、HttpClient(网络客户端)、RPC/RMI(远程调用)
在这里存放文件系统、数据库存储等等相关的内容。包括了缓存,像Java里缓存又会分为on-heap和off-heap两种。然后就要看看常见的数据库,数据库包括了KeyValue数据库,最常见的就是Redis。还有文档型数据库,最常见的就是Mongodb,还有关系型数据库。关系型数据库的使用中又要注意ORM和数据库分区分表等等插件。
这里主要是测试啊、发布啊相关的内容。包括了单元测试,像JUnit、Debug,像在PHP里面用XDebug实现单步调试,还有Log 日志,像著名的log4j,还有就是运行状态监控。
这里主要存放系统进程相关的内容,包括了切面编程和最重要的并发、同步相关的知识。
(1)并发
并发这部分要了解多线程的基本概念、线程通信的基本概念。基本的异步模式,像Promise、Callback啊等等,还有就是异步的数据流,也就是消息总线,还有就是响应式开发。
(2)同步与线程安全
这边要了解锁的基本概念,譬如Java中的synchronized和Lock。然后还要了解一些内建的线程安全的数据结构。