Java学习第二十七部分——bug检修

1. 日志调试法

Java:

// 原始问题代码

public double calculateDiscount(double price, double discount) {

return price * (1 - discount); // 当 discount > 1 时出错

}

// 修复:添加日志和验证

public double calculateDiscount(double price, double discount) {

// 添加验证日志

if (discount > 1.0) {

logger.error("无效折扣率: {}", discount);

throw new IllegalArgumentException("折扣率不能超过100%");

}

return price * (1 - discount);

}

2. 单元测试驱动修复法

Java:

// 测试用例(JUnit)

@Test

void testCalculateDiscount() {

// 正常情况

assertEquals(90, calculator.calculateDiscount(100, 0.1));

// 边界情况

assertThrows(IllegalArgumentException.class,

() -> calculator.calculateDiscount(100, 1.1));

// 极端值

assertEquals(0, calculator.calculateDiscount(100, 1.0));

}

3. 断点调试法(IDE 工具)

Java:

public void processOrder(Order order) {

int total = 0; // 在此行设置断点

for (Item item : order.getItems()) {

// 观察 item 变量值

total += item.getPrice() * item.getQuantity();

}

// 检查 total 计算是否正确

order.setTotal(total);

}

*操作步骤:*

  1. 在可疑代码行设置断点

  2. 启动 Debug 模式

  3. 使用 Step Over/Into 逐行执行

  4. 观察变量值变化

4. 代码审查法(结对编程)

python:

问题代码:缺少异常处理

def read_file(filename):

return open(filename).read()

审查后修复

def read_file(filename):

try:

with open(filename, 'r') as f:

return f.read()

except FileNotFoundError:

logger.error(f"文件不存在: {filename}")

return ""

```

5. 二分回退法(Git 操作)

bash:

定位引入 bug 的提交

git bisect start

git bisect bad # 当前版本有 bug

git bisect good v1.0 # 标记已知好版本

自动二分测试

git bisect run ./test-script.sh

找到问题提交后

git show <问题提交ID> # 查看问题代码

```

6. 静态分析工具法

Java:

// 使用 SonarQube 检测的空指针问题

public String getUserName(User user) {

return user.getName(); // 可能 NPE

}

// 修复后

public String getUserName(User user) {

return user != null ? user.getName() : "Guest";

}

```

*常用工具:*

  • Java: SpotBugs, PMD

  • JavaScript: ESLint

  • Python: Pylint

  • C/C++: Clang-Tidy

7. 监控追踪法(生产环境)

javascript:

// 添加APM监控

const apm = require('elastic-apm-node').start()

app.get('/api/data', (req, res) => {

const span = apm.startSpan('FetchData')

try {

// 业务逻辑

const data = fetchData()

span.end()

res.json(data)

} catch (err) {

apm.captureError(err) // 捕获异常

span.end()

res.status(500).send('Error')

}

})

8. 最小化复现法

python:

复杂bug -> 简化为最小可复现代码

def bug_reproducer():

剥离无关逻辑

data = [1, 2, 3]

聚焦问题操作

try:

print(data[5]) # 明确索引越界

except IndexError as e:

print(f"错误原因: {e}")

9. 外部协助法(ai和人工)

(1)代码运行错误会有详细错误信息,复制错误信息丢给ai,ai会分析问题根源和解决方案

(2)在大部分购物软件中搜索bug修改,都会有对应的bug检修人工服务,需要付费

(3)idea中有ai协助功能,在齿轮处还可以把具体的文件丢给它分析,简单高效