2024年Java最全API 分页探讨:offset 来分页真的有效率吗?(2),腾讯T3大牛亲自讲解

最后

看完美团、字节、腾讯这三家的面试问题,是不是感觉问的特别多,可能咱们又得开启面试造火箭、工作拧螺丝的模式去准备下一次的面试了。

开篇有提及我可是足足背下了1000道题目,多少还是有点用的呢,我看了下,上面这些问题大部分都能从我背的题里找到的,所以今天给大家分享一下互联网工程师必备的面试1000题

注意不论是我说的互联网面试1000题,还是后面提及的算法与数据结构、设计模式以及更多的Java学习笔记等,皆可分享给各位朋友

最新“美团+字节+腾讯”一二三面问题,挑战一下你能走到哪一面?

互联网工程师必备的面试1000题

而且从上面三家来看,算法与数据结构是必备不可少的呀,因此我建议大家可以去刷刷这本左程云大佬著作的《程序员代码面试指南 IT名企算法与数据结构题目最优解》,里面近200道真实出现过的经典代码面试题

最新“美团+字节+腾讯”一二三面问题,挑战一下你能走到哪一面?

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

GET /api/products

{“items”: […100 products],

“cursor”: “qWe”}

API 返回一个无业务意义的字符串(游标),你可以用它来检索下一个页面。

GET /api/products?cursor=qWe

{“items”: […100 products],

“cursor”: “qWr”}

实现游标有很多方法。一般来说,可以通过一些排序字段比如产品 id 来实现。在这种情况下,你可以用一些可逆算法对产品 id 进行编码。而在接收到一个带有游标的请求时,你会对它进行解码,并生成一个类似 WHERE id > :cursor LIMIT 100 的查询。

下面是一个小小的性能对比,先看看 offset 是如何工作:

=# explain analyze select id from product offset 10000 limit 100;

QUERY PLAN


Limit  (cost=1114.26…1125.40 rows=100 width=4) (actual time=39.431…39.561 rows=100 loops=1)

->  Seq Scan on product  (cost=0.00…1274406.22 rows=11437243 width=4) (actual time=0.015…39.123 rows=10100 loops=1)

Planning Time: 0.117 ms

Execution Time: 39.589 ms

再看看 where (cursor) 语句如何工作:

=# explain analyze select id from product where id > 10000 limit 100;

QUERY PLAN


Limit  (cost=0.00…11.40 rows=100 width=4) (actual time=0.016…0.067 rows=100 loops=1)

->  Seq Scan on product  (cost=0.00…1302999.32 rows=11429082 width=4) (actual time=0.015…0.052 rows=100 loops=1)

Filter: (id > 10000)

Planning Time: 0.164 ms

Execution Time: 0.094 ms

这是几个数量级的差异! 当然,实际的差异取决于表的大小以及过滤器和存储的实现。有一篇不错的文章 (1) 提供了更多的技术信息,里面有 ppt,性能比较见第 42 张幻灯片。

(1) https://use-the-index-luke.com/no-offset

当然,用户不会按 id 来检索商品,而是会按一些相关性来查询(然后按 id 作为关联字段)。在现实世界中,需要根据你的业务来决定该怎么做。订单可以按 id 排序(因为它是单调增加的)。购买清单可以按 wishlist 时间排序。在我们的案例中,产品来自 ElasticSearch,自然支持游标的特性。

我们可以看到的一个不足是,使用无状态的 API, 无法支持翻到“上一页”这样的功能。所以在面向用户界面中,如果有 prev/next 或者 “直接进入第10页” 这样的按钮,就没有办法绕过前面提到的 offset/limit 这种实现。但是在其他情况下,使用基于游标的分页可以极大地提高性能,特别是在真正的大表和真正的深度分页上。

英文原文:

https://solovyov.net/blog/2020/api-pagination-design/

HackerNews 评论:

https://news.ycombinator.com/item?id=25547716

HN网友 et1337:

使用游标的另一个原因是避免由于并发编辑而导致元素重复或跳过的问题,比如你使用 offset 正在第 10 页上,而有人在第 1 页上删除了一个项目,则整个列表会移动,你可能会意外跳过第 11 页上的一行数据。同样,如果有人在第 1 页上添加了一条记录而你正在第 10 页上,第 10 页中的一项也会重复显示在第 11 页上。

游标优雅地回避了这些问题。

HN 网友 chrismorgan:

有时候,你需要一个游标,这样你就可以从你刚才的地方继续前进,而不用担心新的记录进来扰乱你的分页。

有时你想要基于位置的查询,因为你明确地希望所有的东西都是位置的。

有时你想把这两种技术结合起来,例如,如果你跳到一个大的、不断变化的列表中间,然后想在刚才的位置之后检索下一批结果。

我喜欢 JMAP 最后的设计(https://tools.ietf.org/html/rfc8620#page-45):你可以指定一个位置整数,或者一个锚 ID 和可选的 anchorOffset 整数。锚是游标的一种实现,它使用结果集中一个实体 ID,而不是一个可以嵌入其他信息(比如 coroutine 地址)的不透明类型,,它有一个明显的优点,就是可以由客户端控制。

HN 网友 vincnetas

我认为作者在使用 OFFSET 时忽略了一些关键点。至少 postgres 文档对此有明确的的说法(https://www.postgresql.org/docs/13/queries-limit.html)

When using LIMIT, it is important to use an ORDER BY clause that constrains the result rows into a unique order. Otherwise you will get an unpredictable subset of the query’s rows. You might be asking for the tenth through twentieth rows, but tenth through twentieth in what ordering?

看起来作者提供的分页查询没有考虑到排序,这意味着第 100 页上的项目的 ID 大于 10000,但顺序未定义。

explain analyze select id from product where id > 10000 limit 100

HN 网友 boulos

鉴于对“游标”一词的重用感到困惑,我更喜欢 Google 为分页所使用的术语:页面令牌和页面大小,详细可以参阅:

https://google.aip.dev/158

图片

总结

阿里伤透我心,疯狂复习刷题,终于喜提offer 哈哈~好啦,不闲扯了

image

1、JAVA面试核心知识整理(PDF):包含JVMJAVA集合JAVA多线程并发,JAVA基础,Spring原理微服务,Netty与RPC,网络,日志,ZookeeperKafkaRabbitMQ,Hbase,MongoDB,Cassandra,设计模式负载均衡数据库一致性哈希JAVA算法数据结构,加密算法,分布式缓存,Hadoop,Spark,Storm,YARN,机器学习,云计算共30个章节。

image

2、Redis学习笔记及学习思维脑图

image

3、数据面试必备20题+数据库性能优化的21个最佳实践

image

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

题+数据库性能优化的21个最佳实践

[外链图片转存中…(img-ua62sTPT-1714849456094)]

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

  • 14
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值