版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
高频java中级面试题及答案Java中线程的状态有哪些?如何在代码中实现状态转换?Java线程共有6种状态,定义在Thread.State枚举中:NEW(新建)、RUNNABLE(可运行)、BLOCKED(阻塞)、WAITING(无限等待)、TIMED_WAITING(超时等待)、TERMINATED(终止)。状态转换逻辑如下:新建线程对象时进入NEW;调用start()方法后进入RUNNABLE(实际可能在等待CPU调度);当线程尝试获取synchronized同步锁失败时进入BLOCKED;调用无参数的wait()、join()或park()方法时进入WAITING,需其他线程调用notify()/notifyAll()或unpark()唤醒;调用带超时参数的wait(long)、join(long)或parkNanos(long)时进入TIMED_WAITING,超时后自动唤醒;线程执行完run()方法或异常终止后进入TERMINATED。例如,A线程调用B.join()会使A进入WAITING,直到B终止;调用Thread.sleep(1000)会使当前线程进入TIMED_WAITING。HashMap在JDK7和JDK8中的实现有哪些主要区别?为什么引入红黑树?JDK7中HashMap基于数组+链表实现,哈希冲突时通过头插法将新节点插入链表头部;JDK8改为数组+链表+红黑树结构,冲突时使用尾插法,当链表长度≥8且数组长度≥64时,链表转换为红黑树(阈值8的设计参考了泊松分布,链表长度超过8的概率低于0.00000006,此时转换能平衡空间和时间复杂度)。主要区别包括:1.数据结构:JDK8增加红黑树,查询时间复杂度从O(n)优化为O(logn);2.插入方式:JDK7头插法可能导致多线程扩容时的循环链表问题(死循环),JDK8尾插法避免了该问题;3.哈希计算:JDK7的hash()方法通过4次位运算+5次异或减少碰撞,JDK8简化为(h=key.hashCode())^(h>>>16),仅一次异或,减少计算开销;4.扩容逻辑:JDK7扩容时重新计算每个元素的哈希值,JDK8通过(e.hash&oldCap)是否为0判断元素在新数组中的位置(0则位置不变,非0则位置为原位置+oldCap),提升扩容效率。synchronized和ReentrantLock的区别是什么?如何选择?两者均用于实现线程同步,但存在以下差异:1.锁性质:synchronized是JVM内置的关键字,依赖对象头的Monitor锁;ReentrantLock是JUC包中的类,基于AQS(AbstractQueuedSynchronizer)实现。2.锁特性:synchronized自动释放锁(同步块/方法执行完毕或异常退出),支持可重入但不支持公平锁;ReentrantLock需手动调用unlock()释放(通常配合try-finally),支持可重入、公平锁(构造时传入true)和非公平锁(默认),提供tryLock()(尝试获取锁)、lockInterruptibly()(可中断获取锁)等扩展方法。3.性能:早期版本synchronized因重量级锁性能较差,JDK6引入锁升级(偏向锁→轻量级锁→重量级锁)后,性能与ReentrantLock接近,高竞争场景下后者通过CAS减少上下文切换可能更优。选择建议:简单同步场景优先用synchronized(代码简洁);需要可中断、超时获取锁或公平锁时用ReentrantLock;需条件变量(Condition)实现精准唤醒(如生产者-消费者模型)时必须用ReentrantLock(synchronized仅支持wait/notify,无法分组唤醒)。JVM内存区域如何划分?各区域的作用及常见异常是什么?JVM内存分为线程共享和线程私有区域:线程共享区域:1.堆(Heap):存储对象实例和数组,是GC的主要区域。可通过-Xms(初始大小)和-Xmx(最大大小)设置。常见异常:OutOfMemoryError(OOM,内存不足时抛出)。2.方法区(MethodArea):存储类信息、常量、静态变量、即时编译后的代码等。JDK7前称为永久代(PermGen),使用堆内存;JDK8起改为元空间(Metaspace),使用本地内存。常见异常:JDK7前PermGen空间不足抛OOM,JDK8后Metaspace不足抛OOM。3.运行时常量池(RuntimeConstantPool):方法区的一部分,存储编译期提供的字面量和符号引用,JDK7起字符串常量池移至堆中。线程私有区域:1.程序计数器(ProgramCounterRegister):记录当前线程执行的字节码行号,是唯一不会抛OOM的区域。2.虚拟机栈(VMStack):存储栈帧(局部变量表、操作数栈、动态链接、方法出口等),每个方法调用对应一个栈帧入栈。常见异常:栈深度超过限制抛StackOverflowError(如递归未终止);扩展时内存不足抛OOM。3.本地方法栈(NativeMethodStack):为本地方法(如用C编写的方法)服务,与虚拟机栈类似,HotSpot虚拟机将其与虚拟机栈合并。此外,直接内存(DirectMemory)不属于JVM规范定义的区域,但通过Unsafe或NIO的ByteBuffer.allocateDirect()分配,可能导致OOM(总内存超出物理限制)。如何解决Spring中的循环依赖?三级缓存的具体作用是什么?Spring通过三级缓存解决单例Bean的循环依赖(仅支持setter注入或默认构造,不支持构造器注入)。三级缓存定义在DefaultSingletonBeanRegistry中:1.一级缓存(singletonObjects):存储已初始化完成的单例Bean(成品Bean)。2.二级缓存(earlySingletonObjects):存储提前暴露的未完全初始化的单例Bean(半成品Bean),用于解决循环依赖时获取早期引用。3.三级缓存(singletonFactories):存储ObjectFactory(Bean工厂),用于提供早期Bean引用(可能包含AOP代理)。解决流程以A→B→A为例:1.创建A时,实例化A(调用构造器),将A的ObjectFactory(λ表达式:()->getEarlyBeanReference(beanName,mbd,bean))存入三级缓存,标记A为“正在创建”。2.A需要注入B,触发B的创建流程:实例化B,将B的ObjectFactory存入三级缓存,标记B为“正在创建”。3.B需要注入A,此时A未完成初始化,从三级缓存获取A的ObjectFactory,提供早期引用(可能是代理对象),将早期引用存入二级缓存,并移除三级缓存中的A的工厂。4.B获取到A的早期引用后完成属性注入,执行初始化方法,存入一级缓存。5.A获取到B(已在一级缓存中)完成属性注入,执行初始化方法,存入一级缓存,移除二级缓存中的早期引用。三级缓存的核心作用是通过ObjectFactory延迟提供早期Bean(尤其是处理AOP代理),避免在实例化阶段就提供代理对象(可能导致未初始化的Bean被提前使用)。若仅用二级缓存,无法在实例化阶段区分是否需要代理,可能导致代理对象在初始化前被错误使用。ArrayList和LinkedList的区别是什么?如何选择?两者均实现了List接口,但底层数据结构和适用场景不同:1.数据结构:ArrayList基于动态数组(Object[]elementData),支持随机访问(通过索引O(1));LinkedList基于双向链表(Node<E>),每个节点包含前驱和后继指针。2.插入/删除性能:ArrayList在中间插入/删除需移动元素(O(n)),尾部插入(不扩容时)O(1);LinkedList插入/删除只需修改相邻节点指针(O(1),但需先定位到目标位置,若通过迭代器则O(1),通过索引则O(n))。3.内存占用:ArrayList有数组扩容的冗余空间(如初始容量10,添加第11个元素时扩容至15);LinkedList每个节点需额外存储前驱和后继指针,内存占用更高。4.线程安全:两者均非线程安全,多线程环境需用Collections.synchronizedList()包装或使用CopyOnWriteArrayList。选择建议:频繁随机访问(如遍历、按索引查询)选ArrayList;频繁在中间插入/删除(如队列、栈)选LinkedList;需注意ArrayList的扩容机制(默认初始容量10,扩容因子1.5倍),若已知数据量可通过构造函数指定初始容量减少扩容次数。volatile的作用是什么?如何保证可见性和禁止指令重排?volatile是轻量级同步机制,主要有两大作用:1.保证可见性:被volatile修饰的变量,其修改对所有线程可见。JVM通过在写操作后插入StoreStore屏障,在读操作前插入LoadLoad屏障,确保变量修改后立即刷新到主内存,其他线程读取时直接从主内存获取最新值(避免线程本地缓存的脏读)。2.禁止指令重排:通过内存屏障限制编译器和CPU的重排序优化。JVM定义了4种内存屏障(LoadLoad、LoadStore、StoreLoad、StoreStore),volatile写操作后插入StoreLoad屏障,确保写操作前的所有操作先于写操作完成;volatile读操作前插入LoadLoad屏障,确保读操作后的所有操作后于读操作完成。典型应用场景:状态标志(如线程终止标志位,用volatile修饰避免其他线程无法及时感知);单例模式的双重检查锁定(DCL),防止指令重排导致其他线程获取到未初始化的实例(需用volatile修饰单例变量)。注意:volatile不保证原子性(如i++操作包含读-改-写三步,非原子),因此无法替代synchronized或AtomicInteger在复合操作中的同步作用。如何实现一个线程安全的单例模式?枚举式单例为什么更优?常见的线程安全单例实现方式包括:1.饿汉式:类加载时初始化实例,线程安全(类加载机制保证),但可能浪费资源(未使用时已创建)。```javapublicclassSingleton{privatestaticfinalSingletonINSTANCE=newSingleton();privateSingleton(){}publicstaticSingletongetInstance(){returnINSTANCE;}}```2.懒汉式(双重检查锁定,DCL):延迟初始化,通过synchronized和volatile保证线程安全。```javapublicclassSingleton{privatestaticvolatileSingletonINSTANCE;//volatile防止指令重排privateSingleton(){}publicstaticSingletongetInstance(){if(INSTANCE==null){//第一次检查,减少锁竞争synchronized(Singleton.class){if(INSTANCE==null){//第二次检查,防止多线程同时通过第一次检查INSTANCE=newSingleton();}}}returnINSTANCE;}}```3.静态内部类:利用类加载的懒加载特性,内部类在第一次调用getInstance()时加载,线程安全。```javapublicclassSingleton{privateSingleton(){}privatestaticclassHolder{staticfinalSingletonINSTANCE=newSingleton();}publicstaticSingletongetInstance(){returnHolder.INSTANCE;}}```4.枚举式:Java枚举类默认单例,线程安全且防止反射/反序列化攻击。```javapublicenumSingleton{INSTANCE;publicvoiddoSomething(){}}```枚举式单例更优的原因:线程安全:枚举类的实例化由JVM保证,类加载时完成,无需额外同步;防止反射攻击:反射无法通过newInstance()创建枚举实例(会抛出IllegalArgumentException);防止反序列化攻击:反序列化时返回已存在的枚举实例,不会创建新对象;代码简洁,无需处理复杂的同步和单例维护逻辑。JVM的垃圾回收算法有哪些?各有什么优缺点?常见的垃圾回收算法包括:1.标记-清除(Mark-Sweep):分标记(标记存活对象)和清除(回收未标记的内存)两步。优点:实现简单,无需移动对象;缺点:产生内存碎片(可能导致大对象无法分配),效率随存活对象增加而降低。2.复制(Copying):将内存分为大小相等的两块,每次只使用一块,回收时将存活对象复制到另一块,然后清空当前块。优点:无内存碎片,复制成本与存活对象数量成正比;缺点:可用内存减半(空间浪费),适用于存活对象少的场景(如新生代)。3.标记-整理(Mark-Compact):标记存活对象后,将存活对象向内存一端移动,然后清理边界外的内存。优点:无内存碎片,空间利用率高;缺点:移动对象需调整引用,成本较高(适用于存活对象多的场景,如老年代)。4.分代收集(GenerationalCollection):根据对象存活周期分为新生代(Eden区+两个Survivor区)和老年代。新生代用复制算法(存活少,复制成本低),老年代用标记-清除或标记-整理(存活多,减少复制开销)。现代JVM(如HotSpot)采用分代收集策略:新生代(Eden:Survivor1:Survivor2=8:1:1,通过复制算法回收,存活对象进入Survivor区或老年代);老年代(对象多次MinorGC存活或大对象直接进入,用标记-整理或CMS的标记-清除)。SpringAOP的实现方式有哪些?如何选择JDK动态代理和CGLIB?SpringAOP支持两种动态代理方式:1.JDK动态代理:基于接口,通过java.lang.reflect.Proxy类提供代理对象,要求目标类实现至少一个接口。代理类会实现目标接口,重写接口方法并插入切面逻辑。2.CGLIB(CodeGenerationLibrary):基于继承,通过ASM字节码框架提供目标类的子类作为代理对象,无需目标类实现接口。子类会重写父类的非final方法,插入切面逻辑。选择依据:目标类实现了接口:默认使用JDK动态代理(Spring3.2+),可通过配置(如<aop:aspectj-autoproxyproxy-target-class="true"/>)强制使用CGLIB;目标类未实现接口:必须使用CGLIB;目标类包含final方法:CGLIB无法代理final方法(子类无法重写),JDK动态代理若接口包含final方法(Java8接口默认方法非final)则不影响;性能:JDK动态代理在调用次数较少时更快(反射调用),CGLIB通过字节码提供在调用次数较多时更优(但JDK8+优化后差距缩小)。注意:SpringBoot2.0+默认使用CGLIB(因大量类未显式实现接口),可通过xy-target-class=false配置切换为JDK动态代理。Java中的异常处理机制是什么?finally块一定会执行吗?Java异常分为Error(JVM无法处理的严重问题,如OutOfMemoryError)和Exception(程序可处理的异常)。Exception又分为CheckedException(编译期检查,需显式处理,如IOException)和UncheckedException(RuntimeException及其子类,如NullPointerException,无需显式处理)。异常处理通过try-catch-finally或throws声明实现。finally块的执行规则:正常情况下(try块无异常或catch块处理异常),finally块一定会执行;try或catch块中调用System.exit(n)(终止JVM),finally块不执行;守护线程中主线程终止,守护线程的finally块可能不执行(因JVM退出);异常未被捕获且导致线程终止,finally块仍会执行(如线程因未捕获异常终止前会执行finally)。注意:finally块中避免使用return语句(会覆盖try或catch中的返回值),例如:```javapublicinttest(){try{return1;}finally{return2;//最终返回2}}```这种写法可能导致逻辑错误,应避免在finally中使用return。NIO的核心组件有哪些?如何实现非阻塞IO?NIO(NewIO)的核心组件包括:1.Channel(通道):双向数据传输通道,支持异步读写(如FileChannel、SocketChannel、ServerSocketChannel)。2.Buffer(缓冲区):存储数据的容器,支持读/写模式切换(通过flip()方法),常用子类有ByteBuffer、IntBuffer等。Buffer的四个核心属性:capacity(容量)、limit(读写限制)、position(当前位置)、mark(标记位置)。3.Selector(选择器):管理多个Channel的事件(连接、读、写),一个线程通过Selector可监听多个Channel,实现多路复用。非阻塞IO实现流程:1.打开ServerSocketChannel,配置为非阻塞模式(channel.configureBlocking(false));2.绑定端口,创建Selector并将Channel注册到Selector(指定监听OP_ACCEPT事件);3.Selector通过select()方法阻塞等待事件(或select(longtimeout)超时等待);4.事件就绪后(如客户端连接请求),通过selectedKey
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 《GB-T 24759-2009柱坐标测量机》专题研究报告
- 《JBT 15246-2025大型卧式金属挤压机用铸钢件技术规范》专题研究报告
- 《HB 8599-2021飞机低速增压风洞高雷诺数试验模型安装要求》专题研究报告
- 档案馆内部审计制度
- 普通高中学生请假制度
- 上海市师范大学附属外国语中学2026届高三年级期末调研考试(化学试题)试卷含解析
- 九江市重点中学2025-2026学年5月高考二模生物试题含解析
- 南阳六校2026年高三下学期期末调研测试生物试题文试题含解析
- 云南省江川区第二中学2025-2026学年高三下学期适应性月考(一)生物试题含解析
- 湖南省宁乡一中2025-2026学年5月统考生物试题试卷含解析
- 湖南省新高考教学教研联盟2026届高三年级12月联考(长郡二十校联盟)数学试卷(含答案)
- 浅析国有参股企业股权管理优化方案构建与实施
- 住院患者非计划性拔管循证预防与安全管理体系构建
- 后勤工作会议讲话稿
- DB11∕T 1831-2021 装配式建筑评价标准
- 2024-2025学年度陕西能源职业技术学院单招《职业适应性测试》考试历年机考真题集(易错题)附答案详解
- 2025-2026学年度武汉市部分学校高三年级九月调研考试 数学试卷(含答案解析)
- 2025年护士长竞聘上岗理论测试题(附答案)
- 小区楼道物业清理方案(3篇)
- 保安机具管理办法
- 篮球协会各项管理制度
评论
0/150
提交评论