招银网络科技提前批面试

一面 电话面,15分钟

问题

  • map和unorderedmap区别
    map是红黑树实现的,unorderedmap是hash表实现的。

  • 二叉树查找时间
    log(n)

  • 树的遍历方式:
    先序,中序,后序,层次

  • 虚函数
    虚函数的主要作用是实现了多态的机制。用父类指针指向其子类的实例,然后通过父类的指针调用实际子类的成员函数。是一种泛型编程。虚函数是通过一张虚函数表来实现的。在表中,主要是一个类的虚函数的地址表,这张表解决了继承、覆盖的问题,保证实例反应实际的函数。在有虚函数的类的实例中,这个表被分配到了实例的内存。虚函数表的指针存在于对象实例的最前面。

  • 排序算法

    • 稳定的排序:冒泡、归并
  • TCP和UDP

    • TCP面向连接,可靠
    • UDP无连接,不可靠
    • 区别:
    区别 TCP UDP
    连接 面向连接 无连接
    服务对象 点对点的两点间服务 支持一对一,一对多,多对一,多对多交互通信
    可靠性 可靠交付,无差错,不丢失,不重复,按序到达 尽最大努力交付,不保证可靠
    拥塞控制,流量控制
    报文长度 动态报文长度 面向报文,不合并,不拆分
    首部开销 20字节 8字节
    适用场景 可靠但是速度慢 不可靠速度快
  • GET和POST
    GET浏览器会把http header和data一起发送出去,服务器响应200返回数据。
    POST浏览器首先发送header,服务器响应100continue,浏览器再发送数据data,服务器响应200(返回数据)

    • GET和POST区别
区别 GET POST
传参 通过url 在request body中
长度限制 url传参有长度限制 没有长度限制
安全性 更不安全 稍好
编码 只能进行url编码 支持多种编码
cache 浏览器主动cache 参数不会保留
记录 完整保留参数 post参数不会被保留
TCP数据包数量 1个 2个
  • TCP建立和断开过程:
    image

  • vector和list

    • vector是顺序实现
    • list是双向链表实现
  • C++内存模型

    • 栈:局部变量,函数参数
    • 堆:由new非配的内存块,delete释放
    • 自由存储区:malloc等分配的内存块,用free来结束生命周期
    • 全局区(静态区)全局变量和静态变量
    • 常量存储区:存放常量,不允许修改。
  • 常量指针和指针常量

    • 常量指针:被指向的对象是常量,常量的指针。地址可变,值不能变
      int const* p;const int* p;
    • 指针常量:指针本身是常量。本质是个常量。指针常量的值是指针。
      指针本身是常量,指向的地址不可以变化,但是指向的地址对应的内容可以变化。地址不可变,值可以变
      int* const p;
  • C++内存泄漏
    指由于疏忽或错误造成了程序未能释放掉不再使用的内存的情况。内存泄漏并非指内存再物理上的消失,而是由于设计错误,失去了对该段内存的控制,因而造成了内存的浪费。

    • 内存泄漏分类:
      • 堆内存泄漏:通过malloc,realloc,new等分配的堆内存使用完毕后没有用free和delete删掉。
      • 系统资源泄漏:使用bitmap,handler,socket等没有用相应的函数释放掉,导致系统资源的浪费。
      • 没有将基类的析构函数定义为虚函数:当基类指针指向子类对象时,如果基类的析构函数不是虚拟的,子类的析构函数就不会被调用,子类的资源没有正确释放。
    • 如何处理内存泄漏:
    • 使用varglind,mtrace检测。
  • new和malloc区别

new malloc
按照数据类型分配 按照指定的大小分配
返回指定对象的指针 返回void*
分配并调用构造初始化 只分配
用delete释放,且会调用析构 用free释放
new是操作符,可重载 是函数
没有这种操作 可用realloc扩容
分配失败报bad_malloc错误 返回NULL
申请数组是 new[]一次分配所有内存,释放调用delete[] sizeof(int)*n
  • 继承、虚继承和虚函数表对类的大小的影响
    • 真空类
    class CNull
    {
    };
    
    长度为1个字节。内存结构??每次都不一样
  • 空类
    class CNull2
    {
    
    public:
    
        CNull2(){printf("Construct/n");}
    
        ~CNull2(){printf("Desctruct/n");}
    
        void Foo(){printf("Foo/n");}
    };
    
    长度为1,内存结构??内部的成员函数不会影响类大小
  • 简单类
    class COneMember
    {
    public:
        COneMember(int iValue = 0){m_iOne = iValue;};
    private:
        int m_iOne;
    };
    
    长度4 内存结构: 00 00 00 00 00
    只有成员数据才影响大小
  • 虚继承
    虚继承让长度增加4,多了一个指针
    static不占用类的大小。
    带虚函数的类长度增加4

