4.16 拼多多前端暑期实习二面(贼热乎被狠狠拷打版)

知道PDD面试官水平贼高,所以抱着学习和接受拷打的心态来面这场二面了,果然不出所料,问的很有深度,除去汗流浃背的感觉以外还是收获到很多东西的,复盘一下。

基本全是场景题,考察设计,并且逐步深入完善。

1.为什么选择前端

2.有尝试过别的岗位吗,比如后端

3.如果想要设置一个定时器,每隔五秒打印一个“hello world”如何实现(回答了setTimeout递归、setInterval、Promiose等方法)

4.为什么setInterval定时可能不准确

5.用递归的方式实现一下(这个写了个最基础的版本,很简单)

function printHello() {

console.log('Hello');

setTimeout(printHello, 5000);

}

printHello();

6.这个setTimeout跟我设置一个setInterval这种方式去定时,在运行了很长一段时间之后会有什么差异(时间无限长,可能一年两年都行)?

复盘了一下,我觉得我回答的有问题,我是有提到setTimeout和setInterval的执行时机有区别的,但是好像在回答这个问题的时候没有get到面试官的意思。

应该是这样的:setTimeout是在你设置的时间之后才去执行要执行的语句(上一次的结束到下一次的开始是你delay的间隔),setInterval是不受你执行语句的耗时影响的(上一次的开始到下一次的开始是你delay的间隔)。所以重点应该是这个:当需要执行的语句耗时比较久的时候,可能会造成setInterval在某个时间点的某一次操作被跳过,大概是下面这个图:

(表述可能不是很清楚,大家有兴趣可以看一下连接:https://blog.51cto.com/xuqin/949052

7.上面这种对精确性的影响在肉眼观察下是什么表现?

8.对上面的代码优化,需要运行一段时间之后关闭定时器,怎么修改?

let timer;

function printHello() {

    console.log('Hello');

    timer = setTimeout(printHello, 5000);

}

setTimeout(() => {

  clearTimeout(timer);

}, 10000)

printHello();

9.上面这种没问题,如果换一种思路,不用全局变量来写呢?(这个就没做出来了,写了一半吧可能,但是有问题,这个问题想了很久)

function printHello(delay) {

  console.log('hello');

  let timer = setTimeout(printHello, 5000);

  function clearTimer() {

    if (timer) {

      clearTimeout(timer);

      console.log("clear");

    }

  }

  setTimeout(clearTimer, delay);

}

printHello(10000);

问题在于,使用局部变量之后,并不能够很好的清除定时器,并且我下来自己调试了一下,clear会打印两次。我觉得就是因为每次递归调用的时候都是独立的函数作用域,clear只能清除掉当前作用域的?希望有好兄弟指点,这个确实看了好久不太会。

10.上面出现了两个问题,第一清除不掉,第二是不够灵活(在执行前就需要输入停止时间),想一下怎么修改。(这一块想了很久没想出来)

11.第二个场景题:给了两个函数①const api = () => {},返回一个promise②const warning = () => {}发出一个警告

现在需要对这两个函数进行封装,不需要改这两个函数,在调用api之后5s内如果没有拿到返回的promise,那就要调用warning。

前面那个题没搞出来就影响后面的思路了,这个一开始想着怎么改这俩函数呢,后来说不用改,就写了下面的

function handler() {

  let timer = setTimeout(() => {

    warning();

  }, 5000)

  api().then(data => {

    clearTimeout(timer);

    console.log('success');

  })

}

12.上面的思路是对的,如果用原生的promise api来写怎么改进?(当时没想出来,说了用Promise.all或Promise.race。。其实应该用resolve、reject最好吧)

复盘了一下大概是这个思路:

function handler() {

  return new Promise((resolve, reject) => {

    api().then(() => {

      clearTimeout(timer);

      resolve();

    }, () => {

      clearTimeout(timer);

      reject()

    });

    let timer = setTimeout(() => {

      reject(warning());

    }, 5000)

  })

}

function api() {

  return new Promise((resolve, reject) => {

    console.log("pending");

    reject();

  })

}

function warning() {

  console.log("warning");

}

handler().catch((err) => {});

上面这种方法我试了一下应该没问题,可惜面试的时候没想出来

13.Promise.all和Promise.race的话哪个更合适,区别是什么?

14.websocket介绍一下,实际情况下什么时候用websocket?

15.假设考虑一下降级方案,比如某些平台不支持websocket,怎么处理?

16.短轮询和长轮询的区别?

17.什么是虚拟DOM

18.对比更新的时候什么时候会只更新属性,什么情况下会销毁重建?

19.除了对比key以外,什么情况下会销毁重建?

其实想一下真的大部分是没有key的dom元素,但之前一直没想过这个问题,自己确实还是思考的太少了

回答到了比较key值,回答到了比较标签。具体如下:

可以看一下这篇博客,很全面:https://juejin.cn/post/7042221455618572296

总的来说基础的方法都能答出来,但是深度不够,感觉是要凉了,继续努力啦

#我的实习求职记录##拼多多##前端##软件开发2024笔面经##24届软开秋招面试经验大赏#
全部评论
放心佬 应该不会凉 我二面感觉回答的还没你好 已经约三面了
1 回复
分享
发布于 04-16 21:34 湖北
第九条那个,因为你每次递归就建了两次工具函数和清理函数。其实把 print 函数再包一层就好了。 function printHello(delay) { let timer = null; // 执行函数包在内部,这样 timer 相对于它又是全局变量了 function fn() { console.log('hello'); timer = setTimeout(fn, 5000); } fn(); setTimeout(() => { if (!timer) return; clearTimeout(timer); console.log('clear'); }, delay); }
1 回复
分享
发布于 04-17 11:23 浙江
滴滴
校招火热招聘中
官网直投
佬,请问下第6条,setTimeout是上一次的结束到下一次的开始是你delay的间隔,这是什么意思呀,是说如果用setTimeout模拟实现setInterval那种场景中,每次setTimeout回调函数中的代码执行完毕才将下一个回调加入执行栈中吗
点赞 回复
分享
发布于 04-16 21:07 湖北

相关推荐

10 21 评论
分享
牛客网
牛客企业服务