Nodejs 面試題

原文鏈接:https://github.com/jimuyouyou/node-interview-questions

Node是搞后端的伊佃,不應(yīng)該被被歸為前端况既,更不應(yīng)該用前端的觀點去理解,去面試node開發(fā)人員褥芒。所以這份面試題大全,更側(cè)重后端應(yīng)用與對Node核心的理解。

一亩钟、node開發(fā)技能圖解

image.png

二、node 事件循環(huán)機制

image.png

三鳖轰、起源

  • node正風(fēng)生火起清酥,很多介紹卻停留在入門階段,無法投入生產(chǎn)
  • node相關(guān)的高質(zhì)量面試題更是少之又少蕴侣,很難全面考查應(yīng)聘者的node能力
  • 許多文章在講第三方類庫焰轻,可是這些庫質(zhì)量差距較大,一旦遇到問題怎么辦
  • 必需的昆雀,全面了解node核心才能成為一名合格的node開發(fā)人員

四辱志、目標(biāo)與原則

  • 前后端兼顧,更側(cè)重后端
  • 理論實戰(zhàn)兼顧狞膘,側(cè)重考察對實戰(zhàn)中應(yīng)用較多的理論的理解
  • 參考答案簡單明了揩懒,一針見血,不為追求嚴(yán)謹(jǐn)而浪費口舌挽封,繞彎子
  • 盡量用代碼講清理論的應(yīng)用與區(qū)別已球,以接地氣
  • 終極目標(biāo)是讓大家對node有一個快速完整的認(rèn)識

五、內(nèi)容大綱

六、ES6新特性

1. ES6有哪些新特性遭笋?

參考答案:類的支持坝冕,模塊化,箭頭操作符瓦呼,let/const塊作用域喂窟,字符串模板,解構(gòu)央串,參數(shù)默認(rèn)值/不定參數(shù)/拓展參數(shù), for-of遍歷, generator, Map/Set, Promise

2. 你對ES6的個人看法磨澡?

參考答案:ES6必火!從軟件工程角度來看质和,以前真的很弱稳摄,不適合做大型應(yīng)用,很容易導(dǎo)致爛尾工程饲宿。ES6就相當(dāng)于當(dāng)年的Java5,是歷史性的發(fā)展厦酬,從此我們可以用js做大型項目了。事實上瘫想,各大主流瀏覽器現(xiàn)在已經(jīng)支持大部分新特性了仗阅,后端的Node.js更是可以直接使用ES6的絕大多數(shù)語法。

推薦ES6入門好書: 阮一峰 ECMAScript 6入門

七国夜、javascript高級話題(面向?qū)ο笈眨饔糜颍]包支竹,設(shè)計模式等)

1. 常用js類定義的方法有哪些旋廷?

參考答案:主要有構(gòu)造函數(shù)原型和對象創(chuàng)建兩種方法。原型法是通用老方法礼搁,對象創(chuàng)建是ES5推薦使用的方法.目前來看饶碘,原型法更普遍.

代碼演示

  • 1). 構(gòu)造函數(shù)方法定義類
    function Person(){
        this.name = 'michaelqin';
    }
    Person.prototype.sayName = function(){
        alert(this.name);
    }

    var person = new Person();
    person.sayName();
  • 2). 對象創(chuàng)建方法定義類
    var Person = {
        name: 'michaelqin',
        sayName: function(){ alert(this.name); }
    };

    var person = Object.create(Person);
    person.sayName();

2. js類繼承的方法有哪些

參考答案:原型鏈法,屬性復(fù)制法和構(gòu)造器應(yīng)用法. 另外馒吴,由于每個對象可以是一個類扎运,這些方法也可以用于對象類的繼承.

代碼演示

  • 1). 原型鏈法
    function Animal() {
        this.name = 'animal';
    }
    Animal.prototype.sayName = function(){
        alert(this.name);
    };

    function Person() {}
    Person.prototype = Animal.prototype; // 人繼承自動物
    Person.prototype.constructor = 'Person'; // 更新構(gòu)造函數(shù)為人
  • 2). 屬性復(fù)制法
    function Animal() {
        this.name = 'animal';
    }
    Animal.prototype.sayName = function() {
        alert(this.name);
    };

    function Person() {}

    for(prop in Animal.prototype) {
        Person.prototype[prop] = Animal.prototype[prop];
    } // 復(fù)制動物的所有屬性到人量邊
    Person.prototype.constructor = 'Person'; // 更新構(gòu)造函數(shù)為人
  • 3). 構(gòu)造器應(yīng)用法
    function Animal() {
        this.name = 'animal';
    }
    Animal.prototype.sayName = function() {
        alert(this.name);
    };

    function Person() {
        Animal.call(this); // apply, call, bind方法都可以.細(xì)微區(qū)別,后面會提到.
    }
