2023届秋招整理(重点面试题)

425 阅读30分钟

重点八股文(主要是自己不太会的或者有亮点的八股)

本文属于资料整合,希望大家在网上看到类似的文章,多多点赞转发,谢谢!

一、MySQL

1、MySQL有哪些存储引擎,讲讲他们有什么区别(InnoDB,MyISAM,memory)(快手一面)

2、讲讲InnoDB中有哪些锁 表锁、行锁(记录锁、间隙锁、next-key)(快手一面)参考资料

  1. InnoDB 中的行锁的实现依赖于索引,一旦某个加锁操作没有使用到索引,那么该锁就会退化为表锁
  2. 记录锁存在于包括主键索引在内的唯一索引中,锁定单条索引记录。
  3. 间隙锁存在于非唯一索引中,锁定开区间范围内的一段间隔,它是基于临键锁实现的。
  4. 临键锁存在于非唯一索引中,该类型的每条记录的索引上都存在这种锁,它是一种特殊的间隙锁,锁定一段左开右闭的索引区间。

3、什么是 MVCC?MySQL 是怎么实现 MVCC 的呢?(猿辅导一面、百度一面、字节一面、快手一面)参考资料

答:① MVCC 就是多版本并发控制,它维护一个数据的多个版本,是解决高并发下读写冲突的一种手段。有了MVCC后,不再使用单纯的行级锁对数据库中的并发进行控制,而是使用行锁与行的多个版本进行结合,从而大大提高数据库系统的并发性能。

②实现原理:MVCC 的实现依靠三个部分,分别为undo log 日志、隐式字段和 ReadView。其中 undo log 日志形成版本链,不同事务或者相同事务操作一条记录时,会在 undo log 中为这条记录生产版本链表,链表的头部是最新的旧数据记录,链表的底部是最早的旧数据记录,每条记录中都会记录一个事务 id 和回滚指针,也就是隐式字段,最后通过读视图 ReadView 来识别读哪一个版本的数据。(ReadView:是SQL产生了快照读时,生成的一个快照,作为MVCC读取数据的依据,在ReadView中有四个字段来记录不同类型事务的ID,并且这四个字段与undo log中的事务ID有相应的匹配规则,当满足某一项规则时,就会读取该规则对应的版本的历史数据。)

4、介绍一下索引,MySQL的隔离级别,是通过什么实现的?(快手一面、字节三面)参考资料

  • 可重复读的隔离级别下是在事务启动的时候都生成一个MVCC视图
  • 读已提交是在每一个SQL执行的时候生成一个MVCC视图

5、MySQL的锁机制,乐观锁和悲观锁分别在什么场景下使用,乐观锁可以怎样实现?(快手一面)参考资料

  • 乐观锁的实现原理:
      1. 一个事务在读取数据时,将对应的版本号字段读取出来,假设此时的版本号是1。
      1. 另外一个事务也是执行同样的读取操作。当事务一提交时,对版本号执行+1,此时该数据行的版本号就是2。
      1. 第二个事务执行修改操作时,针对业务数据做条件,并默认增加一个版本号作为where条件。此时修改语句中的版本号字段是不满足where条件,该事务执行失败。通过这种方式来达到锁的功能。
  • 悲观锁

6、MySQL事务讲解一下?(快手一面)

7、B+ 树是什么?B+ 树叶子节点内部是什么数据结构?(猿辅导一面)

image.png

