文章目录
- 1. mybatis中 # 和 $ 的区别,sql注入问题
- 2. MySQL的blob 类型的使用
- 3. delete truncate 的区别
- 4. sql语句:将两个订单中的信息统计到一个表中
- 5. JDBC 的流程
- 6. redis 内存回收策略
- 7. redis 过期键的处理方式
- 8. redis 主从复制
- 9. redis 持久化
- 10. redis 底层数据结构
- 11. redis 的单线程为什么快?
- 12. Thread.start(),run() 的区别,sleep()和wait()的区别
- 13. Collection 和 Map 架构的区别
- 14. HashMap 的 put() 和 get() 方法底层实现
1. mybatis中 # 和 $ 的区别,sql注入问题
#{}
:是预编译处理的,mybatis在处理的时候会将sql中的 #{} 替换为==?==,然后调用PreparedStatement的set方法来赋值,传入字符串后,会在值两侧加上单引号,可防止大部分的SQL注入。${}
:是字符串替换,Mybatis在处理的时候 会直接将 **${}**替换为变量的值,会导致sql注入,不利于系统的安全性。- sql注入:就是通过SQL命令插入到Web表单提交或页面请求的查询字符串,最终达到欺骗服务器执行恶意SQL命令。常见的有匿名登录(在登录框输入恶意字符串)
- 能用
#{}
就不要使用${}
,Mybatis排序时使用order by动态参数的时候需要使用${}
2. MySQL的blob 类型的使用
- 二进制大型对象,是一个可以储存大量数据的容器,
类型 | 最大容量 |
---|---|
TinyBlob | 255B |
Blob | 65K |
MediumBlob | 16M |
LongBlob | 4G |
- 实际使用中根据需要存入的数据大小定义不同的BLOB类型,如果存储的文件过大,数据库的性能会下降很多。
3. delete truncate 的区别
- delete:删除部分数据记录
- truncate:清空表数据记录
- drop:清除表结构和表数据记录
4. sql语句:将两个订单中的信息统计到一个表中
5. JDBC 的流程
- 注册驱动: **Class.forName(“com.mysql.jdbc.Driver”)*,【只做一次】
- getConnection()获取连接
- 创建运行对象,PrepareStatement能够预编译SQL语句,并且预编译结果可以储存在PrepareStatement对象中,多次运行SQL语句可以提高效率
- 执行SQL语句,得到结果集ResultSet
- 处理结果集ResultSet,
- 释放有关资源,关闭此次数据库有关连接。
6. redis 内存回收策略
-
过期策略:删除过期时间的key值。(三种过期策略)【看第七点】
-
淘汰策略:内存使用到达maxmemory上限时触发内存淘汰数据
- 简介:当内存使用情况达到maxmemory极限时,需要使用LAU淘汰算法来决定清理掉那些数据,以保证新数据的存入。
- Resis默认情况下使用的是LRU(Least RecentlyUsed),最近最少使用算法,也就是默认删除最近最少使用的键。但是并不会准确删除所有键中最近最少使用的键,而是从中随机删除 3 个键,(这个 3 是可以通过maxmeory-samples设置的,如果设置为10,效果会更好,但也会耗费更多的CPU资源)
7. redis 过期键的处理方式
-
过期策略:删除过期时间的key值。(三种过期策略)
- 定时过期:每个设置过期时间的key都需要创建一个定时器,达到过期时间就会立即清除。该策略可以立即清除过期的数据,对内存很友好。但是会占用大量CPU资源去处理过期的数据,从而影响缓存的响应时间和吞吐量。
- 惰性过期:只有当访问一个key时,才会判断该key是否已经过期,过期则清除。该策略可以最大化的节省CPU资源,却对内存非常不友好。极端情况下可能出现大量的过期key没有再次访问,从而不会被清除,占用大量内存。
- 定期过期:每隔一段时间,会扫描一定数量的数据库的key,并清除其中已过期的key。该策略是前两种的一折中策略。通过调整定时扫描的时间间隔和每次扫描的限定耗时,可以在不同情况下使得CPU和内存资源达到最优的平衡效果。
- 总结:Redis同时使用了惰性过期和定期过期两种策略
8. redis 主从复制
- 为什么要主从复制?当主Redis服务器硬盘损坏了可能会导致数据丢失,但是使用redis的主从复制机制就可以避免这种单点故障。
- 一般主redis只有一台,从redis有多台。主redis中的数据和从redis上的数据保持同步的,当主redis写入数据时会通过主从复制 机制 复制到其他从服务器上。(一个redis可以同时是主也是从)
9. redis 持久化
- aof,rdb。
10. redis 底层数据结构
11. redis 的单线程为什么快?
- 完全基于内存,绝大部分请求时纯粹的内存操作。非常快速。数据存在内存之中,类似于HashMap,HashMap的优势就是查找和操作的复杂度都是O(1);
- 数据结构简单,对数据操作也简单,Redis中的数据结构是专门进行设计的
- 采用单线程,避免了不必要的上下文切换和竞争条件,也不存在多线程切换而消耗CPU,不用去考虑各种锁的问题,不存在加锁释放锁的操作,没有因为死锁可能出现而导致性能的消耗
- 使用多路I/O复用模型,非阻塞IO;
- 使用底层模型不同,他们之间底层实现方式以及客户端之间通信的引用协议不一样,Redis直接构建了自己的 VM 机制,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求。
- 那么为什么Redis是单线程?
- 官方表示:因为Redis是基于内存的操作,CPU不是Redis的瓶颈,Redis的瓶颈最有可能是机器内存的大小或者网络宽带。既然单线程容易实现,而且CPU不会成为瓶颈,那就顺理成章的采用了单线程的方案了(毕竟采用多线程会有很多麻烦!)
12. Thread.start(),run() 的区别,sleep()和wait()的区别
- start():启动线程的方法
- run():线程的实现可以通过继承Thread或者实现Runabble,但是都得重写run()方法,run()方法是线程执行的实体
- sleep():属于Thread()方法,可以在任何地方使用,不会释放锁,在指定时间结束后cpu会再次回到该线程继续执行下去。
- wait():属于Object方法,只能在同步方法或者同步方法块中使用,会释放锁,只有在调用了notify()方法,才会解除该线程的wait状态,重新获得去竞争同步资源的资格,得到资源后,方可再次执行。