大數據文摘出品

  來源:medium

  編譯:高延、蔣寶尚

  谷歌招聘程序員的難度衆所周知,不僅要求程序員碼力超強,還要求有良好的編程習慣。

  那麼他們在寫代碼的過程中,有哪些非常可貴值得我們借鑑的套路呢。

  本文作者是谷歌的軟件工程師Steve Merritt,下面他將介紹其在谷歌的日常工作及與各種level的程序員(培訓生、大學生、實習生)的合作中都會用到的一些小技巧。

  舉個例子來說明這個流程。

  假設有個問題:給定兩個字符串sourceString和searchString,如果sourceString中含有searchString,就返回第一個字符在sourceString中的索引。如果sourceString中沒有searchString,就返回-1。

  先畫個圖

  坦率地說,立刻就去敲代碼是種荒謬且懶惰的想法。就好比在你寫一篇文章之前,要先弄清楚你的假設及論據,從而保證文章的內容有意義。不這麼做的話,你可能會漸漸意識到你所寫內容可能會跑題,不僅浪費時間,還影響心情。寫代碼也一樣,那時你可能像眼睛裏進了洗髮水一樣難受。

  通常,解決問題的方法乍一看很簡單,但其實不然。先在紙上寫寫有助於你找到解決問題的方法,並能證實該方法可用於不同情境,這些都得在敲代碼之前完成。

  所以不要急於敲代碼,甚至想都不要想代碼。隨後你是有足夠的時間來做加分號、逗號這些事的。

  畫個圖吧,畫上箭頭,或在框裏寫上數字,反正,用盡一些可以幫你描述問題的方法。我們的目標是解決問題,所以不要侷限於鍵盤,請盡情使用你的紙筆。

  先設計一些簡單輸入。如果函數要處理的是一個字符串,那abc就是個很好的例子。試想一下正確的結果是什麼,然後梳理一下你是如何解決這個問題的,以及用到了哪些步驟。

  假設字符串的值如下:

  sourceString:"abcdyesefgh"

  searchString:"yes"

  我的思路:我能看出searchString 包含於sourceString中。但我是如何做到的呢?對sourceString從左讀到最右,每3個字符一組和‘yes’進行比對看是否匹配。

  如‘abc’‘bcd’‘cde’等。當讀到索引爲4的字符時,發現了‘yes’,這樣我就確定存在這麼一個匹配,且始於索引爲4的字符

  當我們在寫算法時,我們需要確保我們能表達出所有內容並能應對所有可能的場景。在找到匹配的時候理應返回正確的答案,在沒找到匹配的時候也要放回正確的答案。

  試想一下另一對字符串的情景:

  sourceString:"abcdyefg"

  searchString:"yes"

  我們把sourceString 這個單詞從左往右讀,每3個字符一組地比對是否和‘yes’匹配。讀到索引爲4的字符是,我們看到‘yef’,這看起來像是一樣的,但並不是,因爲第三個字符不同。所以,我們一直讀到最右邊,得出的結論是沒有匹配,所以返回-1。

  我們已經能確定解決該問題需要的一系列步驟(在編程領域,我們稱之爲算法),並且我們已經不同情境中進行都嘗試並都得到正確的結果。基於這點,我們就認爲該算法是有效的,接下來我們就該將它算法化。

  用文字寫出來

  認真思考上一步中確定的算法後,我們就可以試着用文字把它寫出來。

  這麼做能使得步驟變得很具體,以便我們在後續敲代碼的時候進行參考。

  從字符串的首位開始讀。

  查看由3個字符(或是searchString中的字符數)組成的子集。

  如果出現和searchString一致的,就返回其字母的索引號。

  如果我們讀到字符串末尾都沒有能匹配的,就返回-1。

  寫僞代碼

  僞代碼並不是真實的代碼,但是它和代碼結構相仿。下述是我上文算法的僞代碼:

  foreach index in sourceString,

  there are N characters in searchString

  let N chars from index onward be called POSSIBLE_MATCH

  ifPOSSIBLE_MATCH is equal to searchString,returnindex

  at the end,ifwe haven't found a match yet,return-1.

  這樣寫就更像真實代碼了:

  foreach index in sourceString,

  N = searchString.length

  POSSIBLE_MATCH = sourceString[index to index+N]

  ifPOSSIBLE_MATCH === searchString:

  returnindex

  return-1

  僞代碼和真實代碼的相似度取決於你,通過長期實踐你會找到最適合你的一種形式

  轉化爲代碼

  提示:如果問題比較簡單,你也可以一併完成上述步驟

  這下我們需要開始考慮語法、函數參數及語言規範了。你或許不能一下就把代碼寫的很全面,沒關係,先寫下你會的。

  functionfindFirstMatch(searchString, sourceString){

  let length = searchString.length;

  for(let index =; index

  let possibleMatch =

  if(possibleMatch === searchString) {

  returnindex;

  }

  }

  return-1;

  }

  你會發現上述代碼中我留空了一部分。我是故意的,因爲我不確定在JavaScript語言中給字符串切片的語法,所以我會在下一步中查詢該語法。

  不要猜

  我發現新手程序員常範這樣一個錯誤,就是在網上找到一些覺得可能有用語句,不經測試便將其加到程序中。你不理解的代碼段越多,就越不可能找到適合的解決方案。

  隨着你不確定的內容增加,你的程序出錯的方式會呈指數式增加。當你有1處不確定的時候,你程序確實只會因爲這1個原因而出錯。

  但是如果有2處不確定,出錯就有3種情況(A處出錯,B處出錯,或者AB都出錯)。如果有3處不確定,就有7種情況。到時你就很難找到出錯原因了。

  附註:程序出錯原因的個數如梅森序列:a(n) = (2^n)?—?1

  先測試一下你的新代碼。能在互聯網上找有用的內容是很好的,但是請在將其加到程序中之前,用一個獨立的環境進行測試,以確保它能以你認爲的方式運行。

  在上一步中,因爲不確定在JavaScript語言裏選取字符串某個部分的方式,所以就上網搜一下。

  參考如下鏈接:

  https://www.google.com/search?q=how+to+select+part+of+a+string+in+javascript

  第一個結果就是w3schools網站的,雖然內容有點老,但是通常是靠譜。

  w3schools:

  https://www.w3schools.com/jsref/jsref_substr.asp

  在這基礎上,假設我每次用這段代碼

  substr(index, searchString.length)

  來提取sourceString的一部分。我會先建個小例子來測試。

  >> 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"

  這時,我就能確定這個函數的執行效果了。所以,當我將它插入到我的程序中後,我也能知道程序的故障是否由它導致的。

  測試完成後,我就能將這最後一部分代碼添加到我的程序裏了。

  functionfindFirstMatch(searchString, sourceString){

  let length = searchString.length;

  for(let index =; index

  let possibleMatch = (

  sourceString.substr(index, length));

  if(possibleMatch === searchString) {

  returnindex;

  }

  }

  return-1;

  }

  總結

  最後,我想說的是,帶着我的方法回去試試之前讓你奔潰的編程問題,我保證會立竿見影的。

  祝你好運,編碼愉快!

  相關報道:

  https://blog.usejournal.com/how-a-googler-solves-coding-problems-ec5d59e73ec5?gi=af7ed9a9dff9

  志願者介紹

  點「在看」的人都變好看了哦

相關文章