Yuyang 前端小白🥬

问题准备

Vite构建

几大特点

1、冷启动
2、快速热更新
3、bundleless
4、优化构建

特性说明:
1、开发环境冷启动,构建基于ESBuild,线上产物构建 rollup
2、本地HMR,做了很多优化,webpack是不是需要分析依赖图(耗时的),因为开发环境ESM方式请求资源文件
3、配置简单,比parcel还是复杂点

区分环境构建

开发环境 esbuild,bundleless方案进行构建
开发环境 rollup
如果你想在低版本浏览器调试,不好意思,vite不支持,因为vite是基于ESM的,低版本浏览器不支持ESM

热更新原理

建立长链接,websocket

vite/client 插入到客户端
vite websocket 服务

浏览器的热更新需要结合,定义一些事件来处理:connect、disconnect、message
vite/client 会监听文件变化,然后通知vite服务,vite服务会推送到客户端

turbopack

前端工程化

前端工程化方向

1、构建工具
2、自动化测试
3、代码规范
4、性能优化
5、持续集成
6、部署

React性能优化,性能优化指标采集

React性能优化Hooks
1、React.memo
React.memo是一个高阶组件,类似于React.PureComponent,用于函数组件的性能优化,它只会在props发生变化时重新渲染组件,如果props没有发生变化,它会返回上一次的渲染结果,从而避免不必要的渲染。
2、useMemo
useMemo是一个自定义Hook,用于缓存计算结果,它接收一个函数和一个依赖数组,只有依赖数组中的值发生变化时,useMemo才会重新计算结果,否则直接返回上一次的计算结果。
3、useCallback
useCallback是一个自定义Hook,用于缓存函数,它接收一个函数和一个依赖数组,只有依赖数组中的值发生变化时,useCallback才会返回新的函数,否则直接返回上一次的函数。
4、useEffect
useEffect是一个自定义Hook,用于处理副作用,它接收一个函数和一个依赖数组,只有依赖数组中的值发生变化时,useEffect才会执行函数,否则直接返回上一次的执行结果。
5、useLayoutEffect
useLayoutEffect是一个自定义Hook,用于处理副作用,它接收一个函数和一个依赖数组,只有依赖数组中的值发生变化时,useLayoutEffect才会执行函数,否则直接返回上一次的执行结果。

React Hooks实现原理 useEffect的实现原理以及执行时机

React Hooks实现原理:

function组件如何保存状态

1、useState
2、useReducer
3、useRef
4、useMemo
5、useCallback

React事件处理机制是什么?以及为什么?

React事件处理机制是基于合成事件的,React会将原生事件封装成合成事件,然后通过事件委托的方式统一管理事件,从而提高性能。

输入url到页面呈现的过程,以及render树是怎么渲染的

script async和defer的区别

script async和script defer都是用于异步加载脚本的,但是它们之间有一些区别:
1、执行时机
script async是在下载完成后立即执行脚本,不会阻塞页面的渲染,但是执行顺序不确定;
script defer是在DOM解析完成后按照顺序执行脚本,不会阻塞页面的渲染,但是执行顺序是按照顺序执行的。

微任务和红任务

css绘制同心圆

三数之和

状态码

跨域

Promise.all 和 Promise.allSettled

function myPromiseAll(promises) {
return new Promise((resolve, reject) => {
if (!Array.isArray(promises)) {
return reject(new TypeError(“Argument must be an array”));
}

const resultArray = [];
let resolvedCount = 0;

promises.forEach((promise, index) => {
  // 处理非 Promise 对象
  Promise.resolve(promise)
    .then((value) => {
      resultArray[index] = value; // 保存结果在对应位置
      resolvedCount++; // 记录已成功的 Promise 数量

      // 如果所有 Promise 都成功,resolve 返回结果
      if (resolvedCount === promises.length) {
        resolve(resultArray);
      }
    })
    .catch((error) => {
      reject(error); // 一旦有 Promise 失败,立即 reject
    });
});

// 如果传入空数组,直接 resolve
if (promises.length === 0) {
  resolve(resultArray);
}

});
}

// 测试用例
const p1 = Promise.resolve(1);
const p2 = Promise.resolve(2);
const p3 = Promise.resolve(3);

myPromiseAll([p1, p2, p3])
.then((result) => console.log(“成功:”, result)) // 成功: [1, 2, 3]
.catch((error) => console.log(“失败:”, error));

实现一个URL解析

url解析是一个比较复杂的过程,需要考虑很多情况,比如协议、主机、端口、路径、查询参数、锚点等,下面是一个简单的实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function parseUrl(url) {
const urlObject = new URL(url); // 使用 URL 构造函数解析

return {
protocol: urlObject.protocol, // 协议,如 'https:'
host: urlObject.host, // 主机名和端口号,如 'example.com:8080'
hostname: urlObject.hostname, // 主机名,如 'example.com'
port: urlObject.port, // 端口号,如 '8080'
pathname: urlObject.pathname, // 路径,如 '/path/to/resource'
search: urlObject.search, // 查询字符串,如 '?name=John&age=30'
params: Object.fromEntries(new URLSearchParams(urlObject.search)), // 查询参数对象
hash: urlObject.hash // 锚点,如 '#section1'
};
}

// 测试用例
const url = 'https://example.com:8080/path/to/resource?name=John&age=30#section1';
const result = parseUrl(url);
console.log(result);

React.memo/useCallback/useEffect

介绍created和beforeRouteEnter区别 优劣

父子组建生命周期的顺序,为什么是这样的?为什么是在beforeMount的时候渲染子组件?

http和tcp的关系

http状态码以及常见状态码

介绍下三次握手

为什么需要三次

二叉树 求根节点到叶子节点的路径之间数字构成的数总和,如路径4->1->5 表示415,故答案为414+415+436