free-programming-books 仓库贡献指南:免费编程书单的资源分类、Markdown 格式与自动化校验规则详解
本文基于 free-programming-books 仓库的日文版贡献文档 docs/CONTRIBUTING-ja.md(其英文原文为 docs/CONTRIBUTING.md,另有 docs/CONTRIBUTING-zh.md 等各语言翻译)整理而成。free-programming-books 并不是一个软件项目,而是一个以 books/、courses/、casts/、more/ 四个目录组织、覆盖数十种语言的免费编程学习资源清单仓库,其"核心业务"就是维护一套规则严谨、格式统一的资源列表。因此,贡献指南中定义的资源分类口径、内容取舍标准、Markdown 排版契约与自动化校验机制,就是这个项目真正的"技术规范"。读完本文,你将掌握向该仓库提交 Issue / Pull Request 的完整流程,理解六类资源清单的划分边界,能够写出通过 fpb-lint 与 URL 校验的合规列表条目,并了解仓库在贡献流程之上叠加的 RTL/LTR 排版校验等自动化保障。
在投稿之前:两条必须接受的约束
向本仓库提交任何内容,首先意味着两重法律与社区层面的确认:
- 投稿者许可协议:通过提交内容,你即表示同意仓库根目录下 LICENSE 的许可条款。该仓库采用宽松许可,但贡献内容授权关系以 LICENSE 文本为准。
- 投稿者行为规范:通过贡献,你还同意遵守 docs/CODE_OF_CONDUCT-ja.md(日文版行为规范)所述要求,其翻译版本可在 README.md 的语言索引中找到。
这两条是进入后续所有实操规则的前提,无需额外签署任何协议,提交即视为同意。
一言以蔽之:贡献的五条总纲
日文版指南以"一言で言えば"(一句话概括)形式给出了贡献者必须牢记的五条总纲,后文所有细节均由它们展开:
- 免费性是第一原则:"能轻松下载本书的链接"不等于"指向免费图书的链接"。只提交确认为免费的内容,并尽量核实——仓库尤其不接受要求提供工作邮箱才能获取资源的页面链接,但欢迎那些"索取邮箱做登记"的列表式页面。
- 不懂 Git 也可以贡献:如果发现了仓库中还没有的有趣资源,直接带着链接建议去仓库的 Issues 区开一个 Issue 即可;熟悉 Git 的贡献者则可以把仓库 fork 后提交 Pull Request(PR)。
- 清单共有六类,必须对号入座:图书(书籍)、课程、交互式教程、Playground、播客与录屏、题目集与竞赛编程,详见下一节。
- 遵守下面的指南与格式契约:即 贡献指南与 Markdown 格式 两大部分。
- 必须通过自动化测试:仓库通过 GitHub Actions 运行测试,用于检查列表是否按字母顺序排列、格式规则是否被遵守。提交 PR 前务必确认测试通过。
值得注意的是第五点在仓库的 .github/PULL_REQUEST_TEMPLATE.md 中也以强制 checklist 的形式固化了下来,例如要求贡献者先搜索是否重复、包含作者与平台、按字母顺序排列并保持正确间距、补充 PDF 等必要标注,并在 PR 描述中说明"为何这份资源确实免费"。
六类资源清单:先分清楚"这是哪一种"
仓库的所有资源被划分为六个互斥类别,对应仓库中不同目录与文件:
| 类别 | 定义 | 仓库落位 |
|---|---|---|
| 图书 | PDF、HTML、ePub、基于 gitbook.io 的站点、Git 仓库等形式的完整书籍 | books/ 下的各语言 .md 文件 |
| 课程 | 非书籍形态的系统化学习材料(有授课、练习、测验、讲义等) | courses/ |
| 交互式教程 | 用户输入代码或命令、系统即时评测结果的交互网站 | more/free-programming-interactive-tutorials-*.md |
| Playground | 用于边写边编译/运行/分享代码片段的在线或桌面编程环境 | more/free-programming-playgrounds*.md |
| 播客与录屏 | 音频/视频形式的系列节目 | casts/ |
| 题目集与竞赛编程 | 通过解题评估编程技能的网站或软件 | more/problem-sets-competitive-programming.md |
日文版指南对每一类都有精辟的判别口诀,贡献时应逐条对照:
- 图书:PDF、HTML、ePub、gitbook.io 类站点、Git 仓库等都是书籍形态。
- 课程:课程是"不是书的学习材料"。注意——单个讲座或单条视频不算课程,PowerPoint 幻灯片也不算课程。
- 交互式教程:核心判据是"能否打印出来却仍然保有其精髓(交互性)"——如果能,那它就不是交互式教程。
tryhaskell.org、learngitbranching.js.org这类"输入代码 → 系统评测结果"的站点才是典型例子。 - Playground:写作、编译(或运行)、分享代码片段的地方,通常允许你 fork 一段代码上手摆弄。
- 播客与录屏:即音频播客与录屏视频。
- 问题集与竞赛编程:通过解决由简到难的问题来评测你编程技能水平的网站或软件。
这种"六类分治"直接决定了资源应该写进哪个目录、哪个文件,是最容易出现低级错误的环节。
通过 Issue 还是 PR 提交?
- 不熟悉 Git:在仓库 Issues 区新建一个 Issue,贴上资源链接与推荐理由即可。这是门槛最低的路径,也方便维护者先讨论再入库。
- 熟悉 Git:fork 仓库 → 按规则新增/修改列表 → 发起 PR。注意仓库在 .github/PULL_REQUEST_TEMPLATE.md 中明确要求:如果本次 PR 是对之前某个已提交 PR 的修订,应当回到原 PR 的分支上追加提交,而不是另开新 PR,以免让审阅变复杂。
贡献指南(Guidelines)——内容取舍与 URL 规范
免费性、托管平台与来源权威性
- 确认免费:务必确认书籍确实是免费的,必要时二次核验。在 PR 中留言说明"为什么你认为它是免费的",会大幅方便维护者审阅。
- 拒绝文件托管平台:不接受托管在 Google Drive、Dropbox、Mega、Scribd、Issuu 等类似文件上传平台上的文件。
- 来源要"权威":优先选择最权威的来源——作者自己的网站优于编者网站、优于第三方网站;同理不要使用文件托管服务(如 Dropbox / Google Drive 链接)。
- 同一资源多格式:当同一资源存在多个格式时,应分别添加带格式注记的链接(下文格式节有示例)。
- 同一资源多处存续:若资源在互联网上有多个版本/出处,选择最权威的来源;当不同版本差异大到值得分别保留时,可以为每个版本单独添加链接并附注说明。
URL 书写规范
日文版指南对 URL 本身有非常细致的可操作规则:
- HTTPS 优先:同一域名、提供相同内容时,
https链接永远优于http链接。 - 去掉根域名尾斜杠:写
http://example.com,而不是http://example.com/。 - 取最短链接:
http://example.com/dir/优于http://example.com/dir/index.html;禁止使用 URL 短链。 - "最新"优先于"版本号":
http://example.com/dir/book/current/优于http://example.com/dir/book/v1.0.0/index.html。 - 遇到 SSL 问题时按三步处理:① 可能的话先尝试改用
http(因为移动设备上接受证书例外很麻烦);② 若 http 版不可用但 https 版仍可访问,则保留该链接,让浏览器添加例外或忽略警告;③ 否则删除该链接。 - 多格式分开列:资源有多种格式时,为每种格式各加一个链接并注明格式。
- 不用短链服务,从 URL 中移除跟踪代码(tracking codes)。
- 国际化 URL 需转义:浏览器地址栏通常会把它们渲染成 Unicode,但入库时应使用复制粘贴所得、正确转义后的形式。
提交粒度与资源元信息
- 原子提交优先:一次提交只做一件事(一次新增 / 一次删除 / 一次修改),提交 PR 前不强制要求 squash 提交(这条只是维护者便利性约定,不会被强制执行)。
- 旧书标注年份:书籍比较旧时,在标题旁标注出版年。
- 作者署名:合适时写上作者名;作者列表可用"
et al."缩写。 - 未完成书籍:书籍尚未完成、仍在写作中的,加
in process标记(格式见下)。 - 归档资源:经 Internet Archive 的 Wayback Machine(或类似服务)恢复的失效资源,加
archived标记,最好选用较近的完整快照。 - 下载需登记:如果下载前必须配置邮箱或账号,应在括号内追加语言合适的注记,例如"邮箱地址并非必须"。
Markdown 格式规范
所有列表都是 .md 文件,使用标准 Markdown。日文版指南对排版给出了一套"空行契约",可直接对照 books/ 下各语言实际文件验证。
结构与标题层级
- 每个列表文件以**索引(Index)**开头,索引中列出全部章节与子章节链接,并按字母顺序排列。
- 章节用三级标题
###,子章节用四级标题####。例如 books/free-programming-books-ja.md 中### Git、### Go是语言/主题章节,而#### Gradle、#### Grails、#### Spock Framework是### Groovy下的子章节。
空行规则(极易被 lint 抓到的点)
- 最后一个链接与新章节标题之间:2 个空行。
- 标题与该章节第一个链接之间:1 个空行。
- 两个相邻链接之间:0 个空行。
- 每个
.md文件末尾:1 个空行。
示意如下:
[...]
* 某本很棒的书(http://example.com/example.html)
(空行)
(空行)
### 示例
(空行)
* 另一本很棒的书(http://example.com/book.html)
* 还有一本书(http://example.com/other.html)
链接与作者字段的拼写细节
以下正误对照来自日文版指南,是最容易在 lint 中报错的"手滑"点:
]与(之间不能有空格:
BAD : * [Another Awesome Book] (http://example.com/book.html)
GOOD: * [Another Awesome Book](http://example.com/book.html)
- 包含作者时使用
-(前后带空格的连字符):
BAD : * [Another Awesome Book](http://example.com/book.html)- John Doe
GOOD: * [Another Awesome Book](http://example.com/book.html) - John Doe
- 链接与格式注记之间加半角空格:
BAD : * [某本很棒的书](https://example.org/book.pdf)(PDF)
GOOD: * [某本很棒的书](https://example.org/book.pdf) (PDF)
- 作者在格式注记之前:
BAD : * [A Very Awesome Book](https://example.org/book.pdf)- (PDF) Jane Roe
GOOD: * [A Very Awesome Book](https://example.org/book.pdf) - Jane Roe (PDF)
- 多格式资源的推荐写法——同一资源尽量只给一个主链接,不同格式以附加链接形式出现(每多一个链接就多一份维护负担,应尽量规避):
BAD : * [Another Awesome Book](http://example.com/)- John Doe (HTML)
BAD : * [Another Awesome Book](https://downloads.example.org/book.html)- John Doe (download site)
GOOD: * [Another Awesome Book](http://example.com/) - John Doe (HTML) [(PDF, EPUB)](https://downloads.example.org/book.html)
例如 books/free-programming-books-ja.md 中 Pro Git 一条即是多格式链接的教科书式案例:* [Pro Git](http://git-scm.com/book/ja/) - Scott Chacon, trl.: 高木正弘 他 (PDF, EPUB, MOBI)。
- 旧书年份放进标题括号,而不是写在作者后面:
BAD : * [A Very Awesome Book](https://example.org/book.html) - Jane Roe - 1970
GOOD: * [A Very Awesome Book (1970)](https://example.org/book.html) - Jane Roe
- in process(写作中)标记,使用
:construction:图标:
GOOD: * [Will Be An Awesome Book Soon](http://example.com/book2.html) - John Doe (HTML) ( :construction: *in process*)
- archived(已归档)标记,使用
:card_file_box:图标并附 Wayback 快照地址:
GOOD: * [ウェイバックされた面白い本](https://web.archive.org/web/20211016123456/http://example.com/) - John Doe (HTML) *( :card_file_box: archived)*
字母顺序(アルファベット順)
- 标题以同一字母开头的多个条目,从第二个字符起继续比较排序,如
aa排在ab之前。 - 含空格标题的排序规则是:
one two排在onetwo之前。 - 若出现链接顺序错位,查看 linter 报错信息即可知道该交换哪几行。仓库中 books/free-programming-books-ja.md 等列表文件的目录顺序即为实测样例。
内容边界:什么绝不收录,什么是"书"
不收入清单的类型
为避免无限膨胀,以下类型一律不收录:
- 博客、博客文章、普通文章;
- 网站(那些承载了大量上榜资源的平台除外);
- 课程与录屏之外的视频;
- 书的章节、书的预告样章;
- IRC / Telegram 频道;
- Slack 群与邮件列表。
竞赛编程列表对这些排除项相对宽松——仓库边界由社区共同决定,若想扩展或修改收录范围,请通过 Issue 提议。
判断"它是不是书"
指南对"书"的判定并不僵化,以下属性可以辅助判断:
- 拥有 ISBN;
- 有目录(目次);
- 提供可下载版本,尤其有 ePub;
- 有版本(edition);
- 不依赖交互内容或视频;
- 试图全面覆盖某个主题;
- 自成一体(self-contained)。
榜单中很多条目并不具备全部属性,关键是与既有条目气质一致。
书 vs 课程
两者有时难以区分:课程往往附带教科书(教科书进图书榜),而课程本身包含授课、练习、测验、笔记与讲义等要素。单条讲座或视频不足以构成课程,PowerPoint 也不是课程。
交互式教程 vs 其他
判别唯一法则是:能打印出来却仍保有精髓的东西,不是交互式教程——交互性一旦脱离键盘输入与即时反馈就不复存在。
元数据与平台注意点(注意事項)
标题
- 不要创作标题:尽量避免编造或采用编辑性标题;例外是"旧作"——当作品主要因历史意义被收录时,可在标题加括号年份,帮读者判断是否值得一看。
- 不要全大写(ALLCAPS):一般遵循源出处的正常大小写,拿不准时照抄原文大小写。
- 不要使用 emoji。
URL(补充)
- 不允许短链;删除 URL 中的跟踪代码;国际化 URL 使用转义形式;
https优先于http;我们不喜欢指向"并未承载所列资源"的落地页的 URL。
创作者(クリエイター)
项目希望给创作者署名,包括译者:
- 译作的署名:原著者应获署名,其他创作者可用 MARC relators 编码标注。文档推荐用
trl.:表示译者,示例:books/free-programming-books-ja.md 中既有trl:也有trl.:两种写法的真实条目,如* [オープンソースソフトウェアの育て方](https://producingoss.com/ja/) - Fogel Karl, trl: 高木正弘, trl: Yoshinari Takaoka。MARC 编码本身建议参考 loc.gov 的 relator 词表。 - 作者列表各项用英文逗号
,分隔;可用et al.缩写。 - 禁止给创作者附加外部链接。
- 汇编/混编作品的创作者需要描述性说明,例如 GoalKicker、RIP Tutorial 出品的书应标注"
Compiled from StackOverflow documentation"。 - 创作者姓名中不要包含
Prof.、Dr.等头衔。
限时课程与试用(期間限定のコースとトライアル)
- 凡是"6 个月之内就会被移除"的内容不收录;
- 报名期间/有效期受限的课程不收录;
- 限时免费资源不收录。
平台与访问注记
- 课程平台:课程清单中平台是资源描述的重要组成。图书通常不列需要注册才能阅读的,但许多课程平台没有账号就用不了(如 Coursera、edX、Udacity、Udemy 等)。课程依赖某平台时,平台名须写入括号。
- YouTube:以播放列表形式组织的课程很多;这时一般不把 YouTube 当平台名,而是标注 YouTube 创作者。
- 单条 YouTube 视频:除非时长在 1 小时以上且按课程/教程结构组织,否则不收录;收录时务必在 PR 描述中说明。
- 短链(如 youtu.be/xxxx)禁止。
- Leanpub:该平台混合了多种访问模式。无需注册即可读的收录;需要 Leanpub 账号才能免费读的,允许附加访问注记
*(Leanpubアカウントまたは有効な電子メールが必要です)*(需要 Leanpub 账号或有效邮箱)。
自动化校验:fpb-lint、awesome_bot 与 RTL/LTR 检查
日文版指南明确说明,格式规则的强制依靠 fpb-lint 与 GitHub Actions 完成:
- 格式检查:由 fpb-lint(free-programming-books-lint)负责。该 workflow 在 PR 事件触发时全局安装
free-programming-books-lint,然后执行:
fpb-lint books casts courses more &> output.log
它会检查列表是否按字母顺序排列、格式规则(间距、空行、]/( 紧贴等)是否合规,并把清理后的错误日志上传为 workflow artifact 供作者查看。free-programming-books-lint 本身也独立发布,供本地预检使用。
- URL 有效性检查:使用
awesome_bot完成。查看 .github/workflows/check-urls.yml 可见其实际执行方式为:
awesome_bot "${{ matrix.file }}" --allow-redirect --allow-dupe --allow-ssl || true;
即允许跳转、允许重复、允许 SSL,并对每个改动文件生成结果 artifact 再汇总成报告。
- 手动触发 URL 检查:向仓库推送一条提交消息中带
check_urls=文件路径的提交即可触发校验,例如:
check_urls=free-programming-books.md free-programming-books-ja.md
可以同时指定多个文件。当指定多个文件时,构建结果以最后检查的那个文件为准——因此请在 PR 末尾点击 "Show all checks" → "Details" 查看构建日志,以免误判。
- RTL/LTR 排版检查(仓库现有扩展):除贡献指南提到的两项外,仓库还内置了第三个质量门禁——.github/workflows/rtl-ltr-linter.yml 会在 PR 涉及阿拉伯语/希伯来语/波斯语/乌尔都语(ar、he、fa、ur)等 RTL 语言文件或带
RTL标签时,运行 scripts/rtl_ltr_linter.py。该脚本逐行解析 Markdown 列表条目,检测 RTL 文本中嵌入的 LTR 关键词(如HTML)、符号(如C#)是否需要‏/‎等 Unicode 控制符,并结合python-bidi做双向文本视觉序分析;其严重级别(error/warning/notice)与忽略清单等均可在 scripts/rtl_ltr_linter_config.yml 中配置。这意味着面向 RTL 语言文件贡献时,除了格式与 URL,还要保证双向文本在 GitHub 上渲染不乱序。
给贡献者的最终自查清单
综合日文版贡献指南与仓库内的 .github/PULL_REQUEST_TEMPLATE.md,一次合格的贡献应当通过以下自查:
- 先检索确认没有重复条目(官方还提供免费的搜索界面用于查重)。
- 明确资源属于六类中的哪一类,写进正确的目录文件。
- 确认资源确实免费且不受"6 个月内下架 / 限时免费 / 需工作邮箱"等限制,不托管在网盘类平台。
- 选择了最权威来源、最短且无跟踪参数的 URL,
https优先。 - 格式合规:正确空行、
-分隔作者、格式注记用半角空格、标题不造词不带 emoji。 - 必要时补齐标注:旧书年份入标题、写作中加
:construction: in process、归档快照加:card_file_box: archived、多格式附次级链接、译者用trl.:编码。 - 列表保持字母顺序,让
fpb-lint与(涉 RTL 文件时的)rtl-ltr-linter全部通过;URL 校验如需手动触发,用带check_urls=的提交消息推送,并在 PR 页面确认最终构建日志。
遵循上述规范提交的 PR,将能顺畅地通过自动化校验并大幅降低维护者的审阅成本——这正是 free-programming-books 能在十余年、数十种语言间保持列表一致性与高质量的原因。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0627
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00