想象你是位开“融合菜餐厅”的老板。招牌菜“冬阴功和牛煲”是你的命根子,绝不能让人把配方抄走。要做这道菜,你得去食材市场进货:牛肉、香茅、青柠……每样食材的包装袋上都印着“使用规则”。有的写着“随便用,不用告诉我你怎么做菜”;有的写着“用了我的焦糖酱,你这道菜的做法必须公开贴在墙上”。这些规则,就是开源世界里的“许可证”。商业落地最怕的就是:辛辛苦苦做了一桌好菜,却因为一瓶不起眼的酱料,被迫把全部祖传秘方公之于众。这篇指南带你认清楚货架上每瓶酱料的性格——谁随便用、谁爱黏人、谁和谁不能进同一口锅,把合规风险拦在厨房门外。

岗位关联

开源协议兼容性是 AI 技术人走向商业落地的“合规基本功”:懂得选酱,才能在技术选型会上说清风险,在产品发布前拦住法律踩坑,成为团队里既懂技术又懂商业的稀缺人才。

目录
  1. 可视化演示
  2. 协议家族图谱
  3. 宽松许可证
  4. 传染性协议
  5. 兼容性判断
  6. 混用实践
  7. 商业落地策略
  8. 合规检查清单
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

动态演示开源协议兼容性怎么选?商业落的核心机制,通过开始/执行/监控/完成四种模式展示关键概念与交互流程。

本节配有交互动效(进入视口后自动加载,约 3KB)。

开源协议兼容性怎么选?商业落:协议兼容 协议兼容性的定义与判定标准 MIT与Apache协议的兼容 核心机制可视化 开源协议兼容性怎么选?商业落整体架构与关键组件

协议家族图谱

站在食材市场门口,几百瓶酱料看得人眼花。但仔细翻看标签,你会发现所有供应商其实只有两种“性格”:一类是“随便用、不追究”的佛系食材,一类是“用了就必须分享”的黏人酱料。开源世界也一样——所有许可证都可以粗分成两大阵营:宽松许可证(permissive)和传染性许可证(copyleft)。它们决定了代码进了你的锅之后,你还能不能保留自己的秘方。

许可证本质上是一份“使用许可合同”,版权人用它来约定别人能用代码做什么。要在几百份协议里做选择,关键是看懂一条“宽松度光谱”:从义务最少的 MIT,到义务最重的 GPL,自由度逐级递减。

光谱最左端 MIT 条款极短,核心义务只有“保留版权声明”;往右 Apache-2.0 在 MIT 之上增加了专利授权和修改标注;中间的 MPL-2.0 只要求被你修改过的文件开源;LGPL 把开源要求收窄到“库”本身;最右端的 GPL 则要求整个衍生作品全部开源。这条光谱,是后面所有兼容性判断的地图。

进货先看性格。同一种食材,标签不同,进了厨房的命运就完全不同——先认识家族图谱,才能谈得上搭配。

宽松度:MIT≻Apache≻MPL≻LGPL≻GPL\text{宽松度}: \text{MIT} \succ \text{Apache} \succ \text{MPL} \succ \text{LGPL} \succ \text{GPL}
这条链排序就是你的“进货优先级表”:越靠左的食材越安全、义务越少。
  1. 宽松度(自由度)指使用者能保留多少自主权,数值越大、义务越少、越自由。
    宽松度:MIT≻Apache\text{宽松度}: \text{MIT} \succ \text{Apache}
  2. Apache 次之MIT 基础上多了专利授权与修改标注义务。
    Apache≻MPL\text{Apache} \succ \text{MPL}
  3. MPL 居中只要求被你修改过的文件按 MPL 开源。
    MPL≻LGPL\text{MPL} \succ \text{LGPL}
  4. LGPL 库级只要求库本身开源,动态链接的主程序不受影响。
    LGPL≻GPL\text{LGPL} \succ \text{GPL}
  5. GPL 居末最严格的强传染协议,整个衍生作品必须开源。
    传染范围(GPL)=整个衍生作品\text{传染范围}(GPL) = \text{整个衍生作品}

宽松许可证

市场西侧有一排贴着绿标的“免费食材箱”——MIT、Apache、BSD。供应商拍胸脯保证:肉和菜随便拿,回去做成什么菜、卖多少钱都行,只求你在菜单不起眼处贴张小纸条,注明“食材来自谁家”。这大概是所有餐厅老板最爱的进货渠道。

