快手一面 客户端开发

快手一面【日常实习】

base: 北京

岗位:客户端开发-ios

时间: 2024/9/2 上午 11点

一面已过 ,明天晚上二面

操作系统 :

进程和线程的区别

  • 定义:

进程:操作系统中一个正在运行的程序实例。 它包含了程序代码和当前活动状态。每个进程都有自己独立的地址空间。
线程:是进程中的一个执行单元。线程共享进程的资源(如内存、文件句柄),但它们有自己的栈、寄存器和程序计数器。

进程是系统进行资源分配和调度的基本单位
线程是操作系统能够进行运算调度的最小单位,其是进程中的一个执行任务(控制单元)

  • 资源:

进程:拥有独立的内存空间和系统资源。
线程:同一个进程中的线程共享该进程的资源。

  • 开销:

进程:进程之间的切换开销大,因为需要切换独立的内存空间和资源。
线程:线程之间的切换开销小,线程共享同一进程的资源,切换时不需要更换内存空间。

  • 通信:

进程:进程间通信相对复杂,需要通过操作系统提供的机制如管道、消息队列、共享内存等来进行。
线程:线程间的通信更为直接,因为它们共享进程的地址空间,可以通过直接访问共享数据来通信。

详解推荐: 面试官:说说什么是进程?什么是线程?区别?

计网:

1. 网络协议有哪些?

网络协议主要分为以下几层,各层具有不同的协议:
应用层: HTTP, HTTPS, FTP, SMTP, DNS, POP3, IMAP
传输层: TCP, UDP
网络层: IP,ICMP, ARP, RARP, OSPF, BGP
数据链路层:Ethernet, PPP, HDLC
物理层:光纤、网线、无线信号等物理媒介

2. TCP和UDP在哪一层?

TCP和UDP都属于传输层协议

3.TCP 和 UDP的区别?

连接性:

TCP:面向连接的协议,在传输数据前需要建立连接(三次握手)。 UDP:无连接协议,发送数据前不需要建立连接。
可靠性:

TCP:提供可靠的数据传输,有确认、重传机制,保证数据的完整性和顺序性。 UDP:不保证可靠传输,没有确认、重传机制,数据可能丢失或乱序。

流控制和拥塞控制:

TCP:有流控制和拥塞控制机制,保证网络的稳定性。 UDP:没有流控制和拥塞控制机制,传输速度快,但不保证数据的稳定传输。
速度:

TCP:较慢,由于连接建立、确认和重传机制,开销较大。 UDP:较快,适用于实时应用,如视频直播、在线游戏。

4.TCP 为什么可靠?

顺序控制:TCP数据包带有序号,接收方可以按序重组数据包,即使数据包乱序也能正确排序。
确认应答:每次数据包传送后,接收方都需要发送一个确认应答(ACK),未收到确认的包会被重传。
超时重传:如果发送方在一定时间内没有收到确认应答,数据包将被重新发送。
流量控制:TCP使用滑动窗口机制来控制数据流的传输速度,防止网络拥塞。
拥塞控制:TCP采用慢启动、拥塞避免、快重传、快恢复等机制,确保网络不会因为过载而崩溃。

  1. 三次握手 和 四次挥手 解释一下!

三次握手:

客户端发送SYN:客户端向服务器发送一个SYN(同步)包,请求建立连接。
服务器发送SYN-ACK:服务器收到SYN包后,返回一个SYN-ACK包,表示同意连接,并请求客户端确认。
客户端发送ACK:客户端收到SYN-ACK包后,发送一个ACK包,确认连接建立。 连接正式建立。

四次挥手:

客户端发送FIN:客户端向服务器发送一个FIN(终止)包,表示要断开连接。
服务器发送ACK:服务器收到FIN包后,返回一个ACK包,表示收到请求。
服务器发送FIN:服务器在准备好断开连接后,发送一个FIN包,表示可以断开连接。
客户端发送ACK:客户端收到服务器的FIN包后,发送一个ACK包,确认连接断开。 连接正式断开。

详解推荐: TCP 三次握手与四次挥手面试题

5. HTTP 和 HTTPS的区别?

安全性:

HTTP:不安全,数据以明文形式传输,容易被拦截、篡改。 HTTPS:安全,使用SSL/TLS协议对数据进行加密,防止数据被拦截和篡改。
端口:

HTTP:使用端口80。 HTTPS:使用端口443。
证书:

HTTP:不需要证书。 HTTPS:需要数字证书,由CA机构颁发,保证服务器的真实性。
性能:

HTTP:性能稍高,因为不涉及加密解密操作。 HTTPS:性能稍低,因为涉及加密解密操作,但现代硬件的性能已经使这个差距非常小。

语言

面试官: 看你做后端java开发比较多,解释一下 String、StringBuilder以及StringBuffer 的区别

数据结构

排序算法 和 稳定性

常见的排序算法有哪些?哪些是稳定的?

推荐链接: ❤️十大排序算法详解❤️——可能是你看过最全的,完整版代码
也可以多看一些 动图 解释,印象更深刻

常见的排序算法有很多,主要包括:

冒泡排序(Bubble Sort)
选择排序(Selection Sort)
插入排序(Insertion Sort)
归并排序(Merge Sort)
快速排序(Quick Sort)
堆排序(Heap Sort)
希尔排序(Shell Sort)
计数排序(Counting Sort)
桶排序(Bucket Sort)
基数排序(Radix Sort)

稳定与不稳定排序算法
排序算法是否稳定,取决于它在处理相等元素时,是否保持它们在原数组中的相对顺序。稳定的排序算法对于某些场景(如需要进一步操作排序后的结果)非常重要。

稳定的排序算法:
冒泡排序
插入排序
归并排序
计数排序
基数排序
桶排序(在某些实现中)
不稳定的排序算法:
选择排序
快速排序
堆排序
希尔排序
常见排序算法的代码实现及解释

1. 冒泡排序(Bubble Sort)(稳定)

冒泡排序通过多次遍历数组,每次比较相邻的元素并交换顺序,直到所有元素有序。

def bubble_sort(arr):
    n = len(arr)
    for i in range(n):
        for j in range(0, n-i-1):
            if arr[j] > arr[j+1]:
                arr[j], arr[j+1] = arr[j+1], arr[j]
    return arr

解释: 逐渐将较大的元素“冒泡”到数组的末尾。
时间复杂度:O(n²)

2. 选择排序(Selection Sort)(不稳定)

选择排序每次从未排序的部分中选出最小的元素,并将其放到已排序部分的末尾。

def selection_sort(arr):
    n = len(arr)
    for i in range(n):
        min_idx = i
        for j in range(i+1, n):
            if arr[j] < arr[min_idx]:
                min_idx = j
        arr[i], arr[min_idx] = arr[min_idx], arr[i]
    return arr

解释:每次选择剩下部分中最小的元素放到合适的位置。 时间复杂度:O(n²)

3. 插入排序(Insertion Sort)(稳定)

插入排序通过逐步将元素插入到已排序部分的合适位置。

def insertion_sort(arr):
    for i in range(1, len(arr)):
        key = arr[i]
        j = i - 1
        while j >= 0 and key < arr[j]:
            arr[j + 1] = arr[j]
            j -= 1
        arr[j + 1] = key
    return arr

解释:

类似于玩扑克牌时的整理牌顺序,每次插入一个元素。
时间复杂度:O(n²)

4. 归并排序(Merge Sort)(稳定)

归并排序是一种分治算法,先将数组分成两个子数组,分别排序后再合并。

