资讯动态

t3code:一套自动化刷题与代码复盘仓库的搭建指南

发布时间:2026/10/26 17:10:28 来源:尧图企业网站定制
把 t3code 从“一个想法”变成“一个每天都会自动跑起来的仓库”我大概花了一个周末。这个项目说白了非常简单每天固定写三道代码题把题目、思路、代码、复盘全部落进一个规范化的仓库里再靠几个小脚本把整个流程串成一条流水线。到现在它已经跑了三个月我最大的收获不是“刷了多少题”而是终于找到了一套不会烂尾的代码训练节奏。如果你现在的状态跟我之前很像收藏夹里躺着十几个题单刷题 App 的连续打卡断过三四次或者每次想练代码都从“今天先看半小时题解”开始然后没有然后那这篇内容就是给你准备的。我会把 t3code 的命名逻辑、目录设计、自动化脚本、以及这三个月里踩过的坑全部摊开讲你可以直接照着搭一套自己的版本。1. 项目背景与整体设计思路1.1 为什么需要 t3code先说清楚我最初遇到的问题。大部分想提升编码能力的人并不是不知道要多写代码而是“知道”和“做到”之间隔着一条巨大的沟。我以前刷题的状态是某天心血来潮打开题库挑一道中等难度的题卡了四十分钟看了题解觉得自己懂了关掉页面。第二天再打开昨天那道题已经完全想不起来。这种状态持续了很长时间刷题变成了“感动自己”的仪式而不是能力的积累。后来我给自己总结了三个具体痛点没有沉淀。做过的题散落在各个平台没有一个统一的归档想复盘的时候根本翻不到。没有节奏。刷题完全是随机行为状态好就连刷十道状态差就一周不碰。没有反馈。不知道自己到底在哪些类型上反复卡壳不知道时间花在哪里进步与否全靠感觉。t3code 就是为了解决这三个问题才出现的。它的目标是建立一个“低摩擦、自动化、可复盘”的个人代码训练系统核心逻辑只有一句话每天三道题全部落盘复盘留痕。很多人问我为什么非要用仓库加脚本这套组合直接在刷题网站上做不就行了吗我的答案很简单刷题网站解决的是“做题”的问题但解决不了“沉淀”和“复盘”的问题。只有把代码和思考过程变成自己仓库里的文件你才拥有对这段训练经历的完全控制权。1.2 命名逻辑与设计原则t3code 这个名字拆开就是 T3 code。T3 代表 Three也就是每天三道题code 代表所有训练内容都以真实代码的形式保存。为什么不叫“daily-three”或者“three-problems”因为 t3code 读起来更像一个产品代号而且它有一个隐藏含义Think思考、Type动手、Track追踪。这其实就是整个项目的三个核心动作——先思考解题思路再写代码实现最后把过程和结果记录下来。围绕这个命名我给自己定了三条设计原则后来发现这三条原则很大程度上决定了项目没有夭折第一摩擦必须最小。如果每天开始训练之前还要做一堆准备工作这个习惯一定坚持不下来。所以一定要有脚本一条命令生成当天目录和模板让“开始行动”的成本降到五秒以内。第二一切皆可追溯。每道题对应一个文件每个文件里有题目链接、思路、复杂度分析和代码。三个月后翻出来我能准确知道某一天我在某道题上卡了一个小时卡在哪一步。第三允许“敷衍”。这是最重要的一条。我不要求自己每天必须写出三道高难度题的满分解状态差的时候写三道简单题甚至只写一个思路说明然后空白代码也算打卡。节奏比强度重要先保证不断更再谈提高。1.3 技术方案选型为什么是脚本加仓库在设计 t3code 的时候我面前其实有三个方案。第一个方案是做一个带界面的本地应用或者响应式网页。功能很完整能记录题目、计时、统计曲线但这个方案的问题是开发成本太高而且每天打开一个网页再点好几个按钮摩擦比打开终端敲一条命令大得多。更麻烦的是一个应用的时间长了就容易变成“维护应用”而不是“刷题”。所以我直接放弃。第二个方案是用现成的刷题平台收藏夹加笔记软件。这个方案摩擦低但数据分散统计口径混乱也没有版本历史。想在某个平台上查“我做过的所有动态规划题”很容易但想查“我做这几道题时当时的思考过程”几乎不可能。这也是我放弃的原因。第三个方案就是最终采用的纯文本仓库加少量 Python 脚本。仓库用 Git 管理题目按日期和主题双向组织脚本负责生成模板、统计进度、更新文档。整套系统的核心依赖只有一个就是你已经装好的 Python 或者 Node.js零额外部署。这个方案看着寒酸但恰恰因为它足够简单所以足够稳定跑了三个月没崩过。注意方案选型的核心不是“哪个最强”而是“哪个最能让你坚持”。对个人训练系统来说长期可用远比功能强大重要。2. 目录结构与题目模板设计2.1 目录结构日期与主题的二维归档t3code 的仓库结构我前后重构过三次。第一次是单纯的按日期堆文件结果三个月后发现想找某一类题的时候要翻几十个文件夹第二次改成按主题分类但每天的记录被拆得太碎复盘起来很别扭。最终定下来的是“日期 主题”的二维交叉方式t3code/ ├── topics/ # 按主题分类的题解归档 │ ├── arrays/ │ ├── strings/ │ ├── dynamic-programming/ │ ├── trees/ │ ├── graphs/ │ └── binary-search/ ├── daily/ # 按日期组织的每日训练记录 │ ├── 2025-06-01/ │ ├── 2025-06-02/ │ └── 2025-06-03/ ├── templates/ # 模板文件 │ ├── problem_template.md │ └── code_template.py ├── scripts/ # 自动化脚本 │ ├── new_day.py │ ├── stats.py │ └── generate_readme.py ├── progress.csv # 全局进度表 └── README.md # 自动生成的索引页这个结构看起来简单但它解决了两个关键问题。daily 目录解决的是“每天怎么开始”的问题。每天新建一个以日期命名的文件夹里面放当天三道题的内容打开这个文件夹就能看到今天该做什么训练完就有一种“今天也留下了痕迹”的踏实感。topics 目录解决的是“复习怎么查”的问题。每道题在 daily 里记录完之后我会把精炼版题解复制到对应的主题目录下。这样等三个月后想集中刷动态规划只需要打开 topics/dynamic-programming就能看到我做过的所有 DP 题的精简笔记。progress.csv 是全局的数据中枢。它记录每道题的核心字段供统计脚本使用。这个文件不需要手动维护脚本会读取 daily 目录自动更新这也是我强调“摩擦最小”的一个体现。2.2 模板设计把复盘做成填空题模板是整个 t3code 的灵魂。很多人刷题不复盘本质原因是“不知道怎么复盘”觉得打开昨天的题一片空白无从下手。我的解决办法是把复盘做成填空题把思考过程固化成固定的问题每道题强制自己回答。题解模板是这个样子的# [LC-{题目编号}] {题目名称} - 难度{简单/中等/困难} - 主题{arrays / strings / ...} - 日期{YYYY-MM-DD} - 用时{分钟} ## 题目描述 用自己的话复述题目一两句话即可 ## 我的原始思路 写下看到题目时的第一反应即使很笨也没关系 ## 卡住的位置 具体写清楚卡在哪一步为什么卡住 ## 最终解法与复杂度 写出最终通过的解法以及时间和空间复杂度 ## 这道题教会我什么 一句话总结比如“遇到子数组问题先想前缀和”这个模板看起来简单但每一栏都有自己的意图。“用自己的话复述题目”是为了确认你真的看懂了题目很多卡壳其实从读题阶段就开始。“卡住的位置”是整个模板里最有价值的一栏因为如果你能准确知道自己卡在哪下一次进步就会非常快。代码模板则更简单只保留最小骨架 题目编号: LC-XXX 题目名称: XXX 难度: XXX 主题: XXX 日期: YYYY-MM-DD from typing import List def solve(nums: List[int]) - int: # 在这里写下你的解法 pass if __name__ __main__: # 在这里写两个测试用例 assert solve([1, 2, 3]) 6 print(all tests passed)会写代码的人一眼就能看出来这个模板的定位是“让你尽快写出可运行的代码”而不是“让你设计架构”。函数签名里的类型标注也不是随意写的它能帮你把注意力集中在逻辑而不是语法上。提示模板的价值不在于排版漂亮而在于“强制性”。每一栏都是必填项你每天都被逼着输出一点东西而反复输出就是复盘的本质。2.3 进度表字段设计progress.csv 是整个仓库的数据底座stats.py 脚本会读取它来做统计。字段设计如下date,problem_id,title,difficulty,topic,status,time_spent,key_lesson 2025-06-01,LC-1,Two Sum,Easy,arrays,completed,20,hashmap空间换时间 2025-06-01,LC-121,Best Time to Buy and Sell Stock,Easy,arrays,completed,45,一次遍历维护最小值 2025-06-01,LC-206,Reverse Linked List,Easy,linked-list,completed,15,递归与迭代两种视角 2025-06-02,LC-3,Longest Substring Without Repeating Characters,Medium,strings,reviewed,60,滑动窗口右指针扩展对你可能关心的字段做个简单说明status 字段有四个枚举值pending还没做、completed已 AC、reviewed过几天复盘过、failed卡了很久没做出来标记为待重做。time_spent 是分钟数不是精确计时大概估算就行。它的意义在于统计你的时间分布比如某天两道题花了 90 分钟就该考虑是不是题目选太难了。key_lesson 是“这道题教会我什么”的极简版只有一句话。这个字段的价值在于生成 README 索引时能快速扫出一整周的经验总结。这个 CSV 用 Excel 或者任何文本编辑器都能打开完全是开放格式不存在被绑定在某一个工具里的问题。3. 自动化脚本与核心流程实现3.1 每日新题生成器每天开始训练前只需要在终端跑一条命令脚本就会自动创建当天目录生成三个题解模板和三个代码模板并更新 progress.csvpython scripts/new_day.py这是 new_day.py 的核心实现#!/usr/bin/env python3 t3code 每日训练初始化脚本 import csv import datetime import os from pathlib import Path ROOT Path(__file__).resolve().parent.parent DAILY_DIR ROOT / daily TEMPLATE_DIR ROOT / templates PROGRESS_FILE ROOT / progress.csv DAILY_COUNT 3 def load_templates(): with open(TEMPLATE_DIR / problem_template.md, encodingutf-8) as f: problem_tpl f.read() with open(TEMPLATE_DIR / code_template.py, encodingutf-8) as f: code_tpl f.read() return problem_tpl, code_tpl def init_day(date: datetime.date): day_dir DAILY_DIR / date.isoformat() day_dir.mkdir(parentsTrue, exist_okTrue) rows [] for i in range(1, DAILY_COUNT 1): # 生成题解 markdown 文件 problem_file day_dir / fproblem_{i}.md if not problem_file.exists(): problem_file.write_text(problem_tpl, encodingutf-8) # 生成代码 python 文件 code_file day_dir / fsolution_{i}.py if not code_file.exists(): code_file.write_text(code_tpl, encodingutf-8) # 记录当天初始状态到 progress.csv rows.append({ date: date.isoformat(), problem_id: fTBD-{i}, title: , difficulty: , topic: , status: pending, time_spent: , key_lesson: , }) # 追加到 progress.csv注意处理文件不存在的情况 file_exists PROGRESS_FILE.exists() with open(PROGRESS_FILE, a, newline, encodingutf-8) as f: writer csv.DictWriter(f, fieldnamesrows[0].keys()) if not file_exists: writer.writeheader() writer.writerows(rows) print(f初始化完成: {date.isoformat()}) print(day_dir) if __name__ __main__: problem_tpl, code_tpl load_templates() init_day(datetime.date.today())这个脚本我已经用了很多天稳定性很高。几个关键细节说一下。路径解析这里用了Path(__file__).resolve().parent.parent而不是直接用相对路径。因为脚本可能在任意目录下执行如果写死相对路径换一个目录跑就崩了。resolve()的作用是把符号链接和相对路径全部转成绝对路径这是很多初学者写脚本时最容易忽略的坑。文件写入都加了exist_okTrue或者if not exists判断防止重复执行脚本时把已经写完的解题内容覆盖掉。我以前吃过这个亏跑了两遍初始化脚本结果三道题的空模板把三道已经做好的题解直接覆盖了还好 Git 能救回来从那以后所有生成类脚本都加了覆盖保护。3.2 进度统计与 README 自动生成第二个脚本是 stats.py它读取 daily 目录下的所有 markdown 文件统计已完成题数、连续打卡天数、主题分布然后输出到终端同时生成一份 README.md 作为仓库的门面。python scripts/stats.py核心统计逻辑大概是这样的#!/usr/bin/env python3 统计 t3code 仓库的训练数据并生成 README import csv from collections import Counter from pathlib import Path ROOT Path(__file__).resolve().parent.parent PROGRESS_FILE ROOT / progress.csv def load_progress(): with open(PROGRESS_FILE, encodingutf-8) as f: reader csv.DictReader(f) return list(reader) def compute_stats(rows): total len(rows) completed [r for r in rows if r[status] completed] reviewed [r for r in rows if r[status] reviewed] topic_counter Counter() for r in completed: if r[topic]: topic_counter[r[topic]] 1 difficulty_counter Counter() for r in completed: if r[difficulty]: difficulty_counter[r[difficulty]] 1 return { total: total, completed: len(completed), reviewed: len(reviewed), completion_rate: len(completed) / total * 100 if total else 0, topics: topic_counter.most_common(), difficulties: difficulty_counter.most_common(), }统计脚本输出的效果大概是这样t3code 统计报告 总题数: 45 已完成: 42 完成率: 93.3% 已复盘: 15 主题分布: arrays 12 dynamic-programming 8 strings 7 trees 5 难度分布: Easy 20 Medium 16 Hard 6这个统计带来的反馈非常重要。坚持一个月后你会发现自己的知识盲区清晰可见比如所有 Hard 题集中在动态规划那下一步就很明确了。README.md 的生成逻辑也不复杂就是把统计数字组织成一段 Markdown再附上最近 7 天的记录。好处是你打开仓库首页就能看到整体进展而不是要翻一堆文件才能搞清楚自己练到哪了。3.3 Git 工作流与提交规范t3code 每天的训练流程配合 Git形成了这样一条完整链路# 1. 初始化今天的内容 python scripts/new_day.py # 2. 训练过程做题、改文件、写题解 # 3. 提交今天的结果 git add . git commit -m daily: 2025-06-01 | 3 problems | 1 reviewed git push提交信息我约定了一个简单格式日期 完成情况 备注比如daily: 2025-06-01 | 3 problems | 1 reviewed。这样以后想看某一天做了什么一条git log --oneline就能快速定位。这里想特别说明一点每天训练结束后除了日常提交我还会定期打一个标签tag。比如每完成 30 道题就打一个v1.2、v1.3这样的标签。这就像游戏里的存档点回头想对比某个阶段的代码水平直接 checkout 到对应标签就能看到当时的全部状态。如果你也在搭自己的版本我建议把 Git 提交当成“完成训练”的仪式感。理论上代码效率工具不依赖仪式感但实际操作中仪式感对坚持是有帮助的。每一次git push都意味着今天的训练正式结束这种“收尾”动作能让大脑产生一种完成任务的满足感。4. 常见问题与排查技巧4.1 坚持不下去的三个真实原因t3code 跑了三个月中间最危险的一段时间是第二周到第三周差点放弃。我复盘后总结了三个真实原因每一个都有对应的解决办法。第一个原因是题目选得太难。状态好的时候我总觉得应该挑战 Hard 题结果两道 Hard 题卡了一晚上挫败感极强第二天就不想打开了。解决办法是引入难度配额每天三道题默认 1 道 Easy、1 道 Medium、1 道 Hard但允许动态调整状态差就 2 道 Easy 加 1 道 Medium状态好再上 Hard。第二个原因是反馈周期太长。刷题的学习反馈本来就慢如果连续一周没有做出一道“有感觉的题”很容易陷入自我怀疑。解决办法是在模板里强制记录“教会我什么”哪怕只是“这个 API 我记错了”也算一条收获。这种微小的正反馈其实很有用它把“今天学到东西了”具象化了。第三个原因是“全有或全无”心态。某天因为加班没刷题就觉得整个节奏断了想放弃整条线。解决方法是给每天留一条“最低线”哪怕只写一道题哪怕只填模板的前三栏也算今天完成了。断更最大的代价不是少练了一天而是让你觉得可以继续断下去。t3code 的 progress.csv 里允许 pending 状态存在就是为了不把“没完成”变成“放弃”。这几个问题在技术文章里很少被讨论但我觉得它们才是个人项目生死存亡的关键。一个自动化系统再精巧如果使用者三天后就跑了一切都等于零。4.2 文件结构乱了怎么救我中途有一段时间偷懒连续一周没有跑 new_day.py 脚本手动在 daily 目录下建了几个文件命名也比较随性。结果一周后想统计进度stats.py 读了一堆格式不一致的 markdown 文件名统计结果直接错乱。碰到这种情况核心原则是“先修数据再谈规则”。我常用的恢复流程是三步用 Git 找回最近的稳定版本看看问题是从哪次提交开始变乱的。把格式不标准的文件名统一重命名比如把题目.md、test.py全部改回problem_1.md和solution_1.py用正则批量处理。修正 progress.csv 里缺失的字段然后再跑 stats.py 验证。分享一个教训文件命名规范一定要写进 README 里并且脚本里有对应的校验逻辑。我现在 new_day.py 启动时就会检查当天目录里的文件数量是否至少为 63 个 markdown 3 个 python不足就会提醒。这个检查只花一行代码但能挡住大部分手滑操作。4.3 自动化脚本的常见故障脚本本身也会出问题我遇到过的典型故障主要有三个。第一个是时区问题。如果你把 t3code 接到 GitHub Actions 上做定时任务默认的 UTC 时区会让你在 UTC 0 点跑脚本而北京时间已经是早上八点日期会错位一天。解决办法是在 workflow 里显式设置时区比如- name: Setup timezone run: sudo timedatectl set-timezone Asia/Shanghai如果用的不是 GitHub Actions而是在本地用 cron同理也要先确认date命令输出的是不是本地日期。所有脚本里的datetime.date.today()都依赖系统时区这是一个很容易被忽略的坑。第二个是路径问题。脚本在本地跑得好好的push 到远端后如果 CI 环境里的目录结构和本地不一样就会FileNotFoundError。我给的脚本里用了Path(__file__).resolve().parent.parent就是为了在任何环境下都能定位到仓库根目录。这个模式在写任何小工具时都应该保持。第三个是 CSV 编码问题。Windows 上如果直接写文件Python 默认编码可能是 gbk而 GitHub 上一般是 utf-8会导致乱码。所有open()都加上encodingutf-8同时在仓库根目录放一个.gitattributes文件声明文本文件统一用 UTF-8一劳永逸。还有一个 Git 层面的问题如果你跟别人协作同一个仓库daily 目录因为每个人都有自己的日期路径冲突其实很少。但如果两个人同一天改了同一个题解pull 的时候就会出现冲突。我的建议是如果多人协作尽量用独立分支或者直接给每个人开一个 fork每周合并一次不要在同一分支上高频并发。5. 这套方案的扩展方向5.1 自动生成每周复盘报告t3code 目前已经能自动统计进度但我还在规划一个更自动化的功能每周生成一份复盘报告。逻辑其实不复杂遍历 progress.csv按周聚合数据输出本周完成题数、平均用时、最常见的卡壳原因然后把结果写进一个reports/weekly-2025-W24.md文件。这个功能的价值在于把复盘从“每周花半小时回忆”变成“打开文件就能看到数据”。我一直认为个人训练系统最值钱的部分不是训练本身而是“训练后如何回顾”的闭环。如果每周能一眼看到自己的薄弱点下一周的练习计划就有了明确依据。5.2 把答题模板接入你的编辑器我目前是手写 markdown 文件但如果你用 VS Code 或 Neovim完全可以把模板做成代码片段snippet在做题时输入一个前缀就能自动展开整个模板结构。VS Code 里用CtrlShiftP打开 Snippets 配置把问题模板贴进去就行。也可以更进一步写一个极小的 VS Code 插件调用 new_day.py但以我的经验来说直接用命令行已经很快了没必要增加一层 UI 依赖。工具链越长维护成本越高t3code 的设计哲学就是一切从简。5.3 从个人项目到组队打卡如果你有一两个朋友也想一起练代码可以在 t3code 的基础上去掉单人色彩变成一个小团队共享仓库。每个人每天提交到自己的目录下再用一个脚本汇总所有人的进度到总 README 里。组队模式最大的好处是加入了社交压力断更的时候会有人在群里问今天为什么没提交。但它有一个前提每个人都要遵守相同的模板和流程否则汇总脚本会炸掉。这其实也是一次很好的“工程协作”训练比单纯刷题更有意思。我个人在实际操作中体会最深的一件事是这个项目最大的产出不是代码量而是它让我养成了“固定时间、固定动作、固定输出”的习惯。现在每天写三道题前我会把昨天的模板里“这道题教会我什么”那一栏先读一遍这个动作花不到三十秒但比新刷三道题更有用因为它在强行激活记忆。最后再分享一个小技巧写模板的时候不要追求“完美格式”而是追求“任何时候都能看懂”。三个月后你能看懂当时写的“用双指针因为数组有序”这句话远比一个漂漂亮亮的排版重要。t3code 这套东西看起来很朴素但它真正跑起来的那一天你会在每一次 commit 和每一次复盘里感受到它的价值。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