手把手教你锤面试官 04——假装精通 redis
本文是手把手教你锤面试官系列第四篇文章,该系列主要为大家分析和讲解在面试过程中,遇到面试官经常提出的面试问题如何进行攻防。另外本系列的文章也会提供许多小技巧给大家去间接试探出面试官的技术能力和专业水平,从而达到碾压面试官的目的。本系列文章只适用于JAVA工程师。
由于redis是目前企业级JAVA开发中最流行的KEY-VALUE内存数据库,所以基本上所有的面试都会提到它,虽然很多人可能在实际项目中压根就没用过redis。为了让没有redis使用经验的面试者在面试的时候不会因为redis被面试官锤,本文特地总结了redis的常见面试问题以及加分项回答,可以让你瞬间拥有精通redis数据库的假象。
0.redis的默认端口是什么?怎么修改?
1.Redis支持的数据类型有哪些?
2.redis的持久化方式有哪两种?有什么不同?
3.怎么在redis里面存储一个对象?
4.redis支持事务吗?
5.简单描述一下redis是怎么做集群的。
6.redis有哪些使用场景?
0.0回答
6379,因为该端口很容易被网络工具扫描出来,建议修改默认端口。打开redis.conf文件,找到port 6379改成你要的端口即可。
1.1回答
常用的有五种:字符串String、字典Hash、列表List、集合Set、有序集合SortedSet。
对应的常用命令如下:
String:set.get,decr,incr
Hash:hget,hset,hgetall
List: lpush,rpush,lpop,rpop,lrange
Set:sadd,spop,smembers,sunion
SortedSet: zadd,zrange,zrem,zcard
2.2回答
AOF RDB两种备份策略(既持久化,redis的数据是放在内存里面的,为了保障关机后数据还有会把数据或者数据操作命令持久化到硬盘上)
RDB是指定一个时间备份一次,备份的是数据.rdb数据文件,开销小,可靠性低
AOF是时时刻刻把操作命令备份到aof日志文件中,开销大,可靠性高
33.回答
先把对象序列化(如转成json),存入redis中。虽然redis号称支持5种低级,3种高级数据类型,但本质上来说,redis只支持字符串读写。取出来之后再反序列化成JAVA对象使用。
4.4回答
redis每一个操作就是一个事务,且放在一个线程里面(单线程天然具有原子性),所以redis可以说有事务一致性。但redis本身不具备关系数据库的事务功能和隔离机制,所以也可以说redis不支持事务。
5.5回答
哨兵模式不讲了,基本已经被淘汰了。主要讲一下cluster模式,也就是所谓的最低要求3主3从集群模式。如下图所示,三个主节点负责选举和数据槽分发,每个主节点和对应的从节点进行同步复制。当有一个主节点挂掉的时候,从节点会自动上升为主节点。当有一组主从节点挂掉的时候,该集群失效。注意:该模式下主节点与主节点之间并不同步数据。为保证主节点的选举机制一直生效,可以在每个主节点下挂多几个从节点。
作该集群的步骤很简单:
1.启动各个节点redis
2.使用redis-trib.rb(命令)工具进行集群即可
6.6回答
redis的使用场景很多,可以列举一些我在曾经的项目中用到的一些方式
1)存放字典、常量等不轻易修改但是经常访问的数据,如select的value和text下拉值,登录后当前用户可访问的url资源,币种、国籍代码等等
2)高频操作的数据,如车管所等政府机关单位的取号、排队、预约数据。这种数据的特点是,工作时间会有大量的高频读写访问,对数据库查询压力极大。但办公时间过后,基本没人访问(如户籍办、车管所、税务局等)。可以将数据库中的表在开业前放入redis中,业务系统对redis中的数据进行读写操作。等到休息时间或者日终时候,再将该数据通过pipe同步持久化到数据库表中。
3)ORM框架的二级缓存,如mybatis的二级缓存。redis和mybatis可以完美的结合,使用redis充当mybatis的二级缓存。可以将数据库的压力转移到redis数据库中,这种方案在秒杀、商城、营销、小游戏等系统中使用较多。但要注意,针对这种操作,分布式系统,或者多个系统使用一个库中的表可能会出现数据不一致的情况。另外redis中的数据失效问题也要注意,不要把表中的数据失效时间设置成同一个时间点,或者根据snowflake算法进行优化,避免过多缓存同一时间失效。
4)充当MQ,redis完全可以替代MQ实现MQ的异步队列、消息发布功能实现销峰填谷。如广告订阅、短信发送、消息推送等功能。
5)作为注册中心使用,比较冷门的功能还有可以替换zookeeper、eureka这一类分布式的注册中心,也曾在一些项目中有见过。除了配套代码要写多点以外,维护性差一点以外,性能和功能上都可以满足zk和eureka的需要。利用redis你也可以很简单的写一套自己的微服务框架(相关技术推荐:jersey2.0<接口暴露>+redis4.0<注册中心>+httpclient<服务通信>+fastJson<序列化反序列化>)
6)利用redis实现分布式锁,分布式事务控制。也就是用redis实现TCC分布式事务或者LCN分布式事务。对于2PC分布式事务的支持,redis并不佳,不建议使用。推荐一个比较好用的国产开源分布式事务框架——TX-LCN,就是基于redis来进行分布式事务控制的。
7)session共享,我们使用Nginx进行集群的时候,如果系统使用RBAC框架(如springsecurity shrio等),在不对Nginx进行优化配置的情况下,由于Nginx的请求随机派发会出现session丢失的情况,极端情况下会出现让用户重复登录多次的情况。这个时候可以通过redis将业务系统的session缓存起来,进行session共享。相关技术可以看看spring-session组件整合redis的教程。
有更多的redis奇妙使用场景欢迎各位留言补充哦~
最后,想要检验一个面试官redis的水平高低,有一个很简单的问题可以暴露。所谓知己知彼,百战不殆。你可以这样说,redis是一个内存数据库,NOSQL,由于它的核心采用了多线程的读写模式,所以它操作内存中的数据相当快。如果面试官对你的阐述没有疑义,还点头同意,基本可以确定他对redis的认知也是相当粗浅的,上面的回答足够锤死他了。
首先,redis快的一个主要原因是它采用了单线程,避免了不必要的上下文切换和竞争条件。
redis只在网络通讯的IO处理(如协议解析)上面采用了多线程,其对内存的操作是单线程的。所以redis对于CPU的要求不高,对内存的要求极高。
其次,redis访问内存读写采用了IO多路复用机制(即epoll和select-pooll机制),该机制的本质仍是单线程自行的。该机制不展开讨论,读书的时候操作系统原理上面学过,我也忘得差不多了。大概就是你想要打印100份文件,你不用自己打印,直接把这100份文件丢给打印机去处理,然后你去处理别的事情。打印机打印完了给你一个结果即可,到点你去取打印文件即可(可能有点记错了,欢迎校正)。
评论