字节初面:十道经典面试题解析

418次阅读  |  发布于2年以前

前言

有位朋友面试了字节,后端方向。整理了这几道面试真题以及答案,如有错误,欢迎大家留言区讨论哈。金九银十冲刺,面试的小伙伴加油呀。

1.http请求头里,expire和cache-control字段含义,说说HTTP状态码

1.1 expire和cache-control字段含义

1.2 常见HTTP状态码

2.https原理,数字签名,数字证书。

2.1 https 原理

Https工作流程

  1. 用户在浏览器里输入一个https网址,然后连接到server的443端口。
  2. 服务器必须要有一套数字证书,可以自己制作,也可以向组织申请,区别就是自己颁发的证书需要客户端验证通过。这套证书其实就是一对公钥和私钥。
  3. 服务器将自己的数字证书(含有公钥)发送给客户端。
  4. 客户端收到服务器端的数字证书之后,会对其进行检查,如果不通过,则弹出警告框。如果证书没问题,则生成一个密钥(对称加密),用证书的公钥对它加密。
  5. 客户端会发起HTTPS中的第二个HTTP请求,将加密之后的客户端密钥发送给服务器。
  6. 服务器接收到客户端发来的密文之后,会用自己的私钥对其进行非对称解密,解密之后得到客户端密钥,然后用客户端密钥对返回数据进行对称加密,这样数据就变成了密文。
  7. 服务器将加密后的密文返回给客户端。
  8. 客户端收到服务器发返回的密文,用自己的密钥(客户端密钥)对其进行对称解密,得到服务器返回的数据。

2.2 数字签名,数字证书

了解过Https原理的小伙伴,都知道数字证书这玩意。为了避免公钥被篡改,引入了数字证书,如下:

数字证书构成

3.tcp连接client和server有哪些状态,time_wait状态

3.1 tcp 连接

tcp连接时,客户端client 有SYN_SENDESTABLISHED状态,服务端server有SYN_RCVDESTABLISHED状态。

tcp三次握手

开始客户端和服务器都处于CLOSED状态,然后服务端开始监听某个端口,进入LISTEN状态

3.2 time_wait状态

可以先回忆下TCP的四次挥手哈,

TCP四次挥手

TIME-WAIT 状态为什么需要等待 2MSL

2MSL,2 Maximum Segment Lifetime,即两个最大段生命周期

  • 1个 MSL 保证四次挥手中主动关闭方最后的ACK 报文能最终到达对端
  • 1个 MSL 保证对端没有收到 ACK 那么进行重传的FIN报文能够到达

4.什么是虚拟内存? 什么是物理内存?

4.1 什么是虚拟内存?

虚拟内存,是虚拟出来的内存,它的核心思想就是确保每个程序拥有自己的地址空间,地址空间被分成多个块,每一块都有连续的地址空间。同时物理空间也分成多个块,块大小和虚拟地址空间的块大小一致,操作系统会自动将虚拟地址空间映射到物理地址空间,程序只需关注虚拟内存,请求的也是虚拟内存,真正使用却是物理内存。

4.2 什么是物理内存

物理内存,指通过物理内存条而获得的内存空间,而虚拟内存则是指将硬盘的一块区域划分来作为内存。

我们常说的物理内存大小,其实是指内存条的大小。一般买电脑时,我们都会看下内存条是多大容量的,话说如果内存条大小是100G,那这100G就都能够被使用吗?不一定的,更多的还是要看CPU地址总线的位数,如果地址总线只有20位,那么它的寻址空间就是1MB,即使可以安装100G的内存条也没有意义,也只能视物理内存大小为1MB。

4.3 虚拟内存如何映射到物理内存?

如下图,CPU里有一个内存管理单元(Memory Management Unit),简称为MMU,虚拟内存不是直接送到内存总线,而是先给到MMU,由MMU来把虚拟地址映射到物理地址,程序只需要管理虚拟内存就好,映射的逻辑自然有其它模块自动处理。

