From e85962e530f33cf45a42e6fd557ae10c7798282e Mon Sep 17 00:00:00 2001 From: xiajieqiong Date: Mon, 22 Apr 2024 16:05:06 +0800 Subject: [PATCH] update --- docs/Knowledge/Browser.md | 163 ++++++++++++++++++++++++++++++++++ docs/Knowledge/Code.md | 136 ++++++++++++++++++++++++++++ docs/Knowledge/React.md | 57 ++++++++++++ docs/Knowledge/Security.md | 28 ++++++ docs/Knowledge/index.md | 1 + docs/TechnicalTopics/React.md | 7 -- 6 files changed, 385 insertions(+), 7 deletions(-) create mode 100644 docs/Knowledge/Browser.md create mode 100644 docs/Knowledge/Security.md diff --git a/docs/Knowledge/Browser.md b/docs/Knowledge/Browser.md new file mode 100644 index 0000000..194ccc3 --- /dev/null +++ b/docs/Knowledge/Browser.md @@ -0,0 +1,163 @@ +[[toc]] + +## Chrome 架构 + +### 进程与线程 + +每一个执行中的程序可以理解为 进程, 一个进程由多个线程组成 + +一个进程中任意一个线程出错, 就会导致整个进程出错 + +一个进程中的所有线程共享进程中的数据 + +不同进程之间的内容相互隔离 + +关闭进程时, 进程中的所有线程也会关闭 + +#### 进程 + +进程是 CPU 资源分配的最小单位 + +#### 线程 + +线程是 CPU 调度的最小单位 + +#### 区别 + +1. 进程是资源分配的最小单位,线程是程序执行的最小单位 + +2. 进程有自己的独立地址空间,每启动一个进程,系统就会为它分配地址空间,建立数据表来维护代码段、堆栈段和数据段,这种操作非常昂贵。而线程是共享进程中的数据的,使用相同的地址空间,因此 CPU 切换一个线程的花费远比进程要小很多,同时创建一个线程的开销也比进程要小很多 + +3. 线程之间的通信更方便,同一进程下的线程共享全局变量、静态变量等数据,而进程之间的通信需要以通信的方式(IPC)进行。不过如何处理好同步与互斥是编写多线程程序的难点 + +4. 但是多进程程序更健壮,多线程程序只要有一个线程死掉,整个进程也死掉了,而一个进程死掉并不会对另外一个进程造成影响,因为进程有自己独立的地址空间 + +### 单进程浏览器架构 + +进程包含 网络、插件、js 运行环境、渲染引擎等模块 + +#### 缺点 + +- 不稳定 + +一个模块的崩溃会引起整个浏览器的崩溃 + +- 不流畅 + +- 不安全 + +### 多进程浏览器架构 + +最新的 Chrome 浏览器包括:1 个浏览器(Browser)主进程、1 个 GPU 进程、1 个网络(NetWork)进程、多个渲染进程和多个插件进程 + +#### 浏览器进程 + +界面显示、用户交互、子进程管理,同时提供存储等功能 + +#### 渲染进程 + +核心任务是将 HTML、CSS 和 JavaScript 转换为用户可以与之交互的网页,排版引擎 Blink 和 JavaScript 引擎 V8 都是运行在该进程中,默认情况下,Chrome 会为每个 Tab 标签创建一个渲染进程。出于安全考虑,渲染进程都是运行在沙箱模式下 + +渲染进程中的几种线程: + +- GUI 渲染线程 +- JavaScript 引擎线程 +- 定时器触发线程 +- 事件触发线程 +- 异步 http 请求线程 + +#### GPU 进程 + +UI 界面都选择采用 GPU 来绘制 + +#### 网络进程 + +主要负责页面的网络资源加载,之前是作为一个模块运行在浏览器进程里面的,直至最近才独立出来,成为一个单独的进程 + +#### 插件进程 + +主要是负责插件的运行,因插件易崩溃,所以需要通过插件进程来隔离,以保证插件进程崩溃不会对浏览器和页面造成影响 + +## 渲染流程 + +整个渲染流程分为: 构建 DOM 树、样式计算、布局阶段、分层、绘制、分块、光栅化和合成 + +- 渲染进程将 HTML 内容转换为能够读懂的 DOM 树结构。 +- 渲染引擎将 CSS 样式表转化为浏览器可以理解的 styleSheets,计算出 DOM 节点的样式。 +- 创建布局树,并计算元素的布局信息。 +- 对布局树进行分层,并生成分层树。 +- 为每个图层生成绘制列表,并将其提交到合成线程。 +- 合成线程将图层分成图块,并在光栅化线程池中将图块转换成位图。 +- 合成线程发送绘制图块命令 DrawQuad 给浏览器进程。 +- 浏览器进程根据 DrawQuad 消息生成页面,并显示到显示器上 + +### 构建 DOM 树 + +解析 HTML 输出 DOM 树 + +1. 样式计算 + + 通过 样式表, CSS 继承规则,CSS 层叠规则 计算出每个 DOM 节点的具体样式 + + 1. 解析 CSS 文件 + + 2. 标准化样式表属性 + + 3. 计算 DOM 节点样式 + +2. 布局 + + 1. 创建布局树 + + 遍历 DOM 树中所有可见节点,并添加到布局中 + + 2. 布局计算 + + 计算节点坐标 + +3. 分层 + + 1. 拥有层叠上下文属性的元素会被提升为单独的一层 + + - position: fixed + - z-index: 2 + - filter + - opacity + + 2. 需要裁剪的地方也会被创建为图层 + +4. 图层绘制 + +5. 栅格化 + + 记录绘制顺序和绘制指令的列表 + +6. 合成与显示 + +### 渲染优化 + +#### 重排 + +布局引擎会根据各种样式计算每个盒子在页面上的大小与位置 + +元素的几何属性修改会触发浏览器重新布局 + +- 添加或删除可见的 DOM 元素 +- 元素的位置发生变化 +- 元素的尺寸发生变化(包括外边距、内边框、边框大小、高度和宽度等) +- 内容发生变化,比如文本变化或图片被另一个不同尺寸的图片所替代 +- 浏览器的窗口尺寸变化 + +#### 重绘 + +当计算好盒模型的位置、大小及其他属性后,浏览器根据每个盒子特性进行绘制 + +元素绘制属性变化, 触发重绘, 重绘省去了布局和分层阶段,执行效率高于重排 + +- 颜色的修改 +- 文本方向的修改 +- 阴影的修改 + +#### 直接合成阶段 + +无需布局和绘制, 只执行合成操作 diff --git a/docs/Knowledge/Code.md b/docs/Knowledge/Code.md index 2b06c18..8ca5caf 100644 --- a/docs/Knowledge/Code.md +++ b/docs/Knowledge/Code.md @@ -443,3 +443,139 @@ function LazyMan(name) { return new LazyManConstructor(name) } ``` + +## 排序 + +### 插入排序 + +```js +function insert(arr) { + let len = arr.length + for (let i = 0; i < len - 1; i++) { + let preIdx = i + let current = arr[i + 1] + while (preIdx >= 0 && current < arr[preIdx]) { + arr[preIdx + 1] = arr[preIdx] + preIdx-- + } + arr[preIdx + 1] = current + } + return arr +} +``` + +### 选择排序 + +```js +function selectSort(arr) { + let len = arr.length + let temp, minIdx + for (let i = 0; i < len - 1; i++) { + minIdx = i + for (let j = i + 1; j < len; j++) { + if (arr[minIdx] > arr[j]) { + minIdx = j + } + } + temp = arr[minIdx] + arr[minIdx] = arr[i] + arr[i] = temp + } + return arr +} +``` + +### 归并排序 + +```js +function mergeSort(arr) { + _mergeSort(arr, 0, arr.length - 1) +} + +function _mergeSort(arr, l, r) { + if (l < r) { + const mid = l + parseInt((r - l) / 2) + _mergeSort(arr, l, mid) + _mergeSort(arr, mid + 1, r) + _merge(arr, l, mid, r) + } +} + +function _merge(arr, l, mid, r) { + let i = l, + j = mid + 1 + let k = 0, + temp = [] + while (i <= mid && j <= r) { + if (arr[i] > arr[j]) { + temp[k++] = arr[j++] + } else { + temp[k++] = arr[i++] + } + } + + while (i <= mid) { + temp[k++] = arr[i++] + } + + while (j <= r) { + temp[k++] = arr[j++] + } + for (let i = 0; i < k; i++) { + arr[l + i] = temp[i] + } +} +``` + +### 快速排序 + +```js +function quickSort(arr) { + _quickSort(arr, 0, arr.length - 1) +} +function _quickSort(arr, l, r) { + if (l > r) return + + let left = l, + right = r + + let base = arr[left] + let temp + while (l != r) { + while (arr[r] >= base && l < r) { + r-- + } + while (arr[l] <= base && l < r) { + l++ + } + + if (l < r) { + temp = arr[l] + arr[l] = arr[r] + arr[r] = temp + } + } + arr[left] = arr[l] + arr[l] = base + _quickSort(arr, left, l - 1) + _quickSort(arr, l + 1, right) +} +``` + +### 冒泡排序 + +```js +function bubbleSort(arr) { + let len = arr.length + for (let i = 0; i < len - 1; i++) { + for (let j = 0; j < len - i; j++) { + if (arr[j] > arr[j + 1]) { + let temp = arr[j] + arr[j] = arr[j + 1] + arr[j + 1] = temp + } + } + } + return arr +} +``` diff --git a/docs/Knowledge/React.md b/docs/Knowledge/React.md index 18452f3..cdaf46e 100644 --- a/docs/Knowledge/React.md +++ b/docs/Knowledge/React.md @@ -1 +1,58 @@ [[toc]] + +## React 18 + +18 带来的更新 + +- 并发模式 +- 更新 render API +- 自动批处理 +- Suspense 支持 SSR +- startTransition +- useTransition +- useDeferredValue +- useId +- 提供给 第三方库的 Hook + +## JSX + +JSX 是 JS 语法的扩展, 可以编写 类 HTML 的代码 + +提高了代码可读性与开发效率 + +## 生命周期 + +## 合成事件 + +React 在内部对事件做了统一的处理 + +1. 合成事件抹平了浏览器兼容性差异 +2. React 通过顶层监听的形式,通过事件委托的方式来统一管理所有的事件,可以在事件上区分事件优先级 + +## React Hooks + +## fiber 架构 + +## React 错误捕获 + +## diff 算法 + +计算出 Virtual DOM 中真正变化的部分,并只针对该部分进行原生 DOM 操作,而非重新渲染整个页面 + +### tree diff + +两棵树只对同一层级节点进行比较,只要该节点不存在了,那么该节点与其所有子节点会被完全删除,不在进行进一步比较 +只需要遍历一次,便完成对整个 DOM 树的比较 + +### component diff + +同类型组件,组件 A 转化为了组件 B,如果 virtual DOM 无变化,可以通过 shouldComponentUpdate()方法优化 +不同类型的组件,那么 diff 算法会把要改变的组件判断为 dirty component,从而替换整个组件的所有节点 + +### element diff + +key 往前移动的节点不进行任何操作,所以当把最后一个节点移动到头部时,性能损耗最大 + +- 插入: 新的组件不在原来的集合中,而是全新的节点,则对集合进行插入操作 +- 删除: 组件已经在集合中,但集合已经更新,此时节点就需要删除 +- 移动: 组件已经存在于集合中,并且集合更新时,组件并没有发生更新,只是位置发生改变(同一层的节点添加唯一 key 进行区分,并且移动,当新集合中位置在旧集合之后时,需要移动) diff --git a/docs/Knowledge/Security.md b/docs/Knowledge/Security.md new file mode 100644 index 0000000..17d84fc --- /dev/null +++ b/docs/Knowledge/Security.md @@ -0,0 +1,28 @@ +[[toc]] + +## XSS + +浏览器渲染整个 HTML 文档的过程中出现了不被预期的脚本指令执行 + +### 存储型 XSS + +前端提交的数据未经处理存储到数据库,在读取返回到页面上时引发问题,比如执行 js 代码 + +### 反射型 XSS + +发出请求时,XSS 代码作为输入提交到服务端,服务端解析后返回这段 XSS 代码,最后浏览器解析执行 + +### DOM 型 XSS + +### 防范 + +1. 转译特殊字符 + +## CSRF + +一种诱骗受害者提交恶意请求的攻击,攻击者盗用了你的身份,以你的名义发送恶意请求,请求到达后端时,服务器将无法区分恶意请求和合法请求。CSRF 能够做的事情包括:以你名义发送邮件,发消息,盗取你的账号,甚至于购买商品,虚拟货币转账等。 + +### 防范 + +1. 同源检测,禁止外域的请求 +2. CSRF token,服务端校验 token diff --git a/docs/Knowledge/index.md b/docs/Knowledge/index.md index d656f7d..e4b1ffe 100644 --- a/docs/Knowledge/index.md +++ b/docs/Knowledge/index.md @@ -4,4 +4,5 @@ - [Js](./Js.html) - [调试](./Debugger.html) - [React](./React.html) +- [浏览器](./Browser.html) - [其他](./Other.html) diff --git a/docs/TechnicalTopics/React.md b/docs/TechnicalTopics/React.md index 47d16e1..f1a7629 100644 --- a/docs/TechnicalTopics/React.md +++ b/docs/TechnicalTopics/React.md @@ -1,12 +1,5 @@ [[toc]] -## 合成事件 - -React 在内部对事件做了统一的处理 - -1. 合成事件抹平了浏览器兼容性差异 -2. React 通过顶层监听的形式,通过事件委托的方式来统一管理所有的事件,可以在事件上区分事件优先级 - ## 架构模型 ### Scheduler 调度器