【字节】番茄小说一面面经|讲解|0508

今天挑选一篇字节番茄小说一面,给大家做讲解分析,参考回答和学习资料指引,期望对大家有所帮助~

自产《大厂后端Top100面试题》对本篇面经题目覆盖率:9/12

自产《大厂后端Top200面试题》对本篇面经题目覆盖率:11/12

alt

感谢这位同学的分享,预祝Offer多多~~~ 原贴链接

讲解开始~~~~~

1. static关键字的使用

解析

所属专项:Java|Java基础

专项考察占比:

Java】面试中考察Java的比率:大厂:17%腾讯:6%阿里:32%

Java-基础】面试考察Java时,问Java基础问题的比率:11%

参考口述回答

首先,static可以修饰类的成员变量和方法。当一个成员变量或方法被static修饰时,它们就属于类本身,而不是类的某个实例。这意味着,我们不需要创建类的对象就可以访问这些静态成员。

例如,如果我们有一个static变量,它会在类被加载到JVM时被初始化,并且只会被初始化一次。这个变量将被类的所有实例共享。同样,static方法也属于类本身,而不是类的实例。它们通常用于执行与类本身相关的操作,而不是与类的特定实例相关的操作。

此外,static还可以用于修饰代码块。静态代码块在类被加载时执行,而且只执行一次。这常用于进行一些初始化操作。

在Java中,static还有一个常见的用途是定义静态内部类。静态内部类不依赖于外部类的实例,它可以包含静态和非静态成员。与非静态内部类相比,静态内部类可以创建静态成员,而且不需要外部类的实例就可以被实例化。

推荐学习资料

《JavaGuide》| Java关键字总结:static 关键字

2. 多态的用法,多态的实现原理

解析

属于次高频考题:属于自产《大厂后端Top101-200面试题》

所属专项:Java|Java基础

专项考察占比:

Java】面试中考察Java的比率:大厂:17%腾讯:6%阿里:32%

Java-基础】面试考察Java时,问Java基础问题的比率:11%

参考口述回答

一、多态的用法

多态在编程中的用法主要体现在以下几个方面:

  1. 父类引用指向子类对象: 我们可以声明一个父类类型的变量,并将其指向子类的对象。这样做的好处是,我们可以使用统一的接口来处理不同类型的子类对象,提高了代码的复用性和可扩展性。
  2. 方法重写(Override)与重载(Overload) : 子类可以重写父类的方法,以实现自己的业务逻辑。同时,一个类中可以定义多个方法名相同但参数不同的方法,即方法的重载。多态允许我们在运行时根据对象的实际类型调用相应的方法。
  3. 接口回调: 多态也常用于实现接口回调。通过定义接口,并让不同的类实现该接口,我们可以实现灵活的方法调用。在运行时,根据对象的实际类型来调用相应的方法实现。

二、多态在JVM层面的实现原理

在JVM层面,多态的实现主要依赖于动态方法分派(Dynamic Method Dispatch)机制,具体包括以下步骤:

  1. 加载类信息: JVM在加载类时会解析类的字节码,并建立方法表(Method Table)和虚方法表(Virtual Method Table, VTable)。
  2. 动态绑定: 当使用父类引用调用方法时,JVM会查找虚方法表来确定实际要调用的方法。这个过程是在运行时动态确定的,因此称为动态绑定。
  3. 执行方法: JVM根据虚方法表的指引,跳转到实际子类的方法实现并执行。

推荐学习资料

《CSDN 博客》:Java 中多态的实现原理

3. HashTable与HashMap对比

解析

属于次高频考题:自产《大厂后端Top101-200面试题》

所属专项:Java|Java集合框架

专项考察占比:

Java】面试中考察Java的比率:大厂:17%腾讯:6%阿里:32%

Java-集合框架】面试考察Java时,问Java集合框架问题的比率:9%

增加ConcurrentHashMap一起对比回答

参考口述回答

