公司动态

【AI踩坑实录】让AI写了3个月代码,这7个坑让我返工了整整2周——附完整避坑清单

📅 2026/7/16 4:25:45
【AI踩坑实录】让AI写了3个月代码,这7个坑让我返工了整整2周——附完整避坑清单
文章目录写在前面一、坑一业务逻辑理解偏差——频次最高、后果最严重二、坑二SQL没有索引意识——开发环境飞一样线上直接崩三、坑三线程安全完全不考虑——并发场景直接翻车四、坑四异常处理只打e.printStackTrace()——上线后日志失踪五、坑五配置值硬编码——上线后改一次发一次版六、坑六缺少幂等性设计——超时重试导致重复操作七、坑七代码能跑但无法维护——技术债从第一行开始写在最后写在前面三个月前开始用AI编程工具第一周觉得这玩意儿简直是神——CRUD接口、单元测试、前端页面点几下就出来了。开发效率直接翻倍。然后上线第二周出事了。用户反馈某些操作莫名其妙没有权限。排查了4个小时定位到是AI写的权限校验代码——角色继承关系理解反了。代码逻辑是天衣无缝的但业务逻辑是全错的。修复加测试整整花了一天。从那天起我整理了一份代码审查checklist每次AI生成的代码对着过一遍。三个月下来这篇checklist帮我省了至少两周的返工时间。今天全摊给你。环境说明本文案例基于Spring Boot 3.x Spring Security项目AI工具涵盖多款主流AI编程产品。每个案例均为真实经历附详细的修复代码。一、坑一业务逻辑理解偏差——频次最高、后果最严重这就是上面提到的权限校验事故。复盘一下细节。需求很简单判断当前用户是否有权限访问某个资源要考虑角色继承。比如角色A继承角色B的权限那么拥有角色A的用户自动拥有角色B的所有权限。AI写的代码// AI生成的权限校验逻辑有问题publicbooleanhasPermission(StringresourcePath){SetStringuserRolesgetCurrentUserRoles();SetStringrequiredRolesgetRequiredRoles(resourcePath);for(Stringrequired:requiredRoles){if(userRoles.contains(required)){returntrue;}}returnfalse;}这段代码的问题在哪它只检查了用户是否直接拥有某个角色完全没有处理角色继承关系。我们是这样的层级超级管理员继承管理员的权限管理员继承编辑的权限。用户A被分配了超级管理员角色他应该也能访问只有编辑权限的资源。但上面的代码认为他不可以。修复后的代码// 修复后包含角色继承的权限校验publicbooleanhasPermission(StringresourcePath){SetStringuserRolesgetCurrentUserRoles();// 展开继承关系拿到用户拥有的所有角色直接继承SetStringexpandedRolesroleHierarchyService.expandRoles(userRoles);SetStringrequiredRolesgetRequiredRoles(resourcePath);for(Stringrequired:requiredRoles){if(expandedRoles.contains(required)){returntrue;}}returnfalse;}修复成本定位4小时 修复1小时 回归测试2小时 半天没了。避坑方法涉及业务规则的代码在给AI提需求时显式列出所有规则不要让AI猜。比如“判断权限时需要通过RoleHierarchyService.expandRoles()展开用户的全部角色直接分配继承获取的然后再判断。”二、坑二SQL没有索引意识——开发环境飞一样线上直接崩这个坑是隐形的。开发环境数据少完全测不出来。需求商品列表查询支持按名称模糊搜索、按分类筛选、按价格区间筛选、分页。AI生成的JPA Repository// AI生成的Repository有问题RepositorypublicinterfaceProductRepositoryextendsJpaRepositoryProduct,Long{Query(SELECT p FROM Product p WHERE (:name IS NULL OR p.name LIKE %:name%) AND (:category IS NULL OR p.category :category) AND (:minPrice IS NULL OR p.price :minPrice) AND (:maxPrice IS NULL OR p.price :maxPrice))PageProductsearch(Param(name)Stringname,Param(category)Stringcategory,Param(minPrice)BigDecimalminPrice,Param(maxPrice)BigDecimalmaxPrice,Pageablepageable);}看着没问题对吧但表上只有一个主键索引。模糊搜索LIKE %:name%根本走不了索引全表扫描。500条数据0.03秒5万条数据1.8秒50万条数据直接超时修复-- 手动加联合索引ALTERTABLEproductADDINDEXidx_product_search(category,name);-- 注意LIKE %keyword% 前缀通配导致索引失效改用全文索引或ES-- 如果模糊搜索是核心功能建议引入ElasticsearchALTERTABLEproductADDFULLTEXTINDEXft_name(name);避坑方法AI生成SQL后EXPLAIN跑一遍。如果type列是ALL全表扫描必须处理。另外明确告诉AI表上已有的索引名称。三、坑三线程安全完全不考虑——并发场景直接翻车这个坑最隐蔽因为单线程测试永远测不出来。让AI写一个商品浏览计数器// AI生成的计数器有问题ServicepublicclassViewCountService{privateMapLong,IntegerviewCountMapnewHashMap();publicvoidincrement(LongproductId){IntegercountviewCountMap.getOrDefault(productId,0);viewCountMap.put(productId,count1);}publicIntegergetCount(LongproductId){returnviewCountMap.getOrDefault(productId,0);}}HashMap在并发场景下会出什么问题两个线程同时put可能导致循环链表CPU飙到100%。而且即使不发生循环链表count的值也会因为竞态条件而丢失计数。修复// 修复后线程安全版本ServicepublicclassViewCountService{privatefinalConcurrentHashMapLong,AtomicIntegerviewCountMapnewConcurrentHashMap();publicvoidincrement(LongproductId){viewCountMap.computeIfAbsent(productId,k-newAtomicInteger(0)).incrementAndGet();}publicIntegergetCount(LongproductId){AtomicIntegercountviewCountMap.get(productId);returncount!null?count.get():0;}}修复成本写代码5分钟但线上排查花了一个下午CPU飙升 - 线程dump - 定位循环链表 - 修bug。避坑方法代码里有共享状态Map、List、计数器强制AI使用并发安全容器。HashMap → ConcurrentHashMapint → AtomicIntegerArrayList → CopyOnWriteArrayList读多写少场景。四、坑四异常处理只打e.printStackTrace()——上线后日志失踪AI最喜欢的一种写法// AI生成的异常处理完全无用try{processOrder(orderId);}catch(Exceptione){e.printStackTrace();// ❌ 在Docker/K8s里根本没人看控制台}或者更离谱的}catch(Exceptione){// TODO: 添加日志 // ← AI真的会这么写}到了生产环境Docker容器 K8s集群printStackTrace的内容不会进入任何日志采集系统。线上出错了你看不到任何痕迹。修复// 修复后规范的异常处理privatestaticfinalLoggerlogLoggerFactory.getLogger(OrderService.class);try{processOrder(orderId);}catch(BusinessExceptione){log.warn(订单处理业务异常orderId{}, reason{},orderId,e.getMessage());throwe;}catch(Exceptione){log.error(订单处理系统异常orderId{},orderId,e);thrownewServiceException(订单处理失败请联系管理员,e);}避坑方法全文搜索catch块。确保每个catch都有①日志记录带业务上下文②明确的处理策略抛出自定义异常 / 走补偿逻辑 / 降级处理。空catch绝对不过审。五、坑五配置值硬编码——上线后改一次发一次版AI从来不把配置值放在配置文件里// AI生成的硬编码到处是魔法数字ServicepublicclassOrderService{privatestaticfinalintMAX_RETRY3;privatestaticfinallongTIMEOUT_MS30000;privatestaticfinalintPAGE_SIZE20;publicvoidprocess(){// 中间用了这些硬编码的值}}问题测试环境30秒超时够用线上用户多了Connection Pool爆了。调到60秒 → 改代码 → 打包 → 发布 → 重启。一整个发布流程就为了改个数字。修复# application.ymlorder:max-retry:${ORDER_MAX_RETRY:3}timeout-ms:${ORDER_TIMEOUT_MS:30000}page-size:${ORDER_PAGE_SIZE:20}// 修复后从配置读取ServicepublicclassOrderService{Value(${order.max-retry:3})privateintmaxRetry;Value(${order.timeout-ms:30000})privatelongtimeoutMs;Value(${order.page-size:20})privateintpageSize;}避坑方法全文搜索字面量数字。凡是可能改的、环境之间有差异的全部提取到配置文件。六、坑六缺少幂等性设计——超时重试导致重复操作客户端调用接口 → 网络超时 → 自动重试 → 同一笔订单被扣了两次款。AI生成的接口从不考虑幂等性// AI生成的扣款接口缺少幂等保护PostMapping(/pay)publicResponseEntityStringpay(RequestBodyPayRequestrequest){// 直接扣款没有检查是否已经扣过accountService.deduct(request.getOrderId(),request.getAmount());returnResponseEntity.ok(扣款成功);}修复// 修复后加入幂等性校验PostMapping(/pay)publicResponseEntityStringpay(RequestBodyPayRequestrequest){StringidempotentKeypay:idempotent:request.getOrderId();BooleansuccessredisTemplate.opsForValue().setIfAbsent(idempotentKey,1,Duration.ofHours(24));if(Boolean.FALSE.equals(success)){log.warn(重复扣款请求orderId{},request.getOrderId());returnResponseEntity.ok(已处理);}try{accountService.deduct(request.getOrderId(),request.getAmount());returnResponseEntity.ok(扣款成功);}catch(Exceptione){redisTemplate.delete(idempotentKey);throwe;}}避坑方法涉及金钱、库存、状态变更的接口必须要求AI加入幂等校验。七、坑七代码能跑但无法维护——技术债从第一行开始这个坑没有上面那些那么炸裂但日积月累是最伤元气的。AI生成的代码通常方法长度300行变量名a, b, c, temp, data零注释业务逻辑和数据库访问混在一起同一个判断逻辑复制了5处这些代码今天能跑下个月你自己都看不懂。解决方式不是不让AI写代码是让AI自己审查自己写的代码。// 给AI的代码审查指令放在prompt最后// 请按照以下标准审查你生成的代码// 1. 找出所有超过50行的public方法建议拆分// 2. 找出所有含义不明的变量名如temp、data、result建议重命名// 3. 找出可以提取为私有方法的重复代码块// 4. 给所有public方法添加JavaDoc注释// 5. 确保Service层不直接操作HttpServletRequest/ResponseAI改完之后用Git diff看变更确认没问题再合。写在最后这7个坑不是让你不要用AI编程——正好相反用对之后效率提升是实打实的。关键是知道AI的弱点在哪在弱点上人工把关在优势上放手让它干。用AI编程的正确节奏是AI负责速度你负责质量。AI写第一版你做最终审查。AI出覆盖量你提供判断力。建议你把这篇收藏下来每次AI生成代码后对着7个检查项过一遍。坚持一个月返工时间至少减半。有问题评论区聊。如果这篇对你有用点赞收藏让更多人看到我继续出第二篇《AI生成SQL的9个安全漏洞》。