头条前端面试(笔试 + 一面)

头条面试

近期参加头条面试,把面试过程整理一遍。

到头条总部,前台给了一份前端面试题,然后就带到小屋去做了。总览了一下整个题目,基础题居多,还有一道算法题。当时也有几道题做得不正确,算法题可以说思路也没有。最后总结也发现头条给的面试题不是很好,一会会在每道题下进行说明。

笔试:基础题1、有CSS实现一个三角箭头,如▶️。

这确实是头条原题,题目中的「 有 」应该为「 用 」。这题之前我在做三角箭头的时候曾经用less去做了一个封装,在【 css secret 】一书中也有怎么实现一个三角箭头,所以一下就想到解决方法。

<div class="arrow"></div>

.arrow {
display: inline-block;
border-left: 0;
border-right: 8px solid #222;
border-top: 8px solid #222;
border-bottom: 8px solid #222;
}

以上是我的答案,这道题我自己写的时候是不断调试,也想到用border来绘三角形,但经过面试官提示,我还是做错了,而正确答案应该是下面的代码段。

<div class="arrow"></div>

.arrow {
display: inline-block;
border-left: 8px solid #222;
border-right: 8px solid transparent;
border-top: 8px solid transparent;
border-bottom: 8px solid transparent;
}

这题考察css中border的高级应用,对于有实战经验的人来说确实很容易,因为平常我们经常用到一些三角形去做些ui。
这题目对于中高级前端来说应该不是什么问题

笔试:基础题2、请使用CSS切不低于两种方式实现自适应搜索框。

没错,这也的的确确是头条原题。错别字「 切 」应该是「 且 」。并且这道题的意思我是很迷茫的,是用input自适应input里的字还是自适应父级元素。
针对这个问题,我问了面试官,他给出的解释是,一个input框,一个button,根据窗口的大小,button宽度不变,input宽度自适应。有点无语。然后我根据需求写下了下面一种方案,根据position去做的。还有另一种我写的是flex,但我平时很少用flex,对flexbox语法不了解,所以只好坦白。

<div class="wrap">
<input type="text" class="input" />
<button type="button" class="button">搜索</button>
</div>

.wrap {
position: relative;
padding-right: 120px;
}
.input {
display: block;
width: 100%;
}
.button {
position: absolute;
top: 0;
right: 0px;
width: 100px;
}

下面是我自己回家后用flex去做的

<div class="wrap">
<input type="text" class="input" />
<button type="button" class="button">搜索</button>
</div>

.wrap {
display: flex;
}
.input {
width: 100%;
}
.button {
width: 100px;
}

发现flex真是简单

这道题考察的是布局,position、flexbox的布局
这道题其实是非常好的题目,但是希望头条能严谨些,把题目说清楚。

笔试:基础题3、请问跨域CORS的http请求和普通的http请求有什么区别,请描述通信过程。

这道题我着实不太清楚,在日常开发中基本没遇见跨域问题,就算是本地开发的跨域问题,也是用nginx来解决的。
我在MDN找到跨域的http控制文档。对跨域的不同也有部分说明。
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS

这道题考察跨域和http,但是考察的比较深入,对于跨域http了解少之又少,甚至是第一次想到这个问题,跨域的http是说明原理。

笔试:基础题4、JS如何解析字节流。

字节流这个名词很少听到,所以这题我也是不知道,只知道与Blob有关。面试官说是如何把blob转成string。

题目很偏,考察Blob对象。

笔试:基础题5、window.onload和document.onload是同时触发吗?请描述触发过程。

在答题的时候,我一直在想window和document基于谁先存在,然后一想window是一个全局的变量。而document只是挂载在window上面的一个属性。所以我回答的时候是指window.onload先触发的。
这道题面试官也没进行讲解和提示。
但你以为这对了么。too simple~!
我回去自己去试的时候给window.onload和document.onload分别赋值如下:

window.onload = function () {
console.log('onload', 1)
}
document.onload = function () {
console.log('onload', 2)
}

你猜输出什么?
输出1,document.onload是不执行的。
然后我换了一个方法

window.onload = function () {
console.log('onload', 1)
}
document.onreadystatechange = function () {
console.log(2)
}

这回我看到这个方法执行了两边,并且先于window.onload执行,这是为什么?
然后我把document.onreadystatechange改造下,想看看内部发生了什么

document.onreadystatechange = function (state) {
console.log(2)
console.log(state)
}

这回可以看到第一次输出的state是这样的:
第一次console.log(state)
第二次输出和第一次基本无差别:
第二次console.log(state)
然后我去看MDN文档https://developer.mozilla.org/en-US/docs/Web/Events/readystatechange,发现这个方法被执行的原因是因为document.readyState发生改变。
然后我再改下代码

document.onreadystatechange = function (state) {
console.log(2)
console.log(state)
console.log('document.readyState', document.readyState)
}