3. js類多重繼承的實現(xiàn)方法是怎么樣的?

參考答案:就是類繼承里邊的屬性復(fù)制法來實現(xiàn).因為當(dāng)所有父類的prototype屬性被復(fù)制后饮戳,子類自然擁有類似行為和屬性.

4. js里的作用域是什么樣子的豪治?

參考答案:大多數(shù)語言里邊都是塊作作用域,以{}進(jìn)行限定扯罐,js里邊不是.js里邊叫函數(shù)作用域负拟,就是一個變量在全函數(shù)里有效.比如有個變量p1在函數(shù)最后一行定義,第一行也有效歹河,但是值是undefined.

代碼演示

    var globalVar = 'global var';

    function test() {
        alert(globalVar); // undefined, 因為globalVar在本函數(shù)內(nèi)被重定義了掩浙,導(dǎo)致全局失效花吟,這里使用函數(shù)內(nèi)的變量值,可是此時還沒定義
        var globalVar = 'overrided var'; // globalVar在本函數(shù)內(nèi)被重定義
        alert(globalVar); // overrided var
    }
    alert(globalVar); // global var厨姚,使用全局變量
5. js里邊的this指的是什么?

參考答案: this指的是對象本身衅澈,而不是構(gòu)造函數(shù).

代碼演示

    function Person() {
    }
    Person.prototype.sayName() { alert(this.name); }

    var person1 = new Person();
    person1.name = 'michaelqin';
    person1.sayName(); // michaelqin
6. apply, call和bind有什么區(qū)別?

參考答案:三者都可以把一個函數(shù)應(yīng)用到其他對象上,注意不是自身對象.a(chǎn)pply,call是直接執(zhí)行函數(shù)調(diào)用谬墙,bind是綁定今布,執(zhí)行需要再次調(diào)用.a(chǎn)pply和call的區(qū)別是apply接受數(shù)組作為參數(shù),而call是接受逗號分隔的無限多個參數(shù)列表拭抬,

代碼演示

    function Person() {
    }
    Person.prototype.sayName() { alert(this.name); }

    var obj = {name: 'michaelqin'}; // 注意這是一個普通對象险耀,它不是Person的實例
    1) apply
    Person.prototype.sayName.apply(obj, [param1, param2, param3]);

    2) call
    Person.prototype.sayName.call(obj, param1, param2, param3);

    3) bind
    var sn = Person.prototype.sayName.bind(obj);
    sn([param1, param2, param3]); // bind需要先綁定,再執(zhí)行
    sn(param1, param2, param3); // bind需要先綁定玖喘,再執(zhí)行
7. caller, callee和arguments分別是什么?

參考答案: caller,callee之間的關(guān)系就像是employer和employee之間的關(guān)系,就是調(diào)用與被調(diào)用的關(guān)系蘑志,二者返回的都是函數(shù)對象引用.a(chǎn)rguments是函數(shù)的所有參數(shù)列表累奈,它是一個類數(shù)組的變量.

代碼演示

    function parent(param1, param2, param3) {
        child(param1, param2, param3);
    }

    function child() {
        console.log(arguments); // { '0': 'mqin1', '1': 'mqin2', '2': 'mqin3' }
        console.log(arguments.callee); // [Function: child]
        console.log(child.caller); // [Function: parent]
    }

    parent('mqin1', 'mqin2', 'mqin3');
8. 什么是閉包,閉包有哪些用處?

參考答案: 閉包這個術(shù)語急但,無論中文翻譯還是英文解釋都太2B了澎媒,我必須罵人,因為它什么其實都不是.非要講它是什么的話波桩,兩個字函數(shù)戒努,更多字嵌套函數(shù)的父子自我引用關(guān)系.所有函數(shù)都是閉包.通俗的說,閉包就是作用域范圍镐躲,因為js是函數(shù)作用域储玫,所以函數(shù)就是閉包.全局函數(shù)的作用域范圍就是全局,所以無須討論.更多的應(yīng)用其實是在內(nèi)嵌函數(shù)萤皂,這就會涉及到內(nèi)嵌作用域撒穷,或者叫作用域鏈.說到內(nèi)嵌,其實就是父子引用關(guān)系(父函數(shù)包含子函數(shù)裆熙,子函數(shù)因為函數(shù)作用域又引用父函數(shù)端礼,這它媽不是死結(jié)嗎?所以叫閉包)入录,這就會帶來另外一個問題蛤奥,什么時候引用結(jié)束?如果不結(jié)束僚稿,就會一直占用內(nèi)存凡桥,引起內(nèi)存泄漏.好吧,不用的時候就引用設(shè)為空蚀同,死結(jié)就解開了.

