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

Java面试题及详细答案120道之(081-100)

前后端面试题》专栏集合了前后端各个知识模块的面试题,包括html,javascript,css,vue,react,java,Openlayers,leaflet,cesium,mapboxGL,threejs,nodejs,mangoDB,MySQL,Linux… 。

前后端面试题-专栏总目录

在这里插入图片描述

文章目录

  • 一、本文面试题目录
      • 81. Java中的`ConcurrentHashMap`与`HashMap`在并发场景下有什么区别?
      • 82. 解释Java中的`JIT`编译
      • 83. Java中的`try-catch-finally`中`return`的执行顺序是什么?
      • 84. 什么是Java中的`Record`(记录类)?
      • 85. Java中的`Arrays.asList()`返回的列表有什么特点?
      • 86. Java中的`synchronized`关键字的实现原理(JDK 6+的优化)
      • 87. 什么是Java中的`模式匹配(Pattern Matching)`?
      • 88. Java中的`@FunctionalInterface`注解有什么作用?
      • 89. 解释Java中的`内存泄漏`及常见场景
      • 90. 什么是Java的反射机制?有哪些常见应用场景?
      • 91. Java中的异常体系结构是怎样的?`Checked Exception`和`Unchecked Exception`有何区别?
      • 92. `try-catch-finally`中,如果`finally`有`return`,`try`或`catch`中的`return`会生效吗?
      • 93. 什么是线程安全?如何实现线程安全?
      • 94. `synchronized`和`Lock`的区别是什么?
      • 95. 什么是死锁?如何避免死锁?
      • 96. Java中的线程池有哪些核心参数?`ThreadPoolExecutor`的工作原理是什么?
      • 97. Java中的`volatile`关键字有什么作用?它能保证原子性吗?
      • 98. 什么是Java内存模型(JMM)?它解决了什么问题?
      • 99. `ArrayList`和`LinkedList`的区别是什么?各自的适用场景?
      • 100. `HashMap`的底层实现原理是什么?JDK1.7和JDK1.8有何区别?
  • 二、120道面试题目录列表

一、本文面试题目录

81. Java中的ConcurrentHashMapHashMap在并发场景下有什么区别?

原理

  • HashMap:非线程安全,并发修改可能导致ConcurrentModificationException
  • ConcurrentHashMap(JDK 8+):线程安全,采用“CAS + 同步块”实现,支持高并发读写,效率优于HashTable

核心区别

  • 锁粒度:ConcurrentHashMap锁桶(链表/红黑树),HashTable锁整个表;
  • 迭代器:ConcurrentHashMap的迭代器弱一致性(不抛异常),HashMap的迭代器快速失败。

