jvm常见面试题
0x01. 内存模型以及分区,需要详细到每个区放什么。
- 栈区:
栈分为java虚拟机栈和本地方法栈
重点是Java虚拟机栈,它是线程私有的,生命周期与线程相同。
每个方法执行都会创建一个栈帧,用于存放局部变量表,操作栈,动态链接,方法出口等。每个方法从被调用,直到被执行完。对应着一个栈帧在虚拟机中从入栈到出栈的过程。
通常说的栈就是指局部变量表部分,存放编译期间可知的8种基本数据类型,及对象引用和指令地址。局部变量表是在编译期间完成分配,当进入一个方法时,这个栈中的局部变量分配内存大小是确定的。
会有两种异常StackOverFlowError和 OutOfMemoneyError。当线程请求栈深度大于虚拟机所允许的深度就会抛出StackOverFlowError错误;虚拟机栈动态扩展,当扩展无法申请到足够的内存空间时候,抛出OutOfMemoneyError。
本地方法栈为虚拟机使用到本地方法服务(native)
- 堆区:
堆被所有线程共享区域,在虚拟机启动时创建,唯一目的存放对象实例。
堆区是gc的主要区域,通常情况下分为两个区块年轻代和年老代。更细一点年轻代又分为Eden区最要放新创建对象,From survivor 和 To survivor 保存gc后幸存下的对象,默认情况下各自占比 8:1:1。
不过很多文章介绍分为3个区块,把方法区算着为永久代。这大概是基于Hotspot虚拟机划分,然后比如IBM j9就不存在永久代概论。不管怎么分区,都是存放对象实例。
会有异常OutOfMemoneyError
- 方法区:
被所有线程共享区域,用于存放已被虚拟机加载的类信息,常量,静态变量等数据。被Java虚拟机描述为堆的一个逻辑部分。习惯是也叫它永久代(permanment generation)
垃圾回收很少光顾这个区域,不过也是需要回收的,主要针对常量池回收,类型卸载。
常量池用于存放编译期生成的各种字节码和符号引用,常量池具有一定的动态性,里面可以存放编译期生成的常量;运行期间的常量也可以添加进入常量池中,比如string的intern()方法。
- 程序计数器:
当前线程所执行的行号指示器。通过改变计数器的值来确定下一条指令,比如循环,分支,跳转,异常处理,线程恢复等都是依赖计数器来完成。
Java虚拟机多线程是通过线程轮流切换并分配处理器执行时间的方式实现的。为了线程切换能恢复到正确的位置,每条线程都需要一个独立的程序计数器,所以它是线程私有的。
唯一一块Java虚拟机没有规定任何OutofMemoryError的区块。
0x02. 堆里面的分区:Eden,survivalfrom to,老年代,各自的特点
1.JVM中堆空间可以分成三个大区,新生代、老年代、永久代。
2.新生代可以划分为三个区,Eden区,两个幸存区。
在JVM运行时,可以通过配置以下参数改变整个JVM堆的配置比例
- JVM运行时堆的大小
-Xms堆的最小值
-Xmx堆空间的最大值
复制
- 新生代堆空间大小调整
-XX:NewSize新生代的最小值-XX:MaxNewSize新生代的最大值-XX:NewRatio设置新生代与老年代在堆空间的大小-XX:SurvivorRatio新生代中Eden所占区域的大小
复制
- 永久代大小调整
-XX:MaxPermSize
复制
- 其他
-XX:MaxTenuringThreshold,设置将新生代对象转到老年代时需要经过多少次垃圾回收,但是仍然没有被回收
复制
复制(Copying)算法
将内存平均分成A、B两块,算法过程:
- 新生对象被分配到A块中未使用的内存当中。当A块的内存用完了, 把A块的存活对象对象复制到B块。
- 清理A块所有对象。
- 新生对象被分配的B块中未使用的内存当中。当B块的内存用完了, 把B块的存活对象对象复制到A块。
- 清理B块所有对象。
- goto 1。
优点:简单高效。
缺点:内存代价高,有效内存为占用内存的一半。
对复制算法进一步优化:使用Eden/S0/S1三个分区
平均分成A/B块太浪费内存,采用Eden/S0/S1三个区更合理,空间比例为Eden:S0:S1==8:1:1,有效内存(即可分配新生对象的内存)是总内存的9/10。
算法过程:
- Eden+S0可分配新生对象;
- 对Eden+S0进行垃圾收集,存活对象复制到S1。清理Eden+S0。一次新生代GC结束。
- Eden+S1可分配新生对象;
- 对Eden+S1进行垃圾收集,存活对象复制到S0。清理Eden+S1。二次新生代GC结束。
- goto 1。
默认Eden:S0:S1=8:1:1,因此,新生代中可以使用的内存空间大小占用新生代的9/10,那么有人就会问,为什么不直接分成两个区,一个区占9/10,另一个区占1/10,
这样做的原因大概有以下几种
1.S0与S1的区间明显较小,有效新生代空间为Eden+S0/S1,因此有效空间就大,增加了内存使用率
2.有利于对象代的计算,当一个对象在S0/S1中达到设置的XX:MaxTenuringThreshold值后,会将其分到老年代中,设想一下,如果没有S0/S1,直接分成两个区,该如何计算对象经过了多少次GC还没被释放,你可能会说,在对象里加一个计数器记录经过的GC次数,或者存在一张映射表记录对象和GC次数的关系,是的,可以,但是这样的话,会扫描整个新生代中的对象, 有了S0/S1我们就可以只扫描S0/S1区了~~~
0x03. 对象创建方法,对象的内存分配,对象的访问定位。
创建:
1. 类加载检查
JVM遇到一条new指令时,首先检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已被加载、解析和初始化过。
如果没有,那必须先执行相应的类的加载过程。
2. 对象分配内存
对象所需内存的大小在类加载完成后便完全确定(对象内存布局),为对象分配空间的任务等同于把一块确定大小的内存从Java堆中划分出来。
根据Java堆中是否规整有两种内存的分配方式:(Java堆是否规整由所采用的垃圾收集器是否带有压缩整理功能决定)。
指针碰撞(Bump the pointer)
Java堆中的内存是规整的,所有用过的内存都放在一边,空闲的内存放在另一边,中间放着一个指针作为分界点的指示器,分配内存也就是把指针向空闲空间那边移动一段与内存大小相等的距离。例如:Serial、ParNew等收集器。
空闲列表(Free List)
Java堆中的内存不是规整的,已使用的内存和空闲的内存相互交错,就没有办法简单的进行指针碰撞了。虚拟机必须维护一张列表,记录哪些内存块是可用的,在分配的时候从列表中找到一块足够大的空间划分给对象实例,并更新列表上的记录。例如:CMS这种基于Mark-Sweep算法的收集器。
3. 并发处理
对象创建在虚拟机中时非常频繁的行为,即使是仅仅修改一个指针指向的位置,在并发情况下也并不是线程安全的,可能出现正在给对象A分配内存,指针还没来得及修改,对象B又同时使用了原来的指针来分配内存的情况。
同步
虚拟机采用CAS配上失败重试的方式保证更新操作的原子性
本地线程分配缓冲(Thread Local Allocation Buffer, TLAB)
把内存分配的动作按照线程划分为在不同的空间之中进行,即每个线程在Java堆中预先分配一小块内存(TLAB)。哪个线程要分配内存,就在哪个线程的TLAB上分配。只有TLAB用完并分配新的TLAB时,才需要同步锁定。
4. 内存空间初始化
虚拟机将分配到的内存空间都初始化为零值(不包括对象头),如果使用了TLAB,这一工作过程也可以提前至TLAB分配时进行。
内存空间初始化保证了对象的实例字段在Java代码中可以不赋初始值就直接使用,程序能访问到这些字段的数据类型所对应的零值。
注意:类的成员变量可以不显示地初始化(Java虚拟机都会先自动给它初始化为默认值)。方法中的局部变量如果只负责接收一个表达式的值,可以不初始化,但是参与运算和直接输出等其它情况的局部变量需要初始化。
5. 对象设置
虚拟机对对象进行必要的设置,例如这个对象是哪个类的实例、如何才能找到类的元数据信息、对象的哈希码、对象的GC分代年龄等信息。这些信息存放在对象的对象头之中。
6. 执行init()
在上面的工作都完成之后,从虚拟机的角度看,一个新的对象已经产生了。但是从Java程序的角度看,对象的创建才刚刚开始init()方法还没有执行,所有的字段都还是零。
所以,一般来说(由字节码中是否跟随invokespecial指令所决定),执行new指令之后会接着执行init()方法,把对象按照程序员的意愿进行初始化,这样一个真正可用的对象才算产生出来。
访问定位:句柄或者直接指针。
0x04. GC的两种判定方法:引用计数与引用链。
1.在JDK1.2之前,使用的是引用计数器算法,即当这个类被加载到内存之后,就会产生方法区,堆栈、程序计数
器等一系列信息,当创建对象的时候,为这个对象在堆栈空间中分配对象,同时会产生一个引用计数器,同时引
用计数器+1,当有新的引用时,引用计数器继续+1,而当其中一个引用销毁时,引用计数器-1,当引用计数器减
为0的时候,标志着这个对象已经没有引用了,可以回收了!但是这样会有一个问题:
当我们的代码出现这样的情况时:
a)ObjA.obj=ObjB
b)ObjB.obj=ObjA
这样的代码会产生如下引用情形objA指向objB,而ObjB又指向objA,这样当其他所有的引用都消失了之后,objA
和objB还有一个相互的引用,也就是说两个对象的引用计数器各为1,而实际上这两个对象都已经没有额外的引用,已经是垃圾了。
2.根搜索算法:
根搜索算法是从离散数学中的图论引入的,程序把所有的引用关系看做一张图,从一个节点GC Root开始,寻找对
应的引用节点,找到这个节点之后,继续寻找这个节点的引用节点,当所有的引用节点寻找完毕之后,剩余的节
点则被认为是没有被饮用到的节点,即无用的节点。
目前Java中可作为GC Root的对象有:
1.虚拟机栈中引用的对象(本地变量表)
2.方法区中静态属性引用的对象
3.方法区中常量引用的对象
4.本地方法栈中引用的对象(Native对象)。
java中存在的四种引用
(1)强引用:
只要引用存在,垃圾回收器永远不会回收。
(2)软引用
非必须引用,内存溢出之前进行回收,可以通过以下代码实现
Object obj=new Object();
SoftReference<Object> sf=newSoftRerence<Object>(obj);
obj=null;
sf.get();//有时会返回null
这时候sf是对obj的一个软引用,通过sf.get()方法可以取到这个对象,当然这个对象被标记为需要回收的对象时,
则返回null;
软引用主要用于用户实现类似缓存的功能,在内存不足的情况下直接通过软引用取值,无需从繁忙的真实来源查
询数据,提升速度;当内存不足时,自动删除这部分缓存数据,从真实的来源查询这些数据。
(3)弱引用
第二次垃圾回收时回收,可以通过如下代码实现
Object obj=new Object();
WeakReference<Object> wf=newWeakReference<Object>(obj);
obj=null;
wf.get();//有时会返回null
wf.isEnQueued();//返回是否被垃圾回收器标记为即将回收的垃圾
弱引用是在第二次垃圾回收时回收,短时间内通过弱引用取对应的数据,可以取到,当执行过第二次垃圾回收时,
将返回null。弱引用主要用于监控对象是否已经被标记为即将回收的垃圾,可以通过弱引用的isEnQueues方法
返回对象是否被垃圾回收器标记。
(4)虚引用
垃圾回收时回收,无法通过引用取到对象值,可以通过如下代码实现
Object obj=new Object();
PhantomReference<Object> pf=newPhantomReference<Object>(obj);
obj=null;
pf.get();//永远是返回null
pf.isEnQueued();//返回从内从中已经删除。
虚引用是每次垃圾回收的时候都会被回收,通过虚引用的get方法永远获取到的数据为null。
0x05. GC的三种收集方法:标记清除、标记整理、复制算法的原理与特点,分别用在什么地方,如果让你优化收集方法,有什么思路?
垃圾回收算法
标记-清除算法(Mark-Sweep)
从根节点开始标记所有可达对象,其余没有标记的即为垃圾对象,执行清除。但回收后的空间是不连续的。
标记-清除算法采用从根集合进行扫描,对存活的对象标记,标记完毕后,在扫描整个空间中未被标记的对象,进
行回收。
标记-清除算法不需要进行对象的移动,并且仅对不存活的对象进行处理,在存活对象比较多的情况下极为高效,
但由于标记-清除算法直接回收不存活的对象,因此会造成内存碎片。
复制算法
复制算法采用从根集合扫描,并将存活对象复制到一块新的,没有使用过的空间中,这种算法当控件存活的对象
比较少时,极为高效,但是带来的成本是需要一块内存交换空间进行对象的移动。也就是s0,s1等空间。
标记-整理法
标记-整理算法采用标记-清除算法一样的方式进行对象的标记,但在清除时,在回收不存活的对象占用的空间后,
会将所有的存活对象网左端空闲空间移动,并更新相应的指针。标记-整理算法是在标记-清除算法的基础上,
又进行了对象的移动,因此成本更高,但是却解决了内存碎片的问题。
0x06. GC收集器有哪些?CMS收集器与G1收集器的特点。
串行垃圾回收器(Serial Garbage Collector)
并行垃圾回收器(Parallel Garbage Collector)
并发标记扫描垃圾回收器(CMS Garbage Collector)
G1垃圾回收器(G1 GarbageCollector)
并发标记垃圾回收使用多线程扫描堆内存,标记需要清理的实例并且清理被标记过的实例。并发标记垃圾回收器只会在下面两种情况持有应用程序所有线程。
当标记的引用对象在tenured区域;
在进行垃圾回收的时候,堆内存的数据被并发的改变。
相比并行垃圾回收器,并发标记扫描垃圾回收器使用更多的CPU来确保程序的吞吐量。如果我们可以为了更好的程序性能分配更多的CPU,那么并发标记上扫描垃圾回收器是更好的选择相比并发垃圾回收器。
通过JVM参数 XX:+USeParNewGC 打开并发标记扫描垃圾回收器。
G1垃圾回收器适用于堆内存很大的情况,他将堆内存分割成不同的区域,并且并发的对其进行垃圾回收。G1也可以在回收内存之后对剩余的堆内存空间进行压缩。并发扫描标记垃圾回收器在STW情况下压缩内存。G1垃圾回收会优先选择第一块垃圾最多的区域
通过JVM参数–XX:+UseG1GC 使用G1垃圾回收器
0x07. Minor GC与Full GC分别在什么时候发生?
从年轻代空间(包括 Eden 和 Survivor 区域)回收内存被称为 Minor GC。
这一定义既清晰又易于理解。但是,当发生Minor GC事件的时候,有一些有趣的地方需要注意到:
当 JVM 无法为一个新的对象分配空间时会触发 Minor GC,比如当 Eden 区满了。所以分配率越高,越频繁执行 Minor GC。
内存池被填满的时候,其中的内容全部会被复制,指针会从0开始跟踪空闲内存。Eden 和 Survivor 区进行了标记和复制操作,取代了经典的标记、扫描、压缩、清理操作。所以 Eden 和 Survivor 区不存在内存碎片。写指针总是停留在所使用内存池的顶部。
执行 Minor GC 操作时,不会影响到永久代。从永久代到年轻代的引用被当成 GC roots,从年轻代到永久代的引用在标记阶段被直接忽略掉。
质疑常规的认知,所有的 Minor GC 都会触发“全世界的暂停(stop-the-world)”,停止应用程序的线程。对于大部分应用程序,停顿导致的延迟都是可以忽略不计的。
其中的真相就是,大部分 Eden 区中的对象都能被认为是垃圾,永远也不会被复制到 Survivor 区或者老年代空间。
如果正好相反,Eden 区大部分新生对象不符合 GC 条件,Minor GC 执行时暂停的时间将会长很多。
所以 Minor GC 的情况就相当清楚了——每次 Minor GC 会清理年轻代的内存。
大家应该注意到,目前,这些术语无论是在 JVM 规范还是在垃圾收集研究论文中都没有正式的定义。但是我们一看就知道这些在我们已经知道的基础之上做出的定义是正确的,
Minor GC 清理年轻带内存应该被设计得简单:
Major GC 是清理永久代。
Full GC 是清理整个堆空间—包括年轻代和永久代。
很不幸,实际上它还有点复杂且令人困惑。首先,许多 Major GC 是由 Minor GC 触发的,所以很多情况下将这两种 GC 分离是不太可能的。另一方面,许多现代垃圾收集机制会清理部分永久代空间,所以使用“cleaning”一词只是部分正确。
这使得我们不用去关心到底是叫 Major GC 还是 Full GC,大家应该关注当前的 GC 是否停止了所有应用程序的线程,还是能够并发的处理而不用停掉应用程序的线程。
0x08. 几种常用的内存调试工具:jmap、jstack、jconsole
0x09. 类加载的五个过程:加载、验证、准备、解析、初始化
加载:
在加载阶段,虚拟机主要完成三件事:
1.通过一个类的全限定名来获取定义此类的二进制字节流。
2.将这个字节流所代表的静态存储结构转化为方法区域的运行时数据结构。
3.在Java堆中生成一个代表这个类的java.lang.Class对象,作为方法区域数据的访问入口。
验证:
验证阶段作用是保证Class文件的字节流包含的信息符合JVM规范,不会给JVM造成危害。如果验证失败,就会抛出一个java.lang.VerifyError异常或其子类异常。验证过程分为四个阶段:
1.文件格式验证:验证字节流文件是否符合Class文件格式的规范,并且能被当前虚拟机正确的处理。
2.元数据验证:是对字节码描述的信息进行语义分析,以保证其描述的信息符合Java语言的规范。
3.字节码验证:主要是进行数据流和控制流的分析,保证被校验类的方法在运行时不会危害虚拟机。
4.符号引用验证:符号引用验证发生在虚拟机将符号引用转化为直接引用的时候,这个转化动作将在解析阶段中发生。
准备:
准备阶段为变量分配内存并设置类变量的初始化。在这个阶段分配的仅为类的变量(static修饰的变量),而不包括类的实例变量。对已非final的变量,JVM会将其设置成“零值”,而不是其赋值语句的值:
pirvate static int size = 12;
那么在这个阶段,size的值为0,而不是12。final修饰的类变量将会赋值成真实的值。
解析:
解析过程是将常量池内的符号引用替换成直接引用。主要包括四种类型引用的解析。类或接口的解析、字段解析、方法解析、接口方法解析。
初始化:
在准备阶段,类变量已经经过一次初始化了,在这个阶段,则是根据程序员通过程序制定的计划去初始化类的变量和其他资源。这些资源有static{}块,构造函数,父类的初始化等。
至于使用和卸载阶段阶段,这里不再过多说明,使用过程就是根据程序定义的行为执行,卸载由GC完成。
0x10. 双亲委派模型:Bootstrap ClassLoader、ExtensionClassLoader、ApplicationClassLoader。
类加载器按照层次,从顶层到底层,分为以下三种:
(1)启动类加载器(BootstrapClassLoader)
这个类加载器负责将存放在JAVA_HOME/lib下的,或者被-Xbootclasspath参数所指定的路径中的,并且是虚拟机识别的类库加载到虚拟机内存中。启动类加载器无法被Java程序直接引用。
(2)扩展类加载器(ExtensionClassLoader)
这个加载器负责加载JAVA_HOME/lib/ext目录中的,或者被java.ext.dirs系统变量所指定的路径中的所有类库,开发者可以直接使用扩展类加载器
(3)应用程序类加载器(ApplicationClassLoader)
这个加载器是ClassLoader中getSystemClassLoader()方法的返回值,所以一般也称它为系统类加载器。它负责加载用户类路径(Classpath)上所指定的类库,可直接使用这个加载器,如果应用程序没有自定义自己的类加载器,一般情况下这个就是程序中默认的类加载
类加载的双亲委派模型
双亲委派模型要求除了顶层的启动类加载器外,其他的类加载器都应当有自己的父类加载器。这里类加载器之间的父子关系一般不会以继承关系来实现,而是都使用组合关系来复用父加载器的代码
工作过程:
如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去完成,每一个层次的类加载器都是如此,因此所有的加载请求最终都应该传递到顶层的启动类加载器中,
只有当父类加载器反馈自己无法完成这个请求(它的搜索范围中没有找到所需的类)时,子加载器才会尝试自己去加载。
好处:
Java类随着它的类加载器一起具备了一种带有优先级的层次关系。例如类Object,它放在rt.jar中,无论哪一个类加载器要加载这个类,最终都是委派给启动类加载器进行加载,因此Object类在程序的各种类加载器环境中都是同一个类。
判断两个类是否相同是通过classloader.class这种方式进行的,所以哪怕是同一个class文件如果被两个classloader加载,那么他们也是不同的类。
实现自己的加载器
只需要继承ClassLoader,并覆盖findClass方法。
在调用loadClass方法时,会先根据委派模型在父加载器中加载,如果加载失败,则会调用自己的findClass方法来完成加载。
0x11. 分派:静态分派与动态分派
静态分派
所有依赖静态类型来定位方法执行版本的分派动作称为静态分派,其典型应用是方法重载(根据参数的静态类型来定位目标方法)。
静态分派发生在编译阶段,因此确定静态分派的动作实际上不是由虚拟机执行的。
动态分派
在运行期根据实际类型确定方法执行版本。
相关文章:
jvm常见面试题
0x01. 内存模型以及分区,需要详细到每个区放什么。 栈区: 栈分为java虚拟机栈和本地方法栈 重点是Java虚拟机栈,它是线程私有的,生命周期与线程相同。 每个方法执行都会创建一个栈帧,用于存放局部变量表࿰…...
TF-A 项目的长期支持介绍
引流关键词:Armv8-A, Armv9-A, Cortex-A, Cortex-A12, Cortex-A15, Cortex-A17, Cortex-A32, Cortex-A34, Cortex-A35, Cortex-A5, Cortex-A510, Cortex-A53, Cortex-A55, Cortex-A57, Cortex-A65, Cortex-A65AE, Cortex-A7, Cortex-A710, Cortex-A715, Cortex-A72, Cortex-A7…...
企业电子招标采购系统源码java 版本 Spring Cloud + Spring Boot
项目说明 随着公司的快速发展,企业人员和经营规模不断壮大,公司对内部招采管理的提升提出了更高的要求。在企业里建立一个公平、公开、公正的采购环境,最大限度控制采购成本至关重要。符合国家电子招投标法律法规及相关规范,以及…...
7.Mysql 事务底层
一、事务的基础知识 mysql中的事务 分为 显式事务 和 隐式事务。 1.1 显式事务 显式事务就是我们手动开启事务,并且提交事务比如: -- 开启事务 begin; -- 执行查询语句 select *from where id = 1 for update ; -- 提交事务 commit;1.2 隐式事务 在 MySQL 中,隐式事务是…...
15.DIY可视化-拖拽设计1天搞定主流小程序-分类联动文章列表实时刷新
分类联动文章列表实时刷新 本教程均在第一节中项目启动下操作 分类联动文章列表实时刷新前言需求一:功能实现:点击首页分类,对应分类内容显示到当前页一、清空原分类界面:二. 设置选项卡三:设定展示内容字段:1.跨页面复制:文章分类组件到分类![在这里插入图片描述](https://img…...
【SpringCloud】二、服务注册发现Eureka与负载均衡Ribbon
文章目录 一、Eureka1、服务提供者与消费者2、Eureka原理分析3、搭建Eureka4、服务注册5、模拟多服务实例启动6、服务的发现 二、Ribbon1、负载均衡的原理2、源码分析3、负载均衡策略4、饥饿加载 一、Eureka 1、服务提供者与消费者 服务提供者:一次业务中…...
图形学实验(完整文件见上传)
CRect rect; this->GetClientRect(rect); pDC->Ellipse(rect); // DDALineView.cpp : implementation of the CDDALineView class // #include “stdafx.h” #include “DDALine.h” #include “DDALineDoc.h” #include “DDALineView.h” #ifdef _DEBUG #define new…...
Spark大数据处理学习笔记(3.2.1)掌握RDD算子
该文章主要为完成实训任务,详细实现过程及结果见【http://t.csdn.cn/FArNP】 文章目录 一、准备工作1.1 准备文件1. 准备本地系统文件2. 把文件上传到 1.2 启动Spark Shell1. 启动HDFS服务2. 启动Spark服务3. 启动Spark Shell 二、掌握转换算子2.1 映射算子 - map()…...
lammps初级:石墨烯、金属材料、纳米流体、热传导、多成分体系、金属、半导体材料的辐照、自建分子力场、MOFS、H2/CO2混合气体等模拟
1 LAMMPS的基础入门——初识LAMMPS是什么?能干什么?怎么用? 1.1 LAMMPS在win10和ubuntu系统的安装及使用 1.2 in文件结构格式 1.3 in文件基本语法:结合实例,讲解in文件常用命令 1.4 data文件格式 1.5 LAMMPS常见错误解…...
【MarkerDown】CSDN Markdown之时序图sequenceDiagram详解
CSDN Markdown之时序图sequenceDiagram详解 序列图 sequenceDiagram参与者与组参与者 participant拟人符号 actor别名 as组 box 消息(连线)激活/失活 activate/deactivate备注 Note循环 loop备选 Alt并行 par临界区 critical中断 break背景高亮 rect注释 %%转义字符的实体代码序…...
ReentrantLock实现原理-公平锁
在ReentrantLock实现原理(1)一节中,我们了解了ReentrantLock非公平锁的获取流程,在本节中我们来看下ReentrantLock公平锁的创建以及锁管理流程 创建ReentrantLock公平锁 创建公平锁代码如下: ReentrantLock reentrantLock new ReentrantL…...
掌握Scala数据结构(2)MAP、TUPLE、SET
一、映射 (Map) (一)不可变映射 1、创建不可变映射 创建不可变映射mp,用键->值的形式 创建不可变映射mp,用(键, 值)的形式 注意:Map是特质(Scala里的trait,相当于Java里的interface&#…...
flutter:文件系统目录、文件读写
参考 参考:老孟 文件存储和网络请求 数据存储 Dart的 IO 库包含了文件读写的相关类,它属于 Dart 语法标准的一部分,所以通过 Dart IO 库,无论是 Dart VM 下的脚本还是 Flutter,都是通过 Dart IO 库来操作文件的。但…...
计算机提示“找不到vcruntime140.dll,无法继续执行代码可”以这样子修复
首先,对于那些不熟悉的人来说,vcruntime140.dll是一个关键文件,用于在Windows操作系统上运行使用C语言编写的大型应用程序。如果你正在运行或安装这样的应用程序,但找不到vcruntime140.dll文件,那么你的应用程序可能无…...
深度学习pytorch实战五:基于ResNet34迁移学习的方法图像分类篇自建花数据集图像分类(5类)超详细代码
1.数据集简介 2.模型相关知识 3.split_data.py——训练集与测试集划分 4.model.py——定义ResNet34网络模型 5.train.py——加载数据集并训练,训练集计算损失值loss,测试集计算accuracy,保存训练好的网络参数 6.predict.py——利用训练好的网…...
Rust in Action笔记 第五章 深入理解数据
如果希望看到f32类型的数转换成整型数字u32类型,需要在unsafe包裹下调用std::mem::transmute(data),因为在安全的Rust语法中没有把整型数据按照bit转换成浮点数据的实现,如果想要看到浮点数的二进制输出(通过{:b})&…...
Cocos creator实现飞机大战空中大战《战击长空》小游戏资源及代码
Cocos creator实现飞机大战空中大战《战击长空》小游戏资源及代码 最近在学习Cocos Creator,作为新手,刚刚开始学习Cocos Creator,刚刚入门,这里记录一下飞机大战小游戏实现。 https://wxaurl.cn/VEgRy2eTMyi 一 安装CocosDashBo…...
2.4 逻辑代数的基本定理
学习目标: 如果我要学习逻辑代数的基本定理,我会采取以下步骤: 1. 学习基本概念:首先,我会花时间了解逻辑代数的基本概念,如逻辑运算符(合取、析取、否定等)、真值表、逻辑等价性等…...
适用于 Linux 的 Windows 子系统wsl文档
参考链接:https://learn.microsoft.com/zh-cn/windows/wsl/ 鸟哥的Linux私房菜:http://cn.linux.vbird.org/ http://cn.linux.vbird.org/linux_basic/linux_basic.php http://cn.linux.vbird.org/linux_server/ 目录 安装列出可用的 Linux 发行版列出已…...
C++特殊类的设计与类型转换
特殊类的设计与类型转换 特殊类的设计请设计一个类,只能在堆上创建对象请设计一个类,只能在栈上创建对象请设计一个类,只能创建一个对象(单例模式) C的类型转换 特殊类的设计 请设计一个类,只能在堆上创建对象 通过new创建的类就…...
如何通过关键词搜索API接口
如果你是一位电商运营者或者是想要进行1688平台产品调研的人员,你可能需要借助API接口来获取你所需要的信息。在这篇文章中,我们将会讨论如何通过关键词搜索API接口获取1688的商品详情。 第一步:获取API接口的授权信息 在使用API接口前&…...
智驾域控新战争打响,谁在抢跑?
智能驾驶域控制器赛道,已经成为了时下最为火热的市场焦点之一。 最近,头部Tier1均胜电子公布了全球首批基于高通Snapdragon Ride第二代芯片平台的智能驾驶域控制器产品nDriveH,在这一赛道中显得格外引人注意。 就在不久之前,均胜…...
Android 13无源码应用去掉无资源ID的按钮
Android Wifionly项目,客户要求去掉谷歌联系人里的 手机联系人按钮 需求分析 无应用源码,只能通过系统侧去修改 首先通过 Android Studio 工具 uiautomatorviewer 获取父控件资源ID chip_group ,然后通过遍历获取子控件去掉目标按钮 --- a/frameworks/base/core/java/andr…...
【SCI征稿】中科院2区(TOP),正刊,SCIEEI双检,进化计算、模糊集和人工神经网络在数据不平衡中应用
【期刊简介】IF:8.0-9.0,JCR1区,中科院2区(TOP) 【检索情况】SCIE&EI 双检,正刊 【数据库收录年份】2004年 【国人占比】22.78%(期刊国际化程度高) 【征稿领域】进化计算、模…...
Android Audio开发——AAudio基础(十五)
AAudio 是一个自 Android O 引入的新的 Android C API。它主要是为需要低延迟的高性能音频应用设计的。应用程序通过直接从流中读取或向流中写入数据来与 AAudio 通信,但它只包含基本的音频输入输出能力。 一、AAudio概述 AAudio 在应用程序和 Android 设备上的音频输入输出之…...
SDK接口远程调试【内网穿透】
文章目录 1.测试环境2.本地配置3. 内网穿透3.1 下载安装cpolar内网穿透3.2 创建隧道 4. 测试公网访问5. 配置固定二级子域名5.1 保留一个二级子域名5.2 配置二级子域名 6. 使用固定二级子域名进行访问 转发自cpolar内网穿透的文章:Java支付宝沙箱环境支付࿰…...
Mybatis学习笔记二
目录 一、MyBatis的各种查询功能1.1 查询一个实体类对象1.2 查询一个List集合1.3 查询单个数据1.4 查询一条数据为map集合1.5 查询多条数据为map集合1.5.1 方法一:1.5.2 方法二: 二、特殊SQL的执行2.1 模糊查询2.2 批量删除2.3 动态设置表名2.4 添加功能…...
大屏数据可视化开源项目
一、DataGear —— 数据可视化项目 官网:DataGear - 开源免费的数据可视化分析平台 DataGear 是一款开源免费的数据可视化分析平台,数据可视化看板。 功能特性: 1、多种数据源,支持运行时接入任意提供 JDBC 驱动的数据库&#…...
面试经典150题:数组/字符串合集
新专栏,预计两个月写完吧,每天下班回来抽空做几道题。会把做题计划顺序记录下来,如果你有缘,刷到这个开篇序列,那就跟着文章去练题吧。初学者可以慢慢来 88. 合并两个有序数组 void merge(vector<int>& nums…...
Java源文件的执行过程
目录 1.JVM 2.字节码 3.Java源文件执行的过程 4.JIT(Just In Time Compilation) 5.AOT(Ahead Of Time Compilation) 6.AOT破坏Java动态性 7.编译型语言与解释型语言 8.Java-编译与解释并存的语言 9.Java和C的相同点与不同…...
三只松鼠网站建设/临沂seo
JVM PPT的演进文稿分享 此PPT长达46页,不方便在页面中全部展示,文中只展示了文稿的前十二页。 获取完整版请在公众号内回复“JVM”。...
网站提交做外链有什么作用/seo运营是什么意思
1,安装sublime编辑器,下载地址:http://www.sublimetext.com/3 2,要使用sublime的插件机制必须安装package control:https://packagecontrol.io/installation 如果上面package control网址打不开,直接复制下…...
wordpress结构化标签/拉新推广赚钱的app
目录 1. asyncio 简介 1.1 协程与 asyncio协程编写的三个组成部分:1. 事件循环, 2. 回调(驱动生成器), 3. epoll(IO 多路复用) asyncio 是 python 用于解决异步 IO 编程的一整套解决方案。基于 asyncio 的框架有: torn…...
拖拽式建站源码/网络营销最主要的工具是
面向对象设计的过程就是抽象的过程,一般分为三步: (1)发现类,类定义了 对象将会用用的特征(属性)和行为(方法)。 (2)发现类的属性,对象…...
武汉搭建网站/品牌策划运营公司
文章目录开篇问题简介各种锁简介源码分析成员属性构造方法添加元素初始化桶数组判断是否需要扩容协助扩容(迁移元素)迁移元素删除元素获取元素获取元素个数总结开篇问题 (1)ConcurrentHashMap与HashMap的数据结构是否一样&#x…...
wordpress 重写url插件/seo渠道
监听域对象的生命周期:在Web应用程序的运行期间,Web容器会创建和销毁三个比较重要的对象ServletContext、HttpSession和ServletRequest,这些对象被称为域对象,为了监听这些域对象的生命周期,Servlet API中专门提供三个…...