编程中,调试几乎是必不可少的,一劳永逸、一次完成预想功能而完全不出bug的情况凤毛麟角,出现bug→调试→再出现bug→再调试……基本是软件工程中的常态。可以说,软件调试是每个coder的必修课,而《软件调试修炼之道》便是一本调试教科书,考虑到前两次大作业中出现的各种bug,我有必要系统地学习debug的一些思想和技巧,因此本周我阅读了这本书的Part 1:问题的核心。这一部分由五章组成:山重水复疑无路,重现问题,诊断,修复缺陷,反思。以下我将分别浅谈我的阅读感想。

  1、概览调试:流程、问题和原则

  第一章名为“山重水复疑无路”,颇为扑朔迷离的命名,内容却很明晰:介绍软件调试,简单概述调试的流程、原则和遇到的问题,为后四章详细铺叙起头。其中给我感触比较深的是关于调试的意义与价值的介绍。在我和身边同学的一贯认知中,调试就是为自己的bug买单,算是编程中最令人烦躁、耗费大量时间而收获寥寥、时常引起心态伴随程序一起崩的工作,我每次点下“ctrl+F7/F5”和设置断点查看结果,都伴随着难以名状的期待:但愿不要出bug。而本书中认为,真正的调试并非简单的修复缺陷,而是要发现问题、解决问题、提高代码质量并确保问题不再发生。为调试所花的时间往往比敲代码更有意义和价值。回想过去的编程经历,确实如此。我已记不清大整数加减乘除的实现算法,但却能轻易想起当初调试越界问题、数组移位进位问题的教训;编写数独程序的生成算法和QT界面代码我也印象不深了,但对QT信号传递、部件命名的debug过程还历历在目。短期而言,调试确实让我们抓耳挠腮、耗费心力却只解决了某个细节问题;但从长远来看,每一次调试都让我们交足了学费、痛定思痛,不再跌入同一个坑。同时,调试往往比重写更有效率。个人作业中的词频搜索里,由于一个判断逻辑的错误,我的输出与示例偏差很大,一度想要换算法重写。但经过调试,最终只改了一个if中的判断条件,便符合了需求,省下了不少功夫。

  原则方面,按照约定俗成的经验,我们基本上每次调试只解决一个问题,同时避免影响其他部分的正常工作,以免顾此失彼、焦头烂额。

  2、调试核心:重现、诊断、修复和反思

  重现,即发现问题,之后才能谈解决。在简单程序的debug中,往往不需要重现,因为bug就堂堂正正地摆在眼前耀武扬威;但软件发布后的调试中,很多情况下是基于用户反馈的缺陷,往往需要重现问题,来发现问题所在、寻求解决方案。书中介绍了朴素的控制变量法和玄学的推测法等。在结对编程中,我们的dll发布后交由UI组测试,与软件交付用户的流程比较相近,调试流程也基本相同。好在好心的UI组们基本都把可能的bug给我们列举出来,我们只需要用推测法简单尝试就能发现问题,也有一些问题是显而易见的,例如泛用性、便利性等。总而言之,发现问题是解决问题的第一步,重现问题,才能做到有的放矢。

  诊断,即发现问题后提出假设、进行实验,直到找到症结所在。这种思想方法在我们过往的断点debug中经常使用。当结果不符合预期时,我们会先通过断点确定问题出现的区域,再通过实验逐步找到问题语句,完成诊断。更科学地说,可以通过“插桩法”“二分法”等方式“排雷”,这些也算是老生常谈了。需要注意的是,诊断有时会造成“陷阱”,即看错症结、治标不治本。词频统计作业中,我曾在调试中改错条件,使得输出结果里原本错误的词汇统计变得正确了,但词组统计依旧错误,后来发现修改处不正确,只是生硬地打上了补丁。可见找准问题所在、外科手术式精准定位和修改后仔细筛查,是非常重要的。

  修复,是调试的最终阶段,也是最可能出问题的阶段。这是因为有些问题的症结根深蒂固,甚至修复代价大得让人难以接受。在日常生活中其实不乏这样的例子,比如某程序的核心算法存在致命缺陷,只能重构;比如某校BBS论坛的实现中纯用C语言完成,甚至连数据库都没有,落后时代十几年而基本无法有效维护、更新,修复的工作量基本和推倒重建的工作量差不多。这时,“掩盖真相”的手法应运而生:不管根本原因出在哪里,只要用一些操作来让输出结果正确就可以。这样的方法确实有一些效果,也能避免付出过大的修复代价,但高风险、留隐患的弊端也是显而易见。惭愧的是,我在结对编程中也使用了这样“掩盖真相”的手法。由于某些我debug良久而想不通的原因,生成算式中乘方(^)后跟的数字会超过我设置的限制范围,还会带上括号,最终我选择通过暴力筛选手段筛掉不合要求的式子,并通过不断超量生成式子、选出合适的式子的操作来使输出的式子都正确。客观来说,这样的做法实质上并没有解决核心问题,但实际操作中确实卓有成效,算是没有办法的办法。现实中的修复当然还是要力求解决根本问题,但有时也不得不为效率和资源做出妥协,个人而言,我真诚地期望不再使用“表面补丁”修复程序,而是更负责地进行重构。

  反思,就是吸取经验教训了。每一次调试都是为我们犯下的错误买单,包括数据结构选择的不合理、算法的缺陷、逻辑错误和键入失误等。常言道,吃一堑长一智,每次调试都是总结错误、吸取教训的宝贵经历。

  总而言之,调试的核心流程近似一个瀑布模型,各流程间又不断迭代。在调试中解决问题、提升程序的完整性和可靠性,正是软件调试修炼之道。

