编程经验总结

[TOC]

想要学好一门编程语言:看源码 / 看书 + 实战模仿

代码调试

不调试代码,不按 F10 或F11,水平永远也无法提上来,所以,要想学好一门编程语言,最好的办法就是多调试。

工欲善其事必先利其器

经验总结

学习技术,最重要的一点是打破自己心理上的障碍,走出对于新技术的恐惧,走出自己的舒适区。

  • 看书一定要快看,因为实践才是重点,实践的时候,想到书上讲了可以这么做,然后去查书,看如何实践。不实践,就等于没看书。核心在于快看书,后实践。

  • more thinking, less coding.

  • 多看书,stay hungry,stay foolish。多思考。看书还要思考!

  • 有理想,有追求!自由精神,独立思想。Don't Follow。 对完美的不懈追求。我们是为了改变世界,而不是单纯的学技术。

  • 基础乃治学之本,多学基础知识,不要把主要精力放在新技术上

  • 每天把学习到的知识,用思维导图的方式进行总结,可以有效的复习知识点,思维导图 有利于知识体系的构建

技术问题归根结底还是数学问题

  • 将一个实际问题抽象成数学问题的能力,然后用数学的做题思维来解决

  • 没有什么代码是读不懂的,只要头脑清晰,一段代码一段代码地看下去,总能看懂的

  • 没有什么开发问题(正常的开发问题)是解决不了的,因为其本质上还是一个数学的计算问题,都可以抽象成一个一个小步骤,慢慢解决

  • 在编程的世界中,最重要的便是抽象能力

如何学习技术

Google: 大量的英文资料

官网:第一手的资料

官网的 Tutorial:最佳入门资料

wiki:快速了解

知乎,百度:中文的资料

经典书籍:

遇到问题:去 Google 搜索英文资料,英文资料有更好的沉淀

代码规范 和 编程思想

DRY 原则

DRY

二八定律

80% 的时间用来思考,20% 的时间用来编码

写代码前 Git?

1. 是否需要建立仓库?建仓库
2. 是否需要切换分支?切换分支
3. 是否需要另起一个分支?新建分支
4. 是否有研发记录文档?

写完代码后

1. 写文档总结一下遇到的 bug,以后再遇到的话可以快速定位,DRY 原则
2. 是否需要测试?写一份测试文档

代码测试

代码测试是代码编辑的相当重要的环节。

  1. 每一个模块,每一个 if 分支都要测试,代码运行正常并不代表没有 bug,可能只是没有遇到触发 bug 的情景。

  2. 代码测试的时间甚至可能比代码编写的时间还要多

  3. 写代码的时候 think more,测试的时候 bug less

  4. 测试的以后 think more,后期的 bug less

编程思想和编程原则

* 先思考!先理清思路和需求!再编码!这是最重要的!!!
* 不要浅层思考,不要意识流
* 考虑可扩展性,需求改了后会不会改变
* 冗余的代码很难维护,因为改了一个地方,可能第二个地方也要修改,但是你不知道
* 代码要后期可维护,具有适量的注释,高内聚,低耦合
* 代码要有可读性
* 修改代码或变量的时候要注意与其相关的会不会受牵连,如果受牵连,怎么解耦
* 会产生异常的地方一定不能忽视,前面留下的问题,以后要花更多的时间解决
* 注意不要硬编码
* Dry 原则
不要出现重复的代码,SQL语句等
* 程序的运行要遵循一条主线的原则,在一条主线上加入分支,不要多条主线,灵活运用 break,continue
* 墨菲定律:觉得会出问题的地方,一定会出问题!!!(不要容忍破窗户,要严谨编码)
* 一条需求、一项任务,如果能够用语言将其描述,那么代码实现起来应该也不会太难。
* 软件开发规律和人的直觉是相反的。
* Think more ——> code less
* 编码在整个项目中一般只占 10% 左右的时间, 50 % 的时间用于沟通
* 编码之前一定要严格要求自己,建立好的品味
* 一个系统工程师的培养需要至少 8 - 10 年的时间
* 各个模块一定要正交!!!函数、模块、类的正交
* 函数一定要短小:在一屏内完成,适合解耦。写好函数的秘诀:将函数写的短小!!
* 代码是一种表达方式,代码是写给人看的!可读性最重要!代码是写给人看的!代码是写给人看的!代码是写给人看的!

代码优化原则

