ollama-python-Python快速部署Llama 3等大型语言模型最简单方法

ollama介绍 在本地启动并运行大型语言模型。运行Llama 3、Phi 3、Mistral、Gemma和其他型号。 Llama 3 Meta Llama 3 是 Meta Inc. 开发的一系列最先进的模型,提供8B和70B参数大小(预训练或指令调整)。 Llama 3 指令调整模型针对对话/聊天用例进行了微调和优化,并且在常见基准测试中优于许多可用的开源聊天模型。 安装 pip install ollama 高性价比GPU资源:https://www.ucloud.cn/site/active/gpu.html?ytag=gpu_wenzhang_tongyong_shemei 用法 import ollamaresponse = ollama.chat(model='llama2', messages=[ { 'role': 'user', 'content': 'Why is the sky blue?', },])print(response['message']['content']) 流式响应 可以通过设置stream=True、修改函数调用以返回 Python 生成器来启用响应流,其中每个部分都是流中的一个对象。 import ollama stream = ollama.chat( model='llama2', messages=[{'role': 'user', 'content': 'Why is the sky blue?'}], stream=True, ) for chunk in stream: print(chunk['message']['content'], end='', flush=True) 应用程序编程接口 Ollama Python 库的 API 是围绕Ollama REST API设计的

【Spring】SpringBoot整合Redis,用Redis实现限流(附Redis解压包)

