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 端化指啥。案例的价值靠”读者能代入”,代入需要共享语境,黑话切断了语境。改法:抽掉公司专属词,还原成普适技术场景——“一个服务要同时服务内部系统和终端用户,但底层字段定义没统一,导致两边解析出错”。去掉专有名词,保留技术矛盾,案例就普适了。


十、动手练习

  1. 找一篇你写过的教程/文档,标出所有案例,用”三条标准”(能代入/有对比/能推广)逐条打分,删掉不过标的。
  2. 给你最熟的一个技术坑,写一正一反两个案例:典型案例如何避坑(教程体)+ 边缘案例后果多惨(钉钉子)。
  3. 把一个你公司的内部黑话案例,改写成普适技术场景,对比”代入感”差多少。

自评标准:

  • 留下的案例都能说出”证明了哪句论点” → 不是装饰过关。
  • 教程案例典型性高(读者能代入)、演讲案例冲击力高 → 分工过关。
  • 没有”典型性低且冲击力低”的废案例 → 筛选过关。

十一、小结

  • 案例两个功能:典型性建立共鸣(跟我有关系),边缘性建立记忆(值得记住)。
  • 四类组合:典型+平淡(教程主线)、典型+惨痛(最佳教材)、边缘+震撼(演讲钩子)、边缘+平淡(别用)。
  • 选案例三条标准:读者能代入、有对比、能推广。
  • 三种案例病:内部黑话、孤例当规律、例子比论点长。
  • 心法:案例是论点的证据,不是装饰。答不出”所以呢”的例子,删。

十二、实战加深:建你自己的案例库

好作者不是每次现想案例,是有一座案例库。你踩过的坑、见过的事故、读过的复盘,分类存好,写时随手取。

建库三栏:

标签案例用途
典型-并发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 和那条结论,不是五个名字。

跑完这四步,你体验到的就是”案例选择”的全部心法:攒库、挑典型、加反例、控密度。这四步,写任何技术文都通用,也是你和”每次现编例子”的人真正的差距所在。

心法卡:

例子不是阵仗,是证据。
问它:证明了哪句论点?答不出,删。
教程用典型(读者代入),演讲用边缘(读者震撼)。
一正一反配对,钉子钉透。

下一章讲”故事的钩子”——读者打开你文章三秒就决定走不走,开头那一钩,决定了你全篇的命。