【JVM】总结篇-类的加载篇之 类的加载器 和ClassLoader分析
文章目录
- 类的加载器
- ClassLoader
- 自定义类加载器
- 双亲委派机制
- 概念
- 源码分析
- 优势劣势
- 如何打破
- Tomcat
- 沙箱安全机制
- JDK9 双亲委派机制变化
类的加载器
获得当前类的ClassLoader clazz.getClassLoader()
获得当前线程上下文的ClassLoader Thread.currentThread().getContextClassLoader()
获得系统的ClassLoader ClassLoader.getSystemClassLoader()
ClassLoader
抽象类ClassLoader的主要方法:(内部没有抽象方法)
public final ClassLoader getParent()
返回该类加载器的超类加载器
public Class<?> loadClass(String name) throws ClassNotFoundException
加载名称为name的类,返回结果为java.lang.Class类的实例。
如果找不到类,则返回 ClassNotFoundException 异常。该方法中的逻辑就是双亲委派模式的实现。
protected Class<?> findClass(String name) throws ClassNotFoundException
查找二进制名称为name的类,返回结果为java.lang.Class类的实例。这是一个受保护的方法,
JVM鼓励我们重写此方法,需要自定义加载器遵循双亲委托机制,
该方法会在检查完父类加载器之后被loadClass()方法调用。
在JDK1.2之前,在自定义类加载时,总会去继承ClassLoader类并重写loadClass方法,从而实现自定义的类加载类。但是在JDK1.2之后已不再建议用户去覆盖loadClass()方法,而是建议把自定义的类加载逻辑写在findClass()方法中,从前面的分析可知,findClass()方法是在loadClass()方法中被调用的,当loadClass()方法中父加载器加载失败后,则会调用自己的findClass()方法来完成类加载,这样就可以保证自定义的类加载器也符合双亲委托模式。
需要注意的是ClassLoader类中并没有实现findClass()方法的具体代码逻辑,取而代之的是抛出ClassNotFoundException异常,同时应该知道的是findClass方法通常是和defineClass方法一起使用的。一般情况下,在自定义类加载器时,会直接覆盖ClassLoader的findClass()方法并编写加载规则,取得要加载类的字节码后转换成流,然后调用defineClass()方法生成类的Class对象。
protected final Class<?> defineClass(String name, byte[] b, int off, int len)
根据给定的字节数组b转换为Class的实例,off和len参数表示实际Class信息在byte数组中的位置和长度,
其中byte数组b是ClassLoader从外部获取的。这是受保护的方法,只有在自定义ClassLoader子类中可以使用。
defineClass()方法是用来将byte字节流解析成JVM能够识别的Class对象(ClassLoader中已实现该方法逻辑),通过这个方法不仅能够通过class文件实例化class对象,也可以通过其他方式实例化class对象,如通过网络接收一个类的字节码,然后转换为byte字节流创建对应的Class对象。
defineClass()方法通常与findClass()方法一起使用,一般情况下,在自定义类加载器时,会直接覆盖ClassLoader的findClass()方法并编写加载规则,取得要加载类的字节码后转换成流,然后调用defineClass()方法生成类的Class对象
简单举例:
protected Class<?> findClass(String name) throws ClassNotFoundException {// 获取类的字节数组byte[] classData = getClassData(name);if (classData == null) {throw new ClassNotFoundException();} else {//使用defineClass生成class对象return defineClass(name, classData, 0, classData.length);}
}
protected final void resolveClass(Class<?> c)
链接指定的一个Java类。使用该方法可以使用类的Class对象创建完成的同时也被解析。
前面我们说链接阶段主要是对字节码进行验证,
为类变量分配内存并设置初始值同时将字节码文件中的符号引用转换为直接引用。
protected final Class<?> findLoadedClass(String name)
查找名称为name的已经被加载过的类,返回结果为java.lang.Class类的实例。这个方法是final方法,无法被修改。
private final ClassLoader parent;
它也是一个ClassLoader的实例,这个字段所表示的ClassLoader也称为这个ClassLoader的双亲。
在类加载的过程中,ClassLoader可能会将某些请求交予自己的双亲处理。
自定义类加载器
public class UserClassLoader extends ClassLoader {private String rootDir;public UserClassLoader(String rootDir) {this.rootDir = rootDir;}/*** 编写findClass方法的逻辑*/@Overrideprotected Class<?> findClass(String name) throws ClassNotFoundException {// 获取类的class文件字节数组byte[] classData = getClassData(name);if (classData == null) {throw new ClassNotFoundException();} else {//直接生成class对象return defineClass(name, classData, 0, classData.length);}}/*** 编写获取class文件并转换为字节码流的逻辑 * @param className * @return*/private byte[] getClassData(String className) {// 读取类文件的字节String path = classNameToPath(className);try {InputStream ins = new FileInputStream(path);ByteArrayOutputStream baos = new ByteArrayOutputStream();byte[] buffer = new byte[1024];int len = 0;// 读取类文件的字节码while ((len = ins.read(buffer)) != -1) {baos.write(buffer, 0, len);}return baos.toByteArray();} catch (IOException e) {e.printStackTrace();}return null;}/*** 类文件的完全路径*/private String classNameToPath(String className) {return rootDir + "\\" + className.replace('.', '\\') + ".class";}public static void main(String[] args) {String rootDir = "D:\\Java_course\\JVM\\JVMdachang\\chapter02_classload\\src\\";try {//创建自定义的类的加载器1UserClassLoader loader1 = new UserClassLoader(rootDir);Class clazz1 = loader1.findClass("com.cz.java3.User");//创建自定义的类的加载器2UserClassLoader loader2 = new UserClassLoader(rootDir);Class clazz2 = loader2.findClass("com.cz.java3.User");System.out.println(clazz1 == clazz2); //clazz1与clazz2对应了不同的类模板结构。System.out.println(clazz1.getClassLoader());System.out.println(clazz2.getClassLoader());//######################Class clazz3 = ClassLoader.getSystemClassLoader().loadClass("com.cz.java3.User");System.out.println(clazz3.getClassLoader());System.out.println(clazz1.getClassLoader().getParent());} catch (ClassNotFoundException e) {e.printStackTrace();}}}
false
com.atguigu.java3.UserClassLoader@14ae5a5
com.atguigu.java3.UserClassLoader@6d6f6e28
sun.misc.Launcher$AppClassLoader@18b4aac2
sun.misc.Launcher$AppClassLoader@18b4aac2
双亲委派机制
双亲委派好处有哪些?(亚信)
类加载器双亲委派模型机制?(苏宁)
双亲委派机制 (蚂蚁金服)
双亲委派机制及使用原因 (蚂蚁金服)
类加载器的双亲委派模型是什么? (蚂蚁金服)
双亲委派模型介绍一下 (小米)
讲一下双亲委派模型,以及其优点 (滴滴)
类加载器的双亲委派模型是什么? (京东)
概念
1.定义
如果一个类加载器在接到加载类的请求时,它首先不会自己尝试去加载这个类,而是把这个请求任务委托给父类加载器去完成,依次递归,如果父类加载器可以完成类加载任务,就成功返回。只有父类加载器无法完成此加载任务时,才自己去加载。
2.本质
规定了类加载的顺序是:引导类加载器先加载,若加载不到,由扩展类加载器加载,若还加载不到,才会由系统类加载器或自定义的类加载器进行加载。
源码分析
protected Class<?> loadClass(String name, boolean resolve)throws ClassNotFoundException{synchronized (getClassLoadingLock(name)) {// First, check if the class has already been loadedClass<?> c = findLoadedClass(name);if (c == null) {long t0 = System.nanoTime();try {if (parent != null) {c = parent.loadClass(name, false);} else {c = findBootstrapClassOrNull(name);}} catch (ClassNotFoundException e) {// ClassNotFoundException thrown if class not found// from the non-null parent class loader}if (c == null) {// If still not found, then invoke findClass in order// to find the class.long t1 = System.nanoTime();c = findClass(name);// this is the defining class loader; record the statssun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);sun.misc.PerfCounter.getFindClasses().increment();}}if (resolve) {resolveClass(c);}return c;}}
优势劣势
如何打破
双亲委派机制可以打破吗?为什么 (京东)
可以打破双亲委派么,怎么打破。(拼多多)
Tomcat
什么是tomcat类加载机制?(猎聘)
请解释tomcat的类加载机制?(阿里)
Tomcat8 和 Tomcat6比较大的区别是 :
Tomcat8可以通过配置 表示遵循双亲委派机制。
Tomcat的类加载机制是违反了双亲委托原则的,对于一些未加载的非基础类,各个web应用自己的类加载器(WebAppClassLoader)会优先查看自己的仓库加载,加载不到时再交给commonClassLoader走双亲委托。
Tomcat 如何实现自己独特的类加载机制?
当tomcat启动时,会创建几种类加载器:
- Bootstrap 引导类加载器
加载JVM启动所需的类,以及标准扩展类(位于jre/lib/ext下) - System 系统类加载器
加载tomcat启动的类,比如bootstrap.jar,通常在catalina.bat或者catalina.sh中指定。位于CATALINA_HOME/bin下。
- CommonClassLoader、CatalinaClassLoader、SharedClassLoader和WebappClassLoader
这些是Tomcat自己定义的类加载器,它们分别加载/common/、/server/、/shared/*(在tomcat 6之后已经合并到根目录下的lib目录下)和/WebApp/WEB-INF/*中的Java类库。其中WebApp类加载器和Jsp类加载器通常会存在多个实例,每一个Web应用程序对应一个WebApp类加载器,每一个JSP文件对应一个Jsp类加载器。
commonLoader:Tomcat最基本的类加载器,加载路径中的class可以被Tomcat容器本身以及各个Webapp访问;(加载CATALINA_HOME/lib下的结构,比如servlet-api.jar)
catalinaLoader:Tomcat容器私有的类加载器,加载路径中的class对于Webapp不可见;
sharedLoader:各个Webapp共享的类加载器,加载路径中的class对于所有Webapp可见,但是对于Tomcat容器不可见;
WebappClassLoader:单个Tomcat实例中各个Web应用程序私有的类加载器,加载路径中的class只对当前Webapp可见;(加载WEB-INF/lib和WEB-INF/classes下的结构)
从图中的委派关系中可以看出:
CommonClassLoader能加载的类都可以被Catalina ClassLoader和SharedClassLoader使用,从而实现了公有类库的共用,而CatalinaClassLoader和Shared ClassLoader自己能加载的类则与对方相互隔离。
WebAppClassLoader可以使用SharedClassLoader加载到的类,但各个WebAppClassLoader实例之间相互隔离。
而JasperLoader的加载范围仅仅是这个JSP文件所编译出来的那一个.class文件,它出现的目的就是为了被丢弃:当Web容器检测到JSP文件被修改时,会替换掉目前的JasperLoader的实例,并通过再建立一个新的Jsp类加载器来实现JSP文件的HotSwap功能。
当应用需要到某个类时,则会按照下面的顺序进行类加载:
1 使用bootstrap引导类加载器加载
2 使用system系统类加载器加载
3 使用应用类加载器在WEB-INF/classes中加载
4 使用应用类加载器在WEB-INF/lib中加载
5 使用common类加载器在CATALINA_HOME/lib中加载
好了,至此,我们已经知道了tomcat为什么要这么设计,以及是如何设计的,那么,tomcat 违背了java 推荐的双亲委派模型了吗?答案是:违背了。 我们前面说过:双亲委派模型要求除了顶层的启动类加载器之外,其余的类加载器都应当由自己的父类加载器加载。
很显然,tomcat 不是这样实现,tomcat 为了实现隔离性,没有遵守这个约定,每个webappClassLoader加载自己的目录下的class文件,不会传递给父类加载器。
Tomcat中WebappClassLoader的源码分析:
1 public Class loadClass(String name, boolean resolve)2 throws ClassNotFoundException {3 Class clazz = null;4 // (0) 先从自己的缓存中查找,有则返回,无则继续5 clazz = findLoadedClass0(name);6 if (clazz != null) {7 if (resolve) resolveClass(clazz); 8 return (clazz);9 }
10 // (0.1) 再从parent的缓存中查找
11 clazz = findLoadedClass(name);
12 if (clazz != null) {
13 if (resolve) resolveClass(clazz);
14 return (clazz);
15 }
16 // (0.2) 缓存中没有,则首先使用system类加载器来加载
17 clazz = system.loadClass(name);
18 if (clazz != null) {
19 if (resolve) resolveClass(clazz);
20 return (clazz);
21 }
22 //判断是否需要先让parent代理
23 boolean delegateLoad = delegate || filter(name);
24 // (1) 先让parent加载,通常delegateLoad == false,即这一步不会执行
25
26 if (delegateLoad) {
27 ClassLoader loader = parent;
28 if (loader == null)
29 loader = system;
30 clazz = loader.loadClass(name);
31 if (clazz != null) {
32 if (resolve) resolveClass(clazz);
33 return (clazz);
34 }
35 }
36 // (2) delegateLoad == false 或者 parent加载失败,调用自身的加载机制
37 clazz = findClass(name);
38 if (clazz != null) {
39 if (resolve) resolveClass(clazz);
40 return (clazz);
41 }
42 // (3) 自己加载失败,则请求parent代理加载
43
44 if (!delegateLoad) {
45 ClassLoader loader = parent;
46 if (loader == null)
47 loader = system;
48 clazz = loader.loadClass(name);
49 if (clazz != null) {
50 return (clazz);
51 }
52 }
53 throw new ClassNotFoundException(name);
54 }
总结一下:
首先findLoadedClass0()和findLoadedClass()分别从本地和父类加载器的缓存中查找当前要加载的类是否已经加载过了。之后为了避免上面提到的安全问题,Tomcat类加载器会将加载请求委派给系统类加载器。接下来根据delegate变量的设置,决定是先由自己加载,还是先由父类加载器去加载。
1、既然 Tomcat 不遵循双亲委派机制,那么如果我自己定义一个恶意的HashMap,会不会有风险呢?(阿里面试问题)
答: 显然不会有风险,如果有,Tomcat都运行这么多年了,那能不改进吗?
tomcat不遵循双亲委派机制,只是自定义的classLoader顺序不同,但顶层还是相同的,还是要去顶层请求classloader。
2、我们思考一下:Tomcat是个web容器, 那么它要解决什么问题?
- 一个web容器可能需要部署两个应用程序,不同的应用程序可能会依赖同一个第三方类库的不同版本,不能要求同一个类库在同一个服务器只有一份,因此要保证每个应用程序的类库都是独立的,保证相互隔离。
- 部署在同一个web容器中相同的类库相同的版本可以共享。否则,如果服务器有10个应用程序,那么要有10份相同的类库加载进虚拟机,这是扯淡的。
- web容器也有自己依赖的类库,不能于应用程序的类库混淆。基于安全考虑,应该让容器的类库和程序的类库隔离开来。
- web容器要支持jsp的修改,我们知道,jsp 文件最终也是要编译成class文件才能在虚拟机中运行,但程序运行后修改jsp已经是司空见惯的事情,否则要你何用? 所以,web容器需要支持 jsp 修改后不用重启。
3、Tomcat 如果使用默认的类加载机制行不行?
答案是不行的。为什么?我们看:
第一个问题,如果使用默认的类加载器机制,那么是无法加载两个相同类库的不同版本的,默认的累加器是不管你是什么版本的,只在乎你的全限定类名,并且只有一份。
第二个问题,默认的类加载器是能够实现的,因为他的职责就是保证唯一性。
第三个问题和第一个问题一样。
我们再看第四个问题,我们想我们要怎么实现jsp文件的热替换,jsp 文件其实也就是class文件,那么如果修改了,但类名还是一样,类加载器会直接取方法区中已经存在的,修改后的jsp是不会重新加载的。那么怎么办呢?我们可以直接卸载掉这jsp文件的类加载器,所以你应该想到了,每个jsp文件对应一个唯一的类加载器,当一个jsp文件修改了,就直接卸载这个jsp类加载器。重新创建类加载器,重新加载jsp文件。
4、如果tomcat 的 Common ClassLoader 想加载 WebApp ClassLoader 中的类,该怎么办?
看了前面的关于破坏双亲委派模型的内容,我们心里有数了,我们可以使用线程上下文类加载器实现,使用线程上下文加载器,可以让父类加载器请求子类加载器去完成类加载的动作。
5、为什么java文件放在Eclipse/IDEA中的src文件夹下会优先jar包中的class?
tomcat类加载机制的理解,就不难明白。因为Eclipse/IDEA中的src文件夹中的文件java以及webContent中的JSP都会在tomcat启动时,被编译成class文件放在 WEB-INF/class 中。
而Eclipse/IDEA外部引用的jar包,则相当于放在 WEB-INF/lib 中。
因此肯定是 java文件或者JSP文件编译出的class优先加载。
沙箱安全机制
保证程序安全
保护Java原生的JDK代码
沙箱机制就是将Java代码限定在虚拟机(JVM)特定的运行范围中,并且严格限制代码对本地系统资源访问。
通过这样的措施来保证对代码的有限隔离,防止对本地系统造成破坏。
JDK9 双亲委派机制变化
相关文章:
【JVM】总结篇-类的加载篇之 类的加载器 和ClassLoader分析
文章目录 类的加载器ClassLoader自定义类加载器双亲委派机制概念源码分析优势劣势如何打破Tomcat 沙箱安全机制JDK9 双亲委派机制变化 类的加载器 获得当前类的ClassLoader clazz.getClassLoader() 获得当前线程上下文的ClassLoader Thread.currentThread().getContextClassLoa…...
Android:文件管理:打开文件意图
三步走: 一、先在AndroidManifest.xml声明provider: <providerandroid:name"androidx.core.content.FileProvider"android:authorities"${applicationId}.FileProvider"android:exported"false"android:grantUriPermi…...
《计算机网络A》单选题(详解)
《计算机网络A》单选题-复习题库 1、计算机网络最突出的优点是( D ) A、存储容量大 B、将计算机技术与通信技术相结合 C、集中计算 D、资源共享 解析:算机网络最突出的优点是 D、资源共享。通过计算机网络&…...
【SpringBoot3】Spring Boot 3.0 集成 Mybatis Plus
在Spring Boot 3.0中,你可以使用MyBatis Plus来简化数据库操作。以下是一个基本的集成示例: 1.添加依赖到你的pom.xml: <dependencies> <!-- Spring Boot Starter --> <dependency> <groupId>org.springframework.…...
第147场双周赛:子字符串匹配模式、设计任务管理器、最长相邻绝对差递减子序列、删除所有值为某个元素后的最大子数组和
Q1、子字符串匹配模式 1、题目描述 给你一个字符串 s 和一个模式字符串 p ,其中 p 恰好 包含 一个 * 符号。 p 中的 * 符号可以被替换为零个或多个字符组成的任意字符序列。 如果 p 可以变成 s 的子字符串,那么返回 true ,否则返回 false…...
数据结构C语言描述9(图文结合)--二叉树和特殊书的概念,二叉树“最傻瓜式创建”与前中后序的“递归”与“非递归遍历”
前言 这个专栏将会用纯C实现常用的数据结构和简单的算法;有C基础即可跟着学习,代码均可运行;准备考研的也可跟着写,个人感觉,如果时间充裕,手写一遍比看书、刷题管用很多,这也是本人采用纯C语言…...
开源存储详解-分布式存储与ceph
ceph体系结构 rados:reliable, autonomous, distributed object storage, rados rados采用c开发 对象存储 ceph严格意义讲只提供对象存储能力,ceph的块存储能力实际是基于对象存储库librados的rbd 对象存储特点 对象存储采用put/get/delete…...
Vue 快速入门:开启前端新征程
在当今的 Web 开发领域,Vue.js 作为一款极具人气的 JavaScript 前端框架,正被广泛应用于各类项目之中。它以简洁的语法、高效的数据绑定机制以及强大的组件化开发模式,为开发者们带来了前所未有的开发体验。如果你渴望踏入前端开发的精彩世界…...
GPT系统重大升级,开创国内先河:o1支持图片识别功能正式上线
文章目录 零、前言一、授权码登录体验优化:一步直达聊天界面二、全新“项目”功能:让工作更有条理三、语音功能升级:全新交互体验四、o1支持图片识别五、总结 零、前言 我是虚竹哥,目标是带十万人玩转ChatGPT。 亲爱的用户&…...
常用的数据结构API概览
List ArrayList 1、在初始化一个ArrayList的时候,如果我想同时set一些值 比如存放int[ ] List<int[]> list new ArrayList(Arrays.asList(new int[]{intervals[0][0],intervals[0][1]}));//或者int[] temp new int[]{intervals[0][0],intervals[0][1]}…...
《探秘计算机视觉与深度学习:开启智能视觉新时代》
《探秘计算机视觉与深度学习:开启智能视觉新时代》 一、追溯起源:从萌芽到崭露头角二、核心技术:解锁智能视觉的密码(一)卷积神经网络(CNN):图像识别的利器(二࿰…...
Linux:操作系统不朽的传说
操作系统是计算机的灵魂,它掌控着计算机的硬件和软件资源,为用户和应用程序提供了一个稳定、高效、安全的运行环境。 在众多操作系统中,Linux 的地位举足轻重。它被广泛应用于服务器、云计算、物联网、嵌入式设备等领域。Linux 的成功离不开…...
Excel重新踩坑5:二级下拉列表制作;★数据透视表;
0、在excel中函数公式不仅可以写在单元格里面,还可以写在公式里面。 1、二级下拉列表制作: 2、数据透视表: 概念:通过拖拉就能实现复杂函数才能实现的数据统计问题。 概览:在插入选项中有个数据透视表,数…...
containerd配置镜像加速(含新旧版本)
文章目录 镜像加速使用文档containerd配置说明文档host.toml配置步骤(containerd2.x新版功能,与config.toml解耦,无需重启containerd)传统配置(需要重启containerd) 镜像加速使用文档 关于镜像加速的使用可…...
国产编辑器EverEdit - 常用资源汇总
1 国产编辑器EverEdit-常用资源汇总 EverEdit是一款国产文本编辑器,历经超过15年的更新和维护,拥有不输业界顶级商业文本编辑器(EmEditor、UltraEdit)的实力,甚至在某些方面的功能更强(当然,各有千秋),开发者对文本编辑…...
应急指挥系统总体架构方案
引言 应急指挥系统总体架构方案旨在构建一个高效、智能的应急管理体系,以应对自然灾害、事故灾难等突发事件,保障人民生命财产安全。 背景与挑战 近年来,安全生产形势严峻,自然灾害事故频发,对应急指挥系统的要求越…...
Edge Scdn的应用场景有哪些?
酷盾安全Edge Scdn 具备强大的安全防护能力,通过多层防御机制,如防火墙、DDoS 攻击防护、入侵检测和防御、数据加密等,有效抵御各种网络攻击,包括 DDoS 攻击、CC 攻击、SQL 注入攻击、XSS 跨站脚本攻击等,保障网站和应…...
LeetCode:98.验证二叉搜索树
跟着carl学算法,本系列博客仅做个人记录,建议大家都去看carl本人的博客,写的真的很好的! 代码随想录 LeetCode:98.验证二叉搜索树 给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树。 有效 …...
mysql报错2059
客户端连接mysql服务时提示2059错误,通常与身份验证插件有关,具体表现为客户端无法加载指定的身份验证插件。这个错误在MySQL 8.0及更高版本中较为常见,因为从MySQL 8.0开始,默认的加密规则从mysql_native_password变为了caching_…...
2025/1/4期末复习 密码学 按老师指点大纲复习
我们都要坚信,道路越是曲折,前途越是光明。 --------------------------------------------------------------------------------------------------------------------------------- 现代密码学 第五版 杨波 第一章 引言 1.1三大主动攻击 1.中断…...
【数据仓库金典面试题】—— 包含详细解答
大家好,我是摇光~,用大白话讲解所有你难懂的知识点 该篇面试题主要针对面试涉及到数据仓库的数据岗位。 以下都是经典的关于数据仓库的问题,希望对大家面试有用~ 1、什么是数据仓库?它与传统数据库有何区别? 数据仓库…...
deepFM模型pytorch实现
deepFM deepfm包含两个部分:因子分解机FM和神经网络DNN,分别负责低阶特征和高阶特征的提取。可以处理全是分类特征的数据,或者分类与数值型结合的数据。 FM部分是对一阶特征和二阶特征(一阶特征之间的交互)的处理。 …...
【Linux】传输层协议UDP
目录 再谈端口号 端口号范围划分 UDP协议 UDP协议端格式 UDP的特点 UDP的缓冲区 UDP注意事项 进一步深刻理解 再谈端口号 在上图中,有两个客户端A和B,客户端A打开了两个浏览器,这两个客户端都访问同一个服务器,都访问服务…...
MOE怎样划分不同专家:K-Means聚类算法来实现将神经元特征聚类划分
MOE怎样划分不同专家:K-Means聚类算法来实现将神经元特征聚类划分 目录 MOE怎样划分不同专家:K-Means聚类算法来实现将神经元特征聚类划分MOE划分不同专家的方法K-Means聚类算法来实现将神经元特征聚类划分成不同专家(行或者列聚类)举例说明怎么聚类,最后神经网络怎么保存M…...
Redis两种主要的持久化方式是什么?
Redis支持两种主要的持久化方式,它们分别是RDB(Redis Database Snapshotting)和AOF(Append Only File)。以下是这两种持久化方式的详细介绍: 一、RDB(Redis Database Snapshotting) …...
【生活】冬天如何选口罩(医用口罩,N95, KN95还是KP95?带不带呼吸阀门?带不带活性炭?)
💡总结一下就是: 日常防护的话,医用口罩就可以啦。要是想长时间佩戴N95(KN95)口罩的话也可以. 在高风险环境(像医院、疫情防控期间),一定要选不带呼吸阀门的N95口罩KN95)…...
机器学习基础-卷积的计算
1 掌握卷积计算的基本过程 1.1 单通道单卷积核 如图3所示,现在有一张形状为[5,5,1]的灰度图,我们需要用图3右边的卷积核对其进行卷积处理,同时再考虑到偏置的作用。计算过程如下: 1.2 单通道多卷积核 如下图所示,左…...
使用LINUX的dd命令制作自己的img镜像
为了避免重复安装同一镜像,配置环境,首先我准备一个正常使用的完整系统。 使用Gparted软件先将母盘(如U盘,TF卡)分区调整为只有数据的大小。如:60G的TF卡,只用了3.5G,将未使用的空间…...
pdf预览兼容问题- chrome浏览器105及一下预览不了
使用的"tato30/vue-pdf": "^1.11.2"预览插件,发现chrome浏览器105及一下预览不了 pdfPreview预览组件: <template><div id"vue_pdf_view"><div class"tool_tip"><template v-if"pa…...
SpringBoot中实现拦截器和过滤器
【SpringBoot中实现过滤器和拦截器】 1.过滤器和拦截器简述 过滤器Filter和拦截器Interceptor,在功能方面很类似,但在具体实现方面差距还是比较大的。 2.过滤器的配置 2.1 自定义过滤器,实现Filter接口(SpringBoot 3.0 开始,jak…...
基于深度学习的视觉检测小项目(六) 项目的信号和变量的规划
• 关于前后端分离 当前流行的一种常见的前后端分离模式是vueflask,vueflask模式的前端和后端之间进行数据的传递通常是借助 API(应用程序编程接口)来完成的。vue通过调用后端提供的 API 来获取或提交数据。例如,前端可能通过发送…...
GitHub的简单操作
引言 今天开始就要开始做项目了,上午是要把git搭好。搭的过程中遇到好多好多的问题。下面就说一下git的简单操作流程。我们是使用的GitHub,下面也就以这个为例了 一、GitHub账号的登录注册 https://github.com/ 通过这个网址可以来到GitHub首页 点击中间绿色的S…...
LLM大语言模型自动化测试(ROUGE和RAGAS)及优化方案
1. 模型自动化测试 模型的测试中,不同类型的任务评测指标有显著差异,比如: 分类任务: 准确率(Accuracy):正确预测的比例。 精确度(Precision)、召回率(Recal…...
你已经分清JAVA中JVM、JDK与JRE的作用和关系了吗?
你已经分清JAVA中JVM、JDK与JRE的作用和关系了吗? 一. JVM、JDK与JRE的关系二. JVM、JDK与JRE的作用2.1 什么是JVM?2.2 什么是JDK?2.3 什么是JRE? 前言 点个免费的赞和关注,有错误的地方请指出,看个人主页有…...
实际开发中,常见pdf|word|excel等文件的预览和下载
实际开发中,常见pdf|word|excel等文件的预览和下载 背景相关类型数据之间的转换1、File转Blob2、File转ArrayBuffer3、Blob转ArrayBuffer4、Blob转File5、ArrayBuffer转Blob6、ArrayBuffer转File 根据Blob/File类型生成可预览的Base64地址基于Blob类型的各种文件的下载各种类型…...
Elasticsearch:Lucene 2024 年回顾
作者:来自 Elastic Chris Hegarty 2024 年对于 Apache Lucene 来说又是重要的一年。在本篇博文中,我们将探讨主要亮点。 Apache Lucene 在 2024 年表现出色,发布了许多版本,包括三年来的首次重大更新,其中包含令人兴奋…...
springboot实战纪实-课程介绍
教程介绍 Spring Boot是由Pivotal团队提供的一套开源框架,可以简化spring应用的创建及部署。它提供了丰富的Spring模块化支持,可以帮助开发者更轻松快捷地构建出企业级应用。 Spring Boot通过自动配置功能,降低了复杂性,同时支持…...
什么是TDD测试驱动开发(Test Driven Development)?
什么是测试驱动开发? 软件开发团队通常会编写自动化测试套件来防止回归。这些测试通常是在编写应用程序功能代码之后编写的。我们将采用另一种方法:在实现应用程序代码之前编写测试。这称为测试驱动开发 (TDD)。 为什么要应用 TDD?通过在实…...
学习随记:word2vec的distance程序源码注释、输入输出文件格式说明
word2vec中有5个程序,其中demo-word.sh中涉及两个:word2vec、distance。考虑到distance比较简单,所以我从这个入手,希望通过简单代码理解如何在一个高维数据空间计算距离(查找)。一维数据的查找,…...
CSS 之 position 定位属性详解
CSS系列文章目录 CSS 之 display 布局属性详解 CSS 之 position 定位属性详解一文搞懂flex布局 【弹性盒布局】 文章目录 CSS系列文章目录一、前言二、静态定位:position:static;二、相对定位:position:relative三、绝对定位:pos…...
初学STM32 --- USMART
目录 USMART简介 USMART主要特点: USMART原理 USMART组成: USMART 的实现流程简单概括 USMART扫描函数: USMART系统命令 USMART移植 USMART简介 USMART是一个串口调试组件,可以大大提高代码调试效率! USMART主…...
MySQL叶子节点为啥使用双向链表?不使用单向呢?
文章内容收录到个人网站,方便阅读:http://hardyfish.top/ 文章内容收录到个人网站,方便阅读:http://hardyfish.top/ 文章内容收录到个人网站,方便阅读:http://hardyfish.top/ MySQL 中的 B 树索引&#x…...
4_TypeScript 条件语句 --[深入浅出 TypeScript 测试]
在 TypeScript 中,条件语句用于根据不同的条件执行不同的代码块。这些语句包括 if 语句、else if 语句、else 语句和 switch 语句。通过使用条件语句,你可以编写出能够根据特定逻辑分支的代码,从而实现更加动态和灵活的功能。 1. if 语句 i…...
vue elementUI Plus实现拖拽流程图,不引入插件,纯手写实现。
vue elementUI Plus实现拖拽流程图,不引入插件,纯手写实现。 1.设计思路:2.设计细节3.详细代码实现 1.设计思路: 左侧button列表是要拖拽的组件。中间是拖拽后的流程图。右侧是拖拽后的数据列表。 我们拖动左侧组件放入中间的流…...
图漾相机基础操作
1.客户端概述 1.1 简介 PercipioViewer是图漾基于Percipio Camport SDK开发的一款看图软件,可实时预览相机输出的深度图、彩色图、IR红外图和点云图,并保存对应数据,还支持查看设备基础信息,在线修改gain、曝光等各种调节相机成像的参数功能…...
【阅读笔记】基于FPGA的红外图像二阶牛顿插值算法的实现
图像缩放技术在图像显示、传输、分析等多个领域中扮演着重要角色。随着数字图像处理技术的发展,对图像缩放质量的要求也越来越高。二阶牛顿插值因其在处理图像时能够较好地保持边缘特征和减少细节模糊,成为了图像缩放中的一个研究热点。 一、 二阶牛顿插…...
K210识别技术简介与基础使用方法
目录 一、K210芯片概述 二、K210的硬件配置与开发环境 1. 硬件配置 2. 开发环境 三、K210的识别技术基础 1. 图像识别 2. 语音识别 四、K210识别技术的基础使用方法 1. 图像识别基础使用 2. 语音识别基础使用 五、K210识别技术的应用场景 六、总结与展望 一、K210芯…...
【Android学习】Adapter中使用Context
参考文章 文章目录 1. 通过 Adapter 构造函数传入 Context2. 通过 Parent.context 获取3. 通过 onAttachedToRecyclerView() 方法获取4. 通过 ImageView 获取 context (局限于本例子中)5. 四种方法对比分析6. 作者推荐的方法 需求: Glide加载图片需要用到Context 1…...
LLM大模型RAG内容安全合规检查
1.了解内容安全合规涉及的范围 我们先回顾一下智能答疑机器人的问答流程。问答流程主要包括用户、智能答疑机器人、知识库、大语言模型这四个主体。 涉及内容安全的关键阶段主要有: 输入阶段:用户发起提问。 输出阶段:机器人返回回答。 知识…...
Flink operator实现自动扩缩容
官网文档位置: 1.Autoscaler | Apache Flink Kubernetes Operator 2.Configuration | Apache Flink Kubernetes Operator 1.部署K8S集群 可参照我之前的文章k8s集群搭建 2.Helm安装Flink-Operator helm repo add flink-operator-repo https://downloads.apach…...