web前端面试题

web前端面试题

页面导入样式时,使用link和@import有什么区别?

  1. link属于XHTML标签,除了加载CSS外,还能用于定义RSS, 定义rel连接属性等作用;而@import是CSS提供的,只能用于加载CSS;
  2. 页面被加载的时,link会同时被加载,而@import引用的CSS会等到页面被加载完再加载;
  3. import是CSS2.1 提出的,只在IE5以上才能被识别,而link是XHTML标签,无兼容问题;

简述一下你对HTML语义化的理解?

  1. 为了在没有CSS的情况下,页面也能呈现出很好地内容结构、代码结构:为了裸奔时好看;
  2. 用户体验:例如title、alt用于解释名词或解释图片信息、label标签的活用;
  3. 有利于SEO:和搜索引擎建立良好沟通,有助于爬虫抓取更多的有效信息:爬虫依赖于标签来确定上下文和各个关键字的权重;
  4. 方便其他设备解析(如屏幕阅读器、盲人阅读器、移动设备)以意义的方式来渲染网页;
  5. 便于团队开发和维护,语义化更具可读性,是下一步吧网页的重要动向,遵循W3C标准的团队都遵循这个标准,可以减少差异化。

GET和POST的区别?

  1. GET参数通过url传递,POST放在request body中。
  2. GET回退时不会再发起请求,POST会。
  3. GET请求会主动被浏览器cache,而POST不会,除非手动设置。
  4. GET请求是安全和幂等的
    • 所谓安全的意味着该操作用于获取信息而非修改信息。换句话说,GET 请求一般不应产生副作用。就是说,它仅仅是获取资源信息,就像数据库查询一样,不会修改,增加数据,不会影响资源的状态。
    • 幂等的意味着对同一URL的多个请求应该返回同样的结果。
  5. GET只接受ASCII字符的参数数据类型,而POST没有限制
  6. GET请求只支持进行url编码,而POST支持多种编码方式
  7. GET产生的URL地址可以被收藏,而POST不可以,因为POST的请求数据在body中,无法收藏
  8. 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



// 页面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 过期时间之前一直有效,即使窗口或浏览器关闭;

页面可见性(Page Visibility)API 可以有哪些用途?

通过 visibilityState 的值检测页面当前是否可见,以及打开网页的时间等;在页面被切换到其他后台进程的时候,自动暂停音乐或视频的播放;
Page Visibility(页面可见性) API介绍、微拓展

网页验证码是干嘛的,是为了解决什么安全问题?

防止恶意注册和暴力破解 所谓恶意注册和暴力破解都是用软件进行的。 人工注册再快,也需要一项一项输入资料,速度很慢,对服务器基本没有影响。如果没有验证码可以使用软件注册的话,可以同时运行成千上万个线程,一次能注册成千上万个用户,让服务器的数据库很快变得臃肿不堪,运行效率下降。 如果一个无聊的人或竞争对手对某网站怀有敌意,那么这种方法很容易就能让对方瘫痪。

如何在页面上实现一个圆形的可点击区域

1. map+area或者svg
2. border-radius
3. 纯js实现, 需要求一个点在不在圆上简单算法、获取鼠标坐标等等;

实现不使用 border 画出1px高的线,在不同浏览器的Quirksmode和CSSCompat模式下都能保持同一效果。

