想象你刚拿到一套毛坯房:四面水泥墙,满地管线,空荡荡的。装修的第一步不是急着刷漆,而是先定格局——哪里做客厅、哪里隔卧室,用粉笔在墙上画出房间的骨架。这就是 Markdown 排版:用最小的符号成本,把文档的“户型图”立起来。接着,水电师傅登场,他用带箭头的图例画出走线回路,哪里接头、哪里分叉一目了然——这是 Mermaid 流程图。再往后,装修工长排出工序传话单:拆旧→水电→泥瓦→木工→油漆,谁先谁后绝不含糊——这是序列图。设计师还喜欢在餐巾纸上画手绘草图,线条微微抖动,却一下子拉近了沟通的距离——这是 Excalidraw。而软装物料清单则像 PlantUML,把每一件家具、每一根横梁分门别类、注明连接关系。最后,靠谱的工头会记一本装修日志,哪天改过哪面墙、为什么改——这就是图表的版本管理。这篇文章,就是带你用一套“装修方法论”,把技术文档从毛坯房装成看得懂、改得动、传得远的专业作品。

岗位关联

掌握这套文档生产线,你的开源项目、技术博客和团队协作文档都会从“能看”升级到“专业”,让技术影响力随代码一起持续累积。

目录
  1. 可视化演示
  2. Markdown排版基础:先画户型图
  3. Mermaid流程图:一张水电走线图
  4. Mermaid序列图:一张工序传话单
  5. Excalidraw架构图:一张餐巾纸草图
  6. PlantUML类图:一份物料分类清单
  7. 图表设计规范:一册装修验收标准
  8. 图表版本管理:一本装修日志
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

Markdown技术写作中通过流程图、序列图与架构图提升可读性。演示Mermaid流程图、序列图与PlantUML架构图的语法结构,并展示图表配色与版本管理规范。

本节配有交互动效(进入视口后自动加载,约 3KB)。

Mermaid流程图:graph TD 矩形节点表示处理步骤 菱形表示条件判断分支 声明式语法定义节点与连接 graph TD → 自上而下布局 文本化声明让图表可被版本管理、易于复用

Markdown排版基础:先画户型图

装修的第一步永远是画户型图。再豪华的吊顶,也救不了一个没有隔断规划的房子:人住在里面,上厕所要穿过客厅,做饭要绕过卧室,一天下来多走两万步。技术文档同理,读者打开一篇文章,第一眼判断的不是字号和配色,而是标题层级。#、##、### 就是墙上的粉笔线,把“客厅”(章节)、“卧室”(小节)、“衣帽间”(更小的节)分得一清二楚。

Markdown 成为技术写作事实标准的原因,是它用最接近纯文本的低成本语法完成了排版:井号定义标题,短横线和数字定义列表,竖线画表格,大于号做引用,反引号包代码。编辑器(VS Code、Typora、Obsidian)会把纯文本实时渲染成漂亮的页面,但底层始终是这份可读的“粉笔稿”。

排版的核心规范是“层级不跳级”。从 ## 直接跳到 ####,等于从二楼直接爬到了四楼,读者气喘吁吁,目录生成、大纲视图、屏幕阅读器也全部断裂。同时每个标题下要维持适度的内容量:内容多就拆小节,小节太空就向上合并。理想状态下,任何一级标题都能同时服务于“扫读找路”和“逐段精读”两种读者。文档适合用多少个层级,与内容量之间存在一个粗略的对数关系:

合格的户型图,没有一堵墙“从地板直插天花板”把客厅劈成两半。文档的每一级标题也应当各居其位——层级分明、密度均匀,读者走进来,一眼就能找到属于自己的房间。

dmax⁡=⌈log⁡2(n)⌉,1≤dmax⁡≤6\displaystyle d_{\max} = \lceil \log_2(n) \rceil, \quad 1 \le d_{\max} \le 6
段落数翻一倍,层级才需要加一层;超过六级,就该把文档拆成两篇。
  1. 统计段落数 n统计正文的段落总数。段落越多,文档的信息密度越高,需要的标题层级也越深。
    n=正文段落总数n = \text{正文段落总数}
  2. 取以 2 为底的对数每多一层标题,可容纳的段落量约翻一倍,因此层级与内容量是对数关系而非线性关系。
    log⁡2(n)\log_2(n)
  3. 向上取整对数结果往往不是整数,向上取整保证层数“够用”。
    ⌈⋅⌉\lceil \cdot \rceil
  4. 限制在 1 到 6 之间Markdown 只支持六级标题,达到上限仍装不下内容,说明文档太长,应当拆分。
    1≤dmax⁡≤61 \le d_{\max} \le 6

Mermaid流程图:一张水电走线图

户型图定完,水电师傅上场。他画的水电图不用文字啰嗦,符号与箭头就说明一切:一条线从配电箱出发,经开关到灯头,再用一个判断框标出“这里接双控”。流程图正是文档里的水电图——它把“先做什么、遇到分支怎么选、最后到哪去”用节点和箭头画成一条可以循迹的回路。

Mermaid 是一门用文本描述图表的轻量语言,像给装修师傅口头报走线:你说“从 A 到 B,B 判断一下,合格去 C,不合格回 A”,它就把图渲染出来。下面这段就是一张完整的流程图:

Mermaid 的语法要点有三条:第一,节点由“ID + 形状”定义,方括号是普通步骤,花括号是判断,圆括号是圆角框,形状就表达了语义;第二,连线有实线箭头 -->、无箭头 ---、虚线 -.-> 三种,信息流向靠箭头方向传达;第三,复杂流程可用 subgraph 把相关节点圈成一族,相当于水电图上的“回路分区”。判断一张图是否“该拆了”,可以借助圈复杂度——边越多、嵌套越深,数值越大,超过 10 就建议拆成多张:

水电图的原则是“回路清晰、接头明确”,多绕一圈都让后期检修想骂人。流程图也一样:一张图画清一条主干,分支单独成图,读者顺着箭头走完,比读十段文字都快。

M=E−N+2P\displaystyle M = E - N + 2P
圈复杂度用三条数一数就能算:连线数减去节点数,再加上两倍的连通分量数。
  1. 统计边数 E流程图中的每一条连线都算一条边,边越多代表分支越密。
    E=图中连线的数量E = \text{图中连线的数量}
  2. 统计节点数 N矩形、菱形、圆角框等每个框都是一个节点。
    N=图中节点的数量N = \text{图中节点的数量}
  3. 统计连通分量 P互相不连通的独立小图块各自算一个分量,整张完整图通常 P=1。
    P=连通分量的个数P = \text{连通分量的个数}
  4. 计算并判断阈值M 值大于 10 时读者容易“迷路”,建议拆图或分组。
    M=E−N+2P,M>10⇒拆图M = E - N + 2P, \quad M>10 \Rightarrow \text{拆图}
mermaid5 行
graph TD    A[需求分析] --> B{方案可行?}    B -->|是| C[编码实现]    B -->|否| A    C --> D[测试验收]

Mermaid序列图:一张工序传话单

装修工地上有两类信息:一类是“水管怎么走”的空间关系,另一类是“明天瓦工进场、后天木工量尺”的时间顺序。后者靠一张工序传话单——谁先、谁后、谁回应谁,写成一排箭头,现场没有一个人会看错。序列图扮演的正是这个角色。

序列图(sequenceDiagram)描述多个参与方之间的消息顺序。参与方用 participant 声明,消息从上到下严格按时间排列:

关键语法有四条:->> 是实线同步调用,-->> 是虚线返回,-) 表示异步发出;activate 和 deactivate 画出参与者被占用的“激活条”,一眼看出谁在等待谁;Note over A, B 可以在两方之间写旁白;参与方的顺序由声明顺序决定,与消息顺序无关。序列图本质上在说一件事:任何消息序列必须遵守时间单调递增——第 i 条消息的时刻一定晚于第 i-1 条,就像工单不可能先审批后填报:

有了工序传话单,没人会追问“到底谁先动工”。接口评审时把 Mermaid 序列图往文档里一贴,服务端、客户端、数据库的调用顺序一目了然,省下的口舌比一次返工工资还多。

Ti=Ti−1+Δti,Δti>0\displaystyle T_i = T_{i-1} + \Delta t_i, \quad \Delta t_i > 0
每条消息都是上一条消息的“后来者”,时间只前进、不倒退。
  1. 第 i 条消息序列图中的消息按行自上而下编号,i 从 1 开始。
    i=1,2,…,ni = 1, 2, \ldots, n
  2. 上一条消息的时刻T_{i-1} 是前一条消息发生的时间,是递推的基准。
    Ti−1=第 i−1 条消息的时刻T_{i-1} = \text{第 } i-1 \text{ 条消息的时刻}
  3. 时间增量每条消息之间的间隔必须为正,保证时序不会“倒带”。
    Δti>0\Delta t_i > 0
  4. 递推定义当前消息时刻等于上一条时刻加正增量,从而形成严格先后顺序。
    Ti=Ti−1+ΔtiT_i = T_{i-1} + \Delta t_i
