手写的面试题,你来不来围观一波腾讯云开发者社区

☠️每日毒鸡汤:这个社会是存在不公平的,不要抱怨,因为没有用!人总是在反省中进步的!

今天给大家分享一下Java中的核心技术JVM。作为一个Java程序员,相比或多或少的都会接触到一些关于Java底层的知识,这些底层知识是非常重要的,相比之下这些知识也是比较难以理解的,小编今天用大白话的方式给大家整理了一些面试题,可以便于大家的理解,喜欢的家人们点赞支持呦.....

线程私有区

程序计数器

当同时进行的线程数超过CPU数或其内核数时,就要通过时间片轮询分派CPU的时间资源,不免发生线程切换。这时,每个线程就需要一个属于自己的计数器来记录下一条要运行的指令。如果执行的是JAVA方法,计数器记录正在执行的java字节码地址,如果执行的是native方法,则计数器为空。

虚拟机栈

与虚拟机栈作用相似。但它不是为Java方法服务的,而是本地方法(C语言)。由于规范对这块没有强制要求,不同虚拟机实现方法不同。

线程共享区

方法区

线程共享的,用于存放被虚拟机加载的类的元数据信息,如常量、静态变量和即时编译器编译后的代码。若要分代,算是永久代(老年代),以前类大多“static”的,很少被卸载或收集,现回收废弃常量和无用的类。其中运行时常量池存放编译生成的各种常量。(如果hotspot虚拟机确定一个类的定义信息不会被使用,也会将其回收。回收的基本条件至少有:所有该类的实例被回收,而且装载该类的ClassLoader被回收)。

存放对象实例和数组,是垃圾回收的主要区域,分为新生代和老年代。刚创建的对象在新生代的Eden区中,经过GC后进入新生代的S0区中,再经过GC进入新生代的S1区中,15次GC后仍存在就进入老年代。这是按照一种回收机制进行划分的,不是固定的。若堆的空间不够实例分配,则OutOfMemoryError。

栈是运行时单位,代表着逻辑,内含基本数据类型和堆中对象引用,所在区域连续,没有碎片;堆是存储单位,代表着数据,可被多个栈共享(包括成员中基本数据类型、引用和引用对象),所在区域不连续,会有碎片。

栈内存用来存储局部变量和方法调用,而堆内存用来存储Java中的对象。无论是成员变量,局部变量,还是类变量,它们指向的对象都存储在堆内存中。

栈内存是线程私有的。 堆内存是所有线程共有的。

栈的空间大小远远小于堆的。

老年代空间不足

Permanet Generation空间满

CMS GC时出现promotion failed和concurrent mode failure 对

于采用CMS进行旧生代GC的程序而言,尤其要注意GC日志中是否有promotion failed和concurrent mode failure两种状况,当这两种状况出现时可能会触发Full GC。 promotionfailed是在进行Minor GC时,survivor space放不下、对象只能放入旧生代,而此时旧生代也放不下造成的;concurrent mode failure是在执行CMS GC的过程中同时有对象要放入旧生代,而此时旧生代空间不足造成的。 应对措施为:增大survivorspace、旧生代空间或调低触发并发GC的比率,但在JDK 5.0+、6.0+的版本中有可能会由于JDK的bug29导致CMS在remark完毕后很久才触发sweeping动作。对于这种状况,可通过设置-XX:CMSMaxAbortablePrecleanTime=5(单位为ms)来避免。

统计得到的Minor GC晋升到旧生代的平均大小大于旧生代的剩余空间

Java虚拟机是一个可以执行Java字节码的虚拟机进程。Java源文件被编译成能被Java虚拟机执行的字节码文件。 Java被设计成允许应用程序可以运行在任意的平台,而不需要程序员为每一个平台单独重写或者是重新编译。Java虚拟机让这个变为可能,因为它知道底层硬件平台的指令长度和其他特性。

平台无关关键在于需要在每个平台安装对应的的JDK版本。

JVM类加载分为5个过程:加载,验证,准备,解析,初始化,使用,卸载

加载

