当前位置: 首页 > 编程日记 > 正文

java类为什么要建两个class_ClassLoader的几个概念、类和对象的解释

首先,转载一篇文章,个人认为是看到过了讲得最清楚的 XD

当JVM(Java虚拟机)启动时,会形成由三个类加载器组成的初始类加载器层次结构:

bootstrap classloader

|

extension classloader

|

system classloader

bootstrap classloader -引导(也称为原始)类加载器,它负责加载Java的核心类。在Sun的JVM中,在执行java的命令中使用-Xbootclasspath选项或使用 -D选项指定sun.boot.class.path系统属性值可以指定附加的类。这个加载器的是非常特殊的,它实际上不是 java.lang.ClassLoader的子类,而是由JVM自身实现的。大家可以通过执行以下代码来获得bootstrap classloader加载了那些核心类库:

URL[] urls=sun.misc.Launcher.getBootstrapClassPath().getURLs();for(inti=0; i

System.out.println(urls.toExternalForm());

}在我的计算机上的结果为:

file:/C:/j2sdk1.4.1_01/jre/lib/endorsed/dom.jar

file:/C:/j2sdk1.4.1_01/jre/lib/endorsed/sax.jar

file:/C:/j2sdk1.4.1_01/jre/lib/endorsed/xalan-2.3.1.jar

file:/C:/j2sdk1.4.1_01/jre/lib/endorsed/xercesImpl-2.0.0.jar

file:/C:/j2sdk1.4.1_01/jre/lib/endorsed/xml-apis.jar

file:/C:/j2sdk1.4.1_01/jre/lib/endorsed/xsltc.jar

file:/C:/j2sdk1.4.1_01/jre/lib/rt.jar

file:/C:/j2sdk1.4.1_01/jre/lib/i18n.jar

file:/C:/j2sdk1.4.1_01/jre/lib/sunrsasign.jar

file:/C:/j2sdk1.4.1_01/jre/lib/jsse.jar

file:/C:/j2sdk1.4.1_01/jre/lib/jce.jar

file:/C:/j2sdk1.4.1_01/jre/lib/charsets.jar

file:/C:/j2sdk1.4.1_01/jre/classes

这时大家知道了为什么我们不需要在系统属性CLASSPATH中指定这些类库了吧,因为JVM在启动的时候就自动加载它们了。

extension classloader -扩展类加载器,它负责加载JRE的扩展目录(JAVA_HOME/jre/lib/ext或者由java.ext.dirs系统属性指定的)中JAR的类包。这为引入除Java核心类以外的新功能提供了一个标准机制。因为默认的扩展目录对所有从同一个JRE中启动的JVM都是通用的,所以放入这个目录的 JAR类包对所有的JVM和system classloader都是可见的。在这个实例上调用方法getParent()总是返回空值null,因为引导加载器bootstrap classloader不是一个真正的ClassLoader实例。所以当大家执行以下代码时:

System.out.println(System.getProperty("java.ext.dirs"));

ClassLoader extensionClassloader=ClassLoader.getSystemClassLoader().getParent();

System.out.println("the parent of extension classloader :"+extensionClassloader.getParent());

结果为:

C:"j2sdk1.4.1_01"jre"lib"ext

the parent of extension classloader : null

extension classloader是system classloader的parent,而bootstrap classloader是extension classloader的parent,但它不是一个实际的classloader,所以为null。

system classloader -系统(也称为应用)类加载器,它负责在JVM被启动时,加载来自在命令java中的-classpath或者java.class.path系统属性或者 CLASSPATH操作系统属性所指定的JAR类包和类路径。总能通过静态方法ClassLoader.getSystemClassLoader()找到该类加载器。如果没有特别指定,则用户自定义的任何类加载器都将该类加载器作为它的父加载器。执行以下代码即可获得:

System.out.println(System.getProperty("java.class.path"));

输出结果则为用户在系统属性里面设置的CLASSPATH。

