面经总结——腾讯面试题汇总(一)

1.i++是不是原子操作,++i呢?

答:i++不是原子操作,++i也不是原子操作。
原子操作是指不会被线程调度机制打断的操作;这种操作一旦开始,就一直运行到结束,中间不会切换到另一个线程。
i++其实一共做了三次指令操作,第一次,从内存中读取i变量的值到CPU的寄存器,第二次在寄存器中的i自增1,第三次将寄存器中的值写入内存。这三次指令操作中任意两次如果同时执行的话,都会造成结果的差异性。
而对于++i,在多核机器上,CPU在读取内存时也可能同时读到同一个值,这样就会同一个值自增两次,而实际上只自增了一次,所以++i也不是原子操作。

2.红黑树查找时间复杂度?哈希查找时间复杂度?

AVL树和红黑树详讲

哈希详讲

答:红黑树的时间复杂度为Olog(n);哈希查找时间复杂度为Olog(1).

3.哈希一个字符串,输出的结果是什么?

4.平时如何调试代码?简述gdb调试的用法?

linux下gdb调试方法与技巧整理

5.简述三次握手,三次握手之后建立的连接就可靠了吗?

TCP连接的特点:面向连接的、可靠的、基于字节流的传输层通信协议。
所谓三次握手(Three-Way Handshake)即建立TCP连接,就是指建立一个TCP连接时,需要客户端和服务端总共发送3个包以确认连接的建立。在socket编程中,这一过程由客户端执行connect来触发,整个流程如下图所示:在这里插入图片描述(1)第一次握手:Client将标志位SYN置为1,随机产生一个值seq=x,并将该数据包发送给Server,Client进入SYN_SENT状态,等待Server确认。
(2)第二次握手:Server收到数据包后由标志位SYN=1知道Client请求建立连接,Server将标志位SYN和ACK都置为1,ack=x+1,随机产生一个值seq=y,并将该数据包发送给Client以确认连接请求,Server进入SYN_RCVD状态。
(3)第三次握手:Client收到确认后,检查ack是否为x+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=y+1,并将该数据包发送给Server,Server检查ack是否为y+1,ACK是否为1,如果正确则连接建立成功,Client和Server进入ESTABLISHED状态,完成三次握手,随后Client与Server之间可以开始传输数据了。

6.简述四次挥手,TIMEWAIT状态出现的时机和原因?

四次挥手,别名连接终止协议。其性质为终止协议。
四次挥手即终止TCP连接,就是指断开一个TCP连接时,需要客户端和服务端总共发送4个包以确认连接的断开。在socket编程中,这一过程由客户端或服务端任一方执行close来触发
在这里插入图片描述
第四次挥手时,Client接收到Fin后,并没有立即进入CLOSED状态,而是进入TIME_WAIT状态,这是为什么呢?
(1)Client不能保证最后的ACK能到达Server,所以还应该观望一段时间,护送一段时间。如果最后的ACK丢失,那么Server显然收不到,于是Server发起了重传FIN的操作,此时如果Client处于CLOSED状态,就无法重发ACK了。所以Client要等待一个2MSL的时间,这段时间就是TIME_WAIT。
因而,要实现TCP全双工连接的正常终止,必须处理终止过程中四个分节任何一个分节的丢失情况,主动关闭连接的Server端必须维持TIME_WAIT状态 。
2)允许老的重复分节在网络中消逝。TCP分节可能由于路由器异常而“迷途”,在迷途期间,TCP发送端可能因确认超时而重发这个FIN包,迷途的分节在路由器修复后也会被送到最终目的地,这个迟到的迷途分节到达时可能会引起问题。在关闭“前一个连接”之后,马上又重新建立起一个相同的IP和端口之间的“新连接”,“前一个连接”的迷途重复分组在“前一个连接”终止后到达,而被“新连接”收到了。为了避免这个情况,TCP协议不允许处于TIME_WAIT状态的连接启动一个新的可用连接,因为TIME_WAIT状态持续2MSL,就可以保证当成功建立一个新TCP连接的时候,来自旧连接重复分组已经在网络中消逝。

7.如何用到TCP、UDP协议?