mermaid5 行
sequenceDiagram    participant U as 用户    participant S as 服务器    U->>S: 发送请求    S-->>U: 返回响应

Excalidraw架构图:一张餐巾纸草图

装修设计师有个习惯:谈需求时不掏 CAD,而是抽一张餐巾纸,随手画个家具摆放,线条微微抖动,字也歪歪扭扭。奇怪的是,这种“不完美”的草图反而让人敢于提意见——因为它看起来随时可以改。Excalidraw 就是工程师的餐巾纸。

当架构图需要表达模块划分、依赖关系、部署边界,而布局又没法用文本规则自动排布时,Excalidraw 是最顺手的工具。它的线条刻意带手绘抖动,天然传递“这是草稿,欢迎讨论”的信号,特别适合设计研讨会、方案评审和技术博客的概览图。

用法要点有四条:无限画布自由拖动,矩形、椭圆、箭头一应俱全;内置素材库,图标和流程元素拖拽即用,省去从零画起;多人实时协作,光标像工地上的手电筒各指一处;完成后导出 SVG 或 PNG 嵌入 Markdown,与正文混排。手绘线条的本质,是给理想坐标加了一点随机扰动——从数学上看,每个点的位置都落在以理想位置为中心的微小正态分布里,正是这点“不完美”拉近了与读者的距离:

餐巾纸草图的价值在于“可讨论”,但它的归宿是“转正”:讨论定稿后,流程关系落到 Mermaid、类关系落到 PlantUML,草图光荣退役。草稿与正稿各司其职,就像装修现场的粉笔痕最终要被真正的墙面取代。

yi=yi∗+εi,εi∼N(0,σ2)\displaystyle y_i = y_i^{*} + \varepsilon_i, \quad \varepsilon_i \sim \mathcal{N}(0, \sigma^2)
手绘感不是误差,是精心设计的“随机误差”,它让线条有了人味。
  1. 理想坐标数学意义上完美的位置 y_i^*,例如绝对水平的直线。
    yi∗=理想坐标y_i^{*} = \text{理想坐标}
  2. 抖动偏差手绘感来自每个点上的随机微小偏移 ε_i。
    εi=第 i 个点的随机偏移\varepsilon_i = \text{第 } i \text{ 个点的随机偏移}
  3. 正态分布偏移量以 0 为中心、方差 σ² 很小,绝大多数点偏移极小。
    εi∼N(0,σ2)\varepsilon_i \sim \mathcal{N}(0, \sigma^2)
  4. 叠加出实际坐标实际坐标在理想位置附近轻微浮动,线条因此有了手写温度。
    yi=yi∗+εiy_i = y_i^{*} + \varepsilon_i

PlantUML类图:一份物料分类清单

木工进场前,工头会给一份物料分类清单:板材归板材、五金归五金,每一根横梁标着“与哪面墙连接”。软件系统的“户型图”是类图——它回答的不是流程问题,而是结构问题:有哪些类、各自带什么成员、类与类之间是什么关系。

PlantUML 用极简文本描述 UML 图,尤其擅长类图。它把“类声明”和“关系声明”拆开写,你只管列清单,画布布局由引擎自动完成:

语法要点有三条:类名后跟花括号声明字段与方法,- 表示私有、+ 表示公有;关系线有继承 <|--、实现 ..|>、组合 *--、聚合 o--、依赖 ..>,箭头方向一律从子类指向父类、从使用方指向被使用方;布局完全自动,新增一个类只需加三行文本。类图最适合放在代码仓库里和源码一起维护,重构时类关系一变,图跟着变,文档永不撒谎。类图的核心就是一组关系箭头:

物料清单越清楚,木工干活越少返工。软件项目里 PlantUML 类图就是这份清单——它不负责讲故事,只负责把结构钉死。等你的仓库里有了它,新成员读代码的入门时间会从一周缩短到一天。