classloader 加载类用的是全盘负责委托机制。所谓全盘负责,即是当一个classloader加载一个Class的时候,这个Class所依赖的和引用的所有 Class也由这个classloader负责载入,除非是显式的使用另外一个classloader载入;委托机制则是先让parent(父)类加载器 (而不是super,它与parent classloader类不是继承关系)寻找,只有在parent找不到的时候才从自己的类路径中去寻找。此外类加载还采用了cache机制,也就是如果 cache中保存了这个Class就直接返回它,如果没有才从文件中读取和转换成Class,并存入cache,这就是为什么我们修改了Class但是必须重新启动JVM才能生效的原因。

每个ClassLoader加载Class的过程是:

1.检测此Class是否载入过(即在cache中是否有此Class),如果有到8,如果没有到2

2.如果parent classloader不存在(没有parent,那parent一定是bootstrap classloader了),到4

3.请求parent classloader载入,如果成功到8,不成功到5

4.请求jvm从bootstrap classloader中载入,如果成功到8

5.寻找Class文件(从与此classloader相关的类路径中寻找)。如果找不到则到7.

6.从文件中载入Class,到8.

7.抛出ClassNotFoundException.

8.返回Class.

其中5.6步我们可以通过覆盖ClassLoader的findClass方法来实现自己的载入策略。甚至覆盖loadClass方法来实现自己的载入过程。

类加载器的顺序是:

先是bootstrap classloader,然后是extension classloader,最后才是system classloader。大家会发现加载的Class越是重要的越在靠前面。这样做的原因是出于安全性的考虑,试想如果system classloader“亲自”加载了一个具有破坏性的“java.lang.System”类的后果吧。这种委托机制保证了用户即使具有一个这样的类,也把它加入到了类路径中,但是它永远不会被载入,因为这个类总是由bootstrap classloader来加载的。大家可以执行一下以下的代码:

System.out.println(System.class.getClassLoader());

将会看到结果是null,这就表明java.lang.System是由bootstrap classloader加载的,因为bootstrap classloader不是一个真正的ClassLoader实例,而是由JVM实现的,正如前面已经说过的。

下面就让我们来看看JVM是如何来为我们来建立类加载器的结构的:

sun.misc.Launcher,顾名思义,当你执行java命令的时候,JVM会先使用bootstrap classloader载入并初始化一个Launcher,执行下来代码:

System.out.println("the Launcher's classloader is "+sun.misc.Launcher.getLauncher().getClass().getClassLoader());

结果为:

the Launcher's classloader is null (因为是用bootstrap classloader加载,所以class loader为null)

Launcher 会根据系统和命令设定初始化好class loader结构,JVM就用它来获得extension classloader和system classloader,并载入所有的需要载入的Class,最后执行java命令指定的带有静态的main方法的Class。extension classloader实际上是sun.misc.Launcher$ExtClassLoader类的一个实例,system classloader实际上是sun.misc.Launcher$AppClassLoader类的一个实例。并且都是 java.net.URLClassLoader的子类。

让我们来看看Launcher初试化的过程的部分代码。

Launcher的部分代码:

