记头条前端面试

头条前端 面试小记

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

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);
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。