2019年4月4日晚,我应邀在全人之美教师联盟做了一次关于编程的主题分享,本文根据录音内容整理而成,略有删节改动。
一、什么是编程?


编程,就是编写程序。那么,程序又是什么呢?大家可能都以为,只有在电影中计算机专家和黑客们输入的那些花花绿绿的命令和代码是程序吧?就像这样子的:

相信大家都看不懂,因为这都是用专业的编程语言写出来的程序。但「程序」这个词并不是只在计算机领域使用,在我们的日常生活中也京城会使用这个词,比如:走程序、作业程序、通过法律程序解决……等等。

程序,就是做一件事情的流程和顺序。 我们做任何一件事,都有一个流程,包含一些步骤,而这些步骤之间往往有一个确定的顺序。比如我们要出门,得先穿衣服、穿鞋、穿袜子,但你不可能先穿鞋子再穿袜子,一定是先穿袜子再穿鞋。这样的流程和顺序合在一起,就是程序。
拿我们最熟悉的上课来说,上课之前要备好课,准备好PPT,在上课铃响前来到教室,指导学生做好课前准备或预习,开始上课后要先进行导入,然后讲解新知识,组织课堂讨论和对应的练习活动,下课前要对本节课的内容进行回顾,布置课后作业,然后下课铃响了,下课。如果把刚才这所有的步骤都写下来的话,那就是「上课」的程序。

当你给孩子买了一套乐高玩具时,包装里一定会有一张说明书,描述了把一大堆零件组装起来的详细步骤。这个说明书记录的就是安装玩具的程序,如果你家孩子把这套玩具装了又拆、拆了又装,最后不用说明书也能成功地组装起来的话,这套程序其实就已经安装到孩子的脑袋里了。
程序这个概念对我们最大的启示就是:做任何事情都有一个程序,那么去找现成的程序并在其基础上改良,肯定比从零开始写这个程序要简单一些。当你要做这件事时,首先应该想到的是:你往往不是第一个要做这件事的人,肯定有人已经做过了,那么其中有一部分人就会把这个程序用某种方式写下来,记录在某处。我们要做的就是去把它找出来参考。

正如我们在做一道新菜时,会先到网上去找合适的菜谱,然后按照菜谱准备材料,再一步一步加工。同样,我们要去一个新地方旅游时,也会先在网上查找各种攻略,看看都需要准备哪些东西,有哪些好吃的,好玩的,然后再安排我们的行程。
大多数时候,我们是先找到合适的程序,然后再按照它来进行执行的。不过也有这样的情况:我们找不到合适的程序,但这件事还得做,那怎么办?就只能自己写程序了。比如我在运城国际学校开编程课时,找不到任何先人的成熟经验,只能摸索着一步一步来,然后把自己的经验总结(课程编排、教学流程、应急处理等)沉淀下来,归纳出一条条的原则和流程。
所谓编程,就是把原本存在你脑中的那个流程写出来,把原本抽象的思维具像化的过程。我们在开始上课前要进行备课,这是编程;我们把某项工作的具体流程写下来交代给别人,或者给自己备忘,这是编程;音乐创作人把音乐写成歌词和乐谱,这也是编程;去旅游前做好攻略和计划,逛完之后自己也写篇游记和攻略,这还是编程。
所以,并不是只有电脑上那些神秘的代码算程序,也不是只有专业的程序员才能编程。在生活中,我们每个人都在编程,也都在被编程。

当你按照别人设计好的流程在一步一步执行时,你就是在被编程,比如参加一个旅游团,只能严格按照人家规定好的行程来,每一步都不能更改。只有当程序是你自己设计的时,你才是在编程,比如自己计划自由行,详细安排出行计划中的每一步;又或者把一项任务的详细流程梳理清楚,交代给其他人去做。
当然了,我们都想做一个编程的人,而不是被编程的人,对吧?
二、为什么要编程?

要想把一件事情做好,首先我们要知道完整的程序,其次我们要记住当前执行到了哪一步,下一步该干什么。然而人的记忆力其实是很差的,研究表明我们的工作记忆只有四个组块,所以我们不太可能把一个复杂的程序一次性完整地记住。即便是经过多次操练,已经滚瓜烂熟的程序,我们也不能保证永远不出现遗忘的情况。何况在执行过程中一旦收到任何干扰(来电话、发生突发事件),都有可能导致出问题,要么忘记了当前做到了哪一步,要么是多做了一步,要么是少做了一步,或者是顺序做错了。
相信有很多老师都有自己的微信公众号吧?我个人就运营着两个微信号「镓话」、「编程镓教」,经常需要发布文章。之前经常会发生这样的情况:文章发布后,发现有错别字、排版有问题、该加的链接没加上、忘了申请原创、忘了开放留言……要知道之前微信公众平台是没有修改功能的,有问题只能通过评论补救,或者删除掉重新发布。为了解决这些问题,我写了下面这个程序:

