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

下载本文档

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

文档简介

Java高级工程师面试题及详细答案(实战版)一、Java核心基础(高频进阶)1、==和equals的区别?重写equals为什么必须重写hashCode?详细答案:==是运算符,既可以比较基本类型也可以比较引用类型。基本类型比较的是数值本身,引用类型比较的是对象的内存地址。equals是Object类的方法,原生逻辑和==一致,也是比较对象地址。大部分业务类(String、Integer、自定义实体)都会重写该方法,重写后是比较对象的内容、属性值,不再比较地址。必须重写hashCode的核心原因:Java哈希表集合(HashMap、HashSet)存储数据时,先判断hashCode是否一致,再判断equals是否相等。如果只重写equals不重写hashCode,两个内容相同的对象,会生成不同的hash值,在哈希集合中会被判定为两个不同对象,导致重复存储、去重失效,违反哈希存储规则。2、String、StringBuilder、StringBuffer的区别?业务场景怎么选?详细答案:String是不可变字符串,底层是final修饰的字符数组(JDK9+是字节数组),每次拼接、修改都会生成新对象,频繁操作会产生大量无用对象,占用内存。StringBuffer和StringBuilder是可变字符串,修改不会生成新对象。核心区别是线程安全:StringBuffer所有方法加了synchronized锁,线程安全但性能低;StringBuilder无锁,线程不安全、性能高。场景选择:1、少量字符串定义、常量赋值、无需修改:用String;2、单线程环境、频繁字符串拼接(循环拼接):优先StringBuilder;3、多线程共享、并发修改字符串场景:用StringBuffer。3、Java泛型的原理?什么是类型擦除?泛型为什么不能用基本类型?详细答案:Java泛型是编译期语法糖,核心作用是编译期类型校验、避免强制类型转换异常,提升代码复用性。类型擦除是泛型的核心原理:编译阶段完成类型校验后,编译器会擦除泛型类型,运行时JVM不识别泛型,所有泛型最终都会退化为原始类型(如List<String>擦除为List),泛型参数会被替换为Object或上界类型。泛型不能使用基本类型的原因:泛型擦除后是Object类型,而基本类型不继承Object,无法完成自动装箱适配;同时集合存储的都是对象引用,基本类型没有引用地址,所以只能使用包装类。二、JVM核心面试题(高级重点)1、JVM内存区域划分?各区域作用和OOM场景?详细答案:JVM运行时内存分为五大区域,线程私有:程序计数器、虚拟机栈、本地方法栈;线程共享:堆、元空间(JDK8替代永久代)。1、程序计数器:记录当前线程执行的字节码行号,是唯一没有OOM的内存区域;2、虚拟机栈:存储栈帧、局部变量、方法参数、返回值,方法调用和执行都依赖该区域。栈深度过大触发栈溢出(StackOverflowError),线程过多会导致栈内存溢出OOM;3、本地方法栈:服务于native本地方法,底层C/C++实现,溢出场景和虚拟机栈一致;4、堆内存:所有对象实例、数组的存储区域,是GC主要回收区域。分为新生代、老年代,对象创建过多、大对象溢出、内存泄漏都会导致堆OOM;5、元空间:存储类元数据、方法、常量、注解等,使用本地内存,默认无固定大小,动态扩容。动态生成大量类、反射、代理类过多会触发元空间OOM。2、GC垃圾回收机制?CMS和G1垃圾收集器核心区别?详细答案:GC核心是回收堆中无引用的无效对象,释放内存,避免内存溢出。判断对象存活用可达性分析算法,替代传统引用计数法,解决循环引用问题。GC分为MinorGC(新生代回收)、MajorGC(老年代回收)、FullGC(整堆回收)。CMS和G1核心区别:1、定位不同:CMS是老年代专用收集器,主打低延迟;G1是整堆收集器,兼顾吞吐量和低延迟,JDK9默认收集器;2、内存模型:CMS将堆分为新生代、老年代;G1将整个堆划分为多个大小相等的Region分区,可精准回收垃圾多的分区;3、停顿时间:CMS无法控制停顿时间,老年代越大停顿越久;G1支持设置最大停顿时间,可预判GC耗时;4、缺点差异:CMS存在内存碎片、浮动垃圾问题;G1在大吞吐量场景下性能略低于CMS,小内存堆场景优势明显。3、什么是内存泄漏?常见内存泄漏场景和排查思路?详细答案:内存泄漏指程序中已无效的对象,仍然被强引用持有,GC无法回收,长期堆积导致内存占用越来越高,最终触发OOM。常见场景:1、静态集合(staticList/Map)长期持有对象,全局不释放;2、未关闭的资源流(IO、数据库连接、Redis连接);3、线程池核心线程一直存活,持有任务对象引用;4、匿名内部类、异步线程持有外部类引用;5、缓存无过期策略,无限堆积数据。排查思路:1、通过jps、jstat查看进程内存、GC频率,判断是否频繁FullGC;2、jmap导出堆快照,用MAT、JProfiler分析大对象、常驻对象;3、排查静态资源、缓存、线程引用,定位无法回收的对象;4、结合日志、接口监控,定位内存持续上涨的业务接口。三、Java并发编程(高级核心)1、synchronized和Lock的区别?底层原理是什么?详细答案:核心区别:1、语法层面:synchronized是JVM原生关键字,隐式加锁解锁;Lock是Java代码层面的接口,需要手动lock()、unlock(),灵活性更高;2、锁特性:synchronized是可重入、不可中断、非公平锁;Lock(ReentrantLock)支持可重入、可中断、可公平/非公平锁,可实现读写锁;3、条件等待:synchronized只有一个wait()等待队列;Lock可以创建多个Condition条件队列,精准唤醒指定线程;4、性能:JDK1.6之后synchronized做了偏向锁、轻量级锁、重量级锁优化,性能基本和Lock持平,低并发场景更优。底层原理:synchronized基于对象头的MarkWord实现,通过锁升级机制(偏向锁→轻量级锁→重量级锁)适配不同并发场景;ReentrantLock基于AQS(抽象队列同步器)实现,通过CAS自旋+双向阻塞队列,完成锁的抢占、等待、唤醒。2、线程池核心参数?为什么不推荐使用Executors创建线程池?详细答案:线程池七大核心参数:核心线程数、最大线程数、空闲线程存活时间、时间单位、任务队列、线程工厂、拒绝策略。执行流程:任务提交后,先判断核心线程数是否满,未满则创建核心线程执行;核心线程满则进入任务队列;队列满则创建非核心线程;达到最大线程数则触发拒绝策略。不推荐Executors的原因:1、newFixedThreadPool、newSingleThreadExecutor:任务队列为无界队列,任务堆积过多会导致内存溢出;2、newCachedThreadPool、newScheduledThreadPool:最大线程数为Integer最大值,高并发下会创建大量线程,导致CPU耗尽、线程溢出;生产环境必须手动创建ThreadPoolExecutor,自定义参数和有界队列,规避风险。3、volatile关键字的作用?能不能保证线程安全?详细答案:volatile有两大核心作用:保证可见性、禁止指令重排序。1、可见性:一个线程修改volatile变量,会立即刷新到主内存,其他线程会从主内存读取最新值,避免缓存过期;2、禁止重排序:编译器和CPU不会对volatile修饰的变量做指令重排,解决单例模式双重检查锁的空指针问题。volatile不能保证线程安全,只能保证单次读写可见。对于i++、复合赋值等读写复合操作,无法保证原子性,多线程下依然会出现数据不一致,这类场景需要用synchronized或Atomic原子类。四、Spring核心原理1、SpringIOC容器原理?Bean的生命周期?详细答案:IOC即控制反转,核心是将对象的创建、依赖注入、生命周期管理交给Spring容器管理,替代开发者手动new对象,实现解耦。底层基于工厂模式、反射、配置解析实现。Bean完整生命周期:1、配置加载:Spring启动扫描注解/XML配置,解析Bean定义信息;2、实例化:通过反射创建Bean对象(无参构造);3、属性填充:完成依赖注入(@Autowired、set方法);4、初始化前置处理:执行BeanPostProcessor前置方法;5、初始化:执行InitializingBean、自定义init方法;6、初始化后置处理:执行BeanPostProcessor后置方法;7、销毁:容器关闭时,执行DisposableBean、自定义destroy方法。2、SpringAOP原理?动态代理JDK和CGLIB区别?详细答案:AOP是面向切面编程,核心是在不修改原有业务代码的前提下,对方法进行增强,用于日志、事务、权限、限流等通用功能,底层基于动态代理实现。JDK动态代理vsCGLIB:1、实现方式:JDK代理基于接口实现,只能代理实现接口的类;CGLIB基于字节码增强,继承目标类生成子类代理,无需接口;2、性能:JDK8+JDK代理性能优于CGLIB;低版本CGLIB更优;3、限制:JDK无法代理无接口类、私有方法;CGLIB无法代理final类和final方法;Spring默认规则:目标类有接口用JDK代理,无接口用CGLIB;SpringBoot2.0+默认统一使用CGLIB。3、Spring事务传播机制和隔离级别?事务失效场景有哪些?详细答案:7种传播机制(核心常用):1、REQUIRED:默认,有事务加入,无事务新建;2、SUPPORTS:有事务加入,无事务非事务运行;3、REQUIRES_NEW:新建独立事务,挂起原有事务;4、NESTED:嵌套事务,依赖父事务,可独立回滚子事务;4种隔离级别:读未提交、读已提交、可重复读、串行化,默认可重复读。常见事务失效场景:1、方法非public修饰;2、同类中方法内部调用(绕过AOP代理);3、异常被try-catch捕获,未抛出;4、传播机制配置不当;5、数据库引擎不支持事务(MyISAM)。五、数据库MySQL面试题1、InnoDB引擎特性?聚簇索引和非聚簇索引区别?详细答案:InnoDB是MySQL默认引擎,支持事务、行级锁、外键、MVCC多版本并发控制、崩溃恢复,适合高并发业务场景。索引区别:1、聚簇索引:主键索引,叶子节点存储完整行数据,一张表只有一个,数据和索引绑定存储;2、非聚簇索引(二级索引):普通索引、唯一索引,叶子节点只存储索引列值和主键值,查询数据需要回表查询;主键查询直接命中聚簇索引,无需回表;普通索引查询会先走二级索引,再通过主键回表取数据,覆盖索引可以避免回表。2、慢SQL优化思路?索引失效场景有哪些?详细答案:慢SQL优化步骤:1、通过慢查询日志、explain分析SQL执行计划,定位全表扫描、未使用索引、回表过多问题;2、优化索引:建立联合索引、覆盖索引,避免冗余索引;3、优化SQL语句:避免select*、避免子查询嵌套、拆分大事务、分页优化;4、架构优化:分库分表、读写分离、缓存兜底。索引失效常见场景:1、索引列使用函数、运算、类型转换;2、like%前缀模糊查询;3、or左右字段无全部建立索引;4、联合索引不遵循最左匹配原则;5、数据量过少、索引区分度极低,MySQL优化器放弃索引。3、MVCC多版本并发控制原理?解决什么问题?详细答案:MVCC是InnoDB实现事务隔离的核心机制,通过数据多版本、undolog日志、readview视图,实现无锁读写,提升并发性能。核心原理:每条数据都有隐藏字段(事务ID、回滚指针),数据修改时不会直接覆盖旧数据,而是生成新数据版本,旧数据存入undolog。读操作读取符合当前事务视图的历史版本数据,写操作操作最新版本。解决问题:1、解决读写冲突,实现读不加锁、写加锁不阻塞读;2、实现读已提交、可重复读两种隔离级别;3、有效降低数据库锁竞争,提升高并发吞吐量。六、Redis核心面试题1、Redis缓存穿透、击穿、雪崩解决方案?详细答案:缓存穿透:查询数据库和缓存都不存在的数据,绕过缓存直接打数据库。解决方案:缓存空值、布隆过滤器、接口参数校验、限流拦截非法请求。缓存击穿:热点key过期瞬间,大量并发请求直接访问数据库。解决方案:热点key永不过期、互斥锁(分布式锁)、后台定时续期。缓存雪崩:大量key同时过期、Redis宕机,导致所有请求直达数据库,压垮数据库。解决方案:过期时间随机打散、Redis集群高可用、多级缓存、服务熔断降级、限流。2、Redis分布式锁实现原理?Redisson优势?详细答案:原生Redis分布式锁基于SETkeyvalueNXEX实现,NX保证不存在才创建(加锁),EX设置过期时间,避免死锁。原生锁存在问题:锁超时误释放、不可重入、主从切换锁失效、无法续期。Redisson基于原生锁做了全方位优化:支持可重入、公平锁、读写锁;提供watchdog看门狗自动续期,避免业务未执行完锁过期;支持锁可中断、重试机制;基于Redlock算法解决主从集群锁失效问题,适配生产高并发场景。七、微服务&中间件高频题1、SpringCloud核心组件及作用?详细答案:1、Nacos:服务注册发现、配置中心,替代Eureka+Config,支持动态配置刷新;2、Gateway:网关,负责路由转发、限流、熔断、鉴权、请求过滤;3、OpenFeign:声明式远程调用,简化微服务之间的接口调用;4、Sentinel:流量控制组件,实现限流、熔断、降级、热点参数限流,保障服务稳定性;5、Ribbon:客户端负载均衡,实现服务集群请求分发;6、Seata:分布式事务解决方案,

温馨提示

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

评论

0/150

提交评论