头条面试题
一面
:都是基础,问的比较深,BFC、缓存、简单算法;递归、链表排序(冒泡、插入、快排、归并、希尔、堆排序),常用的实现,考察了vue的一些原理和浏览器机制;递归、手动实现节流、防抖,比较麻烦的布局;
- css Bfc static和relative的区别
BFC块级格式化上下文;
static静态定位,relative相对的定位,z-index,top,left,right,bottom;
提示
BFC块级格式化上下文,三个特性
BFC会阻止垂直外边距(margin-top,margin-bottom)的重叠。当元素属于一个BFC时,两个元素才可能发生外边距重叠
BFC不会重叠浮动元素
BFC可以包含浮动
我们可以利用BFC的第三条特性来清除浮动。这里说清除浮动并不是太合适,应该说包含浮动,也就是父容器编程BFC就可以了,如何形成BFC呢
- 根元素
- float为left或right
- overflow为hidden|auto|scroll
- display为table-cell|table-caption|inline-block|flex|inline-flex
- position为absolute|fixed
因此,我们可以为浮动元素的父容器添加上面这些属性来形成BFC达到清除浮动的效果。
hasLayout 我们知道在IE6,7有个hasLayout的概念,很多bug的源头正是它。
- 当元素的hasLayout属性值为false的时候,元素的尺寸和位置由最近的祖先元素控制
- 当元素的hasLayout属性值为true的时候会达到和BFC类似的效果,元素负责自身及其子元素的尺寸的定位
我们可以利用这点在IE6/7下完成清除浮动,首先我们要先看看如何使元素的hasLayout为true
- position:absolute
- float:left|right
- display:inline-block;
- width:除auto外
- height:除auto外
- zoom:除normal外
- 在Ie7中使用overflow:hidden|auto|scroll也可以
Bfc清除浮动
综上,我们就可以得出利用BFC清除浮动的方法:
.clearfix{
*zoom:1;
}
.clearfix:after{
content:".";
display:block;
height:0;
visibility:hidden;
clear:left;
}
或
.clearfix{
*zoom:1;
}
.clearfix:after{
content:"";
display:table;
clear:both;
}上面就是得出的两种浏览器兼容的方案。总之,清除浮动就两种方式
利用 clear 属性,清除浮动 使父容器形成BFC 今天,我们谈的是第二种的方法背后的原理,至于第一种是不涉及的。
- node require和import的区别,require看起来来像注册在全局
node编程中最重要的思想就是模块化,import和require都是被模块化所使用
遵循规范
require是AMD规范引入;
Import是es6的一个语法标准,如果要兼容浏览器的话就必须转化成es5语法调用时间
require是运行时调用,所以require理论上可以运用在代码的任何地方
import是编译时调用,所以必须放在文件开头本质
require是赋值过程,其实require的结果就是对象、数字、字符串、函数等,再把require的结果赋值给某个变量
import是解构过程,但是目前所有的引擎都还没有实现import,我们在node中使用babel支持ES6,也仅仅是将ES6转码为ES5再执行,import语法会被转码为require
- 写版本号排序的代码(及优化),时间复杂度
//第一种 从大到小排序
var arr = ['0.5.1','0.1.1','2.3.3','0.302.1','4.2','4.3.5','4.3.4.5'];
arr.sort((a, b) => {
let i = 0;
const arr1 = a.split('.');
const arr2 = b.split('.');
while(true) {
const s1 = arr1[i];
const s2 = arr2[i++];
if (s1 === undefined || s2 === undefined) {
return arr2.length - arr1.length;
}
if (s2 === s1) continue;
return s2- s1;
}
})- http 的 cache ,浏览器如何获取设置 强缓存&协商缓存
- react 的diff算法,key 的作用 更高效的优化虚拟node
- 是否喜欢看源码,看源码的感觉
- 实现一个add方法,使计算结果能够满足如下预期:
add(1)(2)(3) ()
add(1, 2, 3)(4)()
function add() {
var _args = Array.prototype.slice.call(arguments);
function _adder() {
_args.push(...arguments);
return _adder;
}
_adder.toString = function() {
return _args.reduce(function (a, b) {
return a + b;
});
}
return _adder;
}
// 解答
function sum(...args) {
return args.reduce((a, b) => a + b, 0)
}
function curry(func) {
let args = [];
return function temp(...newArgs) {
if (newArgs.length) {
args = [
...args,
...newArgs
]
return temp
} else {
let val = func.apply(this, args)
args = [];
return val;
}
}
}
let add = curry(sum);
console.log(add(1,2)(2)())项目优化
浏览器重绘和回流
页面中节点一部分或者全部改变布局,显示隐藏引起页面重新构建的--回流
改变节点的属性引起外观改变,不改变页面布局的--重绘虚拟dom的好处
减少频繁操作DOM,优化页面性能(频繁操作DOM,造成页面卡段)动态规划求解最多有几种方案求解硬币找零问题
// 贪心
const MinCoinChange = (coints, amount) => {
coints = coints.sort((a, b) => b - a);
let change = [];
let total = 0;
for (let i = 0; i < coints.length; i++) {
let coin = coints[i];
while(total + coin <= amount) {
change.push(coin);
total += coin;
}
}
return change;
}
console.log(MinCoinChange([1,2,5,10], 36))// 输入:coins = [1, 2, 5], amount = 11
// 输出:3
// 解释:11 = 5 + 5 + 1
var coinChange = function(coins, amount) {
let dp = new Array(amount+1).fill(Infinity);
dp[0] = 0;
for(let i = 1; i <= amount; i++){
for(let coin of coins){
if(i - coin >= 0){
dp[i] = Math.min(dp[i],dp[i-coin]+1);
}
}
}
return dp[amount] == Infinity ? -1 : dp[amount];
};- 比较vue 和react , React 代码与Vue 代码互转和复用
- vue适合小而精的项目,react则更适合偏大的项目
- vue双向绑定 react单向数据流 - react是JSX,Vue是模板语法 - react推崇函数式编程
- 关于异步任务执行的题目,涉及主线程任务、宏任务、微任务
- 场景:从1-10,按顺序每秒输出一个数字
var i = 0;
var timer = setInterval(function () {
console.log(i++)
if (i>10) {
clearInterval(timer);
}
},1000)变量提升,函数内 var 和 let 声明的执行结果各怎样
var a = 10; function say() { console.log(a); var a = 20; // var let a = 20; console.log(a); }css 垂直居中
//弹性盒模型
display:flex;
align-item:center;
justify-content:center;- css 3D 加速
GPU处理- redux 的优缺点
- react 中 render props 适用场景(类组件和函数组件的区别)
- 浏览器缓存策略及相应流程
参考文档https://www.cnblogs.com/slly/p/6732749.html - 手写 Promise.all
- 垂直居中
- arguments是数组吗?如果不是,怎么转换成数组?
- event loop
- 手写节流函数
- event loop, css动画, webpack 插件 , react 生命周期, promise
- 设计和产品规划的一个组件,但是基础组件库没有,rax 的
- HTTPS 和 HTTP 的区别
- 浏览器是单进程吗?进行和线程的区别?
浏览器是多进程 - 什么时候传值,什么时候传变量
- 问了debounce的实现,居中定位的各种方法,给了一个数组求两数相加和等于m总共有多少种可能性,还有问怎么定位排查用户反馈页面性能问题,性能方面的问题聊了比较久
- arguments
- Array.prototype.slice.call(arguments);
- arguments 为什么可以通过上述方式转为数组?
代码执行顺序
// 同步代码
console.log('begin');
// setTimeout 添加一个 宏观任务
setTimeout(() => {
// 同步
console.log('setTimeout 1');
// 微观任务
Promise.resolve()
.then(() => {
// 同步
console.log('promise 1');
// 添加宏观任务
setTimeout(() => {
console.log('setTimeout2 between promise1&2');
})
})
.then(() => {
// 微观任务
console.log('promise 2');
});
}, 0);
// 同步代码
console.log('end');
结果:
begin
end
setTimeout 1
promise 1
promise 2
setTimeout2 between promise1&2
arguments 如何转数组, 尽可能多方式
[...arguments];
Array.prototype.slice.call(arguments);
function(...arg) {}
Array.from(arguments)- react setState什么时候同步什么时候异步
- render props和HOC优缺点
- 手写promise 问的都和自己项目有关的,编程题一道CSS的10px字体无法显示的解决方案,transform:scale,防抖
console.log('begin'); setTimeout(() => { console.log('setTimeout 1'); Promise.resolve().then(() => { console.log('promise 1'); setTimeout(() => { console.log('setTimeout2 between promise1&2'); }) }).then(() => { console.log('promise 2'); }); }, 0);
console.log('end'); 请说出执行结果,并谈一下对事件循环(event loop)的理解 38. 解释一下边距重叠?以及如何解决。什么是BFC? 39. 浏览器的绘制原理,重排及重绘
- 请实现 DOM2JSON 一个函数,可以把一个DOM节点输出JSON的格式,例如下面的例子
<div>
<span>
<a></ a>
</span>
<span>
<a></ a>
<a></ a>
</span>
</div>
{
tag: 'DIV',
children: [
{
tag: 'SPAN',
children: [
{ tag: 'A', children: [] }
]
}//解决问题
function DOM2JSON(node) {
var obj = {};
obj['tag'] = node.nodeName;
obj['children'] = [];
var child = node.children;
for (var i = 0; i < child.length; i++) {
obj['children'].push(DOM2JSON(child[i]))
}
return obj;
}- 请实现如下的函数,可以批量请求数据,所有的 URL 地址在 urls 参数中,同时可以通过 max 参数控制请求的并发度,当所有请求结束之后,需要执行 callback 回掉函数。发请求的函数可以直接使用 fetch 即可
function sendRequest(urls: string[], max: number, callback: () => void) {
}42.ts class里面怎么实现一个runtime里面访问不到private的属性 43.闭包的变量内存怎么分布的
- 协程与同步异步
//http://zhangchen915.com/index.php/archives/719/
//https://blog.poetries.top/browser-working-principle/guide/part1/lesson01.html45.实现一个Promise.all
47.[-1,-2,8,9,-10] 求最大和
48.webpack的plugin与loader的区别,有没有写过plugin或者loader?
49.React的diff算法原理?
50.Node的SSR是否有做过,怎么做的?
51.项目中自认为最好的项目是哪个,做了哪些比较有价值的事?
52.重绘与回流?
53.虚拟dom的好处?
54.编程题:
DomtoJson:将Dom树写成Json格式? 链表环检测? 请实现如下的函数,可以批量请求数据,所有的 URL 地址在 urls 参数中,同时可以通过 max 参数控制请求的并发度,当所有请求结束之后,需要执行 callback 回掉函数。发请求的函数可以直接使用 fetch 即可 function sendRequest(urls: string[], max: number, callback: () => void) { }
55.arguments是数组吗?如果不是,怎么转换成数组?
macrotask和microtask
手写双向绑定实现,两种
顺序延时输出数组里的每一项
promise是如何实现链式调用的
在哪些情况下一个元素绑定的点击事件不会被触发
一个完全二叉树,全部是大于0的整数,给出一个整数N,问从二叉树的根部开始向下,存不存在一个路径,使路径上所有的点的和是N
N级台阶,一次只能跳3级4级或者5级,请问一种有多少种跳法
自我介绍,结合简历中写的项目问整个项目的架构设计
算法题,给一个字符串,给出该字符串字符的所有排列组合方式
前端代码题:EventEmitter 的实现
http 协商缓存和强缓存
项目中的沉淀,做的比较好的项目
node 开发相关,基于node 的项目介绍
二面
- 都是vue各种原理解析. react原理. http协议理解. 用法;
- 各种异步任务执行顺序,类型转换;算法:动态规划
- 讲一下收获最大的项目
- 讲一下 react 常用的优化项
- 讲一下 dom-diff 算法
- 实现下面功能
class Scheduler {
add(promiseCreator) {
// 手写代码部分
return new Promise((resolve, reject) => {
promiseCreator().then(res => {
resolve()
})
})
}
}
const timeout = (time) => new Promise(resolve => {
setTimeout(resolve, time)
})
const scheduler = new Scheduler()
const addTask = (time, order) => {
scheduler.add(() => timeout(time))
.then(() => console.log(order))
}
addTask(1000, '1')
addTask(500, '2')
addTask(300, '3')
addTask(400, '4')
// output: 2 3 1 4
// 一开始,1. 2两个任务进入队列
// 500ms时,2完成,输出2,任务3进队
// 800ms时,3完成,输出3,任务4进队
// 1000ms时,1完成,输出1
// 1200ms时,4完成,输出4- 实现下面功能
function sum() {
//...
}
console.log(sum(2,3)); // 输出5
console.log(sum(2)(3)); // 输出5- 实现一个函数sum, 运算结果可以满足如下预期结果: sum(1, 2, 3).valueOf(); //6 sum(2, 3)(2).valueOf(); //7 sum(1)(2)(3)(4).valueOf(); //10 sum(2)(4, 1)(2).valueOf(); //9
- redux saga vue 订阅. 发版 双向绑定 观察者模式 设计模式 单例 中介者 高阶组件 reflow repaint 获取 react性能优化 houldComponentUpdate function component
diff key immutable equal redux性能 connect reselect 多线程 多进程 web首屏 3个js文件,300k,是否需要合并为900k的js tcp 并发上线 多域名 dns, tcp tcp keep-alive http2 nw electron - 继承和原型链,浏览器窗口居中,宏任务与微任务,性能优化,深度克隆,算法题(题目非常长,没有记下来)
- 链表环检测
- 聊聊动态规划,红黑树原理
- 自适应search框; input + button 布局;
- 页面性能优化
- vue diff算法,key作用; // 实现 sum 函数 sum(1, 2, 3).valueOf(); //6 sum(2, 3)(2).valueOf(); //7 sum(1)(2)(3)(4).valueOf(); //10 sum(2)(4, 1)(2).valueOf(); //9
- Promise
- Promise.all 返回值
- 实现方式? 入参,返回值,内部实现 Promise.then 如何实现链式调用,返回值是什么? 为什么每次返回新 Promise, 像 jquery 那样直接返回 this 不行吗? [1,2,2,3,2,1] 有以上数组输出字符串 (不考虑缩进): 尽量不用到 domApi
有 A B C D E 5所学校。在一次检查评比中,已知 E 肯定不是第二名或第三名,他们相互进行推测。
A:E一定不是第一名;B: 我校第二名;C:A校最差;D:C不是最好;E: D是第一名。结果这只有实际排名为第一和第二名的学校猜对了,其他学校都猜错了。
请编写一个程序,求出这5所学校的名次。 要求编码清楚,简单。 设计时考虑一定的灵活性,猜测可能更复杂,如:C: A的排名和B的排名的乘积再减去D的排名的结果是7
使用说明
- 先提示不是智力题
- 确保面试者清楚完理解完题意再开始解题
- 先描述清楚解法再开始编码
补充
可以认为已知所有可能的排列情况,直接判断。
如何采集错误?
如何解决 window.onerror 监听跨iframe错误?
页面内一个元素点击后没有执行事件监听函数,原因可能有哪些?如何定位到问题代码?
算法: 回文数字判断,要尽可能高效的算法.
级联组件设计,及很大数据量时的优化;
页面卡顿如何定位,如何优化.
讲讲做过最难/有价值项目?学到什么?有啥问题,如何解决?
业务项目问题,性能问题,问题定位, 会被反复问到
http1-http2、缓存优化、加载链路优化、加载距离优化、响应顺序优化、文件大小优化、打包工具
- 用正则表达式把一个数字字符串分割成千分位形式
var str = '100000000000';
var reg = /(?=(\B\d{3})+$)/g;
console.log(str.replace(reg, ','))
// 方法二
function numFormat(num) {
num = num.toString().split('.');
let arr = num[0].split('').reverse();
let res = [];
for (let i = 0, len = arr.length; i++) {
if (i % 3 === 0 && i !== 0) {
res.push('.')
}
res.push(arr[i]);
}
res.reverse();
if (num[1]) {
res = res.join('').concat('.' + num[1]);
} else {
res = res.join('')
}
return res;
}
// 方法三
var a = 1231242354;
console.log(a.toLocaleString())- 前端优化的思路和方法
- 聊的都是具体的项目
面试形式:网上直接写代码,或者笔试,聊天的形式都有可能;3论技术面+1轮hr面 如果是视频面试,请提前10分钟进入链接,检查好耳机和摄像头 总结:1. 算法只是加分项,https://leetcode-cn.com/explore/featured/card/bytedance/ 建议优先刷这个页面的题目,再刷其它的基础算法题 2. 温馨提醒:头条面试有一定的难度,请一定准备充足在面试 3. 心态很重要,如果一上来考了一个算法题,如果没有回答好,请不要灰心,算法只是加分项,调整心态,把后面的题目回答好,一样可以通过;结束时可以请教面试官算法题的思路
- 面试过程中题目一定要写出多种答案,面试官可能会问每种答案的优缺点,如果面试过程中有回答不上来的题目,千万不要直接回答:不知道!可以请教面试官,如:这个地方是这样吗?有哪些书籍或者资料可以查询?哪怕只有一般的思路,也要讲出来,和面试官一起切磋,面试官的目的不是难倒你,而是想考察你的思路。
- 面试结束时,面试官一般会问:你有什么问题问我的吗?(请不要问一些技术无关的问题,比如:几点下班,团队现在多少人等;这些问题可以留给我或者hr来解答 。最好是根据面试情况,问一下技术方向的话题,比如性能优化你回答的不好,问面试官,如何提高这方面的技术,尽量表现出对技术的追求,面试官会喜欢的)
- 无论你出于什么目的参加面试,请尊重面试机会,初试面试官可能级别不高,主要考察基础知识,请知晓。面试过程中把最好的素养和丰富的知识展现出来,大厂每次面试,都会留档,面试过程愉快和良好,对以后的跳槽也是有好处的。面试的好,谈薪的时候,才有可能谈到更高的薪资
- 上一轮面试没有回答出来的题目,下一轮面试很有可能再次考到,请在等待下一轮面试官的过程中,再想一下最优解(如果2次面试分开面试的,回去一定好好复习上轮面试回答不好的题目,然后做一下拓展),有人选3次都有问同一道题
- 最近很多人选,反复考到性能优化的题目,请好好复习,祝面试顺利!
- 面经请不要外传,不要给自己增加竞争对手,也请理解我的工作,谢谢!