C++基础(二)

牛客课程学习,关于C++的操作系统、计算机网络、数据库、设计模式的八股文。

文章目录


一、C++操作系统

1.Linux中查看进程运行状态的指令、查看内存使用情况的指令、tar解压文件的参数。

(1)查看进程允许状态:ps命令。“ps -aux | grep PID”,用来查看某PID进程状态。
(2)查看内存使用情况的指令:free命令。“free -m”,命令查看内存使用情况。
(3)tar解压文件的参数(必选其中之一):Ⅰ.-c:建立压缩档案;Ⅱ.-x:解压
Ⅲ.-t:查看内容;Ⅳ. -r:向压缩归档文件末尾追加文件;Ⅴ.-u:更新原压缩包中的文件。
(4)tar解压文件的参数(可选):Ⅰ.-z:有gzip属性的;Ⅱ.-j:有bz2属性的;Ⅲ.-Z:有compress属性的;Ⅳ.-v:显示所有过程;Ⅴ.-O:将文件解开到标准输出。
(5)-f后面跟档案名称,必须的。
(6)常用的解压命令:tar -zxvf xxx.gz;gz是gzip
(7)常用的压缩命令:tar -zcvf xxx.tar.gz;gz是gzip

2. 文件权限怎么修改?

(1)Linux文件的基本权限就有九个,分别是owner(属主)/group(同组)/others(其他组)三种身份的rwx权限。
(2)修改权限指令: chmod [-R] xyz 文件或目录

3.如何以root权限运行某个程序?

通过以下2个命令就可以了:
sudo chown root (文件名)
sudo chmod u+s (文件名)

4.软链接和硬链接的区别?

(1)定义不同。软链接又叫符号链接,这个文件包含了另一个文件的路径名。(路径)硬链接就是一个文件的一个或多个文件名(文件)。
(2)限制不同。硬链接只能对已存在的文件进行创建,不能交叉文件系统进行硬链接的创建;软链接可对不存在的文件或目录创建软链接;可交叉文件系统;
(3)创建方式不同。硬链接不能对目录进行创建,只可对文件创建;软链接可对文件或目录创建;
(4)影响不同。删除一个硬链接文件并不影响其他有相同 inode 号的文件。删除软链接并不影响被指向的文件,但若被指向的原文件被删除,则相关软连接被称为死链接。

5.静态库和动态库怎么制作及如何使用,区别是什么?

(1)静态库制作:①gcc hello.c;②ar rcs libhello.a hello.o.
动态库制作:①gcc -shared -fpic hello.c -o libhello.so;②-shared 指定生成动态库
③-fpic :fPIC选项作用于编译阶段,在生成目标文件时就得使用该选项,以生成位置无关的代码
(2)静态库使用:gcc main.c -lhello -o staticLibrary
动态库使用:gcc main.c -lhello -L ./ -o dynamicDepot
(3)区别:①静态库代码装载的速度快,执行速度略比动态库快。②动态库更加节省内存,可执行文件体积比静态库小很多。③静态库是在编译时加载,动态库是在运行时加载。④生成的静态链接库,Windows下以.lib为后缀,Linux下以.a为后缀。生成的动态链接库,Windows下以.dll为后缀,Linux下以.so为后缀。

6.GDB常见的调试命令,什么是条件断点,多进程下如何调试?

(1)GDB调试:gdb调试的是可执行文件,在gcc编译时加入 -g ,告诉gcc在编译时加入调试信息,这样gdb才能调试这个被编译的文件 gcc -g tesst.c -o test。
(2)条件断点:break if 条件 以条件表达式设置断点
(3)多进程下调试:用set follow-fork-mode child 调试子进程 或者set follow-fork-mode parent 调试父进程。

7.什么是大端小端,如何判断大端小端?

(1)小端模式:低的有效字节存储在低的存储器地址。小端一般为主机字节序;常用的X86结构是小端模式。
(2)大端模式:高的有效字节存储在低的存储器地址。大端为网络字节序;KEIL C51则为大端模式。
(3)相同字节序的平台在进行网络通信时可以不进行字节序转换,但是跨平台进行网络数据通信时必须进行字节序转换。如果当前平台是大端,则直接返回不进行转换,如果当前平台是小端,会将接收到得网络字节序进行转换。

8.进程调度算法有哪些?

(1)先来先服务调度算法
(2)短作业(进程)优先调度算法
(3)高优先级优先调度算法
(4)时间片轮转法
(5)多级反馈队列调度算法
抢占式:允许将逻辑上可继续运行的在运行过程暂停的调度方式可防止单一进程长时间独占,CPU系统开销大
非抢占式:让进程运行直到结束或阻塞的调度方式,容易实现,适合专用系统,不适合通用系统。

9.操作系统如何申请以及管理内存的?

(1)操作系统如何管理内存:物理内存有四个层次,分别是寄存器、高速缓存、主存、磁盘。
(2)虚拟内存:操作系统为每一个进程分配一个独立的地址空间,但是虚拟内存。虚拟内存与物理内存存在映射关系,通过页表寻址完成虚拟地址和物理地址的转换。
(3)从操作系统角度来看,进程分配内存有两种方式,分别由两个系统调用完成:*brk和mmap

10.Linux系统态与用户态,什么时候会进入系统态?

(1)内核态与用户态:内核态(系统态)与用户态是操作系统的两种运行级别。
(2)内核态拥有最高权限,可以访问所有系统指令;用户态则只能访问一部分指令。
(3)用户态进入内核态有3种方法:a、系统调用。b、异常。c、设备中断。系统调用是主动的,另外两种是被动的。
(4)区分内核态与用户态主要是出于安全的考虑。

11.LRU算法及其实现方式?

(1)LRU算法用于缓存淘汰。思路是将缓存中最近最少使用的对象删除掉。
(2)利用链表和hashmap。当需要插入新的数据项的时候,如果新数据项在链表中存在(一般称为命中),则把该节点移到链表头部,如果不存在,则新建一个节点,放到链表头部,若缓存满了,则把链表最后一个节点删除即可。
(3)在访问数据的时候,如果数据项在链表中存在,则把该节点移到链表头部,否则返回-1。这样一来在链表尾部的节点就是最近最久未访问的数据项。

12.一个线程占多大内存?

(1)一个linux的线程大概占8M内存。

13.什么是页表,为什么要有?

(1)页表是虚拟内存的概念。操作系统虚拟内存到物理内存的映射表,就被称为页表。
(2)不可能每一个虚拟内存的 Byte 都对应到物理内存的地址。这张表将大得真正的物理地址也放不下,于是操作系统引入了页(Page)的概念。进行分页,这样可以减小虚拟内存页对应物理内存页的映射表大小。

14.简述操作系统中的缺页中断?

(1)缺页异常:malloc和mmap函数在分配内存时只是建立了虚拟地址空间,并没有分配虚拟内存真正的物理内存。
(2)缺页中断:缺页异常后将产生一个缺页中断,此时操作系统会根据页表中的外存地址在外存中找到所缺的一页,将其调入内存。

15.为什么要用虚拟内存?

(1)虚拟内存:操作系统为每一个进程分配一个独立的地址空间,是虚拟内存。虚拟内存与物理内存存在映射关系,通过页表寻址完成虚拟地址和物理地址的转换。
(2)进程地址空间不隔离。会导致数据被随意修改。
(3)内存使用效率低。
(4)程序运行的地址不确定。操作系统随机为进程分配内存空间,所以程序运行的地址是不确定的。

16.使用虚拟内存的好处和缺点?

(1)好处:Ⅰ.扩大地址空间。Ⅱ.内存保护。Ⅲ.可以实现内存共享,方便进程通信。Ⅳ.可以避免内存碎片,虽然物理内存可能不连续,但映射到虚拟内存上可以连续。
(2)缺点:Ⅰ.可以避免内存碎片,虽然物理内存可能不连续,但映射到虚拟内存上可以连续。Ⅱ.虚拟地址到物理地址的转换,增加了执行时间。Ⅲ.页面换入换出耗时。Ⅳ.一页如果只有一部分数据,浪费内存。

17.虚拟地址到物理地址怎么映射的?

(1)操作系统为每一个进程维护了一个从虚拟地址到物理地址的映射关系的数据结构,叫页表。
(2)逻辑地址转线性地址:段起始地址+段内偏移地址=线性地址。
(3) 页目录地址 + 页目录索引 = 页表地址
页表地址 + 页表索引 = 页地址
页地址 + 页内偏移 = 物理地址

18.堆栈溢出是什么,会怎么样?

(1)堆溢出:比如不断的new 一个对象,一直创建新的对象,而不进行释放,最终导致内存不足。
(2)栈溢出:一次函数调用中,栈中将被依次压入:参数,返回地址等,而方法如果递归比较深或进去死循环,就会导致栈溢出。

19.操作系统中malloc的实现原理?

(1)malloc底层实现:当开辟的空间小于 128K 时,调用 brk()函数;当开辟的空间大于 128K 时,调用mmap()。

20.进程空间从高位到低位都有些什么?

(1)从高地址到低地址,一个程序由命令行参数和环境变量、栈、文件映射区、堆、BSS段、数据段、代码段组成。

21.32位系统能访问4GB以上的内存吗?

(1)正常情况下是不可以的。32位正好是2的32次方,正好是4G,所以大于4G就没办法表示了,而在32位的系统中,因其它原因还需要占用一部分空间,所以内存只能识别3G多。
(2)PAE技术:PAE技术将地址扩展到了36位。

22.并发和并行?

(1)并发:对于单个CPU,在一个时刻只有一个进程在运行,但是线程的切换时间则减少到纳秒数量级,多个任务不停来回快速切换。
(2)并行:对于多个CPU,多个进程同时运行。
(3)区别。通俗来讲,它们虽然都说是"多个进程同时运行",但是它们的"同时"不是一个概念。并行的"同时"是同一时刻可以多个任务在运行(处于running),并发的"同时"是经过不同线程快速切换,使得看上去多个任务同时都在运行的现象。

23.进程、线程、协程是什么,区别是什么?

(1)进程:程序是指令、数据及其组织形式的描述,而进程则是程序的运行实例,包括程序计数器、寄存器和变量的当前值。
(2)线程:微进程,一个进程里更小粒度的执行单元。一个进程里包含多个线程并发执行任务。
(3)协程:协程是微线程,在子程序内部执行,可在子程序内部中断,转而执行别的子程序,在适当的时候再返回来接着执行。
(4)区别:Ⅰ.一个线程从属于一个进程;一个进程可以包含多个线程。Ⅱ.一个线程挂掉,对应的进程挂掉;一个进程挂掉,不会影响其他进程。Ⅲ.进程是系统资源调度的最小单位;线程CPU调度的最小单位。Ⅳ.进程系统开销显著大于线程开销;线程需要的系统资源更少。Ⅴ.进程在执行时拥有独立的内存单元,多个线程共享进程的内存,如代码段、数据段、扩展段;但每个线程拥有自己的栈段和寄存器组。Ⅵ.进程切换时需要刷新TLB并获取新的地址空间,然后切换硬件上下文和内核栈,线程切换时只需要切换硬件上下文和内核栈。Ⅶ.通信方式不一样。Ⅷ.进程适应于多核、多机分布;线程适用于多核

24.线程与协程的区别?

(1)协程执行效率极高。协程直接操作栈基本没有内核切换的开销,所以上下文的切换非常快,切换开销比线程更小。
(2)协程不需要多线程的锁机制,因为多个协程从属于一个线程,不存在同时写变量冲突,效率比线程高。
(3)一个线程可以有多个协程。

25.Linux的fork的作用

(1)fork函数用来创建一个子进程。对于父进程,fork()函数返回新创建的子进程的PID。对于子进程,fork()函数调用成功会返回0。如果创建出错,fork()函数返回-1。

26.什么是孤儿进程,什么是僵尸进程,如何解决僵尸进程

(1)孤儿进程:是指一个父进程退出后,而它的一个或多个子进程还在运行,那么这些子进程将成为孤儿进程。
(2)僵尸进程:是指一个进程使用fork函数创建子进程,如果子进程退出,而父进程并没有调用wait()或者waitpid()系统调用取得子进程的终止状态,那么子进程的进程描述符仍然保存在系统中,占用系统资源,这种进程称为僵尸进程。
(3)解决僵尸进程:Ⅰ.当子进程退出的时候,内核都会给父进程一个SIGCHLD信号,所以我们可以建立一个捕获SIGCHLD信号的信号处理函数,在函数体中调用wait(或waitpid),就可以清理退出的子进程以达到防止僵尸进程的目的。Ⅱ.使用kill命令。

27.什么是守护进程,如何实现?

(1)守护进程:守护进程是运行在后台的一种生存期长的特殊进程。它独立于控制终端,处理一些系统级别任务。
(2)实现:Ⅰ.创建子进程,终止父进程。方法是调用fork() 产生一个子进程,然后使父进程退出。Ⅱ.调用setsid() 创建一个新会话。Ⅲ.将当前目录更改为根目录。使用fork() 创建的子进程也继承了父进程的当前工作目录。Ⅳ.重设文件权限掩码。文件权限掩码是指屏蔽掉文件权限中的对应位。Ⅴ.关闭不再需要的文件描述符。子进程从父进程继承打开的文件描述符。

28.进程通信的方式有哪些?

(1)管道:包括无名管道和命名管道。
(2)消息队列
(3)信号量
(4)信号
(5)内存共享
(6)套接字socket

29.进程同步的方式?

(1)信号量semaphore
(2)管道
(3)消息队列

30.Linux进程调度算法及策略有哪些?

(1)先来先服务调度算法
(2)短作业(进程)优先调度算法
(3)高优先级优先调度算法
(4)时间片轮转法
(5)多级反馈队列调度算法

31.进程有多少种状态?

(1)进程有五种状态:创建、就绪、执行、阻塞、终止。

32.进程通信中的管道实现原理是什么?

(1)操作系统在内核中开辟一块缓冲区(称为管道)用于通信。
(2)父进程调用pipe开辟管道,得到两个文件描述符指向管道的两端。
(3)父进程关闭管道读端,子进程关闭管道写端。

33.mmap的原理和使用场景

(1)mmap是一种内存映射文件的方法,即将一个文件或者其它对象映射到进程的地址空间,实现文件磁盘地址和进程虚拟地址空间中一段虚拟地址的一一对映关系。
(2)对同一块区域频繁读写操作;
(3)可用于实现用户空间和内核空间的高效交互
(4)可提供进程间共享内存及相互通信
(5)可实现高效的大规模数据传输。

34.互斥量能不能在进程中使用?

(1)能,不同的进程之间,存在资源竞争或并发使用的问题,所以需要互斥量。
(2)进程中也需要互斥量,因为一个进程中可以包含多个线程,线程与线程之间需要通过互斥的手段进行同步,避免导致共享数据修改引起冲突。可以使用互斥锁,属于互斥量的一种。

35.协程是轻量级线程,轻量级表现在哪里?

(1)协程调用跟切换比线程效率高
(2)协程占用内存少
(3)切换开销更少

36.什么是死锁,产生的条件,如何解决?

(1)死锁: 是指多个进程在执行过程中,因争夺资源而造成了互相等待。此时系统产生了死锁。
(2)产生条件:Ⅰ.互斥条件。Ⅱ.请求保持条件。Ⅲ.不可剥夺条件。Ⅳ.环路等待条件
(3)解决:Ⅰ.资源一次性分配,从而解决请求保持的问题。Ⅱ.可剥夺资源。Ⅲ.资源有序分配。

37.有了进程,为什么还要有线程?

(1)进程频繁切换将引起额外开销,从而严重影响系统的性能。为了减少进程切换的开销,每个任务用一个更小粒度的执行单元来实现并发执行,这就是线程。
(2)进程间的信息难以共享。
(3)创建线程比创建进程通常要快 10 倍甚至更多。线程间是共享虚拟地址空间的,无需采用写时复制来复制内存,也无需复制页表。

38.单核机器上写多线程程序,是否要考虑加锁,为什么?

(1)在单核机器上写多线程程序,仍然需要线程锁。
(2)线程锁通常用来实现线程的同步和通信。在单核机器上的多线程程序,仍然存在线程同步的问题。
(3)两个线程共享某些数据,不使用线程锁的前提下,可能会导致共享数据修改引起冲突。

39.多线程和多进程的不同?

(1)一个线程从属于一个进程;一个进程可以包含多个线程。
(2)一个线程挂掉,对应的进程挂掉,多线程也挂掉;一个进程挂掉,不会影响其他进程,多进程稳定。
(3)进程系统开销显著大于线程开销;线程需要的系统资源更少。
(4)多个进程在执行时拥有各自独立的内存单元,多个线程共享进程的内存,如代码段、数据段、扩展段;但每个线程拥有自己的栈段和寄存器组。
(5)多进程切换时需要刷新TLB并获取新的地址空间,然后切换硬件上下文和内核栈;多线程切换时只需要切换硬件上下文和内核栈。
(6)通信方式不一样。
(7)多进程适应于多核、多机分布;多线程适用于多核。

40.简述互斥锁的机制,互斥锁与读写的区别?

(1)互斥锁机制:mutex,用于保证在任何时刻,都只能有一个线程访问该对象。当获取锁操作失败时,线程会进入睡眠,等待锁释放时被唤醒。
(2)互斥锁和读写锁:
Ⅰ.读写锁区分读者和写者,而互斥锁不区分。Ⅱ.互斥锁同一时间只允许一个线程访问该对象,无论读写;读写锁同一时间内只允许一个写者,但是允许多个读者同时读对象。

41.什么是信号量,有什么作用?

(1)信号量本质上是一个计数器,用于多进程对共享数据对象的读取,它主要是用来保护共享资源(信号量也属于临界资源),使得资源在一个时刻只有一个进程独享。
(2)用于多进程对共享数据对象的读取,它主要是用来保护共享资源(信号量也属于临界资源),使得资源在一个时刻只有一个进程独享。

42.进程、线程的中断切换的过程是怎样的?

(1)上下文切换指的是内核(操作系统的核心)在CPU上对进程或者线程进行切换。
(2)进程上下文切换:Ⅰ.保护被中断进程的处理器现场信息;Ⅱ.修改被中断进程的进程控制块有关信息,如进程状态等;Ⅲ.把被中断进程的进程控制块加入有关队列;Ⅳ.选择下一个占有处理器运行的进程;Ⅴ.根据被选中进程设置操作系统用到的地址转换和存储保护信息。Ⅵ.切换页目录以使用新的地址空间。Ⅶ.​ 切换内核栈和硬件上下文。Ⅷ.根据被选中进程恢复处理器现场
(3)线程上下文切换:Ⅰ.保护被中断进程的处理器现场信息;Ⅱ.修改被中断进程的线程控制块有关信息,如线程状态等;Ⅲ.把被中断进程的线程控制块加入有关队列;Ⅳ.选择下一个占有处理器运行的线程;Ⅴ.根据被选中进程设置操作系统用到的存储保护信息。Ⅵ.​ 切换内核栈和硬件上下文。Ⅶ.根据被选中线程恢复处理器现场。

43.简述自旋锁和互斥锁的使用场景

(1)互斥锁用于临界区持锁时间比较长的操作,Ⅰ.临界区有IO操作。Ⅱ.临界区代码复杂或者循环量大。Ⅲ.临界区竞争非常激烈。Ⅳ.单核处理器
(2)自旋锁就主要用在临界区持锁时间非常短且CPU资源不紧张的情况下。

44.多线程编程要注意什么,多线程加锁需要注意什么?

(1)多线程编程需要考虑同步的问题。线程间的同步方式包括互斥锁、信号量、条件变量、读写锁。
(2)多线程加锁,主要需要注意死锁的问题。破坏死锁的必要条件从而避免死锁。

45.sleep和wait的区别?

(1)sleep是一个延时函数,让进程或线程进入休眠。休眠完毕后继续运行。
(2)wait是父进程回收子进程PCB资源的一个系统调用。
(3)sleep是一个延时函数,让进程或线程进入休眠。休眠完毕后继续运行。
(4)wait是父进程回收子进程PCB(Process Control Block)资源的一个系统调用。