宽松许可证的核心是“不设传染条件”:它不要求你开源修改后的代码,也不限制你闭源商用。但“宽松”不等于“零义务”——拿食材也得留小纸条。

MIT 的义务只有一项:在软件副本或实质部分中,保留原作者的版权声明和许可文本。Apache-2.0 在此基础上多了两项:标注你修改过哪些文件,以及第 3 条“专利授权”——贡献者把相关专利免费授予使用者;如果你反过来起诉别人侵犯该专利,你的授权会自动终止(第 3.2 条)。正因如此,商业团队更偏爱 Apache:React 选 MIT,Kubernetes 选 Apache-2.0,大厂们就是为了给下游商业公司“敢用”的信心。

免费食材箱的“小纸条”成本极低,却换来了整个商业生态的信任。这正是宽松许可证的伟大之处:它用最小的约束,换来了最大的采用。

义务MIT={保留版权声明},义务Apache={保留声明,标注修改,专利授权}\text{义务}_{\text{MIT}} = \{\text{保留版权声明}\},\quad \text{义务}_{\text{Apache}} = \{\text{保留声明}, \text{标注修改}, \text{专利授权}\}
宽松协议的义务清单很薄,这也是商业闭源最爱的原因——用了几乎像没用。
  1. 义务集合花括号表示“一揽子必须履行的条件”,每一项都不可省略。
    义务MIT={保留版权声明}\text{义务}_{\text{MIT}} = \{\text{保留版权声明}\}
  2. Apache 扩展项在 MIT 基础上增加“标注修改位置”和“向使用者授予专利许可”。
    义务Apache={保留声明,标注修改,专利授权}\text{义务}_{\text{Apache}} = \{\text{保留声明}, \text{标注修改}, \text{专利授权}\}
  3. 无传染项两个集合里都没有“开源衍生作品”这类义务,所以改完可以闭源卖钱。
    义务Apache∩传染义务=∅\text{义务}_{\text{Apache}} \cap \text{传染义务} = \varnothing

传染性协议

后厨货架最深处锁着一瓶红色标签的焦糖酱,包装上印着:“本品倒入任何菜肴,该菜肴完整做法须公之于众。”厨师们私下叫它“共享病”——一沾就黏住整锅。这就是传染性许可证(copyleft,也称著佐权)的风格:版权人反过来用版权做杠杆,要求你的衍生作品必须以同样条款开源。

最著名的传染性协议是 GPL。它的传染对象是“衍生作品”——通俗讲,就是从你的代码“长出来”的作品:修改版、合并版、链接版都算。但这瓶焦糖酱的黏度分三档。

GPL 最黏,传染整个衍生作品;LGPL 是 GPL 的“图书馆特供版”,动态链接使用不传染主程序,但如果你修改了库本身或静态链接,库的改动必须开源;MPL-2.0 最温和,只要求被你改过的那个文件开源,其他文件可以继续闭源商用。于是传染范围形成了“整锅 > 酱瓶 > 一片”的嵌套递减。

焦糖酱到底黏到什么程度,决定了你上菜前要不要公开配方。搞清楚黏度,是混用前最重要的一课。

传染范围(GPL)  ⊇  传染范围(LGPL)  ⊇  传染范围(MPL)\text{传染范围}(GPL) \;\supseteq\; \text{传染范围}(LGPL) \;\supseteq\; \text{传染范围}(MPL)
传染范围是层层子集:最严格的 GPL 把整个锅都占了,LGPL 只黏酱瓶,MPL 只黏你动过的那一片。
  1. 传染范围函数输入一种协议,输出“必须开源的作品范围”。
    传染范围(⋅)\text{传染范围}(\cdot)
  2. GPL 全覆盖整个衍生作品(整锅菜)都要公开源码。
    传染范围(GPL)\text{传染范围}(GPL)
  3. LGPL 收窄只波及库本身,动态链接的主程序不被传染。
    传染范围(LGPL)\text{传染范围}(LGPL)
  4. MPL 最小只要求被修改过的文件开源,其余文件保持私有。
    传染范围(MPL)\text{传染范围}(MPL)
  5. 包含关系三者层层嵌套,构成“整体 > 库 > 文件”的递减链条。
    传染范围(GPL)⊇传染范围(LGPL)⊇传染范围(MPL)\text{传染范围}(GPL) \supseteq \text{传染范围}(LGPL) \supseteq \text{传染范围}(MPL)

