AI编程=准点下班?
用AI这一年我反而把这3件事
看得更重了
代码审查 · 需求拆解 · 架构判断 · 三个真实踩坑场景
码蜂奶爸 · 每日采蜜
📦 3 Parts + Conclusion
👉 滑动
PART 01
代码审查
从走过场到不敢了
PART 02
需求拆解
AI不知道该写什么
PART 03
架构判断
系统的账还得人算
PART ///
写在最后
奶爸悟
AI没有让我变闲,它让我把时间从“动手”挪到了“动脑”
去年这个时候,我还在跟同事争论“AI到底能不能写好Flutter”。今年我已经离不开它了,每天打开Cursor的次数比打开微信还多。
我本来以为用上AI之后能准点下班接娃,结果反而比之前更忙了。不是加班写代码,是把原来花在“写”上的时间,全挪到了三件以前觉得“可以缓缓”的事情上。
今天这篇不讲AI有多好用,讲讲它“逼”我变认真的那3件事。
01
PART
代码审查:以前是走过场,现在不敢了
CODE REVIEW · 护城河
AI写代码快,快到你来不及想它为什么这么写。
前阵子做一个Flutter商品列表页,我让AI帮忙写下拉刷新+上拉加载。它几秒钟就甩出来一段:
// 商品列表Bloc
class ProductListBloc extends Bloc<ProductEvent, ProductState> {
final ProductRepository _repo;
int _page = 1;
final int _pageSize = 20;
ProductListBloc(this._repo) : super(ProductInitial()) {
on<LoadProducts>(_onLoad);
on<LoadMore>(_onLoadMore);
}
Future<void> _onLoad(LoadProducts event, Emitter<ProductState> emit) async {
emit(ProductLoading());
_page = 1; // 关键:刷新时必须重置页码
final result = await _repo.fetch(page: _page, size: _pageSize);
emit(ProductLoaded(result.items, hasMore: result.hasMore));
}
Future<void> _onLoadMore(LoadMore event, Emitter emit) async {
final current = state is ProductLoaded ? state as ProductLoaded : null;
if (current == null || !current.hasMore) return;
_page++;
final result = await _repo.fetch(page: _page, size: _pageSize);
// 注意:合并旧数据,不能直接覆盖
emit(ProductLoaded(
[...current.items, ...result.items],
hasMore: result.hasMore,
));
}
}
看起来挺像样对吧?页码重置、数据合并、hasMore判断都有。但我review的时候发现两个坑。
!踩坑提示 🕳
第一个坑:没处理并发刷新。用户手快连拉两次,_page被重置两次,中间那次请求回来的时候页码已经乱了,列表会出现重复商品。
第二个坑:没做错误态恢复。加载失败后state卡在Error,用户再下拉刷新触发不到LoadProducts,因为事件路由里只判断了if state is ProductInitial。
这两个问题AI一个都没提。如果我不review直接合进去,上线后准有用户来投诉“列表怎么有重复的商品”。
以前我自己写代码,边写边想这些边界,脑子是热的,上下文都在。现在AI把“写”这一步省了,我的注意力只能全压到“审”上。审别人(哪怕是AI)的代码,比审自己的还累,因为你没有它生成时的思路上下文。
这一年我养成了一个习惯,AI生成的代码至少读三遍:第一遍读逻辑对不对,主干流程跑不跑得通;第二遍读边界全不全,并发、失败、空数据、极端值;第三遍读它有没有偷偷引入我没要的依赖或副作用。三遍下来,有时候比我自己从头写还费神。但质量确实更稳了,线上bug也比去年同期少了一截。
02
PART
需求拆解:AI会写代码,但它不知道该写什么
REQUIREMENT · 业务语义鸿沟
这个感受最深。
做一个电商App的“凑单”功能,需求是:用户购物车里差XX元免运费,推荐几个凑单商品。我直接把需求丢给AI,它给我写了一屏代码,按价格排序、过滤库存、展示列表,跑起来没问题。
但上线第二天产品就找我:“为什么推荐的全是9块9的手机壳?用户买的是奶粉啊。”
AI不知道“凑单推荐”在业务上应该是“同品类优先、价格接近差额、别推荐用户刚看过的”。它只实现了字面意思的“差多少推荐多少”。这个业务语义的鸿沟,AI填不了,因为它旁边没有产品经理跟它吵架。
后来我把需求拆成这样再喂给它:
1. 输入:购物车总金额、免运费门槛、品类列表
2. 候选池:同品类优先(权重0.6),相邻品类次之(0.3)
3. 价格区间:[差额-5, 差额+10],避免推荐高价品
4. 排除:用户近7天浏览过的商品(从行为表查)
5. 排序:价格升序,同价格按销量降序
6. 数量:最多展示6个,不足则用相邻品类补齐
它一下就写对了。
以前需求模糊,我还能边写边跟产品磨,反正写代码也慢。现在AI一秒出代码,你需求没拆清楚,它就一秒给你产出一个“看起来对但业务错”的东西,还特别自信。所以我现在写代码之前,会花比以前多一倍的时间在拆需求上,把每个功能拆成输入、输出、边界、异常、业务规则五块,写在注释里,再交给AI。这个习惯以前也知道,但从来没被AI逼得这么紧。
03
PART
架构判断:AI擅长局部,系统的账还得人来算
ARCHITECTURE · 全局视角
这个最隐蔽。
AI写单个页面、单个组件、单个工具函数,质量已经超过大部分初中级工程师。但一旦涉及跨模块的架构决策,它就开始“装傻”了。不是不会,是它没有你的项目上下文。
举个鸿蒙的例子。我们在做一个鸿蒙原生迁移,AI给了一个ArkUI的状态管理方案,局部看很优雅:
// AI推荐的组件内状态管理
@Component
struct ProductCard {
@State isSelected: boolean = false;
@Prop product: ProductModel;
build() {
// ...UI代码省略
}
}
单看没问题。但我们这个卡片要和购物车页、收藏页共享选中状态,跨页面同步。如果按AI的方案每个组件自己管@State,最后会出现三个页面各存一份选中态,同步起来全是bug。
AI不知道你有几个页面要共享这个状态,不知道你的导航结构,不知道你的性能瓶颈在哪。这些信息只在你脑子里。
正确的做法是把选中状态提升到AppStorage做全局共享:
// 修正后:状态上提,跨页面共享
AppStorage.setOrCreate('selectedProductIds', new Set<string>());
@Component
struct ProductCard {
@StorageLink('selectedProductIds') selectedIds: Set<string>;
@Prop product: ProductModel;
// 关键:选中态读写都走全局
toggleSelect() {
if (this.selectedIds.has(this.product.id)) {
this.selectedIds.delete(this.product.id);
} else {
this.selectedIds.add(this.product.id);
}
// Set引用没变,必须重新赋值触发刷新
AppStorage.set('selectedProductIds', new Set(this.selectedIds));
}
build() {
// ...UI代码省略
}
}
这个“状态该放在哪一层”的判断,AI给不了你。它只会给你一个局部方案,然后很礼貌地问你“这样可以吗”。
用AI这一年,我最大的感触是它把“造砖”的活儿全包了,但“盖房子”的图纸还是得你自己画。而且因为砖来得太快,你反而得更早把图纸想清楚,不然一会儿就堆成一堆没人要的砖头山。
///
LAST
写在最后
SUMMARY · 奶爸悟
回看这一年,AI帮我省下的时间并没有变成准点下班的轻松,而是变成了三件更费脑子的事:代码审查从走过场变成了不敢松懈,需求拆解从边写边磨变成了先拆后写,架构判断从写的时候顺手做变成了提前想清楚。
AI没有让我变闲,它让我把时间从“动手”挪到了“动脑”
奶爸悟
这事儿跟带娃挺像的。你以为给孩子报个辅导班自己就解放了,结果发现真正费神的,是得想清楚让他学什么、为什么学。工具越省事,判断越值钱。
我是 码蜂奶爸,10年+移动端全栈程序员,两个孩子的爸爸。分享AI编程实战、移动端技术沉淀、奶爸带娃日常。
既然看到这里了,如果觉得有用,随手点个赞、在看、转发三连吧。
THANKS FOR READING
夜雨聆风