18 · 案例的选择:典型性 vs 边缘性
你写教程,有没有过这种挫败:
你举了个例子,自己觉得特贴切——“上次我们那个支付链路,因为跨行清算延迟,导致对账差了三毛钱,排查了两天”——你写得津津有味,读者却划走了。他心里想的是:“跨行清算?三毛钱?这破事跟我有什么关系,我代码里遇不到。”
你举的例子,对你来说是血泪史,对读者来说是别人的闲事。
反过来,另一种例子你一定见过:某大厂 PPT 上讲架构,开篇就是”双十一零点流量是平时的 100 倍,我们的系统扛住了”。你听得热血沸腾,记了很久。但细想,你一辈子遇不到双十一那种流量。这例子对你”典型”吗?不典型。但它震撼。
这两类例子,一类叫”典型”,一类叫”边缘”。它们不是好坏之分,是分工不同。选错了场合,典型的变无聊,边缘的变浮夸。
这一章讲:案例怎么选,才能让读者”既觉得跟自己有关,又记得住”。
一、先问对问题:你举例子,是为了什么?
很多人举例子,是为了”证明我对”。这动机就歪了。读者不关心你对不对,他关心”这跟我有没有关系”。
例子在正文里只有两个正当功能:
功能一:建立共鸣(典型性)。 让读者觉得”这情况我天天遇到”。共鸣一建立,他就不划走了,因为”这是我的事”。
功能二:建立记忆(边缘性)。 让读者觉得”这情况太极端了,我得记住”。极端案例像钉子,钉进脑子拔不出来。
典型例子回答:“这跟我有关系吗?“——有。 边缘例子回答:“这值得记住吗?“——值得。
你写作时得先想清楚:这一段,我是要让读者”觉得跟自己有关”,还是要让他”记住这个教训”? 目的不同,选的案例类型不同。
反问你:你上一次举例子,是想”让他有共鸣”还是想”让他记住”?还是根本没想,随手抓了个自己印象深的?
二、原理:典型性与边缘性,是两个坐标轴
把案例放在两个维度上看:
- 典型性(常见度):读者遇到这情况的频率。高 = 典型,低 = 边缘。
- 冲击力(记忆度):这案例让人记住的强度。高 = 震撼,低 = 平淡。
组合出四种案例:
| 冲击力低 | 冲击力高 | |
|---|---|---|
| 典型性高 | 日常小坑(适合教程主线) | 典型但惨痛(最佳教材) |
| 典型性低 | 纯边缘平淡(别用) | 极限案例(适合演讲/开篇钩子) |
教程、文档、博客——主案例要落在”典型性高”那一列。因为读者是来学”我常遇到的事怎么处理”的。你通篇举双十一,他学不到自己能用的事。
演讲、开篇、复盘开场——可以用”典型性低但冲击力高”的极限案例。因为它要的是”抓住注意力”,不是”教日常操作”。双十一开场,是为了让老板/听众先”哇”一下,再听你讲平常的限流。
最该避开的,是右下角”典型性低 + 冲击力低”——纯边缘又平淡的例子。比如”我同事有次把测试库当生产库清了”。既不是你常遇的(典型性低),又不算多震撼(冲击力低,顶多一笑)。这种例子,除了凑字数没用。
三、三类案例的”适用场合”
1. 典型案例:教程的骨架
教程里 80% 的例子该是典型案例。特征:读者高频遇到、场景普适、能直接套用。
“你写了一个
for循环查数据库,每次循环都开连接,1000 次循环开 1000 个连接——这就是典型的 N+1 查询。”
这个案例典型到爆炸:几乎每个写过后端的人都干过。读者一看”啊对对对我就是这样”,共鸣建立,接着你讲怎么改(批量/连接池),他立刻能用在自己代码上。
典型案例的价值:可迁移。读者学完,明天就能在自己的项目里用。这是教程的核心交付。
2. 边缘案例:记忆的钉子
边缘案例典型性低,但冲击力高。适合用来钉牢一个容易忘的原则。
“某交易所因为时间戳用了 32 位整数,在 2038 年 1 月 19 日 03:14:07 之后,系统时间回滚到 1901 年,交易全乱。”
这案例你遇不到(典型性极低),但冲击力极高——它把”时间要用 64 位”这个枯燥原则,钉成一根忘不掉的钉子。读者从此写时间戳,会想起 2038 这个鬼故事。
边缘案例的价值:不可迁移,但不可忘。它不教日常操作,它教”别犯这种蠢”。适合放在”原则强调”处,不适合做教程主线。
3. 反面案例:认知的对照
还有一类特殊案例——你犯过的错、踩过的坑。它的典型性看运气,但它的价值在”真实”:读者知道这是真事不是编的,信服度翻倍。
“我 2019 年写过一段
if err != nil { log.Println(err); return nil }——把 error 吞了还返回 nil,调用方以为成功,其实啥也没干。这个 bug 在生产躺了三个月。”
反面案例的真实感,是正例比不了的。读者看正例觉得”道理我都懂”,看反例觉得”卧槽我也这么干过”。所以教程里,正反案例配对效果最好:先讲对的怎么写,再亮一个真实的错法,读者印象最深。
四、选案例的三条标准
动手选案例前,拿这三条过一遍:
标准一:读者能代入吗?(典型性过滤) 如果这个案例只有你公司、你这个项目才遇得到,读者代入不了,别用。换成”任何写后端的人都遇过”的版本。
- 坏:“我们订单系统的
order_status字段从 int 改成 enum 时……”(太具体) - 好:“你把数据库字段从 int 改成 enum,旧代码还在按数字比较……”(普适)
标准二:有对比吗?(记忆度过滤) 好案例自带”改前 vs 改后""踩坑 vs 避坑”的对比。没有对比的案例,平。
- 坏:“我们用缓存提升了性能。“(平,没对比)
- 好:“没缓存时查库 200ms,加缓存后命中率 90%、降到 5ms——快了 40 倍。“(有对比,记得住)
标准三:能推广吗?(可迁移过滤) 案例讲完,读者能不能抽象出一条”我也能用的原则”?不能推广的案例,是孤例。
- 坏:“我们那天就是运气好,刚好运维在线。“(不可推广)
- 好:“我们那天能救回来,是因为有兜底脚本——所以关键路径都要有可手动触发的兜底。“(可推广成原则)
三条都过的案例,才是好案例。
五、反例:你正在犯的三种案例病
病一:内部黑话案例
“上次 TPS 项目里,那个 B 端的 C 端化改造,因为中台没对齐,导致……”
读者:TPS 是啥?B 端 C 端化是啥?中台是啥?——全是你公司内部的词。这种案例,出了你们工位就失效。解法:翻译成普适场景。“一个服务要同时给内部系统和终端用户用,但底层字段没统一,导致……”
病二:孤例当规律
“我朋友公司用了微服务,结果运维崩了,所以微服务不好。”
一个朋友的孤例,推不出”微服务不好”。这是用边缘案例当普遍结论,逻辑谬误。边缘案例只能”钉教训”,不能”证规律”。要证规律,得用数据或多案例。
病三:例子比论点还长
你用 800 字讲一个案例,只为说明一个 20 字的道理。读者读完案例,忘了你要讲啥。案例是论据,不是主角。案例长度应明显短于它服务的论点展开。一条经验:案例占该段 1/3 以内,论点展开占 2/3。
六、一个对照:同一个论点,两种案例
论点:“不要在生产环境用 panic 处理可预期错误。”
用典型案例(教程体):
“你写一个解析配置的函数,配置格式错了你就
panic。结果运维改配置手滑一个字符,服务起不来,整个实例崩了。可预期的错误(格式不对)不该panic,该返回 error 让调用方决定怎么处理。”
读者:对对对我写过这种。共鸣 + 可迁移。适合教程正文。
用边缘案例(钉钉子):
“某公司的配置解析用
panic,一次例行发布改错一行配置,上千个实例同时panic起不来,全网宕机 40 分钟。事后复盘:可预期错误绝不该panic。”
读者:卧槽。冲击力极高,但典型性低(你不会天天全网宕机)。适合复盘开场/原则强调。
最佳组合: 先典型案例讲”你也会犯、怎么改”,再亮边缘案例”犯了的后果能多惨”。读者先共鸣(这我会),再震撼(那我得改)。一正一反,钉子钉透。
七、心法:案例是论点的证据,不是装饰
这章心法:
你举的每个例子,都要能回答”所以呢”——它证明了哪个论点? 答不上来的例子,是装饰,删。
很多人写东西爱堆案例,觉得”例子多显得有料”。但例子多不等于有料,例子对才等于有料。一个精准的典型案例,顶十个浮夸的边缘案例。案例是论点的雇佣兵——你雇它来打仗(证明论点),不是来阅兵(显得阵仗大)。
反问你:你上次写东西,举的例子,有多少个能明确说出”它证明了哪句论点”?说不出的一半,其实是凑数的。
八、思考题
思考题一: 你想讲”数据库索引不是越多越好”,请分别设计一个典型案例(读者常遇)和一个边缘案例(震撼),并说明各自用在什么场合。 思考题二: “反面案例比正面案例更让人记住”——为什么?你在学技术时,印象最深的是哪个反面案例(自己踩的坑)?它为什么忘不掉? 思考题三: 内部黑话案例(“我们 TPS 项目的 B 端改造”)为什么出了工位就失效?怎么改成才普适?
九、参考答案
思考题一:
典型案例(教程正文用):
“你给
user表加了 8 个索引,每次插入都要更新 8 个 B+ 树,写入从 1ms 飙到 5ms。其实常用的查询只用其中 2 个索引,剩下 6 个是’以防万一’加的。”
读者:对对对我表也一堆索引。共鸣 + 可迁移(删多余索引)。
边缘案例(原则强调用):
“某业务给一张热表加了 20 个索引,写入慢到上游超时,促销日直接雪崩。复盘发现一半索引从没被查询命中。”
读者:卧槽。冲击力高,钉住”索引多会拖写入”这个原则。
思考题二:
反面案例忘不掉,是因为它带”痛”。正面案例是”正确操作”,读起来顺,但没情绪钩子;反面案例是”真实犯过的错 + 后果”,读者代入”我也可能这样”,情绪参与度高,记忆深。我印象最深的反例是早年把测试库当生产库 DROP 了——不是记得操作,是记得那种”完了”的胃疼感。情绪是记忆的胶水。
思考题三:
内部黑话案例失效,因为读者没有你的语境:他不知道 TPS 项目是啥、B 端 C 端化指啥。案例的价值靠”读者能代入”,代入需要共享语境,黑话切断了语境。改法:抽掉公司专属词,还原成普适技术场景——“一个服务要同时服务内部系统和终端用户,但底层字段定义没统一,导致两边解析出错”。去掉专有名词,保留技术矛盾,案例就普适了。
十、动手练习
- 找一篇你写过的教程/文档,标出所有案例,用”三条标准”(能代入/有对比/能推广)逐条打分,删掉不过标的。
- 给你最熟的一个技术坑,写一正一反两个案例:典型案例如何避坑(教程体)+ 边缘案例后果多惨(钉钉子)。
- 把一个你公司的内部黑话案例,改写成普适技术场景,对比”代入感”差多少。
自评标准:
- 留下的案例都能说出”证明了哪句论点” → 不是装饰过关。
- 教程案例典型性高(读者能代入)、演讲案例冲击力高 → 分工过关。
- 没有”典型性低且冲击力低”的废案例 → 筛选过关。
十一、小结
- 案例两个功能:典型性建立共鸣(跟我有关系),边缘性建立记忆(值得记住)。
- 四类组合:典型+平淡(教程主线)、典型+惨痛(最佳教材)、边缘+震撼(演讲钩子)、边缘+平淡(别用)。
- 选案例三条标准:读者能代入、有对比、能推广。
- 三种案例病:内部黑话、孤例当规律、例子比论点长。
- 心法:案例是论点的证据,不是装饰。答不出”所以呢”的例子,删。
十二、实战加深:建你自己的案例库
好作者不是每次现想案例,是有一座案例库。你踩过的坑、见过的事故、读过的复盘,分类存好,写时随手取。
建库三栏:
| 标签 | 案例 | 用途 |
|---|---|---|
| 典型-并发 | N+1 查询、连接池打满、goroutine 泄漏 | 教程主线,读者代入 |
| 边缘-惨痛 | 2038 时间戳回滚、rm -rf 生产库、跨时区对账差三分钱 | 钉原则,震撼记忆 |
| 反面-自己 | 吞 error 返回 nil 躺三个月、测试库当生产库清 | 真实感最强,读者共鸣 |
你每遇到一个值得记的案例,丢进对应栏。写教程时从”典型”栏取主线,讲原则时从”边缘/反面”栏取钉子。库越厚,你写东西越不用”硬编例子”,例子自己跳出来。
而且——你写五年 Go,库里至少有几十个真案例。你不是”没东西写”,是”没存”。现在开个 cases.md,把记得的坑丢进去,它就是你的素材矿。
十三、案例与论点的匹配表
写之前,拿论点去库里匹配案例,不是拿了案例硬凑论点。匹配逻辑:
- 论点”日常操作类”(怎么写对)→ 匹配典型案例(读者常遇)。
- 论点”原则警告类”(别犯某错)→ 匹配边缘/反面案例(震撼/真实)。
- 论点”决策类”(A 还是 B)→ 匹配对比案例(A 翻车 B 成了,或反之)。
错配的后果:用边缘案例讲日常操作(读者”这我遇不到”),或用典型案例钉原则(读者”这不算惨,记不住”)。匹配对了,案例才发力。
十四、附:案例与读者画像的匹配
选案例前,先想”读者是谁”,同样的论点,对不同读者案例不同:
- 写给新人:用典型案例(他天天遇),别用边缘(他没语境,记不住)。新人要”我能用”,不是”好震撼”。
- 写给老板/评审:用边缘+数据案例(震撼+可信),别用典型琐事(他觉得”这有啥”)。决策者要”值不值得做”,震撼案例帮他拍板。
- 写给同行高手:用反面/踩坑案例(真实感强,他共鸣”我也干过”),别用基础典型(他觉得”这还用讲”)。
同一论点”要限流”,三套案例:
- 新人:“你没限流,突发打满连接池,请求全阻塞。“(典型)
- 老板:“去年大促没限流,全站 40 分钟不可用,损失 200 万。“(边缘+数据)
- 同行:“我见过有人用
time.After做超时,每次请求建个 timer 不释放,高并发下 GC 压力爆了——限流没做对,一样漏。“(反面,高手懂)
案例库里的案例,按”适用读者”打标签,写时按读者取。这是”以读者为中心”在案例选择上的落地。
案例库长期维护: 每月往里丢 1-2 个新案例(你当月踩的/见的),半年就是 30+ 案例的矿。写时不再”硬编”,随手取。且案例随时间更新——你三年前的”边缘案例”可能现在变”典型”了(技术普及),定期回看重标典型性。
反面:当案例变成”堆砌”(实战加深)
典型性讲完,讲一个对称的错:案例不是越多越好。新手常犯”恐空症”——怕一章太短,就拼命往里塞案例,结果典型案例被边缘案例淹了。
看这段:
并发问题很常见。比如你下单时库存超卖;比如你转账时余额对不上;比如秒杀时请求堆积;比如定时任务重复跑;比如消息消费重复;比如分布式锁失效;比如……
列了六个案例,读者记住了几个?大概率是零。因为没有一个被展开,全是”比如”带过的名词。案例堆砌 ≠ 案例充实,它只是把”信息密度”伪装成”内容丰富”。
正确做法:选一个最典型的(库存超卖),展开讲清它的发生链路、为什么会发生、怎么防;其余的用一句话归类:“类似地,转账对账、秒杀限流、消息幂等,本质都是同一类问题”——点到为止,把读者的注意力留给那个被讲透的。
怎么搭一个自己的”案例库”(实战)
好案例是攒出来的,不是现想的。建议你建一个文档,按主题收案例:
- 每个案例记三样:场景、反直觉之处、你从中提炼的结论;
- 写文章时从库里挑”最典型 + 最反直觉”的那个,而不是”最先想到”的那个;
- 定期回看,把讲烂了的换掉,把新遇到的补进来。
时间久了,你写任何主题都能三秒调出一个好案例。这是”把内容写充实”的人,和”每次现编例子”的人,真正的差距所在。
案例的”反例”用法(实战加深)
案例不只用来”证明”,还用来”证伪边界”。好作者会讲一个”反例”:在什么情况下这个做法会翻车。
讲”缓存提速”,配一个反例”缓存击穿——热点 key 失效瞬间流量全打到库,反而更慢”。读者读完不仅知道”要用”,还知道”用的前提”。这比只堆正面案例扎实得多。
实战:给你正在写的任何案例,补一句”但它的边界是…/ 在 X 情况下它会失效”。一句反例,让你的案例从”宣传”变成”分析”。读者要的不是”这个方法好”,是”这个方法好到什么程度、在哪儿会翻车”——后者才是他做决策要的。
综合实战:从零搭案例库并写一篇短文
前面讲了典型性、反例、密度。这节把这三样串起来,做一次完整实战,主题”Go 并发”。
第一步:攒库(30 分钟)。 写 5 个案例,每个记三样:场景、反直觉之处、结论。
- A 库存超卖:两请求同读”剩 1”都通过,卖成 2。反直觉:读写非原子。结论:并发读写要加锁或原子操作。
- B goroutine 泄漏:起的 goroutine 等 channel 没人写,永阻,内存涨。反直觉:goroutine 不自动回收。结论:起之前想清退出条件。
- C channel 死锁:无缓冲 channel 写没人读,直接 panic。反直觉:写会等读。结论:读写要配对。
- D 锁竞争:10 协程抢一把锁,吞吐低于串行。反直觉:锁非越多越安全。结论:缩小临界区。
- E context 取消:请求超时下游不知还在算。反直觉:超时不自动传。结论:传 context 监听取消。
第二步:挑典型。 写”为什么 Go 并发容易出 bug”,挑 A——最典型、最反直觉、读者大概率踩过。其余一句归类:“goroutine 泄漏、死锁、锁竞争,本质都是并发协调没想清。”
第三步:加反例。 A 之后补一句边界:“但加锁不是银弹——锁太粗反而竞争(案例 D),所以要缩临界区。” 读者读完不仅知”要加锁”,还知”加到什么程度”。
第四步:控密度。 全篇就一个展开案例 + 一句归类 + 一句反例。不堆 B/C/D/E。读者记住的是 A 和那条结论,不是五个名字。
跑完这四步,你体验到的就是”案例选择”的全部心法:攒库、挑典型、加反例、控密度。这四步,写任何技术文都通用,也是你和”每次现编例子”的人真正的差距所在。
心法卡:
例子不是阵仗,是证据。
问它:证明了哪句论点?答不出,删。
教程用典型(读者代入),演讲用边缘(读者震撼)。
一正一反配对,钉子钉透。
下一章讲”故事的钩子”——读者打开你文章三秒就决定走不走,开头那一钩,决定了你全篇的命。