美文网首页
面试题整理(二)

面试题整理(二)

作者: 宋乐怡 | 来源:发表于2019-08-15 12:09 被阅读0次

    1.对象方法
    2.新建对象时,new操作符干了什么?var a = new A;
    3.bem,bfc
    4.永久性重定向(301)和临时性重定向(302)对 SEO 有什么影响?
    5.一个div,左边固定,右边、自适应,有几种方法?
    6.清除浮动
    7.div水平垂直居中
    8.VUE双向绑定原理,对MVVM的理解
    9.diff算法时间复杂度及原理
    10.webpack打包时如何优化减少打包时间?webpack loader和plugin有什么区别?
    11.尾递归优化,尾调用优化?
    12.遇到过哪些兼容性问题?
    13.深度优先遍历
    14.嵌套数组展开
    15.跨域
    16.文本溢出显示省略号,一行或多行的情况分别处理
    17.Git命令,从指定分支新建分支。
    18.找出数组中重复次数最多的元素
    19.Linux命令,打印执行过的命令
    20.proxy
    21.将数字反转,63->36

    1.对象方法

    答:

    • Object.defineProperty() 修改对象属性的默认特性,创建新属性
    • Object.defineProperties() 多个
    • Object.getOwnPropertyDescriptor() 取得给定属性的描述符
    • instanseOf()检测对象类型
    • a.isPrototypeOf(b) a是否是b的原型
    • Object.getPrototypeOf(a) 找到a的原型
    • hasOwnProperty()返回实例属性
    • in 操作符 存在原型链上的属性
    • hasPrototypeProperty() 返回原型属性
    • Object.keys()返回实例上的可枚举属性
    • Object.getOwnPropertyNames()返回实例上的所有属性,无论是否可枚举

    2.新建对象时,new操作符干了什么?var a = new A;

    答:这种方式调用构造函数,实际经历了以下4个步骤:
    (1)创建一个新对象;
    (2)将构造函数的作用域赋给新对象;(因此this就指向了新对象)
    (3)执行构造函数中的代码;(为这个新对象添加属性)
    (4)返回新对象。

    1. bem,bfc
      瓜子二手车、微店

    答:原文链接:https://juejin.im/post/5909db2fda2f60005d2093db

    BFC(Block Formatting Context)翻译为块级格式化上下文,它其实就是一个css布局的概念,是一个上下文环境, 是一块区域,是一个隔离的独立容器,容器里的子元素不会影响到外面的元素, 反之亦然。
    formatting context 是一个决定如何渲染的容器。

    • BFC布局规则:
      (1)内部的box会在垂直方向一个接一个的放置。
      (2)box之间垂直间距由margin决定,属于同一个BFC的两个相邻的box的margin会重叠。
      (3)每个元素的marginbox的左边与包含块borderbox的左边相接触,即使存在浮动也如此。???
      (4)BFC的区域不会与floatbox重叠。
      (5)BFC就是页面上的一个独立区域,区域里面的子元素布局不会影响到外面的布局排列,反之亦然。
      (6)计算BFC高度时,浮动元素也参与计算。
      (7)位于不同BFC下的元素不会发生margin重叠。

    • BFC有哪些用途?
      (1)自适应两栏布局
      (2)可以阻止元素被浮动元素覆盖,把不浮动的元素添加overflow:hidden ,触发该元素的bfc,让自己免受外界影响。
      (3)可以清除内部浮动(清除浮动的原理是两个div都位于同一个浮动的BFC区域之中。)
      (4)分属于不同的BFC 可以阻止margin重叠。
      (5)解决浮动问题。给父元素加overflow:hidden触发bfc,形成一个独立的渲染区域,所以内部的元素不会影响外面的布局,bfc把浮动子元素的高度算作自己的高度处理溢出,所以外界不会受到影响。

    • 触发BFC有哪些方式?
      (1)根元素HTML
      (2)float不为none
      (3)display为inline-block或table-cell
      (4)overflow不为visible
      (5)position不为static
      (6)flex-boxes
      概括来说就是脱离了文档流的元素

    • 文本环绕?


      image.png
      image.png

      div会被float覆盖而文本不会,这是因为float当初设计的时候就是为了让文本在浮动对象周围。

    BEM( Block,Element和Modifier的缩写)是一个高可用的,强大的,而且简单的命名规范,它可以使得你的前端代码更加易读和理解,容易与他人协作,容易扩展,更加强壮和明确,关键是更加严谨

    1. 永久性重定向(301)和临时性重定向(302)对 SEO 有什么影响?
      github 124

    答:从SEO角度出发,301优于302。

    • 301:(Permanently Moved),从搜索引擎优化角度来讲, 301是转移网址最好的办法,因为当网站的域名改变后,搜索引擎只对新网址进行搜索,旧网址下的所有外部链接全部转移到新网址下, 旧网址排名清零作废,从而不会让网站的排名受到影响。另外,使用301命令让多个域名指向网站主域时,也不会对网站的排名产生负面影响。
    • 302:(Temporarily Moved ),使用302重定向时, 绝大部分浏览器会把链接成绩向多个域名分摊,因此就会削弱网站主站的链接总量,作为网站排名的关键因素之一的外链数量受到影响,网站排名自然会降低。目前为止, 只有谷歌对302的这个行为进行了优化,当其他域名指向主域时,会把其他域名的链接成绩计入主域。

    5.一个div,左边固定,右边、自适应,有几种方法?
    博彦科技
    bfc、左边position:absolute,右边margin-left、flex、计算属性、table

    (1)bfc方法(最优,左边菜单拖拽的情况下,可以监听左边元素的宽度,右边什么值都不用改)

    <div class="aside"></div>
    <div class="text">
      <div class="main">aaaaa</div>
    </div>
    .aside {
      width: 100px;
      height: 150px;
      float: left;
      background: #f66;
    }
    
    .main {
      height: 200px;
      overflow: hidden;
      background: #fcc;
    }
    
    .text {
      width: 100%;
    }
    

    注意:是右边部分的父元素宽度100%,让main自己形成一个bfc,bfc的区域不会与float-box重叠。


    image.png

    (2)左边position:absolute,右边margin-left,这个方式和让左边float-left同理。

    <div class="parent">
      <div class="l-child">左边固定1 左边固定2 左边固定3</div>
      <div class="r-child">右边自适应1 右边自适应2 右边自适应3</div>
    </div>
    .parent {
      display: relative;
      background: #ddd
    }
    
    .l-child {
      position: absolute;
      width: 100px;
      background: #bbb
    }
    
    .r-child {
      margin-left: 100px;
      background: #999
    }
    
    image.png

    (3)flex

    body{
                display: flex;
            }
    .right{
                flex:1
            }
    

    (4)table布局

            body{
                display: table;
                width:100%;
            }
            .left{
                display: table-cell;
            }
            .right{
                display: table-cell;
            }
    

    6.清除浮动
    大搜车、微店、
    https://juejin.im/post/59e7190bf265da4307025d91

    答:clear、父元素前加空标签做clear、在parent上加一个伪类,让这个伪类清除浮动、浮动元素的父元素增加overflow不为visible的属性(BFC)。

    (1)在被float影响的元素上添加clear:both;
    如下图,浮动元素导致text元素和下面的other被遮挡。父元素高度撑不开。


    image.png

    解决办法:


    image.png
    不过这种办法也有漏洞,假如浮动元素在text后面,父元素高度依然撑不开,other依然会被影响。
    (2)父元素结束标签之前插入清除浮动的块级元素
    原理同上。
    image.png

    (3)在parent上加一个伪元素,让这个伪元素清除浮动,原理和上面两种相同。


    image.png
    (4)浮动元素的父元素增加overflow不为visible的属性,原理是,这样会触发BFC,而BFC高度包含浮动元素。
    image.png

    7.div水平垂直居中
    作业帮、大搜车、

    答:

    • 未知父元素,未知子元素宽高
      (1) flex
    .parent {
      display: flex;
      justify-content: center;
      align-items: center;
    }
    

    (2)table cell
    子元素设置为inline或inline-block时,父元素display:table-cell

    .parent {
      border: 1px solid black;
      display: table-cell;
      width: 500px;
      height: 500px;
      vertical-align: middle;
      text-align: center;
    }
    
    .child {
      width: 100px;
      height: 100px;
      border: 1px solid red;
      display: inline-block;
    
    }
    

    (3)绝对定位+子元素transform:translate(-50%,-50%);

    .parent {
      border: 1px solid black;
      width: 500px;
      height: 500px;
      position: relative;
    }
    
    .child {
      width: 100px;
      height: 100px;
      border: 1px solid red;
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
    }
    
    • 已知子元素宽高,未知父元素宽高
      (1)子元素绝对定位,top和left都设为50%,然后margin-top和margin-left设为负数自身的一半。
    .parent {
      width: 500px;
      height: 500px;
      border: 1px solid black;
      position: relative;
    }
    
    .child {
      height: 100px;
      width: 100px;
      border: 1px solid red;
      position: absolute;
      top: 50%;
      left: 50%;
      margin: -50px 0 0 -50px;
    }
    

    (2)子元素绝对定位,top,bottom,right,left值均为0,margin设为auto。

    .parent {
      border: 1px solid black;
      position: relative;
    }
    
    .child {
      width: 100px;
      height: 100px;
      border: 1px solid red;
      position: absolute;
      top: 0;
      bottom: 0;
      right: 0;
      left: 0;
      margin: auto;
    }
    

    8.VUE双向绑定原理,对MVVM的理解
    酷家乐,博彦科技

    答:VUE双向绑定是通过Object.defineProperty的数据劫持能力,结合发布者订阅者模式实现的。
    vue中的data实际上是一个带有访问器属性(getter和setter)的对象。

    什么是访问器属性?
    JS对象有两种属性:数据属性和访问器属性,访问器属性不能直接定义,必须通过Object.defineProperty()来定义,它包含一对getter,setter函数,在读取访问器属性时,会调用getter,在写入访问器属性时,会调用setter 并传入新值。setter这个函数负责如何处理数据。

    VUE 就是通过这个Object.defineProperty来实现数据劫持的。

    VUE 的双向绑定包括两个方面,view更新data,data更新view。
    view更新data比较简单,通过事件监听即可,比如input标签绑定input事件。

    比较困难的是data更新view。
    这里面有两个点:
    1.如何知道数据变了?
    2.数据变了如何更新DOM?

    对以上两点做出一些解答:
    1.如何知道数据变了?
    其实上面已经给出答案了,就是通过Object.defineProperty()对属性设置一个set函数,数据改变时就会触发这个函数,我们将一些更新view的方法放在set函数的逻辑里,就可以实现data更新view了。


    image.png
    实现过程

    (1)实现数据的双向绑定,首先要对数据进行劫持监听,所以第一步需要设置一个监听器Observer,用来监听所有属性。
    (2)如果属性发生变化了,就要告诉订阅者watcher看是否需要更新。
    (3)因为订阅者watcher有很多个,所以需要一个消息订阅器Dep来专门收集这些订阅者,在监听器Observer和订阅器Watcher之间进行统一管理。
    (4)接着,为了解析view上的指令, 我们需要一个指令解析器Compiler,对页面每个节点和元素进行扫描和解析,将相关指令初始化成一个订阅者watcher。通过解析指令绑定相应的函数。
    (5)此时,当watcher收到来自Observer的通知,就会执行对应的更新view的函数。

    image.png
    如果要自己实现一个双向绑定也就大致需要以下三个步骤:

    1.实现一个监听器Observer,用来劫持监听所有的属性,有变动就通知watcher。
    2.实现一个watcher,可以收到监听器传来的属性变化通知,并执行相应的函数,从而更新视图。
    3.实现一个解析器Compile,可以扫描解析每个节点的指令,并初始化末班数据和初始化订阅器。

    以下详细思考每个步骤如何实现?

    1.实现Observer

    Observer是一个数据监听器,其实现的核心方法就是前文所说的Object.defineProperty(),如果要对所有的属性都进行监听的话,可以用递归的方法遍历所有属性值,对其进行Object.defineProperty处理。

    image.png

    还需要创建一个容纳所有Watcher的订阅器Dep,订阅器主要负责收集订阅者,然后属性变化的时候,执行对应订阅者的更新函数,所以显然订阅者需要有一个容器,这个容器就是list,将上面的代码稍微改造下,植入Dep。


    image.png

    在get里面添加一个订阅器是为了初始化触发,所以初始化时要判断是否需要添加watcher,这个要具体情况具体考虑。
    接下来实现watcher.

    2.实现监听器watcher

    9.diff 算法时间复杂度及原理
    大搜车、作业帮
    https://user-gold-cdn.xitu.io/2019/8/1/16c49afec13e0416

    10.webpack打包时如何优化减少打包时间?webpack loader和plugin有什么区别?
    北明软件、瓜子二手车、博彦科技、滴滴

    11.尾递归优化,尾调用优化?
    https://www.jianshu.com/p/0ed8ed003fe0

    12.遇到过哪些兼容性问题?

    答:

    • js
      (1)DOM2级定义的深度优先遍历器NodeIterator 和 TreeWalker在IE中没有对应的类型和方法,所以使用遍历的跨浏览器解决方案非常少见。
    • css

    13.深度优先遍历

    • 递归
    function deepTraversal(node,nodeList) {  
        if (node) {    
                nodeList.push(node);    
                var children = node.children;    
                for (var i = 0; i < children.length; i++) 
                    deepTraversal(children[i],nodeList);    
            }    
        return nodeList;  
    }  
    var root = document.getElementById('root')
    console.log(deepTraversal(root,nodeList=[]))
    
    • 非递归
    function deepTraversal(node) {  
        var nodeList = [];  
        if (node) {  
            var stack = [];  
            stack.push(node);  
            while (stack.length != 0) {  
                var childrenItem = stack.pop();  
                nodeList.push(childrenItem);  
                var childrenList = childrenItem.children;  
                for (var i = childrenList.length - 1; i >= 0; i--)  
                    stack.push(childrenList[i]);  
            }  
        }    
        return nodeList;  
    }   
    var root = document.getElementById('root')
    console.log(deepTraversal(root))
    
    1. 嵌套数组展开
    • 递归
    function flattenMd(arr) {
        var result = [];
        for(var i = 0; i < arr.length; i++){
            if(arr[i] instanceof Array) {
                result = result.concat(flattenMd(arr[i]));
            }
            else {
                result.push(arr[i]);
            }
        }
        return result;
    }
    var arr=[1, [2, 3, [4, 5], 6], 7, 8]
    console.log(flattenMd(arr));
    
    • 非递归
    function flattenDeep(arr){
        const res = [];
        const stack = [...arr];
        while(stack.length){
            let item = stack.shift();
            Array.isArray(item)?stack.unshift(...item):res.push(item);
        }
        return res;
    }
    var arr = [1,[2,[3,[[5]]],[4]]];
    console.log(flattenDeep(arr))
    

    15.跨域解决办法?同源策略是什么?
    博彦科技,大搜车,酷家乐,滴滴,贝壳

    答: 通过XHR实现ajax的一个主要限制就来源于跨域安全策略。
    默认情况下,XHR对象只能访问与包含它的页面位于同一个域中的资源。
    以下简要说明常用方法:

    • CORS
    • IE和其他浏览器对CORS的实现
    • Preflighted Request
    • withCredentials 带凭据的请求
    • 跨浏览器的CORS

    CORS(Cross-Origin Resource Sharing)

    CORS背后的思想是,使用自定义的HTTP头部让浏览器与服务器进行沟通,从而决定请求或响应应该是成功还是失败。

    CORS的使用方法:
    在发送请求时,需要给它附加一个额外的Origin头部,其中包含请求页面的信息(协议,域名,端口),以便服务器根据这个信息决定是否给予响应。

    Origin: http://www.nczonline.net
    

    如果服务器认为这个请求可以接受,就在Access-Control-Allow-Origin头部中回发相同的源信息。

    Access-Control-Allow-Origin:http://www.nczonline.net
    

    如果没有这个头部,或者有这个头部但是源信息不匹配,浏览器就会驳回请求,正常情况下,浏览器会处理请求。
    请求和响应都不包含cookie信息。

    IE对CORS 的实现:

    微软在IE8中引入了XDR(XDomainRequest)类型,与XHR相似,但是能实现跨域通信。
    XDR使用方法和XHR类似,
    (1)创建一个XDomainRequest对象
    (2)open() //与XHR不同的是XDR只接受两个参数,请求类型和URL
    (3)send()

    缺点:
    (1)所有的XDR都是异步的,不能用来创建同步请求。
    (2)收到响应后,只能访问响应的原始文本,没有办法确定响应的状态码。成功触发onload,响应数组放在xhr.responseText中,失败触发onerror,但是除了错误本身之外,没有其他信息可以用。

    XDR也支持
    onerror()检测错误
    abort()在请求返回前终止请求
    timeout属性 超时设定
    ontimeout()事件处理程序 超时处理程序

    其他浏览器对CORS的实现

    Firefox3.5+,Sarafi4+,Chrome,ios版Safari和Android平台中的webkit都通过XHR对象实现了对CORS的原生支持。

    使用方法:

    要请求另一个域中的资源,使用标准的XHR对象,并在open()方法中传入绝对的URL即可。

    对比IE中XDR的优点:
    (1)XHR可以访问status和statusText属性
    (2)可以发送同步请求

    但是出于安全考虑也有一些限制:
    (1)不能使用setRequestHeader自定义头部信息。
    (2)不能发送接收cookie
    (3)调用getAllResponseHeaders()总是返回空字符串。

    因为同源请求和跨域请求使用相同的接口,所以建议本地资源使用相对URL,远程资源使用绝对URL,这样能消除歧义,避免出现 限制访问头部或本地cookie信息等问题。

    Preflighted Request

    支持Preflight请求的浏览器有Firefox3.5+,Safari4+,Chrome

    CORS 通过Preflighted Request的透明服务器验证机制支持开发人员使用自定义的GET或POST之外的方法,以及不同类型的主题内容。浏览器向服务器通过高级选项发送一个Preflight请求,服务器可以决定是否允许这种类型的请求。

    withCredentials 带凭据的请求

    支持withCredentials的浏览器有Firefox3.5+,Safari4+,Chrome,IE10及更早版本都不支持。

    默认情况下,跨源请求不提供凭据,(cookie,HTTP认证及客户端SSL等),
    通过将withCredentials设置为true,可以指定某个请求应该发送凭证。如果服务器接收带凭据的请求,会用下面的HTTP头部来响应。
    Access-Control-Allow-Credentials: true

    16.文本溢出显示省略号,一行或多行的情况?

    答:

    • 一行:
     overflow: hidden;
      text-overflow: ellipsis;
      white-space:nowrap;
    }
    
    • 多行
    .a {
      display: inline-block;
      width: 200px;
      height: 200px;
      overflow: hidden;
      position: relative;
    }
    
    .a::after {
      content: '...';
      position: absolute;
      right: 0;
      bottom: 0;
    }
    
    

    17.Git命令,从指定分支新建分支。

    git branch [branch name] [from branch name ]
    

    18.找出数组中重复次数最多的元素

    答:

    var arr = [1];
    var res = {};
    var most = -1;
    var ele = -1;
    
    function findMost(arr) {
      if (!arr.length) {
        return
      } else if (arr.length == 1) {
        return arr[0];
      } else if (arr.length > 1) {
        for (let i = 0; i < arr.length; i++) {
          res[arr[i]] ? res[arr[i]]++ : res[arr[i]] = 1;
          if (res[arr[i]] > most) {
            most = res[arr[i]];
            ele = arr[i];
          }
    
        }
      }
      console.log(ele);
    
    }
    
    findMost(arr);
    

    19.Linux命令,打印执行过的命令

    history [n] //n是数字,要打印的条数
    

    20.proxy
    VUE3.0的双向数据绑定

    proxy用于修改某些操作的默认行为,等同于在语言层面做出修改,所以属于一种“元编程”,即对 编程语言进行编程。
    Proxy可以理解成在目标对象前架设一个拦截层,外界对该对象的访问必须先通过这层拦截,因此提供了一种机制可以对外界的访问进行过滤和改写。Proxy这个词的愿意是代理,用在这里表示由他来”代理“某些操作,可以译为代理器

    21.将数字反转

    答:

    function reverseNum(n){
    console.log(n.toString().split("").reverse().join("")) | 0;
    }
    reverseNum(123);
    

    相关文章

      网友评论

          本文标题:面试题整理(二)

          本文链接:https://www.haomeiwen.com/subject/ucckjctx.html