一、HTML & CSS 核心问题
1. 请说说HTML5有哪些新特性?
参考答案:
-
语义化标签 :
<header>,<footer>,<nav>,<section>,<article>,<aside>等 -
媒体元素 :
<audio>,<video>标签 -
图形绘制 :
<canvas>和<svg> -
本地存储 :
localStorage和sessionStorage -
表单增强 :新的输入类型如
email,url,number,date等 -
Web Workers:允许在后台运行JavaScript脚本
2. 什么是CSS盒模型?标准盒模型和怪异盒模型有什么区别?
参考答案:
-
标准盒模型 :
width和height只包含内容(content),不包括 padding 和 border -
怪异盒模型 :
width和height包含 content + padding + border -
切换方式 :
box-sizing: content-box;(标准) 和box-sizing: border-box;(怪异)
3. 请实现一个水平垂直居中的方案(至少三种)
参考答案:
css
/* 方法1:Flex布局(最推荐) */
.container {
display: flex;
justify-content: center;
align-items: center;
}
/* 方法2:Grid布局 */
.container {
display: grid;
place-items: center;
}
/* 方法3:绝对定位 + transform */
.center {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
/* 方法4:绝对定位 + margin */
.center {
position: absolute;
top: 0; left: 0; right: 0; bottom: 0;
margin: auto;
}
4. 说说Flex布局和Grid布局的区别及应用场景?
参考答案:
-
Flex布局:一维布局,适合线性排列的项目(导航栏、卡片列表)
-
Grid布局:二维布局,适合复杂的网格结构(整个页面布局、仪表盘)
-
选择原则:组件内部用Flex,整体布局用Grid
二、JavaScript 核心问题
1. var、let、const 的区别?
参考答案:
| 特性 | var | let | const |
|---|---|---|---|
| 作用域 | 函数作用域 | 块级作用域 | 块级作用域 |
| 变量提升 | 提升且初始化为undefined | 提升但不初始化 | 提升但不初始化 |
| 重复声明 | 允许 | 不允许 | 不允许 |
| 重新赋值 | 允许 | 允许 | 不允许 |
2. 什么是闭包?有什么应用场景?
参考答案:
-
定义:函数能够访问并记住其词法作用域,即使函数在作用域外执行
-
创建条件:函数嵌套 + 内部函数引用外部变量
-
应用场景:
javascript
// 1. 创建私有变量 function createCounter() { let count = 0; // 私有变量 return { increment() { count++; }, getValue() { return count; } }; } // 2. 函数柯里化 function add(x) { return function(y) { return x + y; }; }
3. 说说Promise是什么?有哪些状态?
参考答案:
-
三种状态 :
pending(进行中)、fulfilled(已成功)、rejected(已失败) -
特点:状态一旦改变就不会再变
-
常用方法:
javascript
// 基本使用 new Promise((resolve, reject) => { // 异步操作 if (success) resolve(data); else reject(error); }).then(data => { console.log(data); }).catch(error => { console.error(error); }); // 静态方法 Promise.all([p1, p2, p3]) // 全部成功 Promise.race([p1, p2, p3]) // 第一个完成
4. 手写防抖和节流函数
参考答案:
javascript
// 防抖:连续触发时,只在最后执行一次
function debounce(fn, delay) {
let timer = null;
return function(...args) {
clearTimeout(timer);
timer = setTimeout(() => {
fn.apply(this, args);
}, delay);
};
}
// 节流:连续触发时,每隔一段时间执行一次
function throttle(fn, delay) {
let lastTime = 0;
return function(...args) {
const now = Date.now();
if (now - lastTime >= delay) {
fn.apply(this, args);
lastTime = now;
}
};
}
// 使用场景
window.addEventListener('resize', debounce(handleResize, 300));
window.addEventListener('scroll', throttle(handleScroll, 100));
三、Vue.js 核心问题
1. Vue 的生命周期有哪些?
参考答案:
-
创建阶段 :
beforeCreate→created(实例创建,数据观测) →beforeMount→mounted(DOM挂载完成) -
更新阶段 :
beforeUpdate→updated -
销毁阶段 :
beforeUnmount→unmounted
2. Vue 组件间通信方式有哪些?
参考答案:
-
父子通信 :
props+$emit -
子父通信 :
$emit事件 -
兄弟通信:事件总线或 Vuex/Pinia
-
跨级通信 :
provide/inject -
任意组件:Vuex/Pinia 状态管理
3. Vue2 和 Vue3 响应式原理的区别?
参考答案:
javascript
// Vue2:Object.defineProperty
Object.defineProperty(obj, key, {
get() { /* 依赖收集 */ },
set(newVal) { /* 通知更新 */ }
});
// Vue3:Proxy
new Proxy(obj, {
get(target, key) { /* 依赖收集 */ },
set(target, key, newVal) { /* 通知更新 */ }
});
Vue3优势:可以检测到对象属性的添加/删除,数组索引和length的变化
4. computed 和 watch 的区别?
参考答案:
-
computed:计算属性,基于依赖缓存,只有依赖变化才重新计算
-
watch:监听器,数据变化时执行异步或开销较大的操作
-
使用场景:
javascript
// computed - 适合模板中使用的衍生数据 computed: { fullName() { return this.firstName + ' ' + this.lastName; } } // watch - 适合数据变化时需要执行异步操作 watch: { searchText(newVal) { this.fetchSearchResults(newVal); } }
四、网络与浏览器问题
1. 从输入URL到页面显示发生了什么?
参考答案:
-
DNS解析:将域名解析为IP地址
-
TCP连接:三次握手建立连接
-
发送HTTP请求:浏览器发送请求报文
-
服务器处理:服务器返回响应报文
-
浏览器解析渲染:
-
解析HTML构建DOM树
-
解析CSS构建CSSOM树
-
合并成渲染树(Render Tree)
-
布局(Layout)和绘制(Paint)
-
2. 常见的HTTP状态码有哪些?
参考答案:
-
1xx:信息性状态码
-
2xx :成功 -
200 OK(成功)、201 Created(创建成功) -
3xx :重定向 -
301 Moved Permanently(永久重定向)、302 Found(临时重定向) -
4xx :客户端错误 -
400 Bad Request、401 Unauthorized、403 Forbidden、404 Not Found -
5xx :服务器错误 -
500 Internal Server Error、502 Bad Gateway
3. 什么是跨域?如何解决?
参考答案:
-
产生原因:浏览器的同源策略(协议、域名、端口相同)
-
解决方案:
-
CORS (跨域资源共享):服务器设置
Access-Control-Allow-Origin -
代理服务器:开发环境配置proxy
-
JSONP :利用
<script>标签不受同源策略限制 -
WebSocket:不受同源策略限制
-
五、手写代码题
1. 手写深拷贝函数
javascript
function deepClone(obj, hash = new WeakMap()) {
if (obj === null || typeof obj !== 'object') return obj;
if (obj instanceof Date) return new Date(obj);
if (obj instanceof RegExp) return new RegExp(obj);
if (hash.has(obj)) return hash.get(obj);
const cloneObj = new obj.constructor();
hash.set(obj, cloneObj);
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
cloneObj[key] = deepClone(obj[key], hash);
}
}
return cloneObj;
}
2. 手写数组去重
javascript
// 方法1:Set(最简洁)
const unique = arr => [...new Set(arr)];
// 方法2:Filter + indexOf
const unique = arr => arr.filter((item, index) => arr.indexOf(item) === index);
// 方法3:Reduce
const unique = arr => arr.reduce((prev, curr) =>
prev.includes(curr) ? prev : [...prev, curr], []);