Java ES-ElasticSearch面试题

  • 前言
  • 1、ElasticSearch是什么?
  • 2. 说说你们公司ES的集群架构,索引数据大小,分片有多少 ?
  • 3. ES的倒排索引是什么?
  • 4. ES是如何实现 master 选举的?
  • 5. 描述一下 ES索引文档的过程:
  • 6、文档从接收到写入磁盘过程:
  • 7、ES在部署时,有哪些优化方法?
  • 8、ES中的节点(比如共 20 个),其中的 10 个选了一个 master,另外 10 个选了另一个 master,怎么办?
  • 9、详细描述一下 ES更新和删除文档的过程:
  • 10、在并发情况下,ES如果保证读写一致?
  • 11、如何避免订单重复提交?
  • 12、说一下HTTP和HTTPS的区别?
  • 13、什么是数字证书?
  • 14、说说TCP与UDP的区别,以及各自的优缺点
  • 15、你设计库表时会考虑哪些问题?
  • 16、说一下你对设计模式的理解?
  • 17、cpu高或者内存高,是怎去排查的问题?
  • 18、你们JVM启动参数怎么设置的,大小怎么配置?
  • 19、CMS简介?
  • 20、SPI 机制了解吗?
  • 总结


1、ElasticSearch是什么?

  • Elasticsearch是一个开源的分布式全文搜索引擎,它可以近乎实时的存储、检索数据。

2. 说说你们公司ES的集群架构,索引数据大小,分片有多少 ?

提供一组真实生产环境数据供参考:
379万数据;每条数据字符数大概是400个英文字母;1个副本、5个分片;占用空间1.53G(也就是es-head看到的索引大小);每个节点的esdata目录大小:2.1G;

3. ES的倒排索引是什么?

传统的我们的检索是通过文章,逐个遍历找到对应关键词的位置。
倒排索引,是通过分词策略,形成了词和文章的映射关系表,这种词典+映射表即为倒排索引。有了倒排索引,检索文章的时间复杂度是 o(1),极大的提高了检索效率。

4. ES是如何实现 master 选举的?

ES的选主是ZenDiscovery模块负责,对所有可以成为Master的节点(node.master: true)根据 nodeId 排序,每次选举每个节点都把自己所知道节点排一次序,然后选出第一个(第0位)节点,暂且认为它是 Master 节点。
如果对某个节点的投票数超过一半,并且该节点自己也选举自己,那这个节点就是master,否则重新选举。

5. 描述一下 ES索引文档的过程:

  • 1、客户端向 Node 1 发送新建、索引或者删除请求;
  • 2、节点使用文档id 确定文档属于分片 0 ,请求会被转发到 Node 3,因为分片 0 的主分片目前被分配在 Node 3 上;
  • 3、Node 3 在主分片上面执行请求,如果成功了,它将请求并行转发到 Node 1 和 Node 2 的副本分片上;
  • 4、一旦所有的副本分片都报告成功, Node 3 就向协调节点报告成功,协调节点向客户端报告成功。

6、文档从接收到写入磁盘过程:

  • 1、当分片所在的节点接收到来自协调节点的请求后,会将请求写入到 MemoryBuffer,然后定时(默认是每隔 1 秒)写入到 Filesystem Cache,这个从 MomeryBuffer 到 Filesystem Cache 的过程就叫做 refresh;
  • 2、在某些情况下,存在 Momery Buffer 和 Filesystem Cache 的数据可能会丢失,ES 是通过 translog 的机制来保证数据的可靠性的。其实现机制是接收到请求后,同时也会写入到 translog 中,当 Filesystem cache 中的数据写入到磁盘中时,才会清除掉,这个过程叫做 flush;
  • 3、在flush过程中,内存中的缓冲将被清除,内容被写入一个新段,段的 fsync将创建一个新的提交点,并将内容刷新到磁盘,旧的translog将被删除并开始一个新的 translog;
  • 4、flush触发的时机是定时触发(默认30分钟)或者translog变得太大(默认为512M)时;
    (1. translog 可以理解为就是一个文件,一直追加;MemoryBuffer 应用缓存; Filesystem Cache系统缓冲区)

