spring的事务传播机制是什么?
在Spring中,事务的传播机制定义了在多个事务方法之间如何传播事务。当一个方法调用另一个方法时,如果被调用方法需要事务支持,那么事务的传播机制决定了是否使用调用方的事务或创建一个新的事务。
Spring定义了多种事务传播机制,以下是其中一些常见的:
- REQUIRED(默认):如果当前没有事务,就创建一个新的事务;如果当前已经存在事务,就加入到当前事务中。
- REQUIRES_NEW:每次调用该方法都会创建一个新的事务,如果当前已经存在事务,则挂起当前事务。
- SUPPORTS:如果当前有事务,就加入到当前事务中,如果没有事务,就以非事务的方式执行。
- NOT_SUPPORTED:以非事务方式执行,如果当前存在事务,则挂起当前事务。
- MANDATORY:当前必须存在事务,否则抛出异常。
- NEVER:当前必须不存在事务,否则抛出异常。
- NESTED:嵌套事务,如果当前有事务,则嵌套在当前事务中,如果没有事务,则创建一个新的事务。
Spring的事务传播机制允许我们在不同层级的方法之间进行事务管理,以保证数据的一致性和完整性。通过合理的选择事务传播机制,我们可以灵活地管理事务边界,从而确保业务逻辑的正确执行。
b树、b 树、红黑树有什么区别
B树、B 树和红黑树都是常见的自平衡二叉查找树,用于在数据库和文件系统等数据结构中进行索引操作。它们在实现上有一些区别,下面是它们的主要区别:
- B树:
- B树是一种多叉树,每个节点可以有多个子节点,通常在实现中有一个上限,即节点的最大子节点数目。
- 每个节点除了包含关键字(key)和对应的值(value)外,还包含了指向子节点的指针。
- B树适用于在磁盘等外存储设备上进行索引操作,因为每个节点可以存储多个关键字,从而减少了磁盘I/O次数,提高了查询效率。
- B树的节点分裂和合并操作相对较复杂。
- B 树:
- B 树是B树的变体,也是一种多叉树结构,但与B树不同,B 树的内部节点不存储数据,只存储关键字。
- 所有的数据都存储在叶子节点上,叶子节点之间通过链表连接,形成一个有序的数据列表。
- B 树在查询过程中只需要遍历叶子节点即可,查询效率更高。
- B 树适用于数据库索引等场景,常用于支持范围查询。
- 红黑树:
- 红黑树是一种二叉查找树,每个节点上都有一个额外的存储位表示节点的颜色,可以是红色或黑色。
- 红黑树满足以下性质:
- 节点是红色或黑色。
- 根节点是黑色。
- 所有叶子节点(NIL节点)是黑色。
- 如果一个节点是红色,其子节点必须是黑色。
- 从任意节点到其每个叶子节点的所有路径上,黑色节点的数量必须相同。
- 红黑树在插入和删除操作后需要通过旋转和重新着色来维持平衡。
总结:B树和B 树适用于外存储设备上的索引操作,B树适用于点查询,而B 树适用于范围查询。红黑树适用于内存中的索引操作,它通过保持平衡性来保证在各种操作下的较稳定的性能。
mybits 二级缓存
MyBatis是一个开源的Java持久层框架,它提供了多种缓存机制来提高数据库查询性能。其中,二级缓存是MyBatis的一个重要特性,用于缓存查询结果,避免频繁地访问数据库,从而提高查询效率。
二级缓存是基于Mapper级别的缓存,可以跨越SqlSession的生命周期,在不同的SqlSession之间共享缓存数据。当一个Mapper的查询结果被缓存后,下次再执行相同的查询时,MyBatis会直接从缓存中获取结果,而不会再去执行数据库查询操作,从而节省了数据库访问时间。
MyBatis的二级缓存默认是基于内存的缓存实现,可以通过配置不同的缓存实现来支持分布式缓存等场景。常见的二级缓存实现有:
- PerpetualCache:默认的基于内存的缓存实现。
- Ehcache:支持分布式缓存的实现,可以将缓存数据放置在内存或者磁盘上。
- RedisCache:使用Redis作为缓存存储,支持分布式环境下的缓存共享。
需要注意的是,虽然二级缓存可以提高查询性能,但也有一些需要注意的点:
- 缓存数据的更新和失效:当数据发生变化时,需要手动刷新缓存或者设置合理的缓存失效时间,避免数据不一致的问题。
- 缓存的内存管理:缓存数据存放在内存中,如果缓存数据过多,可能会导致内存溢出的问题。因此,需要合理设置缓存大小和淘汰策略。
总体来说,MyBatis的二级缓存是一个非常有用的功能,可以在适当的场景下显著提升数据库查询性能。但在使用时需要根据具体情况进行配置和管理,避免潜在的缓存问题。
0721考试
- MySql 数据的隔离级别有以下四种:
- READ UNCOMMITTED(读未提交):允许一个事务读取另一个事务未提交的数据,存在脏读、不可重复读和幻读问题。
- READ COMMITTED(读已提交):一个事务在提交后,另一个事务才能读取其数据。可以解决脏读问题,但仍可能出现不可重复读和幻读问题。
- REPEATABLE READ(可重复读):一个事务在整个过程中多次读取同一数据会保持一致。可以解决脏读和不可重复读问题,但仍可能出现幻读问题。
- SERIALIZABLE(串行化):最高的隔离级别,每个事务都必须等待其他事务完成后才能执行。可以避免脏读、不可重复读和幻读,但会降低并发性能。
- MySql中的回表是指在使用非聚集索引进行查询时,MySQL需要通过索引找到对应的行,并进一步通过主键索引或聚集索引获取完整的行数据。这个过程中需要”回”到原始数据表中去获取缺失的数据列。
- SQL优化包括以下几个方面:
- 选择合适的索引:根据查询的条件和频率选择合适的索引来加快查询速度。
- 避免全表扫描:尽量使用索引或优化查询条件,避免对整张表进行全表扫描。
- 减少查询次数:通过合并多个查询或使用JOIN等操作来减少查询次数。
- 优化查询语句:使用合适的SQL语句,避免使用SELECT *,只查询所需的列。
- 适当拆分大表:将大表拆分为多个小表,减少查询的数据量。
- 缓存结果:对于频繁的查询,可以将结果缓存在缓存中,避免频繁查询数据库。
- 冒泡排序的实现:
javaCopy codepublic void bubbleSort(int[] arr) {
int n = arr.length;
for (int i = 0; i < n - 1; i ) {
for (int j = 0; j < n - i - 1; j ) {
if (arr[j] > arr[j 1]) {
int temp = arr[j];
arr[j] = arr[j 1];
arr[j 1] = temp;
}
}
}
}
5.冒泡排序的时间复杂度是O(n^2)。计算方法是,对于长度为n的数组,最坏情况下需要进行n-1次比较,n-2次比较,…,1次比较,共进行(n-1) (n-2) … 1次比较,即等差数列求和,结果为 (n-1) * n / 2,所以时间复杂度是O(n^2)。
6.Spring是一个完整的Java开发框架,提供了依赖注入(DI)、面向切面编程(AOP)、事务管理、MVC框架等功能。Spring Boot是基于Spring的快速开发框架,旨在简化Spring应用程序的构建和部署过程,提供了自动配置和默认值,让开发者能够更轻松地启动一个生产就绪的Spring应用程序。
7.SpringBoot自动装配原理是通过Starter、自动配置类和条件注解实现的。它通过分析项目依赖和配置信息,自动选择和应用合适的自动配置类,完成Bean的装配和配置。
8.循环依赖是指在Spring容器中,两个或多个Bean之间相互引用,形成了循环的依赖关系。为了解决循环依赖,可以使用构造器注入或使用@Lazy注解。构造器注入可以保证Bean在被实例化时就已经得到了所需的依赖。@Lazy注解可以延迟Bean的实例化,从而避免循环依赖问题。
9.MySQL主从复制搭建步骤包括:
- 确保MySQL已安装并配置正确。
- 在主服务器上开启二进制日志,并设置server_id。
- 创建用于复制的用户,并授权REPLICATION SLAVE权限。
- 备份主服务器数据。
- 在从服务器上设置server_id,并配置连接主服务器的信息。
- 同步主从服务器状态。
- 启动从服务器复制进程。
10.Redis缓存击穿是指在高并发情况下,一个热点数据缓存过期后,大量请求同时访问数据库,造成数据库压力过大,导致系统性能下降。缓存击穿可以通过设置热点数据的永不过期或设置较长的过期时间来解决。
11.缓存雪崩是指缓存中大量数据在同一时间失效或过期,导致大量请求直接访问数据库,给数据库造成巨大压力,引起系统性能下降或崩溃。缓存雪崩可以通过在设置缓存过期时间时采用随机时间,或使用多级缓存来解决。
12.缓存穿透是指当一个请求查询一个不存在于缓存和数据库中的数据时,这个请求会穿透缓存直接访问数据库,导致缓存无效,频繁访问数据库,增加数据库负担。缓存穿透可以通过使用布隆过滤器等技术,在缓存层或应用层进行数据校验,过滤掉不存在的数据请求,从而解决。
13.MyBatis的一级缓存是指在同一个SqlSession中,执行相同的SQL语句时,查询结果会缓存在内存中,下次再执行相同的SQL语句时,会从缓存中获取结果,而不再去数据库查询。一级缓存是默认开启的,其生命周期是与SqlSession绑定的。
14.MyBatis的二级缓存是指多个SqlSession之间可以共享的缓存,它可以跨越多个SqlSession,需要手动配置启用和配置。二级缓存的作用域是Mapper级别的,由MyBatis的整个SqlSessionFactory来管理。
15.Spring的事务传播机制是指在多个事务方法调用时,事务应该如何传播和合并。Spring定义了多个事务传播行为,如REQUIRED、SUPPORTS、MANDATORY、REQUIRES_NEW等。例如,REQUIRED表示当前方法必须运行在事务中,如果已经有一个事务在运行,则加入该事务,如果没有事务,则创建一个新事务。
Spring定义了多种事务传播机制,以下是其中一些常见的:
- REQUIRED(默认):如果当前没有事务,就创建一个新的事务;如果当前已经存在事务,就加入到当前事务中。
- REQUIRES_NEW:每次调用该方法都会创建一个新的事务,如果当前已经存在事务,则挂起当前事务。
- SUPPORTS:如果当前有事务,就加入到当前事务中,如果没有事务,就以非事务的方式执行。
- NOT_SUPPORTED:以非事务方式执行,如果当前存在事务,则挂起当前事务。
- MANDATORY:当前必须存在事务,否则抛出异常。
- NEVER:当前必须不存在事务,否则抛出异常。
- NESTED:嵌套事务,如果当前有事务,则嵌套在当前事务中,如果没有事务,则创建一个新的事务。
16.Redis被设计为单线程的主要原因是为了避免多线程带来的线程安全问题,简化实现并提高性能。Redis使用单线程的事件循环模型,所有的请求都由一个线程处理,这样避免了多线程之间的竞争和同步开销。此外,Redis的主要瓶颈通常是CPU性能,而不是多线程的并发处理能力。
17.select * from —where name like ‘%王%’ 会引起全表扫描。因为LIKE ‘%王%’的模糊查询无法使用索引,所以MySQL会对表中的每一行都进行模糊匹配,导致全表扫描。
18.select * from —where name like ‘王%’ 不会引起全表扫描。这种情况下,MySQL可以使用name列的前缀索引,加快查询速度,不会进行全表扫描。
19.MySql使用B树索引和哈希索引。B树索引用于普通查找和范围查找,适用于数据分布较为均匀的情况。哈希索引适用于等值查找,适用于数据分布较为离散的情况,但不支持范围查找。
20.红黑树、B树和B 树是数据库索引中常用的树状数据结构:
- 红黑树是一种自平衡的二叉查找树,用于实现哈希索引,适合于在内存中使用,查询性能较高。
- B树是一种多路搜索树,用于实现普通索引,适合于磁盘存储,支持随机查找和范围查找。
- B 树是在B树的基础上优化而来,只有叶子节点存储数据,适合于数据库索引,查询性能更稳定,支持顺序查找和范围查找。
0722
作业
1、如何设计一个能够支持高并发的系统
2、sprintboot redis
3、rabbitmq 剩余 整合springboot
4、es
锁
0729
1、什么是回表,怎么减少回表的次数
2、什么是排他锁和共享锁
- 排他锁(Exclusive Lock): 排他锁也称为写锁,它是一种独占锁,当一个事务持有了某个数据对象的排他锁时,其他事务无法同时持有该数据对象的任何锁,包括共享锁和排他锁。排他锁保证了数据的独占性,即在一个事务修改数据时,其他事务无法读取或修改该数据,直到当前事务释放锁。 排他锁用于保证数据的一致性和完整性,防止并发更新导致数据不一致的情况。但是,排他锁可能会导致并发性降低,因为多个事务无法同时访问相同的数据。
- 共享锁(Shared Lock): 共享锁也称为读锁,它是一种共享锁,多个事务可以同时持有相同数据对象的共享锁,但是无法持有排他锁。共享锁用于实现并发读取,即多个事务可以同时读取相同的数据,而不会对数据造成影响。 共享锁适用于读多写少的场景,多个事务可以同时读取数据,提高了并发性。但是,共享锁可能会导致读取的数据是过去的数据,因为多个事务可以同时读取相同的数据,即使其中某些事务已经对数据进行了修改。
综合来说,排他锁和共享锁是数据库管理并发访问的重要手段。通过适当地使用这两种锁类型,可以平衡并发性和数据一致性之间的关系,保障数据库在多个事务同时进行读写操作时的正确性和效率。
3、什么是脏读、幻读、不可重复读
- 脏读(Dirty Read): 脏读指的是一个事务读取了另一个事务未提交的数据。当一个事务读取了另一个事务所做的更新,而这个更新后来由于某些原因被回滚,那么读取到的数据实际上是无效的,是”脏”的。脏读可能导致数据的不一致性,因为读取到的数据可能最终不会被提交。
- 幻读(Phantom Read): 幻读指的是一个事务在读取数据时,另一个事务插入了新的数据,导致第一个事务读取到了之前不存在的数据。幻读通常发生在范围查询(Range Query)中,当第一个事务读取一批数据时,另一个事务在该批数据范围内插入了新的数据,导致第一个事务再次读取时发现有新增的”幻影”数据。
- 不可重复读(Non-repeatable Read): 不可重复读指的是一个事务在读取数据后,另一个事务对这些数据进行了修改,导致第一个事务再次读取时发现数据已经发生了变化。不可重复读可能导致数据的一致性问题,因为事务在读取数据时得到的结果并不一致。
这些问题都是由于数据库事务并发访问时可能引发的隔离性问题。数据库系统采用事务隔离级别来控制这些问题的出现概率,常见的事务隔离级别有四种:读未提交(Read Uncommitted)、读已提交(Read Committed)、可重复读(Repeatable Read)和串行化(Serializable)。不同的隔离级别对应不同的数据一致性和并发性能权衡,开发者需要根据业务需求选择适合的隔离级别。
4、为什么大厂不建议使用多表join
- 性能问题: 多表join涉及多个表的数据连接操作,如果表中的数据量很大,join操作可能会导致性能下降。数据库的性能在大厂中尤为重要,对于高并发和大数据量的应用来说,频繁的多表join会增加数据库的负担,影响整体的性能。
- 维护问题: 多表join增加了数据库查询的复杂性,使得SQL语句变得复杂难懂,不易于维护和调试。当数据库中的表结构变更时,涉及join的查询语句可能需要进行调整,这对开发人员来说增加了工作量。
- 水平扩展问题: 多表join操作在大规模的水平扩展时可能会变得更加困难。在水平扩展时,需要保持数据的一致性,而join操作跨越多个节点将增加数据同步和维护的复杂性。
- NoSQL趋势: 随着NoSQL数据库的兴起,越来越多的大厂在一些特定场景下选择了NoSQL解决方案。NoSQL数据库在某些查询场景下更具优势,而不是使用传统的关系型数据库,并且NoSQL数据库一般不支持join操作。
虽然大厂不建议频繁使用多表join,但并不意味着join完全不可用。在一些复杂查询场景下,使用多表join是合理的选择,但需要注意合理设计数据库表结构、建立合适的索引,避免不必要的join操作。同时,也可以考虑使用缓存、数据冗余、分库分表等技术来优化查询性能,以减少多表join的使用频率。总之,合理使用多表join是需要权衡利弊的,要结合具体场景进行选择和优化。
5、索引失效的问题如何排查
- 检查查询语句: 首先检查查询语句是否正确,并且是否使用了索引列作为查询条件。确保查询语句的条件与索引的列匹配,以便数据库可以正确选择并使用索引。
- 使用EXPLAIN命令: 在MySQL等数据库中,可以使用EXPLAIN命令来查看查询计划,看是否使用了索引。执行
EXPLAIN SELECT ...
命令,可以查看查询的执行计划,包括使用了哪些索引以及执行的顺序。 - 检查索引列是否被修改: 如果索引列的值在查询时被修改了,那么索引可能会失效。例如,在WHERE条件中使用了函数或表达式对索引列进行操作,会导致索引无法使用。
- 统计信息是否准确: 数据库优化器使用统计信息来估算索引的选择性,从而决定是否使用索引。确保统计信息是最新的、准确的,以保证优化器能够正确选择索引。
- 注意数据类型转换: 确保查询条件中的数据类型与索引列的数据类型相匹配,避免因数据类型转换而导致索引失效。
- 避免使用不等于操作符(<>, !=): 在某些数据库中,不等于操作符可能导致索引失效,建议使用等于操作符(=)代替不等于操作符。
- 检查是否存在列组合索引: 如果查询条件中的多个列可以组合在一起使用索引,可以考虑创建列组合索引,以提高查询性能。
- 使用FORCE INDEX(MySQL)或 HINTS(Oracle): 有些数据库支持使用FORCE INDEX或HINTS等提示来强制指定使用某个索引,可以在特定情况下用于解决索引失效的问题。
以上排查方法可以帮助定位索引失效的原因。需要根据具体数据库和查询场景来选择适合的优化方法,以提高查询性能并避免索引失效问题。
6、Redis支持哪几种数据类型
- String(字符串): String是最基本的数据类型,在Redis中,String类型可以存储任意类型的数据,例如字符串、整数和浮点数等。
- Hash(哈希): Hash是一个键值对的集合,类似于Java中的Map。在Redis中,Hash适合存储对象的属性和值。
- List(列表): List是一个有序的字符串列表,可以在列表的两端进行插入和删除操作。Redis的List类型是一个双向链表。
- Set(集合): Set是一个无序的字符串集合,集合中的元素是唯一的,不允许重复。
- Sorted Set(有序集合): Sorted Set是一个有序的集合,其中的元素以分数(score)来排序。集合中的元素是唯一的,但每个元素可以关联一个分数。
- Bitmap(位图): Bitmap是一个特殊的数据类型,它是一个由二进制位组成的字符串。Bitmap可以用于记录某个事件在某个时间点是否发生。
- HyperLogLog(基数估计): HyperLogLog是一种基数估计算法,用于估计集合中不重复元素的数量,占用空间很小。
- Geospatial(地理空间索引): Redis支持存储和查询地理空间数据,如经纬度坐标。
除了上述主要数据类型,Redis还有一些其他的数据类型和扩展功能,如Pub/Sub(发布/订阅)、Lua脚本执行、多个数据库的支持等。Redis的灵活性和丰富的数据类型使得它成为一个功能强大的缓存、消息队列、数据存储等多用途的工具。