第2章 你好,世界
要了解计算机不能做什么,我们需要先了解计算机擅长什么,以及它的工作原理。为此,我们将编写一个简单的计算机程序。程序员每学习一门新的编程语言,都会先做这样一件事:写一个“Hello,world”(你好,世界)程序。如果你在学编程,不管是在编程训练营,还是在斯坦福大学、社区大学或是网上教程,你也很可能会被要求编写一个。“Hello,world”是布赖恩·克尼汉和丹尼斯·里奇于1978年出版的经典著作《C程序设计语言》中的第一个编程项目,用于教读者如何(用C语言)创建程序,在屏幕上显示“Hello,world”。克尼汉和里奇当时在贝尔实验室工作。贝尔实验室可以说是现代计算机科学界中的智库,地位好比巧克力界的好时巧克力。(感谢AT&T贝尔实验室的垂青,我在此也工作了多年。)计算机科学界的大量创新都起源于贝尔实验室,包括激光、微波和Unix系统(除了C语言之外,丹尼斯·里奇也参与了Unix的开发)。C语言之所以叫C语言,是因为它诞生于贝尔实验室所写的“B语言”之后。C++是一种如今仍然流行的语言。它和它的近亲C#一样,都是C语言的后代。
因为我喜欢传统,咱们就以“Hello,world”开头吧。请取出一张纸和一支笔,然后在纸上写“Hello,world”。
祝贺你!很简单吧?
实际上,这是一个非常复杂的过程。你在脑中形成了一个意图,收集了必要的工具,以实现脑中的这个意图,大脑向你的手发送了一条信息,告诉它要写什么字母,并让你的另一只手或身体的其他部位在你书写的时候稳住这张纸。经过这样一通折腾,这个意图才能正常实现。你的身体按照你的指示,执行了一系列步骤,以实现特定的目标。
现在,咱们让计算机来做同样的事。
打开文字处理程序(Word、Notes、Pages或OpenOffice,只要能用文字处理程序就行),创建一个新文档。在文档中,键入“Hello,world”。如果你乐意,可以打印出来。
再次祝贺你!你使用不同的工具执行了相同的任务:你的意图、物理显示等。你做得很棒。
下一个挑战是使用稍微不一样的方式,让计算机显示“Hello,world”。我们来编写一个将“Hello,world”显示到屏幕上的程序。就用Mac上自带的Python语言来写吧。(如果你用的不是Mac,流程会略有不同,你得上网查查流程。)在Mac上,打开“应用程序”文件夹,然后打开里面的“实用工具”文件夹。在“实用工具”文件夹中,有一个名为“终端”的程序(见图2.1)。打开它。
祝贺你!你刚刚提升了自己的计算机使用技能。你的计算机技能距离硬件只有一步之遥!
所谓“硬件”,是指计算机的芯片、晶体管和电线等,这些东西构成了计算机的物理形态。“终端”程序是一个精美的图形用户界面(GUI),打开它,你距离硬件就更近了。接下来,我们在“终端”程序里用Python语言写一个程序。这个程序将在计算机屏幕上显示“Hello,world”。
图2.1 我的“实用工具”文件夹中的“终端”程序
“终端”程序上有一个闪烁的光标。光标所在的地方,就是一个“命令行”。计算机会逐字逐句地将你在命令行中键入的所有内容进行解读。通常,在你按回车键时,计算机会尝试执行你前面所输入的所有内容。现在,我们来试试输入下面的内容:
python
你会在“终端”程序上看到下面的内容:
Python 3.5.0 (default, Sep 22 2015, 12:32:59)
[GCC 4.2.1 Compatible Apple LLVM 7.0.0 (clang-700.0.72)] on
darwin
Type "help," "copyright," "credits" or "license" for more
information.
“>>>”表示,你现在正在使用Python解释器,而不是常规的命令行解释器。常规的命令行解释器通常使用shell编程语言,Python解释器则使用Python编程语言。就像在口语中有不同的方言一样,编程语言中也有许多方言。
输入下面的内容,然后按回车键:
Print ("Hello, World!")
祝贺你!你刚刚写了一个计算机程序!感觉怎么样?
我们刚刚用三种不同的方法做了同样的事情。在这三种方法中,可能有一个最轻松,也可能有一个最快、最简单。哪种方法更容易、更快,取决于你的个人体验。要记住这一点:没有哪一个是最好的。非要说用技术办事比不用技术更好,就像是非说用Python写“Hello,world”比在纸上写更好一样荒谬。其实,两者之间没有可比性。使用哪一种方法更优,要看个人体验,以及实际使用之后产生的结果。“Hello,world”太简单了,随手一试就知道,风险非常低。
大多数程序比“Hello,world”复杂得多。只有能理解这种简单的程序,你才可以去理解更为复杂的程序。无论是最复杂的科学计算程序,还是最新推出的社交网络程序,每一个程序都是由人编写的。而这些人都是从“Hello,world”开始编程的。他们构建的复杂程序,都从构建简单的代码块(如“Hello,world”)开始。他们会逐步将简单的代码块添加到程序中,让程序慢慢变得更加复杂。计算机程序并不神奇,它们只是人做出来的东西。
比如说,我想写一个显示10遍“Hello,world”的程序。我可以重复写10行命令:
print ("Hello, world!")
print ("Hello, world!")
呃,我才不会那么做呢。才写了两遍,我就觉得没意思了。还要敲击8次“Ctrl+P”,太麻烦了。(懒惰有助于你像程序员一样思考。)许多程序员觉得打字非常乏味,于是他们尽量少打字。与其输入10遍代码,或是复制、粘贴那一行代码,还不如写一个循环,让计算机重复执行10次这一行代码。
x=1
while x<=10:
print("Hello, world!\n")
x+=1
这就有趣多了!现在,电脑会帮我完成这项任务!等等,刚刚发生了什么?
我把x的值设为1,并且创建了一个WHILE循环。WHILE循环会一直执行,直到达到停止条件x>10。第一次循环时,x=1。程序会显示“Hello, world!”以及一个回车符或行结束符(代码中用“\n”表示)。反斜杠在Python语言中是一个特殊字符。根据Python语法,解释器一遇到这个字符就“知道”,接下来要对反斜杠符的文本所示做出反应。在这个示例中,我让计算机显示一个回车符。要是我们必须给每一台笨重的大块头计算机从零开始编程,以构建它的底层功能,比如让它读取文本并将其转换成二进制,或是让它根据所选编程语言的语法规则来执行指定的任务,那就太令人痛苦了。啥都干不了了!因此,所有的计算机都有内置的功能,也都允许增加功能。我刚才使用“知道”这个词,只是为了方便读者理解。记住,计算机并不像有意识的人那样,能“知道”些什么。计算机内部没有意识,只有一些功能模块在同时运行着,那个场面静默而壮丽。
下一行的“x+=1”,表示给x的值加1。这个语法规则借鉴了C语言,我认为它相当优雅简洁。以往在编程中,为让变量进入下一个循环,编程者得写上无数个“x=x+1”。C语言的设计人员觉得这样太无趣了,于是写了一个快捷方式。其实,“x+=1”和“x=x+1”是一样的,有时候也写成“x++或++x”。几乎每一门编程语言都对“x=x+1”有不同的快捷表达方式,因为程序员对它的使用率非常高。
循环了一次之后,此时x=2,程序运行到了WHILE循环的最后一行。在while语句下方的命令行,若行首有空格,表明当行属于while循环。程序运行到循环的末尾之后,就会回到循环的开头——“while”开头的那一行,并再次检查运行条件:x是否小于或等于10?若是,程序再次执行指令,在屏幕上显示“Hello, world!\n”,效果如下:
Hello, world!
然后,再给x值加1。现在,x=3。程序再次回到循环的开头,以此循环往复,直到x=11。当x=11时,就满足了这个循环的停止条件,于是循环就此终止。你可以这样理解这个逻辑:
如果x小于或等于10
则:执行循环指令
否则:执行下一步骤
程序每一次执行循环都是一个小步骤。如果能将许许多多像这样的小步骤组合在一起,聚沙成塔,你就能干成大事儿。计算机编程人员非常擅长分析任务,将任务拆解成非常多的小步骤,并且让计算机处理每一个小步骤。只要将所有小步骤放在一起,再稍加修改,让它们互相配合,很快你就得到了一个能运行的计算机程序。现在的程序都是模块化的。所谓模块化,就是说可由不同的程序员构建不同的模块,而且只要将模块正确地拼接上,它们就能正常运行。
现在我们已经写了一个程序,让我们来聊聊数据。程序可以输入数据,也可以输出数据。数据(即信息点或信息单位)的生成方式多种多样。美国国家气象局每天都在美国数千个地点收集高温和低温数据。计步器能够记录你每天的步数,按日、按周、按年为你生成步数曲线。我认识的一个幼儿园老师,每周一让孩子们计算班上同学的衣服口袋总数。数据可以告诉我们有多少人购买了某顶帽子,自然界还有多少濒危的白犀牛,极地冰盖正在以多快的速度融化,等等。数据的魅力是无穷的,它给予我们洞见。它使我们有能力了解世界,让我们能设法理解超出我们理解范畴的概念。(不过,如果你都能阅读这本书了,你的理解力应该早就超出应对“同学们总共有多少个衣服口袋”这种问题了。)
虽然数据可由许多方式生成,但上述所有的示例都有一个共同点:所有数据都是由人类生成的。所有数据都是如此,无一例外。最终,数据的本质就是人类在数数。如果我们不做深入的探究,可能会以为数据是从天神宙斯的脑中涌进这个世界的。我们还总是假定,因为存在数据,所以数据一定是正确的。本书的第一条原则就是:数据是由社会构建的。数据是人造的,如果你脑中有数据非人造的观念,请立即摒弃。
“那计算机数据呢?”一个熟知幼儿园小朋友衣服口袋数据收集问题的人可能会问。这个问题问得非常好。计算机生成的数据本质上也是由社会构建出来的,因为计算机就是由人类制造的。而数学也是人类创造的一个符号系统。顾名思义,计算机就是能计算的机器,能执行上百万次数学运算。计算机并非诞生自绝对的宇宙规律或自然法则,而是一些专业人员在特定的组织环境中,有意图地做了上百万个细微的设计决策,从而得到的产物。我们在理解数据以及计算机(作为生成并处理数据的机器)时,必须理解这样一个社会与技术背景:人类制造计算机,计算机制造数据。
要想了解计算机能输出什么,可以先了解一下计算机里面有什么。关于计算机,我们要知道一些事实。大部分计算机都有外壳,内部则由一些电路板和其他东西组成。我们来具体说说“其他东西”。电源、显示器的连接电路、晶体管、内置存储器和可写存储器,都是非常重要的零件。这些零件属于计算机的“硬件”。计算机的硬件是物理实体,软件则是在硬件上运行的任何东西。
20世纪90年代,我在高中首次了解计算机的物理本质。当时,我参加了洛克希德·马丁公司赞助的一个特殊的青少年工程项目。我所在的新泽西小镇上有一个洛克希德工厂,它的大楼外形像一艘战舰,还有方圆好几英里[1]的空置农田。当时盛传该工厂专门制造核武器,而金色的麦浪下藏着导弹发射井。如果苏联攻打过来,导弹发射井可以升到地面,发射核导弹进行反击。当时,冷战还未结束。惊悚的迷你剧《浩劫后》(The Day After)展示了核灾难的余殃,搞得人心惶惶。我们会时常讨论,美国的导弹藏在哪里,苏联的导弹会打到哪里,如果苏联打过来,我们该怎么办,等等。每个月,我都会乘校车去几次洛克希德工厂,与当地学校的其他一些青少年见面,一起学习工程学相关的知识。
人们有时会说,计算机就像人的大脑。事实并非如此。如果截掉一块脑组织,大脑就会“变道”,创造新的通路,以补偿缺失脑组织造成的问题。想想2011年美国亚利桑那州众议院女议员加比·吉福兹颅脑损伤的事件。当时,吉福兹正在西夫韦杂货店的停车场与选民交流,独行枪手贾里德·李·拉夫纳突然近距离向她开枪,她的头部中弹。接着,拉夫纳又朝停车场内的人群盲目射击,导致6人死亡,18人受伤。此前,他一直在跟踪吉福兹。
在停车场子弹横飞的时候,吉福兹手下的实习生小丹尼尔·埃尔南德斯扶她起来,并且给她头部的伤口施压。最后,旁观者制服了枪手,警察与急救人员也到达了现场。吉福兹当时的伤势非常严重。医生为她实施了紧急脑部手术,并且用药物使她保持医学昏迷状态,以保护她受伤的大脑,给大脑足够的恢复时间。四天之后,吉福兹睁开了眼睛。她无法说话,几近失明,但她活下来了。
吉福兹坚毅地踏上了漫长的康复之路。要恢复说话并非易事,她接受强化治疗,痛苦地重新学习说话。许多遭受此类颅脑损伤的人的嗓音会发生很大变化,吉福兹也不例外。她现在说话比以前要慢很多,听起来也非常不流畅。她一说话就非常疲劳。她的大脑创造了新的通路,以替代在事故中缺失的旧通路。人的大脑神奇就神奇在这里:在特殊的情况下,它能够以特殊的方式进行自我修复。
计算机做不到这一点。如果拿走计算机的一块组件,它就运行不了了。存储在计算机里的内容都有对应的物理地址。本书的草稿就存在我电脑硬盘里的一个特定地址。如果这处地址被抹去,我就会丢失那些我精心润色过的文本。那就坏了——我可能会有点小崩溃,并且会错过截稿日期。不过,本书的构想仍然存储在我的脑子里。如果有必要,我可以重新写出这些文本。人的大脑比硬盘要灵活得多,适应性也强得多。
我在洛克希德工厂学到了许多有用的知识,这是其中一个。我还发现,很多科技公司里会有许多刚过时不久的电脑备用零件,都是员工升级电脑或是离职后留下的。每个参加青少年工程项目的人都分到了一个Apple II的机箱、一块电路板、一些内存芯片、一些色彩鲜艳的带状电缆,还有各式各样从工厂(可能是核电站)不同的办公室捡来的其他零件。我们将这些组件接在一起,插上电源,听老师解释各个零件的功能。机箱很脏,键盘有点黏糊糊的,所有的电路板都落满了灰尘,但我们都不在意这些。我们只管组装自己的电脑,这很有意思。装完电脑之后,我们就学着使用一种简单的编程语言BASIC给电脑编程。在学期末,我们得以留着各自组装的电脑。
我讲这个故事的用意是希望读者知道,电脑可以由人类手工组装,而且确实就是由人的双手组装而成的。我的新闻编程课上的学生就是对技术无所适从的一批人。他们总是担心会弄坏电脑,或是用电脑造成什么毁灭性的后果。“没事儿,你们得用锤子才能弄坏电脑。”我这样告诉他们。一开始,他们都不太相信。到了学期末,他们才变得没那么畏首畏尾。哪怕弄坏了什么东西,他们也有信心修复或是搞清楚问题所在。这种自信是培养技术素养的关键。
你不是我班上的学生,我无法直接给你一台电脑,但我希望你能尝试亲手拆开一台旧电脑。就拿你自己的旧电脑试试吧。如果自己没有旧的,可以去二手商店买一台,想必不会太昂贵。你也可以问问你们办公室的相关人员。专管技术或者网络的工作人员通常会有一些旧设备用不上,要么放着做装饰,要么来不及回收。台式电脑是最适合用来拆卸的。
我们来试试把电脑拆开。如果你拆的是笔记本电脑,那你可能需要一把小螺丝刀。一般来说,台式电脑的内部结构如图2.2所示。
观察一下,看看图中的零件如何互相连接。跟着输入电路(USB端口、视频端口、音频端口)的线路,看看线路连到了哪里。不妨摸摸粘在电路板上的那些长方形块状物。试试找一下微处理器芯片的位置——瞧瞧哪个零件上印着“Intel”,就八九不离十了。微处理器是主机里最关键的零件。再找找看,哪条线路是连接硬件和电脑显示器的。这种连接线多半是特别粗实的带状电缆,它将图形类信息传输给显示器,显示器则将这些信息按程序指定的方式展示出来。
回想刚才你写的第一个Python程序。你在键盘上打字,这些信息从键盘传输到了主机,然后被逐字解释。随后,主机向另一个零件——显示器发出指令,让它显示“Hello,world”。不论程序指令简单还是复杂,任何程序都是这么运行的。
图2.2 台式电脑的内部结构
拆电脑这个活动非常适合亲子互动。在我儿子上小学的时候,我曾和他一起拆了一台笔记本电脑。当时,我打算回收几台笔记本电脑,于是我把硬盘从电脑上拆下来,打算在扔掉之前,先用锤子砸碎它们。(我发现,砸碎硬盘要比清空硬盘数据更简单,而且操作起来更痛快。)我问儿子愿不愿意帮把手,帮我把硬盘从电脑上拆下来。他说:“你开什么玩笑?我何止想拆硬盘,我想把整台电脑都拆了。”于是,我们一起在厨房的柜台上把两台笔记本电脑大卸八块,度过了愉快的一两个小时。
在我的大学课堂上,我们先摆弄摆弄硬件,然后就开始聊软件——包括“Hello,world”。所谓软件,就是所有在硬件上运行的东西。有了软件,你就可以用键盘输入指令,然后让机器按你的指令执行任务。有了软件,“Hello,world”程序才可以运行——在屏幕背后,你输入的文字被编译成了计算机能够理解的指令。硬件是物理实体,软件是硬件之外的所有东西。计算机编程和编写软件通常是一回事。
不瞒你说,编程其实就是数学。如果有人告诉你编程跟数学无关,或者你可以脱离数学来学编程,别上当,他们可能就是想骗你买他们的东西。
好消息是,学习编程入门知识所需的数学知识,大概等同于小学四五年级的水平。你需要懂得加法、减法、乘法、除法、分数、百分比和余数等概念。你还需要懂得基础的几何学知识,比如面积、周长、半径和圆周长等。你得知道一些基本的绘图术语,比如x轴、y轴和z轴。此外,你还得懂得函数的基础知识,比如,要把2变成22,我们要执行一个函数。
如果你有特别严重的数学恐惧症,可能这本书你就不想再读下去了。没关系!有太多言论主张人人都该学编程,我不能苟同。如果你实在不会算术,那勉强学编程可能会让你痛苦不堪。但如果你平时就能够计算就餐的小费,而且像估算该给客厅买多大的地毯之类的事情你也能轻易做到,那你学编程就没有问题了。
要从编程的入门水平进阶到中等水平,需要懂得线性代数、一点几何学和一点微积分的知识。不过,很多人即使只拥有基础编程水平,也能在编程这一行里混得风生水起。编程既是一门艺术,也是一门手艺。若把编程当作手艺,你可以跟师傅做学徒,然后以编程谋生。但若把编程当作一门艺术,则既要有极好的手艺,还需要接受高等数学方面的训练。我假定本书读者主要是把编程当作手艺的,我会以此为前提继续往下讲述。
有很多专业的方法可以描述软件如何与硬件协作运行。现在,我打算用一个比喻来说明。理解计算机的层级结构,跟理解火鸡俱乐部三明治的结构没什么两样(见图2.3)。
火鸡俱乐部三明治跟计算机的结构是相似的。它也有许多不同的组成部分,而这些食材配合得特别好,形成了一个美味的三明治。你会按特定的顺序来摆放三明治的食材,以得到你想要的口味。计算机也一样,会按特定的规则来运行。
做一个火鸡俱乐部三明治,要先把底层搭好。三明治的底层是面包片,计算机的底层则是硬件。硬件其实什么都不“知道”——它只知道如何处理二进制数据:0和1。所谓“处理”,其实就是“计算”。记住,计算机所做的任何事,本质上都是数学。
图2.3 火鸡俱乐部三明治
紧接着硬件层,是一个能将代码转换为二进制(0与1)的层。不妨叫它机器语言层。这一层就好比火鸡俱乐部三明治底层面包片上的一层食材。机器语言能将符号转换成二进制,好让计算机能理解并执行计算。这些符号是我们人类之间用以沟通的文字和数字。这是一个人工系统,而人类所使用的机器语言并非二进制,而是一种“方言”,叫作汇编语言。这种方言会将符号汇编成机器代码。
汇编语言非常难。下面是一个用汇编语言写10遍“Hello,world”的示例,是我在开发者网站Stack Overflow上拷贝来的:
org
xor ax, ax
mov ds, ax
mov si, msg
boot_loop:lodsb
or al, al
jz go_flag
mov ah, 0x0E
int 0x10
jmp boot_loop
go_flag:
jmp go_flag
msg db 'hello world', 13, 10, 0
times 510-($-$$) db 0
db 0x55
db 0xAA
读写汇编语言都不是易事,只有极少数人愿意花时间钻研这门语言。人类想要更轻松地传达计算机指令,就要依赖机器语言层上的一层结构:操作系统。我的Mac装的操作系统是Linux,这个名称取自它的创始人林纳斯·托瓦兹(Linus Torvalds)的名字。Linux操作系统基于Unix系统,Unix系统的创始人就是那位以“Hello,world”闻名于世的丹尼斯·里奇。你也可能很熟悉操作系统,哪怕你可能不知道它们的名字。20世纪80年代的个人计算机革命,有一部分要归功于操作系统的胜利。操作系统运行在机器语言层之上,人类与之沟通要比直接跟机器语言层沟通容易得多。
至此,电脑就能用了(尽管有点简陋)。只用Linux就能够直接运行各种刺激好玩的程序。然而,Linux是基于文本的系统,非常不直观。在Mac上,还有另一个操作系统,叫作OSX系统。OSX系统使用了独特的Mac式界面交互。这种交互方式叫作图形用户界面,它是史蒂夫·乔布斯的一项伟大创新:他发现以文字为主的用户界面使用起来难度很大,于是普及了一个操作方式,那就是将图片(图标)置于文字上方,并使用鼠标操控图片和界面。乔布斯的桌面图形用户界面和鼠标的灵感,来源于艾伦·凯在施乐帕克研究中心所领导的团队。施乐帕克研究中心是施乐的另一个研究实验室,1973年曾发布过一款带有图形用户界面和鼠标的计算机。我们总爱将技术创新归功于个人,但事实上很少有人能够单枪匹马在现代计算机领域做出任何革新。仔细观察,你会发现任何技术革新都会有一个逻辑上的前任,还有一大帮人为这个想法工作了好几个月或者好几年。乔布斯当年花钱参观了施乐帕克研究中心实验室,发现了图形用户界面这个概念创意,还注册了版权。施乐帕克研究中心的那台使用图形用户界面和鼠标的计算机衍生于先前的一个叫“联机系统”(oN-Line System,NLS)的创意。1968年,在一场被誉为“所有演示之母”(mother of all demos)的国际计算机学会大会上,道格·恩格尔巴特展示了联机系统。在第6章中,我们将展开讲讲这段错综复杂的历史。
再往上一层,是另一个软件层:运行于操作系统上的程序层。网络浏览器(如Safari、Firefox、Chrome或IE)是一个让你能够浏览网页的程序。微软的Word是一个文字处理程序。诸如《我的世界》之类的桌面电子游戏也是程序。所有的程序都是围绕不同操作系统的特性而设计的,因此我们无法在Mac上运行Windows系统程序,除非安装了另一个软件程序——模拟器。这些程序都设计得非常易用,但其实内部都是非常精确的。
咱们来点复杂的吧。假设你是一名记者,每周在网上写一篇关于猫的专栏文章。你得使用一个程序来给文章排版。大多数记者会使用文字处理程序来完成这项工作,比如微软的Word或谷歌的Docs。这两个软件都可以在电脑本地运行,也可以在云端运行。所谓本地运行,是指程序在你电脑的硬件上运行;而在云端运行,则是指程序在别人的电脑上运行。“云端”听起来是一个很美妙的比喻,不过实际上它指的只是另外一台电脑,这台电脑很可能跟其他几千台电脑一起摆在三州地区一个巨大的机房仓库里。你所创作的内容来自你的想象,是独一无二的——你倾情打造的那个构思巧妙、文字精练的关于猫骑着扫地机器人的故事,对人类来说就是独一无二的。但对计算机来说,每个故事都没有区别,都是存储在硬盘上的0和1的集合。
你写完文章之后,要将其放到内容管理系统(content management system,CMS)中,这样编辑才能看到你的文章并进行处理,最终读者才能读到文章。内容管理系统是现代传媒机构需要用到的一种基本软件。传媒机构一天要处理几百篇文章,而且天天如此。这些文章的交稿时间不同;这些文章在某个时间点处于不同的编辑状态(或者说不同的混乱状态);这些文章都分别有不同的印刷版标题和网络版标题;每篇文章都有一个摘录用于在各社交媒体平台上发表;每篇文章都有关联的图片、视频、数据可视化资料或代码;每篇文章都由人创作,这些人需要奖赏、酬劳,还需要管理。这些事情每天24小时都在发生,一年365天从不间断。这个规模实在太庞大了,怎么强调都不为过。管理这么复杂的业务,如果不用软件,那可真是太愚蠢了。内容管理系统就是这样一种工具,能够管理传媒机构日常印刷出版或在网络发布的所有文章和图片等资料。
传媒机构还可以使用内容管理系统给每篇文章应用统一的设计模板,让他们的文章看起来风格统一。这样做有助于品牌的建设,而且很实用。如果所有文章都要为呈现风格而分别做设计,那么要想出版任何东西,设计工作就没完没了了。因此,最好还是使用内容管理系统,给记者或编辑在系统中输入的原始文本应用一个标准化的设计模板。
接下来你要考虑,你要用设计模板中的哪些东西去装饰你的文章。你要使用突出引文的样式吗?你打算加上超链接吗?你是否会嵌入文中所引用的人物在社交平台上发布的帖子?这些细微的设计细节都会影响读者的阅读体验。
最后,文章需要被公之于众。这时,就需要一个网络服务器了。网络服务器也是一个软件,用于将文章从内容管理系统中取出,送到任何想到阅读它的人手上,而读者则通过网络浏览器(如Chrome或Safari)读取你的文章。网络浏览器在这里就是一个“客户端”。网络服务器将你的文章(内容管理系统会将你的文章转换成HTML页面)提供给用户手上的客户端。这种“服务器——客户端”的模式以及这种没完没了地发送和接收信息的过程,就是网络的运行原理。“客户端”和“服务器”这两个术语源于餐饮业的“顾客”和“服务员”。要理解这个模式,不妨想象餐厅的服务员向前来就餐的顾客端上食物的画面。
我们在网上存取任何数据都要经历上述这样一个过程(大致如此)。这个过程步骤繁多,因此经常会出岔子。真的,如今上网出现故障的情况并不算多,能做到这样已经很不容易了。
你每次使用电脑,其实都用上了这一系列复杂的层结构。虽然这看起来很神奇,但它不是什么魔法。了解这些技术背后的知识是非常重要的,因为这能让你在使用电脑时预料到哪些问题会出现,它们如何出现、为何出现,以及在哪里出现。哪怕你感觉到电脑在跟你说话,或是你在与电脑互动,实际上你就是在跟一个由人类编写的程序进行互动而已。这个程序背后的人跟你一样,会思考,有感觉,有偏见,也有独特的个人背景。
这些知识非常好用。跟1966年的文字交互机器人Eliza(伊丽莎)交谈特别有意思。Eliza会以一名罗杰斯心理治疗师的身份对你做出应答。推特上有一些机器人账号,它们至今还在使用Eliza软件开创的模式回应用户的提问。只要稍稍进行一个简单的网络调查,就能发现大量Eliza的代码实例。[2]Eliza那些预设的应答内容会基于用户输入的内容而改变。它的预设应答包括:
你不相信我能____吗?
可能你是想要做到____吧?
你希望我能够____。
也许你不想要做____。
多说说你的感受吧。
你最喜欢什么答案?
你怎么看?
你究竟想知道什么呢?
为什么你不能____?
难道你不知道?
试着自己搭建一个Eliza聊天机器人,这种形式的局限性立马一览无遗。要预设好能应付任何对话的应答内容,你办得到吗?这是不可能的。你也许可以想到能应付大部分对话的应答内容,但绝不可能应付得了所有对话。计算机在应答人类上肯定会有局限,这是因为计算机程序员作为人类,也必然有想象力上的局限。哪怕把这活儿众包出去,那也不够。毕竟要考虑到所有曾经发生的以及未来可能会发生的对话场景,不管众包给多少人,都是远远不够的。斗转星移,世界时时都在变,人们的对话风格也日新月异。就连罗杰斯心理疗法都不再是最时兴、最好的心理治疗互动方式,如今认知行为疗法远比罗杰斯心理疗法更加流行。
人们会试着去预先设计聊天机器人的应答内容,但这总归是无望的,部分原因是我们都无法逃脱生活中的意外事件。这让我想起一件旧事。当时,我听说一个朋友在纽约的一个地铁站跳到列车前自杀了。我全然没有心理准备,突然间不知该怎么办。有那么一会儿,一切似乎都停止了。
最终,我从震惊中回过神来,开始感到悲痛。但在此事发生之前,我没有任何办法可以预知我需要去面对一个这么可怕的悲剧。就这一点而言,我们其实都一样。在对意外糟心事的预料上,程序员并不比别人强多少。在需要人类设想某事最坏情况的时候,人类社群都会出现集体盲点,最终选择性地忽略一些事情。社会学家卡伦·A.赛鲁罗(Karen A.Cerulo)在她的书《不曾预见:人类设想最坏情况的文化挑战》(Never Saw It Coming: Cultural Challenges to Envisioning the Worst)中将这种认知偏差称为“正非对称”(positive asymmetry)。她写道,所谓“正非对称”是一种认知倾向,它“偏向于强调最好或最积极的结果”。许多社会文化都偏好于奖赏那些关注光明面的人,而忽视甚至惩罚那些提及阴暗面的人。如果一名程序员提出产品的潜在新用户定位,另一名程序员指出新产品可能被用于骚扰或诈骗,前者的说法肯定会得到更多关注。[3]
Eliza的预设应答内容反映了设计者取巧的态度。通过观察Eliza的应答,我们就能轻松理解诸如苹果公司Siri之类的语音助手的原理。最初版本的Eliza只有几十条预设应答,Siri则拥有由大量人员精心设计的应答内容。Siri有许多功能,它可以发短信、打电话、更新待办事项,还可以设置闹钟。“调戏”Siri还挺好玩的,小孩子就特别热衷于探索Siri应答能力的边界。然而,Siri和其他语音助手一样,应答能力受程序员集体想象力(以及“正非对称”)所限。斯坦福大学医学院的一个团队对多个语音助手进行了测试,以了解语音助手是否能够辨别病人的健康问题,以得体的用语做应答,并且为病人指派相应的医生。他们在2016年的《美国医学会杂志·内科学卷》上撰文表示,那些程序表现得“前言不搭后语,且不完整”,“如果要将语音助手应用到医疗界,它们的性能必须不断提升,才能完整而高效地进行应答”。[4]
技术沙文主义者都愿意相信,计算机在绝大多数工作上都能做得比人类好。计算机的运行基于数学逻辑,因此他们相信这种逻辑也适用于线下的现实世界。有一点他们是对的:说到计算能力,计算机绝对比人类要强得多。任何一个批改过学生数学试卷的人都很乐意承认这一点。不过,计算机的能力在一些特殊的情况下会受到限制。
比如玉米饼无人机(tacocopter)。这个古怪的创意在网上风靡一时,听起来也确实讨喜:用四旋翼飞行器直接把一袋又热又好吃的玉米饼送到你的家门口!不过,如果你细想一下硬件和软件上的问题,这个创意的缺点就变得显而易见了。无人机本质上就是一架内置电脑和摄像头的遥控直升机。如果下雨了,它会怎么样?电器遇到雨雪或者雾天是无法正常作业的。我的有线电视一遇到暴雨天气就会失灵,更别说脆弱得多的无线无人机了。玉米饼无人机应该飞到窗边送货,还是飞到门口送货?它要如何按开电梯门,如何推开楼梯门,如何按对讲机门铃?这些操作对人类来讲都是非常简单的,但对计算机来讲却难于上青天。玉米饼无人机该如何配送其他营养价值较低的合法物品?要是收货的客人被它吓坏了,开枪把它打下来,该怎么办呢?只有技术沙文主义者才会觉得玉米饼无人机要优于今天我们拥有的人类外卖配送系统。
如果你问Siri玉米饼无人机是不是一个好点子,她会在网上查找“玉米饼无人机”这个词。你会看到一些关于玉米饼无人机的新闻报道,其中一篇来自《连线》(Wired)杂志(后面会有章节展开讲述该杂志的出版事务和其中一位创始人斯图尔特·布兰德的故事)的报道,它对玉米饼无人机概念的解读比我还要深入。杂志的一位创始人认为,这个创意在逻辑上是不可能实现的,至少美国联邦航空局对于无人操控飞行器的管理条例就是这么规定的。不过,她同时也认为,虽然这个想法不切实际,但是保持这种创想精神是非常重要的。“就像赛博朋克对互联网的影响那样,”她说,“琢磨一些看起来不可能的事情,让人们保持思考的能力。”[5]
这里似乎缺少了对玉米饼无人机这个创意更为完整的构想。究竟有玉米饼无人机的世界是什么样子的?这是不是意味着我们要设计出能与无人机兼容的建筑物和都市环境?如果我们的窗户变成了外卖无人机的对接站,那我们要用什么东西去让家里的空气流通,让阳光照射进屋子?在没有玉米饼无人机的今天,外卖食物从一个人的手里传递到另一个人手里——假如要抹除这种最为乏味而无足轻重的人际互动,要消耗的社会成本是什么?我们真的要将“Hello,world”这句话说给那样一个现实世界听吗?
[1] 1英里≈1.61千米。——编者注
[2] Weizenbaum, “Eliza.”
[3] Cerulo, Never Saw It Coming.
[4] Miner et al., “Smartphone-Based Conversational Agents and Responses to Ques tions about Mental Health, Interpersonal Violence, and Physical Health.”
[5] Bonnington, “Tacocopter.”