📝个人主页:哈__ 期待您的关注 目录 一、Windows安装Redis 二、启动Redis 三、SpringBoot整合Redis 1.引入依赖 2.添加配置文件application.yml 3.创建RedisController 四、Redis限流的几种方法 1.基于Redis的数据结构zset(滑动窗口) 2.基于Redis的令牌桶算法 本文介绍SpringBoot整合Redis并且进行接口的限流,文章主要介绍的是一种思想,具体代码还要结合实际。 一、Windows安装Redis Redis的解压包我放在了百度网盘上,有需要的可以下载。 Redis-x64-3.0.504 解压码:uhwj 二、启动Redis 我们在本地解压下载的Redis压缩包,打开解压后的目录,首先启动redis-server.exe,之后在启动redis-cli.exe。 启动成功截图如下。 三、SpringBoot整合Redis 1.引入依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> 2.添加配置文件application.yml 我们并没有设置密码所以不用配置。 spring: redis: host: 127.0.0.1 port: 6379 3.创建RedisController 我们现在是介绍思想,所以传入了一个用户的id来判断是哪一个用户访问的接口。我们对redis中保存的key为用户id的键值对进行一个自增操作,然后返回这个自增后的值,这个值代表的就是我们在十秒钟内访问接口的次数。每次访问我们都重新设置这个键值对的有效时间,如果值大于5说明我们访问的次数已经达到了系统对个人十秒钟内访问次数的限制了,就不可以执行我们的业务逻辑。 @Resource private RedisTemplate<String, String> redisTemplate; @GetMapping("/test2") public String test2(String id){ Long increment = redisTemplate.opsForValue().increment(id); redisTemplate.expire(id,10,TimeUnit.SECONDS); if(increment > 5){ return "不可以访问,访问次数为"+increment; } return "

【Java】实现一个简单的线程池

📝个人主页:哈__ 期待您的关注 目录 ​编辑 一、线程池的模式 二、线程池的一些参数 三、代码实现 1.BlockingQueue 2.ThreadPool 四、拒绝策略 一、线程池的模式 线程池顾名思义就是管理线程的一个池子,我们把创建线程的过程交给线程池来处理,而这个线程池当中的线程都会从阻塞队列当中取获取任务执行。 我们不在直接把任务的创建过程写到我们初始化的线程对象中,而是通过调用线程池的execute()方法,同时把我们的具体任务交作为参数传给线程池,之后线程池就会把任务添加到阻塞队列当中,而线程池当中的线程会从阻塞队列当中获取任务并执行。 二、线程池的一些参数 corePoolSize:线程池核心线程大小,即最小线程数(初始化线程数)。线程池会维护当前数量的线程在线程池中,即使这些线程一直处于闲置状态,也不会被销毁,除非设置了allowCoreThreadTimeOut。maximumPoolSize:线程池最大线程数量。当任务提交到线程池后,如果当前线程数小于核心线程数,则会创建新线程来处理任务;如果当前线程数大于或等于核心线程数,但小于最大线程数,并且任务队列已满,则会创建新线程来处理任务。keepAliveTime:空闲线程的存活时间。当线程池中的线程数量大于核心线程数且线程处于空闲状态时,在指定时间后,这个空闲线程将会被销毁,从而逐渐恢复到稳定的核心线程数数量。unit:keepAliveTime的存活时间的计量单位,通常使用TimeUnit枚举类中的方法,如TimeUnit.SECONDS表示秒级。workQueue:任务队列。用于存放等待执行的任务,常见的实现类有LinkedBlockingQueue、ArrayBlockingQueue等。threadFactory:线程工厂。用于创建新的线程,可以自定义线程的名称、优先级等。handler:拒绝策略。当任务无法执行(如线程池已满)时,可以选择的策略有:AbortPolicy(抛出异常)、CallerRunsPolicy(调用者运行)、DiscardOldestPolicy(丢弃最老的任务)、DiscardPolicy(无声丢弃)。 三、代码实现 因为我们只是简单的实现,所以有一些情况和实际不太相似。 1.BlockingQueue 先来看看我们阻塞队列当中的一些参数,为了在多线程环境下防止并发问题,我使用了ReentrantLock,使用它的目的是为了创建多个不同的阻塞条件。 在我们调用一个对象的await()方法后,我们的当前线程就会加入到一个特定的队列当中去等待,直到有调用了这个对象的notify()方法后才会从这个队列中抽取一个线程唤醒。 举个例子,我们去医院的时候,一个医生同一时间只能看一个病人,剩下的人都只能等待,如果只有一个大厅的话,看不同病的病人都只能等待在一个候诊室中。使用ReentrentLock的意思就是为了创建多个不同的候诊室,将不同医生的病人分开在不同的候诊室当中。 //1.阻塞队列 private Deque<T> deque = new ArrayDeque<>(); //2.实现阻塞的锁 private ReentrantLock lock = new ReentrantLock(); //3. 生产者等待条件 private Condition fullWaitSet = lock.newCondition(); //4.消费者等待条件 private Condition emptyWaitSet = lock.newCondition(); //5.阻塞队列的大小 private int CAPACITY; 在自定义的阻塞队列中,我使用了一个双向队列来存储任务,并且设置了一个队列大小的属性,在我们创建这个队列的时候我们可以进行初始化。 先来看看阻塞队列任务的添加过程。这个逻辑并不难,我们在代码的上方上锁,在finally中解锁。如果这时我们的队列是满的,就无法在继续添加任务了,这个时候我们就把当前线程挂起(注意我们的挂起条件)。如果队列不是满的话那我们就加入到队尾,同时把另一类挂起的线程唤醒(这类线程在队列为空的时候挂起,等待任务的添加)。 // 生产者放入数据 public void put(T t) { lock.lock(); try { while (deque.size() == CAPACITY) { fullWaitSet.

Java之抽象类和接口

一、抽象类 1.抽象类概念 如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类, 比如动物类。没有实际工作的方法 , 我们可以把它设计成一个 抽象方法, 包含抽象方法的类我们称为 抽象类。 2.抽象类语法 在Java中,一个类如果被 abstract 修饰称为抽象类,抽象类中被 abstract 修饰的方法称为抽象方法,抽象方法不用给出具体的实现体。 // 抽象类:被abstract修饰的类 public abstract class Shape { // 抽象方法:被abstract修饰的方法,没有方法体 abstract public void draw(); abstract void calcArea(); // 抽象类也是类,也可以增加普通方法和属性 public double getArea(){ return area; } protected double area; // 面积 } 注意:抽象类也是类,内部可以包含普通方法和属性,甚至构造方法 3. 抽象类特性 1. 抽象类不能直接实例化对象 Shape shape = new Shape(); // 编译出错 Error:(30, 23) java: Shape是抽象的; 无法实例化 2.抽象方法不能被final和static和private修饰,因为抽象方法要被子类重写 public abstract class Shape { abstract private void draw(); abstract final void methodA(); abstract public static void methodB(); } // 编译报错: //Error:(19, 27) java: 非法的修饰符组合: abstract和private // Error:(20, 25) java: 非法的修饰符组合: abstract和final // Error:(21, 33) java: 非法的修饰符 4.

java.lang.IllegalArgumentException异常的正确解决方法

java.lang.IllegalArgumentException是Java中常见的异常之一,通常表示方法接收到了不合法的参数。要正确解决这个异常,可以采取以下几个步骤: 查看异常信息:首先要查看异常的详细信息,包括异常堆栈跟踪,以确定出现异常的具体位置和原因。 检查参数传递:确认传递给方法的参数是否符合方法预期的要求。可能需要检查参数的类型、范围、空值检查等。 验证输入:对于从外部获取的输入数据,要进行有效性验证,确保其符合预期的格式和约束。 使用断言:在方法内部可以使用断言(assert)来进行参数合法性检查,如果参数不合法,则抛出IllegalArgumentException。 优化异常处理:在捕获异常时,可以提供更多的上下文信息,以帮助定位和解决问题。 更新文档:如果是自己编写的方法,要确保文档清晰地说明了方法的预期参数,以及可能抛出的异常类型和原因。 单元测试:编写单元测试用例,覆盖各种可能的参数情况,以确保方法在各种条件下都能正确处理。 修复代码:根据异常信息和检查结果,修改代码逻辑,确保不会再出现非法参数导致的异常。 综上所述,要正确解决java.lang.IllegalArgumentException异常,需要仔细检查代码逻辑,确认参数的合法性,优化异常处理,并确保代码质量和可靠性。

深入OceanBase分布式数据库:MySQL 模式下的 SQL 基本操作

码到三十五 : 个人主页 OceanBase与MySQL模式下兼容性序 在当今的大数据时代,数据库技术的选择对于企业的信息化发展至关重要。OceanBase作为一种高性能、高可用的分布式关系数据库,在与MySQL模式的兼容性方面展现出了显著的优势,为企业数据迁移、整合与升级提供了极大的便利。 OceanBase与MySQL的兼容性不仅体现在数据类型、SQL语法等基本面,更深入到了存储引擎、优化器等多个层次。这种高度的兼容性使得企业在不改变原有业务逻辑的情况下,能够轻松地将数据和应用从MySQL迁移到OceanBase,从而享受到OceanBase带来的高性能和可扩展性。 本文将探讨OceanBase与MySQL模式下的兼容性和OceanBase的MySQL 模式下的 SQL 基本操作。 目录 前言:OceanBase与 MySQL 兼容性对比数据类型兼容性SQL语法兼容性存储引擎和分区功能优化器和执行计划备份与恢复 1. 创建数据库1.1 语法1.2 参数说明 2. 表操作2.1 创建表2.2 查看表2.3 修改表2.4 删除表 3. 索引操作3.1 创建索引3.2 查看索引3.3 删除索引 4. 插入数据5. 删除数据6. 更新数据7. 查询数据8. 提交事务9. 回滚事务 前言:OceanBase与 MySQL 兼容性对比 OceanBase与MySQL模式下的兼容性可以从以下几个方面进行简述: 数据类型兼容性 OceanBase的MySQL模式兼容MySQL 5.7的绝大部分数据类型,包括数值类型(如INT、BIGINT、FLOAT、DOUBLE等)、日期和时间类型(如DATETIME、TIMESTAMP等)、字符串类型(如CHAR、VARCHAR等)以及其他复杂数据类型(如ENUM、SET、JSON等)。此外,OceanBase还支持空间数据类型,这在某些特定应用场景中非常有用。 OceanBase 数据库支持的数据类型有: 数值类型 整数类型:BOOL/BOOLEAN/TINYINT、SMALLINT、MEDIUMINT、INT/INTEGER 和 BIGINT。 定点类型:DECIMAL 和 NUMERIC。 浮点类型:FLOAT 和 DOUBLE。 Bit-Value 类型:BIT。 日期时间类型:DATETIME、TIMESTAMP、DATE、TIME 和 YEAR。 字符类型:CHAR、VARCHAR、BINARY 和 VARBINARY。 大对象类型:TINYBLOB、BLOB、MEDIUMBLOB 和 LONGBLOB。 文本类型:TINYTEXT、TEXT、MEDIUMTEXT 和 LONGTEXT。

Python实战演练之python实现神经网络模型算法

python实现神经网络模型算法 今天,后背小罗和大家分享用Python实现神经网络模型算法,仅用于技术学习交流。 实现技巧 1.导入依赖库: 主要是安装相关的依赖库。本文实现的环境为:python 3.7。 from __future__ import division import math import random import pandas as pd 2.构建BP神经网络类: 主要是构建三层反向传播神经网络类。 """ 三层反向传播神经网络 """ class NN: def __init__(self, ni, nh, no): self.ni = ni + 1 # 输入层节点 self.nh = nh + 1 # 隐藏层节点 self.no = no # 输出层种类 self.ai = [1.0] * self.ni self.ah = [1.0] * self.nh self.ao = [1.0] * self.no self.wi = self.makeMatrix(self.ni, self.nh) # 输出层到隐藏层的映射矩阵 self.

Java进阶-Java Stream API详解与使用

本文全面介绍了 Java Stream API 的概念、功能以及如何在 Java 中有效地使用它进行集合和数据流的处理。通过详细解释和示例,文章展示了 Java Stream API 在简化代码、提高效率以及支持函数式编程方面的优势。文中还比较了 Java Stream API 与其他集合处理库的异同,强调了其在现代 Java 开发中的重要性和实用性。 一、Java Stream API介绍 1. Java Stream API简述 Java Stream API 是Java 8中引入的一项功能,它允许程序员以声明式方式处理数据集合。通过Stream API,可以对数据执行复杂的查询操作,而不必编写冗余的代码。Stream 不是数据结构,它更像是一个高级版本的Iterator。单次使用,数据只能遍历一次,遍历过程中你可以对数据进行过滤、排序、聚合等操作。 2. Java Stream API支持的功能 功能描述filter过滤流中的元素,根据条件只留下满足条件的元素map将流中的每个元素映射成其他形式,结果是一个包含映射后结果的新流sorted确保流中的元素在消费时的顺序按照自然顺序或自定义Comparator排序collect将流转换为其他形式,如List、Set或Map,或者是自定义的收集器forEach遍历流中的每个元素并执行给定的操作reduce通过重复处理其元素来将流减少到单个汇总结果anyMatch检查流中的元素是否有一个满足给定的条件allMatch检查流中的元素是否全部满足给定条件noneMatch检查流中的元素是否没有满足给定条件的findFirst返回流中的第一个元素,如果流为空,则返回空的Optionallimit截断流,使其最大长度不超过给定数量skip跳过流中的前n个元素,返回包含余下元素的新流 3. 使用Java Stream API的优势 功能Java Stream API传统集合操作数据处理模式声明式,支持函数式编程命令式,代码较为复杂内存效率更高,因为它是在流上直接操作低,需要复制到新的数据结构并发处理内建支持并发处理手动处理并发可读性高,流操作可链式调用低,循环和条件判断多使用场景数据集合操作,大数据处理小数据量操作 二、常用的Java Stream API功能 下面是针对每个Java Stream API函数的示例代码: 1. filter 过滤流中的元素,根据条件只留下满足条件的元素。 List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6); List<Integer> evenNumbers = numbers.stream() .filter(n -> n % 2 == 0) .

