自从成为考公党,在电子化和纸质版中间不断变换,随着正确率的提升,复盘也越来越重要。尤其是行测中的资料分析,题目是刷不完的,但题型是相似的,与其花大量时间在不停的刷题,不如调整比例,增加复盘时间。
因为不同板块的类型不一样,部分内容有变换,由于在论坛分享,考公人是小部分,我便以资料分析为例,其他不展示了。
【注:涉及插件Templater和Dataview】
模板需求分析
先考虑资料分析的模板需求:基础数据展示和错题收集复盘
基础数据:
1. 一套资料分析一般20个题目,有的15个
2. 做完一套资料分析的耗时
3. 做完后的正确率
复盘角度
1. 做题过程中的心态感受
2. 题目不同类型复盘:错题、蒙对的题、耗时较长的题
3. 错题题型考点
4. 如何改进
所以需要创建两个文件夹,一个是历年试题,用来放置每套题,后续由模板生成的文档将放入历年试题,另一个是错题集,将错题放入。
插件Templater配置
模板创建需要插件templater,首先创造两个模板文件,分别名为tp-资料分析和资料分析错题模板。配置可参考我的:tp-资料分析放在设置的模板文件夹即可,比如我的6.模板。
模板逻辑
使用方式:
- 使用命令栏
Templater: Create new note from template - 点击
tp-资料分析 - 输入标题
- 输入一套题的总题数
- 输入错误题数
- 输入耗时
- 输入完成,生成模板
- 开始错题分析
- 点击自动生成的错题双链,将自动运用
资料分析错题模板,生成错题文件,开始复盘。
错题分析:我之前将错题集输入给AI,归纳了六种类型,并且每种类型有更细的错误分支,同时输出了编码表,方便后续其他管理。

