美文网首页
记头条前端面试

记头条前端面试

作者: FConfidence | 来源:发表于2017-12-27 13:15 被阅读159次

    头条前端 面试小记

    因为是职业生涯第一次面试, 所以有很多地方准备不足的地方, 心理上有点慌张, 现将面试的题目整理一下,实际上这些题目私底下稍微想一下, 都应该能写出来.

    1. 实现界面中一个正方形, 宽度高度是body的一半, 同时在body中居中

    第一思路是使用flex布局, 确实可以水平和垂直居中, 但是重点在于正方形, 宽高是body的一半
    后来提示说可以使用css3的新单位, 想了想rem不行, 后来想到了用vh vw但是自己不会用, 写了一半放弃了, 实际上vh可以实现

    html, body {
        height: 100%;
        width: 100%;
        margin: 0;
        padding: 0;
    }
    body {
        display:flex;
        align-items: center;
        justify-content:center;
        background: #aaa;
    }
    .div-center {
        height: 50vh;
        width: 50vh;
        border: 1px solid red;
    }
    

    第二种实现方案: 原理: 利用padding的百分比是按照父元素的宽度计算来实现

    * {
         padding: 0;
         margin: 0;
     }
    
     html,
     body {
         width: 100%;
         height: 100%;
     }
    
     body {
         position: relative;
     }
    
     .box {
         position: absolute;
         left: 0;
         top: 0;
         right: 0;
         bottom: 0;
         background: red;
         box-sizing: border-box;
         width: 50%;
         padding-bottom: 50%;
         height: 0;
         margin: auto;
     }
    

    2. call, apply, bind的区别, 用apply实现自己的bind方法

    • 不多说了, 直接贴代码吧, 当时写到一半, 以为自己写不出来, 有点虚, 平时实践的代码还是写的太少了, 概念性的东西懂, 所以要多写代码
    function func(a) {
      this.a = a;
    }
    
    var obj = {};
    // var f1 = func.bind(obj, a)
    
    // 柯理化
    Function.prototype.bd = function(context) {
    
      // 这里this指的是当前调用的方法
      console.log(typeof this)
      var _this = this;
      return function(a) {
        _this.apply(context, [a])
      }
    }
    
    var a = 1
    
    // 第一个参数 替换func里面的this  第二个参数表示传递的参数
    func.bd(obj)(a)
    
    console.log(obj)
    
    Function.prototype.mybind = function(context) {
      // 调用mybind的时候传递的参数
        var outerArg = Array.prototype.slice.call(arguments, 1)
        var _this = this;
    
        // 标准浏览器  这里比较难理解
        if ("bind" in Function.prototype) {
            // 传递进来的参数传递过bind, 还需要将bind的this指正
            return this.bind.apply(this,[context].concat(outerArg))
        }
        // 兼容化处理
        function _fn() {
            var innerArg = Array.prototype.slice.call(arguments)
            // 将默认传递的参数传递进入
            if (innerArg.length==0) {
                innerArg.push(window.event);
            }
            var arg = outerArg.concat(innerArg)
            _this.apply(context, arg)
        }
        return _fn;
    }
    
    // 完整版
      function bind(callback, context) {
          // 考虑传递的参数问题
          var ourterArg = Array.prototype.slice.call(arguments, 2)
          context = context || window;
          function _fn() {
              var innerArg = Array.prototype.slice.call(arguments)
              console.log(innerArg) // MouseEvent
              callback.apply(context, outerArg.concat(innerArg))
          }
          return _fn;
      }
    
    

    3. JSONP原理, 自己实现JSONP

    • 好吧, 我讲的是后台是怎么实现的, 前端我平时都是用jquery已经封装好的, 原理当时讲的是后台返回一段用callback包好数据的一段字符串, 前端用eval进行运行, 写代码的时候傻到用XMLHttpRequest, 唉, 回头一想就知道自己错了
    • JSONP原理: 利用<script>标签没有跨域限制的“漏洞”来达到与第三方通讯的目的。当需要通讯时,本站脚本动态创建一个<script>元素,地址指向第三方的API网址, 调用双方协商好的回调函数, 在回调中处理数据
      优点: 兼容老式浏览器, 无跨域限制
      缺点: 只能是GET请求, 不能发送POST请求
    function JSNP(url, callbackName) {
        var script = document.createElement('script');
        script.src = url+'&callback='+callbackName; // callbackName前后台协商
        document.body.appendChild(script); // 只有在append的时候, 脚本才会运行
    }
    
    function callback(data) {
        alert(data)
    }
    

    4. 隐式转换的问题

    问题: 隐式转换规则即案例分析

    1. 如果x不是正常值(比如抛出一个错误),中断执行。

    2. 如果y不是正常值,中断执行。

    3. 如果Type(x)与Type(y)相同,执行严格相等运算x === y。

    4. 如果x是null,y是undefined,返回true。

    5. 如果x是undefined,y是null,返回true。

    6. 如果Type(x)是数值,Type(y)是字符串,返回x == ToNumber(y)的结果。

    7. 如果Type(x)是字符串,Type(y)是数值,返回ToNumber(x) == y的结果。

    8. 如果Type(x)是布尔值,返回ToNumber(x) == y的结果。

    9. 如果Type(y)是布尔值,返回x == ToNumber(y)的结果。

    10. 如果Type(x)是字符串或数值或Symbol值,Type(y)是对象,返回x == ToPrimitive(y)的结果。
      Number( {toString() {return 1} } ) 为1
      对象和其他类型比较的时候 对象转化成为PrimitiveValue

    11. 如果Type(x)是对象,Type(y)是字符串或数值或Symbol值,返回ToPrimitive(x) == y的结果。

    12. 不满足上述情况返回false。

    • 案例分析: (不多讲直接贴原理)
    1) 0==null  不属于上述1-11情况 返回false
    
    2) false == '0'
        x是布尔值 属于第8种情况 则 0 == '0'
        0 == '0' 属于第6种情况 则 0 == 0 
        0 == 0 满足第三种情况 返回true
    
    3) true == ({toString() {return '1'}})
        x是布尔值 第七种情况 则 Number(true) 即比较 1== ({toString() {return '1'}})
        1== ({toString() {return '1'}}) 中 y是对象 满足第10种情况  所以 1 == '1'
        1=='1' 满足第6中情况 所以 1==Number('1') 
        1 == 1 第三种情况 返回true
    
    4) NaN == NaN 不满上上述11种情况 返回false
    
    5) undefined == undefined 满足第三种情况 执行  undefined === undefined  为true    
    
    // 头条题目
    if ([]== false) { console.log(1); };
    if ({} == false) { console.log(2); };
    if ([]) { console.log(3); }; //Boolean([])
    if ([1] == [1]) { console.log(4); };
    

    5. 自己实现inherit函数, 即实现自己的继承函数

    var Animal = function(name) {
        this.name = name;
    }
    
    Animal.prototype.hello = function() {
        console.log('hello, '+ this.name)
    }
    
    var Cat = inherit(Animal, {
        say:function() {
            console.log('MiaoMiao, ' + this.name)
        }
    })
    
    var cat = new Cat('miaomiao');
    cat.hello();
    
    // 题目: 实现inherit函数
    

    6. promise nextTick setTimeout setImmediate的执行顺序问题

    console.log('script start'); // 1
    
    setTimeout(function() {
        console.log('setTimeout');
    }, 0);
    
    new Promise(function(resolve) {
        console.log('promise1');
        resolve();
    }).then(function() {
        console.log('promise2');
    });
    
    // 2
    console.log('script end');
    

    7. 从长度为m的数组中选取n个数 使其和满足为target, 已知n个数必存在

    // 从给定的无序、不重复的数组data中,取出n个数,使其相加和为sum(不需要找到所有的解,找到一个解即可)
    

    8. 快速排序

    算法思想: 在待排序的表中L[0....n-1]中, 任意取一个元素作为基准值pivot, 通过一趟排序将待排序列划分为两个独立的部分, 其中L[0 ... k-1]和L[k+1 ... n-1], 其中L[0 ... k-1]所有的元素都小于pivot基准元素, L[k+1 ... n-1]中的元素都大于或者等于pivot , 同时将pivot放在最终的位置L[k]上吗这一趟过程称之为快速排序

    • 时间复杂度: O(nlog2n)
    • 稳定性: 不稳定
    • 优化:
        1. 当递归过程中的子序列的规模较小的时, 不要再继续递归调用快速排序, 可以采用直接插入排序算法进行后续的操作
        1. 尽量选取一个可以将数据中分的枢纽元素 (从序列中头尾以及中间选取三个元素, 将三个元素的中间值作为枢纽元素, 或者随机在序列中获取)
    /*时间复杂度: log2n*/
    function QuickSort(arr, low, high) {
        if (low < high) {
            var pivotPos = PartionSort(arr, low, high);
            QuickSort(arr, low, pivotPos);
            QuickSort(arr, pivotPos + 1, high);
        }
    }
    /*时间复杂度: n */
    // 一次PartionSort之后 将arr[low]放在了合适的位置上, 其左侧都比其小, 右侧都比其大
    function PartionSort(arr, low, high) {
        // 将当前表中的第一个元素当做枢纽值
        var pivot = arr[low];
        while (low < high) {
            while (low < high && arr[high] >= pivot) high--;
            arr[low] = arr[high];
            while (low < high && arr[low] <= pivot) low++;
            arr[high] = arr[low];
        }
        arr[low] = pivot;
        return low;
    }
    
    var a = [5, 2, 4, 3, 8, 6, 9, 0, 1, 7];
    QuickSort(a, 0, a.length - 1);
    console.log(a);
    

    相关文章

      网友评论

          本文标题:记头条前端面试

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