liuqinh2s' blog

Do something cool!

行内元素和块级元素算是 css 中最基础,也是最重要的部分了。需要彻底掌握才行。

比如,width 和 height 跟父节点和子节点的关系到底是什么,默认是什么?行内元素的 padding 和 margin 能设置吗?

阅读全文 »

这题是数位 dp 类型的题,遍历对象有两个:

  1. 遍历 N 的每一位
  2. 遍历 digits

问题规模是 N 的位数。

状态转移方程是这样思考得出:

在遍历 digits 时,设当前 digits 的值为 digits[i]:

  1. 如果 digits[i]比 N 的第 j 位的数字小,则低位的数字就可以任意,那么由 digits[i]开头所产生的组合数是:digits.length**(j-1)
  2. 如果 digits[i]等于 N 的第 j 位数字,则还要继续对比第 j-1 位才知道能否凑出一个比 N 小的,也即递归,缩小问题规模。产生组合:dp[j-1]
  3. 如果 digits[i]大于 N 的第 j 位数字,则后面低位的数字不管是什么,都已经不能产生小于 N 的组合了。产生组合:0

把每个 digits[i]对应的结果加起来,就是当前问题规模(问题规模为:j)的答案。

状态转移方程:

1
2
3
4
5
if (digits[i] < N[j]) {
dp[j] += digits.length ** (j - 1);
} else if (digits[i] == N[j]) {
dp[j] += dp[j - 1];
}
阅读全文 »

什么是副作用函数?

如果一个函数只是接收输入,然后输出,没有影响外部(比如修改外部变量),那么我们就说这个函数没有副作用,反之就是有副作用。理想的情况下,我们希望所有的函数都很纯粹,没有副作用。

举个例子:

1
2
3
function effect() {
document.body.innerText = "hello vue3";
}
阅读全文 »

每次面试问到了解 React Diff 算法吗?我都不知道说什么,这次总结一下,该怎么说。

首先我们应该思考为什么要有这么一个东西,也就是它的目的是什么?

目的

React Diff 算法的目的是优化真实 DOM 更新,手段是搞一套虚拟 DOM 树,并对比新旧虚拟 DOM 树的差异,然后只对有虚拟 DOM 树中有差异的地方去更新真实 DOM。

时间复杂度:通过启发式策略(如:同层比较、Key 标识)将传统 $$O(n^3)$$ 复杂度降至 O(n)

三大核心策略

  1. Tree Diff(树层比较)
    • 仅比较同一层级节点,跨层级移动会触发销毁和重建(如:节点从父节点 A 移动到节点 B,视为删除后重建),疑问?假如父节点 A、B 是同层级,那么它们的子节点(A+B)算同一层级吗
    • 优化建议:避免频繁跨层级操作,可用 CSS 隐藏代替 DOM 移除
  2. Component Diff(组件比较)
    • 相同类型组件:递归比较子节点,触发更新生命周期(如:componentDidUpdate)
    • 不同类型组件:直接销毁旧组件(触发 componentWillUnmount)并创建新组件(触发 componentDidMount)
  3. Element Diff(元素比较)
    • 节点类型不同:直接替换整个节点(如<div>变为<span>
    • 节点类型相同:仅更新属性和子节点(如修改 className 或文本内容)

Fibber 架构下的优化(React 16+)

  1. 增量更新与任务拆分
    • Diff 过程拆分为可中断的小任务,避免阻塞主线程
    • 高优先级更新(如用户交互)可中断低优先级任务
  2. 更细粒度的协调
    • Fiber 节点保存完整上下文,支持更精准的 Diff 和状态复用
0%