没发文的两个礼拜,我面了哔哩哔哩和腾讯

浅聊一下

看了一下,已经有大概两个礼拜没有写过文章了,有点小懒...在这两个礼拜里,我经历了哔哩哔哩的两次面试,和腾讯的一次面试(均在等结果中),因为是大三找实习的情况,所以题目不是很难...上着外教课,闲来无事做做总结...

面试了这么多天,觉得一个人的力量还是太过薄弱,如果你和我一样有向前冲的勇气,欢迎掘友们私聊我交流面经(wechat: LongLBond

B站一面

自我介绍

自我介绍少不了,我在之前的文章中也提到过,要讲明白: 我是谁+从哪里来+我做过什么+有什么成绩+为什么能胜任...

介绍一下项目

先简单介绍了一下我的小demo,主要是做了一个类似朋友圈的一个功能的demo,使用了Vant组件来上传我们的图片,接着说我在另一个项目中对上传文件进行了另外的处理,也就是大文件上传灵机一动的我连夜抛弃Vant的uploader组件 - 掘金 (juejin.cn),掘友们可以去看我的这篇文章,详细介绍了如何实现一个大文件上传...

后续还问到我的文件是以一个什么类型在流通以及我是如何传给后端的等等,在我的文章中都有说到

视差滚动

我在自我介绍的时候提到了哔哩哔哩首页的视差滚动的效果,于是让我说说视差滚动的原理,在这篇文章中我有做一个总结,这里就不再展开了 面了这么多天,该做总结了-CSS篇(三) - 掘金 (juejin.cn)

列表循环

给你一个数组,数组中的数据为树形结构(其实是一个多级列表),要你在页面上渲染出这个多级菜单

当时有点没明白题目的意思,然后说了一下递归的一个思路,接着面试官就说行行行,那我们接着下一道

版本号排序

有这么一些版本号:

js 复制代码
let arr = [
    'v1.0.1-beta.1.1',
    'v1.21.1-cr.2.1',
    'v1.1.01-alpha.1',
    'v1.1.0'
]

其中 cr>beta>alpha,要你实现一个函数,传入两个字符串,返回版本号大的那个

这里主要的难点是如何去处理后面的单词,我们可以使用

js 复制代码
let obj = {
    cr:-1,
    beta:-2,
    alpha:-3
}

当我们要比较单词大小的时候,可以使用以下方式来进行对比

js 复制代码
return obj[cr] > obj[beta]

想明白这点的话其他的步骤就非常简单了...

二叉树的遍历

在反问的时候和面试官聊的比较high,于是面试官又给我出了两个题目

一层一层一次输出一个二叉树的所有结点

二叉树的层序遍历秒了...

然后又问如何不使用递归来进行深度优先遍历

使用栈的方式,有子节点就入栈,没有就出栈...

一面大概就这些内容了,面了一个小时十分钟...

B站二面

大概等了四天,通知我B站二面,我之前还以为G了...

自我介绍

在这里花费了比较久的时间聊了一下我的学习方法,学习历程和学习计划,面试官问的比较详细,比如为什么会想要学习前端(之前搞java)、自己比起其他竞争者的优点等等...

项目

先讲的是我的jwt的登录模块,等我噼里啪啦介绍完以后开始问:

  1. jwt是由什么组成的
  2. jwt解决了什么问题
  3. jwt相对以前的模式有什么优点,或者说以前的session+cookie有什么缺点

我记得我在前面的文章中说过了,这里就不详细展开讲了...

输入url到页面渲染

从DNS域名解析开始说,直到回流重绘...掘友们可以看我这两篇文章面试官: 输入www.url.com以后的全过程 - 掘金 (juejin.cn)从输入4399.com到页面渲染之间的回流和重绘(附字节面试题) - 掘金 (juejin.cn)

介绍完整个流程以后,问:当我们DNS域名解析拿到ip地址以后,是如何找到服务器的?

没回答出来,但是面试官给我做了详细的解释,也是类似DNS域名解析的一个过程,不过多了一个向下查找的过程

http

问了一下http1.1和http2.0的一个区别,大家可以看看这篇文章 ,聊聊http发展史 - 掘金 (juejin.cn)

一些优化(网络层、或者在项目中的优化)

对于网络层我了解的不多,主要聊了一下因为TCP慢启动和队头堵塞造成的一些问题,然后聊了一下使用http3.0,抛弃TCP协议...讲完这个就问了我下一个题目了

服务端渲染

大概聊了一下我的了解,比如vite、cli脚手架在页面上看不见我们div中的结点,会导致SEO搜索不太顺利...

webpack和vite

我webpack使用较少,于是面试官直接跳过

React

我在前面提到,我最近在学习React,面试官问我了解多少

我从Vue和React的一个比较学习说起,讲了一下class组件和函数式组件的响应式、生命周期、组件传值,顺便夹带一点Vue的东西在里面

节流

手写一个节流,防抖和节流-'帕金森'网友的良方 - 掘金 (juejin.cn)

到这里就基本结束了,面试官说你很欧克,但是我们只招一个,面完其他人作横向比较再通知结果/(ㄒoㄒ)/~~

腾讯一面

今天上午面的,面的是腾讯应用宝部门的前端实习生岗位,话说大厂都这么有个性吗?上来自我介绍都木有,直接上了五道题😂,掘友们可以自己做做

第一题

给你一个字符串表达式,请你实现一个基本计算器来计算并返回他的值

第二题

完成搜索页

要求:

  • 实现点击搜索按钮以后,获取输入框最新值,调用searchByKeyword方法获取搜索结果
  • 实现用于展示搜索结果的列表组件,并在搜索区使用
  • 在列表组件中实现分页功能,每页五条数据
html 复制代码
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>搜索页 - Vue</title>
    <script src="https://cdn.yyb.gtimg.com/exam/vue.global.js"></script>
  </head>
  <body>
    <div id="app" class="main-container">
      <div class="search-container">
        <search-input v-model:value="keyword" class="input"></search-input>
        <search-button></search-button>
      </div>
      
      <div class="result-container">
        搜索结果区
      </div>
    </div>
    <script>
      // 按钮组件
      const searchButton = {
        template: `
          <button @click="$emit('search')">
            搜索
          </button>
        `,
      };

      // 输入框组件
      const searchInput = {
        template: `
          <input type="text" :value="value" @input="$emit('update:value', $event.target.value)" class="search-input"/>
        `,
        props: ['value'],
      };

      const { createApp } = Vue;
      createApp({
        data() {
          return {
            keyword: ''
          }
        },
        components: {
          searchButton,
          searchInput,
        },
        methods: {
          // 根据关键字搜索,获得结果列表,为方便考试随机生成结果,可假想为内部调用了搜索接口
          searchByKeyword(keyword) {
            const min = 3;
            const max = 20;
            const resultLength = Math.round((max - min) * Math.random()) + min;
            return Array.from(Array(resultLength).keys()).map(() => ({
              title: this.genRandomString(keyword, 5),
              content: this.genRandomString(keyword, 20),
            }));
          },
          // 根据关键字生成指定长度的随机字符串
          genRandomString(keyword, length) {
            const randomString = Array.from(Array(length).keys()).map(() => String.fromCodePoint(Math.round(Math.random() * 20901) + 19968)).join('');
            const randomIndex = Math.floor(Math.random() * (randomString.length + 1));
            return randomString.slice(0, randomIndex) + keyword + randomString.slice(randomIndex);
          },
          console(e){
            console.log(e);
          }
        },
      }).mount('#app');
    </script>
  </body>
  <style>
    .main-container {
      display: flex;
      align-items:center;
      flex-direction: column;
    }
    .search-container, .result-container {
      display: flex;
      margin-top: 50px;
    }
    .search-input {
      margin-right: 10px;
      width: 300px;
    }
  </style>
</html>

第三题

这是一个简易计算器,有一些bug,请你找出来并且修改:

  • 在浏览器打开出现显示异常并且操作无反馈
  • 解决问题1后,计算器能正常输入了,但是不能正常运算,如输入"3+3="无法计算出结果
  • 解决问题2以后,计算器除0会出现"Infinity"结果,且在该结果之后仍能添加数字进行操作,但是操作结果为Infinity

我给的是已修正版本

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Vue 3 Calculator</title>
  <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/@vue/babel-plugin-jsx@1.2.2/dist/index.min.js"></script>
  <style>
    .calculator {
      max-width: 400px;
      margin: 50px auto;
      border: 1px solid #ccc;
      border-radius: 5px;
      padding: 10px;
    }

    .display {
      padding: 10px;
      margin-bottom: 10px;
      background-color: #f2f2f2;
      text-align: right;
      border: 1px solid #ccc;
      border-radius: 5px;
    }

    .button {
      width: 23%;
      padding: 10px;
      margin: 1%;
      font-size: 1.2em;
      border: 1px solid #ccc;
      border-radius: 5px;
      background-color: #e7e7e7;
      cursor: pointer;
    }

    .button:hover {
      background-color: #d7d7d7;
    }

    .row {
      display: flex;
      justify-content: space-between;
    }
  </style>
</head>
<body>
  <div id="app" class="calculator">
    <div class="display">{{ display }}</div>
    <div class="row">
      <button class="button" @click="clear">C</button>
      <button class="button" @click="sign">±</button>
      <button class="button" @click="percent">%</button>
      <button class="button" @click="setOperator('/')">÷</button>
    </div>
    <div class="row">
      <button class="button" @click="append('7')">7</button>
      <button class="button" @click="append('8')">8</button>
      <button class="button" @click="append('9')">9</button>
      <button class="button" @click="setOperator('*')">x</button>
    </div>
    <div class="row">
      <button class="button" @click="append('4')">4</button>
      <button class="button" @click="append('5')">5</button>
      <button class="button" @click="append('6')">6</button>
      <button class="button" @click="setOperator('-')">-</button>
    </div>
    <div class="row">
      <button class="button" @click="append('1')">1</button>
      <button class="button" @click="append('2')">2</button>
      <button class="button" @click="append('3')">3</button>
      <button class="button" @click="setOperator('+')">+</button>
    </div>
    <div class="row">
      <button class="button" @click="append('0')">0</button>
      <button class="button" @click="append('.')">.</button>
      <button class="button" style="flex: 2;" @click="calculate">=</button>
    </div>
  </div>

<script>
  const { createApp, ref, computed } = Vue;
  createApp({
    setup() {
      const current = ref('');
      const previous = ref(null);
      const operator = ref(null);
      const operatorClicked = ref(false);

      const display = computed(() => current.value || '0');

      function clear() {
        current.value = '';
      }

      function sign() {
        current.value = current.value.charAt(0) === '-' ? current.value.slice(1) : `-${current.value}`;
      }

      function percent() {
        current.value = `${parseFloat(current.value) / 100}`;
      }

      function append(number) {
        if (operatorClicked.value) {
          current.value = '';
          operatorClicked.value = false;
        }
        console.log(current.value,number);
        current.value = current.value === Infinity?`${number}`:`${current.value}${number}`;
      }

      function setPrevious() {
        previous.value = current.value;
        operatorClicked.value = true;
      }

      function calculate() {
        let result;
        const currentNumber = parseFloat(current.value);
        const previousNumber = parseFloat(previous.value);

        if (isNaN(previousNumber) || isNaN(currentNumber)) {
          return;
        }

        switch (operator.value) {
          case '+':
            result = previousNumber + currentNumber;
            break
          case '-':
            result = previousNumber - currentNumber;
            break
          case '*':
            result = previousNumber * currentNumber;
            break
          case '/':
            result = previousNumber / currentNumber;
            break
          default:
            return;
        }

        current.value = result;
        operator.value = null;
        previous.value = null;
      }

      function setOperator(op) {
        if (current.value === '') return;
        if (previous.value !== null) {
          calculate();
        } else {
          setPrevious();
        }

        operator.value = op;
        operatorClicked.value = true;
      }

      return {
        display,
        clear,
        sign,
        percent,
        append,
        calculate,
        setOperator
      };
    }
  }).mount('#app');
</script>
</body>
</html>

第四题

下面代码段功能如下,点击查询按钮,从后台服务器接口和URL参数中获取指定字段的数据显示到界面上,请从代码风格规范、实现逻辑、方案设计、性能、安全等不同方面考虑、列出该代码存在的问题,并简单给出解决方案

html 复制代码
<button id="btn1" onclick="clickFunction">查询</button>
<p id="text1"></p>
<script>
var DOC=document;
var clickFunction=function() {
  var BTN=DOC.getElementById('#btn1');
  var TEXT=DOC.getElementById('#text1')

  var getUrlParam=function(k){
      var url=window.location.href;
      var params=url.split("&")
      for(var i=0;i<params.length;i++){
          var param = params[i].split("=");
          if(k=param[0]){
            return param[1]
          }
      }
  }
  getDataFromServer(function(d){
      var obj=JSON.parse(d);
      BTN.innerHTML="已查询";
      TEXT.innerHTML=obj.data[0].text+" "+getUrlParam("text")
  });
}
</script>

第五题

赛马:25匹马,5个赛道,每次只能同时有5匹马跑,在无法计时的前提下,最少比赛几次选出最快的前三名的马?

一个小时的做题时间,我写完了两道,还有十分钟,连忙和面试官说时间不太够,我来给您讲讲我的思路,讲完以后面试官又问我对其他没写的题的思路,然后又讲了一会,面试时长一个半小时,面的我饥肠辘辘...

结尾

在金三银四的尾声,大家好好把握机会...

相关推荐
知否&知否3 分钟前
Kafka面试夺命连环30问(一)
分布式·面试·kafka
小牛itbull17 分钟前
ReactPress:深入解析技术方案设计与源码
javascript·react.js·reactpress
alexbai!18 分钟前
el-date-picker picker-options属性中disabledDate设置时间的禁用和启用,并且支持到时分秒的禁用和启用
javascript·vue.js·elementui
秃头女孩y25 分钟前
【React】条件渲染——逻辑与&&运算符
前端·react.js·前端框架
学无止境鸭1 小时前
vue读取本地excel文件并渲染到列表页面
前端·javascript·vue.js
不cong明的亚子1 小时前
在vue中,完成@wangeditor/editor组件的大数据量加载,解决卡顿
前端·vue.js
百晓生说测试1 小时前
15:00面试,15:08就出来了,问的问题有点变态。。。
自动化测试·软件测试·功能测试·程序人生·面试·职场和发展
原机小子1 小时前
Spring Boot编程训练系统:前端与后端集成
前端·spring boot·后端
小满zs1 小时前
React第十五章(useEffect)
前端·react.js
爱米的前端小笔记1 小时前
前端学习八股资料CSS(一)
前端·css·经验分享·学习·职场和发展