兼容性判断

两种酱料能不能进同一口锅?厨师长老规矩一句话:“谁强听谁的。”宽松的佛系酱油掉进 GPL 的锅里,整锅还是 GPL;可 GPL 焦糖被加到一碗自由酱油里,这碗酱油也得按 GPL 公开。协议兼容性,本质就是求两份“使用规则”的公约数。

判断兼容有四条经验。第一,宽松组件(MIT/BSD)可以并入任何 GPL 项目,整体按 GPL 发布。第二,Apache-2.0 与 GPLv3 兼容,因为 GPLv3 明确了与 Apache 的兼容声明。第三,Apache-2.0 与 GPLv2 不兼容:GPLv2 不承认 Apache 的专利救济条款,两者法律逻辑互斥。第四,GPLv2-only 与 GPLv3-only 互相不兼容,只有标注"or later"的代码才能自动升级到兼容版本。

常用组合可以查这张速记表:

| 主项目协议 | 引入 MIT | 引入 Apache | 引入 LGPL | 引入 GPL |

|---|---|---|---|---|

| MIT / Apache(宽松) | ✅ | ✅ | ⚠️ 限动态链接 | ❌ 整体变 GPL |

| GPL-3.0 | ✅ | ✅ | ✅ | ✅ |

| GPL-2.0 | ✅ | ❌ 专利冲突 | ✅ | ⚠️ 限 GPLv2 |

混酱前先看“谁强谁弱”:强协议永远决定整锅的底线。选错一瓶酱,可能毁掉整桌菜。

