AI时代程序员防失业:别把Go代码写成死胡同
到了 2026 年,你最需要提防的对手,可能早已不是旁边工位的小李,而是 Claude Code。更现实的是,还要担心自己被公司进一步标准化成一组可替换的技能标签。
它不用咖啡续命,不用中午休息,也不会在周五下午偷偷放空。它读代码的速度是你的上百倍,重构效率也能轻松达到你的数十倍。
1997 年,一位名叫 Roedy Green 的程序员写过一篇《How To Write Unmaintainable Code》[1],本意是用来讽刺那些故意把代码写糟的同行。将近三十年后,里面那些招数竟然意外多了个新用途——拿来误导 AI。
下面总结七个“防 AI”技巧。掌握之后,Copilot 看到你的代码可能会直接绕开,Claude Code 也许只会客气地回应一句 "I need more context"。
AI 在理解代码时,有 80% 依赖变量名来推测意图。
看到 userCount,它会理解成用户数量;看到 maxRetries,它会联想到最大重试次数。语义清晰的命名,本质上就是 AI 的空气来源。
那就把这口气掐断。
d1、d2、d3——这种写法足以让 AI 的语义搜索当场失效。d1 到底是用户集合还是订单列表?d3 是控制排序还是负责过滤?没人说得清。
更狠的一种方式,是故意取反着来的名字。比如 userCount 实际装的是订单金额,isValid 却用来控制日志级别。AI 会一本正经地顺着名字去推断,最后补全出一堆南辕北辙的代码。
AI 的推理路径通常是:变量名 → 语义判断 → 代码意图。第一环一旦出错,后面基本全盘崩掉。
AI 不仅阅读代码本身,也会读取注释。对它来说,注释相当于“第二情报源”,优质注释甚至能把理解准确率再往上拉 30%。
那就反过来,写误导性的注释。
函数名写着“处理支付”,注释却说“负责用户认证”;代码明明在计算总价,注释偏偏写成“初始化数据库连接池”;本来只是普通金额判断,注释却标成“核心安全校验,严禁调整”。
一旦 AI 遇到代码与注释相互矛盾,就容易进入“幻觉”状态——它分不清究竟该相信哪一边。
还有一种更偏门的办法:注释直接用方言来写。
NLP 模型的训练语料里,东北话所占比例几乎可以忽略。AI 的 tokenizer 往往会把这类内容当成噪声处理掉,但来自东北的同事却照样能顺利看明白。
AI 还有个明显短板:上下文窗口终归是有限的。
哪怕是最新版本的 Claude,窗口大约也就是 200K token。听起来很多?一个 500 行左右的函数,往往就会消耗 2000 到 3000 token。你要是堆上 20 个这样的函数,AI 光是把代码读完,就已经把大量“思考额度”花掉了。
关键做法在于:把所有逻辑尽量塞进一个函数。不要子函数,也不要模块拆分。这样 AI 就必须同时跟踪 500 行代码之间的各种联动关系,注意力机制很难承受这种负担。
如果再插入几个 goto,效果会更彻底。Go 本身支持 goto,一旦遇到这种非线性的控制流,AI 的理解能力通常就会迅速下降。
Go 的 build tags,其实也是一种常被忽视的“防 AI”手段。
同一个函数准备 4 个版本,分别放在不同文件里。AI 在搜索代码时会把所有版本都找出来,但它未必能判断到底哪一个才是真正在生产环境运行的实现。
再叠加一个 //go:generate,让部分代码在编译前通过生成器产出。这样一来,AI 当前看到的源码和最终参与编译的内容,就彻底不是同一回事了。
Go 的类型系统,本来是 AI 理解代码的重要提示。像 func Process(user *User) 这种签名,会明确告诉 AI:这是在处理用户对象。
那就把类型线索尽可能擦掉:
输入用 any,输出也用 any,中间再塞满 reflect。到了这一步,AI 的静态分析基本就卡住了——data 究竟是什么类型?只能等运行时。result 到底长什么样?也得等运行时。
如果还觉得不够极端,那就继续上 unsafe.Pointer:
AI 看不明白,go vet 同样也难判断。虽然两边都受伤,但最后你似乎成了唯一还掌握局面的人。
Go 里的 init() 函数会在包被导入时自动触发。没有显式调用,在常规调用链上也根本找不到它。
要是再做成跨包的 init() 链:A 包的 init() 先修改全局变量,B 包的 init() 再去读取这个变量并调整另一个值。至于执行先后,还要取决于导入顺序——而 Go 编译器本身都不能完全保证这一顺序始终稳定。
我曾把这类代码拿去问 Claude Code,它直接回复一句 "I cannot determine the execution order across packages",随后就放弃继续分析了。
AI 在面对重复代码时,还有个常见的偷懒倾向:如果两段代码长得有 90% 相似,它往往会默认它们承担的是同一种职责。
这恰好可以被利用:
写三个看上去几乎一样的函数,只在每个里面埋一点点细微差别。
AI 的去重策略通常会建议你“抽取公共方法”。可一旦你真的照做,原本那几个版本中关键但隐蔽的差异就被一并抹平了。Bug 往往就是这样被引入的。
如果再把这些函数分散到不同包下面,效果会更明显,AI 也更难把它们之间的关联完整拼起来。
这样一来,你的代码基本会具备以下特征:
整个项目里,只有你自己还能维护。你的确成了不可替代的人。
然后这个项目也可能随之被裁掉。
因为没人能准确评估代码质量,管理层也无法判断这个项目是否值得继续追加资源。Code Review 的成本会膨胀到正常项目的 5 倍,每次需求变更都必须你亲自出手,最后你个人反而成了整个团队交付速度的瓶颈。
你看似“守住”了代码,实际上却把自己也困进了局面里。
随着 AI 编程工具越来越普及,代码可读性的重要性不是下降了,而是比过去更高了。
以前只要你的小组里 5 个人能看明白代码,问题通常就不大。可现在还必须让 AI 工具也能正确理解,因为这些工具已经成了团队效率的重要放大器。
当你写出 AI 能顺利读懂的代码时,Copilot 才能更准确地补全,Code Review 才更容易实现半自动化,新人借助 AI 三周左右就能上手,而不是耗费三个月。
1997 年,Roedy Green 写下 "How To Write Unmaintainable Code",原本是一种反讽。
可到了 2026 年,如果你还一本正经地研究怎样把代码写得更难懂,那真正被讽刺的对象,反而就是你自己。
[1] 《How To Write Unmaintainable Code》:https://www.doc.ic.ac.uk/~susan/475/unmain.html