慕课网《前端跳槽面试必备技巧》学习笔记

关于面试

  • 技术面试
  • 负责人面试
  • HR面试

面试准备

  • JD描述分析
  • 业务分析
  • 技术栈准备
    • jquery:源码研究:核心架构、事件委托、插件机制
    • vue:源码,实战,遇到什么问题,怎么解决的,思路是什么
    • react
    • node
    • sass
    • less
    • gulp
    • webpack
    • npm:常用命令
  • 自我介绍
    • 把手面试的沟通方向
    • 豁达、自信的适度发挥

面试技巧

  • 模拟一面:主要测试基础知识
    • 面试技巧
      • 准备要充分
      • 知识要系统
      • 沟通要简洁
      • 内心要诚实
      • 态度要谦虚
      • 回答要灵活
    • 页面布局类

题目:假设高度已知,请写出三栏布局,其中左栏、右栏宽度各为300px,中间自适应

方法一:display:flex
#container{
    display: flex;
    height: 100vh;
}
.left{
    width: 300px;
    background: red;
}
.content{
    flex: 1;
    background: darkcyan;
}
.right{
    width: 300px;
    background: red;
}
<article id="container">
    <div class="left"></div>
    <div class="content"></div>
    <div class="right"></div>
</article>
方法二:浮动
#container{
    min-height: 100px;
}
.left{
    float: left;
    width: 300px;
    background: red;
}
.content{
    background: darkcyan;
}
.right{
    float: right;
    width: 300px;
    background: red;
}
<article id="container">
    <div class="left"></div>
    <div class="right"></div>
    <div class="content"></div>
</article>
方法三:定位
*{
    margin: 0;
    padding: 0;
}
.left{
    position: absolute;
    top: 0;
    left: 0;
    width: 300px;
    height: 100vh;
    background: red;
}
.content{
    margin: 0 300px;
    height: 100vh;
    background: darkcyan;
}
.right{
    position: absolute;
    top: 0;
    right: 0;
    width: 300px;
    height: 100vh;
    background: red;
}
<article id="container">
    <div class="left"></div>
    <div class="right"></div>
    <div class="content"></div>
</article>
方法四:表格布局
*{
    margin: 0;
    padding: 0;
}
#contenter{
    display: table;
    width: 100%;
    min-height: 100px;
}
.left,.center,.right{
    display: table-cell;
}
.left{
    width: 300px;
    background: red;
}
.right{
    width: 300px;
    background: cornflowerblue;
}
<article id="contenter">
    <div class="left"></div>
    <div class="center">表格布局</div>
    <div class="right"></div>
</article>
方法五:网格布局
*{
    margin: 0;
    padding: 0;
}
#contenter{
    display: grid;
    width: 100%;
    grid-template-rows: 100px;
    grid-template-columns: 300px auto 300px;
}
.left{
    background: red;
}
.center{
    background: rebeccapurple;
}
.right{
    background: cornflowerblue;
}
<article id="contenter">
    <div class="left"></div>
    <div class="center">表格布局</div>
    <div class="right"></div>
</article>
  • 每个解决方案优缺点

flex布局:是比较完美的

表格布局:兼容性好

网格布局:新技术,代码量少

绝对定位解决方案:

  • 好处是快捷
  • 缺点:布局已经脱离文档流,意味着下面的子元素也要脱离文档流

