为什么重写 equals 还要重写 hashCode 方法
1、如果 equals 和 hashCode 方法的实现不一致,在集合中使用时可能会报错,比如找不到对象、重复存储对象
2、比如 Set 集合存储的是不重复的对象,它就是根据 equals 和 hashCode 方法进行判断的
3、避免内存泄露:当 key 是自定义对象时重写 equals 和 hashCode 方法能够避免创建相同的对象,从而避免内存浪费
4、阿里巴巴开发手册:规定只要重写 equals 就必须重写 hashCode 方法
equals 方法
1、默认采用 == 比较对象的内存地址是否相等,所以我们需要重写为根据对象的内容值进行判断
hashCode 方法
1、底层用 C 语言写的,根据对象的内存地址生成一个整数。
内存泄漏
1、内存泄露就是内存不释放。比如一个教室的学生上完课了不走,导致下一节课的学生进不来。
内存溢出
1、内存溢出就是内存不够用。比如一个教室只能容纳一个班的学生,但是来了两个班的学生。
请你说说 Java 的特点和优点,为什么要选择 Java
1、面向对象,支持封装、继承、多态
2、跨平台,源代码编译成字节码后,由不同操作系统的 JVM 运行
3、支持多线程,能够处理并发需求
HashMap 时间复杂度
1、key 没有冲突,时间复杂度为 O (1)
2、key 产生冲突,链表存放则为 O (N),红黑树存放则为 O (logN)
请你说说 Java 基本数据类型和引用类型
1、提供 8 种基本数据类型:byte (1), short (2), int (4), long (8), float (4), double (8), char (2), boolean (1/8)
2、除了 8 种基本数据类型之外的都是引用数据类型,比如 String
3、基本数据类型存在栈中
4、引用数据类型的地址存在栈中,内容存在堆中
请你说一下抽象类和接口的区别
1、都不可以被实例化,抽象类可以有构造器,接口不能有构造器
2、抽象类用 extends 继承,接口用 implements 实现
3、类只能继承一个抽象类,但是可以实现多个接口
4、抽象类可以定义抽象方法和非抽象方法,JDK1.8 开始接口可以定义默认方法和静态方法
5、接口的变量都是 public static final 的,方法默认是 public 的
6、抽象类是 “is-a” 关系,强调所属关系,而接口是 “has-a” 关系,强调功能实现
介绍一下 MyBatis 的缓存机制
1、MyBatis 提供了一二级缓存机制,避免每次查询都去访问数据库。
2、一级缓存是默认开启的,生命周期和 SqlSession 一样,在同一个 SqlSession 中对于相同的查询语句只会执行一次,并且将结果放到 SqlSession 的本地缓存中。
3、每个 SqlSession 都有一个 Executor,Executor 有一个 LocalCache 成员变量,它就是本地缓存。
4、一级缓存的数据结构是 HashMap,虽然 HashMap 是线程不安全的,但因为一级缓存只作用在同一个 SqlSession 中,所以它是线程安全的。
5、也正是因为一级缓存只作用在同一个 SqlSession 中,所以缓存不能跨会话共享,当有多个会话或者在分布式环境下时,可能会存在脏读的问题。
6、解决脏读的方法是将缓存级别设置为 statement,它会在增删改查时清空缓存。
7、二级缓存是全局缓存,可以被多个 SqlSession 共享,同时粒度更加的细,能够控制到 namespace 级别,一个名称空间对应一个二级缓存。
8、当开启二级缓存后,会在一级缓存之前使用 CachingExecutor 装饰 Executor,查询顺序就变成了 “二级缓存、一级缓存、数据库”。
9、平时开发的话,一般都是关闭 MyBatis 的二级缓存,单纯作为一个 ORM 框架来使用的,然后使用 Redis 实现分布式缓存。
@Resource
private SqlSessionFactory sqlSessionFactory;
UserMapper userMapper = sqlSessionFactory.openSession(true).getMapper(UserMapper.class);
mybatis-plus:
configuration:
# 禁用二级缓存
cache-enabled: false
# 设置一级缓存级别,可选值 session、statement
local-cache-scope: statement