AI 辅助编程的 7 个误区:把模型当高级搜索引擎是对它的最大浪费

📅 2026/7/28 15:06:35
AI 辅助编程的 7 个误区:把模型当高级搜索引擎是对它的最大浪费
AI 辅助编程的 7 个误区把模型当高级搜索引擎是对它的最大浪费一、当 AI 说这里加一个 Mutex 就好的时候去年十二月我在给 dayuan 做并发缓存层。ChatGPT 很自信地建议在HashMap外层包一个ArcMutex多线程访问就安全了。我照做了。然后发现高并发场景下吞吐量从 5000 QPS 跌到了 300 QPS——因为所有读操作都在争同一个锁。最后我用dashmap 分片锁的方案才把性能拉回来。这事让我明白一个道理AI 给你的方案永远只是能编译通过的方案不是正确的方案更不是好的方案。作为自学编程的人我天然依赖 AI 来弥补知识短板。但一年多下来我发现很多人在用 AI 编程时陷入了 7 个典型的认知误区。二、误区全景三、从使用工具到被工具使用误区 1把 AI 当高级搜索引擎这是最常见的用法——也是最浪费的用法。用户tokio::spawn 怎么用 AI 这是文档……你在浪费模型的推理能力。你不是在用一个代码助手你是在用一个美化版的grep docs.rs。正确的用法用户我在写一个 WebSocket 服务需要在 accept 新连接时 同时维护一个全局的在线用户列表支持广播。 现在我用 ArcMutexVecu64 存储在线用户 ID。 每次广播都要遍历一遍5000 并发时 Mutex 变成瓶颈了。 不用给我写全代码帮我分析三种可能的优化方向 以及每种在什么场景下适合。 AI 好我来分析 1. dashmap 连接级别锁 适用读写比例均衡需要强一致性 代价内存占用比 Vec 高 30% 2. 分片路由 无锁广播 适用写少读多在线状态变更少广播多 代价实现复杂度高需要设计分片策略 3. 事件总线 订阅模式 适用广播是主要操作不需要存储状态快照 代价需要引入消息中间件如 tokio::broadcast看到了吗你不是在问怎么用你是在把自己的设计困境描述给 AI让它帮你做 trade-off 分析。误区 2无脑接受 AI 的代码/// ❌ AI 写的代码看起来没问题直到你在生产环境看到 OOM async fn process_all_users(user_ids: Vecu64) - VecUserInfo { let mut tasks Vec::new(); for id in user_ids { // AI 不知道你的 user_ids 可能有 10 万个 tasks.push(tokio::spawn(async move { fetch_user_info(id).await })); } // 10 万个 task 同时运行 → 连接池耗尽 → OOM let mut results Vec::new(); for task in tasks { results.push(task.await.unwrap()); } results }每次收到 AI 代码带着这五个问题审一遍边界条件如果输入为空会怎样如果输入有 10 万条会怎样错误处理每个.await点都可能出错处理了吗性能假设这个操作是 O(1) 还是 O(n)瓶颈在哪里并发安全多线程/多协程同时运行时有数据竞争吗资源泄露文件句柄、网络连接、内存有没有正确释放误区 3跳过理解直接复制粘贴这是我刚开始用 ChatGPT 时最大的毛病。看到代码跑通了就以为学会了一周后再遇到同样的问题——还是不会。我的实践AI 辅助学习的正确姿势/// 场景AI 生成了这段代码帮你解决问题 /// 但你没有直接粘贴而是逐行加注释来确保自己理解了 use std::collections::HashMap; use std::sync::Arc; use tokio::sync::RwLock; /// 线程安全的缓存实现 /// 追问 AI 的问题 /// Q: 为什么用 RwLock 而不是 Mutex /// A: 因为缓存的读操作远多于写操作RwLock 允许多个读并发 /// Q: 为什么外面要包 Arc /// A: 因为 RwLock 需要被多个 task 共享Arc 提供多所有权 pub struct Cache { inner: ArcRwLockHashMapString, String, // ^^^ 多线程共享需要引用计数 // ^^^^^^ 读写锁多个读者可以同时读写者独占 // ^^^^^^^^^^^^^^^^^^^ 实际存储 } impl Cache { pub fn new() - Self { Self { inner: Arc::new(RwLock::new(HashMap::new())), } } /// 读取缓存可以多个 task 同时读 pub async fn get(self, key: str) - OptionString { let guard self.inner.read().await; // ^^^^^^ 获取读锁不阻塞其他读者 guard.get(key).cloned() } // guard 在这里被 drop → 读锁释放 /// 写入缓存独占访问 pub async fn set(self, key: String, value: String) { let mut guard self.inner.write().await; // ^^^^^^^ 获取写锁阻塞所有读者和写者 guard.insert(key, value); } }我的法则AI 生成的代码凡是不能逐行解释的先弄懂再用。误区 4觉得 AI 能替代系统学习AI 能告诉你Tokio 的 runtime 有block_in_place这个函数。但它不能告诉你什么时候不该用它。/// ❌ AI 告诉你的 /// 在 async 函数里调用同步代码用 block_in_place 就行 async fn my_async_fn() { let result tokio::task::block_in_place(|| { // 同步阻塞代码 std::thread::sleep(Duration::from_secs(5)); 42 }); } /// 但 AI 不会告诉你的是 /// 1. block_in_place 会把当前 task 移出 worker 线程 /// 2. 如果大量 task 都用 block_in_placeworker 线程池会漏光 /// 3. block_in_place 只应在 CPU 密集计算中使用 /// 4. 对于 IO 操作应该用 spawn_blocking 或专门的异步 IO系统学习 AI 问答。对于一个新概念我的学习路径是读官方文档的 Overview至少前 3 页用 AI 回答这个概念解决了什么问题不是怎么用写一个最小可运行的 demo故意写一个反例看看会出什么问题最后才把 AI 生成的代码放进项目误区 5用 AI 生成安全关键代码/// ❌ AI 写的用户认证代码 —— 永远不要这样用 #[derive(Deserialize)] pub struct LoginRequest { pub username: String, pub password: String, } async fn login_handler(req: LoginRequest) - Resultimpl Reply { // AI 的建议直接拼 SQL let query format!( SELECT * FROM users WHERE username {} AND password {}, req.username, req.password // ← SQL 注入 ); // 用 req.username admin -- 就能绕过密码验证 sqlx::query(query).fetch_one(pool).await?; Ok(登录成功) }安全敏感的代码永远不要让 AI 替你写。包括但不限于类别为什么不能信 AISQL 查询拼接AI 不一定会用参数化查询密码哈希AI 可能建议用 MD5/SHA1JWT 验证AI 可能跳过签名校验权限检查AI 可能把授权逻辑写在客户端加密实现永远不要自己实现加密算法误区 6高估 AI 的上下文理解能力// 你问 AI // 这个函数有什么问题帮我修复 pub async fn process_data(config: Config, data: Data) - ResultOutput { // AI 能看到这段代码但它不知道 // 1. Config 的字段中哪些是热更新的 // 2. Data 在什么生命周期内有效 // 3. 调用方的并发模型是什么样的 // 4. 这个函数在整体架构中的角色 let enriched enrich(data)?; let transformed transform(config.rules, enriched).await?; Ok(transformed) }给 AI 提供上下文的最佳实践用户我在维护一个多租户 SaaS 的数据处理管线。这个 process_data 函数是管线的第二步前一步是数据清洗后一步是存储。 当前的问题是当租户数量从 10 增长到 1000 时 这个函数从 50ms 变成了 3s。 [粘贴函数代码] 我在怀疑 enrich 阶段的 HashMap 在租户维度做了 O(n²) 操作。 帮我分析是否存在这个问题以及如何修复。误区 7用 AI 做架构决策AI 不能替你选数据库不能替你决定微服务拆分不能替你评估技术债。因为架构决策的核心不是技术优劣而是你今天有多大的团队、明天要支持多少用户、三个月后的需求是什么——而这些信息都不在模型的训练数据里。四、我现在的 AI 编程工作流具体来说需求阶段把需求描述给 AI让 AI 用三种不同方案各写 5 行伪代码。比较思路不比较代码细节。设计阶段自己画出数据流图或状态机图让 AI 挑漏洞。实现阶段自己写核心逻辑。AI 帮忙生成测试用例、文档注释、CLI 参数定义。审查阶段把自己的代码给 AI限定问题这段代码有哪些我没考虑的边界情况重构阶段功能验证通过后让 AI 提出重构建议——这时候它已经有了完整上下文。五、总结AI 辅助编程一年多我对 AI 的定位经历了三次迭代第一阶段AI 是代码生成器——帮我写一个……第二阶段AI 是结对编程伙伴——这里有问题帮我看看……第三阶段现在AI 是思维延伸——我在做 X有三种方案帮我分析每种在 Y 场景下的 trade-off……关键转变是从让 AI 替我想变成了我思考AI 检查。的我之所以能靠自学转行很大程度上受益于 AI。但我也看到太多人陷入AI 写了代码 → 跑通了 → 以为自己学会了的循环里。这不是在学习这是在制造技术债——只不过债主是你未来的自己。记住两件事AI 写代码只节省了你 20% 的时间但如果你不理解它写的代码未来修 bug 会多花 200% 的时间。好的开发者不是能快速写出代码的人而是能判断这段代码不该这么写的人。AI 不能帮你做这个判断——只有你自己的理解能。下一篇预告Rust 错误处理的反面教材半年里见过的最糟糕的错误处理代码分析。