字节无缘后,迎来了滴滴二面,好家伙鏖战三小时!

前言

先说明下自身成分,双非二本,属于 debuff 拉满了,在之前的一个月中也面试了许多的中厂,自认为经验准备充分,于是4月2号去面试了字节的懂车帝实习岗位(这里后续会写一篇),第一次面试这种顶级大厂,结果还是实力不济,被丢进鱼塘......

来不及为死去的字节哀悼了,接下来就重整信心找了学长帮忙去投滴滴,流程很快,一面下来受益颇多,发现了自己的很多不足,项目经验不足,节后就约了二面,好家伙直接部门组长来面我,提前打好预防针说我们面试时间可能会长很多,最后手写的时候一边被怼一遍擦冷汗,手抖个不停,写到后面我连函数声明都忘了怎么写,脑子一团浆糊,面完之后才发现已经面试了三小时,手写就花了2个小时,中途还停了一下跟面试官说先冷静下,面试官虽然会怼我的错误之处,但是也一直在引导我去如何实现,也通过这次面试明白了自己是真的很需要打磨自己,把基础抓牢固,也感谢面试官一直陪我走完整个流程......

一、由于篇幅和记忆问题这里就只出列举这些,uu感兴趣可以自行查阅

经典项目拷打环节

jwt与token

css定位

js有哪些原生获取dom结构的方法

js常见方法

js数据类型以及判断方法

js宏任务和微任务有哪些

输入url的渲染过程

http和https

知道哪些加密方法(对称加密和非对称加密)

说说vue框架帮你做了什么事情

  1. 声明式渲染: 通过在模板中使用指令,可以将数据自动渲染到 DOM 中,而无需手动操作 DOM。
  2. 组件化开发: 将应用拆分为独立的可重用组件,这种组件化开发方式使得代码易于维护和复用。
  3. 响应式数据: Vue 使用响应式系统来跟踪所有数据的变化,并在数据变化时自动更新 DOM。
  4. 单文件组件: Vue 支持单文件组件,即将组件的模板、逻辑和样式都写在一个文件中。
  5. 指令和过滤器: 例如,v-bind 指令用于绑定属性,v-on 指令用于监听事件。
  6. 路由管理: Vue Router,用于管理单页面应用的路由。
  7. 状态管理: Vuex 用于管理应用的状态,使得状态的管理更加简单和可预测。

那cli帮你做了什么事情?vite呢?

Vue CLI: Vue CLI 是一个官方提供的 Vue.js 项目脚手架工具,它帮助开发者快速搭建基于 Vue.js 的项目,并提供了一系列的命令和插件,简化了项目的配置和管理。

  1. 项目初始化: 通过 vue create 命令可以快速初始化一个新的 Vue 项目。

  2. 项目管理: 例如,vue serve 用于在开发环境中快速启动一个开发服务器,vue build 用于构建生产环境的代码,vue deploy 用于部署项目到不同的平台等。

  3. 插件系统: 例如可以安装 Vuex、Vue Router 等官方插件,也可以安装第三方插件。

  4. 配置扩展: 通过 vue.config.js 文件来对项目进行配置扩展,例如配置 webpack、babel 等构建工具。

Vite: Vite 提供更快的开发体验和更佳的构建性能。相比传统的基于 webpack 或者 Rollup 的构建工具,Vite 使用了一种全新的构建方式,称为原生 ES 模块动态引入

  1. 快速开发: Vite 利用原生 ES 模块的特性,实现了按需编译和即时热更新。

  2. 支持多种框架: 虽然 Vite 不仅仅支持 Vue.js,还支持 React、Preact、Lit Element 等多种框架。

  3. 插件化配置: 可以通过安装插件来扩展 Vite 的功能。

  4. 优化构建性能: Vite 在构建过程中利用了现代浏览器的原生 ES 模块支持,实现了快速的构建和加载速度。

真记不得还有哪些了......

二、手写一个轮播图

面试官一开始问我知道哪些前端组件库我说用过 elementplusvant ,用过 vant ?面试官一下来劲了,那你写一个轮播图吧!

刚刚听到这个手写我不知道是该庆幸还是悲哀,庆幸的是这个组件可太熟悉了,悲哀是真的没想到会让手写这玩意,没办法了,只能硬着头皮上了......

