1. 逻辑错误:条件判断或边界值错误
问题:age >= 60 错误地将 60 岁包含在折扣范围内,但实际需求是超过 60 岁才享受。
黑盒测试局限:若测试用例未覆盖 age=60,功能可能“看似正常”。
代码走读:直接审查条件逻辑,发现与需求不符。
// 示例:边界值误用(应排除 age=60)
public class DiscountService {
public double getDiscount(int age) {
if (age >= 60) { // 错误!需求是 age > 60 才享受折扣
return 0.8;
} else {
return 1.0;
}
}
}
2. 死代码:永远不会执行的逻辑
问题:if (false) 导致代码块永远不会执行,可能是调试残留代码。
黑盒测试局限:无法感知未执行的代码路径。
代码走读:直接发现冗余代码。
// 示例:条件永远为假的代码块
public class DataProcessor {
public void process(String data) {
if (false) { // 条件永远为假
System.out.println("Processing data: " + data); // 死代码
}
// 真实逻辑...
}
}
3. 资源泄漏:未关闭文件/数据库连接
问题:FileInputStream
未关闭,导致文件句柄泄漏。
黑盒测试局限:短期功能正常,长期运行后系统可能崩溃。
代码走读:直接检查资源释放逻辑。
// 示例:文件流未关闭
import java.io.FileInputStream;
import java.io.IOException;
public class FileReader {
public void readFile(String path) {
try {
FileInputStream fis = new FileInputStream(path); // 打开文件流
int data = fis.read();
// 忘记调用 fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
4. 安全漏洞:硬编码密码或 SQL 注入
问题:
密码明文硬编码。
用户输入直接拼接 SQL 语句,存在注入风险。
黑盒测试局限:功能测试可能通过,但无法发现安全漏洞。
代码走读:直接暴露敏感信息和 SQL 拼接问题。
// 示例:硬编码密码 + SQL 注入
import java.sql.*;
public class UserService {
private static final String DB_PASSWORD = "admin123"; // 硬编码密码
public boolean login(String username, String password) {
String query = "SELECT * FROM users WHERE username='" + username
+ "' AND password='" + password + "';"; // SQL 注入风险
try (Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/db", "user", DB_PASSWORD);
Statement stmt = conn.createStatement()) {
ResultSet rs = stmt.executeQuery(query);
return rs.next();
} catch (SQLException e) {
return false;
}
}
}
5. 并发问题:竞态条件(Race Condition)
问题:count++
是非原子操作,多线程并发时结果不可预测。
黑盒测试局限:并发问题难以稳定复现。
代码走读:直接发现缺少同步机制(如 synchronized
或 AtomicInteger
)。
// 示例:非线程安全的计数器
public class Counter {
private int count = 0;
public void increment() {
count++; // 非原子操作,多线程下可能丢失更新
}
public int getCount() {
return count;
}
}
6. 代码规范问题:命名混乱或冗余
问题:
方法名 a
和参数名 b
无法表达意图。
变量 c
冗余,可直接返回 b + 1
。
黑盒测试局限:功能正确,但代码可维护性差。
代码走读:直接暴露代码“坏味道”。
// 示例:无意义的命名和冗余代码
public class BadCode {
public int a(int b) { // 方法名和参数名无意义
int c = b + 1; // 冗余变量
return c;
}
}
7. 异常处理缺失
问题:异常未被正确处理(如重试或抛出),导致功能静默失败。
黑盒测试局限:若未模拟文件不存在的情况,问题无法暴露。
代码走读:直接发现异常处理不完整。
// 示例:未处理可能的异常
public class FileService {
public void readFile(String path) {
try {
FileInputStream fis = new FileInputStream(path);
fis.read();
fis.close();
} catch (IOException e) {
// 仅打印日志,未处理异常
System.out.println("Error: File not found");
}
}
}
8.函数意外修改全局状态
问题:init()
方法修改了全局配置,但未在接口中声明。
黑盒测试局限:若其他模块依赖 timeout
的初始值,问题可能被忽略。
代码走读:直接发现对全局状态的隐式修改。
// 示例:函数意外修改全局状态
public class GlobalConfig {
private static int timeout = 1000;
public static void init() {
timeout = 500; // 意外修改全局配置
}
}
- 算法低效
问题:使用冒泡排序而非更高效的算法(如快速排序)。
黑盒测试局限:功能正确,但性能差。
代码走读:直接发现低效算法设计。
// 示例:低效的 O(n²) 算法
public class InefficientSort {
public void sort(int[] array) {
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array.length; j++) {
if (array[i] < array[j]) {
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
}
}
}
10. 数值类型溢出或精度丢失
问题:未处理数值溢出,可能导致业务逻辑错误(如金融计算)。
代码走查如何发现:
审查者会注意数值范围(如 int 是否足够,是否需要改用 long)。
发现未做溢出校验的算术操作。
public class OverflowExample {
public void process() {
int a = Integer.MAX_VALUE;
int b = a + 1; // 溢出(实际值为 Integer.MIN_VALUE)
System.out.println(b); // 输出 -2147483648
}
}