Redis分布式缓存面试题(2025.3.1更新)

为什么使用分布式缓存?

1. 提升性能

  • 降低延迟:将数据缓存在离应用更近的地方,减少数据访问时间。
  • 减轻数据库压力:缓存频繁访问的数据,减少对后端数据库的请求,提升系统响应速度。

2. 扩展性

  • 水平扩展:通过增加节点,分布式缓存可以轻松扩展,处理更大规模的数据和请求。
  • 负载均衡:数据分布在不同节点上,避免单点瓶颈,提升系统整体吞吐量。

3. 高可用性

  • 容错能力:即使某个节点故障,其他节点仍能继续提供服务,确保系统稳定运行。
  • 数据冗余:通过数据复制,防止单点故障导致的数据丢失。

4. 支持高并发

  • 应对大量请求:分布式缓存能有效处理高并发场景,确保系统在高负载下仍能快速响应。

为什么使用Redis做分布式缓存?

1. 高性能

  • 内存存储,读写速度快。
  • 单线程模型,避免竞争问题,支持高并发。

2. 丰富的数据结构

  • 支持字符串、哈希、列表、集合、有序集合等。

3. 持久化支持

  • RDB 快照和 AOF 日志,确保数据不丢失。

4. 高可用性

  • 主从复制、哨兵模式、集群模式。

5. 分布式支持

  • Redis Cluster 支持数据分片和动态扩展。

6. 丰富的功能

  • Lua 脚本、过期机制、发布/订阅、事务。

面对缓存穿透问题,有什么解决办法?

1. 缓存空值

  • 将空结果缓存,设置较短过期时间。

2. 布隆过滤器

  • 快速判断数据是否存在,过滤无效请求。

3. 缓存预热

  • 提前加载热点数据到缓存。

4. 限流和降级

  • 限制请求量或返回默认值。

数据库更新时布隆过滤器的同步方案

1. 定期重新建布隆过滤器

  • 定期(每天或每小时)重新加载数据库中的有效键构建布隆过滤器。

2. 使用计数布隆过滤器

  • 通过对每个key进行计数,支持动态删除和更新。

3. 结合缓存

  • 通过缓存和布隆过滤器的组合实现实时更新。

4. 使用布隆过滤器的变种

  • 如 Scalable Bloom Filter,适合动态数据量。

介绍一下分层布隆过滤器Scalable Bloom Filter

Scalable Bloom Filter 是布隆过滤器的一种变体,旨在解决传统布隆过滤器在数据量动态增长时的局限性。传统布隆过滤器需要预先设定容量,如果实际数据量超过预设容量,误判率会显著增加。而 Scalable Bloom Filter 可以动态扩展,适应数据量的增长。


Scalable Bloom Filter 的核心思想

  1. 分层设计

    • Scalable Bloom Filter 由多个布隆过滤器层(Layer)组成。
    • 每一层都是一个独立的布隆过滤器,容量和误判率可以单独设置。
    • 当某一层的容量接近饱和时,会自动创建新的层。
  2. 动态扩展

    • 当数据量增加时,新的数据会被添加到最新的层中。
    • 查询时,会依次检查每一层,直到找到匹配的层或确认数据不存在。
  3. 误判率控制

    • 每一层的误判率可以单独设置,通常随着层数的增加,误判率逐渐降低。
    • 整体误判率是所有层误判率的累积结果。

Scalable Bloom Filter 的优点

  1. 动态扩容:无需预先设定容量,适合数据量动态增长的场景。
  2. 误判率可控:通过分层设计,可以有效控制整体误判率。
  3. 灵活性高:可以根据需求调整每一层的容量和误判率。

Scalable Bloom Filter 的缺点

  1. 内存占用较高:由于分层设计,每一层都需要独立的内存空间。
  2. 查询性能稍低:查询时需要依次检查每一层,性能略低于单层布隆过滤器。
  3. 实现复杂度较高:需要管理多个布隆过滤器层。

Java 实现

以下是 Scalable Bloom Filter 的简单实现:

import com.google.common.hash.BloomFilter;
import com.google.common.hash.Funnels;
import java.util.ArrayList;
import java.util.List;public class ScalableBloomFilter {private List<BloomFilter<String>> filters; // 布隆过滤器层private int layerCapacity; // 每一层的容量private double falsePositiveRate; // 每一层的误判率public ScalableBloomFilter(int layerCapacity, double falsePositiveRate) {this.filters = new ArrayList<>();this.layerCapacity = layerCapacity;this.falsePositiveRate = falsePositiveRate;addLayer(); // 初始化第一层}/*** 添加一个新层*/private void addLayer() {BloomFilter<String> newLayer = BloomFilter.create(Funnels.stringFunnel(), layerCapacity, falsePositiveRate);filters.add(newLayer);}/*** 添加一个元素*/public void add(String value) {// 如果当前层已满,添加新层if (filters.get(filters.size() - 1).approximateElementCount() >= layerCapacity) {addLayer();}// 将元素添加到最新的层filters.get(filters.size() - 1).put(value);}/*** 检查元素是否存在*/public boolean mightContain(String value) {// 依次检查每一层for (BloomFilter<String> filter : filters) {if (filter.mightContain(value)) {return true;}}return false;}/*** 获取当前层数*/public int getLayerCount() {return filters.size();}
}

使用示例

public class ScalableBloomFilterExample {public static void main(String[] args) {ScalableBloomFilter scalableBloomFilter = new ScalableBloomFilter(1000, 0.01);// 添加元素scalableBloomFilter.add("key1");scalableBloomFilter.add("key2");// 检查元素是否存在System.out.println("Contains key1: " + scalableBloomFilter.mightContain("key1")); // trueSystem.out.println("Contains key3: " + scalableBloomFilter.mightContain("key3")); // false// 获取当前层数System.out.println("Layer count: " + scalableBloomFilter.getLayerCount()); // 1}
}

Scalable Bloom Filter 的应用场景

  1. 动态数据量场景:如实时日志处理、用户行为分析等。
  2. 分布式系统:如分布式缓存、分布式数据库的去重。
  3. 大数据处理:如海量数据的快速过滤和查询。

总结

Scalable Bloom Filter 通过分层设计和动态扩展,解决了传统布隆过滤器在数据量动态增长时的局限性。它的核心优势在于:

  1. 动态扩容:无需预先设定容量。
  2. 误判率可控:通过分层设计控制整体误判率。
  3. 灵活性高:适合数据量动态变化的场景。

Redis分布式缓存如何判断热点数据?

1. 基于访问频率

  • 原理:通过统计每个键的访问频率(如每秒访问次数),识别出访问频率最高的数据。
  • 实现方法
    • 使用 Redis 的 INCR 命令或监控工具(如 Redis Monitor)统计键的访问频率。
    • 使用 Lua 脚本或客户端代码记录每个键的访问次数。

Java 实现

import redis.clients.jedis.Jedis;public class HotKeyDetector {private Jedis jedis;public HotKeyDetector(Jedis jedis) {this.jedis = jedis;}public void trackAccess(String key) {// 使用 Redis 的计数器记录每个键的访问次数jedis.incr("access_count:" + key);}public String getMostFrequentKey() {// 获取所有键的访问计数Set<String> keys = jedis.keys("access_count:*");String hotKey = null;long maxCount = 0;for (String key : keys) {long count = Long.parseLong(jedis.get(key));if (count > maxCount) {maxCount = count;hotKey = key.replace("access_count:", "");}}return hotKey;}
}

2. 基于时间窗口

  • 原理:在特定的时间窗口内(如最近 1 分钟)统计键的访问频率,识别出热点数据。
  • 实现方法
    • 使用 Redis 的 ZSET(有序集合)记录每个键的访问时间戳。
    • 定期清理过期的访问记录,并统计时间窗口内的访问次数。

Java 实现

import redis.clients.jedis.Jedis;public class TimeWindowHotKeyDetector {private Jedis jedis;private static final long WINDOW_SIZE = 60000; // 时间窗口大小(1 分钟)public TimeWindowHotKeyDetector(Jedis jedis) {this.jedis = jedis;}public void trackAccess(String key) {long currentTime = System.currentTimeMillis();// 使用 ZSET 记录访问时间戳jedis.zadd("access_times:" + key, currentTime, String.valueOf(currentTime));// 清理时间窗口之外的数据jedis.zremrangeByScore("access_times:" + key, 0, currentTime - WINDOW_SIZE);}public String getMostFrequentKey() {Set<String> keys = jedis.keys("access_times:*");String hotKey = null;long maxCount = 0;for (String key : keys) {long count = jedis.zcard(key);if (count > maxCount) {maxCount = count;hotKey = key.replace("access_times:", "");}}return hotKey;}
}

3. 基于采样统计

  • 原理:通过采样部分请求,统计键的访问频率,推断出热点数据。
  • 实现方法
    • 使用 Redis 的 MONITOR 命令或客户端代码采样请求。
    • 对采样数据进行分析,识别出高频访问的键。

4. 使用 Redis 模块(如 RedisGears)

  • 原理:利用 RedisGears 这样的扩展模块,实时监控和分析键的访问模式。
  • 实现方法
    • 编写 RedisGears 脚本,统计键的访问频率并输出热点数据。

5. 基于外部监控工具

  • 原理:使用外部监控工具(如 Prometheus、Grafana)收集 Redis 的访问数据,并通过可视化或分析工具识别热点数据。
  • 实现方法
    • 配置 Redis 的监控插件,将访问数据导出到监控工具。
    • 在监控工具中设置告警规则或分析报告。

总结

判断 Redis 分布式缓存中的热点数据可以通过以下方法:

  1. 基于访问频率:统计每个键的访问次数。
  2. 基于时间窗口:统计特定时间窗口内的访问频率。
  3. 基于采样统计:通过采样请求推断热点数据。
  4. 使用 Redis 模块:如 RedisGears 实时监控。
  5. 基于外部监控工具:如 Prometheus、Grafana。

Redis分布式缓存如何进行数据预热?

数据预热是指在系统启动或流量高峰到来之前,提前将热点数据加载到缓存中,以避免大量请求直接访问数据库,从而提升系统性能和稳定性。


1. 手动预热

人为指定热key,将数据加载到缓存中

  • 原理:在系统启动或流量高峰前,通过脚本或工具手动将热点数据加载到 Redis 中。
  • 优点:简单直接,适合数据量较小或热点数据明确的场景。
  • 缺点:需要人工干预,无法自动化。

Java 实现

import redis.clients.jedis.Jedis;public class DataPreheating {private Jedis jedis;public DataPreheating(Jedis jedis) {this.jedis = jedis;}public void preheatData() {// 模拟从数据库加载热点数据String[] hotKeys = {"key1", "key2", "key3"};for (String key : hotKeys) {String value = loadFromDatabase(key);jedis.set(key, value);}}private String loadFromDatabase(String key) {// 模拟数据库查询return "value_for_" + key;}
}

2. 基于历史访问记录的预热

系统自动读取热key,不需要人为指定

  • 原理:根据历史访问记录(如日志或监控数据),识别出热点数据,并在系统启动时加载到 Redis 中。
  • 优点:基于实际访问数据,预热效果较好。
  • 缺点:需要收集和分析历史数据,实现复杂度较高。

Java 实现

import redis.clients.jedis.Jedis;
import java.util.List;public class HistoricalDataPreheating {private Jedis jedis;public HistoricalDataPreheating(Jedis jedis) {this.jedis = jedis;}public void preheatData() {// 从历史访问记录中获取热点数据List<String> hotKeys = getHotKeysFromLogs();for (String key : hotKeys) {String value = loadFromDatabase(key);jedis.set(key, value);}}private List<String> getHotKeysFromLogs() {// 模拟从日志中分析热点数据return List.of("key1", "key2", "key3");}private String loadFromDatabase(String key) {// 模拟数据库查询return "value_for_" + key;}
}

3. 基于定时任务的预热

定期自动加载热点数据,热点数据可通过访问频率,时间范围等自动计算

  • 原理:通过定时任务(如 Cron Job 或 Quartz)定期将热点数据加载到 Redis 中。
  • 优点:自动化程度高,适合数据变化较频繁的场景。
  • 缺点:需要配置定时任务,可能增加系统复杂性。

Java 实现

import redis.clients.jedis.Jedis;
import java.util.Timer;
import java.util.TimerTask;public class ScheduledDataPreheating {private Jedis jedis;public ScheduledDataPreheating(Jedis jedis) {this.jedis = jedis;}public void startPreheating() {Timer timer = new Timer();timer.schedule(new TimerTask() {@Overridepublic void run() {preheatData();}}, 0, 60 * 60 * 1000); // 每小时执行一次}private void preheatData() {// 模拟从数据库加载热点数据String[] hotKeys = {"key1", "key2", "key3"};for (String key : hotKeys) {String value = loadFromDatabase(key);jedis.set(key, value);}}private String loadFromDatabase(String key) {// 模拟数据库查询return "value_for_" + key;}
}

4. 基于消息队列的预热

详细方案可参考此篇: 数据库与缓存一致性方案

  • 原理:当数据库中的数据发生变化时,通过消息队列(如 Kafka、RabbitMQ)通知缓存系统更新数据。
  • 优点:实时性高,适合数据变化频繁的场景(如商品上架,提前将信息预热到缓存中)。
  • 缺点:需要引入消息队列组件,增加系统复杂性。

Java 实现

import redis.clients.jedis.Jedis;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;public class MessageQueuePreheating {private Jedis jedis;private BlockingQueue<String> messageQueue;public MessageQueuePreheating(Jedis jedis) {this.jedis = jedis;this.messageQueue = new LinkedBlockingQueue<>();startConsumer();}public void onDataChange(String key) {// 当数据库数据变化时,将 key 放入消息队列messageQueue.offer(key);}private void startConsumer() {new Thread(() -> {while (true) {try {String key = messageQueue.take();String value = loadFromDatabase(key);jedis.set(key, value);} catch (InterruptedException e) {Thread.currentThread().interrupt();break;}}}).start();}private String loadFromDatabase(String key) {// 模拟数据库查询return "value_for_" + key;}
}

5. 基于缓存淘汰策略的预热

没淘汰的key默认为热点数据

  • 原理:通过 Redis 的缓存淘汰策略(如 LRU、LFU),在缓存中保留热点数据。
  • 优点:无需额外操作,Redis 自动管理热点数据。
  • 缺点:无法精确控制预热数据。

配置 Redis 淘汰策略

在 Redis 配置文件中设置:

maxmemory-policy allkeys-lfu
  • allkeys-lfu:淘汰访问频率最低的键。
  • allkeys-lru:淘汰最近最少使用的键。

总结

Redis 分布式缓存的数据预热可以通过以下方法实现:

  1. 手动预热:适合数据量较小或热点数据明确的场景。
  2. 基于历史访问记录的预热:根据历史数据加载热点数据。
  3. 基于定时任务的预热:定期加载热点数据,适合数据变化频繁的场景。
  4. 基于消息队列的预热:实时更新缓存,适合数据变化频繁的场景。
  5. 基于缓存淘汰策略的预热:利用 Redis 的淘汰策略自动管理热点数据。

介绍一下Redis的几种数据结构、用途及原理

数据结构用途原理常用命令示例
字符串(String)存储简单键值对,如用户信息、配置项、计数器等。动态字符串(SDS),支持动态调整长度。SET key valueGET keyINCR key
哈希(Hash)存储对象或结构化数据,如用户信息、商品信息等。使用 ziplisthashtable 存储键值对。HSET key field valueHGET key fieldHGETALL key
列表(List)实现队列、栈等数据结构,适合存储有序数据。使用 ziplistlinkedlist 存储双向链表。LPUSH key valueRPUSH key valueLPOP keyRPOP key
集合(Set)存储不重复元素,适合去重、交集、并集等操作。使用 intsethashtable 存储唯一元素。SADD key memberSREM key memberSINTER key1 key2
有序集合(Sorted Set)存储有序且不重复的元素,适合排行榜、优先级队列等场景。使用跳跃表和哈希表实现,支持快速范围查询和排序。ZADD key score memberZRANGE key start stopZREM key member
位图(Bitmap)存储二进制位,适合实现布隆过滤器、用户签到等功能。基于字符串实现,每个位只能是 0 或 1。SETBIT key offset valueGETBIT key offsetBITCOUNT key
地理空间索引(Geospatial Index)存储地理位置信息,支持范围查询、距离计算等操作。使用有序集合存储,地理位置信息映射到分数。GEOADD key longitude latitude memberGEODIST key member1 member2
HyperLogLog用于基数统计(去重计数),适合统计独立访客数(UV)等场景。使用概率算法估算基数,误差率约为 0.81%。PFADD key elementPFCOUNT keyPFMERGE destkey sourcekey1 sourcekey2

1. 字符串(String)

用途

  • 存储简单的键值对,如用户信息、配置项、计数器等。
  • 支持原子操作,适合实现计数器、分布式锁等功能。

原理

  • Redis 的字符串是动态字符串(Simple Dynamic String, SDS),可以动态调整长度。
  • SDS 的结构包括:
    • len:字符串的长度。
    • free:未使用的空间。
    • buf:存储实际数据的字节数组。

常用命令

  • SET key value:设置键值对。
  • GET key:获取键对应的值。
  • INCR key:将键的值加 1(原子操作)。

2. 哈希(Hash)

用途

  • 存储对象或结构化数据,如用户信息、商品信息等。
  • 适合存储字段较多的对象,可以单独操作某个字段。

原理

  • Redis 的哈希是一个键值对集合,底层使用两种编码方式:
    • ziplist:当哈希元素较少且字段值较小时,使用压缩列表存储。
    • hashtable:当哈希元素较多或字段值较大时,使用哈希表存储。

常用命令

  • HSET key field value:设置哈希字段的值。
  • HGET key field:获取哈希字段的值。
  • HGETALL key:获取哈希的所有字段和值。

3. 列表(List)

用途

  • 实现队列、栈等数据结构。
  • 适合存储有序数据,如消息队列、最新消息列表等。

原理

  • Redis 的列表是一个双向链表,支持在头部和尾部快速插入和删除元素。
  • 底层使用两种编码方式:
    • ziplist:当列表元素较少且元素值较小时,使用压缩列表存储。
    • linkedlist:当列表元素较多或元素值较大时,使用双向链表存储。

常用命令

  • LPUSH key value:在列表头部插入元素。
  • RPUSH key value:在列表尾部插入元素。
  • LPOP key:从列表头部弹出元素。
  • RPOP key:从列表尾部弹出元素。

4. 集合(Set)

用途

  • 存储不重复的元素,适合去重、交集、并集等操作。
  • 常用于标签系统、好友关系等场景。

原理

  • Redis 的集合是一个无序的、元素唯一的集合。
  • 底层使用两种编码方式:
    • intset:当集合元素较少且元素为整数时,使用整数集合存储。
    • hashtable:当集合元素较多或元素为非整数时,使用哈希表存储。

常用命令

  • SADD key member:向集合中添加元素。
  • SREM key member:从集合中移除元素。
  • SINTER key1 key2:求两个集合的交集。

5. 有序集合(Sorted Set)

用途

  • 存储有序且不重复的元素,适合排行榜、优先级队列等场景。
  • 每个元素关联一个分数(score),根据分数排序。

原理

  • Redis 的有序集合使用跳跃表(Skip List)和哈希表实现。
    • 跳跃表用于支持快速的范围查询和排序。
    • 哈希表用于快速查找元素。

常用命令

  • ZADD key score member:向有序集合中添加元素。
  • ZRANGE key start stop:获取指定范围内的元素。
  • ZREM key member:从有序集合中移除元素。

6. 位图(Bitmap)

用途

  • 存储二进制位,适合实现布隆过滤器、用户签到等功能。
  • 节省内存,适合存储大量布尔值。

原理

  • Redis 的位图是基于字符串实现的,每个位只能是 0 或 1。
  • 通过位操作(如 AND、OR、XOR)实现复杂的逻辑。

常用命令

  • SETBIT key offset value:设置位的值。
  • GETBIT key offset:获取位的值。
  • BITCOUNT key:统计值为 1 的位的数量。

7. 地理空间索引(Geospatial Index)

用途

  • 存储地理位置信息,支持范围查询、距离计算等操作。
  • 适合实现附近的人、地点搜索等功能。

原理

  • Redis 的地理空间索引使用有序集合(Sorted Set)实现。
  • 地理位置信息被编码为经纬度,并映射到有序集合的分数。

常用命令

  • GEOADD key longitude latitude member:添加地理位置信息。
  • GEODIST key member1 member2:计算两个位置之间的距离。
  • GEORADIUS key longitude latitude radius:查询指定半径内的位置。

8. HyperLogLog

用途

  • 用于基数统计(去重计数),适合统计独立访客数(UV)等场景。
  • 占用内存非常小,适合大规模数据统计。

原理

  • HyperLogLog 使用概率算法估算基数,误差率约为 0.81%。
  • 通过哈希函数将元素映射到二进制位,统计前导零的数量来估算基数。

常用命令

  • PFADD key element:向 HyperLogLog 中添加元素。
  • PFCOUNT key:估算基数。
  • PFMERGE destkey sourcekey1 sourcekey2:合并多个 HyperLogLog。

总结

Redis 的每种数据结构都有其特定的用途和实现原理:

  1. 字符串:存储简单键值对,支持原子操作。
  2. 哈希:存储结构化数据,适合对象存储。
  3. 列表:实现队列、栈等数据结构。
  4. 集合:存储不重复元素,支持集合运算。
  5. 有序集合:存储有序元素,适合排行榜等场景。
  6. 位图:存储二进制位,节省内存。
  7. 地理空间索引:存储地理位置信息,支持范围查询。
  8. HyperLogLog:用于基数统计,占用内存小。

根据具体业务场景选择合适的数据结构,可以充分发挥 Redis 的性能优势。如果你有更多问题,欢迎继续提问! 😊

明日继续更新 😊

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/27196.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Minio搭建并在SpringBoot中使用完成用户头像的上传

Minio使用搭建并上传用户头像到服务器操作,学习笔记 Minio介绍 minio官网 MinIO是一个开源的分布式对象存储服务器&#xff0c;支持S3协议并且可以在多节点上实现数据的高可用和容错。它采用Go语言开发&#xff0c;拥有轻量级、高性能、易部署等特点&#xff0c;并且可以自由…

FPGA AXI-Stream协议详解与仿真实践

AXI-Stream协议详解与仿真实践 1 摘要 AXI-Stream总线是一种高效、简单的数据传输协议,主要用于高吞吐量的数据流传输场景。相比于传统的AXI总线,AXI-Stream总线更加简单和轻量级,它通过无需地址的方式,将数据从一个模块传输到另一个模块,适用于需要高速数据传输的应用场…

浙大 DeepSeek 线上课学习笔记

目录 DeepSeek&#xff1a;回望AI三大主义与加强通识教育 从达特茅斯启航的人工智能三大主义 人工智能三剑客之一&#xff1a;符号主义人工智能的逻辑推理 人工智能三剑客之二&#xff1a;连接主义人工智能的数据驱动 人工智能三剑客之三&#xff1a;行为主义人工智能的百…

【Python机器学习】1.2. 线性回归理论:一元线性回归、最小化平方误差和公式(SSE)、梯度下降法

喜欢的话别忘了点赞、收藏加关注哦&#xff08;关注即可查看全文&#xff09;&#xff0c;对接下来的教程有兴趣的可以关注专栏。谢谢喵&#xff01;(&#xff65;ω&#xff65;) 1.2.1. 什么是回归分析(Regressive Analysis)? 一些例子 举一些例子吧&#xff1a; 下图是…

golang介绍,特点,项目结构,基本变量类型与声明介绍(数组,切片,映射),控制流语句介绍(条件,循环,switch case)

目录 golang 介绍 面向并发 面向组合 特点 项目结构 图示 入口文件 main.go 基本变量类型与声明 介绍 声明变量 常量 字符串(string) 字符串格式化 空接口类型 数组 切片 创建对象 追加元素 复制切片 map(映射) 创建对象 使用 多重赋值 控制流语句…

《白帽子讲 Web 安全》之移动 Web 安全

目录 摘要 一、WebView 简介 二、WebView 对外暴露 WebView 对外暴露的接口风险 三、通用型 XSS - Universal XSS 介绍 四、WebView 跨域访问 五、与本地代码交互 js 5.1接口暴露风险&#xff1a; 5.2漏洞利用&#xff1a; 5.3JavaScript 与 Native 代码通信 六、Chr…

算法日常刷题笔记(3)

为保持刷题的习惯 计划一天刷3-5题 然后一周总计汇总一下 这是第三篇笔记 笔记时间为2月24日到3月2日 第一天 设计有序流 设计有序流https://leetcode.cn/problems/design-an-ordered-stream/ 有 n 个 (id, value) 对&#xff0c;其中 id 是 1 到 n 之间的一个整数&#xff…

mysql5.7离线安装及问题解决

这次主要是讲解mysql5.7离线安装教程和一主一从数据库配置 1、去官网下载自己对应的mysql https://downloads.mysql.com/archives/community/2、查看需要安装mysql服务器的linux的类型 uname -a第二步看一下系统有没有安装mysql rpm -qa|grep -i mysql3、上传安装包 用远程…

JAVA实战开源项目:安康旅游网站(Vue+SpringBoot) 附源码

本文项目编号 T 098 &#xff0c;文末自助获取源码 \color{red}{T098&#xff0c;文末自助获取源码} T098&#xff0c;文末自助获取源码 目录 一、系统介绍二、数据库设计三、配套教程3.1 启动教程3.2 讲解视频3.3 二次开发教程 四、功能截图五、文案资料5.1 选题背景5.2 国内…

三数之和_算法

1.题目描述 首先我们分析下这道题目:假设给我们一个数组,让数组某三个不同下标的数相加最终得0,那么我就返回这三个数.但是如果返回的多个数组中的元素相同,那么我们还要删掉其中一个保留一个. 注意:这道题的重点是三个数的下标不能相等并且返回的数组中的元素也不能相等,通过…

关于Deepseek本地部署硬件环境检查教程

要在电脑上本地部署DeepSeek&#xff0c;需要关注以下硬件和软件配置&#xff1a; 硬件配置 CPU&#xff1a;至少4核CPU&#xff0c;推荐Intel i5/i7或AMD Ryzen 5/7系列处理器。内存&#xff1a;至少8GB DDR4内存&#xff0c;推荐16GB DDR4内存&#xff0c;对于大型模型建议…

一周一个Unity小游戏2D反弹球游戏 - 移动的弹板(鼠标版)

前言 本文将实现控制弹板移动,通过Unity的New Input System,可以支持鼠标移动弹板跟随移动,触控点击跟随移动,并且当弹板移动到边界时,弹板不会移动超过边界之外。 创建移动相关的InputAction 项目模版创建的时候默认会有一个InputAction类型的文件,名字为InputSystem_Ac…

250302-绿联NAS通过Docker配置SearXNG及适配Open-WebUI的yaml配置

A. 配置Docker中的代理 绿联NAS简单解决docker无法获取镜像-不用软路由 - 哔哩哔哩 B. 下载官网对应的镜像 群晖NAS用docker搭建SearXNG元搜索引擎_哔哩哔哩_bilibili C. 修改默认省略的参数&#xff0c;只配置Base_URL&#xff0c;删除其它默认的空缺项 searxng-docker/REA…

C++-第十九章:异常

目录 第一节&#xff1a;异常有哪些 第二节&#xff1a;异常相关关键字 2-1.抛出异常 2-2.捕获异常 2-3.异常的捕获规则 2-3-1.异常被最近的catch捕获 2-3-2.catch捕获的是异常的拷贝 2-3-3.异常为子类时&#xff0c;可以用父类引用接收 2-4.捕获任意异常 第三节&#xff1…

Redis详解(实战 + 面试)

目录 Redis 是单线程的&#xff01;为什么 Redis-Key(操作redis的key命令) String 扩展字符串操作命令 数字增长命令 字符串范围range命令 设置过期时间命令 批量设置值 string设置对象,但最好使用hash来存储对象 组合命令getset,先get然后在set Hash hash命令: h…

‘ts-node‘ 不是内部或外部命令,也不是可运行的程序

新建一个test.ts文件 let message: string = Hello World; console.log(message);如果没有任何配置的前提下,会报错’ts-node’ 不是内部或外部命令,也不是可运行的程序。 此时需要安装一下ts-node。 npm install

(十 五)趣学设计模式 之 命令模式!

目录 一、 啥是命令模式&#xff1f;二、 为什么要用命令模式&#xff1f;三、 策略模式的实现方式四、 命令模式的优缺点五、 命令模式的应用场景六、 总结 &#x1f31f;我的其他文章也讲解的比较有趣&#x1f601;&#xff0c;如果喜欢博主的讲解方式&#xff0c;可以多多支…

基于单片机的智能扫地机器人

1 电路设计 1.1 电源电路 本电源采用两块LM7805作为稳压电源&#xff0c;一块为控制电路和传感器电路供电&#xff0c;另一块单独为电机供电。分开供电这样做的好处&#xff0c;有利于减小干扰&#xff0c;提高系统稳定性。 LM7805是常用的三端稳压器件&#xff0c;顾名思义0…

【Redis学习】Redis Docker安装,自定义config文件(包括RDB\AOF setup)以及与Spring Boot项目集成

【本文内容】 第1章&#xff1a;通过Docker安装Redis&#xff0c;并自定义config文件以及mount data目录。第2章&#xff1a;介绍Redis持久化到磁盘&#xff0c;有4种方式&#xff1a;RDB / AOF / NONE / RDB AOF。第3章&#xff1a;使用Server自带的redis-cli工具连接。第4章…

【3天快速入门WPF】13-MVVM进阶

目录 1. 窗体设置2. 字体图标3. 控件模板4. 页面逻辑4.1. 不使用MVVM4.2. MVVM模式实现本篇我们开发一个基于MVVM的登录页面,用来回顾下之前学习的内容 登录页面如下: 窗体取消了默认的标题栏,调整为带阴影的圆角窗体,左侧放一张登录背景图,右边自绘了一个关闭按钮,文本框…