MyBatis两级缓存机制详解:从配置到Redis替换的实践指南
聊到MyBatis 缓存机制我见过不少同事的状态是这样配置过cache标签知道有一级缓存、二级缓存这回事但真到排查数据不一致、缓存不生效、序列化报错的时候又得翻半天文档。我自己在模拟项目和实际后台系统里因为缓存问题踩过好几次坑从默认的本地二级缓存一路换到 Redis 方案对这套机制的理解才算真正落地。这篇文章不打算把源码逐行讲透而是从一个使用者的视角把 MyBatis 两级缓存各自的作用范围、生命周期、脏读场景、排查手法和分布式替换方案串起来。无论你是在写单体应用还是已经在微服务环境里摸爬滚打这套思路都能直接用。1. 缓存机制全貌到底为什么要分两级先给一个整体视角。MyBatis 的缓存不是一套独立中间件而是框架内置在 SqlSession 和 Mapper 生命周期里的两个容器。理解它最简单的方式是把它比作抽屉每个会话手里有一个小抽屉你把常用东西放进去同时办公室里还有一个公用柜子所有会话都能存取。MyBatis 的设计就是先翻自己抽屉一级缓存再翻公用柜子二级缓存都没有才去数据库拿。这里有个容易混淆的点大家常说的默认开启到底指什么一级缓存默认开启且强制存在于单个 SqlSession 内二级缓存默认也需要在 Mapper 中显式配置才会生效全局开关cacheEnabled默认是true所以真正决定二级缓存是否启用的是你有没有写cache或cache-ref标签。1.1 一级缓存与二级缓存的职责划分下面这张表基本能概括两级缓存的边界后面所有排查问题都可以回到这张表找方向。维度一级缓存二级缓存默认状态总是开启无法彻底关闭需要 Mapper 内配置cache或cache-ref作用范围单个 SqlSession同一个 namespace 下的所有 SqlSession 共享存储位置JVM 内存中的本地 Map默认也是应用内存可替换为 Redis 等外部存储数据生命周期SqlSession 关闭、commit、rollback 后清空随缓存实例存活受 flushInterval、size 等参数影响对象要求无特殊要求默认要求对象实现Serializable性能损耗极低直接内存引用有序列化/反序列化开销外部缓存还有网络开销一级缓存解决的是同一个会话里短时间内重复查询同一数据的问题二级缓存解决的是跨会话、跨线程多个请求同时命中同一热点数据的问题。职责完全不同不能互相替代。1.2 两级缓存的工作顺序查询路径是这样的先查二级缓存再查一级缓存两者都没命中才查数据库。数据写回的顺序则反过来查询结果先放进一级缓存事务提交后才会写入二级缓存。这个顺序很关键。我见过有人误以为查完数据库后立刻写二级缓存实际上二级缓存是经过TransactionalCacheManager控制的。如果你在一个事务里查了数据但事务还没提交那么这部分数据只存在于一级缓存和事务暂存区里其他 SqlSession 是看不到的。只有 commit 之后暂存数据才真正进入二级缓存rollback 则直接丢弃。1.3 为什么设计成两级而不是一个通用缓存如果只有一个一级缓存多线程、多会话之间没办法共享数据命中率太低如果只有二级缓存所有会话直接读全局缓存事务隔离又不好控制而且序列化和网络开销会拖累高频小查询。MyBatis 用两级缓存做了一次比较合理的折中小范围高频命中用一级缓存大范围低频命中用二级缓存最后用数据库兜底。2. 一级缓存默认开启但经常被误解一级缓存是 SqlSession 级别的这句话说起来简单但实际行为受 Key 构造、清空时机和 Spring 事务边界影响很大。2.1 一级缓存的 Key 生成规则一级缓存不是拿 SQL 字符串当 Key而是用CacheKey对象。它的核心构成包含这几部分MappedStatement的 idRowBounds 的 offset 和 limit完整执行的 SQL 语句查询参数值Environment 的 id代码里大致是这个流程CacheKey key new CacheKey(); key.update(ms.getId()); key.update(rowBounds.getOffset()); key.update(rowBounds.getLimit()); key.update(boundSql.getSql()); key.update(params);注意参数值本身也被放进 Key 里。所以两条 SQL 一样、参数不同的查询会被视为不同的缓存项。这也是为什么我们在同一 SqlSession 里先查id1再查id2会被当成两次独立查询。判断一级缓存是否命中最直观的方法是看日志。把 MyBatis 日志级别调到 DEBUG 后第一次查询会打印Preparing: select ...第二次相同查询如果没打印这行说明命中了缓存。2.2 一级缓存什么时候会被清空一级缓存不是一直存在的。以下几种情况都会让缓存失效调用sqlSession.clearCache()手动清空当前会话缓存执行commit()或rollback()执行 insert、update、delete 语句默认flushCachetrue把localCacheScope设置为STATEMENT让每条语句执行完就清空SqlSession 关闭这个会话的缓存对象随之销毁。其中最容易踩坑的是更新会清空缓存这个行为。很多人以为同一条更新语句只清空跟它相关的缓存实际上不是只要当前 SqlSession 执行了任何写操作整个一级缓存都会被清掉。好处是安全坏处是如果你在事务里先查了一次列表再改一条记录然后想再查一次列表拿到最新数据这次查询会重新走数据库因为缓存已经被清了。localCacheScope默认是SESSION也就是缓存贯穿整个会话如果设成STATEMENT相当于把一级缓存的共享范围缩小到单条语句。你没法彻底关闭一级缓存但可以把它废掉让每次查询都走数据库。2.3 和 Spring 搭在一起时一级缓存为什么总是失效一级缓存和 Spring 整合时最常见的问题是我在 Service 里调了两次同一个 Mapper 方法为什么日志显示执行了两次 SQL原因不在 MyBatis而在 SqlSession 的获取方式。Spring 中 Mapper 是通过SqlSessionTemplate代理的每次调用 Mapper 方法时它会从TransactionSynchronizationManager里取当前线程绑定的 SqlSession。如果你没有开启事务SqlSessionUtils会创建一个新的 SqlSession方法执行完立刻关闭。关闭之后一级缓存就没了第二次调用自然重新查库。如果你把两段查询放到同一个事务方法里Spring 会把 SqlSession 绑定在当前线程上直到事务提交或回滚才关闭。只有在这种情况下一级缓存才能在两次查询之间复用。想用一级缓存的人不要在无事务方法里期待它反过来也不建议为了缓存而硬加事务。事务有隔离级别、连接占用和锁的开销单纯为了缓存加Transactional不一定划算。3. 二级缓存跨 SqlSession 的公共抽屉二级缓存才是大多数性能优化真正依靠的部分。它跨 SqlSession、跨线程同一个 namespace 下的查询结果可以被多个会话共享。3.1 开启二级缓存的完整三步第一步确认全局开关是开启状态。mybatis-config.xml里加上下面这段比较保险settings setting namecacheEnabled valuetrue/ setting namelocalCacheScope valueSESSION/ setting namelocalCacheSize value512/ /settingscacheEnabled默认就是true但如果公司历史配置里有人改过还是显式写清楚更稳。第二步让要缓存的实体类实现Serializablepublic class UserInfo implements Serializable { private static final long serialVersionUID 1L; private Long id; private String name; private Integer status; }这一步很多人漏掉结果启动时报NotSerializableException。注意不只是当前实体类查询结果如果是个List那List里的泛型元素也必须是可序列化的。第三步在 Mapper XML 里配置cache标签mapper namespacecom.example.mapper.UserMapper cache evictionLRU flushInterval60000 size512 readOnlyfalse blockingfalse/ /mapper配置完成后该 namespace 下所有 select 默认都会走二级缓存除非你给某个查询单独加useCachefalse。同样增删改默认flushCachetrue执行后会把该 namespace 下的缓存清空。3.2 cache 标签里的参数到底按什么标准选eviction是缓存淘汰策略默认LRU。各策略差异如下策略行为适用场景LRU最近最少使用优先淘汰最久没访问的通用默认热点集中时效果好FIFO先进先出跟访问频率无关数据生命周期稳定、顺序访问明显时用SOFT基于软引用JVM 内存不足时才回收希望缓存尽量占用内存但不导致 OOMWEAK基于弱引用GC 时基本就回收缓存价值低宁缺毋滥实战中我用得最多的是 LRU其余策略很少碰。flushInterval单位是毫秒设置后会在读取时检查是否超时超时则先清空缓存再查询。注意它不是定时器不是到了时间点立刻删而是一个惰性过期检查。size不是字节数而是缓存对象引用个数。默认值是1024如果你的缓存项是个大 List合理调小比如512或256。把它当成内存上限而不是存多少条记录。readOnly是很容易被忽略的参数。设成trueMyBatis 直接返回缓存对象的引用调用方改数据会直接影响缓存里的对象设成false会通过序列化拷贝一份返回调用方怎么改都不污染缓存。默认是false安全性高但开销高只读场景下可以设成true。blocking用于防止缓存击穿。多个线程同时查同一个 Key 时开启后能让后来的线程等待前一个线程查库并写缓存而不是全部打到数据库和外部缓存上。并发热点场景建议开启。3.3 命中二级缓存时内部发生了什么我之前花了不少时间才理解这个机制二级缓存不是查完立刻写入的。它内部有一个事务暂存机制查询结果先进TransactionalCache相当于放在一个临时缓冲区等到 SqlSession 提交事务才真正写入全局缓存。回滚时暂存数据直接丢弃。这意味着一个很反直觉的现象在一个事务里查了数据事务还没提交你换成另一个 SqlSession 去查同一个数据大概率是查不到的。只有提交后才可能命中。理解了这一点排查明明刚查过二级缓存命中率还是 0时就不会慌。当readOnly为默认值false时每次命中缓存都会经过序列化反序列化把缓存对象复制一份出来给调用方。这保证了多线程环境下一个请求对缓存对象的修改不会影响到其他请求。代价是每次读取都多了一次性能开销。如果你缓存的是很大的列表这个开销不能忽视。4. 缓存不一致的经典坑多 Mapper 操作同一张表二级缓存最经典的问题不是缓存不生效而是改了一方另一方还在用旧缓存。4.1 一个能让缓存脏读的演示场景假设有UserMapper和UserAdminMapper两个 Mapper 都操作同一张user_info表但分属不同 namespace。各自配置了cache后流程是这样的请求 A 通过UserMapper查询用户列表结果缓存在UserMapper的 namespace 下请求 B 通过UserAdminMapper更新了一个用户状态flushCache只清空UserAdminMappernamespace 下的缓存请求 C 再次通过UserMapper查询用户列表命中的还是步骤 1 的旧缓存。你看到的现象就是库里数据已经变了接口返回的却还是原来的列表。这不是 MyBatis 的 bug而是缓存隔离边界的正常行为每个 namespace 都是独立缓存池增删改只会清空自己那个池子。4.2 用 cache-ref 把两个 Namespace 拉到同一个缓存池解决思路很简单——让操作同一张表的所有 Mapper 共享同一个缓存。实现方式是cache-refmapper namespacecom.example.mapper.UserAdminMapper cache-ref namespacecom.example.mapper.UserMapper/ /mapper注意一个 Mapper 里配置了cache-ref就不要同时配cache否则会冲突。配置之后两个 namespace 共用UserMapper里定义的缓存实例任何一方执行增删改都会清空这个共享缓存池。上面的脏读问题就消失了。这个方案也有代价缓存共享范围越大被清空的频率越高命中率自然下降。如果一个系统里几十个 Mapper 都指向同一个缓存池那这个缓存基本形同虚设。我的原则是只让确实会写同一批表的 Mapper 共享不为了省事搞全局大池子。4.3 什么时候不该用二级缓存不是所有查询都适合进二级缓存尤其是以下几种情况数据实时性要求非常高的场景比如库存、账户余额写入频繁的表缓存数据刚写进去就被更新清掉纯属浪费资源查询结果跟用户强相关比如我的订单我的消息这种数据命中率低缓存意义不大复杂的多表关联查询一张表被多个 Mapper 共同操作时失效边界很难控制多实例部署且没有统一分布式缓存默认本地二级缓存会带来实例间数据不一致。如果碰到这些场景用不上二级缓存不是遗憾反而帮你少踩坑。5. 从内置缓存到分布式缓存Redis 接入实操单体应用里默认的二级缓存够用。但系统一拆多实例问题就来了。5.1 为什么生产环境要换成 Redis默认二级缓存是 JVM 内存里的本地缓存每个应用实例各存一份。多实例部署时会出现三个问题。第一是数据不一致。请求 A 打到实例 1缓存写进了实例 1 的内存请求 B 打到实例 2读到的是实例 2 的缓存两边可能不一样。就算你有负载均衡也没办法保证同一个 key 永远落在同一个实例上。第二是内存不可控。每个实例都存一份热点数据节点越多冗余越大。一个实例的 GC 压力已经够大缓存再占一块堆内存很容易引发频繁 Full GC。第三是缓存失效机制失效。实例 1 更新了数据库只能清空实例 1 的缓存实例 2 的缓存还是旧的。除非手动通知所有实例否则这种脏数据会一直存在。所以多实例环境下我更推荐把二级缓存换成 Redis让所有节点共享同一份缓存数据。对比维度默认本地二级缓存Redis 二级缓存多实例共享否是数据一致性实例间不一致统一存储内存管理占用应用 JVM 堆独立内存访问耗时纳秒级毫秒级取决于网络适用范围单机应用微服务、多实例部署5.2 继承 Cache 接口的写法MyBatis 的二级缓存设计得比较开放只要实现org.apache.ibatis.cache.Cache接口就能替换。你可以引入现成组件也可以自己封装。以 Redis 为例比较省事的方式是用mybatis-redis这个适配包大致配置是dependency groupIdorg.mybatis.caches/groupId artifactIdmybatis-redis/artifactId version1.0.0-beta2/version /dependencyMapper 里改成mapper namespacecom.example.mapper.UserMapper cache typeorg.mybatis.caches.redis.RedisCache/ /mapper这个包的原理是走 Jedis 客户端读写 Redis。但要注意这个项目更新不算活跃生产环境我会更建议自己写一个轻量实现便于控制序列化方式和日志。自定义实现的核心是继承Cache接口举一个骨架public class CustomRedisCache implements Cache { private final String id; private final RedisTemplateString, Object redisTemplate; public CustomRedisCache(String id) { this.id id; // 这里注入你自己封装好的 RedisTemplate } Override public String getId() { return id; } Override public void putObject(Object key, Object value) { String cacheKey id : key; redisTemplate.opsForValue().set(cacheKey, value); } Override public Object getObject(Object key) { String cacheKey id : key; return redisTemplate.opsForValue().get(cacheKey); } Override public Object removeObject(Object key) { String cacheKey id : key; return redisTemplate.delete(cacheKey); } Override public void clear() { // 按 id 前缀删除该 namespace 下所有缓存 key } Override public int getSize() { // 如果能拿到 size 就返回真实值拿不到可以返回近似值 return 0; } }几个容易踩的点MyBatis 会通过构造器传入 Mapper 的 namespace 作为id所以不要顺手写一个无参构造器把 id 丢了key 一定要带 namespace 前缀否则多个 Mapper 的缓存会互相覆盖Redis 里的 value 不能用默认 JDK 序列化去存任意 List 对象容易遇到类型转换问题建议结合 MyBatis 的Serializable机制统一处理clear()方法一定要把当前 namespace 下的缓存全部删掉不能只删一个 key。5.3 接入后的性能消耗观察接入 Redis 不是银弹它带来共享能力的同时也增加了开销。每次缓存读写多了一次网络 RTT序列化方式也从本地 JDK 序列化变成了 Redis 侧的序列化方案整体延迟肯定比本地缓存高。实测下来如果 Redis 和应用同机房部署单次读写大概增加零点几毫秒到几毫秒但如果 Redis 网络抖动查询接口的 P99 会被明显拉高。所以我通常会做一层优化热点数据依然可以在应用本地放一个短生命周期的小缓存二级缓存交给 Redis形成Redis 为主、本地极短缓存为辅的组合模式。需要提醒的是接入 Redis 后原本默认二级缓存里的Cache Hit Ratio日志不一定再出现因为自定义缓存不会自动套LoggingCache。如果你依赖这个日志观察命中率记得在自己的实现里加上命中计数。6. 排查与调优缓存问题速查与实战技巧最后这部分我把自己遇到过的常见问题和排查思路整理成一份速查表可以直接收藏。6.1 缓存问题排查速查表现象优先排查点解决方向同一 SqlSession 重复查询仍执行 SQLlocalCacheScope是否被改成STATEMENT改回SESSION并确认没执行 clearCacheSpring 下二级缓存命中率极低事务是否及时 commitSqlSession 是否被复用确认有事务边界的查询在一个 SqlSession 内执行开启二级缓存后报NotSerializableException实体类以及 List 泛型元素是否实现Serializable补上序列化接口和serialVersionUID多个 Mapper 操作同一张表数据出现脏读namespace 缓存互相隔离用cache-ref共享缓存池修改数据后立即查询返回的仍是旧值是否是同一 namespace、是否 flushCache 被设为 false检查增删改是否保留了默认flushCachetrue缓存命中率一直在低水平size 太小、flushInterval 太短、多个 namespace 频繁清空调整 size 和过期时间缩小共享范围多实例环境下使用默认二级缓存出现不一致缓存是否独立存储于各实例 JVM换 Redis 等外部缓存排查缓存问题我自己的习惯是先分清是第几层缓存再看事务边界最后看日志。顺序反了很容易绕进死胡同。6.2 日志里的 Cache Hit Ratio 怎么看把日志级别调到 DEBUGMyBatis 内置的LoggingCache会输出类似这样的内容Cache Hit Ratio [com.example.mapper.UserMapper]: 0.714这个数字代表该 namespace 窗口期内的累计命中率。0.714 表示大概七成的查询命中了二级缓存是典型的健康缓存数据如果长时间是 0.0说明缓存根本没被用到要么没配cache要么每次查询后缓存都被清掉了要么是事务一直没提交。需要注意的是一级缓存不走这个日志所以你不能用这个值判断一级缓存是否生效。判断一级缓存只能看同一个 SqlSession 内有没有重复打印PreparingSQL。6.3 调优缓存参数的个人建议关于参数调优我不太相信有一套放之四海而皆准的配置但有几个经验可以直接参考size不要拍脑袋设很大先估算一个 namespace 下实际可能被缓存的对象数量再乘以 2 左右作为余量flushInterval不要设太短否则缓存频繁失效也不要依赖它做实时更新它最多只能保证一定时间后重新查库readOnlytrue只在明确没人会改返回对象的情况下用否则宁可选false多花点序列化开销增删改操作频繁的 namespace建议干脆别开二级缓存报表、字典这类几乎不变化的数据可以设置较长的flushInterval并把 size 调大收益最明显如果发现慢 SQL 是因为缓存没命中先别急着加缓存先看 SQL 索引和表结构缓存只是锦上添花不是雪中送炭。最后分享两个比较实际的体会。第一线上排查缓存问题别靠猜先把日志级别调起来看Cache Hit Ratio和 SQL 打印情况通常几分钟就能定位问题。第二如果你决定用 Redis 替换默认二级缓存记得把序列化方案、key 前缀、namespace 隔离规则提前设计好否则等到多实例上线后再改会牵连一堆 Mapper。缓存机制看着不大影响面却一点都不小值得花点时间把它彻底理顺。

相关新闻

通达信day格式解析:用Python批量转换行情二进制文件为CSV

通达信day格式解析:用Python批量转换行情二进制文件为CSV

简介:通达信day格式转CSV的轻量工具,面向需要批量处理上证、深证及港股日线数据的量化爱好者与本地投资者。针对股票、基金、港股的不同二进制结构分别处理,将stock.exe复制到对应lday目录运行即可生成csv,无需额外运行环境&#…

2026/10/16 11:06:00 阅读更多 →
FFmpeg API 实战:读取视频信息与避坑指南

FFmpeg API 实战:读取视频信息与避坑指南

FFmpeg 这个库,做音视频开发的没人绕得开。但很多人第一次翻开它的头文件,看到AVFormatContext、AVCodecParameters、AVStream这一堆结构体,第一反应是懵的——文档少、示例老、API 还老变。我当初也是这样,为了拿一个视频的宽高和…

2026/10/16 11:06:00 阅读更多 →
操作系统隔离与系统调用全链路:从用户态到内核态的穿越

操作系统隔离与系统调用全链路:从用户态到内核态的穿越

6.S081这门操作系统课程讲到第三讲,终于开始触及最核心的部分:OS organization和system calls。前面几讲我们在用户态这边打转,fork、exec、wait这些系统调用用得很熟,但很少认真想过一个问题——你随手调一个write(),…

2026/10/16 11:04:59 阅读更多 →

最新新闻

本地多模态Embedding模型实战:740M参数实现图文向量检索

本地多模态Embedding模型实战:740M参数实现图文向量检索

搞向量检索、RAG、知识库的开发者,最近应该都在盯着 Embedding 模型。我第一次看到“EmbeddingGemma 2,740M 参数,多模态,本地推理”这几个关键词时,第一反应是:终于有模型把“多模态”“中等规模”“可本地…

2026/10/16 13:46:28 阅读更多 →
3GPP协议中文版:从术语理解移动通信标准的核心概念

3GPP协议中文版:从术语理解移动通信标准的核心概念

简介:3GPP协议中文版是一份以中文梳理3GPP Release-99核心术语与系统结构的参考文档,主要面向无线通信初学者、协议研究者及需要快速查阅IMT-DS FDD(WCDMA)基础概念的工程师。内容依据TS 25.990 V3.0.0整理,系统归纳了接入层、激活集、控制RN…

2026/10/16 13:46:28 阅读更多 →
perler-beads新手必会的5个技巧:用精细度与颜色合并阈值调出完美拼豆图纸

perler-beads新手必会的5个技巧:用精细度与颜色合并阈值调出完美拼豆图纸

【免费下载链接】perler-beads 拼豆底稿生成器 (Perler Beads Generator) 项目地址: https://gitcode.com/gh_mirrors/pe/perler-beads 点击查看 免费下载 perler-beads 是一个开源的智能拼豆底稿生成器(Perler Beads Generator)&#xff0c…

2026/10/16 13:46:28 阅读更多 →
C# WinForms图片移动原理与避坑实战

C# WinForms图片移动原理与避坑实战

简介:本资源是一个基于Windows Forms的C#图片动态移动演示项目,面向C#初学者与GUI编程学习者,解决图像在窗体中平滑移动、方向控制与边界检测等典型动画实现问题,适用于教学演示、课程设计或小型交互界面开发。压缩包共22个文件&a…

2026/10/16 13:46:28 阅读更多 →
Agent开始为‘工具‘付费了:Treg按次计费背后,API经济的新暗流

Agent开始为‘工具‘付费了:Treg按次计费背后,API经济的新暗流

Agent开始为工具付费了:Treg按次计费背后,API经济的新暗流 【免费下载链接】treg OpenRouter for agent tools. Join community here: https://discord.gg/6mQYYfFMAn 项目地址: https://gitcode.com/GitHub_Trending/treg/treg 当行业还在争论&q…

2026/10/16 13:46:28 阅读更多 →
Hadoop大版本升级前必读:评估、兼容、数据安全与回滚实战指南

Hadoop大版本升级前必读:评估、兼容、数据安全与回滚实战指南

1. 升级这件事,为什么值得单独拿出来聊干了十来年大数据平台运维,我参与过的大大小小集群升级少说也有几十次。从最早的单机伪分布式玩票,到后来几百台节点的生产集群跨大版本迁移,踩过的坑能写满一个笔记本。Hadoop升级这四个字&…

2026/10/16 13:45:26 阅读更多 →

日新闻

个人 AI Agent 平台接入 TaoToken:统一 Key 与 API 通道的配置大纲

个人 AI Agent 平台接入 TaoToken:统一 Key 与 API 通道的配置大纲

/* 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 0:00:05 阅读更多 →
信号与系统频域分析作业解题指南

信号与系统频域分析作业解题指南

1. 作业背景与核心要求解析信号与系统作为电子信息类专业的核心基础课,其作业设计往往直接关联课程的核心知识框架。2026年春季第六次作业的布置,通常对应着课程进展到频域分析的关键阶段。根据常规教学进度推测,本次作业可能涉及以下核心内容…

2026/10/16 0:00:05 阅读更多 →
Django MVT实战:从零构建图书借阅系统,彻底搞懂Model-View-Template分层

Django MVT实战:从零构建图书借阅系统,彻底搞懂Model-View-Template分层

1. 从一个"四不像"的练手项目说起如果你已经看完了Django的官方教程前几章,跟着敲完了投票应用,大概会有一种"我好像会了,又好像什么都不会"的割裂感。教程里每个知识点都是拆开的——这一章讲模型,下一章讲视…

2026/10/16 0:00:05 阅读更多 →

周新闻

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

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

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

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

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

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

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

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

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

2026/10/15 13:48:15 阅读更多 →

月新闻

我发现了一个新思路:用 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/15 0:14:36 阅读更多 →
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/15 9:49:14 阅读更多 →