当前位置: 首页 > news >正文

测试开发面试题---JVM

JAVA的内存区域

  • 程序计数器:线程私有的,保存当前线程的字节码文件。
  • JAVA虚拟机栈:包含局部变量信息,用于方法的调用和执行。
  • 本地方法栈:与JAVA虚拟机栈类似,但只服务于本地方法。
  • 堆:所有线程共享,存放对象实例变量,GC的主要区域。
  • 方法区:所有线程共享,用于存放已经被JVM加载的类信息。
  • 运行时常量池:所有线程共享,方法区的一部分,存储编译期间生成的字面量和符号引用

JAVA栈和堆的区别

  • 栈主要用于存储局部变量和方法调用的上下文信息,栈中数据生命周期短暂,当元素调用结束时,占空间会被释放;每个线程有自己独立的栈空间,栈上的数据不能被其他线程访问和修改;堆栈上的数据访问速度更快(堆中数据涉及复杂的算法保证数据分配和回收)。
  • 堆主要用于存储对象实例和变量,堆的生命周期不稳定,当对象不再被引用时,堆会自动调用GC进行回收,堆中的数据所有线程共享,可以被其他线程访问和修改。 

JAVA虚拟机栈溢出情况

  • 递归调用过深:当一个方法调用自身时,如果没有正确的终止条件或者终止条件不满足。
  • 方法调用层次过深:层层嵌套调用。
  • 线程过多
  • 栈帧过大:方法中局部变量过多,或者单个局部变量过大
  • JVM参数配置不当:JVM为每个线程分配的栈过小。

解决方法

  • 优化递归逻辑,确保递归调用有明确的终止条件,如果可以,将递归改为迭代。
  • 合理设置JVM参数,增加每个线程的大小。
  • 避免无限制创建线程。

垃圾回收(GC)算法

  • Serial:单线程,在回收垃圾的时候会暂停所有的事情。
  • CMS:多线程,采用标记-清理方法产生大量空间碎片。
  • G1:多线程,强化分区,将JVM堆划分为多个区域,每次选择最多的区域进行回收。

类加载器

类加载器是JVM加载类文件的组件,它负责将字节码文件加载到内存中并转化为.class对象。

类加载过程

  1. 加载:根据类的全限定名查找它的字节码文件并创建.class对象
  2. 验证:验证类文件格式是否正确
  3. 准备:为静态变量创建内存并初始化默认值
  4. 解析:将符号引用改为直接引用
  5. 初始化:之形类的静态初始化块以及对静态变量赋值

分类

启动类加载器、扩展类加载器和应用程序类加载器

双亲委派模型

当一个类加载器需要加载一个类的时候,它先让它的父类去加载这个类,如果父类无法加载它就自己加载,这主要是为了避免核心类库被重复加载。

进程和线程

  • 进程:资源分配的基本单位,拥有独立的内存空间和资源,创建和销毁开销大,具有良好的错误隔离和稳定性。
  • 线程:程序执行的基本单位,共享进程的内存资源,适合高效的并发和并行程序。
  • 并发:一个系统能够处理多个任务,这些任务不需要同时执行
  • 并行:同一时刻执行多个任务

用户线程:执行具体的业务逻辑,完成程序的核心功能。只要有一个用户线程在执行,JVM就不会退出。

守护线程:提供辅助功能,主要用于后台任务,它的生命周期取决于用户线程,一旦用户线程执行完毕,JVM会强制退出,所有的守护线程也会退出。

Start和Run方法

Start会创建并执行一个新的线程,Run只是执行当前线程不会启动一个新线程。

线程状态

  1. new:线程刚创建时候
  2. 就绪:在可运行线程池中等待CPU时间片
  3. 运行:获得CPU时间片开始运行
  4. 阻塞:等待某种条件的发生(等待锁的释放)
  5. 终止:线程执行完毕

Sleep和Wait

  • Sleep是线程类的方法,它不会释放锁而是在指定时间后恢复对线程的执行;用于定时任务或者防止循环过快消耗CPU资源。
  • Wait是Object类的方法,它会释放锁然后等待另一个线程用notify来唤醒;用于线程间的同步和通信。

公平锁:保证线程按照它们申请的顺序获得锁,每个线程都会获得锁不会导致线程饥饿。

非公平锁:不保证线程按照它们申请的顺序获得锁,锁的获取和释放更快,但可能导致线程饥饿。

Sychronized锁

JAVA的关键字,用于线程之间互斥和同步,作用于方法和代码块;由JVM管理,简单易用,可重入,自动释放锁;它是自动释放锁,可能会导致线程饥饿,不可中断。保证互斥、原子性和可见性。

Sychronized锁升级

  • 偏向锁:优化技术,减少无竞争情况下的同步代价。如果一个线程获得了偏向锁,它在接下来的的锁请求中无需进行同步操作,直接进入临界区。只有在其他线程尝试竞争这把锁的时候,偏向锁才会撤销(锁的头部会记录第一个获得锁线程的ID,当这个锁再次被线程请求的时候,无需CAS直接进入临界区)。适合于无竞争情况,减少无竞争下的同步开销。
  • 轻量级锁:自旋锁,线程获取锁失败的时候不立即阻塞而是忙循环反复尝试获取锁。适合于竞争时间比较小的锁,避免线程阻塞和唤醒的开销。
  • 锁粗化:将多个小范围锁合并成一个大范围的锁,减少加锁解锁的开销。
  • 锁去除:在编译期间判断锁对象是否只在当前线程内使用,如果是则去除锁。

首先,Sychronized通过尝试获取偏向锁来竞争资源,如果能竞争到代表加锁成功,如果不行则需要将锁升级为轻量级锁,在轻量级锁状态下线程会根据自旋次数来抢占锁资源,如果还是无法竞争到,会升级到重量级锁,在重量级锁状态下,没有竞争到锁的线程会被阻塞。

Volatile

轻量级的同步机制保证变量的可见性和有序性,它通过将修改后的值直接刷新到内存中来确保其他线程对修改后的变量值立即可见;通过禁止指令重排序来达到有序性。

Lock

Lock最常用的实现类是Reentrantlock(可重入锁,允许一个线程多次获取同一个锁而不会阻塞)。它的锁的获取和释放需要显示调用lock()和unlock()方法,它可以被配置为公平锁或者非公平锁;提供了trylock()方法来中断锁,提供了更加强大的功能,是用于处理复杂场景。

Sychronized与Volatile区别

Volatile比Sychronized有更小的性能开销,但Volatile只保证可见性和有序性,不保证复杂操作的原子性,它只适合状态标志、配置参数等不涉及复杂逻辑的变量,在复杂场景下仍旧使用Sychronized。

Sychronized与Lock区别

Sychronized是JAVA关键字,Lock是JUC的接口;Lock的灵活性更高,它可以使用lock()和unlock()方法随时加锁、解锁,Sychronized只能在同步代码块执行完自动释放锁;Lock提供了非公平锁和公平锁,Sychronized只提供非公平锁;如果同步代码块中抛出异常,Sychronized会自动释放,Lock则需要在finally中显示释放,否则会导致死锁。总之,Sychronized提供了更加简单直接的同步机制,而Lock提供了功能更加强大更灵活的同步机制。

Threadlock

Threadlock是线程变量,为每个使用该变量的线程提供了一个变量副本,每个线程可以独立修改自己的变量副本而不受其他线程的影响。它的实现核心在于每个线程维护了一个ThreadlockMap的对象,该对象保存了自己的本地变量。

使用场景

  • 线程的上下文切换
  • 数据库连接
  • 事务管理,事务处理中保存每个事务信息
  • 对象跨层传递时,打破层级间的约束避免多次传递

可能会导致内存泄漏,因为ThreadlockMap键是弱引用,但是它的值是强引用。当Threadlock没有被其他引用时,它会被GC收回,但是它的值无法回收。每次使用Threadlock后要利用remove清除数据。

JAVA内存模型

  • 可见性:线程对变量的修改对其他线程可见
  • 原子性:操作是不可以分割的,要么完全成功要么失败
  • 有序性:禁止指令重排序
  • 工作内存和主内存:主内存是线程共享区域,工作内存是每个线程私有区域。工作内存中保留了线程所需要的变量副本,线程修改变量的时候是在工作内存中,修改完成后刷新到主内存中。

JAVA内存模型中的关键机制

  • Volatile:可见性和有序性
  • Sychroized:互斥、可见性、有序性和原子性
  • happens-before:保证前一个操作在后一个操作之前且对后一个操作可见。

JAVA中常见的并发容器

  • ConcurrentHashMap:采用分段锁的技术,将整个数据分为多个段,每个段使用独立锁,在JAVA 8以后,采用更加高效CAS和同步链表代替分段锁,进一步提高性能。
  • CopyonWriteArraylist:写操作时,不直接修改原来的数组而是创建一个新的数组,使用新数组来代替就数组,在读多写少的情况下性能更高。

