尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

AI时代手写代码过时了吗?工程能力才是程序员底气

AI时代手写代码过时了吗?工程能力才是程序员底气 最近在技术社群里经常看到类似问题“AI 都能自动生成代码了还有必要手写代码吗”、“初级程序员是不是很快就要被 AI 取代”、“现在学编程是不是等于学怎么给 AI 提需求”这类焦虑在 ChatGPT、Copilot、Cursor 等 AI 编程工具爆发式增长之后变得尤其普遍。甚至有人喊出“手写代码已死”的口号仿佛程序员下一秒就要集体失业。但实际在项目中摸爬滚打过的开发者应该都有一个直观感受AI 确实能帮我们写很多代码但它离“替代手动编程”还很远。真正到了复杂业务、遗留系统、性能调优、线上故障排查的时候手写代码所代表的工程能力反而是决定项目成败的关键。这篇文章我想认真聊聊“AI 时代手写代码是否过时”这个话题。不会只停留在情绪层面而是结合日常开发场景拆解手动编程为什么仍然不可替代以及 AI 时代开发者应该怎么调整自己的学习方向和工作方式。1. AI 编程工具到底发展到什么程度了1.1 从“代码补全”到“对话生成代码”先回顾一下 AI 编程工具的演进这有助于我们理解它们的能力边界。早期的 AI 编程辅助主要是“代码补全”。你写一个函数名它帮你补全后面的参数和逻辑本质上像加强版的智能提示。代表工具是 GitHub Copilot 的早期版本和各种基于 Inception 模型的 IDE 插件。随后进入“对话式编程”阶段。以 ChatGPT、Claude、文心一言等大语言模型为代表开发者可以把需求描述成自然语言让 AI 直接生成完整函数、单元测试、SQL 语句甚至 Dockerfile。到了 Cursor、Windsurf 这类 AI 原生 IDE 出现后AI 不仅能生成代码还能跨文件理解项目上下文自动重构某个模块甚至给出修改建议。从效率上看AI 确实把“编码”这件事的门槛降低了不少。以前写一个爬虫脚本可能要花半小时现在把需求描述清楚AI 几秒钟就能给出一个可运行的版本。1.2 AI 编程的优点和边界AI 编程的优点很突出生成样板代码效率极高比如 CRUD 接口、实体类、DTO、Mapper。对常见算法、正则表达式、日期处理等“通用知识”掌握得很扎实。能辅助翻译旧代码、解释陌生代码、生成单元测试用例。在重构过程中能提供多种方案供选择。但这里有一个关键点AI 生成代码的高效建立在“需求足够清晰”和“场景足够通用”这两个前提之上。一旦业务逻辑复杂到一定程度或者涉及公司内部特有的规则、权限、数据模型AI 的表现会迅速下降。它并“理解”业务它只是根据概率预测下一段最可能的代码。这意味着 AI 可以写出“看起来正确”的代码但经常缺少边界条件判断、异常处理、语义正确性和安全性考虑。先看一个最简单的例子让 AI 写一个“获取用户列表”的接口// 文件路径src/main/java/com/example/demo/controller/UserController.java RestController RequestMapping(/api/users) public class UserController { Autowired private UserService userService; GetMapping public ListUser getAllUsers() { return userService.listAllUsers(); } }这段代码表面上看没问题但放到真实项目里至少有这些问题没有分页如果用户表有几十万数据这个接口会直接把内存打爆。没有异常处理数据库异常会直接抛出堆栈。没有权限校验任何一个匿名用户都能拉全量用户数据。没有日志出问题后无法追踪。所以结论是AI 能写代码但它写的是“代码片段”不是“可上线的功能”。把片段变成稳定、安全、可维护的功能仍然需要开发者手动补全大量的工程细节。2. 手写代码为什么仍然不可替代2.1 业务理解是 AI 无法替代的手写代码最重要的价值首先体现在对业务的理解上。举个例子你要实现一个“订单超时自动取消”的功能。表面需求是“下单后 30 分钟未支付就自动取消订单”。但真实业务里你要先弄明白订单状态有哪些已支付、已取消、待支付、退款中、已完成哪些状态需要参与超时判断超时取消之后库存要不要释放优惠券要不要退回如果用户已经使用了积分积分怎么处理是轮询扫描还是延迟消息轮询的频率怎么设计延迟消息可靠性怎么保证如果订单正在被用户操作取消逻辑和支付逻辑并发冲突了怎么办这些问题没有任何一个能靠 AI 自动分析出来因为它们藏在产品需求文档的细节里藏在和运营、产品经理的沟通里甚至藏在历史故障复盘文档里。只有开发者真正理解这些业务规则才能写出正确的代码。AI 可以帮你把“取消订单”的函数体写出来但它不知道你的订单状态机长什么样不知道库存需要回滚不知道优惠券过期时间怎么计算。这就是为什么资深开发者的经验大多不是“写代码快”而是“知道代码应该怎么写”。2.2 架构设计与技术选型依赖人工判断另一个手写代码不可替代的领域是架构设计。当你要设计一个系统的模块划分、接口规范、数据模型、缓存策略、消息队列选型时AI 可以给出通用建议但最终的判断必须由人来做。以“系统要不要引入消息队列”为例。AI 会告诉你消息队列有解耦、削峰、异步等优点但你的系统如果只有每天几万的请求量引入 MQ 反而增加了运维成本和故障点。这种“取舍”不是一个概率模型能帮你决策的它依赖的是对团队规模、业务发展、运维能力的综合判断。再比如服务拆分的粒度。拆得细系统灵活但分布式事务复杂拆得粗开发简单但扩展受限。这个边界在哪里只有熟悉业务和团队的人才能把握。手写代码的过程本质上是在做一系列决策。你写下的每一行代码都代表了你对业务、性能、可维护性的判断。AI 能把代码写出来但把决策权交给 AI 的代价是系统会在不知不觉中积累大量不符合业务场景的技术债。2.3 调试和排障能力完全依赖人AI 时代有一个被很多人忽略的事实AI 能生成代码但它几乎不会帮你调试代码。当线上接口突然超时当数据库连接池被打满当 GC 导致 CPU 飙升当某个事务莫名回滚你需要做的是看日志定位异常发生的位置。分析调用链判断是哪个环节出现了性能瓶颈。查看监控指标确认是内存、CPU、磁盘还是网络问题。结合业务场景推断可能的原因。写测试代码或临时脚本复现问题。修改代码、验证、复盘。这个过程需要的是对系统运行机制的理解、对业务逻辑的熟悉、对日志和监控工具的掌握。AI 可以解释一段报错信息也可以给出“可能是内存泄漏”的推测但它无法像开发者一样完整地走完整个排障闭环。更重要的是排障时你往往需要临时修改代码、打印日志、写小工具验证这些“即兴手写代码”的能力恰恰是程序员最核心的生存技能。一个人如果只会让 AI 写代码遇到线上故障时会非常被动因为连“让 AI 帮我看日志”都需要你先把日志的关键信息提取出来。2.4 代码审查与质量把控代码审查同样是手写代码能力的重要体现。在团队协作中Code Review 的作用不只是“找 bug”更是检查代码是否符合团队规范。判断设计是否合理、是否过度设计。发现潜在的性能问题和安全漏洞。确保新代码和现有架构保持一致。如果你没有手写代码的底子不理解事务的传播行为、索引的原理、并发安全的基本策略你是没办法做好 Code Review 的。AI 确实能帮你审查代码但它的审查往往停留在“代码风格”和“明显错误”层面对于业务语义和架构层面的问题它看不出太多问题。换句话说AI 时代真正重要的能力不是“用嘴写代码”而是“看懂代码、评估代码、改进代码”。3. 手写代码对程序员成长的核心价值3.1 编程思维是在手写代码中练出来的很多新手问“既然 AI 能写代码我直接让它写然后我理解不就行了吗”这个问题看似合理但实际上忽略了编程思维的形成过程。所谓“编程思维”不是记住多少 API而是面对一个复杂问题时能把它拆解成若干小问题再考虑每个小问题的解决方案最后组装成一个完整方案。这种拆解、抽象、组合的能力只能通过大量的手写代码训练来获得。举一个简单的例子。你要写一个工具方法统计一个字符串数组中每个字符串出现的次数。如果直接让 AI 写几秒钟就出来了from collections import Counter def count_strings(arr): return dict(Counter(arr))但如果亲手写过这个逻辑你会经历这样的思考用普通字典还是 Counter需要考虑大小写吗需要考虑空字符串吗数据量很大时怎么优化内存返回的数据结构用什么最合适这些思考才是编程能力成长的来源。AI 直接给你结果相当于跳过了思考过程。如果你长期依赖 AI 写代码写出的功能可能越来越多但解决新问题的能力反而可能下降。这也是为什么很多资深开发者建议新手阶段一定要强制自己手写代码哪怕 AI 已经给出了答案。3.2 深度理解底层原理手写代码的另一个好处是它能倒逼你理解底层原理。你写SELECT * FROM user WHERE age 18如果只是让 AI 生成你可能永远不知道这条 SQL 为什么在全表扫描时性能很差。但如果你自己手动建过表、插过数据、分析过执行计划你就能理解索引为什么有用、什么时候应该用组合索引、为什么age 18这种条件可能无法走索引。写 Java 的人如果只让 AI 生成 Spring Boot 接口可能永远不知道 Spring 的 bean 生命周期是什么、事务的默认传播行为是什么、为什么循环依赖在某些版本下会报错。但这些底层知识恰恰决定了你在遇到诡异问题时能不能快速定位。手写代码的过程就是不断把“用工具”变成“懂原理”的过程。3.3 代码主权与职业安全感还有一个不太被谈起但很重要的点手写代码能给你带来“代码主权”。什么叫代码主权就是当系统出现问题、当产品需要调整、当老板问你“这个功能是怎么实现的”时你能立刻给出答案而不是说“这是 AI 生成的我也不完全清楚”。这种掌控感带来的职业安全感是 AI 替代不了的。反过来如果一个人长期只做 AI 代码的“搬运工”和“拼接工”一旦 AI 工具升级或者换了新的模型他之前积累的“使用技巧”可能瞬间失效但底层的手写代码能力、系统设计能力、排查能力却是长期稳定增值的。所以我一直认为AI 时代程序员的职业安全感不是来自“我会用更先进的 AI 工具”而是来自“即使没有 AI 工具我也能独立把功能做出来、把问题查清楚”。4. AI 时代手写代码的正确姿势人机协作4.1 AI 适合写什么人适合写什么既然手写代码不可替代那是不是意味着要完全排斥 AI当然不是。一个成熟开发者应该学会的是“人机协作”——把 AI 用在最擅长的地方把人工精力集中在最有价值的地方。AI 适合做的生成样板代码、配置文件、DTO/VO/Entity 等重复性强的代码。编写单元测试的骨架生成常见的测试用例。解释不熟悉的技术栈代码快速了解一个开源项目的结构。生成正则表达式、日期处理、字符串操作等通用工具代码。优化已有代码的命名和结构提供重构建议。将一种语言或框架的代码“翻译”成另一种。人工必须负责的业务规则的分析和建模。系统架构、模块划分、接口设计。核心算法和业务逻辑的编写。异常处理、并发控制、事务边界、安全校验。性能调优、线上问题排查。代码审查、技术方案评审。与产品、测试、运维的沟通协作。4.2 一个典型的 AI 协作开发流程下面我以一个实际开发场景为例演示一个比较合理的“AI 人工”协作流程。假设我们要开发一个“用户注册”接口包含手机号校验、密码加密、验证码校验、用户信息入库四个步骤。第一步让 AI 生成一个初版校验逻辑理解整体思路。// 文件路径src/main/java/com/example/demo/service/UserRegisterService.java Service public class UserRegisterService { Autowired private UserMapper userMapper; Autowired private PasswordEncoder passwordEncoder; Autowired private ValidateCodeService validateCodeService; public void register(RegisterRequest request) { // 校验验证码 validateCodeService.checkCode(request.getPhone(), request.getCode()); // 校验手机号是否已注册 User user userMapper.selectByPhone(request.getPhone()); if (user ! null) { throw new BusinessException(手机号已注册); } // 密码加密 String encodePassword passwordEncoder.encode(request.getPassword()); // 插入用户 userMapper.insert(new User(request.getPhone(), encodePassword)); } }第二步人工审查找出 AI 忽略的问题。这段初版代码至少有 4 个问题手机号格式没有校验。AI 只校验了验证码和是否存在但数据库里可能存了138^%$这种脏数据。没有幂等控制。用户在极端并发下发起两次注册请求可能出现两个相同手机号记录如果数据库没有唯一索引的话。密码长度和复杂度没有限制。攻击者可能用一个超长字符串导致数据库字段溢出或者用一个弱密码导致安全风险。没有事务控制。虽然这里只有一个 insert但如果后续注册逻辑还要同步创建默认角色、默认配置就必须加Transactional。第三步人工补充关键代码把 AI 生成的“半成品”完善成可上线版本。// 文件路径src/main/java/com/example/demo/service/UserRegisterService.java Service public class UserRegisterService { Autowired private UserMapper userMapper; Autowired private PasswordEncoder passwordEncoder; Autowired private ValidateCodeService validateCodeService; Transactional(rollbackFor Exception.class) public void register(RegisterRequest request) { // 1. 基础参数校验 if (!RegexUtils.isPhone(request.getPhone())) { throw new BusinessException(手机号格式不正确); } if (!RegexUtils.isLegalPassword(request.getPassword())) { throw new BusinessException(密码必须为8~20位字母、数字组合); } // 2. 校验验证码 validateCodeService.checkCode(request.getPhone(), request.getCode()); // 3. 幂等控制数据库唯一索引 这里再查一次 User user userMapper.selectByPhoneForUpdate(request.getPhone()); if (user ! null) { throw new BusinessException(手机号已注册); } // 4. 密码加密 String encodePassword passwordEncoder.encode(request.getPassword()); // 5. 插入用户 userMapper.insert(new User(request.getPhone(), encodePassword)); // 6. 注册后续业务初始化默认角色、发送欢迎消息等 initDefaultRole(request.getPhone()); sendWelcomeMessage(request.getPhone()); } }对比这两版代码你可以发现AI 生成代码只花了十几秒但真正让它符合生产标准的是开发者手动补充的边界校验、幂等处理、事务控制、异常语义。这些内容 AI 不是不会写而是它不知道你的业务需要这些。你只有在手写代码、阅读代码、审视代码的过程中才能逐步建立这种“敏感性”。4.3 如何向 AI 提问提升生成代码质量既然要用 AI掌握提问技巧也很重要。很多人抱怨“AI 生成的代码根本不能用”其实往往是因为需求描述不够具体。同样让 AI 写一个分页接口这样提问效果更好请帮我实现一个用户列表分页接口使用 Spring Boot 3.2 MyBatis-Plus。 要求 1. 返回统一响应体 RT。 2. 分页参数 pageNum 默认 1pageSize 默认 10pageSize 最大 100。 3. 支持根据用户名模糊查询和根据状态过滤。 4. 查询结果按创建时间倒序。 5. 对 pageNum 和 pageSize 做参数校验。 6. 添加 Service 层和 Controller 层的完整代码。描述得越清楚AI 生成的结果越接近可用的代码。但你仍然需要审查它生成的代码是否符合项目里的异常处理规范、日志规范、权限规范。这就是“人机协作”的核心AI 负责把工作量完成 60%剩下的 40% 靠人工精修。5. AI 时代的开发者技能树应该怎么调整5.1 基础能力仍然要打牢先说结论数据结构和算法、操作系统原理、计算机网络、数据库原理、设计模式这些东西不但不能扔反而比以前更重要。为什么因为 AI 解决的是“已知问题的已知解法”而你在真实项目中遇到的大多数问题是需要你基于底层原理做判断的开放性问题。不懂数据库的索引原理你连给 AI 提需求都提不准不懂并发模型你甚至描述不清“什么是线程安全”。举个例子你对 AI 说“帮我写一个线程安全的计数器”AI 能给你AtomicInteger的实现。但如果你问它“什么时候用AtomicInteger什么时候用synchronized什么时候用LongAdder”它给的答案往往是泛泛而谈。最终选择哪个方案还是取决于你对并发程度的预估。基础能力决定了你能不能看懂 AI 代码、能不能发现 AI 的坑、能不能提出准确的问题。5.2 把重点从“怎么写”转向“为什么这么写”过去我们学习一门新技术习惯是“先看看怎么写”比如学 Redis先学set/get命令学 Spring Boot先写一个 HelloWorld。AI 时代这种学习方式会被大幅压缩。因为类似“Redis 常用的 5 种数据类型怎么用”、“Spring Boot 怎么创建一个 Web 项目”这种问题AI 的回答已经足够好完全不需要你花大量时间背 API。但有一个问题是 AI 很难帮你解决的为什么这个项目要用 Redis 而不是本地缓存为什么这个模块要拆成独立的服务为什么这个接口要设计成异步的这些问题只有在真实的业务场景中结合成本和收益去权衡。所以建议把学习重点从“怎么写”转向“为什么这么写”。多问自己几个问题这个框架为什么这样设计解决了什么痛点这段代码为什么要加这个判断不加会出什么问题这个数据结构为什么比另一种更合适这个系统的瓶颈在哪为什么是这里带着这种思路去读优秀开源项目源码去复盘线上故障成长速度会快很多。5.3 掌握 AI 时代新增的“软技能”除了传统技术能力AI 时代还催生了一些新的能力要求。需求描述能力能把模糊的业务需求转化为清晰、可执行的技术描述这样 AI 才能更好地辅助你。代码审查能力AI 生成代码之后你要有能力快速判断哪些能用、哪些要改、哪些必须重写。风险判断能力知道哪些功能可以放心交给 AI哪些功能风险很高必须人工把关。比如支付、权限、数据处理等核心链路建议人工编写并配合充分的测试。工具整合能力熟悉 AI 编程 IDE如 Cursor、AI 代码补全插件如 Copilot、AI 代码审查工具并能够把它们融入日常开发流。这本身也是一种工程能力。快速学习能力AI 工具迭代速度极快今天用这个模型明天可能换新的。保持好奇心持续尝试新工具但不要盲目追新。6. 常见认知误区与 FAQ6.1 “AI 生成的代码不需要测试”这是最危险的一个误区。AI 生成代码只能证明“模型认为这段代码合理”不代表它满足你的业务需求。AI 代码里常见的隐藏问题包括边界条件缺失空值、超长值、并发冲突。依赖注入方式不符合项目规范。事务边界错误导致部分写入成功、部分失败。安全漏洞如 SQL 注入、越权访问。所以 AI 生成的代码必须走和手写代码一样的流程单元测试、Code Review、集成测试。绝不能因为是 AI 生成的就跳过质量保障步骤。6.2 “手写代码就是不用 AI 工具”不是。手写代码是一种能力不是一种形式。成熟的开发者会根据自己的需要灵活决定哪些代码用 AI 辅助哪些代码必须亲手写。真正重要的是即便 AI 不在了你也有能力把任务完成。把 AI 当杠杆是聪明的做法把 AI 当唯一支柱则很危险。6.3 “新手学编程可以直接学提示词工程”不建议。提示词工程更像是一种使用技巧它的底层仍然是语言理解和项目语境。一个不懂编程的人很难通过提示词描述清楚“我要一个线程池执行异步任务”这类需求。只有先学编程基础理解变量、函数、数据结构、控制流才能真正用好 AI 编程工具。下面整理一个 FAQ 表格方便快速查阅和收藏问题回答AI 能完全替代程序员吗短期内不能。AI 能生成代码但不能替代业务理解、架构设计、排障、审查和决策。手写代码会被淘汰吗不会。手写代码所代表的工程能力是 AI 时代最稀缺的资产。新手学编程还要手写代码吗建议前 1-2 年坚持手写打好基础之后再逐步加入 AI 协作工具。如何提升向 AI 提问的能力多提供业务上下文、环境版本、期望结果、约束条件并让 AI 分步输出。AI 代码可以直接上生产吗不行必须经过完整的测试、审查、验证流程。哪些模块绝对不能完全交给 AI支付、权限、数据删除、资金操作、用户隐私等核心链路。7. 我的建议把“手写代码”当成一种长期投资最近在一些技术社群里看到一种风气谁还在手写代码谁就显得“落后”谁用 AI 写得多谁就“先进”。我觉得这种二元对立的看法没有意义。工具是为人服务的不是用来划分阵营的。AI 诞生之后程序员的定位从“把需求翻译成机器语言的人”逐步升级为“定义问题、设计方案、把控质量的人”。这种升级不仅没有降低手写代码的重要性反而让手写代码所代表的深度思考能力变得更加值钱。你想一想如果 AI 可以解决所有“怎么写”的问题那人与人之间拉开差距的是什么是你能不能想到要做什么、能不能判断方案好不好、能不能在系统出问题时快速恢复。这些都是写代码的基础上生长出来的判断力。所以我的建议很直接不要因为用了 AI 工具就停止手写代码。不要因为 AI 能补全代码就不去理解代码背后的逻辑。不要因为 AI 能解释错误就不去学习调试和排障。不要因为 AI 能生成单元测试就不去思考测试边界和覆盖率。把时间拉长看手写代码的能力会在你面对复杂系统、紧急故障、关键决策时给你带来巨大的回报。它是一项值得长期投入的技能也是程序员在 AI 时代最有底气的护城河。最后用一句话收尾AI 能帮你写出一百段代码但只有你自己知道其中哪一段是项目真正需要的。保持手写代码的习惯不仅是为了保住饭碗更是为了让自己的思考能力不退化。如果这篇文章对你有帮助建议收藏备用。后续还可以继续聊聊AI 辅助编程的工具链搭建、如何用 Cursor 高效开发完整项目、AI 时代如何做好技术方案评审。有需要的话可以在评论区告诉我。
返回列表