概述
1 node介绍
node特点
事件驱动
异步IO / 非阻塞IO
事件与回调函数
世界上最大得开源生态系统-npm
单线程 维护事件循环队列实现
优点:在node中 js线程无法共享状态 不用关心状态问题 没有死锁 也没有线程切换得开销
缺点:1)无法利用多核CPU 2)错误会引起整个应用的退出 3)大量计算占用CPU导致无法继续调用异步IO
跨平台
应用场景
IO密集型 基于事件循环得处理能力 擅长
CPU密集型 擅长 挑战:长时间得计算会占用CPU时间片 解决:分解大型运算
充分利用CPU:1)c#扩展来实现计算更高效 2)通过子进程 将计算与IO分离 还能充分利用多核CPU
与遗留系统不冲突
分布式应用
2 模块机制
规范
- CommonJS 规范 侧重于后端 同步加载 require module.exports 模块标识符 相对路径 绝对路径 可以没有文件后缀名
- AMD 规范 侧重于前端 异步并行加载 依赖前置 模块定义 define(id?, dependencies?, factory);
- CMD规范 支持动态引入 依赖就近 按需引入
- ES6模块化 尽量的静态化 编译时就能确定依赖关系以及输入输出变量 import export 只读引用
详细说明 https://segmentfault.com/a/1190000015991869
node模块实现
路径分析 文件定位 编译执行 三个步骤 详细 可参照 https://www.cnblogs.com/AliceX-J/p/5276125.html
npm 与包
第三方库得发布与管理工具
3 异步IO
单线程 原理多线程死锁 状态同步等问题 利用异步IO 原理单线程阻塞 更好得使用CPU 多核CPU 提供了类似webworker得子进程
阻塞IO 需要等待CPU等待系统内核执行完毕后返回
非阻塞IO 调用后立即返回 通过轮询不断确认是都调用完毕
node得异步IO 事件循环 观察者 和请求对象 IO线程池
事件循环 每次循环为一个Tick 如果有待处理事件 则处理 如果有关联回调则执行 如果没有则下一个Tick
观察者 事件循环就是典型得生产者 消费者 异步IO 网络请求 就是事件的生产者
请求对象 中间产物 所以的状态都保存在这个对象中 包括送入线程池等待执行以及IO操作完毕后的回调处理
执行回调 组装好请求兑现给送入IO线程池等待执行 是第一部分 回调通知是第二部分 结果存储在req->result 然后通知对象操作已完成 然后归还线程池 然后提交完成 事件轮询 会检查 然后执行
非IO异步
定时器 settimeout setinterval 创建的定时器会被插入到定时器观察者内部的一个红黑树中 每次Tick 会取出检查时都超时 执行 时间复杂度O(lg(n))
process.nextTick 将回调函数放入队列(数组) 下一轮Tick时取出执行 时间复杂度O(1)
setimmediate 回调函数保存在链表中 一次Tick执行一个
4 异步编程
函数式编程
高阶函数 可以把函数作为参数 或者把函数作为返回值
偏函数 通过指定部分参数产生一个新的定制函数的形式
异步编程
优点 高效 非阻塞
难点 1)异常处理 error-first 2)嵌套过深 3)阻塞代码 4)多线程编程 5)异步转同步
解决方案
1)事件发布订阅模式 - hook机制 - 很容易继承 - 利用once解决雪崩(同一时间同意命令的大量请求)只查询一次
2)promise deffer - promise只会存在三种状态 未完成 完成 失败 其中的一种 不可逆转 不可更改
3)流程控制库
(但目前为止 异步的终极方案是ES7 的 async/await 是Promise加生成器模式的语法糖 将生成器和run封装)
5 内存控制
V8垃圾回收机制
新生代内存(存活时间短)Scavenge算法进行垃圾回收 具体实现中主要采用了Cheney算法 将空间一分为二 标记存活对象复制到另一半 然后将原来的空间清空 两个空间进行交换
晋升 两种情况(一个是看对象是否经历过Scavenge回收 一个时To空间的内存占用超过限制)
老生代内存 (常驻内存)Mark-Sweep & Mark-Compact 标记(标记活着的对象) 清除 (死亡的对象)
Incremental Marking 增量标记 拆分执行 (上面两种为全停顿“stop-the-world”)
影响内存的因素
闭包 和全局变量引用
内存泄漏
缓存 队列 (消费速度低于生产速度 造成队列的堆积)
6 理解Buffer
对外内存 位于全局变量 使用无需require
Buffer对象类似于数组 元素为16进制的两位数 即0-255的值 dayu255依次-255 小于255依次+255
内存分配 slab分配机制 动态内存管理机制 申请固定大号的内存区域 8k为界限
小于8k为小对象 放到没有被分配状态(empty)slab 或者 部分分配状态(partial)slab空间中
大对象 直接分配一个slowBuffer对象作为slab单元 独占
Buffer转字符串
toString()
Buffer拼接
对于中文宽字节 可能会出现buffer之间拼接转码错误的问题 可以设置setEncoding('utf-8'); 传递编码后的字符串
7 网络编程
以下 还有 构建web应用 玩转进程 测试 产品化 就看了 但是看不懂 也许在这方面的基础知识太过欠缺 学一学网络之后再来看一遍再做笔记吧!
最后
以上就是背后老鼠为你收集整理的《深入理解nodejs》笔记 一1 node介绍2 模块机制3 异步IO5 内存控制6 理解Buffer7 网络编程的全部内容,希望文章能够帮你解决《深入理解nodejs》笔记 一1 node介绍2 模块机制3 异步IO5 内存控制6 理解Buffer7 网络编程所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复