* 找到可以优化的地方
找细节
找循环(重复的地方)
* 还要考虑的地方
减少访问文件的次数
减少访问数据库的次数
减少请求网络的次数
* 优化的玄学
代码质量与代码的整洁程度成正比。如果代码一眼望去,杂乱无章,没有阅读的欲望,那么多半代码的质量也很差。这就提供了一个直觉,如果代码看起来“很丑”,那么多半需要优化了。

可读性

* 尽量不要有三层以上的代码缩进
* 命名不能随意,否则后面代码维护的时候自己都看不懂,代码的可读性和可维护性很重要!

if 语句避免嵌套过多的技巧

1. 德摩根律
非(p 且 q) == 非p 或 非 q
非(p 或 q) == 非p 且 非 q
2. 先对一些特殊条件进行处理,及时 return,主线原则

命名

* 一个好的命名可以免去了写注释的麻烦,多思考,少重复
* 命名一定不能随意,否则程序可读性非常差,后面可能自己都读不懂。
* 匈牙利命名法:把变量的『类型』缩写,放到变量名的最前面

后期修改 bug,修改代码的原则,维护的原则

* 修改后一定要想一想修改会不会引起新的变动。会不会导致之前写的代码不能用,出 bug。
* 修改完 Bug 一定要写文档记录一下,否则后面可能还会重复之前的劳动

注释

* 加注释最好在上一行加,不要在行末加,否则会触发 diff 检查

Debug 经验

查看 log 日志的重要性

遇到问题,先查看日志。

Debug 要考虑 有没有 log 文件可以分析,这是第一手资料

Debug 思路要清晰,不能慌

Demo: 网络传输耗时问题

问题描述

Basic交接后,出现了某些 URL 访问超时的问题。

log 文件定位

/home/work/odp/log/error_log 文件中报错:
2018/08/24 15:49:54 [error] 9830#0: *2233 upstream timed out (110: Connection timed out) while reading response header from upstream, client: 172.24.128.30, logid: 2984131137, -, server: yq01-yq-qadev-wanshuo.epc.baidu.com, request: "GET /summary/pzeroproblem?productid=all&subproduct=all&stime=2018-01-01%2000%3A00%3A00&etime=2018-08-24%2000%3A00%3A00 HTTP/1.1", -, upstream: "fastcgi://unix:/home/work/odp/var/php-cgi.sock", host: "yq01-yq-qadev-wanshuo.epc.baidu.com:8081", referrer: "http://yq01-yq-qadev-wanshuo.epc.baidu.com:8081/", -, -,

问题定位过程

经过测试,在修改开始时间后,例如从 4月1日 开始计算,那么能返回数据。
目前定位到错误应该源自:\baidu\ceqa-mdns\bq\models\service\page\summary\PZeroProblem.php 文件,因为两个接口都调用了该文件。所以问题应该都来自于该文件。
进一步定位发现,耗时操作来源于频繁访问数据库:`$this->product->get_product_name($product_id);`。线上 Basic 之所以没有产生超时的问题,是因为 ODP 服务和 数据库是放在了一台机器上,虽然 ODP 是通过 IP 访问的数据库,但是 IP 报文最终只是在局域网内进行传输,所以传输较快。
测试的时候出现该问题,原因在于测试机的 ODP 环境 和 线上数据库 属于不同的局域网,大部分时间浪费在了数据的传输上,实测线上机器运行上一条语句的时间只有不要 1 ms,而测试机需要 7 ms。更进一步的原因在于代码没有针对数据库的访问进行优化,频繁的访问数据库,后期的开发中,如果频繁的访问一张表,可以直接将整张表读取出来,放入内存中进行查询,这样数据只需要传输一次即可。

解决方案

  • ODP 环境 和 数据库放在一台机器上

  • 优化访问数据库的代码

经验总结

  • 正常的语句运行,例如赋值,加减等操作,不会耗费很多时间,即使是在循环中,也不会耗费太多时间

  • 访问数据库是一个很耗时的操作,如果数据库是远程数据库,那么很容易忽略数据的传输时间,而实际上,如果网速不好,或者开发机和数据库之间经过了多次路由,那么网络传输时间可能远远多于数据库的查询时间

  • 再复杂的语句,只要元语句是简单语句,那么其运行耗时都可能是 ms 级的,如果运行耗时是 s 级别的,那么要考虑数据库效率问题 和 网络传输问题

  • Bug 总能解决的,决定Bug能否解决的因素,往往是一个人的态度,而不是这个人的专业素质,困难也是如此

  • 网络采集模块出 bug 的概率比较高