总结

  1. 普通单继承,只需将自身成员变量的大小加上父类大小(父类中 有虚函数,子类中不管有没有)若父类没有虚函数,则子类大小需要加上指向虚表的指针大小。

  2. 普通多继承,若几个父类都有虚表,则子类与第一个父类公用一个虚表指针,其他有几个有虚函数的父类则就有几个虚表指针。

  3. 虚拟单继承,此时若子类有虚函数则加上一个自身的虚表指针的大小,(若没有则不加)再加上自身的成员变量大小,还要加上一个虚类指针ptr_sonclass_fatherclass,最后加上父类的大小。

  4. 多重虚拟继承,此时若子类有虚函数则加上一个自身的虚表指针的大小,(若没有则不叫)再加上自身的成员变量大小,还要加上 一个公用的虚类指针(不管有几个虚拟父类,只加一个),在加上所有父类的大小。

  5. 普通、虚拟混合多继承,此时子类的大小为自身大小(若子类或普通父类有虚函数,则为成员变量+虚表指针大小;若都没虚函数,则就为成员变量大小),加上一个虚类指针大小,在加上虚拟父类的大小,在加上普通父类的大小(除虚表指针,因为它和子类公用一个虚表指针)。

虚函数工作原理

  • 虚函数的实现是通过对象携带额外的信息(虚函数表指针vptr)来实现的。vprt指向一个被称为vtbl的函数指针数组。
  • 对象调用虚函数过程:找到对象的vptr指向的vtbl,然后再vtbl中寻找合适的函数指针。虚函数的地址翻译取决于对象的内存地址,而不是数据类型。
    虚函数表是类级别的,vptr是指向虚函数指针数组是对象所有的。

介绍排序算法:

各种排序算法介绍

  • 归并排序(稳定):该算法采用分治法;对于包含m个元素的待排序序列,将其看成m个长度为1的子序列。然后两两合归并,得到n/2个长度为2或者1的有序子序列;然后再两两归并,直到得到1个长度为m的有序序列。
  • 冒泡排序(稳定):对于包含n个元素的带排序数组,重复遍历数组,首先比较第一个和第二个元素,若为逆序,则交换元素位置;然后比较第二个和第三个元素,重复上述过程。每次遍历会把当前前n-i个元素中的最大的元素移到n-i位置。遍历n次,完成排序。
  • 快速排序(不稳定):通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
  • 选择排序(不稳定):每次循环,选择当前无序数组中最小的那个元素,然后将其与无序数组的第一个元素交换位置,从而使有序数组元素加1,无序数组元素减1.初始时无序数组为空。
  • 插入排序(稳定):对于一个带排序数组来说,其初始有序数组元素个数为1,然后从第二个元素,插入到有序数组中。对于每一次插入操作,从后往前遍历当前有序数组,如果当前元素大于要插入的元素,则后移一位;如果当前元素小于或等于要插入的元素,则将要插入的元素插入到当前元素的下一位中。
  • 堆排序(不稳定):堆排序是一种选择排序,利用堆这种数据结构来完成选择。其算法思想是将带排序数据构造一个最大堆(升序)/最小堆(降序),然后将堆顶元素与待排序数组的最后一个元素交换位置,此时末尾元素就是最大/最小的值。然后将剩余n-1个元素重新构造成最大堆/最小堆。

时间复杂度

image

hash表的实现,包括STL中的哈希桶长度系数

hash表的实现主要包括构造哈希和处理哈希冲突两个方面

  • 构造哈希:直接地址法,平方取中法,除留余数法等。
  • 处理哈希冲突:开放定址法、再哈希法、链地址法、建立公共溢出区等。SGL中采用链地址法。SGL以质数来设计哈希桶长度。提前计算好28个质数。
  • rehash:当loadFactor==1时,开辟一个原来桶数组的两倍空间,然后把原来的桶数组元素全部重新哈希到新的桶数组中。

二面 视频面,牛客

问题

  • 内联函数和宏定义(凭自己理解写的)
  • C++内存。new和malloc区别(一面的时候已经准备,所以答上来了)
  • 链表找环,思路。求环外长度。

手撕代码

两个字符串,找最大公共子串

三面 视频面,牛客

问题

  • 对一个超大的文件内容按第一列统计数量
  • 排序

Answer:

with open(filename,'rb') as f:
    for line in f: #自动使用缓冲以及内存管理
        do something with the line

四面 HR面,牛客

猜你喜欢

转载自blog.csdn.net/weixin_44583265/article/details/107635310