快手前端暑期实习一面

一、前言

先说一下结果吧——一面秒挂。

这个是我暑期实习的第一次面试,为啥过了这么久才发?当然是我的面试都结束了,现在终于可以抱着轻松的心态复盘一下了!!

我个人感觉自己确实是有很多的不足的地方,对于 Promise 的相关知识以及算法的部分掌握的实在是太不牢固了。在这里先记录一下吧。

二、题目列表

  1. 上来老三样,自我介绍+询问实习时间地点要求+询问我的项目经历。由于我在简历里面写了挺多竞赛相关的项目,让他误以为我是一个超级全能的全干工程师,然后就让我挑一个比较有难度的项目来讲。 于是我就挑了一个目前正在参与的开源项目:Create-Neat,并详细讲了一下我当初负责的 TemplateAPI 的设计。这个就相当于是偏纯技术的一个项目,因此和面试官聊的还比较多。 这个项目聊完了之后,又跟我聊了一个我在目前公司负责的 Markdown 渲染器的设计与实现,这个也聊的比较久。

  2. 代码题:JavaScript 事件循环,给我一段代码,让我判断 console.log() 打印输出的顺序。这个题目相对比较经典+我没有录屏这边就不写原题了。

  3. 代码题:实现一个 sleep()函数,使用 async/await ,可以向其中传入一个参数 dalay 用于控制其函数内部 console.log() 触发的延迟时间。具体代码如下:

    const func = async () => {
      await sleep(3);
      console.log("Hello World");
    };
    
    const sleep = (delay) => {
      // 编写函数体
    };
    

    这道题实际上比较简单,就是利用了 Promise 的机制,我们可以把 await 语句下面的代码看成 Promise.then() 回调内部的代码,我们只要在 sleep 函数里面返回一个 Promise ,然后在 delay 秒之后把其状态变为 fulfilled 就可以了。

    解法代码如下:

    const func = async () => {
      await sleep(3);
      console.log("Hello World");
    };
    
    const sleep = (delay) => {
      return new Promise((resolve) => {
        setTimeout(resolve, delay * 1000);
      });
    };
    
  4. 代码题:第三题的进阶版。

    首先有一个已经写好的接口: getUserInfo ,它接受一个参数 userId ,在内部通过 axios 发起请求,返回一个 Promise 对象。

    目前有一个新的需求:实现一个新的函数用来二次封装这个 getUserInfo ,同样也返回一个 Promise 对象,如果正常返回成功/失败,那么就正常的触发成功/失败的回调;如果请求时长超过了10s,那么就需要自动触发报错,不管原来的这个接口接下来是否请求成功/失败。

    当时这道题有点懵,想了半天没有想出来,因为之前这种超时报错的处理基本100%全都是交给 axios 的响应拦截器做的处理,还没有自己手动实现过。

    接下来给一下我事后实现的一个 TS 版本的源码,给大家参考一下:

    import axios from 'axios';
    
    function getUserInfo(userId: string): Promise<any> {
        return axios.get(`/api/user/${userId}`);
    }
    
    function getUserInfoWithTimeout(userId: string): Promise<any> {
        return new Promise((resolve, reject) => {
            const timeout = setTimeout(() => {
                reject(new Error('请求超时'));
            }, 10000); // 设置10秒超时
    
            getUserInfo(userId)
                .then((response) => {
                    clearTimeout(timeout); // 清除超时计时器
                    resolve(response.data);
                })
                .catch((error) => {
                    clearTimeout(timeout); // 清除超时计时器
                    reject(error);
                });
        });
    }
    
    // 示例用法
    getUserInfoWithTimeout('123')
        .then((data) => {
            console.log('成功:', data);
        })
        .catch((error) => {
            console.error('失败:', error.message);
        });
    
  5. 代码题:判断 this 作用域。

    具体题目如下:

    var num = 123;
    
    var obj = {
      num: 456,
      getNum: function () {
        var num = 789;
        return this.num;
      },
    };
    
    console.log(obj.getNum());
    

    让我判断最终打印输出的结果为多少。

    实际上, getNum 方法被调用时,会返回 this.num。在这个上下文中,this 指向了 obj 对象,因此 this.num 实际上是指向了 obj 对象中的 num 属性。根据 JavaScript 的作用域链规则,如果当前作用域中找不到某个变量,就会向外层作用域查找,直到找到或者查找到最外层作用域为止。

    getNum 方法内部,虽然有一个同名的 num 变量(var num = 789;),但在返回语句 return this.num; 中,this.num 实际上是指向了 obj 对象中的 num 属性,而不是方法内部的 num 变量。因此,最终打印输出的结果是 456

  6. 代码题:大数相加。简单来说,实现一个函数,内部可以传递两个无限长的字符串,而这两个字符串全都是由数字字符组成,在这个函数中实现这两个字符串数字的相加,最终返回的也是一个由数字组成的字符串。当时由于前两题发挥不太好导致心情崩溃了,结果没有写出来。

    这里给一下之后写的一个解法:

    function addStrings(num1: string, num2: string): string {
        let carry = 0; // 进位
        let result = ''; // 结果字符串
        let i = num1.length - 1;
        let j = num2.length - 1;
    
        // 从个位开始逐位相加
        while (i >= 0 || j >= 0 || carry > 0) {
            const digit1 = i >= 0 ? parseInt(num1[i]) : 0;
            const digit2 = j >= 0 ? parseInt(num2[j]) : 0;
            const sum = digit1 + digit2 + carry;
    
            // 计算当前位的结果,并更新进位
            const digitSum = sum % 10;
            carry = Math.floor(sum / 10);
    
            // 将当前位的结果添加到结果字符串的开头
            result = digitSum.toString() + result;
    
            // 更新索引
            i--;
            j--;
        }
    
        return result;
    }
    
  7. 反问阶段。

