开源许可证,欢迎来到云时代

出品 | OSC开源社区(ID:oschina2013)

作者 | 唐建法

前言

开源许可证从最早的 GPL 开始, 逐渐演进到 GPLv2 和 v3,中间还有 Apache、MPL、AGPL、LGPL 等,但是近几年来有一批新的许可证的出现,引起了社区的一些激烈的讨论。这些新的许可证包括 BSL、SSPL、Elastic 以及一个比较特殊的附加条款 Commons Clause。

社区内从争论的角度主要分为两大阵营:原教旨主义和实用主义。

原教旨主义的同学们认为只有遵从1998年成立的 Open Source Initiative(OSI)定义的10大原则,通过OSI 这个组织审核认证过的(OSI-Certified),才可以称之为开源的许可证。

实用主义则从开源本身的目的出发,认为在源代码开放,绝大部分的社区开发者在使用或者贡献时不受影响的情况下,不必纠结于字面的定义如何,对社区有益即可。

按照 OSI 的开源许可证规则,目前使用 SSPL 的 MongoDB,使用 Elastic License V2 的 Elastic Search、Airbyte,使用 BSL 的 CockroachDB, 以及附加了 Common Clause 的 Redis,这些大名鼎鼎的开源软件,都不能称之为“开源软件”了。

那么问题来了?如果因为上面的原因,这些软件不被认为是开源了,是 Proprietary 软件了,难道我们真的叫这些我们已经一直在免费使用,并且可以持续使用很好的软件为“闭源软件”或者“商业软件”?好像也不太对。“源代码可用”,略微绕口了一点。

让我们先从以 SSPL 为代表的新一代开源软件厂商和 OSI 的角度分别来看一下这个问题两个对立面的一些底层逻辑。最后我们再来分享下对于云时代开源许可证的一些观点。

1、我所知道的 SSPL

MongoDB 是一个非常受程序员喜欢的的 NoSQL 数据库,我是12年左右在硅谷和朋友创业的时候接触到的。在花了一个周末改写了几千行 Python 代码,把和 MySQL 的交互改成了 MongoDB 之后,本来意图是改善并发性能的我却发现了一个意外的惊喜:代码行数缩小到了小几百行,是原来的15%——从此我就义无反顾地开始了我的 NoSQL 之路。

因为在社区比较活跃,自己也写了一个和 MongoDB 相关的开源 NodeJS 组件,所以在13年创业项目停止后我就加入了 MongoDB。在我加入的时候,MongoDB 已经成立6年了,人员规模也有300~400人,每年支出一亿美元,收入呢?当时 MongoDB 的主要营收来自于一些咨询服务和企业版的售卖。但是咨询服务收入实在是少得可怜,企业版也不太好卖,最大的竞品是自己:开源版本。所以只能一直依靠大量风投资本不断输血。可是融资已经到了F轮,投资人的耐心终于告罄。在一场董事会后,当时的 CEO 和 CRO 全体撤下,换成一个久经沙场的职业经理人 Dev Ittycheria。

Dev 上马以后立即制定了2-3年内完成上市的目标,推行了一系列新的商业化举措,包括商业化第一优先,进军全球,推出云版产品等一系列措施。我就是在那个时间,从生活工作了10多年的美国回到中国,作为 MongoDB 在大中华区的第一位正式员工来帮助 MongoDB 在中国落地商业化。在我回国的14年下半年,MongoDB 云产品 Atlas 还在研发中,MongoDB 的主要商业化手段还是企业版。

2016年的时候,MongoDB 正式发布了 Atlas 产品,一个在公有云上的托管数据库服务。MongoDB 企业版的客户是可以用百或千计的,但是开源版本的开发者可能有几十万。这些大部分开发者不会购买企业版授权,但是无论如何他们需要使用和管理维护。这个时候 Atlas 这种云产品形式就很快得到了这些开发者的青睐。虽然成本不是太低,但毕竟是开箱即用,省了0.5或者0.25个 DBA 的费用,所以MongoDB Atlas 上线后就呈现了比较快的增速,在2017年上市的时候,已经成为 MongoDB 的增长最快的业务了。

反观国内,某公有云其实也在2016年,比 MongoDB 原厂更早的时间,推出了云上的 MongoDB as a Service,还是用的 MongoDB 的基于 AGPL 的社区版。当时的中国市场,企业版的销售其实是举步维艰,企业版的售卖逻辑是提供了额外的价值,主要包括原厂技术支持和一套独立的额外集群管理工具(监控、备份等),MongoDB 数据库能力都是一样的,和开源版相比。但是在软件获取成本上,一个是0元/年,一个是数十万元/年。在10万元就能请一个工程师的中国企业市场,可想而知企业的付费意愿度有多高。

