软件构造 第七章第四节 调试

第七章第四节
调试

【bug的常见类型】

  • 数学bug:例如
    零除法,算术溢出
  • 逻辑bug:例如 无线循环和无限递归
  • 源头bug:例如 使用了为被定义的变量、资源泄漏,其中有限的系统资源如内存或文件句柄通过重复分配耗尽而不释放。缓冲区溢出,其中程序试图将数据存储在分配存储的末尾。
  • 团队工程bug:例如 评论过时或者评论错误、文件与实际产品的区别

## 调试的基本过程

  • Debug是测试的后续步骤:测试发现问题,debug消除问题;当防御式编程和测试都无法挡住bug时,我们就必须进行debug了;
  • Debug的目的:寻求错误的根源并消除它;(Debug占用了大量的时间)

【调试的过程】

  • 常用方法:假设-检验
  • 重现(Reproduce)-->诊断(Diagnose/Locating)-->修复(Fix)-->反思(Reflect)
  • 重现(Reproduce):寻找一个可靠、方便得在线需求问题的方法。

    • 从最小的测试用例开始复现错误(保持复现bug的前提下降低输入规模)
    • 消除因版本、环境、配置等不同引起的差异(通过构建软件实现),确定bug出现的环境(通过程序模拟硬件平台的细节,实现不同的操作系统环境)
    • 利用逆向设计推断导致错误的输入
    • 若无法重现,则无法观察以证明分析和修补的正确性
  • 诊断(Diagnose/Locating):构建假设,并通过执行实验来测试它们,直到您确信已识别错误的根本原因。

    • 从假设开始,构造实验,证明它是对的或者错的
    • 从不符合理论的观察结果开始,修正理论
    • 查看导致错误的测试输入,以及错误的结果,失败的断言以及由此导致的堆栈跟踪
    • 提出一个与所有数据一致的假设,说明错误发生的位置或错误发生的位置,设计实验测试假设
    • 收集实验数据,减少错误可能出现的范围,做出新的假设
    • 设计不同的实验:检查内部状态、修改运行方式、改变本身逻辑 
    • 每次只做一个修改、做好记录、不忽略细节、运行不同的测试用例、设置断点、用可实现相同功能并且被证实无问题的组件替代当前组件
  • 修复(Fix):设计和实施解决问题的变化,避免引入回归,并保持或提高软件的整体质量。

    • 确保从干净的源代码树开始
    • 运行现有的测试,并证明它们通过
    • 添加一个或多个新测试,或修复现有测试,以演示错误
    • 修复错误、发现可改进之处
    • 证明你的修复工作正常且没有引入回归(以前通过的测试现在失败)
    • 如果引入回归,通过回顾以前的版本来找出确切的变化
  • 反思(Reflect):思考需求、设计、测试、结构(库、编译器等)

原文地址:https://www.cnblogs.com/masteryellow/p/9215635.html

时间: 2024-08-08 20:58:41

软件构造 第七章第四节 调试的相关文章

软件构造 第七章第二节 错误与异常处理

第七章第二节 错误与异常处理 内部错误:程序员通常无能为力,一旦发生,想办法让程序优雅的结束 异常:你自己程序代码发生的,可以捕获处理 [Error] Error类描述很少发生的Java运行时系统内部的系统错误和资源耗尽情况(例如,VirtualMachineError,LinkageError). 对于内部错误:程序员通常无能为力,一旦发生,想办法让程序优雅的结束 Error的类型: 用户输入错误 例如:用户要求连接到语法错误的URL,网络层会投诉. 设备错误 硬件并不总是做你想做的. 输出器

软件构造 第七章第三节 断言和防御性编程

第七章第三节 断言和防御性编程 断言:在开发阶段的代码中嵌入,检验某些"假设"是否成立.若成立,表明程序运行正常,否则表明存在错误. 可用于检查: 内部不变量: 表示不变量: 控制流不变量 方法的前置条件 方法的后置条件 断言主要用于开发阶段,避免引入和帮助发现bug 实际运行阶段, 不再使用断言 软件发布阶段,禁用断言避免影响性能. 断言?Correctness 错误/异常处理?Robustness Defensive Programming 对来自外部的数据源要仔细检查,例如:文件

软件构造 第三章第五节 ADT和OOP中的等价性

第三章第五节 ADT和OOP中的等价性 1.==与equals ==是引用等价性 :而equals()是对象等价性. == 比较的是索引.更准确的说,它测试的是指向相等(referential equality).如果两个索引指向同一块存储区域,那它们就是==的.对于我们之前提到过的快照图来说,==就意味着它们的箭头指向同一个对象. equals()操作比较的是对象的内容,换句话说,它测试的是对象值相等(object equality).在每一个ADT中,equals操作必须合理定义 2.等价性

Git帮助文档阅读笔记----第二章-第四--节远程仓库的使用

管理这些远程仓库,以便推送或拉取数据 添加远程库 移除废弃的远程库 管理各式远程库分支 定义是否跟踪分支 查看当前的远程库 可以用 git remote 命令,它会列出每个远程库的简短名字 也可以加上 -v 选项(译注:此为 --verbose 的简写,取首字母),显示对应的克隆地址: 如果有多个远程仓库,此命令将全部列出.比如在我的 Grit 项目中,可以看到: 添加远程仓库 要添加一个新的远程仓库,可以指定一个简单的名字,以便将来引用,运行 git remote add [shortname

软件构造 第三章第三节 抽象数据型(ADT)

软件构造 第三章第三节 抽象数据型(ADT) Creators(构造器): 创建某个类型的新对象,?个创建者可能会接受?个对象作为参数,但是这个对象的类型不能是它创建对象对应的类型.可能实现为构造函数或静态函数.(通常称为工厂方法) t* ->  T 例子:Integer.valueOf( ) Producers(生产器): 通过接受同类型的对象创建新的对象. T+ , t* -> T 例子:String.concat( ) Observers(观察器): 获取抽象类型的对象然后返回一个不同类

【软件构造】第二章第二节 软件构造的过程、系统和工具

第二章第二节 软件构造的过程.系统和工具 Outline 广义的软件构造过程 编程 静态代码分析 动态代码分析 调试与测试 重构 狭义的软件构造过程 构造系统:经典BUILD场景 构造系统的组件 构造过程和构造描述 Java编译工具 子目标和结构变体 构造工具 Notes ## 广义的软件构造过程 [编程(Coding)] 开发语言:如Java.C.Python 使用IDE(集成开发工具)的优势(组成) 方便编写代码和管理文件(有代码编辑器,代码重构工具.文件和库(Library)管理工具) 能

【软件构造】第一章 软件构造基础(2)

二.软件构造的质量目标 1. 外部属性(主要):影响用户感受,如外观.速度等 (1)正确性:符合规格范围和计划目标 ·只保证各个层面的正确性(假设调用正确) ·检验与调试 ·防御性编程 ·形式化编程 (2)健壮性:响应规格范围外的异常情况 ·提示错误信息 ·正常退出或降级 (3)可扩展性:提供增加新功能的空间 ·固化需求以规避风险 ·设计简洁.离散化 (4)可复用性:使软件模块能够被其他程序使用 ·模式固化 (5)兼容性:跨平台.跨软件交互 ·使用标准文件格式.数据结构.接口,保持一致性 ·定义

软件构造 第五章第一节 可复用性的度量、形态和外部观察

第五章第一节  可复用性的度量.形态和外部观察 面向复用编程(programming for reuse):开发出可复用的软件 基于复用编程(programming with reuse):利用已有的可复用软件搭建应用系统 代码复用的类型: 白盒复用:源代码可见,可修改和扩展 含义:复制已有代码到正在开发的系统,进行修改 优点:可订制化程度高 缺点:对其修改增加了软件的复杂度,且需要对其内部充分的了解 黑盒服用:源代码不可见,不能修改 含义:只能通过过API接口来使用,无法修改代码 优点:清晰.

软件构造 第三章第二节 软件规约

第三章第二节 软件spec 客户端无需阅读调用函数的代码,只需理解spec即可. 精确的规约,有助于区分责任,给"供需双方"确定了责任,在调用的时候双方都要遵守. @param @return @throws 例子: Behavioral equivalence (行为等价性) 根据规约判断是否行为等价 与实现无关! 如果两个函数符合这个规约,故它们等价. Specification Structure 前置条件(precondition):对客户端的约束,在使用方法时必须满足的条件.