nodeJS常见问题
- node的特点
- 异步IO
- 单线程
- 跨平台
- 前后端编程语言的统一
- 工具类应用
- 单线程的缺点
- 无法利用多核CPU
- 错误会引起整个应用的退出
- 大量计算占用CPU无法继续调用异步IO
- 解决方案:
- node提供了子进程的概念
- 对于javascript自身而言,它的规范依然包若,还有以下的缺陷
- 没有模块系统
- 标准库较少
- 没有标准接口
- 缺乏包管理系统
为什么javaScript是单线程
js语言的一大特点就是单线程,也就是说,同一个时间只能做一件事。
javascript的单线程,与他的用途有关,作为浏览器脚本语言,js的主要用途是用于交互,以及操作DOM元素。
这决定了他只能是单线程,否则,会带来很复杂的同步问题!
所以为了避免复杂性,js从一诞生,就是单线程,已经成了这门语言的核心特征。
EventLoop
主线程从”任务队列”中读取事件,这个过程是循环不断的,所以整个的这种运行机制又称为Event Loop(事件循环)。
Libuv
什么是Libuv?Libuv是一个高性能的,事件驱动的I/O库,并且提供了 跨平台(如windows, nix)的API。简单的来说:
Node.js的异步、非阻塞I/O,底层实际上是Libuv实现的。
Node 的模块实现
Node在实现中并非完全按照实现,尽管规范中 exports,require和module 听起来十分简单,但是node在实现他们的过程中经历了。
- 在node中引入模块,需要经历如下3个步骤
- 路径分析
- 文件定位
- 编译执行
- 在node中,模块分为两类:一类是node提供的模块,称为核心模块;
- 另一类是用户编写的模块,称为文件模块
- 简洁以下 以上的问题
- 核心模块(node自身的)
- 文件模块
node 的模块会优先从缓存加载
NODE.js的运行机制
- V8引擎解析Javascript脚本
- 解析后的代码,调用NODE API
- libuv库负责Node API的执行。它将不同的任务分配给不同的线程,形成一个Event Loop(事件循环),以异步的方式将任务的执行结果返回给V8引擎。
- V8引擎再将结果返回
模块编译过程总结
核心模块编译过程中经过了头尾包装的过程
有些模块是C++来编写,有些则是由C++完成核心部分,其他部分择优javascript实现包装或向外导出。
内建模块的优势
- 本身是由C/C++编写,性能上高于脚本语言
- 在文件被编译时,它被编译成二进制文件,一旦node执行,在直接被加载进内存中。
前后端模块的侧重点
前后端javascript分别搁置在HTTP的两端,它们扮演的角色并不同。浏览器端的Javascript需要经历从同一个服务器端分发到多个客户端执行,而服务端的javascript则是相同的代码多次执行,前者的瓶颈在于带宽,后者的瓶颈在于CPU和内存等资源。
前者需要通过网络加载代码,后者从磁盘中加载,两者的加载不在一个数量级上。
异步IO小结
从前面实现的异步IO过程描述中,我们可以提取出几个异步IO的关键字
- 单线程
- 事件循环
- 观察者
- IO线程池
在node中,除了JavaScript是单线程外,node自身其实是多线程
除了用户的代码无法并行执行外,所有的IO操作则是可以并行起来的
总结
时间循环是异步实现的核心,它与浏览器中的执行模型基本保持了一致。
NODE与v8
v8的内存限制
- 在node中通过javascript使用内存时,只能使用部分内存
- 64位操作系统 1.4GB
- 32位操作系统0.7gb
- 这导致node无法直接操作大内存对象
- node在启动时,可以打开内存限制
网络编程
NODE提供了net,dgram,http,https 着4个模块,分别用于处理TCP,UDP,HTTP,HTTPS适用于服务端和客户端
TCP
TCP名为传输控制协议,在OSI模型(由七层组成,物理层,数据链结层,网络层,传输层,会话层,表示层,应用层)
TCP是面向连接的协议,最显著地特征就是需要三次握手形成会话,只有会话形成后,服务端与客户端才能进行互相的发送数据
内存泄漏
- 用户服务异常
- 进程异常
- 服务器性能异常
事物(ACID)
数据库事物的四大特性
- 原子性 atomicity
- 原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚。
- 这样避免中间某一部分操作失败不会对数据库造成影响
- 一致性 consistency
- 事务执行之前和执行之后都必须处于一致性的状态
- 拿转账来说,假设用户A和用户B两者的钱加起来一共是5000,那么不管A和B之间如何转账,转几次账,事务结束后两个用户的钱相加起来应该还得是5000,这就是事务的一致性。
- 隔离性 isolation
- 隔离性是当多个用户并发访问数据库,操作数据库,比如操作同一张表,数据库为每个用户开启的事物,不能被其他事物打扰,多个并发事物之间相互隔离
- 持久性 DURability
- 持久性是指一个事务一旦被提交了,那么对数据库中的数据的改变就是永久性的,即便是在数据库系统遇到故障的情况下也不会丢失提交事务的操作。
事物
- 脏读
- 服务A读取了事物B更新的数据,然后B回滚操作,那么A读取到的数据是脏数据
- 不可重复读
- 事物 A 多次读取统一数据 事物 B 在事物A多次读取的过程中,对数据做了更新并提交,导致事物A多次读取统一数据时,结果不一致
- 虚读
- 系统管理员A将数据库中所有学生的成绩从具体分数改为ABCDE等级,但是系统管理员B就在这个时候插入了一条具体分数的记录,当系统管理员A改结束后发现还有一条记录没有改过来,就好像发生了幻觉一样,这就叫幻读。
事务隔离级别
事物隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
读未提交 | 是 | 是 | 是 |
不可重复读 | 否 | 是 | 是 |
可重复读 | 否 | 否 | 是 |
串行化 | 否 | 否 | 否 |
### mongoDb |
- mongodb在创建索引时,会自动给索引命名!
- 索引名字有长度限制 124字节
索引属性重要的有
- 名字
- 唯一性
- 稀疏性
- 是否定时删除
mongodb索引都有哪些?
- _id索引
- 复合索引
- 过期索引
- 全文索引
- 地理空间索引
mongodb 索引分析
- mongoStat工具
- 查看MongoDB运行状态的程序
- profile集合
- 索引优点:加快索引相关的查询
- 索引缺点:增加磁盘空间消耗,降低写入性能
MongoDB安全概念
- 最安全的是物理隔绝 :不现实
- 网络隔离层 某些网络下可以
- 防火墙隔离 某些ID可以
- 用户密码隔离 最常使用的
鉴权机制用于用户密码隔离,也是最常用的安全隔离方法
关系型数据库和非关系型数据库
关系型数据库
简单来说,关系模型指的就是二维表格模型,而一个关系型数据库就是由二维表及其之间的联系所组成的一个数据组织。
关系型数据库的优点:
- 容易理解:二维表结构是非常贴近逻辑世界的一个概念,关系模型相对网状、层次等其他模型来说更容易理解
- 使用方便: 通用的SQL语言使得操作关系型数据库非常方便
- 易于维护:丰富的完整性(实体完整性、参照完整性和用户定义的完整性)大大减低了数据冗余和数据不一致的概率
关系型数据库瓶颈
高并发读写需求
- 网站的用户并发性非常高,往往达到每秒上万次读写请求,对于传统关系型数据库来说,硬盘I/O是一个很大的瓶颈
海量数据的高效率读写
- 网站每天产生的数据量是巨大的,对于关系型数据库来说,在一张包含海量数据的表中查询,效率是非常低的
高扩展性和可用性
- 在基于web的结构当中,数据库是最难进行横向扩展的,当一个应用系统的用户量和访问量与日俱增的时候,数据库却没有办法像web server和app server那样简单的通过添加更多的硬件和服务节点来扩展性能和负载能力。对于很多需要提供24小时不间断服务的网站来说,对数据库系统进行升级和扩展 是非常痛苦的事情,往往需要停机维护和数据迁移。
非关系型数据库
特点
- 非结构化的存储
- 基于多维关系的模型
- 部署容易,开源免费,成本低
优点
- 处理高并发,大批量数据的能力强
- 支持分布式集群,负载均衡,性能高
- 内存级数据库,查询速度快
- 存储格式多
- 没有多表连接查询机制的限制,扩展性高
缺点
- 不支持SQL工业标准
- 没有JOIN等复杂的链接操作 新版已经支持
- 事务处理能力弱 新版也有了
- 没有完整性约束,对于复杂业务支持较差
网络协议
常见状态
- 1xx(临时响应)
- 2xx(成功)
- 3xx(重定向)
- 4xx(请求错误)
- 5xx(服务器错误)
HTTP || HTTPS的区别
- https协议需要申请证书
- http是超文本传输协议,信息是明文传输,https则具有安全的ssl加密传输协议
- http与https的的端口不一样前者是80 后者是443
- 加密传输比http安全
HTTP 1.1与1.0相比有什么差异?
HTTP 1.1于1997年1月发布,在HTTP 2.0发布前,一直被使用了15年,下面为HTTP 1.1 和1.0之间的主要差异:
- 长连接
- 在HTTP 0.9和1.0中,TCP连线在每一次请求/回应对之后关闭。在HTTP 1.1中,引入了保持连线的机制,一个连接可以重复在多个请求/回应使用。持续连线的方式可以大大减少等待时间,因为在发出第一个请求后,双方不需要重新运行TCP握手程序。
- 同一个Ip和端口提供不同服务
- 能够使不同域名配置在同一个IP地址的服务器上,web server上的多个虚拟站点可以共享同一个ip和端口。
- 带宽
- HTTP 1.1还使改进了HTTP 1.0的带宽。
- 例如,HTTP 1.1引入了分块传输编码,以允许传递内容可以在持续连在线被流传输而不必使用到缓冲器。HTTP管道允许客户端在收到每个回应之前发送多个请求,进一步减少用户感受到的滞后时间。协议的另一个补充是字节服务,允许客户端请求资源的某一部分,服务器仅回应某资源的指明部分。
HTTP 2.0新功能
- 并行交错地发送多个请求,请求之间互不影响。
- 并行交错地发送多个响应,响应之间互不干扰。
- 使用一个连接并行发送多个请求和响应。
- 所有通信都在一个 TCP 连接上完成,此连接可以承载任意数量的双向数据流。
async与await原理
KOA
Promise的实现原理
如果避免高并发
- 优化数据库
- 加索引
SQL语法
select from where //条件查询
`SELECT * FROM Persons WHERE City='Beijing'`
order by 排序
limit 返回数量
like
- SQL LIKE子句中使用 % 字符来表示任意字符,包含某个字段中含有 “XXX”记录的值
SELECT * FROM <表名> WHERE <name> LIKE "字段中包含的"
in
- IN 操作符允许我们在 WHERE 子句中规定多个值。
SELECT * FROM Persons WHERE lastName IN('aDMIN','caret')
between
- BETWEEN 操作符在WHERE子句中 使用,作用是选取介于两个值之前的数据范围
- 如需以字母顺序显示介于 “Adams”(包括)和 “Carter”(不包括)之间的人,请使用下面的 SQL:
SELECT * FROM Persons WHERE lastName BETWEEN 'Adams' AND 'Carter'
join // inner join, left join, right join
- SQL join 用于根据两个或多个表中的列之间的关系,从这些表中查询数据。
group by SELECT Persons.LastNmae,Persons.FirstName,Order.OrderNo FROM Persons INNER JOIN Orders ON Persons.id_p = Orders.id_P ORDER BY Persons.LastNmae
- SQL join 用于根据两个或多个表中的列之间的关系,从这些表中查询数据。
count
- COUNT(column_name) 函数返回指定列的值的数目
SELECT COUNT(*) AS NumberOFOrders FROM Orders
avg
- AVG 函数返回数值列的平均值。NULL 值不包括在计算中。
SELECT AVG(OrderPrice) AS orderLenght FROM Orders
sum
- SUM 函数返回数值列的总数(总额)。
SELECT COUNT(OrderPrice) AS OrderTotal FROM order
- 本文作者: 前端圈
- 本文链接: https://lizheguang.github.io/zhaiGuang/2018/12/17/node面试/
- 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!