C++八股学习day2

字节跳动面经

1、虚拟地址怎么转化到物理地址?

计算机系统的内存由M个连续的字节大小组成,每个字节有一个唯一的物理地址,CPU通过物理地址访问内存,现在采用虚拟寻址将虚拟地址翻译成实际的物理地址,然后再进行物理地址。

虚拟内存,可以理解为是被存放在磁盘上上的N个连续的字节大小的单元数组。这个连续数组被分割成固定大小的虚拟页(VP)。虚拟内存的每一个虚拟页会映射到一个物理页。映射是通过一个页表的结构做到的。

页表,就是一个个页表条目PTE(Page Table Entry)组成的数组。页表条目PTE由一个有效位和一个n位地址字段组成(还有其他字段,这里简化方便解释)。

分段机制把一个逻辑地址转换为线性地址

线性地址是一个32位的无符号整数,可以表达高达2^32(4GB)的地址。 通常用16进制表示线性地址,其取值范围为0x00000000~0xffffffff。 线性地址-分段机制映射之后得到的地址。如果不采用分页机制,那么线性地址和物理地址是相同的。

分页机制把一个线性地址转换为物理地址

MMU 的职责:虚地址和物理地址转换

MMU 是一种硬件电路,它包含两个部件,一个是分段部件,一个是分页部件

2、操作系统中的原子操作是这么实现的?

原子操作理解为不需要用到互斥技术的多线程并发编程技术,在多线程中不会被打断。

变量要么完成,要么没完成,不存在中间态

原子操作意味着不可分割的整体,一个CPU执行过程中不会被其他CPU打断分为三步(READ->Modified->Write)

1) 先read变量的值到CPU内存寄存器; //读:Read

2) 对寄存器的值递增;//改:Modified

3) 将寄存器的值写回变量。//写: Write

3、C++的内存分区和变量存储。


一个由c/C++编译的程序占用的内存分为以下几个部分 :
1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。 局部变量,函数参数等的存储区。他的存储空间是连续的,两个紧密挨着定义的局部变量,他们的存储空间也是紧挨着的。
2、堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,一般由malloc(或new)函数来分配内存块,并且需要用free(delete)函数释放内存。
3、全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域(RW), 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域(ZI)。 - 程序结束后有系统释放 
4、文字常量区 —常量字符串就是放在这里的。 程序结束后由系统释放 (RO)
5、程序代码区—存放函数体的二进制代码。 (RO)

4、初始化的和未初始化的全局变量分别放在什么地方?BSS段的全称是啥?

1.初始化的全局变量存放在数据段(data segment),数据段数据静态分配

2.未初始化的全局变量存放在bss段,BSS是英文Block Started by Symbol的简称。BSS段属于静态内存分配。

BSS段(bss segment)通常是指用来存放程序中未初始化的或者初始值为0的全局变量的一块内存区域。BSS是英文Block Started by Symbol的简称。BSS段属于静态内存分配。

数据段(data segment)通常是指用来存放程序中已初始化的全局变量的一块内存区域。数据段属于静态内存分配

 5、什么是内存对齐?为什么字节对齐。

内存字节对齐目的: 提高CPU访问效率;

64位系统默认进行8字节对齐,32位系统默认进行4自己对齐;

基本数据类型地址是其长度整数倍就可实现内存对齐;

数组中对第一个地址进行对齐后,就可实现内部地址对齐;

结构体对齐规则:

1. 数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员的偏移量是( #pragma pack 指定的数值和这个数据成员自身长度两者之间的较小值)的整数倍。

2. 结构体的整体对齐规则:在数据成员按照 #1 完成各自对齐之后,结构体本身也要进行对齐。对齐会将结构体的大小增加为( #pragma pack 指定的数值和结构体最大数据成员长度)中较小那个值的整数倍。

结构是一种复合数据类型,其构成元素既可以是基本数据类型(如int、long、float等)的变量,也可以是一些复合数据类型(如数组、结构、联合等)的数据单元。在结构中,编译器为结构的每个成员按其自然边界(alignment)分配空间。各个成员按照它们被声明的顺序在内存中顺序存储,第一个成员的地址和整个结构的地址相同

为了使CPU能够对变量进行快速的访问,变量的起始地址应该具有某些特性,即所谓的”对齐”. 比如4字节的int型,其起始地址应该位于4字节的边界上,即起始地址能够被4整除.

6、vector中push_back和emplace_back的区别?

1.push_back() 向容器尾部添加元素时,首先会创建这个元素,然后再将这个元素拷贝或者移动到容器中(如果是拷贝的话,事后会自行销毁先前创建的这个元素);而emplace_back() 在实现时,则是直接在容器尾部创建这个元素,省去了拷贝或移动元素的过程。

2.若vector<pair<,>>这种情况 push_back({x.y}) 要以pair的格式添加, 而emplace_back(x,y) 不需要加{}
3.emplace_black比push_back少一次移动构造,少一次拷贝构造。

7、C++中的多态?说一下虚函数的多态。

C++ 中的虚函数的作用主要是实现了多态的机制。关于多态,说白了就是用父类型别的指针指向其子类的实例,然后通过父类的指针调用实际子类的成员函数(当然引用也可以达到该目的,引用也是指针的另一种变种)。

多态,指完成某个行为,不同的对象去完成时会产生出不同的状态。如:定一个一Animal类,类中包含动物的叫声这种方法,分别定义Dog和Cat类继承自动物类,那么Dog和Cat类中也会包含叫声这种方法,但是他们具体实现是不同的,因为每种动物的声音都不相同,这便是一种多态。

虚函数的定义是在基类中进行的,它是在基类中需要定义为虚函数的成员函数的声明中冠以关键字virtual,从而提供一种接口界面。定义虚函数的方法如下:

virtual 返回类型 函数名(形参表) {
    函数体
}

多态的关键在于通过基类指针或引用调用一个虚函数时,编译时不确定到底调用的是基类还是派生类的函数,运行时才确定。每一个有虚函数的类(或有虚函数的类的派生类)都有一个虚函数表,该类的任何对象中都放着虚函数表的指针。

8、内联函数?内联函数的缺点?

内联函数是指用inline关键字修饰的函数。在类内定义的函数被默认成内联函数。内联函数从源代码层看,有函数的结构,而在编译后,却不具备函数的性质。不是在调用时发生控制转移,而是在编译时将函数体嵌入在每一个调用处。编译时,类似宏替换,使用函数体替换调用处的函数名。一般在代码中用inline修饰,但是能否形成内联函数,需要看编译器对该函数定义的具体处理。

优点

1、内联函数,编译器将会根据上下文环境进一步深度优化代码,而这一点是普通函数无法达到的作用
2、省略了函数调用压入堆栈和弹出堆栈所用的时间
3、常用于高频使用的函数,可以提高时间

缺点

1、编译之后代码量会偏多,内联可以说是一种以空间换取时间的方法。牺牲一定的空间来加速运行时间。增加的代码量取决于函数调用次数和函数本身的大小
2、内联函数实现的更改往往并不可以保持链接兼容性,也就是说这样的更改需要用户重新编译他们的代码

9、tcp的可靠传输?拥塞控制?流量控制?

【计算机网络-传输层】TCP可靠传输、TCP流量控制、拥塞控制

可靠:保证接收方进程从缓存区读出的字节流与发送方发出的字节流是完全一样的。

TCP 实现可靠传输的机制

  1. 校验
  2. 序号
  3. 确认
  4. 重传

2.TCP的流量控制,TCP 提供流量控制服务来消除发送方(发送速率太快)使接收方缓存区溢出的可能性,因此可以说流量控制是一个速度匹配服务(匹配发送方的发送速率与接收方的读取速率)

TCP 提供一种基于滑动窗口协议的流量控制机制。

在通信过程中,接收方根据自己接收缓存的大小,动态地调整发送方的发送窗口大小,即接收窗口rwnd (接收方设置确认报文段的窗口字段来将 rwnd通知给发送方) ,发送方的发送窗口取接收窗口rwnd和拥塞窗口cwnd的最小值。
 

3.TCP的拥塞控制出现拥塞的条件:
对资源需求的总和 > 可用资源

网络中有许多资源同时呈现供应不足 → \rightarrow→ 网络性能变坏 → \rightarrow→ 网络吞吐量将随输入负荷增大而下降

拥塞控制: 防止过多的数据注入到网络中。

10、IP数据报的报头字段?TTL的设置了解过吗?

TTLIP协议包中的一个值,指定数据报被路由器丢弃之前允许通过的网段数量。(IP数据包在计算机网络中可以转发的最大跳数)

1.TTL的作用是限制IP数据包在计算机网络中的存在的时间。TTL的最大值是255,TTL的一个推荐值是64。

虽然TTL从字面上翻译,是可以存活的时间,但实际上TTL是IP数据包在计算机网络中可以转发的最大跳数。

3,TTL字段由IP数据包的发送者设置,在IP数据包从源到目的的整个转发路径上,每经过一个路由器,路由器都会修改这个TTL字段值,具体的做法是把该TTL的值减1,然后再将IP包转发出去。

4,如果在IP包到达目的IP之前,TTL减少为0,路由器将会丢弃收到的TTL=0的IP包并向IP包的发送者发送 ICMP time exceeded消息。

5, TTL 是由发送 主机 设置的,以防止数据包不断在 IP 互联网络上永不终止地循环。转发 IP 数据包时,要求路由器至少将 TTL 减小 1。


 TTL的主要作用是避免IP包在网络中的无限循环和收发,节省了网络资源,并能使IP包的发送者能收到告警消息。

11、怎么实现断点续传?

断点续传是指在网络传输中,当传输过程中出现异常或者用户主动停止传输时,能够恢复传输过程,避免重新传输已经传输过的数据,提高传输效率。实在HTTP协议中,通过设置请求头Range来实现断点续传。Range头指示服务器返回指定范围的响应内容现断点续传可以通过以下方式:

Range: bytes=500-999

文件分块下载

文件分块下载是指将文件分成若干个固定大小的块,分别下载每个块,从而实现断点续传。客户端可以记录已经下载的块的信息,下次继续下载时,跳过已经下载的块,下载未下载的块。文件分块下载可以使用HTTP或FTP等协议进行实现。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值