浮动

  • 浮动后是脱离文档流的,如果处理不好会带来很多问题

  • 优点是兼容性比较好

    • CSS盒模型

      题目:谈谈你对CSS盒模型的认识

      • 基本概念:标准模型+IE模型
      • 标准模型和IE模型区别:宽高的计算方式不同
      • CSS是如何设置这两种模型:
        • box-sizing:content-box
        • box-sizing:border-box (ie模型)
      • JS如何设置获取盒模型对应的宽和高
        • dom.style.width/height:只能取出内联样式的宽高
        • dom.currentStyle.width/height:只有IE支持
        • window.getComputedStyle(dom).width/height:兼容性好
        • dom.getBoundingClientRect().widht/height
      • 实例题(根据盒模型解释边距重叠)
      • BFC(边距重叠解决方案):块级格式化上下文
      • BFC原理:
        1. BFC这个元素的垂直方向会发生重叠
        2. BFC区域不会与浮动元素的box重叠
        3. BFC在页面里是一个独立的容器,外面的元素不会影响里面的元素
        4. 计算BFC高度时,浮动元素也会参与计算
      • 如何创建BFC:
        1. 浮动的值不为none
        2. 只要postion的值不是static或是relative,就创建了BFC
        3. display
        4. overflow:auto/hidden
      • BFC使用场景
      BFC垂直方法边距重叠
      <style>
          article{
              background: blue;
              overflow: auto;
          }
          p{
              margin: 5px 0 25px;
              background: red;
          }
          div{
              overflow: auto;
          }
      </style>
      <section>
          <article>
              <p>1</p>
              <div>
                  <p>2</p>
              </div>
              <p>3</p>
          </article>
      </section>
      BFC不与float重叠
      <style>
          article{
              background: blue;
          }
          .left{
              width: 100px;
              height: 100px;
              float: left;
              background: red;
          }
          .right{
              height: 110px;
              background: #ccc;
              overflow: hidden;
          }
      </style>
      <section>
          <article>
              <div class="left"></div>
              <div class="right"></div>
          </article>
      </section>
      BFC子元素即使是float,也会参与高度计算
      <style>
          section{
              /*float: left;*/
              overflow: auto;
              background: red;
          }
          .float{
              float: left;
          }
      </style>
      <section>
          <div class="float">我是浮动元素</div>
      </section>
      
      • IFC:内联格式化上下文
    • DOM事件类

      • 基本概念:DOM事件的级别
      DOM0 element.onclick=function(){}
      DOM2 element.addEventListener('click',function(){},false)
      DOM3 element.addEventListener('keyup',function(){},false)
      DOM3增加了一些事件类型
      
      • DOM事件模型:
      冒泡:从目标元素往上
      捕获:从上到下的过程往目标元素
      
      • DOM事件流
      浏览器在为当前页面与用户做交互的过程中,点击鼠标左键,这个左键是如何传到页面上。
      一个完整的事件流分三个阶段:
      1. 捕获:
      2. 目标阶段:事件通过捕获到达目标元素
      3. 冒泡阶段:从目标元素再上传到window对象
      
      • 描述DOM事件捕获的具体流程
      1.window
      2.document
      3.html:获取html节点:docoment.documentElement
      4.body
      ……
      目标元素
      
      • Event对象的常见应用
      Event对象的常见应用
      event.preventDefault():阻止默认事件
      event.stopPropagation():阻止事件冒泡
      event.stopImmediatePropagation():阻止事件执行(事件响应优先级)
      event.currentTarget:当前所绑定的事件对象
      event.target:当前被点击的元素
      
      • 自定义事件
      Event('事件名')
      <div id="ev">目标元素</div>
      <script>
          var eve=new Event('custome');
          ev.addEventListener('custome',function () {
              console.log('custome');
          });
          ev.dispatchEvent(eve);
      </script>
      CustomEvent('事件名',obj):可以增加一个obj参数对象
      detail:提供有关事件的自定义信息的子对象。
      <div id="ev">目标元素</div>
      <script>
          var ev=document.getElementById('ev');
          var eve=new CustomEvent('test',{detail:{a:1, b:2}});
          ev.addEventListener('test',function (e) {
              console.log(e.detail.a)
          });
          ev.dispatchEvent(eve);
      </script>
      
    • HTTP协议类

      • HTTP协议的主要特点
        1. 简单快速:URI(统一资源符)是固定的
        2. 灵活:HTTP协议头里有一个数据类型,通过HTTP协议可以完成不同数据类型的传输
        3. 无连接:连接一次就会断开,不会保持连接
        4. 无状态:客户端和服务端是两种
      • HTTP报文的组成部分
        1. 请求报文
          • 请求行:HTTP方法,页面地址,HTTP协议,版本
          • 请求头:key:value
          • 空行:遇到空行,服务端知道下一行不是请求头部分了,该当作请求体解析了
          • 请求休:
        2. 响应报文
          • 状态行
          • 响应头
          • 空行
          • 响应体
      • 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状态码
        • 1**:提示信息-表示请求已接收,继续处理
        • 2**:成功-表示请求已被成功接收
        • 3**:重定向-要完成请求必须进行更进一步的操作
        • 4**:客户端错误-请求有语法错误或请求无法实现
        • 5**:服务器错误-服务器末能实现合法的请求
        • 200 OK:客户端请求成功
        • 206 Partial Content:客户发送了一个带有Range头的GET请求,服务器完成了它
        • 301 Moved Permanently:所请求的页面已经转移至新的url
        • 302 Found:所请求的页面已经临时转移至新的url
        • 304 Not Modified:客户端有缓存的文档并发出了一个条件性的请求,服务器告诉客户,原来缓存的文档可以继续使用
        • 400 Bod Request:客户端请求有语法错误,不能被服务器所理解
        • 401 Unauthorized:请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用
        • 403 Forbidden:对被请求页面的访问被禁止
        • 404 Not Found:请求资源不存在
        • 500 Internal Server Error:服务器发生不可预期的错误原来缓冲的文档还可以继续使用
        • 503 Server Unavailable:请求未完成,服务器临时过载或当机,一段时间后可能恢复正常
      • 什么是持久连接(HTTP1.1版本支持,HTTP1.0版本不支持)
        • HTTP协议采用“请求-应答”模式,当使用普通模式,即非Keep-Alive模式时,每个请求/应答客户和服务器都要新建一个连接,完成之后立即断开连接(HTTP协议为无连接时协议)
        • 当使用Keep-Alive模式(又称持久连接、连接重用)时,Keep-Alive功能使客户端到服务器端的连接持续有效,当出现对服务器的后继请求时,Keep-Alive功能避免了建立或者重新建立连接
      • 什么是管线化:是把所有请求打包给服务器商,服务器端把所有响应一次性打包给客户端
        • 是通过持久连接完成了,仅HTTP1.1支持此技术
        • 只有GET和HEAD请求可以进行管线化,而POST则有所限制
        • 在使用持久连接的情况下,某个连接上消息的传递类似于
        • 请求1-》响应1-》请求2-》响应2-》请求3-》响应3-》
        • 某个连接上的消息变成了类似这样
        • 请求1-》请求2-》请求3-》响应1-》响应2-》响应3
    • 原型链类

      • 创建对象的几种方法
          //对象字面量
         var o1={name:'wbq'};
         console.log(o1.name);
         //new Object
         var o2=new Object({name:'wbq2'});
         console.log(o2.name);
         //构造函数方法
         var o3=function (name) {
             this.name=name;
         }
         var result=new o3('wbq3');
         console.log(result.name);
         //Object.create
         var o4=Object.create({name:'wbq4'});
         console.log(o4.name);
      
      • 原型、构造函数、实例、原型链
        • 对象都有proto属性
        • 原型链原理:利用原型让一个引用类型继承另一个引用类型的属性和方法 构造函数也是函数,任何函数通过new操作符生成一个实例,都是构造函数
        • 构造函数可以使用new操作符生成一个实例
        • 函数都有一个prototype属性,prototype指的是原型对象
        • 原型对象中有一个constructor构造器,默认指向构造函数
        • o3.prototype.constructor===o3//true
        • result.proto===o3.prototype//true
      • instanceof的原理
      • new 运算符
        • 一个新对象被创建,它继承自foo.prototype
        • 构造函数被执行,执行的时候,相应的传参会被传入,同时上下文(this)会被指定为这个新实例,new foo等同于new Foo(),只能用在不传递任何参数的情况
        • 如果构造函数返回一个“对象”,那么这个对象会取代整个new出来的结果,如果构造函数没有返回对象,那么new出来的结果为步骤1创建的对象。
        var M=function (name) {
            this.name=name;
        }
        var new2=function (func) {
          var o=Object.create(func.prototype);
          var k=func.call(o);
          if(typeof k==='object'){
              return k
          }else {
              return o
          }
        }
        
    • 面向对象类

      • 类与实例
        • 类的声明
        /*类的声明:构造函数方法*/
        function Animal(name){
            this.name=name;
        }
        /*ES6中的class的声明*/
        class Animal2{
            constructor(){
                this.name=name;
            }
        }
        
        • 生成实例:
          new Animal()
      • 类与继承
        • 如何实现继承:实现继承本质是原型链
        • 继承的几种方式
        /*借助构造函数实现继承:只实现部分继承,无法继承父类原型对象的方法*/
        function Parent1(){
            this.name='parent1';
        }
        function Child1() {
            Parent1.call(this);//继承
            this.type='child1';
        }
        //call,apply改变函数运行上下文,改变this指向
        console.log(new Child1());
        /*借助原型链实现继承:缺点改第一个对象的属性,第二个对象的属性也跟着改变了*/
        function Parent1(){
            this.name='parent1';
            this.play=[1,2,3];
        }
        function Child1() {
            this.type='child1';
        }
        Child1.prototype=new Parent1();
        console.log(new Child1().play);
        var s1=new Child1();
        var s2=new Child1();
        console.log(s1.play,s2.play);//[1,2,3]f
        s2.play.push(4);
        console.log(s1.play,s2.play);//[1, 2, 3, 4]
        /*借助组合方式实现继承:*/
        function Parent1(){
            this.name='parent1';
            this.play=[1,2,3]
        }
        function Child1() {
            Parent1.call(this);
            this.type='child1';
        }
        Child1.prototype=new Parent1();
        var s1=new Child1();
        var s2=new Child1();
        s2.play.push(4);
        console.log(s1.play,s2.play);//[1,2,3],[1, 2, 3, 4]
        /*借助组合继承优化方式1:*/
        function Parent1(){
            this.name='parent1';
            this.play=[1,2,3]
        }
        function Child1() {
            Parent1.call(this);
            this.type='child1';
        }
        Child1.prototype=Parent1.prototype;//这样不用两次调用new Parent1()
        var s1=new Child1();
        var s2=new Child1();
        s2.play.push(4);
        console.log(s1.play,s2.play);//[1,2,3],[1, 2, 3, 4]
        console.log(s1.instanceOf Child1,s1.instanceOf Parent1);//true,true
        console.log(s1.constructor);//Parent1,缺点是构造函数指向的是一个,无法区分实例是由父类创建还是由子类创建的
        /*借助组合继承优化方式2:*/
        function Parent1(){
            this.name='parent1';
            this.play=[1,2,3]
        }
        function Child1() {
            Parent1.call(this);
            this.type='child1';
        }
        Child1.prototype=Object.create(Parent1.prototype);//Object.create创建对象的原理:
        Child1.prototype.constructor=Child1;
        var s1=new Child1();
        console.log(s1 instanceof Child1,s1 instanceof Parent1);//true true
        console.log(s1.constructor);//Child1
        
    • 通信类

      • 什么是同源策略及限制
      同源策略:端口、域名、协议相同
      同源策略限制从一个源加载的文档或脚本如何与来自另一个源的资源进行交互。
      这是用于隔离潜在恶意文件的关键的安全机制
      1. Cookie,LocalStorage和indexDB无法读取
      2. DOM无法获得
      3. Ajax请求不能发送
      
      • 前后端如何通信
      1.Ajax:同源下的通信方式
      2.WebSocket:不受同源策略限制
      3.CORS:支持跨域通信也支持同源通信
      
      • 如何创建Ajax
      1.XMLHttpRequest对象的工作流程
      2.兼容性处理
      3.事件的触发条件
      4.事件的触发顺序
      
      • 跨域通信的几种方式
      1.JSONP
      原理是什么:利用script可以实现异步加载实现的
      怎么实现的:script的src链接里要加上一个callback名称。在全局创建一个callback函数
      2.Hash:浏览器链接#后面的值
      window.localtion.hash
      window.onhashchange
      利用hash,场景是当前页面A通过iframe或frame嵌入了跨域的页面B
      //在A中的代码
      var B=document.getElementsByTagName('iframe');
      B.src=B.src+'#'+'data';
      //在B中的代码如下:
      window.onhashchange=function(){
          var data=window.location.hash;
      };
      

      3.postMessage

          窗口A向(http:A.com)向跨域的窗口B(http:B.com)发送信息
          //在A窗口发送数据:
          window.postMessage('data','http:B.com')
          //在B窗口中监听message事件:
          window.addEventListener('message',function(event){
              console.log(event.origin);//http:A.com
              console.log(event.source);//Bwindow
              console.log(event.data);//data
          },false);
      

      4.WebSocket

          var ws=new WebSocket('wss://echo.websocket.org');
          ws.onopen=function(evt){
              console.log('Connection open...');
          ws.send('Hello WebSocktes!');
          ws.onmessage=function(evt){
              console.log('Received Message'+evt.data);
              ws.close();
          }
          ws.onclose=function(evt){
              console.log('connection closed')
          }
      }
      

      5.CORS

      fetch('/some/url',{
          method:'get'
      }).then(function(response){
          
      }).catch(function(err){
          //出错,等价于then的第二个参数,但这样更好用直观
      })
      http://www.ruanyifeng.com/blog/2016/04/cors.html
      
    • 前端安全类

      • CSRF
        • 基本概念和缩写:
          Cross-site request forgery:跨站请求伪造
        • 攻击原理:
          1. 用户注册过的网站
          2. 利用本身的漏洞,自动执行一些接口
        • 防御措施:
          • 加Token验证
          • Referer验证:页面来源验证
          • 隐藏令牌:隐藏在http-head头中
      • XSS
        • 基本概念和缩写
          • XSS(cross-核潜艇 scripting):跨域脚本攻击
          • 攻击原理:向页面注入脚本
          • 防御措施
            www.imooc.com/learn/812
    • 前端算法类

  • 模拟二面

    • 面试技巧
    • 渲染机制类
      • 重排Reflow
        • DOM结构中的各个元素都有自已 的盒子,这些都需要浏览器根据各种样式来计算并根据计算结果将元素放到它该出现的位置,这个过程称之为reflow
        • 触发Reflow
        • 当你增加、删除、修改DOM结点时,会导致Reflow或Repaint
        • 当你移动DOM的位置,或是搞个动画时
        • 当你修改css样式时
        • 当你Resize窗口的时候,或是滚动的时候
        • 当你修改网页的默认字体时
      • 重绘Repaint
        • 当各种盒子位置、大小以及其他属性,例如颜色、字体大小等都确定下来后,浏览器于是便把这些元素按照各自的特性绘制一遍,于是页面的内容出现了。
        • 触发Repaint
          • DOM改动
          • CSS改动
    • JS运行机制
      • 异步任务
        • setTimeout和setInterval
        • DOM事件
        • ES6中的promise
    • 页面性能
      • 提升页面性能的方法有哪些?
        • 资源压缩合并,减少HTTP请求
        • 非核心代码异步加载->异步加载方式-》异步加载区别
        • 利用浏览器缓存->缓存分类->缓存的原理
        • 使用CDN
        • 预解析DNS
        <meta http-equiv="x-dns-prefetch-control" content="on">
        <link rel="dns-prefetch" href="//www.imooc.com">
        
      • 异步加载方法
        • 动态脚本加载
        • defer
        • async
      • 异步加载区别
        • defer是在HTML解析完成之后才会执行。如果有多个,按照加载的顺序依次执行
        • async是在加载完成后立即执行,如果是多个,执行顺序和加载顺序无关
      • 浏览器缓存
        • 缓存分类
          • 强缓存
            • Expires:Expires:Thu,21 Jan 2017 23:39:02 GMT
            • Cache-Control:Cache-Control:max-age=3600
          • 协商缓存
            • Last-Modified If-Modified-Since Last-Modified
            • Etag:If-None-Match
    • 错误监控
      • 前端错误的分类
        • 即时运行错误:代码错误
        • 资源加载错误
      • 错误的捕获方式
        • 即时运行错误的捕获方法
          • try...catch
          • window.onerror
        • 资源加载错误
          • object.onerror
          • performance.getEntries()
          • Error事件捕获
      • 上报错误的基本原理
        • 采用Ajax通信的方式上报
        • 利用Image对象上报
          延伸:跨域的js运行错误可以捕获吗,错误提示什么,应该怎么处理?
  1. 在script标签上增加crossorigin属性
  2. 设置js资源响应头Access-Control-Allow-Origin
<script crossorigin  src="http://www.lmj.com/demo/crossoriginAttribute/error.js"></script>

res.setHeader("Access-Control-Allow-Origin","*");
  • 模拟三面
    • 面试技巧
    • 业务能力
      • 我做过什么业务?
      • 负责的业务有什么业绩
      • 使用了什么技术方案
      • 突破了什么技术难点
      • 遇到了什么问题
      • 最大的收获是什么
    • 团队协作能力
    • 带人能力
  • 模拟终面
    • 面试技巧
    • 职业竞争力
    • 职业规划
  • 课程总结
    • 注意事项
    • 复习指南
  • 授课方式
    • 明确面试技巧
    • 模拟题目,由浅入深
    • 代码实战+学习指南

题目演练

知识梳理

复习指导

课程价值

  • JD描述怎么看?
  • 简历怎么写?
  • 知识怎么复习?
  • 问题该怎么回答?
  • 项目怎么准备?
  • 和负责人怎么沟通?
  • HR印象怎么留?

推荐阅读更多精彩内容