代码示例

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;public class ConcurrentMapDemo {public static void main(String[] args) throws InterruptedException {Map<String, Integer> map = new ConcurrentHashMap<>();// 多线程并发写入Runnable task = () -> {for (int i = 0; i < 1000; i++) {map.put(Thread.currentThread().getName() + i, i);}};Thread t1 = new Thread(task);Thread t2 = new Thread(task);t1.start();t2.start();t1.join();t2.join();System.out.println("map大小:" + map.size()); // 输出2000(无并发问题)}
}

82. 解释Java中的JIT编译

原理:JIT(即时编译)是JVM的优化技术,将热点代码(频繁执行的代码)从字节码编译为机器码,提高执行效率(字节码解释执行慢)。
关键概念

  • 解释执行:字节码逐条翻译为机器码,启动快但执行慢;
  • 编译执行:提前将字节码编译为机器码,执行快但启动慢;
  • 混合模式:JVM默认模式,结合两者优势(热点代码编译,其他解释)。

代码示例(热点代码触发JIT):

public class JITDemo {// 热点方法(被频繁调用)public static int add(int a, int b) {return a + b;}public static void main(String[] args) {// 频繁调用add(),触发JIT编译for (int i = 0; i < 10_000_000; i++) {add(i, i + 1);}}
}

83. Java中的try-catch-finallyreturn的执行顺序是什么?

原理finally块始终执行(除非JVM退出),若trycatch中有return,会先执行finally,再返回结果(finally中的return会覆盖之前的返回值)。

代码示例

public class TryCatchFinally {public static int test() {try {System.out.println("try块");return 1; // 先暂存返回值1,执行finally后返回} catch (Exception e) {return 2;} finally {System.out.println("finally块");// return 3; // 若打开此行,最终返回3(覆盖try的return)}}public static void main(String[] args) {System.out.println("结果:" + test());// 输出:try块 → finally块 → 结果:1}
}

84. 什么是Java中的Record(记录类)?

原理:JDK 16引入的Record,用于简化“数据载体”类(仅含字段和访问方法),自动生成equals()hashCode()toString()和构造器。
特点:不可变(字段final),不能继承其他类(可实现接口)。

代码示例

// 记录类:自动生成getter、equals、hashCode、toString
public record Point(int x, int y) {// 可定义静态方法或构造器public Point { // 紧凑构造器(无参数列表)if (x < 0 || y < 0) {throw new IllegalArgumentException("坐标不能为负");}}public static Point origin() { // 静态方法return new Point(0, 0);}
}public class RecordDemo {public static void main(String[] args) {Point p = new Point(3, 4);System.out.println(p.x()); // 自动生成的getter(无get前缀)System.out.println(p); // 输出Point[x=3, y=4](自动生成的toString)}
}

85. Java中的Arrays.asList()返回的列表有什么特点?

原理Arrays.asList()返回java.util.Arrays.ArrayList(内部类),而非java.util.ArrayList,特点:

  • 长度固定(不可增删元素,否则抛UnsupportedOperationException);
  • 底层是原数组的视图(修改列表元素会同步修改原数组);
  • 不支持null元素(针对基本类型数组的包装类)。

代码示例

import java.util.Arrays;
import java.util.List;public class AsListDemo {public static void main(String[] args) {String[] arr = {"a", "b", "c"};List<String> list = Arrays.asList(arr);// 修改列表元素 → 原数组同步修改list.set(0, "x");System.out.println(arr[0]); // 输出x// list.add("d"); // 抛出UnsupportedOperationException(长度固定)// 转换为可修改的ArrayListList<String> mutableList = new java.util.ArrayList<>(list);mutableList.add("d"); // 成功}
}

86. Java中的synchronized关键字的实现原理(JDK 6+的优化)

原理synchronized通过锁机制保证同步,JDK 6+引入锁升级优化,避免性能损耗:

  1. 偏向锁:单线程访问时,仅记录线程ID,无竞争时无需加锁;
  2. 轻量级锁:多线程交替访问,通过CAS尝试获取锁,避免重量级锁开销;
  3. 重量级锁:多线程竞争激烈时,使用操作系统互斥量,性能较差。

代码示例(同步方法与同步块):

public class SynchronizedDemo {// 同步方法(锁为当前对象)public synchronized void syncMethod() {// 同步代码}// 同步块(锁为指定对象)public void syncBlock() {Object lock = new Object();synchronized (lock) {// 同步代码}}
}

87. 什么是Java中的模式匹配(Pattern Matching)

原理:JDK 16+引入的语法糖,简化类型判断和转换,主要用于instanceofswitch
instanceof模式匹配:判断类型的同时完成转换,避免显式强转。

代码示例

public class PatternMatching {public static void print(Object obj) {// 传统方式:先判断再强转if (obj instanceof String) {String str = (String) obj;System.out.println("字符串长度:" + str.length());}// 模式匹配:判断+转换一步完成if (obj instanceof String str) { // 变量str仅在if块内有效System.out.println("字符串长度:" + str.length());}// switch模式匹配(JDK 17+)switch (obj) {case Integer i -> System.out.println("整数:" + i);case String s -> System.out.println("字符串:" + s);default -> System.out.println("未知类型");}}
}

88. Java中的@FunctionalInterface注解有什么作用?

原理@FunctionalInterface是标记注解,用于编译期检查接口是否为函数式接口(仅含一个抽象方法),若不符合则编译报错,增强代码可读性。

代码示例

@FunctionalInterface // 正确:仅一个抽象方法
interface MyFunction {void doSomething();default void defaultMethod() {} // 允许默认方法static void staticMethod() {} // 允许静态方法
}// @FunctionalInterface // 编译错误:两个抽象方法
interface InvalidFunction {void method1();void method2();
}

89. 解释Java中的内存泄漏及常见场景

原理:内存泄漏指对象不再使用但未被GC回收,导致内存占用持续增加,最终可能引发OutOfMemoryError
常见场景

  • 静态集合持有对象(如static List未清除元素);
  • 未关闭资源(如流、连接未调用close());
  • 匿名内部类持有外部类引用(如线程未终止,外部类无法回收);
  • ThreadLocal未调用remove()(线程池线程复用导致变量残留)。

代码示例(静态集合导致内存泄漏):

import java.util.ArrayList;
import java.util.List;public class MemoryLeak {// 静态集合持有对象引用private static List<Object> list = new ArrayList<>();public static void addObject(Object obj) {list.add(obj); // 对象被静态集合引用,无法回收}public static void main(String[] args) {while (true) {addObject(new Object()); // 持续添加对象,导致内存泄漏}}
}

90. 什么是Java的反射机制?有哪些常见应用场景?

答案
反射机制是指程序在运行时可以获取自身的信息(类、方法、字段等),并能动态操作这些信息的能力。通过java.lang.reflect包中的类(如ClassMethodField)实现。

原理
Java编译器将类编译为字节码(.class),运行时JVM加载类并生成Class对象,反射通过该对象访问类的结构。

应用场景

  • 框架开发(如Spring的IOC容器,通过反射实例化Bean);
  • 动态代理(如MyBatis的Mapper接口代理);
  • 注解解析(如JUnit的@Test注解检测)。

代码示例

public class ReflectionDemo {public static void main(String[] args) throws Exception {// 获取Class对象Class<?> clazz = User.class;// 实例化对象Object user = clazz.getDeclaredConstructor().newInstance();// 获取并设置字段Field nameField = clazz.getDeclaredField("name");nameField.setAccessible(true); // 访问私有字段nameField.set(user, "Alice");// 调用方法Method getNameMethod = clazz.getMethod("getName");String name = (String) getNameMethod.invoke(user);System.out.println(name); // 输出:Alice}
}class User {private String name;public String getName() { return name; }
}
No.大剑师精品GIS教程推荐
0地图渲染基础- 【WebGL 教程】 - 【Canvas 教程】 - 【SVG 教程】
1Openlayers 【入门教程】 - 【源代码+示例 300+】
2Leaflet 【入门教程】 - 【源代码+图文示例 150+】
3MapboxGL【入门教程】 - 【源代码+图文示例150+】
4Cesium 【入门教程】 - 【源代码+综合教程 200+】
5threejs【中文API】 - 【源代码+图文示例200+】

91. Java中的异常体系结构是怎样的?Checked ExceptionUnchecked Exception有何区别?

答案
异常体系结构

  • 顶层父类为Throwable,分为Error(错误,如OutOfMemoryError,程序无法处理)和Exception(异常,程序可处理)。
  • Exception分为RuntimeException(运行时异常,如NullPointerException)和非运行时异常(如IOException)。

区别

类型特点示例
Checked Exception编译时检查,必须捕获或声明抛出IOExceptionSQLException
Unchecked Exception运行时抛出,编译不检查,无需强制处理NullPointerExceptionIndexOutOfBoundsException

代码示例

// Checked Exception:必须处理(捕获或声明)
public void readFile() throws IOException { // 声明抛出FileReader fr = new FileReader("test.txt");fr.read();
}// Unchecked Exception:无需强制处理
public void divide(int a, int b) {if (b == 0) {throw new ArithmeticException("除数不能为0"); // 运行时抛出}
}

92. try-catch-finally中,如果finallyreturntrycatch中的return会生效吗?

答案
不会。finally块始终执行(除非JVM退出),若finally包含return,会覆盖trycatch中的return值。

代码示例

public static int test() {try {return 1;} catch (Exception e) {return 2;} finally {return 3; // 覆盖try的return}
}public static void main(String[] args) {System.out.println(test()); // 输出:3
}

原理
编译器会将try/catch中的return值暂存,执行finally后,若finallyreturn,则直接返回该值,丢弃暂存值。

93. 什么是线程安全?如何实现线程安全?

答案
线程安全:多线程环境下,多个线程访问共享资源时,无需额外同步操作即可保证结果正确。

实现方式

  1. 同步机制
    • synchronized关键字(修饰方法或代码块,保证原子性、可见性、有序性)。
    • Lock接口(如ReentrantLock,更灵活的锁控制)。
  2. 使用线程安全的类:如ConcurrentHashMapAtomicInteger
  3. 无状态设计:避免共享变量(如Servlet默认线程不安全,需通过无状态实现安全)。

代码示例(synchronized)

class Counter {private int count = 0;// 同步方法,保证线程安全public synchronized void increment() {count++;}public int getCount() { return count; }
}

94. synchronizedLock的区别是什么?

答案

特性synchronizedLock
实现方式JVM层面的隐式锁API层面的显式锁(需手动加锁/释放)
灵活性自动释放锁,无法中断等待线程可手动释放(unlock()),支持中断、超时获取锁
公平性非公平锁可指定公平锁(构造方法参数)
绑定条件不支持条件变量支持(Condition),可实现复杂等待/唤醒
性能JDK1.6后优化(偏向锁、轻量级锁),性能接近Lock性能更优(高并发下)

代码示例(Lock)

class LockCounter {private int count = 0;private Lock lock = new ReentrantLock(); // 显式锁public void increment() {lock.lock(); // 加锁try {count++;} finally {lock.unlock(); // 必须手动释放}}
}

95. 什么是死锁?如何避免死锁?

答案
死锁:两个或多个线程相互持有对方所需的资源,且都不释放,导致无限等待的状态。

产生条件

  • 互斥:资源不可共享;
  • 持有并等待:线程持有部分资源,等待其他资源;
  • 不可剥夺:资源不可被强制剥夺;
  • 循环等待:线程间形成资源等待循环。

避免方式

  1. 按固定顺序获取资源(打破循环等待);
  2. 限时获取资源(如tryLock(timeout));
  3. 减少锁的持有时间。

死锁示例

// 线程1持有lock1,等待lock2;线程2持有lock2,等待lock1 → 死锁
Object lock1 = new Object();
Object lock2 = new Object();new Thread(() -> {synchronized (lock1) {try { Thread.sleep(100); } catch (InterruptedException e) {}synchronized (lock2) { System.out.println("线程1获取lock2"); }}
}).start();new Thread(() -> {synchronized (lock2) {try { Thread.sleep(100); } catch (InterruptedException e) {}synchronized (lock1) { System.out.println("线程2获取lock1"); }}
}).start();

96. Java中的线程池有哪些核心参数?ThreadPoolExecutor的工作原理是什么?

答案
ThreadPoolExecutor核心参数

  1. corePoolSize:核心线程数(始终存活,除非设置allowCoreThreadTimeOut)。
  2. maximumPoolSize:最大线程数(核心线程+临时线程)。
  3. keepAliveTime:临时线程空闲超时时间。
  4. workQueue:任务等待队列(如LinkedBlockingQueue)。
  5. threadFactory:线程创建工厂。
  6. handler:拒绝策略(如AbortPolicy:直接抛出异常)。

工作原理

  1. 提交任务时,若核心线程未满,创建核心线程执行任务;
  2. 核心线程满,任务加入等待队列;
  3. 队列满,若未达最大线程数,创建临时线程执行;
  4. 超过最大线程数,触发拒绝策略。

代码示例

ThreadPoolExecutor executor = new ThreadPoolExecutor(2, // 核心线程数5, // 最大线程数60L, TimeUnit.SECONDS, // 临时线程超时时间new LinkedBlockingQueue<>(3), // 等待队列Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy() // 拒绝策略
);

97. Java中的volatile关键字有什么作用?它能保证原子性吗?

答案
作用

  1. 可见性:一个线程修改volatile变量后,其他线程能立即看到最新值(禁止CPU缓存)。
  2. 有序性:禁止指令重排序(通过内存屏障实现)。

不能保证原子性:例如i++操作(读取→修改→写入),多线程下可能出现丢失更新。

代码示例(可见性)

class Flag {volatile boolean stop = false; // 保证可见性public void run() {while (!stop) {// 循环执行,直到stop被修改为true}}
}

原子性问题示例

class VolatileTest {volatile int count = 0;public void increment() {count++; // 非原子操作,多线程下结果可能不正确}
}

98. 什么是Java内存模型(JMM)?它解决了什么问题?

答案
Java内存模型(JMM):是一种抽象模型,定义了线程和主内存之间的交互规则,解决多线程环境下的可见性、原子性、有序性问题。

核心问题及解决

  • 可见性:线程对共享变量的修改需立即同步到主内存,其他线程从主内存读取(通过volatilesynchronized实现)。
  • 原子性:保证操作不可分割(通过synchronizedLock、原子类实现)。
  • 有序性:禁止指令重排序(通过volatilesynchronizedhappens-before规则)。

JMM抽象结构

  • 线程操作本地内存(CPU缓存),通过主内存交换共享变量。

99. ArrayListLinkedList的区别是什么?各自的适用场景?

答案

特性ArrayListLinkedList
数据结构动态数组(连续内存)双向链表(非连续内存)
随机访问快(O(1)),通过索引直接访问慢(O(n)),需遍历链表
增删操作(中间)慢(O(n),需移动元素)快(O(1),只需修改指针)
内存占用较少(仅存储元素)较多(需存储前后指针)

适用场景

  • ArrayList:频繁随机访问、少量增删(尾部)。
  • LinkedList:频繁增删(中间)、不频繁随机访问。

代码示例

List<String> arrayList = new ArrayList<>();
arrayList.add("A"); // 尾部添加快
arrayList.get(0); // 随机访问快List<String> linkedList = new LinkedList<>();
linkedList.add(1, "B"); // 中间插入快
linkedList.remove(0); // 头部删除快

100. HashMap的底层实现原理是什么?JDK1.7和JDK1.8有何区别?

答案
底层原理:基于数组+链表/红黑树实现,通过哈希函数计算键的索引,存储键值对。

JDK1.7 vs JDK1.8区别

特性JDK1.7JDK1.8
数据结构数组+链表数组+链表+红黑树(链表长度>8时转为树)
哈希冲突解决头插法(可能导致死锁)尾插法(避免死锁)
扩容机制需重新计算哈希值高低位拆分(减少哈希计算)
存储结构Entry<K,V> 数组Node<K,V> 数组(实现Entry接口)
红黑树优化有(提升查询效率,O(logn)

代码示例(HashMap使用)

HashMap<String, Integer> map = new HashMap<>();
map.put("a", 1);
map.put("b", 2);
int value = map.get("a"); // 获取值

二、120道面试题目录列表

文章序号Java面试题120道
1Java面试题及详细答案120道(01-20)
2Java面试题及详细答案120道(21-40)
3Java面试题及详细答案120道(41-60)
4Java面试题及详细答案120道(61-80)
5Java面试题及详细答案120道(81-100)
6Java面试题及详细答案120道(5101-120)
http://www.xdnf.cn/news/16524.html

相关文章:

  • 电商项目_核心业务_数据归档
  • 计算机网络:(十二)传输层(上)运输层协议概述
  • 【测试报告】玄机抽奖系统(Java+Selenium+Jmeter自动化测试)
  • KNN 算法中的各种距离:从原理到应用
  • PandasAI连接LLM进行智能数据分析
  • Tkinter美化 - 告别土味Python GUI
  • 医疗AI语义潜空间分析研究:进展与应用
  • 2507C++,APC可以干的活
  • 第二阶段-第二章—8天Python从入门到精通【itheima】-138节(MySQL的综合案例)
  • 记录一次薛定谔bug
  • SpringAI入门及浅实践,实战 Spring‎ AI 调用大模型、提示词工程、对话记忆、Adv‎isor 的使用
  • goland编写go语言导入自定义包出现: package xxx is not in GOROOT (/xxx/xxx) 的解决方案
  • red靶机
  • zabbix-agent静默安装
  • AI编程自动化与算法优化实践指南
  • Oracle 19C RU 19.28 升级和安装
  • Spring Cloud 详解与搭建全攻略
  • MySQL的底层原理--InnoDB数据页结构
  • Java实现大根堆与小根堆详解
  • 53. 最大子数组和
  • 在 Windows 系统中实现 WinToGo 的 VHDX 文件切换使用的常见方法
  • 9.3 快速傅里叶变换
  • Cortex-M内核SysTick定时器介绍
  • [2025CVPR-图象合成、生成方向]ODA-GAN:由弱监督学习辅助的正交解耦比对GAN 虚拟免疫组织化学染色
  • 【Keepalived】高可用集群
  • 香港本地和国际金融科技应用
  • Javaweb————HTTP的九种请求方法介绍
  • RoPE:相对位置编码的旋转革命——原理、演进与大模型应用全景
  • 【micro:bit】从入门到放弃(六):示例蜂鸣器音乐、摇色子、光照强度、串口调试、麦克风
  • mac版SVN客户端