408 大题书写实践

从题目动词、分值和评分说明判断答案写多深,并用真题练习简答、计算、推导、列举和算法题的落笔方式

本页是 408 大题书写规范 的实践手册。讲义回答“为什么这样写”,本页解决“拿到一道具体题后怎样落笔”。

大题书写的目标不是接近参考答案的字数,而是用尽可能明确的文字暴露采分点:

阅卷人能找到结论,也能沿着必要依据复核结论。

先判断题目要你交付什么

读完一个小问,先圈出动词。动词决定最低书写量。

题目动词应交付的内容常见缺陷
写出、指出、填写对象明确的结论写了原理,却没有明确答案
是否、能否是/否 + 题目要求的理由只写“能”“不能”
说明理由、为什么结论 + 决定性判据 + 题目条件默写整段定义,没有结合本题
计算、求公式或规则 + 代入 + 结果和单位只写最终数字
推导、证明已知关系 + 关键变形 + 结论直接背结论
列举、哪些按对象分点列全多写不确定项,污染正确答案
设计、描述算法基本思想 + 实现 + 必要分析只有代码,或只有自然语言

然后看分值估计采分点数量。1 分题有时只需要一个准确结论;2 分题常见“结论 + 理由”或两个并列点;更高分的小问通常需要多个步骤。但分值不是字数换算表,最终仍要看题目动词和信息结构。

一个可伸缩的答案骨架

不要机械地给每道题都套三段话。下面这个骨架可以按题目要求缩放:

1. 结论:直接回答所问对象。
2. 依据:写决定结论的定义、公式或规则。
3. 对应:指出题目中的哪个条件满足该规则。
4. 过程:有计算或状态变化时,保留关键中间步骤。
  • 只要求“写出结果”的 1 分题,可能只用第 1 层。
  • 要求“说明理由”的题,通常至少写到第 3 层。
  • 要求计算或推导的题,需要写到第 4 层。

判断是否写够,可以做一次“删除测试”:删掉一句话后,阅卷人还能确认你的答案和依据吗?如果不能,就保留;如果能,而且该句与问题无关,就删掉。

简答题:结论和决定性判据

示例一:比较两个处理的开销

2016 年第 45 题 问:Cache 缺失和缺页处理哪个时间开销大?为什么?

不充分的写法:

缺页处理的开销大。

它给了结论,却没有完成“为什么”。

合格写法:

缺页处理的开销更大。缺页需要访问磁盘,
而 Cache 缺失只需访问主存;磁盘访问远慢于主存访问。

也可以从处理机制回答:缺页需要由软件参与处理,而 Cache 缺失主要由硬件处理。该题的评分说明明确接受这种不同于参考答案的正确理由。

这个例子说明,简答题不要求逐字复现参考答案。只要结论正确,判据能够支持结论,并且与题目场景对应,就可以形成采分点。

示例二:一句“为什么”里可能有两个动作

2015 年第 43 题 问:为什么单总线数据通路需要暂存器 T?

较弱写法:

T 用来暂存数据。

“暂存数据”没有说明为什么必须暂存,区分度不足。

更好的写法:

单总线一次只能传送一个操作数。先将一个操作数暂存在 T 中,
再由总线送入另一个操作数,ALU 才能同时获得两个不同输入。

这里的关键词是“单总线”“两个操作数”和“同时输入 ALU”。不是字多,而是因果链完整。

示例三:什么时候只写结论就够

2017 年第 43 题 的部分小问只要求最大的 n。评分说明明确写着“只要给出 n=30 即可给分”。此时写:

n=30

已经足够。若时间充裕,可以补一句范围依据帮助自查,但不能因此得出“所有 1 分题都只写结果”的结论。是否需要理由,仍由题目要求和评分点决定。

判断或论证题:反例必须能完成反驳

2009 年第 41 题 给出一种“每次走向当前最近顶点”的方法,问它能否求得最短路径;若不能,需要举例说明。

只写下面这句不够:

不能,因为局部最优不一定能得到全局最优。

它表达了方向,但题目明确要求举例。完整答案至少应包含:

结论:该方法不一定得到最短路径。