《软件调试修炼之道》Part 1(CH1~5)读书笔记 PB16110698 第八周(~4.26)的更多相关文章

  1. 《代码整洁之道》ch1~ch4读书笔记 PB16110698 (~3.8 第一周)

    <代码整洁之道>ch1~ch4读书笔记  <clean code>正如其书名所言,是一本关于整洁代码规范的“教科书”.作者在书中通过实例阐述了整洁代码带来的种种利处以及混乱代码 ...

  2. 《移山之道》第十一章:两人合作 读书笔记 PB16110698 第六周(~4.15)

     本周在考虑阅读材料时,我翻阅了<移山之道>,正好看到这一章:两人合作,心想:正好,我们正值结对作业的紧要关头,书中两人合作的宝贵经验和教诲应当对我们有很大帮助.于是,我开始一边在ddl苦 ...

  3. 《代码整洁之道》ch5~ch9读书笔记 PB16110698(~3.15) 第二周

    <代码整洁之道>ch5~ch9读书笔记 本周我阅读了本书的第5~9章节,进一步了解整洁代码需要注意的几个方面:格式.对象与数据结构.错误处理.边界测试.单元测试和类的规范.以下我将分别记录 ...

  4. 《Linux内核设计与实现》读书笔记(十八)- 内核调试

    内核调试的难点在于它不能像用户态程序调试那样打断点,随时暂停查看各个变量的状态. 也不能像用户态程序那样崩溃后迅速的重启,恢复初始状态. 用户态程序和内核交互,用户态程序的各种状态,错误等可以由内核来 ...

  5. 软件开发-MSF方法(《构建之法》读书笔记2)

    MSF-微软解决方案框架,是一套大型系统开发指南,它描述了如何用组队模型.过程模型和应用模型来开发Client/Server结构的应用程序,是在微软的工具和技术的基础上建立并开发分布式企业系统应用的参 ...

  6. <《巴菲特之道 (第三版)》>读书笔记

    以便宜的价格买入长期绩优的股票 他把对公司的投资看做是拥有公司的一部分股权,看重的是公司的长期经济价值 别人越是草率,我们越要加倍慎重 如果你发现自己已经在陷阱中,最重要的是想办法让自己不要再往下陷 ...

  7. 《单元测试之道Java版》的读书笔记

    总览 第2章 首个单元测试 第3章 使用JUnit编写测试 3.1 构建单元测试 3.2 JUnit的各种断言 3.3 JUnit框架 4. 测试什么? 5.CORRECT(正确的)边界条件 6.使用 ...

  8. <读书笔记>软件调试之道 :从大局看调试-理想的调试环境

    声明:本文档的内容主要来源于书籍<软件调试修炼之道>作者Paul Butcher,属于读书笔记.欢迎转载! ---------------------------------------- ...

  9. <读书笔记>软件调试之道 :从大局看调试-零容忍策略

    声明:本文档的内容主要来源于书籍<软件调试修炼之道>作者Paul Butcher,属于读书笔记.欢迎转载! ---------------------------------------- ...

随机推荐

  1. 网页压缩--gzip和deflate的区别

    我们在配置网站GZip压缩的时候,会发现有两个模块可以设置的,一个是GZip模块的参数配置,另一个是Deflate模块的参数配置,他们的设置方法是一样的.刚开始时我不太明白,这两地方有什么不同?网站开 ...

  2. Ethenet: MAC PHY MII RMII

    https://www.cnblogs.com/liangxiaofeng/p/3874866.html 1. general 下图是网口结构简图.网口由CPU.MAC和PHY三部分组成.DMA控制器 ...

  3. ubuntu 搭建嵌入式开发环境tftp的方法

    网上很多安装的时候都要安装tftpd-hpa tftp-hpa xinetd三个安装包,经我测试,xinetd无需安装,安装好前两个后,修改tftpd-hpa的配置文件即可:etc/default/t ...

  4. nuxt header 设置

    1. nuxt.config.js 中配置全局 2. 在单页面设置单独

  5. 微信小程序支付之代码详解

    微信小程序自带的一套规则,类似vue语法,但是好多功能都集成在api中,给了很多初学者轮子,所以首先要熟悉这些api,忘记可照官网继续开发 这里主要说下微信小程序的支付,原理类似上篇介绍的公众网页支付 ...

  6. winform 使用webbrowser 打开不了pdf的解决办法

    最近有个项目需要在winform 打开网络路径的pdf文件,自然想到了webbrowser,但是让我没想到的是,在我电脑调试一点问题都没有,但是到了其他同事的电脑是各种各样的问题,有的打不开,有的显示 ...

  7. rest_framework 认证组件 权限组件

    认证组件 权限组件 一.准备内容 # models class User(models.Model): name = models.CharField(max_length=32) pwd = mod ...

  8. 如何将sql查询出的列名用注释代替?

    如何将sql查询出的列名用注释代替? 大家正常的工作的时候,会有这样的要求,客户想要看下原始数据,但是呢.前台导出又麻烦,这时候只能从数据库拷贝出来一份.但是呢,数据库里面的字段客户又看不明白,只能用 ...

  9. Dart编程环境

    本章讨论在Windows平台上为Dart设置执行环境. 使用DartPad在线执行脚本 您可以使用https://dartpad.dartlang.org/上的在线编辑器在线测试您的脚本.Dart编辑 ...

  10. Ruby 环境

    Ruby 环境 本地环境设置 如果您想要设置 Ruby 编程语言的环境,请阅读本章节的内容.本章将向您讲解与环境设置有关的所有重要的主题.建议先学习下面几个主题,然后再进一步深入学习其他主题: Lin ...