【面试复习一】

面试复习篇一

  1. 如何判断两个浮点数相同
    a. 浮点数的存储方式是小数科学计数法,不能直接使用==好进行判断
    b. 对于数量级较小的数可以使用绝对值误差的方式进行判断——fabs(a - b) < eps——float的精度一般是1.0e-6,双精度的是1.0e-15
    c. 对于数量级较大的可以使用相对误差的方式进行判断——fabs(a - b) < eps * fabs(a)
  2. 如何判断两个结构体相等
    a. 不能使用memcpy进行判断,因为memcpy函数是逐个字节进行判断的,而因为结构他对齐的缘故,字节对齐时字节的内容是随机的无法进行比较
    b. 一般是使用从重载的方式进行判断
  3. C++引用参数和指针参数传参的区别是什么
    a. 语法:指针需要解引用访问数据,引用不用
    b. 可能性:引用定义必须要初始化,指针在任何时候都可以指向另一个对象
    c. 大小:引用不占空间只是起一个别名,指针占据空间存储变量的地址
    d. 指针可以执行空,但是引用必须指向一个对象
    e. 能力:应用绑定后不可以改变,指针在任何时候都可以指向不同的对象
  4. printf函数的压栈方式
    a. printf处理多个参数的时候会从右往左一次压栈
    b. 动态变化参数:从右往左可以更好的确定参数的个数,同样也可以保证参数在按照正确的方式出栈
    c. 符合编程习惯:大多数编程语言和函数在设计的时候都遵从从右往左的规则
  5. TCP为什么是三次握手,如何确认的通信双方都有收发数据的能力
    a. 其实如果完整来说的话是四次握手,四次握手简单化就是一问一答进行两次,三次握手是保证数据可靠传输的重要手段之一,只不过在进行连接的时候回应一段会进行捎带应答,会将发起请请求连接和ACK应答同时填充,这样做可以确保双都是可以通信的。
    b. 双方都接收到了对方的ACK应答。
  6. TCP三次握手交换了那些数据
    a. 同步序列编号SYN,确认应答序号(ACK),初始序列号
  7. TCP的报文字段
    a. 16位目的/源端口号
    b. 32位序号/确认序号
    c. 4位头部长度
    d. 6位保留字(SYN,ACK,FIN,RST,PSH,URG)
    e. 16位窗口大小
    f. 16位校验和
    g. 16位紧急指针
  8. 四次挥手
    a. 客户端和服务器双方都可以主动提出端口连接,在传输报文中包含那FIN即可
    b. 四次挥手为什么不能是三次挥手
    i. 中间的两次在大多数情况是不能进行合并的,即不能进行捎带应答,发送ACK和FIN的时机是不同的,当一方发送了FIN请求断开连接时对方的内核会立马返回ACK确认机制这是由内核完成的,但那时当要返回FIN时,这个时由用户代码决定的例如close(fd)这样的操作。
    c. 并且主动提出断开连接的一方在最后会有一段时间处于TIME_WAIT状态
    i. 这样做的好处有:可以出发对方的超时重传,如果最后依次ACK对方没有收到会重新发起一次FIN
    ii. 确保在断开连接时确保双发的数据已经传输完成了,防止后期再次启动时会有残留数据影响。
  9. 四次挥手等待2MSL事件的理由
    a. 确保最后一次ACK报文可以到达对方,因为主动发起断开连接的一方的最后一次ACK不能确保是是否到达对方了,而这2MSL时间段中,如果对方没有收到来自主动方的ACK就会触发来自接收方的超时重传。
    b. 防止已经失联的连接请求报文段出现在本链接中,也就是将所有连接都能断开,如果立即断开的话,有些还保持这来连接状态的话,可能就还会发送数据,同时也可以做到将还处于连接状态的中的数据消除,防止下一次重启的时候残留数据的影响。
  10. 进程和线程的区别和联系
    a. 定义方面
    i. 进程是承担系统分配资源的实体,同一进程内线程共享其资源
    ii. 线程是CPU调度的基本单位
    b. 一个进程中可以有多个线程,但是至少要有一个线程
    c. 创建方面
    i. 线程创建的代价更小,只需要创建对应的TCB,共享同一地址空间
    ii. 进程创建则需要创建PCB,地址空间,页表等
    d. 调度方面
    i. CPU调度一个进程其实真正调度的是进程中的线程线程,在linux其实叫做轻量级进程
    ii. 调度进程的代价比调度线程的代价要高
    e. 进程/线程切换方面
    i. 线程切换只需要切换TCB和自身上下文数据,由于线程是共享进程的资源的,所以在切换到时候并不需要每次都加载地址空间的数据
    ii. 而进程切换则需要切换地址空间,页表,映射关系,特别是上下切换catch寄存器中的数据消耗大。
  11. 进程通信的方式
    a. 管道
    b. System V
    i. 消息队列
    ii. 共享内存
    iii. 信号量
    c. POSIX IPC
  12. main函数是怎么开始的
    a. main函数其实也是被操作系统中的函数调用的
    b. main函数在被调用之前操作系统要先为main函数开辟栈空间,初始化全局变量等
  13. 为什么升序要建大堆
    a. 大堆的特点是所有的父亲节点都会比他的左右孩子大,并且大堆是使用数组实现的
    b. 而实现堆排的原理则是将根节点与未排序的最后一个节点进行交换,然后再进行一次向下调整,而在这个过程中如果是小堆的话根节点是所有元素中最小的那个,无法实现升序的效果。
  14. C语言中extern关键字的作用
    a. 声明外部函数/变量,避免可能使用include导致重复定义的问题
    b. 连接不同源文件,extern关键字确保当前源文件的外部符号与其他文件保持一致
    c. 连接指定的C标准库
    d. 声明外部连接,extern声明的函数/变量具有外部连接属性,这些函数/变量在其他文件中是可见的。
  15. TCP和UDP的适用场景
    a. TCP对于数据的完整性和顺序性要求比较高,比如网页浏览,文件传输,电子邮件等
    b. UDP适用于一些实时性高的场景,可以容忍一些丢包情况,比如在线视频,语音通话,时事游戏等。
  16. 智能指针
    a. 智能指针利用RAII(资源获取即初始化)思想
    b. 智能指针的使用的主要用途就是为了防止内存泄漏问题
    c. auto_ptr
    i. 坑货,会导致对象悬空
    d. unique_ptr
    i. 不能拷贝构造于赋值拷贝
    e. share_ptr
    i. 引入引用计数,可以进行拷贝构造和赋值构造
    ii. 但是会出现循环引用
    iii. 引用weak_ptr不遵从RAII,不会使引用计数增加,用来解决share_ptr的循环引用
  17. 如果刚判断玩shared_ptr存在,正准备使用,此时引用计数变为0,会发什么
  18. socket编程
  19. 网络面试
    a. 三天吃透计算机网络面试八股文 - 知乎
  20. 数据库查询优化的几种思路
    a. 使用索引,在经常查询的列上建立索引,但是同时也不能有过多的索引
    b. 优化查询语句,适当使用关键字
    c. 避免子查询
  21. XML和JSON的区别
    a. 浅析XML和JSON的区别 - 知乎 (zhihu.com)
    b. 可拓展性:XML有很好的可拓展性,当然JSON也是的
    c. 编码难度:JSON的编码比XML简单很多,但是XML有丰富的编码工具
    d. 解码难度:XML的解码难度会比较高,但是JSON的解码难度很简单
    e. 数据体积方面:JSON相对于XML来讲,数据体积小,传输数据块。
  22. AVL数和红黑树的区别和使用场景
    a. 旋转规则不同
    i. AVL数的旋转规则是所有父节点的的左右孩子的高度差不得超过1
    ii. 红黑树的的规则是最长路径不得超过最短路径的2倍,根节点和叶子节点都是黑色的,所有红色节点的孩子都是黑色节点,从任意一个节点到叶子节点上的所有的所有路径的黑色节点的个数都是相同的。
    b. 适用场景
    i. AVL树多用于多数用于查询操作,删除和修改操作较少的场景
    ii. 红黑树则是多用于删除,修改操作较多的场景下
  23. 多线程怎么调试
  24. 内存泄漏的解决思路
    a. 出现内存泄漏的一般情况
    i. 未释放动态申请的内存
    ii. 适用share_ptr是造成的循环引用
    iii. 异常导致资源未释放
    iv. 虚析构,父类的虚构函数没有定义成虚构函数,会导致子类无法析构——STL中的大部分容器都不支持继承,因为他们的析构没有提供虚函数
    b. 避免内存泄漏方法
    i. 使用智能指针
    ii. RAII思想(资源获取即初始化)
    iii. 使用内存泄漏的检测工具——Valgrind(动态工具),cppcheck(静态工具)
  25. Linux中查看内存使用情况的指令有哪些
    a. free
    b. cat /proc/meminfo
    c. vmstat
    d. top
    e. 检查 Linux 中内存使用情况的 8 条命令 - 知乎 (zhihu.com)
  26. select,poll,epoll的优缺点
    a. select的优缺点
    i. 优点
    1) 可以同时关注多个文件描述符
    ii. 缺点
    1) 关注的文件描述符有限,具体要看fd_set的大小、
    2) 输入输出参数混合使用,每次使用都需要重新定义
    3) 每次调用select的时候都需要手动设置fd集,并且每次调用都需要将用户级数据拷贝到内核中,开销大
    4) 在内核中采用的是遍历的方式进行查询就绪的fd,并且会把所有的fd集重新拷贝回用户级中,同样开销大
    b. poll的优缺点
    i. 优点
    1) 没有最大关注文件描述符上线
    2) 输入输出参数没有混合即监听事件和返回事件进行分离
    ii. 缺点
    1) 底层同样采用轮询的方式遍历,效率低
    2) 每次调用poll的时候同样要将用户级数据拷贝到内核中,开销同样大
    c. epoll的优缺点
    i. 优点
    1) 同样没有最大关注描述符上线
    2) 底层实现不是使用循环的方式遍历,而是通过维护一个就绪队列,通过回调的方式添加到就绪队列中,并且只会返回就绪队列中的事件
    ii. 缺点
    1) 在关注的事件比较少的时候性能可能没有select,poll的性能好,因为维护就绪队列以及回调函数也是需要开销的。
  27. epoll LT/ET模式
    a. LT水平触发
    b. ET边缘触发
  28. 介绍一个下项目中的http协议,以及它和https协议有什么不同
    a. Http
    i. http协议属于TCP/IP四层协议中的应用层协议,是一种无连接,无状态的协议,其中http协议中有请求报文和响应报文,所对应的报文格式略有不同,但是总体可以分为三部分,请求/响应行,请求/响应报文,请求/响应正文,其中正文和有效载荷通过一行空行进行分割。而请求报文是通过报文中的的URL(同一定位资源符)来确定数据的位置的,在计算机中可以通过ip+port+url的方式唯一确认计算机网路中的唯一一台主机中的的对应url路径下的数据。而请求的方式有分很多种,但是最常用的两种是get(通过url的方式发送),和post(通过添加到正文中的方式进行发送)方法。请求/响应报文中有很多的其他属性。
    b. Https
    i. 其实就是在http层添加了一层加密层,https的加密方式时使用(非堆成加密+堆成加密+证书认证)的方式进行加密。
  29. session是如何实现的,cookie字段怎么设置的
    a. 当客户端第一次发起请求时,服务器会通过特殊的算法生成唯一的可与session id,并将id和客户的信息形成映射关系,并通过cookie的方式发送给客户端。
    b. 在客户第一次发出请求的时候,服务器回在响应报文中添加set-cookie字段,在客户端接收到这个字段后回对其进行保存,在下一次发请求的时候自动回带上该字段。
  30. 当用户打开多个相同的网页时,如何保证网页的内容,用户的信息是一致的
    a. 在进行网页打开时,无非就是一次http请求,而如果用户不是第一次进行请求,那么在对应的浏览器中一定保存了对应的cookie信息,而这个时浏览器会经cookie信息加入http请求报文中发送给服务端,而服务端根据拿到的cookie从中拿到session id唯一表示一个位用户,所以这时候服务器就可以根据session id确定一名用户的信息,并通过响应报文返回给用户。
  31. 设计一个多人购物系统,需要考虑那些情况
    a. 面试必考:秒杀系统如何设计?-腾讯云开发者社区-腾讯云 (tencent.com)
    b. 考虑到如果人数过多的话,需要考虑负载均衡,防止一台服务器过载
    c. 对共享资源的保护,商品操作保证原子性
    d. 高并发情况——双十一
  32. 如何避免惊群问题
    a. 如何避免线程惊群现象?——多线程编程技巧总结随着计算机技术的不断发展,多线程编程已经成为了现代软件开发中不可或缺的一部分 - 掘金 (juejin.cn)
    b. 什么时惊群问题
    i. 多个线程同时在等待同一个共享资源,当资源可用是,所有线程都被唤醒,同时进程锁,导致系统新能下降
    c. 解决方法
    i. 使用条件变量
    ii. 使用互斥锁
    iii. 使用信号量
  33. 左值和右值
    a. 区分左值和右值的方法
    i. 区分右值和左值的重要依据就是能不能取地址,左值可以取地址,右值不能(因为右值本身就是常量或者时临时变量,并没有被保存起来,所有也就没有存储地址)
    b. 左值引用和右值引用
    i. 无论时左值引用还是右值引用都是给变量取别名(无非是给左值取别名,和给右值取别名)
    ii. 一定给右值取别名后,会导致右值被存储到特定位置,所以这个时候右值是可以被取地址的。
    iii. 一般情况下,左值引用是不能引用右值的,但是被const修饰的左值引用是可以引用右值也可以引用左值。同理右值引用是不能引用左值的,但是右值引用可以引用move后的左值。
  34. 右值引用的应用,简单描述一下移动构造和移动拷贝
    a. 左值引用解决了函数参数传参拷贝的问题,同时解决了部分返回拷贝的问题(左值引用可以解决生命周期调用该函数结束时长)
    b. 移动构造和移动赋值
    i. 移动构造和移动拷贝的本质就是将右值中的将亡值或者说只是一个不需要使用的临时的常量/常量(可以使用move使其成为右值属性)进行资源转移,以此来减少拷贝成本。
  35. get请求和post请求的区别
    a. 规范上的区别:get是用来请求资源的,post是用来传输实体对象的
    b. 请求参数存放地方不同:get请求的参数是存放在URL中的,而post请求的参数十存放在请求体中的。
  36. 如何解决TCP分包,粘包问题
    a. TCP是面向字节流的,会根据缓冲区的实际情况自行对数据进行包划分,所以一个完整的包可能会被差分分成多个小的包进行传输(分包),也有可以能多个小包被包装成一个包进行传输(粘包)
    b. 解决方案
    i. 发送端每个数据包固定长度的进行发送
    ii. 在数据尾部添加特殊符号进行分割
    iii. 将数据分成两部分,头部和内容体;头部固定长度,声明一个变量用来表示内容体的大小
  37. socket连接一个未启动的服务器端口会产生生么情况?返回的错误码是多少
    a. ip地址和port都不存在
    i. 主机不断的发出请求,同时不断的发出ARP请求,企图回去目的主机的MAC地址
    b. ip地址存在但是port都不存在
    i. 服务器的ip地址没有问题,但是bind的端口号十错误的,这时候当客户端进行SYN发起请求连接的时候,由于ip地址是正确的所以报文在传输到服务器的路径上的MAC地址和ip地址都不会有错误,一直回到到达服务器的网络层,这个时候其实已经握手的一次了,但是在到传输层的时候port端口号是错误的此时服务器会返回RET,而RET本来是用来请求重新连接的,但是不免有时候上方上的一个会出现问题,所以RST也有关闭异常连接的作用,但是如果服务器端的防火墙关闭的话可能会出现一直请求的情况。返回的错误码是属于服务器当中的错误所以一般是500
  38. 负载均衡的实现及原理
    a. 轮询
    b. 加权轮询
    c. 最少连接数
    d. 最短响应时间
    e. IP/URL散列
  39. 超时重传机制
    a. TCP会维护一个动态的超时时间,如果超时了就会触发重传机制
    b. 而在此期间可能会有很多的重复数据,但是因为有序列号的缘故,会将重复数据进行丢包处理。
  40. 访问一个网页需要经过的过程
    a. 应用层
    i. 用户输入URL
    ii. 浏览器为其封装成http请求
    iii. 进行DNS域名解析获取请求ip地址
    iv. 根据http协议生成http请求报文
    v. TLS进行加密
    b. 传输层
    i. 发起TCP三次握手
    c. 网络层
    i. 通过ip寻址找到对应主机
    d. 数据链路层
    i. 通过APR机制找到吓一跳的MAC地址
    e. 物理层
    i. 到达服务器主机的网卡,通过一些类的得到客户端的request请求报文进行分析
    f. 然后重复上述过程服务器将response发送个客户端
  41. TCP重传,超时重传,快速重传有什么区别
    a. 触发条件
    i. 超时重传是通过设计重传定时器来确保数据的可靠传输,而快速重传则是通过冗余的ACK来加速数据重传(这个过程是发生在滑动窗口机制中的)
  42. ARP协议
    a. ARP协议是解决同一局域网中主ip和MAC地址的映射关系
    b. 工作流程
    i. 每天主机都会有自己的ARP缓冲区,当一个数据包要发送到目标主机时,先检查自己的ARP缓存是否有对应的映射关系,如果有则直接获取并发送到指定的MAC地址主机上。
    ii. 如果主机ARP缓存中没有对应的映射关系,则该主机会发出一个广播地址,在当前局域网中查找,当前网段的路由器接收到这个广播会将接收到的ip地址进行对比,如果没有则不做反应,如果有则将MAC地址和ip地址的映射关系添加到自己的ARP缓存中,如果原来已经有了映射关系则会进行覆盖处理。
    iii. 如果主机一直没有收到ARP响应数据包,则ARP查询失败。
  43. 滑动窗口
    a. 滑动窗口的大小表示无需等待确认应答可以可以继续发送数据的最大值
    b. 当第一个收到一个ACK后窗口就会向后移动
    c. 其中通过快重传机制保证数据的可靠性(即当收到三次相同的ACK后触发快重传机制)
  44. 拥塞控制
    a. 流量控制十服务器和客户端之进行数据交换时所需要控制的,但是数据时要经过网路传输的,那是必须要经过很多次路由,而在路由的过程中同样需要控制流量,一方网络拥塞导致大量的丢包重传影响数据传输效率。
    b. 拥塞控制采用了慢启动的方法,用来维护一个拥塞窗口,拥塞窗口的大小开始位1,后通过慢启动的方式呈现位指数型上升,但是不会超过阈值,一开始慢启动的阈值等于滑动窗口大小,一旦达到阈值后呈现线程增长,后如果出现超时重传的数据报,慢启动的阈值会变成原来一般并重置拥塞窗口大小再次慢启动,而这里滑动窗口的大小就不能是对方的缓冲区的大小了,而是要将拥塞窗口的大小进行比较取最小的那一个。
  45. 如果在TCP传输过程中有一方网络断开了,会发生什么
    a. 接受方断网
    i. 如果接收方断网了,发送方在进行了多次重传后都没有接收到ACK确认应答后,发送方会尝试进行重新连接,但是还是没有反应,这个时候发送方就会认为是网络上的问题,就会自行进行断开。
    b. 发送方断网
    i. 因为是发送方对网络,接收方不知道是因为数据还没发过来还是发送方断网了,所以所以接收方会定时的发送“心跳包”,来确定接收方是否断网了。“心跳包”是一种特殊的ping报文,如果对方还存在就会放回一个pong报文依次来确定对方的存在。
  46. 网络通信中怎么确保不同的设备间数据的正确性
    a. 通过协议,在网络传输的过程中,都需要遵循协议,比如http协议
    b. 我们拿http协议来讲,http协议规定了网络字节序必须是大端的,并且提供了一些类的字节序的转换函数。
  47. SYN攻击发生在那个阶段,对服务器有什么影响
    a. 发生在三次握手的第一阶段
    b. SYN攻击就是大量发送SYN请求,但是不给予ACK应答,形成一种半连接状态
    c. 这样做会会消耗服务器的资源,服务器会给每个SYN请求分配资源,如果过多的SYN请求导致服务器资源耗尽,服务器将无法正常工作
    d. 可以通过SYN cookie或者SYN代理防火墙进行预防
  48. NULL和nullptr的区别
    a. NULL是预处理宏,nullptr是C++中的关键字
    b. 在C语言中NULL通常是别这样定义的:#define NULL ((void*)0),在C语言中是可以发生隐式类型转换的,把void指针转换为其他类型的指针。
    c. 但是在C++中NULL被定义为0,这是因为在C++中void*类型是不能被转换为其他类型的,他是强类型语言
    d. 所以在C++中NULL就会有而一些,有时候我们可能想表达的是NULL是一个指针类型的,但是他被定义为0整数类型的,就会有二义性。
    e. 所以在C++11引入了nullptr这一关键字来代指空指针。
  49. class和struct的区别在哪里
    a. 默认访问权限不同
    i. class的默认访问权限是private的,而struct的默认访问权限是public
    b. 继承时的默认继承方式不同
    i. struct的默认继承方式时public的,而class的默认继承时private的
    c. class可以使用模板,但是struct不能
  50. malloc和new的区别
    a. 关于C++ new和malloc的区别,记住这张表格就行了! - 知乎
    b. 属性上
    i. malloc/free是一个库函数
    ii. new/delete是C++中的一个关键字
    c. 使用方面
    i. malloc在使用的时候需要进行强制类型转换,并且需要填入申请的大小
    ii. new无需强制类型转换以及填入申请大小,它会根据new的类型自动分配内存
    d. 存储内存位置
    i. 在C++中new的底层实现是使用malloc实现的,所以一般是存放在堆上的,但是C++中new是可以进行重载的,所以也可以实现new开辟空间在其他内存分布上
    e. 返回值
    i. malloc内存分配返回的是void*类型的,需要程序员手动的强制类型转换为指定的类型
    ii. new则返回的是对象的指针类型,无需强制类型转换
    f. 分配失败情况
    i. malloc失败返回NULL
    ii. new失败则会抛出异常,
    g. 创建和销毁
    i. 使用malloc申请空间只能申请到对应的空间大小,使用free也是只能释放对应的空间的。
    ii. new的使用其实可以分两步,开辟空间,调用构造函数,也就是说new是可以对对象进行初始化的,而使用delete同样也是可以分两步的,第一调用对象的析构函数,释放空间。
    h. 内存扩张
    i. 使用malloc开辟空间,如果发现空间不够,可以使用realloc来进行扩张,realloc首先会从原来的空间中找后序的空间是否可以达到扩充给的大小如果可以以则直接扩张,如果不够则会重新找一份足够的空间然后把原来的数据重新拷贝一份。
    new没有扩充机制。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

三问走天下

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值