猿辅导Java面试真实经历与深度总结(二)

作者:360_go_php日期:2025/10/22

在面试中,掌握Java的基础知识和深入的理解是非常重要的。今天,我们来解析几个常见的Java面试问题,包括线程状态、线程池、深拷贝与浅拷贝、线程安全、Lock与Synchronized的区别,以及逃逸分析等话题。


1. 线程状态

Java中,线程有七种状态,它们是由 Thread.State 枚举类定义的。线程的状态随着程序的执行而发生变化,下面是七种状态的描述:​编辑

  • NEW:线程被创建,但尚未启动。
  • RUNNABLE:线程可以运行,或者已经正在运行。线程调度器选择合适的线程让它执行。
  • BLOCKED:线程被阻塞,等待获得锁。
  • WAITING:线程进入无限期等待,直到其他线程唤醒它。常见的场景包括 Object.wait()Thread.join()LockSupport.park()
  • TIMED_WAITING:线程在等待指定的时间后自动恢复,如 Thread.sleep(1000)Object.wait(1000)
  • TERMINATED:线程执行完毕,或者因为异常等原因终止。

线程的状态转换过程是由JVM线程调度器来控制的,线程从一个状态到另一个状态的转换通常是由应用程序逻辑和操作系统调度来完成的。


2. 线程池​编辑

线程池ExecutorService)是一种用于管理和复用线程的技术。它可以有效地避免频繁创建和销毁线程所带来的性能损失。线程池可以通过以下方式提高程序的性能和资源利用率:

  • 核心池大小:线程池中保持活动的线程数,默认情况下,Executors.newFixedThreadPool() 方法创建的是一个固定大小的线程池。
  • 最大池大小:线程池可以容纳的最大线程数。​编辑
  • 任务队列:线程池内部有一个队列,用于存储等待执行的任务。常见的队列有无界队列、有界队列等。
  • 线程池的生命周期:线程池有不同的状态,如RUNNINGSHUTDOWNSTOP等,表示线程池是否正在工作或是否已经关闭。

使用线程池的一个重要好处是可以管理系统中线程的最大数量,防止过多的线程导致系统资源过度消耗。

示例代码:

1import java.util.concurrent.*;
2
3public class ThreadPoolExample {  
4    public static void main(String[] args) {  
5        ExecutorService executor = Executors.newFixedThreadPool(3);
6
7        for (int i = 0; i < 5; i++) {  
8            executor.submit(() -> {  
9                System.out.println(Thread.currentThread().getName() + " is working");  
10            });  
11        }
12
13        executor.shutdown();  
14    }  
15}  
16

3. 深拷贝,浅拷贝​编辑

  • 浅拷贝 (Shallow Copy):复制对象的引用,而不是复制对象本身。如果原对象包含引用类型的字段,浅拷贝会复制这些字段的引用,而不是创建新的对象实例。这样,原对象和拷贝对象会共享同一个内部对象。​编辑

浅拷贝示例
```java
class Person {
String name;
int age;
Person(String name, int age) {
this.name = name;
this.age = age;
}
}

public class ShallowCopy {
public static void main(String[] args) {
Person p1 = new Person("Alice", 30);
Person p2 = p1; // 浅拷贝
p2.name = "Bob"; // 修改p2的name
System.out.println(p1.name); // 输出"Bob"
}
}
```

  • 深拷贝 (Deep Copy):完全复制对象以及对象中引用的所有对象。深拷贝会创建对象及其引用的对象的独立副本,因此原对象和拷贝对象之间没有任何共享部分。

深拷贝示例
```java
class Person {
String name;
int age;
Person(String name, int age) {
this.name = name;
this.age = age;
}
public Person(Person other) {
this.name = other.name;
this.age = other.age;
}
}

public class DeepCopy {
public static void main(String[] args) {
Person p1 = new Person("Alice", 30);
Person p2 = new Person(p1); // 深拷贝
p2.name = "Bob"; // 修改p2的name
System.out.println(p1.name); // 输出"Alice"
}
}
```


4. 线程安全

线程安全是指在多线程环境中,多个线程对同一个共享资源进行操作时,不会发生竞态条件(race conditions),也就是说,程序的行为是可预测的,且不会出现数据错误或异常。

  • 常见的线程安全解决方案包括:
    - 同步方法:通过 synchronized 关键字对共享资源进行同步,保证同一时刻只有一个线程访问。
    - 并发集合:如 ConcurrentHashMap,它采用分段锁的机制提高并发度。
    - 原子变量:通过 AtomicInteger 等类提供原子操作,避免使用锁。
    - ReentrantLock:通过显示锁来控制资源的并发访问。

