代码是最好的笔记

随笔

网络上有很多关于如何写读书笔记的方法,但问题是我还是不理解其中的奥义,我自己在笔记中也写过很多种方法,但都没有一套成型的方法出来,我的笔记风格也是一直都在转变。我喜欢 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'              // 步骤

当然好的笔记是我们尽可能的靠近大众的使用习惯,这也有助于我们理解其他人的文章和书籍。作为读者,在《如何阅读一本书》的规则五有提到:

规则五:诠释作者的关键字,与他达成共识。

这里的「关键字」实际上一个个的概念名称,这里会可能出现几种情况:

  1. 自己知道这个概念;
  2. 自己不知道这个概念;

已知的概念

如果已经知道,那么接下来要做的就是对比作者的定义,作者对这个概念的定义是否与自己的相一致,这里同样可能出现几种情况:

  1. 与自己的定义相一致,可能表达上略有不同:此时我们可以确定作者所说的与我们所理解的概念是同一事物,所以不需要做什么;
  2. 可以补充自己的定义:作者所说的与我们所理解是同一事物,但是作者通过其他角度来丰富了这个概念,此时我们需要用作者的描述来补充自己的定义;
  3. 与自己的定义完全不同:作者说的是完全另外一种事物,此时还可能出现几种情况:
  4. 我们理解的概念中有另外一个概念 B 与之相同:此时我们可以得知作者所说的这个概念等于我门自己的概念 B;
  5. 我们理解的概念中没有任何一个概念与之相同:此时作者所说的是一个全新的概念,我们可以将其收录在自己的笔记中,但是对于名称最好去一个不同的;

因此定义中也包括了几方面的内容:首先说明是什么,有什么样的特点,以及其目的。

## 定义
是什么

### 特征

### 目的

···

属性

属性就是列举出我们可以通过哪些维度来描述这个概念。例如上文中的「文章」的属性可以包括:标题、内容、作者、发布状态、发布日期等。属性中包含可能的属性值,例如「发布状态」可能的值包括:已发布、未发布,据此我们可以产生两个子概念,也就是未发布的文章和已发布的文章。这点正如在《从程序的角度来理解世界》所描述说的那样:

每一个「属性值」的「对象」我们可以理解为该对象的一个「子对象」。

对于属性,可以通过以下几点来进行描述:

  • 该属性的可选值
  • 解释它的默认值
  • 影响该属性的外部因素,也就是该属性值取决于什么因素;
  • 该属性会影响的外部因素;
...

## 属性
### 发布状态
#### 可选值
- 已发布 [[已发布的文章]]
- 未发布 [[未发布的文章]]
#### 默认值
- 未发布
#### 取决于
- 编辑对文章的操作
#### 会影响
- 读者对文章的可见性

...

方法

方法就是这个概念可以做什么。通常方法可能会有一些前提条件,以及步骤。

前置条件实际上就是子概念中的一些预设的条件,所以这里的方法是已经预设子概念中的条件之后可以「无条件」执行的方法。如果有条件,那么这个方法应该放在对应的子概念当中。

方法里面实际上是步骤,每一个方法都是如何做去一件事情,那么笔记记录的就是做这件事情的步骤。


因为笔记只是解释概念,而不是输出观点,所以它不应该包含「为什么」的内容,就好像代码中不会解释为什么这段逻辑是这样,如果需要可以给出一段参考链接。我的理解笔记是沉淀已知的内容,对于未知,可能在另外一种类型的笔记,不在本文的讨论范围。

以上是我对笔记的初步思考,会在尝试之后逐步完善。