49

谷歌程序员有哪些高效的编程习惯?

 5 years ago
source link: http://zhuanlan.51cto.com/art/201904/595106.htm?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

NvmE32a.jpg!web

大数据文摘出品

来源: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。

写伪代码

伪代码并不是真实的代码,但是它和代码结构相仿。下述是我上文算法的伪代码:

for each index in sourceString, 
    there are N characters in searchString 
    let N chars from index onward be called POSSIBLE_MATCH 
    if POSSIBLE_MATCH is equal to searchString, return index 
at the end, if we haven't found a match yet, return -1. 

这样写就更像真实代码了:

for each index in sourceString, 
    N = searchString.length 
    POSSIBLE_MATCH = sourceString[index to index+N] 
     if POSSIBLE_MATCH === searchString: 
        return index 
return -1 

伪代码和真实代码的相似度取决于你,通过长期实践你会找到最适合你的一种形式

转化为代码

提示:如果问题比较简单,你也可以一并完成上述步骤

这下我们需要开始考虑语法、函数参数及语言规范了。你或许不能一下就把代码写的很全面,没关系,先写下你会的。

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; 
} 

你会发现上述代码中我留空了一部分。我是故意的,因为我不确定在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" 

这时,我就能确定这个函数的执行效果了。所以,当我将它插入到我的程序中后,我也能知道程序的故障是否由它导致的。

测试完成后,我就能将这最后一部分代码添加到我的程序里了。

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; 
} 

总结

最后,我想说的是,带着我的方法回去试试之前让你奔溃的编程问题,我保证会立竿见影的。

祝你好运,编码愉快!

相关报道:

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

【本文是51CTO专栏机构大数据文摘的原创文章,微信公众号“大数据文摘( id: BigDataDigest)”】

Znaa2ir.jpg!web

戳这里,看该作者更多好文


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK