python 正则表达式

>>>input = '自然语言处理很重要, 123abc456' >>>import re >>>pattern = re.compile('.') >>>re.findall(pattern,input) ['自', '然', '语', '言', '处', '理', '很', '重', '要', ',', ' ', '1', '2', '3', 'a', 'b', 'c', '4', '5', '6'] >>>pattern = re.compile(r'[abc]') >>>re.findall(pattern,input) ['a', 'b', 'c'] >>>pattern = re.compile(r'[a-zA-Z]') >>>re.findall(pattern,input) ['a', 'b', 'c'] >>>pattern = re.compile(r'[^abc]') >>>re.findall(pattern,input) ['自', '然', '语', '言', '处', '理', '很', '重', '要', ',', ' ', '1', '2', '3', '4', '5', '6'] >>>pattern = re.

[Spring] Spring Web MVC案例实战

🌸个人主页:https://blog.csdn.net/2301_80050796?spm=1000.2115.3001.5343 🏵️热门专栏: 🧊 Java基本语法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm=1001.2014.3001.5482 🍕 Collection与数据结构 (92平均质量分)https://blog.csdn.net/2301_80050796/category_12621348.html?spm=1001.2014.3001.5482 🧀Java EE(96平均质量分) https://blog.csdn.net/2301_80050796/category_12643370.html?spm=1001.2014.3001.5482 🍭MySql数据库(93平均质量分)https://blog.csdn.net/2301_80050796/category_12629890.html?spm=1001.2014.3001.5482 🍬算法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12676091.html?spm=1001.2014.3001.5482 🍃 Spring(97平均质量分)https://blog.csdn.net/2301_80050796/category_12724152.html?spm=1001.2014.3001.5482 感谢点赞与关注~~~ 目录 1. 加法计算器1.1 约定前后端交互的接口(接口文档)1.2 前端代码1.3 后端代码 2. 用户登录2.1 接口文档2.2 前端代码2.2.1 登录页面2.2.2 首页 2.3 后端代码2.3.1 登录页面2.3.2 主页 3. 留言板3.1 接口文档3.2 前端代码3.3 后端代码3.3.1 lombok介绍 4. 图书管理系统4.1 接口文档4.2 前端代码4.3 后端代码 5. 应用分层4.1 介绍4.2 具体在项目中的体现 1. 加法计算器 需求:输入两个整数,点击"点击相加"按钮,显示计算结果. 1.1 约定前后端交互的接口(接口文档) 这是Web开发中的关键一环.接口又叫API,我们一般讲到的API或者接口,指的都是同一个东西.如今我们的开发一般采用前后端分离的方式,所以我们在开发之前,前端开发人员和后端开发人员会约定好前后端交互的方式.我们一般会把约定的内容写在文档上,就是"接口文档".接口文档可以理解为是应用程序中的"操作说明书". 在项目开发之前.我们需要先更具需求拟写接口文档,前后端必须都准寻接口文档中的标准.**接口文档通常由服务提供方来写,有服务使用方确认,也就是客户端.**关于接口文档怎么写,每个公司有不同的标准,一般是需求分析和接口定义(接口名称,URL),传递参数,返回参数下面我们来拟写这个案例的简单接口文档: 需求分析: 输入两个整数,点击"点击相加"按钮,显示计算结果. 接口定义: 请求路径:calc/sum, 请求方式:GET/POST, 接口描述:计算两个整数相加 请求参数: 参数名类型是否必须备注num1Integer是参与计算的第⼀个数num2Integer是参与计算的第⼆个数响应数据: Content-Type: text/html 响应内容:计算机计算的结果 1.2 前端代码 首先,我们需要准备前端的代码.把前端的代码calc.html放在项目的Static目录中. <!DOCTYPE html> <html lang="

Laravel数据库的魔法棒:深入探索数据库迁移(Migrations)

Laravel数据库的魔法棒:深入探索数据库迁移(Migrations) 在Laravel的世界中,数据库迁移(Migrations)是一种强大的工具,它允许开发者以版本控制的方式管理数据库结构的变化。通过迁移,你可以轻松地创建、修改或删除数据库表,同时保持代码的整洁和一致性。本文将带你深入了解Laravel数据库迁移的概念、作用以及如何使用它们,并通过实际的代码示例,让你对Laravel迁移有更直观的认识。 什么是Laravel数据库迁移? Laravel数据库迁移是一种文件,用于描述数据库表的创建、修改或删除。每个迁移文件都包含了两个方法:up()和down()。up()方法定义了如何应用迁移,而down()方法则定义了如何撤销迁移。这使得数据库结构的版本控制成为可能。 为什么使用数据库迁移? 版本控制:迁移文件可以与代码一起进行版本控制,使得团队协作更加方便。可重复性:迁移可以被重复运行,确保在不同环境或数据库中应用相同的数据库结构。可逆性:迁移可以被撤销,使得数据库结构的修改更加安全。自动化:Laravel提供了命令行工具来自动化迁移的运行和管理。 如何创建数据库迁移? 在Laravel中,创建迁移非常简单。首先,确保你已经安装了Laravel,并创建了一个项目。然后,使用以下命令创建一个新的迁移文件: php artisan make:migration create_users_table 这将在database/migrations目录下创建一个新的迁移文件,文件名包含时间戳,以确保迁移的顺序。 编写迁移代码 打开创建的迁移文件,你将看到以下结构: use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; class CreateUsersTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('users', function (Blueprint $table) { $table->id(); $table->string('name'); $table->string('email')->unique(); $table->timestamp('email_verified_at')->nullable(); $table->string('password'); $table->rememberToken(); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('users'); } } 在这个示例中,我们创建了一个名为users的表,并定义了一些字段。up()方法用于创建表,而down()方法用于删除表。

技术速递|Let’s Learn .NET Aspire – 开始您的云原生之旅!

作者:James Montemagno 排版:Alan Wang Let’s Learn .NET 是我们全球性的直播学习活动。在过去 3 年里,来自世界各地的开发人员与团队成员一起学习最新的 .NET 技术,并参加现场研讨会学习如何使用它!最重要的是,Let’s Learn .NET 活动在全球各地以当地时区和语言举办。 我们将开始本系列的下一篇,“Let’s Learn .NET Aspire”,您将在其中了解使用 .NET 构建可观察、生产就绪、分布式应用程序的全新云就绪技术栈。更棒的是,您将学习如何将 .NET Aspire 集成到您现有的 .NET 应用程序中,并了解它如何通过可观察性为您提供更好的洞察力、通过编排进行更好的管理以及如何随着应用程序的增长轻松集成新组件。 我们为这场 2 小时的活动提供了全套的服务,为您提供开始 .NET Aspire 之旅所需的一切。 参加研讨会 您要做的第一件事就是参加我们的完整样例并将样例从 GitHub 克隆到您的本地开发机器。这个 repo 将为您提供所需的一切,包括研讨会的开始和结束项目、每个步骤的研讨会指南以及您可以随时查看的完整演示文稿。 这是一个全新的样例,您将使用 Blazor 前端构建一个天气浏览器,并与美国国家气象局的实时天气数据进行交互。 设置您的开发机器 本次研讨会将使用以下工具: .NET 8 SDK .NET Aspire 工作组件 Docker Desktop 或 Podman Visual Studio 2022 或带有 C# DevKit 的 Visual Studio Code 为了获得最佳体验,我们建议将 Visual Studio 2022 与 .NET Aspire 工作组件一起使用。但是,您也可以将带有 C# Dev Kit 的Visual Studio Code 和 .

信创学习笔记(四),信创之数据库DB思维导图

