前端面试准备
前端面试准备
- 计算机网络基础
- 七层结构和五层结构
- HTTP和HTTPS
- HTTP访问过程
- HTTPS访问过程
- HTTP版本
- 怎样实现二进制编码
- HTTP状态码
- TCP UDP
- 区别
- TCP四次挥手
- IP
- IP协议
- IP地址
- 划分子网
- VLSM
- IP与MAC (Media Access Control Address)
- 路由表(Routing Info Base,RIB)
- 转发表(Forwarding Info Base,FIB)
- 地址解析协议(Address Resolution Protocol,ARP)
- 路由算法与协议
- 进程
- 进程和线程
- Java多线程
- 进程间通信(IPC)的方式
- Java 套接字
- 什么是socket
- socket编程
- 端口号
- JS
- 正则表达式
- 原型prototype
- JS执行模式:同步和异步
- 单线程
- 主线程和任务队列
- 同步模式和异步模式
- 事件冒泡和事件循环
- 异步编程的方法
- AJAX(Asynchronize JavaScript And XML)
- JS内置对象
- JSON(Java Script Object Notation,JS对象表示法)
- JQuery
- Vue
- 指令
- v-bind 绑定元素attribute
- v-if v-for 条件与循环
- 虚拟DOM
- 生命周期
- MVVM (Model-View-ViewModel)
- HTML CSS XML
- web安全
- SQL注入攻击
- XSS(Cross Site Scripting,跨站脚本攻击)
- CSRF(Cross-Site Request Forgery,跨站伪造请求攻击)
- SSRF(Server Side Request Forgery,服务端请求伪造攻击)
- 字符串匹配算法
- 朴素的方法
- KMP
- 数据库
- B树和B+树
- 事务隔离级别
- 事务
- 更新丢失 脏读 不可重复读 幻读
- 隔离级别
- 范式
- 底层存储方式
- sql和nosql(Not Only SQL)的区别
- 关系数据库
- 常用sql语句
- JSP
- Servlet Filter Listener
- Servlet
- Filter
- Listener
- 9大内置对象
- Cookie和session
- ES6
- ES6 中的类和对象
- this
- ES6 的新增语法
- html5
- 页面加载优化
- 浏览器缓存
- 本地缓存方式
【写在前面:主要自用,持续更新。】
计算机网络基础
七层结构和五层结构
五层 | 七层 | 作用 | 设备 | 主要协议 |
---|---|---|---|---|
物理层 | 物理层 | 确保原始的数据可在各种物理媒体上传输 | 中继器/放大器 (Repeater) 和集线器 | - |
数据链路层 | 数据链路层 | 数据链路层为网络层提供可靠的数据传输,基本数据单位为帧 | 网桥和交换机 | 以太网协议 |
网络层 | 网络层 | 网络层负责对子网间的数据包进行路由选择。还可以实现拥塞控制、网际互连等功能,基本数据单位为IP数据报 | 路由器 | IP (Internet Protocol), ICMP (Internet Control Message Protocol, 控制报文协议), ARP(Address Resolution Protocol, 地址解析协议, 跨网络层和链路层的协议), RARP(Reverse Address Resolution Protocol, 逆地址解析协议) |
传输层 | 传输层 | 传输层负责将上层数据分段并提供端到端的、可靠的或不可靠的传输,以及端到端的差错控制和流量控制问题 | 网关 | TCP, UDP |
应用层 | 会话层-表示层-应用层 | 数据传输基本单位为报文 | - | FTP (文件传送协议), Telnet (远程登录协议), DNS (域名解析协议), SMTP (邮件传送协议), POP3 (邮局协议), HTTP (Hyper Text Transfer Protocol) |
HTTP和HTTPS
HTTP协议是"明文"传输,面临问题:数据被篡改、被监听、身份伪装。
HTTPS在HTTP的基础上加入了SSL/TLS协议,SSL/TLS依靠证书来验证服务器的身份,并为浏览器和服务器之间的通信加密。(加密传输、身份认证)
HTTPS协议的主要作用:1.建立一个信息安全通道,来保证数据传输的安全。2.确认网站的真实性。
区别:
- HTTP是超文本传输协议,信息是明文传输,HTTPS则是具有安全性的SSL/TLS加密传输协议。
- HTTP和HTTPS使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
- HTTP的连接很简单,是无状态的;HTTPS协议是由SSL/TLS+HTTP协议构建的可进行加密传输、身份认证的网络协议,比HTTP协议安全。
- HTTPS协议需要到CA申请证书,一般免费证书较少,因而需要一定费用。
HTTPS:采用对称加密和非对称加密结合的方式来保护浏览器和服务端之间的通信安全。对称加密:加密和解密都是同一个密钥。非对称加密:密钥成对出现,分为公钥和私钥,公钥和私钥之间不能互相推导,公钥加密需要私钥解密,私钥加密需要公钥解密。
SSL:在TCP协议之上,应用层之下运作,用来传输敏感信息。使用SSL连接的URL地址以https开头,而不是http。
HTTP访问过程
- 当客户在浏览器中输入网址的并按下回车,浏览器会在浏览器DNS缓存,本地DNS缓存和Hosts中寻找对应的记录,如果没有获取到则会请求DNS服务来获取对应的IP。
- 浏览器申请和服务器建立TCP连接(三次握手:SYN ACK)。
- 浏览器向服务器发送get或post请求(请求报文的方法,URL和版本)
- 浏览器向服务器发送请求报文的首部,最后发送一个空首部表示结束,如果是post还会继续提交请求报文的实体。
- 服务器应答,向浏览器发送响应报文中的版本,状态码和短语(状态码的解释,如:200 OK)。
- 服务器向浏览器发送响应报文的首部,包括自己的信息和请求的文档,最后发送一个空首部表示结束。
- 服务器向浏览器发送响应报文的实体,即用户所请求的实际数据。
- 服务器关闭和浏览器的TCP连接(四次挥手:FIN ACK)。
注:CRLF是回车换行。
HTTPS访问过程
- 浏览器使用Https的URL访问服务器(端口443),建立SSL链接。(发送浏览器支持的加密协议及版本)
- 服务器接收到SSL链接后,筛选合适的加密协议,返回CA证书(有非对称加密的公钥A)给浏览器。(服务器->浏览器:公钥A)
- 浏览器使用根证书验证证书合法性。
- 浏览器生成随机数,作为对称加密的密钥B。(浏览器:对称密钥B)浏览器使用服务器返回的公钥A,对自己生成的对称加密密钥B进行加密,得到密钥C。(浏览器:用A给B加密->密钥C)浏览器将密钥C发送给服务器。(浏览器->服务器:密钥C)
- 服务器使用自己的私钥D对接受的密钥C进行解密,得到对称密钥B,使用B给数据加密,发送加密的数据给浏览器。(服务器:用私钥D解密C->B)
- 浏览器使用密钥B解密数据,之后和服务器之间使用密钥B加密通信数据进行通信。(SSL加密层建立)
验证证书安全性过程:
- 浏览器收到服务器发送的证书后,使用本地配置的CA公钥对证书进行解密得到服务器的公钥和证书的数字签名。
- 浏览器使用CA公钥解密数字签名得到信息摘要。
- 浏览器使用签名计算方法(hash)计算当前证书信息的信息摘要,与收到的信息摘要(2中解密得到的信息摘要)作对比,如果一样,表示证书是服务器下发的,没被中间人篡改过。
注:数字证书内容包括加密后服务器的公钥、权威机构的信息、服务器域名,证书信息,证书数字签名(证书信息–[Hash函数]–>证书数字摘要–[CA私钥加密]–>数字签名),签名计算方法(hash)以及证书对应的域名。
HTTP版本
HTTP:超文本传输协议,是一个基于请求与响应、无状态的、应用层的协议,常基于TCP/IP协议传输数据。所有的WWW文件都必须遵守这个标准。设计HTTP的初衷是为了提供一种发布和接收HTML页面的方法。
版本 | 功能 | 传输层协议 |
---|---|---|
0.9 | 只有get,用于获取HTML(纯文本) | TCP |
1.0 | 请求报文与响应报文:支持首部,响应状态行,超文本,GET、HEAD、POST方法;短连接(每个请求建立一个TCP连接,完成后立刻断开) | TCP |
1.1 | 默认长连接(FIFO处理请求),分块编码传输,范围请求(允许只请求资源的某个部分),Pipelining(允许一个 TCP 连接同时发送多个请求),请求报文与响应报文:支持Host头域,增加OPTIONS、PUT、DELETE、TRACE、CONNECT方法,缓存处理 | TCP |
2 | 多路复用(二进制分帧),头部压缩(压缩相同的头部信息),随时复位(RST_STREAM:停止一个信息传输),服务器端推流(服务器预估浏览器可能需要的资源提前发送),优先权和依赖(流) | TCP |
3 | 参考 | UDP |
注:多路复用(二进制分帧):将所有传输的信息分割为更小的消息和帧,并对它们采用二进制格式的编码 ,其中HTTP1.x的首部信息会被封装到Headers帧,request body则封装到Data帧里面。HTTP 2.0 通信都在一个连接上完成,这个连接可以承载任意数量的双向数据流。相应地,每个数据流以消息的形式发送,而消息由一或多个帧组成,这些帧可以乱序发送,然后再根据每个帧首部的流标识符重新组装。HTTP/2 的每个请求都会被拆分成多个 Frame,不同请求的 Frame 组合成 Stream,Stream 是 TCP 上的逻辑传输单元,这样 HTTP/2 就达到了一条连接同时发送多条请求的目标,这就是多路复用的原理。
版本 | 问题 |
---|---|
1.0 | 连接无法复用,队头阻塞 |
1.1 | - |
2 | - |
注:队头阻塞:TCP连接在请求队列中间一个请求丢失时,会阻塞该请求之后的请求,需要等待。如一个 TCP 连接同时传输 10 个请求,其中第 1、2、3 个请求已被客户端接收,但第 4 个请求丢失,那么后面第 5 - 10 个请求都被阻塞,需要等第 4 个请求处理完毕才能被处理,这样就浪费了带宽资源。
怎样实现二进制编码
HTTP状态码
HTTP状态码(HTTP Status Code)是用以表示网页服务器HTTP响应状态的3位数字代码。
1xx:信息。
2xx:成功。200 请求成功。
3xx:重定向。301 资源被永久转移到其他URL。
4xx:客户端错误。404 请求的资源不存在。
5xx:服务端错误。500 内部服务器错误。503 服务器当前无法处理请求。522 连接超时。
TCP UDP
区别
TCP:支持可靠的面向连接服务,支持字节流传输服务,传输数据没有大小限制,支持全双工服务。
UDP:无连接、不可靠(发送方发送的数据报并不一定以相同的次序到达接收方)的传输层协议,没有提供拥塞控制机制,不提供最小延时保证,传输数据有大小限制(每个被传输的数据报限定在64KB之内)。
TCP四次挥手
- 发送方----FIN---->接收方。
发送方进入第一个等待时间:FIN-WAIT-1。 - 接收方----ACK---->发送方。
接收方收到发送方的FIN进入关闭等待阶段:CLOSE-WAIT。这个期间还可以进行数据的传输。
发送方收到接收方的第一次确认(ACK)后进入第二个等待时间:FIN-WAIT-2。 - 接收方----FIN---->发送方。
接收方进入最后确认等待:LAST-ACK。等待发送方返回的ACK。如果没有收到会进行重传。
发送方接收到FIN后会返回一个ACK。 - 发送方----ACK---->接收方。
发送方进入TIME-WAIT,默认2MSL(Maximum Segment Lifetime),这个期间不会释放连接。如果收到了重传的FIN,则会再次进入新的TIME-WAIT。直到计时器结束,释放连接。
MSL指一个片段在网络中最大的存活时间。2MSL是发送和回复一次来回所需的最大时间。如果直到2MSL发送方都没有再次收到FIN,那么认为接收方已经成功收到ACK,结束TCP连接。
IP
IP协议非常简单,仅仅提供不可靠、无连接的传送服务。
IP协议的主要功能有:无连接数据报传输、数据报路由选择和差错控制。
与IP协议配套使用实现其功能的还有地址解析协议ARP、逆地址解析协议RARP、因特网报文协议ICMP、因特网组管理协议IGMP。
IP协议
IP数据报头(20字节)
- 4位版本号:IP协议的版本,IPv4:4
- 4位头部长度:标识IP头部长度,单位:4字节。4位最大能表示15(1111),所以IP头部最长是60字节。
- 8位服务类型:优先权字段(3位)+TOS字段(4位:最小延时,最大吞吐量,最高可靠性,最小费用)+保留字段(1位:0)。TOS字段最多有一个位能置1。
- 16位总长度:整个IP数据报的长度,单位:字节。IP数据报的最大长度为65535字节。长度超过MTU会进行分片传输。
- 16位标识:唯一地标识主机发送地每一个数据报。初始值由系统随机生成,每发送一个数据报值加1。该值在数据报分片时被复制到每个分片中,因此同一个数据报的所有分片都具有相同的标识。
- 3位标志:保留位,禁止分片,更多分片。
禁止分片=1:IP数据包长度超过MTU时会丢弃该数据包并返回ICMP差错报文。
更多分片:表示还有其他该数据报的分片,数据包的最后一个分片置为0,其他分片置为1。 - 13位片偏移:分片相对原始IP数据报(仅指数据部分)的偏移。
- 8位生存时间 (TTL) :数据报到达目的地之前允许经过的路由器跳数。由发送端设置 (常见值64) 。防止数据报陷入路由循环。
每经过一个路由,TTL减1。TTL=0时,路由器将丢弃数据报,并向源端发送一个ICMP差错报文。 - 8位协议:区分上层协议,ICMP是1,TCP是6,UDP是17。
- 16位头部校验和:发送端填充,接收端CRC算法以检验IP数据报头部在传输过程中是否损坏。
- 32位源端IP地址
- 32位目的端IP地址
- 可变长的可选信息
- 记录路由:记录传输过程中经过的所有路由器的IP地址。
- 时间戳:记录每个路由器转发数据报的时间。
- 松散源路由选择:数据报发送过程必须经过指定的所有路由器。
- 严格源路由选择:数据报只能经过被指定的路由器。
注:
MTU(最大传输单元)。
封包(encode):存这个字段的时候他把实际的偏移值/8封进去。
解包(decode):解析这个字段×8得到实际偏移值。
由于这个原因,除了最后一个IP分片外,每个IP分片的数据部分的长度必须是8的整数倍(这样才能保证后面的IP分片拥有一个合适的偏移量)。
分片可能发生在发送端,也可能发生在中转路由器上。传输过程中可能多次分片,只有在最终的目标机器上,这些分片才会被内核中的IP模块重新组装。
IP地址
IP地址由网络ID和主机ID组成。同一个物理网络上的所有主机都使用同一个网络ID,网络上的一个主机对应一个主机ID。
IP地址根据网络ID的不同分为5种:
- A
- 1字节网络ID+3字节主机ID。网络ID以0开头。
- 范围1.0.0.0 到127.0.0.0。127种。
- 127.0.0.1:回环地址,表示主机本身,用于本地机器的测试。
- 0.x.x.x:代表任何地址。
- 默认子网掩码为255.0.0.0。
- B
- 2字节网络ID+2字节主机ID。网络ID以10开头。
- 范围128.0.0.0到191.255.255.255。16382种。
- 128.0.0.0和191.255.0.0为保留IP。
- C
- 3字节网络ID+1字节主机ID。网络ID以110开头。
- 范围192.0.0.0到223.255.255.255。每个网络能容纳254个主机。
- 192.0.0.0和223.255.255.0为保留IP。
- D
- 多播地址。网络ID以1110开头。
- 范围224.0.0.0到239.255.255.255。
- E
- 保留地址。网络ID以0开头。
- 范围240.0.0.0到255.255.255.254。
- 255.255.255.255用于广播地址。
注: 全0(0.0.0.0)地址对应于当前主机。全1地址(255.255.255.255)是当前子网的广播地址。
划分子网
原因:IP地址不够用了。
VLSM(可变长子网掩码)和CIDR(无类别域间路由):把传统标准的IPv4有类网络演变成一个更为高效,更为实用的无类网络。
VLSM:用于IPv4子网的划分,即把一个大的网络划分成多个小的子网。
CIDR:用于IPv4子网的聚合,主要是指路由的聚合,即路由汇总。通过CIDR可以把多个小的子网路由条目汇总成一个大网络的路由条目,以减少路由器中路由条目的数量,提高路由效率。
VLSM
基本思想:借用现有网段的主机位的最左边某几位作为子网位,划分出多个子网。
- 把原来有类网络IPv4地址中的 网络ID 部分向 主机ID 部分借位。借位的部分为 子网ID 。
- 原来的 网络ID+子网ID=新网络ID 。 子网ID 的长度决定了可以划分子网的数量。
子网掩码:用于区分IP为2级IP还是三级IP。
网络号和子网号用1表示,主机号用0表示。
简写:/数字 表示有多少位是网络号+子网号。
192.168.0.0/24 网络号占24位。
划分成两个大小一样的子网:取主机号的一位做为子网号。
192.168.0.0/25,192.168.0.128/25。
(27=128)
等长子网划分:所有子网的大小一样,子网掩码一样。
变长子网划分:子网的大小不一样。
IP与MAC (Media Access Control Address)
- IP地址是Internet协议使用的地址,而MAC地址是Ethernet协议使用的地址。
- IP地址的分配是基于网络拓朴,MAC地址的分配是基于制造商。
- MAC地址是唯一的,物理上的,不可改变的;IP地址在同一网段可以是唯一的,也可能有冲突(因为可以自己设置),动态的,虚拟的,软件的。
为什么有了MAC还要有IP?为什么有了IP还要有MAC?
MAC可以唯一标识一个设备,但当设备很多时进行路由寻址十分复杂,于是把网络划分成了多个子网,数据在转发时只需要发送到目的设备所在的子网,之后再由子网内部转发给目的设备。如果只有MAC地址,我们需要标识每个MAC地址所在的子网,无法实现。IP地址则可以知道设备所在的子网,因为对于同一个子网的设备,它的IP地址的前缀都是一样的。
由于IP地址只有在接入子网后才会产生,且在不同网络划分下会有重复,因此我们需要MAC地址来唯一标识设备。
而在转发时,我们不仅需要知道源地址(发送方)和目的地址(接收方),还需要知道下一跳的地址,这时如果在IP报文头部保存下一跳的IP也可以实现,但不利于解耦,所以在转发时,通过更改MAC地址来记录下一跳信息。
路由表 (RIB) 视为路由器的控制平面。全局路由表,通常存储在设备的动态内存,如随机存储器(Random Access Memory,RAM)中。
路由表实际上并不直接指导数据转发,路由器在执行路由查询时,查询的是FIB表,位于控制层面的路由表只是提供了路由信息而已。
转发表 (FIB) 基于 IP 包的网络前缀,判断如何进行转发。对于每一条可达的目标网络前缀,FIB 包含接口标识符和下一跳信息。 FIB 概念上类似于路由表。它维护一份 RIB 表中的转发信息镜像。
当 IP 路由从 RIB 拷贝到 FIB 时,它们的下一跳信息被明确地分析出来,包括下一跳的具体端口,以及如果到下一跳有多条路径时,每条路径的具体端口。
从A发送到D | A->B | B->C | C->D |
---|---|---|---|
源IP | A | A | A |
目的IP | D | D | D |
源MAC | A | B | C |
目的MAC | B | C | D |
下一跳 | B | C | D |
路由表(Routing Info Base,RIB)
- S:static,表示静态路由。
- C:connected,直连路由,直连可达的。
- 10.69.0.0./16和10.69.65.24/24是目的IP,需要通过172.20.0.1(下一跳IP)到达。
- 172.20.0.0/16是直连IP,该设备可以与当前设备直接传输。
- 172.20.64.23/32是local lookback(本地回路),即当前设备的IP。
转发表(Forwarding Info Base,FIB)
- vrId:VRF ID,vpn的实例id。
- prefix/mask:路由前缀/前缀长度。
- next-hop ID:对应的下一跳。参考索引表。
- vid: VLAN ID,vlan的实例号。
- interface:出接口,数据包将从哪个接口转发出去。
- mac:从接口转发出去时候应该封装的mac地址。
地址解析协议(Address Resolution Protocol,ARP)
根据IP地址获取物理地址的一个TCP/IP协议。
主机发送信息时将包含目标IP地址的ARP请求广播到网络上的所有主机,并接收返回消息,以此确定目标的物理地址;收到返回消息后将该IP地址和物理地址存入本机ARP缓存中并保留一定时间,下次请求时直接查询ARP缓存以节约资源。
路由算法与协议
- 静态:管理员手动配置
- 动态
- RIP(Routing Information Protocol)
基于距离矢量路由算法 DVR( Distance Vector Routing )。以跳数为代价单位,每个路由器周期性的与相邻路由器交换若干路由信息 <可达IP, 跳数> ,按照距离矢量算法(最短路径原则,实现最佳性)建立或更新路由表。
使用UDP的520端口来发送和接收RIP分组。
路由表项:目的地,下一跳,跳数。
跳数最大为16,表示不可达。
只适用于小型网络(传递消息经过的路由器不超过15个)。 - OSPF(Open Shortest Path First,开放最短路径优先协议)
基于Dijkstra算法。
使用IP协议号89。 - BGP
使用TCP协议的179端口号。
BGP 其着眼点不在于自动发现网络拓扑,而在于在AS之间选择最佳路由和控制路由的传播。
- RIP(Routing Information Protocol)
内部网关协议(IGP), 也称域内路由选择:使用RIP或OSPF。
外部网关协议(EGP), 也称域间路由选择:使用BGP。
进程
进程和线程
线程:程序中一个单一的顺序控制流程。每个程序都至少有一个线程,若程序只有一个线程,那就是程序本身。
进程:资源分配的基本单位,拥有一个完成的虚拟地址空间。与线程的关系:当进程发生调度时,不同的进程用有不同的虚拟地址空间,而同一进程内的不同线程共享同一地址空间。
多线程:在单个程序中同时运行多个线程完成不同的工作。
Java多线程
线程阻塞:
- sleep
线程sleep时不释放锁对象,不放弃CPU执行权。此时其他线程无法执行,被阻塞。- 恢复:到时间进入runnable状态。
- wait
线程wait时释放锁对象,放弃CPU执行权,被阻塞。- 恢复:使用notify(随机唤醒一个),notifyAll进入runnable状态。
- yield
线程yield时不释放锁对象,放弃CPU执行权给同等级或更高级的线程,线程进入就绪状态。 - join
线程join时立即进入阻塞状态,等待其他线程执行完毕,然后线程进入就绪状态。 - suspend
- 恢复:resume
进程间通信(IPC)的方式
- 无名管道( pipe ): 管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。
- 高级管道(popen): 将另一个程序当做一个新的进程在当前程序进程中启动,则它算是当前程序的子进程,这种方式我们成为高级管道方式。
- 有名管道 (named pipe) : 有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信。
- 消息队列( message queue ) : 消息队列是消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。
- 信号量( semophore ) : 信号量是一个计数器,用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。
- 信号 ( sinal ) : 信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。
- 共享内存( shared memory ) :共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的 IPC 方式,它是针对其他进程间通信方式运行效率低而专门设计的。它往往与其他通信机制(如信号量)配合使用,来实现进程间的同步和通信。
- 套接字( socket ) : 可用于不同机器间的进程通信。
Java 套接字
传输层建立了主机端到端(端口号)的链接。传输层为上层协议提供端到端的可靠和透明的数据传输服务,包括差错控制和流量控制等。该层向高层屏蔽了下层数据通信的细节,使高层用户看到的只是在两个传输实体间的一条主机到主机的、可由用户控制和设定的、可靠的数据通路。
网络层的IP地址可以唯一地确定Internet上的一台主机。传输层提供面向应用的可靠 (TCP) 的或不可靠 (UDP) 的数据传输机制。
- 客户端/服务器(C/S)
服务器等待客户端的请求并予以响应。客户端在需要服务时向服务器发出请求。
服务器一般始终运行,监听网络端口,一旦接受到服务请求,就会启动一个服务进程来响应,同时继续监听服务端口。 - 浏览器/服务器(B/S)
客户端在需要服务时向服务器发出请求。服务器响应后及时返回,不需要实时监听端口。
什么是socket
网络上的两个进程通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket。
Socket是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元,是网络通信过程中端点的抽象表示。
Socket包含进行网络通信五元组
- 连接使用的协议
- 本地主机的IP地址:源IP
- 本地进程的协议端口:源端口
- 远地主机的IP地址:目的IP
- 远地进程的协议端口:目的端口
socket编程
Socket编程本质是接口(API),对TCP/IP的封装。
Socket的工作过程:
创建Socket => 打开连接到Socket的输入/输出流 => 按照协议对Socket进行读/写 => 关闭Socket。
socket建立连接的过程:
- 服务器监听
服务器端socket处于等待连接的状态,实时监控网络状态。
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;public class Service {public static void main(String[] args) {try {// 创建套接字:可选参数 int port表示监听的端口ServerSocket serverSocket = new ServerSocket (8090); //TCPDatagramSocket dgSocket = new DatagramSocket(8091); //UDP// 绑定SocketAddress: 主机号和端口 最大连接数backlogInetSocketAddress tcpAddress=new InetSocketAddress("localhost",8090);InetSocketAddress udpAddress=new InetSocketAddress("localhost",8091);int backlog=10;serverSocket.bind(tcpAddress, backlog);dgSocket.bind(udpAddress);// 循环监听端口while(true) {// 处理tcp请求Socket socket=serverSocket.accept();// 接收到请求创建一个线程处理请求Thread service=new Thread(new ServerThread(socket));service.start();// 处理udp请求byte[] bytes = new byte[1024];DatagramPacket packet = new DatagramPacket(bytes, bytes.length);dgSocket.receive(packet); // 接收udp数据包dgSocket.send(packet); // 向客户端返回信息}} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}
}
import java.io.IOException;
import java.net.Socket;public class ServerThread implements Runnable{private Socket socket; public ServerThread(Socket socket) {this.socket=socket;}@Overridepublic void run() {// TODO Auto-generated method stubtry {byte[] data=new byte[1024];socket.getInputStream().read(data); //data保存从客户端接收的请求socket.getOutputStream().write("向客户端返回数据".getBytes());} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();} }
}
- 客户端请求
客户端socket提出连接请求。
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;public class Client {public static void main(String[] args) throws UnknownHostException, IOException {// TODO Auto-generated method stub//tcpSocket tcpsocket = new Socket("localhost", 8090); // 请求连接:服务器的ip+端口号tcpsocket.getOutputStream().write("发送给服务器的数据".getBytes());byte[] data = new byte[1024];tcpsocket.getInputStream().read(data); //接收服务器返回的数据tcpsocket.close();//udpDatagramSocket udpsocket = new DatagramSocket();InetAddress ip=InetAddress.getByName("localhost");DatagramPacket packet=new DatagramPacket(data, data.length, ip, 8091); //要访问的目的地址信息封装在数据包中udpsocket.send(packet);udpsocket.close();}
}
其他写法
3. 连接确认
当服务器端socket监听到或接收到客户端socket的连接请求,会进行响应,建立一个新的线程把服务器端socket的描述发给客户端,一旦客户端确认了此描述,连接就建立好了。而服务器端socket继续处于监听状态,继续接收其他客户端socket的连接请求。
端口号
- 公认端口:0-1023
紧密绑定于一些服务。通常这些端口的通讯明确表明了某种服务的协议。
TCP保留端口号:HTTP 80,FTP 20/21,Telnet 23,SMTP 25,DNS 53。
UDP保留端口号:DNS 53,BootP 67(server) / 68(client),TFTP 69,SNMP 161。 - 注册端口:1024-49151
松散地绑定于一些服务。动态端口。 - 动态/私有端口:49152-65535。
理论上,不应为服务分配这些端口。。
JS
正则表达式
// 创建
var 变量名 = new RegExp(/表达式/); // 1
var 变量名 = /表达式/; // 2regexObj.test(str) // 测试str是否符合定义的正则表达式regexObj
正则表达式中的边界符(位置符)用来提示字符所处的位置,主要有两个字符:^以谁开始,$以谁结尾,同时使用需要精确匹配。
[]:匹配其中一个。
[a-z]:匹配范围内。
[^123]:取反。
量词:* 0或多次,+ 1或多次,? 0或1次,{n} n次,{n,} n或多次,{n,m} n到m次。
预定义类:
\d:[0-9],\D:[0-9],\w:[a-zA-Z0-9_],\W:[a-zA-Z0-9_],\s:[\t\r\n\v\f],\S[^\t\r\n\v\f]。
replace() 方法可以实现替换字符串操作,用来替换的参数可以是一个字符串或是一个正则表达式。
switch(也称为修饰符) 按照什么样的模式来匹配,有三种值:g(全局匹配),i(忽略大小写),gi(全局匹配 + 忽略大小写)。
stringObject.replace(regexp/substr,replacement)
/表达式/[switch]
原型prototype
构造函数是一种特殊的函数,主要用来初始化对象,为对象成员变量赋初始值。new一个普通function即得到一个对象。该function为该对象的构造函数。
静态成员:在构造函数本身上添加,只能由构造函数本身来访问。
实例成员:在构造函数内部的 this 上添加,只能由实例化的对象来访问)。
new 在执行时会做四件事情:①在内存中创建一个新的空对象。②让 this 指向这个新的对象。③执行构造函数里面的代码,给这个新对象添加属性和方法。④返回这个新对象(所以构造函数里面不需要 return )。
每个对象都有构造函数,存在浪费内存的问题。我们希望所有的对象使用同一个函数。
JavaScript 规定,每一个构造函数都有一个 prototype 属性,指向另一个对象。我们可以把那些不变的方法,直接定义在 prototype 对象上,这样所有对象的实例就可以共享这些方法。
注意:prototype 就是一个对象,这个对象的所有属性和方法,都会被构造函数所拥有。作用为共享方法。
对象都会有一个属性 proto 指向构造函数的 prototype 原型对象:__proto__对象原型和原型对象 prototype 是等价的,__proto__对象原型的意义在于为对象的查找机制提供一个方向,或者说一条路线。
function employee(name){this.name=name;
}
var bill=new employee("Bill Gates"); //new 函数创建对象,该函数变为构造函数
employee.prototype.salary=null; //prototype可以向对象添加属性和方法。
bill.salary=20000;
document.write(bill.salary); //打印20000
JS执行模式:同步和异步
单线程
JavaScript是单线程,同一个时间只能做一件事。作为浏览器脚本语言,JavaScript的主要用途是与用户互动,以及操作DOM。这决定了它只能是单线程,否则会带来很复杂的同步问题。
主线程和任务队列
单线程意味着所有任务需要排队,前一个任务结束,才会执行后一个任务。如果前一个任务耗时很长,后一个任务就不得不一直等着。于是就有一个概念,任务队列。
很多时候CPU是闲着的,因为IO设备很慢(比如Ajax操作从网络读取数据),不得不等着结果出来,再往下执行。
主线程完全可以不管IO设备,挂起处于等待中的任务,先运行排在后面的任务。等到IO设备返回了结果,再回过头,把挂起的任务继续执行下去。
同步模式和异步模式
- 同步模式:后一个任务等待前一个任务结束,然后再执行,程序的执行顺序与任务的排列顺序是一致的、同步的。
- 异步模式:每一个任务有一个或多个回调函数(callback),前一个任务结束后,不是执行后一个任务,而是执行回调函数,后一个任务则是不等前一个任务结束就执行,所以程序的执行顺序与任务的排列顺序是不一致的、异步的。
异步运行机制:
- 所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。
- 主线程之外,还存在一个任务队列(task queue)。只要异步任务有了运行结果,就在任务队列之中放置一个事件。
- 一旦执行栈中的所有同步任务执行完毕,系统就会读取任务队列,看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。
- 主线程不断重复上面的第三步。
任务队列是一个事件的队列,FIFO,IO设备完成一项任务,就在任务队列中添加一个事件,表示相关的异步任务可以进入执行栈了。主线程读取任务队列,就是读取里面有哪些事件。主线程的读取过程基本上是自动的,只要执行栈一清空,任务队列第一位的事件就自动进入主线程。(对于存在定时器的事件,主线程首先要检查一下执行时间,某些事件只有到了规定的时间,才能返回主线程。)
任务队列中的事件除了IO设备的事件外,还包括一些用户产生的事件(如鼠标点击、页面滚动等)。只要指定过回调函数,这些事件发生时就会进入任务队列,等待主线程读取。
回调函数callback就是那些会被主线程挂起来的代码。异步任务必须指定回调函数,当主线程开始执行异步任务,就是执行对应的回调函数。
事件冒泡和事件循环
事件循环:异步运行机制。
事件冒泡 :当一个元素接收到事件的时候,会把他接收到的事件传给自己的父级,一直到window。只传递事件,不传递绑定的函数。
事件委托:也称事件代理,把事件绑定到父级上,利用冒泡的原理,触发执行效果。
取消事件冒泡有两种方式:
标准的W3C方式:调用方法,e.stopPropagation()
非标准的IE方式:设置属性,ev.cancelBubble=true
异步编程的方法
- 回调函数:做为参数传递的函数,如JQuery 的 ajax。
- 事件监听:任务的执行不取决于代码的顺序,而取决于某个事件是否发生。
- 发布订阅模式/观察者模式:利用一个消息中心,发布者发布一个消息给消息中心,订阅者从消息中心订阅该消息。
- Promises对象
代表未来将要发生的事件,用来传递异步操作的消息。- 特点:对象的状态不受外界影响,一旦状态改变,就不会再变,任何时候都可以得到这个结果。这与事件(Event)完全不同,事件的特点是,如果你错过了它,再去监听,是得不到结果的。
- Promise 对象代表一个异步操作,有三种状态:
pending:初始状态(进行中)。fulfilled:操作成功。rejected:操作失败。 - Promise 对象的状态改变只有两种:Pending->Resolved和Pending->Rejected。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。
- 优点:Promise 对象可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。此外,Promise 对象提供统一的接口,使得控制异步操作更加容易。
- 缺点:Promise一旦新建就会立即执行,无法中途取消。如果不设置回调函数,Promise内部抛出的错误,不会反应到外部。当处于 Pending 状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。
- Generator (ES6)
Generator 函数是一个状态机,封装了多个内部状态。执行 Generator 函数会返回一个遍历器对象,使用该对象的 next() 方法,可以遍历 Generator 函数内部的每一个状态,直到 return 语句。 - async (ES7)
async函数返回的是一个 Promise 对象,可以使用 then 方法添加回调函数,async 函数内部 return 语句返回的值,会成为 then 方法回调函数的参数。当函数执行的时候,一旦遇到await就会先返回,等到异步操作完成,再接着执行函数体内后面的语句。
//回调函数
function f1() {setTimeout(function(){console.log('先执行 f1')},1000);
}
function f2() {console.log('再执行 f2');
}
function f1(f2){setTimeout(function(){console.log('先执行 f1')},1000);f2();
}
function f2() {console.log('再执行 f2');
}//事件监听
$(function(){console.log('DOM 已经 ready')});//观察者模式
$('#app').on('showData',function(data){console.log(data)}); //订阅showData事件
$('#app').trigger('showData','saveData'); //发布事件//Promises对象
var promise = new Promise(function(resolve, reject) {// 异步处理// 处理结束后,如果一切都正常,则调用resolve,否则调用reject。//已经实例化过的 promise 对象可以调用 promise.then() 方法,传递 resolve 和 reject 方法作为回调。
});function getMethods (url){return new Promise(function(resolve, reject){axios.get(url).then(res => {resolve(res)}).catch(err =>{reject(err)})})
}
getMethods('/api/xxx').then(res => {console.log(res)}, err => {console.log(err)}) //.then异步执行:当.then()前的方法执行完后再执行then()内部的程序. promise.then(onCompleted, onRejected);//Generator
function *generatorDemo() {yield 'hello'; //yield:暂停执行的标记。yield 1 + 2;return 'ok';
}
var demo = generatorDemo()
//next()方法遇到yield表达式,就暂停执行后面的操作,并将紧跟在yield后面的值作为返回对象的属性值。
demo.next() // { value: 'hello', done: false }
demo.next() // { value: 3, done: false }
demo.next() // { value: 'ok', done: ture }
demo.next() // { value: undefined, done: ture }//async
async function demo() {try {await new Promise(function (resolve, reject) {// something});} catch (err) {console.log(err);}
}
demo().then(data => {console.log(data)});
AJAX(Asynchronize JavaScript And XML)
异步的JavaScript和XML,在不重新加载整个页面的情况下,服务器交换数据并更新部分网页的艺术。实现异步刷新。
原始实现方式
<div id="myDiv"><h3>Let AJAX change this text</h3></div>
<button type="button" onclick="check()">Change Content</button>
var xmlhttp;
function check(){var div1 = document.getElementById("div1").value;var url = "../checkname.jsp?div1="+div1;xmlhttp = new XMLHttpRequst(); //创建对象xmlhttp.onreadystatechange = checkResult; //设置响应函数xmlhttp.open("GET",url,true); //执行访问xmlhttp.send(null);// xmlhttp.open("POST","../checkname.jsp",true); xmlhttp.send("div1="+div1);
}
function checkResult(){if(xmlhttp.readystate==4&&xmlhttp.status==200)document.getElementById("checkResult").innerHTML = xmlhttp.responseText; //responseText responseXML 获取服务端传回的文本//readystate:0-请求未被初始化,1-服务器连接已建立,2-请求已接收,3-请求处理中,4-请求完成且响应就绪。
}
JQuery实现方式
$("#buttonId").load(url,function(responseText,status,XMLHttpRequest){}) //responseText:servlet返回的文本 status:HTTP状态码$.get(url,提交到servlet的json数据,function(data,status){}) //data:返回数据$.post(url,提交到servlet的json数据,function(data,status){})$.ajax({
type:"get"或"set",
dataType:"text",
url:"url",
data:"name=zsq", //传递的参数
success:function(data,status){}
})
JS内置对象
Number
String
Array
Date
Math
JSON(Java Script Object Notation,JS对象表示法)
// object
var objname={"field1":"value1","field2":"value2"};
objname.field1; //value1// array
var arr=[{"a":1,"b":2},{"c":3},{"d":4}];
arr[0].a; //1
arr[1].c; //3// 对象转换
eval() // String->JSON
jsonObj.stringify // JSON->String
JQuery
<script type="text/javascript" src="jquery.js"></script>
$(选择器).action()// 文档就绪函数
$(document).ready(function(){});
$(function(){}); //简写// css元素选择器
$("p") $("p.classname") $("p#idname")
// xpath属性选择器
$("[href]") $("[href='#']") $("[href!='#']") $("[href$='.jpg']") //以.jpg结尾//JQuery事件函数
$(选择器).click(function(){});
$(选择器).dbclick(function(){});
$(选择器).focus(function(){}); //焦点事件
$(选择器).mouseover(function(){}); //鼠标悬停
$(选择器).on("事件",function(){}); //为指定元素的一个或多个事件绑定事件处理函数。
$(选择器).trigger("事件1","事件2",...); //触发事件//JQuery效果 []表示可选参数
$(选择器).hide([speed,callback]); //speed=slow/fast/xx ms
$(选择器).show([speed,callback]);
$(选择器).toggle([speed,callback]);
$(选择器).fadeIn([speed,callback]); //淡入
$(选择器).fadeOut([speed,callback]);
$(选择器).fadeToggle([speed,callback]);
$(选择器).fadeTo(speed,opacity[,callback]); //渐变为给定的透明度opacity:0-1
$(选择器).slideDown([speed,callback]); //滑动
$(选择器).slideUp([speed,callback]);
$(选择器).slideToggle([speed,callback]);
$(选择器).animate({params},[speed,callback]); //{params}定义动画的css属性//JQuery DOM
//()内有值为设置,无值为返回
$(选择器).text()
$(选择器).html()
$(选择器).val() //表单字段
$(选择器).attr() //属性值
//添加
$(选择器).append() //尾部追加
$(选择器).prepend() //头部追加
$(选择器).after() //之前插入
$(选择器).before() //之后插入
//删除
$(选择器).remove()
$(选择器).empty()
//css
$(选择器).addClass()
$(选择器).removeClass()
$(选择器).toggleClass()
$(选择器).css() //()内有值为设置,无值为返回
//尺寸
$(选择器).width()
$(选择器).height()
$(选择器).innerWidth() //包括内边距padding
$(选择器).innerHeight()
$(选择器).outerWidth() //包括内边距和边框
$(选择器).outerHeight() //JQuery 遍历
$(选择器).parent()
$(选择器).parents()
$(选择器1).parentsUntil(选择器2) //返回1和2之间的祖先元素
$(选择器).children()
$(选择器).find()
$(选择器).siblings() //所有同胞
$(选择器).next()
$(选择器).nextAll()
$(选择器1).nextUntil(选择器2)
$(选择器).prev()
$(选择器).prevAll()
$(选择器1).prevUntil(选择器2) //JQuery 过滤
$(选择器).first()
$(选择器).last()
$(选择器).eq(index) //选中指定索引号的元素
$(选择器).filter(pattern) //返回匹配pattern的元素
$(选择器).not(pattern) //返回不匹配pattern的元素//JQuery 对象转换
$(选择器).get[0] $().[0] //JQuery->DOM
$(document.getElementById("idname")) //DOM->JQuery
Vue
html5
<!DOCTYPE HTML>
引入vue
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
vue不再和HTML直接交互。一个Vue应用会挂载到一个DOM元素上然后对其进行完全控制。
例子:DOM元素 #name
<div id='name'>
{{name}}<br/>外括号表示这是JS语句,内括号表示里面是变量.
</div><script>
//Object.freeze()会阻止响应式变化
var myname = new Vue({el: '#name', //vue对象挂载的DOM元素data: { //vue对象的属性:数据类型name: 'zhangsiqi'}
})
</script>
在控制台输入myname.name可以获得值和修改值。
指令
指令带有前缀v-,以表示它们是Vue提供的特殊attribute。
v-bind 绑定元素attribute
<div id='info'>
<span v-bind:title="infotext">
悬停显示具体信息
</span>
</div><script>
var myinfo = new Vue({el: '#info',data: {infotext: myname.name + new Date().toLocaleString()}
})
</script>
title
v-if v-for 条件与循环
<div id='if'>
<span v-if="condition == 1">
<ol><li v-for="item in items">{{item.item}}</li>
</ol>
<pre style="font-size:16px">
控制台输入myifandfor.items.push({item:'myframe'})
myifandfor.items.pop()
</pre>
</span>
<div v-else-if="condition == 2">condition=2</div>
<div v-else>条件不成立,显示失败(使用时需创建Vue实例)</div>
</div><script>
var myifandfor = new Vue({el: '#if',data: {condition: 1,items: [ {item: 'vue'}, {item: 'angular'}, {item: 'react'}]}
})
</script>
虚拟DOM
生命周期
MVVM (Model-View-ViewModel)
HTML CSS XML
HTML:超文本标记语言。
XML:可扩展标记语言。
web安全
SQL注入攻击
攻击者将SQL命令插入Web表单以提交或输入域名或页面请求的查询字符串,并最终诱使服务器执行恶意SQL命令,从而入侵数据库以执行任意查询。
SQL注入可能造成的危害:篡改网页和数据,窃取核心数据,攻击数据库所在的服务器,攻击者成为受害主机。
SQL注入的位置:
- 表单提交,主要是POST请求,也包括GET请求;
- URL参数提交,主要为GET请求参数;
- Cookie参数提交;
- HTTP请求头部的一些可修改的值,比如Referer、User_Agent等;
- 一些边缘的输入点,比如.mp3文件的一些文件信息等。
解决方式:
- 预编译的SQL(pre-statement)。所有的查询语句都使用数据库提供的参数化查询接口,参数化的语句使用参数而不是将用户输入变量嵌入到SQL语句中。
- 对进入数据库的特殊字符(’”<>&*;等)进行转义或编码转换。
- 确认每种数据的类型,比如数字型的数据就必须是数字,数据库中的存储字段必须对应为int型。
- 严格规定数据长度。
- 网站每个数据层的编码统一,建议全部使用UTF-8编码,上下层编码不一致有可能导致一些过滤模型被绕过。
- 严格限制网站用户的数据库的操作权限。
- 避免网站显示SQL错误信息,比如类型错误、字段不匹配等,防止攻击者利用这些错误信息进行一些判断。
- 在网站发布之前建议使用一些专业的SQL注入检测工具进行检测,及时修补这些SQL注入漏洞。
XSS(Cross Site Scripting,跨站脚本攻击)
XSS通过网页插入恶意脚本,即自己的网站运行了别的网站里面的代码。该漏洞发生在用户端,是指在渲染过程中发生了不在预期过程中的JavaScript代码执行。XSS通常被用于获取Cookie、以受攻击者的身份进行操作等行为。
分类:
- 反射型XSS:非持久型跨站,跨站代码一般存在于链接中,请求这样的链接时,跨站代码经过服务端反射回来,这类跨站的代码不存储到服务端(比如数据库中)。
通过URL参数直接注入,一般是使用alert来探测站点是否防御,直接攻击的使用src来引入自己的脚本。 - 储存型XSS:持久型跨站,跨站代码存储于服务端(比如数据库中)后读取时注入。
常见情况是某用户在论坛发贴,如果论坛没有过滤用户输入的Javascript代码数据,就会导致其他浏览此贴的用户的浏览器会执行发贴人所嵌入的Javascript代码。 - DOM XSS:发生在客户端DOM中的跨站漏洞,很大原因是因为客户端脚本处理逻辑导致的安全问题。
解决方式:
- 对所有输入中的script、iframe等字样进行严格的检查。
- 验证数据的类型、格式、长度、范围和内容。
- 对进入数据库的特殊字符(’”<>&*;等)进行转义或编码转换。
- 在客户端做数据的验证与过滤,在服务端进行关键的过滤步骤。
- 对输出的数据也要检查,数据库里的值有可能会在一个大网站的多处都有输出。
- 富文本:由于需要完整的HTML因此不太容易过滤,一般是按照白名单进行保留部分标签和属性来进行过滤,除了允许的标签和属性,其他的全部不允许。
- 在发布应用程序之前测试所有已知的威胁。
CSRF(Cross-Site Request Forgery,跨站伪造请求攻击)
伪装来自受信任用户的请求来利用受信任的网站。攻击者盗用了合法用户的身份,以合法用户的名义发送恶意请求。CSRF能够做的事情包括:以合法用户名义发送邮件,发消息,盗取账号,甚至于购买商品,虚拟货币转账。
造成的问题:个人隐私泄露以及财产安全。
攻击方式:
要完成一次CSRF攻击,受害者必须依次完成两个步骤:登录受信任网站A,并在本地生成Cookie。在不登出A的情况下,访问危险网站B。
用户不能保证你登录了一个网站后,不再打开一个tab页面并访问另外的网站。也不能保证关闭浏览器了后,本地的Cookie立刻过期。攻击网站,可能是一个存在其他漏洞的可信任的经常被人访问的网站。
解决方式:
从服务端进行CSRF防御:在客户端页面增加伪随机数。
- Cookie Hashing (构造加密的Cookie信息)
- 验证码 (用户每次提交的表单填写上图片中的随机字符串)
- One-Time Tokens (不同的表单包含一个不同的伪随机值)
SSRF(Server Side Request Forgery,服务端请求伪造攻击)
攻击者在未能取得服务器所有权限时,利用服务器漏洞以服务器的身份发送一条构造好的请求给服务器所在内网。SSRF攻击通常针对外部网络无法直接访问的内部系统。
SSRF可以对外网、服务器所在内网、本地进行端口扫描,攻击运行在内网或本地的应用,或者利用File协议读取本地文件。
内网服务防御相对外网服务来说一般会较弱,甚至部分内网服务为了运维方便并没有对内网的访问设置权限验证,所以存在SSRF时,通常会造成较大的危害。
攻击方式:
解决方式:
- 过滤返回的信息,如果web应用是去获取某一种类型的文件。那么在把返回结果展示给用户之前先验证返回的信息是否符合标准。
- 统一错误信息,避免用户可以根据错误信息来判断远程服务器的端口状态。
- 限制请求的端口,比如80,443,8080,8090。
- 禁止不常用的协议,仅仅允许http和https请求。可以防止类似于file:///,gopher://,ftp://等引起的问题。
- 使用DNS缓存或者Host白名单的方式。
字符串匹配算法
朴素的方法
没有数据预处理,滑动窗口只后移一位。
时间复杂度:O((n - m + 1)m)
KMP
通过消除主串指针的回溯来提高匹配的效率。
参考文章
π数组存储部分匹配值,即“前缀”和“后缀”的最长的共有元素的长度。
前缀:指除了最后一个字符以外,一个字符串的全部头部组合。
后缀:指除了第一个字符以外,一个字符串的全部尾部组合。
如下图:ababababca
a的前缀和后缀都为空集,共有元素的长度为0;
ab的前缀为a,后缀为b,共有元素的长度为0;
aba的前缀为a,ab,后缀为ba,a,共有元素的长度为1(共有a);
abab的前缀为a,ab,aba,后缀为bab,ab,b,共有元素的长度为2(共有ab);
以此类推。
部分匹配的实质:有时候,字符串头部和尾部会有重复。搜索词移动的时候可以从第一个(前缀共有部分)来到第二个(后缀共有部分)。
搜索匹配时,向后移动的位数=已匹配的字符数 - 对应的部分匹配值。
如果完成一次匹配,需要进行全部匹配,则向后移动的位数=已匹配的字符数。
数据库
B树和B+树
事务隔离级别
事务
事务:访问和更新数据库的程序执行单元。
ACID:
- Atomicity:原子性,一个事务要么完成,要么不完成。
- Consistency:一致性,事务开始和结束前后数据库的完整性不被破坏。即写入的数据符合所有预设规则。
- Isolation:隔离性,多个并发事务进行时互不影响。
- Durability:持久性,事务处理结束后对数据的操作是永久保存的。
更新丢失 脏读 不可重复读 幻读
- 更新丢失:A修改data,B也修改data,A的修改丢失。
- 脏读:A修改data,B读data,A又撤回修改,B读到脏数据。
- 不可重复读:A多次读data,B在此期间修改data,A前后读到不一样的data。
- 幻读:A按一定条件读data(比如年龄大于10的同学),B插入一条数据(新同学年龄为20),A再次按同样条件读data发现多了一条数据。
隔离级别
- 读未提交:避免更新丢失。
- 读
- 写:可以同时读。禁止同时写。
- 读提交:避免更新丢失和脏读。
- 读
- 写:禁止其他事务访问。
- 可重复读:避免更新丢失、脏读和不可重复读。
- 读:可以同时读。禁止同时写。
- 写:禁止其他事物访问。
- 序列化:避免更新丢失、脏读、不可重复读和幻读。
锁表。
范式
1范式:每个字段都是原子的(不可分割)。
2范式:非属性码(非主键)的属性必须完全依赖于主码(即主键)。
3范式:消除传递依赖。
BC范式:
4范式:
5范式:
6范式:
函数依赖:属性组A可以唯一确定属性B,那么B依赖于A,A->B,即A确定B。
完全函数依赖:属性组A中的所有属性确定B。
部分函数依赖:属性组A中的某个或某几个属性确定B。
传递函数依赖:A->B->C。
底层存储方式
索引+B+树
sql和nosql(Not Only SQL)的区别
- 存储方式
SQL数据存在特定结构的表中。
NoSQL更加灵活和可扩展,存储方式可以是JSON文档、哈希表或者其他方式。 - 表/数据集合的数据的关系
在SQL中,必须定义好表和字段结构后才能添加数据。表结构可以在被定义之后更新,但是如果有比较大的结构变更的话就会变得比较复杂。
在NoSQL中,数据可以在任何时候任何地方添加,不需要先定义表。 - 外部数据存储
SQL中如果需要增加外部关联数据的话,规范化做法是在原表中增加一个外键,关联外部数据表。
NoSQL中除了这种规范化的外部数据表做法以外,还能用非规范化方式把外部数据直接放到原数据集中,以提高查询效率。 - SQL中的JOIN查询
SQL中可以使用JOIN表链接方式将多个关系数据表中的数据用一条简单的查询语句查询出来。
NoSQL暂未提供类似JOIN的查询方式对多个数据集中的数据做查询。所以大部分NoSQL使用非规范化的数据存储方式存储数据。 - 数据耦合性
SQL中不允许删除已经被使用的外部数据,以保证数据完整性。
NoSQL中没有这种强耦合的概念,可以随时删除任何数据。 - 事务
SQL中如果多张表数据需要同批次被更新,即如果其中一张表更新失败的话其他表也不能更新成功。这种场景可以通过事务来控制,可以在所有命令完成后再统一提交事务。
NoSQL中没有事务这个概念,每一个数据集的操作都是原子级的。 - 查询性能
NoSQL中省略了JOIN查询的消耗,故理论上性能上是优于SQL的。 - 语法不同
关系数据库
关系:关系二维表。
元组:每一行记录。
属性:每一列字段。
常用sql语句
create database mydb;
drop database mydb;
use mydb;create table mytable (field1 fieldtype fieldconstrait,field2 fieldtype fieldconstrait,...
);
create table mytablecopy like mytable ;
create table newtable select * from mytable where field1 == "value";desc mytable; //查看表结构
show create table mytable; //查看建表语句
drop table mytable;alter table mytable rename mytable_newname;
alter table mytable add field fieldtype fieldconstrait; //添加字段,可用first/after函数调整字段位置
alter table mytable drop fieldname;
alter table mytable modify field1 newfieldtype newfieldconstrait;
alter table mytable change field1 newfieldname newfieldtype newfieldconstrait;
alter table mytable engine=InnoDB; //或MyISAM
alter table mytable add primary key(fieldname); //添加主键
alter table mytable drop primary key; //删除主键
alter table mytable add constraint foreignkeyname foreign key(fieldname) references mytable(primarykeyname);
alter table mytable drop foreign key foreignkeyname;
alter table mytable drop index fieldname; //删除唯一约束
alter table mytable auto_increment=n; //设置自动增长的初始位置insert into mytable (field1,field2,...) values (data1,data2,...),(data1,data2,...),(data1,data2,...),...;
insert into mytable select fieldname from tablename (查询语句);
Load data local infile '数据路径' Into table tablename Fields terminated by '分隔符' Ignored 1 lines; //加载外部数据到表update mytable set fieldname=newvalue where fieldname=rawvalue;
delete from mytable where 条件;
delete from mytable;
truncate table mytable; //删除整个表Select fieldname From tablename Where 查询条件 Group by 分组字段 Having 分组后的约束条件 Order by 排序字段 Limit 限制输出行数;SELECT DISTINCT field1,field2 FROM tablename Where "查询条件" Group by field1 Having SUM(field2)>1500 Order by field1 DESC Limit 100; //普通索引
CREATE INDEX indexName ON mytable (fieldname); //创建
CREATE TABLE mytable(ID INT NOT NULL,username VARCHAR(16) NOT NULL,INDEX [indexName] (username(length))
);
ALTER table mytable ADD INDEX indexName(fieldname); //添加,普通索引索引值可出现多次。
DROP INDEX [indexName] ON mytable; //删除//唯一索引:索引列的值必须唯一,但允许有空值。
CREATE UNIQUE INDEX indexName ON mytable (fieldname); //创建
CREATE TABLE mytable(ID INT NOT NULL,username VARCHAR(16) NOT NULL,UNIQUE [indexName] (username(length))
);
ALTER table mytable ADD UNIQUE [indexName] (fieldname); //添加//全文索引
ALTER TABLE mytable ADD FULLTEXT indexName (fieldname);SHOW INDEX FROM mytable; //显示表的索引信息
JSP
Servlet Filter Listener
Servlet
Servlet技术是在服务器端生成动态网页的一种方式。
Servlet容器是Web服务器或Java EE应用服务器的一部分。
Servlet不能独立运行,它必须被部署到Servlet容器中,由容器来实例化和调用Servlet的方法,Servlet容器在Servlet的生命周期内管理Servlet。
生命周期:
- 加载和实例化
Servlet容器负责加载和实例化Servlet。默认情况下,当第一次请求访问某个Servlet时,容器就会创建(实例化)该Servlet实例。 - 初始化
在Servlet实例化之后,容器将调用Servlet的init()方法初始化这个对象。 - 请求处理
Servlet容器调用Servlet的service()方法对请求进行处理。在service()方法中,Servlet实例通过ServletRequest对象得到客户端的相关信息和请求信息,在对请求进行处理后,调用ServletResponse对象的方法设置响应信息。 - 服务终止
当Web应用被终止,或Servlet容器终止运行,或Servlet容器重新装载Servlet的新实例时,容器就会调用实例的destroy()方法,让该实例释放它所占用的资源。
POST和GET都是向服务器提交数据,并且都会从服务器获取数据。区别:
- get
- 通过地址栏传输:get参数通过URL传递,长度受限于URL长度。只能进行URL编码(可编码的ASCII码)。
- 对于get方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(OK)并返回数据,因此get产生一个TCP数据包。
- get在浏览器回退时是无害的。
- get产生的URL地址可以被Bookmark。
- get请求会被浏览器主动cache。
- get请求参数会被完整保留在浏览器历史记录里。
- get比post更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息。
- post
- 通过报文传输:post参数放在Request body中,长度无限制。支持多种编码方式(通常为UTF-8)。
- 对于post,浏览器先发送header,服务器响应100(Continue),浏览器再发送data,服务器响应200(OK)并返回数据。因此post产生两个TCP数据包。
- post在浏览器回退时会再次提交请求。
- post产生的URL地址不可以被Bookmark。
- post请求不会被浏览器主动cache,可以手动设置。
- post中的参数不会被浏览器历史记录保留。
一个来自于客户端的Servlet请求一般按如下顺序被响应:
1)Servlet容器检测是否已经装载并创建了该Servlet的实例对象。如果是,则直接执行4),否则,执行2)。
2)装载并创建该Servlet的实例对象。
3)调用Servlet实例对象的init()方法。
4)创建一个用于封装HTTP请求消息的HttpServletRequest对象和一个代表响应消息的HttpServletResponse对象,然后调用Servlet的service()方法,并将上述请求和响应对象作为参数传递进去。
Web应用程序被停止或重新启动之前,Servlet容器将卸载Servlet,并在卸载之前调用Servlet的destroy()方法。
Servlet规定,相应客户访问特定servlet流程如下:
- 客户端发出请求。
- Servlet容器接收客户请求解析。
- Servlet容器创建一个ServletRequest对象。其中包含客户请求信息及其他关于客户的信息如请求头,请求正文,客户机的IP等。
- 容器创建一个ServletResponse对象。
- 容器调用客户请求的Servlet的service(ServletRequest, ServletResponse) 方法。
- Servlet从客户参数中获得客户请求信息。
- Servlet利用ServletResponse对象来生产相应结果。
- Servlet容器把Servlet生成的结果发给客户。
Filter
Filter是servlet 2.3 新增加的功能。Filter可认为是Servlet的一种“加强版”,它主要用于对用户请求进行预处理,以及对服务器响应进行后处理。Filter负责过滤的Web组件可以是Servlet、JSP、HTML。
作用:
- 在Servlet被调用前检查Request对象,修改请求头和请求内容。
- 在Servlet被调用后检查Response对象,修改响应头和响应内容。
Filter可拦截多个用户请求或响应,一个请求或响应也可被多个Filter拦截。拦截之后,Filter就可以进行一些通用处理:如访问权限控制、编码转换、记录日志等。
接口中的方法
- void init(FilterConfig config)
完成Filter初始化。Servlet容器创建Filter实例后调用一次Init方法。通过FilterConfig参数可读取web.xml文件中过滤器的初始化参数 - void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
完成实际的过滤操作。每次用户发送请求或向客户端发送响应时都会调用。 - void destroy()
Servlet容器在销毁Filter实例前调用该方法,释放Filter占用的资源。
FilterChain接口:定义了doFilter(ServletRequest request, ServletResponse response)方法。在进行Filter配置时,可以把多个过滤器串联组装成一条链,然后依次执行其中的doFilter()方法。FilterChain调用链中的下一个过滤器,如果没有下一个过滤器,则到达用户最终想访问的Web组件。
过滤器在web.xml中的配置
<filter><filter-name>filterName</filter-name><filter-class>className</filter-class>
</filter>
<filter-mapping><filter-name>filterName</filter-name><url-pattern>url</url-pattern>
</filter-mapping>
Listener
Listener是Servlet规范中定义的一种特殊类,用于监听ServletContext、HttpSession和ServletRequest等域对象的创建和销毁事件,它还可以监听域对象的属性发生修改的事件,可以在事件发生前或者发生后做一些必要的处理。
在Servlet中要创建Listener类首先需要新建一个类并继承相应的监听器接口,实现接口中定义的方法,然后在web.xml文件中注册相应的监听器即可。如果一个web.xml文件中注册了多个监听器,则监听器的启动顺序按照在web.xml中的注册顺序启动。如果一个web.xml文件中同时定义了Listener、Filter器和Servlet,那么web容器会先加载Listener、再加载Filter最后加载Servlet。
分类:
- 监听域对象自身的创建和销毁的事件监听器;
- 监听域对象中属性的增加和删除的事件监听器;
- 监听绑定到HttpSession域中某个对象状态的事件监听器。
xml配置
<listener><listener-class>className1</listener-class><listener-class>className2</listener-class>
</listener>
9大内置对象
- request对象
javax.servlet.httpServletRequest
该对象代表了客户端的请求信息,主要用于接受通过HTTP协议传送到服务器的数据。
作用域:一次请求。 - response对象
对客户端的响应,主要是将JSP容器处理过的对象传回到客户端。
作用域:只在JSP页面内有效。 - session对象
由服务器自动创建的与用户请求相关的对象。服务器为每个用户都生成一个session对象,用于保存该用户的信息,跟踪用户的操作状态。
session对象内部使用Map类来保存数据,因此保存数据的格式为 “Key/value”。 session对象的value可以使复杂的对象类型,而不仅仅局限于字符串类型。 - application对象
将信息保存在服务器中,直到服务器关闭,否则application对象中保存的信息会在整个应用中都有效。
与session对象相比,application对象生命周期更长,类似于系统的“全局变量”。 - out 对象
用于在Web浏览器内输出信息,并且管理应用服务器上的输出缓冲区。
在使用 out 对象输出数据时,可以对数据缓冲区进行操作,及时清除缓冲区中的残余数据,为其他的输出让出缓冲空间。
待数据输出完毕后,要及时关闭输出流。 - pageContext 对象
取得任何范围的参数,可以获取 JSP页面的out、request、reponse、session、application 等对象。
pageContext对象的创建和初始化都是由容器来完成的,在JSP页面中可以直接使用 pageContext对象。 - config 对象
取得服务器的配置信息。通过 pageConext对象的 getServletConfig() 方法可以获取一个config对象。
当一个Servlet 初始化时,容器把某些信息通过 config对象传递给这个 Servlet。
开发者可以在web.xml 文件中为应用程序环境中的Servlet程序和JSP页面提供初始化参数。 - page 对象
代表JSP本身,只有在JSP页面内才是合法的。 page隐含对象本质上包含当前 Servlet接口引用的变量,类似于Java编程中的 this 指针。 - exception 对象
显示异常信息,只有在包含 isErrorPage=“true” 的页面中才可以被使用,在一般的JSP页面中使用该对象将无法编译JSP文件。
excepation对象和Java的所有对象一样,都具有系统提供的继承结构。exception 对象几乎定义了所有异常情况。
在Java程序中,可以使用try/catch关键字来处理异常情况;
在JSP页面中出现没有捕获到的异常,就会生成 exception 对象,并把 exception 对象传送到在page指令中设定的错误页面中,然后在错误页面中处理相应的 exception 对象。
Cookie和session
HTTP协议是无状态的协议,所以服务端需要记录用户的状态时,就需要用某种机制(Session)来识具体的用户。
如购物车,当用户点击下单按钮时,由于HTTP协议无状态,并不知道是哪个用户操作的,所以服务端要为特定的用户创建特定的Session,用于标识并跟踪用户。这个Session是保存在服务端的,有一个唯一标识。
在服务端保存Session的方法有内存、数据库、文件等。
每次HTTP请求的时候,客户端都会发送相应的Cookie信息到服务端。大多数应用都是用 Cookie 来实现Session跟踪的,第一次创建Session的时候,服务端会在HTTP协议中告诉客户端,需要在 Cookie 里面记录一个Session ID,以后每次请求把这个会话ID发送到服务器,我就知道你是谁了。
如果客户端的浏览器禁用了 Cookie,会使用一种叫做URL重写的技术来进行会话跟踪,即每次HTTP交互,URL后面都会被附加上一个诸如 sid=xxxxx 这样的参数,服务端据此来识别用户。
Cookie还可以用在帮助用户存储一些信息(如使用过的用户名和密码)。
Session是在服务端保存的一个数据结构,用来跟踪用户的状态,这个数据可以保存在集群、数据库、文件中。
Cookie是客户端保存用户信息的一种机制,用来记录用户的一些信息,也是实现Session的一种方式。
ES6
ES 的全称是 ECMAScript,它是由 ECMA 国际标准化组织,制定的一项脚本语言的标准化规范。
为什么使用 ES6 ?
JS的变量提升特性增加了程序运行时的不可预测性,语法过于松散,实现相同的功能,不同的人可能会写出不同的代码。
ES6 中的类和对象
class Person {constructor(name, age) { // constructor 构造方法或者构造函数this.name = name; //constructor 里面的this指向实例对象, 方法里面的this 指向这个方法的调用者this.age = age;}say() {console.log(this.name + '你好');}
}
var ldh = new Person('刘德华', 18);
console.log(ldh.name)
ldh.say()class Man extends Person { // 子类继承父类//super 关键字用于访问和调用对象父类上的函数。
}
this
改变函数内部的this指向:
- bind():不会调用函数,但是能改变函数内部this指向。返回由指定的 this 值和初始化参数改造的原函数拷贝。bind 返回的是一个新的函数,你必须调用它才会被执行。当只想改变 this 指向并不想调用这个函数时,可以使用 bind。
- call():调用一个对象并改变函数内部this指向。返回值为对象的返回值。当想改变 this 指向的同时调用这个对象,可以使用 call,比如继承。
- apply():调用一个函数并改变函数内部this指向。返回值为函数的返回值。apply 主要跟数组有关,比如使用 Math.max() 求数组的最大值。
//thisArg:需要指向的this对象,arg:需要传递进函数的参数
fun.bind(thisArg, arg1, arg2, ...)()
fun.call(thisArg, arg1, arg2, ...)
fun.apply(thisArg, [argsArray])
对比:
- 相同点:都可以改变函数内部的this指向。
- 不同点:
- call 和 apply 会调用函数, bind 不会调用函数。
- call 和 apply 传递的参数不一样, call 传递参数 arg1, arg2…形式 apply 必须数组形式[arg]
主要应用场景:call-继承,apply-数组,如借助Math对象实现数组最大值最小值,bind-改变定时器内部的this指向。
ES6 的新增语法
- let:声明块级变量,不存在变量提升,暂时性死区(只寻找{}内的变量名)。
- const:声明常量,声明时必须赋值且之后不能修改,块级作用域。
- 解构赋值:ES6中允许从数组中提取值,按照对应位置,对变量赋值。对象也可以实现解构。如果解构不成功,变量的值为undefined。
//数组解构
let [a, b, c] = [1, 2, 3];
console.log(a)
console.log(b)
console.log(c)let [bar, foo] = [1];
//对象解构
let person = { name: 'zhangsan', age: 20 };
let { name, age } = person;
console.log(name); // 'zhangsan'
console.log(age); // 20let {name: myName, age: myAge} = person; // myName myAge 属于别名
console.log(myName); // 'zhangsan'
console.log(myAge); // 20
- 箭头函数:箭头函数不绑定this关键字,箭头函数中的this,指向的是函数定义位置的上下文this。
(参数) => {函数体}
const fn = () => {}//函数体中只有一句代码,且代码的执行结果就是返回值,可以省略大括号
const sum = (num1, num2) => num1 + num2;
//如果形参只有一个,可以省略小括号
const fn = v => v;
- 剩余参数:允许我们将一个不定数量的参数表示为一个数组。
function sum (first, ...args) {
console.log(first); // 10
console.log(args); // [20, 30]
}
sum(10, 20, 30)
- Array 的扩展方法
- 扩展运算符 … 可以将数组或者对象转为用逗号分隔的参数序列。可以应用于合并数组。可以将类数组或可遍历对象转换为真正的数组。
- 构造函数方法,Array.from():将类数组或可遍历对象转换为真正的数组。参数二作用类似于数组的map方法,用来对每个元素进行处理,将处理后的值放入返回的数组。
- 实例方法。find():用于找出第一个符合条件的数组成员,如果没有找到返回undefined。findIndex():用于找出第一个符合条件的数组成员的位置,如果没有找到返回-1。includes():表示某个数组是否包含给定的值,返回布尔值。
//...
let ary = [1, 2, 3];
console.log(...ary); // 1 2 3
//合并数组
let ary1 = [1, 2, 3];
let ary2 = [3, 4, 5];
let ary3 = [...ary1, ...ary2];let oDivs = document.getElementsByTagName('div');
oDivs = [...oDivs];//Array.from()
let arrayLike = {'0': 'a', '1': 'b', '2': 'c', length: 3};
let arr2 = Array.from(arrayLike); // ['a', 'b', 'c']let arrayLike = {"0": 1, "1": 2, "length": 2}
let newAry = Array.from(aryLike, item => item *2)//find()
let ary = [{id: 1, name: '张三'}, {id: 2, name: '李四'}];
let target = ary.find((item, index) => item.id == 2);
//findIndex()
let ary = [1, 5, 10, 15];
let index = ary.findIndex((value, index) => value > 9);
console.log(index); // 2
//includes()
[1, 2, 3].includes(2) // true
[1, 2, 3].includes(4) // false
- String 的扩展方法
- 模板字符串:反引号 ` ` 定义。模板字符串中可以解析变量(${varible}),换行,调用函数。
- 实例方法:startsWith(),endsWith(),repeat(n)
- Set:Set本身是一个构造函数,用来生成 Set 数据结构。Set函数可以接受一个数组作为参数,用来初始化。
实例方法:add(value),delete(value),has(value),clear()。
遍历:forEach
const s = new Set();
s.add(1).add(2).add(3); // 向 set 结构中添加值
s.delete(2) // 删除 set 结构中的2值
s.has(1) // 表示 set 结构中是否有1这个值 返回布尔值
s.clear() // 清除 set 结构中的所有值s.forEach(value => console.log(value))
html5
页面加载优化
只有10%-20%的最终用户响应时间花在了在从Web服务器获取HTML文档并传送到浏览器(后端)。其余的80%-90%时间花在了下载页面中的所有组件上。
优化方式:
- 1.减少HTTP请求的数量
- 图片地图
假设导航栏上有5幅图片,点击每张图片都会进入一个链接,这样五张导航的图片在加载时会产生5个HTTP请求。使用一个图片地图可以提高效率,这样就只需要一个HTTP请求。将所有点击提交到同一个url,同时提交用户点击的x、y坐标,服务器端根据坐标映射响应。
缺点:不规则形状难以确定坐标区域。 - CSS Sprites
将多个图片融合到一副图里面,然后通过CSS的一些技术布局到网页上。 - 字体图标 (font-awesome)
减少很多图片的使用,从而减少http请求。字体图标还可以通过CSS来设置颜色、大小等样式。 - 合并脚本和css文件
将多个样式表或者脚本文件合并到一个文件中,可以减少HTTP请求的数量从而缩短效应时间。
缺点:合并所有的css文件或者脚本文件可能会导致在一个页面加载时加载了多于自己所需要的样式或者脚本,对于只访问该网站一个(或几个)页面的人来说反而增加了下载量。
- 图片地图
- 2.使用CDN (Content Delivery Network, 内容分发网络)
CDN是一组分布在多个不同地理位置的Web服务器,用于更加有效地向用户发布内容。在优化性能时,向特定用户发布内容的服务器的选择基于对网络拥堵的测量。例如,CDN可能选择网络阶跃数最小的服务器,或者具有最短响应时间的服务器。
CDN还可以进行数据备份、扩展存储能力、缓存,同时有助于缓和Web流量峰值压力。
CDN的本质是缓存,它将媒体资源、动静态图片(Flash)、HTML、CSS、JS等内容缓存到距离用户更近的IDC (Internet Data Center,互联网数据中心),从而让用户进行资源共享,实现缩减站点间的响应时间等需求。
缺点:响应时间可能会受到其他网站流量的影响。CDN服务提供商在其所有客户之间共享Web服务器组。如果CDN服务质量下降了,那么你的工作质量也将下降。无法直接控制组件服务器。 - 3.添加Expires(逐渐淘汰)和Cathe-Control
添加Expires能有效的利用浏览器的缓存能力来改善页面的性能,能在后续的页面中有效避免很多不必要的Http请求,WEB服务器使用Expires头来告诉Web客户端它可以使用一个组件的当前副本,直到指定的时间为止。
例如:Expires:Thu,15 Apr 2010 20:00:00 GMT;
他告诉浏览器缓存有效性持续到2010年4月15日为止,在这个时间之内相同的请求使用缓存,这个时间之外使用http请求。
缺陷:它使用一个固定的时间,要求服务器与客户端的时钟保持严格的同步,并且这一天到来后,服务器还得重新设定新的时间。
HTTP1.1引入了Cathe-Control,它使用max-age指定组件被缓存多久,从请求开始在max-age时间内浏览器使用缓存,之外的使用请求,这样就可以消除Expires的限制。
例如:Cathe-Control:max-age=315360000
缺陷:如果在max-age时间内,服务器文件有修改,这样用户就不能第一时间获取最新的信息。
解决方式:修改请求的文件名。 - 4.压缩组件
从HTTP1.1开始,Web客户端可以通过HTTP请求中的Accept-Encoding头来表示对压缩的支持。如果Web服务器看到请求中有这个头,就会使用客户端列出来的方法中的一种来进行压缩。Web服务器通过响应中的Content-Encoding来通知Web客户端。
例如:Accept-Encoding: gzip,deflate - 5.将样式表放在头部,将脚本放在底部
减少页面首屏出现的时间,使页面内容逐步呈现。
如果样式表仍在加载,构建呈现树就是一种浪费。
js的下载和执行会阻塞DOM树的构建(严谨地说是中断了DOM树的更新)。 - 6.避免CSS表达式
一次性表达式。
用js事件处理机制来动态改变元素的样式,使函数运行次数在可控范围之内。 - 7.使用外部的JavaScript和CSS
当脚本或者样式是从外部引入的文件,浏览器就有可能缓存它们,从而在以后加载的时候能够直接使用缓存,而HTML文档的大小减小,从而提高加载速度。 - 8.减少DNS查找
当客户端DNS(浏览器和操作系统)缓存为空时,DNS查找的数量与要加载的Web页面中唯一主机名的数量相同,包括页面URL、脚本、样式表、图片、Flash对象等的主机名。减少唯一主机名的数量就可以减少DNS查找的数量。
建议将组件放到至少两个但不多于4个主机名下,减少DNS查找的同时也允许高度并行下载。 - 10.精简JavaScript和CSS
- 11.避免重定向
重定向用于将用户从一个URL重新路由到另一个URL。 - 12.删除重复脚本
- 13.配置ETag
EntityTag(实体标签)是唯一标识了一个组件的一个特定版本的字符串,是web服务器用于确认缓存组件的有效性的一种机制,通常可以使用组件的某些属性来构造它。
如果组件过期了,浏览器在重用它之前必须首先检查它是否有效。浏览器将发送一个条件GET请求到服务器,服务器判断缓存还有效,则发送一个304响应,告诉浏览器可以重用缓存组件。
服务器是根据什么判断缓存是否还有效的方式:ETag(实体标签)和最新修改日期(Last-Modified头)。
在此模式下,客户端下次获取资源时,他会分别通过If-None-Match(与ETage对应)和If-Modified-Since(与Last-Mofied对应)两个请求首部将值发送给服务器。如果服务器发现两次值都是对等的,返回一个HTTP 304。 - 14.使Ajax可缓存
GET的请求,是可以(而且默认)在客户端进行缓存的,除非指定了不同的地址,否则同一个地址的AJAX请求,不会重复在服务器执行,而是返回304。
补充:
- Cache-Control可以设置的值
private、public和no-cache(使用缓存资源之前必须经过服务器的检查):指定客户端和代理缓存的可缓存性。
max-age和s-maxage:指定客户端和代理缓存的缓存时间。
must-revalidate和proxy-revalidate:指定缓存过期后是否必须验证才能使用。
no-store:任何地方都不应该缓存内容。
其他设置。- 304状态和Cathe-Control
浏览器初次访问服务器:服务器返回200状态和请求的文件。浏览器将文件存入缓存。
浏览器再次请求服务器时,浏览器会先判断max-age,如果未到期则直接从缓存中取,否则请求服务器。服务器收到请求后,判断文件是否被修改过,若是则向浏览器返回200状态和请求的文件,否则返回304,浏览器将从缓存中获取文件。
若同步刷新页面,则浏览器并不会先判断max-age,而是直接发送请求,服务器接收到请求后,判断文件是否有变化,若有则返回200,若没有则返回304。
检测工具:
前端页面的性能测试可以使用httpwatch或者chrome自带的工具 network,可以看到页面加载的过程中比较慢的步骤。
浏览器缓存
Expires。
Cathe-Control配合Last-Modified/If-Modified-Since和Etag/If-None-Match。
为什么既有Last-Modified又有Etag:
- Last-Modified标注的最后修改只能精确到秒级,如果某些文件在1秒钟以内,被修改多次的话,它将不能准确标注文件的修改时间
- 如果某些文件会被定期生成,内容并没有任何变化,但Last-Modified却改变了,导致文件没法使用缓存
- 可能存在服务器没有准确获取文件修改时间,或者与代理服务器时间不一致等情形。
本地缓存方式
- storage
- sessionStorage
临时的会话存储,只要当前的会话窗口未关闭,存储的信息就不会丢失,即便刷新了页面或者在编辑器中更改了代码,存储的会话信息也不会丢失。 - localStorage
永久存储在客户端,数据实际是存在浏览器的文件夹下,如果不主动清除,会一直保存。
特定于页面,不是同一域名,不能访问。
有长度限制,5M左右,不同浏览器大小会有不同。
浏览器可以设置是否可以访问数据,如果设置不允许会访问失败。
兼容IE8以上浏览器。
只能存储字符串类型,需要转成字符串存储。
- sessionStorage
- cookies
cookie兼容所有的浏览器,但其存储的数据是有大小限制的,一般同源是4kb。
cookie本地存储的数据会被发送到服务器(所以建议在服务器环境下使用cookie)。
cookie有过期时间。
存在跨域访问和浪费带宽等问题。
// window.sessionStorage
// 设置值
sessionStorage.setItem("keyname", "value");
// 取值
sessionStorage.getItem("keyname");
// 删除key
sessionStorage.removeItem("keyname");
// 清除所有
sessionStorage.clear();// window.localStorage
// 浏览器是否支持localStorage
if(! window.localStorage)
// 设置值
localStorage.setItem("keyname","value");
localStorage["keyname"]="value";
localStorage.keyname="value";
// 取值
localStorage.getItem("keyname");
localStorage["keyname"];
localStorage.keyname;
// 删除key
localStorage.removeItem("keyname");
delete localStorage["keyname"];
delete localStorage.keyname;
// 获取key
for (var i=0;i<localStorage.length;i++) {console.log(localStorage.key(i));
}
for(var key in localStorage){console.log(key);
}
// 获取值
localStorage.valueOf();
// 清除所有
localStorage.clear();
// 是否存在某个key
localStorage.hasOwnProperty("keyname");// javax.servlet.http.Cookie
// 设置
Cookie c = new Cookie("keyname","value");
c.setMaxAge(24*60*60); // 设置过期时间,单位(s)
response.addCookie(c); // 保存cookie到客户端
// 删除
c.setMaxAge(0); // 设置生命周期为0,表示将要删除
response.addCookie(c); // 执行添加后就从response里删除了
// 其他设置,有对应的get方法
c.setValue("newValue"); // 更新值
c.setComment("描述信息");
c.setDomain(".google.com"); // 设置可访问域名
c.setHttpOnly(true); // 只能通过http访问,不能通过js访问,防止xss攻击
c.setPath("使用路径");
c.setSecure(true); // 服务器只能通过https访问客户端的cookie
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
相关文章
- 笔记
遍历数组的方式: 1.定义循环数组 $arr = array(website=>http://www.poluoluo.com,webname=>脚本之家) while(list($k,$v) = each($arr)){ echo $k.=>.$v.<br />; } 2.定义数组 $arr = array(http://www.poluoluo.com,脚本之家,PHP教程); foreach($arr…...
2024/4/20 16:53:48 - IDEA使用教程—2、创建一个scala程序
1. Intellij IDEA开发环境简介具体介绍请参见:http://baike.baidu.com/link?url=SBY93H3SPkmcmIOmZ8H60O1k4iVLgOmdqoKdGp9xHtU-Pbdsq2cpn75ZPZPWAJxeUlwr0ravraQzOckh777beqIntellij IDEA是我用过最好的集成开发环境,没有之一,它对于Scala的支持远胜于Scala IDE for Eclip…...
2024/4/20 16:53:47 - python爬虫的原理以及步骤-Python-爬虫的基本原理
什么是爬虫 爬虫就是请求网站并提取数据的自动化程序。其中请求,提取,自动化是爬虫的关键!下面我们分析爬虫的基本流程 爬虫的基本流程发起请求 通过HTTP库向目标站点发起请求,也就是发送一个Request,请求可以包含额外…...
2024/4/20 16:53:45 - Spring Boot篇
第一章 SpringBoot篇 Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。通过这种方式,Spring Boot致力于在…...
2024/4/20 16:53:45 - 双眼皮全切看得出吗
...
2024/4/20 1:45:14 - 双眼皮全切会不会留疤吗
...
2024/4/20 16:53:42 - 双眼皮全切后厚重
...
2024/4/20 16:53:41 - angularjs $watch监听模型变化
$watch简单使用 $watch是一个scope函数,用于监听模型变化,当你的模型部分发生变化时它会通知你。 $watch(watchExpression, listener, objectEquality); 每个参数的说明如下: watchExpression:监听的对象,它可以是一个…...
2024/4/21 8:26:56 - 双眼皮祛皮是什么原因
...
2024/4/21 11:50:38 - 双眼皮祛皮是什么意思
...
2024/4/21 11:50:36 - checkbox阻止事件
比如现在一个checkbox是checked的,此时全局变量i 2;在checkbox的click事件发生时绑定一个函数 function bind(e){var target e.target;var isChecked target.checked; //falsei;if (i 3){return fals…...
2024/4/28 0:38:15 - 自定义表单控件(基于nz-checkbox)
1.在自定义的表单组件中,需要实现ControlValueAccessor接口,这个接口的作用有两个: 将form模型中的值映射到视图中当视图发生变化时,通知form directives或form controls 在自定义的表单组件中实现ControlValueAccessor接口的方…...
2024/4/21 11:50:34 - html做出漂亮的复选框(angular)
效果 首先要准备两张svg格式的图片,分别是未选中状态和选中状态的。 icon_check.svg <?xml version"1.0" standalone"no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/…...
2024/4/21 11:50:33 - Angularjs checkbox的ng属性
本文转载自: https://www.cnblogs.com/ayseeing/p/3658273.html 作者:ayseeing 转载请注明该声明。angularjs 默认给 input[checkbox] 元素定制了一些属性,如: <input type"checkbox" ng-mudel"name" ng-…...
2024/4/21 11:50:33 - 双眼皮祛皮是什么
...
2024/4/21 11:50:32 - 双眼皮切开术后疼吗
...
2024/4/21 11:50:31 - 双眼皮切开手术要多久恢复自然
...
2024/4/27 5:31:01 - 双眼皮切开手术要多久恢复
...
2024/4/21 11:50:29 - html页面引入jquery或者vue或者angular简单学习
html引用jquery jquery获取元素:$(‘p’)...
2024/4/21 11:50:27 - jquery和vue的区别
前言:很多人说jquey和vue没有什么可比的,应该和Angular,React来比吧,我到觉得他们倒没有多大的可比性,都是基于mvvm思想设计的框架,无非就是实现的方式不一样,在不同场景下性能上会有一些差异。…...
2024/4/26 16:42:25
最新文章
- 蚂蚁面试:Springcloud核心组件的底层原理,你知道多少?
尼恩说在前面 在40岁老架构师 尼恩的读者交流群(50)中,最近有小伙伴拿到了一线互联网企业如得物、阿里、滴滴、极兔、有赞、希音、百度、网易、美团、蚂蚁、得物的面试资格,遇到很多很重要的相关面试题: 说说:蚂蚁面试࿱…...
2024/5/3 2:59:22 - 梯度消失和梯度爆炸的一些处理方法
在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言,在此感激不尽。 权重和梯度的更新公式如下: w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...
2024/3/20 10:50:27 - macU盘在电脑上读不出来 u盘mac读不出来怎么办 macu盘不能写入
对于Mac用户来说,使用U盘是很常见的操作,但有时候可能会遇到Mac电脑无法读取U盘的情况,这时候就需要使用一些特定的工具软件来帮助我们解决问题。本文就来告诉大家macU盘在电脑上读不出来是怎么回事,u盘mac读不出来怎么办。 一、m…...
2024/5/1 14:03:01 - 【Linux系列】tree和find命令
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...
2024/5/1 14:56:22 - 【外汇早评】美通胀数据走低,美元调整
原标题:【外汇早评】美通胀数据走低,美元调整昨日美国方面公布了新一期的核心PCE物价指数数据,同比增长1.6%,低于前值和预期值的1.7%,距离美联储的通胀目标2%继续走低,通胀压力较低,且此前美国一季度GDP初值中的消费部分下滑明显,因此市场对美联储后续更可能降息的政策…...
2024/5/1 17:30:59 - 【原油贵金属周评】原油多头拥挤,价格调整
原标题:【原油贵金属周评】原油多头拥挤,价格调整本周国际劳动节,我们喜迎四天假期,但是整个金融市场确实流动性充沛,大事频发,各个商品波动剧烈。美国方面,在本周四凌晨公布5月份的利率决议和新闻发布会,维持联邦基金利率在2.25%-2.50%不变,符合市场预期。同时美联储…...
2024/5/2 16:16:39 - 【外汇周评】靓丽非农不及疲软通胀影响
原标题:【外汇周评】靓丽非农不及疲软通胀影响在刚结束的周五,美国方面公布了新一期的非农就业数据,大幅好于前值和预期,新增就业重新回到20万以上。具体数据: 美国4月非农就业人口变动 26.3万人,预期 19万人,前值 19.6万人。 美国4月失业率 3.6%,预期 3.8%,前值 3…...
2024/4/29 2:29:43 - 【原油贵金属早评】库存继续增加,油价收跌
原标题:【原油贵金属早评】库存继续增加,油价收跌周三清晨公布美国当周API原油库存数据,上周原油库存增加281万桶至4.692亿桶,增幅超过预期的74.4万桶。且有消息人士称,沙特阿美据悉将于6月向亚洲炼油厂额外出售更多原油,印度炼油商预计将每日获得至多20万桶的额外原油供…...
2024/5/2 9:28:15 - 【外汇早评】日本央行会议纪要不改日元强势
原标题:【外汇早评】日本央行会议纪要不改日元强势近两日日元大幅走强与近期市场风险情绪上升,避险资金回流日元有关,也与前一段时间的美日贸易谈判给日本缓冲期,日本方面对汇率问题也避免继续贬值有关。虽然今日早间日本央行公布的利率会议纪要仍然是支持宽松政策,但这符…...
2024/4/27 17:58:04 - 【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响
原标题:【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响近日伊朗局势升温,导致市场担忧影响原油供给,油价试图反弹。此时OPEC表态稳定市场。据消息人士透露,沙特6月石油出口料将低于700万桶/日,沙特已经收到石油消费国提出的6月份扩大出口的“适度要求”,沙特将满…...
2024/4/27 14:22:49 - 【外汇早评】美欲与伊朗重谈协议
原标题:【外汇早评】美欲与伊朗重谈协议美国对伊朗的制裁遭到伊朗的抗议,昨日伊朗方面提出将部分退出伊核协议。而此行为又遭到欧洲方面对伊朗的谴责和警告,伊朗外长昨日回应称,欧洲国家履行它们的义务,伊核协议就能保证存续。据传闻伊朗的导弹已经对准了以色列和美国的航…...
2024/4/28 1:28:33 - 【原油贵金属早评】波动率飙升,市场情绪动荡
原标题:【原油贵金属早评】波动率飙升,市场情绪动荡因中美贸易谈判不安情绪影响,金融市场各资产品种出现明显的波动。随着美国与中方开启第十一轮谈判之际,美国按照既定计划向中国2000亿商品征收25%的关税,市场情绪有所平复,已经开始接受这一事实。虽然波动率-恐慌指数VI…...
2024/4/30 9:43:09 - 【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试
原标题:【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试美国和伊朗的局势继续升温,市场风险情绪上升,避险黄金有向上突破阻力的迹象。原油方面稍显平稳,近期美国和OPEC加大供给及市场需求回落的影响,伊朗局势并未推升油价走强。近期中美贸易谈判摩擦再度升级,美国对中…...
2024/4/27 17:59:30 - 【原油贵金属早评】市场情绪继续恶化,黄金上破
原标题:【原油贵金属早评】市场情绪继续恶化,黄金上破周初中国针对于美国加征关税的进行的反制措施引发市场情绪的大幅波动,人民币汇率出现大幅的贬值动能,金融市场受到非常明显的冲击。尤其是波动率起来之后,对于股市的表现尤其不安。隔夜美国股市出现明显的下行走势,这…...
2024/5/2 15:04:34 - 【外汇早评】美伊僵持,风险情绪继续升温
原标题:【外汇早评】美伊僵持,风险情绪继续升温昨日沙特两艘油轮再次发生爆炸事件,导致波斯湾局势进一步恶化,市场担忧美伊可能会出现摩擦生火,避险品种获得支撑,黄金和日元大幅走强。美指受中美贸易问题影响而在低位震荡。继5月12日,四艘商船在阿联酋领海附近的阿曼湾、…...
2024/4/28 1:34:08 - 【原油贵金属早评】贸易冲突导致需求低迷,油价弱势
原标题:【原油贵金属早评】贸易冲突导致需求低迷,油价弱势近日虽然伊朗局势升温,中东地区几起油船被袭击事件影响,但油价并未走高,而是出于调整结构中。由于市场预期局势失控的可能性较低,而中美贸易问题导致的全球经济衰退风险更大,需求会持续低迷,因此油价调整压力较…...
2024/4/26 19:03:37 - 氧生福地 玩美北湖(上)——为时光守候两千年
原标题:氧生福地 玩美北湖(上)——为时光守候两千年一次说走就走的旅行,只有一张高铁票的距离~ 所以,湖南郴州,我来了~ 从广州南站出发,一个半小时就到达郴州西站了。在动车上,同时改票的南风兄和我居然被分到了一个车厢,所以一路非常愉快地聊了过来。 挺好,最起…...
2024/4/29 20:46:55 - 氧生福地 玩美北湖(中)——永春梯田里的美与鲜
原标题:氧生福地 玩美北湖(中)——永春梯田里的美与鲜一觉醒来,因为大家太爱“美”照,在柳毅山庄去寻找龙女而错过了早餐时间。近十点,向导坏坏还是带着饥肠辘辘的我们去吃郴州最富有盛名的“鱼头粉”。说这是“十二分推荐”,到郴州必吃的美食之一。 哇塞!那个味美香甜…...
2024/4/30 22:21:04 - 氧生福地 玩美北湖(下)——奔跑吧骚年!
原标题:氧生福地 玩美北湖(下)——奔跑吧骚年!让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 啊……啊……啊 两…...
2024/5/1 4:32:01 - 扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!
原标题:扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!扒开伪装医用面膜,翻六倍价格宰客!当行业里的某一品项火爆了,就会有很多商家蹭热度,装逼忽悠,最近火爆朋友圈的医用面膜,被沾上了污点,到底怎么回事呢? “比普通面膜安全、效果好!痘痘、痘印、敏感肌都能用…...
2024/4/27 23:24:42 - 「发现」铁皮石斛仙草之神奇功效用于医用面膜
原标题:「发现」铁皮石斛仙草之神奇功效用于医用面膜丽彦妆铁皮石斛医用面膜|石斛多糖无菌修护补水贴19大优势: 1、铁皮石斛:自唐宋以来,一直被列为皇室贡品,铁皮石斛生于海拔1600米的悬崖峭壁之上,繁殖力差,产量极低,所以古代仅供皇室、贵族享用 2、铁皮石斛自古民间…...
2024/4/28 5:48:52 - 丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者
原标题:丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者【公司简介】 广州华彬企业隶属香港华彬集团有限公司,专注美业21年,其旗下品牌: 「圣茵美」私密荷尔蒙抗衰,产后修复 「圣仪轩」私密荷尔蒙抗衰,产后修复 「花茵莳」私密荷尔蒙抗衰,产后修复 「丽彦妆」专注医学护…...
2024/4/30 9:42:22 - 广州械字号面膜生产厂家OEM/ODM4项须知!
原标题:广州械字号面膜生产厂家OEM/ODM4项须知!广州械字号面膜生产厂家OEM/ODM流程及注意事项解读: 械字号医用面膜,其实在我国并没有严格的定义,通常我们说的医美面膜指的应该是一种「医用敷料」,也就是说,医用面膜其实算作「医疗器械」的一种,又称「医用冷敷贴」。 …...
2024/5/2 9:07:46 - 械字号医用眼膜缓解用眼过度到底有无作用?
原标题:械字号医用眼膜缓解用眼过度到底有无作用?医用眼膜/械字号眼膜/医用冷敷眼贴 凝胶层为亲水高分子材料,含70%以上的水分。体表皮肤温度传导到本产品的凝胶层,热量被凝胶内水分子吸收,通过水分的蒸发带走大量的热量,可迅速地降低体表皮肤局部温度,减轻局部皮肤的灼…...
2024/4/30 9:42:49 - 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...
解析如下:1、长按电脑电源键直至关机,然后再按一次电源健重启电脑,按F8健进入安全模式2、安全模式下进入Windows系统桌面后,按住“winR”打开运行窗口,输入“services.msc”打开服务设置3、在服务界面,选中…...
2022/11/19 21:17:18 - 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。
%读入6幅图像(每一幅图像的大小是564*564) f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...
2022/11/19 21:17:16 - 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...
win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面,在等待界面中我们需要等待操作结束才能关机,虽然这比较麻烦,但是对系统进行配置和升级…...
2022/11/19 21:17:15 - 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...
有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows,请勿关闭计算机”的提示,要过很久才能进入系统,有的用户甚至几个小时也无法进入,下面就教大家这个问题的解决方法。第一种方法:我们首先在左下角的“开始…...
2022/11/19 21:17:14 - win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...
置信有很多用户都跟小编一样遇到过这样的问题,电脑时发现开机屏幕显现“正在配置Windows Update,请勿关机”(如下图所示),而且还需求等大约5分钟才干进入系统。这是怎样回事呢?一切都是正常操作的,为什么开时机呈现“正…...
2022/11/19 21:17:13 - 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...
Win7系统开机启动时总是出现“配置Windows请勿关机”的提示,没过几秒后电脑自动重启,每次开机都这样无法进入系统,此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一:开机按下F8,在出现的Windows高级启动选…...
2022/11/19 21:17:12 - 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...
有不少windows10系统用户反映说碰到这样一个情况,就是电脑提示正在准备windows请勿关闭计算机,碰到这样的问题该怎么解决呢,现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法:1、2、依次…...
2022/11/19 21:17:11 - 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...
今天和大家分享一下win7系统重装了Win7旗舰版系统后,每次关机的时候桌面上都会显示一个“配置Windows Update的界面,提示请勿关闭计算机”,每次停留好几分钟才能正常关机,导致什么情况引起的呢?出现配置Windows Update…...
2022/11/19 21:17:10 - 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...
只能是等着,别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚,只能是考虑备份数据后重装系统了。解决来方案一:管理员运行cmd:net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...
2022/11/19 21:17:09 - 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?
原标题:电脑提示“配置Windows Update请勿关闭计算机”怎么办?win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢?一般的方…...
2022/11/19 21:17:08 - 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...
关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!关机提示 windows7 正在配…...
2022/11/19 21:17:05 - 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...
钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...
2022/11/19 21:17:05 - 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...
前几天班里有位学生电脑(windows 7系统)出问题了,具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面,长时间没反应,无法进入系统。这个问题原来帮其他同学也解决过,网上搜了不少资料&#x…...
2022/11/19 21:17:04 - 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...
本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法,并在最后教给你1种保护系统安全的好方法,一起来看看!电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中,添加了1个新功能在“磁…...
2022/11/19 21:17:03 - 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...
许多用户在长期不使用电脑的时候,开启电脑发现电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机。。.这要怎么办呢?下面小编就带着大家一起看看吧!如果能够正常进入系统,建议您暂时移…...
2022/11/19 21:17:02 - 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...
配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!配置windows update失败 还原更改 请勿关闭计算机&#x…...
2022/11/19 21:17:01 - 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...
不知道大家有没有遇到过这样的一个问题,就是我们的win7系统在关机的时候,总是喜欢显示“准备配置windows,请勿关机”这样的一个页面,没有什么大碍,但是如果一直等着的话就要两个小时甚至更久都关不了机,非常…...
2022/11/19 21:17:00 - 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...
当电脑出现正在准备配置windows请勿关闭计算机时,一般是您正对windows进行升级,但是这个要是长时间没有反应,我们不能再傻等下去了。可能是电脑出了别的问题了,来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...
2022/11/19 21:16:59 - 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...
我们使用电脑的过程中有时会遇到这种情况,当我们打开电脑之后,发现一直停留在一个界面:“配置Windows Update失败,还原更改请勿关闭计算机”,等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢࿰…...
2022/11/19 21:16:58 - 如何在iPhone上关闭“请勿打扰”
Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...
2022/11/19 21:16:57