面试问题整理
c/c++
- 构造函数和析构函数能否为虚函数
- 结构体字节对齐
- 什么是野指针,举个例子,如何避免
- 什么是指针函数和函数指针
- memcpy和strcpy,能否实现一下memcpy
- 声明子类,构造函数和析构函数的执行顺序
- 深拷贝/浅拷贝
- 变量声明和定义的区别
- 零值比较
- strlen和sizeof区别
- static作用是什么?在C和C++中有何区别?
- 结构体和类的区别?
- 指针和引用区别?
- 宏定义和函数有何区别?
- 宏定义和const区别?
- 宏定义和typedef区别?
- 宏定义和内联函数(inline)区别?
- 条件编译#ifdef, #else, #endif作用?
- volatile有什么作用?
- 什么是常引用?
- 常量指针和指针常量区别?
- 数组名和指针(这里为指向数组首元素的指针)区别?
- 野指针是什么?
- 堆和栈的区别?
- delete和delete[]区别?
- 面向对象三大特性?
- public/protected/private的区别?
- 对象存储空间?
- C++空类有哪些成员函数?
- 构造函数调用顺序,析构函数呢?
- 拷贝构造函数中深拷贝和浅拷贝区别?
- 拷贝构造函数和赋值运算符重载的区别?
- 虚函数和纯虚函数区别?
- 覆盖、重载和隐藏的区别?
- 在main执行之前执行的代码可能是什么?
- 哪几种情况必须用到初始化成员列表?
- 什么是虚指针?
- 重载和函数模板的区别?
- this指针是什么?
- 类模板是什么?
- 构造函数和析构函数调用时机?
- 共同体/结构体区别
- sleep()/wait()
-
虚函数:基类可以通过在其成员函数的声明语句之前加上关键字 virtual 使得该函数执行动态绑定,任何构造函数之外的非静态函数都可以是虚函数,关键字 virtual 只能出现在类内部的声明语句之前而不能用于类外部的函数定义。如果基类把一个函数声明成虚函数,则该函数在派生类中隐式的也是虚函数。
- 在一个对象中,继承自基类的部分和派生类自定义的部分不一定是连续存储的。
-
如何让类不能被继承?有时会定义一种类,不希望他被继承或者不想考虑它是否适合作为一个基类。c++11提供了一种防止继承发生的方法,即在类名后跟一个关键字 final :
class Base final {....}
-
静态类型/动态类型:
场景:当我们使用存在继承关系的类型时,不许将一个变量或其他表达式的静态类型与该表达式表示对象的动态类型去分开。
区别:表达式的静态类型在编译时总是已知的,它是变量声明时的类型或表达式生成的类型;动态类型则是变量或表达式表示的内存中的对象的类型,动态类型直到运行时才可知。
如果表达式既不是引用也不是指针,则他的动态类型永远与静态类型一致。 - 虚函数必须被定义(通常的函数如果不使用则无需为该函数提供定义),因为编译器也无法确定到底哪个函数会被使用。
- 动态绑定只有当我们通过指针或引用调用虚函数时才会发生。
- 一个派生类的函数如果覆盖了某个继承而来的虚函数,则他的形参类型必须与被它覆盖的基类函数完全一致。派生类中虚函数的返回类型也必须与基类函数匹配,只有当函数返回类型是类本身的指针或引用时例外。
- final 说明符,如果将函数定义成 final, 则之后任何尝试覆盖该函数的操作都将引发错误。
- override 说明符,显示的说明该函数要重写基类的函数,使用override标记,有利于编译器帮忙进行检查。
- 回避虚函数的机制:默写情况下,希望对虚函数的调用不进行动态绑定,而是强迫执行虚函数的某个版本,可以使用**域运算符(::)**实现这一目的。使用情景:当一个派生类的虚函数调用它覆盖的积累的虚函数版本时。
- 纯虚函数无须定义,通过在函数体的位置(在声明语句的分号之前)书写=0(=0只能出现在类内部虚函数声明语句处)就可将虚函数说明为纯虚函数,例如:
double net_price(std::size_t) const = 0;
。可以为纯虚函数提供定义,不过函数体必须定义在类的外部,但是这么做是没有意义的,因为含有纯虚函数的类不能被实例化,而派生类又不能调用基类的函数,因此不会被实际用到。 - 抽象基类:含有(或者未经覆盖直接继承)纯虚函数的类。抽象基类负责定义接口,后续的其它类可以覆盖该接口。不能(直接)创建一个抽象基类的对象。
- struct与class:唯一的一点区别是默认访问权限不一样,struct关键字,则定义在第一个访问说明符之前的成员是public的,相反,class是private的。
- 多重继承:指从多个直接基类产生派生类的能力。派生类的派生列表中可以包含多个基类,每个基类包含一个可选的访问说明符,如果忽略访问说明符,则如果派生类是class关键字则默认为private访问说明符,struct则为public。
- 派生类的构造函数初始值列表将实参分别传递给每个直接基类。其中基类的构造顺序与派生列表中基类的出现顺序一致,而与派生类构造函数初始值列表中的基类顺序无关。
- 虚继承:虚继承的目的是令某个类做出声明,承诺愿意共享它的基类。其中,共享的基类子对象称为虚基类。在这种机制下,不论虚基类在继承体系中出现了多少次,在派生类中都只包含唯一一个共享的虚基类子对象。在派生列表中添加关键字
virtual
- 虚继承的构造方式:含有虚基类的对象的构造函数与一般顺序稍有区别:首先使用提供给最底层派生类构造函数的初始值初始化该对象的虚基类字部分,接下来按照直接基类在派生列表中出现的次序依次对其进行初始化。
- 虚基类总是先于非虚基类构造,与他们在继承体系中的次序和位置无关。
- 含有虚基类时构造与析构的次序:先构造虚基类,再构造直接虚基类,再根据声明顺序构造其他非虚基类。
STL
数据结构
- 数组/链表区别
- 满二叉树/完全二叉树/平衡二叉树
- 树的三种遍历方式(前、中、后)
- 红黑树
算法
- 口述冒泡排序、快速排序、归并排序的算法思想
计算机网络
- 大小端存储以及如何判断大小端
- 网络字节序
操作系统
- 什么是内存泄漏,举个例子
- 动静态库含义、区别、用法
- 进程/线程区别
- 进程通信有哪些方式
- 线程同步有哪些机制
- 内核线程和用户线程区别
数据库
- B树和B+树(索引层次分析,哪个更适合增删改,哪个更加适合查询)
- 聚簇索引和非聚簇索引
Linux
参考答案/面筋贴子
- https://github.com/linw7/Skill-Tree