当前位置: 首页 > article >正文

【后端开发】一次把 MySQL 深分页讲透:从 limit 1000000,10 到游标分页的工程化改造

文章目录前言一、复现深分页问题1.1 准备测试表1.2 准备测试数据1.3 先看普通分页查询1.4 用 EXPLAIN 看一下执行计划1.5 LIMIT 1000000, 20 到底慢在哪里1.6 为什么 MySQL 不能直接跳到第 100 万条二、四种常见解决方案2.1 方案一主键游标分页2.2 方案二created_at id 复合游标分页2.3 方案三延迟关联2.4 方案四覆盖索引2.5 几种方案对比三、业务层面怎么解决深分页3.1 限制最大页数3.2 引导用户使用筛选条件3.3 用“加载更多”替代“跳到第 N 页”3.4 冷热数据拆分和历史数据归档写在文后 个人主页铁皮哥欢迎关注 作者简介28届校招生后端开发/Agent 方向在学 学习内容Java、Python、计算机视觉、大语言模型、Agent开发 专栏内容从零开始的Claude Code零代码生活持续更新中✨不只背八股更想搞懂为什么这样设计前言假设我们有一张订单表里面已经有 1000 万条数据。后台管理系统需要支持分页查询订单列表最开始的 SQL 可能会写成这样SELECT*FROMordersORDERBYidLIMIT1000000,20;从语义上看这条 SQL 很简单按照id排序从第 1000000 条之后开始取 20 条数据。但问题也出在这里。很多人第一次看到这条 SQL 时容易下意识觉得既然最后只返回 20 条数据那查询成本应该也只和这 20 条数据有关。可实际上MySQL 并不是直接“跳到”第 1000000 条记录然后取后面的 20 条。它需要先按照排序规则找到前面的 1000020 条记录再丢掉前面的 1000000 条最后才把剩下的 20 条返回。这条 SQL 真正昂贵的地方不是返回了多少数据而是为了返回这 20 条数据数据库需要先扫描并丢弃大量无用数据。如果查询还是SELECT *情况会更糟。因为 MySQL 可能不仅要扫描索引还要根据主键回表读取完整行数据。随着 offset 越来越大这部分无效扫描和回表成本也会越来越高。这就是深分页问题最核心的矛盾用户只想看 20 条数据但数据库可能已经为此处理了上百万条记录。一、复现深分页问题这里我用一张订单表来模拟真实业务里的列表查询场景。1.1 准备测试表先创建一张orders表。为了更接近实际业务这张表不会只保留一个id字段而是加上用户、订单状态、金额、创建时间、更新时间等字段。CREATETABLEorders(idBIGINTPRIMARYKEYAUTO_INCREMENTCOMMENT订单ID,user_idBIGINTNOTNULLCOMMENT用户ID,statusTINYINTNOTNULLCOMMENT订单状态,amountDECIMAL(10,2)NOTNULLCOMMENT订单金额,created_atDATETIMENOTNULLCOMMENT创建时间,updated_atDATETIMENOTNULLCOMMENT更新时间,INDEXidx_created_at(created_at),INDEXidx_user_created(user_id,created_at))ENGINEInnoDBDEFAULTCHARSETutf8mb4COMMENT订单表;这张表里有几个比较关键的点。id是自增主键用来模拟最常见的主键分页场景。created_at表示订单创建时间很多后台列表都会按照时间倒序查询所以这里也单独给它建了一个索引。user_id created_at是一个组合索引用来模拟“查询某个用户的订单列表”这种业务场景。1.2 准备测试数据接下来需要往表里插入一批测试数据。数据大致满足下面几个特点user_id随机分布模拟不同用户下单 status在几个订单状态之间随机 amount随机金额 created_at分布在最近一年 updated_at在 created_at 之后随机生成可以用存储过程、Java 脚本、Go 脚本或者 Python 脚本批量插入。这里不展开完整造数脚本只给一个大概思路。伪代码类似这样INSERTINTOorders(user_id,status,amount,created_at,updated_at)VALUES(10001,1,99.90,2026-01-01 10:00:00,2026-01-01 10:05:00),(10002,2,199.00,2026-01-01 10:01:00,2026-01-01 10:06:00),...;实际插入时不要一条一条插否则会非常慢。可以采用批量插入比如每批插入 5000 条或 10000 条。如果用 Java 或 Python 脚本造数核心逻辑大概是循环生成订单数据 每 5000 条拼接成一批 INSERT 提交一次事务 重复执行直到插入 1000 万条这里有一个小细节造数的时候最好让created_at有一定重复概率。比如同一秒内生成多条订单。这样后面讲created_at id复合游标分页时才更容易解释为什么不能只用created_at做 cursor。1.3 先看普通分页查询数据准备好之后我们先执行几条普通分页 SQL。第一条是浅分页SELECT*FROMordersORDERBYidLIMIT20,20;第二条是中等 offsetSELECT*FROMordersORDERBYidLIMIT100000,20;第三条是深分页SELECT*FROMordersORDERBYidLIMIT1000000,20;从 SQL 语义上看这三条语句都只返回 20 条数据。但它们的区别在于 offset 不同。SQLoffsetsize含义LIMIT 20, 202020跳过 20 条返回 20 条LIMIT 100000, 2010000020跳过 10 万条返回 20 条LIMIT 1000000, 20100000020跳过 100 万条返回 20 条这时候可以打开profiling或者直接用程序统计执行耗时。比如测试结果可能类似这样查询语句offset返回条数耗时LIMIT 20, 2020205 msLIMIT 100000, 201000002080 msLIMIT 1000000, 20100000020700 ms这里的数字不一定和你的机器完全一致因为它会受到很多因素影响比如机器配置、MySQL 版本、Buffer Pool 大小、数据是否在内存中、磁盘性能等等。但趋势通常是比较明显的offset 越大查询越慢。也就是说哪怕最终都只返回 20 条数据MySQL 的查询成本也不是固定的。1.4 用EXPLAIN看一下执行计划接下来可以用EXPLAIN看一下 MySQL 对这条 SQL 的执行计划。EXPLAINSELECT*FROMordersORDERBYidLIMIT1000000,20;因为这里按照主键id排序MySQL 通常会走主键索引。你可能会看到类似这样的结果type: index key: PRIMARY rows: 1000020 Extra:重点看两个地方。第一个是key。如果key是PRIMARY说明 MySQL 使用了主键索引。第二个是rows。它表示 MySQL 预估需要扫描的行数。对于LIMIT1000000,20来说MySQL 并不是只扫描 20 行而是要扫描大约1000000 20行。这就能解释为什么深分页会慢。很多人会有一个误区既然这条 SQL 走了主键索引那应该很快。但实际上走索引不代表一定快。如果 offset 很大即使走的是主键索引MySQL 仍然需要沿着索引从前往后扫描很多条记录。索引可以让扫描更有序但它不能让 MySQL 直接无成本地跳过前面的 100 万条数据。1.5LIMIT 1000000, 20到底慢在哪里现在我们可以回到最核心的问题SELECT*FROMordersORDERBYidLIMIT1000000,20;这条 SQL 的执行过程可以粗略理解成这样1. 按照 id 顺序扫描数据 2. 找到前 1000020 条记录 3. 丢弃前 1000000 条 4. 返回最后 20 条用图表示就是[1] [2] [3] ... [999998] [999999] [1000000] [目标20条] └──────────────── 被扫描但最终丢弃的数据 ────────────────┘所以它慢的关键不是最后返回了 20 条而是前面那 100 万条也被处理过了。如果查询语句是SELECT*FROMordersORDERBYidLIMIT1000000,20;由于查询的是*MySQL 需要返回整行数据。如果排序字段和查询字段不能完全通过索引覆盖就可能发生大量回表。这也是为什么深分页里经常会提到两个关键词大量扫描 大量丢弃如果是SELECT *还要额外加上大量回表1.6 为什么 MySQL 不能直接跳到第 100 万条这里可能会有一个疑问既然有索引为什么 MySQL 不能直接跳到第 100 万条原因是B 树索引擅长的是按条件定位比如WHEREid1000000这种查询可以直接利用索引定位到id 1000000附近然后继续往后扫描。但是LIMIT1000000,20里面的1000000不是某个具体的id值而是“跳过 1000000 行”。这两者是不一样的。id 1000000的意思是从 id 大于 1000000 的位置开始查而LIMIT 1000000, 20的意思是按照排序结果跳过前 1000000 行前者有明确的索引定位条件后者没有。所以 MySQL 只能按照排序结果往后数数够 1000000 行之后再返回后面的 20 行。二、四种常见解决方案上一章我们已经把深分页慢的原因拆开了。简单来说LIMIT 1000000, 20慢不是因为它返回了 20 条数据而是因为 MySQL 为了拿到这 20 条需要先扫描并丢弃前面的 100 万条。所以优化深分页的核心思路也很明确不要让数据库做大量无意义的 offset 扫描。下面来看几种常见解决方案。2.1 方案一主键游标分页如果列表是按照主键递增顺序展示的那么最直接的优化方式就是把 offset 分页改成游标分页。原来的分页 SQL 是这样SELECT*FROMordersORDERBYidLIMIT1000000,20;这种写法的问题在于1000000表示要跳过前 100 万条记录。MySQL 没办法直接跳过这些记录它还是要按照id顺序往后扫描扫描到第 1000020 条之后再丢掉前面的 100 万条。如果改成游标分页SQL 可以写成这样SELECT*FROMordersWHEREid1000000ORDERBYidLIMIT20;这里的1000000就不再是 offset而是上一页最后一条数据的id。也就是说第一页查询SELECT*FROMordersORDERBYidLIMIT20;假设第一页最后一条数据的id是100020那么下一页就可以这样查SELECT*FROMordersWHEREid100020ORDERBYidLIMIT20;这样 MySQL 就可以直接利用主键索引定位到id 100020的位置然后继续往后扫描 20 条数据。相比LIMIT 1000000, 20这种方式不需要从头扫描并丢弃大量数据。对应到接口设计上也可以从传统的页码分页GET /orders?page50000page_size20改成游标分页GET /orders?last_id100020page_size20接口返回时带上下一个游标{items:[{id:100021,user_id:9527,status:1,amount:99.90}],next_cursor:100040}下次请求时前端把next_cursor传回来后端继续从这个位置往后查。这个方案的优点非常明显查询成本和页码深度关系不大只和本次要取多少条数据有关。它很适合下面这些场景订单流水 消息列表 评论列表 操作日志 Feed 流 任务执行记录不过它也有一个缺点不适合跳页。比如用户想直接跳到第 50000 页游标分页就不太好支持。因为它的设计思路不是“第几页”而是“从上一次看到的位置继续往后查”。所以主键游标分页更适合“上一页 / 下一页 / 加载更多”这种交互而不适合强依赖页码跳转的后台表格。2.2 方案二created_at id复合游标分页实际业务里很多列表并不是按照id排序而是按照创建时间倒序排序。比如订单列表通常会把最新订单放在最前面SELECT*FROMordersORDERBYcreated_atDESCLIMIT1000000,20;这种写法同样会遇到深分页问题。如果直接改成时间游标可以写成SELECT*FROMordersWHEREcreated_at2026-05-01 12:00:00ORDERBYcreated_atDESCLIMIT20;它的含义是查询创建时间早于某个时间点的 20 条订单。看起来没问题但这里有一个很容易被忽略的细节created_at不是唯一的。在高并发系统里同一秒甚至同一毫秒内都可能产生多条订单。如果只用created_at作为游标可能会出现数据重复或者数据丢失。举个例子假设第一页最后一条数据是id 100 created_at 2026-05-01 12:00:00但数据库里还有几条数据的created_at也是这个时间id 99 created_at 2026-05-01 12:00:00 id 98 created_at 2026-05-01 12:00:00 id 97 created_at 2026-05-01 12:00:00如果下一页查询条件写成WHEREcreated_at2026-05-01 12:00:00那么这些同一时间的数据就会被跳过。所以更稳的做法是使用created_at id作为复合游标。排序也要保持一致ORDERBYcreated_atDESC,idDESC下一页查询可以这样写SELECT*FROMordersWHEREcreated_at2026-05-01 12:00:00OR(created_at2026-05-01 12:00:00ANDid100)ORDERBYcreated_atDESC,idDESCLIMIT20;这条 SQL 的含义是如果创建时间更早直接进入下一页如果创建时间相同就继续比较id只取id更小的数据。这样可以保证分页顺序稳定不容易出现重复或丢数据。对应的索引可以设计成CREATEINDEXidx_created_idONorders(created_at,id);如果查询方向是倒序MySQL 也可以利用这个组合索引来减少扫描成本。接口返回时cursor 可以包含两个字段{items:[{id:100,created_at:2026-05-01 12:00:00,status:1}],next_cursor:{created_at:2026-05-01 12:00:00,id:100}}真实项目里一般不会直接把这个对象暴露给前端而是做一层编码。比如把{created_at:2026-05-01 12:00:00,id:100}编码成一个字符串eyJjcmVhdGVkX2F0IjoiMjAyNi0wNS0wMSAxMjowMDowMCIsImlkIjoxMDB9前端不需要关心 cursor 内部结构只需要在下一次请求时原样传回来。GET /orders?cursoreyJjcmVhdGVkX2F0IjoiMjAyNi0wNS0wMSAxMjowMDowMCIsImlkIjoxMDB9limit20后端解析 cursor 后再拼出对应的查询条件。这种方式非常适合时间线类型的数据比如订单列表 评论列表 消息列表 通知列表 Agent Run 记录 工具调用日志 会话历史2.3 方案三延迟关联前面两种游标分页都很好但它们有一个共同问题不适合任意跳页。可是有些后台管理系统确实会要求保留页码分页。比如运营后台、订单后台、财务对账系统页面上可能就是一个传统表格第一页 第二页 第三页 ... 跳到第 N 页如果产品形态暂时不能改成 cursor 分页那可以考虑延迟关联。原始 SQL 是SELECT*FROMordersORDERBYidLIMIT1000000,20;这个写法会直接在大 offset 场景下读取完整行数据。优化后可以改成SELECTo.*FROMorders oJOIN(SELECTidFROMordersORDERBYidLIMIT1000000,20)tONo.idt.id;这条 SQL 分成两步理解。第一步子查询只查idSELECTidFROMordersORDERBYidLIMIT1000000,20因为id本身就是主键索引所以这一步只需要扫描主键索引拿到目标页的 20 个主键。第二步再根据这 20 个主键回表查询完整数据SELECTo.*FROMorders oJOIN(...)tONo.idt.id;这样做的好处是前面那 100 万条被跳过的数据只发生在更轻量的索引扫描上而不是对每一行都读取完整数据。尤其是当表字段很多、单行数据比较大时这种优化会更明显。比如订单表里如果还有很多字段收货地址 备注 优惠信息 扩展 JSON 发票信息 物流信息直接SELECT *深分页成本会比较高。而延迟关联可以先在索引里找到目标页的主键再只对最终需要返回的 20 条数据回表。不过这个方案也不要神化。延迟关联并没有从根上消灭 offset。它依然需要扫描前面的 100 万个索引项只是避免了对前面 100 万行都读取完整数据。所以它更适合这种场景业务必须保留页码分页 表字段比较多 直接 SELECT * 深分页很慢 短期内不方便改成 cursor 分页如果业务允许改接口优先级通常还是 cursor 分页更高。2.4 方案四覆盖索引还有一种常见思路是使用覆盖索引。很多慢 SQL 之所以慢是因为查询写成了SELECT*FROMordersORDERBYcreated_atDESCLIMIT1000000,20;但实际上列表页可能根本不需要展示所有字段。比如订单列表只展示订单 ID 用户 ID 订单状态 订单金额 创建时间那就没必要SELECT *。可以把查询改成SELECTid,user_id,status,amount,created_atFROMordersORDERBYcreated_atDESCLIMIT1000000,20;然后设计一个覆盖索引CREATEINDEXidx_order_listONorders(created_at,id,user_id,status,amount);覆盖索引的意思是查询需要的字段都能从索引里直接拿到不需要再回表读取完整行数据。这样可以减少大量回表成本。如果列表页本来只需要几个字段但是 SQL 却写成SELECT *那就会导致很多不必要的数据读取。这一点在真实项目里非常常见。因为一开始数据量小SELECT *看起来没什么问题开发也方便。等数据量上来以后列表查询越来越慢再回头看就会发现很多字段其实根本没有用到。不过覆盖索引也不是越多越好。索引本身是有成本的会占用更多磁盘空间 插入和更新数据时需要维护索引 索引字段太多会让索引变大 过多索引会影响写入性能所以覆盖索引更适合那些查询频率高、字段相对固定、性能收益明显的列表接口。比如订单列表、日志列表、消息列表这类接口如果它们的查询字段很稳定就可以考虑用覆盖索引优化。2.5 几种方案对比到这里四种常见优化方案就讲完了。它们的目标都是减少深分页带来的无效成本但适用场景不太一样。方案核心思路适合场景优点缺点主键游标分页用id last_id替代LIMIT offset按主键顺序浏览的数据性能好实现简单不支持任意跳页created_at id复合游标用时间和主键共同定位下一页时间线、订单、消息、日志排序稳定适合真实业务接口和 SQL 都比普通分页复杂延迟关联先查目标页主键再回表查完整数据必须保留页码分页的后台系统兼容原有分页模式减少回表仍然需要扫描 offset覆盖索引查询字段全部从索引中获取字段固定的高频列表查询减少回表提升查询效率增加索引存储和维护成本技术方案没有绝对最优只有是否适合当前业务。三、业务层面怎么解决深分页前面讲的几种方案主要还是站在 SQL 和索引的角度解决问题。但在真实项目里深分页很多时候不只是数据库问题。比如下面这条 SQLSELECT*FROMordersORDERBYcreated_atDESCLIMIT1000000,20;从技术角度看我们可以用游标分页、延迟关联、覆盖索引去优化它。但从业务角度看也应该反过来问一句用户真的需要翻到第 100 万条订单吗很多性能问题并不是数据库不够强而是业务查询方式本身太粗放。如果产品允许用户在一个几千万数据量的列表里无限制翻页那数据库迟早会被拖慢。所以深分页优化不能只靠 SQL还要从产品交互、接口设计和数据架构上一起处理。3.1 限制最大页数最直接的业务方案是限制最大可翻页范围。比如后台订单列表最多允许查询前 100 页每页 20 条最多查看前 100 页也就是最多查看 2000 条数据如果用户继续往后翻可以提示数据量过大请缩小筛选范围后再查询这个做法听起来有点“粗暴”但在很多后台系统里其实很合理。因为用户翻到非常靠后的页码时通常不是为了“浏览”而是想找某一类数据。比如运营同学想查某个时间段的订单 某个用户的订单 某个状态下的异常订单 某个金额范围内的订单这时继续让他一页一页翻体验并不好。更合理的做法是引导他增加筛选条件。限制最大页数的本质不是禁止用户查数据而是避免用户用低效的方式查数据。这一点在后台系统里尤其重要。后台系统不像普通用户端页面很多查询都是直接打到核心业务表上。如果每个人都能随便翻到几万页数据库压力会非常不可控。所以我觉得对于大数据量列表可以提前定一个规则默认只支持查看最近数据 超过一定页数后必须增加筛选条件 历史数据走专门的查询入口这比单纯在 SQL 上做优化更稳定。3.2 引导用户使用筛选条件深分页出现频繁往往说明查询范围太大。比如用户直接查全量订单SELECT*FROMordersORDERBYcreated_atDESCLIMIT1000000,20;这个查询没有任何过滤条件只是按时间倒序翻页。如果订单表有几千万条数据越往后翻肯定越慢。更合理的方式是让用户先缩小查询范围。比如按时间筛选SELECT*FROMordersWHEREcreated_at2026-05-01 00:00:00ANDcreated_at2026-06-01 00:00:00ORDERBYcreated_atDESCLIMIT20;或者按订单状态筛选SELECT*FROMordersWHEREstatus1ORDERBYcreated_atDESCLIMIT20;再或者组合多个条件SELECT*FROMordersWHEREcreated_at2026-05-01 00:00:00ANDcreated_at2026-06-01 00:00:00ANDstatus1ORDERBYcreated_atDESCLIMIT20;这样做有两个好处。第一减少数据库需要扫描的数据量。第二更符合用户真实的查询意图。很多时候用户不是想看“第 50000 页”而是想找到“5 月份未支付的订单”或者“某个用户最近的订单”。从这个角度看筛选条件其实比分页更重要。分页解决的是“数据怎么分批返回”筛选解决的是“用户到底想查哪部分数据”。如果筛选条件设计得好很多深分页问题自然就不会出现。在实际项目里可以优先考虑这些筛选维度筛选维度示例时间范围最近 7 天、最近 30 天、自定义时间段状态待支付、已支付、已取消、退款中用户维度用户 ID、手机号、用户名业务编号订单号、任务 ID、流水号金额范围大于 100、小于 1000异常类型支付失败、库存不足、调用失败对于后台系统来说最好不要只给一个大列表然后让用户从第一页慢慢翻。更好的设计是先筛选再分页。3.3 用“加载更多”替代“跳到第 N 页”并不是所有列表都适合页码分页。比如下面这些场景消息列表 评论列表 通知列表 Feed 流 操作日志 Agent 执行记录 工具调用日志用户通常只关心最近的数据。这时页面上如果还设计成第 1 页、第 2 页、第 3 页、跳到第 10000 页其实并不符合使用习惯。更自然的交互是下拉刷新 加载更多 继续查看更早记录对应到后端接口也可以从传统的 page 模式GET /orders?page50000page_size20改成 cursor 模式GET /orders?cursorxxxlimit20这个变化看起来只是接口参数变了但背后代表的是查询模型的变化。page page_size关心的是我要第几页cursor limit关心的是从上一次看到的位置继续往后查对于大数据量列表来说后者通常更稳定。尤其是数据还在不断写入的时候cursor 分页也更容易保证分页结果的连续性。比如用户正在查看消息列表时系统又插入了新的消息。如果用页码分页第二页的数据可能会因为新数据插入而发生偏移导致用户看到重复数据或者漏掉数据。而 cursor 分页是基于上一页最后一条记录继续查受新增数据影响更小。所以在设计列表接口时可以先问自己一个问题这个列表真的需要跳到第 N 页吗如果答案是否定的就没必要强行使用页码分页。3.4 冷热数据拆分和历史数据归档如果一张表的数据量持续增长只靠分页优化是不够的。比如订单表、日志表、消息表、任务执行记录表都有一个共同特点数据一直在写入 最近数据访问频繁 历史数据访问较少这类表很适合做冷热数据拆分。比如订单数据可以拆成近 3 个月订单orders_hot 3 个月以前订单orders_archive大多数在线查询只查热表SELECT*FROMorders_hotWHEREcreated_at2026-05-01 00:00:00ORDERBYcreated_atDESCLIMIT20;如果用户确实需要查询历史订单再走历史查询入口。这种设计的好处是核心在线表的数据量可以控制在一个相对稳定的范围内查询性能也更容易保障。对于日志、Agent 执行记录这类数据也可以采用类似思路。比如最近 7 天日志放在 MySQL 热表 更早日志归档到 ClickHouse / Elasticsearch / 对象存储所以当数据量越来越大时不要把所有查询压力都压到一张 MySQL 表上。分页优化只能缓解问题数据分层才能从架构上降低压力。写在文后期待您的一键三连如果有什么问题或建议欢迎在评论区交流

相关文章:

【后端开发】一次把 MySQL 深分页讲透:从 limit 1000000,10 到游标分页的工程化改造

文章目录 前言一、复现深分页问题1.1 准备测试表1.2 准备测试数据1.3 先看普通分页查询1.4 用 EXPLAIN 看一下执行计划1.5 LIMIT 1000000, 20 到底慢在哪里?1.6 为什么 MySQL 不能直接跳到第 100 万条? 二、四种常见解决方案2.1 方案一:主键游…...

将OpenClaw智能体工作流对接至Taotoken以获取更丰富的模型选择

将OpenClaw智能体工作流对接至Taotoken以获取更丰富的模型选择 1. 场景需求与方案概述 在构建基于OpenClaw的自动化工作流时,开发者常面临模型选择单一的问题。当工作流的不同环节需要调用具备不同特长的模型时,传统方案往往需要为每个环节单独配置API密…...

别再用错约束了!Scipy中trust-constr和SLSQP两种有约束优化算法保姆级对比与选择指南

别再用错约束了!Scipy中trust-constr和SLSQP两种有约束优化算法保姆级对比与选择指南 在工程优化问题中,约束条件的处理往往比目标函数本身更让人头疼。Scipy作为Python生态中最常用的科学计算库,提供了两种主流的有约束优化算法:…...

