20240122面试练习题10

2024-01-26 07:12
文章标签 面试 练习题 20240122

本文主要是介绍20240122面试练习题10,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1. Redis为什么执行这么快?

二、Redis为什么这么快?
1、完全基于内存,数据存在内存中,绝大部分请求是纯粹的内存操作,非常快速,跟传统的磁盘文件数据存储相比,避免了通过磁盘IO读取到内存这部分的开销。

2、数据结构简单,对数据操作也简单。Redis中的数据结构是专门进行设计的,每种数据结构都有一种或多种数据结构来支持。Redis正是依赖这些灵活的数据结构,来提升读取和写入的性能。

3、采用单线程,省去了很多上下文切换的时间以及CPU消耗,不存在竞争条件,不用去考虑各种锁的问题,不存在加锁释放锁操作,也不会出现死锁而导致的性能消耗。

4、使用基于IO多路复用机制的线程模型,可以处理并发的链接。


2. Redis是单线程执行还是多线程执行?它有线程安全问题吗?为什么吗?

1、Redis5及之前是单线程版本
2、Redis6开始引入多线程版本(单线程+多线程 版本)
请求是多线程的,但核心的内存读写操作(或者说读写计算)仍然是单线程的。

线程安全的场景:
1、单个键的读写操作:对于单个键的读操作和写操作是线程安全的。多个线程可以同时读取或写入同一个键,不会引发并发问题。
例如:

SET key value
GET key

2、原子操作:Redis 提供了一些原子性的操作,例如 INCR、LPUSH、SADD 等。这些操作是线程安全的,多个线程同时执行也不会引发问题。
例如:

INCR counter
LPUSH mylist value
SADD myset value

3、发布与订阅:Redis 的发布与订阅功能是线程安全的,多个线程可以同时进行发布和订阅操作。 例如:

PUBLISH channel message
SUBSCRIBE channel

线程不安全的场景:1、多个键的事务操作:如果多个线程同时对不同的键进行事务操作,可能会引发竞态条件。在这种情况下,需要使用分布式锁或其他并发控制技术来保证操作的一致性。
例如:

MULTI
SET key1 value1
SET key2 value2
EXEC

2、对于同一个键的并发写操作:如果多个线程同时对同一个键进行写操作,可能会引发竞态条件。在这种情况下,需要使用分布式锁或其他并发控制技术来保证操作的一致性。
例如:

SET key value1
SET key value2

总之,对于单个键的读写操作、原子操作和发布与订阅功能,Redis 是线程安全的。但在多个键的事务操作和对同一个键的并发写操作时,需要注意并发问题,并使用适当的并发控制机制来保证数据的一致性。


3. 在实际工作中,使用Redis实现了哪些业务场景?

1、缓存
例如:热点数据缓存(商品信息详情),可以提升热点数据的访问效率。

2、分布式锁
String 类型setnx方法,只有不存在时才能添加成功,返回true

public static boolean getLock(String key) {Long flag = jedis.setnx(key, "1");if (flag == 1) {jedis.expire(key, 10);}return flag == 1;
}public static void releaseLock(String key) {jedis.del(key);
}

3、全局ID
int类型,incrby,利用原子性

incrby userid 1000

分库分表的场景,一次性拿一段

4、计数器
int类型,incr方法
例如:文章的阅读量、微博点赞数、允许一定的延迟,先写入Redis再定时同步到数据库

5、限流
int类型,incr方法
以访问者的ip和其他信息作为key,访问一次增加一次计数,超过次数则返回false

6、位统计
String类型的bitcount
字符是以8位二进制存储的

例如:在线用户统计,留存用户统计

setbit onlineusers 01 
setbit onlineusers 11 
setbit onlineusers 20

7、购物车
String 或hash。所有String可以做的hash都可以做。
例如:
key:用户id;field:商品id;value:商品数量。
+1:hincr。-1:hdecr。删除:hdel。全选:hgetall。商品数:hlen。

8、用户消息时间线timeline
list,双向链表,直接作为timeline就好了。插入有序

9、消息队列
List提供了两个阻塞的弹出操作:blpop/brpop,可以设置超时时间

blpop:blpop key1 timeout 移除并获取列表的第一个元素,如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。
brpop:brpop key1 timeout 移除并获取列表的最后一个元素,如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。

10、抽奖
自带一个随机获得值

spop myset

11、点赞、签到、打卡

假如上面的微博ID是t1001,用户ID是u3001用 like:t1001 来维护 t1001 这条微博的所有点赞用户
点赞了这条微博:sadd like:t1001 u3001
取消点赞:srem like:t1001 u3001
是否点赞:sismember like:t1001 u3001
点赞的所有用户:smembers like:t1001
点赞数:scard like:t1001

12、商品筛选

// 获取差集
sdiff set1 set2
// 获取交集(intersection )
sinter set1 set2
// 获取并集
sunion set1 set2

筛选商品,苹果的、ios的、屏幕在6.0-6.24之间的,屏幕材质是LCD屏幕

sinter brand:apple brand:ios screensize:6.0-6.24 screentype:lcd

13、用户关注、推荐模型
follow 关注 fans 粉丝

相互关注:

sadd 1:follow 2
sadd 2:fans 1
sadd 1:fans 2
sadd 2:follow 1

我关注的人也关注了他(取交集):

sinter 1:follow 2:fans

可能认识的人:

用户1可能认识的人(差集):sdiff 2:follow 1:follow
用户2可能认识的人:sdiff 1:follow 2:follow

4. Redis常用数据类型有哪些?

1、String(字符串)
字符串类型是Redis中最为基础的数据存储类型,每个键最大可存储数据512MB
使用方法:

redis 127.0.0.1:6379> set key1 value1
OK
redis 127.0.0.1:6379> set key2 value2
OK
redis 127.0.0.1:6379> get key1
value1
redis 127.0.0.1:6379> get key2
value2
redis 127.0.0.1:6379> set onlineNum 0
OK
redis 127.0.0.1:6379> incr onlineNum
(integer) 1
redis 127.0.0.1:6379> incrby onlineNum 4
(integer) 5
redis 127.0.0.1:6379> decr onlineNum
(integer) 4

适用场景:
很常见的场景用于统计网站访问数量,当前在线人数等。

2、Hash (散列Hash)
hash 是一个 string 类型的 field 和 value 的映射表,hash 特别适合用于存储对象或者map。Redis中的散列可以看成具有String key和String value的map容器,可以将多个key-value存储到一个key中。
使用方法:

redis 127.0.0.1:6379> hset user name zhangsan
(integer) 1
redis 127.0.0.1:6379> hmset user user age 10 sex 30
(integer) 2
redis 127.0.0.1:6379> hget user age
"10"
redis 127.0.0.1:6379> hmget user name sex
1)"zhangsan"
2)"30"
redis 127.0.0.1:6379>

适用场景:
存储、读取、修改用户属性(name,age,pwd等)

3、list (列表)
列表是简单的字符串列表,按照插入顺序排序。双向链表,可从头部或尾部插入或取出数据。
使用方法:

redis 127.0.0.1:6379> lpush users zhangsan
(integer) 1
redis 127.0.0.1:6379> lpush users lisi
(integer) 2
redis 127.0.0.1:6379> lpush users xiaofang
(integer) 3
redis 127.0.0.1:6379> lrange users 0 10 
1) "xiaofang"
2) "lisi"
3) "zhangsan"
redis 127.0.0.1:6379> rpush users chacha
(integer) 4
redis 127.0.0.1:6379> lrange users 0 10 
1) "xiaofang"
2) "lisi"
3) "zhangsan"
4) "chacha"
redis 127.0.0.1:6379> rpop users 
"chacha"
redis 127.0.0.1:6379> rpop users
"zhangsan"
redis 127.0.0.1:6379> lpop users
xiaofang
redis 127.0.0.1:6379>

适用场景
1)最新消息排行榜(如朋友圈的时间线)。
2)消息队列。生产者可以用push操作将任务存在list中,消费者用pop操作将任务取出。

4、set (无序集合)
列表是简单的字符串列表。数据插入无序且不可重复。

使用方法:

redis 127.0.0.1:6379> sadd friends zhangsan
(integer) 1
redis 127.0.0.1:6379> sadd friends lisi
(integer) 1
redis 127.0.0.1:6379> sadd friends zhangsan
(integer) 0
redis 127.0.0.1:6379> sadd friends wupeng
(integer) 1
redis 127.0.0.1:6379> scard friends
(integer) 3
redis 127.0.0.1:6379> sismember friends wupeng
(integer) 1
redis 127.0.0.1:6379> sismember friends shasha
(integer) 0
redis 127.0.0.1:6379> srem friends shasha
(inetegr) 0
redis 127.0.0.1:6379> srem friends zhangsan
(integer) 1
redis 127.0.0.1:6379> scard friends
(integer) 2
redis 127.0.0.1:6379> 

适用场景
利用不可重复性,实现求共同好友、访问某地址ip去重,当前在线用户人数去重等

5、zset (有序集合)
redis的zset 和 set 一样也是string类型元素的集合,且不允许重复的成员。
不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。zset的成员是唯一的,但分数(score)却可以重复

使用方法

redis 127.0.0.1:6379>  zadd rank  97 zhangsan
(integer) 1
redis 127.0.0.1:6379>  zadd rank  70 lisi
(integer) 1
redis 127.0.0.1:6379>  zadd rank  78 wupeng
(integer) 1
redis 127.0.0.1:6379>  zadd rank  75 zhangsan
(integer) 1
redis 127.0.0.1:6379>  zcard rank 
(integer) 3
redis 127.0.0.1:6379>  

