写代码最完美的就是, 想清楚, 码, 运行, perfect, DONE, 下班.

当然, 那是完美的状态. 大多数时候只存在于理想中.

现实是, 我们会被各种坑, 被环境坑, 被语言坑, 被依赖坑, 被第三方库坑, 被编辑器坑, 被自己坑(三个月前的自己/昨天的自己/几分钟前的自己), 被数据库坑, 被缓存坑, 被队友坑(这个比较惨), 被需求变更坑(这个也是)……

所以, 总是避免不了代码调试.

今天顺带过了下<<想计算机科学家一样思考Python>>, 里面每一章最后都有关于调试的一些观点, 例如阅读 - 深思 - 修改/运行/回退, 所以决定来写写关于代码调试的一些东西.

其实, 代码调试是论如何排查问题的一个过程, 根据一切蛛丝马迹, 推断出问题所在, 并消灭之.(破案的即视感)

下面是一些关于一些自己在写代码和调试的总结


1.你得明白你在做什么, 保持清醒

代码调试有时候会让你陷入无尽的自我怀疑/迷茫/愤怒/沮丧/窘迫/挫败(无限负能量), 很容易被这些情绪左右, 不清醒, 陷入怀疑自我(一定是我调用的方式不对), 或者怀疑一切(一定是数据库问题, 不对, 缓存问题, 不对, 接口问题, 好像不对, 数据问题), 或者胡乱改代码(改-跑-错了-再改-跑-又错-再改, 传说中的随机行走编程), 或者……(挣扎吧……)

此刻, 保持清醒的自我是非常重要的, 要明确: 我在做什么问题是什么症状原来逻辑是什么最有可能出问题的是哪里?

2.想清楚了再写代码

如果连需求是什么, 想要做什么都没整明白, 就吭哧吭哧开写, 意图在实践中摸索通向胜利的道路, 是很愚蠢的行为.

需要去理解需求, 自己要做什么, 然后, 在大脑中构造, 现在有什么, 为了完成需求需要做什么, 完成大体的组成结构/步骤流程的思考后, 再着手去做.

大到整体设计, 小到一个函数, 都可以这么处理

例如, 遇到复杂问题, 可以先写注释, 完整所有函数整体设计, 然后再填充细节

def dosomething():“””“””# step1: call func test()# step2: parse url to # step3: judge# step4: convert and return

3.关于脚手架代码

在逻辑的关键位置, print/assert关键信息, 用于在调试中迅速确认问题. (一些中间值/状态/条件判断结果)

当然, 信息除了关键这个特性, 还需要足够丰富显眼, 一遍一次性定位问题. (既要好看又要有用)

你需要确定下如何用顺手的编辑器快速输入这些代码, 可以用各类语言的snippets

例如, 在写python时候, 我很喜欢prt(k-vim自动补全), 快速插入一些需要的信息

print "TRACK ================= result", type(result), result, result == "test"

4.写完一段代码第一时间自己review一下

事实证明, review的效果比写完直接跑再来调, 效率高多了.

刚写完一段代码, 思路还很清晰, 跳到开始, review过程中注意各类变量, 条件判断, 函数调用, 上下文, 一致性, 错误处理等, 花不了多少时间, 却能发现一些显而易见的问题, 省下很多无谓的调试时间(没问题不需要调试!).

5.review中注意, 代码是过来的么?

很多时候从其他地方copy代码过来(一行或几行, 有时候只是一个函数调用或一个判断), 但是很容易忘了根据当前情况修改一些必要的值, 导致问题

例如函数调用, 这个地方调用参数可能跟你copy这行代码需要参数不一样, 但是放在这里并不会报错(一切运作正常), 最终结果并不对…..

好了, 开始调试

6.搞明白问题的表现是什么(症状)

运行代码, 报错了, 有些人会瞬切回编辑器, 开始改代码(作高效状)……>_<#

问题是: 报错提示你看了么, 看明白了么?

现在大部分语言, 其报错提示已经很明显了, 精确到行/变量, 虽然整个异常栈信息可能很长(非常长), 但是都有其特征(在最前或在最后,或在中间靠后, 有关键字), 仔细看下报错信息, 精确制导才是王道.

所以, 你需要从错误信息中先确认

错误类型
发生错误的地方

很多语法问题可以根据这个信息直接定位

7.调试过程中, 需要时刻注意

改的是不是正确的目录下正确的文件?(大坑)

