文章目录
-
- 1.说一下Java内存模型?
- 2.List、Set、Map的区别?
- 3.介绍一下设计模式?
- 4.MySQL存储结构?
- 5.索引失效的场景?
- 6.为什么使用函数索引会失效?
- 7.Spring事务有哪两种?
-
- 7.1 编程式事务@RestController
- 7.2 声明式事务
- 8.@Transactional实现原理?
- 9.事务如何合并@Transactional修饰的方法?
- 10.Redis数据类型有哪些?
- 11.Redis如何实现分布式锁?
- 12.什么时候用RocketMQ?
- 13.说下RocketMQ和OpenFeign的应用场景?
- 14.抽象类和接口的区别?
- 15.什么时候用抽象类?什么时候用接口?
- 16.try、catch、finally各有return,会怎么执行?
- 17.服务宕机时直接降级是最优解吗?
1.说一下Java内存模型?
注意,当问到 Java 内存模型的时候,不要和 JVM 内存布局(JVM 运行时数据区域)搞混了,这块问的不是 JVM 内存的布局是啥,而是 Java 内存模型,Java Memory Model,简称 JMM。
Java 内存模型是用来定义 Java 线程和内存之间的操作规范的,目的是解决多线程正确执行的问题。 Java 内存模型规范的定义确保了多线程程序的可见性、有序性和原子性,从而保证了线程之间正确的交互和数据一致性。 Java 内存模型主要包括以下内容:
- 主内存(Main Memory):所有线程共享的内存区域,包含了对象的字段、方法和运行时常量池等数据。
- 工作内存(Working Memory):每个线程拥有自己的工作内存,用于存储主内存中的数据的副本。线程只能直接操作工作内存中的数据。
- 内存间交互操作:线程通过读取和写入操作与主内存进行交互。读操作将数据从主内存复制到工作内存,写操作将修改后的数据刷新到主内存。
- 原子性(Atomicity):JMM 保证基本数据类型(如 int、long)的读写操作具有原子性,即不会被其他线程干扰,保证操作的完整性。
- 可见性(Visibility):JMM 确保一个线程对共享变量的修改对其他线程可见。这意味着一个线程在工作内存中修改了数据后,必须将最新的数据刷新到主内存,以便其他线程可以读取到更新后的数据。
- 有序性(Ordering):JMM 保证程序的执行顺序按照一定的规则进行,不会出现随机的重排序现象。这包括了编译器重排序、处理器重排序和内存重排序等。
Java 内存模型通过以上规则和语义,提供了一种统一的内存访问方式,使得多线程程序的行为可预测、可理解,并帮助开发者编写正确和高效的多线程代码。开发者可以利用 JMM 提供的同步机制(如关键字 volatile、synchronized、Lock 等)来实现线程之间的同步和通信,以确保线程安全和数据一致性。
内存模型的简单执行示例图如下:
2.List、Set、Map的区别?
List、Set 和 Map 都是常见的集合接口,用于存储和操作数据,它们的区别如下:
- List 是有序的集合,允许重复元素,可以按索引访问。它的常见实现类有 ArrayList、LinkedList 和 Vector。
- Set 是无序的集合,不允许重复元素。它的常见实现类有 HashSet、TreeSet 和 LinkedHashSet。
- Map 是键值对的映射集合,键不允许重复,值可以重复。它的常见实现类有 HashMap、TreeMap 和 LinkedHashMap。
3.介绍一下设计模式?
当聊到设计模式时,可以举一些常见的设计模式,以及这些设计模式的具体应用,比如以下这些:
- 工厂模式(Factory Pattern): 工厂模式是一种创建型设计模式,它提供了一种创建对象的方式,使得应用程序可以更加灵活和可维护。比如在 Spring 中,FactoryBean 就是一个工厂模式的实现,使用它的工厂模式就可以创建出来其他的 Bean 对象。
- 单例模式(Singleton Pattern):单例模式是一种创建型设计模式,它保证一个类只有一个实例,并提供了一个全局访问点。比如在 Spring 中,所以的 Bean 默认是单例的,这意味着每个 Bean 只会被创建一次,并且可以在整个应用程序中共享。
- 代理模式模式(Proxy Pattern): 代理模式是一种结构型设计模式,它允许开发人员在不修改原有代码的情况下,向应用程序中添加新的功能。比如在 Spring AOP(面向切面编程)就是使用代理模式的实现,