5. Lock和Synchronized的区别

  • Synchronized
    - 是Java的内置关键字,简单易用。
    - 自动释放锁,不需要显式地调用 unlock()
    - 每个对象都有一个锁,保证同一时刻只有一个线程可以访问同步方法或代码块。
    - 不支持公平性,可能会出现线程饥饿。
  • Lock
    - 是java.util.concurrent.locks包中的接口,需要手动加锁和解锁。
    - 支持更灵活的锁机制,比如公平锁、非公平锁。
    - 可中断的锁,通过 lockInterruptibly() 可以响应中断。
    - 可以在不同的作用域内持有锁,提供了更多的操作灵活性。

示例代码:

1import java.util.concurrent.locks.Lock;  
2import java.util.concurrent.locks.ReentrantLock;
3
4public class LockExample {  
5    private static Lock lock = new ReentrantLock();
6
7    public static void main(String[] args) {  
8        lock.lock();  // 显式加锁  
9        try {  
10            // 线程安全的代码块  
11        } finally {  
12            lock.unlock();  // 释放锁  
13        }  
14    }  
15}  
16

6. 逃逸分析​编辑

逃逸分析是Java虚拟机的一种优化技术,用于判断对象的引用是否会“逃逸”到方法外部。通过逃逸分析,JVM能够确定哪些对象可以在栈上分配,从而避免堆上的内存分配,并减少GC的负担。

  • 栈上分配:如果对象在方法内部没有逃逸,它就可以被分配到栈上,而不是堆上。这样可以减少垃圾回收的压力,因为栈上的对象在方法调用结束后会自动销毁。
  • 同步消除:如果通过逃逸分析确定某个对象在多线程环境中不会被共享,就可以消除不必要的同步操作,提升性能。​编辑

总结

以上就是关于线程状态、线程池、深拷贝和浅拷贝、线程安全、Lock与Synchronized的区别以及逃逸分析的简要解析。理解这些概念不仅能够帮助你应对Java面试中的常见问题,还能让更好地掌握并发编程和性能优化的技巧。


猿辅导Java面试真实经历与深度总结(二)》 是转载文章,点击查看原文


相关推荐


Docker 通信核心:docker.sock 完全指南
做运维的阿瑞2025/10/20

阅读时长: 15min | 难度: 中级 | 作者: 做运维的阿瑞 | 更新时间: 2025-10 文章目录 前言一、Docker 通信原理总览1.1 技术架构解析1.2 核心技术对比 二、核心用法与技巧2.1 容器内访问宿主机 Docker2.2 使用 Docker SDK2.3 直接与 API 交互 三、安全风险与最佳实践Q1: 有多危险?为什么说拿到 `docker.sock` 就等于 `root`?Q2: 如何安全地授权用户使用 Docker?Q3: 有没有比挂


自定义Spring Boot Starter项目并且在其他项目中通过pom引入使用
劝导小子2025/10/19

1、创建starter项目 我电脑只有JDK 8,但是创建项目的时候最低只能选择17,后续创建完后去修改即可 2、项目结构 删除主启动类Application:Starter不需要启动类删除配置文件application.properties:Starter不需要自己的配置文件删除test里面的测试启动类 在resources下创建META-INF文件夹 3、修改JDK 修改成JDK8,如果你有更高的版本请切换 4、配置pom.xml <?xml version="1


RabbitMQ消息传输中Protostuff序列化数据异常的深度解析与解决方案
Mr.45672025/10/18

目录 问题背景 环境配置 使用的依赖 测试对象 初始代码(有问题的版本) 问题分析 1. 初步排查 2. 关键发现 3. RabbitTemplate的默认行为分析 4. SimpleMessageConverter的处理机制 深入理解消息转换 消息转换器的层次结构: 而直接发送 Message: 解决方案 方案1:直接使用Message对象(推荐) 方案2:配置自定义MessageConverter 问题根因总结 经验教训 结论 最后最后附上序列化工具:


Apache Doris 与 ClickHouse:运维与开源闭源对比
SelectDB技术团队2025/10/16