自从每次按照这个程序来发布文章后,我的文章就很少出现前面那些问题了。把所有要做的步骤都列出来,然后做完一个就划掉一个。这样不管中途受到怎样的干扰,都很难让我们出现记忆错误。
有人说:这不就是清单么?有本很流行的书叫《清单革命》,说的就是这么一回事。没错,工作清单就是一种最简单的程序。那么,为什么仅仅是把程序写下来,就有这么明显的效果呢?

通过把程序写下来,可以解放我们的大脑和注意力,让我们可以把精力放在更重要的事情上。每个步骤的细节、执行的进度,这原本是要靠我们大脑去记忆的东西,现在通过程序来保存了,相当于给我们的大脑装了一个扩展存储器,我们的精力就可以从中解放出来,专注于执行好每一个步骤。
把程序写下来后还有个好处,就是你可以把这项原本需要自己完成的工作交给别人,甚至是机器来做。很多人认为自己在一个岗位上是不可或缺的存在,这样就能说明自己很厉害。但我可不这么认为,如果这个岗位离了你就不转了,那么你不得累死?没人能接手你的工作,那你还有机会跳槽或升职么?强行离开,你会不会有愧疚感?
真正的高手,会为自己的每份工作写好程序,随时可以交接给别人,可以让自己随时离开,而组织依然能正常运转。这就是专家和教练的区别,也是领导力的体现。为什么很多专家自己很厉害,却无法把别人教得跟他一样好?这往往是因为他并不能把做事的程序想清楚并写清楚,也不能把如何抵达自己目前水平的程序想清楚和写清楚。毕竟和执行程序比起来,编写程序需要完全不同层次的能力。这就好比你能读懂一篇文章,但不代表你就能写出这样的文章。

通过把原本抽象的程序具象化,让我们可以对其进行全局审视和局部聚焦,进行不断地修改和完善,并让它能突破时间和空间的限制进行传播。如果一个想法只是装在我们的脑子里,我们往往会认为自己已经对它足够地熟悉,而很少会对它进行不同角度的审视和思考,也就很难发现其中的问题和缺陷。可是一旦把它写出来,我们就能梳理清楚它的结构脉络,仔细斟酌并完善其中每一个细节。在这个过程中,还可以让更多的人加入进来,利用集体的智慧来避免个人认知和视角的局限。
往往一段看上去无懈可击的逻辑,写下来之后再看看,就会马上发现诸多问题,到最后这篇文章跟最初的想法往往大不一样,甚至有可能最后都不好意思发了,只能丢在草稿里。如果你也是经常写文章的人,应该很容易理解我所说的这一点。我自己就有很多文章就是这样烂尾的,只能作为素材,等待合适的时机拿出来用。
如果一个程序只有一个人知道,那就只有他一个人能操作,那么它就和这个人产生了强耦合,也不具备传播的可能性。一旦这个人离开或者死去,这个程序就无法继续发挥原有的作用,因此它所提供的价值是不可靠的。
武侠小说里的各种绝世武功如果不能写成秘笈,那么早晚一定会失传。因为再厉害的高手也是人,终归是要死的,万一临死前还没找到合适的徒弟怎么办?如果徒弟不能在师傅死前把功夫练到家怎么办?如果徒弟好不容易学会了,结果却被人打死了,师傅又该怎么办?难道再重新收一个吗?但如果写成一本秘笈,可以流传数百年,跨越时间的限制,也可以从西域传到中土,再传到东瀛,跨越空间的限制。
正如我在《未来我们该学什么语言?》一文中说过的那样:古代先知们的各种思想得以流传到今天,全依赖于文字的发明。靠口口相传只能留下神话故事,却留不下真知灼见。没有柏拉图的文字,苏格拉底其人其事注定不会被我们所知。只有将抽象的思想具像化,才能解除其对特定的人和环境的依赖,从而流传开来。
写作从本质上来说也是一种编程,而文章就是作者用来描述自己思想的程序。思想一旦被写成文字,就摆脱了其创作者的束缚,可以自由地传播和进化。每一位传播者都会对它们做有意或无意的加工,就好像是基因的随机变异一样,其中更有价值的变化最终会被保留下来传世,没有价值的变化则会被淘汰掉。文章也好,程序也好,其实都可以理解为一种生命。一点也不过分地说,写作和编程都是在创造生命。虽然它们都是我创造的,但我死了之后,它们往往还存在,还在不断地发展和传播。

如果能把程序用机器能理解的语言写出来,就可以让机器去完成原本需要人去做的重复性工作,从而突破人类的体能极限,做到原本做不到的事情。一百多年前,正是家用电器的普及使女性从繁重的家庭工作中解放出来,从而能参与社会工作,其中最重要的电器莫过于洗衣机了。当时一个传统的家庭妇女每次洗衣服要花三四个小时,而洗衣机和的出现,使洗衣服的时间减少到了不到一个小时,而且大部分的时间是机器在工作,人不需要参与。
我们都知道,机器在完成重复性的体力工作上是全方位碾压人类的。没有哪个银行柜员会和点钞机比速度,也没有哪个交警能和电子摄像头比耐力,更没有哪个举重运动员会傻到去和起重机比力气。我们也知道,现在人工智能已经发展到了令人可敬甚至可畏的地步。几年前,人类和软件下中国象棋只要十盘能和上三盘,就是国家特级大师了,根本不要想赢的事,因为软件算无遗策,根本不会犯错误,而人只能减少犯错的概率,却不可能永远不犯错误。围棋曾经被视为人类最后的智力堡垒,现在也被AlphaGo给碾压了。
机器可以不吃不喝不睡24小时运转,不要工资不要福利不请假不偷懒不休息不发脾气,性能两三年就翻一倍,成本则降低一半,干活比人又快又便宜还靠谱。即便只是把工作中的一部分交给机器,也能大大提升工作的效率并降低成本。更何况,机器可以廉价批量生产制造,软件可以免费快速复制,从而可以让一个程序迅速大规模普及开来,使其价值最大化。
而如果靠人来普及推广的话,教育、培训、训练、维持的时间和金钱成本都太高了。优秀的人既无法量产,也无法复制,更不愿意做重复性的工作。一项工作先让人去做,总结经验并写出程序后再让机器去做,最后让人负责不断优化和迭代程序,这才是最好的安排。
那么有人就问了:编程是很好,那不能让让专业的程序员去做吗?我们普通人只要享用他们提供的软件和服务就好了,真有必要时请个程序员不行吗?

我们正生活在一个即将、甚至已经由程序支配的世界。股票交易、地铁运行早已由程序接管,因为没有人能处理如此大的数据量,没有人能作出如此精准的操作,更没有人可以承担出错的责任;全自动流水线和机器人已经席卷全世界的制造工厂;我们每天拿出手机轻轻一点,百度地图就帮助你规划好了路线,QQ音乐帮你识别出了马路上听到的音乐,今日头条推送了你最感兴趣的新闻,抖音刷出了你最爱看的视频……
在电器时代来临之前,那怕是手表这样复杂的机械结构只要拆开了慢慢研究,总能明白其中的道理;像台灯和电风扇这样的简单电器,具备简单的初中物理学基础后,观察电路板也可以理解原理;然而在集成电路出现之后,就出现了一个不可观察的黑盒;互联网时代的软件和APP,用户更是只能接触到操作交互界面,对界面后的服务器和运作逻辑完全一无所知;到了人工智能时代,我们会发现自己身边存在着无穷无尽的黑魔法,它们功能强大,简单易用……但是我们永远无法理解它们到底是怎么一回事。
很多人不满足于现在我们生活的世界,想要改变它。但是,如果根本不能理解这个世界,又谈何作出改变呢?如果你很需要这个世界,而这个世界却根本不需要你呢?那你的存在,还有价值吗?
编程,就是信息时代的物理学。学习编程,就是为了更好地理解并改造我们生活在其中的这个世界,从而让我们在不远的将来,能更好地生存下去。因为即便所有的工作都被机器和软件取代了,这些机器和软件本身也是需要人维护和升级的。当然,这些人肯定都是会编程的人。
三、怎么学习编程?

最近两年,少儿编程可以说是现在是国内最热门的风口了。随着教育部连续发文要在中小学推行人工智能和编程教育,腾讯、网易、京东、新东方、学而思等巨头也都纷纷布局。各类培训机构不断贩卖着家长们的焦虑,把孩子们送进这样那样的培训班,参加这样那样的线上课。 Scratch、Python、智能硬件、机器人……花样层出不穷,看得人眼花缭乱。那么,到底该学什么、又该怎么学呢?
现在想要学习编程的,大部分是对未来充满焦虑的成人,或是孩子的家长。我今天的这次演讲,有可能进一步加深了各位的焦虑,这里首先对各位表示抱歉。接下来,我就给大家分析一下学习编程的目标,以及可供选择的学习内容和学习方法。我说的只是个人的理解,并不一定对,仅供大家参考。

