目录
String和StringBuffer和 StringBuilder
mysql/oracle 查询前100条数据,有什么常见优化手段
同步锁 synchronized synchronized 和 lock 区别 作用域区别 方法 类
sql查询 查询数据重复 最大id groupby id count>1 大于一行判断
redis和数据库同步?
秉着最终一致:
1,先更新数据库
2,在更新缓存
如果在第2步出错了,没更新缓存,可采用重试机制,高并发情况下可用异步发送到中间件mq,来实现解耦
非高并发,可把1,2步骤放在一个事物里,失败就回滚;
其他同步方式:
如果采用先删除缓存,再更新数据库如何避免出现脏数据?
采用延时双删策略:
先删除缓存;
写数据库;
休眠 500 毫秒,再删除缓存。
这样子最多只会出现 500 毫秒的脏数据读取时间。关键是这个休眠时间怎么确定呢?
延迟时间的目的就是确保读请求结束,写请求可以删除读请求造成的缓存脏数据。
所以我们需要自行评估项目的读数据业务逻辑的耗时,在读耗时的基础上加几百毫秒作为延迟时间即可。
在高并发的场景下,重试最好使用异步方式,比如发送消息到 mq 中间件,实现异步解耦。
终极方案:
读取binlog异步+Canal工具;
推荐采用「先更新数据库,再删除缓存」方案,并配合「消息队列」或「订阅变更日志」的方式来做。
数据库的存储过程
没懂 引用文章地址
String和StringBuffer和 StringBuilder
String是只读字符串,它并不是基本数据类型,而是一个对象。从底层源码来看是一个final类型的字符 数组,所引用的字符串不能被改变,一经定义,无法再增删改。每次对String的操作都会生成新的 String对象。
private final char value[];
每次+操作 : 隐式在堆上new了一个跟原字符串相同的StringBuilder对象,再调用append方法 拼接 +后面的字符。
StringBuffer 对方法加了同步锁或者对调用的方法加了同步锁,所以是 线程安全的。StringBuilder 并没有对方法进行加同步锁,所以是非线程安全的。
ArrayList和linkedList的区别
ArrayList底层的实现是Array, 数组扩容实现
Array(数组)是基于索引(index)的数据结构,查询快增删慢
缺点: 数组初始化必须指定初始化的长度, 否则报错
LinkList是一个双链表,在添加和删除元素时具有比ArrayList更好的性能.但在get与set方面弱于 ArrayList.当然,这些对比都是指数据量很大或者操作很频繁。
List—是一个有序的集合,可以包含重复的元素,提供了按索引访问的方式,它继承Collection。 List有两个重要的实现类:ArrayList和LinkedList ArrayList: 可以看作是能够自动增长容量的数组 ArrayList的toArray方法返回一个数组
ArrayList的asList方法返回一个列表
接口和抽象类的区别?
01. 接口的方法默认是 public,所有方法在接口中不能有实现(Java 8 开始接口方法可以有默认实现),抽象类可以有非抽象的方法。
02. 接口中的实例变量默认是 final 类型的,而抽象类中则不一定 。
03. 一个类可以实现多个接口,但最多只能实现一个抽象类 。
04. 一个类实现接口的话要实现接口的所有方法,而抽象类不一定 。
05. 接口不能用 new 实例化,但可以声明,但是必须引用一个实现该接口的对象 从设计层面来说,抽象是对类的抽象,是一种模板设计,接口是行为的抽象,是一种行为的规范。
重载和重写的区别?
重载:发生在同一个类中,方法名必须相同,参数类型不同.个数不同.顺 序不同,方法返回值和访问修饰符可以不同,发生在编译时。
重写:发生在父子类中,方法名.参数列表必须相同,返回值范围小于等于父类,抛出的异常范围小于等于父类,访问修饰符范围大于等于父类;如果父类方法访问修饰符为 private 则子类就不能重写该方法。
冒泡排序?
int arr[] = {5, 3, 7, 1, 6, 2, 9, 0};
for (int i = 0; i < arr.length - 1; i++) {
//只需要对没有排序的进行排序
for (int j = 0; j < arr.length - 1 - i; j++) {
//将前一个比后一个大的两元素进行交换
if (arr[j] > arr[j + 1]) {
int tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
}
}
mysql/oracle 查询前100条数据,有什么常见优化手段
SELECT *
FROM table_name
ORDER BY column_name DESC
LIMIT 100 --ASC升序、DESC降序
SELECT *
FROM table_name
WHERE ROWNUM <= 100
ORDER BY column_name DESC
优化:
应尽量避免在 where 子句中对字段进行 null 值判断, 否则将导致引擎放弃使用索引而进行全表扫描,
应尽量避免在 where 子句中对字段进行 null 值判断, 否则将导致引擎放弃使用索引而进行全表扫描,
应尽量避免在 where 子句中使用 or 来连接条件, 否则将导致引擎放弃使用索引而进行全表扫描
Orcale数据转化为mysql怎么操作
手动迁移Oracle数据库到MySQL需要以下步骤:
1. **创建MySQL数据库:** 在MySQL服务器上创建一个新的数据库,用于存储从Oracle迁移而来的数据。
2. **导出Oracle数据库结构:** 使用Oracle提供的工具,如SQL*Plus或SQL Developer,导出Oracle数据库的结构信息,包括表、索引、约束等,保存为SQL文件。
3. **转换Oracle数据库的SQL语法:** 使用文本编辑器或脚本,将Oracle数据库的SQL语法转换为MySQL兼容的语法。这可能涉及到一些差异,比如数据类型、函数、存储过程等。
4. **在MySQL中创建表结构:** 使用转换后的SQL文件,在MySQL数据库中创建相应的表结构。
5. **导出Oracle数据库数据:** 使用Oracle提供的工具或命令,如exp导出工具,将Oracle数据库中的数据导出为SQL文件。
6. **转换数据:** 如果必要,对导出的数据进行转换,以确保其与MySQL兼容。
7. **导入数据到MySQL:** 使用MySQL提供的工具或命令,如mysql导入命令,将导出的数据文件导入到MySQL数据库中。
8. **验证数据完整性:** 确保数据在转移过程中没有丢失或损坏,可以通过对比源数据库和目标数据库的数据进行验证。
9. **测试应用程序:** 在转移完成后,测试你的应用程序确保它能够正常工作并且数据一致性没有问题。
10. **定期备份:** 完成迁移后,定期备份MySQL数据库,以防止数据丢失或损坏。
这些步骤需要一定的数据库管理经验和技能,确保在开始迁移之前仔细阅读相关文档并做好备份是非常重要的。
使用数据迁移工具进行Oracle到MySQL的迁移通常比手动迁移更简单和可靠。以下是一般的步骤:
1. **选择合适的迁移工具:** 根据你的需求选择一个合适的数据迁移工具,如Oracle的GoldenGate、AWS的Database Migration Service、或其他第三方工具如Talend、Attunity等。
2. **安装和配置工具:** 安装并配置选定的迁移工具。这可能涉及到在源数据库和目标数据库服务器上安装相应的客户端或代理程序,并设置连接参数和权限等。
3. **创建迁移任务:** 在迁移工具中创建一个新的迁移任务,指定源数据库(Oracle)和目标数据库(MySQL),以及要迁移的数据表和其他对象。
4. **配置映射和转换:** 配置迁移任务以确保源数据库中的数据可以正确映射到目标数据库中。这可能涉及到数据类型转换、字段映射、约束转换等。
5. **执行迁移任务:** 启动迁移任务,让工具开始将数据从Oracle数据库迁移到MySQL数据库。在此过程中,工具会自动处理数据同步和转换,确保数据的一致性和完整性。
6. **监控和调优:** 在迁移过程中监控任务的进度和性能,根据需要进行调优以提高迁移效率和准确性。
7. **验证数据完整性:** 迁移完成后,验证目标数据库中的数据与源数据库中的数据一致性和完整性。
8. **测试应用程序:** 在迁移完成后,测试你的应用程序确保它能够正常工作并且数据一致性没有问题。
9. **定期备份:** 完成迁移后,定期备份MySQL数据库,以防止数据丢失或损坏。
每个迁移工具都有其独特的特性和步骤,因此在使用之前最好阅读相关文档并按照指导执行相应的操作。
后端用过什么框架,前段用过什么框架
linux部署过哪些系统 微服务部署有吗
java外还有用过哪些语言
java面向对象怎么理解的,java有几种引用方式
Java 面向对象编程是基于对象的概念,通过封装、继承、多态来模拟现实世界中的对象和它们之间的关系。
封装:将对象的状态(数据)和行为(方法)打包在一起,隐藏对象的内部实现细节,只提供公开的接口供其他对象访问。
继承:一个类可以继承另一个类的属性和方法,同时可以添加自己的属性和方法。
多态:同一个行为具有多种不同的表现形式,可以通过方法重载(Overloading)和方法重写(Overriding)实现
强引用:当我们new对象时候就是强引用,垃圾回收器是不会回收的,就算内存不足时候抛异常,也不会
软引用:在内存足够的时候,软引用对象不会被回收,只有在内存不足时,系统则会回收软引用对象
弱引用:无论内存是否足够,只要 JVM 开始进行垃圾回收,那些被弱引用关联的对象都会被回收
虚拟引用:虚引用是最弱的一种引用关系,如果一个对象仅持有虚引用,那么它就和没有任何引用一样,它随时可能会被回收
bio阻塞、aio异步,nio非阻塞 等区别
aio异步:它的特点是 I/O 操作不会阻塞线程,而是在后台由操作系统完成,完成后会通知应用程序。AIO 可以让应用程序在等待 I/O 完成时执行其他任务,提高了系统的并发性能。AIO 适用于高并发的网络应用,比如聊天室、多人在线游戏等。
bio阻塞:它的特点是 I/O 操作会阻塞线程,直到 I/O 操作完成。BIO 的缺点是并发性能较差,因为每个线程都会阻塞等待 I/O 完成。
nio非阻塞:它的特点是 I/O 操作不会阻塞线程,但是需要轮询操作系统的 I/O 事件来判断是否有 I/O 操作完成。 适用于连接数较多、并发性要求较高的网络应用,比如高性能的服务器应用、网关应用等。
sprinIoc怎么理解
控制反转,就是我们以前创建对象主动权和时机是我们自己掌控,现在就是把这个权利转移到了ioc容器,他来帮我们创建。我们不需要知道他何时创建的,我们就直接用就可以了。简化代码,解耦。
举例:找对象。传统的就是 我们需要认识了解他的喜好一堆步骤,才能找到符合的对象。ioc就是婚介所,我们只需要说出要啥类型的,婚介所直接帮我找好了,直接处就行了
git用过吗,流程了解吗
mybatis 一二级缓存?
Mybatis为了提高查询的效率,内置了缓存机制。
缓存:把经常访问但是不经常修改的数据存储在缓存内容中,减少与数据库交互,从而达到提高效率的目的
Mybatis因为缓存的位置不一样又分为了2种缓存:一级缓存 和二级缓存
1,一级缓存的数据存储在SqlSession对象里面
类似于map key是sql value是执行结果
默认开启 session结束 缓存清除
保持一致性方法 非查询操作时候回清除缓存
2,二级缓存是把缓存的数据存储在SQLSessionFactory上面(对象内部)
二级缓存的数据,所有的session可以共用
二级缓存默认关闭,使用的需要配置
项目 加密?
1,对称加密 des,aes
2,非对称RSA
sql优化?
- 优化索引,看看索引生效没语句:(EXPLAIN SELECT * FROM table_name WHERE column = 'value';)(SHOW INDEX FROM table_name;),
- 优化查询列,不要selest* 尽量不用子查询
- 优化表,优化表结构 数据类型优化 ,4,分库分表
- 优化机器
什么情况不走索引
- like 左模糊查询
- in关键字,
- 查询索引上有函数计算
- 字段值过少,例如性别字段 只有男女,
- where字段=两边字段类型不一样
- 使用or时候 有一个列没索引
mysql执行计划
在MySQL中,我们可以通过explain命令来查看执行计划。其语法如下
EXPLAIN SELECT * FROM `Seckills` AS `s`
执行计划的输出结果包含了多个列,下面是对一些常见列的介绍:
- id:一个查询的唯一标识符。对于一个较复杂的查询,可能包含多个子查询,每个子查询都有一个唯一的id。
- select_type:查询的类型,常见的类型有SIMPLE(简单查询)、PRIMARY(最外层查询)、SUBQUERY(子查询)等。
- table:查询涉及的表名。
- partitions:查询涉及的分区名称。
- type:访问类型,表示MySQL将如何访问表。常见的类型有ALL(全表扫描)、index(索引扫描)、range(范围扫描)等。
- possible_keys:可能使用的索引列表。
- key:实际使用的索引。
- key_len:实际使用的索引长度。
- ref:与索引相关的字段。
- rows:扫描的行数。
- filtered:过滤的行数。
- Extra:额外的信息,包括是否使用了临时表、文件排序等。
什么是数据库的设计三范式?
第一范式:每列的原子性:每列都是不可再分的最小数据单元
第二范式(2nd NF):每个表只描述一 件事情
第三范式(3rd NF):不存在对非主键列的传递依赖
文件上传 文件大小控制 2种?
- 后端 第一步 request.getContentLenght()是否大于规定的请求,第二步 获取file 文件 file.getSize() 方法获取文件大小
- 前端 input.files[0].size() 是否大于规定
equas会重写hashcode方法吗?
- 一定会
session和cookie的区别与联系?
Cookie是在客户端保持状态的方案,主要包括名字,值,过期时间,路径和域,session是存在服务器的一种用来存放用户数据的类HashTable结构。
区别:
1.存储数据量方面:session 能够存储任意的 java 对象,cookie 只能存储 String 类型的对象。
2.数据存储位置:一个在客户端一个在服务端。因Cookie在客户端所以可以编辑伪造,不是十分安全。
3.资源消耗程度:Session过多时会消耗服务器资源,大型网站会有专门Session服务器,Cookie存在客户端没问题。
4.域的支持范围不一样:比方说a.com的Cookie在a.com下都能用,而www.a.com的Session在api.a.com下都不能用,解决这个问题的办法是JSONP或者跨域资源共享。
单点登录问题:如果禁用了Cookie,怎么办?
单点登录的原理是后端生成一个 session ID,设置到 cookie,后面所有请求浏览器都会带上cookie,然后服务端从cookie获取 session ID,查询到用户信息。所以,保持登录的关键不是cookie,而是通过cookie 保存和传输的 session ID,本质是能获取用户信息的数据。除了cookie,还常用 HTTP 请求头来传输。但这个请求头浏览器不会像cookie一样自动携带,需手工处理
final,finally和finalize三者的区别
final是一个修饰符:
当final修饰一个变量的时候,变量变成一个常量,它不能被二次赋值
当final修饰的变量为静态变量(即由static修饰)时,必须在声明这个变 量的时候给它赋值
当final修饰方法时,该方法不能被重写
当final修饰类时,该类不能被继承
Final不能修饰抽象类,因为抽象类中会有需要子类实现的抽 象方法,(抽 象类中可以有抽象方法,也可以有普通方法,当一个抽象类中没有抽象方 法时,这个抽象类也就没有了它存在的必要)
Final不能修饰接口,因为接口中有需要其实现类来实现的方法
Finally:
Finally只能与try/catch语句结合使用,finally语句块中的语句一定会执行, 并且会在return,continue,break关键字之前执行
finalize:
Finalize是一个方法,属于java.lang.Object类,finalize()方法是GC (garbage collector垃圾回收)运行机制的一部分,finalize()方法是在 GC清理它所从 属的对象时被调用的
多态理解
- 一个事物他有多种形态 比如 汽车,他有大众,比亚迪,不同形态的车。大众继承 汽车,必须重写 父类的所有方法们也可以有自己的方法。
强引用,弱引用
- 强引用(StrongReference)强引用是使用最普遍的引用。如果一个对象具有强引用,那垃圾回收器绝不会回收它。当内存空间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足的问题。
- 软引用(SoftReference)如果一个对象只具有软引用,则内存空间足够,垃圾回收器就不会回收它;如果内存空间不足了,就会回收这些对象的内存。只要垃圾回收器没有回收它,该对象就可以被程序使用。软引用可用来实现内存敏感的高速缓存。 软引用可以和一个引用队列(ReferenceQueue)联合使用,如果软引用所引用的对象被垃圾回收器回收,Java虚拟机就会把这个软引用加入到与之关联的引用队列中。
- 弱引用(WeakReference) 弱引用与软引用的区别在于:只具有弱引用的对象拥有更短暂的生命周期。在垃圾回收器线程扫描它所管辖的内存区域的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。不过,由于垃圾回收器是一个优先级很低的线程,因此不一定会很快发现那些只具有弱引用的对象。
- 虚引用(PhantomReference) “虚引用”顾名思义,就是形同虚设,与其他几种引用都不同,虚引用并不会决定对象的生命周期。如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收器回收。 虚引用主要用来跟踪对象被垃圾回收器回收的活动。虚引用与软引用和弱引用的一个区别在于:虚引用必须和引用队列 (ReferenceQueue)联合使用。当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之 关联的引用队列中。
数组和链表啥区别
- 数组可以随机以及顺序存取,而链表只能顺序存取。
- 数组静态分配内存,链表动态分配内存。
- 数组是一种线性表数据结构,有一组连续的内存空间,链表是通过指针将一组零散的内存块串联起来使用的数据结构,不需要一块连续的内存空间。
list set map
- hashmap hashtable 区别
- hashmap 线程不安全 可以有null 初始大小是16 扩容为2n
- hashtable现成安全 不能有null 初始大小是11 扩容为2n+1
error exception 异常那个
- error是虚拟机无法解决的
- exception 是程序员造成的 可以别解决
全局异常怎么做的
- 使用@ControllerAdvice和@ExceptionHandler注解:
- `@ControllerAdvice`用于定义全局控制器异常处理。
- `@ExceptionHandler`用于指定针对特定类型的异常进行捕获和处理。
微服务之间调用几种方法
- RestTemplate()
- 引入Nacos注册中心
HttpClient、RestTemplate 对比
- HttpClient代码复杂,还得操心资源回收等
- RestTemplate可以很好的集成spring 提供了多种便捷访问远程Http服务的方法,能够大大提高客户端的编写效率。
实现线程方式
现成同步
同步锁 synchronized
synchronized 和 lock 区别 作用域区别 方法 类
- synchronized是Java中的关键字,隐式地控制线程同步;而Lock是一个接口,需要用户自己创建锁对象。 Lock比synchronized更灵活
悲观 和乐观锁
lock实现方式 +版本号
事务特性
脏读 幻读 不可重复读
@Resource注解与@Autowired
- @Autowired注解默认按照类型进行注入,并且支持自动装配。而@Resource注解则可以按照名称或类型进行注入
ioc 和aop
# 和$
mybatis 实现分页几种方式,
- 物理分页 借助liit 来分页
- 逻辑分页 一次查出全部数据 靠代码来分页
limin 参数
- 第一个参数表示第几行开始 第二参数表示展示几行数据
mybatis 一对一 和一对多标签
mybatis包扫描 几种方式
redis多少个库 16个
redis缓存穿透,
redis分布式事务
sql查询 查询数据重复 最大id groupby id count>1 大于一行判断
查看当前目录 ls
查看当前目录地址 pwd
HTTP,HTTPS啥区别
简单来说https是http的加密版
1,http端口是80,https是443。URL 以 开头http://,而通过 HTTPS 的 URL 以 开头https://。
2,http是铭文传输,https是加密传输 (ssl/tls)。
3,http不需要证书,https需要像ssl购买证书
List和Set区别
List、Set都继承自Collection接口
1,list是一个有序,可重复,允许多null元素的,set无序,不可重复,只能一个null元素
2,list有索引下标可以使用增强for 和迭代器遍历,set,只能迭代器遍历,没有索引下表
3,list在增加,删除素的快,因为使用动态数组。set在判断是否存在效率更高,用的哈希表来存储元素
resulttype和resultMap区别
是mybatis的用于处理sql语句的返回结果
resulttype简单的一对一处理,直接返回pojo映射属性
resultMap是一对多,多对多的关系,并在 `mapper.xml` 中通过 `association` 等节点元素来定义表之间的连接处理。
浏览器发出一个请求到收到响应经过哪些步骤?
1,浏览器解析url 生成一个http的请求
2,根据url域名从本地hosts文件好查找映射地址,
3,浏览器通过四层网络协议发出去
4,通过路由器,交换机,到达服务器
5,服务器接收到请求后,根据请求端口,发送到绑定该端口的应用程序上,
6,tomcat接收到请求后,按照http协议解析,得到访问的servlet
7,通过servelt处理请求,返回方法得到的结果
8,tomcat等到结果后,封装http格式返回响应,到浏览器在的服务器
9,浏览器所在的服务器拿到结果后再传递给浏览器,浏览器负责解析渲染
Tcp三次握手和四次挥手
三次握手:
1,客户端发送一个数据包给服务器,第一次握手
2,服务器给客户端返回一个数据包ack说我收到了,第二次
3,客户端再次给服务器发送一个数据包ack说我知到你收到了。第三次
四次挥手:
1,客户端想服务端发送fin,说我要断开了,
2,服务端收到fin之后,向客户端发送ack说我知道你要断开但是先别断还有点数据没完事。等下
3,服务端处理完数据之后,再向客户端发送fin说ok了可以断开了。
4,客户端收到fin之后,在向服务端发送ack,表示客户端也会断开了
Spring的bean生命周期
答:5个
1:实例化(Spring容器根据配置信息或注解来创建Bean的实例。实例化可以通过构造函数实例化,也可以通过工厂方法实例化)
2:赋值属性()
3:初始化
4:使用
5:销毁
Spring中Bean是线程安全的吗?
答:没有对Bean做线程安全处理的,Bean有状态是不安全,无状态是安全的,作用域是对线程安全灭有关系的,作用域是表示Bean对象的生命周期范围。线程安全不安全还是得看Bean对象本身
Spring的事务怎么实现的?
答:对加了@Transactional注解的Bean 会创建一个代理对象最为Bean,连接数据库,把autocommit=false,(自动提交关闭)就执行sql,没有异常,提交;有异常,回滚。
(隔离级别是和就是数据库的隔离级别)
Sring中什么时候@Transactional会失效?
答:方法是用private非public修饰的会失效,底层是cglib基于父子类实现的子类不能重载父类private方法。
Sring启动容器流程怎样?
扫描所有的BeanDefinition对 然后存到Map,利用BeanDefinition创建Bean的生命周期,实例化,填充属性,初始化, Spring启动结束
多列Bean是需要在启东时候创建,他会在灭磁获取Bean时候利用BeanDefinition创建
Spring用到的设计模式?
工厂模式,单例模式,观察者模式,适配器模式,访问者模式,装饰器模式,代理模式,策略模式怎人链模式,模版方法模式。
Spring常用的注解?
@SringBootApplication注解
这个注解标志一个SpringBoot工程,它是由3个注解组合的
1:@SPringBootConfiguration:这个注解其实就是@Configuration,表示启动类也是一个配置类
2:@EnableAutoConfiguration:他是用来加载ClassPath下SpringFactories中所有自定义的自动配置类,讲这些自动加载为配置Bean
3:@ComponentScan:扫描路径,默认是没有配置实际的扫描路径,所以,他扫描的路径是启动类所在的当前目录
@Bean:
他是用来定义Bean类似于xml<Bean>标签,在Spring启动时会对加了@Bean注解的方法解析,方法名字作beanName,并通过执行方法得到bean对象
@RequestBody
是作用在形参列表上,用于将前台发送过来固定格式的数据【xml格式 或者 json等】封装为对应的 JavaBean 对象
@ResponseBody
作用其实是将java对象转为json格式的数据
@Controller,@Service,@RequestMapping("路径"),@Autowired等等
SpringBoot是怎么启动Tomcat的
SpringBoot启动会先创建一个Spring容器,创建容器过程会用@ConditionalOnClass技术判断classpath中是否存在Tomcat依赖,存在会生成一个启动Tomcat的Bean,Spring创建完容器之后就会获取启动Tomcat的Bean,创建Tomcat对象,绑定端口,启动Tomcat
Mybatis优缺点
优点
简洁 方便,可以单独的在xml文件里写sql,方便同意管理;提供xml标签,支持编写动态的sql,可以重用;可以和Spring很好的集成。
很好的与各种数据库兼容,(Mybatis使用JDBC连接数据库,只要J都不错支持那MybATIS也支持)
提供映射标签,支持对象与数据库字段映射,提供对象关系映射标签支持组件维护
<resultMap id="roleMap" type="role">
<!--id:主键字段
property:实体中的属性名称
column:数据库字段的名称-->
<id property="id" column="id"></id>
<!--
result:普通字段手动赋值
property:实体中的属性名称
column:数据库字段的名称-->
<result property="roleName" column="role_name"></result>
<result property="roleDesc" column="role_desc"></result>
</resultMap>
<select id="findAll" resultMap="roleMap">
select * from role
</select>
缺点:sql编程量大字段多表多的时候,书写难度增加
sql依赖数据库,不能更换数据库
#{}和${}区别?
#{}是占位符 ;${}是字符串替换是拼接符
Mybatis处理#{} 会讲sql中#{}替换为?,可以防止sql注入提高安全
Mybatis处理${} 会将sql中${}变成变量的值
事务的特征和隔离级别
ACID
1,原子性:一个事务中要么全部成功要么全部失败
2,一致性:数据库总是从一个一致性的状态转换到另一个一致性的状态,比如AB转账,他俩的总额是不会变的
3,隔离性:在提交之前对其他事务不可见。也叫串行
a:read uncommit 读未提交,这种可能读到其他事务未提交的数据也叫脏数据
b:read commit 读已提交 ,要是2次读结果不一致叫做不可重复读,不可重复读解决了脏数据的问题,他只会读取已提交的数据;举例:开启事务 name=“张三” 查询到age=10,在次读时候发现age=20 ,在同一个事务里,2次读取的结果不一致叫做不可重复度
c:repeatable read 可重复读,mysql默认级别,就是每次读取的结果都一直,但是有可能产生幻读
d:serializable 串行,他会给每一行加锁,导致大量锁超时和锁竞争问题
4,持久性:事务一旦提交,所做的修改就会永久的保存到数据库里
Mysql有那些锁?
按颗粒度
行锁:锁某行,颗粒度最小,并发高
表锁:锁整张表,颗粒度最大,并发低
间隙锁:锁的一个区间
还可以分
1,共享锁:就是读锁给某行数据加了锁,其他事务能读不能写
2,排它锁:给某行加了锁,其他事物不能读也不能写
乐观锁:不会去真正的去锁某行,只有在更新数据的时候才会检查这条数据是否被其他线程更新了;通过版本号和时间戳来实现加锁
悲观锁:在事务开始时就对数据进行加锁,其他事务需要等待当前事务完成后才能获取到相同数据的锁。这种锁定机制可以保证数据的一致性,但会导致并发度下降
mysql查询优化
1检查查询是否走了索引,要是么有优化sql
2检查索引是否用到了最优的索引
3检查查询select字段是否全有用,去掉没用的字段
4检查是否表数据太多,是否进行分库分表
5检查数据库所在的机器的性能,适当增加资源
RDB和AOF
rdb:快照,在指定的间隔时间内,把内存的数据集体写入磁盘
优点:整个redis数据库质保函一个dump.rdb,方便持久化
性能最大化,用fork子线程去完成写的操作,主线程继续处理命令,IO最大化。保证高性能
相比于大的数据集比Aof快
缺点:因为是固定时间间隔,在这个中间出现问题,会发生丢失数据
子线程完成持久化当数据集大的时候 会导致整个服务器停止几百毫秒
Aof:
以日志的形式来记录服务器的的写,删除操作(查询不会记录),文本的形式。
优点:数据安全,可以设置每秒记录,还有每次修改同步,保证数据不会丢失
缺点:aof文件比rdb文件大,恢复慢,效率低;
Redis数据结构?
String(字符串) key-value结构
Hash(哈希)
list(列表)
Set(集合)
Sorted Set(有序集合)
Redis分布式锁底层原理是怎么实现的?
1利用setx来保证:如果key不存在才能获取锁,如果key存在,则获取不到锁。
2,然后还要利用lua脚本来保证多个redis操作的原子性
3,考虑锁过期,所以需要额外的一个看门狗定时任务来监听锁是否要续约
4,同事考虑到redis节点挂到之后,所以需要采用 采用红锁方式来同时向N/2+1个节点申请锁,都申请到了,才能证明获取锁成功了。这样就算其中某个redis挂掉了,也不能让其他的客户端获取到。
redis主从复制原理?
1,先启动集群,建立连接
2,住库先将所有的数据都复制给从库,这里主要用到的rdb快照(Io最大化)
3,因为在这个复制过程,还会有新的写操作,就导致rdb快照之后的数据没有复制到从库,为了持一致性,主库会在内存用专门replication buffer,记录之后的写操作
4,主库会把新接受到的写命令,在发送给从库。rdb完事之后,此时replication buffer中修改的操作发送给从库,从库执行这些命令。这样就主从一致了
5,之后主库和从库都可以读操作,写操作给主库,主库接收到新写还会发送给从库,就主从一致了。
redis集群策略?
主从:主库可以读写,从库只能读操作,会和从库进行数据同步,这种情况客户端连接主库或者从库,一旦主库宕机后,需要手动修改ip,这种也难扩容,因为整个集群能存数据的上限收到某台机器的容量,所以不能支持特大数据量
哨兵:就是在主从模式上增加了哨兵节点。主库宕机了,哨兵会发现然后选择一个从库最为主库,哨兵也可以做集群来保证一个哨兵宕机了还有其他的哨兵继续工作。这种会保证集群的高可用
cluster模式(集群):是一种多主多从模式,这种模式按照key进行槽位的分配,可以使得不同key分散到不同的主节点,利用这种模式可以使得整个集群支持更大的数据容量,同时每个主节点都拥有多个从节点,如果主节点宕机就会选择他的从节点中选举一个新的主节点。
这三种模式如果数据量不大 用哨兵,数据量大并且需要扩容,用cluster
缓存穿透,缓存击穿,缓存雪崩是啥?
缓存雪崩:指的大连的热点key过期,直接访问数据库导致的。解决办法,在过期时间上增加一点随机值,另外如果搭建一个高可用的redis集群也是防止缓存雪崩的的有效手段。
缓存击穿:和雪崩类似,只不过是一个热点key过期,导致访问数据库。解决方案让这个热点key不过期。
缓存穿透:在某一时刻 访问redis的key都不存在(黑客伪造的key)那么也会给数据造成压力,就是缓存穿透。解决方案,使用布隆过滤器,访问时如果他都认为key不存在,那么就是不存在,不让他访问。