web前端面试题
页面导入样式时,使用link和@import有什么区别?
- link属于XHTML标签,除了加载CSS外,还能用于定义RSS, 定义rel连接属性等作用;而@import是CSS提供的,只能用于加载CSS;
- 页面被加载的时,link会同时被加载,而@import引用的CSS会等到页面被加载完再加载;
- import是CSS2.1 提出的,只在IE5以上才能被识别,而link是XHTML标签,无兼容问题;
简述一下你对HTML语义化的理解?
- 为了在没有CSS的情况下,页面也能呈现出很好地内容结构、代码结构:为了裸奔时好看;
- 用户体验:例如title、alt用于解释名词或解释图片信息、label标签的活用;
- 有利于SEO:和搜索引擎建立良好沟通,有助于爬虫抓取更多的有效信息:爬虫依赖于标签来确定上下文和各个关键字的权重;
- 方便其他设备解析(如屏幕阅读器、盲人阅读器、移动设备)以意义的方式来渲染网页;
- 便于团队开发和维护,语义化更具可读性,是下一步吧网页的重要动向,遵循W3C标准的团队都遵循这个标准,可以减少差异化。
GET和POST的区别?
- GET参数通过url传递,POST放在request body中。
- GET回退时不会再发起请求,POST会。
- GET请求会主动被浏览器cache,而POST不会,除非手动设置。
- GET请求是安全和幂等的
- 所谓安全的意味着该操作用于获取信息而非修改信息。换句话说,GET 请求一般不应产生副作用。就是说,它仅仅是获取资源信息,就像数据库查询一样,不会修改,增加数据,不会影响资源的状态。
- 幂等的意味着对同一URL的多个请求应该返回同样的结果。
- GET只接受ASCII字符的参数数据类型,而POST没有限制
- GET请求只支持进行url编码,而POST支持多种编码方式
- GET产生的URL地址可以被收藏,而POST不可以,因为POST的请求数据在body中,无法收藏
- GET请求会被保留在历史记录里,而POST不会
HTML5的离线储存怎么使用,工作原理能不能解释一下
在用户没有与因特网连接时,可以正常访问站点和应用,在用户与因特网连接时,更新用户机器上的缓存文件;
原理:
HTML5 的离线存储是基于一个新建的.appcache 文件的缓存机制(不是存储技术),通过这个文件上的解析清单离线存储资源,这些资源就会像cookie一样被存储了下来。之后当网络在处于离线状态下时,浏览器会通过被离线存储的数据进行页面展示;
如何使用:
1. 页面头部像下面一样加入一个 manifest 的属性;
2. 在 cache.manifest 文件的编写离线存储的资源;
CACHE MANIFEST #v0.11
CACHE:
js/app.js
css/style.css
NETWORK:
resource/logo.png
FALLBACK:
/ /offline.html
3. 在离线状态时,操作 window.applicationCache 进行需求实现
浏览器是怎么对 HTML5 的离线储存资源进行管理和加载的呢?
在线的情况下,浏览器发现 html 头部有 manifest 属性,它会请求 manifest 文件,如果是第一次访问 app,那么浏览器就会根据 manifest 文件的内容下载相应的资源并且进行离线存储。如果已经访问过 app 并且资源已经离线存储了,那么浏览器就会使用离线的资源加载页面,然后浏览器会对比新的 manifest 文件与旧的 manifest 文件,如果文件没有发生改变,就不做任何操作,如果文件改变了,那么就会重新下载文件中的资源并进行离线存储;离线的情况下,浏览器就直接使用离线存储的资源;
如何实现浏览器内多个标签页之间的通信?
调用 localstorge、cookies 等本地存储方式
方法一:使用localStorage
使用localStorage.setItem(key,value);添加内容
使用storage事件监听添加、修改、删除的动作
window.addEventListener("storage",function(event) {
$("#name").val(event.key+”=”+event.newValue);
});
方法二、使用cookie+setInterval
<input id="name">
<input type="button" id="btnOK" value="发送">
// 页面1
$(function(){
$("#btnOK").click(function(){
varname=$("#name").val();
document.cookie="name="+name;
});
});
// 页面2
//获取Cookie的内容
function getKey(key) {
return JSON.parse("{\"" + document.cookie.replace(/;\s+/gim, "\",\"").replace(/=/gim, "\":\"") + "\"}")[key];
}
//每隔1秒获取Cookie的内容
setInterval(function() {
console.log(getKey("name"));
}, 1000);
webSocket如何兼容低浏览器?
1. Adobe Flash Socket
2. ActiveX HTMLFile (IE)
3. 基于 multipart 编码发送 XHR
4. 基于长轮询的 XHR
请描述一下 cookies,sessionStorage 和 localStorage 的区别?
- cookie 是网站为了标示用户身份而储存在用户本地终端(Client Side)上的数据(通常经过加密);
- cookie 数据始终在同源的 http 请求中携带(即使不需要),记会在浏览器和服务器间来回传递;
- sessionStorage 和 localStorage 不会自动把数据发给服务器,仅在本地保存;
- 存储大小:
- cookie数据大小不能超过4k;
- sessionStorage和localStorage 虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大;
- 有期时间:
- localStorage
存储持久数据,浏览器关闭后数据不丢失除非主动删除数据; - sessionStorage
数据在当前浏览器窗口关闭后自动删除; - cookie
设置的 cookie 过期时间之前一直有效,即使窗口或浏览器关闭;
- localStorage
页面可见性(Page Visibility)API 可以有哪些用途?
通过 visibilityState 的值检测页面当前是否可见,以及打开网页的时间等;在页面被切换到其他后台进程的时候,自动暂停音乐或视频的播放;
Page Visibility(页面可见性) API介绍、微拓展
网页验证码是干嘛的,是为了解决什么安全问题?
防止恶意注册和暴力破解 所谓恶意注册和暴力破解都是用软件进行的。 人工注册再快,也需要一项一项输入资料,速度很慢,对服务器基本没有影响。如果没有验证码可以使用软件注册的话,可以同时运行成千上万个线程,一次能注册成千上万个用户,让服务器的数据库很快变得臃肿不堪,运行效率下降。 如果一个无聊的人或竞争对手对某网站怀有敌意,那么这种方法很容易就能让对方瘫痪。
如何在页面上实现一个圆形的可点击区域
1. map+area或者svg
2. border-radius
3. 纯js实现, 需要求一个点在不在圆上简单算法、获取鼠标坐标等等;
实现不使用 border 画出1px高的线,在不同浏览器的Quirksmode和CSSCompat模式下都能保持同一效果。
<div style="height:1px;overflow:hidden;background:black"></div>
让js不去查找原型
hasOwnProperty不会去查找原型
let,const和var的区别
声明方式 | 变量提升 | 作用域 | 初始值 | 重复定义 |
---|---|---|---|---|
const | 否 | 块级 | 需要 | 不允许 |
let | 否 | 块级 | 不需要 | 不允许 |
var | 是 | 函数级 | 不需要 | 允许 |
变量提升:const 和 let 必须先声明再使用,不支持变量提升
作用域:const,let 支持块级作用域,有效避免变量覆盖
块级作用域:在外层不能直接访问内层变量
const 定义常量,该常量不能赋值,但该常量的属性可以赋值
全局变量不再设置为顶层对象(window)的属性,有效避免全局变量污染
符合预期的 for 循环初始值:const 声明的变量必须设置初始值,且不能重复赋值。
重复定义:const 和 let 不支持重复定义
怎么判断null,undefined和NaN
1. 判断null
// 判断null,typeof null的结果为object
function isNull (obj) {
if (!obj && typeof obj !== "undefined" && obj != 0) {
return true
}
return false
}
console.log(isNull(null))
2. 判断undefined
function isUndefind (obj) {
return typeof obj === 'undefined'
}
console.log(isUndefind(undefined)) // true
3. 判断null和undefined
// null == undefined
function isNullOrUndef (obj) {
return obj == undefined
}
console.log(isNullOrUndef(null)) // true
console.log(isNullOrUndef(undefined)) // true
function isUndefOrNull (obj) {
return obj == null
}
console.log(isUndefOrNull(null)) // true
console.log(isUndefOrNull(undefined)) // true
for循环作用域问题
for (var i = 0; i < 5; i++) {
setTimeout(function () {
console.log(i)
}, 1000)
}
// 5
// 5
// 5
// 5
// 5
以上代码输出和我们预期的不符,主要是因为var只有函数作用域和全局作用域,而for循环并不是一个函数体。最终循环结束时,i为5,而setTimeout并不会立即执行,而是会先进入setTimeout队列,等待执行,当执行队列时,获取到的i都为5
// 使用闭包修改
for(var i = 0; i < 5; i++) {
(function (i) {
setTimeout(function () {
console.log(i)
}, 1000)
})(i)
}
// 0
// 1
// 2
// 3
// 4
// 用promise改写
for(var i = 0; i < 5; i++) {
new Promise(function (resolve, reject) {
resolve(i)
}).then(function (i) {
setTimeout(function () {
console.log(i)
}, 1000)
})
}
// 0
// 1
// 2
// 3
// 4
// 使用es6的let改写,因为let具有块级作用域
for(let i = 0; i < 5; i++) {
setTimeout(function () {
console.log(i)
}, 1000)
}
Promise是在new时就运行吗?
是的。
getElementById和querySelector的区别
getElementById是dom节点的引用(动态引用)
querySelector是dom节点的复制(静态引用)
bind,call和apply的区别
JavaScript中的每一个Function都有call和apply方法
共同点
三者都可以显示改变函数this指向不同点
apply只接受两个参数,包括新的this指向对象和一个数组参数
call可以接受多个参数,包括新的this指向对象,以及多个调用参数
bind可以和call一样接受多个参数,但是因为bind是返回的仍然是一个函数,所以可以直接传参,也可以在后续调用的时候再进行传参
/*apply()方法*/
function.apply(thisObj[, argArray])
/*call()方法*/
function.call(thisObj[, arg1[, arg2[, [,...argN]]]]);
apply妙用
// 让Math.max支持传入数组
var arr = [3, 11, 5];
var max = Math.max.apply(null, arr);
console.log(max); // 11
var arr1 = [1, 2, 3];
var arr2 = [4, 5, 6];
// 合并两个数组,并返回新数组长度
var len = Array.prototype.push.apply(arr1, arr2);
console.log(len); // 6
另外:bind是属于引用绑定,call和apply是属于直接绑定
Javascript的多态性
当我们向两种地图对象分别发出“展示地 图”的消息时,会分别调用它们的 show 方法,就会产生各自不同的执行结果。对象的多态性提示我们,“做什么”和“怎么去做”是可以分开的,即使以后增加了其他地图,renderMap 函数不需要做任何改变,如下所示:
var googleMap = {
show: function () {
console.log('开始渲染谷歌地图');
}
};
var bdMap = {
show: function () {
console.log('开始渲染百度地图');
}
};
var renderMap = function( map ){
if ( map.show instanceof Function ){
map.show();
}
};
renderMap( googleMap ); // 输出:开始渲染谷歌地图
renderMap( bdMap ); // 输出:开始渲染百度地图
箭头函数的this指向以及与function区别
- 箭头函数不绑定this,会捕获其所在的上下文的this值,作为自己的this值
- 箭头函数是匿名函数,不能用于构造函数,即是不能被new(运行便会报错:Uncaught TypeError: xxx is not a constructor)
- 箭头函数调用必须在定义之后
- 箭头函数没有arguments,取而代之用rest函数代替
- 箭头函数没有原型属性
- 箭头函数不能做Generator函数,不能使用yield关键字
- 箭头函数通过 call()或apply() 方法调用一个函数时,只传入了一个参数,对 this 并没有影响。(任何方法都无法改变箭头函数的this指向)
另外:ES7提出了“函数绑定”(function bind)运算符,用来取代call、apply、bind调用,函数绑定运算符是并排的两个双冒号(::),双冒号左边是一个对象,右边是一个函数。该运算符会自动将左边的对象,作为上下文环境(即this对象),绑定到右边的函数上面。
JS原型链的终点是什么?
首先要明确一点,原型链是指对象的原型链,所以原型链上的所有节点都是对象,不能是字符串、数字、布尔值等原始类型。
另外,规范要求原型链必须是有限长度的(从任一节点出发,经过有限步骤后必须到达一个终点。显然也不能有环。)
那么,应该用什么对象作为终点呢?很显然应该用一个特殊的对象。
好吧,Object.prototype
确实是个特殊对象,我们先假设用它做终点。那么考虑一下,当你取它的原型时应该怎么办?即
Object.prototype.__proto__;
应该返回什么?
取一个对象的属性时,可能发生三种情况:
如果属性存在,那么返回属性的值。
如果属性不存在,那么返回undefined。
不管属性存在还是不存在,有可能抛异常。
我们已经假设Object.prototype
是终点了,所以看起来不能是情况1。另外,抛出异常也不是好的设计,所以也不是情况3。那么情况2呢,它不存在原型属性,返回undefined怎么样?也不好,因为返回undefined一种解释是原型不存在,但是也相当于原型就是undefined。这样,在原型链上就会存在一个非对象的值。
所以,最佳选择就是null。一方面,你没法访问null的属性,所以起到了终止原型链的作用;另一方面,null在某种意义上也是一种对象,即空对象,因为null一开始就是为表示一个“空”的对象存在的。这样一来,就不会违反“原型链上只能有对象”的约定。
所以,“原型链的终点是null”虽然不是必须不可的,但是却是最合理的。
移动端点击穿透
点击穿透现象有3种:
点击穿透问题:点击蒙层(mask)上的关闭按钮,蒙层消失后发现触发了按钮下面元素的click事件。蒙层的关闭按钮绑定的是touch事件,而按钮下面元素绑定的是click事件,touch事件触发之后,蒙层消失了,300ms后这个点的click事件fire,event的target自然就是按钮下面的元素,因为按钮跟蒙层一起消失了
跨页面点击穿透问题:如果按钮下面恰好是一个有href属性的a标签,那么页面就会发生跳转,因为 a标签跳转默认是click事件触发 ,所以原理和上面的完全相同
另一种跨页面点击穿透问题:这次没有mask了,直接点击页内按钮跳转至新页,然后发现新页面中对应位置元素的click事件被触发了,和蒙层的道理一样,js控制页面跳转的逻辑如果是绑定在touch事件上的,而且新页面中对应位置的元素绑定的是click事件,而且页面在300ms内完成了跳转,三个条件同时满足,就出现这种情况了
解决方案
-
只用touch事件
把所有click事件换成touch事件(touchstart, touchend, tap)
-
只用click
缺点是会带来300ms的延迟
tap后延迟300ms再隐藏mask
-
pointer-events
mask隐藏后,给按钮下面元素添加pointer-events:none;300ms后去掉样式,缺点是用户手速快的话会发现点击没有反应
fastclick库
image的上传进度以及如何上传
- 通过轮询或者长链接的方式在上传文件的同时用Ajax去读取,这需要后端提供读取文件上传进度的接口。这个方案显得很笨重,所以一般还是采用flash的解决方案。
- XMLHttpRequest Level2已经支持用Ajax直接传输文件,并且提供onprogress,onloadstart,onloadend,onload等事件来跟踪进度,事件的ProgressEvent参数中提供了loaded和total可以用来计算百分比,但是很遗憾的是IE仍需要Flash提供兼容方案。ios不能上传本地文件,所以Flash方案能覆盖大部分客户端。
从输入URL到页面渲染出来的过程
跨域的几种方式以及区别?
JSONP
使用script标签的src不受跨域限制的特点,允许用户传递一个callback参数给服务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据,这样客户端就可以随意定制自己的函数来自动处理返回数据了。
优点:
它不像XHR对象实现ajax请求那样受到同源政策的限制,它的兼容性更好,XHR在进行ajax请求时,为了兼容IE,还需创建ActiveX对象。并且在请求完毕之后可以通过回调函数的方式将结果回传
缺点:
它只支持get请求而不支持post等其它类型的HTTP请求;它只支持跨域HTTP请求这种情况,不能解决不同域的两个页面之间如何进行JavaScript调用问题
CORS
CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。它允许浏览器向跨源(协议 + 域名 + 端口)服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。
-
CORS允许在下列场景中使用跨域 HTTP 请求:
- 由 XMLHttpRequest 或 Fetch 发起的跨域 HTTP 请求。
- Web 字体 (CSS 中通过 @font-face 使用跨域字体资源), 因此,网站就可以发布 TrueType 字体资源,并只允许已授权网站进行跨站调用。
- WebGL 贴图
- 使用 drawImage 将 Images/video 画面绘制到 canvas
- 样式表
- Scripts (未处理的异常)
-
概述:
跨域资源共享标准新增了一组 HTTP 首部字段,允许服务器声明哪些源站有权限访问哪些资源。另外,规范要求,对那些可能对服务器数据产生副作用的 HTTP 请求方法(特别是 GET 以外的 HTTP 请求,或者搭配某些 MIME 类型的 POST 请求),浏览器必须首先使用 OPTIONS 方法发起一个预检请求(preflight request),从而获知服务端是否允许该跨域请求。服务器确认允许之后,才发起实际的 HTTP 请求。在预检请求的返回中,服务器端也可以通知客户端,是否需要携带身份凭证(包括 Cookies 和 HTTP 认证相关数据)。
-
简单请求:
某些请求不会触发 CORS 预检请求,我们称这样的请求为简单请求。满足下列条件,即为简单请求。
- GET
- POST
- HEAD
-
Fetch规范定义了对 CORS 安全的首部字段集合,不得人为设置该集合之外的其他首部字段。该集合为:
- Accept
- Accept-Language
- Content-Language
- Content-Type (需要注意额外的限制)
- DPR
- Downlink
- Save-Data
- Viewport-Width
- Width
-
Content-Type 的值仅限于下列三者之一:
- text/plain
- multipart/form-data
- application/x-www-form-urlencoded
-
请求中的任意XMLHttpRequestUpload 对象均没有注册任何事件监听器;
XMLHttpRequestUpload 对象可以使用 XMLHttpRequest.upload 属性访问。
-
请求中没有使用 ReadableStream 对象。
注意: 这些跨域请求与浏览器发出的其他跨域请求并无二致。如果服务器未返回正确的响应首部,则请求方不会收到任何数据。因此,那些不允许跨域请求的网站无需为这一新的 HTTP 访问控制特性担心。
-
预检请求
与前述简单请求不同,“需预检的请求”要求必须首先使用 OPTIONS 方法发起一个预检请求到服务器,以获知服务器是否允许该实际请求。"预检请求“的使用,可以避免跨域请求对服务器的用户数据产生未预期的影响。
当请求满足下述任一条件时,即应首先发送预检请求:- 使用了下面任一 HTTP 方法:
- PUT
- DELETE
- CONNECT
- OPTIONS
- TRACE
- PATCH
- 人为设置了对 CORS 安全的首部字段集合之外的其他首部字段。该集合为:
- Accept
- Accept-Language
- Content-Language
- Content-Type (需要注意额外的限制)
- DPR
- Downlink
- Save-Data
- Viewport-Width
- Width
- Content-Type 的值不属于下列之一:
- text/plain
- multipart/form-data
- application/x-www-form-urlencoded
- 请求中的XMLHttpRequestUpload 对象注册了任意多个事件监听器。
- 请求中使用了ReadableStream对象。
- 使用了下面任一 HTTP 方法:
附带身份凭证的请求
var invocation = new XMLHttpRequest();
var url = 'http://bar.other/resources/credentialed-content/';
function callOtherDomain(){
if(invocation) {
invocation.open('GET', url, true);
invocation.withCredentials = true;
invocation.onreadystatechange = handler;
invocation.send();
}
}
第 7 行将 XMLHttpRequest 的 withCredentials 标志设置为 true,从而向服务器发送 Cookies。因为这是一个简单 GET 请求,所以浏览器不会对其发起“预检请求”。但是,如果服务器端的响应中未携带 Access-Control-Allow-Credentials: true ,浏览器将不会把响应内容返回给请求的发送者。
-
附带身份凭证的请求与通配符
如果客户端请求设置withCredentials=true时,服务器端不能设置Access-Control-Allow-Origin 的值为“*”,否则请求将会失败,必须设置对应的域名。
-
HTTP请求首部字段
- Origin(表明预检请求或实际请求的源站)
- Access-Control-Request-Method(将实际请求所使用的 HTTP 方法告诉服务器。)
- Access-Control-Request-Headers(将实际请求所携带的首部字段告诉服务器。)
-
HTTP请求响应字段
- Access-Control-Allow-Origin(指定了允许访问该资源的外域 URI。)
- Access-Control-Expose-Headers(跨域访问时,XMLHttpRequest对象的getResponseHeader()方法只能拿到一些最基本的响应头,Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma,如果要访问其他头,则需要服务器设置本响应头。)
- Access-Control-Max-Age(预检请求能够被访问多少秒)
- Access-Control-Allow-Credentials(指定了实际的请求是否可以使用credentials)
- Access-Control-Allow-Methods(指明了实际请求所允许使用的 HTTP 方法。)
- Access-Control-Allow-Headers(指明了实际请求中允许携带的首部字段。)
比较:
JSONP只能实现get请求,而CORS支持所有类型的HTTP请求
使用CORS,开发者可以使用普通的XHR发起请求和获得数据,比起JSONP有更好的错误处理
JSONP主要被老的浏览器支持,而绝大多数现代浏览器都已经支持CORS
XSS和CSRF分别是什么?
Xss
Xss(跨站脚本攻击),全称Cross Site Scripting,恶意攻击者向web页面中植入恶意js代码,当用户浏览到该页时,植入的代码被执行,达到恶意攻击用户的目的。
Xss攻击的危害
盗取各类用户账号
窃取有商业价值的资料
非法转账操作
强制发送电子邮件
控制受害者机器向其它网站发起攻击
等等...
原因分析
原因:没有对客户端提交的数据进行校验分析,导致恶意代码被植入。
根本解决:不要相信任何客户端提交的任何数据!!!
Xss攻击的分类
- 反射型Xss攻击(在url使用脚本注入)
- 存贮型xss攻击(在input等输入框输入,并存储到数据库)
- DOMBasedXSS(基于Dom的跨站点脚本攻击)
前提是易受攻击的网站有一个HTML页面采用不安全的方式从document.location或document.URL或document.referrer获取数据(或者任何其他攻击者可以修改的对象),所以应该避免直接从document.location或document.URL或document.referrer获取数据。
Xss的漏洞修复
- 对用户表单输入的数据进行转义,然后再存入数据库
- 对信息展示页面也需要进行转义,防止Javascript在页面上执行
- 将重要的cookie标记为http only, 这样的话Javascript 中的document.cookie语句就不能获取到cookie了
- 对表单信息进行验证,规范输入
CSRF
CSRF(Cross-site request forgery跨站请求伪造)是一种依赖web浏览器的、被混淆过的代理人攻击。
CSRF漏洞修复
- 所有需要用户登录之后才能执行的操作属于重要操作,这些操作传递参数应该使用post方式,更加安全;
- 为防止跨站请求伪造,我们在某次请求的时候都要带上一个csrf_token参数,用于标识请求来源是否合法,csrf_token参数由系统生成,存储在SESSION中。
怎么只让部分用户看到新发布的页面改变?
node
为什么用Nodejs,它有哪些缺点?
- 事件驱动,通过闭包很容易实现客户端的生命活期。
- 不用担心多线程,锁,并行计算的问题
- V8引擎速度非常快
- 对于游戏来说,写一遍游戏逻辑代码,前端后端通用
缺点
- nodejs更新很快,可能会出现版本兼容
- nodejs还不算成熟,还没有大制作
- nodejs不像其他的服务器,对于不同的链接,不支持进程和线程操作
如何避免回调地域
- 模块化:将回调函数转换为独立的函数
- 使用流程控制库,例如[aync]
- 使用Promise
- 使用aync/await
node如何使用多处理器
nodejs是单线程,这意味着Node只能利用一个处理器来工作。但多数服务器都有多个核。好在nodejs提供了cluster模块,可以把任务分配给子进程。每个子进程有些特殊能力,比如能与其他子进程共享socket连接。当用cluster时,主进程不会参与每个具体的事务中,主进程管理所有的子进程,但当子进程与I/O操作交互时,它们是直接进程操作的,不需要通过主进程。
var cluster = require('cluster');
var http = require('http');
var numCPUs = require('os').cpus().length;
if (cluster.isMaster) {
//创建工作进程
for (var i = 0; i < numCPUs; i++) {
cluster.fork();
}
cluster.on('death', function(worker) {
console.log('worker' + worker.pid + 'died');
});
} else {
//工作进程创建http服务
http.Server(function(req, res) {
res.writeHead(200);
res.end("Hello world\n");
}).listen(8000);
}
cluster工作的原理是每一个Node进程要么是主进程,要么成为工作进程。当一个主进程调用cluster.fork()方法时,它会创建于主进程一模一样的子进程,除了两个让每个进程可以检查自己是父/子进程的属性以外。在主进程cluster.isMaster会返回true,而cluster.isWorker()会返回false,在工作进程中则相反。
除了共享socket外,还能利用cluster做更多事情,因为它是基于child_process模块的,这个模块会提供一系列属性,其中最有用一些可以检查子进程健康状态,在上面例子中,当子进程死亡时,主进程会用console.log()输出死亡进程,既然监测到了死亡进程,那么我们可以在这个子进程死亡时,再重新创建一个新的子进程。
cluster.on('death', function(worker)
{
console.log('worker' + worker.pid + 'died');
cluster.fork();
});
node大文件下载
使用createReadStream读取信息,encoding:binary
通过HttpRequest的Range 请求http头文件中的断点信息,如果没有则为undefined,格式(range: bytes=232323-),并返回206编码(206一般为只要请求部分数据时的响应)
什么是stub?举个使用场景
stub是用于模拟一个组件或模块的函数或程序。在测试用例中,简单的说,你可以用stub去模拟一个方法,从而避免调用真实的方法,使用stub你还可以返回虚构的结果。你可以配合断言使用stub。
举个例子,在一个读取文件的场景中,当你不想读取一个真正的文件时
var fs = require('fs');
var readFileStub = sinon.stub(fs, 'readFile', function(path, cb) {
return cb(null, 'filecontent');
});
expect(readFileStub).to.be.called;
readFileStub.restore();
在单元测试中:Stub是完全模拟一个外部依赖,而Mock常用来判断测试通过还是失败
CSS
介绍一下标准的CSS的盒子模型?与低版本IE的盒子模型有什么不同的?
CSS盒子模型:由四个属性组成的外边距(margin)、内边距(padding)、边界(border)、内容区(width和height);
- 标准的css盒子模型宽高就是content
- 低端IE css盒子模型宽高 padding+border+content
display:none与visibility:hidden的区别是什么?
二者都是用来隐藏元素的显示效果的,但区别是:
* display: none不再占据页面空间
* visibility: hidden依然占据页面空间
CSS权重优先级是如何计算的?
优先级就近原则
同权重以最近者为准 载入样式以最后载入的样式为准;
同权重下:内联样式表(标签内部) > 嵌入样式表(当前文件) > 外部样式表(外部文件)
!import > id > class > tag
Import比内联样式优先级高
层叠重要度层次
带有important的用户样式
带有important的作者样式
作者样式
用户样式
浏览器/用户代理应用的样式
权重分为a b c d ,4个等级,每个等级以10为基数分别是
内联样式(或行内样式)a=1
b = ID选择器个数
c = 类、伪类和属性选择器的个数
d = 元素选择器和伪元素选择器的个数
让页面的字变清晰,变细用CSS怎么做?
-webkit-font-smoothing: antialiased;