一、线程安全性

  1. HashMap:它是非线程安全的。在多线程环境下,如果多个线程同时操作HashMap,可能会导致数据的不一致。
  2. HashTable:它是线程安全的。HashTable内部的方法基本都经过synchronized修饰,因此可以在多线程环境下安全地使用。但正因为其线程安全性,效率上会比HashMap稍低。
  3. ConcurrentHashMap:它也是线程安全的。与HashTable不同的是,ConcurrentHashMap JDK1.7采用了分段锁机制,将整个哈希表分成多个段,每个段上有一个独立的锁。这种设计使得多个线程可以同时访问不同的段,从而提高了并发性能。JDK 1.8开始弃用分段锁,缩小加锁粒,进一步优化了ConcurrentHashMap的并发性能。

二、对Null key和Null value的支持

  1. HashMap:在HashMap中,null可以作为键,且这样的键只有一个。同时,HashMap也允许有一个或多个键所对应的值为null。
  2. HashTable:在HashTable中,如果put进的键值对中有任何一个为null,都会直接抛出NullPointerException。
  3. ConcurrentHashMap:与HashTable相似,ConcurrentHashMap也不允许键或值为null。

三、初始容量大小和每次扩充容量大小

  1. HashMap:默认的初始化大小为16,之后每次扩充时,容量会变为原来的2倍。如果创建时给定了容量初始值,HashMap会将其扩充为2的幂次方大小。
  2. HashTable:默认的初始大小为11,之后每次扩充时,容量会变为原来的2n+1倍。如果创建时给定了容量初始值,HashTable会直接使用这个大小。
  3. ConcurrentHashMap:其初始容量和扩充策略与HashMap类似,但具体实现可能因版本和配置而异。

四、底层数据结构

  1. HashMap:在JDK1.8以后,HashMap在解决哈希冲突时采用了链表+红黑树的结构。当链表长度大于阈值(默认为8)时,会将链表转化为红黑树,以减少搜索时间。
  2. HashTable:没有采用链表+红黑树的结构来解决哈希冲突。它通常使用链表来处理冲突。
  3. ConcurrentHashMap:其底层数据结构与HashMap类似,但为了适应并发访问的需求,进行了相应的优化和调整。

推荐学习资料

《JavaGuide》| Java基础面试题:

HashMap 和 Hashtable 的区别

ConcurrentHashMap 和 Hashtable 的区别

4. String,StringBuilder,StringBuffer的区别?

解析

属于高频考题:自产《大厂后端Top100面试题|第19题》

所属专项:Java|Java基础

专项考察占比:

Java】面试中考察Java的比率:大厂:17%腾讯:6%阿里:32%

Java-基础】面试考察Java时,问Java基础问题的比率:11%

参考口述回答

一、加号(+)拼接

  1. 性能:当使用加号进行字符串拼接时,每次拼接都会创建一个新的String对象,这会导致大量的中间对象创建和内存分配。如果拼接操作频繁或字符串较大,这种方式可能会带来较大的性能开销。
  2. 线程安全:加号拼接本身是线程安全的,因为它不涉及共享状态或并发操作。
  3. 使用场景:加号拼接适用于简单的、少量的字符串拼接操作,或者在不需要考虑性能的场合。

二、StringBuffer拼接

  1. 性能:StringBuffer在进行字符串拼接时,不会像加号那样每次都创建新的对象。它内部维护了一个可变的字符序列,通过append()方法可以将新的字符串添加到已有字符串的末尾,从而避免了频繁的内存分配。因此,在处理大量或频繁的字符串拼接时,StringBuffer的性能通常优于加号拼接。
  2. 线程安全:StringBuffer是线程安全的。它内部使用了同步机制来确保在多线程环境下数据的一致性。这意味着在多线程应用中,你可以安全地使用StringBuffer进行字符串拼接,而不用担心数据混乱或不一致的问题。
  3. 使用场景:当你需要在多线程环境下进行字符串拼接,或者需要频繁地进行大量的字符串拼接操作时,StringBuffer是一个很好的选择。

三、StringBuilder拼接

  1. 性能:StringBuilder与StringBuffer类似,都维护了一个可变的字符序列来进行字符串拼接。然而,与StringBuffer不同的是,StringBuilder没有提供同步机制,因此它在单线程环境下的性能更高。实际上,在处理大量或频繁的字符串拼接时,StringBuilder的性能通常是最优的。
  2. 线程安全:由于StringBuilder没有提供同步机制,所以它不是线程安全的。在多线程环境下使用StringBuilder进行字符串拼接可能会导致数据混乱或不一致的问题。
  3. 使用场景:当你只需要在单线程环境下进行字符串拼接,并且追求最高的性能时,可以选择使用StringBuilder。特别是在处理大量的、频繁的字符串拼接操作时,如日志记录、文本处理等场景,StringBuilder是最佳的选择。

