关于缓存的几个关键词

缓存可以看成浏览器开辟了一个区域来放缓存的东西。有些放在内存有些放在硬盘。
从缓存返回的状态码为304。缓存分两种

强缓存:

设定一个期限,期限的重复访问都会去缓存获取,有两个字符来表示这个期限:
__http1__的是__Expires__,Expires: Wed, 22 Oct 2018 08:41:00 GMT表示资源会在 Wed, 22 Oct 2018 08:41:00 GMT 后过期,需要再次请求。
__http1.1__的是__Cache-Control__,当Cache-Control:max-age=300,表示5分钟缓存时间。还有其他几个值。直接看另外一个比较有影响的:no-cache。这个看做就是不强缓存,继续去判断协商缓存。

Cache-Control优先级高于Expires,现在基本都是http1.1,Expires也就是兼容用。

协商缓存:

首次访问资源,响应头会返回标识符(__Last-Modified/ETag__),下次访问请求头会带上标识符(__If-Modified-Since/If-None-Match__),去服务器查询是否启用缓存。也就是请求还是要发,但是至少东西是省发了。

响应头和请求头的缓存标识符字段名不一样,但值一样。

Last-Modified和If-Modified-Since,就是资源最后修改时间,发送到服务器去判断有没有更新,无则返回304。
缺点就很明显,如果文件有被打开或者别的什么改动了时间,那缓存失效。同时最低也是精确到秒,一秒内的改动判断不出来。

ETag和If-None-Match
Etag可以看成根据文件算出的哈希,唯一的,文件一改肯定就改。
缺点就是要消耗资源去计算。

当然ETag明显精度高于Last-Modified,所以优先级也是ETag高。

应用中的策略

设定一个期限很大的强缓存,如 max-age=31536000 (一年)。文件通过打包工具生成出来都带上哈希。只要文件内容不改哈希就不改,请求的地址就不改,命中强缓存。改了内容自然连请求地址都改了,就会返回新文件。

代码的角度,

看到的资料几乎都是服务端的,比如node的express可以在请求资源的返回里设置响应头

app.get('/foo.js', function (req, res) {
  res.set({
    'Content-Type': 'text/javascript',
    'Cache-Control': 'no-cache',
    'ETag': '12345'
  })
  res.sendFile('foo.js')
})

当然每个都这样搞未免太麻烦了,在静态资源那里可以统一设置

const options = {
  dotfiles: 'ignore',
  etag: false,
  extensions: ['htm', 'html'],
  index: false,
  maxAge: '1d',
  redirect: false,
  setHeaders: function (res, path, stat) {
    res.set('x-timestamp', Date.now())
  }
}

app.use(express.static('public', options))

上面是默认设置,自己也可以修改。

至于前端的设置,似乎只有

<meta http-equiv="expires" content="Wed, 20 Jun 2007 22:33:00 GMT">
<meta http-equiv="cache-control" content="no-cache">

尝试设置为强缓存好像没生效。而且这还是只是针对该份html,其他的资源似乎无能为力,可能也是了解不够。

其他

上面提到的利用打包工具来做这个哈希名字的事,首先想到的当然是webpack

module.exports = {
  output:{
    path:path.join(__dirname, '/dist/js'),
    filename: '[name].[chunkhash].js',
  }
}

都知道输出文件名字可配置成带哈希字符的,也就是上面的 [chunkhash] 部分,这里有三个值可以写:
hash、chunkhash、contenthash

__hash:__利用整个工程内容来计算,所以改一点点全部都改。
__chunkhash:__计算的单独chunk(这个是webpack的概念,相当于每个要输出的文件,一般一个entry对应一个chunk)的哈希。
__contenthash:__在使用抽离的css插件的时候,抽离的css文件会与引用它的js共用一份chunkhash,那js一改css也得改。当然反过来也是。此时用contenthash就只针对该份文件内容做哈希,就不会互相影响到了。

HTML几个资源异步属性

async

异步加载,乱序,只要它加载完了就会立刻执行。不阻塞页面解析。在window.onload前执行完。

defer

异步加载,DOMContentLoaded 事件触发之前完成,并且是安装加载顺序运行,相当于把js放在body最后。

prefetch

用于告诉浏览器,这段资源将会在未来某个导航或者功能要用到,但是本资源的下载顺序权重比较低。也就是说prefetch通常用于加速下一次导航,而不是本次的。被标记为prefetch的资源,将会被浏览器在空闲时间加载。

preload

通常用于本页面要用到的关键资源,包括关键js、字体、css文件。preload将会把资源得下载顺序权重提高,使得关键数据提前下载好,优化页面打开速度。

__注:__这个影响到浏览器下载资源的优先级,具体可参阅下这篇文章:
https://www.cnblogs.com/xiaohuochai/p/9183874.html
css的优先级居然比js高…

http协议等内容

注:资料来源于网络,省得到处找

TCP冷启动:

TCP连接有一个预热和保护的过程,先检查数据是否传送成功,一旦成功过,则慢慢加大传输速度。因此对应瞬时并发的连接,服务器的响应就会变慢。所以最好能使用一个建立好的连接,并且这个连接可以支持瞬时并发的请求。

HTTP1.1

1、长连接
在一个TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟。
一个包含有许多图像的网页文件的多个请求和应答可以在一个连接中传输,但每个单独的网页文件的请求和应答仍
然需要使用各自的连接。HTTP 1.1还允许客户端不用等待上一次请求结果返回,就可以发出下一次请求,但服务器
端必须按照接收到客户端请求的先后顺序依次回送响应结果,以保证客户端能够区分出每次请求的响应内容,这样
也显著地减少了整个下载过程所需要的时间。基于HTTP 1.1协议的客户机与服务器的信息交换过程。

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

3、节约带宽
HTTP 1.1支持只发送header信息(不带任何body信息),如果服务器认为客户端有权限请求服务器,则返回100,
否则返回401。客户端如果接受到100,才开始把请求body发送到服务器。
这样当服务器返回401的时候,客户端就可以不用发送请求body了,节约了带宽。
另外HTTP还支持传送内容的一部分。这样当客户端已经有一部分的资源后,只需要跟服务器请求另外的部分资源即可。这是支持文件断点续传的基础。

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

5、丰富报错码
在HTTP1.1中新增了24个错误状态响应码。

HTTP2.0

1、多路复用
所有的HTTP2.0通信都在一个TCP连接上完成,这个连接可以承载任意数量的双向数据流。
每个数据流以消息的形式发送,而消息由一或多个帧组成。这些帧可以乱序发送,然后再根据每个帧头部的流标识符(stream id)重新组装。

举个例子,每个请求是一个数据流,数据流以消息的方式发送,而消息又分为多个帧,帧头部记录着stream id用来标识所属的数据流,不同属的帧可以在连接中随机混杂在一起。接收方可以根据stream id将帧再归属到各自不同的请求当中去。

另外,多路复用(连接共享)可能会导致关键请求被阻塞。HTTP2.0里每个数据流都可以设置优先级和依赖,优先级高的数据流会被服务器优先处理和返回给客户端,数据流还可以依赖其他的子数据流。
可见,HTTP2.0实现了真正的并行传输,它能够在一个TCP上进行任意数量HTTP请求。而这个强大的功能则是基于“二进制分帧”的特性。

2、头部数据压缩
在HTTP1.1中,HTTP请求和响应都是由状态行、请求/响应头部、消息主体三部分组成。一般而言,消息主体都会经过gzip压缩,或者本身传输的就是压缩过后的二进制文件,但状态行和头部却没有经过任何压缩,直接以纯文本传输。随着Web功能越来越复杂,每个页面产生的请求数也越来越多,导致消耗在头部的流量越来越多,尤其是每次都要传输UserAgent、Cookie这类不会频繁变动的内容,完全是一种浪费。
HTTP1.1不支持header数据的压缩,HTTP2.0使用HPACK算法对header的数据进行压缩,这样数据体积小了,在网络上传输就会更快。

3、服务器推送
当我们对支持HTTP2.0的web server请求数据的时候,服务器会顺便把一些客户端需要的资源一起推送到客户端,免得客户端再次创建连接发送请求到服务器端获取。这种方式非常合适加载静态资源。
服务器端推送的这些资源其实存在客户端的某处地方,客户端直接从本地加载这些资源就可以了,不用走网络,速度自然是快很多的。

UDP和TCP的区别

1、连接方面区别
TCP面向连接(如打电话要先拨号建立连接)。
UDP是无连接的,即发送数据之前不需要建立连接。

2、安全方面的区别
TCP提供可靠的服务,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达。
UDP尽最大努力交付,即不保证可靠交付。

3、传输效率的区别
TCP传输效率相对较低。
UDP传输效率高,适用于对高速传输和实时性有较高的通信或广播通信。

4、连接对象数量的区别
TCP连接只能是点到点、一对一的。
UDP支持一对一,一对多,多对一和多对多的交互通信。

TCP 是面向字节流(流模式)的,UDP 是基于数据报的

MySql 基本指令

不做后端开发,不常操作数据库,很容易忘记。记录下自己用到过几条数据库命令。(持续)

连上数据库

// -u 指向用户, -p 需要密码
mysql -u root -p

显示数据库

show databases;

创建数据库

create database 数据库名字;

删除数据库

drop table 数据库名字;

选择数据库

use 数据库名字;

显示表

show tables;

创建表

create table 表名字;

删除表

drop table 表名字;

查看表结构

show create table 表名字;

查看表内容

select * from 表名字;

查看表条数

select count(*) from 表名字;

查看表索引

show index table 表名字;

清空表

truncate table 表名字;

更新数据,注意搜索的值字符串的话要加引号

update table_name set 要更新的字段=要更新的值 where 搜索的字段=搜索的值;

设置密码

// set password for 用户名@localhost = password(‘新密码’);
set password for root@localhost = password('123456');

更新数据是从另外一张表拿的值

update 表A,表B set 表A.字段A=表B.字段A where 表A.字段B=表B.字段B and 表A.字段A=字段值;

增加字段名

// 字段类型可以先看表结构参考其他字段 show create table 表名字;
alter table 表名 add 字段名 字段类型 default 默认值;