架构思维:缓存层场景实战_读缓存(下)
文章目录
- Pre
- 业务场景
- 缓存存储数据的时机与常见问题解决方案
- 1. 缓存读取与存储逻辑
- 2. 高并发下的缓存问题及解决方案
- 3. 缓存预热(减少冷启动问题)
- 缓存更新策略(双写问题)
- 1. 先更新缓存,再更新数据库(不推荐)
- 2. 先删除缓存,再更新数据库(不推荐)
- 3. 先更新数据库,再更新缓存(不推荐)
- 4. 先更新数据库,再删除缓存(Cache-Aside模式 推荐⭐)
- 5. 延迟双删(先删缓存→更新DB→再删缓存)(最佳实践⭐)
- 总结:如何选择缓存更新策略
- 最终建议
- 缓存高可用设计核心要点与监控方案
- 1、缓存高可用设计的5大核心要点
- 2、缓存监控关键指标与工具
- 3、总结
Pre
Java避坑案例 - 高并发场景下的分布式缓存策略
Redis - 缓存设计深度解析:穿透、并发、雪崩与热点策略
深入理解分布式技术 - 先更新数据库,还是先更新缓存
架构思维:读缓存 - 减少数据库读操作压力
业务场景
某系统商品详情页因叠加推荐、成交记录、优惠活动等功能,导致每次访问需执行数十条SQL,平均响应时间从3.61秒恶化至15.53秒。初期考虑本地缓存(如Guava),但测算发现5万商品数据需750GB内存(30节点×25GB),成本过高。最终采用分布式缓存方案,将数据集中存储(如Redis),所有服务节点共享同一缓存源,避免冗余存储,显著提升访问速度至毫秒级,同时降低硬件成本。优化后,异步加载非核心数据(如成交记录)进一步减轻实时查询压力。
技术选型完成后,开始考虑缓存的一些具体问题,先从缓存何时存储数据入手
缓存存储数据的时机与常见问题解决方案
1. 缓存读取与存储逻辑
- 先查缓存:请求到达时,优先从缓存(如Redis)读取数据。
- 缓存未命中:若数据不存在或过期,则查询数据库,并将结果写入缓存。
- 返回数据:最终返回缓存中的数据给调用方。
2. 高并发下的缓存问题及解决方案
这种逻辑唯一麻烦的地方是,当用户发来大量的并发请求时,它们会发现缓存中没有数据,那么所有请求会同时挤在第2)步,此时如果这些请求全部从数据库读取数据,就会让数据库崩溃。
数据库的崩溃可以分为3种情况。
-
1)单一数据过期或者不存在,这种情况称为缓存击穿。
解决方案:第一个线程如果发现Key不存在,就先给Key加锁,再从数据库读取数据保存到缓存中,最后释放锁。如果其他线程正在读取同一个Key值,那么必须等到锁释放后才行。关于锁的问题前面已经讲过,此处不再赘述。
-
2)数据大面积过期或者Redis宕机,这种情况称为缓存雪崩。
解决方案:设置缓存的过期时间为随机分布或设置永不过期即可。
-
3)一个恶意请求获取的Key不在数据库中,这种情况称为缓存穿透。
比如正常的商品ID是从100000到1000000(10万到100万之间的数值),那么恶意请求就可能会故意请求2000000以上的数据。这种情况如果不做处理,恶意请求每次进来时,肯定会发现缓存中没有值,那么每次都会查询数据库,虽然最终也没在数据库中找到商品,但是无疑给数据库增加了负担。这里给出两种解决办法。
①在业务逻辑中直接校验,在数据库不被访问的前提下过滤掉不存在的Key。
②针对恶意请求的Key存放一个空值在缓存中,防止恶意请求骚扰数据库。
故,总结如下:
-
缓存击穿(单一Key失效)
- 问题:热点Key失效时,大量请求同时穿透到数据库。
- 解决:加锁(如Redis分布式锁),仅允许一个线程查询DB并回填缓存,其余线程等待。
-
缓存雪崩(大量Key同时失效或Redis宕机)
- 问题:缓存大面积失效,导致数据库被压垮。
- 解决:
- 设置随机过期时间(如30分钟±5分钟)。
- 缓存永不过期,后台异步更新(如定时任务)。
-
缓存穿透(恶意查询不存在的数据)
- 问题:恶意请求查询不存在的Key,导致频繁访问DB。
- 解决:
- 业务层校验:如商品ID范围检查(100000~1000000)。
- 缓存空值:对不存在的Key存储
null
或占位符,并设置较短过期时间。
3. 缓存预热(减少冷启动问题)
上面这些逻辑都是在确保查询数据的请求已经过来后如何适当地处理,如果缓存数据找不到,再去数据库查询,最终是要占用服务器额外资源的。那么最理想的就是在用户请求过来之前把数据都缓存到Redis中。这就是缓存预热。
其具体做法就是在深夜无人访问或访问量小的时候,将预热的数据保存到缓存中,这样流量大的时候,用户查询就无须再从数据库读取数据了,将大大减小数据读取压力。
故,总结如下:
- 时机:在低峰期(如凌晨)提前加载热点数据到缓存。
- 方式:
- 定时任务扫描DB并写入缓存。
- 启动时自动加载核心数据。
缓存更新策略(双写问题)
关于缓存何时存数据的问题就讨论完了,接下来开始讨论更新缓存的问题,这部分内容因涉及双写(缓存+数据库),所以会花费一些篇幅。
- 先更新DB还是缓存?
- Cache-Aside(旁路缓存):先更新DB,再删除缓存(推荐)。
- Write-Through(写穿透):先更新缓存,再同步到DB(一致性高,但性能较低)。
- Write-Behind(写回):先更新缓存,异步刷回DB(高性能,但可能丢数据)。
在缓存更新时,我们需要考虑 数据库与缓存的一致性,同时避免 并发问题 和 性能瓶颈。以下是 5种常见的缓存更新策略,分析它们的优缺点,并给出推荐方案。
1. 先更新缓存,再更新数据库(不推荐)
对于这个组合,会遇到这种情况:假设第二步更新数据库失败了,要求回滚缓存的更新,这时该怎么办呢?Redis不支持事务回滚,除非采用手工回滚的方式,先保存原有数据,然后再将缓存更新回原来的数据,这种解决方案有些缺陷。
这里简单举个例子。
1)原来缓存中的值是a,两个线程同时更新库存。
2)线程A将缓存中的值更新成b,且保存了原来的值a,然后更新数据库。
3)线程B将缓存中的值更新成c,且保存了原来的值b,然后更新数据库。
4)线程A更新数据库时失败了,它必须回滚,那现在缓存中的值更新成什么呢?理论上应该更新成c,因为数据库中的值是c,但是,线程A里面无从获得c这个值。
如果在线程A更新缓存与数据库的整个过程中,先把缓存及数据库都锁上,确保别的线程不能更新,是否可行?当然是可行的。但是其他线程能不能读取?
假设线程A更新数据库失败回滚缓存时,线程C也加入进来,它需要先读取缓存中的值,这时又返回什么值?
看到这个场景,是不是有点儿熟悉?不错,这就是典型的事务隔离级别场景。所以就不推荐这个组合,因为此处只是需要使用一下缓存,而这个组合就要考虑事务隔离级别的一些逻辑,成本太大。接着考虑别的组合。
故, 总结如下:
流程:
- 更新缓存
- 更新数据库
问题:
- 事务回滚困难:如果数据库更新失败,缓存无法自动回滚(Redis不支持事务回滚)。
- 并发问题:
- 线程A更新缓存为
b
,线程B更新缓存为c
,最终缓存可能是b
或c
,而数据库可能是另一个值。 - 需要加锁,但会降低性能。
- 线程A更新缓存为
结论:❌ 不推荐,容易导致数据不一致。
2. 先删除缓存,再更新数据库(不推荐)
使用这种方案,即使更新数据库失败了也不需要回滚缓存。这种做法虽然巧妙规避了失败回滚的问题,却引出了两个更大的问题。
1)假设线程A先删除缓存,再更新数据库。在线程A完成更新数据库之前,后执行的线程B反而超前完成了操作,读取Key发现没有数据后,将数据库中的旧值存放到了缓存中。线程A在线程B都完成后再更新数据库,这样就会出现缓存(旧值)与数据库的值(新值)不一致的问题。
2)为了解决一致性问题,可以让线程A给Key加锁,因为写操作特别耗时,这种处理方法会导致大量的读请求卡在锁中。
以上描述的是典型的高可用和一致性难以两全的问题,如果再加上分区容错就是CAP(一致性Consistency、可用性Availability、分区容错性Partition Tolerance)了,这里不展开讨论,接下来继续讨论另外3种组合
故, 总结如下:
流程:
- 删除缓存
- 更新数据库
问题:
- 缓存与数据库不一致(旧数据问题):
- 线程A删除缓存 → 线程B查询缓存未命中 → 从DB读取旧数据并写入缓存 → 线程A更新DB,导致缓存是旧数据。
- 高并发下缓存击穿:大量请求穿透到数据库。
解决方案:
- 加锁(如分布式锁),但会影响性能。
结论:❌ 不推荐,容易导致缓存与数据库不一致。
3. 先更新数据库,再更新缓存(不推荐)
对于组合3,同样需要考虑两个问题。
1)假设第一步(更新数据库)成功,第二步(更新缓存)失败了怎么办?
因为缓存不是主流程,数据库才是,所以不会因为更新缓存失败而回滚第一步对数据库的更新。此时一般采取的做法是重试机制,但重试机制如果存在延时还是会出现数据库与缓存不一致的情况,不好处理。
2)假设两个线程同时更新同一个数据,线程A先完成了第一步,线程B先完成了第二步怎么办?线程A把值更新成a,线程B把值更新成b,此时数据库中的最新值是b,因为线程A先完成了第一步,后完成第二步,所以缓存中的最新值是a,数据库与缓存的值还是不一致,这个逻辑还是有问题的。
因此,也不建议采用这个组合
故, 总结如下:
流程:
- 更新数据库
- 更新缓存
问题:
- 缓存更新失败:如果第二步失败,缓存仍是旧数据。
- 并发问题:
- 线程A更新DB为
a
,线程B更新DB为b
→ 线程B先更新缓存为b
,线程A后更新缓存为a
,导致缓存是a
,而DB是b
。
- 线程A更新DB为
结论:❌ 不推荐,仍可能不一致。
4. 先更新数据库,再删除缓存(Cache-Aside模式 推荐⭐)
针对组合4,先看看它能不能解决组合3的第二个问题。
假设两个线程同时更新同一个数据,线程A先完成第一步,线程B先完成第二步怎么办?
线程A把值更新成a,线程B把值更新成b,此时数据库中的最新值是b,因为线程A先完成了第一步,所以第二步谁先完成已经不重要了,因为都是直接删除缓存数据。这个问题解决了。
那么,它能解决组合3的第一个问题吗?假设第一步成功,第二步失败了怎么办?
这种情况的出现概率与组合3相比明显低不少,因为删除比更新容易多了。虽然这个组合方案不完美,但出现一致性问题的概率较低。
故, 总结如下:
流程:
- 更新数据库
- 删除缓存
优点:
- 缓存删除失败概率低(删除比更新更简单)。
- 并发问题较少:
- 即使线程A更新DB后未及时删除缓存,线程B读取旧数据,但下次查询会重新加载最新数据。
问题:
- 短暂不一致:
- 线程A更新DB后,未删除缓存前,线程B可能读到旧数据。
- 缓存击穿:删除缓存后,大量请求穿透到DB。
解决方案:
- 延迟双删(组合5)可进一步降低不一致概率。
- 缓存预热减少击穿影响。
结论:✅ 推荐,相比前3种方案更可靠。
5. 延迟双删(先删缓存→更新DB→再删缓存)(最佳实践⭐)
除了组合3会碰到的问题,组合4还会碰到别的问题吗?
是的。假设线程A要更新数据,先完成第一步更新数据库,在线程A删除缓存之前,线程B要访问缓存,那么取得的就是旧数据。这是一个小小的缺陷。
那么,以上问题有办法解决吗?
还有一个方案,就是先删除缓存,再更新数据库,再删除缓存。这个方案其实和先更新数据库,再删除缓存差不多,因为还是会出现类似的问题:假设线程A要更新数据库,先删除了缓存,这一瞬间线程C要读缓存,先把数据迁移到缓存;然后线程A完成了更新数据库的操作,这一瞬间线程B也要访问缓存,此时它访问到的就是线程C放到缓存里面的旧数据。
不过组合5出现类似问题的概率更低,因为要刚好有3个线程配合才会出现问题(比先更新数据库,再删除缓存的方案多了一个需要配合的线程)。
但是相比于组合4,组合5规避了第二步删除缓存失败的问题——组合5是先删除缓存,再更新数据库,假设它的第三步“再删除缓存”失败了,也没关系,因为缓存已经删除了。
其实没有一个组合是完美的,它们都有读到脏数据(这里指旧数据)的可能性,只不过概率不同。根据以上分析,组合5相对来说是比较好的选择。
不过这个组合也有一些问题要考虑,具体如下。
- 1)删除缓存数据后变相出现缓存击穿,此时该怎么办?此问题在前面已经给出了方案。
- 2)删除缓存失败如何重试?这个重试可以做得复杂一点,也可以做得简单一点。简单一点就是使用try…catch…,假设删除缓存失败了,在catch里面重试一次即可;复杂一点就是使用一个异步线程不断重试,甚至用到MQ。不过这里没有必要大动干戈。而且异步重试的延时大,会带来更多的读脏数据的可能性。所以仅仅同步重试一次就可以了。
- 3)不可避免的脏数据问题。虽然这个问题在组合5中出现的概率已经大大降低了,但是还是有的。关于这一点就需要与业务沟通,毕竟这种情况比较少见,可以根据实际业务情况判断是否需要解决这个瑕疵。
任何一个方案都不是完美的,但如果剩下1%的问题需要花好几倍的代价去解决,从技术上来讲得不偿失,这就要求架构师去说服业务方,去平衡技术的成本和收益。
故, 总结如下:
流程:
- 删除缓存
- 更新数据库
- 延迟几百毫秒后,再次删除缓存
优点:
- 减少不一致窗口:第二次删除能清理可能的脏数据。
- 避免缓存更新失败问题:即使第二次删除失败,缓存已被第一次删除,不会长期存储旧数据。
问题:
- 短暂不一致仍存在(但概率更低)。
- 实现稍复杂:需要引入延迟任务(如MQ、定时任务)。
适用场景:
- 对一致性要求较高的电商、金融等业务。
结论:✅ 最佳实践,比方案4更可靠。 延迟双删通过两次删除操作建立安全窗口,在工程实践上实现了性能与一致性的最佳平衡,是分布式系统缓存更新的首选方案 .
总结:如何选择缓存更新策略
方案 | 描述 | 一致性 | 推荐度 |
---|---|---|---|
1️⃣ 先更新缓存,再更新DB | 易回滚问题 | ❌ 差 | ❌ 不推荐 |
2️⃣ 先删缓存,再更新DB | 旧数据问题 | ❌ 差 | ❌ 不推荐 |
3️⃣ 先更新DB,再更新缓存 | 并发问题 | ⚠️ 一般 | ❌ 不推荐 |
4️⃣ 先更新DB,再删缓存 | 较可靠 | ✅ 较好 | ⭐ 推荐 |
5️⃣ 延迟双删 | 最可靠 | ✅ 最佳 | ⭐⭐⭐ 最佳 |
最终建议
- 普通业务:使用 方案4(先更新DB,再删缓存),简单可靠。
- 高一致性业务(如支付、库存):使用 方案5(延迟双删),减少不一致窗口。
- 补充优化:
- 缓存预热减少击穿影响。
- 异步重试(如MQ)处理删除失败情况。
- 加锁(如Redis分布式锁)防止并发问题。
没有完美方案,但 方案4和5 在大多数场景下能平衡 性能与一致性。
缓存高可用设计核心要点与监控方案
1、缓存高可用设计的5大核心要点
-
负载均衡(读扩展)
- 目标:通过多节点分摊读请求压力。
- 方案:
- 使用代理层(如Twemproxy、Redis Cluster)自动分配请求。
- 客户端分片(如一致性哈希)直接路由请求。
-
数据分片(写扩展)
- 目标:分散数据存储与写压力。
- 方案:
- Redis Cluster:自动分片(16384个槽),支持动态扩缩容。
- Codis:Proxy层分片,兼容原生Redis协议。
-
数据冗余(容灾)
- 目标:单节点故障时数据不丢失。
- 方案:
- 主从复制(Replication):主节点写,从节点读+备份。
- 多副本存储:如Redis Cluster的每个分片包含主从节点。
-
故障自动转移(Failover)
- 目标:节点宕机时自动切换,保障服务可用。
- 方案:
- 哨兵模式(Sentinel):监控主节点,自动选举新主。
- Redis Cluster内置Failover:主节点宕机时,从节点自动升级。
-
一致性保证
- 目标:数据分片、故障恢复时避免脏数据。
- 挑战:Redis默认异步复制,可能丢失少量数据。
- 解决方案:
- WAIT命令:同步复制(牺牲性能)。
- 业务层补偿:如定时校对DB与缓存。
推荐架构:
- 中小规模:Redis Sentinel + 主从复制。
- 大规模:Redis Cluster(内置分片、Failover)。
2、缓存监控关键指标与工具
-
核心监控指标
- 命中率:
keyspace_hits / (keyspace_hits + keyspace_misses)
,低于80%需优化缓存策略。 - 内存使用:
used_memory
,避免超过最大内存(maxmemory
)触发淘汰。 - 慢查询:
slowlog
分析耗时命令(如KEYS *
、大Value操作)。 - 延迟:
redis-cli --latency
,超过1ms需排查网络或阻塞命令。 - 连接数:
connected_clients
,防止连接泄漏。
- 命中率:
-
开源监控工具
- RedisLive:实时仪表盘展示关键指标。
- Prometheus + Grafana:自定义报警与可视化。
- Redis-exporter:为Prometheus提供Redis指标。
-
自研监控建议
- 定时巡检脚本:检查
INFO
命令输出的关键指标。 - 自动化报警:如内存使用率超90%、命中率低于70%时触发告警。
- 定时巡检脚本:检查
3、总结
- 高可用核心:分片扩展写、冗余保障读、自动Failover。
- 监控关键点:命中率、内存、慢查询、延迟。
- 工具选型:
- 快速上手:RedisLive。
- 长期运维:Prometheus+Grafana。
最终建议:根据业务规模选择Redis Sentinel或Cluster,并配套监控告警体系,确保缓存稳定支撑业务高峰。
相关文章:
架构思维:缓存层场景实战_读缓存(下)
文章目录 Pre业务场景缓存存储数据的时机与常见问题解决方案1. 缓存读取与存储逻辑2. 高并发下的缓存问题及解决方案3. 缓存预热(减少冷启动问题) 缓存更新策略(双写问题)1. 先更新缓存,再更新数据库(不推荐…...
软件架构设计:MVC、MVP、MVVM、RIA 四大风格优劣剖析
MVC、MVP、MVVM 和 RIA 都是软件架构中常见的设计风格,以下是对它们的详细介绍: 一、MVC 架构风格(Model - View - Controller) 1.简介:MVC 架构风格将软件应用程序分为三个核心部分,通过这种划分来分离不…...
java基础课程-springmvc课程
一. 回顾MVC: tomcat是servlet容器, servlet实现方式: xml中配置: 二. 回顾servlet: 三. SpringMvc学习 3.1 springMvc搭建和讲解: jar包引入spring-webmvc即可。 核心:DispatcherServlet Spring的web…...
NLP高频面试题(四十二)——RAG系统评估:方法、指标与实践指南
1. 引言:RAG系统概述与评估挑战 检索增强生成(Retrieval-Augmented Generation,简称 RAG)是近年来自然语言处理领域的一个重要进展。RAG系统在大型语言模型生成文本的过程中引入了外部检索模块,从外部知识库获取相关信息,以缓解纯生成模型可能出现的幻觉和知识盲点。通过…...
Flutter学习 滚动组件(1):ListView基本使用
目录 一、ListView构造方法1.1 常规方法1.2 ListView.builder1.3 ListView.separated 二、自定义ListView样式和布局:三、ListView性能优化:总结: 一、ListView构造方法 主要以下几种方法: 常规方法,直接使用默认的构…...
处理 Flutter 没有反应
现象 有以下几种 VS Code 中 Initializing the Flutter SDK. This may take a few minutes. 会一直维持在这个右下角提示窗, 但是无后续动作 Flutter CMD flutter_console.bat 执行 --version 或者 doctor [-v] 没有任何输出, 命令卡住 解决办法 参考官方说明 管理员身份…...
java面向对象06:封装
封装 该露的露,该藏的藏 我们程序设计要追求“高内聚,低耦合”。高内聚就是类的内部数据操作细节自己完成,不允许外部干涉;低耦合:仅暴露少量的方法给外部使用。 封装(数据的隐藏) 通常&#x…...
测试定时发布
测试定时发布 测试定时发布 测试定时发布 测试定时发布 欢迎使用Markdown编辑器 你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。 新的改变 我…...
2025年4月15日 百度一面 面经
目录 1. 代理相关 从静态代理到动态代理 2. cglib可以代理被final修饰的类吗,为什么 3. JVM 体系结构 4. 垃圾回收算法 5. 什么是注解 如何使用 底层原理 6. synchronized和reentrantlock 7. 讲一下你项目中 redis的分布式锁 与java自带的锁有啥区别 8. post 请求和 ge…...
抖音卸载了ip属地还会更新吗?深度解析
近期,关于抖音IP属地显示功能的讨论热度持续攀升,许多用户提出疑问:如果卸载抖音APP,账号的IP属地还会继续更新吗?这一问题背后,既涉及平台算法的运作逻辑,也关乎用户对隐私保护的深层需求。本文…...
Spring IoC与DI详解:从Bean概念到手写实现
一、Spring Bean的概念与本质 1.1 什么是Bean? 在Spring框架中,Bean是一个由Spring IoC容器实例化、组装和管理的对象。Bean及其之间的依赖关系通过容器使用的配置元数据来定义。简单来说,Bean就是Spring容器管理的Java对象。简单来说&…...
【Qt】信号和槽
文章目录 信号和槽的概念信号和槽的使用链接信号和槽查看内置信号和槽通过 Qt Creator 生成信号槽代码 自定义信号和槽基本语法带参数的信号和槽 信号与槽的连接方式一对一一对多多对一 信号和槽的其他说明信号与槽的断开 使用 Lambda 表达式定义槽函数 信号和槽的概念 在 Qt 中…...
小事务架构下的业务完整性保障:基于业务处理记录与补偿机制的技术实现
随着微服务架构、事件驱动架构(EDA)和最终一致性理念的普及,传统的大事务管理方式被更细粒度的“小事务”所取代。在这种架构中,全局业务流程被拆解成多个局部事务节点,通过异步消息进行编排。这种解耦提高了可扩展性和…...
DELL电脑开机进入自检界面
疑难解答 - 如何解决开机直接进入BIOS画面 添加链接描述 一、DELL电脑开机自检提示please run setup program 未设置一天中的时间-请运行安装程序(Time-of-day not set - please run SETUP program) 配置信息无效-请运行安装程序(Invalid configuration information - ple…...
Spring Boot 微服务中集成 MyBatis-Plus 与集成原生 MyBatis 有哪些配置上的不同?
在Spring Boot 微服务中集成 MyBatis-Plus (MP) 与集成原生 MyBatis (MB) 在配置上的主要不同点。MyBatis-Plus 是在 MyBatis 基础上进行的增强,它兼容 MyBatis 的所有配置方式,并提供了更简洁、更强大的配置选项。 相同点: 基础数据源配置 (DataSource…...
最近准备写个Playbook,详细点的指导手册,作为后续的销售培训文件,也趁着这个机会整理下产品思路,尤其是对于UALink,UEC新的联盟规范的测试用例
# 最近准备写个Playbook,详细点的指导手册,作为后续的销售培训文件,也蹭这个机会整理下产品思路。随着产品线越来越多(其实也是越来越少),东西越来越杂,已经不是三言两语就能解释得清楚了。 其…...
Kimi-VL:开源多模态视觉语言模型的崭新突破
近年来,人工智能在多模态模型的领域取得了显著的进展,特别是在能够处理文本和视觉输入的模型方面。MoonshotAI团队近期开源发布了Kimi-VL模型,这一模型凭借其在视觉理解、推理和智能体任务中的优异表现,受到了广泛关注。与GPT-4o等…...
NLP专业技能2025
Linux: 熟练使用Linux操作系统,熟练使用Linux常用命令进行开发。 熟悉掌握shell脚本编程技术的使用,能够编写简单的Shell脚本并熟练使用shell脚本四剑客(find、sed、grep、awk)进行日志解析。 熟练使用Linux环境进行开…...
C++STL循环队列实现
核心概念 循环队列(Circular Queue),也称为环形队列,是一种特殊的队列数据结构。它通过将队列的首尾相连,解决了传统队列因出队操作导致的空间浪费问题(即“假溢出”),从而更高效地…...
YOLOv3实践教程:使用预训练模型进行目标检测
目录 简介环境准备获取预训练模型图像目标检测视频目标检测模型性能优化常见问题解答进阶学习路径 简介 YOLOv3(You Only Look Once version 3)是一种高效的实时目标检测算法,由Joseph Redmon和Ali Farhadi于2018年提出。与传统的目标检测…...
confluent-kafka入门教程
文章目录 官方文档与kafka-python的对比配置文档配置项 Producer代码示例Consumer代码示例 官方文档 confluent_kafka API — confluent-kafka 2.8.0 documentation Quick Start for Confluent Cloud | Confluent Documentation 与kafka-python的对比 对比维度confluent-ka…...
网络安全-Http\Https协议和Bp抓包
1. http协议,有请求必有相应, 请求协议, 响应协议; 2. 密码学加密机制及常用算法和常用名称说明: 算法 密钥 明文数据 密文; 加密算法分类和常用算法: 加密算法可以归结为三大类ÿ…...
TDengine 语言连接器(C#)
简介 TDengine.Connector 是 TDengine 提供的 C# 语言连接器。C# 开发人员可以通过它开发存取 TDengine 集群数据的 C# 应用软件。 .NET 版本兼容性 .NET Framework 4.6 及以上版本。.NET 5.0 及以上版本。 支持的平台 原生连接支持的平台和 TDengine 客户端驱动支持的平台…...
AI对百度搜索与抖音社区的影响差异?
在AIGC(生成式人工智能)快速发展的背景下,用户获取内容的方式确实变得更加直接和便捷。抖音、小红书等视频内容社区的流量下降速度可能比百度搜索更慢,这一现象可以从以下几个角度分析: 1. 内容形式的差异:…...
《ADVANCING MATHEMATICAL REASONING IN LAN- GUAGE MODELS》全文阅读
《ADVANCING MATHEMATICAL REASONING IN LAN- GUAGE MODELS: THE IMPACT OF PROBLEM-SOLVING DATA, DATA SYNTHESIS METHODS, AND TRAINING STAGES》全文阅读 提升语言模型中的数学推理能力:问题求解数据、数据合成方法及训练阶段的影响 \begin{abstract} 数学推…...
是德科技KEYSIGHT Agilent U2004A功率传感器
是德科技KEYSIGHT Agilent U2004A功率传感器 Keysight U2004A USB功率传感器的特性和规格包括: 频率范围为 9 kHz 至 6 GHz -60 至 20 dBm 的宽动态范围 内部调零功能消除了外部校准 测量速度高达 250 个读数/秒 在 PC 或其他 Agilent 仪器上显示功率测量值 频率…...
Kubernetes(K8S)内部功能总结
Kubernetes(K8S)是云技术的最核心的部分,也是构建是云原生的基石 K8S K8S,是Kubernetes的缩写,是Google开发的容器编排平台,现在由云原生计算基金会(CNCF)进行维护。 K8Sÿ…...
智谱最新模型GLM4是如何练成的
写在前面 这篇博客将基于《ChatGLM: A Family of Large Language Models from GLM-130B to GLM-4 All Tools》,深入剖析 GLM-4 系列在**模型架构设计、预训练、后训练(对齐)、以及关键技术创新(如长上下文处理、Agent 能力构建)**等环节的实现逻辑与设计考量,带你全面了…...
类头文件相互包含的问题
1.预编译指令: #ifndef CLASS_A_ #define CLASS_A_#include CLASS_B.h#endif 2.#pragma once 3.将类A中声明类B,并类中声明类B的指针,在类中的实现文件中包含类B的头文件。在类B中包含类A的头文件 a.h:class Bclass A {public:private:B*…...
云原生周刊:K8s 中的 GPU 共享
开源项目推荐 A2A Google 的 Agent2Agent(A2A)协议是一个开源标准,旨在促进不同框架和供应商构建的 AI 代理之间的互操作性。它允许代理通过统一的协议安全地交换信息、协同执行任务,并在多种企业平台和云环境中无缝协作。 A2A…...
(五)机器学习---决策树和随机森林
在分类问题中还有一个常用算法:就是决策树。本文将会对决策树和随机森林进行介绍。 目录 一.决策树的基本原理 (1)决策树 (2)决策树的构建过程 (3)决策树特征选择 (4࿰…...
DeepReaserch写的文献综述示例分享
目录 DeepReaserch提供的文献综述: 人工智能在医疗影像诊断中的研究进展综述(2015–2025) 引言 1 近十年研究进展回顾 1.1 深度学习崛起阶段(2015–2017年) 1.2 方法完善与临床初探(2018–2020年&…...
Token安全存储的几种方式
文章目录 1. EncryptedSharedPreferences示例代码 2. SQLCipher示例代码 3.使用 Android Keystore加密后存储示例代码1. 生成密钥对2. 使用 KeystoreManager 代码说明安全性建议加密后的几种存储方式1. 加密后采用 SharedPreferences存储2. 加密后采用SQLite数据库存储1. Token…...
阶段性使用总结-通义灵码
序言 前段时间用通义灵码,参加了下数字中国闽江流域的比赛。https://www.dcic-china.com/competitions/10173 最后成绩一般般,106名,大概有2000多人参加这题目,估计有一堆小号。 按照下面这个思路建模的,迭代了大概15…...
SpringBoot 与 Vue3 实现前后端互联全解析
在当前的互联网时代,前后端分离架构已经成为构建高效、可维护且易于扩展应用系统的主流方式。本文将详细介绍如何利用 SpringBoot 与 Vue3 构建一个前后端分离的项目,展示两者如何通过 RESTful API 实现无缝通信,让读者了解从环境搭建、代码实…...
Flutter 图标和按钮组件
引言 在 Flutter 应用开发中,图标和按钮是构建用户界面不可或缺的元素。图标能够以直观的图形方式传达信息,增强应用的视觉吸引力;而按钮则是用户与应用进行交互的重要途径。本文将详细介绍 Flutter 中图标和按钮组件的使用,涵盖…...
大模型平台Dify工作流高效调用Ragflow知识库,解决其原生知识库解析和检索能力不足的问题
Dify调用Ragflow知识库的详细步骤,安装详细部署在我之前文章 多图超详细:Docker安装知识库AI客服RAGFlow的详细步骤、使用教程及注意事项:。超详细:Dify大语言模型工作流开发平台的安装与使用,deepseek知识库客服等。…...
数据库的基本原则
数据库的核心原则 原子性与持久性:原子性(Atomicity)确保一个事务中的所有操作要么全部完成,要么完全不执行,不会出现部分完成的情况。持久性(Durability)则保证一旦事务提交成功,即…...
项目集管理汇报报告 (范本)
该文档适用于企业管理层、项目经理、项目团队成员以及对项目集管理感兴趣的人员。它对企业项目管理至关重要,通过全面分析 揭示了如目标达成率低、数据缺失严重、成本进度管控有风险等关键问题,为管理层提供决策依据,助力其了解项目整体状况&…...
阿里云 MSE Nacos 发布全新“安全防护”模块,简化安全配置,提升数据保护
作者:张文浩 阿里云在其微服务引擎(MSE)注册配置中心 Nacos 上正式推出全新“安全防护”功能模块,旨在帮助企业用户有效管理安全状态和降低开启安全相关功能的学习成本,提升微服务架构的安全性。首期推出的“安全防护…...
Pydantic v2 的使用
一、前言 Pydantic 是一个 Python 数据验证 和 设置管理 库,使用 Python 类型 注解。具有以下特点: 1.1 核心功能 数据验证:自动验证数据类型和约束条件类型转换:自动将输入数据转换为声明类型Schema 生成:自动生成…...
从零开始学A2A二 : A2A 协议的技术架构与实现
A2A 协议的技术架构与实现 学习目标 技术架构掌握 深入理解 A2A 协议的分层架构设计掌握各层次的功能和职责理解协议的工作原理和数据流 实现能力培养 能够搭建基本的 A2A 服务端掌握客户端开发方法实现智能体间的有效通信 架构设计理解 理解与 MCP 的本质区别掌握多智能体协…...
设计模式每日硬核训练 Day 12:装饰器模式(Decorator Pattern)完整讲解与实战应用
🔄 回顾 Day 11:适配器模式小结 在 Day 11 中,我们学习了适配器模式(Adapter Pattern): 用于将“不兼容”的接口适配为目标接口,解决新旧系统之间的桥接问题。强调“接口兼容、外部桥接”&…...
[CMake] CMakePresets.json简单使用
解决的问题 CMakePresets.json是为了解决在使用命令行编译使用CMake的项目时,可能会十分麻烦。如类似的参数-DCMAKE_BUILD_TYPEDebug所以有了CMakePresets.json来配置configure和build时的命令,然后在使用时 cmake --preset<configure-preset-name&…...
智能办公如何创建e10流程
智能办公如何创建e10流程 配置e10流程前,您要做的事情: 1、进入e10管理后台,创建应用,开放接口权限;2、进入e10管理后台,配置千里聆套件,配置同步人员;3、进入千里聆系统ÿ…...
Mac关闭sip方法
Mac关闭sip方法 导航 文章目录 Mac关闭sip方法导航完整操作流程图详细步骤 完整操作流程图 这东西是我在网上搬运下来的,但是我在为业务实操过程中,根据实操情况还是有新的注意点的 详细步骤 1.在「关于本机」-「系统报告」-「软件」;查看SIP是否开启…...
Flutter 播放利器:`media_kit` 的详细介绍与使用指南
在 Flutter 项目中实现音视频播放,开发者过去主要依赖如 video_player、just_audio 等第三方库,但这些库或多或少存在一些局限性,比如平台兼容性差、定制能力不足、播放格式有限等问题。 而 media_kit 是近年崛起的一款全平台音视频播放解决…...
GEO优化中的关键底座:知识图谱如何提升生成式AI的准确性与实时性?
今天,我将与大家分享如何通过GEO优化(生成式人工智能优化)和动态知识图谱,帮助企业提升智能化水平并实现高效的业务运营。首先,GEO优化利用生成式AI为企业提供内容生成、客服自动化和智能销售等服务,而知识…...
案例 - 登录认证:保障系统安全访问的实现
摘要:本文介绍了为Tlias智能学习辅助系统添加登录认证功能的过程,涵盖从需求分析、接口文档设计,到思路分析、功能开发以及最后的测试等多个关键环节,旨在实现只有通过登录认证的用户才能安全访问后台系统功能的目标。 关键词&am…...
Node.js Session 原理简单介绍 + 示例代码
目录 ✅ Session 原理简要说明 🧩 示例项目 - 使用 Node.js Express 实现简单 Session 登录 📁 文件结构 🔹 server.js (JavaScript) 🔸 index.html (HTML) ▶️ 程序运行步骤 ✅ 程序运行效果 🎯 总结 在 We…...