记头条前端面试

头条前端 面试小记

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

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);
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,602评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,442评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,878评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,306评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,330评论 5 373
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,071评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,382评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,006评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,512评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,965评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,094评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,732评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,283评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,286评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,512评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,536评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,828评论 2 345