前言

最近刚面试了一家互联网公司的中级前端开发工程师。好家伙,一面上来直接开始手写题,考算法什么的。

特此记录一下考题。看能不能帮助到大家,有些题忘记了,记录个大概吧。

目录

--手写题--

1.let,var区别

2. event loop执行结果

3. 算法题

4. promise考察

5. 算法题,判断有效括号

--技术题--

6. 说一下diff算法

7. 输入url到页面显示的过程

9. webpack工作过程,以及使用过webpack的哪些东西

最后


1.let,var区别

for(let i = 0; i<5; i++) {

setTimeout(() => console.log(i),0)

}

问执行结果,以及let换成var的执行结果

我的回答:

我当时一看就是靠let块级作用域的,我一般for循环的话也喜欢用let,所以基本是答对了,但是却输错了循环次数,无语子。。。

正确答案:

let: 0 1 2 3 4

var: 5 5 5 5 5

解析:

var声明的是全局变量,然后的话setTimeout是异步函数,等循环完i变成了5,所以输出了5个5;

而let是块级的,每次循环有自己的局部作用域,因此输出0-4

2. event loop执行结果

题记不清了,大概是下面这两种,我大概写了一下

setTimeout(function() {console.log('1')new Promise(function() {console.log('2')}).then(console.log('3'))
},0)new Promise(function() {console.log('4')
}).then(console.log('5')
)setTimeout(function() {new Promise(function() {console.log('6')}).then(console.log('7'))
},0)

正确答案:

script start  2  3 script end  1   4

setTimeout(function() {console.log('1')new Promise(function() {console.log('2')}).then(console.log('3'))
},0)new Promise(function() {console.log('4')
}).then(console.log('5')
)setTimeout(function() {new Promise(function() {console.log('6')})
},0)

正确答案:

4  5  1  2  3  6

我的回答:

第一个回答挺顺利的,然后第二个卡住了,当时有点蒙了,第一次写结果想成了执行完所有宏任务再去执行微任务队列。后来反应过来了,是执行一个宏任务,然后执行所有微任务。

所以当时就卡在了最后是1263  还是 1236  ,还好最后改正了

3. 算法题

有一个函数add:

执行  add(1)(1+2+3+4)   ,结果为11

执行  add(2)(1+2+3+4)   ,结果为12

执行  add(2)(1+2+3+4+1+1)   ,结果为14

请写出add这个函数

我的回答:

首先的话,我先去观察这个函数的特点。

观察片刻,发现是第二次输入的值加上第一次输入的值

然后的话,该函数能连续执行,肯定add函数内部要返回一个方法

所以我的答案:

第一次写出来:

function add(num) {let result return function(num,...rest){let result = rest.reduce((a,b) => a+b)+nreturn result}
}

第一次的答案我按照我的思路,后面的值加前面的值,所以后面值接收用...rest剩余参数,因为第二次传参数量不一定嘛,但是面试官提示,第二次调用没有传num。所以我才反应过来,第二次只是传第二次的值。

然后我立马想到用arguments代替rest参数,然后的话,第一个传入的数字在第一层函数里声明下,这要就构成了闭包,第二层函数可以直接用了~ Nice

function add(num) {let n = numreturn function(){let arr = Array.from(arguments)let result = arr.reduce((a,b) => a+b)+nreturn result}
}

4. promise考察

var a = Promise.resolve()
var b = Promise.resolve('foo')
var c = Promise.resolve(() => null)
var d = Promise.resolve(() => undefined)
var e = Promise.resolve(() => 'foo')
var f = Promise.resolve(() => Promise.resolve('foo'))
var g = Promise.resolve(() => Promise.reject('err'))
var h = Promise.resolve(() => new Promise(() => {Error('err')
}))
console.log(a,b,c,d,e,f,g,h)

请写出a,b,c,d,e,f,g,h的值

我的回答:

我看到这题,直接一脸懵逼,瞎说了一通,一半答错了

正确答案:
Promise {<fulfilled>: undefined}

Promise {<fulfilled>: 'foo'}

Promise {<fulfilled>: f}

Promise {<fulfilled>: f}

Promise {<fulfilled>: f}

Promise {<fulfilled>: f}

Promise {<fulfilled>: f}

解析:

MDN详解

Promise.resolve()方法返回一个 Promise使用给定值解析的对象。如果该值是一个承诺,则返回该承诺;如果值是一个 thenable(即有一个 "then" method),返回的 promise 将“跟随”那个 thenable,采用它的最终状态;否则返回的 Promise 将用该值实现。这个函数将嵌套的类似 promise 的对象层(例如,解析为解析为某事物的 promise)扁平化为单层。

有时需要将现有对象转换为promise对象,Promise.resolve()方法就起到了这个作用。

Promise.resolve('foo')

等价于

new Promise(resolve => resolve('foo'))

Promise.resolve()共有四种参数

第一种:不带任何参数

