# Troubleshooting

# CPU

# 一次只能运行一个进程,为什么可以同时播放音乐和QQ 聊天呢?

  • 多核 CPU(运行多个进程)
  • 单核 CPU (采用分时系统)

多核儿就是系统同时可以运行多个线程,比如双核可以同时执行两个线程。单核儿只能一次执行一个线程。 在 mac 运行命令,sysctl machdep.cpu,可以查看 CPU 的具体信息。

# 多核CPU

多核CPU即多个CPU组成,这些CPU集成在一个芯片里,可以通过内部总线来交互数据,共享数据,这些CPU中分配出一个独立的核执行操作系统,每个核都有自己的寄存器,alu运算单元等(这些都是封装在cpu内部的),但是一级二级缓存是共享的,这些CPU通过总线来交互数据,并且工作是并行的,资源分配是由操作系统来完成的,操作系统来决定程序cpu的控制权分配,所以一个多核cpu的工作效率大多体现在操作系统的分配上,因为一个CPU基本上可以执行很多个程序,通过PCB进程控制块的方式存储当前代码段,然后来回跳转,所以当你的CPU核过多时,操作系统在分配时可能会导致部分CPU闲置!

# 事件循环

# 为什么 JS 是单线程的,却可以实现异步操作呢?

回答:采用消息队列,即执行栈,读取任务队列-处理-读取任务队列 这样的方式。

# 分析

  • 回到 IO 编程层面,CPU 的速度远远快于磁盘、网络等 IO,因此我们要解决的问题是 CPU 高速执行能力和 IO 设备的龟速严重不匹配,因此避免因为一个 IO 操作就阻塞了当前线程,而其他需要 CPU 执行的代码就无法被当前线程执行了,所以我许必须使用多线程和多进程来并发执行代码,为多个用户服务。每个用户都会分配一个线程,如果遇到 IO 导致线程被挂起,其他用户的线程不受影响。
  • 多线程和多进程的模型虽然解决了并发问题,但是系统不能无上限地增加线程。由于系统切换线程的开销也很大,所以,一旦线程数量过多,CPU 的时间就花在线程切换上了,真正运行代码的时间就少了,结果导致性能严重下降。
  • 另一种解决 IO 问题的是异步 IO。当代码需要执行一个耗时的 IO 操作时,它只发出 IO 指令,并不等待 IO 结果,然后去执行其他代码了。一段时间后,当 IO 结果返回时,再通知 CPU 进行处理。异步 IO 模型需要一个消息循环,在消息循环中,主线程不断重复“读取信息-处理消息”这一过程。
  • 在“发出IO请求”到收到“IO完成”的这段时间里,同步IO模型下,主线程只能挂起,但异步IO模型下,主线程并没有休息,而是在消息循环中继续处理其他消息。这样,在异步IO模型下,一个线程就可以同时处理多个IO请求,并且没有切换线程的操作。对于大多数IO密集型的应用程序,使用异步IO将大大提升系统的多任务处理能力。
  • JS 的单线程可以实现异步操作也是上面的原理,异步 IO处理。JS 引擎不断执行任务队列的事件。 总结: js 解决单线程的问题:异步和开多一个线程(worker)

# 为什么 Vue nextTick 优先采用微任务来处理逻辑?

**回答:**假如现在执行到某个 task,我们改变一个数据,触发新视图,此时会响应 vue 的 nextTick 异步 dom 渲染任务,我们将此任务插进 tasks,也就是用宏任务来实现。

如果这个时候 task 里排队的队列任务很多,同时遇到比较多的微任务队列执行完,那很可能触发多次浏览器渲染,但是依旧没有执行我们真正的修改 dom 任务。

这种情况下,不仅会延迟视图更新,带来性能问题。因此failing微任务更加适合。

# Promise .then() 是什么时候被添加进微任务队列的

回答:Promise.resolve 的时候,即被添加进去。

# 执行到JS 文件内部的代码,如果涉及到操作 dom 的,是直接挂起,然后 GUI 渲染,还是说等整个 JS 文件的代码执行完成?

回答:涉及到 DOM 操作的,直接执行 GUI 渲染。

# 如何判断渲染引擎和 JS 引擎什么情况下才会空闲?它们是什么时候开始互斥?空闲时机是什么时候?

回答: JS 一直执行脚本直到执行完,而渲染引擎就马上渲染 HTML 页面,直到遇到 script 标签,执行脚本进行打断。

-默认情况下,JS 引擎执行每个 task 之间进行一次 GUI 的渲染,如果中途碰到

  • 操作 dom 的,则 JS 线程马上被挂起,进行 GUI 的更新渲染。 GUI 更新渲染时,如果这时候遇到 script 脚本时,则GUI 渲染线程会马上被挂起,而JS 引擎线程开始执行。