反例:给出一个带非负权值的图,并标明起点、终点和边权。
按题设贪心规则,算法依次选择的路径长度为 3;
但图中存在另一条长度为 2 的路径。因此该方法得到的不是最短路径。

一个有效反例要让人检查四件事:

  1. 反例满足原命题前提,例如边权非负、起点到终点存在路径;
  2. 题设算法在该图上会作出什么选择;
  3. 算法得到的结果是多少;
  4. 更优结果是多少,两者确实矛盾。

只画图而不标出算法路径和更短路径,会让关键反驳停留在阅卷人的推测中。

计算题:每个数字都应该有来源

示例一:Cache 命中率

2014 年第 45 题 问程序执行时指令 Cache 的命中率。

只写:

99.98%

结果虽然正确,但评分说明明确指出,没有原因和过程只能得到该问的一部分分数。

推荐写成:

6 条指令共占 6×4 B=24 B。程序从主存块首地址开始,
且 24 B<32 B,所以全部指令位于同一个主存块。

第一次取指发生 Cache 缺失,调入后其余取指均命中。
总取指次数为 1000×6,故
命中率=(1000×6-1)/(1000×6)≈99.98%。

这段答案中每一行承担不同功能:

暴露的采分点
6×4 B=24 B程序的指令空间范围
24 B<32 B 且从块首开始所有指令位于同一主存块
第一次缺失,之后命中缺失次数
命中率公式最终计算

如果最后除法算错,前三步仍然让阅卷人看到正确思路;只写结果则没有这种余地。

示例二:中断和 DMA 的 CPU 开销

2009 年第 43 题 要求给出计算过程。中断方式的答案可以压缩成下面四步:

每次中断开销=(18+2)×5=100 个时钟周期。
每秒中断次数=0.5 MB/4 B=125000 次。
每秒中断总开销=100×125000=12.5M 个时钟周期。
CPU 时间占比=12.5M/500M=2.5%。

不要把四步合成一个无法辨认单位的长算式。分行以后,“单次开销、发生次数、总开销、占比”四个量都可以独立检查。

计算题还要注意:

  • 第一次出现缩写或中间量时说明含义;
  • 单位在代入前统一,尤其是 bit/B、KB/B、ns/ms;
  • 近似值写 ,不要写成严格相等;
  • 题目要求“至少”“最多”时,在结论中保留限定词。

推导题:保留起点、桥梁和终点

2016 年第 42 题 问:正则 k 叉树有 m 个非叶结点时,叶结点有多少个?题目明确要求给出推导过程。

只写结论:

n₀=(k-1)m+1

不能满足题目要求。一个足够短而完整的推导是:

设叶结点数为 n₀,则总结点数 n=n₀+m,树的边数为 n-1。
另一方面,m 个非叶结点的度均为 k,所以边数也等于 mk。
因此 n₀+m-1=mk,解得 n₀=(k-1)m+1。

这里包含:

起点:总结点数与边数的关系
桥梁:用两种方法计算同一个边数
终点:联立并解出待求量

参考答案采用哪一种推导并不重要。评分说明明确表示,其他正确推导方法同样给分。复习时应该记住“对哪个量进行两次计数”,而不是背整段文字。

列举题:宁缺毋滥也不是原则,精准才是原则

示例一:错误项会污染整组答案

2015 年第 43 题 要求判断哪些端点连接到控制部件的输出端。评分说明指出,答案一旦包含某些错误端点,该问不给分;答案不全则酌情给分。

这说明“把可能的都写上,总能碰到几个”并不成立。列举题应当:

  1. 先在草稿上逐项判断;
  2. 答题纸只写最终确认的集合;
  3. 使用清楚的分隔符,不让编号和解释混在一起;
  4. 若要求说明理由,再逐项对应理由。

推荐格式:

应连接的端点为:①、②、③、⑤、⑧。

不要在最终答案后面加“④可能也算”这类自我否定的内容。

示例二:不能把整个字段表抄上去

2011 年第 47 题 问 IP 分组经过路由器 R 转发时需要修改哪些首部字段。结合题目场景,应写:

