从单表到24分表:业务层分表改造的完整实战解析

前阵子刚带团队把我们内部的一套核心数据链路,从单表硬生生拆成了24张分表,业务层也跟着做了一轮彻底改造。项目代号就叫“24分表业务层改造”,从设计到上线前后折腾了两周多。这活儿看起来简单,不就是算个哈希、拼个表名嘛,真做起来全是细节。今天把这轮改造的完整思路、代码要点、迁移方案和踩过的坑都捋一遍,给后面要做分表改造的朋友做个参考。

先说清楚这套系统的背景。业务侧的数据以用户维度为主,每天写入量在千万级,单表数据量到了几亿之后,索引维护成本、写入锁竞争、慢查询都开始冒头。我们希望在不引入重量级中间件的前提下,用成本最低的方式把这波压力拆开——最终选了应用层路由 + 固定24张分表的方案。为什么是24,不是16也不是64?后面细讲。

1. 为什么是24张表:分表策略设计思路

1.1 选择24的由来:取模基数背后的业务考量

分表数量不是拍脑袋定的,核心就三个考量维度:数据增长预估、单表性能拐点、以及运维复杂度。

我当时先估算了一下未来一年的数据总量。系统日增量大概1000万行,一年就是36亿行左右。单张MySQL表在索引合理的情况下,超过2亿行之后,B+树的层级和缓存命中率都会明显劣化,写入性能也会因为页分裂和刷脏变差。所以我给自己定的目标是——单表一年内的数据量控制在1亿到1.5亿之间。

36亿除以1.5亿,约等于24。这就是24张表的由来,不是靠什么玄学公式,纯粹是容量倒推出来的。当然,为什么不用更小的16或者更大的32?16张表,单表年数据量2.25亿,已经踩到性能拐点边缘;32张表,单表1.125亿倒是安全,但表数量越多,应用层维护成本、跨表查询的聚合开销都跟着涨。24恰好是中间的甜点位。

还有一个隐性好处是24能被2、3、4、6、8、12整除。这意味着后续如果还想继续拆,迁移时有非常灵活的粒度选择。比如哪天单表又扛不住了,我可以按3的倍数把24张扩到72张,数据搬迁的逻辑会简单很多。

1.2 路由键选型:为什么锁定业务ID而不是时间

分表必须选一个稳定的路由键。我们一开始讨论过按时间分表,就是每个月一张表的方案。这种分法对写入场景非常友好,按时间顺序写,几乎没有跨表事务问题,归档也直观。

但业务查询模型把我们拉回了现实。这套系统的核心查询几乎全部围绕用户维度展开——查某个用户某段时间的记录、查用户最后的操作状态、按用户批量拉取数据。如果按时间分表,任何用户维度的查询都需要扫描全部24张表,然后聚合结果。时间分表适合“按批次扫全量”的分析场景,但在“按用户点查”的在线业务场景里,几乎是一场灾难。

所以最终路由键锁定了业务用户ID。这样同一个用户的所有数据天然落在同一张表里,点查一条SQL直接定位,不需要跨表聚合。加上用户ID本身自带比较高的基数,分布不会出现明显倾斜,这个选择无论从业务侧还是数据分布侧,都有足够的说服力。

1.3 表结构与分片键的预处理

路由键定了之后,还有一个前置动作要做——检查业务用户ID的数据类型。我们系统里的用户ID是BigInt类型,路由计算非常方便。如果你手里的路由键是字符串,比如订单号、手机号,那就涉及到字符串哈希的问题。最简单稳妥的做法是用MurmurHash或者CRC32取整,但要注意两点:一是要选一个吞吐性能好的哈希算法,二是哈希后的分布要尽量均匀。这里强烈不建议用Java原生的hashCode,一是可能出现负数,二是不同字符串的哈希分布并没有那么理想。

