再棘手的问题都能用这个方法解决
任何一个学科都有一些基础的概念和方法,可以通过短时间内快速学习的方式掌握。
编程中对人最有用的一个基础概念就是Problem solving,在《Think Python》的第一章中,就直接下了一个定义:
Problem solving means the ability to formulate problems, think creatively about solutions, and express a solution clearly and accurately。
这句话看上去似乎无关痛痒,每个人都能理解,你就问了,这到底怎么用呢?
举编程中的一个练习题来说明。放心,理解这个例子无需任何编程基础,我只是用它来说明一种解决问题的思路,不会用任何术语。
上图是三朵菊花。这题是,让你设计一个函数,函数中有一个自变量n代表花瓣个数,你可以随便给n取一个数,这个函数就可以执行出一朵菊花来。
你就说,我勒个去,TM没有编程基础怎么解这道题?
岂止是你,我学完函数这一章,做这道题时尼玛我也懵逼了,我就知道怎么用一些简单的函数画直线,再让他拐一个弯儿,现在就让我直接搞一朵菊花?
后来我还是顺利解出了这道题,画出来的菊花和题图一模一样。现在说一下解题思路。
我回过头重新去理解编程中对于Problem solving的定义——
1、formulate problems
2、think about solutions
3、express a solution
首先得提出一个正确的问题,如果我的问题是如何画一朵菊花,现学的函数都不能直接画菊花,所以我这个问题就提错了。
先看看这朵菊花由哪些要素组成。
直观来看,花瓣是菊花的基本要素。意思是,只要我先画出一朵花瓣,再让它围绕圆心旋转几次,就有菊花了。那么,问题就从如何花一朵菊花变成了如何花一朵花瓣。
再看花瓣是由什么要素组成的。花瓣似乎就是两段弧边拼在一起的是吧。于是,问题从如何花一朵花瓣变成了如何画一段弧。
一段弧是怎么来的?一段弧是一个圆的一部分啊,如果我能画一个圆,那么截取一段出来不就是一段弧了么?于是,问题从如何画一段弧变成了如何画一个圆。
我刚说了,我会画直线。即便你没学编程,我相信你也能猜测到,写一个画直线的函数肯定很简单。
画了一条直线后,再拐一个弯儿,这也不难做到。
现在的问题是如何画圆,目前我会的解决方案是画直线,还能让它拐弯。于是,我还得想办法,把画圆这个问题,跟我目前掌握的解决方案衔接起来。
既然我能画直线,并让它按一定角度拐弯,那么一根直线拐弯四次不就是一个正方形吗?
诶!那如果,我让拐弯的角度变化,是不是就可以画一个五边形?六边形不是可以了吗?
于是,我便可以随意画出多边形,哈,圆不就是一个边足够多的多边形吗?于是我把边数加到足够多。
Bingo!既然圆能画,顺着刚才的思路往上推,很快就能得到一个菊花函数,问题就解决了。我用这函数画了一朵黑黑的菊花:
这个案例非常鲜明地展现了编程解决难题的思路,我总结如下:
1、分解问题对象的构成要素
2、不断分解
3、分解至现有解决方案能直接使用的层次
4、逆推回去
在使用这种解决思路前,都持有一个信念前提:
坚信一切事物都可再分。
其实这是中还原论的思想,和马斯克所推崇的第一性原理非常接近:
「第一性原理」的思考方式是用物理学的角度看待世界的方法,也就是说一层层剥开事物的表象,看到里面的本质,然后再从本质一层层往上走。
这种解决问题的思路可以迁移应用到生活的方方面面。例如如何赚到人生第一个1000万,这种问题确实有点难,但是仍可再分,比如人生的第一个500万,100万,50万,20万…直到你目前可达到的水平,然后构建一个简单的函数去解决它。
每一个逻辑层次问题解决后,它就被封装成一个组块,用于解决下一个问题。
这时,你无需在考虑这个组块内部是如何构成的。例如画菊花这道题,当我要画弧边时,我就完全不管圆是怎么画的了,直接拿圆的函数来用。
其实,人类的知识也是如此发展的,很多解决方案被封装成一个又一个组块,很多时候,你直接调用它即可,未必需要理解其原理。
很多朋友都说,学完认知学习法后,感觉收获非常大,但不知道该用在哪。我的建议很简单,找一个自己从没接过的技能或领域,动手学!对于我来说,技术领域是完全没有接触过的,所以我就从编程开始,将认知学习法的思想和方法使用起来,本文就是学习法中提到的读取-编码方法的使用案例。
为了快速熟悉开发环境,我给自己定了一个小任务,用Github+Hexo+NexT搭了一个博客,Pisces主题。顺便把之前写的文章放上去了,有分类和搜索功能,有兴趣的朋友欢迎围观(复制到浏览器打开):qiangulc.com