java面试题收集(18)---ES查询出来的结果如何排序、Token介绍、DNS、CNAME、Socket

70 阅读19分钟

1、 ES查询出来的结果如何排序?

在排序的过程中,只能使用可排序的属性进行排序。 可以排序的属性:数字,日期。 ES查询的DSL语句中我们是用了HotScore来进行排序的,HotScore通过点击量来决定热度。 相关性排序、字段值排序、多级排序:第一排序是zcsj,第二排序是_score。

2、Token介绍

(1)Token可以解决哪些问题呢? 1)Token 完全由应用管理,所以它可以避开同源策略。

2)Token 可以避免 CSRF 攻击。

3)Token 可以是无状态的,可以在多个服务间共享。

Token 是在服务端产生的。如果前端使用用户名/密码向服务端请求认证,服务端认证成功,那么在服务端会返回 Token 给前端。前端可以在每次请求的时候带上 Token 证明自己的合法地位。如果这个 Token 在服务端持久化(比如存入数据库),那它就是一个永久的身份令牌。

(2)Token时长视具体情况而定,我们暂定7天

(3)同源策略

同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。 同源策略,它是由Netscape提出的一个著名的安全策略。 当一个浏览器的两个tab页中分别打开来 百度和谷歌的页面 当浏览器的百度tab页执行一个脚本的时候会检查这个脚本是属于哪个页面的, 即检查是否同源,只有和百度同源的脚本才会被执行。 如果非同源,那么在请求数据时,浏览器会在控制台中报一个异常,提示拒绝访问。 同源策略是浏览器的行为,是为了保护本地数据不被JavaScript代码获取回来的数据污染,因此拦截的是客户端发出的请求回来的数据接收,即请求发送了,服务器响应了,但是无法被浏览器接收。

3、DNS

域名系统(英文:Domain Name System,缩写:DNS)是Internet上解决网上机器命名的一种系统。它作为将域名和IP地址相互映射的一个分布式数据库,能够使人更方便地访问互联网,而不用去记住能够被机器直接读取的IP数串。域名系统使用TCP和UDP端口53,对于每一级域名长度的限制是63个字符,域名总长度则不能超过253个字符。

4、CNAME

CNAME指别名记录也被称为规范名字。这种记录允许您将多个名字映射到同一台计算机。通常用于同时提供WWW和MAIL服务的计算机。例如,有一台计算机名为“r0WSPFSx58.baihuikm.com”(A记录)。它同时提供WWW和MAIL服务,为了便于用户访问服务。可以为该计算机设置两个别名(CNAME):WWW和MAIL。这两个别名的全称就是“r0WSPFSx58.baihuikm.com”和“zz.baidu.com”。实际上他们都指“zz.baidu.com”。 CNAME记录就是把别名指向(映射到)主机名的过程。

5、域名解析

域名解析是把域名指向网站空间IP,让人们通过注册的域名可以方便地访问到网站的一种服务。IP地址是网络上标识站点的数字地址,为了方便记忆,采用域名来代替IP地址标识站点地址。域名解析就是域名到IP地址的转换过程。域名的解析工作由DNS服务器完成。 域名解析也叫域名指向、服务器设置、域名配置以及反向IP登记等等。说得简单点就是将好记的域名解析成IP,服务由DNS服务器完成,是把域名解析到一个IP地址,然后在此IP地址的主机上将一个子目录与域名绑定。

6、物理层

物理层(Physical Layer)是计算机网络OSI模型中最低的一层,位于OSI参考模型的最底层,它直接面向实际承担数据传输的物理媒体(即通信通道),物理层的传输单位为比特(bit),即一个二进制位(“0”或“1”)。实际的比特传输必须依赖于传输设备和物理媒体,但是,物理层不是指具体的物理设备,也不是指信号传输的物理媒体,而是指在物理媒体之上为上一层(数据链路层)提供一个传输原始比特流的物理连接。物理层规定:为传输数据所需要的物理链路创建、维持、拆除,而提供具有机械的,电子的,功能的和规范的特性。简单的说,物理层确保原始的数据可在各种物理媒体上传输。 协议:EIA/TIA RS-232、EIA/TIA RS-449、V.35、RJ-45等。

7、数据链路层

数据链路层的主要协议有: (1)Point-to-Point Protocal——PPP点到点。 (2)Ethernet——以太网。 (3)High-Level Data Link Control Protocal——高级zhi链路控制协议dao。 (4)Frame Relay——帧中继。 (5)Asynchronous Transfer Mode——异步传输模式。 常用的数据链路层: TCP/IP支持多种不同的数据链路层协议,这取决于网络使用的硬件,如以太网、令牌环、FDDI等局域网,串行线路、X.25、帧中继FR、ATM等广域网。 早期,由于各网络公司的竞争,局域网没有形成统一标准,为了将各种局域网融合,将链路层拆分成两层,逻辑链路层(LLC)和媒体接入控制(MAC)(802.3封装:SAP)。 90年代,以太网取得垄断地位,以太网成为局域网代名词。数据链路层仅需要MAC层,采用以太网帧格式(Ethernet V2封装:ARPA)。

8、Socket

在这里插入图片描述

9、Maven

Maven的概念: Maven 是一个项目构建,依赖管理和项目信息聚合的工具,提供了帮助管理 构建、文档、报告、依赖、发布、分发的方法。可以方便的编译代码、进行依赖管理、管理二进制库等等。Maven 作为 Apache的一个开源项目,旨在给项目管理提供更多的支持,它最早的意图只是为了给 apache 组织的几个项目提供统一的开发、测试、打包和部署,能让开发者在多个项目中方便的切换。而 Maven的好处在于可以将项目过程规范化、自动化、高效化以及强大的可扩展性,利用maven自身及其插件还可以获得代码检查报告、单元测试覆盖率、实现持续集成等等。

Maven的构建生命周期: Maven对构建(build)的过程进行了抽象和定义,这个过程被称为构建的生命周期(lifecycle)。 构建生命周期(lifecycle)由多个阶段(phase)组成,每个阶段(phase)会挂接一到多个goal,而goal是maven里定义任务的最小单元,相当于ant里的target。可以理解maven为一个插件的容器,每个插件绑定到某个goal执行。 例如,默认(default)的生命周期包括以下阶段:

(1)验证(validate) - 验证项目是否正确,所有必要的信息可用。

(2)编译(compile) - 编译项目的源代码。

(3)测试(test) - 使用合适的单元测试框架测试编译的源代码。这些测试不应该要求代码被打包或部署。

(4)打包(package) - 采用编译的代码,并以其可分配格式(如JAR)进行打包。

(5)验证(verify) - 对集成测试的结果执行任何检查,以确保满足质量标准。

(6)安装(install) - 将软件包安装到本地存储库中,用作本地其他项目的依赖项。

(7)部署(deploy) - 在构建环境中完成,将最终的包复制到远程存储库以与其他开发人员和项目共享。

三个仓库:

(1)Maven的本地仓库

Maven中的本地资源库存储的是所有项目的依赖关系,每新建一个Maven项目,所有相关的项目文件都会被存储在本地资源库中。Maven默认的本地资源库的位置是在一个.m2的文件夹中。

(2)Maven的中央存储库

新建一个Maven项目后,会产生一个pom.xml的配置文件,然后Maven检查你的pom.xml配置文件看看哪些依赖需要加载。首先是先从你的本地资源库里查找,若没有查找到对应的依赖,则转换到Maven的中央存储库进行查找。 Maven的中央存储库地址为:mvnrepository.com/

(3)远程仓库

在maven中,如果你所需要的依赖没在本地资源库中、也没在中央存储库中,那么maven将会报错。但是我们可以通过配置来加载远程存储库。具体的是在pom.xml配置文件中添加如下的代码: releases http://域名:端口/nexus/content/repositories/releases/

