Java面试题汇总-Java高级篇(共50道题)

张开发
2026/4/17 17:51:06 15 分钟阅读

分享文章

Java面试题汇总-Java高级篇(共50道题)
一、java中的序列化和反序列化是什么思维导图回答序列化就是将对象转换为字节流的过程反序列话就是将字节流转换为对象的过程也就是序列化的逆过程主要应用在网路传输、远程调用、持久化存储和分布式系统数据交换当中。java要想实现对象的序列化需要实现Serializable接口底层实现序列化是用到了ObjectOutputStream这个类而反序列化则是用到了ObjectInputStream这个类。serialVersionUID的作用是什么就是一个版本号的作用来确保数据在序列化的过程中被修改而导致不一致的问题在序列化的时候判断UID是否跟当前对象的UID一致如果一致就说明当前对象没有被其他线程修改过此时可以继续序列化其本质就是一个乐观锁。transient关键字有什么用这个关键字可以标记在不想被序列化的字段上确保不被序列化。二、什么是java的不可变类思维导图回答不可变类就是创建后其状态也就是对象的字段无法被修改的类。一般是通过final关键字去创建一个不可变类最常见的例子就是String字符串String被创建后其值不可变假设有sa,也只是创建了一个新对象并将s的引用指向了新对象s的旧引用指向的老对象的值没有变化还是s。不可变类主要有线程安全、缓存友好等优点但是也有缺点例如性能问题当执行了过多的字符串操作可能会创建大量字符串对象浪费内存空间。三、Java 中 Exception 和 Error 有什么区别?思维导图回答从定义上来讲Exception是指程序能够处理的异常情况而Error则是JVM层次内系统级的错误一般程序不能够处理。Exception和Error的共同之处就是都是Throwable类的子类java代码只有继承了Throwable类的实例才能被throw或catch。四、你觉得java的优势是什么思维导图回答我觉得java的优势有跨平台性、垃圾回收、生态、面向对象四个优势。其中跨平台性主要体现在java代码被编译成字节码然后被不同平台下的JVM编译成对应平台的机器码并交由对应平台执行从而实现跨平台性这也就是java“一次编译到处运行”的原因。java内部的JVM有内存回收机制极大地减少了程序员内存管理的成本。java有丰富的第三方类库和成熟的开发框架以及各种中间件。java还是一种面向对象的语法其封装继承多态的特性也使得java可扩展性强。篇幅限制下面就只能给大家展示小册部分内容了。整理了一份核心面试笔记包括了Java面试、场景题、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafc需要全套面试笔记及答案【点击此处即可/免费获取】​https://docs.qq.com/doc/DQXdYWE9LZ2ZHZ1ho五、什么是java的多态特性思维导图回答多态的定义是同一个接口或父类引用变量可以指向不同的对象实例并根据实际指向的对象类型执行相应的方法。多态还分为编译时多态和运行时多态编译时多态主要体现为方法重载方法重载就是同一个类中可以定义多个同名方法但参数列表不同java编译器会根据传入的参数来决定调用哪一个方法。运行时多态体现为方法重写方法重写就是子类重写父类中的一个或多个方法。通过父类引用调用方法时实际上执行的是子类重写后的方法。六、java中的参数传递是按值还是按引用java中的参数传递都是值传递其中基本数据类型传递的是值引用数据类型传递的是地址值。七、为什么java不支持多重继承因为不想走C的老路C支持多重继承这就导致在继承过程中可能会出现歧义的情况具体如下D继承B和C多重继承B和C共同继承AA的方法在B和C中都得到重写在D想调用A中方法时因为B和C都有不同的实现此时就会出现歧义不知道应该调用哪个了。八、面向对象编程和面向过程有什么区别面向对象是以对象作为编程指导或中心通过对象间的交互操作来实现具体的功能最直观的表现就是封装继承多态数据和行为封装在一个对象中。面向过程就是以函数作为编程指导或中心通过函数间的调用来实现具体的功能数据和行为是分开的。面向对象更加模块规范化且扩展性强但是开发难度高适合大型项目。面向过程更加直接但扩展性弱维护成本高不易协作适合小型项目快速开发。九、Java 方法重载和方法重写之间的区别是什么?首先方法重载就是在同一个类中允许有多个重名方法但是参数列表不同个数、顺序、类型通过传进来的参数来调用对应的方法。而方法重写就是字类去重写父类的方法为该方法提供新的实现或扩展。方法重载的参数列表返回类型都可以不一样但是方法重写的参数列表和返回类型都必须和父类的保持一致。而且子类方法的访问修饰不能比父类更严格且不能抛出比父类更多的异常也就是子类要一直生活在父类的阴影下。十、什么是java内部类内部类是指在一个类的内部定义的类。 成员内部类:可以访问外部类的所有成员 静态内部类:可以访问外部类的静态成员 局部内部类:定义在方法或代码块中仅在代码块或方法中可见通常用于临时的对象构建 匿名内部类:没有类名的内部类通常用于创建短期使用的对象实例尤其是在接口回调或者事件处理时被广泛使用。十一、Java 中 String、StringBuffer 和 StringBuilder 的区别是什么?线程安全:String、StringBuffer 线程不安全:StringBuilderString是不可变类底层用final修饰每次对String进行修改的时候会生成新的副本从而占用更多的资源频繁大量的修改会造成资源的浪费StringBuffer为了解决String的可能造成资源浪费问题底层使用char新增了append方法来修改字符串同时各个修改方法加上了sychronized同步锁所以它是线程安全的但是需要消耗一定的性能作为代价StringBuilder是在StringBuffer的基础上将同步锁给去除掉了舍弃了线程安全但换来了更高的性能使用场景: 1、String:适用与少量的修改 2、StringBuffer:修改频率很高需要保证线程安全的情况下使用 3、StringBuilder:修改频率很高不需要保证线程安全 细节:由于StringBuffer和StringBuilder底层是数组实现所以会涉及到扩容的机制如果在使用时知道大概的数据量在创建实例时可以给其赋予初始大小减少扩容次数提高性能十二、java的Stringbuilder是怎么实现的StringBuilder内部有一个字符数组这个数组用来存储字符串。当你开始拼接字符串时StringBuilder会先检查这个内部数组是否有足够的空间来存放新的字符串。如果内部数组空间不够StringBuilder会自动进行扩容。它会创建一个新的更大的数组并将旧数组的内容复制到新数组中然后再加上新的字符串。这个过程叫做动态扩容。十三、Java 中包装类型和基本类型的区别是什么?1.基本数据类型占用的内存小效率高包装数据类型占用的内存大 2.基本数据类型的默认值为0,false包装数据类型的默认为null 3.基本数据类型如果是局部变量存放在栈中如果是成员变量存放在堆中包装数据类型存放在堆中 4.包装数据类型可以用于泛型基本数据类型不可以用于泛型 5.基本数据类型直接赋值包装数据类型需要通过new对象 6.基本数据类型使用比较值包装数据类型使用比较内存地址使用重写后的equals比较值十四、接口和抽象类有什么区别接口是协议调用方无需关心实现细节实现方维护底层实现在实现发生变更时调用方无需感知; 抽象类是模版即一些类共有的部分可以抽象出来提高代码复用便于子类扩展。篇幅限制下面就只能给大家展示小册部分内容了。整理了一份核心面试笔记包括了Java面试、场景题、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafc需要全套面试笔记及答案【点击此处即可/免费获取】​https://docs.qq.com/doc/DQXdYWE9LZ2ZHZ1ho十五、JDK和JRE有什么区别1.JDK JRE 开发工具集(例如 Javac,java 编译工具等JRE JVM Java SE 标准类库(java 核心类库)3.如果只想运行开发好的 .class 文件 只需要 JRE十六、Java 中 hashCode 和 equals 方法是什么?它们与 操作符有什么区别?hashCode: 快速比较两个对象是否相同,hash码不同肯定不相等。但是hash码相同也不一定相等。 equals方法:比较两个对象的内容是否相等。通常需要自己实现对象的比较逻辑。 :如果是引用比较的是内存地址:如果是基本数据类型比较的是值。十七、Java 中的 hashCode 和 equals 方法之间有什么关系?这两者的关系主要体现在HashMap和HashSet中HashMap和HashSet底层都是有数组作为数据结构的所以在查询的时候会先用hashCode方法去计算获得key的唯一hash值也就是这个key在数组中所在的位置然后在这个位置中去使用equals方法去比较具体的属性值是否一致。所以说两个对象的equals相等那么他们的hashCode()也必须相等那是因为hashCode如果不相等就会导致hashMap和HashSet中存在相同的key值这显然不符合定义。十八、什么是java中的动态代理动态代理是一种在运行时生成代理对象的机制允许在不修改原始类的情况下为其方法调用添加额外的行为。 AOP(面向切面编程)是动态代理的一个实际应用它通过代理为核心业务逻辑添加横切关注点(如日志、事务等)。 在 Java 中Spring AOP 可以基于 JDK 动态代理或 CGLIB 动态代理来实现。 简单来说AOP 通过动态代理来实现面向切面的编程。十九、JDK 动态代理和 CGLIB 动态代理有什么区别?JDK动态代理:基于Java反射只能代理实现了接口的类。首先通过InvocationHandler接口得到一个切面类然后利用Proxy根据目标类的类加载器、接口和切面类得到一个代理类。CGLIB代理:基于字节码技术可以代理所有对象。首先通过Methodlnterceptor接口得到一个拦截类new一个enhancer传入需要代理的类创建callback方法并设置拦截类再使用enhancer.create()方法返回一个代理类同时这个代理类和方法不能被final修饰。二十、java的注解原理是什么注解就是一个标记是给机器看的就是在类或者方法或属性中设置一些标记注解本身不影响代码执行相当于标记一些元数据注解一些代码可以生命文档也可以作为切面增强。其中Retention可以说明注解的有效访问source、class、runtimeTarget可以说明注解应用元素field、method等。二十一、你使用过java的反射机制吗如何应用反射Java 的反射机制是指在运行时获取类的结构信息(如方法、字段、构造函数)并操作对象的一种机制。对于任意一个类都能够知道这个类的所有属性和方法对于任意一个对象都能够调用它的任意方法和属性并且能改变它的属性。Java反射机制的核心是在程序运行时动态加载类并获取类的详细信息从而操作类或对象的属性和方法。其本质是JVM得到Class对象之后再通过Class对象进行反编译从而获取对象的各种信息。java反射的优点可以动态地获取类的信息不需要在编译时就知道类的信息。 可以动态地创建对象不需要在编译时就知道对象的类型。 可以动态地调用对象的属性和方法在运行时动态地改变对象的行为。应用场景有spring就是使用反射机制来读取配置文件实现依赖注入和aop。二十二、什么是泛型泛型的作用是什么泛型允许类、接口和方法在定义时使用一个或多个类型参数这些类型参数在使用时可以被指定为具体的类型。类型安全:运行时异常转为编译时异常提早发现异常确保类型安全代码重用:方法或者类可以使用泛型使方法和类能够处理多种不同的数据类型。而不用每个数据类型都写一个方法或者类。二十三、java的泛型擦除是什么java的泛型擦除是指java编译器在编译过程中将所有的泛型信息删除的过程这样做的目的是为了保证java版本的兼容性因为在java5之前一些集合比如ArrayList和LinkedList都是非泛型化的java5之后这两个集合都是泛型化的为了保证这两个java版本的兼容性就有这个泛型擦除。会在编译的时候将E替换成Object并通过插入类型转换指令保持类型安全和多态性。二十四、Java 中的深拷贝和浅拷贝有什么区别?深拷贝:不仅拷贝对象本身和基本类型成员变量堆内的引用对象也会复制一份(相互独立不干扰) 浅拷贝:仅拷贝对象本身和基本类型成员变量共享堆内的引用对象(仅复制引用地址)二十五、什么是 Java 的 Integer 缓存池?java的Interger缓存池为了提高性能和减少内存在-128到127以内的对象会被缓存并复用例如interger a 127这时候就会将a放进interger缓存池在interger b 127的时候并不是重新创建创建一个对象而是去interger缓存池查找有没有这个值的缓存对象有的话直接拿过来用没有才去重新创建并存入缓存池。二十六、java的类加载过程是怎样的Java的类加载过程包括加载、链接和初始化三个主要步骤。 1.在加载阶段通过类加载器将类文件加载到内存中生成一个Class对象。 2.在链接阶段包括 验证 、 推备 和 解析 三个子阶段确保类的字节码安全并为静态变量分配内存和进行符号引用解析。 3.最后在初始化阶段执行类的初始化逻辑将静态变量和静态代码块的初始化操作整合并执行。二十七、String s new String(abc)会创建几个对象1.首先new会先在堆内存中创建一个String对象(第一个对象称它为new String对象吧)并让s引|用指向该对象。2.JVM用字面量”abc“去字符串常量池中尝试获取“abc”对应的String对象的引用。 2.1 如果获取成功则让new String对象引用常量池中的abc” 2.2 如果获取失败则在堆内存中创建一个abc的String对象(第二个对象)并把它的引用保存在字符串常量池。然后让newString 对象引用常量池中的abc。所以使用new String方法时会创建1个或者2个对象。二十八、如果一个线程在 Java 中被两次调用 start() 方法会发生什么?会报错!因为在 Java 中一个线程只能被启动一次!所以尝试第二次调用 start() 方法时会抛出 legalThreadStateException 异常。这是因为一旦线程已经开始执行它的状态不能再回到初始状态。线程的生命周期不允许它从终止状态回到可运行状态。二十九、java的IO流是什么Java的I/O流是用于处理数据输入输出的类库可以从各种位置读取数据也可以将数据写入特定位置I/O流分为两大类: 字节流:处理8字节数据适合处理二进制文件比如图片、视频。承担任务的类有Inputstream和Outputstream类及其子类。 字符流:处理16字节数据适合处理文本文件。承担任务的类有Reader和Writer及其子类。三十、java的基本数据类型有哪些四种八类 1.整型byte 1字节short 2字节int 4字节long 8字节2.浮点型float 4字节double 8字节字符型char 2字节4.布尔型boolean 不定四十一、什么是java的自动拆箱和装箱自动装箱:将基本数据类型自动的转化为包装类型 自动拆箱:将包装类型自动转化为基本数据类型 减少了代码复杂度减少了代码的编写常见于集合处理 算数运算。四十二、什么是java中的迭代器迭代器就是java集合框架提供的一种用来遍历集合元素的接口,可以遍历和修改集合的元素(set,map)。 通过ltearator. hasNext()看是否有下一个元素。通过ltearator. next()返回其元素。四十三、Java 运行时异常和编译时异常之间的区别是什么?编译时异常是指在编写程序时编译器检查出来的异常需要显示的进行处理try catch 进行捕获或者throw扔出。常见的编译异常如FileNotFoundExceptionIOException等运行时异常是在程序运行时抛出的异常需要在代码编写时处理好逻辑减少运行时异常。常见的运行时异常如算数异常空指针异常数组下标越界异常等四十四、Java 中的访问修饰符有哪些?访问权限:用来控制类、方法、变量的访问级别有4种:public、protected、default、private public:访问权限最大当前类、当前包、子类(不同包)、不同包可以访问 protected:当前类、当前包、子类(不同包)可以访问 default:当前类、当前包可以访问 private:当前类可以访问篇幅限制下面就只能给大家展示小册部分内容了。整理了一份核心面试笔记包括了Java面试、场景题、Spring、JVM、MyBatis、Redis、MySQL、并发编程、微服务、Linux、Springboot、SpringCloud、MQ、Kafc需要全套面试笔记及答案【点击此处即可/免费获取】​https://docs.qq.com/doc/DQXdYWE9LZ2ZHZ1ho四十五、Java 中静态方法和实例方法的区别是什么?静态方法:1.属于类 2.可以使用类名访问 3.不能访问实例变量和实例方法 4.场景:作为工具类的方法实例方法:1.属于对象 2.只能通过对象访问 3.可以访问静态变量和静态方法六、什么是 Java 中的双亲委派模型?双亲委派模型是 Java 类加载机制的设计模式之一。它的核心思想是:类加载器在加载某个类时会先委派给父类加载器去加载父类加载器无法加载时才由当前类加载器自行加载。工作流程:当一个类加载器(如自定义类加载器)试图加载某个类时先将加载请求向上委派给父类加载器父类加载器再向上委派给它的父类直到根类加载器(Bootstrap ClassLoader)。在 JDK9 之前Java 自身提供了 3种类加载器: 1.启动类加载器( Bootstrap classLoader )它是属于虚拟机自身的一部分用 C实现的主要负责加载JAVA_HOME\1ib 目录中或被xbootclasspath 指定的路径中的并且文件名是被虚拟机识别的文件。它是所有类加载器的爸爸。 2.扩展类加载器( Extension classloader),它是 Java 实现的独立于虚拟机主要负责加载JAVA HOME\lib\ext 目录中或被java.ext.dirs 系统变量所指定的路径的类库, 3.应用程序类加载器( Application classoader),它是Java 实现的独立于虚拟机。主要负责加载用户类路径( classpath)上的类库如果我们没有实现自定义的类加载器那这玩意就是我们程序中的默认加载器。 所以一般情况类加载会从应用程序类加载器委托给扩展类再委托给启动类启动类找不到然后扩展类找扩展类加载器找不到再应用程序类加载器找。为什么要有双亲委派机制安全性:避免重复加载类。例如java.lang.0bject 类只能由根类加载器加载防止恶意代码加载不受信任的类来替代系统核心类。一致性:保证同一个类在 JVM 中只会被加载一次确保在整个应用中使用的是同一个类对象。双亲委派机制先自下而上委托再自上而下加载那为什么不直接自上而下加载?因为本来类加载器是组合关系也就是子加载器只记录了父加载器父加载器没记录子加载器(找不到子加载器)其次如果先父加载器接活再传给子加载器假设有5个子加载器(比如5个平级的自定义加载器)传给哪个加载呢?每个试过去嘛?效率就不高了。一般聊到双亲委派机制会说到类加载过程具体看以下博文每日速记10道java面试题03-CSDN博客四十七、java中sleep和wait方法的区别1.sleep方法 属于Thread类中的方法 释放cpu给其它线程 不释放锁资源 seep(1000)等待超过1s被唤醒wait方法 属于Object类中的方法 释放cpu给其它线程同时释放锁资源 wait(1000) 等待超过1s被唤醒 wait() 一直等待需要通过notify或者notifyAll进行唤醒 wait 方法必须配合 synchronized 一起使用不然在运行时就会抛出legalMonitorStateException异常四十八、什么是BIO、NIO、AIOBIO阻塞IO:人一直盯着水烧开水烧开之后亲自关火 NIO非阻塞IO:人在烧水的时候去干别的事情时不时看着水烧没烧开烧开之后亲自关火 AIO异步IO:人找了一个帮手帮手在烧水的时候一直盯着水烧开之后帮手关火然后提醒人水烧开了。人全程不管烧水的事情四十九、什么是Channel是非阻塞式IO中的一个核心概念NIO是一种更有利于数据读写操作的数据结构1.Channel是双向的可以同时进行读取和写入2.非阻塞式的可以引入Selector实现多路复用并发操作。Channel有四种实现,SocketChannel、ServerSocketChannel、DatagramChannel、FileChannel

更多文章