适用场景
排行榜、带权重的消息队列


5. 存储Session信息你会使用哪种数据类型?为什么?

Session 数据结构复杂且需要频繁更新或查询其中的个别字段,通常建议使用哈希表来存储 Session;而在 Session 数据较为简单、不涉及局部更新的情况下,使用字符串存储也是可行的选择


6. 有序集合底层是如何实现的?

Redis中的有序集合zset底层实现采用了两种编码方式:

REDIS_ENCODING_SKIPLIST 跳跃列表
REDIS_ENCODING_ZIPLIST 压缩列表

当zset满足以下两个条件的时候,使用ziplist:

保存的元素少于128个
保存的所有元素大小都小于64字节

不满足这两个条件则使用skiplist。


7. 什么是跳表?为什么要用跳表?

跳表是一个随机化的数据结构,实质就是一种可以进行二分查找的有序链表。
跳表在原有的有序链表上面增加了多级索引,通过索引来实现快速查找。
跳表不仅能提高搜索性能,同时也可以提高插入和删除操作的性能。


8. 说一下跳表的查询流程?

把一些节点从有序表中提取出来,缓存一级索引,就组成了下面这样的结构:
在这里插入图片描述
要查找17这个元素,只要从一级索引往后遍历即可,只需要经过1、6、15、17这几个元素就可以找到17了。

查找11这个元素,从一级索引的1开始,向右到6,再向右发现是15,它比11大,此路不通,从6往下走,再从下面的6往右走,到7,再到11。

同样地,一级索引也可以往上再提取一层,组成二级索引,如下:

在这里插入图片描述


9. 说一下跳表的添加流程?为什么要有“随机层数”这个概念?

每一个元素添加到跳表中时,首先需要随机指定这个元素在跳表中的层数,如果随机指定的层数大于了跳表的层数,则在将元素添加到跳表中之前,还需要扩大跳表的层数,而扩大跳表的层数就是将头尾节点的层数扩大。
关于“随机层数”的概念,其主要目的是为了保持跳表的平衡性。如果我们固定每个元素的层数,那么在某些情况下,跳表可能会退化成普通的链表,从而导致查找效率降低。通过随机选择每个元素的层数,我们可以确保跳表的高度大致为log(n),从而保证查找、插入和删除操作的时间复杂度为O(log n)


10. 使用Redis如何实现分布式锁?

想要实现分布式锁,必须要求Redis有互斥的能力。可以使用SETNX命令,其含义是SET IF NOT EXIST,即如果key不存在,才会设置它的值,否则什么也不做。两个客户端进程可以执行这个命令,达到互斥,就可以实现一个分布式锁。

加锁操作完成后,加锁成功的客户端,就可以去操作共享资源,例如,修改MySQL的某一行数据。操作完成后,还要及时释放锁,给后来者让出操作共享资源的机会。释放锁直接使用DEL命令删除这个key即可。

// 加锁
SETNX lock_key 1
// 业务逻辑
DO THINGS
// 释放锁
DEL lock_key

以上实现存在一个很大的问题,当客户端1拿到锁后,如果发生下面的场景,就会造成死锁。

程序处理业务逻辑异常,没及时释放锁
进程挂了,没机会释放锁
以上情况会导致已经获得锁的客户端一直占用锁,其他客户端永远无法获取到锁。

为了解决以上死锁问题,最容易想到的方案是在申请锁时,在Redis中实现时,给锁设置一个过期时间,假设操作共享资源的时间不会超过10s,那么加锁时,给这个key设置10s过期即可。

但以上操作还是有问题,加锁、设置过期时间是2条命令,有可能只执行了第一条,第二条却执行失败,例如:

SETNX执行成功,执行EXPIRE时由于网络问题,执行失败
SETNX执行成功,Redis异常宕机,EXPIRE没有机会执行
SETNX执行成功,客户端异常崩溃,EXPIRE没有机会执行
总之这两条命令如果不能保证是原子操作,就有潜在的风险导致过期时间设置失败,依旧有可能发生死锁问题。在Redis 2.6.12之后,Redis扩展了SET命令的参数,可以在SET的同时指定EXPIRE时间,这条操作是原子的,例如以下命令是设置锁的过期时间为10秒。

SET lock_key 1 EX 10 NX

这篇关于20240122面试练习题10的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/646029

相关文章

字节面试 | 如何测试RocketMQ、RocketMQ?

字节面试:RocketMQ是怎么测试的呢? 答: 首先保证消息的消费正确、设计逆向用例,在验证消息内容为空等情况时的消费正确性; 推送大批量MQ,通过Admin控制台查看MQ消费的情况,是否出现消费假死、TPS是否正常等等问题。(上述都是临场发挥,但是RocketMQ真正的测试点,还真的需要探讨) 01 先了解RocketMQ 作为测试也是要简单了解RocketMQ。简单来说,就是一个分

