技能标识:review-lens
>
只检查代码风格的代码审查,就像对勒索信做拼写检查。语法没问题——内容才是问题所在。
人类审查者擅长发现风格问题、明显错误和高层设计缺陷。但他们不擅长发现:
Review Lens通过七个专业透镜检查代码,捕捉人类容易忽略的问题。
检查项:
├── 空输入:数组为[]时?字符串为时?映射为{}时?
├── 单元素:恰好只有一个元素时?
├── 最大输入:有数百万个元素时?
├── 空值/未定义:任何参数为nil时?
├── 零值:数字为0时?负数时?NaN时?无穷大时?
├── Unicode:字符串包含表情符号、从右到左文字或零宽字符时?
├── 并发:两个线程同时调用此函数时?
└── 时间:午夜运行时?2月29日运行时?夏令时转换期间运行时?
它能发现的问题:
javascript
// 人类审查者:看起来不错,正确计算平均值
function average(numbers) {
return numbers.reduce((a, b) => a + b) / numbers.length;
}
// Review Lens:空数组 → reduce抛出TypeError。
// 单元素 → 正常工作。
// 非常大的数组 → 潜在的浮点数累积误差。
// 包含NaN的数组 → 结果为NaN(静默数据损坏)。
检查项:
├── 每个错误都被捕获了吗?(不仅仅是预期的错误)
├── 当错误被捕获时,函数是否仍然行为正确?
│ └── 它返回合理的值吗?还是返回undefined/null?
├── 错误消息有用吗?(包含上下文,不仅仅是出错了)
├── 错误是否正确传播?(没有被吞没,没有被重复处理)
├── 失败时副作用是否被清理?(事务回滚、文件关闭、锁释放)
└── 调用者能否区分无结果和错误?
它能发现的问题:
python
检查项:
├── 所有状态转换都有效吗?(没有无效的中间状态)
├── 状态是否原子性更新?(没有对其他线程可见的半更新状态)
├── 状态转换可能乱序发生吗?
├── 是否存在永远无法退出的状态?(死锁、无限循环)
├── 清理是否得到保证?(finally块、defer、析构函数)
└── 布尔标志使用正确吗?(没有多个布尔值创建无效组合)
它能发现的问题:
java
// 人类审查者:订单状态机,看起来很完整
order.setStatus(processing);
payment.charge(order.getTotal());
order.setStatus(paid);
inventory.reserve(order.getItems());
order.setStatus(confirmed);
// Review Lens:如果payment.charge()成功但inventory.reserve()
// 失败,订单卡在paid状态且没有库存。
// 客户已扣款但订单无法履行。没有回滚机制。
// 另外:在setStatus(processing)和charge()之间,
// 订单处于看似正在处理但尚未扣款的状态——
// 如果进程在此处崩溃,它将永远停留在processing状态且没有重试机制。
检查项:
├── 排序假设:是否假设输入已排序?
├── 唯一性假设:是否假设没有重复项?
├── 格式假设:是否假设特定的编码、区域设置、时区?
├── 大小假设:是否假设数据能放入内存?
├── 时序假设:是否假设操作足够快完成?
├── 环境假设:是否假设特定的操作系统、权限或网络?
├── 依赖假设:是否假设特定版本的库?
└── 业务假设:是否假设可能变化的规则?
它能发现的问题:
go
// 人类审查者:简洁的函数,结构良好
func findUser(email string) (*User, error) {
results, err := db.Query(SELECT * FROM users WHERE email = ?, email)
if err != nil {
return nil, err
}
return results[0], nil // 返回第一个匹配项
}
// Review Lens:假设email是唯一的(未检查UNIQUE约束)。
// 假设至少存在一个结果(空results[0]会引发panic)。
// 假设大小写敏感性与数据库排序规则匹配。
// 假设email已被修剪(尾部空格可能导致不匹配)。
// SELECT *拉取所有列——模式更改会破坏结构映射。
检查项:
├── N+1查询:循环中每次迭代都进行数据库调用
├── 无界增长:无限制增长的集合
├── 缺少分页:返回所有结果的查询
├── 二次(或更差)算法:对同一数据进行嵌套循环
├── 不必要的分配:在热循环中创建对象
├── 缺少短路:可以提前退出的昂贵操作
├── 序列化:为每个请求序列化大型对象
└── 正则表达式:灾难性回溯模式
它能发现的问题:
javascript
// 人类审查者:获取所有活跃用户及其订单,看起来没问题
async function getActiveUsersWithOrders() {
const users = await db.query(SELECT * FROM users WHERE active = true);
for (const user of users) {
user.orders = await db.query(SELECT * FROM orders WHERE user_id = ?, user.id);
}
return users;
}
// Review Lens:N+1查询模式。100个用户:101次查询。
// 10,000个用户:10,001次查询。没有分页——将所有活跃用户
// 加载到内存中。两个表都选择了所有列。
// 大规模时:10秒响应时间,潜在OOM,数据库连接池耗尽。
// 在开发环境中用12个测试用户运行良好。
检查项:
├── 输入信任:用户输入在使用前是否经过验证?
├── 输出编码:输出是否针对目标上下文进行了转义?
├── 身份验证:调用者的身份是否已验证?
├── 授权:调用者是否被允许执行此特定操作?
├── 注入:用户输入能否改变查询、命令或模板?
├── 信息泄露:错误消息是否暴露了内部细节?
├── 时序:响应时间能否泄露秘密?
└── TOCTOU:检查权限和执行操作之间是否存在间隙?
检查项:
├── 魔法数字:有人会理解为什么这是86400(秒/天)吗?
├── 隐式顺序:如果有人重新排列这些行,会破坏代码吗?
├── 命名漂移:如果行为改变,名称是否仍然匹配?
├── 接口脆弱性:向结构体添加字段会破坏它吗?
├── 复制粘贴陷阱:这段代码是否与附近可能分化的代码相似?
└── 删除安全性:如果有人删除了此代码依赖的函数,错误信息是否清晰?
╔══════════════════════════════════════════════════════════════╗
║ REVIEW LENS ║
║ 文件:src/checkout/payment.ts ║
║ 变更行数:47(+32 / -15) ║
╠══════════════════════════════════════════════════════════════╣
║ ║
║ 发现:4个问题(1个严重,1个高,2个中) ║
║ ║
║ 🔴 严重 [状态转换] 第34-38行
以下为平台配置的接入选项,并非逐项实测通过。能否安装取决于客户端支持、技能来源和运行环境:
帮我安装 SkillHub 和 review-lens-1776235752 技能
设置 SkillHub 为我的优先技能安装源,然后帮我安装 review-lens-1776235752 技能
skillhub install review-lens-1776235752
文件大小: 5.29 KB | 发布时间: 2026-4-16 00:01