46.线程池的设计思路,线程池中线程的数量由什么确定?

(1)设置一个生产者消费者队列,作为临界资源。
(2)初始化n个线程,并让其运行起来,加锁去队列里取任务运行
(3)当任务队列为空时,所有线程阻塞。
(4)当生产者队列来了一个任务后,先对队列加锁,把任务挂到队列上,然后使用条件变量去通知阻塞中的一个线程来处理。
(5)线程数量和哪些因素有关:CPU,IO、并行、并发。
(6)创建线程和销毁线程的花销是比较大的,这些时间有可能比处理业务的时间还要长。线程池也是为了提升系统效率。

47.进程和线程相比,为什么慢?

(1)进程系统开销显著大于线程开销;线程需要的系统资源更少。
(2)进程切换开销比线程大。多进程切换时需要刷新TLB并获取新的地址空间,然后切换硬件上下文和内核栈;多线程切换时只需要切换硬件上下文和内核栈。
(3)进程通信比线程通信开销大。进程通信需要借助管道、队列、共享内存,需要额外申请空间,通信繁琐;而线程共享进程的内存,如代码段、数据段、扩展段,通信快捷简单,同步开销更小。

48.Linux零拷贝的原理?

(1)所谓「零拷贝」描述的是计算机操作系统当中,CPU不执行将数据从一个内存区域,拷贝到另外一个内存区域的任务。通过网络传输文件时,这样通常可以节省 CPU 周期和内存带宽。
(2)零拷贝的好处:Ⅰ.节省了 CPU 周期,空出的 CPU 可以完成更多其他的任务。Ⅱ.减少了内存区域之间数据拷贝,节省内存带宽。Ⅲ.减少用户态和内核态之间数据拷贝,提升数据传输效率。Ⅳ.应用零拷贝技术,减少用户态和内核态之间的上下文切换。

49.简述epoll和select的区别,epoll为什么高效?

(1)每次调用select,都需要把fd集合从用户态拷贝到内核态,这个开销在fd很多时会很大;而epoll保证了每个fd在整个过程中只会拷贝一次。
(2)每次调用select都需要在内核遍历传递进来的所有fd;而epoll只需要轮询一次fd集合,同时查看就绪链表中有没有就绪的fd就可以了。
(3)select支持的文件描述符数量太小了,默认是1024;而epoll没有这个限制,它所支持的fd上限是最大可以打开文件的数目,这个数字一般远大于2048。
(4)select,poll实现需要自己不断轮询所有fd集合,直到设备就绪,期间可能要睡眠和唤醒多次交替。而epoll只要判断一下就绪链表是否为空就行了,这节省了大量的CPU时间。
(5)select,poll每次调用都要把fd集合从用户态往内核态拷贝一次,并且要把当前进程往设备等待队列中挂一次,而epoll只要一次拷贝,而且把当前进程往等待队列上挂也只挂一次,这也能节省不少的开销。

50.BIO、NIO有什么区别?

(1)BIO(Blocking I/O):阻塞IO。调用者调用了某个函数,等待这个函数返回,期间什么也不做,不停的检查这个函数有没有返回,必须等这个函数返回后才能进行下一步动作。
(2)NIO(New I/O):同时支持阻塞与非阻塞模式,NIO的做法是叫一个线程不断的轮询每个IO的状态,看看是否有IO的状态发生了改变,从而进行下一步的操作。

二、C++计算机网络

1.简述静态路由和动态路由?

(1)静态路由是由系统管理员设计与构建的路由表规定的路由。适用于网关数量有限的场合,且网络拓朴结构不经常变化的网络。其缺点是不能动态地适用网络状况的变化,当网络状况变化后必须由网络管理员修改路由表。
(2)动态路由是由路由选择协议而动态构建的,路由协议之间通过交换各自所拥有的路由信息实时更新路由表的内容。动态路由可以自动学习网络的拓朴结构,并更新路由表。其缺点是路由广播更新信息将占据大量的网络带宽。

2.有哪些路由协议,都是如何更新的?

(1)路由可分为静态&动态路由。静态路由由管理员手动维护;动态路由由路由协议自动维护。
(2)步骤:Ⅰ.向其它路由器传递路由信息;Ⅱ.接收其它路由器的路由信息;Ⅲ.

3.简述域名解析过程,本机如何干预域名解析?

(1)在浏览器中输入www.qq.com域名,操作系统会先检查自己本地的hosts文件是否有这个网址映射关系,如果有,就先调用这个IP地址映射,完成域名解析。
(2)如果hosts里没有这个域名的映射,则查找本地DNS解析器缓存,是否有这个网址映射关系,如果有,直接返回,完成域名解析。
(3)如果hosts与本地DNS解析器缓存都没有相应的网址映射关系,首先会找TCP/IP参数中设置的首选DNS服务器,在此我们叫它本地DNS服务器,此服务器收到查询时,如果要查询的域名,包含在本地配置区域资源中,则返回解析结果给客户机,完成域名解析,此解析具有权威性。
(4)如果要查询的域名,不由本地DNS服务器区域解析,但该服务器已缓存了此网址映射关系,则调用这个IP地址映射,完成域名解析,此解析不具有权威性。
(5)如果本地DNS服务器本地区域文件与缓存解析都失效,则根据本地DNS服务器的设置(是否设置转发器)进行查询,如果未用转发模式,本地DNS就把请求发至13台根DNS,根DNS服务器收到请求后会判断这个域名(.com)是谁来授权管理,并会返回一个负责该顶级域名服务器的一个IP。
(6)如果用的是转发模式,此DNS服务器就会把请求转发至上一级DNS服务器,由上一级服务器进行解析,上一级服务器如果不能解析,或找根DNS或把转请求转至上上级,以此循环。不管是本地DNS服务器用是是转发,还是根提示,最后都是把结果返回给本地DNS服务器,由此DNS服务器再返回给客户机。
(7)从客户端到本地DNS服务器是属于递归查询,而DNS服务器之间就是的交互查询就是迭代查询。
(8)通过修改本机host来干预域名解析:修改/etc/hosts文件。

4.简述 DNS 查询服务器的基本流程是什么?DNS 劫持是什么?

(1)打开浏览器,输入一个域名。比如输入www.163.com,这时,你使用的电脑会发出一个DNS请求到本地DNS服务器。本地DNS服务器一般都是你的网络接入服务器商提供,比如中国电信,中国移动。
(2)DNS劫持就是通过劫持了DNS服务器,通过某些手段取得某域名的解析记录控制权,进而修改此域名的解析结果,导致对该域名的访问由原IP地址转入到修改后的指定IP,其结果就是对特定的网址不能访问或访问的是假网址,从而实现窃取资料或者破坏原有正常服务的目的。DNS劫持通过篡改DNS服务器上的数据返回给用户一个错误的查询结果来实现的。

5.简述网关的作用是什么,同一网段的主机如何通信?

(1)网关即网络中的关卡,我们的互联网是一个一个的局域网、城域网、等连接起来的,在连接点上就是一个一个网络的关卡,即我们的网关,他是保证网络互连的,翻译和转换,使得不同的网络体系能够进行。
(2)网内通信,即通信双方都位处同一网段中,数据传输无需经过路由器(或三层交换机),即可由本网段自主完成。

6.简述CSRF攻击的思想以及解决方法?

(1)CSRF全称叫做,跨站请求伪造。就是黑客可以伪造用户的身份去做一些操作,进而满足自身目的。
(2)CSRF 攻击是一种请求伪造的攻击方式,它利用的是服务器不能识别用户的类型从而盗取用户的信息来攻击。因此要防御该种攻击,因为从服务器端着手,增强服务器的识别能力,设计良好的防御机制。

7.MAC地址和IP地址分别有什么作用?

(1)IP地址是IP协议提供的一种统一的地址格式,它为互联网上的每一个网络和每一台主机分配一个逻辑地址,以此来屏蔽物理地址的差异。而MAC地址,指的是物理地址,用来定义网络设备的位置。
(2)IP地址的分配是根据网络的拓扑结构,而不是根据谁制造了网络设置。若将高效的路由选择方案建立在设备制造商的基础上而不是网络所处的拓朴位置基础上,这种方案是不可行的。
(3)当存在一个附加层的地址寻址时,设备更易于移动和维修。例如,如果一个以太网卡坏了,可以被更换,而无须取得一个新的IP地址。如果一个IP主机从一个网络移到另一个网络,可以给它一个新的IP地址,而无须换一个新的网卡。
(4)无论是局域网,还是广域网中的计算机之间的通信,最终都表现为将数据包从某种形式的链路上的初始节点出发,从一个节点传递到另一个节点,最终传送到目的节点。数据包在这些节点之间的移动都是由ARP(Address Resolution Protocol:地址解析协议)负责将IP地址映射到MAC地址上来完成的。

8.TCP 2次握手行不行?为什么要3次?

(1)为了实现可靠数据传输, TCP 协议的通信双方, 都必须维护一个序列号, 以标识发送出去的数据包中, 哪些是已经被对方收到的。 三次握手的过程即是通信双方相互告知序列号起始值, 并确认对方已经收到了序列号起始值的必经步骤
(2)如果只是两次握手, 至多只有连接发起方的起始序列号能被确认, 另一方选择的序列号则得不到确认。

9.简述 TCP 和 UDP 的区别,它们的头部结构是什么样的?

(1)TCP协议是有连接的,有连接的意思是开始传输实际数据之前TCP的客户端和服务器端必须通过三次握手建立连接,会话结束之后也要结束连接。而UDP是无连接的
(2)TCP协议保证数据按序发送,按序到达,提供超时重传来保证可靠性,但是UDP不保证按序到达,甚至不保证到达,只是努力交付,即便是按序发送的序列,也不保证按序送到。
(3)TCP协议所需资源多,TCP首部需20个字节(不算可选项),UDP首部字段只需8个字节。
(4)TCP有流量控制和拥塞控制,UDP没有,网络拥堵不会影响发送端的发送速率。
(5)TCP是一对一的连接,而UDP则可以支持一对一,多对多,一对多的通信。
(6)TCP面向的是字节流的服务,UDP面向的是报文的服务。