我们最后是直接用用户IDmod 24算出表后缀。公式是tableSuffix = userId % 24,然后统一拼成order_info_0到order_info_23这种命名格式。为什么用0到23而不是1到24?因为取模结果天然是0到23,命名跟计算对齐,省去一次+1的偏移,不容易出bug。

2. 业务层改造的整体架构:DAO层、路由层、数据访问层的重新分工

2.1 分表前后代码结构的变化

分表之前,业务代码里到处是select * from order_info where uid = ?这样的裸SQL。分表之后,所有涉及到这张表的操作都必须先经过路由层计算出物理表名,再把SQL发到对应的库表上去。

我们改造的第一步,是把所有直接操作分表对象的代码收拢到一个独立的DAO层里。对外暴露的还是业务方法签名,比如queryByUserId(userId, params),内部封装了路由计算、表名拼接、SQL执行和结果映射。上层业务代码基本不用关心底层是单表还是24张表。

这一步非常关键,也是很多团队分表改造失败的原因——没有做边界收敛,导致路由逻辑散落在各个业务代码里,维护成本直线上升。我们当时定了一条铁规矩:分表字段只允许出现在DAO层,业务层一律不感知表名。

2.2 改造范围界定:哪些SQL需要动

不是所有SQL都需要改造。改造前我们做了一次全量SQL扫描,把涉及分表对象的所有SQL都列出来,按功能分了三类:

  • 第一类是单键操作SQL,包括按用户ID的插入、更新、删除、单条查询,这类改造最简单,只需要做路由计算,SQL本身语法基本不用动。
  • 第二类是多键操作SQL,比如一次查多个用户的数据,这类需要应用层做拆分,把“一条大SQL”拆成“多条小SQL”并发执行,再聚合结果。
  • 第三类是跨全表的聚合SQL,比如后台的报表统计、全局分页查询,这类SQL没法直接路由到单表,需要走全表扫描汇总方案。

我们当时的策略是:第一类优先改造,保障核心交易链路;第二类坚决下沉到应用层;第三类业务侧能绕的绕,不能绕的就用异步离线计算,避免在线接口触发全表扫描。

2.3 路由组件的封装设计

路由组件是整个改造的核心。我们封装了一个独立的TableRouter类,对外暴露一个方法:String getTableName(Long shardKey)。内部实现就是一个取模运算。但真正工程化的时候,有几个细节绕不开:

  • 路由结果要带缓存。一个请求生命周期内,同一个用户ID可能被多次查询,每次都计算取模虽然不快但也浪费。用ThreadLocal或者请求上下文缓存一下,能省掉重复计算。我们是在DAO层入口处缓存了表名,方法返回前清掉,避免内存泄漏。
  • 路由规则要支持可配置。虽然当前是24张表,但代码里不能写死% 24,而是通过配置中心下发分表数量,后续扩缩容的时候改配置就能生效,不用重新发布代码。
  • 要对路由键做非空校验。如果业务层漏传了用户ID,路由组件拿到null直接取模就是空指针或者算错表名。我们在路由入口加了一道防御,发现路由键为空立刻抛异常并打出告警日志,方便快速定位上游调用问题。

3. 核心代码改造实操:从增删改查到跨表聚合

3.1 单键操作的改造:插入、更新、删除

单键操作是三类改造里最轻松的部分,但依然有值得注意的细节。以插入为例,原来一段很普通的insert into order_info (...) values (...),现在要先通过TableRouter算出物理表名,再拼成真正的SQL。这里最容易踩的坑是——表名拼接一定要用占位符或者白名单校验,绝对不能直接拼用户输入。虽然用户ID是BigInt类型,不太可能有注入风险,但工程习惯要养好。

我们当时用的方案是自己封装了一个SQL模板工具。业务层传入的是逻辑表名order_info和分片键用户ID,路由层解析出物理表名order_info_07,然后通过预编译PreparedStatement执行。整个过程中开发同学看到的还是逻辑表名,代码可读性没有下降,反而是路由层集中管理了所有表名拼接逻辑。

更新和删除的唯一额外注意点是——更新条件里必须带上分片键。原来可能是update order_info set status = 1 where id = 123,分表之后这条SQL根本不知道去哪张表找。必须改成where id = 123 and user_id = ?这种形式,路由层才能根据user_id定位表。这个规则很难用框架自动保证,只能在代码Review时重点审查。我们当时的办法是在DAO方法命名加约定前缀,比如updateByUidAndId,让开发一眼就注意到有没有带分片键。

3.2 单点查询的实现细节

点查是分表改造后性能收益最明显的部分。原来单表数据量几个亿的时候,一条点查SQL要扫好几层B+树,平均耗时七八毫秒。分表之后单表数据量骤降到几千万,绝大多数点查在1毫秒内就能返回。这个过程一定要实测记录前后对比数据,这既是上线后的汇报材料,也是判断分表是否达到预期目标的核心依据。

但点查也有一个需要警惕的坑:查询条件里没带分片键。比如业务方想查一个订单记录,但只传了订单号,没传用户ID。这种SQL在单表时代没问题,分表之后就抓瞎了——不知道去哪张表找。我们的处理方案有两个:

  • 第一个方案是在订单号本身里嵌入用户ID信息。比如订单号生成规则里,中间几位就是用户ID取模后的值。这种设计比较优雅,但改动订单号生成规则的影响面比较大,需要产品侧配合。
  • 第二个方案是建立路由索引表,维护订单号和用户ID的映射关系。这种方案实现成本低,但多一次查询开销,而且索引表本身也是一张表,可能也要考虑容量问题。

我们当时因为订单号规则不好动,最终采用了第二种方案,用Redis缓存这个映射关系,热点数据全部命中在内存里,性能损耗几乎可以忽略。

3.3 跨表批量查询:逐表查询、并发聚合还是中间表

跨表批量查询是分表改造里最容易翻车的地方。我们系统里有一个典型场景:运营后台按条件筛选一批用户,一次性展示这些用户的最近订单记录,条件可能涉及时间范围、订单状态、金额区间等。在单表时代一句SQL就搞定了,分表之后要跑24张表。

最初的方案非常简单粗暴——循环遍历所有表,逐张查询,然后应用层合并结果。这个方案在表数量少(比如8张以内)的时候还能接受,但到了24张表,循环查询的串行耗时直接膨胀到了秒级,接口完全不可用。

后来我们优化成并发查询方案。用固定大小的线程池调度24个查询任务,每张表一个子任务,Future拿到结果后统一归并排序。这里有几个参数需要调:线程池大小、单个查询的超时时间、结果的归并策略。我们实测下来,在数据库连接池上限允许的前提下,并发度调到12到16之间效果最好,再上去会被数据库端的连接数和CPU拖累,反而变慢。

但并发查询也不是银弹。如果条件本身非常宽泛,比如“查全平台最近一小时所有退款订单”,24张表并发扫一遍,单表可能扫出几万行,聚合后接口依然会超时。这种全局统计类需求,我们已经明确不做在线查询了,全部走离线数仓,生成报表供运营使用。分表之后,在线接口绝对不要接全表扫描类需求,这是条红线。

3.4 分页排序里的深坑:limit offset 和 order by 的拆解

分页排序在分布式分表场景下是最容易被低估的问题。运营后台的表格几乎都要分页,一页20条,按时间倒序排。单表时代很简单:order by create_time desc limit 20 offset 0。

分表之后问题来了:数据分散在24张表里,全平台的“最新20条”需要先把每张表最新的20条取出来,然后内存里排序取前20。取每张表20条,是因为你不知道全局最新20条是否可能全部落在某一张表里,所以只能先截断到单表TopN(N至少要等于一页条数),再合并。如果用户翻到第100页,offset是1980,你就需要每张表取前2000条再合并排序,性能直接爆掉。

这个问题的本质是:深分页在分表场景下几乎是无解的。我们最终的产品侧方案是:后台只允许翻前200页,超过200页强制用户用筛选条件缩小范围。同时在SQL层做优化,用create_time+id的联合索引支撑每张表的TopN查询,加上游标分页替代offset分页,把性能压到可接受范围。

这里能给大家的忠告是:分表之后,业务产品应该重新审视“全量排序分页”这个需求是否真的必要,绝大部分后台系统根本不缺这200页,缺的是一个“精准筛选器”。

3.5 统计类SQL的迁移方案:离线与近线并行

统计类SQL是分表改造的另一个重灾区。我们的系统里,业务后台有好几个统计指标:今日订单量、今日新增用户数、七日活跃用户数等等。这些指标在单表时代全部是select count(*) from order_info where create_time > ?这种实时统计。

分表之后就有两条路可以走:

一条路是实时的“按表汇总”。最朴素的实现,24张表并发跑count(*),然后把24个结果相加。这个方案在数据量不大、统计指标少的场景下是可以接受的。我们当时压测过,24张表并发count,每张表单次查询都能控制在100毫秒以内,汇总一次总耗时不超过300毫秒——这在后台报表场景里完全够用。

另一条路是异步统计。用一个定时任务每小时跑一次,把统计结果写入一张独立的汇总表,报表页面直接读汇总表。这是最稳妥的方案,不占用在线数据库资源,也不影响主链路的查询性能。

综合下来,我们当时是对折处理的:核心看板上的数字走异步统计,保证实时性要求不高的场景稳定;数据校验类的临时统计,走按表汇总的临时方案。两条路并行,谁也别堵谁。

4. 数据迁移与灰度切换:从单表平滑过渡到24张分表

4.1 存量数据的全量搬迁策略

分表改造里代码改动只是冰山一角,真正的硬骨头是存量数据怎么平滑搬到24张表里,而且不能停服太久。

我们的存量数据当时大概有8亿行。全量迁移的方案选了很久,最后敲定的是原生SQL导出+并发导入。按用户ID取模,把原来的单表数据拆成24份,每一份并行导入到对应的分表。全量数据迁移的耗时主要取决于磁盘IO和目标库的写入性能,实测下来,在目标库配置正常的条件下,8亿行数据大约用了6个小时完成搬迁。

这里有一个非常值得注意的细节:迁移过程中,源表依然在持续写入新数据。也就是说,全量迁移只能保证搬到某一时刻的快照,之后新增的数据会漏掉。所以光有全量迁移是不够的,必须配合增量同步,这个方案通常叫“全量+增量”双轨迁移。

4.2 增量同步与双写机制

增量同步我们采用了一个非常经典的方案:在应用层做双写。改造初期,所有写操作同时写入单表和分表,单表保证读的可用性,分表积累新数据。等全量迁移完成、数据校验通过后,再把读流量切到分表。

具体执行步骤分三步:

  1. 应用发布新版本,DAO层改为双写模式。业务写操作先写单表(老路径),再异步写分表(新路径)。异步写有一个隐患是丢数据,所以我们还加了一张本地消息表,分表写入失败就记录失败状态,由补偿任务重试。
  2. 全量迁移完成,进入数据校验阶段。抽查若干用户ID,对比单表和对应分表里的数据量、关键字段的哈希值是否一致。我们当时的抽检率是1%,也就是每100条数据里抽1条出来比对,发现不一致就定位原因重新搬迁。
  3. 校验通过,正式切读。把读流量按10%、30%、50%、100%的比例逐步灰度切到分表,每一步都盯监控指标,确认无异常后再继续加量。

这整套方案做下来,业务全程无感,没有停服窗口。代价是开发同学多写了一套双写逻辑,以及并发量会短暂提升一些,但换来的是平滑过渡,这笔账非常划算。

4.3 双写期间的典型数据不一致场景

双写方案最怕数据不一致,而最容易出现不一致的场景就是并发更新。比如同一个用户同时有两个请求,一个请求更新status=1,另一个请求更新status=2。单表写入顺序和分表写入顺序可能不一样,最终两边数据就可能不一致。