Csub→is-aCsuper,Cclient→usesCserver\displaystyle C_{\text{sub}} \xrightarrow{\text{is-a}} C_{\text{super}}, \qquad C_{\text{client}} \xrightarrow{\text{uses}} C_{\text{server}}
继承读作"is-a“,依赖读作”uses",方向相反、语义不同,写反一处就会引发评审争论。
  1. 子类标识C_sub 表示继承关系中的子类,是箭头的起点。
    Csub=子类C_{\text{sub}} = \text{子类}
  2. 继承语义箭头指向父类,读作"is-a",表达子类是一种父类。
    →is-aCsuper\xrightarrow{\text{is-a}} C_{\text{super}}
  3. 依赖语义客户端使用服务端,箭头从使用方指向被使用方。
    Cclient→usesCserverC_{\text{client}} \xrightarrow{\text{uses}} C_{\text{server}}
  4. 自动布局输出关系声明完成后,引擎计算所有元素的位置,生成最终画布。
    布局结果=f(全部关系声明)\text{布局结果} = f(\text{全部关系声明})
plantuml7 行
@startumlclass Car {  -engine: Engine  +start()}Car *-- Engine : 组合@enduml

图表设计规范:一册装修验收标准

装修最怕“每个师傅都有自己的审美”:这个插座装 20 厘米,那个装 50 厘米,开关方向还不统一。所以有经验的工头会带着一册验收标准进场——插座离地 30 厘米、防水刷到 1.8 米,白纸黑字,谁也别争。文档里的图表同样需要这样一册“验收标准”。

设计规范的目标不是限制创意,而是降低读者的认知税。读者每看到一张新图,都要花精力解码它的布局和颜色;如果全文档的图风格统一、信息量受控,读者的记忆带宽就会被释放出来,真正聚焦内容本身。

三条最实用的规范:第一,一图一主题,主要视觉元素控制在 7±2 个以内,超过就拆图或分组;第二,颜色要有语义且全文一致——红色表示异常、绿色表示正常、蓝色表示主流程,不要为了好看乱用;第三,术语与正文一致,图内文字能少则少,并给每张图编号,正文用“如图 3 所示”引用。人类短时工作记忆大约只能同时把握 7 个左右的信息块,超过这个数,读者就得来回数数——这跟标题层级公式背后是同一个认知规律:信息量越大,越要分层、分组、分图:

验收标准让工地不会出现“十个师傅十种插座高度”,图表规范让文档不会出现“每张图一种暗号”。规范不是枷锁,是让二十张图看起来像出自同一个人之手的魔法。

Nelements≤7±2\displaystyle N_{\text{elements}} \le 7 \pm 2
一张图的主要视觉块超过 9 个,读者就“记不住,只能数”。
  1. 视觉元素计数统计图中主要的视觉块:框、箭头标注、图例等。
    Nelements=主要视觉元素个数N_{\text{elements}} = \text{主要视觉元素个数}
  2. 工作记忆上限人类短时记忆大约能同时把握 7 个左右的块,上下浮动 2。
    7±27 \pm 2
  3. 超限判断元素超过 9 个时,读者必须来回数数才能读图。
    Nelements>9⇒认知超载N_{\text{elements}} > 9 \Rightarrow \text{认知超载}
  4. 拆图决策超限就拆成子图或分组,保证一眼看懂。
    Nelements>9⇒拆图分组N_{\text{elements}} > 9 \Rightarrow \text{拆图分组}

图表版本管理:一本装修日志

靠谱的工头会随身带一本装修日志:今天拆了哪面墙、为什么改水管走向、油漆色号从哪版换到哪版,逐条记下。半年后房东想改造,翻一翻日志,所有决策都有据可查。图表的生命周期管理,就是这本日志。

图表版本管理的核心前提是“文本即源码”:Mermaid 和 PlantUML 的 DSL 本身是文本,天然可以放进 Git 做版本跟踪;Excalidraw 的文件是 JSON,同样可以入库。导出的 PNG 只是“照片缓存”,如果当作唯一真源保存,文档就会越维护越乱——照片无法 diff,无法注释,无法追溯“为什么把箭头改成了虚线”。

推荐工作流是“三件套”:源码进仓库;每次改动先改 DSL、再重新渲染;CI 里自动生成图片并发布到文档站。版本号上可以套用语义化版本约定:结构或语义破坏性变更升主版本,新增节点或关系升次版本,微调样式或文字升修订号。这样一来,每次代码评审时,图表的 diff 和代码的 diff 一起出现,文档和代码永远步调一致:

装修日志记得好,几年后改造才有据可查;图表源码在仓库里,文档才能持续演化而不是腐烂。到这一步,你的文档就真正具备了“可维护性”——它不再是一堆截图的坟场,而是一条和代码同步生长的生产线。

V=M.m.p,M′=M+1 (破坏性变更)\displaystyle V = M.m.p, \qquad M' = M + 1 \ (\text{破坏性变更})
主版本号是“大改”的警报器,次版本号是“新增”的记录员,修订号是“微调”的便签。
  1. 三段式版本号版本号由主版本、次版本、修订号三段组成,缺一不可。
    V=主版本.次版本.修订号V = \text{主版本}. \text{次版本}. \text{修订号}
  2. 主版本递增图表的结构或语义发生破坏性变更(如重画布局、改变含义)时,主版本 +1。
    M′=M+1 (结构或语义破坏)M' = M + 1 \ (\text{结构或语义破坏})
  3. 次版本递增新增节点或关系时,次版本 +1。
    m′=m+1 (新增元素)m' = m + 1 \ (\text{新增元素})
  4. 修订号递增微调样式、修正错别字时,修订号 +1。
    p′=p+1 (微调修正)p' = p + 1 \ (\text{微调修正})

AI 应用场景

开源项目 README 重构

阶段:项目交付与文档化

解决的问题:开源仓库的 README 只有长段落文字,新用户 30 秒内找不到“怎么跑起来”。AI 时代的模型与推理库尤其需要一张图讲清模块关系。用 Markdown 搭骨架 + Mermaid 画快速开始流程 + Excalidraw 画总体架构,把“劝退文”变成“导览图”。

具体案例:某开源 RAG 框架维护者重构 README:顶部放一张 Excalidraw 架构图(检索、重排、生成三条链路一目了然),快速开始用 Mermaid 流程图,接口调用用 Mermaid 序列图;全部源码进仓库,CI 渲染后自动发布到文档站。

技术博客的图文编排

阶段:技术影响力建设

解决的问题:模型原理讲解往往涉及流程、时序、类关系多种图,博客编辑器对 Mermaid 支持深浅不一,排版容易失控。标题层级设计 + 图表统一风格,让读者跟得上推导节奏。

具体案例:撰写“LoRA 微调原理”教程时,训练流程用 Mermaid 流程图,模型结构用 PlantUML 类图,正文用 Markdown 分级标题组织,每个公式配一段“人话”,并用“如图 2 所示”编号引用图表。

接口评审与研发协作

阶段:研发协作与评审

解决的问题:接口文档用文字描述“谁调谁、谁回谁”,评审时各说各话。序列图把调用顺序一摆,歧义立刻消失;手绘草图让方案讨论阶段可以随意推翻重画。

具体案例:团队评审 RAG 服务接口时,先在 Excalidraw 白板上实时画模块草图,确认后落成 Mermaid 序列图进仓库,与接口代码在同一个 MR 中评审,图跟着代码一起 diff。

Python 演示

python58 行
# -*- coding: utf-8 -*-"""markdown_diagram_tool.py -- 检查 Markdown 标题层级并生成 Mermaid 流程图""" import re  def check_headings(lines):    """检查标题层级, 返回跳级问题列表"""    issues = []    prev_level = 0    for lineno, line in enumerate(lines, 1):        m = re.match(r'^(#{1,6})\s+(.*)$', line)        if not m:            continue        level = len(m.group(1))        title = m.group(2)        if prev_level and level - prev_level > 1:            issues.append("[行 %d] 标题「%s」从 %d 级跳到 %d 级" % (                lineno, title, prev_level, level))        prev_level = level    return issues  def build_flowchart(headings):    """把一级标题串成 Mermaid 流程图"""    nodes = [h for h in headings if h["level"] == 1]    if len(nodes) < 2:        nodes = headings    lines = ["graph TD"]    for h in nodes:        lines.append("    n%d[\"%s\"]" % (h["idx"], h["title"]))    for i in range(len(nodes) - 1):        lines.append("    n%d --> n%d" % (nodes[i]["idx"], nodes[i + 1]["idx"]))    return "\n".join(lines)  def main():    doc = """# 项目简介## 功能特性### 特性一### 特性二## 架构说明# 快速开始"""    headings = []    for lineno, line in enumerate(doc.splitlines(), 1):        m = re.match(r'^(#{1,6})\s+(.*)$', line)        if m:            headings.append({"idx": lineno, "level": len(m.group(1)),                             "title": m.group(2)})    issues = check_headings(doc.splitlines())    print("标题层级检查:", issues if issues else "全部通过, 无跳级")    print("--- 生成的 Mermaid 流程图 ---")    print(build_flowchart(headings))  if __name__ == "__main__":    main()
目的:自动检查 Markdown 文档的标题是否跳级,并把一级标题自动生成一张 Mermaid 流程图——相当于给文档配了一位“层级监理”。
  1. m = re.match(r'^(#{1,6})\s+(.*)$', line)用正则识别 Markdown 标题行,井号个数 1 到 6。
  2. if prev_level and level - prev_level > 1:发现“二楼跳四楼”式跳级,记录问题和行号。
  3. headings.append({"idx": lineno, ...})把标题连同行号存入列表,作为后续生成流程图的原料。
  4. nodes = [h for h in headings if h["level"] == 1]只把一级标题当作流程主干节点,体现“文档骨架”思想。
  5. " n%d --> n%d" % (...)生成 Mermaid 的连线语法,把相邻主干串联成图。
  6. if __name__ == "__main__":可执行入口,让脚本既能被导入也能直接运行。

常见误区

误区“我都是把画好的流程图截图贴进文档,Mermaid 源码存不存无所谓,反正图已经出来了。”

正解截图是“照片”,源码是“户型图”。照片只能记录结果,户型图才能改、能 diff、能追溯。版本管理、协作修改、CI 重新渲染全都依赖文本源码,截图只能看,不能改,改一次就得重画一张。正确做法永远是:源码入库,PNG 只是缓存。

为何常见:读者最终看到的是渲染后的图,初学阶段感受不到源码的价值,等要改图时才发现要重新画一遍。

误区“反正 Mermaid 能画流程图、序列图,甚至能画饼图,干嘛还要学 Excalidraw 和 PlantUML?”

正解工具各有所长:Mermaid 文本快、易嵌入,但复杂架构的自由布局很吃力;Excalidraw 手绘白板适合研讨和架构草图;PlantUML 是 UML 类图的专业选择。就像装修不能一把锤子干完全程,选图如选工具,按图型选最顺手的。

为何常见:学会第一个工具后容易形成路径依赖,遇到不适合的场景也硬用,最后画出一张“火柴棍拼的架构图”。

误区“从 ## 直接到 #### 没什么大不了,反正浏览器渲染出来字体大小对得上就行。”

正解标题层级是语义,不是样式。跳级会让目录生成、大纲提取、屏幕阅读器全部断裂,读者也丢失“我在文档第几层”的方位感。跳级等于在户型图上凭空少了二楼,住在三楼的人每天要跳窗进出。Markdown 渲染是容错的,所以这个错误特别容易被忽略。

为何常见:渲染器不报错,跳级看起来“一切正常”,初学者就误以为这是允许的。

误区“流程图里绿色红色随便用,只要我觉得好看、读者能分清不同模块就行。”

正解颜色是语义通道:一旦这一章图里红=异常、绿=正常,下一章就得保持一致,否则读者每张图都要重新解码。规范的本质是降低认知税——就像装修里插座统一离地 30 厘米,不是美不美的问题,是安全与一致性的问题。全文一套色板,读者才能把颜色当语言读。

为何常见:单张图看,颜色误导不明显;多张图组合时才暴露混乱,而初学者很少一次画多张图。

误区“把每一个异常分支、每一条备选路径都画进一张图,显得我很严谨。”

正解圈复杂度告诉我们:分支越多,图越难读。一张图塞 30 个节点,读者视线来回折返,反而丢失信息。标准做法是主流程一张图,异常分支单独成图并用编号互相引用。就像装修水电图要按回路分开画,一张纸画满全屋管线,再专业的电工也得看花眼。

为何常见:初学者把“完整”等同于“专业”,忽略了读者的认知带宽——图是给人看的,不是给保险柜看的。

面试题

Q1. 在 Markdown 中,表示二级标题的正确语法是?

单选题 · easy

  • A.# 一级标题
  • B.## 二级标题← 正确答案
  • C.### 三级标题
  • D.加粗标题

答案:B。井号个数代表标题层级,# 是一级,## 是二级,就像楼层号:一层是 #,二层是 ##。加粗 是强调而不是标题,注意区分。

Q2. Mermaid 中菱形节点 B{方案可行?} 通常表示什么?