除了国内,俄罗斯的一些头部云厂商也开始在他们的云上推出了 MongoDB as a Service,也都基于免费的 MongoDB 社区版。在此过程中,云厂商为了能够更好地将一个产品融入到他们统一的云管平台,提供一些额外的能力支撑,或者自己动手解决一些产品的 Bug 来满足 SLA,势必会对源码做许多修改。在这个时候 MongoDB 发现,某些云厂商并没有完全按照 AGPL 协议规范,将所有这些改动如数开源。

云商的实际做法往往是如此,首先公开 Fork 某个 MongoDB 的上游版本,然后在这个 Fork 里面象征性地提交一些更新,推到 GitHub。实际上大量的开发会在一个 Private fork 上进行,不会推送到公开的 Fork 上面,更别说回溯到上游了。从 MongoDB 的角度,当发现这些 AGPL 协议并没有在这些云厂商得到很好的合规执行的迹象的时候,就试图从商业化上和云商进行沟通,希望对方要么是按照行业的规矩公布代码,要么就达成商业化合作。

经过多次协商,动用到各自的 Legal Team 以后,MongoDB 发现面临的问题是——商业化合作,双方期望值相差太大,一个想吃肉,一个只愿意给肉汤。开源合规方面,云商指着那个基本不怎么更新的 Repo 说我们已经按照协议开源了。只有到诉诸公堂,才可以去内部取证。怎么办?类似的案子,没有先例,再在一个完全陌生的国家去走这条路,听上去就是非常坎坷。可是云服务又几乎是所有新一代开源软件公司最主要的收入增长引擎,实在又无法听之任之。

于是 MongoDB 选择了釜底抽薪。改许可证。

在改协议之前,MongoDB 主要采用的是 AGPL 许可证。这是 OSI Certified 的,一致认可的标准开源许可证类型。为了应对在云厂商这里碰到的困难,MongoDB 在基于 AGPL 协议之上,增加了一个补充条款(解释版,非官方文字):

第13条:如果你用这个软件来直接在公有云上以“xxx as a Service" 的服务方式售卖这个软件本身,那么你需要将所有相关的改动,包括支持这个软件使用的后台管理平台软件,都进行开源。

所以,简单来说,SSPL 就等于 AGPL + 第13条修改。理解这条修改的初衷、意图、影响范围,也就理解了 SSPL 的本质。

初衷:和云厂商在商业化利益上的博弈

目的:防止这种使用开源软件直接获利,但是不遵循游戏规则的第三方

影响范围:直接提供“开源软件 as a Service”的公有云厂商

在 SSPL 正式发布以后,直接效果是很明显的:云厂商们要么是下线,要么就和原厂达成商业化合作,获取特别的授权来继续提供 MongoDB as a Service。

当然,影响也是极其深远的——对开源界造成了巨大的动荡。针对于使用 SSPL 以及后来的 Elastic License V2 这些新的许可证的软件,是否可以被称之为“开源软件”的争议一时间充斥了技术社交网络。不少极端的观点认为如果接受这样的开源方式,开源将逐渐灭亡。亦有观点认为采用这样的”quasi-开源“ 许可证肯定会引发社区极大反弹,要不了2-3年这些公司就会陨落(这些讨论集中在2018年)。


2、OSI Certified

我们再来看看 OSI, 开源软件标准的守护者。

当我们说一个软件是否可以被称之为“开源软件”时,严谨的说法应该是这个软件如果使用了某一个 OSI Certified 许可证,那么可以称之为“开源软件”。反之如果使用的许可证不在 OSI Certified 列表里,那么这个软件可能就不应该被称之为“开源软件”。

OSI Certified 许可证我们常见的有这些:

  • MIT

  • BSD

  • Apache

  • MPL

  • GPL

  • LGPL

  • AGPL

等等。

值得注意的是,这种定义更多是一个社区的自我约束,并不具有法律意义上的约束。按照 OSI 自己的说法,“开源”这个词并不是个注册商标,所以理论上谁都可以使用,你无法使用法律手段来禁止某个软件自称“开源软件”,哪怕它并没有获得 OSI 的认可。

