最终挂在三面了,有点可惜,不过继续加油把,第一次已经很棒了!
一面
C++ 多态是什么
多态是在不同继承关系的类对象,去调同一函数,产生了不同的行为。
就是说,有一对继承关系的两个类,这两个类里面都有一个函数且名字、参数、返回值均相同,然后我们通过调用函数来实现不同类对象完成不同的事件。
但是构成多态还有两个条件:
1、调用函数的对象必须是指针或者引用。
2、被调用的函数必须是虚函数,且完成了虚函数的重写,也就是说必须要在两个产生多态的函数前面加virtual
关键字。
调用函数的参数必须是指针或引用,因为派生类改变了虚表,那么这个虚表就属于派生类对象,赋值的时候只会把基类的成员给过去,虚表指针不会给。所以在调用函数的时候会发生语法检查,如果满足多态的条件,就会触发寻找虚表中虚函数地址。如果不满足条件,则会直接用基类对象调用基类函数。
基类中的析构函数如果是虚函数,那么派生类的析构函数就重写了基类的析构函数。这里他们的函数名不相同,看起来违背了重写的规则,其实不然,这里可以理解为编译器对析构函数的名称做了特殊处理,编译后析构函数的名称统一处理成destructor
,这也说明的基类的析构函数最好写成虚函数。
纯虚函数就是在虚函数的前提上加上=0
。
override
可以用于防止忘记重写虚函数:
virtual void fun() override {}
不想让类被继承
class A final{}
或者
构造函数声明为private
文件从编写的 C 代码到生成可执行文件中间经历了哪些主要步骤?
预处理:
头文件展开:将程序中所用的头文件用其内容来替换头文件名。
宏替换:扫描程序中的符号,将其替换成宏所定义的内容。
去注释:去掉程序中的注释。
条件编译:筛选掉条件编译中的伪命令。
编译:
分析语法
→
\to
→代码优化
→
\to
→目标代码优化
主要是删除公共表达式、循环优化(代码外提、强度削弱、变换循环控制条件、已知量的合并等)、复写传播以及无用赋值的删除,等等。
目标代码优化:最主要的是考虑是如何充分利用机器的各个硬件寄存器存放的有关变量的值,以减少对于内存的访问次数。另外根据机器硬件执行指令的特点(如流水线、RISC、CISC、VLIW等)而对指令进行一些调整使目标代码比较短,执行的效率比较高。
汇编:
把汇编语言代码翻译成目标机器指令的过程。
通常一个目标文件中至少有两个段:
代码段:该段中所包含的主要是程序的指令,一般是可读和可执行的,但一般却不可写;
数据段:主要存放程序中要用到的各种全局变量或静态的数据,该段都是可读,可写,可执行的。
链接:
完成文件中各种调用的函数以及库的连接,并将它们一起打包合并形成可执行文件。
内存分区
堆和栈区别(内存)
申请方式
stack
:
由系统自动分配。例如,声明在函数中一个局部变量int b;
系统自动在栈中为b开辟空间。
heap
:
需要程序员自己申请,并指明大小
在c
中malloc
函数,如:p1 = (char *)malloc(10);
在C++
中用new运算符,如:p2 = new char[10];
但是注意p1
、p2
本身是在栈中的。
申请后系统的响应
栈: 只要栈的剩余空间大于所申请空间,系统将为程序提供内存,否则将报异常提示栈溢出。
堆: 首先应该知道操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时,遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点的空间分配给程序,另外,对于大多数系统,会在这块内存空间中的首地址处记录本次分配的大小,这样,代码中的delete
语句才能正确的释放本内存空间。另外,由于找到的堆结点的大小不一定正好等于申请的大小,系统会自动的将多余的那部分重新放入空闲链表中。
申请大小的限制
栈:在Windows下,栈是向低地址扩展的数据结构,是一块连续的内存的区域。这句话的意思是栈顶的地址和栈的最大容量是系统预先规定好的,在WINDOWS下,栈的大小是2M(也有的说是1M,总之是一个编译时就确定的常数),如果申请的空间超过栈的剩余空间时,将提示overflow。因此,能从栈获得的空间较小。
堆:堆是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大。
申请效率的比较:
栈由系统自动分配,速度较快。但程序员是无法控制的。
堆是由new
分配的内存,一般速度比较慢,而且容易产生内存碎片,不过用起来最方便。
堆和栈中的存储内容
栈:在函数调用时,第一个进栈的是主函数中后的下一条指令(函数调用语句的下一条可执行语句)的地址,然后是函数的各个参数,在大多数的C编译器中,参数是由右往左入栈的,然后是函数中的局部变量。注意静态变量是不入栈的。
当本次函数调用结束后,局部变量先出栈,然后是参数,最后栈顶指针指向最开始存的地 址,也就是主函数中的下一条指令,程序由该点继续运行。
堆: 一般是在堆的头部用一个字节存放堆的大小。堆中的具体内容由程序员安排。
存取效率的比较
char s1[] = "aaaaaaaaaaaaaaa";
char *s2 = "bbbbbbbbbbbbbbbbb";
aaaaaaaaaaa
是在运行时刻赋值的;
而bbbbbbbbbbb
是在编译时就确定的;
但是,在以后的存取中,在栈上的数组比指针所指向的字符串(例如堆)快。
栈为什么效率比堆高
1、有寄存器直接对栈进行访问 (esp
(栈指针寄存器),ebp
(基址指针寄存器),而对堆访问,只能是间接寻址。也就是说,可以直接从地址取数据放至目标地址;使用堆时,第一步将分配的地址放到寄存器,然后取出这个地址的值,然后放到目标地址。
2、栈中数据cpu
命中率更高,满足局部性原理。
3、栈是编译时系统自动分配空间,而堆是动态分配(运行时分配空间),所以栈的速度快。
空类大小
空类大小为1
(为了区分实例),函数在内存中不占字节,但是如果有虚函数则占内存(32
位:4
个字节),因为存放了指向虚表的指针,继承的时候需要加上基类大小,虚函数会放在基类的虚表下,虚继承的话会产生新的虚表,指向虚表指针和虚继承表的指针。
类指针为空,调用函数
1)NULL对象指针可以调用成员函数
2)通过对象调用成员函数,对象的指针会被传入函数中,指针名称为this
3)NULL对象指针调用成员函数时,只要不访问此对象的成员变量,则程序正常运行
4)NULL对象指针调用成员函数时,一旦访问此对象的成员变量,则程序崩溃
类的成员函数并不与具体对象绑定,所有的对象共用一份函数体。
调用虚函数也不行,因为会用到虚表指针。
虚拟内存的作用
1、程序不再受物理内存的可用量所限制。用户可以为一个巨大的虚拟地址空间编写程序,从而简化了编程任务。
2、由于每个用户程序可占用较少的物理内存,因此可以同时运行更多的程序,进而增加 CPU 利用率和吞吐量,但没有增加响应时间或周转时间。
3、由于加载或交换每个用户程序到内存所需的 I/O 会更少,用户程序会运行得更快。因此,运行不完全处于内存的程序将使系统和用户都受益。
缓存
内存管理
内存保护
- 不允许一个用户进程修改它的只读代码段;
- 不允许用户进程读或修改任何内核中的代码和数据结构;
- 不允许用户进程读或写其他进程的私有内存;
- 不允许用户进程修改任何其他进程共享的虚拟页表
为什么要分页分段
段向用户提供二维地址空间;页向用户提供的是一维地址空间
段是信息的逻辑单位,便于存储保护和信息的共享,页的保护和共享受到限制
提高内存使用率,减少内存碎片
分页和分段划分的大小不同。
分页:满足操作系统内存管理的需求
分段:段是逻辑信息的单位,满足用户需求,段有具体的意义
vector的内存机制
vector
是STL
中最常见的容器,它是一种顺序容器,支持随机访问。vector
是一块连续分配的内存,从数据安排的角度来讲,和数组极其相似,
不同的地方就是:数组是静态分配空间,一旦分配了空间的大小,就不可再改变了;而vector
是动态分配空间,随着元素的不断插入,它会按照自身的一套机制不断扩充自身的容量。
vector
的扩充机制:按照容器现在容量的一倍进行增长。vector
容器分配的是一块连续的内存空间,每次容器的增长,并不是在原有连续的内存空间后再进行简单的叠加,而是重新申请一块更大的新内存,并把现有容器中的元素逐个复制过去,然后销毁旧的内存。这时原有指向旧内存空间的迭代器已经失效,所以当操作容器时,迭代器要及时更新。
vector push_back的复杂度
假设有
n
n
n个元素,倍增因子为
m
m
m,那么完成操作,重新分配大约是logm(n)
次,第
i
i
i次分配会导致复制
m
i
m^i
mi个元素,所以总共为
a
1
−
a
n
q
1
−
q
=
1
−
m
l
o
g
m
n
m
1
−
m
=
m
n
−
1
m
−
1
≈
m
n
m
−
1
\frac{a_1-a_nq}{1-q}=\frac{1-m^{log_m{n}}m}{1-m}=\frac{mn-1}{m-1}≈\frac{mn}{m-1}
1−qa1−anq=1−m1−mlogmnm=m−1mn−1≈m−1mn
均摊每次都是
m
m
−
1
=
2
\frac{m}{m-1}=2
m−1m=2
TCP和UDP的区别
TCP
是面向连接的,UDP
是无连接的;
TCP
是可靠的,UDP
是不可靠的;
TCP
只支持点对点通信,UDP
支持一对一、一对多、多对一、多对多的通信模式;
TCP
是面向字节流的,UDP
是面向报文的;
TCP
有拥塞控制机制;UDP
没有拥塞控制,适合媒体通信;
TCP
首部开销(20个字节)比UDP
的首部开销(8个字节)要大;
TCP的通信异常
试图和一个不存在的端口创建连接
服务器没有监听端口,会响应一个RST
,表示出错。
试图和一个不存在的主机上面的某端口
如果客户端TCP
没有得到任何响应,那么等待6s
之后再发一个SYN,若无响应则等待24s
再发一个,若总共等待了75s
后仍未收到响应就会返回ETIMEDOUT
错误。这是TCP
建立连接自己的一个保护机制,但是我们要等待75s
才能知道这个连接无法建立,对于我们所有服务来说都太长了。更好的做法是在代码中给connect
设置一个超时时间,使它变成我们可控的,让等待时间在毫秒级还是可以接收的。
服务器进程阻塞
建立连接的过程是对应用程序是不可见的,连接可以正常建立。
客户端进程也可以通过这个连接给服务器端发送请求,服务器端TCP
会应答ACK
表示已经收到这个分节(这里的收到指的是数据已经在内核的缓冲区里准备好,由于进程被阻塞,无法将数据从内核的缓冲区复制到应用程序的缓冲区),永远不会返回结果。
我们杀死进程
在进程正常退出的时候,会自动调用close
函数来关闭它所打开的文件描述符,然后会进行正常的四次握手。
主机关机
init
进程(Linux
中的所有进程都是由init
进程创建并运行的)会给所有进程发送SIGTERM
信号,等待一段时间(5
~20
秒),然后再给所有仍在运行的进程发送SIGKILL
信号。当服务器进程死掉时,会关闭所有文件描述符。带来的影响和上面杀死server
相同。
服务器主机宕机
TCP
客户端得不到任何响应,会不断重传,对端TCP
显然不会响应这个分节,因为主机已经挂掉,于是客户端TCP
持续重传分节,试图从服务器上接收一个ACK
,然而服务器始终不能应答,重传数次之后,大约4
~10
分钟才停止,之后返回一个ETIMEDOUT
错误。
事实上TCP
为我们提供了更好的方法,用SO_KEEPALIVE
的套接字选项——相当于心跳包,每隔一段时间给对方发送一个心跳包,当对方没有响应时会一更短的时间间隔发送,一段时间后仍然无响应的话就断开这个连接。
服务器主机宕机后重启
在客户端发出请求前,服务器端主机经历了宕机——重启的过程。当客户端TCP
把分节发送到服务器端所在的主机,服务器端所在主机的TCP
丢失了崩溃前所有连接信息,即TCP
收到了一个根本不存在连接上的分节,所以会响应一个RST
分节。如果开发的代码足够健壮的话会试图重新建立连接,或者把这个请求转发给其他服务器。
TCP场景下发送多个小包,增加速率
Nagle
算法:
为防止因数据包过多而发生网络过载, Nagle
算法诞生了。它应用于TCP
层,非常简单。其使用与否会导致如图所示差异。
Nagle
算法:“只有收到前一数据的ACK
消息时,Nagle
算法才发送下一数据”
最典型的是传输大文件时,由于把数据输入到缓冲区的速度快,但是把缓冲区输出到网络上就慢,如果还要等待ACK
的话,那就更慢,所以我们希望缓冲区的数据尽快发送出去,后面的数据才更好的输入到缓存区中。在这种情况下不使用Nagle
算法不仅不会增加数据包的数量, 反而会在无需等待ACK
的前提下连续传输, 因此可以大大提高传输速度。(服务器及时响应)
如果发送方持续地发送小批量的数据, 并且接收方不一定会立即发送响应数据, 那么Nagle
就会让发送方看起来很慢。
【由于发送方会控制小的分组,并期望合并成为较大的分组一起发送给接收方,因此实时的单向的发送数据并及时获取响应的场景需要谨慎。另外,如果接收方设置了DELAY ACK
,情况可能会比较糟糕:因为如果接收方设置了DELAY ACK
,接收方接收到发送方发过来的小分组后,并不及时发送ACK
,只有等到Delay ACK
的Timer到期后,才会给发送方回ACK
。】
算法会使发送方运行很慢.
HTTP和HTTPS的区别
HTTP
(超文本传输协议)默认工作在TCP
协议80
端口,用户访问网站http://
打头的都是标准HTTP
服务。
HTTP
协议以明文方式发送内容,不提供任何方式的数据加密,如果攻击者截取了Web浏览器和网站服务器之间的传输报文,就可以直接读懂其中的信息,因此,HTTP
协议不适合传输一些敏感信息,比如:信用卡号、密码等支付信息。
HTTPS
是一种透过计算机网络进行安全通信的传输协议。
HTTPS
经由HTTP
进行通信,但利用SSL/TLS
来加密传输数据包。
HTTPS
开发的主要目的,是提供对网站服务器的身份认证,保护交换数据的隐私与完整性。
HTTPS
默认工作在TCP
协议443
端口,工作流程:
1、TCP
三次同步握手
2、客户端验证服务器数字证书
3、DH
算法协商对称加密算法的密钥、hash
算法的密钥
4、SSL
安全加密隧道协商完成
5、网页以加密的方式传输,用协商的对称加密算法和密钥加密,保证数据机密性;用协商的hash
算法进行数据完整性保护,保证数据不被篡改。
HTTPS
需要7
次握手:
1、客户端向服务端发送Client Hello
消息,其中携带客户端支持的协议版本、加密算法、压缩算法以及客户端生成的随机数;
2、服务端收到客户端支持的协议版本,加密算法等信息后:
向客户端发生Server Hello
消息,并携带选择待定的协议版本、加密方法、会话ID
以及服务端生成的随机数消息;
向客户端发生Certificate
,即:服务端的证书链,其中包含证书支持的域名、发行方和有效期等信息;
向客户端发送Server Key Exchange
,传递公钥以及签名等信息
向客户端发送可选的消息CertificateRequest
,验证客户端的证书
向客户端发送Server Hello Done
消息,通知服务端已经发送了全部的相关消息;
3、客户端收到服务端的协议版本、加密方法、会话 ID 以及证书等信息后,验证服务端的证书;
向服务端发送Client Key Exchange
消息,包含使用服务端公钥加密后的随机字符串,即预主密钥(Pre Master Secret
);
向服务端发送Change Cipher Spec
消息,通知服务端后面的数据段会加密传输;
向服务端发送Finished
消息,其中包含加密后的握手信息;
4、服务端收到Change Cipher Spec
和Finished
消息后;
向客户端发送Change Cipher Spec
消息,通知客户端后面的数据段会加密传输;
向客户端发送Finished
消息,验证客户端的Finished
消息并完成TLS
握手;
区别:
1、HTTP
明文传输,数据都是未加密的,安全性较差,HTTPS
(SSL
+HTTP
) 数据传输过程是加密的,安全性较好。
2、使用 HTTPS
协议需要到 CA
(Certificate Authority
,数字证书认证机构) 申请证书,一般免费证书较少,因而需要一定费用。证书颁发机构如:Symantec
、Comodo
、GoDaddy
和 GlobalSign
等。
3、HTTP
页面响应速度比HTTPS
快,主要是因为HTTP
使用 TCP
三次握手建立连接,后者用了七次。
4、http
和 https
使用的是完全不同的连接方式,用的端口也不一样,前者是 80,后者是 443
。
5、HTTPS
其实就是建构在 SSL/TLS
之上的HTTP
协议,所以,要比较HTTPS
比HTTP
要更耗费服务器资源。
实际流程:
数据库索引,实现原理
使用了B+
树;
B
树:是一种多路搜索树,每个节点可以拥有多于两个孩子节点,M
路最多M
个孩子节点,多路是为了降低树的高度,无限多路会退化成有序数组。
而数据量大的时候,并不能把数据一次加载在内存中。
每次加载一个节点进内存。
B+
树:数据都在叶子节点,同时叶子节点加了指针形成了链表。
如果要取数据的话,因为索引有序,只需要找到首尾就可以把所有数据取出来了,而B
树需要一个个去找。
具体一点:
- B+树的数据都集中在叶子节点。分支节点只负责索引。B树的分支节点也有数据。B+树的层高会小于B树,平均的IO次数会远小于B树
- B+树更擅长范围查询。存储在叶子节点中的数据是按顺序放置的双向链表。而B树范围查询只能中序遍历。
- 索引节点没有数据。比较小。b树可以把索引完全加载至内存中。
B*树在B+树基础上,为非叶子结点也增加链表指针,并且分裂的时候会加到兄弟节点上,如果兄弟满了在两者之间增加新结点,最后要修改关键字。
二面
DNS查询
本地DNS
服务器是运营商提供的DNS
IP地址
IP地址由网络号(包括子网号)和主机号组成,网络地址的主机号为全0,网络地址代表着整个网络。
广播地址与网络地址的主机号正好相反,广播地址中,主机号为全1。当向某个网络的广播地址发送消息时,该网络内的所有主机都能收到该广播消息。
组播地址:(组播是局部的广播)
D
类地址就是组播地址。
A类地址以0
开头,第一个字节作为网络号,0.0.0.0~127.255.255.255
127.X.X.X
是保留地址,做循环测试使用。
B类地址以10
开头,前两个字节作为网络号,128.0.0.0~191.255.255.255
169.254.X.X
是保留地址。如果你的IP地址是自动获取IP
地址,而你在网络上有没有找到可用的DHCP
服务器,就会得到其中一个IP
地址。
C类地址以110
开头,前三个字节作为网络号,192.0.0.0~223.255.255.255
。
D类地址以1110
开头,地址范围是224.0.0.0~239.255.255.255
,D类地址作为组播地址(一对多的通信);
E类地址以1111
开头,地址范围是240.0.0.0~255.255.255.255
,E类地址为保留地址,供以后使用。
私有地址(private address)也叫专用地址,它们不会在全球使用,只具有本地意义。
A类私有地址:10.0.0.0/8
,范围是:10.0.0.0~10.255.255.255
B类私有地址:172.16.0.0/12
,范围是:172.16.0.0~172.31.255.255
C类私有地址:192.168.0.0/16
,范围是:192.168.0.0~192.168.255.255
注:只有A
,B
,C
有网络号和主机号之分,D
类地址和E
类地址没有划分网络号和主机号。
255.255.255.255
:受限的广播地址,只用于本地网络。
0.0.0.0
:用于寻找自己的IP
地址
保留的IP地址段不会在互联网上使用,因此与广域网相连的路由器在处理保留IP地址时,只是将该数据包丢弃处理,而不会路由到广域网上去,从而将保留IP地址产生的数据隔离在局域网内部,只用于内部通信。
子网掩码:
子网掩码用来标识两个IP
地址是否属于一个子网。
如果不需要划分子网,那么子网掩码是:B类:255.255.0.0
子网数:27=11011
二进制位数为
N
=
5
N=5
N=5
然后将类子网掩码主机地址前
N
N
N位置1
得到255.255.248.0
划分成多个子网,每个子网内有主机700
台:
1
将主机数目转换成二进制来表示;
2
如果主机数小于
254
254
254(去掉全
0
0
0和全
1
1
1),就是
N
<
8
N<8
N<8,否则
N
>
8
N>8
N>8
3
将主机地址全部置为
1
1
1,然后从后往前置
N
N
N位
0
0
0
如果一个子网有
10
10
10个主机,需要
13
13
13个
I
P
IP
IP地址,分别是广播地址、本网络地址、以及这个网络连接时所需的网关地址。
1.子网划分的好处:节省IP资源/方便划分VLAN,分割局域网。
2.子网掩码的作用:区分不同网络。
TCP模型,为什么没有应用层和会话层
因为将其合并在了应用层协议。
怎么查看进程cpu使用率
top
命令
%CPU
上次更新到现在的CPU时间占用百分比
TIME
进程使用的CPU
时间总计,单位秒
TIME+
进程使用的CPU
时间总计,单位1/100
秒
%MEM
进程使用的物理内存百分比
SHR
共享内存大小,单位kb
RES
进程使用的、未被换出的物理内存大小,单位kb
。RES=CODE+DATA
查看linux负载情况
当前时间
系统已运行的时间
当前在线用户
平均负载:0.54
, 0.40
, 0.20
,最近1
分钟、5
分钟、15
分钟系统的负载
直接查看平均负载:
后面两个表示进程使用个数/总进程,最后一个进程
i
d
id
id.
系统负载是什么
系统平均负载被定义为在特定时间间隔内运行队列中的平均进程数。如果一个进程满足以下条件则其就会位于运行队列中:
它没有在等待I/O操作的结果
它没有主动进入等待状态(也就是没有调用’wait
’)
没有被停止(例如:等待终止)
负载均衡
负载均衡有两方面的含义:首先,大量的并发访问或数据流量分担到多台节点设备上分别处理,减少用户等待响应的时间;其次,单个重负载的运算分担到多台节点设备上做并行处理,每个节点设备处理结束后,将结果汇总,返回给用户,系统处理能力得到大幅度提高。
分类:
1)二层负载均衡
m
a
c
mac
mac
根据OSI模型分的二层负载,一般是用虚拟mac地址方式,外部对虚拟MAC地址请求,负载均衡接收后分配后端实际的MAC地址响应.
2)三层负载均衡
i
p
ip
ip
一般采用虚拟IP地址方式,外部对虚拟的ip地址请求,负载均衡接收后分配后端实际的IP地址响应. (即一个ip对一个ip的转发, 端口全放开)
3)四层负载均衡
t
c
p
tcp
tcp
在三次负载均衡的基础上,即从第四层"传输层"开始, 使用"ip+port"接收请求,再转发到对应的机器。
4)七层负载均衡
h
t
t
p
http
http
从第七层"应用层"开始, 根据虚拟的
u
r
l
url
url或
I
P
IP
IP,主机名接收请求,再转向相应的处理服务器。
1)四层的负载均衡就是基于IP+端口的负载均衡:在三层负载均衡的基础上,通过发布三层的IP地址(VIP),然后加四层的端口号,来决定哪些流量需要做负载均衡,对需要处理的流量进行NAT处理,转发至后台服务器,并记录下这个TCP或者UDP的流量是由哪台服务器处理的,后续这个连接的所有流量都同样转发到同一台服务器处理。
对应的负载均衡器称为四层交换机(L4 switch),主要分析IP层及TCP/UDP层,实现四层负载均衡。此种负载均衡器不理解应用协议(如HTTP/FTP/MySQL等等)。
2)七层的负载均衡就是基于虚拟的URL或主机IP的负载均衡:在四层负载均衡的基础上(没有四层是绝对不可能有七层的),再考虑应用层的特征,比如同一个Web服务器的负载均衡,除了根据VIP加80端口辨别是否需要处理的流量,还可根据七层的URL、浏览器类别、语言来决定是否要进行负载均衡。举个例子,如果你的Web服务器分成两组,一组是中文语言的,一组是英文语言的,那么七层负载均衡就可以当用户来访问你的域名时,自动辨别用户语言,然后选择对应的语言服务器组进行负载均衡处理。
对应的负载均衡器称为七层交换机(L7 switch),除了支持四层负载均衡以外,还有分析应用层的信息,如HTTP协议URI或Cookie信息,实现七层负载均衡。此种负载均衡器能理解应用协议。
三面
linux可以带写带删吗
linux
是通过link
的数量来控制文件删除,只有当一个文件不存在任何link
的时候,这个文件才会被删除。
而每个文件都会有2个link
计数器i_count
和i_nlink
。i_count
的意义是当前使用者的数量,也就是打开文件进程的个数。i_nlink
的意义是介质连接的数量;或者可以理解为i_count
是内存引用计数器,i_nlink
是硬盘引用计数器。再换句话说,当文件被某个进程引用时,i_count
就会增加;当创建文件的硬连接的时候,i_nlink
就会增加。
对于 rm
而言,就是减少 i_nlink
。这里就出现一个问题,如果一个文件正在被某个进程调用,而用户却执行rm
操作把文件删除了,会出现什么结果呢?
当用户执行rm
操作后,ls
或者其他文件管理命令不再能够找到这个文件,但是进程却依然在继续正常执行,依然能够从文件中正确的读取内容。这是因为,rm
操作只是将i_nlink
置为 0 了;由于文件被进程引用的缘故,i_count
不为 0,所以系统没有真正删除这个文件。i_nlink
是文件删除的充分条件,而i_count
才是文件删除的必要条件。
c++的字节对齐
详情
注意:字节对齐要考虑对齐的那个变量大小,最后也要对齐上。
长度为
0
0
0的数组是可以的,但是没有内存大小,但是内存对齐会按它对齐。
TraceRoute
UDP
实现:
客户端发送一个TTL为1,端口号大于30000的UDP数据包,到达第一站路由器之后TTL被减去1,返回了一个超时的ICMP数据包,客户端得到第一跳路由器的地址。
客户端发送一个TTL为2的数据包,在第二跳的路由器节点处超时,得到第二跳路由器的地址。
客户端发送一个TTL为3的数据包,数据包成功到达目标主机,返回一个端口不可达错误,traceroute结束。
ICMP
实现:
客户端发送一个TTL为1的ICMP请求回显数据包,在第一跳的时候超时并返回一个ICMP超时数据包,得到第一跳的地址。
客户端发送一个TTL为2的ICMP请求回显数据包,得到第二跳的地址。
客户端发送一个TTL为3的ICMP请求回显数据包,到达目标主机,目标主机返回一个ICMP回显应答,traceroute结束。
进程、线程、协程的区别
进程:拥有自己独立的堆和栈,既不共享堆,也不共享栈,进程由操作系统调度;
线程:拥有自己独立的栈和共享的堆,共享堆,不共享栈,标准线程由操作系统调度;
协程:拥有自己独立的栈和共享的堆,共享堆,不共享栈,协程由程序员在协程的代码里显示调度
线程里面可以包含多个协程,协程之间执行按照一定顺序交替执行。
HTTP和HTTPS
HTTP工作流程:
第一步:建立TCP/IP连接,客户端与服务器通过Socket三次握手进行连接。
第二步:客户端向服务端发起HTTP请求(例如:POST/login.html http/1.1)。
第三步:客户端发送请求头信息,请求内容,最后会发送一空白行,标示客户端请求完毕。
第四步:服务器做出应答,表示对于客户端请求的应答,例如:HTTP/1.1 200 OK。
第五步:服务器向客户端发送应答头信息。
第六步:服务器向客户端发送请求头信息后,也会发送一空白行,标示应答头信息发送完毕,接着就以Content-type要求的数据格式发送数据给客户端。
第七步:服务端关闭TCP连接,如果服务器或者客户端增Connection:keep-alive就表示客户端与服务器端继续保存连接,在下次请求时可以继续使用这次的连接。
HTTPS特点:
HTTPS是HTTP协议的修改,他加密数据并确保其机密性。其配置可保护用户在于网站交互时免于窃取个人信息和计费数据。
1、优点
相比于http,https可以提供更加优质保密的信息,保证了用户数据的安全性,此外https同时也一定程度上保护了服务端,使用恶意攻击和伪装数据的成本大大提高。
2、缺点
缺点也同样很明显,第一https的技术门槛较高,多数个人或者私人网站难以支撑,CA机构颁发的证书都是需要年费的,此外对接Https协议也需要额外的技术支持;其二,目前来说大多数网站并不关心数据的安全性和保密性,其https最大的优点对它来说并不适用;其三,https加重了服务端的负担,相比于http其需要更多的资源来支撑,同时也降低了用户的访问速度;第四,目前来说Http网站仍然大规模使用,在浏览器侧也没有特别大的差别,很多用户不关心的话根本不感知。
HTTPS工作流程:
第一步:客户使用https的URL访问Web服务器,要求与Web服务器建立SSL连接。
第二步:Web服务器收到客户端请求后,会将网站的证书信息(证书中包含公钥)传送一份给客户端。
第三步:客户端的浏览器与Web服务器开始协商SSL连接的安全等级,也就是信息加密的等级。
第四步:客户端的浏览器根据双方同意的安全等级,建立会话密钥,然后利用网站的公钥将会话密钥加密,并传送给网站。
第五步:Web服务器利用自己的私钥解密出会话密钥。
第六步:Web服务器利用会话密钥加密与客户端之间的通信。
UDP协议有哪些
1.RIP:路由选择信息协议(RIP)是一种在网关与主机之间交换路由选择信息的标准
2.DNS:用于域名解析服务,这种服务在Windows NT系统中用得最多的。因特网上的每一台计算机都有一个网络地址与之对应。
3.SNMP:简单网络管理协议,使用161号端口,是用来管理网络设备的。由于网络设备很多,无连接的服务就有了优势。
4.OICQ:OICQ程序既接受服务,又提供服务,这样两个聊天的人才是平等的。