为什么要使用redis:
来自与https://www.cnblogs.com/bigben0123/p/9115597.html
性能:因为redis将数据存储在缓存中,可以迅速响应
并发:在分布式系统中,会有大量的请求并发进行,如果同时访问数据库,会造成很大的压力,甚至于搞挂数据库,可以先用redis做下缓冲操作
1.redis面试题:1.什么是redis?答:redis是基于内存的一个key-value数据库。2.redis的特点?答:高性能,支持保存多种数据结构,高性能,持久化。受到物理内存限制,不能存储海量数据。可用于缓存,消息,按key设置过期时间,过期后将会自动删除,支持事务,操作都是原子性,所谓的原子性就是对数据的更改要么全部执行,要么全部不执行3.数据类型?答:string,list,hash,set,sort set(zset)。3.为什么redis将数据存储到内存中?答:redis为了最快的读写速度将数据都读到内存中,并且异步的写入磁盘中。4.redis是单进程单线程的。答:redis利用队列技术将访问变成串行。5.redis集群?答:redis支持主从模式,原则master会将数据同步到slave,slave启动时会从master同步数据。6.redis的回收策略?答:volatile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰。no-enviction(驱逐):禁止驱逐数据7.面试资料整理-redis篇1.redis面试题:1.什么是redis?答:redis是基于内存的一个key-value数据库。2.redis的特点?答:高性能,支持保存多种数据结构,高性能,持久化。受到物理内存限制,不能存储海量数据。可用于缓存,消息,按key设置过期时间,过期后将会自动删除,支持事务,操作都是原子性,所谓的原子性就是对数据的更改要么全部执行,要么全部不执行3.数据类型?答:string,list,hash,set,sort set(zset)。3.为什么redis将数据存储到内存中?答:redis为了最快的读写速度将数据都读到内存中,并且异步的写入磁盘中。4.redis是单进程单线程的。答:redis利用队列技术将访问变成串行。5.redis集群?答:redis支持主从模式,原则master会将数据同步到slave,slave启动时会从master同步数据。6.redis的回收策略?答:volatile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰。no-enviction(驱逐):禁止驱逐数据7.redis事物的了解CAS(check-and-set 操作实现乐观锁 )答: 1.事物中所有的命令都会串行执行,执行期间不会再为其他客户端的请求提供任何服务,保证原子性。2.某一条命令失败了,后面的命令继续执行。8.redis的持久化?答: 1.快照,可以在配置文件中设置,保存的方式,每过多久多少次触发进行保存一次。保存到磁盘上只保存为数据库文件。2.AOF,会记录所有打印的日志,通过日志进行恢复。9.适合redis使用的场景?答: 1.会话缓存。2.页面缓存。3.实现队列,因为list和set的数据结构4.排行榜,计数器,sorted set 就是为了积分排行榜而生的。5.发布/订阅,10.redis的分布式锁?答: 1.可靠性,互斥性,任意时刻只能有一个客户端持有锁;不会死锁;具有容错性;加锁和解锁是同一客户端。2.实现:public class RedisLock {@Autowiredprivate StringRedisTemplate stringRedisTemplate;/*** 加锁* @param key productId - 商品的唯一标志* @param value 当前时间+超时时间 也就是时间戳* @return*/public boolean lock(String key,String value){if(stringRedisTemplate.opsForValue().setIfAbsent(key,value)){//对应setnx命令//可以成功设置,也就是key不存在return true;}//判断锁超时 - 防止原来的操作异常,没有运行解锁操作 防止死锁String currentValue = stringRedisTemplate.opsForValue().get(key);//如果锁过期if(!StringUtils.isEmpty(currentValue) && Long.parseLong(currentValue) < System.currentTimeMillis()){//currentValue不为空且小于当前时间//获取上一个锁的时间valueString oldValue =stringRedisTemplate.opsForValue().getAndSet(key,value);//对应getset,如果key存在//假设两个线程同时进来这里,因为key被占用了,而且锁过期了。获取的值currentValue=A(get取的旧的值肯定是一样的),两个线程的value都是B,key都是K.锁时间已经过期了。//而这里面的getAndSet一次只会一个执行,也就是一个执行之后,上一个的value已经变成了B。只有一个线程获取的上一个值会是A,另一个线程拿到的值是B。if(!StringUtils.isEmpty(oldValue) && oldValue.equals(currentValue) ){//oldValue不为空且oldValue等于currentValue,也就是校验是不是上个对应的商品时间戳,也是防止并发return true;}}return false;}/*** 解锁* @param key* @param value*/public void unlock(String key,String value){try {String currentValue = stringRedisTemplate.opsForValue().get(key);if(!StringUtils.isEmpty(currentValue) && currentValue.equals(value) ){stringRedisTemplate.opsForValue().getOperations().delete(key);//删除key}} catch (Exception e) {log.error("[Redis分布式锁] 解锁出现异常了,{}",e);}}}11.实现积分榜。直接定义redisTemplate对象,将zset放入,定义积分输出即可。redisTemplate.opsForValue();//操作字符串redisTemplate.opsForHash();//操作hashredisTemplate.opsForList();//操作listredisTemplate.opsForSet();//操作setredisTemplate.opsForZSet();//操作有序set。12.RedisTemplate中定义了对5种数据结构操作redisTemplate.opsForValue();//操作字符串redisTemplate.opsForHash();//操作hashredisTemplate.opsForList();//操作listredisTemplate.opsForSet();//操作setredisTemplate.opsForZSet();//操作有序setStringRedisTemplate默认采用的是String的序列化策略,保存的key和value都是采用此策略序列化保存的
转载于:https://www.cnblogs.com/josephusmao/p/9327759.html
相关资源:redis-面经-面试常见题汇总.docx