Redisson实战指南:分布式锁与数据结构封装全解析
1. 为什么Redis生态里最终选了RedissonRedis本身只是个键值存储真正让它在业务系统里发光发热的是各种客户端库把它们包装成了开发人员顺手的东西。这个系列前面十篇把Redis的数据类型、持久化、主从、哨兵、集群都过了一遍到了第十一篇该聊聊实际项目里最常用的那把瑞士军刀了——Redisson。先说说我自己的经历。早些年用Java操作Redis主力是Jedis后来Spring Boot默认的Lettuce也用了很久。它们本质上都是传输工具你发一条命令它帮你把命令发给Redis再把结果拿回来。这套模式够用但遇到分布式场景就开始难受了。比如你要实现一个分布式锁拿Jedis得自己写SETNX加Lua脚本还得处理过期时间、锁续期、可重入这些边界问题每一行代码都是坑。我的团队早期就有一套自己封装的锁工具维护了大半年修了不少bug最后还是决定换掉。换掉之后用的就是Redisson。它和Jedis、Lettuce最大的区别在于Redisson不只是一个命令发送器它把Redis的各种能力封装成了Java里非常自然的数据结构和工具——你拿到的是一把看着像ReentrantLock的锁一个用起来像ConcurrentHashMap的RMap一个像AtomicLong的计数器。底层那些Redis命令、Lua脚本、序列化细节全部被藏起来了。对于正在学Redis的读者我的建议是前几篇你要是已经把Redis基础操作搞熟了这一篇的Redisson就是你从会操作Redis到能在生产环境用好Redis的转折点。它不改变Redis本身但彻底改变了你使用Redis的方式。这篇文章我尽量把Redisson最核心的几个能力拆开讲重点放在分布式锁、数据结构封装、以及一堆只有在实战里才会发现的坑。2. 引入Redisson前的准备依赖、配置与序列化2.1 Maven依赖怎么选版本Redisson的Java客户端坐标很简单就是一个核心包dependency groupIdorg.redisson/groupId artifactIdredisson/artifactId version3.27.2/version /dependency版本选择上有个建议如果项目用的是Spring Boot优先找带-spring-boot-starter后缀的版本比如redisson-spring-boot-starter。这样Spring容器会自动帮你装配好RedissonClient配置文件里的spring.redis.*参数它也能识别一部分。不过我自己更习惯用原生包手动创建RedissonClient原因后面说。另外要注意版本和JDK的兼容性Redisson 3.2x系列要求JDK 8如果你用的是JDK 17甚至21反而更省心。曾经踩过一个坑项目JDK还是8Redisson升级到了3.2x最新版虽然能用但某些新特性会走兼容模式后来干脆锁了一个稳定版本不动。2.2 三种部署模式下的客户端配置Redisson支持单机、哨兵、集群三种部署模式每种模式一个Config类就能搞定。单机模式最简单开发环境最常见Config config new Config(); config.useSingleServer() .setAddress(redis://127.0.0.1:6379) .setPassword(yourpassword) .setDatabase(0) .setConnectionPoolSize(64) .setConnectionMinimumIdleSize(16); RedissonClient redisson Redisson.create(config);哨兵模式适合高可用场景Config config new Config(); config.useSentinelServers() .addSentinelAddress(redis://192.168.1.101:26379, redis://192.168.1.102:26379) .setMasterName(mymaster) .setPassword(yourpassword) .setMasterConnectionPoolSize(64) .setSlaveConnectionPoolSize(64); RedissonClient redisson Redisson.create(config);集群模式则是这样Config config new Config(); config.useClusterServers() .addNodeAddress(redis://192.168.1.201:7001, redis://192.168.1.202:7002) .setScanInterval(2000) .setMasterConnectionPoolSize(64) .setSlaveConnectionPoolSize(64); RedissonClient redisson Redisson.create(config);这里setScanInterval是集群拓扑扫描间隔单位毫秒。Redisson会定期去探测集群节点变化默认就是2000毫秒一般不用改。连接池参数我后面专门讲这里不展开。2.3 序列化器必须单独配置Redisson默认序列化是FST线程安全性能不错但它有个问题存进去的字符串键值对用redis-cli看是一堆二进制乱码。如果你是纯Java应用这无所谓但团队里如果有运维同事要用命令行排查数据或者有其他语言的服务需要读同一份Redis数据就尴尬了。我的做法是统一用JSON序列化尤其是Value那一层config.setCodec(new JsonJacksonCodec());这个改动会让数据可读性大幅提升。举例来说用默认FST存一个User对象redis-cli拿到的是类似\xAC\xED\x00\x05t...的内容换成JsonJacksonCodec之后存进去的就是{id:1,name:张三}一眼能看懂。唯一需要注意的地方如果Redis里同时存在老版本FST序列化的数据切换Codec之后会反序列化失败。生产环境切换前要么先让旧数据自然过期要么做一个兼容读取的过渡。读者如果在已有系统上引入Redisson这一步一定不能省。3. 分布式锁Redisson最核心的王牌3.1 自己写分布式锁为什么会翻车分布式锁是Redis最热门的应用场景之一。很多人面试的时候能背出SETNX 过期时间 Lua脚本这套方案真到生产环境落地就会发现远没那么简单。第一层坑只用了setIfAbsent没设过期时间结果业务代码崩溃锁永远不释放其他线程全部卡死。这个算是低级错误了。第二层坑加了过期时间但业务执行时间超过过期时间锁被自动释放另一个线程拿到了锁临界区里有两个线程同时运行。解决思路是续期——起一个后台线程不断给锁续期直到业务结束。第三层坑续期逻辑判断这个锁是不是自己的。如果只按key释放锁线程A的锁过期了线程B拿到锁线程A业务结束把B的锁删了——这就是经典的误删别人的锁。第四层坑可重入怎么办同一个线程嵌套调用需要能重入还有锁等待超时、锁获取后的看门狗续期、以及Redis主从切换时锁丢失的极端场景。自己写这些一两百行Lua脚本加调度线程起步还要反复压测边界。Redisson把这些问题全部封装好了这也是我用它的最大理由。3.2 RedissonLock的底层原理Redisson的分布式锁核心类和实现流程值得了解一下至少面试和排障时用得上。锁的key是你在代码里指定的名字value里存的是一个UUID加线程ID的标识用来区分这个锁是谁持有的。加锁的时候Redisson并不是简单发一条SETNX而是执行一段Lua脚本脚本内部做了三件事判断锁的key是否存在不存在就直接加锁并设置初始过期时间默认30秒同时记录持有者标识和重入次数如果key存在但持有者标识是当前线程就把重入次数加1否则返回锁剩余存活时间调用方据此决定是否进入等待。释放锁时也走Lua脚本先判断持有者标识防止上面说的误删别人的锁确认是本人之后递减重入次数减到0才真正删除key。这个Lua脚本是原子的Redis单线程执行模型保证不会出现并发判断错乱。整个锁机制对外看起来和Java的ReentrantLock几乎一样。3.3 看门狗续期机制默认30秒不会提前过期Redisson锁默认的过期时间是30秒但如果你拿锁之后没有指定leaseTime参数Redisson会启动一个看门狗后台任务。这个任务每隔10秒锁过期时间的三分之一检查一次锁是否还存在存在就重新设置为30秒。这样业务代码无论跑多久只要线程没挂锁就不会在业务执行中被自动释放。这里有个值得重视的细节看门狗只在未指定leaseTime时启用。如果你调用lock(10, TimeUnit.SECONDS)这种带leaseTime的重载方法Redisson会认为你明确了锁的持有上限直接按10秒过期不启动续期。很多人踩过锁提前释放的坑回头一看代码发现正是在调用时传了leaseTime。生产环境我的建议很直接除非有必须防止持有锁超过固定时长的强需求否则一律用不带leaseTime的lock()方法把续期交给看门狗。要设置等待时间用这个重载// 最多等5秒拿不到就放弃 boolean locked redissonClient.getLock(order:pay:1001).tryLock(5, TimeUnit.SECONDS);注意这个5秒是等待获取锁的超时不是锁的过期时间两者容易搞混。业务执行完之后手动unlock()或者配合finally块统一释放。3.4 生产环境正确的加锁姿势直接上一段我项目里的标准写法Autowired private RedissonClient redissonClient; public void deductStock(Long skuId, int count) { RLock lock redissonClient.getLock(stock:deduct: skuId); // 持有锁看门狗自动续期 lock.lock(); try { int stock getStockFromCache(skuId); if (stock count) { throw new BizException(库存不足); } // 业务操作扣库存、写订单等 updateStock(skuId, stock - count); } finally { if (lock.isHeldByCurrentThread()) { lock.unlock(); } } }几个关键点lock.lock()拿不到锁的时候会阻塞等待不像tryLock可以控制等待时间。高并发场景一般用tryLock更稳妥。isHeldByCurrentThread()判断当前线程是否还持有锁防止业务异常导致锁状态混乱时误调用unlock。unlock放在finally里但是要包一层判断。虽然Redisson内部有防误删机制但主动判断一次能避免一些异常路径下的重复释放。3.5 公平锁、读写锁、RedLock怎么选Redisson还提供了几种特殊锁我这里把每个的适用场景说清楚。公平锁getFairLock内部通过Redis的zset维护了一个等待队列保证先到先得。适合秒杀、抢兑这类讲究公平性的场景。代价是性能比默认的不可重入锁低因为每次排队都要操作有序集合。读写锁getReadWriteLock读锁之间可以共享写锁独占。适合读多写少、数据一致性要求不高的场景比如配置读取、商品详情缓存更新。实测在高并发读场景下读写锁吞吐量比全量互斥锁高一截。RedLock红锁是Redisson提供的一种多节点锁方案需要向N个独立的Redis主节点分别加锁超过半数成功才算拿到锁。这个方案理论上能解决Redis主从切换时锁丢失的问题但实际工程里争议很大。我在生产环境没用过RedLock原因很简单多数业务场景其实用不到跨数据中心的强一致锁而且RedLock本身也存在分布式系统里关于时钟漂移的争论。如果你的系统已经有ZooKeeper或etcd强一致锁优先考虑它们Redis锁更适合够用就好的场景。4. 除了锁Redisson这些数据结构才是真宝藏4.1 RBucket、RMap、RList、RSet面向对象的Redis操作很多人学Redis数据类型的时候是分开记的String干什么、Hash干什么、List干什么、Set干什么。用Redisson之后这些维度收敛成了Java对象的使用习惯。RBucket相当于一个泛型容器对应Redis的String类型存一个对象RBucketUser bucket redissonClient.getBucket(user:123); bucket.set(user); User cached bucket.get();RMap对应Hash类型用法和ConcurrentHashMap非常像RMapString, String map redissonClient.getMap(product:attrs); map.putIfAbsent(color, red); map.fastPut(weight, 1.5kg); map.addAndGet(stock, -1);注意fastPut这个API很有意思它跳过了同步回调直接异步写入性能比put高但拿不到返回值。适合只写不管结果的场景。RList、RSet、RScoredSortedSet也是类似的封装思路。用这些封装的巨大好处是你不在业务代码里拼接Redis命令字符串了编译器能帮你提前发现拼写错误对象的序列化也统一由Codec处理。4.2 RAtomicLong分布式计数器不用再自己写Lua了上一篇文章讲Redis事务的时候我演示过用WATCH和Lua实现计数器递增。Redisson直接把这个操作封装成了RAtomicLongRAtomicLong counter redissonClient.getAtomicLong(visit:count); long value counter.incrementAndGet();这个类还支持decrementAndGet、addAndGet、compareAndSet这些方法背后走的就是Redis的原子操作。我在项目里用它做过接口防刷的计数器、灰度开关的流量分配、以及生成跨节点的自增序号配合每日零点重置。4.3 RDelayedQueue不用MQ也能做延迟任务这个是我个人最喜欢的Redisson特性。业务里经常有下单后30分钟未支付自动关闭、确认收货后7天自动打款这种延迟任务需求。引入整套延迟消息中间件太重用Redis的Key过期监听又不可靠Redis 5.0之后好在有Keyspace通知但生产环境对过期事件丢失比较敏感。Redisson的RDelayedQueue把这个问题解决得很优雅。原理是这样的数据先放进一个普通BlockingQueue同时注册一个DelayedQueue与其关联。Redisson通过定时扫描和zset的score机制实现延迟控制到期后元素会转移到目标队列BlockingQueue里。RBlockingQueueString queue redissonClient.getBlockingQueue(delayed:order:close); RDelayedQueueString delayedQueue redissonClient.getDelayedQueue(queue); // 30分钟后把订单号放入目标队列 delayedQueue.offer(order_10086, 30, TimeUnit.MINUTES); // 消费端 while (true) { String orderId queue.take(); closeOrder(orderId); }这个方案配合项目里一个简单的后台消费线程就能跑。要注意的是Redisson在Redis侧存储这些延迟数据会有额外的key空间消耗量特别大时要注意清理策略。我线上跑过每天几万条延迟数据问题不大。4.4 本地缓存和分布式缓存的联合用药Redisson有个RLocalCachedMap是在RMap的基础上加了JVM本地缓存层。查询时优先走本地缓存本地没有才访问Redis减少了远程调用次数。它的失效机制支持本地缓存同步失效本地JVM检测到Redis端数据更新后会通过广播机制通知其他节点清理本地缓存。听起来很美好但在集群部署时要特别小心。本地缓存是存储在JVM内存里的如果Redis数据更新没来得及同步到某个节点那个节点就会读到旧数据。Redisson默认提供失效广播机制但网络抖动时可能出现短暂的数据不一致。我的经验是对一致性要求高的数据不要用RLocalCachedMap对最终一致即可的高频读数据比如商品标签、活动开关可以用它把QPS打上去。5. 实战里绕不开的坑和性能调优经验5.1 看门狗失效的几种场景前面说了看门狗但看门狗不是万能的。这里讲几个我实测遇到过的失效场景。第一个是线程阻塞。看门狗续期本质上靠的是锁所属线程的TASK调度如果业务代码里调用了Thread.sleep()或者等一个很慢的外部接口这个期间看门狗任务依赖的是Redisson的netty事件循环线程一般不受影响。但如果你用的是lock.lockInterruptibly()并且线程被中断锁的持有状态和看门狗之间的关系会变得微妙这种情况直接会导致锁提前释放。第二个是主从切换。锁的key写在主节点上master宕机后数据还没来得及同步到slave哨兵提升新master锁信息丢了。Redisson官方提供RedLock试图解决这个问题但它要求至少3个独立节点很多业务系统根本搭不起这个架构。真要严谨得在基础设施层面接受极端故障时锁可能丢失这个事实再用幂等设计兜底。第三个是长事务。如果业务方法里有数据库事务整个事务可能要几十秒甚至更久而看门狗默认30秒续期逻辑没问题但如果你显式配置了leaseTime就一定要保证leaseTime大于最大业务耗时。我见过一个同事把leaseTime设成5秒接口偶尔要跑8秒线上间歇性出现并发问题排查了整整一天才定位到。5.2 锁粒度别把整个方法都锁住这是使用分布式锁最容易走偏的地方。很多人图省事直接在方法入口加锁public Order createOrder(CreateOrderRequest req) { RLock lock redissonClient.getLock(order:create); lock.lock(); try { // 查询商品 // 校验库存 // 扣减库存 // 生成订单 // 发送消息 } finally { lock.unlock(); } }这个写法的后果是所有订单创建请求串行化了Redis再快也扛不住全局互斥。正确做法是只锁真正需要互斥的资源比如某个商品的库存扣减锁key带上商品ID让不同商品之间的并发请求互不影响RLock lock redissonClient.getLock(stock:sku: skuId);锁的粒度越小系统并发能力越高。真正的实践是先把需要原子操作的代码抽出来再决定锁一段代码还是锁一个数据。5.3 连接池参数怎么调Redisson默认的连接池参数其实比较保守高并发场景下容易成为瓶颈。我给出一个实测可用的配置参考参数默认值建议值说明connectionPoolSize64128~256最大连接数取决于Redis实例的最大连接配置connectionMinimumIdleSize2416~32最小空闲连接数预热所需timeout3000ms3000ms连接超时别设太长否则故障时接口被拖死retryAttempts32重试次数太多会放大Redis故障影响retryInterval1500ms1000ms重试间隔调连接池有个前提Redis服务端也需要相应调大maxclients配置。我曾经把客户端连接池改成256没改Redis配置结果Redis服务端连接被打满一堆客户端报max number of clients reached。另外线程模型方面Redisson默认使用Netty事件循环不需要额外配置线程数但要注意业务线程池不要和它混淆。5.4 Spring Cache整合以及序列化匹配问题不少项目用Spring Cache做缓存抽象Redisson提供了RedissonSpringCacheManager可以无缝接入Cacheable、CacheEvict这些注解。Bean public CacheManager cacheManager(RedissonClient redissonClient) { MapString, CacheConfig config new HashMap(); config.put(userCache, new CacheConfig(24*60*60*1000, 12*60*60*1000)); return new RedissonSpringCacheManager(redissonClient, config); }它的好处是走了Redisson的RMapCache实现支持每个缓存单独的TTL。但这里有个大坑Spring Cache的key默认是方法的参数组合值如果你没有自定义KeyGenerator各种类型拼接出来的字符串可能长得很丑而且容易碰撞。我建议缓存key统一用SpEL表达式指定比如Cacheable(valueuserCache, key#userId)。还有一个坑是序列化匹配。Redisson分别有key的序列化和value的序列化如果缓存对象里有自定义类且类结构变了比如加了字段反序列化可能抛异常。遇到这种情况尽量让缓存对象保持简单的DTO结构别把Entity直接扔进去。5.5 和本系列前面内容的衔接Redisson读写操作的本质最后说点贯穿性的理解。Redisson不管封装得多漂亮它落到Redis上的命令仍然是SET、GET、HSET、ZADD这些基础指令。所以本系列前面学的Redis数据结构、持久化策略、淘汰策略、主从同步在Redisson场景下依然全部生效。举个直观例子RMap底层就是HSET/HGETRScoredSortedSet底层就是ZADD/ZRANGEBYSCORERDelayedQueue底层结合了zset和list。你懂Redis本身排查Redisson问题时用redis-cli盯着这些key的数据变化基本能看出端倪。这也是为什么我一直强调Redisson是使用Redis的上层建筑不是替代品。先搞懂Redis本身再拥抱Redisson的便利性遇到问题才能两头通透。整个系列走到这一篇Redis的完整使用体系就算是闭环了。

相关新闻

具身智能数据工厂:用云原生流水线让机器人数据“生长”起来

具身智能数据工厂:用云原生流水线让机器人数据“生长”起来

1. 具身智能卡在哪:数据不是"攒出来"的,是"长出来"的1.1 具身智能的"数据饥渴",比你想象的严重得多具身智能最近两年有多热,做机器人数据的人就有多焦虑。模型层卷得飞快,操作、导航、移…

2026/10/5 10:20:20 阅读更多 →
34岁程序员辞职两年:从“一事无成”到重新出发的复盘

34岁程序员辞职两年:从“一事无成”到重新出发的复盘

“34岁程序员辞职两年,一事无成”——这句标题最近在技术社区炸开了锅,评论区里一千多条回复,骂的却不是发帖人,而是镜子里的自己。作为一个见证过身边好几波裸辞潮、自己也亲历过长期空窗期的老开发,我太清楚这句话背…

2026/10/5 10:29:10 阅读更多 →
Qt QCPColorMap实现高性能瀑布图的完整指南

Qt QCPColorMap实现高性能瀑布图的完整指南

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

2026/10/5 11:11:19 阅读更多 →

最新新闻

Python实时2D流体模拟:从Navier-Stokes到GPU加速的完整实现

Python实时2D流体模拟:从Navier-Stokes到GPU加速的完整实现

1. 这个项目到底想解决什么问题 先说结论:我这次折腾的目标,是纯粹用 Python 从零实现一个能实时交互的 2D 流体模拟器,核心基于 Navier-Stokes 方程,最终通过 GPU 加速把计算规模拉到肉眼可见的流畅帧率,整套流程覆盖…

2026/10/5 15:47:17 阅读更多 →
追觅AURORA剑指高端:扫地机器人的体验与算法才是“主考官”

追觅AURORA剑指高端:扫地机器人的体验与算法才是“主考官”

1. 高端家电这场“科举”,到底在考什么 1.1 参数战争早就出局,体验才是真正的“主考官” 国内清洁电器市场这几年卷到什么程度?吸尘器从几千帕一路卷到上万帕,扫地机器人从单机智能卷到全能基站,洗地机又沿着“洗得干…

2026/10/5 15:47:17 阅读更多 →
Open Shell 配置指南:在 Win10/11 中重造高效经典开始菜单

Open Shell 配置指南:在 Win10/11 中重造高效经典开始菜单

用 Open Shell 之前,我先说我为什么还在折腾开始菜单。Windows 10 出来的那阵子,我是第一波从 7 升上来的用户,升级完第一件事,不是去摸新功能,而是花二十分钟把系统自带的开始菜单点了个遍,然后得出结论&a…

2026/10/5 15:47:17 阅读更多 →
插件加载失败排查指南:从failed to load plugins到web boot

插件加载失败排查指南:从failed to load plugins到web boot

早上打开流水线控制台,一整片红色日志挂在屏幕中央,最扎眼的是这行: failed to load plugins ,后面跟着 web boot: 2 entries did not activate 。我这一年多里见过不少类似场面,在 Harness 的自托管代理上、在 IA…

2026/10/5 15:47:17 阅读更多 →
CloudCompare三维模型转点云全流程:采样、导出与工程实践指南

CloudCompare三维模型转点云全流程:采样、导出与工程实践指南

1. 为什么一直用CloudCompare做点云转换1.1 它和市面其他点云工具的区别做三维相关工作久了,你一定遇到过这种场景:甲方或同事甩过来一个OBJ、FBX或者SKP模型,说“帮我转成点云”或者“帮我把点放到模型表面”。以前遇到这种需求,…

2026/10/5 15:47:17 阅读更多 →
Superpowers技能框架实战:从零构建可组合的AI工作流

Superpowers技能框架实战:从零构建可组合的AI工作流

1. 从“superpowers”这个标题说起:它到底是什么 第一次看到“superpowers”这个词,很多人脑子里蹦出来的可能是超级英雄电影,或者某个游戏里的技能系统。但如果你最近在开发者社区、效率工具圈或者AI工作流相关的讨论里频繁刷到它&#xff0…

2026/10/5 15:46:17 阅读更多 →

日新闻

马斯克杀回智能体战场,Grok 4.5万亿参数撑腰,Cursor接手数字白领项目:用TaoToken统一Key跑通多模型Agent工作流

马斯克杀回智能体战场,Grok 4.5万亿参数撑腰,Cursor接手数字白领项目:用TaoToken统一Key跑通多模型Agent工作流

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

2026/10/5 0:00:22 阅读更多 →
AI编程工具插件机制详解:plugin.json配置与加载失败排查指南

AI编程工具插件机制详解:plugin.json配置与加载失败排查指南

1. 从“plugins”这个词说起:它到底在解决什么问题如果你最近在折腾 AI 编程工具,尤其是 Cursor、Codex CLI、Claude Code 这类带 CLI 的编辑器或命令行助手,那你大概率绕不开一个词——plugins。这个词本身不新鲜,从浏览器到 IDE…

2026/10/5 0:00:23 阅读更多 →
第26课:OpenClaw|日志审计与问题诊断:把日志链路改到 TaoToken 的排查清单

第26课:OpenClaw|日志审计与问题诊断:把日志链路改到 TaoToken 的排查清单

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

2026/10/5 0:00:23 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

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

2026/10/5 5:06:42 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

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

2026/10/5 1:10:22 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

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

2026/10/5 3:06:17 阅读更多 →

月新闻

我发现了一个新思路:用 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/4 11:40:45 阅读更多 →
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/4 9:43:54 阅读更多 →
黑夜航拍船只数据集训练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/4 20:14:29 阅读更多 →