【译】Googler如何解决编程问题
本文是Google工程師Steve Merritt的一篇博客,向大家介紹他自己和身邊的同事解決編程問題的方法。
原文地址:blog.usejournal.com/how-a-googl…
在本文中,我將完整的向你介紹一種解決編程問題的策略,這個(gè)策略是我在日常工作中一直使用的,并且用它來幫助各個(gè)等級的程序員(包括新手、大學(xué)生和實(shí)習(xí)生)學(xué)習(xí)和成長。應(yīng)用這個(gè)結(jié)構(gòu)化流程可以最大幅度的減少那令人沮喪的調(diào)試時(shí)間,并且能夠在盡可能短的時(shí)間內(nèi)編寫出更加整潔、錯(cuò)誤率更低的代碼。
一步步
接下來我將用一個(gè)栗子來說明。
問題:有兩個(gè)字符串sourceString和searchString,返回searchString在sourceString中第一次出現(xiàn)的位置,如果searchString不是sourceString的字串,就返回-1。
第一步:畫下來
當(dāng)你拿到一個(gè)需求,馬上就開始著手寫代碼是一個(gè)非常愚蠢的主意。在寫一篇文章之前,首先要弄清楚論證和論據(jù),并且你要保證論證是有意義的。如果你沒有這么做的話,當(dāng)你意識到你所寫的東西前言不搭后語時(shí),你可能會因?yàn)槔速M(fèi)了大把的時(shí)間而想請自己吃一頓大嘴巴子。編程也是一樣的道理,甚至比這還嚴(yán)重,嚴(yán)重到像洗澡的時(shí)候把洗發(fā)水弄進(jìn)眼睛里。
問題的解決方法通常很重要,即使它看上去很簡單。在寫代碼之前,首先要做的就是把這個(gè)方法在紙面上呈現(xiàn)出來,并且保證在不同的情況下適用。
所以不找急著寫代碼,甚至都不要思考如何寫。后面你會有充足的時(shí)間去敲代碼,在這之前,你要把自己當(dāng)成一臺計(jì)算機(jī),弄清楚你這臺計(jì)算機(jī)會怎么解決這個(gè)問題。
你可以使用流程圖,或者使用其他能幫你具象化的方法,總之我們的目標(biāo)是解決問題。你可以用紙和筆隨意發(fā)揮,不需要收到鍵盤的限制。
我們從一些簡單的情況開始,如果一個(gè)方法是“輸入一個(gè)字符串”,那么“abc”可以作為第一個(gè)例子。首先要搞清楚正確的結(jié)果是什么,然后去想怎么樣得到正確的結(jié)果,并且一步一步的進(jìn)行。
我們假設(shè)輸入的字符串是這樣:
sourceString: "abcdyesefgh" searchString: "yes" 復(fù)制代碼我的想法是這樣的:
我看到了searchString在sourceString里,但是我要怎么做呢?我從sourceString的第一個(gè)字符開始,逐字去讀,一直到最后,判斷每一個(gè)三個(gè)字符是不是yes。比如abc,bcd,cdy等等。當(dāng)index值為4時(shí),我找到了字符串yes,所以我知道結(jié)果是index為4。
當(dāng)我們寫下算法時(shí),必須要保證我們考慮了所有的情況,并且處理了所有可能的場景。當(dāng)我們找到匹配的字符串時(shí),返回結(jié)果。如果找不到匹配的字符串,同樣要返回結(jié)果。
我們來嘗試另一組字符串:
sourceString: "abcdyefg" searchString: "yes" 復(fù)制代碼我們重復(fù)剛才的操作,當(dāng)我們讀到下標(biāo)為4的字符時(shí),找到的字符串是yef,這是最接近的結(jié)果了,但是第三個(gè)字符卻不同,所以我們繼續(xù)往后讀,一直到最后,沒有找到匹配的字符串,所以我們決定返回-1。
我們確定這一系列步驟(程序設(shè)計(jì)中,我們稱之為算法)解決了我們的問題,并且處理了兩種不同的場景,每次都得到了正確的結(jié)果。這時(shí),我們就對我們的算法比較有信心了,并且可以將它形成條目。我們一起來進(jìn)行下一步:
第二步:用英語寫下來
這里我們考慮將第一步形成的算法用英語寫下來。這可以使每一步變得更加具體,以便我們后面寫代碼的時(shí)候有所參考。
看起來很棒,不是嗎
第三步:寫偽代碼
偽代碼并不是真正的代碼,只是一種模擬形式,這里我寫下上面的算法的偽代碼:
for each index in sourceString,there are N characters in searchStringlet N chars from index onward be called POSSIBLE_MATCHif POSSIBLE_MATCH is equal to searchString, return index at the end, if we haven't found a match yet, return -1. 復(fù)制代碼我也可以用一種更接近代碼的形式來寫:
for each index in sourceString,N = searchString.lengthPOSSIBLE_MATCH = sourceString[index to index+N]if POSSIBLE_MATCH === searchString:return index return -1 復(fù)制代碼你的偽代碼寫得有多像真正的代碼,你就會發(fā)現(xiàn)它有多么好用。
第四步:翻譯可以編碼的內(nèi)容
注意:對于簡單的問題,這一步可以和上一步合并
到這時(shí)我們才第一次需要考慮語法、方法參數(shù)和語言規(guī)則的問題。可能你不是全部代碼都會寫,但是沒關(guān)系,先把會寫的寫出來。
function findFirstMatch(searchString, sourceString) {let length = searchString.length;for (let index = 0; index < sourceString.length; index++) {let possibleMatch = <the LENGTH chars starting at index i>if (possibleMatch === searchString) {return index;}}return -1; } 復(fù)制代碼注意我留了一部分沒有寫,這是故意的!我不確定JavaScript切分字符串的語法要怎么寫,所以我會在下一步查找它。
第五步:不要猜測
我發(fā)現(xiàn)所有新手程序員都會犯一個(gè)共同的錯(cuò)誤,就是從網(wǎng)上找到一個(gè)方法,覺得“可能有用”,然后不經(jīng)過測試就寫進(jìn)代碼里。你不理解的代碼越多,就越不可能找到正確的方法。
你的程序的錯(cuò)誤可能是你不了解代碼的兩倍還多。有一處不理解,如果程序出錯(cuò),那么罪魁禍?zhǔn)字挥幸惶帯H绻阌袃商幉焕斫?#xff0c;那就有三種可能出錯(cuò)(A出錯(cuò),B出錯(cuò),或者A和B都出錯(cuò))。如果有三處不理解,就會有七種情況……很快它就失控了。
邊注:程序出錯(cuò)的情況種類遵循Mersenne公式 a(n) = (2^n)?—?1
首先要測試你的新代碼。從互聯(lián)網(wǎng)上找答案是好的,但是在寫進(jìn)你的代碼之前,你要先對它進(jìn)行單獨(dú)的測試,確保它能按照你想要的方式執(zhí)行。
在上一步中,我不確定JavaScript怎么切分字符串,所以我選擇面向Google編程
www.google.com/search?q=ho…
第一條結(jié)果來自w3schools,有點(diǎn)小過時(shí),但比較可靠
www.w3schools.com/jsref/jsref…
基于此,我覺得我應(yīng)該使用substr(index, searchString.length)來提取sourceString ,但這只是個(gè)假設(shè),所以我要先來測試一下:
>> let testStr = "abcdefghi" >> let subStr = testStr.substr(3, 4); // simple, easy usage >> console.log(subStr); "defg" >> subStr = testStr.substr(8, 5); // ask for more chars than exist "i" 復(fù)制代碼現(xiàn)在我確定這個(gè)函數(shù)是可以用的,如果程序出錯(cuò),就不是這個(gè)函數(shù)不可用導(dǎo)致的。最后我補(bǔ)充上最后的代碼。
function findFirstMatch(searchString, sourceString) {let length = searchString.length;for (let index = 0; index < sourceString.length; index++) {let possibleMatch = (sourceString.substr(index, length));if (possibleMatch === searchString) {return index;}}return -1; } 復(fù)制代碼結(jié)論
如果你讀到這里,我要說的只有:”干就完了!“
再嘗試處理一下上周遇到的困難,用上我教你的方法,我保證你很快就會有提高。
祝你好運(yùn),編碼愉快!
譯者注:個(gè)人認(rèn)為作者還是強(qiáng)調(diào)要先想清楚,再動手寫代碼。而且要學(xué)會面向Google編程
轉(zhuǎn)載于:https://juejin.im/post/5cae1f19e51d456e747c5300
總結(jié)
以上是生活随笔為你收集整理的【译】Googler如何解决编程问题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一次性搞懂JavaScript正则表达式
- 下一篇: CSharpGL(49)试水OpenGL