前言
不搞信息学奥赛,为什么还要学编程?
在我策划和写作本书的时候,有许多家长问:“孩子到底要不要学编程?”虽然人工智能已经渐渐普及,但依然有大量的家长并不知道要不要让孩子学编程,也不知道该怎么学。部分家长的心态很现实:“学编程能带给孩子什么,特别是,能不能对升学有帮助?”
在编程逐渐普及的过程中,出现了两种不同的声音。一种是编程对数学基础要求很高,数学基础不好,编程也肯定学不好;另一种是无论谁都可以从编程学习中获益,编程并不需要太好的数学基础。
那么,到底哪一种是对的呢?下面8个问题的回答将为大家释疑。
问题1:编程=信息学奥赛?
产生上面不同声音的一大原因是许多人在信息学奥赛(全称为全国青少年信息学奥林匹克竞赛)和编程之间画上了等号,但显然这是不正确的。信息学奥赛只是编程的一个小子集。这就跟我们所有人都要学数学,但只有极少数人会去参加数学奥赛是一个道理。
在编程门槛日益降低的当下,一般的编程只需要一定的逻辑思维能力即可。大部分的核心算法和框架都是现成的,普通的编程人员只要按需将它们组装起来就能实现某个特定的功能。所以,千万不要把程序员的职业想得有多“高大上”,大部分程序员只是代码的搬运工和组装者。但参加信息学奥赛则不同,参赛者需要非常强的数学能力、问题分析能力和问题解决能力。即便是一名拥有多年工作经验的老程序员,在面对信息学奥赛的问题时,解答不出来也是很正常的。
问题2:编程是什么?
信息学奥赛是不是编程?是!
孩子组装个机器人、搭个积木是不是编程?也是!
这好比是问:100以内的加减法是不是数学?费马大定理是不是数学?它们当然都是数学!
所以,编程到底是什么呢?
编程的目的是让计算机帮助人类解决问题。为了使计算机能够理解人的意图,人类就必须将需要解决的问题的思路、方法和手段通过计算机能够理解的形式告诉计算机,使得计算机能够根据人给出的指令一步一步地去完成某项特定任务。这种人和计算机之间交流的过程就是编程。
编程的难易主要取决于两个方面:一是程序设计语言的友好性,二是所要解决问题的难度。其中,起决定性作用的是后者。从最早的机器语言到汇编语言,再到高级语言,再到现在的图形化编程语言,程序设计的语法已经变得越来越友好了。但无论用哪种编程语言,能写出可以解决“八皇后问题”的程序的程序员还真不多(“八皇后问题”在本套书的基础篇第6章介绍)。
这就好比英国人觉得法语要比中文容易学。但不管怎样,只要肯学,学会一门语言并能与人交流并不是太难的事,但要用这门语言创作一首诗歌或一篇小说,则要难得多。
问题3:为什么信息学奥赛如此受关注?
信息学奥赛是与数学奥赛、物理奥赛、化学奥赛和生物奥赛并列的五大学科奥赛之一。
目前国内面向青少年的信息学奥赛,从难度与规模来说,分为下面4个阶段。
●省级考试:CSP-J/S
CSP是非专业级计算机软件能力认证标准,分为CSP-J(入门级,Junior)和CSP-S(提高级,Senior),均涉及算法和编程。每年的9月初赛,形式为笔试;10月复赛,形式为机考。
●省选级考试:NOIP
全国青少年信息学奥林匹克联赛(NOIP)自1995年至今(除2019年外),每年由中国计算机学会(CCF)统一组织。NOIP在同一时间、不同地点以各省市为单位由特派员组织考试,全国统一大纲、统一试卷。高中或其他中等专业学校的学生可报名参加联赛。联赛分初赛和复赛两个阶段。初赛考查通用和实用的计算机科学知识,以笔试为主。复赛考查程序设计能力,须在计算机上调试完成程序设计。联赛分普及组和提高组两个组别,难度不同。
2019年8月,CCF发布公告称NOIP从2019年起暂停。在暂停NOIP比赛后,CCF在同年8月23日宣布举办CSP-J/S非专业级软件能力认证活动。2020年9月,CCF发布通知恢复举办NOIP,并指出:凡是在由CCF认定的国内国际程序设计竞赛中或能力认证(CSP-S)活动中取得优秀成绩的学生可以获得NOIP的参赛资格;学生也可以通过CCF认可的指导教师的推荐获得NOIP的参赛资格,但推荐人数有限,大部分的学生如果想要参加NOIP,还是要先通过CSP-S。
通知中还指出:参加NOIP是参加NOI(全国青少年信息学奥林匹克竞赛)的必要条件,不参加NOIP将不具有参加NOI的资格。因此,可以认为CSP-S是NOIP的选拔赛,NOIP是考生参加NOI的必要条件。
●全国级比赛:NOI
NOI即全国青少年信息学奥林匹克竞赛,是面向初、高中或其他中等专业学校学生的全国性质的编程最高级别比赛。每年在NOI中取得优异成绩的学生可以进入国家集训队(50名)。
●国际级中学生比赛:IOI
IOI(国际信息学奥林匹克竞赛)是面向全世界中学生的一年一度的信息学学科竞赛,每个国家最多可选派4名选手参加。
问题4:编程和数学到底是什么关系?
这取决于学编程的目的。
如果就是想参加信息学奥赛学编程,那编程与数学绝对是强相关。因为信息学奥赛本身承载了选拔的重任,而数学能力是最基础的。具体地说,信息学奥赛主要涉及离散数学的内容,知识点涵盖计数、数论、集合论、图论、数理逻辑、离散概率、矩阵运算等。思维和方法方面,对递归和分治的要求比较高。当然,除了数学能力,信息学奥赛还对阅读理解、问题分解、编码与调试等一系列综合能力有一定的要求。
那如果不参加信息学奥赛呢?编程和数学就没有那么强相关,有些时候甚至可以说是弱相关。现在编程的门槛越来越低,有些编程工作其实只是简单地做了些功能的调用。程序员懂一些基本的编程语法,会阅读接口的说明书,就能实现一些很有用的功能了。要求稍高一点的,需要自己原创一些代码,这时对逻辑思维能力和抽象能力的要求也就更高。再难一点儿,涉及核心的算法,那数学能力就必不可少。我国的程序员数量不少,整个群体结构呈金字塔状,涉及核心算法的群体属于金字塔塔尖,实属少数,大部分程序员并不需要学习太复杂的数学知识。
问题5:什么时候开始学编程合适?
如今,市场上有些机构宣传孩子在幼儿园阶段就可以开始学编程,让一些不明就里的家长无所适从。我个人认为,除了极少天赋异禀的孩子,大部分孩子在5岁以前逻辑思维尚不健全,很难明白编程的内涵。而且,即便是学普通的编程,最基本的四则运算和逻辑运算也是必备的基础,从课内的数学教学进度来看,至少得要小学二年级以后才适合学习编程。
很多家长想借鉴孩子学英语的经验,希望孩子在编程方面也能像学英语一样早早起跑。我并不是说更小的孩子不能学编程,只是编程和英语真的不一样。孩子从小开始学习英语,学3年,它的效果很明显,晚学的孩子花几个月时间根本追不上。但换成编程就不一样,同等智力的孩子,从5岁开始先学3年编程,后学的孩子用短则两三个月、长则半年的时间就能追上。所以,思维没有到一定地步,过早开始学习编程反而会事倍功半。
问题6:孩子学习编程的语言怎么选择?
如果想让孩子早点儿接触编程并对编程产生兴趣,那可以先让孩子接触图形化编程。待孩子理解了程序的工作原理,后面想让孩子参加信息学奥赛的家长可以选择在四年级以后让孩子学习C++代码编程。数据表明,信息学奥赛顶级选手的成绩与起步时间没有明显的相关性,因此,家长大可不必担心孩子是不是学习编程起步晚了。
如果孩子数学天赋一般,或者家长并没想让孩子参加信息学奥赛,只是纯粹想让孩子体验编程的乐趣并建立计算思维,那么对于图形化编程的学习可以持续到五六年级。再往后,Python是一个不错的选择,因为使用Python可以很快做出一些很酷的程序。
问题7:图形化编程能训练计算思维吗?
有些家长认为训练计算思维一定需要学C++或Python这类编程语言才行,而图形化编程只是搭搭积木,没法训练计算思维。其实,这种认知是片面的。
图形化编程目前看起来没有起到很好的训练计算思维的效果,问题不在于图形化编程本身,而在于市场把图形化编程的学习下沉得太厉害,很多机构已经把图形化编程下沉到三年级以下。幼儿园甚至是小学一二年级的小朋友,大都不具备逻辑与数学基础,对这个阶段的孩子进行计算思维的培养实在有点“巧妇难为无米之炊”。如果孩子在更高的年级(比如小学的四至六年级)去学图形化编程,那图形化编程完全可以作为计算思维训练的载体。
从本质上来说,计算思维的训练与具体的编程语言无关。这就好比一个人的文学修养与他所使用的语言没有关系,作家用文言文可以写出优秀的文学作品,用现代白话文和英文也一样。
问题8:编程会影响学科类课程的学习吗?
有些家长会有这样的顾虑:孩子学编程需要花费大量的时间,等到进入初中后会不会影响学科类课程的学习?也正因为此,进入初中后,很多家长就不再支持孩子学编程了。
有这个顾虑是很正常的,但如果学习的目的是训练计算思维、培养编程素养,这样的担忧就是没有必要的。
我们不妨来看看编程能培养孩子的哪些能力。
编写程序是为了解决某个具体问题,但这个问题通常是以某种情景表现的,不像数学题那样抽象。因此,编程学习首先有助于提高孩子的问题理解、分析和抽象的能力。
一个稍微复杂一点儿的问题往往由若干个子问题构成,其中有些是我们熟悉的,可以利用现有的程序,有些是我们需要去编写的。编程学习非常有助于提高孩子们的问题分析能力。
在编写程序的过程中,逻辑思维能力极为重要。程序里用得最多的就是逻辑判断和循环。满足什么条件执行哪个分支程序,满足什么条件退出循环,这些问题的解决都需要较高的逻辑思维能力。当然,如果没有良好的数学素养,写出的程序可能并不理想。拥有良好数学思维的人往往可以写出非常简洁且高效的程序。
写程序常常是一个不断优化的过程。一开始写出的可执行程序,往往效率并不那么高,结构并不那么美。这时,我们可以不断去寻找更优化的方法,不断提升程序的效率和可读性。因此,编程能锻炼孩子不断优化、追求卓越的品质。
数学题解错了,如果我们不验算,就很难看出来,更何况有些数学题也不好验算。但程序不允许一丝一毫的马虎,错了要么无法运行,要么执行结果不符合我们的预期。编程不允许半点儿粗心,一旦发现了错误,就得像福尔摩斯一样去寻找问题所在。有可能一个不经意的小错误,我们得花上半天甚至更长时间才能找出症结。所以,编程非常有助于帮助孩子克服粗心的毛病,锻炼孩子的耐心,提高孩子的错误诊断能力。
对于一个大型的程序,我们常常需要几个人一起协作完成。这个时候,程序就不单单是写给自己看,还要让别人也能看得懂。因此,编程非常有助于锻炼孩子的团队协作能力和结构化与模块化思维。
没错,编程确实很花时间。如果连学科内容都学得吃力,那我不建议去学编程。如果学有余力并且对编程感兴趣,那在学习编程的过程中无论是直接或间接获得的能力,对孩子的学科类学习和长远发展都是有益的。
本书的特点
我发现目前的编程教育存在一个问题,就是重算法、轻结构。我在大学从事计算机专业的教学工作,在工作中发现这个问题在本科生或研究生写的程序里体现得非常明显。我曾经参与起草由全国高等学校计算机教育研究会、全国高等院校计算机基础教育研究会、中国软件行业协会、中国青少年宫协会4个团体联合发布的《青少年编程能力等级》中的图形化编程部分。在那篇标准文件中,我把数学思维和结构化思维的培养放在了与算法同等重要的位置。这一思想也贯穿了本书的撰写过程。本书并不是简单地让孩子搭积木玩,也并非止步于了解一下编程的规则,而是更侧重于计算思维和编程素养的培养,因此更适合于小学中高年级的孩子,也适合从事少儿编程教育的从业者。
什么是计算思维?
我们生活在一个数字世界,软件和技术已经彻底改变了我们的生活。为了能游刃有余地生活和工作,我们需要了解自己所生活的这个数字世界。这就是计算思维被称为“21世纪必备技能”的原因,它对每个人而言都很重要。学习计算思维对于了解数字世界的运作方式、利用计算机的力量解决棘手的问题都至关重要。它还能帮助我们进行批判性的思考,不仅可了解某些技术的好处,也懂得它们的潜在危害、道德影响或意外后果。
虽然我们在这里及前文中多次提及了计算思维,但究竟什么是计算思维呢?让我们来看看卡内基梅隆大学周以真教授的学术定义:
“计算思维是涉及确切表达问题及其解决方案的思维过程,使解决方案以一种信息处理代理可以有效执行的形式来表示。”
听起来够绕吧?但其实,这只是用高大上的语言来表达简单的想法。“信息处理代理”是指任何遵循一组指令来完成任务(我们称之为“计算”)的东西。大多数情况下,这个“代理”是指计算机或其他类型的数字设备—但它也可以是人!为了使事情变得简单,我们将其称为计算机。为了以计算机可以执行的方式表示解决方案,我们必须将它们表示为一步一步的过程,即算法。为了创建这些算法解决方案,我们应用了一些特殊的问题解决技能。这些技能构成了计算思维,它们可以迁移到任何领域。
计算思维同时借鉴了数学思维和工程思维。然而,与数学不同的是,我们的计算系统受到底层“信息处理代理”及其操作环境的物理限制。因此,我们必须担心边界条件、故障、恶意代理和现实世界的不可预测性。但与其他工程学科不同,由于我们独特的“秘密武器”软件的存在,在计算中我们可以构建不受物理现实约束的虚拟世界。因此,在网络与数字世界中,我们的创造力仅受想象力的限制。
计算思维可以被描述为“像计算机科学家一样思考”,但它现在是每个人都需要学习的重要技能,无论人们是否想成为计算机科学家!有趣的是,计算思维和计算机科学并不完全与计算机有关,它们更多地与人有关。计算思维的训练甚至可以完全脱离计算机而存在!你可能认为我们为计算机编写程序,但实际上我们是为人编写程序—编写程序的最终目的是帮助人们交流、查找信息和解决问题。
例如,我们使用智能手机上的应用程序来获取前往朋友家的路线。这个应用程序就是计算机程序的一个例子,而智能手机是为我们运行该程序的“信息处理代理”。那些设计计算最佳路线的算法,以及设计交互界面和如何存储地图等所有细节的人,都应用了计算思维来设计这个应用。但他们设计这个应用并不是为了智能手机,而是为了帮助使用智能手机的人。
一门教授计算思维的课,应该教会学生以下5个方面的内容。
●描述一个问题。
●确定解决此问题所需的重要细节。
●把问题分解成小的、合乎逻辑的步骤。
●使用这些步骤来创建解决问题的流程(算法)。
●评估这个过程。
事实上,业界对计算思维有多种定义,但大多数定义都涉及计算思维背后体现的解决问题所必备的技能。
计算思维
下面,我列出6种重要的技能。
1.抽象
计算思维中最重要和最高级的思维过程是抽象。抽象的作用是简化事物,它赋予我们处理复杂问题的能力。抽象需要确定问题最重要的方面是什么,并隐藏我们不需要关注的其他具体细节。我们根据问题最重要的方面来创建原始事物的模型。然后,我们可以使用这个模型来解决问题,而不必一次处理所有的细节。
抽象用于定义模式、将个体实例泛化和参数化。抽象的本质是在个性中找共性,它识别出一组对象共有的属性,同时隐藏它们之间不相关的区别。例如,算法是一个过程的抽象,它接受输入、执行等一系列步骤并产生预期的目标输出。一个排序算法既可以对一组数排序,也可以对一组学生姓名排序。抽象数据类型定义了一组抽象的值和用于操作这些数据的操作,对使用这些数据类型的用户隐藏了数据的实际表示,这就好比驾驶汽车的人只需关心方向盘、油门、刹车等的使用即可,不需要知道内部引擎是怎么工作的。
计算机科学家常常在多个抽象层次上工作。反复应用抽象使我们能够构建越来越庞大的系统。最底层(至少对于计算机科学而言)是位(0和1)。在计算中,我们通常基于抽象层构建系统,这使我们能够一次只关注一层及相邻层之间的关系。当我们用高级语言编写程序时,我们不必担心底层硬件、操作系统、文件系统或网络的细节。
我们在日常生活中经常使用抽象。比如,地图通过省略不必要的细节(例如公园中每一棵树的位置),只保留地图阅读器所需要的最关键信息,例如道路和街道名称,向我们展示了整个世界的简化版本。
计算机一直都在使用抽象对用户隐藏尽可能多的不必要信息。例如,假设你在上次旅行中拍了一张漂亮的风景照片,现在你想在计算机上对它进行编辑并调整其中的颜色。通常我们可以通过打开图片编辑程序、调整一些颜色滑块或选择过滤器来做到这一点。当你这样做时,会有很多复杂的操作发生,而这些操作是计算机对你隐藏的。
你拍的照片在计算机上是作为一个像素阵列存储的,每个像素有不同的颜色,每种颜色都用一组数字表示,每一个数字都存储为二进制数!这将是非常多的信息。想象一下,如果你在调整颜色时必须查看每个像素的颜色值对应的二进制数并更改其中的一部分,那会不会崩溃?好在计算机为你隐藏了这些信息,因此你不需要知道这些二进制信息就能达成你的目标。
2.分解
分解是将一个复杂的问题分解为更小、更简单的部分,然后专注于解决每个小问题。这些更小、更简单的问题的解决方案组合成了我们最初的大问题的解决方案。分解有助于让大问题变得不那么令人生畏!
由于计算机需要非常具体的指令,因此分解是创建可在计算设备上实现的算法和过程的一项重要技能。我们需要告知计算机它应该遵循的每一个步骤,才能让计算机帮助我们做事。
例如,制作蛋糕的整个任务可以分解为几个较小的任务,每个任务都可以轻松执行。
制作蛋糕
1.烤蛋糕
●将原材料(黄油、糖、鸡蛋、面粉)放入碗中
●混合原材料
●将混合的原材料倒入铝合金模具
●放入烤箱烤30分钟
●从铝合金模具中取出蛋糕
2.打发奶油
3.将奶油涂在蛋糕上
3.算法思维
算法是计算思维和计算机科学的核心。在计算机科学中,问题的解决方案不仅仅是一个答案,而是算法。算法是解决问题或完成任务的一步步过程。如果我们正确地遵循算法的步骤,即使对于不同的输入,也会得到正确的答案。例如,我们可以使用算法来找到地图上两个地点之间的最短路线。相同的算法可应用于任何一对起点和终点,因此最终的答案取决于算法的输入。如果我们知道解决问题的算法,那么我们随时可以轻松解决这类问题而无须思考!我们只需按照步骤操作。计算机自己并不能思考,所以我们需要给它们算法,告诉它们怎么做事。
算法思维是创造算法的过程。当我们创建一个算法来解决一个问题时,我们把创建出的算法称为算法解决方案。算法的构成元素相对较少,因为计算设备只有几种类型的指令可以遵循。它们可以做的主要事情是接收输入、提供输出、存储值、按顺序执行指令、根据分支进行选择和在循环中重复执行指令。尽管指令的范围非常有限,却描述了计算设备可以计算的所有内容,这就是为什么我们要将算法描述为仅限于这些元素的过程。
4.泛化和模式
泛化也被称为“模式识别和泛化”。泛化是将问题的解决方案(或解决方案的一部分)进行普适化,以便它可以应用于其他类似的问题和任务。由于计算机科学中的解决方案是算法,这意味着我们将一种算法变得足够通用,它就可以解决一系列问题。这个过程涉及抽象。为了使事物更通用,我们必须剔除与特定问题或场景相关但对算法的运行而言并不重要的细节。
发现模式是这个过程的重要组成部分。当我们思考多个问题时,我们可能会认识到它们之间的相似之处,并发现它们可以用相似的方式予以解决。这被称为模式匹配,也是我们的日常生活每时每刻在做的事情。
泛化的算法可以被重用,用于解决一组相似的问题,这意味着我们可以快速有效地提出解决方案。
5.评估
评估涉及找出解决问题的多种算法,并判断哪种算法最好用,它们是否在某些情况下有效但在其他情况下无效,以及如何改进它们。在评估一个算法方案时,我们需要考虑一系列因素。例如,这些过程(算法)求解问题需要多长时间,它们是否可扩展,是否能够可靠地解决问题,或者是否在某些情况下会以非常不同的方式执行。评估是我们在日常生活中经常做的事情,常常,我们还需要用户的反馈来帮助我们改进方案。
我们可以通过不同的方式来评估算法。比如,可以通过在计算机上实现并运行算法来测试它们的速度;或者可以从理论上分析算法需要的执行步数。我们可以通过给算法许多不同的输入并检查它们是否按预期工作来测试它们是否正确。此时,需要考虑用于测试的不同输入。我们并不想检查每一个可能的输入(通常有无数个可能的输入),但仍然需要确认所给出的算法是否对所有输入都有效。测试是计算机科学家和程序员一直在做的事情。但是,因为我们通常无法测试所有可能的输入,所以我们也会尝试使用逻辑推理来评估算法。
6.逻辑
在尝试解决问题时,我们需要进行逻辑推理。逻辑推理是指通过观察、收集数据、思考,然后根据已知事实搞清楚整个事情的缘由,从而试图完整地理解事物。
例如,假设你正在编写软件来计算从你家到某个位置的最短路线。在地图上看,如果你从家向北走,到图书馆需要2分钟,但如果你向南走,则需要3分钟才能到达下一个十字路口。你可能想知道:如果一开始就向南走,去图书馆是否有更好的路线?显然,从逻辑上讲这不可能,因为你需要步行3分钟才能到达第一个十字路口。
在更深层次上,计算机的运行完全建立在逻辑之上。它们使用“真”和“假”,并使用被称为“布尔表达式”的东西(比如“年龄>5”)在计算机程序中做出决定。追踪程序中的错误的位置和原因也需要用到逻辑思维。
一个甜甜圈的例子
最后,以一个甜甜圈的例子来形象地说明什么是计算思维。
假设我们现在有一个任务,要从商店带甜甜圈给我们的同学。我们收集了每个人的订单,形成了一张110个甜甜圈的购买清单列表,我们希望在去商店之前计算出所有甜甜圈的总价格。计算思维可以帮助我们更容易地解决这个问题。
我们首先定义问题:计算110个甜甜圈的总价格。
看到这个问题时,我们的第一反应通常是拿起自己的手机,并将甜甜圈的价格一个个累加起来。这个方法可行,却是一种低效的方法。计算思维为我们提供了一种更好、更省力的方式。
我们可以将问题分解为更小的步骤(分解)。
(1)给出每种甜甜圈的价格。
(2)给出我们购买的每种甜甜圈的数量。
一旦知道了这两点,就可以计算出总价格,下面给出了一个实例。
不同类型甜甜圈的单价表:
类型A:每个3.00元
类型B:每个1.60元
类型C:每个2.00元
类型D:每个2.10元
类型E:每个2.15元
按类型划分的甜甜圈数量:
25个甜甜圈A,每个3.00元
30个甜甜圈B,每个1.60元
10个甜甜圈C,每个2.00元
15个甜甜圈D,每个2.10元
30个甜甜圈E,每个2.15元
现在,通过把甜甜圈按照类型和数量有序组织成价格列表,我们发现列表中的每一项都遵循相同的模式(发现模式),这使我们能够建立一个公式来计算每种甜甜圈的总价格。
甜甜圈A的总价格:25个×3.00元/个=75元
对于模式化的数据类型,可以对列表中的每一项简单地重复使用这个公式。
甜甜圈B的总价格:30个×1.60元/个=48元
甜甜圈C的总价格:10个×2.00元/个=20元
甜甜圈D的总价格:15个×2.10元/个=31.5元
甜甜圈E的总价格:30个×2.15元/个=64.5元
最后,我们可以将每种类型的甜甜圈价格相加来计算总价格。
75+48+20+31.5+64.5=239(元)
有了用于解决每个小问题的公式,我们可以抽象出一个模板,其中包含两个计算价格的公式。
按类型划分的项目数×单价=每个项目类型的价格
项目A的价格+项目B的价格+项目C的价格+…=总价格
这个公式不仅可以用于甜甜圈价格的计算,也同样适用于纸杯蛋糕、冰淇淋、三明治的价格计算,当然也适用于甜甜圈数量更多的情况。在消除了最初问题中的复杂性后,这个公式现在成了一个易于使用的工具(泛化)。
然后,我们可以进一步扩展从这一经验中获得的知识,通过构建算法来确保每次都能获得可靠的输出,以便在其他需要计算的活动中复用它(算法思维)。
第1步:按类型添加项目。
第2步:为每个项目类型设置单价。
第3步:将按类型划分的项目数与其单价相乘。
第4步:将每种类型的总价格加在一起。
我们来评估一下这个方法。首先,它总是可以正确地完成计算总价格的任务。其次,抽象出来的模板和算法有很强的复用性。最后,这种方法可扩展性较强,即按这种方式来计算总价格的速度要远远快于逐个相加的方法,特别是在数量变得越来越多的时候(评估)。
正如这个小例子所希望展示的那样,这个过程体现了我们解决问题方式的转变。通过公式化的过程,我们可以驾驭复杂性并专注于重要的事情,不会在复杂性中迷失解决问题的方向。尽管这只是计算思维的一个简单例子,但很明显,这个过程可以被复制并用于解决大量数据的问题,并在充满数据的世界中引导未知的旅程。