首先,你必須做到能夠高效的解決問題。這是一個(gè)關(guān)鍵的起點(diǎn)因?yàn)榫幊叹褪菫榱私鉀Q問題的。

雖然覺得問題的方法可以有很多,但過程中有幾個(gè)部分讓我印象深刻。擁有出色的解決問題的能力的程序員會(huì)先將問題的本質(zhì)提煉出來,以便于確定總體目標(biāo)并帶著這個(gè)目標(biāo)著手解決問題。然后他們將每個(gè)問題分解成容易處理的小問題,依次處理每個(gè)小問題,有時(shí)還可以通過繪制導(dǎo)圖使其實(shí)現(xiàn)可視化。

這個(gè)過程做起來遠(yuǎn)比聽起來難得多。當(dāng)我開始學(xué)習(xí)編程的時(shí)候,我也會(huì)遇到瓶頸:和大多數(shù)人一樣,我從未在學(xué)校學(xué)會(huì)如何解決問題,這也不是一項(xiàng)容易傳授的技能,曾經(jīng),老師在數(shù)學(xué)課上布置了一組習(xí)題,我便一頭栽了進(jìn)去,正如我剛剛開始編程的時(shí)候。毋庸置疑,我這是在做無用功并且在最簡(jiǎn)單的問題就遇到了障礙。

當(dāng)我開始學(xué)習(xí)如何解決問題甚至是高效的解決問題,情況開始發(fā)生變化。我開始去關(guān)注一個(gè)問題的最終目的是什么,得益于喬治·波利亞的書《如何解決這個(gè)問題》。

我把波利亞的一些想法運(yùn)用到編程里,比如如何去理解問題。“這個(gè)問題必須被理解,”波利亞寫道。這包括能夠“指出問題的主要部分、未知、數(shù)據(jù)和條件。”對(duì)于每一個(gè)問題,我都拿出一張紙,然后寫下這些問題的答案:我在解決什么問題,或者我在試圖尋找什么?(未知);我現(xiàn)在有什么已知?(數(shù)據(jù));我需要注意哪些限制條件或細(xì)節(jié)?(條件)。

理解這個(gè)問題對(duì)我們來說似乎是顯而易見的,但顯而易見的問題很容易被忽視。我不止一次在一個(gè)問題上投入了數(shù)小時(shí)但是毫無收獲,過了一會(huì)才意識(shí)到這個(gè)問題,我錯(cuò)過了問題陳述中一個(gè)小而關(guān)鍵的細(xì)節(jié)。寫下問題的細(xì)節(jié)雖然會(huì)讓我的思維變慢,但是同時(shí)這幫助我準(zhǔn)確地思考我需要做什么,這就已經(jīng)成功的一半。

在此基礎(chǔ)上,我也會(huì)制定了計(jì)劃,這也是喬治·波利亞的另一個(gè)建議,畫家在正式作畫之前會(huì)先畫一幅草圖,建筑商用圖紙和藍(lán)圖來建造房屋,編程也一樣。與其急著去做,我還不如先想好我要做什么,然后制定一個(gè)計(jì)劃。 具體的實(shí)施方法有很多種。有時(shí)我用數(shù)字的順序列出我需要采取的步驟:第一件事做這個(gè),第二件事做那個(gè)。有時(shí)候我也可以把問題可視化,當(dāng)我學(xué)習(xí)for loops的時(shí)候,我拿出一把杏仁,在這堆杏仁中進(jìn)行物理循環(huán)。這個(gè)例子聽起來很幼稚,但它能很好的幫助我思考了這個(gè)問題。

我也會(huì)畫一些示意圖。對(duì)于遞歸問題,我會(huì)繪制圖表來說明每次遞歸調(diào)用時(shí)發(fā)生的情況,直到遞歸完成為止。我會(huì)想辦法如何去簡(jiǎn)化問題,使其更易于處理,并幫助我發(fā)現(xiàn)一個(gè)合適的解決方法。最重要的是,我是帶著目的性去進(jìn)入一個(gè)問題,并在解決問題的過程中始終保持著這種目的明確的感覺。

