• C++ 基础知识 问答题(五)


    PART1

    1.int型整数的最大值和最小值分别是什么?如何用二进制表示?使用最大值和最小值进行计算时会出现什么问题?

    2.类声明成指针相对于声明成对象有什么好处?

    3.迭代器可以加减常数吗?

    4.动态绑定是如何实现的?

    5.哈希函数是什么?

    6.当发生哈希表冲突时,有哪些处理方法?

    7.deque的底层结构是什么?

    8.哪些迭代器有除了!=和==之外的关系运算?

    9.迭代器it进行it++和++it的区别

    10.Lambda表达式用来做什么?语法形式是什么?捕获列表有几种形式?

    11.线性表是什么?

    13.mutable关键字的作用是什么?

    14.编译过程的四个步骤是什么?

    15.希尔排序是什么?时间复杂度是多少?

    16. Lambda表达式的底层实现是什么?

    17. vector是如何扩容的?

    18. vector的resize和reserve方法有什么区别?

    19.bitset类如何使用?

    20.deque类如何使用?

    21.仿函数是什么?

    22.函数指针是什么?作用是什么?

    PART2

    1.int型整数的最大值和最小值分别是什么?如何用二进制表示?使用最大值和最小值进行计算时会出现什么问题?

    INT_MAX: 2^31-1     01111111111111111111111111111111

    INT_MIN:-2^31       10000000000000000000000000000000

    会发生的问题:

    INT_MAX +1 = INT_MIN

    INT_MIN - 1 = INT_MAX

    abs(INT_MIN) = INT_MIN

    2.类声明成指针相对于声明成对象有什么好处?

    多态特性

    可以用new操作符来申请动态内存

    生命周期:由程序员决定何时释放对象

    对象的共享和传递:传参时不用拷贝整个对象,提高效率

    3.迭代器可以加减常数吗?

    只用存储在连续空间的容器的迭代器可以加减常数,因为这些容器支持随机访问。

    vetcor, deque, string的迭代器可以加减常数。

    map, set, list, forward_list的迭代器不可以加减常数,只能自增自减。

    4.动态绑定是如何实现的?

    父类指针或引用指向子类对象,父类指针调用虚函数,在运行时实现动态绑定,根据虚函数表,确定调用哪个类的该函数。

    5.哈希函数是什么?

    将一组数据映射到一段有限的地址空间的函数。

    6.当发生哈希表冲突时,有哪些处理方法?

    开放寻址法

    • 线性探测法:若地址冲突,沿着该地址加一,直到找到空单元
    • 平方探测法:若地址冲突,沿着该地址加1^2, 2^2, 3^2....  直到找到空单元
    • 双散列函数探查法:若地址冲突,沿着该地址加上一个步长,步长由关键字在第二个哈希函数中计算得到(若地址空间在0到n-1之间,那么第二个哈希函数计算出的值在1到n-1之间,且该值与n互素),直到找到空单元。该探查序列具有随机性。
    • 伪随机探查法:建立一个伪随机数序列list,若地址冲突,关键字加上伪随机数序列中的值list[i],再次计算地址,直到地址不再冲突。

    链地址法

    将地址都为m的元素都存储在一个单向链表中,哈希表中的第m个单元指向该单向链表。

    再哈希法

    构造多个哈希函数,当第一个哈希函数产生地址冲突时,就使用第二个哈希函数,直到不再发生冲突。不易产生聚集,但是增加了计算时间。

    建立公共溢出区

    将哈希表分为公共表和溢出区,当发生地址冲突了,就存储到溢出区。

    7.deque的底层结构是什么?

    deque的底层结构是由一段一段连续的等长的存储空间组成的,每段存储空间之间不一定连续。

    为了管理这些连续空间,deque用数组存储了每段存储空间的首地址,也就是指针。

    8.哪些迭代器有除了!=和==之外的运算?

    vector, string, queue

    可以进行的运算:

    iter1 += iter2

    iter1 -= iter2

    iter1 - iter2  获取两个迭代器之间的距离

    > < >= <= 元素靠后的迭代器大于靠前的迭代器

    9.迭代器it进行it++和++it的区别

    ++it返回的是引用

    it++返回的是临时对象,开销大,每次自增都在创建和销毁对象

    10.Lambda表达式用来做什么?语法形式是什么?捕获列表有几种形式?

    Lambda表达式用于定义和创建匿名函数。

    语法形式: [捕获列表](参数列表)mutable或exception异常->返回类型 {函数体}

    捕获列表有多种形式:

    []:不捕获父作用域的任何遍量

    [=]:用值传递的方式捕获父作用域的所有变量

    [&]:用引用传递的方式捕获父作用域的所有变量

    [=a,&]:用值传递的方式捕获父作用域的a变量,用引用传递的方式捕获父作用域的其他变量

    [&a,=]:用引用传递的方式捕获父作用域的a变量,用值传递的方式捕获父作用域的其他变量

    11.线性表是什么?

    具有相同特性的数据元素组成的有限序列。

    线性表包含顺序表(数组)和链表。

    13.mutable关键字的作用是什么?

    用于修饰成员变量,表示const成员函数可以修改该变量。

    14.编译过程的四个步骤是什么?

    预处理:替换预处理指令,展开宏定义

    编译:完成词法分析、语法分析、语义分析等操作,将源代码编译成汇编指令

    汇编:将汇编指令翻译成机器语言的目标文件,生成一个与机器硬件相关的目标文件

    链接:将目标文件与所需的库文件链接,生成最终的可执行文件

    15.希尔排序是什么?时间复杂度是多少?

    希尔排序是缩小增量的插入排序。把下标按照一定的增量分组,对每组进行直接插入排序。随着增量减少,每组的元素越来越多,直到最后被分成一组。

    时间复杂度:O(N^(2/3))

    16. Lambda表达式的底层实现是什么?

    编译器实现Lambda表达式,分三步:

    创建一个Lambda匿名类,实现构造函数,用Lambda表达式的函数体重载operator()

    创建一个Lambda匿名类的对象

    使用该对象调用operator()

    17. vector是如何扩容的?

    为了避免每次插入都扩容,vector会在插入元素前,预估所需大小,提前将底层容量开辟好。

    Windows: 按照当前容量的1.5倍扩容(可以充分利用之前用到过的内存块)

    Linux: 按照当前容量的2倍扩容

    18. vector的resize和reserve方法有什么区别?

    resize: 改变vector的size大小,并对元素初始化。有可能会影响capacity。

    若resize要求的大小小于vector当前的size,则舍弃多余元素(逻辑上舍弃,物理上还能访问)。

    若resize要求的大小大于vector当前的size,则新添加元素,并对元素默认初始化。

    若resize要求的大小大于vector当前的capacity,则先扩容,再添加元素,并对元素默认初始化。

    reserve: 改变vector的capacity大小,不影响size。

    若reserve要求的大小大于vector当前的capacity,那么会重新分配一块连续的存储空间,将vector原有的数据copy过去,这时vector的capacity增大了,但size不变。

    若reserve要求的大小小于vector当前的capacity,则不会产生任何影响。

    19.bitset类如何使用?

    bitset 是二进制集合,必须指定模板参数N,表示bitset有几位。

    初始大小4字节,大小每次两倍增长

    bitset<1> : 4字节

    bitset<32> : 4字节

    bitset<33> : 8字节

    bitset<65> : 16字节

    20.deque类如何使用?

    双端队列,可以在队列头和尾插入和删除元素。可以用下标遍历deque。

    21.仿函数是什么?

    仿函数又称函数对象,它并不是一个函数,但有类似函数的功能,可以像普通函数那样调用,传入参数,有返回值。

    仿函数是实现了operator()的一个类,有自己的成员变量。

    22.函数指针是什么?作用是什么?

    函数指针指向一个函数在内存中的起始地址。

    函数指针可以指向参数列表和返回值类型与它相同的函数:

            函数指针的声明: (返回值类型)(*函数指针名)(参数列表)int(*p)(string s);

    函数指针的作用是将函数作为参数传递: process(0,0,p);p("hello");

    函数指针不支持算数运算:+1, ++, --

  • 相关阅读:
    下载遥感数据慢的原因
    Spring学习(2) Spring的IOC底层实现
    认识的几位清华同学都离职了……
    数据库迁移-国产化-Oracle迁移至GBase8a(存储过程)
    换掉ES!Redis官方搜索引擎来了,性能炸裂!
    ES6中的一些新特性,一篇就够了
    Python基础分享之面向对象的进一步拓展
    Avalonia使一个弹窗弹到指定位置
    阿里p9技术专家纯手打《程序员“不迷茫”职业路指南》给你指明方向
    实现一个博客系统----基于前后端分离
  • 原文地址:https://blog.csdn.net/jmqxnxg/article/details/132423151