1.什么是 Java 内部类? 内部类的分类有哪些 ?内部类有哪些优点和应用场景?
顾名思义,内部类是指定义在某一个类中的类,主要分为成员内部类,静态内部类,局部内部类和匿名内部类四种。
创建与获取
// 1、私有内部类 => 在外部类中编写方法,对外提供内部类对象 // 定义方法(外部类中) public Inner getInstance(){ return new Inner(); } // 使用方法 Outer o = new Outer(); Object i = o.getInstance(); // 2. 非私有内部类 => 直接创建成员内部类 // 外部类名.内部类名 对象名 = new 外部类对象.new 内部类对象; Outer.Inner oi = new Outer().new Inner();优点
可以隐藏实现细节。
便于编写和维护,提高代码的可读性和可维护性。
使用内部类解决 Java单继承问题
可以更换的对外部类进行扩展
注:JDK16 之前成员内部类里不能定义静态变量
2.覆盖索引和联合索引是什么?讲一下索引的最左前缀匹配原则。
覆盖索引和联合索引是数据库中常见的两种索引类型。
覆盖索引是指一个包含了所有查询需要的列的索引,查询时可以直接从索引中取到需要的数据,而不需要再回到表中查找,从而可以提高查询效率。
联合索引是指使用多个列组合起来作为一个索引,可以同时查询多个列,以提高查询效率。联合索引可以包含多个列,但是查询时只能使用前缀列进行查询,即只有在查询中使用了联合索引的前几个列,才能利用联合索引进行查询。如果查询中没有使用前缀列,那么联合索引就不能发挥作用,需要使用单独的索引或全表扫描。
-- 假设有联合索引(A,B,C) SELECT A,B,C FROM table -- 使用覆盖索引,查询列均为索引列,无需回表最左前缀匹配原则是指如果一个联合索引包含了多个列,那么在查询时只能使用前面的列进行匹配。例如,一个联合索引包含了 A、B、C 三列,那么查询时只能使用 A、AB 或 ABC 进行匹配,而不能只使用 B 或 C 进行匹配。这是因为如果查询时使用的列不是最左前缀列,那么 MySQL 就无法使用索引进行查询,会导致全表扫描,从而降低查询效率。
-- 假设有联合索引(A,B,C) SELECT A,B,C FROM table WHERE A=1 AND B=1 -- 满足最左前缀匹配原则,可以使用到联合索引 SELECT A,B,C FROM table WHERE B=1 AND C=1 -- 不满足最左前缀匹配原则,未使用到联合索引在实际的应用中,覆盖索引和联合索引可以结合使用,以提高查询效率。同时,使用最左前缀匹配原则可以让我们更加合理地设计索引,从而提高查询性能。
3.Spring 如何处理线程并发问题,ThreadLocal 你了解过吗?
Spring 如何处理线程并发问题?
Spring 中处理线程并发问题的主要方式是使用线程安全的对象和并发包中提供的类来避免线程安全问题。
例如,Spring 中的单例 Bean 是线程安全的,因为 Spring 容器在创建单例 Bean 时会确保只有一个实例存在。Spring 还提供了对多线程的支持,例如使用 @Async 注解实现异步方法调用等。
在 Spring 中处理线程并发问题,常用的方法有以下几种:
Synchronized关键字
:使用 synchronized 关键字可以锁定某个对象或类,使得多个线程无法同时进入该代码块,从而保证数据的安全性。
ReentrantLock
:与 synchronized 相比,ReentrantLock 提供了更加灵活的加锁方式,可以控制锁的获取和释放的时机,提供了更多的扩展功能。
Atomic 包
:Java 的 Atomic 包提供了一些原子性操作,例如 AtomicLong、AtomicInteger 等,可以保证某个操作的原子性。
ThreadLocal
:ThreadLocal 可以使得每个线程拥有自己的变量副本,避免了多个线程之间共享变量所带来的线程安全问题。ThreadLocal 你了解过吗?
ThreadLocal 是 Java 中的一个线程局部变量,它可以为每个线程提供一个独立的变量副本,避免了多线程之间的数据共享和数据竞争问题。
ThreadLocal 可以在每个线程中存储一个对象,并且每个线程只能访问自己的对象,而不会影响其他线程中的对象。
ThreadLocal 主要用于解决线程安全问题,例如在 Web 应用中,可以使用 ThreadLocal 存储用户的会话信息,这样每个线程就可以独立地访问自己的会话信息,避免了多个线程之间的数据共享和数据竞争问题。
在 Spring 中,ThreadLocal 通常用于存储和传递一些与线程相关的上下文信息,例如当前登录用户的信息、请求的 IP 地址等。可以将 ThreadLocal 对象定义为一个 Bean,然后在需要使用时注入到其他 Bean 中使用。
Spring 还提供了一些与 ThreadLocal 相关的类和工具,例如 SimpleThreadScope,用于实现线程范围内的 Bean,以及 TaskExecutor,用于在多线程环境中执行任务。