- 1.大家在开发Node.js的时候都知道异步的嵌套非常麻烦,有人叫回调地域有人叫回调黑洞,请问如何解决这个问题?(5分)
- 2.如何解释NodeJS 适用于IO密集型不适用CPU密集型?(5分)
- 3.请画出Node.js的异步事件回调机制的实现,并解释原理。(5分)
- 4.开完一个完整的Node程序,有UI层、Service层、DAO层、MODEL层等,我们要在交给QA前需要编写测试用例。测试用例一般遵循测试金字塔(测试金字塔指的是在编写测试用例时,底层的单元测试应该远比上层的端到端测试要多,如下图)请问在如下三个阶段,都用什么样的技术进行测试用例的编写。(10分)
- 5.有人说Node是玩具,写错一处整个网站就挂。为了解决它你有什么办法么?(10分)
- 6.请你写出你知道的HTTP请求报头,并写出常见的HTTP Status Code标明他的含义(5分)
- 7.请用KOA2实现基本的服务端,并输出HelloWorld,且实现功能测试。(20分)
- 8.NodeJS使用了Scavenge、Mark-Sweep 、 Mark-compact算法进行垃圾回收,请绘制三种算法的原理,并描述何种情况下会造成NodeJS的内存泄露,如何检测?(20分)
- 9.请你写出你能力范围的一个Node项目文件夹的划分,并标明他的作用。(10分)
- - 10.请绘制浏览器实现缓存机制。(10分)
1.大家在开发Node.js的时候都知道异步的嵌套非常麻烦,有人叫回调地域有人叫回调黑洞,请问如何解决这个问题?(5分)
答案:
- 模拟 Promise/Defferred 的库如 q.js、Step、wind
在之前用的 express 模块,还没有ES6 时,别人实现的模拟现在 Promise 的库,之前的老项目用的这个方法现在已经不用了- ES6 Generator函数 + Promise 对象
koa1 时使用的
参考链接:http://www.ruanyifeng.com/blog/2015/04/generator.html Generator 函数的含义与用法 -> 阮一峰先生的日志- Async await 函数
参考链接:http://www.ruanyifeng.com/blog/2015/05/async.html async 函数的含义和用法 -> 阮一峰先生的日志2.如何解释NodeJS 适用于IO密集型不适用CPU密集型?(5分)
答案:- Node 还没有简单易用的多核计算接口,Cluster并不是那么好用
Node 主要是基于异步进行计算的,在 Node 里面能够接收大量的请求,能做一些基础的事情,但是它占用硬件的成本较低,所以用它去解决异步时是非常好用的。- Node 的单核效率虽然比传统脚本语言,但是和 C、C++、Java 比并没有优势
假设你纯粹地去计算一段 CPU 密集型的数据的时候,Node相对于Java之类的相比没有什么优势,因为Node 本身就是 C++ 语言来写的,所以Node执行时会将请求编译后交给 C++ 去处理
因为Node 占得资源比较少 Node 是基于异步去处理任务,所以比较适用于IO密集型,如果让它去处理 CPU 密集型的计算,它需要将请求编译后交给 C++ 去处理
参考:CPU密集型 / I/O密集型
一些进程绝大多数时间在计算上,称为计算密集型(CPU密集型)computer-bound。
有一些进程则在input 和output上花费了大多时间,称为I/O密集型,I/O-bound。比如搜索引擎蜘蛛大多时间是在等待响应这种就属于I/O密集型。3.请画出Node.js的异步事件回调机制的实现,并解释原理。(5分)
流程:首先是通过 JS 写好的应用简称 APP ,绑定到 V8 引擎上,V8 引擎通过中间的操作系统 进入到事件队列 事件队列里面走 EVENT LOOP ,EVENT LOOP 里面不会执行在这里转圈 然后是同步的绑定到操作系统的执行事件,然后事件执行完毕之后把这个事件从 EVENT LOOP 循环里的事件队列中拆出去 拆出去之后返回给对应的操作系统 操作系统返回给 V8 引擎 V8引擎返回给你的 JS 应用
这个事件它是一个独立的线程,LIBUV 也是一个独立的线程 帮助你去做 EVENT LOOP
Node 是操作不了很多底层的东西的,还得依靠操作系统来实现
4.开完一个完整的Node程序,有UI层、Service层、DAO层、MODEL层等,我们要在交给QA前需要编写测试用例。测试用例一般遵循测试金字塔(测试金字塔指的是在编写测试用例时,底层的单元测试应该远比上层的端到端测试要多,如下图)请问在如下三个阶段,都用什么样的技术进行测试用例的编写。(10分)
答案:
- selenium-webdriver nigthwatch
- mocha supertest 接口测试
- karma PhantomJS+chai 单元测试
5.有人说Node是玩具,写错一处整个网站就挂。为了解决它你有什么办法么?(10分)
答案:- 中间件处理掉常见的404 500
- 关键函数比如请求进行封装 容错重试等
参考函数式编程- 全部错误监听 uncaughtExcetion
会写 NodeJS 才完成了 NodeJS 的10% 剩下的 90% 是性能和测试6.请你写出你知道的HTTP请求报头,并写出常见的HTTP Status Code标明他的含义(5分)
HTTP Status Code HTTP状态码 -> 百度百科 https://baike.baidu.com/item/HTTP状态码/5053660?fr=aladdin&fromid=11296236&fromtitle=HTTP+Status+Code
2 成功
3 重定向
4 请求错误
5、6 服务器错误- 200 Ok 请求已成功,请求所希望的响应头或数据体将随此响应返回。出现此状态码是表示正常状态
- 301 Moved Permanently 被请求的资源已永久移动到新位置,并且将来任何对此资源的引用都应该使用本响应返回的若干个 URI 之一。如果可能,拥有链接编辑功能的客户端应当自动把请求的地址修改为从服务器反馈回来的地址。除非额外指定,否则这个响应也是可缓存的。
- 302 Move temporarily 请求的资源临时从不同的 URI响应请求。由于这样的重定向是临时的,客户端应当继续向原有地址发送以后的请求。只有在Cache-Control或Expires中进行了指定的情况下,这个响应才是可缓存的。
- 304 Not Modified 你的资源被缓存了 如果客户端发送了一个带条件的 GET 请求且该请求已被允许,而文档的内容(自上次访问以来或者根据请求的条件)并没有改变,则服务器应当返回这个状态码。304响应禁止包含消息体,因此始终以消息头后的第一个空行结尾
- 403 Forbidden 没有权限 服务器已经理解请求,但是拒绝执行它。
- 404 Not Found 请求失败,请求所希望得到的资源未被在服务器上发现。
- 405 Method Not Allowed 类似于设置的是 get 请求方法 然后写的时候用了 post 请求方法便会报这个错误 请求行中指定的请求方法不能被用于请求相应的资源。
- 502 Bad Gateway 服务器出问题了 作为网关或者代理工作的服务器尝试执行请求时,从上游服务器接收到无效的响应。
- 503 Service Unavailable 代码写的有问题,由于处理的时间过长之类的将服务给堵死了 长时间的请求服务器超时了未处理 由于临时的服务器维护或者过载,服务器当前无法处理请求。这个状况是临时的,并且将在一段时间以后恢复。
注意:503状态码的存在并不意味着服务器在过载的时候必须使用它。某些服务器只不过是希望拒绝客户端的连接。- 504 Gateway Timeout 服务器连上了 但是超时了 作为网关或者代理工作的服务器尝试执行请求时,未能及时从上游服务器(URI标识出的服务器,例如HTTP、FTP、LDAP)或者辅助服务器(例如DNS)收到响应。
注意:某些代理服务器在DNS查询超时时会返回400或者500错误7.请用KOA2实现基本的服务端,并输出HelloWorld,且实现功能测试。(20分)
答案:
//参考:https://www.npmjs.com/package/koa2
//app.js
const koa = require('koa');
const app = new koa();
const result = new Promise(function(resolve,reject) {
setTimeout(function(){
resolve('Hello World');
},1000)
});
app.use(async(ctx,next)=>{
const start = new Date();
ctx.body = await result;
});
app.listen(3000);
export default app;
//参考:https://www.npmjs.com/package/supertest
//servertest.js
var app = require('./app');
var request = require('supertest').agent(app.listen());
describe('Hello World',function(){
it('should say "Hello World"',function(done){
request
.get('/')
.expect(200)
.expect('Hello World',done);
});
});
8.NodeJS使用了Scavenge、Mark-Sweep 、 Mark-compact算法进行垃圾回收,请绘制三种算法的原理,并描述何种情况下会造成NodeJS的内存泄露,如何检测?(20分)
答案:
- 三种算法的原理
回收机制分成:新生代空间 和 老生代空间
新生代空间分为 from 和 to ,from 是一些新进来的变量,所以新生代空间用来存储这些比较新的这些变量,它把内存一分为二 分成 from 和 to ,首先呢 from 变量进来 然后开始垃圾回收 开始收拾它们 收拾之后呢 有一些用到的变量把它们放到 to 没有用的呢放到 from ,现在分成了 from(没用到的) 和 to (用到的)然后垃圾回收将 from 和 to 里的东西调一下位置 然后将 to 干掉 这样这些变量就只留下了一次,这样的话再次进行垃圾回收的时候发现上次垃圾回收后(颠倒并干掉 to 之后)留下的 某个变量它还在那这个变量就有机会进入到老生代空间,晋升到老生代空间之后下次再进行垃圾回收的时候就是它想把一堆变量再次塞到 to 的时候发现 to 使用的百分比超过了 25% 这些东西直接晋升到老生代空间,那这样的话 老生代空间就会不愿意了 越来越多的变量堆积在老生代空间里,所以将不用的东西呢打个 叫做标记清除 Mark-Sweep 然后把所有东西都全部干掉 这个时候会出现一个内存不连续的一个段 这个时候怎么办呢 它先把这些东西标个 然后呢想干掉的东西留下 不想干掉的东西往右一挪 这个就叫标记合并 Mark-compact, 最终挪完了之后 把那些标 * 的全部干掉 这样内存就会不是不连续的了
Scavenge 处理的是新生代空间 ; Mark-Sweep 、 Mark-compact 处理的是老生代空间
- 造成内存泄漏的原因
一般就是闭包,和大对象的引用 后面会继续深入学习
9.请你写出你能力范围的一个Node项目文件夹的划分,并标明他的作用。(10分)
答案:
以下的结构是比较基础的,也可以照着 .NET 或者 Java 来
model 请求层
views 模板层
public/assets 静态资源
controller 路由
libs
config
app.js- 10.请绘制浏览器实现缓存机制。(10分)
答案:
Etag 是一个文件的戳,它相当于一个文件 MD5 的戳 存在浏览器里