10.简述 TCP 连接 和 关闭的具体步骤?

(1)TCP通过三次握手建立链接
(2)通过4次挥手关闭链接

11. 简述TCP慢启动?

(1)慢启动(Slow Start),是传输控制协议(TCP)使用的一种阻塞控制机制。慢启动也叫做指数增长期。慢启动是指每次TCP接收窗口收到确认时都会增长。增加的大小就是已确认段的数目。这种情况一直保持到要么没有收到一些段,要么窗口大小到达预先定义的阈值。如果发生丢失事件,TCP就认为这是网络阻塞,就会采取措施减轻网络拥挤。一旦发生丢失事件或者到达阈值,TCP就会进入线性增长阶段。这时,每经过一个RTT窗口增长一个段。

12. TCP 如何保证有序?

(1)主机每次发送数据时,TCP就给每个数据包分配一个序列号并且在一个特定的时间内等待接收主机对分配的这个序列号进行确认,如果发送主机在一个特定时间内没有收到接收主机的确认,则发送主机会重传此数据包。接收主机利用序列号对接收的数据进行确认,以便检测对方发送的数据是否有丢失或者乱序等,接收主机一旦收到已经顺序化的数据,它就将这些数据按正确的顺序重组成数据流并传递到高层进行处理。

13.TCP 常见的拥塞控制算法有哪些?

(1)TCP Tahoe/Reno。
(2)TCP BBR(Bottleneck Bandwidth and Round-trip propagation time)。该算法认为随着网络接口控制器逐渐进入千兆速度时,分组丢失不应该被认为是识别拥塞的主要决定因素,所以基于模型的拥塞控制算法能有更高的吞吐量和更低的延迟,可以用BBR来替代其他流行的拥塞算法,例如CUBIC。

14.简述 TCP 超时重传?

(1)TCP可靠性中最重要的一个机制是处理数据超时和重传。TCP协议要求在发送端每发送一个报文段,就启动一个定时器并等待确认信息;接收端成功接收新数据后返回确认信息。若在定时器超时前数据未能被确认,TCP就认为报文段中的数据已丢失或损坏,需要对报文段中的数据重新组织和重传。

15.TCP 可靠性保证?

(1)TCP主要提供了检验和、序列号/确认应答、超时重传、最大消息长度、滑动窗口控制等方法实现了可靠性传输。
(2)检验和:通过检验和的方式,接收端可以检测出来数据是否有差错和异常,假如有差错就会直接丢弃TCP段,重新发送。
(3)序列号/确认应答:只要发送端有一个包传输,接收端没有回应确认包(ACK包),都会重发。或者接收端的应答包,发送端没有收到也会重发数据。这就可以保证数据的完整性。
(4)超时重传:超时重传是指发送出去的数据包到接收到确认包之间的时间,如果超过了这个时间会被认为是丢包了,需要重传。
(5)最大消息长度:在建立TCP连接的时候,双方约定一个最大的长度(MSS)作为发送的单位,重传的时候也是以这个单位来进行重传。
(6)滑动窗口控制:不用等待确认包就发送下一个数据包,窗口的大小就是在无需等待确认包的情况下,发送端还能发送的最大数据量。这个机制的实现就是使用了大量的缓冲区,通过对多个段进行确认应答的功能。通过下一次的确认包可以判断接收端是否已经接收到了数据,如果已经接收了就从缓冲区里面删除数据。发送端在收到某个应答包之后,又连续3次收到同样的应答包,则数据已经丢失了,需要重发。
(7)拥塞控制:TCP引入慢启动机制,先发出少量数据,就像探路一样,先摸清当前的网络拥堵状态后,再决定按照多大的速度传送数据。

16.简述 TCP 滑动窗口以及重传机制?

(1)滑动窗口协议是传输层进行流控的一种措施,接收方通过通告发送方自己的窗口大小,从而控制发送方的发送速度,从而达到防止发送方发送速度过快而导致自己被淹没的目的。TCP的滑动窗口解决了端到端的流量控制问题,允许接受方对传输进行限制,直到它拥有足够的缓冲空间来容纳更多的数据。
(2)TCP在发送数据时会设置一个计时器,若到计时器超时仍未收到数据确认信息,则会引发相应的超时或基于计时器的重传操作,计时器超时称为重传超时(RTO) 。另一种方式的重传称为快速重传,通常发生在没有延时的情况下。若TCP累积确认无法返回新的ACK,或者当ACK包含的选择确认信息(SACK)表明出现失序报文时,快速重传会推断出现丢包,需要重传。

17.滑动窗口过小怎么办?

(1)窗口过小,那么当传输比较大的数据的时候需要不停的对数据进行确认,这个时候就会造成很大的延迟。

18.如果三次握手时候每次握手信息对方没收到会怎么样,分情况介绍?

(1)如果第一次握手消息丢失,那么请求方不会得到ack消息,超时后进行重传
(2)如果第二次握手消息丢失,那么请求方不会得到ack消息,超时后进行重传
(3)

19.简述 TCP 的 TIME_WAIT,为什么需要有这个状态?

(1)TIME_WAIT状态也成为2MSL等待状态。
(2)理论上,四个报文都发送完毕,就可以直接进入CLOSE状态了,但是可能网络是不可靠的,有可能最后一个ACK丢失。所以TIME_WAIT状态就是用来重发可能丢失的ACK报文。

20.简述什么是 MSL,为什么客户端连接要等待2MSL的时间才能完全关闭?

(1)MSL是Maximum Segment Lifetime的英文缩写,可译为“最长报文段寿命”,它是任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃。
(2)假设客户端不等待2MSL,而是在发送完ACK之后直接释放关闭,一但这个ACK丢失的话,服务器就无法正常的进入关闭连接状态。
(3)保证客户端发送的最后一个ACK报文段能够到达服务端。
(4)防止“已失效的连接请求报文段”出现在本连接中。

21.什么是 SYN flood,如何防止这类攻击?

(1)SYN Flood是当前最流行的DoS(拒绝服务攻击)与DDoS(分布式拒绝服务攻击)的方式之一,这是一种利用TCP协议缺陷,发送大量伪造的TCP连接请求,使被攻击方资源耗尽(CPU满负荷或内存不足)的攻击方式.
(2)从互联网服务提供商(ISP)购买服务。
(3)保留在内部并自己解决。
(4)使用内容分发网络(CDN)。

22.什么是 TCP 粘包和拆包?

(1)TCP是个“流”协议,所谓流,就是没有界限的一串数据。大家可以想想河里的流水,是连成一片的,其间并没有分界线。TCP底层并不了解上层业务数据的具体含义,它会根据TCP缓冲区的实际情况进行包的划分,所以在业务上认为,一个完整的包可能会被TCP拆分成多个包进行发送,也有可能把多个小的包封装成一个大的数据包发送,这就是所谓的TCP粘包和拆包问题。

23. TCP 与 UDP 在网络协议中的哪一层,他们之间有什么区别?

(1)TCP和UDP协议都是传输层协议。
区别:
(2)TCP是面向连接的协议。UDP是无连接的协议。UDP更加适合消息的多播发布,从单个点向多个点传输消息。
(3)TCP提供交付保证,传输过程中丢失,将会重发。UDP是不可靠的,不提供任何交付保证。(网游和视频的丢包情况)
(4)TCP保证了消息的有序性,即使到达客户端顺序不同,TCP也会排序。UDP不提供有序性保证。
(5)TCP不保存数据边界。UDP保证。
(6)TCP速度慢。UDP速度快。应用在在线视频媒体,电视广播和多人在线游戏。
(7)TCP是重量级。UDP是轻量级。
(8)TCP头大。UDP头小。
(9)TCP有流量控制。UDP不能进行流量控制。
(10)由于TCP提供可靠交付和有序性的保证,它是最适合需要高可靠并且对传输时间要求不高的应用。UDP是更适合的应用程序需要快速,高效的传输的应用,如游戏。UDP是无状态的性质,在服务器端需要对大量客户端产生的少量请求进行应答的应用中是非常有用的。在实践中,TCP被用于金融领域,如FIX协议是一种基于TCP的协议,而UDP是大量使用在游戏和娱乐场所。
(11)基于TCP协议的:Telnet,FTP以及SMTP协议。基于UDP协议的:DHCP、DNS、SNMP、TFTP、BOOTP。

24.从系统层面上,UDP 如何保证尽量可靠?

(1)UDP仅提供了最基本的数据传输功能,至于传输时连接的建立和断开、传输可靠性的保证这些UDP统统不关心,而是把这些问题抛给了UDP上层的应用层程序去处理,自己仅提供传输层协议的最基本功能。
(2)最简单的方式是在应用层模仿传输层TCP的可靠性传输。添加seq/ack机制确保数据发送到对端。添加发送和接收缓冲区,主要是用户超时重传。添加超时重传机制。

25.TCP 的 keepalive,以及和 HTTP 的 keepalive 的区别?

(1)HTTP Keep-Alive。在http早期,每个http请求都要求打开一个tpc socket连接,并且使用一次之后就断开这个tcp连接。使用keep-alive可以改善这种状态,即在一次TCP连接中可以持续发送多份数据而不会断开连接。配置不当的keep-alive,有时比重复利用连接带来的损失还更大。所以,正确地设置keep-alive timeout时间非常重要。
(2)TCP KEEPALIVE。链接建立之后,如果应用程序或者上层协议一直不发送数据,或者隔很长时间才发送一次数据,当链接很久没有数据报文传输时如何去确定对方还在线,到底是掉线了还是确实没有数据传输,链接还需不需要保持,这种情况在TCP协议设计中是需要考虑到的。当超过一段时间之后,TCP自动发送一个数据为空的报文给对方,如果对方回应了这个报文,说明对方还在线,链接可以继续保持,如果对方没有报文返回,并且重试了多次之后则认为链接丢失,没有必要保持链接。
(3)TCP的keepalive机制和HTTP的keep-alive机制是说的完全不同的两个东西,tcp的keepalive是在ESTABLISH状态的时候,双方如何检测连接的可用行。而http的keep-alive说的是如何避免进行重复的TCP三次握手和四次挥手的环节。

26.简述 TCP 协议的延迟 ACK 和累计应答?

(1)延迟应答指的是:TCP在接收到对端的报文后,并不会立即发送ack,而是等待一段时间发送ack,以便将ack和要发送的数据一块发送。当然ack不能无限延长,否则对端会认为包超时而造成报文重传。linux采用动态调节算法来确定延时的时间。
(2)累计应答指的是:为了保证顺序性,每一个包都有一个ID(序号),在建立连接的时候,会商定起始的ID是多少,然后按照ID一个个发送。而为了保证不丢包,对应发送的包都要进行应答,但不是一个个应答,而是会应答某个之前的ID,该模式称为累计应答。

27. TCP 如何加速一个大文件的传输?

(1)建连优化:TCP 在建立连接时,如果丢包,会进入重试,重试时间是 1s、2s、4s、8s 的指数递增间隔,缩短定时器可以让 TCP 在丢包环境建连时间更快,非常适用于高并发短连接的业务场景。
(2)平滑发包:在 RTT 内均匀发包,规避微分时间内的流量突发,尽量避免瞬间拥塞。
(3)丢包预判:有些网络的丢包是有规律性的,例如每隔一段时间出现一次丢包,例如每次丢包都连续丢几个等,如果程序能自动发现这个规律(有些不明显),就可以针对性提前多发数据,减少重传时间、提高有效发包率。
(4)RTO 探测:若始终收不到 ACK 报文,则需要触发 RTO 定时器。RTO 定时器一般都时间非常长,会浪费很多等待时间,而且一旦 RTO,CWND 就会骤降(标准 TCP),因此利用 Probe 提前与 RTO 去试探,可以规避由于 ACK 报文丢失而导致的速度下降问题。
(5)带宽评估:通过单位时间内收到的 ACK 或 SACK 信息可以得知客户端有效接收速率,通过这个速率可以更合理的控制发包速度。
(6)带宽争抢:有些场景(例如合租)是大家互相挤占带宽的,假如你和室友各 1Mbps 的速度看电影,会把 2Mbps 出口占满,而如果一共有 3 个人看,则每人只能分到 1/3。若此时你的流量流量达到 2Mbps,而他俩还都是 1Mbps,则你至少仍可以分到 2/(2+1+1) * 2Mbps = 1Mbps 的 50% 的带宽,甚至更多,代价就是服务器侧的出口流量加大,增加成本。(TCP 优化的本质就是用带宽换用户体验感)

28.服务器怎么判断客户端断开了连接?

(1)检测连接是否丢失的方法大致有两种:keepalive和heart-beat
(2)(tcp内部机制)采用keepalive,它会先要求此连接一定时间没有活动(一般是几个小时),然后发出数据段,经过多次尝试后(每次尝试之间也有时间间隔),如果仍没有响应,则判断连接中断。可想而知,整个周期需要很长的时间。
(3)(应用层实现)一个简单的heart-beat实现一般测试连接是否中断采用的时间间隔都比较短,可以很快的决定连接是否中断。并且,由于是在应用层实现,因为可以自行决定当判断连接中断后应该采取的行为,而keepalive在判断连接失败后只会将连接丢弃。

29.端到端,点到点的区别?

(1)端到端通信是针对传输层来说的,传输层为网络中的主机提供端到端的通信。因为无论tcp还是udp协议,都要负责把上层交付的数据从发送端传输到接收端,不论其中间跨越多少节点。只不过tcp比较可靠而udp不可靠而已。所以称之为端到端,也就是从发送端到接收端。
(2)端到端通信建立在点到点通信的基础之上,它是由一段段的点到点通信信道构成的,是比点到点通信更高一级的通信方式,完成应用程序(进程)之间的通信。
(3)点到点通信是针对数据链路层或网络层来说的,因为数据链路层只负责直接相连的两个节点之间的通信,一个节点的数据链路层接受ip层数据并封装之后,就把数据帧从链路上发送到与其相邻的下一个节点。点对点是基于MAC地址和或者IP地址,是指一个设备发数据给与该这边直接连接的其他设备,这台设备又在合适的时候将数据传递给与它相连的下一个设备,通过一台一台直接相连的设备把数据传递到接收端。

30.浏览器从输入 URL 到展现页面的全过程?

(1)输入地址
(2)浏览器查找域名的 IP 地址
(3)浏览器向 web 服务器发送一个 HTTP 请求
(4)服务器的永久重定向响应
(5)服务器处理请求
(6)服务器返回一个 HTTP 响应
(7)浏览器显示 HTML
(8)浏览器发送请求获取嵌入在 HTML 中的资源(如图片、音频、视频、CSS、JS等等)

31.简述 HTTP 和 HTTPS 的区别?

(1)HTTP:是互联网上应用最为广泛的一种网络协议,是一个客户端和服务器端请求和应答的标准(TCP),用于从WWW服务器传输超文本到本地浏览器的传输协议,它可以使浏览器更加高效,使网络传输减少。
(2)HTTPS:是以安全为目标的HTTP通道,简单讲是HTTP的安全版,即HTTP下加入SSL层,HTTPS的安全基础是SSL,因此加密的详细内容就需要SSL。
(3)HTTPS协议的主要作用可以分为两种:一种是建立一个信息安全通道,来保证数据传输的安全;另一种就是确认网站的真实性。
(4)区别:Ⅰ.https协议需要到ca申请证书,一般免费证书较少,因而需要一定费用。 Ⅱ.http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议。Ⅲ.http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。 Ⅳ.http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。

32. HTTP 中的 referer 头的作用?

(1)HTTP Referer是header的一部分,当浏览器向web服务器发送请求的时候,一般会带上Referer,告诉服务器该网页是从哪个页面链接过来的,服务器因此可以获得一些信息用于处理。
(2)防盗链。
(3)防止恶意请求
(4)空Referer,允许Referer为空,意味着你允许比如浏览器直接访问。
(5)防御CSRF。比对HTTP 请求的来源地址,如果Referer中的地址是安全可信任的地址,那么就放行。

33. HTTP 的方法有哪些?

(1)GET: 用于请求访问已经被URI(统一资源标识符)识别的资源,可以通过URL传参给服务器
(2)POST:用于传输信息给服务器,主要功能与GET方法类似,但一般推荐使用POST方式。
(3)PUT: 传输文件,报文主体中包含文件内容,保存到对应URI位置。
(4)HEAD: 获得报文首部,与GET方法类似,只是不返回报文主体,一般用于验证URI是否有效。
(5)DELETE:删除文件,与PUT方法相反,删除对应URI位置的文件。
(6)OPTIONS:查询相应URI支持的HTTP方法。

34.简述 HTTP 1.0,1.1,2.0 的主要区别?

(1)http/1.0 :默认不支持长连接,需要设置keep-alive参数指定。强缓存expired、协商缓存last-modified\if-modified-since 有一定的缺陷。
(2)http 1.1 :默认长连接(keep-alive),http请求可以复用Tcp连接,但是同一时间只能对应一个http请求(http请求在一个Tcp中是串行的)。增加了强缓存cache-control、协商缓存etag\if-none-match 是对http/1 缓存的优化。
(3)http/2.0 :多路复用,一个Tcp中多个http请求是并行的,二进制格式编码传输,使用HPACK算法做header压缩,服务端推送。

35. HTTP 常见的响应状态码及其含义?

1XX : 信息类状态码(表示接收请求状态处理)
2XX : 成功状态码(表示请求正常处理完毕)
3XX : 重定向(表示需要进行附加操作,已完成请求)
4XX : 客户端错误(表示服务器无法处理请求)
5XX : 服务器错误状态码(表示服务器处理请求的时候出错)

36. GET请求和 POST 请求的区别?

(1)GET请求在URL中传送的参数是有长度限制的,而POST没有。
(2)GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息。
(3)GET参数通过URL传递,POST放在Request body中。
(4)GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。
(5)GET请求只能进行url编码,而POST支持多种编码方式。
(6)GET请求会被浏览器主动cache,而POST不会,除非手动设置。
(7)GET产生的URL地址可以被Bookmark,而POST不可以。
(8)GET在浏览器回退时是无害的,而POST会再次提交请求。

37.Cookie 和 Session 的关系和区别是什么?

(1)Cookie与Session都是会话的一种方式。它们的典型使用场景比如“购物车”,当你点击下单按钮时,服务端并不清楚具体用户的具体操作,为了标识并跟踪该用户,了解购物车中有几样物品,服务端通过为该用户创建Cookie/Session来获取这些信息。
(2)cookie数据存放在客户的浏览器上,session数据放在服务器上。
(3)cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗 考虑到安全应当使用session。
(4)session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能 考虑到减轻服务器性能方面,应当使用COOKIE。
(5)单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。

38.简述 HTTPS 的加密与认证过程?

(1)客户端在浏览器中输入一个https网址,然后连接到server的443端口 采用https协议的server必须有一套数字证书(一套公钥和密钥) 首先server将证书(公钥)传送到客户端 客户端解析证书,验证成功,则生成一个随机数(私钥),并用证书将该随机数加密后传回server server用密钥解密后,获得这个随机值,然后将要传输的信息和私钥通过某种算法混合在一起(加密)传到客户端 客户端用之前的生成的随机数(私钥)解密服务器端传来的信息
(2)首先浏览器会从内置的证书列表中索引,找到服务器下发证书对应的机构,如果没有找到,此时就会提示用户该证书是不是由权威机构颁发,是不可信任的。如果查到了对应的机构,则取出该机构颁发的公钥。用机构的证书公钥解密得到证书的内容和证书签名,内容包括网站的网址、网站的公钥、证书的有效期等。浏览器会先验证证书签名的合法性。签名通过后,浏览器验证证书记录的网址是否和当前网址是一致的,不一致会提示用户。如果网址一致会检查证书有效期,证书过期了也会提示用户。这些都通过认证时,浏览器就可以安全使用证书中的网站公钥了。

三、C++数据库

1.简述数据库分页?

(1)为了返回第一行或前几行,可使用LIMIT子句,以实现分页查询。
(2)优化LIMIT分页:Ⅰ.如果表的字段过多时,可以采取先扫描少字段建新表,再从.Ⅱ.如果可以使用书签记录上次取数的位置,那么下次就可以直接从该书签记录的位置开始扫描,这样就可以避免使用OFFSET。可以避免了全部数据,只是中间数据就行。

