参考书籍:《C++ primer》,《effective C++》,《STL源码解析》,《深度搜索C++对象模型》html
extern关键字做用linux
static关键字做用c++
volatile是干啥的git
说说const的做用,越多越好程序员
new与malloc区别github
C++多态性与虚函数表web
可是虚函数在设计上还具备封装和抽象的做用。好比抽象工厂模式。面试
动态绑定是如何实现的?
第一个问题中基本回答了,主要都是结合虚函数表来答就行。算法
静态多态和动态多态。静态多态是指经过模板技术或者函数重载技术实现的多态,其在编译器肯定行为。动态多态是指经过虚函数技术实如今运行期动态绑定的技术。数据库
纯虚函数如何定义,为何对于存在虚函数的类中析构函数要定义成虚函数
为了实现多态进行动态绑定,将派生类对象指针绑定到基类指针上,对象销毁时,若是析构函数没有定义为析构函数,则会调用基类的析构函数,显然只能销毁部分数据。若是要调用对象的析构函数,就须要将该对象的析构函数定义为虚函数,销毁时经过虚函数表找到对应的析构函数。
C++标准指明析构函数不能、也不该该抛出异常。C++异常处理模型最大的特色和优点就是对C++中的面向对象提供了最强大的无缝支持。那么若是对象在运行期间出现了异常,C++异常处理模型有责任清除那些因为出现异常所致使的已经失效了的对象(也即对象超出了它原来的做用域),并释放对象原来所分配的资源, 这就是调用这些对象的析构函数来完成释放资源的任务,因此从这个意义上说,析构函数已经变成了异常处理的一部分。
(2) 一般异常发生时,c++的机制会调用已经构造对象的析构函数来释放资源,此时若析构函数自己也抛出异常,则前一个异常还没有处理,又有新的异常,会形成程序崩溃的问题。
构造函数和析构函数中调用虚函数吗?
指针和引用的区别
指针与数组千丝万缕的联系
C++四种类型转换:static_cast, dynamic_cast, const_cast, reinterpret_cast
内存对齐的原则
内联函数有什么优势?内联函数与宏定义的区别?
C++内存管理
STL里的内存池实现
STL内存分配分为一级分配器和二级分配器,一级分配器就是采用malloc分配内存,二级分配器采用内存池。
二级分配器设计的很是巧妙,分别给8k,16k,…, 128k等比较小的内存片都维持一个空闲链表,每一个链表的头节点由一个数组来维护。须要分配内存时从合适大小的链表中取一块下来。假设须要分配一块10K的内存,那么就找到最小的大于等于10k的块,也就是16K,从16K的空闲链表里取出一个用于分配。释放该块内存时,将内存节点归还给链表。
若是要分配的内存大于128K则直接调用一级分配器。
为了节省维持链表的开销,采用了一个union结构体,分配器使用union里的next指针来指向下一个节点,而用户则使用union的空指针来表示该节点的地址。
STL里set和map是基于什么实现的。红黑树的特色?
STL里的其余数据结构和算法实现也要清楚
这个问题,把STL源码剖析好好看看,不只面试不慌,本身对STL的使用也会上升一个层次。
必须在构造函数初始化式里进行初始化的数据成员有哪些
(1) 常量成员,由于常量只能初始化不能赋值,因此必须放在初始化列表里面
(2) 引用类型,引用必须在定义的时候初始化,而且不能从新赋值,因此也要写在初始化列表里面
(3) 没有默认构造函数的类类型,由于使用初始化列表能够没必要调用默认构造函数来初始化,而是直接调用拷贝构造函数初始化
模板特化
(1) 模板特化分为全特化和偏特化,模板特化的目的就是对于某一种变量类型具备不一样的实现,所以须要特化版本。例如,在STL里迭代器为了适应原生指针就将原生指针进行特化。
定位内存泄露
(1)在windows平台下经过CRT中的库函数进行检测;
(2)在可能泄漏的调用先后生成块的快照,比较先后的状态,定位泄漏的位置
(3)Linux下经过工具valgrind检测
手写strcpy
这一块考察范围太广,主要靠多刷题吧,牛客网,剑指OFFER,LeetCode等。
树的各类常见算法题(http://blog.csdn.net/xiajun07061225/article/details/12760493);
什么是红黑树?
红黑树与AVL树的区别
十亿整数(随机生成,可重复)中前K最大的数
相似问题的解决方法思路:首先哈希将数据分红N个文件,而后对每一个文件创建K个元素最小/大堆(根据要求来选择)。最后将文件中剩余的数插入堆中,并维持K个元素的堆。最后将N个堆中的元素合起来分析。能够采用归并的方式来合并。在归并的时候为了提升效率还须要建一个N个元素构成的最大堆,先用N个堆中的最大值填充这个堆,而后就是弹出最大值,指针后移的操做了。固然这种问题在如今的互联网技术中,通常就用map-reduce框架来作了。
大数据排序相同的思路:先哈希(哈希是好处是分布均匀,相同的数在同一个文件中),而后小文件装入内存快排,排序结果输出到文件。最后建堆归并。
十亿整数(随机生成,可重复)中出现频率最高的一千个
几十亿个数常常要查找某一个数在不在里面,使用布隆过滤器,布隆过滤器的原理。布隆过滤器可能出现误判,怎么保证无偏差?
参考书籍:《图解TCP/IP》,《TCP/IP详解 卷一》,《图解HTTP》,《HTTP权威指南》
TCP与UDP之间的区别
(1) IP首部,TCP首部,UDP首部
(2) TCP和UDP区别
(3) TCP和UDP应用场景
(4) 如何实现可靠的UDP
详细说明TCP状态迁移过程
(1) 三次握手和四次挥手状态变化;
(2) 2MSL是什么状态?做用是什么?
(3)三次握手为何不是两次或者四次?
Ping和TraceRoute实现原理
http的主要特色:
简单快速:当客户端向服务器端发送请求时,只是简单的填写请求路径和请求方法便可,而后就能够经过浏览器或其余方式将该请求发送就好了
灵活: HTTP 协议容许客户端和服务器端传输任意类型任意格式的数据对象
无链接:无链接的含义是限制每次链接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开链接,采用这种方式能够节省传输时间。(当今多数服务器支持Keep-Alive功能,使用服务器支持长链接,解决无链接的问题)
无状态:无状态是指协议对于事务处理没有记忆能力,服务器不知道客户端是什么状态。即客户端发送HTTP请求后,服务器根据请求,会给咱们发送数据,发送完后,不会记录信息。(使用 cookie 机制能够保持 session,解决无状态的问题)
http1.1的特色
a、默认持久链接节省通讯量,只要客户端服务端任意一端没有明确提出断开TCP链接,就一直保持链接,能够发送屡次HTTP请求
b、管线化,客户端能够同时发出多个HTTP请求,而不用一个个等待响应
c、断点续传
http2.0的特色
a、HTTP/2采用二进制格式而非文本格式
b、HTTP/2是彻底多路复用的,而非有序并阻塞的——只需一个HTTP链接就能够实现多个请求响应
c、使用报头压缩,HTTP/2下降了开销
d、HTTP/2让服务器能够将响应主动“推送”到客户端缓存中
http数据由请求行,首部字段,空行,报文主体四个部分组成
首部字段分为:通用首部字段,请求首部字段,响应首部字段,实体首部字段
浏览器中输入URL,首先浏览器要将URL解析为IP地址,解析域名就要用到DNS协议,首先主机会查询DNS的缓存,若是没有就给本地DNS发送查询请求。DNS查询分为两种方式,一种是递归查询,一种是迭代查询。若是是迭代查询,本地的DNS服务器,向根域名服务器发送查询请求,根域名服务器告知该域名的一级域名服务器,而后本地服务器给该一级域名服务器发送查询请求,而后依次类推直到查询到该域名的IP地址。DNS服务器是基于UDP的,所以会用到UDP协议。
获得IP地址后,浏览器就要与服务器创建一个http链接。所以要用到http协议,http协议报文格式上面已经提到。http生成一个get请求报文,将该报文传给TCP层处理。若是采用https还会先对http数据进行加密。TCP层若是有须要先将HTTP数据包分片,分片依据路径MTU和MSS。TCP的数据包而后会发送给IP层,用到IP协议。IP层经过路由选路,一跳一跳发送到目的地址。固然在一个网段内的寻址是经过以太网协议实现(也能够是其余物理层协议,好比PPP,SLIP),以太网协议须要直到目的IP地址的物理地址,有须要ARP协议。
至少了解攻击的原理和基本的防护方法,常见的攻击方法有一下几种
主要参考书籍:《数据库系统概念》,《高性能MySQL》
主要参考书籍:《现代操做系统》,《APUE》,《UNP》,《LINUX内核设计与实现》,《深刻理解LINUX内核》
(1) 进程与线程区别?
(2) 线程比进程具备哪些优点?
(3) 何时用多进程?何时用多线程?
(4) LINUX中进程和线程使用的几个函数?
(5) 线程同步?
在Windows下线程同步的方式有:互斥量,信号量,事件,关键代码段
在Linux下线程同步的方式有:互斥锁,自旋锁,读写锁,屏障(并发完成同一项任务时,屏障的做用特别好使)
知道这些锁之间的区别,使用场景?
管道( pipe ):管道是一种半双工的通讯方式,数据只能单向流动,并且只能在具备亲缘关系的进程间使用。进程的亲缘关系一般是指父子进程关系。
命名管道 (FIFO) : 有名管道也是半双工的通讯方式,可是它容许无亲缘关系进程间的通讯。
信号量:信号量用于实现进程间的互斥与同步,而不是用于存储进程间通讯数据,有XSI信号量和POSIX信号量,POSIX信号量更加完善。
消息队列( message queue ) : 消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。
共享内存( shared memory ) :共享内存就是映射一段能被其余进程所访问的内存,这段共享内存由一个进程建立,但多个进程均可以访问。共享内存是最快的 IPC 方式,它是针对其余进程间通讯方式运行效率低而专门设计的。它每每与其余通讯机制,如信号两,配合使用,来实现进程间的同步和通讯。(原理必定要清楚,常考)
信号 ( sinal ) : 信号是一种比较复杂的通讯方式,用于通知接收进程某个事件已经发生,常见的信号。
套接字( socket ) : 套解口也是一种进程间通讯机制,与其余通讯机制不一样的是,它可用于不一样及其间的进程通讯。
共享文件映射mmap
mmap创建进程空间到文件的映射,在创建的时候并不直接将文件拷贝到物理内存,一样采用缺页终端。mmap映射一个具体的文件能够实现任意进程间共享内存,映射一个匿名文件,能够实现父子进程间共享内存。
常见的信号有哪些?:SIGINT,SIGKILL(不能被捕获),SIGTERM(能够被捕获),SIGSEGV,SIGCHLD,SIGALRM
(1) 死锁产生的条件;
(2) 死锁的避免;
与CPU,内存,磁盘相关的命令(top,free, df, fdisk)
网络相关的命令netstat,tcpdump等
sed, awk, grep三个超强大的命名,分别用与格式化修改,统计,和正则查找
ipcs和ipcrm命令
查找当前目录以及字母下以.c结尾的文件,且文件中包含”hello world”的文件的路径
建立定时任务
五种IO模型:阻塞IO,非阻塞IO,IO复用,信号驱动式IO,异步IO
select,poll,epoll的区别
select:是最初解决IO阻塞问题的方法。用结构体fd_set来告诉内核监听多个文件描述符,该结构体被称为描述符集。由数组来维持哪些描述符被置位了。对结构体的操做封装在三个宏定义中。经过轮寻来查找是否有描述符要被处理,若是没有返回**
存在的问题:
1. 内置数组的形式使得select的最大文件数受限与FD_SIZE;
2. 每次调用select前都要从新初始化描述符集,将fd从用户态拷贝到内核态,每次调用select后,都须要将fd从内核态拷贝到用户态;
3. 轮寻排查当文件描述符个数不少时,效率很低;
poll:经过一个可变长度的数组解决了select文件描述符受限的问题。数组中元素是结构体,该结构体保存描述符的信息,每增长一个文件描述符就向数组中加入一个结构体,结构体只须要拷贝一次到内核态。poll解决了select重复初始化的问题。轮寻排查的问题未解决。**
epoll:轮寻排查全部文件描述符的效率不高,使服务器并发能力受限。所以,epoll采用只返回状态发生变化的文件描述符,便解决了轮寻的瓶颈。
- 为何使用IO多路复用,最主要的缘由是什么?
- epoll有两种触发模式?这两种触发模式有什么区别?编程的时候有什么区别?
- 上一题中编程的时候有什么区别,是在边缘触发的时候要把套接字中的数据读干净,那么当有多个套接字时,在读的套接字一直不停的有数据到达,如何保证其余套接字不被饿死(面试网易游戏的时候问的一个问题,答不上来,印象贼深入)。
fork与vfork区别
fork和vfork都用于建立子进程。可是vfork建立子进程后,父进程阻塞,直到子进程调用exit()或者excle()。
对于内核中过程fork经过调用clone函数,而后clone函数调用do_fork()。do_fork()中调用copy_process()函数先复制task_struct结构体,而后复制其余关于内存,文件,寄存器等信息。fork采用写时拷贝技术,所以子进程和父进程的页表指向相同的页框。可是vfork不须要拷贝页表,由于父进程会一直阻塞,直接使用父进程页表。
exit()与_exit()区别
exit()清理后进入内核,_exit()直接陷入内核。
孤儿进程与僵死进程
Linux是如何避免内存碎片的
共享内存的实现原理?
共享内存实现分为两种方式一种是采用mmap,另外一种是采用XSI机制中的共享内存方法。mmap是内存文件映射,将一个文件映射到进程的地址空间,用户进程的地址空间的管理是经过vm_area_struct结构体进行管理的。mmap经过映射一个相同的文件到两个不一样的进程,就能实现这两个进程的通讯,采用该方法能够实现任意进程之间的通讯。mmap也能够采用匿名映射,不指定映射的文件,可是只能在父子进程间通讯。XSI的内存共享实际上也是经过映射文件实现,只是其映射的是一种特殊文件系统下的文件,该文件是不能经过read和write访问的。
两者区别:
一、 系统V共享内存中的数据,历来不写入到实际磁盘文件中去;而经过mmap()映射普通文件实现的共享内存通讯能够指定什么时候将数据写入磁盘文件中。注:前面讲到,系统V共享内存机制实际是经过映射特殊文件系统shm中的文件实现的,文件系统shm的安装点在交换分区上,系统从新引导后,全部的内容都丢失。
二、 系统V共享内存是随内核持续的,即便全部访问共享内存的进程都已经正常终止,共享内存区仍然存在(除非显式删除共享内存),在内核从新引导以前,对该共享内存区域的任何改写操做都将一直保留。
三、 经过调用mmap()映射普通文件进行进程间通讯时,必定要注意考虑进程什么时候终止对通讯的影响。而经过系统V共享内存实现通讯的进程则否则。注:这里没有给出shmctl的使用范例,原理与消息队列大同小异。
系统调用与库函数(open, close, create, lseek, write, read)
同步方法有哪些?
++i是不是原子操做
明显不是,++i主要有三个步骤,把数据从内存放在寄存器上,在寄存器上进行自增,把数据从寄存器拷贝会内存,每一个步骤均可能被中断。
判断大小端
部分问题只是列出思考的概要,去书中和实践中找到这些问题的答案才能真正的消化。
PS:欢迎转载,转载请标明出处!