# node简介

介绍了nodejs的起源、特点以及应用场景

# 模块机制

  • nodejs中的模块机制叫做 commonjs

    require, module.exports = {}

  • 模块分为两种:核心模块、文件模块

  • 核心模块

    • C/C++编写,放在源码仓库的的src目录下
    • javascript编写,放在源码仓库的lib目录下

    C/C++编写核心模块,javascript负责包装和向外导出 纯 C/C++编写的,被称为内建模块 javascript 核心模块:js文件被v8的js2c.py转换成C++数组,使用时直接从内存中加载 由里到外:内建模块>核心模块>文件模块

# 异步I/O

其他语言中主要是同步I/O,在node中异步I/O为其主要变成方式和设计理念

有4种:异步、同步、阻塞、非阻塞,操作系统只有阻塞I/O和非阻塞I/O

非/阻塞I/O 还是通过轮询,查询状态,跟异步I/O其实是两回事,很容易混淆 轮询技术的衍变历程:

  • read

    重复检查I/O状态

  • select

    对文件描述符上的事件状态进行判断

  • poll

    在select的基础上改进,采用链表存储,避免数组长度的问题

  • epoll

    最高效,真正的事件通知、执行回调

大概过程:异步调用 -> 线程池执行 -> 事件循环(通知循环中的IO观察者)

非IO的异步api:

  • setTimeout
  • setInterval

    这两者无需IO线程池的参与,在tick中判断是否需要执行 插入到定时器观察者的一个红黑树中

  • process.nextTick

    插入队列,下一轮tick中执行

  • setImmediate

    优先级低于nextTick,nextTick属于idle观察者,setImmediate属于check观察者

# 异步编程

sync async解决了回调地狱 如果调用IO特别多,为了防止并发过多,还是需要自行设计队列来控制并发数

# 内存控制

  • 内存使用情况:
node
process.memoryUsage()
{
  rss: 26009600,
  heapTotal: 5222400,   // 申请到的堆内存
  heapUsed: 2962952,    // 已使用的内存
  external: 1526857,
  arrayBuffers: 9399
}
  • 内存对象被分为新生代和老生代两代

与java, .net很像

  • 新生代采用scavenge算法(具体实现中采用Cheney算法)

scavenge: 内存一分为二,从from里把活的复制到to,然后角色翻转(from释放空间变成to,to变成from)

  • 老生代采用Mark-Sweep & Mark-Compact算法

Mark-Sweep:引用标记,给活着的对象打上标记,清理未标记的对象 Mark-Sweep 会导致内存碎片(内存不连续) Mark-Compact 会在清理后把活着的对象移动,使得内存连续

  • 增量标记、延迟清理、增量式整理

# 理解Buffer

  • 处理字节所用
  • 内存分配在C++层面,并不在V8的堆内存中
  • slab 分配机制
  • Node中以8KB为界限来区分Buffer是大对象还是小对象

# 网络编程

介绍了TCP、Http、WebSocket等原生模块

# 构建Web应用

从基础模块中搭建web应用

# 玩转进程

Cluster

# 测试

单元测试、性能测试

# 产品化

工程化、部署、性能、日志、监控、稳定性、异构并存