【面试题系列】(一)
Redis有哪些数据结构?其底层是怎么实现的?
Redis 系列(一):深入了解 Redis 数据类型和底层数据结构
-
字符串(String): 用于存储文本或二进制数据。可以执行字符串的基本操作,如设置、获取、增加、减少等。
-
哈希表(Hash): 存储键值对集合,类似于关联数组。适用于存储对象属性或配置信息。
-
列表(List): 使用双向链表实现的有序集合,允许插入和删除元素。可以用于实现队列、栈等数据结构。
-
集合(Set): 存储不重复的无序元素集合。支持求交集、并集、差集等操作,适用于数据去重和关联性操作。
-
有序集合(Sorted Set): 类似于集合,但每个元素都有一个分数(score),并根据分数进行排序。适用于排行榜、优先级队列等场景。
-
位图(Bitmap): 使用字符串来表示位的数据结构,支持位操作。适用于标记、计数等场景。
-
HyperLogLog: 用于估计集合中唯一元素的个数,占用固定的内存空间,适用于基数统计场景。
-
地理空间(GeoSpatial): 存储地理位置信息,支持距离计算和位置查询。
什么是缓存击穿?什么原因?如何解决?
缓存击穿是指在高并发情况下,一个缓存中不存在但是频繁被请求的数据,导致请求直接打到数据库,增加数据库的负载和延迟。这通常发生在以下情况下:
-
热点数据失效: 当某个热点数据过期或被移除时,大量的并发请求同时访问该数据,导致请求绕过缓存直接访问数据库。
-
分布式系统中的节点失效: 在分布式缓存环境下,如果一个或多个缓存节点失效,会导致请求无法命中缓存,从而打到后端数据库。
解决缓存击穿的方法有多种,其中常见的包括:
-
设置热点数据永不过期: 对于热点数据,可以设置永不过期,确保数据始终可用。但要注意,这会占用缓存空间,可能导致其他数据的驱逐。
-
使用互斥锁(Mutex Lock): 在缓存失效时,使用互斥锁来控制只有一个请求能够从数据库加载数据,其他请求在等待中,避免并发访问数据库。
-
提前异步加载: 在数据即将过期时,启动一个异步任务去加载数据到缓存,避免过期时直接请求数据库。
-
使用分布式锁: 在分布式环境下,可以使用分布式锁来保护缓存数据的加载过程,确保只有一个节点进行加载。
-
使用布隆过滤器: 布隆过滤器是一种用于判断元素是否存在于集合中的数据结构,可以用来判断某个数据是否需要去数据库加载,减少无效的请求。
-
热点数据预加载: 提前在系统启动时加载热点数据到缓存,避免在运行时因为缓存失效而引起的问题。
选择哪种方法取决于具体的业务场景和需求,通常需要根据系统的特点和访问模式来综合考虑。
什么是缓存雪崩?什么原因?如何解决?
缓存雪崩是指缓存在某个时间段内大面积失效,导致大量请求直接访问后端数据库,造成数据库压力激增和系统性能下降的情况。通常发生在以下情况下:
-
大量缓存同时失效: 当多个缓存数据在同一个时间段内同时失效,导致大量请求直接打到后端数据库。
-
缓存服务器宕机: 如果缓存服务器宕机,缓存数据不可用,请求会直接访问后端数据库。
-
业务高峰期: 在业务高峰期,访问量剧增,缓存失效导致数据库请求激增。
解决缓存雪崩的方法包括:
-
使用多级缓存: 引入多级缓存,将数据同时存储在多个缓存层,降低某个缓存层失效的风险。
-
设置随机过期时间: 对于相同类型的数据,设置随机的过期时间,避免大量数据同时失效。
-
缓存数据永不过期: 对于热点数据,可以设置永不过期,确保数据始终可用。
-
异步加载缓存: 在缓存失效时,启动异步任务去加载数据,避免在缓存失效时直接访问数据库。
-
限流降级: 在高峰期限制请求的并发数,将部分请求降级处理,避免对后端服务造成过大压力。
-
熔断策略: 根据系统负载情况,实施熔断策略,避免系统崩溃。
-
缓存预热: 在系统启动时,预先加载热点数据到缓存,避免系统启动时的大量请求。
-
分布式部署: 将缓存服务器分布在不同的节点上,降低单点故障的风险。
综合考虑业务需求和系统特点,可以采用上述方法来解决缓存雪崩问题,保障系统的稳定性和性能。
Redis持久化机制了解吗?
Redis 系列(二):深入解读 Redis 的两种持久化方式
是的,Redis具有两种主要的持久化机制:RDB(Redis Database)快照和AOF(Append-Only File)日志。这些机制用于将内存中的数据持久化到硬盘上,以防止数据丢失。
-
RDB快照:
-
RDB持久化通过将内存中的数据快照保存到一个二进制文件(例如 dump.rdb)中来实现。 -
可以手动执行RDB快照,也可以通过配置项定期自动执行。 -
优点是文件小,适合备份和恢复,对性能影响较小。 -
缺点是数据可能在两次快照之间发生丢失,不适合数据实时性要求较高的场景。
-
-
AOF日志:
-
AOF持久化记录每个写操作(例如SET、DEL)到一个追加的日志文件(例如 appendonly.aof)中。 -
AOF文件以文本方式记录,可以随时对其进行追加、更新和重写。 -
可以通过配置项设置不同的AOF策略: always(每次写操作都记录)、everysec(每秒记录一次)、no(不记录)。 -
优点是可以实现更高的数据实时性,适合对数据安全性要求较高的场景。 -
缺点是AOF文件相对较大,恢复速度可能较慢。
-
在实际应用中,可以根据业务需求选择合适的持久化机制,甚至可以同时使用RDB和AOF,以提高数据的安全性和可靠性。另外,Redis还提供了混合持久化的方式(默认使用AOF来恢复数据,而RDB用于备份),以充分发挥两种持久化机制的优势。
Redis应用场景有哪些?
-
缓存: 最常见的用途,将热门数据存储在内存中,以提高访问速度,减轻数据库负担。适用于读取频繁、数据量较大的场景。
-
会话存储: 将用户会话数据存储在Redis中,实现分布式会话管理,以避免单点故障和状态共享问题。
-
计数器和统计: Redis的原子操作可以实现计数器功能,用于统计页面访问、点赞、评论等。
-
排行榜/热门内容: 利用有序集合(Sorted Set)数据结构,存储并排名用户、文章、商品等,以实现排行榜或展示热门内容。
-
发布订阅: Redis的发布订阅机制允许实时地将消息发布给订阅者,用于构建实时通知、聊天室等功能。
-
分布式锁: 利用Redis的原子操作和过期时间设置,实现分布式环境下的锁机制,保障资源的互斥访问。
-
限流器: 利用Redis的令牌桶或漏桶算法,实现请求的限流控制,防止突发流量影响系统稳定性。
-
缓存穿透防护: 将空值或异常数据存储在缓存中,避免缓存穿透引起的数据库查询压力。
-
地理位置服务: 利用Redis的地理位置数据类型,存储并查询地理位置信息,用于附近的人、地点等功能。
-
任务队列: 利用列表数据结构,实现异步任务队列,处理后台任务、消息队列等。
-
即时数据分析: 将实时产生的数据存储在Redis中,供数据分析使用,如实时监控、实时报表等。
这些只是Redis应用场景的一部分,实际上,由于Redis的高性能、低延迟和丰富的数据结构,它在很多领域都有广泛的应用。根据具体的业务需求,可以灵活选择合适的场景来使用Redis。
Redis为什么这么快?
Redis之所以具有如此高的性能,主要是由于以下几个方面的设计和优化:
-
内存存储: Redis将数据存储在内存中,内存的读写速度远高于磁盘,因此能够实现极低的读写延迟。
-
单线程模型: Redis采用单线程模型处理客户端请求,避免了多线程的锁竞争和上下文切换开销,减少了性能损耗。
-
非阻塞IO: Redis使用非阻塞IO和事件驱动的方式来处理客户端连接和网络通信,有效利用了操作系统提供的异步IO机制,提高了并发能力。
-
数据结构优化: Redis内置了多种高效的数据结构,如哈希表、有序集合、跳表等,针对不同的应用场景选择最合适的数据结构,提高了数据操作的效率。
-
持久化策略: Redis支持多种持久化方式,如RDB快照和AOF日志,可以根据需求选择合适的持久化策略,保障数据的可靠性。
-
多种网络协议支持: Redis支持多种网络协议,如HTTP、RESP(Redis Serialization Protocol)等,方便不同编程语言和应用程序与Redis进行交互。
-
数据压缩: Redis在存储数据时进行了压缩,减小了内存占用,提高了数据的存储密度。
-
预分配内存: Redis在启动时预先分配一定数量的内存,减少了内存分配的开销,提高了内存使用效率。
-
管道技术: Redis的管道(Pipeline)技术允许客户端发送多个命令,在一个连接上连续执行,减少了网络通信的开销。
-
高效的排序算法: 在有序集合(Sorted Set)中,Redis采用跳表(Skip List)作为底层数据结构,实现了高效的排序和检索。
Redis事务如何实现?
Redis事务是一组命令的集合,可以在一个原子操作内执行多个命令。Redis的事务通过MULTI、EXEC、WATCH、DISCARD等命令来实现,它提供了类似于传统数据库的事务特性,但与传统数据库的事务有一些不同之处。
以下是Redis事务的实现流程:
-
MULTI命令: 事务开始时,客户端发送MULTI命令,告诉Redis开始记录后续的命令序列。
-
多个命令: 在MULTI和EXEC之间的命令会被加入到事务队列中,但并不会立即执行。
-
EXEC命令: 当客户端发送EXEC命令时,Redis会依次执行事务队列中的命令。在执行过程中,Redis会将事务队列中的命令依次执行,如果其中的某个命令执行失败,不会影响其他命令的执行。
-
事务执行结果: EXEC命令执行完成后,Redis会返回事务中所有命令的执行结果,以数组形式返回。如果事务中的某个命令执行失败,对应的结果将是错误信息。
-
DISCARD命令: 如果在MULTI和EXEC之间,客户端发送了DISCARD命令,那么事务队列中的所有命令都会被清除,事务被取消。
-
WATCH命令: 为了实现乐观锁的机制,可以使用WATCH命令监视一个或多个键。如果在事务执行前,有其他客户端修改了被监视的键,整个事务会被取消。
Redis事务的特点:
-
Redis事务是原子性的:在EXEC执行期间,事务中的所有命令要么都被执行,要么都不被执行。 -
Redis事务是隔离的:事务的执行过程不会受到其他客户端的影响。 -
Redis事务是不支持回滚的:即使其中某个命令执行失败,不会回滚前面已经执行的命令。
需要注意的是,虽然Redis事务提供了一种封装多个命令的方式,但是由于Redis的单线程模型,事务中的某些命令可能会因为特定的情况(如阻塞操作)导致整个事务执行的时间较长。因此,在使用Redis事务时,需要考虑事务执行期间可能的性能影响。
Redis过期键删除策略?
在Redis中,有两种主要的过期键删除策略,分别是惰性删除和定期删除,还有一些淘汰策略用于释放内存空间。以下是这些策略的详细说明:
-
惰性删除(Lazy Expiration): 这是Redis默认的过期键删除策略。当访问一个已经过期的键时,Redis会立即删除该键并返回空值。这种策略避免了在访问时才删除键,节省了内存和CPU资源。
-
定期删除(定时任务删除): Redis会随机抽取一些过期键,并检查它们是否过期。如果过期,就会删除这些键。这种策略通过定期任务进行删除,以避免删除大量过期键对性能造成影响。
-
内存淘汰策略(Eviction Policies): 当内存使用达到一定阈值(由
maxmemory参数指定)时,Redis会触发淘汰策略来释放空间。常见的淘汰策略包括:-
noeviction:当内存不足以容纳新写入数据时,写入操作会报错。 -
allkeys-lru:从所有键中选择最近最少使用的键进行删除。 -
volatile-lru:从设置了过期时间的键中选择最近最少使用的键进行删除。 -
allkeys-random:随机选择一个键进行删除。 -
volatile-random:从设置了过期时间的键中随机选择一个键进行删除。 -
volatile-ttl:从设置了过期时间的键中选择剩余时间最短的键进行删除。
-
这些策略可以通过Redis的配置参数进行设置,例如:
# 设置过期键删除策略为定期删除
config set maxmemory-policy noeviction
需要根据实际场景和需求来选择适合的策略和参数值,以平衡内存使用和性能。
Redis怎么实现消息队列?
Redis可以用作轻量级的消息队列,实现基本的消息发布和订阅功能。以下是在Redis中如何实现消息队列的基本步骤:
-
发布消息: 在发布者端,使用
PUBLISH命令将消息发布到指定的频道(通道)。PUBLISH channel_name message_content -
订阅消息: 在订阅者端,使用
SUBSCRIBE命令订阅一个或多个频道,从中接收发布者发布的消息。SUBSCRIBE channel_name -
接收消息: 订阅者在订阅了频道后,会实时接收到发布者发布的消息。
通过上述步骤,你可以实现基本的发布-订阅模式的消息队列。然而,需要注意以下几点:
-
Redis的消息队列不支持消息持久化,即如果没有订阅者在线时,消息会丢失。 -
如果需要支持持久化、多个消费者、消息确认等高级特性,可能需要考虑使用专门的消息队列中间件,如RabbitMQ、Apache Kafka等。
在实际应用中,如果需要更多的消息队列特性,可以使用Redis的LIST数据结构来实现简单的队列。将发布者发布的消息插入到LIST中,然后消费者从LIST中弹出消息进行处理。但需要注意的是,Redis并不是专门为消息队列设计的,更适合用于一些简单的消息发布-订阅场景。对于高性能、大规模的消息队列需求,建议使用专门的消息队列中间件。
本文由 mdnice 多平台发布
相关文章:
【面试题系列】(一)
Redis有哪些数据结构?其底层是怎么实现的? Redis 系列(一):深入了解 Redis 数据类型和底层数据结构 字符串(String): 用于存储文本或二进制数据。可以执行字符串的基本操作…...
vscode C++17便捷配置教程(懒人版)
环境链接 以上是已经配置好的c17环境链接,直接下载解压即可(注意文件路径上不要带有中文) 下载解压之后按照msys64-mingw64-bin路径打开 然后单击该路径右方空白区域可直接复制路径 然后点击开始菜单搜索“环境变量“并打开(如…...
动态数组实现链地址法哈希表
通常情况下哈希函数的输入空间远大于输出空间,因此理论上哈希冲突是不可避免的。比如,输入空间为全体整数,输出空间为数组容量大小,则必然有多个整数映射至同一数组索引。 解决哈希冲突方法常见有:链地址法、开放寻址…...
Eclipse(STS):pom.xml 报错:Multiple markers at this line
pom.xml 报错:Multiple markers at this line STS中,项目能够正常运行,但是 pom.xml 报错:Multiple markers at this line 项目本身没有任何修改,之前不报错的,突然报错了。 Multiple markers at this li…...
CSerialPort教程4.3.x (3) - CSerialPort在MFC中的使用
CSerialPort教程4.3.x (3) - CSerialPort在MFC中的使用 环境: 系统:windows 10 64位 编译器:Visual Studio 2008前言 CSerialPort项目是一个基于C/C的轻量级开源跨平台串口类库,可以轻松实现跨平台多操作系统的串口读写&#x…...
2022版 的IDEA创建一个maven项目(超详细)
一.设置idea中指定的maven的位置以及本地存储仓库 开发中一般我们使用自己下载的maven,不使用IDEA工具自带的,这就需要将我们下载的maven配置到IDEA工具中,配置如下图所示: 或者直接 快捷键 CtrlAltS 直接进入设置 maven home pa…...
lvs实现DR模型搭建
目录 一,实现DR模型搭建 1, 负载调度器配置 1.1调整ARP参数 1.2 配置虚拟IP地址重启网卡 1.3 安装ipvsadm 1.4 加载ip_vs模块 1.5 启动ipvsadm服务 1.6 配置负载分配策略 1.7 保存策略 2, web节点配置 1.1 调整ARP参数 1.2 配置虚拟I…...
设计模式之迭代器模式(Iterator)的C++实现
1、迭代器模式的提出 在软件开发过程中,操作的集合对象内部结构常常变化,在访问这些对象元素的同时,也要保证对象内部的封装性。迭代器模式提供了一种利用面向对象的遍历方法来遍历对象元素。迭代器模式通过抽象一个迭代器类,不同…...
【0基础入门Python Web笔记】二、python 之逻辑运算和制流程语句
二、python 之逻辑运算和制流程语句 逻辑运算控制流程语句条件语句(if语句)循环结构(for循环、while循环)continue、break和pass关键字控制流程语句的嵌套以及elif 更多实战项目可进入下方官网 逻辑运算 Python提供基本的逻辑运算…...
容器——Docker
1.安装docker服务,配置镜像加速器 2.下载系统镜像(Ubuntu、 centos) 3.基于下载的镜像创建两个容器 (容器名一个为自己名字全拼,一个为首名字字母) 4.容器的启动、 停止及重启操作 5.怎么查看正在运行的容器…...
SQL注入之宽字节注入
文章目录 宽字节注入是什么?注入练习让转义符失效联合查询 代码审计 宽字节注入是什么? 宽字节注入准确来说不是注入手法,而是另外一种比较特殊的情况。宽字节注入的目的是绕过单双引号转义。 宽字节注入是一种绕过单双引号转义的手段&#x…...
MyBatis动态sql
文章目录 一、MyBatis动态sql1.1 概述1.2 if元素1.3 foreach元素 二、模糊查询2.1 使用#{字段名}2.2 使用${字段名}2.3 使用concat{%,#{字段名},%}2.4 mybatis中#与$的区别 三、MyBatis结果映射3.1 区别3.2 应用场景 一、MyBatis动态sql 1.1 概述 MyBatis是一个Java持久化框架…...
L1-032 Left-pad 测试点全过
题目 根据新浪微博上的消息,有一位开发者不满NPM(Node Package Manager)的做法,收回了自己的开源代码,其中包括一个叫left-pad的模块,就是这个模块把javascript里面的React/Babel干瘫痪了。这是个什么样的…...
ssm+Vue.js在线购物系统源码和论文
ssmVue.js在线购物系统源码和论文049 开发工具:idea 数据库mysql5.7 数据库链接工具:navcat,小海豚等 技术:ssm 摘 要 随着科学技术的飞速发展,各行各业都在努力与现代先进技术接轨,通过科技手段提高自身的优势…...
港联证券|指数或进入磨底阶段 短期关注环保、煤炭等板块
磨底历来都不是一天能达到的,比方2018年的政策底到商场底,半途也阅历两个多月时间。当下政策底出现之后至今也有近一个月时间,并且下跌量能不断缩短,心情面也降至冰点,种种迹象阐明离真正商场底的构成已经不远了。此时…...
pytorch 实现VGG
VGG全称是Visual Geometry Group,因为是由Oxford的Visual Geometry Group提出的。AlexNet问世之后,很多学者通过改进AlexNet的网络结构来提高自己的准确率,主要有两个方向:小卷积核和多尺度。而VGG的作者们则选择了另外一个方向&a…...
科技项目验收检测报告获取有哪些注意事项,作用都有哪些?
验收测试报告 软件从研发到结束是一个很长的周期,对于软件想要完成上市或者是交付到用户手中之前我们还需要进行一次全面检测,也就是科技项目验收测试,此测试有着严格的要求,需要第三方软件测评机构来完成,并出具科技…...
OceanBase:谁动了我得参数?
作者:郑增权 爱可生南区数据库工程师,爱可生 DBA 团队成员,负责数据库相关技术支持。爱好:桌球、羽毛球、咖啡、电影。 本文来源:原创投稿 爱可生开源社区出品,原创内容未经授权不得随意使用,转…...
Python快速入门体验
Python快速入门体验 一、环境信息1.1 硬件信息1.2 软件信息 二、Conda安装2.1 Conda介绍2.1.1 Conda简介2.1.2 Conda、Anaconda及Miniconda及的关系 2.2 Conda安装包下载2.2.1 Miniconda下载2.2.2 Anconda下载 2.3 Conda安装2.3.1 Miniconda安装2.3.2 Anconda安装 2.4 Conda初始…...
【从零学习python 】68. Python正则表达式中的贪婪和非贪婪模式
文章目录 贪婪和非贪婪模式进阶案例 贪婪和非贪婪模式 Python里数量词默认是贪婪的(在少数语言里也可能是默认非贪婪),总是尝试匹配尽可能多的字符; 非贪婪则相反,总是尝试匹配尽可能少的字符。 在*、?、、{m,n}后面…...
conda相比python好处
Conda 作为 Python 的环境和包管理工具,相比原生 Python 生态(如 pip 虚拟环境)有许多独特优势,尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处: 一、一站式环境管理:…...
Ubuntu系统下交叉编译openssl
一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机:Ubuntu 20.04.6 LTSHost:ARM32位交叉编译器:arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...
深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法
深入浅出:JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中,随机数的生成看似简单,却隐藏着许多玄机。无论是生成密码、加密密钥,还是创建安全令牌,随机数的质量直接关系到系统的安全性。Jav…...
(二)TensorRT-LLM | 模型导出(v0.20.0rc3)
0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述,后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作,其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...
Go 语言并发编程基础:无缓冲与有缓冲通道
在上一章节中,我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道,它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好࿰…...
人机融合智能 | “人智交互”跨学科新领域
本文系统地提出基于“以人为中心AI(HCAI)”理念的人-人工智能交互(人智交互)这一跨学科新领域及框架,定义人智交互领域的理念、基本理论和关键问题、方法、开发流程和参与团队等,阐述提出人智交互新领域的意义。然后,提出人智交互研究的三种新范式取向以及它们的意义。最后,总结…...
【Android】Android 开发 ADB 常用指令
查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...
数学建模-滑翔伞伞翼面积的设计,运动状态计算和优化 !
我们考虑滑翔伞的伞翼面积设计问题以及运动状态描述。滑翔伞的性能主要取决于伞翼面积、气动特性以及飞行员的重量。我们的目标是建立数学模型来描述滑翔伞的运动状态,并优化伞翼面积的设计。 一、问题分析 滑翔伞在飞行过程中受到重力、升力和阻力的作用。升力和阻力与伞翼面…...
Python学习(8) ----- Python的类与对象
Python 中的类(Class)与对象(Object)是面向对象编程(OOP)的核心。我们可以通过“类是模板,对象是实例”来理解它们的关系。 🧱 一句话理解: 类就像“图纸”,对…...
数据分析六部曲?
引言 上一章我们说到了数据分析六部曲,何谓六部曲呢? 其实啊,数据分析没那么难,只要掌握了下面这六个步骤,也就是数据分析六部曲,就算你是个啥都不懂的小白,也能慢慢上手做数据分析啦。 第一…...
