web前端 美团 一面9.21
目录
1、自我介绍
2、TCP握手的过程
三次握手(Three-way Handshake),是指建立一个 TCP 连接时,需要客户端和服务器总共发送3个报文。三次握手的目的是连接服务器指定端口,建立 TCP 连接,并同步连接双方的序列号和确认号,交换 TCP 窗口大小信息。
- 第一次握手:
客户端将TCP报文标志位SYN置为1,随机产生一个序号值seq=J,保存在TCP首部的序列号(Sequence Number)字段里,指明客户端打算连接的服务器的端口,并将该数据包发送给服务器端,发送完毕后,客户端进入SYN_SENT状态,等待服务器端确认。 - 第二次握手:
服务器端收到数据包后由标志位SYN=1知道客户端请求建立连接,服务器端将TCP报文标志位SYN和ACK都置为1,ack=J+1,随机产生一个序号值seq=K,并将该数据包发送给客户端以确认连接请求,服务器端进入SYN_RCVD状态。 - 第三次握手:
客户端收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,并将该数据包发送给服务器端,服务器端检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,客户端和服务器端进入ESTABLISHED状态,完成三次握手,随后客户端与服务器端之间可以开始传输数据了。
注意:ack和ACK不是同一个概念:
小写的ack代表的是头部的确认号Acknowledge number, 缩写ack,是对上一个包的序号进行确认的号,ack=seq+1。
大写的ACK,则是我们上面说的TCP首部的标志位,用于标志的TCP包是否对上一个包进行了确认操作,如果确认了,则把ACK标志位设置成1。
3、HTTP1和HTTP2的区别联系
- HTTP1.1和HTTP1.0区别?(HTTP1.1特性?)
持久连接:重复使用TCP连接,减少了连接建立和关闭的开销(Connection: keep-alive/close)。
缓存控制:Cache-Control,Etag。 - HTTP1和HTTP2区别?(HTTP2.0特性?)
二进制分帧传输:HTTP1中的报文是文本格式;HTTP2把报文从小到大划分成帧,消息和数据流。其中帧是通信的基本单位,消息是一个完整的http请求或者响应,由帧组成,流是TCP连接中的一个双向虚拟通道,可以承载多个消息。
多路复用:HTTP1如果想实现并发多个请求,必须建立多个TCP连接,而且存在慢启动,队头阻塞,带宽竞争的问题;HTTP2基于二进制分帧,同域名下所有通信都在单个TCP连接上完成,一个连接可以承载多个双向数据流。不同帧之间可以以乱序发送,因为根据帧首部的流ID可以重新进行组装,从而实现单连接的请求并发。
报文头部压缩:请求可能会发送很多相同的请求头如Cookie,User-Agent,HTTP2.0会存在客户端和服务端,各维护一个表,相同的数据不做重复发送。
服务端推送:在客户端请求之前主动发送数据,加快页面响应速度。
可设置请求优先级。
HTTP建立连接的过程:
4、HTTP和HTTPS区别?
HTTPS=HTTP+加密+完整性+身份认证
● HTTP不需要证书;HTTPS需要证书
● HTTP是明文传输;HTTPS加密传输
● HTTP默认端口80;HTTPS默认端口443,连接方式不同
● HTTP无状态;HTTPS是由SSL+HTTP加密+身份认证的网络协议
5、HTTP状态码
● 200:OK
● 304:Not Modified
● 400:Bad Request 请求语法错误
● 401:Unauthorized 身份未验证
● 403:Forbidden 请求被拒绝
● 404:Not Found 资源不存在
● 500:Internal Server Error 服务器错误
6、浏览器内核和JavaScript引擎的关系
-
浏览器的内核是指支持浏览器运行的最核心的程序,分为两个部分的,一是渲染引擎,另一个是JS引擎。
-
渲染引擎在不同的浏览器中不是都相同的,兼容性也是从IE时代结束后能达到良好平衡。
所谓的浏览器内核就是指浏览器的排版引擎(layout engine),也叫浏览器引擎(browser engine)、页面渲染引擎(rendering engine)、样板引擎、模板引擎。
排版引擎决定了浏览器如何显示网页的内容以及页面的格式信息。不同的浏览器内核对网页编写语法的解释也有不同,因此同一网页在不同的内核的浏览器里的渲染(显示)效果也可能不同,这也是网页编写者需要在不同内核的浏览器中测试网页显示效果的原因。
渲染引擎包括有Html解释器、CSS解释器、布局Layout和JavaScript引擎。 -
为什么需要JavaScript引擎?
JavaScript是不能直接被计算机识别的,高级的编程语言都是需要转成最终的机器指令来执行的;
事实上编写的JavaScript无论交给浏览器或者Node环境执行,最后都是需要被CPU执行的,其它高级编程语言也一样。
但是CPU只认识自己的指令集,实际上是机器语言,才能被CPU所执行,所以需要JavaScript引擎将JavaScript代码翻译成CPU指令来执行。 -
常见的JS引擎:
SpiderMonkey:第一款JavaScript引擎,由Brendan Eich开发(也就是JavaScript作者)。
Chakra:微软开发,用于IE浏览器。
JavaScriptCore:WebKit中的JavaScript引擎,Apple公司开发,用于Safari浏览器。
V8:Google开发的强大JS引擎,也帮助Chrome从众多浏览器中脱颖而出,也是目前用得最多的JS引擎,用于Chrome浏览器。 -
浏览器内核和JavaScript引擎的关系
浏览器内核包含JavaScript引擎,因为每个不同的浏览器内核不一样,所以也就没有统一的叫法。
以WebKit浏览器内核为例,WebKit内核事实上由两部分组成的:
WebCore:负责HTML解析、布局、渲染等等相关的工作。
JavaScriptCore:解析、执行JavaScript代码。 -
浏览器内核是用来解析HTML,CSS,JavaScript代码的集合体,然后向我们展示页面内容的,JaveScript引擎是用来解析执行JavaScript代码的,它可以集成在浏览器上,也可以集成在任何C++环境上,Node正是集成了V8引擎,所以能在Node环境运行javaScript代码。
- 五大浏览器的内核(渲染引擎)和JS引擎:
浏览器 | 内核 | JS引擎 |
---|---|---|
IE | Trident | IE8及以下是JScript,IE9以上为Chakra |
Mozilla Firefox | Gecko | Monkey系列:SpiderMonkey(第一款JavaScript引擎)、Rhino、TraceMonkey、JaegerMonkey、WebKit、IonMonkey、OdinMonkey |
Safari | WebKit,由两部分组成,渲染引擎WebCore,JS引擎JavaScriptCore | JavaScriptCore,被改写为 SquirrelFish,升级版本为 QuirrelFish Extreme,也叫做 Nitro |
Chrome | Chromium,采用了WebKit中的WebCore渲染引擎,从13年发布的Chrome 28.0.1469.0版本开始,Chrome放弃Chromium引擎转而使用最新的Blink引擎,它是WebKit中WebCore的一个分支。 | V8 |
Opera | Blink(Opera 3.5-6.1版本使用的内核叫做Elektra。Opera 7.0及以后版本到Opera12.17的内核叫Presto,已废弃) | Linear A,用于Opera 4.0~6.1版本;Linear B,用于Opera 7.0~9.2版本;Futhark,用于Opera 9.5~10.2版本;Carakan,由Opera软件公司编写,自Opera10.50版本开始使用。 |
- 国产多核浏览器一般是一个内核采用Trident,然后再增加其他内核使用WebKit或者Blink。
7、二叉树遍历方式
四种主要的遍历思想为:
前序遍历:根结点 —> 左子树 —> 右子树
中序遍历:左子树—> 根结点 —> 右子树
后序遍历:左子树 —> 右子树 —> 根结点
层次遍历:只需按层次遍历即可
前序、中序、后序遍历属于深度优先遍历,
层次遍历属于广度优先遍历。
- 手撕中序遍历二叉树
struct BiTree{
int val;
struct BiTree *left, *right;
}//递归
void inOrderTraverse1(BiTree root) {
if (root != null) {
inOrderTraverse1(root.left);
cout<<root.val<<" ";
inOrderTraverse1(root.right);
}
}
//非递归
void inOrderTraverse2(BiTree *tree){
std::stack<BiTree> treeStack;
BiTree *p=tree;
while(p || !treeStack.empty()){
if(p){
treeStack.push(p);
p=p->left;
}
else{
p = treeStack.pop();
cout<<p->val<<endl;
p=p->right;
}
}
}
8、图的遍历方式
遍历定义:从已给的图中某一顶点出发,沿着一些边,访遍图中所有的顶点,且使每个顶点仅被访问一次,就叫做图的遍历。
遍历实质:找每个顶点的邻接点的过程。
图的遍历方式:深度优先搜索、广度优先搜索
9、排序算法
手撕快排
#include<bits/stdc++.h>
using namespace std;
void quickSort(int a[], int l, int r){
if(l<r){
int i=l, j=r;
int x=a[i];
while(i<j){
while(i<j && x<a[j]){
j--;
}
if(i<j){
a[i]=a[j];
i++;
}
while(i<j && x>a[i]){
i++;
}
if(i<j){
a[j]=a[i];
j--;
}
}
a[i]=x;
quickSort(a, l, i-1);
quickSort(a, i+1, r);
}
}
int main()
{
// int a[]={2,4,1,9,65,32,0};
// int n=7;
int n;
cin>>n;
int *a=new int [n];
for(int i=0;i<n;i++){
cin>>a[i];
}
quickSort(a,0,n-1);
for(int i=0;i<n;i++){
cout<<a[i]<<" ";
}
cout<<endl;
return 0;
}