必然修改:TTL、首部校验和。
由于 R 执行 NAT,还要修改源 IP 地址。
若输出链路需要分片,再修改总长度、标志和片偏移字段。

该题的评分说明特别指出,把所有 IP 首部字段全部罗列出来不给分。原因不是写得多本身有罪,而是“全部罗列”没有完成“哪些字段需要修改”的筛选。

列举题的答案应当是一个明确集合:属于集合的写出来,不属于的不要写;条件性答案要把条件一并写出。

状态变化题:不要跨过触发条件

操作系统调度、页面置换、中断和 TCP 序号题经常不是缺少最终结论,而是漏写一次状态更新。建议按下面的最小链条书写:

事件 → 触发条件 → 使用的规则 → 新状态

例如,不能只写:

P2 抢占 P1。

应该根据题目实际规则写成类似:

t=30 时 P2 到达,但题目规定只在时钟中断时检查抢占,
所以此时 P1 继续运行;到下一次时钟中断,再比较优先级并调度 P2。

这里的关键不是句式,而是区分“事件发生”和“状态立即改变”。具体的建模方法见 长题综合题实践

算法题:思想、实现和分析必须相互对应

2017 年第 41 题 要求把表达式树输出为带必要括号的中缀表达式,包括“基本设计思想”和“C/C++ 实现”两个小问。

基本思想可以写成:

对表达式树进行中序遍历。访问非根、非叶的分支结点所代表的子表达式时,
在遍历其左子树前输出左括号,在遍历其右子树后输出右括号;
根结点和叶结点不额外加括号。

这段话应当能映射到代码:

void printExpr(BTree *root, int depth) {
    if (root == NULL) return;

    int isLeaf = root->left == NULL && root->right == NULL;
    if (depth > 1 && !isLeaf) printf("(");

    printExpr(root->left, depth + 1);
    printf("%s", root->data);
    printExpr(root->right, depth + 1);

    if (depth > 1 && !isLeaf) printf(")");
}

算法题检查清单:

  • 思想中说的遍历次序,是否与代码一致;
  • 基本情况是否处理,如空树、叶结点、根结点;
  • 括号、下标、循环边界是否成对或闭合;
  • 题目要求的输入输出是否真的实现;
  • 复杂度是否根据自己写出的算法分析,而不是背“最优复杂度”。

注释只写关键意图,不必把每行代码翻译成中文。评分说明允许其他正确算法,参考答案的代码不是唯一合法写法。

草稿和答题纸承担不同任务

草稿允许试错,答题纸负责呈现最终逻辑。

草稿纸答题纸
缩写题干、试公式、画状态按小问编号给出最终答案
保留被排除的可能性只保留确认后的结论
可以使用个人符号符号首次出现时含义明确
可以跳步供自己使用关键采分步骤必须可复核

不要把草稿原样誊写,也不要因为草稿上“已经算过”就在答题纸只写结果。

如何使用参考答案

对完答案后,不要只标一个对勾或叉号。把参考答案拆成采分点:

题目要求:为什么缺页开销更大?
结论点:缺页开销更大。
依据点:缺页访问磁盘,Cache 缺失访问主存。
我的缺口:只写了结论,漏掉比较依据。

遇到自己的方法和参考答案不同,可以依次检查:

  1. 最终结论是否回答了同一个对象;
  2. 使用的定义和规则是否成立;
  3. 是否使用了题目全部相关条件;
  4. 中间步骤能否推出结论;
  5. 时间、空间或适用范围是否满足题目要求。

五项都成立,就不必为了“长得不像答案”而否定自己的解法。真题中的评分说明多次明确接受其他正确推导、算法或表述。

书写复盘模板

每周选几道综合题,不重算整题,只复盘落笔:

题目年份/题号:
小问动词:写出 / 说明 / 计算 / 推导 / 设计
预计采分点:
我的答案:
遗漏的依据或步骤:
可以删除的无关内容:
单位、对象、条件是否准确:
压缩后的合格答案:

“压缩后的合格答案”最重要。它既不能只有结果,也不应照抄长篇解析,而应保留足以得分和复核的最短逻辑链。