【腾讯云】CSIG一面,凉凉凉|0313
1. 介绍下TCP UDP的区别
解析:
计算机网络基础知识,简单题,必考题。
参考答案:
TCP(传输控制协议)和UDP(用户数据报协议)是计算机网络中传输层的两个主要协议,它们各自具有不同的特点和适用场景。以下是TCP和UDP之间的主要区别:
- 连接特性:
- TCP是面向连接的协议。在传输数据之前,需要通过三次握手来建立连接,并在数据传输完成后通过四次挥手来释放连接。这种连接机制确保了数据传输的可靠性和顺序性。
- UDP则是无连接的协议。发送数据前不需要建立连接,直接发送数据包,这使得UDP在传输数据时更加灵活和高效。
- 可靠性:
- TCP提供可靠的数据传输服务。它使用校验和、重传控制、序号标识、滑动窗口和确认应答等机制来确保数据的无差错、不丢失、不重复且按序到达。
- UDP则提供尽最大努力交付的服务,不保证数据的可靠传输。在数据传输过程中,如果发生丢包或乱序,UDP不会进行重传或顺序控制。
- 效率与实时性:
- UDP具有较好的实时性和较高的工作效率,因为它不需要建立连接和进行复杂的控制操作。这使得UDP适用于对高速传输和实时性有较高要求的通信或广播通信,如语音、视频、直播等。
- TCP虽然提供了可靠的数据传输,但由于其复杂的控制机制,相对UDP而言效率较低。
- 通信模式:
- TCP连接只能是点对点的,即一条TCP连接只能连接两个端点。
- UDP则支持一对一、一对多、多对一和多对多的交互通信模式,这使得UDP在广播和多播等场景中更具优势。
- 首部开销:
- TCP的首部较大,通常为20字节,这增加了每个数据包的开销。
- UDP的首部较小,只有8字节,减少了数据包的开销,提高了传输效率。
TCP和UDP在连接特性、可靠性、效率与实时性、通信模式以及首部开销等方面存在显著差异。在选择使用TCP还是UDP时,需要根据具体的应用场景和需求进行权衡。例如,对于需要可靠数据传输的场景(如文件传输、远程登录等),TCP是更好的选择;而对于实时性要求较高或需要广播和多播的场景(如语音、视频等),UDP则更具优势。
学习指引:TCP和Udp的区别是什么?
2. TCP怎么保证他的连接可靠
解析:
计算机网络常见题,必考题。
参考答案:
TCP(传输控制协议)通过一系列机制保证连接的可靠性。以下是TCP确保连接可靠性的主要方式:
- 序列号与确认应答:TCP给每一个发送的数据包都赋予一个序列号,同时要求接收方在收到数据后回复一个确认应答(ACK),告知发送方已成功接收。如果发送方在一定时间内没有收到ACK,它会认为数据包丢失并重传。
- 校验和:TCP在发送数据前会计算数据的校验和,并在接收端对数据进行校验和比对。如果校验和不匹配,接收端会丢弃该数据包,并要求发送方重传。
- 超时重传:TCP在发送数据包后会启动一个定时器。如果定时器超时前未收到ACK,发送方会重传该数据包。
- 连接管理:TCP通过三次握手来建立连接,确保双方都已准备好进行数据传输。在数据传输完成后,通过四次挥手来关闭连接,确保数据已完全传输并释放资源。
- 流量控制:TCP使用滑动窗口机制来实现流量控制,确保发送方不会发送过多数据导致接收方缓冲区溢出。
- 拥塞控制:TCP通过慢开始、拥塞避免、快重传和快恢复等算法来避免网络拥塞,确保数据传输的稳定性和可靠性。
学习指引:TCP协议如何保证可靠传输
3. 介绍一下四次挥手
解析:
计算机网络常见题,必考题。
参考答案:
四次挥手是TCP(传输控制协议)中用于释放已建立的连接的一个过程。这个过程确保客户端和服务器双方都能正常、有序地关闭连接,并释放相关资源。以下是四次挥手的详细步骤:
- 第一次挥手:客户端(假设为主动关闭的一方)发送一个FIN报文给服务器,用来关闭客户端到服务器的数据传送。此时,客户端进入FIN_WAIT_1状态,等待服务器的确认。
- 第二次挥手:服务器收到FIN报文后,发送一个ACK报文给客户端,确认收到客户端的关闭请求。此时,服务器进入CLOSE_WAIT状态,客户端收到这个ACK后,进入FIN_WAIT_2状态。
- 第三次挥手:服务器在完成所有数据传输后,发送一个FIN报文给客户端,表示服务器也准备关闭连接。此时,服务器进入LAST_ACK状态,等待客户端的确认。
- 第四次挥手:客户端收到服务器的FIN报文后,发送一个ACK报文给服务器,确认收到服务器的关闭请求。此时,服务器进入CLOSE状态,完成连接的关闭。客户端在发送完ACK后,会等待一段时间(通常是2MSL,即两倍的最长报文段寿命),确保服务器已经收到ACK并关闭了连接。然后,客户端进入CLOSE状态,完成四次挥手过程。
通过四次挥手,TCP协议确保了双方都能正常、有序地关闭连接,避免了资源泄露和网络问题。这也是TCP协议保证连接可靠性的一个重要方面。
4. TIME_WAIT出现在TCP连接的什么时候
解析:
计算机网络基础知识,简单题,必考题。
参考答案:
TIME_WAIT状态出现在TCP连接的关闭过程中,特别是在四次挥手的阶段。具体来说,当主动关闭连接的一方(通常是客户端)发送完最后一个ACK报文后,它会进入TIME_WAIT状态。
在四次挥手的过程中,主动关闭连接的一方首先发送一个FIN报文给对端,表示希望关闭连接。然后,它等待并接收到对端的ACK报文,进入FIN_WAIT_2状态。接着,当对端也准备好关闭连接并发送FIN报文时,主动关闭连接的一方会发送一个ACK报文进行确认,并进入TIME_WAIT状态。
在TIME_WAIT状态中,主动关闭连接的一方会等待一段时间(通常是2MSL,即两倍的最长报文段寿命),以确保对端收到了ACK报文并关闭了连接。这样做的目的是为了防止已经关闭的连接中的报文段还在网络中滞留,导致出现“迷途”的数据包,影响下一次在相同端口上建立的新连接。
学习指引:TCP中time_wait解释及解决方法
5. 介绍一下HTTP连接的流程
解析:
在计算机网络中,HTTP 属于常考题,必考题。
参考答案:
- 浏览器进行DNS域名解析,得到对应的IP地址
- 根据这个IP,找到对应的服务器建立连接(三次握手)
- 建立TCP连接后发起HTTP请求(一个完整的http请求报文)
- 服务器响应HTTP请求,浏览器得到html代码(服务器如何响应)
- 浏览器解析html代码,并请求html代码中的资源(如js、css、图片等)
- 浏览器对页面进行渲染呈现给用户
- 服务器关闭TCP连接(四次挥手)
学习指引:一次完整的HTTP请求过程是怎么样的呢?
6. HTTP有长连接吗,怎么实现的
解析:
在计算机网络中,HTTP 进阶题,常考题。
参考答案:
HTTP有长连接。HTTP的长连接通常是通过在HTTP请求头中设置
Connection: keep-alive
字段来实现的。这个字段告诉服务器,客户端希望保持与服务器的TCP连接,直到超时或显式地断开连接。HTTP长连接的实现基于TCP协议。在HTTP/1.1中,长连接是默认启用的,除非显式地在请求头中设置
Connection: close
。在使用长连接的情况下,客户端和服务端建立一次连接之后,可以在这条连接上进行多次请求/响应操作。当客户端发送完一个HTTP请求后,连接并不会立即关闭,而是等待服务器发送响应。服务器在发送完响应后,也不会立即关闭连接,而是保持连接开放,以便客户端可以继续发送新的请求。这样,客户端和服务器之间可以重用已经建立的TCP连接,避免了频繁地建立和关闭连接所带来的开销,提高了网络性能。需要注意的是,长连接并不意味着连接会一直保持打开状态。在实际应用中,服务器可能会根据一些策略(如超时时间、并发连接数等)来主动关闭连接,或者客户端在发送完所有请求后也可以主动关闭连接。此外,HTTP/2协议中采用了更高效的连接管理方式,称为多路复用,它默认使用长连接,并通过更复杂的机制来管理多个请求在同一连接上的并发传输。
HTTP长连接的实现依赖于TCP协议的支持和HTTP协议中相关字段的设置。通过合理使用长连接,可以提高Web应用的性能和用户体验。
学习指引:HTTP长连接实现原理
7. TCP长短连接流程,怎么实现
解析:
参考答案:
TCP长短连接的流程如下:
短连接:
- 建立连接:客户端与服务器之间建立TCP连接。
- 发送消息:客户端向服务器发送消息或请求。
- 响应回传:服务器响应回传消息或处理结果给客户端。
- 关闭连接:完成一次发送与接收(读、写)服务后,客户端和服务器都会关闭连接。
长连接:
- 建立连接:客户端与服务器之间建立TCP连接。
- 发送消息:客户端向服务器发送消息或请求。
- 响应回传:服务器响应回传消息或处理结果给客户端。
- 多次通信:一次请求响应结束后,当前连接不关闭,通过当前连接实现多次通信。
- 关闭连接:客户端或服务器在不再需要连接时,会主动关闭连接。通常,客户端会发起关闭连接的请求,而服务器则依据连接的超时时间(timeout)来关闭连接。
实现方式:
TCP长短连接的实现主要依赖于TCP协议本身以及应用程序的设计。在TCP层面,连接的建立、数据的传输和连接的关闭都是通过TCP协议的相关机制来完成的。而在应用层面,如HTTP协议,可以通过在请求头中设置相应的字段(如
Connection: keep-alive
或Connection: close
)来指示使用长连接还是短连接。特点:
- 短连接:管理简单,每次请求都需要建立连接和释放连接,因此每次连接只用于一次读写操作。它适合于访问不频繁的操作,如简单的web页面访问、用户注册、数据查询或文件下载等。
- 长连接:可以省去较多的TCP建立和关闭的操作,减少浪费,节约时间。它适用于需要频繁通信的场景,如实时数据传输、聊天应用等。
TCP长短连接的实现主要依赖于TCP协议和应用层协议(如HTTP)的设定。根据应用的需求和场景,可以选择使用短连接或长连接来优化性能和资源利用。
学习指引:TCP 长连接 短连接
8. 介绍一下线程
解析:
操作系统必考题,简单难度。
参考答案:
线程,被称为轻量级进程(Lightweight Process, LWP),是程序执行流的最小单元,也是CPU调度和分派的基本单位。线程间共享进程的所有资源,每个线程有自己的堆栈和局部变量。使用线程的最大作用是提高程序并行执行的能力,充分利用CPU的利用率。然而,线程并非越多越好,因为过多的线程切换会消耗资源,反而可能导致程序的运行时间增加。
线程与进程类似,但线程是一个比进程更小的执行单位。一个进程在其执行的过程中可以产生多个线程。与进程不同的是,同类的多个线程共享同一块内存空间和一组系统资源,所以系统在产生一个线程,或是各个线程之间做切换工作时,负担要比进程小得多。
实现多线程主要有三种方法:继承Thread类、实现Runnable接口和实现Callable接口。线程与进程之间的主要区别在于,进程是资源分配的最小单位,而线程是CPU资源调度的最小单位。
总的来说,线程是操作系统中进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位。线程自己不拥有系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),但它可与同属一个进程的其它的线程共享进程所拥有的全部资源。
学习指引:进程?线程?有什么区别?
9. 线程的调度怎么完成
解析:
操作系统必考题,难度中等。
参考答案:
线程调度的完成通常涉及以下几个步骤:
- 选择调度算法:操作系统可以使用不同的调度算法来决定线程的执行顺序。常见的调度算法包括先来先服务(FCFS)、最短作业优先(SJF)、轮转调度(Round Robin)等。选择适合系统需求的调度算法是很重要的。
- 确定优先级:每个线程通常都有一个优先级,优先级决定了线程被调度的顺序。高优先级的线程会被优先执行,而低优先级的线程则可能被延迟执行。操作系统可以根据线程的类型、重要性等因素来确定线程的优先级。
- 创建和管理线程队列:操作系统会维护一个线程队列,用于存储等待执行的线程。当一个线程需要执行时,它会被添加到队列中。调度器会从队列中选择一个线程,并将其分配给可用的处理器执行。
- 上下文切换:当调度器决定切换到另一个线程时,它会进行上下文切换操作。上下文切换包括保存当前线程的上下文信息(如寄存器状态、程序计数器等),并加载下一个线程的上下文信息,以便继续执行。
- 执行线程:一旦调度器选择了一个线程,并完成了上下文切换,该线程就会开始执行。线程执行的时间片通常是有限的,当时间片用完后,调度器会再次选择下一个线程执行。
不同的操作系统可能会有不同的实现方式和策略。线程调度的目标是合理分配系统资源,提高系统的性能和响应能力。
学习指引:【操作系统】进程和线程调度
10. 线程在什么时候会阻塞
解析:
操作系统常考题,难度中等。
参考答案:
线程在多种情况下可能会进入阻塞状态。以下是一些常见的情况:
线程休眠:当线程执行了
Thread.sleep(int n)
方法时,它会放弃CPU的使用权,进入休眠状态,持续n毫秒后恢复运行。在休眠期间,线程处于阻塞状态。等待获取同步锁:当线程需要执行一段同步代码块,但无法获得相关的同步锁时,它会进入阻塞状态。只有当获得了所需的同步锁后,线程才能继续执行。
执行
wait()
方法:线程在执行一个对象的wait()
方法时,会进入阻塞状态。此时,线程会释放它持有的对象锁,并等待其他线程执行该对象的notify()
或notifyAll()
方法,才能被唤醒并继续执行。等待相关资源:线程在执行I/O操作(如文件读写、网络通信等)时,可能会因为等待相关资源而进入阻塞状态。例如,在远程通信中,客户端线程可能在等待服务器端响应时阻塞。
读写数据时的阻塞:
- 线程在向Socket的输出流写一批数据时,可能会进入阻塞状态,直到所有数据都输出,或者发生异常。
- 线程从Socket的输入流读取数据时,如果没有足够的数据,就会进入阻塞状态,直到读取到足够的数据,或者到达输入流的末尾,或者出现异常。
其他线程操作:当一个线程调用了
yield()
方法时,它会将执行权礼让给同等级或更高优先级的线程,此时也可能进入阻塞状态。线程设置延迟关闭:如果线程在Socket通信中设置了延迟关闭(通过
Socket.setSoLinger()
方法),那么在调用Socket.close()
方法时,线程会等待底层Socket发送完所有剩余数据,或者超过设定的延迟时间,才返回。这期间,线程也会处于阻塞状态。此外,线程的阻塞还可能由其他因素导致,如用户输入、文件上传、加载等操作。这些因素都会导致线程需要等待某个事件或条件成立后才能继续执行,从而进入阻塞状态。
学习指引:什么是线程阻塞?为什么会出现线程阻塞?](https://www.cnblogs.com/JonaLin/p/11570858.html)
11. 介绍一下c++的内存分配策略
解析:
C++ 原理基础题,必会题。
参考答案:
C++的内存分配策略主要包括静态内存分配、栈内存分配和堆内存分配。
- 静态内存分配:静态内存分配是在程序编译阶段完成的,用于存储全局变量和静态变量。这些变量的内存空间在程序启动时就被分配,并在整个程序的生命周期内保持不变。
- 栈内存分配:栈内存分配是由编译器自动管理的,用于存储局部变量和函数调用的上下文信息。栈内存的分配和释放是自动进行的,遵循"先进后出"的原则。当一个函数被调用时,它的局部变量会被分配到栈上,当函数执行完毕时,这些变量会被自动释放。
- 堆内存分配:堆内存分配是由程序员手动管理的,用于存储动态分配的对象。在堆上分配内存需要使用特定的操作符(如new、malloc等),并在不需要时手动释放内存(使用delete、free等)。堆内存的分配和释放不受函数调用的限制,可以在程序的任意位置进行。
静态内存分配适用于全局变量和静态变量,栈内存分配适用于局部变量和函数调用,堆内存分配适用于动态分配的对象。
学习指引:C++内存分配的几种策略
12. c++从编译到运行发生了什么
解析:
C++ 原理题,常考题。
参考答案:
C++程序从编译到运行经历了以下几个步骤:
- 预处理(Preprocessing):在编译之前,预处理器会对源代码进行处理。它会处理以"#"开头的预处理指令,例如#include、#define等,并展开宏定义,删除注释等。预处理后的代码成为编译单元。
- 编译(Compilation):编译器将预处理后的代码翻译成汇编语言。它会进行词法分析、语法分析、语义分析等过程,生成汇编代码。
- 汇编(Assembly):汇编器将汇编代码转换成机器码,生成目标文件(通常是二进制文件)。目标文件包含了可执行代码、数据和符号表等信息。
- 链接(Linking):链接器将目标文件与其他必要的库文件进行链接,生成可执行文件。它会解析符号引用,将目标文件中的符号与其他目标文件或库文件中的符号进行关联,生成最终的可执行文件。
- 加载(Loading):操作系统将可执行文件加载到内存中,并为程序分配运行所需的资源。加载过程包括分配内存空间、建立程序入口点、加载依赖的动态链接库等。
- 运行(Execution):程序开始执行,按照指令序列进行操作。它会分配栈空间、执行全局初始化、调用main函数等。程序执行过程中可能会进行输入输出、调用其他函数、分配和释放内存等操作。
学习指引:一个程序从编译到运行的全过程
13. c++的动态链接和静态链接
解析:
C++ 原理题,难度中等。
参考答案:
C++中的链接可以分为动态链接和静态链接两种方式。
- 静态链接(Static Linking): 静态链接是将所有的目标文件和库文件在编译时链接到可执行文件中。在静态链接的情况下,目标文件中使用的所有函数和库函数的代码都会被复制到最终的可执行文件中。这意味着可执行文件独立于系统中的动态链接库,可以在没有其他依赖的情况下运行。静态链接的优点是执行速度快,不受系统环境的影响。但缺点是可执行文件的体积较大,占用磁盘空间较多。
- 动态链接(Dynamic Linking): 动态链接是在程序运行时将目标文件和库文件链接到可执行文件中。在动态链接的情况下,可执行文件只包含对库函数的引用,而不包含实际的库函数代码。当程序运行时,操作系统会在内存中加载所需的动态链接库,并将其与可执行文件进行链接。动态链接的优点是可执行文件的体积较小,节省了磁盘空间。同时,多个程序可以共享同一个动态链接库,减少了内存的占用。然而,动态链接的缺点是在程序运行时需要查找和加载动态链接库,可能会稍微降低程序的执行速度。
在C++中,可以使用编译器提供的选项来指定链接方式。对于静态链接,可以使用编译器的静态库选项(如"-static"),将库文件静态链接到可执行文件中。对于动态链接,可以使用编译器的动态库选项(如"-shared")生成动态链接库文件,并在编译时指定动态链接库的路径。
选择动态链接还是静态链接取决于具体的需求。静态链接适用于独立的、可移植的可执行文件,而动态链接适用于共享库、模块化的程序设计和资源共享的场景。
学习指引:深入浅出静态链接和动态链接
14. 大小端字节序
解析:
存储相关的常考题,难度中等。
参考答案:
大小端字节序(Endianness)是指在多字节数据类型(如整数、浮点数)在内存中存储时,字节的顺序是从高位到低位还是从低位到高位。
- 大端字节序(Big Endian):在大端字节序中,高位字节存储在低地址,低位字节存储在高地址。例如,十六进制数0x12345678在大端字节序中存储为:0x12 0x34 0x56 0x78。
- 小端字节序(Little Endian):在小端字节序中,低位字节存储在低地址,高位字节存储在高地址。例如,十六进制数0x12345678在小端字节序中存储为:0x78 0x56 0x34 0x12。
选择使用大端字节序还是小端字节序是由硬件架构和操作系统决定的。x86架构的计算机通常采用小端字节序,而一些网络协议(如TCP/IP)通常使用大端字节序。
在C++中,可以使用类型转换和位操作来处理大小端字节序的问题。例如,可以使用memcpy函数将字节序进行转换,或者使用位操作来逐个字节读取和写入数据。
在跨平台开发时,应该考虑字节序的问题,以确保数据在不同平台上的正确解析和传输。
学习指引:字节序(大小端)理解
15. 网络字节序是大端还是小端,本地字节序是大端还是小端
解析:
考的不多,多读几遍有印象即可。
参考答案:
网络字节序是大端字节序,即高位字节存储在内存的低地址端,低位字节存储在内存的高地址端。这种字节序的采用主要是为了不同平台之间的兼容性问题,确保数据在网络传输中的一致性和准确性。
而本地字节序则取决于具体的硬件和操作系统。例如,Intel和AMD的处理器采用的是小端字节序,即低位字节存储在内存的低地址端,高位字节存储在内存的高地址端。然而,也有一些处理器采用大端字节序。因此,在进行网络通信或跨平台编程时,需要注意字节序的转换问题,以确保数据的正确解析和处理。
学习指引:网络字节序为什么使用大端字节序呢?
16. MySQL什么时候会用索引
解析:
MySQL 重点题,常考题,必会题。
参考答案:
MySQL在以下情况下会使用索引:
- 查询条件中的关键字:当查询条件中使用了某个字段的关键字,且该字段上建立了索引时,MySQL会尝试使用索引来加速查询。例如,使用
WHERE
子句中的=
、>
、<
、>=
、<=
等操作符进行条件筛选时,如果相关字段有索引,MySQL通常会利用这些索引。- 联接操作:在进行表联接(如
JOIN
操作)时,如果联接条件中的字段有索引,MySQL会尝试使用这些索引来加速联接过程。- 排序和分组操作:当使用
ORDER BY
或GROUP BY
子句时,如果排序或分组的字段有索引,MySQL可能会利用这些索引来优化排序和分组操作。- 覆盖索引:如果一个查询只需要访问索引中的信息,而无需回表查询原始数据,那么这个索引被称为覆盖索引。当MySQL检测到可以使用覆盖索引时,它会优先使用覆盖索引,因为这样可以避免回表操作,从而提高查询效率。
- 唯一性约束和主键约束:在MySQL中,为表的主键和具有唯一性约束的字段自动创建索引。这些索引不仅用于加速查询,还用于确保数据的唯一性。
虽然索引可以提高查询性能,但它们也会占用额外的磁盘空间,并可能降低写操作的性能(如INSERT、UPDATE和DELETE操作)
。因此,在创建索引时,需要权衡查询性能与存储和写操作的开销。通常建议只对经常用于查询条件、排序、分组或联接操作的字段创建索引。同时,可以通过定期分析查询性能和数据访问模式来确定哪些索引是最有益的。
学习指引:MySQL索引的分类、何时使用、何时不使用、何时失效?
#24届软开秋招面试经验大赏#
收录各个网友分享的各个公司的面经,并给出答案。