5.一台机器最多可以建立多少个tcp连接,client端,server端,超过了怎么办

  • TCP连接的客户端机:每一个ip可建立的TCP连接理论受限于ip_local_port_range参数,也受限于65535。但可以通过配置多ip的方式来加大自己的建立连接的能力。
  • TCP连接的服务器机:每一个监听的端口虽然理论值很大,但这个数字没有实际意义。最大并发数取决你的内存大小,每一条静止状态的TCP连接大约需要吃3 .3K的内存。

6.Eureka原理,是否是强一致性,eureka集群。宕机了服务还能调用么?Eureka和ZooKeeper对比

6.1 eureka架构

注册中心是分布式开发的核心组件之一,而eureka是spring cloud推荐的注册中心实现。

架构图如下:

6.2 基于集群的Eureka架构图

Eureka server可以集群部署,多个节点之间会通过Replicate(异步方式)进行数据同步,保证数据最终一致性。Eureka Server作为一个开箱即用的服务注册中心,提供的功能包括:服务注册、接收服务心跳、服务剔除、服务下线等。

服务启动后向Eureka注册,Eureka Server会将注册信息向其他Eureka Server进行同步,当服务消费者要调用服务提供者,则向服务注册中心获取服务提供者地址,然后会将服务提供者地址缓存在本地,下次再调用时,则直接从本地缓存中取,完成一次调用。

6.3 宕机了服务还能调用么?

Eureka 挂了,微服务是可以调通的,不过有个前提:provider的地址没变!如果 provider换了一个 IP 地址或者端口,这个时候,consumer 就无法及时感知到这种变化,就会调不通。

6.4 Eureka和ZooKeeper对比

7.Hystrix了解嘛?说说Hystrix的工作原理

Hystrix 工作流程图如下:

  1. 构建命令

Hystrix 提供了两个Command, HystrixCommand 和 HystrixObservableCommand,可以使用这两个对象来包裹待执行的任务。

2 . 执行命令

有四种方式执行command。分别是:

3 . 检查缓存

如果启用了 Hystrix Cache,任务执行前将先判断是否有相同命令执行的缓存。如果有则直接返回缓存的结果;如果没有缓存的结果,但启动了缓存,将缓存本次执行结果以供后续使用。

4. 检查断路器是否打开 断路器(circuit-breaker)和保险丝类似,保险丝在发生危险时将会烧断以保护电路,而断路器可以在达到我们设定的阀值时触发短路(比如请求失败率达到50%),拒绝执行任何请求。

如果断路器被打开,Hystrix 将不会执行命令,直接进入Fallback处理逻辑。

5. 检查线程池/信号量情况 Hystrix 隔离方式有线程池隔离和信号量隔离。当使用Hystrix线程池时,Hystrix 默认为每个依赖服务分配10个线程,当10个线程都繁忙时,将拒绝执行命令。信号量同理。

6. 执行具体的任务 通过HystrixObservableCommand.construct() 或者 HystrixCommand.run() 来运行用户真正的任务。

7. 计算链路健康情况 每次开始执行command、结束执行command以及发生异常等情况时,都会记录执行情况,例如:成功、失败、拒绝以及超时等情况,会定期处理这些数据,再根据设定的条件来判断是否开启断路器。

8. 命令失败时执行 Fallback 逻辑 在命令失败时执行用户指定的 Fallback 逻辑。上图中的断路、线程池拒绝、信号量拒绝、执行执行、执行超时都会进入 Fallback 处理。

9. 返回执行结果 原始结果将以Observable形式返回,在返回给用户之前,会根据调用方式的不同做一些处理。

8.zookeeper一致性保证,zab协议原理,zookeeper属于哪种一致性,强一致性么,还是最终一致性

Zab协议,英文全称是Zookeeper Atomic Broadcast(Zookeeper原子广播)。Zookeeper是通过Zab协议来保证分布式事务的最终一致性

Zab协议是为分布式协调服务Zookeeper专门设计的一种支持崩溃恢复的原子广播协议 ,是Zookeeper保证数据一致性的核心算法。Zab借鉴了Paxos算法,是一种通用的分布式一致性算法。

基于Zab协议,Zookeeper实现了一种主备模型(即Leader和Follower模型)的系统架构来保证集群中各个副本之间数据的一致性。就是指只有一台Leader节点负责处理外部的写事务请求,然后它(Leader)将数据同步到其他Follower节点。

