计算机科学是一个极其宽泛的学科。全球的分布式系统、人工智能、机器人、图形、安全、科学计算,计算机体系结构和许多新兴的二级领域,每年都会由于新技术和新发现而扩展。计算机科学的快速发展广泛影响了人类生活。商业、通信、科学、艺术、休闲和政治都被计算机领域彻底改造。
计算机科学的巨大生产力可能只是因为它构建在一系列优雅且强大的基础概念上。所有计算都以表达信息、指定处理它所需的逻辑、以及设计管理逻辑复杂性的抽象作为开始。对这些基础的掌握需要我们精确理解计算机如何解释程序以及执行计算过程。
这些基础概念在伯克利长期教授,使用由Harold Abelson、Gerald Jay Sussman和Julie Sussman创作的经典教科书《计算机科学的构造与解释》(SICP)。这个讲义大量借鉴了这本书,原作者慷慨地使它可用于改编和复用。
我们的智力之旅一旦出发就不能回头了,我们也永远都不应该对此有所期待。
我们将要学习计算过程的概念。计算过程是计算机中的抽象事物。在演化中,过程操纵着叫做数据的其它事物。过程的演化由叫做程序的一系列规则主导。人们创造程序来主导过程。实际上,我们使用我们的咒语来凭空创造出计算机的灵魂。
我们用于创造过程的程序就像巫师的魔法。它们由一些古怪且深奥的编程语言中的符号表达式所组成,这些语言指定了我们想让过程执行的任务。
在一台工作正确的计算机上,计算过程准确且严谨地执行程序。所以,就像巫师的学徒那样,程序员新手必须学会理解和预测他们的魔法产生的结果。
–Abelson & Sussman, SICP (1993)
为了定义计算过程,我们需要一种编程语言,最好是一种许多人和大量计算机都能懂的语言。这门课中,我们将会使用Python语言。
就像所有伟大的软件一样,Python具有许多版本。这门课会使用Python3最新的稳定版本(本书编写时是3.2)。许多计算机都已经安装了Python的旧版本,但是它们可能不满足这门课。你应该可以在这门课上使用任何能安装Python3的计算机。不要担心,Python是免费的。
在Python交互式会话中,你可以在提示符>>>
之后键入一些Python代码。Python解释器读取并计算你输入的东西,并执行你的各种命令。
有几种开始交互式会话的途径,并且具有不同的特性。把它们尝试一遍来找出你最喜欢的方式。它们全部都在背后使用了相同的解释器(CPython)。
最简单且最普遍的方式就是运行Python3应用。在终端提示符后(Mac/Unix/Linux)键入python3
,或者在Windows上打开Python3应用。(译者注:Windows上设置完Python的环境变量之后,就可以在cmd
或PowerShell中执行相同操作了。)
有一个更加用户友好的应用叫做Idle3(idle3
),可用于学习这门语言。Idie会高亮你的代码(叫做语法高亮),弹出使用提示,并且标记一些错误的来源。Idle总是由Python自带,所以你已经安装它了。
Emacs编辑器可以在它的某个缓冲区中运行交互式会话。虽然它学习起来有些挑战,Emacs是个强大且多功能的编辑器,适用于任何语言。请阅读61A的Emacs教程来开始。许多程序员投入大量时间来学习Emacs,之后他们就不再切换编辑器了。
在所有情况中,如果你看见了Python提示符>>>
,你就成功开启了交互式会话。这些讲义使用提示符来展示示例,同时带有一些输入。
控制:每个会话都保留了你的历史输入。为了访问这些历史,需要按下<Control>-P
(上一个)和<Control>-N
(下一个)。<Control>-D
会退出会话,这会清除所有历史。
为了介绍Python,我们会从一个使用多个语言特性的例子开始。下一节中,我们会从零开始,一步一步构建整个语言。你可以将这章视为即将到来的特性的预览。
Python拥有常见编程功能的内建支持,例如文本操作、显示图形以及互联网通信。导入语句
为访问互联网上的数据加载功能。特别是,它提供了叫做urlopen
的函数,可以访问到统一资源定位器(URL)处的内容,它是互联网上的某个位置。
语句和表达式:Python代码包含语句和表达式。广泛地说,计算机程序包含的语句
计算某个值
或执行某个操作
语句通常用于描述操作。当Python解释器执行语句时,它执行相应操作。另一方面,表达式通常描述产生值的运算。当Python计算表达式时,就会计算出它的值。这一章介绍了几种表达式和语句。
赋值语句
将名称shakespeare
和后面的表达式的值关联起来。这个表达式在URL上调用urlopen
函数,URL包含了莎士比亚的37个剧本的完整文本,在单个文本文件中。
函数:函数封装了操作数据的逻辑。Web地址是一块数据,莎士比亚的剧本文本是另一块数据。前者产生后者的过程可能有些复杂,但是我们可以只通过一个表达式来调用它们,因为复杂性都塞进函数里了。函数是这一章的主要话题。
另一个赋值语句
将名称words
关联到出现在莎士比亚剧本中的所有去重词汇的集合,总计33,721个。这个命令链调用了read
、decode
和split
,每个都操作衔接的计算实体:从URL读取的数据、解码为文本的数据、以及分割为单词的文本。所有这些单词都放在set
中。
对象:集合是一种对象,它支持取交和测试成员的操作。对象整合了数据和操作数据的逻辑,并以一种隐藏其复杂性的方式。对象是第二章的主要话题。
表达式
是一个复合表达式,计算出正序或倒序出现的“莎士比亚词汇”集合。神秘的记号w[::-1]
遍历单词中的每个字符,然而-1
表明倒序遍历(::
表示第一个和最后一个单词都使用默认值)。当你在交互式会话中输入表达式时,Python会在随后打印出它的值,就像上面那样。
解释器:计算复合表达式需要可预测的过程来精确执行解释器的代码。执行这个过程,并计算复合表达式和语句的程序就叫解释器。解释器的设计与实现是第三章的主要话题。
与其它计算机程序相比,编程语言的解释器通常比较独特。Python在意图上并没有按照莎士比亚或者回文来设计,但是它极大的灵活性让我们用极少的代码处理大量文本。
最后,我们会发现,所有这些核心概念都是紧密相关的:函数是对象,对象是函数,解释器是二者的实例。然而,对这些概念,以及它们在代码组织中的作用的清晰理解,是掌握编程艺术的关键。
Python正在等待你的命令。你应当探索这门语言,即使你可能不知道完整的词汇和结构。但是,要为错误做好准备。虽然计算机极其迅速和灵活,它们也十分古板。在斯坦福的导论课中,计算机的本性描述为
计算机的基本等式是:计算机 = 强大 + 笨拙
计算机非常强大,能够迅速搜索大量数据。计算机每秒可以执行数十亿次操作,其中每个操作都非常简单。
计算机也非常笨拙和脆弱。它们所做的操作十分古板、简单和机械化。计算机缺少任何类似真实洞察力的事情…它并不像电影中的HAL 9000。如果不出意外,你不应被计算机吓到,就像它拥有某种大脑一样。它在背后非常机械化。
程序是一个人使用他的真实洞察力来构建出的一些实用的东西,它由这些简单的小操作所组成。
在你实验Python解释器的时候,你会马上意识到计算机的古板:即使最小的拼写和格式修改都会导致非预期的输出和错误。
学习解释错误和诊断非预期错误的原因叫做调试(debugging)。它的一些指导原则是:
逐步测试:每个写好的程序都由小型的组件模块组成,这些组件可以独立测试。尽快测试你写好的任何东西来及早捕获错误,并且从你的组件中获得自信。
隔离错误:复杂程序的输出、表达式、或语句中的错误,通常可以归于特定的组件模块。当尝试诊断问题时,在你能够尝试修正错误之前,一定要将它跟踪到最小的代码片段。
检查假设:解释器将你的指令执行为文字 — 不多也不少。当一些代码不匹配程序员所相信的(或所假设的)行为,它们的输出就会是非预期的。了解你的假设,之后专注于验证你的假设是否整理来调试。
询问他人:你并不是一个人!如果你不理解某个错误信息,可以询问朋友、导师或者搜索引擎。如果你隔离了一个错误,但是不知道如何改正,可以让其它人来看一看。在小组问题解决中,会分享一大堆有价值的编程知识。
逐步测试、模块化设计、明确假设和团队作业是贯穿这门课的主题。但愿它们也能够一直伴随你的计算机科学生涯。