保存了么(编译了么)?(又一个坑)

服务重启了么?

跟数据库有没有关系/跟缓存有没有关系, 要不要清?

……

以上问题, 随便碰上一个你都可能发现, 自己书写的代码和当前运行来调试的代码不一样.(会浪费你巨量的时间)

自己调试半天怎么还是一样的结果

我一直在修改, 但是没有什么区别(出现这种情况要自问一下了)

可以显示在代码头部打印或者故意出错, 确认是同一套代码

8.环境/数据一致性

当你发现在本地无法复现别人报过来的问题(在我电脑上是正常的), 这时候, 需要考虑是否是环境和数据的问题.

9.先不要动代码, 假设代码是正确的

遇到问题, 不要急着修改代码, 需要假设, 代码是正确的, 然后去复现, 复现之后定位.

10.首先要怀疑自己

你不能一旦代码跑不动就怀疑是别人的问题, 然后抛给别人, 这样做同样是很不负责任而且很愚蠢的.

首先, 你需要怀疑自己, 排查问题, 当确定不是自己的问题之后, 将问题定位, 输入, 预期结果, 现在的异常结果都处理好, 生成一个问题, 抛给对应负责人. (一切没有价值的怀疑都是无意义的)

程序员都是好人, 每次都在想: 一定是我的问题

11.对于莫名其妙的问题, 多试几种情况

有时候碰上一些诡异的问题, 例如有一种情况的输入会报错, 这时候, 再跳过去修改代码前, 可以多尝试几种输入, 涉及边界/异常/正常等情况, 排除法, 精确制导.

例如, 可以变换输入值的范围(扩大或缩小, 可能用二分法), 变换输入类型和格式

12.先回到正确的代码

如果这段代码是由于修改导致的, 可以注掉此次变更代码, 同样的输入再次验证定位

13.如果一段代码是没动过的代码

如果你确保确实没动过, 此时, 先不要怀疑自己, 更大的可能是别人的问题.

可能情况: 依赖出了问题(调用函数返回数据不对/异常? 依赖请求挂了? ……), 数据出了问题(表结构变更/服务返回数据变更), 环境问题(数据库/缓存)

14.bug总是倾向于集中出现在一起

很多时候, bug是扎堆的, 可以回忆下之前修改的地方, 确认问题.

15.对于很长很长, 上二分法

可能函数很长, 或者调用链很长, 不易调试.(光打调试信息就得打得手疼)

找到关键变量, 上二分法, 无上利器.

16.print or debug?

个人偏好简单粗暴的print, 主要是用的vim+sinppet, 快速高效.

当然, 如果用IDE, 用 debug

17.十分十分诡异的问题

debug, 打断点, 一点点调试吧, 只能这样了.

18.当一个问题超过半小时

歇一歇, 走动走动, 打个水, 呼吸下新鲜空气.

这时候有利于脱出情境, 去掉挫败感/愤怒/迷信等

很多时候突然灵感一到, 瞬间明了(这种感觉很奇妙)

19.关于google

有些错误信息, 如果觉得比较独特诡异, 可以google下, 你会找到更多的一些信息的.

20.关于求助

实在搞不定, google大神也搞不定, 此时可能需要求助了.

前提, 你自己能把问题想清楚, 并且逻辑清晰地描述出来.(什么业务什么位置的什么逻辑, 报错类型和报错信息, 输入输出, 迄今做了哪些尝试等等) 要学会聪明地问问题, 高效, 尊重自己也尊重别人.

如果你自己都没整明白怎么问, 别人也无能为力.

遇到很多人, 直接上来就一句xxx出问题了, 没有前置条件后置结果中间症状……

不过, 如果你会聪明地问, 那就放心大胆地问吧, 不用磨磨唧唧的, 程序员大都是善良的孩子.

21.吃一堑长一智

被坑了就要总结总结, 有个记录, 不被同一个问题坑两次.

如果被坑了就忘, 还需要去反复求助, 那这属于坑队友的行为(鄙视下)


好了, 就这些:)

关于代码调试de那些事相关推荐

  1. 香草冰淇淋和代码调试

    //===================================================================== //TITLE: //    香草冰淇淋和代码调试 // ...

  2. 【VS实践】代码调试与错误处理

    程序员的装逼技能:调试,错误处理和快捷键 学计算机3年,只知道一些基础的理论知识,写代码和调试很差,基本不会什么吧! 花时间了解一下关于这块的东西!以前觉得调试就是代码写出来一运行,有问题了分析那里出 ...

  3. 转:Python 代码调试技巧

    Python 代码调试技巧 转载于:https://www.cnblogs.com/kira2will/p/4254754.html

  4. 树形dp——树的重心(2) 代码调试理解

    和树的最大独立问题类似,先任选一个结点作为根节点,把无根树变成有根树,然后设d(i)表示以i为根的子树的结点的个数.不难发现d(i)=∑d(j)+1,j∈s(i).s(i)为i结点的所有儿子结点的编号 ...

  5. 三、K3 Cloud 开发插件《K3 Cloud插件开发新手指导 + K3 Cloud插件开发代码调试》

    案例需求:在销售订单上新增一个按钮,在订单明细中新增一个字段,命名[即时库存]. 点击按钮,弹出"Hello World!",并获取订单明细物料的即时库存,填入字段[即时库存]. ...

  6. 【Android 逆向】代码调试器开发 ( 使用 NDK 中的 ndk-build + Android.mk 编译 Android 平台的代码调试器可执行应用 )

    文章目录 一.Android 平台代码调试器代码 二.Android.mk 构建脚本内容 三.Application.mk 构建脚本内容 四.正式编译 五.博客资源 一.Android 平台代码调试器 ...

  7. 【Android 逆向】代码调试器开发 ( 等待进程状态改变 | detach 脱离进程调试 PTRACE_DETACH | 调试中继续运行程序 PTRACE_CONT )

    文章目录 一.等待进程状态改变 二.detach 脱离进程调试 PTRACE_DETACH 三.调试中继续运行程序 PTRACE_CONT 一.等待进程状态改变 上一篇博客 [Android 逆向]代 ...

  8. 【Android 逆向】代码调试器开发 ( 代码调试器功能简介 | 设置断点 | 读写内存 | 读写寄存器 | 恢复运行 | Attach 进程 )

    文章目录 一.代码调试器功能简介 二.Attach 进程 一.代码调试器功能简介 代码调试器功能 : 设置断点 : 无论什么类型的调试器 , 都必须可以设置断点 , 运行到断点处 , 挂起被调试进程 ...

  9. Python代码调试方法

    对于每个程序开发者来说,调试几乎是必备技能.常用Pycharm编辑器里的方法有Print大法.log大法,但缺少类似Matlab的变量区,给代码调试带来不便,特别是在有函数的情况下,变量无法实时查看. ...

最新文章

  1. java大文件读写操作,java nio 之MappedByteBuffer,高效文件/内存映射
  2. ARKit从入门到精通(7)-ARCamera介绍
  3. STM32F103:一.(1)MDK的配置
  4. 旅游景点、住宿带餐饮一天一万多流水能做到吗?
  5. 用命令行安装IIS(pkgmgr版)
  6. JTT1077-2016道路运输车辆卫星定位系统视频平台技术要求(企业监控平台功能-文字版)
  7. 继音频转换历程总结成综合
  8. 【算法讲19:同余最短路】跳楼机 | 墨墨的等式 | Lazy Running
  9. mmclassification使用步骤与心得/ACCV实验记录
  10. 对txt文件批量操作
  11. 如何用Tableau可视化?
  12. 用js代码实现四位验证码
  13. 我看好金融IT业的几个理由
  14. 网易企业邮箱搬家步骤
  15. 怎么写小说?做好这4步,你也能开始写小说 | Effie经验分享
  16. 修改用户名和用户组名
  17. 不相关的正态分布随机变量也不一定就独立
  18. 数据之美:可视化会给你意想不到的答案!
  19. matlab求矩阵的谱半径,【什么是矩阵的谱半径?怎么求?】百度-谱半径
  20. 推荐几个很好的编程在线测试平台 online judge

热门文章

  1. 【云笔记搭建】Visual Code + Github仓库 + Git
  2. tsql_TSQL的历史
  3. 使用SQL Server数据工具进行SQL单元测试
  4. 使用Java对sftp带有中文路径的文件夹进行下载,乱码打不开文件夹
  5. [补档]noip2019集训测试赛(十三)
  6. 曼哈顿交易 - 题解
  7. Django ORM QuerySet集合对象的特性
  8. synchronized(this)、synchronized(class)与synchronized(Object)的区别
  9. whereis 命令(转)
  10. vs2008+sp1