2025年Java秋招面试必看的 | Java并发编程 面试题

前言

作为一名专业的 Java 开发者,掌握在并发场景下编写高质量代码的能力是必不可少的,这也是衡量 Java 开发者技术水平的重要标准。因此,Java 并发问题一直是各大公司面试中的重点考察内容。然而,我发现许多求职者在面试时,往往对并发原理的理解不够深入,虽然有所了解,但无法清晰地表达,最终导致面试失利。
为了解决这一问题,我决定深入学习并发编程。然而,面对厚重的理论书籍,我感到有些无从下手。实际上,尽管 Java 并发编程的内容较为复杂,但其整体脉络是清晰的,只要抓住关键点,就能逐步掌握。

小编分享的这份2022年Java秋招备战面试题总计有1000多道面试题,包含了MyBatis、ZooKeeper、Dubbo、Elasticsearch、Memcached、Redis、MySQL、Java 并发编程、Java基础、Spring、微服务、Linux、Spring Boot 、Spring Cloud、RabbitMQ、kafka等16个专题技术点,都是小编在今年金三银四总结出来的面试真题,已经有很多粉丝靠这份PDF拿下众多大厂的offer,今天在这里总结分享给到大家!【已完结】

由于资料篇幅较长,因此选择性地展示了部分内容。资料整理花费了一年的零碎时间,希望能对大家学习有所帮助!需要篇末vx名片获取即可哈!

序号专题技术内容地址
1MyBatisMybatis面试题
2ZooKeeperZooKeeper面试题
3DubboDubbo面试题
4ElasticsearchElasticsearch 面试题
5MemcachedMemcached面试题
6RedisRedis 面试题
7MySQLMySQL 面试题
8Java并发编程Java并发编程面试题
9Java基础Java基础面试题
10SpringSpring面试题
11微服务微服务面试题
12LinuxLinux面试题
13Spring BootSpring Boot面试题
14Spring CloudSpring Cloud面试题
15RabbitMQRabbitMQ面试题
16kafkakafka面试题

1、在java中守护线程和本地线程区别?
java 中的线程分为两种:守护线程(Daemon)和用户线程(User)。


2、线程与进程的区别?
进程是操作系统分配资源的最小单元,线程是操作系统调度的最小单元。 一个程序至少有一个进程,一个进程至少有一个线程。
3、什么是多线程中的上下文切换?


4、死锁与活锁的区别,死锁与饥饿的区别?


5、Java中用到的线程调度算法是什么?
采用时间片轮转的方式。可以设置线程的优先级,会映射到下层的系统上面的优先级上,如非特别需要,尽量不要用,防止线程饥饿。
6、什么是线程组,为什么在 Java 中不推荐使用?


7、为什么使用Executor框架?


8、在Java中Executor和Executors的区别?


10、什么是原子操作?在Java Concurrency API中有哪些原子类(atomic cla


11、Java Concurrency API中的Lock接口(Lock interface)是什么


12、什么是Executors框架?


13、什么是阻塞队列?阻塞队列的实现原理是什么?如何使用阻塞队列来实现生产者-消费者模型?


14、什么是Callable和Future?


15、什么是FutureTask?使用ExecutorService启动任务。


16、什么是并发容器的实现?


17、多线程同步和互斥有几种实现方法,都是什么?


18、什么是竞争条件?你怎样发现和解决竞争?
当多个进程都企图对共享数据进行某种处理,而最后的结果又取决于进程运行的顺序时,则我们认为这发生了竞争条件(race condition)。
19、你将如何使用thread dump?你将如何分析Thread dump?
新建状态(New)
用 new 语句创建的线程处于新建状态,此时它和其他 Java 对象一样,仅仅在堆区中被分配了内存。
就绪状态(Runnable)
当一个线程对象创建后,其他线程调用它的 start()方法,该线程就进入就绪状态,Java 虚拟机会为它创建方法调用栈和程序计数器。处于这个状态的线程位于可运行池中,等待获得 CPU 的使用权。
运行状态(Running)
处于这个状态的线程占用 CPU,执行程序代码。只有处于就绪状态的线程才有机会转到运行状态。
阻塞状态(Blocked)
阻塞状态是指线程因为某些原因放弃 CPU,暂时停止运行。当线程处于阻塞状态时,Java 虚拟机不会给线程分配 CPU。直到线程重新进入就绪状态,它才有机会转到运行状态。
阻塞状态可分为以下 3 种:
位于对象等待池中的阻塞状态(Blocked in object’s wait pool)
当线程处于运行状态时,如果执行了某个对象的 wait()方法,Java 虚拟机就会把线程放到这个对象的等待池中,这涉及到“线程通信”的内容。
位于对象锁池中的阻塞状态(Blocked in object’s lock pool)
当线程处于运行状态时,试图获得某个对象的同步锁时,如果该对象的同步锁已经被其他线程占用,Java 虚拟机就会把这个线程放到这个对象的锁池中,这涉及到“线程同步”的内容。
其他阻塞状态(Otherwise Blocked)
当前线程执行了 sleep()方法,或者调用了其他线程的 join()方法,或者发出了 I/O请求时,就会进入这个状态。
死亡状态(Dead)
当线程退出 run()方法时,就进入死亡状态,该线程结束生命周期。我们运行之前的那个死锁代码 SimpleDeadLock.java,
然后尝试输出信息:
/* 时间,jvm 信息 */ 2017-11-01 17:36:28 Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.144-b01 mixed mode): /* 线程名称:DestroyJavaVM 编号:#13 优先级:5 系统优先级:0 jvm 内部线程 id:0x0000000001c88800 对应系统线程 id(NativeThread ID):0x1c18 线程状态: waiting on condition [0x0000000000000000] (等待某个条件) 线程详细状态:java.lang.Thread.State: RUNNABLE 及之后所有*/ "DestroyJavaVM" #13 prio=5 os_prio=0 tid=0x0000000001c88800 nid=0x1c18 waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE "Thread-1" #12 prio=5 os_prio=0 tid=0x0000000018d49000 nid=0x17b8 waiting for monitor entry [0x0000000019d7f000] /* 线程状态:阻塞(在对象同步上) 代码位置:at com.leo.interview.SimpleDeadLock$B.run(SimpleDeadLock.java:56) 等待锁:0x00000000d629b4d8 已经获得锁:0x00000000d629b4e8*/ java.lang.Thread.State: BLOCKED (on object monitor) at com.leo.interview.SimpleDeadLock$B.run(SimpleDeadLock.java:56) - waiting to lock <0x00000000d629b4d8> (a java.lang.Object) - locked <0x00000000d629b4e8> (a java.lang.Object) "Thread-0" #11 prio=5 os_prio=0 tid=0x0000000018d44000 nid=0x1ebc waiting for monitor entry [0x000000001907f000] java.lang.Thread.State: BLOCKED (on object monitor) at com.leo.interview.SimpleDeadLock$A.run(SimpleDeadLock.java:34) - waiting to lock <0x00000000d629b4e8> (a java.lang.Object) - locked <0x00000000d629b4d8> (a java.lang.Object) "Service Thread" #10 daemon prio=9 os_prio=0 tid=0x0000000018ca5000 nid=0x1264 runnable [0x0000000000000000] java.lang.Thread.State: RUNNABLE "C1 CompilerThread2" #9 daemon prio=9 os_prio=2 tid=0x0000000018c46000 nid=0xb8c waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE "C2 CompilerThread1" #8 daemon prio=9 os_prio=2 tid=0x0000000018be4800 nid=0x1db4 waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE "C2 CompilerThread0" #7 daemon prio=9 os_prio=2 tid=0x0000000018be3800 nid=0x810 waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE "Monitor Ctrl-Break" #6 daemon prio=5 os_prio=0 tid=0x0000000018bcc800 nid=0x1c24 runnable [0x00000000193ce000] java.lang.Thread.State: RUNNABLE at java.net.SocketInputStream.socketRead0(Native Method) at java.net.SocketInputStream.socketRead(SocketInputStream.java:116) at java.net.SocketInputStream.read(SocketInputStream.java:171) at java.net.SocketInputStream.read(SocketInputStream.java:141) at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284) at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326) at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178) - locked <0x00000000d632b928> (a java.io.InputStreamReader) at java.io.InputStreamReader.read(InputStreamReader.java:184) at java.io.BufferedReader.fill(BufferedReader.java:161) at java.io.BufferedReader.readLine(BufferedReader.java:324) - locked <0x00000000d632b928> (a java.io.InputStreamReader) at java.io.BufferedReader.readLine(BufferedReader.java:389) at com.intellij.rt.execution.application.AppMainV2$1.run(AppMainV2.java:6 4) "Attach Listener" #5 daemon prio=5 os_prio=2 tid=0x0000000017781800 nid=0x524 runnable [0x0000000000000000] java.lang.Thread.State: RUNNABLE "Signal Dispatcher" #4 daemon prio=9 os_prio=2 tid=0x000000001778f800 nid=0x1b08 waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE "Finalizer" #3 daemon prio=8 os_prio=1 tid=0x000000001776a800 nid=0xdac in Object.wait() [0x0000000018b6f000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <0x00000000d6108ec8> (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143) - locked <0x00000000d6108ec8> (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:164) at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:209) "Reference Handler" #2 daemon prio=10 os_prio=2 tid=0x0000000017723800 nid=0x1670 in Object.wait() [0x00000000189ef000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <0x00000000d6106b68> (a java.lang.ref.Reference$Lock) at java.lang.Object.wait(Object.java:502) at java.lang.ref.Reference.tryHandlePending(Reference.java:191) - locked <0x00000000d6106b68> (a java.lang.ref.Reference$Lock) at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153) "VM Thread" os_prio=2 tid=0x000000001771b800 nid=0x604 runnable "GC task thread#0 (ParallelGC)" os_prio=0 tid=0x0000000001c9d800 nid=0x9f0 runnable "GC task thread#1 (ParallelGC)" os_prio=0 tid=0x0000000001c9f000 nid=0x154c runnable "GC task thread#2 (ParallelGC)" os_prio=0 tid=0x0000000001ca0800 nid=0xcd0 runnable "GC task thread#3 (ParallelGC)" os_prio=0 tid=0x0000000001ca2000 nid=0x1e58 runnable "VM Periodic Task Thread" os_prio=2 tid=0x0000000018c5a000 nid=0x1b58 waiting on condition JNI global references: 33 /* 此处可以看待死锁的相关信息! */ Found one Java-level deadlock: ============================= "Thread-1": waiting to lock monitor 0x0000000017729fc8 (object 0x00000000d629b4d8, a java.lang.Object), which is held by "Thread-0" "Thread-0": waiting to lock monitor 0x0000000017727738 (object 0x00000000d629b4e8, a java.lang.Object), which is held by "Thread-1" Java stack information for the threads listed above: ============================================== ===== "Thread-1": at com.leo.interview.SimpleDeadLock$B.run(SimpleDeadLock.java:56) - waiting to lock <0x00000000d629b4d8> (a java.lang.Object) - locked <0x00000000d629b4e8> (a java.lang.Object) "Thread-0": at com.leo.interview.SimpleDeadLock$A.run(SimpleDeadLock.java:34) - waiting to lock <0x00000000d629b4e8> (a java.lang.Object) - locked <0x00000000d629b4d8> (a java.lang.Object) Found 1 deadlock. /* 内存使用状况,详情得看 JVM 方面的书 */ Heap PSYoungGen total 37888K, used 4590K [0x00000000d6100000, 0x00000000d8b00000, 0x0000000100000000) eden space 32768K, 14% used [0x00000000d6100000,0x00000000d657b968,0x00000000d8100000) from space 5120K, 0% used [0x00000000d8600000,0x00000000d8600000,0x00000000d8b00000) to space 5120K, 0% used [0x00000000d8100000,0x00000000d8100000,0x00000000d8600000) ParOldGen total 86016K, used 0K [0x0000000082200000, 0x0000000087600000, 0x00000000d6100000) object space 86016K, 0% used [0x0000000082200000,0x0000000082200000,0x0000000087600000) Metaspace used 3474K, capacity 4500K, committed 4864K, reserved 1056768K class space used 382K, capacity 388K, committed 512K, reserved 1048576K
20、为什么我们调用start()方法时会执行run()方法,为什么我们不能直接调用run()方法?