8、关系型数据库和非关系型数据库的差别?(猿辅导一面)

  • 关系型数据库 表结构、SQL、读写性能差、一般存储在硬盘
    • 关系型数据库最典型的数据结构是表,由二维表及其之间的联系所组成的一个数据组织。
    • 优点: 1、易于维护:都是使用表结构,格式一致; 2、使用方便:SQL语言通用,可用于复杂查询; 3、复杂操作:支持SQL,可用于一个表以及多个表之间非常复杂的查询。
    • 缺点: 1、读写性能比较差,尤其是海量数据的高效率读写; 2、固定的表结构,灵活度稍欠; 3、高并发读写需求,传统关系型数据库来说,硬盘I/O是一个很大的瓶颈。
  • 非关系型数据库 数据结构化存储、可以是文档或者键值对、速度快、一般不支持事务
    • 是一种数据结构化存储方式,可以是文档或者键值对等。
    • 优点: 1、格式灵活:存储数据的格式可以是key,value形式、文档形式、图片形式等等,文档形式、图片形式等等,使用灵活,应用场景广泛,而关系型数据库则只支持基础类型。 2、速度快:nosql可以使用硬盘或者随机存储器作为载体,而关系型数据库只能使用硬盘; 3、高扩展性; 4、成本低:nosql数据库部署简单,基本都是开源软件。
    • 缺点:  1、不提供sql支持,学习和使用成本较高; 2、无事务处理; 3、数据结构相对复杂,复杂查询方面稍欠。

9、什么默认的隔离级别是可重复读呢?为什么选 RR 做隔离级别?(字节一二面)

10、幻读和可重复读有什么区别?(字节二面)

11、MySQL 索引的的底层?(快手三面)

二、Redis

1、Redis 的底层数据结构了解过吗?数据类型各自底层原理?(字节火山二面、快手一面、字节国际电商一面)

2-1、Redis 的 Hash 的底层数据结构?(猿辅导一面)

答:Redis 存储的数据都会关联一个 RedisObject 对象,RedisObject 对象中有个字段 encoding 也就是编码格式,而 Hash 的底层采用的编码有两种情况:在数据容量较低的时候,默认采用 ZipList 压缩链表来节省内存,在压缩链表的相邻两个 Entry 分别存储哈希的 filed 和 value。当数据容量较大(达到一定的阈值),会存在底层编码的转换,采用字典格式的编码,一个哈希结构关联两个两个HashTable,其中一个用作 rehash 用。

2-2、Redis 的 rehash 能讲一下吗?(猿辅导一面)

答:① rehash 是 Redis 的哈希数据在进行扩容或收缩的时进行的操作。在底层的字典结构里,存在两个 HashTable,其中一个存当前数据,另外一个是空用作reahsh用。② 字典每次在插入键值对的时候都会检查负载因子,当复杂因子达到一定的阈值,就会创建新的哈希表,导致哈希表的 size 和 sizemask 发生变,需要对哈希表中的每一个 key 重新计算索引位置,插入新的哈希表,这个过程就是 rehash。③ 具体的步骤,首先需要计算新的哈希表的大小,决定是要扩容还是缩容;然后申请内存空间,并赋值给字典中的空闲的哈希表;设置字典中的一个标志,将值从 -1 改为 0,标志着 rehash 的开始;然后就是惰性的进行 rehash,rehash并不是一次性完成的,在进行键值对增删改查的时候,判断 rehash 标志,增的话直接计算哈希值插入到新的哈希表上,删的话直接从旧哈希表上删除,改查就是从就哈希表转移到新的哈希表,这就保证了旧哈希表的元素只减不增,直到所有的元素迁移到另外一个表中;最后就是复位操作,rehash 标志置为 -1,交换两个哈希表。

3、如果要自己实现zset,可以用哪些数据结构(hashset+跳表)?( 快手一面)

4、Redis怎么判断缓存失效?是通过一个定时任务还是访问失效了就删除?(快手一面)

5、常用哪些数据库?(快手一面)

6、Redis 持久化介绍?Redis RDB 有没有可能阻塞?阻塞点在哪里?RDB 持久化时内存会翻倍吗?AOF 重写实现原理?(猿辅导一面)

7、Redis 清理过期 Key 的时机?(字节一面)

三、JVM

1、三色标记算法?(猿辅导一面)

四、并发编程

1、Java有哪些锁,synchronized 和 Reentrantlock 的区别?(快手一面)

答题技巧 1) 底层原理;2) 公平锁;3) 可打断;4) 条件变量;

2、Reentrantlock 的实现原理是什么?

3、了解过 AQS 吗?它的实现原理是什么? (字节火山一面)参考资料

