autodl 上 使用 LLaMA-Factory 微调 中文版 llama3

autodl 上 使用 LLaMA-Factory 微调 中文版 llama3 环境准备创建虚拟环境下载微调工具 LLaMA-Factory下载 llama3-8B开始微调测试微调结果模型合并后导出vllm 加速推理 环境准备 autodl 服务器: https://www.autodl.com/console/homepage/personal 基本上充 5 块钱就可以搞完。 强烈建议选 4090(24G),不然微调的显存不够。 我们用 LoRA 微调,至少得 20G(8B模型)。 微调工具: https://github.com/hiyouga/LLaMA-Factory.git 模型: https://www.modelscope.cn/LLM-Research/Meta-Llama-3-8B-Instruct.git 创建虚拟环境 conda activate LLaMA-Factory 上传中文微调 dpo_zh.json 数据: https://www.123pan.com/s/cD4cjv-kvgVh.html提取码: NpsA 下载微调工具 LLaMA-Factory git clone https://github.com/hiyouga/LLaMA-Factory.git cd LLaMA-Factory pip install -e .[metrics] # 下载全部依赖 下载 llama3-8B # pip install modelscope import torch from modelscope import snapshot_download, AutoModel, AutoTokenizer import os model_dir = snapshot_download('LLM-Research/Meta-Llama-3-8B-Instruct', cache_dir='/root/autodl-tmp', revision='master') 模型路径:/root/autodl-tmp/LLM-Research/Meta-Llama-3-8B-Instruct

最全IDEA 2024 配置 Maven 创建 Spring Boot 项目,那些年Java面试官常问的知识点

最后 分享一些资料给大家,我觉得这些都是很有用的东西,大家也可以跟着来学习,查漏补缺。 《Java高级面试》 《Java高级架构知识》 《算法知识》 本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录 需要这份系统化的资料的朋友,可以点击这里获取 Maven 安装配置 Maven 配置 Maven 仓库(仓库路径、阿里云下载) IDEA 配置 Maven IDEA 创建 springboot 项目 在新电脑上配环境总是要不停的百度,简单记录一下。。。 Maven ======================================================================== 安装配置 Maven 前提:已经安装好 Java 运行环境,否则配置不能成功; cmd 输入 java -version 可以看到 java 版本号再做下面的; 这里下载各个版本的Maven:http://archive.apache.org/dist/maven/maven-3/ 根据 SpringBoot 官网文档,Mave 版本需要 3.3 及以上; 下载后,解压,将 bin 目录配置到环境变量中: 右键我的电脑-属性-高级系统设置-环境变量-系统变量-Path; cmd 里输入:mvn -v;提示如下则配置成功; 配置 Maven 仓库(仓库路径、阿里云下载) 所谓的仓库就是用于存放项目需要的 jar 包的,只要配好一个仓库,以后的项目都可以去使用这个仓库里的 jar 包。 配置仓库位置:打开 Maven 根目录下的 conf/setting.xml; Ctrl + F 搜索 <localRepository>,将默认路径修改为你要配置的路径(不要放到 C 盘); 配置阿里云下载:还是在 Maven 根目录下的 conf/setting.

ZooKeeper【部署 01】单机版安装+配置+添加到service服务+开机启动配置

学习路线: 这个方向初期比较容易入门一些,掌握一些基本技术,拿起各种现成的工具就可以开黑了。不过,要想从脚本小子变成黑客大神,这个方向越往后,需要学习和掌握的东西就会越来越多以下是网络渗透需要学习的内容: 网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。 需要这份系统化资料的朋友,可以点击这里获取 一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长! vim /etc/profile.d/my_env.sh # 1.添加 ZOOKEEPER\_HOME 和 PATH export ZOOKEEPER\_HOME=/usr/local/zookeeper export PATH=$PATH:$ZOOKEEPER\_HOME/bin # 2.使得配置的环境变量立即生效: # 首先是要赋权限【只操作一次就行】 chmod +x /etc/profile.d/my_env.sh source /etc/profile.d/my_env.sh # 3.验证是否生效 echo ${ZOOKEEPER\_HOME} /usr/local/zookeeper zookeeper配置文件: # 进入${ZOOKEEPER\_HOME}/conf/ 目录下 拷贝配置样本并进行修改 cp zoo_sample.cfg zoo.cfg vim zoo.cfg # ------------以下为配置文件内容------------ # 指定数据存储目录和日志文件目录(目录不用预先创建) dataDir=/usr/local/zookeeper/data dataLogDir=/usr/local/zookeeper/log # 以下使用默认值 tickTime=2000 initLimit=10 syncLimit=5 clientPort=2181 配置项说明: dataDir:zk用于存储内存数据库快照的目录。如果不指定dataLogDir参数,则数据库更新的事务日志也将会存储在该目录下。dataLogDir:指定zk事务日志的存储目录。tickTime: zk中使用的基本时间单元,单位为毫秒,用于控制心跳和超时,比如session超时:N*tickTime。更低的tickTime值可以更快的发现超时问题。initLimit:用于集群,zk集群中follower初始化连接到leader时,最长能忍受多少个tickTime,以tickTime的倍数来表示,默认值为10,即为20s。syncLimit:用于集群,用于配置leader和follower间进行心跳检测的最大超时时间。如果在设置的时间内followers无法与leader进行通信,那么follower将会被丢弃。以tickTime的倍数来表示,默认值为5,即10s。clientPort:服务器监听客户端连接的端口,默认值为2181maxClientCnxns:限制单个客户端与单台服务之间的并发连接数,默认值为60,设置为0则不限制。autopurge.snapRetainCount:配置zk在自动清理的时候需要保存的数据文件快照的数量和对应的事务日志文件,默认为3。autopurge.purgeInterval:和autopurge.snapRetainCount配置使用,用于配置zk自动清理文件的频率,默认为1小时,即默认开启自动清理功能,设置为0,则表示禁用清理功能。 3.启动 命令启动: # zookeeper服务命令 zkServer.sh [--config <conf-dir>] {start|start-foreground|stop|version|restart|status|print-cmd} # 启动 zkServer.sh start 配置开机启动: # 1.

android中Room数据库的基本使用