引言 在当今数据驱动的商业环境中,OLAP(在线分析处理)数据库的选择对企业的数据分析能力和运维成本有着深远影响。Apache Doris 和 ClickHouse 作为业界领先的高性能 OLAP 数据库,各自在不同场景下展现出独特优势。 Apache Doris 以其优秀的宽表查询能力、多表 JOIN 性能、实时更新、search 以及湖加速特性而著称。ClickHouse 同样在宽表处理方面表现出色,其丰富的分析函数库和高性能单表聚合能力备受青睐。 然而,从运维角度来看,两者在存算分离


统一高效图像生成与编辑!百度&新加坡国立提出Query-Kontext,多项任务“反杀”专用模型
AI生成未来2025/10/15

论文链接:https://arxiv.org/pdf/2509.26641 亮点直击 Query-Kontext,一种经济型集成多模态模型(UMM),能够将视觉语言模型(VLMs)中的多模态生成推理与扩散模型执行的高保真视觉渲染相分离。 提出了一种三阶段渐进式训练策略,该策略逐步将 VLM 与越来越强大的扩散生成器对齐,同时增强它们在生成推理和视觉合成方面的各自优势。 提出了一种精心策划的数据集收集方案,以收集真实、合成和经过仔细筛选的开源数据集,涵盖多样的多模态参考到图像


微美全息(NASDAQ:WIMI)融合区块链+AI+IoT 三大技术,解锁物联网入侵检测新范式
爱看科技2025/10/14

在全面数字化转型的浪潮中,区块链、网络安全、人工智能与机器学习不再是孤立的技术概念,而是相互交织、共同推动行业进步的强大引擎。这些技术的紧密结合,特别是在物联网(IoT)领域的应用,正引领着一场前所未有的安全、效率与智能化变革。   实际,区块链技术以其去中心化、安全性和不可篡改性,为物联网数据存储和共享提供了全新的解决方案。而人工智能与机器学习技术的应用,使得物联网系统具备了自我学习和优化的能力。机器学习算法能够分析海量数据,识别出潜在的安全威胁或性能瓶颈,为系统提供精准的决策支持。


基于旗鱼算法优化卷积神经网络结合长短期记忆网络与注意力机制(CNN-LSTM-Attention)的风电场发电功率预测
智能算法研学社(Jack旭)2025/10/12

基于旗鱼算法优化卷积神经网络结合长短期记忆网络与注意力机制(CNN-LSTM-Attention)的风电场发电功率预测 文章目录 基于旗鱼算法优化卷积神经网络结合长短期记忆网络与注意力机制(CNN-LSTM-Attention)的风电场发电功率预测1.CNN原理2.LSTM原理3.注意力机制4.CNN-LSTM-Attention5.风电功率预测5.1 数据集6.基于旗鱼算法优化的CNN-LSTM-Attention7.实验结果8.Matlab代码 1.CNN原理 卷积神经


C++ const 用法全面总结与深度解析
oioihoii2025/10/10

1. const 基础概念 const 关键字用于定义不可修改的常量,是C++中确保数据只读性和程序安全性的核心机制。它可以应用于变量、指针、函数参数、返回值、成员函数等多种场景,深刻影响代码的正确性和性能。 1.1 本质与编译期处理 const变量在编译时会被编译器严格检查,任何修改尝试都会导致编译错误。与C语言不同,C++中的const变量(尤其是全局const)通常不会分配内存,而是直接嵌入到指令中(类似#define),但在以下情况会分配内存: 取const变量地址时 const变量为


php artisan db:seed执行的时候遇到报错
快支棱起来2025/10/9

INFO Seeding database. Illuminate\Database\QueryException SQLSTATE[42S22]: Column not found: 1054 Unknown column 'email_verified_at' in 'field list' (Connection: mysql, SQL: insert into users (name, email, email_verified_at, password, remember_token,


apache POI 万字总结:满足你对报表一切幻想
大鱼七成饱2025/10/7

背景 国庆期间接了个兼职,处理机构的几张Excel报表。初次沟通,感觉挺简单,接入Easyexcel(FastExcel),然后拼lamda表达式就跑出来了。不过毕竟工作了这些年,感觉没这么简单。后面找业务方详细聊了一次,将需求落到纸面上。逐行研究了下BRD,有点挠头,跑数加各种样式,兼容新老版本,老方案是不行了。综合对比,最终选了老牌的 Apache POI 实现,下面说下为啥选POI,还有POI怎么用,包含样式、公式、动态表头、安全防范、百万级数据导入导出等功能。 一、技术选型 如果实现该

首页编辑器站点地图

Copyright © 2025 聚合阅读

License: CC BY-SA 4.0