🧑🏻‍💻前端面试高频考题(万字长文📖)

引言

这篇文章整合了28个前端高频考题,篇幅较长,可以根据目录自行跳转。🚀


一、图片懒加载

1. 概念

图片懒加载是一种优化网页性能的技术,它可以让图片在即将出现在视口(viewport)时才加载,而不是在页面加载时一次性加载所有图片。这样可以减少页面初始加载时间,提高性能。

2. 实现方式

方法 1:使用 loading="lazy"(原生方式)

HTML5 提供了 loading="lazy" 属性,浏览器会自动处理懒加载:

ini 复制代码
<img src="image.jpg" loading="lazy" alt="Lazy Loaded Image">
方法 2:使用 Intersection Observer API

适用于需要兼容更多浏览器的情况:

ini 复制代码
const images = document.querySelectorAll("img[data-src]");
const observer = new IntersectionObserver((entries, observer) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      const img = entry.target;
      img.src = img.dataset.src;
      img.removeAttribute("data-src");
      observer.unobserve(img);
    }
  });
});

images.forEach(img => observer.observe(img));

在 HTML 中:

ini 复制代码
<img data-src="image.jpg" alt="Lazy Loaded Image">

二、大文件上传

1. 问题

直接上传大文件可能导致:

  • 超时问题:网络不好时可能导致上传失败。
  • 服务器压力大:大文件占用带宽,影响并发请求。
  • 断点续传:如果中途断网,重新上传会很耗费时间。

2. 解决方案

  • 分片上传:把大文件拆分成小块(chunk),逐个上传到服务器。
  • 断点续传:记录已上传的部分,断线后继续上传。

3. 实现

前端代码(分片上传 + 断点续传)

ini 复制代码
async function uploadFile(file) {
  const chunkSize = 5 * 1024 * 1024; // 5MB
  const chunks = Math.ceil(file.size / chunkSize);
  
  for (let i = 0; i < chunks; i++) {
    const start = i * chunkSize;
    const end = start + chunkSize;
    const chunk = file.slice(start, end);
    
    const formData = new FormData();
    formData.append("file", chunk);
    formData.append("index", i);
    formData.append("total", chunks);

    await fetch("/upload", { method: "POST", body: formData });
  }
}

后端(Node.js 示例)

ini 复制代码
const fs = require('fs');
const express = require('express');
const app = express();
app.use(express.json());

app.post('/upload', (req, res) => {
  const { file, index, total } = req.body;
  fs.appendFileSync(`./uploads/file_${index}`, file);
  res.send({ status: "ok" });
});

app.listen(3000);

三、异步操作

1. 同步 vs. 异步

  • 同步:代码按顺序执行,阻塞后续操作。
  • 异步 :不会阻塞主线程,比如 setTimeoutfetchPromise

2. Promise & async/await

Promise 示例
javascript 复制代码
function fetchData() {
  return new Promise(resolve => {
    setTimeout(() => resolve("数据加载完成"), 2000);
  });
}

fetchData().then(console.log); // 2秒后打印 "数据加载完成"
async/await
ini 复制代码
async function fetchData() {
  const response = await fetch("https://api.example.com/data");
  const data = await response.json();
  console.log(data);
}
fetchData();

四、axios(HTTP 请求库)

1. axios vs fetch

特性 axios fetch
自动 JSON 解析 ❌ 需 response.json()
拦截器
超时控制
取消请求

2. 基本使用

javascript 复制代码
import axios from "axios";

axios.get("https://api.example.com/data")
  .then(response => console.log(response.data))
  .catch(error => console.error(error));

3. 拦截器

ini 复制代码
axios.interceptors.request.use(config => {
  config.headers.Authorization = "Bearer token";
  return config;
});

五、闭包

1. 定义

闭包是指函数可以访问其外部作用域的变量,即使函数在外部作用域执行

2. 示例

scss 复制代码
function outer() {
  let count = 0; // 外部变量
  return function inner() {
    count++;
    console.log(count);
  };
}

const counter = outer();
counter(); // 1
counter(); // 2

3. 应用场景

  • 数据缓存:避免全局变量污染。
  • 实现私有变量:防止变量被外部修改。
  • 事件监听:封装逻辑,使代码更清晰。

六、防抖与节流

1. 防抖

定义 :防抖是指短时间内多次触发同一事件时,只有最后一次生效 。常用于搜索框输入、窗口大小调整 等场景。
实现