秋招最新大模型算法面试,熬夜都要肝完它

💥大家在面试大模型LLM这个板块的时候,不知道面试完会不会复盘、总结,做笔记的习惯,这份大模型算法岗面试八股笔记也帮助不少人拿到过offer ✨对于面试大模型算法工程师会有一定的帮助,都附有完整答案,熬夜也要看完,祝大家一臂之力 这份《大模型算法工程师面试题》已经上传CSDN,还有完整版的大模型 AI 学习资料,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

dp算法练习题【8】

不同二叉搜索树 96. 不同的二叉搜索树 给你一个整数 n ,求恰由 n 个节点组成且节点值从 1 到 n 互不相同的 二叉搜索树 有多少种?返回满足题意的二叉搜索树的种数。 示例 1: 输入:n = 3输出:5 示例 2: 输入:n = 1输出:1 class Solution {public int numTrees(int n) {int[] dp = new int

java面试常见问题之Hibernate总结

1  Hibernate的检索方式 Ø  导航对象图检索(根据已经加载的对象,导航到其他对象。) Ø  OID检索(按照对象的OID来检索对象。) Ø  HQL检索(使用面向对象的HQL查询语言。) Ø  QBC检索(使用QBC(Qurey By Criteria)API来检索对象。 QBC/QBE离线/在线) Ø  本地SQL检索(使用本地数据库的SQL查询语句。) 包括Hibern

贝壳面试:什么是回表?什么是索引下推?

尼恩说在前面 在40岁老架构师 尼恩的读者交流群(50+)中,最近有小伙伴拿到了一线互联网企业如得物、阿里、滴滴、极兔、有赞、希音、百度、网易、美团的面试资格,遇到很多很重要的面试题: 1.谈谈你对MySQL 索引下推 的认识? 2.在MySQL中,索引下推 是如何实现的?请简述其工作原理。 3、说说什么是 回表,什么是 索引下推 ? 最近有小伙伴在面试 贝壳、soul,又遇到了相关的

毕业前第二次面试的感慨

距面试已经过去了有几天了,我现在想起来都有说多的恨感慨。 我一直都是想找刚刚起步的企业,因为这能让我学到更多的东西,然而正好有一家企业是刚起步的,而且他还有自己的产品专利,可以说这是一家,即是创业又是刚起步的公司,这家公司回复了我投给他的简历,这家企业想进一步了解我的情况,因为简历上我符合这家企业的基本要求,所以要进一步了解。 虽然面试的过程中,他给我的面试题,我做得并不是很理想,

腾讯社招面试经历

前提:本人2011年毕业于一个普通本科,工作不到2年。   15号晚上7点多,正在炒菜做饭,腾讯忽然打电话来问我对他们的Linux C++的职位是否感兴趣,我表达了我感兴趣之后,就开始了一段简短的电话面试,电话面试主要内容:C++和TCP socket通信的一些基础知识。之后就问我一道算法题:10亿个整数,随机生成,可重复,求最大的前1万个。当时我一下子就蒙了,没反应过来,何况我还正在烧

完整的腾讯面试经过

从9月10号开始到现在快两个月了,两个多月中,我经历数次面试和笔试,在经历这些的同时积累了不少的经验,也学到了不少东西,在此把它记录下来,算是和一起找工作中的同学一起共勉吧。我是本校的学生,专业是机械制造及其自动化,找工作的主要目标是计算机软件类和机械制造方向的国内的企业,所以意向去外企的同学就不必浪费时间看这些面经啦,想去国内IT企业的同学可以继续看下去。本贴中我把最近的腾讯面试经过写下

仕考网:结构化面试流程介绍

(一)结构化面试 结构化面试,也叫做标准化面试,考官按照预先设定好的一套试题以问答方式与应试者当面交谈,根据应试者的言语、行为表现,对其相关能力和个性特征作出相应评价。 (二)考试流程 抵达考场——审核抽签——面试候考——进入考场——面试答题——考生退场——计分审核 (三)答题技巧 1.声音洪亮,音量可以比平时说话声音大一点。 2.语速不要过快,语速快容易卡顿,而且不便于考官听清答

嵌入式面试经典30问:二

1. 嵌入式系统中,如何选择合适的微控制器或微处理器? 在嵌入式系统中选择合适的微控制器(MCU)或微处理器(MPU)时,需要考虑多个因素以确保所选组件能够满足项目的具体需求。以下是一些关键步骤和考虑因素: 1.1 确定项目需求 性能要求:根据项目的复杂度、处理速度和数据吞吐量等要求,确定所需的处理器性能。功耗:评估系统的功耗需求,选择低功耗的MCU或MPU以延长电池寿命或减少能源消耗。成本