从SiLU到LeakyReLU:手把手教你改造YOLOv5模型,让它能在KV260上跑起来

从SiLU到LeakyReLU:KV260边缘设备部署YOLOv5的深度改造指南 在边缘计算设备上部署深度学习模型时,硬件兼容性往往是开发者面临的首要挑战。KV260作为一款强大的边缘计算平台,结合Vitis AI工具链,为计算机视觉应用提供了高效的推理…...

蓝桥杯单片机省赛国赛避坑指南:STC15F2K60S2板子上的那些‘暗雷’与实战解法

蓝桥杯单片机竞赛高阶实战:STC15F2K60S2核心问题深度拆解 在蓝桥杯单片机设计与开发竞赛中,STC15F2K60S2开发板作为官方指定平台,其独特的硬件架构和资源限制常常成为参赛选手的"隐形绊脚石"。本文将从工程实践角度,剖析…...

ICode竞赛Python4级通关秘籍:用列表索引和循环搞定那些‘会飞的小人’

ICode竞赛Python4级通关秘籍:用列表索引和循环搞定那些‘会飞的小人’ 想象一下,你站在一个神秘的编程迷宫里,面前站着十几个"会飞的小人"(Flyer)。他们有的需要前进1步,有的需要转圈跳舞&#x…...

为 Ubuntu 上的 Claude Code 编程助手配置 Taotoken 作为后端

为 Ubuntu 上的 Claude Code 编程助手配置 Taotoken 作为后端 1. 准备工作 在开始配置之前,请确保已在 Taotoken 控制台创建有效的 API Key,并记录下模型广场中目标模型的完整 ID。Ubuntu 系统需要已安装 Claude Code 的 CLI 或桌面端应用,…...

基于LangChain的AI代理系统:自动化软件开发生命周期实践

1. 项目概述:一个能自主完成软件开发生命周期的AI代理系统如果你和我一样,每天都要在GitHub上处理大量的Issue和Pull Request,那你肯定也幻想过:要是能有个不知疲倦的助手,能自动分析需求、写代码、提PR,甚…...

掌握MECE原则:结构化思维的核心工具与实战应用

1. 项目概述与核心价值最近在GitHub上看到一个挺有意思的项目,叫bigboskuai-prog/mece-skill。光看这个名字,可能有点摸不着头脑,但如果你在项目管理、数据分析、产品设计或者咨询行业待过,对“MECE”这个词应该不会陌生。MECE&am…...

别再画‘麻子脸’散点图了!用Matplotlib的gaussian_kde搞定海量数据可视化(附完整代码)

告别数据点重叠:用Matplotlib打造专业级密度散点图 当你的数据集膨胀到数万甚至百万级别时,传统散点图就会变成一场视觉灾难——密密麻麻的"麻子脸"不仅掩盖了数据分布特征,还可能误导分析结论。上周我处理一组50万行的电商用户行为…...

