真正的编程高手,都具备高度抽象能力。
生活中许多现象,其实不仅仅是我们表面看上去的那个样子。
比如企业招聘时,往往要求学生必须通过英语四六级,并不是因为英语有多刚需,而是为了确保应聘者是个合格的大学毕业生。英语或其他证书的合格,证明他曾经在大学里认真学习过,更容易在工作中也可以有持续学习的能力。
比如一些专家宣传红酒有利于健康。真正原因是,有条件喝红酒的人,往往社会层次相对高,人更有钱,能拥有更舒适的生活条件,更好的医疗保健条件,更多的体育锻炼条件,更充分的健康意识等等。是这些条件,而不是红酒,让他们更健康。
比如花大价钱买学区房,让孩子进入好学校,是孩子日后成绩优异的原因。但真正为孩子创造成绩优异条件的,是愿意花大价钱买学区房的家长,是高度重视子女教育的人。他们往往本身也比较优秀,这种家长会在各个方面督促、帮助子女学习。是这些家长,长年累月的努力和关心,才让他们的孩子学习成绩更好,学区房只是一个表象而已。
为什么有的人能看到现象,有的人能分析更多原因甚至直击本质呢?
因为抽象能力。
在之前的《编程究竟难在哪?》,我们谈过编程思维,其实就是“理解问题——找出路径”的思维过程,它由分解—识别模式—抽象—算法四个步骤组成。
今天,想和大家探讨的是这其中最重要的一步——抽象能力。
(一)什么是抽象能力?
人们在实践中认识到,在现实世界中一定事物、状态或过程之间,总存在某些相似的方面,即共性。
把这些相似的方面集中和概括起来,暂时忽略它们之间的差异,这就是抽象。
比如,我们将10只十分熟悉的猫咪放入100只陌生的猫咪中,一开始仅靠形象记忆,就可轻而易举找到这10只猫咪,但如果把这10只熟悉的猫放入一千只、一万只、十万只陌生的猫群中,我们仅靠形象记忆找到猫的困难会越来越大,大到不可能。
如果在10只猫身体上都打上记号,事情立即会变得很简单。
这个打记号的过程,是抽象思维。
抽象思维在理解概念时,就是在给所指事物寻找记号,不过这个记号不是人为的,而是事物本身固有的,指的是事物的规律和本质。
当我们遇到从未见过的事物时,如果能够运用“抽象思维”去寻找记忆中的知识——现有的事物之间的联系,作为解决过程的关键要素,那么我们解决问题的效率将会大大上升。
《北大逻辑课》一书中,就讲了一个运用“抽象思维”解决现实问题的例子。
在大宋提刑官中,有这么一桩有名的案子:
有一天衙门接到报案,发现一民居失火,男主人与房屋都惨遭不幸,而女主人因为刚好有事离家,因此幸免于难。
正在女主人为丈夫的逝去而哭泣的时候,法医宋慈发现了尸体的异样:死者虽表层皮肤被烧毁,但口中十分干净,并无烟灰。于是断定这个案件并非意外事故,而是另有凶手隐瞒真相,死者是先被谋杀、后尸体被烧毁。
宋慈的推理过程是这样的:
取一活猪、一死猪一起放在火中烧着,取出后发现活猪被烧毁后口中有大量烟灰,而死猪口中十分干净,并无烟灰。
宋慈解释道:“之所以会如此,是因为动物在被火烧会发出激烈的自救运动,而剧烈运动会大量的呼吸氧气,同时,就必然会把烟灰吸入口中、肺中,例如我们过年烧的猪头,由于是死猪,口中就十分干净。”
“同理,本案中死者的口中并无烟灰,因此可以推断,他在火灾发生前,就已经被人杀害了!”
宋慈之所以能做出这段推理,就是灵活运用抽象,从“猪遇火灾的反映”抽象出“口中有无烟灰是生物遇火时,是死或生的唯一标准”这一定理,并加以证明的结果。
一个抽象能力强的人,往往能从复杂的现象中直击事物的本质。也就是我们生活中常见的“这个人总是能抓住重点”“这个人总能看到我们看不到的”。
二、为什么抽象能力如此重要?
1.抽象能力决定你是否能比别人快速掌握技能
回忆你学习的过程,其实是一个抽象能力的过程。
首先,你需要观察大量具体事物,比如学英语,要观察大量的英语单词;学物理,你要解答很多相同的题型。
在这基础上,你寻找共同规律。很多英语单词都是很多词根、词缀组成的,而词根、词缀又是有限的,这是一种规律;物理考试考的都是不一样的题目,但很多习题考察的都是牛顿的三大定律。
紧接着,你开始加以演绎变化。在英语单词里,词缀有些是放在前面,有些是放在后面,有些词根、词缀两两组合,根据不同的排列组合,就会得出一定的变化。
最后,你总结出共同规律和这些规律演绎出来的新变化,即使遇到新的问题,也能迅速答出/应对。
这也是为什么以前老师总是让我们做题海战术,只是有的人只停留在了“题海”,有的人于千千万万中寻找规律总结出了一套“战术”。
编程也是这样,初级开发者和高级开发者在技能的学习、使用上是有差距的。
初级开发者往往只是停留在“见西瓜是西瓜,见葡萄是葡萄”的层次,客户/产品说什么就做什么,在设计上让你怎么做你就怎么实现,从来也不去想是否满足了用户哪些方面的需求,代码质量和结构也就很难得到保障,甚至通常会等到逻辑重复时再抽象封装,可能只能解决了表面问题,严重则会引起返工。
但高级开发者,能够根据业务的特点,抽象出软件最合理的设计,使得程序具有良好的可读性和扩展性,通常一开始写出的逻辑就为了以后的重用。
许多开发框架就是一步步抽象/埋坑/优化而来的。
包括各领域的顶尖高手,他们之所以能在自己的领域上,有深刻和精到的认识,能够解决复杂困难的问题,并且能够不断产生创造性的想法并付诸实践,除了具备大量的知识积累外,也依赖于其个人的抽象能力。
像数学、物理、化学以及其他各学科中的各种各样的公式,它们都是抽象思考的结果。
2、抽象能力,能把复杂的问题变简单
我之前看过一个产品经理分享的案例,说他给大神级别的人物汇报产品方案的时候,被对方为难,对方反复说一句话:不要说这些具象的东西,讲一些抽象的概念。
当时他很不理解,方案最终不是要看具体的产品原型吗?为什么又要抽象呢?
在后来的工作中,他才意识到能讲出抽象的概念有多重要。因为把事情想复杂很容易,但是把复杂的事情想简单,是个需要功力的活。
从简单到复杂,更突出全面性,多积累经验多假设一些情况就可以。
但从复杂到简单,则需要从表面看到本质,从片面看到整体,然后提炼出共同的特征。
作为产品,要满足的,往往是一个需求类别而不是具体的某个需求,所以一定会考虑代码的复用性、组件的复用性、同一个功能对不同场景的复用性。有了复用的能力,才能够用更少的开发去满足更多场景的同类需求问题。
因此,一个具备抽象能力的产品经理,是反复从一个具体的需求,看到一类的需求,看到衍生的相关的需求,甚至再对需求进行分类,看到更高层面的需求,进而系统性解决同类的需求的循环训练。
如此反复训练,当他们再遇到复杂问题时,便比其他人,能更迅速直击到本质而简单的重点上。
在我们的生活里,利用抽象把复杂的问题变得简单的场景也有很多。
看看我们的地铁路线图。
即使不标出各个站点之间相隔的具体距离,也没有标出它们的具体位置,仅仅只是提取了必需的信息,就能将整个复杂的地铁体系简单地表现出来。我们只要有地铁路线图,就可以知道要怎样去各个站。
还有日历,日历将日期和星期的概念用简单的一连串的数字排列表现出来,我们在看日历时,就可以直观地理解日期、星期以及月份。这是因为日历将这些概念抽象化地、精准地表现了出来。
3.抽象能力,是能力的能力
台湾大学哲学系主任傅佩荣,在《西方哲学课》中谈到哲学是什么时,问了大家两个问题。
第一个问题,你到全世界任何一所图书馆去查找书,可以发现编号都是从“1”开始,请问:编号“1”的会是什么?
是哲学。哲学为什么排第一呢?因为世间所有的学问分门别类,只有哲学是一个整合性的学问,把各种学问整合起来找到重点,给你一个明确的归纳。
第二个问题,你看到有些人明明研究的是数学、物理、化学,或者专攻社会学、心理学、人类学,但是他们研究到最后所得到的最高的学位都称作“哲学博士”,这又是怎么回事呢?
在西方传统中,经过整个中世纪的发展,到近代的时候,他们认为哲学是所有学问里面最特别的,它可以称作“学问的学问”“知识的知识”或“科学的科学”,是各门学科里面最具综合性的学科。
因为哲学是一门人们对具体事物进行抽象与概括、说理与解释、透过现象看本质的学科,它是抽象思考的过程。
因此可以说,抽象思考体现了综合能力,是一种元能力,即“能力的能力”。
我们每个人都拥有元能力,比如,我们知道反思,能说出某一道题的解题思路,能不断地追问自己为什么,甚至能隐隐感知别人在想什么。
但每个人的元能力又有高低之分。
很多传统广告人写文案,更追求灵感,想个创意需要对环境和心情提出要求,否则就难以创作。
后来,一些优秀文案行家出现了,告诉大家写文案不依赖灵感,是有科学方法的,只要掌握了科学的营销方法,写文案就像做数学题一样套用公式就可以推导出来,于是传统广告人懵逼了。
这套科学写文案方法,是将大量文案的规律和方式总结成系统性的知识。这过程其实就一种能力的能力。它最大的优势就是,能够建立一个完整的知识架构,来提高学习认知和解决问题的效率。
综合以上,抽象能力非常重要,甚至决定着一个人能力水平的上限。
正如每个高级开发工程师都能做到:一旦掌握了某个语言的语法,就能将问题映射成语法,写出合格的代码。
如果你不想一辈子都做一个初级码农,想写出来一些自己也感觉到满意的代码,不被更高级的编码工具取代,你需要学会抽象。
三、如何培养抽象能力?
抽象能力的训练和培养,离不开对大量具体事物的观察,发现共同规律并加以演绎变化,最终找到提高效率的解决路径。
这个过程就是学编程的过程。
编程中抽象思维运用的极为普遍。一般在实际工作中,常常需要把问题的实体对象,根据需求表示为各种数据结构如树、堆、栈等,把业务逻辑过程表示为各种算法如排序和查找等。
抽象表示是解决问题的第一步,也是关键的一步。在程序员的实践中,一旦问题被准确的无歧义表示出来了,解决方案就烘云托月般地呈现出来了。这就是“数据即代码,代码即数据”的道理。
这种反复把现实问题转化为机器问题,将问题简化为概念模型,进而写成代码的训练,能使人变得更加精炼和逻辑清晰。
最重要的是,编程的本质也是为了解决生活中的实际问题而存在的。
一个很典型的例子,我们每个人都离不开要搭乘电梯。
当你想从 1 楼去 14 楼,涉及了编程里起终点和循环的概念。从起点 1 出发,终点为 14,循环计数从 1 到 14,满足的退出循环条件,即电梯停了,门也打开了。
当你在上升的过程中,外面有人按了按钮,涉及了编程里的判断语句。电梯的程序中,有一个判断条件 If,判断是否有人按了按钮,当条件成立,电梯就会停止。
所以,开发学编程,学的不仅仅是敲代码,更是通过总结,掌握背后一整套高效解决问题的思维模式,来解决生活的现实问题。
普通人学编程也是如此。拥有编程思维的人,是为了使自己能力更加突出:逻辑清楚、能从现象看本质、做事效率也非常高。
四、尾声
生活处处有编程,“学会抽象”就是编程教会我们的其中一门重要的人生课。
学会抽象,也是学会了大道至简。当你能去除现象看本质,你本身就在着力同构这个世界。大数据喧嚣的时代,真正的核心其实就是解构世界的一个个经典算法,是算法在无比深刻地表达我们身处的现实世界。
-END-
最后,一起来发现编程的美好吧!