BAT大厂Java多线程面试笔试真题(含详细答案解析)_第1页
BAT大厂Java多线程面试笔试真题(含详细答案解析)_第2页
BAT大厂Java多线程面试笔试真题(含详细答案解析)_第3页
BAT大厂Java多线程面试笔试真题(含详细答案解析)_第4页
BAT大厂Java多线程面试笔试真题(含详细答案解析)_第5页
已阅读5页,还剩3页未读, 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

BAT大厂Java多线程面试笔试真题(含详细答案解析)整套试题贴合BAT一线大厂校招、社招笔试面试核心考点,覆盖线程基础、锁机制、并发容器、线程池、JMM内存模型、CAS、AQS等高频重点,题型全面,解析通俗易懂、落地性强,无模板化话术。一、单项选择题(10题,每题3分,共30分)1.下列关于Java线程状态的说法,正确的是()A.Java线程有8种运行状态B.线程调用sleep()方法后,进入阻塞状态D.线程start()方法可重复调用【答案】B详细解析:2.以下方法中,不会释放锁资源的是()A.wait()B.sleep()C.notify()D.notifyAll()【答案】B详细解析:wait()是Object类方法,执行后会主动释放当前持有的对象锁,进入等待队列;sleep()是Thread类静态方法,仅暂停线程执行,不会释放任何锁资源,锁会继续持有;notify/notifyAll仅唤醒等待线程,不会主动释放锁,锁会在当前同步代码块执行结束后释放。3.关于synchronized和Lock的区别,下列说法错误的是()A.synchronized是内置锁,Lock是显式锁B.synchronized可自动释放锁,Lock需手动解锁C.synchronized支持公平锁机制D.Lock锁的灵活性更高,可实现超时获取锁【答案】C详细解析:synchronized是JVM层面的内置锁,默认非公平锁,不支持公平锁配置;Lock接口的实现类ReentrantLock支持公平锁、非公平锁自定义配置。synchronized代码块执行完毕或异常时自动释放锁,Lock必须手动调用unlock()解锁,否则会造成死锁,且Lock支持tryLock()超时抢锁、可中断抢锁等高级特性,灵活性远高于内置锁。4.CAS操作的核心原理是()A.悲观锁机制B.内存值、预期值、更新值对比替换C.队列排队抢占锁D.重量级锁阻塞线程【答案】B详细解析:CAS即比较并交换,是典型的乐观锁实现方式。核心逻辑:读取内存中的旧值,更新前对比当前内存值是否等于预期旧值,相等则更新为新值,不相等则说明数据已被修改,放弃本次更新或重试。CAS无锁操作,不阻塞线程,效率高于重量级锁,不存在队列抢锁逻辑。5.下列属于线程安全的集合是()A.ArrayListB.HashMapC.ConcurrentHashMapD.LinkedList【答案】C详细解析:ArrayList、LinkedList、HashMap均为非线程安全集合,多线程并发读写会出现数据覆盖、链表断裂、空指针等问题;ConcurrentHashMap是JDK专门提供的并发安全哈希表,基于CAS+分段锁(JDK1.7)/CAS+数组+链表+红黑树+synchronized(JDK1.8)实现,支持高并发读写。6.JDK1.8中ConcurrentHashMap的锁机制是()A.分段Segment锁B.全局synchronized锁C.桶位synchronized锁+CASD.ReentrantLock可重入锁【答案】C详细解析:JDK1.7采用Segment分段锁机制,将集合分为多个分段,每个分段独立加锁;JDK1.8彻底废弃Segment,优化为CAS乐观锁+桶位级synchronized轻量级锁,仅对当前操作的数组桶位加锁,锁粒度更细,并发性能大幅提升,不再使用ReentrantLock。7.下列关于线程池核心参数的说法,正确的是()A.corePoolSize是线程池最大线程数B.maximumPoolSize是核心常驻线程数C.任务队列满且线程数达最大值时,触发拒绝策略D.keepAliveTime对核心线程生效【答案】C详细解析:corePoolSize为核心常驻线程数,maximumPoolSize为线程池最大线程数;keepAliveTime是非核心线程的空闲存活时间,默认对核心线程无效;线程池执行规则:核心线程满载→任务队列入队→队列满则创建非核心线程→线程数达最大值,触发拒绝策略。8.导致线程死锁的必要条件不包括()A.互斥条件B.资源可抢占C.请求与保持D.循环等待【答案】B详细解析:死锁四大必要条件:互斥、请求与保持、不可抢占、循环等待。资源可抢占是打破死锁的核心手段,不属于死锁产生条件,只要破坏任意一个必要条件,即可避免死锁。9.关于volatile关键字,下列说法正确的是()A.可以保证原子性B.可以保证可见性和有序性C.可以替代synchronizedD.会阻塞线程执行【答案】B详细解析:volatile核心作用:保证多线程变量可见性、禁止指令重排序,但无法保证复合操作(i++、赋值运算)的原子性;无锁、不阻塞线程,性能远高于synchronized,但无法替代锁的原子性保障,仅适用于状态标记、读写分离的简单场景。10.AQS框架的核心数据结构是()A.数组B.双向阻塞队列C.单向链表D.哈希表【答案】B详细解析:AQS(抽象队列同步器)是Java并发锁的底层核心,核心维护一个FIFO双向阻塞队列,存储所有抢锁失败的阻塞线程,同时通过state变量记录锁状态,ReentrantLock、CountDownLatch、Semaphore等并发工具均基于AQS实现。二、填空题(5题,每题4分,共20分)1.Java线程的两大核心特性是_________、_________。答案:原子性、可见性、有序性(任选其二)2.终止线程的三种常用方式:_________、_________、_________。答案:正常执行完毕、stop()(废弃)、interrupt()中断3.线程池四种默认拒绝策略:_________、_________、_________、_________。答案:AbortPolicy(直接抛出异常)、CallerRunsPolicy(调用者执行)、DiscardPolicy(丢弃任务)、DiscardOldestPolicy(丢弃队首旧任务)4.解决CASABA问题的两种常用方案:_________、_________。答案:版本号机制、时间戳机制(AtomicStampedReference)5.wait()、notify()方法必须在_________代码块中使用。答案:synchronized同步三、简答题(4题,每题8分,共32分)1.简述sleep()和wait()的核心区别(大厂高频问答)参考答案:(1)所属类不同:sleep()是Thread类静态方法,wait()是Object类方法;(2)锁释放不同:sleep()仅休眠线程,不释放锁;wait()会主动释放当前对象锁;(3)唤醒方式不同:sleep()休眠时间结束自动唤醒;wait()需被动等待notify/notifyAll唤醒;(4)使用场景不同:sleep()可任意位置使用;wait()必须在同步代码块/同步方法中使用;2.简述volatile无法保证原子性的原因,并举出典型场景参考答案:原子性指一个操作要么全部执行成功,要么完全不执行。volatile仅保证变量读写的内存可见性,无法保证复合操作的原子性。典型场景:i++操作,该操作分为三步:读取内存值、自增计算、写入新值。volatile只能保证每次读取的是最新内存值,但多线程并发时,多个线程可能同时读取同一个值,分别计算后覆盖写入,最终出现数据丢失,无法保证操作原子性。解决方案:使用synchronized锁、ReentrantLock锁或Atomic原子类。3.简述线程池的优势,为什么生产环境禁止使用Executors创建线程池?参考答案:线程池核心优势:①复用线程,避免频繁创建、销毁线程带来的性能开销;②统一管理线程,控制并发数量,避免海量线程导致OOM、CPU飙升;③任务队列缓冲,合理调度任务,提升系统响应效率。禁止Executors的原因:Executors创建的线程池参数不透明,存在严重线上隐患:①newFixedThreadPool、newSingleThreadExecutor:任务队列为无界队列,任务堆积会导致内存溢出OOM;②newCachedThreadPool、newScheduledThreadPool:最大线程数无上限,高并发下会创建大量线程,耗尽系统资源。生产环境必须通过ThreadPoolExecutor手动创建线程池,自定义核心参数和拒绝策略。4.简述死锁的排查思路和解决方案参考答案:排查思路:①使用jps命令查看Java进程ID;②使用jstack进程ID打印线程堆栈信息,查找FoundoneJava-leveldeadlock关键字;③分析线程锁持有、锁等待关系,定位循环等待的代码位置。解决方案:①破坏循环等待:统一多锁的获取顺序,所有线程按固定顺序抢锁;②破坏请求与保持:一次性申请所有需要的锁资源,不持有部分锁再申请新锁;③破坏不可抢占:使用可超时锁(tryLock),抢锁失败主动释放已持有锁;④减少锁粒度,避免嵌套锁,从代码层面规避死锁场景。四、编程题(18分)题目:手写多线程交替打印1-100,两个线程分别打印奇数、偶数,有序交替输出解题思路:使用synchronized锁+wait/notify线程通信,定义全局计数器,两个线程互相唤醒,交替执行打印逻辑,保证有序性。完整可运行代码:java

publicclassThreadPrintDemo{

//全局计数器

privatestaticintnum=1;

//锁对象

privatestaticfinalObjectLOCK=newObject();

publicstaticvoidmain(String[]args){

//打印奇数线程

newThread(()->{

while(num<=100){

synchronized(LOCK){

//不是奇数则等待

while(num%2==0){

try{

LOCK.wait();

}catch(InterruptedExceptione){

e.printStackTrace();

}

}

if(num<=100){

System.out.println("奇数线程:"+num);

num++;

}

//唤醒偶数线程

LOCK.notifyAll();

}

}

},"奇数线程").start();

//打印偶数线程

newThread(()->{

while(num<=100){

synchronized(LOCK){

//不是偶数则等待

while(num%2!=0){

try{

LOCK.wait();

}catch(InterruptedExceptione){

e.printStackTrace();

}

}

if(num<=100){

System.out.println("偶数线程:"+num);

num++;

}

//唤醒奇数线程

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论