答:AQS 就是抽象队列同步器,是 Java 并发包中的一个基本组件,维护了一个 volatile int state 变量,表示共享资源以及一个 FIFO 线程等待队列。这里volatile能够保证多线程下的可见性,当state=1则代表当前对象锁已经被占有,其他线程来加锁时则会失败,加锁失败的线程会被放入一个FIFO的等待队列中,并且会被UNSAFE.park()操作挂起,等待其他获取锁的线程释放锁才能够被唤醒。

4、synchronized什么用,锁存储在什么地方?是非公平锁还是公平锁?(快手一面)

5-1、ThreadLocal 的原理知道吗?(猿辅导一面)参考资料

image.png

  • Thread类中,有个 ThreadLocal.ThreadLocalMap 的成员变量threadLocals,即每个线程都有一个属于自己的ThreadLocalMap
  • ThreadLocalMap内部维护了Entry数组,每个Entry代表一个完整的对象,keyThreadLocal本身,valueThreadLocal的泛型对象值。
  • 并发多线程场景下,每个线程Thread,在往ThreadLocal里设置值的时候,都是往自己的ThreadLocalMap里存,读也是以某个ThreadLocal作为引用,在自己的map里找对应的key,从而可以实现了线程隔离

注意:ThreadLocal 和 synchronized 都是保证线程安全的方式,前者是利用空间换时间,在每个线程的本地,都保存一份共享变量的拷贝副本。多线程对共享变量进行修改时,实际是操作这个变量的副本,从而保证线程安全。后者是利用时间换空间,采用的是互斥锁的方式,使得在同一时刻只有一个线程能够对共享变量进行访问。

5-2、为什么要用 ThreadLocal?ThreadLocal 可能会出现什么问题?(ThreadLocal 为什么会导致内存泄露?ThreadLocal 的 key 为什么要设计成弱引用?)(快手一面、字节一面)

  • ThreadLocal 利用空间换时间,在每个线程的本地,都保存一份共享变量的拷贝副本。多线程对共享变量进行修改时,实际是操作这个变量的副本,从而保证线程安全。(为什么ThreadLocal?)

  • ThreadLocal 对象弱引用导致的内存泄露。 image.png

  • ThreadLocalMap使用ThreadLocal弱引用作为key,当ThreadLocal变量被手动设置为null,即一个ThreadLocal没有外部强引用来引用它,当系统GC时,ThreadLocal一定会被回收。这样的话,ThreadLocalMap中就会出现keynullEntry,就没有办法访问这些keynullEntryvalue,如果当前线程再迟迟不结束的话(比如线程池的核心线程),这些keynullEntryvalue就会一直存在一条强引用链:Thread变量 -> Thread对象 -> ThreaLocalMap -> Entry -> value -> Object 永远无法回收,造成内存泄漏。

  • 当ThreadLocal变量被手动设置为null后的引用链图: image.png

  • 实际上,ThreadLocalMap的设计中已经考虑到这种情况。所以也加上了一些防护措施:即在ThreadLocalget,set,remove方法,都会清除线程ThreadLocalMap里所有keynullvalue

5-3、Entry的Key为什么要设计成弱引用呢?

  • 如果Key使用强引用:当ThreadLocal的对象被回收了,但是ThreadLocalMap还持有ThreadLocal的强引用的话,如果没有手动删除,ThreadLocal就不会被回收,会出现Entry的内存泄漏问题。
  • 如果Key使用弱引用:当ThreadLocal的对象被回收了,因为ThreadLocalMap持有ThreadLocal的弱引用,即使没有手动删除,ThreadLocal也会被回收。value则在下一次ThreadLocalMap调用set,get,remove的时候会被清除。

5-4、为什么不直接用线程id作为ThreadLocalMap的key呢?

  • 使用线程 id 作为ThreadLocalMap的key的话,那么 map 中就只能有一个键值对,是区分不了多个共享变量的。
public class TianLuoThreadLocalTest {

    private static final ThreadLocal<String> threadLocal1 = new ThreadLocal<>();
    private static final ThreadLocal<String> threadLocal2 = new ThreadLocal<>();
 
}

这种场景:一个使用类,有两个共享变量,也就是说用了两个ThreadLocal成员变量的话。如果用线程id作为ThreadLocalMapkey,怎么区分哪个ThreadLocal成员变量呢?因此还是需要使用ThreadLocal作为Key来使用。每个ThreadLocal对象,都可以由threadLocalHashCode属性唯一区分的,每一个ThreadLocal对象都可以由这个对象的名字唯一区分。

6、能详细地说下 synchronized 锁升级的全过程吗?(快手一面)参考资料

image.png 答:synchronized 的锁升级有四种状态,无锁、偏向锁、轻量级锁和重量级锁,随着竞争的激烈锁会进行升级。

  • 首先是无锁到偏向锁,JVM 默认开启偏向锁,但是偏向锁是有延迟的,可以设置一个启动参数来禁止延迟,也可以设置一个参数来禁止偏向锁。偏向锁在对象头里面设置一个线程的 id 表明这个对象偏向于该线程,偏向锁不会主动的释放,只会被动的撤销,或者是重偏向,当某一个线程,比如说 A 线程,获取对象锁的时候,通过 MarkWord 的后三位,也就是101判断对象加的是偏向锁,紧接着会比较 A 线程的 id 和对象头中的线程 id 是否一致。1)一致的话,发生锁重入,不需要 CAS 加锁解锁。2)如果不一致,则说明A线程来竞争锁,,此时 A 线程会判断对象头里存放的 B 线程是否存活,如果 B 线程没有存活,就会发生锁撤销,将对象重偏向为 A 线程。如果存活的话,就会撤销 B 的偏向锁升级为轻量级锁
  • 第二个阶段就是轻量级锁到重量级锁的过程,当一个线程,比如说线程 A 获得轻量级锁之后,会将锁对象的对象头 MarkWord 复制一份到 A 线程的栈帧中的锁记录空间,然后用 CAS 自旋的方式把对象头的 MarkWord 替换成 A 线程存储的锁记录地址。如果在 CAS 替换之前有某个线程,比如说线程 C 已经将锁对象的对象头替换成功,那么 A 线程就会 CAS 失败,A 线程就会自旋一定的次数等待 C 线程释放锁,自旋到一定的次数之后,A 线程就会将锁升级为重量级锁,并进入阻塞队列 EntryList 中等待。

7、轻量级锁的加锁流程,能详细说下吗?里面有个锁膨胀的过程?

8、join 的实现原理?

答:利用保护性暂停模式。

image.png

9、 ConcurrentHashMap 是怎么实现线程安全的?(快手一面)

image.png

  • CHM 的实现在 Java 1.7 和 1.8 中存在很大的不同,1)1.7 中使用 Segment + HashEntry + 分段锁的方式实现线程安全。CHM 内部维护了一个 Segment 数组,每个 Segment 可以看做是一个 HashMap,并且 Segment 继承了 ReentrantLock,本身就是一个锁。而每个 Segment 中维护了一个 HashEntry 数组,HashEntry 就代表 map 的一个 key-value,最后就是将所有的 HashEntry 组成一个链表结构。在进行并发修改的时候,可以针对 Segment 进行上锁,其他的线程就无法操作这个 Segment,可以操作其他的 Segment。CHM 默认使用 16 个 Segment,可同时支持 16 个并发访问。2)在进行 put 操作时候,首先会根据 key 的 hash 值定位一个 segment,如果 segment 没有初始化就会调用 ensureSegment 方法初始化,然后调用 segment 的 put 方法。因为 Segment 继承了 ReentrantLock,本身就是一个锁,执行 put 方法时,segment 会调用 tryLock 尝试获取锁,如果获取成功,那么其他的线程就无法修改这个 Segment,如果获取失败,就会调用 scanAndLockForPut 方法根据key和hash尝试找到这个node,如果不存在,则创建一个node并返回,如果存在则返回null,在查找的过程中会不断地尝试获取锁,在多核CPU环境下,会尝试64次tryLock(),如果64次还没获取到,会直接调用lock(),创建结点这一步一定会获取锁。3)在进行 rehash 的时候,CHM 只针对每个 Segment 中的 HashEntry 进行扩容,也是对 segment 上了锁的。