一文了解TCP/UDP协议

TCP与UDP的区别:
1) TCP提供面向连接的传输,通信前要先建立连接(三次握手机制); UDP提供无连接的传输,通信前不需要建立连接。
2) TCP提供可靠的传输(有序,无差错,不丢失,不重复); UDP提供不可靠的传输
3) TCP面向字节流的传输,因此它能将信息分割成组,并在接收端将其重组; UDP是面向数据报的传输,没有分组开销。
4) TCP提供拥塞控制和流量控制机制; UDP不提供拥塞控制和流量控制机制。

UDP应用场景
1.面向数据报方式
2.网络数据大多为短消息
3.拥有大量Client
4.对数据安全性无特殊要求
5.网络负担非常重,但对响应速度要求高

8.多线程和多进程用哪个好?什么情况下用多线程?

线程和进程有什么区别?
  • 进程是程序的一次执行。线程可以理解为进程中执行的一段程序片段。
  • 进程间式独立的,这表现在内存空间,上下文环境;线程运行在进程空间内。一般来讲,进程无法突破进程边界存取其它进程内的存储空间;而线程由于处于进程空间内,所以同一进程所产生的线程共享在同一内存空间。
  • 同一进程中的两段代码不能够同时执行,除非引入线程。
  • 线程是属于进程的,当进程退出时该所产生的线程都会被强制退出并清除。线程占用的资源要少于进程所占的资源。进程和线程都可以有优先级。
  • 进程间可以通过IPC通信,但线程不可以。
何时使用多进程,何时使用多线程?
  • 对资源的管理和保护要求高,不限制开销和效率时,使用多进程。
  • 要求效率高,频繁切换时,资源的保护管理要求不是很高时,使用多线程。

9.进程间通信方式?线程间通信方式?

进程间通信

管道(pipe):管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用进程间的亲缘关系通常是指父子进程关系。
命名管道(named pipe/FIFO):命名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信。
信号量(semophonre):信号量是一个计数器,可以用来控制多个进程队共享资源的访问。它常作为一个锁机制,防止某进程在访问共享资源时,其他进程也访问此资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。
消息队列(message queue):消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少,管道只能承载无格式字节流以及缓冲区大小受限等缺点。
信号(sinal):信号是一种比较复杂的通信方式,用于通知接受进程某个事件已经发生。
共享内存(shared memory):共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的ipc通信方式,它是针对其他进程间通信方式运行效率低而专门设计的。它往往和其他通信方式如信号量,配合使用来实现进程间的同步和通信。
套接字(socket):套接字也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同设备间的进程通信。
全双工管道:共享内存、信号量、消息队列、管道和命名管道只适用于本地进程间通信,套接字和全双工管道可用于远程通信,因此可用于网络编程。

线程间通信

锁机制:包括互斥锁、条件变量、读写锁
互斥锁:提供了以排他方式防止数据结构被并发修改的方法。
读写锁:允许多个线程同时共享数据,而对写操作是互斥的。
条件变量:可以以原子的方式阻塞进程,直到某个特定条件为真为止。对条件的测试是在互斥锁的保护下进行的。条件变量始终与互斥锁一起使用。
信号量机制(Semaphore):包括无名进程信号量和命名线程信号量
信号机制(Signal):类似进程间的信号处理

10.文件传输中的断点续传是如何实现的?

断点续传的实现原理

11.I/O复用模式(LT/ET)的使用场景?

linux 中IO多路复用epoll函数的ET和LT工作模式详解

12.讲讲I/O复用中的select?

I/O多路转接之select

13.fork()后子进程和父进程的返回值分别是什么?

答:父进程fork()之后返回值为子进程的pid号,而子进程fork()之后的返回值为0。

fork函数详讲
  • fork函数的特点概括起来就是“调用一次,返回两次”,在父进程中调用一次,在父进程和子进程中各返回一次。
  • fork的另一个特性是所有由父进程打开的描述符都被复制到子进程中。父、子进程中相同编号的文件描述符在内核中指向同一个file结构体,也就是说,file结构体的引用计数要增加。

猜你喜欢

转载自blog.csdn.net/weixin_44826356/article/details/107053990