都工作3年了,怎么能不懂双亲委派呢?(带你手把手断点源码)
💗推荐阅读文章💗
- 🌸JavaSE系列🌸👉1️⃣《JavaSE系列教程》
- 🌺MySQL系列🌺👉2️⃣《MySQL系列教程》
- 🍀JavaWeb系列🍀👉3️⃣《JavaWeb系列教程》
- 🌻SSM框架系列🌻👉4️⃣《SSM框架系列教程》
🎉本博客知识点收录于🎉👉🚀《JavaSE系列教程》🚀—>✈️18【枚举、类加载器、动态代理】✈️
文章目录
二、类加载器
2.1 类加载时机
我们知道,所有的代码都是运行在内存中的,我们必须把类加载到内存中才能运行;在Java中,所有的Java类都是通过类加载器加载到内存进行执行的;
- 一个类何时被加载?
- 1)main方法所在的类总是被首先初始化
- 2)创建该类对象时,首先会将内加载到内存(如果该类存在父类,那么首先加载父类到内存,创建父类的对象(super))
- 3)访问该类的静态成员时,会将类加载到内存(该静态成员不能被fianl修饰)
- 4)class.forName(“类的全包名”)
package com.dfbz.demo01;
import org.junit.Test;
/*** @author lscl* @version 1.0* @intro:*/
public class Demo01_类何时被加载 {@Testpublic void test1() throws ClassNotFoundException {
// new B(); // 先加载A再加载B
// Integer num = B.num; // 先加载A再加载BClass<?> clazz = Class.forName("com.dfbz.demo01.B"); // 先加载A再加载B}
}
class A {public static Integer num = 10;static {System.out.println("A loader...");}
}
class B extends A {public static Integer num = 20;static {System.out.println("B loader...");}
}
Tips:不管是用什么方法加载,类从始至终只会加载一次;
2.3 类加载器
2.3.1 类加载器的种类
- 启动类加载器Bootstrap ClassLoader: 是嵌在JVM内核中的加载器,该加载器是用C++语言写的,主要负则加载JAVA_HOME/lib下的类库,启动类加载器无法被应用程序直接使用。
- **扩展类加载器Extension ClassLoader:**该加载器器是用JAVA编写,且它的父加载器是Bootstrap,是由sun.misc.Launcher$ExtClassLoader实现的,主要加载JAVA_HOME/lib/ext目录中的类库。开发者可以这几使用扩展类加载器。
- **系统类加载器App ClassLoader:**系统类加载器,也称为应用程序类加载器,负责加载应用程序classpath目录下的所有jar和class文件(第三方jar)。它的父加载器为Ext ClassLoader。
Tips:这里的父加载器并非是Java中的继承关系,而是我们后面学习双亲委派过程中向上委派的加载器,我们将其称为父加载器;
测试类:
package com.dfbz.demo01;
import com.dfbz.demo02.Demo02;
import com.sun.java.accessibility.AccessBridge;
import org.junit.Test;
/*** @author lscl* @version 1.0* @intro:*/
public class Demo02_类加载器的种类 {@Testpublic void test1(){// Bootstrap类加载器是获取不到的,为nullSystem.out.println("Bootstrap ClassLoader: "+ String.class.getClassLoader());// jre\lib\ext\access-bridge-64.jarSystem.out.println("ExtClassLoader ClassLoader: "+ AccessBridge.class.getClassLoader());System.out.println("AppClassLoader ClassLoader: "+ Demo02.class.getClassLoader());}
}
2.3.2 双亲委派机制
从JDK1.2开始,类的加载过程采用双亲委派机制,它是一种任务委派模式。即把加载类的请求交由父加载器处理,一直到顶层的父加载器(BootstrapClassLoader);如果父加载器能加载则用父加载器加载,否则才用子加载器加载该类;
- 示例代码:
package com.dfbz.demo01;
import org.junit.Test;
/*** @author lscl* @version 1.0* @intro:*/
public class Demo03_类加载的过程 {@Testpublic void test1() {Class<T> tClass = T.class;System.out.println(tClass);}class T {}
}
JVM在加载类时,会调用类加载器(ClassLoader)的loadClass方法进行加载;
ClassLoader类加载源码:
protected Class<?> loadClass(String name, boolean resolve)throws ClassNotFoundException
{synchronized (getClassLoadingLock(name)) {// 检查该类是否被加载过Class<?> c = findLoadedClass(name);if (c == null) {long t0 = System.nanoTime();try {if (parent != null) {// 使用父加载器加载c = parent.loadClass(name, false);} else {// 如果没有父加载器则使用BootstrapClassLoader加载c = findBootstrapClassOrNull(name);}} catch (ClassNotFoundException e) {// ClassNotFoundException thrown if class not found// from the non-null parent class loader}if (c == null) {// 如果依旧没有加载,则调用自身的findClass方法进行加载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;}
}
findClass方法源码:
protected Class<?> findClass(String name) throws ClassNotFoundException {throw new ClassNotFoundException(name);
}
可以看到,默认情况下ClassLoader的findClass方法只是抛出了一个异常而已(这个方法是留给我们写的)
- 双亲委派机制流程图:
- 1)从上图我们可以分析,当一个Demo.class这样的文件要被加载时,首先会在AppClassLoader中检查是否加载过,如果有那就无需再加载了。
- 2)如果没有加载,那么会拿到父加载器(向上委派),然后调用父加载器的loadClass方法进行加载。AppClassLoader的父加载器为ExtClassLoader,而ExtClassLoader并没有重写loadClass方法,因此还是调用ClassLoader类的loadClass方法,相当于是一个递归的操作;
- 3)父类中同理也会先检查自己是否已经加载过,如果没有再往上。注意是个递归的过程,直到到达Bootstrap classLoader之前,都是在检查是否加载过,并不会选择自己去加载。直到BootstrapClassLoader,已经没有父加载器了,这时候开始考虑自己是否能加载了,如果自己无法加载,会下沉到子加载器去加载,一直到最底层,如果没有任何加载器能加载,就会抛出ClassNotFoundException。
BootstrapClassLoader不能加载该类,因此还是为null,然后调用本类的findClass方法;这里需要注意两点:
- 1)本类还是ExtClassLoader
- 2)ExtClassLoader是自身没有findClass方法,但ExtClassLoader继承与URLClassLoader,并且URLClassLoader提供有findClass方法;
接下来调用到URLClassLoader类中的findClass方法来加载该类:
URLClassLoader类中的findClass方法无法加载我们传递的类,然后向上抛出了一个异常;这里需要注意:
- 1)URLClassLoader类中的findClass方法是通过ExtClassLoader调用findClass方法进去的,因此向上抛出异常后,findClass方法后面的代码将不会执行了,并且触发的异常继续往上抛给调用者(调用loadClass的对象)
- 2)ExtClassLoader的loadClass方法是在AppClassLoader中,通过parent.loadClass()调用进去的,因此异常被抛到了这里;
异常被抛到了AppClassLoader中的loadClass方法中,接着尝试使用AppClassLoader的findClass()方法来加载类;
最终交给AppClassLoader完成类的加载:
2.3.3 双亲委派的好处
我们已经了解了Java中类加载的双亲委派机制,**即加载类时交给父加载器加载,如果父加载器不能加载,再交给子加载器加载;**这样做有何好处呢?
- 1)避免类的重复加载:当父类加载器已经加载了该类时,就没有必要子 ClassLoader 再加载一次。
- 2)安全问题:有了双亲委派机制,当有人想要替换系统级别的类或者篡改他的实现时,在双亲委派机制下,在任何的Java代码运行之前,会将所有要用到的系统类提前使用BootstrapClassLoader加载进内存(而当一个类需要被加载时必定会轮到BootstrapClassLoader来加载,只是是否能加载的问题,不能加载的必定不是系统级别的类),所以其他类加载器并没有机会再去加载,从一定程度上防止了危险代码的植入。
在指定的系统包下建立指定的类(由BootstrapClassLoader、ExtClassLoader加载的系统类):
- Object:
package java.lang;
/*** @author lscl* @version 1.0* @intro:*/
public class Object {static {System.out.println("自定义的Object类被加载了....");}
}
- AccessBridge:
package com.sun.java.accessibility;
/*** @author lscl* @version 1.0* @intro:*/
public class AccessBridge {static {System.out.println("自定义的AccessBridge类被加载了.....");}
}
- 测试类:
package com.dfbz.demo01;
import com.sun.java.accessibility.AccessBridge;
import org.junit.Test;
/*** @author lscl* @version 1.0* @intro:*/
public class Demo04_双亲委派的好处 {@Testpublic void test1() {// java.lang.Object 类在JVM启动时就已经被加载过了,因此不会再被加载了Class<Object> clazz = Object.class;// com.sun.java.accessibility.AccessBridge 类在JVM启动时就已经被加载过了,因此不会再被加载了Class<AccessBridge> accessBridgeClass = AccessBridge.class;}
}
Tips:根据双亲委派机制,我们自定义的Object、AccessBridge类不可能被加载;
另外,JVM的类加载器对包名的定义也有限制;不允许我们自定义系统包名
在系统包名下创建任意一个类:
@Test
public void test2() {// 不允许用户将类定义在受限包名下 ,Prohibited package name: java.langClass<AA> clazz = AA.class;
}
运行结果:
2.3.4 URLClassLoader类加载器
在 java.net 包中,JDK提供了一个更加易用的类加载器URLClassLoader,它扩展了 ClassLoader,能够从本地或者网络上指定的位置加载类,我们可以使用该类作为自定义的类加载器使用。
URLClassLoader的构造方法:
public URLClassLoader(URL[] urls)
:指定要加载的类所在的URL地址,父类加载器默认为系统类加载器public URLClassLoader(URL[] urls, ClassLoader parent)
:指定要加载的类所在的URL地址,并指定父类加载器。
1)加载本地磁盘上的类:
在指定目录下准备一个Java文件并把它编译成class文件:
- Show.java:
package com.dfbz.demo01;
/*** @author lscl* @version 1.0* @intro:*/
public class Show {public Show(){System.out.println("new Show....");}
}
- 编译文件:
D:\000\com\dfbz\demo01>javac Show.java
D:\000\com\dfbz\demo01>
- 测试代码:
package com.dfbz.demo01_类加载器的功能;
import org.junit.Test;
import java.io.File;
import java.net.URI;
import java.net.URL;
import java.net.URLClassLoader;
/*** @author lscl* @version 1.0* @intro:*/
public class Demo05_URLClassLoader {@Testpublic void test() throws Exception{File file = new File("D:\\000");// file ---> URIURI uri = file.toURI();// URI ---> URLURL url = uri.toURL();// 根据URL构建一个类加载器URLClassLoader classLoader = new URLClassLoader(new URL[]{url});System.out.println("父类加载器:" + classLoader.getParent()); // 默认父类加载器是系统类加载器Class clazz = classLoader.loadClass("com.dfbz.demo01.Show");// 实例化这个类clazz.newInstance();}
}
运行结果:
2)加载网络上的类:
@Test
public void test2() throws Exception{// 构建一个网络地址URL url = new URL("http://www.baidu.com/class/");URLClassLoader classLoader = new URLClassLoader(new URL[]{url});System.out.println("父类加载器:" + classLoader.getParent()); // 默认父类加载器是系统类加载器Class clazz = classLoader.loadClass("com.baidu.demo.Show");// 实例化这个类clazz.newInstance();
}
Tips:关于加载网络上的类,等我们以后学习了服务器编程再来体验!
2.3.5 自定义类加载器
我们如果需要自定义类加载器,只需要继承ClassLoader,并覆盖掉findClass方法即可。
Tips:我们自定义的类加载器的父加载器为AppClassLoader;
- 自定义类加载器:
package com.dfbz.demo02;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
// 1. 继承 ClassLoader
// 2. 覆盖 findClass方法
public class MyClassLoader extends ClassLoader {// 被加载类所在的目录private String dir;public MyClassLoader(String dir) { // 默认父类加载器就是系统类加载器 AppClassLoaderthis.dir = dir;}public MyClassLoader(ClassLoader parent, String dir) {super(parent);this.dir = dir;}/**** @param name* @return 重写findClass方法* @throws ClassNotFoundException*/@Overrideprotected Class<?> findClass(String name) throws ClassNotFoundException {try {// 把类名转换为目录 ---> D:/000/com/dfbz/demo01/Show.classString file = dir + "/" + name.replace(".", "/") + ".class";// 从文件中读取这个Class文件InputStream in = new FileInputStream(file);// 构建一个内存输出流(将读取到的Class文件写在内存中)ByteArrayOutputStream baos = new ByteArrayOutputStream();byte[] buf = new byte[1024];int len ;while ((len = in.read(buf)) != -1) {baos.write(buf, 0, len);}// 读取到的流的二进制数据byte[] data = baos.toByteArray();in.close();baos.close();/*defineClass: 根据类的全包名和内存中的数据流来加载一个类- 参数1: 需要加载类的全包名- 参数2: 已经加载到内存中的数据流- 参数3: 从指定的数据下表开始读取- 参数4: 读取到什么位置*/return defineClass(name, data, 0, data.length);} catch (IOException e) {throw new RuntimeException(e);}}
}
- 测试类:
package com.dfbz.demo02;
/*** @author lscl* @version 1.0* @intro:*/
public class Demo01_自定义类加载器的使用 {public static void main(String[] args) throws Exception{// 创建我们自己的类加载器MyClassLoader classLoader = new MyClassLoader("d:/000");// 使用loadClass加载类Class<?> clazz = classLoader.loadClass("com.dfbz.demo01.Show");clazz.newInstance();}
}
2.3.6 打破双亲委派
我们前面自定义了类加载器,观察下面代码:
package com.dfbz.demo02_自定义类加载器;
/*** @author lscl* @version 1.0* @intro:*/
public class Demo02_打破双亲委派_01 {public static void main(String[] args) throws Exception {MyClassLoader classLoader = new MyClassLoader("d:/000");MyClassLoader classLoader2 = new MyClassLoader("d:/000");Class<?> clazz = classLoader.loadClass("com.dfbz.demo01.Show");Class<?> clazz2 = classLoader2.loadClass("com.dfbz.demo01.Show");System.out.println(clazz == clazz2); // trueSystem.out.println(clazz.getClassLoader()); // sun.misc.Launcher$AppClassLoader@18b4aac2System.out.println(clazz2.getClassLoader()); // sun.misc.Launcher$AppClassLoader@18b4aac2}
}
运行结果:
根据我们之前学习双亲委派机制,上面两个类加载器在加载Show类时,都会判断有没有加载这个类,没有加载则使用父加载器加载,MyClassLoader的父加载器是AppClassLoader,而AppClassLoader正好可以加载这个类;所以其实这两次的加载都是由AppClassLoader来加载的,而AppClassLoader在加载时会判断是否已经加载过,加载过了则不加载;因此Show类只会加载一次;
但是需要注意的是,双亲委派机制的逻辑是写在ClassLoader类的loadClass方法中的,通过一系列逻辑判断最终执行findClass方法来加载类;如果我们加载类直接使用findClass方法呢?那就相当于避开了双亲委派;(当然也可以重写loadClass方法,重新自定义loadClass规则)
- 测试类:
package com.dfbz.demo02;
/*** @author lscl* @version 1.0* @intro:*/
public class Demo03_打破双亲委派_02 {public static void main(String[] args) throws Exception{MyClassLoader classLoader = new MyClassLoader("d:/000");MyClassLoader classLoader2 = new MyClassLoader("d:/000");// 不使用loadClass来加载类,直接使用findClass方法去加载类,每一次调用findClass都相当于是加载一次新的类Class<?> clazz = classLoader.findClass("com.dfbz.demo01.Show");Class<?> clazz2 = classLoader2.findClass("com.dfbz.demo01.Show");System.out.println(clazz == clazz2); // falseSystem.out.println(clazz.getClassLoader()); // com.dfbz.demo02.MyClassLoader@135fbaa4System.out.println(clazz2.getClassLoader()); // com.dfbz.demo02.MyClassLoader@330bedb4}
}
运行结果:
2.2 类的加载过程
2.2.1 类的生命周期
一个Java类从开始到结束整个生命周期会经历7个阶段:加载(Loading)、验证(Verification)、准备(Preparation)、解析(Resolution)、初始化(Initialization)、使用(Using)和卸载(Unloading)。
其中验证、准备、解析三个部分又统称为连接(Linking)。
1)加载
加载过程就是把class字节码文件载入到虚拟机中,至于从哪儿加载,虚拟机设计者并没有限定,你可以从文件、压缩包、网络、数据库等等地方加载class字节码。
类加载的方式有:
- 1)通过类的全限定名来获取定义此类的二进制字节流
- 2)将此二进制字节流所代表的静态存储结构转化成方法区的运行时数据结构(加载到内存)
- 3)在内存中生成代表此类的java.lang.Class对象(在堆中),作为该类访问入口;
2)连接
连接阶段的开始,并不一定等到加载阶段结束。加载阶段与连接阶段的部分内容(如一部分字节码文件格式验证动作)是交叉进行的,加载阶段尚未完成,连接阶段可能已经开始,但这些夹杂在加载阶段之中的动作任然属于连接阶段,加载和连接这两个阶段的开始顺序是固定的。
- 验证:验证节点主要确保Class文件的格式正确,运行时不会危害JVM的安全;包含文件格式验证、元数据验证、字节码验证、符号引用验证等;
- 准备:准备阶段会为类变量(被static修饰的变量)分配内存并设置类变量的初始值,这些变量所使用的内存都将在方法区中分配。
假如有一个变量private static int value = 123;
那么value在准备阶段过后值是0,而不是123;因为这个时候尚未执行任何java方法,而把value赋值为123的动作在初始化阶段才会执行。
但是如果上面的变量被final修饰,变为:private static final int value = 123;
编译时javac会为value生成ConstantValue属性,在准备阶段虚拟机就会根据ConstantValue的设置将value赋值为123。 - 解析:解析阶段是虚拟机将常量池内的符号引用替换为直接引用的过程。
Tips:
- 符号引用:在编译的时候每个java类都会被编译成一个class文件,但在编译的时候虚拟机并不知道所引用类的地址,所以就用符号引用来代替,而在这个解析阶段就是为了把这个符号引用转化成为真正的地址的阶段。
- 直接引用:直接引用可以直接指向目标的指针,如果有了直接引用,那引用的目标必定已经在内存中存在。
解析动作主要针对类或接口、字段、类方法、接口方法、方法类型方法句柄和调用点限定符7类符号引用进行。
3)初始化
类初始化是类加载过程的最后一步,这一步会真正开始执行类中定义的Java程序代码(或者说字节码)。在准备阶段,变量已经被赋过一次系统要求的初始值,在初始化阶段,变量会再次赋值为程序员设置的值。比如变量:private static int value = 123;
那么value在准备阶段过后值是0,初始化阶段后值是123。
会导致 类加载 的情况
- 1)main方法所在的类总是被首先初始化
- 2)创建该类对象时,首先会将内加载到内存(如果该类存在父类,那么首先加载父类到内存,创建父类的对象(super))
- 3)访问该类的静态成员时,会将类加载到内容(该静态常量不能被final修饰的基本类型和字符型)
- 4)class.forName(“类的全包名”)
不会导致 类加载 的情况
- 1)访问 类的 static final 静态变量(基本类型和字符型)不会触发初始化
- 2)类对象.class 不会触发初始化
- 3)创建该类的数组不会触发初始化
- 4)Class.forName 的参数2 为 false 时
测试类:
package com.dfbz.demo03_类的初始化流程;
/*** @author lscl* @version 1.0* @intro:*/
public class Demo01_测试类 {public static void main(String[] args) {System.out.println(A.B); // 访问类中的final成员类并不会初始化System.out.println(A.OBJ); // 访问非基本数据类型和String时将会初始化AClass<A> aClass = A.class; // 类已经初始化过一次了,并不会再次初始化System.out.println(aClass);}
}
class A {static {System.out.println("A加载了");}public static final String B = "1";
// public static final String B = new String(); // 如果访问的是堆内存中的String,那么A将会被加载public static final Obj OBJ = new Obj();
}
class Obj{}
相关文章:
都工作3年了,怎么能不懂双亲委派呢?(带你手把手断点源码)
💗推荐阅读文章💗 🌸JavaSE系列🌸👉1️⃣《JavaSE系列教程》🌺MySQL系列🌺👉2️⃣《MySQL系列教程》🍀JavaWeb系列🍀👉3️⃣《JavaWeb系列教程》…...
Hive 运行环境搭建
文章目录Hive 运行环境搭建一、Hive 安装部署1、安装hive2、MySQL 安装3、Hive 元数据配置到 Mysql1) 拷贝驱动2) 配置Metastore 到 MySQL3) 再次启动Hive4) 使用元数据服务的方式访问Hive二、使用Dbaver连接HiveHive 运行环境搭建 HIve 下载地址:http://archive.a…...
SAP ABAP 深度解析Smartform打印特殊符号等功能
ABAP 开发人员可以在 Smartform 输出上显示 SAP 图标或 SAP 符号。例如,需要在 SAP Smart Forms 文档上显示复选框形状的输出。SAP Smartform 文档上可以轻松显示空复选框、标记复选框以及 SAP 图标等特殊符号。 在 SAP Smartform 文档中添加一个新的文本节点。 1. 单击“更…...
React17+React Hook+TS4 最佳实践仿 Jira 企业级项目笔记
前言 个人笔记,记录个人过程,如有不对,敬请指出React17React HookTS4 最佳实践仿 Jira 企业级项目项目完成到第十章,剩下后面就没有看了,说的不是特别好 github地址:https://github.com/superBiuBiuMan/React-jira husky方便我们管理git hooks的工具 REST-API风格 https://zh…...
35- tensorboard的使用 (PyTorch系列) (深度学习)
知识要点 FashionMNIST数据集: 十种产品的分类. # T-shirt/top, Trouser, Pullover, Dress, Coat,Sandal, Shirt, Sneaker, Bag, Ankle Boot.writer SummaryWriter(run/fashion_mnist_experiment_1) # 网站显示一 tensorboard的使用 在网站显示pytorch的架构:1.1 …...
ChatGPT在工业领域的用法
在工业数字化时代,我们需要怎么样的ChatGPT? 近日,ChatGPT热度高居不下,强大的人机交互能力令人咋舌,在国内更是掀起一股讨论热潮。一时间,这场由ChatGPT引起的科技飓风,使得全球最顶尖科技力量…...
使用Chakra-UI封装简书的登录页面组件(React)
要求:使用chakra ui和react 框架将简书的登录页面的表单封装成独立的可重用的组件使用到的API:注册API请求方式:POST 请求地址:https://conduit.productionready.io/api/users请求数据: {"user":{ "username&quo…...
Three.js初试——基础概念(二)
前言 姊妹篇:Three.js初试——基础概念 介绍了 Three.js 的一些核心要素概念,这篇文章会讲一下它的关键要素概念。 之前我们了解到展示一个3D图像,必须要有场景、相机、渲染器这些核心要素,仅仅这些还不够,我们还需要…...
Qt音视频开发21-mpv内核万能属性机制
一、前言 搞过vlc内核后又顺带搞了搞mpv内核,mpv相比vlc,在文件数量、sdk开发便捷性方面绝对占优势的,单文件(可能是静态编译),不像vlc带了一堆插件,通过各种属性来set和get值,后面…...
C语言学生随机抽号演讲计分系统
6.学生随机抽号演讲计分系统(★★★★) 设计一款用于课程大作业检查或比赛计分的软件,基本功能: (1)设置本课程的学生总数 (2)根据本次参与的学生总数,随机抽取一个还未汇报演讲的学生的学号。 (3)每个学生汇报演讲完毕,输入该学生…...
Spring Boot 3.0系列【12】核心特性篇之任务调度
有道无术,术尚可求,有术无道,止于术。 本系列Spring Boot版本3.0.3 源码地址:https://gitee.com/pearl-organization/study-spring-boot3 文章目录 前言Spring Scheduler1. 单线程任务2. 自动配置3. 多线程异步任务Quartz1. 简介2. 核心组件2.1 Job(任务)2.2 Trigger(…...
Java操作XML
Java操作XML XML语法 一个XML文件分为文档声明、元素、属性、注释、CDATA区、特殊字符、处理指令。 转义字符 对于一些单个字符,若想显示其原始样式,也可以使用转义的形式予以处理。 & > & < > < > > > " &g…...
女神节灯笼祝福【HTML+CSS】
✅作者简介:2022年博客新星 第八。热爱国学的Java后端开发者,修心和技术同步精进。 🍎个人主页:Java Fans的博客 🍊个人信条:不迁怒,不贰过。小知识,大智慧。 💞当前专栏…...
CUDA并行计算基础知识
1、相关缩写术语 显卡:GPU 显卡驱动:驱动软件 GPU架构: 硬件的设计方式,例如是否有L1 or L2缓存 CUDA: 一种编程语言像C++, Python等,只不过它是专门用来操控GPU的 cudnn: 一个专门为深度学习计算设计的软件库,里面提供了很多专门的计算函数 CUDAToolkit:所谓的装cuda首先…...
88. 合并两个有序数组
给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2 中的元素数目。请你 合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。注意:最终,合并后数组不应…...
卢益贵(码客):软件开发团队的管理要素
卢益贵(码客):软件开发团队的管理要素 最好的范例是领导 无论个人素养、技术水平和代码风格,管理者应该起到典范的作用。 最高的权力是威望 管理者的威望比手中权力更有信服力。在处处倚仗权力施压的团队中,高压必有…...
中小企业的TO B蓝海,如何「掘金」?
中国中小企业的数字化转型土壤,如今究竟成长到了哪一步?对一众数字服务厂商而言,在另一个付费群体出现的当下,产品形态是否应该进行微调? 作者|皮爷 出品|产业家 中国市场存在一个黄金定律:二八法则。 这…...
C++ 算法主题系列之集结0-1背包问题的所有求解方案
1. 前言 背包问题是类型问题,通过对这一类型问题的理解和掌握,从而可以归纳出求解此类问题的思路和模板。 背包问题的分类有: 0-1背包问题,也称为不可分割背包问题。无限背包问题。判定性背包问题.带附属关系的背包问题。双背包…...
【Vue】Vue常见的6种指令
Vue的6种指令-前言指令(Directives)是vue 为开发者提供的模板语法,用于辅助开发者渲染页面的基本结构。vue 中的指令按照不同的用途可以分为如下6 大类① 内容渲染指令 ② 属性绑定指令 ③ 事件绑定指令 ④ 双向绑定指令 ⑤ 条件渲染指令 ⑥ …...
计算机科学与技术(嵌入式)四年学习资料_文件目录树
说明: 资料内容主要包括:计嵌专业2019级大学四年主要科目的各种电子资料,有电子实验报告、课程设计报告、课程设计项目、整理复习笔记、电子书、ppt、练习题、期末试卷、部分课程软件资源、科创项目,职业生涯规划书,大…...
【java】Java 继承
文章目录继承的概念生活中的继承:类的继承格式为什么需要继承公共父类:继承类型继承的特性继承关键字extends关键字implements关键字super 与 this 关键字final 关键字构造器继承的概念 继承是java面向对象编程技术的一块基石,因为它允许创建…...
自媒体账号数据分析从何入手?
账号的数据可以直接反应这个账号的好坏,数据越高收益就会越好,数据越差收益自然高不了。 新手要从哪些方面入手见效更快呢?今天大周就来把自己的经验分享给粉丝们! 1、账号定位 (1)账号所创作的领域 &a…...
Clickhouse新版本JSON字段数据写入方式
Clickhouse新版本JSON字段数据写入方式 在Clickhouse版本22.3.1版本以上,提供了针对JSON格式数据的新的数据类型:JSON,从而实现了存储此类数据由原先的结构化表结构,更新为现在的半结构化表存储。对于新增字段,某些同…...
HNU-电路与电子学-实验2
实验二 模型机组合部件的实现(一) 班级 计XXXXX 姓名 wolf 学号 2021080XXXXX 一、实验目的 1.了解简易模型机的内部结构和工作原理。 2.熟悉译码器、运算器的工作原理。 3.分析模型机的功…...
从0开始学python -49
Python MySQL - mysql-connector 驱动 -2 插入数据 插入数据使用 “INSERT INTO” 语句: demo_mysql_test.py: 向 sites 表插入一条记录。 import mysql.connectormydb mysql.connector.connect(host"localhost",user"root",passwd"…...
Spring MVC 详解(连接、获取参数、返回数据)
在之前我们先简单那谈谈Spring、SpringBoot以及Spring MVC框架之间有什么关系?首先Spring是一个框架,SpringBoot脚手架是为了快速开发Spring框架而创造的技术。可以理解为SpringBoot又在Spring上面包了一层壳子,是基于Spring的,是…...
IT女神节(致敬中国IT界永远的女神严蔚敏-数据结构)
我们都知道程序数据结构算法。相信很多人都学过严蔚敏的数据结构的课程。作为一个码农,在这不管是3.7女神节,还是3.8妇女节。我觉得都有必要向这些教育界的老前辈致敬。今天我就梳理梳理,最经典的数据结构教材。 严蔚敏介绍(来自…...
Java 集合分页
一、前言 在Java开发中,若单次展示的数据量太大,会造成程序响应缓慢,就需要用到 分页 功能,每一页展示一定量的数据,分多次展示 ... 那么在List集合中,如何实现 分页 功能呢? 本文将以3种方式&a…...
代码随想录之哈希表(力扣题号)
242. 有效的字母异位词 直接用数组模拟哈希表 只有小写字母,开26的数组就可以了 class Solution {public boolean isAnagram(String s, String t) {//24-28int[] hash new int[26];Arrays.fill(hash,0);for(int i0;i<s.length();i){hash[s.charAt(i)-a];}for(i…...
如何在知行之桥EDI系统中定时自动更换交易伙伴AS2证书?
为了保证客户与交易伙伴之间数据传输的安全性,AS2传输协议中,通常会通过一对数字证书对传输数据进行签名和加密。但是证书是有有效期的,在证书到期之前,需要贸易双方及时更换新的证书。 在更新证书时,由于客户通常是和…...
号号网站开发/抖音热门搜索关键词
大数据有很多方向,目前我们口中经常说的大数据的主要就业方向是:大数据研发,大数据分析与挖掘,深度学习,人工智能等方向。 推荐一个大数据学习群 119599574晚上20:10都有一节【免费的】大数据直播课程,专注…...
创建网站用突唯阿做响应式网站/泉州搜索推广
原文地址:http://java-frog.iteye.com/blog/243703 正则表达式限制输入框只能输入数字 代码如下: <input type"text" onkeyup"this.valuethis.value.replace(/[^\d]/g,) " onafterpaste"this.valuethis.value.replace(/[^\d]/g,)…...
我想建网站/百度账号登录入口
(重发下我这篇原发于 2014-03-18 的网易博客,原博客被网易莫名禁掉了。。被迫手动搬家,忧伤)现在好像各种题目出树已经出烦了,开始出仙人掌了。什么时候咱们不出动态树了,搞个Link-Cut Cactus!最…...
wordpress 赞/市场推广方案ppt
显示笔记下拉菜单 ------------------------------------------------------------------------------------------------ 1.通过点击“箭头”按钮显示三个菜单项 2.获取DIV对象 调用slideDown(200);动画展示菜单200毫秒 3.点击其余下拉…...
要强化人大网站建设/北京高端网站建设
English Learning - L2 语音作业打卡 前元音 [i:] Day7 2023.2.27 周一💌 发音小贴士:💌 当日目标音发音规则/技巧:🍭 Part 1【热身练习】🍭 Part2【练习内容】🍭【练习感受】🍓元音…...
哪些大型网站用mysql/竞价排名是什么
项目中我打算使用一个MP4视频作为登录界面背景,首先在静态页面都没法显示出来,后来发现需要将视频的编码格式转换为H264的格式方能正常显示(使用格式工厂转换即可);后又发现视频没办法铺满全屏,在不同的分辨…...