InterviewQuestions
some questions and answers
Q1:JS 繼承有哪幾種方式厘唾?
首先有兩個構(gòu)造函數(shù)Animal,Dog
function Animal(){
this.species = 'animal';
}
function Dog(name,color){
this.name = name;
this.color = color;
}
我們要讓Dog繼承Animal的屬性画机。(通過utils.inherits只能繼承基于原型的屬性)
ANSWER:
1.構(gòu)造函數(shù)綁定
使用apply或者call方法
function Dog(name,color){
Animal.apply(this,arguments);
//Animal.call(this,name,color);
this.name = name;
this.color = color;
}
var lucky = new Dog('lucky','brown');
console.log(lucky.species; // animal'
2.prototype模式
Dog.prototype = new Animal();
Dog.prototype.constructor = Dog;
var lucky = new Dog('lucky','Brown');
console.log(lucky.species);
先將Dog的prototype對象指向一個Animal的實例,然后將prototype.constructor指向構(gòu)造函數(shù)Dog税肪,這樣就實現(xiàn)了繼承
3.直接繼承prototype
function Animal(){}
Animal.prototype.species = 'animal';
function Dog(name,color){
this.name = name;
this.color = color;
};
Dog.prototype = Animal.prototype;
Dog.prototype.constructor = Dog;
var lucky = new Dog('lucky','brown');
console.log(lucky.species);
這樣做的好處是效率高罐监,速度快沼撕,省內(nèi)存侧啼,但是Dog.prototype和Animal.prototype現(xiàn)在指向了同一個對象,修改Dog.prototype會直接修改Animal.prototype泪蔫。
4.利用空對象作為中介
var F = function(){};
F.prototype = Animal.prototype;
Dog.prototype = new F();
Dog.prototype.constructor = Dog;
console.log(Animal.prototype.constructor); //Animal
var lucky = new Dog('lucky','brown');
console.log(lucky.species); // animal
5.拷貝繼承
function extend(Child,Parent){
var p = Parent.prototype;
var c = Child.prototype;
for(var i in p){
c[i] = p[i];
}
c.uber = p;//為子對象留有可以訪問父對象的接口
}
function Dog(name,color){}
extend(Dog,Animal);
var lucky = new Dog('lucky','brown');
console.log(lucky.species); //animal
Q2:JS 嚴(yán)格模式跟普通模式的區(qū)別棒旗?
ANSWER:
1.在js文件中使用'use strict‘進入嚴(yán)格模式
- 消除Javascript語法的一些不合理、不嚴(yán)謹(jǐn)之處撩荣,減少一些怪異行為;
- 消除代碼運行的一些不安全之處铣揉,保證代碼運行的安全;
- 提高編譯器效率餐曹,增加運行速度逛拱;
- 為未來新版本的Javascript做好鋪墊。
2.會將拼寫錯誤轉(zhuǎn)成異常
'use strict';
var maxNumber = 100;
maxNumbre = 10;//ReferenceError
console.log(maxNumber);
3.全局變量顯式聲明
正常模式中台猴,一個變量未聲明直接賦值朽合,默認(rèn)是全局變量,嚴(yán)格模式中禁止這種用法饱狂,全局變量必須顯示聲明
'use strict';
v1 = 1;//error
4.禁用with旁舰,eval
5.禁止刪除聲明變量
'use strict';
var x;
delete x; //語法錯誤
Q3:V8垃圾回收機制
ANSWER:
V8使用是垃圾回收器(GC)進行回收,
具體信息可以參考下列文章:
1.阿里云團隊博客
2.Segmentfault
Q4:web后端緩存策略有哪些嗡官?
ANSWER:
1.利用redis(node-redis)或 memcached
在服務(wù)器與數(shù)據(jù)庫之間設(shè)置redis數(shù)據(jù)庫作為緩存介質(zhì)箭窜,在需要緩存的請求到達時,先檢查redis數(shù)據(jù)庫是否有衍腥,使用
var redis = require('redis').createClient();
redis.get('key',function (err,reply){
//logic code
});
進行判斷磺樱,如果不存在,則從對應(yīng)數(shù)據(jù)庫獲取數(shù)據(jù)婆咸,然后將數(shù)據(jù)寫入redis數(shù)據(jù)庫竹捉,并設(shè)置過期時間。
var redis = require('redis').createClient();
redis.set('key','value');
redis.expire('key',1000);//ms
2.max-age和cache-control
主要針對靜態(tài)資源的緩存
response.setHeader('Cache-Control','public,max-age=3600');
3.etag
從req.headers里取'if-none-match',如果存在且hash值一致尚骄,返回304
var hashStr = "A hash string.";
var hash = require("crypto").createHash('sha1').update(hashStr).digest('base64');
require("http").createServer(function(req, res){
if(req.headers['if-none-match'] == hash){
res.writeHead(304);
res.end();
return;
}
res.writeHead(200, { "Etag": hash })
res.write(hashStr); res.end();
}).listen(9999);
這樣可以在輸出沒有變化的時候過濾請求块差,減輕服務(wù)器壓力。
4.CDN緩存
將圖片等數(shù)據(jù)放在CDN緩存倔丈,可以大大減輕自己服務(wù)器壓力憨闰,可以參考這個模塊express-cdn
參考資料:
Web開發(fā)后端緩存思路
Etag緩存
緩存策略
Q5:TCP與UDP的區(qū)別?
A:
1.TCP是面向鏈接的需五,雖然說網(wǎng)絡(luò)的不安全不穩(wěn)定特性決定了多少次握手都不能保證連接的可靠性鹉动,但TCP的三次握手在最低限度上(實際上也很大程度上保證了)保證了連接的可靠性;
而UDP不是面向連接的,UDP傳送數(shù)據(jù)前并不與對方建立連接宏邮,對接收到的數(shù)據(jù)也不發(fā)送確認(rèn)信號泽示,發(fā)送端不知道數(shù)據(jù)是否會正確接收缸血,當(dāng)然也不用重發(fā),所以說UDP是無連接的械筛、不可靠的一種數(shù)據(jù)傳輸協(xié)議捎泻。
2.也正由于1所說的特點,使得UDP的開銷更小數(shù)據(jù)傳輸速率更高埋哟,因為不必進行收發(fā)數(shù)據(jù)的確認(rèn)族扰,所以UDP的實時性更好。
Q6:為什么選擇mocha這種測試框架定欧?
ANSWER:
- 與node完美結(jié)合,可以在node端和瀏覽器端測試
- 可以使用不同的斷言庫(chai,should等)
- 異步方法測試簡單
- 支持before,after等hook
Q7:TDD/BDD分別是什么怒竿?
ANSWER:
TDD(測試驅(qū)動開發(fā))
即先寫測試用例砍鸠,再一一實現(xiàn)功能
BDD(行為驅(qū)動開發(fā))
先寫功能,再對功能進行測試耕驰,更貼近人類思維方式
Q8:閉包
ANSWER:
我理解的閉包就是外部函數(shù)獲取內(nèi)部函數(shù)私有屬性的一種方法爷辱,簡單的用下面的例子解釋一下:
function myHouse(){
var __myname = 'Kevin';
var getMyname = function(){
return __myname;
};
return getMyname;
}
var getName = myHouse();
console.log(getName());//Kevin
即通過在myHouse()中返回getMyname函數(shù),getMyname函數(shù)中返回私有變量__myname朦肘,從而獲取私有變量饭弓,同時保護私有變量不會直接暴露給外部,以免改變私有變量值媒抠。
Q9:node.js跨域問題
ANSWER:
var express = require('express');
var app = express();//設(shè)置跨域訪問
app.all('*', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*"); //核心
res.header("Access-Control-Allow-Headers", "X-Requested-With"); //核心
res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS"); //核心
res.header("X-Powered-By",' 3.2.1') ;
res.header("Content-Type", "application/json;charset=utf-8"); next();
});
app.get('/auth/:id/:password', function(req, res) {
res.send({
id:req.params.id,
name: req.params.password
});
});
app.listen(3000);console.log('Listening on port 3000...');
Q10:ES6新特性:
ANSWER:
這個寫的很不錯弟断,推薦閱讀
阮一峰的日志