我最近在社区里看到一个很有意思的热搜词——"caveman",原意是穴居人、原始人,但在一批开发者圈子里,它正在脱离贬义,变成一种主动选择的工程姿态:把复杂的现代工具链全部丢掉,用最原始、最笨拙、最直接的方式解决问题。我原本以为这只是一次技术复古的玩梗,直到自己试着把一个小项目强制退回"石器时代"来做,才意识到这种返祖式工作法背后,藏着好多现代开发已经丢失的东西。
这篇文章想聊聊我理解的"Caveman"式开发到底是什么、它的适用边界在哪里、我在实际操作中怎么一步步收敛工具链,以及踩过哪些只有丢掉拐杖之后才会撞上的坑。
1. Caveman不等于倒退,而是主动降级复杂度
我第一次看到这个词被用在技术语境里,是在一个用裸tcpdump排查线上网络抖动问题的帖子里,楼主全程没有开Wireshark,没有上APM平台,没有分布式追踪工具,就把问题定位了。底下有人评论:"This is pure caveman debugging."——不是说粗暴,而是说这位老哥回到了一种极原始的、直击物理链路的状态。
理解Caveman,首先要把它和"技术倒退""不拥抱新工具"区分开。它不是拒绝现代化,而是拒绝被工具绑架后那种“看似在解决问题、实际只是在操作系统界面”的假性忙碌。我自己的定义很简单:
Caveman不是回到没有工具的时代,而是回到你完全理解每一层原理的状态,工具只是顺手可选的手套,没有核心依赖。
这句话怎么理解?举个例子,我们现在排查一个接口慢,习惯性动作是打开SkyWalking或者Jaeger,看链路拓扑、看Span耗时。但在Caveman模式下,你会先确认自己能不能用一条curl -w把总耗时拆解成DNS解析、TCP握手、TLS协商、首字节时间四段,再决定问题到底在哪一层。前者依赖工具给出结论,后者依赖自己对HTTP生命周期的基本功,而工具只是验证手段。
我去年带一个刚转行的同事排查超时问题,他打开链路追踪平台,指着一条红链表说“这里Redis慢了”。我让他先关掉平台,手动redis-cli -h host --latency跑一下,再在应用里面用秒表打印一下两条命令之间的墙钟耗时,结果发现Redis本身0.4毫秒就返回了,慢的是服务之间一次多余的重复连接。那一刻我意识到,工具给的信息太多了,反而把人训练得只看结论、不看证据链。
所以Caveman的第一层价值,是把“信息过载”打回“少量但关键的事实”。它让人重新构建从表象到根因的推导能力,而不是在仪表盘之间跳来跳去,靠看颜色猜问题。
2. 我的Caveman落地清单:把现代工具收敛到什么程度
光有理念没有边界,只会变成一场行为艺术表演。我分享一下自己在实际项目里怎么落地Caveman模式,注意,不是把所有工具都扔了,而是给工具分了个三六九等,只留下那些"不可替代"的,把“可替代的”全部换成更原生的操作。
2.1 开发环境:编辑器可以留,IDE全家桶可以砍
我日常写Java/Go/Python,以前喜欢开IDEA或者GoLand,各种插件、代码生成器、重构助手,看起来效率拉满。实际体验是:项目一打开,CPU风扇先转起来,索引要建五分钟,我在这五分钟里刷手机,然后开始在弹窗之间点"是/否"。
Caveman模式下的组合是:一个支持语法高亮的轻量编辑器(我用VS Code,Neovim也行)+ 终端 +grep/rg。代码跳转、查看定义、查找引用,这些动作退回命令行工具来完成。
有人会说,这不就是装个插件的事吗?问题不在于插件本身,而在于“按F12跳转”这个动作太轻松了,导致你跳进了一个依赖网络里,连续点了七八层还回不来。用rg "functionName" ~/src --n了以后,因为他在终端里敲了太多行了。终端里传错行、按错方向键、环境变量没刷新,都会带来复制成本,要rm -rf`重来。真是把自己培养成了野人。
最后一个至暗时刻是,某个环节依赖一个外部二进制,我用apt list和weget一顿操作,结果在里面发现这个包名不对,折腾了二十分钟才意识到。我用的是wget --no-check-certificate去某镜像下包,那个镜像的证书链本来就是坏的,是我的命令里的类型里有一个反斜杠\把URL弄折行了。
在Caveman模式下,没有哪个库是"自动安装"的,所以你就养成了用一个规格清单记录每一个下载动作的习惯。我后来给自己写了一条纪律:每次手动装包前,先问自己三个问题——这个包的真实来源域名是什么、安装后会覆盖现有环境的哪些文件、能不能用当前发行版的包管理器解决。这三个问题在普通的pip install流程里几乎没人考虑,但在Caveman模式下,它们是生死线。
3.4 不带调试器,靠"打印迁移"找到逻辑裂口
真正让我体验到Caveman威力的,是处理一个支付回调幂等问题时,整个应用被要求在完全无DB事务脚本、无断点调试、无日志平台的环境里复现。那个问题在线下测试环境怎么都测不出来,压力一大就会出现重复入账。
我当时的做法非常原始:定义了一个全局唯一请求ID,然后从入口到最后入库,每个关键节点往标准输出打一行defer风格的日志,用两个终端窗口跑,一个跑应用,一个用tail -f实时看。没有ELK、没有Loki、没有trace_id自动透传,纯靠打印。
跑了三轮压测之后,我发现一个异常顺序:偶尔会出现dup-check-passed和status-updated两条日志的时间戳只差1毫秒,但正常情况下它们应该差5毫秒以上。顺着这个时间差,我去翻锁机制,才发现分布式锁的续期线程因为一个GC停顿没有及时续上,锁提前过期,第二个线程进来了。如果我当时开着调试器在单步跟踪,大概率会直接盯着数据流,反而忽略掉GC停顿这种"隐形间隙"。
这段经历给我一个很大的触动:调试器给的是"我猜的流程和实际流程的对比",而打印日志给的是"一条完整的时间线"。前者偏空间感,后者偏时间感,很多并发问题只能通过时间线暴露,空间感根本看不到。
4. 什么人适合Caveman工作法,什么人千万别试
Caveman不是银弹,我把它吹得再高,也得承认它有严格适用边界。盲目返祖,只会把自己搞死。根据我自己的观察和实践,我觉得可以用一个清单来判断。
适合试Caveman的场景:
- 你正在排查一个诡异问题,现有工具已经给出了互相矛盾的信息,你急需回到第一性原理重新推一遍。
- 你刚接手一个遗留系统,技术栈老到没有现代化工具支持,只能用最基础的手段摸清行为。
- 你想训练自己或团队新人的基本功,让他们脱离“自动补全依赖症”。
- 你的运行环境极其受限(内网隔离、最小化容器、嵌入式设备),不得不靠原始手段作战。
- 你发现自己维护了一堆不知道为什么存在的框架、依赖、云服务,想重新评估它们存在的必要性。
不适合甚至危险的场景:
- 项目处于快速原型期,首要目标是用最低成本验证想法,这时候该用现成脚手架就用,别为了姿态返祖。
- 团队协作场景下,你的队友没有同样的基本功储备,你用Caveman方式留下的线索他们根本看不懂。
- 涉及严格审计、合规要求的产线环境,明确的工具链和操作留痕本身就是硬性要求,不能为了“返祖”牺牲可审计性。
- 你的问题本质上是一个纯粹的“框架配置问题”,花两小时研究手工配置,不如跑一遍官方脚手架快速恢复。
/ 一个非常现实的标准:*Caveman状态应该是你能进得去也出得来的状态,而不是你唯一的状态。*我见过有的开发者把返祖变成一种“我比你们懂得多”的姿态,不写任何注释、不用任何自动格式化工具、拒绝一切代码生成,最后生成出一堆只有自己能读懂的代码,这已经从Caveman滑向了原始部落主义了。
我自己给自己定的规则是:排查阶段、学习阶段、攻坚阶段,切Caveman模式;产出交付阶段、协作阶段、维护阶段,切回标准化模式。这个双向切换的能力,比纯粹追求某一种风格重要得多。
5. 关于"工具仪式感"的背叛:我为什么越来越喜欢那台没有桌面的服务器
闲聊一点感受。我有一台用了很多年的服务器,装的是纯命令行Linux,没有桌面环境,没有图形面板,系统日志直接往串口打。在那台机器上,我做了不少Caveman式的实验。每次折腾完,关掉终端站起来,我有一种在社交媒体上拿再多点赞都换不来的踏实感。
其实我心里清楚,那台机器的效率可能不如云平台上开一台装好监控、自动告警、一键部署的实例。但问题在于,那些现代化的东西都把"我"包得太舒服了——出了问题有告警,跑不动了有伸缩,一切看起来都在自动变好,我的大脑在这种环境里逐渐懒得转动了。
Caveman最珍贵的一点,不是让我重新手搓所有轮子,而是让我记住了所有轮子旋转的基本原理。有一次跟朋友聊,他说这是"必要的低下效率对高阶认知能力的滋养",我大概同意,但不想说得那么玄。用大白话讲,就是:
当你习惯用打火机点烟,突然要求你用钻木取火生个营地篝火,你虽然狼狈,但你会真正理解"火"是什么。
技术世界变化太快,我们太容易在工具的海洋里溺水。每隔一段时间把自己打回Caveman状态,逼问一句“如果没有这个东西,我一个人能不能搞定”,这既是对抗技术焦虑的方式,也是判断一个工具是否真有用的试金石。
最后分享一个小技巧。如果你想尝试Caveman又担心耽误进度,不用一上来就大动干戈。先把强制安装的依赖和工具列个清单,然后标注每一个工具“最近一周我用它做了什么实事情”。很快你就会发现,超过一半的工具只是为了满足“我觉得可能用得到”的安全感。砍掉它们,你的系统变轻了,心智负担也跟着下来,那种像原始人一样掌控每一个字节的感觉,试过一次就很难回去。