C++ 面经
C++部分
面向对象设计
- 面向对象含义及其几大特性
- 基于对象的、基于类的软件开发思想
- 面向对象具备继承、封装、多态的特性
- 析构函数
- 有个Computer类,有内存、硬盘、CPU属性。其中CPU有AMD和INTEL两个类别,画下类的设计。这两个CPU多是AMD或者INTEL,实现可能不一样,实现方法?
- 回调函数
- for循环中i++和++i哪一个效率快
- 对基础类型来讲编译器作了优化,效率差很少,对于自定义类型来讲,i++会返回一个i的副本,效率低一些。
- HashMap解决冲突的方法
- 链表和红黑树
- 函数重载
- extern c的做用
C++基础
- 《Effective C++》、《C++ Prime》、《STL源码剖析》
- 指针和引用的区别
- 指针保存的是指向对象的地址,引用至关于变量的别名
- 引用在定义的时候必须初始化,不能直接传递字面量,指针没这个要求
- 指针能够改变地址,引用必须从一而终
- 不存在空引用,可是存在空指针,相对而言引用更加安全
- 引用的建立不会调用类的拷贝构造函数
- new/delete与malloc/free的区别
- new是运算符,malloc是C语言库函数
- new能够重载,malloc不能重载
- new的变量是数据类型,malloc的是字节大小
- new能够调用构造函数,delete能够调用析构函数,malloc/free不能
- new返回的是指定对象的指针,而malooc返回的是void*,所以malloc的返回值通常都须要进行类型转化
- malloc分配的内存不够的时候能够使用realloc扩容,new没有这样的操做
- new内存分配失败能抛出bad_malloc,malloc内存分配失败返回NULL值
- volatile关键字
- 用volatile关键字声明的变量i每一次被访问时,执行部件都会从i相应的内存单元中取出i的值。
- 没有用volatile关键字声明的变量i在被访问的时候可能直接从CPU寄存器中取值,这样作的目的是为了提高速度,是编译器优化的结果
- 可是当访问某些特殊内存地址,该内存地址上的数据可能被某些编译器未知的因素修改(好比操做系统、硬件、其余线程)而且来不及同步到寄存器上
- 为了保证变量及时更新,使用volatile关键字修饰,保证对变量的读取访问内存地址而不是寄存器
- 一个参数能够既是const又是volatile的吗?能够,一个例子是只读状态寄存器,是volatile是由于它可能被意想不到的改变,是const告诉程序不该该试图去修改他。
- static 关键字的做用
- 修饰全局变量
- 修饰局部变量
- 修饰全局函数
- 限制他的做用域只在本文件内
- 修饰局部函数
- 修饰类的成员变量、成员函数
- extern 关键字
- 声明一个外部变量
- const 关键字做用 (const 指针好像错了)
- 修饰全局变量
- 修饰局部变量
- 修饰指针,const int*
- 修饰引用作形参
- 修饰成员变量,必须在构造函数列表中初始化
- 修饰成员函数,说明该函数不该该修改非静态成员,可是这样并非十分可靠的,指针所指的非成员对象值可能会被改变
- define/const/inline的区别
- define只是宏替换,const 参与编译运行
- define不会作类型检查,const拥有类型,会执行相应的类型检查
- define仅仅是宏替换,不占用内存,const会占用内存
- const内存效率更高,编译器一般将const变量保存在符号表中,而不会分配存储空间,这使得它成为一个编译期间的常量,没有存储和读取的操做
- define宏替换,inline由编译器控制
- 内联函数在编译时展开,而宏是由预处理器对宏进行展开
- 内联函数会检查参数类型,宏定义不检查参数,因此内联函数更安全
- 宏不是函数,而inline函数是函数
- 宏在定义时要当心处理宏参数(通常状况下是把参数用括弧括起来)
- C++预约义宏
- <center>
- _LINE_ => 在程序编译时包含当前行号
- _FILE_ => 在程序编译时包含当前文件名
- _DATE_ => 包含一个形式为 month/day/year
- _TIME_ => 包含一个形式为 hour:minute:second 的字符串,它表示程序被编译的时间
- C++构造函数能抛出异常嘛?析构呢?
- C++/C内存分配方式,堆与栈的区别
- 构造函数为何不能定义为虚函数,析构函数为何能够?
- 虚函数的执行依赖于虚函数表。而虚函数表须要在构造函数中进行初始化工做,即初始化vptr,让他指向正确的虚函数表。而在构造对象期间,虚函数表尚未被初始化,将没法进行。
- 在类的继承中,若是有基类指针指向派生类,那么用基类指针delete时,若是不定义成虚函数,派生类中派生的那部分没法析构。
- 构造函数不要调用虚函数。在基类构造的时候,虚函数是非虚,不会走到派生类中,既是采用的静态绑定。显然的是:当咱们构造一个子类的对象时,先调用基类的构造函数,构造子类中基类部分,子类尚未构造,尚未初始化,若是在基类的构造中调用虚函数,若是能够的话就是调用一个尚未被初始化的对象,那是很危险的,因此C++中是不能够在构造父类对象部分的时候调用子类的虚函数实现。可是不是说你不能够那么写程序,你这么写,编译器也不会报错。只是你若是这么写的话编译器不会给你调用子类的实现,而是仍是调用基类的实现。
- 有哪些内存泄漏?如何判断内存泄漏?如何定位内存泄漏?
- new完不delete
- malloc完不free
- 待添加...
- 全局变量和局部变量的区别
- C++智能指针
- C++动态内存
- C++11新特性
- 纯虚函数的做用和实现方式
- 字节对齐原则
- 从0位置开始存储
- 变量存储的起始位置是该变量大小的整数倍
- 结构体总的大小是其最大元素的整数倍,不足的后面要补齐
- 结构体中包含结构体,从结构体中最大元素的整数倍开始存
- 若是加入pragma pack(n),取n和变量自身大小较小的一个
- 空结构体的sizeof()的返回值
- 答案是1
- 静态连接和动态连接的区别
- 静态连接
- 在编译连接时直接将须要的执行代码拷贝到调用处,优势就是在程序发布的时候就不须要依赖库,也就是再也不须要带着库一块发布,程序能够独立执行,可是体积可能会相对大一些。
- 动态连接
- 在编译的时候不直接拷贝可执行代码,
- 而是经过记录一系列符号和参数,在程序运行或加载时将这些信息传递给操做系统,操做系统负责将须要的动态库加载到内存中,而后程序在运行到指定的代码时,去共享执行内存中已经加载的动态库可执行代码,最终达到运行时链接的目的。
- 优势是多个程序能够共享同一段代码,而不须要在磁盘上存储多个拷贝,缺点是因为是运行时加载,可能会影响程序的前期执行性能。
- 多态是什么?举一个多态的例子
- 多态性与虚函数表
- 静态多态和动态多态
- 多态分为静态多态和动态多态。静态多态是经过重载和模板技术实现,在编译的时候肯定。动态多态经过虚函数和继承关系来实现,执行动态绑定,在运行的时候肯定。
- 重写、重载与隐藏的区别
- 重载的函数都是在类内的。只有参数类型或者参数个数不一样,重载不关心返回值的类型。
- 覆盖(重写)派生类中从新定义的函数,其函数名,返回值类型,参数列表都跟基类函数相同,而且基类函数前加了virtual关键字。
- 隐藏是指派生类的函数屏蔽了与其同名的基类函数,注意只要同名函数,无论参数列表是否相同,基类函数都会被隐藏。有两种状况
- 参数列表不一样,无论有无virtual关键字,都是隐藏;
- 参数列表相同,可是无virtual关键字,也是隐藏。
- 必须在构造函数初始化式里进行初始化的数据成员有哪些
- 常量成员
- 由于常量只能初始化不能赋值,因此必须放在初始化列表里面
- 引用类型
- 引用必须在定义的时候初始化,而且不能从新赋值,因此也要写在初始化列表里面
- 没有默认构造函数的类类型
- 由于使用初始化列表能够没必要调用默认构造函数来初始化,而是直接调用拷贝构造函数初始化
- C++四种类型转换
- static_cast
- 非const 转const
- void*转指针
- static_cast能用于多态向上转化,若是向下转能成功可是不安全,结果未知;
- dynamic_cast
- 动态类型转换
- 只能用于含有虚函数的类,用于类层次间的向上和向下转化。只能转指针或引用。向下转化时,若是是非法的对于指针返回NULL,对于引用抛异常。要深刻了解内部转换的原理。
- const_cast
- 将const变量转换为非const
- reinterpret_cast
- 几乎什么均可以转,好比将int转指针,可能会出问题,尽可能少用
- 为何不用C的强制转换?
- C的强制转换表面上看起来功能强大什么都能转,可是转化不够明确,不能进行错误检查,容易出错。
- 如何让一个类不能实例化?
- 将类定义为抽象基类或者将构造函数声明为private
- 如何让main函数以前执行函数
- C++在main以前定义一个全局对象,调用构造函数
- C语言使用GCC的attribute关键字,声明constructor和destructor
- C++如何建立一个类,使得他只能在堆上或者栈上建立?
- 只能在堆上建立对象:将虚构函数设置为私有
- C++是静态绑定型语言,编译器管理栈上对象的生命周期,编译器在为类对象分配栈空间时,会先检查类的析构函数的访问性,若析构函数不可访问,则不能在栈上建立对象。
- 只能在栈上生成对象:将new和delete重载为私有
- 在堆上生成对象,使用new关键词操做,其过程分为两个阶段
- 第一阶段,使用new在堆上寻找可用内存,分配给对象
- 第二阶段,调用构造函数生成对象。将new操做设置为私有,那么第一阶段就没法完成,就不可以再在堆上生成对象。
- C++命名空间,命名空间的嵌套
- namespace first_space{void fun(){...}}
- namespace second_space{void fun(){...}}
- int main() {
- first_space::fun();
- second_space::fun();
- return 0;
- }
- C++多线程
-
- explict关键字的做用
C++内存模型
- 内存分配
- malloc函数实现原理
- 给一段逻辑连续的内存,怎么设计
- 保证充分利用空间和动态分配
- 内存分配的几大算法
C++ STL库
- vector
- 变长数组
- map
- 红黑树实现,有序
- unordered_map
- vector实现,hash
- 和Java中的区别
- priority_queue
-
C和C++的区别
- C是面向过程的语言,C++是面向对象的语言
- C++中new和delete是对内存分配的运算符,取代了C中的malloc和free
- C++中有引用的概念,C中没有
- C++引用了类的概念,C没有
- C++有函数重载,C中不能
- C变量只能在函数的开头出声明和定义,C++随用随定义
C和Java的区别
- Java的应用在高层,C++在中间件和底层
- Javaa语言简洁,取消了指针带来更高的代码质量,彻底面向对象,独特的运行机制是其具备自然的可移植性
- Java在web应用上具备C++无可比拟的优点
- 垃圾回收机制的区别,C++用析构函数回收垃圾,Java自动回收,写C和C++程序必定要注意内存的申请和释放
- Java用接口(Interface)技术取代C++程序中的多继承性
不一样语言区别、编码
- 强类型和弱类型
- 强类型如Java,弱类型如Python
- varchar和char的区别
- varchar动态决定占用空间大小,char固定
- UTF-8下面varchar能占用多少字符?GBK呢?
- Java和C++的区别
计算机基础知识部分
算法与数据结构
- 《剑指offer》、《LeetCode》、《组合数学》
- 链表
- 输出链表中倒数第K个节点
- 找到链表环节点入口
- 单链表倒置
- 链表归并
- 排序算法
- 冒泡、选择
- 快排、归并、堆排序
- 快排时间复杂度 : patition复杂度O(N),有T(N) = 2(T(N/2) + O(N))
- 顺带分析最好、最坏、平均时间复杂度
- 排序算法的稳定性
- 经常使用排序的优缺点、应用场景
- 链表实现快排
- 链表的倒数第K个结点
- 快排思想
- 基于二分法的排序
- 有递归法和非递归法
- 1000w个整数排序,范围0到100w,8G内存(MapReduce)
- 动态规划
- 动态规划的思想
- 动态规划的使用前提
- 动态规划和分治法、贪心算法的异同
- dp和分治法都是分解子问题可是分治法子问题不重叠
- dp和贪心都是要求问题有最优子结构
- 贪心算法是自顶向下,经过一种规则直接选择一种最优子问题去求解,没被选到的子问题就不去求解了。
- dp是自底向上,无论子问题是否是最优子结构都去求解,解上层子问题时再来选择最优子结构。
- 应用
- 最大连续子列和 LCS
- 最长不降低子序列 LIS
- 最长回文子串
- 最长重复子序列
- 找零钱问题(动态规划&贪心算法)
- 01背包
- 彻底背包
- 排列组合问题(递归&回溯)
- 图的存储以及相关算法
- 二分图相关算法
- 图搜索算法
- 哈希算法
- 哈希处理冲突的解决办法
- 开放定址法
- 链表法
- 空间换时间
- O(1)时间复杂度访问
- 但根据映射方法不一样,会退化到O(N) ?
- 一致性哈希的性质、算法
- 各类树结构
- 二叉树
- 非递归完成二叉树的遍历
- 先序用栈
- 中序用栈
- 后序用两个栈(不必定哦)
- 求二叉树最大深度
- 先序遍历,求高度
- 二叉树的镜像
- 二叉树的前K个大个节点
- 堆排序
- 构建霍夫曼树
- B树
- B+树
- 红黑树
- 平衡二叉树
- 红黑树的自旋
- 线段树
- 字典树
- 可有自旋?
- 前缀树
- 树状数组
- 并查集
- 求两个集合的交集和并集
- 有25匹马,5个赛道,用最少比赛次数将25匹马排序
- 队列算法?https://www.nowcoder.com/questionTerminal/e07d8e0df93b4f6b93a3fadbe72f2c7c](https://www.nowcoder.com/questionTerminal/e07d8e0df93b4f6b93a3fadbe72f2c7c
- 一匹马只有跑了才能看出其速度,25匹马至少都跑了一次,最少五轮,且每轮能排除名词,因为最终只要最快的三名,故每组只有一、二、3有意义继续比下去,四、5名直接淘汰,每组的3有意义的前提是该组的2就是总排名的二、1就是总排名的1,每组的2有意义的前提是该组的1至少第2;归根到底仍是看每组第一的状况,故5个第一比一次,第一就是总的第一;第四第五所在的组所有被淘汰,故第一组的二三名,第二组的第一二名,第三组的第一名比最后一次,前两名就是总的二三名;共七轮。
- 8个球,有一个比较重的,给一个没有刻度的天平,怎么最快找出
- 3和3相称,相同再称,两次搞定
- 千万的数据求前100个最大重复的(Top-K问题)
- Hash + 小顶堆
- int -> 8Byte能够表示十亿的范围
- Hash统计每一个数出现的次数,发生冲突的地方用链表连接起来
- 结点结构体成员:data和count,data记录相应的数字,count记录对应的数字出现的次数,这一步的时间复杂度是O(N),虽然有十亿个数字,可是出大量重复,因此不用担忧最后的空间会有十亿)
- 建立一个大小为100的小顶堆,将Hash表中前100个非空成员放入小顶堆
- 堆顶是当前小顶堆中出现次数最少的数
- 将Hash表中其余数据和堆顶出现的次数比较,若是比堆顶出现的次数少,则丢弃当前数,若是大于堆顶元素出现的次数,则替换堆顶,而后进行堆调整,这一步时间复杂度是O(Nlog100)
- 总的时间复杂度是O(N)+O(Nlog100)
- 数组中数字出现的次数,一个数组中除了两个数字只出现一次,其余的都出现两次,找出这两个数字?位运算,或者哈希表
- 实现12306余票查询的关键数据结构与算法
- 车次 + 时间 : 车箱 + 车座。 两层hash + 一层数组
- 证实一个数字是2的n次方
- int类型 2^k次方只有一位是1,其余位是0,故统计1个数
- 最简洁的方法 value & (value - 1) == 0
- 合并两个有序数组并取中位数
- twopointer 合并 过程当中第n/2个数就是中位数
- 给定二叉树现实最右边的那一列结点
- 层序遍历,存个high表示当前层数,每一个high相同的最后一个元素打印
- 若是是彻底二叉树,能够递归使用NRL遍历,直到第一个叶子结点(不保证对)
- 实现一个最简单的hashmap,参考jdk1.7
- 大量int,内存装不下,去重 + 排序
- C++数据结构 bitset
- 使用bit位图,int能够装10亿个位
- 将全部位置0 => 将集合初始化为空
- 经过读入文件中的每一个整数创建集合,将每一个对应的位置为1
- 检验每一位,若是该位位1,就输出对应的整数
- 两个数组去重,分别根据有序和无序说下,写个有序的算法
- 给个式子,括号匹配,括号去了怎么算出结果
- 中缀表达式转前缀表达式
- 1000瓶水有1瓶水有毒,老鼠喝一滴就会死,可是须要一周毒发,请问最少须要多少老鼠多少时间才能找到那瓶有毒的水
- 十只老鼠一周,解法是十进制转二进制
- A...Z全部字母组合方式,不容许有重复的,用最优的方法实现
- 位运算方式
- 位运算判断2的26次方种状况 (i & allcs[j]) == 1判断该字母是否取到
- 组合数
- 写一个方法输入一个整数,输出这个整数里面的最大质数
- 质数标记法,找出N之内的全部质数,而后标记
- 每输入一个数,判断是不是质数,而且和最大的质数比较
- 跳跃数组问题
- dfs
- 二叉树后序遍历用几个栈实现
- 答案都说是两个栈,可是我为何只用一个栈就能写?
- 设定N张扑克牌和一个随机函数,设计一个洗牌算法
- 设定N次独立重复实验,对每张牌打乱顺序
- 异步消息队列的实现
- 100层楼,2个鸡蛋,鸡蛋从某一个临界楼层丢下会摔碎,请设计方案,能用最小的次数找到临界楼层
- 用三、四、五、六、七、8组成不重复的四位奇数,按照从小到大的顺序排序,第62个数字是?
- 首先是奇数的话,末位只能是三、五、7中的一种,有$C_{3}^{1}$种方法
- 前面三个数是$A_{5}^{3}$排列方法
- 那么总的方法数为$C_{3}^{1}×A_{5}^{3} = 180$种方法,组成的奇数从小到大排序
- 当第一位是3的时候,末位必定是5或者7,那么这样的数一共有$C_{2}^{1}×A_{4}^{2} = 24$种方法
- 当第一位是4的时候,末位必定是3或者5或者7,这样的数一共有$C_{3}^{1}×A_{4}^{2} = 36$种方法
- 那么这里一共就有$24+36=60$种方法
- 当第一位是5的时候,末位必定是3或者7,取较小的数,第二位是3,最后一位是7,那么第61个数是5347,第62个数为5367
- 24点游戏
- 25匹马,5个跑道,如何经过最少的比赛次数肯定前3名?
- 一家人过桥问题
操做系统
- 临界区
- 一段共享资源的保护代码,该代码在任意时刻只容许一个线程对共享资源访问
- 进程进入临界区的调度原则
- 抢占性,如有若干进程要求进入空闲的临界区,一次仅容许一个进程进入
- 忙等待,任什么时候候,处于临界区的进程不可多于一个,若是已有进程进入本身的临界区,则其余全部试图进入临界区的进程必须等待
- 进入临界区的进程要在有限时间内退出,以便于其余进程可以及时进入本身的临界区
- 若是进程不能进入本身的临界区,则应该出让CPU,避免出现忙等待现象
- 互斥对象、临界区和事件的区别
- 互斥
- 用途普遍的内核对象。可以保证多个线程对同一资源的互斥访问。
- 事件对象
- 内核对象,主要成员包括
- 使用计数
- 指明该事件是一个自动重置事件仍是一我的工重置事件的布尔值
- 指明该事件处于已通知状态仍是未通知状态的布尔值
- 互斥对象、事件对象都属于内核对象,利用内核对象进行线程同步,速度较慢,但能够在多个进程种的多个线程间进行同步
- 临界区属于在用户模式下,同步速度也较快,可是很容易进入死锁状态,由于在等待进入临界区时没法设定超时值
- 进程和程序
- 进程是动态的,而程序是静态的
- 进程有必定的生命周期,而程序是指令的集合,自己无“运动”的含义。没有创建进程的程序不能做为1个独立单位获得操做系统的承认
- 一个程序能够对应多个进程,但1个进程只能对应1个程序。进程和程序的关系就犹如演出和剧本的关系
- 进程和线程
- 进程内存地址的分配
- 分配虚拟内存地址
- 一个进程能够建立多少个线程,和什么有关?
- 进程和线程的区别(经典问题)
- 进程
- 资源(CPU、内存等)分配的基本单位,它是程序执行时的一个实例。程序运行时系统就会建立一个进程,并为她分配资源,而后把该进程放入进程就绪队列,进程调度器选中它的时候就会为它分配CPU时间,程序开始真正运行。
- 线程是程序执行时的最小单位,它是进程的一个执行流,是CPU调度和分派的基本单位,一个进程能够由不少个线程组成,线程间共享进程的全部资源,每一个线程有本身的堆栈和局部变量。线程由CPU独立调度执行,在多CPU环境下就容许多个线程同时运行。一样多线程也能够实现并发操做,每一个请求分配一个线程来处理。
- 内核和用户线程的映射
- 一对一
- 一对多
- 多对多
- 一个进程能够建立多少个线程?和什么有关?
- 一个进程必定要有个线程吗?
- 不用
- 没有线程的进程是什么?
- 守护进程 daemon
- 线程间的同步和互斥怎么作的
- 守护进程和僵尸进程、孤儿进程有什么了解?
- 孤儿进程是子进程未结束时而父进程异常退出,子进程变成孤儿,init进程会认做他爹
- 僵尸进程是子进程结束后,父进程没有显示发送通知,致使子进程的结构没办法被回收,变成僵尸进程,浪费空间
- 守护进程就是init进程、负责监控进程的状态,以及认儿子,杀死父进程等操做
- 系统对僵尸进程和孤儿进程的解决办法
- init会杀死父进程或者回收僵尸进程
- 进程是对计算机资源的复用,线程是对CPU时间片的复用
- 线程共享、独占进程的资源
- 共享的资源
- 堆
- 因为堆实在进程空间中开辟出,理所固然被共享
- 所以new出来的都是被共享的
- 16位平台上分全局堆和局部堆,局部堆是独享的
- 全局变量
- 它与某一具体函数无关,与特定线程无关
- 静态变量
- 对于局部变量来讲,它在代码中是“放”在某一函数中的,可是其存放位置和全局变量同样,存于堆中开辟的.bss和.data段,是共享的
- 文件等公用资源
- 共享,使用该资源的线程必须同步
- 对于互斥资源要保持互斥
- 同步与互斥的方式
- 信号量、临界区、事件和互斥体
- 独享的资源
- 栈
- 寄存器
- 线程里存放的是寄存器值得副本,包括程序计数器PC
-
- ...
- 进程的结构
- 进程通讯
- 管道pipe
- 管道是一种半双工的通讯方式,数据只能单向流动,并且只能在具备亲缘关系的进程间使用。进程的亲缘关系一般是指父子进程关系。
- 命名管道FIFO
- 有名管道也是半双工的通讯方式,可是它容许无亲缘关系进程间的通讯。
- 消息队列MessageQueue
- 消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流及缓冲区大小受限等缺点。
- 共享存储SharedMemory
- 共享内存就是映射一段能被其余进程所访问的内存,这段共享内存由一个进程建立,可是多个进程能够访问
- 共享内存是最快的IPC(进程间通讯)方式,它是针对其余进程间通讯方式运行效率低而专门设计的。它每每与其余通讯机制,如信号量,配合使用,来实现进程间的同步和通讯
- 信号量Semaphore
- 信号量是一个计数器,能够用来控制多个进程对共享资源的访问,
- 它做为一种锁机制,防止某进程正在访问共享资源时,其余进程也访问该资源。所以,主要做为进程间以及同一进程内不一样线程间的同步手段
- 套接字Socket
- 套接口也是一种进程间通讯机制,与其余通讯机制不一样的是,它可用于不一样及主机间的进程通讯
- 信号(signal)
- 信号是一种比较复杂的通讯方式,用于通知接受某个进程事件已经发生
- 线程共享资源
- JAVA内存模型
- 以 JVM为例,JVM里的堆就是一个公共区间,线程负责采起资源,这样就能够实现资源共享
- 线程同步方法
- 锁机制
- 互斥锁
- 提供了以排它方式阻止数据结构被并发修改的方法
- 读写锁
- 容许多个线程同时读共享数据,而对写操做互斥
- 条件变量
- 能够以原子方式阻塞进程,直到某个特定条件真为止。对条件测试是在互斥锁的保护下进行的。条件变量始终与互斥锁一块儿使用
- 信号量机制
- 包括无名线程信号量与有名线程信号量
- 信号机制
- 相似于进程间信号处理
- Note -> 线程间通讯主要目的是用于线程同步,因此线程没有像进程通讯用于数据交换的通讯机制
- 线程建立方式有几种
- 进程调度算法
- 先来先去服务 -> FIFO
- 短做业优先调度算法SJ(P)F
- 时间片轮转算法
- 多级反馈队列算法
- 页面置换算法
- 最优页面置换算法 OPT
- 只在理论上存在,其所选择被淘汰的页面,将是之后永不使用的
- 最近未使用页面置换算法(NRU) Not Recently Used
- 一个访问位R,0:未访问过 1 被访问
- 一个修改位M,0:未修改过 1 被修改
- R位被按期清零
- 共四类页面,00 01 10 11
- 按照00 -> 11前后顺序替换页面
- 先进先出页面置换算法(FIFO)及其改进
- 每次置换最早调入内存的页面
- 优势 : 实现比较简单,能够不须要硬件的支持
- 缺点 : 会发生Belady异常
- 第二次机会算法 - FIFO算法改进
- 基本思想与FIFO相同,改进是避免把常用的页面换出去,当选择置换页面时依然和FIFO同样,选择最先置入内存的页面。
- 可是第二次机会法还设置了一个访问状态位,因此还要检查页面的访问位,若是是0,就淘汰这页,若是访问位是1,就给第二次机会,并选择下一个FIFO页面
- 当一个页面获得第二次机会时,它的状态位就清0,它的到达时间就置为当前时间
- 若是该页在此期间被访问过,则访问位置为1
- 这样给了第二次机会的页面将不被淘汰,直至全部的其余页面被淘汰过(或者也给了第二次机会)。所以,若是一个页面常用,它的访问位总保持为1,就历来不会被淘汰出去
- 第二次机会算法可视为一个环形队列,用一个指针指示哪一页是下面要淘汰的,当缺页时,指针就往前遍历直到找到访问位是0的页。随着指针的前进,把访问位清0,在最坏的状况下,全部的访问位是1,指针要经过整个队列一周,每一个页都给第二次机会,这时就退化成FIFO算法。
- 时钟页面置换算法(CLOCK)
- 给每一个访问的页面关联一个附加位(reference bit),有些地方也叫作使用位(use bit)。
- 附加位造成一个大小为内存最大能支持的页面数量
- 当页面所有为1时,指针加一同时将全部use bit置0
- 最近最少使用页面置换算法(LRU) Least Recently Used => 性能接近OPT,但实现起来比较困难,开销大
- 最近最久未使用的页面被淘汰
- 当发生缺页中断时,选择未使用时间最长的页面置换出去
- 能够考虑使用一个大顶堆做为数据结构?
- 工做集算法
- 一个进程当前正在使用的页面 => 工做集(集合,页面重复)
- 设法跟踪进程的工做集,以确保在让进程运行前,它的工做集就已在内存中 = > 工做集模型
- 在进程运行前预先装入其工做集页面也称为预先调页
- 布隆过滤器的优缺点
- 一种比较巧妙的几率型数据结构(probabilistic data)
- 特色是高效插入和查询,能够用来得知”某样东西必定不存在或者可能存在“
- 优势
- 相比于传统的List、Set、Map等数据结构,更加高效、占用空间更少
- 缺点
- 返回的结果是几率性的而不是确切的
- 普通哈希查找的问题
- HashMap能够完成查找,可是考虑到负载因子,空间利用率经常不高
- 还好比数据集存储在远程服务器上,本地服务器接受输入,而数据集很是大不可能一次性读进内存构建HashMap的时候,也会存在问题
- 布隆过滤器数据结构
- 一个bit向量或者说是bit数组
- 要映射一个值到布隆过滤器中,须要使用多个不一样的哈希函数生成多个哈希值,并对每一个生成的哈希值指向的bit位置1
- 随着存储的数据增多,因为key冲突,未查找到的key必定不存在,查找到的key可能存在,也可能不存在
- 传统布隆过滤器不支持删除操做
- 布隆过滤器通常用来加速判断一个查找是否存在,因其判断不存在的操做很是廉价,能够避免肯定性哈希查找算法的昂贵操做
- 布隆过滤器实践
- 减小磁盘IO或者网络请求,由于一旦一个值一定不存在的话,咱们能够不用进行后续昂贵的查询请求
- 既然布隆过滤器用来加速查找和判断是否存在,那么性能很低的哈希函数不是个好选择,推荐MurmurHash、Fnv这些
- 处理大规模问题时的持久化,包括内存大小受限、磁盘换入换出问题
- 布隆过滤器trade-off
- 太小的布隆过滤器很快全部的bit均为1,那么查询任何值都会返回”可能存在“,起不到过滤的目的了。布隆过滤器的长度会直接影响误报率,布隆过滤器越长其误报率越小。
- 哈希函数的个数也须要权衡,个数越多则布隆过滤器bit位置为1的速度越快,且布隆过滤器的效率越低,可是若是太少的话,误报率会变高
- 有合适业务大小的k(哈希函数个数)和m(布隆过滤器长度)的推导公式
- 文件读写使用的系统调用
- 线程池的了解、优势、调度处理方式和保护任务队列的方式
- 为了不一个程序须要大量建立线程时的没必要要浪费,也就是最好的去避免线程建立与线程销回的开销,出现了线程池
- 线程池就是初始批量建立线程(一般认为CPU核心数的两倍为最佳,也有说是两倍+1,建立的线程为挂起状态(就绪),当咱们有任务要处理的时候,就激活一个线程完成任务,完成后线程又变为就绪态。
- 每一个线程一次建立,屡次使用
- 线程池怎么建立
- 怎么回收线程
- 多线程同步(项目中可能会问)
- mencache
- 异常和中断的区别
- 如何保证线程安全
- 生产者和消费者的程序,注意临界区和加锁
- OS内存管理实现
- 进程间调度和上下文切换怎么实现
- 系统调用或者说中断的过程
- 软中断 硬中断
- Inode是什么
- 文件的根节点,存储除了文件名以外的全部元数据信息,真正存储着数据所在硬盘地址的节点。
- 彷佛还有个文件控制块FCB、对比一下和Inode的区别
- 软链接 硬链接
- 硬链接不一样文件名指向同一个node,node中有引用计数
- 软链接只是节点中存储目标文件的绝对路径
- 删除硬链接和软链接的后果
- 硬链接会根据引用计数判断是否为0来决定是否删除文件
- 软链接不会
- Windos内存管理方式
- 分页存储
- 用户程序的逻辑地址空间被划分为若干固定大小的区域,称为:页“或者”页面“,相应地,内存物理空间也分红相对应地若干个物理块,页和块地大小相等,提升了内存的利用率
- 分段存储
- 将用户程序地址空间分红若干个大小不等的段,每段能够定义一组完整的逻辑信息。提升程序的逻辑性
- 段页式存储
- 二者结合,做业地址空间首先被分为若干个逻辑段,每段都有本身的段号,而后再将每段分红大小相等的页。
- 一个程序从开始运行到结束的完整过程
- 预处理
- 源代码.c -> 预处理器 -> .i文件,把替换头文件以及预处理宏定义
- 编译
- .i文件通过编译生成汇编.s文件
- 汇编
- .s的汇编文件通过汇编器生成.obj的目标文件
- 连接
- .obj通过连接器和lib(静态连接库)dll(动态连接库)文件生成exe可执行程序
- 头文件在编译过程当中的做用(网易游戏)
- 头文件并不参加连接和编译
- 在预处理阶段提供头文件替换
- 头文件里包含函数、库声明
- 通常不包含数据结构定义
- 头文件中可定义静态变量和静态函数
- 为什么不能再头文件中定义
- 防止多重定义
- 内存延迟分配实现方法
- VFS是啥
- 云计算?虚拟化?
- 内存分配的系统调用是什么
- Linux里的RCU是啥
- 锁
- Linux有哪些锁
- 死锁产生的缘由
- 系统资源的竞争
- 系统资源的竞争致使系统资源不足,以及资源分配不当,致使死锁。
- 进程运行推动顺序不合适
- 进程在运行过程当中,请求和释放资源的顺序不当,会致使死锁
- 什么状况下会发生死锁,解决策略有哪些
- 互斥条件:一次只有一个进程能够使用一个资源,已经分配掉的资源不能被从新占用
- 请求并保持条件:当一个进程在等待分配获得其余资源时,其继续占有已经分配获得的资源。
- 不可剥夺,非抢占:不能强行抢占进程中已经占有的资源。
- 循环等待:存在一个封闭的进程链,使得每一个资源至少占有此链中下一个进程所须要的一个资源。
- 解决策略
- 死锁预防 : 确保思索的一个必要条件不会知足
- 死锁检测 : 容许死锁的发生,可是能够经过系统设置的检测结构及时的检测思索地发生,采起一些措施,讲死锁清除掉。
- 死锁避免 : 银行家算法,在资源分配过程当中经过某种方法避免系统进入**不安全状态**,从而避免发生死锁。
- 死锁解除 : 与死锁检测配套的措施,检测到发生死锁,须要将进程从死锁中释放出来。
- 经常使用方法 : 撤销或者挂起一些进程,以便回收一些资源,再将资源分配给处于阻塞状态的进程。
- 撤销进程法
- 资源剥夺法
- 有哪些自旋锁,分别是怎么实现的
- Linux的地址空间布局是怎么样的
- 为何内核映射到每一个进程是同样的,若是每一个进程的内核映射是不同的会怎么样
- LRU算法
-
计算机网络
- OSI七层网络模型
- 交换机的工做原理和做用
- 对路由协议的理解与介绍,内部网关协议IGP包括RIP,OSPF和外网网关协议EGP和BGP
- 路由协议使用的算法
- 服务器攻击(DDos攻击)
- 路由器的工做原理和做用
- TCP可靠传输实现
- TCP和UDP
- 区别
- TCP滑动窗口
- “窗口”对应一段能够被发送者发送的字节序列,其连续的范围称之为“窗口”
- 滑动则是指这段“容许发送的范围”是能够随着发送的过程而变化的,方式就是按照顺序“滑动”
- 是为了进行流量控制,让发送方的发送速率不要太快,让接收方来得及接收
- Nagle算法
- 滑动窗口机制为端到端设备间的数据传输提供了可靠的流量控制机制。然而它只能在源端设备和目的端设备间起做用,当网络中间设备(例如路由器等)发生拥塞控制时,滑动窗口机制将不起做用。
- TCP拥塞控制
- 慢开始、拥塞避免、快重传、快恢复
- TCP拥塞控制和流量控制的区别
- 拥塞控制
- 防止过多的数据注入到网络中,这样能够使网络中的路由器或链路不会过载
- 流量控制
- 每每是点对点通讯量的控制,是一个端到端的问题,流量控制要作的是抑制发送端发送数据的速率,以便接收端来得及接收。
- TCP怎么样保证可靠性
- 应用数据被分割成TCP认为最合适发送的数据块
- 超时重传:当TCP发出一个段后,它启动一个定时器,等待目的端ACK确认收到这个报文段。若是不能及时收到一个确认ACK,将重发这个报文段
- TCP给发送的每个包进行编号,接收方对数据包进行排序,把有序数据传送给应用层
0 校验和:TCP将保持它首部和数据的校验和。这是一个端到端的检验和,目的是检测数据在传输过程当中的任何变化。若是收到段的检验和有差错,TCP将丢第这个报文段和不确认收到此报文段
- TCP的接收端会丢弃重复的数据
- 流量控制:让发送方的发送速率不要太快,要让接收方来得及接收
- 拥塞控制:当网络拥塞时,减小数据的发送
- TCP创建链接、重发、保证有序等
- TCP保证消息有序
- 连续发送连续确认,根据序号来保证有序
- TCP流水线传输
- 效率比较高
- HTTP协议和TCP协议的联系
- TCP协议是传输层协议,主要解决数据如何在网络中传输,而HTTP是应用层协议,主要解决如何包装数据。
- HTTP协议是创建在TCP协议基础上的,当浏览器须要从服务器获取网页数据的时候,会发出一次HTTP请求。
- HTTP会经过TCP创建起一个到服务器的链接通道,当本次请求须要的数据完毕后,HTTP会当即将TCP链接断开,这个过程是很短的。因此HTTP链接是一种短链接,是一种无状态链接。
- 网络的四层结构,TCP协议属于哪一层?(传输层)
- MTU
- MTU限制最大帧长度
- 因此当IP数据报超过MTU时,IP数据报必须分片
- TCP则会本身进行数据长度安排
- TCP三次握手
- C----->SYN(x)------>S, C进入SYN_SENT状态
- S收到请求报文段,S----->seq(y),ack(x+1)----->C, S进入SYN_REVD状态
- C收到S的SYN+ACK包,C----->seq(x+1),ack(y+1)-----S,此包发送完毕,C和S进入ESTABLISHED(TCP链接成功)状态,完成三次握手。
- TCP三次握手时client&server的状态,为何不是两次握手?
- 三次握手的状态
- 第一次C进入SYN_SENT状态
- 第二次S进入SYN_REVD状态
- 第三次C和S进入ESTABLSHED(TCP链接成功)状态,完成三次握手
- 须要三次的缘由
- 防止已经失效的报文段出如今本连接中
- TCP四次挥手过程?最后等待链接关闭要多长时间?
- 客户端发送断开TCP链接请求的报文,其中报文包含seq序列号,是由发送端随机生成的,而且还将报文中的FIN字段置为1,表示须要断开TCP链接。(FIN=1, seq=x, x由客户端随机生成)
- 服务端会回复客户端发送的TCP断开请求报文,其包含seq序列号,是由回复端随机生成的,并且会产生ACK字段,ACK字段数值是在客户端发过来的seq序列号基础上加1进行回复,以便客户端收到信息时,知晓本身的TCP断开请求已经获得验证。(FIN=1, ACK=x+1, seq=y, y由服务端随机生成)
- 服务端在回复完客户端的TCP断开请求后,不会立刻进行TCP链接的断开,服务端会先确保断开前,全部传输到A的数据是否已经传输完毕,一旦确认数据传输完毕,就会将回复报文的FIN字段置1,而且产生随机seq序列号。(FIN=1, ACK=x+1, seq=z, z由服务端随机生成)
- 客户端收到服务端的TCP断开请求后,会回复服务端的断开请求,包含随机生成的seq字段和ACK字段,ACK字段会在服务端的TCP断开请求的seq基础上加1,从而完成服务端请求的验证回复。(FIN=1, ACK=z+1, seq=h, h为客户端随机生成)至此TCP断开的4次挥手过程完毕
- 为何TCP创建链接要三次握手,而断开链接须要四次挥手?
- 由于S端收到C端的SYN链接请求报文后,能够直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。可是关闭链接时,当S端收到FIN报文时,极可能不会当即关闭SOCKET,因此只能先回复一个ACK报文,告诉C端“你发的FIN报文我收到了”。只有等到我S端全部的报文都发送完了,我才能发送FIN报文,所以不能一块儿发送,故须要四步握手。
- TIME_WAIT的意义,为何等于2MSL
- MSL是最长报文段寿命,设置的目的是
- 保证A发送的最后一个ACK可以到达B
- 防止已经失效的报文段出如今本链接中
- TCP头部校验的原理,安全吗?能够仿造嘛?
- TCP校验是一个端到端的校验和,由发送端计算,而后由接收端验证。其目的是为了发现TCP首部和数据在发送端到接收端之间发生的任何改动。若是接收方检测到的校验和有差错,则TCP段会被直接丢弃。
- 能够仿造
- 你会发现TCP报文超出MTU时,分组发送也会从新计算首部校验和
- TCP、UDP的区别?服务端和客户端创建的过程?
- TCP
- 传输控制协议提供的是面向链接、可靠的字节流服务。
- 当客户端和服务器彼此交换数据前,必须先在双方创建一个TCP链接,以后才能传输数据。TCP提供超时重发,丢弃重复数据,检验数据,流量控制等功能,保证数据能顺序地从一端传送到另外一端。
- UDP
- 用户数据协议,是一个简单地面向数据报地运输层协议。UDP不提供可靠性,它只是把应用程序传给IP层地数据报发送出去,可是并不能保证它们能到达目的地。因为UDP在传输数据报前不用再C/S之间创建一个链接,且无超时重发等机制,不保证数据按顺序传递,故而传输速度很快。
- UDP编程
- 服务器通常步骤
- 建立一个socket,用函数socket()
- 设置socket属性,用函数setsockopt()*可选
- 绑定IP地址、端口等信息到socket上,用函数bind()
- 循环接收数据,用函数recvform()
- 关闭网络链接
- 客户端通常步骤是
- 建立一个socket,用函数socket()
- 设置socket属性,用函数setsockopt(); *可选
- 绑定IP地址、端口等信息到socket上,用函数bind(); *可选
- 设置对方的IP地址和端口等属性
- 发送数据,用函数sendto()
- 关闭网络链接
- TCP编程
- 服务端
- 建立一个socket,用函数socket()
- 设置socket属性,用函数setsockopt()*可选
- 绑定IP地址、端口等信息到socket上,用函数bind()
- 开启监听,用函数listen()
- 接收客户端上来的链接,用函数accept()
- 接收数据,用函数send()和recv(),或者read()和write()
- 关闭网络链接
- 关闭监听
- 客户端
- 建立一个socket,用函数socket()
- 设置socket属性,用函数setsockopt()*可选
- 绑定IP地址、端口等信息到socket上,用函数bind() *可选
- 设置要链接的对方的IP地址和端口等属性
- 链接服务器,用函数connect()
- 收发数据,用函数send()和recv(),或者read()和write()
- 关闭网络链接
- 超时重传是怎么作的?
- ACK序号表示已经收到的序号吗?(关于重传)
- ACK表示返回已收到的序列
- 超时重传是对每一个序列作一个计时器,而后若是没有收到ACK则说明超时,重传
- 给每一个组分配不一样的IP段,怎么设计一种结构快速得知IP是哪一个组的
- Trie树是什么?
- B+树,每一个树节点保存一个段
- TCP粘包
- 发送缓冲区和接收缓冲区处理不及时或者大小设置不当,致使粘包和拆包。
- 正常状况:若是Socket Client发送的数据包,在Socket Sever端也是一个一个完整接收的,那个就不会出现粘包和分包状况,数据可正常读取
- 粘包状况:Socket Client发送的数据包,在客户端发送和服务器接收的状况下都有可能发送,由于客户端发送的数据都是发送的一个缓冲Buffer,而后由缓冲buffer最后刷到数据链路层的,那么就有可能把数据包2的一部分数据结合数据包1的所有被一块儿发送出去了,这样在服务器端就有可能出现这样的状况,致使读取的数据包包含了数据包2的一部分数据,产生粘包,固然也有可能把数据包1和数据包2所有读取出来。
- 分包状况:意思就是把数据包2或者数据包1都有可能被分开一部分发送出去,接着另外的部分,在服务器端有可能一次读取操做只读到一个完整数据包的一部分。
- 在数据包发送的状况下,有可能后面的数据包分开成2个或者多个,可是最前面的部分包,黏住在前面的一个完整或者部分包的后面。也就是粘包和分包同时产生了。
- 有没有抓过TCP包,描述一下
- 一个IP配置多个域名,靠什么识别?
- 主机头
- HTTP和HTTPS的区别,HTTPS是如何加密的,它的加密方式怎么样
- HTTP - 超文本传输协议
- HTTPS - 超文本传输安全协议
- HTTPS就是将HTTP中的传输内容进行了加密,而后经过可靠的链接(TCP),传输到对方的机器上。加密的协议是TLS,其前身是SSL
- http明文传输不安全,https加密传输
- 后者是前者的安全实现
- 客户端发起请求时服务端会返回一个公钥
- 而后客户端根据公钥规则发送消息
- 服务端根据本身的配对密钥解密实现加密
- 公钥放在哪里呢?
- HTTP中浏览器访问一个URL的流程
- 浏览器向DNS服务器查询输入的URL对应的地址
- DNS服务器返回网站的IP地址
- 浏览器根据IP地址与目标web服务器在80端口上创建TCP链接
- 浏览器获取请求页面的HTML代码
- 浏览器在显示窗口内渲染HTML
- 窗口关闭时,浏览器终止与服务器的链接
- URL包括
- 协议(或者称为服务方式)
- 存有该资源的主机IP地址(有时也包括端口号)
- 主机资源的具体地址,如目录和文件名等
- HTTP的四个会话过程
- 创建TCP链接
- 发出请求文档
- 发出响应文档
- 释放TCP链接
- 网页解析的过程
- 一个机器能使用的端口号上限
- 端口号两个字节:16位,因此最大表示65535
- 端口号不能超出限制,表示端口号的字节数也不能改变
- https创建链接的过程
- 数字证书
- 生成随机数
- 公钥加密
- 私钥加密
- 之后都用该随机数进行对称加密
- http请求方法有哪些?get和post的区别
- OPTIONS
- 返回服务器针对特定资源所支持的HTTP请求方法,也能够利用向web服务器发送‘*’的请求来测试服务器的功能性
- HEAD
- 向服务器索与GET请求相一致的响应,只不过响应体将不会被返回。这一方法能够再没必要传输整个响应内容的状况下,就能够获取包含在响应小消息头中的元信息。
- GET
- 向特定的资源发出请求。注意:GET方法不该当被用于产生“反作用”的操做中,例如在Web Application中,其中一个缘由是GET可能会被网络蜘蛛等随意访问。Loadrunner中对应get请求函数:web_link和web_url
- POST
- 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会致使新的资源的创建和/或已有资源的修改。 Loadrunner中对应POST请求函数:web_submit_data,web_submit_form
- PUT
- 向指定资源位置上传其最新内容
- DELETE
- 请求服务器删除Request-URL所标识的资源
- TRACE
- 回显服务器收到的请求,主要用于测试或诊断
- CONNECT
- HTTP/1.1协议中预留给可以将链接改成管道方式的代理服务器
- 根据HTTP规范,GET用于信息获取,并且应该是安全的和幂等的
- 根据HTTP规范,POST表示可能改变服务器上的资源的请求
- http1.0 和 http1.1有什么区别
- http1.1提供永久性链接,1.0使用非持久链接
- http1.1增长host头
- http1.1还提供了身份认证,状态管理和cache缓存机制等相关的请求头和响应头
- header、长链接、二进制
- http常见状态码
- 300
- 302
- 301
- 304
- http缓存说一下?
- 介绍一下Ping的过程,分别用到了哪些协议?
- 过程 ...
- ICMP协议
- icmp原理
- Restful和传统的http对比
- session和cookie讲一下
- session的出现是为了解决cookie存放本地并且量小的问题产生的,经过浏览器缓存的技术把须要的信息缓存,服务端就能够在同一应用中不一样页面传递数据,我的以为服务端采用的是hash表存放信息。
- 服务端会发送一个sessionid标识客户端
- cookies的最大保存时间
- SYN FLOOD了解吗?DDOS
- 洪泛攻击
- 分布式请求攻击
- 如何处理SYN FLOOD
- XSS原理
- 跨站点脚本注入
- 嵌入js代码致使页面被恶意篡改和重定向
- 介绍区块链
数据库SQL原理与应用
- 写SQL
- 左链接
- Mysql索引的原理、底层是怎么存的
- 主键和惟一键有什么区别
- 十亿个QQ号,每秒有10万条请求查询过来,如何处理
- 消息队列削峰
- 缓存查找
- 数据库集群
- innodb和MyISAM区别
- 数据库MD5加密方法的具体实现
- 三级范式
- 数据库CAP
- 数据库存储引擎了解吗?
- 底层索引怎么实现的?
- 黑名单功能算法实现
- 存储过程
- 经常使用的关系型数据库是MySQL,操做数据库的语言通常为SQL语句,SQL在执行的时候须要先编译,而后执行,而存储过程(Stored Procedure)是一组为了完成某种特定功能的SQL语句集,经编译后存储在数据库中,用户经过指定存储过程的名字并给定参数(若是该存储过程带有参数)来调用执行它
- 一个存储过程是一个可编程的函数,它在数据库中建立并保存。它能够有SQL语句和一些特殊的控制结构组成,当但愿在不一样的应用程序或平台上执行相同的函数或封装特定功能时,存储过程是很是有用的。数据库中的存储过程能够看做是对面向对象方法的模拟,它容许控制数据的访问方式
- 存储过程的优势
- 存储过程加强了SQL语言的功能和灵活性
- 存储过程能够用流控制语句编写,有很强的灵活性,能够完成复杂的判断和较复杂的运算
- 存储过程容许标准组件式编程
- 存储过程被建立后,能够在程序中被屡次调用,而没必要从新编写该存储过程的SQL语句,并且能够随时对存储过程进行修改,对应用程序源代码毫无影响
- 存储过程能实现较快的执行速度
- 若是某一操做包含大量的Transaction-SQL代码或者分别被屡次执行,那么存储过程要比批处理的执行速度快不少。由于存储过程是预编译的。在首次运行一个存储过程时,优化器对其进行分析优化,而且给出最终被存储在系统表中的执行计划。而批处理的Transaction-SQL语句每次运行时都要进行编译和优化,速度都相对要慢一些。
- 存储过程能减小网络流量
- 针对同一个数据库对象的操做(如查询、修改),若是这一操做涉及的Transacion-SQL语句被组织成存储过程,那么当在客户计算机上调用该存储过程时,网络中传送的只是该调用语句,从而大大增长了网络流量并下降了网络负载
- 存储过程可被做为一种安全机制来充分利用
- 系统管理员经过对执行某一存储过程的权限进行限制,可以实现相应的数据的访问权限的限制,避免了非受权用户对数据的访问,保证了数据的安全
- 索引
- 索引(Index)是帮助MySQL高效获取数据的数据结构,在数据以外,数据库兄还维护者知足特定算法查找的数据结构,这些数据结构以某种方式引用(指向)数据,能够在这些数据结构上实现高级查找算法,提升查询速度,这种数据结构,就是索引
- B-Tree索引 -> 最多见的索引类型,大部分引擎都支持B树索引
- HASH索引 -> 只有Memory引擎支持,使用场景简单
- R-Tree索引(空间索引) -> 空间索引是MyISAM的一种特殊索引类型,主要用于地理空间数据类型
- Full-text(全文索引) -> 全文索引也是MyISAM的一种特殊索引类型,主要用于全文索引,InnoDB从MySQL5.6版本提供对全文索引的支持
- 事务是什么
- 事务(Transaction)是并发控制的基本单位,所谓的事务,它是一个操做序列,由一条或者多条SQL语句组成,这些操做要么都执行,要么都不执行,它是一个不可分割的工做单位
- ACID特性
- 原子性(Atomicity)
- 指整个数据库事务是不可分割的工做单位,只有事务中全部的数据库操做都执行成功,整个事务的执行才算成功。事务中任何一个SQL语句执行失败,那么已经执行成功的SQL语句必须撤销,数据库状态应退回到执行事务以前的状态
- 一致性(Consistency)
- 事务应确保数据库的状态从一个一致状态转变为另外一个一致状态,一致状态的含义是数据库中的数据应知足完整性约束,也就是说事务开始以前和事务结束以后,数据库的完整性约束没有被破坏
- 隔离性(Isolation)
- 隔离性也叫作并发控制、可串行化或者锁
- 事物的隔离性要求每一个读写事务的对象与其余事务的操做对象能相互分离,即该事务提交前对其余食物都不可见,这一般使用锁来实现多个事务并发执行,一个事务的执行不该影响其余事务的执行
- 持久性(Durability)
- 表示事务一旦提交了,其结果就是永久性的,也就是数据已经写入到数据库了,若是发生了宕机事故,数据库也能将数据恢复
- 数据库中的“主属性”、“码”、“主码”的区别是什么?
- 在数据库的表(关系)中可以用于惟一区分开每一个记录(元组)的属性或属性的集合,咱们称之为码(候选码)
- 当咱们指定其中一个用来区分每一个记录(元组)的码称为主码
- 主属性是指包含在候选码中的属性
- 主码和码的关系就像班长和班长候选人之间的关系
- 每一个班长候选人,咱们可称之为主属性,只不过在数据库中,候选码多是多个属性共同组成的
计算机组成原理
实践应用
Linux
- Linux操做系统启动加载进程
- 熟悉的Linux命令
- 基本
- pwd rm
- touch 生成文件
- cat mkdir
- file 查看文件类型
- df 查看磁盘容量
- wc 计数工具
- tr 删除一段文本信息中的某些文字,或者将其进行转换
- join 链接两个文件
- paste 它是在不对比数据的状况下,简单的将多个文件合并在一块儿,以Tab隔开
- grep、awk、sed掌握程度
- grep 打印输出文本中匹配的模式串,它使用正则表达式做为模式匹配的条件
- sed 用于过滤和转换文本的流编辑器
- AWK是一种用于处理文本的编程语言工具
- 文件 : ls ll -a la
- lsof -p pid
- 列出被进程打开得文件的信息,被打开的文件能够是普通的文件、目录、网络文件系统的文件、字符设备文件、(函数)共享库、管道、命名管道、符号连接、底层的socket字节流、网络socket、unix域名socket
- 进程和文件 : ps top df du pstree
- 网络 : netstat ping curl traceroute
- 查看网络链接 netstat 都有什么状态,刚刚说的状态怎么发生
- 产看某个端口占用的进程
- netstat -anp
- 查看网络链接
- netstat -n
- ip a
- traceroute原理说一下
- icmp原理说一下
- 文本 : cat vi wc grep awk sed head tail more less
- 查找 : where is find -n locate which
- 权限 : chmod chown 777 su sudo
- 磁盘 :
- 定时任务和后台执行 : crontab nohup & 后台执行(终端能不能关掉?)
- 如何把文件快速下发到100w个服务器(迅雷怎么做到下载速度那么快的)
- P2P的下载,发布文件到整个网络中,每一个机器上既能上传又能下载
- Linux socket相关
- 在linux里面,大部分东西被当成文件
- 文件描述符做用
- 负责文件的标识,包括网络流、文件流、设备io流,这些均可以经过文件描述符来表示
- epoll => eventpoll linux内核实现IO多路复用的一个实现
- https://zhuanlan.zhihu.com/p/56486633
- select & epoll是什么?并发度各有什么限制?epoll为何快?
- 就序列表,根据场景
- epoll的水平触发和边缘触发
- 水平不断通知io就绪,边缘触发只有一次通知
- epoll后的套接字怎么存
- 红黑树 + 链表
- 阿里云linux版本
- 6.3
- 阿里云虚拟机版本
- 7.0
- Linux性能监测
- 待查
- Linux的I/O模型介绍以及同步异步非阻塞的区别
- 阻塞IO
- 非阻塞IO
- IO复用
- 信号驱动IO
- 异步IO
- Linux进程管理
- Linux内核的进程调度
- fork返回值是什么
- 什么是虚拟内存
- 文件系统的理解
- EXT4
- 使用普遍
- XFS
- XFS文件系统时扩展文件系统的一个扩展,XFS文件系统有一些缺陷,例如它不能压缩,删除大量文件时性能低下
- btrfs
- 有不少好用的功能,例如写复制、扩展校验、快照、清晰、自修复数据、冗余删除以及其余保证数据完整性的功能
- Linux的内存管理
- Linux如何避免内存碎片
- 伙伴算法,用于管理物理内存,避免内存碎片
- 高速缓存Slab层用于管理内核分配内存,避免碎片
- Linux如何打开一个文件,如何处理一个正在动态增加的文件
- IO复用的三种方法,poll、epoll、slect的特色和区别
- select、poll、epoll都是IO多路复用的机制
- IO多路复用就经过一种机制,能够监视多个描述符,一旦某个描述符就绪(通常是读就绪或者写就绪),可以通知程序进行相应的读写操做
- 但slect、poll、epoll本质上都是同步IO,由于他们都须要在读写事件就绪后本身负责进行读写,也就是说这个读写过程是阻塞的,而异步IO则无需本身负责进行读写,异步IO的实现会负责把数据从内核拷贝到用户空间
- SELECT
- 最初解决IO阻塞问题的方法。用结构体fd_set来告诉内核监听多个文件描述符,该结构体被称为描述符集。由数组来维持哪些描述符被置位了。对结构体的操做封装在三个宏定义中,经过轮询来查找是否有描述符要被处理,若是没有则返回
- 存在的问题
- 内置数组的形式使得select的最大文件数受限与FD_SIZE
- 每次调用select前都要从新初始化描述符集,将fd从用户态拷贝到内核态,每次调用select后,都须要将fd从内核态拷贝到用户态
- 轮询排查当文件描述符个数不少时,效率很低
- poll
- 经过一个可变长度的数组解决了select文件描述符受限的问题。数组中元素是结构体,该结构体保存描述符的信息,每增长一个文件描述符就向数组中加入一个结构体,结构体只要拷贝一次到内核态,poll解决了select重复初始化的问题,轮询排查的问题未解决。
- epoll
- 轮询排查全部文件描述符的效率不高,使服务器并发能力受限,所以,epoll采用只返回状态发生变化的文件描述符,便解决了轮询的瓶颈
- 为何使用IO多路复用,最主要的缘由是什么?
- epoll有两种触发模式?这两种触发模式有什么区别?编程的时候有什么区别?
- GDB调试
- Linux进程和线程如何建立、退出?进程退出的时候,本身没有释放的资源(如内存没有free)会怎么样?
git命令
- git init
- git pull
- git fetch git merge
- git commit
- git push
- git reset --hard
- git stash git stash pop
深度学习网络调优
分布式
- 什么是分布式
- 多节点部署
- 分布式存储
- 分布式计算
- 分布式部署
- 分布式存储架构
- 通常存储使用raid冗余阵列或者SSD快速磁盘
- raid0 raid 1区别?
- 分布式存储方案
- 块存储
- 直接对磁盘进行裸盘映射使用,甚至不安装文件系统,使用起来比较麻烦
- 文件存储
- 基于文件系统使用存储,经过网络协访问,好比ftp。通常是单机的存储系统
- 对象存储
- 包括控制节点和存储节点,控制节点存储元数据,存储结点存储数据,通常经过api使用,相似hdfs,结合块存储的速度和文件存储的易用性,而且支持并发读写。
- 分布式锁原理
- 间隙锁
- 可重复通常不能避免幻读(可是MYSQL中能够,它使用了gap lock+行级锁的增强版:next key lock来避免幻读)
- 序列化则是加表锁
- 固然使用mvcc机制也能够解决这个问题
- mvcc存储引擎
- 请求失败怎么办
- 重发
- 加锁失败怎么办
- 轮询cas
- 回滚失败怎么办
记录日志,重试
- 高并发与异步服务器怎么设计
- 网络IO的话就epoll大法好,异步就用回调模型
- 高并发就要多线程开发代码
- 具体设计就是请求到达、处理、访问IO、以及回复结果
加密算法
- MD五、SHA摘要算法,非对称加密
- RSA是对称加密算法,有公钥私钥之分,比较复杂
- 对称加密和非对称加密
- 对称加密(也叫私钥加密)指加密和解密使用相同密钥的加密算法。有时又叫传统密码算法,就是加密密钥可以从解密密钥中推算出来,同时解密密钥也能够从加密密钥中推算出来。
- 非对称加密算法须要两个密钥:公开密钥(public key)和私有密钥(private key)。公开密钥与私有密钥是一对,若是用公开密钥对数据进行加密,只有用对应的私有密钥才能解密,若是用私有密钥对数据进行加密,那么只有用对应耳洞公开密钥才能解密。由于加密和解密使用的是两个不一样的密钥,因此这种算法才叫作非对称加密算法。
- 数字证书的了解(高频)
- 客户端为何信任第三方证书?
- RSA加密算法,MD5原理
- 单条记录高并发访问的优化
redis
- redis的主从复制怎么作的
- aof 和 rdb两种同步方式
- redis在项目中用来干什么,基于什么考虑
- 讲了频繁访问的数据放到redis中,还有拿redis作异步任务队列
- 单机redis有可能挂掉,解决措施
- 单机作持久化,主从部署
- 哨兵或者集群
- 集群redis挂掉的话,解决措施。
- 把数据访问直接转到mysql
- 是否是最好加一个异步任务队列来作数据库操做
- 整个集群挂掉只能异地容灾
- redis挂掉了,而后如今恢复了,怎么作,redis挂掉的这段时间,你是把在mysql上存取数据,这样势必要同步数据到redis。可是同步这个过程你redis是须要被访问的,解决措施 :
- 同步后访问
- 增量同步
- 主从,写入主、访问从
- 数据库分库分表,垂直和水平来分,若是某个问题数据量暴增,讲了用分类来做为分库的依据,又给了场景,若是某类问题数据暴增,要怎么作。后面面试官说了基于预测,能够先作一个冗余库。好比某类问题有可能会数据量暴增,那能够对这个模块加冗余的库。而后冗余库接下来去怎么用这个...没听清楚(hash?)
- 垂直分业务,水平分数量
- 划分依据,好比id、时间戳、根据场景、好比某个类
- 分片的规则就是进行hash,取模等方式进行
- 最好使用数据库中间件如mycat
- 惊群效应和雪崩效应说一下,redis源码看过没
- 多线程/多进程(linux下线程进程也没多大区别)等待同一个socket事件
- 当这个socket事件发生时,这些线程/进程被同时唤醒,这就是惊群。
- 惊群效率很低下,许多进程被内核从新调度唤醒,同时去响应这一事件,固然只有一个进程只能处理事件成功,其余的进程在处理该事件失败后从新休眠(也有其余选择)。这种性能浪费现象就是惊群。
- 惊群一般发生在server上,当父进程绑定一个端口监听socket,而后fork出多个子进程,子进程们开始循环处理(好比accept)这个socket。
- 每当用户发起一个TCP链接时多个子进程被同时唤醒,而后其中一个子进程accept新链接成功,余者皆失败,从新休眠。
- 避免惊群要保证每次只通知到一个等待线程
- 其实在linux2.6内核上,accept系统调用已经不存在惊群了(至少我在2,6,18内核版本上已经不存在)。你们能够写个简单的程序试下,在父进程中bind,listen,而后fork出子进程,全部的子进程都accept这个监听句柄。
- 这样,当新链接过来时,你们会发现,仅有一个子进程返回新建的链接,其余子进程继续休眠在accept调用上,没有被唤醒。
- however,一般咱们的程序没那么简单,不会愿意阻塞在accept调用上,咱们呢还有许多其余网络读写事件处理,linux下咱们爱用epoll解决非阻塞socket。因此,即便accept调用没有惊群了,咱们也还得处理惊群这事,由于epoll有这问题。上面说的测试程序,若是咱们在子进程内不是阻塞调用accept,而是用epoll_wait,就会发现,新链接过来时,多个子进程都会在epoll_wait后被唤醒。
- 惊群的性能瓶颈是什么
- 性能瓶颈是内存大小
- nginx惊群效应?
- nginx就是这样,master进程监听端口号(例如80),全部的nginx worker进程开始用epoll_wait开始用来处理新事件,若是不加任何保护,一个新链接来临时,会有多个worker进程在epoll_wait后被唤醒,而后发现本身accept失败。
- nginx处理惊群
- nginx的每一个worker进程在函数ngx_process_events_and_timer中处理事件,(void)ngx_process_events(cycle, timer, flags);封装了不一样的事件处理机制,在linux上默认就封装了epoll_wait调用。咱们来看看ngx_process_events_and_timers为解决惊群作了什么, 代码过长,存储在另一个地方。
- 简单的说,就是同一时刻只容许一个nginx worker在本身的epoll中处理监听句柄。它的负载均衡也很简单,当达到最大connection时,本worker不会去试图拿accept锁,也不会去处理新连接,这样其余nginx worker进程就有机会去处理监听句柄,创建新连接了。并且,因为timeout的设定,使得没有拿到锁的worker进程,去拿锁的频率更高。
nginx的七层负载和四层负载均衡
- nginx的消息中间件
消息中间件开源
- kafka, rabbitmq
tomcat
- 网络上点击一个连接说一下全过程,到tomcat后,tomcat作了什么呢?
- 底层如何处理整个请求的?详细说一下?
- 线程池,NIO,socket,servlet等
设计模式
- 参考资料《设计模式之禅》,简要了解一下便可
- 23种设计模式
- 单例模式程序的实现
软件工程
- 软件的健壮性是指什么
- 程序能够适应正常和非正常的运行环境,均可以正常的运行,随着业务量的增长,不会出现阻塞和不可用的状况
- 影响程序健壮性的因素
- 没有容错控制
- 执行耗时的操做
- 执行复杂的任务
- 数据不一致
- 算法效率低
- 不能应对大流量冲击
- 什么是正确性
- 不可重入的任务被重入
- 没有前置状态断定
- 没有遵照”受理-处理-关闭“AHC模型
- 没有遵照“申请-前置审批-审批-善后-完成”RPC模型
- 数据库复制形成的数据延迟
Java思想
- Java四个特性
- Java GC原理,什么对象会进入老年代?垃圾回收算法有哪些?为何新生代使用复制算法?
- Java里面的final关键字怎么用的?
- 重载和重写的区别?相同参数不一样返回值能重载吗?
- 不能
- 进程通讯、GC机制
- 共享内存
- 管道和信号量
- JVM内存模型
- JVM里的堆就是一个公共区间,线程负责取资源,这样就能够实现资源共享
- 内存模型
- Java里面抽象类和接口的区别,同步机制的方式
- 接口能不能直接执行方法
- Java网络编程,Java中socket的使用,腾讯基本用Java来作网络编程,其余的都用C来实现。
- Java反射机制
- 在类加载的加载阶段会产生java.lanag.class对象,并且初始化阶段jvm也规定由relect包下的方法必须加载进来,这样就能够经过class forname动态加载类得到对象和调用getclass得到class对象,而后再用newinstance方法得到对象,...不够全面
- 依赖倒置
- Java里的sort方法
- hashmap和hash冲突
- 1.7用数组+单链表,1.8变成了红黑树
- 初始容量和扩容问题
- 取哈希值的改进,能够算得更快
- HashMap和concurrenthashmap内部实现细节
智力题
- 100层楼,2个鸡蛋,鸡蛋从某一个临界楼层丢下会摔碎,请设计方案,能用最小的次数找到临界楼层
- 用3,4,5,6,7,8组成不重复的4位奇数,按照从小到大的顺序排序,第62个数字是?
- 24点游戏
- 25匹马,5个跑道,如何经过最少的比赛次数肯定前3名?
- 一家人过桥问题
待定
- 如何处理SYN FLOOD
注意事项
- 尽可能现场面试
- 作加法 : 充实本身的知识面,计网、操做系统、数据结构和常见算法、开发框架都要懂一些,而后挑其中一个深挖一下。
- 作减法 : 不要提到任何本身不熟的东西,包括简历上和自我介绍中,禁不起深挖的项目,课程都要删掉。
- 作总结:对于简历上每个项目经历、实习经验都要总结。对本身的贡献和过程当中的难点进行整理。
- 创建排版 : 简历控制在一页内。
跟面试官交流下怎么修改简历
团队、业务问题
- 如何解决团队中的冲突,在团队讨论中该怎么作。
- 先听onwer的解决方案,而后提意见,本身是owner本身先有解决方案,而后听其余人意见。
- 怎么看由于工做换主语言
- 项目主要作的啥?本身负责的部分?
- 以为最很差解决的几个问题?怎么解决的?
- 家里哪里的?爸爸妈妈干什么的?
- 还投了别的什么公司吗?偏向于哪一个?
- 找实习比较看重什么?
- 家庭状况、女票、互联网行业高压、腾讯文化、房价
我的提问环节
- 秒杀系统设计
- 爆发性增加的数据给数据库带来的问题
- 常规三问
- 您是哪一个部门的,作什么?
- 对我今天面试的表现评价一下?
- 对我从此的学习或者工做提些建议?