系统设计类题目汇总
1 设计一个系统统计当前时刻北京用户在线人数
【Redis】位图以及位图的使用场景(统计在线人数和用户在线状态)
1.1 方案一:
- 在用户登录时,使用 Redis SET 将用户 ID 添加到一个特定的键(例如 “online:beijing”)。
- 用户退出时,从 SET 中移除用户 ID。
- 为了统计在线人数,直接获取 SET 的元素数量。
1.2 方案二:为什么不能用一个 count 字段
如果使用单一的 count 字段,当多个进程或线程同时更新该字段时,可能会出现竞争条件,导致不准确的计数。此外,你无法知道哪些用户是在线的。
1.3 方案三:方案一在计数方面不方便,所以我是不是可以把这两个方案结合起来,要查总在线人数的时候使用count字段一次性查出,想要看哪些活跃的人数的时候就按照方案一查(其实redis的set集合中应该也提供了计算元素数量的api)
确实,你可以将两个方案结合起来以便根据不同的需求灵活地查询。
结合方案:
-
处理登录:
- 当用户登录时,执行以下操作:
- 使用 Redis SET 将用户 ID 添加到一个特定的键(例如 “online:beijing”)。
- 使用 Redis 的
INCR
命令增加一个 “online:count:beijing” 字段的值。
- 当用户登录时,执行以下操作:
-
处理退出:
- 当用户退出时,执行以下操作:
- 从 SET “online:beijing” 中移除用户 ID。
- 使用 Redis 的
DECR
命令减少 “online:count:beijing” 字段的值。
- 当用户退出时,执行以下操作:
-
查询在线人数:
- 直接获取 “online:count:beijing” 字段的值。
-
查询在线的具体用户:
- 直接获取 SET “online:beijing” 的所有成员。
这种方法结合了两种方案的优点:INCR
和 DECR
命令都是原子的,这意味着即使有多个进程或线程同时操作,“online:count:beijing” 的值也会被准确地更新。而 SET “online:beijing” 则提供了查询特定在线用户的能力。
需要注意的是,这种方法会稍微增加存储和操作的开销,因为每次登录或退出都需要操作两个 Redis 键。但从实用性和灵活性的角度来看,这是一个很好的折中方案。
1.4 方案四:使用bitMap
前几个方案的缺点:如果使用set,会存储每一个用户的id,在1亿用户量的情况下,每一个用户id占用4B,总的内存使用量就是10^9*4B=4GB,内存会撑爆
答:所以这个时候会使用位图,将每一个在线用户放入到一个编码函数生成一串数字,根据对应的数字将其在bitMap中对应位置的值置为1,用户下线时就将对应位置的值置换为0,此时内存使用量为100000000/8b/1024B/1024MB 约等于 12MB;
本方案不足:当需要查找在线人数的时候,就是用bitcount()获取,但是这个方法会遍历bitMap,复杂度是O(n)的
1.5 方案五:使用bitMap+count字段
新设置一个count字段,用于统计在线人数,然后每次上线一个用户,就使用原子化操作将bitMap和count自增操作打包在一起更新。这样在查询总人数的时间复杂度也是O(1)
2 让你设计一个mysql优化器,怎么设计
2.1 收集统计信息:
扫描数据表和索引来估计行数、数据分布和存储大小。
**定期更新这些统计信息,**以保持查询优化器的信息是最新的。
2.2 SQL 重写:
解析输入的 SQL 查询并形成一个初始的执行计划。
对计划进行转化,例如合并相邻的表扫描,简化 WHERE 子句等。
2.3 索引建议:
分析查询以确定哪些列经常被用作过滤条件。
基于这些信息提供索引创建的建议,以加速查询。
2.4 缓存:
为经常运行的查询结果提供缓存,避免重复的计算。
考虑缓存的失效策略,如 LRU。
2.5 分析查询:
对查询的执行计划进行深入的分析,找出可能的性能瓶颈。
提供关于查询如何修改或重写以改善性能的建议。
3 让你设计一个延时任务系统怎么做?
3.1 Redis ZSET
(1)使用 Redis ZSET,score作为时间戳,任务id作为哈希表的key:
(2)分片: 为了抗高并发,可以将数据分散到多个 Redis 实例中,使用一致性哈希或其他分片算法。
(3)持久化: 利用 Redis 的 RDB 或 AOF 功能,确保数据不丢失。
(4)哨兵模式: 用于故障转移,当主节点出现问题时,哨兵可以自动将从节点提升为主节点。
3.2 时间片轮转算法
时间轮是一个非常高效的延时任务调度方法,其基本概念是将时间分成多个小的时间片段,并使用一个循环队列(轮子)来表示。每个槽代表一个时间片段。时间轮持续地旋转,当时间推进到某个槽时,会执行该槽中的所有任务。
- 初始化: 创建一个固定大小的时间轮,每个槽都有一个任务队列。
- 添加任务: 根据任务的延时时间,计算应该放入哪个槽。将任务放入相应槽的任务队列中。
- 时间推进: 定期(例如每秒)检查当前槽,执行所有任务,然后移动到下一个槽。
- 槽溢出处理: 对于超过时间轮大小的延时,可以使用多层时间轮来处理。
4 Redis 的 ZSET 做排行榜时,如果要实现分数相同时按时间顺序排序怎么实现?
4.1 方案一:拆分 score:
即将 score 拆分为高 32 位和低 32 位,高32位存储时间戳,低32位存储score
4.2 方案二:使用 ZSET
使用 ZSET 存储分数,再使用一个 HASH 表存储每个用户的时间戳。在获取排行榜时,首先按分数排序,分数相同的则根据 HASH 表中的时间戳排序。
5 redis实现好友关系、粉丝数
5.1 好友关系(使用一个set存储我关注的人)
- 对于每个用户,使用一个 SET 来存储他的所有好友的 ID。
- 添加好友:在两个用户的 SET 中互相添加对方的 ID。
- 删除好友:在两个用户的 SET 中互相移除对方的 ID。
- 检查是否为好友:查询其中一个用户的 SET 是否包含另一个用户的 ID。
- 获取好友列表:直接获取用户的 SET 中的所有元素。
- 共同好友:将两个用户的set都查出来,取得交集
5.2 粉丝数
再设置一个set,存储关注我的人,别人关注我就需要同时在两个set上put新值
6 给一个场景:有很多图片,然后我们需要对图片进行存储,以及查找,有什么数据结构比较适合?如果我要加速查询的速率,你要怎么设计?
6.1 方案一
处理大量图片的存储和检索通常涉及多个层次的设计。以下是针对这一场景的一些建议:
-
存储:
- 分布式文件系统:例如 Hadoop Distributed FileSystem (HDFS) 或 Facebook 的 Haystack,它们专为存储大量文件而设计。
- 对象存储:例如 Amazon S3,它可以存储和检索任意数量的数据。
-
为图片建立索引:
当你只知道图片的元数据(例如上传者、时间、标签等)并希望基于这些数据检索图片时:
- 使用关系数据库或NoSQL数据库来存储图片的元数据和其在分布式文件系统或对象存储中的位置。
当你希望基于图片内容本身进行检索(例如查找与给定图片相似的图片)时:
- 使用特征提取技术从每张图片中提取特征,并使用这些特征为图片建立索引。
- 一种常见的方法是使用哈希函数将图片特征转化为“图像哈希”,并将这些哈希值存储在数据库中。
-
加速查询:
- 缓存:对于经常被查询的图片,可以使用像 Redis 这样的内存数据库进行缓存,以减少对主存储的访问。
- 数据库索引:确保数据库表中用于查询的字段都已经建立了索引。
- 减少数据量:通过数据分片或选择性地只查询某些数据,可以加速查询速度。
- 内容检索优化:对于基于内容的检索,可以使用近似最近邻搜索(ANNS)库,如 FAISS,以加速相似度搜索。
-
其他加速技术:
- CDN:使用内容分发网络(CDN)可以将图片缓存到全球各地,从而加速对图片的访问速度。
- 预加载技术:根据用户的使用模式和行为,预先加载他们可能会访问的图片。
- 图片压缩:通过减少图片的大小,可以加速加载速度和减少存储需求。
-
搜索扩展性:
如果搜索请求量非常大,可以考虑使用分布式搜索引擎,如 Elasticsearch 或 Solr,它们提供了分布式搜索能力,易于扩展,并支持复杂的查询。
总之,选择哪种方法取决于具体的使用场景,例如查询的频率、数据量、预算等。
方案二
是的,使用云存储来存放图片是现代应用中的常见做法,尤其是当应用需要可扩展的存储和全球分布时。以下是这种方法的详细步骤:
-
上传到云存储:
- 用户或应用将图片上传到云存储服务,如 Amazon S3、Google Cloud Storage 或 Azure Blob Storage。
- 这些服务通常会为每个上传的文件提供一个唯一的URL。
-
存储URL:
- 上传成功后,将从云服务获得的URL存储在本地数据库中。这个数据库可以是关系型数据库、NoSQL数据库等。
- 可以存储与图片相关的其他元数据,如上传日期、标签和描述等。
-
查询与检索:
- 当用户或应用需要查询图片时,你可以查询本地数据库并返回相关的URL。
- 用户或应用可以直接使用这些URL从云存储服务下载图片。
-
加速查询:
- 数据库缓存:像 Redis 这样的内存数据库可以用来缓存热门的图片URL。
- CDN:考虑使用内容分发网络服务,这样热门的图片可以缓存在全球各地的边缘位置,从而减少加载时间。
-
安全与权限:
- 云存储服务通常提供详细的权限和安全设置。确保只有授权的用户可以上传或访问图片。
- 如果需要,可以为URL设置过期时间,这样它们在某段时间后就不能再访问了。
这种设计方案不仅可以扩展存储,还可以通过利用云服务的全球网络来提高访问速度,同时,通过将存储与处理解耦,还可以简化应用的架构和维护。
7 讲解了我怎么设计负载均衡算法的,以及每种策略的适用场景
负载均衡的目的是将网络流量分散到多个服务器,以确保每个服务器都不会因超载而宕机,并且可以最大化吞吐量、最小化响应时间并避免任何单一点的故障。以下是一些常用的负载均衡策略,以及各自的适用场景:
-
轮询 (Round Robin)
- 策略:这是最简单的负载均衡算法,请求按顺序分配到服务器。如果服务器列表到达末尾,则重新开始。
- 适用场景:当所有服务器都具有相似的规格并且预期的请求处理时间相似时,轮询是一个好选择。
-
加权轮询 (Weighted Round Robin)
- 策略:与轮询相似,但给每个服务器一个权重,权重较高的服务器会接收到更多的请求。
- 适用场景:当你有不同能力的服务器并希望每台服务器都接收到与其能力相称的流量时。
-
最少连接 (Least Connections)
- 策略:将请求路由到连接数最少的服务器。
- 适用场景:适用于服务器处理速度大致相同,但处理请求的时间可以变化的场景。例如,如果有一个长轮询或Websockets服务。
-
加权最少连接 (Weighted Least Connections)
- 策略:与最少连接类似,但考虑到每个服务器的权重。
- 适用场景:当服务器规格和处理速度不同时,且处理请求的时间可变。
-
IP哈希 (IP Hash)
- 策略:基于请求者的IP地址确定应该路由到哪个服务器。通常是通过取IP的哈希值然后对服务器数取模得到的。
- 适用场景:当你希望来自特定IP的客户端始终连接到同一个服务器,这在需要保持会话或某些级联数据缓存时非常有用。
-
URL哈希 (URL Hash)
- 策略:基于请求URL的哈希值来确定路由到哪个服务器。
- 适用场景:特别适用于HTTP缓存服务器,因为请求的相同URL可以确保路由到包含其缓存的同一服务器。
-
最短延迟 (Least Latency)
- 策略:负载均衡器持续检测每台服务器的延迟或响应时间,并将请求路由到响应最快的服务器。
- 适用场景:对于需要实时或快速响应的应用,如在线游戏或语音通信。
-
健康检查
- 策略:定期检查服务器的健康状况,如果服务器未响应或返回错误,它将从活动服务器池中移除,直至再次被确定为健康。
- 适用场景:适用于任何需要高可用性的应用。
根据你的应用类型、服务器规格和预期的流量模式选择合适的策略是关键。很多现代的负载均衡器都支持这些策略,并允许你基于实时流量模式动态地切换策略。
8 注册中心能否处理容灾情况,这里的灾是指哪些
注册中心是微服务架构中的一个核心组件,它负责为服务提供发现和配置功能。如果注册中心发生故障,可能会对整个系统的正常运行产生巨大影响。因此,确保其高可用性和对各种“灾难”情况的容错能力是至关重要的。
以下是一些可能影响注册中心的“灾难”情况:
- 硬件故障:如服务器、存储或网络设备的物理故障。
- 软件故障:软件缺陷、资源耗尽(例如内存溢出)、不正确的配置等。
- 网络问题:网络分区、延迟、抖动或连接中断等。
- 数据中心故障:如火灾、洪水、电力中断或其他自然灾害。
- 安全事件:如DDoS攻击、恶意软件感染、未经授权的访问或数据泄露。
- 人为错误:如误删除数据、误配置或发布有缺陷的代码。
为了处理这些容灾情况,可以采取以下策略:
- 多实例部署:在不同的物理服务器上运行多个注册中心的实例,确保一个实例故障时,其他实例可以继续提供服务。
- 跨区域部署:在地理位置分散的多个数据中心部署注册中心的实例,确保某一地区的灾难不会影响整体系统。
- 数据持久化:定期将注册中心的数据(例如服务列表、配置数据等)备份到持久存储,以便在故障发生时进行恢复。
- 网络冗余:确保有多条网络路径可供使用,以避免单点故障。
- 安全策略:实施防火墙、入侵检测系统、流量限制和其他安全措施,以防止恶意攻击。
- 监控和报警:持续监控注册中心的健康状况,并在检测到故障时立即发出报警。
- 故障转移和恢复:当检测到故障时,自动将流量切换到健康的注册中心实例,并启动恢复过程。
具体的容灾策略会根据所使用的注册中心软件(如Eureka、Consul、Zookeeper等)和组织的需求有所不同。总之,设计一个高可用和容错的注册中心是确保微服务系统稳定运行的关键。
相关文章:

