java后端面试题大全
- 3.JVM
- 3.1 对象实例、类信息、常量、静态变量分别在运行时数据区的哪个位置?
- 3.2 java类的加载流程
- 3.3 ThreadLocal
3.JVM
3.1 对象实例、类信息、常量、静态变量分别在运行时数据区的哪个位置?
- 堆
对象实例、String常量池、基本类型常量池、静态变量 - 方法区
类信息、类常量池、运行时常量池 - 虚拟机栈
临时变量
3.2 java类的加载流程
java文件到最终运行, 需要经过编译和类加载这两个阶段
编译的过程:把.java文件编译成.class文件
类加载的过程:把.class文件加载到jvm的内存中
- 加载
通过类的全限定名获取类的二进制数据, 这可以通过类加载器完成, 类加载器可以从文件系统、网络、ZIP文件等地方获取类文件的二进制数据
将获取的二进制数据转换为方法区(或元空间)的运行时数据结构, 这个数据结构存储了类的字段、方法、构造方法等信息,同时也包含了类的常量池,即字面量(如字符串、final常量)和符号引用等。 - 验证
确保被加载的类的正确性. 这个阶段主要包括文件格式验证、元数据验证、字节码验证等,以确保类文件的正确性和安全性。 - 准备
为类的静态变量分配内存并设置初始值, 这里的初始值通常是默认值,比如数值类型的默认值是0,引用类型的默认值是null - 解析
类、接口、字段和方法的符号引用解析为直接引用 - 初始化
类的初始化方法
3.3 ThreadLocal
一、简介
ThreadLocal是一种线程隔离机制,使得每个线程都可以拥有自己独立的变量副本,从而避免了多线程环境下的线程安全问题。
public class Demo {
static ThreadLocal<String> threadLocal = new ThreadLocal<>();
static void print(String str){
System.out.println(str + ":" + threadLocal.get());
}
public static void main(String[] args) {
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
threadLocal.set("abc");
print("thread1 variable");
}
});
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
threadLocal.set("def");
print("thread2 variable");
}
});
thread1.start();
thread2.start();
}
}
二、ThreadLocal与synchronized
虽然ThreadLocal与synchronized都用于处理多线程并发访问变量的问题, 不过两者处理问题的角度和思路不同
synchronized | ThreadLocal | |
---|---|---|
原理 | 同步机制采用时间换空间的方法, 只提供了一份变量, 让不同的线程排队访问 | ThreadLocal采用空间换时间的方式, 为每一个线程提供了一份变量的副本, 从而实现同时访问, 互不干扰 |
侧重点 | 多个线程之间访问资源的同步 | 多线程中让每个线程之间数据相互隔离 |
三、ThreadLocal的内部结构
视频