setTimeout(function () {console.log('three');
}, 0);Promise.resolve().then(function () {console.log('two');
});console.log('one');
// one two three

相当于一个resolve状态的promise对象

第二种:普通变量或者普通对象

const p = Promise.resolve('Hello');p.then(function (s){console.log(s)
});
// Hello

相当于resolve状态的promise对象

第三种:参数是一个 Promise 实例

如果参数是 Promise 实例,那么Promise.resolve将不做任何修改、原封不动地返回这个实例。

第四种:参数是一个thenable对象

//thenable对象指的是具有then方法的对象,比如下面这个对象let thenable = {then: function(resolve, reject) {resolve(42);}
};
//Promise.resolve方法会将这个对象转为 Promise 对象,然后就立即执行thenable对象的then方法。let thenable = {then: function(resolve, reject) {resolve(42);}
};let p1 = Promise.resolve(thenable);
p1.then(function(value) {console.log(value);  // 42
});
//thenable对象的then方法执行后,对象p1的状态就变为resolved,
//从而立即执行最后那个then方法指定的回调函数,输出 42

5. 算法题,判断有效括号

写一个方法,输入一个只有括号的字符串,(){}[]      [(),{}]     {[()]} 这些都会返回true

([)]   (})  这种都会返回false

我的回答:

我一看这个题,心想:好家伙,我在力扣上刷到过,稳了!再一想,忘了怎么做了。。。焯!

第一次作答:

我的思路是先判断是不是空字符串和偶数,排除特殊情况。

然后遍历这个字符串,对元素的六种情况  ( , ),{ , } , [ , ] ,分别做判断,比如如果是左小括号,它的右侧必须是右小括号。

but!面试官提示,只能判断  (){}[]  这种情况,那 {[()]}这种怎么办呢?

第二次作答:

我反手想到另一种解决办法,双指针,遍历两层字符串,第一层正向,第二层反向,然后比如第一层如果是左小括号,第二层就必须是右小括号。

but!面试官提示,这只能判断{[()]}这种情况了

第三次作答:

焯!!什么鬼,我蒙圈了。突然我灵机一动,想到挨个去找到匹配成功的括号,然后将匹配成功的括号从字符串中删除,最后看这个字符串剩下什么。

就在这时,面试官也提示我,可以想想换一种数据结构,考虑一下用栈。其实我的想法基本也是和栈差不离,只不过不会。。。

正确答案:

var isValid = function(s) {const n = s.length;if (n % 2 === 1) {return false;}const pairs = new Map([[')', '('],[']', '['],['}', '{']]);const stk = [];for (let ch of s){if (pairs.has(ch)) {if (!stk.length || stk[stk.length - 1] !== pairs.get(ch)) {return false;}stk.pop();} else {stk.push(ch);}};return !stk.length;
};

到这里,手写题就结束了,然后问了一些技术题:

6. 说一下diff算法

我的回答:

1. vue的diff算法是从两侧向中间节点去对比的。并且使用了双指针,边对比边更新。而react的diff算法是从左到右去对比的,对比时把改变的节点生成patch树,对比完才去打补丁。

2. diff算法一般要指定节点key,也就是唯一值,这样才能在节点进行删除或者排序操作后,保证diff对比的准确性。

3. vue3的diff算法相比vue2做了优化,它会在编译阶段判断每个节点是否是动态节点,通过看节点上有没有像v-on,:class等这种符号,然后收集动态节点生成block tree,在dom发生变化时,只会去比对block tree。因为vue3对静态节点做了静态提升,所以静态节点只会渲染一次。

4. vue3的diff算法还再用了patchFlag标记动态节点,更高效的判断修改了哪些东西。

7. 输入url到页面显示的过程

1. url没输入完成时,查找书签,历史记录等,可以智能提示,补全地址

2. 因为输入的是域名,所以要先解析出域名映射的ip地址。所以要先进行DNS解析,首先去看浏览器缓存有没有,没有的话请求本地DNS服务器,也就是本地运营商,还没有再请求根DNS服务器,然后再顶级域名服务器,最后权威域名服务器。知道找到为止。

3. 解析出ip地址后,进行tcp连接

4. 浏览器网络进程发起请求,三次握手请求数据,拿到数据后,四次挥手,释放tcp连接

5. 浏览器浏览器进程准备开始渲染,准备好后ipc进程通信通知渲染进程开始渲染

6. 渲染进程开始渲染,先解析html,生成dom树,然后解析css规则,生成css树,然后结合生成render树,这时的render树会去掉head标签以及dispaly:none的节点,所以和dom树结构不完全相同。最后布局,绘制。

8. webpack工作过程,以及使用过webpack的哪些东西

工作过程的话,我可能当时没理解对,说了点ast抽象语法树的东西。实际应该是说这个:

  • compile 开始编译
  • make 从入口点分析模块及其依赖的模块,创建这些模块对象
  • build-module 构建模块
  • after-compile 完成构建
  • seal 封装构建结果
  • emit 把各个chunk输出到结果文件
  • after-emit 完成输出

然后使用我说的这些:

1. 配置svg啥的loader

2. 开sourcemap

3. 开gzip压缩

4. 配置跨域

5. 分包

6. 安装插件

7. 第三方库按需加载

最后

如果哪里有不对或者补充的,欢迎大家指正或补充!

【面试】中级前端面试题记录及答案总结相关推荐

  1. 【面试真题】腾讯2018秋招前端正式试题(含答案)

    参考答案关注公众号,回复"腾讯答案"获取 01 不定向多选 1.    往下面的5阶B树中插入关键吗80后,该B树第二层的节点数为( ). A.   6 B.   7 C.   8 ...

  2. 前端面试题记录(大环境不太友好的2022篇)

    前言 不出去体会一下就想不到所谓的别人口中的 "大环境不太好" 的具体情况 结果就是:相比上一次确实难多了,之前没投几家最后就确定了,这次真的是达到了海投的地步 (还是准备不够充分 ...

  3. 2019前端面试题记录(杂文)

    session和redis 目前session直接是js变量,放到nodejs的进程内存中,存在问题 问题一:进程内存有限,访问量过大,内存爆增怎么办?(有可能进程崩溃) 问题二:正式上线后运行的是多 ...

  4. 一年内经验前端面试题记录

    1. JavaScript 1. JavaScript文件在什么情况下会放在html哪个位置 https://zhuanlan.zhihu.com/p/... 对于必须要在DOM加载之前运行的Java ...

  5. 腾讯web前端笔试题及个人答案

    每道题都有答案,大多数答案亲测正确. 简答题 1.js中"5"+4=? 答案:54 2.js中void(0)=? 答案:undefined 3.js中NaN*4=? 答案:NaN ...

  6. 前端笔试题记录【1】 + JS内置对象复习

    目录 一.海康威视 二.微众银行 三.长沙兴盛优选 四.复习JS的内置对象 1.Math对象 2.Date对象 Array对象 String对象 一.海康威视 单选题 多选题 两道编程题 1.冒泡排序 ...

  7. 前端笔试题(附答案)

    1.以下哪条语句会产生运行错误:(a) A.var obj = ();//语法错误 B.var obj = [];//创建数组 C.var obj = {};//创建对象 D.var obj = // ...

  8. 一些知识点的整理以及面试题记录

    每日任务 2018年3月2日 -Service-和-IntentService-的区别 链接 Service Service是长期运行在后台的应用程序组件. Service不是一个单独的进程,它和应用 ...

  9. 2021年茶艺师(中级)考试报名及茶艺师(中级)免费试题

    题库来源:安全生产模拟考试一点通公众号小程序 安全生产模拟考试一点通:茶艺师(中级)考试报名考前必练!安全生产模拟考试一点通每个月更新茶艺师(中级)免费试题题目及答案!多做几遍,其实通过茶艺师(中级) ...

最新文章

  1. Linux 下hosts文件
  2. svg 转图标字体制作
  3. IT自动化:自动化的网络管理变得很重要
  4. 剑指offer--51.表示数值的字符串
  5. (轉載) 大學就學貸款 可分12年還 (News)
  6. x264_sps_init
  7. oracle 如何形成死锁,Oracle数据表中的死锁情况解决方法
  8. MySQL企业级主从复制
  9. python 装饰器应用
  10. Tp5.0 PHPMailer邮件发送
  11. C语言中callback回调函数,C++回调函数(callback)的使用
  12. android 插桩工具,自插桩测试示例  |  Android 开源项目  |  Android Open Source Project...
  13. js实现网页在线聊天功能(一)
  14. linux firefox体验,Firefox插件 让你在桌面浏览器体验Firefox OS(附安装教程)
  15. POS机电销常见话术_其中有危害吗
  16. 水仙花数的判断(JAVA)
  17. 图像分割——Multi-Scale and Pyramid Network Based Models( PSPN)理解和代码分析
  18. 携手京东发布锐龙品牌整机,AMD这次会赶超英特尔吗
  19. 6. 查询选修了课程名为“信息系统”的学生学号和姓名
  20. 解读《电子劳动合同订立指引》,规范签订电子劳动合同

热门文章

  1. android 光晕效果,【转】七、android图片特效处理之光晕效果
  2. MP3 和 音频播放器
  3. Oracle 18c新特性:多租户舰队 CDB Fleet
  4. C++ 并行编程(thread)
  5. windows下bat批处理实现守护多个进程
  6. mysql union语法,mysql中的union用法
  7. Opensim教程3-缩放,逆运动学,逆动力学
  8. 奈奎斯特 带宽 码元 比特
  9. 上亿条个人信息被泄露 源头竟是房产商
  10. 百度蜘蛛ip段大全分析,百度每个ip都什么意思