让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区别

  1. 箭头函数不绑定this,会捕获其所在的上下文的this值,作为自己的this值
  2. 箭头函数是匿名函数,不能用于构造函数,即是不能被new(运行便会报错:Uncaught TypeError: xxx is not a constructor)
  3. 箭头函数调用必须在定义之后
  4. 箭头函数没有arguments,取而代之用rest函数代替
  5. 箭头函数没有原型属性
  6. 箭头函数不能做Generator函数,不能使用yield关键字
  7. 箭头函数通过 call()或apply() 方法调用一个函数时,只传入了一个参数,对 this 并没有影响。(任何方法都无法改变箭头函数的this指向

另外:ES7提出了“函数绑定”(function bind)运算符,用来取代call、apply、bind调用,函数绑定运算符是并排的两个双冒号(::),双冒号左边是一个对象,右边是一个函数。该运算符会自动将左边的对象,作为上下文环境(即this对象),绑定到右边的函数上面。

JS原型链的终点是什么?

首先要明确一点,原型链是指对象的原型链,所以原型链上的所有节点都是对象,不能是字符串、数字、布尔值等原始类型。

另外,规范要求原型链必须是有限长度的(从任一节点出发,经过有限步骤后必须到达一个终点。显然也不能有环。)

那么,应该用什么对象作为终点呢?很显然应该用一个特殊的对象。

好吧,Object.prototype确实是个特殊对象,我们先假设用它做终点。那么考虑一下,当你取它的原型时应该怎么办?即

Object.prototype.__proto__;

应该返回什么?

取一个对象的属性时,可能发生三种情况:

  1. 如果属性存在,那么返回属性的值。

  2. 如果属性不存在,那么返回undefined。

  3. 不管属性存在还是不存在,有可能抛异常。

我们已经假设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内完成了跳转,三个条件同时满足,就出现这种情况了

解决方案

  1. 只用touch事件

    把所有click事件换成touch事件(touchstart, touchend, tap)

  2. 只用click

    缺点是会带来300ms的延迟

  3. tap后延迟300ms再隐藏mask

  4. pointer-events

    mask隐藏后,给按钮下面元素添加pointer-events:none;300ms后去掉样式,缺点是用户手速快的话会发现点击没有反应

  5. fastclick库

image的上传进度以及如何上传

  1. 通过轮询或者长链接的方式在上传文件的同时用Ajax去读取,这需要后端提供读取文件上传进度的接口。这个方案显得很笨重,所以一般还是采用flash的解决方案。
  2. XMLHttpRequest Level2已经支持用Ajax直接传输文件,并且提供onprogress,onloadstart,onloadend,onload等事件来跟踪进度,事件的ProgressEvent参数中提供了loaded和total可以用来计算百分比,但是很遗憾的是IE仍需要Flash提供兼容方案。ios不能上传本地文件,所以Flash方案能覆盖大部分客户端。

XMLHttp upload API

从输入URL到页面渲染出来的过程

从输入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 请求:

    1. 由 XMLHttpRequest 或 Fetch 发起的跨域 HTTP 请求。
    2. Web 字体 (CSS 中通过 @font-face 使用跨域字体资源), 因此,网站就可以发布 TrueType 字体资源,并只允许已授权网站进行跨站调用。
    3. WebGL 贴图
    4. 使用 drawImage 将 Images/video 画面绘制到 canvas
    5. 样式表
    6. 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对象。
  • 附带身份凭证的请求

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
  • 附带身份凭证的请求与通配符

    如果客户端请求设置withCredentials=true时,服务器端不能设置Access-Control-Allow-Origin 的值为“*”,否则请求将会失败,必须设置对应的域名。

  • HTTP请求首部字段

    1. Origin(表明预检请求或实际请求的源站)
    2. Access-Control-Request-Method(将实际请求所使用的 HTTP 方法告诉服务器。)
    3. Access-Control-Request-Headers(将实际请求所携带的首部字段告诉服务器。)
  • HTTP请求响应字段

    1. Access-Control-Allow-Origin(指定了允许访问该资源的外域 URI。)
    2. Access-Control-Expose-Headers(跨域访问时,XMLHttpRequest对象的getResponseHeader()方法只能拿到一些最基本的响应头,Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma,如果要访问其他头,则需要服务器设置本响应头。)
    3. Access-Control-Max-Age(预检请求能够被访问多少秒)
    4. Access-Control-Allow-Credentials(指定了实际的请求是否可以使用credentials)
    5. Access-Control-Allow-Methods(指明了实际请求所允许使用的 HTTP 方法。)
    6. Access-Control-Allow-Headers(指明了实际请求中允许携带的首部字段。)
      比较:
      JSONP只能实现get请求,而CORS支持所有类型的HTTP请求
      使用CORS,开发者可以使用普通的XHR发起请求和获得数据,比起JSONP有更好的错误处理
      JSONP主要被老的浏览器支持,而绝大多数现代浏览器都已经支持CORS

HTTP访问控制(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的漏洞修复

  1. 对用户表单输入的数据进行转义,然后再存入数据库
  2. 对信息展示页面也需要进行转义,防止Javascript在页面上执行
  3. 将重要的cookie标记为http only, 这样的话Javascript 中的document.cookie语句就不能获取到cookie了
  4. 对表单信息进行验证,规范输入

CSRF

CSRF(Cross-site request forgery跨站请求伪造)是一种依赖web浏览器的、被混淆过的代理人攻击。

CSRF漏洞修复

  1. 所有需要用户登录之后才能执行的操作属于重要操作,这些操作传递参数应该使用post方式,更加安全;
  2. 为防止跨站请求伪造,我们在某次请求的时候都要带上一个csrf_token参数,用于标识请求来源是否合法,csrf_token参数由系统生成,存储在SESSION中。

Xss和Csrf介绍

怎么只让部分用户看到新发布的页面改变?

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();
});    

nodejs:使用多处理器

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;

你可能感兴趣的:(web前端面试题)