理解和复习
数据结构与算法,如果你的数据结构基础很差,建议先去看一些基础教程,再转过来看。受限
的数组,怎么个受限法呢?我们后面讨论。如何确保组件内部 hooks 保存的状态之间的对应关系
这个工作交给了开发人员去保证,即你必须保证 HOOKS 的顺序严格一致,具体可以看 React 官网关于 Hooks Rule 部分。"队列"这个名称,可类比为现实生活中排队(不插队的那种)
队头阻塞
是一个专有名词,不仅仅在 HTTP 有,交换器等其他地方也都涉及到了这个问题。实际上引起这个问题的根本原因是使用了队列
这种数据结构。请求的响应
收到了,才能发送下一个请求,这个时候就发生了阻塞,并且这个阻塞主要发生在客户端。HTTP/1.0
和 HTTP/1.1
:HTTP/1.0
中每一次请求都需要建立一个 TCP 连接,请求结束后立即断开连接。HTTP/1.1
中,每一个连接都默认是长连接 (persistent connection)。对于同一个 tcp 连接,允许一次发送多个 http1.1 请求,也就是说,不必等前一个响应收到,就可以发送下一个请求。这样就解决了 http1.0 的客户端的队头阻塞,而这也就是HTTP/1.1
中管道 (Pipeline)
的概念了。http1.1 规定,服务器端的响应的发送要根据请求被接收的顺序排队
,也就是说,先接收到的请求的响应也要先发送。这样造成的问题是,如果最先收到的请求的处理时间长的话,响应生成也慢,就会阻塞已经生成了的响应的发送,这也会造成队头阻塞。可见,http1.1 的队首阻塞是发生在服务器端。HTTP/2
和 HTTP/1.1
:HTTP/1.1
中的服务端队首阻塞,HTTP/2
采用了二进制分帧
和 多路复用
等方法。HTTP/2
数据通信的最小单位。在 HTTP/1.1
中数据包是文本格式,而 HTTP/2
的数据包是二进制格式的,也就是二进制帧。HTTP/2
中,同域名下所有通信都在单个连接上完成,该连接可以承载任意数量的双向数据流。每个数据流都以消息的形式发送,而消息又由一个或多个帧组成。多个帧之间可以乱序发送,根据帧首部的流标识可以重新组装。多路复用
用以替代原来的序列和拥塞机制。在HTTP/1.1
中,并发多个请求需要多个 TCP 链接,且单个域名有 6-8 个 TCP 链接请求限制(这个限制是浏览器限制的,不同的浏览器也不一定一样)。在HTTP/2
中,同一域名下的所有通信在单个链接完成,仅占用一个 TCP 链接,且在这一个链接上可以并行请求和响应,互不干扰。"栈"这个名称,可类比于一组物体的堆叠(一摞书,一摞盘子之类的)。
我画的图没有画出执行上下文中其他部分(this 和 scope 等), 这部分是闭包的关键,而我这里不是讲闭包的,是为了讲解栈的。
社区中有很多“执行上下文中的 scope 指的是执行栈中父级声明的变量”说法,这是完全错误的, JS 是词法作用域,scope 指的是函数定义时候的父级,和执行没关系
图片来自 Lin Clark 在 ReactConf 2017 分享
虚拟执行栈
来解决这个问题,这个虚拟执行栈的底层实现就是链表。内置堆栈的同步递归模型
,变为具有链表和指针的异步模型
。Andrew 是这么说的: 如果你只依赖于 [内置] 调用堆栈,它将继续工作直到堆栈为空。
Fiber 是堆栈的重新实现,专门用于 React 组件
。 你可以将单个 Fiber 视为一个虚拟堆栈帧
。细心的朋友可能已经发现了, alternate 也是一个 fiber, 那么它是用来做什么的呢? 它其实原理有点像 git, 可以用来执行 git revert ,git commit 等操作,这部分挺有意思,我会在我的《从零开发 git》中讲解
图
,是一种无环连通图,是一种极大无环图,也是一种极小连通图。长子 + 兄弟
法,对于 你理解树这种数据结构有着很大用处, 说是一种对树的本质的更深刻的理解也不为过。所谓的前中后指的是根节点的位置,其他位置按照先左后右排列即可
。比如前序遍历就是根左右
, 中序就是左根右
,后序就是左右根
, 很简单吧?栈
来进行,可以极大减少代码量。如果使用栈来简化运算,由于栈是 FILO 的,因此一定要注意左右子树的推入顺序。
唯一
路径,路径的长度为节点所处的深度k-d 树
等。长子 + 兄弟
法,用邓老师的话说就是二叉树是多叉树的特例,但在有根且有序时,其描述能力却足以覆盖后者
。实际上, 在你使用长子 + 兄弟
法表示树的同时,进行 45 度角旋转即可。
其中序遍历的结果是一个有序数组
。 有时候我们可以利用到这个性质。树在数据结构层面构造了二分查找算法
。immutableJS
的底层就是share + tree
. 这样看的话,其实和字典树是一致的。