项目经验俺也没有啊。

问题来源:java线上模拟面试(我问你答版)二面-中间件和项目_哔哩哔哩_bilibili

你好小李同学,我是这次二面的面试官,研发部门的主管,上次你面试的Java基础结果还不错,所以说来到这次二面我们一些中间件和项目的问题,

我看他简历当中写着你使用过这个redis是吧?众所周知,Redis是一个单线程架构的NoSQL数据库

那么它redis它是一个单线程的模式,这是它的特点,它到底是好处还是坏处?

Redis单线程的优劣势

1)单进程单线程优势

代码更清晰,处理逻辑更简单

指的是执行命令时的单线程(一条命令从从客户端达到服务端不会立刻被执行,而是会进入一个队列中等待,每次只会有一条指令被选中执行)

避免了线程切换,不用考虑锁,)

都知道Redis是基于内存的操作,所以不会受CPU性能影响,反而是需要内存条。。。

2)单进程单线程弊端

无法发挥多核CPU性能,不过可以通过在单机开多个Redis实例来完善。

(通常来讲,单线程处理能力要比多线程差,但是redis基于内存(发挥不了多核CPU性能,但是也够快,而且多线程之间切换也是要花费时间的),省去了磁盘IO的时间,内存的响应时长大约为100纳秒,这是Redis达到每秒万级别访问的最重要的基础。)

(对于需要磁盘I/O的程序来讲,磁盘I/O是一个比较耗时的操作,所以对于需要进行磁盘I/O的程序,我们可以使用多线程,在某个线程进行I/O时,CPU切换到当前程序的其他线程执行,以此减少CPU的等待时间。

那么,为什么不在等待数据从内存读入CPU期间执行其他线程,以此提高CPU的使用率呢?

内存的读些速度虽然比CPU慢很多,但是也是非常快的。CPU切换线程需要花费一定的时间,而多次切换线程所花费的时间,可能比直接使用单线程执行相同的任务,花费的时间要更多。)

不过, Redis 4.0 之后开始变成多线程,除了主线程外,它也有后台线程在处理一些较为缓慢的操作,例如清理脏数据、无用连接的释放、大 Key 的删除等等。

Redis到底是多线程还是单线程? - 知乎

因为毕竟单线程会造成所谓的阻塞问题,你怎么看待?

I/O多路复用技术来解决I/O的问题

什么是I/O多路复用:

假设你是一个老师,让30个学生解答一道题目,然后检查学生做的是否正确,你有下面几个选择:

  1. 第一种选择:按顺序逐个检查,先检查A,然后是B,之后是C、D。。。这中间如果有一个学生卡主,全班都会被耽误。这种模式就好比,你用循环挨个处理socket,根本不具有并发能力。

  2. 第二种选择:你创建30个分身,每个分身检查一个学生的答案是否正确。 这种类似于为每一个用户创建一个进程或者线程处理连接。

  3. 第三种选择,你站在讲台上等,谁解答完谁举手。这时C、D举手,表示他们解答问题完毕,你下去依次检查C、D的答案,然后继续回到讲台上等。此时E、A又举手,然后去处理E和A。

第一种就是阻塞IO模型,第三种就是I/O复用模型,

好,那么一个redis实例,它至始至终它就起着一个线程吗?

首先还是明确概念,redis的单线程,指的是它的处理模块始终是单线程,(多个请求进来不会立马被执行,而是进等待队列,每次只有一个被处理),其他的模块可以是多线程。

对,它持久化的时候会fork()出来一个线程进行持久化,那么说到持久化,你知道redis当中它有几种持久化的策略? 他们分别是干什么?aof、rdb好,非常好,

rdb(redis database),就是利用copyonwrite,把整个redis数据库转储保存成一个 dump.rdb的二进制文件;

优点:

恢复大数据集时的速度比 AOF 的恢复速度要快

缺点:

RDB需要保存整个数据集的状态,如果面对大数据集,可能保存间隔设置较长,丢失的数据比较多,

而且由于它是fork()出一个子线程利用写时复制来转储数据,面对大数据集,CPU压力大时,会卡顿。

aof(append only file),就是将对redis数据修改添加的操作语句记录到日志中,恢复数据就是在执行这些语句一遍。

优点:

因为记录日志设置时间间隔很短的,一般都是每秒/次,丢失数据较RDB少。

缺点:

就是对于相同的数据集来说,AOF 文件的体积通常要大于 RDB 文件的体积;

可能会受到log语句的影响,再执行时会出BUG,无法恢复数据。

那么比如说在生产环境当中,我们知道服务器它有两颗CPU,一般来说是64和128线程, right,它既然是单线程的,那么我们应该如何最大化的压榨一下服务器的性能呢?这个没有考虑过。

好,那么redis当中它最新版本六点几版本也引入了多线程了,你有了解过相关的机制吗?好,没有了解算了,

支持多线程的 Redis 6.0 版本于 2020-05-02 终于发布了:

1.虽然支持,默认不开启 2.配置线程数要小于CPU数 3.虽然开了多线程,但其实还是单线程处理逻辑,不用担心线程安全问题 4.多线程主要解决I/O读写瓶颈问题,针对业务量达到亿级的应用,常规项目没有必要使用

注意:如果开启多线程,至少要 4 核的机器,且 Redis 实例已经占用相当大的 CPU 耗时的时候才建议采用,否则使用多线程没有意义。所以估计 80% 的公司开发人员看看就好。

那么redis当中它的 value的值它是不是有常见有5种类型,分别是什么呢?八股背得不错,

String,List,Set,Zset,HashMap

那么我就想问你这5种类型分别应该能应用在哪些场景当中?比方说list用在哪些场景?是不是队列?好,那么map Set你说一下。

String使用场景:常规key-value缓存应用。常规计数: 微博数, 粉丝数。

list使用场景:比如可以通过 list 存储一些列表型的数据结构,类似粉丝列表、文章的评论列表之类的东西。比如可以通过 lrange 命令,读取某个闭区间内的元素,可以基于 list 实现分页查询,这个是很棒的一个功能,基于 redis 实现简单的高性能分页,可以做类似微博那种下拉不断分页的东西,性能高,就一页一页走。

# 0开始位置,-1结束位置,结束位置为-1时,表示列表的最后一个位置,即查看所有。
lrange mylist 0 -1

set 是无序集合,自动去重。

可以基于 set 玩儿交集、并集、差集的操作,比如交集吧,可以把两个人的粉丝列表整一个交集,看看俩人的共同好友。

# 求两set的交集
sinter yourSet mySet
​
# 求两set的并集
sunion yourSet mySet
​
# 求在yourSet中而不在mySet中的元素
sdiff yourSet mySet

zset 排序的 set,去重但可以排序,写进去的时候给一个分数,自动根据分数排序。热搜榜,排行榜之类的会用到。

redis 都有哪些数据类型?分别在哪些场景下使用比较合适?_change的博客-CSDN博客_redis有哪些数据类型,用在什么场景

Redis系列(二)Redis的8种数据类型 - itzhouq - 博客园

好,那么常见是5种类型,不常见的有哪些类型是不知道还是没用过?hyperLog,你听说过没有?好没事不知道也无所谓。

(HyperLogLong[基数:数学上集合的元素个数,是不能重复的], 统计网页访问量,靠IP地址去重。

geospatial[该功能可以推算出地理位置信息,两地之间的距离],

bitmap 位图,通过最小的单位bit来进行0或者1的设置,表示某个元素对应的值或者状态)

那么redis既然它是一个缓存是吧?我们就往大了想缓存当中,你知道所谓的什么缓存穿透缓存雪崩和缓存击穿还有缓存预热,分别是在干什么?

我们应该如何解决这些问题?

缓存穿透:用户不断访问缓存和数据库都不存在的数据,导致数据库压力过大。比如id=-1。

解决方案:将key-value对写为key-null,缓存有效时间可以设置短点,如30秒;

接口层增加校验,如用户鉴权校验,id做基础校验,id<=0的直接拦截;

缓存雪崩:大批量缓存数据同时到期,请求全部落到数据库,造成压力过大。

解决方案:设置热点数据,永不过期;或者给ttl设置随机数,避免同时大批量到期。

缓存击穿:某个数据到期,大量针对其的请求落到数据库,造成压力过大。

解决方法:设置热点数据;加互斥锁(多线程请求此数据,第一个线程拿到锁,去DB取数据更新缓存,其他线程自旋等待,缓存更新完数据,锁被释放,大家正常取缓存中的数据)

缓存预热:上线之前,先把redis数据准备好。

缓存降级:丢卒保车,访问量剧增或者某些非核心服务影响到核心服务时,必须保证服务可用,就会降级。最终目的是保证核心服务可用,即使是有损的。而且有些服务是无法降级的(如加入购物车、结算)

好 redis比方说我想让你来部署一个集群的话,你知道它有几种集群部署模式。

主从模式,主从复制。读写分离,通过 SLAVEOF 命令或者配置的方式,让一个服务器去复制另一个服务器即成为它的从服务器。

哨兵模式,基于主从,节点之外还有一个Sentinel系统去监视主服务器及其所属的所有从服务器。高可用,读写分离。目的是在主节点挂掉后,自动选举出新的主节点。靠心跳检测判断节点存活与否。

集群模式cluster:多个主从组成。不再受主节点限制性能。了解不多。

好,我比如说我现在就设计一个场景,比方说让你就设计这么一套系统,怎么说?使用哨兵模式,我们部署5个redis实例,每个实例是一主三从,你会怎么设计?我不到啊

很好,我再让你设计一下,比方说你现在就是张小龙, 你设计一下微信朋友圈的功能,

比方说你设计这么一个朋友圈,你可以发布一个朋友圈,比方说我拿到了我们公司的 Offer了,好你发了这个帖子了相当于是吧? 那么这里边涉及到了什么

点赞,

共同好友

是不是能看到点赞,然后

原公司的员工你要让他看不见,然后包括

拉黑了的人你也看不见,

怎么实现是吧? 还有近半年可见

你又应该如何实现。

我们用redis设计一套?想一想。

首先,“我”发布的内容,肯定使用String来实现。以 userid + 当前时间戳 为key的string 数据结构,value 为具体内容

然后,用一个list来保存所有“我”发布的内容,以 userid + "self" 为key,value 就是contentid,LPUSH可以实现新增记录

像是点赞数,这样的也用String来实现。

还有共同好友,就是典型的交集,就用set类型,里面有sunion指令获得两个set的交集。

指定一些人看不到,也是set,sismember指令判断是否为拉黑的人这样。大概就是这样。

好,那我还看到你这里边简历当中写着你用mq,好,

你知道哪种mq,市面上,那么你用过几种?

市面上常用的,目前有 activemq,rabbitmq,rocketmq,kalfa。

好,你说你用过rabbitmq和rocketmq那么你说说它们的异同,然后再说一说如何保证这个消息的可靠性投递的。

好,你也说到了 Rocktmq有本身就有延迟消息是吧? rabbitmq没有。 好,那么 rabbitmq没有延迟消息,我让你设计一下,你怎么能用rabbit给我设计出一套延迟消息来的?

Ok好,然后我看见你上一家公司实习的时候是在一个电商公司是吧?做过电商平台,这个是真的假的? 做过你就介绍一下这家电商公司当中它是在做什么,然后你负责了哪些模块呢? 比方说我问你你们电商平台当中优惠券功能是如何实现的? 比方说满100-5毛钱,然后跨店满300减99块钱怎么实现? 然后继续如果用户跨店满300减了9块,9块减了99块9了,那么如果他是退货,他只退某一家店的一件商品的话,那么这个优惠券你应该如何给他退回去?

好,然后你在电商平台当中,我看你还写了,你还接触过支付,行, 你说一下你电商平台如何和微信支付宝这些平台对接的, 然后整体的支付流程图你可以在咱们这儿画一下很好, 比方说支付肯定会出现各种各样的问题,比方说用户说他付了钱了,然后我们平台没有收到你应该如何进行数据的勾兑校验。 好,那么如果说他有一笔订单,他是30分钟还没支付这种超时订单,我们应该如何处理?

好的,那么面试就这样,那么我们问问你写两道算法题好吧?

很简单,前两道比如说第一道不调用数学库,你写一个算法计算一下正数的平方根 ,有点难简单点,那就是正整数的一个平方根,然后算出来的话,结果只取正整数,比方说我输入一个85,你输出就可以了,这个怎么做?

第二个算法很简单,我们线程方面的,比方说让你起三个线程顺序打印,1~100代码尽量不要重复冗余,来你写一下两个算法半个小时。

好写的不错,包括这次面试你回答的也是非常好,最后再让你做一个小的demo,做个什么给你三天时间。

你起一个spring boot,工程很简单,做一个文件上传功能上传到哪里,上传到阿里云的oss,然后能够上传上去之后返回一个URL,然后通过 Url直接访问就能看到这个图片,比如说那么三天后拿着小demo到咱们公司来进行 hr的第三面好吧?

对了,那么你平常是如何进行知识的学习的? 是看书还是看视频还是上b站白嫖? 我推荐你去b站关注一下it,男老师和it,李老师两个账号是吧?上面有很多的知识讲解,可以吧?行,那么最后你还有什么样的问题可以问一下吗?主管你好,我面试的是20k的,上次一面的小哥说他给我7k薪资满足不了,我三天后不来。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值