这个问题本质上是一个分布式事务问题。我们没有引入重量级分布式事务框架,而是走了一条轻量级路线:双写时,先写单表,拿到主键ID后,再把同一主键ID写入分表。更新的时候分表SQL里带上版本号字段,两次更新如果版本号不一致,说明出现了并发冲突,补偿任务以单表的数据为准覆盖分表。

这套机制虽然不能百分之百杜绝瞬间不一致,但能把不一致窗口缩到毫秒级,而且最终能通过补偿任务收敛到一致状态。对于多数业务系统来说,这种“最终一致性”已经完全够用了。

5. 踩坑实录:分表改造里那些防不胜防的细节

5.1 事务跨表:分布式事务问题的简化处理

分表之前,一个业务操作里改多张表的数据,直接用本地事务就行。分表之后,数据分散在多个物理表里,本地事务管不了跨表操作了。

我们遇到的第一个实际问题就是:用户下单的流程里,要同时更新“订单表”和“用户账户余额表”。这两张表如果都分表了,各自的物理表后缀可能不一样,一个在表0,一个在表15,就不能在同一个数据库事务里完成。

当时我们没有立刻上分布式事务中间件,而是先做了两个层面的缓解:

  • 第一层:把涉及跨表事务的业务操作,拆分成“先更新主表、后更新从表”的流程,通过本地消息表记录状态,由异步任务保证最终一致。这种方案牺牲了一点实时一致性,换来了应用的极度简化。
  • 第二层:尽量把相关联的数据放到同一张物理表里。比如订单表和订单明细表,在分表候选键上采用相同的路由键,保证一个用户的所有订单和订单明细都在同一张分表里。这样同一个业务环节内的强一致操作,就可以退化为单表单事务。

提示:分表场景下,尽量不要在业务代码里写跨表事务。绝大多数分布式事务的开销和复杂度,远大于业务上那几毫秒的强一致需求。

5.2 连接池被打满:并发查询导致的数据库连接数爆炸

分表改造上线后我们遇到过一个比较惊险的问题:某次大促预热期间,数据库连接池突然被打满,部分接口报连接获取超时。

排查下来,原因其实不复杂。原来一个查询只需要1个数据库连接,改造后变成了24个并发的“子查询”,一个请求瞬间占用24个连接。如果这个接口的QPS是200,瞬间就有4800个连接在跑,连接池不炸才怪。

这个问题的解法有两个维度:

  • 应用侧:限制并发查询的总连接数,线程池的大小和数据库连接池容量必须联动设计。我们当时把连接池最大容量压到单库单表能承受的范围内,然后通过信号量机制限制跨表查询的并发度,宁可让请求排队,也不能击穿数据库。
  • 架构侧:对跨表查询场景做分流,把跨24张表的AP查询放到只读从库去执行,不和在线交易链路争抢主库连接。

这里再强调一句:分表之后,数据库连接池的监控必须提上日程,连接使用率、等待时长、活跃连接数都要和改造前做对比基线,上线后如果出现明显波动,第一时间就要看是不是并发子查询造成的。

5.3 热点用户问题:分表不是万能的

分表解决的是“数据量大”的问题,但解决不了“数据倾斜”的问题。我们上线之后就观察到某个头部大客户,名下订单数据量占据了某个分表总数据量的将近15%。这张分表的查询和写入压力明显高于其他表,单表性能再次成为瓶颈。

这种场景在To C业务里相对少见,但在To B的SaaS系统里非常普遍。我们的应对策略是:

  • 对大客户的数据单独拆一张专属分表,也就是“超大规模租户独立路由”方案。在路由组件里加一层判断,如果用户ID属于超大客户名单,直接路由到专属表,不走取模逻辑。
  • 这一层逻辑要尽量前置,最好在路由组件内部解决,不要让业务代码感知。我们当时在配置中心维护了一份“超大客户路由映射表”,路由组件启动时加载到内存,每次路由时先查名单,命中就走专属表。

