2025前端面试题(加麻加辣)

258 阅读6分钟

https的过程,本地信任证书是为什么?

HTTPS(基于SSL/TLS的安全通信)的核心目标是确保通信的机密性完整性,而证书信任机制是这一目标的关键保障。以下是HTTPS的完整过程,以及本地信任证书的原因:


HTTPS 通信过程

  1. 客户端发起请求

    • 用户访问 https://example.com,浏览器向服务器发起连接请求。
  2. 服务器返回证书

    • 服务器将自身的 SSL/TLS证书(包含公钥、域名、有效期等信息)发送给客户端。
  3. 客户端验证证书

    • 证书链验证:客户端检查证书是否由可信的**证书颁发机构(CA)**签发。
    • 域名匹配:验证证书中的域名是否与访问的域名一致。
    • 有效期检查:确认证书未过期。
    • 吊销状态检查:通过OCSP或CRL列表确认证书未被吊销。
  4. 密钥协商

    • 若证书验证通过,客户端生成一个对称加密密钥(如AES密钥),用服务器的公钥加密后发送给服务器。
    • 服务器用私钥解密获取对称密钥。
  5. 加密通信

    • 双方使用协商的对称密钥加密后续通信数据。

为什么需要本地信任证书?

本地信任证书是为了建立可信的证书链验证体系,解决以下问题:

1. 防止中间人攻击(MITM)

  • 攻击者可能伪造证书冒充目标网站。
  • 本地信任的根证书(CA证书)构成信任锚点,只有由这些CA签发的证书才会被信任。
  • 若证书链无法追溯到本地信任的根证书,浏览器会提示风险(如 NET::ERR_CERT_AUTHORITY_INVALID)。

2. 验证服务器身份

  • 证书中包含了服务器的公钥和域名信息,本地信任机制确保客户端连接的是真实的服务器,而非钓鱼网站。