Zookeeper 客户端会随机的链接到 zookeeper 集群中的一个节点,如果是读请求,就直接从当前节点中读取数据;如果是写请求,那么节点就会向Leader提交事务,Leader 接收到事务提交,会广播该事务,只要超过半数节点写入成功,该事务就会被提交。

Zab协议要求每个 Leader 都要经历三个阶段:发现,同步,广播

9 . 聊聊zookeeper选举机制

服务器启动或者服务器运行期间(Leader挂了),都会进入Leader选举,我们来看一下~假设现在ZooKeeper集群有五台服务器,它们myid分别是服务器1、2、3、4、5,如图:

9.1 服务器启动的Leader选举

zookeeper集群初始化阶段,服务器(myid=1-5)依次启动,开始zookeeper选举Leader~

  1. 服务器1(myid=1)启动,当前只有一台服务器,无法完成Leader选举
  2. 服务器2(myid=2)启动,此时两台服务器能够相互通讯,开始进入Leader选举阶段

服务器1和服务器2都将自己作为Leader服务器进行投票,投票的基本元素包括:服务器的myid和ZXID,我们以(myid,ZXID)形式表示。初始阶段,服务器1和服务器2都会投给自己,即服务器1的投票为(1,0),服务器2的投票为(2,0),然后各自将这个投票发给集群中的其他所有机器。

每个服务器都会接受来自其他服务器的投票。同时,服务器会校验投票的有效性,是否本轮投票、是否来自LOOKING状态的服务器。

收到其他服务器的投票,会将被人的投票跟自己的投票PK,PK规则如下:

  • 优先检查ZXID。ZXID比较大的服务器优先作为leader。
  • 如果ZXID相同的话,就比较myid,myid比较大的服务器作为leader。

服务器1的投票是(1,0),它收到投票是(2,0),两者zxid都是0,因为收到的myid=2,大于自己的myid=1,所以它更新自己的投票为(2,0),然后重新将投票发出去。对于服务器2呢,即不再需要更新自己的投票,把上一次的投票信息发出即可。

每次投票后,服务器会统计所有投票,判断是否有过半的机器接受到相同的投票信息。服务器2收到两票,少于3(n/2+1,n为总服务器),所以继续保持LOOKING状态

3 . 服务器3(myid=3)启动,继续进入Leader选举阶段

4 . 服务器4启动,发起一次选举。

5 . 服务器5启动,发起一次选举。

6 . 投票结束,服务器3当选为Leader

9.2 服务器运行期间的Leader选举

zookeeper集群的五台服务器(myid=1-5)正在运行中,突然某个瞬间,Leader服务器3挂了,这时候便开始Leader选举~

1 . 变更状态

Leader 服务器挂了之后,余下的非Observer服务器都会把自己的服务器状态更改为LOOKING,然后开始进入Leader选举流程。

2 . 每个服务器发起投票

每个服务器都把票投给自己,因为是运行期间,所以每台服务器的ZXID可能不相同。假设服务1,2,4,5的zxid分别为333,666,999,888,则分别产生投票(1,333),(2,666),(4,999)和(5,888),然后各自将这个投票发给集群中的其他所有机器。

3 . 接受来自各个服务器的投票

4 . 处理投票

投票规则是跟Zookeeper集群启动期间一致的,优先检查ZXID,大的优先作为Leader,所以显然服务器zxid=999具有优先权。

5 . 统计投票

6 . 改变服务器状态

10. 算法:给定一个字符串s ,请你找出其中不含有重复字符的最长连续子字符串的长度。

可以使用滑动窗口实现,代码如下:


public int lengthOfLongestSubstring2(String s) {
    int n = s.length();
    if (n <= 1) return n;
    int maxLen = 1;

    //左、右指针
    int left = 0, right = 0;

    Set<Character> window = new HashSet<>();
    while (right < n) {
        char rightChar = s.charAt(right);
        while (window.contains(rightChar)) {
            window.remove(s.charAt(left));
            left++;
        }
        //最大长度对比
        maxLen = Math.max(maxLen, right - left + 1);
        window.add(rightChar);
        right++;
    }

    return maxLen;
}

Copyright© 2013-2020

All Rights Reserved 京ICP备2023019179号-8