时隔16年Jeff Barr重返10.23-25 QCon上海站,带你看透AI如何重塑软件开发! 了解详情
写点什么

Remy Sharp 谈调试的艺术

  • 2015-11-04
  • 本文字数:2444 字

    阅读完需:约 8 分钟

继 2012 年的经典演讲《Mobile Debugging》之后,JavaScript 开发大师 Remy Sharp 近日又在 Fronteers 2015 上发表了题为《The Art of Debugging》的演讲。随后,Remy 在博客中对调试的艺术进行了详细描述。接下来,本文就走近大师,聆听其对调试的心得。

在开篇,Remy 就提到,程序开发人员总是免不了编写bug。那么,调试就是一项必须要掌握的技能。Remy 认为,调试是不存在捷径的,开发人员需要时间和经验的积累才能提升相关能力。10 年前,当Remy 还是个新人的时候,他曾遇到一个CSS 大牛——Chris。每当Remy 遇到问题时,Chris 总能一针见血的指出问题所在。其原因就是Chris 已经积累了足够的经验,对代码和可能遇到的问题有了清楚的认识。

另外一方面,调试其实也是很好的工作机会。Remy 提到,当10 年前在一家公司工作的时候,老员工总是会给新人炫耀程序员工作的成果和他们正在解决的问题。然后,新员工实习期的主要工作就是负责调试代码。这看起来非常艰难的工作,其实是对新人而言一个非常好的锻炼机会。程序编写人员可能已经花费了3 个月、6 个月甚至一年的时间在代码上。调试人员则可以根据工作需要迅速了解这些代码的方方面面,并因为解决若干个bug 而享受项目成功所带来的荣耀。因此,调试虽然艰难,却最能给开发人员最好的精神和物质回报。

在进一步介绍调试艺术之前,Remy 提出了两条免责声明。第一条,文中所提及的框架和工具不一定对任何人和任何项目都适用。Remy 更多的希望读者能够关注文章所表达的一些思路和想法。第二条,Remy 很少进行跨浏览器测试。他认为,如果代码存在bug,在任何浏览器中访问都应该存在问题;反之,就不应该存在问题。

Remy 将调试划分了三个步骤——复制、隔离和消除。复制主要完成问题的重现工作,是调试中最困难的部分。问题重现不仅要保存现场,还需要收集尽可能多的相关信息。Remy 建议,复制要一步步的进行。一般情况下,bug 都是由一系列事件造成。调试人员需要理解这些事件,并在以后重现这些事件以进行调试中的分析。Remy 介绍了两个帮助复制环境的工具——匿名模式(incognito)和多账户(multiple profiles)。匿名模式可以很好的避免扩展、缓存和离线存储等引起的问题。Remy 表示,他每年都会遇到扩展应用引起的古怪问题。而匿名模式可以帮助尽快确认问题是否与扩展有关。多账户包括了日常账户、匿名账户和 Troll 账户。Troll 账户主要用于发现高安全级别引起的问题。

隔离主要负责缩小并锁定可疑代码的范围。如果是扩展引起的问题,调试人员最好一个一个的使能以最终锁定目标。一旦范围锁定到足够小,就可以开始消除 bug 的工作了。在走完上述两个步骤后,消除 bug 就变得容易很多。调试人员只需要针对问题,修改代码即可。真正麻烦的是,复制操作有时候很难完成——例如, Heisenbug 的情况。Remy 表示,他曾经遇到过只在 CI 系统中出现的 bug。尽管 Remy 已经对代码非常熟悉,并且非常确定问题已经在本地环境中得以修复,CI 系统的测试仍然无法通过。Remy 建议,这时候就需要对测试环境进行调试。另外一种情况是,调试人员使用的调试工具可能会引起 bug。Remy 曾经使用的 Firebug 就引起过这样的问题。因此,进行带开发工具时间线的调试时,程序员最好关闭部分录制选项、所有的其他标签和可能使用 WebKit 的东西。

在调试方法方面,Remy 将其分为 Inside out 和 Outside in 两类。前者是指 bug 的原因已经确定。这种情况下,调试人员只需要添加一个函数、几行代码或者设置相应断点即可。而后者是指调试人员只看到了问题的表相,并不清楚问题的根源。针对这种情况,调试人员可以使用 DOM 断点、Ajax 断点、重新运行 XHR 请求和时间线截屏。

最后,Remy 分享了他部分他所使用的工作流和最常用的工具。在工作区和实时更新方面,Remy 会直接把本地目录拖拽到工具区中,并选择至少一个文件映射到文件系统资源中。这样,任何在源面板中的修改都会直接保存到磁盘中。如果 CSS 文件也同样被映射,任何元素面板中对风格的改变都会更新相应的 CSS 文件。在元素面板的撤销操作方面,Remy 推荐源控制和撤销。而,Chrome 的开发工具很好的支持了撤销操作。在控制台快捷方式方面,Remy 使用$_来表示最后一个表达式的结果、$0表示当前元素面板中选中的 DOM 节点、copy(...)完成拷贝到粘贴板的操作等。

