cpp-interview/README.md
2018-02-15 01:23:27 +08:00

660 lines
20 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

## 目录
* [C/C++](#cc)
* [STL](#stl)
* [数据结构](#%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84)
* [算法](#%E7%AE%97%E6%B3%95)
* [Problems](#problems)
* [操作系统](#%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F)
* [计算机网络](#%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C)
* [数据库](#%E6%95%B0%E6%8D%AE%E5%BA%93)
* [设计模式](#%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F)
* [网络编程](#%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8B)
* [链接装载库](#%E9%93%BE%E6%8E%A5%E8%A3%85%E8%BD%BD%E5%BA%93)
* [海量数据处理](#%E6%B5%B7%E9%87%8F%E6%95%B0%E6%8D%AE%E5%A4%84%E7%90%86)
* [其他](#%E5%85%B6%E4%BB%96)
* [书籍](#%E4%B9%A6%E7%B1%8D)
* [复习刷题网站](#%E5%A4%8D%E4%B9%A0%E5%88%B7%E9%A2%98%E7%BD%91%E7%AB%99)
* [面试题目经验](#%E9%9D%A2%E8%AF%95%E9%A2%98%E7%9B%AE%E7%BB%8F%E9%AA%8C)
----
## C/C++
* 封装
* 继承
* 多态
* 虚函数
* 内存分配和管理
* extern"C"
* const作用
* 什么是面向对象OOP
* new、malloc、alloca的区别
* 运行时类型识别RTTI
* 友元类和友元函数
* struct和class的区别
## STL
## 数据结构
### 顺序结构
#### 顺序栈Sequence Stack
```cpp
typedef struct {
ElemType *elem;
int top;
int size;
int increment;
} SqSrack;
```
![](images/SqStack.png)
#### 队列Sequence Queue
```cpp
typedef struct {
ElemType * elem;
int front;
int rear;
int maxSize;
}SqQueue;
```
##### 非循环队列
![](images/SqQueue.png)
`SqQueue.rear++`
##### 循环队列
![](images/SqLoopStack.png)
`SqQueue.rear = (SqQueue.rear + 1) % SqQueue.maxSize`
#### 顺序表Sequence List
```cpp
typedef struct {
ElemType *elem;
int length;
int size;
int increment;
} SqList;
```
![](images/SqList.png)
### 链式结构
```cpp
typedef struct LNode {
ElemType data;
struct LNode *next;
} LNode, *LinkList;
```
#### 链队列Link Queue
![](images/LinkQueue.png)
#### 线性表的链式表示
##### 单链表Link List
![](images/LinkList.png)
##### 双向链表Du-Link-List
![](images/DuLinkList.png)
##### 循环链表Cir-Link-List
![](images/CirLinkList.png)
### 哈希表
#### 概念
哈希函数:`H(key): K -> D , key ∈ K`
#### 构造方法
* 直接定址法
* 除留余数法
* 数字分析法
* 折叠法
* 平方取中法
#### 冲突处理方法
* 链地址法key相同的用单链表链接
* 开放定址法
* 线性探测法key相同 -> 放到key的下一个位置`Hi = (H(key) + i) % m`
* 二次探测法key相同 -> 放到 `Di = 1^2, -1^2, ..., ±k)^2,(k<=m/2`
* 随机探测法:`H = (H(key) + 伪随机数) % m`
#### 线性探测的哈希表数据结构
```cpp
typedef char KeyType;
typedef struct {
KeyType key;
}RcdType;
typedef struct {
RcdType *rcd;
int size;
int count;
bool *tag;
}HashTable;
```
![](images/HashTable.png)
### 递归
#### 概念
函数直接或间接地调用自身
#### 递归与分治
* 分治法
* 问题的分解
* 问题规模的分解
* 折半查找(递归)
* 归并查找(递归)
* 快速排序(递归)
#### 递归与迭代
* 迭代:反复利用变量旧值推出新值
* 折半查找(迭代)
* 归并查找(迭代)
#### 广义表
##### 头尾链表存储表示
```cpp
// 广义表的头尾链表存储表示
typedef enum {ATOM, LIST} ElemTag;
// ATOM==0原子LIST==1子表
typedef struct GLNode {
ElemTag tag;
// 公共部分,用于区分原子结点和表结点
union {
// 原子结点和表结点的联合部分
AtomType atom;
// atom是原子结点的值域AtomType由用户定义
struct {
struct GLNode *hp, *tp;
} ptr;
// ptr是表结点的指针域prt.hp和ptr.tp分别指向表头和表尾
} a;
} *GList, GLNode;
```
![](images/GeneralizedList1.png)
##### 扩展线性链表存储表示
```cpp
// 广义表的扩展线性链表存储表示
typedef enum {ATOM, LIST} ElemTag;
// ATOM==0原子LIST==1子表
typedef struct GLNode1 {
ElemTag tag;
// 公共部分,用于区分原子结点和表结点
union {
// 原子结点和表结点的联合部分
AtomType atom; // 原子结点的值域
struct GLNode1 *hp; // 表结点的表头指针
} a;
struct GLNode1 *tp;
// 相当于线性链表的next指向下一个元素结点
} *GList1, GLNode1;
```
![](images/GeneralizedList2.png)
### 二叉树
#### 性质
1. 非空二叉树第 i 层最多 2^(i-1) 个结点 (i >= 1)
2. 深度为 k 的二叉树最多 2^k - 1 个结点 (k >= 1)
3. 度为 0 的结点数为 n0度为 2 的结点数为 n2则 n0 = n2 + 1
4. 有 n 个结点的完全二叉树深度 k = ⌊ log2(n) ⌋ + 1
5. 对于含 n 个结点的完全二叉树中编号为 i (1 <= i <= n) 的结点
1. 若 i = 1为根否则双亲为 ⌊ i / 2 ⌋
2. 若 2i > n则 i 结点没有左孩子,否则孩子编号为 2i + 1
3. 若 2i + 1 > n则 i 结点没有右孩子,否则孩子编号为 2i + 1
#### 存储结构
##### 顺序存储
![](images/SqBinaryTree.png)
##### 链式存储
![](images/LinkBinaryTree.png)
#### 遍历方式
* 先序遍历
* 中序遍历
* 后续遍历
* 层次遍历
#### 分类
* 满二叉树
* 完全二叉树(堆)
* 大顶堆:根 >= 左 && 根 >= 右
* 小顶堆:根 <= 左 &&<= 右
* 二叉查找树(二叉排序树):左 < <
* 平衡二叉树AVL树| 左子树树高 - 右子树树高 | <= 1
* 最小失衡树平衡二叉树插入新结点导致失衡的子树调整
* LL型根的左孩子右旋
* RR型根的右孩子左旋
* LR型根的左孩子左旋再右旋
* RL型右孩子的左子树先右旋再左旋
### 森林
#### 树的存储结构
* 双亲表示法
* 双亲孩子表示法
* 孩子兄弟表示法
#### 并查集
一种不相交的子集所构成的集合 S = {S1, S2, ..., Sn}
#### B树
#### B+树
#### 红黑树
#### 八叉树
### 图
## 算法
### 排序
* [冒泡排序](Algorithm/BubbleSort.h)
* [冒泡排序(改进版)](Algorithm/BubbleSort_orderly.h)
* [选择排序](Algorithm/SelectionSort.h)
* [快速排序](Algorithm/QuickSort.h)
* [文件排序](Algorithm/FileSort)
### 查找
* [顺序查找](Algorithm/SequentialSearch.h)
* [蛮力字符串匹配](Algorithm/BruteForceStringMatch.h)
* [文件查找](Algorithm/FileSearch)
## Problems
### Single Problem
* [Chessboard Coverage Problem (棋盘覆盖问题)](Problems/ChessboardCoverageProblem)
* [Knapsack Problem (背包问题)](Problems/KnapsackProblem)
* [Neumann Neighbor Problem (冯诺依曼邻居问题)](Problems/NeumannNeighborProblem)
* [Round Robin Problem (循环赛日程安排问题)](Problems/RoundRobinProblem)
* [Tubing Problem (输油管道问题)](Problems/TubingProblem)
### Leetcode Problems
#### Array
* [1. Two Sum](Problems/LeetcodeProblems/1-two-sum.h)
* [4. Median of Two Sorted Arrays](Problems/LeetcodeProblems/4-median-of-two-sorted-arrays.h)
* [11. Container With Most Water](Problems/LeetcodeProblems/11-container-with-most-water.h)
* [26. Remove Duplicates from Sorted Array](Problems/LeetcodeProblems/26-remove-duplicates-from-sorted-array.h)
* [53. Maximum Subarray](Problems/LeetcodeProblems/53-maximum-subarray.h)
* [66. Plus One](Problems/LeetcodeProblems/66-plus-one.h)
* [88. Merge Sorted Array](Problems/LeetcodeProblems/88-merge-sorted-array.h)
* [121. Best Time to Buy and Sell Stock](Problems/LeetcodeProblems/121-best-time-to-buy-and-sell-stock.h)
* [169. Majority Element](Problems/LeetcodeProblems/169-majority-element.h)
* [283. Move Zeroes](Problems/LeetcodeProblems/283-move-zeroes.h)
## 操作系统
* 进程间的通信方式管道有名管道信号共享内存消息队列信号量套接字文件
## 计算机网络
* TCP/IP
* TCP协议
* TCP三次握手
* TCP和UDP的区别
* socket套接字
* HTTP返回码
### HTTP
[runoob . HTTP教程](http://www.runoob.com/http/http-tutorial.html)
#### HTTP 请求方法
* GET请求指定的页面信息并返回实体主体
* HEAD类似于get请求只不过返回的响应中没有具体的内容用于获取报头
* POST向指定资源提交数据进行处理请求例如提交表单或者上传文件)。数据被包含在请求体中POST请求可能会导致新的资源的建立和/或已有资源的修改
* PUT从客户端向服务器传送的数据取代指定的文档的内容
* DELETE请求服务器删除指定的页面
* CONNECTHTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器
* OPTIONS允许客户端查看服务器的性能
* TRACE回显服务器收到的请求主要用于测试或诊断
#### HTTP 状态码
* 200 OK: 请求成功
* 301 Moved Permanently: 永久移动请求的资源已被永久的移动到新URI返回信息会包括新的URI浏览器会自动定向到新URI今后任何新的请求都应使用新的URI代替
* 400 Bad Request: 客户端请求的语法错误服务器无法理解
* 401 Unauthorized: 请求要求用户的身份认证
* 403 Forbidden: 服务器理解请求客户端的请求但是拒绝执行此请求
* 404 Not Found: 服务器无法根据客户端的请求找到资源网页)。通过此代码网站设计人员可设置"您所请求的资源无法找到"的个性页面
* 408 Request Timeout: 服务器等待客户端发送的请求时间过长超时
* 500 Internal Server Error: 服务器内部错误无法完成请求
* 503 Service Unavailable: 由于超载或系统维护服务器暂时的无法处理客户端的请求延时的长度可包含在服务器的Retry-After头信息中
* 504 Gateway Timeout: 充当网关或代理的服务器未及时从远端服务器获取请求
## 数据库
* 数据库事务四大特性原子性一致性分离性持久性
* 数据库索引顺序索引 B+树索引 hash索引
[MySQL索引背后的数据结构及算法原理](http://blog.codinglabs.org/articles/theory-of-mysql-index.html)
## 设计模式
## 网络编程
## 链接装载库
### 内存、栈、堆
一般应用程序内存空间有如下区域
* 由操作系统自动分配释放存放函数的参数值局部变量等的值用于维护函数调用的上下文
* 一般由程序员分配释放若程序员不释放程序结束时可能由操作系统回收用来容纳应用程序动态分配的内存区域
* 可执行文件映像存储着可执行文件在内存中的映像由装载器装载是将可执行文件的内存读取或映射到这里
* 保留区保留区并不是一个单一的内存区域而是对内存中受到保护而禁止访问的内存区域的总称如通常C语言讲无效指针赋值为0NULL因此0地址正常情况下不可能有效的访问数据
#### 栈
栈保存了一个函数调用所需要的维护信息常被称为堆栈帧Stack Frame或活动记录Activate Record一般包含以下几方面
* 函数的返回地址和参数
* 临时变量包括函数的非静态局部变量以及编译器自动生成的其他临时变量
* 保存上下文包括函数调用前后需要保持不变的寄存器
#### 堆
堆分配算法
* 空闲链表Free List
* 位图Bitmap
* 对象池
#### “段错误segment fault” 或 “非法操作该内存地址不能read/write”
典型的非法指针解引用造成的错误当指针指向一个不允许读写的内存地址而程序却试图利用指针来读或写该地址时会出现这个错误
普遍原因
* 将指针初始化位NULL之后没有给它一个合理的值就开始使用指针
* 没用初始化栈中的指针指针的值一般会是随机数之后就直接开始使用指针
### 编译链接
#### 编译链接过程
1. 预编译预编译器处理如`#include`、`#define`等预编译指令生成`.i``.ii`文件
2. 编译编译器进行词法分析语法分析语义分析中间代码生成目标代码生成优化生成`.s`文件
3. 汇编汇编器把汇编码翻译成机器码生成`.o`文件
4. 链接连接器进行地址和空间分配符号决议重定位生成`.out`文件
> 现在版本GCC把预编译和编译合成一步预编译编译程序cc1、汇编器as、连接器ld
> MSVC编译环境编译器cl、连接器link、可执行文件查看器dumpbin
#### 目标文件
编译器编译源代码后生成的文件叫做目标文件目标文件从结构上讲它是已经编译后的可执行文件格式只是还没有经过链接的过程其中可能有些符号或有些地址还没有被调整
> 可执行文件Windows的`.exe`和Linux的`ELF`、动态链接库Windows的`.dll`和Linux的`.so`、静态链接库Windows的`.lib`和Linux的`.a`都是按照可执行文件格式存储Windows按照PE-COFFLinux按照ELF
##### 目标文件格式
* Windows的PEPortable Executable或称为PE-COFF`.obj`格式
* Linux的ELFExecutable Linkable Format`.o`格式
* Intel/Microsoft的OMFObject Module Format
* Unix的`a.out`格式
* MS-DOS的`.COM`格式
> PE和ELF都是COFFCommon File Format的变种
##### 目标文件存储结构
| 功能
--- | ---
File Header | 文件头描述整个文件的文件属性包括文件是否可执行是静态链接或动态连接及入口地址目标硬件目标操作系统等
.text section | 代码段执行语句编译成的机器代码
.data section | 数据段已初始化的全局变量和局部静态变量
.bss section | BBS段Block Started by Symbol未初始化的全局变量和局部静态变量因为默认值为0所以只是在此预留位置不占空间
.rodate section | 只读数据段存放只读数据一般是程序里面的只读变量如const修饰的变量和字符串常量
.comment section | 注释信息段存放编译器版本信息
.note.GNU-stack section | 堆栈提示段
> 其他段略
#### 链接的接口————符号
在链接中目标文件之间相互拼合实际上是目标文件之间对地址的引用即对函数和变量的地址的引用我们将函数和变量统称为符号Symbol函数名或变量名就是符号名Symbol Name)。
如下符号表Symbol Table
Symbol符号名 | Symbol Value 地址
--- | ---
main| 0x100
Add | 0x123
... | ...
#### extern "C"
extern "C" 的作用是让C++编译器将 `extern "C"` 声明的代码当作C语言代码处理可以避免C++因符号修饰导致代码不能和C语言库中的符号进行链接的问题
```cpp
#ifdef __cplusplus
extern "C" {
#endif
void *memset(void *, int, size_t);
#ifdef __cplusplus
}
#endif
```
### Linux的共享库Shared Library
Linux下的共享库就是普通的ELF共享对象
共享库版本更新应该保证二进制接口ABIApplication Binary Interface的兼容
#### 命名
`libname.so.x.y.z`
* x主版本号不同主版本号的库之间不兼容需要重新编译
* y次版本号高版本号向后兼容低版本号
* z发布版本号不对接口进行更改完全兼容
#### 路径
大部分包括Linux在内的开源系统遵循FHSFile Hierarchy Standard的标准这标准规定了系统文件如何存放包括各个目录结构组织和作用
* `/lib`存放系统最关键和最基础的共享库如动态链接器C语言运行库数学库等
* `/usr/lib`存放非系统运行时所需要的关键性的库主要是开发库
* `/usr/local/lib`存放跟操作系统本身并不十分相关的库主要是一些第三方应用程序的库
> 动态链接器会在`/lib`、`/usr/lib`和由`/etc/ld.so.conf`配置文件指定的,目录中查找共享库
#### 环境变量
* `LD_LIBRARY_PATH`临时改变某个应用程序的共享库查找路径而不会影响其他应用程序
* `LD_PRELOAD`指定预先装载的一些共享库甚至是目标文件
* `LD_DEBUG`打开动态链接器的调试功能
### Windows的动态链接库Dynamic-Link Library
DLL头文件
```cpp
#ifdef __cplusplus
extern "C" {
#endif
#ifdef _WIN32
# ifdef MODULE_API_EXPORTS
# define MODULE_API __declspec(dllexport)
# else
# define MODULE_API __declspec(dllimport)
# endif
#else
# define MODULE_API
#endif
MODULE_API int module_init();
#ifdef __cplusplus
}
#endif
```
DLL源文件
```cpp
#define MODULE_API_EXPORTS
#include "module.h"
MODULE_API int module_init()
{
/* do something useful */
return 0;
}
```
### 运行库Runtime Library
#### 典型程序运行步骤
1. 操作系统创建进程把控制权交给程序的入口往往是运行库中的某个入口函数
2. 入口函数对运行库和程序运行环境进行初始化包括堆I/O线程全局变量构造等等)。
3. 入口函数初始化后调用main函数正式开始执行程序主体部分
4. main函数执行完毕后返回到入口函数进行清理工作包括全局变量析构堆销毁关闭I/O等然后进行系统调用结束进程
> 一个程序的I/O指代程序与外界的交互包括文件、管程、网络、命令行、信号等。更广义地讲I/O指代操作系统理解为“文件”的事物。
#### glibc 入口
`_start -> __libc_start_main -> exit -> _exit`
其中`main(argc, argv, __environ)`函数在`__libc_start_main`里执行
#### MSVC CRT 入口
`int mainCRTStartup(void)`
执行如下操作
1. 初始化和OS版本有关的全局变量
2. 初始化堆
3. 初始化I/O
4. 获取命令行参数和环境变量
5. 初始化C库的一些数据
6. 调用main并记录返回值
7. 检查错误并将main的返回值返回
#### C语言运行库CRT
大致包含如下功能
* 启动与退出包括入口函数及入口函数所依赖的其他函数等
* 标准函数有C语言标准规定的C语言标准库所拥有的函数实现
* I/OI/O功能的封装和实现
* 堆的封装和实现
* 语言实现语言中一些特殊功能的实现
* 调试实现调试功能的代码
#### C语言标准库ANSI C
包含
* 标准输入输出stdio.h
* 文件操作stdio.h
* 字符操作ctype.h
* 字符串操作string.h
* 数学函数math.h
* 资源管理stdlib.h
* 格式转换stdlib.h
* 时间/日期time.h
* 断言assert.h
* 各种类型上的常数limits.h & float.h
* 变长参数stdarg.h
* 非局部跳转setjmp.h
## 海量数据处理
* [ 海量数据处理面试题集锦](http://blog.csdn.net/v_july_v/article/details/6685962)
* [十道海量数据处理面试题与十个方法大总结](http://blog.csdn.net/v_JULY_v/article/details/6279498)
## 其他
## 书籍
* 剑指Offer
* 编程珠玑
* 深度探索C++对象模型
* Effective C++》
* More Effective C++》
* 深入理解C++11
* STL源码剖析
* 深入理解计算机系统
* TCP/IP网络编程
* 程序员的自我修养
## 复习刷题网站
* [leetcode](https://leetcode.com/)
* [牛客网](https://www.nowcoder.net/)
* [慕课网](https://www.imooc.com/)
* [菜鸟教程](http://www.runoob.com/)
## 面试题目经验
* [知乎 . 互联网公司最常见的面试算法题有哪些?](https://www.zhihu.com/question/24964987)
* [知乎 . 面试 C++ 程序员,什么样的问题是好问题?](https://www.zhihu.com/question/20184857)
* [cnblogs . C++面试集锦( 面试被问到的问题 )](https://www.cnblogs.com/Y1Focus/p/6707121.html)
* [cnblogs . C/C++ 笔试、面试题目大汇总](https://www.cnblogs.com/fangyukuan/archive/2010/09/18/1829871.html)
* [cnblogs . 常见C++面试题及基本知识点总结(一)](https://www.cnblogs.com/LUO77/p/5771237.html)
* [CSDN . 全面整理的C++面试题](http://blog.csdn.net/ljzcome/article/details/574158)
* [CSDN . 百度研发类面试题C++方向)](http://blog.csdn.net/Xiongchao99/article/details/74524807?locationNum=6&fps=1)
* [CSDN . c++常见面试题30道](http://blog.csdn.net/fakine/article/details/51321544)
* [CSDN . 腾讯2016实习生面试经验已经拿到offer)](http://blog.csdn.net/onever_say_love/article/details/51223886)
* [segmentfault . C++常见面试问题总结](https://segmentfault.com/a/1190000003745529)