程序员超强大脑
上QQ阅读APP看书,第一时间看更新

任何陌生的代码都会在一定程度上困扰程序员,但并非所有代码都以同样的方式困扰他们。我们通过 3 个不同的代码示例加以说明。3 段代码分别采用 APL、Java 和 BASIC 编写,作用都是把给定的 N 或 n 转换为相应的二进制表示。

请花几分钟时间仔细阅读这 3 段代码,想一想需要具备哪类知识来阅读代码以及理解这些代码所需的知识有什么不同。你也许暂时不清楚如何形容阅读代码时大脑的活动情况,但我想阅读每段代码的感觉应该都不一样。在读完本章后,你就会知道该使用哪些术语来描述不同的认知过程。

如代码清单 1-1所示,第一段代码采用 APL 编写,作用是把 n 转换为相应的二进制表示。本例的困惑之处在于程序员不一定清楚 T 的含义。也许只有 20 世纪 60 年代的数学家才接触过 APL,它是“A Programming Language”的缩写。这门语言专为数学运算而设计,如今已很少使用。

代码清单 1-1 n 的二进制表示(APL)

2 2 2 2 2 ⊤ n

如代码清单 1-2所示,第二段代码采用 Java 编写,作用是把 n 转换为相应的二进制表示。本例的困惑之处在于程序员可能不了解 toBinaryString() 方法的用途。

代码清单 1-2 n 的二进制表示(Java)

public class BinaryCalculator {
    public static void mian(String[] args) {
        int n = 2;
        System.out.println(Integer.toBinaryString(n));
    }
}

如代码清单 1-3所示,第三段代码采用 BASIC 编写,作用是把 N 转换为相应的二进制表示。本例的困惑之处在于大脑无法记住执行过程的所有步骤。

代码清单 1-3 N 的二进制表示(BASIC)

 1  LET N2 =  ABS (INT (N))
 2  LET B$ = ""
 3  FOR N1 = N2 TO 0 STEP 0
 4      LET N2 =  INT (N1 / 2)
 5      LET B$ =  STR$ (N1 - N2 * 2) + B$
 6      LET N1 = N2
 7  NEXT N1
 8  PRINT B$
9  RETURN

接下来,我们深入剖析阅读 3 段代码时遇到的情况。首先讨论 APL 程序,如代码清单 1-4所示,请观察这段代码如何把 n 转换为相应的二进制表示。本例的困惑之处在于程序员可能不清楚 T 的含义。

代码清单 1-4 二进制表示(APL)

2 2 2 2 2 ⊤ n

如果本书的大多数读者既不熟悉 APL,也不清楚运算符 T 的含义,那么缺乏知识就是困惑的根源所在。

对第二段代码来说,困惑的根源有所不同。只要对程序设计有一定了解,那么就算不是 Java 方面的专家,大脑也能检索到 Java 程序的相关信息。如代码清单 1-5所示,这段代码的作用是把 n 转换为相应的二进制表示,而不了解 toBinaryString() 方法的用途可能令程序员感到困惑。

代码清单 1-5 二进制表示(Java)

public class BinaryCalculator {
    public static void mian(String[] args) {
        int n = 2;
        System.out.println(Integer.toBinaryString(n));
    }
}

虽然根据方法名可以推测出 toBinaryString() 方法的用途,但要想深入了解这段代码的作用,还要浏览其他代码以找出 toBinaryString() 方法的定义,并从声明该方法的位置继续阅读。因此,本例的困惑之处在于缺乏信息:很难判断 toBinaryString() 方法的具体用途,需要从其他代码中寻找线索。

阅读第三段代码时,可以根据变量名和操作合理推测代码的作用。但是在阅读代码的过程中,大脑很难处理整个执行过程。这段代码的作用是把 N 转换为相应的二进制表示,困惑的原因在于大脑无法记住执行过程的所有步骤。如图1-1所示,为厘清每一步的脉络,可以把变量的中间值写在代码行旁边作为参考。

图1-1 二进制表示(BASIC)

本例造成的困惑与大脑缺乏加工能力有关,因为要同时记住所有变量的中间值和相应的操作绝非易事。如果确实希望心算这段代码的结果,那么可能需要用纸和笔记下几个中间值,或者像图1-1 那样把中间值写在代码行旁边。困惑总是面目可憎、令人生厌,上述 3 个示例展示了困惑的 3 个来源。第一种困惑源于不了解正在阅读的编程语言、算法或领域。第二种困惑源于无法获得理解代码所需的全部信息,尤其是如今的代码经常使用各种库、模块或包,想读懂代码就需要检索大量信息,而在收集新信息的同时还不能忘记原本应该完成的任务。第三种困惑源于代码有时过于复杂,超出了大脑的加工能力。

1.2 节将详细介绍 3 种认知过程,它们分别对应于上面讨论的 3 种困惑。