大二下的我今天也是约到第一次面试了,记录一下。

148 阅读9分钟

大二下的我也是闲不住,早早地来趟面试这摊浑水,话不多说搞个复盘吧。

面试

1.react与vue之间的主要区别是什么?

vue:它采用模板语法和响应式数据绑定,通过简洁的指令(如 v-ifv-model)实现声明式开发,降低了学习门槛。使用模板语法,将 HTML、CSS 和 JavaScript 分离。Vue 采用 "一站式" 解决方案,提供了官方的路由、状态管理等库,集成度更高,开发者可以更快速地实现复杂功能。成为了一些快速开发的首选。

react:React 以函数式编程和组件化为设计理念,强调“单向数据流”与不可变数据。使用 JSX语法,将 HTML 和 JavaScript 逻辑混合在一起。react更偏向于原生js,往往对于一些复杂的功能需要自己去依赖于第三方库,自己去实现,但也使得它更灵活。而且自react18以后,react更推荐hooks来作为主要的状态管理和副作用处理方式。而不推荐使用类组件了。

2.问我自己的项目是自己做的吗?特别是后端

答:我只能说大部分是,有很多借鉴的地方。

3.项目中的基于RBAC模型设计动态路由权限是怎么做的?

什么是RBAC模型?

RBAC 模型(Role-Based Access Control,基于角色的访问控制)  是一种常用的访问控制模型,用于管理系统中用户对资源的访问权限。其核心逻辑是:用户→角色→权限:用户不直接关联权限,而是通过分配角色间接获得权限。超级管理员可以给用户分配不同的角色,从而达到控制不同的权限,快速调整不同的权限,而不是对用户进行逐个修改。

3.1 怎么做的?

主要通过前端路由鉴权和后端路由权限控制,通过前端的路由守卫来检查本地token是否存在,然后后端 再根据登录者的身份返回对应的路由。基于RBAC的话,就是有一个超级管理员,通过他来给用户赋予不同的身份,就能有不同的权限,而用户在注册的时候都是普通的用户。

3.2 因为我又用到了动态路由,面试官又问我是怎么实现路由懒加载的?

主要是通过vite中的API:import.meta.glob,它是Vite 特有的语法,用于批量导入文件,返回一个模块路径到模块导入函数的映射对象。 根据这个获取到src/views 目录下的所有 .vue 文件,然后再自定义函数获取对应的动态导入函数。 如下:

function loadComponent(url: string){
  let Module = import.meta.glob("@/views/**/*.vue");
  return Module[`/src/views/${url}.vue`];
}

然后再根据递归返回对应的路由。

4.面试官跟我聊了聊富文本编辑器,例如WangEditor

5.项目优化是怎么做的?

a. 首先通过 rollup-plugin-visualizer 插件生成打包分析报告,直观展示各个模块的大小。

b. 配置打包文件分类输出,指定不同类型文件的输出格式。

c. js最小拆包:例如把体积较大的包拆成一些小包,将来自于node_modules的每一个依赖的包都单独打包,拆分出来。还配置了入口文件,静态资源文件,还有项目中的其他文件的输出格式。

d. 利用terser剔除项目中多余的console.log和debugger。

e. 将项目中的图片资源压缩一遍,我用的是 vite-plugin-minipic 插件。

f. 按需引入第三方库,例如element-plus,echarts。

g. 路由懒加载。

h. 开启tree-shaking,注意这需要项目使用ES作为模块系统,这样Tree Shaking 才能正常工作,- 确保你的代码按照ES模块的规范进行导出和导入。例如,使用export关键字导出模块,使用import关键字导入模块。确保你的代码是静态的,即在编译时可确定模块的导入和导出关系。Tree Shaking才能在编译时确定哪些代码是不需要的,从而将其删除。

I. 使用 gzip 压缩。

5.1 紧接着面试官又问了我,你知道tree-shaking是什么吗?是用来干什么的,简单说说呢?

Tree Shaking 是一种静态分析技术,用于在编译时移除未使用的代码(即 "dead code")。

5.2 你在项目中导出的时候,使用export还是export default呢?

答:应该是export导出,从tree-shaking的角度来说,默认导出会导出整个对象,编辑器不知道对象中哪些属性未被使用,因此整个对象都会被打包,tree-shaking就不起作用了。这里还有个:

常见误区:默认导出 + 解构赋值≠Tree Shaking

5.3 你在压缩图片的时候又是怎么处理的呢?为什么?

首先我们需要知道图片压缩本质是用计算资源换取传输带宽

  • 压缩收益:减少文件体积,加快下载速度。
  • 压缩成本
    • 构建时:压缩算法消耗 CPU 时间(影响打包速度)。
    • 运行时:浏览器解压图片消耗内存和 CPU(影响首屏渲染速度)。