【活动】AIGC 技术的发展现状与未来趋势

🌈个人主页: 鑫宝Code 🔥热门专栏: 闲话杂谈| 炫酷HTML | JavaScript基础 ​💫个人格言: "如无必要,勿增实体" 文章目录 AIGC 技术的发展现状与未来趋势引言AIGC技术的发展现状文本生成图像生成音频生成视频生成 AIGC技术的挑战AIGC技术的未来趋势更高质量的生成多模态生成个性化和定制化可解释性和透明度的提升安全性和伦理性的关注 结论 AIGC 技术的发展现状与未来趋势 引言 随着人工智能技术的飞速发展,AIGC(Artificial Intelligence Generated Content)即人工智能生成内容技术,已经成为了科技领域的热点话题。AIGC涉及文本、图像、音频和视频等多种内容形式,它通过机器学习模型来自动或半自动地生成具有创意的内容。在这篇文章中,我将探讨AIGC技术的发展现状以及未来的发展趋势。 AIGC技术的发展现状 文本生成 在文本生成方面,自然语言处理(NLP)技术已经取得了显著的进步。以Transformer为基础的模型,如GPT-3,已经能够生成连贯且富有创意的文本。这些模型在新闻撰写、故事创作、代码编写等领域展现出了巨大的潜力。 图像生成 在图像生成领域,GAN(生成对抗网络)技术是一大亮点。通过训练,GAN能够生成高质量的图像,甚至是逼真的人脸。此外,StyleGAN和BigGAN等变体在细节和风格上提供了更多的控制,使得生成的图像更加多样化和定制化。 音频生成 音频生成方面,WaveNet等模型能够合成接近人声的音频。这些技术被广泛应用于语音合成、音乐创作和声音效果生成等领域。 视频生成 视频生成是一个更为复杂的领域,因为它涉及到时空数据的处理。目前,通过结合图像生成和音频生成的技术,AI已经能够生成简单的视频内容,如虚拟角色的讲话或是动态的风景画面。 AIGC技术的挑战 尽管AIGC技术取得了显著的进步,但仍然面临着一些挑战: 质量控制:生成内容的质量仍然是一个问题,尤其是在复杂和创意性要求较高的任务中。原创性与版权:如何确保生成内容的原创性,以及如何处理与现有作品的版权问题,是法律和伦理上的大问题。可解释性和透明度:AI生成内容的过程往往是黑箱的,这给理解、控制和改进生成结果带来了困难。安全性和滥用:随着技术的发展,如何防止AIGC被用于制造假新闻、深度伪造(deepfakes)和其他恶意用途,成为了一个紧迫的问题。 AIGC技术的未来趋势 更高质量的生成 未来的AIGC技术将更加注重生成内容的质量。通过更精细的模型设计和训练策略,我们可以期待生成的内容将更加精准、丰富和有创意。 多模态生成 多模态生成,即同时处理和生成多种类型的内容(如文本、图像、音频和视频),将是一个重要的发展方向。这将使得AIGC技术在电影制作、游戏开发和虚拟现实等领域有更大的应用空间。 个性化和定制化 随着模型的改进和数据分析能力的提升,AIGC将能够更好地理解用户的喜好和需求,从而生成更加个性化和定制化的内容。 可解释性和透明度的提升 为了解决黑箱问题,未来的AIGC模型将更加注重可解释性和透明度。这不仅有助于提高用户对生成内容的信任,也有助于研究人员和开发者改进模型。 安全性和伦理性的关注 随着AIGC技术的广泛应用,其安全性和伦理性问题将受到更多关注。研究者和开发者需要与政策制定者、社会学家和艺术家等多方合作,共同探讨如何确保AIGC技术的健康发展。 结论 AIGC技术正在快速进步,已经在多个领域展现出了巨大的潜力。然而,它也面临着质量控制、原创性与版权、可解释性和安全性等挑战。未来的AIGC技术将更加注重生成质量、多模态生成、个性化和定制化、可解释性和透明度以及安全性和伦理性。我们有理由相信,AIGC技术将为我们的生活带来更多的创意和便利。

Web 渗透测试神器:HackBar 保姆级教程