首先,我不太建议把「当一名程序员」作为学习编程的目标。在别人眼里,程序员这个职业往往意味着高薪+年终奖、弹性工作制、免费零食下午茶、下班打车报销……然而作为一名从业多年的程序员,我会告诉你只有在北上广深这样的发达城市里还能够表现出众的人,才可以享受到这些待遇。大多数程序员和普通的工薪阶层一样,干着整天搬砖的活,加班加点累死累活,还赚不到满意的薪水,因为他们就像螺丝钉一样,可以被随便替代,因为大家拥有的技能都差不多。公司越大,程序员就越没有存在感。
程序员干久了,你就会发现不管在哪家公司,其实干的都是一样的活。业务逻辑不外乎就是增删改查,核心服务不外乎就是用集群负载均衡抗住流量。原本认为自己从事程序员的是为了消灭重复而生的职业,到头来每天做的却是千篇一律的重复工作,真是可笑。这也正是我选择放弃程序员生涯,转而从事教育事业的核心原因之一。

普通人最应该学习的不是一门编程语言,而是编程的基本概念和解决问题的方法论。正如我们都需要了解必要的物理常识,却没必要成为物理学家一样。编程的每一个核心概念(循环、事件、函数、变量、队列、缓存……)和方法论(调试、封装、自顶向下、自底而上……)都是一种思维工具,可以迁移到任何领域重复使用,并受益终身。
我家里有一个小爱音箱,想要让它放首歌,可以跟它说「小爱同学,播放张学友的歌」,也可以说「小爱同学,播放沙漠骆驼」,还可以说「小爱同学,来首适合睡觉听的歌」……这其实就是编程中的「兼容性」概念的一种拓展应用,可以接受多种形式的输入。如果只能用一种规定好的方式来调用功能,那么符合了一些用户的习惯,却又不符合另一些用户的习惯,用户就会用得不爽。
那么,我们该怎么学习这些基本概念和方法论呢?这些概念和方法论分散在编程的各个领域,出现在各种专业书籍和教科书上。但现在市面上,还真就没有面向初学者讲述基础概念的书和课程。大多数的书都是在教你如何用一种编程语言,按部就班地完成某些功能和效果。然而零基础的学习者连最基础的编程概念都不明白,即便照猫画虎操作上一遍,实现了最终的效果,还是搞不明白这到底是怎么回事。为什么这里要这样?为什么不能那样?……真正的小白问题是专业人士想都想不到的,但这些却是初学者最需要的。
我现在正在写一本面向零基础的高段儿童和成人的书,希望今年能顺利完稿,敬请关注。
接下来,我给大家简单介绍一下零基础学习编程可以考虑选择的课程:
1、Scratch

Scratch是由美国麻省理工学院(MIT)于2003年推出的一种模块式编程环境。Scratch不需要掌握任何编程语言,只用拖拽模块就能完成编程。Scratch提供了丰富的基础功能,支持插入自定义素材,也可以进行很多拓展,可以用来制作不错的游戏和动画。现在市面上流行的少儿编程课程,大多是Scratch的衍生物和仿制品。

但是Scratch并不提供课程,所有的课程都是第三方开发的,质量良莠不齐。另外Scratch的界面太丰富,容易让学生失去焦点。零基础的学习者在不经指导的情况下,很难摸到门路,只靠自己尝试往往是无法真正理解的。即便是按照一个别人设计好的流程,按部就班地一个步骤一个步骤地完成,最终得到一个大同小异的项目。成果倒是有了,可以发到朋友圈去炫耀一下,但学习者其实还是没搞明白其中的概念和原理。
2、Code.org

Code.org是美国的一个公益网站,和Scratch一样是拖拽模块式的编程,还针对不同的年龄段提供了免费的编程课程。Code.org提供的课程相对精确且系统,能循序渐进地让学生者接触各种编程概念。比如在学习循环时,只提供必要的模块,不会像Scratch那样出现大量的选择来让学习者感到困惑和无从下手。

然而,想要纯靠Code.org来自学还是有一定难度的。虽然对每个概念都提供了英文的视频(有中文字幕)讲解,但想让零基础学生真正理解概念,还需要配合一系列的线下课程。因此只有在学校或培训机构里由老师指导进行学习,才能取得最好的效果。另外Code.org在完成基础部分的学习后,后续的自由度和扩展度明显不足,它不支持上传本地素材,也不支持第三方扩展,难以像Scratch那样做出真正个性化且有用的项目。
即便如此,我仍然觉得Code.org是目前市面上能找到最好的零基础编程课程。我在运城国际学校的编程课,就是在它的基础之上进行研发的。完成基础阶段的学习后,可以考虑过渡到Scratch,也可以直接过渡到Python。
3、Python

