代码是最好的笔记
网络上有很多关于如何写读书笔记的方法,但问题是我还是不理解其中的奥义,我自己在笔记中也写过很多种方法,但都没有一套成型的方法出来,我的笔记风格也是一直都在转变。我喜欢 Wikipedia 那种,但也不喜欢它没有结构,在写《从程序的角度来理解世界》的时候我突然有了灵感,其实这不就是最佳的笔记方案吗?
为什么要记录笔记,从《如何阅读一本书》中作者提出两种读书的目的:一是为了获取资讯而阅读;二是为了增进理解而阅读。做笔记也是适用于着这两种目的,但可能还有另外一种就是管理,例如子弹笔记。所以本文中所说的「笔记」更多的是指第二种:「为了增进理解而记录的笔记」。这类笔记当中通常记录着一些概念(名词解释)以及方法等,其实最终的形态都是为了构建一套属于自己的知识体系。
我觉得全人类都是可以公用同一套知识体系的,Wikipedia 就是一套很不错的方法,只允许引用而不允许发表自己的观点,我很认同这种做法。只是 Wikipedia 本身并不是一个很好的编辑器,而且很多时候已经变成了编辑们的观点之争,而变得不那么纯粹。而且因为内容是随时可以被其他修改的,你昨天成型的知识框架可能在今天就已经「过时」了。所以每个人都有必要形成一套属于自己的知识体系,Wikipedia 是自己形成这种体系的很重要的参考。
在《从程序的角度来理解世界》的开头有提到:
在面向对象编程中,其核心就是「对象」(Object),围绕着对象建立起属性和方法。
因此笔记的核心同样是概念(对象),每一篇笔记实际上都是在解释一个概念(是什么),描述这种概念有哪些属性(从哪些方面去理解),以及可以有哪些方法(可以用来做什么)。
属性可以理解概念内部的元素,以及这些元素是如何计算的。子概念也是在属性中外链到对应的笔记。如果其他的元素影响到了某个属性,也是在这里进行说明。方法可以理解为概念对外的影响力,概念可以进行一些操作来影响其他概念,通过这里来关联。
因此从最高层去看一篇笔记,它的结构应该是这样的:
# 概念名称
## 定义
## 内在属性
## 对外方法
这种结构就像是在代码中在声明一个「类」:
class MyClass: // 定义
i = 12345 // 属性
def f(self): // 方法
return 'hello world' // 步骤
定义
定义就是解释评判一个事物是否是这个概念的标准,例如我们可以说满足某些条件的就可以被称之为 A,满足某些条件的就一定不是 A。因此通常定义中包含的是一些常量,这些常量是不允许被修改的,例如我们定义「公开的文章」的意思是以「已经发了的文章」,那么在定义中我们可以说「发布状态为已发布的文章」。这句话中有两层定义,首先「已发布的文章」是一种「文章」,一种「发布状态」等于「已发布」的「文章」。这里的 发布状态 == 已发布
就是一个常量,应当出现在定义当中。
定义的名称
因为这个笔记/知识体系是属于个人的,因此定义不一定要和大众的认知相同,你完全可以把狗定义成猫,只要在自己的系统中达成一致即可。
class Dog: // 定义
name = "cat" // 属性
def bark(self): // 方法
return 'meowing' // 步骤
当然好的笔记是我们尽可能的靠近大众的使用习惯,这也有助于我们理解其他人的文章和书籍。作为读者,在《如何阅读一本书》的规则五有提到:
规则五:诠释作者的关键字,与他达成共识。
这里的「关键字」实际上一个个的概念名称,这里会可能出现几种情况:
- 自己知道这个概念;
- 自己不知道这个概念;
已知的概念
如果已经知道,那么接下来要做的就是对比作者的定义,作者对这个概念的定义是否与自己的相一致,这里同样可能出现几种情况:
- 与自己的定义相一致,可能表达上略有不同:此时我们可以确定作者所说的与我们所理解的概念是同一事物,所以不需要做什么;
- 可以补充自己的定义:作者所说的与我们所理解是同一事物,但是作者通过其他角度来丰富了这个概念,此时我们需要用作者的描述来补充自己的定义;
- 与自己的定义完全不同:作者说的是完全另外一种事物,此时还可能出现几种情况:
- 我们理解的概念中有另外一个概念 B 与之相同:此时我们可以得知作者所说的这个概念等于我门自己的概念 B;
- 我们理解的概念中没有任何一个概念与之相同:此时作者所说的是一个全新的概念,我们可以将其收录在自己的笔记中,但是对于名称最好去一个不同的;
因此定义中也包括了几方面的内容:首先说明是什么,有什么样的特点,以及其目的。
## 定义
是什么
### 特征
### 目的
···
属性
属性就是列举出我们可以通过哪些维度来描述这个概念。例如上文中的「文章」的属性可以包括:标题、内容、作者、发布状态、发布日期等。属性中包含可能的属性值,例如「发布状态」可能的值包括:已发布、未发布,据此我们可以产生两个子概念,也就是未发布的文章和已发布的文章。这点正如在《从程序的角度来理解世界》所描述说的那样:
每一个「属性值」的「对象」我们可以理解为该对象的一个「子对象」。
对于属性,可以通过以下几点来进行描述:
- 该属性的可选值;
- 解释它的默认值;
- 影响该属性的外部因素,也就是该属性值取决于什么因素;
- 该属性会影响的外部因素;
...
## 属性
### 发布状态
#### 可选值
- 已发布 [[已发布的文章]]
- 未发布 [[未发布的文章]]
#### 默认值
- 未发布
#### 取决于
- 编辑对文章的操作
#### 会影响
- 读者对文章的可见性
...
方法
方法就是这个概念可以做什么。通常方法可能会有一些前提条件,以及步骤。
前置条件实际上就是子概念中的一些预设的条件,所以这里的方法是已经预设子概念中的条件之后可以「无条件」执行的方法。如果有条件,那么这个方法应该放在对应的子概念当中。
方法里面实际上是步骤,每一个方法都是如何做去一件事情,那么笔记记录的就是做这件事情的步骤。
因为笔记只是解释概念,而不是输出观点,所以它不应该包含「为什么」的内容,就好像代码中不会解释为什么这段逻辑是这样,如果需要可以给出一段参考链接。我的理解笔记是沉淀已知的内容,对于未知,可能在另外一种类型的笔记,不在本文的讨论范围。
以上是我对笔记的初步思考,会在尝试之后逐步完善。