2019年3月-4月前端面试题汇总(持续更新中...)

小编推荐:Fundebug提供JS错误监控、微信小程序错误监控、微信小游戏错误监控,Node.j错误监控和Java错误监控。真的是一个很好用的错误监控费服务,众多大佬公司都在使用。

搜罗了最近看机会的小伙伴遇到的面试问题(3月-4月),不排序不归类,贵在真实

1. [1,2,3].map(parseInt)输出结果

image.png

parseInt() 函数可解析一个字符串,并返回一个整数。
parseInt(string, radix)这里面有两个参数,这里重点讲一下第二个

  • 可选。表示要解析的数字的基数。该值介于 2 ~ 36 之间。
  • 如果省略该参数或其值为 0,则数字将以 10 为基础来解析。如果它以 “0x” 或 “0X” 开头,将以 16 为基数。
  • 如果该参数小于 2 或者大于 36,则 parseInt() 将返回 NaN。

map(function(currentValue, index, arr){}) map里面的函数有三个参数,分别是当前值,当前值的索引值以及当前数组对象

于是上面的表达式就变成了这样

parseInt(1, 0), parseInt(2, 1), parseInt(3, 2) // 1, NaN, NaN

2. 手写一个完整的继承

这个不用多说了,基本是必问的东西,这里会顺延很多东西,原型,原型链,构造函数,以及相应之间的关系,很多很多,反正说越多越好,可以看出知识广度

to继承
new的原理

3. eventLoop事件循环和事件队列

JS的异步机制由事件循环和任务队列构成。JS本身是单线程语言,所谓异步依赖于浏览器或者操作系统等完成。JavaScript主线程拥有一个执行栈以及一个任务队列,主线程会依次执行代码,当遇到函数时,会先将函数入栈,函数运行完毕后再将该函数出栈,直到所有代码执行完毕。

遇到异步操作(例如:setTimeout, AJAX)时,异步操作会由浏览器(OS)执行,浏览器会在这些任务完成后,将事先定义的回调函数推入主线程的任务队列(task queue)中,当主线程的执行栈清空之后会读取task queue中的回调函数,当task queue被读取完毕之后,主线程接着执行,从而进入一个无限的循环,这就是事件循环.

Microtask 与 Macrotask
一个浏览器环境只能拥有一个事件循环(event loop),而一个事件循环可以多个任务队列(Task queue),每个任务都有一个任务源(Task source)。任务队列是一个先进先出的队列.

macrotask(macro-task: script(整体代码), setTimeout, setInterval, setImmediate, I/O, UI rendering) 和 microtask(micro-task: process.nextTick, Promises(这里指浏览器实现的原生 Promise), Object.observe, MutationObserver) 是异步任务的两种分类。在挂起任务时,JS 引擎会将所有任务按照类别分到这两个队列中,首先在 macrotask 的队列(这个队列也被叫做 task queue)中取出第一个任务,执行完毕后取出 microtask 队列中的所有任务顺序执行;之后再取 macrotask 任务,周而复始,直至两个队列的任务都取完。

全部代码(script)是一个macrotask,js先执行一个macrotask,执行过程中遇到(setTimeout, setInterval, setImmediate等)异步操作则创建一个macrotask,遇到(process.nextTick, Promises等)创建一个microtask,这两个queue分别被挂起.执行栈为空时开始处理macrotask,完成后处理microtask,直到该microtask全部执行完,然后继续主线程调用栈.

每一次事件循环(one cycle of the event loop),只处理一个 (macro)task。待该 macrotask 完成后,所有的 microtask 会在同一次循环中处理。处理这些 microtask 时,还可以将更多的 microtask 入队,它们会一一执行,直到整个 microtask 队列处理完。

<script type="text/javascript">
  console.log(1)
  setTimeout(function(){
   console.log(2);
   let promise = new Promise(function(resolve, reject) {
      console.log(6);
      resolve()
   }).then(function(){
    console.log(7)
   });
  },0);
  let promise = new Promise(function(resolve, reject) {
     console.log(3);
     resolve()
  }).then(function(){
   console.log(4)
  }).then(function(){
   console.log(8)
  });
  console.log(5)
 </script>

以上代码的打印顺序 1>3>5>4>8>2>6>7

4. 常见的HTTP状态码都有哪些302,301,304都是什么

简单说301永久重定向,302是临时重定向,304如果客户端发送了一个带条件的 请求且该请求已被允许,而文档的内容(自上次访问以来或者根据请求的条件)并没有改变,则服务器应当返回这个状态码

这里可能会被追问HTTP的缓存机制
状态码
关于缓存

5. https的原理,http 1.1 和 2.0的区别,页面输入url之后做了什么

https的原理,http 1.1 和 2.0的区别
输入url做了什么

6. 网络安全方面,xss攻击是什么,怎么防御,csrf攻击是什么怎么防御

网络安全

7. 数组去重

写越多种方法越好吧
还有一个问题是使用最小的空间和时间复杂度去重

8. ...运算符的原理

对象中的扩展运算符(...)用于取出参数对象中的所有可遍历属性,拷贝到当前对象之中
扩展运算符

9. 一个无限大的有序数组如何找到两个值相加等于9的所有下标

简单写了一下,利用对象的方法,对象的key存储原数组的值,对象的value存储原数组的index

let arr = [1,12,3,14,5,6,7,18,9,0]
function find(arr) {
    let _obj = {}
    let _index = []
    arr.forEach((element, index) => {
        _obj[element] = index
    });
    for (let ele in _obj) {
        if (_obj[9 - parseInt(ele)]) {
            _index.push(_obj[9 - parseInt(ele)])
        }
    }
    return _index
}
console.log(find(arr))

image.png

如果考虑到数组内有重复元素的话,以上方法就不适用了,感谢评论大哥的提醒

10. 关于排序,快速排序,冒泡排序,堆排序等等

这里简单写一个快排

let qsort = (list) => { 
    if( list.length === 0 ){
      return []
    } 
    
    let [x, ...xs] = list
    return [...qsort(xs.filter(u => u <= x)), x, ...qsort(xs.filter(u => u > x))]
}

剩下的百度好了....

11. 跨域

跨域也是经常问的内容比方说jsonp,为什么jsonp要设置随机函数名,优缺点,CROS服务端怎么配置,iframe怎么做到数据互通...说的越多越好吧
跨域

12. this的指向问题

简单讲解一下this的使用场景
这里最后会延伸到call,apply,bind,再向上会让你手动封装一个call或者bind
this
封装一个call
封装一个bind

13. 关于es6的东西

关于es6有很多比方说会问到箭头函数和普通函数的区别,val,let和const的区别,Map,Set的使用,proxy的使用方法,Generator 函数等等,基本常看到的,都看看吧
es6

14. 函数防抖、函数节流

百度一下吧...

15. TCP和UDP的区别

1、TCP面向连接(如打电话要先拨号建立连接);UDP是无连接的,即发送数据之前不需要建立连接

2、TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付

3、TCP面向字节流,实际上是TCP把数据看成一连串无结构的字节流;UDP是面向报文的

UDP没有拥塞控制,因此网络出现拥塞不会使源主机的发送速率降低(对实时应用很有用,如IP电话,实时视频会议等)

4、每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信

5、TCP首部开销20字节;UDP的首部开销小,只有8个字节
6、TCP的逻辑通信信道是全双工的可靠信道,UDP则是不可靠信道

16. 关于vue

vue的双向绑定原理,老生常谈的一个问题
vue-router的原理
vuex的原理
vue的生命周期

基本偏原理向,要求看过源码

17. 关于react

这个不是我的专长,被问到最多的就是和vue的区别,还有项目上当时为什么选型vue,这个仁者见仁智者见智,大家自己想一下怎么回答就好

18. promise

关于promise的问题也很常见,最烦的应该是手写实现一个promise,还有可能面试官会随机出一些场景,让你利用promise解决,再或者会套用到eventloop中,让你判断输出

19. 闭包

最经典的问题,到现在也经常被问到

function a() {
    for(var i = 0 ; i< 10 ; i++) {
        setTimeout(function() {
            console.log(i)
        }, 0)
    }
}

用闭包解决这个问题
闭包

20. 关于二叉树

基本都是使用递归的方法,但是根据问题不一样,解法都不一样,建议没事多刷刷领扣

21. 关于布局的问题

关于布局的问题挺多的,比方说
实现一个品字结构
常见的居中问题
两栏自适应布局
左半边宽度固定右半边撑开的问题

总之就是尽量的多几种,大概使用浮动定位表格flexgrid什么的都可以实现吧...

21. img为什么能设置宽高

img是可替换元素
替换元素就是浏览器根据元素的标签和属性,来决定元素的具体显示内容。
img input select textarea button label 等都是可替换元素

他们区别一般inline元素是:这些元素拥有内在尺寸 内置宽高 他们可以设置width/height属性。他们的性质同设置了display:inline-block的元素一致。

22. git的问题

git add和git commit,分别做了什么,代码都存放在哪里
怎么从git commit 回退到git add的步骤

23 比较有难度的问题

用react 或者 VUE 实现一个简单的 table组件,不要求任何样式。要求在不使用翻页组件的情况下(可以使用滚动条),同时加载 1w 条数据且不会造成前端卡顿。

理论上是在加载之后的数据时,删除掉已经加载过的节点,这是一道机试题,需要完成功能,各位可以想一下具体怎么实现...



作者:广告位招租
链接:https://www.jianshu.com/p/e45ff4a7124f

猜你喜欢

转载自blog.csdn.net/qq_40126542/article/details/89668140