这个方案会带来额外的代码复杂度,但相比让某一个分表被热点压垮,这点复杂度完全是值得的。

5.4 自增主键的失效:分布式ID的必要性

单表时代,主键ID交给数据库的自增主键就行。分表之后,24张表各自维护自增ID,就会出现同一个ID在表0和表1里分别存在,而且业务上无法通过ID唯一标识一条记录,只有“ID + 用户ID”的组合才能唯一定位。

这个问题的本质是:分布式环境下,全局唯一ID不能再依赖单库自增。我们的改造方案是引入了一套全局ID生成服务,基于“时间戳 + 机器号 + 自增序号”生成64位ID,保证全局唯一且趋势递增,写入任何一张分表都不会有冲突。

如果你手头不想额外引入ID服务,至少也要用雪花算法自己实现一个。因为趋势递增对于数据库索引性能非常重要,如果用随机UUID做主键,B+树的写放大和页分裂问题会在分表场景下被放大数倍。

5.5 上线后的性能监控与容量规划

最后一块拼图是监控。分表改造不是上线就算完了,上线后我们持续盯了一个月的性能指标,重点关注几个核心数据:

  • 慢查询数量:和改造前做对比,理想情况是下降50%以上,如果没有明显下降,说明索引或者SQL本身还有问题。
  • 单表QPS分布:通过路由日志统计每张分表的请求量,看是否存在倾斜,及时发现热点。
  • 数据增长率:按周统计每张分表的数据量增长,提前估算下一次扩容的时间点。

这种监控体系不需要很复杂的组件,用现成的日志采集和监控看板就可以做到。关键是改造前后要有基线对比数据,否则你没法证明改造到底带来了什么收益。

最后再分享一点个人的实操体会

分表这套东西,听上去是高并发架构里的常见套路,但真正把一个存量单表系统改造成分表结构,过程远比想象中琐碎。其中最磨人的不是技术本身,而是“怎么让团队里所有人都对分表保持敬畏”——每一个没带分片键的查询、每一条绕过路由层的SQL、每一个意外落空的事务,都可能在上线后变成事故。

我个人的建议是,做这类改造之前,一定要先想清楚三个问题:业务未来一年的数据增长到底有多快?核心查询场景是否能够稳定地带上传分片键?跨表聚合类需求能不能从在线链路里剥离出去?这三个问题没有明确答案就动手,哪怕代码写完了,后续的运维成本和业务适配成本也会让你很难受。

如果你正打算做类似的分表改造,不妨先拿一张业务影响最小的辅助表做试点,把路由、双写、迁移、灰度完整的链路跑一遍,积累经验后再动核心表。这比直接拿核心链路开刀要稳妥得多。希望这轮改造的经验,能帮你少走一些我们走过的弯路。

相关新闻

上下文图谱:破解超大组织里智能体落地的断点难题

上下文图谱:破解超大组织里智能体落地的断点难题

1. 十万人的组织里,智能体到底卡在哪一环这两年“智能体”几乎成了企业数字化的标配提法:让AI理解任务、拆解流程、调用工具、给出答案。但真把它放到十万人员工的巨型组织里,事情就变得完全不一样了。我接触过不少负责企业AI基础设施的团队&…

2026/10/20 6:05:24 阅读更多 →
CRC计算源码选型指南:参数模型、查表法与逐位法实现及避坑实践

CRC计算源码选型指南:参数模型、查表法与逐位法实现及避坑实践

简介:这份循环冗余校验码(CRC)计算源代码合集面向嵌入式开发、通信协议实现与数据校验方向的学习者,帮助理解并落地CRC-8、CRC-16、CRC-32等常见算法的软件实现与硬件映射思路。压缩包共1220个文件,约6.65MB&#xff0…

2026/10/20 6:04:24 阅读更多 →
E22-400T22D LoRa模块实战:配置、距离测试与避坑指南

E22-400T22D LoRa模块实战:配置、距离测试与避坑指南