一开始的时候是处于一个半懵逼状态,我只知道平常我们调用轮播图组件的时候都是给 Swiper 标签设置属性,来实现各种功能,所以一开始也脑抽这么写了......

Vant 组件调用实例:

我写的......

js 复制代码
<template>
    <button @click="prev">上一张</button>
    <button @click="next">下一张</button>
    <div>
        <div :list="list" :auto="true" :time="1000" v-for="(item, index) in props.list" :key="index">
            <img :src="item" alt="" />
        </div>
        <div class="swiper"></div>
    </div>
</template>

当时也是脑抽,这么一写直接被面试官怒怼,直接说你先把父组件调用写完再谈轮播图......

这时候我抽风的脑子才醒悟过来,我是要封装一个组件而不是调用一个组件......

后来在面试官的帮助下才把轮播图写了一个大概......

被怼:

  1. 你总算明白了是要封装一个组件而不是调用一个组件(我在这卡了好久,我太菜了......)
  2. 你怎么把defineProps写成了defineprops,常见api你都记不住?(这里真不怪我,我写的时候电脑抽风,没有提示,全程代码摁打的)
  3. 调用watch你不传参数?(后面急速改watchEffect
  4. 你再看看你定时器取消是不是有问题?(继续改......)
  5. 变量命名都出错?(......)

没被怼的:

  1. 思路通了以后写的挺快,就是变量命名不规范
  2. 相加求余这点蛮重要
  3. 绑定stylex轴平移还不错

就这么一边冒冷汗,手抖个不停地写了一个小时🐭🐭太菜了

源码:

js 复制代码
// 轮播图组件 ./components/Swiper.vue
<template>
    <button @click="prev">上一张</button>
    <button @click="next">下一张</button>
    <div>
        <div class="swiper-item" v-for="(item, index) in props.list" :key="index"
            :style="{ transform: `translateX(${currentIndex * -140}px)`, transition: 'transform 0.5s ease', }">
            <img :src="item" alt="" />
        </div>
        <div class="swiper"></div>
    </div>
</template>

<script setup>
import { ref, watchEffect } from "vue";
const props = defineProps({
    list: {
        type: Array,
    },
    auto: {
        type: Boolean,
        default: true,
    },
    time: {
        type: Number,
        default: 3000,
    },
});

const currentIndex = ref(0);
const isPaused = ref(false);

const prev = () => {
    currentIndex.value =
        (currentIndex.value - 1 + props.list.length) % props.list.length;
    console.log(currentIndex.value);
};

const next = () => {
    currentIndex.value =
        (currentIndex.value + 1 + props.list.length) % props.list.length;
    console.log(currentIndex.value);
};

watchEffect(() => {
    let timer;
    if (props.auto) {
        timer = setInterval(() => {
            next();
        }, props.time);
    } else if (timer) {
        clearInterval(timer);
    }
});
</script>

<style lang="css" scoped>
* {
    margin: 0;
    padding: 0;
}

.swiper-item {
    float: left;
}

img {
    height: 100px;
    width: 100px;
    margin: 20px;
}

.swiper {
    position: absolute;
    width: 140px;
    height: 140px;
    border: 1px solid #000;
    overflow: hidden;
}
</style>
js 复制代码
// 父组件调用 SwipTest.vue
<template>
  <swip :list="list" :auto="true" :time="1000" />
</template>

<script setup>
import swip from "./components/Swiper.vue";

const list = [
  "https://yanxuan-item.nosdn.127.net/cac68a7880bec1c72dcfce112d10e955.png",
  "https://yanxuan-item.nosdn.127.net/06a158d2888b20383a466227e39bbbc7.jpg",
  "https://yanxuan.nosdn.127.net/8f8092d5bf6a133a8cb59ab7b9f790e9.png",
  "https://yanxuan-item.nosdn.127.net/eac6c40fdb0f977fdf80048d7b181ffa.png",
  "https://yanxuan-item.nosdn.127.net/f881cfe7de9a576aaeea6ee0d1d24823.jpg",
];
</script>

<style lang="scss" scoped></style>

当用户点击按钮切换图片时,会调用 prevnext 方法,这两个方法会修改 currentIndex 的值,从而实现图片的切换。

  1. 模板部分 (<template>):

    • 通过动态绑定 :style 属性来实现图片的滑动效果。transform 属性通过修改 translateX 来控制图片的水平偏移,从而实现图片的滑动效果。transition 属性用于定义过渡效果,使图片切换时具有动画效果。
  2. 脚本部分 (<script setup>):

    • 使用 ref 创建了响应式数据 currentIndex,它表示当前显示的图片索引。
    • 定义了 prevnext 方法,用于切换图片。这两个方法会根据按钮点击事件修改 currentIndex 的值,实现上一张和下一张图片的切换。
    • 使用了 watchEffect 监听 props.autoprops.time 的变化。当 props.auto 的值为 true 时,会启动一个定时器,定时调用 next 方法来自动切换图片,并根据 props.time 来设置定时器的间隔时间。当 props.auto 的值变为 false 时,会清除定时器停止自动播放。
  3. 相加求余:

    • prevnext 方法中,使用了 (currentIndex.value - 1 + props.list.length) % props.list.length 来计算下一个要显示的图片索引。这是为了实现循环播放效果。当 currentIndex 等于 0 时,再向前切换就会回到最后一张图片;当 currentIndex 等于 props.list.length - 1 时,再向后切换就会回到第一张图片。

三、手写getElementById

好不容易写完后听到这个我又蒙了,这也能手写?......

我们都知道dom结构本质是一种树状结构,所以这题的本意就是让你获树状结构的id值并返回改结构......

简单可以将dom结构转化为以下这种形式,就拿ul标签来说,每个ul都有属于自己的id值,其ul标签下还有许多li标签,那么可以理解为li标签在ul中的children 属性中(同理被div标签包裹的子元素也可以这么理解)

js 复制代码
const tree = {
  id: 1,
  children: [
    {
      id: 2,
      children: [
        {
          id: 3,
          children: [
            {
              id: 4,
              children: [],
            },
          ],
        },
        {
          id: 5,
          children: [],
        },
      ],
    },
    {
      id: 6,
      children: [],
    },
  ],
};

能想到这里那么这题就迎刃而解了,就是遍历树来找id并返回结构嘛~

结果我是这么写的

js 复制代码
// 深度优先搜索
Function findIdDfs(tree, id) {
  if (!tree) return null;
  if (tree.id === id) {
    return this;
  }

  if (tree.children) {
    for (let i = 0; i < tree.children.length; i++) {
      const findtree = tree.children[i].findIdDfs(id);
      if (findtree) {
        return findtree;
      }
    }
  }
  return null;
};

面试官说你用 getElementById 你是怎么调用的? 😫😫

js 复制代码
let box = document.getElementByid('box')

然后继续改成这样的:

js 复制代码
// 深度优先搜索
Function.prototype.findIdDfs(tree, id) {};

然后继续被批,你调用原型你怎么获得tree你告诉我?

用this获取对象......

写完后......

面试官:这是什么思路

我:深度优先遍历

面试官:那你再用广度写下

🐭🐭再次洗掉......

源码

js 复制代码
// 深度优先搜索
Object.prototype.findIdDfs = function (id) {
  if (!this) return null;
  if (this.id === id) {
    return this;
  }

  if (this.children) {
    for (let i = 0; i < this.children.length; i++) {
      const findtree = this.children[i].findIdDfs(id);
      if (findtree) {
        return findtree;
      }
    }
  }
  return null;
};

console.log(tree.findIdDfs(5));

// 广度优先搜索
Object.prototype.findIdBfs = function (id) {
  const queue = [this];
  while (queue.length > 0) {
    const node = queue.shift();
    if (node.id === id) {
      return node;
    }

    if (node.children && node.children.length > 0) {
      for (let i = 0; i < node.children.length; i++) {
        queue.push(node.children[i]);
      }
    }
  }
  return null;
};

console.log(tree.findIdBfs(5));

本人实力太菜,前面轮播图写了一个多小时,写到这里的时候已经面了3小时,最后反问环节,老师说我实战太少,基础不扎实,🐭🐭泪目

不管怎么活每次面试都是一次磨砺,下次继续努力吧~

相关推荐
崔庆才丨静觅12 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby606112 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了13 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅13 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅13 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅13 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment13 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅14 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊14 小时前
jwt介绍
前端
爱敲代码的小鱼14 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax