标签:调试 情况 sse 三个月 ref 格式 负责人 等等 ==
原文出处:http://www.wklken.me/posts/2014/11/23/how-to-debug.html
写代码最完美的就是, 想清楚, 码, 运行, perfect, DONE, 下班.
当然, 那是完美的状态. 大多数时候只存在于理想中.
现实是, 我们会被各种坑, 被环境坑, 被语言坑, 被依赖坑, 被第三方库坑, 被编辑器坑, 被自己坑(三个月前的自己/昨天的自己/几分钟前的自己), 被数据库坑, 被缓存坑, 被队友坑(这个比较惨), 被需求变更坑(这个也是)......
所以, 总是避免不了代码调试.
今天顺带过了下<<想计算机科学家一样思考Python>>, 里面每一章最后都有关于调试的一些观点, 例如阅读 - 深思 - 修改/运行/回退
, 所以决定来写写关于代码调试的一些东西.
其实, 代码调试是论如何排查问题
的一个过程, 根据一切蛛丝马迹, 推断出问题所在, 并消灭之.(破案的即视感)
下面是一些关于一些自己在写代码和调试的总结
代码调试有时候会让你陷入无尽的自我怀疑/迷茫/愤怒/沮丧/窘迫/挫败(无限负能量), 很容易被这些情绪左右, 不清醒, 陷入怀疑自我(一定是我调用的方式不对), 或者怀疑一切(一定是数据库问题, 不对, 缓存问题, 不对, 接口问题, 好像不对, 数据问题), 或者胡乱改代码(改-跑-错了-再改-跑-又错-再改, 传说中的随机行走编程), 或者......(挣扎吧......)
此刻, 保持清醒的自我是非常重要的, 要明确: 我在做什么
, 问题是什么症状
, 原来逻辑是什么
, 最有可能出问题的是哪里
?
如果连需求是什么, 想要做什么都没整明白, 就吭哧吭哧开写, 意图在实践中摸索通向胜利的道路, 是很愚蠢的行为.
需要去理解需求, 自己要做什么, 然后, 在大脑中构造, 现在有什么, 为了完成需求需要做什么, 完成大体的组成结构/步骤流程的思考后, 再着手去做.
大到整体设计, 小到一个函数, 都可以这么处理
例如, 遇到复杂问题, 可以先写注释, 完整所有函数整体设计, 然后再填充细节
def dosomething():
“””
“””
# step1: call func test()
# step2: parse url to
# step3: judge
# step4: convert and return
脚手架
代码在逻辑的关键位置, print/assert关键信息, 用于在调试中迅速确认问题. (一些中间值/状态/条件判断结果)
当然, 信息除了关键
这个特性, 还需要足够丰富
和显眼
, 一遍一次性定位问题. (既要好看又要有用)
你需要确定下如何用顺手的编辑器快速输入这些代码, 可以用各类语言的snippets
例如, 在写python时候, 我很喜欢prt(k-vim自动补全), 快速插入一些需要的信息
print "TRACK ================= result", type(result), result, result == "test"
事实证明, review的效果比写完直接跑再来调, 效率高多了.
刚写完一段代码, 思路还很清晰, 跳到开始, review过程中注意各类变量, 条件判断, 函数调用, 上下文, 一致性, 错误处理等, 花不了多少时间, 却能发现一些显而易见
的问题, 省下很多无谓的调试时间(没问题不需要调试!).
抠
过来的么?很多时候从其他地方copy代码过来(一行或几行, 有时候只是一个函数调用或一个判断), 但是很容易忘了根据当前情况修改一些必要的值, 导致问题
例如函数调用, 这个地方调用参数可能跟你copy这行代码需要参数不一样, 但是放在这里并不会报错(一切运作正常), 最终结果并不对.....
好了, 开始调试
运行代码, 报错了, 有些人会瞬切回编辑器, 开始改代码(作高效状)......>_<#
问题是: 报错提示你看了么, 看明白了么?
现在大部分语言, 其报错提示已经很明显了, 精确到行/变量, 虽然整个异常栈信息可能很长(非常长), 但是都有其特征(在最前或在最后,或在中间靠后, 有关键字), 仔细看下报错信息, 精确制导才是王道.
所以, 你需要从错误信息中先确认
错误类型 发生错误的地方
很多语法问题可以根据这个信息直接定位
改的是不是正确的目录下正确的文件?(大坑)
保存了么(编译了么)?(又一个坑)
服务重启了么?
跟数据库有没有关系/跟缓存有没有关系, 要不要清?
……
以上问题, 随便碰上一个你都可能发现, 自己书写的代码和当前运行来调试的代码不一样.(会浪费你巨量的时间)
自己调试半天怎么还是一样的结果
我一直在修改, 但是没有什么区别(出现这种情况要自问一下了)
可以显示在代码头部打印或者故意出错, 确认是同一套代码
当你发现在本地无法复现别人报过来的问题(在我电脑上是正常的), 这时候, 需要考虑是否是环境和数据的问题.
遇到问题, 不要急着修改代码, 需要假设, 代码是正确的, 然后去复现, 复现之后定位.
你不能一旦代码跑不动就怀疑是别人的问题, 然后抛给别人, 这样做同样是很不负责任而且很愚蠢的.
首先, 你需要怀疑自己, 排查问题, 当确定不是自己的问题之后, 将问题定位, 输入, 预期结果, 现在的异常结果都处理好, 生成一个问题, 抛给对应负责人. (一切没有价值的怀疑都是无意义的)
程序员都是好人, 每次都在想: 一定是我的问题
有时候碰上一些诡异的问题, 例如有一种情况的输入会报错, 这时候, 再跳过去修改代码前, 可以多尝试几种输入, 涉及边界/异常/正常等情况, 排除法, 精确制导.
例如, 可以变换输入值的范围(扩大或缩小, 可能用二分法), 变换输入类型和格式
正确的代码
如果这段代码是由于修改导致的, 可以注掉此次变更代码, 同样的输入再次验证定位
没动过
的代码如果你确保确实没动过
, 此时, 先不要怀疑自己, 更大的可能是别人的问题
.
可能情况: 依赖出了问题(调用函数返回数据不对/异常? 依赖请求挂了? ……), 数据出了问题(表结构变更/服务返回数据变更), 环境问题(数据库/缓存)
很多时候, bug是扎堆的, 可以回忆下之前修改的地方, 确认问题.
二分法
可能函数很长, 或者调用链很长, 不易调试.(光打调试信息就得打得手疼)
找到关键变量, 上二分法
, 无上利器.
个人偏好简单粗暴的print
, 主要是用的vim+sinppet, 快速高效.
当然, 如果用IDE, 用 debug
吧
上debug
, 打断点, 一点点调试吧, 只能这样了.
歇一歇, 走动走动, 打个水, 呼吸下新鲜空气.
这时候有利于脱出情境, 去掉挫败感/愤怒/迷信等
很多时候突然灵感一到, 瞬间明了(这种感觉很奇妙)
有些错误信息, 如果觉得比较独特诡异, 可以google下, 你会找到更多的一些信息的.
实在搞不定, google大神也搞不定, 此时可能需要求助了.
前提, 你自己能把问题想清楚, 并且逻辑清晰地描述出来.(什么业务什么位置的什么逻辑, 报错类型和报错信息, 输入输出, 迄今做了哪些尝试等等) 要学会聪明地问问题, 高效, 尊重自己也尊重别人.
如果你自己都没整明白怎么问, 别人也无能为力.
遇到很多人, 直接上来就一句xxx出问题了
, 没有前置条件后置结果中间症状......
不过, 如果你会聪明地问, 那就放心大胆地问吧, 不用磨磨唧唧的, 程序员大都是善良的孩子.
被坑了就要总结总结, 有个记录, 不被同一个问题坑两次.
如果被坑了就忘, 还需要去反复求助, 那这属于坑队友的行为(鄙视下)
好了, 就这些:)
标签:调试 情况 sse 三个月 ref 格式 负责人 等等 ==
原文地址:http://www.cnblogs.com/guochaoxxl/p/7086619.html