别再只会用drop_duplicates了!Pandas duplicated()函数这5个高级用法,让你数据处理效率翻倍

解锁Pandas duplicated()函数的5个高阶技巧:让重复数据处理更高效 在数据分析的日常工作中,重复数据就像隐藏在角落里的"数据幽灵",不仅会扭曲统计结果,还会影响机器学习模型的训练效果。大多数数据分析师对drop_duplic…...

C# 13拦截器实战指南:如何在金融级交易服务中实现无侵入日志、熔断与权限校验(附IL织入对比基准)

更多请点击: https://intelliparadigm.com 第一章:C# 13拦截器在金融级交易服务中的定位与价值 C# 13 引入的拦截器(Interceptors)并非传统意义上的运行时 AOP 工具,而是一种编译期重写机制——它允许开发者在调用特定…...

【C++27 constexpr 极致优化权威指南】:20年编译器专家亲授7大突破性技巧,绕过ISO WG21未公开限制

更多请点击: https://intelliparadigm.com 第一章:C27 constexpr 函数极致优化的底层范式跃迁 C27 将 constexpr 的语义边界彻底重构——它不再仅是编译期求值的“标记”,而成为统一编译期与运行期执行模型的**元执行契约(Meta-E…...

Java虚拟线程与Project Loom深度绑定指南:从编译期协程支持到JFR事件追踪(JDK21 GA后唯一权威路径)