一、介绍 HackBar 是一个用于浏览器的扩展插件,主要用于进行网络渗透测试和安全评估。它提供了一系列方便的工具和功能,可以帮助用户执行各种网络攻击和测试,包括 XSS、SQL 注入、CSRF、路径穿越等。以下是 HackBar 插件的一些主要特点和功能: 自定义请求发送:HackBar 允许用户自定义 HTTP 请求,并可以通过插件直接发送这些请求。用户可以手动构造 GET、POST、PUT、DELETE 等类型的请求,并添加自定义的 HTTP 头部、参数等信息。 编码/解码工具:HackBar 提供了各种编码和解码工具,包括 URL 编码、Base64 编码、MD5 加密等。这些工具可用于在渗透测试中对数据进行编码或解码,以绕过一些安全机制或进行数据处理。 漏洞检测:HackBar 可以帮助用户检测网站中常见的漏洞,例如 XSS、SQL 注入、CSRF 等。用户可以通过插件发送特定的测试请求,然后分析响应来确定目标网站是否存在漏洞。 Cookie 管理:HackBar 允许用户管理浏览器中的 Cookie,包括添加、编辑、删除 Cookie 等操作。这对于进行身份验证、绕过登录限制等方面的渗透测试非常有用。 参数注入:HackBar 提供了一个参数注入工具,可以帮助用户在 URL 中注入自定义的参数。用户可以使用这个工具测试网站的安全性,尝试发现潜在的漏洞。 总的来说,HackBar 是一款功能丰富、易于使用的浏览器插件,适用于进行各种网络渗透测试和安全评估任务。它提供了许多有用的工具和功能,可以帮助安全专家快速有效地发现和利用网站中的漏洞。 二、安装 HackBar 打开火狐浏览器点击右上角的三条杠,点击扩展和主题 搜索输入 HackBar 选择 V2 版本 进去点击安装即可(笔者已经安装过了) 三、使用 HackBar 3.1 加密 Encryption 对应的则是加密,展开可以发现各种加密方法 这里笔者随便输入了字符 “I Love You”加密 可以发现与其他网站上的在线工具是一致的 3.2 解密 后面的则对应着解密了 3.3 分割参数 在咱们复制好 URL 地址后点击图中的分割 URL 会自动分割参数 3.4 发送 点击 Execute 即可发送编辑好的 URL

Python-VBA函数之旅-object基类(非函数)

目录 一、object基类的常见应用场景 二、object基类使用注意事项 三、如何用好object基类? 1、object基类: 1-1、Python: 1-2、VBA: 2、推荐阅读: 个人主页:神奇夜光杯-CSDN博客 一、object基类的常见应用场景 在Python中,object函数本身并不是一个经常直接使用的函数,因为它实际上是一个内置的基类,而不是一个用于创建对象的函数,然而,object类及其子类(包括用户自定义的类)在Python编程中有广泛的应用,常见的应用场景有: 1、元编程(Metaprogramming):通过操作类和其他类型对象,你可以在运行时创建、修改或查询这些对象的行为。例如,你可以使用type()函数在运行时动态地创建新的类,这些类可以继承自其他类(包括object)并包含自定义的方法。 2、实现设计模式: object可以作为实现各种设计模式的基类。例如,你可以使用继承和多态性来实现工厂模式、单例模式或观察者模式等。 3、使用__slots__优化内存使用:通过在类中定义`__slots__`属性,你可以限制实例可以拥有的属性,这有助于减少内存使用并提高性能;`__slots__`必须是一个字符串序列,其中每个字符串对应一个有效的实例变量名。 4、自定义描述符(Descriptors): 描述符是一种具有特殊方法的类,它们可以控制对属性的访问,描述符通常用于实现属性验证、属性存储或属性的动态计算等,描述符的实现通常涉及`__get__`, `__set__`, 和 `__delete__`方法。 5、实现上下文管理器(Context Managers):通过实现`__enter__`和`__exit__`方法,你可以将对象用作上下文管理器,这允许你使用with语句来管理资源(如文件、网络连接等)的获取和释放。 6、使用弱引用(Weak References):通过weakref模块,你可以创建对对象的弱引用,这不会增加对象的引用计数,这在处理循环引用或需要跟踪但不拥有对象的情况时非常有用。 7、实现自定义的迭代器(Iterators)和生成器(Generators):通过实现`__iter__`和`__next__`方法,你可以创建自定义的迭代器类,生成器函数是创建迭代器的简便方式,它们使用yield语句来产生一系列的值。 8、多重继承与混合(Mixins):你可以使用多重继承来组合多个类的功能,混合是一种特殊的多重继承用法,其中一个小型类(mixin)被设计用来给一组不相关的类添加相同的方法,这有助于代码重用和模块化。 9、特殊的魔法方法:object类还定义了一些特殊的魔法方法(magic methods),比如`__new__`用于创建实例,`__getattribute__`用于获取属性,`__setattr__`用于设置属性等,虽然这些魔法方法通常在你需要深度控制对象的创建和属性访问时才会用到,但它们的存在为Python的面向对象编程提供了强大的灵活性。 10、多态性和接口实现:通过继承和多态性,你可以创建遵循共同接口或协议的类,这使得代码更加灵活和可维护,因为你可以使用这些类的实例而不必关心它们的具体类型。 总之,object类及其子类在Python编程中无处不在,它们是实现自定义数据结构、行为和交互的基础。 二、object基类使用注意事项 在Python中,object实际上不是一个函数,而是一个内置的基类。当你提到“使用`object`函数”时,我猜你可能是在讨论与object基类相关的一些概念或实践,以下是在使用object基类时需要注意的一些事项: 1、无需显式继承:在Python 3中,所有的类都默认继承自object,因此你不需要(也不应该)在类定义中显式地指定它,例如,`class MyClass:` 和 `class MyClass(object):` 在Python 3中是等效的。 2、重写特殊方法:object基类定义了许多特殊方法(双下划线方法),如`__init__`, `__str__`, `__repr__`, `__eq__`等,当你在自己的类中重写这些方法时,需要确保你理解它们的作用和预期的行为,不正确的实现可能会导致意外的结果或错误。 3、避免使用内置属性名:避免在你的类中使用与object或其他内置类型相同的属性名或方法名,这可能会导致冲突或意外的行为。 4、多重继承:虽然Python支持多重继承,但在使用多重继承时需要小心,因为它可能导致方法解析顺序(MRO)的问题,确保你了解Python的MRO规则,并仔细测试你的代码以确保它按预期工作。 5、元编程和反射:当你使用元编程和反射技术(如`getattr`, `setattr`, `delattr`, `hasattr`等)时,需要格外小心,这些函数允许你动态地访问和修改对象的属性,但如果不正确使用,可能会导致程序崩溃或数据损坏。 6、避免不必要的继承:虽然继承是面向对象编程中的一个重要概念,但并不意味着你应该在所有情况下都使用它。有时,使用组合(composition)而不是继承(inheritance)可能更合适,组合允许你将一个对象作为另一个对象的属性,从而避免继承层次过深或复杂的类结构。 7、使用抽象基类(ABCs):如果你正在设计一个框架或库,并希望定义一些必须被子类实现的接口,那么可以考虑使用Python的`abc`模块来定义抽象基类(Abstract Base Classes, ABCs),抽象基类允许你定义一些没有具体实现的方法,并要求子类必须提供这些方法的实现,这有助于确保你的框架或库的使用者遵循一定的规范。 8、理解类型检查:在Python中,类型检查是可选的,并且通常通过鸭子类型(duck typing)来实现,这意味着只要对象具有所需的方法或属性,就可以被视为具有特定的类型,然而,在某些情况下,你可能需要进行显式的类型检查,在使用isinstance()或type()函数进行类型检查时,需要确保你了解它们的区别和用途,并避免过度依赖类型检查来编写代码。 三、如何用好object基类? 在Python中,object作为所有类的基类,为类的设计和实现提供了强大的基础,要有效地使用object基类,需遵循以下建议: 1、理解继承:虽然Python 3中的类默认继承自object,但理解继承的概念仍然很重要;通过继承,你可以创建新的类,这些类继承自其他类(包括`object`)的属性和方法,这有助于代码重用和扩展性。 2、重写特殊方法:object类定义了许多特殊方法(如`__init__`, `__str__`, `__eq__`等),你可以在自己的类中重写这些方法以定义对象的行为,例如,重写`__str__`方法可以提供对象的字符串表示形式,这对于调试和日志记录非常有用。 3、避免不必要的继承:虽然继承是一个强大的工具,但过度使用可能导致代码复杂性和维护性的增加,在决定是否使用继承时,要仔细考虑是否真的需要继承某个类的属性和方法,或者是否可以通过组合(将对象作为另一个对象的属性)来实现所需的功能。 4、利用多态性:由于所有类都继承自object,Python支持多态性,这意味着你可以编写接受任何类型对象的函数或方法,并在运行时根据对象的实际类型来执行不同的操作,这增加了代码的灵活性和可重用性。 5、使用属性装饰器:Python提供了`@property`装饰器,它可以用于将方法转换为对象的属性,这使得你可以定义复杂的属性访问逻辑,同时保持属性的访问方式与简单属性相同,这有助于保持代码的清晰和一致性。 6、理解方法解析顺序(MRO):当使用多重继承时,理解方法解析顺序(MRO)很重要,MRO决定了当子类调用一个方法时,Python将按照什么顺序搜索基类以找到该方法的定义,了解MRO可以帮助你避免意外地覆盖或跳过方法定义。 7、设计可扩展的API:当你设计类库或框架时,考虑使用object作为基类,并定义一些抽象方法或属性,这样,其他开发者可以继承你的类并实现这些方法或属性,从而扩展你的库或框架的功能。