当压缩收益小于压缩成本的时候,说明这个图片不值得压缩。简单来说,压缩图片的时候设定一个阈值,假设是10kb,当图片大于10kb就现在压缩,小于10kb的时候就不进行压缩,因为浏览器在解压小体积的图片的时候更影响性能。

6.你是怎么实现移动端多尺寸屏幕自适应布局的呢?

答:采用rem方案。

基准值设定
将设计稿宽度设为 375px,并假设 1rem = 100px,方便换算。

响应式调整
通过监听 resize 事件,在窗口大小变化时重新计算 font-size,确保动态适配(如横竖屏切换)。

最大宽度限制
当设备宽度超过 375px 时,固定 font-size 为 100px,避免在大屏幕上元素过大。

关键代码如下:

~(function anonymous(window) {
  let computedREM = function computedREM() {
    let winW = document.documentElement.clientWidth, // 获取视口宽度
        desW = 375; // 设计稿基准宽度
    
    // 限制最大宽度(可选)
    if (winW >= 375) {
      document.documentElement.style.fontSize = '100px';
      return;
    }
    
    // 核心计算:根据当前视口宽度动态调整根元素字体大小
    document.documentElement.style.fontSize = (winW / desW) * 100 + 'px';
  }
  
  computedREM(); // 初始化执行一次
  window.addEventListener('resize', computedREM); // 窗口大小变化时重新计算
})(window);

7.你用过vm/vh吗,你知道vm/vh与rem之间的区别吗?

维度vh/vw/vminrem
基准视口尺寸(浏览器窗口宽高)根元素字体大小(<html>font-size
实现方式纯 CSS,无需 JS需要 JS 动态设置根字体
动态适应性自动随视口变化,实时响应依赖resize事件监听,需手动触发更新
设计稿映射直接计算比例(如 375px 设计稿中,1px=1/3.75vw通过根字体转换(如 375px 对应100px根字体,1px=0.01rem
典型场景固定高度栏(height: 50px → height: 50/视口高度*100vh整体布局缩放(如按钮、间距等按比例适配)
兼容性现代浏览器支持好(IE11+),低版本需前缀广泛支持(IE9+)
性能影响无 JS 执行成本JS 计算与事件监听可能带来轻微开销

8.你知道flex:1吗?

flex: 1 是 Flexbox 布局中的一个常用属性值,用于让元素自动填充剩余空间按比例分配空间。它是 flex-growflex-shrink 和 flex-basis 三个属性的简写。

flex-grow: 1;      /* 允许元素在主轴方向上增长 */
flex-shrink: 1;    /* 允许元素在空间不足时收缩 */
flex-basis: 0;     /* 元素的初始大小为0,剩余空间全部分配 */

flex-basis 这个属性不为0的话,假设为100,就会让元素先占据100px的空间,然后再自动分配剩下的空间。

9.假设在处理表单中头像与描述文字的布局溢出问题时,就是文字太多会导致头像被挤压应该怎么解决呢?

当描述文字过长时,可能出现两种情况:

  1. 头像被挤压:头像宽度被迫缩小(默认 flex-shrink: 1)。
  2. 文字溢出:文字超出容器边界(默认 white-space: normal 会换行,若设置 nowrap 则溢出)。
  • 所有 flex 子项默认 flex-shrink: 1,即空间不足时会收缩
  • 问题:若头像设置了固定宽度(如 width: 40px),但描述文字过长,头像可能被挤压变形。 解决方案:给头像禁用收缩(flex-shrink: 0

10.请你用flex布局完成一个三明治布局

顶部和底部固定宽度,中间自适应和滚动
<div class="page">
  <header>头部</header>
  <main>主要内容</main>
  <footer>底部</footer>
</div>
.page {
  display: flex;
  flex-direction: column;
  height: 100vh;
}
header {
  height: 60px;
}
main {
  flex: 1; /* 填充中间所有空间,超出会滚动 */
  overflow: auto;
}
footer {
  height: 50px;
}

11.请举几个例子平常对flex的应用呢?

  • 让元素水平垂直居中:align-items: centerjustify-content: center

  • 水平等距分布元素:当你需要让多个元素在水平方向上等距分布时,justify-content: space-betweenjustify-content: space-around,等等。

  • 元素对齐方式:借助align-items属性,能够设置元素在交叉轴上的对齐方式。如flex-end,flex-start。

  • 多行行内对齐:当有多行元素时,可以使用align-content来设置行与行之间的对齐方式。

12.在完成微信小程序的时候是否有遇到过,textarea表达在iOS系统

中,唤起键盘时会挡住表单内容的情况?

ps:没遇到过,也没答出来。

13.微信小程序采用的是哪种方式登录的呢?

1.(登录鉴权流程 )
2. (手机号一键登录)

14.做微信小程序信息收集的时候用过哪些原生组件?

很多例如select,radio,form等等。