检索技术核心 20 讲
陈东
前数禾科技 CTO,前奇虎 360 商业化资深总监
21492 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 29 讲
检索技术核心 20 讲
15
15
1.0x
00:00/00:00
登录|注册

测一测 | 高性能检索系统的实战知识,你掌握了多少?

附近兴趣相同的人排序方案
标签变化和位置变化的体现
实时性支持
解答主观题
巩固之前讲过的知识
一道主观题
20道单选题
高性能检索系统的设计思想
高级的检索知识
系统设计
解题思路
学习效果检验
测试题
经典解决方案
进阶实战篇
高性能检索系统的实战知识

该思维导图由 AI 生成,仅供参考

你好,我是陈东。欢迎来到进阶实战篇的测试环节!
在进阶实战篇中,我们针对一些应用中的实际问题,学习了对应的经典解决方案。这其中涉及了很多高级的检索知识,以及一些高性能检索系统的设计思想。这些知识,无论是对你现在的工作来说,还是对你之后自己设计系统、设计应用都会有非常大的帮助。
那这些知识你都掌握了多少呢?为了让你能检验自己的学习效果,同时也能巩固之前讲过的知识,我特别给你准备了一套测试题。和基础篇的测试一样,题目不多,依然是 20 道单选题,也同样建议你在 30 分钟内完成。
当然,我还为你准备了一道主观题。可以好好想想,利用我们进阶篇学到的知识怎么来解答,最后,希望你能把思考过程和最终答案都写在留言区,我们一起探讨。我会在下周三把解题思路放到评论区,一定要来看啊。
还等什么,点击下面的按钮开始测试吧!

主观题