image.png

  • 在 1.8 中,1)CHM 抛弃了 Segment 改为使用 CAS + synchronized + Node 结点实现线程安全,同时也加入了红黑树来避免链表过长的问题。

扩展:Java 中目前实现的线程安全的Map类有 HashTable、synchronizedMap 和 ConcurrentHashMap 的实现,前两者是全局锁,也就是锁住整个 Map,存在很大的性能问题。

10、两个线程交替增加变量,线程A输出1,3,5,...,99,线程B输出2,4,6,8,...,100?多个方法实现?(字节二面)

五、Java基础知识

1、HashMap用了什么数据结构?为什么引入红黑树?红黑树是什么?什么是红、什么是黑?红黑树和数据库的B树有什么区别?(快手一面)

2、Hashmap1.7和1.8的区别?他们的散列函数一样吗?为什么转化为红黑树的阈值是8?(字节一面)

3、扩容的负载因子为什么是 0.75?

4、HashMap 的 put 流程?

5、数组扩容的时候,容量为什么是 2 的 n 次幂?

6、HashMap 中的哈希值是怎么计算的?

  • 采用的是高低位异或的方式,也就是 hashcode 的高 16 位和 低 16 位进行异或运算并且保留高 16 位,这样做的话就可以使得哈希值更加的散列,减少哈希碰撞。
  • 因为计算桶下标的时候,使用的是 (len- 1) & hash 值,如果 len 比较小的话,哈希值的高 16 位基本没有,都和 0 相与,这样的话高 16 的差异性就没有显现出来。

7、Java 1.8 采用的是尾插法,为什么呢?

  • 在尾插法进行插入的时候,遍历过程中能判断是否达到变成红黑树的条件(尾插法遍历->树华条件)。
  • 1.8变成尾插法不仅仅是解决死循环问题。

六、计算机网络

1、TCP/IP五层协议(ISO七层模型),每一层分别有哪些协议?快手一面、字节一面

image.png

2、用户输入URL到显示的全过程,越详细越好。(快手一面)

image.png 缓存、DNS、TCP 三次握手、HTTP 请求与响应、页面解析、TCP 四次挥手(面试官需要扩展就扩展)

image.png

  • 浏览器查找当前 URL 的 DNS 缓存记录,并比较缓存是否过期;
  • DNS 服务器解析 URL,得到对应的 IP 地址;
  • 根据 IP 地址通过三次握手建立起 TCP 连接;
  • HTTP 发起请求;
  • 服务器处理请求,浏览器接收 HTTP 响应;
  • 浏览器进行页面的渲染;
  • 通过四次挥手关闭 TCP 连接;

3、ARP协议是做什么的?(快手一面)

答:ARP 协议是路由器在和服务器之间通信时,需要将 IP 地址转化为 MAC 地址,实现一个从 IP 地址到物理地址的映射。

4-0、HTTP 的对头阻塞问题?怎么解决呢?

  • “请求 - 应答”模式则加剧了 HTTP 的性能问题,这就是著名的“队头阻塞”(Head- of-line blocking),因为 HTTP 规定报文必须是“一发一收”,这就形成了一个先进先出的“串行”队列。队列里的请求没有轻重缓急的优先级,只有入队的先后顺序,排在最前面的请求被最优先处理。当对头的请求因为某种原因被阻塞时,在后面排队的所有请求也一并被阻塞,会导致客户端迟迟收不到数据。
  • 因为“请求 - 应答”模型不能变,所以“队头阻塞”问题在 HTTP/1.1 里无法解决,只能缓解。用“并发连接”(concurrent connections),也就是同时对一个域名发起多个长连接,用数量来解决质量的问题,最大可支持 6~8 个并发连接。用“域名分片”(domain sharding)技术,还是用数量来解决质量的思路。多开几个域名,比如 shard1.chrono.com、shard2.chrono.com,而这些域名都指向同一台服务器www.chrono.com 的IP地址,这样实际长连接的数量就又上去了。

4-1、HTTP的请求方法有哪些?(快手一面)

4-2、HTTP 中的 POST 和 GET 的区别?(字节一面)