(4)查询顺序

    现在maven的查询顺序为:
    首先在本地资源库中查找依赖,若不存在,则进入下一步,否则,退出;
    然后在中央存储库中查找依赖,若不存在,则进入下一步,否则,退出;
    最后在远程仓库中查找依赖,若不存在,则提示错误信息,退出。

10、Nignx

(1)正向代理

正向代理是一个位于客户端和原始服务器(origin server)之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器),然后代理向原始服务器转交请求并将获得的内容返回给客户端。客户端必须要进行一些特别的设置才能使用正向代理。

(2)反向代理

反向代理(ReverseProxy)方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给internet上请求连接的客户端,简单来说就是真实的服务器不能直接被外部网络访问,想要访问必须通过代理。

(3)动静分离

运用Nginx的反向代理功能分发请求:所有动态资源的请求交给应用服务器,而静态资源的请求(例如图片、视频、CSS、JavaScript文件等)则直接由Nginx返回到浏览器,这样能大大减轻应用服务器的压力

(4)负载均衡

负载均衡也是 Nginx常用的一个功能,当一台服务器的单位时间内的访问量越大时,服务器压力就越大,大到超过自身承受能力时,服务器就会崩溃。为了避免服务器崩溃,让用户有更好的体验,我们通过负载均衡的方式来分担服务器压力。我们可以建立很多很多服务器,组成一个服务器集群,当用户访问网站时,先访问一个中间服务器,在让这个中间服务器在服务器集群中选择一个压力较小的服务器,然后将该访问请求引入该服务器。如此以来,用户的每次访问,都会保证服务器集群中的每个服务器压力趋于平衡,分担了服务器压力,避免了服务器崩溃的情况。负载均衡配置一般都需要同时配置反向代理,通过反向代理跳转到负载均衡。 nginx负载均衡要两台或以上的应用服务器 , 并且在nginx.conf中写入相关配置,主要是对proxy_pass,upstream的使用。

nginx支持的负载均衡调度算法方式如下:

(1)weight轮询(默认):

接收到的请求按照顺序逐一分配到不同的后端服务器,即使在使用过程中,某一台后端服务器宕机,nginx会自动将该服务器剔除出队列,请求受理情况不会受到任何影响。 这种方式下,可以给不同的后端服务器设置一个权重值(weight),用于调整不同的服务器上请求的分配率;权重数据越大,被分配到请求的几率越大;该权重值,主要是针对实际工作环境中不同的后端服务器硬件配置进行调整的。

(2)ip_hash:

每个请求按照发起客户端的ip的hash结果进行匹配,这样的算法下一个固定ip地址的客户端总会访问到同一个后端服务器,这也在一定程度上解决了集群部署环境下session共享的问题。

(3)fair:

智能调整调度算法,动态的根据后端服务器的请求处理到响应的时间进行均衡分配,响应时间短处理效率高的服务器分配到请求的概率高,响应时间长处理效率低的服务器分配到的请求少;结合了前两者的优点的一种调度算法。但是需要注意的是nginx默认不支持fair算法,如果要使用这种调度算法,请安装upstream_fair模块。

(4)url_hash:

按照访问的url的hash结果分配请求,每个请求的url会指向后端固定的某个服务器,可以在nginx作为静态服务器的情况下提高缓存效率。同样要注意nginx默认不支持这种调度算法,要使用的话需要安装nginx的hash软件包。

11、Java虚拟机内存分布

Java虚拟机内存分为五个区域:方法区,堆,虚拟机栈,本地方法栈,程序计数器。其中方法区和堆是java虚拟机共享的内存区域,虚拟机栈,本地方法栈,程序计数器是线程私有的。

程序计数器(Program Counter Register)

当前线程执行字节码的行号指示器。通过改变这个指示器的值来选取下一条需要执行的字节码指令。这个内存区域是Java虚拟机唯一一个没有定义OutOfMemeryError情况的区域。

Java虚拟机栈(Java Visual Machine Stacks)

虚拟机栈描述的是Java方法执行的内存模型:每个方法执行是都会创建栈帧(Stack Frame)用于存储局部变量,操作栈,方法信息,动态链接,方法出口等信息。 在java虚拟机规范中,对于这两个区域规定了两种情况的异常:

1)如果线程请求的栈深度大于虚拟机所允许的深度将会抛出StackOverFlowError异常。

2)Java虚拟机可以动态扩展,当无法申请到足够的内存时会抛出OutOfMemeryError。

本地方法栈(Native Method Stacks)

本地方法栈与Java虚拟机栈非常类似,其区别是Java虚拟机栈为虚拟机执行Java方法服务,而本地方法栈是虚拟机使用到的Native方法服务。 所以本地方法栈也可能出现两种与Java虚拟机栈相同的异常。

Java堆(Java Heap)

Java堆是Java虚拟机管理的最大的一块内存区域,java堆是被所有Java线程共享的,在Java虚拟机启动时创建,此内存的唯一目的就是存放对象实例。几乎所有的对象实例都要分配在堆中。(随着JIT编译器的发展,逃逸分析技术的逐渐成熟,栈上分配,标量替换等优化技术,使得部分对象不再分配在堆上。)

Java堆的大小通过 -Xmx和-Xms两个参数控制。但是当堆的内存再无法扩展时,就会出现OutOfMemeryError。

方法区(Method Area)

方法区与Java堆一样,是各个线程共享的内存区域,他用于存储类信息,常量,静态变量以及及时编译后的代码等数据。当方法区无法满足内存分配需求时,将抛出OutOfMemeryError。

12、JVM调优

(1)JVM调优经验总结 JVM调优的一般步骤为:

第1步:分析GC日志及dump文件,判断是否需要优化,确定瓶颈问题点;

第2步:确定JVM调优量化目标;

第3步:确定JVM调优参数(根据历史JVM参数来调整);

第4步:调优一台服务器,对比观察调优前后的差异;

第5步:不断的分析和调整,直到找到合适的JVM参数配置;

第6步:找到最合适的参数,将这些参数应用到所有服务器,并进行后续跟踪。

(2)JVM调优重要参数解析

注意:不同应用,其JVM最佳稳定参数配置是不一样的。 配置: -server

-Xms12g -Xmx12g -XX:PermSize=500m -XX:MaxPermSize=1000m -Xmn2400m

-XX:SurvivorRatio=1 -Xss512k -XX:MaxDirectMemorySize=1G

-XX:+DisableExplicitGC -XX:CompileThreshold=8000 -XX:+UseConcMarkSweepGC

-XX:+UseParNewGC

-XX:+UseCompressedOops -XX:CMSInitiatingOccupancyFraction=60

-XX:ConcGCThreads=4

-XX:MaxTenuringThreshold=10 -XX:ParallelGCThreads=8

-XX:+ParallelRefProcEnabled -XX:+CMSClassUnloadingEnabled

-XX:+CMSParallelRemarkEnabled

-XX:CMSMaxAbortablePrecleanTime=500 -XX:CMSFullGCsBeforeCompaction=4

-XX:+UseCMSInitiatingOccupancyOnly -XX:+UseCMSCompactAtFullCollection

-XX:+HeapDumpOnOutOfMemoryError -verbose:gc -XX:+PrintGCDetails

-XX:+PrintGCDateStamps -Xloggc:/weblogic/gc/gc_$$.log

重要参数(可调优)解析:

-Xms12g:初始化堆内存大小为12GB。

-Xmx12g:堆内存最大值为12GB 。

-Xmn2400m:新生代大小为2400MB,包括 Eden区与2个Survivor区。

-XX:SurvivorRatio=1:Eden区与一个Survivor区比值为1:1。

-XX:MaxDirectMemorySize=1G:直接内存。报java.lang.OutOfMemoryError: Direct buffer memory 异常可以上调这个值。

-XX:+DisableExplicitGC:禁止运行期显式地调用 System.gc() 来触发fulll GC。

注意: Java RMI的定时GC触发机制可通过配置 -Dsun.rmi.dgc.server.gcInterval=86400来控制触发的时间。

-XX:CMSInitiatingOccupancyFraction=60:老年代内存回收阈值,默认值为68。

-XX:ConcGCThreads=4:CMS垃圾回收器并行线程线,推荐值为CPU核心数。

-XX:ParallelGCThreads=8:新生代并行收集器的线程数。

-XX:MaxTenuringThreshold=10:设置垃圾最大年龄。如果设置为0的话,则年轻代对象不经过Survivor区,直接进入年老代。对于年老代比较多的应用,可以提高效率。如果将此值设置为一个较大值,则年轻代对象会在Survivor区进行多次复制,这样可以增加对象再年轻代的存活时间,增加在年轻代即被回收的概论。

-XX:CMSFullGCsBeforeCompaction=4:指定进行多少次fullGC之后,进行tenured区 内存空间压缩。

-XX:CMSMaxAbortablePrecleanTime=500:当abortable-preclean预清理阶段执行达到这个时间时就会结束。

13、GC是什么?垃圾回收算法的实现?怎么去回收?

(1)GC:垃圾收集器

(2)垃圾回收算法

对象存活判断 判断对象是否存活一般有两种方式:

1)引用计数

每个对象有一个引用计数属性,新增一个引用时计数加1,引用释放时计数减1,计数为0时可以回收。此方法简单,无法解决对象相互循环引用的问题。

2)可达性分析

从GC Roots开始向下搜索,搜索所走过的路径称为引用链。当一个对象到GC Roots没有任何引用链相连时,则证明此对象是不可用的。不可达对象。

垃圾收集算法

1)引用计数(reference counting)

原理:此对象有一个引用,则加1;删除一个引用,则减1。只用收集计数为0的对象。
缺点:无法处理循环引用的问题。 

2)复制(copying)

原理:把内存空间划分为2个相等的区域,每次只使用一个区域。垃圾回收时,遍历当前使用区域,把正在使用的对象复制到另外一个区域。
优点:不会出现碎片问题。
缺点:1、暂停整个应用。2、需要2倍的内存空间。

3)标记-清理(Mark-and-sweep)---sun前期版本就是用这个技术。

原理:对于“活”的对象,一定可以追溯到其存活在堆栈、静态存储区之中的引用。这个引用链条可能会穿过数个对象层次。第一阶段:从GC roots开始遍历所有的引用,对有活的对象进行标记。第二阶段:对堆进行遍历,把未标记的对象进行清除。这个解决了循环引用的问题。
缺点:
1、暂停整个应用;
2、会产生内存碎片。

4)标记-压缩(Mark-Compact)自适应

原理:第一阶段标记活的对象,第二阶段把为标记的对象压缩到堆的其中一块,按顺序放。
优点:
1、避免标记扫描的碎片问题;
2、避免停止复制的空间问题。
具体使用什么方法GC,Java虚拟机会进行监视,如果所有对象都很稳定,垃圾回收器的效率低的话,就切换到“标记-扫描”方式;同样,Java虚拟机会跟踪“标记-扫描”的效果,要是堆空间碎片出现很多碎片,就会切换回“停止-复制”模式。这就是自适应的技术。

5)分代(generational collecting) 原理:基于对象生命周期分析得出的垃圾回收算法。把对象分为年轻代、年老代、持久代,对不同的生命周期使用不同的算法(2-3方法中的一个即时自适应)进行回收。

6)自适应算法(Adaptive Collector) 在特定的情况下,一些垃圾收集算法会优于其它算法。基于Adaptive算法的垃圾收集器就是监控当前堆的使用情况,并将选择适当算法的垃圾收集器。