互联网Java工程师面试题·Elasticsearch 篇·第二弹

12、详细描述一下 Elasticsearch 索引文档的过程。

协调节点默认使用文档 ID 参与计算(也支持通过 routing ),以便为路由提供合适的分片。
shard = hash(document_id) % (num_of_primary_shards)
1 、当分片所在的节点接收到来自协调节点的请求后,会将请求写入到 Memory Buffer,然后定时(默认是每隔 1 秒)写入到 Filesystem Cache ,这个从 Momery Buffer 到 Filesystem Cache 的过程就叫做 refresh
2 、当然在某些情况下,存在 Momery Buffer Filesystem Cache 的数据可能会丢失,ES 是通过 translog 的机制来保证数据的可靠性的。其实现机制是接收到请求后,同时也会写入到 translog 中,当 Filesystem cache 中的数据写入到磁盘中时,才会清除掉,这个过程叫做 flush
3 、在 flush 过程中,内存中的缓冲将被清除,内容被写入一个新段,段的 fsync将创建一个新的提交点,并将内容刷新到磁盘,旧的 translog 将被删除并开始一个新的 translog
4 flush 触发的时机是定时触发(默认 30 分钟)或者 translog 变得太大(默认为 512M )时;

补充:关于 Lucene Segement
1 Lucene 索引是由多个段组成,段本身是一个功能齐全的倒排索引。
2 、段是不可变的,允许 Lucene 将新的文档增量地添加到索引中,而不用从头重建索引。
3 、对于每一个搜索请求而言,索引中的所有段都会被搜索,并且每个段会消耗CPU 的时钟周、文件句柄和内存。这意味着段的数量越多,搜索性能会越低。
4 、为了解决 这个 问题 , Elasticsearch 会合并小段到一个较大的段,提交新的合并段到磁盘,并删除那些旧的小段。

13、详细描述一下 Elasticsearch 更新和删除文档的过程。

1 、删除和更新也都是写操作,但是 Elasticsearch 中的文档是不可变的,因此不能被删除或者改动以展示其变更;
2 、磁盘上的每个段都有一个相应的 .del 文件。当删除请求发送后,文档并没有真的被删除,而是在.del 文件中被标记为删除。该文档依然能匹配查询,但是会在结果中被过滤掉。当段合并时,在.del 文件中被标记为删除的文档将不会被写入新段。
3 、在新的文档被创建时, Elasticsearch 会为该文档指定一个版本号,当执行更新时,旧版本的文档在.del 文件中被标记为删除,新版本的文档被索引到一个新段。旧版本的文档依然能匹配查询,但是会在结果中被过滤掉。

14、详细描述一下 Elasticsearch 搜索的过程。

1 、搜索被执行成一个两阶段过程,我们称之为 Query Then Fetch
2 、在初始查询阶段时,查询会广播到索引中每一个分片拷贝(主分片或者副本分片)。 每个分片在本地执行搜索并构建一个匹配文档的大小为 from + size 的优先队列。
PS :在搜索的时候是会查询 Filesystem Cache 的,但是有部分数据还在 Memory Buffer,所以搜索是近实时的。
3 、每个分片返回各自优先队列中 所有文档的 ID 和排序值 给协调节点,它合并这些值到自己的优先队列中来产生一个全局排序后的结果列表。
4 、接下来就是 取回阶段,协调节点辨别出哪些文档需要被取回并向相关的分片提交多个 GET 请求。每个分片加载并 丰富 文档,如果有需要的话,接着返回文档给协调节点。一旦所有的文档都被取回了,协调节点返回结果给客户端。
5 、补充: Query Then Fetch 的搜索类型在文档相关性打分的时候参考的是本分片的数据,这样在文档数量较少的时候可能不够准确,DFS Query Then Fetch 增加了一个预查询的处理,询问 Term Document frequency ,这个评分更准确,但是性能会变差。*


15、在 Elasticsearch 中,是怎么根据一个词找到对应的倒排索引的?

SEE
Lucene学习总结之三:Lucene的索引文件格式(1) - 刘超觉先 - 博客园 (cnblogs.com)
Lucene学习总结之三:Lucene的索引文件格式(2) - 刘超觉先 - 博客园 (cnblogs.com)

16Elasticsearch 在部署时,对 Linux 的设置有哪些优化方法?

1 64 GB 内存的机器是非常理想的, 但是 32 GB 16 GB 机器也是很常见的。少于 8 GB 会适得其反。
2 、如果你要在更快的 CPUs 和更多的核心之间选择,选择更多的核心更好。多个内核提供的额外并发远胜过稍微快一点点的时钟频率。
3 、如果你负担得起 SSD ,它将远远超出任何旋转介质。 基于 SSD 的节点,查询和索引性能都有提升。如果你负担得起,SSD 是一个好的选择。
4 、即使数据中心们近在咫尺,也要避免集群跨越多个数据中心。绝对要避免集群跨越大的地理距离。
5 、请确保运行你应用程序的 JVM 和服务器的 JVM 是完全一样的。 在Elasticsearch 的几个地方,使用 Java 的本地序列化。
6 、通过设置 gateway.recover_after_nodes gateway.expected_nodes 、 gateway.recover_after_time 可以在集群重启的时候避免过多的分片交换,这可能会让数据恢复从数个小时缩短为几秒钟。
7 Elasticsearch 默认被配置为使用单播发现,以防止节点无意中加入集群。只有在同一台机器上运行的节点才会自动组成集群。最好使用单播代替组播。
8 、不要随意修改垃圾回收器( CMS )和各个线程池的大小。
9 、把你的内存的(少于)一半给 Lucene (但不要超过 32 GB !),通过ES_HEAP_SIZE 环境变量设置。
10 、内存交换到磁盘对服务器性能来说是致命的。如果内存交换到磁盘上,一个100 微秒的操作可能变成 10 毫秒。 再想想那么多 10 微秒的操作时延累加起来。 不难看出 swapping 对于性能是多么可怕。
11 Lucene 使用了大量 的文件。同时, Elasticsearch 在节点和 HTTP 客户端之间进行通信也使用了大量的套接字。 所有这一切都需要足够的文件描述符。你应该增加你的文件描述符,设置一个很大的值,如 64,000
补充:索引阶段性能提升方法
1 、使用批量请求并调整其大小:每次批量数据 5–15 MB 大是个不错的起始点。
2 、存储:使用 SSD
3 、段和合并: Elasticsearch 默认值是 20 MB/s ,对机械磁盘应该是个不错的设置。如果你用的是 SSD ,可以考虑提高到 100–200 MB/s 。如果你在做批量导入,完全不在意搜索,你可以彻底关掉合并限流。另外还可以增加 index.translog.flush_threshold_size 设置,从默认的 512 MB 到更大一些的值,比如 1 GB,这可以在一次清空触发的时候在事务日志里积累出更大的段。
4 、如果你的搜索结果不需要近实时的准确度,考虑把每个索引的
index.refresh_interval 改到 30s
5 、如果你在做大批量导入,考虑通过设置 index.number_of_replicas: 0 关闭副本。

17、对于 GC 方面,在使用 Elasticsearch 时要注意什么?

1 SEE https://elasticsearch.cn/article/32
2 、倒排词典的索引需要常驻内存,无法 GC ,需要监控 data node segment memory 增长趋势。
3 、各类缓存, field cache, filter cache, indexing cache, bulk queue 等等,要设置合理的大小,并且要应该根据最坏的情况来看 heap 是否够用,也就是各类缓存全部占满的时候,还有 heap 空间可以分配给其他任务吗?避免采用 clear cache等“ 自欺欺人 的方式来释放内存。
4 、避免返回大量结果集的搜索与聚合。确实需要大量拉取数据的场景,可以采用scan & scroll api 来实现。
5 cluster stats 驻留内存并无法水平扩展,超大规模集群可以考虑分拆成多个集群通过 tribe node 连接。
6 、想知道 heap 够不够,必须结合实际应用场景,并对集群的 heap 使用情况做
持续的监控。

18、Elasticsearch 对于大数据量(上亿量级)的聚合如何实现?

        Elasticsearch 提供的首个近似聚合是 cardinality 度量。它提供一个字段的基数,即该字段的 distinct 或者 unique 值的数目。它是基于 HLL 算法的。 HLL 会先对我们的输入作哈希运算,然后根据哈希运算的结果中的 bits 做概率估算从而得到基数。其特点是:可配置的精度,用来控制内存的使用(更精确 = 更多内存);小的数据集精度是非常高的;我们可以通过配置参数,来设置去重需要的固定内存使用量。无论数千还是数十亿的唯一值,内存使用量只与你配置的精确度相关

19、在并发情况下,Elasticsearch 如果保证读写一致?

1 、可以通过版本号使用乐观并发控制,以确保新版本不会被旧版本覆盖,由应用层来处理具体的冲突;
2 、另外对于写操作,一致性级别支持 quorum/one/all ,默认为 quorum ,即只有当大多数分片可用时才允许写操作。但即使大多数可用,也可能存在因为网络等原因导致写入副本失败,这样该副本被认为故障,分片将会在一个不同的节点上重建。
3 、对于读操作,可以设置 replication sync( 默认 ) ,这使得操作在主分片和副本分片都完成后才会返回;如果设置 replication async 时,也可以通过设置搜索请求参数_preference primary 来查询主分片,确保文档是最新版本。

20、如何监控 Elasticsearch 集群状态?

        Marvel 让你可以很简单的通过 Kibana 监控 Elasticsearch 。你可以实时查看你的集群健康状态和性能,也可以分析过去的集群、索引和节点指标。

21、介绍下你们电商搜索的整体技术架构。


22、介绍一下你们的个性化搜索方案?

SEE 基于 word2vec Elasticsearch 实现个性化搜索


23、是否了解字典树?

常用字典数据结构如下所示:

Trie 的核心思想是空间换时间,利用字符串的公共前缀来降低查询时间的开销以达到提高效率的目的。它有 3 个基本性质:
1 、根节点不包含字符,除根节点外每一个节点都只包含一个字符。
2 、从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串。
3 、每个节点的所有子节点包含的字符都不相同。

1 、可以看到, trie 树每一层的节点数是 26^i 级别的。所以为了节省空间,我们还可以用动态链表,或者用数组来模拟动态。而空间的花费,不会超过单词数× 单词长度。
2 、实现:对每个结点开一个字母集大小的数组,每个结点挂一个链表,使用左儿子右兄弟表示法记录这棵树;
3 、对于中文的字典树,每个节点的子节点用一个哈希表存储,这样就不用浪费太大的空间,而且查询速度上可以保留哈希的复杂度 O(1)

24、拼写纠错是如何实现的?

1 、拼写纠错是基于编辑距离来实现;编辑距离是一种标准的方法,它用来表示经过插入、删除和替换操作从一个字符串转换到另外一个字符串的最小操作步数;
2 、编辑距离的计算过程:比如要计算 batyu beauty 的编辑距离,先创建一个7×8 的表( batyu 长度为 5 coffee 长度为 6 ,各加 2 ),接着,在如下位置填入黑色数字。其他格的计算过程是取以下三个值的最小值:
如果最上方的字符等于最左方的字符,则为左上方的数字。否则为左上方的数字+1。(对于 3,3 来说为 0
左方数字 +1 (对于 3,3 格来说为 2
上方数字 +1 (对于 3,3 格来说为 2
最终取右下角的值即为编辑距离的值 3

对于拼写纠错,我们考虑构造一个度量空间( Metric Space ),该空间内任何关系满足以下三条基本条件:
d(x,y) = 0 -- 假如 x y 的距离为 0 ,则 x=y
d(x,y) = d(y,x) -- x y 的距离等同于 y x 的距离
d(x,y) + d(y,z) >= d(x,z) -- 三角不等式
1 、根据三角不等式,则满足与 query 距离在 n 范围内的另一个字符转 B ,其与 A 的距离最大为 d+n ,最小为 d-n
2 BK 树的构造就过程如下:每个节点有任意个子节点,每条边有个值表示编辑距离。所有子节点到父节点的边上标注 n 表示编辑距离恰好为 n 。比如,我们有棵树父节点是”book”和两个子节点 ”cake” ”books” ”book” ”books” 的边标号 1 ”book” ”cake” 的边上标号 4 。从字典里构造好树后,无论何 时你想插入新单词时,计算该单词与根节点的编辑距离,并且查找数值为 d(neweord, root)的边。递归得与各子节点进行比较,直到没有子节点,你就可 以创建新的子节点并将新单词保存在那。比如,插入”boo” 到刚才上述例子的树中,我们先检查根节点,查找 d(“book”, “boo”) = 1 的边,然后检查标号为 1 的边的子节点,得到单词 ”books” 。我们再计算距离 d(“books”, “boo”)=2 ,则将新单词插在”books” 之后,边标号为 2
3 、查询相似词如下:计算单词与根节点的编辑距离 d ,然后递归查找每个子节点标号为 d-n d+n (包含)的边。假如被检查的节点与搜索单词的距离 d 小于 n ,则返回该节点并继续查询。比如输入 cape 且最大容忍距离为 1 ,则先计算和根的编辑距离 d(“book”, “cape”)=4 ,然后接着找和根节点之间编辑距离为 3 到5 的,这个就找到了 cake 这个节点,计算 d(“cake”, “cape”)=1 ,满足条件所以返回 cake ,然后再找和 cake 节点编辑距离是 0 2 的,分别找到 cape 和cart 节点,这样就得到 cape 这个满足条件的结果。


要想了解更多:

千题千解·Java面试宝典_时光の尘的博客-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/149215.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Qt creator+cmake编译并安装

1、qt creator打开项目中的CMakeLists.txt 2、修改“构建设置“-“Cmake”-”Current Configuration“,其中,安装路径为CMAKE_INSTALL_PREFIX 3、修改“构建设置“-“构建的步骤”-”目标“,勾选"all"和"install" 4、构…

C语言qsort函数

排序qsort int int cmp(const void *a, const void *b) {return *(int *)a - *(int *)b;//先强转成int型,后解引用取值比较大小 }字符串数组 char a[] “hello world” //字符串数组,存放的是字符 int cmp(const void *a, const void *b) {return *(…

7.wifi开发【智能家居:终】,实践总结:智能开关,智能采集温湿,智能灯。项目运行步骤与运行细节,技术归纳与提炼,项目扩展

一。项目运行步骤与运行细节 1.项目运行步骤(一定有其他的运行方式,我这里只提供一种我现在使用的编译方式) (1)项目运行使用软件与技术: 1.Virtual linux 使用这个虚拟机进行程序的编译 2.Makefile与shl…

阿里云服务器镜像系统Anolis OS龙蜥详细介绍

阿里云服务器Anolis OS镜像系统由龙蜥OpenAnolis社区推出,Anolis OS是CentOS 8 100%兼容替代版本,Anolis OS是完全开源、中立、开放的Linux发行版,具备企业级的稳定性、高性能、安全性和可靠性。目前阿里云服务器ECS可选的Anolis OS镜像系统版…

【Java】猫和狗接口版本思路分析

目录 猫🐱和狗🐕(接口版本) 画图分析 案例代码 猫🐱和狗🐕(接口版本) 需求:对猫和狗进行训练,它们就可以跳高了,这里加入了跳高功能&#xff0…

Vue中实现自定义编辑邮件发送到指定邮箱(纯前端实现)

formspree里面注册账号 注册完成后进入后台新建项目并且新建表单 这一步完成之后你将得到一个地址 最后就是在项目中请求这个地址 关键代码如下: submitForm() {this.fullscreenLoading true;this.$axios({method: "post",url: "https://xxxxxxx…

MATLAB算法实战应用案例精讲-【优化算法】火烈鸟搜索优化算法(FSA)(附python代码实现)

前言 火烈鸟搜索算法(flamingo search algorithm,fsa)是一种模拟火烈鸟群体觅食行为的新型智能优化算法,可以用于路径规划领域。根据fsa的寻优过程可知,fsa存在以下不足:(1)初始化种群位置是随机的,不能保证种群质量;(2)在个体的迭代更新过程中缺少变异机制,导致种群多…

程序三高的方法

程序三高的方法 目录概述需求: 设计思路实现思路分析1.1)高并发 参考资料和推荐阅读 Survive by day and develop by night. talk for import biz , show your perfect code,full busy,skip hardness,make a better result,wait for change,c…

Git使用【中】

欢迎来到Cefler的博客😁 🕌博客主页:那个传说中的man的主页 🏠个人专栏:题目解析 🌎推荐文章:题目大解析3 目录 👉🏻分支管理分支概念git branch(查看/删除分…

华为云云耀云服务器L实例评测|基于canal缓存自动更新流程 SpringBoot项目应用案例和源码

前言 最近华为云云耀云服务器L实例上新,也搞了一台来玩,期间遇到各种问题,在解决问题的过程中学到不少和运维相关的知识。 在之前的博客中,介绍过canal的安装和配置,参考博客 拉取创建canal镜像配置相关参数 & …

UG\NX CAM二次开发 加工模块获取 UF _ask_application_module

文章作者:代工 来源网站:NX CAM二次开发专栏 简介: UG\NX CAM二次开发 加工模块获取 UF _ask_application_module 代码: void MyClass::do_it() { // TODO: add your code here // 获取NX当前所在的模块 int module_id = 0; // UF_ask_application_module(&…

JMeter性能测试

性能测试前言 老师开局一句话:性能测试和你会不会JMeter一点关系没有…… 作者坚持技多不压身的原则,还是多学一点JMeter吧,看老师到底要怎么讲下去,什么并发量、吞吐量啥的…… 性能测试的核心思想:在于创造大量并发去…

深度学习基础之参数量(3)

一般的CNN网络的参数量估计代码 class ResidualBlock(nn.Module):def __init__(self, in_planes, planes, norm_fngroup, stride1):super(ResidualBlock, self).__init__()print(in_planes, planes, norm_fn, stride)self.conv1 nn.Conv2d(in_planes, planes, kernel_size3, …

MySQL——使用mysqldump备份与恢复数据

目录 1.mysqldump简介 2.mysqldump备份数据 2.1 备份所有数据库 2.2 备份一个/多个数据库 2.3 备份指定库中的指定表 3.mysqldump恢复数据 3.1 恢复数据库 3.2 恢复数据表 1.mysqldump简介 mysqldump命令可以将数据库中指定或所有的库、表导出为SQL脚本。表的结构和表中…

互联网Java工程师面试题·Elasticsearch 篇·第一弹

目录 1、elasticsearch 了解多少,说说你们公司 es 的集群架构,索引数据大小,分片有多少,以及一些调优手段 。 1.1 设计阶段调优 1.2 写入调优 1.3 查询调优 1.4 其他调优 2、elasticsearch 的倒排索引是什么 3、elastic…

使用Pytorch从零实现Vision Transformer

在这篇文章中,我们将基于Pytorch框架从头实现Vision Transformer模型,并附录完整代码。 Vision Transformer(ViT)是一种基于Transformer架构的深度学习模型,用于处理计算机视觉任务。它将图像分割成小的图像块(patches),然后使用Transformer编码器来处理这些图像块。V…

【单片机】16-LCD1602和12864和LCD9648显示器

1.LCD显示器相关背景 1.LCD简介 (1)显示器,常见显示器:电视,电脑 (2)LCD(Liquid Crystal Display),液晶显示器,原理介绍 (3&#xff…

十天学完基础数据结构-第九天(堆(Heap))

堆的基本概念 堆是一种特殊的树形数据结构,通常用于实现优先级队列。堆具有以下两个主要特点: 父节点的值始终大于或等于其子节点的值(最大堆),或者父节点的值始终小于或等于其子节点的值(最小堆&#xff…

【2023年11月第四版教材】第18章《项目绩效域》(合集篇)

第18章《项目绩效域》(合集篇) 1 章节内容2 干系人绩效域2.1 绩效要点2.2 执行效果检查2.3 与其他绩效域的相互作用 3 团队绩效域3.1 绩效要点3.2 与其他绩效域的相互作用3.3 执行效果检查3.4 开发方法和生命周期绩效域 4 绩效要点4.1 与其他绩效域的相互…

2023/10/4 QT实现TCP服务器客户端搭建

服务器端&#xff1a; 头文件 #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTcpServer> #include <QTcpSocket> #include <QList> #include <QMessageBox> #include <QDebug>QT_BEGIN_NAMESPACE namespace Ui { cla…