Java面试50问,女面试官最喜欢问的居然是它!

简介: Java面试50问,女面试官最喜欢问的居然是它!

[] 什么是死锁?

死锁(Deadlock)是多线程编程中的一种情况,当两个或多个线程在执行过程中,因争夺资源而造成的一种僵局。当发生死锁时,因为线程都在等待其他线程释放资源,但没有一个线程能够继续执行,导致程序无法继续运行。

死锁通常由以下四个必要条件同时发生而引起:

1. 互斥条件:每个线程至少持有一个排他资源,即其他线程无法访问该资源。

2. 占有和等待条件:线程至少各自占有一个资源,并且等待获取其他线程所占有的资源。

3. 不可抢占条件:线程所占有的资源只能由该线程自愿释放,其他线程无法强行夺取。

4. 循环等待条件:存在一个线程等待队列,使得每个线程都在等待下一个线程所占有的资源。

当这四个条件同时满足时,就可能发生死锁。

死锁的解决策略:

1. 避免死锁:通过改变程序逻辑,打破上述死锁的四个条件之一,可以避免死锁的发生。

2. 检测死锁:在系统运行时,通过算法检测死锁的发生,并采取相应措施。

3. 预防死锁:通过资源分配策略的设计,避免死锁条件的出现。

4. 解除死锁:当检测到死锁时,通过终止线程或回滚事务等手段,强制解除死锁。

避免死锁的常见方法:

- 资源一次性分配:确保线程能够一次性请求所有需要的资源,从而避免线程在运行过程中因等待资源而陷入僵局。

- 按顺序分配资源:为系统中的所有资源分配一个唯一的顺序,并要求每个线程按照固定的顺序请求资源。

- 使用锁超时机制:在请求资源时设置超时时间,如果超时则释放已占有的资源,并重新尝试。

- 使用死锁检测工具:利用操作系统或Java平台提供的工具检测死锁。

在Java中,可以使用多种同步机制来避免死锁,如使用Lock接口和显式锁,或者使用java.util.concurrent包中的线程安全数据结构。合理设计资源的分配和锁定机制,可以有效降低死锁发生的风险。

[] 什么是线程池?

线程池是一种执行器(Executor),用于在一个后台线程中执行任务。线程池的主要目的是减少在创建和销毁线程时所产生的性能开销。通过重用已经创建的线程来执行新的任务,线程池提高了程序的响应速度,并且提供了更好的系统资源管理。

线程池的核心组件和概念包括:

1. 线程池管理器:负责创建、管理线程,以及分配任务到线程。

2. 工作线程:线程池中的线程,用于执行任务。

3. 任务队列:用于存放待执行的任务,通常是一个阻塞队列(BlockingQueue)。

4. 线程工厂:用于创建新线程,可以自定义线程参数,如线程名称、线程优先级等。

5. 拒绝策略:当任务太多,无法被线程池及时处理时,采取的策略。Java提供了四种拒绝策略:

 - AbortPolicy:抛出RuntimeException。

 - CallerRunsPolicy:调用者所在的线程执行任务。

 - DiscardPolicy:默默地丢弃无法处理的任务。

 - DiscardOldestPolicy:丢弃队列最前面的任务,并尝试再次提交任务。

线程池的主要参数包括:

- 核心线程数(corePoolSize):线程池中始终保持的线程数量,即使它们处于空闲状态。

- 最大线程数(maximumPoolSize):线程池中允许的最大线程数量。

- 工作队列(workQueue):用于存放待执行任务的阻塞队列。

- 线程存活时间(keepAliveTime):非核心线程空闲时在终止前等待新任务的最长时间。

- 时间单位(unit):与线程存活时间相关的时间单位。

- 线程工厂(threadFactory):用于创建新线程的工厂。

- 拒绝策略(handler):当任务太多时,无法处理额外任务时使用的策略。

在Java中,线程池可以通过java.util.concurrent包中的ThreadPoolExecutor类或Executors类来创建和管理。

使用线程池的好处包括:

- 资源复用:线程池的线程可以在执行完一个任务后,再从队列中获取另一个任务,从而提高线程的利用率。

- 控制最大并发数:线程池可以控制最大的线程数量,避免因大量线程竞争资源导致系统过载。

- 提高响应速度:线程池中的线程是时刻待命的,可以快速响应任务的请求。

- 提高线程的可管理性:线程池提供了线程的创建、管理、调优、监控等能力。

正确配置和管理线程池对于确保应用程序的性能和稳定性至关重要。

相关文章
|
29天前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
67 2
|
18天前
|
Java 程序员
Java社招面试题:& 和 && 的区别,HR的套路险些让我翻车!
小米,29岁程序员,分享了一次面试经历,详细解析了Java中&和&&的区别及应用场景,展示了扎实的基础知识和良好的应变能力,最终成功获得Offer。
48 14
|
28天前
|
存储 缓存 算法
面试官:单核 CPU 支持 Java 多线程吗?为什么?被问懵了!
本文介绍了多线程环境下的几个关键概念,包括时间片、超线程、上下文切换及其影响因素,以及线程调度的两种方式——抢占式调度和协同式调度。文章还讨论了减少上下文切换次数以提高多线程程序效率的方法,如无锁并发编程、使用CAS算法等,并提出了合理的线程数量配置策略,以平衡CPU利用率和线程切换开销。
面试官:单核 CPU 支持 Java 多线程吗?为什么?被问懵了!
|
1月前
|
存储 算法 Java
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
本文详解自旋锁的概念、优缺点、使用场景及Java实现。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
|
1月前
|
存储 缓存 Oracle
Java I/O流面试之道
NIO的出现在于提高IO的速度,它相比传统的输入/输出流速度更快。NIO通过管道Channel和缓冲器Buffer来处理数据,可以把管道当成一个矿藏,缓冲器就是矿藏里的卡车。程序通过管道里的缓冲器进行数据交互,而不直接处理数据。程序要么从缓冲器获取数据,要么输入数据到缓冲器。
Java I/O流面试之道
|
23天前
|
Java 编译器 程序员
Java面试高频题:用最优解法算出2乘以8!
本文探讨了面试中一个看似简单的数学问题——如何高效计算2×8。从直接使用乘法、位运算优化、编译器优化、加法实现到大整数场景下的处理,全面解析了不同方法的原理和适用场景,帮助读者深入理解计算效率优化的重要性。
28 6
|
1月前
|
存储 缓存 Java
大厂面试必看!Java基本数据类型和包装类的那些坑
本文介绍了Java中的基本数据类型和包装类,包括整数类型、浮点数类型、字符类型和布尔类型。详细讲解了每种类型的特性和应用场景,并探讨了包装类的引入原因、装箱与拆箱机制以及缓存机制。最后总结了面试中常见的相关考点,帮助读者更好地理解和应对面试中的问题。
54 4
|
1月前
|
存储 Java 程序员
Java基础的灵魂——Object类方法详解(社招面试不踩坑)
本文介绍了Java中`Object`类的几个重要方法,包括`toString`、`equals`、`hashCode`、`finalize`、`clone`、`getClass`、`notify`和`wait`。这些方法是面试中的常考点,掌握它们有助于理解Java对象的行为和实现多线程编程。作者通过具体示例和应用场景,详细解析了每个方法的作用和重写技巧,帮助读者更好地应对面试和技术开发。
106 4
|
1月前
|
算法 Java
JAVA 二叉树面试题
JAVA 二叉树面试题
18 0
|
SQL 缓存 安全
Java高频面试题目
面试时面试官最常问的问题总结归纳!
148 0