推荐学习资料

《JavaGuide》| Java基础面试题:### String、StringBuffer、StringBuilder 的区别?

5. Linux中的IO多路复用

解析

属于高频考题之一:自产《大厂后端Top100面试题|第59题》

所属专项:操作系统|网络系统

专项考察占比:

操作系统】面试中考察操作系统的比率:大厂:12%腾讯:18%阿里:8%

操作系统-网络系统】面试考察操作系统时,问“网络系统”相关问题的比率:22%

参考口述回答

  1. IO多路复用?

IO多路复用是一种高效的IO处理方式,它允许单个进程或线程同时监视多个文件描述符,如网络连接或文件句柄。当这些描述符中的任何一个就绪时,比如有数据可读或可写,多路复用机制就能够通知应用程序进行相应的读写操作。这种机制的核心优势在于,它可以在不增加额外线程或进程的情况下,处理大量的并发连接,从而显著地提高系统的并发性和响应能力。

常见的IO多路复用技术包括select、poll和epoll等。这些技术各有特点,但核心思想都是通过一个线程来管理多个连接,减少系统资源的消耗,并提高程序运行的效率。

  1. select,poll,epoll的区别

select是最早的一种I/O多路复用技术。它使用一个fd_set数据结构来表示所有被监视的文件描述符。然而,select有几个明显的缺点。首先,它监视的文件描述符数量有限,默认上限是1024。其次,每次调用select时,都需要将fd_set从用户态拷贝到内核态,并且在内核中需要遍历所有被监视的文件描述符来检查是否有就绪的,这个开销在文件描述符数量很多时会变得非常大。最后,select返回后,还需要再次遍历fd_set来找出哪些文件描述符是就绪的,这进一步增加了处理开销。

poll则是select的一种改进方案。它使用一个pollfd结构来表示被监视的文件描述符及其事件。与select相比,poll没有文件描述符数量的限制,因为它基于链表来存储。然而,poll仍然需要在每次调用时从用户态拷贝所有的pollfd结构到内核态,并在内核中遍历检查每个文件描述符的状态。因此,当文件描述符数量很多时,poll的性能也会下降。

epoll则是Linux特有的I/O多路复用技术,它在很多方面都优于select和poll。首先,epoll只在初始时完成一次文件描述符的注册,避免了每次调用时的拷贝开销。其次,epoll采用回调函数的方式,只有当一个或多个文件描述符就绪时,才会调用回调函数并通知用户空间,这使得epoll在处理大量文件描述符时仍然能保持高效。最后,epoll返回时已经明确指出了哪些文件描述符是就绪的,因此无需再像select和poll那样进行额外的遍历操作。

推荐学习资料

《小林Coding》|图解系统:IO多路复用

6. MySQL中的事务

解析

属于高频考题:自产《大厂后端Top100面试题|第8题》

所属专项:MySQL|事务

专项考察占比:

MySQL】面试中考察操作系统的比率:大厂:18%腾讯:13%阿里:17%

MySQL-事务】面试考察MySQL时,问“事务”相关问题的比率:18%

参考口述回答

  1. 事务特性ACID介绍

事务的ACID特性是数据库管理系统在处理事务时所必须遵循的四个基本原则,它们分别是原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability)。下面我将逐一介绍这四个特性及其在实现层面是如何得到保证的。

首先是原子性。原子性意味着事务是一个不可分割的工作单位,事务中的操作要么全部完成,要么全部不完成。实现原子性的关键在于事务管理机制,它确保了一组相关的数据库操作要么全部执行成功,要么在发生错误时全部回滚到事务开始前的状态。这主要通过数据库管理系统的日志机制和回滚技术来实现。在事务执行过程中,系统会记录所有的操作日志,一旦发生错误,系统可以利用这些日志来回滚到事务开始前的状态,从而保证原子性。