组合结果={GPLMIT 并入 GPL 项目GPLv3Apache 并入 GPLv3 项目不兼容Apache 并入 GPLv2 项目\text{组合结果} = \begin{cases} \text{GPL} & \text{MIT 并入 GPL 项目} \\ \text{GPLv3} & \text{Apache 并入 GPLv3 项目} \\ \text{不兼容} & \text{Apache 并入 GPLv2 项目} \end{cases}
混用前先用这个分段函数心算一遍,比事后被律师提醒便宜得多。
  1. 组合结果函数混用协议时,输出协议由“谁更严格”决定。
    组合结果=f(各类输入协议)\text{组合结果} = f(\text{各类输入协议})
  2. MIT 进 GPLMIT 允许被吸收,整件作品按 GPL 发布。
    MIT⊂GPL 作品\text{MIT} \subset \text{GPL 作品}
  3. Apache 进 GPLv3GPLv3 官方声明兼容 Apache-2.0,可正常混用。
    Apache⊂GPLv3 作品\text{Apache} \subset \text{GPLv3 作品}
  4. Apache 进 GPLv2专利救济条款互斥,法理上不能兼容。
    Apache∩GPLv2=∅\text{Apache} \cap \text{GPLv2} = \varnothing

混用实践

焦糖酱真要上桌怎么办?厨师长有对策:不把酱倒进主锅,而是装进独立小碟子让客人自己蘸;甚至做成一道单独的“配菜”,通过传菜窗递进餐厅。主厨秘方保住了,酱也上了桌。技术世界同理——是否被传染,取决于主程序和第三方组件是“合体”还是“拼接”。

“合体”在法律上叫衍生作品,“拼接”叫聚合(mere aggregation)。静态链接(第三方代码被编进你的二进制)通常被视为合体,GPL 传染生效。动态链接(运行时才加载 .so/.dll)中主程序和库边界清楚:LGPL 明确允许这种用法,但要求你必须允许用户替换、重新链接该库;对 GPL 而言,动态链接是否构成衍生作品仍有争议,稳妥方案是进程隔离。

进程隔离就是把 GPL 组件做成独立服务,通过 HTTP 或 RPC 通信。这样主程序和组件是两个独立作品,GPL 不传染。最后记住一条红线:即使隔离成功,你修改 GPL/LGPL 组件本身产生的改动代码,依然要开源。

小碟子让主厨秘方保住了,但碟子本身若被改过,配方也得公开。隔离是技术方案,更是边界意识。

传播条件{传染静态链接或整体合并隔离动态链接或进程通信\text{传播条件} \begin{cases} \text{传染} & \text{静态链接或整体合并} \\ \text{隔离} & \text{动态链接或进程通信} \end{cases}
链接方式是厨房里的“倒法”:倒进锅里传染,放旁边碟子隔离。
  1. 传播条件判定是否传染取决于主程序与组件的“合体”方式。
    传播=g(链接方式,分发方式)\text{传播} = g(\text{链接方式}, \text{分发方式})
  2. 静态链接或整体合并代码边界消失,视为衍生作品,触发传染。
    传染⇐静态链接\text{传染} \Leftarrow \text{静态链接}
  3. 动态链接运行时加载库,LGPL 允许主程序保持私有。
    隔离⇐动态链接\text{隔离} \Leftarrow \text{动态链接}
  4. 进程通信通过接口传数据而非合代码,组件是独立作品。
    隔离⇐进程通信\text{隔离} \Leftarrow \text{进程通信}

商业落地策略

开餐厅终究为了赚钱。聪明的老板会把秘制酱料锁进保险柜,只在门口免费送几包大众化腌料——既引来流量,又保住命根子。这就是“开放核心(open core)”的生意经:内核闭源,外围开源。

商业落地选协议,本质是回答两个问题:哪些代码必须闭源?哪些代码可以开源换生态?答案藏在三条原则里。第一,核心算法、模型管线、推荐策略只依赖宽松协议组件,任何传染性协议都不应进入交付物。第二,SaaS 场景要特别警惕 AGPL:它把“通过网络提供服务”也视作分发,用了修改版就必须把服务端源码公开。第三,双许可证双轨制:社区版用开源协议获客,商业版用专有协议卖进阶功能,MySQL 就是经典案例。

为了给每个组件排风险优先级,团队常用这条经验公式:传染组件越多、改动越深,风险越大;隔离手段越强,风险越小。

菜单设计决定餐厅命运,协议选型决定产品能否安全赚钱。记住一句话:核心永远别碰焦糖酱。

风险分=∑i(传染组件数i×修改程度i)隔离系数\text{风险分} = \frac{\displaystyle\sum_i(\text{传染组件数}_i \times \text{修改程度}_i)}{\text{隔离系数}}
风险分只用于排优先级:分数越高的组件,越应优先替换或单独隔离。
  1. 分子传染组件数 × 修改程度:组件越多、改动越深,风险基数越大。
    ∑i(传染组件数i×修改程度i)\displaystyle\sum_i(\text{传染组件数}_i \times \text{修改程度}_i)
  2. 修改程度系数0 到 1 之间的加权值,只改调用约 0.2,改源码则接近 1。
    修改程度i∈[0,1]\text{修改程度}_i \in [0, 1]
  3. 分母隔离系数:动态链接、独立进程等手段可以成倍压低风险,取值不小于 1。
    隔离系数≥1\text{隔离系数} \geq 1
  4. 整体风险分综合得分越高,越要优先替换或重构该组件。
    风险分=分子分母\text{风险分} = \frac{\text{分子}}{\text{分母}}

合规检查清单

餐厅火了之后,卫生稽查上门了。老板需要拿出三样东西:进货单、配料表、后厨操作记录,证明每道菜来源清白。开源产品的“卫生检查”就是法律合规审计——难点不在“做”,而在“可证明”。

四道工序缺一不可,最好在产品发布前就固化进流程。第一,许可证声明:每个组件目录保留 LICENSE 与 NOTICE 文件,分发物里附带声明页。第二,源码提供义务:对 GPL/LGPL 组件提供对应源码,或附上有效期至少三年的书面要约(written offer)。第三,修改记录:用 CHANGELOG 和 Git 历史锁定每个传染组件的改动痕迹。第四,清单管理:用 SBOM(软件物料清单)配合 SPDX 标准登记组件名、版本、协议,并在 CI 流水线里自动扫描新引入的依赖。

卫生合格证到手,餐厅才能安心开张;协议合规清点完毕,产品才能放心商用。把清单做成习惯,法律风险就追不上你。

合规  ⟺  声明∧源码提供∧修改记录∧清单留档\text{合规} \iff \text{声明} \land \text{源码提供} \land \text{修改记录} \land \text{清单留档}
合取式提醒你:合规是一整套动作,不是选择题——缺任何一项,合取结果就是“不合规”。
  1. 合取号 ∧四项义务是“并且”关系,缺一项合规即不成立。
    合规=⋀i=14义务i\text{合规} = \bigwedge_{i=1}^{4} \text{义务}_i
  2. 声明义务随分发保留 LICENSE、NOTICE、版权说明。
    义务1=许可证声明\text{义务}_1 = \text{许可证声明}
  3. 源码提供义务对传染性组件附源码或三年有效的书面要约。
    义务2=源码提供\text{义务}_2 = \text{源码提供}
  4. 记录与留档修改记录与 SBOM 清单长期存档,审计可追溯。
    义务3∧义务4\text{义务}_3 \land \text{义务}_4

AI 应用场景

场景 1:AI 模型库的“引包前体检”

阶段:技术选型与架构评审

解决的问题:AI 工程师习惯直接 pip install 开源库,却常忽略库的许可证——一旦引入 GPL 传染组件,整个商业产品被迫开源。传统做法靠人工翻 README,漏检率极高。

具体案例:某 AI 面试产品团队计划集成一个 GPL 协议的语音识别库,法务评审发现它若与核心服务静态链接,会传染整个后端。团队最终改为调用对方提供的商用 API(进程隔离),并把推理组件换成 Apache 协议的替代库,风险当场清零。

场景 2:模型权重与训练代码的协议边界

阶段:模型训练与数据合规

解决的问题:用开源代码训练出的模型权重,算不算“衍生作品”?不同协议边界不同,判断错了可能侵犯版权。

具体案例:某创业公司用 GPL 爬虫框架抓数据训练推荐模型。法务意见是:权重通常不视为 GPL 下必须开源的衍生作品,但修改后的训练管线代码需要开源。团队随后把训练管线全部重写为 MIT 组件,彻底规避了争议。

场景 3:开源商业化的双许可证设计

阶段:产品发布与商业化定价

解决的问题:既想靠开源社区引流,又怕核心算法被复制。这是每个开源创业团队都要过的坎。

具体案例:某向量数据库创业公司采用 Apache-2.0 社区版开放基础功能,商业版闭源提供高可用集群与管控界面;同时评估了 fork 一个 AGPL 数据库做 SaaS 的风险,最终选择自研存储层,绕开网络传染条款。

Python 演示

python50 行
# -*- coding: utf-8 -*-"""开源协议兼容性体检: 检查项目依赖列表中的许可证风险""" LICENSE_LEVEL = {    "MIT": 0,    "BSD-3-Clause": 0,    "Apache-2.0": 0,    "MPL-2.0": 1,    "LGPL-3.0": 2,    "GPL-3.0": 3,    "GPL-2.0": 3,} STRONG = {"GPL-3.0", "GPL-2.0"}  def risk_report(project, deps):    """project 为项目自选协议, deps 为 {组件名: 协议名}"""    if project not in LICENSE_LEVEL:        return ["项目协议未知: %s" % project]    issues = []    for name, lic in deps.items():        if lic not in LICENSE_LEVEL:            issues.append("%s 协议未知, 需人工确认: %s" % (name, lic))            continue        if LICENSE_LEVEL[project] == 0 and lic in STRONG:            issues.append("%s(%s) 会传染整个项目, 建议替换或隔离" % (name, lic))        if project == "GPL-2.0" and lic == "Apache-2.0":            issues.append("Apache-2.0 与 GPL-2.0 专利条款冲突, 不可混用")        if {project, lic} == {"GPL-2.0", "GPL-3.0"}:            issues.append("GPL-2.0 与 GPL-3.0 版本不兼容, 不可直接组合")    return issues  def main():    deps = {        "requests": "Apache-2.0",        "django": "BSD-3-Clause",        "ffmpeg-core": "GPL-3.0",    }    print("== 项目协议: MIT ==")    for line in risk_report("MIT", deps):        print(line)    print("== 项目协议: GPL-2.0 ==")    for line in risk_report("GPL-2.0", deps):        print(line)  if __name__ == "__main__":    main()
目的:一个极简的“协议体检器”——输入项目自选协议和依赖清单,自动输出每一条许可证兼容性风险,相当于把本文的兼容性矩阵翻译成了可执行的检查规则。
  1. LICENSE_LEVEL = { ... }给每种协议打“传染等级分”:0 宽松、1 文件级、2 库级、3 强传染,程序比较全靠它。
  2. STRONG = {"GPL-3.0", "GPL-2.0"}用集合圈出强传染协议,便于快速判断“会不会黏住整锅”。
  3. if project not in LICENSE_LEVEL项目自选协议不在表里,直接返回“需人工确认”。
  4. if LICENSE_LEVEL[project] == 0 and lic in STRONG宽松项目撞上 GPL 强传染组件,整锅菜被黏住,建议替换或隔离。
  5. if project == "GPL-2.0" and lic == "Apache-2.0"Apache 专利条款与 GPLv2 冲突的规则,变成一行可执行代码。
  6. if {project, lic} == {"GPL-2.0", "GPL-3.0"}用集合比较同时捕获两种顺序的版本冲突,写法很 Pythonic。
  7. for line in risk_report("MIT", deps)把体检报告逐条打印出来,接到 CI 里就能当门禁。

常见误区

误区我用了 MIT 的代码,既然它说“随便用”,那我连版权声明都不用保留,直接当自己写的就行。

正解MIT 的两项核心义务恰恰是“保留版权声明”和“保留许可声明”。它宽松的是“不要求开源、不限制商用”,不是“零义务”。类比:免费食材箱的老板不要求你公开秘方,但要求你在菜单角落贴上“食材来源”纸条。

为何常见:把“宽松”误读成“无要求”,看到 MIT 文本很短就直接跳过,从未真正读过许可内容。

误区我的服务里 pip install 了一个 GPL 包,是不是整个后台代码都要被迫开源?

正解传染与否取决于“衍生作品”边界和分发行为。动态链接、独立进程、通过接口调用通常不构成衍生作品;内部使用、不对外分发也不触发 GPL 的源码提供义务。焦糖酱是倒进锅里才算黏住整锅,放桌上当蘸料不算。

为何常见:把“接触”等同于“混合”,把“使用”等同于“分发”,对传染的触发条件想当然。

误区Apache 是宽松协议,宽松可以并入 GPL,所以 Apache 跟 GPLv2、GPLv3 都能一起用。

正解Apache-2.0 与 GPLv3 确实兼容(GPLv3 明确列出 Apache 为兼容协议),但与 GPLv2 不兼容——GPLv2 不承认 Apache 的专利救济与终止条款,两者法律逻辑冲突。混用时必须看清 GPL 的大版本。

为何常见:只背了“宽松可被强传染吸收”的粗规则,忽略了专利条款这个隐藏冲突点。

误区只要是 copyleft,LGPL 跟 GPL 就没区别,我的商业软件碰都不敢碰。

正解LGPL 专为库而设计,动态链接使用时不传染主程序,仅需允许用户替换和重新链接该库。只有你修改了 LGPL 库本身、或把 LGPL 静态链接进可执行文件时,库的修改版本才要求开源。类比:蘸料包可以随餐附上,但别拆开改配方再假装是自产的。

为何常见:把“copyleft 家族”整体划等号,没有区分传染的单位——整个作品、库、还是文件。

误区我开发的是 SaaS,用户只通过浏览器访问,我从不把二进制发给客户,所以 GPL 管不到我。

正解普通 GPL 确实只管“分发”,SaaS 场景不触发;但 AGPL(Affero GPL)第 13 条专门针对网络服务:只要用户通过网络与修改后的软件交互,就必须提供服务端源码。很多云厂商会用 AGPL 堵住“SaaS 逃避开源”的漏洞。

为何常见:混淆了 GPL 与 AGPL 的触发条件,只记住“分发才传染”的旧常识,没跟上网络时代的新条款。

面试题

Q1. 下列哪项是 MIT 协议明确要求的义务?

单选题 · easy

  • A.必须开源全部衍生作品
  • B.保留版权与许可声明← 正确答案
  • C.向使用者提供专利授权
  • D.禁止将代码用于商业

答案:B。MIT 的“自由”在于不要求开源衍生作品,但保留版权声明和许可文本是它的核心义务。C 是 Apache-2.0 的专利授权条款,D 完全错误——MIT 允许商用。

Q2. Apache-2.0 额外提供而 MIT 没有的“福利”是哪项?

单选题 · easy

  • A.允许用户随意修改代码
  • B.要求标注修改时间
  • C.明确的专利授权条款← 正确答案
  • D.禁止出售修改版本

答案:C。Apache-2.0 第 3 条明确授予使用者专利许可,这是它区别于 MIT 的关键。A 是两者共有权利,B 是 Apache 的“标注修改”但标注的是“修改了哪些文件”而非时间,D 与 Apache 精神相反。

Q3. Apache-2.0 组件并入 GPL-2.0 项目,结果会怎样?

单选题 · mid

  • A.完全兼容可直接使用
  • B.两协议冲突不可混用← 正确答案
  • C.项目自动降级为 MIT
  • D.必须改用 LGPL 发布

答案:B。Apache-2.0 的专利救济条款与 GPLv2 存在法理冲突,二者不兼容;只有 GPLv3 明确兼容 Apache-2.0。C、D 都是不存在的机制。

Q4. GPL 的开源义务一般在哪一时刻触发?

单选题 · mid

  • A.本地编译运行的瞬间
  • B.对外分发作品之时← 正确答案
  • C.修改源码的当天
  • D.下载进依赖的此刻

答案:B。普通 GPL 的义务在“分发(distribution)”时触发——把作品给第三方,比如销售、发布二进制。内部使用和修改本身不触发源码提供义务,这正是它与 AGPL 最大的不同。

Q5. 商业软件动态链接 LGPL 库时,以下哪个要求必须满足?

单选题 · mid

  • A.整个商业软件强制开源
  • B.允许用户替换该库版本← 正确答案
  • C.删除库的版权声明
  • D.改为静态链接方式

答案:B。LGPL 允许动态链接使用而不传染主程序,但要求用户能替换、重新链接这个库,因此你还需提供 relink 所需的目标文件或等价手段。A 是 GPL 的风格,C 违反任何协议的基本义务。

Q6. MPL-2.0 与 GPL-3.0 的最大区别是什么?

单选题 · mid

  • A.传染范围限制在文件级← 正确答案
  • B.要求全部代码都开源
  • C.必须附上专利授权
  • D.禁止再分发修改版

答案:A。MPL-2.0 是文件级 copyleft——只有被修改过的文件需要以 MPL 开源,其他文件可以闭源;GPL-3.0 要求整个衍生作品开源。C 的专利授权在两者中都存在,D 完全错误。

Q7. MIT 组件与 GPL-3.0 组件混用的项目,整体分发时应遵循哪份协议?

单选题 · hard

  • A.按 MIT 协议整体发布
  • B.按 GPL 协议整体发布← 正确答案
  • C.无需遵守任何协议
  • D.仅保留 MIT 版权声明

答案:B。MIT 是宽松许可证,允许被 GPL 吸收;两者混用后整体作品按 GPL-3.0 发布,MIT 组件的版权声明仍须保留。A 会让 GPL 组件失去许可证保障,属于违规。

Q8. 以下哪些属于宽松(permissive)许可证?

多选题 · easy

  • A.MIT 宽松协议← 正确答案
  • B.Apache-2.0 协议← 正确答案
  • C.GPL-3.0 协议
  • D.LGPL-3.0 协议

答案:AB。MIT 和 Apache-2.0 都不要求衍生作品开源,属于宽松阵营。GPL-3.0 是强传染,LGPL-3.0 是库级传染,两者都属于 copyleft 阵营。

Q9. 关于 GPL 传染边界的正确说法有哪些?

多选题 · hard

  • A.静态链接通常视为衍生作品← 正确答案
  • B.动态链接是否传染存在争议← 正确答案
  • C.调用过 API 就一定被传染
  • D.独立聚合一起发布不传染← 正确答案

答案:ABD。静态链接代码合并、边界消失,通常判定为衍生作品;动态链接因边界是否成立有争议,需要个案分析;独立聚合(mere aggregation)各自独立,不触发传染。C 把“接触”绝对化,是错误的。

Q10. 商业闭源产品要避免传染风险,哪些措施是有效的?

多选题 · hard

  • A.只选用 MIT 或 Apache 组件← 正确答案
  • B.用独立进程替换静态链接← 正确答案
  • C.修改 GPL 源码后自行编译
  • D.把 GPL 组件独立打包分发← 正确答案

答案:ABD。A 从源头避开传染性协议;B 用进程隔离划清作品边界;D 按“独立聚合”方式分发,各自独立。C 恰恰是危险操作——修改 GPL 源码并并入自己的闭源产品,会触发传染义务。