1.什么是序列化和反序列化?
- 序列化 序列化是将对象转换成字节流的过程,方便与网络传输和持久化存储,java提供了Serializable接口来方便实现序列化,只要实现了这个接口就可以进行序列化
- 反序列化 是指将字节流重新转换成对象的过程,从字节流中读取信息然后重新创建对象
2.什么是JAVA中不可变类?
java中不可变类是指被final关键字修饰的类,一旦被创建之后其属性(字段)就不可以被修改
final关键字修饰类时不可被继承,修饰方法时不能被重写(但是可以被重载),修饰字段时属性不可以被改变
3.JAVA中Exception和Error有什么区别?
Error和Exception都是继承自Throwable类,其中Error一般指的是JVM层级的内部错误而Exception是指可以被处理的异常
Exception分为checkedException(编译时异常)和uncheckedException(运行时异常),其中编译时异常需要被显示处理,是可以提前预见的(比如IOException),通过try-catch捕获处理或者用throw抛出
4.你认为JAVA的优势是什么?
可以从跨平台,垃圾回收,生态,面向对象四个方面进行处理
跨平台:JAVA是运行在JVM中的,所以不论在什么机器上都可以运行
垃圾回收:JVM中有垃圾回收机制,可以帮助我们管理内存,不需要我们去手动分配内存,可以将注意力集中在代码编写上
生态:JAVA有着非常庞大的生态
面向对象:JAVA是一个严格的面相对象的编程语言有助于代码的可维护性和扩展性
5.什么是JAVA的多态性?
java多态指的是同一个接口或者父类的引用可以指向不同的实例对象,并根据具体的实例对象来执行相应的方法
优点:增强了系统的可扩展性,降低了代码的耦合度
6.JAVA中的参数传递是按值还是按引用?
JAVA中参数传递对于基础类型来说传递的是副本,对于引用类型对象传递的是“引用”即这个对象的地址
所以即使是传入引用,也可以改变这个对象内部的属性
7.JAVA为什么不支持多继承?
因为可能会出现菱形继承问题,如果B,C是A的子类,并且都实现了A的一个方法,假设支持多继承,如果现在D同时继承了B,C那么当子类D想要调用父类A的一个方法的时候就不知道是要调用B的还是调用C的了
扩展:为什么可以多实现呢?
java8之前如果要实现一个类就必须要实现这个类的所有方法,这样就不会出现子类要调用父类的方法了
但是JAVA8之后出现了默认方法(defuault method),为了避免菱形问题再次发生,java强制规定,当多个接口拥有相同的默认方法的时候,子类必须要重写这个方法
8.JAVA面向对象编程和面相过程编程的区别是什么?
面向对象编程:指以对象为中心的一种编程风格,把类或对象当做基本单元来组织代码
面相过程编程:指以过程或者函数为中心的一种编程风格,把过程当做基本单元来组织代码
9.JAVA重载和重写有什么区别?
- 发生场所:
重载发生在同一个类中,重写发生在父子类中
- 条件不同:
重载只要求参数名相同,对参数列表,返回值类型,final修饰等都没有要求
重写要求参数列表,参数名,返回值类型都要相同
重载既可以重载静态方法也可以重载非静态方法,重写只能重写非静态方法
- 访问修饰符:
重载没有限制,重写的方法的修饰符不能比父类的更加严格
10.什么是JAVA的内部类?有什么作用?
JAVA内部类分为
成员内部类(非静态):可以访问外部类的所有所有成员,包括私有成员
静态内部类:无法访问外部类的非静态成员变量,只能访问静态成员变量
局部内部类:只能在局部内访问
匿名内部类:(常用于回调函数等)
11.JAVA8有哪些新特性?
- 引入了Lambda表达式
- 引入日期类,接口的默认方法,静态方法
- 新增Stream流接口
- 引入Optional类
Lambda表达式:
类似于js中的匿名函数
日期类:
常用:LocalDataTime.now()可以直接获取当前时间
输出的时间格式是 LocalDateTime 的默认字符串表示形式,通常是 yyyy-MM-ddTHH:mm:ss.nnnnnn (例如: 2025-02-17T15:30:45.123456 )
创建一个DateTimeFormatter 类来进行时间格式化
LocalDateTime now = LocalDateTime.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String formattedDate = now.format(formatter);
System.out.println(formattedDate); // 输出示例:2025-02-17 15:30:45
接口的默认方法和静态方法
java8之后提供了默认方法可以使得接口创建默认方法,此时子类继承的时候就不必实现这个方法
Stream流式接口
Stream流是JAVA8引入的一个高级迭代器用于处理集合元素(Collections)
Stream流只会遍历一次
创建流:
数组创建流:Arrays.stream()或者Stream.of()方法
集合创建流:直接调用集合中的stream()方法或者使用parallelStream()方法创建并发流
操作流:
可以使用.filter方法对数据进行过滤,
映射:使用.map()方法将流中的元素转换成新的流
匹配:使用anyMatch()匹配(只要有一个满足即返回true
allMatch()所有的都满足才返回True
noneMatch()只要有一个满足传入条件就返回false,全部不满足才返回true
组合:reduce()方法
转换流:将流转换成集合或数组
使用toArray()方法将集合转换成数组
使用collect()方法将集合转换成List()或者其他,比如collect(Collector.toList())
Collectors 是一个收集器的工具类,内置了一系列收集器实现,比如说 toList() 方法将元素收集到一个新的 java.util.List 中;比如说 toCollection() 方法将元素收集到一个新的 java.util.ArrayList 中;比如说 joining() 方法将元素收集到一个可以用分隔符指定的字符串中。
Optional类
用处:优雅地处理可能为null的值,避免显示处理null
创建optional类:
使用静态方法empty(),of(value),ofNullable(value)来创建optional对象
比如Optional option=Optional.ofNullable<>(),这个泛型就是即将要存入对象的泛型
可以使用.isPresent()方法和isEmpty()方法来判断值是否存在(即是否为null)
使用orElse()和orElseGet()方法来处理如果值为null的时候应该怎么做
Optional中也有filter()方法和Map()方法,通过这两个方法返回新的Optional对象
12.JAVA中Stirng,StringBuffer,StringBuilder之间有什么区别?
String为不可变类,不利于频繁增删改这样的操作
StringBuilder和StringBuffer都是可变的,其中StringBuilder是非现成安全的,StringBuffer是线程安全的
13.JAVA中StringBuilder是如何实现的?
内部使用 char数组(char[] value)来保存字符串序列,当需要增删改的时候直接改变字符数组而不是像String类型一样创建一个新的对象返回;操作字符串的时候如果容量不足会直接扩容两倍来减少扩容容量,提高扩容性能
14.JAVA中基本类型和包装类型的区别是什么?
基本类型有:boolean,char,byte,short,int ,float,long,double
是可以直接存储数值的变量,位于栈上(局部变量在栈上,成员变量在堆上,静态字段在方法区),性能较高且不支持Null
包装类型有:Boolean,character,Byte,Short,Integer,Long,Float,Double
包装类型是类,存储在堆中,可以用于面向对象编程,并且支持null,可以用于面向对象编程
扩展:java中很多地方都是用对象所以会设计自动装(拆)箱
装箱:将基本类型转换成包装类型
拆箱:将包装类型重新转换成基本类型
缓存机制:比如Integer的缓存机制(就是-128~127之间的数很常用所以创建了一个缓存区,用来存放值在这个范围的对象,这样如果两个Integer对象的值相同,这两个Integer对象不是一样的,但是其内部的值指向的是同一个缓存区内的对象)
15.接口和抽象类有什么区别?
接口是自上而下的,是提前知道了一些行为,为了约束这些行为创建出一个接口来进行规范
而抽象类是自下而上的,是写了多个代码之后发现有重复的地方,为了减少代码的复用,将这些公共逻辑封装成一个抽象类减少代码的冗余
- 方法实现
接口中的方法默认是public和abstract的(java8之后可以有静态方法和默认方法)
抽象类可以包含abstract方法和具体的方法,并且子类可以调用这些具体的方法
- 构造函数和成员变量 接口不能包含构造函数,接口默认变量类型为public static final,即常量 抽象类可以包含构造函数,并且对成员没有限制
16.JDK和JRE有什么区别?
JDK:java开发工具包
JRE:java运行环境
JRE包含JVM和其他类库
JDK包含完整的JRE和其他开发工具,如编译器(javac),java文档生成器(javadoc)
打包工具(jar),调试器(jdb)等
17.你是用过那些JDK提供的工具?
- java命令,运行java应用程序的命令,使用JVM来解释并执行编译后的字节码文件
- javac:java编译器,负责将java源代码编译成字节码(.class文件)
- javadoc:java文档生成器,用于生成API文档
- jar:用来打包
- jdb:java调试工具可以在命令行中调试java应用程序,支持断点设置,变量查看等功能
18.JAVA中hashCode()和equals()方法和==有什么区别?
==方法
对于基本类型变量是判断值是否相等
对于引用类型变量判断是否为同一个对象(即内存地址是否相等)
equals()方法,object类中的方法,不过现在大部分类都自主重写了这个方法 ,用于引用类型判断值是否相等
hashCode()方法,返回对象的哈希码,Object类(默认会根据内存地址来生成哈希码)中的方法,基本上每一个类都会重写hashCode()方法
tip:如果两个对象的值equals()方法判断是相等的,那么他们的hashCode()方法也一定是相等的,
反之:如果hashCode()方法是相等的,他们的equals方法不一定相等但是会被放在同一个哈系桶中
因为大部分hashCode()方法都是根据值算出来的
19.JAVA中hashCode()和equals()方法有什么联系?
1.如果两个对象的值equals()方法判断是相等的,那么他们的hashCode()方法也一定是相等的,
反之:如果hashCode()方法是相等的,他们的equals方法不一定相等但是会被放在同一个哈系桶中
因为大部分hashCode()方法都是根据值算出来的
2.在hashMap或者hashSet存储的数据中如果重写了equals()方法就一定要重写hashCode()方法,都则可鞥会造成hashCode和hashMap不能正确的保存和检索值
20.什么是JAVA中的动态代理?
java动态代理是一种在运行时创建代理对象的机制,可以使在运行时决定对象的行为,而不用在编译的时候就确定
可以在不修改类的情况下对其进行修改
扩展:java动态代理只能堆接口进行代理不支持对类进行代理
CGLIB代理:通过字节码技术可以实现对类进行代理
AOP技术就是使用JAVA动态代理和CGLIB代理,默认时使用java代理,如果要代理的类没有实现接口就使用CGLIB进行代理
21.JDK动态代理和CGLIB代理有什么区别?
jdk动态代理:
基于接口,要求目标类(被代理的类)必须实现一个或多个接口,并且只能代理目标类中实现接口的方法
也就是说如果这个目标类自己定义了一个方法不是接口中的方法,那么这个方法是不能被java动态代理的,需要使用CGLIB代理
原理:根据接口生成代理类,将代理类的方法转发到InvocationHandler 的 invoke() 方法,在这里定义对代码的增强
CGLIB代理:通过生成目标类的子类来进行代理,所以这个目标类不能是final类,方法也不能是fianl方法