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协助功能,在齿轮处还可以把具体的文件丢给它分析,简单高效