像机器一样思考:所有的问题都从输入和输出的角度去思考。
Analytical Thinking
那么针对一个问题到底怎么做呢?
思考过程:
- 分解问题
- 找到子问题之间的关联(通过输入输出关联起来)
- 找到问题的边界,明确假设与结果
看一个例子:写一个函数,可以选出一个由数字组成的集合当中所有的偶数的最大值。
我们可以成两步:
- 选出集合中的偶数
- 选出偶数中的最大值
#1 选出集合中的偶数
输入:
inputArray: [Number]
输出:
evenArray: [Number]
#2 选出偶数中的最大值
输入:
evenArray
输出:
max: Number
在表达输入输出的同时,我们最好将其对应的数据类型加上,这有利于我们思考怎么处理这些数据。
穷尽
当我们开始解决一些稍微复杂点的问题的时候,我们会发现差不多的态度是不行的,我们需要严谨的态度进行缜密的思考才能真正发挥出这个思考模型的力量。
所谓的完全穷尽,说的是我们需要穷尽这个代码块或函数里所有的输入和输出。不能遗漏任何一个输入,任何一个输出。我们的每一项,它的属性,也不能有遗漏,而不能只考虑部分属性。
既然要穷尽输入输出,我们首先要了解输入输出几个大类。
输入总共有下面几大类:
1.参数
2.读取全局变量
3.调用全局函数后得到的返回值
4.读取局部作用域变量(比如this)
5.调用局部函数后得到的返回值
6.hard code的数据
输出总共有下面几大类:
1.返回值
2.修改全局变量
3.调用全局函数时传的参数
4.修改局部作用域变量(比如this)
5.调用局部函数时传的参数
同时我们还要思考清楚数据从哪来,又要到哪去。
tasking图
当我们把一个完整的功能拆解为一个个输入输出穷尽,互相独立的任务后,它是容易转化为代码了,可是这种方式并不容易思考规模更大的问题(光从哪来到哪去就够我们绕的)。所以我们需要一种对传输友好的编码方式,这种方式就是画图。
画图的规则
我们的画图方法受时序图启发而发明,具体的规则如下:
- 本图基本元素由方块和带箭头的线组成
- 一个方块只代表一个函数或一个代码块,通常是函数,方块中可以写字,可以表达函数是属于哪个类或哪个实例等信息。
- 指向方块的线代表该函数的输入,背离方块的线代表函数的输出。
- 数据流动的时间轴遵守先从左到右,再从上到下的顺序。
- 每一对输入输出(输入在上,输出在下)加一个方块,表达了一次函数调用。
举例:
比如下列代码:
function c(){
}
function b(){
c();
}
function a(){
b();
}
a();
画成图是这个样子的