- 原文地址:How to think like a programmer — lessons in problem solving
- 原文作者:Richard Reis
- 譯文出自:掘金翻譯計劃
- 本文永久連結:github.com/xitu/gold-m…
- 譯者:mingxing47
- 校對者:rockyzhengwu Park-ma
原文作者 Richard Reis
如果你對程式設計感興趣,那麼你之前可能會聽說過這樣的 一句話
:
“每個人都應該學習程式設計,因為它會教你如何思考。” —— 史蒂夫·賈伯斯
你可能還想知道,像程式設計師一樣思考到底意味著什麼?同時,要怎麼樣才能做到呢?
從本質上講,像程式設計師般思考是一種更加有效的解決問題的方法。
通過這篇文章,我的目的是教會你用那樣的方式去思考問題。
到最後,你就會更加清楚地知道,要通過哪些步驟才能成為一個更好的難題終結者。
這件事為什麼很重要?
解決問題是最根本的元技能。
我們所有人都會遇到或大或小的各種各樣的難題。而很多時候,我們如何去解決這些問題卻顯得,可以說...很隨機。
除非你有一套解決問題的體系,否則如下很可能就是你“解決”問題的方法(這也正是我程式設計之初常常走的歧途):
- 嘗試某種解決方案。
- 如果這種解決方案不湊效,那麼換另外一個進行嘗試。
- 如果另一種還是不湊效,那麼不斷重複步驟 2,直到走大運恰好碰到解決這個問題的方法。
你看,某些時候可能你很走運,能夠把問題解決。但這卻是解決問題中最最糟糕的方法。同時,這對你的時間造成了巨大浪費。
最好的方法包含了以下的兩個方面:a)擁有一套解決問題的框架;b)不斷練習實踐這套框架。
“幾乎所有的僱主都把解決問題的能力放在首位。
解決問題的能力幾乎是所有僱主一致追尋的最重要的品質,甚至比精通程式語言、除錯和系統設計更為重要。
證明計算思維或者說分解大型複雜問題的能力,對於一份工作來說,至少與其所需的基本技術技能一樣有價值(就算不是更有價值的話)。” —— Hacker Rank (2018 年開發者技能報告)
擁有一套解決問題的框架
為了找到正確的框架,我遵循了蒂姆·費里斯(Tim Ferriss)關於學習的書《4 小時廚師》(the 4-Hour Che) 中的建議。
這個建議讓我採訪了兩位真正令人印象深刻的人:C. Jordan Ball(在 Coderbyte 65,000+ 使用者中排名第一或者第二),以及 V. Anton Spraul(書籍 “像程式設計師般思考:創造性解決難題導論” 的作者)。
我問了他們相同的問題,你猜猜結果如何?他們的答案基本是一致的!
很快,你也會認識到這些答案。
作者注:這並不意味著他們用相同的方法去做每一件事。每個人都是不同的,你和他們也是不同的。但如果你遵循了我們都認同的好的原則,以此開始,你會走得更遠更快。
“我看到的新手程式設計師犯的最大的錯誤就是專注於學習程式語言語法而不是去學習如何解決問題。” —— V. Anton Spraul
那麼,遇到新問題時該怎麼做呢?
下面就是解決問題的一些步驟:
1. 理解問題
準確地理解問題所問的點是什麼。絕大多數的難題,僅難在你不能理解這些問題(這就是為什麼要把理解問題放在第一步的原因)。
如何知道你已經理解了一個問題?當你能用語言描述它的時候就真的理解了。
你記憶中是否有這樣一個場景,當你被困在一個問題中時,你開始解釋它,然後突然之間,你發現了之前從來沒有考慮過的邏輯漏洞?
絕大多數的程式設計師都應該對這種感覺深有體會。
這就是為什麼你要把你的問題寫下來、畫個圖或者告訴他人的原因(另外一件事是...有些程式設計師會使用小黃鴨除錯法來解決問題)。
“如果你無法簡單地解釋清楚某件事,你就還沒有弄懂它。” —— Richard Feynman
2. 做出計劃
在沒有計劃之前千萬不要一頭扎入問題的解決當中(除非你希望能夠矇混過關)。一定要做好計劃!
如果你無法寫下做事情的確切步驟,那麼什麼都幫不了你。
在程式設計中,這意味著不要一開始就強行暴力破解。一定要先給你大腦一些時間來分析問題和處理資訊。
為了獲得一個好的解決問題計劃,先回答一下如下問題:
“在已有輸入 X 的前提下,如果要得到返回值 Y,將要進行哪些必要的步驟?”
作者注:程式設計師們有一種很棒的工具來解決這個問題...那就是註釋!
3. 劃分問題單元
注意了,這是所有步驟中最最重要的。
不要嘗試去解決一個大的問題。這樣做你肯定會哭的。
相反,應該把大問題分解成多個更容易解決的的子問題。
然後,對這些子問題各個擊破。從最簡單的問題開始吧。最簡單的問題意味著你知道問題的答案(或者至少更為靠近答案)。
除此之外,最簡單的問題還意味著這個子問題的解決並不依賴於其他問題的解決。
一旦你把每一個子問題都解決了,然後就把每一個小點連線起來。
串聯起你的每一個**“子方案”**將會讓你獲得最終的原始問題的解決方案。祝賀你,你已經解決了問題!
這種解決問題的技術是所有問題解決的基石。牢牢記住它(如果有必要,請再次閱讀這一步)。
“如果我能教給每個新手程式設計師一個解決問題的技巧,那就是‘減少問題的技術’。
例如,如果你是一個新程式設計師,然後你被要求去寫一個程式,讀取 10 個數字,然後算出哪個數字是第三大的。對於一個全新的程式設計師來說,這可能是一項艱鉅的任務,儘管它只需要基本的程式設計語法。
如果你陷入困境,你應該把問題簡化。先不考慮找第三大的數,如果你去找最大的數你該如何做?還是太困難?那如果要從三個數字中找到最大的你該怎麼做呢?如果從兩個數字中尋找呢?
不斷簡化問題直到你能寫出解決方案。然後稍微把問題進行擴充套件,並寫下相應的解決方法,不斷擴充套件下去直到源問題被解決。” —— V. Anton Spraul
4. 陷入問題當中?
現在,你可能正坐在那裡想到:“嘿,Richard... 這方法很酷,但是如果我卡住了,然後連子問題都無法解決該怎麼辦?”
首先呢,進行一下深呼吸。其次,這件事是公平的。
不要擔心,朋友。這種情況會在每個人身上發生!
不同的是最好的程式設計師/問題解決者對 bugs 或錯誤更感興趣而不是惱怒。
事實上,當不幸面臨難題時,這裡有三件事可以嘗試:
- 除錯: 一步一步檢查你的解決方案,然後去試圖尋找到底那裡出錯了。程式設計師們把這件事稱為除錯(事實上,這事全是偵錯程式做的)。
“除錯的藝術在於找出你真正告訴你的程式去做的事情,而不是你所認為你已經告訴了你的程式去做的事情。” —— Andrew Singer
- 重新考慮: 後退一步。從另外一個角度來看待這個問題。是否有可以抽象成更一般的方法?
“有時候我們迷失在問題的細節裡,而忽略了能在更一般層面上解決問題的通用方法。 […]
當然,最經典的例子是求連續自然數和, 1 + 2 + 3 + … + n,非常年輕的高斯很快認識到答案是簡單的 n(n+1)/2,這樣就不用去做加法了。” —— C. Jordan Ball
作者注:另外一種重新評估的方式是重新開始。刪除所有內容,用全新的眼光重新開始。我是認真的,你會驚訝於這是多麼的有效。
- 搜尋:啊哈,你沒有讀錯,好好去搜尋一下。無論你遇到什麼樣的問題,很可能已經有人解決過了。去找到那個人或者找到那種解決方法。事實上,即使你解決了問題,你也可以再去調查一下!(你可以從其他人的解決方案中學到很多的東西。)
注意:不要去尋找解決一個大問題的方法。只去尋找解決子問題的方案。這是為什麼呢?因為除非你努力(哪怕是一點點),否則你什麼都學不到。如果你什麼都沒有學到,你就是在浪費時間。
不斷實踐練習這套框架
不要期望僅僅一個星期之後就能變得很棒。如果你想成為一個好的問題解決者,那就多去解決一些問題吧!
練習、練習、再練習。遲早你會意識到“這個問題可以通過 <在這裡插入概念> 輕鬆解決”。
如何去練習呢?這裡有很多的選擇!
象棋謎題、數學難題、數獨、圍棋、大富翁、電子遊戲、加密貓,等等等等。
事實上,成功人士的一個普遍模式是他們有著不斷練習“微觀解決問題”的習慣。例如,彼得·泰爾 (Peter Thiel) 通過下棋,埃隆·馬斯克 (Elon Musk) 通過玩電子遊戲來進行練習一樣。
“拜倫•裡夫斯 (Byron Reeves) 說,‘如果你想知道未來三到五年的企業領導是什麼樣的,那就看看網路遊戲正在發生什麼吧。’”
快進到今天。埃隆·馬斯克(Elon Musk)、雷德·霍夫曼(Reid Hoffman)、馬克·祖克伯(Mark Zuckerberg)和其他許多人都表示,遊戲是他們成功建立公司的基石。” —— Mary Meeker(2017年網際網路趨勢報告)
這是否意味著你應該只玩電子遊戲?並不是這樣。
但是電子遊戲到底是關於什麼的呢?沒錯,就是問題解決!
所以,你應該做的是找到能夠練習的機會。可以是能讓你解決很多小問題的東西(理想情況下,這應該是你喜歡的東西)。
例如,我喜歡程式設計挑戰。每天,我都試圖解決至少一個挑戰(通常在 Coderbyte 上)。
正如我所說,所有的問題都有相似的模式。
結論
以上就是全部內容!
直至目前,你已經更好地瞭解了“像程式設計師般思考”究竟意味著什麼。
你也知道了解決問題是一種難以置信的技能(元技能)。
如果這還不夠,請注意,你還知道了要練習解決問題的技巧該做些什麼!
嘖嘖嘖... 聽起來很酷,對吧?
最後,祝你遇到很多問題。
你沒有讀錯,就是祝你遇到更多的問題。因為至少現在你知道怎麼去解決問題了!(同時,你將會知道,每解決一個問題都會使你獲得進步)。
“就在你認為你已經成功跨越了一個藩籬時,你與另外一個障礙不期而遇。但這就是生活的奇妙之處。[...]
生活就是一個不斷突破桎梏的過程 —— 這是一些我們成長必須突破的阻礙。
每次,你都會獲取新知。
每次,你都會變得更加強壯有力,睿智深邃和洞察非凡。
每次,都會有一些挑戰被你逾越,從而消失。直到最後所留下的:是那個最好的你。” —— Ryan Holiday (絕境逢生的藝術 (The Obstacle is the Way))
從現在開始,去解決一些問題吧!
祝你好運 ?
特別鳴謝 C. Jordan Ball 和 V. Anton Spraul,他們給了我很多寶貴的建議。
此外,如果沒有 Lambda School 學校,我無法在如此短暫的時間內獲得所有的程式設計知識。在這裡我要非常感謝以及強烈推薦他們。
感謝您的閱讀! ? 如果您喜歡這篇文章,請您猛烈地把右手拍向左手,試一試您在 5 秒鐘之內能夠拍 ? 多少次吧。這是對您有益的手指有氧健身操,當然這也會幫助其他人看到這個故事。
在 Twitter 上向我 “打個招呼” 吧!
如果發現譯文存在錯誤或其他需要改進的地方,歡迎到 掘金翻譯計劃 對譯文進行修改並 PR,也可獲得相應獎勵積分。文章開頭的 本文永久連結 即為本文在 GitHub 上的 MarkDown 連結。
掘金翻譯計劃 是一個翻譯優質網際網路技術文章的社群,文章來源為 掘金 上的英文分享文章。內容覆蓋 Android、iOS、前端、後端、區塊鏈、產品、設計、人工智慧等領域,想要檢視更多優質譯文請持續關注 掘金翻譯計劃、官方微博、知乎專欄。