还在使用原生的sqllite?有这么清爽且稳如狗的room为啥不用呢? Room是Google官方推荐使用的数据库,相比较某些优秀数据库框架来说,不用过于担心某天库会停止维护,且访问数据库非常流畅,并且提供了与常规的ORM框架一样,通过添加编译期注解来进行表和字段的配置,譬如@Database、@Dao、@Entity、@Query、@Insert、@Update、@Detele等的注解,可以使用简单代码实现相比以前SQLite更复杂的代码的效果,这点儿有点儿类似于java世界里的mybatis。总而言之, Room功能强大,速度和稳定性不弱,还简单易用,算得上是一个优秀的数据库。 PS: Demo以kotlin代码为例,kotlin最近刚在学O.o?java应该也是类似的。插入代码时没有看到kotlin语言选项,代码标识可能显示js,复制代码注意包名~ Demo展示效果: 架构组件: LiveData、ViewModel 和 Room LiveData:一种可监测的数据存储器类。务必保存/缓存最新版本的数据,并在数据发生变化时通知其监测者。LiveData 具有生命周期感知能力。界面组件只是监测相关数据,不会停止或恢复监测。LiveData 将自动管理所有这些操作,因为它在监测时可以感知相关的生命周期状态变化。ViewModel:充当存储库(数据)和界面之间的通信中心。对于界面而言,数据来源不再是一个需要关注的问题。ViewModel 实例在重新创建 activity/fragment 后仍然存在。存储库:您创建的类,主要用于管理多个数据源。实体:使用 Room 时用于描述数据库表的带注解的类。Room 数据库:可简化数据库工作,并充当 SQLite 底层数据库的接入点(隐藏 SQLiteOpenHelper)。它使用 DAO 向 SQLite 数据库发出查询请求。SQLite 数据库:设备上的存储空间。Room 持久性库会为您创建和维护此数据库。DAO:数据访问对象。从 SQL 查询到函数的映射。在使用 DAO 时,您需要调用相应方法,其余操作均由 Room 完成。 依赖添加: 在app(应用模块)下的build.gradle(app)中添加 apply plugin: 'kotlin-kapt' dependencies { // ... 省略无关 // room implementation "androidx.room:room-runtime:$rootProject.roomVersion" implementation "androidx.room:room-ktx:$rootProject.roomVersion" kapt "androidx.room:room-compiler:$rootProject.roomVersion" androidTestImplementation "androidx.room:room-testing:$rootProject.roomVersion" } 在项目下的build.gradle(project)中添加 ext { roomVersion = '2.1.0-alpha06' //... 省略无关 } 项目结构: 使用步骤: 1.创建entity 创建一个Kotlin类,用于表示数据库中的一个表,表名为"word_table"。 import androidx.

一文实现Llama 3 图片理解能力微调(XTuner+LLaVA 版)

本次实验基于 Llama3-8B-Instruct 和 XTuner 团队预训练好的 Image Projector 微调自己的多模态图文理解模型 LLaVA。实验平台为InternStudio,实验所用的显存为24G。 =============目录============ 一、总体步骤 二、可能遇到的问题 三、测试效果 四、部分Q&A =============正文============ 一、总体步骤 参考Llama3-Tutorial/docs/llava.md at main · kv-chiu/Llama3-Tutorial · GitHub 本文实现时用的是24G显存。另外,也测试了80g(1卡A100),2*80g(2卡A100)。共三种情况。 二、可能遇到的问题 1. 输入xtuner train命令训练时,报错“RuntimeError: operator torchvision::nms does not exist” 原因:torchvision版本有问题 解决:通过“conda update torchvision -c pytorch”命令再次更新 如果再次报错,可以尝试“pip install --upgrade torchvision”再次更新,安装成功 2.训练时,即使用了deepspeed参数,仍然报错out of memory 原因:显存不够 思路一:用lmdeploy里的量化技术。结果:不可行。因为该训练命令是在xtuner框架下的,不支持。 思路二:修改deepspeed的参数命令如下: xtuner train /root/Llama3-Tutorial/configs/llama3-llava/llava_llama3_8b_instruct_qlora_clip_vit_large_p14_336_lora_e1_finetune.py --work-dir /root/model/llama3_llava_pth --deepspeed deepspeed_zero2_offload 结果:可行(原理解释参照下文的第四部分Q&A) 3.测试没有添加export命令,直接跑xtuner 运行llava模型,会报错。 解决:再次添加教程里的export命令即可(解释见Q&A) 3.用24g显存训练了4小时30分钟左右,日志显示保存pth文件成功。但实际文件找不到。 解决:云盘空间不足,自动删除了,当时是45g。扩容到75g后重跑即可。 总结教训:这个其实是非常惨重的教训。花了了很长时间去训练的模型前功尽弃。 延伸问题: 1)如何预估训练时要用的硬盘空间(乃至内存、显存、时间等资源) 2)后续成功后,看到生成的pth文件并没有大到会爆了硬盘空间的程度,为什么仍然会磁盘空间不足? (见Q&A) 4.用2*80g(2卡A100)和80g(A100)运行训练时,报错“typeError: All input tensors need to be on the same GPU, but found some tensors to not be on a GPU”

微信公众号 - Java推送小程序订阅消息给用户_java 通过微信公众号发送订阅通知

难道这样就够了吗?不,远远不够! 提前多熟悉阿里往年的面试题肯定是对面试有很大的帮助的,但是作为技术性职业,手里有实打实的技术才是你面对面试官最有用的利器,这是从内在散发出来的自信。 备战阿里时我花的最多的时间就是在学习技术上,占了我所有学习计划中的百分之70,这是一些我学习期间觉得还是很不错的一些学习笔记 我为什么要写这篇文章呢,其实我觉得学习是不能停下脚步的,在网络上和大家一起分享,一起讨论,不单单可以遇到更多一样的人,还可以扩大自己的眼界,学习到更多的技术,我还会在csdn、博客、掘金等网站上分享技术,这也是一种学习的方法。 今天就分享到这里了,谢谢大家的关注,以后会分享更多的干货给大家! 本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录 需要这份系统化的资料的朋友,可以点击这里获取 官方文档 注意低版本订阅消息api必须在点击事件中触发,一般可做成显示一个按钮,友好的提示用户,然后再让用户点击按钮去手动触发订阅。 我这里就随便找了个页面在一个点击事件上添加了授权弹窗,不要纠结命名,页面是前端做的(疯狂甩锅ing)。 事件定义 微信开发者工具中的效果 真机效果 三、引用第三方sdk,集成订阅消息推送 我这儿是集成订阅消息推送到已有的系统消息中,通过配置是否发送订阅消息进行分发,具体实现各工程不一样,我这儿就不展示了。 1、pom引入第三方sdk 引入第三方sdk,我们就只需要封装好消息发送的核心代码,微信相关的token及其他信息的维护就交给sdk,我们不用关注(但是原理要知道)。 sdk的作者:GitHub com.github.binarywang weixin-java-miniapp 4.1.0 2、核心代码(有注释) import cn.binarywang.wx.miniapp.api.WxMaService; import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl; import cn.binarywang.wx.miniapp.bean.WxMaSubscribeMessage; import cn.binarywang.wx.miniapp.config.impl.WxMaDefaultConfigImpl; import com.coyee.core.log.Logger; import org.springframework.stereotype.Component; import java.util.ArrayList; @Component public class WeChatMessageHelperTest { private static WxMaService wxMaService = new WxMaServiceImpl(); /** * 发送小程序订阅消息 * @param appletsSubType 小程序类型(developer为开发版、trial为体验版、formal为正式版) * @param appSubTempId 订阅消息模板id * @param appSubPagePath 跳转小程序地址 * @param appletsAppid 小程序appId * @param appletsSecret 小程序secret * @param appletsSubToken 小程序token * @param appletsSubAesKey 小程序EncodingAESKey * @param appletsSubDataFormat 数据格式 * @param wxMaSubMsgList 消息列表 * @param userIds 接收用户id * @return void * @version V1.

已解决java.lang.AbstractMethodError: 抽象方法错误的正确解决方法,亲测有效!!!

已解决java.lang.AbstractMethodError: 抽象方法错误的正确解决方法,亲测有效!!! 目录 问题分析 报错原因 解决思路 解决方法 更新和重新编译依赖 确认类和接口的版本一致性 类加载器配置检查 总结 问题分析 java.lang.AbstractMethodError通常在尝试调用一个抽象方法的实现时抛出,但是该实现在运行时并未被找到。这个错误大多发生在接口或者抽象类有改动之后,依赖它们的实现类没有相应更新的情况下。 报错原因 抽象方法错误主要由以下原因引起: 在接口或抽象类中新增了抽象方法,而依赖于这些接口或类的现有实现没有更新对应的方法实现。类和接口的不同版本间的兼容问题,通常是因为编译时依赖的版本和运行时使用的版本不一致。类加载器的问题,可能导致旧版本的类或接口被错误地加载。 解决思路 解决AbstractMethodError的思路包括: 确保所有的依赖库都是最新的,并且与项目中使用的API版本一致。重新编译所有受影响的代码以确保所有的方法实现都是最新的。检查并修改类加载器的设置,确保正确的类被加载。 解决方法 更新和重新编译依赖 确保所有依赖的库和项目组件都使用最新的版本,并重新编译整个项目。 # 示例:使用Maven更新依赖并重新编译项目 mvn clean install 确认类和接口的版本一致性 检查项目中使用的所有类和接口的版本,确保它们在编译时和运行时是一致的。 # 示例:检查JAR文件的版本 java -jar jarfilename.jar 类加载器配置检查 在复杂的Java应用环境中,特别是在使用多个类加载器的环境中,确保没有类加载器冲突。 // 示例代码:打印类加载器信息 Class<MyClass> clazz = MyClass.class; System.out.println(clazz.getClassLoader()); 总结 java.lang.AbstractMethodError是由于运行时环境中的类或接口与编译时的版本不一致导致的。通过确保所有组件的一致性、更新和重新编译依赖以及检查类加载器配置,可以有效地解决这种错误。维护清晰的依赖管理和兼容性检查是预防此类错误的关键措施,有助于提高项目的可维护性和稳定性。 以上是此问题报错原因的解决方法,欢迎评论区留言讨论是否能解决,如果本文对你有帮助 欢迎 关注 、点赞 、收藏 、评论, 博主才有动力持续记录遇到的问题!!! 博主v:XiaoMing_Java 📫作者简介:嗨,大家好,我是 小明(小明Java问道之路),互联网大厂后端研发专家,2022博客之星TOP3 / 博客专家 / CSDN后端内容合伙人、InfoQ(极客时间)签约作者、阿里云签约博主、全网5万粉丝博主。 🍅 文末获取联系 🍅 👇🏻 精彩专栏推荐订阅收藏 👇🏻 专栏系列(点击解锁) 学习路线(点击解锁) 知识定位 🔥Redis从入门到精通与实战🔥

fastjson2使用

说明:fastjson2是一个性能极致并且简单易用的Java JSON库(官方语),本文介绍在Spring Boot项目中如何使用fastjson2。 创建项目 首先,创建一个Maven项目,引入fastjson2依赖,如下: <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.7.12</version> <relativePath/> </parent> <groupId>com.hezy</groupId> <artifactId>fastjson2_demo</artifactId> <version>1.0-SNAPSHOT</version> <name>Archetype - fastjson2_demo</name> <url>http://maven.apache.org</url> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <!--fastjson2依赖--> <dependency> <groupId>com.alibaba.fastjson2</groupId> <artifactId>fastjson2</artifactId> <version>2.0.50</version> </dependency> </dependencies> </project> 创建一个实体类对象,User import lombok.*; import java.io.Serializable; @Data public class User implements Serializable { /** * id */ private String id; /** * 证件号 */ private String cardNo; /** * 手机号 */ private String phone; /** * 姓名 */ private String name; /** * 用户名 */ private String username; /** * 密码 */ private String password; } 这里需要注意对象需要实现Serializable 接口,表示该对象实例能被序列化,另外对象需要有全参构造、无参构造(@Data注解自动生成),在分布式项目中,服务之间传输对象(如Dubbo、MQ)底层实现依赖于对象的全参构造,如果对象没有全参构造方法会报错的。

告别数据泥潭:PySpark性能调优的黄金法则

阿佑今天给大家带来个一张藏宝图——使用PySpark进行性能调优的黄金法则,从内存管理到执行计划,再到并行度设置,每一步都是提升数据处理速度的关键! 文章目录 Python Spark 详解1. 引言2. 背景介绍2.1 大数据处理技术演变2.2 Apache Spark简介2.3 PySpark概述 3. PySpark基础3.1 安装与环境配置3.2 SparkContext与SparkSession3.3 RDD操作 4. PySpark高级功能4.1 DataFrame与SQL查询4.2 数据处理与分析4.3 机器学习库MLlib4.4 流处理:Structured Streaming 5. PySpark性能优化与调优5.1 内存管理与调优5.2 执行计划与资源分配5.3 并行度与任务调度 6. PySpark在实际项目中的应用案例6.1 大规模数据处理案例6.2 实时数据分析6.3 机器学习应用 7. 结论回顾PySpark的核心价值与应用范围展望PySpark在大数据与AI领域的前景 参考文献官方文档链接关键书籍推荐相关研究论文与博客文章在线课程与教程 Python Spark 详解 1. 引言 在当今这个信息爆炸的时代,我们每天都在产生海量的数据。想象一下,当你走进超市,拿起一瓶饮料,这个简单的动作可能就被摄像头捕捉下来,成为数据的一部分。再比如,当你在网上浏览新闻,点击广告,你的浏览习惯和偏好也在无声无息中被记录。这些数据,如果能够被有效地收集和分析,就能为我们的生活和工作带来巨大的价值。 但是,大数据处理并不是一件容易的事。数据量巨大,类型多样,处理速度要求高,这些都是挑战。就像是一位厨师面对着堆积如山的食材,想要做出一桌色香味俱全的佳肴,没有一把好刀和一套精湛的厨艺是不行的。 这时候,Apache Spark 出现了,它就像是一位技艺高超的厨师,能够快速、高效地处理这些数据。而PySpark,作为Spark的Python接口,更是让这把“刀”更加锋利,让数据的处理变得更加简单和直观。 接下来,让我们一起走进这个大数据的世界,探索PySpark的奥秘吧! 2. 背景介绍 2.1 大数据处理技术演变 在大数据的江湖里,曾经有一位霸主,名叫Hadoop。它以其强大的分布式文件系统HDFS和MapReduce编程模型,一度成为大数据处理的代名词。但随着时间的推移,人们发现MapReduce虽然在批处理大数据方面表现出色,但在面对需要实时处理和更复杂计算的场景时,就显得有些力不从心了。 这时,Apache Spark横空出世,它以其创新的内存计算能力和灵活的数据处理能力,迅速赢得了人们的青睐。Spark不仅能够处理大规模的批处理任务,还能够轻松应对实时数据流的处理,以及复杂的数据聚合和交互式查询。这就像是从一把沉重的斧头进化到了一把多功能的瑞士军刀,让数据处理变得更加得心应手。 2.2 Apache Spark简介 Apache Spark的核心概念是围绕着三个核心抽象构建的:RDD(弹性分布式数据集)、DataFrame和Dataset。 RDD:它是Spark的基本抽象,代表了一个不可变、分布式的数据集合,可以通过一系列的并行操作进行转换和行动。DataFrame:是建立在RDD之上的一个更高级的抽象,提供了结构化的数据操作,类似于SQL表。它使得对结构化数据的处理变得更加简单。Dataset:是DataFrame的进化版,它结合了RDD的强类型和DataFrame的结构化,提供了更优化的性能和更强大的类型安全。 2.3 PySpark概述 而当我们谈论PySpark时,我们实际上是在谈论如何将Python语言的强大功能与Spark的数据处理能力结合起来。Python以其简洁的语法和丰富的库,已经成为数据科学家和开发者的首选语言。PySpark的出现,让这些用户能够无缝地使用他们熟悉的Python语言,来操作和分析大规模的数据集。 通过PySpark,我们可以使用Python的简洁语法来创建RDD、DataFrame和Dataset,执行复杂的数据转换和分析任务,而无需深入了解底层的分布式计算细节。这就像是给瑞士军刀装上了一个智能芯片,让它不仅功能强大,而且更加易于使用。 在这一章节中,我们简要介绍了大数据处理技术的演变,Apache Spark的核心概念,以及PySpark如何将Python的便捷性与Spark的强大数据处理能力结合起来。接下来,我们将深入探讨PySpark的基础知识,包括安装、环境配置以及如何使用SparkContext与SparkSession 3. PySpark基础 3.1 安装与环境配置 想象一下,你刚买了一套全新的厨具,准备在厨房大展身手。但在开始烹饪前,你需要先安装好这些工具,调整好火候,这正是我们使用PySpark前需要做的准备工作。