更多请点击: https://intelliparadigm.com 第一章:Java虚拟线程与Project Loom的演进本质 Java 虚拟线程(Virtual Threads)是 Project Loom 的核心成果,标志着 JVM 并发模型从“操作系统线程绑定”向“轻量级协作调度…...

Java服务网格配置性能断崖式下跌?用Arthas+Prometheus定位ConfigMap热更新延迟的11ms真相

更多请点击: https://intelliparadigm.com 第一章:Java服务网格配置 在现代云原生架构中,Java应用接入服务网格(Service Mesh)需兼顾兼容性、可观测性与流量控制能力。Istio 是最广泛采用的控制平面,而 Ja…...

如何高效实现抖音内容批量下载:技术架构与实践指南

如何高效实现抖音内容批量下载:技术架构与实践指南 【免费下载链接】douyin-downloader A practical Douyin downloader for both single-item and profile batch downloads, with progress display, retries, SQLite deduplication, and browser fallback support.…...

零刻EQ12 N100小主机变身家庭网络中枢:保姆级ESXi 8.0U2 + iKuai + OpenWrt + 黑群晖7.2全栈部署避坑指南

零刻EQ12 N100家庭网络中枢全栈部署实战指南 在智能家居和远程办公日益普及的今天,一个稳定高效的家庭网络中枢已成为现代家庭的刚需。零刻EQ12 N100凭借其紧凑的机身、双2.5G网口和出色的能耗比,成为搭建All In One家庭服务器的理想选择。不同于简单的分…...

