资讯中心>资讯正文

二十年编程生涯教会我的事

少年创客官方 阅读:100

我是徐雁斐。感谢有这么一个机会,在这里和大家聊聊程序员这个职业带给我的收获,分享我对中小学计算机教育的想法。 






从初一在小霸王学习机上用logo小海龟画图算起,已经写了二十几年程序了。


我在研究 Scratch 教学的时候,留意到了美国的 k12cs 框架和 csta 标准,发现它们很接地气,能看到很多工程实践的影子。仔细一瞧,果然,这些框架和标准制定的背后,有谷歌、微软、亚马逊等众多科技公司的支持。于是,我就在想,我们国内 IT 行业的从业人员,也应该做些什么。


我希望能在工程师和老师之间架起一座桥,让工程师的技术能力和工程实践经验,与老师的教学理论和经验相结合,共同推进我国青少年计算机科学教育的发展。




今天我来这里,是想和大家分享编程带给我的收获。既然写了二十年代码,我就先说说过去、现在的编程有什么不同。  




十几、二十年前,写程序很难,我记得自己当时看《effective C++》、《C++ prime》等书,学习无数奇技淫巧。那时候要写一个有界面的可以真正投入使用的程序更麻烦。


现在流行的语言就比 C++ 容易多了,而且github上能找到各种好用的框架和类库,大大降低开发难度提升开发效率。更美妙的是,我们还有大量云服务可以用。可能我写一个APP,里面的聊天的功能是使用融云的,视频直播是七牛的,服务器端的数据读写用的是LeanCloud……虽然我的程序看上去很厉害,换在十几年前,每个功能都是一个大坑,足够写上一个月,但现在我只需要用“胶水”把一个个云服务粘起来,很快app就写好了。


现在甚至很多事情都不需要写代码就能完成。常有非 IT 行业的要我帮忙找人开发网站,往往听完需求后我就扔个链接给他们:用在线建站工具托托拽拽,很快一个漂亮的网站就做好了。APP,小程序,都有这类服务。


这是好事吗?当然,节约了多少时间呀!工程师们不需要重复造轮子了。


但是,这也使得程序员的价值越来越得不到体现。好些互联网/移动互联网创业公司里,程序员做的事难度不高,只要动作快、能跟得上运营的节奏就行。所以会有很多工程师自嘲码农,他们就是为产品、为业务、为运营服务,在这些公司里技术真没有多么重要。


那么,我们到底还要不要学编程呢?难道真的就去当码农吗?




不妨参考一下英语专业。


在三十年前,懂英语是一件很厉害的事情,引进了国外的机器看不懂说明书,商品想要卖到国外,就一定得请个专门的翻译。但十年前呢?英语已经成了年轻人的基本技能,光会翻译说明书或者商品介绍,是找不到好饭碗的。


英语专业的人是不是就很倒霉呢?其实也不是。你会发现英语专业毕业后从事的职业很多元,而且做得厉害的还不少。最出名的一个,是英语老师马云,对吧。


为啥学了英语做别的事也能做得不错呢?因为在十年前,大家虽然都学英语但普遍水平一般,学得好的那些同学就多了一扇面向海外的窗。他们有更多机会去接触更先进的东西,自然成长就会更快。


英语给人们打开了一扇面向海外的窗,那么编程,就是给擅长它的人打开了一扇面向未来的窗,让他更好的看清未来。为什么我这么说?接下来我就来讲讲编程的作用。






从工具的角度来看,懂编程最直接的好处,就是能让你更好的使用新时代的工具。作为一个程序员,自己写了那么多程序,当拿到别人的产品的时候,默认就应该是秒懂的,如果没秒懂那大概就是产品设计的问题。所以对于一个计算机行业的人来讲,我们不会对陌生的应用犯怵;我们会很清楚的知道一个功能的边界在哪里,哪些事情是它能做的,哪些事情是不能做的;我们还会思考它的实现原理。程序难免会有 bug,遇到 bug 之后,懂程序的人就可以猜测这个 bug 是什么原因导致的,有没有 workarounds,也就是把程序产品从黑盒变成白盒了。 


 

懂编程更大的好处,是自己可以创造工具。我把这种创造称之为木匠精神。在我小时候,家里有一个木匠是件非常幸福的事儿,需要个桌子椅子大衣柜什么的,直接找个木匠朋友打出来。有了需求撸起袖子动手做,这就是我说的木匠精神。


会编程的人可以写工具来满足自己的需求。我大二的时候学德语,德语中有几个字符是英语里没有的,在德语论坛发帖时遇到这样的字符就很麻烦。我花了一个小时在论坛发言的输入框边上加了几个小按钮,每个小按钮一点就加一个特殊字符到输入框里,整个论坛几千号人一下子都感觉好幸福,这就是程序员发挥木匠精神去搞定生活中小问题的例子。IT 公司也常会举办黑客马拉松,创作各种提升工作效率或者是生活幸福感的小工具。




学编程,对我更深远的影响,是思维的塑造。