但是,我们都是在一个生态里面。这个生态就是有各种成员组成。在这里,在法律管辖范围之外,更多的是行业的一些约定俗成和标准化组织。OSI 就是一个为鼓励促进开源软件的蓬勃发展而成立的组织。试想一下,如果没有OSI 通过严格的流程来审核许可证,界定软件的安全使用范围,提供权威的解释,那么市场上的许可证可能会是形形色色,五花八门。对于开源社区绝大多数的成员,开源软件的使用者,来说,这将是个巨大的认知和风险成本。如果你用了一个不知名的许可证,也没有请律师仔细审核,只是因为代码可以用就集成到你的产品里来,等你小有成功的那一天,没准就是你收到对方律师信的一天。

不说其他,就从这一点上看,我们需要 OSI 这样的组织,以及 OSI Certified 许可证机制。这不是限制,目的是帮助社区用户移除隐性的开源软件使用风险,为了保护开源社区更好的发展。

这也是为什么 MongoDB 在宣布了 SSPL 以后,MongoDB 的 CTO Elliot 向 OSI 提交了 SSPL 认证申请,希望 OSI 审核通过,将 SSPL 列为 Certified 许可证。(但是后来 MongoDB 很快就收回了申请,原因是 OSI 在开始正式审核流程之前,已经在社交媒体上预判了 SSPL的死刑, MongoDB 认为在这样的情况下是无法保证一个比较公平的审核过程。)

我们来看下 OSI  对现行开源许可证的认定原则。OSI 认为,一个许可证是不是开源的属性,要看它是否符合(Open Source Definition,OSD)的10条要求:

1. Free Redistribution-分发自由

2. Source Code- 可以获得源代码

3. Derived Works- 允许衍生作品(以类似的许可证)

4. Integrity of The Author's Source Code - 原作者源码的完整性

5. No Discrimination Against Persons or Groups - 不歧视个人或团体

6. No Discrimination Against Fields of Endeavor - 不歧视任何领域

7. Distribution of License - 许可的分发

8. License Must Not Be Specific to a Product - 许可不能针对特定产品

9. License Must Not Restrict Other Software - 许可证不能限制其他软件

10. License Must Be Technology-Neutral - 不能以专门的技术或界面完成授权

原文参照:https://opensource.org/osd

针对 SSPL 的批评,集中在第9条规则:许可证不能约束其他软件。而 SSPL 的条款,正是在开发者(公有云厂商)试图直接销售 MongoDB as a Service(注意是销售数据库服务本身,而不是衍生服务)的时候会触发对开发者的其他软件(云管理平台软件)的限制。

所以如果按照现有的约定俗成,SSPL/Elastic 这样的许可证,确实是不满足 OSI 的开源标准。所有 MongoDB 、 Elastic 等确实在尊重这个社区共识,不直接称呼自己为开源,而是“源码可用”。

作为一个非盈利的 MongoDB 中文社区运营方,我们最近做了一个小调查,来看看作为社区的主要成员——开发者和用户们是怎么看待这些问题的。


3、MongoDB 中文社区许可证问卷调查结果

我们的问卷在半天的时间,收集了99份有效答卷,以下是部分调研结果:

170856507a87e52a297752c7fd7e4715.png

ab1466d9556c264276c1d27582d5338d.png

e90e5a557e044943d3cded0beed89510.png

可点击链接观看完整问卷:https://mongoing.com/wp-content/uploads/2022/08/52c020886a57cf6.pdf


这里是一些摘要的数据,可以提供一些跃然纸上的观察:

  • 91%的用户支持开源软件做商业化,7%不支持,2%其他

  • 开源软件的代码贡献者仅占8%,其余的可以理解为使用者。也就是说,开源社区绝大多数是开源软件的用户

  • 关于选择开源软件,只有6%的用户表示软件的许可证模式是一个比较重要的考量

  • 多达73%的用户表示 SSPL/Elastic 针对云厂商的修改是合理并支持的,10%表示无所谓,17%反对

  • 对于开源软件用户,89% 的用户表示许可证的改变对他们继续使用软件没有影响

  • 对于开源软件的贡献者,7%的用户因为许可证改变而停止了贡献。

4、我们该如何理性看待云时代开源许可证

在经过对 SSPL 和 OSI Certified 的一些讨论以及一些对社区的调查之后,回到我们的核心问题:

在云时代,我们该如何看待这些新的开源许可证?

考虑到 MongoDB、Elastic 以及 Redis 这些软件厂商修改许可证的初衷,他们其实都是在寻找一种对抗公有云厂商不公平竞争的一种解决方案。所以我们说,这个问题是一个云时代才出现的问题。

我先罗列一些不具太多争议性的事实和观点:

  • MongoDB / Elastic / Redis 都是获得了巨大成功,非常主流的开源软件厂商

  • 这些软件的持续健康发展,无论OSI 持什么态度,依然可以服务绝大部分的开源社区用户(89%)

  • 这些厂商的开源许可证的修改都是在面临云厂商的碾压式商业竞争情况下采取的应对措施

  • 开源社区需要具有包容性,就如既定的规则里就有不歧视任何个人和团体一样

  • OSI 的开源10大规则建立于20多年前,在公有云这个跨时代形态出现之前

  • OSI 的最大的意义之一是制定标准,帮助社区用户界定不同开源许可证的边界范围

  • 追求商业化的开源软件,依然是开源社区合理的一部分

  • 社区的用户是支持开源软件商业化的(91%)

  • 我们不喜欢垄断、独断、一家独大,我们喜欢生态百花齐放,鼓励创新

在上面的这些基础观点之下,我分享一些我的看法:

1) MongoDB / Elastic / Redis 代表的是开源技术厂商,他们的特点是以一家技术创新型公司的形式,将代码开放出来,通过开源社区进行产品的传播,在为社区提供可免费获得的非常优秀的软件的同时,吸收社区的贡献和反馈,并服务于自己的商业化诉求。相比于没有商业化公司支撑的开源软件,这种 For-profit 的开源有它自己独特的优势:产品路线明确(开发者可以放心规划),技术迭代快速(有足够多非常优秀的工程师全职研发),安全问题或者重大 bug 有保障得到解决。

2)20多年前 OSI 诞生的时代,开源社区大多是以个体贡献者为主流的 Hobbist。而现在绝大部分的开源社区数量上是由开发者(使用者)而非贡献者组成。开发者对于一个名词的科学定义的感知度是相对较低的(6%的开发者关注许可证的内容),反过来优秀的性能、功能及成熟度是社区用户之首要关注点。

3)作为一个面向社区的组织,OSI 需要以发展的视角来看待新生事物。如果真心是为社区用户着想,可以做一些基于社区投票的机制,来吸纳社区的反馈,共同修订已经20多岁的规定,容纳一些有商业化考量的许可证到开源这个大家庭里。比如说,可以对开源软件从不同的维度进行分类,对有商业化诉求的许可证单独放到一个类别下,并对一些常见的合规条款进行明确的阐述和审核,帮助大家正确采用合适的开源软件。甚至可以考虑,只要软件代码开源并且可以免费获得,剩下的一些限制性条款,可以从Most Permissive 到 Most Restrictive 这样一个开放程度,分成 Level 1,2,3 这样。大家可以各自按需采用相应level的开源软件。这样才是一个真正为社区服务,而非一个“靠机构赞助运营,受非常有意见性的一些少数派影响的”的标准组织。

4)对于绝大多数用户,以及贡献者,这些云时代新的许可证的出现,你需要理解背后的初衷和意图。就像我们对技术进行科学选型的时候,我们都知道不能只听市场上的声音,最终要看是否适合自己的业务场景。如果这些许可证的改变对你的场景没有影响(一个简单的判断:你是否为公有云厂商,如果不是,大概率这些对你来说是没有变化的),你完全可以坦然接受这些新的“源码可用”许可证。

5、我们在 Tapdata 的实践

在离开 MongoDB 之后,我创立了 Tapdata.inc,并对我们公司报以很大的期望,希望我们成为一家极具使命感的公司——让企业能够更加简单、低成本使用实时的数据,来发挥更大的业务价值,Make Data on Tap。

历经3年打磨,数十家客户的线上验证,Tapdata 俨然成为了一个以全链路实时为核心技术能力栈的实时数据平台,同时也是首个支持50多个数据源的实时异构数据集成平台。

为了达成使命,我们发现降低获取 Tapdata 的成本和鼓励社区传播是这个时代最有效的一个手段。所以我们于近期正式在 Github 上开放了源代码,成立了 Tapdata 开源项目 (https://github.com/tapdata/tapdata)。

Tapdata 开源项目采用的是一个混合许可证模式。我们的策略是针对社区贡献者利用我们 Plugin Development Kit 来开发各种数据源和数据计算插件代码,采用 Apache V2 的许可证,而 Tapdata 开源团队研发的核心引擎框架,包括数据类型标准化、流计算引擎、自研的算子以及 UDF 能力等会采用 SSPL 许可证模式。

我们希望依托于 Tapdata 开源项目在实时数据领域的先发和领先优势、强大的产品能力,以及有效的商业化手段,为社区开发者和我们的客户持续不断地提供一个最优秀的数据产品。

最后我引用 Thomas Kurian,  Google Cloud CEO 对开源软件的态度,来佐证在云时代,我们需要的是一个共同发展的生态,而不是因为云厂商的非对称竞争优势导致那些 For-profit 开源软件无法生存的结局。

“我们坚信最终能够胜利的是那些提供生态而不是扼杀生态的平台(云厂商)...

... 为了能够让这些开源软件公司能够可持续地生存和发展,他们需要一个有效的商业化手段。如果云厂商利用开源协议攻击这些开源公司,让这些公司无以为继,那这最终会让开源社区变得更加糟糕”

“The most important thing is that we believe that the platforms that win in the end are those that enable rather than destroy ecosystems...

... In order to sustain the company behind the open-source technology, they need a monetization vehicle. If the cloud provider attacks them and takes that away, then they are not viable and it deteriorates the open-source community.”

原文链接:https://techcrunch.com/2019/04/09/google-clouds-new-ceo-on-gaining-customers-startups-supporting-open-source-and-more/

开源许可证,欢迎进入云时代!

关于作者:

唐建法(TJ),Tapdata 创始人 CEO,MongoDB 中文社区主席,前 MongoDB 大中华区首席架构师。

058a6dedb20f8f3351b11c0a976a4a11.jpeg

本文来源于开源精选集《开源观止》第 3 期,更多精彩内容,请点击查看↓↓↓

《开源观止》第 3 期


这里有最新开源资讯、软件更新、技术干货等内容

点这里 ↓↓↓ 记得 关注✔ 标星⭐ 哦~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/283252.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

selenium - Select类 - 下拉框

WebDriver提供了Select类来处理下拉框。 如百度搜索设置的下拉框,如下图: from selenium import webdriver from selenium.webdriver.support.select import Select from time import sleepdriver webdriver.Chrome() driver.implicitly_wait(10) drive…

.NET 7 预览版 7

点击上方蓝字关注我们(本文阅读时间:12分钟)今天我们发布了 .NET 7 预览版 7。这是 .NET 7 的最后一个预览版,下一个版本将是我们的第一个候选版本 (RC)。.NET Conf 2022 的日期已经公布!请于 2022 年 11 月…

android--------volley之网络请求和图片加载

为什么80%的码农都做不了架构师?>>> Volley是 Google 推出的 Android 异步网络请求框架和图片加载框架。 Volley的特性 封装了的异步的请求API。Volley 中大多是基于接口的设计,可配置性强。一个优雅和稳健的请求队列,一定程度符…

经典算法学习——冒泡排序

冒泡排序是我们学习的第一种排序算法。应该也算是最简单、最经常使用的排序算法了。无论怎么说。学会它是必定的。今天我们就用C语言来实现该算法。演示样例代码已经上传至:https://github.com/chenyufeng1991/BubbleSort算法描写叙述例如以下:&#xff…

Mybatis之设计模式之装饰者模式

了解,什么是装饰者模式? 1.定义 装饰模式是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。 2.特点 1 装饰对象和真实对象有相同的接口。这样客户端对象就能以和真…

一天掌握Android JNI本地编程 快速入门

一、JNI(Java Native Interface) 1、什么是JNI:JNI(Java Native Interface):java本地开发接口JNI是一个协议,这个协议用来沟通java代码和外部的本地代码(c/c) 外部的c/c代码也可以调用java代码2、为什么使用JNI:效率上…

[转]CentOS 7忘记root密码解决办法

转自:http://www.linuxidc.com/Linux/2016-08/134034.htm 亲测可用! CentOS 7 root密码的重置方式和CentOS 6完全不一样,CentOS 7与之前的版本6变化还是比较大的,以进入单用户模式修改root密码为例。 1.重启开机按esc 2.按e 3.编…

美链BEC合约漏洞技术分析

这两天币圈链圈被美链BEC智能合约的漏洞导致代币价值几乎归零的事件刷遍朋友圈。这篇文章就来分析下BEC智能合约的漏洞 <!-- more --> 漏洞攻击交易 我们先来还原下攻击交易&#xff0c;这个交易可以在这个链接查询到。我截图给大家看一下&#xff1a; 攻击者向两个账号转…

vue 公众号扫描_vue编写微信公众号打开相机功能

vue编写微信公众号打开相机功能&#xff0c;什么都不多说直接上代码页面布局代码class"previewer-demo-img":key"index":src"item.src"width"100"click"previewImg(index)">1.微信config初始化前端代码initWxConfig() {l…

SQL Server-聚焦NOT IN VS NOT EXISTS VS LEFT JOIN...IS NULL性能分析(十八)

前言 本节我们来综合比较NOT IN VS NOT EXISTS VS LEFT JOIN...IS NULL的性能&#xff0c;简短的内容&#xff0c;深入的理解&#xff0c;Always to review the basics。 NOT IN、NOT EXISTS、LEFT JOIN...IS NULL性能分析 我们首先创建测试表 USE TSQL2012 GOCREATE SCHEMA [c…

global using 的另类用法

前言global using 指令在 C# 10 中被引入&#xff0c;意味着 using 将应用于编译中的所有文件&#xff08;通常是一个项目&#xff09;。比如&#xff1a;global using System.Text;则在同一项目的其他位置&#xff0c;可以直接使用 System.Text 下的所有类型而无需再次声明 us…

利用 Node.js 实现 SAP Hana 数据库编程接口

为什么80%的码农都做不了架构师&#xff1f;>>> 自 SAP HANA SP 11 之后&#xff0c;可以使用 Node.js 作为 Hana 的编程接口。SAP 将 Application server 简称为 XS。现在 XS 已经演化为 Advanced 版本。为了区别&#xff0c;早期的 XS 被称为 XS Classical。 从下…

WPF 实现自绘验证码

WPF 实现自绘验证码控件名&#xff1a;VerifyCode作者&#xff1a;WPFDevelopersOrg原文链接&#xff1a; https://github.com/WPFDevelopersOrg/WPFDevelopers框架使用大于等于.NET40&#xff1b;Visual Studio 2022;项目使用 MIT 开源许可协议&#xff1b;如何通过DrawingV…

css中的单位换算_CSS单位px、em、rem及它们之间的换算关系

作者:WangMin格言:努力做好自己喜欢的每一件事国内的设计师大都喜欢用px&#xff0c;而国外的网站大都喜欢用em和rem&#xff0c;那么三者的区别与优势是什么&#xff1f;接下来我们就来学习一下吧&#xff01;单位px、em、rem分别表示什么&#xff1f;1、 px(Pixel) 相对于显示…

【MAC】Ncnn 编译so文件方案

【MAC】Ncnn 编译so文件方案 1、下载ncnn github地址是&#xff1a;https://github.com/Tencent/ncnn 指定目录&#xff1a;在终端或者git管理工具 输入&#xff1a;git clone https://github.com/Tencent/ncnn.git 2、编译Ncnn 2.1 Mac平台 安装cmake、wget&#xff08;根据实…

SSM学习注意杂记

2019独角兽企业重金招聘Python工程师标准>>> 1.spring导包时一定要版本对应&#xff0c;最好不要导不同版本的包&#xff0c;还有mybatis的包&#xff0c;springmvc的包&#xff0c;三个框架的包都需配套&#xff0c;要不然会出现一些想象不到的错误。 2.mybatis写映…

《ASP.NET Core 6框架揭秘》实例演示[15]:针对控制台的日志输出

针对控制台的ILogger实现类型为ConsoleLogger&#xff0c;对应的ILoggerProvider实现类型为ConsoleLoggerProvider&#xff0c;这两个类型都定义在 NuGet包“Microsoft.Extensions.Logging.Console”中。ConsoleLogger要将一条日志输出到控制台上&#xff0c;首选要解决的是格式…

《HeadFirst Python》第一章学习笔记

对于Python初学者来说&#xff0c;舍得强烈推荐从《HeadFirst Python》开始读起&#xff0c;这本书当真做到了深入浅出&#xff0c;HeadFirst系列&#xff0c;本身亦是品质的保证。这本书舍得已在《Python起步&#xff1a;写给零编程基础的童鞋》一文中提供了下载。为了方便大家…

Oracle-13:Oracle中的表分区

------------吾亦无他,唯手熟尔&#xff0c;谦卑若愚&#xff0c;好学若饥------------- 本篇博客记录了表分区 表分区的含义&#xff1a; 典型的拿空间换时间的案例&#xff01; 表分区对一张表进行分区&#xff0c;分区之后表中的数据存在相对应的分区内&#xff08;可以是不…

js控制图像等比例缩放

<!DOCTYPE html> <html> <head><title>图片内部放大效果</title> <meta charset"utf-8"> <style type"text/css">#imgborder{ width: 200px;height: 160px;border: 3px solid #000; overflow: hidden;position:…