单选题 · easy

  • A.流程开始节点
  • B.流程结束节点
  • C.分支判断节点← 正确答案
  • D.外部依赖节点

答案:C。菱形在流程图中代表判断,像装修验收时的“合格/不合格”关卡。起止节点通常用圆角矩形,因此 A、B 描述的位置不对;外部依赖在流程图中一般用独立泳道或子图表达。

Q3. 圈复杂度公式 $M = E - N + 2P$ 中,$N$ 的含义是?

单选题 · mid

  • A.图中的边数
  • B.图中的节点数← 正确答案
  • C.连通分量数
  • D.菱形判断数

答案:B。$N$ 是节点总数,$E$ 是边数,$P$ 是连通分量数。$E - N$ 衡量分支密集程度,加上 $2P$ 修正后得到 $M$。节点越多、分叉越多,复杂度越高,超过 10 就建议拆图。

Q4. 在 Mermaid 序列图中,-->> 表示什么?

单选题 · mid

  • A.同步调用消息
  • B.创建对象消息
  • C.虚线返回消息← 正确答案
  • D.异步发送消息

答案:C。实线箭头 ->> 是同步调用,虚线箭头 -->> 是返回消息——像工地里工人 B 传话给 A,A 点头回应。返回消息用虚线,读者一眼就能认出“这是应答而不是新请求”。

Q5. Excalidraw 最突出的视觉特征是?

单选题 · easy

  • A.像素风风格
  • B.手绘抖动风← 正确答案
  • C.3D 渲染风
  • D.渐变配色风

答案:B。Excalidraw 的线条带有类似手绘的随机抖动,像设计师在餐巾纸上画的草图。这种“未完成感”反而降低读者的心理压力,暗示“随时可以改”,因此特别适合草图和研讨场景。

Q6. 在 PlantUML 中,表示继承关系的连线符号是?

单选题 · mid

  • A.-- 组合线
  • B.<|-- 继承线← 正确答案
  • C...> 依赖线
  • D.--> 箭头线

答案:B。<|-- 的三角箭头指向父类,表示 is-a 继承关系;..> 表示依赖,-- 表示组合。就像物料清单里“十字螺丝 <|-- 螺丝”——子类是一种父类,方向绝不能反。

Q7. 图表设计规范建议,单图主要视觉元素应控制在多少以内?

单选题 · hard

  • A.不超过 3 个
  • B.7±2 个← 正确答案
  • C.不超过 15 个
  • D.越多越专业

答案:B。人类短时工作记忆的上限约 7±2 个信息块。单图元素超过 9 个时,读者要来回数数才能理解,应拆图或用子图分组。这与标题层级公式同理:信息量越大,越要分层、分组、分图。

Q8. 下列哪些属于图表版本管理的正确实践?

多选题 · mid

  • A.Mermaid 源码入库← 正确答案
  • B.只保存 PNG 图片
  • C.DSL 改后重渲染← 正确答案
  • D.CI 自动生成图片← 正确答案

答案:ACD。文本源码才能 diff、才能追溯,导出的 PNG 只是“照片缓存”,不能作为唯一真源。正确流程是源码入库、改动先改 DSL 再渲染、CI 自动生成图片,保证文档里的图和代码永远同步。

Q9. 关于 Mermaid、Excalidraw、PlantUML 三种工具,下列说法正确的是?

多选题 · hard

  • A.Mermaid 适合快速出流程图← 正确答案
  • B.Excalidraw 适合架构草图← 正确答案
  • C.PlantUML 适合 UML 类图← 正确答案
  • D.三者都无法嵌入文档

答案:ABC。三者都能嵌入 Markdown——Mermaid 原生代码块渲染,Excalidraw 导出 SVG 引用,PlantUML 由插件渲染代码块。选工具看场景:要快选 Mermaid,要自由选 Excalidraw,要严谨 UML 选 PlantUML,D 选项描述与事实相反。

Q10. 关于 Markdown 排版规范,下列做法正确的是?

多选题 · mid

  • A.标题层级逐级递增← 正确答案
  • B.跳级可增强紧凑感
  • C.每级内容量要适度← 正确答案
  • D.层级最多用六级← 正确答案

答案:ACD。跳级是典型的排版坏味道——目录、大纲、屏幕阅读器都会断裂,读者也失去方位感。逐级递增、内容密度适度、六级封顶,这三条构成文档的“户型图规范”,B 的说法恰恰违反了第一原则。