接下来是一致性。一致性要求事务执行前后,数据库的状态必须保持一致。这意味着,如果事务在执行过程中因为某些原因而中断,数据库系统必须能够恢复到事务开始前的状态,以保持数据的一致性。数据库管理系统通过一系列完整性约束、触发器和级联更新等操作来维护数据的一致性。同时,在事务结束时,系统会对数据库的状态进行检查,以确保所有的约束条件都得到满足,如果有不一致的情况,事务会被回滚。

再来说说隔离性。隔离性是指多个并发事务之间不会互相影响。为了实现隔离性,数据库管理系统采用了锁机制来控制对数据的并发访问。通过锁定正在被访问的数据,可以确保在事务完成之前,其他事务无法修改这些数据。此外,数据库还提供了不同的隔离级别,如读未提交、读已提交、可重复读和串行化等,以满足不同应用场景下的隔离需求。

最后是持久性。持久性意味着一旦事务提交,其对数据库中数据的修改将是永久性的。为了实现持久性,数据库管理系统采用了写前日志(Write-Ahead Logging)技术。在事务提交前,系统会先将事务的修改记录在日志中,并确保这些日志已经持久化到磁盘上。这样,即使数据库系统发生故障或重启,已经提交的事务的修改也不会丢失,因为系统可以根据日志来恢复数据到一致的状态。

  1. ACID四种特性如何得到保证的的?
  • 持久性是通过 redo log 来保证的;
  • 原子性是通过 undo log 来保证的;
  • 隔离性是通过 MVCC(多版本并发控制) 或锁机制来保证的;
  • 一致性则是通过持久性+原子性+隔离性来保证;

推荐学习资料

《掘金专栏》|全解MySQL数据库:# 事务的ACID原则

《小林Coding》|图解MySQL:# 事务有哪些特性?

7. 事务隔离级别,哪个是默认的,特点?

解析

属于高频考题:自产《大厂后端Top100面试题|第9题》

所属专项:MySQL|事务

专项考察占比:

MySQL】面试中考察MySQL的比率:大厂:18%腾讯:13%阿里:17%

MySQL-事务】面试考察MySQL时,问“事务”相关问题的比率:18%

参考口述回答

  1. 读未提交(Read Uncommitted)

    1. 这是最低的隔离级别。在此级别下,一个事务可以读取另一个事务尚未提交的数据。
    2. 这种级别的问题在于,它可能导致“脏读”(Dirty Read)问题,即读取到未经确认的临时数据。
    3. 由于这个原因,这个隔离级别在实际应用中很少使用。
  2. 读已提交(Read Committed)

    1. 在这个级别,每个查询都会在事务执行时获取当前可见的数据。
    2. 它可以避免脏读,因为只能读取已提交的数据。
    3. 但这种级别可能导致“不可重复读”(Non-repeatable Read)问题,即同一个查询在多次执行时可能读取到不同的数据,因为其他事务可能在此期间修改了数据。
  3. 可重复读(Repeatable Read)

    1. 这是MySQL的默认事务隔离级别
    2. 在这个级别下,事务在开始时“快照”当前状态,因此它看到的是一致的数据视图,在事务执行期间不会改变。
    3. 这可以避免脏读和不可重复读问题。
    4. 但这种级别可能导致“幻读”(Phantom Read)问题,即当事务读取某个范围内的记录时,另一个并发事务插入了一些新的记录,导致前一个事务在再次读取该范围的记录时,会看到一些“幻影”记录。
    5. InnoDB通过多版本并发控制(MVCC)和间隙锁来解决这个问题。
  4. 串行化(Serializable)

    1. 这是最高的隔离级别。
    2. 在这个级别下,事务是完全串行执行的,避免了脏读、不可重复读和幻读问题。
    3. 它通过在事务执行期间对数据加锁来实现,这可以防止其他事务对数据进行修改和插入。
    4. 但这种严格的控制可能会导致大量的锁竞争和性能开销。

推荐学习资料

《掘金专栏》|全解MySQL数据库:#MySQL事务的隔离机制

《小林Coding》|图解MySQL:# 事务的隔离级别有哪些?

8. MySQL中一条SQL的执行流程

解析