三、结语

我是第一次遇见八股一个都不问,项目问完之后直接开始拷打算法的面试。我之前辛辛苦苦准备了这么久的八股一个都没用上,还偏偏是考我最薄弱的算法部分,实在是令人忍俊不禁。

嘛,不过这也基本确定了我本人的算法还是不太行,得好好加油,平时除了写业务之外,得把刷算法也当成家常便饭才行。

全部评论
大佬面完多长时间有结果的
1 回复 分享
发布于 2024-05-17 14:37 黑龙江

相关推荐

!!小厂线下面试(。。录音录了一半剩下的没录上&nbsp;不过基础八股问的不多&nbsp;基本都是场景题?&nbsp;本菜比回答的如坐针毡&nbsp;。)介绍&nbsp;之前是有实习吗&nbsp;做的什么业务&nbsp;ToC吗&nbsp;介绍一下考研了吗&nbsp;为什么做前端讲一下项目&nbsp;你是怎么做这个菜单权限的&nbsp;SSE是怎么实现的你用过keep&nbsp;alive吗实习是做过小程序开发吗&nbsp;用的是自研的还是微信自带的微信的小程序的缓存为什么存在前端不存在后端??让你设计一个表单你现在给我说一下怎么写设计一个按钮实现禁用功能怎么实现nexttick是干什么的组件之间怎么通信watch监听&nbsp;setTimeout&nbsp;触发器和延时器作用.....剩下的忘了点评:项目够用回去多练练技术!!某外包中厂线上面+小厂线上面(两家问的其实差不多&nbsp;也没录音&nbsp;但是基本纯八股项目没问什么深的&nbsp;看起来是面试官现搜的ai问题&nbsp;但是小厂是我第一次面&nbsp;有点紧张&nbsp;面试官点评:建议你联系一下表达方式&nbsp;说完之后她笑了呜呜&nbsp;中厂点评:要熟练掌握开发中常用知识&nbsp;比如promise)介绍自己&nbsp;介绍项目&nbsp;亮点啊困难啊&nbsp;之类的let&nbsp;const&nbsp;varcss居中方法&nbsp;响应式布局h4&nbsp;h5的区别&nbsp;(一个字没答出来&nbsp;就记得多了标签)普通函数箭头函数区别&nbsp;(只打出来this&nbsp;原型&nbsp;面试官提示argument)Promise&nbsp;async/await&nbsp;(自认为回答的还行&nbsp;但是面试官结束说我这块没掌握好&nbsp;可能是发现是纯背八股速成。)数组常用方法&nbsp;你的项目中怎么用的&nbsp;(不会说)讲讲响应式原理&nbsp;vue2&nbsp;3&nbsp;区别(没答好computed&nbsp;watch&nbsp;常用于什么场景生命周期有哪些git全流程是什么&nbsp;提交代码第一步是什么&nbsp;(&nbsp;这个可能是我中厂被挂最大原因&nbsp;因为之前实习用过&nbsp;我简历上就写了&nbsp;然而我完全忘了也没准备。。完全是胡乱猜&nbsp;我说一个面试官就说不对&nbsp;,,一直到我猜到git&nbsp;add为止)。。!!小厂线下面(可能实在缺人&nbsp;给我招进来了&nbsp;呜呜&nbsp;但是工资很低&nbsp;可转正&nbsp;转正工作也低&nbsp;公司居然还是js多&nbsp;因为都是老项目&nbsp;vue2&nbsp;3&nbsp;比较少&nbsp;实在没办法了&nbsp;但是还是感谢给我这种菜比一个机会&nbsp;双休不加班&nbsp;环境好&nbsp;面试我的是40左右的姐)介绍项目&nbsp;你负责哪一块你自己重新布局能力如何&nbsp;自己写页面&nbsp;一般布局有哪些盒模型(我听错了&nbsp;没想起来是box这个盒)Css新特性&nbsp;content&nbsp;动画(动画我没有涉及过)水平垂直局中&nbsp;选择器优先级&nbsp;数组去重(只记得map)ES6新特性有哪些VUE&nbsp;2&nbsp;3区别&nbsp;生命周期跳转路由有什么方式&nbsp;传参
查看30道真题和解析
点赞 评论 收藏
分享
评论
9
19
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务