投资银行的 15 大 Java 多线程、并发面试问题

多线程和并发问题是任何 Java 面试的重要部分。在投资银行(如巴克莱、花旗银行、摩根士丹利)的股票前台 Java 开发人员职位面试中,会有很多多线程面试问题。投资银行面试中,多线程和并发是热门话题,特别是在电子交易开发工作中,会考察很多棘手的 Java 线程面试问题。他们希望确保候选人对 Java 中的多线程和并发编程有扎实的知识,因为他们大多从事性能业务,以获得竞争优势。

例如,用于直接入市(DMA)交易的高容量和低延迟电子交易系统通常是并发的。大多数时候,他们会关注微秒级延迟,这就是为什么了解如何有效减少延迟和提高吞吐量很重要。

以下是一些我最喜欢的关于 Java 的线程面试问题。我不会提供这些线程面试问题的答案,但会在可能的情况下给出提示。我将进一步更新帖子,提供详细答案,就像我最近的帖子Java 中的 10 个单例面试问题一样。

JDK 1.5 中引入并发包后,出现了一些关于并发实用工具和并发集合的问题,例如ThreadLocalBlockingQueueCounting SemaphoreConcurrentHashMap变得流行起来。

Java 8 和 Java 9 也是如此。出现了关于 lambda 表达式、并行流、新的 fork-join 池和 CompletableFuture 的问题,这些在 2018 年逐渐增加,并将在 2019 年保持。因此,你应该准备好这些主题。

15 个 Java 线程面试问题及答案

以下是一些在投资银行(如巴克莱、摩根士丹利、花旗银行等)的 Java 开发人员面试中经常被问到的 Java 多线程和并发问题:

1) 你有线程 T1、T2 和 T3。如何确保线程 T2 在 T1 之后运行,线程 T3 在 T2 之后运行?
这个线程面试问题大多在面试的第一轮或电话筛选轮中被问到,目的是检查候选人是否熟悉“join”方法的概念。这个多线程问题的答案很简单——可以通过使用 Thread 类的join方法来实现。

2) 在 Java 中,新的 Lock 接口相对于同步块的优势是什么?你需要实现一个高性能缓存,允许多个读取器,但如何实现单个写入器以保持完整性?
在多线程和并发编程中,锁接口的主要优势是它们为读取和写入提供了两个单独的锁,使你能够编写高性能的数据结构,如ConcurrentHashMap条件阻塞
这个 Java 线程面试问题越来越受欢迎,基于受访者的答案会有越来越多的后续问题。
我强烈建议在参加任何 Java 多线程面试之前阅读锁的相关内容,因为现在它被大量用于在客户端和交易所连接空间中为电子交易系统构建缓存。

3) Java 中的 wait 和 sleep 方法有什么区别?
这是另一个在 Java 中经常被问到的线程面试问题,大多出现在电话面试中。唯一的主要区别是 wait 会释放锁或监视器,而 sleep 在等待时不会释放任何锁或监视器。wait 用于线程间通信,因为 sleep 用于在执行中引入暂停。更多信息请查看我的帖子Java 中的 wait vs sleep

4) 编写在 Java 中实现阻塞队列的代码?
这是一个相对较难的 Java 多线程面试问题,有很多目的。它检查候选人是否真的能使用线程编写 Java 代码。它考察候选人对并发场景的理解程度,并且可以根据他的代码问很多后续问题。如果他使用wait()和 notify()方法来实现阻塞队列,一旦候选人成功编写出来,你可以让他再次使用新的 Java 5 并发类来编写等。

5) 编写在 Java 中解决生产者消费者问题的代码?(解决方案)
与上述关于线程的问题类似,这个问题本质上更经典,但有时面试官会问后续问题,如“如何在 Java 中解决生产者消费者问题?”嗯,有多种方法可以解决。我分享了一种使用 Java 中的 BlockingQueue 解决生产者-消费者问题的方法,所以要为一些惊喜做好准备。有时,他们甚至会让你实现哲学家就餐问题的解决方案。

6) 编写一个会导致死锁的程序。如何在 Java 中修复死锁?
这是我最喜欢的 Java 线程面试问题,因为即使在编写多线程并发程序时死锁很常见,很多候选人也无法编写无死锁代码,他们会很挣扎。
只需问他们如果有 N 个资源和 N 个线程来完成一个操作,然后需要所有资源。
这里 N 可以用 2 替换为最简单的情况,用更高的数字使问题更具威慑力。更多关于死锁的信息请查看如何在 Java 中避免死锁

7) 什么是原子操作?Java 中的原子操作是什么?
这是一个简单的 Java 线程面试问题。另一个后续问题是:是否需要同步原子操作?你可以在此处阅读更多关于Java 同步的信息。

8) Java 中的 volatile 关键字是什么?如何使用它?它与 Java 中的同步方法有何不同?
基于 Java 中的volatile 关键字的线程问题在 Java 5 及其 Java 内存模型的更改后变得更加流行。准备好了解 volatile 变量如何在并发环境中确保可见性、排序和一致性是很有好处的。

9) 什么是竞态条件?如何发现和解决竞态条件?
另一个 Java 多线程问题大多出现在高级面试中。大多数面试官会询问你最近遇到的竞态条件、如何解决它,有时他们会编写示例代码并让你检测竞态条件。更多信息请查看我的关于Java 中的竞态条件的帖子。在我看来,这是最好的 Java 线程面试问题之一,可以真正测试候选人在解决竞态条件或编写无数据争用或任何其他竞态条件的代码方面的经验。关于这个主题的最好的书是“Java 中的并发实践”。

10) 如何在 Java 中获取线程转储?如何分析线程转储?
在 UNIX 中,你可以使用 kill -3,然后线程转储将在 Windows 上打印日志,你可以使用“CTRL+Break”。虽然这是一个相当简单的线程面试问题,但如果他们问你如何分析它,可能会变得棘手。线程转储也可用于分析死锁情况。

11) 为什么我们调用 start()方法,它又调用 run()方法,为什么不直接调用 run()方法?
这是另一个经典的 Java 多线程面试问题。最初,我在开始线程编程时有些疑惑。现在,我在电话面试或中级和初级 Java 面试的第一轮面试中大多会被问到这个问题。
以下是这个问题的答案。当你调用start()方法时,它会创建一个新线程并执行在run()中声明的代码,而直接调用run()方法不会创建任何新线程,而是在同一个调用线程上执行代码。更多细节请阅读我的帖子线程中 start 和 run 方法的区别

12) 如何在 Java 中唤醒一个阻塞的线程?
这是一个关于线程的棘手问题。阻塞可能有多种方式——如果线程在 IO 上阻塞,那么我认为没有办法中断该线程。请告诉我是否有。另一方面,如果线程由于调用wait()sleep()join()方法的结果而被阻塞,你可以中断该线程,它将通过抛出InterruptedException而唤醒。更多关于处理阻塞线程的信息请查看我的帖子如何处理 Java 中的阻塞方法

13) Java 中的 CyclicBarriar 和 CountdownLatch 有什么区别?(答案)
新的 Java 线程面试问题大多检查你对 JDK 5 并发包的熟悉程度。一个区别是,一旦屏障被打破,你可以重用CyclicBarrier,但不能重用CountDownLatch。如果你想了解更多,请查看 Udemy 上的Java 中的多线程和并行计算课程。

14) 什么是不可变对象?它如何帮助编写并发应用程序?
虽然这个面试问题与线程没有直接关系,但它间接地有很大帮助。如果他们让你编写一个不可变类或问你为什么 Java 中的 String 是不可变的作为后续问题,这个面试问题可能会变得更棘手。

15) 在多线程环境中你遇到过哪些常见问题?你是如何解决它们的?
内存干扰、竞态条件、死锁、活锁和饥饿是多线程和并发编程中出现的一些问题的示例。问题无穷无尽;如果你做错了,它们将很难检测和调试。
这主要是一个基于经验的 Java 面试问题。你可以查看Heinz Kabutz 的 Java 并发实践课程,了解在实际高性能多线程应用程序中遇到的一些实际问题。

这些是我最喜欢的 Java线程面试问题和投资银行常见问的问题。这个列表绝不是完整的,所以请在下面评论你在面试中遇到的一些有趣的 Java 线程问题。这篇文章收集并分享了关于多线程概念的优秀面试问题,不仅有助于面试,还为学习新的线程概念打开了大门。

Java-revisited 的一位读者 Hemant 贡献了一些更多的 Java 线程面试问题:
1) Java 中的绿色线程和本机线程的区别?
2) 线程和进程的区别?(答案)
3) 多线程中的上下文切换是什么?
4) 死锁和活锁、死锁和饥饿的区别?
5) Java 中使用的线程调度算法是什么?
6) Java 中的线程调度器是什么?
7) 如何在线程中处理未处理的异常?
8) 什么是线程组,为什么不建议在 Java 中使用线程组?
9) 为什么 Executor 框架比通过应用程序创建和管理线程更好?
10) Java 中的 Executor 和 Executors 的区别?(答案)
11) 如何在 Windows 和 Linux 服务器中找到占用最大 CPU 的线程?

阅读 23
0 条评论