Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

20200513 #26

Open
into-piece opened this issue May 13, 2020 · 0 comments
Open

20200513 #26

into-piece opened this issue May 13, 2020 · 0 comments

Comments

@into-piece
Copy link
Owner

into-piece commented May 13, 2020

koa的洋葱模型实现

koa被认为是第二代node web framework,它最大的特点就是独特的中间件流程控制,是一个典型的洋葱模型。koa和koa2中间件的思路是一样的,但是实现方式有所区别,koa2在node7.6之后更是可以直接用async/await来替代generator使用中间件,本文以最后一种情况举例。

const Koa = require('koa');

const app = new Koa();
const PORT = 3000;

// #1
app.use(async (ctx, next)=>{
    console.log(1)
    await next();
    console.log(1)
});
// #2
app.use(async (ctx, next) => {
    console.log(2)
    await next();
    console.log(2)
})

app.use(async (ctx, next) => {
    console.log(3)
})

app.listen(PORT);
console.log(`http://localhost:${PORT}`);

当程序运行到await next()的时候就会暂停当前程序,进入下一个中间件,处理完之后才会仔回过头来继续处理。也就是说,当一个请求进入,#1会被第一个和最后一个经过,#2则是被第二和倒数第二个经过,依次类推。

实现

koa的实现有几个最重要的点

  1. context的保存和传递
  2. 中间件的管理和next的实现

当我们app.use的时候,只是把方法存在了一个数组里。

use(fn) {
    this.middleware.push(fn);
    return this;
}

服务端是如何做路由分发

  • 浏览器: hash和history api

操作系统 - 磁盘寻道调度算法

FIFO

先入先出队列(First Input First Output,FIFO)这是一种传统的按序执行方法,先进入的指令先完成并引退,跟着才执行第二条指令。

先来先服务算法(FCFS)

这是一种比较简单的磁盘调度算法。它根据进程请求访问磁盘的先后次序进行调度。此算法的优点是公平、简单,且每个进程的请求都能依次得到处理,不会出现某一进程的请求长期得不到满足的情况。此算法由于未对寻道进行优化,在对磁盘的访问请求比较多的情况下,此算法将降低设备服务的吞吐量,致使平均寻道时间可能较长,但各进程得到服务的响应时间的变化幅度较小。

最短寻道时间优先算法(SSTF),

该算法选择这样的进程,其要求访问的磁道与当前磁头所在的磁道距离最近,以使每次的寻道时间最短,该算法可以得到比较好的吞吐量,但却不能保证平均寻道时间最短。其缺点是对用户的服务请求的响应机会不是均等的,因而导致响应时间的变化幅度很大。在服务请求很多的情况下,对内外边缘磁道的请求将会无限期的被延迟,有些请求的响应时间将不可预期。

扫描算法(SCAN)(电梯调度算法)

循环扫描算法(CSCAN)

常见进程间通信(IPC)方式

  • 管道pipe
  • 有名管道FIFO
  • 消息队列MessageQueue
  • 共享存储
  • 信号量Semaphore
  • 信号Signal
  • 套接字Socket

从输入 URL 到页面渲染经历了什么

5个主要步骤

1 DNS 查询
2 TCP 连接
3 HTTP 请求即响应
4 服务器响应
5 客户端渲染

