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

下载本文档

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

文档简介

Java开发面试题及详细答案(真实面试版)一、Java基础核心面试题1.说说==和equals的区别这是Java最基础的高频考点,核心区别是比较的内容不一样:==是运算符,针对基本数据类型和引用类型有不同逻辑:基本类型比较的是数值本身;引用类型比较的是对象的内存地址。equals是Object类的方法,默认逻辑和==一致,也是比较对象地址。但像String、Integer、自定义实体类都会重写这个方法,重写后不再比较地址,只比较对象的内容、属性值。举个实际场景:newString("abc")=="abc"结果是false,因为地址不同;但两者equals对比是true,因为字符串内容一致。2.String、StringBuilder、StringBuffer的区别核心差异在可变性、线程安全、性能三个维度:String是不可变字符串,底层是final修饰的字符数组。每次拼接、修改字符串都会生成新对象,频繁操作会产生大量垃圾对象,性能最差。适用于少量字符串操作、常量定义场景。StringBuilder是可变字符串,底层数组可扩容,操作不会新建对象。非线程安全,多线程并发操作会出现数据错乱,但单线程下性能最好,日常开发90%场景都用它。StringBuffer同样是可变字符串,所有方法都加了synchronized锁,线程安全。但锁会带来性能损耗,效率低于StringBuilder,仅适用于多线程并发操作字符串的场景。3.final、finally、finalize的区别三个单词看似相似,完全没有关联,是高频易混题:final是修饰符,可以修饰类、方法、变量。修饰类则类不能被继承;修饰方法则方法不能被重写;修饰变量则变量一旦赋值不可修改(基本类型值不变,引用类型地址不变)。finally是异常处理的关键字,搭配try-catch使用。作用是无论代码是否抛出异常,最终都会执行,常用于释放资源(关闭流、数据库连接),唯一不执行的场景是调用了System.exit(0)退出程序。finalize是Object类的废弃方法,JDK9之后已废弃。原本设计是GC回收对象前触发该方法,用于自定义资源释放,但执行时机不确定、无法保证调用,实际开发没人使用。4.接口和抽象类的区别1.定义约束不同:抽象类用abstract修饰,可包含普通成员变量、构造方法、抽象方法、普通方法;接口(JDK8之前)只能有常量和抽象方法,JDK8后支持默认方法、静态方法,JDK9支持私有方法,不能有构造方法和成员变量。2.继承规则不同:类只能单继承一个抽象类,但可以多实现多个接口,解决了单继承的局限性。3.设计思想不同:抽象类是模板复用,抽取子类通用代码、通用属性;接口是行为规范,定义统一的功能标准,不关心实现细节。4.访问修饰符不同:抽象类方法可以用public、protected、默认权限;接口方法默认public,不能使用私有、受保护权限。二、Java集合框架面试题1.ArrayList和LinkedList的区别及使用场景底层结构是核心差异,直接决定性能和使用场景:ArrayList底层是动态数组,内存连续。优点是随机查询、遍历速度极快,通过下标可直接定位元素;缺点是增删元素时需要移动数组元素,扩容还会复制新数组,效率低。LinkedList底层是双向链表,内存不连续,每个节点存储前后节点引用。优点是首尾增删元素效率极高,无需移动数据;缺点是随机查询需要从头遍历,查询效率极差。实际开发场景:绝大多数查询、遍历多、增删少的场景用ArrayList;频繁首尾增删、极少查询的场景用LinkedList。2.HashMap的底层原理(JDK1.8)HashMap底层是数组+链表+红黑树的结构,核心是哈希寻址、冲突解决、树化优化:1.存储结构:主体是哈希数组,数组每个位置称为桶。当发生哈希冲突时,同一桶位的元素以链表形式存储;当链表长度大于8,且数组容量大于64时,链表会转换为红黑树,降低查询时间复杂度。2.存取流程:put元素时,先通过key的hash值计算数组下标;如果桶位为空,直接存入元素;如果有元素,判断key是否相同,相同则覆盖值,不同则挂在链表末尾。3.扩容机制:默认初始容量16,负载因子0.75。当元素数量超过容量*负载因子时触发扩容,容量翻倍,所有元素重新哈希寻址。4.时间复杂度:无哈希冲突时查询、插入O(1);链表结构O(n);红黑树结构O(logn)。3.HashMap和ConcurrentHashMap的区别1.线程安全:HashMap非线程安全,多线程put、扩容会出现数据覆盖、死循环问题,不能用于并发场景;ConcurrentHashMap是线程安全的并发集合。2.加锁方式:JDK1.8的ConcurrentHashMap采用分段锁+CAS+synchronized,只锁住当前操作的桶位,不影响其他桶位操作,并发性能极高。摒弃了1.7的分段数组锁,锁粒度更细。3.空值支持:HashMap允许key、value为null;ConcurrentHashMap不允许key和value为null,避免并发场景空指针歧义。4.使用场景:单线程场景用HashMap;多线程高并发存取场景用ConcurrentHashMap。三、JVM与GC面试题1.JVM内存区域划分及各区域作用JVM运行时数据区分为线程私有和线程共享两大块:线程私有(随线程创建销毁):1.程序计数器:记录当前线程执行的字节码行号,线程切换后恢复执行位置,是唯一没有OOM的区域。2.虚拟机栈:存储局部变量、方法参数、操作数栈、方法返回地址,方法调用入栈,执行结束出栈,栈深度过大会抛出栈溢出异常。3.本地方法栈:作用和虚拟机栈类似,专门为JDK的native本地方法服务。线程共享(全局唯一):1.堆内存:所有对象、数组的存储区域,是GC垃圾回收的主要区域,分为新生代、老年代。2.方法区:存储类信息、常量、静态变量、即时编译后的代码,JDK8后元空间取代永久代,使用本地内存,不再占用JVM堆内存。2.垃圾回收的判定方式,哪些对象会被GC回收JVM不会回收存活对象,只回收无效对象,核心判定两种方式:1.引用计数法:给对象添加引用计数器,有引用则+1,引用失效则-1,计数器为0则判定为可回收。缺点是无法解决循环引用问题,主流JVM不再单独使用。2.可达性分析法(主流):以GCRoots为起始节点,遍历引用链,没有被引用链连接到的对象,判定为垃圾对象,可被回收。可作为GCRoots的对象:虚拟机栈中引用的对象、方法区静态变量/常量引用的对象、本地方法栈引用的对象、活跃线程对象。会被回收的对象:没有任何有效引用、脱离业务使用的对象,包括循环引用但无外部引用的对象。3.常见GC算法及优缺点1.标记清除算法:先标记垃圾对象,再统一清除。优点是简单;缺点是会产生大量内存碎片,后续大对象无法分配连续内存。2.标记整理算法:标记垃圾对象后,将存活对象向内存一端移动,清空末端垃圾。优点是无内存碎片;缺点是移动对象需要耗时,效率较低,多用于老年代GC。3.复制算法:将内存分为两块,只使用其中一块,GC时将存活对象复制到另一块空白内存,清空原内存。优点是无碎片、效率高;缺点是内存利用率只有50%,适合存活对象少的新生代。实际JVM组合使用:新生代用复制算法,老年代用标记清除+标记整理算法。四、多线程与并发面试题1.线程和进程的区别1.资源占用:进程是操作系统资源分配的最小单位,每个进程独立占用内存、CPU资源;线程是CPU调度的最小单位,共享所在进程的所有资源,资源开销极小。2.独立性:进程之间完全独立,一个进程崩溃不会影响其他进程;线程共享进程资源,一个线程异常崩溃,会导致整个进程终止。3.开销:进程创建、销毁、切换开销极大;线程开销极小,切换速度快。4.通信方式:进程间通信复杂(管道、socket);线程间通信简单,直接共享变量即可。2.synchronized和Lock的区别1.底层实现:synchronized是JVM原生关键字,底层依赖操作系统互斥锁,隐式加锁释放;Lock是Java接口(如ReentrantLock),基于代码层面实现,显式加锁、手动释放锁。2.锁特性:synchronized是可重入、不可中断、非公平锁;ReentrantLock支持可重入、可中断、可公平/非公平锁,还能绑定多个条件变量。3.灵活性:synchronized锁范围固定,只能修饰方法、代码块;Lock锁粒度更灵活,可精准控制锁的起止范围。4.性能:JDK1.6之后对synchronized做了大量优化(偏向锁、轻量级锁、自旋锁),两者性能基本持平,低并发下synchronized更简洁,高并发灵活场景用Lock。3.线程池的核心参数及工作原理核心参数共7个,日常重点掌握5个核心:1.核心线程数:线程池常驻的线程数量,即使空闲也不会销毁。2.最大线程数:线程池能创建的最大线程数量。3.空闲超时时间:非核心线程空闲超过该时间会被销毁。4.任务队列:存储等待执行的任务,常用阻塞队列。5.拒绝策略:任务超出最大线程+队列容量时的处理策略。线程池执行流程:1.接收新任务,判断当前线程数是否小于核心线程数,是则新建核心线程执行任务;2.核心线程已满,任务加入阻塞队列;3.队列已满,新建非核心线程执行任务;4.线程数达到最大值,触发拒绝策略处理任务。五、Spring核心面试题1.SpringIOC原理IOC即控制反转,核心是将对象的创建、管理、依赖注入权限,从业务代码转移到Spring容器,实现解耦。核心执行流程:1.容器启动时,扫描项目的注解/配置文件,解析所有Bean的定义信息;2.根据Bean定义,通过反射创建Bean实例;3.自动完成Bean之间的依赖注入(DI);4.将初始化完成的Bean存入Spring单例池,业务代码直接获取使用,无需手动new对象。优势:彻底解耦,统一管理对象生命周期,方便后续AOP、事务等功能扩展。2.SpringAOP原理及应用场景AOP即面向切面编程,核心是在不修改原有业务代码的前提下,对方法进行增强,基于动态代理实现。核心原理:Spring默认优先使用JDK动态代理(接口代理),目标类无接口时使用CGLIB字节码代理。通过切点匹配目标方法,在方法前后、异常、返回后执行增强逻辑。常用应用场景:统一日志记录、接口权限校验、事务控制、接口耗时统计、缓存处理、异常统一捕获。3.SpringBean的生命周期完整生命周期分为5个核心阶段,面试常用精简版流程:1.实例化:Spring通过反射创建Bean的空实例;2.属性填充:完成依赖注入,给Bean的属性赋值;3.初始化:执行前置处理器、初始化方法、后置处理器,完成Bean初始化;4.就绪阶段:初始化完成,Bean存入容器,可供业务使用;5.销毁阶段:容器关闭时,执行Bean的销毁方法,释放资源。六、数据库与MyBatis面试题1.MySQL索引原理,B+树为什么适合做索引MySQLInnodb引擎索引底层采用B+树结构,相比二叉树、B树、哈希索引优势明显:1.磁盘IO更少:B+树是多叉平衡树,层数极低(千万级数据仅3-4层),查询时只需少量磁盘IO,效率远高于二叉树;2.数据存储规整:所有数据都在叶子节点,非叶子节点只存索引键,内存可缓存更多索引,提升查询速度;3.支持范围查询:叶子节点有序双向链表,可快速完成区间查询、排序、分页,哈希索引无法支持范围查询;4.结构稳定:平衡树结构,不会出现极端倾斜,查询性能稳定。2.什么是索引失效?常见索引失效场景索引失效就是查询没有走索引,触发全表扫描,严重影响SQL性能,常见场景:1.索引列使用函数、运算、类型转换;2.模糊查询以%开头(如%abc);3.违背最左匹配原则(联合索引未使用最左侧字段);4.or连接的字段有未索引列;5.数据量少、索引选择性极低,MySQL优化器自动放弃索引。3.MyBatis#{}和${}的区别1.预处理机制:#{}是预编译参数,会生成占位符,自动拼接参数,彻底防止SQL注入;${}是直接字符串拼接,无预编译,存在严重SQL注入风险。2.引号处理:#{}会自动给字符串、日期类型加单引号;${}纯原样拼接,需要手动加引号。3.使用场景:日常查询、传参优先用#{};仅动态表名、动态排序字段等无法预编译的场景使用${}。七、实战场景面试题(手写问答)1.线上接口慢、超时,怎么排查?按照从外到内、从链路到代码的顺序排查,是后端开发必备排查思路:1.先看监控:查看接口QPS、响应时间、报错率、服务器CPU、内存、磁盘、线程池状态,判断是服务器资源问题还是代码问题;2.排查SQL:查看慢日志,检查是否有全表扫描、索引失效、关联查询过多、分页未优化等数据库问题(80%接口慢都是SQL导致);3.排查代码:检查是否有循环查询数据库、大量对象创建、死循环、锁等待、线程阻塞等问题;4.排查中间

温馨提示

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

评论

0/150

提交评论