当前位置: 首页 > news >正文

百度前端面试准备

以下是对该前端面试考点总结的超详细解释,从技术原理、使用场景、代码示例等维度展开:

一、JavaScript 核心考点

1. 数据类型与判断
  • JS 类型体系:JavaScript 有 7 种基本数据类型(stringnumberbooleanundefinednullsymbolbigint)和 1 种引用数据类型(object,包含数组、函数、对象等)。
  • typeof 相关
    • 作用:用于检测变量的类型,返回一个表示类型的字符串。
    • 特殊情况:typeof null 返回 'object',这是 JavaScript 早期设计的历史遗留问题,因为 null 被认为是一个空的对象指针。例如:
      console.log(typeof 123); // 'number'
      console.log(typeof 'abc'); // 'string'
      console.log(typeof null); // 'object'
      
  • 判断数组的方式
    • Array.isArray():专门用于判断一个值是否为数组,是最直接可靠的方法。示例:
      console.log(Array.isArray([1, 2, 3])); // true
      console.log(Array.isArray({})); // false
      
    • instanceof:通过判断对象的原型链中是否存在构造函数的 prototype 属性来确定类型。但它存在跨窗口/框架的问题,因为不同窗口的 Array 构造函数是不同的。示例:
      console.log([1, 2, 3] instanceof Array); // true
      console.log({} instanceof Array); // false
      
    • Object.prototype.toString.call():调用对象的 toString 方法,返回一个 [object 类型] 格式的字符串,可精准判断类型。示例:
      console.log(Object.prototype.toString.call([1, 2, 3])); // '[object Array]'
      console.log(Object.prototype.toString.call({})); // '[object Object]'
      
2. 进阶概念
  • 闭包
    • 定义:闭包是指有权访问另一个函数作用域中变量的函数,即使外部函数已经执行完毕,闭包仍能访问其作用域内的变量。通常是在一个函数内部创建另一个函数,内部函数引用外部函数的变量。
    • 作用:可以实现变量的私有化(模块化)、延迟执行等。例如,创建一个计数器:
      function createCounter() {let count = 0;return function() {return ++count;};
      }
      const counter = createCounter();
      console.log(counter()); // 1
      console.log(counter()); // 2
      
    • 内存泄漏:如果闭包中引用的变量是大型对象,且闭包长期存在(如被全局变量引用),会导致这些变量无法被垃圾回收机制回收,从而引发内存泄漏。
  • 事件循环机制
    • 宏任务(MacroTask):包括 setTimeoutsetIntervalI/O 操作、UI 渲染等。
    • 微任务(MicroTask):包括 Promise.then/catch/finallyMutationObserverprocess.nextTick(Node.js 中)等。
    • 执行顺序:执行栈中的同步代码执行完毕后,先清空所有微任务队列,然后再从宏任务队列中取出一个宏任务执行,之后又会清空微任务队列,如此循环。例如:
      console.log('同步1');
      setTimeout(() => {console.log('宏任务');
      }, 0);
      Promise.resolve().then(() => {console.log('微任务');
      });
      console.log('同步2');
      // 执行顺序:同步1 → 同步2 → 微任务 → 宏任务
      
3. 数据结构对比(Map 与对象)
  • 键类型:对象的键只能是字符串或 Symbol 类型;而 Map 的键可以是任意类型,包括基本类型(如数字、字符串、布尔值等)和引用类型(如对象、数组、函数等)。示例:
    const obj = {};
    const key1 = {};
    obj[key1] = 'value'; // 实际存储为 obj['[object Object]'] = 'value'
    console.log(obj[key1]); // 'value',但键是字符串化后的结果const map = new Map();
    const key2 = {};
    map.set(key2, 'value');
    console.log(map.get(key2)); // 'value',键是原对象
    
  • 键顺序Map 中的键是按照插入顺序进行排列的;对象在 ES6 之前,键的顺序是不确定的,ES6 之后,对象的键按照一定规则排序(数字优先升序,然后是字符串按插入顺序,最后是 Symbol 按插入顺序)。
  • 性能表现:在频繁进行增删操作的场景下,Map 的性能优于对象。因为 Map 是专门为键值对存储设计的,其内部实现针对增删查等操作做了优化;而对象的属性操作在某些情况下(如大量属性时)性能会稍差。