属于高频考题:自产《大厂后端Top100面试题|第2题》

所属专项:MySQL|基础

专项考察占比:

MySQL】面试中考察MySQL的比率:大厂:18%腾讯:13%阿里:17%

MySQL-基础】面试考察MySQL时,问“基础”相关问题的比率:10%

参考口述回答:

在这里,我主要对比两种最常用的存储引擎:InnoDB和MyISAM,同时简要提及其他几种引擎的特点。

1. InnoDB存储引擎:

  • 事务支持:InnoDB是事务型数据库的首选引擎,它提供了提交、回滚和崩溃恢复能力来保护用户数据,确保数据的完整性。它遵循ACID原则,即原子性、一致性、隔离性和持久性。
  • 行级锁定:InnoDB支持行级锁定,这意味着在多个用户并发访问数据库时,它只会锁定被访问的行,而不是整个表。这大大提高了数据库的并发性能。
  • 外键约束:InnoDB还支持外键约束,可以确保数据的参照完整性。
  • 聚簇索引:InnoDB使用聚簇索引,即数据和主键索引存储在一起,这有助于提高某些查询的效率。

2. MyISAM存储引擎:

  • 表级锁定:MyISAM不支持事务和行级锁定,只支持表级锁。这意味着在读写操作时,会对整个表进行锁定,可能导致并发性能较差。
  • 全文索引:MyISAM支持全文索引,适合进行文本搜索。
  • 高速读取:MyISAM通常用于只读或大量读取的应用场景,如Web站点的归档数据或只读的数据仓库。其查询速度相对较快。
  • 压缩存储:MyISAM还支持压缩表,可以节省存储空间。

3. 其他存储引擎:

  • Memory:将所有数据保存在RAM中,提供极快的访问速度,适用于需要快速查找引用的场景。但服务器关闭时数据会丢失。

总的来说,选择哪种存储引擎取决于具体的应用需求和性能要求。例如,对于需要高并发写入和数据完整性的应用,InnoDB是更好的选择;而对于只读或文本搜索为主的应用,MyISAM可能更合适。在实际应用中,我们需要根据具体情况进行权衡和选择。

推荐学习资料:

《掘金专栏》|全解MySQL数据库:# (十三)MySQL引擎篇:半道出家的InnoDB为何能替换官方的MyISAM?

9. https与http的区别,加密的实现?

解析

属于高频考题:自产《大厂后端Top100面试题|第89题和第96题》

所属专项:计算机网络|HTTP

专项考察占比:

计算机网络】面试中考察计算机网络的比率:大厂:11%腾讯:17%阿里:7%

计算机网络-HTTP】面试考察计网时问HTTP问题的比率:35%

参考口述回答:

  1. http和https的区别?

首先,安全性是这两者之间最显著的区别。HTTP是超文本传输协议,它是以明文方式传输数据的,这意味着在数据传输过程中,如果遭到拦截,信息将以明文形式暴露,存在安全风险。而HTTPS则是HTTP的安全版,它在HTTP的基础上加入了SSL/TLS协议,可以对数据进行加密传输和身份认证,从而保证了数据传输的安全性。

其次,从端口号上来看,HTTP和HTTPS使用的端口也不同。HTTP默认使用80端口,而HTTPS则使用443端口。

再者,HTTPS将加密,解密,验证,解压缩等流程都交给了SSL/TLS来处理,因此相对于HTTP来说,HTTPS在处理速度上会有所降低,但由于目前硬件性能的大幅提升,这种影响在实际使用中几乎可以忽略不计。

最后,HTTPS需要向认证机构(CA)申请证书,一般需要一定的费用,而HTTP则不需要。

在当今这个信息安全至关重要的时代,HTTPS的重要性不言而喻,它能为我们的数据传输提供强有力的安全保障。虽然HTTPS在处理速度和费用方面相较HTTP有所不足,但这些都可以看作是为了保障信息安全而做出的必要牺牲。

2.加密实现?

HTTPS确实采用了对称加密和非对称加密结合的方式。在HTTPS连接建立的过程中,非对称加密主要用于密钥交换和安全认证,而对称加密则用于实际的数据传输。