1 publicclassLauncher  {2 publicLauncher() {3 ExtClassLoader extclassloader;4 try{5 //初始化extension classloader6 extclassloader=ExtClassLoader.getExtClassLoader();7 }catch(IOException ioexception) {8 thrownewInternalError("Could not create extension class loader");9 }10 try{11 //初始化system classloader,parent是extension classloader12 loader=AppClassLoader.getAppClassLoader(extclassloader);13 }catch(IOException ioexception1) {14 thrownewInternalError("Could not create application class loader");15 }16 //将system classloader设置成当前线程的context classloader(将在后面加以介绍)17 Thread.currentThread().setContextClassLoader(loader);18 9b8a8a44dd1c74ae49c20a7cd451974e.png

9b8a8a44dd1c74ae49c20a7cd451974e.png19 }20 publicClassLoader getClassLoader() {21 //返回system classloader22 returnloader;23 }24 }25

extension classloader的部分代码:

1 staticclassLauncher$ExtClassLoaderextendsURLClassLoader {2 3 publicstaticLauncher$ExtClassLoader getExtClassLoader()4 throwsIOException5 {6 File afile[]=getExtDirs();7 return(Launcher$ExtClassLoader)AccessController.doPrivileged(newLauncher$1(afile));8 }9 privatestaticFile[] getExtDirs() {10 //获得系统属性“java.ext.dirs”11 String s=System.getProperty("java.ext.dirs");12 File afile[];13 if(s!=null) {14 StringTokenizer stringtokenizer=newStringTokenizer(s, File.pathSeparator);15 inti=stringtokenizer.countTokens();16 afile=newFile;17 for(intj=0; j

1 staticclassLauncher$AppClassLoaderextendsURLClassLoader2 {3 4 publicstaticClassLoader getAppClassLoader(ClassLoader classloader)5 throwsIOException6 {7 //获得系统属性“java.class.path”8 String s=System.getProperty("java.class.path");9 File afile[]=s!=null?Launcher.access$200(s) :newFile[0];10 return(Launcher$AppClassLoader)AccessController.doPrivileged(newLauncher$2(s, afile, classloader));11 }12 }看了源代码大家就清楚了吧,extension classloader是使用系统属性“java.ext.dirs”设置类搜索路径的,并且没有parent。system classloader是使用系统属性“java.class.path”设置类搜索路径的,并且有一个parent classloader。Launcher初始化extension classloader,system classloader,并将system classloader设置成为context classloader,但是仅仅返回system classloader给JVM。

这里怎么又出来一个context classloader呢?它有什么用呢?我们在建立一个线程Thread的时候,可以为这个线程通过setContextClassLoader方法来指定一个合适的classloader作为这个线程的context classloader,当此线程运行的时候,我们可以通过getContextClassLoader方法来获得此context classloader,就可以用它来载入我们所需要的Class。默认的是system classloader。利用这个特性,我们可以“打破”classloader委托机制了,父classloader可以获得当前线程的context classloader,而这个context classloader可以是它的子classloader或者其他的classloader,那么父classloader就可以从其获得所需的 Class,这就打破了只能向父classloader请求的限制了。这个机制可以满足当我们的classpath是在运行时才确定,并由定制的 classloader加载的时候,由system classloader(即在jvm classpath中)加载的class可以通过context classloader获得定制的classloader并加载入特定的class(通常是抽象类和接口,定制的classloader中是其实现),例如web应用中的servlet就是用这种机制加载的.

好了,现在我们了解了classloader的结构和工作原理,那么我们如何实现在运行时的动态载入和更新呢?只要我们能够动态改变类搜索路径和清除classloader的cache中已经载入的Class就行了,有两个方案,一是我们继承一个classloader,覆盖loadclass方法,动态的寻找Class文件并使用defineClass方法来;另一个则非常简单实用,只要重新使用一个新的类搜索路径来new一个classloader就行了,这样即更新了类搜索路径以便来载入新的Class,也重新生成了一个空白的cache(当然,类搜索路径不一定必须更改)。噢,太好了,我们几乎不用做什么工作,java.netURLClassLoader正是一个符合我们要求的classloader!我们可以直接使用或者继承它就可以了!

这是j2se1.4 API的doc中URLClassLoader的两个构造器的描述:

URLClassLoader(URL[] urls)

Constructs a new URLClassLoader for the specified URLs using the default delegation parent ClassLoader.

URLClassLoader(URL[] urls, ClassLoader parent)

Constructs a new URLClassLoader for the given URLs.

其中URL[] urls就是我们要设置的类搜索路径,parent就是这个classloader的parent classloader,默认的是system classloader。

好,现在我们能够动态的载入Class了,这样我们就可以利用newInstance方法来获得一个Object。但我们如何将此Object造型呢?可以将此Object造型成它本身的Class吗?

首先让我们来分析一下java源文件的编译,运行吧!javac命令是调用“JAVA_HOME/lib/tools.jar”中的“com.sun.tools.javac.Main”的compile方法来编译:

publicstaticintcompile(String as[]);publicstaticintcompile(String as[], PrintWriter printwriter);

返回0表示编译成功,字符串数组as则是我们用javac命令编译时的参数,以空格划分。例如:

javac -classpath c:"foo"bar.jar;. -d c:" c:"Some.java

则字符串数组as为{"-classpath","c:""foo""bar.jar;.","-d","c:""","c:""Some.java"},如果带有PrintWriter参数,则会把编译信息出到这个指定的printWriter中。默认的输出是System.err。

其中 Main是由JVM使用Launcher初始化的system classloader载入的,根据全盘负责原则,编译器在解析这个java源文件时所发现的它所依赖和引用的所有Class也将由system classloader载入,如果system classloader不能载入某个Class时,编译器将抛出一个“cannot resolve symbol”错误。

所以首先编译就通不过,也就是编译器无法编译一个引用了不在CLASSPATH中的未知Class的java源文件,而由于拼写错误或者没有把所需类库放到CLASSPATH中,大家一定经常看到这个“cannot resolve symbol”这个编译错误吧!

其次,就是我们把这个Class放到编译路径中,成功的进行了编译,然后在运行的时候不把它放入到CLASSPATH中而利用我们自己的 classloader来动态载入这个Class,这时候也会出现“java.lang.NoClassDefFoundError”的违例,为什么呢?

我们再来分析一下,首先调用这个造型语句的可执行的Class一定是由JVM使用Launcher初始化的system classloader载入的,根据全盘负责原则,当我们进行造型的时候,JVM也会使用system classloader来尝试载入这个Class来对实例进行造型,自然在system classloader寻找不到这个Class时就会抛出“java.lang.NoClassDefFoundError”的违例。

OK,现在让我们来总结一下,java文件的编译和Class的载入执行,都是使用Launcher初始化的system classloader作为类载入器的,我们无法动态的改变system classloader,更无法让JVM使用我们自己的classloader来替换system classloader,根据全盘负责原则,就限制了编译和运行时,我们无法直接显式的使用一个system classloader寻找不到的Class,即我们只能使用Java核心类库,扩展类库和CLASSPATH中的类库中的Class。

还不死心!再尝试一下这种情况,我们把这个Class也放入到CLASSPATH中,让system classloader能够识别和载入。然后我们通过自己的classloader来从指定的class文件中载入这个Class(不能够委托 parent载入,因为这样会被system classloader从CLASSPATH中将其载入),然后实例化一个Object,并造型成这个Class,这样JVM也识别这个Class(因为 system classloader能够定位和载入这个Class从CLASSPATH中),载入的也不是CLASSPATH中的这个Class,而是从 CLASSPATH外动态载入的,这样总行了吧!十分不幸的是,这时会出现“java.lang.ClassCastException”违例。

为什么呢?我们也来分析一下,不错,我们虽然从CLASSPATH外使用我们自己的classloader动态载入了这个Class,但将它的实例造型的时候是JVM会使用system classloader来再次载入这个Class,并尝试将使用我们的自己的classloader载入的Class的一个实例造型为system classloader载入的这个Class(另外的一个)。大家发现什么问题了吗?也就是我们尝试将从一个classloader载入的Class的一个实例造型为另外一个classloader载入的Class,虽然这两个Class的名字一样,甚至是从同一个class文件中载入。但不幸的是JVM 却认为这个两个Class是不同的,即JVM认为不同的classloader载入的相同的名字的Class(即使是从同一个class文件中载入的)是不同的!这样做的原因我想大概也是主要出于安全性考虑,这样就保证所有的核心Java类都是system classloader载入的,我们无法用自己的classloader载入的相同名字的Class的实例来替换它们的实例。

看到这里,聪明的读者一定想到了该如何动态载入我们的Class,实例化,造型并调用了吧!

那就是利用面向对象的基本特性之一的多形性。我们把我们动态载入的Class的实例造型成它的一个system classloader所能识别的父类就行了!这是为什么呢?我们还是要再来分析一次。当我们用我们自己的classloader来动态载入这我们只要把这个Class的时候,发现它有一个父类Class,在载入它之前JVM先会载入这个父类Class,这个父类Class是system classloader所能识别的,根据委托机制,它将由system classloader载入,然后我们的classloader再载入这个Class,创建一个实例,造型为这个父类Class,注意了,造型成这个父类 Class的时候(也就是上溯)是面向对象的java语言所允许的并且JVM也支持的,JVM就使用system classloader再次载入这个父类Class,然后将此实例造型为这个父类Class。大家可以从这个过程发现这个父类Class都是由 system classloader载入的,也就是同一个class loader载入的同一个Class,所以造型的时候不会出现任何异常。而根据多形性,调用这个父类的方法时,真正执行的是这个Class(非父类 Class)的覆盖了父类方法的方法。这些方法中也可以引用system classloader不能识别的Class,因为根据全盘负责原则,只要载入这个Class的classloader即我们自己定义的 classloader能够定位和载入这些Class就行了。

这样我们就可以事先定义好一组接口或者基类并放入CLASSPATH中,然后在执行的时候动态的载入实现或者继承了这些接口或基类的子类。还不明白吗?让我们来想一想Servlet吧,web application server能够载入任何继承了Servlet的Class并正确的执行它们,不管它实际的Class是什么,就是都把它们实例化成为一个Servlet Class,然后执行Servlet的init,doPost,doGet和destroy等方法的,而不管这个Servlet是从web- inf/lib和web-inf/classes下由system classloader的子classloader(即定制的classloader)动态载入。说了这么多希望大家都明白了。在applet,ejb等容器中,都是采用了这种机制.

对于以上各种情况,希望大家实际编写一些example来实验一下。

最后我再说点别的,classloader虽然称为类加载器,但并不意味着只能用来加载Class,我们还可以利用它也获得图片,音频文件等资源的URL,当然,这些资源必须在CLASSPATH中的jar类库中或目录下。我们来看API的doc中关于ClassLoader的两个寻找资源和Class的方法描述吧:

public URL getResource(String name)

用指定的名字来查找资源,一个资源是一些能够被class代码访问的在某种程度上依赖于代码位置的数据(图片,音频,文本等等)。

一个资源的名字是以'/'号分隔确定资源的路径名的。

这个方法将先请求parent classloader搜索资源,如果没有parent,则会在内置在虚拟机中的classloader(即bootstrap classloader)的路径中搜索。如果失败,这个方法将调用findResource(String)来寻找资源。

public static URL getSystemResource(String name)

从用来载入类的搜索路径中查找一个指定名字的资源。这个方法使用system class loader来定位资源。即相当于ClassLoader.getSystemClassLoader().getResource(name)。

例如:

System.out.println(ClassLoader.getSystemResource("java/lang/String.class"));

的结果为:

jar:file:/C:/j2sdk1.4.1_01/jre/lib/rt.jar!/java/lang/String.class

表明String.class文件在rt.jar的java/lang目录中。

因此我们可以将图片等资源随同Class一同打包到jar类库中(当然,也可单独打包这些资源)并添加它们到class loader的搜索路径中,我们就可以无需关心这些资源的具体位置,让class loader来帮我们寻找了!

以上是转自bea论坛的一篇文章,作者不清楚,估计是bea内部的大牛。是值得俺们顶礼膜拜的神一般的存在 XD

最后 附上自己的几点理解

bootstrap classloader  -------  对应jvm中某c++写的dll类

Extenson ClassLoader ---------对应内部类ExtClassLoader

System ClassLoader  ---------对应内部类AppClassLoader

Custom ClassLoader  ----------对应任何URLClassLoader的子类(你也可以继承SecureClassLoader或者更加nb一点 直接继承ClassLoader,这样的话你也是神一般的存在了 XD)

以上四种classloder按照从上到下的顺序,依次为下一个的parent

这个第一概念

第二个概念是几个有关的classloader的类

抽象类 ClassLoader

|

SecureClassLoader

|

URLClassloader

|           |

sun的ExtClassLoader   sun的AppClassLoader

以上的类之间是继承关系,与第一个概念说的parent是两回事情,需要小心。

第三个概念是Thread的ContextClassLoader

其实从Context的名称就可以看出来,这只是一个用以存储任何classloader引用的临时存储空间,与classloader的层次没有任何关系。

第四 就是如何实现自己的classloader了,本来是要翻译另外一篇文章Find a way out of the ClassLoader maze

不过今天时间都花在《小夫妻天天恶战》这篇神文上了 XD 强烈推荐任何和俺一样期望彪悍人生的朋友都去看看

翻译明天补上,浪费时间是可耻的 XD

匿鸟,晚上还有朋友推荐的 《lie with me》(与我同眠)要看。XD

相关文章:

第四章 python的turtle库的运用

我们可以尝试用python的自带turtle库绘制一条蟒蛇 首先我们设计一下蟒蛇的基本形状 我们先把这段蟒蛇绘制的实例代码贴出来,各位可以在自己的本地运行一下看看效果,然后我们再继续分析代码: 1 #PythonDraw.py2 import turtle3 turtle.setup(6…

oracle导入索引b报错,impdp导入索引很慢

impdp用NETWORK_LINK从远程库导入到本地库,导入表的速度还正常,导入索引的速度特别慢。2个小时才导1300个索引。使用imp的格式:impdp vebackup/abc DIRECTORYDATABAK_DIR NETWORK_LINKprimarydb_link SCHEMASveasms TABLE_EXISTS_ACTIONREPLA…

新的mysql如何使用_如何使用新的MySQL更新日志

使用新的MySQL更新日志的方法未必人人都会,下面就教您如何使用新的MySQL更新日志的方法,希望对您能够有所帮助。如果你只使用一使用新的MySQL更新日志的方法未必人人都会,下面就教您如何使用新的MySQL更新日志的方法,希望对您能够…

find_in_set

在查询表中数据用 ‘,’隔开的记录时 如图所示 用like 查询auth 字段中含A5是查不出来的 如图所示 用find_in_set 可以查询出 auth字段含 ‘A5’的记录 如图所示 用法介绍: find_in_set 可以查询出字段内容以英文逗号隔开的记录 find_in_set(匹配值,字段名)转载于:h…

一堆棋子java代码编程_网易2018校招内推编程题-堆棋子-C++实现

0 1 3 10解法暴力枚举所有可能的点。如图所示,黑点为输入点。所需遍历的点为红线的交点,红圈表示。当时自己写的是遍历了外围红线所构成的封闭矩形里面所有的点了,只有60%的AC率,原因超时。看了康学长的代码,才知道有些…

linux free命令详解和使用实例(查看内存使用率)

free命令可以显示Linux系统中空闲的、已用的物理内存及swap内存,及被内核使用的buffer。在Linux系统监控的工具中,free命令是最经常使用的命令之一1.命令格式: free [参数] 2.命令功能: free 命令显示系统使用和空闲的…

awk linux 获取端口号_Linux提权后获取敏感信息命令

如果不能执行的可能是不同类型的linux。系统版本?cat /etc/issuecat /etc/*-releasecat /etc/lsb-releasecat /etc/redhat-release内核版本?cat /proc/versionuname -auname -mrsrpm -q kerneldmesg | grep Linuxls /boot | grep vmlinuz环境变量?cat /…

lemp-------3多站点访问,,访问控制,,虚拟目录

基于ip vi /etc/nginx/nginx.conf server { listen 192.168.1.142:80; server_name localhost; access_log logs/host.access.log main; location / { root /web2; index index.html index.htm index.php; } error_page 500 502 503 504 /50x.html; location /50x.html { root…

oracle统计id出现次数,oracle 统计sql

oracle 统计月平均交易次数 :select n_tsc_src_usr_id , floor(count(c_tsc_no)/trunc(months_between(max(d_tsc_req_time),min(d_tsc_req_time))))from tbl_tsc_basegroup by n_tsc_src_usr_idhaving months_between(max(d_tsc_req_time),min(d_tsc_req_time)) &g…

java避免使用orderby_java – Spring安全配置@Order不是唯一的例外

我试图在我的Spring Security配置中注册多个过滤器,但是我总是得到相同的异常:04-Nov-2015 14:35:23.792 WARNING [RMI TCP Connection(3)-127.0.0.1]org.springframework.web.context.support.AnnotationConfigWebApplicationContext.refreshException encountered…

es 启动问题

max file descriptors [4096] for elasticsearch process is too low, increase to at least [65536] vim /etc/security/limits.conf 文件末尾添加: mst hard nofile 65536 mst soft nofile 65536 mst是es启动用户 max virtual memory areas vm.max_map_count [65…

imrot matlab,Matlabtuxiangpipei

文件名大小更新时间Matlab图像匹配的都可以用的到做三维重建\matlabcode\examples-code\11.jpg.......................................\..........\.............\addons\rectifData.mat.......................................\..........\.............\......\shelves.jp…

mysql 5.7 full_MySQL5.7默认打开ONLY_FULL_GROUP_BY 解决方案

MySQL5.7后将sql_mode的ONLY_FULL_GROUP_BY模式默认设置为打开状态,这样一来,很多之前的sql语句可能会出现错误,错误信息如下:Error Code: 1055. Expression #3 of SELECT list is not in GROUP BY clause and contains nonaggreg…

通过web sql实现增删查改

<!DOCTYPE html><html><head lang"en"> <meta charset"UTF-8"> <title></title></head><body><h3>***添加学生***</h3>学号&#xff1a;<input type"text" id"id&qu…

java发送苹果消息慢_Spring-boot JMS 发送消息慢的解决方法

Spring-boot JMS 发送消息慢的问题解决Servicepublic class Producer {Autowiredprivate JmsMessagingTemplate jmsTemplate;public void sendMessage(Destination destination, final String message){jmsTemplate.convertAndSend(destination, message);}}经使用JMeter进行压…

快速幂 + 矩阵快速幂

快速幂 1 #include<iostream>2 #include<algorithm>3 #include<cstring>4 #define LL long long5 using namespace std;6 7 LL Pow(LL a, LL b)8 {9 LL ans 1; 10 while(b ! 0){ 11 if(b&1) 12 ans * a; 13 a …

【Ctsc2011】幸福路径

题目链接&#xff1a;http://www.lydsy.com/JudgeOnline/problem.php?id2306 给定一张有向图&#xff0c;每个点有权值&#xff0c;蚂蚁从某个节点出发&#xff0c;初始体力值为$1$&#xff0c;每走一条边$体力值*p$&#xff0c;每经过一个点会获得幸福值为$点权*体力值$&…

mysql 去重con_python 爬虫 实现增量去重和定时爬取实例

前言&#xff1a; 在爬虫过程中&#xff0c;我们可能需要重复的爬取同一个网站&#xff0c;为了避免重复的数据存入我们的数据库中 通过实现增量去重 去解决这一问题 本文还针对了那些需要实时更新的网站 增加了一个定时爬取的功能&#xff1b;本文作者同开源中国(殊途同归_)&a…

oracle数据导出方法,oracle多种导入导出数据方法

dmp格式:1.dmp格式的导出可以通过客户端工具(PL/SQL)操作来完成,通过菜单栏---->Tools---->Export Tables&#xff0c;然后设置勾选相应参数即可,rows代表是否连同数据一起导出2.导出还可以用cmd工具,速度也更快:exp [email protected] filed:\***.dmp fullyfully表示全导…

java 枚举转byte_如何在java中将一个枚举转换为另一个枚举?

一种方法是在您的详细枚举中定义一个方法asSimple()&#xff1a;public enum Detailed {PASSED {OverrideSimple asSimple() {return PASSED;}},INPROCESS {OverrideSimple asSimple() {return RUNNING;}},ERROR1,ERROR2,ERROR3;public Simple asSimple() {return Simple.ERROR…

BZOJ4566: [Haoi2016]找相同字符

BZOJ4566: [Haoi2016]找相同字符 Description 给定两个字符串&#xff0c;求出在两个字符串中各取出一个子串使得这两个子串相同的方案数。两个方案不同当且仅当这两个子串中有一个位置不同。Input 两行&#xff0c;两个字符串s1&#xff0c;s2&#xff0c;长度分别为n1&#x…

mysql索引空间太大_MySQL优化索引

1. MySQL如何使用索引索引用于快速查找具有特定列值的行。如果没有索引&#xff0c;MySQL必须从第一行开始&#xff0c;然后遍历整个表以找到相关的行。表越大&#xff0c;花费越多。如果表中有相关列的索引&#xff0c;MySQL可以快速确定要在数据文件中间查找的位置&#xff…

Mac-sublime text 3破解版

在史蒂芬周下载破解版安装package controlimport urllib.request,os,hashlib; h df21e130d211cfc94d9b0905775a7c0f 1e3d39e33b79698005270310898eea76; pf Package Control.sublime-package; ipp sublime.installed_packages_path(); urllib.request.install_opener( urll…

oracle library cache lock,【案例】Oracle等待事件library cache lock产生原因和解决办法...

【案例】Oracle等待事件library cache lock产生原因和解决办法时间:2016-12-07 18:56 来源:Oracle研究中心 作者:网络 点击:次天萃荷净Oracle研究中心案例分析&#xff1a;运维DBA发现Oracle数据库出现library cache lock等待事件导致cpu使用非常高&#xff0c;结合案例来…

python uiautomation选择list内容_使用python UIAutomation从QQ2017(v8.9)群界面获取所有群成员详细资料,...

首先安装pip install uiautomation, 再运行本文代码。或者下载https://github.com/yinkaisheng/Python-UIAutomation-for-Windows代码(包含了uiautomation module)&#xff0c;直接运行demos目录里的脚本get_qq_group_members.pyuiautomation.py是我写的一个python封装微软UIAu…

【BZOJ】2734: [HNOI2012]集合选数

题目链接&#xff1a;http://www.lydsy.com/JudgeOnline/problem.php?id2734 考虑$N4$的情况&#xff1a; \begin{bmatrix} 1&3 &X \\ 2&X &X \\ 4&X &X \end{bmatrix} 其实就是吧最小值丢在了矩阵中${(0,0)}$的位置上&#xff0c;对于矩阵中的任意…

Linux命令:tar命令批量解压方法总结

tar命令批量解压方法总结 (2010-05-24 17:48:46) 转载▼标签&#xff1a; tar 批量解压 杂谈 分类&#xff1a; linux学习 由于linux的tar命令不支持批量解压&#xff0c;所以很多网友编写了好多支持批量解压的shell命令&#xff0c;收集了一下&#xff0c;供大家分享&#xff…

php column not found,java.sql.SQLException: Column 'cloumn name' not found.

Hi,My system configuration:Mandrake 9.0 Tomcat 4.1.24 MySQL 4.0.12. Apache[問題]我有一隻Servlet app. 如果 Tomcat MySQL APache IBM JDK 1.3 or SUN JDK 1.4.1_02在一開機時就起動. 我在http://localhost:8080/servlet/myApp 是可以看到Servlet run 起來. 可是如…

批量新建文件夹并命名_dos命令实现批量新建文件夹

1、批量新建文件夹&#xff08;使用命令&#xff1a;MD&#xff09;实现案例&#xff1a;假如我们要新建10个文件夹&#xff0c;这10个文件夹的名称分别是数字1-10来命名。以下详细步骤&#xff1a;1&#xff09;在excel表里面把需要批量新建的文件夹名字放到一列&#xff08;假…

java去掉mongodb日志_如何禁用mongoDB java驱动程序日志记录?

我试图禁用mongo-java-driver-3.0.0的日志输出.我试图在我的应用程序开始之前设置它们,然后加载mongo驱动程序,但它没有帮助.// Enable MongoDB logging in generalSystem.setProperty("DEBUG.MONGO", "false");// Enable DB operation tracingSystem.setP…