一、HTML/CSS 基础篇
1. 如何让一个 div 水平居中?至少写出 3 种方法
答题思路:
- 方法1:
margin: 0 auto;
+ 设置宽度(块级元素)。 - 方法2:父级
text-align: center;
,子级display: inline-block;
。 - 方法3:Flex 布局,父级
display: flex; justify-content: center;
。
2. CSS 中隐藏元素的方法有哪些?区别是什么?
答题思路:
- **
display: none
**:元素不占据空间,无法触发点击事件。 - **
visibility: hidden
**:元素占据空间,但不可见,无法触发事件。 - **
opacity: 0
:元素透明且占据空间,可以触发事件**。
3. 什么是 CSS 盒模型?如何设置怪异盒模型?
答题思路:
- 标准盒模型:
width = content
,总宽度 =width + padding + border
。 - 怪异盒模型:
width = content + padding + border
,通过box-sizing: border-box;
设置。
4. 如何实现两栏布局(左侧固定宽度,右侧自适应)?
答题思路:
- Flex 布局:父级
display: flex;
,左侧定宽,右侧flex: 1;
。 - 浮动布局:左侧
float: left; width: 200px;
,右侧margin-left: 200px;
。 - Grid 布局:父级
display: grid; grid-template-columns: 200px 1fr;
。
5. 如何实现一个三角形?
答题思路:
利用 border
属性:
css
.triangle { width: 0; height: 0; border-left: 50px solid transparent; border-right: 50px solid transparent; border-bottom: 100px solid red;
}
二、JavaScript 核心篇
6. 如何判断一个变量的类型?typeof
和 instanceof
的区别?
答题思路:
- **
typeof
**:返回基本类型(string
/number
/boolean
),但typeof null
返回"object"
。 - **
instanceof
**:判断对象类型(如[] instanceof Array
)。 - **
Object.prototype.toString.call()
**:万能方法(如[object Array]
)。
7. 什么是闭包?写一个闭包的例子
答题思路:
闭包是函数嵌套时,内部函数引用外部函数变量的机制。
javascript
function outer() { let count = 0; function inner() { count++; console.log(count); } return inner;
}
const fn = outer();
fn(); // 1
fn(); // 2
应用场景:计数器、防抖节流、模块化封装。
8. 如何实现数组去重?至少写出 2 种方法
答题思路:
- Set 去重:
[...new Set(arr)]
。 - filter + indexOf:
javascript
arr.filter((item, index) => arr.indexOf(item) === index);
9. 什么是事件冒泡和事件捕获?如何阻止事件冒泡?
答题思路:
- 事件冒泡:事件从目标元素向上传播到根节点(默认)。
- 事件捕获:事件从根节点向下传播到目标元素。
- 阻止冒泡:
event.stopPropagation()
。
10. 什么是 Promise?如何解决回调地狱?
答题思路:
- Promise:表示异步操作的最终完成或失败,支持链式调用。
- 解决回调地狱:
javascript
fetchData() .then(data => processData(data)) .then(result => displayResult(result)) .catch(error => console.error(error));
三、浏览器与网络篇
11. 从输入 URL 到页面展示发生了什么?
答题思路:
- DNS 解析:将域名转换为 IP 地址。
- TCP 连接:三次握手建立连接。
- 发送 HTTP 请求:浏览器发送请求报文。
- 服务器处理并返回响应。
- 浏览器解析 HTML/CSS,构建 DOM 树和渲染树。
- 布局(Layout)和绘制(Paint)。
12. 什么是跨域?如何解决跨域问题?
答题思路:
- 跨域:协议、域名、端口不一致导致的请求限制。
- 解决方案:
- CORS:服务端设置
Access-Control-Allow-Origin: *
。 - JSONP:通过
<script>
标签跨域请求(仅 GET)。
- CORS:服务端设置
13. Cookie、LocalStorage、SessionStorage 的区别?
答题思路:
Cookie | LocalStorage | SessionStorage | |
---|---|---|---|
容量 | 4KB | 5MB | 5MB |
生命周期 | 可设置过期时间 | 永久 | 会话结束销毁 |
通信 | 每次请求携带 | 不参与 | 不参与 |
14. 什么是事件循环(Event Loop)?
答题思路:
- 宏任务:
script
、setTimeout
、setInterval
。 - 微任务:
Promise.then
、MutationObserver
。 - 执行顺序:宏任务 → 微任务 → 渲染 → 下一轮宏任务。
15. 如何优化页面加载速度?
答题思路:
- 减少资源体积:压缩代码、图片转 WebP。
- 使用 CDN:加速静态资源加载。
- 懒加载:图片/组件按需加载。
四、手写代码与场景题
16. 手写深拷贝函数
答题思路:
javascript
function deepClone(obj) { if (typeof obj !== 'object' || obj === null) return obj; const result = Array.isArray(obj) ? [] : {}; for (let key in obj) { if (obj.hasOwnProperty(key)) { result[key] = deepClone(obj[key]); } } return result;
}
17. 手写数组扁平化函数
答题思路:
javascript
function flatten(arr) { return arr.reduce((prev, curr) => { return prev.concat(Array.isArray(curr) ? flatten(curr) : curr); }, []);
}
18. 实现一个防抖函数(Debounce)
答题思路:
javascript
function debounce(fn, delay) { let timer; return (...args) => { clearTimeout(timer); timer = setTimeout(() => fn(...args), delay); };
}
19. 如何实现一个简单的发布-订阅模式?
答题思路:
javascript
class EventEmitter { constructor() { this.events = {}; } on(event, callback) { if (!this.events[event]) this.events[event] = []; this.events[event].push(callback); } emit(event, ...args) { this.events[event]?.forEach(cb => cb(...args)); }
}
20. 实现一个函数,判断变量是否为对象
答题思路:
javascript
function isObject(obj) { return obj !== null && (typeof obj === 'object' || typeof obj === 'function');
}