验证

验证是连接阶段的第一步,主要确保加载进来的字节流符合JVM规范。 验证阶段会完成以下4个阶段的检验动作: 1)文件格式验证 2)元数据验证(是否符合Java语言规范) 3)字节码验证(确定程序语义合法,符合逻辑) 4)符号引用验证(确保下一步的解析能正常执行)

准备

主要为静态变量在方法区分配内存,并设置默认初始值。

解析

是虚拟机将常量池内的符号引用替换为直接引用的过程。

初始化

初始化阶段是类加载过程的最后一步,主要是根据程序中的赋值语句主动为类变量赋值。 注: 1)当有父类且父类为初始化的时候,先去初始化父类; 2)再进行子类初始化语句。

类加载器是一个用来加载类文件的类。Java 源代码通过 javac 编译器编译成类文件。然后 JVM 来执行类文件中的字节码来执行程序。类加载器负责加载文件系统、网络或其他来源的类文件。

实现通过类的权限定名获取该类的二进制字节流的代码块叫做类加载器。

主要有一下四种类加载器:

在介绍双亲委派模型之前先说下类加载器。对于任意一个类,都需要由加载它的类加载器和这个类本身一同确立在 JVM 中的唯一性,每一个类加载器,都有一个独立的类名称空间。类加载器就是根据指定全限定名称将 class 文件加载到 JVM 内存,然后再转化为 class 对象。

类加载器分类:

双亲委派机制

如果一个类加载器收到了类加载的请求,它首先不会自己去加载这个类,而是把这个请求委派给父类加载器去完成,每一层的类加载器都是如此,这样所有的加载请求都会被传送到顶层的启动类加载器中,只有当父加载无法完成加载请求(它的搜索范围中没找到所需的类)时,子加载器才会尝试去加载类。

当一个类收到了类加载请求时,不会自己先去加载这个类,先查询是否已经加载过,没有加载过就将其委派给父类,由父类去加载,如果此时父类不能加载,反馈给子类,由子类去完成类的加载。

如果不想打破双亲委派模型,就重写ClassLoader类中的fifindClass()方法即可,无法被父类加载器加载的类最终会通过这个方法被加载。而如果想打破双亲委派模型则需要重写loadClass()方法(当然其中的坑也不会少)。典型的打破双亲委派模型的框架和中间件有tomcat与osgi 。

用户根据需求自己定义的。需要继承自 ClassLoader ,重写方法 findClass() 。

如果想要编写自己的类加载器,只需要两步:

继承 ClassLoader 类

覆盖 findClass(String className) 方法

ClassLoader 超类的 loadClass 方法用于将类的加载操作委托给其父类加载器去进行,只有当该类尚未加载并且父类加载器也无法加载该类时,才调用 findClass 方法。 如果要实现该方法,必须做到以下几点:

2.调用 ClassLoader 超类的 defineClass方法,向虚拟机提供字节码。

最大的好处就是解决了碎片化。也就是说为什么一个Survivor区不行?第一部分中,我们知道了必须设置Survivor区。假设 现在只有一个Survivor区,我们来模拟一下流程:刚刚新建的对象在Eden中,一旦Eden满了,触发一次Minor GC,Eden中的存活对象就会被移动到Survivor区。这样继续循 环下去,下一次Eden满了的时候,问题来了,此时进行Minor GC,Eden和Survivor各有一些存活对象,如果此时把Eden区的 存活对象硬放到Survivor区,很明显这两部分对象所占有的内存是不连续的,也就导致了内存碎片化。永远有一个Survivor space是空的,另一个非空的Survivor space无碎片。

新生代中的可用内存:复制算法用来担保的内存为9:1,所以只会造成 10% 的空间浪费。 可用内存中 Eden:S1 区为8:1 即新生代中 Eden:S1:S2 = 8:1:1这个比例,是由参数 -XX:SurvivorRatio 进行配置的(默认为 8)。

(2)老年代空间不足

(3)方法去空间不足

(4)通过Minor GC后进入老年代的平均大小 > 老年代的可用内存

