—— 当 AI 写得比你快,你靠什么赢?不是手速,是判断力。
🚨 前言:AI 是加速器,不是导航仪
❗ 残酷真相:
用 AI 写代码 ≠ 会写代码;
能跑 ≠ 能上线;
绿色测试 ≠ 安全上线。
当 Prompt 工程师遍地开花,真正的高手正在做三件事:
✅ 精准喂 Context(不是喂垃圾)
✅ 严查 Supply Chain(不是信 AI 推荐)
✅ 重构「AI 原稿」为「生产级代码」(不是 Ctrl+V)
下面,我们用 7 个实战习惯 + 代码示例,教你从「AI 用户」蜕变为「AI 驾驶员」。
🔑 习惯 1:拿名字赌尊严 —— 你的代码,你负责
🩹 AI 原稿:电商风控规则引擎(脆弱版)
// ❌ AI 生成:用 CompletableFuture.allOf 实现风控三查
public RiskCheckResult checkOrderRisk(Order order) {
var idCheck = CompletableFuture.supplyAsync(() -> idService.verify(order.getUserId()));
var addrCheck = CompletableFuture.supplyAsync(() -> addressService.isHighRisk(order.getAddress()));
var deviceCheck = CompletableFuture.supplyAsync(() -> deviceService.analyze(order.getDeviceId()));
CompletableFuture.allOf(idCheck, addrCheck, deviceCheck).join(); // 全挂则挂!
return new RiskCheckResult(
idCheck.get(),
addrCheck.get(),
deviceCheck.get()
);
}
问题在哪?
- 任一服务超时/失败 → 整单风控中断 → 用户无法下单
- 无超时控制 → 线程被慢服务卡死
.get()二次抛异常 → 日志难追溯
✅ 人类重构:弹性 + 降级 + 可观测
// ✅ 人类优化:Java 21 + 虚拟线程 + 降级策略
public RiskCheckResult checkOrderRisk(Order order) {
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
var idFuture = safeAsync(() -> idService.verify(order.getUserId()), 1_000, true);
var addrFuture = safeAsync(() -> addressService.isHighRisk(order.getAddress()), 1_500, false);
var deviceFuture = safeAsync(() -> deviceService.analyze(order.getDeviceId()), 2_000, false);
return new RiskCheckResult(
idFuture.join(), // 实名必须成功,否则阻断
addrFuture.join(), // 地址失败 → 降级为 false(低风险)
deviceFuture.join() // 设备失败 → 降级为 UNKNOWN
);
}
}
// 通用弹性封装
private <T> CompletableFuture<T> safeAsync(
Supplier<T> task, long timeoutMs, T fallbackOnFail) {
return CompletableFuture
.supplyAsync(task)
.orTimeout(timeoutMs, TimeUnit.MILLISECONDS)
.exceptionally(e -> {
log.warn("Risk check failed", e);
return fallbackOnFail;
});
}
💡 关键差异:
- 虚拟线程资源友好
- 按业务重要性分级降级
- 统一异常处理 + 日志
- 你写的不是代码,是 SLA 承诺
🔑 习惯 2:喂 Context,别喂 Prompt
🧠 AI 是「上下文压缩机」,不是「需求猜测机」
❌ 低效 Prompt:
// 给 AI 的指令:
// 实现一个运费计算方法
→ AI 产出:基于重量的 5 元基础运费(完全忽略你的多仓、会员、跨境规则)
✅ 高效 Context:
/*
* JIRA: LOGISTICS-102 【多仓动态运费】
*
* 业务规则:
* - 同城仓(30km 内):免运费(所有用户)
* - 跨城仓(≤300km):
* • 金牌会员:免运费
* • 普通会员:满 99 免运费,否则 8 元
* - 跨省/跨境:固定 25 元 + 15% 关税(仅跨境)
*
* 数据模型:
* class User { Tier tier(); } // enum Tier { BRONZE, GOLD }
* class Order { List<Item> items(); Warehouse from(); Address to(); }
* class Warehouse { GeoPoint location(); }
* class GeoPoint { double lat(), lng(); }
*
* 工具类:
* DistanceCalculator.distance(Warehouse w, Address a) // 返回 km
*
* 要求:
* - 返回 FreightCost 对象,含 base + tax + discount
* - 支持未来扩展(策略模式)
*/
✅ AI 生成 + 人类微调:
public record FreightCost(BigDecimal base, BigDecimal tax, BigDecimal discount) {
public BigDecimal total() {
return base.add(tax).subtract(discount); }
}
public FreightCost calculateFreight(User user, Order order) {
double km = DistanceCalculator.distance(order.from(), order.to());
if (km <= 30) {
return new FreightCost(BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO);
}
if (km <= 300) {
BigDecimal base = user.tier() == GOLD ? BigDecimal.ZERO : new BigDecimal("8.00");
BigDecimal discount = order.subtotal().compareTo(new BigDecimal("99")) >= 0
? (user.tier() == BRONZE ? base : BigDecimal.ZERO)
: BigDecimal.ZERO;
return new FreightCost(base, BigDecimal.ZERO, discount);
}
// 跨省/跨境
BigDecimal base = new BigDecimal("25.00");
BigDecimal tax = "CN".equals(order.to().country())
? BigDecimal.ZERO
: order.subtotal().multiply(new BigDecimal("0.15"));
return new FreightCost(base, tax, BigDecimal.ZERO);
}
✅ 结果:
- 10 分钟写完 + 90% 准确
- 剩下 10%:人类加
@VisibleForTesting、边界 case 补充- 你省下的不是时间,是返工成本
🔑 习惯 3:防「代码泥球」—— 拒绝 clever,拥抱 boring
⚠️ Stream 的三大幻觉:
- “一行搞定” = 可读
- “函数式” = 无副作用
- “AI 生成” = 可维护
❌ AI 的「炫技流」:
// ❌ 用 Stream 处理物流单状态机(副作用藏在 peek 里!)
List<Shipment> updated = shipments.stream()
.filter(s -> s.status() == PENDING)
.peek(s -> {
if (s.isCOD()) paymentService.collect(s.amount()); // 💣 隐式支付!
smsService.send(s.customerPhone(), "Your order is shipped!");
})
.map(s -> s.withStatus(SHIPPED))
.collect(Collectors.toList());
repository.saveAll(updated);
✅ 人类选择:清晰循环 + 显式边界
// ✅ boring but robust
List<Shipment> toUpdate = new ArrayList<>();
for (Shipment s : shipments) {
if (s.status() != PENDING) continue;
try {
// 显式拆解:支付 → 通知 → 更新
if (s.isCOD()) {
paymentService.collect(s.amount()); // 可独立回滚
}
smsService.send(s.customerPhone(), "Your order is shipped!");
toUpdate.add(s.withStatus(SHIPPED));
} catch (PaymentException e) {
log.error("Payment failed for shipment {}", s.id(), e);
// 单条失败不影响其他
}
}
repository.saveAll(toUpdate);
🎯 Why boring wins:
- 断点可设在任何一行
- 异常可按业务单元隔离
- 新人 30 秒看懂逻辑
- 维护成本 ≈ 0
🔑 习惯 4:打扫房间 —— 清理「数字垃圾」
❌ AI 推荐的依赖(高危!):
<!-- ❌ AI 说这是 "latest CSV parser" -->
<dependency>
<groupId>com.github.super-csv</groupId>
<artifactId>super-csv-jdk7</artifactId> <!-- 实际已废弃 8 年! -->
<version>2.4.0</version>
</dependency>
✅ 安全操作三步:
- 查源:去 Maven Central 搜
super-csv - 看维护:最新版是
4.0.0,groupId 为net.sf.supercsv - 验漏洞:用
mvn org.owasp:dependency-check-maven:check
<!-- ✅ 正确姿势 -->
<dependency>
<groupId>com.univocity</groupId>
<artifactId>univocity-parsers</artifactId> <!-- 活跃维护 + Apache 2.0 -->
<version>2.9.1</version>
</dependency>
🔒 黄金法则:
永远不要复制 AI 给的<dependency>—— 它可能来自 2014 年的 StackOverflow 评论区
🔑 习惯 5:三重审查制 —— AI、Code、Supply Chain
| 审查层 | 工具建议 | 检查重点 |
|---|---|---|
| AI 系统 | GitHub Copilot Business / CodeWhisperer Enterprise | 是否泄露私有代码?是否支持私有模型? |
| 生成代码 | SonarLint + SpotBugs + 人工读三遍 | - 是否用 String 存密码?- 是否 try 里写 return?- 是否 Java 8 写法(该用 record/sealed)? |
| 依赖链 | OWASP DC + Snyk + 人工查 LICENSE | - 是否 GPL/AGPL? - 是否含 Log4j 1.x? - 是否被 npm 包投毒仿冒?(如 spring-boot-startr) |
🚨 真实案例:AI 推荐「高效 JSON 库」
// ❌ AI: "Use fastjson2 for best performance!"
// 你:直接加依赖 → 中招 CVE-2024-1234(RCE 漏洞)
// ✅ 正确做法:
// 1. 查 fastjson2 GitHub → 发现 2.0.46 已修复
// 2. 升级:
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>2.0.53</version> <!-- latest safe -->
</dependency>
// 3. 配置全局 safeMode
JSON.config(JSON.DEFAULT_PARSER_FEATURE, Feature.SafeMode.mask);
🔑 习惯 6:测试 ≠ 覆盖率,而是「信心度」
❌ 无意义的 100% 覆盖:
@Test
void testCalculateScore() {
// AI 生成:覆盖所有分支,但无业务意义
assertEquals(100, scoreService.calculate(null, 0));
assertEquals(80, scoreService.calculate("A", 1));
assertEquals(60, scoreService.calculate("B", 2));
}
✅ 有意义的集成测试(Testcontainers + 真 DB):
@SpringBootTest
@Testcontainers
class OrderServiceIT {
@Container
static MySQLContainer<?> mysql = new MySQLContainer<>("mysql:8.0")
.withInitScript("schema.sql"); // 含真实索引/约束
@Test
void concurrentOrderCreationDoesNotDuplicate() throws InterruptedException {
// 模拟 10 用户抢购最后 1 件库存
var latch = new CountDownLatch(10);
var results = new CopyOnWriteArrayList<Order>();
for (int i = 0; i < 10; i++) {
new Thread(() -> {
try {
results.add(orderService.createOrder("PROD-001", 1));
} finally {
latch.countDown();
}
}).start();
}
latch.await(5, TimeUnit.SECONDS);
// 断言:仅 1 单成功,其余 9 抛库存不足异常
long success = results.stream().filter(Objects::nonNull).count();
assertThat(success).isEqualTo(1);
}
}
✅ 这测试能发现:
- 乐观锁失效
@Transactional隔离级别错误- DB 死锁
- 而 Mock 测试永远不能
🔑 习惯 7:Code Review 是「设计对话」,不是「找茬大赛」
❌ 旧时代 Review:
“Line 42:变量名
tmp→ 改为tempResult”
“Line 67:空行多了 1 行”
✅ 新时代 Review :
👋 “Hi,这个缓存用了 Caffeine,很棒!有个架构问题想讨论:
当前是本地缓存,但我们的订单服务是 3 节点集群。
如果管理员在后台改了商品价格,可能有 2 分钟各节点看到不同价格。
我们是否考虑:
- 方案 A:加 Redis 缓存(需改 2 天)
- 方案 B:接受最终一致(加文档说明)
- 方案 C:用 Kafka 广播失效事件(适合高一致性场景)
你怎么看?”💬 这才是 Review 的本质:
- 分享经验
- 对齐架构
- 让代码有「人味」
🌈 结语:AI 时代,人类开发者更值钱
🔮 未来已来:
- 初级:用 AI 写 CRUD
- 中级:用 AI 写 Service
- 高级:用 AI 写 Spec + Review AI 的 Code
你无法阻止 AI 写代码,但你能决定——
✅ 它写的是「能跑的 demo」,还是「能扛双 11 的系统」
✅ 它引入的是「技术债」,还是「可演进架构」
“AI 是副驾,方向盘,永远在你手里。”