前言
因工作需求原因导致我的技术栈一直都在变化,从大学到现在,语言从Java 到 C# 到 Node,再到现在的Go。朋友都会虚假客套你一句赞叹:很厉害,会的语言很多。其实,只有我知道,我属于会而不精系列。所以我这种P民,我还是觉得我应该专注做一件事,深入研究,做好,做到极致。但唯一庆幸的是我一直都在做后端开发。“语言只是工具”。是的,但我还是觉得应该专精一种,再扩展其他旁系。
废话不闲聊,今日话题主要是想聊下我对Node 和Go的一些认识和理解。
Node
Node历史背景
Node的创作者Ryan Dahl的主要工作就是围绕高性能Web服务器,他最初的目标是写一个基于事件驱动、非阻塞I/O的Web服务器,以达到更高的性能。
JavaScript 在浏览器中有广泛的事件驱动方面的应用,而且Chrome浏览器的JavaScript引擎V8在浏览器性能大战中获得头名。这都是JavaScript成为Node的实现语言原因的一部分。
Node为什么会叫Node?最初作者将他的项目称为web.js,一个web服务器。在不断的发展,Node发展成一个不共享任何资源的单线程、单进程系统,包含各种库。每一个Node进程都构成这个网络应用中的一个节点,所以这是名字意义所在。
Node特点
异步I/O
异步I/O,代码执行一个IO操作时,发出请求后无需等待结果,就可以继续往下执行。一段时间后,当IO返回结果时,再通知CPU进行处理。相反,同步就是进行一个I/O操作时需要等待操作结束后才能继续进行。
经典例子,理解起来更容易:
var fs = require('fs');
fs.readFile('/path',function(err,files){
console.log('读取文件完成');
})
console.log('发起读取文件');
//输出结果:
//发起读取文件
//读取文件完成
如果读取文件是一个长时间I/O操作,那么先输出“发起读取文件”,读取文件结束后才输出“读取文件完成”。这样就是一个异步I/O的例子。如果是多个异步I/O操作,那么耗时就是最长那个时间。如果是同步的话,耗时就是多个操作耗时之和。这就是异步I/O带来的优势。
事件与回调函数
说到事件和回调函数,可以去查阅Node的执行模型—事件循环,后续也会对这部分输出自己的深入学习笔记【待办】
Node的所有的异步 I/O 操作在完成时都会发送一个事件到事件队列。每个事件执行完后会执行回调函数。
单线程
Node保持了JavaScript在浏览器中单线程的特点。
优势
- 单线程无需考虑像多线程存在状态的同步问题
- 单线程无需考虑线程上下文切换问题
- 单线程也不会出现多线程的死锁问题
劣势
- 无法利用多核CPU,浪费资源
- 单线程错误就会导致整个应用都退出
- 大量占用CPU的计算就会影响整体性能
跨平台
兼容多平台,主要是基于底层libuv实现跨平台。libuv在操作系统和node之间构建了一层平台层架构
应用场景
1、擅长I/O密集型应用场景,主要通过事件循环机制,一个线程服务所有的请求,资源占用少
2、对于密集型计算常用,其实可以通过C/C++扩展实现有效利用CPU或者通过Node子进程
3、分布式应用
Go
Go历史背景
Go的创造者目的是想创造一种新语言来取代C++。虽然到现在还无法取而代之,但是Go的执行性能和开发效率以及编译速度,可算顶尖。
Go的关键特性
- 语法简洁,如在变量声明、结构体声明、函数定义等方面
- 静态语言,静态编译速度快,拥有静态语言的安全与性能
- 为并发而生,goroutine轻量级线程,支持大并发处理
- 提供垃圾回收机制
- 异常处理机制,普通异常通过返回error对象处理,严重异常由panic、recover处理
- 函数多返回值,方便接受多值
- 支持defer延迟调用
- 内存使用效率高
- 依赖少,go底层的runtime 和内置的库非常强大,比如net/http, sync, bufio这些都非常稳定易用, 简洁的代码就能构建网络服务
- 部署方便
- .......
很多特性,也是它的优点。后续将在GO专题中详细扩展这部分的内容
Go使用场景
- 服务端开发
- 分布式系统,微服务
- 网络编程
- 区块链开发
- 内存KV数据库,例如boltDB、levelDB
所以,如果面试的时候,面试官问你对Node和Go的认识,可以从Node 和Go带来的优势,和有利的使用场景来阐述。相较于很多业务场景,其实都可以实现,所以只有适用,可用,而非必须用。
更多的发现可以在深入学习的时候继续探究。