做物联网设备这行,无线通信方案永远是绕不开的一道坎。这篇要聊的是一款非常经典的E22-400T22D LoRa模块,很多朋友在户外采集、农业监测、机房环境监控这类项目里都会遇到它。市面上那么多无线模块,为什么LoRa方案能站住脚,这款22…

2026/10/20 6:04:24 阅读更多 →

最新新闻

永磁同步电机无感FOC实战:龙贝格观测器与PLL锁相环方案解析

永磁同步电机无感FOC实战:龙贝格观测器与PLL锁相环方案解析

前阵子把一套基于龙贝格观测器的永磁同步电机无感FOC方案从仿真搬到了实机台架,整个过程前后折腾了小两个月。核心思路很直接:用龙贝格观测器在线提取电机反电势,再用PLL锁相环从反电势里解出转子位置和速度,完全甩掉编码器和旋变…

2026/10/20 6:48:42 阅读更多 →
深入理解C++ std::string:存储机制、性能陷阱与避坑指南

深入理解C++ std::string:存储机制、性能陷阱与避坑指南

刚开始用C那会儿,我对std::string的理解就是“一个会自动长大的字符数组”。但真正在工程里写多了之后,我发现自己对它的误解比想象中要多。字符串处理几乎无处不在,无论是解析配置、拼接日志,还是做协议编解码,string…

2026/10/20 6:48:42 阅读更多 →
C++模板元编程实现选择排序

C++模板元编程实现选择排序

前言 模板元编程(template metaprogramming, TMP)是在编译期用类型和常量完成计算的技术。它的"变量"是类型与 static constexpr 值,"函数"是类模板特化,"循环"是递归实例化,"条件…

2026/10/20 6:48:42 阅读更多 →
100行代码手写Hermes式智能体框架并接入飞书机器人

100行代码手写Hermes式智能体框架并接入飞书机器人

1. 为什么我要自己动手写一个智能体框架1.1 从“玩具”到“工具”的转折点市面上开源的智能体框架我几乎都翻过一遍。LangChain 生态庞大,但依赖链太长,一个简单的对话循环要引入几十个包;AutoGen 的多智能体协作很惊艳,可一旦要接…

2026/10/20 6:48:42 阅读更多 →
技能管理系统Skills:用数据化技术画像精准定位自身能力短板

技能管理系统Skills:用数据化技术画像精准定位自身能力短板

从面试被问到“你还会什么”那一刻,我才意识到自己的技能清单有多失真。简历上写着“熟悉微服务”,可真聊起服务拆分和容错设计,脑子里能拿出来的只有几个名词;写了三年业务代码,却说不清自己到底擅长什么、短板在哪里…

2026/10/20 6:48:42 阅读更多 →
国产大模型崛起:榜单前20占6席,技术底座与落地实践全解析

国产大模型崛起:榜单前20占6席,技术底座与落地实践全解析

1. 榜单背后的真实格局:国产大模型凭什么挤进前二十全球AI模型榜单前20名里国产模型占了6个,这个数字放在三年前几乎没人敢想。我翻了一圈榜单的评测维度,发现这次上榜的国产模型覆盖了文本理解、代码生成、多模态推理、长上下文处理几个主要…

2026/10/20 6:47:42 阅读更多 →

日新闻

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

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

2026/10/20 1:01:30 阅读更多 →
ESP32舵机控制指南:原理、多路驱动与避坑实战

ESP32舵机控制指南:原理、多路驱动与避坑实战

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

2026/10/20 1:01:30 阅读更多 →
位移法实现一阶低通滤波:单片机ADC采样降噪实战

位移法实现一阶低通滤波:单片机ADC采样降噪实战

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

2026/10/20 1:01:30 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/19 10:02:04 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/19 17:32:41 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 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/19 2:54:50 阅读更多 →
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/19 9:10:22 阅读更多 →
黑夜航拍船只数据集训练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/18 12:16:16 阅读更多 →