网易整理

程序运行过程,预处理,编译,汇编,链接

首先对源文件进行预处理,这个过程主要是处理一些#号定义的命令或语句(如宏、#include、预编译指令#ifdef等),生成*.i文件;然后进行编译,这个过程主要是进行词法分析、语法分析和语义分析等,生成*.s的汇编文件;最后进行汇编,这个过程比较简单,就是将对应的汇编指令翻译成机器指令,生成可重定位的二进制目标文件。以上就是编译的过程,下面主要介绍两种链接方式–静态链接和动态链接。

静态链接是在形成可执行程序前,而动态链接的进行则是在程序执行时,下面来详细介绍这两种链接方式。
为什么要进行静态链接
在我们的实际开发中,不可能将所有代码放在一个源文件中,所以会出现多个源文件,而且多个源文件之间不是独立的,而会存在多种依赖关系,如一个源文件可能要调用另一个源文件中定义的函数,但是每个源文件都是独立编译的,即每个*.c文件会形成一个*.o文件,为了满足前面说的依赖关系,则需要将这些源文件产生的目标文件进行链接,从而形成一个可以执行的程序。这个链接的过程就是静态链接

从静态链接到可执行文件的过程,根据在源文件中包含的头文件和程序中使用到的库函数,如stdio.h中定义的printf()函数,在libc.a中找到目标文件printf.o(这里暂且不考虑printf()函数的依赖关系),然后将这个目标文件和我们hello.o这个文件进行链接形成我们的可执行文件。

链接器在链接静态链接库的时候是以目标文件为单位的。比如我们引用了静态库中的printf()函数,那么链接器就会把库中包含printf()函数的那个目标文件链接进来,如果很多函数都放在一个目标文件中,很可能很多没用的函数都被一起链接进了输出结果中。

静态编译优缺点,优:执行速度快,缺浪费空间,更新困难

静态链接的缺点很明显,一是浪费空间,因为每个可执行程序中对所有需要的目标文件都要有一份副本,所以如果多个程序对同一个目标文件都有依赖,如多个程序中都调用了printf()函数,则这多个程序中都含有printf.o,所以同一个目标文件都在内存存在多个副本;另一方面就是更新比较困难,因为每当库函数的代码修改了,这个时候就需要重新进行编译链接形成可执行程序。但是静态链接的优点就是,在可执行程序中已经具备了所有执行程序所需要的任何东西,在执行的时候运行速度快。
为什么会出现动态链接
动态链接出现的原因就是为了解决静态链接中提到的两个问题,一方面是空间浪费,另外一方面是更新困难。下面介绍一下如何解决这两个问题。

动态链接的原理
动态链接的基本思想是把程序按照模块拆分成各个相对独立部分,在程序运行时才将它们链接在一起形成一个完整的程序,而不是像静态链接一样把所有程序模块都链接成一个单独的可执行文件。下面简单介绍动态链接的过程

假设现在有两个程序program1.o和program2.o,这两者共用同一个库lib.o,假设首先运行程序program1,系统首先加载program1.o,当系统发现program1.o中用到了lib.o,即program1.o依赖于lib.o,那么系统接着加载lib.o,如果program1.o和lib.o还依赖于其他目标文件,则依次全部加载到内存中。当program2运行时,同样的加载program2.o,然后发现program2.o依赖于lib.o,但是此时lib.o已经存在于内存中,这个时候就不再进行重新加载,而是将内存中已经存在的lib.o映射到program2的虚拟地址空间中,从而进行链接(这个链接过程和静态链接类似)形成可执行程序。

设计一个分布式的图片处理系统

50台机器 怎么设计 使得处理速度最快 一致性哈希

答了 一致性哈希的方式 把图片交给虚拟节点处理 然后 虚拟节点分配机器

如果机器的算力不同,比如cpu核数不同 如何让它均衡

答了由虚拟节点统计算力然后平均分配

每个机器的空闲状态是动态变化的 如果由虚拟节点统计 空闲状态 是没有时效性的:自己申请作业

每个机器的空闲状态是动态变化的 如果由虚拟节点统计 空闲状态 是没有时效性的,而且 计算算力的方式比较复杂 有没有简单的方式
让每个机器自己根据是否空闲来申请作业
又问了 如果有的机器 处理图片速度特别快 但是网络通讯的消耗特别大 怎么办

TCP丢包如何判断

乱序和丢包对接收端看是一样的,是为丢包空洞和乱序空洞,其中,乱序空洞是一种可以靠时间来弥补的空洞,而丢包空洞只能重传数据包来弥补。

连续分组序号的最后一号出现三次,才算一次丢包,表明其下一组丢失.