4. 算法实现(快速排序)

快速排序是一种分治算法,核心思想是选择一个基准元素,将数组分成比基准小和比基准大的两部分,然后对这两部分分别递归进行快速排序。

function quickSort(arr,low=0,high=arr.length-1){if(low>=high)return;const pivot=arr[high];let i=slow;for(let j=slow;j<high;j++){if(arr[j]<=pivot){[arr[i],arr[j]]=[arr[j],arr[i]];i++;}}[arr[i],arr[high]]=[arr[high],arr[i]];quickSort(arr,low,i-1);quick(arr,i+1,high);
}

二、CSS 核心考点

1. 性能相关(回流与重绘)
  • 回流(重排)
    • 定义:当元素的几何属性(如宽度、高度、位置等)发生变化时,浏览器需要重新计算元素的几何位置和大小,然后重新构建渲染树,这个过程称为回流。
    • 触发场景:
      • 页面初次渲染。
      • 元素的尺寸、位置、内容变化(如修改 widthheightpaddingmarginbordertextContent 等)。
      • 浏览器窗口大小变化(resize 事件)。
      • 添加或删除可见的 DOM 元素。
    • 优化方式:
      • 避免频繁操作样式,可通过修改 class 来批量修改样式。
      • 将 DOM 操作离线处理,如先将元素设置为 display: none,操作完成后再显示。
      • 使用 DocumentFragment 进行 DOM 批量操作。
  • 重绘
    • 定义:当元素的外观属性(如颜色、背景色等)发生变化,而几何属性不变时,浏览器只需要重新绘制元素的外观,这个过程称为重绘。
    • 触发场景:修改元素的 colorbackgroundborder-color 等不影响几何结构的属性。
    • 优化方式:同回流的优化思路,减少不必要的样式修改。
