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

点击上方 "程序员小乐" ,关注公众号

8点20分,第一时间与你相约

每日英文

Promise yourself to be so strong that nothing can disturb your peace of mind.

对自己承诺:我要强大到任何事情都无法破坏我内心的平和。


每日掏心话

你不会发现到自己有多强大,直到有一天你发现你身边的支点都倒下了,你也没有倒下。


来源:medium | 大数据文摘 | 责编:乐乐

640?wx_fmt=jpeg

图片来自网络



   正文   



Google 招聘程序员的难度众所周知,不仅要求程序员码力超强,还要求有良好的编程习惯。那么他们在写代码的过程中,有哪些非常可贵值得我们借鉴的套路呢。


本文作者是谷歌的软件工程师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 endif 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(34);  // simple, easy usage 
>> console.log(subStr); 
"defg" 
>> subStr = testStr.substr(85);   // 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; 


总结


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

祝你好运,编码愉快!

欢迎在留言区留下你的观点,一起讨论提高。如果今天的文章让你有新的启发,学习能力的提升上有新的认识,欢迎转发分享给更多人。


欢迎各位读者加入程序员小乐技术群,在公众号后台回复“加群”或者“学习”即可。

640?wx_fmt=png


猜你还想看


阿里、腾讯、百度、华为、京东最新面试题汇集

当我们遇到100亿次请求?该如何设计后端架构?

高中就开始学的正态分布,原来如此重要

一个合格的技术面试官是怎么样的?

百度地震了,也许早晚的事

看完感觉我 RecyclerView 白学了!

640?wx_fmt=png

关注「程序员小乐」,收看更多精彩内容
第1章 敏捷——高效软件开发之道 第2章 态度决定一切 1. 做事 2. 欲速则不达 3. 对事不对人 4. 排除万难,奋勇前进 第3章 学无止境 5. 跟踪变化 6. 对团队投资 7. 懂得丢弃 8. 打破砂锅问到底 9. 把握开发节奏 第4章 交付用户想要的软件 10. 让客户做决定 11. 让设计指导而不是操纵开发 12. 合理地使用技术 13. 保持可以发布 14. 提早集成,频繁集成 15. 提早实现自动化部署 16. 使用演示获得频繁反馈 17. 使用短迭代,增量发布 18. 固定的价格就意味着背叛承诺 第5章 敏捷反馈 19. 守护天使 20. 先用它再实现它 21. 不同环境,就有不同问题 22. 自动验收测试 23. 度量真实的进度 24. 倾听用户的声音 第6章 敏捷编码 25. 代码要清晰地表达意图 26. 用代码沟通 27. 动态评估取舍 28. 增量式编程 29. 保持简单 30. 编写内聚的代码 31. 告知,不要询问 32. 根据契约进行替换 第7章 敏捷调试 33. 记录问题解决日志 34. 警告就是错误 35. 对问题各个击破 36. 报告所有的异常 37. 提供有用的错误信息 第8章 敏捷协作 38. 定期安排会面时间 39. 架构师必须写代码 40. 实行代码集体所有制 41. 成为指导者 42. 允许大家自己想办法 43. 准备好后再共享代码 44. 做代码复查 45. 及时通报进展与问题 第9章 尾声:走向敏捷 9.1 只要一个新的习惯 9.2 拯救濒临失败的项目 9.3 引入敏捷:管理者指南 9.4 引入敏捷:程序员指南 9.5 结束了吗 附录A 资源 索引
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值