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

下载本文档

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

文档简介

Java高频面试试题及详细答案(真实职场版)一、Java基础篇(高频必问)1、谈谈JDK、JRE、JVM的区别与联系参考答案:三者是层层包含的关系,范围从大到小依次是JDK>JRE>JVM。JVM是Java虚拟机,是Java程序运行的核心环境,负责加载class文件、解释/编译字节码、内存管理、垃圾回收,是实现Java跨平台的核心,单独的JVM无法运行Java程序。JRE是Java运行环境,包含JVM+Java核心运行类库(rt.jar等),只用于运行已经编译好的Java程序,不具备代码编译、调试等开发功能,普通用户运行Java软件只需安装JRE。JDK是Java开发工具包,包含JRE+开发工具(javac编译器、java运行命令、jmap、jstack调试工具等),是开发Java程序必须安装的环境,开发者日常使用的都是JDK。总结:开发用JDK,运行用JRE,底层依托JVM。2、==和equals()的区别参考答案:1、==是运算符,可以用于基本数据类型和引用数据类型。基本类型比较的是数值本身是否相等;引用类型比较的是内存地址是否相同,也就是判断是否为同一个对象。2、equals()是Object类的方法,仅适用于引用数据类型。Object类中原生的equals()方法底层就是==,比较对象地址;但String、Integer等包装类重写了该方法,重写后比较的是对象的内容值,不再比较地址。高频场景:字符串比较必须用equals(),绝对不能用==。3、String、StringBuilder、StringBuffer的区别参考答案:1、String:字符串常量,底层是被final修饰的字符数组,不可变。每次字符串拼接、修改都会生成新的String对象,频繁操作会产生大量垃圾对象,效率极低。2、StringBuffer:字符串变量,线程安全,方法加了synchronized锁,多线程环境下可正常使用,但锁会带来性能损耗,单线程下效率较低。3、StringBuilder:字符串变量,线程不安全,无锁机制,性能最高,是日常开发单线程字符串拼接的首选。使用场景总结:少量字符串操作用String;单线程频繁拼接用StringBuilder;多线程频繁拼接用StringBuffer。4、final、finally、finalize的区别参考答案:1、final:是修饰符,用于修饰变量、方法、类。修饰变量:变量变为常量,只能赋值一次;修饰方法:方法不能被重写;修饰类:类不能被继承。2、finally:是异常处理的关键字,搭配try-catch使用。代码块中的代码一定会执行(除JVM退出等极端情况),主要用于释放资源,比如关闭流、关闭数据库连接。3、finalize():是Object类的废弃方法,JDK9之后已废弃。原本用于垃圾回收前触发,让对象完成资源收尾,但其执行时机不确定、不可靠,开发中绝对不使用。5、接口和抽象类的区别参考答案:1、定义与修饰:抽象类用abstract修饰;接口用interface修饰。2、继承实现:类只能单继承一个抽象类;类可以多实现多个接口,解决了单继承的局限性。3、成员特性:抽象类可以有构造方法、普通成员变量、静态变量、抽象/普通方法;接口(JDK8前)只能有全局常量和抽象方法,JDK8支持默认方法、静态方法,JDK9支持私有方法,无构造方法。4、设计思想:抽象类是模板复用,提炼子类通用属性和行为;接口是行为规范,定义统一的功能标准。二、Java集合篇(面试核心)1、ArrayList和LinkedList的区别参考答案:1、底层结构:ArrayList基于动态数组;LinkedList基于双向链表。2、查询效率:ArrayList支持随机访问,通过下标查询速度极快;LinkedList只能从头节点遍历查询,速度慢。3、增删效率:ArrayList增删元素会涉及数组扩容、元素移位,效率低;LinkedList只需修改节点指针,无需移动元素,首尾增删效率极高。4、内存占用:ArrayList会预留冗余容量,存在内存浪费;LinkedList每个节点包含数据和前后指针,单个元素内存占用更大。场景选择:查询多、增删少用ArrayList;频繁首尾增删、随机查询少用LinkedList。2、HashMap的底层原理(JDK1.8重点)参考答案:HashMap底层是数组+链表+红黑树的结构,基于哈希表实现,用于存储键值对数据。1、存储流程:通过key的hash值计算数组下标,判断下标位置是否有元素;无元素则直接插入;有元素则判断key是否重复,重复则覆盖value,不重复则挂载到链表末尾。2、树化规则:当链表长度大于8且数组容量大于64时,链表转换为红黑树,降低查询时间复杂度;当链表长度小于6时,红黑树退化为链表。3、扩容机制:默认初始容量16,负载因子0.75,当元素数量达到容量*0.75时触发2倍扩容,重新哈希分配元素位置。4、特点:线程不安全,key允许null(仅一个),value允许null,存取速度快。3、HashMap和HashTable的区别参考答案:1、线程安全:HashTable线程安全,所有方法加了synchronized锁;HashMap线程不安全,并发环境下会出现数据覆盖、死链问题。2、null值支持:HashTable的key和value都不允许为null;HashMap允许一个key为null,多个value为null。3、效率:HashTable加锁导致并发效率极低;HashMap无锁,单线程性能优异。4、初始容量:HashTable默认容量11,扩容2倍+1;HashMap默认容量16,扩容2倍。拓展:并发场景不推荐HashTable,推荐使用ConcurrentHashMap。4、ConcurrentHashMap线程安全原理(JDK1.8)参考答案:JDK1.8摒弃了分段锁机制,采用CAS+synchronized锁实现线程安全,底层依旧是数组+链表+红黑树。1、无冲突时:通过CAS无锁操作尝试插入数据,不阻塞线程,性能高。2、发生哈希冲突时:只对当前数组下标位置的头节点加synchronized锁,不是锁整个数组,锁粒度极小,并发性能大幅提升。3、树结构:红黑树节点使用CAS和锁配合保证并发安全,同时支持高效的查询和修改。整体特点:兼顾线程安全和高性能,是Java并发场景下存储键值对的首选。三、多线程篇(面试重难点)1、线程和进程的区别参考答案:1、进程:是操作系统资源分配的最小单位,独立占用内存、CPU资源,进程之间相互隔离,通信成本高。2、线程:是CPU调度的最小单位,隶属于进程,一个进程包含多个线程,线程共享进程的内存资源(堆、方法区),仅拥有独立的栈内存,线程间通信成本低、切换速度快。总结:进程是资源容器,线程是执行单元;进程开销大、隔离性强,线程开销小、效率高。2、synchronized和Lock的区别参考答案:1、锁类型:synchronized是内置锁,JVM层面实现;Lock是显示锁,代码层面实现的接口(常用ReentrantLock)。2、锁释放:synchronized无需手动释放,代码执行完毕或异常自动释放锁;Lock必须手动调用unlock()释放,否则会造成死锁。3、灵活性:synchronized锁机制固定,无法中断、无法超时;Lock支持超时锁、可中断锁、公平锁,功能更丰富。4、性能:低并发下两者性能相近,高并发下Lock性能更优;JDK1.6后对synchronized做了大量优化(偏向锁、轻量级锁、重量级锁),性能大幅提升。3、volatile关键字的作用参考答案:volatile是轻量级同步关键字,核心两大作用:1、保证可见性:一个线程修改volatile变量,会立即刷新到主内存,其他线程能立刻读取到最新值,解决多线程变量缓存不一致问题。2、禁止指令重排:底层通过内存屏障禁止编译器和CPU对代码进行乱序执行,解决单例模式DCL的重排漏洞。注意:volatile不保证原子性,无法替代锁,不能用于计数、累加等复合操作。4、什么是线程死锁?如何避免死锁参考答案:死锁定义:多个线程互相持有对方需要的锁,同时等待对方释放锁,所有线程永久阻塞,程序无法继续执行。死锁产生四大必要条件:互斥条件、请求与保持条件、不可剥夺条件、循环等待条件。避免方案:1、破坏循环等待:统一锁的获取顺序,所有线程按固定顺序申请锁;2、破坏请求保持:一次性申请所有需要的锁,不持有部分锁再申请新锁;3、使用超时锁:通过Lock的tryLock()设置超时时间,超时自动放弃锁;4、减少嵌套锁:尽量避免锁嵌套,降低死锁概率。四、JVM与垃圾回收篇1、JVM内存区域划分参考答案:JVM运行时数据区分为五大区域,其中线程私有3个、线程共享2个:1、程序计数器(线程私有):记录当前线程执行的字节码行号,是唯一一个无内存溢出的区域。2、虚拟机栈(线程私有):存储方法栈帧、局部变量、操作数栈,方法调用创建栈帧,执行完毕销毁,会抛出StackOverflowError。3、本地方法栈(线程私有):服务于native本地方法,底层C/C++实现。4、堆内存(线程共享):所有对象、数组的存储区域,是垃圾回收的核心区域,会发生OOM内存溢出。5、方法区(线程共享):存储类信息、常量、静态变量、即时编译代码,JDK1.8后方法区改为元空间,使用本地内存,不再占用堆内存。2、GC垃圾回收的对象和回收时机参考答案:GC主要回收堆内存中没有任何有效引用的对象,栈、方法区、程序计数器基本不做垃圾回收。回收时机:1、新生代GC(MinorGC):新生代内存不足时触发,频率高、速度快,清理Eden区无效对象;2、老年代GC(MajorGC/FullGC):老年代内存不足、MinorGC后晋升对象过多、手动调用System.gc()时触发,速度慢、耗时久,线上应尽量避免。3、常见垃圾回收器及适用场景参考答案:1、Serial:单线程回收器,适合客户端、小内存程序,效率低;2、Parallel:多线程并行回收器,注重吞吐量,适合后台批量任务、大数据离线场景;3、CMS:并发低停顿回收器,注重响应速度,适合互联网线上服务,延迟低,但内存碎片多;4、G1:分区式回收器,兼顾吞吐量和低延迟,可控制停顿时间,是JDK9+默认回收器,适合大内存服务;5、ZGC:超低延迟回收器,适合超大内存、高并发、低延迟核心服务。五、Spring核心篇1、SpringIOC的原理参考答案:IOC即控制反转,核心是将对象的创建、管理、依赖注入权限交给Spring容器,不再由开发者手动new对象。传统开发:开发者主动创建对象、维护对象依赖,控制权在开发者;IOC模式:程序启动时Spring扫描注解/配置,初始化Bean对象存入IOC容器,程序需要对象时主动从容器获取,实现控制权反转。核心优势:解耦,降低代码耦合度,方便统一管理对象,为AOP、事务等功能奠定基础。2、SpringAOP的原理和应用场景参考答案:AOP即面向切面编程,基于动态代理机制,在不修改原有业务代码的前提下,对方法进行增强。核心原理:通过前置通知、后置通知、异常通知等,在目标方法执行前后切入通用逻辑,实现业务代码和通用功能的解耦。常用场景:统一日志记录、权限校验、事务控制、接口限流、性能耗时统计、异常统一处理。代理规则:目标类有接口用JDK动态代理,无接口用CGLIB字节码代理。3、Spring事务传播机制有哪些参考答案:Spring共7种事务传播机制,开发最常用5种:1、REQUIRED(默认):有事务则加入,无事务新建事务,最常用;2、SUPPORTS:有事务则加入,无事务则非事务运行;3、MANDATORY:必须在事务内运行,无事务直接报错;4、REQUIRES_NEW:新建独立事务,暂停原有事务,互不影响;5、NESTED:嵌套事务,依赖父事务,父事务回滚则子事务必须回滚,子事务回滚不影响父事务。六、数据库与Redis篇1、MySQL索引原理、B+树优势参考答案:MySQLInnoDB引擎索引底层采用B+树结构。B+树核心优势:1、所有数据都在叶子节点,非叶子节点只存索引键,内存占用小,磁盘IO次数少;2、叶子节点通过双向链表串联,范围查询、排序查询效率极高;3、树的层级低,千万级数据树高基本3-4层,查询速度稳定。区分:主键索引(聚簇索引)叶子节点存整行数据,普通索引(二级索引)叶子节点存主键值。2、SQL慢查询优化思路参考答案:1、先通过explain分析执行计划,查看是否命中索引、是否存在全表扫描、临时表、文件排序;2、对高频查询字段建立合理索引,避免索引失效(like%xxx、or、字段函数运算、隐式转换等);3、优化SQL语句,避免select*,只查询需要的字段;减少子

温馨提示

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

评论

0/150

提交评论