像機(jī)器一樣思考:所有的問題都從輸入和輸出的角度去思考。
Analytical Thinking
那么針對一個問題到底怎么做呢?
思考過程:
- 分解問題
- 找到子問題之間的關(guān)聯(lián)(通過輸入輸出關(guān)聯(lián)起來)
- 找到問題的邊界,明確假設(shè)與結(jié)果
看一個例子:寫一個函數(shù),可以選出一個由數(shù)字組成的集合當(dāng)中所有的偶數(shù)的最大值。
我們可以成兩步:
- 選出集合中的偶數(shù)
- 選出偶數(shù)中的最大值
#1 選出集合中的偶數(shù)
輸入:
inputArray: [Number]
輸出:
evenArray: [Number]
#2 選出偶數(shù)中的最大值
輸入:
evenArray
輸出:
max: Number
在表達(dá)輸入輸出的同時,我們最好將其對應(yīng)的數(shù)據(jù)類型加上,這有利于我們思考怎么處理這些數(shù)據(jù)。
窮盡
當(dāng)我們開始解決一些稍微復(fù)雜點的問題的時候,我們會發(fā)現(xiàn)差不多的態(tài)度是不行的,我們需要嚴(yán)謹(jǐn)?shù)膽B(tài)度進(jìn)行縝密的思考才能真正發(fā)揮出這個思考模型的力量。
所謂的完全窮盡,說的是我們需要窮盡這個代碼塊或函數(shù)里所有的輸入和輸出。不能遺漏任何一個輸入,任何一個輸出。我們的每一項,它的屬性,也不能有遺漏,而不能只考慮部分屬性。
既然要窮盡輸入輸出,我們首先要了解輸入輸出幾個大類。
輸入總共有下面幾大類:
1.參數(shù)
2.讀取全局變量
3.調(diào)用全局函數(shù)后得到的返回值
4.讀取局部作用域變量(比如this)
5.調(diào)用局部函數(shù)后得到的返回值
6.hard code的數(shù)據(jù)
輸出總共有下面幾大類:
1.返回值
2.修改全局變量
3.調(diào)用全局函數(shù)時傳的參數(shù)
4.修改局部作用域變量(比如this)
5.調(diào)用局部函數(shù)時傳的參數(shù)
同時我們還要思考清楚數(shù)據(jù)從哪來,又要到哪去。
tasking圖
當(dāng)我們把一個完整的功能拆解為一個個輸入輸出窮盡,互相獨立的任務(wù)后,它是容易轉(zhuǎn)化為代碼了,可是這種方式并不容易思考規(guī)模更大的問題(光從哪來到哪去就夠我們繞的)。所以我們需要一種對傳輸友好的編碼方式,這種方式就是畫圖。
畫圖的規(guī)則
我們的畫圖方法受時序圖啟發(fā)而發(fā)明,具體的規(guī)則如下:
- 本圖基本元素由方塊和帶箭頭的線組成
- 一個方塊只代表一個函數(shù)或一個代碼塊,通常是函數(shù),方塊中可以寫字,可以表達(dá)函數(shù)是屬于哪個類或哪個實例等信息。
- 指向方塊的線代表該函數(shù)的輸入,背離方塊的線代表函數(shù)的輸出。
- 數(shù)據(jù)流動的時間軸遵守先從左到右,再從上到下的順序。
- 每一對輸入輸出(輸入在上,輸出在下)加一個方塊,表達(dá)了一次函數(shù)調(diào)用。
舉例:
比如下列代碼:
function c(){
}
function b(){
c();
}
function a(){
b();
}
a();
畫成圖是這個樣子的