JAVA 面试题 合辑(三)

JAVA 面试题 合辑(一)https://blog.csdn.net/haponchang/article/details/92741553

JAVA 面试题 合辑(二)https://blog.csdn.net/haponchang/article/details/92829739

JAVA 面试题 合辑(三)https://blog.csdn.net/haponchang/article/details/92833016

目录

tomcat的架构

Mybatis架构

微服务架构

MQ详解

hibernate架构,hibernate二级缓存如何实现

JDBC相关知识,比如PrepareStatement和Statement的优缺点,优化 

设计模式

单例模式(线程安全且内存消耗小)

Java中如何实现代理机制(JDK、CGLIB)

分布式

为什么要进行系统拆分?

分布式服务框架

(分布式锁)使用redis和zk如何设计分布式锁?使用zk来设计分布式锁可以吗?这两种分布式锁的实现方式区别是什么,哪种效率比较高?

分布式事务

分布式会话

RPC原理,使用过的框架

分布式场景的一些问题,分布式事务,分段提交实现,分布式锁如何实现

zookeeper组件,介绍选主算法

分布式集群下如何做到唯一序列号

设计一个秒杀系统,30 分钟没付款就自动关闭交易。

如果有人恶意创建非法连接,怎么解决

分布式事务的原理,优缺点,如何使用分布式事务。

什么是一致性 hash。

什么是 restful,讲讲你理解的 restful。

解释什么是 MESI 协议(缓存一致性)

说说你知道的几种 HASH 算法,简单的也可以。

什么是 paxos 算法

什么是 zab 协议

一个在线文档系统,文档可以被编辑,如何防止多人同时对同一份文档进行编辑更新

Dubbo Cluster 实现集群

线上系统突然变得异常缓慢,你如何查找问题

一次 RPC 请求的流程是什么

注册中心来实现服务发现与传统的 DNS 实现服务发现有什么不同

注册中心实现方式

异步模式的用途和意义

编程中自己都怎么考虑一些设计原则的,比如开闭原则,以及在工作中的应用

后台系统怎么防止请求重复提交

描述一个服务从发布到被消费的详细过程

讲讲你理解的服务治理。

如何做到接口的幂等性

优化

算法


框架源码解读

tomcat的架构

概述

Tomcat 的整体架构包含了两个核心组件连接器(Connector)和容器(Container)。

连接器负责对外交流,处理 Socket 连接,负责网络字节流与 Request 和 Response 对象的转化。

容器负责内部处理,加载和管理 Servlet,以及具体处理 Request 请求。

连接器:

连接器用 ProtocolHandler 接口来封装通信协议和 I/O 模型的差异,ProtocolHandler 内部又分为 EndPoint 和 Processor 模块,EndPoint 负责底层 Socket 通信,Proccesor 负责应用层协议解析。连接器通过适配器 Adapter 调用容器。

Tomcat 支持的 I/O 模型有

NIO:非阻塞 I/O,采用 Java NIO 类库实现。

NIO2:异步 I/O,采用 JDK 7 最新的 NIO2 类库实现。

APR:采用 Apache 可移植运行库实现,是 C/C++ 编写的本地库。

Tomcat 支持的应用层协议有

HTTP/1.1:这是大部分 Web 应用采用的访问协议。

AJP:用于和 Web 服务器集成(如 Apache)。

HTTP/2:HTTP 2.0 大幅度的提升了 Web 性能。

容器

Tomcat 设计了 4 种容器,分别是 Engine、Host、Context 和 Wrapper。这 4 种容器不是平行关系,而是父子关系。

所有容器组件都实现了 Container 接口,因此组合模式可以使得用户对单容器对象和组合容器对象的使用具有一致性。这里单容器对象指的是最底层的 Wrapper,组合容器对象指的是上面的 Context、Host 或者 Engine。Container 接口定义如下:

public interface Container extends Lifecycle {

    public void setName(String name);

    public Container getParent();

    public void setParent(Container container);

    public void addChild(Container child);

    public void removeChild(Container child);

    public Container findChild(String name);

}

连接器中的 Adapter 会调用容器的 Service 方法来执行 Servlet,最先拿到请求的是 Engine 容器,Engine 容器对请求做一些处理后,会把请求传给自己子容器 Host 继续处理,依次类推,最后这个请求会传给 Wrapper 容器,Wrapper 会调用最终的 Servlet 来处理。那么这个调用过程具体是怎么实现的呢?答案是使用 Pipeline-Valve 管道。

Pipeline-Valve 是责任链模式,责任链模式是指在一个请求处理的过程中有很多处理者依次对请求进行处理,每个处理者负责做自己相应的处理,处理完之后将再调用下一个处理者继续处理。

Valve 表示一个处理点

public interface Valve {

  public Valve getNext();

  public void setNext(Valve valve);

  public void invoke(Request request, Response response)

}

 Pipeline 接口:

public interface Pipeline extends Contained {

  public void addValve(Valve valve);

  public Valve getBasic();

  public void setBasic(Valve valve);

  public Valve getFirst();

}

整个调用过程由连接器中的 Adapter 触发的,它会调用 Engine 的第一个 Valve:

// Calling the container

connector.getService().getContainer().getPipeline().getFirst().invoke(request, response);

Wrapper 容器的最后一个 Valve 会创建一个 Filter 链,并调用 doFilter() 方法,最终会调到 Servlet 的 service 方法。

请求的链式调用是基于 Pipeline-Valve 责任链来完成的,这样的设计使得系统具有良好的可扩展性,如果需要扩展容器本身的功能,只需要增加相应的 Valve 即可。

 

Mybatis架构

Mybatis的功能架构分为三层:

API接口层:提供给外部使用的接口API,开发人员通过这些本地API来操纵数据库。接口层一接收到调用请求就会调用数据处理层来完成具体的数据处理。
数据处理层:负责具体的SQL查找、SQL解析、SQL执行和执行结果映射处理等。它主要的目的是根据调用的请求完成一次数据库操作。
基础支撑层:负责最基础的功能支撑,包括连接管理、事务管理、配置加载和缓存处理,这些都是共用的东西,将他们抽取出来作为最基础的组件。为上层的数据处理层提供最基础的支撑。

MyBatis运行流程


加载全局配置文件:加载数据源,用来操作数据库,事务。
获取SqlSesionFactory:用来生成sqlSesion,sqlsessionFactory是线程安全。
SqlSessionFactory生产出sqlSession,sqlSesion里面提供一系列操作数据库的接口。
程序员通过调用sqlSession提供的接口来操作数据。

 

微服务架构

微服务架构下,服务调用主要依赖下面几个基本组件:

服务描述

服务调用首先要解决的问题就是服务如何对外描述。比如服务名、调用这个服务需要提供哪些信息、返回的结果是什么格式的、如何解析等问题。

常用的服务描述方式包括 RESTful API、XML 配置以及 IDL 文件三种。

其中,RESTful API 方式通常用于 HTTP 协议的服务描述,并且常用 Wiki 或者Swagger来进行管理。下面是一个 RESTful API 方式的服务描述的例子。

XML 配置方式多用作 RPC 协议的服务描述,通过 *.xml 配置文件来定义接口名、参数以及返回值类型等。

IDL 文件方式通常用作 Thrift 和 gRPC 这类跨语言服务调用框架中,比如 gRPC 就是通过 Protobuf 文件来定义服务的接口名、参数以及返回值的数据结构。

注册中心

有了服务的接口描述,下一步要解决的问题就是服务的发布和订阅,就是说你提供了一个服务,如何让外部想调用你的服务的人知道。这个时候就需要一个类似注册中心的角色,服务提供者将自己提供的服务以及地址登记到注册中心,服务消费者则从注册中心查询所需要调用的服务的地址,然后发起请求。

一般来讲,注册中心的工作流程是:

服务提供者在启动时,根据服务发布文件中配置的发布信息向注册中心注册自己的服务。

服务消费者在启动时,根据消费者配置文件中配置的服务信息向注册中心订阅自己所需要的服务。

注册中心返回服务提供者地址列表给服务消费者。

当服务提供者发生变化,比如有节点新增或者销毁,注册中心将变更通知给服务消费者。

服务框架

通过注册中心,服务消费者就可以获取到服务提供者的地址,有了地址后就可以发起调用。但在发起调用之前你还需要解决以下几个问题。

服务通信采用什么协议?就是说服务提供者和服务消费者之间以什么样的协议进行网络通信,是采用四层 TCP、UDP 协议,还是采用七层 HTTP 协议,还是采用其他协议?

数据传输采用什么方式?就是说服务提供者和服务消费者之间的数据传输采用哪种方式,是同步还是异步,是在单连接上传输,还是多路复用。

数据压缩采用什么格式?通常数据传输都会对数据进行压缩,来减少网络传输的数据量,从而减少带宽消耗和网络传输时间,比如常见的 JSON 序列化、Java 对象序列化以及 Protobuf 序列化等。

服务监控

一旦服务消费者与服务提供者之间能够正常发起服务调用,你就需要对调用情况进行监控,以了解服务是否正常。通常来讲,服务监控主要包括三个流程。

指标收集。就是要把每一次服务调用的请求耗时以及成功与否收集起来,并上传到集中的数据处理中心。

数据处理。有了每次调用的请求耗时以及成功与否等信息,就可以计算每秒服务请求量、平均耗时以及成功率等指标。

数据展示。数据收集起来,经过处理之后,还需要以友好的方式对外展示,才能发挥价值。通常都是将数据展示在 Dashboard 面板上,并且每隔 10s 等间隔自动刷新,用作业务监控和报警等。

服务追踪

除了需要对服务调用情况进行监控之外,你还需要记录服务调用经过的每一层链路,以便进行问题追踪和故障定位。

服务追踪的工作原理大致如下:

服务消费者发起调用前,会在本地按照一定的规则生成一个 requestid,发起调用时,将 requestid 当作请求参数的一部分,传递给服务提供者。

服务提供者接收到请求后,记录下这次请求的 requestid,然后处理请求。如果服务提供者继续请求其他服务,会在本地再生成一个自己的 requestid,然后把这两个 requestid 都当作请求参数继续往下传递。

以此类推,通过这种层层往下传递的方式,一次请求,无论最后依赖多少次服务调用、经过多少服务节点,都可以通过最开始生成的 requestid 串联所有节点,从而达到服务追踪的目的。

服务治理

服务监控能够发现问题,服务追踪能够定位问题所在,而解决问题就得靠服务治理了。服务治理就是通过一系列的手段来保证在各种意外情况下,服务调用仍然能够正常进行。

 

MQ详解

当客消息中间件的组成

1 Broker

消息服务器,作为server提供消息核心服务

 2 Producer

消息生产者,业务的发起方,负责生产消息传输给broker,

 3 Consumer

消息消费者,业务的处理方,负责从broker获取消息并进行业务逻辑处理

4 Topic

主题,发布订阅模式下的消息统一汇集地,不同生产者向topic发送消息,由MQ服务器分发到不同的订阅者,实现消息的       广播

 5 Queue

队列,PTP模式下,特定生产者向特定queue发送消息,消费者订阅特定的queue完成指定消息的接收

 6 Message

消息体,根据不同通信协议定义的固定格式进行编码的数据包,来封装业务数据,实现消息的传输

消息中间件模式分类

1 点对点

PTP点对点:使用queue作为通信载体

说明: 
消息生产者生产消息发送到queue中,然后消息消费者从queue中取出并且消费消息。 
消息被消费以后,queue中不再存储,所以消息消费者不可能消费到已经被消费的消息。 Queue支持存在多个消费者,但是对一个消息而言,只会有一个消费者可以消费。

2 发布/订阅

Pub/Sub发布订阅(广播):使用topic作为通信载体 

消息中间件的优势

1 系统解耦

交互系统之间没有直接的调用关系,只是通过消息传输,

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值