阻塞IO

阻塞I/O模型
最广泛的模型是阻塞I/O模型,默认情况下,所有套接口都是阻塞的。 进程调用recvfrom系统调用,整个过程是阻塞的,直到数据复制到进程缓冲区时才返回(当然,系统调用被中断也会返回)。

非阻塞I/O模型, IO轮询

当我们把一个套接口设置为非阻塞时,就是在告诉内核,当**请求的I/O操作无法完成时,不要将进程睡眠,而是返回一个错误。**当数据没有准备好时,内核立即返回EWOULDBLOCK错误,第四次调用系统调用时,数据已经存在,这时将数据复制到进程缓冲区中。这其中有一个操作时轮询(polling)

IO复用

1、阻塞 I/O 只能阻塞一个 I/O 操作,而 I/O 复用模型能够阻塞多个 I/O 操作,所以才叫做多路复用

2、采用epoll模型时创建了一个共享的内存空间,操作系统采用事件通知的方式,使一个进程能同时等待多个文件描述符

3、这样就可以同时监听多个网络连接 IO, 相对于多进程、多线程切换的开销问题,IO 多路复用可以极大的提升系统效率。

IO复用为什么比非阻塞效率高

非阻塞IO ,IO请求时加上O_NONBLOCK一类的标志位,立刻返回,IO没有就绪会返回错误,需要请求进程主动轮询不断发IO请求直到返回正确。IO复用同非阻塞IO本质一样,不过利用了新的select系统调用,由内核来负责本来是请求进程该做的轮询操作。看似比非阻塞IO还多了一个系统调用开销,不过因为可以支持多路IO,才算提高了效率

or 建索引 用UNION替换OR  用in来替换or

select loc_id , loc_desc , region from location where loc_id = 10   
union   
select loc_id , loc_desc , region  from location where region = "melbourne"   



select loc_id , loc desc , region from location where loc_id = 10 or region = "melbourne"  
低效: 
select…. from location where loc_id = 10 or loc_id = 20 or loc_id = 30 
高效 
select… from location where loc_in  in (10,20,30);

好文要顶 关注我 收藏该文  

DNS劫持

DNS劫持就是通过劫持了DNS服务器,通过某些手段取得某域名的解析记录控制权,进而修改此域名的解析结果,导致对该域名的访问由原IP地址转入到修改后的指定IP
DNS可以将域名映射为IP,并且知道了使用了多种缓存方案来减少DNS访问的压力。那么DNS一旦出错,很可能将域名解析到其他IP地址,这样我们也就无法正确访问网页(PS是不是有的时候发现开启不了网页但是qq等可以使用,很可能就是DNS搞鬼了哟)。

对于DNS劫持,可以采用使用国外免费公用的DNS服务器解决。例如OpenDNS(208.67.222.222)或GoogleDNS(8.8.8.8)。

用DNS服务器进行DDOS攻击

什么是DDOS,我们应该知道SYN Flood,是一种DoS(拒绝服务攻击)与DDOS(分布式拒绝服务攻击的方式),利用大量的伪造TCP请求让被攻击方资源榨干

HTTP定义

HTTP协议(HyperTextTransferProtocol,超文本传输协议)是用于从WWW服务器传输超文本到本地浏览器的传输协议。

HTTP 2.0 的出现,相比于 HTTP 1.x ,大幅度的提升了 web 性能。

HTTP 2.0 和 1.1 区别

后面我们将通过几个方面来说说HTTP 2.0 和 HTTP1.1 区别,并且和你解释下其中的原理。

区别一:多路复用

多路复用允许单一的 HTTP/2 连接同时发起多重的请求-响应消息。

HTTP2建立一个TCP连接,一个连接上面可以有任意多个流(stream),消息分割成一个或多个帧在流里面传输。帧传输过去以后,再进行重组,形成一个完整的请求或响应。这使得所有的请求或响应都无法阻塞。

区别二:首部压缩,  (静态字典,动态字典)用一个字符表示

为什么要压缩?在 HTTP/1 中,HTTP 请求和响应都是由「状态行、请求 / 响应头部、消息主体」三部分组成。一般而言,消息主体都会经过 gzip 压缩,或者本身传输的就是压缩过后的二进制文件(例如图片、音频),但状态行和头部却没有经过任何压缩,直接以纯文本传输

1.1而每个请求带的一些首部字段都是相同的,例如cookie、user-agent等。HTTP2为此采用HPACK压缩格式来压缩首部。头部压缩需要在浏览器和服务器端之间:

维护一份相同的静态字典,包含常见的头部名称,以及常见的头部名称和值的组合
维护一份相同的动态字典,可以动态的添加内容
通过静态Huffman编码对传输的首部字段进行编码

静态字典的作用有两个:

对于完全匹配的头部键值对,例如 “:method :GET”,可以直接使用一个字符表示;
对于头部名称可以匹配的键值对,例如 “cookie :xxxxxxx”,可以将名称使用一个字符表示。

同时,浏览器和服务端都可以向动态字典中添加键值对,之后这个键值对就可以使用一个字符表示了。需要注意的是,动**态字典上下文有关,需要为每个 HTTP/2 连接维护不同的字典。**在传输过程中使用,使用字符代替键值对大大减少传输的数据量。

区别三:二进制分帧层

在这里插入图片描述
HTTP2性能提升的核心就在于二进制分帧层。HTTP2是二进制协议,他采用二进制格式传输数据而不是1.x的文本格式。
1.1响应是文本格式,而2.0把响应划分成了两个帧,图中的HEADERS(首部)和DATA(消息负载) 是帧的类型。

流(Stream):已建立的TCP连接上的双向字节流,可以承载一个或多个消息。
消息(Message):一个完整的HTTP请求或响应,由一个或多个帧组成。特定消息的帧在同一个流上发送,这意味着一个HTTP请求或响应只能在一个流上发送。
帧(Frame):通信的基本单位。
一个TCP连接上可以有任意数量的流。

区别四:HTTP2支持服务器推送

http2.0的帧 信息分割为帧, 二进制编码为HEADER 帧 DATA帧

在二进制分帧层中, HTTP/2 会将所有传输的信息分割为帧(frame),并对它们采用二进制格式的编码 ,其中 首部信息会被封装到 HEADER frame,而相应的 Request Body 则封装到 DATA frame 里面。

HTTP1.0和HTTP1.1的区别

长连接(Persistent Connection)

   HTTP1.1支持长连接和请求的流水线处理,在一个TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟**,在HTTP1.1中默认开启长连接keep-alive**,一定程度上弥补了HTTP1.0每次请求都要创建连接的缺点。HTTP1.0需要使用keep-alive参数来告知服务器端要建立一个长连接。

节约带宽,断点续传, 先发header,返回100,继续发body

   HTTP1.0中存在一些浪费带宽的现象,例如客户端只是需要某个对象的一部分,而服务器却将整个对象送过来了,**并且不支持断点续传功能**。**HTTP1.1支持只发送header信息(不带任何body信息),如果服务器认为客户端有权限请求服务器,则返回100,客户端接收到100才开始把请求body发送到服务器**;如果返回401,客户端就可以不用发送请求body了节约了带宽。

HOST域 http1.1要求必须有host域支持同一物理服务器多个虚拟主在这里插入图片描述

,否则返回400
在HTTP1.0中认为每台服务器都绑定一个唯一的IP地址,因此,请求消息中的URL并没有传递主机名(hostname),HTTP1.0没有host域。随着虚拟主机技术的发展,在一台物理服务器上可以存在多个虚拟主机(Multi-homed Web Servers),并且它们共享一个IP地址。HTTP1.1的请求消息和响应消息都支持host域,且请求消息中如果没有host域会报告一个错误(400 Bad Request)。

缓存处理

   在HTTP1.0中主要使用header里的If-Modified-Since,Expires来做为缓存判断的标准,HTTP1.1则引入了更多的缓存控制策略例如Entity tag,If-Unmodified-Since, If-Match, If-None-Match等更多可供选择的缓存头来控制缓存策略。

错误通知的管理

   在HTTP1.1中新增了24个错误状态响应码,如409(Conflict)表示请求的资源与资源的当前状态发生冲突;410(Gone)表示服务器上的某个资源被永久性的删除。

HTTPS工作原理

首先服务端给客户端传输证书,这个证书就是公钥,只是包含了很多的信息,比如说证书的办法机构,证书的过期时间
客户端进行证书的解析,比如说验证办法机构,过期时间,如果发现没有任何问题,就生成一个随机值(私钥),然后用证书对这个私钥进行加密,并发送给服务端
服务端使用私钥将这个信息进行解密,得到客户端的私钥,然后客户端和服务端就可以通过这个私钥进行通信了
服务端将消息进行对称加密(简单来说就是讲消息和私钥进行混合,除非知道私钥否则服务进行解密),私钥正好只有客户端和服务端知道,所以信息就比较安全了
服务端将进行对称加密后的消息进行传送
客户端使用私钥进行信息的解密

对称加密非对称加密

在加密和解密时使用相同的密钥,或是使用两个可以简单地相互推算的密钥的加密方式就是对称密钥加密(Symmetric-key algorithm),简称对称加密。常见的对称加密算法有:AES、DES、3DES

