0
点赞
收藏
分享

微信扫一扫

C++相关八股-3

1.系统调用

内核提供给用户空间访问外部等受限资源(外设、网络)的编程接口,用户层可通过这个接口访问内核资源

步骤:(宏观上) 应用程序 -> 函数库 -> 系统调用 -> 内核资源

中断:软中断和硬中断(系统调用为软中断,用用户态切换到内核态)

中断号: 软中断 int 0x80

中断处理程序:内核线程来执行

中断向量表:通过中断号来查找对应的中断处理程序

系统调用的流程:触发中断 -> 切换堆栈 -> 执行中断程序 -> 从中断处理程序返回

样例:int n = read(fd, buf, sz); 系统调用号 -> 存到eax寄存器;int 0x80 执行软中断;用户态切换到内核态; 0x80 -> system_call; eax->系统调用号 -> 系统调用表 -> 处理函数 sys_read; iret 将返回值返回并从内核态切换到用户态

系统调用是否引起进程/线程的切换?不一定。int n = read(fd, buf, sz); fd 是 一个阻塞IO

如果使用阻塞的IO且IO未就绪,将进行线程或进程切换;运行态 -> 阻塞态; fcntl(fd,O_NONBLOCK) 使用非阻塞IO 则会立即返回 n=0,errno =EWOULDBLOCK

用户态切换成内核态 切换堆栈 指的是切换中断上下文,首先进程状态会发生改变 task_strust 里面有一个状态会从用户态切换成内核态;保存运行现场 :cpu寄存器存储的是用户态的指令(用户态指令暂时存储在*stack) 转为存储内核态的指令

2.TCP和UDP区别

相同点:都是传输层的协议 目的是为上层应用层提供服务;

是否面向连接:TCP是面向连接的,要建立数据收发通信,首先要进行三次握手,随后客户端和服务端才可以互相发送数据,这条连接出现异常或者主动断开,要进行四次挥手断开连接(端对端的连接)(全双工通信);UDP是面向无连接的, 支持1v1 1v多 多v1 多v多 发送数据,无需三次握手四次挥手;

数据传输方式:TCP基于字节流传输(需要处理粘包的问题,UDP不需要处理粘包问题,TCP完整的用户消息可能被拆分成多个TCP报文进行传输),如果使用TCP传输且发送的数据大于MSS(1500 - 20(IP头) - 20(TCP头) = 1460),则进行分段,在IP层如果大于MTU(1500字节),还可能进行分片,用户的数据在经过传输层时使用TCP则可能进行拆分 ;UDP基于报文传输,每次收发都是完整的报文传输;

是否可靠:TCP可靠传输,1.TCP分段,IP层分片,进行发送数据包的控制,2.序列号(确保完整接收,丢失重复数据,接收端排序重组),为什么需要序列号,数据包确认机制数据包确认应答机制,为什么三次握手时需要随机序列号,前面的历史连接可能会干扰当前的连接,3.校验和:检测报文在传输过程中的数据变化,避免数据被篡改,4.滑动窗口: 实现流量控制,防止包丢失,5.拥塞控制, 6.超时重传机制,;UDP不可靠传输,不保证消息交付,不保证交付顺序,不进行拥塞控制,不进行流量控制(没有接收缓冲区);

传输效率:TCP效率低,TCP实现可靠传输造成性能损失,TCP头20个字节,UDP效率高,UDP不可靠,头部8个字节;

应用场景:TCP要求数据可靠,对速度要求不高;UDP实时性要求高;

3.TCP如何保证可靠性

重传机制:解决数据丢失问题。通过序列号和确认应答机制(定时器)实现。怎么重传:超时重传 (如果在时间内没有收到就进行重传),快速重传(超时之前收到了三个相同的数据包确认,直接重传丢失的数据)到底是重传一个还是重传所有的包,SACK: TCP头部信息选项中有40个字节,这个SACK里面包含需要重传什么数据,只需重传丢失的数据。DSACK:把重复收到的包通过SACK告诉发送方,解决了(发送方) 判断是数据包丢失了还是ACK包丢失了还是网络超时。

滑动窗口:解决的问题(无需为数据包应答),窗口(没有应答的情况下,发送方可以发送多少数据),滑动(收到确认包后就会移动),发送方的滑动窗口是由接收方来决定的。

流量控制:解决的问题(解决通过接收方的处理能力来限制发送方发送的数据量,避免产生丢包),怎么控制(先收缩窗口,再缩小缓冲区)

拥塞控制:解决网络拥塞问题,避免出现延时丢包等问题。方式:慢启动

4.malloc是如何分配内存的,free怎么知道该释放多少内存

背景:进程启动的时候操作系统会提供虚拟内存空间,malloc 分配的是虚拟内存,进程虚拟内存空间的分配(从低地址往高地址:代码段(二进制可执行代码),已初始化的数据段(静态常量),未初始化的数据段,堆段(从低地址往高地址扩展,动态分配),文件映射段(动态库、共享内存),栈段(由高地址往低地址,局部变量和函数调用上下文等),内核空间)

分配的是虚拟内存,使用时才会分配真实的物理内存,如何分配:缺页异常(中断),分为2种情况:如果要分配的内存小于128K,便会从堆栈进行分配;如果大于等于128K,是通过mmap在文件映射区进行分配的。

是不是系统调用名:不是 是C库函数。小于128K通过brk系统调用从堆段分配, 为了减小频繁的上下文切换,malloc维护了一个内存池,优先从内存池进行分配,缺点:增加内存碎片。大于128K通过mmap系统调用从文件映射区分配内存。

free 释放内存后,内存还在吗:通过brk分配的内存释放后,会归还给内存池,通过mmap分配的内存立刻归还给操作系统。在通过malloc申请内存时,会多申请16字节空间用来存放申请的内存大小以及其他描述信息,在释放内存时,指针会向左偏移16字节,读取内存块信息,从而得知需要释放多大的空间

举报

相关推荐

0 条评论