2.SQL中的聚合函数?

(1)常用的聚合函数有COUNT()、AVG()、SUM()、MAX()、MIN()

3.表跟表是怎么关联的?

(1)表与表之间常用的关联方式有两种:内连接、外连接。
(2)从语法上来说明表与表之间关联的实现方式:内连接、外连接、等值连接
(3)从表的关系上来说,比较常见的关联关系有:一对多关联、多对多关联、自关联。

4.说一说你对外连接的了解?

(1)常见的外连接有两种形式:左外连接(LEFT OUTER JOIN)、右外连接(RIGHT OUTER JOIN)。
(2)左外连接:可以简称为左连接(LEFT JOIN),它会返回左表中的所有记录和右表中满足连接条件的记录。
(3)右外连接:可以简称为右连接(RIGHT JOIN),它会返回右表中的所有记录和左表中满足连接条件的记录。
(4)实际上,外连接还有一种形式:完全外连接(FULL OUTER JOIN),但MySQL不支持这种形式。

5.数据库的左连接和右连接?

(1)左外连接:可以简称为左连接(LEFT JOIN),它会返回左表中的所有记录和右表中满足连接条件的记录。
(2)右外连接:可以简称为右连接(RIGHT JOIN),它会返回右表中的所有记录和左表中满足连接条件的记录。

6.SQL中怎么将行转成列?

(1)使用 CASE…WHEN…THEN 语句实现行转列,SUM() 是为了能够使用GROUP BY根据userid进行分组,因为每一个userid对应的subject="语文"的记录只有一条,所以SUM() 的值就等于对应那一条记录的score的值。
(2)使用 IF() 函数实现行转列。

7.对SQL注入的理解?

(1)SQL注入的原理是将SQL代码伪装到输入参数中,传递到服务器解析并执行的一种攻击手法。也就是说,在一些对SERVER端发起的请求参数中植入一些SQL代码,SERVER端在执行SQL操作时,会拼接对应参数,同时也将一些SQL注入攻击的“SQL”拼接起来,导致会执行一些预期之外的操作。
(2)解决SQL注入:Ⅰ.严格的参数校验。Ⅱ.SQL预编译.

8.一张表的部分数据更新到另一张表,该如何操作呢?

(1)可以采用关联更新的方式,将一张表的部分数据,更新到另一张表内。

9. WHERE和HAVING有什么区别?

(1)WHERE是一个约束声明,使用WHERE约束来自数据库的数据,WHERE是在结果返回之前起作用的,WHERE中不能使用聚合函数。
(2)HAVING是一个过滤声明,是在查询返回结果集以后对查询结果进行的过滤操作,在HAVING中可以使用聚合函数。另一方面,HAVING子句中不能使用除了分组字段和聚合函数之外的其他字段。

10.你对MySQL索引的理解?

优点:
(1)通过创建唯一索引,可以保证数据库表中每一行数据的唯一性。
(2)可以大大加快数据的查询速度,这也是创建索引的主要原因。
(3)在实现数据的参考完整性方面,可以加速表和表之间的连接。
(4)在使用分组和排序子句进行数据查询时,也可以显著减少查询中分组和排序的时间。
缺点:
(1)创建索引和维护索引要耗费时间,并且随着数据量的增加所耗费的时间也会增加。
(2)索引需要占磁盘空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果有大量的索引,索引文件可能比数据文件更快达到最大文件尺寸。
(3)当对表中的数据进行增加、删除和修改的时候,索引也要动态地维护,这样就降低了数据的维护速度。

11.索引有哪几种?

(1)普通索引和唯一索引
(2)单列索引和组合索引
(3)全文索引
(4)空间索引

12.如何创建及保存MySQL的索引?

(1)在创建表的时候创建索引
(2)在已存在的表上创建索引alter table add index

13.MySQL怎么判断要不要加索引?

(1)当唯一性是某种数据本身的特征时,指定唯一索引。使用唯一索引需能确保定义的列的数据完整性,以提高查询速度。
(2)在频繁进行排序或分组(即进行group by或order by操作)的列上建立索引,如果待排序的列有多个,可以在这些列上建立组合索引。

14. 只要创建了索引,就一定会走索引吗?

(1)不一定,在使用组合索引的时候,如果没有遵从“最左前缀”的原则进行搜索,则索引是不起作用的。

15.如何判断数据库的索引有没有生效?

(1)可以使用EXPLAIN语句查看索引是否正在使用。

16.如何评估一个索引创建的是否合理?

(1)避免对经常更新的表进行过多的索引,并且索引中的列要尽可能少。应该经常用于查询的字段创建索引,但要避免添加不必要的字段。
(2)数据量小的表最好不要使用索引,由于数据较少,查询花费的时间可能比遍历索引的时间还要短,索引可能不会产生优化效果。
(3)在条件表达式中经常用到的不同值较多的列上建立索引,在不同值很少的列上不要建立索引。
(4)当唯一性是某种数据本身的特征时,指定唯一索引。使用唯一索引需能确保定义的列的数据完整性,以提高查询速度。
(5)在频繁进行排序或分组(即进行group by或order by操作)的列上建立索引,如果待排序的列有多个,可以在这些列上建立组合索引。

17.索引是越多越好吗?

(1)索引并非越多越好,一个表中如有大量的索引,不仅占用磁盘空间,还会影响INSERT、DELETE、UPDATE等语句的性能,因为在表中的数据更改时,索引也会进行调整和更新。

18.数据库索引失效了怎么办?

(1)使用组合索引时,需要遵循“最左前缀”原则;
(2)不在索引列上做任何操作,例如计算、函数、类型转换,会导致索引失效而转向全表扫描;
(3)尽量使用覆盖索引(之访问索引列的查询),减少 select * 覆盖索引能减少回表次数;
(4)MySQL在使用不等于(!=或者<>)的时候无法使用索引会导致全表扫描;
(5)LIKE以通配符开头(%abc)MySQL索引会失效变成全表扫描的操作;
(6)字符串不加单引号会导致索引失效(可能发生了索引列的隐式转换);
(7)少用or,用它来连接时会索引失效。

19. 所有的字段都适合创建索引吗?

(1)频繁更新的字段不适合建立索引;
(2)where条件中用不到的字段不适合建立索引;
(3)数据比较少的表不需要建索引;
(4)数据重复且分布比较均匀的的字段不适合建索引,例如性别、真假值;
(5)参与列计算的列不适合建索引。(上面操作2,会失效)

20.索引的实现原理?

(1)在MySQL中,索引是在存储引擎层实现的,不同存储引擎对索引的实现方式是不同的,下面我们探讨一下MyISAM和InnoDB两个存储引擎的索引实现方式。
(2)MyISAM索引实现:MyISAM引擎使用B+Tree作为索引结构,叶节点的data域存放的是数据记录的地址,MyISAM索引的原理图如下。在MyISAM中,主索引和辅助索引(Secondary key)在结构上没有任何区别,只是主索引要求key是唯一的,而辅助索引的key可以重复。
(3)InnoDB索引实现:虽然InnoDB也使用B+Tree作为索引结构,但具体实现方式却与MyISAM截然不同。第一个重大区别是InnoDB的数据文件本身就是索引文件。第二个与MyISAM索引的不同是InnoDB的辅助索引data域存储相应记录主键的值而不是地址。

21.数据库索引的重构过程?

(1)重建索引原因:Ⅰ.表上频繁发生update,delete操作;
Ⅱ.表上发生了alter table …move操作(move操作导致了rowid变化)。
(2)索引重建判断:Ⅰ.一般看索引是否倾斜的严重,是否浪费了空间,对索引进行结构分析。Ⅱ.在相同的session中查询index_stats表,当查询的height>=4(索引的深度,即从根到叶节点的高度)或DEL_LF_ROWS/LF_ROWS>0.2的情况下,就应该考虑重建该索引。
(3)重建索引:Ⅰ.drop原索引,然后再创建索引。Ⅱ.直接重建索引。
(4)rebuild是快速重建索引的一种有效的办法,因为它是一种使用现有索引项来重建新索引的方法。如果重建索引时有其他用户在对这个表操作,尽量使用带online参数来最大限度的减少索引重建时将会出现的任何加锁问题。由于新旧索引在建立时同时存在,因此,使用这种重建方法需要有额外的磁盘空间可供临时使用,当索引建完后把老索引删除,如果没有成功,也不会影响原来的索引。利用这种办法可以用来将一个索引移到新的表空间。

22.MySQL的索引为什么用B+树?

(1)B+树由B树和索引顺序访问方法演化而来,它是为磁盘或其他直接存取辅助设备设计的一种平衡查找树,在B+树中,所有记录节点都是按键值的大小顺序存放在同一层的叶子节点,各叶子节点通过指针进行链接。

23.联合索引的存储结构是什么,它的有效方式是什么?

(1)联合索引的键值数量不是1,而是大于等于2,只有在查询条件中使用了这些字段的左边字段时,索引才会被使用,所以使用联合索引时遵循最左前缀集合。

24.MySQL的Hash索引和B树索引有什么区别?

(1)hash索引底层就是hash表,进行查找时,调用一次hash函数就可以获取到相应的键值,之后进行回表查询获得实际数据。
(2)B+树底层实现是多路平衡查找树,对于每一次的查询都是从根节点出发,查找到叶子节点方可以获得所查键值,然后根据查询判断是否需要回表查询数据。
(3)hash索引进行等值查询更快(一般情况下),但是却无法进行范围查询。
(4)hash索引不支持使用索引进行排序
(5)hash索引不支持模糊查询以及多列索引的最左前缀匹配,原理也是因为hash函数的不可预测。
(6)hash索引任何时候都避免不了回表查询数据,而B+树在符合某些条件(聚簇索引,覆盖索引等)的时候可以只通过索引完成查询。
(7)hash索引虽然在等值查询上较快,但是不稳定,性能不可预测,当某个键值存在大量重复的时候,发生hash碰撞,此时效率可能极差。而B+树的查询效率比较稳定,对于所有的查询都是从根节点到叶子节点,且树的高度较低。
(8)在大多数情况下,直接选择B+树索引可以获得稳定且较好的查询速度。而不需要使用hash索引。

