一
零、准备
-
0.面试环节设置:
- 一面:基础知识
- 二面/三面:中高级人员问你基础知识之上,问原理,一般都是从简历入手。
- 三面/四面:技术负责人或业务负责人关注你从业生涯的业务、角色、你改变了什么。
- 终面:hr面。沟通、性格、潜力。
-
1.职位描述(JD)分析
- 认真分析职位要求,快速识别这个岗位自己是否喜欢,二是目前的技术能力能否hold住这个岗位。
- 认真准备要求上出现的技术。工作经验年限不要太较真。了解、熟悉、精通,注意3者用词区别。
-
2.业务分析或实战模拟
- 更加具体的分析这个公司所用到的技术栈,以及他们的业务特色是什么,更侧重哪些知识点
- (官网的开发,给些不同的开发思路。)
- 控制台研究用到的技术栈。
-
3.技术栈准备
- 技术:
- jQuery:1.源码:核心架构,事件委托,插件机制,兼容性(可不看)。2.方法:看博客,不用自己看源码
- Vue.js/React/Angular:准备1-2个即可。
- node.js:如果不了解,就不要在简历体现。除非职位要求
- 前端工程:
- SASS/less:去了解
- gulp/grunt:都不了解,准备gulp吧
- npm:一定要准备它。常用的命令(有相关资料,在裙里
- webpack:一定要看
-
4.自我介绍
- 简历:
- 基本信息
- 学历
- 工作经历:时间-公司-岗位-职责-技术栈-业绩
- 开源项目,GitHub和说明
- 自我陈述 :
- 把握面试的沟通方向
- 豁达、自信的适度发挥
一、
-
1.页面布局
-
- 代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>页面布局</title>
<style>
html *{
padding: 0;
margin: 0;
}
.layout{
margin-top: 20px;
}
.layout article div{
min-height: 60px;
}
</style>
</head>
<body>
<section class="layout float">
<style media="screen">
.layout.float .left{
float: left;
width: 300px;
background: red;
}
.layout.float .right{
float: right;
width: 300px;
background: blue;
}
.layout.float .center{
background: yellow;
}
</style>
<article class="left-right-center">
<div class="left"></div>
<div class="right"></div>
<div class="center">
<h1>浮动解决方案</h1>
1、这是三栏布局的中间部分
2、这是三栏布局的中间部分
</div>
</article>
</section>
<section class="layout absolute">
<style>
.layout.absolute .left-right-center>div{
position: absolute;
}
.layout.absolute .left{
left: 0;
width: 300px;
background: red;
}
.layout.absolute .center{
left: 300px;
right: 300px;
background: yellow;
}
.layout.absolute .right{
right: 0;
width: 300px;
background: blue;
}
</style>
<article class="left-right-center">
<div class="left"></div>
<div class="center">
<h1>绝对定位解决方案</h1>
1、这是三栏布局绝对定位的中间部分
2、这是三栏布局绝对定位的中间部分
</div>
<div class="right"></div>
</article>
</section>
<section class="layout flexbox">
<style>
.layout.flexbox{
margin-top: 100px;
}
.layout.flexbox .left-right-center{
display: flex;
}
.layout.flexbox .left{
width: 300px;
background: red;
}
.layout.flexbox .center{
flex: 1;
background: yellow;
}
.layout.flexbox .right{
width: 300px;
background: blue;
}
</style>
<article class="left-right-center">
<div class="left"></div>
<div class="center">
<h1>flexbox解决方案</h1>
1、这是三栏布局flexbox的中间部分
2、这是三栏布局flexbox的中间部分
</div>
<div class="right"></div>
</article>
</section>
<section class="layout table">
<style>
.layout.table .left-right-center{
width: 100%;
display: table;
height: 60px;
}
.layout.table .left-right-center>div{
display: table-cell;
}
.layout.table .left{
width: 300px;
background: red;
}
.layout.table .center{
background: yellow;
}
.layout.table .right{
width: 300px;
background: blue;
}
</style>
<article class="left-right-center">
<div class="left"></div>
<div class="center">
<h1>表格布局解决方案</h1>
1、这是三栏布局表格布局的中间部分
2、这是三栏布局表格布局的中间部分
</div>
<div class="right"></div>
</article>
</section>
<section class="layout grid">
<style>
.layout.grid .left-right-center{
display: grid;
width: 100%;
grid-template-rows: 60px;
grid-template-columns: 300px auto 300px;
}
.layout.grid .left{
background: red;
}
.layout.grid .center{
background: yellow;
}
.layout.grid .right{
background: blue;
}
</style>
<article class="left-right-center">
<div class="left"></div>
<div class="center">
<h1>网格布局解决方案</h1>
1、这是三栏布局网格布局的中间部分
2、这是三栏布局网格布局的中间部分
</div>
<div class="right"></div>
</article>
</section>
</body>
</html>
-
- 效果:
-
- 每种方案的优缺点?
- 浮动:清除浮动;兼容性好
- 绝对定位:脱离文档流,意味着你下面的所有子元素也必须脱离文档流,可使用性差;快捷,不容易出问题
- flexbox:css3出现,为解决上述问题出现的,比较完美,现在移动端基本上是这种布局。
- table:中间高度撑开后,两旁表格高度会跟着撑开,有时不需要这样;兼容性非常好,IE8不兼容flex。
- grid:可以做很多事情,代码量也非常少。新技术。
- 每种方案的优缺点?
-
- 去掉高度已知,哪个不再实用了?
-
- 在现有代码的基础上,增加中间div的内容,效果如图下,浮动、绝对、grid要改变,flex跟table还可用。
-
- 兼容性,最优方案?
- 扩展题目?
-
2.CSS盒模型
- 基本概念:标准模型+IE模型
- 标准模型和IE模型的区别
- CSS如何设置这两种模型
- 标准模型:box-sizing:content-box;(浏览器默认)
- IE模型:box-sizing:border-box;
- JS如何获取盒模型对应的宽和高
- dom.style.width/height(不能取到所有的,dom文档的内连属性,只能获得内连样式的宽和高,对于外链的是获取不到宽和高的。)
- dom.currentStyle.width/height(跟上一种相比,不管内连还是外链样式,拿到的是浏览器渲染以后的宽和高,缺点是只有IE支持)
- window.getComputedStyle(dom).width/height(跟上一种相比,兼容更多的浏览器,兼容性好)
- dom.getBoundingClientRect().width/height(使用场景是计算一个元素的绝对位置。根据视窗左顶点,拿到left、top、width、height。)
- 根据盒模型节食边距重叠
- 父子元素边距重叠(父元素添加overflow:hidden,相当于给父元素创建了一个BFC)
- 兄弟元素,重叠原则:取最大值。
- BFC(边距重叠解决方案)
- 基本概念:块级格式化上下文。
- 原理(渲染规则):
- 在BFC这个元素的垂直方向的边距会发生重叠
- BFC的区域不会与浮动元素的box重叠(清除浮动布局
- BFC在页面上是一个独立的容器,外面的元素不会影响里面的元素,里面的元素也不会影响外面的元素
- 计算BFC高度的时候,BFC也会参与计算
- 如何创建BFC:
- float值不为null
- position的值不为static或relative
- display的值跟table相关的那几个都是
- overflow的值不为visible(最常用
- BFC的使用场景:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>CSS盒模型</title> <style media="screen"> html *{ margin: 0; padding: 0; } </style> </head> <body> <section id="sec"> <style media="screen"> #sec{ background: #f00; } .child{ height: 100px; margin-top: 10px; background: yellow; } </style> <article class="child"></article> </section> <!--BFC垂直方向边距重叠--> <section id="margin"> <style media="screen"> #margin{ background: pink; overflow: hidden; } #margin p{ margin: 5px auto 25px; background: red; } </style> <p>1</p> <div style="overflow: hidden"> <!--BFC--> <p>2</p> </div> <p>3</p> </section> <!--BFC不与float重叠--> <section id="layout"> <style media="screen"> #layout{ background: red; } #layout .left{ float: left; width: 100px; height: 100px; background: pink; } #layout .right{ height: 110px; background: #ccc; overflow: auto; /*BFC*/ } </style> <div class="left"></div> <div class="right"></div> </section> <!--BFC子元素即使是float也会参与高度计算--> <section id="float"> <style media="screen"> #float{ background: red; /*float: left;*/ /*BFC*/ overflow: auto; /*BFC*/ } #float .float{ float: left; font-size: 30px; } </style> <div class="float">我是浮动元素</div> </section> </body> </html>
-
3.DOM事件
- 基本事件:DOM事件的级别
- DOM0 element.onclick=function(){}
- DOM2 element.addEventListener('click',function(){},false)
- DOM3 element.addEventListener('keyup',function(){},false)
- DOM事件模型
- 捕获:从上到下
- 冒泡:从下到上
- DOM事件流
- 捕获——目标阶段——冒泡
- 描述DOM事件捕获的具体流程
- window——document——html——body——...——目标元素
- Event对象的常见应用
- event.preventDefault() 阻止默认事件
- event.stopPropagation() 阻止冒泡
- event.stopImmediatePropagation() 事件响应优先级
- event.currentTarget 事件委托中,当前所绑定的事件,父级元素
- event.target 事件委托中,当前被点击的元素
- 自定义事件
- Event和CustomEvent都可以自定义事件,区别CustomEvent可以事件名后面可以跟一个object来做参数。
var eve = new Event('custome'); ev.addEventListener('custome',function(){ console.log('costome'); }); ev.dispatchEvent(eve); //CustomEvent方法也可以
-
- 代码实例:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Event</title> </head> <body> <div id="ev"> <style> #ev{ width: 300px; height: 100px; background: red; color: #fff; text-align: center; line-height: 100px; } </style> 目标元素 </div> <script> var ev = document.getElementById('ev'); //dom2 定义事件 默认false,即冒泡阶段触发。true的话表明在捕获阶段触发 window.addEventListener('click',function () { console.log('window captrue'); },true) document.addEventListener('click',function () { console.log('document captrue'); },true) document.documentElement.addEventListener('click',function () { console.log('html capture'); },true) document.body.addEventListener('click',function () { console.log('body captrue'); },true) ev.addEventListener('click',function () { console.log('ev captrue'); },true) //自定义事件 var eve = new Event('test') ev.addEventListener('test',function () { console.log('test dispatch'); }) // ev.dispatchEvent(eve); setTimeout(function () { ev.dispatchEvent(eve); },1000) </script> </body> </html>
-
- 效果:
-
4.类型转换
- 数据类型:最新的ECMAScript标准定义了7种数据类型
- 原始类型:Boolean Null Undefined Number String Symbol
- 对象:Object
- 显示类型转换
- Number函数
- 原始类型转换:
- 数值:转换后还是原来的值
- 字符串:如歌可以被解析为数值,则转换为相应的数值,否则NaN。空字符串转为0.
- 布尔值:true转为1,false转为0
- undefined:转为NaN
- null:转为0
- 对象类型转换:
- 先调用对象自身的valueOf方法,如果该方法返回原始类型的值(数值、字符串、布尔值),则直接对该值使用Number方法,不再进行后续步骤。
- 如果valueOf方法返回复合类型的值,再调用对象自身的toString方法。toString方法返回原始类型的值,则对该值使用Number方法,不再进行后续步骤。
- 如果toString方法返回复合类型的值,则报错。
var a = {aa:1}; console.log('a:',Number(a)); //a:NaN 解析如下: a.valueOf(); //{aa:1} a.toString(); //"[object Object]" Number("[object Object]"); //NaN
- String函数
- 原始类型转换:
- 数值:转为相应的字符串
- 字符串:原来的值
- 布尔值:true转为“true”,false转为“false”
- undefined:转为“undefined”
- null:转为“null”
- 对象类型转换:
- 先调用toString方法,如果返回的是原始类型的值,该值使用String方法,不再进行以下步骤。
- 如果返回的是复合类型的值,再调用valueOf方法。如果返回是原始类型值,则该值使用String方法,不再进行以下步骤。
- 如果返回的是复合类型的值,则报错。
- Boolean函数
- 原始类型转换,以下都为false。除此之外,都为true:
- undefined
- null
- -0
- +0
- NaN
- ‘’(空字符串)
- Number函数
- 隐式类型转换
- 四则运算
- 判断语句
- Native调用
- 常见题目:
[]+[] //"" []+{} //"[object Object]" {}+[] //0 {}+{} //"[object Object][object Object]" true+true //2 1+{a:1} //"1[object Object]"
- typeof:
-
5.HTTP协议
- HTTP协议的主要特点:
- 简单快速。(每个资源都是固定的,统一资源符
- 灵活。(通过一个http协议可以完成不同数据类型的传输
- 无连接。(连接一次就会断掉
- 无状态。(不能区分两次连接者的身份
- HTTP报文的组成部分:
- 请求报文:
-
- 请求行(http方法,页面地址,http协议以及版本
- 请求头(key\value值来告诉服务端我要哪些内容,要注意什么类型
- 空行
- 请求体
- 相应报文:
-
- 状态行
- 相应头
- 空行
- 响应体
- HTTP方法
- GET:获取资源
- POST:传输资源
- PUT:更新资源
- DELETE:删除资源
- HEAD:获得报文手部
- POST和GET的区别
- GET在浏览器回退时是无害的,而POST会再次提交请求
- GET产生的URL地址可以被收藏,而POST不可以
- GET请求会被浏览器主动缓存,而POST不会,除非手动设置
- GET请求只能进行URL编码,POST支持多种编码方式
- GET请求参数会被完整的保存在浏览器历史记录里,而POST中的参数不会被保留
- GET请求在URL中传送的参数是有长度限制的,而POST没有限制
- 对参数的数据类型,GET只接受ASCII字符,而POST没有限制
- GET比POST更不安全,因为参数直接暴露在URL中,所以不能用来传递敏感信息
- GET参数通过URL传递,POST放在Request body中
- HTTP状态码
- 1XX:指示信息——表示请求已接收,继续处理
- 2XX:成功——表示请求已被成功接收
- 3XX:重定向——要完成请求必须进行更进一步的操作
- 4XX:客户端错误——请求有语法错误或请求无法实现
- 5XX:服务器错误——服务器未能实现合法的请求
-
-
- 200 OK:客户端请求成功
- 206 Partial Content:客户发送了一个带有Range的GET请求,服务器完成了它
- 301 Moved Permanently:所请求的页面已经转移至新的URL(重定向)
- 302 Found:所请求的页面已经临时转移至新的URL(临时重定向)
- 304 Not Modified:客户端有缓冲的文档并发出了一个条件性的请求,服务器告诉客户,原来缓冲的文档还可以继续使用
- 400 Bad Request:客户端请求有语法错误,不能被服务器所理解
- 401 Unauthorized:请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用
- 403 Forbidden:对被请求页面的访问被禁止
- 404 Not Found:请求资源不存在
- 500 Interval Server Error:服务器发生不可预期的错误原来缓冲的文档还可以继续使用
- 503 Server Unavailable:请求未完成,服务器临时过载或当机,一段时间后可能恢复正常
-
-
- 什么是持久连接
- HTTP协议采用“请求-应答”模式,当使用普通模式,即非Keep-Alive模式时,每个请求/应答客户和服务器都要新建一个连接,完成之后立即断开连接(HTTP协议为无连接的协议)
- 当使用Keep-Alive模式(又称持久连接、连接重用)时,Keep-Alive功能使客户端到服务器端的连接持续有效,当出现对服务器的后继请求时,Keep-Alive功能避免了建立或者重新建立连接
- 什么是管线化
- 在使用持久连接的情况下,某个连接上消息的传递类似于:请求1—>响应1—>请求2—>响应2—>请求3—>响应3
- 管线化后,某个连接上的消息变成了类似这样:请求1—>请求2—>请求3—>响应1—>响应2—>响应3
- 管线化机制通过持久连接完成,仅在HTTP/1.1支持此技术
- 只有GET和HEAD请求可以进行管线化,而POST则有所限制
- 初次创建连接时不应启动管线机制,因为对方(服务器)不一定支持HTTP/1.1版本的协议
- 管线化不会影响响应到来的顺序,如上面的例子,响应返回的顺序并未改变
- HTTP/1.1要求服务器端支持管线化,但并不要求服务器端也对响应进行管线化处理,只是要求对于管线化的请求不失败即可
- 由于上面提到的服务器端问题,开启管线化很可能不会带来大幅度的性能提升,而且很多服务器端和代理程序对于管线化的支持并不好,因此现在浏览器如CHrome和Firefox默认并未开启管线化支持
- 什么是持久连接
-
6.原型链
- 创建对象有几种方法
-
<script> //第一种方式:字面量 var o1 = {name:'o1'}; var o2 = new Object({name:'o2'}); //第二种方式:通过构造函数 var M = function(name){this.name=name} var o3 = new M('o3'); //第三种方式:Object.create var P={name:'o4'}; var o4 = Object.create(P) </script>
-
- 原型、构造函数、实例、原型链
- 只要是对象,就是一个实例
- 任何函数,都可以当作构造函数。任何一个函数,只要被new使用,就是一个构造函数。构造函数可以使用new运算符来生成一个实例。
- 函数都有prototype属性,这个是在声明一个函数的时候,js自动加上去的。这个prototype指的就是原型对象。
- 原型对象中会有一个构造器constructor,这个构造器会默认你声明的那个函数
- 实例通过__proto__属性,找到原型对象。
- 原型链:从实例对象往上找,构造这个实例相关联的对象,然后这个关联的对象继续往上找,又有创建它的上一级的原型对象,以此类推,一直到object.prototype原型对象终止。
- 通过原型链的方式找到原型对象,原型对象上的方法是被不同实例所共有的。
-
M.prototype.say=function () { console.log('say hi'); } var o5 = new M('o5');
- instanceof的原理
- 判断实例,不光构造函数,原型对象也返回true
- new运算符
- 一个新对象被创建。它继承自foo.prototype
- 构造函数foo被执行。执行的时候,相应的传参会被传入,同时上下文(this)会被指定为这个新实例。new foo等同于new foo(),只能用在不传递任何参数的情况下。
- 如何构造函数返回了一个“对象”,那么这个对象会取代整个new出来的结果。如果构造函数没有返回对象,那么new出来的结果为步骤1创建的对象
- 创建对象有几种方法
var new2 = function (func) { var o=Object.create(func.prototype); var k=func.call(o); if(typeof k === 'object'){ return k }else{ return o } }
-
7.面向对象类
- 类与实例
- 类的声明
- 生成实例
-
<script> //类的声明 function Animal() { this.name = 'name'; } // ES6中的class的声明 class Animal2(){ constructor(){ this.name = name; } } //实例化 console.log(new Animal()); </script>
- 类与继承
- 如何实现继承:继承的本质就是原型链
- 继承的几种方式
- 1.借助构造函数实现继承:缺点是父类原型对象上的方法,子类继承不到。
//借助构造函数实现继承 function Parent1() { this.name = 'parent1'; } Parent1.prototype.say = function () {}; function Child1() { /*将父级的构造函数的this指向子构造函数的实例上去, 导致父级构造函数的所有属性在子类中也有。*/ Parent1.call(this); //apply this.type = 'child1'; } console.log(new Child1());
- 2.借助原型链实现继承:
//借助原型链实现继承 function Parent2() { this.name = 'parent2'; } function Child2() { this.type = 'child2'; } Child2.prototype = new Parent2(); console.log(new Child2) //无传参,()可省略
- 1.借助构造函数实现继承:缺点是父类原型对象上的方法,子类继承不到。
- 类与实例
缺点:在一个类上实例两个对象,改一个对象的属性,第二个对象也跟着改变。因为原型链上的原型对象它俩是共用的。
//借助原型链实现继承 function Parent2() { this.name = 'parent2'; this.play = [1,2,3]; } function Child2() { this.type = 'child2'; } Child2.prototype = new Parent2(); // new Child2().__proto === Child2.prototype //true console.log(new Child2) //无传参,()可省略 var s1 = new Child2(); var s2 = new Child2(); console.log(s1.play,s2.play); s1.play.push(4); console.log(s1.play,s2.play); // s1.__proto__ === s2.__proto__ //true
-
-
-
- 3.组合方式:可以解决上述2种的缺陷,不足之处是父构造函数调用2次
-
-
//组合方式 function Parent3() { this.name = 'parent3'; this.play = [1,2,3]; } Parent3.prototype.say = function () {} function Child3() { Parent3.call(this); //1 this.type = 'child3'; } Child3.prototype = new Parent3(); //2 console.log(new Child3()) console.log(new Child3().say) var s3 = new Child3(); var s4 = new Child3(); s3.play.push(4); console.log(s3.play,s4.play);
-
-
-
- 4.组合继承的优化1:缺点是实例不确定继承的是子类还是父类(上一个方式也有这个缺点)
//组合继承的优化1 function Parent4() { this.name = 'parent4'; this.play = [1,2,3]; } function Child4() { Parent4.call(this); this.type = 'child4'; } Child4.prototype = Parent4.prototype; //important var s5 = new Child4(); var s6 = new Child4(); console.log(s5,s6); console.log(s5 instanceof Child4, s5 instanceof Parent4); console.log(s5.constructor);
- 组合继承的优化2:实例继承自子类
//组合继承的优化2 function Parent5() { this.name = 'parent5'; this.play = [1,2,3]; } function Child5() { Parent5.call(this); this.type = 'child5'; } Child5.prototype = Object.create(Parent5.prototype); // __proto__ Child5.prototype.constructor = Child5; var s7 = new Child5(); console.log(s7 instanceof Child5, s7 instanceof Parent5); console.log(s7.constructor); //Child5
- 4.组合继承的优化1:缺点是实例不确定继承的是子类还是父类(上一个方式也有这个缺点)
-
-
-
8.通信
- 什么是同源策略及限制
- 同源策略限制从一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的关键的安全机制。
- 源:包含三个部分,协议、域名、端口。没写端口的话,默认端口是80。
- 限制:不是一个源的文档,没有权利去操作另一个源的文档。
- 主要限制:
- Cookie、LocalStorage和IndexDB无法读取
- DOM无法获得
- AJAX请求不能发送
- 前后端如何通信
- Ajax
- WebSocket
- CORS
- 如何创建Ajax
- XMLHttpRequest对象的工作流程
- 兼容性处理
var xhr = XMLHttpRequest ? new XMLHttpRequest : new window.ActiveXObject('Microsoft.XMLHTTP');
- 事件的触发条件
- 事件的触发顺序
- 跨域通信的几种方式
- JSONP。(JSONP的原理?怎么实现的?如果让你来实现,你怎么实现?)
- 利用script的标签异步加载来实现的
- Hash:URL地址中#后面的东西。Hash改变,页面不会刷新(URL中?后面的search的改变页面会刷新,所以search不能做跨域通信)
//利用hash,场景是当前页面A,通过iframe或frame嵌入了跨域的页面B //在A中伪代码如下: var B = document.getElementByTagName('iframe'); B.src = B.src + '#' + 'data'; //在B中的伪代码如下: window.onhashchange = function(){ var data = window.location.hash; };
- postMessage:H5的新标准
//postMessage //窗口A(http://A.com)向跨域的窗口B(http://B.com)发送信息 //window B: window.postMessage('data','http://B.com'); //窗口B中监听: window.addEventListener('message',function(event){ console.log(event.origin); //http://A.com console.log(event.sourse); //B window console.log(event.data); //data },false);
- WebSocket
//websocket 【参考资料】(http://www.ruanyifeng.com/blog/2017/05/websocket.html) var ws = new WebSocket('wss://echo.websocket.org'); ws.onopen = function(evt){ console.log('Connection open ...'); ws.send('Hello WebSockets!'); }; ws.onmessage = function(evt){ console.log('Received Message: ' + evt.data); ws.close(); }; ws.onclose = function(evt){ console.log('Connection closed. '); };
- CORS:可以理解为变种的支持跨域通信的Ajax:浏览器在识别你用Ajax发送了一个跨域请求的时候,它会在你的http请求头中加一个original,来允许跨域通信
// CORS 【参考资料】(http://www.ruanyifeng.com/blog/2016/04/cors.html) //url(必须),option(可选) fetch('/some/url',{ method: 'get', }).then(function(response){ }).catch(function(err){ //出错了;等价于then的第二个参数,但这样更好用更直观 });
- JSONP。(JSONP的原理?怎么实现的?如果让你来实现,你怎么实现?)
- 什么是同源策略及限制
-
9.安全
- CSRF
- 基本概念和缩写:CSRF,通常成为跨站请求伪造,英文名Cross-site request forgery
- 攻击原理:1.他的网站中某一个接口存在这种漏洞 2.用户在这个网站确实登陆过
- 防御措施:
- 加Token验证:在访问接口的时候,浏览器只是自动生成了cookie,但是没有手动的上传一个token。这个token是你注册成功以后、或者你没有注册,只要你访问这个网站,服务器会自动向你本地存储一个token。在你访问各种接口的时候,如果你没有带着这个token的话,它就不能帮你通过验证。如果我们向上边一样,点击了引诱连接,这个链接只会自动携带cookie,不会自动携带token,所以就避免了攻击。
- Referer验证:Referer指页面来源,服务器判断这个页面来的是不是我这个站点下的页面,如果是的话我就执行动作,如果不是,一律拦截。
- 隐藏令牌:类似token,比如隐藏在http head头中,不会放在链接上,这样的话就会做的比较隐蔽。它俩本质没有太大的区别,只是使用方式上有一点差别。
- XSS
- 基本概念和缩写:XSS(cross-site scripting),跨域脚本攻击
- 攻击原理:(http://www.imooc.com/learn/812)它不需要你做任何的登陆验证,它的核心原理是向你的页面注入脚本
- 防御措施:是让你插入的js不可执行
- CSRF
-
10.算法
- 排序
- 快速排序(https://segmentfault.com/a/1190000009426421)
- 选择排序(https://segmentfault.com/a/1190000009366805)
- 希尔排序(https://segmentfault.com/a/1190000009461832)
- 冒泡
- 堆栈、队列、链表 (https://juejin.im/entry/58759e79128fe1006b48cdfd)
- 递归 (https://segmentfault.com/a/1190000009857470)
- 波兰式和逆波兰式
- 理论:(http://www.cnblogs.com/chenying99/p/3675876.html)
- 源码:(https://github.com/Tairraos/rpn.js/blob/master/rpn.js)
- 排序
二、
-
0.技巧
- 知识面要广
- 理解要深刻
- 内心要诚实
- 态度要谦虚
- 回答要灵活
- 要学会赞美
-
1.模拟
- 渲染机制
- 什么是DOCTYPE及作用:
- DTD(document type definition,文档类型定义)是一系列的语法规则,用来定义XML或(X)HTML的文件类型。浏览器会使用它来判断文档类型,决定使用何种协议来解析,以及切换浏览器模式。
- DOCTYPE是用来声明文档类型和DTD规范的,一个主要的用途便是文件的合法性验证。如果文件代码不合法,那么浏览器解析时便会出一些差错。
- HTML5 : <!DOCTYPE html>
- HTML4.0有严格模式和宽松模式
- Strict 该DTD包含所有的HTML元素和属性,但不包括展示型和弃用的元素(比如font)
- Transitional 该DTD包含所有的HTML元素和属性,包括展示型和弃用的元素(比如font)
- 浏览器渲染过程
- 重排Reflow
- 定义:DOM结构中的各个元素都有自己的盒子(模型),这些都需要浏览器根据各种样式来计算并根据计算结果将元素放到它该出现的位置,这个过程成为reflow
- 触发Reflow:
- 增加、删除、修改DOM节点时,会导致Reflow或Repaint
- 移动DOM的位置,或搞动画的时候
- 修改css样式
- Resize窗口的时候(移动端没有这个问题),或是滚动的时候
- 修改网页默认字体
- 重绘Repaint
- 定义:当各种盒子的位置、大小以及其他属性,例如颜色、字体大小等都确定下来后,浏览器把这些元素按照各自的特性绘制了一遍,于是页面的内容出现了,这个过程称为repaint
- 触发Repaint:
- DOM改动
- CSS改动
- 布局Layout
- 什么是DOCTYPE及作用:
- JS运行机制
- 单线程:同一时间只能做一件事情
- 任务队列:
- 同步任务
- 异步任务:异步任务要挂起,同步任务执行以后才会执行异步任务。
- setTimeout和setInterval
- DOM事件
- ES6中的Promise
- Event Loop
console.log(1); setTimeout(function () { console.log(2); },0); console.log(3); //1,3,2 //setTimeout异步任务等待同步任务执行完成后执行
console.log('A'); while(true){ } console.log('B'); //A 页面不停刷新中,容易卡死 //while循环死循环,永远无法执行下一步console.log(‘B’)
console.log('A'); setTimeout(function () { console.log('B'); },0); while (1){ } console.log('C') //A 且页面一直刷新 死循环 卡死
for(var i=0; i<4; i++){ setTimeout(function () { console.log(i); },1000); } //4个4
- 提升页面性能
- 资源压缩合并,减少HTTP请求 非核心代码异步加载
- 异步加载的方式:1.动态脚本加载 2.defer 3.async
- 异步加载的区别:
- defer是在HTML解析完后才会执行,如果是多个,按照加载的顺序依次执行。
- async是在加载完后立即执行,如果是多个,执行顺序和加载顺序无关
- 利用浏览器缓存
- 缓存的分类:
- 强缓存:问都不问,直接用
//Expires,过期。key:value形式, value是绝对时间,服务器下发时间 Expires:Thu,21 Jan 2017 23:39:02 GMT //Cache-Control。相对时间,客户端时间,3600s。即拿到资源后,3600s之内不会再请求服务器,缺点服务器时间跟客户端时间可能不一致。
//如果服务器两个时间都下发了,以后者为准。规定。
Cache-Control:max-age=3600 - 协商缓存:浏览器问服务器缓存是否过期,能否使用
//Last-Modified //Of-Modified-Since Last-Modified:Wed,26 Jan 2017 00:35:11 GMT //Etag //If-None-Match
- 强缓存:问都不问,直接用
- 缓存的原理
- 缓存的分类:
- 使用CDN
- 预解析DNS
- <meta http-equiv="x-dns-prefetch-control" content="on"> (浏览器默认打开DNS预解析,但是https的则默认关闭。这个强制它打开)
- <link rel="dns-prefetch" href="//host_name_to_prefetch.com"> (预解析DNS)
- 错误监控
- 前端错误的分类
- 即时运行错误:代码错误
- 资源加载错误
- 错误的捕获方式
- 及试运行错误的捕获方式:
- try...catch
- window.onerror
- 资源加载错误的捕获方式:
- object.onerror
- performance.getEntries()
//baidu首页,打开控制台 performance.getEntries().forEach(item =>(console.log(item.name)))
document.getElementsByTagName('img')
- Error事件捕获
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>错误监控</title> <script type="text/javascript"> //true表示捕获 window.addEventListener('error',function (e) { console.log('捕获',e); },true) </script> </head> <body> <script src="/baidu.com/test.js" charset="utf-8"></script> </body> </html>
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>错误监控</title> <script type="text/javascript"> //false表示冒泡,捕获不到事件 window.addEventListener('error',function (e) { console.log('冒泡',e); },false) </script> </head> <body> <script src="/baidu.com/test.js" charset="utf-8"></script> </body> </html>
- 延伸:跨域的js运行错误可以捕获吗?错误提示什么?应该怎么处理?
- 在script标签增加crossorigin属性
- 设置js资源响应头Access-Control-Allow-Origin:*
- 及试运行错误的捕获方式:
- 上报错误的基本原理
- 采用Ajax通信的方式上报
- 利用Image对象上报
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>错误监控</title> </head> <body> <script type="text/javascript"> (new Image()).src = 'http://baidu.com/tesjk?r=tksjk'; </script> </body> </html>
- 前端错误的分类
- MVVM框架类
- 了解MVVM框架吗?
- Vue.js/React.js/Angular
- 想好说哪个。收住优点,攒着说,开启引导模式。话别太满,谨慎。
- 谈谈你对MVVM的认识?
- 先说MVC,彰显知识面
- MVVM的定义
- 对比MVVM和MVC
- 双向绑定是什么原理,可以写出来吗?
- object.defineProperty的用法要熟记于心
- object.defineProperty与reflect.defineProperty的区别
- object.defineProperty要会手写
- 使用了什么设计模式?
- 生命周期是什么?
- 有看过源码吗?
- 了解MVVM框架吗?
- 渲染机制