小米(二)21.11.02 二面

1、自我介绍

2、堆和栈的区别

首先从内存角度来说,堆中存放的数据可以通过malloc、realloc、new这些操作来进行申请,栈中的内存可以通过定义变量或指针来进行申请,堆和栈在内存结构中的划分一个处于上部为,一个处于下部,才内存结构中,首先是内核区、接着就是栈区、下来是内存映射段,下来就是堆区,由于有了这样的内存结构,所以栈区内存生长方向是向下生长,堆区的内存生长方向是向上增长

1.3 堆与栈区别

堆与栈实际上是操作系统对进程占用的内存空间的两种管理方式,主要有如下几种区别:
(1)管理方式不同。栈由操作系统自动分配释放,无需我们手动控制;堆的申请和释放工作由程序员控制,容易产生内存泄漏;

(2)空间大小不同。每个进程拥有的栈大小要远远小于堆大小。理论上,进程可申请的堆大小为虚拟内存大小,进程栈的大小 64bits 的 Windows 默认 1MB,64bits 的 Linux 默认 10MB;

(3)生长方向不同。堆的生长方向向上,内存地址由低到高;栈的生长方向向下,内存地址由高到低。

(4)分配方式不同。堆都是动态分配的,没有静态分配的堆。栈有 2 种分配方式:静态分配和动态分配静态分配是由操作系统完成的,比如局部变量的分配。动态分配由alloca()函数分配,但是栈的动态分配和堆是不同的,它的动态分配是由操作系统进行释放,无需我们手工实现。

(5)分配效率不同。栈由操作系统自动分配,会在硬件层级对栈提供支持:分配专门的寄存器存放栈的地址,压栈出栈都有专门的指令执行,这就决定了栈的效率比较高。堆则是由C/C++提供的库函数或运算符来完成申请与管理,实现机制较为复杂,频繁的内存申请容易产生内存碎片。显然,堆的效率比栈要低得多。

(6)存放内容不同。栈存放的内容,函数返回地址、相关参数、局部变量和寄存器内容等。当主函数调用另外一个函数的时候,要对当前函数执行断点进行保存,需要使用栈来实现,首先入栈的是主函数下一条语句的地址,即扩展指针寄存器的内容(EIP),然后是当前栈帧的底部地址,即扩展基址指针寄存器内容(EBP),再然后是被调函数的实参等,一般情况下是按照从右向左的顺序入栈,之后是被调函数的局部变量,注意静态变量是存放在数据段或者BSS段,是不入栈的。出栈的顺序正好相反,最终栈顶指向主函数下一条语句的地址,主程序又从该地址开始执行。堆,一般情况堆顶使用一个字节的空间来存放堆的大小,而堆中具体存放内容是由程序员来填充的。

从以上可以看到,堆和栈相比,由于大量malloc()/free()或new/delete的使用,容易造成大量的内存碎片,并且可能引发用户态和核心态的切换,效率较低。栈相比于堆,在程序中应用较为广泛,最常见的是函数的调用过程由栈来实现,函数返回地址、EBP、实参和局部变量都采用栈的方式存放。虽然栈有众多的好处,但是由于和堆相比不是那么灵活,有时候分配大量的内存空间,主要还是用堆。

无论是堆还是栈,在内存使用时都要防止非法越界,越界导致的非法内存访问可能会摧毁程序的堆、栈数据,轻则导致程序运行处于不确定状态,获取不到预期结果,重则导致程序异常崩溃,这些都是我们编程时与内存打交道时应该注意的问题。

3、虚函数的原理,多态底层的实现

虚函数底层通过一张虚表来存储各个虚函数的入口地址,而这张虚表的地址存放在类的内存模型中的前四个字节中(32位下),编译器通过类中前四个字节的这块地址来访问这个虚表,然后通过这张虚表对其他虚函数进行入口访问,而这张虚表是在构造函数后就完成了对这块虚表即虚表指针的初始化

多态就是不同的对象处理访问同一个函数而产生了不同的效果,这些对象都被基类的指针进行调用,然后调用他们之间功能不同的虚函数的实现,

