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

下载本文档

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

文档简介

Java高频模拟面试题及详细答案(企业真实版)本次面试题贴合一线互联网、传统软件企业真实面试场景,剔除书面化套话,答案为程序员面试口述标准版,涵盖Java基础、核心特性、集合框架、多线程、JVM、Spring核心、数据库交互、实战问题八大模块,适合中级及以下Java开发者面试备考。一、Java基础语法与核心特性1、==和equals的区别是什么?这是Java最基础的高频题,核心区别分为比较规则和适用场景:第一,==是运算符,可以用于基本数据类型和引用数据类型。基本类型比较的是数值本身,比如int、long、boolean;引用类型比较的是内存地址,也就是判断两个对象是不是同一个对象。第二,equals是Object类的方法,只适用于引用数据类型。默认情况下和==效果一致,也是比较内存地址。但像String、Integer这些常用类,都重写了equals方法,重写后不再比较地址,而是比较对象的内容、数值是否相等。举个实际例子:newString("abc")==newString("abc")结果是false,因为两个对象地址不同;但equals比较结果是true,因为字符串内容一致。2、String、StringBuilder、StringBuffer的区别?三者核心差异在可变性、线程安全、执行效率三个维度:1、String:字符串常量,底层是final修饰的字符数组,不可变。每次拼接、修改字符串都会生成新的String对象,频繁操作会产生大量垃圾对象,效率最低。2、StringBuilder:可变字符串,底层数组可扩容,线程不安全,没有加锁。单线程环境下字符串拼接、修改效率最高,日常开发单线程场景优先使用。3、StringBuffer:可变字符串,方法都加了synchronized锁,线程安全。多线程并发操作字符串时不会出现数据错乱,但加锁会带来性能损耗,效率低于StringBuilder。实际开发选型:单线程用StringBuilder,多线程用StringBuffer,固定不变的字符串直接用String。3、final、finally、finalize的区别?三个单词只是拼写相近,功能完全无关,是面试高频易混题:1、final:是修饰符,可以修饰类、方法、变量。修饰类则类不能被继承;修饰方法则方法不能被重写;修饰变量则变量一旦赋值不能修改(基本类型值不变,引用类型地址不变)。2、finally:是异常处理的关键字,搭配try-catch使用。作用是无论代码正常执行还是抛出异常,最终都会执行,唯一不执行的场景是调用了System.exit(0)退出虚拟机。主要用于释放资源,比如关闭流、关闭数据库连接。3、finalize:是Object类的废弃方法,JDK9之后已被废弃。原本设计是垃圾回收器回收对象前,触发该方法让对象完成资源释放,但执行时机不确定、无法保证调用,实际开发中完全不用。4、接口和抽象类的区别?1、定义与修饰:抽象类用abstract修饰,可以包含普通成员变量、构造方法、静态方法、抽象方法、普通实例方法;接口默认是publicabstract,JDK8之前只有抽象方法,JDK8支持默认方法、静态方法,JDK9支持私有方法,不能有普通成员变量,只能有常量。2、继承规则:类只能单继承一个抽象类,但可以多实现多个接口,解决了单继承的局限性。3、构造方法:抽象类有构造方法,用于子类初始化父类成员;接口没有构造方法,不能实例化。4、设计思想:抽象类是模板复用,提取子类的公共代码和通用属性;接口是行为规范,定义类必须实现的功能,不关注属性和实现细节。二、集合框架核心面试题1、ArrayList和LinkedList的区别?底层结构决定了两者的性能差异,是集合最常问的题目:1、底层结构:ArrayList基于动态数组实现;LinkedList基于双向链表实现。2、查询效率:ArrayList支持随机访问,通过下标直接定位元素,查询速度极快;LinkedList只能从头节点或尾节点遍历查找,查询效率极低。3、增删效率:ArrayList中间、头部增删元素需要移动大量数组元素,效率低;尾部新增速度很快。LinkedList任意位置增删只需要修改节点指针,不需要移动元素,增删效率更高。4、内存占用:ArrayList数组会预留扩容空间,存在内存冗余;LinkedList每个节点都要存储前后节点引用,单个元素占用内存更大。开发选型:查询多、增删少用ArrayList,频繁中间增删用LinkedList,日常90%场景都是用ArrayList。2、HashMap的底层原理?JDK1.8做了哪些优化?HashMap是面试重中之重,底层核心是数组+链表+红黑树,基于哈希表实现。存储流程:通过key的hash值计算数组下标,如果下标位置没有元素,直接存入;如果有元素,发生哈希冲突,挂载链表上;当链表长度大于阈值8、数组容量大于64时,链表转换为红黑树,提升查询效率;当链表长度小于6时,红黑树退化为链表。JDK1.8核心优化点:1、数据结构优化:由JDK1.7的「数组+单向链表」升级为「数组+链表+红黑树」,解决大量哈希冲突后链表过长、查询效率极低的问题。2、哈希算法优化:简化了hash计算逻辑,减少哈希冲突概率。3、扩容优化:JDK1.7扩容时会重新计算所有元素hash位置,容易出现链表死循环;JDK1.8优化了迁移逻辑,保证高低位元素位置不变,避免循环链表问题。4、插入方式优化:由头插法改为尾插法,规避并发扩容的死循环风险。3、HashMap和HashTable、ConcurrentHashMap的区别?1、HashMap:线程不安全,效率高,允许key和value为null,初始容量16,默认扩容2倍。2、HashTable:线程安全,效率极低,所有方法都加了全局synchronized锁,并发时所有线程竞争同一把锁,阻塞严重,基本已被淘汰,不允许key、value为null。3、ConcurrentHashMap:JDK1.8主流并发集合,线程安全且效率高。底层采用CAS+synchronized分段锁,只锁住当前哈希桶位置,不会全局阻塞,并发性能远超HashTable,是多线程场景下HashMap的首选替代方案。三、多线程核心面试题1、线程和进程的区别?1、进程是操作系统资源分配的最小单位,线程是CPU调度的最小单位。2、进程相互独立,拥有独立的内存空间,一个进程崩溃不会影响其他进程;线程共享所在进程的堆内存、方法区资源,一个线程异常崩溃,整个进程都会终止。3、进程创建、销毁开销极大;线程创建、切换、销毁开销很小,轻量化。4、进程之间通信复杂,需要管道、socket等方式;线程之间通信简单,直接共享变量即可。2、synchronized和Lock的区别?两者都是Java解决线程安全的锁机制,核心区别如下:1、底层实现:synchronized是JVM原生锁,底层依赖操作系统实现;Lock是Java代码层面的锁,基于AQS队列同步器实现。2、锁特性:synchronized是隐式锁,自动加锁、自动释放锁,无法中断等待线程;Lock是显式锁,需要手动lock()加锁、unlock()释放锁,支持中断等待、超时等待。3、锁机制:synchronized是非公平锁,不可重入(底层支持可重入但无法配置);ReentrantLock支持公平锁和非公平锁切换,支持可重入。4、功能拓展:Lock可以绑定多个条件变量,实现精准唤醒指定线程;synchronized只能随机唤醒一个或全部唤醒线程。日常开发:简单同步场景用synchronized,复杂并发、需要超时、公平锁场景用Lock。3、线程的生命周期有哪些状态?Java线程一共5种核心状态:1、新建(NEW):创建线程对象,未调用start()方法。2、就绪(RUNNABLE):调用start()后,等待CPU调度,随时可以执行。3、运行(RUNNING):CPU分配时间片,线程正在执行代码。5、终止(TERMINATED):线程代码执行完毕或异常终止,生命周期结束。四、JVM核心面试题1、JVM内存区域分为哪几块?各自作用?JVM运行时数据区分为5个区域,其中线程私有3个,线程共享2个:线程私有(随线程创建销毁):1、程序计数器:记录当前线程执行的字节码行号,是唯一没有内存溢出的区域。2、虚拟机栈:存储方法栈帧、局部变量、方法返回值,方法调用即入栈,执行结束即出栈。栈内存过小会抛出StackOverflowError。3、本地方法栈:作用和虚拟机栈一致,专门为Native本地方法服务。线程共享(全局唯一):1、堆内存:所有对象、数组的创建都在堆中,是垃圾回收的主要区域,也是最容易发生OOM的区域。2、方法区(元空间):存储类信息、常量、静态变量、编译后的代码,JDK1.8后由永久代改为元空间,使用本地内存,不再受JVM堆限制。2、GC垃圾回收的原理?哪些对象会被回收?GC核心是回收堆中没有任何引用指向的无效对象,释放内存空间,避免内存泄漏。判断对象可回收的核心算法是可达性分析:以GCRoots为起点遍历内存,能遍历到的对象就是存活对象,没有遍历到的对象就是无效对象,会被GC回收。常见GCRoots:虚拟机栈中引用的对象、静态变量引用的对象、常量引用对象、本地方法栈引用对象。不会被回收的对象:被有效引用、作为GCRoots、正在使用的对象。3、MinorGC、MajorGC、FullGC的区别?1、MinorGC:新生代垃圾回收,频率高、速度快,触发频繁,清理Eden区和幸存区无效对象,不会影响老年代。2、MajorGC:老年代垃圾回收,频率低、速度慢,通常伴随MinorGC触发。3、FullGC:全堆回收,清理新生代、老年代、元空间所有无效对象,暂停所有用户线程,性能开销极大,线上项目要尽量避免频繁FullGC。五、Spring核心面试题1、SpringIOC的原理?IOC即控制反转,是Spring的核心思想。传统开发是开发者主动new对象、管理对象依赖;IOC是将对象的创建、初始化、依赖管理、销毁全部交给Spring容器,控制权从开发者反转给容器。底层实现流程:1、项目启动时,Spring扫描所有加了注解的类(@Component、@Service等);2、通过反射创建类的实例对象;3、解析对象的依赖关系,自动完成依赖注入(DI);4、将所有对象统一存入IOC容器统一管理,随用随取。核心作用:解耦代码,不用手动管理对象依赖,大幅提升开发效率。2、SpringBean的生命周期?完整生命周期分为6步,面试口述核心流程即可:1、实例化:Spring通过反射创建Bean对象实例;2、属性填充:自动完成依赖注入,给对象赋值;3、初始化前置处理:执行Bean后置处理器的前置方法;4、初始化:执行InitializingBean的初始化方法、自定义init方法;5、初始化后置处理:执行Bean后置处理器后置方法,完成Bean增强(AOP代理在此步骤实现);6、销毁:容器关闭时,执行DisposableBean销毁方法、自定义destroy方法。3、SpringAOP的原理和应用场景?AOP即面向切面编程,核心是在不修改原有业务代码的前提下,对方法进行增强,实现业务与通用逻辑解耦。底层原理:动态代理。目标类有接口则用JDK动态代理,没有接口则用CGLIB字节码增强代理。常用应用场景:统一日志记录、事务控制、权限校验、接口限流、性能监控、异常统一处理。六、数据库与MyBatis面试题1、MyBatis#{}和${}的区别?1、#{}:预编译占位符,底层会生成PreparedStatement,可以防止SQL注入,会自动给字符串加引号、转义特殊字符,日常参数查询优先使用。2、${}:直接字符串拼接,没有预编译,存在严重的SQL注入风险,不会自动加引号。使用场景:普通查询、条件参数用#{};动态排序、动态表名、列名场景只能用${},使用时需要手动校验参数,防止注入。2、数据库事务四大特性ACID?1、原子性(Atomicity):事务是最小执行单元,要么全部执行成功,要么全部回滚,不能部分执行。2、一致性(Consistency):事务执行前后,数据库数据完整性、约束规则保持一致,不会出现非法数据。3、隔离性(Isolation):多个事务并发执行时,相互独立互不干扰,通过事务隔离级别控制并发问题。4、持久性(Durability):事务提交成功后,数据永久落地,即使服务器宕机、重启,数据也不会丢失。七、实战高频场景题1、什么是内存泄漏?常见Java内存泄漏场景?内存泄漏指:对象已经没有业务用途,但是仍然存在有效引用,GC无法回收,长期堆积导致内存占用过高,最终引发OOM。常见场景:1、静态集合类(staticList/Map)长期持有对象,静态变量生命周期和项目一致,不会被回收;2、未关闭

温馨提示

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

评论

0/150

提交评论