1、Java中HashMap的原理
简洁回答:哈希函数映射到数组桶;哈希冲突通过链表或红黑树处理;扩容机制根据负载因子和容量动态调整。
HashMap是基于哈希表的数据结构,用于存储键值对(key-value)。其核心是将键的哈希值映射到数组索引位置;通过数组+链表(在Java8及之后是数组+链表+红黑树)来处理哈希冲突;支持O(1)的平均时间复杂度来执行 put、get和remove操作,但在发生扩容时会有性能开销。默认的负载因子是0.75,容量初始为16,并在超过阈值时扩容
2、Java中ConcurrentHashMap 1.7和1.8之间有哪些区别?
JDK 1.7 ConcurrentHashMap采用的是分段锁,即每个Segment是独立的,可以并发访问不同的Segment,默认是16个Segment,所以最多有16个线程可以并发执行。而JDK 1,8移除了Segment,锁的粒度变得更加细化,锁只在链表或红黑树的节点级别上进行。通过CAS进行插入操作,只有在更新链表或红黑树时才使用synchronized,并且只锁住链表或树的头节点,进一步减少了锁的竞争,并发度大大增加。
3、为什么JDK 1.8对HashMap进行了红黑树的改动?
简洁回答:红黑树时一种平衡二叉树,插入、删除和查找操作时的时间复杂度为O(logn),在元素多的情况下远优于链表
在JDK1.8之前,HashMap使用链表来解决哈希冲突。当哈希冲突较多时,链表中的元素增多,查找、插入和删除的时间复杂度从O(1)退化为O(n)。因此在JDK1.8引入了红黑树,将链表长度超过一定阈值(默认为8)时的链表转换为红黑树,避免性能急剧下降。当链表降到6以下时,红黑树会重新退化为链表,保持简单高效。
4、JDK1.8对HashMap除了红黑树还进行了哪些改动?
(1)改进了哈希函数的计算:JDK1.8中优化了哈希函数,使得哈希值的分布更加均匀,减少了哈希冲突的发生。通过在生成哈希值时使用“扰动函数”,确保哈希值的高低位都能参与到桶的选择中
(2)扩容机制优化:JDK1.8改进了扩容时的元素迁移机制。在扩容过程中不再对每个元素重新计算哈希值,而是根据原数组长度的高位来判断元素是留在原位置。这一改动减少了不必要的计算,提高了扩容效率。
5、Java中有哪些集合类?请简单介绍
Java中的集合类主要分为两大类:Collection接口和Map接口。前者存储对象的集合类,后者存储的是键值对(key-value)
Collection
1)List系列集合:添加的元素是有序、可重复、有索引
ArrayList、LinkedList:有序、可重复、有索引。
2)Set系列集合:无序、不重复、无索引
HashSet:无序、不重复、无索引
LinkedHashSet:有序、不重复、无索引
TreeSet:按照大小默认升序排序、不重复、无索引
Map
HashMap:元素按照键是无序、不重复、无索引。值不做要求
LinkedHashMap:元素按照键是有序,不重复,无索引。值不做要求
TreeMap :元素按照键是排序,不重复,无索引的。值不做要求
6、MySQL索引的最左前缀匹配原则是什么?
基本概念:MYSQL的最左前缀匹配原则是使用联合时,查询条件必须从联合索引的最左侧开始匹配,如果一个联合索引包含多列,则查询条件必须包含第一列,然后是第二列,依次类推。(8.0版本之后支持跳跃索引,即使不满足最左前缀匹配原则,也可以走索引)
7、数组库的脏读、不可重复读和幻读分别是什么?
脏读:脏读就是指当一个事物正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库,这时,另外一个事物也访问这个数据,然后使用了这个数据。
不可重复读:在一个事务内两次读到的数据是不一样的。
幻读:同一查询条件中两次查到的数据集不一致
https://blog.csdn.net/song854601134/article/details/125147625
8、MYSQL的存储引擎有哪些?它们之间有什么区别?
(1)InnoDB:支持事务处理,支持外键,支持崩溃修改能力和并发控制(完整性要求高、实现并发控制;需要频繁更新、删除的数据库)。
(2)MyISAM:插入数据块,空间和内存使用比较低(主要用于插入新纪录和读出记录;完整性和并发性要求比较低)。
(3)MEMORY:所有的数据都在内存中,数据的处理速度快,但是安全性不高(可以用于读写速度快和安全性要求较低的,且不能建立太大的表)。
注:同一个数据库也可以使用多种存储引擎的表。如果一个表要求比较高的事务处理,可以选择InnoDB。这个数据库中可以将查询要求比较高的表选择MyISAM存储。如果该数据库需要一个用于查询的临时表,可以选择MEMORY存储引擎。
https://blog.csdn.net/qq_19309473/article/details/90144552
9、MySQL的覆盖索引是什么?
基本概念:指一个索引包含了查询所需要的所有列的数据。
CREATE TABLE employees ( emp_id INT PRIMARY KEY, first_name VARCHAR(50), last_name VARCHAR(50), department_id INT, salary DECIMAL(10, 2), INDEX idx_dept_salary(department_id, salary) );
现在执行以下查询:
SELECT department_id, salary FROM employees WHERE department_id = 5;
在这个查询中,SELECT 子句只涉及 department_id 和 salary 列,而这些列都包含在 idx_dept_salary 索引中。因此,MySQL 可以利用这个覆盖索引来优化查询。
优点:(1)减少了I/O操作 (2)提高查询速度 (3)减少锁竞争
局限性:(1)索引大小的限制 (2)冗余数据 (3)适用场景有限
使用场景:(1)频繁查询特定列 (2)优化读性能 (3)减少回表操作
https://blog.csdn.net/weixin_43844521/article/details/141175454
10、MySQL的索引类型有哪些?
1)普通索引:最基本的索引类型,用于频繁查询的字段,但不需要唯一性约束
2)唯一索引:限制列的值必须唯一:用于确保列值唯一性的字段,例如邮箱、用户名等。
3)主键索引:特殊的唯一索引,主键值必须唯一且不能为NULL
4)全文索引:用于加速对文本数据的搜索,用于Char,Varchar,Text等字段。需要高效匹配大量文本字段场景,例如文章标题或内容搜索
5)复合索引:多个列上建立索引。
https://blog.csdn.net/qq_37829947/article/details/143689267
11、MySQL的索引下推(ICP)是什么?
概念:旨在减少MySQL查询过程中对数据页的访问次数,其核心思想是在索引层次尽早地过滤不满足条件的记录,从而避免不必要的全表扫描或数据页访问。
工程流程:
1)索引扫描:MySQL 根据前缀条件扫描索引,遍历满足前缀条件的索引条目。
2)索引条件过滤:对于每一个索引条目,MySQL 评估除前缀条件之外的其他查询条件。
3)数据页访问:只有当所有索引条件都满足(覆盖索引)时,MySQL 才访问数据页获取完整的记录。
4)最终结果集:将满足所有条件的记录返回给客户端。
https://blog.csdn.net/stone_tmp/article/details/144703636
12、MySQL InnoDB引擎中的聚簇索引和非聚簇索引有什么区别?
聚簇索引(主键索引):指数据表中的数据存储按照索引的顺序排列,因此索引的叶子节点存储的不仅是索引列的值,还存储整行数据。
非聚簇索引:指索引和数据是分开存储的·。非聚簇索引的叶子节点存储的是索引列的值和指向实际数据的指针(即行号或主键)。一张表可以有多个非索引聚簇,每个索引都有自己的存储顺序。
https://blog.csdn.net/whs_8792/article/details/143865410
13、MySQL中的回表是什么?
定义:当查询的条件字段中只命中非聚簇索引的一部分字段时,MySQL需要根据索引中的记录再到原表里查找完整的数据,这个过程叫做回表查询。
14、MySQL中使用索引一定有效吗?如何排查索引效果?
索引失效场景:
-使用了联合索引却不符合最左前缀
-索引中使用了运算
-索引上使用了函数也会失效
-like/or的随意使用
-随意的字段类型使用
-不同的参数也会导致索引失效
-表中两个不同字段进行比较
-使用了!=、<>
-使用了is not null/order by
索引生效但是查询变慢:
-索引也是需要占空间的
-对大字段建立了索引
-对重复值较多的字段建立索引
https://blog.csdn.net/2401_84419325/article/details/139390233
15、RabbitMQ怎么实现延迟队列?
延迟队列常用于需要在特定时间后执行某些操作的场景(比如下单未付款)
1)创建一个普通队列作为消息的初始存放地,并设置消息的过期时间(TTL)。
2)当消息过期时,RabbitMQ 会将其转发到绑定的死信交换机(DLX)。
3)在死信交换机中,消息被路由到延迟队列,消费者可以从延迟队列中取出消息。
https://blog.csdn.net/qq_51226710/article/details/142700436
16、MySQL中的索引数量是否越多越好?为什么?
1)索引越多,更新的速度越慢。
2)太多的索引会影响mysql查询优化器的选择时间。
3)更新的索引需要更多的空间。
索引的作用:索引减少了存储引擎需要扫描的数据量;帮助我们进行排序,避免使用临时表;索引可以随机IO转换为顺序IO
17、请详细描述MySQL的B+树中查询数据的全过程、原因
选择B+树作为索引结构的原因:
一种自平衡树,在插入和删除时节点会进行分裂和合并操作,以保持树的平衡。
高度不会增长过快,查询磁盘I/O次数减少
范围查询能力强
过程:
1、从根节点开始
2、跳转到对应叶子节点
3、扫描叶子节点
4、顺序链表查找
https://blog.csdn.net/2303_76696898/article/details/142645680
18、MySQL三层B+树能存多少数据?
bigint类型的索引(8字节),一条数据假设是1KB的话,三层B+树 能存2000万条数据
计算思路:
1.计算叶节点的大小
2.计算子节点的个数,由此算出第三层叶子节点的个数(n*n)
一个节点的子节点个数=页大小/(索引键大小+指向该子节点的指针大小)
3.计算每个叶子节点存储的数据行个数(多少条数据)
4.算出第三层能存储的总的[数据行数
https://blog.csdn.net/m0_64422133/article/details/144731271
19、详细描述一条SQL语句在MySQL中的执行过程?
1)客户端连接和请求
2)查询解析
3)查询优化
4)查询执行
5)结果返回
5)日志记录(可选)
https://blog.csdn.net/le12345678934694/article/details/144144504
20、MySQL是如何实现事务的?
事务:事务中的所有操作要么全部提交,要么全部回滚。
事务的特性:原子性、一致性、隔离性、持久性
事务实现:MySQL的InnoDB存储引擎是MySQL默认的存储引擎,提供了完整的事务支持。通过锁机制、日志系统、缓冲池和检查点等机制来实现事务管理。
日志机制:redo log和undo log
锁机制:行级锁、表级锁、间隙锁
事务的隔离级别:读未提交(脏读)、读已提交(不可重复读)、可重复读(解决不可重复读)、串行化(幻读)
事务的管理和配置:自动提交、显式控制事物、使用保存点
事务的生命周期:
1)事务开始:start transaction/start
2)事务操作:在事务中执行一系列的SQL操作,如插入、更新、删除
3)事务提交:所有操作成功执行,通过COMMIT命令持久化
4)事务回滚:通过ROLLBACK命令撤销事务中的所有操作
https://blog.csdn.net/Flying_Fish_roe/article/details/143992698
21、MySQL事务的二阶段提交是什么?
定义:分布式事务协议,用于保证在分布式系统中有节点对事务的一致性。这种协议确保了即使在部分系统故障的情况下,也能保持数据的一致性。二阶段提交主要应用于跨多个数据库或资源管理器的场景。
包括两个阶段:准备阶段和提交阶段
准备阶段:
协调者向所有参与者发送“准备请求”——>每个参与者判断能否执行——>可以,则返回,否则拒绝——>协调者等着回复,若其中一个拒绝,则取消事务
提交阶段:
参与者准备好,协调者发送“提交”命令——>参与者接收命令,提交事务,释放资源——>参与者完成后发送确认——>所有参与者确认后,认为事物已成功提交,结束事务(若未能从所有参与者那里获得确认,则协调者发出回滚,所有参与者撤销事务)
缺陷:性能开销大、阻塞问题、单点故障
https://blog.csdn.net/qq_33240556/article/details/142548096
22、MySQL中长事务可能会导致哪些问题?
概念:长事务指的是运行时间比较长,长时间未提交的事务。
出现的问题:
1、锁定资源
2、增加死锁风险
3、占用系统资源
4、可能导致主从延迟
5、影响数据一致性
如何解决:
1、优化事务
2、合理设计事务
3、监控长事务
4、设置超时参数
5、及时提交或回滚
https://blog.csdn.net/m0_63331248/article/details/140543917
23、MySQL中的MVCC是什么?
定义:MySQL数据库用来处理并发访问的技术,特别是在InnoDB存储引擎中,MVCC允许多个事务并发执行而不互相干扰,确保数据的一致性和隔离性。
基本原理:
事务标识和版本控制
数据化版本管理
读取数据的版本选择
提交和回滚
MVCC的优势:
1、提交并发性
2、避免锁竞争
3、实现一致性读
挑战和限制:
1、内存和磁盘空间消耗
2、更新操作的开销
3、脏读和幻读的可能性
https://www.cnblogs.com/eiffelzero/p/18607443
24、MySQL中的事务隔离级别有哪些?
事务的4种隔离级别:
1、读未提交:解决脏写问题(一个事务还未提交之前,其对数据的修改被另一个事务所看见或覆盖的情况)
2、读已提交:解决脏读问题(当一个事务读取了另一个事务尚未提交的数据时,就发生了脏读)
3、可重复读:解决不可重复读问题(在同一个事务内,多次从数据库读取数据,读取到的值不一样)
4、串行化: 解决幻读问题(一个事物两次查询中查询到的结果新出了原来没有的)
https://blog.csdn.net/WLKQNYJY_SHT/article/details/139938299
25、MySQL默认的事务隔离级别是什么?为什么要选择这个级别?
MySQL中默认的事务隔离级别是可重复读,InnoDB存储引擎的默认事务隔离级别。
为什么:
1、解决不可重复读问题
2、较高的并发性能
3、减少幻读问题的影响(下一键锁)
4、适用于大多数应用场景
(选择这个级别是因为它在一致性和并发性之间提供了合理的折中,能够解决不可重复读和幻读等常见问题,并且在大多数应用场景下提供了较高的性能;通过下一键锁减少了幻读问题的影响)
https://www.cnblogs.com/eiffelzero/p/18607447
26、MySQL中有哪些锁类型?
(1)分类:
对数据操作的粒度来分:
表锁:操作时会锁定整个表
行锁:操作时会锁定当前操作行
从对数据操作的类型分:
读锁(共享锁):针对同一份数据,多个读操作可以同时进行而不会互相影响
写锁(排它锁):当前操作没有完成之前,它会阻断其他写锁和读锁
(2)Mysql锁:
特性:
表级锁(偏向MyISAM存储引擎;不会死锁,锁粒度大->发烧锁冲突的概率最高)
行级锁(偏向InnoDB存储引擎;会死锁;锁粒度小—>发生锁冲突的概率最低)
页面锁
(3)MyISAM表锁:在查询语句会自动加读锁;更新操作会自动加写锁,用户无需干预
(4)InnoDB表锁:共享锁和排它锁
https://blog.csdn.net/qq_28419035/article/details/140929110
27、MySQL中的乐观锁和悲观锁是什么?
乐观锁:认为在大多数情况下,并发事务之间不会发生冲突(在提交更新之前判断是否被修改,被修改则考虑更新或抛出异常),用于读多写少的情况。
悲观锁:认为在并发环境中,数据很可能被其他事物修改(在开始时就对操作数据进行加锁,直到事务完成并提交或回滚才释放锁),用于写少读多
https://blog.csdn.net/weixin_69477306/article/details/143972939
28、MySQL中如果发生死锁应该如何解决?
(1)死锁预防:预防死锁发生的任一条件:破坏互斥条件(较难)、破坏占有等待事件、破坏不剥夺条件、破坏循环等待条件
(2)死锁避免:动态地判断当前系统是否进入安全状态来避免死锁(银行家算法)
(3)死锁检测:资源分配图法、循环等待检测法
(4)死锁恢复:进程终止、资源剥夺、回滚
29、MySQL中count(*)、count(1)、count(字段名)有什么区别?
https://blog.csdn.net/x1234w4321/article/details/143904798
30、MySQL中如何进行SQL调优?
(1)使用恰当的索引
(2)避免全表扫描
(3)优化查询语句
(4)合理使用JOIN
(5)使用查询缓存(通过控制应用层缓存:Redis等)
(6)避免使用函数操作索引列(会放弃索引,使用全表扫描)
(7)使用EXPLAIN分析查询
(8)限制返回结果集
(9)优化表结构
(10)事务管理
https://blog.csdn.net/ethnicitybeta/article/details/142489059
31、如何使用MySQL的EXPLAIN语句进行查询分析?
作用:是MySQL提供的分析SQL查询执行计划的工具,用于了解查询语句的执行过程,帮助优化查询性能。(可以查看查询的执行顺序、所使用的索引、扫描的表、访问方法等信息)
输出字段包括:
常见优化点:
1、优先使用合适的索引
2、优化扫描范围
3、减少扫描行数
4、消除临时表和文件排序
5、使用覆盖索引
https://www.cnblogs.com/eiffelzero/p/18607963
32、MySQL中如何解决深度分页的问题?
问题:当使用LIMIT和OFFSET进行分页时,MySQL必须扫描OFFSET+LIMIT行,然后丢弃前OFFSET行。意味着随着分页的深入,MySQL需要扫描的行数越来越多,导致查询功能下降
如何优化:
1、使用索引优化查询
2、使用覆盖索引
3、利用标记分页
4、分区表
5、缓存结果
https://blog.csdn.net/2401_85373732/article/details/145061201
33、什么是MySQL的主从同步机制?它们是如何实现的?
概念:是一种数据库复制技术,它通过将主服务器上的数据更改复制到一个或多个从服务器,实现数据的自动同步。
工作流程:
1、主库:接受客户端的写请求并将更改记录到二进制日志中
2、从库:从主库获取二进制日志并保存在中继日志中
3、从库:读取中继日志并执行其中的SQL语句,应用到自己的数据库中
同步方式:
1、异步复制(默认):主库执行完事务后立即返回,数据的同步是通过从库异步拉取主库的二进制日志来完成的。
2、同步复制:主库提交事务时,必须等待所有的从库都确认事务已执行完毕,才能返回客户端
3、半异步复制:当主库提交事务时,至少等待一个从库确认已接收到该事务的二进制日志后才提交。
优点:提高读取性能、数据冗余、负载均衡、高可用行
缺点:数据一致性问题、延迟问题、故障恢复复杂性问题
https://blog.csdn.net/unbuntu_luo/article/details/143944871
34、为什么RocketMQ不使用Zookeeper作为注册中心呢?而选择自己实现NameServer?
目的:
1、对于注册中心,RocketMQ集群需要保存到元数据非常少,完全没有必要引入Zookeeper这种重量级的注册中心。
2、RocketMQ实现了基于raft协议的DLedger算法,可以保证Broker集群高可用,不用依赖Zookeeper
3、NameServer是RocketMQ内部组件,实现简单,易于扩展,不用考虑运维复杂性。
https://cloud.tencent.com/developer/article/2118883
35、RabbitMQ中消息什么时候会进入死信交换机?
1、消息被拒绝并且不重新入队列
2、消息过期
3、队列达到最大长度
4、消息被消费者消费次数达到限制
https://blog.csdn.net/weixin_41992498/article/details/139986162
36、RabbitMQ中无法路由的消息会去到哪里?
1、消息直接被丢弃(默认行为)
2、配置了备用交换机(Alternate Exchange)
3、启用消息的返回机制(Mandatory标志)
4、配置了死信交换机
5、配置了延迟队列
37、Kafka为什么要抛弃Zookeeper?
原因:
1、复杂性增加:独立于Kafka的外部组件,需要单独部署和维护
2、性能瓶颈:在高负载场景下,分区数量增加,Zookeeper需要存储更多的信息,监听延迟增加,影响性能
3、一致性问题:两者的一致性模型有所不同,影响消息传递的可靠性和系统稳定性
38、Kalfa中Zookeeper的作用?
1、Broker注册与管理
2、Topic管理
3、Controller选举
4、Partition Leader选举
5、消费者组协调
6、监控与通知
https://blog.csdn.net/qq_33240556/article/details/136046445
39、说一下Kalfa中关于事务消息的实现?
工作流程:
1、生产者开始事务;
2、生产者发送消息;
3、提交事务
4、回滚事务
5、事务状态管理
https://blog.csdn.net/weixin_44837153/article/details/136474339
40、为什么Java8移除了永久代(PermGen)并引入了元空间(Metaspace)?
永久代缺陷:
1、固定大小的内存区域;
2、垃圾回收的复杂性
3、使用限制
元空间的优点:
1、动态扩展
2、垃圾回收的优化
3、更好的内存利用率
4、减少OutOfMemoryError
其他原因:
1、促进JVM的融合
2、优化内存管理
https://blog.csdn.net/qq_44391293/article/details/141429570
41、说一下RocketMQ中关于事务消息的实现?
42、RocketMQ的事务消息有什么缺点?你还了解过别的事务消息实现吗?
43、为什么需要消息队列?
44、说一下消息队列的模型有哪些?
45、谈谈你了解的最常见的几种设计模式,说说他们的应用场景?
46、什么是策略模式?一般用在什么场景?
47、什么是责任链模式?一般用在什么场景?
48、什么是模板方法模式?一般用在什么场景?
49、什么是观察者模式?一般用在什么场景?
50、什么是代理模式?一般用在什么场景?
51、说说Spring启动过程?
启动流程:
1、创建和配置ApplicationContext
2、加载配置
3、实例化Bean
4、依赖注入(DI)
5、初始化Bean
6、事件发布与监听
7、准备就绪,开始使用Bean
8、容器关闭
52、Spring有哪些事务传播行为?
定义:在多个事务操作嵌套执行时,如何处理事务的传播与管理。
事务传播行为:
1、REQUIRED(默认):当一个方法被声明为REQUIRED时,它会检查当前是否存在一个事务。若存在,则将该方法放入该事务中执行,不存在则创建一个新事务。
2、SUPPORTS:如果当前存在事务,则该方法会加入到事务中执行;若不存在,则该方法以非事务方式执行。
3、MANDATORY:必须在一个已存在的事务中执行,否则会抛出异常。
4、REQUIRES_NEW:始终会开启一个新的事务,无论当前是否存在事务。
5、NOT_SUPPORT:将当前方法的执行置为非事务方式。
6、NEVER:绝对不允许方法在事务中执行。
7、NESTED:在当前事物的内部开启一个新的嵌套事务,嵌套事务是外部事务的一部分。
53、说说Springboot的启动流程?
大致步骤:
1、启动入口:main方法及SpringApplication.run()
2、初始化SpringApplicaton实例()
3、配置和执行启动
4、环境准备
5、创建和刷新应用上下文
6、加载和实例化Beam
7、调用Runner接口
8、通知启动监听器
54、SpringBoot是如何实现自动配置的?
流程:
1、启动主配置类(启动时加载@SpringBootApplication,其中包含@EnableAutoConfiguration(自动配置功能))
2、解析@EnableAutoConfiguration
3、加载候选配置类
4、过滤配置类
5、加载自动配置类到容器
6、注册主动配置的Bean
7、覆盖默认配置
55、如何理解SpringBoot中的starter?
定义:是一个预配置的依赖项集合,用于快速启动特定功能或技术的开发。封装了相关的库和配置,使得开发者可以轻松引入所需功能。
作用:
1、快速启动项目
2、简化依赖管理
3、提供默认配置
56、Spring Boot是如何通过main方法启动web项目的?
启动过程:
1、初始化Spring环境:通过SpringApplication.run()方法来初始化Spring应用上下文,加载配置文件,创建并启动Spring容器
2、嵌入式Web服务器启动:Spring Boot内置了一个嵌入式Web服务器(如Tomcat),该服务器会在应用启动时自动启动并监听指定端口
3、加载Web组件:启动过程中,SpringBoot会自动配置和初始化所有的Web相关组件
4、处理请求:一旦Web服务器启动并监听端口,Spring MVC的DispatcherServlet会处理传入的Http请求,执行相应的控制器方法。
https://blog.csdn.net/sinat_53467514/article/details/137826992
---------------太多啦太多啦---------------------------------
57、你了解的Spring都用到哪些设计模式?
九种设计模式:
1、简单工厂:BeanFactory
2、工厂方法
3、单例模式
4、适配器模式
5、装饰器模式
6、代理模式
7、观察者模式
8、策略模式
9、模板方法模式
https://blog.csdn.net/weixin_46768610/article/details/128928552
58、请描述简单工厂模式的工作原理。
59、工厂模式和抽象工厂模式有什么区别?
60、Redis集群的实现原理是什么?
定义:是一个由多个主从节点群组成的分布式服务集群,它具有复制、高可用和分片特性。
优点:
1、Redis集群有多个master,可以减少访问瞬断的影响;
2、Redis集群有多个master,可以提供更高的并发量
3、Redis集群可以分片存储,可以存储更多的数据
原理:
1、分片:Redis集群通过分片将数据分布到多个节点上,每个节点负责存储部分数据。
2、主从复制:在Redis集群中,每个分片通常会有多个副本,每个分片的一个节点作为主节点,其他节点作为从节点。
3、节点间通信:Redis集群中的节点之间通过集群总线(Cluster Bus)进行通信,用于节点发现、配置更新、故障检测等。
4、故障转移和重新平衡:当Redis集群中的某个主节点失效时,集群会通过投票选举出一个新的主节点
5、客户端路由:客户端与Redis集群通信时,需要根据键名的哈希值计算出数据所在的节点,并直接连接到该节点进行操作。
61、Redis集群会出现脑裂问题吗?
脑裂现象:当Redis主从集群环境中出现两个主节点为客户提供服务,这时客户端请求命令可能会出现数据丢失的情况。
原因:哨兵集群认为主节点出现故障了,重新选举其他从节点作为主节点,而原主节点其实就是假故障,从而导致短暂的出现两个主节点,那么在主从切换期间客户端一旦给原主节点发送命令,就会造成损失。
https://blog.csdn.net/2301_76166241/article/details/140669425
62、Redis中如何实现分页式锁?
特征:
1、互斥性:任意时刻,只有一个客户端能持有锁
2、锁超时释放:持有锁超时,可以释放,防止不必要的资源浪费,避免分布式锁失效
3、可重入性:一个线程如果获取了锁之后,可以再次对其请求加锁
4、高性能和高可用:加锁和解锁需要开销尽可能低,同时也要保证高可用,避免分布式锁失效
5、安全性:锁智能被持有的客户端删除,不能被其他客户端删除
方案:
1、SETNX+EXPIRE
存在问题:setnx和expire两个命令分开了,非原子操作(可能发生异常锁得不到释放的场景)
2、SETNX+value值(系统时间+过期时间)
3、使用Lua脚本
4、使用SET的拓展命令(SET EX PX NX)
EX seconds:设定key的过期时间,时间单位是秒
PX milliseconds:设定key的过期时间,单位为毫秒
NX:表示key不存在时才能set成功,也即保证只有第一个客户端请求才能获得锁,而其他客户端请求只能等其释放锁,才能获取。
存在问题:1、锁过期释放,业务未完 2、锁被别的线程误删
5、SET EX PX NX +校验唯一随机值,再删除(解决锁被别的线程误删)
6、Redisson框架
7、多机实现的分布式锁Redlock+Redisson
https://www.cnblogs.com/sunnycc/p/16014049.html
63、Redis实现分布式锁时可能遇到的问题有哪些?
问题:
1、非原子操作:加锁操作与设置超时时间是分开的
2、忘记释放锁:达到超时时间才释放锁
3、释放别人的锁:多线程场景中,可能会出现释放别人的锁的情况
4、大量失败请求:
5、锁重入问题:如果对某个key加锁了,如果该key对应的锁还没失效,再用相同key去加锁,大概率会失败——>可重入锁
6、锁竞争问题:有大量读取操作而写入操作较少时浪费性能——>减少锁的粒度——>1、采用读写锁 2、锁分段
7、锁超时问题
8、主从复制的问题
https://cloud.tencent.com/developer/article/1932377
64、说说Redisson分布式锁的原理?
原理:
1、加锁操作:使用Redis的SET命令设置一个键作为锁标识、唯一标识
2、可重入性:支持同一个线程对同一把锁进行多次加锁。(加锁或释放锁Redis中的计数器都会发生对应加一/减一)
3、解锁(Unlock)操作:解锁时,Redission会先校验锁的持有者(通过唯一标识),只有锁的持有者才能执行解锁操作
4、自动续期:锁看门狗机制:默认锁的有效期是30秒,若在锁持有期间仍需要延长锁时间,会启动一个后台线程定期对锁续期,直到客户端主动释放锁。
5、高可用支持:保证可以在Redis集群、哨兵模式下工作
65、如何实现Redis快速实现排行榜?
使用Redis中的有序集合(Sorted Set),每个元素都有唯一成员和一个函数,Redis会根据分数对元素进行排序
常用命令:
1、ZADD:添加元素
2、ZREM:删除元素
3、ZINCRBY:增加有序集合中元素的分数
4、ZRANG:按分数从低到高获取有序集合中的元素
5、ZRANK:获取元素在有序集合中的排名
逆序则加REV
https://blog.csdn.net/weixin_43319056/article/details/142797699
66、Redis中如何保证缓存与数据库的一致性?
常见方法:
1、缓存穿透处理
2、缓存雪崩处理
3、读写缓存时的双写一致性
4、使用缓存更新策略
5、定期更新缓存
6、使用分布式锁
缓存更新的设计:
1、先更新缓存,再更新数据库
2、先更新数据库,再更新缓存
3、先删除缓存,再更新数据库
4、先更新数据库,再删除缓存
更新缓存还是删除缓存:
更新缓存
优点:每次数据变化都及时更新缓存,所以查询时不容易出现未命中的情况
缺点:更新缓存的消耗比较大。若数据需要经过复杂的计算再写入缓存,那么频繁的更新缓存,就会影响服务器的性能。
删除缓存:
优点:操作简单,无论更新操作是否复杂,都将缓存中的数据直接删除
缺点:删除缓存中,下一次查询缓存会出现未命中,重写读取一次数据库。
综合比较下,删除缓存是更优方案
综合最终情况,先更新数据库,再删除缓存是影响最小的方案
https://blog.csdn.net/u011397981/article/details/132752377
67、什么情况下需要使用分布式事务,有哪些方案?
使用情况:一般在跨多个数据库或者不同服务的情况下需要用到分布式事务,比如订单服务和库存服务。
常见方案:2PC、3PC、TCC、本地消息、事务消息
1、2PC:两阶段提交协议:包括准备阶段和提交阶段。引入一个事物协调者角色,来管理各个参与者(各数据资源)
存在问题:同步阻塞、单点故障和数据不一致问题
2、TCC:基于补偿事务的分布式事务解决方案;将事务分解为三个阶段:尝试、确认和取消
三阶段处理:TCC 事务通过 Try、Confirm 和 Cancel 三个阶段来实现:
Try:预留必须的资源,执行业务检查。
Confirm:确认执行,提交事务,释放资源。
Cancel:取消操作,释放预留的资源,回滚事务。
补偿机制:TCC 通过补偿操作来保证最终一致性,即使在部分参与者失败的情况下也可以进行处理。
https://blog.csdn.net/2401_84419325/article/details/139576848
68、Redis为什么这么快?
第一:基于内存实现:内存由CPU控制,享受与CPU通信的最优带宽。
第二:使用I/O多路复用模型
第三:才用单线程模型
不会因为现场创建导致的性能消耗、避免上下文切换引起的CPU消耗、避免了线程之间的竞争问题、代码更清晰,处理逻辑简单
第四:高效的数据结构:Redis使用两个全局哈希表,通过rehash操作,增加现有的哈希桶数量,分散单桶元素数量。从而在减少哈希冲突的同时缩短链表长度,提高Redis的查询效率。
第五:合理的数据编码
如何使用Redis快速实现布隆过滤器
69、说说TCP的三次握手?
建立TCP连接的重要过程,确保通信双方能够正确建立连接。
过程:
首先客户端向服务器发送一个 SYN 包,并等待服务器确认
服务器接收到客户端发来的 SYN 包后,对该包进行确认后结束 LISTEN 阶段,并返回一段 TCP 报文
客户端接收到发送的 SYN + ACK 包后,明确了从客户端到服务器的数据传输是正常的,从而结束 SYN-SENT 阶段。并返回最后一段报文
70、简单说说Netty的零拷贝机制?
Netty中的零拷贝技术主要是通过优化用户态的操作来提升IO的执行速度,从而实现零拷贝的。
实现:
1、使用堆外内存:避免JVM内存到堆外内存的数据拷贝,从而提升了IO的操作性能
2、使用CompositeByteBuf合并对象:可以组合多个Buffer对象合并成一个逻辑上的对象,避免通过传统内存拷贝的方式将几个Buffer合并成一个更大的Buffer
3、通过Unpooled.wrappedBuffer合并数据:可以将byte数组包装成ByteBuf对象,包装过程中不会产生内存拷贝
4、使用ByteBuf.slice共享对象:操作与Unpooled.wrappedBuffer相反,slice操作可以将一个ByteBuf对象切分成多个ByteBuf对象,切分过程不会产生内存拷贝,底层共享一个byte数组的存储空间
5、使用FileRegion实现零拷贝:FileRegion底层封装了FileChannerl#transferTo()方法,可以将文件缓冲区的数据直接传输到目标Channel,避免内核缓存区和用户缓冲区之间的数据拷贝,这属于操作系统级别的零拷贝。
https://cloud.tencent.com/developer/article/2425733
71、什么是配置中心?有哪些常见的配置中心?
定义:一种集中管理和存储应用程序配置信息的系统。允许开发人员和运维人员在运行时动态地修改应用程序的配置,而无需重新部署或重启应用。配置中心的主要目的是提高系统的灵活性、可维护性和可拓展性。
常见的配置中心:
1·、Spring Cloud Config
2、Nacos
3、Apollo
4、Consul
5、Etcd
https://blog.csdn.net/weixin_45422672/article/details/145172852
72、说说TCP的四次握手?
在断开连接之前客户端和服务器都处于ESTABLISHED状态,双方都可以主动断开连接,以客户端主动断开连接最优。
第一次挥手:客户端打算断开连接,发出连接释放报文段(FIN报文),指定序列号seq=u,主动关闭TCP连接,等待服务器的确认。
第二次握手:服务器收到连接释放报文段(FIN报文)后,就向客户端发送ACK应答报文,以客户端的FIN报文的序列号seq+1作为ACK应答报文段的确认序列号ack=seq+1=u+1
第三次握手:服务器打算断开连接,向客户端发送连接释放(FIN)报文段,之后服务器进入LASK_ACK(最后确认)状态,等待客户端的确认。
第四次握手:客户端收到来自服务器的连接释放(FIN)报文段后,会向服务器发送一个ACK应答报文段,以连接释放(FIN)报文段的确认序号ack作为ACK应答报文段的序列号seq,以连接释放(FIN)报文段的序列号seq+1作为确认序号ack。
https://cloud.tencent.com/developer/article/2094245
73、Netty是如何解决粘包和拆包问题的?
粘包:消息1和消息2在一个数据包中,一起发送到服务端
拆包:消息1被拆分放在不同的数据包中
解决方案:
1、固定长度:服务端和客户端定好每次发送的业务数据包长度,不够长度填充指定的字符,服务端每次按照固定长度进行读取(FixedLengethFrameDecoder固定长度)
2、分隔符:定好·业务数据分割符,服务端接收数据只有当收到分隔符时,才判断分隔符之前的数据是个完整的业务数据,否则继续等待分隔符(DelimiterBasedFrameDecoder分隔符)
3、自定义包结构体:每次发送数据同时将数据长度带上,存放数据长度的位置定好。
https://cloud.tencent.com/developer/article/2197630
74、为什么Java中HashMap的默认负载因子是0.75?
高负载因子:
更多的元素被存储在有限的桶中,容易发生哈希冲突
哈希冲突会导致链表长度增加,查询和插入操作从O(1)降低到O(n)
低负载因子:
哈希冲突少,查询性能高
但由于扩容过早,内存使用效率低
0.75是一个经验值,能有效减少哈希冲突,同时保证较高的内存利用率。
https://blog.csdn.net/T_Y_F_/article/details/144302579
75、如何处理MySQL的主从同步延迟?
主从同步延迟通常是由主库和从库之间的网络延迟、从库的处理能力、主库的写操作量等因素导致的。
方法:
1、优化主库性能
增加硬件资源
优化SQL查询
批量操作
2、优化从库性能
3、调整复制参数
https://blog.csdn.net/weixin_43968370/article/details/144888582
76、Netty如何解决JDK NIO中的空轮询Bug?
空轮询是指Selector不断进行选择操作(即调用select()方法)却没有实际的I/O事件发生,这会导致CPU利用率异常升高。
Netty作为一个高性能的异步事件驱动的网络应用程序框架,它对JDK NIO的Selector空轮询问题进行了优化处理。
解决方法:
1、使用自定义的Selector实现
2、轮询策略优化
3、使用selectNow()与select(long timeout)结合
4、事件合并
5、异常处理
6、使用多线程模型
https://blog.csdn.net/qq_33240556/article/details/143500438
77、Java中HashMap的扩容机制是怎样的?
HashMap是一个常用的数据结构,基于哈希表实现,它通过键值对的形式存储数据。为了保证其操作的效率,HashMap才用了一种动态扩容机制,当HashMap中元素数量增长到一定程度时,会自动进行扩容。
HashMap的底层存储结构是一个数组,数组中每一个元素称为桶。当插入的元素越来越多是,这些桶会存储链表或红黑树,以解决哈希冲突问题。HashMap的扩容是由其负载因子控制的,负载因子是一个表示HashMap允许装满的程度,默认为0.75,意味着当HashMap中填满了75%的桶时,就会触发扩容操作。
https://blog.csdn.net/hyc010110/article/details/142856587
78、为什么Redis设计为单线程?6.0版本为何引入多线程?
Redis的设计目标是高性能和高并发。采用单线程模型可避免多线程带来的线程切换和锁竞争等开销和多线程环境下可能出现的复杂性和不稳定性问题,提高Redis的性能和并发能力。
由于应用场景越来越广泛,数据量和并发量增加,单线程模型无法满足,故引入多线程提高Redis的处理能力和吞吐量。多线程主要用于网络数据的读写这类耗时操作,而执行命令仍然是单线程顺序执行,避免了线程安全问题,同时确保命令执行的顺序性。
https://blog.csdn.net/H_Sino/article/details/137069050
79、为什么TCP挥手需要有TIME_WAIT状态?
作用:
1、防止延迟的报文段影响新连接
2、确保最后一个ACK被接收到
3、清理资源
4、防止端口冲突
https://blog.csdn.net/qq_39279448/article/details/145320678
80、SpringBoot的核心特性有哪些?
独立运行的Spring应用程序:
1、内嵌Servlet容器
2、可执行JAR和WAR文件
3、简化的启动和关闭过程
自动配置:
1、基于条件自动配置
2、自定义自动配置
3、自动配置报告
灵活的配置管理:
外部化配置
配置文件的优先级
环境变量和命令行参数
丰富的生产级管理
日志管理
安全管理
健康检查和监控
易于拓展:
自定义Starter
事件监听和发布
集成第三方库和框架
https://blog.csdn.net/Javaaaaaaaaaaa13/article/details/144223458
81、为什么HashMap在Java中扩容时采用2的n次方倍?
原因:
1、提高运算速度:在HashMap中,元素的位置是通过计算其键的哈希码并将其映射到内部数组的一个索引来确定的。
2、减少哈希碰撞:当HashMap的容量是2的幂次方时,哈希值的分布更加均匀,有助于减少哈希碰撞的发生。
3、便于调整大小:当HashMap需要扩容时,新的容量也是2的幂次方,这使得旧的哈希值在新的容量下重新计算索引时,可以更好地分散到更大的数组中,从而进一步降低哈希碰撞的概率。
82、你在项目中使用的Redis客户端是什么?
1、Jedis:简单易用,适合同步操作,主要多线程问题
特点:Redis官方推荐的Java客户端,采用同步、阻塞的I/O模型。
同步阻塞、多线程支持、高性能
2、Lettuce:Spring Boot默认使用的客户端,支持同步和异步,线程安全
特点:基于Netty的Redis客户端,支持同步和异步操作,连接默认是线程安全的。
支持异步、同步和响应式操作、线程安全、基于Netty
3、Redisson:提供丰富的分布式工具,适合需要分布式锁、分布式集合等高级功能的场景。
构建分布式系统、支持分布式对象和服务、简单易用的API、可扩展性强
https://blog.csdn.net/qq_35861084/article/details/143339834
83、TCP超时重传机制是为了解决什么问题?
解决问题:数据包在传输过程中可能会丢失。
目的:
确保数据完整性:TCP是连接可靠的传输层协议,保证数据正确无误地源传送到目的地。
处理网络延迟:网络延迟是数据包传输时间超过预期的时间。
84、简述MyBatis的插件运行原理,以及如何编写一个插件?
原理:
插件加载:MyBatis的插件在启动时通过配置文件中的标签定义和加载。每个插件对应一个实现了org.apache.ibatis.plugin.Interceptor接口的类
拦截器接口实现:
动态代理机制
拦截器链构建与运行
基本步骤:
1、创建一个类,实现org.apache.ibatis.plugin.Interceptor接口
2、实现intercept()方法,其中编写具体拦截处理逻辑
3、如果需要处理插件自身的属性配置,实现setProties()方法并处理传入的properties参数
4、在插件类上使用@Signature注解来指定要拦截的目标方法签名
5、在Mybatis的全局配置文件中注册插件,包括插件类的全限定名以及可选的属性配置。
https://blog.csdn.net/qq_46450354/article/details/144751485
85、数组和链表在Java中的区别是什么?
区别:
1、内存存储方式:数组是连续存储的一段空间,而链表非连续
2、大小灵活性:数组大小在创建时已确定,而链表可以方便添加或删除节点来动态改变链表的长度
3、插入和删除操作效率:数组中插入或删除元素时,如果操作位置不是在数组末尾,需要移动大量后续元素;链表值需要调整指针即可
4、访问元素效率:数组由于内存连续存储,可以快速获取,而链表要从头遍历,查找效率低
5、内存使用效率:数组没有额外的内存开销,而链表每个节点除了存储数据元素外,还需要存储指向下一个节点的指针,因此在内存上使用较多
总之:数组用于数据量固定、需要频繁访问元素的场景;链表用于数据量动态变化,需要频繁插入和删除操作的场景。
https://blog.csdn.net/qq_54276699/article/details/144139324**
86、Redis中常见的数据类型有哪些?
1、String:最基本的数据类型,能存储任何形式的字符串
2、Hash:由键值对组成的无序散列表,适合存储对象的属性
3、List:按插入顺序排序的字符串列表
4、Set:无序且不重复的字符串集合(自动去重)
5、Sorted Set:有序集合,每个元素会关联一个分数,根据分数对元素排序
6、Stream:流,用于处理日志、事件流等大规模的消息数据,以时间为序,支持消费者组,便于多消费者协调消费信息
7、Geospatial:用于存储地理位置信息,计算两点距离,获取指定范围内的地理位置等操作
8、Bitmap:通过位操作来存储和操作数据,把数据映射为二进制位,用于海量数据的统计
9、HyperLogLog:基数估算,能用极小的内存空间近似计算海量集合中的不重复元素数量。
https://blog.csdn.net/weixin_46425661/article/details/144747182
87、TCP滑动窗口的作用是什么?
TCP滑动窗口是TCP协议中的一种流量控制机制,用于调节发送方和接收方之间的数据传输速率,以避免网络拥塞和提高传输效率。
88、介绍一个Reactor线程模型?
89、Java线程池核心线程数在运行过程中能修改吗?如何修改?
可以修改。通过调用ThreadPoolExecutor类的setCorePoolSize(int corePoolSize)方法来修改核心线程数。
https://blog.51cto.com/u_16175471/13080191
90、TCP/IP四层模型是什么?
91、说说MyBatis的缓存机制?
缓存:
缓存是存储在内存中的数据。当用户查询数据时,系统可以直接从缓存中获取,而不需要访问数据库,从而提升查询效率。
为什么使用缓存:
减少数据库交互、提高查询效率、支持高并发
使用缓存场景:
经常被查询、变化不频繁
Mybatis缓存机制:
一级缓存(本地缓存):默认开启,作用域为SqlSession级别(不同的SqlSession缓存不会共享)
二级缓存(全局缓存):手动开启,作用域为SqlSessionFactory级别,即同一SqlSessionFactory产生的多个SqlSession共享缓存;缓存的数据时对象的副本,而不是对象本身;
缓存失效情况:
执行了增删改操作,会清空一级缓存和二级缓存,以保证数据一致性
SqlSession关闭,手动清除缓存等。
https://blog.csdn.net/Future_yzx/article/details/145393846
92、什么是SpringBoot?
用于简化Spring应用程序的创建和部署过程,旨在让开发者更快速地启动和运行Spring项目,通过提供一系列默认配置来减少开发者在配置上的工作量。
SpringBoot的自动配置是其核心特性之一,@SpringBootApplication是Spring Boot的核心注解,包含@configuration、@EnableAutoConfiguration、@CompentScan
@configuration:当前类是配置类,可以包含Bean的定义
@EnableAutoConfiguration:启用Spring Boot的自动配置装置,Spring Boot会根据类路径中的库和Bean来配置应用程序
@componentscan:启用组件扫描,自动检测和注册应用程序中的组件。
https://blog.csdn.net/molangmolang/article/details/140856126
93、Java中如何创建多线程?
继承Thread类创建线程:
创建一个类继承自Thread类
重写run方法,在run方法中定义线程要执行的任务
创建该类的实例,调用start方法启动线程
实现Runnable接口创建线程:
创建一个类实现Runnable接口
实现run方法,在run方法中定义线程要执行的任务
创建Runnable接口实现类的实例,将其作为参数传递给Thread类的构造函数,然后调用start方法启动线程
实现Callable接口创建线程:
使用线程池创建线程:
通过Executor工具类的静态方法创建一个线程池对象,或者直接使用ThreadPoolExecutor类来创建自定义的线程池
创建Runnable或Collable接口实现类的实例,作为任务提交给线程池。对于Runnable任务,可以使用execue方法提交;对于Callable任务,使用submit提交
https://blog.csdn.net/weixin_64726356/article/details/143865586
94、Redis中跳表的实现原理是什么?
原理:扩展的有序链表,通过维护一个多级索引结构实现快速查找。在跳跃表中,每个节点包含一个数据元素和一组指向其他节点的指针。这些指针分布在不同层级,每个层级的指针数量都比下一层少。最底层包含所有元素,最高层包含少数几个元素
查找性能:平均O(log N)、最坏O(N)
https://cloud.tencent.com/developer/article/2419519
95、Redis性能瓶颈时如何处理·?
内存使用过高
内存使用过高时,会引发如系统性能下降、内存溢出等问题
优化方法:
定期清理过期数据
数据压缩
分库分表
CPU使用率过高
避免使用复杂的命令
限制数据写入速率
优化数据结构和算法
网络I/O瓶颈
增加网络带宽
数据本地缓存
部署Redis集群
持久化操作影响性能
合理配置持久化策略
调整持久化频率
大键值对的问题
拆分大键
避免存储过大的值
https://blog.csdn.net/yvchiby/article/details/140874581
96、OSI七层模型是什么?
应用层:规定数据的传输协议(HTTP、POP、SMTP等等)
表示层:解决不同系统之间的通信
会话层:会话层建立、管理和终止表示层与实体之间的通信会话
传输层:向高层提供可靠的端到端的网络数据流服务(端口与端口的通信)
网络层:负责在源和终点之间建立连接
数据链路层:规定了0和1的分包形式,确定了网络数据包的形式
物理层:将信息编码成电流脉冲或其它信号用于网上传输
https://zhuanlan.zhihu.com/p/685931989
97、说说AQS吧?
AQS是Java中用于构建锁和其他同步器的基础框架。AQS的核心思想是基于队列的同步器,通过一个先进先出的等待队列来管理线程的排队和唤醒,可以实现各种自定义的同步器,包括互斥锁、信号量、倒计时器等(基于模板方法模式)。
数据结构:一个整型的state变量,用于表示同步状态,通过state变量来实现线程的排队和幻想以及锁的获取和释放。
实现方法:
独占模式方法:实现独占锁,即占有一个线程能够获取到锁
共享模式方法:实现共享锁,多个线程可以同时获取到锁
https://blog.csdn.net/qq_67358181/article/details/138729420
98、Cookie、Session、Token之间有什么区别?
Token:验证用户身份的令牌,通常用于接口的身份验证,一般获取之后放在请求头中
Session:服务器为了方便存储用户会话信息产生的,客户端访问服务器时,服务器会给每个访问对象创建一个的sessionID存储在服务器,客户端通常会将sessionID存储在cookie中,在发送请求时一并发给服务器
Cookie:服务器发送到客户端然后存储在客户端的,可以用来保持用户的登录信息
Cookie跟Session的区别:
存储位置不同:cookie存放在客户端,session存放在服务端
大小限制不同:cookie存储在客户端,数据大小是有限制的,session没有大小限制
安全性不同:cookie的数据在客户端容易被篡改
时效性不同:cookie的时效性短,在服务器设定的时间后失效,session时效性由服务器控制,一般在关闭浏览器断开服务器连接时失效
https://www.cnblogs.com/tyl-bok/p/18200048
99、什么是分库分表?分库分表有哪些类型(或策略)?
概念:分库分表是数据库架构设计策略,用于处理数据量过大,单一数据库无法承载的情况。通过将数据分散到多个数据库或多个数据表中,分库分表能有效提高数据库的扩展性、性能和可维护性。主要目的是提升查询效率,减轻单个数据库的负载,确保系统的高可用性和高性能。
类型:
水平分库分表:数据按照某种规则分散到多个数据库或多个表中
垂直分库分表:数据表中的列拆分到多个表中,每个表存储部分字段,常常用于表的列数过多或某些列的访问频率较低
混合分库分表:
范围分库分表
哈希分库分表
https://www.cnblogs.com/eiffelzero/p/18607999
100、MyBatis中#{}和${}的区别是什么?
#{}是占位符,在预编译时执行
${}是拼接符,能在编译时执行
#{}能防止sql注入,${}不能防止sql注入:由于预编译机制。预编译完成后,sql的结构已经固定,即使用户输入非法参数,也不会对SQL结构产生影响,避免潜在风险。
总结:
能用#{}的地方就用#{};
表名做参数,或者order by排序时用${};
传参时参数使用@param("")注解,@param注解的作用是给参数命名,参数命名后就能根据名字得到参数值(相当于又加了一层密)。
https://blog.csdn.net/X_islu/article/details/134689105