后台开发面试题.md

面试题

一、数据库

1.使用mysql索引都有哪些原则

​ 1.对于查询频率高的字段创建索引

​ 2.对排序、分组、联合查询频率高的字段创建索引

​ 3.索引的数目不宜过多

​ 原因:a、每创建一个索引都会占用相应的物理空间

​ b、过多的索引会导致insert、updata、delete语句的执行效率降低

​ 4.若在实际中,需要将多个列设置索引时,可以采用多列索引

​ 5.选择唯一性索引

​ 6.尽量使用数据量少的索引

​ 7.尽量使用前缀来索引

​ 8.删除不再使用或者很少使用的索引

2.从Innodb的索引结构分析,为什么索引的Key长度不能太长

​ key太长会导致一个页当中存放的key的数目变少,间接导致索引树的页数目变多,索引层次增加,从而影响整体查询变更的效率

3.数据库事务有哪些

​ 原子性:所有操作要么全部成功,要么全部失败

​ 一致性:例如转账,一个事务执行前和执行后必须一致

​ 隔离性:防止脏读,重复读问题

​ 持久性:永久性提交数据库

4.SQL语句优化

​ 1.

二、时间复杂度

1.优先队列时间复杂度

​ 优先级队列用堆实现,只是需要构建初始堆,这个时间复杂度是O(n),插入和删除只是修改了堆顶和堆底,不需要所有的都排序,只是需要再次调整好堆,因此时间复杂度都是O(log2n),堆的维护时间复杂度就是O(n)

2.红黑树如果插入和删除的

​ 插入:

​ (1)如果父节点为黑色,直接插入不处理

​ (2)如果父节点为红色,叔叔节点为红色,则父节点和叔叔节点变为黑色,祖先节点变为红色,将节点操作转换为祖先节点

​ (3)如果当前节点为父亲节点的右节点,则以父亲节点为中心左旋操作

​ (4)如果当前节点为父亲节点的左节点,则父亲节点变为黑色,祖先节点变为红色,以祖先节点为中心右旋操作

​ 删除:

​ (1)先按照排序二叉树的方法,删除当前节点,如果需要转移即将转移到下一个节点

​ (2)当前节点,必定为这样的情况,没有左子树

​ (3)删除为红色节点,不需要处理,直接按照删除二叉树节点一样

​ (4)如果兄弟节点为黑色,兄弟节点的两个子节点为黑色,则将兄弟节点变为红色,将着色转移到父亲节点

​ (5)如果兄弟节点为红色,将兄弟节点设为黑色,父亲节点设为红色节点,对父亲节点进行左旋操作

​ (6)如果兄弟节点为黑色,左孩子为红色,右孩子为黑色,对兄弟节点进行右旋操作

​ (7)如果兄弟节点为黑色,右孩子为红色,则将父亲节点的颜色赋值给兄弟节点,将父亲节点设置为黑色,将兄弟节点的右孩子设为黑色,对父亲节点进行左旋

3.CPU是怎么执行指令的

​ 计算机每执行一条指令都可分为三个阶段进行,即取指令——分析指令——执行指令

​ 取指令:根据程序计数器PC中的值从程序存储器读出现行指令,送到指令寄存器

​ 分析指令:将指令寄存器中的指令操作码取出来后进行译码,分析其指令性质,如指令 要求操作数,则寻找操作数地址

​ 执行指令:逐条指令的重复执行上述操作过程,直至遇到停机指令可循环等待指令

4.什么函数不能声明为虚函数

​ 1.普通函数(非成员函数)只能重载,不能被覆盖,不能被声明为虚函数,因此,编译器会在编译时绑定函数

​ 2.静态成员函数不能是虚函数,因为静态成员函数对于每个类来说只有一份代码,所有的对象都共享这一份代码,它不归某个对象所有,所以它也没有动态绑定的必要性

​ 3.内联成员函数不能是虚函数,因为内联函数本身就是为了在代码中直接展开,减少函数调用花费的代价而设立的,而虚函数是为了在继承后对象能够准确的执行自己的动作,这是不可能统一的,再说,inline函数在编译时被展开,虚函数在运行时才能动态的绑定函数

​ 4.构造函数之所以不能是虚函数,因为构造函数本来是为了明确初始化对象成员才产生的,然而虚函数主要是为了在不完全了解细节的情况下也能正确处理对象,另外虚函数是在不同类型的对象产生不同的动作,现在对象还没有产生,如何使用虚函数来完成你想完成的动作呢?

​ 5.友元函数,C++语言不支持友元函数的继承,对于没有继承特性的函数没有虚函数的说法,友元函数不属于类的成员函数,不能被继承,所以友元函数不能是虚函数

5.线上CPU爆高,请问如何找到问题所在