创作不易 只因热爱!! 热衷分享,一起成长! “你的鼓励就是我努力付出的动力” 一. 信创学习回顾 1.信创内容 信创内容思维导图 2.信创之CPU芯片架构 信创之CPU芯片架构思维导图 3.信创之操作系统OS 信创之操作系统OS思维导图 二. 信创之国产数据库DB思维导图 用一张图学习信创之国产数据库 阿里云,开源+商业 分布式shared-nothing, 节点并行shared-disk 南大通用 , 分布式shared-nothing 蚂蚁集团,开源+商业,C++ tpmC事务强,分布式shared-nothing 达梦数据,C语言 分布式,tpmC事务超强 PingCAP,开源+商业,Go语言 分布式shared-nothing openGauss社区,完全开源, C++,Java,C多语言, 传统主备数据库,tpmC事务超强 shared-everything 北京人大金仓, 分布式 华为云, 分布式 金篆信科, 分布式 腾讯云,开源+商业 tpmC事务强,分布式shared-nothing PolarDB 自研 HTAP 融合事务与分析 GBASE 起源于IBM的Informix OLTP 主增删改, 业务高吞吐低延迟 事务的ACID OLAP 主查询分析, 数据决策 分布式并行查询 OceanBase 达梦数据库 TiDB 起源于RocksDB openGauss 起源于 PostgreSQL 人大金仓KingBase GaussDB GoldenDB 起源于 Mysql TDSQL 数据库排行可以直接参考 墨天轮数据社区[https://www.modb.pro/dbRank] 不正确的地方欢迎指出!感谢!

最大电子书平台Z-Library

前段时间,号称“全球最大的数字图书馆”Z-Library网站的多个域名遭美国政府查封。与此同时,法国、印度等国家也官方下达了封禁指令,将Z-Library从当地搜索引擎的结果列表中移除。该事件一出也引发中文互联网世界哗然,网友戏称“道理都懂”,但还是忍不住为这场“亚历山大图书馆的焚烧”哀叹,也有保留意见称,该事件或许仍有转机。 Z-Library原先网站截图。该网站在下方介绍中自称为“全球最大的数字图书馆”。 然而,据美国司法部最新消息,该网站的两名创始人已在阿根廷被捕,并面临“侵犯版权、电汇欺诈及洗钱罪”等多项指控,目前案件仍在审理当中。实际上,在过去二十年左右的时间中,曾相继出现了一系列“影子图书馆”(Shadow Library,通常指收集了大量享有著作权的书籍,并向公众免费开放的网站,“影子”也意味着其可能处于不合法的灰色地带)——Gigapedia、Kolkhoz、Librusec,以及最近的Lib.gen和Sci-Hub,它们多次面临解散或关闭的结局,但又一次次借由新的域名重启。如果这背后当真是黑白分明的版权之争,为何被贴上“数字盗版”标签的这些网站,会在舆论场上一再获得声援? 在过去的一个月,Z-Library遭遇封站后,国外社交媒体上也在持续进行着一场围绕“数字版权与知识开放”的大讨论。一边是价格连年高走的资源付费让读者叫苦不迭,另一边是坚持“版权至上”的出版公司不断发起维权围剿,这些同今年四月“中国知网”引发的风波遥相呼应。值得注意的是,在这一轮交锋中,越来越多的创作者从幕后走到台前,这一次,他们中有不少人站在了宣称“保护其权益”的出版商对面,质疑现有的“版权结构”对作者本人的伤害远超因“盗版”而失去的利润。这些声音再度引发人们思考,“版权”在实际运作中究竟保护的是谁的权益。 当我们梳理相关争议会发现,围绕Z-Library的关停风波中,人们在面对盗版伦理的相关问题时,同时也在与现有合法的出版模式辩论,后者提供给原作者或投稿人的报酬多数时候十分有限。由此引出的更深的问题在于,知识作为一种可以被精确地无限复制的资源,是否应该受到“绝对所有权”的限制?在当前全球对开放获取运动的支持呼声持续高涨的背景下,法院对Z-Library一案的最终裁定,或将成为一个具有风向标意义的分水岭事件。 撰文|申璐 铁打的网站,流水的域名: “影子图书馆”的缘起与自我复制 “这注定是一场无法取胜的版权战争。”美国月刊《理性》(Reason)杂志认为,根除以Z-Library为代表的这类数字图书馆几乎是不可能的,只要人们需要免费信息,现代科技和数字生态系统就会提供,最终这一系列行动将以耗时耗力的高昂代价收场。 尽管Z-Library最近一次公布的数据显示,截至2022年6月12日,该网站收录了超1045万本书籍和8483万篇文章,自称“全球最大的数字图书馆”,但这一颇为惊人的馆藏却是短短十余年间快速积累的结果。早在2009年,Z-Library最初作为另一家知名电子书分享平台Lib.Genesis(创世纪图书馆)的镜像版出现,与Sci-Hub并称全球知名的三大在线数据库。它们彼此之间形成资源共享,服务器分布在全球多个地区。据创建Sci-Hub的哈萨克斯坦神经科学家亚历山德拉·埃尔巴金 (Alexandra Elbakyan)称,当有人请求一篇文章时,系统会首先检索Lib.Gen数据库。但如果文章不在那里,系统就会使用捐赠的密码登录期刊网站,下载文章,并将其同时提供给请求它的用户和主数据库。 这样的互联结构可以最大限度地减少备份数据的空间,同时在包含相关数据库的磁盘丢失的情况下,依然能够继续运作。一旦某个域名遭到封禁,一些用户也能够快速罗织一个未被阻止的链接列表,进而通过另一条数字路径将其带到被禁止的网站。这些层出不穷的镜像网址就像是神话中的“九头蛇”,即便官方能够查封其某个分部,它们也能通过建立新的域名快速重建馆藏。 Sci-Hub界面。关于“开放知识”的更多讨论,详见论文免费共享的“开放知识”,与我们有多远距离? 值得注意的是,包括Lib.Gen和Sci-Hub在内,今天的许多影子图书馆几乎最初都是在俄语环境中开展业务。最早的影子图书馆之一lib.ru是由一位俄罗斯学者创建,在过去二十年左右,互联网世界相继出现了一系列“图书馆”——Gigapedia、Kolkhoz、Librusec等,这些馆藏文本也以俄语为主,后来才逐渐发展为包含其他语种的资源库。而“开放”的传统来源于“限制”,阿姆斯特丹大学的盗版研究人员巴拉兹-博多(Balázs Bodó)认为,松散的版权法、薄弱的知识产权保护规则,这些都使得影子图书馆得已在俄罗斯存在并蓬勃发展。更何况,当地还有着世界上最早一批台式机和数据库。 20世纪90年代之前,苏联大中城市68%以上的家庭会在黑市购买书籍,当地学者也常年通过地下出版物规避政府审查。即便在1991年苏联解体后,审查制度正式结束,但国家对出版业的资助也随之结束,此前的政治限制被经济限制取代,大规模失业、工资下降以及由此导致的可自由支配收入的减少进一步削弱了向以市场为基础的出版模式的转变。与此同时,俄罗斯本土的版权保护一直比其他地方更为宽松,在签署《世界版权公约》前,作者去世后15年,其作品就可在俄“免费”使用。 这些都为影子图书馆的不断重启蒙上了一层“利他主义”的光晕,它自诞生之初就被视为官方图书文化和出版商业模式的对面,假使抛开其对个人信息安全构成的潜在风险不谈,它的确免费、自下而上且不受审查制约。博多在其另一篇发表于2020年的研究中,对“影子图书馆”的访问记录作了“供给侧分析”,发现很大一部分下载集中在合法但无法访问的作品上,“黑市的出现,无论是文化、毒品还是武器,始终是一种症状,是供需摩擦的警告信号”。当合法可用的东西与需求的东西之间存在重大差异时,“文化黑市”将在这里与既定和公认的“文化中介”竞争,并超越竞争。在这种持续存在的生存威胁下,商业模式和机构面对“铁打的营盘,流水的兵”,也不得不亦步亦趋地适应,或是主动进化或是被动出局。 纪录片《书缘》(2017)剧照。 “别以你的名字呼唤我”: 学术界与创作者的质疑声音 早在Z-Library关停风波前,影子图书馆就已经成为大型出版商及期刊的眼中钉。2015 年,美国最大的学术出版商之一爱思唯尔(Elsevier)上诉法庭,试图关闭其中两家最受欢迎的图书馆Sci-Hub和Lib.Gen。2017年,美国纽约地方法院裁定Sci-Hub违反美国版权法,判给爱思唯尔1500万美元的赔偿金。2020年,爱思唯尔、美国化学学会(ACS)联合美国出版商威利(Wiley)在德里高等法院再次对Sci-Hub提起诉讼,并将其创建者埃尔巴金一并列为被告。在发起的连番声讨中,他们坚称影子图书馆不仅给出版商造成经济损失,也危及那些图书作者与科研人员的利益。 然而,这一说法并未赢得一致支持,至少来自学界的反对声音由来已久。2015年,包括前文提到的盗版研究员博多在内,多位学界人士曾联名签署公开信支持影子图书馆,他们在信中直言,上述诉讼案件实则对研究人员而言是“一个沉重的打击”。以爱思唯尔为例,其每年37%的利润率与不断上涨的学费、扩大的学生贷款债务以及兼职教师的微薄的工资形成鲜明对比。爱思唯尔拥有一些最大的学术资料数据库,这些资料的授权价格却高得离谱,以至于即使是全球北方最富有的大学哈佛大学也曾抱怨“负担不起”。 哈佛图书馆前任馆长罗伯特·达恩顿 (Robert Darnton) 称:“我们的教师做研究,写论文,为其他研究人员的论文做评议,在编辑委员会任职,所有这些都是免费的……然后,我们却要以离谱的价格买回我们的劳动成果。”如果取消“捆绑”订阅,一篇期刊文章的平均成本一般在30美元左右。此外,仅阅读摘要部分可能很难知道该研究是否相关。这就迫使学者和学生在知道他们是否真的需要阅读这篇论文之前,先掏钱。期刊文章的定价使得世界各地的许多学者——以及所有非学者——难以进入其中,从而使其成为特权的象征。 面对这一局面,20世纪90年代初,学界也曾兴起一波“开放获取”(Open Access)的浪潮。支持者的诉求很简单,因为制作数字副本的成本几乎为零,他们呼吁学术文章免费开放,如今使用率颇高的维基百科就是这一构想的实践尝试。而在开放获取运动约两年后,美国的几所大学纷纷威胁要取消对学术期刊的订阅,以抗议过高定价。 不过,这一浪潮至今也没能将影子图书馆带到阳光之下。《纽约时报》的一篇评论没有避讳其中的复杂性。一方面,校方的威胁反而导致出版商重新设计商业模式,最后推出了所谓的“作者付费”,这意味着作者必须向期刊支付在线发表文章的费用。另一方面,开放获取的真正障碍其实来自学界内部。在现有的考评机制下,学者想要在竞争教席、晋升、终身教职和资助金申请中获得优势,其所处的环境会根据他们发表的文章来评判。那些享有盛名的期刊,如《细胞》《自然》和《柳叶刀》等,也往往对其内容保护得最好,而高校也倾向于通过其在这些期刊发表文章的数量标榜学术实力,“真正的罪魁祸首是科学界的领导人——诺贝尔科学家、机构负责人、大学校长——他们有能力改变现状,但从未正视这个问题,部分原因在于,他们也构成了系统本身”。 对于那些游离于大学的研究者而言,影子图书馆显得更为珍稀。印度法学者高塔姆·巴蒂亚(Gautam Bhatia)甚至在其2019年的作品《变革性宪法》(暂译,The Transformative Constitution)中引用了影子图书馆。他坦言如果没有Lib.Gen,也就不会有这本书的面世,“在大学的封闭区域之外做学术,就像尝试仅凭一只胳膊和一条腿游泳”。 相较于学界研究者而言,图书作者此前对影子图书馆的抵制情绪相对一致,毕竟作者依靠的并非同行评议和引用,而是不断上升的销售数据来供给创作的物质养分,同时凭借这个数据争取更多的出版机会。不过值得注意的是,近年来不少图书作者也纷纷表态,对关停影子图书馆持保留意见。出版《变革性宪法》的巴蒂亚同时也是位科幻小说家,他的小说《墙》(暂译,The Wall)此前可以在Z-Library下载,对此,他调侃说:“我对那些下载电子图书的人没有任何评判,因为你知道,他们毕竟是要花钱的。” 另一部分反对关停影子图书馆的创作者实则出于权衡利弊。美国自由撰稿人艾莉森·鲁米特(Alison Rumitt)认为,虽然该网站的存在令她损失了一部分收入,但相比于切断作品的访问渠道以及美方因此逮捕个人而言,所谓的“解决方案”远比问题本身更糟糕。她承认自己也会访问影子图书馆下载那些已经绝版的作品。对于试图在资本主义机器中谋生的作家而言,单本书售出后分得的利润太过有限,现有的“版权结构”对作者本人的伤害可能远超因“盗版”而失去的利润。鲁米特称,与其以保护作者之名讨伐影子图书馆,不如先保证作者能够得到更加公平的待遇,“这很可能是目前唯一的解决办法”。 纪录片《书缘》(2017)剧照。 围绕“版权”的争议: 数字盗版?不合理垄断? 尽管反对关停Z-Library的声音四起,但影子图书馆本身的确长期存在争议。来自美国知识产权注册处的贾斯丁·斯宾塞(Justin Spence)称,以Sci-Hub为代表的影子图书馆是在宣扬“盗版”的正当性,它传递了一个错误的观念,即“任何知识都应该是免费的”,然而学术生产与交流的动力其实十分复杂,这套“利他主义”的构想模糊了其中的成本。斯宾塞承认每个人都能以合理的价格获得知识成果本身十分重要,但不应该将其推到极致,以至于为了实现这一目标,所有手段都可以接受。 那么,影子图书馆究竟是否涉及“盗版”侵权?在《影子图书馆:侵犯版权还是公共利益?》一文中,卡维亚·贾(Kavya Jha)对比了2016年发生在印度的“德里大学复印案”。牛津大学出版社曾联合多家机构起诉德里校内复印店侵犯其版权,被告辩解称,影印资料被用于教学参考,只有一小部分书籍被复制,并未影响原告书籍市场。最终,法院判定被告胜诉,依据是“在出于教育目的正当合理的范围内,使用受版权保护的作品属于合理使用”。不过,稍有不同的是,在Z-Library为代表的案件中,影子图书馆无法证明其提供的材料并未用于商业研究。 《影子图书馆》(Joe Karaganis著),该书研究和比较世界各地知识分享的方式和现状。 与此同时,影子图书馆涉及的另一个问题是“营利”判定。卡维亚·贾指出,大多数盗版网站的目的不是提供免费内容,而是赚钱。然而,影子图书馆并非以营利为目的运作。为反驳这一点,出版方声称这些网站曾接受过高额捐款,这足以显示其营利动机。但是否能够将商业动机等同于接受捐赠其实也有待商榷,更何况,其中并非所有资源都受到版权保护。 而在“盗版”界定之争以外,影子图书馆仍在一次次重启,这之中的症结其实在于资源的可及性,或者说知识本身的阶级性。正如前文统计,在影子图书馆的使用记录中,很大一部分下载集中在那些合法但无法访问的作品上。这种“无法访问”部分出于资源的不均衡,偏远地区“很难在当地书店买到需要的书籍,即便能远程买到,也需要等几个月才能收到”,又或者是“绝版资料”。同时,迈阿密大学法学院知识产权教授维维克·贾亚拉姆(Vivek Jayaram)指出,过高的准入价格也引起质疑——“信息不应仅限于那些有足够特权的人才能负担得起”。 相关争论也逐渐上升为对“版权”本身的质疑。美国自由主义律师斯蒂芬·金塞拉(Stephan Kinsella)甚至直言,版权是政府立法授予的不合理垄断。不同于具有竞争性和排他性的“稀缺实物”,文字或思想可以被精确地无限复制,应该属于公共物品范畴。更何况,大部分时候“版权”所维护的也并非创作者的利益,而是将出版商变成了他人“财产”的部分所有者。2021年,总部位于荷兰的爱思唯尔的出版部门报告利润约为11亿美元,收入为30亿美元。而据中国知网的财报显示,其2021年净利润1.94亿元,毛利率高达53.35%,这一数据自2005以来最高时一度达到72%,而这之中作者本人分得的收益微乎其微。 另外《理性》杂志评论则称,从功利主义角度看,版权的规定原是为了“促进科学和实用艺术的进步”,但实际上关闭“影子图书馆”弊大于利,因为后者在很大程度上促进了研究。正如《柳叶刀》在2016年的一封公开信所言,此类网站可能对秘鲁等地的医生大有裨益,那里很少有医生能够访问“他们需要的文件和信息,以照顾越来越多病情多样的患者”。而在新冠大流行期间,此类论点变得更加有力。 这些都使得Z-Library一案的最终裁定备受关注。正如卡维亚·贾所言,在当前全球对开放获取运动的支持呼声持续高涨的背景下,法院每一次对此类案件的判定都可能成为一个具有风向标意义的分水岭事件。回到“德里影印案”,法院判决中的阐释或许至今仍然值得思考:“版权,特别是文字作品的版权,并非一种不可避免的、神圣的或自然的权利、赋予作者对其创作的绝对所有权……版权的目的是促进而不是阻碍知识的获取。它的目的是激励作者和发明者的创造性活动,最终,以造福公众。” 参考链接: 1. Z-Library shutdown leaves users scrambling to find alternatives https://huntnewsnu.com/69818/lifestyle/z-library-shutdown-leaves-users-scrambling-to-find-alternatives/ 2. Z-library banned, students in a frenzy

Spark学习之SparkSQL

SparkSQL 1、SparkSql初识案例 :WordCount spark sql处理数据的步骤1、读取数据源2、将读取到的DF注册成一个临时视图3、使用sparkSession的sql函数,编写sql语句操作临时视图,返回的依旧是一个DataFrame4、将结果写出到hdfs上 import org.apache.spark.SparkContext import org.apache.spark.sql.{DataFrame, Dataset, Row, SaveMode, SparkSession} object Demo1WordCount { def main(args: Array[String]): Unit = { //创建编写spark sql的环境 val sparkSession: SparkSession = SparkSession /** * 用于创建或配置 SparkSession 实例的一个构建器(Builder)模式的应用 * 使用 SparkSession.builder(),你可以链式地设置各种配置选项, * 并最终通过调用 .getOrCreate() 方法来获取一个 SparkSession 实例。 */ .builder() // 执行模式:本地执行 .master("local") // 名称 .appName("sql语法风格编写WordCount") // 获取SparkSession.builder()创建的 SparkSession 实例 .getOrCreate() /** * spark sql是spark core的上层api,如果要想使用rdd的编程 * 可以直接通过sparkSession获取SparkContext对象 */ val context: SparkContext = sparkSession.sparkContext //spark sql的核心数据类型是DataFrame(注意与RDD的区别) val df1: DataFrame = sparkSession.

【Redis】集群

文章目录 一、集群是什么?二、 Redis集群分布式存储为什么redis集群的最大槽数是16384(不太懂)redis的集群主节点数量基本不可能超过1000个 三、 配置集群(三主三从)3.1 配置config文件3.2 启动六台redis3.2 通过redis-cli命令为6台机器构建集群关系3.3 任意连接一个作为切入点(集群只需要连一个),并检验集群状态 四、 扩展 以下是本篇文章正文内容 一、集群是什么? 由于数据量过大,单个Master复制集难以承担,因此需要对多个复制集进行集群,形成水平扩展每个复制集只负责存储整个数据集的一部分,这就是Redis的集群,其作用是提供在多个Redis节点间共享数据的程序集。 Redis集群是一个提供在多个Redis节点间共享数据的程序集 Redis集群可以支持多个Master Redis集群支持多个Master,每个Master又可以挂载多个Slave读写分离支持海量数据的高可用支持海量数据的读写存储操作由于Cluster自带Sentinel的故障转移机制,内置了高可用的支持,无需再去使用哨兵功能客户端和Redis的节点连接,不再需要连接集群中所有节点,只需连接集群中的任意一个可用节点即可槽位slot负责分配到各个物理服务节点,由对应的集群来负责维护节点、插槽和数据之间的关系redis集群不保证强一致性,这意味着在特定的条件下,Redis集群可能会丢掉一些被系统收到的写入请求命令 二、 Redis集群分布式存储 槽位 集群的密钥空间被分成16384个槽,有效地设置了16384个主节点的集群大小上限(但是,建议的最大节点大小约为1000个节点)。 Redis集群投有使用一致性hash,而是引入了哈希槽的概念. Redis集群有16384个哈希槽,每个key通过CRC16校验后对16384取模来决定放置哪个槽。 集群的每个节点(master)负责一部分hash槽。 比如,有一个集群有三个节点: 分片 使用Redis集群时我们会将存储的数据分散到多台redis机器上,这称为分片。简言之,集群中的每个Redis实例都被认为是整个数据的一个分片。 如何找到给定key的分片:为了找到给定key的分片,我们对key进行CRC16(key)算法处理并通过对总分片数量取模。然后,使用确定性哈希函数,这意味着给定的key将多次始终映射到同一个分片,我们可以推断将来读取特定key的位置。 Redis集群分布式存储有大概有3种解决方法 哈希取余分区 hash(key) % N个机器台数,计算出哈希值,用来决定数据映射到哪一个节点上。 优点: 简单粗暴,直接有效,只需要预估好数据规划节点例如3台、8台、10台,就能保证一段时间的数据支撑。使用Hash算法让固定的一部分请求落到同一台服务器上,这样每台服务器固定处理一部分请求(并维护这些请求的信息),起到负载均衡+分而治之的作用。 缺点: 直接规划好节点,进行扩容或者缩容会很麻烦,不管扩还是缩,每次数据变动会导致节点有变动,映射关系都要重新计算,在服务器个数固定不变时没有问题。如果需要弹性扩容或故障停机的情况下,原来的取模公式就会发生变化,Hash(key)/3会变成Hash(key) /?。此时地址经过取余运算的结果将发生很大变化,根据公式获取的服务器也会变得不可控。 一致性哈希算法分区 为了解决分布式缓存数据变动和映射问题,某个机器宕机了,分母数量改变了,自然取余数不行了。 目的是当服务器个数发生变动时,尽量减少影响客户端到服务器的映射关系 算法步骤: 哈希槽分区 哈希槽实质就是一个数组,数组[0,2^14 -1]形成hash slot空间。 解决均匀分配的问题,在数据和节点之间又加入了一层,把这层称为哈希槽(slot),用于管理数据和节点之间的关系(即解决映射问题),现在就相当于节点上放的是槽,槽里放的是数据。 一个集群只能有16384个槽,编号0-16383(0-2^14-1)。这些槽会分配给集群中的所有主节点,分配策略没有要求。 接下来就需要对key求哈希值,然后对16384取模,余数是几key就落入对应的槽里。集群会记录节点和槽的对应关系。 HASH_SLOT = CRC16(key) mod 16384。 以槽为单位移动数据,因为槽的数目是固定的,处理起来比较容易,这样数据移动问题就解决了。 写入的总体流程:当需要在 Redis 集群中放置一个 key-value时,redis先对key使用crc16算法算出一个结果然后用结果对16384求余数[ CRC16(key) % 16384],这样每个 key 都会对应一个编号在 0-16383 之间的哈希槽,也就是映射到某个节点上。 为什么redis集群的最大槽数是16384(不太懂) Redis集群并没有使用一致性hash而是引入了哈希槽的概念。Redis 集群有16384个哈希槽,每个key通过CRC16校验后对16384取模来决定放置哪个槽,集群的每个节点负责一部分hash槽。

“初探Java:新手指南与实践之旅“

前言 这次将开启我的Java编程的学习之旅!在这个旅程中,我将会探索Java的世界——一种强大、灵活且广泛使用的编程语言。Java自1995年诞生以来,已经成为软件开发领域的中流砥柱,它的跨平台兼容性和“一次编写,到处运行”的理念使其成为企业和开发者们的首选。Java不仅是一种语言,更是一个充满活力的社区,拥有丰富的资源和支持。随着你的进步,你会发现自己能够构建从简单的控制台应用到复杂的企业级系统的一切。 学习编程是一场马拉松,而不是短跑。遇到难题时不要气馁,因为每一个挑战都是成长的机会。保持好奇心,享受每一次“啊哈!”时刻。 目录 1.Java是什么 2.Java的应用领域及重要性 3.Java语言的特点 4.Java开发环境搭建 5.Java学习的必备方式 一:Java是什么 Java是一种优秀的程序设计语言,它具有令人赏心悦目的语法和易于理解的语义。 不仅如此,Java还是一个有一系列计算机软件和规范形成的技术体系,这个技术体系提供了完整的用于软件开发和跨平台部署的支持环境,并广泛应用于嵌入式系统、移动终端、企业服务器、大型机等各种场合。 二:Java的应用领域及重要性 工作领域 Java语言目前在IT领域的应用是非常广泛的,掌握Java语言可以从事不少IT行业的相关开发岗位,具体包括: 企业级系统 比如大型复杂的企业级软件系统,Java的安全机制以及跨平台性的优势,其在分布式系统领域开发中有广泛应用,涉及到金融、电信、交通、电子商务、ERP系统等。 Web开发领域 Java语言在设计初期,赶上了互联网发展的风口,当时就瞄准了互联网开发,凭借稳定的性能表现和较好的扩展性,Java语言一直是大型互联网平台的重要解决方案。 android平台应用 Android是一种智能手机操作系统,Java是一门非常流行的编程语言。Android上的应用程序就是大多是用Java编写的,Android的SDK大部分就是直接将Java SDK翻译过来的,所以具有Java基础,也可以快速上手Android开发。 大数据平台开发 大数据相关的各类框架,比如:Hadoop、spark、storm、flink等,以及各种中间件flume、kafka、sqoop等,这些框架以及工具等大多数是用Java语言开发的,随着大数据技术的落地应用,Java在大数据领域的应用前景也是比较广阔的。 除上述开发领域外,Java在游戏领域、人工智能领域、科学计算领域、嵌入式领域也有一定的应用。因此学好Java,将来就业的选择也会非常广泛。 2. 在校招中的岗位需求 从上述位置需求中可以看出,由于应届生缺少实际工作经验,因此校招中企业更看重学生的基础,也就是:语言、数据结构/算法、操作系统、网络、数据库等,其他的属于加分项。 3. 语言广泛使用程度 下图数据来自于TIOBE编程语言社区2024年7月最新的排行榜,常年占据语言排行榜前四,是近些年最火的编程语言之一。 TIOBE 编程语言社区排行榜是编程语言流行趋势的一个指标,每月更新,这份排行榜排名基于互联网上有经验的程序员、 课程和第三方厂商的数量。排名使用著名的搜索引擎(诸如 Google、MSN、Yahoo!、Wikipedia、YouTube 以及 Baidu 等)进行计算。 三:Java语言的特点 以下Java语言特性来自于Java白皮书: 1. 简单性 Java语法是C++语法的一个“纯净版本”,相当于对C++做了一个减法。这里没有头文件、指针运算(甚至指针语法)、结构、联合、操作符重载、虚基类等等。不仅如此,Java开发环境远远超出大多数其他编程语言的开发环境。 2. 面向对象 什么是面向对象?在Java的世界里,一切皆对象。比如:人、狗、手机、电脑等都是对象。所谓面相对象,就是依靠对象之间的交互来完成事情,比如:人用手机网上购物,狗吃骨头…Java的面向对象特性与C++旗鼓相当,与C++的主要不同点在于多重继承。在Java中,取而代之的是更简单的接口概念。而且与C++相比,Java提供了更丰富的运行时自省功能。 3. 分布式(微服务) Java有丰富的例程库,用于处理像HTTP和FTP之类的TCP/IP协议。Java应用程序能够通过URL打开和访问网络上的对象,其便捷程度就好像访问本地文件一样。 4. 健壮性 Java与C++最大的不同在于Java采用的指针模型可以消除重写内存和损坏数据的可能性(对于曾经花费几个小时来检查由于指针bug而引起内存冲突的人来说,一定很喜欢Java的这一特性)。不仅如此,Java编译器能够检测许多在其他语言中仅在运行时才能够检测出来的问题。 5. 安全性 Java适用于网络/分布式环境。为了达到这个目标,在安全性方面投入了大量的精力。使用Java可以构建防病毒、防篡改的系统从一开始,Java就设计成能够防范的各种攻击: 运行时堆栈溢出。蠕虫和病毒常用的攻击手段。 破坏自己进程空间之外的内存。 未经授权读写文件 6. 体系结构中立 编译器生成一个体系结构中立的目标文件格式,按照该中规范生成的文件,只要有Java运行时系统,这些编译后的代码就可以在许多处理器上运行。Java编译器通过生成与特定计算机体系结构无关的字节码指令来实现这一特性。精心设计的字节码不仅可以很容易的在任何机器上解释执行,而且还可以动态地翻译成本地机器代码。这就是为什么可以:“Wrice once,Run anywhere”。而且其他语言编写的程序,在编译后如果能够严格按照字节码文件的规范生成.class文件,也可以在JVM上运行。 7. 可移植性 与C/C++不同,Java规范中没有“依赖具体实现的地方”。基本数据类型的大小以及有关运算都做了明确的说明。例如,Java中的int永远是32位的整数,而C/C++中,int可能是16位整数、32位整数,也可能是编译器提供商指定的其他大小。在Java中,数据类型具有固定的大小,这消除了代码移植时令人头疼的主要问题。 8. 解释性 Java为了实现与平台无关,自己维护了一套基于栈架构的指令集,Java源代码经编译之后,字节码文件中的指令就是按照自己的指令集来组织的,但是在具体硬件环境中运行时,系统并不能识别,因为Java程序在执行时,Java解释器会逐条的将字节码文件中的指令翻译成CPU的指令集。

数据结构进阶:使用链表实现栈和队列详解与示例(C, C#, C++)

文章目录 1、 栈与队列简介栈(Stack)队列(Queue) 2、使用链表实现栈C语言实现C#语言实现C++语言实现 3、使用链表实现队列C语言实现C#语言实现C++语言实现 4、链表实现栈和队列的性能分析时间复杂度空间复杂度性能特点与其他实现的比较 总结 在软件开发中,数据结构是不可或缺的一部分。本文将详细介绍如何使用链表来实现栈和队列这两种基本的数据结构,并提供C、C#和C++三种语言的示例代码。 1、 栈与队列简介 栈(Stack) 栈是一种后进先出(Last In First Out, LIFO)的数据结构。栈的基本操作包括: push:将元素压入栈顶。pop:移除栈顶元素。peek:查看栈顶元素。 队列(Queue) 队列是一种先进先出(First In First Out, FIFO)的数据结构。队列的基本操作包括: enqueue:在队列尾部添加元素。dequeue:移除队列头部元素。peek:查看队列头部元素。 2、使用链表实现栈 链表是一种灵活的数据结构,非常适合实现栈。 C语言实现 #include <stdio.h> #include <stdlib.h> typedef struct Node { int data; struct Node* next; } Node; typedef struct Stack { Node* top; } Stack; void initStack(Stack* stack) { stack->top = NULL; } void push(Stack* stack, int data) { Node* newNode = (Node*)malloc(sizeof(Node)); newNode->data = data; newNode->next = stack->top; stack->top = newNode; } int pop(Stack* stack) { if (stack->top == NULL) { printf("

全面认识AI Agent,一文读懂AI智能体的架构指南

文章目录: AI Agent概述 AI Agent的架构 AI Agent与相关技术的比较 AI Agent框架和平台 总结与未来展望 AI Agent概述 1.1 定义AI Agent AI Agent,或称为人工智能代理,我更愿意称为AI智能体。它是一种模拟人类智能行为的人工智能系统,以大型语言模型(LLM)作为其核心引擎。它们能够感知其环境,做出决策,并执行任务以实现特定的目标。AI Agent的设计理念是赋予机器自主性、适应性和交互性,使其能够在复杂多变的环境中独立运作。 1.2 AI Agent的应用领域 AI Agent技术已广泛应用于多个领域,包括但不限于: 客户服务(Customer Service):自动回答客户咨询,提供个性化服务。 医疗诊断(Medical Diagnosis):辅助医生进行疾病诊断和治疗方案推荐。 股市交易(Stock Trading):自动化交易系统,根据市场数据做出买卖决策。 智能交通(Intelligent Transportation):自动驾驶车辆和交通管理系统。 教育辅导(Educational Tutoring):个性化学习助手,根据学生的学习进度提供辅导。 1.3 AI Agent的重要性 AI Agent的重要性在于其能够提高效率、降低成本、增强用户体验,并在某些情况下提供超越人类能力的决策支持。随着技术的发展,AI Agent正逐渐成为现代社会不可或缺的一部分。 二 AI Agent的架构 2.1 精简架构:Agent的决策流程 AI Agent的决策流程可以精简为三个基本步骤:感知(Perception)、规划(Planning)和行动(Action),简称为PPA模型。这个模型是Agent智能行为的骨架,支撑着其与环境的交互和自主决策。 感知(Perception):Agent通过感知系统从环境中收集信息,这些信息可以是文本、图像、声音等多种形式。感知是Agent理解周遭世界的第一道工序。 规划(Planning):在收集到信息后,Agent需要一个规划系统来确定如何达到目标。这个过程涉及到决策制定,将复杂任务分解为可执行的子任务。 行动(Action):最后,Agent根据规划的结果执行行动。这些行动可能是物理的,如机器人的移动,也可能是虚拟的,如软件系统的数据处理。 在一个理想的AI Agent架构中,Agent与环境的交互是双向的、动态的,并且是连续的。这种交互模式可以类比于人类与物理世界的互动。正如人类通过感知来理解世界,AI Agent通过其感知系统收集关于外部环境的数据。这些数据不仅包括直接的观察结果,还可能涉及通过传感器、数据输入或其他方式获得的信息。 AI Agent内部,它利用这些感知数据,以支持复杂的Planning、决策和行动。因此,记忆对于AI Agent而言,是一种使其能够跨越时间累积经验、学习教训并优化决策的关键能力。 2.2 记忆的基础知识 在深入Agent架构之前,我们首先需要了解记忆的基础知识。记忆是大脑存储、保留和检索信息的能力。 感觉记忆(Sensory Memory):这是记忆的最初阶段,负责临时存储通过感官接收到的信息(视觉、听觉等)的印象的能力。感觉记忆通常只持续几秒钟 短期记忆(Short-Term Memory, STM):也称为工作记忆,它储存我们当前意识到的信息,以执行复杂的认知任务,如学习和推理。短期记忆被认为有大约7个项目的容量(Miller 1956)并持续20-30秒。。 长期记忆(Long-Term Memory, LTM):长期记忆负责存储可长期保留的信息。长期记忆可以储存信息很长一段时间,从几天到几十年,其储存容量基本上是无限的。 2.3 记忆机制:Agent的知识库 如果AI Agent想要实现智能化,Agent的记忆机制便是其学习和决策过程中不可或缺的一部分。在AI Agent的实际制作与应用中,借鉴人类的记忆机制,Agent的记忆可以被分为以下几类:

无人机监测的必要性及方法

为什么需要无人机探测? 无人机的快速发展和广泛使用为各个行业带来了巨大好处,包括送货服务、农业和监控。然而,这种扩散也导致滥用现象增多,造成非法入侵空域、侵犯隐私和安全威胁。监控和探测在特定空域盘旋的无人机的能力变得越来越重要。 以下是需要无人机探测的一些基本原因: 防止非法活动:探测涉及走私、未经授权的监视或向监狱或边境等敏感区域运送违禁品的无人机。 增强安全性:保护关键基础设施、公共活动和禁区免受潜在的无人机威胁,包括恐怖袭击或间谍活动。 确保安全:防止无人机与载人飞机相撞,并减轻无人机在繁忙空域或人口稠密地区带来的风险。 保护隐私:保护个人和组织免受未经授权的无人机的侵入性监视或数据收集。 无人机探测技术有哪些不同? 技术1——基于雷达的探测 雷达系统发射无线电波并探测从其路径上的物体(包括无人机)反射回来的回波。当雷达波遇到无人机时,部分波会反射回雷达接收器。通过分析反射波返回所需的时间及其多普勒频移(由于运动而导致的频率变化),雷达系统可以确定无人机的存在、位置和速度。它的工作带宽为3MHz至300GHz。 雷达有两种类型:有源雷达和无源雷达。有源雷达发射信号,然后接收反射信号来探测物体,而无源雷达则依靠外部来源(如太阳、星星、蜂窝信号和FM广播)来探测物体。有源雷达通常简称为雷达,可以是单基地(相同的发射和接收天线)或双基地(不同的天线)。有源雷达发射连续波(CW)或脉冲,CW雷达包括阶梯频率连续波(SFCW)雷达和脉冲雷达等类型。脉冲多普勒雷达结合了两者的特点。它使用由移动叶片产生的微多普勒频移来探测无人机,提供有效的信号来区分无人机和鸟类等其他物体。 技术2——射频探测 射频探测系统监测电磁频谱,以查找无人机通信系统、控制链路或其他电子设备发出的信号。无人机发射射频信号用于控制、遥测和视频传输。射频传感器分析这些信号以探测与无人机相关的独特特征。此分析包括信号频率、调制特性和其他识别特征。通过三角测量或使用定向天线,射频系统确定信号来源的方向并根据信号强度估算距离。射频探测使用射频传感器被动监听和监测70MHz至6GHz频率,以查找无人机和飞行员(接收器)之间通信链路的传输,以确定无人机的位置,在某些情况下,还可以确定飞行员的位置。 基于射频的无人机探测非常高效,因为无线电发射器和GPS接收器等无人机组件会发射能量。该探测系统包括无人机、其控制器和两个接收器,用于捕获不同的射频信号波段。无人机通常使用2.4GHz ISM频段的射频信号,射频扫描仪被动监听这些信号进行探测。利用监督式机器学习技术来区分“无人机”和“非无人机”等标签或不同的无人机型号和功能。 技术4——光学和红外(IR)探测 光学和红外传感器通过视觉或基于热信号探测无人机。摄像头或红外传感器捕捉无人机的图像或热信号。图像处理算法分析这些输入以探测和跟踪无人机。它涵盖了3MHz至300GHz的所有可见和红外频谱。

建造者模式例题

假定现在有这样一个需求:电脑可以由主板、硬盘、CPU、内存、显卡、显示器和键盘等元素构成,华硕公司可以生产里面的各种元素,Lenovo公司也可以生产里面的各种元素。假定你现在就想要一台电脑,这个电脑可以全部是来自华硕的品牌机,也可以是来自Lenovo的品牌机,也可以一部分元素来自华硕、另一部分来自Lenovo,请根据上述要求对代码进行设计,给出设计思路和源码。 以下这段代码展示了一个简单的电脑组装系统。首先定义了不同的电脑元素接口,如主板、硬盘、CPU等。然后定义了电脑类 Computer,包含各种电脑组件,并通过 set 方法设置各个组件,最后通过 showInfo 方法展示电脑信息。 接着有一个电脑建造者类 ComputerBuilder,其中包含了建造不同品牌电脑的方法,如 buildHSComputer(华硕电脑)、buildLenovoComputer(联想电脑)、buildCustomComputer(混合电脑),最后通过 getComputer 方法获取组装好的电脑。 最后是 Director 类,包含了导演的角色,负责调用建造者类中的方法来组装不同品牌的电脑,并展示电脑的信息。 电脑元素接口: //电脑元素接口 interface IMotherboard { void makeIMotherboard(); } interface IHardDisk { void makeIHardDisk(); } interface ICPU { void makeICPU(); } interface IMemory { void makeIMemory(); } interface IGraphicsCard { void makeIGraphicsCard(); } interface IDisplay { void makeIDisplay(); } interface IKeyboard { void makeIKeyboard(); } 电脑类 //电脑 public class Computer { private IMotherboard motherboard; private IHardDisk hardDisk; private ICPU cpu; private IMemory memory; private IGraphicsCard graphicsCard; private IDisplay display; private IKeyboard keyboard; public void setMotherboard(IMotherboard motherboard) { this.

MyBatis源码中的设计模式1

1. 建造者模式的应用 建造者模式属于创建类模式,通过一步一步地创建一个复杂的对象,能够将部件与其组装过程分开。用户只需指定复杂对象的类型,就可以得到该对象,而不需要了解其内部的具体构造细节。《Effective Java》中也提到,遇到多个构造器参数时,考虑用构建者(Builder)模式。 在 Mybatis 的环境初始化过程中,SqlSessionFactoryBuilder会调用XMLConfigBuilder读取所有的MybatisMapConfig.xml和所有的*Mapper.xml文件,构建 Mybatis 运行的核心对象Configuration对象,然后将该Configuration对象作为参数构建一个SqlSessionFactory对象。 示例图 其中,XMLConfigBuilder在构建Configuration对象时,也会调用XMLMapperBuilder用于读取*.Mapper文件,而XMLMapperBuilder会使用XMLStatementBuilder来读取和构建所有的 SQL 语句。 示例图 在这个过程中,Builder模式会读取文件或者配置,然后做大量的 XPath 解析、配置或语法解析、反射生成对象、存入结果缓存等步骤。因此,大量采用了 Builder 模式来解决这些问题。 对于Builder的具体类,方法大都用build*开头,比如SqlSessionFactoryBuilder类中包含的方法: 示例图 从建造者模式的设计初衷来看,SqlSessionFactoryBuilder虽然带有 Builder 后缀,但不完全是标准的建造者模式。它的设计初衷是为了简化开发,隐藏构建SqlSessionFactory的复杂过程,对程序员透明。 2. 工厂模式的应用 在 Mybatis 中,SqlSessionFactory使用了简单工厂模式。 简单工厂模式(Simple Factory Pattern):又称为静态工厂方法(Static Factory Method)模式,它属于类创建型模式。简单工厂模式中,可以根据参数的不同返回不同类的实例。 示例图 SqlSession是 Mybatis 工作的核心接口,通过这个接口可以执行 SQL 语句、获取 Mappers、管理事务。 示例图 在DefaultSqlSessionFactory的默认工厂实现里,openSessionFromDataSource方法展示了工厂如何产出一个产品: 示例图 这个方法会先从configuration读取对应的环境配置,然后初始化TransactionFactory获得一个Transaction对象,通过Transaction获取一个Executor对象,最后通过configuration、Executor、autoCommit参数构建了SqlSession。 3. 代理模式的应用 代理模式是 Mybatis 核心使用的模式,使我们只需要编写Mapper.java接口,不需要实现,由 Mybatis 背后完成具体 SQL 的执行。 代理模式(Proxy Pattern):给某个对象提供一个代理,并由代理对象控制对原对象的引用。 示例图 每次调用sqlSession的getMapper方法时,都会创建一个新的动态代理类实例。 示例图 当我们使用Configuration的getMapper方法时,会调用mapperRegistry.getMapper方法, 示例图 在这里,通过T newInstance(SqlSession sqlSession)方法得到一个MapperProxy对象,然后调用T newInstance(MapperProxy<T> mapperProxy)生成代理对象。 示例图 通过这种方式,我们只需要编写Mapper.java接口类,实际执行时会转发给MapperProxy.invoke方法,调用后续的sqlSession.cud > executor.

安卓ANR问题最全解析

目录 前言一、ANR产生原因二、Timeout时长三、典型的ANR场景四、超时检测机制五、前台与后台ANR六、ANR分析流程七、trace.txt文件解读八、ANR定位分析实例8.1 Logcat分析8.2 trace.txt文件分析 九、ANR源码分析十、ANR实例及分析10.1 应用在主线程上进行长时间的计算10.2 应用在主线程上执行耗时的I/O的操作10.3 主线程处于阻塞状态,等待获取锁10.4 主线程与其他线程之间发生死锁10.5 主线程对另一个进程进行同步Binder调用,后者需很长时间才能返回 十一、总结 前言 ANR即Application Not Responding(应用程序无响应),一般在ANR的时候会弹出一个应用无响应对话框,同时会候产生一个日志文件trace.txt,位于/data/anr/文件夹下面,trace文件是Android Davik虚拟机在收到异常终止信号时产生的,最常见的一个触发条件就是Android应用中产生了FC(force close)。由于该文件的产生是在DVM中的,所以只有运行DVM实例的进程才能产生该文件,也就是说只有Java代码才能产生该文件,App应用的Native层(如Android Library、用c/c++编译的库)即使异常也不会产生ANR日志文件。我们可以通过ANR产生的traces日志文件分析应用在哪里产生了ANR,以此来有效解决应用中的ANR。 一、ANR产生原因 只用当应用程序的UI线程响应超时才会引起ANR,超时原因一般有两种: 1.当前的事件没有机会得到处理,例如UI线程正在响应另一个事件,当前事件由于某种原因被阻塞了。2.当前的事件正在被处理,但是由于好事太长没有能够及时完成 根据ANR产生的原因不同,超时时间也不尽相同,从本质上讲,产生ANR的场景有四种,大致可以对应到Android中的(Activity、BroadcastReceive、Service、InputDispatch) 第一种:InputDispatching Timeout :最常见的一种类型,原因是View事件或者触摸事件在特定时间内无法得到响应 第二种:Broadcast Timeout:BroadcastReceiver的onReceive函数运行在主线程,并在特定的时间内无法完成处理 第三种:Service Timeout:Service的各个生命周期函数在特定时间内无法完成响应 第四种:ContentProvider Timeout :ContentProvider的操作在特定时间内无法完成响应。 二、Timeout时长 对于前台服务,则超时为SERVICE_TIMEOUT=20S;对于后台服务,则超时为SERVICE BACKGROUND TIMEOUT=200S·对于前台广播,则超时为BROADCAST FG TIMEOUT=10S;对于后台广播,则超时为BROADCAST BG TIMEOUT=60s;.ContentProvider超时为CONTENT PROVIDER PUBLISH TIMEOUT = 10S:.InputDispatching Timeout: 输入事件分发超时5s,包括按键和触摸事件。 注意事项: Input的超时机制与其他的不同,对于input来说即便某次事件执行时间超过timeout时长,只要用户后续在没有再生成输入事件,则不会触发ANR 三、典型的ANR场景 1.主线程频繁进行IO操作,比如读写文件或者数据库;2.硬件操作如进行调用照相机或者录音等操作;3.多线程操作的死锁,导致主线程等待超时;4.主线程操作调用join()方法、sleep()方法或者wait()方法;5.耗时动画/耗资源行为导致CPU负载过重6.system server中发生WatchDog ANR;7.service binder的数量达到上限 四、超时检测机制 1.Service超时检测机制: 超过一定时间没有执行完相应操作来触发移除延时消息,则会触发anr; 2.BroadcastReceiver超时检测机制: 有序广播的总执行时间超过 2receiver个数timeout时长,则会触发anr;有序广播的某一个receiver执行过程超过 timeout时长,则会触发anr; 3.另外: 对于Service, Broadcast, Input发生ANR之后,最终都会调用AMS.appNotResponding;对于provider,在其进程启动时publish过程可能会出现ANR,则会直接杀进程以及清理相应信息,而不会弹出ANR的对话框 五、前台与后台ANR 前台ANR:用户能感知,比如拥有前台可见的activity的进程,或者拥有前台通知的fg-service的进程,此时发生ANR对用户体验影响比较大,需要弹框让用户决定是否退出还是等待后台ANR:只抓取发生无响应进程的trace,也不会收集CPU信息,并且会在后台直接杀掉该无响应的进程,不会弹框提示用户 六、ANR分析流程 1. 前台ANR发生后,系统会马上去抓取现场的信息,用于调试分析,收集的信息如下:

Spring与设计模式实战之策略模式

Spring与设计模式实战之策略模式 引言 在现代软件开发中,设计模式是解决常见设计问题的有效工具。它们提供了经过验证的解决方案,帮助开发人员构建灵活、可扩展和可维护的系统。本文将探讨策略模式在Spring框架中的应用,并通过实际例子展示如何通过Spring的特性来实现和管理策略模式。 1. 策略模式(Strategy Pattern)的概述 策略模式是一种行为型设计模式,它允许定义一系列算法,并将每个算法封装起来,使它们可以互换。这种模式让算法的变化独立于使用算法的客户。在Java中,策略模式通常通过接口和它们的实现类来实现。 1.1 策略模式的结构 策略接口:声明了所有具体策略类都必须实现的操作。具体策略类:实现了策略接口,定义了具体的算法。上下文类:维护一个对策略对象的引用,并在需要时调用策略对象的方法。 2. ApplicationContextAware接口的介绍 在Spring框架中,ApplicationContext是一个非常核心的概念。它代表Spring IoC容器,负责实例化、配置和管理Beans。通过实现ApplicationContextAware接口,Spring Bean可以访问Spring的ApplicationContext,从而获取其他Beans或上下文信息。 2.1 ApplicationContextAware的使用 当一个Bean实现ApplicationContextAware接口时,Spring会在初始化该Bean时自动调用其setApplicationContext方法,并传入ApplicationContext实例。这样,该Bean就可以使用这个上下文来获取其他Beans或与Spring容器交互。 import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.stereotype.Component; @Component public class MyBean implements ApplicationContextAware { private ApplicationContext applicationContext; @Override public void setApplicationContext(ApplicationContext applicationContext) { this.applicationContext = applicationContext; } public void doSomething() { // 使用applicationContext获取其他Bean AnotherBean anotherBean = applicationContext.getBean(AnotherBean.class); anotherBean.performTask(); } } 3. StrategyFactory的设计与实现 StrategyFactory是一个策略工厂类,负责根据业务需求创建和提供策略实例。它使用自定义的@TradeStrategy注解来识别和创建具体的策略类实例。 3.1 自定义注解@TradeStrategy 我们首先定义一个自定义注解@TradeStrategy,用于标注具体的策略类。这个注解可以在运行时通过反射机制进行处理。 import java.lang.annotation.*; @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface TradeStrategy { String value(); } 3.

基于SpringBoot的旅游管理系统

基于SpringBoot+Vue的旅游管理系统的设计与实现~ 开发语言:Java数据库:MySQL技术:SpringBoot+MyBatis工具:IDEA/Ecilpse、Navicat、Maven 系统展示 前台 后台 摘要 本文旨在设计和实现一个基于Spring Boot框架的旅游管理系统。该系统通过利用Spring Boot的快速开发特性和丰富的生态系统,提供了一个高效、可靠和灵活的解决方案。该系统涵盖了旅游景点信息的管理、线路规划、跟团游玩、旅游攻略、酒店信息管理、订单管理和用户权限控制等功能。用户可以通过该系统方便地浏览和搜索旅游景点信息,并根据个人喜好和需求进行景点线路规划和跟团游玩预订。同时,系统还提供了管理员权限,以便管理和维护景点信息、订单和用户信息等。本研究不仅提升了旅游服务的质量和用户体验,还为旅游行业的数字化转型和智能化发展做出了积极贡献。 研究意义 随着旅游业的蓬勃发展,传统的旅游管理方式逐渐暴露出诸多弊端,已无法满足日益增长的市场需求。信息不对称、操作繁琐、效率低下等问题如同一道道枷锁,严重制约了旅游业的发展和游客体验的提升。在这样的背景下,开发一个高效、智能的旅游管理系统显得尤为重要和迫切。基于Spring Boot的旅游管理系统应运而生,它凭借自动化和智能化的手段,为旅游信息的高效管理和个性化服务提供了全新的解决方案。这一系统不仅极大地提高了旅游信息的管理效率,更通过数据分析和决策支持功能,为旅游企业注入了强劲的技术动力。具体而言,该系统通过集成先进的信息技术,实现了旅游数据的实时更新和共享,有效打破了信息不对称的壁垒。游客可以随时随地通过系统获取最新的旅游信息,包括景点介绍、线路规划、酒店预订等,从而更加便捷地安排自己的行程。同时,系统还提供了个性化的服务,根据游客的喜好和需求,为其推荐合适的旅游产品和服务,进一步提升了游客的满意度和忠诚度。对于旅游企业而言,该系统更是一个不可或缺的得力助手。它通过对旅游数据的深度挖掘和分析,帮助企业更好地了解市场趋势和客户需求,从而制定更加科学、合理的经营策略。例如,系统可以分析游客的游览行为、消费习惯等数据,为企业调整产品结构、优化服务流程提供有力的依据。此外,系统还可以实时监控企业的运营状况,及时发现并解决问题,确保企业的稳健发展。值得一提的是,基于Spring Boot的旅游管理系统还具备出色的可扩展性和可维护性。这意味着随着旅游业的不断发展和市场需求的不断变化,系统可以轻松地进行升级和扩展,以适应新的业务场景和技术要求。同时,系统的模块化设计也使得维护和管理工作变得更加简单和高效。综上所述,基于Spring Boot的旅游管理系统不仅为旅游业带来了前所未有的变革和机遇,更为游客和企业创造了更加美好的旅游体验和发展前景。它的出现标志着旅游业正向着更加智能化、个性化的方向迈进,为未来的旅游市场发展奠定了坚实的基础。 研究目的 本研究的主要目的旨在全方位提升旅游管理系统的性能与效用。首先,我们致力于通过Spring Boot技术构建一个高效的旅游管理系统,以简化旅游相关数据的收集、存储、检索和更新过程。这一目标的实现将极大地提高旅游信息的管理效率,使得旅游数据更加易于访问和维护。我们深知,在传统的旅游管理方式中,数据处理往往繁琐且耗时,这不仅影响了工作效率,还可能导致信息的滞后或不准确。因此,我们希望通过这一系统的构建,能够打破这一瓶颈,为旅游行业带来更加便捷、高效的数据管理体验。其次,我们注重用户体验的提升。一个好的系统不仅仅要有强大的后台支持,更需要有用户友好的界面和快速、可靠的服务。因此,在设计本系统时,我们充分考虑了不同用户的需求和使用习惯,力求打造一个既美观又实用的用户界面。同时,我们还将不断优化系统的响应速度和服务质量,以确保用户在使用过程中能够获得流畅、愉悦的体验。此外,我们还注重系统的数据分析和决策支持功能。通过对旅游信息的有效分析,我们可以为企业或组织的决策制定提供有力的数据支持。这将帮助企业更好地了解市场趋势、客户需求和运营绩效,从而制定出更加科学、合理的经营策略。我们相信,这一功能的实现将为旅游行业的发展注入新的活力。最后,我们充分考虑了系统的可维护性和可扩展性。利用Spring Boot的模块化开发方式,我们可以确保系统在未来能够适应新的需求和技术变化。这意味着,当旅游行业出现新的业务模式或技术革新时,我们的系统能够迅速进行升级和扩展,以满足市场的变化。同时,这种模块化的设计也使得系统的维护和管理工作变得更加简单和高效。这将大大降低企业的运营成本,提高系统的使用寿命和价值。综上所述,本研究的主要目的旨在通过Spring Boot技术构建一个高效、智能的旅游管理系统,以提高旅游信息的管理效率、提升用户体验、提供数据分析和决策支持功能,并确保系统的可维护性和可扩展性。我们相信,这一目标的实现将为旅游行业的发展带来积极的影响和推动。 代码展示 // UserController.java @RestController @RequestMapping("/api/users") public class UserController { @Autowired private UserService userService; @PostMapping("/login") public ResponseEntity<?> login(@RequestBody UserLoginDto userLoginDto) { User user = userService.login(userLoginDto.getUsername(), userLoginDto.getPassword()); if (user != null) { // 生成token等操作 return ResponseEntity.ok(user); } else { return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("用户名或密码错误"); } } } // UserService.java @Service public class UserService { @Autowired private UserRepository userRepository; public User login(String username, String password) { User user = userRepository.

RabbitMQ 和 RocketMQ 的区别

RabbitMQ 和 RocketMQ 都是流行的开源消息中间件,它们用于在分布式系统中异步传输消息。尽管它们都实现了核心的消息队列功能,但它们在设计、性能、特性和使用场景上有一些关键的区别: 基础架构: RabbitMQ: 基于AMQP(高级消息队列协议)构建,支持多种消息协议,如STOMP、MQTT等。RocketMQ: 阿里巴巴开源,最初是为了满足其大规模电商交易系统的需求,主要支持其自定义的灵活的消息模型。 性能: RabbitMQ: 适合于一般的消息队列需求,但在高吞吐量和大规模分布式系统场景下可能不是最优选择。RocketMQ: 优化了高吞吐量和大规模集群的性能,特别是在阿里巴巴的电商交易场景中得到了验证。 可伸缩性: RabbitMQ: 通过代理集群和联邦集群实现可伸缩性,但配置和运维相对复杂。RocketMQ: 设计之初就考虑了水平扩展,提供了较为简单的集群部署和运维方式。 容错和高可用性: RabbitMQ: 通过镜像队列和集群插件提供高可用性。RocketMQ: 具有内置的高可用性支持,包括主从复制和故障自动切换。 特性和功能: RabbitMQ: 提供了丰富的特性,如消息持久性、事务性、死信队列、延迟消息等。RocketMQ: 专注于核心消息队列功能,提供了顺序消息、事务消息、定时消息等特性。 社区和生态系统: RabbitMQ: 拥有一个成熟的社区和广泛的插件生态系统,支持多种编程语言和框架。RocketMQ: 主要由阿里巴巴维护,社区相对较小,但在中国有广泛的用户基础。 使用场景: RabbitMQ: 适用于需要多种消息协议支持和复杂路由功能的场景。RocketMQ: 更适合于需要高性能、高吞吐量和大规模分布式系统的场景。 部署和运维: RabbitMQ: 运维可能相对复杂,特别是在集群配置和故障排查方面。RocketMQ: 运维相对简单,易于部署和管理。 选择哪一个取决于具体的业务需求、性能要求、开发团队的熟悉度以及生态系统的支持。每种消息队列系统都有其优势和局限性,理解这些差异有助于做出更合适的技术选型。

【C++】C/C++内存管理

个人主页~ 内存管理 一、C/C++内存分布二、C语言中动态内存管理方式三、C++内存管理方式1、new和delete操作内置类型2、new和delete操作自定义类型 四、operator new 和operator delete 函数五、new 和 delete 实现的原理1、内置类型2、自定义类型(1)new(2)delete(3)new[ ](4)delete[ ] 六、定位new(placement new)表达式七、malloc和new、free和delete的区别八、内存泄漏1、内存泄漏的危害2、内存泄漏的种类3、避免内存泄漏的方法 九、抛异常及捕获异常 一、C/C++内存分布 C/C++中程序内存区域划分为栈、内存映射段、堆、数据段、代码段 栈:存放非静态局部变量、函数参数、返回值等等,是向下增长的 内存映射段:用于装载一个共享的动态内存库,做映射 堆:用于程序运行时动态内存分配,是向上增长的 数据段:存储全局变量和静态数据,也叫静态区 代码段:存储可执行的代码以及只读常量,也叫常量区 #include <stdlib.h> int a = 1; static int b = 1; void Test() { static int c = 1; int d = 1; int num1[10] = { 1, 2, 3, 4 }; char char2[] = "abcd"; const char* pchar3 = "abcd"; int* p1 = (int*)malloc(sizeof(int) * 4); int* p2 = (int*)calloc(4, sizeof(int)); int* p3 = (int*)realloc(p2, sizeof(int) * 4); free(p1); free(p3); } 栈中数据:d、num1、*num1、char2、*char2、pchar3、p1、p2、p3

数据类型与结构设计:Rust 语言的深度探索

数据类型与结构设计:Rust 语言的深度探索 引言:数据与结构的精妙交响Rust 数据类型概览:坚实的基础数据类型详解基本数据类型:构建程序的原子单元复合数据类型:构建复杂数据结构的积木与结构体和枚举的结合 结构体与枚举:数据的容器与形态方法与关联函数:赋予行为的桥梁进阶议题:泛型、Traits 与模式匹配结语:构造与设计的艺术 你的世界你是主角,你也不普通 。 引言:数据与结构的精妙交响 在编程的世界里,数据类型与结构设计是构建软件大厦的砖石,它们不仅承载着信息的存储与传输,更决定了程序的逻辑与效率。Rust ,作为一门旨在融合高性能与内存安全的现代编程语言,以其严谨的数据模型、灵活的类型系统以及强大的抽象能力,为开发者提供了一套构建高质量软件的完备工具集。本文旨在深入探讨 Rust 的数据类型概览、结构体与枚举的精妙运用,以及方法与关联函数的定义,并通过详实的代码论证,揭示 Rust 在数据管理与结构设计方面的独特魅力。 Rust 数据类型概览:坚实的基础 Rust 的数据类型系统既丰富又严格,它不仅包括基础类型,如整数(如 i32 )、浮点数(如 f64 )、布尔值( bool )和字符( char ),还涵盖了一系列复合类型,如数组、向量( Vec<T> )、元组和字符串( String )。此外,Rust 还引入了 Option<T> 和 Result<T, E> 这样的高级类型来优雅地处理潜在的空值或错误情况,体现了其对安全性的重视。 let age: u8 = 30; // 基础类型示例 let pi: f64 = 3.14159; // 浮点数 let is_valid: bool = true; // 布尔值 let initial: char = 'A'; // 字符 数据类型详解 基本数据类型:构建程序的原子单元 **Rust 的基本数据类型是构建复杂数据结构和算法的基石。**它们是语言内建的、不可分解的类型,直接映射到计算机的硬件表示。Rust 的基本数据类型包括但不限于: