目录
- 怎么看nodejs可支持高并发
- 前端怎么处理文本编辑、计算,类似excel
1. 怎么看nodejs可支持高并发
nodejs的单线程架构模型
nodejs其实并不是真正的单线程架构,因为nodejs还有I/O线程存在(网络I/O、磁盘I/O),这些I/O线程是由更底层的libuv处理,这部分线程对于开发者来说是透明的。JavaScript 代码永远运行在V8上,是单线程的。
所以从开发者的角度上来看 nodejs 是单线程的。
来张网图:
注意看图的右边有个Event Loop,接下来要讲的重点
单线程架构的优势和劣势:
优势:
- 单线程就一个线程在玩,省去了线程间切换的开销
- 还有线程同步的问题,线程冲突的问题的也不需要担心
劣势:
- 劣势也很明显,现在起步都是4 核,单线程没法充分利用cpu的资源
- 单线程,一旦崩溃,应用就挂掉了,大家调试脚本也知道一旦执行过程报错了,本次调试就直接结束了
- 因为只能利用一个cpu ,一旦cpu被某个计算一直占用,cpu得不到释放,后续的请求就会一直被挂起,直接无响应了
当然这些劣势都已经有成熟的解决方案了,使用PM2管理进程,或者上K8S也可以。
核心:事件循环机制
那你个单线程怎么支持高并发呢?
核心就要在于js引擎的事件循环机制(我觉得这个开场还挺不错)
浏览器和nodejs的事件循环是稍有区别的,先给面试官简单说下事件循环的核心,执行栈、宏队列和微队列。然后重点说nodejs事件循环的差异点,因不想把两个问题混在一起,所以独立成一个问题,具体讲解大家稍微往下翻看下一个问题的解答。
给出个结论nodejs是异步非阻塞的,所以能扛住高并发
来个个栗子:
比如有个客户端请求A进来,需要读取文件,读取文件后将内容整合,最后数据返回给客户端。但在读取文件的时候另一个请求进来了,那处理的流程是怎么样的?
看图:
- 请求A进入服务器,线程开始处理该请求
- A请求需要读取文件,ok,交给文件IO处理,但是处理得比较慢,需要花3秒,这时候A请求就挂起(这个词可能不太恰当),等待通知,而等待的实现就是由事件循环机制实现的
- 在A请求等待的时候,cpu是已经被释放的,这时候B请求进来了,cpu就去处理B请求
- 两个请求间,并不存在互相竞争的状态。那什么时候会出现请求阻塞呢?涉及到大量计算的时候,因为计算是在js引擎上执行的,执行栈一直卡着,别的函数就没法执行,举个栗子,构建一个层级非常深的大对象,反复对这个这个对象JSON.parse(JSON.stringify(bigObj))
有机会的话可以给面试官扩展,同步、异步、阻塞、非阻塞这个几个概念
同步和异步关注的是消息通信机制。
- 同步:在发起一个调用后,在没有得到结果前,该调用不返回,知道调用返回,才往下执行,也就是说调用者等待被调用方返回结果。
- 异步:在发起一个调用后,调用就直接返回,不等待结果,继续往下执行,而执行的结果是由被调用方通过状态、通知等方式告知调用方,典型的异步编程模型比如 Node.js
阻塞和非阻塞,关注的是在等待结果时,线程的状态。
- 阻塞:在等待调用结果时,线程挂起了,不往下执行
- 非阻塞:与上面相反,当前线程继续往下执行
2. 前端怎么处理文本编辑、计算,类似excel
准备:
首先我们需要让一个 div 成为可编辑状态,加入contenteditable=“true” 属性即可。
<div contenteditable="true" id="rich-editor"></div>
在这样的
光标:
作为富文本编辑器,开发者需要有能力控制光标的各种状态信息,位置信息等。浏览器提供了selection对象和range对象来操作光标。
Selection对象:
Selection对象表示用户选择的文本范围或插入符号的当前位置。它代表页面中的文本选区,可能横跨多个元素。文本选区由用户拖拽鼠标经过文字而产生。
获得一个selection对象
let selection = window.getSelection();
通常情况下我们不会直接操作selection对象,而是需要操作用seleciton对象所对应的用户选择的ranges(区域),俗称“拖蓝”。获取方式如下:
let range = selection.getRangeAt(0);
由于浏览器当前可能存在多个文本选取,所以getRangeAt函数接受一个索引值。在富文本编辑其中,我们不考虑多选取的可能性。
selection对象还有两个重要的方法,addRange和removeAllRanges。分别用于向当前选取添加一个range对象和删除所有range对象。之后你会看到他们的用途。
range对象:
通过selection对象获得的range对象才是我们操作光标的重点。Range表示包含节点和部分文本节点的文档片段。初见range对象你有可能会感到陌生又熟悉,在哪儿看见过呢?作为一个前端工程师,想必你一定拜读过《javascript高级程序设计第三版》这本书。在第12.4节,作者为我们介绍了DOM2级提供的range接口,用来更好的控制页面。反正我当时看的一脸????这个有啥用,也没有这种需求啊。这里我们就大量的用到这个对象。
之后操作就是操作对象中的api。