20190204:《imooc -前端跳槽面试技巧》 |
一、一面知识点
1、面试技巧 页面布局类
2、css盒模型dom事件类
3、http协议类 原型链类
4、面向对象类 通信类
5、前端安全类 前端算法类
二、二面
1、面试技巧
2、渲染机制类
3、js运行机制
4、页面性能
5、错误监控
三、三面
1、面试技巧
2、业务能力
3、团队协作能力
4、带人能力
四、终面
1、面试技巧
2、职业竞争力
3、职业规划
一、京东金融是京东最赚钱的软件开发部门。
3、代码易读易可维护。
4、用户体验,用户研究等相关知识有深入的了解和实践经验。
5、web前端技术有兴趣,github,博客前沿技术。
6、sass、less等css预编译语言。(sass看一下)
7、了解、熟悉、精通。构建工具,推荐gulp。
8、grunt和gulp的区别。
9、面向对象,类,原型链
10、系统化设计:模块化设计,前后端分离
11、动画:dom动画,SVG的path
12、gpu加速,css的属性有哪些是能提高性能的?
13、web标准
14、js异常:js运行异常,资源加载错误(资源可用性、可访问性)
一、
二、怎么提升网站性能,dns预解析
三、application
1、local storage
2、字体,自定义字体,字体图标
一、async
script外链加载方式有几种?
二、requirejs 模块化加载
模块化加载的方式有几种
requirejs和cjs的区别
三、静态域:专门放静态资源的域
四、jquery的模板引擎:head bar、ejs引擎、underspone的template
deligate(延迟的方法)
es6怎么处理模块化
一、jquery的源码:核心架构、事件委托、插件机制。
二、MVM:vue、react、angular
三、阿里很喜欢问vue的源码(v2.0静态语法检查)
四、postcss不如less/sass全面。
五、npm scripts怎么用的
一、自我介绍
1、简历
(1)基本信息,姓名、年龄、手机、邮箱、籍贯
(2)学历,本科
(3)工作经历,时间、公司、岗位、职责、技术栈、业绩
(4)开源项目,github和说明
charles、webpack、es6
略微了解nodejs
不推荐写自我评价
背景、技术(mvc/less,ajax不属于技术)、收益(业务收益、技术收益)
熟悉http协议(包括http2,https协议)
2、自我陈述
(1)把握面试的沟通方向,1个点不够,多准备几个点。
(2)豁达、自信的适度发挥
一、遇到不知道的问题,不能说不知道、不懂、没经历过。可以说思考一下、回去思考一下,也可以请教面试官
二、页面布局,能写几种方法就写几种,实现->追求技术难度。面试题没有标准答案。
三、给你出再难的题目,不要自卑,心态要平和。
一、知识要系统
二、三栏布局:左右各300px,中间自适应
1、5种写法:
flex布局,浮动float, 绝对定位position:abolute, 表格布局 table-cell,网格布局grid布局
2、注意点:
(1)所有元素重置padding,margin
(2)浮动布局中间块元素自动撑开,中间块元素不要用float:left;
(3)绝对定位的时候,最好三栏都用绝对定位,不要一会儿用浮动,一会儿用绝对定位。
(4)不要通篇用div,语义化标签
3、代码
浮动解决方案
1.这是三蓝布局中间部分
2.这是三蓝布局中间部分
绝对定位解决方案
1.这是三蓝布局中间部分
2.这是三蓝布局中间部分
flexbox解决方案
1.这是三蓝布局中间部分
2.这是三蓝布局中间部分
表格布局解决方案
1.这是三蓝布局中间部分
2.这是三蓝布局中间部分
网格布局解决方案
1.这是三蓝布局中间部分
2.这是三蓝布局中间部分
4、延伸
(1)这5种方案的优缺点
①浮动:清除浮动,兼容性比较好。
②绝对定位:快捷,布局已经脱离了文档流,导致下面的元素也要脱离文档流,使用性较差。
③flex布局,解决了浮动和绝对定位的缺点,移动端基本已经支持了兼容性。
④表格布局:表格布局的兼容性非常好
⑤网格布局:新出的
(2)如果“高度已知”去掉,中间内容高度撑开了,需要左右的高度也自动撑开,哪些方案仍适合,哪些方案不再适用。
①flex、table能用
②flex左边有遮挡,所以显示在右边,没有遮挡的时候,就会显示在最左边。创建bfc
(3)5种方案的兼容性,如果是实际项目中,最优方案是什么?
(4)三栏布局
①左右宽度固定,中间自适应
②上下高度固定,中间自适应。
(5)两栏布局
①左宽度固定,右自适应
②右宽度固定,左自适应
③上高度固定,下自适应
④下高度固定,上自适应
一、谈谈你对css盒模型的认识
1、基本概念:标准模型+IE模型
margin、border、padding、content
2、标准模型和IE模型的区别:计算高度和宽度的不同,怎么不同,高度宽度是怎么计算的
width:100px; 如果是IE,100px包括border和padding,
3、css如何设置这两种模型
box-sizing:content-box;
box-sizing:border-box; /IE模型/
4、js如何设置获取盒模型对应的宽和高
dom.style.width/height // 只能取到内联样式
dom.currentStyle.width/height // 取到渲染后的样式(只有IE支持)
window.getComputedStyle(dom).width/height // 兼容firefox,chrome,兼容性更好
dom.getBoundingClientRect().width/height // 运行后的宽度,getBoundingClientRect()能得到left/top/width/height,bounding:范围,rect,矩形
5、实例题(根据盒模型解释边距重叠)
(1)边距重叠:父子元素,兄弟元素,空元素上下边距
(2)#sec的子元素是.child
①#sec{}
.child{height:100px;margin-top:10px;}
这时#sec的高度为100px;
②#sec{overflow:hidden;}
.child{height:100px;margin-top:10px;}
这时#sec的高度为110px;
6、BFC(边距重叠解决方案)
(1)BFC的基本概念:块级格式化上下文,Block Formatting Context
IFC:内联元素格式化上下文,不过面试问的比较多的是BFC
(2)BFC原理/BFC渲染规则
①BFC元素垂直方向的边距会发生重叠
②BFC的区域不会与浮动元素的box重叠(可用于清除浮动)
③BFC为一个独立的元素,外面的元素不会影响里面的元素,里面的元素也不会影响外面的元素。
④计算BFC高度的时候,浮动元素也会参与计算。
(3)如何创建BFC
①float值不为none;
②position的值不为static(默认值),relative,即为absolute,fixed
③display为inline box,table-cell,table,table-caption,跟table相关的。
④overflow不为visible,overflow为auto,hidden;
(4)BFC的使用场景
①BFC垂直方向边距重叠
②BFC不与float重叠
③清除浮动:子元素是浮动元素的时候,把外层元素设置成BFC的时候,子元素的浮动元素也会参与到父级元素的高度计算上来。
我是浮动元素
一、dom事件类
1、基本概念:dom事件的级别
(1)dom0 element.οnclick=function(){}
(2)dom2 element.addEventListener(‘click’, function(){}, false) // 默认是false。false:冒泡阶段执行,true:捕获阶段产生。
(3)dom3 element.addEventListener(‘keyup’, function(){}, false) // 事件类型增加了很多,鼠标事件、键盘事件
2、dom事件模型
捕获:从上到下
冒泡:从当前元素往上
3、dom事件流
浏览器在为当前页面与用户交互的过程中,比如说点击鼠标左键,左键怎么传到页面上,这就是事件流,他又是怎么响应的。
捕获-> 目标阶段->冒泡
4、描述dom事件捕获的具体流程
window-> document-> html-> body-> … -> 目标元素
document.documentElement();获取到html
document.body获取到body
5、event对象的常见应用
event.preventDefault(); // 阻止默认行为,阻止a链接默认的跳转行为
event.stopPropagation(); // 阻止冒泡
event.stopImmediatePropagation(); // 按钮绑定了2个响应函数,依次注册a,b两个事件,点击按钮,a事件中加event.stopImmediatePropagation()就能阻止b事件
event.currentTarget // 早期的ie不支持,当前绑定的事件
event.target
6、自定义事件/ 模拟事件
(1)给一个按钮自己增加一个事件,在其他地方触发,而不是用回调的方式触发
var ev = document.getElementById('ev');
var eve = new Event('custome'); // eve:事件对象
ev.addEventListener('custome', function(){
console.log('custome');
});
ev.dispatchEvent(eve);
(2)customeEvent
一、http协议类
HyperText Transfer Protocol,超文本传输协议。因特网上应用最为广泛的一种网络传输协议,所有的WWW文件都必须遵守这个标准
1、http协议的主要特点
简单快速、灵活、无连接、无状态
①简单快速:每个资源的url是固定的
②灵活:每个http协议中有个头部分,有个数据类型,通过一个http协议,可以完成不同类型数据的传输。
③无连接:连接一次就会断掉,不会保持连接。
④无状态:客户端、服务端是两种身份,http传输完成后,下次连接再过来,服务端无法确认是否是上一次连接者的身份。
2、http报文的组成部分
(1)请求行:包含http方法,页面地址,http协议,版本。
(2)请求头:key,value值,告诉服务端我要哪些内容。
(3)空行:分隔请求头、请求体。
3、http方法
get:获取资源
post:传输资源
put:更新资源
delete:删除资源
head:获得报文首部
4、post和get的区别
9个区别,至少记住标记的4个
(1)get在浏览器回退时是无害的,而post会再次提交请求。(记住)
(2)get产生的url地址可以被收藏,而post不可以。
(3)get请求会被浏览器主动缓存,而post不会,除非手动设置。(记住)
(4)get请求只能进行url编码,而post支持多种编码方式。
(5)get请求参数会被完整保留在浏览器历史记录里,而post中的参数不会被保留。(记住)
(6)get请求在url中传送的参数是有长度限制的,而post没有限制。
(7)对参数的数据类型,get只接受ASCII字符,而post没有限制。
(8)get比post更不安全,因为参数直接暴露在url上,所以不能用来传递敏感信息。
(9)get参数通过url传递,post放在request body 中。(记住)
5、http状态码
1、状态码
1xx:指示信息-表示请求已接收,继续处理。
2xx:成功-表示请求已被成功接收。
3xx:重定向-要完成请求必须进行更进一步的操作。
4xx:客户端错误-请求有语法错误或请求无法实现。
5xx:服务器错误-服务器未能实现合法的请求。
2、常见状态码
200 OK:客户端请求成功
206 Partial Content:客户发送了一个带有Range头的GET请求,服务器完成了它。 // video, audio
301 Moved Permanently:所请求的页面都已经转移至新的url
302 Found:所请求的页面已经临时转移至新的url
304 Not Modified:客户端有缓冲的文档并发出了一个条件性的请求,服务器告诉客户,原来缓冲的文档还可以继续使用。
400 Bad Request:客户端请求有语法错误,不能被服务器所理解
401 Unauthorized: 请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用
403 Forbidden:对被请求页面的访问被禁止
404 Not Found:请求资源不存在
500 Internal Server Error:服务器发生不可预期的错误
503 Server Unavailable:请求未完成,服务器临时过载或宕机,一段时间后可能恢复正常。
6、什么是持久连接
(1)http协议采用“请求-应答”模式,当使用普通模式,即非keep-alive模式时,每个请求/应答,客户端和服务器都要新建一个连接,完成之后立即断开连接(http协议为无连接的协议)
当使用keep-alive模式(又称持久连接、连接重用)时,keep-alive功能使客户端到服务器端的连接持久有效,当出现对服务器的后继请求时,keep-alive功能避免了建立后者重新建立连接。
(aSuncat:chrome默认开启持久连接)
(2)http1.1才支持,http1.0是不支持的。
7、什么是管线化
(1)在使用持久连接的情况下,某个连接上消息的传递类似于
请求1-> 响应1 -> 请求2 -> 响应2 -> 请求3 -> 响应3
某个连接上的消息变成了类似这样
请求1 -> 请求2 -> 请求3 -> 响应1 -> 响应2 -> 响应3
(2)管线化注意点:
6个注意点,至少记住标记的3个
①管线化机制通过持久连接完成,仅http/1.1支持此技术。(记住)
②只有get和head请求可以进行管线化,而post则有所限制。(记住)
③初次创建连接时不应启动管线机制,因为对方(服务器)不一定支持http/1.1版本的协议。(记住)
④管线化不会影响响应到来的顺序,如上面的例子所示,响应返回的顺序并未改变。
⑤http/1.1要求服务器支持管线化,但并不要求服务器也对响应进行管线化处理,只是要求管线化的请求不失败即可
⑥由于上面提到的服务器问题,开启管线化很可能并不会带来大幅度的性能提升,而且很多服务器端和代理程序对管线化的支持并不好,因为现代浏览器如chrome和firefox默认并未开启管线化支持
一、原型链类
1、创建对象有几种方法
(1)
①字面量对象 // 默认这个对象的原型链指向object
var o1 = {name: '01'};
②通过new Object声明一个对象
var o11 = new Object({name: '011'});
(2)使用显示的构造函数创建对象
var M = function(){this.name='o2'};
var o2 = new M();
o2.__proto__=== M.prototype
o2的构造函数是M
o2这个普通函数,是M这个构造函数的实例
(3)object.create()
var P = {name:'o3'};
var o3 = Object.create(P);
2、原型、构造函数、实例、原型链
(1)Object.prototype属性是整个原型链的顶端
(2)原型链通过prototype原型和__proto__属性来查找的
(3)实例本身的属性和方法如果没有找到,就会去找原型对象的属性和方法。如果在某一级找到了,就会停止查找,并返回结果
(4)函数才有prototype,对象是没有prototype的
(5)对象才有__proto__,实例是构造函数生成的
(6)函数也是对象
3、instanceof的原理
(1)实例对象的属性引用的是构造函数的原型对象
(2)instanceof的原理:实例对象的这个属性和构造函数的属性,判断是不是同一个引用
var M = new Object({name: '1'});
var o3 = new M;
console.log(o3 instanceof M); // true
console.log(o3 instanceof Object); // true,只要是原型链上的构造函数,都会被看成是object的构造函数,都会返回true
console.log(M.prototype.__proto__===Object.prototype);
console.log(o3.__proto__.constructor === M); // true,o3是M这个构造函数直接生成的
console.log(o3.__proto__.constructor === Object); // false
4、new运算符
new运算符后面跟的是一个构造函数
var new2 = function(func) {
var o = Object.create(func.prototype);
var k = func.call(o); // call转移上下文
if (type k === 'Object') {
return k;
} else {
return o;
}
}
var o6 = new2(M);
console.log(o6 instanceof M); // true
o6 instanceof Object // true
o6.__proto__.constructor === M; // true
M.prototype.walk = function(){console.log('walk')};
o6.walk(); // 能成功
一、类与实例
1、类的声明
/*类的声明*/
// 传统的构造函数,声明一个类
function Animal() {
this.name = 'name';
}
/*es6中的class声明*/
class Animal2{
constructor() {
this.name = name;
}
}
2、生成实例
/*实例化*/
console.log(new Animal(), new Animal2()); // 通过New就可以实例化一个类,如果没有参数,Animal后面的()可以不要
3、声明一个类,怎么生成类的实例?
二、类与继承
1、如何实现继承
(1)继承的本质就是原型链
(2)aSuncat:call、apply的共同点与区别
①改变了函数运行上下文
(aSuncat:call()和apply()主要是能扩充函数赖以运行作用域。两者的作用方式相同,它们的区别在于接收参数的方式不同,对于call()而言,第一个参数this与apply()相同,其他的参数必须直接传给函数,要一个一个的列出来,而对于来说,apply()可以接收一个数组或arguments对象。所以如何选择二者,在于哪种给函数传参数的方式最简单。)
2、继承的几种方式,这几种方式的优缺点
(1)方法1:借助构造函数实现继承(部分继承)
/**
* 借助构造函数实现继承
*/
function Parent1() {
this.name = 'parent';
}
Parent1.prototype.say = function() {}; // 不会被继承
function Child1() {
// 继承:子类的构造函数里执行父级构造函数
// 也可以用apply
// parent的属性都会挂载到child实例上去
// 借助构造函数实现继承的缺点:①如果parent1除了构造函数里的内容,还有自己原型链上的东西,自己原型链上的东西不会被child1继承
// 任何一个函数都有prototype属性,但当它是构造函数的时候,才能起到作用(构造函数是有自己的原型链的)
Parent1.call(this);
this.type = 'child1';
}
console.log(new Child1);
①如果父类的属性都在构造函数内,就会被子类继承。
②如果父类的原型对象上有方法,子类不会被继承。
(2)方法2:借助原型链实现继承
/**
* 借助原型链实现继承
*/
function Parent2() {
this.name = 'name';
}
function Child2() {
this.type = 'child2';
}
Child2.prototype = new Parent2();
console.log(new Child2().__proto__);
console.log(new Child2().__proto__ = Child2.prototype); // true
var s1 = new Child2(); // 实例
var s2 = new Child2();
console.log(s1.play, s2.play);
s1.play.push(4);
console.log(s2.__proto__ === s2.___proto__); // true // 父类的原型对象
①原型链的基本原理:构造函数的实例能访问到它的原型对象上
②缺点:原型链中的原型对象,是共用的
(3)方法3:组合方式
/**
* 组合方式
*/
function Parent3() {
this.name = 'name';
this.paly = [1, 2, 3];
}
function Child3() {
Parent3.call(this);
this.type = 'child3';
}
Child3.prototype = new Parent3();
var s3 = new Child3();
var s4 = new Child3();
s3.play.push(4);
console.log(s3.play, s4.play);
// 父类的构造函数执行了2次
// 构造函数体会自动执行,子类继承父类的构造函数体的属性和方法
①组合方式优化1:
/**
* 组合继承的优化方式1:父类只执行了一次
*/
function Parent4() {
this.name = 'name';
this.paly = [1, 2, 3];
}
function Child4() {
Parent4.call(this);
this.type = 'child4';
}
Child4.prototype = Parent4.prototype; // 继承父类的原型对象
var s5 = new Child4();
var s6 = new Child4();
console.log(s5 instanceof Child4, s5 instanceof Parent4); // true
console.log(s5.constructor); // Parent4 //prototype里有个constructor属性,子类和父类的原型对象就是同一个对象, s5的constructor就是父类的constructor
②组合方式优化2:
/**
* 组合继承优化2
*/
function Parent5() {
this.name = 'name';
this.paly = [1, 2, 3];
}
function Child5() {
Parent4.call(this);
this.type = 'child5';
}
Child5.prototype = Object.create(Parent5.prototype); // Object.create创建的对象就是参数
Child5.prototype.constructor = Child5;
var s7 = new Child5();
console.log(s7 instanceof Child5, s7 instanceof Parent5);
console.log(s7.constructor); // 构造函数指向Child5
3、一个对象,是继承了某个类,问你他的原型链
一、通信类
1、什么是同源策略及限制
(1)同源策略限制从一个源加载的文档或脚本如何与来自另一个源的资源进行交互。
这个是一个用于隔离潜在恶意文件的关键的安全机制。
源:协议、域名、端口
(2)Cookie、localStorage 和indexDB无法读取。
(3)DOM无法获得。
(4)ajax请求不能发送
2、前后端如何通信
ajax(同源)
websocket
cors
3、如何创建ajax
var xhr = XMLHttpRequest ? new XMLHttpRequest() : new window.ActiveXObject('Microsoft.XMLHttp);
xhr.open(type, url, true);
xhr.sendRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xhr.send();
(1)XMLHttpRequest对象的工作流程
(2)兼容性处理
(3)事件的触发条件
(4)事件的触发顺序
4、跨域通信的几种方式
(1)jsonp
script标签的异步加载
原理:视频#3-13的第20分钟
(2)hash
hash改变,页面是不刷新的
search改变,页面是会刷新的
window.onhashchange 得到window.location.hash
(3)postMessage
Bwindow.postMessage('data', 'http://B.com');
windwo.addEventListener('message', function(event) {
console.log(event.origion); // http://A.com
console.log(event.source); // Awindow
console.log(event.data); // data
})
(4)websocket
var ws = new WebSocket('wss://echo.websocket.org');
ws.open, ws.onmessage, ws.onclose
(5)cors
①cors会在http请求中添加origin的请求头
②ajax不支持跨域,cors是变种的ajax
③同源下,fetch就是ajax
fetch('/some/url', {
method: 'get'
}).then(function(response) {
}).catch(function(err) {})
④参考资料:http://www.ruanyifeng.com/blog/2016/04/cors.html
一、CSRF
1、基本概念和缩写
CSRF,通常被称为跨站请求伪造,英文名Cross-site request forgery。
2、攻击原理
(1)前提:①用户在注册网站A登录过,②接口有漏洞。
(2)引诱点击,往往是一个链接(这个链接自动携带cookie,不会带token),指向网站A的api,接口是get类型。浏览了A,浏览器自动生成新的cookie,网站A拿到cookie,接口运行。
3、防御措施
(1)token验证。
注册网站,或者访问网站,服务器自动向本地存储一个token。
(2)refer验证。
服务器判断页面是不是我这个站点来的页面。
(3)隐藏令牌。
http的head头,不会放在链接上。
二、XSS
1、基本概念和缩写
XSS(cross-site scripting 跨域脚本攻击)
2、攻击原理:http://www.imooc.com/learn/812
原理:向页面注入脚本。
eg:提交区(评论区)写img标签,script标签,利用合法渠道向页面注入js
3、防御措施:http://www.imooc.com/learn/812
宗旨:让xss不可执行。
三、CSRF ,XSS的区别
XSS是向页面注入js去运行,然后在js函数体中做他想做的事情。
CSRF是利用网站漏洞,自动执行接口。用户需要登陆网站。
通常情况下,搞金融的都会考算法。
一、排序
快速排序:https://segmentfault.com/a/1190000009426421
选择排序:https://segmentfault.com/a/1190000009366805
希尔排序:https://segmentfault.com/a/1190000009461832
二、堆栈、队列、链表
堆栈:https://juejin.im/entry/58759e79128fe1006b48cdfd
队列:https://juejin.im/entry/58759e79128fe1006b48cdfd
链表:https://juejin.im/entry/58759e79128fe1006b48cdfd
(1)js数组本身就具备堆栈和队列特性。
(2)堆栈:先进后出。
三、递归
递归:https://segmentfault.com/a/1190000009857470
(1)60%的算法题都用到递归。
四、波兰式和逆波兰式
理论:http://www.cnblogs.com/chenying99/p/3675876.html
源码:https://github.com/Tairraos/rpn.js/blob/master/rpn.js
一、什么是DOCTYPE及作用
DTD(document type definition,文档类型定义)是一系列的语法规则,用来定义XML或(X)HTML的文件类型。浏览器会使用它来判断文档类型,决定使用何种协议来解析,以及切换浏览器模式。
DOCTYPE是用来声明文档类型和DTD规范的,一个主要的用途便是文件的合法性验证。如果文件代码不合法,那么浏览器解析时便会出一些差错。
1、常见的doctype有哪些?
①HTML5:
②HTML4.01 Strict:该DTD包含所有html元素和属性,但不包括展示性的和启用的元素,如font
③HTML 4.01 Transitional :该DTD包含所有html元素和属性,包括展示性的和启用的元素,如font
2、h5的doctype怎么写
二、浏览器渲染过程
1、在浏览器中输入url,发生了哪些事情?
dns解析、发送到服务器、服务器响应、浏览器渲染过程
2、浏览器的渲染过程:
三、重排Reflow
1、定义
DOM结构中的各个元素都有自己的盒子(模型),这些都需要浏览器根据各种样式来计算并根据计算结果将元素放到它该出现的位置,这个过程称之为reflow
2、触发reflow
(1)增加、删除、修改dom结点时,会导致reflow或repaint
(2)移动dom的位置,或是搞个动画的时候
(3)修改css样式
(4)resize窗口的时候(移动端没有这个问题),或者是滚动的时候,有可能会触发。
(5)修改网页的默认字体时
3、如何避免reflow
四、重绘Repaint
1、定义
当各种盒子的位置、大小及其他属性,如颜色、字体大小等都确定下来后,浏览器于是便把这些元素都按照各自的特性绘制了一遍,也是页面的内容出现了,这个过程称之为repaint
即页面呈现的内容统统画在屏幕上。
2、触发repaint
(1)dom改动
(2)css改动
3、如何尽量减少repaint
向浏览器中一次repaint一个节点
五、布局layout
一、
console.log(1);
setTimeout(function(){
console.log(2);
}, 0);
console.log(3);
// 依次输出1,3,2
1、js是单线程的。
2、任务队列。
3、setTimeout就是一个异步任务。异步任务要挂起。
4、同步任务没有被执行完之前,所有异步任务都是不会被执行的。
二、
console.log('A');
while(1) {};
console.log('B');
// 输出A(因为1一直为true,while一直在执行,页面一直在转,执行不到B)
三、
for(var i = 0; i < 4; i++) {
setTimeout(funciton(){
console.log(i);
}, 1000)
}
1、for循环是一个同步任务。
2、队列插入的时间。
3、浏览器的timer模块(主要处理setTimeout、setInterval):定时器到了那个时间,才会把语句放在异步队列。而不是执行到这个异步任务的时候,就会把它放入异步队列,如setTimeout(function(){console.log(i)}, 1000),是在1000ms后才会被放入异步队列中。
四、
1、如何理解js的单线程
一个时间内,js只能干一件事
2、什么是任务队列
同步任务,异步任务,异步任务的执行时间。
3、什么是event loop
事件循环。
运行栈:执行同步任务的
浏览器js引擎遇到了setTimeout,识别了这是一个异步任务,不会将其放入运行栈,而是把它拿走,拿走了之后也没有立马放到异步任务队列中,按延迟时间放入到异步队列中。同步任务没有正在执行的东西,就会读异步任务,把任务放到运行栈中,执行完了又去读异步任务,把任务放到运行栈中,如此循环。
五、异步任务
1、哪些语句会放入异步任务队列中?
setTimeout和setInterval
dom事件
ES6中的promise
一、题目:提升页面性能的方法有哪些?
1、资源压缩合并,减少http请求。
2、非核心代码异步加载。
(1)异步加载的方式
①动态脚本加载
script标签,加入到body中
②defer
加载js的时候,script标签加defer和async
③async
(2)异步加载的区别
①defer是在html解析完之后才会执行,如果是多个,按照加载的顺序依次进行。
②async是在加载完之后立即执行,如果是多个,执行顺序和加载顺序无关。
3、利用浏览器缓存。
(1)缓存的分类
①强缓存
// Expires:
Expires:Thu, 21 Jan 2017 23:39:02 GMT // value值表示的是绝对时间,一般都是服务器时间,可能与客户端时间不一样
// Cache-Control:
Cache-Control: max-age=3600 // value值是以客户端时间为准
如果服务器这两个时间都下发了,以后者为准
②协商缓存:与服务器协商是否要用,是否过期
// Last-Modified If-Modified-Since
Last-Modified: Web, 26 Jan 2017 00:35:11 GMT
// Etag If-None-Match
// if-none-match的值就是服务器发过来的etag的值
1)与浏览器缓存相关的http头有哪些?
Expires、Cache-Control、Last-Modified、If-Modified-Since、Etag、If-None-Match
(2)缓存的原理。
4、使用cdn
5、预解析dns
(1)
(2)强制打开a标签的dns预解析
页面中所有a标签,默认打开了dns预解析,如果链接是https开头的,默认关闭dns预解析
一、如何检测js错误?(如何保证你的产品质量?)
1、前端错误的分类?
(1)即时运行错误:代码错误
①try.catch
②window.onerror:只能捕获即时运行错误
(2)资源加载错误,资源加载错误不会向上冒泡,不会冒泡到window
①object.onerror:图片有onerror事件,script标签也有onerror事件
②performance.getEntries:高级浏览器,可以间接拿到没有加载的资源错误。返回的是一个数组。
performance.getEntries().forEach(item=> {console.log(item.name)}); // 打印出来的是已成功加载的资源
document.getElementByTagName('img'); // 打印出来的是所有图片资源(包括已经成功加载和没有成功加载)
③error事件捕获:资源加载错误不会冒泡,但是会发生捕获
2、错误的捕获方式?(同上述方法3的error事件捕获)
window.addEventListener('error', function(e) {
console.log('捕获:', e);
}, true); // 第三个参数是true:捕获, false:冒泡
延伸:跨域的js运行错误可以捕获吗,错误提示什么,应该怎么处理?
①在script标签增加crossorigin属性。
②设置js资源响应头Access-Control-Allow-Origin:*
3、上报错误的基本原理?
(1)采用ajax通信的方式上报。
能做到,但是所有的错误监控都不是通过这种方式做的。
(2)采用image对象上报。
所有的错误方式都是通过这种方式上报的。
(new Image()).src = 'http://baidu.com/tesjk?r=tksjk'; // 不需要借助任何第三方库,错误上报路径后面可以加任何参数,如r=tksjk等
4、参考资料:http://www.cnblogs.com/luozhihao/p/8635507.html
一、业务能力、团队协作能力、事务推动能力、带人能力、其他能力。
二、面试题
1、我做过什么业务?一两句话
独立负责360数据彩票走势图开发
2、负责的业务有什么业绩?最好是能量化:用户增加了多少,性能提升了多少,收入增加了多少
历时3周完成所有彩种开发,用户量上涨15%
3、使用了什么技术方案?
区别常规canvas方案,使用vml+svg方案
canvas:ie9以下不兼容,如果页面高度大于2000px,canvas无法绘画。
4、突破了什么技术难点?
解决了走势图高级绘图板的开发
5、遇到了什么问题?
橡皮擦的问题,动态连线甲酸等
6、最大的收获是什么?
对业务的理解更加深入,对技术图表更有把握
一、团队协作能力(主动描述)
1、对彩票足球的奖金算法有深入研究,业内第一。
2、为h5、客户端讲解算法并协助完成开发。
3、和php、pm同学在一天的时间内快速支持足球竞猜活动。
4、和leader独立负责彩票pc站。
二、事务推动能力
1、对历史算法更新换代。
2、推动专题的CMS架构。
3、主导客服系统的建设。
4、完成多项专利的申请。
三、带人能力
1、带一个社招完成数字彩的开发和维护。
2、带一个实习生完成专题活动的开发。
3、代码规范、review
一、在职业竞争力、职业规划中要表现出:
1、乐观积极
2、主动沟通
3、逻辑顺畅
4、上进有责任心
5、有主张,做事果断
二、职业竞争力
公司这么多人应聘,为什么要招你?
1、业务能力
可以做到行业第一
2、思考能力
对同一件事可以从不同角度去思考,找到最优解
3、学习能力
不断学习新的业务和技术,沉淀、总结
4、无上限的付出
对于无法解决的问题可以熬夜、加班
三、职业规划
1、目标是什么
在业务上成为专家,在技术上成为行业大牛
2、近阶段的目标
不断的学习积累各方面的经验,以学习为主
3、长期目标
做几件很有价值的事情,如开源作品、技术框架等。
4、方式方法
先完成业务上的主要问题,做到极致,然后逐步向目标靠拢
5、多赞美公司,多赞美hr
一、jd描述一定要看。
二、简历:对照jd改写出相吻合的简历,对于未掌握的技术栈快速复习、理解。
三、自我介绍:一定要打草稿,展示什么优势、描述什么项目,切忌临场发挥。
四、gulp是通过流来传递的
五、http://www.w3school.com.cn,html,html5,css,css3,javascript的属性等。
六、算法:LeetCode,https://leetcode.com/problemset/algorithms
20190218:《imooc- 揭秘一线互联网企业 前端javaScript高级面试》 |
(aSuncat:①内容较为冗余,不复杂的内容,说得却不够简洁。②很多简单的东西,对于高级面试课程,可以一笔带过,讲师却浮于表面过多解释。③第三章讲解jQuery源码,原型-构造函数-实例,可以看一下)
一、基础知识
1、es6常用语法
class、module、promise等
2、原型高级应用
结合jQuery和zepto源码
3、异步全面讲解
从原理到jQuery,再到promise
二、框架原理
1、虚拟dom
存在价值,如何使用,diff算法
2、MVVM dom
vue 响应式、模板解析、渲染
3、组件化react
组件化、jsx、vdom、setState
三、混合开发
1、hybrid
2、hybrid vs h5
基础,和h5对比,上线流程
3、前端客户端通讯
通讯原理,js-bridge封装
四、热爱编程
1、读书博客
2、开源
五、高级js面试中,面试官爱问“源码”、“实现”
一、es6
1、模块化的使用和编译环境
2、class和js构造函数的区别
3、promise的用法
4、es6其他常用功能
二、异步
1、什么是单线程,和异步有何关系
2、什么是event-loop
3、目前js解决异步的方案有哪些
4、如果只用jquery,如何解决异步
5、promise的标准
6、async/await的使用
三、原型
1、原型如何实际应用
2、原型如何满足扩展
四、vdom
1、什么是vdom,为何要用vdom
2、vdom如何使用,核心函数有哪些?
3、了解diff算法吗
vom的核心算法
五、mvvm
1、之前使用jquery和现在使用vue或react框架的区别
2、你如何理解mvvm
3、vue如何实现响应式
4、vue如何解析模板
5、介绍vue的实现流程
六、组件化
1、对组件化的理解
2、jsx是什么
3、jsx和vdom什么关系
4、简述react和setState
5、阐述自己如何比较react和vue
七、hybrid
1、hybrid是什么,为何要用hybrid
2、hybrid如何更新上线
3、hybrid和h5如何区别
4、js如何与客户端通信
八、其他
如何写博客
如何做开源
一、es6模块化如何使用,开发环境如何打包?
二、class和普通构造函数有何区别?
三、promise的基本使用和原理?
四、总结一下es6其他常用功能?
一、es6模块化如何使用,开发环境如何打包?
1、模块化的基本语法
export/ˈekspɔːrt/
export default{
a: 100
}
2、开发环境配置
3、关于js众多模块化标准
一、开发环境-babel (处理es6语法)
1、电脑有node环境,运行npm init
2、npm install --save-dev babel-core babel-preset-es2015 babel-pareset-latest
3、创建.babelrc文件
4、npm install --global babel-cli
5、babel -version
6、创建 ./src/index
7、.babelrc文件
"presets": ["es2015", "latest"],
"plugins": []
8、sudo npm install -g babel-cli (windows需要管理员模式)
9、babel src/indes.js 就能得到es6转换为es5的代码
一、webpack (处理es6模块,当然还有其他功能)
1、npm install webpack bable-loader --save-dev
2、配置webpack.config.js
module.exports = {
entry: './src/index.js',
output: {
path: __dirname,
filename: './build/bundle.js'
},
module: { // 模块
rules: [{
test: /\.js?$/,
exclude: /(node_modules)/, // 安装第三方插件创建的,是第三方插件的代码
loader: 'babel-loader'
}]
}
}
3、配置pacakage.json的scripts
“scripts”: {
"start": "webpack" // 运行webpack,根据webpack.js对babel进行编译,输出bundle.js
}
4、运行npm start
5、index.html中script 的src 是build/bundle.js
6、http-server -p 8881 // 启动一个静态服务
一、rollup
1、npm init
2、npm i --save-dev rollup ruollup-plugin-node-resolve rollup-plugin-babel babel-plugin-external-helpers babel-preset-latest babel-core
3、配置.babelrc(一般面试官不会问这个配置文件里的东西)
{
"presets": [
[
"latest": {
"es2015": {
"modules": false
}
}
],
"plugins": ["external-helpers"]
]
}
4、配置rollup.cofig.js
import babel from 'rollup-plugin-babel';
import resolve from 'rollup-plugin-node-resolve';
export default {
entry: 'src/index.js',
format: 'umd', // 格式,兼容直接引入,兼容amd,兼容comonJs
plugins: [
resolve(),
babel({
exclude: 'node_modules/**'
})
],
dest: 'build/bundle.js'
}
5、package.json里的scripts的start改成rollup -c rollup.config.js
6、npm start
二、rollup功能单一,只能打包模块化,webpack功能强大
参考《设计原则》和《linux/unix设计思想》
三、rollup没有冗余代码,调试方便。
一、模块化
1、amd成为标准,require.js(也有cmd)
2、前端打包工具,使nodejs可以被使用(commonJs虽然是后端的,但是可以被打包成前端可识别的方式)
3、es6出现,想统一现在所有模块化标准
4、nodejs积极支持,浏览器尚未统一
5、可以自造库lib,但是不要自造标准(造轮子是属于造类,造库,但是不属于造标准)
二、问题解答
1、语法:import export(注意有无default)
2、环境:babel编译es6语法,模块化可用webpack和rollup
3、扩展:说一下自己对模块化标准统一的期待
1、class和普通构造函数有何区别?
(1)js构造函数
function MathHandle(x, y) { // 构造函数
this.x = x;
this.y = y;
}
MathHandle.prototype.add = function() { // 原型的一个扩展
return this.x + this.y;
}
var m = new MathHandle(1, 2); // new一个实例
console.log(m.add())
(2)class基本语法
class MathHandler{ // MathHandler是一个构造函数,构造函数都有显式原型:prototype
constructor(x, y) { // 构造器,java,c#的语法,面向对象高级语言的语法
this.x = x;
this.y = y;
}
add() {
return this.x + this.y;
}
}
const m = new MathHandle(1, 2); // 实例,所有实例都会有一个隐式原型:__proto__
console.log(m.add());
typeof MathHandle // 'function'
MathHandle.prototype.constructor === MathHandle; // true
m.__proto__ === MathHandle.prototype; // true
(3)语法糖
class本身就是一个语法糖
(4)继承
①低级构造函数的原型,赋值成高级构造函数的实例
②
function Animal(){this.eat = function() {console.log('animal eat')}}
function Dog(){this.bark = function() {console.log('dog dark')}}
Dog.prototype = new Animal(); // 绑定原型,实现继承
var hashiqi = new Dog();
class的继承
class Animal() {
constructor(name) {
this.name = name;
}
eat() {
alert(this.name + 'eat);
}
}
class Dog extends Animal{
constructor(name) {
super(name); // 如果有class,extends,则要用super(),super是被继承的class的constructor
this.name = name;
}
eat() {
alert(this.name + 'eat);
}
}
一、问题解答
1、class 在语法上更加贴合面向对象的写法
2、class实现继承更加易读、易理解
3、更易于写java等后端语言的使用
4、本质还是语法糖,使用prototype
一、promise
1、new promise实例,要return
2、new promise时要传入函数,函数有resolve、reject两个参数
3、成功时执行resolve(),失败时执行reject()
4、then监听结果
一、总结一下es6其他常用功能
1、let、const /'kɑnst/
const定义常量,常量不能被重新赋值
2、多行字符串/模板变量
js拼接变量字符串模板
console.log(`输出:${name}`)
3、解构赋值
整体数组或对象中拿到其中一个元素或属性值
// obj
const obj = {a: 10, b: 20, c:30};
const {a, c} = obj;
console.log(a); // 10
console.log(c); // 30
// arr
const arr = ['xxx', 'yyy', 'zzz'];
const [x, y, z] = arr;
console.log(x); // xxx
console.log(z); // zzz
4、块级作用域
for循环
// js
var obj = {a: 100, b: 200};
for (var item in obj) {console.log(item)};
console.log(item); // 'b'
// es6
const obj = {a: 100, b: 200};
for (let item in obj) {console.log(item)};
console.log(item); // undefined
5、函数默认参数
// js
function(a, b) {
if(b == null) {b = 0;}
}
// es6
function (a, b=0) {
}
6、箭头函数
彻底解决了之前函数this指向全局window对象的问题
function fn() {
console.log('real', this); // {a: 100}
var arr = [1, 2, 3];
// 普通js
arr.map(function(item) {
console.log('js',this); // window
return item + 1;
});
// 箭头函数
arr.map(item => {
console.log('es6', this); // {a: 100}
return item + 1;
});
}
fn.call({a: 100})
1、说一个选型的实际应用
2、原型如何体现它的拓展性
一、jquery
多个实例都可以共用一个方法时,说明这些方法(eg:css(), html())都是来自于一个构造函数的原型中
var $p = $('p');
$p.css('color', 'red'); // css是原型方法
console.log($p.html()); // html是原型方法 // 如果有多个p元素,$p.html()默认是最后一个元素的html
段落1
段落2
(2)全局define函数
define(['./a-util.js'], function(aUtil) {
return {
printDate: function(date) {
console.log(aUtil.aGetFromatDate(date));
}
}
})
(3)全局require函数
// main.js
require(['./a.js'], function(a) {
var date = new Date();
a.printDate(date);
})
(4)依赖js会自动、异步加载
2、commonJS
二、全局变量
1、全局变量很容易造成污染
2、js引用的顺序,和引用的条件(a.js应用了a-util.js,但是不知道还需要依赖util.js)。
一、CommonJs
1、nodejs模块化,现在被大量用于前端,原因:
(1)前端开发依赖的插件和库,都可以从npm中获取。
(2)构建工具的高度自动化,使用npm的成本非常低。
2、commonjs不是异步加载js,而是同步一次性加载出来。
3、服务器端不存在同步、异步的问题。
二、amd、cmd
1、amd推崇依赖前置。
amd在定义模块的时候要先声明其依赖的模块。
2、cmd推崇就近依赖。
cmd只要依赖的模块在附近就行了。
一、webpack.config.js中
context: path.resolve(__dirname, ‘./src’); // 找到该目录
一、webpack.config.js中
module.exports = {
context: ,
entry: {},
output: {},
plugins: [
new webpack.optimize.UglifyJsPlugin(); // 文件压缩
]
}
一、上线流程要点
1、将测试完成的代码提交到git版本库的master分支。
2、将当前服务器的代码全部打包并记录版本号,备份。
3、将master分支的代码提交到线上服务器,生成新版本号。
二、回滚流程要点
1、将当前服务器的代码打包并记录版本号,备份。
2、将备份的上一个版本号解压,覆盖到线上服务器,并生成新的版本号。
三、
1、ls:文件名字
ll:文件列表
pwd:文件目录
cd … :返回上级目录
rm -rf a :删除文件a
vi a.js:创建a文件
cp a.js a1.js :将a.js拷贝成a1.js,放在当前目录
mv a1.js src/a1.js 将a1.js移到src下
cat a.js // 打印a.js内容
head a.js // 看头部部分
tail a.js // 看文件的尾部部分
head -n 1 a.js // 看头部第一行
tail -n 2 a.js // 看倒数第一二行
grep ‘2’ a.js // 搜出带2的一行
一、题目
1、从输入url到html的详细过程
2、window.onload和DOMContentLoaded的区别
// 同window.onload
window.addEventListener('load', function() {
// 页面全部资源加载完才会执行,包括图片、视频等。
})
document.addEventListener('DOMContentLoaded', function() {
// dom渲染完即可执行,此时图片、视频可能还没有加载完
})
二、知识点
1、加载资源的形式
2、加载一个资源的过程
3、浏览器渲染页面的过程
三、加载资源的形式
1、输入url(或跳转页面)加载html
http://coding.m.imooc.com
2、加载html中的静态资源
四、加载一个资源的过程
1、浏览器根据dns服务器得到域名的Ip地址
2、向这个ip的机器发送http/https请求
3、服务器收到、处理并返回http/https请求
4、浏览器得到并返回内容
五、浏览器渲染页面的过程
1、根据html结构生成dom Tree
2、根据css生成cssom(om:object model)
3、将dom和cssom整合行程renderTree
4、浏览器根据renderTree开始渲染和展示
5、遇到,会执行并阻塞渲染
一、为什么要把js放在body最下面
一、原则
1、多使用内存、缓存或者其他方法。
2、减少cpu就散,减少网络。
二、从哪里入手
1、加载页面和静态资源。
2、页面渲染。
三、加载资源优化
1、静态资源的压缩合并
2、静态资源缓存
(1)通过链接名称控制缓存,只有内容改变的时候,链接名称才会改变。
3、使用cdn让资源加载更快
(1)bootcdn
4、使用ssr后端渲染,数据直接输出到html中(ssr:server site render)
四、渲染优化
1、css放前面,js放后面。
2、懒加载(图片懒加载,下拉加载更多)
3、减少dom查询,对dom查询做缓存。
// 未缓存dom查询
var i;
for (i = 0; i < document.getElementsByTagName('p').length; i++) {\
// todo
}
// 缓存了dom查询
var pList = document.getElementByTagName('p');
var i;
for (i = 0; i < pList.length; i++) {
// todo
}
4、减少dom操作,多个操作尽量合并在一起执行。
var frag = document.createDocumentFragment(); // 片段,循环插入dom,改成先插入到片段,再append到文档流
5、事件节流
var textarea = document.getElementById('text');
var timeoutId;
textarea.addEventListener('keyup', function() {
if(timeoutId) {
clearTimeout(timeoutId);
}
timeoutId = setTimeout(function() {
// 触发change事件
}, 100)
})
6、尽早执行操作(如DOMContentLoaded)
一、xss
1、前端替换关键字,如替换<为<
> 为>
2、后台替换。
一、简历
1、简洁明了,重点突出项目经理和解决方案。
有什么问题,用什么解决
技术栈
二、博客,个人博客放在简历,并且定期维护更新博客。
三、个人的开源项目放在简历中,并维护开源项目。
四、简历不要造假,保持能力和经历上的真实性。