​ 1.top命令:Linux命令。可以查看实时的CPU使用情况,也可以查看最近一段时间的CPU使用情况

​ 2.ps命令:Linux命令。强大的进程状态监控命令,可以查看进程以及进程中线程的当前CPU使用情况,属于当前状态的采样数据

​ 3.pstack:Linux命令,可以查看某个进程的当前线程栈运行情况

6.为什么要字节对齐?

​ 1.有些特殊的CPU只能处理4倍开始的内存地址

​ 2.如果不是整数倍数读取会导致读取多次

​ 3.数据总线为读取数据提供了基础

7.操作系统进程调度策略有哪几种

​ FCFS(先来先服务),优先级,时间片轮转,多级反馈-调度算法

​ 1.先来先服务调度算法:是一种最简单的调度算法,每次调度是从进程队列中选择一个最先进入该队列的进程,为之分配资源投入运行,该进程一直运行完全或发生某事件而阻塞后才继续处理后面的进程

​ 2.优先级调度算法:有短进程优先级,高优先权优先级、高响应比优先级等,按照优先级来执行就绪队列中的调度。(高响应比:(等待时间+服务运行时间)/服务运行时间)

​ 3.时间片轮转调度算法:系统还是按照先来先服务调度就绪进程,但每次调度时,CPU都会为队首进程分配并执行一个时间片,执行时间片用完后计时器即产生时钟中断,停止该进程并将它送到队尾,其他依次执行,这样保证系统能在给定的时间内执行所有用户进程的请求

​ 4.多级反馈调度算法:前面都有局限性,综合——>多级反馈调度算法则不必事先知道各进程所需的执行时间,而且还可以满足各类型进程的需要,因此它是目前被公认的一种较好的进程调度算法。

​ (1)设置多个就绪队列,每个队列优先级依次减小,为每个队列分配的时间片大小不同,优先级队列越高,里面进程规定的执行时间片就越小

​ (2)队列中还是按照FCFS原则排队等待,如果第一队列队首进程在规定的时间片内未执行完,则直接调送至第二队尾,依次向后放一个队列的队尾,因此一个长作业进程会分配到n个队列的时间片执行

​ (3)按照队列先后依次执行,如果新进的待处理进程优先级较高,则新进程将抢占正在执行的进程,被抢占的进程放置正在运行的队尾

8.Linux操作系统重要部分

​ Linux系统一般有4个主要部分:内核、shell、文件系统和应用程序,内核、shell、和文件系统一起形成了基本的操作系统结构,它们使得用户可以运行程序、管理文件并使用系统

​ 1.Linux内核是操作系统的核心,具有很大基本功能,如虚拟内存,多任务,共享库,需求加载,可执行程序和TCP/IP网络功能,Linux内核的模块分为以下几个部分:存储管理、CPU和进程管理、文件系统、设备管理和驱动、网络通信、系统的初始化和系统调用等

​ 2.Linux shell是系统的用户界面,提供了用户与内核进行交互操作的一种接口,它接收用户输入的命令并把它送入内核去执行,是一个命令解释器,另外,shell编程语言具有普遍编程语言的很大特点,用这种编程语言写的shell程序与其他应用程序具有相同的效果

​ 3.Linux文件系统是文件存放在磁盘等存储设备上的组织方式,Linux系统能支持多种目前流行的文件系统,如EXT2、EXT3、FAT、FAT32

​ 4.Linux应用程序,标准的Linux系统一般都有一套称为应用程序的程序集,它包括文本编辑器、编程语言、XWindow、办公套件、Internet工具和数据库等

9.TCP的nagle算法和延迟ack,还有CORK

​ nagel算法:防止网络中存在太多小包而造成网络拥塞

​ 延迟ack:减少ACK包的频繁发送

​ CORK:将多个包变成一个包发送,提高网络利用率,使载荷率更大

​ 不可以一起使用

10.什么是协程?

协程是一种比线程更加轻量级的存在,正如一个进程可以拥有多个线程一样,一个线程也可以拥有多个协程,更重要的是,协程不是被操作系统内核所管理,而完全是由程序所控制(也就是用户态执行),这样的好处就是性能得到了很大的提升,不会像线程切换那样消耗资源,协程的暂停完全由程序控制,线程的阻塞是由操作系统内核来进行切换,因此协程的开销远远小于线程的开销

11.请求页面置换策略有哪些方式,它们的区别是什么,各自有什么算法解决

​ 全局和局部

​ 全局:在整个内存空间置换

​ 1.工作集算法 2.缺页率置换算法

​ 局部:在本进程中进行置换

​ 1.最优算法 2.FIFO先进先出算法 3.LRU最近最久未使用 4.时钟算法

12.创建进程的步骤

​ 1.申请空的PCB

​ 2.为新进程分配资源

​ 3.初始化PCB

​ 4.将新进程插入就绪队列中

13.进程切换发生的原因,处理进程切换的步骤

​ 原因:(1)中断发生(2)更高优先级进程唤醒(3)进程消耗完了时间片(4)资源阻塞

​ 步骤:

​ (1)保存处理器的上下文

​ (2)用新状态和其它相关信息更新正在运行进程的PCB

​ (3)将原来的进程移到合适的队列中【就绪、阻塞】

​ (4)选择另一个执行的进程,更新被选中进程的PCB,将它加载进CPU

14.拥塞控制的方式,快重传的时机是什么

​ 1.慢开始

​ 2.拥塞避免

​ 3.快重传【收到3个失序分组确认】

​ 4.快恢复

15.分段机制和分页机制的区别

​ 1.分页机制会使用大小固定的内存块,而分段管理则使用了大小可变的块来管理内存

​ 2.分页使用固定大小的块更为适合管理物理内存,分段机制使用大小可变的块更适合处理复杂系统的逻辑分区

​ 3.段表存储在线性地址空间,而页表则保存在物理地址空间

16.关键字const是什么含义

​ 1.欲阻止一个变量被改变,可以使用const关键字,在定义该const变量时,通常需要对它进行初始化,因为以后就没有机会再去改变它了

​ 2.对指针来说,可以指定指针本身为const,也可以指定指针所指的数据为const,或二者同时指定为const

​ 3.在一个函数声明中,const可以修饰形参,表明它是一个输入参数,在函数内部不能改变其值

​ 4.对于类的成员函数,若指定其为const类型,则表明其是一个常函数,不能修改类的成员变量

​ 5.对于类的成员函数,有时候必须指定其返回值为const类型,以使得其返回值不为左值

17.C++中static有什么作用

​ 1. 隐藏。当我们同时编译多个文件时,所有未加static前缀的全局变量和函数都具有全局可见性,故使用static在不同的文件中定义同名函数和同名变量,而不必担心命名冲突

​ 2. static的第二个作用是保持变量内容的持久。存储在静态数据区的变量会在程序刚开始运行时就完成初始化,也是唯一的一次初始化,共有两种变量存储在静态存储区,全局变量和static变量

​ 3. static的第三个作用是默认初始化为0,其实全局变量也具备这一属性,因为全局变量也存储在静态数据区,在静态数据区,内存中所有的字节默认值都是0x00,某些时候这一特点可以减少程序员的工作量

18.在C++程序中调用被C编译器编译后的函数,为什么要加extern “C”声明

​ 函数和变量被C++编译后在符号库中的名字与C语言的不同,被extern “C”修饰的变量和函数是按照C语言方式编译和连接的,由于编译后的名字不同,C++程序不能直接调用C函数,C++提供了一个C连接交换指定符合extern “C”来解决这个问题

19.delete []arry 和delete arry的区别

​ delete []arry释放的是多个同一类型的地址空间

​ delete arry释放的是一个某种类型的地址空间

20.输入www.baidu.com在浏览器的完整过程越详细越好

​ 1. 浏览器获取输入的域名www.baidu.com

​ 2. 浏览器向域名系统DNS请求解析www.baidu.com的IP地址

​ 3. DNS解析出百度服务器的IP地址

​ 4. 浏览器与服务器建立TCP连接(默认端口号80)

​ 5. 浏览器发出HTTP请求,请求百度首页

​ 6. 服务器通过HTTP请求把首页文件发给浏览器

​ 7. TCP连接释放

​ 8. 浏览器解析首页文件,展示web界面

21.请描述C/C++程序的内存分区

​ 1. 栈区(stack)——由编译器自动分配释放,存放函数参数值,局部变量的值等,其操作方式类似于数据结构中的栈

​ 2. 堆区(heap)——一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收。分配方式类似于链表

​ 3. 全局区(静态区static)——全局变量和静态变量的存储是放在一起的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量的在相邻的另一块区域,程序结束后由系统释放

​ 4. 文字常量区——常量字符串就是放在这里的,程序结束后由系统释放

​ 5. 程序代码区——存放函数体的二进制代码

22.栈区和堆区的区别

​ 1. 堆和栈中的存储内容,栈存储局部变量、函数参数等,堆存储使用new、malloc申请的变量等

​ 2. 申请方式:栈内存由系统分配,堆内存由自己申请

​ 3.申请后系统的响应:

​ 栈——只要栈的剩余空间大于所申请空间,系统将为程序提供内存,否则将报异常提示栈溢出

​ 堆——首先应该知道操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时,会遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点的空间分配给程序

​ 4.申请大小的限制:Windows下栈的大小一般是2M,堆的容量较大

​ 5.申请效率的比较:栈由系统自动分配,速度较快,堆使用new、malloc等分配,较慢

你可能感兴趣的:(后台开发面试题.md)