4-3、HTTP 的状态码有哪些?(字节一面)

  • 2××类状态码表示成功,常用的有 200(通用成功状态码,服务器返回了期望的处理结果,如果是非 HEAD 请求,通常在响应头后都会有 body 数据)、204(No Content,含义与“200 OK”基本相同,但响应头后没有 body 数据)、206(Partial Content,是 HTTP 分块下载或断点续传的 基础,在客户端发送“范围请求”、要求获取资源的部分数据时出现,它与 200 一样,也是服务器成功处理了请求,但 body 里的数据不是资源的全部,而是其中的一部分,伴随头字段“Content-Range”,表示响应报文里 body 数据的具体范围,例如“Content-Range: bytes 0-99/2000”,意思是此次获取的是总计 2000 个字节的前 100 个字节);
  • 3××类状态码表示重定向,也就是客户端请求的资源发生了变动,客户端必须用新的 URI 重新发送请求获取资源,常用的有 301(Moved Permanently “永久重定向”,含义是此次请求的资源已经不存在了,需要改用改用新的 URI再次访问)、302(Moved Temporarily,“临时重定向”,意思是请求的资源还在,但需要暂时用另一个 URI 来访问,301 和 302 都会在响应头里使用字段Location指明后续要 跳转的 URI,最终的效果很相似,浏览器都会重定向到新的URI)、304(Not Modified,“缓存重定向”,它用于 If-Modified-Since 等条件请求,表示资源未修改,用于 缓存控制。它不具有通常的跳转含义,但可以理解成“重定向已到缓存的文件”)
  • 4××类状态码表示客户端错误,常用的有 400(Bad Request,通用客户端错误码,表示请求报文有错误)、403(Forbidden,实际上不是客户端的请求出错,而是表示服务器禁止访问资源)、404(Not Found,资源在本服务器上未找到,所以无法提供给客户端)、405(Method Not Allowed:不允许使用某些方法操作资源,例如不允许 POST 只能 GET)、408(Request Timeout:请求超时,服务器等待了过长的时间)
  • 5××类状态码表示服务器错误,常用的有 500(通用服务端错误码)、501(Not Implemented,表示客户端请求的功能还不支持)、502(Bad Gateway,通常是服务器作为网关或者代理时返回的错误码,表示服务器自身工作正常,访问后端服务器时发生了错误,但具体的错误原因也是不知道的。)、503(Service Unavailable,表示服务器当前很忙,暂时无法响应服务)

4-4、长连接和短连接?(字节一二面)

  • 早期的 HTTP 协议使用短连接,收到响应后就立即关闭连接,效率很低;
  • HTTP/1.1 默认启用长连接,在一个连接上收发多个请求响应,提高了传输效率;
  • 服务器会发送“Connection: keep-alive”字段表示启用了长连接;
  • 报文头里如果有“Connection: close”就意味着长连接即将关闭;
  • 过多的长连接会占用服务器资源,所以服务器会用一些策略有选择地关闭长连接;
  • “队头阻塞”问题会导致性能下降,可以用“并发连接”和“域名分片”技术缓解

4-5、断点续传?(字节一面)

5、TCP和UDP各自的特点区别?(猿辅导一面)

  • 1)连接; 2)数据类型; 3)可靠; 4)首部大小;
  • TCP 是面向连接的,UDP 是无连接的,发送数据之前不需要建立连接。
  • TCP 是面向字节流的,UDP 是面向报文的,在网络出现拥塞的情况下,发送的速率不变但是会丢包。
  • TCP 提供可靠的传输服务,也就是说 TCP 传输的数据无差错,不丢失,不重复;而 UDP 尽最大努力交付,不保证可靠交付。
  • TCP 的首部最少是 20 个字节,适合大数据量的交换;UDP 的首部只有 8 个字节,适合少数据的交换。

6、四次挥手?为什么是四次挥手,而不是三次挥手?没有第四次挥手会怎么样?(猿辅导二面、字节一面)

