前言
工作一段时间后,体会到自己学的知识太零散。最近时间比较多,准备整合下大部分前端知识体系的重点难点,一方面是日后复习方便,另一方面是务实基础。
git相关
git工作区域流程
- Workspace:工作区,本地代码存放的地方,通过git clone 可将远程仓库的代码,拉到工作区。
- Index/Stage:暂存区,本地代码的改动可以通过git add/git stage暂存一个区域里面。而这些操作会被.git文件夹记录下来。.git文件夹它是 Git 用来保存元数据和对象数据库的地方。(暂存区是为commit做准备)
- Repository:本地仓库,待提交数据的区域。缓存区数据提交后传到本地仓库。
- Remote:远程仓库,用来远程托管的服务器。
- 基本的 Git 工作流程如下:
- 在工作目录中修改某些文件。
- 对修改后的文件进行快照,然后保存到暂存区域。
- 提交更新,将保存在暂存区域的文件快照永久转储到 Git 目录中。
常用的分支
- Master:主分支, 一般为稳定分支用于发稳定版本。
- Develop:开发分支,日常开发使用的分支。
- Release:即将发布的版本,从develop拉出,待测试完成后,合并回开发分支。
- Feature:新功能分支,一个新的功能对应一个版本。
- Hotfit: 需要火速处理的版本。
- Stable: 稳定版本。
git命令相关
- git stage 其实和git add同义,将文件提交到缓存区。
- git pull 等于 git merge + git fetch
- git reset、git revert 、 git checkout区别
git reset 支持三种标记:--mixed(影响缓存区和历史记录区,默认选项)、- - soft (只影响历史记录区)、--hard (影响工作区、暂存区和历史记录区)如撤回上一版本的提交(git reset --soft HEAD~)、git reset --hard HEAD~3 回退三次提交之前。
git chechout (检出分支) 操作各种分支操作
git revert 和 git reset目的一样,但是有commit的记录比较安全。不做文件上的操作。 - git rebase 操作commit(可以对某一段线性提交历史进行编辑、删除、复制、粘贴)
- git cherry-pick 摘取替换。摘取某个分支的记录替换到最新的分支
- git diff 指定文件在工作区和暂存区上差异比较。
- git tag 对git标签操作指令
- git log 日志相关
- git status 查询当前工作区所有文件的状态
- git mv 移除文件
- git stash 储藏相关指令
- git remote 仓库操作指令
- git branch 对分支操作指令
- 文件.gitignore 提交时可忽略的文件
- .git文件夹内容
hooks:存放一些shell脚本,他的实现的功能是与响应的git动作相关。当执行一些git命令的时候会触发hook。
info:存放部分信息
logs:记录提交信息
object:存放git对象,git 中的一些操作以及文件都会以 git 对象形式保存在这里,git 对象分为 BLOB,tree,commit 三种类型
refs:存放git指针信息
config:一些相关的配置信息
index:该文件 stage 暂存区信息,也就是 add 之后保存到的区域,内容包括它指向的文件的时间戳,文件名,hash值等
gitFlow、githubFlow、gitlabFlow流程标准
gitFlow
gitflow是Vincent Driessen提出的一个git的规范和流程。其实对于中小项目来说这样严格遵守gitflow是会增加开发成本的,因为其中流程复杂,工作量大。
其中gitflow常用的分支有:
- master:主分支,功能全部实现后,用于产品发布
- hotfixes:紧急分支,也称补丁分支。用于修复补丁时时候。修复完合并回相关分支
- realse: 版本分支,发新版本时,拉出来测试的一个分支。测试完毕合并回原分支
- develop:开发分支,用于日常开发。也是交互最多的一个分支。
- feature:新功能分支,主要用于新功能新需要的开发。 工作流程:
- 项目创建,从master分支上拉取devlop分支作为主开发分支。
- 根据不同的功能需求建立不同的feature分支,并分配给不同的开发人员,因为功能点互不相干,所以可进行并行开发。开发完成后合并回develop分支。
- 开发完成后从develop上拉出release分支提测,在Realease上修复完bug合并回develop。
- 上线后如果发生bug,从master拉出hotflex分支进行修复,修复完成后合并回相关分支。 (下图是整个gitflow的工作流程图)。
githubflow
githubflow是一个非常轻便的,基于分支的工作流。合适频繁发版的项目。 主要流程如下:
- 创建一个分支
- 在分支上添加新版本
- 开启一个 Pull Request
- 讨论和代码审核
- 合并分支,然后部署
其实最重要的点在从本地仓库的新分支想要合并到主仓库的时候,需要在主仓库上Open a pull request。当leader审核代码,确定无误后,才允许合并。
gitlabflow
Gitlab flow 是 Git flow 与 Github flow 的综合。它吸取了两者的优点,既有适应不同开发环境的弹性,又有单一主分支的简单和便利。它是 Gitlab.com 推荐的做法。 主要流程: 对于持续发版的项目,建议三个分支:分支、预生产分支和生产分支 Gitlab flow 的最大原则叫做”上游优先”(upsteam first),即只存在一个主分支master,它是所有其他分支的”上游”。只有上游分支采纳的代码变化,才能应用到其他分支。 对于”版本发布”的项目,建议的做法是每一个稳定版本,都要从master分支拉出一个分支,比如2-3-stable、2-4-stable等等。 详细可参考(docs.gitlab.com/ee/topics/g…
http相关内容
osi模型
1. 应用层 - 为应用服务提纲服务 - http、ftp、dns、snmp
2. 表示层 - 数据格式化、数据加密 - 无协议
3. 会话层 - 建立、管理和维护会话 - 无协议
4. 传输层 - 建立、管理和维护端到端的链接 - tcp、udp协议
5. 网络层 - ip选址及路由选择 - ip/ipv6协议
6. 数据链路层 - 提供介质访问和链路管理 - 将比特流转变为逻辑传输线路
7. 物理层 - 原始的比特流传输
tcp/ip
tcp/ip是互联网各类协议的总称,其中最有代表性的二个协议分别是TCP协议和UDP协议。
UDP协议
- UDP面向无连连,不像tcp需要三次握手,可直接发送数据。就只是在发送端给数据加一个udp表示头就发送了。
- 有单播、多播和广播的功能
- 直接面向报文
- 不可靠行
- 头部开销小,传输数据报文时是高效
- 如电话会议都是使用的udp
TCP协议
- 面向连接的可靠协议
- 连接需要三次握手(请求连接--可以连接---好我要开始连接了)
- 断开连接需要四次握手(双向请求断开,再断开 请求断开--同意--请求断开--同意)
- 面向字节流
- 一般用于文件传输
- 只能一对一通信
局域网、城域网、广域网、国际互联网
局域网
局域网(Local Area Network)是在一个局部的地理范围内(如一个学校、工厂和机关内),将各种计算机。外部设备和数据库等互相联接起来组成的计算机通信网,简称LAN。它可以通过数据通信网或专用数据电路,与远方的局域网、数据库或处理中心相连接,构成一个大范围的信息处理系统。
广域网
在一个广泛范围内建立的计算机通信网。广泛的范围是指地理范围而言,可以超越一个城市,一个国家甚至及于全球。因此对通信的要求高、复杂性也高。广域网简称WAN。
城域网
城域网,即CAN(City Area Network),是在整个城市内建设的大型网络。
国际互连网
Internet中文名也称“因特网”或“国际互联网”。是70年代有美国军方的ARPA发展而来的。是一个由各种不同类型和规模的独立运行和管理的计算机网络组成的全球范围的计算机网络。网络间可以畅通无阻地交换信息。
子网划分和子网掩码
后面有时间再回来补充
http的结构
报文结构
http的报文结构又分为请求报头和响应报头。
请求报文:请求行 + 请求头部 + 空行 + 请求体
- 请求行 = 方法 + 路径 + http版本
- 请求头部:为可配置的一些参数
- 空行:请求头之后是一个空行,通知服务器以下不再有请求头
- 请求体:post请求才有。就是请求参数 响应报文:状态行 + 响应头部 + 空行 + 响应体
请求头字段
其中authority、method、path、scheme不做赘述
accept字段:
- accept 数据格式
- accept-encoding 压缩方式
- accept-language 支持语音
- accept-charset 字符集
- content-type:传参内容格式
content-length: 传参内容的长度限制
Cache-control:缓存信息管理:no-cache 不缓存任何资源、no-store不进行缓存max-age指定大小 Connection:是否持久连接
keep-alive:每个请求/应答客户和服务器都要建立一个新的链接。当出现服务器出现后续请求时,keep-alive避免了重新建立连接。
User-agent:将浏览器以及用户代理名称传给服务器
Sec-Fetch-*:网络请求的元数据描述
响应头字段
- Access-Control-Allow-Origin/methods/max-Age/headers: 响应的资源指定共享源/请求方法/最大值/头部
- Vary:区分同样的网络请求的不同之处
- X-XSS-Protection: 用于xss攻击相关配置
请求方法
- GET: 通常用来获取资源
- HEAD: 获取资源的元信息
- POST: 提交数据,即上传数据
- PUT: 修改数据
- DELETE: 删除资源(几乎用不到)
- CONNECT: 建立连接隧道,用于代理服务器
- OPTIONS: 列出可对资源实行的请求方法,用来跨域请求(获取服务器支持的http请求方法/用来检查服务器的性能)
- TRACE: 追踪请求-响应的传输路径
http中的状态码
- 1xx代表中间状态,还需要后续操作
- 2xx代表成功状态
- 3xx代表重定向
- 4xx代表请求报文有误
- 5xx 代表服务端发送错误
其他的http内容
URI (其实大家都习惯叫它URL)
全称统一资源标识符。作用在于区分互联网上不同资源。实际上URL包括URN和URL。只不过由于URL比较普及,就默认URI为URL了。 URI = scheme(协议名) + user + post + path + query + fragment(描点)
cookie
由于http默认不需要保留状态信息,就引入了cookie,cookie本质就是浏览器里面存储了一下很小的文件。其中属性expires为过期时间,在设置的某个时间点后该cookie会失效。
作用域Domain和path二个属性给cookie绑定域名和路径,不匹配则不携带cookie。
如果前端资源地址和后端资源地址不一样则会不携带cookie做一个反向代理既可解决。安全相关如果带上secure,说明只能通过https传输。
Cookie缺点:体积小,性能缺陷,cookie紧跟域名,强制携带,且安全性差。现在大部分都是在使用localStorage和sessionStorage。
http跨域
浏览器遵循同源政策,协议、主机、端口相同则为同源,非同源站点有如下限制,不能读取修改对方dom,不能都缓存,限制xmlhttp请求。跨域请求一般会被浏览器拦截,实际上已到达客户端。
解决跨域的几种方案:
cors(跨域资源共享)就是在请求中添加请求头
- (Access-Control-Allow-Origin/methods/max-Age/headers),当请求发出去时,服务器拿到请求,回应时对应的添加Access-Control-Allow-Origin字段,如果请求不再字段范围内则浏览器拦截掉
- JSONP: 借助html中script元素的开放策略实现跨域。
- 其他方案:反向代理、websocket、postMessage
DNS协议
DNS协议提供的是一种主机名到ip地址的转换服务,就是域名系统。基于udp协议,在下面的浏览器相关内容会详细说明。
https和http的区别
- https需要协议证书,而http不需要。
- http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议。
- http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
- http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。
负载均衡
小编能力有限,给推一篇写得很好的文章瞅瞅吧(www.zhihu.com/question/61…
http1/2/3
http1.0 浏览器与服务器只能进行短暂的连接,服务器完成请求处理后立即断开 TCP 连接,服务器不跟踪每个客户也不记录过去的请求。解决方案:添加头字段 Connection: keep-alive。
http1.1改进点:持久连接、管道机制、分块传输编码 、新增几种请求方式
HTTP/2.0:采用二进制格式而非文本格式;完全多路复用,而非有序并阻塞的、只需一个连接即可实现并行;使用报头压缩,降低开销服务器推送。而它的特点为:
- 二进制协议
- 完全多路复用(多路复用的单一长连接)
- 报头压缩
- 服务器推送 http3.0特点:
- 0RTT传输层0RTT建立连接
- 真正的多路复用
- 加密认证的报文
- 向前纠错机制 具体的详细内容这边不多做概述,只做大概的总结。如果后面有时间在详细写。
短轮询、长轮询、websocket
长轮询:server收到请求后,如果存在数据就立刻响应。如果没有,则停留一段时间,一段时间后,有数据响应数据,无数据返回空。若浏览器收到的数据为空,会再次发送同样的http请求到server。
短轮询:h server 收到请求 不管是否有数据到达都直接响应http 请求。如果浏览器收到的数据为空,则隔一段时间,浏览器又会发送相同的http请求到server 以获取数据响应。
websocket:是一种在单个TCP连接上进行全双工通信的协议。客户端与服务器建立的是持久连接;它解决了http协议的被动性、http协议的无状态性/健忘性。
DOM树
在浏览器输入url会发生什么
- 在浏览器中输入url
- 浏览器会先查看缓存中是否有dns,如果没有dns会解析域名成ip给浏览器
- 浏览器拿着ip与服务器建立TCP连接
- 服务端传递数据给浏览器
- 断开TCP连接
- 浏览器处理相关数据。浏览器构建dom树 --> 构建css --> 构建reader树 --> 布局 --> 绘制
事件代理
事件代理友称事件委托,是JavaScript中常用绑定事件的常用技巧。顾名思义,“事件代理”即是把原本需要绑定在子元素的响应事件(click、keydown......)委托给父元素,让父元素担当事件监听的职务。事件代理的原理是DOM元素的事件冒泡。存在事件代理的原因是,减少浏览的dom的直接交互。
事件冒泡
事件冒泡是指一个事件触发后,会在子元素和父元素之间传播(propagation)。 事件冒泡一共分为三个阶段:
- 捕捉阶段:window从顶层传导到底层。
- 目标阶段:到目标后,触发事件。
- 冒泡阶段:从目标节点传导回windows对象。
如果在第三阶段使用stopPropagation方法,便会阻止继续传递window对像。
浏览器默认行为
许多事件会自动触发浏览器执行某些行为。
例如:
- 点击一个链接 —— 触发导航(navigation)到该 URL。
- 点击表单的提交按钮 —— 触发提交到服务器的行为。
- 在文本上按下鼠标按钮并移动 —— 选中文本。
如果我们使用 JavaScript 处理一个事件,那么我们通常不希望发生相应的浏览器行为。而是想要实现其他行为进行替代。
阻止浏览器行为,有两种方式来告诉浏览器我们不希望它执行默认行为:
- 主流的方式是使用
event
对象。有一个event.preventDefault()
方法。 - 如果处理程序是使用
on<event>
(而不是addEventListener
)分配的,那返回false
也同样有效。
页面生命周期
页面的生命周期包含三个重要事件:
-
DOMContentLoaded —— 浏览器已完全加载 HTML,并构建了 DOM 树,但像
和样式表之类的外部资源可能尚未加载完成。
-
load —— 浏览器不仅加载完成了 HTML,还加载完成了所有外部资源:图片,样式等。
-
beforeunload/unload —— 当用户正在离开页面时。 每个事件都是有用的:
-
DOMContentLoaded 事件 —— DOM 已经就绪,因此处理程序可以查找 DOM 节点,并初始化接口。
-
load 事件 —— 外部资源已加载完成,样式已被应用,图片大小也已知了。
-
beforeunload 事件 —— 用户正在离开:我们可以检查用户是否保存了更改,并询问他是否真的要离开。
-
unload 事件 —— 用户几乎已经离开了,但是我们仍然可以启动一些操作,例如发送统计数据。面生命周期
DOM 变动观察器
MutationObserver 是一个内建对象,它观察 DOM 元素,并在检测到更改时触发回调。
<!doctype html>
<body>
<div contentEditable id="elem">Click and <b>edit</b>, please</div>
<script>
let observer = new MutationObserver(mutationRecords => {
console.log(mutationRecords); // console.log(the changes)
});
// 观察除了特性之外的所有变动
observer.observe(elem, {
childList: true, // 观察直接子节点
subtree: true, // 及其更低的后代节点
characterDataOldValue: true // 将旧的数据传递给回调
});
</script>
</body>
事件循环
宏任务&微任务
宏任务(macrotask)
在ECMAScript中,macrotask也被称为task
我们可以将每次执行栈执行的代码当做是一个宏任务(包括每次从事件队列中获取一个事件回调并放到执行栈中执行), 每一个宏任务会从头到尾执行完毕,不会执行其他。 常见的宏任务有:
- 主代码块
- setTimeout
- setInterval
- requestAnimationFrame
- /O、UI 交互事件
- setImmediate(Node.js 环境)
微任务
微任务是在es6 Promise出现时,浏览器新规定的一个概念。在ECMAScript中,microtask也被称为jobs。
我们已经知道宏任务结束后,会执行渲染,然后执行下一个宏任务, 而微任务可以理解成在当前宏任务执行后立即执行的任务。常见的微任务有:
- Promise
- MutaionObserver
- process.nextTick(Node.js 环境)
- Object.observe
异步任务运行机制
在事件循环中,每一次的循环我们称为tick,而其中tick的关键点为:
- 在 tick 中选择最先进入队列的任务( oldest task ),如果有则执行(一次)
- 检查是否存在 jobs ,如果存在则不停地执行,直至清空jobs Queue
- 更新 render
- 主线程重复执行上述步骤 图解如下
相关的例子
监听div的点击
<div class="outer">
<div class="inner"></div>
</div>
<script>
let outer = document.querySelector('.outer');
let inner = document.querySelector('.inner');
new MutationObserver(function () {
console.log('mutate');
}).observe(outer, {
attributes: true,
});
function onClick() {
console.log('click');
setTimeout(function () {
console.log('timeout');
}, 0);
Promise.resolve().then(function () {
console.log('promise');
});
outer.setAttribute('data-random', Math.random());
}
inner.addEventListener('click', onClick);
outer.addEventListener('click', onClick);
</script>
<style>
.outer {
height: 200px;
width: 200px;
background: lightgray;
display: flex;
justify-content: center;
align-items: center;
}
.inner {
height: 100px;
width: 100px;
background: gray;
}
</style>
- 如果我们点击inner会发生什么呢?
- 触发事件onclike输出:click
- settimeout入宏任务队列挂起
- promise进入微任务队里挂起
- dom监听器监听到事件,进入微任务队列挂起
- primise出栈输入:promise
- 监听器出栈输出:mutate
- 父div触发onclick事件输出:click
- promise进入微任务队里挂起
- dom监听器监听到事件,进入微任务队列挂起
- primise出栈输入:promise
- 监听器出栈输出:mutate
- setimeout出栈输入:timeout 但是在不同浏览器中,可能结果不一样哦,因为浏览器内核,对异步机制有不一样的处理。
下面在举几个例子我就不一一解析了,大家自己分析判断吧
例子一:
async function one() {
console.log('1')
await two()
console.log('1 end')
}
function two() {
setTimeout(() => {
console.log('2')
})
}
one()
setTimeout(() => {
console.log('setTimeout')
})
new Promise((resolve, reject) => {
console.log('promise')
resolve()
}).then(function () {
console.log('then')
})
console.log('end')
运行结果:
总结
这一期做的比较粗糙,接下来有时间会去完善还没有完善的知识点,文章也有很不多不足的地方。
下一期将会花时间总结下:es5/6、ts、webpack相关的知识点。