(5)由Eden区、From Space区向To Space区复制时,对象大小大于To Space可用内存,则把该对象转存到老年代,且老年代的可用内存小于该对象大小。即老年代无法存放下新年代过度到老年代的对象的时候,会触发Full GC。

这个方法就有点类似于某个人被拍了死刑,但是不一定会死。

即使在可达性分析算法中不可达的对象,也并非一定是“非死不可”的,这时候他们暂时处于“缓刑”阶段,真正宣告一个对象死亡至少要经历两个阶段:

Java对象由三个部分组成:对象头、实例数据、对齐填充。

对象头由两部分组成,第一部分存储对象自身的运行时数据:哈希码、GC分代年龄、锁标识状态、线程持有的锁、偏向线程ID(一般占32/64 bit)。第二部分是指针类型,指向对象的类元数据类型(即对象代表哪个类)。如果是数组对象,则对象头中还有一部分用来记录数组长度。实例数据用来存储对象真正的有效信息(包括父类继承下来的和自己定义的)

对齐填充:JVM要求对象起始地址必须是8字节的整数倍(8字节对齐)

垃圾回收不会发生在永久代,如果永久代满了或者是超过了临界值,会触发完全垃圾回收(FullGC)。如果你仔细查看垃圾收集器的输出信息,就会发现永久代也是被回收的。这就是为什么正确的永久代大小对避免Full GC是非常重要的原因。请参考下Java8:从永久代到元数据区 (注:Java8中已经移除了永久代,新加了一个叫做元数据区的native内存区)

GC最基础的算法有三种: 标记 -清除算法、复制算法、标记-压缩算法,我们常用的垃圾回收器一般都采用分代收集算法。

从上面这些出发点来看,我们平常的 Web 服务器,都是对响应性要求非常高的。选择性其实就集中在 CMS 、 G1 、 ZGC 上。而对于某些定时任务,使用并行收集器,是一个比较好的选择。