答:关闭连接时,服务器收到对方的FIN报文时,仅仅表示客户端不再发送数据了但是还能接收数据,而服务端也未必全部数据都发送给对方了,所以服务端可以立即关闭,也可以发送一些数据给对方后,再发送FIN报文给对方来表示同意现在关闭连接。 因此,服务端 ACK和FIN 一般都会分开发送,从而导致多了一次。

7、TCP 三次握手?为什么是三次?两次可以吗?四次呢?(猿辅导二面)

8、Ping 了解吗?一次 Ping 的全过程流程能描述一下吗?

答:Ping (Packet InterNet Groper) 即是分组网间探测,是 ICMP 报文的一个重要应用,是应用层直接使用网络层 ICMP 的一个例子,没有经过传输层的 TCP、UDP。主要用来测试两个主机的连通性。

原理:1) 向目的主机发送多个ICMP回送请求报文; 2) 根据 目的主机返回的ICMP回送回答报文中的时间戳,从而计算出往返时间; 3) 1. 最终显示的结果:发送到目的主机的IP地址、发送 & 收到 & 丢失的分组数、往返时间的最小、最大 & 平均值。

过程:

image.png

9、路由器和交换机有啥区别?

image.png

10、四次挥手的过程中,客户端在收到服务端的 ACK 之后,为什么没有立即关闭连接,而是等待了两个 MSL (最长报文段寿命)?(字节一面)

防止第四次传输数据包发生丢失的情况

答:1)客户端的最后一个ACK报文在传输的时候丢失,服务器并没有接收到这个报文。这个候时候服务器就会超时重传这个FIN消息,然后客户端就会重新返回最后一个ACK报文,等待两个时间周期,完成关闭。2)如果不等待这两个时间周期,服务器重传的那条消息就不会收到。服务器就因为接收不到客户端的信息而无法正常关闭。

11-1、如果已经建立了连接,但是客户端突然出现故障了怎么办?(小米一面)

答:TCP 保活计时器,每次客户端请求服务器会重置计时器,当2小时之内,如果服务端没收到客户端任何数据时,会每隔75s向客户端发一个探测报文,若接连发送10个,客户端都没有反应,则认为客户端故障,关闭连接。

11-2、TCP 和 HTTP 长连接的区别?(字节二面)

11-3、TCP 保活机制是谁实现的?(字节二面)

12、什么是SYN洪泛攻击?

  • SYN洪泛攻击就是利用TCP协议的特性(三次握手)。

  • 攻击者发送TCP的 SYN,SYN是TCP三次握手中第一个数据包,而当服务器返回ACK后,该攻击者就不对其进行再确认,那这个TCP连接就处于挂起状态,也就是半连接状态,服务器收不到再确认的话,还会重复发送ACK给攻击者。

  • 这样更加会浪费服务器资源。攻击者就对服务器发送大量的这种TCP连接,由于每一个连接都无法完成三次握手,所以就在服务器上,这些TCP连接会因为挂起状态而消耗CPU和内存,最后服务器可能死机。如果攻击者伪造了成千上万的握手报文,携带了1K+ 字节的数据,而接收方会开辟大量的缓存来容纳这些巨大数据,内存会很容易耗尽,从而拒绝服务。

13、序号(ISN)为什么要随机?三次握手的第一次可以携带数据吗?为何?(字节一面)

答:① 增加安全性,为了避免被第三方猜测到,从而被第三方伪造的RST报文Reset。② 不可以,三次握手还没有完成。而且这样会放大SYN FLOOD(SYN洪泛)攻击。

14-1、TCP如何实现可靠传输?(快手一面)

image.png 答:主要通过以下四种方式实现可靠传输机制。

  • 校验和,伪首部是为了增加TCP校验和的检错能力,通过伪首部的目的IP地址来检查TCP报文是否收错了、通过伪首部的传输层协议号来检查传输层协议是否选对了。需要注意的是,伪首部实际上是不存在的,只是用来验证TCP报文是否出错。
  • 序号,TCP 是面向字节流的,比如第一个字节就是序号1,第二个字节就是序号2。TCP 首部,有一个序号字段,这个指的是一个报文段第一个字节的序号。有了序号,就能保证数据是有序的传入应用层。
  • 确认,发送方在收到接收方的确认包之后,才继续发送剩下的数据。
  • 超时重传,TCP 的发送方在规定的时间内没有收到确认就要重传已发送的报文段(超时重传)。重传时间是动态改变的,依据的是RTTS(加权平均往返时间)。
  • 流量控制
  • 拥塞控制