【仅限头部SaaS厂商内部流出】PHP 8.9 JIT火焰图调优手册:定位热点函数、规避Tracing失效、绕过x86_64指令对齐坑

更多请点击: https://intelliparadigm.com 第一章:PHP 8.9 JIT 编译器生产级调优教程 PHP 8.9(预发布版)对内置的 Zend JIT 编译器进行了关键性增强,包括函数内联策略优化、寄存器分配器重写及内存屏障指令插入支持&a…...

Godot-MCP终极指南:用AI对话开发游戏的5个惊人技巧

Godot-MCP终极指南:用AI对话开发游戏的5个惊人技巧 【免费下载链接】Godot-MCP An MCP for Godot that lets you create and edit games in the Godot game engine with tools like Claude 项目地址: https://gitcode.com/gh_mirrors/god/Godot-MCP Godot-MC…...

【.NET 9低代码配置终极指南】:20年微软生态专家亲授,3大核心配置模式+5个避坑红线

更多请点击: https://intelliparadigm.com 第一章:.NET 9低代码配置的演进逻辑与本质认知 .NET 9 将低代码能力深度融入平台原生配置体系,其演进并非简单封装可视化拖拽,而是以“声明即契约、配置即契约实现”为内核,…...

C# 13模块化开发稀缺资源包:12个生产环境验证的顶级语句模块模板(含CI/CD集成配置与SonarQube规则集)