可能我设置的有些繁琐,这是随着我的错题数的减少而改变的。不需要后续管理的,可以舍弃资料分析错题模板,直接复盘,改成打Tag。
模板设置
tp-资料分析
结构为:
Yaml——需设置
# 基础数据看板——需设置
# 时间分配和心态——需设置
# 复盘题目
## 错题分析——需设置
# 薄弱点诊断
## 错题分类整理——需设置
## 解题思维优化
### 方法论升级
%% 总结通用解题思路改进(如:先看选项再计算) %%
### 避坑指南
%% 记录新发现的命题陷阱(如:表格单位默认为万吨) %%
### 行动清单
- 强化练习:%% 需要加强的题型(如:混合增长率) %%
- 工具掌握:%% 需要熟悉的速算技巧(如:百化分) %%
- 习惯培养:%% 需要养成的做题习惯(如:先圈单位) %%
效果图
Yaml配置
<%-*
// 1.初始化标题
let finalTitle = tp.file.title;
if (finalTitle.startsWith("Untitled")) {
finalTitle = await tp.system.prompt("请输入试卷标题(例:2023国考资料分析)");
}
// 清理非法字符
const sanitizedTitle = finalTitle.replace(/[\\/:*?"<>|]/g, "");
// 文件路径处理
const basePath = "/1. 项目/资料分析/历年试题/";
await tp.file.rename(sanitizedTitle);
await tp.file.move(basePath + sanitizedTitle);
// 动态获取考试数据
const total = await tp.system.suggester(["20题", "15题"], [20, 15], false, "请选择总题数");
let errorCount;
do {
errorCount = parseInt(await tp.system.prompt('错误题数')) || 0;
} while (errorCount > total);
const timeCost = parseInt(await tp.system.prompt('总耗时(分钟)如:25')) || 0;
const correctRate = total > 0 ? Math.round(((total - errorCount)/total)*100) : 0;
// 省份全称匹配
const provinceRegex = /(北京|天津|上海|重庆|河北|山西|辽宁|吉林|黑龙江|江苏|浙江|安徽|福建|江西|山东|河南|湖北|湖南|广东|海南|四川|贵州|云南|陕西|甘肃|青海|台湾|内蒙古|广西|西藏|宁夏|新疆)/;
const provinceMatch = sanitizedTitle.match(provinceRegex);
// 考试类型识别
let examType = "其他";
if (sanitizedTitle.includes("国考")) {
examType = "国考";
} else if (sanitizedTitle.includes("联考") || sanitizedTitle.includes("省考")) {
examType = "省考";
}
// 智能标签生成
const speedStatus = (timeCost/total) <= 1.2 ? "速度达标" : "需提速";
const scoreStatus = correctRate >= 90 ? "高分复盘" : "重点补漏";
-%>
cdata: <% tp.date.now("YYYY-MM-DD") %>
examType: <% `${examType}` %>
year: <% sanitizedTitle.match(/\d{4}/)?.[0] || '未知' %>
province: <% provinceMatch ? provinceMatch[1] : '全国' %>
Time: <% `${timeCost}` %>
Total: <% `${total}` %>
error_count: <% `${errorCount}` %>
correctRate: <% `${correctRate}` %>
timePerQuestion: <% (timeCost/total).toFixed(1) %>分钟/题
tags:
- 资料分析
- <% `${scoreStatus}` %>
- <% `${speedStatus}` %>
这个还添加了一些个人需要,除了下面涉及到的,其他没有需要的可以自行删除。
基础数据看板
```dataview
table
Total as "📊 总题数",
error_count as "❌ 错题",
correctRate as "🎯 正确率"
from ""
where file = this.file
```
不需要的可删除。
时间分配和心态
复盘时间分配:: (单题 <% (timeCost/total).toFixed(1) %>分钟)
做题心态:: <% await tp.system.prompt("简要描述心态(如:图表密集导致分心)") %>
错题分析
<%*
const ERROR_TYPES = [
"计算错误",
"题目理解错误",
"逻辑思维错误",
"数据查找错误",
"题目陷阱未识别",
"知识盲区"
];
for(let i=1; i<=errorCount; i++) {
// 输入题号
const qNum = await tp.system.prompt(`错题${i}题号(如:Q115)`);
// 选择错误类型
const errType = await tp.system.suggester(
ERROR_TYPES,
ERROR_TYPES.map(t => `${t}`), // 实际存储格式
false,
`请选择【题${qNum}】的错误类型`
);
const uid = tp.date.now("YYYYMMDDHHmm");
tR += `- [[${errType}-${qNum}-${uid}-${finalTitle}]]\n`;
}
%>
<%*
// 先确认是否存在耗时题
const needSlowAnalysis = await tp.system.suggester(
["✅ 存在需要分析的耗时题", "❌ 没有耗时题"],
[true, false]
);
if (needSlowAnalysis) {
const slowQ = await tp.system.prompt("请输入耗时题号(逗号分隔)");
if (slowQ) {
tR += "## 长耗时题诊断\n";
slowQ.split(',').forEach(q => {
tR += `- **${q.trim()}**:\n - 原因分析:\n - 改进方案:\n`;
});
}
}
%>
不需要资料分析错题模板的可删除,或者让AI修改,变成自己需要的。
错题分类整理
```dataview
TABLE code, 题目, 错误描述
FROM outgoing([[<% `${finalTitle}` %>]])
WHERE code
```
不需要资料分析错题模板的可删除,主要是收集错题。
资料分析错题模板
结构:
Yaml
题目::
错误描述::
效果图
Yaml
<%-*
// 解析文件名中的错因代码和名称
const [errType, Num, uid,append] = tp.file.title.split("-");
// 根据错因匹配模板类型、建议内容和代码值
let codeSuggestions = [];
let codeValues = [];
if (errType.startsWith("计算错误")) {
codeSuggestions = ["估算误差", "基本运算错误", "公式应用错误", "单位换算错误"];
codeValues = ["A-01", "A-02", "A-03", "A-04"];
} else if (errType.startsWith("题目理解错误")) {
codeSuggestions = ["关键词误解", "时间范围错误", "数据关系混淆"];
codeValues = ["B-01", "B-02", "B-03"];
} else if (errType.startsWith("逻辑思维错误")) {
codeSuggestions = ["反向比较", "过度简化问题"];
codeValues = ["C-01", "C-02"];
} else if (errType.startsWith("数据查找错误")) {
codeSuggestions = ["数据定位错误", "数据漏读"];
codeValues = ["D-01", "D-02"];
} else if (errType.startsWith("题目陷阱未识别")) {
codeSuggestions = ["单位陷阱", "概念陷阱", "统计口径陷阱", "数据范围陷阱"];
codeValues = ["E-01", "E-02", "E-03", "E-04"];
} else {
// 默认为“知识盲区模板”
codeSuggestions = [""];
codeValues = [""];
}
// 文件路径处理
let Title = tp.file.title;
const basePath = "/1. 项目/资料分析/错题本/";
await tp.file.move(basePath + Title);
-%>
code: <% tp.system.suggester(codeSuggestions, codeValues) %>
uid: <% `${uid}` %>
append: "[[<% `${append}` %>]]"
tags:
- 资料分析/错题
- 资料分析/<% `${errType}` %>
正文
题目::
错误描述::
<%-*
// 重命名文件去掉 finalTitle 部分
let newFileName = `${errType}-${Num}-${uid}`;
await tp.file.rename(newFileName);
-%>
通用版
在制定这套模板之前,也制定过通用模板,需要依靠Modal Form插件。
创建通用模板tp-试题。
复盘模板框架
正确率—— 错题—— 总题数
1. 时间分配和心态
- 时间分配:题目时间分配怎么样
- 做题心态:精力集不集中,有没有因为被部分难题影响
2. 复盘错题
- 序号1 :错误原因
- 序号2 :错误原因
- 序号3 :错误原因
3. 蒙对的题
4. 做对但耗时长的题
5. 薄弱点
6. 错题归纳
模板逻辑
使用方式:
- 使用命令栏
Templater: Create new note from template - 点击
tp-试题 - 选择试题类型
-
输入信息——需要
Modal Form插件
-
开始错题分析
tp-试题
Yaml
<%-*
var cleanTitle = tp.user.getTitleSnippet(tp.file.title)
var title = `${cleanTitle}`;
await tp.file.rename(`${title}`);
const modalForm = app.plugins.plugins.modalforms.api;
let filetype = await tp.system.suggester(["资料分析", "言语理解", "数量关系", "推理判断"], ["资料分析", "言语理解", "数量关系", "推理判断"], false, "路径放到哪里?")
if (filetype === "资料分析") {
myFilePath = "/1. 项目/资料分析/历年试题/" + `${title}`;
await tp.file.move(`${myFilePath}`);
const result = await modalForm.openForm('资料分析');
tR += result.asFrontmatterString();
} else if (filetype === "言语理解") {
myFilePath = "/1. 项目/言语理解/历年试题/" + `${title}`;
await tp.file.move(`${myFilePath}`);
const result = await modalForm.openForm('言语理解');
tR += result.asFrontmatterString();
} else if (filetype === "数量关系") {
myFilePath = "/1. 项目/数量关系/历年试题/" + `${title}`;
await tp.file.move(`${myFilePath}`);
const result = await modalForm.openForm('数量关系');
tR += result.asFrontmatterString();
} else if (filetype === "推理判断") {
myFilePath = "/1. 项目/推理判断/历年试题/" + `${title}`;
await tp.file.move(`${myFilePath}`);
const result = await modalForm.openForm('推理判断');
tR += result.asFrontmatterString();
}else {
tp.file.cursor(1)
}
-%>
correctRate:
tags: <% `${filetype}` %>
将会根据Modal Form插件设置的生成相应信息。
正文
# 时间分配和心态
复盘时间分配::
做题心态::
# 复盘题目
## 错题
## 蒙对的题
## 做对但耗时长的题
# 薄弱点
## 错题分类整理
## 解题思维优化
数据展示
```dataviewjs
var pages = dv.pages('"1. 项目/资料分析/历年试题"').filter(p => String(p.file.tags).includes('资料分析'))
dv.table(
["Name", "时间", "题数", "错题数", "正确率"],
pages.sort(b => b.file.ctime, "desc").map(b => {
return [b.file.link, b.Time + "min", b.Total, b.error_count, b.correctRate];
})
);
```
此模板制作在Bases 数据库前,如果有需要可以自己使用Bases 数据库制作。
其他
个人进阶使用
比较适合Anki玩家与考公党。
- 做完一套题后可以在粉笔上输入生成答案。
- 安装Quicker,并安装动作粉笔错题\n制Anki卡 - by 乐昂岚 - 动作信息 - Quicker
- 根据教程直接将错题一键导入Anki
- Anki安装插件hjp-linkmaster,能够将Anki中卡片链接至obsidian
花费时间
因为使用上述所说的错题导入,在错题整理上其实并没有花费多少时间,而是更多在复盘错题。甚至可以选择性地在anki中复盘。
错题管理与分享
本来错题的分类是为了以后更集中的复盘,但是现在我已经不需要使用它,没有进一步利用起来。在给周围朋友分享后,一直闲置着,上论坛后发现关于错题集的流程几乎没有,或许我分享出来更好。
关于复盘
对我而言,复盘的过程带来更深层次的思考。在刚开始时,我大量的刷题,机械地对答案,却发现这次错的题,下次还错,这次对的题,下次却做错,不免思考我如何改进。单纯的正确率背后,是知识点掌握程度与做题状态的结合。我不仅要确定我的状态,也要确定对题目是不是真的理解,知识点是否真的掌握。就像蒙对的题,即便我对了,不代表我懂了。这在资料分析里也体现得最为直观。
结语
我的复盘可能不适合每一个人,仅希望给提供需要的朋友提供一些灵感。