Python可以是目前全世界范围内最火爆热门的编程语言了,因为大部分的人工智能项目都是用Python写的。而且在各种正规编程语言(Java、PHP、C++……)中,Python的语法简单,对初学者相对比较友好,学习起来相对简单一些。
尽管如此,Python的学习门槛依然较高。学习者需要掌握语言特性、开发环境、包管理等等一大堆知识和技能,才能真正在工作中应用起来。然而一旦学会,就可以用它来编写一些实用脚本,来提升日常工作的效率。比如每天我都会用Python脚本来自动生成上课记录单,统计需要补课的学生名单并发布通知,统计Excel表格中的数据……

零基础学Python,我推荐大家试试网易代理codecombat后推出的《极客战纪》,它会通过游戏的形式让你熟悉Python的基本语法和一些语言特性。但是它仅限于让你用Python解决游戏中的问题,如果想要用它来完成实际工作中的任务,还是要买一些零基础的入门书来看看,并多多在网上学习,掌握查询和阅读开发文档的能力。
我曾在《「学习」到底是怎么回事?》一文中总结过自己的高效学习方法论:「大量试错 + 持续迭代」。不管你想学什么,都要想办法构建出一个有保护的环境,降低试错成本,然后反复尝试各种可能性,再从可靠渠道获取有效反馈,自己不断反思迭代,这样才能以最快速度地成长。
比如你学要游泳,先看上一大堆视频和教程,其实都是没用的。最有效的方法就是先跳到水里,带上鼻夹和泳镜,保证自己不呛水,然后多喝水多扑腾,不断摸索尝试,直到找出最适合自己的方法。你可以按照教程来,但是每个环节都应该试试不同的方法,多问问自己「如果这样会如何?」「为什么不能那样?」之类的问题,然后去大胆尝试,找到自己的答案。
所谓的高手,不过就是把能犯的错误几乎都犯过一遍,对各种小概率事件足够熟悉的人而已。
后话
虽然教育部三令五申要在中小学推广编程教育,但事实上只有极少数学校真的在教学生编程,更多学校里上的还是传统的信息技术课,也就是教Office、PS、Flash之类常规软件的使用:

为什么编程课难开?因为合格的编程老师太难找了。然而计算机专业是典型的理科专业,男女比例相当悬殊。那些学得好的、能力强劲的,大都跑去做程序员了;在剩下的人里,愿意当老师的也少之又少。因为当老师不仅收入低,还需要有亲和力、沟通能力、耐心,这往往跟理科男的特质格格不入。
最理想的编程老师,应该是既是拥有充分编程经验的程序员,又是具备充分教学经验的老师。但程序员整天和机器打交道,老师整天和学生打交道,本来就在要求完全不同的性格和能力。这两个集合的交集本来就非常小,想要在里面找出一个既有编程能力,又有教学能力的人,更是难上加难。
而英美国家则从小学甚至幼儿园就开始进行编程启蒙了,而中国绝大多数的中小学乃至高中生都在学怎么用办公软件,只有到了大学的计算机专业才有机会接触到真正的编程。中国的计算机系优秀毕业生往往并不会输国外,在世界上还是很有竞争力的。但非计算机系的学生呢?

我曾有上百次面试官的经历,也写过不少程序员面试相关的文章。我发现大多数应聘者都是能干标准的活,但没能吃透最核心的概念和原理,因此情况稍微变化一下,就不知道怎么应对了。他们接受了太多关于怎么通过考试、乃至如何通过面试的教育和培训,反而丢掉了最宝贵、最有价值、能让他们受益终身的东西。
在我了解到我们和国外的编程教育的现状差距后,我觉得我有责任做点什么来改变这一切,所以我选择了投身编程教育事业。经过这两三年的教学实践,我认为自己已经找到了一些行之有效的方法,可以让小学阶段的孩子们掌握最基础的核心编程概念,以及解决问题的方法论。
接下来的路该怎么走,我还在不断地探索之中。其实就连自己能在这条路上走多远、走多久,我也无法给出一个答案。但我坚信在不远的将来,会有越来越多的人会认识到学习编程的价值和意义。总有那么一天,编程会成为人人都不得不掌握的一种思维技能。
但愿到了不得不选择出发的时候,我能为大家照亮前方的路,哪怕只有一小段也好。
