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

下载本文档

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

文档简介

Java工程师面试题(含详细真实答题答案)一、Java基础核心(高频必问)1.说说==和equals的区别?参考答案:==是比较运算符,既可以比较基本数据类型,也可以比较引用数据类型。基本类型比较的是数值本身,引用类型比较的是对象的内存地址。equals是Object类的方法,默认情况下和==一样,比较的是对象地址。但是像String、Integer这些类都重写了equals方法,重写后是直接比较对象的内容值,而不是地址。日常开发中,字符串对比一律用equals,基本类型判断用==。2.String、StringBuilder、StringBuffer的区别?参考答案:1、String是不可变字符串,底层是final修饰的char数组(JDK9+是byte数组),每次拼接、修改都会生成新对象,频繁操作性能很差。2、StringBuilder和StringBuffer是可变字符串,不会新建对象。3、线程安全区别:StringBuffer所有方法都加了synchronized,线程安全但性能低;StringBuilder无锁,线程不安全,性能高。实际开发选型:单线程字符串拼接用StringBuilder,多线程场景用StringBuffer,常量字符串直接用String。3.final、finally、finalize的区别?参考答案:三个完全不相关的关键字,只是名字相似:1、final:修饰符。修饰变量是常量,不能二次赋值;修饰方法不能重写;修饰类不能被继承。2、finally:异常处理关键字。搭配try-catch使用,无论代码是否报错,finally代码块都会执行,一般用来关闭流、释放资源。3、finalize:Object类的废弃方法,JVM垃圾回收前会调用这个方法。但是执行时间不确定、不保证执行,实际开发绝对不用,JDK9已经废弃。4.接口和抽象类的区别?参考答案:1、定义不同:抽象类用abstract修饰,接口用interface定义。2、继承规则:类只能单继承抽象类,但可以多实现接口。3、成员区别:抽象类可以有构造方法、成员变量、普通方法、抽象方法;接口(JDK8前)只能有常量和抽象方法,JDK8后支持默认方法、静态方法,JDK9支持私有方法。4、设计思想:抽象类是模板复用,抽取子类公共代码;接口是行为规范,定义功能标准。5.Java基本数据类型有哪些?包装类和基本类的区别?参考答案:8种基本类型:byte、short、int、long、float、double、char、boolean。区别:1、基本类型是栈内存存储,效率高、无默认null;包装类是对象,堆内存存储,默认值为null。2、基本类型不能泛型、不能存集合,包装类可以。3、有自动装箱拆箱:基本转包装是装箱,包装转基本是拆箱。开发注意点:Integer有缓存,-128~127范围内的对象会复用,超出范围会新建对象,所以区间内==为true,区间外为false。二、Java集合框架(重中之重)1.ArrayList和LinkedList区别?参考答案:1、底层结构:ArrayList基于动态数组;LinkedList基于双向链表。2、查询效率:ArrayList随机访问快,根据下标直接定位;LinkedList必须从头遍历,查询慢。3、增删效率:ArrayList尾部增删快,中间、头部增删需要移动元素,效率低;LinkedList任意位置增删只需要改指针,效率高。4、内存:ArrayList会有扩容冗余空间;LinkedList每个节点都存指针,占用内存更大。选型:查询多、遍历多用ArrayList;频繁增删用LinkedList(实际开发ArrayList占90%场景)。2.HashMap底层原理?JDK1.7和1.8区别?参考答案:HashMap底层是数组+链表+红黑树,基于哈希表实现,用来存键值对,无序、可null键值、线程不安全。存储流程:通过key的hash值计算数组下标,下标位置为空直接存入;有值就发生哈希冲突,挂链表;链表长度超过8、数组长度大于64,链表转红黑树;当红黑树节点小于6,退化成链表。JDK1.7VS1.8核心区别:1、底层结构:1.7只有数组+链表;1.8新增红黑树。2、哈希冲突:1.7头插法,多线程会出现循环链表死循环;1.8尾插法,规避了死循环问题。3、扩容优化:1.8扩容后节点位置只可能在原位置或原位置+旧容量位置,不需要重新计算hash。4、阈值:链表长度>8转树,<6退链表。3.HashMap和HashTable、ConcurrentHashMap区别?参考答案:1、HashMap:线程不安全,效率高,允许null键null值,无锁。2、HashTable:线程安全,所有方法加synchronized,效率极低,不允许null,基本废弃不用。3、ConcurrentHashMap:线程安全,高并发首选。JDK1.8采用CAS+Synchronized锁单个节点,不是锁整个数组,并发性能极高。4.HashMap为什么线程不安全?参考答案:多线程同时put数据时,会出现数据覆盖;JDK1.7扩容时头插法会产生循环链表,导致get请求死循环、CPU飙高。1.8虽然修复了死循环,但依然存在数据覆盖、丢失数据问题,所以依旧线程不安全。三、多线程与并发(核心难点)1.线程和进程的区别?参考答案:进程是操作系统资源分配的最小单位,独立占用内存、CPU资源,进程之间互不共享数据,开销大。线程是CPU调度的最小单位,依附进程存在,一个进程包含多个线程,线程之间共享进程堆内存、方法区资源,切换开销小、效率高。2.synchronized和Lock的区别?参考答案:1、来源:synchronized是JVM原生关键字,底层依赖虚拟机锁机制;Lock是Java接口(ReentrantLock),代码层面实现锁。2、锁释放:synchronized自动加锁、自动释放,异常也会解锁;Lock需要手动lock()、unlock(),必须在finally解锁,否则会死锁。3、锁特性:synchronized是非公平锁、不可中断;ReentrantLock支持公平锁、可中断、可超时、可绑定多个条件。4、粒度:synchronized锁方法/代码块;Lock锁粒度更灵活。开发选型:简单并发场景用synchronized,复杂精细控制并发用ReentrantLock。3.什么是线程池?核心参数有哪些?参考答案:线程池是复用线程的工具,避免频繁创建、销毁线程带来的开销,统一管理线程,控制并发数。核心7大参数:1、核心线程数:常驻线程,空闲也不销毁;2、最大线程数:线程池能创建的最大线程数量;3、空闲超时时间:非核心线程空闲多久销毁;4、时间单位:超时时间单位;5、阻塞队列:存放等待执行的任务;6、线程工厂:创建线程,一般默认;7、拒绝策略:任务满了之后的处理方式。任务执行流程:来任务先开核心线程→核心线程满了进队列→队列满了开非核心线程→达到最大线程数触发拒绝策略。4.常见的线程池拒绝策略?参考答案:1、AbortPolicy:直接抛出异常,默认策略;2、CallerRunsPolicy:让调用者线程自己执行任务;3、DiscardPolicy:直接丢弃任务,不报错;4、DiscardOldestPolicy:丢弃队列最旧任务,执行新任务。开发规范:禁止用Executors创建线程池,必须手动newThreadPoolExecutor,避免OOM。四、JVM虚拟机(中高级必问)1.JVM内存区域划分?参考答案:JVM运行时数据区分为5块:1、程序计数器:线程私有,记录当前线程执行的行号,唯一一个无OOM的区域;2、虚拟机栈:线程私有,存局部变量、方法栈帧,方法执行结束自动释放,栈溢出报StackOverflowError;3、本地方法栈:线程私有,服务Native本地方法;4、堆内存:线程共享,所有对象、数组都存在堆,是GC主要回收区域,会发生OOM;5、方法区(元空间):线程共享,存类信息、常量、静态变量、编译后的代码,JDK8彻底移除永久代,改用本地内存的元空间。2.GC垃圾回收机制?哪些对象会被回收?参考答案:GC主要回收堆内存中没有任何引用指向的对象。判断垃圾算法:引用计数法(有循环引用弊端,不用)、可达性分析算法(JVM默认)。可达性分析:从GCRoots出发,遍历所有引用链,无法遍历到的对象就是垃圾对象。GCRoots包含:虚拟机栈引用对象、本地方法栈引用对象、静态变量、常量引用对象。3.年轻代、老年代垃圾回收特点?参考答案:1、年轻代:对象朝生夕死,回收频率高、速度快,用复制算法,分为Eden、S0、S1区,大部分对象诞生后一次MinorGC就被回收。2、老年代:存放存活时间久、大对象、晋升过来的对象,回收频率低、速度慢,用标记整理、标记清除算法,触发MajorGC,耗时很长。五、Spring核心框架1.SpringIOC原理?参考答案:IOC就是控制反转,把对象的创建、管理、依赖注入的权力,从开发者代码中交给Spring容器,不用自己new对象。核心流程:启动项目加载配置文件/注解→扫描Bean→实例化对象→初始化对象→存入IOC容器→用时直接依赖注入。目的:解耦,降低代码依赖,方便统一管理。2.SpringAOP原理、应用场景?参考答案:AOP面向切面编程,在不修改原有业务代码的前提下,对方法进行增强,基于动态代理实现。代理规则:有接口用JDK动态代理,无接口用CGLIB字节码代理。常用场景:日志记录、事务控制、权限校验、限流、缓存、异常统一处理。3.Spring事务传播机制、隔离级别?参考答案:传播机制(常用3个):1、REQUIRED:默认,有事务就加入,没有就新建事务;2、SUPPORTS:有事务就加入,没有就非事务运行;3、REQUIRES_NEW:每次都新建独立事务,互不影响。隔离级别:读未提交、读已提交、可重复读(MySQL默认)、串行化。开发踩坑:同类内部方法调用,事务失效;try-catch捕获异常不抛出,事务不回滚。六、MySQL数据库1.InnoDB和MyISAM区别?参考答案:1、事务:InnoDB支持事务、ACID;MyISAM不支持。2、锁机制:InnoDB行锁+表锁;MyISAM只有表锁,并发差。3、外键:InnoDB支持外键;MyISAM不支持。4、崩溃恢复:InnoDB支持事务日志恢复;MyISAM崩溃易损坏数据。5、查询性能:MyISAM简单查询略快,但并发场景完全不如InnoDB。选型:业务系统一律用InnoDB。2.索引原理?B+树为什么比B树、哈希好?参考答案:MySQL索引默认B+树结构。1、B+树所有数据都在叶子节点,非叶子节点只存索引键,内存能存更多索引,磁盘IO次数更少;2、叶子节点双向链表有序,支持范围查询、排序、分页;3、哈希索引不支持范围查询、排序,只适合精准匹配;4、B树数据分散在各个节点,查询层数更多,IO更高。3.慢SQL优化思路?参考答案:1、先用explain分析执行计划,看是否走索引、有没有全表扫描、临时表、文件排序;2、避免索引失效:不要select*、不要隐式类型转换、or左右字段都要建索引、like%xxx会失效;3、优化join查询,小表驱动大表;4、分页深分页用覆盖索引+子查询优化;5、避免大事务、大批量数据操作拆分批次。七、Redis缓存1.Redis为什么快?参考答案:1、纯内存操作,没有磁盘IO开销;2、单线程模型,避免线程竞争、锁开销,只用一个线程处理命令;3、IO多路复用,处理大量并发连接;4、数据结构简单,底层优化极致。2.缓存穿透、击穿、雪崩解决方案?参考答案:1、缓存穿透:查询不存在的数据,直接打数据库。解决:布隆过滤器、空值缓存、接口校验。2、缓存击穿:热点key过期,瞬间大量请求打数据库。解决:互斥锁、热点key永不过期。3、缓存雪崩:

温馨提示

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

评论

0/150

提交评论