15 个多线程和并发面试题

简介:

多线程和并发问题已成为各种 Java 面试中必不可少的一部分。如果你准备参加投行的 Java 开发岗位面试,比如巴克莱银行(Barclays)、花旗银行(Citibank)、摩根史坦利投资公司(Morgan Stanley),你会遇到很多有关多线程的面试题。多线程和并发是投行面试的热门知识点,尤其是在面试有关电子交易开发工作时,他们喜欢用棘手的 Java 线程面试题轰炸面试者。他们希望确保面试者对 Java 多线程和并发有扎实的知识基础,因为他们大多数关注高性能带来的竞争优势。

举个例子,直接市场准入模式(Direct to Market,DMA)使用高容量低延迟的电子交易系统,通常来说是并发的。大多数时间他们致力于微秒级的延迟,所以掌握如何有效地降低延迟、提高吞吐量非常重要。

有一些 Java 线程面试题是我特别中意的。我并不会直接给你答案,而是尽可能给你指点。我会之后补充上详细答案,正如我在其他文章中那样。

JDK 1.5 中引入并发包之后,并发工具和并发集合备受欢迎,比如 ThreadLocal、 BlockingQueue、Counting Semaphore 和 ConcurrentHashMap,与这些工具相关的面试题也越来越多。

Java 8 和 Java 9 也是这种情况。围绕 lambda 表达式、并行流(parallel streams)、新的 Fork/Join 线程池、CompletableFuture 的问题在 2018 年不断涌现,2019 年还将持续。今后你也应该对这些知识点有所准备。

15 个 Java 线程面试题和答案

总之不要考虑那么多,下面是各种投行,比如巴克莱银行(Barclays)、花旗银行(Citibank)、摩根史坦利投资公司(Morgan Stanley)等等,面试 Java 开发者时常问的 Java 多线程和并发问题。

1. 现在有线程 T1、T2 和 T3。你如何确保 T2 线程在 T1 之后执行,并且 T3 线程在 T2 之后执行?

这个线程面试题通常在第一轮面试或电话面试时被问到,这道多线程问题为了测试面试者是否熟悉 join 方法的概念。答案也非常简单——可以用 Thread 类的 join 方法实现这一效果。

2. Java 中新的 Lock 接口相对于同步代码块(synchronized block)有什么优势?如果让你实现一个高性能缓存,支持并发读取和单一写入,你如何保证数据完整性。

多线程和并发编程中使用 lock 接口的最大优势是它为读和写提供两个单独的锁,可以让你构建高性能数据结构,比如 ConcurrentHashMap 和条件阻塞。

这道 Java 线程面试题越来越多见,而且随后的面试题都基于面试者对这道题的回答。

我强烈建议在任何 Java 多线程面试前都要多看看有关锁的知识,因为如今电子交易系统的客户端和数据交互中,锁被频繁使用来构建缓存。

3. Java 中 wait 和 sleep 方法有什么区别?

我们来看看另一个经常被问到的线程面试题。这道题常出现在电话面试中。两者主要的区别就是等待释放锁和监视器。sleep方法在等待时不会释放任何锁或监视器。wait 方法多用于线程间通信,而 sleep 只是在执行时暂停。

1db04efaaacd1a648864057af891411f6495a196

4. 如何在 Java 中实现一个阻塞队列?

这是一道相对困难的 Java 多线程面试题,考察点很多。它考察了面试者是否真正写过 Java 多线程代码,考察了面试者对并发场景的理解。并且可以根据面试者的代码问很多后续问题,如果他用 wait() 和 notify() 方法成功实现了阻塞队列,可以让他用 Java 5 的并发类重新实现一次。

5. 如何在 Java 中编写代码解决生产者消费者问题?

和上面有关线程的问题相似,这个问题在工作中很典型,但有时面试官会问这类问题,比如“在 Java 中如何解决生产者消费者问题?”其实,有很多解决方式。我分享过用 Java 中 BlockingQueue 的解决方案。有时他们甚至会让你给出哲学家进餐问题的解决方案。

6. 写一段死锁代码。你在 Java 中如何解决死锁?

这是我最喜欢的 Java 多线程面试题,因为即使死锁在多线程并发编程中十分常见,许多面试者仍然抓耳挠腮,不能写出无死锁的代码。

只需要问他们如果有 N 个资源和 N 个线程去执行某个操作,然后请求所有资源。

这里的 N 可以是 2 作为最简单的情况,也可以是个很大的数字让问题变复杂。

b2c949cbdcf673aa8efc162ba2b257a719a6d4b1

7. 什么是原子操作?Java 中有哪些原子操作?

这是个简单的 Java 线程面试题。另一个紧随其后的问题将是:你需要同步原子操作吗?

8. Java 中 volatile 关键字是什么?你如何使用它?它和 Java 中的同步方法有什么区别?

自从 Java 5 中调整 volatile 关键字和 Java 内存模型后,有关 volatile 关键字的线程问题越来越常见。掌握 volatile变量在并发环境中如何确保可见性、有序性和一致性非常重要。

9. 什么是竞态条件?你如何发现并解决竞态条件?

这个 Java 多线程问题一般出现在高级面试。多数面试官会问你最近一次遇到的竞态条件,如何解决的,有时他们也会写点简单代码让你发现竞态条件。可以看看我的这篇文章Java 中的竞态条件。我认为,这是最棒的 Java 线程面试问题之一,而且可以测试出面试者解决竞态条件的经验,或是编写无数据竞争、无其竞态条件的代码经验。

10. 在 Java 中你如何转储线程(thread dump)?如何分析它?

在 UNIX 中,你可以使用 kill -3 然后线程转储日志会打印在屏幕上,可以使用 CTRL+Break 查看。这只是一个较简单的线程面试题,狡猾一点的话他们会问你如何分析转储日志。线程转储日志对于分析死锁情况非常有用。

11. 既然 start() 方法会调用 run() 方法,为什么我们调用 start() 方法,而不直接调用 run() 方法?

这是一个基本的 Java 多线程面试题。最初,我刚开始多线程编程时对此还有些困惑。如今我一般在 Java 中级面试的电话面试或一轮面试中遇到。

这道问题的答案是这样的。当你调用 start() 方法时,它会新建一个线程然后执行 run() 方法中的代码。如果直接调用 run() 方法,并不会创建新线程,方法中的代码会在当前调用者的线程中执行。

1bf0303c6ac1b2e2ae36e0889efa6b8e05b470aa

12. Java 中你如何唤醒阻塞线程?

这是有关线程的一个很狡猾的问题。有很多原因会导致阻塞,如果是 IO 阻塞,我认为没有方式可以中断线程(如果有的话请告诉我)。另一方面,如果线程阻塞是由于调用了 wait(),sleep() 或 join() 方法,你可以中断线程,通过抛出 InterruptedException 异常来唤醒该线程。

13. Java 中 CyclicBarriar 和 CountdownLatch 有什么区别?

最近的 Java 线程面试题多数在测试你对 JDK 5 并发包的掌握程度。两者区别之一就是 CyclicBarrier 在屏障打开之后(所有线程到达屏障点),可以重复使用。而 CountDownLatch 不行。

14. 什么是不可变类?它对于编写并发应用有何帮助?

尽管这道面试题和线程没有直接关系,但间接影响也很大。

15. 你在多线程环境中遇到的最多的问题是什么?你如何解决的?

内存干扰、竞态条件、死锁、活锁、线程饥饿是多线程和并发编程中比较有代表性的问题。这类问题无休无止,而且难于定位和调试。

上面所说的是我喜欢的,也是投行最常问的 Java 线程面试题。这个清单并不完整,所以可以在下方评论出你在面试中遇到的有意思的 Java 线程题目。这篇文章收集并分享与多线程概念有关的面试题,不仅仅有助于面试,还为大家打开多线程概念的大门。

有位读者提供了一些 Java 线程面试题。补充在下面:

  1. Java 中绿色线程和本地线程的区别?

  2. 线程和进程的区别?

  3. 多线程的上下文切换是什么?

  4. 死锁和活锁的区别?死锁和饥饿的区别?

  5. Java 中使用什么线程调度算法?

  6. Java 中线程调度是什么?

  7. 线程中如何处理某个未处理异常?

  8. 什么是线程组?为什么 Java 中不建议使用线程组?

  9. 为什么使用 Executor 框架比直接创建线程要好?

  10. Java 中 Executor 和 Executors 的区别?

  11. 在 windows 和 linux 系统上分别如何找到占用 CPU 最多的线程?


原文发布时间为:2018-10-28
本文作者:全栈开发者社区
本文来自云栖社区合作伙伴“ 全栈开发者社区”,了解相关信息可以关注“ 全栈开发者社区”。

相关文章
|
25天前
|
Java 程序员
java线程池讲解面试
java线程池讲解面试
43 1
|
1月前
|
安全 Java
Qt经典面试题:Qt开启线程的几种方式
Qt经典面试题:Qt开启线程的几种方式
22 0
|
1月前
|
安全 数据库连接 数据库
连接池的并发和线程安全
连接池的并发和线程安全
|
4天前
|
安全 Java
深入理解 Java 多线程和并发工具类
【4月更文挑战第19天】本文探讨了Java多线程和并发工具类在实现高性能应用程序中的关键作用。通过继承`Thread`或实现`Runnable`创建线程,利用`Executors`管理线程池,以及使用`Semaphore`、`CountDownLatch`和`CyclicBarrier`进行线程同步。保证线程安全、实现线程协作和性能调优(如设置线程池大小、避免不必要同步)是重要环节。理解并恰当运用这些工具能提升程序效率和可靠性。
|
5天前
|
调度 Python
Python多线程、多进程与协程面试题解析
【4月更文挑战第14天】Python并发编程涉及多线程、多进程和协程。面试中,对这些概念的理解和应用是评估候选人的重要标准。本文介绍了它们的基础知识、常见问题和应对策略。多线程在同一进程中并发执行,多进程通过进程间通信实现并发,协程则使用`asyncio`进行轻量级线程控制。面试常遇到的问题包括并发并行混淆、GIL影响多线程性能、进程间通信不当和协程异步IO理解不清。要掌握并发模型,需明确其适用场景,理解GIL、进程间通信和协程调度机制。
22 0
|
6天前
|
Java 开发者
Java中多线程并发控制的实现与优化
【4月更文挑战第17天】 在现代软件开发中,多线程编程已成为提升应用性能和响应能力的关键手段。特别是在Java语言中,由于其平台无关性和强大的运行时环境,多线程技术的应用尤为广泛。本文将深入探讨Java多线程的并发控制机制,包括基本的同步方法、死锁问题以及高级并发工具如java.util.concurrent包的使用。通过分析多线程环境下的竞态条件、资源争夺和线程协调问题,我们提出了一系列实现和优化策略,旨在帮助开发者构建更加健壮、高效的多线程应用。
6 0
|
9天前
|
Java API 调度
安卓多线程和并发处理:提高应用效率
【4月更文挑战第13天】本文探讨了安卓应用中多线程和并发处理的优化方法,包括使用Thread、AsyncTask、Loader、IntentService、JobScheduler、WorkManager以及线程池。此外,还介绍了RxJava和Kotlin协程作为异步编程工具。理解并恰当运用这些技术能提升应用效率,避免UI卡顿,确保良好用户体验。随着安卓技术发展,更高级的异步处理工具将助力开发者构建高性能应用。
|
22天前
|
安全 Java
Java中的多线程并发控制
在Java中,多线程是实现并发执行任务的一种重要方式。然而,随着多个线程同时访问共享资源,可能会导致数据不一致和其他并发问题。因此,了解并掌握Java中的多线程并发控制机制显得尤为重要。本文将深入探讨Java的多线程并发控制,包括synchronized关键字、Lock接口、Semaphore类以及CountDownLatch类等,并通过实例代码演示其使用方法和注意事项。
12 2
|
29天前
|
算法 安全 Unix
【C++ 20 信号量 】C++ 线程同步新特性 C++ 20 std::counting_semaphore 信号量的用法 控制对共享资源的并发访问
【C++ 20 信号量 】C++ 线程同步新特性 C++ 20 std::counting_semaphore 信号量的用法 控制对共享资源的并发访问
29 0
|
1月前
|
消息中间件 存储 算法
【C/C++ 泡沫精选面试题04】在实际项目中,多进程和多线程如何选择?
【C/C++ 泡沫精选面试题04】在实际项目中,多进程和多线程如何选择?
43 1