def merge_sort(arr):
    if len(arr) > 1:
        mid = len(arr) // 2
        L = arr[:mid]
        R = arr[mid:]
        
        merge_sort(L)
        merge_sort(R)
        
        i = j = k = 0
        while i < len(L) and j < len(R):
            if L[i] < R[j]:
                arr[k] = L[i]
                i += 1
            else:
                arr[k] = R[j]
                j += 1
            k += 1
        
        while i < len(L):
            arr[k] = L[i]
            i += 1
            k += 1
        
        while j < len(R):
            arr[k] = R[j]
            j += 1
            k += 1
    return arr

解释:

通过递归分割数组,并将两个有序数组合并成一个。
时间复杂度:O(n log n)

5. 快速排序(Quick Sort)(不稳定)

快速排序是一种分治算法,选取一个基准点(pivot),将数组分为比基准点小和大的两部分,分别排序。

def quick_sort(arr):
    if len(arr) <= 1:
        return arr
    else:
        pivot = arr[len(arr) // 2]
        left = [x for x in arr if x < pivot]
        middle = [x for x in arr if x == pivot]
        right = [x for x in arr if x > pivot]
        return quick_sort(left) + middle + quick_sort(right)

解释:

通过递归地划分数组,最终得到有序数组。
时间复杂度:平均O(n log n),最坏O(n²)

6. 堆排序(Heap Sort)(不稳定)

堆排序利用二叉堆的数据结构,每次从堆顶取出最大元素放到排序部分。

def heapify(arr, n, i):
    largest = i
    left = 2 * i + 1
    right = 2 * i + 2

    if left < n and arr[i] < arr[left]:
        largest = left

    if right < n and arr[largest] < arr[right]:
        largest = right

    if largest != i:
        arr[i], arr[largest] = arr[largest], arr[i]
        heapify(arr, n, largest)

def heap_sort(arr):
    n = len(arr)
    for i in range(n // 2 - 1, -1, -1):
        heapify(arr, n, i)

    for i in range(n - 1, 0, -1):
        arr[i], arr[0] = arr[0], arr[i]
        heapify(arr, i, 0)
    return arr

解释:

通过构建最大堆,每次提取堆顶元素来构建有序数组。
时间复杂度:O(n log n)

稳定性和不稳定性解释:
稳定排序:在处理相同值的元素时,不会改变它们在原始序列中的相对顺序。例如,归并排序和冒泡排序是稳定的。
不稳定排序:在排序过程中,可能会改变相同值元素的相对顺序。例如,快速排序和堆排序是不稳定的。

情景题:

看你有机器学习、深度学习的基础,如果我们现在想要做一个,距离优先、价格优先的东西,你觉得你会如何处理 哪些数据,以及如何处理这些数据?

项目介绍

介绍一下,你做项目遇到的难题,怎么解决的

代码题

层序遍历

用二叉树,实现一个层序遍历,简单实现核心功能即可!

#include <iostream>
#include <queue>

using namespace std;

// 定义二叉树节点结构
struct TreeNode {
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};

// 层序遍历函数
void levelOrderTraversal(TreeNode* root) {
    if (root == nullptr) return;

    queue<TreeNode*> q;
    q.push(root);

    while (!q.empty()) {
        TreeNode* node = q.front();
        q.pop();

        cout << node->val << " ";

        if (node->left) q.push(node->left);
        if (node->right) q.push(node->right);
    }
}

int main() {
    // 构建一个简单的二叉树
    TreeNode* root = new TreeNode(1);
    root->left = new TreeNode(2);
    root->right = new TreeNode(3);
    root->left->left = new TreeNode(4);
    root->left->right = new TreeNode(5);

    cout << "层序遍历结果: ";
    levelOrderTraversal(root);

    return 0;
}

反问环节

转载链接: https://vue3js.cn/interview/linux/thread_process.html#%E4%B8%80%E3%80%81%E8%BF%9B%E7%A8%8B

https://xiaolincoding.com/network/3_tcp/tcp_interview.html#tcp-%E5%9F%BA%E6%9C%AC%E8%AE%A4%E8%AF%86

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值