更多请点击: https://intelliparadigm.com 第一章:C# 13模块化开发核心范式演进 C# 13 引入了原生模块(module)声明语法与细粒度程序集可见性控制,标志着 .NET 平台正式迈入显式模块化时代。不同于传统 AssemblyInfo…...

Hypergrep:现代代码搜索工具的设计原理与工程实践

1. 项目概述:一个为现代开发者打造的极速代码搜索工具如果你和我一样,每天有超过一半的时间是在代码仓库里“寻宝”——寻找某个函数定义、追踪某个变量的所有引用、或者在一堆日志文件中定位特定的错误信息——那么你一定对grep这个老牌工具又爱又恨。爱…...

Windows系统优化终极指南:5分钟掌握WinUtil高效管理技巧

Windows系统优化终极指南:5分钟掌握WinUtil高效管理技巧 【免费下载链接】winutil Chris Titus Techs Windows Utility - Install Programs, Tweaks, Fixes, and Updates 项目地址: https://gitcode.com/GitHub_Trending/wi/winutil 你是否厌倦了Windows系统…...

终极指南:如何使用Harepacker复活版轻松编辑MapleStory游戏资源

终极指南:如何使用Harepacker复活版轻松编辑MapleStory游戏资源 【免费下载链接】Harepacker-resurrected All in one .wz file/map editor for MapleStory game files 项目地址: https://gitcode.com/gh_mirrors/ha/Harepacker-resurrected 你是否曾经想过自…...

2025届学术党必备的六大降重复率方案横评

Ai论文网站排名(开题报告、文献综述、降aigc率、降重综合对比) TOP1. 千笔AI TOP2. aipasspaper TOP3. 清北论文 TOP4. 豆包 TOP5. kimi TOP6. deepseek 当下,在学术写作跟内容创作里头,把文本的AI生成痕迹给降低&#xff0…...

告别背包焦虑!TQVaultAE:泰坦之旅玩家的终极装备管理解决方案

告别背包焦虑!TQVaultAE:泰坦之旅玩家的终极装备管理解决方案 【免费下载链接】TQVaultAE Extra bank space for Titan Quest Anniversary Edition 项目地址: https://gitcode.com/gh_mirrors/tq/TQVaultAE 还在为《泰坦之旅》中的背包空间不足而…...

21st.dev:社区驱动的React组件注册中心,基于shadcn/ui与Tailwind CSS

1. 项目概述:21st.dev,一个面向未来的React组件社区如果你和我一样,每天都在和React、Tailwind CSS打交道,那你肯定也经历过这样的时刻:为了一个漂亮的按钮、一个顺滑的弹窗,或者一个复杂的表单组件&#x…...

从Open3D到CloudCompare:手把手教你用两种工具搞定点云距离分析(附代码对比)

从Open3D到CloudCompare:点云距离分析的跨平台实战指南 在三维数据处理领域,点云距离分析是检测物体形变、评估重建精度、进行质量控制的基石操作。当开发者需要在Python生态的Open3D与专业桌面软件CloudCompare之间切换时,往往面临工具链割裂…...

基于MCP协议实现AI助手与Intervals任务管理的无缝集成

1. 项目概述:当你的AI助手能直接管理你的任务系统如果你和我一样,日常开发工作流里离不开Intervals这样的任务管理工具,同时又重度依赖Claude、Cursor这类AI编程助手,那你肯定也幻想过:要是能让AI直接帮我查任务、更新…...

深入理解Mybatis

什么是Mybatis? MyBatis呢,是Java领域中的一款持久化框架,它的主要功能是,让我们能够轻松地在Java对象和数据库之间建立联系。通过这种联系,开发者可以很方便地存储、检索和操作数据。MyBatis与其他ORM框架相比,有一些独有的特点。 首先,MyBatis强调对SQL的可控…...