25.聚簇索引和非聚簇索引有什么区别?

(1)在InnoDB存储引擎中,可以将B+树索引分为聚簇索引和辅助索引(非聚簇索引)。无论是何种索引,每个页的大小都为16KB,且不能更改。
(2)聚簇索引是根据主键创建的一棵B+树,聚簇索引的叶子节点存放了表中的所有记录。
(3)辅助索引是根据索引键创建的一棵B+树,与聚簇索引不同的是,其叶子节点仅存放索引键值,以及该索引键值指向的主键。如果通过辅助索引来查找数据,那么当找到辅助索引的叶子节点后,很有可能还需要根据主键值查找聚簇索引来得到数据,这种查找方式又被称为书签查找。
(4)因为辅助索引不包含行记录的所有数据,这就意味着每页可以存放更多的键值,因此其高度一般都要小于聚簇索引。

26.什么是联合索引?

(1)联合索引是指对表上的多个列进行索引,联合索引的创建方法与单个索引创建的方法一样,不同之处仅在于有多个索引列。

27.select in语句中如何使用索引?

(1)如果字段类型为字符串,需要给in查询中的数值与字符串值都需要添加引号,索引才能起作用。
(2)如果字段类型为int,则in查询中的值不需要添加引号,索引也会起作用。

28.模糊查询语句中如何使用索引?

(1)可以通过加入冗余列,如果以%查询开头的会导致索引失效,但是加入反转列,就可以变成以%结尾的了。

29.数据库事务的了解?

(1)事务可由一条非常简单的SQL语句组成,也可以由一组复杂的SQL语句组成。在事务中的操作,要么都执行修改,要么都不执行,这就是事务的目的,也是事务模型区别于文件系统的重要特征之一。
(2)事务需遵循ACID四个特性:原子性、一致性、隔离性、持久性。
(3)事务可以分为以下几种类型:扁平事务、带有保存点的扁平事务、链事务、嵌套事务、分布式事务。

30. MySQL的ACID特性分别是怎么实现的?

(1)原子性实现原理:实现原子性的关键,是当事务回滚时能够撤销所有已经成功执行的sql语句。undo log属于逻辑日志,它记录的是sql执行相关的信息。当发生回滚时,InnoDB会根据undo log的内容做与之前相反的工作。
(2)持久性实现原理:InnoDB作为MySQL的存储引擎,数据是存放在磁盘中的,但如果每次读写数据都需要磁盘IO,效率会很低。InnoDB提供了缓存(Buffer Pool),Buffer Pool中包含了磁盘中部分数据页的映射,作为访问数据库的缓冲。当从数据库读取数据时,会首先从Buffer Pool中读取,如果Buffer Pool中没有,则从磁盘读取后放入Buffer Pool。:如果MySQL宕机,而此时Buffer Pool中修改的数据还没有刷新到磁盘,就会导致数据的丢失,事务的持久性无法保证。redo log被引入来解决这个问题。
(3)隔离性实现原理:隔离性追求的是并发情形下事务之间互不干扰。
(4)一致性实现原理:一致性是事务追求的最终目标。前面提到的原子性、持久性和隔离性,都是为了保证数据库状态的一致性。除了数据库层面的保障,一致性的实现也需要应用层面进行保障。保证原子性、持久性和隔离性,如果这些特性无法保证,事务的一致性也无法保证。数据库本身提供保障,应用层面进行保障。

31.MySQL的事务隔离级别?

(1)SQL 标准定义了四种隔离级别,这四种隔离级别分别是:读未提交、读提交、可重复读、串行化 。
(2)脏读:当前事务(A)中可以读到其他事务(B)未提交的数据(脏数据),这种现象是脏读。
(3)不可重复读:在事务A中先后两次读取同一个数据,两次读取的结果不一样,这种现象称为不可重复读。
(4)幻读:在事务A中按照某个条件先后两次查询数据库,两次查询结果的条数不同,这种现象称为幻读。

32.MySQL的事务隔离级别是怎么实现的?

(1)READ UNCOMMITTED:它是性能最好、也最野蛮的方式,因为它压根儿就不加锁,所以根本谈不上什么隔离效果,可以理解为没有隔离。
(2)SERIALIZABLE:读的时候加共享锁,其他事务可以并发读,但是不能写。写的时候加排它锁,其他事务不能并发写也不能并发读。
(3)REPEATABLE READ & READ COMMITTED:为了解决不可重复读,MySQL 采用了 MVVC (多版本并发控制) 的方式。

33.事务可以嵌套吗?

(1)因为嵌套事务也是众多事务分类中的一种,它是一个层次结构框架。有一个顶层事务控制着各个层次的事务,顶层事务之下嵌套的事务被称为子事务,它控制每一个局部的变换。

34. 如何实现可重复读?

(1)实现可重复读,MySQL 采用了 MVVC (多版本并发控制) 的方式。
(2)可重复读是在事务开始的时候生成一个当前事务全局性的快照。
(3)当前事务内的更新,可以读到;
(4)版本未提交,不能读到;
(5)版本已提交,但是却在快照创建后提交的,不能读到;
(6)版本已提交,且是在快照创建前提交的,可以读到。

35.如何解决幻读问题?

(1)MySQL 已经在可重复读隔离级别下解决了幻读的问题,用的是间隙锁。MySQL 把行锁和间隙锁合并在一起,解决了并发写和幻读的问题,这个锁叫做 Next-Key锁。

36.MySQL事务如何回滚?

(1)当显示地开启一个事务时,可以使用ROLLBACK语句进行回滚。
(2)ROLLBACK:要使用这个语句的最简形式,只需发出ROLLBACK。
(3)ROLLBACK TO [SAVEPOINT] identifier :这个语句与SAVEPOINT命令一起使用。

37.数据库的锁?

(1)锁的类型:共享锁(S Lock),允许事务读一行数据。排他锁(X Lock),允许事务删除或更新一行数据。
(2)InnoDB存储引擎支持多粒度锁定,这种锁定允许事务在行级上的锁和表级上的锁同时存在。为了支持在不同粒度上进行加锁操作,InnoDB存储引擎支持一种额外的锁方式,称之为意向锁。意向锁是将锁定的对象分为多个层次,意向锁意味着事务希望在更细粒度上进行加锁。
(3)意向共享锁(IS Lock),事务想要获得一张表中某几行的共享锁。意向排他锁(IX Lock),事务想要获得一张表中某几行的排他锁。
(4)InnoDB存储引擎有3种行锁的算法,其分别是:Ⅰ.Record Lock:单个行记录上的锁。Ⅱ.Gap Lock:间隙锁,锁定一个范围,但不包含记录本身。Ⅲ.Next-Key Lock∶Gap Lock+Record Lock,锁定一个范围,并且锁定记录本身。
(5)死锁是指两个或两个以上的事务在执行过程中,因争夺锁资源而造成的一种互相等待的现象。若无外力作用,事务都将无法推进下去。解决死锁问题最简单的一种方法是超时,即当两个事务互相等待时,当一个等待时间超过设置的某一阈值时,其中一个事务进行回滚,另一个等待的事务就能继续进行。
(6)锁升级(Lock Escalation)是指将当前锁的粒度降低。举例来说,数据库可以把一个表的1000个行锁升级为一个页锁,或者将页锁升级为表锁。

38.简述间隙锁?

(1)InnoDB存储引擎有3种行锁的算法,间隙锁(Gap Lock)是其中之一。间隙锁用于锁定一个范围,但不包含记录本身。它的作用是为了阻止多个事务将记录插入到同一范围内,而这会导致幻读问题的产生。

39.InnoDB中行级锁是怎么实现的?

(1)InnoDB行级锁是通过给索引上的索引项加锁来实现的。只有通过索引条件检索数据,InnoDB才使用行级锁,否则,InnoDB将使用表锁。
(2)当表中锁定其中的某几行时,不同的事务可以使用不同的索引锁定不同的行。另外,不论使用主键索引、唯一索引还是普通索引,InnoDB都会使用行锁来对数据加锁。

40. 数据库在什么情况下会发生死锁?

(1)死锁是指两个或两个以上的事务在执行过程中,因争夺锁资源而造成的一种互相等待的现象。若无外力作用,事务都将无法推进下去。

41.数据库死锁的解决办法?

(1)解决死锁问题最简单的一种方法是超时,即当两个事务互相等待时,当一个等待时间超过设置的某一阈值时,其中一个事务进行回滚,另一个等待的事务就能继续进行。
(2)除了超时机制,当前数据库还都普遍采用wait-for graph(等待图)的方式来进行死锁检测。wait-for graph要求数据库保存以下两种信息:Ⅰ.锁的信息链表;Ⅱ.事务等待链表;通过上述链表可以构造出一张图,而在这个图中若存在回路,就代表存在死锁,因此资源间相互发生等待。

42.数据库优化的理解?

(1)MySQL数据库优化是多方面的,原则是减少系统的瓶颈,减少资源的占用,增加系统的反应速度。
(2)针对查询,我们可以通过使用索引、使用连接代替子查询的方式来提高查询速度。
(3)针对慢查询,我们可以通过分析慢查询日志,来发现引起慢查询的原因,从而有针对性的进行优化。
(4)针对插入,我们可以通过禁用索引、禁用检查等方式来提高插入速度,在插入之后再启用索引和检查。
(5)针对数据库结构,我们可以通过将字段很多的表拆分成多张表、增加中间表、增加冗余字段等方式进行优化。

43.优化MySQL的查询?

(1)使用索引:如果查询时没有使用索引,查询语句将扫描表中的所有记录。在数据量大的情况下,这样查询的速度会很慢。如果使用索引进行查询,查询语句可以根据索引快速定位到待查询记录,从而减少查询的记录数,达到提高查询速度的目的。
(2)索引失效情况:Ⅰ.使用LIKE关键字的查询语句,第一个为%;Ⅱ.使用多列索引的查询语句。Ⅲ.使用OR关键字的查询语句,只有前后两个条件都是索引,查询才使用索引。
(3)优化子查询:使用子查询可以进行SELECT语句的嵌套查询,即一个SELECT查询的结果作为另一个SELECT语句的条件。子查询可以一次性完成很多逻辑上需要多个步骤才能完成的SQL操作。在MySQL中,可以使用连接(JOIN)查询来替代子查询。连接查询不需要建立临时表,其速度比子查询要快,如果查询中使用索引,性能会更好。

44.插入数据才能更高效?

(1)影响插入速度的主要是索引、唯一性校验、一次插入记录条数等。
(2)对于MyISAM引擎(select性能好)的表,常见的优化方法如下:Ⅰ.禁用索引。Ⅱ.禁用唯一性检查。Ⅲ.使用批量插入。Ⅳ.使用LOAD DATA INFILE批量导入。
(3)对于InnoDB引擎的表,常见的优化方法如下:Ⅰ.禁用唯一性检查。Ⅱ.禁用外键检查。Ⅲ.禁用自动提交。

45.表中包含几千万条数据该怎么办?

(1)优化SQL和索引;
(2)增加缓存,如memcached、redis;
(3)读写分离,可以采用主从复制,也可以采用主主复制;
(4)使用MySQL自带的分区表,这对应用是透明的,无需改代码,但SQL语句是要针对分区表做优化的;
(5)做垂直拆分,即根据模块的耦合度,将一个大的系统分为多个小的系统;
(6)做水平拆分,要选择一个合理的sharding key,为了有好的查询效率,表结构也要改动,做一定的冗余,应用也要改,sql中尽量带sharding key,将数据定位到限定的表上去查,而不是扫描全部的表。

46.MySQL的慢查询优化?

(1)开启慢查询日志,分析慢查询日志。
(2)常见慢查询优化:Ⅰ.索引没起作用的情况。Ⅱ.优化数据库结构。Ⅲ.分解关联查询。Ⅳ.优化LIMIT分页。

47.对explain的了解?

(1)MySQL中提供了EXPLAIN语句和DESCRIBE语句,用来分析查询语句。

48. 数据库设计的三大范式?

(1)第一范式:必须规定一个字段为主键,而且每个主键都不能再分
(2)第二范式:非主键字段必须完全依赖于主键(一般是联合主键而不是单一主键),不能部分依赖于主键。
(3)第三范式:不能有依赖传递。

49.MySQL引擎的了解?

(1)InnoDB存储引擎:
Ⅰ.InnoDB是事务型数据库的首选引擎,支持事务安全表(ACID),支持行锁定和外键。
Ⅱ.InnoDB给MySQL提供了具有提交、回滚和崩溃恢复能力的事务安全(ACID兼容)存储引擎。
Ⅲ.InnoDB是为处理巨大数据量的最大性能设计。
Ⅳ.InnoDB存储引擎完全与MySQL服务器整合,为在主内存中缓存数据和索引而维持它自己的缓冲池。
Ⅴ.InnoDB支持外键完整性约束(FOREIGN KEY)。
Ⅵ.InnoDB被用在众多需要高性能的大型数据库站点上。
(2)MyISAM存储引擎:
Ⅰ.MyISAM拥有较高的插入、查询速度,但不支持事务。
Ⅱ.在支持大文件(达63位文件长度)的文件系统和操作系统上被支持。
Ⅲ.每个表一个AUTO_INCREMENT列的内部处理。MyISAM为INSERT和UPDATE操作自动更新这一列,这使得AUTO_INCREMENT列更快(至少10%)。在序列顶的值被删除之后就不能再利用。
Ⅳ.可以把数据文件和索引文件放在不同目录。
Ⅴ.每个字符列可以有不同的字符集。

50.简述redo log、undo log、binlog:

(1)binlog(Binary Log):二进制日志文件就是常说的binlog。二进制日志记录了MySQL所有修改数据库的操作,然后以二进制的形式记录在日志文件中,其中还包括每条语句所执行的时间和所消耗的资源,以及相关的事务信息。
(2)redo log:重做日志用来实现事务的持久性,即事务ACID中的D。它由两部分组成:一是内存中的重做日志缓冲(redo log buffer),其是易失的;二是重做日志文件(redo log file),它是持久的。redo log用来保证事务的持久性,undo log用来帮助事务回滚及MVCC的功能。
(3)undo log:重做日志记录了事务的行为,可以很好地通过其对页进行“重做”操作。但是事务有时还需要进行回滚操作,这时就需要undo。

51.简述MVCC?

(1)MVCC即多版本的并发控制协议。它最大的优点是读不加锁,因此读写不冲突,并发性能好。
(2)InnoDB实现MVCC,多个版本的数据可以共存,主要基于以下技术及数据结构:Ⅰ.隐藏列:InnoDB中每行数据都有隐藏列,隐藏列中包含了本行数据的事务id、指向undo log的指针等。
Ⅱ.基于undo log的版本链:每行数据的隐藏列中包含了指向undo log的指针,而每条undo log也会指向更早版本的undo log,从而形成一条版本链。
Ⅲ.ReadView:通过隐藏列和版本链,MySQL可以将数据恢复到指定版本。但是具体要恢复到哪个版本,则需要根据ReadView来确定。所谓ReadView,是指事务(记做事务A)在某一时刻给整个事务系统(trx_sys)打快照,之后再进行读操作时,会将读取到的数据中的事务id与trx_sys快照比较,从而判断数据对该ReadView是否可见,即对事务A是否可见。

52. MySQL主从同步是如何实现的?

(1)复制(replication)是MySQL数据库提供的一种高可用高性能的解决方案,一般用来建立大型的应用。
(2)主服务器(master)把数据更改记录到二进制日志(binlog)中。
(3)从服务器(slave)把主服务器的二进制日志复制到自己的中继日志(relay log)中。
(4)从服务器重做中继日志中的日志,把更改应用到自己的数据库上,以达到数据的最终一致性。
(5)复制的工作原理并不复杂,其实就是一个完全备份加上二进制日志备份的还原。

四、C++设计模式

1.什么是单例设计模式,如何实现?

(1)保证一个类仅有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享。该类不能被复制。该类不能被公开的创造。
(2)单例模式构造函数,拷贝构造函数和赋值函数都不能被公开调用。
(3)实现方式:分别为懒汉式单例和饿汉式单例。
(4)懒汉模式(多线程时会出现问题)实现:Ⅰ.静态指针 + 用到时初始化。Ⅱ.局部静态变量
(5)饿汉模式实现:Ⅰ.直接定义静态对象。Ⅱ.静态指针 + 类外初始化时new空间实现

2.单例设计模式的懒汉式和饿汉式,如何保证线程安全?

(1)懒汉式设计模式:懒汉模式的特点是延迟加载,比如配置文件,采用懒汉式的方法,配置文件的实例直到用到的时候才会加载。也就是说在第一次用到类实例的时候才会去实例化。
(2)饿汉模式:单例类定义的时候就进行实例化。因为main函数执行之前,全局作用域的类成员静态变量m_Instance已经初始化,故没有多线程的问题。
(3)懒汉设计模式两种实现方式线程不安全问题的解决:Ⅰ.静态指针 + 用到时初始化。在程序运行结束时,系统会调用Singleton的静态成员Garbo的析构函数,该析构函数会删除单例的唯一实例。Ⅱ.局部静态变量。对于析构的顺序,我们可以用一个容器来管理它,根据单例之间的依赖关系释放实例,对所有的实例的析构顺序进行排序,之后调用各个单例实例的析构方法,如果出现了循环依赖关系,就给出异常,并输出循环依赖环。

3.工厂设计模式,如何实现,以及它的优点?

(1)工厂设计模式:定义一个创建对象的接口,让子类决定实例化哪个类,而对象的创建统一交由工厂去生产,有良好的封装性,既做到了解耦,也保证了最少知识原则。
(2)工厂模式属于创建型模式,大致可以分为三类,简单工厂模式、工厂方法模式、抽象工厂模式。
(3)简单工厂模式:它的主要特点是需要在工厂类中做判断,从而创造相应的产品。当增加新的产品时,就需要修改工厂类。优点:简单工厂模式可以根据需求,动态生成使用者所需类的对象,而使用者不用去知道怎么创建对象,使得各个模块各司其职,降低了系统的耦合性。
(4)工厂方法模式:所谓工厂方法模式,是指定义一个用于创建对象的接口,让子类决定实例化哪一个类。优点:展性好,符合了开闭原则,新增一种产品时,只需增加改对应的产品类和对应的工厂子类即可。
(5)抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。优点:工厂抽象类创建了多个类型的产品,当有需求时,可以创建相关产品子类和子工厂类来获取。

4.装饰器模式,以及它的优缺点?

(1)装饰器模式:指在不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)的模式,它属于对象结构型模式。
(2)优点:Ⅰ.装饰器是继承的有力补充,比继承灵活,在不改变原有对象的情况下,动态的给一个对象扩展功能,即插即用;Ⅱ.通过使用不用装饰类及这些装饰类的排列组合,可以实现不同效果;Ⅲ.装饰器模式完全遵守开闭原则。
(3)缺点:装饰模式会增加许多子类,过度使用会增加程序得复杂性。
(4)装饰模式的结构与实现:通常情况下,扩展一个类的功能会使用继承方式来实现。但继承具有静态特征,耦合度高,并且随着扩展功能的增多,子类会很膨胀。如果使用组合关系来创建一个包装对象(即装饰对象)来包裹真实对象,并在保持真实对象的类结构不变的前提下,为其提供额外的功能,这就是装饰模式的目标。

5.观察者设计模式,如何实现?

(1)观察者设计模式:指多个对象间存在一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
(2)优点:Ⅰ.降低了目标与观察者之间的耦合关系,两者之间是抽象耦合关系。Ⅱ.目标与观察者之间建立了一套触发机制。
(3)缺点:Ⅰ.目标与观察者之间的依赖关系并没有完全解除,而且有可能出现循环引用。Ⅱ.当观察者对象很多时,通知的发布会花费很多时间,影响程序的效率。
(4)实现:具体主题类添加观察者链表,通过notify函数去通知观察者链表中的观察者。


参考

牛客C++训练营

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值