Java岗大厂面试百日冲刺 - 日积月累,每日三题【Day38,我崩溃了

本栏目Java开发岗高频面试题主要出自以下各技术栈:Java基础知识集合容器并发编程JVMSpring全家桶MyBatis等ORMapping框架MySQL数据库Redis缓存RabbitMQ消息队列Linux操作技巧等。

面试题1:当你发现一条SQL很慢,你的处理思路是什么?

==========================================================================================

当你发现BUG怎么处理?相信看过【Day18】的朋友们都已经心中有数~~

  1. 发现Bug

  2. 确定Bug不是自己造成的,如果无法确定,不要理会步骤1

  3. 向组内宣传“程序里有一个未知Bug,错不在我”

  4. 谁响应,谁对Bug负责

  5. 没人响应,就要求特定人员配合调试

  6. 如果不配合,就是特定人员对Bug负责

  7. 如果特定人员配合,就相当于特定人员发现了一个Bug

  8. 让特定人员看步骤1

  9. 完美,无懈可击

在这里插入图片描述

言归正传。。

我们是如何发现慢SQL的?除了慢查询日志和人为发现之外,一般出现慢查询时会有如下三个特征:

  • 数据库CPU负载高。一般是查询语句中有很多计算逻辑,或并发处理线程较多,导致数据库cpu负载。

  • IO过高导致服务器卡住,这个一般和全表查询没索引有关系,问题出在处理的数据量太大

  • 查询语句正常,索引正常但是还是慢。如果表面上索引都配置了,但是查询慢,那得看看索引是否生效

有些SQL虽然出现在慢查询日志中,但未必是其本身的性能问题,可能是因为锁等待服务器压力高等等。

需要分析SQL语句真实的执行计划,而不是看重新执行一遍SQL时,看是不是变快了(查询缓存都不带考虑的?)。。而是使用Explain工具来逐步调优,了解 MySQL 在执行这条数据时的一些细节,比如是否进行了优化、是否使用了索引、索引选择器是否正确选择等等。基于 Explain 的返回结果我们就可以根据 MySQL 的执行细节进一步优化语法,使索引能被正确使用,实现性能需求。

关于索引的创建及优化原则,美团点评技术团队的几点总结,引用一下:

  1. 最左前缀匹配原则,非常重要的原则,mysql会一直向右匹配直到遇到范围查询(>、<、between、like)就停止匹配,比如a = 1 and b = 2 and c > 3 and d = 4 如果建立(a,b,c,d)顺序的索引,d是用不到索引的,如果建立(a,b,d,c)的索引则都可以用到,a,b,d的顺序可以任意调整;

  2. =和in可以乱序,比如a = 1 and b = 2 and c = 3 建立(a,b,c)索引可以任意顺序,mysql的查询优化器会帮你优化成索引可以识别的形式,当然,好习惯要靠自己保持;

  3. 尽量选择区分度高的列作为索引,区分度的公式是count(distinct col)/count(*),表示字段不重复的比例,比例越大我们扫描的记录数越少,唯一键的区分度是1,而一些状态、性别字段可能在大数据面前区分度就是0,那可能有人会问,这个比例有什么经验值吗?使用场景不同,这个值也很难确定,一般需要join的字段我们都要求是0.1以上,即平均1条扫描10条记录;

  4. 索引列不能参与计算,保持列“干净”,比如from_unixtime(create_time) = ’2014-05-29’就不能使用到索引,原因很简单,b+树中存的都是数据表中的字段值,但进行检索时,需要把所有元素都应用函数才能比较,显然成本太大。所以语句应该写成create_time = unix_timestamp(’2014-05-29’)

  5. 尽量的扩展索引,不要新建索引。比如表中已经有a的索引,现在要加(a,b)的索引,那么只需要修改原来的索引即可。