14-2、TCP 的接收方怎么确认收到的,收到的顺序是乱的怎么办?会丢弃吗?(快手一面)

15、TCP 的流量控制?

  • TCP 中采用滑动窗口来进行传输控制,滑动窗口的大小意味着接收方还有多大的缓冲区可以用于接收数据。发送方可以通过滑动窗口的大小来确定应该发送多少字节的数据。
  • 当滑动窗口为 时,发送方一般不能再发送数据报,但有两种情况除外,一种情况是可以发送紧急数据,例如,允许用户终止在远端机上的运行进程。另一种情况是发送方可以发送一个 1 字节的数据报来通知接收方重新声明它希望接收的下一字节及发送方的滑动窗口大小。

16、TCP 的拥塞控制的几种实现方式?(字节一面)

答:

17、为什么有了 MAC 地址,还需要 IP 地址呢?

18-1、讲讲 TCP/IP 四层模型?(快手一面)

18-2、能详细地说下每一层分别有哪些协议,讲下是做什么的?(快手一面)

18-3、局域网是什么协议?(快手一面)

19-0、你能介绍一下 HTTP 协议吗?(字节一面)

HTTP协议是一个无状态的协议,本次请求和之前的请求无关。它是一种报文交换格式的约定,规定了响应码、请求头、请求方法等内容,比如说常用的GET、POST、DELETE、PUT请求等,为了解决HTTP请求的无状态,我们通常会使用服务端的会话管理机制或者COOKIE来追踪客户端状态,对于响应码,有多种响应码表示不同的响应状态,比如正常响应是200,302重定向、404资源不存在、500服务端错误等。HTTPS是HTTP的安全版本,具体安全机制的实现方案不太了解(非计算机专业),但是了解其安全加密方案是基于公私钥的加密方案。

19-1、说一下 HTTP1.0、1.1、2.0?(快手一面)

19-2、HTTP2.0 是如何保证有序的?是如何通信的?(快手一面)

19-3、HTTPS 有了解过吗?说下与HTTP的区别?并说下大致地加密过程(SSL/TLS具体的加密过程、总共需要加密几次)?(快手一面、字节一面)

19-4、HTTPS 中的密钥交换流程?(字节二面)

19-5、非对称加密是否是安全的?(字节一面)

非对称加密是安全的,一般不用非对称加密传输信息的原因是因为非对称加密相比对称加密效率低,楼主的说法不对,公钥谁都可以从证书获得,私钥加密内容我们叫它签名,公钥解密可以用来验证身份,之所以有安全问题是因为中间人攻击,替换掉了证书,换了一个假的证书给对方,这时候再利用公钥加密对称密钥,用的是中间人假的证书的公钥,所以中间人就知道了对方的加密信息,解决方法就是设置ca(证书)服务器,专门来管理证书,验证或者销毁证书。

七、操作系统

1、什么是 IO 多路复用?说下 epoll 的实现原理?(快手一面)

2、进程间的通信有哪几种?(字节一面)

3、操作系统的中断了解吗?(字节基础架构一面)

4、操作系统的并发了解吗?(字节基础架构一面)

5、操作系统的临界区了解吗?(字节基础架构一面)

6、虚拟内存?(字节一面)

7、分页和分段?(字节一面)

八、Linux

九、Netty

十、Dubbo

1、简单介绍一下Dubbo的原理?(快手一面)

2、Dubbo用到的传输协议、序列化协议?(快手一面)

3、如果自己手写一个RPC的话,可能用到哪些类?(快手一面)

十一、Spring 全家桶

1、Spring的循环依赖问题。(字节一面)

十二、分布式

十三、数据结构与算法

1、常用排序算法及时间复杂度?

2、八大排序的复杂度,稳定性,适用场景?(快手一面)

十四、设计模式

1、你用过的设计模式有哪些?(字节一面)