假设有一个移动互联网应用,要实现找到附近具有相同兴趣的人功能。这里面的相同兴趣,指的是具有相同兴趣标签的人。如果一个人身上有多个标签,那只要有一个标签和其他人相同,就算有相同兴趣。
在这种情况下,我们需要支持以下功能:
列出附近兴趣相同的人,允许结果为空;
系统要具备实时性,如果有用户的标签发生变化或者位置发生变化,需要及时在系统中得到体现;
如果附近兴趣相同的人很多,那么需要将这些人进行排序,需要设计排序方案。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文是关于高性能检索系统的实战知识的测试环节。作者陈东在进阶实战篇中提到了一些应用中的实际问题,并学习了对应的经典解决方案。这些问题涉及了高级的检索知识和高性能检索系统的设计思想。作者特别为读者准备了一套测试题,包括20道单选题和一道主观题,以检验读者的学习效果。主观题涉及一个移动互联网应用,要实现找到附近具有相同兴趣的人功能,需要支持列出附近兴趣相同的人、实时性和排序功能。读者需要利用进阶实战篇学到的知识来设计和实现这个功能。整体来说,本文是一篇针对高性能检索系统实战知识的测试环节,旨在帮助读者巩固所学知识并应用于实际问题。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《检索技术核心 20 讲》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(5)

  • 最新
  • 精选
  • 陈东
    置顶
    这是一道开放的设计题,并没有标准答案,但是,我会给你一个参考的解答思路。你可以和你自己的方案进行对比,看看有哪些相同或者不同的地方,这些地方是否合理。下面是具体的解答思路。 对于第一个问题,其实是有着两个检索维度,一个维度是地理位置,另一个维度是兴趣标签。因此,我们可以将这两个维度进行解耦,分别建立两个索引。 对于基于地理位置,查询附近的人,我们可以使用区域编码,或者Geohash,将区域进行划分。由于允许检索结果为空,因此,我们可以根据应用的需求,选择合适的区域大小。然后对于所有的区域进行索引构建。我们可以使用跳表,也可以使用倒排索引。在构建好索引以后,针对要查询的区域,进行一次查询即可。如果希望更精准一些,那么可以查询周边的区域。这样,我们就可以得到“附近的人”的列表。 而对于基于兴趣标签,查找具有相同兴趣的人,我们可以通过以标签为Key,来构建倒排索引。这样,通过查询兴趣标签,我们就能找到“具有相同兴趣”的人的列表。如果一个人身上有多个兴趣标签,那么我们会查询倒排索引多次,得到每个标签对应的posting list,并将它们求并集即可。 那么,对于“附近的具有相同兴趣的人”,我们将这两个候选集求交集,就可以得到我们期望的结果。 如果不考虑该应用是否还有其他的和兴趣检索有关的需求,那么为了提高检索效率,我们其实还能将这两个维度的索引层次组合起来。我们可以根据“地理位置”将所有的人进行分片,对于同一个区域里的所有人,我们再根据兴趣标签来为每个区域的人建立倒排索引。这种组合索引结构,你会发现和层次聚类,或者倒排乘积量化的结构有点相似。它们都是通过将不同的索引进行层次组合,使得我们能快速减少减少空间。 那第二个问题,关于索引更新,在内存都可以加载的情况下,我们可以使用double buffer机制来实现。 当一个用户的位置发生变化时,如果他的位置区域没变,那么基于地理位置的索引就不用改变;而如果所属区域变化了,那么我们就将这个用户从原有区域列表中删除,然后加入到新的区域列表中。 而当一个用户的兴趣发生变化时,我们也用同样的操作,去修改兴趣标签的倒排索引。 第三个问题,要对所有符合条件的人进行打分排序,我们可以考虑一下有哪些重要的因子。在这个应用中,兴趣相似度和距离关系是最重要的因子。 关于计算两个人的兴趣相似度,其实这个和计算两个文档的相似度非常像。我们可以将每个人看作是一个文档,将每个兴趣标签看作是一个关键词。因此,我们可以使用TF-IDF的思想,或者BM25算法来进行打分。 而地理位置的距离关系,其实也是很重要的一个指标,我们可以把它当作一个独立的因子,赋予你认为合适的权重,和相关性打分进行累加即可。 当然,你也可以使用机器学习模型,将所有的因子都考虑进去,用机器学习来学习权重和进行打分。 好了,这就是全部的解题思路啦。快把你想到的答案放到留言区吧!期待与你的交流!
    2020-05-13
    2
    4
  • 那时刻
    谈谈我的想法,采用两种数据结构保存数据: 1. 按照用户地理位置geoHash,建立倒排索引,posting list为用户ID。 [geoHash | userId] 2. 以用户标签建立倒排索引,posting list为用户ID。[tag | userId] 查找用户A 附近相同标签用户的时候,首先按照A的地理位置,在地理位置索引里找到附近的用户列表B,B = [b1, b2, b3...]. 其次,再按照用户A的标签,假设有两种标签[t1, t2, t3],在标签索引找到相同标签的用户列表集合C,C = [c1, c2, c3...] 最后,取 B和C的交集,即是相同标签的用户。这个过程中可以采用优化算法,比如跳表,位图,加快交集的计算。 如果匹配到的用户过多的话,可以按照匹配标签的数目来对用户排序,也就是用户之前相同标签的数量。 例如,按照标签t1,匹配到用户列表C1 = [c1, c2, c3]. 按照标签t2,匹配到用户列表C2 = [c2, c3, c4]. 按照标签t3,匹配到用户列表C3 = [c3, c4, c6]. (前面提到的C是C1 C2 C3的并集) 那么对于用户出现次数排序为 CC = [c3, c2, c4...]。对于标签数量一样的用户,可以增加标签权重的因子。

    作者回复: 你写得很清晰。这的确是可行的方法。至于排序的问题,我们有没有优化的空间呢?比如说将用户看作是一个文档,身上的标签看作是文档中的关键词,那么使用第11讲的内容能否优化?

    2020-05-06
    2
    4
  • Eascholas
    “关于计算两个人的兴趣相似度,其实这个和计算两个文档的相似度非常像。我们可以将每个人看作是一个文档,将每个兴趣标签看作是一个关键词。因此,我们可以使用TF-IDF的思想,或者BM25算法来进行打分。” 陈老师,这里用相似度来打分,比如A用户的标签是“a,b”,B用户的标签是“a,b,c,d,e,f,g,h”,这样的话我理解他们俩的相似度打分应该不高。 对于有相同兴趣标签的用户,如果按照“相同兴趣标签个数越多,排序越靠前”,这样是否更好呢?标签是个大类,总量不会很大,使用位图来改造posting list,这样就判断两个用户的位图与后,bit为1的个数,越多打分越高;或者直接使用数组来查找。这个思路可行吗?

    作者回复: 你的想法很好。“相同标签越多,相似度越高”,这个思路是可行的。其实这就是求集合相似度的Jaccard距离,它的计算公式是“集合交集元素个数”除以“集合并集个数”。包括你用位图来实现,的确是一种高性能的实现。 当然,对于“a,b”和“a,b,c,d,e,f,g,h”求相似度,用我文中说的bm25算法也是可行的。因为bm25算法会考虑到文章的长度问题。

    2020-07-01
  • 进阶实战篇到了后面,我一直有种每篇文章我知道讲什么,但没有一条主线能把它们串起来,最关键的是冥冥之中我感觉它们是有联系的┭┮﹏┭┮。花了一上午重温,得出结论: 倒排索引更泛化得讲,是一个一个的索引值key 到 完整数据集合的子集set的一个映射关系。而本专栏的8-16章就可以理解为从这个映射的各个方面进行的阐述,来,强制解释一波: 8,9,10 很明显讲的是映射关系的构建,维护,分片。 11,12 讲的是用户输入key的一个组合,返回最匹配的前k个数据,这说明映射的集合set与它对应的key之间是有匹配度的,而且set是可以按这个匹配度进行组织的。(这里有点牵强,毕竟核心思想还在于如何通过线下打分,在线上操作的时候就排除一大批数据,使得线上查询需要精确打分的很少) 13,14,在我看来讲的是映射关系中key怎么进行编码,以及当key不在是单维度信息下,怎么用前缀树,kd-tree这样的结构维护key之间的关系,使得从一个key能够找到其他相似key. 15,16 就是对key编码的升级版,通过simhash,聚类把key的空间减小,同时保留key之间的相似性。 最大感受: 虽然只是key-> set的映射,但怎么根据查询种类去设计key,以及采用什么样的数据结构组织key,set存储结构附加信息,整个映射的构建,更新,分片都是值得深思的问题。

    作者回复: 其实总结得蛮好的,这样的总结,也说明了你有自己的思考和理解。尤其是最后,你说了该怎么去设计key,以及怎么进行分片,这些都是值得深思的问题,这一点我很赞同。而且从这个点再往下挖,就会回到我们在专栏开始不久时,提到的如何用深度学习来构建索引的问题。相信你现在再去想这个问题,就会有不一样的视角了。 还有,进阶篇的这一系列内容,的确还有一条暗线在串联着,我在结束语时会揭晓。

    2020-05-16
  • ifelse
    65分
    2023-04-18归属地:浙江
收起评论
显示
设置
留言
5
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部