1. 一个老程序员的AI工作流进化实录:从“试试看”到“离不开”
我干了十六年软件开发,写过嵌入式驱动、做过Android系统定制、带过百人规模的技术团队,也亲手把三个从零起步的App推上千万用户。过去十年里,我习惯用“经验”这个词来锚定自己的价值——代码写得快不快、Bug定位准不准、架构设计稳不稳,全靠日积月累的肌肉记忆和条件反射。但今年二月的一个下午,当我看着Claude Code在23分钟内把一份27页的车载空调协议PDF解析成可编译的Java接口定义,并自动生成了带单元测试的Mock服务层时,我关掉了编辑器,泡了杯浓茶,坐了整整十五分钟没动。不是震惊,也不是焦虑,而是一种久违的、近乎生理性清醒的顿感:我的工作方式,正在被不可逆地重写。这不是科幻预告片,也不是技术布道PPT里的未来图景,它就发生在我每天打开IDE的那一刻。这篇文章不谈大模型原理、不列参数指标、不对比各家API吞吐量——我就用两个真实项目:一个从零搭建的车控测试工具,一个让全组避之不及的“祖传空调模块”重构,把这两个月怎么用Claude Code、为什么这么用、踩过哪些坑、又省下多少无效劳动,掰开揉碎讲给你听。如果你也是写了十年以上代码、现在还在用Ctrl+C/V复制粘贴改逻辑、看到新需求第一反应是“这得干一周”的老家伙,这篇文字就是为你写的。它不承诺让你一夜成为AI专家,但它能帮你把“要不要用AI”这个悬在头顶的问题,换成“明天早上第一件事,先让AI帮我读哪段代码”。
2. 为什么是Claude Code?一次老程序员的工具选型心路
2.1 三阶段试错:从“网页搜索替代品”到“工作流心脏”
很多人问我:“你为啥不直接用GitHub Copilot或者通义灵码?”这个问题背后藏着一个关键认知偏差——我们不是在选一个“更聪明的自动补全”,而是在找一个能深度参与工程决策的协作者。我的尝试严格按时间线分了三个阶段,每个阶段都对应着我对AI能力边界的重新校准。
第一阶段是2025年初DeepSeek爆火后,我抱着“试试看”的心态用网页端。腾讯元宝、豆包、DeepSeek R1轮着试。它们在“确定性任务”上确实惊艳:输入“Python写个快速排序,要求用迭代非递归”,三秒出带注释的完整代码;粘贴一段报错日志,它能精准定位到NullPointerException发生在第47行user.getProfile()未判空。但一旦任务需要上下文纵深理解,体验就断崖式下跌。比如我给它一段200行的车载CAN通信解析逻辑,问“这段代码如何支持新增的座椅加热温度反馈字段?”,它会生成一个看似合理的addHeatingTempField()方法,但完全忽略了原逻辑中CANFrameParser类是单例且线程不安全,新加字段会导致多线程竞争——这种结构性风险,网页端根本看不到。更致命的是工作流割裂:我要在浏览器里查文档、在IDE里写代码、在终端里跑测试,AI像一个站在门外的顾问,只能隔着门缝递纸条。
第二阶段转向IDE插件。我主力用Android Studio,试了Trae和通义灵码。体验提升最明显的是“操作密度”——不用切窗口,光标停在哪,AI就能在哪补全。写RecyclerView.Adapter时,它能根据onCreateViewHolder的返回类型,自动补全onBindViewHolder的holder.itemView绑定逻辑;写Kotlin协程,它能根据suspend fun签名,智能插入withContext(Dispatchers.IO)。但问题很快浮现:当任务需要跨文件、跨模块的语义关联时,插件就像近视眼摘了眼镜。我让它分析一个包含AirConditionerController.java、TempSensorService.kt、ClimateConfigManager.kt三个文件的空调初始化流程,它给出的调用链是线性的“A→B→C”,却完全漏掉了ClimateConfigManager在Application.onCreate()里通过反射加载了LegacyACAdapter这个关键跳转点。结果是,它建议我把所有温度计算逻辑移到TempSensorService,而实际上这个类只负责硬件采样,业务规则全在那个被反射加载的适配器里。插件的优势在于“快”,劣势在于“浅”——它擅长处理局部语法,但对工程级的隐式契约束手无策。
第三阶段切换到Claude Code,直接原因很朴素:它能“看见”整个项目。不是靠扫描当前文件,而是通过我手动指定的/src/main/java/com/car/aircon/路径,它构建了一个完整的符号索引。当我输入“请分析AirConditionerController.java的职责边界,并指出与ClimateConfigManager的耦合点”,它不仅列出所有new ClimateConfigManager()的实例化位置,还标注出其中两处是通过Class.forName("com.car.legacy.LegacyACAdapter")动态加载的,并明确提示:“此处存在运行时依赖,静态分析无法覆盖,需结合proguard-rules.pro确认是否保留该类”。这种对工程现实约束的敬畏感,是前两个阶段从未有过的。它不假装自己无所不知,但会清晰告诉你“我知道什么”和“我为什么不知道”。
2.2 核心差异:不是“更聪明”,而是“更懂工程”
我把Claude Code和其他工具的根本区别,总结为三个工程维度的“穿透力”:
穿透文件壁垒:传统工具分析单个文件时,会把
import com.car.legacy.LegacyACAdapter;当作一个黑盒符号。Claude Code则会主动询问:“是否需要我分析LegacyACAdapter的源码?它位于/legacy/src/目录下。”一旦我授权,它立刻将两个模块的调用关系映射成一张可视化的依赖图(文本版),并标注出LegacyACAdapter.setTargetTemp()被AirConditionerController调用了7次,其中3次传入的targetTemp值来自ClimateConfigManager.getOptimalTemp()——这种跨模块的数据流追踪,是重构决策的基石。穿透抽象层级:当我说“重构空调模块”,普通AI会建议“把大类拆成小类”。Claude Code则会先问我:“您希望采用哪种分层模式?MVP、MVVM还是Clean Architecture?各层间的数据传递是通过EventBus、LiveData还是StateFlow?”它不预设答案,但会列出每种选择的工程代价:比如选Clean Architecture,它会计算出需新增12个接口定义、4个Repository实现、3个UseCase类,并预估迁移耗时约8小时(基于它对当前代码复杂度的静态分析)。这种把架构决策量化为可执行任务的能力,让“重构”从玄学变成了项目管理。
穿透意图模糊:程序员最头疼的不是写代码,而是把模糊需求翻译成精确指令。比如业务方说“空调要支持语音控制”,传统AI可能生成一堆
VoiceCommandHandler类。Claude Code会反问:“语音指令的触发词有哪些?(如‘打开空调’、‘调高温度’);响应延迟要求是多少?(<300ms);是否需要离线支持?(影响ASR引擎选型)”。它强迫我把隐藏假设显性化,而这些恰恰是项目成败的关键。它不是在替我思考,而是在教我如何更结构化地思考。
提示:Claude Code的“工程穿透力”高度依赖你的输入质量。我试过直接丢一个
build.gradle文件问“怎么优化”,它回复了一堆通用建议。当我改成“当前APK体积超限2MB,请分析app/build/outputs/apk/debug/app-debug.apk的组成,并针对com.car.aircon.*包下的资源提出压缩方案”,它立刻生成了ProGuard规则、SVG转WebP的脚本、以及移除未使用字体的清单——给它上下文,它才给你答案;给它模糊,它还你更模糊。
3. 实战案例一:车控接口测试工具——从一周到一小时的生产力跃迁
3.1 项目背景:车载开发者的“重复劳动地狱”
车载系统测试是公认的苦活。一辆主流车型的车控接口(Vehicle Control API)通常包含300+个独立功能点,覆盖车身控制(车窗、门锁)、舒适系统(座椅、空调)、驾驶辅助(ACC、LKA)等。每个接口必须支持三种操作模式:
Set:下发控制指令(如setWindowPosition(LEFT_FRONT, 50))Get:查询当前状态(如getWindowPosition(LEFT_FRONT))Callback:订阅状态变更(如registerWindowPositionListener(...))
传统验证方式极其原始:开发工程师拿到供应商提供的PDF接口文档和Java SDK jar包,手动编写Android测试App。流程是机械的:
- 解析PDF中的接口定义,提取方法名、参数、返回值
- 在IDE中创建对应Activity,拖拽Button/TextView控件
- 为每个Button编写
onClick事件,调用SDK方法 - 将返回值
setText()到对应TextView - 为Callback注册监听器,更新UI
我上家公司做过类似项目,团队5人花了两周才覆盖80%接口,剩下20%因文档歧义卡在“供应商说我们理解错了”上。这次我决定用Claude Code挑战极限:目标是在一个工作日内,完成覆盖全部327个接口的测试工具,且支持批量执行、结果导出Excel、UI按功能域分组。
3.2 操作全流程:如何让AI精准理解你的工程意图
整个过程我严格遵循“人类决策-机器执行”分工,共分四步,每步都附关键操作细节:
第一步:喂数据,建上下文(耗时12分钟)
我没有直接扔PDF,而是做了三件事:
- 将PDF用Adobe Acrobat导出为纯文本(避免OCR错误),保存为
aircon_api_spec.txt - 反编译jar包,提取所有
*.java源码(用JADX-GUI),存入/sdk_src/目录 - 创建
project_context.md文件,明确告知Claude Code:当前项目是Android App,目标API级别33,使用Kotlin+Jetpack Compose。 测试工具需满足: - 主界面按功能域分Tab:【空调】、【座椅】、【灯光】、【驾驶模式】 - 每个Tab内,接口按Set/Get/Callback三类分组 - 支持“一键执行所有Set接口”并记录耗时 - 结果导出为Excel,含列:接口名、操作类型、耗时(ms)、返回值、状态(成功/失败) - 所有UI组件使用Material3规范
注意:这里
project_context.md是成败关键。我试过只发PDF,AI生成的代码大量使用findViewById()(已废弃),且UI布局混乱。明确指定技术栈和UI规范,相当于给AI装上了“工程导航仪”。
第二步:生成骨架,校验核心逻辑(耗时28分钟)
我输入指令:“基于aircon_api_spec.txt和/sdk_src/,生成AirconTestActivity.kt的Compose UI骨架,要求:
- 使用
TabRow实现四大功能域Tab - 每个Tab内用
LazyColumn展示接口列表 - 每个接口项包含:名称Text、Set/Get/Callback三个OutlinedButton、状态Indicator
- 所有按钮点击事件留空,仅声明
onClick = { /* TODO: implement */ }”
Claude Code输出的代码质量极高:
- 正确识别出
aircon_api_spec.txt中“空调温度设置”对应AirConditionerService.setTemperature(int temp) - 自动生成了
@Composable fun AirconTab()等符合Jetpack Compose范式的函数 - 甚至为
LazyColumn添加了rememberLazyListState()以支持滚动状态保持
但我发现一个致命错误:它把setTemperature()的参数类型识别为String(因PDF中写“temp: string value like '25'”),而实际SDK中是int。我立刻指出:“setTemperature参数应为Int,不是String,请修正所有相关调用”。它3秒内重生成全部代码,且同步更新了UI上的输入框类型(从TextField改为OutlinedTextField并添加数字键盘)。
第三步:注入业务逻辑,处理边缘Case(耗时41分钟)
这是最考验协作的环节。我让AI为每个接口生成具体调用逻辑,但要求它:
- 对
Set操作,自动生成随机合法参数(如温度范围16-32℃) - 对
Get操作,添加超时处理(withTimeout(5000) { ... }) - 对
Callback,生成Disposable管理模板
它完成了90%的工作,但有两个地方需要人工干预:
- 车型兼容逻辑:某接口
setSeatHeatingLevel(LEVEL)在A车型支持3档(0/1/2),B车型支持5档(0/1/2/3/4)。AI生成的代码硬编码了LEVEL=2,我补充说明:“请根据CarModelDetector.getCurrentModel()返回值动态设置档位”,它立刻重写为when (model) { A -> 2; B -> 4; else -> 1 }。 - 异步回调陷阱:
registerWindowPositionListener()的回调在Binder线程,直接更新Compose UI会崩溃。我提醒:“所有Callback必须切回主线程”,它迅速加入LaunchedEffect(Unit) { withContext(Dispatchers.Main) { /* update UI */ } }。
第四步:收尾与交付(耗时19分钟)
最后一步是自动化收尾:
- 让AI生成
ExportToExcel.kt,使用Apache POI库,将测试结果写入/sdcard/Download/aircon_test_report.xlsx - 生成
BatchExecutor.kt,实现“一键执行所有Set接口”并汇总耗时 - 为所有Activity添加
android:exported="true"(Android 12+强制要求)
当我在模拟器上点击“空调”Tab,327个接口整齐排列,点击任意Set按钮,毫秒级弹出Toast显示“setTemperature(25) success, cost: 12ms”,点击“导出报告”,手机存储中立刻出现格式完美的Excel——全程1小时02分钟,比上家公司5人团队两周的成果更完整、更健壮。最讽刺的是,我导出的Excel里有一列“文档准确性”,标记出17处PDF与SDK实际不符的地方,这成了我们向供应商索赔的技术依据。
4. 实战案例二:空调模块重构——当AI成为你的“资深同事”
4.1 项目痛点:一个2500行类的“技术债务黑洞”
这个叫AirConditionerController.java的文件,是我们团队的“公开处刑对象”。它诞生于2018年,历经7任开发者之手,最新一次修改是2024年11月,由一位已离职的同事提交。它的恐怖之处在于:
- 物理规模:2543行,单个文件占整个空调模块代码量的68%
- 逻辑熵增:172个
if-else嵌套最深达7层,switch语句覆盖42个状态码 - 数据污染:113个
public static final常量散落在不同位置,其中27个命名如FLAG_0X1A,无注释 - 架构失能:所有业务逻辑(温度计算、风速控制、除霜策略)与硬件交互(CAN发送、传感器读取)混在同一方法中
线上Bug清单触目惊心:
- 后除霜按钮点击无响应(实际是
startRearDefrost()被isAutoModeEnabled()的错误判断拦截) - 最大制冷/制热状态错乱(因
MAX_COOL_TEMP = 16和MAX_HEAT_TEMP = 32被同一变量targetTemp复用) - 香氛浓度调节失效(
setFragranceLevel()调用链中,FragranceManager的getInstance()返回null,因单例初始化时机错误)
管理层的共识是:“重构风险太高,先加监控,等下一代平台再动”。直到我决定用Claude Code把它“解剖”一遍。
4.2 四步重构法:人类做决策,AI做执行
我将重构拆解为四个不可逆的阶段,每个阶段都设定明确的“人类守门员”节点:
阶段一:理解即重构——让AI成为你的“代码考古学家”(耗时37分钟)
我上传整个/aircon/目录(含AirConditionerController.java及所有被引用类),输入指令:
“请执行以下分析:
- 绘制
AirConditionerController的类图,标注所有public方法及其调用的外部类方法 - 识别所有状态变量,按生命周期分组:(a)全局配置(如
DEFAULT_TEMP)、(b)运行时状态(如currentTemp)、(c)临时缓存(如lastSentCANFrame) - 标出所有违反SOLID原则的代码段,重点标注:
- 违反单一职责(如
updateDisplay()方法同时处理UI刷新、温度计算、CAN帧组装) - 违反开闭原则(如
handleCANMessage()中硬编码了12种消息ID的switch分支)
- 违反单一职责(如
- 输出一份《重构风险地图》,列出:
- 必须优先处理的3个高危点(可能导致编译失败或运行时崩溃)
- 可延后处理的5个中危点(影响可维护性但不阻断功能)
- 建议保留的2个低危点(如某个车型专用的
LegacyModeHandler)”
AI的输出让我脊背发凉:它准确指出了updateDisplay()是“重构第一刀”,因为该方法调用了TempCalculator.calculate()、DisplayRenderer.render()、CANTransmitter.send()三个完全无关的模块,且calculate()的返回值被直接强转为DisplayRenderer需要的DisplayData对象——这正是香氛失效的根源(类型转换失败导致render()传入null)。更惊人的是,它标记出LegacyModeHandler是“低危点”,理由是:“该类仅在CarModel == LEGACY_X1时被反射加载,且其handle()方法内部有完整的try-catch,不影响主流程”,这与我翻阅Git历史确认的结论完全一致。
阶段二:架构设计——用AI把蓝图变成施工图(耗时52分钟)
基于风险地图,我决定采用Clean Architecture分层:
- Presentation Layer:
AirconScreen.kt(Compose UI) - Domain Layer:
AirconUseCase.kt(业务规则,如CalculateTargetTempUseCase) - Data Layer:
AirconRepository.kt(数据获取,封装CAN通信) - Framework Layer:
CANTransmitterImpl.kt(硬件适配)
我让AI执行:
“为AirConditionerController的2543行代码,生成上述四层的初始骨架。要求:
- Domain层定义所有UseCase接口,方法签名需100%匹配原
AirConditionerController的public方法 - Data层定义
AirconDataSource接口,方法需覆盖所有CAN通信调用点 - Presentation层生成
AirconViewModel,包含StateFlow<AirconUiState>,状态字段需包含原类中所有关键状态变量 - 为每个层生成
TODO注释,标明需迁移的具体代码行号(如// TODO: migrate lines 421-487 from AirConditionerController.java)”
AI生成的骨架完美对齐我的设计。最妙的是AirconUiState数据类,它自动聚合了原类中分散的113个状态变量,按语义分组:
data class AirconUiState( val temperature: TemperatureState, // 包含current, target, min, max val airflow: AirflowState, // 包含mode, speed, direction val defrost: DefrostState, // 包含rear, front, auto val fragrance: FragranceState // 包含level, type, enabled )这直接解决了“状态变量散落各处”的顽疾。
阶段三:代码迁移——AI的“机械臂”与人类的“神经中枢”(耗时14小时,分3天)
这是体力与脑力的混合战场。我每天分配2小时给AI执行批量迁移,其余时间做三件事:
- 审核迁移结果:AI把
if (mode == MODE_AUTO) { ... }迁移到CalculateTargetTempUseCase时,漏掉了MODE_AUTO的枚举定义。我截图指出,它立刻补全enum class AirconMode { AUTO, COOL, HEAT, DRY }。 - 修复业务逻辑:原代码中
startRearDefrost()的判断逻辑是if (isPowerOn && !isFrontDefrostActive),但AI迁移到Domain层后,误将isFrontDefrostActive当作Boolean处理,而实际是DefrostStatus枚举。我强调:“DefrostStatus有ACTIVE/INACTIVE/ERROR三种状态,请用when表达式处理”,它重写为when (frontDefrostStatus) { ACTIVE -> false; else -> true }。 - 注入测试用例:每完成一个UseCase,我要求AI生成JUnit5测试,覆盖边界Case。例如
CalculateTargetTempUseCase,它生成了12个测试用例,包括testCalculateForAutoModeWithLowAmbientTemp(),精准复现了线上“低温环境下自动模式不启动”的Bug场景。
阶段四:验证与上线——用AI把回归测试变成自动化流水线(耗时6小时)
重构完成后,最大的恐惧是“修好一个Bug,冒出十个”。我让AI:
- 生成
RegressionTestSuite.kt,自动遍历所有历史Bug的复现步骤,生成测试用例 - 创建
DiffAnalyzer.kt,对比重构前后APK的Method Count、Dex Size、启动耗时 - 输出《上线检查清单》,包含:
- [ ] 确认
LegacyModeHandler在LEGACY_X1车型上仍能通过反射加载 - [ ] 验证
CANTransmitterImpl的send()方法在弱网环境下超时降级逻辑 - [ ] 检查
AirconViewModel的StateFlow是否在Configuration Change(横竖屏)时正确恢复
- [ ] 确认
最终,三款车型的APK全部通过编译,CI流水线一次性通过所有测试。那些曾让我们夜不能寐的Bug,没有一个被专门修复,却全部消失——因为错误的土壤(2500行混杂逻辑)已被连根拔起。
5. 老程序员的AI生存指南:那些没人告诉你的硬核经验
5.1 关键认知:AI不是替代者,而是“经验放大器”
这两个月最深刻的体会是:AI不会削弱你的经验价值,反而会指数级放大它。以前,我的经验体现在“我能快速写出setWindowPosition()的完整实现”。现在,我的经验体现在“我一眼看出AI生成的setWindowPosition()调用链中,漏掉了WindowSafetyLock的权限校验,而这个校验在CarService的checkPermission()方法里被动态代理拦截”。前者是技能,后者是洞察。AI把“写代码”的体力劳动接管了,但“判断代码是否合理”的脑力劳动,变得前所未有的重要和值钱。我观察到一个规律:在AI时代,程序员的薪酬曲线不再由“代码行数”决定,而由“决策质量”决定。一个能准确指出AI方案缺陷的中级工程师,价值远超一个只会高效执行AI指令的高级工程师。
5.2 实操铁律:三不原则与三必做
基于血泪教训,我总结出“三不原则”和“三必做”,这是保证AI协作不翻车的底线:
三不原则:
- 不交出架构决策权:绝不让AI决定“用MVP还是MVVM”、“数据库用Room还是SQLite”。它只能提供选项和代价分析,拍板必须由人完成。我见过AI建议用
LiveData替代StateFlow,理由是“更简单”,却无视了StateFlow的协程友好性和LiveData的生命周期泄漏风险。 - 不跳过人工审核环节:所有AI生成的代码,必须经过“三眼原则”——第一眼扫逻辑结构,第二眼看异常处理,第三眼看线程安全。尤其警惕
try-catch块里空的catch,这是AI最常见的偷懒行为。 - 不脱离版本控制:每次让AI生成大段代码,必须先
git commit -m "WIP: AI-generated skeleton for AirconUseCase"。我有一次让AI重构一个网络模块,它把OkHttpClient的connectTimeout从30秒改成3秒,导致所有请求超时。幸亏有commit记录,git revert三秒回滚。
三必做:
- 必做上下文快照:每次开始新任务前,用
tree -L 2 /path/to/module > context_tree.txt生成目录结构快照,连同build.gradle关键配置一起喂给AI。这能避免它“猜错”项目结构。 - 必做术语表:为领域专有名词创建
glossary.md,如:
AI对术语的误解是多数失败的根源。- CAN Frame: 车载控制器局域网数据帧,格式为[Header][Payload][CRC] - Legacy Mode: 仅在X1/X2车型支持的兼容模式,启用后禁用所有新特性 - Defrost Status: 枚举类,值为ACTIVE/INACTIVE/ERROR - 必做渐进式验证:永远不要等AI完成全部工作再测试。比如重构时,我要求AI先生成
TemperatureCalculator的Domain层代码,我立刻写测试验证calculateTargetTemp(ambient=5, mode=AUTO)是否返回18℃。通过后再让它生成AirflowController。这种“小步快跑”让问题暴露在早期,成本最低。
5.3 常见问题速查表:从“AI又错了”到“我早料到它会错”
| 问题现象 | 根本原因 | 排查技巧 | 我的解决方案 |
|---|---|---|---|
| AI生成的代码编译失败 | 未识别Kotlin/Java版本差异(如用val声明Java字段) | 先让AI输出kotlinVersion和sourceCompatibility配置 | 在project_context.md中强制声明:“本项目使用Kotlin 1.9.20,所有代码必须符合K2编译器规范” |
| AI忽略多线程安全 | 大模型训练数据中,线程安全代码占比极低 | 检查所有涉及Handler、LiveData、SharedFlow的代码 | 在指令中加入硬性约束:“所有UI更新必须在Dispatchers.Main,所有IO操作必须在Dispatchers.IO,禁止使用runBlocking” |
| AI对业务逻辑“一本正经胡说八道” | 训练数据缺乏车载领域知识,强行拟合 | 用Git Blame找出该逻辑最后一次修改者,直接问他 | 创建domain_expert.md文件,粘贴专家解释:“startRearDefrost()必须在isPowerOn==true AND isFrontDefrostActive==false时才生效,否则会触发ECU保护机制” |
| AI生成的测试用例覆盖率低 | 无法感知代码的隐式约束(如某个方法只在DEBUG模式下调用) | 运行./gradlew test --tests "*CoverageTest"查看Jacoco报告 | 要求AI生成测试时,附加指令:“请覆盖所有@VisibleForTesting方法,并模拟BuildConfig.DEBUG==true/false两种场景” |
| AI反复犯同一类错误 | 未建立有效的反馈闭环 | 记录错误模式,形成ai_mistake_patterns.md | 我的模式库中有一条:“当涉及CANFrame解析时,AI总把payload[0]当作命令字节,实际是header[1]”。此后所有CAN相关指令,开头必加:“注意:CAN命令字节位于header[1],非payload[0]” |
5.4 给观望者的真心话:别等“准备好”,现在就开始“用错”
很多老同事问我:“我英语不好,会不会用不了?”“我没学过Prompt Engineering,是不是得先报个班?”我的回答很粗暴:忘掉“学习AI”,开始“用AI干活”。我第一次用Claude Code时,输入的是“帮我写个Hello World”,它回了我12行Kotlin代码,我一句没看懂。第二天,我直接扔给它一个报错日志:“java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference”,它立刻告诉我:“findViewById(R.id.temp_textview)返回null,请检查XML中id是否拼写为temp_textview,或是否在setContentView()前调用”。那一刻,我明白了:AI不是考试,它是你的即时技术支援。你不需要知道Transformer怎么工作,就像司机不需要懂四冲程原理。你只需要知道:
- 当你卡在Bug里,把日志+相关代码丢给它,它大概率能指出方向
- 当你面对陌生模块,让它“画出调用链图”,比你自己读三小时代码更高效
- 当你被重复劳动淹没,让它“生成100个测试用例”,你来审核
这两个月,我节省了至少120小时的机械劳动,把这些时间用来做真正需要人类智慧的事:和产品经理对齐需求本质、和技术总监讨论架构演进、带新人理解系统脉络。AI没有让我失业,它让我终于有机会,去做一个程序员本该做的、更有尊严的工作。如果你还在犹豫,我的建议只有一个:今天下班前,打开你的IDE,找一个最近让你烦躁的Bug,把日志和代码复制进去,对AI说:“帮我看看这错在哪?”——然后,你就已经开始了。