《软件调试修炼之道》Part 1(CH1~5)读书笔记 PB16110698 第八周(~4.26)
编程中,调试几乎是必不可少的,一劳永逸、一次完成预想功能而完全不出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)的更多相关文章
- 《代码整洁之道》ch1~ch4读书笔记 PB16110698 (~3.8 第一周)
<代码整洁之道>ch1~ch4读书笔记 <clean code>正如其书名所言,是一本关于整洁代码规范的“教科书”.作者在书中通过实例阐述了整洁代码带来的种种利处以及混乱代码 ...
- 《移山之道》第十一章:两人合作 读书笔记 PB16110698 第六周(~4.15)
本周在考虑阅读材料时,我翻阅了<移山之道>,正好看到这一章:两人合作,心想:正好,我们正值结对作业的紧要关头,书中两人合作的宝贵经验和教诲应当对我们有很大帮助.于是,我开始一边在ddl苦 ...
- 《代码整洁之道》ch5~ch9读书笔记 PB16110698(~3.15) 第二周
<代码整洁之道>ch5~ch9读书笔记 本周我阅读了本书的第5~9章节,进一步了解整洁代码需要注意的几个方面:格式.对象与数据结构.错误处理.边界测试.单元测试和类的规范.以下我将分别记录 ...
- 《Linux内核设计与实现》读书笔记(十八)- 内核调试
内核调试的难点在于它不能像用户态程序调试那样打断点,随时暂停查看各个变量的状态. 也不能像用户态程序那样崩溃后迅速的重启,恢复初始状态. 用户态程序和内核交互,用户态程序的各种状态,错误等可以由内核来 ...
- 软件开发-MSF方法(《构建之法》读书笔记2)
MSF-微软解决方案框架,是一套大型系统开发指南,它描述了如何用组队模型.过程模型和应用模型来开发Client/Server结构的应用程序,是在微软的工具和技术的基础上建立并开发分布式企业系统应用的参 ...
- <《巴菲特之道 (第三版)》>读书笔记
以便宜的价格买入长期绩优的股票 他把对公司的投资看做是拥有公司的一部分股权,看重的是公司的长期经济价值 别人越是草率,我们越要加倍慎重 如果你发现自己已经在陷阱中,最重要的是想办法让自己不要再往下陷 ...
- 《单元测试之道Java版》的读书笔记
总览 第2章 首个单元测试 第3章 使用JUnit编写测试 3.1 构建单元测试 3.2 JUnit的各种断言 3.3 JUnit框架 4. 测试什么? 5.CORRECT(正确的)边界条件 6.使用 ...
- <读书笔记>软件调试之道 :从大局看调试-理想的调试环境
声明:本文档的内容主要来源于书籍<软件调试修炼之道>作者Paul Butcher,属于读书笔记.欢迎转载! ---------------------------------------- ...
- <读书笔记>软件调试之道 :从大局看调试-零容忍策略
声明:本文档的内容主要来源于书籍<软件调试修炼之道>作者Paul Butcher,属于读书笔记.欢迎转载! ---------------------------------------- ...
随机推荐
- ( 转)WPF面板布局介绍Grid、StackPanel、DockPanel、WrapPanel
回顾 上一篇,我们介绍了基本控件及控件的重要属性和用法,我们本篇详细介绍WPF中的几种布局容器及每种布局容器的使用场景,当 然这些都是本人在实际项目中的使用经验,可能还存在错误之处,还请大家指出. 本 ...
- MySQL数据库(一)—— 数据库介绍、MySQL安装、基础SQL语句
数据库介绍.MySQL安装.基础SQL语句 一.数据库介绍 1.什么是数据库 数据库即存储数据的仓库 2.为什么要用数据库 (1)用文件存储是和硬盘打交道,是IO操作,所以有效率问题 (2)管理不方便 ...
- ubuntu 无pthread
由于学习多线程编程,所以用到pthread,但是man的时候却发现没有pthread函数库的手册页,然后安装 $sudo apt-get install glibc-doc 安装以后,发现还是有很多函 ...
- 【二】Jmeter接口自动化测试系列之函数使用及扩展
上一篇文章我们了解了Jmeter的参数化的集中方法,虽然方法不是很多,但已经足够使用! 本篇文章,介绍一下Jmeter自带函数的使用和 函数扩展,来满足测试工作中的各种需求! Jmeter自带函数 点 ...
- 自从阿里买了Flink母公司以后,你不懂Flink就out了!
个免费报名权限 Ps:小助理手动给大家发送资料,精力有限,仅限前100名免费领取,这份资料对于想要提升大数据技能进阶的小伙伴来说,将会是一份不可或缺的宝贵资料. 特别感谢飞总的部分原创支持!
- Android USB Host 与 HID 之通讯方法(bulkTransfer()与controlTransfer()方法使用)
转载地址:差满多乃几 Android USB Host与HID通讯,就目前Google Developer提供的方法有bulkTransfer()与controlTransfer(),看是简简单单的两 ...
- @value传值到static字段
解决办法: 1.将这两个私有属性的set方法从私有变成公开(private -->>> public); 2.生成这两个静态属性的set方法: 3.将原来在静态属性上的@Value( ...
- 2019-9-25-如何让-USB-设备不显示安全删除硬件弹出选项
title author date CreateTime categories 如何让 USB 设备不显示安全删除硬件弹出选项 lindexi 2019-09-25 11:58:19 +0800 20 ...
- React简单入门
各位圆友,新年好!!! 使用 React 的网页源码时,首先,最后一个 <script> 标签的 type 属性为 text/babel .这是因为 React 独有的 JSX 语法,跟 ...
- 笔记54 Mybatis快速入门(五)
Mybatis中注解的使用 1.XML方式的CRUD 新增加接口CategoryMapper ,并在接口中声明的方法上,加上注解对比配置文件Category.xml,其实就是把SQL语句从XML挪到了 ...