线程池

线程启动前就创建若干个线程等待响应,减少了频繁创建和销毁线程的开销,通过控制并发线程数量和合理的任务调度来更好地进行资源调度;避免在高并发下因为创建过多线程导致系统崩溃,提供了更好的系统稳定性;在完成任务后将线程归还到池中,避免线程未正确销毁导致的泄露。

线程池的参数

  • 核心线程数:线程池中始终保持的线程数量,线程池会优先使用核心线程来执行任务
  • 最大线程数:线程池中可以创建线程的上限
  • 空闲线程存活时间:非核心线程在执行完任务后最久存活时间
  • 任务队列:存储等待执行的线程,当前线程数达到核心线程的数量时,新提交的任务会保留在任务队列中
  • 拒绝策略:当任务队列已满且达到最大线程数时,线程池无法接受新的任务

实现原理

线程池在创建时根据默认的参数配置核心线程,无论是否当前有任务需要执行,这些线程都会一直保留在线程池中。当需要执行任务时,线程池会优先使用这些线程去执行。如果当前没有空闲的核心线程,就会把这个任务放在任务队列中等待执行。如果任务队列已满但还未达到线程池中所能接受的最大核心数时,线程池会创建一个新的线程去处理这个任务。当任务队列已满且线程数达到最大线程数时,线程池采用拒绝策略停止继续工作。任务完成后,线程会返回空闲状态。核心线程不会回收,非核心线程会根据空闲线程存活时间进行回收。当线程池不在需要的时候,调用shutdown()和shutdownnow()来执行(shutdown()是等待已提交的任务完成后回收,shutdownnow()会尝试停止当前正在执行的任务然后回收)

线程池的拒绝策略

  • 默认策略:直接抛出异常
  • 调用者运行策略:提交任务的线程自己处理任务,降低任务提交速度
  • 直接丢弃策略:丢弃无法处理的任务,不抛出异常
  • 丢弃最旧策略:丢弃队列中最旧的未处理的任务

execute和submit区别

execute只能提交实现了Runnable接口的任务,不返回任何结果,当出现异常时会直接抛出异常。submit可以提交实现了Runnable和Callable接口的任务,对于Callable任务会返回一个Future对象,这个对象可以检查任务是否完成,如果遇到异常允许调用者捕获并处理异常。

相关文章:

测试开发面试题---JVM

JAVA的内存区域 程序计数器:线程私有的,保存当前线程的字节码文件。JAVA虚拟机栈:包含局部变量信息,用于方法的调用和执行。本地方法栈:与JAVA虚拟机栈类似,但只服务于本地方法。堆:所有线程共…...

python库 - jsonpath

JSONPath 是一种用于从 JSON 数据中提取数据的查询语言,类似于 XML 中的 XPath。它允许通过路径表达式来导航和查询 JSON 结构中的数据。JSONPath 在处理 API 响应、配置文件和复杂数据结构时非常有用。 以下是一些常用的 JSONPath 表达式及其功能: $&…...

[RK3588][Android12] Android->OTA包超过4个G导致打包失败

测试平台 Platform: RK3588 OS: Android12 问题说明: 有的客户需要往系统中内置大量apk,这样就导致最终打包的OTA包超过4个G,从而导致打包OTA的时候报错:Zipfile size would require ZIP64 extensions 解决方法: 可能…...

(雷达数据处理中的)跟踪算法(3) – 可用于目标跟踪实践的数据集介绍解析

说明 本博文作为跟踪算法系列博文的第3篇,对可用于目标跟踪的一份数据集进行了介绍,本文介绍的这份数据集将用于后续博文的目标跟踪实践。读者在阅读本博文前,建议先看看本系列的第一篇博文[1]:(雷达数据处理中的)跟踪…...

【C语言报错已解决】Use of Uninitialized Variable

🎬 鸽芷咕:个人主页 🔥 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想,就是为了理想的生活! 引言: 在编程中,未初始化的变量是一个常见的问题,它可能导致程序的行为变得不可预测。未初…...

3 Go语言的变量声明

本专栏将从基础开始,循序渐进,由浅入深讲解Go语言,希望大家都能够从中有所收获,也请大家多多支持。 查看相关资料与知识库 专栏地址:Go专栏 如果文章知识点有错误的地方,请指正!大家一起学习,…...

PyMySQL库的使用方法

过程和步骤: 安装 PyMySQL 首先,需要使用 pip 安装 PyMySQL 库: pip install pymysql连接数据库 使用 PyMySQL.connect() 方法可以建立到 MySQL 数据库的连接: import pymysql# 配置数据库连接参数 config {host: localhost…...

iOS 创建一个私有的 CocoaPods 库

创建一个私有的 CocoaPods 库(pod)涉及几个步骤,包括设置私有的 Git 仓库、创建 Podspec 文件、发布到私有仓库等等。以下是详细步骤: 设置私有 Git 仓库 首先,在 GitHub、GitLab 或 Bitbucket 上创建一个新的私有仓库…...

Linux_实现UDP网络通信

目录 1、实现服务器的逻辑 1.1 socket 1.2 bind 1.3 recvfrom 1.4 sendto 1.5 服务器代码 2、实现客户端的逻辑 2.1 客户端代码 3、实现通信 结语 前言: 在Linux下,实现传输层协议为UDP的套接字进行网络通信,网络层协议为IPv4&am…...

C# 代理模式

栏目总目录 概念 代理模式是一种结构型设计模式,它为其他对象提供一种代理以控制对这个对象的访问。在代理模式中,我们创建一个具有现有对象(称为“真实对象”或“被代理对象”)相同功能的代理对象。代理对象可以在客户端和目标对…...

【1】Python机器学习之基础概念

1、什么是机器学习 最早的机器学习应用——垃圾邮件分辨 传统的计算机解决问题思路: 编写规则,定义“垃圾邮件”,让计算机执行对于很多问题,规则很难定义规则不断变化 机器学习在图像识别领域的重要应用: 人脸识别…...

HashMap源码解析

目录 一:put方法流程 二:get方法 三:扩容机制 一:put方法流程 public V put(K key, V value) {return putVal(hash(key), key, value, false, true); }final V putVal(int hash, K key, V value, boolean onlyIfAbsent,boolean evict) {No…...

[Javascript】前端面试基础3【每日学习并更新10】

Web开发中会话跟踪的方法有那些 cookiesessionurl重写隐藏inputip地址 JS基本数据类型 String:用于表示文本数据。Number:用于表示数值,包括整数和浮点数。BigInt:用于表示任意精度的整数。Boolean:用于表示逻辑值…...

C++自定义字典树结构

代码 #include <iostream> using namespace std;class TrieNode { public:char data;TrieNode* children[26];bool isTerminal;TrieNode(char ch){data ch;for (int i 0; i < 26; i){children[i] NULL;}isTerminal false;} }; class Trie { public:TrieNode* ro…...

dockerfile部署wordpress

1.将容器直接提交成镜像 [rootlocalhost ~]# docker commit 8ecc7f6b9c12 nginx:1.1 sha256:9a2bb94ba6d8d952527df616febf3fbc8f842b3b9e28b7011b50c743cd7b233b [rootlocalhost ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE nginx …...

CSS(二)——CSS 背景

CSS 背景 CSS 背景属性用于定义HTML元素的背景。 CSS 背景属性 Property描述background简写属性&#xff0c;作用是将背景属性设置在一个声明中。background-attachment背景图像是否固定或者随着页面的其余部分滚动。background-color设置元素的背景颜色。background-image把…...

开机出现grub无法进入系统_电脑开机出现grub解决方法

最近有小伙伴问我电脑开机出现grub无法进入系统怎么回事&#xff1f;电脑开机出grub的情况有很多&#xff0c;电脑上安装了Linux和Win10双系统&#xff0c;但是由于格式化删除了Linux之后&#xff0c;结果win10开机了之后&#xff0c;直接显示grub&#xff1e;&#xff0c;无法…...

uboot 设置bootargs配置内核网络挂载根文件系统

uboot 设置bootargs配置内核网络挂载根文件系统 uboot设置bootargs env set bootargs "mem256M consolettyAMA0,115200 root/dev/nfs init/linuxrc nfsrootnfs主机地址:nfs路径/busybox/rootfs_glibc_arm64,prototcp rw nfsvers3 rootwait ip板子地址:nfs主机地址:网关:2…...

Vue3+.NET6前后端分离式管理后台实战(三十一)

1&#xff0c;Vue3.NET6前后端分离式管理后台实战(三十一)...

22集 如何minimax密钥和groupid-《MCU嵌入式AI开发笔记》

22集 如何获取minimax密钥和groupid-《MCU嵌入式AI开发笔记》 minimax密钥获取 https://www.minimaxi.com/platform 进入minimax网站&#xff0c;注册登录后&#xff0c;进入“账户管理”&#xff0c; 然后再点击“接口密钥”&#xff0c;然后再点击“创建新的密钥”。 之…...

决策树的概念

决策树的概念 决策树是一种监督学习算法&#xff0c;主要用于分类任务。它通过构建一棵树结构模型来进行预测&#xff0c;其中每个内部节点表示一个特征属性上的判断条件&#xff0c;每条边代表一个判断结果对应的分支&#xff0c;而叶节点则代表最终的类别标签。 应用领域 …...

C++《类和对象》(中)

一、 类的默认成员函数介绍二、构造函数 构造函数名与类同名内置类型与自定义类型析构函数拷贝构造函数 C《类和对象》(中) 一、 类的默认成员函数介绍 默认成员函数就是⽤⼾没有显式实现&#xff0c;编译器会⾃动⽣成的成员函数称为默认成员函数。 那么我们主要学习的是1&…...

SpringBoot中JSR303校验

JSR是 Java EE 的一种标准&#xff0c;用于基于注解的对象数据验证。在Spring Boot应用中&#xff0c;你可以通过添加注解直接在POJO类中声明验证规则。这样可以确保在使用这些对象进行操作之前&#xff0c;它们满足业务规则。个人认为非常有用的&#xff0c;因为它减少了代码中…...

图像数据增强方法概述

图像数据增强方法概述 1. 什么是图像数据增强技术?2. 图像数据增强技术分类2.1 几何变换Python 示例代码 2.2 颜色变换2.3 噪声添加 3. 参考文献 1. 什么是图像数据增强技术? 基础概念&#xff1a;图像增强技术是计算机视觉和图像处理领域中的一个关键技术&#xff0c;主要用…...

【学习笔记】无人机系统(UAS)的连接、识别和跟踪(五)-无人机跟踪

目录 引言 5.3 无人机跟踪 5.3.1 无人机跟踪模型 5.3.2 无人机位置报告流程 5.3.3 无人机存在监测流程 引言 3GPP TS 23.256 技术规范&#xff0c;主要定义了3GPP系统对无人机&#xff08;UAV&#xff09;的连接性、身份识别、跟踪及A2X&#xff08;Aircraft-to-Everyth…...

分享从零开始学习网络设备配置--任务6.1 实现计算机的安全接入

项目描述 随着网络技术的发展和应用范围的不断扩大&#xff0c;网络已经成为人们日常生活中必不可少的一部分。园区网作为给终端用户提供网络接入和基础服务的应用环境&#xff0c;其存在的网络安全隐患不断显现出来&#xff0c;如非人为的或自然力造成的故障、事故&#xff1b…...

双向链表(C语言版)

1. 双向链表的结构 注意&#xff1a;这里的“带头”跟单链表的“头结点”是两个概念&#xff0c;实际上在单链表阶段称呼不太严谨&#xff0c;但是为了更好地理解就直接称为单链表的头结点。带头链表里的头结点&#xff0c;实际为“哨兵位”&#xff0c;哨兵位结点不存储任何有…...

【算法/学习】前缀和差分

前缀和&&差分目录 1. 前缀和的概念及作用 &#x1f308;概念 &#x1f308;用途 &#x1f319;一维前缀和 &#x1f319;二维前缀和 2. 差分的概念及用途 &#x1f308;概念&#xff1a; &#x1f308;用途 &#x1f319;一维差分 &#x1f319;二维差分 1. …...

idea Project 不显示文件和目录

idea Project 不显示文件和目录 File - Close Project - 重新打开项目即可删除.idea文件夹&#xff0c;重新打开项目即可。 原因分析: 可能与使用不同ide例如java、python打开同一项目有关 参考: https://blog.csdn.net/hgnuxc_1993/article/details/132595900 解决打开IDE…...

Linux--Socket编程预备

目录 1. 理解源 IP 地址和目的 IP 地址 2.端口号 2.1端口号(port)是传输层协议的内容 2.2端口号范围划分 2.3理解 "端口号" 和 "进程 ID" 2.4理解 socket 3.传输层的典型代表 3.1认识 TCP 协议 3.2认识 UDP 协议 4. 网络字节序 5. socket 编程接…...