古法
二〇二一年深冬,北京西二旗。
周明远把我领进工位的时候,我正在用湿巾擦前任留下的机械键盘。键帽缝隙里全是烟灰和瓜子皮,Delete 键已经磨出了油光。
“别擦了,”他从抽屉里掏出一个黑色 U 盘,啪地拍在桌上,“先把环境装了。CentOS 7 镜像在里面,配不通局域网别下班。”
U 盘上贴着一张泛黄的标签纸,用圆珠笔写着“装机神器”四个字。后来我才知道,这个 U 盘在他手里传了四届实习生,装过至少二十台开发机。
那是我入行的第一天。
周明远,三十二岁,全栈,据说是公司元老级的第 7 号员工。他不喜欢 IDE,用的是 Vim 配一套自己攒了六年的插件配置。他的浏览器书签栏里,前三名永远是 MDN、Stack Overflow 和 Can I Use。
“写代码不是敲字儿,”他端着搪瓷茶杯,眼睛盯着纯黑底色的终端,上面连语法高亮都没有,“是跟机器聊天。你得知道它什么脾气。”
那阵子我们在做一个电商后台的重构。前端是 jQuery 加 Bootstrap,后端是 PHP 5.6。光是那个表单页面的联动逻辑,我就写了两天。三个下拉框,省市区三级联动,数据要从后端接口拉,要缓存,要处理异步竞态,还要兼容 IE 11。
我写得焦头烂额,周明远搬了把椅子坐过来,没用搜索引擎,直接从记忆里给我手写了一个防抖函数。
“你看,这个 debounce,你得理解事件循环。”他用笔在纸上画了一条时间轴,“JS 是单线程的,计时器不是精确的,是宏任务。理解了这一点,你才能写出真正稳的代码。”
那幅画我现在还留着。圆珠笔画的,边角已经被翻卷了。
那个项目我们做了整整四个月。上线那天晚上,周明远请我吃了顿涮羊肉。铜锅里咕嘟咕嘟冒着热气,他喝了口二锅头,难得话多起来。
“你知道我为什么非让你配那个局域网吗?”
我摇头。
“因为你在配的时候,会遇到一百个莫名其妙的问题。网卡驱动不对,路由表冲突,DNS 解析失败。你一个一个解决掉,就知道网络是怎么回事了。以后你写代码出了问题,就知道往哪找。”
他夹了片羊肉,在麻酱里涮了涮,“这叫手感。手感不是练出来的,是磨出来的。”
我当时觉得他说得特别对。现在想想,也的确对。
转折
二〇二三年秋天,公司开始用 GitHub Copilot。
周明远是组里最后一个装的。他盯着那个紫色的图标看了很久,像在看一个不请自来的客人。
“你说它写的代码能信吗?”他问我。
“试试呗。”
他试着写了一个注释:// 将数组按 id 去重。Copilot 瞬间补了一行 reduce 的代码,完美运行。
周明远沉默了几秒钟,把键盘往前一推,站起来去茶水间泡了杯茶。回来以后,他什么也没说,但那个紫色的图标再也没有关掉过。
变化是从那时候开始的。
以前我们讨论问题的方式是“你去翻翻文档”,后来变成了“你问问它”。以前遇到一个陌生的库,要花一个下午读 API 文档,现在直接把代码丢进去,让它解释。以前写单元测试是体力活,现在 Tab 键按三下,断言都给你写好了。
周明远的编程方式也在变。他的 Vim 配置精简了一半,因为很多功能 AI 能直接生成。但他还是保留了一些老习惯——比如坚持用命令行操作 Git,坚决不用 GUI。
“这不是守旧,”他跟我解释,“你知道 SourceTree 在背后执行了什么命令吗?不知道。但敲 git rebase -i 的时候,你知道每一行 pick 和 squash 意味着什么。这就是区别。”
我似懂非懂。
原住民
二〇二四年夏天,公司来了个应届生,叫杨树。
杨树是〇二年出生的,比我和周明远小了快一轮。他报到那天背着一个帆布包,里面只有一台 MacBook 和一副降噪耳机,连充电器都没带——他说公司不是有吗。
周明远习惯性地拉开抽屉,准备递出那个传了多届的装机 U 盘。
杨树看了一眼,笑了笑:“周哥,不用了。”
他打开浏览器,进了一个我们都熟悉的 AI 编程工具的网页版。手指在键盘上敲了一行字——
“帮我在 Mac 上配置完整的 Node.js 开发环境,包括 nvm 安装、全局包配置、以及 SSH 密钥生成,输出每一步的命令。”
回车。
对话框里一行一行地吐出命令,带解释,带注意事项。杨树复制、粘贴、回车,眼睛都没离开屏幕。
七分钟后,环境好了。
“周哥,Git 权限我加好了,你拉我进组就行。”
整个办公室安静了大概三秒钟。周明远手里那个贴着“装机神器”标签的 U 盘悬在半空,最后被轻轻放回了抽屉最深处。
那天下班,我发现周明远没有像往常一样关电脑就走。他坐在工位上,屏幕上是和杨树一样的那个 AI 工具界面。他正在笨拙地、一字一顿地敲着提示词——
“请帮我把这个 Express 中间件重构为 async/await 风格,同时保留错误处理逻辑,并且加上中文注释。”
他敲得很慢,每打几个字就要停下来想想措辞,像是在学习一门新的语言。
我站他身后看了一会儿,没出声。
那一刻我突然理解了什么叫时代的分水岭。
对我和周明远来说,写代码是先学会走再学会跑——从 Hello World 开始,一行一行地理解语法,一个 bug 一个 bug 地调试,在无数次“ undefined is not a function”的报错中,慢慢建立起对计算机的心智模型。
但对杨树来说,他进入这个世界的第一站,是一个对话框。
他没有经历过那个“手写一切”的年代。他不知道在没有 Copilot 的时候,写一个防抖函数需要去翻 Lodash 源码。他不知道 Stack Overflow 曾经是程序员的第一生产力工具。他不知道那些年我们为一个跨域问题能调一下午。
但这不重要。
重要的不是他错过了什么,而是他从一开始就站在了不同的地基上。他的编程思维是“对话式”的——把需求描述清楚,让 AI 生成实现,然后快速验证、调整、迭代。他把精力花在了更高维度的事情上:理解业务、设计架构、评估方案。
“古法”和“新生代”之间,差的不是智力,不是勤奋,是一整套与机器交互的范式。
渡口
故事真正的转折,发生在两个月后的一个深夜。
那天线上出了个事故。一个订单结算的接口在高峰期超时,导致十几笔订单状态异常。杨树排查了半天,找到了问题——一个嵌套了三层的循环里,每次循环都发了一次数据库查询,数据量大时直接打满连接池。
他很快用 AI 生成了一个优化的版本,把嵌套查询改成了联表查询,性能提升了二十倍。他正准备提交代码,周明远叫住了他。
“等一下。”
周明远指着屏幕上那个联表查询的 SQL 语句:“你这条 SQL,在订单表千万级的时候,索引会失效。因为你在 WHERE 条件里用了函数。”
杨树愣了一下。
“而且,”周明远往下滚动了一屏,“你这个联表写法,在 MySQL 5.7 和 8.0 里执行计划不一样。5.7 会走全表扫描。”
杨树仔细看了看,沉默了。
“AI 写得没错,”周明远说,语气出奇地平和,“它只是给了你一条正确的 SQL。但它不知道我们的生产环境还在跑 MySQL 5.7,不知道订单表已经一千二百万行了,不知道这条 SQL 会在凌晨四点被定时任务调用。”
他打开终端,敲了几行命令,调出慢查询日志,指着上面的数字:“看到了吗?这是血的教训。”
杨树没说话,把 AI 生成的 SQL 仔仔细细改了一遍,加了强制索引,拆了联表,做了分页。
提交完代码,杨树突然问了一句:“周哥,这些知识,AI 不能直接告诉我吗?”
周明远想了想,回答了一句话。
这句话我认为是这个时代最准确的注脚——
“AI 能告诉你这条路怎么走。但它不会告诉你,这条路在暴雨天会塌方。因为它没被埋过。”
融合
二〇二五年春天,我们组接了一个新项目——用全新的技术栈重构一个旧系统。
技术选型会上,周明远主动提出用 Cursor 做主力开发工具,用 Claude 做代码评审辅助。
所有人都很意外。
“我试了三个月,”周明远说,“它确实比我快。但我发现一件事——你得知道该问它什么。”
他说,AI 就像一个有无穷知识的实习生,聪明、勤快、不知疲倦,但缺乏判断力。它能写出语法完美的代码,但不知道这段代码放在生产环境里会发生什么。它能给出十种解决方案,但不知道哪一种最适合当前的场景。
“所以问题变成了——谁是这个实习生的 mentor?”
他环顾了一圈会议室,目光最后落在杨树身上。
“以前是我带新人,告诉他怎么写代码。现在是你教 AI 写代码,我来告诉你在什么情况下不该信它。”
杨树点了点头。
那个项目,成了我们组有史以来效率最高的一个。
杨树负责快速产出方案——他把需求拆解成清晰的提示词,让 AI 生成原型代码,十分钟出一个可运行的 MVP。周明远负责把关——他用十几年的经验审视每一处关键逻辑,找出 AI 考虑不到的风险点。
一个快,一个稳。
一个负责“把它做出来”,一个负责“让它别塌”。
河岸
项目上线那天,我们聚餐。还是那家涮羊肉,还是那个铜锅。
周明远破天荒没喝二锅头,要了瓶啤酒。他举起杯子,对着杨树说了一句:
“你们是 AI 时代的原住民。我们是从对面渡河过来的。你们天生就会跟它对话,我们得一个字一个字学。”
他喝了口酒,“但河这边有些石头的位置、水流的急缓、哪个漩涡淹死过人——这些地图在我们脑子里。”
“所以不是谁取代谁。”
杨树把杯子碰上去,接了一句话,我觉得这句话应该记入史册:
“周哥,你们负责记住被淹死的地方。我们负责造更快的船。”
那天晚上散场后,我和周明远走回公司取包。
路过工位时,我看到他打开抽屉,拿出那个贴着“装机神器”标签的 U 盘,端详了一会儿。
“留着干嘛,”他自言自语,“又用不上了。”
但他没有扔掉。
他把 U 盘放回了抽屉最深处,然后关上抽屉,锁好,拿起外套走出了门。
走廊里他的背影被灯光拉得很长。
那一刻我突然觉得,那个 U 盘其实不是工具,是一枚印章,盖在一个时代的扉页上。
上面写着:我们曾经这样写过程序。
而现在,杨树他们正在写新的扉页。
我们还没有完全到彼岸,还在两段河道之间。水声很大,风向不定。
但船已经下水了。
夜雨聆风