本文的文字及图片来源于网络,仅供学习、交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理
本文章来自腾讯云 作者:Python知识大全
编程究竟难在哪?
“编程一点都不难,它只是和你十几年来在学校受的教育格格不入而已。”
第一次看到这句话,是在知乎问题“编程究竟难在哪里?”里一位名叫@ invalid s的高赞回答。
与也是这两年才开始半路学编程的我,所感所悟不谋而合。
所以今天站在前人的肩膀上,我想和大家好好聊聊“编程究竟难在哪?”这件事。
一、难在我们从未接受过解决问题的训练
从小到大,我们受到的教育终极目的是有一个:考取理想的学校。每一张张考卷都是一个个堆砌起来的知识点:三角函数,解析几何,数列,函数……
这么多知识点,你需要做的是背下它们,或者说的更高级一点,理解它们。
即便是强调思辨和分析的“文科类”,也可以靠死记硬背答题模板拿分,就连作文都要有统一的标准。
我记得有一年考试,题目是对冰心的一首小诗写评论:
“墙角的花,当你孤芳自赏的时候,世界就变小了。”
出题老师原意是让大家批判孤芳自赏,但有同学偏偏赞美孤芳自赏,赞美这种洁身自好的精神。而这种文章要一律判作不及格。
年纪尚小的我们甚至都来不及怀疑“为什么这个学生说得没有道理?为什么所有的人都只能有一样的价值观呢?”因为千万军挤独木桥,保险起见的我们只需要按照所理解下来的知识,将一块块碎片,根据正确而万能的模板拼好,才容易拿下满分。
我们非常擅长理解和记忆,并井井有条地套公式。
这一切,到了学编程这里,统统不奏效。
我大一的时候刚开始接触C语言,非常痛苦。那会儿,没有任何计算机基础,编程语法大多靠背——C++语法、操作系统各项定义、计算机网络各种协议、常量、作用域、多态…
身边不少同学也这样,“高考精神”还深深印烙在骨子里,我们都认为学习一门编程语言最重要的就是掌握其语法,所以为了将语法烂熟于心,最直接的方法就是记忆。
结果可想而知,即便拿了相应的学分,没有人敢说自己会编程。
我们接受了十几年的应试教育,为了最大化公平,考试必须有一套清晰的标准。正是如此,我们更看中重应试技巧而非知识本身,学习变成了追求标准答案,求知变成了死记硬背。
绝大部分人,难以形成系统的学习方法论的意识,以至于很多人一旦脱离试卷,在社会中面对实际问题的时候,完全没有一套行之有效的方法论支撑其解决问题。
而编程的核心,不是编程,不是语法,甚至不是算法或数据结构本身,恰恰是如何分解问题——发现规律建立解决问题模型,映射到合适的数据结构和算法上,最后才根据算法写程序实现。
基于此,卡耐基梅隆大学计算机的一名华裔教授提出「编程思维」这个概念。
他定义编程思维——能够把现实生活中的复杂问题,逐步拆分成可理解的小问题。
1、Decomposition,即拆分。
根据已有的知识和经验,把问题拆分。
比如我想喝咖啡,那我可以请求你:“可以帮我倒杯咖啡吗?”但这句话如果想让电脑听懂,我得先告诉它哪个是“杯子”、哪个是“咖啡”、什么是“倒”,然后再告诉它怎么去倒,比如先直走5米,左转75度,左臂下放50度……
现实生活,每一个复杂问题,都是基于解决一个个被拆分的小问题而被解决的。
比如说,超级计算机感觉很复杂最后无非是解决一个带宽问题、一个存储问题;
比如说,解决碳排无从下手,实际上是解决人口、服务、能源、单位能源的碳排放这几个问题。
2、Pattern Recognition
即模式识别。根据新问题和以前解决过的问题的相似性,举一反三琢磨出规律。
假如你需要画100只猫,你会怎么办?找100只猫来挨个临摹?
对于计算机来说,你需要找出猫的“模式”。
你要知道猫是专属的毛,眼睛,尾巴,四条腿等,按照这个“模式”,你才可以“批量”画猫——你不用每次画一个新动物,只需要变换局部特征:黄白条的猫还是黑猫,长尾巴的猫还是短尾猫。
3、Abstraction,即抽象
将问题里涉及的数据,抽象到数据结构(变量,数组,链表等),把数据处理过程可重复执行部分抽象成函数模块。
听起来很复杂吧?这是一个过滤的过程,整个过程你要聚焦重要的关键信息,忽视无用细节,这样才能通过认知问题的核心本质,帮助我们形成解决问题的构想。
比如,当我们看到这一房子,我们看到的是:
但在建筑师的眼中,它可能是这样的:·
建筑师通过自己的经验,抽象出房子里面具体的构造。
这一步,我们虽然几乎难以在应试教育的学习方法中获得,但我们能从不断地编程训练中去培养抽象思维。会编程的人,往往能透过一个应用表象,看到背后实现的步骤。
4、Algorithms,即算法。通过循环执行,根据前三步的分析成果,设计步骤,写出算法,从而解决问题。
这一整个过程,我们看到所谓的编程语言和语法,在最后才发挥出作用。
所以当我们觉得学编程难,是因为我们还未从过去根深蒂固的学习习惯中抽离出来,凡是需要打破习惯的事,必是不易的。
就像很多刚刚出国读书的孩子,常常在面对外国老师问出「why」的问题时,马上一种惊慌失措的表情,满脑子想着自己是不是又说错答案了,不知道老师这样问仅仅是为了引导他们拓展思维。
我们真实的社会和生活也是不易的,它们没有标准答案,许多人终其一生没有追寻问题的能力,无法理解世界的复杂。
而编程,是你找出解决方法的能力,把现实问题转换为代码逻辑的能力。只有认清这一点,你才能更好地攻克它。
二、难在我们从未学过创造
清华大学前校长陈吉宁曾提过一个观点:
清华大学里有很多“A型学生”,但未来社会最需要的是“X型学生”。
“A型学生”,指的是传统观念里的“好学生”,他们的成绩总是能得“A”。
“X型学生”与之不同,他们的成绩并不一定拔尖,但愿意承担创新风险,勇于尝试新鲜事物。
两者最重要的差别,在于创造力。
可是我们连作文还不敢写得太跳,生怕阅卷的是个老古董,大笔一挥,让你再考一年。创造力,更是我们在学校想都不敢想的事。
绝大部分学生的思维,早已在填鸭式的教学中,变成了一个只会收纳外部知识的容器,根本无法用所学的东西创造出任何东西来。
所以,当我们开始学编程,面对“Hello world.”这个等着我们创造的世界,其实是非常茫然的。
因为编程没有“题型”和“公式”能把你解决问题的过程简化成填空,编程提出的问题基本都是空而泛,需要你根据脑子里的逻辑推断,利用所学编程语言的各项功能组织成代码,来解决问题。
整个世界的运转,都是靠你的大脑想象出来的。这是编程的难。
但是,只要你明知其中不易,仍有一腔骁勇,你可以尝试在编程的世界中,保持“实验者心态”,不断探索自己的想法,质疑自己的假设,从所犯错误中学习宝贵的经验,就一定能在编程的魔法世界中得到更多宝藏。
如果你看过近期大火的《乐队的夏天》,那么在参赛的三十一支乐队中,你一定会被其中一支叫做“刺猬”的乐队所打动。
刺猬乐队的子健,他是台上的狂躁主唱,台下的学霸码农。
即使每天都在和冰冷的数字打交道,但作为程序员的他,体内有被保护得非常好的创造力,使得他拥有满腔的诗意与细腻的内心,更可以谱写出令人折服,引人共鸣,充满无限色彩的音乐作品。
三、难在我们从未需要如此深刻了解世界
在我工作以后,曾受过一名编程大佬指点,他说了一句让我印象深刻的话:
“所有的程序,都是建立在自然之上,我们现在所学的编程,和自然是一体的。”
举两个小例子:
C语言冒泡排序法,它的原理是来自汽水中的气泡,水中常常有许多小小的气泡,哗啦哗啦飘到上面来。而组成小气泡的二氧化碳比水要轻,所以小气泡可以一点一点向上浮动。
在C语言中,这种排序算法的每一个元素都可以像小气泡一样,根据自身大小,一点一点向着数组的一侧移动。
人工神经网络,则是依靠一种类似于大脑神经突触联接的结构,进行信息处理的数学模型。
它们都受到了自然的启发。
学编程,往往学的也不仅仅是计算机本身,而是将各行各业,结构力学,生物细胞,光学声学……等千百万个行业,抓住它们的重点,迅速理解并且教给CPU,让它代替人类工作。
尤其是身处信息时代,计算机是信息处理的核心,商业、农业、工业、教育等,都被计算机技术推动着进步,如果能知道计算机是怎么做到这一切的,即知道这里蕴含的编程思维是什么,才能给个人在所处行业的发展带来帮助。否则,就只能浮于表面地应用现成软件而已。
这是编程的第三难。应试教育标准化的课堂,正好背离了这点。
从前的课堂里,为了实现教学效益化,将课程进行了划分。
遗传学被归入了生物课,概率这个概念被归入了数学教育,然而遗传学实际上是对概率的应用。同理,物理明明需要应用代数和微积分,它却与这两门课程脱节,成了独立的学科。
仿佛每个知识只存在于真空中,于外界事物毫无关联。
这些划分限制了学生的理解,让学生对世间万物运行规律的理解产生了偏差。
于是,为了了解每个“独立”的知识,我们接收各种各样精细化加工的知识:推演好的理论、公式,讲义、ppt、难点总结、高分模板,我们无需知道这些公式是怎么推导出来的,只要运用公式去解题就好了。
久而久之,我们认为学语文就是语文,数学就是数学,甚至我们对世界的认知,只是基于“知识共同体”,对于许多现象无须究其根本,自动达成共识。
什么叫知识共同体?
史蒂文·斯洛曼和菲利普·费恩巴赫的《知识的错觉》一书提出了“知识共同体”。
知识共同体由某一知识领域相互联系的行为体组成的,人类社会本身就是一个庞大的知识共同体系统。
为了人与人之间的相互协作,人们逐渐根据不同人擅长的领域进行分工。时至今日,如果我们家的锁坏了,我们会去找锁匠;如果有人生病了,我们会去找医生。不同的工种的人,掌握了不同的知识。于是,人们被归入一个个不同的群体,这就是所谓的“知识共同体”。
我们以为自己非常了解世间万事万物,其实是个错觉,事实上我们脑袋里存着的知识微不足道,全靠相互依存和形成的认知。
就好比中世纪的人们相信地球是平的,而现代的我们相信地球是圆的,并非由于我们大多数人能够给出基于物理学的解释,而是现代科学让我们相信了这个基本事实。
即便日常生活中充满了各种各样的奇迹,也因为司空见惯的缘故,很多人甚至没有意识到它们是奇迹:
我们坐拥空调暖气,搭乘高铁飞机,手握平板手机, 搜索查询问题,享受生活之安全惬意,当整个世界的知识就在指尖之时,我们仿佛真的认为自己博学多闻,其实我们只是活在在知识共同体里。
这也是为什么我们以为掌握了知识,其实没有——
考完试以后,我们会忘记大部分所学的知识;
开会讨论出很多点子,但一到执行的时候,就故态复萌,还是不知道从哪里入手,典型的“一听就会,一做就废”。
回到学编程。
之所以感觉那么难,正是因为它不允许我们丧失独立并深入探究知识细节的能力,不允许我们冠以笼统的态度求知,因为计算机听不懂我们模棱两可的语言。
程序员需要探其根本,理解每一个概念的来由、定义和用途;需要多学科、深入而原始了解这个世界:
他要懂“生物”:不同的技术构成不同的生态系统,不同的生态系统有不同的规则。
他要懂“化学”:各类系统和语言的关键性质,提供能写出优秀程序的原料;
他要懂“历史”:技术从哪里来,要到哪里去;
他甚至还要懂“艺术”:写程序对得起自己的眼睛,做产品对得起用户。
编程世界是真实世界的缩影。
四、尾声
所以,你说编程难吗?编程一点都不难,用电脑听得懂的语言,告诉它帮你做你想要做的事情,只要认真学,谁都可以。
难就难在,"学以致考"和"学以致用"是不一样的;记忆和创造是不一样的;学好学科和理解世界是不一样的。
当然,并非要彻底否定应试教育。在中国教育资源极其不平均、经济文化撕裂的大生态下,以考试为目的的教育,提供了一套非常清晰的评判标准,通过分数这个显性的指标来筛选和划分学生群体,选拔出社会精英,可能是当下最公平的取舍了。
只是时代在不断的发展,无论是学校,家长还是孩子,都应该反思一下现在的所接受的教育形式,如何发挥出每一个自己的个性,让他们成长为更好的人——学编程的过程会给你提供答案。