2026年Java面试题最新整理,附白话答案
2026年最新常见Java开发面试题、面试常问Java面试题整理附白话答案一、Java基础部分面试题 (2026)1. Java面向对象的三个特征封装对象只需要选择性的对外公开一些属性和行为。继承子对象可以继承父对象的属性和行为并且可以在其之上进行修改以适合更特殊的场景需求。多态允许不同类的对象对同一消息做出响应。2. Java中基本的数据类型有哪些 以及他们的占用字节数据类型占用字节byte1short2int4long8float4double8char2boolean43. int和Integer的区别int是Java中的原始类型Integer是Java为int提供的封装类他们有不同的特征和用法包括大小、速度、默认值。4. String 、StringBuilder、StringBuffer的区别及使用场景String一旦定义就不可改变可空赋值。操作少量数据时使用。StringBuilder可改变线程不安全。操作单线程大量数据时使用。StringBuffer可改变线程安全。操作多线程大量数据时使用。5. ArrayList、Vector 和LinkedList的区别及使用场景ArrayList和Vector都是使用数组方式存储数据允许按序号索引元素但是插入数据会涉及到元素移动等内存操作所以索引快插入慢。ArrayList懒加载 默认大小10 每次扩容1.5倍线程不安全性能较高Vector 实例化时初始化 默认大小10 每次扩容2倍线程安全性能较低 已弃用额外回答加分项多读少写建议使用CopyOnWriteArrayListCopyOnWriteArrayList原理是发生修改的时候复制一份多写少读或读写比较均匀建议使用Connections.synchronizedListLinkedList 使用双向链表方式存储数据插入只需要记录本项的前后项索引需要向前或向后进行遍历所以插入速度较快线程不安全频繁在任意位置插入和删除的情况可以使用如果需要多线程访问可以使用Connections.synchronizedList()或ConcurrentLinkedQueue6. Collection和Collections的区别Collection是集合类上级接口继承他的主要有List和SetCollections是集合类的帮助类提供了对集合的搜索、排序、线程安全化等操作。7. List和Map的区别List是存储单列数据的集合Map是存储键值对双列数据的集合。List存储的数据是有顺序且可重复的Map存储的数据是无顺序键不可重复值可重复的。8. HashMap和HashTable的区别HashMap是Map接口的实现非线程安全允许空键值。HashTable是Dictionary的子类线程安全不允许空键值。几乎被淘汰建议使用ConcurrentHashMap来替代它。HashMap使用的是快速失败迭代器在迭代器创建后除非通过迭代器自身的remove或者add方法其他任何方式的修改都会抛出异常。9. HashMap底层实现原理和扩容机制JDK1.8以前数组单链表的组合以键值对的方式存储元素。JDK1.8及以后引入红黑树结构添加元素时若链表个数大于8链表会转换为红黑树反之小于6时会修剪或还原成链表结构。选择6和8可以有效防止频繁的链表和红黑树转换。扩容条件存放新值的时候当前已有元素个数大于阈值。存放新值的时候当前存放数据发生hash碰撞当前key计算的hash值换算出来的数组下标位置已经存在值默认容量是16负载因子0.75所以扩容阈值是12。每次扩容的容量是原有的2倍。篇幅限制下面就只能给大家展示小册部分内容了。整理了一份核心面试笔记包括了Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafc需要全套面试笔记及答案【点击此处即可/免费获取】https://docs.qq.com/doc/DQXdYWE9LZ2ZHZ1ho10. HashMap什么样的类适合作为键String最为常见因为String对象不可变且重写了equals和hashcode方法。不可变性是必要的如果key的hashcode存入和获取是不一致就无法找到。获取对象时需要用到equals和hashCode方法正确的重写这两个方法是非常重要的因为两个不相等的对象返回不同的hashCode的话碰撞的几率就会小些就可以提高HashMap的性能。11. final、finally、finalize的区别final用于修饰属性、方法和类分别表示属性不可变方法不可覆盖类不可继承。finally是异常处理语句结构的一部分表示总是执行。finalize是Object类的一个方法在GC执行时会调用被回收对象的此方法。12. sleep()和wait()的区别sleep()是Thread类的wait()是Object类的方法sleep不会释放锁wait会释放锁。sleep可在任意地方使用wait notify notifyAll只能在synchronized块\方法中使用。sleep必须捕获异常而wait不需要。13. 抽象类和接口的区别、以及使用场景抽象类中可以有构造方法、静态方法、普通方法、普通成员变量。接口中不能有。抽象类中的抽象方法访问类型可以是public、protected和默认类型接口中只能是public。抽象类中的静态成员变量访问类型可以任意接口中只能是public的。一个类只能继承一个类但是可以实现多个接口。抽象类和子类为“是不是”的关系。主要用于为一些类提供公共实现代码。接口和实现为“有没有”的关系。主要用于代码的扩展性和可维护性。14. Overload重载和Override重写的区别重载是一个类中多态性的一种表现在一个类中定义了多个同名的方法他们有不同的参数列表。重写是父类与子类之间多态的一种表现子类中定义了与父类有相同名称和参数的方法时子类对象使用该方法会调用子类中的定义。15. forward转发和redirect重定向的区别forward是服务器请求资源服务器 访问目标URL把响应内容发给用户用户不知道数据是从哪来的。redirect是服务器向客户端发送一个状态码告知重新请求该URL。16. 连接池的工作机制服务器启动时会建立一定数量的池连接客户端需要连接时池会返回一个未使用的连接并将其标记为忙如果没有空闲连接池会新建一定数量的连接当连接使用完毕后池会将其标记为空闲。17. 什么是序列化序列化就是一种用来处理对象流的机制就是将对象的内容进行流化可以对流化后的对象进行读写操作也可以将流化后的对象传输于网络之间。可通过实现java.io.Serializable接口来实现序列化。二、第三方框架部分 (2026)1. 什么是AOP、Spring AOP的底层原理是什么AOP是面向切面编程用于在不改变原有逻辑的基础上增加一些额外的功能如事务管理、日志、缓存、权限控制等。Spring AOP是基于代理的。如果目标对象实现了接口则默认采用JDK动态代理。如果目标对象没有实现接口则采用CgLib进行动态代理。如果目标对象实现了接口且强制CgLib代理则采用CgLib动态代理。2. 什么是IOC、IOC注入方式有哪些IOC翻译为控制反转他还有个别名为DI依赖注入。IOC就是由IOC容器来负责对象的生命周期和对象之间的关系。控制反转就是本来应该你做的事情让系统去做比如通常获取一个对象需要通过new而使用IOC则是IOC将对象创建后注入到被注入的对象中。注解注入Spring、构造器注入、setter方法注入、接口方式注入不推荐3. Mybatis中 #{} 和 ${}的区别#{}是预编译可防止SQL注入。${}是直接拼接在SQL语句中。4. Spring Boot的核心注解是什么它是由哪几个注解组成的核心注解SpringBootApplication包含SpringBootConfiguration 实现配置文件功能EnableAutoConfiguration 打开自动配置功能CompoentScan 组件扫描功能5. SpringBoot 怎么读取配置文件属性上使用Value注解类上使用ConfigurationProperties注解读取指定文件注解可在类上使用PropertySource不支持yml文件读取注入Environment对象获取到。6. SpringCloud 和Dubbo的区别SpringCloud采用基于HTTP的REST APIDubbo采用RPC方式。7. SpringCloud的Hystrix断路器特性请求熔断请求服务失败量超过一定比例默认50%断路器会切换到开路状态这时所有请求不会发送到后端服务断路器在保持开路状态一段时间后默认5秒自动切换到半开路状态。这时如果下一次请求成功断路器切回闭路状态否则重新切换到开路状态。服务降级对于查询操作可以实现一个fallback方法。当请求服务出现异常时可以使用fallback方法返回的值。依赖隔离通过线程池来实现资源隔离比如一个服务调用另外两个服务如果这两个服务在同一线程池那么如果一个服务卡住后面的请求又来了就会导致后面的请求都会卡住等待。请求缓存缓存上次请求结果返回给后续请求。请求合并把多个请求合并成一个请求提升效率。三、MySQL 数据库部分 (2026)1. 事物的四大特性和隔离级别原子性不可分割的操作单元要么全部成功要么回滚。一致性如果执行事物之前数据库是一致的那么执行后还是一致的。隔离性事物操作之间彼此独立和透明互不影响。持久性事物一旦提交其结果就是永久的。未提交读允许脏读其他事物只要修改了数据即使未提交本事物也能看到修改后的数据值。提交读只能读取到已提交的数据。可重复读innoDB默认无论其他事物是否修改并提交了数据这个事物中的数据不受影响。串行读完全串行化的读每次读都要获得锁读写相互都会阻塞。2. MySQL优化相关使用更小的整数类型、尽可能的定义字段为not null否则会导致索引复杂、只创建需要的索引、分库分表。使用explain检查复杂SQL语句、LIMIT语句尽量要跟order by或distinct、插入多条数据时使用单条INSERT语句。3. MySQL存储引擎InnoDB和MyISAM的区别InnoDB支持事物MyISAM不支持。InnoDB支持外键MyISAM不支持。InnoDB是聚集索引MyISAM是非聚集索引。索引和数据文件是分离的。InnoDB必须要有主键没有会自己找或创建MyISAM可以没有。InnoDB不保存表的行数MyISAM用了一个变量保存表的行数。InnoDB支持表、行级锁 默认行级锁MyISAM只支持表级锁。4. MySQL在哪些情况下不使用索引like查询使用%开头不能使用索引但用%结尾的可以使用索引。where语句中使用或!。where语句中使用or且没有把or中的所有字段加上索引。where语句中对字段表达式操作。where语句中使用NOT IN。使用简单的IN会使用索引。5. MySQL分库分表策略垂直切分某个表字段过多可以将不常用或字段长度较大的字段拆分出去到扩展表中。水平切分分为库内分表和分库分表是根据表内数据的逻辑关系按照不同的条件分散到多个数据库或表中。四、扩展阅读 (2026)1. 关于Spring对JDK和CgLib动态代理的选择通过查阅Spring-AOP包中的org.springframework.aop.framework.DefaultAopProxyFactory 类得到以下代码public class DefaultAopProxyFactory implements AopProxyFactory, Serializable { Override public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException { if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) { Class? targetClass config.getTargetClass(); if (targetClass null) { throw new AopConfigException(TargetSource cannot determine target class: Either an interface or a target is required for proxy creation.); } if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) { return new JdkDynamicAopProxy(config); } return new ObjenesisCglibAopProxy(config); } else { return new JdkDynamicAopProxy(config); } } private boolean hasNoUserSuppliedProxyInterfaces(AdvisedSupport config) { Class?[] ifcs config.getProxiedInterfaces(); return (ifcs.length 0 || (ifcs.length 1 SpringProxy.class.isAssignableFrom(ifcs[0]))); } }运行项目并下载源码java运行可以看到Spring先使用isOptimize()方法、isProxyTargetClass()方法以及hasNoUserSuppliedProxyInterfaces()方法进行判断这三个方法的含义分别如下篇幅限制下面就只能给大家展示小册部分内容了。整理了一份核心面试笔记包括了Java面试、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafc需要全套面试笔记及答案【点击此处即可/免费获取】https://docs.qq.com/doc/DQXdYWE9LZ2ZHZ1hoisOptimize()是否对生成代理策略进行优化当返回值为true时为进行优化如果有接口就代理接口(使用JDK动态代理)没有接口代理类CGLIB代理当返回值为false时为不进行优化defaultisProxyTargetClass()是否强制使用CGLIB来实现代理当返回值为true时为强制使用CgLib来实现代理当范围值为false时为不强制使用CgLib来实现代理而是首选JDK来实现代理defaulthasNoUserSuppliedProxyInterfaces()判断代理的对象是否只有指定了SpringProxy的接口或未实现接口当返回值为true时代表没有实现接口或仅实现了指定SpringProxy的接口当返回值为false时代表实现了接口直接使用JDK动态代理当了解这三个方法的含义后接下来阅读代码就很简单了。如果以上三个方法有任意方法返回值为true就进入下一步判断如果所有的返回值均为false说明即不强制使用CgLib或又实现了接口则使用JDK动态代理。在第二步判断中首先对其targetClass进行了判空然后判断它是否为接口或代理类如果是则使用JDK动态代理。反之则使用CgLib进行代理。2. 为什么CgLib可以代理任何类但还是需要JDK的动态代理CgLib和JDK动态代理的区别。这就不得不说到CgLib的特点创建速度慢但执行速度快而JDK的动态代理与其刚好相反创建速度快但执行速度慢。如果在程序运行时不断地使用CgLib去创建代理的话系统运行的性能会大打折扣所以建议一般在系统初始化时采用CgLib来创建代理并放入Spring的ApplicationContext中。