
“skills”这个词在程序员工具箱里通常是个命令、一个文件名或者某个配置文件里不起眼的字段。但过去两个月它是我个人一直在迭代的一个项目一套基于纯文本文件和个人脚本搭建的技能管理系统。它不是什么大平台不依赖Notion模板也不用联网建表就靠一个 YAML 文件加一个 Python 脚本把技能清单、自评等级、复盘记录全部管起来。这套东西解决的是我自己的一个实际问题技能太多太杂脑子里一团浆糊学了后面忘前面简历上写起来也没底气。如果你也处于这种状态或者正打算给团队建一张可落地的能力矩阵那这篇帖子就是给你准备的。1. 项目定位与设计思路1.1 为什么用文件存储而不是直接套用在线表格刚开始我想过用在线表格或者用飞书多维表格搭一个整齐好看还能多人协作。但后来我放弃了原因有三个。第一数据所有权问题技能数据是个人长期资产放在别人的服务器上哪天服务调整了、账号出问题数据说没就没。第二离线使用问题在线表格一旦没网基本上就是一块白板而我在地铁上、在飞机上经常会有想记点技能的冲动。第三可复用和可迁移性一块纯 Markdown 或 YAML 文件可以被脚本读取可以被 Git 记录版本哪天想迁移到新工具改一改格式就能走。用文件存储的本质是“数据与工具解耦”。你可以用 VS Code 打开也可以用记事本打开甚至可以用cat命令在终端里看。这个思路和我平时管理配置文件是一样的把配置和程序分开数据就在那里任谁都能读。用生活里的事来类比这就好比整理衣橱。你不需要先买一个昂贵的智能衣柜才能开始整理你需要做的只是把所有衣服拿出来分个类记录哪些常穿、哪些压箱底然后定期断舍离。技能管理也是这个逻辑核心不在工具多高级而在你愿不愿意坐下来清点自己。1.2 从岗位需求倒推技能分类项目最开始我犯了一个典型错误看见什么技术就想往里面塞。今天看到 Docker 很火加一个明天看到大模型很火再加一个。结果技能清单变成了一大锅乱炖根本没有结构感。后来我把思路完全倒过来不按“技术热度”来而是按“目标岗位需求”来。我先问自己一个问题我未来一年最有价值的角色是什么比如是“后端开发工程师”那我就围绕这个角色拆解能力。程序设计能力数据结构、算法、设计模式、系统设计语言与运行环境Java、Python、JVM、Linux框架与中间件Spring Boot、Redis、Kafka、MySQL工程化与交付CI/CD、Docker、Kubernetes、监控告警软技能需求沟通、技术文档、指导新人这样分类的好处是每一项都能对应到实际工作场景也方便和招聘 JD 做比对。给团队做能力矩阵时这个思路同样适用先确定团队要交付的目标再倒推每个角色需要具备哪些技能而不是把每个成员会的一堆零碎工具罗列上去。1.3 技能粒度的控制不能粗到没用也不能细到没法评技能粒度是早期最让我头疼的问题。写一个“Java”太粗了因为 Java 三个字根本看不出你到底是能写 CRUD还是能搞并发调优。写一个“Java Stream 的 groupBy 用法”又太细了这类细节属于知识点不该作为技能树的叶子节点。我推荐的粒度是能独立评估水平的一个能力域。例如“Java 并发编程”是一个技能可评估“Spring Boot 应用开发”是一个技能可评估“MySQL 性能优化”是一个技能可评估“Redis 的分布式锁实现”更像一个知识点可以作为“缓存设计与实践”这个技能下的一个备注而不是独立技能判断粒度是否合适的标准很简单拿到这个技能名称你能不能立刻判断自己掌握到什么程度如果犹豫超过五秒那就说明要么它太宽要么它太窄。2. 核心功能拆解记录、量化与复盘2.1 自评等级“0-5级”背后的能力阶段模型量化技能我用的是 0-5 六个档位。这个体系参考的是 Dreyfus 技能获取模型简化成六档之后自评起来大脑负担很低也方便在团队里统一口径。0 级没接触过1 级了解概念能说出它是干什么的2 级在指导下做过简单任务3 级能独立完成常规任务遇到问题能自己查资料解决4 级不仅能独立交付还能根据项目场景做选型和优化5 级能教学、能输出方法论能指导别人避坑为什么不用百分制因为百分制容易制造“假精度”。你说你 Java 会 80 分那 80 分和 85 分有什么区别没人能说得清。0-5 分级虽然粗糙但每一档都有明确的行为描述自评时我只需要对照自己最近一次实操表现就能打出一个相对稳定的分数。我给技能记录表格设计的字段很简单技能名称、所属大类、自评等级、最近使用时间、关键证据。关键证据很重要它可以是一句话比如 “三月份完成订单系统的接口幂等改造”也可以直接指向一个项目笔记的链接。有了证据你自评的 4 级才不会自嗨。2.2 技能雷达图让“短板”一眼现形技能清单一旦长到几十项直接看表格其实是看不出整体结构的。这时候需要用可视化方式辅助判断我选的是雷达图。雷达图的每个轴对应一个技能大类数值是该大类下所有技能等级的平均值。因为单个技能看多了容易钻牛角尖而大类平均分能反映你的能力分布是否均衡。比如我自己的数据里“程序设计能力”平均分只有 1.8而“框架与中间件”平均分是 3.2。雷达图上那一块凹陷非常扎眼逼着我直面一个问题我花大量时间学框架但底层的数据结构和算法基础一直没补上。这个发现比我列一百个技能都有用因为我终于知道下一步该往哪里发力了。生成雷达图我用的工具很简单就是 Python 的 matplotlib。脚本读 YAML把技能按大类聚合并计算平均分然后生成一张 PNG 图片。整个脚本不到 70 行后续你会在实操部分看到完整代码。我更建议你在本地跑一遍这个脚本体会一下“从数据文件到图”的整个链路跑通后的成就感。2.3 从静态清单到动态复盘流程技能清单最大的敌人是“尘封感”。三个月不更新它就变成了一张过期的历史博物馆展品清单。我的做法是把这套系统嵌进月度复盘中每个月底花二十分钟做四件事新增这一个月接触了哪些新技能没接触到的就先不写不必为了好看硬凑。重评把过往技能重新看一遍水平是否有提升有没有因为久不用而退化。关联给重要技能补充一条最近使用的证据比如项目名、PR 链接、一页笔记。清理删掉那些早就脱离主线、未来也不可能再用的技能标签给清单减负。这样做的核心原因是技能水平不是一劳永逸的属性而是会随着使用频率升降的变量。用“最近使用时间”这个字段做辅助你才能在雷达图之外看到“哪些技能是存量哪些技能是活跃资产”。3. 实操用 skills 工具从零搭建技能档案3.1 初始化项目目录与数据文件这个项目我保持了极简风格目录结构只有三块skills/ ├── data/ │ └── skills.yaml ├── scripts/ │ ├── read_skills.py │ └── radar_chart.py └── output/ └── radar.pngdata/skills.yaml存放技能树scripts/放读取和可视化脚本output/放生成的图表。整体并没有引入数据库也没有依赖 Docker因为它只需要在一个 python 环境里跑几个脚本就够。这里我刻意保持了极简原因就是开头说的数据归数据脚本归脚本不要一开始就搭建复杂设施。YAML 数据结构设计如下version: 1.0 owner: your-name updated: 2025-01-15 categories: - name: 程序设计能力 skills: - name: 数据结构与算法 level: 2 last_used: 2025-01-10 evidence: 完成一次二叉树遍历专题练习 - name: 设计模式 level: 3 last_used: 2024-12-20 evidence: 在支付模块中使用策略模式重构代码 - name: 语言与运行环境 skills: - name: Java 并发编程 level: 3 last_used: 2025-01-05 evidence: 排查过线上线程池阻塞问题 - name: Python 脚本开发 level: 3 last_used: 2025-01-14 evidence: 实现自动化报表生成脚本选择 YAML 而不是 JSON最重要的原因是可以写注释。技能这种数据几乎每个字段都需要上下文比如“为什么给这个技能打 3 级”不写下来下次自己都会忘。JSON 虽然也能写注释但支持度有限体验不如 YAML 顺手。另外YAML 用缩进表达层级结构肉眼比 JSON 更清晰。3.2 自动校验技能数据并输出成长进度数据文件有了接着需要一个能读取数据、生成统计信息的脚本。我写了一个很短的read_skills.py它只做三件事读取 YAML统计每个大类的技能数量和平均等级输出一个表格方便我快速在终端里看。import yaml from collections import defaultdict def load_skills(pathdata/skills.yaml): with open(path, r, encodingutf-8) as f: return yaml.safe_load(f) def calculate_progress(data): stats [] for cat in data[categories]: names cat.get(skills, []) if not names: continue avg_level sum(s[level] for s in names) / len(names) stats.append({ category: cat[name], count: len(names), avg_level: round(avg_level, 2) }) return stats if __name__ __main__: data load_skills() print(f技能档案管理员: {data[owner]}) print(f最后更新: {data[updated]}\n) for item in calculate_progress(data): print(f{item[category]:12} 技能数 {item[count]:4} 平均等级 {item[avg_level]})跑这个脚本的方法很简单cd skills pip install pyyaml python scripts/read_skills.py你不需要改造任何配置文件只要 YAML 里的数据是正确的脚本会自动把它打印成一个统计表。这个脚本的价值不在于功能强大而在于它把“数据”和“观察”连接起来了。没有这个脚本你打开 YAML 要头脑里做聚合有了这个脚本一眼就能看到整体情况。3.3 生成可视化雷达图让成绩单变成决策工具第二步我用 matplotlib 做了雷达图脚本。代码逻辑也不复杂读取分类平均等级映射到雷达图上。如果你的技能分类不是五类也没关系脚本会自适应分类数量。import yaml import matplotlib.pyplot as plt import numpy as np from math import pi def load_skills(pathdata/skills.yaml): with open(path, r, encodingutf-8) as f: return yaml.safe_load(f) def get_category_averages(data): labels [] values [] for cat in data[categories]: skills cat.get(skills, []) if skills: labels.append(cat[name]) values.append(round(sum(s[level] for s in skills) / len(skills), 2)) return labels, values def create_radar_chart(labels, values, save_pathoutput/radar.png): angles [i / float(len(labels)) * 2 * pi for i in range(len(labels))] values values[:1] angles angles[:1] fig, ax plt.subplots(figsize(8, 8), subplot_kwdict(polarTrue)) ax.plot(angles, values, linewidth1.5, linestylesolid) ax.fill(angles, values, alpha0.25) ax.set_xticks(angles[:-1]) ax.set_xticklabels(labels, fontsize12) ax.set_ylim(0, 5) ax.set_yticks([1, 2, 3, 4, 5]) plt.savefig(save_path, dpi300, bbox_inchestight) print(f雷达图已保存到: {save_path}) if __name__ __main__: data load_skills() labels, values get_category_averages(data) create_radar_chart(labels, values)运行之后会在output/目录里得到一张雷达图。这张图里每一瓣代表一个大类分值范围是 0-5。最初跑通这个脚本时我盯着它看了好久因为那是第一次有了一张“可视化能力画像”。对于团队场景你还可以把每个成员的雷达图打印出来贴在用研数据对面谁强谁弱、哪里有缺口会议室里一眼就能看明白。3.4 体验一次完整的技能评估流程理论讲完了脚本也有了我把一次完整的技能评估流程放在前面你拿到项目后可以直接照着做。选择目标角色。假设你是一名 Web 全栈方向的学生未来想找后端开发岗位。建立分类。在skills.yaml里先写好三个大类基础理论、后端技术、工程能力。录入技能。每个类别下按粒度要求列 5-10 个技能给每个技能打等级、填最近使用时间和证据。运行统计脚本。用read_skills.py查看当前掌握情况的汇总。生成雷达图。用radar_chart.py生成图对比各大类平均分。定一个动作。雷达图上哪个大类最低下个月就围绕这个大类的关键技能做一次刻意练习并在月底更新等级。不要小看最后一步很多人做完雷达图就结束了根本没有落到行动上。技能管理的价值不在“知道自己有多弱”而在“知道自己该补哪一块”。4. 常见问题与避坑指南4.1 自评时手软手严怎么校准经常有人问我“你怎么保证自评分数的准确性”诚实说自评永远有偏差但我们可以用方法减小偏差。我的习惯是三个校验轮第一对照目标岗位的招聘要求如果 JD 里明确写了“熟练掌握 Java 并发编程”而你只能说出线程池的几个参数那评级就不应该超过 2第二找一个同事或朋友帮你评你会发现别人对你的判断往往比你自己更保守第三用交付物说话你最近半年有没有拿得出手的项目、文章或代码如果一样都没有那这项技能即使打 3 级也很难让人信服。自评偏差最集中的地方是“会用”和“能交”的混淆。你会用 Redis 的 GET/SET 命令能在本地跑起来这不代表你懂缓存穿透和缓存一致性。把技能重评时多问自己一个问题“如果这周有个人让我基于这项技能解决一个线上问题我能不查文档就说出排查思路吗”答不上来就降一级。4.2 技能跨类和重叠怎么去重技能分类最容易遇到的坑是一项技能同时属于两个大类。比如 Docker既算“容器技术”又算“DevOps 工具链”再比如 Redis既算“分布式存储”又算“缓存设计”。如果不处理重复雷达图里同一项能力会被算两次大类均值会虚高。我的处理原则有一个每个技能只在最贴近业务目标的大类里挂载一次其他大类里绝对不重复出现。比如 Docker如果你的目标是做后端服务部署那它挂在“工程化与交付”下如果你的目标是做云原生基础设施那它挂在“云原生基础设施”下。重复技能本质上不是数据问题而是分类目标不清晰的映射方式。分类不准造成的连锁反应很明显雷达图会“虚胖”让你误以为某些维度能力不错实际上那只是同一个技能被算了两遍。所以每次新增技能时先看它是不是已经在其他类别里存在过。如果存在那就在原类别里补充描述而不是在多个类别里重复列一遍。4.3 项目做一半数据乱了怎么恢复文件式存储最大的好处是可以用 Git 管理所以从项目第一天起我就把data/目录纳入版本控制。每周末对自己的技能档案做一次 commit写个简单的信息比如 “月度复盘更新 Redis 等级为 3新增容器网络学习笔记”。这样的习惯建立了三层安全网本地有备份文件远端 Git 仓库有历史版本每个技能都有明确的变更时间线如果哪天真改乱了一条git revert或者git checkout -- data/skills.yaml就能恢复绝不至于哭天喊地。数据这种长期资产不做备份和版本管理就是在给自己埋雷。更重要的当你一个月后再回来看那份 YAML 时Git 历史能告诉你这个月你的技术方向发生了哪些变化等于给职业成长写了个日记。4.4 常见问题速查表问题现象主要原因解决建议技能数量越来越多逐渐变成大杂烩没有按目标角色倒推分类先定义角色再列出角色需要的能力自评等级普遍偏高混淆了“知道”和“能交付”用关键证据和交付物校准雷达图某几个维度虚高同一技能挂载到了多个大类按“一次挂载”原则去重技能档案几个月不更新没有内嵌到月度复盘中把更新技能列为每月固定动作新学技能总是加到旧分类里分类本身落后于业务目标定期审视角色定位重构 YAML 分类树5. 后续扩展方向skills 项目目前只服务我一个人但它天然可以扩展到团队场景。给团队做能力矩阵时不需要改变任何核心设计只需要让每个成员维护自己的skills.yaml然后由一个汇总脚本把所有成员的数据合并起来就可以生成团队级的热力图哪条链路上缺人、哪类技能存在结构性短板很快就暴露出来。另一个扩展方向是把它和招聘面试结合。把候选人简历里的关键词按照这套技能分类整理一遍自动生成一张技能雷达图面试官在开始聊技术之前就能直观看到候选人的能力结构省去先读半天简历再做判断的时间。这些后续能力我目前还在探索中但核心数据结构已经足够支撑。我自己的体会是这套系统最大的价值不是那张好看的雷达图也不是那一堆分级数字而是它逼着我每个月坐下来认真想一遍我现在的技能结构离我想要的职业方向还差在哪一块。思考的过程本身比工具和脚本值钱得多。所以如果你也想搭一套别急着先写代码先拿一张纸列出来为你未来的角色拆十个技能出来再打上等级。这第一步比任何工具都重要。