浏览器渲染分五个步骤

  1. 处理 HTML 标记并构建 DOM 树。

  2. 处理 CSS 标记并构建 CSSOM 树。

  3. 将 DOM 与 CSSOM 合并成一个渲染树。

  4. 根据渲染树来布局,以计算每个节点的几何信息。

  5. 将各个节点绘制到屏幕上。

  6. cdn解析:浏览器缓存=》本机缓存

  7. 建立tcp连接: 检查是否强缓存/协商缓存

  8. 请求资源html的解析(词法分析和语法分析

  9. css和js文件的请求和解析

  10. 构建的DOM树和cssom树结合生成render tree

构建对象模型

  1. 转换: 浏览器从磁盘或网络读取 HTML 的原始字节,并根据文件的指定编码(例如 UTF-8)将它们转换成各个字符。
  2. 令牌化: 浏览器将字符串转换成 W3C HTML5 标准规定的各种令牌,例如,“”、“”,以及其他尖括号内的字符串。每个令牌都具有特殊含义和一组规则。
  3. 词法分析: 发出的令牌转换成定义其属性和规则的“对象”。
  4. DOM 构建: 最后,由于 HTML 标记定义不同标记之间的关系(一些标记包含在其他标记内),创建的对象链接在一个树数据结构内,此结构也会捕获原始标记中定义的父项-子项关系:HTML 对象是 body 对象的父项,body 是 paragraph 对象的父项,依此类推。
    js执行,会堵塞GUI渲染线程,

渲染层合并

setTimeout setImmediate process.nextTick的区别

链接
Node.js的event loop及timer/setImmediate/nextTick

/process.nextTick

process.nextTick()方法的操作相对较为轻量,每次调用Process.nextTick()方法,只会将回调函数放入队列中,在下一轮Tick时取出执行。定时器采用红黑树的操作时间复杂度为o(lg(n)),而nextTick()的时间复杂度为o(1)。相较之下,process.nextTick()更高效。

setImmediate()方法和process.nextTick()方法十分类似,都是将回调函数延迟在下一次立即执行。

区别
1、process.nextTick中回调函数的优先级高于setImmediate
原因在于事件循环对观察者的检查是有先后顺序的,process.nextTick属于idle观察者,setImmediate属于check观察者。在每一轮循环检查中,idle观察者先于I/O观察者,I/O观察者先于check观察者。

多个process.nextTick语句总是一次执行完,多个setImmediate则需要多次才能执行完。

2、在实现上,process.nextTick的回调函数保存在一个数组中,setImmediate则保存在一个链表中

3、setImmediate可以使用clearImmediate清除,process.nextTick不能被清除。

观察者优先级

在每次轮训检查中,各观察者的优先级分别是:

idle观察者 > I/O观察者 > check观察者。

idle观察者:process.nextTick

I/O观察者:一般性的I/O回调,如网络,文件,数据库I/O等

check观察者:setImmediate,setTimeout

setTimeoout和setImmiediate谁快?

在一个异步流程里,setImmediate会比定时器先执行

同样在最外层的,需要看情况。

node.js里面setTimeout(fn, 0)会被强制改为setTimeout(fn, 1)

我们发现关键就在这个1毫秒,如果同步代码执行时间较长,进入Event Loop的时候1毫秒已经过了,setTimeout执行,如果1毫秒还没到,就先执行了setImmediate。每次我们运行脚本时,机器状态可能不一样,导致运行时有1毫秒的差距,一会儿setTimeout先执行,一会儿setImmediate先执行。但是这种情况只会发生在还没进入timers阶段的时候。

http2对比websocket

  • HTTP/2 Server Push 不能被代码使用,所以还得配合SSE(Server sent event),无论从coder还是运维的角度来看,这混搭增加了复杂度。
  • IE对http2以及SSE都支持的不好
  • HTTP/2 连接不确定性会永远保持连接,而websocket有onclose事件,对代码友好
  • 多个tab页windows页可能共用一个HTTP/2连接,你无法知道Server Push来自哪一个

vue3

  • Performance:性能更比Vue 2.0强。
  • Tree shaking support:可以将无用模块“剪辑”,仅打包需要的。
  • Composition API:组合API
  • Fragment, Teleport, Suspense:“碎片”,Teleport即Protal传送门,“悬念”
  • Better TypeScript support:更优秀的Ts支持
  • Custom Renderer API:暴露了自定义渲染API

性能:

编译模板的优化(PatchFlag:告知我们不光有TEXT变化,还有PROPS变化(id)。这样既跳出了virtual dom性能的瓶颈,又保留了可以手写render的灵活性。 等于是:既有react的灵活性,又有基于模板的性能保证。

事件监听缓存:cacheHandlers

开启cacheHandlers会自动生成并缓存一个内联函数,“神奇”的变为一个静态节点。 Ps:相当于React中useCallback自动化。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant