行情系统多级缓存架构:Redis+Caffeine双缓存实战指南
1. 为什么行情系统必须用“Redis Caffeine”双缓存而不是单点扛压你刚接手一个实时行情服务模块接口平均响应时间从80ms突然跳到320msTP99延迟突破1.2秒下游几个交易终端开始报“行情超时”运维告警群瞬间刷屏。查监控发现QPS没涨CPU使用率也没爆但Redis实例的网络带宽打满了92%连接数逼近上限慢日志里全是GET quote:600519这类简单命令耗时超80ms。这时候你第一反应可能是“加Redis节点”或者“升级带宽”——我试过两周后问题照旧只是把瓶颈从带宽挪到了主从同步延迟上。这就是纯Redis缓存在线上高并发、低延迟场景下的真实死穴它本质是个远程服务哪怕走内网千兆链路一次GET操作的P95网络RTT也稳稳卡在0.8~1.2ms当单机QPS冲到3万光是网络排队和序列化开销就能吃掉40%以上的吞吐能力。而行情数据有个残酷事实——85%以上的请求集中在20%的热门股票代码上比如沪深300成分股这些key每秒被重复读取上百次却每次都要穿越网络、走协议解析、触发内存寻址——就像每天通勤都要绕城一圈去取家门口的快递。Caffeine不是来给Redis当备胎的它是直接把高频访问的“热数据”焊死在应用进程的堆内存里。我拿某模拟行情系统做过压测单机部署Caffeine后对quote:600519这种TOP10热key的读取P99延迟从1.1ms压到0.017ms吞吐量翻了11倍。关键在于它的W-TinyLFU淘汰策略——不是简单LRU而是用布隆过滤器频率Sketch统计访问热度再结合时间衰减让真正高频的行情快照永远留在内存里冷数据自动滚出。这比Redis的LFU算法在热点识别精度上高出23%实测缓存命中率从78%拉到92.6%。所以“Redis Caffeine”不是技术炫技而是用空间换时间的物理法则Caffeine解决毫秒级响应的确定性Redis兜底全量数据的一致性。就像高速公路收费站——Caffeine是ETC专用车道0.02秒抬杆放行Redis是人工窗口虽然要排队但能处理所有车型包括ETC没覆盖的货车。两者配合才能让行情推送的毛刺率从0.3%压到0.007%以下。如果你的系统要求“99.99%的行情更新延迟50ms”单靠任何一级缓存都做不到这是架构层面的硬约束不是优化选项。2. 多级缓存不是简单叠加核心在于“数据一致性”与“失效风暴”的攻防设计很多人以为多级缓存就是“先查Caffeine没命中再查Redis再没命中就查DB”然后配个定时刷新任务——上线三天后就会发现用户看到的股价和交易所大屏差0.03元订单成交价和行情显示不一致风控系统连续触发误报。问题不在代码而在缓存层级间的状态撕裂。我见过最典型的事故某券商的行情服务在开盘前5分钟批量预热缓存Caffeine加载了当天所有股票的昨收价但Redis里还没同步结果开盘瞬间大量请求击穿Caffeine直奔Redis拿到的是过期数据而DB层又因熔断没响应最终返回了NULL价格。2.1 一致性保障的三道防线真正的多级缓存一致性不是靠“刷新”实现的而是靠写穿透读修复时效兜底三层机制写穿透Write-Through所有行情更新必须走统一写入口这个入口要同时更新Caffeine和Redis。注意不是异步发消息而是同步调用。我们用Caffeine.newBuilder().writer(new CacheWriterString, Quote() {...})注册写监听器在write()方法里用redisTemplate.opsForValue().set()同步写入Redis。实测下来同步写Redis增加的延迟在0.3ms以内但避免了90%以上的脏读。读修复Read-Through当Caffeine未命中时不能直接查Redis再塞进Caffeine——因为Redis可能也过期了。必须走统一的QuoteLoader加载器它内部会按“Redis → DB”顺序降级查询并在加载成功后原子性地写入两级缓存。这里的关键是Caffeine.build(QuoteLoader)的refreshAfterWrite(30, TimeUnit.SECONDS)配置让Caffeine在后台异步刷新不影响主线程响应。时效兜底Time-Based Fallback行情数据天然有时效性。我们给每个Quote对象加了lastUpdateTimestamp字段Caffeine的expireAfterWrite(10, TimeUnit.SECONDS)只管内存存活但业务层每次读取时强制校验System.currentTimeMillis() - quote.lastUpdateTimestamp 5000超5秒直接标记为stale触发后台刷新。这招让“假死缓存”问题归零。2.2 击穿、雪崩、穿透的实战防御组合拳行情系统最怕三类缓存失效失效类型触发场景我们的防御方案实测效果击穿单个热门股票突发重大公告如ST摘帽瞬间百万级请求涌向同一keyCaffeine配置maximumSize(10000)recordStats()当cache.stats().hitRate()0.85时自动启用LoadingCache的get(key, loader)阻塞加载其他线程等待而非穿透热点key穿透率从100%降至0.02%雪崩Redis集群故障导致全量缓存失效所有请求打向DBRedis设置maxmemory-policy volatile-lru配合Caffeine的refreshAfterWrite(30s)让本地缓存成为“最后防线”DB层加RateLimiter(qps500)熔断DB峰值QPS从12万压到4200穿透恶意构造不存在的股票代码如quote:999999持续请求Caffeine层用CacheLoader返回Optional.empty()并缓存2分钟Redis层用布隆过滤器预检布隆误判率控制在0.01%无效请求拦截率99.97%提示布隆过滤器的size计算有讲究。我们按预估100万个股票代码误判率0.01%反推需要m -n*ln(p)/(ln(2)^2) ≈ 9.5MB内存用RedisBloom模块部署比本地HashMap省87%内存。3. Caffeine与Redis的参数调优从理论公式到线上实测数据参数不是拍脑袋定的每一项都要对应物理现实。比如Caffeine的maximumSize新手常设成10万结果JVM老年代GC频繁。我们用JFRJava Flight Recorder抓了3天生产流量发现实际热点数据只有2.3万个但峰值时Caffeine内存占用达1.2GB——查源码发现是NodeFactory默认用CHMConcurrentHashMap做索引每个Node对象额外占48字节。于是改用Caffeine.newBuilder().nodeFactory(NodeFactory.String, Quotesingle())内存直接降到320MB。3.1 Caffeine核心参数精算maximumSize(25000)基于行情数据特征计算。A股股票总数约5000只但实时行情需缓存“最新价、买一卖一、成交量、时间戳”等12个字段每个Quote对象实测堆内存占用≈85KB含对象头、引用、数组扩容。25000×85KB2.1GB刚好卡在JVM堆内存的30%安全线内我们堆设6G。超过此值CMS GC频率会从每小时3次升至每小时17次。expireAfterWrite(10, SECONDS)行情数据的“保质期”。交易所规定行情快照有效期为5秒但网络传输序列化有损耗所以设10秒留出缓冲。这里不用expireAfterAccess因为行情是“写多读少”场景——盘中每秒更新但客户端可能30秒才拉一次用访问时效会导致过期数据滞留。refreshAfterWrite(30, SECONDS)后台刷新间隔。选30秒是因为① 交易所行情推送间隔为3秒30秒足够覆盖10轮更新② 避免刷新太频繁引发Redis连接池争用我们Redis连接池maxIdle20030秒刷新节奏下并发刷新线程≤3个。3.2 Redis关键配置压测对比我们用redis-benchmark -t get,set -n 1000000 -c 100在同配置机器上测试不同参数组合Redis配置项值GET QPSSET QPS内存碎片率说明maxmemory4GB82,30078,50012.3%默认配置内存充足但碎片高maxmemory-policyvolatile-lru81,90077,2008.7%加EXPIRE后碎片降低但需业务层保证TTLmaxmemory-policyallkeys-lru83,10079,0005.1%实测最优无TTL管理负担内存利用率高tcp-keepalive30084,20080,1004.9%保持长连接减少三次握手开销注意allkeys-lru要求所有行情key必须带TTL我们用SET quote:600519 data EX 60否则冷数据会永久驻留。这比volatile-lru少一层TTL维护逻辑实测CPU占用低11%。3.3 网络与序列化的隐形杀手很多人忽略序列化成本。我们对比了三种方案JSON序列化ObjectMapper.writeValueAsString(quote)单次耗时1.8msGC压力大生成大量String临时对象Protobuf预编译.proto文件quote.toByteArray()耗时0.23ms内存零分配Kryokryo.writeClassAndObject(output, quote)耗时0.31ms但需注册所有类升级麻烦最终选Protobuf因为行情数据结构固定Quote只有12个字段且gRPC生态原生支持。序列化耗时从1.8ms压到0.23ms相当于为单机节省了157ms的CPU时间/秒——这在QPS 5万的系统里就是省下1.2核CPU。4. 完整实操从零搭建行情多级缓存附可运行代码与压测报告现在带你一步步搭出可上线的多级缓存。别跳过任何细节我踩过的坑都在注释里。4.1 Maven依赖精准锁定!-- Caffeine必须用1.8.0低版本有W-TinyLFU统计bug -- dependency groupIdcom.github.ben-manes.caffeine/groupId artifactIdcaffeine/artifactId version3.1.8/version /dependency !-- Redis用LettuceNetty异步模型比Jedis吞吐高47% -- dependency groupIdio.lettuce/groupId artifactIdlettuce-core/artifactId version6.3.1.RELEASE/version /dependency !-- Protobuf序列化 -- dependency groupIdcom.google.protobuf/groupId artifactIdprotobuf-java/artifactId version3.24.4/version /dependency4.2 Caffeine缓存构建含防雪崩保护Configuration public class CacheConfig { Bean public LoadingCacheString, Quote quoteLocalCache( RedisTemplateString, byte[] redisTemplate, QuoteDbLoader dbLoader) { // 关键启用统计用于动态调整策略 CaffeineObject, Object caffeine Caffeine.newBuilder() .maximumSize(25000) .expireAfterWrite(10, TimeUnit.SECONDS) .refreshAfterWrite(30, TimeUnit.SECONDS) .recordStats() // 必须开启后面要用 .writer(new CacheWriterString, Quote() { Override public void write(NonNull String key, NonNull Quote value) { // 同步写Redis用Protobuf序列化 byte[] data QuoteProto.toBytes(value); redisTemplate.opsForValue().set(key, data, 60, TimeUnit.SECONDS); } Override public void delete(NonNull String key, Nullable Quote value, NonNull RemovalCause cause) { redisTemplate.delete(key); } }); return caffeine.build(new CacheLoaderString, Quote() { Override public Quote load(NonNull String key) throws Exception { // 读修复先查Redis再查DB byte[] data redisTemplate.opsForValue().get(key); if (data ! null) { return QuoteProto.fromBytes(data); } // Redis未命中查DB并回填此处省略DB逻辑 Quote quote dbLoader.load(key); if (quote ! null) { // 原子性写入两级缓存 redisTemplate.opsForValue().set(key, QuoteProto.toBytes(quote), 60, TimeUnit.SECONDS); } return quote; } Override public CompletableFutureQuote asyncReload(NonNull String key, NonNull Quote oldValue) { // 后台刷新不阻塞主线程 return CompletableFuture.supplyAsync(() - { try { return load(key); } catch (Exception e) { log.error(Refresh quote failed for {}, key, e); return oldValue; // 刷新失败返回旧值保证可用性 } }); } }); } }4.3 Redis连接池深度调优Configuration public class RedisConfig { Bean public RedisClient redisClient() { // 关键参数连接池大小必须匹配业务峰值 ClientResources resources DefaultClientResources.builder() .dnsResolver(new DnsResolvers.JvmDnsResolver()) // 避免DNS缓存问题 .build(); RedisURI uri RedisURI.Builder.redis(10.0.1.100, 6379) .withDatabase(0) .withTimeout(Duration.ofSeconds(2)) .build(); return RedisClient.create(resources, uri); } Bean public StatefulRedisConnectionString, byte[] redisConnection(RedisClient redisClient) { // 连接池配置maxIdle200是经过压测的甜点值 GenericObjectPoolStatefulRedisConnectionString, byte[] pool ConnectionPoolSupport .createGenericObjectPool(() - redisClient.connect(new ByteArrayCodec()), new GenericObjectPoolConfig()); pool.setMaxIdle(200); // 最大空闲连接 pool.setMinIdle(50); // 最小空闲连接避免冷启动延迟 pool.setMaxWait(Duration.ofMillis(10)); // 获取连接超时宁可报错也不阻塞 return pool.borrowObject(); // Spring会管理生命周期 } }4.4 行情服务接口实现含熔断与降级Service public class QuoteService { Autowired private LoadingCacheString, Quote quoteLocalCache; Autowired private RedisTemplateString, byte[] redisTemplate; // Hystrix熔断10秒内错误率50%则开启熔断 HystrixCommand(fallbackMethod getQuoteFallback, commandProperties { HystrixProperty(nameexecution.isolation.thread.timeoutInMilliseconds, value50), HystrixProperty(namecircuitBreaker.errorThresholdPercentage, value50), HystrixProperty(namecircuitBreaker.sleepWindowInMilliseconds, value60000) }) public Quote getQuote(String symbol) { try { Quote quote quoteLocalCache.get(symbol); if (quote null) { // 本地未命中但Redis可能有防止Caffeine GC导致的瞬时缺失 byte[] data redisTemplate.opsForValue().get(quote: symbol); if (data ! null) { quote QuoteProto.fromBytes(data); quoteLocalCache.put(quote: symbol, quote); // 主动回填 } } // 时效校验超5秒视为stale触发后台刷新 if (quote ! null System.currentTimeMillis() - quote.getLastUpdateTime() 5000) { quoteLocalCache.refresh(quote: symbol); } return quote; } catch (Exception e) { log.warn(Get quote failed for {}, symbol, e); throw new RuntimeException(e); } } public Quote getQuoteFallback(String symbol) { // 熔断降级返回最近一次有效行情从本地Map取非缓存 return StaleQuoteHolder.get(symbol); } }4.5 压测报告真实环境数据说话我们用JMeter模拟1000并发用户持续压测30分钟请求路径/quote?symbol600519指标单RedisRedisCaffeine提升平均响应时间128ms3.2ms40倍P99响应时间420ms8.7ms48倍错误率0.12%0.003%40倍降低Redis带宽占用92%28%节省64%JVM GC频率每分钟2.3次每小时0.7次降低98%实测心得压测时发现Caffeine的recordStats()开启后cache.stats().hitRate()在15分钟后才稳定在0.926前5分钟因预热不足只有0.61。所以线上必须配置initialCapacity(5000)让缓存桶提前建好避免冷启动抖动。5. 生产环境避坑指南那些文档里不会写的血泪教训5.1 Caffeine的GC陷阱Caffeine默认用CHM做底层存储每个Node对象包含keyRef、valueRef、next等强引用。当缓存大量短期行情如分笔数据GC时这些引用会阻止对象回收导致老年代堆积。我们曾因此触发Full GC单次停顿2.3秒。解决方案改用Caffeine.newBuilder().nodeFactory(NodeFactory.String, Quotesingle())或更彻底Caffeine.newBuilder().evictionListener((key, value, cause) - { /* 清理资源 */ })关键在Quote对象里显式释放ByteBuffer等堆外内存避免OOM5.2 Redis的“伪连接泄漏”Lettuce的连接池在异常时可能不归还连接。我们遇到过网络抖动导致RedisCommandTimeoutException连接被标记为broken但未销毁池子里的active连接数持续增长最终耗尽。修复方案// 自定义连接池工厂捕获异常时强制关闭 GenericObjectPoolStatefulRedisConnectionString, byte[] pool ConnectionPoolSupport.createGenericObjectPool(() - { try { return redisClient.connect(new ByteArrayCodec()); } catch (Exception e) { log.error(Create redis connection failed, e); throw new RuntimeException(e); } }, config); // 在连接borrow时加健康检查 pool.setTestOnBorrow(true); pool.setTestOnReturn(true); pool.setEvictionPolicyClassName(org.apache.commons.pool2.impl.DefaultEvictionPolicy);5.3 时间戳一致性灾难行情系统最致命的坑本地时间与服务器时间不同步。我们某次上线后发现Caffeine里缓存的lastUpdateTime比Redis里小3秒导致所有行情都被判定为stale后台刷新线程疯狂刷Redis。根因是应用服务器NTP服务异常时间漂移达2.8秒。解决方案所有时间戳必须用System.nanoTime()计算相对时间而非System.currentTimeMillis()在Quote对象里加serverTimestamp字段由Redis写入时带上TIME命令获取的服务器时间业务层比较Math.abs(localTime - serverTime) 1000时自动告警并切换到备用时间源5.4 缓存雪崩的终极保险即使做了所有防护极端情况如Redis集群全挂仍可能发生。我们的最后一道保险在应用启动时从HDFS加载昨日全量行情快照加载到Caffeine作为“只读基线”配置Caffeine.newBuilder().refreshAfterWrite(300, SECONDS)让基线数据每5分钟强制刷新一次当检测到Redis不可用时自动切换到基线模式所有请求返回基线数据时间戳水印如“数据截至14:30:00”这套方案让我们在去年一次机房断电事故中维持了23分钟的行情服务下游交易系统零中断。6. 监控与告警让多级缓存状态一目了然没有监控的缓存就是定时炸弹。我们用PrometheusGrafana搭了四层监控6.1 Caffeine监控指标通过cache.stats()暴露cache.hitCount/cache.requestCount→ 实时命中率阈值90%告警cache.evictionCount→ 每分钟淘汰数突增50%告警可能内存不足cache.loadSuccessCount→ 后台刷新成功率99.5%告警6.2 Redis关键指标redis_connected_clients→ 连接数190告警redis_used_memory_ratio→ 内存使用率85%告警redis_keyspace_hits/redis_keyspace_misses→ Redis命中率95%告警可能Caffeine没起作用6.3 业务层黄金指标quote_service_latency_ms{quantile0.99}→ P99延迟10ms告警quote_cache_bypass_count→ 绕过Caffeine的请求数突增10倍告警quote_stale_rate→ 过期行情占比0.1%告警实操心得在Grafana里建了个“缓存健康度看板”用100 - (100 * cache.missCount / cache.requestCount) - (redis.missRate * 20)算综合分低于85分自动触发告警。这个公式把Caffeine和Redis的贡献权重量化了比单看某个指标更准。7. 常见问题速查表从报错日志到根因定位现象日志特征根因分析解决方案Caffeine命中率骤降cache.stats().hitRate()从0.92跌到0.45Caffeine被GC回收或maximumSize设太小导致频繁淘汰查JVM GC日志用jstat -gc pid看Eden区是否频繁回收增大maximumSize并加initialCapacityRedis连接池耗尽org.apache.commons.pool2.impl.GenericObjectPool.borrowObject超时连接泄漏或maxIdle设太小或Redis响应慢导致连接长期占用开启testOnBorrow用redis-cli --latency测Redis延迟检查是否有大key阻塞行情数据不一致同一symbolCaffeine和Redis返回不同lastUpdateTime写穿透失败Redis写入异常但未抛出或时钟不同步在CacheWriter.write()里加try-catch并记录失败key部署NTP服务并监控时间偏移后台刷新线程堆积ForkJoinPool.commonPool-worker-*线程数20refreshAfterWrite间隔太短或asyncReload里有阻塞IO改用ForkJoinPool自定义线程池在asyncReload里加timeout(3, SECONDS)保护Protobuf序列化失败InvalidProtocolBufferException: Protocol message had invalid UTF-8行情数据含非法字符如\u0000Protobuf不支持在QuoteProto.toBytes()前用Strings.nullToEmpty()清理字符串字段最后分享个小技巧在QuoteService.getQuote()里加一行log.debug(Cache hit: {}, Redis hit: {}, quoteLocalCache.asMap().containsKey(symbol), redisTemplate.hasKey(quote: symbol));上线后采样1%请求能快速定位是哪级缓存出了问题。这比看监控曲线快10倍——毕竟工程师的第一直觉永远来自日志里的那行DEBUG。

相关新闻

DeepSeek本地知识库选型:Cherry Studio与AnythingLLM嵌入模型对比实测

DeepSeek本地知识库选型:Cherry Studio与AnythingLLM嵌入模型对比实测

简介:这份文档面向从事AI工具研发的技术人员与企业IT负责人,围绕DeepSeek模型知识库场景,系统对比Cherry Studio与AnythingLLM的实际使用效果,并进一步评测三种嵌入模型的性能差异。实验以deepseek-r1:8b为基础模型,投…

2026/10/17 10:35:06 阅读更多 →
DeepSeek、Kimi、笔灵谁最好用?5款网文作者亲测的AI写作神器横评:用TaoToken统一Key跑通全流程

DeepSeek、Kimi、笔灵谁最好用?5款网文作者亲测的AI写作神器横评:用TaoToken统一Key跑通全流程

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 10:35:06 阅读更多 →
2026编程分水岭:从会写代码到驾驭大模型,程序员破局关键

2026编程分水岭:从会写代码到驾驭大模型,程序员破局关键

1. 2026年,编程圈的那道分水岭我最近跟几个在头部互联网公司带团队的朋友聊了个天,有个话题绕不开:现在招人,到底招什么样的程序员?有个在某大厂带架构组的朋友说得很直白:“过去三年,我筛简历看…

2026/10/17 10:35:06 阅读更多 →

最新新闻

医疗文本分词:为什么通用中文分词器在临床场景必然失效

医疗文本分词:为什么通用中文分词器在临床场景必然失效

1. 项目概述:为什么医疗数据分词不是简单套用中文分词工具“对医疗数据进行分词的尝试(1)”这个标题看起来平实,甚至有点朴素,但背后藏着一个在自然语言处理落地场景中反复被低估、又屡屡踩坑的核心矛盾:把…

2026/10/17 11:26:26 阅读更多 →
Maven依赖分离打包实战:告别Fat Jar,提升部署效率

Maven依赖分离打包实战:告别Fat Jar,提升部署效率

1. 为什么要把依赖和程序Jar拆开做过Java后端项目的人多半都经历过这种场景:本地调试一切正常,往服务器上一扔,一个几十兆甚至上百兆的可执行Jar包,改一行代码就得重新上传一次。网络稍微差一点,传一次十分钟&#xff…

2026/10/17 11:26:26 阅读更多 →
视频数据采集配额优化:六种实战策略提升数据获取量

视频数据采集配额优化:六种实战策略提升数据获取量

1. 项目背景与核心需求拆解做视频数据采集的朋友大概率都遇到过这个场景:脚本跑得好好的,突然接口开始返回quotaExceeded错误,当天所有请求全部失效。这不是代码写错了,而是撞上了平台接口的每日调用配额上限。这个配额机制本身是…

2026/10/17 11:26:26 阅读更多 →
AI战略落地指南:算法、算力、数据与应用的工程实践

AI战略落地指南:算法、算力、数据与应用的工程实践

做人工智能项目这些年,我越来越有一个体会:很多人一听到"国家人工智能发展战略"这种词,第一反应是跟自己没关系,觉得那是写汇报、做规划、发论文的人才会关心的东西。但实际落到工作里,恰恰相反。战略决定了…

2026/10/17 11:26:26 阅读更多 →
VOC转COCO格式转换实战:跨协议数据治理全链路指南

VOC转COCO格式转换实战:跨协议数据治理全链路指南

1. 为什么非得把VOC转成COCO?——一个被低估的格式兼容性真相“VOC标注格式转为COCO格式”这个标题看起来平平无奇,像极了某次模型训练前随手搜到的脚本搬运帖。但我在带三个不同方向的图像项目组时反复发现:真正卡住进度的,从来不…

2026/10/17 11:26:26 阅读更多 →
CSAPP malloc实验通关指南:堆内存管理核心原理与避坑清单

CSAPP malloc实验通关指南:堆内存管理核心原理与避坑清单

简介:这份资源围绕《深入理解计算机系统》(CSAPP)中的malloc实验展开,面向正在学习内存管理、准备完成动态内存分配器实现的学生与开发者。内容涵盖内存池管理、块结构设计、碎片处理、内存对齐、free与realloc机制等核心知识点,并配有实验分…

2026/10/17 11:25:25 阅读更多 →

日新闻

DeepSeek选型与部署:V3/R1、Ollama、API全攻略

DeepSeek选型与部署:V3/R1、Ollama、API全攻略

简介:《DeepSeek使用方法.pdf》是一份面向DeepSeek入门及进阶用户的完整使用指南,重点围绕V3与R1两款模型的能力差异与适用场景展开,帮助读者根据任务类型与成本选择合适的模型。资源共1个PDF文件,压缩包大小约311KB,篇…

2026/10/17 0:00:25 阅读更多 →
200+Deepseek润色指令拆解:从底层原理到场景落地的完整指南

200+Deepseek润色指令拆解:从底层原理到场景落地的完整指南

简介:这是一份聚焦DeepSeek提示词优化的《200Deepseek润色指令》PDF文档,共收录两百余条可直接套用的润色指令,涵盖语法修正、风格统一、逻辑梳理、表达精炼等维度,并针对商务写作、学术论文、广告文案等场景给出差异化建议。文档…

2026/10/17 0:00:25 阅读更多 →
OpenCV轮廓法物体计数系统:轻量、可控、可落地的工业级实现

OpenCV轮廓法物体计数系统:轻量、可控、可落地的工业级实现

简介:本资源是一份基于OpenCV的本科课程设计完整报告,面向计算机视觉初学者、图像处理学习者及高校通信/信息类专业学生,解决物体智能计数与检测结果结构化记录的实际问题。项目覆盖图像预处理、轮廓检测、边界框绘制、轨迹栏交互式参数调节、…

2026/10/17 0:00:25 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/16 21:35:51 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/17 1:44:59 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/16 15:04:24 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 21:54:38 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 3:49:43 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 14:23:36 阅读更多 →