THE END
0.圆桌对谈|《悬崖之上》:谍战片的迷离与归路(悬崖之上)影评圆桌对谈|《悬崖之上》:谍战片的迷离与归路对谈嘉宾;张也奇 高翔 雷勇 焦欣波对谈时间:2021年4月30日原文链接:【西部影谈】圆桌对谈 | 《悬崖之上》:谍战片的迷离与归路嘉宾简介张也奇:辽宁沈阳人,南京大学戏剧与影视学博士,关注中国电影史、电影和戏剧的互动研究等领域。高翔:陕西宝鸡人,南开大学文艺学博士。关jvzquC41oq|jg7iqwdgo0lto1tkwkn|135<849661
1.大模型入门知识点(非常详细)零基础入门到精通,收藏这一篇就够了它们通常是神经网络中的权重(weights)和偏置(biases),但也可能包括其他类型的变量,如批归一化(Batch Normalization, BN)中的缩放因子(scale factors)和偏移量(offsets),以及某些特定层(如LSTM中的门控参数)的额外变量。 数学表示: 在数学上,这些参数通常表现为数值型矩阵或向量。例如,神经网络中的权重矩阵表示了不jvzquC41dnuh0lxfp0tfv8MWCPMYKW>:;:5bt}neng5eg}fknu526;>::5<9
2.下面哪一个叙述是不正确的A、抗生素是植物或微生物产生的次级代谢产物下面哪一个叙述是不正确的 A、抗生素是植物或微生物产生的次级代谢产物 B、抗生素在很低的浓度下能抑制或杀灭各种病原菌,达到治疗的目的 C、早期抗生素主要用于治疗细菌或霉菌感染性疾病,故称为抗菌素 D、磺胺类药物百浪多息,是最早上市的抗菌素。jvzquC41yy}/rypcq0ipo8|cpiqf1mfcp1h9hkf:6cg63=93g3?gc:i5ghi1f;:h3;
3.TowardsDataScience博客中文翻译2020(九百一十一)nehaagarwala与其他类型的工程不同,在其他类型的工程中,工程师的技能或工作成果直接产生最终用户购买的产品或服务,数据科学通常不直接创造价值。这就是领域知识至关重要的原因。数据科学家需要彻底了解业务,然后才能将人工智能模型应用于业务。 通常,我看到人工智能模型通过以下设置来创造利润: jvzquC41dnuh0lxfp0tfv8|k|cxehxwegn5bt}neng5eg}fknu526;<2;5;6
4.TowardsDataScience博客中文翻译2021(四百四十八)收集的图片被上传到云端,在那里计算机视觉模型对标记的桁架进行分类。 特定的计算机视觉问题是预测出现在桁架中的每种作物类型的实例的数量,该桁架主要出现在由移动电话拍摄的图像中。 在这个过程中,与固定相机相比,使用手持相机的优点是标记桁架的图像不会被番茄植株的叶子遮挡。 在该计算机视觉任务中分析的相关生长阶段(被视为类)是:芽、花、jvzquC41dnuh0lxfp0tfv8|k|cxehxwegn5bt}neng5eg}fknu526<586;;1
5.TowardsDataScience博客中文翻译2021(二百一十二)tealium业务理解之后,下一步就是数据理解。这包括收集所有可用的数据。在这里,您需要与业务团队密切合作,因为他们实际上知道存在什么数据,什么数据可以用于这个业务问题以及其他信息。这一步包括描述数据、它们的结构、它们的相关性、它们的数据类型。使用图形绘制来浏览数据,并提取通过浏览数据可以获得的任何信息。 jvzquC41dnuh0lxfp0tfv8|k|cxehxwegn5bt}neng5eg}fknu526;>29472
6.分析:大学生初体验,处女出血的真相,解读心理与生理反应因此,对于醉驾,应强调的不是造成了何种后果才追究责任,而是要将这种行为制止在危害发生前,即只要血液酒精含量达到一定程度,就判定若放任这一行为极有可能对他人造成伤害,并进行法律制裁,从而形成一条不能碰的高压线。 “然而,各地标准不一,在司法实践当中开始不断松绑,实际上根据醉驾的危害后果来量刑,出现了司法乱象jvzq<84vkokt0vil{zguqv{{0usi7hp1s{fu}nqp1843;d94873;7mvo
7.人物关注:狂躁情绪的深层探讨,女人如何应对挑战,寻找内心的平静与c❌o🔞s类型无码㊙️番号 1❌6人🔞人碰免㊙️费视频公开 兄妹❌无码全🔞彩本子百度㊙️云 ❌快🔞妖精品㊙️ 步步高h9❌和s🔞1的选㊙️哪个 湿身的新婚少妇 ❌国产精品在线4🔞00部㊙️ 无码h里番❌有🔞什么意㊙️思 快乐人❌体🔞国模㊙️ jvzq<84hggj/omo{z{ltjz~{0qxh0ls1fqjpe87;28?:0qyo
8.TowardsDataScience博客中文翻译2020(四百六十一)是的,这个项目的动力源于我对榴莲的热爱。你一定想知道,我们到底在分类什么? 你看,榴莲有很多种,它们的味道、质地和颜色都不一样。对于这个项目,我们将对四种不同类型的榴莲进行分类,即: 猫山王 金凤(金凤凰) D24 红对虾 这些榴莲的差异可以总结在下表中: jvzquC41dnuh0lxfp0tfv8|k|cxehxwegn5bt}neng5eg}fknu526;=574>9
9.种设计模式与七大设计原则整理明白了!!!设计类型与设计原则变量的声明类型尽量是抽象类和接口,这样我们的变量引用个实际对象间,就曾在一个缓冲层,利于程序的扩展和优化。(就比如你和对象吵架,你先找丈母娘来劝说对象,而不是与对象直接沟通) 继承时遵循里氏替换原则。 2.4 里氏替换原则 使用继承的时候,父类会对子类进行约束。并且如果父类中的方法发生改变的时候,可能会对所jvzquC41dnuh0lxfp0tfv8hjgpmccxgcq7811jwvkerf1mjvckrt1:7282>26<