抽象封装的泄露
原文地址:The Law of Leaky Abstractions
此文作者 Joel Spolsky 曾任知名技术论坛网站 StackOverflow 的 CEO,此文虽作于 2002 年,但对于 22 年后的我仍有启发,故此记录。
TCP 协议以可靠性著称,它保证了数据能够完整、有序地到达目的地。但与此同时,被 TCP 协议封装的 IP 协议却是不可靠的:它不保证你发送的数据能无损、有序地到达。
在计算机中,像这样的抽象比比皆是:
- 编程语言中的字符串:它能让你对字符串的操作像操作数字一样简单
- 操作系统的文件系统:它将无数的比特所在的磁盘抽象成文件夹和其中的文件
让我们回到 TCP 协议,我们说过 TCP 的可靠性,但这只是一定程度上的。如果你的网线被剪断,你能请求就永远不可能被传输成功。这就是我所说的抽象泄露。
TCP 是一个在不可靠的网络设施基础建立的可靠抽象,但在一些时候,基础设施的不可靠仍会透过这一层抽象,影响到使用抽象的你。
这种抽象泄露的例子同样比比皆是:
- 遍历一个二维数组时,按行遍历和按列遍历的效率可能会天差地别
- 在使用 SQL 查询时,
where a=b and b=c and a=c
就是比结果相同的where a=b and b=c
更快 - 在使用 C++ 字符串类时,你可以通过
s + "bar"
拼接字符串,却不能使用"foo" + "bar"
- ...
由于抽象泄露十分普遍且不可避免,学习底层原理就成了成为优秀的程序员必做的事。如果你不了解 char *
和 STL string 的区别,你就会震惊于 s + "bar"
能够正常运行而 "foo" + "bar"
过不了编译。