非对称加密不同于对称加密,它有一对秘钥,一个称为公钥(publicKey) ,另一个称为私钥(privateKey),并且*只知道公钥是无法推算出私钥。*就和上面的例子中只知道邮箱位置却并不能打开邮箱是一个道理。常见的非对称加密算法有:RSA、DSA、ECC

这是因为对称加密主要的运算是位运算,速度非常快,如果使用硬件计算,速度会更快。以 AES 算法为例,如下图所示,其运算本质上来说就是位移和替换

但是非对称加密计算一般都比较复杂,比如 RSA,它里面涉及到大数乘法、大数模等等运算。其加解密可以用下面的公式来表示:

https 对称非对称结合

HTTPS
既然无法做到既安全又快速的加解密,那我们在实际使用时只能尽量达到一个动态的平衡。
因此我们在项目中通常会采用如下这种将两种加密算法结合在一起的使用方式:

首先随机生成单次请求加密密钥(clientAesKey,长度为 16 位,可以用 26 个字母和数字组成)
RSA 负责加密一个字符串(clientAesKey)、
AES 负责用这个字符串(clientAesKey)、明文加密为一个密文
解密时首先要用 RSA 获取这个字符串(clientAesKey)、然后再用 AES 解密密文

答案, HTTP+SSL, https先和SSL通信,再SSL和TCP通信

HTTPS即加密的HTTP,HTTPS并不是一个新协议,而是HTTP+SSL(TLS)。原本HTTP先和TCP(假定传输层是TCP协议)直接通信,而加了SSL后,就变成HTTP先和SSL通信,再由SSL和TCP通信,相当于SSL被嵌在了HTTP和TCP之间。

但由于公开密钥比共享密钥要慢,所以我们就需要综合一下他们两者的优缺点,使他们共同使用,而这也是HTTPS采用的加密方式**。在交换密钥阶段使用公开密钥加密方式,之后建立通信交换报文阶段则使用共享密钥加密方式**。

虚继承解决菱形继承问题,需要特定域来访问

在这里插入图片描述

可以看到,如果不利用域限定需要访问的函数,那么就会出现模糊调用的问题,但是貌似C++给了更好的方法,虚继承!

#include<bits/stdc++.h>
using namespace std;

class Base{
public:
    void fun(){
        cout<<"Base()"<<endl;
    }
};

class A:public Base{

};

class C:public Base{

};

class D:public A,public C{


};

int main(){
    D d;
    //d.fun(); 出错,返回request for member 'fun' is ambiguous
    d.A::fun();
    d.C::fun();
    return 0;
}

利用虚继承就可以解决菱形继承的问题,具体实现是:A和C中不再保存Base的具体内容,而是保存了一份偏移地址,所以在D调用fun()时,调用的就是Base的fun(),但对于A、C相同的变量名,D在调用时还是要利用域限定来处理。

#include<bits/stdc++.h>
using namespace std;

class Base{
public:
    int _base=1;
    void fun(){
        cout<<"Base()"<<endl;
    }
};

class A:virtual public Base{
public:
    int _base=2;
};

class C:virtual public Base{
public:
    int _base=3;
};

class D:public A,public C{

};

int main(){
    D d;
    d.fun();//Base()
    d.A::fun();//Base()
    d.C::fun();//Base()
    cout<<d.Base::_base<<endl;//1
    cout<<d.A::_base<<endl;//2
    cout<<d.C::_base<<endl;//3
    return 0;
}

DDOS(didos)攻击,半连接

客户端向服务端发送请求链接数据包,服务端向客户端发送确认数据包,客户端不向服务端发送确认数据包,服务器一直等待来自客户端的确认

DDos 预防:

1)限制同时打开SYN半链接的数目

2)缩短SYN半链接的Time out 时间

3)关闭不必要的服务

GeoHash算法

就是一种将经纬度转换成字符串的方法,并且使得在大部分情况下,字符串前缀匹配越多的距离越近

非阻塞IO、NIO为什么会快,我们为什么需要多线程

阻塞io工作方式:
1、尝试读取数据
2、如果数据没有准备完成(在web等工作环境下,经常出现此情况),重复步骤1
3、直到读取数据完成后,返回。

非阻塞io工作方式:
1、尝试读取数据
2、如果数据没有准备完成,返回失败。如果数据准备完毕,读取后返回。

多线程的好处在于异步,避免一个线程在等待其他资源时,cpu空闲
非阻塞IO本身也不会提高速度,只是他在一定程度上能够降低并发数,从而提高CPU效率

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值