Java实战高频面试题及详细答案(企业真实版)_第1页
Java实战高频面试题及详细答案(企业真实版)_第2页
Java实战高频面试题及详细答案(企业真实版)_第3页
Java实战高频面试题及详细答案(企业真实版)_第4页
Java实战高频面试题及详细答案(企业真实版)_第5页
已阅读5页,还剩3页未读, 继续免费阅读

下载本文档

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

文档简介

Java实战高频面试题及详细答案(企业真实版)一、Java基础核心面试题1.==和equals()的区别?工作中怎么用?详细答案:1、对于基本数据类型:==比较的是数值本身,基本类型没有equals方法。2、对于引用数据类型:==比较的是对象内存地址,equals默认也是比较内存地址,但很多类重写了该方法。3、String、Integer、Date等常用类都重写了equals方法,重写后比较的是内容值,不再比较地址。工作场景用法:比较字符串、对象内容是否一致,一律用equals;判断两个对象是否是同一个对象(地址一致),用==。同时为了避免空指针,日常开发会写常量在前的写法:"test".equals(str)。2.String、StringBuilder、StringBuffer的区别?线上场景如何选型?详细答案:1、String:不可变字符串,每次拼接、修改都会生成新字符串对象,频繁操作会产生大量垃圾对象,性能最差。2、StringBuilder:可变字符串,线程不安全,没有锁机制,拼接性能最高。3、StringBuffer:可变字符串,线程安全,方法加了synchronized锁,多线程环境下不会出现数据错乱,但性能偏低。线上选型原则:绝大多数业务场景(接口、业务逻辑、单线程字符串拼接)用StringBuilder;只有多线程共享字符串变量的场景,才用StringBuffer;固定不变的文本、配置文案直接用String。3.final、finally、finalize的区别?详细答案:1、final:修饰符,用于修饰变量、方法、类。final变量不可二次赋值,final方法不可重写,final类不可被继承。日常开发常用final修饰常量、工具类,提升代码安全性。2、finally:异常处理关键字,和try-catch配合使用。无论代码正常执行还是抛出异常,finally代码块一定会执行(除JVM强制退出场景),主要用于关闭流、释放资源、关闭数据库连接等操作。3、finalize:Object类的废弃方法,JVM垃圾回收前会调用该方法用于对象资源回收。该方法执行时机不确定、不可靠,日常开发绝对不使用,已经被废弃。4.接口和抽象类的区别?实际业务中怎么选?详细答案:核心区别:1、抽象类:有构造方法,可以包含普通成员变量、普通方法、抽象方法,单继承机制。2、接口:没有构造方法,JDK8前只有抽象方法,JDK8支持默认方法、静态方法,JDK9支持私有方法,多实现机制,不能定义普通成员变量,只能定义常量。业务选型:1、定义行为规范、功能约束,让多个无关类实现统一功能,用接口(比如支付接口、消息推送接口)。2、存在父子层级关系、公共代码复用,需要抽取通用属性和通用方法,用抽象类(比如通用业务父类、模板父类)。二、Java集合高频面试题1.ArrayList和LinkedList的区别?随机访问和频繁增删选哪个?详细答案:1、底层结构:ArrayList基于动态数组,LinkedList基于双向链表。2、访问效率:ArrayList支持下标随机访问,查询速度极快;LinkedList只能从头结点遍历,查询效率极低。3、增删效率:ArrayList中间、头部增删需要移动大量元素,效率低;LinkedList只需要修改节点指针,首尾增删效率高。4、内存占用:ArrayList会预留扩容空间,存在内存冗余;LinkedList每个节点存储数据和指针,单个元素内存占用更大。开发选型:95%业务场景用ArrayList;只有高频首尾增删、极少查询的场景,才用LinkedList。2.HashMap底层原理?JDK1.8做了哪些优化?详细答案:底层原理:HashMap基于「数组+链表+红黑树」实现,通过hash算法计算key的哈希值,定位数组下标,实现快速存取。当出现hash冲突时,同一下标元素以链表形式存储。JDK1.8核心优化:1、数据结构优化:由JDK1.7的「数组+单向链表」升级为「数组+单向链表+红黑树」。2、树化阈值:当链表长度超过8且数组容量大于64时,链表转为红黑树,将查询时间复杂度从O(n)优化为O(logn)。3、简化hash计算:优化哈希扰动算法,减少哈希冲突概率。4、扩容优化:新增高低位链表拆分机制,避免JDK1.7多线程扩容出现的循环链表死循环问题(但HashMap依旧线程不安全)。3.HashMap为什么线程不安全?并发场景用什么替代?详细答案:不安全原因:1、多线程同时put数据时,会出现数据覆盖,导致数据丢失。2、JDK1.7多线程扩容会产生循环链表,触发死循环、CPU飙高问题。3、多线程同时扩容、插入,会出现null数据、元素缺失等异常。并发替代方案:1、ConcurrentHashMap:分段锁机制(JDK1.7)、CAS+synchronized锁(JDK1.8),并发性能极高,是业务首选。2、Hashtable:全表锁,并发性能极差,基本废弃,不推荐使用。三、多线程与并发面试题1.线程和进程的区别?详细答案:1、进程:操作系统资源分配的最小单位,相互独立,拥有独立内存空间,一个进程崩溃不影响其他进程。2、线程:CPU调度的最小单位,依附进程存在,共享进程的内存资源,一个线程异常崩溃,会导致整个进程终止。3、开销:进程创建、销毁开销大;线程开销极小,切换速度快。4、通信:进程间通信复杂;线程间共享变量即可通信,简单高效。2.synchronized和Lock的区别?项目中如何选择?详细答案:核心区别:1、出身不同:synchronized是JVM原生关键字,底层由虚拟机实现;Lock是Java接口(ReentrantLock是常用实现类),代码层面实现锁机制。2、锁特性:synchronized是隐式锁,自动加锁、自动释放锁;Lock是显式锁,需要手动lock()加锁、unlock()释放锁。3、功能差异:synchronized不支持超时锁、不支持可中断锁、非公平锁;Lock支持超时等待、可中断、可实现公平锁、可绑定多个条件变量。4、性能:低并发场景两者性能接近,高并发下ReentrantLock性能更优。业务选型:简单同步场景、保证原子性、一致性,直接用synchronized;需要锁超时、公平锁、可中断锁、精细化锁控制的复杂并发场景,用ReentrantLock。3.线程池核心参数?为什么不推荐使用Executors创建线程池?详细答案:线程池七大核心参数:1、核心线程数:线程池常驻线程,即使空闲也不会回收。2、最大线程数:线程池允许创建的最大线程数量。3、空闲超时时间:非核心线程空闲超时后会被回收。4、时间单位:超时时间的单位。5、阻塞队列:存储等待执行的任务。6、线程工厂:创建线程的工厂,可自定义线程名称、优先级。7、拒绝策略:任务超出线程池承载能力时的处理策略。不推荐Executors的原因:Executors创建的线程池参数默认,存在线上风险:newFixedThreadPool、newSingleThreadExecutor队列无界,任务堆积会导致OOM;newCachedThreadPool最大线程数无上限,高并发会创建大量线程,导致CPU爆满、服务宕机。开发规范:生产环境必须通过ThreadPoolExecutor手动创建线程池,自定义参数和拒绝策略。四、JVM核心面试题1.JVM内存区域划分及各区域作用?详细答案:1、程序计数器:线程私有,记录当前线程执行的字节码行号,是唯一没有内存溢出的区域。2、虚拟机栈:线程私有,存储局部变量、方法栈帧、操作数栈,方法执行完毕自动释放,栈深过大会抛出StackOverflowError。3、本地方法栈:线程私有,为JNI本地方法服务,作用和虚拟机栈类似。4、堆内存:线程共享,所有对象、数组都在堆中分配,是垃圾回收的核心区域,堆内存不足抛出OOM。5、方法区(元空间):线程共享,存储类信息、常量、静态变量、编译后的代码,JDK1.8后永久代改为元空间,使用本地内存,减少OOM概率。2.垃圾回收GC机制?哪些对象会被回收?详细答案:GC是JVM自动回收堆中无效对象内存的机制,无需手动释放,避免内存泄漏。可被回收的对象:没有任何有效引用指向的对象,常见场景:1、对象引用置为null;2、对象超出作用域;3、集合移除元素、清空集合;4、弱引用、软引用对象在内存不足时被回收。GC分类:MinorGC(新生代回收,频率高、速度快)、FullGC(老年代+整堆回收,耗时久、线上尽量避免)。3.常见OOM原因及线上排查思路?详细答案:常见OOM场景:1、堆内存溢出:创建大量对象、集合无限添加元素、内存泄漏。2、元空间溢出:动态生成大量类、频繁热部署。3、栈溢出:递归死循环、方法嵌套过深。4、直接内存溢出:NIO未释放直接内存。线上排查思路:1、查看日志确定OOM类型;2、导出堆快照,使用MAT、JProfiler分析大对象、泄漏对象;3、排查代码是否存在集合未清空、静态集合常驻内存、循环创建对象问题;4、调整JVM参数,优化堆内存、元空间大小。五、Spring核心面试题1.SpringIOC原理?Bean的生命周期?详细答案:IOC核心原理:控制反转,将对象的创建、管理、依赖注入全权交给Spring容器,不再由开发者手动new对象,降低代码耦合度。核心是工厂模式+反射+配置解析。Bean完整生命周期:1、加载配置,扫描注解/配置文件,解析Bean定义;2、实例化Bean(反射创建对象);3、属性填充(依赖注入);4、初始化前置处理(BeanPostProcessor前置方法);5、初始化方法执行(init-method、InitializingBean);6、初始化后置处理;7、Bean就绪,存入容器;8、容器关闭时,执行销毁方法。2.SpringAOP原理及应用场景?详细答案:AOP原理:面向切面编程,基于动态代理机制,在不修改原有业务代码的前提下,对方法进行增强。目标类有接口用JDK动态代理,无接口用CGLIB代理。核心应用场景:统一日志记录、统一权限校验、事务控制、接口限流、性能监控、参数校验、异常统一处理,实现业务代码和通用功能解耦。3.Spring事务传播机制?常用的3种及实战场景?详细答案:Spring事务传播机制用于控制嵌套调用时事务的传递规则,常用核心三种:1、REQUIRED(默认):当前有事务就加入,没有就新建事务。绝大多数业务增删改接口使用。2、SUPPORTS:当前有事务就加入,没有就非事务运行。适合查询接口。3、REQUIRES_NEW:新建独立事务,挂起当前事务。适合独立日志记录、异步备份,主事务回滚不影响该事务。常见事务失效场景:方法非public、内部调用、try-catch捕获异常、传播机制配置错误。六、Java实战场景面试题(项目高频)1.项目中如何解决接口重复提交问题?详细答案:结合业务层级采用多层方案,生产常用组合方案:1、前端拦截:按钮点击后置灰、禁用,防止连续点击。2、后端令牌机制:接口请求前获取唯一令牌,提交时校验令牌,校验通过且删除令牌,重复提交令牌失效。3、Redis幂等锁:以「用户ID+接口标识+唯一参数」为key,请求成功后设置短暂过期时间,重复请求直接拦截。2.如何避免Redis缓存穿透、击穿、雪崩?详细答案:1、缓存穿透(查询不存在数据,直接打穿到数据库)解决方案:缓存空值、布隆过滤器、接口参数校验拦截非法请求。2、缓存击穿(热点key过期,瞬时大量请求打向数据库)解决方案:热点key永不过期、互斥锁(分布式锁)、定时预热刷新热点缓存。3、缓存雪崩(大量key同时过期/Redis宕机,大量请求

温馨提示

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

评论

0/150

提交评论