此外,Remy 使用时间线截图来修复两类问题。第一个问题是字体加载是否正确、是否占用太长时间。时间线截图可以很好的反映该问题。第二个与标签系统加载延迟太慢相关。利用“camera”按钮中的截图可以很好的记录渲染时间线,从而反映该问题。网络节流也是很好研究网络慢或者离线所造成影响的有效手段。而检查网络报文头和拷贝原始的反馈也非常有用。在调试、修复和重启服务器后,调试人员利用“Replay XHR”即可重新运行请求,测试服务器反馈是否已经调整。“Break on DOM changes”是 Remy 调试方法 _outside in_ 中的一种。针对只知道问题表象的情况,该方法非常有用。

针对内存泄漏这类常见的问题,Remy 推荐两种方法:阶梯形表面测试和利用分析工具来抓取泄露源的线索。阶梯效应是判断是否存在内存泄漏的第一条线索。Remy 通常会首先建立一个参考的内存使用情况,然后运行一个会话后使用垃圾回收,查看是否内存会增加。如果存在内存泄漏,就可以继续进行下一步分析了。分析需要在会话开始和结束时分别抓取 HeapDump。然后,通过比较两个 HeapDump 之间的 delta 值,内存中标红的条目即是无法进行垃圾回收的条目。调试人员针对这些条目进行进一步分析就可找到问题的根源。

在博客最后,Remy 再次强调,调试技巧是需要长期积累的,希望读者可以抓住每次调试的机会多多学习。而且,Remy 提醒读者在调试时多多休息。很多 bug 就是在走路和洗澡的时候想到解决方案的。


感谢徐川对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ @丁晓昀),微信(微信号: InfoQChina )关注我们,并与我们的编辑和其他读者朋友交流(欢迎加入 InfoQ 读者交流群)。

2015-11-04 18:001888
用户头像

发布了 268 篇内容, 共 135.8 次阅读, 收获喜欢 24 次。

关注

评论

发布
暂无评论
发现更多内容

并发相关的性质学习笔记

风翱

并发 10月月更

【LeetCode】Fizz Buzz Java题解

Albert

算法 LeetCode 10月月更

存量时代会员深度运营逻辑

boshi

深度思考 运营

linux中vi,vim操作技巧

入门小站

Linux

青岛敏捷之旅,来了!

禅道项目管理

敏捷 敏捷教练 青岛

”微博评论“的高性能高可用计算架构

缘分呐

架构设计实战

【Flutter 专题】30 图解自定义底部状态栏 ACEBottomNavigationBar (二)

阿策小和尚

Flutter 小菜 0 基础学习 Flutter Android 小菜鸟 10月月更

喜大普奔!焱融科技正式推出 SaaS 数据服务平台

焱融科技

云计算 高性能 公有云 文件存储 分布式,

SSRF漏洞实例分析

网络安全学海

网络安全 信息安全 渗透测试 WEB安全 漏洞分析

阿里架构师总结Go语言和java语言之间的对比联系

hanaper

Facebook宕机事故,暴露了上云不是唯一的答案

脑极体

python 数据库编程,这篇是针对 mysql 的,滚雪球学Python第4季第13篇

梦想橡皮擦

10月月更

智能运维之日志语义异常检测

云智慧AIOps社区

日志 数据处理 异常检测 智能运维 算法实践

直播分发选低延迟 RTC 还是 CDN?

融云 RongCloud

CDN 直播 RTC

Leetcode 题目解析:279. 完全平方数

程序员架构进阶

算法 LeetCode 动态规划 10月月更

在线下划线转驼峰,驼峰转下划线工具

入门小站

工具

CSS架构之Components层

Augus

CSS 10月月更

SpringBoot 实战:在 RequestBody 中优雅的使用枚举参数(原理篇)

看山

Java Spring Boot Effective Spring 10月月更

《沸腾新十年》背后的N重空间

博文视点Broadview

Vue进阶(幺叁肆):npm查看包版本信息

No Silver Bullet

Vue 表单校验 10月月更

015云原生之大数据技术

穿过生命散发芬芳

云原生 10月月更

快速配置浏览器 https 访问 Kibana(qbit)

qbit

elasticsearch TLS Kibana ssl

小知识系列:查询数据库数据的元信息

程序那些事

Java 数据库 元数据 程序那些事

技术分享| RTC通讯中常用的图像格式

anyRTC开发者

音视频 RTC 图像格式 rgb yuv

第 16 章 -《Linux 一学就会》- Linux计划任务与日志的管理

学神来啦

Linux linux运维 linux学习 linux一学就会

粪菌移植的背后,肠道菌那些你不知道的事儿

脑极体

IM系统消息丢失问题排查反思

轻口味

IM Android; 10月月更

keytool生成keystore、truststore、证书

黄敏

火山引擎MARS-APM Plus x 飞书 |降低线上OOM,提高App性能稳定性

字节跳动终端技术

ios android 大前端 MARS-APMPlus

Prometheus 基础查询(一)

耳东@Erdong

Prometheus 10月月更

OceanBase 存储层代码解读(二)微块存储格式

OceanBase 数据库

Remy Sharp谈调试的艺术_语言 & 开发_张天雷_InfoQ精选文章