系统设计类题目汇总
1 设计一个系统统计当前时刻北京用户在线人数 【Redis】位图以及位图的使用场景(统计在线人数和用户在线状态) 1.1 方案一: 在用户登录时,使用 Redis SET 将用户 ID 添加到一个特定的键(例如 “online:beijing”)。用户退出时&…...

css滚动条样式指南
css滚动条样式指南 滚动条是网页设计中经常被忽视的元素。虽然它看起来像是一个小细节,但它在网站导航中起着至关重要的作用。默认的滚动条可能看起来不合适,有损整体美观。本文将介绍如何使用 CSS 自定义滚动条。 在 Chrome、Edge 和 Safari 中设置滚…...

vue子组件修改父组件传递的变量(自定义日期时间组件,时间间隔为15分钟或者一个小时)
vue子组件修改父组件传递的变量 子组件不能直接修改父组件变量的值,但是可以通过调用父组件的方法来修改。 实现步骤 在父组件声明变量 export default {data() {return {startTime:"",......},......} }在父组件使用子组件并传递数据,修改…...

【PyTorch】nn.Conv2d函数详解
nn.Conv2d 是 PyTorch 中的一个卷积层,用于实现二维卷积操作 torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride1, padding0, dilation1, groups1, biasTrue, padding_modezeros, deviceNone, dtypeNone )参数解释 in_channels:输入的通…...

数智保险 创新未来 | GBASE南大通用亮相中国保险科技应用高峰论坛
本届峰会以“数智保险 创新未来”为主题,GBASE南大通用携新一代创新数据库产品及金融信创解决方案精彩亮相,与国内八百多位保险公司高管和众多保险科技公司技术专家,就保险领域数字化的创新应用及生态建设、新一代技术突破及发展机遇、前沿科…...

分布式天梯图算法在 Redis 图数据库中的应用
分布式天梯图算法在 Redis 图数据库中的应用 一、简介1 天梯图算法2 天梯图算法在Redis的应用 二、Redis分布式天梯图算法设计与优化1 基于天梯图的分布式算法设计2 多节点扩展与负载均衡优化3 数据存储方案与压缩策略 三、技术实现3.1 系统架构设计3.2 技术选型3.3 关键实现细…...

观察者模式——对象间的联动
1、简介 1.1、概述 在软件系统中,有些对象之间也存在类似交通信号灯和汽车之间的关系。一个对象的状态或行为的变化将导致其他对象的状态或行为也发生改变,它们之间将产生联动,正所谓“触一而牵百发”。为了更好地描述对象之间存在的这种一…...

【雕爷学编程】Arduino动手做(189)---特别苗条,使用微波传感器控制的纤细小车
装修屋子,找了一段墙面布线槽,外槽宽度只有23毫米,截取一段长为24厘米,尝试做个苗条小车 先在线槽上安装了二只N20小电机 装上二个快餐盒盖做轮子 测试一下使用3.7V锂电池的动力系统(视频) https://v.youk…...

