tcp三次握手四次挥手
tcp是一种面向连接的、可靠的、基于字节流的传输层协议。
6个标志位
1、URG:紧急指针标志,当为1时表示紧急指针有效,为0则忽略紧急指针 2、ACK:确认序号标志,为1表示确认号有效,为0表示报文中不含有确认信息,确认号无效 3、PSH:push标志,当为1时就是让接收方收到该TCP报文的时候不进入缓冲区排队而是快速发给应用程序 4、RST:重置连接标志,当连接出现错误时可以重置,或者用于拒绝非法的报文段和连接请求 5、SYN:同步序号,用于建立连接过程 6、FIN:finish标志,用于释放连接
序号:Seq序号,占32位,用来标识从TCP源端向目的端发送的字节流,发起方发送数据时对此进行标记。
确认号:Ack序号,占32位,只有ACK标志位为1时,确认序号字段才有效,Ack=Seq+1。
三次握手:
握手之前客户端主动打开连接结束CLOSED阶段,被动打开的服务端结束CLOSED阶段进入LISTEN阶段。随后开始三次握手;
第一次握手:
客户端向服务端发送一段tcp报文,标记位为SYN,表示请求建立新连接,序号为Seq=X(X=1)随后客户端进入SYN-SENT阶段
第二次握手:
服务端接收到来自客户端发送的TCP报文之后结束LISTEN阶段,并返回一段TCP报文,其中,标志位为SYN和ACK,表示“确认客户端的报文Seq序号有效,服务器能正常接收客户端发送的数据,并同意创建新连接”(即告诉客户端,服务器收到了你的数据);序号为Seq=y;确认号为Ack=x+1,表示收到客户端的序号Seq并将其值加1作为自己确认号Ack的值;随后服务器端进入SYN-RCVD阶段。
第三次握手:
客户端接收到来自服务端的确认收到数据的TCP报文之后,明确了从客户端到服务端的数据传输是正常的,结束了SYN-RCVD阶段,并返回最后一段TCP报文,其中标志位为ACK,表示确认收到服务器端同意连接的信号,序号为Seq=x+1,表示收到服务器确认号Ack,并将其作为自己的序号值;确认号为Ack=y+1,表示收到服务器序号Seq,并将其加1作为自己的确认号Ack的值,随后客户端进入establishd阶段
服务器收到来自客户端的“确认收到服务器数据”的TCP报文之后,明确了从服务器到客户端的数据传输是正常的。结束SYN-SENT阶段,进入ESTABLISHED阶段。此后客户端和服务器端进行正常的数据传输。这就是“三次握手”的过程。
四次挥手:
四次挥手即TCP的连接释放(解除),连接的释放必须是一方主动释放,另一方被动释放
挥手之前主动释放连接的客户端结束ESTABLISHED阶段,随后开始四次挥手;
第一次挥手:
客户端释放连接,想服务端发送一段TCP报文,其中标记位为FIN,表示“请求释放连接“;
序号为Seq=U;
随后客户端进入FIN-WAIT-1阶段,即半关闭阶段。并且停止在客户端到服务器端方向上发送数据,但是客户端仍然能接收从服务器端传输过来的数据。
注意:这里不发送的是正常连接时传输的数据(非确认报文),而不是一切数据,所以客户端仍然能发送ACK确认报文。
第二次挥手:
服务器端接收到从客户端发出的TCP报文之后,确认了客户端想要释放连接,随后服务器端结束ESTABLISHED阶段,进入CLOSE-WAIT阶段(半关闭状态)并返回一段TCP报文,其中:
标记位为ACK,表示“接收到客户端发送的释放连接的请求”;
序号为Seq=V;
确认号为Ack=U+1,表示是在收到客户端报文的基础上,将其序号Seq值加1作为本段报文确认号Ack的值;
随后服务器端开始准备释放服务器端到客户端方向上的连接。
客户端收到从服务器端发出的TCP报文之后,确认了服务器收到了客户端发出的释放连接请求,随后客户端结束FIN-WAIT-1阶段,进入FIN-WAIT-2阶段
前"两次挥手"既让服务器端知道了客户端想要释放连接,也让客户端知道了服务器端了解了自己想要释放连接的请求。于是,可以确认关闭客户端到服务器端方向上的连接了
第三次挥手:
服务器端自从发出ACK确认报文之后,经过CLOSED-WAIT阶段,做好了释放服务器端到客户端方向上的连接准备,再次向客户端发出一段TCP报文,其中:
标记位为FIN,ACK,表示“已经准备好释放连接了”。注意:这里的ACK并不是确认收到服务器端报文的确认报文。
序号为Seq=W;
确认号为Ack=U+1;表示是在收到客户端报文的基础上,将其序号Seq值加1作为本段报文确认号Ack的值。
随后服务器端结束CLOSE-WAIT阶段,进入LAST-ACK阶段。并且停止在服务器端到客户端的方向上发送数据,但是服务器端仍然能够接收从客户端传输过来的数据。
第四次挥手:
客户端收到从服务器端发出的TCP报文,确认了服务器端已做好释放连接的准备,结束FIN-WAIT-2阶段,进入TIME-WAIT阶段,并向服务器端发送一段报文,其中:
标记位为ACK,表示“接收到服务器准备好释放连接的信号”。
序号为Seq=U+1;表示是在收到了服务器端报文的基础上,将其确认号Ack值作为本段报文序号的值。
确认号为Ack=W+1;表示是在收到了服务器端报文的基础上,将其序号Seq值作为本段报文确认号的值。
随后客户端开始在TIME-WAIT阶段等待2MSL
服务器端收到从客户端发出的TCP报文之后结束LAST-ACK阶段,进入CLOSED阶段。由此正式确认关闭服务器端到客户端方向上的连接。
客户端等待完2MSL之后,结束TIME-WAIT阶段,进入CLOSED阶段,由此完成“四次挥手”。
后“两次挥手”既让客户端知道了服务器端准备好释放连接了,也让服务器端知道了客户端了解了自己准备好释放连接了。于是,可以确认关闭服务器端到客户端方向上的连接了,由此完成“四次挥手”。
JavaScript
JavaScript的基本数据类型
基本数据类型:undefined、null、Boolean、number、string、symbol(基本数据类型的值直接存储在栈中)
引用数据类型:对象、数组、函数、日期(应用数据类型的数据存储在堆中,在栈中保存数据的引用地址,地址指向对应数据,方便快速查找到堆内存中的对象)
null和undefined的区别
null代表空对象,主要用作初始化
undefined未定义
==返回true ===返回false
javascript原型链
当访问一个对象属性时,如果这个对象内部不存在这个属性,那么就会去他的原型对象里去找这个属性,而这个原型对象又会有自己的原型,所以就会一直找下去,这就是原型链的概念。原型链的尽头一般是 Object.prototype,然后Object.prototype.__proto _ _为null
instanceof的原理是什么?
instanceof是通过原型链去查找,找到某个对象的原型对象,使用原型对象的constructor找到构造函数,看看构造函数与instanceof后面的是否相同,不相同则继续向上查找,找到为true,未找到为false
JavaScript中什么是闭包
闭包是指有权访问另一个函数作用域中的变量的函数,创建闭包常见的方式是在一个函数内创建另一个函数,创建的函数可以访问到当前函数的局部变量
应用场景:构造函数的私有性
函数节流、防抖
函数节流是什么?
节流是指在一段时间内只允许函数执行一次。一般采用定时器实现节流。
防抖是什么?
防抖的作用是,一个事件回调函数在一段时间后才执行,如果在这段时间内再次回调则重新计时。
new关键字做了什么?
1.创建了一个新对象
2.设置原型链
3.让函数的this指向这个对象,执行构造函数的代码
4.返回值
####
vue.js
对MVVM的理解?
MVVM模式 model(数据模型,负责数据存储、泛指后端进行的各种业务逻辑和数据操控,主要围绕数据库系统展开),view (负责页面展示,用户界面,主要有HTML和css来构建),viewmodel(负责业务逻辑处理,对数据进行处理后交给视图展示)
MVVM优点:低耦合,可重用性,前后端分离
vue生命周期
-
beforecreate(创建前):组件的实例被创建之初,组件的属性生效之前(beforecreate生命周期执行的时候,data和methods中的数据都还没有初始化,不能在这个阶段使用data中的数据和methods中的方法)
-
create(创建后):组件的实例已经完全创建,属性也绑定,但真实dom还没生成,$el还不可用(data 和 methods都已经被初始化好了,如果要调用 methods 中的方法,或者操作 data 中的数据,最早可以在这个阶段中操作)
-
beforemount(挂载前):在挂载开始之前被调用,相关的render函数首次被调用(执行到这个钩子的时候,在内存中已经编译好了模板了,但是还没有挂载到页面中,此时,页面还是旧的)
-
mounted(挂载后):在el被新创建的vm.$el替换,并挂载到实例之后调用该钩子函数(到mounted周期的时候,Vue实例已经初始化完成了。此时组件脱离了创建阶段,进入到了运行阶段。 如果我们想要通过插件操作页面上的DOM节点,最早可以在和这个阶段中进行)
-
beforeupdate(更新前):组件数据更新之前调用,真实dom还没被渲染(当执行这个钩子时,页面中的显示的数据还是旧的,data中的数据是更新后的,页面还没有和最新的数据保持同步)
-
update(更新后):组价数据更新之后(页面显示的数据和data中的数据已经保持同步了,都是最新的)
-
beforedestory(销毁前):组件销毁前调用(Vue实例从运行阶段进入到了销毁阶段,这个时候上所有的 data 和 methods , 指令, 过滤器 ……都是处于可用状态。还没有真正被销毁)
-
destory(销毁后):组件销毁前调用(这个时候上所有的 data 和 methods , 指令, 过滤器 ……都是处于不可用状态。组件已经被销毁了。)
vue子组件和父组件的执行顺序
-
加载渲染过程:beforeCreate(父) —> created(父)—>beforeMount(父)—>beforeCreate(子)—>created(子)—>beforeMount(子)—>mounted(子)—>mounted(父)
-
更新过程:beforeUpdate(父) —> beforeUpdate(子) —> update(子) —> update(父)
-
父组件更新:beforeUpdate(父) —> updated(父)
-
销毁过程:beforeDestory(父) —> beforeDestory(子) —> destoryed(子) —> destoryed(父)
Vue的el属性和$mount优先级?
el的优先级是高于$mount的,因此以el挂载节点为准
vue实现数据双向绑定的原理
通过object.defineProperty()来劫持各个属性的setter和getter,在数据变动时发布消息给订阅者,触发相应的监听回调。
vue组件间的参数传递
-
父组件传给子组件:子组件通过props方法接受数据
-
子组件传给父组件:$emit方法传递参数
-
兄弟组件传值借用eventBus,,就是创建一个事件中心,相当于中转站,可以用它来传递事件和接收事件。发送数据使用 $emit方法,使用 $on 接收
-
隔代传值使用$provide和$inject
Compute和watch区别和应用场景
computehd(): //计算属性中的属性不需要在data中定义,而且必须有return data(){ return{ firstname:"张", lastname:"三" } } computehd(){ fullname(){ return this.firstname+this.lastname } } /*计算属性具有缓存,计算属性是基于它们的依赖进行缓存的,只有在它的相关依赖发生改变时才会重新求值。 只要计算属性的依赖没有改变,那么调用它就会直接返回之前的缓存。 同时computed对于其中变量的依赖时多个 的时候,只要其中一个发生了变化都会触发这个函数*/ //应用场景:当一个变量的值受多个变量的值影响 watch: //监听器watch中的值需要在data中定义,且函数有参数,newval和oldval data: { firstName: '张', lastName: '三', fullName: '张三r' }, watch: { firstName: function (oval,nval) { this.fullName = nval + ' ' + this.lastName }, lastName: function (oval,nval) { this.fullName = this.firstName + ' ' + nval }, immediate: true,// 代表在wacth里声明了firstName之后立即先去执行其函数方法 deep: true //深度监听 } //watch的依赖是单个的,它每次只可以对一个变量进行监控,并且区别于computed属性,监听器watch可以是异步的而computed则不行 //应用场景:当一个变量的值影响着多个变量的值
vuex
状态管理模式,采用集中式存储所有组件的状态,解决多组件数据通信
五个属性:
state:
vue的状态管理,驱动应用的数据源
mutations:
同步操作,可以直接更改state状态
actions:
异步操作,不能直接改变state而是需要触发mutations来更改state
getters:
计算属性,类似于vue组件中的computed
modules:
模块,支持模块化,让每个模块都有自己的state,mutation,action,getter,甚至可以嵌套子模块