1、RPC的重要组成有哪些?
-
客户端(Client):发起RPC请求的部分。客户端包含代表远程过程的存根(stub),它提供与本地过程相同的接口。
-
服务器(Server):接受RPC请求并执行服务的部分。服务器同样包含一个存根,负责接受请求、解码参数、执行请求并返回结果。
-
传输层:RPC需要一种通信方式来在客户端和服务器之间传输数据。这通常通过网络完成,例如使用TCP/IP或UDP。
-
消息格式/序列化:由于网络传输层通常只能传输字节流,RPC需要将数据(如过程参数和返回值)转换为这种格式。这个转换过程叫做序列化(将数据转换为字节流)和反序列化(将字节流转回原始数据)。
-
请求与响应:客户端发起的是请求,服务器返回的是响应。每个请求都与一个响应匹配。
-
服务注册与发现:在某些RPC系统中(如gRPC、Apache Thrift等),服务器可以注册其提供的服务,并且客户端可以发现这些服务。这可以使得客户端和服务器的连接更加动态和灵活。
-
错误处理:如果远程调用中发生错误(如网络问题、服务不可用等),RPC框架应该能够捕获并处理这些错误。
-
身份验证和授权:为了确保只有合法的客户端可以访问服务,RPC系统可能会包含身份验证和授权机制。
-
负载均衡:在多个服务器实例中,RPC系统可能会提供负载均衡功能,使得客户端的请求可以均匀地分配到不同的服务器。
2、注册中心怎么选?CP更重要还是AP?ZooKeeper是CP还是AP?
(1)选择CP还是AP取决于你的系统需求:
- 如果系统需要确保数据的一致性 ,并且可以承受某些请求失败或延迟,那么CP可能更合适。
- 如果系统需要确保高可用性 ,即使这意味着在某些情况下返回的数据可能是过时的,那么AP可能更合适。
(2)ZooKeeper 是一个CP系统。当网络分区发生时,为了维护一致性,ZooKeeper可能会牺牲可用性。这意味着在某些情况下,ZooKeeper可能不会响应客户端的请求,以确保数据的一致性。
3、序列化的作用是什么?Serializable的原理?
(1)在RPC(远程过程调用)中,序列化的主要作用是将数据或对象转化为可传输的格式,使其能够在网络上进行传输,从而实现不同节点或服务之间的通信。
具体作用如下:
-
数据交换:通过序列化,客户端可以将请求参数转化为字节流,在网络上发送到服务器;服务器接收到字节流后,再通过反序列化恢复为原始的请求参数。
-
保证数据完整性:序列化过程中可以将数据结构完整地转化为字节流,确保数据在传输过程中不丢失任何信息。
-
兼容性:有些序列化协议(如Protocol Buffers, Avro等)提供了版本控制和兼容性管理,使得数据格式可以随着时间演进而不影响已有的客户端和服务器之间的通信。
(2)Serializable的原理
Serializable
是Java中的一个标记性接口 ,用于指示一个类的对象可以被序列化。**当一个类实现了Serializable
接口时,Java的对象序列化机制可以将其转换为字节流,**反之也可以从字节流中重构对象。
4、redis的跳表,说下底层结构和查询过程和效率,和二叉树比较,为啥不用红黑树(红黑树不支持范围查找)?和B+树有什么区别?
(1) 跳表(SkipList)主要被用于有序集合(Sorted Sets, zset)的实现。它能实现快速查询、插入和删除操作。它是由多层链表组成,每一层都是一个有序链表。层级之间通过上下指针相互连接,底层是完整数据链表。
(2)查询过程和效率
- 从最顶层的链表开始,从左至右进行搜索,直到找到一个大于或等于目标值的节点或到达链表的末尾。
- 如果当前节点值等于目标值,查询成功。
- 如果当前节点值大于目标值或到达链表的末尾,则向下移动一层,并从左边的节点继续搜索。
- 如果到达底层链表还没有找到目标值,则查询失败。
查询效率为O(log n),因为每一次跳跃都大致减少了一半的搜索空间。
(3)与二叉树和红黑树的比较
-
平衡问题:二叉查找树(如红黑树)需要进行平衡操作,而跳表通过随机化的方法来确保层级结构的均衡,避免了复杂的旋转操作。
-
范围查询:红黑树不支持范围查询,而跳表的底层是完整的有序链表,所以很容易进行范围查询。
-
简单性和实现难度:跳表的结构和算法相对简单,而红黑树的实现相对复杂。
(4)与B+树的区别
-
结构:跳表是基于链表的,而B+树是基于树的结构。
-
存储方式:在B+树中,所有的值都在叶子节点,并且叶子节点形成了一个有序链表。而在跳表中,每一个节点可能出现在多个层级上。
-
查询效率:B+树和跳表的查询效率都是O(log n),但在实际应用中,由于B+树更适合磁盘存储和I/O操作,它通常用于数据库索引;而跳表因为其结构简单,经常用于内存数据结构,如Redis。
-
扩展性:跳表更容易进行水平扩展。
(5)为什么Redis选择跳表而不是红黑树?
Redis使用跳表来实现其有序集合数据类型(Sorted Set)。跳表相比红黑树来说,更容易实现,理解和维护。同时,跳表更容易支持范围查询和有序数据的快速插入/删除。红黑树的范围查找并不直接得到,需要进行额外的遍历操作。
5、Redis的数据类型?如何实现整数自增?
- 字符串(String):可以存储字符串、整数或浮点数。
- 列表(Lists):是字符串元素的集合,并且是有序的。Redis lists使用链表实现,所以插入和删除操作是快速的。
- 集合(Sets):是字符串的无序集合,并且集合中的每个字符串都是唯一的。
- 有序集合(Sorted Sets, zset):与集合类似,但每个元素都关联了一个分数,这使得元素能按分数进行排序。
- 哈希(Hashes):是键值对的集合。
- 位图(Bitmaps):实际上是字符串的特定操作方式,通过这种方式,你可以将字符串视为位数组,并能够对其进行操作。
- HyperLogLogs:这是一个概率数据结构,用于估计集合的基数。
- 流(Streams):新的数据类型(在Redis 5.0中引入),用于实现持久的日志数据类型。
要实现整数的自增功能,可以使用INCR
命令。如果键不存在,Redis会将它设置为0,然后执行自增操作。
6、Redis集群
Redis集群提供了一种方式,允许多个Redis节点协同工作,以此来提供更高的可用性和性能。其核心特点和概念包括:
- 数据分片:数据被分为多个片段,并在多个Redis节点上进行分布。
- 主从复制:每个Redis节点都会有0或多个复制品。这样,当主节点不可用时,其中一个从节点可以被提升为新的主节点。
- 自动故障转移:当主节点不可用时,Redis集群可以自动从相关的从节点中选择一个进行提升。
- 客户端与集群的通信:Redis客户端不需要连接集群中的所有节点,它可以连接到任何一个可用的节点,然后由该节点重定向到正确的节点(如果需要)。
- 节点之间的通信:使用二进制协议进行,主要用于节点间状态的广播。
集群模式不仅提高了Redis的性能(通过分片)和高可用性(通过主从复制和故障转移),而且还允许Redis部署规模更大、容纳更多数据。
7、Spring的Bean生命周期?
Bean 的生命周期指的是 Bean 在 Spring(IoC)中从创建到销毁的整个过程。Bean 的生命周期主要包含以下 5 个流程:
(1)实例化:为 Bean 分配内存空间;
(2)设置属性:将当前类依赖的 Bean 属性,进行注入和装配;
(3)初始化:
- 执行各种通知。
- 执行初始化的前置方法。
- 执行初始化方法。
- 执行初始化的后置方法。
(4)使用 Bean:在程序中使用 Bean 对象;
(5)销毁 Bean:将 Bean 对象进行销毁操作。
8、如果在bean初始化的时候加一些操作,有哪些方式?
实现BeanPostProcessor接口 其中有(before 和 after)方法
@PostConstuct懒加载的机制
9、MySQL优化主要是怎么优化的?
10、分页查询的MySQL优化有做过吗?
11、MySQL的索引底层结构?
12、MySQL的事务隔离级别?
13、可重复读是如何实现的?
14、多个事务读 和 多个事务写会发生什么问题?
15、MySQL的索引?索引什么时候失效
16、MySQL存储字符串有哪些类型?
17、MVCC机制说一下?
18、Linux中如何杀死一个进程?kill命令的原理?
19、有哪些锁?说一下synchronized和lock的区别
20、hashmap怎么实现的,哈希冲突是什么,解决hash冲突的办法,
21、tcp连接,怎么保证可靠
-
三次握手(Three-way Handshake):建立连接时,TCP使用三次握手机制来确保双方都准备好进行通信。
-
确认应答(Acknowledgements):当接收到数据时,接收方会发送一个确认消息(ACK)回到发送方。发送方在发送数据后会启动一个计时器,等待ACK的到来。
-
超时重传:如果发送方在预定时间内没有收到ACK,它会假设数据包已丢失,并重新发送该数据包。
-
序列号:每个发送出去的字节都有一个序列号。接收方使用这些序列号来重新组装数据流并检测丢失的数据包。
-
滑动窗口:TCP使用滑动窗口协议来控制在一个给定的时间内发送者可以发送多少数据,以及何时需要确认。这不仅可以处理丢包,还可以进行流量控制,防止接收方被发送方的数据淹没。
-
错误检测:TCP头部有一个校验和字段,用于检查数据是否在传输过程中被损坏。
-
拥塞控制:如果网络出现拥塞,TCP会减少其发送数据的速率,避免更严重的网络问题。这是通过观察丢失的数据包来实现的,因为丢失的数据包通常是网络拥塞的一个标志。
-
四次挥手(Four-way Handshake):当连接的一方完成其发送任务后,它可以请求关闭连接,这需要一个四步过程来确保双方都完成了数据传输。
22、Java中如何实现多态
继承、重写和向上转型。 只有满足这3 个条件,开发人员才能够在同一个继承结构中使用统一的逻辑实现代码处理不同的对象,从而执行不同的行为。
- 继承:在多态中必须存在有继承关系的子类和父类。
- 重写:子类对父类中某些方法进行重新定义,在调用这些方法时就会调用子类的方法。
23、垃圾回收算法
24、HTTP和HTTPS的区别,HTTP请求的构成?
**(1)**HTTP与HTTPS的区别
-
安全性:
- HTTP:超文本传输协议,信息是明文传输,存在安全风险。
- HTTPS:即HTTP加入SSL层,超文本传输安全协议。信息是经过加密的,更加安全。
-
端口:
- HTTP:使用端口80。
- HTTPS:使用端口443。
-
性能:
- HTTP:因为没有加密,所以HTTP的速度比较快。
- HTTPS:需要进行加密处理,因此相对较慢(但随着现代技术的发展,这种差异已经被最小化)。
-
证书:
- HTTP:不需要证书。
- HTTPS:需要SSL证书。如果网站使用的是自签名的SSL证书,浏览器会提示访问者。
(2) HTTP请求结构
一个HTTP请求主要包含以下部分:
- 请求行:包括请求方法(如GET, POST, PUT, DELETE等)、请求URI以及HTTP版本。
- 请求头(Headers):描述请求的元数据或其他信息,如User-Agent(浏览器类型)、Accept(可接受的回复类型)、Host(请求的服务器)等。
- 空行:请求头和请求体之间的分隔符。
- 请求体(Body):POST或PUT请求中传送的数据。
(3) 请求头的作用
请求头在HTTP请求中扮演了重要的角色,它为服务器提供了关于客户端请求的一些信息。以下是请求头的一些常见用途:
- 内容类型 :通过
Content-Type
头部,客户端可以告诉服务器发送的数据是什么格式,如application/json
或text/html
。 - 内容长度 :通过
Content-Length
头部,指示请求或响应体的大小。 - 认证 :例如,
Authorization
头部用于包含凭据,通常用于API认证。 - 缓存控制 :
Cache-Control
和其他相关的头部可以控制如何缓存响应内容。 - 用户代理 :
User-Agent
头部描述了发出请求的客户端类型,如浏览器或其他客户端应用。 - 接受的内容类型 :通过
Accept
头部,客户端可以告诉服务器它希望收到哪种类型的响应。 - Cookies :
Cookie
头部可以包含服务器设置的任何cookie,它们在每个请求中发送回服务器。 - 跨域请求 :
Origin
头部表示请求来自哪个源,与CORS(跨来源资源共享)策略相关。
25、GET和POST的区别?
26、介绍二叉树,平衡二叉树,完全二叉树,红黑树,b树,b+树,说下他们的特点,查询时间复杂度,区别和各自的优缺点。
(1)二叉树 (Binary Tree)
- 特点:每个节点最多有两个子节点:左子节点和右子节点。
- 查询时间复杂度:最坏情况下为O(n),平均为O(log n)。
- 优缺点:基础数据结构,简单易于实现;但如果不平衡,查询效率可能会受影响。
(2)平衡二叉树 (Balanced Binary Tree)
- 特点:也被称为AVL树。树中任何两个子树的高度差最大为1。
- 查询时间复杂度:O(log n)。
- 优缺点:自动保持平衡状态,查询时间效率较高;但插入和删除操作可能涉及多次"旋转"。
(3)全二叉树 (Complete Binary Tree)
- 特点:除最后一层外,其他层的节点数达到最大,并且最后一层的节点从左到右连续。
- 查询时间复杂度:O(log n)。
- 优缺点:适于顺序存储结构;不必像完满二叉树那样严格。
(4)红黑树 (Red-Black Tree)
- 特点:自平衡的二叉查找树。节点可以是红色或黑色,树满足特定的红黑性质。
- 查询时间复杂度:O(log n)。
- 优缺点:保证了最坏情况下的时间复杂度为O(log n);相对复杂的插入和删除操作。
(5)B树
- 特点:多路搜索树,通常用于数据库和文件系统。
- 查询时间复杂度:O(log n)。
- 优缺点:可以存储大量数据并减少磁盘I/O操作;结构比较复杂。
(6)B+树
- 特点:B树的扩展,所有的值都在叶子节点上,非叶子节点不存储数据,只用于索引。
- 查询时间复杂度:O(log n)。
- 优缺点:范围查询更加高效;每次查找都需要到达叶子节点。
区别和总结:
- 二叉树是最基础的数据结构,但不保证平衡。
- 平衡二叉树 或AVL树确保了平衡,但需要在插入或删除时进行平衡操作。
- 完全二叉树尽可能地填充每一层,但不像满二叉树那样严格。
- 红黑树保证了最坏情况下的时间效率,但其结构和操作比AVL树更复杂。
- B树 和B+树主要用于存储系统和数据库,优化磁盘I/O。B+树特别适合范围查询。
27、场景题:2个G的文件,里面有两或三条重复的数据记录,如何找出?
(1) 使用哈希函数 :对每条数据记录计算哈希值。如果你的数据记录是字符串或其他数据类型,可以使用像MD5或SHA-1这样的哈希函数。计算哈希的目的是为了将大数据记录转化为较小的唯一标识符(哈希值),这样处理起来更加高效。
(2)外部排序:
- 因为2G的文件可能不适合全部加载到内存中,可以使用外部排序来处理它。首先,将文件划分为多个小的分块,使得每块可以被单独加载到内存中。
- 对每块数据使用内部排序算法(如快速排序或归并排序)进行排序。
- 使用多路归并排序算法合并所有已排序的分块。
(3)使用哈希表进行优化:
- 如果你的机器内存允许,可以考虑将数据的哈希值加载到一个哈希表中。
- 每次读取文件中的一条记录,计算其哈希值,然后查找哈希表中是否已存在该哈希值。
- 如果已存在,这条记录可能是重复的。可以对原始记录进行比较以确认是否真的重复。
注意:哈希函数可能会出现冲突,即不同的数据记录可能会有相同的哈希值。因此,当发现两条记录的哈希值相同时,应该进一步检查原始记录以确定是否确实重复。