7、ES在部署时,有哪些优化方法?

  • 1、关闭缓存swap:
    原因:大多数操作系统会将内存使用到文件系统缓存,会将应用程序未用到的内存交换出去。会导致jvm的堆内存交换到磁盘上。交换会导致性能问题。会导致内存垃圾回收延长。会导致集群节点响应时间变慢,或者从集群中断开。
  • 2、堆内存设置为:Min(节点内存/2, 32GB);
  • 3、设置最大文件句柄数

8、ES中的节点(比如共 20 个),其中的 10 个选了一个 master,另外 10 个选了另一个 master,怎么办?

当集群maste候选数量不小于3个时,可以通过设置最少投票通过数量(discovery.zen.minimum_master_nodes)超过所有候选节点一半以上来解决脑裂问题;
当候选数量为两个时,只能修改为唯一的一个 master 候选,其他作为 data节点,避免脑裂问题。

9、详细描述一下 ES更新和删除文档的过程:

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

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

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

11、如何避免订单重复提交?

  • 1、前端做防重复提交,限制100ms只能请求一次;
  • 2、在提交订单页面之前,先去后端服务获取一个token令牌,后端服务可以令牌放在redis中,前端提交订单后,后端会先去redis查看令牌是否存,如果存在则创建订单成功,同时删除该令牌,如果不存在,就拒绝请求,返回提示信息。

12、说一下HTTP和HTTPS的区别?

  • 1、安全性:HTTP协议是明文传输数据的,因此不够安全,容易被黑客攻击拦截、篡改数据。而HTTPS通过SSL/TLS协议对数据进行加密传输,可以保证数据的安全性,防止数据被窃取和篡改;
  • 2、数据传输方式: HTTP使用的是明文传输,数据包裹在请求报文和响应报文中,传输过程中可能会被拦截和篡改,而HTTPS通过TLS协议对数据进行加密传输,因此需要额外的SSL/TLS协议进行加解密操作,会比HTTP多消耗一些系统资源;
  • 3、端口号:HTTP默认使用80端口进行通信,而HTTPS默认使用443端口进行通信;
  • 4、数字证书:在HTTPS通信中,服务端需要提供数字证书,证书中包含了公钥和域名等信息,客户端通过验证证书的有效性,可以确认自己连接的是正确的服务器。
    总的来说,HTTPS相比于HTTP具有更高的安全性,适合于需要保护用户隐私信息的场景。而HTTP则适用于一些不需要传输敏感数据的场景,例如一些公开的网站、博客等。

13、什么是数字证书?

  • 客户端向服务端发起身份验证请求的一种证书,数字证书在许多相互认证设计中起着非常重要的作用,为请求者的身份提供了强有力的保证。

14、说说TCP与UDP的区别,以及各自的优缺点

  • 1、连接性:TCP在通信之前必须要三次握手建立连接,而UDP是无连接的协议,通信双方不需要建立连接就可以进行数据传输;
  • 2、可靠性:TCP是一种可靠的协议,它可以保证数据的完整性和准确性,而UDP不能保证可靠性,数据可能会丢失;
  • 3、效率:由于TCP需要建立连接、进行错误检测等操作,所以效率较低,而UDP的效率较高,因为它不需要建立连接;
  • 4、传输方式:TCP是面向字节流的协议,数据在传输过程中会被分成小的数据包进行传输,而UDP是面向数据包的协议,每个数据包都是独立的,互不干扰;
    适用场景:由于TCP具有可靠性和连接性,适合用于传输要求可靠的数据,例如网页、电子邮件、文件传输等。而UDP适合用于传输实时性要求较高、数据量较小的数据,例如文本、音频等;

15、你设计库表时会考虑哪些问题?

字段的长度问题、创建的表的字段是否规范、风格是否和项目组统一、后续扩展问题、以及当前表的数据量级问题、后续的优化等。

16、说一下你对设计模式的理解?

设计模式是针对软件开发中经常遇到的一些设计问题,而总结出来的一套实用的解决方案或者设计思想,提高了代码的复用性和可扩展性。
设计模式的六大原则:

  • 1.开闭原则:有开有闭原则,对扩展开放,但是对修改关闭;
  • 2.里氏代换原则:子类可以扩展父类的功能,但不能改变原有父类的功能;
  • 3.依赖倒转原则:依赖依于接口或者抽象类而不赖于实现类;
  • 4.接口隔离原则:使用多个相互隔离的接口开发,比使用单个接口要好;
  • 5.迪米特法则:最少知道原则,尽量降低类与类之间的耦合;
  • 6.合成复用原则:通过将已有对象作为新对象的成员属性,新对象可以调用已有对象的功能,从而达到复用。

17、cpu高或者内存高,是怎去排查的问题?

原因:可能是业务代码死循环、GC频繁、线程阻塞等;

  • 1.执行top命令,查看CPU占用过高的进程(按M可以排序);
  • 2.根据pid找到对应cpu占用最多的Java线程:top -Hp 4861;
  • 3.将10进制线程id转换为16进制:
  • 4.通过jstack 命令找到对应问题现场堆栈信息:jstack 4851|grep 12fd -C 10
    查看线程运行状态和定位问题代码行数;如果有死锁会出现deadlock关键字;
    如果线程阻塞,会出现BLOCKED关键字;
  • 5.查看进程GC情况:jstat -GCutil <进程号> <统计间隔毫秒> <统计次数>
    查看某进程GC持续变化情况,如果发现返回中FGC很大且一直增大,就是FGC;
  • 6.出dump文件:jmap -dump:format=b,file=filename < PID >
    导出某进程下内存heap到文件中,通过jdk自带 visualvm 或者 mat 工具查看内存中程序实例个数。

18、你们JVM启动参数怎么设置的,大小怎么配置?

java -Xms2048m -Xmx2048m -Xmn700m -Xss512K 
-XX:MaxMetaspaceSize=200m -XX:MetaspaceSize=200m -XX:ParallelGCThreads=8
-XX:+PrintGCDetails -XX:+UseConcMarkSweepGC -XX:+
-XX:+HeapDumpOnOutOfMemoryError  -XX:HeapDumpPath=/usr/local/OutOfMemory.hprof
-jar lugu-portal-1.1.jar

可以看到堆内存为2G,新生代为700M,老年代为1348M,元数据区是200M;
UseParNewGC:新生代使用ParNew回收器,UseConcMarkSweepGC:老年代使用CMS算法;
线程栈为512k(默认1024k调小可以增加创建线程数,增加并发量);
同时打印 GC 详细信息和打印 GC 发生时间,当发生OOM时,Dump文件到指定路径。

19、CMS简介?

CMS是一款基于并发、使用标记清除算法的垃圾回收算法,只针对老年代进行垃圾回收,会尽可能让GC线程和用户线程并发执行,以达到降低STW时间的目的。
原理是通过可达性分析算法(GC Root对象)。

  • 能与CMS搭配使用的新生代垃圾收集器有Serial收集器和ParNew收集器。这2个收集器都采用标记复制算法,都会触发STW事件,停止所有的应用线程。不同之处在于,Serial是单线程执行,ParNew是多线程执行。
  • 缺点:容易产生内存碎片和浮动垃圾(在并发清除过程中,由于用户线程也在不断的运行,所以会产生一些垃圾对象),由于CMS支持与用户线程并行,所以会与用户线程进行CPU资源争夺。

20、SPI 机制了解吗?

spi全称为 (Service Provider Interface),是JDK内置的一种服务提供机制,用于提升接口的可扩展性,可以降低模块之间的解耦和相互依赖。
spi的工作原理:

  • 1.服务的提供方对调用方的接口提供了一种实现, 在jar包中resource的META-INF/services目录下创建一个接口的全限定名的文件,该文件的内容是是实现类的全限定名;
  • 2.在主程序中使用java.util包中的ServiceLoader加载该接口从而获取该实现类;
  • 3.实现类要带一个无参构造;