HTTPS之所以在密钥交换阶段使用非对称加密,是因为非对称加密具有很高的安全性。非对称加密算法使用一对密钥,即公钥和私钥。公钥可以公开,任何人都可以用公钥对数据进行加密,但只有持有相应私钥的人才能解密。这种特性使得非对称加密在密钥交换过程中非常有用,因为它可以确保只有服务器能解密客户端发送的数据,从而保证了通信的安全性。

然而,非对称加密的计算复杂度较高,加密和解密速度相对较慢。因此,在大量的数据传输中,如果一直使用非对称加密,会导致性能下降,影响用户体验。

为了提高通信效率,HTTPS在密钥交换完成后,会生成一个对称密钥。这个对称密钥将用于后续的数据传输加密。对称加密的特点是加密和解密使用相同的密钥,其加密速度快,适合用于大量数据的加密传输。

所以,HTTPS在密钥交换阶段使用非对称加密来确保安全性,而在后续的数据传输阶段则切换到对称加密以提高效率。这种结合使用的方式既保证了通信的安全性,又兼顾了性能需求。

推荐学习资料:

《小林Coding》|图解网络:HTTP 与 HTTPS 有哪些区别?

《小林Coding》|图解网络:HTTPS 混合加密

10. 键入url到页面显示的流程

解析

属于高频考题:自产《大厂后端Top100面试题|第78题》

所属专项:计算机网络|基础

专项考察占比:

计算机网络】面试中考察计算机网络的比率:大厂:11%腾讯:17%阿里:7%

计算机网络-基础】面试考察计网时问基础问题的比率:6%

参考口述回答:

首先,我们输入的是网址,也就是URL,这是HTTP协议的使用入口。浏览器会首先检查是否有缓存,如果没有,就会通过HTTP协议向服务器发起请求。但在此之前,需要通过DNS协议将网址解析为服务器对应的IP地址。

DNS协议工作在应用层,浏览器会向DNS服务器发送查询请求,获取网址对应的IP地址。一旦获取到IP地址,就可以准备建立与服务器的连接了。

接下来是TCP协议的工作。TCP位于传输层,它负责建立和管理连接,确保数据的可靠传输。浏览器会与服务器的指定IP地址和端口号进行TCP三次握手,建立连接。

在TCP连接建立后,浏览器就可以通过HTTP协议发送具体的网页请求了。HTTP请求会被封装在TCP数据包中发送出去。

接下来是IP协议和MAC协议的工作。IP协议在网络层,它负责为数据包提供路由信息,即数据包应该如何从源地址传输到目的地址。每个数据包都会包含源IP地址和目标IP地址。而MAC协议则工作在数据链路层,它负责处理数据包在局域网内的传输。每个网络设备都有一个唯一的MAC地址,MAC协议确保数据包能够准确到达局域网内的目标设备。

当数据包从客户端发送到网络中时,首先会经过交换机。交换机根据数据包的MAC地址来决定数据包应该转发到哪个端口。然后数据包会经过路由器,路由器会根据IP地址来决定数据包应该转发到哪个网络。这样,数据包就能够逐级跳转,最终到达目标服务器。

服务器收到数据包后,会进行拆包处理。首先拆除的是MAC层的数据包,然后是IP层的数据包,接着是TCP层的数据包,最后是HTTP层的数据。服务器会根据HTTP请求的内容来准备响应数据,并将响应数据按照相反的顺序封装成数据包发送回客户端。

客户端收到服务器的响应数据包后,也会进行类似的拆包处理,最终提取出HTTP响应的内容。浏览器会根据HTTP响应的内容来渲染网页,展示给用户。

这就是整个从浏览器键入网址到网页显示的过程中所涉及的网络层协议和主要过程。

推荐学习资料:

《小林Coding》|图解网络:# 键入网址到网页显示,期间发生了什么?

11. TCP断开连接过程

解析

属于高频考题:自产《大厂后端Top100面试题|第85题》

所属专项:计算机网络|TCP&UDP

专项考察占比:

计算机网络】面试中考察计算机网络的比率:大厂:11%腾讯:17%阿里:7%

计算机网络-TCP&UDP】面试考察计网时问TCP&UDP问题的比率:42%

参考口述回答(简单版)