javascript 复制代码
function debounce(fn, delay) {
  let timer;
  return function (...args) {
    clearTimeout(timer);
    timer = setTimeout(() => fn.apply(this, args), delay);
  };
}

// 示例:搜索输入框
const searchInput = document.getElementById("search");
searchInput.addEventListener("input", debounce((e) => {
  console.log("搜索内容:", e.target.value);
}, 500));

2. 节流

定义 :节流是指在一定时间间隔内,只执行一次事件 ,即使它被多次触发。常用于滚动事件、按钮点击 等场景。
实现

javascript 复制代码
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("scroll", throttle(() => {
  console.log("滚动事件触发");
}, 1000));

七、跨域、同源策略和CORS

1. 什么是同源策略?

同源策略(Same-Origin Policy,SOP)是浏览器的一种安全机制,限制不同源的网页互相访问数据 ,避免恶意网站窃取信息。同源协议、域名、端口三者必须一致。

2. 解决跨域的方法

  • CORS(跨域资源共享) (推荐)
    服务端 返回 Access-Control-Allow-Origin 头部:

    javascript 复制代码
    app.use((req, res, next) => {
      res.header("Access-Control-Allow-Origin", "*");
      res.header("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE");
      res.header("Access-Control-Allow-Headers", "Content-Type, Authorization");
      next();
    });
  • JSONP(仅支持 GET)

    xml 复制代码
    <script src="https://api.example.com/data?callback=handleData"></script>
    javascript 复制代码
    function handleData(data) {
      console.log(data);
    }
  • 代理服务器(Nginx/Node.js 代理)

    php 复制代码
    // Node.js 代理
    const { createProxyMiddleware } = require("http-proxy-middleware");
    app.use("/api", createProxyMiddleware({ target: "https://example.com", changeOrigin: true }));

八、事件循环(Event Loop)

1. JavaScript 是单线程的

JavaScript 采用事件循环机制来处理异步任务,避免主线程被阻塞。

2. 事件循环执行顺序

  1. 同步代码 先执行。
  2. 微任务队列(Microtask Queue) (优先):Promise.thenprocess.nextTick
  3. 宏任务队列(Macrotask Queue)setTimeoutsetIntervalsetImmediateI/O

3. 示例

javascript 复制代码
console.log("1"); // 同步任务

setTimeout(() => console.log("2"), 0); // 宏任务

Promise.resolve().then(() => console.log("3")); // 微任务

console.log("4");

执行顺序:1 → 4 → 3 → 2

九、拦截器

拦截器一般用于请求和响应的统一处理 ,例如添加 Token、全局错误处理等。

在 axios 中使用拦截器

ini 复制代码
import axios from "axios";

// 请求拦截器
axios.interceptors.request.use(config => {
  config.headers.Authorization = "Bearer token"; // 添加 Token
  return config;
}, error => Promise.reject(error));

// 响应拦截器
axios.interceptors.response.use(response => {
  return response.data; // 统一处理响应数据
}, error => {
  console.error("请求失败", error);
  return Promise.reject(error);
});

应用场景

  • 自动添加 Token
  • 处理请求失败
  • 统一解析数据格式

十、项目部署上线流程

1. 前端项目部署步骤

  1. 打包构建

    arduino 复制代码
    npm run build
  2. 上传到服务器

    • 方式 1:FTP(FileZilla)

    • 方式 2:SSH(SCP 命令)

      ruby 复制代码
      scp -r dist/ user@server:/var/www/html
  3. 服务器配置

    • Nginx 配置:

      ini 复制代码
      server {
        listen 80;
        server_name example.com;
        root /var/www/html;
        index index.html;
      }
    • 启动 Nginx:

      复制代码
      sudo systemctl restart nginx

2. Node.js 项目部署

  1. 上传代码

    ruby 复制代码
    scp -r myapp/ user@server:/home/user/
  2. 安装依赖

    css 复制代码
    npm install --production
  3. 使用 PM2 进程管理

    sql 复制代码
    npm install -g pm2
    pm2 start app.js
    pm2 save
    pm2 startup

3. Docker 部署

  1. 创建 Dockerfile

    sql 复制代码
    FROM node:18
    WORKDIR /app
    COPY . .
    RUN npm install
    CMD ["node", "app.js"]
  2. 构建并运行

    arduino 复制代码
    docker build -t myapp .
    docker run -d -p 3000:3000 myapp

十一、Promise

1. 什么是 Promise?

Promise 是 JavaScript 中用于处理异步操作的对象,它有三种状态:

  • pending(进行中) :初始状态,异步操作未完成。
  • fulfilled(已完成) :异步操作成功,调用 .then()
  • rejected(已失败) :异步操作失败,调用 .catch()

2. Promise 的基本用法

javascript 复制代码
const myPromise = new Promise((resolve, reject) => {
  setTimeout(() => resolve("成功"), 2000);
});

myPromise.then(data => console.log(data)).catch(err => console.log(err));

3. Promise 链式调用

ini 复制代码
fetch("https://api.example.com/data")
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => console.error("请求失败", error));

4. async/await 语法(更简洁的 Promise 处理方式)

javascript 复制代码
async function fetchData() {
  try {
    const response = await fetch("https://api.example.com/data");
    const data = await response.json();
    console.log(data);
  } catch (error) {
    console.error("请求失败", error);
  }
}
fetchData();

十二、虚拟 DOM

1. 什么是虚拟 DOM?

虚拟 DOM 是 React、Vue 等前端框架 中的轻量级 JavaScript 对象,它是对真实 DOM 的模拟,避免直接操作 DOM,提高性能。

2. 传统 DOM vs. 虚拟 DOM

特性 传统 DOM 虚拟 DOM
直接操作 直接修改真实 DOM 先修改 Virtual DOM,再 diff 对比
速度 变更多时性能较差 变更多时性能较优
适用于 低频更新 高频更新的页面(如 React、Vue)

3. 虚拟 DOM 的核心机制

  • 创建 Virtual DOM:用 JavaScript 对象模拟 DOM 结构。
  • Diff 算法:对比新旧 Virtual DOM,找出变化部分。
  • 批量更新:只更新变更的部分,提高效率。
ini 复制代码
const App = () => {
  const [count, setCount] = React.useState(0);
  return <button onClick={() => setCount(count + 1)}>点击 {count} 次</button>;
};

count 变化时:

  1. 生成新的 Virtual DOM。
  2. 旧 Virtual DOM 对比新 Virtual DOM(Diff)。
  3. 只更新变化的部分,减少 DOM 操作。

十三、JSONP

1. 什么是 JSONP?

JSONP(JSON with Padding)是一种利用 <script> 标签 绕过同源策略的方式,只支持 GET 请求。

2. JSONP 实现原理

前端代码

xml 复制代码
<script>
  function handleData(data) {
    console.log("后端返回的数据:", data);
  }
</script>
<script src="https://api.example.com/data?callback=handleData"></script>

后端返回数据(JSONP 格式)

php 复制代码
handleData({ name: "张三", age: 18 });

缺点

  • 仅支持 GET 请求,不支持 POSTPUT 等。
  • 不如 CORS 灵活,现代项目推荐使用 CORS

十四、注册登录的逻辑

1. 注册逻辑

  1. 前端 :用户输入用户名、密码 → 校验格式 → 发送 POST 请求。

  2. 后端

    • 检查用户名是否已存在。
    • 对密码进行加密存储 (如 bcrypt)。
    • 生成用户 ID,并存入数据库。
  3. 返回注册成功信息

前端代码(React 示例)

javascript 复制代码
async function register(username, password) {
  const response = await fetch("/api/register", {
    method: "POST",
    body: JSON.stringify({ username, password }),
    headers: { "Content-Type": "application/json" }
  });
  const data = await response.json();
  console.log(data);
}

2. 登录逻辑

  1. 前端 :用户输入用户名、密码 → 发送 POST 请求。

  2. 后端

    • 查询数据库,检查用户名是否存在。
    • 对比用户输入的密码与数据库中的加密密码。
    • 生成 JWT(JSON Web Token)并返回。
  3. 前端存储 Token(localStorage/sessionStorage)

后端(Node.js + Express 示例)

ini 复制代码
const jwt = require("jsonwebtoken");

app.post("/login", async (req, res) => {
  const { username, password } = req.body;
  const user = await db.findUser(username);
  
  if (!user || !bcrypt.compareSync(password, user.password)) {
    return res.status(401).json({ message: "用户名或密码错误" });
  }

  const token = jwt.sign({ userId: user.id }, "secret_key", { expiresIn: "1h" });
  res.json({ token });
});

十五、SSR、CSR、SSG