3. 信任链的建立

  • 根证书:预置在操作系统或浏览器中的顶级CA证书(如DigiCert、Let's Encrypt)。
  • 中间证书:由根CA签发的次级CA证书,形成链式信任关系。
  • 终端实体证书:由中间CA签发给具体域名的证书。

本地证书信任的典型场景

  1. 浏览器访问HTTPS网站

    • 浏览器自动使用内置的根证书库验证服务器证书。
    • 若证书无效(如自签名证书),需手动导入到本地信任库才能继续访问。
  2. 开发环境使用自签名证书

    • 开发者在本地测试HTTPS服务时,需将自签名证书添加到操作系统或浏览器的信任列表,否则会触发安全警告。
  3. 企业内网证书

    • 企业可能使用私有CA签发内部证书,需在所有员工设备上安装企业根证书。

总结

  • HTTPS过程:证书验证 → 密钥协商 → 加密通信。
  • 本地信任证书:确保客户端只接受由可信CA签发的证书,防止身份伪造和数据窃听。
  • 自签名证书:需手动添加到本地信任库,适用于开发和内网环境,但需谨慎操作。

Webpack 和 Vite有什么区别

  • 构建方式: Webpack 通过构建整个项目的依赖图,将所有资源打包成一个或多个 bundle 文件,每次重启都需要打包。Vite 采用了即时编译的方式,在开发模式下通过浏览器原生支持的 ES Module 特性进行加载,不需要打包。

  • 开发体验: Webpack 需要较多的配置,对复杂的项目来说,需要花费时间和精力来配置各种 loader(比如css-loder) 和 plugin。Vite 开箱即用,不需要复杂的配置即可快速启动项目,支持各种插件以满足特定需求。

  • 热更新: Webpack 的热更新通常需要借助 webpack-dev-server 等插件,在一些情况下配置起来比较复杂。Vite 内置了基于浏览器原生模块热更新的开发服务器,无需额外配置即可实现快速的热更新。

前端页面太多导致打包速度慢怎么处理

针对前端页面过多导致的打包速度慢问题,可以通过以下多维度优化策略显著提升构建效率:

一、构建流程分析与瓶颈定位

  1. 可视化分析工具

    # 安装打包分析插件
    npm install webpack-bundle-analyzer --save-dev
    
    // webpack.config.js
    const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
    module.exports = {
      plugins: [new BundleAnalyzerPlugin()]
    };
    
    • 作用:生成依赖体积分布图,定位巨型模块(如未按需加载的组件库)。
  2. 耗时统计工具

    npm install speed-measure-webpack-plugin --save-dev
    
    // webpack.config.js
    const SpeedMeasurePlugin = require('speed-measure-webpack-plugin');
    const smp = new SpeedMeasurePlugin();
    module.exports = smp.wrap({
      // 原配置
    });
    
    • 输出结果:精确显示每个Loader和Plugin的耗时,针对性优化。

二、核心优化手段

  1. 持久化缓存(Webpack5+)

    // webpack.config.js
    module.exports = {
      cache: {
        type: 'filesystem', // 启用文件系统缓存
        buildDependencies: { config: [__filename] } // 缓存失效策略
      }
    };
    
    • 效果:二次构建时间减少50%~70%。
  2. 多进程并行处理

    npm install thread-loader --save-dev
    
    // webpack.config.js
    module.exports = {
      module: {
        rules: [
          {
            test: /\.js$/,
            use: [
              'thread-loader', // 放在其他Loader前
              'babel-loader'
            ]
          }
        ]
      }
    };
    
  3. 缩小构建范围

    // 仅编译源码目录(避免处理node_modules)
    module.exports = {
      module: {
        rules: [
          {
            test: /\.js$/,
            include: path.resolve(__dirname, 'src'),
            use: ['babel-loader']
          }
        ]
      }
    };
    

三、依赖与代码优化

  1. 按需加载第三方库

    • Ant Design (React)
      // .babelrc
      {
        "plugins": [
          ["import", { "libraryName": "antd", "libraryDirectory": "es", "style": "css" }]
        ]
      }
      
    • Lodash
      import _get from 'lodash/get'; // 直接引用子模块
      
  2. 代码分割(SplitChunks)

    // webpack.config.js
    module.exports = {
      optimization: {
        splitChunks: {
          chunks: 'all',
          cacheGroups: {
            vendors: {
              test: /[\\/]node_modules[\\/]/,
              name: 'vendors',
              priority: 10
            }
          }
        }
      }
    };
    
  3. 动态导入(Lazy Loading)

    // React 路由动态加载
    const Home = React.lazy(() => import('./pages/Home'));
    // Vue 异步组件
    const UserProfile = () => import('./views/UserProfile.vue');
    

四、工程化增强

  1. DLL预编译(Webpack4及以下)

    // webpack.dll.config.js
    module.exports = {
      entry: { vendor: ['react', 'react-dom'] },
      output: {
        path: path.join(__dirname, 'dll'),
        filename: '[name].dll.js',
        library: '[name]_dll'
      },
      plugins: [
        new webpack.DllPlugin({
          name: '[name]_dll',
          path: path.join(__dirname, 'dll/manifest.json')
        })
      ]
    };
    
    // 主配置中引用DLL
    new webpack.DllReferencePlugin({
      manifest: require('./dll/manifest.json')
    });
    
  2. 增量编译与热更新优化

    • Vite:替换Webpack,利用ES Module原生加载实现秒级热更新。
    • SWC:替换Babel,用Rust编写的超高速编译器。

五、架构级优化

  1. 微前端拆分

    • 方案:将巨型应用拆分为多个子应用(如主应用、用户中心、管理后台)。
    • 工具qiankunsingle-spa
    • 效果:独立构建、独立部署,彻底解决单体应用膨胀问题。
  2. Monorepo分模块

    # 使用Lerna或Nx管理多包
    lerna init
    
    • 场景:将通用组件、工具库拆分为独立子包,单独构建。

六、环境与硬件优化

  1. SSD与内存升级
  • 机械硬盘 → SSD:文件读写速度提升5~10倍。
  • Node内存限制
    # 启动Node时增加内存限制
    node --max-old-space-size=4096 build.js
    
  1. CI/CD缓存策略
# GitLab CI示例
cache:
  key: ${CI_COMMIT_REF_SLUG}
  paths:
    - node_modules/
    - .cache/

总结

通过以上组合策略,可系统性解决页面过多导致的打包瓶颈。推荐优先级

  1. 启用持久化缓存(Webpack5必选)
  2. 按需加载与代码分割
  3. 升级构建工具链(如Vite/SWC)
  4. 架构拆分(微前端/Monorepo)

什么是高阶函数

高阶函数,你怎么那么漂亮呢!