目录
- Redis
- mybatis
-
-
- mapper.xml的namespace作用
- 怎样才能不写实体类的全路径名
- mapperJava接口中的方法名、参数、返回值对应哪些属性
- #{值}取的是什么内容
- 为什么要用resultMap
- resultMap可以有哪些子标签,可以有哪些属性
- resultMap的下子标签的property和column属性有什么不同
- 标签id、result、association、collection可以有哪些属性
- 关联多表查询时需要用到association与collection,association与collection的区别
- 一对多和多对一查询有什么不同
- 一对多使用collection,collection里的对象一般是我们自定义对象,那一对多string时呢,resultmap怎么写,collection怎么写
- collection标签位置要注意什么
- insert的parameterType属性和parameterMap属性区别
- 逻辑分页和物理分页区别
- MySQL的limit使用分页
- 动态SQL之if使用
- where 标签是解决什么问题的,怎么用
- 什么时候直接使用where而不使用where标签
- update、set、if配合使用,set标签的好处
- foreach可以将任何可迭代的对象List、set、()、()
- foreach标签有哪些属性
- foreach遍历map
- foreach遍历list和array有什么不同,什么时候需要open和close
- mybatis在使用like时要加两个百分号吗
- where标签和set标签各解决了什么问题
- @Param怎么用
- userMapper.searchUser(map)时,select标签要有parameterType属性吗
- #与$$区别,你什么时候用到过美元符
- mybatis-plus只需要继承()接口,就能获取各种功能
- mybatis-plus
- 标签作用
- mybatis的insert后返回主键
- 一级缓存失效情况
- 二级缓存作用范围
- 二级缓存数据来源
- 什么时候用不到二级缓存
- 二级缓存使用
- 缓存回收策略有哪些:最近最少使用
- readonly属性为true或false代表什么
- 增删改为什么会清空一级缓存,会清空二级缓存吗
- 新会话SQLsession是先看一级缓存,还是二级缓存
- mybatis整合第三方缓存
- 整合ehcache时,配置的实现了cache接口的ehcacheCache是由mybatis实现的还是ehcache实现的
-
- MySQL
-
- SQL
-
- replace into 与 insert into 区别
- drop、truncate、delete三者删除的区别
- 学生表、课程表、成绩表,查询student表中重名的学生,结果包含id和name,按name升序
- 在student_course表中查询平均分不及格的学生,列出学生id和平均分
- 在student_course表中查询每门课成绩都不低于80的学生id
- 总成绩最高的学生,cid=1 成绩第三高的学生
- 在student_course表查询各科成绩最高的学生,结果列出学生id、课程id和对应的成绩
- 在student_course表中查询每门课的前2名,结果按课程id升序,同一课程按成绩降序 这个问题也就是取每组的前N条纪录
- 题目如下:年、季度、销售
- 创建高性能索引
- schema与数据类型优化
-
- 计数表与汇总表可以优化查询,但是()
- 整型与字符型,哪个代价更低
- 字符串存储时间类型好还是timestamp等内建数据类型存储时间类型好
- 什么时候应该避免列为空
- datetime 和 timestamp 精确到()
- timestamp 与 datetime优势比较
- int 与 bigint 占多少位,换算成多少字节
- int 有()属性,表示不允许(),可提升一倍上限
- 为什么浮点运算比decimal快
- 为什么说float精度丢失
- decimal开销比较大,可以用()代替
- 哪些情况使用varchar,哪些情况使用char
- 为什么列的更新少使用varchar较好
- timestamp只能表示到()年,datetime可以表示到()
- 如果要存储比秒更小粒度的时间怎么做
- 统计24小时内发送的消息数
- 当有多个事务并发更新计数器会串行执行,怎么解决效率问题
- mysql优化
Redis
什么是Redis
- key-value
- 数据库
- 缓存
- 中间件
redis和memcached对比
Redis支持持久化,memcached不支持
memcached所有值都是简单字符串,redis支持更多数据结构
衍生新数据结构
- BitMaps:位图
- HyperLogLog:超小内存唯一值计数
- GEO:地理位置信息经纬度
Redis应用场景
- 缓存
- 计数器
- 消息队列
- 排行榜
- 社交网络
- 实时
Redis可执行文件说明
- redis-server:启动Redis服务器
- Redis-cli:启动命令行客户端
- Redis-benchMark:性能测试
- Redis-check-aof:aof文件修复工具
- Redis-check-dump:rdb文件修复工具
- Redis-sentinel:
Redis三种启动方式
查看启动情况:
ps -ef | grep redis
netstat -antpl | grep redis
- 最简单启动:Redis-server,使用Redis默认配置
- 动态参数启动:Redis-server – port 1234,设置端口,默认是6379
- Redis-server configPath:配置文件启动,将配置写在configpath文件里,推荐使用
Redis客户端连接
Redis-cli -h 192.157.11.8 -p 6379
ping 返回:pong
set hello valueworld 返回:ok
get hello 返回:valueworld
Redis客户端返回值
状态回复
ping
返回:pong
错误回复
hget hello filed1
(error)wrongType operation against
整数回复
incr hello
(integer) 1
字符串回复
get hello
world
get hello foo
world
bar
Redis常用配置
redis.conf文件
./redis-server redis.conf
- daemonize:是否是守护进程,推荐使用yes
- port
- logfile:日志文件名
- dir:工作目录
通用命令
keys *
MSET key1 "Hello" key2 "World" haha "hehe"
keys ke*
返回:key1,key2
keys ha[g-i]* //第三个字母在g~i之间
返回:haha
keys key? //?代表一个位置长度
返回:key1,key2
dbsize // 计算key的总数
exist keyName
del key [key...]
expire key seconds
ttl key // 查看key还有多长时间过期,若为-1代表key存在且没有过期时间,-2代表已经不存在了
persist key //去掉key的过期时间
type key // 查看key的数据类型,可能是none、string、hash、list、set、zset
Redis为什么这么快
- 纯内存
- 非阻塞IO
- 单线程避免线程间切换
Jedis
<groupId> redis.clients
<artifactId> jedis
<scope> compile
Jedis jedis = new Jedis("127.0.0.1",6379)
jedis.set("hello","world")
jedis.hset("myhash","field1","value1")
jedis.rpush
...
jedis连接池
- 直连的话需要创建new,关闭jedis对象
- 连接池只需要归还jedis对象即可,减少开销
GenericObjectPoolConfig poolConfig = new ...
JedisPool jedisPool = new JedisPool(poolConfig, ip, port)
Jedis jedis = jedisPool.getResource()
jedis.close() //pool中的连接close是归还资源,而不是关闭连接
连接池配置
// 应用个数 * maxtotal 不能超过RedisServer的最大连接数
maxTotal:最大连接数,默认8,建议50个,实际可以偏大
maxIdle:允许最大空闲数,默认8,建议等于maxTotal
minIdle:默认为0,可以预热先让连接池有一些连接
jmxEnabled:开启jmx监控,建议开启,默认为true
blockWhenExhausted:资源池用尽之后,调用者是否等待,默认true
maxWaitMillis:最大等待时间,-1表示永不超时,不建议使用-1
testOnBorrow/return:借还连接时,是否做有效性检测ping/pong,默认false,建议false
timeout waiting for idle object解决思路
1.池子连接都被hang住,例如所有连接都执行keys *
2.QPS高,池子太小
geo
// geoadd key longitude latitude member
geoadd cities:locations 116.7 78.9 beijin
BitMap
字符串big对应的二进制
01010101 101010100 01010100
set hello big
getbit hello 23 //24位,最后一位是0
setbit key offset value // value只能是0和1,offset是偏移量
- 记录活跃用户
userId最好为自增类型的,数值不要超过4294967295 即(2^32)-1
01000101001001 // 0代表今天没登录,1代表登录了
当活跃用户占总用户数很少的时候,例如:1亿用户只有一个活跃用户,这个时候还不如使用set直接保存活跃用户id即可
发布订阅
新加入的订阅者不能收到之前发布的消息,订阅状态,处于此状态下客户端不能使用除subscribe、unsubscribe、psubscribe和punsubscribe这四个属于"发布/订阅"之外的命令,否则会报错
// publish channel message
publish souhu:tv "hello world"
返回:3,订阅者个数
// subcribe [channel] 一个或多个频道
subscribe souhu:tv
// unsubscribe [channel] 取消一个或多个频道
- 模拟消息队列,抢消息,只有一个订阅者能收到消息
由于Redis会将消息发送给所有订阅者,比较棘手
可以使用列表的阻塞拉取
pipeline
mget、mset类似于一次发生多条get、set命令,节省网络开销
而hmset、hmget这样的命令是没有的,这个时候可以考虑pipeline
Jedis jedis = new ...
PipeLine pipeline = jedis.pipelined()
pipelined.hset...
...
pipeline.syncAndReturnAll()
- 与原生m操作比较
原生m操作都是原子的,不会被插队
pipeline子命令可能会被其他命令插入到之间,但是返回结果是顺序的
集群中,pipeline每次只能作用到一个Redis节点
慢查询
命令执行生命周期
1.client发送命令
2.命令排队
3.执行命令
4.返回结果
- 慢查询发生在第三阶段,命令执行,例如keys *
当一条命令被定义为慢查询时,会进入到一个队列,先进先出固定长度的队列,队列保存在内存中,不会持久化
// 若想记录所有命令,设置为0,通常不会这么做,<0不记录任何命令
slowlog-log-slower-than=10000,单位是微秒
slowlog-max-len=128
// 配置方法
1.修改配置文件重启,不建议
2.动态配置
config set slowlog-max-len 1000 // 建议设置为1000
config set slowlog-log-slower-than 1000 // 单位是微妙,默认值是10000,建议1毫秒即1000
config rewrite
// 获取慢查询队列,n是多少个命令
slowlog get [n]
// 获取慢查询队列长度
slowlog leng
// 清空
slowlog reset
- 定期持久化慢查询
zset(key->score,element)
- 有序集合无重复元素是score还是value,还是value+score
score可以重复,element不能重复
zadd key score1 element1 score2 element2...
zrem key element1...
zscore key element
zincrby key increScore element
zcard key
zrank key element // 获得元素排名
// zrange key start end [withscores]
zrange key