渲染模式 定义 适用场景
CSR(客户端渲染) 浏览器下载 JS 后渲染页面 交互性强的 SPA(单页应用)
SSR(服务器端渲染) HTML 由服务器渲染并返回 SEO 友好、首屏加载快
SSG(静态生成) 构建时生成 HTML,直接部署 文章、博客、营销页

1. CSR(Client-Side Rendering)

  • 流程:HTML 仅包含基本结构 → 加载 JavaScript → 通过 React/Vue 渲染页面。
  • 优点:前端交互流畅,适用于 SPA 应用。
  • 缺点:首屏加载较慢,SEO 不友好。

示例(React 前端渲染):

ini 复制代码
const App = () => {
  const [data, setData] = React.useState(null);

  React.useEffect(() => {
    fetch("/api/data").then(res => res.json()).then(setData);
  }, []);

  return <div>{data ? data.title : "加载中..."}</div>;
};

2. SSR(Server-Side Rendering)

  • 流程:服务器渲染 HTML 并返回,前端仅增强交互。
  • 优点SEO 友好,首屏加载快。
  • 缺点:服务器压力大,不适合高频交互。

示例(Next.js SSR):

javascript 复制代码
export async function getServerSideProps() {
  const res = await fetch("https://api.example.com/data");
  const data = await res.json();
  return { props: { data } };
}

const Page = ({ data }) => <div>{data.title}</div>;
export default Page;

3. SSG(Static Site Generation)

  • 流程:构建时生成静态 HTML,访问时直接返回。
  • 优点 :性能好,适用于博客、文档等页面。
  • 缺点:不适用于频繁更新的数据。

示例(Next.js SSG):

javascript 复制代码
export async function getStaticProps() {
  const res = await fetch("https://api.example.com/data");
  const data = await res.json();
  return { props: { data } };
}

const Page = ({ data }) => <div>{data.title}</div>;
export default Page;

十六、RAG(Retrieval-Augmented Generation)

1. 什么是 RAG?

RAG(检索增强生成)是一种结合信息检索(Retrieval) 生成式 AI(Generation)的技术。它的核心思想是先检索相关数据,再生成文本,以提高模型的回答准确性。

2. RAG 的工作流程

  1. 用户输入问题(Query)。
  2. 检索系统(Retriever)查找相关信息,通常从数据库、知识库或向量索引中检索数据。
  3. 生成模型(Generator)结合检索到的信息,生成最终回答。

3. RAG 的应用

  • 智能问答系统(如 AI 客服、法律咨询)。
  • 代码自动补全(基于已有代码片段生成新代码)。
  • 文档摘要(提取关键信息并生成总结)。

十七、私域

1. 什么是私域?

私域流量 是指企业可以自由掌控 的用户流量,如微信公众号、企业微信群、小程序、CRM 用户库等,相比于公域流量(如搜索引擎、广告流量),私域流量更稳定且转化率更高。

2. 私域流量的优势

  • 降低营销成本:不依赖广告投放,复购率高。
  • 用户忠诚度高:企业可以直接与用户互动,提高品牌粘性。
  • 精准营销:通过用户数据分析,实现个性化推荐。

3. 私域流量的运营方式

  • 建立私域平台(微信群、公众号、小程序)。
  • 提供专属服务(社群互动、福利、会员折扣)。
  • 数据驱动营销(通过用户行为分析,提供个性化内容)。

十八、双 Token

1. 为什么需要双 Token?

  • Access Token:短时间有效,用于快速验证用户身份,减少数据库查询压力。
  • Refresh Token :用于获取新的 Access Token,避免频繁登录。

2. 双 Token 认证流程

  1. 用户登录后,服务器返回 Access TokenRefresh Token
  2. 前端请求 API 时 ,携带 Access Token
  3. 如果 Access Token 过期 ,前端使用 Refresh Token 请求新的 Access Token
  4. 如果 Refresh Token 也过期,要求用户重新登录。

3. 代码示例

后端(Node.js + Express)

ini 复制代码
const jwt = require("jsonwebtoken");

app.post("/refresh-token", (req, res) => {
  const { refreshToken } = req.body;
  try {
    const payload = jwt.verify(refreshToken, "refresh_secret");
    const newAccessToken = jwt.sign({ userId: payload.userId }, "access_secret", { expiresIn: "15m" });
    res.json({ accessToken: newAccessToken });
  } catch (error) {
    res.status(401).json({ message: "Token 失效" });
  }
});

十九、打包工具:Vite 和 Webpack