论文AI率:检测原理是什么?该如何降低论文AI率?

我是娜姐 @迪娜学姐 ,一个SCI医学期刊编辑,探索用AI工具提效论文写作和发表。 上一篇介绍了10个检测AI率的在线工具。本篇来说说AI率到底是如何检测出来的?该如何有效降低论文的AI率? 和AI大模型一样,AI检测的核心也是机器学习模型,它们在包含人类创作和AI生成文本样本的大型数据集上进行训练,通过学习每种文本中存在的模式和特征,以此来区分人类创作的文本和AI生成文本。 AI检测器查找的一些关键特征包括: 1 单词分布和重复性: 与人类写作相比,AI语言模型有时会过度使用某些单词或短语,使得单词频率分布显得不自然。比如,之前有个调查,pubmed数据库中自2023年以来,delve into的使用频次剧增,而这个词组正是ChatGPT的使用偏好之一。 此外,在同行评审中,某些词语(如“commendable值得称赞的”、“meticulous细致的”和“intricate复杂的”)的使用频率发生了显著变化。 详见:斯坦福最新研究:ChatGPT除了写论文,竟有17%的同行评审也是AI生成。 2 连贯性和逻辑性 虽然AI生成的文本在语法上可能是正确的,但它有时可能缺乏人类写作所自然具备的深层次语义理解、逻辑连贯性。比如,中文写作中出现的“首先、其次、然而、并且”等读起来很生硬的转折和连词。 逻辑性方面,有时候AI生成的文本并不具备意思上的因果关系,也就是它在“一本正经的胡说八道”。需要人类来确认这些内容的合理性。 3 创造力和原创性的局限: 在人类擅长的创造性隐喻、类比或提出真正新颖的观点方面,AI生成的内容逊色很多,因为这些内容超出了它的训练数据范畴。 4 内容的可预测性和困惑度: 这个检测指标是说,比如困惑度分数这样的统计指标可以反映一段文本内容的可预测性或意外性。与AI生成的文本相比,人类写作往往更加多样化和充满惊喜。而AI生成的文本则会显得很平淡和稍显乏味。 5 句子结构的单一性: 人类作者的文本在句子长度和结构上表现出更大的变化性,比如长句短句结合,各种语气的句子结合,而AI生成的文本则可能较为单一。 6 风格和语调一致性: 人类作者的写作通常风格、语调和语气在一篇文章中是一致的,而AI生成的文本则可能在同一篇文章中会出现风格上的突然转变。 AI检测工具的可靠性如何? 我在对比那10款AI检测工具的时候就发现,同样的一段文本内容,不同的工具显示出的AI率有很大差异。其实最早ChatGPT也生产过一款AI检测工具,后来下架了,因为它也发现测不准。 因为,一方面,AI能够生成文本也是在大量人类文本预训练的基础上获得的,只要提示语用得好,它可以无限接近人类风格。比如我的课程中的“论文润色提示语”,AI检测率为0. 另一方面,它也可能出现误报。一个精心润色、结构化的人类写作文本,可能因为其完美无瑕的特性而被错误标记为AI生成。 此外,AI检测器需要不断追赶快速发展的生成AI技术。随着AI模型变得更加先进,曾经容易识别的机器生成内容现在越来越接近人类的个性化特征,AI文本检测器的可靠性在很大程度上取决于检测算法的持续开发和改进。 如何有效降低论文的AI率? 1 使用更精细化的提示语prompt: 简单的改写可能不足以绕过AI检测器,它们能够识别出典型的生成式AI的模式。 但是,使用更加精细化的提示语,让AI更深度的在句子结构、语法、风格上模仿并生成人类语言,从而更贴近人类写作风格。 2 混合数据来源: 从多个多样化的来源获取数据或研究内容,可以有效地掩盖AI检测工具追踪的数字足迹。 数据来源的多样性不仅丰富了内容的真实性和复杂性,而且让AI检测器更难检测。 3 增强人类元素: 即使是使用AI写作工具,融入独特的人类洞察力和经验也至关重要。 为了降低AI检测率,尝试将你的个人独特风格融入写作,比如:独特语气语调,展示细节的真实生活的例子。 4 融入习语语言: AI生成的内容往往缺乏人类写作中特有的习语、行话和口语表达。通过融入口语和地区习语,让你的内容显得更真实、更易于得到人类的认同。 5 在修改过程中使用AI检测器: 这种预防性检测,帮助你找出容易被标记为AI生成的文本元素,比如某些重复的模式或不自然的措辞。然后再通过重构句子、改变词序、替换同义词和重组段落的方式,来针对性降低AI率。 6 持续跟踪AI技术的发展: 随着AI能力的增长,检测此类内容的技术也在不断发展。持续保持对AI进展的关注,可以有效提升你利用AI的创作效率,并避免AI检测过高。 随着AI大模型的不断进化,这些AI检测工具也需要不断改进。 AI大模型和AI检测工具的具备竞赛在不断升级。对于我们人类创作者来说,跟上技术的进展,左右大模型,右手检测工具,让这些效率工具都为“我”所用,提升论文产出效率和质量,就对了。

IC-Light-在stable diffusion中实现图像的光影控制新方法 - 技术原理篇

