Java面试题超详细整理《JVM篇》,nginx优化面试,2024年最新字节跳动java面试难吗

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip1024b (备注Java)
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

正文


类加载器的分类


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

JVM支持两种类型的类加载器 ,分别为引导类加载器(Bootstrap ClassLoader)和自定义类加载器(User-Defined ClassLoader)。

从概念上来讲,自定义类加载器一般指的是程序中由开发人员自定义的一类类加载器,但是Java虚拟机规范却没有这么定义,而是将所有派生于抽象类ClassLoader的类加载器都划分为自定义类加载器,所以ExtClassLoader 和 AppClassLoader 都属于自定义加载器。

四者之间是包含关系,不是上层和下层,也不是子父类的继承关系:

在这里插入图片描述

  • 启动类加载器(Bootstrap ClassLoader):用来加载java核心类库,无法被java程序直接引用。
  • 扩展类加载器(extensions class loader):它用来加载 Java 的扩展库。Java 虚拟机的实现会提供一个扩展库目录。该类加载器在此目录里面查找并加载 Java 类。
  • 系统类加载器(system class loader):它根据 Java 应用的类路径(CLASSPATH)来加载Java 类。一般来说,Java 应用的类都是由它来完成加载的。可以通过ClassLoader.getSystemClassLoader()来获取它。
  • 用户自定义类加载器,通过继承 java.lang.ClassLoader类的方式实现。

什么是双亲委派模型?


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

在这里插入图片描述

总结就是: 当一个类收到了类加载请求时,不会自己先去加载这个类,而是将其委派给父类,由父类去加载,如果此时父类不能加载,反馈给子类,由子类去完成类的加载。

作用:

  • 双亲机制避免了类的重复加载
  • 保护程序安全,防止核心API被随意篡改

说一下 JVM 运行时数据区


Java 虚拟机在执行 Java 程序的过程中会把它所管理的内存区域划分为若干个不同的数据区域。这些区域都有各自的用途,以及创建和销毁的时间,有些区域随着虚拟机进程的启动而存在,有些区域则是依赖线程的启动和结束而建立和销毁。Java 虚拟机所管理的内存被划分为如下几个区域:

在这里插入图片描述

线程私有的:程序计数器、虚拟机栈、本地方法栈

线程共享的:堆、方法区

  • 程序计数器(Program Counter Register):当前线程所执行的字节码的行号指示器,字节码解析器的工作是通过改变这个计数器的值,来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能,都需要依赖这个计数器来完成;
  • Java 虚拟机栈(Java Virtual Machine Stacks):每个方法在执行的同时都会在Java 虚拟机栈中创建一个栈帧(Stack Frame)用于存储局部变量表、操作数栈、动态链接、方法出口等信息;栈帧就是Java虚拟机栈中的下一个单位。
  • 本地方法栈(Native Method Stack):与虚拟机栈的作用是一样的,只不过虚拟机栈是服务 Java方法的,而本地方法栈是为虚拟机调用 Native 方法服务的;Native 关键字修饰的方法是看不到的,Native 方法的源码大部分都是 C和C++ 的代码
  • Java 堆(Java Heap):Java 虚拟机中内存最大的一块,是被所有线程共享的,几乎所有的对象实例都在这里分配内存;java堆是垃圾收集器管理的主要区域,因此也被成为“GC堆”。
  • 方法区(Methed Area):用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译后的代码等数据。虽然 Java 虚拟机规范把⽅法区描述为堆的⼀个逻辑部分,但是它却有⼀个别名叫做 Non-Heap(⾮堆),⽬的应该是与 Java 堆区分开来。

运行时常量池:

运⾏时常量池是⽅法区的⼀部分。Class ⽂件中除了有类的版本、字段、⽅法、接⼝等描述信息外,还有常量池表(⽤于存放编译期⽣成的各种字⾯量和符号引⽤)既然运⾏时常量池是⽅法区的⼀部分,⾃然受到⽅法区内存的限制,当常量池⽆法再申请到内存时会抛出 OutOfMemoryError 错误。

JDK1.8 运⾏时常量池在元空间,字符串常量池在堆中。

异常相关:

在这里插入图片描述

  • 程序计数器: 内存区域中唯一一个在Java虚拟机规范中没有规定任何OutOfMemoryError情况的区域。
  • 虚拟机栈与本地方法栈: 在Java虚拟机栈和本地方法栈中,规定了两个异常状况:如果线程请求的栈深度大于栈所允许的深度,将抛出StackOverflowError异常;如果栈可以动态扩展,并且扩展时无法申请到足够的内存,就会抛出OutOfMemoryError异常。
  • 堆: 如果在堆中没有内存完成实例分配,并且堆也无法再扩展时(内存大小超过“-xmx"所指定的最大内存时),将会抛出OutOfMemoryError异常。
  • 方法区: 方法区的大小决定了系统可以保存多少个类,如果系统定义了太多的类(比如说加载大量第三方jar包),导致方法区溢出,虚拟机会抛出 OutOfMemoryError 异常。

介绍下Java虚拟机栈?


Java虚拟机是线程私有的,它的生命周期和线程相同。 虚拟机栈描述的是Java方法执行的内存模型: 每个方法在执行的同时都会创建一个栈帧(StackFrame)用于存储局部变量表、操作数栈、动态链接、方法出口等信息

解析栈帧:

  • 局部变量表:是用来存储我们临时8个基本数据类型、对象引用地址、returnAddress类型。(returnAddress中保存的是return后要执行的字节码的指令地址。)
  • 操作数栈:操作数栈就是用来操作的,例如代码中有个 i = 6*6,他在一开始的时候就会进行操作,读取我们的代码,进行计算后再放入局部变量表中去
  • 动态链接:如果被调用的方法在编译期无法被确定下来,也就是说,只能够在程序运行期将调用的方法的符号转换为直接引用,由于这种引用转换过程具备动态性,因此也被称之为动态链接。
  • 方法返回地址:在方法退出后都返回到该方法被调用的位置,正常的话就是return调用者的pc计数器的值,不正常的话返回异常表中的对应信息

在这里插入图片描述

对于虚拟机栈来说不存在垃圾回收问题

Java 虚拟机栈会出现两种错误: StackOverFlowError 和 OutOfMemoryError 。

  • StackOverFlowError : 若 Java 虚拟机栈的内存⼤⼩不允许动态扩展,那么当线程请求栈的深度超过当前 Java 虚拟机栈的最⼤深度的时候,就抛出 StackOverFlowError 错误。
  • OutOfMemoryError : 若 Java 虚拟机堆中没有空闲内存,并且垃圾回收器也⽆法提供更多内存的话。就会抛出 OutOfMemoryError 错误。

扩展:那么⽅法/函数如何调⽤?

Java 栈可⽤类⽐数据结构中栈,Java 栈中保存的主要内容是栈帧,每⼀次函数调⽤都会有⼀个对应的栈帧被压⼊ Java 栈,每⼀个函数调⽤结束后,都会有⼀个栈帧被弹出。

Java ⽅法有两种返回⽅式: return 语句、抛出异常。不管哪种返回⽅式都会导致栈帧被弹出。

一个方法调用另一个方法,会创建很多栈帧吗?

会创建。如果一个栈中有动态链接调用别的方法,就会去创建新的栈帧,栈中是由顺序的,一个栈帧调用另一个栈帧,另一个栈帧就会排在调用者下面

递归的调用自己会创建很多栈帧吗?

答:递归的话也会创建多个栈帧,就是在栈中一直从上往下排下去


介绍下Java堆吗?


java堆(Java Heap)是java虚拟机所管理的内存中最大的一块,是被所有线程共享的一块内存区域,在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例,⼏乎所有的对象实例以及数组都在这⾥分配内存。

java堆是垃圾收集器管理的主要区域,因此也被成为“GC堆”。从垃圾回收的⻆度,由于现在收集器基本都采⽤分代垃圾收集算法,所以 Java 堆还可以细分为:新生代和老生代,再细致⼀点可分为:Eden 空间、From Survivor、To Survivor 空间等

在这里插入图片描述

根据Java虚拟机规范的规定,Java堆可以处于物理上不连续的内存空间中,只要逻辑上是连续的即可。当前主流的虚拟机都是可扩展的(通过 -Xmx 和 -Xms 控制)。如果堆中没有内存可以完成实例分配,并且堆也无法再扩展时,将会抛出OutOfMemoryError异常。


为什么要将永久代替换为元空间呢?


JDK1.8以前使用永久代(方法区),JDK1.8以后使用元空间

整个永久代有⼀个 JVM 本身设置固定大小上限,⽆法进⾏调整,而JVM加载的class的总数,方法的大小等都很难确定,因此对永久代大小的指定难以确定。太小的永久代容易导致永久代内存溢出,太大的永久代则容易导致虚拟机内存紧张,空间浪费。⽽元空间使⽤的是直接内存,受本机可⽤内存的限制,虽然元空间仍旧可能溢出,但是⽐原来出现的⼏率会更⼩。

元空间溢出时会得到如下错误: java.lang.OutOfMemoryError: MetaSpace

你可以使⽤ -XX MaxMetaspaceSize 标志设置最⼤元空间⼤⼩,默认值为 unlimited,这意味着它只受系统内存的限制。 -XX MetaspaceSize 调整标志定义元空间的初始⼤⼩如果未指定此标志,则 Metaspace 将根据运⾏时的应⽤程序需求动态地重新调整⼤⼩。


什么是直接内存


直接内存(Direct Memory)并不是虚拟机运行时数据区的一部分,也不是Java虚拟机中定义的内存区域。但是这部分内存也被频繁地使用,而且也可能导致 OutOfMemoryError 异常出现。

直接内存可以看成是物理内存和Java虚拟机内存的中间内存,他可以直接使⽤ Native 函数库直接分配堆外内存,然后通过⼀个存储在 Java 堆中的 DirectByteBuffer 对象作为这块内存的引⽤进⾏操作。这样就能在⼀些场景中显著提⾼性能,因为避免了在 Java 堆和 Native 堆之间来回复制数据。

本机直接内存的分配不会受到 Java 堆的限制,但是,既然是内存就会受到本机总内存⼤⼩以及处理器寻址空 需要zi料+ 绿色徽【vip1024b】

间的限制。


堆栈的区别是什么?


| 对比 | JVM堆 | JVM栈 |

| — | — | — |

| 物理地址方面 | 堆的物理地址分配对对象是不连续的。因此性能慢些。在GC的时候也要考虑到不连续的分配,所以使用了各种垃圾回收算法 | 栈使用的是数据结构中的栈,先进后出的原则,物理地址分配是连续的。所以性能快。 |

| 内存分配方面 | 堆因为是不连续的,所以分配的内存是在运行期确认的,因此大小不固定。一般堆大小远远大于栈。 | 栈是连续的,所以分配的内存大小要在编译期就确认,大小是固定的。 |

| 存放的内容方面 | 堆存放的是对象的实例和数组。因此该区更关注的是数据的存储 | 栈存放:局部变量,操作数栈,返回结果。该区更关注的是程序方法的执行。 |

| 程序的可见度 | 堆对于整个应用程序都是共享、可见的。 | 栈只对于线程是可见的。所以也是线程私有。他的生命周期和线程相同。 |

堆:主要用来存储对象和数组,物理地址分配不连续、内存大小不确定、线程共享

栈:用来存放操作数栈,物理地址分配连续、内存在编译期确定、线程私有


说⼀下Java对象的创建过程


  • 加载类元信息,判断类元信息(加载、链接、初始化)是否存在
  • 为对象分配内存
  • 处理并发问题
  • 初始化分配到的空间,属性的默认初始化(零值初始化)
  • 设置对象头信息
  • 执行init方法初始化(属性显示初始化、代码块中的初始化、构造器初始化)

在这里插入图片描述

2021年Java中高级面试必备知识点总结

在这个部分总结了2019年到目前为止Java常见面试问题,取其面试核心编写成这份文档笔记,从中分析面试官的心理,摸清面试官的“套路”,可以说搞定90%以上的Java中高级面试没一点难度。

本节总结的内容涵盖了:消息队列、Redis缓存、分库分表、读写分离、设计高并发系统、分布式系统、高可用系统、SpringCloud微服务架构等一系列互联网主流高级技术的知识点。

目录:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

(上述只是一个整体目录大纲,每个点里面都有如下所示的详细内容,从面试问题——分析面试官心理——剖析面试题——完美解答的一个过程)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

部分内容:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

对于每一个做技术的来说,学习是不能停止的,小编把2019年到目前为止Java的核心知识提炼出来了,无论你现在是处于什么阶段,如你所见,这份文档的内容无论是对于你找面试工作还是提升技术广度深度都是完美的。

不想被后浪淘汰的话,赶紧搞起来吧,高清完整版一共是888页,需要的话可以点赞+关注

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
492961)]

对于每一个做技术的来说,学习是不能停止的,小编把2019年到目前为止Java的核心知识提炼出来了,无论你现在是处于什么阶段,如你所见,这份文档的内容无论是对于你找面试工作还是提升技术广度深度都是完美的。

不想被后浪淘汰的话,赶紧搞起来吧,高清完整版一共是888页,需要的话可以点赞+关注

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
[外链图片转存中…(img-1aIZuGIX-1713557492961)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 18
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值