2. 元素显示控制区别(visibility: hiddendisplay: noneopacity: 0

在这里插入图片描述

  • display: none
    • 元素会从文档流中消失,不再占据空间,也不会触发任何事件。
    • 不会被子元素继承,子元素也会一同消失。
    • 切换显示状态时,会触发回流和重绘,因为元素的几何结构发生了变化。示例:
      .box {display: none;
      }
      
  • visibility: hidden
    • 元素仍占据文档流中的空间,只是视觉上不可见,会触发事件(如点击事件等)。
    • 会被子元素继承,子元素可以通过设置 visibility: visible 来显示。
    • 切换显示状态时,只会触发重绘,因为元素的几何结构未变。示例:
      .box {visibility: hidden;
      }
      .box .child {visibility: visible;
      }
      
  • opacity: 0
    • 元素仍占据文档流中的空间,视觉上透明,会触发事件。
    • 会被子元素继承,子元素无法通过设置 opacity 来显示(因为 opacity 是叠加的)。
    • 切换透明度时,一般会触发重绘,某些浏览器可能会利用 GPU 加速,可能只触发合成操作(性能较好)。示例:
      .box {opacity: 0;
      }
      

三、Vue 框架考点(含 Vue2/Vue3 差异)

1. 基础指令与属性

在这里插入图片描述

  • v-ifv-show 的区别
    • 渲染机制v-if 是“真正”的条件渲染,会根据条件动态创建或销毁元素;v-show 是通过修改元素的 display 属性来控制显示隐藏,元素始终会被渲染。
    • 适用场景v-if 适合条件不常变化的场景,因为频繁创建销毁元素有性能开销;v-show 适合条件频繁切换的场景,因为只是修改样式,性能更好。示例:
      <template><div v-if="isShow">v-if 控制</div><div v-show="isShow">v-show 控制</div>
      </template>
      <script>
      export default {data() {return {isShow: true};}
      };
      </script>
      
  • Vue 中 key 的作用
    • 在 Vue 的虚拟 DOM diff 算法中,key 用于标识节点的唯一性。当节点的 key 不变时,Vue 会认为是同一个节点,从而尽可能复用节点,提升 diff 效率;如果没有 keykey 不正确,可能会导致组件复用错误(如状态残留等问题)。示例:
      <template><div v-for="item in list" :key="item.id">{{ item.name }}</div>
      </template>
2. 响应式原理
  • Vue2 响应式(基于 Object.defineProperty
    • 原理:通过递归遍历对象的所有属性,使用 Object.defineProperty 为每个属性添加 getter 和 setter,当属性被访问或修改时,触发 getter 或 setter,进而通知视图更新。
    • 缺陷:
      • 无法监听数组的索引和长度变化(如 arr[0] = 1arr.length = 0 等操作无法触发响应式),Vue2 是通过重写数组的变异方法(如 pushpop 等)来实现部分数组操作的响应式。
      • 无法监听对象的新增或删除属性,需要使用 Vue.setthis.$set 来添加响应式属性,使用 Vue.deletethis.$delete 来删除属性。
  • Vue3 响应式(基于 Proxy
    • 原理:使用 Proxy 代理整个对象,拦截对象的各种操作(如属性的读取、设置、删除等),从而实现对对象所有变化的监听。同时,使用 Reflect 来操作目标对象,保持行为的一致性。
    • 优势:
      • 可以监听数组的索引、长度变化以及对象的新增、删除属性,无需额外的 API(如 Vue.set)。
      • 支持深层监听的优化,只有在访问到嵌套对象时才会递归创建代理,提升了初始化性能。示例(Vue3 中):
        import { reactive } from 'vue';
        const state = reactive({arr: [1, 2, 3],obj: { name: 'vue' }
        });
        state.arr[0] = 10; // 会触发响应式
        state.obj.age = 18; // 会触发响应式
        
3. 状态管理
  • refreactive 的区别
    • 适用类型ref 主要用于包装基本类型的值(如 numberstringboolean 等),使其成为响应式;也可用于包装引用类型,但内部还是会用 reactive 来处理。reactive 用于将对象(引用类型)转换为响应式对象。
    • 访问方式ref 包装后的值需要通过 .value 来访问和修改;reactive 包装的对象可以直接访问和修改属性。示例:
      import { ref, reactive } from 'vue';
      const count = ref(0);
      console.log(count.value); // 0
      count.value++;const user = reactive({ name: 'vue' });
      console.log(user.name); // 'vue'
      user.name = 'vue3';
      

在这里插入图片描述

  • Pinia 相比 Vuex 的优点
    • 简化 API:Pinia 没有 mutations,只有 stategettersactionsactions 既可以处理同步操作也可以处理异步操作,使用更简洁。
    • 支持 TypeScript:Pinia 对 TypeScript 有更好的类型推断支持,无需额外的类型声明配置,开发体验更优。
    • 无需模块化嵌套:Vuex 中如果有多个模块,需要进行模块的注册和命名空间的管理,较为繁琐;Pinia 中每个 store 都是独立的,不需要嵌套模块,结构更清晰。
    • 更轻量
4. 组件通信
  • Props/emit:父组件通过 props 向子组件传递数据,子组件通过 $emit 触发自定义事件向父组件传递数据。示例:
<template><Child :msg="message" @custom-event="handleEvent" />
</template><script setup>
import { ref } from 'vue';
import Child from './Child.vue';// 响应式数据
const message = ref('父组件消息');// 事件处理函数
const handleEvent = (data) => {console.log('子组件传递的数据:', data);
};
</script>
<template><div @click="sendData">{{ msg }}</div>
</template><script setup>
import { defineProps, defineEmits } from 'vue';// 定义props
const props = defineProps({msg: {type: String,default: ''}
});// 定义emit事件
const emit = defineEmits(['custom-event']);// 发送数据方法
const sendData = () => {emit('custom-event', '子组件数据');
};
</script>
  • Vuex/Pinia:通过全局状态管理库,实现任意组件间的通信。组件可以直接读取全局状态,也可以通过提交 mutations(Vuex)或调用 actions(Vuex/Pinia)来修改全局状态。
  • EventBus:创建一个全局的事件总线(通常是一个 Vue 实例),组件通过 $on 监听事件,通过 $emit 触发事件来实现通信。但在大型项目中,EventBus 可能会导致事件管理混乱,逐渐被 Vuex/Pinia 取代。示例:
    // eventBus.js
    import Vue from 'vue';
    export default new Vue();// 组件 A
    import eventBus from './eventBus.js';
    eventBus.$emit('event-name', data);// 组件 B
    import eventBus from './eventBus.js';
    eventBus.$on('event-name', (data) => {console.log(data);
    });
    
  • provide/inject:用于祖先组件向后代组件传递数据,无论组件层级多深。provide 提供数据,inject 注入数据。示例:
<!-- 祖先组件 Ancestor.vue -->
<template><div><!-- 后代组件(无论层级多深) --><Descendant /></div>
</template><script setup>
import { provide } from 'vue';
import Descendant from './Descendant.vue';// 提供数据:第一个参数是注入的 key,第二个参数是要传递的值
provide('message', '祖先组件通过 provide 传递的数据');// 也可以提供响应式数据(使用 ref 或 reactive)
import { ref } from 'vue';
const count = ref(0);
provide('count', count); // 传递响应式数据
</script>
<!-- 后代组件 Descendant.vue(可以是子组件、孙组件等任意层级) -->
<template><div><p>注入的普通数据:{{ message }}</p><p>注入的响应式数据:{{ count }}</p><button @click="count++">修改响应式数据</button></div>
</template><script setup>
import { inject } from 'vue';// 注入数据:参数为祖先组件提供的 key
// 第二个参数可选,作为默认值(当找不到对应 key 时使用)
const message = inject('message', '默认值(如果未提供数据)');// 注入响应式数据(注入后仍保持响应式)
const count = inject('count');
</script>

好的,根据您提供的图片内容,这是一份非常经典和实用的前端面试提纲。下面我将针对这几个核心考点,为您提供一份详细的解答和知识梳理,希望能帮助您准备面试。


前端核心面试题解答

1. 布局常用方式:Flex 和 Grid 布局

这是考察 CSS 现代布局能力的核心。

Flex 布局(弹性盒子布局)

  • 设计初衷:为一维布局提供更有效的方式,即处理中的一个维度。
  • 核心概念:容器(display: flex;)和项目(flex items)。通过主轴和交叉轴来控制对齐。
  • 常用容器属性
    • justify-content:定义项目在主轴上的对齐方式(如 flex-start, center, space-between)。
    • align-items:定义项目在交叉轴上的对齐方式(如 stretch, center, flex-start)。
    • flex-direction:决定主轴方向(row, column, row-reverse)。
    • flex-wrap:定义项目是否换行(nowrap, wrap)。
  • 适用场景:导航栏、垂直居中、等高分栏、流动式内容排列。

Grid 布局(网格布局)

  • 设计初衷:为二维布局设计,可以同时处理行和列。
  • 核心概念:容器(display: grid;)通过定义网格线和轨道来创建单元格。
  • 常用容器属性
    • grid-template-columns/rows:定义列和行的尺寸和数量(如 1fr 200px 1fr)。
    • gap:设置网格间隙(row-gap, column-gap)。
    • grid-template-areas:通过给区域命名来进行布局,非常直观。
    • justify-items / align-items:项目在网格单元格内的对齐方式。
  • 适用场景:复杂的整体页面布局(如 Holy Grail Layout)、杂志式卡片布局。

面试官可能追问

  • Flex 和 Grid 最主要的区别是什么?(一维 vs 二维)
  • 用什么属性可以实现一个元素的完美垂直居中?
    • Flex: 父容器 display: flex; justify-content: center; align-items: center;
    • Grid: 父容器 display: grid; place-items: center;(或使用 justify/align-items
  • 解释一下 fr 单位。

2. 防抖和节流

这是性能优化的重要知识点,用于控制函数执行频率。

防抖

  • 概念:在事件被触发 n 秒后再执行回调,如果在这 n 秒内又被触发,则重新计时。
  • 比喻:电梯门,如果不断有人进,电梯门会一直保持打开,直到没人进了才会关闭。
  • 适用场景搜索框输入联想、窗口 resize 事件
  • 实现(修复常见瑕疵)
    常见瑕疵是未处理 this 指向和事件对象 event
function debounce(func, wait) {let timeoutId;// 返回一个闭包函数return function (...args) {// 保存本次调用的上下文(this)和参数(args)const context = this;// 如果已经有定时器,就清除它,实现“重新计时”clearTimeout(timeoutId);// 设置新的定时器timeoutId = setTimeout(() => {// 使用 apply 确保 func 中的 this 指向正确,并传入参数func.apply(context, args);}, wait);};
}// 使用示例
const myInput = document.getElementById('search');
myInput.addEventListener('input', debounce(function(e) {console.log('发送搜索请求:', e.target.value);
}, 500));

节流

  • 概念:规定在一个单位时间内,只能触发一次函数执行。如果这个单位时间内触发多次,只有一次生效。
  • 比喻:地铁,每 5 分钟一班,不管你来了多少人,都按固定频率发车。
  • 适用场景滚动加载、按钮频繁点击、鼠标移动事件
  • 实现(时间戳+定时器版,更准确)
function throttle(fn, limit) {let lastRan = 0;let timeout = null;return function(...args) {const now = Date.now();if (now - lastRan >= limit) {fn.apply(this, args);lastRan = now;}//不配合会导致最后一次出发不执行 scroll、resize不友好else {// 结合时间戳 + setTimeout,既立即执行又确保尾部调用。if (timeout) clearTimeout(timeout);timeout = setTimeout(() => {fn.apply(this, args);lastRan = Date.now();}, limit - (now - lastRan));}};
}

面试官可能追问

  • 防抖和节流的区别?分别举一个实际应用例子。
  • 为什么要在防抖函数里保存 thisargs

3. 事件循环机制

考察对 JavaScript 单线程、异步编程底层原理的理解。通常会给出一段包含 setTimeoutPromise 的代码让分析输出顺序。

核心规则

  1. 同步代码优先执行。
  2. 微任务 优先于 宏任务
  3. 常见宏任务setTimeout, setInterval, setImmediate (Node.js), I/O 操作, UI rendering。
  4. 常见微任务Promise.then, Promise.catch, Promise.finally, queueMicrotask, MutationObserver

例题分析

console.log('1');setTimeout(function() {console.log('2');new Promise(function(resolve) {console.log('3');resolve();}).then(function() {console.log('4');});
}, 0);new Promise(function(resolve) {console.log('5');resolve();
}).then(function() {console.log('6');
});console.log('7');

输出顺序1 -> 5 -> 7 -> 6 -> 2 -> 3 -> 4

执行步骤分析

  1. 执行同步代码:输出 1, 5, 7
    • new Promise 内部的 executor 函数是同步执行的,所以输出 5
  2. 同步代码执行完毕,检查微任务队列。此时微任务队列中有 Promise.then 的回调(输出 6 的那个)。执行它,输出 6
  3. 微任务队列清空,开始执行下一个宏任务(即 setTimeout 的回调)。
  4. 执行 setTimeout 回调
    • 输出 2
    • 遇到 new Promise,同步执行 executor,输出 3
    • Promise.then 的回调(输出 4 的那个)放入微任务队列。
  5. 当前宏任务执行完毕,检查微任务队列。发现有微任务(输出 4 的那个),执行它,输出 4

面试官可能追问

  • async/await 的本质是什么?(Generator 的语法糖,其后的代码相当于放在 Promise.then 中,是微任务)。
  • process.nextTick (Node.js) 和微任务的优先级?

4. Webpack 和 Vite 常用配置

考察对前端工程化工具的熟悉程度。

Webpack

  • 核心概念:入口(Entry)、输出(Output)、加载器(Loaders)、插件(Plugins)、模式(Mode)。
  • 常用配置
    • entry:定义打包入口文件。
    • output:定义打包后的文件输出路径和文件名(如 path, filename, chunkFilename, clean)。
    • module.rules:配置 Loader,处理非 JS 文件(CSS,图片,转译 JS)。
      module: {rules: [{ test: /\.css$/, use: ['style-loader', 'css-loader'] },{ test: /\.js$/, exclude: /node_modules/, use: 'babel-loader' },{ test: /\.(png|jpg|gif)$/, type: 'asset/resource' }]
      }
      
    • plugins:用于执行更广泛的任务,如打包优化、资源管理、环境变量注入。
      • HtmlWebpackPlugin:自动生成 HTML 文件并注入 JS 包。
      • MiniCssExtractPlugin:将 CSS 提取到单独的文件。
      • DefinePlugin:定义全局常量。
    • optimization.splitChunks:代码分割配置。
    • devServer:配置开发服务器(端口、代理等)。

Vite

  • 核心优势:基于原生 ES Module,启动速度极快。利用 Esbuild 进行预构建和依赖预打包。
  • 与 Webpack 主要区别
    • 开发环境:Vite 无需打包,服务器随起随用。Webpack 需要先打包构建。
    • 生产环境:Vite 使用 Rollup 进行打包,配置更简洁。
  • 常用配置 (vite.config.js):
    • plugins:集成 Rollup 插件生态,如 @vitejs/plugin-vue@vitejs/plugin-react
    • resolve.alias:配置路径别名。
    • server:开发服务器配置(端口、代理、打开浏览器)。
      server: {port: 3000,proxy: {'/api': {target: 'http://localhost:8080',changeOrigin: true}}
      }
      
    • build:生产构建配置(输出目录、资源路径、打包优化)。
      build: {outDir: 'dist',rollupOptions: {output: {chunkFileNames: 'js/[name]-[hash].js',assetFileNames: '[ext]/[name]-[hash].[ext]'}}
      }
      

面试官可能追问

  • Vite 为什么比 Webpack 快?(开发环境利用浏览器原生 ESM,无需打包)。
  • 谈一下你对 Tree-shaking 的理解。
  • 如何配置 Webpack/Vite 来解决跨域问题?(使用 devServer.proxy / server.proxy)。

http://www.dtcms.com/a/507823.html

相关文章:

  • 立创EDA学习(一、新建项目与自定义元件)
  • dify项目智能记账
  • 使用Jmeter进行接口测试:HTTP请求与响应报文结构详解
  • 前端6:CSS3 2D转换,CSS3动画,CSS3 3D转换
  • Python中使用SQLite
  • 简约个人网站欣赏wordpress pdf view
  • JVM 的启动器类解读 -- sun.misc.Launcher
  • java Servlet 概念讲解 以及和Golang概念对比
  • CoAtNet:让卷积与注意力在所有数据规模上“联姻”,CNN+Transformer融合
  • 个人网站的建设流程博物馆网站做的好的
  • 中间件与CORS(基于fastapi)
  • 【Go】P8 Go 语言核心数据结构:深入解析切片 (Slice)
  • 使用Wireshark测试手机APP网络通信完整指南
  • 【AI论文】MemMamba:对状态空间模型中记忆模式的重新思考
  • 郴州建站扁平化网站后台
  • 请问做网站和编程哪个容易些网站建设一般的流程
  • 三地两中心架构介绍
  • Harmony鸿蒙开发0基础入门到精通Day01--JavaScript篇
  • CCIE好像越来越销声匿迹了......
  • 自己做ppt网站汕头网站制作哪里好
  • UVa 1344 Tian Ji The Horse Racing
  • 网站交换链接友情链接的作用网站地图制作
  • 【给服务器安装服务器安装nacos】
  • 影楼模板网站html5风格网站特色
  • Spark的Shuffle过程
  • 前端HTML常用基础标
  • 智能井盖传感器如何成为智慧城市“无声卫士”?
  • Django Web 开发系列(一):视图基础与 URL 路由配置全解析
  • 【python】在Django中,执行原生SQL查询
  • 5 个 Windows 故障排除工具