当然,我们知道还有单表数据量过大大字段检索模糊匹配效率时间维度统计效果差等MySQL硬性问题,俗称硬伤,那我们就得基于实际情况来进行分库分表、切换检索引擎(如ES、FastDFS)等方式来处理了,术业有专攻,总不能在一棵树上吊死对吧。


在这里插入图片描述

课间休息,欣赏一下来自咱们群里同学的搬砖工地。工作之余抬头看看都市夜景,不禁心驰神往~

坐标:上海

作者:maybe


面试题2:怎么理解负载均衡的?你处理负载均衡都有哪些途径?

============================================================================================

负载均衡(Load Balance)是集群技术(Cluster)的一种应用。负载均衡可以将工作任务分摊到多个处理单元,从而提高并发处理能力。下面是一组普通的web架构,我理解做负载均衡的切入点一般在web层和数据层

在这里插入图片描述

目前最常见的负载均衡应用是Web层负载均衡。根据实现的原理不同,常见的web负载均衡技术包括:DNS轮询IP负载均衡CDN反向代理以及http重定向等等。其中IP负载均衡可以使用硬件设备或软件方式来实现。

对于数据层负载均衡,我们常用的分布式架构、多节点集群、消息中间件(如Mycat)等来控制集群负载均衡状况,同样是横向扩展,但侧重点在于对集群的管理和灾备(高可用)方面。因此,实际大多负载均衡的工作还是在Web层。

在这里插入图片描述

高性能集群:将单个重负载的请求分散到多个节点进行处理,最后再将处理结果进行汇总;

高可用集群:提高冗余单元,避免单点故障;

负载均衡集群:将大量的并发请求分担到多个处理节点。由于单个处理节点的故障不影响整个服务,负载均衡集群同时也实现了高可用性。

Web层负载均衡

任何的负载均衡技术都要想办法建立某种一对多的映射机制:一个请求的入口映射到多个处理请求的节点,从而实现分而治之(Divide and Conquer)。

1、【协议层】http重定向

当http代理(比如浏览器)向web服务器请求某个URL后,web服务器可以通过http响应头信息中的Location标记来返回一个新的URL。这意味着HTTP代理需要继续请求这个新的URL,完成自动跳转。

在这里插入图片描述

这种负载均衡方案的有点是比较简单,缺点是浏览器需要两次请求服务器才能完成一次访问,性能较差;同时,重定向服务器本身的处理能力有可能成为瓶颈,整个集群的伸缩性规模有限;使用HTTP返回码302重定向,有可能使搜索引擎判断为SEO作弊,降低搜索排名。因此实践中很少使用这种负载均衡方案来部署。

2、【协议层】DNS轮询

DNS负责提供域名解析服务,当访问某个站点时,实际上首先需要通过该站点域名的DNS服务器来获取域名指向的IP地址,在这一过程中,DNS服务器完成了域名到IP地址的映射,同样,这样映射也可以是一对多的,这时候,DNS服务器便充当了负载均衡调度器,它就像http重定向转换策略一样,将用户的请求分散到多台服务器上,但是它俩的实现机制完全不同。

相比http重定向,基于DNS的负载均衡完全节省了所谓的主站点,或者说DNS服务器已经充当了主站点的职能。但不同的是,作为调度器,DNS服务器本身的性能几乎不用担心。因为DNS记录可以被用户浏览器或者互联网接入服务商的各级DNS服务器缓存,只有当缓存过期后才会重新向域名的DNS服务器请求解析。也说是DNS不存在http的吞吐率限制,理论上可以无限增加实际服务器的数量。

优势:

  1. 可以根据用户IP来进行智能解析。DNS服务器可以在所有可用的A记录中寻找离用记最近的一台服务器。

  2. 动态DNS:在每次IP地址变更时,及时更新DNS服务器。当然,因为缓存,一定的延迟不可避免。

不足:

  1. 没有用户能直接看到DNS解析到了哪一台实际服务器,对运维人员的调试带来了不便。

  2. 策略的局限性。例如你无法将HTTP请求的上下文引入到调度策略中,而在前面介绍的基于HTTP重定向的负载均衡系统中,调度器工作在HTTP层面,它可以充分理解HTTP请求后根据站点的应用逻辑来设计调度策略,比如根据请求不同的URL来进行合理的过滤和转移。

3、【协议层】CDN

CDN(Content Delivery Network,内容分发网络)。通过发布机制将内容同步到大量的缓存节点,并在DNS服务器上进行扩展,找到里用户最近的缓存节点作为服务提供节点。

因为很难自建大量的缓存节点,所以通常使用CDN运营商的服务。目前国内的服务商很少,而且

《一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》

【docs.qq.com/doc/DSmxTbFJ1cmN1R2dB】 完整内容开源分享

按流量计费,价格昂贵。

4、【协议层】反向代理负载均衡

在客户端明确的前提下,大量访问请求(QPS)涌入。我们后台通过Nginx代理了20个服务器,高QPS打进来后先打到Nginx中,通过Nginx的负载均衡来把请求分发给这20台服务器,减轻了单台服务器负担。这种客户端 → Nginx → 服务器 的模式称为反向代理,如下图:

在这里插入图片描述

N个客户端给服务器发送的请求,Nginx服务器接收到之后,按照一定的规则均衡分发给了后端的业务处理服务器进行处理了。此时,请求的客户端是明确的,但是请求具体由哪台服务器处理的并不明确了,Nginx扮演的就是一个反向代理角色。

  1. 客户端是无感知代理的存在的,反向代理对外都是透明的,访问者并不知道自己访问的是一个代理。因为客户端不需要任何配置就可以访问。

  2. 反向代理,它代理的是服务端,代服务端接收请求,主要用于服务器集群分布式部署的情况下,反向代理隐藏了服务器的信息。

反向代理的作用:

(1)保证内网的安全,通常将反向代理服务器配置为公网访问地址,代理的Web服务器是内网IP。

(2)负载均衡,通过反向代理服务器来优化每个单机服务实例的负载。

详细内容可参考《日积月累,每日三题【Day27】—— Nginx》

5、【网络层】IP负载均衡

在这里插入图片描述

  1. 客户端会向一个ip地址发出请求,这个ip地址是一个VIP(虚拟IP),这也是调度器向外公布的一个地址。

  2. 请求达到调度器,调度器会根据负载均衡算法RealServer列表中选取一个负载不高的服务器,然后把请求报文的目标地址,也就是VIP和端口通过iptables进行NAT转换成选中的服务器的真实ip地址。最后,调度器会把其连接保存在一个hash表中,只要这个连接下次再发请求报文过来就会把其分发到上次选定的服务器中。

  3. RealServer收到报文之后,会把响应返回给调度器

  4. 调度器收到报文之后,会把源地址和源端口改为虚拟ip和端口,最后再返回给客户端。

特点

  • RealServer和调度器必须位于一个ip网络之中。

  • 调度器位于RealServer和客户端之间,处理进出的通信。

  • RIP通常是内部地址,仅用于集群之间通信。

  • RealServer的网关必须指向调度器。

  • 支持端口映射,RealServer没必要跟调度器一个端口。

限制

响应报文一般比较大,每一次都需要NAT转换的话,大流量的时候,会导致调度器成为一个瓶颈。


在这里插入图片描述

课间休息,又来秀一下来自咱们群里同学的搬砖工地,坐标:苏州 大裤衩

作者:好名字可以让我的朋友更容易记住我


面试题3:你平时是怎样定位线上问题的?

==================================================================================

本题回答摘自朱晔的《Java业务开发常见错误100例》

定位问题,首先要定位问题出在哪个层次上。比如,是 Java 应用程序自身的问题还是外部因素导致的问题。我们可以先查看程序是否有异常,异常信息一般比较具体,可以马上定位到大概的问题方向;如果是一些资源消耗型的问题可能不会有异常,我们可以通过指标监控配合显性问题点来定位。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值