【百度Apollo】探索自动驾驶:新版本 Beta全新升级算法方向支持4D毫米波,引入新模型提供增量训练

🎬 鸽芷咕:个人主页 🔥 个人专栏: 《linux深造日志》《粉丝福利》 ⛺️生活的理想,就是为了理想的生活! 文章目录 引入一、背景介绍二、引入全新模型,算法检测效果显著提升2.1、更强大易用的激光雷达检测模型CenterPoint检测效果示意 2.2 Beta激光雷达检测的优势检测效果示意 三、相机检测,Yolo X+Yolo 3D更快更好用**3.1 检测效果示意 四、提供增量训练,适应多种场景4.1效果展示 五、新增支持4D毫米波5.1 检测效果示意 引入 随着自动驾驶技术的不断演进,我们很高兴地宣布 Apollo 平台的最新 Beta 版本中引入了全新的算法方向支持 4D 毫米波,并且推出了增量训练的新模型。这是一项重要的升级,旨在进一步提升自动驾驶系统的感知能力和鲁棒性。本文将深入介绍这一创新性的技术,并探讨它对自动驾驶领域的意义和潜在影响。 一、背景介绍 毫米波雷达是自动驾驶系统中常用的感知传感器之一,它能够在各种复杂的环境条件下实现高精度的目标检测和跟踪。然而,传统的毫米波雷达在处理动态场景和复杂交通情况时存在一定的局限性,例如对于高速移动目标的准确跟踪以及对于复杂道路场景的精细感知能力有待提升。 为了克服这些挑战并进一步提升毫米波雷达的性能,我们团队在新版本的 Apollo Beta 中引入了 4D 毫米波技术,并结合增量训练的方法,实现了对毫米波雷达算法的全新升级。 二、引入全新模型,算法检测效果显著提升 在Apollo 8.0时,我们联合Paddle 3D提供了端到端的自动驾驶模型开发解决方案,覆盖了从自动驾驶数据集到模型训练、模型评估和模型导出的算法开发全流程。 Beta在8.0版本基础上,对算法模型进行了更新升级,同时还在其他方面做了优化,模型泛化性和效果都得到了显著的提升。 2.1、更强大易用的激光雷达检测模型CenterPoint 在激光雷达检测方向,我们采用了新的CenterPoint模型替代了原来的CNNSeg模型,并依托于百度百万级的自动驾驶数据对模型进行了针对性优化,检测精度和召回率远超原CNNSeg模型,可以提供复杂城市道路场景下实时、准确、稳定的3D目标检测效果。 检测效果示意 2.2 Beta激光雷达检测的优势 升级优化后,Beta激光雷达检测具备以下优势: 更好的检测效果,更强的泛化能力。 Beta使用百万真实路测数据对CenterPoint进行训练和优化,精度和召回率相较于应用最多的CNNSeg模型提升了20%+,检测能力和泛化能力显著提升。提供了常见城市道路标识的检测能力。 Beta包括了锥桶、水马、防撞桶、指示牌等目标的检测能力,极大地保障了自动驾驶的安全性。显著提升了近处行人目标和小目标的召回率。 Beta对前后处理、配置、模型推理进行了针对性调优和处理,修复了推理端结果不一致问题,行人和小目标召回率提升。增强了跟踪的稳定性。 Beta优化了障碍物点云的获取逻辑,使CenterPoint可输出准确Polygon信息,进一步增强了跟踪的稳定性。大幅降低模型推理耗时和GPU占用。 Beta提供了Tensorrt + fp16推理 & Int8推理的功能和教程,在保持模型检测效果前提下,大幅降低了模型的推理耗时和GPU占用,在低算力平台运行可满足实时性要求。降低训练开发成本,提升易用性。 Beta开源了CenterPoint的训练代码,新增了以下功能:冻结网络层训练、fp16训练、适配自定义数据集等。开发者可以根据教程,使用公开/自定义数据集快速展开训练,大大降低了用户的训练开发成本,开发者可快速方便地开展模型训练部署、增量训练、Apollo感知赛事等任务。 检测效果示意 三、相机检测,Yolo X+Yolo 3D更快更好用** 在相机检测方向,视觉感知上我们使用了Yolo X+Yolo 3D两阶段模型替换了原来的Yolo单阶段模型,使得Beta的相机检测更易用、更好用,同时速度更快、效果更好。 具体来说,更换模型后Beta在相机检测方面进行了以下优化升级: 更易用。 将单目3D目标检测任务完全解耦为2D框检测与3D姿态回归两个任务,能够满足开发者以插件的方式快速替换任意2D、3D模型的需求;(*Yolo系列模型部署时只需要简单适配前后处理即可实现模型的快速替换)更好用。 开源了Yolo X及Yolo 3D适配Apollo后的训练代码,并提供给开发者在开源数据及内部数据上的预训练模型,开发者可根据需求具体场景需求对模型进行Finetune;更快速。 新推出的Onnx推理框架提供了TensorRT的C++接口来完成模型部署,单阶段模型推理时间可降至1ms,大幅度提升了模型推理速度,助力开发者将自己的模型部署上车;更强大。 2D、3D模型均使用百万量级真实路测数据训练,在有效提升城市域全场景下目标的检测能力的同时二阶段预测出的目标朝向更加稳定、尺寸更加准确,相较于之前的Yolo模型在3D评测集上精度和召回率均提升了17%+。 3.

人脸识别系统架构

目录 1. 系统架构 1.1 采集子系统 1.2 解析子系统 1.3 存储子系统 1.4 比对子系统 1.5 决策子系统 1.6 管理子系统 1.7 应用开放接口 2. 业务流程 2.1 人脸注册 2.2 人脸验证 2.2.1 作用 2.2.2 特点 2.2.3 应用场景 2.3 人脸辨识 2.3.1 作用 2.3.2 特点 2.3.3 应用场景 3. 技术方案 3.1 本地离线方案 3.2 云端服务方案 4. 技术局限 4.1 相似脸较难解决 4.2 算法偏见问题 4.3 算法鲁棒性及性能问题 4.4 年龄变化的影响 4.5 安全性问题 4.6 工程落地问题 5. 标准下载 1. 系统架构 《GB∕T 41772-2022 信息技术 生物特征识别 人脸识别系统技术要求》定义人脸识别系统由采集子系统、解析子系统、存储子系统、比对子系统、决策子系统、管理子系统以及应用开放接口等组成,其系统架构下图所示。 1.1 采集子系统 用于人脸图像或视频的采集,包括人脸采集设备以及执行人脸采集过程所需的任何子过程。

C语言:项目实践(贪吃蛇)

前言: 相信大家都玩过贪吃蛇这款游戏吧,贪吃蛇是久负盛名的游戏,它也和俄罗斯方块,扫雷等游戏位列经典游戏的行列,那贪吃蛇到底是怎么实现的呢? 今天,我就用C语言带着大家一起来实现一下这款游戏,从设计到代码的实现可以帮助我们提升编程能力和逻辑能力,项目适合: C语言已经学完,有一定的代码能力,初步接触数据结构中的链表,因为贪吃蛇是基于链表来实现的。 这里是我们在实现贪吃蛇过程中必须要使用到的一些知识点:C语⾔函数、枚举、结构体、动态内存管理、预处理指令、链表、Win32 API等,至于Win32 API没听过也不要紧,我们下面就会详细讲解到它的使用方法。 目录 一、游戏最终目标二、Win32 API介绍1.Win32 API2.控制台程序3.控制台屏幕上的坐标COORD4.GetStdHandle5.GetConsoleCursorInfo6.SetConsoleCursorInfo7.SetConsoleCursorPosition8.GetAsyncKeyState 三、贪吃蛇游戏设计与分析1.地图2.setlocale函数3.宽字符的打印4.地图坐标5.蛇身和食物6.数据结构设计7.游戏流程设计8.核心逻辑实现分析 四、游戏开始(GameStart)1.初始化游戏主逻辑2.打印欢迎界面3.创建地图4.创建蛇身5.创建第一个食物 五、游戏运行(GameRun)1.打印帮助信息(PrintHelpInfo)2.蛇身移动(SnakeMove)3.判断下一个节点是否是食物(NextIsFood)4.吃食物(EatFood)5.不是食物(NoFood)6.撞到墙(KillByWall)7.撞到自己(KillBySelf)8.游戏结束(GameEnd) 六、完整代码实现 一、游戏最终目标 使用C语言在Windows环境的控制台中模拟实现经典小游戏贪吃蛇。 实现基本的功能: 贪吃蛇地图绘制蛇吃食物的功能 (上、下、左、右方向键控制蛇的动作)蛇撞墙死亡蛇撞自身死亡计算得分蛇身加速、减速暂停游戏正常退出游戏 游戏效果演示 --- 二、Win32 API介绍 本次实现贪吃蛇会使用到的一些Win32 API知识,接下来我们就学习一下。 1.Win32 API Windows 这个多作业系统除了协调应用程序的执行、分配内存、管理资源之外, 它同时也是⼀个很大的服务中心,调用这个服务中心的各种服务(每一种服务就是一个函数),可以帮应用程序达到开启视窗、描绘图形、使用周边设备等目的,由于这些函数服务的对象是应用程序(Application), 所以便称之为 Application Programming Interface,简称 API 函数。WIN32 API也就是Microsoft Windows32位平台的应用程序编程接口。 2.控制台程序 平常我们运行起来的⿊框程序其实就是控制台程序。 我们可以使用cmd命令来设置控制台窗口的长宽:设置控制台窗⼝的大小,30行,100列。 mode con cols=100 lines=30 参考:mode命令 也可以通过命令设置控制台窗口的名字: title 贪吃蛇 参考:title命令 这些能在控制台窗口执行的命令,也可以调用C语言函数system来执行。例如: #include <stdio.h> int main() { //设置控制台窗⼝的⻓宽:设置控制台窗⼝的⼤⼩,30⾏,100列 system("mode con cols=100 lines=30"); //设置cmd窗⼝名称 system("title 贪吃蛇"); return 0; } 3.控制台屏幕上的坐标COORD COORD 是Windows API中定义的一个结构体,表示一个字符在控制台屏幕幕缓冲区上的坐标,坐标系(0,0) 的原点位于缓冲区的顶部左侧单元格。

【Python的魅力】:利用Pygame实现游戏坦克大战——含完整源码

文章目录 一、游戏运行效果二、代码实现2.1 项目搭建2.2 加载我方坦克2.3 加载敌方坦克2.4 添加爆炸效果2.5 坦克大战之音效处理 三、完整代码 一、游戏运行效果 二、代码实现 坦克大战游戏 2.1 项目搭建 本游戏主要分为两个对象,分别是我方坦克和敌方坦克。用户可以通过控制我方的坦克来摧毁敌方的坦克保护自己的“家”,把所有的敌方坦克消灭完达到胜利。敌方的坦克在初始的时候是默认 5 个的(这可以自己设置),当然,如果我方坦克被敌方坦克的子弹打中,游戏结束。从面向对象分析该项目有以下类组成: 主类:主要包括开始游戏、结束游戏的功能。 class MainGame(): def __init__(self): pass # 开始游戏 def startGame(self): pass # 结束游戏 def endGame(self): pass 坦克类:主要包括坦克的创建、显示、移动及射击的功能。 class Tank(): def __init__(self): pass # 移动 def move(self): pass # 射击 def shot(self): pass # 展示坦克的方法 def displayTank(self): pass 我方坦克类继承坦克类,主要包括创建、与敌方坦克的碰撞方法。 # 我方坦克 class MyTank(Tank): def __init__(self): pass 敌方坦克类继承坦克类,主要包括创建、与我方坦克碰撞方法。 # 敌方坦克 class EnemyTank(Tank): def __init__(self): pass 子弹类:主要包括子弹的创建、显示及移动的功能。 # 子弹类 class Bullet(): def __init__(self): pass # 移动 def move(self): pass # 展示子弹的方法 def displayBullet(self): pass 墙壁类:主要包括墙壁的创建、显示的功能。 class Wall(): def __init__(self): pass # 展示墙壁的方法 def displayWall(self): pass 爆炸效果类:主要展示爆炸效果。 class Explode(): def __init__(self): pass # 展示爆炸效果的方法 def displayExplode(self): pass 音效类:主要播放音乐。 class Music(): def __init__(self): pass # 播放音乐 def play(self): pass 显示游戏窗口

【C++】:const成员,取地址及const取地址操作符重载

目录 一,const成员二,取地址及const取地址操作符重载 一,const成员 将const修饰的“成员函数”称之为const成员函数,const修饰类成员函数,实际修饰该成员函数隐含的this指针,表明在该成员函数中不能对类的任何成员进行修改。 使用方式:规定在函数后面加 const。 看看下面的几段代码: 代码1:对象d1是const类型,Print函数后面没有const,运行结果报错。 class Date { public: Date(int year, int month, int day) { _year = year; _month = month; _day = day; } //d1.Print(&d1); d1对象类型是 const Date* 只读 void Print() //Date* const this 可读可写 权限放大了 { cout << _year << "-" << _month << "-" << _day << endl; } private: int _year; int _month; int _day; }; int main() { //d1是const对象,d1对象类型是const Date* const Date d1(2024, 4, 14); d1.

数据复制的艺术:深拷贝与浅拷贝在JavaScript中的实现方式

前言 📫 大家好,我是南木元元,热爱技术和分享,欢迎大家交流,一起学习进步! 🍅 个人主页:南木元元 目录 赋值和拷贝 浅拷贝与深拷贝区别 浅拷贝的实现方式 1.Object.assign() 2.扩展运算符 3.Array.prototype.slice() 4.Array.prototype.concat() 5.手写实现浅拷贝 深拷贝的实现方式 1.JSON.stringify() 2.函数库lodash 3.手写实现深拷贝 结语 赋值和拷贝 js中的数据类型分为两大类: 基本数据类型引用数据类型 基本数据类型保存在栈里面,可以直接访问它的值,赋值时,会完整复制变量值。 let a = 10; let b = a; // 赋值 b = 20; console.log(a); // 10 上面代码中,两个变量保存了两个不同的内存地址,所以b的改变不会引起a的变化。过程如下: 而引用数据类型保存在堆里面,栈里面保存的是地址,通过栈里面的地址去访问堆里面的值。 var obj1 = {} var obj2 = obj1; obj2.name = "yuanyuan"; console.log(obj1.name); // yuanyuan 上面代码在赋值时,复制的是栈中的引用地址,两个变量指向堆内存中的同一个对象,所以更改obj2会对obj1产生影响。赋值过程如下: 这是直接赋值的情况,要想两个值互不影响,就需要进行拷贝,js中的拷贝分为浅拷贝和深拷贝。 浅拷贝与深拷贝区别 浅拷贝是按位拷贝对象,它会创建一个新对象,如果属性是基本类型,拷贝的就是基本类型的值,如果属性是引用类型,拷贝的就是内存地址(只拷贝一层)。如果其中一个对象改变了这个地址,就会影响到另一个对象。 深拷贝是将一个对象从内存中完整的拷贝一份出来,从堆内存中开辟一个新的区域存放新对象,且修改新对象不会影响原对象。 浅拷贝的实现方式 1.Object.assign() Object.assign()方法用于将所有可枚举的自有属性从一个或多个源对象复制到目标对象,并返回这个目标对象。可以使用它来实现浅拷贝。 // 初始对象 const obj = { name: 'yuanyuan', des: { age: 21, gender: 'male' } }; // 使用 Object.

利用Lama Cleaner本地实现AIGC试玩:擦除对象、替换对象、更换风格等等

目录 一、安装二、擦除功能1. LaMa模型实操实例一:去除路人实操实例二:去水印实操实例三:老照片修复 2. LDM模型3. ZITS模型4. MAT模型5. FcF模型6. Manga模型 三、替换对象功能1. sd1.52. sd23. anything44. realisticVision1.45. 四个模型的对比 四、进阶版功能1. Paint By Example2. Stable Diffusion with ControlNet3. Instruct Pix2pix 五、遇到的问题 Lama Cleaner是一个免费的、开源的、完全自托管的修复工具,里面提供了很多最前沿的AIGC模型。可以使用它从图片中删除任何不需要的物体、缺陷、人物,或删除和替换图片上的任何内容。本文章详细介绍了该工具的所有功能,并体验了下每个功能的实际效果。 github:https://github.com/Sanster/lama-cleaner 官方使用文档:https://lama-cleaner-docs.vercel.app/ 一、安装 # 如果电脑带GPU,为了使用GPU首先安装与cuda版本相对应的pytorch,比如cuda11.7的 pip install torch==1.13.1+cu117 torchvision==0.14.1 --extra-index-url https://download.pytorch.org/whl/cu117 # pip直接安装 pip install lama-cleaner 本文安装时版本更新到1.2.4 二、擦除功能 下方擦除功能所需要的模型全部上传至夸克网盘(链接:https://pan.quark.cn/s/370b455924ab,提取码:SNrE),在github下载失败时可手动网盘下载至规定路径。 找到lama-cleaner.exe的路径:C:\Users\zhouying\AppData\Roaming\Python\Python39\Scripts(不同电脑路径不同) cd C:\Users\zhouying\AppData\Roaming\Python\Python39\Scripts lama-cleaner --model=lama --device=cuda --port=8080 device如果没有gpu:--device=cpu。 默认模型权重下载后保存的路径为C盘,可在上面的命令后再加一个参数--model-dir=F:/lama-cleaner/checkpoints用于指定保存权重文件的路径。 该命令会自动下载AI模型到本地(也可手动下载big-lama.pt到下图红框中的路径),然后浏览器打开http://localhost:8080/就可以使用了。 1. LaMa模型 github:https://github.com/saic-mdal/lama paper:Resolution-robust Large Mask Inpainting with Fourier Convolutions lama是默认模型,模型196MB,性能已经挺不错了。 实操实例一:去除路人 实操实例二:去水印 涂抹过程中可以长按Ctrl键进行多处涂抹

Android 开发 OCR 拍照 + ML Kit 识别文字 巨详细全部代码教程

下面是整个详解步骤过程 效果图一、OCR的含义二、什么是ML Kit三、官网步骤教程1、添加依赖2、创建TextRecognizer3、输入图像4、处理图像 四、实际代码案例Demo如下:1、Main.xml1、Main.java 效果图 流程:点击拍照,调取设备相机拍照,获取图片显示到页面,提取照片内的文字 一、OCR的含义 ocr是Optical Character Recognition(光学字符识别)是指电子设备(例如扫描仪或数码相机)检查纸上打印的字符,通过检测暗、亮的模式确定其形状,然后用字符识别方法将形状翻译成计算机文字的过程 二、什么是ML Kit 官网奉上 ML Kit是一个由Google开发的跨平台移动SDK(Android和iOS)。它带来了谷歌的端上机器学习能力。 ML Kit所有在端上运行的API允许实时和离线功能。这也意味着这些功能在离线模式下也可用。 ML Kit可以识别超过100种语言的文本,包括原生拼写及罗马转写系统,比如汉语、俄语、印地语、英语、希腊语等。点击查看支持语言的完整列表 三、官网步骤教程 本文跟着官网教程走,如下图: 1、添加依赖 注意此 API 需要 Android API 级别 21 或更高版本。确保应用的 build file 使用值 21 或更高。minSdkVersion 在项目级文件中,请确保在 your 和 sections 中都包含 Google 的Maven 存储库。build.gradlebuildscriptallprojects将 ML Kit Android 库的依赖项添加到模块的应用级 gradle 文件,该文件通常为:app/build.gradle 本文讲的是中文识别,所以只导入了中文依赖包,你可以根据自己所需选择导入的依赖包 // To recognize Chinese script implementation 'com.google.mlkit:text-recognition-chinese:16.0.0' 2、创建TextRecognizer 因为本文是中文,所以使用的中文脚本库 ChineseTextRecognizerOptions build = new ChineseTextRecognizerOptions.Builder().build(); TextRecognizer recognizer = TextRecognition.getClient(build); 3、输入图像 图像来源有:

【c++】探究C++中的list:精彩的接口与仿真实现解密

🔥个人主页:Quitecoder 🔥专栏:c++笔记仓 朋友们大家好,本篇文章来到list有关部分,这一部分函数与前面的类似,我们简单讲解,重难点在模拟实现时的迭代器有关实现 目录 `1.List介绍``2.接口函数``operations` `3.模拟实现``3.1基本框架``3.2 list的基本函数``3.3迭代器的封装和实现``++等重载函数的实现``与list的关联` `3.4list函数完善``3.5迭代器进一步完善``const迭代器``合并两种迭代器` 1.List介绍 list是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代list的底层是双向链表结构,双向链表中每个元素存储在互不相关的独立节点中,在节点中通过指针指向其前一个元素和后一个元素list与forward_list非常相似:最主要的不同在于forward_list是单链表,只能朝前迭代,已让其更简单高效与其他的序列式容器相比(array,vector,deque),list通常在任意位置进行插入、移除元素的执行效率更好与其他序列式容器相比,list和forward_list最大的缺陷是不支持任意位置的随机访问,比如:要访问list的第6个元素,必须从已知的位置(比如头部或者尾部)迭代到该位置,在这段位置上迭代需要线性的时间开销;list还需要一些额外的空间,以保存每个节点的相关联信息(对于存储类型较小元素的大list来说这可能是一个重要的因素) 所以list本质就是我们的双向循环链表,我们接下来看它的接口函数 2.接口函数 构造函数 这里的构造函数与vector类似 Default constructor (构造一个空的 std::list): std::list<int> myList1; // 创建一个空的整型链表 Fill constructor (构造一个有特定数量元素且每个元素都有相同初始值的 std::list): std::list<int> myList2(5, 10); // 创建一个有5个元素的链表,每个元素都初始化为10 Range constructor (从另一个迭代器定义范围的容器中构建 std::list): std::vector<int> myVector{1, 2, 3, 4, 5}; std::list<int> myList3(myVector.begin(), myVector.end()); // 使用vector的范围来初始化链表 Copy constructor (使用另一个 std::list 来构造一个新的 std::list, 是副本): std::list<int> myOriginalList{1, 2, 3, 4, 5}; std::list<int> myList4(myOriginalList); // 使用另一个list来初始化这个新的list 每个构造函数都有它们独特的用途,可以根据具体需要选择合适的构造函数进行对象的创建和初始化。 默认构造函数创建一个没有任何元素的空链表。填充构造函数允许创建一个包含特定数量相同值的元素的链表。范围构造函数可以从任何提供迭代器接口的其他容器复制元素。拷贝构造函数创建了一个当前list的副本。 填充构造函数前面的explicit关键字表明这个构造函数不能用于隐式转换或复制初始化,它需要直接调用来构造对象。其他构造函数则根据是否带有explicit关键字来决定是否能用于隐式转换或复制初始化 迭代器 迭代器用来遍历链表,下面是迭代器的简单使用 list<int> lt = { 10,20,30,40,50 }; list<int>::iterator i1 = lt.