前端面试必会Node(一)

68

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第19天,点击查看活动详情

1.node的特点,适合做什么业务?

node是一个js运行环境,依赖于chrome的V8引擎进行解释。 特点:

  • 轻量:单线程,非阻塞I/O,事件驱动。
  • 高并发。
  • 适合I/O密集型应用
  • 无法直接渲染静态页面。
  • 要通过路由程序来指定文件进行渲染。
  • 支持单核CPU,不能充分利用cpu。
  • 可靠性低,一旦某个环节崩溃,就会造成系统崩溃。

单线程

像.Net这种服务器语言会为每一个用户单独开一个线程,线程占用服务器的内存。每个线程约占用2MB内存,4G内存的服务器可供同时最多2000人访问。

但是node让所有用户共用一条线程,当用户连接服务器之后,通过非阻塞I/O、事件驱动,让node在宏观上也是并行的。一个4G服务器最多可供2万人同时访问。

单线程的好处就是节省了在创建/销毁线程方面的开销,但是一旦一个用户造成了线程的崩溃,那么整个服务器就都崩溃了。

一个应用对应一个进程,进程就相当于在运行的程序;但是一个进程下面有多个线程,每个线程用于处理任务。

非阻塞I/O

  • 非阻塞I/O:当线程操作I/O时,将I/O操作放到回调里面,转而立即执行后面的代码。也就是异步处理I/O操作。
  • 阻塞I/O:当一个线程操作I/O时,这个线程会阻塞,等I/O操作完成后才继续执行。

事件驱动

node中,同一时刻,只能执行一个事件回调函数,这些回调一般是处理操作I/O的事件,例如数据库的读写,但是在执行这些回调时,依然可以执行其他事件,例如新用户的接入。

图片.png

显而易见,node擅长处理I/O相关的业务。又因为他是单线程,在进行大量计算时,相当于阻塞了单线程,所以不适合做需要大量计算的业务。可以做聊天类的软件。

2.commonJS中的require/exports和ES6中的import/export有什么区别

commonJS模块的重要特性是加载中执行,以及在require的时候全部执行。

ES6中的import/export最后要被编译成require/exports来执行。

3.同步和异步的区别,Node是如何解决异步问题的

同步:方法调用一旦开始,就要等到函数执行完成才会向下执行。

异步:方法调用一旦开始,就会立即返回,然后继续执行后面的程序,异步方法会在另一个队列里面,不影响程序总体的进展。

Node如何解决回调地狱的?

  1. async、await
  2. Promise
  3. 使用流程控制库:例如asyc
  4. 模块化:将回调函数转化为独立函数

4.前端渲染和后端渲染

前端渲染

拿到后端返回的JSON字符串,利用预先写好的HTML模板,将JSON字符串拼接起来,然后将模板插入到页面。

后端渲染

前端发送请求,后端直接将数据和所需要的html标签一起拼接成字符串并返回,浏览器接收到后,直接插入页面。

优缺点

  • 前端渲染的速度取决于用户的带宽和硬件配置,后端渲染取决于用户的带宽,但是后端渲染占用了服务器的资源。
  • 后端的SEO难度低于前端,因为多数浏览器不能抓取AJAX数据。
  • 前端渲染,前后端分离,效率要更高。

5.mysql和mongoDB有什么区别

mysql

  1. 关系型数据库,依据关系模型创建的数据库。
  2. 拥有体系成熟的查询语句。
  3. 在处理海量数据的时候效率会显著降慢。

mongoDB

  1. 非关系型数据库(Nosql),文档型数据库,可以存放XML,JSON,BSON类型的数据。且数据一般是键值对类型的对象。
  2. 存储方式使用的是虚拟内存和持久化。
  3. 专门的查询语句。
  4. 海量数据下,性能优越。因为将热数据存储到了物理内存中,使得热数据读写非常快。
  5. 但是无法进行关联表查询,不适合关系多的数据。

6.中间件

中间件本质就是一个函数,当一个请求到达express服务器后,可以通过next()连续调用多个中间件,从而对请求进行预处理。

图片.png

非内置的中间件通过安装后,使用require()运行。

7.为什么要使用模块化/组件化

当遵循“高内聚,低耦合”的开发规则,模块化可以使得系统的可维护性、代码的可复用性更高。

8.AMD和CMD

AMD推崇依赖前置,在定义模块时要声明其依赖的模块。

CMD推崇就近依赖,只有在用到某个模块时再去require。

9.Node如何跟mongoDB建立连接

  1. 引入 mongoose

  2. 使用 mongoose.connect()方法连接到 MongoDB 数据库

  3. 监听连接是否成功

  4. 然后通过 Node,书写接口,对数据库进行增删改查

10.require模块的加载机制

  1. 先计算模块路径
  2. 加载模块(如果模块在缓存里,就从缓存里取出来)
  3. 输出模块的exports