第一次输出 document.readyState interactive
第二次输出 document.readyState complete

在找window.onload的文档的时候,我看到这么一句话(https://developer.mozilla.org/zh-CN/docs/Web/API/GlobalEventHandlers/onload)

在文档装载完成后会触发 load 事件。此时,在文档中的所有对象都在DOM中,所有图片,脚本,链接以及子框都完成了装载。

所以这道题很好解释了,window.onload触发,而document不触发,当document.onreadystatechange触发后,完成DOM的渲染才进行window.onload的触发。
也就是说当DOM结构完成渲染后,整个window窗口才完成渲染,执行onload函数。

这道题再拓展一下,假如在document.readyState === 'interactive'时候进行DOM操作是怎么样的?

document.onreadystatechange = function (state) {
console.log('state', state)
console.log('document', 3),
console.log('document.readyState', document.readyState)
if (document.readyState === 'interactive') {
var node = document.createElement('div')
node.textContent = 'hello world'
document.body.appendChild(node)
}
}

在chrome浏览器下,正常执行:

显然,chrome是不允许document在”interactive”状态添加DOM

接着我再做一个实验,在document.readyState === 'complete'中进行DOM插入会怎么样?

document.onreadystatechange = function (state) {
console.log('state', state)
console.log('document', 3),
console.log('document.readyState', document.readyState)
if (document.readyState === 'complete') {
var node = document.createElement('div')
node.textContent = 'hello world'
document.body.appendChild(node)
}
}

一样的结果:

这道题主要是考察浏览器渲染过程,然鹅不知道为什么头条给出了window.onload和document.onload的对比。而不是window.onload和wdocument.onreadystatechange的对比。纳闷

笔试:简单题1、什么是闭包,如何将下面代码每隔1秒输出数组中的数字。

function fun (arr) {
var i, len;
for (i = 0, len = arr.length; i < len; i++) {
(function (i) {
setTimeout(function () {
console.log(i);
}, i * 1000);
})(i);
}
}

首先说闭包,我简单在纸上写了 闭包就是在作用域里产生一个新的作用域
然鹅,真正的答案并不是这样,这样描述是错的。我们定义闭包的含义就是 当函数可以记住并访问所在的词法作用域时,就产生了闭包,即使函数是在当前词法作用 域之外执行。
然后看了下代码,我对题目犹豫了,因为这题输出的就是每隔一秒输出数组的索引(要认真看题!!!),我以为改变的是匿名函数的参数,但是在匿名函数就已经在内部的作用域里面产生了一个新的i,所以这里并不会有声明提升的问题。因此正确的答案应该是:

function fun (arr) {
var i, len;
for (i = 0,len = arr.length; i < len; i++) {
(function (i) {
setTimeout(function () {
console.log(arr[i]);
}, i * 1000);
})(i);
}
}

这题完全被考蒙了。第一,对自己的积累不自信,第二,题目不看清楚。这个题很简单,考察的是作用域和闭包。

笔试:简单题2、如何实现同域跨标签通信?

这道题我也是没回答上,因为我不清楚题目的具体意思。然后我问了下面试官,他说是同域跨iframe,嗯,这样不就很简单么?
postMessage,可以在文档上查到方法。https://developer.mozilla.org/zh-CN/docs/Web/API/Window/postMessage

笔试:简单题3、怎么判断一个object是不是数组(array),请说出至少两种。

// es6
const isArray = Array.isArray
var isArray = function (obj) {
return Object.prototype.toString.call(obj) === '[object Array]'
}

回答上call的话会对call和apply做对比。
call和apply都是改变上下文的引用,唯一不同的是参数不同,call第一个参数为要改变上下文的target,而后面的参数是args
apply只有两个参数,第一个参数是和call是一样的,第二个参数则是类数组的arguments

var isArray = function (obj) {
return Object.prototype.toString.call(obj, arguments[1], arguments[2], arguments[3]...) === '[object Array]'
}
var isArray = function (obj) {
return Object.prototype.toString.apply(obj, arguments) === '[object Array]'
}

考察apply和call,this,作用域。这道题还是不错的

笔试:简单题4、请描述for in和for of区别。

这道题我回答的是for in是循环遍历对象的可枚举属性。
而for of 则是使用了Iterator来实现的。
之后面试官还问到Object.keys,我回答说遍历的是可枚举属性,然后用的hasOwnProperty去判断是否存在在自己的原型上。

考察原型、迭代器

编程题:编程题1、请用数组的reduce方法实现ES6中的map方法。

待更新…

编程题:编程题2、Range(1,10,3)返回[1, 4, 7, 10]。Range(‘A’, ‘E’, 2)返回[‘A’, ‘C’, ‘F’]

待更新…

文章作者: 韦宗圻
文章链接: https://www.weizongqi.com/2018/03/01/头条/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 wiki
支付宝打赏
微信打赏