21、Java中你怎样唤醒一个阻塞的线程?


22、在Java中CycliBarriar和CountdownLatch有什么区别?
CyclicBarrier 可以重复使用,而 CountdownLatch 不能重复使用。


23、什么是不可变对象,它对写并发应用有什么帮助?


24、什么是多线程中的上下文切换?


25、Java中用到的线程调度算法是什么?


26、什么是线程组,为什么在Java中不推荐使用?
线程组和线程池是两个不同的概念,他们的作用完全不同,前者是为了方便线程的管理,后者是为了管理线程的生命周期,复用线程,减少创建销毁线程的开销。
27、为什么使用Executor框架比使用应用创建和管理线程好?


28、java中有几种方法可以实现一个线程?

  • 继承 Thread 类
  • 实现 Runnable 接口
  • 实现 Callable 接口,需要实现的是 call() 方法

29、如何停止一个正在运行的线程?


30、notify()和notifyAll()有什么区别?


31、什么是Daemon线程?它有什么意义?


32、java如何实现多线程之间的通讯和协作?
中断 和 共享变量
33、什么是可重入锁(ReentrantLock)?
举例来说明锁的可重入性
public class UnReentrant{ Lock lock = new Lock(); public void outer(){ ock.lock(); inner(); lock.unlock(); } public void inner(){ lock.lock(); //do something lock.unlock(); } }


34、当一个线程进入某个对象的一个synchronized的实例方法后,其它线程是否可进入此对象的其
如果其他方法没有 synchronized 的话,其他线程是可以进入的。所以要开放一个线程安全的对象时,得保证每个方法都是线程安全的。
35、乐观锁和悲观锁的理解及如何实现,有哪些实现方式?


CAS 缺点


36、SynchronizedMap和ConcurrentHashMap有什么区别?


37、CopyOnWriteArrayList可以用于什么应用场景?


38、什么叫线程安全?servlet是线程安全吗?


39、volatile有什么用?能否用一句话说明下volatile的应用场景?


40、为什么代码会重排序?


41、在java中wait和sleep方法的不同?
最大的不同是在等待时 wait 会释放锁,而 sleep 一直持有锁。Wait 通常被用于线程间交互,sleep 通常被用于暂停执行。
直接了解的深入一点吧:
在 Java 中线程的状态一共被分成 6 种


超时等待态
当运行中的线程调用 sleep(time)、wait、join、parkNanos、parkUntil 时,就会进入该状态;它和等待态一样,并不是因为请求不到资源,而是主动进入,并且进入后需要其他线程唤醒;进入该状态后释放 CPU 执行权 和 占有的资源。与等待态的区别:到了超时时间后自动进入阻塞队列,开始竞争锁。


43、一个线程运行时发生异常会怎样?


44、如何在两个线程间共享数据?


45、Java中notify 和 notifyAll有什么区别?


46、为什么wait, notify 和 notifyAll这些方法不在thread类里面?


47、什么是ThreadLocal变量?


48、Java中interrupted 和 isInterrupted方法的区别?


49、为什么wait和notify方法要在同步块中调用?


50、为什么你应该在循环中检查等待条件?
处于等待状态的线程可能会收到错误警报和伪唤醒,如果不在循环中检查等待条件,程序就会在没有满足结束条件的情况下退出。
51、Java中的同步集合与并发集合有什么区别?


52、什么是线程池? 为什么要使用它?


53、怎么检测一个线程是否拥有锁?
在 java.lang.Thread 中有一个方法叫 holdsLock(),它返回 true 如果当且仅当当前线程拥有某个具体对象的锁。
54、你如何在Java中获取线程堆栈?


56、Thread类中的yield方法有什么作用?


57、Java中ConcurrentHashMap的并发度是什么?


58、Java中Semaphore是什么?


59、Java 线程池中 submit() 和 execute()方法有什么区别?


60、什么是阻塞式方法?


61、Java中的ReadWriteLock是什么?
读写锁是用来提升并发程序性能的锁分离技术的成果。
62、volatile 变量和 atomic 变量有什么不同?


63、可以直接调用Thread类的run ()方法么?


64、如何让正在运行的线程暂停一段时间?


65、你对线程优先级的理解是什么?


66、什么是线程调度器(Thread Scheduler)和时间分片(Time Slicing )?


67、你如何确保main()方法所在的线程是Java 程序最后结束的线程?
我们可以使用 Thread 类的 join()方法来确保所有程序创建的线程在 main()方法退出前结束。
68、线程之间是如何通信的?


69、为什么线程通信的方法wait(), notify()和notifyAll()被定义在Objec


70、为什么wait(), notify()和notifyAll ()必须在同步方法或者同步块中被调


71、为什么Thread类的sleep()和yield ()方法是静态的?


72、如何确保线程安全?


73、同步方法和同步块,哪个是更好的选择?


74、如何创建守护线程?

由于资料篇幅较长,因此选择性地展示了部分内容。资料整理花费了一年的零碎时间,希望能对大家学习有所帮助!需要篇末vx名片获取即可哈!

75、什么是Java Timer 类?如何创建一个有特定时间间隔的任务?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值