前端汇总
-
- 计算机网络与浏览器
-
-
- 每日训练
- 1. 计算机网络体系结构分层
- 2. TCP/IP
- 3. 传输层中的TCP与UDP
- 3. HTTP123的区别
- 4. HTTP9种请求方法
- 5. GET 与 POST的区别
- 6. 5种状态码
- 7. 常见请求头
- 8.HTTP
- 9.HTTPS
- 9.三次握手与四次挥手
- 8.TCP/IP如何保证数据包传输的有序可靠
- 9.跨域
- 10 Cookie 、seesionStorage、localStorage、indexDB的区别
- 11.粘包及其解决策略
- 12. 键入网址到网页显示。期间发生了什么?
- 13.进程、线程和协程
- 14.node事件循环
- 15.XSS(安全系列)
- 16.CSRF(安全系列)
- 17. 点击劫持
- 18. 中间人攻击
- 19.URL、href、src
- 20.对称加密与非对称加密(https采用的是对称加密还是非对称加密?说说加密过程)
- 21.ADSL
-
- 操作系统
- CSS
-
-
- 每日训练
- 1. 外边距折叠(塌陷)
- 2. BFC块格式化上下文
- 3. BFC创建的条件
- 4.CSS的单位
- 5.display:none 与visibility:hidden的区别(使元素消失的方法)
- 6.盒模型?如何改变盒模型的尺寸
- 7.页面引入样式时,@import与link的区别
- 8.如何区分伪类伪元素?常见的伪类元素有哪些?
- 9.媒体查询media
- 10. CSS样式选择器及其优先级
- 12.多文本溢出省略截断
- 13.css中的height属性可以被继承吗?还有哪些可以继承?哪些不可以继承?
- 14. 使用纯div+css布局有什么好处
- 15.CSS样式的匹配顺序
- 16.position有哪些值?代表什么?
- 17.清除浮动
- 18.可替换元素
- 19.行内元素、行内块元素、块元素
- 20.sass与lessCSS预处理语言的优缺点
- 21.水平居中:
- 22. 垂直居中:
- 23.隐藏页面中某个元素的方法
- 24.页面自适应
- 25.flex布局
- 26.CSS3新特性
- 27. img中alt和title的区别
- 28.transition与animation的区别
- 29.雪碧图(精灵图)
- 30.移动端适配
- 31.超出隐藏并显示省略号
- 32.伪类的使用
- 33.CSS的长度单位
-
- JavaScript基础知识
-
-
- 每日训练
- 1. == 与 === 的区别
- 2. ==宽松相等
- 8. 数组常用操作方法:
- 9. JSON常用方法
- 10. for,forEach,for…in…, for…of…,map,some,every,filter、flat的区别
- 11. 闭包
- 12. constructor与prototype
- 13. 进程与线程
- 14. 事件循环
- 15. call、apply、bind的异同
- 16. new 一个对象后发生了什么
- 17. 连续多次输出bind
- 18.深拷贝与浅拷贝
- 19.js能改变数组自身的方法
- 20. RegExp 对象
- 21.继承
- 22.this的指向
- 23.type of 与instance of
- 24.如何理解原型链与原型
- 25.作用域
- 26.valueOf与toString
- 27. html中使用的特殊字符
- 28 .让网页中代码自动运行的方式
- 29.变量的定义的规范
- 30. 获取元素的方法
- 31.includes与indexOf的区别?
-
- Vue
-
-
- 每日训练
- 1. 生命周期
- 2. v-show 与v-if
- 3. v-if 与v-for哪个优先级更高
- 4. vue组件间怎么通信
- 5.vue-router的两种工作模式)
- 6. vue.js的两个核心
- 7. vue响应式原理与双向数据绑定
- 8. Computed与Watch
- 9.Key的作用
- 10. Vue2中,vue父组件的mouted与子组件的mouted哪个先执行?
- 10.vue中属性的执行顺序,data先还是methods先?
- 11.keepalive?
- 12.route与router?
- 13.路由守卫
- 14.nextTick
- 15.Ngnix
- 16.Vue低层实现原理
- 17.自定义指令
- 18.谈谈虚拟DOM
- 19.diff算法
- 19.自定义事件
- 20.MVVM
- 21.双向数据绑定
-
- ES6+
- 浏览器与性能及优化
-
-
- 1. 重绘与回流
- 2. 前端性能优化
- 3.节流与防抖
- 4. TDK?如何SEO?
- 5. 虚拟列表
- 6. https 页面访问http 资源报错
- 7. FOUC?如何避免?
- 8. 常见的设计模式
- 9.从浏览器输入url到页面结束响应的具体过程?js是否会阻塞文档渲染?
- 10.浏览器渲染引擎工作原理
- 11.插入几万个DOM,如何实现页面不卡顿
- 12.浏览器缓存机制
- 13. cookie与localStorage或sessionStorage的token对比?(有争议的回答:个人理解为身份验证方式cookie与jwt验证的token对比)
- 14.垃圾回收机制
- 15.浏览器事件机制
- 16.页面跳转以及js打开新窗口
- 17. css优化
-
- HTML
- GIS相关
- ==代码题==
- ==项目与职业规划==
计算机网络与浏览器
每日训练
- 计算机互联的主要目的是资源共享与数据通信
- ATM可以用于广域网,也可以用于局域网,一般用于广域网比较多。ATM的原理是采用面向连接的传输方式,将数据分割成固定长度的信元,通过虚连接进行交换,ATM的原理和以太网的原理是不一样的
- TCP 的服务器程序必须先于其客户程序运行
- 常见的网络操作系统:Windows类、NetWare类、Unix系统、Linux
- IP子网划分:
- B类地址有16位是主机号的位数
》子网内的主机数:2^x-2(x是主机号的位数)
》减去的两个一个是主机号全是0的网络地址,一个是全是1的广播地址
》网络地址+1是第一个主机地址,广播地址减一是最后一个主机地址
- 以太网的表示:
- TCP面向连接的传输模式,没有传输数据等,故使用ping时不需要使用TCP
计算机网络相关详解 - JS操作cookie:
document.cookie
1. 计算机网络体系结构分层
- 检测两部主机间的信道是否畅通:ping命令
- 是当ping不通的时候,也可能是因为时延太长,不一定是网络不通
- ping工作在应用层,它直接使用网络层的ICMP协议,而没有使用传输层的TCP/UDP协议
- 链路的传输效率
香农定理给出了带宽受限且有高斯白噪声干扰的信道的极限数据传输速率。香农定理:信道的极限数据传输速率=Wlog2(1+S/N),单位b/s。其中,S/N为信噪比,即信号的平均功率和噪声的平均功率之比,W为频率带宽
2. TCP/IP
- TCP/IP:为使用互联网而开发定制的协议族,一般称为网际协议群
- TCP:为应用程序之间的通信。确保数据以正确的顺序到达,并且确认数据包的内容没有改变
- IP:计算机之间的通信
- 二者联系:TCP 负责将数据分割并装入 IP 包,IP 负责将包发送至接受者。IP协议仅仅是允许计算机相互发消息,但它并不检查消息是否以发送的次序到达而且没有损坏(只检查关键的头数据)。为了提供消息检验功能,直接在IP协议上设计了传输控制协议TCP。
- 一般使用IP地址给设备编号,对于常用的Ipv4协议,IP地址共分为32位,分成了四段。IP地址有两种意义,一个是网络号,负责识别该IP是属于哪个子网的,一个是主机号,负责标识同一子网下的不同主机,如何区别网络号与主机号,需要借助子网掩码,一般做法是将子网掩码取反(返回到二进制)后与IP地址进行按位与运算
- 数据包:全能性术语
- 帧:表示数据链路层中包的单位
- 数据包:IP与UDP等网络层以上的分层中包的单位
- 段:TCP中数据流的信息
- 消息:指应用协议中数据的单位
3. 传输层中的TCP与UDP
- DUP:
- 不控制:UDP 不提供复杂的控制机制,利用 IP 提供面向无连接的通信服务
- 不能进行流量控制避免网络拥堵:并且它是将应用程序发来的数据在收到的那一刻,立即按照原样发送到网络上的一种机制。即使是出现网络拥堵的情况,UDP 也无法进行流量控制等避免网络拥塞行为
- 丢包:出现丢包,不负责重发
- 不能纠正包的到达顺序:包的到达顺序出现乱序时没有纠正的功能
适用情况:
》包总量较少的通信(DNS、SNMP等)
》即时的通信,例如.视频、音频等多媒体通信
》限定于LAN等特定网络中的通信
》广播通信,例如广播、多播
- TCP
- 数据传输时进行控制,面向有连接的协议
- 丢包重发(确认号)
- 对次序乱掉的分包进行顺序控制(序列号)
- 控制通信流量:作为一种面向有连接的协议,只有在确认通信对端存在时才会发送数据,从而控制通信流量的而浪费
3. HTTP123的区别
4. HTTP9种请求方法
- GET:获取URL指定的资源
- POST:传输实体信息
- PUT:上传文件,更新某个较为完整的资源
- Options:返回服务器支持的请求方法;
- HEAD:向服务器索要与GET请求一致的响应,只是不返回(只返回响应报文的首部);
- ;DELETE:删除文件
- TRACE:追踪请求的路径
- CONNECT:要求在与代理服务器通信时建立隧道,使用隧道进行TCP通信。主要使用SSL和TLS将数据加密后通过网络隧道进行传输
- PATCH:资源的部分内容的更新
5. GET 与 POST的区别
共同点:底层都是基于 TCP/IP 实现的
- get请求
- 用于获取数据
- 参数传递:默认将参数拼接到url上,发送给服务器
- 参数限制:因请求参数通过url传递,url长度有限,所以参数大小与长度有限制
- 回退与刷新:GET 请求可以直接进行回退和刷新,不会对用户和程序产生任何影响
- 缓存(历史记录):get请求一般会被缓存
- 书签:get请求地址能被收藏为书签
- 安全性:低
- post请求
- 用于发送数据,对数据进行增删改
- 参数传递:参数放在请求体中,发送给服务器
- 参数限制:参数放置在请求体中,无限制
- 回退与刷新:POST 请求回滚和刷新将会把数据再次提交
- 缓存(历史记录):一般不会缓存
- 书签:post请求地址不能被收藏为书签
- 安全性:高
6. 5种状态码
- 1xx
- 2xx表示请求处理成功,
200 OK 请求处理成功
204 No Content ,表示请求处理成功,但没有资源可返回
206 Partial Content ,该状态码表示客户端进行了范围请求,而服务器成功执行了这部分的GET 请求。响应报文中包含由 Content-Range 指定范围的实体内容。 - 3XX 重定向
301 Moved Permanently ,永久性重定向。表示请求的资源已被分配了新的 URL,以后应使用资源现在所指的 URL。
302 Found ,临时性重定向。表示请求的资源已被分配了新的 URI,希望用户(本次)能使用新的 URI 访问。
303 See Other ,表示由于请求对应的资源存在着另一个 URI,应使用 GET 方法定向获取请求的资源
304 Not Modified,表示请求已经找到,但是不返回请求资源,因为不符合发送请求时的条件(一般为协商缓存时会出现改状态码)
307 Temporary Redirect ,临时重定向。该状态码与 302 Found 有着相同的含义。尽管 302 标准禁止 POST 变换成 GET,但实际使用时大家并不遵守
(4) 4xx 请求失败(问题集中于客户端)
400 Bad Request ,表示请求报文中存在语法错误。当错误发生时,需修改请求的内容后再次发送请求。另外,浏览器会像 200 OK 一样对待该状态码。
401 Unauthorized ,该状态码表示发送的请求需要有通过 HTTP 认证(BASIC 认证、DIGEST 认证)的认证信息。另外若之前已进行过 1 次请求,则表示用户认证失败。
403 Forbidden ,该状态码表明对请求资源的访问被服务器拒绝了,例如未获得访问文件系统的授权
404 表明服务器上无法找到请求的资源,也可以做服务器拒绝请求的理由
405 表明 客户端请求的方法虽然能被服务器识别,但是服务器禁止使用该方法
(5) 5xx (服务器执行请求时产生错误)
500 Internal Server Error,表明服务器端在执行请求时发生了错误
503 Service Unavailable,表明服务器暂时处于超负载或正在进行停机维护,现在无法处理请求
7. 常见请求头
8.HTTP
- http:是一个客户端和服务器端请求和应答的标准(TCP),用于从 WWW 服务器传输超文本到本地浏览器的超文本传输协议。不仅保证计算机快速正确的传输超文本文档,还确定传输文档中的哪一部分,以及哪部分内容首先显示。
- 协议基础:
- 客户端发起请求,服务器端响应
- 无状态的协议:http为一种无状态的协议,协议自身不对请求和响应之间的通信状态进行保存。
- Cookie 管理状态:在请求和响应报文中写入 Cookie 信息来控制客户端的状态。客户端会根据从服务器端发送的响应报文内的一个叫做 Set-Cookie 的首部字段信息,保存服务器端的Cookie;当客户端再次发送请求时,会在请求报文中将Cookie加入并发送到服务器端,服务器端再检查Cookie列表中的信息去判断。
- URL定位资源: HTTP 协议使用 URI 定位互联网上的资源。正是因为 URI 的特定功能,在互联网上任意位置的资源都能访问到。
- 持久连接:HTTP 协议的初始版本中,每进行一个 HTTP 通信都要断开一次 TCP 连接。(HTTP/1.1 和部分 HTTP/1.0 想出了持久连接的方法)。只要任意一端没有明确提出断开连接,则保持 TCP 连接状态。旨在建立一次 TCP 连接后进行多次请求和响应的交互。在 HTTP/1.1 中,所有的连接默认都是持久连接。
- 管线化:持久连接使得多数请求以管线化方式发送成为可能,做到同时并行发送多个请求,而不需要一个接一个地等待响应了。
- HTTP协议工作的过程:
- 地址解析:对请求的页面URL进行解析,从中分析出协议名、端口号、主机名、对象路径等部分,此步需要DNS域名系统解析域名,得主机的IP地址
- 封装HTTP请求数据包:将以上解析的数据+本机的信息,封装成一个HTTP请求数据包
- 封装成TCP包,建立TCP连接:在HTTP正式工作前,客户端需要通过网络与服务器建立连接,该连接通过TCP连接构成,TCP协议与IP协议共同构建Internet,即著名的TCP/IP协议族,因此Internet又被称作是TCP/IP网络
- 客户端向服务器端发送请求命令:TCP连接后,客户机发送一个请求给服务器,请求方式的格式为:统一资源标识符(URL)、协议版本号,后边是MIME信息包括请求修饰符、客户机信息和可内容
- 服务器响应:服务器接到请求后,给予相应的响应信息,其格式为一个状态行,包括信息的协议版本号、一个成功或错误的代码,后边是MIME信息包括服务器信息、实体信息和可能的内容
- 服务器关闭TCP连接:一般情况下,一旦服务器向客户端返回了请求数据,它就要关闭 TCP 连接,然后如果客户端或者服务器在其头信息加入了这行代码 Connection:keep-alive ,TCP 连接在发送后将仍然保持打开状态。也就是HTTP1.1的持久连接
- 缺点:
- 通信使用明文,容易被窃听
- 不验证通信方的身份,可能遭遇伪装
- 无法证明报文的完整性,有可能遭遇篡改
9.HTTPS
- HTTPS:超文本安全传输协议。经由HTTP进行通信,但利用SSL/TSL进行数据包加密。
- 目的:提供对网站服务器的身份认证,保证交换数据的隐私与完整性。解决了http面临的信息窃听,信息篡改,信息劫持的缺点
- 信息加密===>信息窃听
- 完整性校验===>信息篡改
- 身份验证===>信息伪装、劫持
- 作用:
- 建立一个信息安全通道,来确保传输过程中的数据安全
- 对网站服务器进行真实身份认证
- HTTPS协议工作过程(此过程存在问题):
- 客户端使用 https url 访问服务器,则要求 web 服务器建立 ssl 链接。
- web 服务器接收到客户端的请求之后,会将网站的证书(证书中包含了公钥与数字签名),传输给客户端。
- 客户端和 web 服务器端开始协商 SSL 链接的安全等级,也就是加密等级。客户端浏览器通过双方协商一致的安全等级,建立会话密钥,然后通过网站的公钥来加密会话密钥,并传送给网站。
- web 服务器通过自己的私钥解密出会话密钥。
- web 服务器通过会话密钥(客户端的私钥)加密与客户端之间的通信,进行真正的数据传输。
- 原理:
- 客户端向服务器端索要并验证公钥。这一阶段使用的是非对称加密传输(RSA),服务端将数字证书发给客户端.其中数字证书包括:公钥和数字签名.客户端在拿到后对两者进行校验.
- 在非对称加密传输中,两端协商生成"对话密钥"。
- 双方采用"对话密钥"进行对称加密通信
7.HTTP与HTTPS对比
- 安全性: http 是超文本传输协议,信息是明文传输,HTTPS 协议要比 http 协议安全,https 是具有安全性的 ssl 加密传输协议,可防止数据在传输过程中被窃取、篡改,劫持
- 端口号:http 协议的默认端口为 80,https 的默认端口为 443
- 连接:http 的连接很简单,是无状态的。https 握手阶段比较费时,会使页面加载时间延长 50%,增加 10%~20%的耗电(CDN接入、硬件加速、远程解密)
- 缓存:https 缓存不如 http 高效,会增加数据开销。(会话缓存)
- 证书:Https 协议需要 ca 证书,费用较高,功能越强大的证书费用越高
- SSL 证书需要绑定 IP,不能再同一个 IP 上绑定多个域名
9.三次握手与四次挥手
三次握手
TCP提供面向有连接的通信传输。面向有连接是指在数据通信开始之前做好两端之间的准备工作。
三次握手:是指建立一个TCP连接连接时需要客户端和服务器端总共发送三个包以确认连接的存在。传送的包里不包含数据,三次握手完毕后,客户端与服务器才正式开始传送数据
- 第一次握手:建立连接时,客户端将标志位SYN置为1,并随机产生一个序列号seq=j,将包含SYN与seq的数据包发送到服务器,并进入SYN_SENT状态,等待服务器确认。
- 第二次握手:服务器收到数据包并确认客户的SYN=1知道客户端请求连接,服务器端将标志位SYN与ACK都置为1,并随机产生一个自己的序列号seq = k,同时将确认号字段(ack)填上j+1,将数据包(即SYN+ACK+seq+ack)包发送给客户端以确认连接请求,服务端进入SYN_RECV状态;
- 第三次握手:客户端收到服务器的数据包,检查ack是否为j+1, ACK是否为1,如果正确则将标志位ACK置为1,将确认号字段(ack)填为k+1, 将数据包发送给服务器端;服务器端检查ack是否为k+1,ACK是否为1,如果是则连接成功,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,客户端与服务器端可以传输数据了。
四次挥手**:
四次挥手:即终止TCP连接,当断开一个TCP连接时,需要客户端与服务器端总共发送4个包以确认连接的断开。TCP是双全工的,所以每个方向上都要进行单独关闭。
(中断连接端可以是客户端,也可以是服务器端)
一方主动关闭,一方被动关闭
- 首先客户端想要释放连接,将标志位FIN置为m(即将标志位FIN点亮),将该报文发送个服务器端,随后客户端进入FIN-WAIT-1阶段,即半关闭阶段。并且停止在客户端到服务器端方向上发送数据(ACK确认报文),但是客户端仍然能接收从服务器端传输过来的数据。
- 服务器端接收到从客户端发出的FIN后,确认了客户端想要释放连接,发送确认号字段ack=m+1给客户端,告诉客户端对方想要释放连接的请求已经收到,随后服务器端结束ESTABLISHED阶段,进入CLOSE-WAIT阶段(半关闭状态),客户端进入FIN -WAIT-2阶段
- 服务器端确定数据发送完成后,做好了释放服务器端到客户端方向上的连接准备,再次向客户端发出一段FIN =n 的报文。随后服务器端结束CLOSE-WAIT阶段,进入LAST-ACK阶段。并停止在服务器端到客户端的方向上发送数据,但是服务器端仍然能够接收从客户端传输过来的数据。
- 客户端收到从服务器端发出的FIN = n,确认了服务器端已做好释放连接的准备,但是其仍然不相信网络,怕服务器端并不知道要关闭,向服务器端发送确认字段ack=n+1与CK=1,随后结束FIN-WAIT-2阶段,进入TIME-WAIT阶段,如果server阶段没有收到ACK可以重传,服务器端收到ACK后,知道可以断开连接了。随后客户端等待2MSL没有收到回复,则证明服务器端已经正常关闭,进入closed状态,客户端也立即关闭连接。
同时主动关闭
8.TCP/IP如何保证数据包传输的有序可靠
对**字节流分段并进行编号(生成序列号),**然后通过 ACK 回复和超时重发这两个机制来保证。
ACK确认应答回复
- 为了保证数据包的可靠传递,发送方必须把已发送的数据包保留在缓冲区;
- 并为每个已发送的数据包启动一个超时定时器;
- 如在定时器超时之前收到了对方发来的应答信息(可能是对本包的应答,也可以是对本包后续包的应答),则释放该数据包占用的缓冲区;
- 否则,发送方默认数据丢失,重传该数据包,直到收到应答或重传次数超过规定的最大次数为止。(到达规定的最大次数后还是没有收到确认应答返回,就会判断网络或接收端产生异常,强制关闭连接)
- 接收方收到数据包后,先进行CRC校验,如果正确则把数据交给上层协议,然后给发送方发送一个累计应答包,表明该数据已收到,如果接收方正好也有数据要发给发送方,应答包也可方在数据包中捎带过去。
序列号
- 序列号引入原因:发送方在定时器之前收不到接收方传来的应答消息不一定是丢包,也可能是其他原因导致应答延迟,所以单纯根据在规定时间内收到应答与否来进行包的重新发送是不可取的,因为这样接收端会接收到相同的数据,为了对上层应用提供可靠的传输,接收端应该放弃重复的数据包
- 序列号:
- 建立TCP连接时(在三次握手时),算出发送数据包的单位,称其为“最大消息长度”,TCP在传递大量数据时,以最大消息长度的大小将数据进行分割发送。
是按照顺序给发送数据的每一个字节(8位字节)都标上号码的编号
- 使用序列号:接收端查询接收数据 TCP 首部中的序列号和数据的长度,将自己下一步应该接收的序列号作为确认应答返送回去。通过序列号和确认应答号,TCP 能够识别是否已经接收数据,又能够判断是否需要接收,从而实现可靠传输
注:重发超时的确定
- 最理想的是,找到一个最小时间,它能保证“确认应答一定能在这个时间内返回”。
- TCP 要求不论处在何种网络环境下都要提供高性能通信,并且无论网络拥堵情况发生何种变化,都必须保持这一特性。为此,它在每次发包时都会计算往返时间及其偏差。将这个往返时间和偏差时间相加,重发超时的时间就是比这个总和要稍大一点的值
- Unix 以及 Windows 系统中,超时都以0.5秒为单位进行控制,因此重发超时都是0.5秒的整数倍。不过,最初其重发超时的默认值一般设置为6秒左右。
- 数据被重发之后若还是收不到确认应答,则进行再次发送。此时,等待确认应答的时间将会以2倍、4倍的指数函数延长
9.跨域
跨域:只要协议、域名、端口有任何一个不同,都被当作是不同的域,即跨域。是指浏览器不能执行其他网站的脚本,ajax请求会失败。它是由浏览器的同源策略造成的。(实际上请求已经发出去,但是浏览器拦截了响应)
同源策略:浏览器对 JavaScript 实施的安全限制,主要用来防止CSRF、XSS攻击,但不能完全阻止CSRF。协议、域名、端口都要相同。
解决方案:
- jsonp:
- 原理:动态创建一个script标签。利用script标签的src属性不受同源策略限制,因为所有的src属性和href属性都不受同源策略的限制,可以请求第三方服务器资源内容
- 缺点:因为 script 标签只能使用 get 请求,所以该方式也只能发送get请求; JSONP 需要后端配合返回指定格式的数据。
- CORS:跨域资源共享。CORS 需要浏览器和后端同时支持。浏览器会自动进行 CORS 通信,需要在服务器端设置对cors的支持,服务器设置Access-Control-Allow-Origin :* 响应头之后,浏览器将会允许跨域。( 该属性表示哪些域名可以访问资源,如果设置通配符则表示所有网站都可以访问资源)
- 代理服务器,给服务设置代理服务器(还有nginx反向代理)
- window.postMessage() :HTML5 XMLHttpRequest Level 2中的API,且是为数不多可以跨域操作的window属性之一。
- 使用场景:
》页面和其打开的新窗口的数据传递
》多窗口之间消息传递
》页面与嵌套的iframe消息传递
》上面三个场景的跨域数据传递 - 语法:
otherWindow.postMessage(message, targetOrigin, [transfer]);
/*
otherWindow :要给其发送消息的目标窗口的引用
message:具体的消息内容
targetOrigin:指定哪些窗口能接收到消息事件,可以指定接收消息的窗口的源
监听message事件来获取父窗口传递的消息,可以通过MessageEvent对象获取如下参数
MessageEvent.source:发送消息的窗口引用
MessageEvent.origin: 发送消息的来源origin
MessageEvent.data: 消息内容
*/
》message:将要发送到其他 window的数据
》targetOrigin:通过窗口的origin属性来指定哪些窗口能接收到消息事件,其值可以是字符串"*"(表示无限制)或者一个URI。在发送消息的时候,如果目标窗口的协议、主机地址或端口这三者的任意一项不匹配targetOrigin提供的值,那么消息就不会被发送;只有三者完全匹配,消息才会被发送。
》transfer(可选):是一串和message 同时传递的 Transferable 对象. 这些对象的所有权将被转移给消息的接收方,而发送一方将不再保有所有权。
示例:页面给其嵌套的iframe页面发消息并接受iframe页面返回的消息
// a.html
<iframe src="http://localhost:4000/b.html" frameborder="0" id="frame" onload="load()"></iframe> //等它加载完触发一个事件
//内嵌在http://localhost:3000/a.html
<script>
function load() {
let frame = document.getElementById('frame')
frame.contentWindow.postMessage('我爱你', 'http://localhost:4000') //发送数据
window.onmessage = function(e) {
//接受返回数据
console.log(e.data) //我不爱你
}
}
</script>
// b.html
window.onmessage = function(e) {
console.log(e.data) //我爱你
e.source.postMessage('我不爱你', e.origin)
}
- websocket:HTML5的一个持久化的协议,它实现了浏览器与服务器的全双工通信,同时也是跨域的一种解决方案.WebSocket和HTTP都是应用层协议,都基于 TCP 协议。但是 WebSocket 是一种双向通信协议,在建立连接之后,WebSocket 的 server 与 client 都能主动向对方发送或接收数.
- iframe :iframe + 相关属性进行跨域。
- **iframe + window.name:**主要利用name值在不同的页面(甚至是不同的域名)加载后依然存在,并且可以支持较长的name值。通过iframe的src属性由外域转向本地域,跨域数据即由iframe的window.name从外域传递到本地域。这个就巧妙地绕过了浏览器的跨域访问限制,但同时它又是安全操作
示例:通过与页面a同域的页面b来传递跨域页面c
// a.html(http://localhost:3000/b.html)
<iframe src="http://localhost:4000/c.html" frameborder="0" onload="load()" id="iframe"></iframe>
<script>
let first = true
// onload事件会触发2次,第1次加载跨域页,并留存数据于window.name
function load() {
if(first){
// 第1次onload(跨域页)成功后,切换到同域代理页面
let iframe = document.getElementById('iframe');
iframe.src = 'http://localhost:3000/b.html';
first = false;
}else{
// 第2次onload(同域b.html页)成功后,读取同域window.name中数据
console.log(iframe.contentWindow.name);
}
}
</script>
- iframe + location.hash: 不同页面间跨域通信,不同域之间利用iframe的hash值进行数据跨域传递,相同域之间直接js访问来通信。
示例 :a.html欲与c.html跨域相互通信,通过中间页b.html来实现。页面a给不同域的页面c传一个hash值,然后页面c收到hash值后,再把hash值传递给与页面a同域的页面b,最后页面b将结果放到页面a的hash值中,通过hash值实现跨域数据的传递。
// a.html
<iframe src="http://localhost:4000/c.html#iloveyou"></iframe>
<script>
window.onhashchange = function () {
//检测hash的变化
console.log(location.hash);
}
</script>
// b.html
<script>
window.parent.parent.location.hash = location.hash
//b.html将结果放到a.html的hash值中,b.html可通过parent.parent访问a.html页面
</script>
// c.html
console.log(location.hash);
let iframe = document.createElement('iframe');
iframe.src = 'http://localhost:3000/b.html#idontloveyou';
document.body.appendChild(iframe);
- iframe+document.domain:基础域名相同 子域名不同即只适用于二级域名相同的情况下。实现原理:两个页面都通过js强制设置document.domain二级域名,表示二级域名相同,即就实现了同域。
示例:
// a.html
<body>
helloa
<iframe src="http://b.zf1.cn:3000/b.html" frameborder="0" onload="load()" id="frame"></iframe>
<script>
document.domain = 'zf1.cn'
function load() {
console.log(frame.contentWindow.a);
}
</script>
</body>
// b.html
<body>
hellob
<script>
document.domain = 'zf1.cn'
var a = 100;
</script>
</body>
10 Cookie 、seesionStorage、localStorage、indexDB的区别
- 相同点:都存储在客户端,且同源
- 不同点:
- 数据大小:因为cookie始终在同源的http请求中携带,因此只适合保存很小的数据,cookie数据大小不能超过4k;sessionStorage和localStorage的存储比cookie大得多,可以达到5M+
- 路径限制:cookie数据具有路径概念,可以限制cookie只属于某个路径下
- 数据有效期:cookie设置的过期时间之前一直有效;localStorage永久存储,浏览器关闭后数据不丢失除非主动删除数据;sessionStorage数据在当前浏览器窗口关闭后自动删除;
- 数据传递:cookie的数据会自动的传递到服务器;sessionStorage和localStorage数据保存在本地
- 作用域:sessionStorage不在不同的浏览器窗口中共享,即使是同一个页面;localStorage 在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的。
indexDB:浏览器数据库,数据存储大小不限,数据有效期为一直有效除非手动删除,不参与数据传递;具有同源限制
**
cookie 的属性:
11.粘包及其解决策略
粘包:TCP粘包是指发送方发送的若干包数据到接收方接收时粘成一包,从接收缓冲区看,后一包数据的头紧接着前一包数据的尾。
12. 键入网址到网页显示。期间发生了什么?
- 浏览器解析URL:解析之后,浏览器确定了 web服务器与文件名,接下来便根根这些信息生成发送给 Web 服务器的请求信息。
- DNS真实地址查询:浏览器生成web请求信息后,需要委托操作系统将请求信息发送给服务器,在发送之前需要查询服务器域名对应的IP,而DNS服务器就是存储服务器域名与对应IP的服务器。
- DNS中,用.来分割域名,在域名中越往右靠,表示其层级越高
- DNS真实地址查询的大概流程:客户端发送DNS请求,询问解析出来的服务器域名的ip并将该服务器域名发送给本地DNS服务器,本地DNS服务器找到对应的IP地址后,将地址返回给客户端,至此客户端与目标建立连接
协议栈:DNS获取到IP后,将http的传输工作交给操作系统中的协议栈,主要为应用程序通过调用Socket库,委托协议栈来工作,协议栈内部分为几个部分,分别承担不同的工作
- 可靠传输-TCP:HTTP是基于TCP协议进行传输的
- 远程定位-IP:TCP 模块在执行连接、收发、断开等各阶段操作时,都需要委托 IP 模块将数据封装成网络包发送给通信对象
- 两点传输-MAC:生成了 IP 头部之后,接下来网络包还需要在 IP 头部的前面加上 MAC 头部,MAC 包头里需要发送方 MAC 地址和接收方目标 MAC 地址,用于两点之间的传输。
- 出口-网卡:网络包只是存放在内存中的一串二进制数字信息,没有办法直接发送给对方。因此,我们需要将数字信息转换为电信号,才能在网线上传输发送,也就是说,这才是真正的数据发送过程。负责执行这一操作的是网卡,控制网卡靠网卡驱动程序。
- 送别者-交换机:交换机将网络包原样转发到目的地。交换机工作在MAC层,亦称为二层网络设备。首先是在电信号到达网线接口,交换机里的模块进行接收,接下来交换机里的模块将电信号转换为数字信号。数据包通过交换机转发抵达了路由器。
- 出境大门 —— 路由器:网络包经过交换机后,到达路由器,并在此被转发到下一个路由与目标设备
- 服务器端响应:服务器端根据收到的数据包进行http请求响应
- 客户端响应:根据响应渲染页面并发起TCP四次挥手进行TCP连接断开。
13.进程、线程和协程
- 进程:一个具有一定独立功能的程序在一个数据集上的一次动态执行的过程,是操作系统进行资源分配和调度的一个独立单位,是应用程序运行的载体。进程是一种抽象的概念,从来没有统一的标准定义。
- 线程:程序执行中一个单一的顺序控制流程,是程序执行流的最小单元,是处理器调度和分派的基本单位。一个进程可以有一个或多个线程,各个线程之间共享程序的内存空间(也就是所在进程的内存空间)。一个标准的线程由线程ID、当前指令指针(PC)、寄存器和堆栈组成。而进程由内存空间(代码、数据、进程空间、打开的文件)和一个或多个线程组成。
- 协程:是一种基于线程之上,但又比线程更加轻量级的存在,这种由程序员自己写程序来管理的轻量级线程叫做『用户空间线程』,具有对内核来说不可见的特性。
- 二者联系:
(1)一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程;
(2)资源分配给进程,同一进程的所有线程共享该进程的所有资源;
(3)处理机分给线程,即真正在处理机上运行的是线程;
(4)线程在执行过程中,需要协作同步。不同进程的线程间要利用消息通信的办法实现同步
注:
- 互斥锁:关于线程之间共享内存,可以使用互斥锁(Mutex),防止多个线程同时读取某一块内存区域。
- 信号量:使用信号量,保证多个线程不会相互冲突(小于等于进程的线程容量)
14.node事件循环
- 事件循环机制分不同的阶段,在每个阶段都有一个 FIFO 队列来执行回调。通常情况下,当事件循环进入给定的阶段时,它将执行特定于该阶段的任何操作,然后执行该阶段队列中的回调,直到队列用尽或最大回调数已执行。
- node事件循环的阶段顺序是:输入数据阶段(incoming data)->轮询阶段(poll)->检查阶段(check)->关闭事件回调阶段(close callback)->定时器检测阶段(timers)->I/O事件回调阶段(I/O callbacks)->闲置阶段(idle, prepare)->轮询阶段…
- 轮询阶段(poll):检索新的 I/O 事件;执行与 I/O 相关的回调(几乎所有情况下,除了关闭的回调函数,那些由计时器和 setImmediate() 调度的之外),其余情况 node 将在适当的时候在此阻塞。
- setImmediate() 回调函数在这里执行
- 关闭事件回调阶段(close callback):一些关闭的回调函数,如:socket.on(‘close’, …)
- 本阶段执行 timer 的回调,即 setTimeout、setInterval 里面的回调函数
- I/O事件回调阶段(I/O callbacks):执行延迟到下一个循环迭代的 I/O 回调,即上一轮循环中未被执行的一些I/O回调。
更多node事件循环的介绍
15.XSS(安全系列)
- XSS定义:跨站脚本攻击,Cross-Site Scripting,是一种代码注入攻击。攻击者通过在目标网站上注入恶意脚本,使之在用户的浏览器上运行。利用这些恶意脚本,攻击者可获取用户的敏感信息如 Cookie、SessionID 等,进而危害数据安全。
以下为常见的注入方法
- 在 HTML 中内嵌的文本中,恶意内容以 script 标签形成注入。
- 在内联的 JavaScript 中,拼接的数据突破了原本的限制(字符串,变量,方法名等)。
- 在标签属性中,恶意内容包含引号,从而突破属性值的限制,注入其他属性或者标签。
- 在标签的 href、src 等属性中,包含 javascript: (伪协议)等可执行代码。
- 在 onload、onerror、onclick 等事件中,注入不受控制代码。
- 在 style 属性和标签中,包含类似 background-image:url(“javascript:…”); 的代码(新版本浏览器已经可以防范)。
- 在 style 属性和标签中,包含类似 expression(…) 的 CSS 表达式代码(新版本浏览器已经可以防范)。
- XSS攻击分类:存储型、反射型、DOM型
- 存储型XSS(也被称为持久型XSS):
》常见于带有用户保存数据的网站功能,如论坛发帖、商品评论、用户私信等。
》最危险的一种跨站脚本,相比反射型XSS和DOM型XSS具有更高的隐蔽性,所以危害更大,因为它不需要用户手动触发,任何允许用户存储数据的web程序都可能会存在XSS漏洞,攻击者提交一段XSS代码后,被服务器端接收并存储,当所有浏览者访问某个页面时都会被XSS。
攻击步骤
》攻击者将恶意代码提交到目标网站的数据库中。
》用户打开目标网站时,网站服务端将恶意代码从数据库取出,拼接在 HTML 中返回给浏览器
》用户浏览器接收到响应后解析执行,混在其中的恶意代码也被执行。
》恶意代码窃取用户数据并发送到攻击者的网站,或者冒充用户的行为,调用目标网站接口执行攻击者指定的操作 - 反射型XSS(亦称为非持久型攻击):
》常见于通过 URL 传递参数的功能,如网站搜索、跳转等
》需要通过用户主动打开url才会生效,攻击者经常结合多重手段诱导用户点击。POST 的内容也可以触发反射型 XSS,只不过其触发条件比较苛刻(需要构造表单提交页面,并引导用户点击),所以非常少见。
》与存储型的区别是,前者将恶意代码存储在数据库里,后者则存在url里。
攻击步骤
》攻击者构造出特殊的 URL,其中包含恶意代码
》用户打开带有恶意代码的 URL 时,网站服务端将恶意代码从 URL 中取出,拼接在 HTML 中返回给浏览器。
》用户浏览器接收到响应后解析执行,混在其中的恶意代码也被执行
》恶意代码窃取用户数据并发送到攻击者的网站,或者冒充用户的行为,调用目标网站接口执行攻击者指定的操作。 - DOM型XSS:
》与其他两个类型的XSS攻击不同,取出恶意代码由浏览器完成,属于前端Javascript的自身的安全漏洞,其余两种属于服务器端的安全漏洞。
攻击步骤:
》攻击者构造出特殊的 URL,其中包含恶意代码
》用户打开带有恶意代码的 URL。
》用户浏览器接收到响应后解析执行,前端 JavaScript 取出 URL 中的恶意代码并执行
》恶意代码窃取用户数据并发送到攻击者的网站,或者冒充用户的行为,调用目标网站接口执行攻击者指定的操作。
注意:使用DOM可以允许程序和脚本动态的访问和更新文档的内容、结构和样式。它不需要服务器解析响应的直接参与,触发XSS靠的是浏览器端的DOM解析,所以防范DOM型XSS完全就是前端的责任,必须注意!!!。
- XSS的防御
- 一般防御方法:
①httpOnly: 在 cookie 中设置 HttpOnly 属性后,js脚本将无法读取到 cookie 信息
②输入过滤:一般用于对于输入格式的检查,如:邮箱,电话号码,用户名,密码等,按照规定的格式输入。不仅仅是前端负责,后端也要做相同的过滤检查。因为攻击者完全可以绕过正常的输入流程,直接利用相关接口向服务器发送设置。
③转义 HTML:拼接 HTML 是必要的,就需要对于引号,尖括号,斜杠进行转义,但这还不是很完善.想对 HTML 模板各处插入点进行充分的转义,就需要采用合适的转义库。而且对于现实富文本来说,不能使用转义字符来防止攻击,因为转义字符会将需要的格式也过滤掉。
④白名单:考虑到转义字符的不足,可以使用白名单或者黑名单过滤的方法,一般使用白名单过滤方法。
⑤CSP:本质上就是建立白名单,开发者明确告诉浏览器哪些外部资源可以加载与执行。通过设置http头与meta标签两种方式进行CSP的开启。 - 针对型预防方法:
A. 存储型和反射型 XSS 都是在服务端取出恶意代码后,插入到响应 HTML 里的,攻击者刻意编写的“数据”被内嵌到“代码”中,被浏览器所执行。
①改成纯前端渲染,把代码和数据分隔开。
i. 浏览器先加载一个静态 HTML,此 HTML 中不包含任何跟业务相关的数据
ii.然后浏览器执行 HTML 中的 JavaScript。
iii. JavaScript 通过 Ajax 加载业务数据,调用 DOM API 更新到页面上
②对 HTML 做充分转义。
B.DOM型XSS攻击,其实质为网站前端 JavaScript代码本身不够严谨,把不可信的数据当作代码执行。
①在使用 **.innerHTML、.outerHTML、document.write() **时要特别小心,不要把不可信的数据作为 HTML 插到页面上,而应尽量使用 .textContent、.setAttribute() 等
②如果用 Vue/React 技术栈,并且不使用 v-html/dangerouslySetInnerHTML 功能,就在前端 render 阶段避免 innerHTML、outerHTML 的 XSS 隐患
③DOM 中的内联事件监听器,如 location、onclick、onerror、onload、onmouseover 等, 标签的 href 属性,JavaScript 的 eval()、setTimeout()、setInterval() 等,都能把字符串作为代码运行。如果不可信的数据拼接到字符串中传递给这些 API,很容易产生安全隐患,请务必避免
16.CSRF(安全系列)
- CSRF:跨站请求伪造(英语:Cross-site request forgery),亦被称为one-click attack 或者 session riding。一种挟制用户在当前已登录的 Web 应用程序上执行非本意的操作的攻击方法。如:攻击者诱导受害者进入第三方网站,在第三方网站中,向被攻击网站发送跨站请求。利用受害者在被攻击网站已经获取的注册凭证,绕过后台的用户验证,达到冒充用户对被攻击的网站执行某项操作的目的。
- CSRF的类型:
- GET类型的CSRF:GET类型的CSRF利用非常简单,只需要一个HTTP请求。
示例:当已经登录某网站的用户,在访问了包含这个img的页面后,这浏览器向这个页面发出请求,该网站就会收到包含用户信息的跨域请求
<img src="http://bank.example/withdraw?amount=10000&for=hacker" >
- POST类型的CSRF:该类型的CSRF利用起来通常使用的是一个自动提交的表单
- 链接类型的CSRF:链接类型的CSRF并不常见,比起其他两种用户打开页面就中招的情况,这种需要用户点击链接才会触发。这种类型通常是在论坛中发布的图片中嵌入恶意链接,或者以广告的形式诱导用户中招,攻击者通常会以比较夸张的词语诱骗用户点击
- 攻击步骤:
受害者必须依次完成两个步骤
- 登录受信任网站A,并在本地生成Cookie。
- 在不登出A的情况下,访问危险网站B。
注:一般认为如果不满足上免其中之一的条件,就不会被攻击。事实虽如此,但是很难避免。例如:不能保证你登录了一个网站后,不再打开一个tab页面并访问另外的网站;不能保证你关闭浏览器了后,你本地的Cookie立刻过期,你上次的会话已经结束;所谓的攻击网站,可能是一个存在其他漏洞的可信任的经常被人访问的网站
4. CSRF攻击的特点:
- 攻击一般发起在第三方网站,而不是被攻击的网站。被攻击的网站无法防止攻击发生
- 攻击利用受害者在被攻击网站的登录凭证,冒充受害者提交操作;而不是直接窃取数据
- 整个过程攻击者并不能获取到受害者的登录凭证,仅仅是“冒用”
- 方法多样:图片URL、超链接、CORS、Form提交等等。部分请求方式可以直接嵌入在第三方论坛、文章中,难以进行追踪。
注意:CSRF通常是跨域的,因为外域通常更容易被攻击者掌控。但是如果本域下有容易被利用的功能,比如可以发图和链接的论坛和评论区,攻击可以直接在本域下进行,而且这种攻击更加危险。
- 攻击防御
- 验证码:强制用户必须与应用进行交互,才能完成最终请求,该方法能较好遏制csrf的攻击,但是用户体验感较差
- Referer check:请求来源限制,此种方法成本最低,但是并不能保证 100% 有效,因为服务器并不是什么时候都能取到 Referer,而且低版本的浏览器存在伪造 Referer 的风险
- token:token 验证的 CSRF 防御机制是公认最合适的方案(与前端鉴权有关),但是若网站同时存在XSS攻击漏洞,则该方法会失效
- SameSite:给cookie设置SameSite属性,表示cookie不随着跨域请求发送(不会发送给恶意的第三方网站)
- CSRF与XSS的区别:
- 通常来说 CSRF 是由 XSS 实现的,CSRF 时常也被称为 XSRF(CSRF 实现的方式还可以是直接通过命令行发起请求等)。
- XSS 是代码注入问题,CSRF 是HTTP 问题。 XSS 是内容没有过滤导致浏览器将攻击者的输入当代码执行。CSRF 则是因为浏览器在发送 HTTP 请求时候自动带上 cookie,而一般网站的 session 都存在 cookie里面(Token验证可以避免)
17. 点击劫持
- 点击劫持:视觉欺骗的攻击手段,诱骗用户点击隐藏的网页元素。攻击者通常会通过 iframe 在网站上覆盖一个不可见的 HTML 元素来执行点击劫持,用户可能会因此在无意中下载恶意程序,浏览恶意网站,提供密码或敏感信息、转账或进行网络购物。
- 解决办法:
- 服务器端设置X-FRAME-OPTIONS这个http响应头
- 客户端设置Frame Busting,将iframe进行忽视
18. 中间人攻击
- 中间人攻击:攻击方同时与服务端和客户端建立起了连接,并让对方认为连接是安全的,但是实际上整个通信过程都被攻击者控制了。攻击者不仅能获得双方的通信信息,还能修改通信信息。
- 解决策略
19.URL、href、src
- url的结构:scheme://host:port/path?query
- scheme: 表示协议,如Http, Https, Ftp等;
- host: 表示所访问资源所在的主机名:如:www.baidu.com;
- port: 表示端口号,默认为80;
- path: 表示所访问的资源在目标主机上的储存路径;
- query: 表示查询条件;
20.对称加密与非对称加密(https采用的是对称加密还是非对称加密?说说加密过程)
- 对称加密:指使用同一个密钥来进行加秘和解密,经典对称加密算法有** AES**
- 非对称加密:非对称秘钥指的是通过特殊手段,实现的一种加密方式,这种方式能够通过一个公钥进行加密,然后通过私钥进行解密,而公钥与私钥不同,因此成为非对称,典型的非对称加密算法有 RSA 等
- 二者对比:
- 安全性:非对称加密安全性较高,对称加密安全性较低。使用对称加密可能在主动方发送私钥的时候被拦截,后面任何加密都不再具有效果;而非对称加密即使获取了公钥,但是只有掌握在通信双方手中的私钥才能解开密文。
- 性能:非对称加密设计的算法更加负载,性能会较对称加密更加复杂。因此不能一味使用非对称加密来提高安全性而忽略性能,一般采用非对称加密与对称加密进行加密。
- https使用非对称+对称组合加密,如图所示,因https涉及到大量的接口、数据等频繁的操作行为,不能使用非对称加密因为会导致性能不佳,因此传输数据选择对称加密进行数据传输;而因对称加密的密钥在通讯两端传递的时候更容易被捕获,因此使用非对称加密来对私钥进行传输。这样既保证了数据传输的安全性,又保证了数据传输的性能。
21.ADSL
- 宽带接入技术:用户要连接到互联网,必须先连接到某个 ISP,以便获得上网所需的 IP 地址。早期通过用户电话线通过调制解调器连接到ISP的。
- ADSL:非对称数字用户线,是数字技术对现有的模拟电话用户线进行改造,使它能够承载宽带数字业务
- 使用流程:
- 安装调制解调器:ADSL 在用户线(铜线)的两端各安装一个 ADSL 调制解调器。
- 离散多音调调制技术:目前国内常用的调制解调的方法基本离散多音调 DMT(Discrete Multi-Tone)调制技术。DMT 调制技术采用频分复用的方法。把 40kHz 以上一直到 1.1Mhz 的高端频谱划分为许多自信到,其中 25 个子信道用于上行信道,而 249 个子信道用于下行信道,并使用不同的载波(即不同的音调)进行数字调制。该方法相当于在一对用户线上使用许多较小的调制解调器并行传递数据。ADSL采用自适应调制结束使用户线能够传送尽可能高的数据率,但是受多方因素的影响,其并不能保证固定的数据率
- ADSL的接入网:数字用户线接入复用器;用户线;用户家中的一些设施
- 特点:传送尽可能高的数据率;利用现有电话线中的铜线;上行和下行传输效率可以不同
操作系统
每日训练
1.硬件结构
2. 操作系统结构
3.内存管理
4.进程、线程管理
- 进程
- 进程的状态:创建、就绪、运行、结束、阻塞、阻塞挂起、就绪挂起
- 进程控制结构(process control block):PCB 是进程存在的唯一标识;PCB通常是通过链表的方式进行组织,相同状态的进程链在一起,组成各种队列,如就绪队列与阻塞队列(或者通过索引方式进行组织);具体包含如下信息
①进程描述信息:进程标识符、用户标识符
②进程控制和管理信息:进程当前状态、进程优先级
③资源分配清单
④CPU相关信息 - 进程的控制:创建、终止、阻塞、唤醒过程
- 进程的上下文切换(只能发生在内核态):一个进程切换到另一个进程运行,称为进程的 上下文切换
(注:需要了解CPU的上下文:cpu寄存器,程序计数器;cpu上下文切换包括进程上下文切换、线程上下文切换、中断上下文切换)
①上下文切换的位置、内容
②上下文切换的情形:5种常见情形
- 线程:线程是进程当中的一条执行流程。同一个进程内多个线程之间可以共享代码段、数据段、打开的文件等资源,但每个线程各自都有一套独立的寄存器和栈,这样可以确保线程的控制流是相对独立的。
- 线程的优点:
①一个进程中可以同时存在多个线程;
②各个线程之间可以并发执行;
③各个线程之间可以共享地址空间和文件等资源; - 线程的缺点:当进程中的一个线程崩溃时,会导致其所属进程的所有线程崩溃(这里是针对 C/C++ 语言,Java语言中的线程奔溃不会造成进程崩溃
- 线程的上下文切换:
①属于同一个进程:虚拟内存是共享的,所以在切换时,虚拟内存这些资源就保持不动,只需要切换线程的私有数据、寄存器等不共享的数据
②不属于同一个进程:切换的过程就跟进程上下文切换一样 - 线程的实现方式
①用户线程
②内核线程
③轻量级进程:在内核中来支持用户线程
- 进程与线程的比较
- 进程是资源(包括内存、打开的文件等)分配的单位,线程是 CPU 调度的单位;
- 进程拥有一个完整的资源平台,而线程只独享必不可少的资源,如寄存器和栈;
- 线程同样具有就绪、阻塞、执行三种基本状态,同样具有状态之间的转换关系;
- 线程能减少并发执行的时间和空间开销(时间效率与空间效率高),具体体现在:
①线程的创建时间比进程快,因为进程在创建的过程中,还需要资源管理信息,比如内存管理信息、文件管理信息,而线程在创建的过程中,不会涉及这些资源管理信息,而是共享它们
②线程的终止时间比进程快,因为线程释放的资源相比进程少很多
③同一个进程内的线程切换比进程切换快,因为线程具有相同的地址空间(虚拟内存共享),这意味着同一个进程的线程都具有同一个页表,那么在切换的时候不需要切换页表。而对于进程之间的切换,切换的时候要把页表给切换掉,而页表的切换过程开销是比较大的
④由于同一进程的各线程间共享内存和文件资源,那么在线程之间数据传递的时候,就不需要经过内核了,这就使得线程之间的数据交互效率更高了
- 调度:当进程从一个运行状态到另外一状态变化的时候,其实会触发一次调度。
- 调度时机:
①从就绪态 -> 运行态
②从运行态 -> 阻塞态
③从运行态 -> 结束态 - 若硬件时钟提供某个频率的周期性中断,可根据如何处理时钟中断把调度算法分为两类:
①非抢占式调度算法
②抢占式调度算法:选一个进程,然后让该进程只运行某段时间,如果在该时段结束时,该进程仍然在运行时,则会把它挂起,接着调度程序从就绪队列挑选另外一个进程。这种抢占式调度处理,需要在时间间隔的末端发生时钟中断,以便把 CPU 控制返回给调度程序进行调度,也就是常说的时间片机制。 - 调度原则
①CPU利用率:在发送 I/O 事件致使 CPU 空闲的情况下,调度程序需要从就绪队列中选择一个进程来运行以提高cpu的利用率
调度程序应确保 CPU 是始终匆忙的状态,这可提高 CPU 的利用率
②系统吞吐量:提高系统的吞吐率(CPU在单位时间内完成的进程数量),调度程序要权衡长任务和短任务进程的运行完成数量。
③周转时间:从进程开始到结束的过程中,实际上是包含三个时间,分别是进程运行时间和进程等待、进程阻塞时间,这三个时间总和就称为周转时间。进程的周转时间越小越好,如果进程的等待时间很长而运行时间很短,那周转时间就很长,这不是我们所期望的,调度程序应该避免这种情况发生。
周转时间越短越好
④等待时间:就绪队列中进程的等待时间也是调度程序所需要考虑的原则
等待时间越短越好
⑤ 交互式应用:对于交互式比较强的应用,响应时间也是调度程序需要考虑的原则
响应时间越短越好
注:总之,对调度来说,让进程越快越好 - 调度算法
①先来先服务(First Come First Serve, FCFS):对长作业有利,适用于 CPU 繁忙型作业的系统,而不适用于 I/O 繁忙型作业的系统
②最短作业优先(Shortest Job First, SJF):优先选择运行时间最短的进程来运行,这有助于提高系统的吞吐量,对长作业不利,很容易造成一种极端现象
③高响应比优先 (Highest Response Ratio Next, HRRN):每次进行进程调度时,先计算「响应比优先级」,然后把「响应比优先级」最高的进程投入运行
④时间片轮转调算法:每个进程被分配一个时间段,称为时间片(Quantum),即允许该进程在该时间段中运行
⑤最高优先级调度:
进程的优先级可分为静态优先级与动态优先级,
》静态优先级:创建进程时候,就已经确定了优先级了,然后整个运行时间优先级都不会变化
》动态优先级:根据进程的动态变化调整优先级,比如如果进程运行时间增加,则降低其优先级,如果进程等待时间(就绪队列的等待时间)增加,则升高其优先级,也就是随着时间的推移增加等待进程的优先级
优先级对应算法对应也分为抢占式与非抢占式
》抢占式:当就绪队列中出现优先级高的进程,当前进程挂起,调度优先级高的进程运行
》非抢占式:当就绪队列中出现优先级高的进程,运行完当前进程,再选择优先级高的进程
⑥多级反馈队列:「时间片轮转算法」和「最高优先级算法」的综合和发展。
「多级」表示有多个队列,每个队列优先级从高到低,同时优先级越高时间片越短。
「反馈」表示如果有新的进程加入优先级高的队列时,立刻停止当前正在运行的进程,转而去运行优先级高的队列
》设置了多个队列,赋予每个队列不同的优先级,每个队列优先级从高到低,同时优先级越高时间片越短
》新的进程会被放入到第一级队列的末尾,按先来先服务的原则排队等待被调度,如果在第一级队列规定的时间片没运行完成,则将其转入到第二级队列的末尾,以此类推,直至完成
》当较高优先级的队列为空,才调度较低优先级的队列中的进程运行。如果进程运行时,有新进程进入较高优先级的队列,则停止当前运行的进程并将其移入到原队列末尾,接着让较高优先级的进程运行
- 进程间的通信方式:进程的用户空间独立,内存空间共享,进程之间的通信必须采用通过内存
- 管道:传递的是无格式的字节流数据。其生命周期跟随进程,进程创建而建立,进程结束而结束。
》缺点:效率较低,不适合进程间频繁交换数据。 - 消息队列:消息队列是保存在内核中的消息链表,在发送数据时,会被拆分成一个个独立的数据单元(消息体或数据块),消息体都是固定大小的存储块,若进程从消息队列中读取了消息体,内核就会把这个消息体删除;消息队列的生命周期跟随内核,只要不释放消息对列或者关闭操作系统就不会被销毁。
》缺点:通信不及时;附件也有大小限制(内核中每个消息体有最大长度限制);存在内核态与用户态之间的数据拷贝开销 - 共享内存:现代操作系统对于内存管理采用的是虚拟内存技术。基于此,共享内存的机制就是拿出一块虚拟地址空间来,映射到相同的物理内存中。
》优点:不存在将数据从用户态拷贝到内核态,而是直接映射,提高进程间通信速度 - 信号量:其实是一个整型的计数器,主要用于实现进程间的互斥与同步,而不是用于缓存进程间通信的数据。信号量表示资源的数量,当信号量初始化为1就代表是互斥信号量,可以保证任何时刻共享内存只能有一个进程访问,当初始信号量为0,代表是同步信号量。控制信号量的方式有两种原子操作
①一个是p操作(将信号量-1):进入共享资源之前。相减后如果信号量 < 0,则表明资源已被占用,进程需阻塞等待;相减后如果信号量 >= 0,则表明还有资源可使用,进程可正常继续执行
②一个是v操作(将信号量+1):离开共享资源之后。相加后如果信号量 <= 0,则表明当前有阻塞中的进程,于是会将该进程唤醒运行;相加后如果信号量 > 0,则表明当前没有阻塞中的进程。 - 信号:以上的进程间通信方式都是常规状态下的工作模式,在异常工作的状态下,需要用信号的方式来通知进程,信号是进程间通信机制中唯一的异步通信机制。用户进程对于信号产生,就有如下操作,a.执行默认操作 b.捕捉信号 c.忽略信号
- socket:以上所提5种都是同一台主机上进行进程间的通信,若要跨域通信,需要socket通信了(亦可用于同主机通信)
- 多线程冲突
- 互斥:保证一个线程(进程)在临界区执行时,其他线程(进程)应该被阻止进入临界区。(临界区:访问共享资源的代码片段)
- 同步:并发线程(进程)在一些关键点上可能需要互相等待与互通消息,相互制约的等待与互通消息则称为同步
- 用锁实现互斥:任何想进入临界区的线程,必须先执行加锁操作。若加锁操作顺利通过,则线程可进入临界区;在完成对临界资源的访问后再执行解锁操作,以释放该临界资源
①忙等待锁(自旋锁)
②无等待锁 - 用信号量实现互斥与同步:信号量表示资源的数量,对应一个整型的变量,有两原子操作的系统调用函数来控制信号量,分别是P操作与V操作
锁与信号量的实际案例 - 生产者-消费者问题(信号量):生产者在生成数据后,放在一个缓冲区中;消费者从缓冲区取出数据处理;任何时刻,只能有一个生产者或消费者可以访问缓冲区。任何时刻只能有一个线程操作缓冲区,可认为缓冲区是临界代码,需要互斥;缓冲区空时,消费者需要等待生产数据,则认为消费者与生产者是同步。
- 哲学家就餐问题
- 死锁
- 死锁概念:两个及以上线程都在等待对方释放锁,在没有外力的作用下,会一直相互等待,该情况就会发生死锁。
- 死锁产生的四个必要条件:互斥条件;持有并等待条件;不可剥夺条件;环路等待条件
- 避免死锁问题的产生:只需要破坏四个必要条件之一就可以。
①资源有序分配法,破环环路等待条件
- 多线程访问共享资源,为避免资源竞争而导致数据错乱,在访问共享资源前加锁,锁的种类有很多种
- 互斥锁与自旋锁:两种锁是其他高级锁的基础,当已经有一个线程加锁后,其他线程加锁则就会失败。
①互斥锁加锁失败后,线程会释放 CPU ,给其他线程。互斥锁是一种「独占锁」,对于互斥锁加锁失败而阻塞的现象,是由操作系统内核实现的。死锁会产生两次上下文切换,上下文切换会耗时,若能确定被锁住的代码执行时间很短,就不应该用互斥锁,而应该选用自旋锁,否则使用互斥锁。
②自旋锁加锁失败后,线程会忙等待,直到它拿到锁。在用户态完成加锁和解锁操作。不会主动产生线程上下文切换,所以相比互斥锁来说,会快一些,开销也小一些。 - 读写锁:由「读锁」和「写锁」两部分构成,如果只读取共享资源用「读锁」加锁,如果要修改共享资源则用「写锁」加锁,读写锁适用于能明确区分读操作和写操作的场景。
①工作原理:
》读锁:当「写锁」没有被线程持有时,多个线程能够并发地持有读锁,这大大提高了共享资源的访问效率,因为「读锁」是用于读取共享资源的场景,所以多个线程同时持有读锁也不会破坏共享资源的数据。
》写锁:一旦「写锁」被线程持有后,读线程的获取读锁的操作会被阻塞,而且其他写线程的获取写锁的操作也会被阻塞。
②根据实现不同,分为读优先锁与写优先锁
》读优先锁:当读线程 A 先持有了读锁,写线程 B 在获取写锁的时候,会被阻塞,并且在阻塞过程中,后续来的读线程 C 仍然可以成功获取读锁,最后直到读线程 A 和 C 释放读锁后,写线程 B 才可以成功获取写锁。
》写优先锁:当读线程 A 先持有了读锁,写线程 B 在获取写锁的