2022-02-17 下午
1.SpringMVC常用注解
- @RequestParam:将请求参数绑定到你的控制器的方法参数上
- @RequestBody:如果作用在方法上,就表示该方法的返回结果是直接按写入的Http responsebody中
- @PathVaribale:用于绑定url中的占位符
- @RequsetMappring:用来处理请求地址映射的,也就是说将其中的所有处理器方法都映射到url路径上
2.Redis内存管理(其实就是问内存淘汰策略)
- noeviction:添加数据时,如果redis判断该操作会导致占用内存大小超过内存限制,就返回error,然后啥也不干
- allkeys-lru:添加数据时,如果redis判断该操作会导致占用内存大小超过内存限制,就会扫描所有的key,淘汰一些最近未使用的key
- volatile-lru:添加数据时,如果redis判断该操作会导致占用内存大小超过内存限制,扫描那些设置里过期时间的key,淘汰一些最近未使用的key
- allkeys-random:添加数据时,如果redis判断该操作会导致占用内存大小超过内存限制,就会扫描所有的key,随机淘汰一些key
- volatile-random:添加数据时,如果redis判断该操作会导致占用内存大小超过内存限制,扫描那些设置里过期时间的key,随机淘汰一些key
- volatile-ttl:添加数据时,如果redis判断该操作会导致占用内存大小超过内存限制,扫描那些设置里过期时间的key,淘汰一些即将过期的key
- volatile-lfu:添加数据时,如果redis判断该操作会导致占用内存大小超过内存限制,就会淘汰一些设置了过期时间的,并且最近最少使用的key
- allkeys-lfu:添加数据时,如果redis判断该操作会导致占用内存大小超过内存限制,就会扫描所有的key,淘汰一些最近最少使用的key
3.怎么快速高效地往数据库插入十万条数据
- 单条sql语句插入多条数据。例:insert into table ([列名],[列名]) VALUES ([列值],[列值]), ([列值],[列值]), ([列值],[列值]);
- MyBatis层面的foreach插入
- 线程池
- PreparedStatement。PreparedStatement会先将sql语句发送给数据库进行预编译
4.MySQL的like的%xxx%和x%xx的区别,为什么?
%xxx%:不会走索引
原因:
最左前缀匹配原则:在MySQL建立联合索引时会遵守最左前缀匹配原则,即最左优先,在检索数据时从联合索引的最左边开始匹配。
索引的底层是一颗B+树,那么联合索引的底层也就是一颗B+树,只不过联合索引的B+树节点中存储的是键值。由于构建一棵B+树只能根据一个值来确定索引关系,所以数据库依赖联合索引最左的字段来构建。
举例:创建一个(a,b)的联合索引,那么它的索引树就是下图的样子。
可以看到a的值是有顺序的,1,1,2,2,3,3,而b的值是没有顺序的1,2,1,4,1,2。但是我们又可发现a在等值的情况下,b值又是按顺序排列的,但是这种顺序是相对的。这是因为MySQL创建联合索引的规则是首先会对联合索引的最左边第一个字段排序,在第一个字段的排序基础上,然后在对第二个字段进行排序。所以b=2这种查询条件没有办法利用索引。
5.MySQL什么时候出现表锁和行锁
InnoDB存储引擎:
- select…for update、insert、update、delete…等操作都会触发锁,只要涉及到表的改动都会触发锁
- 表中有索引,并不代表触发的锁就是行锁
- 当where条件中含有至少一个字段添加了索引,才会触发行锁,否则就是表锁
- 当表中只有联合索引,而且是根据查询条件锁创建的索引(所涉及到的列一模一样),触发的将是表锁,而不是行锁。当查询结果过多,索引将会失效,触发全表扫描,此时也会触发表锁。
- 行锁并不一定就是只锁了一行,具体视情况而定
- 当where条件中携带表主键时,即使不走显示索引,触发的也是行锁,而不是表锁
- 执行插入语句insert into时,同样的,当插入的字段含有索引字段时,触发的是行锁,否则触发的是表锁
6.select、from、where、group by、order by、limit的执行顺序
- From:对from左边的表和右边的表计算笛卡尔积,产生虚拟表c1
- On:对c1中的数据进行on过滤,只有符合过滤条件的数据记录才会记录在虚拟表c2中
- Join:若指定了连接条件(left、right),主表中的未匹配的行就会作为外部行添加到c2中,生成虚拟表c3
- Where:对虚拟表c3中的数据进行条件过滤,符合过滤条件的记录插入到虚拟表c4中
- Group by:根据group by子句中的列,对c4中的记录进行分组操作,生成c5
- Having:对虚拟表c5中的记录进行having过滤,符合筛选条件的记录插入虚拟表c6中
- Select:执行select操作,选择指定的列,插入到虚拟表c7中
- Distinct:对c7中的数据去重,生成虚拟表c8
- Order by:对虚拟表c8中的数据按照指定的排序规则进行排序,生成虚拟表c9
- Limit:取出指定的记录,产生虚拟表c10,将结果返回
7.接口可以实现接口吗,接口可以继承接口吗
接口不可以实现接口,接口可以继承接口
因为接口中的方法是没有方法体的,所以不能实现任何接口。
其次,一个接口可以继承多个接口。因为类如果可以多继承,实例化时,如果要调用父类的方法,如果两个一样,根本就不知道该调用哪个父类的方法; 但是接口就不一样了,因为接口继承多个接口,就算多个接口有相同的方法,但是最终实现接口的类只能实现一个方法且@Override一个方法,所以调用时就不会有问题了。
8.Map的三种遍历方式
- keySet()方法获取到Set(key)
- values()方法获取到Collection(value)
- entrySet()方法获取到Set<Entry<key,value>>
9.数值型变量在内存的存放位置
(1) 基本数据类型的存储原理:所有的简单数据类型不存在“引用”的概念,基本数据类型都是直接存储在内存中的内存栈上的,数据本身的值就是存储在栈空间里面,Java语言里面八种数据类型是这种存储模型;
(2) 引用类型的存储原理:引用类型继承于Object类(也是引用类型)都是按照Java里面存储对象的内存模型来进行数据存储的,使用Java内存堆和内存栈来进行这种类型的数据存储,简单地讲,“引用”(存储对象在内存堆上的地址)是存储在有序的内存栈上的,而对象本身的值存储在内存堆上的;
基本数据类型和引用类型的区别主要在于基本数据类型是分配在栈上的,而引用类型是分配在堆上的
10.java的基本数据类型
基本数据类型:
- byte:Java中最小的数据类型,在内存中占1个字节(8 bit),取值范围-128~127,默认值0
- short:短整型,2个字节(16 bit),取值范围-32768~32717,默认值0
- int:整型,用于存储整数,在内存中占4个字节,取值范围-2147483648~2147483647,默认值0
- long:长整型,在内存中占8个字节-263~263-1,默认值0L
- float:浮点型,在内存中占4个字节,用于存储带小数点的数字(与double的区别在于float类型有效小数点只有6~7位),默认值0
- double:双精度浮点型,用于存储带有小数点的数字,在内存中占8个字节,默认值0
- char:字符型,用于存储单个字符,内存中占2个字节,取值范围0~65535,默认值为空
- boolean:布尔类型,占1个字节,用于判断真或假(仅有两个值,即true、false),默认值false
引用类型:
- 类(Class):所有的类,无论是Java自身已经存在的,还是用户后来创建的
- 接口(interface): 系统自带或者用户创建的
- 数组(array): 系统自带或者用户创建的
11.for的普通循坏和foreach循坏有什么区别
普通for循环语法:
for (int i = 0; i < integers.length; i++) {
System.out.println(intergers[i]);
}
foreach 循环语法:
for(Integer in : integers){
System.out.println(in);
}
- foreach适用于数组或实现了iterator的集合类。foreach就是使用Iterator接口来实现对集合的遍历的。
- 在用foreach循环遍历一个集合时,不能改变集合中的元素,如增加元素、修改元素。否则会抛出ConcurrentModificationException异常。
2022-02-19 上午
1.dubbo和springcloud的区别
2.数据库引擎
3.索引原理(问b+树),失效场景,最左原则
4.sql优化
5.数据库事务,默认隔离级别
6.行锁表锁
7.bean生命周期
8.spring事务
9.分布式事务和分布式锁
10.redis的数据类型,io多路复用机制,内存模型
11.atomic类的原子操作
12.锁升级过程
13.syn锁和lock锁的原理和区别
14.es业务场景