👨背景与来源 最近在stable diffusion的粉丝群看到光影控制又有了新的玩法,是controlnet的作者lllyasviel,发了一款名为IC-Light的模型,并且已经被另外一位名为huchenlei的朋友实现了comfyui和webUI(forge )版的插件,并且在github上提到automatic1111 webui的插件也在进行过程中了。 ✨ComfyUI and Forge versions are available: GitHub - huchenlei/ComfyUI-IC-Light-Native: ComfyUI native implementation of IC-LightGitHub - huchenlei/sd-forge-ic-light: SD Forge extension for IC-Light 这篇文章我们就先简单了解下原作者制作模型的基础思路,下一篇我们一起看下comfyui里边实现的方法,看看有没有哪些潜在的坑帮大家先踩一踩。 🎠模型原作者链接:https://github.com/lllyasviel/IC-Light 🥽模型简介与效果 IC-Light 是一个用于控制图像光源效果的项目。 名称 "IC-Light" 代表 "Imposing Consistent Light"(直白翻译是,保持图像的光源一致性)。 目前,我们(原作者哈,不是我)发布了两种类型的模型:文本条件重照明模型和背景条件模型。两种类型的模型都接受前景图像作为输入。 先看下原作者给出的测试效果: 首先是给出前景图,然后结合提示词和光源方向的标签选择,自动生成场景和大致的光源: (其他更多案例略) 其次是给出原图和光源图,然后结合简单的提示词,让模型自行混合前景和光源; 然后作者贴了一张更全面的对比图,左侧第一列是原图,右侧是在输入不同的景色图像作为光源控制的情况下,实现的图像效果: 整体来说,在保持了图像本身结构不变的情况下,很大程度上实现了前景和背景更好的融合,看起来是可以很好的用在摄影写真类工作流中去的,可以一定程度上把人从繁重的后期ps中解放出来。 🍳技术实现部分 在 HDR 空间中,照明具有所有光传输都是独立的属性。 在HDR的世界里,光的传播就像是小朋友们玩传球游戏。每个小朋友(光线)都可以独立地把球(光)传给其他小朋友,而不需要担心球会消失或者变得看不清。这样,不管球传到哪里,大家都能看得清清楚楚,就像真实世界里光是怎样传播的一样。 所以,HDR让电脑游戏里的光和影看起来更真实,更接近我们用眼睛看到的世界。 结合下图来示意,不同光源的外观混合相当于混合光源的外观: 将每一束光源先照射到物体上,然后将物体的图像进行合并,和将光源先组合再统一照射到物体上,效果是一样的。 在训练重新照明模型时,作者强加了这种一致性(在潜在空间中使用 MLP)。 因此,该模型能够产生高度一致的重新光照 -如此一致,甚至可以将不同的重新光照合并为法线贴图!尽管事实上这些模型是潜在扩散的。 从左到右依次是原图像输入、模型输出重新照明效果、分割的阴影图像和合并的法线贴图。请注意,该模型未使用任何法线贴图数据进行训练。最后的这张法线贴图的估算结果,来自于重新一致性照明的图像。 大家也可以到作者提供的在线试验平台去玩玩,反正是完全免费的: https://huggingface.co/spaces/lllyasviel/IC-Light 🍡模型说明 模型下载地址:https://huggingface.co/lllyasviel/ic-light/tree/main iclight_sd15_fc.safetensors - 默认的重新打光模型,通过文字和前景来控制生成结果,你可以控制潜空间的初始化来影响生成效果; iclight_sd15_fcon.safetensors -这个模型和"iclight_sd15_fc.safetensors"很像,但是在训练的时候加入了一些偏移噪声(offset noise)。不过,在一个用户研究中,没有加入偏移噪声的"iclight_sd15_fc.safetensors"模型表现得稍微好一些。这就是为什么默认的模型是那个没有偏移噪声的版本。 iclight_sd15_fbc.safetensors - 支持文字+前景+背景一起控制生成的结果的重新打光模型;

机器学习 - 决策树

1. 决策树基础 定义与概念 决策树是一种监督学习算法,主要用于分类和回归任务。它通过学习从数据特征到输出标签的映射规则,构建一个树形结构。在分类问题中,决策树的每个叶节点代表一个类别。 案例分析 假设我们有一个关于天气和是否进行户外活动的数据集,其中特征包括“温度”、“风速”和“天气类型”,目标变量是“是否进行户外活动”。决策树将从这些特征中学习规则,以预测任何给定天气条件下的活动决定。 公式推导 最简单的决策树使用信息增益来选择每个节点的分裂特征。信息增益计算如下: I G ( T , a ) = H ( T ) − ∑ v ∈ V a l u e s ( a ) ∣ T v ∣ ∣ T ∣ H ( T v ) IG(T, a) = H(T) - \sum_{v \in Values(a)} \frac{|T_v|}{|T|} H(T_v) IG(T,a)=H(T)−v∈Values(a)∑​∣T∣∣Tv​∣​H(Tv​) 常见问题及解决方案 问题:如何处理连续特征? 解决方案:将连续特征通过阈值划分为两个子集,选择最优阈值使信息增益最大化。 问题:决策树容易过拟合吗? 解决方案:是的,可以通过设置树的最大深度或使用剪枝技术来防止过拟合。 问题:如果数据集中有缺失值怎么办? 解决方案:可以用数据集中同一特征的非缺失值的平均值或众数替代缺失值。 问题:决策树在何种情况下表现不好? 解决方案:在特征间复杂的相互作用或分类边界非线性时,单一决策树效果不佳,此时可考虑使用随机森林等集成方法。 问题:如何选择最佳的分裂特征? 解决方案:通过计算每个特征的信息增益或基尼不纯度,并选择增益最大或不纯度降低最多的特征。 2. 关键概念 属性选择度量 在决策树构造中,选择正确的属性对于分裂每个节点至关重要。以下是几种常见的属性选择度量方法:

Go最新Google BigQuery 创始工程师:大数据已“死”(2),最新Golang面试题整理

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。 需要这份系统化的资料的朋友,可以添加戳这里获取 一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长! 针对这个问题,解决方法是购买一些能够处理大规模数据的新奇技术。然而,在大数据任务组购买了所有新工具,并从遗留系统迁移出来之后,人们发现他们仍然无法理解自己的数据。此外,他们可能还会注意到,实际上数据的规模根本不是问题所在。 2023 年,整个世界看起来与大数据的预警有很大的不同。人们预测的数据灾难并没有发生。数据量可能变大了,但硬件的增长速度也更快了。供应商仍在推销扩展能力,但从业者开始质疑规模到底与现实世界的问题有何关系。 d455ce2d08d5fcf855043f13e076ed62.png 背景介绍 十多年来,我一直支持大数据的发展。我是 Google BigQuery 的创始工程师,作为团队中唯一真正喜欢公开演讲的工程师,我经常前往世界各地参加会议,帮忙解释如何抵御即将到来的数据爆炸。我曾经在台上演示过查询 PB 数量级的数据,就为了证明无论多大规模的数据,我们都能搞定,没问题。 前几年,我花了很多时间调试客户在使用 BigQuery 时遇到的问题。我参与出版了两本书,深入研究了 BigQuery 的使用方式。2018年,我转做产品管理,工作内容主要分为两大块:与客户交谈(许多是全球级的大企业)以及分析产品指标。 我发现,大多数使用 BigQuery 的用户并没有大数据。即使是拥有大数据的人,实际上也只使用了数据集很小的一部分。当初 BigQuery 问世,对许多人来说就像科幻小说一样,人们能够利用它以前所未有的速度处理数据。然而,这些曾经只会出现在科幻小说中的情节也已成为生活的常态,而且更传统的数据处理方式也迎头赶上来了。 关于这篇文章 在本文中,我将论证大数据时代已经结束。如今我们不必不再担心数据的规模,相反,我们应该专心研究如何利用大规模数据制定出更好的决策。 我会展示一些图表,虽然这些图表是根据记忆手动绘制的,但重要的是观察曲线的走向。 图表背后的数据来自分析查询日志、交易事后分析、基准测试结果(已发布和未发布)、客服票据、客户对话、服务日志、已发布的博客文章,再加上一些直觉。 一张幻灯片 在过去的十年里,每一个大数据产品的推销平台都是从与下面这张幻灯片类似的宣传资料开始的: 在 Google,多年来我们一直在使用这张幻灯片。后来,我到了 SingleStore,发现他们使用的也是类似的图表,只不过版本略微不同。此外,我见过其他几家供应商也有类似的东西。这张幻灯片可以引发潜在的“恐慌”:“大数据来了!抓紧购买我家的产品吧!” 这张幻灯片真正想转达的消息是:**处理数据的旧方法已经行不通了。**数据生成的加速导致以前的数据系统陷入困境,所有接受新想法的人都将超越竞争对手。 当然,仅仅因为生成的数据量在增加并不意味着这会成为每个人的问题, 数据分布不均。大多数应用程序不需要处理大量数据。这导致使用传统架构的数据管理系统的复兴,SQLite、Postgres、MySQL 都开始强势发展,而 NoSQL 以及 NewSQL 系统的发展都出现了停滞。 若论 NoSQL 或其他横向扩展数据库,MongoDB 的人气最高,虽然多年来 MongoDB 的发展也算顺风顺水,但最近出现了小幅下降,而且与 MySQL 和 Postgres 这两种单体数据库相比,MongoDB 的发展始终不如人意。如果大数据真的占据统治地位,那么几年内我们本应能看到很大的不同。 当然,在分析系统中的情况有所不同,但在 OLAP 中,我们看到了从内部部署到云的巨大转变,并且实际上没有任何可扩展的云分析系统可与之抗衡。 大多数人没有那么多数据 根据上述“大数据即将到来”的图表,用不了多久每个人都会数据淹没。然而十年过去了,我们“预期的未来”仍然未能成为现实。我们可以几种方式验证这一点:查看数据(定量),询问数据量是否与人们的感知一致(定性),从第一原则出发(归纳)思考这个问题。 当初在 BigQuery 工作的时候,我花了很多时间研究客户规模。相关的数据是保密的,所以我不能直接分享任何数字。但是,我可以说绝大多数客户的总数据存储量都不到 1TB。当然,也有一些客户拥有大量数据,但大多数组织,甚至一些巨头企业,他们的数据量也属于中等水平。 客户的数据规模呈幂律分布。存储量最大的客户是第二大客户的两倍,而第二大客户是第三大客户的两倍,依此类推。因此,虽然有些客户拥有数百 PB 的数据,但在分布图上这个规模的下降速度很快。成千上万的客户每月支付的数据存储费用不足 10 美元,即 0.5TB。在大量使用我们的服务的客户中,数据存储规模的中位数远低于 100 GB。

AI大模型探索之路-训练篇21:Llama2微调实战-LoRA技术微调步骤详解

系列篇章💥 AI大模型探索之路-训练篇1:大语言模型微调基础认知 AI大模型探索之路-训练篇2:大语言模型预训练基础认知 AI大模型探索之路-训练篇3:大语言模型全景解读 AI大模型探索之路-训练篇4:大语言模型训练数据集概览 AI大模型探索之路-训练篇5:大语言模型预训练数据准备-词元化 AI大模型探索之路-训练篇6:大语言模型预训练数据准备-预处理 AI大模型探索之路-训练篇7:大语言模型Transformer库之HuggingFace介绍 AI大模型探索之路-训练篇8:大语言模型Transformer库-预训练流程编码体验 AI大模型探索之路-训练篇9:大语言模型Transformer库-Pipeline组件实践 AI大模型探索之路-训练篇10:大语言模型Transformer库-Tokenizer组件实践 AI大模型探索之路-训练篇11:大语言模型Transformer库-Model组件实践 AI大模型探索之路-训练篇12:语言模型Transformer库-Datasets组件实践 AI大模型探索之路-训练篇13:大语言模型Transformer库-Evaluate组件实践 AI大模型探索之路-训练篇14:大语言模型Transformer库-Trainer组件实践 AI大模型探索之路-训练篇15:大语言模型预训练之全量参数微调 AI大模型探索之路-训练篇16:大语言模型预训练-微调技术之LoRA AI大模型探索之路-训练篇17:大语言模型预训练-微调技术之QLoRA AI大模型探索之路-训练篇18:大语言模型预训练-微调技术之Prompt Tuning AI大模型探索之路-训练篇19:大语言模型预训练-微调技术之Prefix Tuning AI大模型探索之路-训练篇20:大语言模型预训练-常见微调技术对比 目录 系列篇章💥前言一、Llama2总体概述二、Llama2功能特点三、Llama2微调准备四、Llama2微调实战学术资源加速步骤1 导入相关包步骤2 加载数据集步骤3 数据集预处理1)获取分词器2)对齐设置3)定义数据处理函数4)对数据进行预处理5)打印查看inpu_ids6)检查数据(是否包含结束符) 步骤4 创建模型1、PEFT 步骤1 配置文件2、PEFT 步骤2 创建模型 步骤5 配置训练参数步骤6 创建训练器步骤7 模型训练步骤8 模型推理 五、Llama2 调试过程问题整理1、MAX_LENGTH设置:2、对齐设置3、设置pad_token_id4、结束符设置5、设置 adam_epsilon 总结 前言 在人工智能领域,大型预训练语言模型(Large Language Models, LLMs)已经成为推动自然语言处理(NLP)任务发展的重要力量。Llama2作为其中的一个先进代表,通过其庞大的参数规模和深度学习机制,展现了在多种NLP任务上的卓越性能。然而,为了使Llama2更好地适应特定的应用场景,对其进行微调(Fine-tuning)成为了一个关键步骤。本文将从专业角度出发,详细介绍如何基于LoRA(Low-Rank Adaptation)技术对Llama2进行微调。 一、Llama2总体概述 Llama2是Meta AI的研究成果(最新版Llama3最近也现世了),这是一个致力于人工智能研究的团队,隶属于Meta公司(即原Facebook公司)。该模型包括7B(70亿参数)、13B(130亿参数)以及70B(700亿参数)三个版本,训练所用的数据集达到了惊人的2万亿tokens。这一大语言模型的开发体现了Meta在AI领域的深入研究和技术积累。 Llama2是继Llama之后的一个大型语言模型,它在原有模型的基础上进行了扩展和优化,以支持更复杂的语言理解和生成任务。Llama2是一个基于Transformer架构的自回归类型大语言模型,Llama2通常具有数十亿甚至数百亿的参数,这些参数通过大量文本数据进行预训练得到,使其具备了广泛的语言知识和强大的语言生成能力。Llama2采用了分层的训练策略,通过预训练、指令微调和任务微调等阶段,使得模型具有较强的泛化能力。 github地址:https://github.com/meta-llama Llama2目前开源的有7B、13B、70B,但对中文支持不是特别友好;需要自己使用中文语料进行预训练;也可以选用经过其他大佬微调过的中文变体版; 二、Llama2功能特点 Llama2的功能特点主要体现在以下几个方面: 1)上下文理解:能够理解长篇文本中的复杂语境和细微差别。 2)多任务学习:在预训练阶段就接触了多种任务,使其具备了解决多种NLP问题的能力。 3)生成能力:可以生成连贯、逻辑性强的文本内容。 4)适应性:通过微调,Llama2能够快速适应特定的应用场景和任务需求 三、Llama2微调准备 在对Llama2进行微调之前,需要做好以下准备工作: 1)数据准备:收集并预处理用于微调的数据集,包括文本清洗、标注等。 数据集:https://huggingface.co/datasets/c-s-ale/alpaca-gpt4-data-zh 2)模型选择:根据任务需求选择合适的Llama2模型版本。 模型地址:https://www.modelscope.cn/models?name=llama2-7b-ms&page=1 模型下载方式1 git clone https://www.