4、看代码,计算带有虚函数的类大小

所有虚函数就占用一个指针大小的内存(32位4字节)

5、空类大小用sizeof计算为多少,为什么

因为空类也需要实例化,如果进行实例化了,那么就必须需要一段空间来存储这个实例化的对象,所谓实例化就是要在内存空间中为对象分配一块地址,而对于空类来说,在Vs2019编译器下为它分配的空间是1个字节

为1,因为创建的空类之间也有它们自己的不同的地方,比如类型存储地址等,所以需要内存才能来对其进行区分

6、了解C++11的一些锁机制吗

互斥锁:互斥锁的本质就是一个0-1计数器,它的实现目的就是为了避免同一时间多个线程对同一个共享资源的访问,0表示不可访问,1表示可以访问,它的运行机制就是在访问资源前获取锁资源,在访问资源后释放锁资源,多个线程想要实现互斥,就必须得访问同一把锁

接口有pthrea_mutex_t定义一个互斥锁变量,pthread_mutex_init初始化互斥锁,也可以通过一种宏来定义一个不需要后续销毁操作的互斥锁,pthread_mutex_lock上锁、pthread_mutex_trylock非阻塞上锁,pthread_mutex_unlock解锁,pthread_mutex_destroy销毁锁

7、内存管理机制有了解吗

分页式、分段式、段页式

分段式:关键的俩个部分就是段表和地址组成,地址组成中分为段号和偏移量,然后通过这个段号访问到对应的段表项,接着由段表项就能获得一块内存起始地址,最终我们需要的实际物理地址就是这个内存起始地址加上这个偏移量。

分页式内存管理方式,通过分页将内存分为一页一页的存储结构,在虚拟地址中得到一块页号,通过这个页号找到一个页表项,然后获得一块内存起始地址,加上偏移量就是实际物理地址

分段式更利于地址管理,分页式的内存利用更加高效

段页式就是将内存先进行分段,在每段内又进行分页,然后每个分页中采用分段的结构(集合了分段式与分页式的优势)

8、讲一下tcp的三次握手

9、为什么是三次不是四次

10、tcp和udp的区别

tcp是面向连接的、可靠稳定的、基于字节流传输的通信方式

        面向连接:在通信前确保双方具有收发数据的能力

        可靠稳定:采用大量的控制机制,保证数据能够有序完整且一致的到达对端

        字节流传输:可以一次性传递大量数据的一种方式,没有传输限制

udp是无连接的。不可靠的。基于数据报的传输通信方式

        无连接:传输数据时不需要建立连接,只需要知道对方的地址就能发送数据

        可靠稳定:它只需要知道对方地址就能发送,但是不能保证数据安全稳定的传输到对端

        基于数据报:有最大大小数据传输限制,且传输交付也有大小限制的一种方式

由于UDP没有控制限制,所以UDP的通信速度快,对于实时性要求高于安全性要求的可使用UDP

11、select和epoll的区别

12、七层模型将一下各层的作用

应用层

网络服务与最终用户的一个接口。

协议有:HTTP FTP TFTP SMTP SNMP DNS TELNET HTTPS POP3 DHCP

表示层

数据的表示、安全、压缩。(在五层模型里面已经合并到了应用层)

格式有,JPEG、ASCll、EBCDIC、加密格式等 [2] 

会话层

建立、管理、终止会话。(在五层模型里面已经合并到了应用层)

对应主机进程,指本地主机与远程主机正在进行的会话

传输层

定义传输数据的协议端口号,以及流控和差错校验。

协议有:TCP UDP,数据包一旦离开网卡即进入网络传输层

网络层

进行逻辑地址寻址,实现不同网络之间的路径选择。

协议有:ICMP IGMP IP(IPV4 IPV6)

数据链路层

建立逻辑连接、进行硬件地址寻址、差错校验 [3]  等功能。(由底层网络定义协议)

将比特组合成字节进而组合成帧,用MAC地址访问介质,错误发现但不能纠正。

物理层

建立、维护、断开物理连接。(由底层网络定义协议)

13、算法:二叉树的前中后序遍历

14、算法:股票123

15、反问

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值