首先,当客户端决定关闭连接时,它会向服务器发送一个FIN报文,这是第一次挥手,表示客户端没有数据要发送了。

接着,服务器收到FIN报文后,会发送一个ACK报文给客户端,确认关闭请求,这是第二次挥手。此时,连接进入半关闭状态,服务器还可以继续发送数据。

然后,当服务器也准备关闭连接时,它会发送一个FIN报文给客户端,告知自己也没有数据要发送了,这是第三次挥手。

最后,客户端收到服务器的FIN报文后,会发送一个ACK报文进行确认,这是第四次挥手。此后,客户端会等待一段时间后关闭连接,而服务器收到ACK后则立即关闭连接。

参考口述回答(系统版)

首先,我们要明确TCP连接是全双工的,这意味着数据可以在两个方向上同时传输。因此,当一方想要关闭连接时,它需要通知另一方,并确保双方的数据传输都已完成,然后才能完全关闭连接。这就是四次挥手的主要目的。

第一次挥手是由客户端发起的。当客户端没有更多的数据要发送时,它会发送一个FIN报文段给服务端。这个FIN报文段的作用是告诉服务端:“我已经没有数据要发送了,你可以开始关闭你那边到我这边的连接了”。同时,客户端会进入FIN_WAIT_1状态,等待服务端的确认。

第二次挥手发生在服务端收到FIN报文段后。服务端会发送一个ACK报文段给客户端,作为对FIN报文段的确认。这个ACK报文段的作用是告诉客户端:“我已经收到你的关闭请求了,我这边会准备关闭连接,但是在我发送完所有的数据之前,连接还不会完全关闭”。此时,服务端进入CLOSE_WAIT状态,等待所有数据发送完毕。而客户端在收到ACK后,会进入FIN_WAIT_2状态,等待服务端的FIN报文段。

第三次挥手发生在服务端发送完所有数据后。此时,服务端会发送一个FIN报文段给客户端,告知客户端它也没有数据要发送了,可以关闭连接了。这个FIN报文段的作用是告诉客户端:“我这边也没有数据要发送了,我们可以关闭连接了”。服务端在发送FIN报文段后,会进入LAST_ACK状态,等待客户端的确认。

第四次挥手是客户端在收到服务端的FIN报文段后发起的。客户端会发送一个ACK报文段给服务端,作为对FIN报文段的确认。这个ACK报文段的作用是告诉服务端:“我已经收到你的关闭请求了,我会关闭连接”。在发送完ACK报文段后,客户端会进入TIME_WAIT状态。这个状态会持续一段时间(通常是2MSL,即数据包在网络中的最大生存时间),以确保关闭请求和确认报文段能够被对方正确接收。如果在这段时间内没有收到对方的重新发送请求,那么客户端会最终关闭连接,进入CLOSED状态。而服务端在收到ACK报文段后,会立即关闭连接,进入CLOSED状态。

这就是TCP四次挥手的全过程。通过这个过程,TCP连接能够在确保双方数据传输完成的前提下安全地关闭。这个过程的每一步都是必要的,以确保数据的完整性和可靠性。

推荐学习资料

《小林 Coding》|图解网络: TCP 四次挥手过程是怎样的?

12. TIME_WAIT相关问题?

解析

属于高频考题:自产《大厂后端Top100面试题|第87题》

所属专项:计算机网络|TCP&UDP

专项考察占比:

计算机网络】面试中考察计算机网络的比率:大厂:11%腾讯:17%阿里:7%

计算机网络-TCP&UDP】面试考察计网时问TCP&UDP问题的比率:42%

TIME_WAIT了解吗?

当TCP连接中主动关闭连接的一方发送最后一个ACK确认包后,它会进入TIME_WAIT状态。这个状态的主要作用是等待一段时间,以确保最后的ACK确认包能够被对方正确接收。

TIME_WAIT状态持续的时间是2MSL,也就是两个最大报文段生存时间。这个时间的选择是为了确保在网络中可能存在的延迟或重传的报文段有足够的时间消失,从而避免对后续新建立的连接造成干扰。

在TIME_WAIT状态下,系统会等待足够的时间以确保对方接收到最后的ACK确认包,并且确保网络中不会再有该连接的残留报文。一旦过了这个时间,连接就会完全关闭,资源也会被释放。

服务器什么情况下会产生大量的TIME_WAIT呢?

首先要知道 TIME_WAIT 状态是主动关闭连接方才会出现的状态,所以如果服务器出现大量的 TIME_WAIT 状态的 TCP 连接,就是说明服务器主动断开了很多 TCP 连接。而服务器主动断开链接的场景有:1. HTTP 没有使用长连接;2.HTTP 长连接超时;3. HTTP 长连接的请求数量达到上限等

如果TIME_WAIT太多会有什么问题吗?

首先端口资源耗尽是一个主要的问题。由于每个处于TIME_WAIT状态的连接都会占用一个端口,当这种状态的连接数量过多时,可能会导致服务端可用端口不足。一旦所有可用端口都被占满,新的连接就无法建立,从而导致服务拒绝新的客户端请求。

其次,大量的TIME_WAIT状态也会消耗服务端的系统资源,如内存和CPU。虽然每个TIME_WAIT连接消耗的资源相对较少,但当数量庞大时,这些资源的累积消耗就会变得显著,可能会影响到服务端的整体性能。

最后,大量的TIME_WAIT状态还可能导致一些管理上的困扰。例如,监控和排查问题时需要更多的精力来处理这些连接。同时,如果服务端频繁出现大量TIME_WAIT状态,可能需要对服务端的网络配置或应用程序逻辑进行优化,以减少这种情况的发生。

你怎么解决大量TIME_WAIT这个问题?

首先,考虑到TIME_WAIT状态主要是为了确保关闭连接的请求和最后的ACK能够被对方正确接收,我会尝试优化TCP参数配置。具体来说,可以调整TCP的SO_REUSEADDR选项,允许端口复用,这样即使端口处于TIME_WAIT状态,也可以被新的连接所使用,从而避免了端口资源耗尽的问题。

其次,我会从应用程序的设计层面进行优化。例如,对于频繁进行短连接操作的场景,我会考虑使用长连接或者连接池技术来减少连接的频繁建立和关闭。这样不仅可以减少TIME_WAIT状态的数量,还能提高系统的整体性能。

另外,我也会关注服务端和客户端之间的网络通信质量。如果网络通信不稳定或者存在延迟,可能会导致连接在关闭后仍然长时间处于TIME_WAIT状态。因此,我会尝试优化网络环境,减少网络延迟和丢包率,从而降低TIME_WAIT状态的数量。

最后,如果服务端确实需要频繁地关闭和打开连接,并且无法避免大量的TIME_WAIT状态,我会考虑增加服务端的端口范围,以确保即使有大量TIME_WAIT状态存在,也不会耗尽所有可用端口。

为什么 TIME_WAIT 等待的时间是 2MSL?

首先,设置2MSL的等待时间可以确保最后的ACK报文能够到达对方并被正确接收。网络传输中可能存在延迟或丢包的情况,所以给予足够的时间窗口,让对方能够接收到确认消息,从而保证连接的可靠关闭。

其次,这个时间的设置也有助于避免新旧连接之间的混淆。在网络中,可能存在多个相同源IP地址和目的IP地址的连接。等待2MSL的时间可以确保之前连接的所有报文都已经在网络中消失,这样新的连接就不会错误地接收到之前连接的残留数据。

总的来说,TIME_WAIT等待的时间是2MSL,是为了确保网络连接的可靠关闭,并防止新旧连接之间的混淆。

推荐学习资料

《小林 Coding》|图解网络:

为什么需要 TIME_WAIT 状态?

服务器出现大量 TIME_WAIT 状态的原因有哪些?

TIME_WAIT 过多有什么危害?

如何优化 TIME_WAIT?

为什么 TIME_WAIT 等待的时间是 2MSL?

本文也是 《热门面经讲解》 专栏 系列文章之一,文末尾有专栏链接,大家可以点个关注,我会持续更新~

#面经##字节##实习##春招##秋招#
热门面经讲解 文章被收录于专栏

挑选近期热门真实后端面经进行讲解分析,给出:个人分析+参考回答+学习资料指引。

全部评论

相关推荐

9 28 评论
分享
牛客网
牛客企业服务