【LeetCode LCR 022】【C语言】环形链表 II

注意:请务必看完以下技术内容再来做这道题【LeetCode例141】【c语言】环形链表-CSDN博客 1 题目介绍 给定一个链表,返回链表开始入环的第一个节点。 从链表的头节点开始沿着 next 指针进入环的第一个节点为环的入口节点。如果链表无环,则返回 null。 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。注意,pos 仅仅是用于标识环的情况,并不会作为参数传递到函数中。 说明:不允许修改给定的链表。 示例1: 输入以下链表,值为3的节点为head节点 返回值应该为值为2的节点 示例2: 输入以下链表,值为1的节点为head节点 返回值应该为值为1的节点 示例3: 输入以下链表,值为1的节点为head节点 返回值应该为NULL 照例放上题目链接: . - 力扣(LeetCode) 2 解题思路 我们首先先判断这个链表是否带环,这里就不多赘述了,如果不太清楚的话可以看文章开头链接的内容 判断完链表是否带环之后我们就可以得到重合在一起的 fast slow 指针 不难看出,此时fast或者slow到入口节点的距离与head到入口节点的距离相等! 那么我们只要在此时同时遍历slow和head,让其重合就能找到入口节点! 3 实现代码 typedef struct ListNode ListNode; struct ListNode *detectCycle(struct ListNode *head) { if(head == NULL || head->next == NULL) { return NULL; } ListNode* fast = head; ListNode* slow = head; while(fast !

录制第一个jmeter性能测试脚本2(http协议)——webtour

我们手工编写了一个测试计划,现在我们通过录制的方式来实现那个测试计划。也就是说‘’测试计划目标和上一节类似:让5个用户在2s内登录webtour,然后进入 页面进行查看。 目录 欢迎访问我的免费课程 PPT、安装包、视频应有尽有! 一.性能测试脚本录制的原理 二、性能测试脚本录制的实操(https) 1.搭建被测环境 2.创建测试计划 2.为线程组添加3个测试元件:缓存管理器、cookie管理器以及HTTP请求默认值 3.添加线程组 4.为测试计划添加HTTP测试脚本录制器 5.将浏览器的代理服务器指向HTTP测试脚本录制器 6.启动HTTP测试脚本录制器 7.浏览器上执行你要录制的操作 8.录制结束后,在HTTP测试脚本录制器的右侧面板上点击stop按钮,停止录制; ​9.取消浏览器的代理设置 10.为脚本增加监听器,以便收集测试结果 12 保存脚本后,运行脚本, 13.添加定时器,模拟用户停顿 14.将第一个请求都设置为 获取嵌入资源 15.执行脚本 16.取消对嵌入资源的请求选项 17 提取动态session值 18 在登录请求中,设置动态会话值 ${userSession} 20 添加调试取样器(debug sampler) 21 设置模拟用户数和启动时间 欢迎访问我的免费课程 PPT、安装包、视频应有尽有! 软件测试与质量保证 (xueyinonline.com)​编辑https://www.xueyinonline.com/detail/219145327https://www.xueyinonline.com/detail/219145327 一.性能测试脚本录制的原理 首先我们来了解下jmeter性能测试脚本录制的原理,然后再来实操。 当我们打开某个网站的页面时,请求会被浏览器发送到网站服务器,服务器将响应返回给浏览器。 如果,我们的请求发送到了jmeter的代理服务器,然后由代理服务器转发到网站服务器,那么代理服务器就会把我们发送的请求录制下来。 如果我们能录制下来用户的请求,我们就能模拟多个用户发送请求,从而达到性能测试的目的。 ​ 二、性能测试脚本录制的实操(https) 步骤前面几步与手工测试的几乎一样: 1.搭建被测环境 webtour环境的安装包以及启动方法如下: 链接: https://pan.baidu.com/s/1BaPe24jMGimiML31LDTcdw?pwd=5uef 提取码: 5uef 安装好后,浏览器上输入网址可以打开wetour http://127.0.0.1:1080/WebTours/ 特别注意: 有的计算机使用127.0.0.1时,jmeter录制不到脚本,因此建议将127.0.0.1替换为你的本机ip地址。例如:http://10.9.31.5:1080/WebTours/ 输入账号:jojo bean 2.创建测试计划 创建测试计划并命名webtour测试计划。添加注释:第一个录制的JMeter脚本(https) ​ 2.为线程组添加3个测试元件:缓存管理器、cookie管理器以及HTTP请求默认值 1)在线程组上点击右键菜单Add -> Config Element -> HTTP Cache Manager添加缓存管理器。缓存管理器在整个测试中将帮助管理用户缓存;

Spring高手之路18——从XML配置角度理解Spring AOP

文章目录 1. Spring AOP与动态代理1.1 Spring AOP和动态代理的关系1.2 AOP基本术语 2. 通过XML配置实现Spring AOP2.1 添加Spring依赖2.2 定义业务接口和实现类2.3 定义切面类2.4 配置XML 1. Spring AOP与动态代理 1.1 Spring AOP和动态代理的关系 Spring AOP使用动态代理作为其主要机制来实现面向切面的编程。这种机制允许Spring在运行时动态地创建代理对象,这些代理对象包装了目标对象(即业务组件),以便在调用目标对象的方法前后插入额外的行为(如安全检查、事务管理、日志记录等)。 JDK动态代理:当目标对象实现了一个或多个接口时,Spring AOP默认使用JDK的动态代理。JDK动态代理通过反射机制,为接口创建一个代理对象,这个代理对象会拦截对目标接口方法的所有调用。 CGLIB代理:如果目标对象没有实现任何接口,Spring AOP会退回到使用CGLIB库生成目标类的子类。CGLIB(Code Generation Library)是一个强大的高性能代码生成库,它在运行时扩展了Java类,并在子类中覆盖了方法来实现方法拦截。 无论使用哪种代理方式,目的都是在不改变原有业务逻辑代码的基础上,通过切面定义的通知在方法执行的不同阶段插入附加行为。 1.2 AOP基本术语 切面(Aspect):切面是面向切面编程的核心,它是将横跨多个类的关注点(如日志记录、事务管理等)模块化的构造。一个切面可以包含多种类型的通知(Advice)和一个或多个切点(Pointcut),用于定义在何处以及何时执行这些通知。 连接点(Join Point):连接点代表程序执行过程中的某个特定位置,Spring AOP限定这些位置为方法的调用。简而言之,连接点就是能够插入切面通知的点。 通知(Advice):通知定义了切面在连接点上要执行的动作。根据通知类型的不同,这些动作可以在方法调用之前、之后、返回结果后或抛出异常时执行。通知类型包括: 前置通知(Before advice):在方法执行之前执行。后置通知(After advice):在方法执行后执行,无论其结果如何。返回后通知(After-returning advice):在方法成功执行之后执行。异常后通知(After-throwing advice):在方法抛出异常后执行。环绕通知(Around advice):在方法执行之前和之后执行,提供对方法调用的全面控制。 切点(Pointcut):切点是一个表达式,切点表达式允许通过方法名称、访问修饰符等条件来匹配连接点,决定了通知应该在哪些方法执行时触发。 目标对象(Target Object):被一个或多个切面所通知的对象。也被称为被代理对象。 AOP代理(AOP Proxy):AOP框架创建的对象,用于实现切面契约(由通知和切点定义)。在Spring AOP中,AOP代理可以是JDK动态代理或CGLIB代理。 引入(Introduction):引入允许向现有的类添加新的方法或属性。这是通过定义一个或多个附加接口(Introduction interfaces)实现的,AOP框架会为目标对象创建一个代理,该代理实现这些接口。 如果还是觉得抽象,我们再举一个电影制作的例子来类比 🎭 切面(Aspect) 想象一下,有人正在拍摄一部电影,而电影中的特效(比如爆炸和特殊光效)就像是应用程序中需要处理的横切关注点(比如日志记录或事务管理)。这些特效会在电影的许多不同场景中出现,而不仅仅局限于某一个特定场景。在AOP中,这些“特效”就是切面,它们可以被应用到程序的多个部分,而不需要改变实际的场景(或代码)。 📍 连接点(Join Point) 继续使用电影的比喻,每个场景中的特定时刻,比如一个爆炸发生的瞬间,可以看作是一个连接点。在编程中,这通常对应于方法的调用。 📣 通知(Advice) 通知就像是导演对特效团队的具体指令,比如“在这个场景开始之前加入一个爆炸效果”或“场景结束后显示烟雾渐散的效果”。这些指令告诉特效团队在电影的哪个具体时刻应该添加特定的效果。在AOP中,这些“指令”就是通知,指定了切面(特效)应该在连接点(特定的代码执行时刻)之前、之后或周围执行。 🎯 切点(Pointcut) 如果说通知是导演对特效团队的指令,那么切点就是指令中包含的具体条件,比如“所有夜晚的外景戏”。切点定义了哪些连接点(比如哪些具体的方法调用)应该接收通知(特效指令)。 🎬 目标对象(Target Object) 目标对象就是那些需要添加特效的场景。在我们的编程比喻中,它们是那些被切面逻辑影响的对象(比如需要日志记录的类)。 🕵️‍♂️ AOP代理(AOP Proxy)

大学生体质测试|基于Springboot+vue的大学生体质测试管理系统设计与实现(源码+数据库+文档)

大学生体质测试管理系统 目录 基于Springboot+vue的大学生体质测试管理系统设计与实现 一、前言 二、系统设计 三、系统功能设计 1系统功能模块 2管理员功能模块 3用户功能模块 4教师功能模块 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取: 博主介绍:✌️大厂码农|毕设布道师,阿里云开发社区乘风者计划专家博主,CSDN平台Java领域优质创作者,专注于大学生项目实战开发、讲解和毕业答疑辅导。✌️ 主要项目:小程序、SpringBoot、SSM、Vue、Html、Jsp、Nodejs等设计与开发。 🍅文末获取源码联系🍅 基于Springboot+vue的大学生体质测试管理系统设计与实现 一、前言 大学生体质测试管理系统提供给用户一个简单方便体质测试管理信息,通过留言区互动更方便。本系统采用了B/S体系的结构,使用了java技术以及MYSQL作为后台数据库进行开发。系统主要分为系统管理员、教师和用户三个部分,系统管理员主要功能包括首页、个人中心、用户管理、教师管理、体质测试管理、测试报告管理、测试成绩管理、留言板、系统管理;基本上实现了整个大学生体质测试管理系统信息管理的过程。 关键词:大学生体质测试管理系统; java技术;MYSQL数据库; 二、系统设计 系统功能结构如图 三、系统功能设计 1系统功能模块 大学生体质测试管理系统,在系统首页可以查看首页、体质测试、公告资讯、留言板、个人中心、后台管理等内容进行详细操作,如图5-1所示。 图5-1系统首页界面图 2管理员功能模块 管理员登录,管理员通过输入用户,密码,选择角色等信息进行系统登录,如图5-5所示。 图5-5管理员登录界面图 3用户功能模块 用户进入大学生体质测试管理系统可以查看首页、个人中心、测试报告管理、测试成绩管理等内容进行详细操作,如图5-14所示。 图5-14用户功能界面图 4教师功能模块 教师注册,通过填写教师工号、密码、确认密码、教师姓名、职称、联系电话等内容进行注册,如图5-16所示。 图5-16教师注册界面图 四、数据库设计 体质测试实体属性图如图4-4所示。 图4-4体质测试实体属性图 数据库表的设计,如下表: 表4-1:token表 字段名称 类型 长度 字段说明 主键 默认值 id bigint 主键 主键 userid bigint 用户id username varchar 100 用户名 tablename varchar 100 表名 role varchar 100 角色 token

[数据结构]动画详解单链表

💖💖💖欢迎来到我的博客,我是anmory💖💖💖 又和大家见面了 欢迎来到动画详解数据结构系列 用通俗易懂的动画的动画使数据结构可视化 先来自我推荐一波 个人网站欢迎访问以及捐款 推荐阅读 如何低成本搭建个人网站 专栏:动画详解leetcode算法题 C语言知识 今天我们来了解一个全新的数据结构,链表 话不多说,直接开始 文章目录 链表概念链表的定义 单链表尾插动画详解尾插 头插动画详解头插 在指定位置之前插入动画详解在指定位置之前插入元素 在指定位置之后插入动画详解在指定位置之后插入 删除指定位置之前的元素动画详解删除指定位置之前元素 删除指定位置之后的元素动画详解删除指定位置之后的元素 链表的销毁 总结 链表概念 什么是链表,链表是一种通过指针串联在一起的线性结构,每一个节点由两部分组成,一个是数据域一个是指针域(存放指向下一个节点的指针),最后一个节点的指针域指向null(空指针的意思)。 链表的入口节点称为链表的头结点也就是head。 ——来自代码随想录 链表的定义 // 定义一个链表结构体 struct ListNode { DataType val; // 链表存储的数据 struct ListNode* next;// 指向下一个节点的指针 }; 单链表 由于不带哨兵位,也就是虚拟头节点,我们需要对链表的头节点进行单独判断 尾插 // 开辟新节点 LN* BuyNode(DataType x) { LN* new = (LN*)malloc(sizeof(LN)); if (new == NULL) { perror("malloc failed"); return; } new->val = x; new->next = NULL; return new; } // 链表尾插 void LNPushBack(LN** pplist, DataType x) { assert(pplist); LN* new = BuyNode(x); if (*pplist == NULL) { *pplist = new; } else { // 找尾 LN* ptail = *pplist; while (ptail->next) { ptail = ptail->next; } ptail->next = new; } } 动画详解尾插 头插 // 链表头插 void LNPushFront(LN** pplist, DataType x) { assert(pplist); LN* new = BuyNode(x); if (*pplist == NULL) { *pplist = new; } else { LN* pfront = new; pfront->next = *pplist; // 让pfront成为新的头节点,也就是更新pplist的位置,使其成为新的头节点 *pplist = pfront; } } 动画详解头插 在指定位置之前插入 // 在指定位置之前插入数据 void LNInsert(LN** pplist, LN* pos, DataType x) { assert(*pplist && pos); LN* new = BuyNode(x); LN* prev = *pplist; while (prev->next !