抖音后端实习一面总结

置之死地而后生

抖音后端开发实习一面

  • 自我介绍

  • 你参加了PAT比赛?介绍一下?

  • 平时有刷题吗?有的,那来做一下算法题目吧,单词拆分(动态规划1h过去了...)

  • TCP有哪些状态?每种状态代表着什么含义?为什么要有这些状态?

  • select/poll/epoll了解吗?有什么区别?

  • epoll为什么高效?(红黑树)

  • epoll里面的回调是什么?

  • 场景:如果上传文件,你会使用哪个?为什么?

  • 反问 (业务是什么?(你打开抖音,里面的功能有哪些就是我们的业务)实习多久(根据你来定))

  • 1个半小时

总结:算法能力欠缺?常见八股的值得细究!

单词拆分

注意是ACM风格,动态规划

复制代码
class Solution {
public:
    bool wordBreak(string s, vector<string>& wordDict) {
        int max_len = ranges::max(wordDict, {}, &string::length).length();
        unordered_set<string> words(wordDict.begin(), wordDict.end());

        int n = s.length();
        vector<int> memo(n + 1, -1); // -1 表示没有计算过
        auto dfs = [&](this auto&& dfs, int i) -> bool {
            if (i == 0) { // 成功拆分!
                return true;
            }
            int& res = memo[i]; // 注意这里是引用
            if (res != -1) { // 之前计算过
                return res;
            }
            for (int j = i - 1; j >= max(i - max_len, 0); j--) {
                if (words.count(s.substr(j, i - j)) && dfs(j)) {
                    return res = true; // 记忆化
                }
            }
            return res = false; // 记忆化
        };
        return dfs(n);
    }
};

TCP的三次握手,四次挥手

TCP(传输控制协议)是互联网协议族中的一种面向连接的、可靠的、基于字节流的传输层通信协议。为了建立和关闭连接,TCP 使用了三次握手(Three-Way Handshake)来建立连接,以及四次挥手(Four-Way Wavehand)来关闭连接。在这个过程中,TCP 连接会经历多种状态,每种状态都有其特定的含义。

三次握手

三次握手是 TCP 建立连接的过程,涉及两个端点之间的三个步骤:

  1. 第一次握手(SYN) :客户端发送一个 SYN(同步序列编号)包到服务器,表示想要建立连接,并包含一个初始序列号 seq=x

  2. 第二次握手(SYN-ACK) :服务器收到客户端的 SYN 包后,会回复一个 SYN-ACK 包,包含服务器的初始序列号 seq=y 和对客户端序列号的确认 ack=x+1

  3. 第三次握手(ACK) :客户端收到服务器的 SYN-ACK 包后,会回复一个 ACK 包,确认服务器的序列号 ack=y+1,并再次确认自己的序列号 seq=x+1。此时,连接建立完成。

四次挥手

四次挥手是 TCP 关闭连接的过程,涉及两个端点之间的四个步骤:

  1. 第一次挥手(FIN):一方(例如客户端)发送一个 FIN 包到另一方(服务器),表示数据发送完毕,请求关闭连接。

  2. 第二次挥手(ACK):接收方(服务器)收到 FIN 包后,回复一个 ACK 包,确认收到 FIN 包。

  3. 第三次挥手(FIN):接收方(服务器)在完成数据发送后,也发送一个 FIN 包到发送方(客户端),表示请求关闭连接。

  4. 第四次挥手(ACK):发送方(客户端)收到服务器的 FIN 包后,回复一个 ACK 包,确认收到 FIN 包。此时,连接关闭完成。

TCP 状态

在三次握手和四次挥手的过程中,TCP 连接会经历多种状态,这些状态在不同的操作系统中可能有所差异,但通常包括以下几种:

  • CLOSED:连接没有建立,处于关闭状态。

  • LISTEN:服务器端处于监听状态,等待客户端连接请求。

  • SYN-SENT:客户端已经发送了 SYN 包,等待服务器的 SYN-ACK 包。

  • SYN-RECEIVED:服务器收到客户端的 SYN 包,已发送 SYN-ACK 包,等待客户端的 ACK 包。

  • ESTABLISHED:连接已经建立,可以进行数据传输。

  • FIN-WAIT-1:客户端已经发送了 FIN 包,等待服务器的 ACK 包。

  • FIN-WAIT-2:客户端已经发送了 FIN 包,并收到了服务器的 ACK 包,等待服务器的 FIN 包。

  • TIME-WAIT:客户端已经发送了 ACK 包响应服务器的 FIN 包,处于时间等待状态,等待可能丢失的服务器 FIN 包的重传。

  • CLOSE-WAIT:服务器收到客户端的 FIN 包,已经发送了 ACK 包,等待应用程序关闭连接。

  • LAST-ACK:服务器已经发送了 FIN 包,等待客户端的 ACK 包。

  • CLOSING:双方同时尝试关闭连接,收到对方的 FIN 包并发送自己的 FIN 包。

这些状态确保了 TCP 连接的可靠性和数据传输的完整性。通过这些状态的转换,TCP 协议能够管理连接的建立、数据传输和关闭过程。

select,poll,epoll区别?

selectpollepoll 都是 Linux 系统中用于实现 I/O 多路复用(I/O multiplexing)的系统调用,它们允许程序同时监视多个文件描述符(file descriptors),并在这些文件描述符上有 I/O 事件发生时通知程序,从而避免在等待 I/O 时阻塞整个程序。尽管它们的目的相同,但它们在实现方式和性能特征上有很大的区别。

1. select

  • 基本原理select 是最早引入的 I/O 多路复用机制。它使用一个 fd_set 结构体来表示一组文件描述符,并使用三个 fd_set 来分别监视读、写和异常(错误)事件。select 会在这些文件描述符上等待,直到至少有一个文件描述符就绪(即有 I/O 事件发生)。

  • 局限性

    • fd_set 的大小是固定的(通常为 1024 个文件描述符),因此 select 最多只能监视 1024 个文件描述符。

    • 每次调用 select 时,需要将 fd_set 从用户空间复制到内核空间,并且每次返回时,内核会将 fd_set 复制回用户空间。这个复制操作在文件描述符数量较多时会带来较大的开销。

    • select 返回后,程序需要遍历所有的文件描述符来检查哪些文件描述符就绪,这在文件描述符数量较多时效率较低。

  • 优点select 兼容性好,几乎所有操作系统都支持。

2. poll

  • 基本原理poll 是对 select 的改进。它使用一个 pollfd 结构体数组来表示一组文件描述符,并指定每个文件描述符感兴趣的事件(读、写、异常)。poll 会在这些文件描述符上等待,直到至少有一个文件描述符就绪。

  • 改进点

    • poll 没有文件描述符数量的限制(虽然实际使用中可能会受到系统资源限制)。

    • 不需要像 select 那样每次调用时都将 fd_set 复制到内核空间,减少了数据复制的开销。

    • poll 返回后,程序只需要遍历就绪的文件描述符,而不是所有的文件描述符,提高了效率。

  • 局限性

    • 虽然 poll 减少了数据复制的开销,但在文件描述符数量较多时,遍历所有文件描述符的开销仍然存在。

    • poll 在高并发情况下,性能可能会下降。

3. epoll

  • 基本原理epoll 是 Linux 特有的 I/O 多路复用机制,专门为高性能网络服务器设计。它使用事件驱动的方式来监视文件描述符,通过 epoll_create 创建一个 epoll 实例,通过 epoll_ctl 添加、修改或删除文件描述符,最后通过 epoll_wait 等待事件的发生。

  • 优点

    • 边缘触发(Edge Triggered, ET)和水平触发(Level Triggered, LT)epoll 支持两种事件触发模式。水平触发(LT)模式下,epoll 会在文件描述符就绪后持续通知程序,直到事件被处理;边缘触发(ET)模式下,epoll 只会在文件描述符状态发生变化时通知程序一次。ET 模式下可以减少不必要的系统调用,提高性能。

    • 内核直接管理文件描述符epoll 在内核中维护一个文件描述符的事件列表,避免了每次调用时从用户空间复制数据到内核空间的开销。

    • 事件驱动epoll_wait 返回后,程序只需要处理就绪的文件描述符,避免了不必要的遍历操作。

  • 局限性

    • epoll 是 Linux 特有的,不具有跨平台性。

    • 使用 epoll 需要更多的编程复杂性,特别是在处理边缘触发模式时。

总结

  • select:适用于简单的场景,尤其是需要跨平台的情况,但性能较差,文件描述符数量有限。

  • poll:改进了 select 的一些限制,但仍然存在性能问题,尤其是在高并发情况下。

  • epoll:专为高性能网络服务器设计,性能优异,但仅适用于 Linux 系统。

选择哪种机制取决于具体的应用场景和需求。在大多数情况下,epoll 是首选,因为它在高并发和高性能方面表现出色。然而,如果你需要跨平台编程或者文件描述符数量不多,selectpoll 可能是更合适的选择。

场景题:上传文件使用哪一个?select/poll/epoll?

在上传文件时,选择使用 selectpoll 还是 epoll 主要取决于应用程序的具体需求和场景。这些 I/O 多路复用机制主要用于处理多个文件描述符的 I/O 事件,例如在网络服务器中监听多个套接字的事件。然而,上传文件通常涉及到的是简单的客户端与服务器之间的交互,而不是高并发的网络服务器。

上传文件的典型流程

上传文件通常涉及以下步骤:

  1. 客户端向服务器发起 HTTP POST 请求。

  2. 客户端将文件数据封装在请求体中,发送到服务器。

  3. 服务器接收文件数据并存储。

在这个过程中,客户端和服务器之间通常是单个连接,而不是多个并发连接。因此,selectpollepoll 在这类场景中的使用并不是必须的,因为它们更多地用于处理多个并发连接或 I/O 操作。

选择 I/O 多路复用机制的考虑

然而,如果你需要在服务器端处理多个并发上传请求,并且希望高效地管理这些连接,那么选择合适的 I/O 多路复用机制就变得重要了。

  • select:适用于简单场景,尤其是在需要跨平台的情况下。然而,select 在处理大量文件描述符时的性能较差。

  • poll:改进了 select 的一些限制,但在高并发情况下,性能仍然有限。

  • epoll:专为高性能网络服务器设计,适用于高并发、高吞吐量的场景。epoll 在内核中维护文件描述符的状态,避免了数据复制的开销,并且支持边缘触发模式,适合处理大量并发连接。

使用建议

  1. 单个文件上传 :如果只是单个文件上传,通常不需要使用 selectpollepoll,直接使用 HTTP POST 请求即可。

  2. 多个并发文件上传 :如果你需要处理多个并发文件上传,并且服务器在高并发环境下运行,那么 epoll 是最佳选择。epoll 能够高效地管理大量并发连接,适用于高吞吐量的文件上传场景。

示例

以下是一个简单的文件上传示例,使用 HTTP POST 请求:

客户端代码(Python)

复制代码
import requests

url = 'http://example.com/upload'
files = {'file': open('example.txt', 'rb')}
response = requests.post(url, files=files)
print(response.text)

服务器端代码(Python,使用 Flask)

复制代码
from flask import Flask, request

app = Flask(__name__)

@app.route('/upload', methods=['POST'])
def upload_file():
    file = request.files['file']
    file.save('/path/to/save/file.txt')
    return 'File uploaded successfully'

if __name__ == '__main__':
    app.run()

在这个示例中,客户端将文件上传到服务器,服务器接收并保存文件,整个过程没有使用 selectpollepoll

总结

在文件上传的典型场景中,直接使用 HTTP POST 请求通常是最简单和最有效的方式。只有在需要处理大量并发文件上传的场景中,才需要考虑使用 epoll 等 I/O 多路复用机制来优化性能。


处女面给了字节,第一次面试直接地狱难度,大厂的强度还是很大的,上来先做一道动态规划,八股虽然就问了两个,但还是很细的。 patience is key...

相关推荐
业精于勤的牙38 分钟前
三角形最小路径和(二)
算法
风筝在晴天搁浅39 分钟前
hot100 239.滑动窗口最大值
数据结构·算法·leetcode
夏乌_Wx1 小时前
练题100天——DAY31:相对名次+数组拆分+重塑矩阵
数据结构·算法
LYFlied1 小时前
【算法解题模板】-解二叉树相关算法题的技巧
前端·数据结构·算法·leetcode
Ven%1 小时前
【AI大模型算法工程师面试题解析与技术思考】
人工智能·python·算法
天勤量化大唯粉1 小时前
枢轴点反转策略在铜期货中的量化应用指南(附天勤量化代码)
ide·python·算法·机器学习·github·开源软件·程序员创富
爱学习的小仙女!2 小时前
算法效率的度量 时间复杂度 空间复杂度
数据结构·算法
AndrewHZ2 小时前
【复杂网络分析】什么是图神经网络?
人工智能·深度学习·神经网络·算法·图神经网络·复杂网络
Swizard2 小时前
拒绝“狗熊掰棒子”!用 EWC (Elastic Weight Consolidation) 彻底终结 AI 的灾难性遗忘
python·算法·ai·训练
fab 在逃TDPIE3 小时前
Sentaurus TCAD 仿真教程(十)
算法