有時(shí)盡管制定了最好的計(jì)劃,問題仍然很難被解決,我還是有可能沒有思路。成為一個(gè)高效的問題解決者需要時(shí)間;我仍在努力的學(xué)習(xí)這個(gè)技能,這是絕對(duì)值得的。

當(dāng)我閱讀由一個(gè)優(yōu)秀程序員編寫的代碼時(shí),最直觀的感覺就是它很干凈,很容易理解。變量被很好的命名,函數(shù)簡(jiǎn)單明了,每一行代碼都有特定的用途。代碼的清晰性度反映了程序員的思考過程:我可以從頭到尾閱讀程序,并確切地知道發(fā)生了什么。這是很棒的解決問題的方法,也是我所追求的。

掌握計(jì)算機(jī)科學(xué)

程序員

學(xué)習(xí)計(jì)算機(jī)科學(xué)是編程基礎(chǔ)的第二部分。我最近開始學(xué)習(xí)計(jì)算機(jī)科學(xué),并且喜歡它,因?yàn)閷W(xué)會(huì)了這些就能站到比別人更高的地方去看問題。比如我開始從幕后的角度去了解使用內(nèi)置函數(shù)時(shí)會(huì)發(fā)生什么。我還學(xué)習(xí)了內(nèi)存和運(yùn)行時(shí)間等許多其他主題。簡(jiǎn)而言之,我正在學(xué)習(xí)計(jì)算機(jī)為什么要做它所做的事情。

明白“為什么”讓我對(duì)前后關(guān)系理解更深刻,幫助我成為一個(gè)見多識(shí)廣的程序員。因此我在編寫代碼時(shí)更加深思熟慮?,F(xiàn)在我對(duì)時(shí)間復(fù)雜度有了一些了解,舉個(gè)例子,我更傾向于使用二分查找,而不是遍歷列表中的每個(gè)元素。

這也豐富了我對(duì)于核心編程概念如何運(yùn)作的理解。打個(gè)比方,曾經(jīng)我在研究一個(gè)遞歸問題,但沒有得到我預(yù)期的結(jié)果。經(jīng)過仔細(xì)審視,我明白了原因:這與調(diào)用堆棧的執(zhí)行有關(guān),幾個(gè)月前的我并不知道這個(gè)。

學(xué)習(xí)計(jì)算機(jī)知識(shí)也幫助我去使用類。對(duì)于類,我苦苦掙扎了很長(zhǎng)一段時(shí)間,也不敢使用它。我知道如何編寫類,但不確定什么時(shí)候用,為什么用。當(dāng)我了解到當(dāng)我的計(jì)算機(jī)中創(chuàng)建實(shí)例和調(diào)用方法時(shí)實(shí)際發(fā)生的事情時(shí),情況就發(fā)生了變化。當(dāng)我有了一些相關(guān)知識(shí)之后,我就敢使用類了。對(duì)于遞歸和類,計(jì)算機(jī)科學(xué)填補(bǔ)了我知識(shí)上的空白。

所有這些基礎(chǔ)要素往往都被拋到一邊。進(jìn)步是緩慢的因?yàn)槿藗兺鶅A向于選擇有趣的工作當(dāng)他們有選擇的余地的時(shí)候。這太可惜了。而掌握基本要素的程序員似乎對(duì)編程充滿信心:他們清楚的知道他們的編程時(shí)的“如何”和“為什么”,這改進(jìn)了他們的工作并增強(qiáng)了他們?cè)谄渌说拿媲暗目尚哦取?/span>

另外,扎實(shí)的基礎(chǔ)知識(shí)使學(xué)習(xí)新的編程語言和技術(shù)沒那么困難。例如,花時(shí)間真正理解一種編程語言的核心概念像迭代、遞歸和抽象這樣的核心概念有助于學(xué)習(xí)另一種語言。簡(jiǎn)單地說,掌握了基本知識(shí),將會(huì)獲益匪淺,幾乎沒有什么損失。