回调函数 相当于线程_阿里面试题:请简述下 Node 的线程模型

前言

如果你有一定的前端基础,比如 HTML、CSS、JavaScript、jQuery;那么,Node.js 能让你以最低的成本快速过渡成为一个全栈工程师(我称这个全栈为伪全栈,我认为的全栈也要精通数据库,不喜勿喷),从而触及后端和移动端的开发。当然,Node.js也不是万能的、也不是说学了它就可以完全取代后端的其他开发语言,它有自己的使命和擅长的应用领域。

除此之外现在非常火热的 Vue.js,React.js ,等很多数据层动态交互优先选用了Node.js,一些比较流行的打包工具也是如此;综上,为你为什么要学习它又增加了一大理由。

Node.js 和传统的后端语言(比如PHP、JAVA等)相比,各有优缺点,各自擅长领域和侧重点不同,因此,各有千秋、各有需求市场。Node.js 让我们进行后端开发多了一种便捷的手段。所以大家也不要总说哪些语言是最好的,各有各的使命,嘿嘿。

Node.js的特点

非阻塞异步io

例如,当在访问数据库取得数据的时候,需要一段时间。在传统的单线程处理机制中,在执行了访问数据库代码之后,整个线程都将暂停下来,等待数据库返回结果,才能执行后面的代码。也就是说,I/O阻塞了代码的执行,极大地降低了程序的执行效率。

由于 Node.js 中采用了非阻塞型I/O机制,因此在执行了访问数据库的代码之后,将立即转而执行其后面的代码,把数据库返回结果的处理代码放在回调函数中,从而提高了程序的执行效率。

当某个I/O执行完毕时,将以事件的形式通知执行I/O操作的线程,线程执行这个事件的回调函数。为了处理异步I/O,线程必须有事件循环,不断的检查有没有未处理的事件,依次予以处理。

阻塞模式下,一个线程只能处理一项任务,要想提高吞吐量必须通过多线程。而非阻塞模式下,一个线程永远在执行计算操作,这个线程的CPU核心利用率永远是100%。所以,这是一种特别有哲理的解决方案:与其人多,但是好多人闲着;还不如一个人玩命,往死里干活儿。

单线程

在 Java、PHP 或者 .net 等服务器端语言中,会为每一个客户端连接创建一个新的线程。而每个线程需要耗费大约2MB内存。也就是说,理论上,一个8GB内存的服务器可以同时连接的最大用户数为4000个左右。要让Web应用程序支持更多的用户,就需要增加服务器的数量,而 Web 应用程序的硬件成本当然就上升了。

Node.js不为每个客户连接创建一个新的线程,而仅仅使用一个线程。当有用户连接了,就触发一个内部事件,通过非阻塞I/O、事件驱动机制,让 Node.js 程序宏观上也是并行的。使用 Node.js ,一个8GB内存的服务器,可以同时处理超过4万用户的连接。

另外,单线程带来的好处,操作系统完全不再有线程创建、销毁的时间开销。但是单线程也有很多弊端,会在 Node.js 的弊端详细讲解,请继续看。

事件驱动

Node.js 中,客户端请求建立连接,提交数据等行为,会触发相应的事件。在 Node.js 中,在一个时刻,只能执行一个事件回调函数,但是在执行一个事件回调函数的中途,又有其他事件产生,可以转而处理其他事件(比如,又有新用户连接了),然后返回继续执行原事件的回调函数,这种处理机制,称为“事件环”机制。

Node.js 底层是 C++(V8也是C++写的)。底层代码中,近半数都用于事件队列、回调函数队列的构建。用事件驱动来完成服务器的任务调度,这是鬼才才能想到的。针尖上的舞蹈,用一个线程,担负起了处理非常多的任务的使命。

9a3a60950773e89f3223b831fd6aaf75.png

注意这里的事件循环,也可以说是 Node.js 的一个精髓所在,下面引用一段 Node.js 官网的内容

   ┌───────────────────────────┐
┌─>│ timers │
│ └─────────────┬─────────────┘
│ ┌─────────────┴─────────────┐
│ │ pending callbacks │
│ └─────────────┬─────────────┘
│ ┌─────────────┴─────────────┐
│ │ idle, prepare │
│ └─────────────┬─────────────┘ ┌───────────────┐
│ ┌─────────────┴─────────────┐ │ incoming: │
│ │ poll ││ └─────────────┬─────────────┘ │ data, etc. │
│ ┌─────────────┴─────────────┐ └───────────────┘
│ │ check │
│ └─────────────┬─────────────┘
│ ┌─────────────┴─────────────┐
└──┤ close callbacks │
└───────────────────────────┘

引用Node官网中的一段内容:

注意:每个框将被称为事件循环的“阶段”。每个阶段都有一个要执行的回调FIFO队列。虽然每个阶段都以其自己的方式特殊,但通常情况下,当事件循环进入给定阶段时,它将执行特定于该阶段的任何操作,然后在该阶段的队列中执行回调,直到队列耗尽或最大回调数量为止已执行。当队列耗尽或达到回调限制时,事件循环将移至下一阶段,依此类推。关于事件循环是一个核心点,经常会被面试官考具体执行输出的问题,大家可以看我的这篇文章

跨平台

起初,Node 只能在 Linux 平台上运行。后来随着 Node的发展,微软注意到了它的存在,并投入了一个团队帮助 Node 实现 Windows 平台的兼容,在v0.6.0版本发布时,Node 已经能够直接在 Window 平台运行了。Node 是基于libuv实现跨平台的。

Node.js的弊端

单线程带来的弊端

Node.js中有一个特点就是单线程,它带来了很多好处,但是它也有弊端,单线程弱点如下。

  1. 无法利用多核CPU
  2. 错误会引起整个应用退出无法继续调用异步I/O
  3. 大量计算占用CPU导致无法继续调用异步I/O

以上确实是Node的弊端,但是都会有一些对应的解决方案:

弊端1:解决方案

  • (1)一些管理工具比如pm2,forever 等都可以实现创建多进程解决多核 CPU 的利用率问题。
  • (2)在v0.8版本之前,实现多进程可以使用child_process
  • (3)在v0.8版本之后,可以使用cluster模块,通过主从模式,创建多个工作进程解决多核CPU的利用率问题。

弊端2:解决方案

  • (1)Nnigx反向代理,负载均衡,开多个进程,绑定多个端口;
  • (2) 一些管理工具比如pm2,forever 等都可以实现进程监控,错误自动重启等
  • (3)开多个进程监听同一个端口,使用Node提供的cluster模块;
  • (4)未出现cluster之前,也可以使用child_process,创建多子线程监听一个端口。
  • (5)这里说明下,有上面的这些解决方案,但是写node后端代码的时候,异常抛出try catch显得格外有必要。

弊端3:解决方案

  • (1)可以把大量的密集计算像上面一样拆分成多个子线程计算
  • 但是如果不允许拆分,想计算100万的大数据,在一个单线程中,Node确实显得无能为力,这本身就是V8内存限制的弊端。

说明:child_process与cluster模块我会单独拿一篇文章来讲。值得开心的是上面这些弊端随着Node的版本更新,和新的api模块出现,好像解决了这些弊端。

调试

用过node的人可能第一时间就会想到debug太难了,没有stack trace,因此调试比较困难。

Node社区中的npm包

Node.js社区有很多包品质良莠不齐、如果你想偷懒而又刚好npm了一个有问题的包你就很麻烦,因为代码是开源的,只能自己调试了。

Node.js的应用场景

介绍了Node.js的特点和弊端,再说一下Node.js的应用场景。

Node.js适合用来开发什么样的应用程序呢?

善于I/O,不善于计算。因为Node.js最擅长的就是任务调度,如果你的业务有很多的 CPU 计算,实际上也相当于这个计算阻塞了这个单线程,就不太适合Node开发,但是也不是没有解决方案,只是说不太适合。

当应用程序需要处理大量并发的I/O,而在向客户端发出响应之前,应用程序内部并不需要进行非常复杂的处理的时候,Node.js非常适合。Node.js也非常适合与websocket配合,开发长连接的实时交互应用程序。

具体场景可以表现为如下:

  • 第一大类:用户表单收集系统、后台管理系统、实时交互系统、考试系统、联网软件、高并发量的web应用程序;

  • 第二大类:基于web、canvas等多人联网游戏;

  • 第三大类:基于web的多人实时聊天客户端、聊天室、图文直播;

  • 第四大类:单页面浏览器应用程序;

  • 第五大类:操作数据库、为前端和移动端提供基于json的API;

  • 第六大类,....

更多招聘信息

扫码添加我的微信,一定要备注面试,进入面试群,或者与我交流。

b152ce6a3df8878d355934a976b7f245.png
加我微信拉你进入面试交流群

关注该公众号接收各大厂招聘信息,直达大厂负责人。如果你是技术负责人,欢迎投递内推信息。

aabe89dbf7e52616084a81e2708af1ee.png
更多大厂招聘,面试面经,技能要求,请关注公众号【互联网大厂招聘】

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/505825.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

微信小程序 本地mysql_微信小程序系列之使用缓存在本地模拟服务器数据库

微信小程序系列之使用缓存在本地模拟服务器数据库现在将data.js这个文件视作是本地数据库的初始化数据,要做的第一件事就是讲这些初始化数据装进缓存中,以形成数据库的初始化数据整个应用程序的生命周期,类比一下页面的生命周期,在…

jvm垃圾回收机制_JVM 垃圾回收机制之堆的分代回收

JVM垃圾回收机制之堆的分代回收前言前文我们了解了Java的GC机制,对于堆中的对象,JVM采用引用计数和可达性分析两种算法来标记对象是否可以清除,本文中我们还会了解到JVM将对分成了不同的区域,以便于更好的回收对象。堆的分代Java的…

roadhog不是内部或外部命令_git:git 不是内部或外部命令,也不是可运行的程序

出现git 不是内部或外部命令,也不是可运行的程序解决方案:Windows下配置Git1、从git官网下载windows版本的git:http://git-scm.com/downloads或是从该链接下载对应版本:https://github.com/git-for-windows/git/releases/tag/v2.1…

前端设定项目奖金有多少_【系列二】建筑工程项目激励模式探讨

​​建筑工程一般以项目制的形式运作,如何在这种“一次性”的组织形式下,确保项目符合质量、安全、进度等方面的要求,并确保项目的经济效益,对项目人员实施恰当的项目激励是关键。我们认为,建筑工程项目的激励主要包括…

xss过滤器无法处理ajax请求_thunkPHP 预防XSS攻击

比如在有人恶意在你的输入框中或文本域中输入<script>标签&#xff0c;如果不做处理的话&#xff0c;输入框中的<script>会保存到我们数据库中&#xff0c;等到将这个数据拿出来展示的时候&#xff0c;就等于将这个内容放入到了html代码中&#xff0c;那么这个<…

mysql bcmod_nextcloud网盘搭建:Ubuntu18.04+Nginx+Mysql

背景前几天在windows系统上搭建了一个seafile网盘服务器&#xff0c;在试用时对它的功能还是比较满意的&#xff0c;有保存文件&#xff0c;共享文件&#xff0c;小组讨论和小组文件共享等功能&#xff0c;基本上可以满足项目式学习的需求。不过在第一节课上课试用时(一个班大概…

mysql mode_MYSQL中的sql_mode模式

mysql数据库的中有一个环境变量sql_mode,定义了mysql应该支持的sql语法&#xff0c;数据校验等&#xff01;我们可以通过以下方式查看当前数据库使用的sql_mode&#xff1a;mysql>select sql_mode一&#xff0c;sql_mode值的含义ONLY_FULL_GROUP_BY对于GROUP BY聚合操作&…

汇编为什么分段执行总是执行不了_为什么我的计划总是执行不了?这里有你要的答案...

公众号配文&#xff1a;有些计划如泰山一样纹丝不动。说它难吧&#xff0c;又不是很难&#xff0c;奈何动不起来&#xff1f;——————————说起每日计划&#xff0c;很多人觉得&#xff0c;不就是写写行动清单&#xff0c;然后赶紧去做呗。不过&#xff0c;是不是有些计…

mysql unhex乱码_理解和解决MySQL乱码问题

本文将详细介绍MySQL乱码的成因和具体的解决方案在阅读本文之前&#xff0c;强烈建议对字符集编码概念还比较模糊的同学 阅读下博主之前对相关概念的一篇科普&#xff1a;十分钟搞清字符集和字符编码MySQL出现乱码的原因要了解为什么会出现乱码&#xff0c;我们就先要理解&…

单目相机 svd 从图像恢复3维位置_论文学习——VINSMono:一种鲁棒且通用的单目视觉惯性系统...

点击上方“视觉部落”&#xff0c;选择“星标”公众号精选作品&#xff0c;第一时间送达文章同步首发于知乎用户yikang专栏Part 1. 基本信息本文提出了一种基于紧耦合滑动窗口非线性优化方法的单目视觉-惯性系统&#xff0c;来自港科大沈老师实验室。这篇论文的亮点包括提出了效…

识别波峰波谷算法_马丁普林格:波峰-波谷演进法

我们有很多方法来识别趋势&#xff0c;计算机可以轻易地帮助我们实现各种复杂的想法。而在技术允许的条件下&#xff0c;我们还总是有把事物复杂化的倾向。事实也的确如此&#xff0c;目前市面上有无数复杂的方法、指标和程式化黑箱。但很显然&#xff0c;这些复杂的东西除了把…

cru使用教程_显示器刷新率超频教程

嫌显示器刷新率不够高&#xff0c;屏幕有拖影&#xff1f;打FPS游戏总是慢人一步&#xff1f;如果你正在使用的显示器面板素质不错的话&#xff0c;说不定可以将出厂标称的刷新率通过软件得到小幅度提升。此方法对于笔记本显示器有可能无效。本文仅展示在Windows 10操作系统下的…

python三方库打包项目中_将Python库打包到项目中

如果你有一个Python项目需要分发出去&#xff0c;但这个项目用了一些第三方库&#xff0c;而你又不想使用你这个项目的用户自行去安装这些库&#xff0c;这时候就很有必要将这些Python库打包到你的项目中了。下面以Faker这个库举例。1. 下载库源码: https://pypi.python.org/py…

网站本地调试工具_一款Web调试代理工具:Fiddler

前言在移动软件开发工作中&#xff0c;我们经常需要对APP软件进行调试及问题定位。在我们检查定位问题的时候&#xff0c;很多情况下需要查看接口的请求情况&#xff0c;当我们没有在调试模式的情况下&#xff0c;如何才能有效快捷的得到各个接口的请求情况呢&#xff1f;这个时…

plsql无监听程序_详细!看看顶级互联网公司都在研究的无服务器架构!

无服务器计算(Severless computing&#xff0c;简称 Serverless)现在是软件架构圈中的热门话题&#xff0c;国外三大云计算供应商(Amazon、Google 和 Microsoft)都在大力投入这个领域&#xff0c;涌现了不计其数的相关书籍、开源框架、商业产品、技术大会。到底什么是 Serverle…

sqlyog怎么连接mysql错误2003_网站突然连不上,MySQL连接错误经常内存不够宕机

阿里云服务器 MySQL 经常自动停止、挂掉、重启。打开 MySQL 的 error.log 错误信息&#xff0c;在阿里云 CentOS 的路径为 /alidata/log/mysql/error.log,如下&#xff1a;2016-03-13 00:16:37 0[Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use--e…

华为抓截屏_原来这才是华为截屏的正确姿势,今天才知道,千万别不当回事

原标题&#xff1a;原来这才是华为截屏的正确姿势&#xff0c;今天才知道&#xff0c;千万别不当回事大家都知道我们的华为手机有很多好用的功能&#xff0c;截屏就是其中一个&#xff0c;那么你知道华为手机截屏的正确姿势吗&#xff1f;今天小编就带大家一起看看吧&#xff0…

oracle和mysql通用建表语句_mysql建表语句到oracle怎么写?

mysql建表语句到oracle怎么写&#xff1f;CREATE TABLE Advertisment ( AdId int(8) NOT NULL auto_increment, AderId int(8) default NULL, AdName varchar(50) default NULL, AdKind varchar(30) default NULL, CreateMan varchar(30) default NULL, StartDate date d…

onenote快捷键_高效飞快地使用onenote快捷键:快捷键功能架构解析

默认快捷键有近200组&#xff0c;涉及到的功能如此之多&#xff0c;但真正频繁使用的&#xff0c;可能也就几十组。如何从这么多快捷键中选择出自己需要的呢&#xff1f;你需要一张功能架构参考图。1默认快捷键功能架构图官方文档已对快捷键做了初步分类&#xff0c;但比较抽象…

ueditor如何设置上传图片的高度宽度_上百张图片上传并对齐,你加班2小时没搞定,同事简单三步就完成...

Excel除了汇总数据还可以上传保存相片&#xff0c;比如我们在人力信息表中将每个人的相片放到表格里面去&#xff0c;或者我们需要将宠物对应的相片放到表格里面去&#xff0c;这就涉及到图片的批量上传以及对齐的操作。如图所示&#xff0c;我们需要将每个动物对应的图片&…