机器学习基础算法及其实现
线性回归 知识点: 1. 线性回归模型可以使用不同的目标函数,最常用的是最小二乘法、最小绝对值法和最大似然法。 2. 在最小二乘法中,目标是最小化实际值与预测值之间的误差平方和,这可以通过求导数等方法来求解。 3. 在最小绝对值…...

docker安装MinIO
简介 Minio 是一个面向对象的简单高性能存储服务。使用 Go 语言编写,性能高、具有跨平台性。 Minio 官网为:https://min.io ,有一个中文站点,单内容更新不是很及时,建议从原始官网学习。 本文采用 Docker 安装&…...

第5章 运算符、表达式和语句
本章介绍以下内容: 关键字:while、typedef 运算符:、-、*、/、%、、--、(类型名) C语言的各种运算符,包括用于普通数学运算的运算符 运算符优先级以及语句、表达式的含义 while循环 复合语句、自动类型转换和强制类型转换 如何编写…...

24考研数据结构-图的存储结构邻接矩阵
目录 6.3 储存结构(邻接表表示法)1. 储存方式2. 结构3. 图的邻接表存储表示(算法)4. 结论5. 邻接矩阵和邻接表的对比邻接矩阵优点:缺点: 邻接表优点:缺点: 邻接矩阵与邻接表的关系 6…...

在线推算两个日期相差天数的计算器
具体请前往:在线推算两个日期相差天数的计算器...

Spring源码解析(七):bean后置处理器AutowiredAnnotationBeanPostProcessor
Spring源码系列文章 Spring源码解析(一):环境搭建 Spring源码解析(二):bean容器的创建、默认后置处理器、扫描包路径bean Spring源码解析(三):bean容器的刷新 Spring源码解析(四):单例bean的创建流程 Spring源码解析(五)&…...

【C#学习笔记】引用类型(1)
文章目录 引用类型class匿名类 记录引用相等和值相等record声明 接口delegate 委托合并委托/多路广播委托 引用类型 引用类型的变量存储对其数据(对象)的引用,而值类型的变量直接包含其数据。 对于引用类型,两种变量可引用同一对…...

STM32CubeMX+VSCODE+EIDE+RT-THREAD 工程创建
Eide环境搭建暂且不表,后续补充。主要记录下Vscode环境下 创建Rt-thread工程的过程。分别介绍STM32CubeMX添加rtt支持包的方式和手动添加rtt kernel方式。STM32CubeMX生成工程的时候有"坑",防止下次忘记,方便渡一下有缘人ÿ…...

java中javamail发送带附件的邮件实现方法
java中javamail发送带附件的邮件实现方法 本文实例讲述了java中javamail发送带附件的邮件实现方法。分享给大家供大家参考。具体分析如下: JavaMail,顾名思义,提供给开发者处理电子邮件相关的编程接口。它是Sun发布的用来处理email的API。它…...

Stable Diffusion高阶技能(2)-稳定扩散百态:解密AI绘画工具「SD WebUI」的提示词高级使用策略
简介 在我们的生活中,艺术元素可谓无处不在,而处于中心地位的绘画,无疑是携带着强烈的艺术魅力。现如今随着AI技术的日新月异,AI绘画对我们的生活世界的改造影响越来越深远。那么,如何让我们在AI绘画工具中更好的指导AI完成我们心中的作品呢? 这需要我们玩转这个工具的…...

【果树农药喷洒机器人】Part2:机器人变量喷药系统硬件选型
本专栏介绍:付费专栏,持续更新机器人实战项目,欢迎各位订阅关注。 关注我,带你了解更多关于机器人、嵌入式、人工智能等方面的优质文章! 文章目录 一、引言二、变量喷药系统总体要求2.1系统功能要求2.2系统技术要求三、机器人关键硬件选型3.1深度相机概述与选型3.2单片机选…...

解决vite+vue3项目npm装包失败
报错如下: Failed to remove some directories [ npm WARN cleanup [ npm WARN cleanup D:\\V3Work\\v3project\\node_modules\\vue, npm WARN cleanup [Error: EPERM: operation not permitted, rmdir D:\V3Work\v3project\node_modules\vue\reactivity\…...

Rust之错误处理
在Rust中,将错误分为两种,可恢复错误和不可恢复错误。所谓可恢复错误就是指类似于文件未找到这类错误,一般需要将它们报告给用户并再次尝试进行操作,而不可恢复错误往往就是Bug,需要停止程序的运行。 1、不可恢复错误…...

docker compose快速编排
Docker-compose概述 Docker-Compose项目是Docker官方的开源项目,负责实现对Docker容集群的快速编排 Docker-Compose将所管理的容器分为三层,分别是工程(project),服务(service)以及容器&#x…...

java.io.File类的使用
文章目录 概述构造器常用方法1、获取文件和目录基本信息2、列出目录的下一级3.File类的重命名功能4、判断功能的方法5、创建、删除功能 练习 概述 File类及本章下的各种流,都定义在java.io包下。一个File对象代表硬盘或网络中可能存在的一个文件或者文件目录&#…...

TypeScript技能总结(三)
typescript是js的超集,目前很多前端框架都开始使用它来作为项目的维护管理的工具,还在不断地更新,添加新功能中,我们学习它,才能更好的在的项目中运用它,发挥它的最大功效 //泛型 > 参数和返回值类型相…...
python绿色版运行程序,python 绿色版免安装
大家好,小编来为大家解答以下问题,python绿色版运行程序,python 绿色版免安装,今天让我们一起来看看吧! 软件简介 Python3.7.0 是一种被广大从业者广泛使用的通用型设计语言。该软件提供了丰富全面的模块,并…...

Python 向Excel写数据
1.项目终端导入 xlwt 库 pip install xlwt2.导入依赖包 import xlwt3.创建Excel表格类型文件 调用xlwt模块中的Workbook方法来创建一个excel表格类型文件,其中的第一个参数是设置数据的编码格式,这里是’utf-8’的形式,style_compression设…...

MySQL(1)
MySQL创建数据库和创建数据表 创建数据库 1. 连接 MySQL mysql -u root -p 2. 查看当前的数据库 show databases; 3. 创建数据库 create database 数据库名; 创建数据库 4. 创建数据库时设置字符编码 create database 数据库名 character set utf8; 5. 查看和显示…...

Android10 Recovery系列(二)增加OTG升级功能
一 、背景 起因是遇到了客户有这个需求,本着了解的原则,去看了一下之前Android版本的代码,想看看之前有没有现成的实现,移植过来。结果很不幸,没有找到。于是自己开始了功能实现的过程。下面分享一下该功能的实现 二 、准备工作 首先简单了解一下Recovery 模块的系统升…...

el-popover使用自定义图标
使用el-popover实现鼠标点击或浮动到自定义图标上弹出表格弹窗,官方文档上使用的是按钮el-button,如果想换成图标或其他的组件的话直接把el-button替换掉即可。注意替换之后的组件一定要加slot“reference”,不然组件是显示不出来的。 代码如…...

KCOM4串口转键鼠控制线测试说明
1.KOCM4介绍 KCOM4是一款最新开发的串口转键盘鼠标控制线,采用32位内核,最大60Mhz的工作频率,完美适用于游戏挂机等应用场景(如果是用在工作电脑控制或展厅电脑控制推荐CH9329双头线)。KCOM4支持普通键盘、相对鼠标、…...