9. defineProperty, hasOwnProperty, propertyIsEnumerable都是做什么用的唬血?

參考答案:Object.defineProperty(obj, prop, descriptor)用來給對象定義屬性,有value,writable,configurable,enumerable,set/get等.hasOwnProerty用于檢查某一屬性是不是存在于對象本身望蜡,繼承來的父親的屬性不算.propertyIsEnumerable用來檢測某一屬性是否可遍歷,也就是能不能用for..in循環(huán)來取到.

10. js常用設(shè)計模式的實現(xiàn)思路拷恨,單例脖律,工廠,代理腕侄,裝飾小泉,觀察者模式等

參考答案:

    1) 單例: 任意對象都是單例,無須特別處理
    var obj = {name: 'michaelqin', age: 30};

    2) 工廠: 就是同樣形式參數(shù)返回不同的實例
    function Person() { this.name = 'Person1'; }
    function Animal() { this.name = 'Animal1'; }

    function Factory() {}
    Factory.prototype.getInstance = function(className) {
        return eval('new ' + className + '()');
    }

    var factory = new Factory();
    var obj1 = factory.getInstance('Person');
    var obj2 = factory.getInstance('Animal');
    console.log(obj1.name); // Person1
    console.log(obj2.name); // Animal1

    3) 代理: 就是新建個類調(diào)用老類的接口,包一下
    function Person() { }
    Person.prototype.sayName = function() { console.log('michaelqin'); }
    Person.prototype.sayAge = function() { console.log(30); }

    function PersonProxy() {
        this.person = new Person();
        var that = this;
        this.callMethod = function(functionName) {
            console.log('before proxy:', functionName);
            that.person[functionName](); // 代理
            console.log('after proxy:', functionName);
        }
    }

    var pp = new PersonProxy();
    pp.callMethod('sayName'); // 代理調(diào)用Person的方法sayName()
    pp.callMethod('sayAge'); // 代理調(diào)用Person的方法sayAge()

    4) 觀察者: 就是事件模式冕杠,比如按鈕的onclick這樣的應(yīng)用.
    function Publisher() {
        this.listeners = [];
    }
    Publisher.prototype = {
        'addListener': function(listener) {
            this.listeners.push(listener);
        },

        'removeListener': function(listener) {
            delete this.listeners[listener];
        },

        'notify': function(obj) {
            for(var i = 0; i < this.listeners.length; i++) {
                var listener = this.listeners[i];
                if (typeof listener !== 'undefined') {
                    listener.process(obj);
                }
            }
        }
    }; // 發(fā)布者

    function Subscriber() {

    }
    Subscriber.prototype = {
        'process': function(obj) {
            console.log(obj);
        }
    }; // 訂閱者

    var publisher = new Publisher();
    publisher.addListener(new Subscriber());
    publisher.addListener(new Subscriber());
    publisher.notify({name: 'michaelqin', ageo: 30}); // 發(fā)布一個對象到所有訂閱者
    publisher.notify('2 subscribers will both perform process'); // 發(fā)布一個字符串到所有訂閱者
11. 列舉數(shù)組相關(guān)的常用方法

參考答案: push/pop, shift/unshift, split/join, slice/splice/concat, sort/reverse, map/reduce, forEach, filter

12. 列舉字符串相關(guān)的常用方法

參考答案: indexOf/lastIndexOf/charAt, split/match/test, slice/substring/substr, toLowerCase/toUpperCase

八微姊、node核心內(nèi)置類庫(事件,流分预,文件兢交,網(wǎng)絡(luò)等)

一)、node概覽

1. 為什么要用node?

參考答案: 總結(jié)起來node有以下幾個特點:簡單強大笼痹,輕量可擴展.簡單體現(xiàn)在node使用的是javascript,json來進(jìn)行編碼配喳,人人都會;強大體現(xiàn)在非阻塞IO,可以適應(yīng)分塊傳輸數(shù)據(jù)凳干,較慢的網(wǎng)絡(luò)環(huán)境晴裹,尤其擅長高并發(fā)訪問;輕量體現(xiàn)在node本身既是代碼救赐,又是服務(wù)器涧团,前后端使用統(tǒng)一語言;可擴展體現(xiàn)在可以輕松應(yīng)對多實例,多服務(wù)器架構(gòu)经磅,同時有海量的第三方應(yīng)用組件.

2. node的構(gòu)架是什么樣子的?

參考答案: 主要分為三層泌绣,應(yīng)用app >> V8及node內(nèi)置架構(gòu) >> 操作系統(tǒng). V8是node運行的環(huán)境,可以理解為node虛擬機.node內(nèi)置架構(gòu)又可分為三層: 核心模塊(javascript實現(xiàn)) >> c++綁定 >> libuv + CAes + http.

3. node有哪些核心模塊?

參考答案: EventEmitter, Stream, FS, Net和全局對象

二)预厌、node全局對象

1. node有哪些全局對象?

參考答案: process, console, Buffer

2. process有哪些常用方法?

參考答案: process.stdin, process.stdout, process.stderr, process.on, process.env, process.argv, process.arch, process.platform, process.exit

3. console有哪些常用方法?

參考答案: console.log/console.info, console.error/console.warning, console.time/console.timeEnd, console.trace, console.table

4. node有哪些定時功能?

參考答案: setTimeout/clearTimeout, setInterval/clearInterval, setImmediate/clearImmediate, process.nextTick

5. node中的事件循環(huán)是什么樣子的?
    總體上執(zhí)行順序是:process.nextTick >> setImmidate >> setTimeout/SetInterval 看官網(wǎng)吧:[https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/](https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/)
6. node中的Buffer如何應(yīng)用?

參考答案: Buffer是用來處理二進(jìn)制數(shù)據(jù)的赞别,比如圖片,mp3,數(shù)據(jù)庫文件等.Buffer支持各種編碼解碼配乓,二進(jìn)制字符串互轉(zhuǎn).

三)仿滔、EventEmitter

1. 什么是EventEmitter?

參考答案: EventEmitter是node中一個實現(xiàn)觀察者模式的類,主要功能是監(jiān)聽和發(fā)射消息犹芹,用于處理多模塊交互問題.

2. 如何實現(xiàn)一個EventEmitter?

參考答案: 主要分三步:定義一個子類崎页,調(diào)用構(gòu)造函數(shù),繼承EventEmitter

代碼演示

    var util = require('util');
    var EventEmitter = require('events').EventEmitter;

    function MyEmitter() {
        EventEmitter.call(this);
    } // 構(gòu)造函數(shù)

    util.inherits(MyEmitter, EventEmitter); // 繼承

    var em = new MyEmitter();
    em.on('hello', function(data) {
        console.log('收到事件hello的數(shù)據(jù):', data);
    }); // 接收事件腰埂,并打印到控制臺
    em.emit('hello', 'EventEmitter傳遞消息真方便!');
3. EventEmitter有哪些典型應(yīng)用?

參考答案:

    1. 模塊間傳遞消息
    1. 回調(diào)函數(shù)內(nèi)外傳遞消息
    1. 處理流數(shù)據(jù)飒焦,因為流是在EventEmitter基礎(chǔ)上實現(xiàn)的.
    1. 觀察者模式發(fā)射觸發(fā)機制相關(guān)應(yīng)用
4. 怎么捕獲EventEmitter的錯誤事件?

參考答案: 監(jiān)聽error事件即可.如果有多個EventEmitter,也可以用domain來統(tǒng)一處理錯誤事件.

代碼演示

    var domain = require('domain');
    var myDomain = domain.create();
    myDomain.on('error', function(err){
        console.log('domain接收到的錯誤事件:', err);
    }); // 接收事件并打印
    myDomain.run(function(){
        var emitter1 = new MyEmitter();
        emitter1.emit('error', '錯誤事件來自emitter1');
        emitter2 = new MyEmitter();
        emitter2.emit('error', '錯誤事件來自emitter2');
    });
5. EventEmitter中的newListenser事件有什么用處?

參考答案: newListener可以用來做事件機制的反射,特殊應(yīng)用,事件管理等.當(dāng)任何on事件添加到EventEmitter時牺荠,就會觸發(fā)newListener事件翁巍,基于這種模式,我們可以做很多自定義處理.

代碼演示

var emitter3 = new MyEmitter();
emitter3.on('newListener', function(name, listener) {
    console.log("新事件的名字:", name);
    console.log("新事件的代碼:", listener);
    setTimeout(function(){ console.log("我是自定義延時處理機制"); }, 1000);
});
emitter3.on('hello', function(){
    console.log('hello node');
});

四)休雌、Stream

1. 什么是Stream?

參考答案: stream是基于事件EventEmitter的數(shù)據(jù)管理模式.由各種不同的抽象接口組成灶壶,主要包括可寫,可讀杈曲,可讀寫驰凛,可轉(zhuǎn)換等幾種類型.

2. Stream有什么好處?

參考答案: 非阻塞式數(shù)據(jù)處理提升效率,片斷處理節(jié)省內(nèi)存担扑,管道處理方便可擴展等.

3. Stream有哪些典型應(yīng)用?

參考答案: 文件恰响,網(wǎng)絡(luò),數(shù)據(jù)轉(zhuǎn)換涌献,音頻視頻等.

4. 怎么捕獲Stream的錯誤事件?

參考答案: 監(jiān)聽error事件胚宦,方法同EventEmitter.

5. 有哪些常用Stream,分別什么時候使用?

參考答案: Readable為可被讀流,在作為輸入數(shù)據(jù)源時使用燕垃;Writable為可被寫流,在作為輸出源時使用枢劝;Duplex為可讀寫流,它作為輸出源接受被寫入,同時又作為輸入源被后面的流讀出.Transform機制和Duplex一樣利术,都是雙向流,區(qū)別時Transfrom只需要實現(xiàn)一個函數(shù)_transfrom(chunk, encoding, callback);而Duplex需要分別實現(xiàn)_read(size)函數(shù)和_write(chunk, encoding, callback)函數(shù).

6. 實現(xiàn)一個Writable Stream?

參考答案: 三步走:1)構(gòu)造函數(shù)call Writable 2) 繼承Writable 3) 實現(xiàn)_write(chunk, encoding, callback)函數(shù)

代碼演示

var Writable = require('stream').Writable;
var util = require('util');

function MyWritable(options) {
    Writable.call(this, options);
} // 構(gòu)造函數(shù)
util.inherits(MyWritable, Writable); // 繼承自Writable
MyWritable.prototype._write = function(chunk, encoding, callback) {
    console.log("被寫入的數(shù)據(jù)是:", chunk.toString()); // 此處可對寫入的數(shù)據(jù)進(jìn)行處理
    callback();
};

process.stdin.pipe(new MyWritable()); // stdin作為輸入源低矮,MyWritable作為輸出源   

五)印叁、文件系統(tǒng)

1. 內(nèi)置的fs模塊架構(gòu)是什么樣子的?

參考答案: fs模塊主要由下面幾部分組成: 1) POSIX文件Wrapper,對應(yīng)于操作系統(tǒng)的原生文件操作 2) 文件流 fs.createReadStream和fs.createWriteStream 3) 同步文件讀寫,fs.readFileSync和fs.writeFileSync 4) 異步文件讀寫, fs.readFile和fs.writeFile

2. 讀寫一個文件有多少種方法?

參考答案: 總體來說有四種: 1) POSIX式低層讀寫 2) 流式讀寫 3) 同步文件讀寫 4) 異步文件讀寫

3. 怎么讀取json配置文件?

參考答案: 主要有兩種方式,第一種是利用node內(nèi)置的require('data.json')機制军掂,直接得到j(luò)s對象; 第二種是讀入文件入內(nèi)容轮蜕,然后用JSON.parse(content)轉(zhuǎn)換成js對象.二者的區(qū)別是require機制情況下,如果多個模塊都加載了同一個json文件蝗锥,那么其中一個改變了js對象跃洛,其它跟著改變,這是由node模塊的緩存機制造成的终议,只有一個js模塊對象; 第二種方式則可以隨意改變加載后的js變量汇竭,而且各模塊互不影響,因為他們都是獨立的穴张,是多個js對象.

4. fs.watch和fs.watchFile有什么區(qū)別细燎,怎么應(yīng)用?

參考答案: 二者主要用來監(jiān)聽文件變動.fs.watch利用操作系統(tǒng)原生機制來監(jiān)聽,可能不適用網(wǎng)絡(luò)文件系統(tǒng); fs.watchFile則是定期檢查文件狀態(tài)變更皂甘,適用于網(wǎng)絡(luò)文件系統(tǒng)玻驻,但是相比fs.watch有些慢,因為不是實時機制.

六)偿枕、網(wǎng)絡(luò)

1. node的網(wǎng)絡(luò)模塊架構(gòu)是什么樣子的?

參考答案: node全面支持各種網(wǎng)絡(luò)服務(wù)器和客戶端璧瞬,包括tcp, http/https, tcp, udp, dns, tls/ssl等.

2. node是怎樣支持https,tls的?

參考答案: 主要實現(xiàn)以下幾個步驟即可: 1) openssl生成公鑰私鑰 2) 服務(wù)器或客戶端使用https替代http 3) 服務(wù)器或客戶端加載公鑰私鑰證書

3. 實現(xiàn)一個簡單的http服務(wù)器?

參考答案: 經(jīng)典又很沒毛意義的一個題目.思路是加載http模塊户辫,創(chuàng)建服務(wù)器,監(jiān)聽端口.

代碼演示

    var http = require('http'); // 加載http模塊

    http.createServer(function(req, res) {
        res.writeHead(200, {'Content-Type': 'text/html'}); // 200代表狀態(tài)成功, 文檔類型是給瀏覽器識別用的
        res.write('<meta charset="UTF-8"> <h1>我是標(biāo)題班惋薄渔欢!</h1> <font color="red">這么原生,初級的服務(wù)器档冬,下輩子能用著嗎?!</font>'); // 返回給客戶端的html數(shù)據(jù)
        res.end(); // 結(jié)束輸出流
    }).listen(3000); // 綁定3ooo, 查看效果請訪問 http://localhost:3000

七)膘茎、child-process

1. 為什么需要child-process?

參考答案: node是異步非阻塞的,這對高并發(fā)非常有效.可是我們還有其它一些常用需求酷誓,比如和操作系統(tǒng)shell命令交互披坏,調(diào)用可執(zhí)行文件,創(chuàng)建子進(jìn)程進(jìn)行阻塞式訪問或高CPU計算等盐数,child-process就是為滿足這些需求而生的.child-process顧名思義棒拂,就是把node阻塞的工作交給子進(jìn)程去做.

2. exec,execFile,spawn和fork都是做什么用的?

參考答案: exec可以用操作系統(tǒng)原生的方式執(zhí)行各種命令,如管道 cat ab.txt | grep hello; execFile是執(zhí)行一個文件; spawn是流式和操作系統(tǒng)進(jìn)行交互; fork是兩個node程序(javascript)之間時行交互.

3. 實現(xiàn)一個簡單的命令行交互程序?

參考答案: 那就用spawn吧.

代碼演示

    var cp = require('child_process');

    var child = cp.spawn('echo', ['你好', "鉤子"]); // 執(zhí)行命令
    child.stdout.pipe(process.stdout); // child.stdout是輸入流玫氢,process.stdout是輸出流
    // 這句的意思是將子進(jìn)程的輸出作為當(dāng)前程序的輸入流帚屉,然后重定向到當(dāng)前程序的標(biāo)準(zhǔn)輸出,即控制臺
4. 兩個node程序之間怎樣交互?

參考答案: 用fork嘛漾峡,上面講過了.原理是子程序用process.on, process.send攻旦,父程序里用child.on,child.send進(jìn)行交互.
代碼演示

    1) fork-parent.js
    var cp = require('child_process');
    var child = cp.fork('./fork-child.js');
    child.on('message', function(msg){
        console.log('老爸從兒子接受到數(shù)據(jù):', msg);
    });
    child.send('我是你爸爸,送關(guān)懷來了!');

    2) fork-child.js
    process.on('message', function(msg){
        console.log("兒子從老爸接收到的數(shù)據(jù):", msg);
        process.send("我不要關(guān)懷生逸,我要銀民幣牢屋!");
    });
5. 怎樣讓一個js文件變得像linux命令一樣可執(zhí)行?

參考答案: 1) 在myCommand.js文件頭部加入 #!/usr/bin/env node 2) chmod命令把js文件改為可執(zhí)行即可 3) 進(jìn)入文件目錄,命令行輸入myComand就是相當(dāng)于node myComand.js了

6. child-process和process的stdin,stdout,stderror是一樣的嗎?

參考答案: 概念都是一樣的槽袄,輸入烙无,輸出,錯誤遍尺,都是流.區(qū)別是在父程序眼里截酷,子程序的stdout是輸入流,stdin是輸出流.

九乾戏、node高級話題(異步迂苛,部署,性能調(diào)優(yōu)鼓择,異常調(diào)試等)

1. node中的異步和同步怎么理解

參考答案: node是單線程的灾部,異步是通過一次次的循環(huán)事件隊列來實現(xiàn)的.同步則是說阻塞式的IO,這在高并發(fā)環(huán)境會是一個很大的性能問題,所以同步一般只在基礎(chǔ)框架的啟動時使用惯退,用來加載配置文件赌髓,初始化程序什么的.

2. 有哪些方法可以進(jìn)行異步流程的控制?

參考答案: 1) 多層嵌套回調(diào) 2) 為每一個回調(diào)寫單獨的函數(shù),函數(shù)里邊再回調(diào) 3) 用第三方框架比方async, q, promise等

3. 怎樣綁定node程序到80端口?

參考答案: 多種方式 1) sudo 2) apache/nginx代理 3) 用操作系統(tǒng)的firewall iptables進(jìn)行端口重定向

4. 有哪些方法可以讓node程序遇到錯誤后自動重啟?

參考答案: 1) runit 2) forever 3) nohup npm start &

5. 怎樣充分利用多個CPU?

參考答案: 一個CPU運行一個node實例

6. 怎樣調(diào)節(jié)node執(zhí)行單元的內(nèi)存大小?

參考答案: 用--max-old-space-size 和 --max-new-space-size 來設(shè)置 v8 使用內(nèi)存的上限

7. 程序總是崩潰,怎樣找出問題在哪里?

參考答案: 1) node --prof 查看哪些函數(shù)調(diào)用次數(shù)多 2) memwatch和heapdump獲得內(nèi)存快照進(jìn)行對比锁蠕,查找內(nèi)存溢出

8. 有哪些常用方法可以防止程序崩潰?

參考答案: 1) try-catch-finally 2) EventEmitter/Stream error事件處理 3) domain統(tǒng)一控制 4) jshint靜態(tài)檢查 5) jasmine/mocha進(jìn)行單元測試

9. 怎樣調(diào)試node程序?

參考答案: node --debug app.js 和node-inspector

10. 如何捕獲NodeJS中的錯誤夷野,有幾種方法? 參考答案: 1) 監(jiān)聽錯誤事件req.on('error', function(){}), 適用EventEmitter存在的情況; 2) Promise.then.catch(error),適用Promise存在的情況 3) try-catch,適用async-await和js運行時異常,比如undefined object

十荣倾、 常用知名第三方類庫(Async, Express等)

1. async都有哪些常用方法悯搔,分別是怎么用?

參考答案: async是一個js類庫,它的目的是解決js中異常流程難以控制的問題.a(chǎn)sync不僅適用在node.js里舌仍,瀏覽器中也可以使用.

  • 1). async.parallel并行執(zhí)行完多個函數(shù)后妒貌,調(diào)用結(jié)束函數(shù)
    async.parallel([
        function(){ ... },
        function(){ ... }
    ], callback);
  • 2). async.series串行執(zhí)行完多個函數(shù)后,調(diào)用結(jié)束函數(shù)
    async.series([
        function(){ ... },
        function(){ ... }
    ]);
  • 3). async.waterfall依次執(zhí)行多個函數(shù)铸豁,后一個函數(shù)以前面函數(shù)的結(jié)果作為輸入?yún)?shù)
    async.waterfall([
        function(callback) {
            callback(null, 'one', 'two');
        },
        function(arg1, arg2, callback) {
          // arg1 now equals 'one' and arg2 now equals 'two'
            callback(null, 'three');
        },
        function(arg1, callback) {
            // arg1 now equals 'three'
            callback(null, 'done');
        }
    ], function (err, result) {
        // result now equals 'done'
    });
  • 4). async.map異步執(zhí)行多個數(shù)組灌曙,返回結(jié)果數(shù)組
    async.map(['file1','file2','file3'], fs.stat, function(err, results){
        // results is now an array of stats for each file
    });
  • 5). async.filter異步過濾多個數(shù)組,返回結(jié)果數(shù)組
    async.filter(['file1','file2','file3'], fs.exists, function(results){
        // results now equals an array of the existing files
    });
2. express項目的目錄大致是什么樣子的

參考答案: app.js, package.json, bin/www, public, routes, views.

3. express常用函數(shù)

參考答案: express.Router路由組件,app.get路由定向节芥,app.configure配置在刺,app.set設(shè)定參數(shù),app.use使用中間件

4. express中如何獲取路由的參數(shù)

參考答案: /users/:name使用req.params.name來獲取; req.body.username則是獲得表單傳入?yún)?shù)username; express路由支持常用通配符 ?, +, *, and ()

5. express response有哪些常用方法

參考答案: res.download() 彈出文件下載
res.end() 結(jié)束response
res.json() 返回json
res.jsonp() 返回jsonp
res.redirect() 重定向請求
res.render() 渲染模板
res.send() 返回多種形式數(shù)據(jù)
res.sendFile 返回文件
res.sendStatus() 返回狀態(tài)

十一、其它相關(guān)后端常用技術(shù)(MongoDB, Redis, Apache, Nginx等)

1. mongodb有哪些常用優(yōu)化措施

參考答案: 類似傳統(tǒng)數(shù)據(jù)庫头镊,索引和分區(qū).

2. mongoose是什么蚣驼?有支持哪些特性?

參考答案: mongoose是mongodb的文檔映射模型.主要由Schema, Model和Instance三個方面組成.Schema就是定義數(shù)據(jù)類型,Model就是把Schema和js類綁定到一起相艇,Instance就是一個對象實例.常見mongoose操作有,save, update, find. findOne, findById, static方法等.

3. redis支持哪些功能

參考答案: set/get, mset/hset/hmset/hmget/hgetall/hkeys, sadd/smembers, publish/subscribe, expire

4. redis最簡單的應(yīng)用

參考答案:

    var redis = require("redis"),
        client = redis.createClient();

    client.set("foo_rand000000000000", "some fantastic value");
    client.get("foo_rand000000000000", function (err, reply) {
        console.log(reply.toString());
    });
    client.end();
5. apache,nginx有什么區(qū)別?

參考答案: 二者都是代理服務(wù)器颖杏,功能類似.a(chǎn)pache應(yīng)用簡單,相當(dāng)廣泛.nginx在分布式坛芽,靜態(tài)轉(zhuǎn)發(fā)方面比較有優(yōu)勢.

十二留储、常用前端技術(shù)(Html5, CSS3, JQuery等)

1. Html5有哪些比較實用新功能

參考答案: File API支持本地文件操作; Canvans/SVG支持繪圖; 拖拽功能支持; 本地存儲支持; 表單多屬性驗證支持; 原生音頻視頻支持等

2. CSS3/JQuery有哪些學(xué)常見選擇器

參考答案: id, 元素,屬性, 值靡馁,父子兄弟, 序列等

3. JQuery有哪些經(jīng)典應(yīng)用

參考答案: 文檔選擇欲鹏,文檔操作机久,動畫, ajax, json, js擴展等.

十三臭墨、node.js 設(shè)計模式

  • HeadFirstDesignPatternInJavascript
  • HeadFirstDesignPattern是一本非常經(jīng)典的設(shè)計模式入門書籍”旄牵可是Javascript由于語言本身的限制胧弛,比較難以應(yīng)用。隨著新瀏覽器和Node.js開始普遍支持ES5, ES6,尤其是對類的支持侠畔。設(shè)計模式已經(jīng)變得觸手可及结缚,對于大型Node.js項目更是非常必要。 HeadFirstDesignPatternInJavascript正是js版本的設(shè)計模式實現(xiàn)软棺。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末红竭,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌茵宪,老刑警劉巖最冰,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異稀火,居然都是意外死亡暖哨,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進(jìn)店門凰狞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來篇裁,“玉大人鸳兽,你說我怎么就攤上這事焦读。” “怎么了馅而?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵斩熊,是天一觀的道長往枣。 經(jīng)常有香客問我,道長粉渠,這世上最難降的妖魔是什么分冈? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮霸株,結(jié)果婚禮上雕沉,老公的妹妹穿的比我還像新娘。我一直安慰自己去件,他們只是感情好坡椒,可當(dāng)我...
    茶點故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著尤溜,像睡著了一般倔叼。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上宫莱,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天丈攒,我揣著相機與錄音,去河邊找鬼授霸。 笑死巡验,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的碘耳。 我是一名探鬼主播显设,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼辛辨!你這毒婦竟也來了捕捂?” 一聲冷哼從身側(cè)響起瑟枫,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎指攒,沒想到半個月后力奋,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡幽七,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年景殷,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片澡屡。...
    茶點故事閱讀 39,841評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡猿挚,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出驶鹉,到底是詐尸還是另有隱情绩蜻,我是刑警寧澤,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布室埋,位于F島的核電站办绝,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏姚淆。R本人自食惡果不足惜孕蝉,卻給世界環(huán)境...
    茶點故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望腌逢。 院中可真熱鬧降淮,春花似錦、人聲如沸搏讶。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽媒惕。三九已至系吩,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間妒蔚,已是汗流浹背穿挨。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留面睛,地道東北人絮蒿。 一個月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓尊搬,卻偏偏與公主長得像叁鉴,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子佛寿,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,781評論 2 354