写了二十年的程序,我能清晰地感受到自己的思考方式是怎样受到写程序的影响。哈佛有一本书《Future Wise》,里面提到我们需要学多种不同学科的思考方式,例如像经济学家一样思考、像生物学家一样思考,等等。看这本书的时候我就在想,像软件工程师一样思考会是怎样的呢。我觉得拆解问题、抽象化,是其中非常重要的特征。谷歌的计算思维课程指出计算思维是一种解决问题的方式,先分解问题,识别出模式,然后抽象化并用算法来实现。确实,这就是软件工程师的思考分方式。


同学们听到这儿可能会觉得有些奇怪,这种思维方式没什么大不了的呀,我们平常不一直在拆解问题吗?确实,所有学科领域,从生物、化学到文学、社会、艺术……都能用上计算思维;甚至可以说早在计算机出现之前,人类的思维体系中就已经有它存在。那为什么,“问题拆解 > 识别模式 > 抽象化 > 算法实现”,这么一个过程会被称为“计算思维”(Computational Thinking)呢?为什么是 computational 而不是别的学科?




一眼就看到的原因,是如今各个领域的很多问题,不管是DNA序列分析还是莎士比亚作品的真伪判断,到“算法实现”这最后一步,光靠人力不行,必须要用到计算机。但是我觉得更重要的一个原因是思维可见性。


计算机领域的思维有非常强的可见性。我们写稍稍复杂一点的程序就免不了要画模块图、时序图、流程图……等到画好了还要定义接口、写文档,最后还要把它变成机器能够读懂的代码。所以计算机专业的人一直在做的事情,就是把脑子里面的那些还抓不住的思维可视化。思维可见了,就会变得清晰;当你能清晰的看见它之后,就能更好的去理解它、更好的知道以后你怎么去使用它。哈佛的另一本书《Make Thinking Visible》就有说让思维可见能非常有效地提升思考能力。我觉得计算思维最先在计算机领域被提炼出来,它的强可见性的很重要的一个原因。


举一个让思维可见的例子。大家平时是怎么玩桌游的呢?普通的玩法就是读懂规则,然后一群人很 High 的开始一起玩,对不对?但我经常会做的事情,是先读懂规则,在脑袋里转换成一堆的 if...else...。然后我开始思考玩的策略,策略又在我脑子生成另一堆if...else。这些东西是如此清晰的在我脑子里被描述出来了,所以我玩起来就很轻松。




最后我要强调一下抽象思考。程序员,尤其是讲究设计模式的“古典”程序员,特别擅长抽象思考。你写一个程序,可能用到了某一些方式,再写一个程序,又用到那些方式。慢慢的你会发现有些相似的东西不断地出现,我们就将它提炼成设计模式,在今后的编程中反复使用。


在生活中我也经常会去模式。我曾经和家长朋友们做过“每日一问”的活动,就是每天和自己的孩子讨论一个问题。那么多问题从哪来呢?我给朋友们分享了很多模式。比如说“如果没有XXX会怎么样”,这是一个模式,可以派生出很多问题例如“如果没有照相机会怎么样?”、“如果没有自来水会怎么样?”。我用过的模式还有“你能列出多少种不同的XXX”、“XXX可以改造成什么”、“XX和XX有什么不同”……我脑袋里装了几十个这样的模式,跟孩子聊天找问题就变得特别容易。有人就问我是怎么找出这些模式来的,很简单,我是一个架构师,我写程序的时候无时无刻不在做的事就是找规律,提炼出模式。我开车带着女儿去老城区,停车位很难找,我们就聊怎样让老城区停车更方便;坐火车排队过安检,就聊怎样让安检队伍短一些;然后我就总结出一个模式:“怎样让XXX变得更好”。这就是模式归纳、抽象化,我们写程序时一直在练习这样的能力,后来我发现在生活中它也很有用。




我刚才讲的这些收获都是我在工作中获得的。我知道在座的各位今后不一定会去 IT 公司工作,你们有可能会成为老师,甚至有可能都不是计算机的老师,那么如何获得这些益处呢?。我的建议是从现在开始,大家在日常的计算机科学的课程的学习当中,要多做一些事情,去有意识地培养这些能力。 


 

首先,是你要会由表及里,去理解藏在知识背后的思想。你要去想这些东西是怎么设计出来的,为什么是现在这样的设计,要去看设计这些东西的人是如何化繁为简,要去体会他们思想中的美丽之处。


举个例子:网络与通信这门课大家是怎么学的?背诵 OSI 七层模型和 TCP/IP 四层模型?光背这些东西,只能够考试拿高分,但我希望大家能透过这些考试的知识点,看到分层的思想。分层是计算机领域中非常重要的一个概念,我们有一句名言:“没有什么问题是分层不能解决的。如果添加一层不行,就添加两层。”为什么?因为如果你要开发的东西架构太复杂,通过增加层次可以让关注点分离——“关注点分离”,这又是一个重要概念——每一个组件只需要关注它这个层次所需要关注的内容,每一层都有明确的职责。层次清晰了、职责明确了,那么软件的研发自然也就变简单了。


还有数据结构:队列、堆栈,多简单的东西啊,就那么几种非常的抽象的描述。恰恰是因为抽象才通用。我们开发程序需要用到的各种各样的东西,现实生活中的万物,都能映射到计算机里面就那么简单的几种数据结构,为什么这么强大?你们可以通过数据结构,去体会抽象的力量。


再举个例子:操作系统。操作系统除了解释计算机怎么运行的,它还能教我们什么?想象一下支撑那么多复杂功能的系统,其实无非就是文件系统、进程调度、存储管理、用户界面等等几个模块。那么复杂系统是怎么被分成这几个模块的?几个模块之间又是怎么进行交互的?模块化又是一个很重要思想。


分层、抽象化、模式化……这些都只是小小的例子。我想表达的,就是当你去学课程的时候,一定要由表及里地去理解背后的奥妙。




其次,你需要能理论联系实际,要理解这些计算机知识在真实世界的模样,知道它们的生活价值。


比如,大家在学数据库的时候,一定会学各种范式,但当你去看互联网公司的数据库表的设计,会发现并不是严格遵循。不管是出于性能的考虑,还是数据特点和使用特点的考虑,都可能用到不少冗余字段。这里的平衡如何取舍,是很值得去体会的。


你们的课表中 Web 开发和 android 应用开发是两门不同的课,你有没有思考过一个网站和一个 APP,这两中不同的软件形态差异对文化有什么影响吗?Web时代的超链接是一个非常伟大的东西,把网上各种东西纵横交错的连在了一起;到移动互联网时代,一个个应用就陷入了 APP 孤岛,因为点击跳转到另一个 APP 之前你还得先下载。这种差异产生的影响是非常深远的。大家可以去思考一下,现在在微信这么一个超级 APP 里,有公众号、有小程序,它们之间要不要有相互间的链接?是全开放还是应该加什么样的限制?为什么?


再比如,软件工程。光记忆瀑布模型、敏捷宣言,是没有用的。你需要的是多问几个为什么,去搞明白这些方法论到底是怎么来的,是怎样的经验总结。


总之,以前我在读书的时候挺傻的,学校安排什么课程就学什么,好好考试拿个A就好嘛。到工作时,带着我一肚子脱离现实的学问,也没觉得科班出生有啥特别。后来才渐渐意识到,其实课本能教我的东西真的挺多的,好些工作几年后才悟到的道理,回头一看,当年读书时就学过嘛,只不过当时的理解太过表面,我没想得那么深呀。


所以,我现在特别想给大家的建议,就是好好学计算机基础知识,由表及里的去思考它背后的思想,由理论到实践的去理解它的生活价值。




好,现在假设你们已经很好的学了这些计算机科学的知识。当你们成为老师之后,怎么教孩子,才能让他们也收获到这些好处呢? 


 

首先,是要培养孩子们的工具意识。我前面讲了,编程的作用,首先是让我能更好的使用新时代工具、并且自己创造工具。


关于使用工具,举个例子:现在不少老师用手机布置作业、管理课堂,孩子们以ppt形式交的作业也越来越多,这些都是潜移默化的影响,挺好的。我们还可以教孩子使用网络问卷收集数据,使用公众号宣传自己的社团,等等。


关于创造工具,对孩子来说,首先就是要理解这个被计算机改变了的世界。现在的孩子,满大街看到摩拜、OFO扫个码就能开锁骑走,打车用手机,付钱用手机……这些生活在数字时代的原住民,会觉得轻巧万能的触屏手机,就是这个世界的本来模样。我们得把万物背后的技术深入浅出地讲解给孩子们听。只有这样,他们们才会知道,世界是由人创造出来的,才会在他们遇到问题时,想着自己是不是也能创造些什么,来解决问题。


其次,我们要锻炼孩子们的思维。一方面,可以通过编程来教。

另一方面,我们甚至聊聊天就教孩子们很多计算机知识。通过对话潜移默化灌输一些计算机知识。




刚才说到用编程来锻炼,Scratch是一个很好的工具。班门弄斧一下,这是哈佛用 Scratch 教《创意计算思维》,其中用到的三维框架,王老师有论文就是关于这个。


这三维,是从低到高三个层面上的东西。

第一层,所谓的编程思维,是基础,绝大多数商业机构关注的就只是在这一层。

第二层,是很多的实践,这是真正能锻炼人给人最大收获的部分,孩子们对计算思维的感知,来自于这里的实践过程。

第三层,尝试、探索,用编程的方式表达想法,创造力,这些是我们真正希望孩子们培养起的能力和习惯,是我们教学的最终目的。


我希望在座的各位,如果今后你们走上教师岗位,千万不要只满足教第一层面的东西,要多多关注第二、第三层面的东西。


好了,我的分享就到这里,谢谢大家。


本文转载自公众号“南瓜博士”。