1. Webpack

  • 特点

    • 支持 模块打包(JS、CSS、图片等)。
    • Tree Shaking(去除无用代码)。
    • 需要复杂的 配置文件(webpack.config.js)
  • 适用场景:适用于大型项目,插件生态丰富。

2. Vite

  • 特点

    • 基于 ESModules,启动快(不需要预打包)。
    • HMR(热更新)更快
    • 默认使用 Rollup 进行生产环境打包。
  • 适用场景:适用于现代前端框架(Vue、React)。

3. Webpack vs. Vite

特性 Webpack Vite
启动速度 慢(构建整个项目) 快(ESModules + 按需加载)
HMR(热更新) 依赖打包 更快
适用场景 传统项目、大型应用 现代前端(Vue、React)

示例:Vite 快速启动 Vue 项目

perl 复制代码
npm create vite@latest my-vue-app --template vue
cd my-vue-app
npm install
npm run dev

二十、TypeScript(TS)

1. 什么是 TypeScript?

TypeScript(TS)是 JavaScript 的超集,添加了静态类型检查,让代码更安全、更可维护。

2. TypeScript 的主要特性

  • 静态类型number, string, boolean
  • 接口(Interface)
  • 泛型(Generics)
  • 类型推导
  • 强大的 IDE 提示

3. 基本用法

typescript 复制代码
// 定义变量
let username: string = "张三";
let age: number = 25;

// 接口
interface User {
  name: string;
  age: number;
}
const user: User = { name: "李四", age: 30 };

// 函数类型
function greet(user: User): string {
  return `你好, ${user.name}`;
}

4. TypeScript 与 JavaScript 的区别

特性 JavaScript TypeScript
类型检查 动态类型(运行时报错) 静态类型(编译时报错)
可维护性 适合小型项目 适合大型项目
开发体验 依赖文档 强类型支持

5. TypeScript 适用于哪些场景?

  • 大型项目(多人协作时,减少错误)。
  • React/Vue 组件开发
  • Node.js 后端开发(如 NestJS)。

二十一、路由守卫

1. 什么是路由守卫?

路由守卫是前端框架(如 Vue Router、React Router)提供的拦截路由跳转 的机制,通常用于权限校验登录验证等场景。

2. Vue Router 路由守卫

  • 全局前置守卫(beforeEach) :进入某个路由前触发。
  • 全局后置守卫(afterEach) :进入路由后触发。
  • 组件内守卫(beforeRouteEnter) :在组件加载前执行。
javascript 复制代码
// Vue Router 全局前置守卫
router.beforeEach((to, from, next) => {
  const isAuthenticated = !!localStorage.getItem("token");
  if (to.meta.requiresAuth && !isAuthenticated) {
    next("/login"); // 未登录跳转到登录页
  } else {
    next(); // 允许访问
  }
});

3. React Router 路由守卫

javascript 复制代码
import { Navigate } from "react-router-dom";

const PrivateRoute = ({ children }) => {
  const isAuthenticated = !!localStorage.getItem("token");
  return isAuthenticated ? children : <Navigate to="/login" />;
};

// 使用 PrivateRoute 保护页面
<Route path="/dashboard" element={<PrivateRoute><Dashboard /></PrivateRoute>} />

二十二、输入 URL 到页面渲染的整个流程

  1. DNS 解析 :将 www.example.com 解析为 IP 地址。

  2. TCP 连接 :使用 TCP 三次握手 连接服务器。

  3. 发送 HTTP 请求 :浏览器向服务器发送 GET 请求。

  4. 服务器处理请求:后端查询数据库,返回 HTML/CSS/JS。

  5. 浏览器解析 HTML

    • 解析 HTML,构建 DOM 树。
    • 解析 CSS,构建 CSSOM 树。
    • 解析 JS,执行脚本(可能会阻塞)。
  6. 构建 Render Tree:结合 DOM 树和 CSSOM 生成渲染树。

  7. 布局(Layout) :计算元素的大小和位置。

  8. 绘制(Painting) :像素渲染并显示到屏幕。

二十三、History 和 HashHistory

1. Hash 路由(HashHistory)

  • 使用 URL 中的 #(如 http://example.com/#/home)。
  • 变化不会触发 HTTP 请求,适用于单页应用(SPA)
javascript 复制代码
window.addEventListener("hashchange", () => {
  console.log("Hash 改变了", location.hash);
});

2. History 路由(History API)

  • 通过 pushState()replaceState() 修改 URL,不依赖 #
  • 需要服务器支持,否则刷新会返回 404。
javascript 复制代码
history.pushState({}, "", "/newpage");
window.onpopstate = () => console.log("浏览器后退/前进");
方式 适用场景 特点
HashHistory 旧浏览器兼容 URL 有 #,不会请求服务器
History API 现代应用 需要后端配置,URL 更简洁

二十四、DNS(Domain Name System)

1. DNS 解析流程

  1. 浏览器缓存:检查是否已有域名的 IP 解析记录。

  2. 系统缓存:查询操作系统的 DNS 解析缓存。

  3. 本地 DNS 服务器(ISP 提供)查询记录。

  4. 递归查询

    • 根 DNS 服务器 (返回 .com 顶级域名服务器)。
    • 顶级域名(TLD)服务器 (返回 example.com 的权威 DNS 服务器)。
    • 权威 DNS 服务器 (返回 www.example.com 的真实 IP)。
  5. 返回 IP 地址,浏览器使用该 IP 访问网站。

2. DNS 解析的优化

  • DNS 预解析(DNS Prefetch)

    ini 复制代码
    <link rel="dns-prefetch" href="//cdn.example.com">
  • CDN 加速(分布式 DNS 提供就近解析)。

  • 减少 DNS 查询次数(合并域名,避免多次查询)。

二十五、原型和原型链

1. 原型链的工作原理

当访问对象的某个属性或方法时:

  1. 先在对象自身查找该属性。
  2. 如果找不到,则沿着 prototype 继续向上查找其原型对象。
  3. 依次查找,直到找到该属性,或者查找到 null 终止(说明属性不存在)。

示例代码:

javascript 复制代码
function Person(name) {
  this.name = name;
}
Person.prototype.sayHello = function () {
  console.log(`Hello, my name is ${this.name}`);
};

const p1 = new Person("Alice");

p1.sayHello(); // "Hello, my name is Alice"
console.log(Object.getPrototypeOf(p1) === Person.prototype); // true
console.log(Object.getPrototypeOf(Person.prototype) === Object.prototype); // true
console.log(Object.getPrototypeOf(Object.prototype) === null); // true

其原型链结构如下:

javascript 复制代码
p1 --> Person.prototype --> Object.prototype --> null

2. __proto__ 的废弃及替代方案

过去,__proto__ 被用于访问对象的原型,例如:

ini 复制代码
console.log(p1.__proto__ === Person.prototype); // true

__proto__ 不是标准的一部分,已被 废弃(deprecated) 。ES6 提供了更好的替代方案:

  • 获取原型Object.getPrototypeOf(obj)
  • 设置原型Object.setPrototypeOf(obj, prototype)

推荐的做法:

javascript 复制代码
console.log(Object.getPrototypeOf(p1) === Person.prototype); // 推荐方式

尽管 __proto__ 仍然在现代浏览器中保留以实现兼容性,但在新的代码中建议使用 Object.getPrototypeOf 代替,以符合现代 JavaScript 的最佳实践。

3. 原型链的作用

  • 实现继承 :子类可以通过 prototype 继承父类的方法。
  • 共享方法:减少重复定义,提高内存使用效率。

二十六、深拷贝和浅拷贝

1. 什么是浅拷贝?

浅拷贝仅复制对象的第一层,如果对象属性是引用类型(如数组、对象),则拷贝的只是引用,修改拷贝对象的引用属性会影响原对象。

示例(浅拷贝):

ini 复制代码
const obj1 = { name: "张三", info: { age: 25 } };
const obj2 = { ...obj1 };

obj2.name = "李四";  // 不影响 obj1
obj2.info.age = 30;  // 影响 obj1,因为 info 是引用类型

console.log(obj1.info.age);  // 输出 30

浅拷贝方法:

  • Object.assign({}, obj)
  • 展开运算符 { ...obj }
  • Array.prototype.slice()(适用于数组)

2. 什么是深拷贝?

深拷贝会递归复制所有层级,即使对象中包含嵌套对象或数组,拷贝后两个对象完全独立,互不影响。

示例(深拷贝):

ini 复制代码
const obj1 = { name: "张三", info: { age: 25 } };

// JSON 方式
const obj2 = JSON.parse(JSON.stringify(obj1));

obj2.info.age = 30;  // 不影响 obj1

console.log(obj1.info.age);  // 输出 25

深拷贝方法:

  • JSON 方法JSON.parse(JSON.stringify(obj)),但不能处理 undefinedfunctionSymbol 等特殊值)
  • Lodash _.cloneDeep(obj)
  • 递归手写深拷贝
javascript 复制代码
function deepClone(obj) {
  if (typeof obj !== "object" || obj === null) return obj;
  const newObj = Array.isArray(obj) ? [] : {};
  for (let key in obj) {
    newObj[key] = deepClone(obj[key]); // 递归拷贝
  }
  return newObj;
}

二十七、HTTP 和 HTTPS

1. HTTP 与 HTTPS 区别

特性 HTTP HTTPS
安全性 明文传输,容易被攻击 加密传输,数据更安全
端口号 80 443
证书 不需要 需要 SSL 证书
速度 相对较慢(因加密解密)

2. HTTPS 如何保障安全?

  1. 对称加密(AES) :双方使用相同密钥加密和解密,速度快但密钥易被盗。
  2. 非对称加密(RSA) :服务器生成公钥,客户端加密数据,服务器用私钥解密,安全性高但速度慢。
  3. SSL/TLS:结合对称加密和非对称加密,使用证书机构(CA)验证网站身份,防止中间人攻击。

3. HTTPS 握手过程

  1. 客户端请求 HTTPS 站点,服务器返回 SSL 证书(包含公钥)。
  2. 客户端验证证书(确保证书有效)。
  3. 客户端生成会话密钥,用公钥加密并传输给服务器。
  4. 服务器使用私钥解密,并使用会话密钥进行后续通信(对称加密)。
  5. 通信建立,数据加密传输

二十八、SEO(搜索引擎优化)

SEO(Search Engine Optimization)是指优化网站,使其在搜索引擎中排名更高,提高流量。

1. SEO 主要策略

  • 站内优化

    • HTML 语义化 (使用 <h1><p><article> 等标签)。
    • URL 规范化 (使用清晰的 URL,如 /products/shoes)。
    • 关键词优化 (在 <title>meta description、内容中合理布局关键词)。
    • 网站地图(Sitemap) 提交给搜索引擎。
    • robots.txt 控制爬虫抓取范围。
  • 站外优化

    • 外链建设(高质量网站的反向链接提升权重)。
    • 社交媒体推广(增加品牌曝光度)。
    • 提高网站访问速度(使用 CDN、压缩资源)。

2. 前端如何优化 SEO?

  • SSR(服务器端渲染) :提升搜索引擎可见性,如 Next.js、Nuxt.js。

  • 静态生成(SSG) :生成静态页面,提高加载速度,如 VitePress、Gatsby。

  • 图片优化 :使用 alt 属性,让搜索引擎识别图片内容:

    ini 复制代码
    <img src="shoes.jpg" alt="红色运动鞋">
  • Schema 结构化数据:让搜索引擎理解内容:

    less 复制代码
    <script type="application/ld+json">
    {
      "@context": "https://schema.org",
      "@type": "Article",
      "headline": "SEO 最佳实践",
      "author": { "@type": "Person", "name": "张三" }
    }
    </script>

结语

这是目前碰到的面试题,后续还会继续更新。🧑🏻‍💻主播还在学习中......

相关推荐
程序员马晓博10 分钟前
Cursor VS Trae, 深度对比第二弹
前端
陈大鱼头1 小时前
CSS 2020-2025:六年演进与革新全景图
前端·css
最新资讯动态1 小时前
“官方网站+公开课程”双赋能,鸿蒙游戏开发者服务焕新升级
前端
京东零售技术1 小时前
在京东做技术是种什么体验?| 13位零售人告诉你答案
前端·后端·面试
藏在歌词里1 小时前
ruoyi-vue部署2
前端·javascript·vue.js
她的双马尾1 小时前
CSS3 基础布局技术与响应式设计
前端·css·css3
uhakadotcom1 小时前
Prompt Flow 入门:简化 AI 应用开发流程
后端·面试·github
uhakadotcom1 小时前
ONNX Runtime入门:高效深度学习推理框架
后端·面试·github
small_wh1te_coder1 小时前
超硬核区块链算法仿真:联盟链PBFT多线程仿真实现 :c语言完全详解版
前端·stm32·单片机·嵌入式硬件·算法·区块链·共识算法
uhakadotcom1 小时前
PyTorch FSDP:大规模深度学习模型的数据并行策略
后端·面试·github