索引失效
1.使用select *
2.使用函数
3.违反最左原则
4.Like 值前有百分号
5.使用运算符
6.字段类型不同
7.列对比–两个列运算当做查询条件
8.使用or关键字–如果使用了or关键字,那么它前面和后面的字段都要加索引
9.Not in --主键可以走,其他不可以 和not exist–都不可以
10.Order by
sql优化
1.避免select *,避免回表
2.使用union all 代替 union,少一次过滤
3.使用join代替子查询
4.使用limit
5.使用in(左大右小),exists (左小右大),让查询条件变快
6.批量操作
7.In中值太多
8.Join表不宜过多,不超3个
9.控制索引数量
10.选择合适的字段类型
11.提升group by 的效率
12.索引优化
多线程
1.Thread 类,默认不可以抛出异常,但是可以自定义异常类进行异常捕获
2.Runnable 接口,不可以抛出异常,可以避免单继承带来的局限性
3.Callable 接口,有返回值,可以抛出异常
4.线程池参数:七个
5.保证提交线程池的任务不会失败:
在任务执行前进行参数校验,确保任务的参数合法性,避免因为参数问题导致任务执行失败。
在任务执行过程中进行异常捕获和处理,避免因为异常导致任务执行失败。
在任务执行完成后进行结果校验,确保任务执行结果正确,避免因为结果问题导致任务执行失败。
在任务提交到线程池前,可以设置线程池的拒绝策略,当线程池队列已满时,可以选择抛出异常或者阻塞等待,避免任务提交失败。
mysql的存储引擎
B+树和B树
在 B 树中每个节点都同时保存索引和数据记录信息,而 B+ 树只保存索引信息,将所有的数据记录都存储在叶子节点上,并按照一个有序链表进行连接。这使 B+ 树具有更快的查找速度和更高的性能,特别适合用于范围查找、分页查询等操作。
事务
事务的隔离级别
幻读是在哪个隔离级别可避免的
消息队列及其实现架构
说一下JVM
JS的异步执行原理
事件修饰符
vue的哪个生命周期可以实现异步加载
数组转 List:使用 Arrays. asList(array) 进行转换。
List 转数组:使用 List 自带的 toArray() 方法。
springboot和spring的区别于优势
springboot常用注解
迭代器,遍历集合,不可以用集合的remove删除,会导致期望版本号与当前版本号不符,报java.util.ConcurrentModificationException运行时异常,应该使用迭代器的remove方法,这样删除的同时,会将当前版本号赋值给期望版本号,就不会报错了
(Iterator是工作在一个独立的线程中,并且拥有一个 mutex 锁。 Iterator被创建之后会建立一个指向原来对象的单链索引表,当原来的对象数量发生变化时,这个索引表的内容不会同步改变,所以当索引指针往后移动的时候就找不到要迭代的对象,所以按照 fail-fast 原则 Iterator 会马上抛出)
增强for循环本质是实现了一个迭代器,编译后源码解析:
Iterator iterator = list.iterator(); 获取List的迭代器
iterator.hasNext(); 判断迭代器中是否有未遍历过的元素
i = (Integer)iterator.next(); 获取第一个未遍历的元素,赋值给临时变量i
System.out.println(i) 输出临时变量i的值
for循环优化
1.嵌套for循环外小内大
2.在for循环外捕获异常
ArrayList 和 LinkedList 都是不同步的,线程不安全,vector增加了synchronized 关键字,是线程安全的
保证线程安全的方式
线程安全解决办法 :
方法1: Collections.synchronizedList(new LinkedList())
方法2: LinkedList和ArrayList换成线程安全的集合,如CopyOnWriteArrayList,ConcurrentLinkedQueue…
方法3:Vector(内部主要使用synchronized关键字实现同步)
HashMap的多种实现方式
HashSet 是基于 HashMap 实现的,HashSet的值存放于HashMap的key上,HashMap的value统一为PRESENT
当我们往Hashmap中put元素时,利用key的hashCode重新hash计算出当前对象的元素在数组中的下标
- 存储时,如果出现hash值相同的key,此时有两种情况。(1)如果key相同,则覆盖原始值;(2)如果key不同(出现冲突),则将当前的key- value放入链表中
- 获取时,直接找到hash值对应的下标,在进一步判断key是否相同,从而找到对应值。
理解了以上过程就不难明白HashMap是如何解决hash冲突的问题,核心就是使用了数组的存储方式,然后将冲突的key的对象放入链表中,一旦发现冲突就在链表中做进一步的对比。
JDK1.8以后,将链表转换成红黑树前会判断,即使阈值大于8,但是数组长度小于64。此时并不会将链表变为红黑树。而是选择进行数组扩容。
HashMap的hash方法
两次扰动:static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
3. 右移16位是为了让高16位也参与运算,可以更好的均匀散列,减少碰撞,进一步降低hash冲突的几率
4. 异或运算是为了更好保留两组32位二进制数中各自的特征
HashMap 是非线程安全的,HashTable 是线程安全的(基本被淘汰);HashTable 内部的方法基本都经过 synchronized 修饰。(如果你要保证线程安全的话就使用 ConcurrentHashMap 吧!,ConcurrentHashMap(1.8中)采用CAS(Compare and swap)和synchronized实现线程安全。synchronized只锁定当前链表或者红黑树的首节点,只要不发生hash冲突,就不会产生并发,效率大大提高。但是不允许键值对为null)
CAS也存在一个著名的问题,叫做ABA问题。ABA问题指的是,如果一个变量A,被修改为B之后又被修改为A,那么CAS机制是无法察觉到这个变化的,因为它只关心变量的当前值是否与预期值相同,而不关心变量的历史值。这就可能导致一些错误的结果。解决办法是每修改一次后版本号增加1,且版本号只增不减
comparable 和 comparator的区别?
- comparable接口实际上是出自java.lang包,它有一个 compareTo(Object obj)方法用来排序
- comparator接口实际上是出自 java.util 包,它有一个compare(Object obj1, Object obj2)方法用来排序
- 一般我们需要对一个集合使用自定义排序时,我们就要重写compareTo方法或compare方法。
Collections 工具类的 sort 方法有两种重载的形式,
第一种要求传入的待排序容器中存放的对象比较实现 Comparable 接口以实现元素的比较;
第二种不强制性的要求容器中的元素必须可比较,但是要求传入第二个参数,参数是Comparator 接口的子类型(需要重写 compare 方法实现元素的比较),相当于一个临时定义的排序规则,其实就是通过接口注入比较元素大小的算法,也是对回调模式的应用
springboot的常用注解和事务
开启事务
Spring提供了一个@EnableTransactionManagement注解在配置类上来开启声明式事务的支持(开启注解支持)。使用了@EnableTransactionManagement后,Spring容器会自动扫描注解@Transactional的方法和类。SpringBoot默认已开启,可不用显式注解。
要使用事务,我们只需要在需要事务的类或方法上使用@Transactional 注解即可,当注解在类上的时候意味着此类的所有public方法都是开启事务的。被注解的方法都成为一个事务整体,同一个事务内共享一个数据库连接,所有操作同时发生。如果在事务内部执行过程中发生了异常,则事务整体会自动进行回滚。事务的隔离级别定义为@Transactional 注解中的属性@Transactional(isolation = Isolation.DEFAULT)
事务的传播
在使用事务时,如果一个事务方法调用另一个事务方法,那么不同事务之间的执行应该如何调度呢?这就是事务传播的作用,用来调度不同事务执行时的顺序和方式。在SpringBoot中,事务的隔离级别定义为@Transactional 注解中的属性@Transactional(propagation = Propagation.REQUIRED)(原文链接:https://blog.csdn.net/qq_40772692/article/details/121476144)
异常回滚
默认情况下,Spring会对unchecked异常进行事务回滚,也就是默认对 RuntimeException() 异常或是其子类进行事务回滚;如果是checked异常则不回滚,例如空指针异常、算数异常等会被回滚;文件读写、网络问题Spring就没法回滚。若想对所有异常(包括自定义异常)都起作用,注解上面需配置异常类型:@Transactional(rollbackFor = Exception.class)
redis的数据类型
orcale表空间和用户的关系
脏读:读到了错误的数据,解决:读已提交
不可重复度:修改(新增,更新,删除)某条数据两次查询结果不一样,解决:可重复读
幻读:新增和删除两次查询结果集不一样,解决:串行化
for update
有主键,行锁
无主键,表锁
使用场景:火车票订票,在屏幕上显示有票,而真正进行出票时,需要重新确定一下这个数据没有被其他客户端修改。所以,在这个确认过程中,可以使用for update。
springboot 核心注解
springbootapplication
linux 常用命令 如日志查询
1.查看实时变化的日志
tail -f filename.log 默认最后10行
tail -200f filename.log 最后200行
tail -n 20 filename.log 显示最后20行
tail -n +5 filename.log 从第5行开始显示
ctrl+c 退出tail
2.搜索关键字附近的日志
cat -n filename |grep ‘关键字’
cat filename.log | grep -C 5 ‘关键字’ 显示匹配关键字及前后5行
cat filename.log | grep -B 5 ‘关键字’ 显示匹配关键字及前5行
cat filename.log | grep -A 6 ‘关键字’ 显示匹配关键字及后5行
3.进入编辑查找
vi vim
进入vim编辑模式 vi filename.log
输入’/关键字’,按enter查找
查找下一个,按’n’查找上一处错误,按’N’查找下一处错误
ctrl+f 下一页
ctrl+b 上一页
ctrl+d 下半页
ctrl+u 上半页
ctrl+e 下一行
ctrl+y 上一行
ctrl+o 回到搜索位置
退出 按esc,输入:,输入wq!保存退出;输入q!不保存退出
4.查看所有关键字相关的日志
more filename.log | grep ‘关键字’
按space键,显示文本下一屏内容
按B键,显示上一屏内容
按H键,显示帮助屏,显示相关帮助信息
5.根据时间查看
cat xxx.log |sed -n ‘/2020-10-24 22:16:21/,/2020-10-24 22:16:59/p’ abc.log
update name set a = b
delete from name where a = b
insert into name (jian) values (zhi)
restful
以不同的URL(主要为使用动词)进行不同的操作。
GET http://localhost:8080/admin/user (查询用户)
POST http://localhost:8080/admin/user (新增用户)
PUT http://localhost:8080/admin/user (更新用户)
DELETE http://localhost:8080/admin/user (删除用户)
引导类加载器 核心类库
拓展类加载器 jir目录下
系统类加载器
自定义类加载器
springboot 启动的三种方式
1.启动类 main方法
2.java -jar 命令启动jar包
3.maven插件 spring-boot-plugin,打包时会忽略spring-boot-devtools
springboot热部署三种方式
1.IDEA 配置
2.maven插件 spring-boot-devtools:会引入新的依赖,并且 class 文件变更会引起应用重启
3.插件工具 JRebel:加载变动的 class 并利用 Spring 的 API 替换新的对象
事务的隔离级别
1.读未提交
2.读已提交
3.可重复读 mysql默认级别
4.串行化
SQL优化
1.避免使用select *
2.用union all代替union
3.小表驱动大表
4.批量操作
5.多用limit
6.in中值太多
7.增量查询
8.高效的分页
9.用连接查询代替子查询
10.join的表不宜过多
11.join时要注意
12.控制索引的数量
13.选择合理的字段类型
14.提升group by的效率
15.索引优化
死锁形成条件
1.互斥条件:一个资源只能被一个线程占有,当这个资源被占用后其他线程就只能等待。
2.不可剥夺条件:当一个线程不主动释放资源时,此资源一直被拥有线程占有。
3.请求并持有条件:线程已经拥有一个资源后仍然不满足,又尝试请求新的资源。
4.环路等待条件:产生死锁一定是发生了线程资源环路链。
char和varchar区别
1.定长和变长
2.存储容量不同
分库分表后id和主键怎么拆分
mybatis-plus优势
stream流
基本数字类型已经各自的长度?
byte:8位(1字节)。范围从-128到127。
short:16位(2字节)。范围从-32,768到32,767。
int:32位(4字节)。范围从-2,147,483,648到2,147,483,647。
long:64位(8字节)。范围从-9,223,372,036,854,775,808到9,223,372,036,854,775,807。
float:32位(4字节)。用于单精度浮点数。
double:64位(8字节)。用于双精度浮点数。
boolean:这个类型的大小不是固定的,因为它表示的逻辑值,通常是使用单个字节存储的,但具体的表示形式取决于JVM实现。
char:16位(2字节)。用于表示Unicode字符。
string类型非基本数据类型
try catch finally 方法执行顺序
异常类
ACID
zookeeper集群搭建最少需要几个服务器?
Zookeeper集群搭建最少需要3台服务器。这是因为Zookeeper集群的机制是,只要超过半数的节点正常,集群就能正常提供服务。比如,一个包含3个节点的集群,即使其中一个节点挂掉,集群仍然可以正常工作,因为剩下的2个节点超过了半数。但如果是一个包含2个节点的集群,任何一个节点挂掉都会导致集群失效,因为剩下的节点没有超过半数。
在mapper文件中,只有返回值不同,能否重载成功?
在 MyBatis 的 Mapper 文件中,方法名和参数列表共同构成了方法的唯一标识。因此,即使返回值类型不同,但方法名和参数列表相同的方法,在 Mapper 文件中是不能被重载的。
mybaits中的动态sql标签