既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
1、讲一下 JVM 的垃圾回收的相关概念?
Java 虚拟机的垃圾回收是 Java 内存管理的一个重要部分,它负责自动化地管理 Java 程序的内存,通过识别和回收不再使用的对象来释放内存。垃圾回收器在程序运行时进行,尽管开发者无法直接控制其精确的运行时间,但可以通过编写“内存友好”的代码以及调整 JVM 配置参数来影响其行为。
以下是关于 JVM 垃圾回收的一些基本概念:
对象的生命周期:Java 对象的生命周期开始于创建(当使用 new 关键字时)并在不再有引用指向它们时结束。如果一个对象不再被引用,那么它就可能被垃圾回收。
堆(Heap)内存:Java 对象存储在堆内存中。堆在 JVM 启动时创建,可以通过 JVM 参数调整其大小。
垃圾回收算法:垃圾回收器使用特定的算法来确定哪些对象可以被视为"垃圾"并进行回收。常见的垃圾回收算法有标记-清除、标记-压缩、复制、以及分代回收等。
停顿时间:垃圾回收器在运行时,通常会导致 Java 应用程序的执行暂停,这种现象被称为“停顿时间”。减少停顿时间是垃圾回收器优化的一个重要目标。
分代回收:Java 的垃圾回收器通常采用分代回收策略,将堆内存分为新生代和老年代。这种策略基于这样一个观察:大多数对象的生命周期都很短。
新生代:新创建的对象首先放在新生代。新生代通常分为一个 Eden 区和两个 Survivor 区(S0和 S1)。大部分对象在 Eden 区被垃圾回收。
老年代:如果对象在新生代中存活了足够长的时间,它们会被移动到老年代。老年代的空间通常比新生代大,并且其垃圾回收频率较低。
垃圾回收器:Java 提供了多种垃圾回收器,包括 Serial、Parallel、CMS、G1以及 ZGC等。每种垃圾回收器都有其特定的使用场景和优劣,选择哪种垃圾回收器取决于具体的应用需求。
2、JVM 常见调优方法有哪些?
内存分配:扩大 JVM 堆的大小可以提供更多的空间给对象,减少垃圾回收(GC)的次数。使用-Xms 和-Xmx 参数可以分别设置堆的初始大小和最大大小。然而,分配过多的内存可能会导致更长的 GC 停顿时间,并可能影响其他进程的性能。
选择垃圾回收器:根据应用的需求和特性选择合适的垃圾回收器。例如,对于需要低延迟的实时系统,选择并发垃圾回收器(如 CMS 或 G1)可能是个好选择。对于可以容忍更长 GC 停顿时间的批处理任务,使用并行垃圾回收器可能更为合适。
调整新生代和老年代的比例:JVM 的堆内存被划分为新生代和老年代,其中新生代通常分为 Eden 区和两个 Survivor 区(S0和 S1)。这些区域的大小可以通过参数-XX:NewRatio,-XX:SurvivorRatio 进行调整。这种调整可以根据应用的对象生命周期进行,以减少 GC 的次数。
调整线程堆栈大小:使用-Xss 参数可以设置每个线程的堆栈大小。如果应用创建了大量的线程,减小线程堆栈大小可能会帮助减少内存消耗。
启用类数据共享:类数据共享可以加快 JVM 启动速度并减少内存消耗。可以通过-XX:+UseSharedSpaces 参数启用 CDS。
使用 JVM 内建工具进行监控和故障排查:JVM 提供了一些内建工具,如 JConsole, VisualVM, jstat 等,可以用于监控 JVM 的性能和资源使用情况,帮助定位和解决性能问题。
3、请解释下Java中的线程池是什么,如何使用线程池来提高程序的性能?
Java中的线程池是一种管理和复用线程的机制,可以通过预先创建、管理和重复利用线程对象来优化多线程程序的性能。使用线程池可以减少频繁创建和销毁线程带来的开销,并且可以控制同时执行任务的最大数量。
具体使用方法如下:
- 使用’ExecutorService’接口提供的’newFixedThreadPool’方法初始化一个固定大小的线程池。
- 创建实现了’Runnable’接口的任务。
- 将任务提交给线程池处理,调用’submit()'方法提交任务。
- 线程池会自动分配可用于处理任务的工作线程,并在执行完后将其放回到缓存队列中等待新任务。
优点:使用线程池机制可以避免因频繁创建和销毁大量额外开销,能够高效触发系统资源利用率;同时,还可方便地控制并发协同与资源消耗。
4、请解释Java中HashMap和HashTable的区别?
HashMap和HashTable是两个常见的哈希表实现类,在以下几个方面有所不同:
- 线程安全性:HashTable是线程安全的,各个方法都有synchronized修饰,适用于多线程环境。而HashMap不是线程安全的,如果多个线程同时访问一个HashMap实例并且至少一个线程修改了Map结构,则必须通过外部同步机制来保证其同步。
- 允许空键和空值:HashMap允许插入null键和null值,而HashTable不允许。
- 迭代器遍历顺序:HashMap的迭代器是fail-fast的,即在迭代过程中如果其它线程对HashMap进行结构修改(增加或者删除元素),会抛出异常。而HashTable继承自Dictionary类,并不支持迭代器。
5、什么是JVM垃圾回收?Java中有几种垃圾回收算法?
JVM垃圾回收指的是当Java应用程序运行时,自动释放不再使用的对象内存空间,并进行资源回收和整理过程。JVM提供了几种垃圾回收算法:
- 标记-清除算法:首先标记所有被引用对象,在清除阶段将未标记的对象释放。
- 复制算法:将内存分为相同大小的两块,每次只使用其中的一块。当一块内存用完了之后,将活着的对象复制到另一块内存上,并清除原来使用过的内存。
- 标记-整理算法:先标记所有被引用对象,然后将活着的对象移动到一端,最后清除边界以外的对象。
- 分代收集算法:根据对象生命周期划分为不同代,在垃圾回收时更关注年轻代,因为大多数新生的对象很快就会死去。这种方式减少了全局垃圾检查和处理时间。
6、请解释下Java中的String、StringBuilder和StringBuffer的区别?
String、StringBuilder和StringBuffer是Java用来操作字符串的类,在以下几个方面有所不同:
- 可变性:String类是不可变类,即String对象在创建后其值不能被改变;而StringBuilder和StringBuffer类是可变类,提供了修改和拼接字符串方法。
- 线程安全行:String是线程安全的;StringBuilder是非线程安全的;StringBuffer是线程安全但效率相对较低。
- 性能效率:由于StringBuilder不是线程安全且没有额外开销,在并发访问场景下比其它两者更高效。如果需要多个线程共享一个字符串缓存区,推荐使用StringBuffer类。
总的来说,如果需要频繁修改字符串且涉及多线程操作,应使用StringBuffer;如果是单线程操作且需要频繁修改字符串,则选择StringBuilder;而若字符串内存不需要被修改,则使用String更为合适。
7、Java的垃圾回收机制是什么?简要描述它的工作原理
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
路线、讲解视频,并且后续会持续更新**