React虚拟DOM的进化之路

引言

在Web前端开发中,用户交互的流畅性和页面性能一直是核心挑战。早期,开发者直接操作真实DOM(Document Object Model)时,频繁的重排(reflow)和重绘(repaint)导致性能瓶颈,用户体验大打折扣。React团队引入虚拟DOM(Virtual DOM)作为革命性的抽象层,旨在通过声明式UI编程(Declarative UI Programming)简化开发并提升性能。然而,随着Web应用复杂度剧增,传统虚拟DOM的同步更新模型暴露了局限性,如卡顿(Jank)和交互延迟。本博客将深入剖析React虚拟DOM的演进历程,从基础Diffing算法到Fiber架构和并发渲染,揭示底层技术突破如何将用户体验推向极致。

通过阅读本文,读者将系统学习以下关键知识和技能:

  • ​DOM操作成本原理​​:掌握真实DOM重排/重绘的机制及性能瓶颈。

  • ​虚拟DOM核心概念​​:理解虚拟DOM作为轻量级抽象层的设计思路与Diffing算法原理。

  • ​Fiber架构细节​​:学习React如何重构底层引擎以实现可中断渲染(Interruptible Rendering)。

  • ​并发特性实战​​:掌握React 18+的自动批处理(Automatic Batching)、Transition和Suspense,优化异步场景。

  • ​性能指标应用​​:应用核心Web Vitals(如FID、INP、LCP)衡量用户体验。

  • ​前瞻技术趋势​​:探索React编译时优化(如React Forget)和服务器组件的发展方向。

无论你是初级开发者还是资深架构师,本文将通过代码示例、图解和权威引用,助你构建高性能React应用的洞察力。


大纲

  1. ​导言:问题与初衷​

    • DOM操作的成本之痛

    • React的革命性思路:虚拟DOM的诞生

    • 进化的驱动力:同步更新模型的挑战

  2. ​第一部分:奠基——基础虚拟DOM与Diffing算法 (React 15时代)​

    • 核心机制详解

    • 关键优化与贡献:批量操作与同层比较

    • 时代的局限性:全量Diff与同步阻塞

  3. ​第二部分:重构——Fiber架构:为并发而生的引擎 (React 16革命)​

    • 突破瓶颈的雄心:可中断渲染的目标

    • Fiber核心变革:工作单元拆解与链表结构

    • 虚拟DOM演变:从原子Diff到增量协调

  4. ​第三部分:腾飞——并发特性:智能化与流畅体验 (React 18+实践)​

    • 并发渲染的含义与机制

    • 核心并发特性详解:自动批处理、Transition和Suspense

    • 虚拟DOM新高度:优先级驱动与异步协作

  5. ​第四部分:回顾、总结与展望​

    • 技术演进图谱梳理

    • 虚拟DOM在React体系的核心地位

    • 开发者启示与实践建议

    • 未来展望:编译时优化与服务端组件

  6. ​结语​

  7. ​附录​


导言:问题与初衷

Web开发的早期阶段,开发者直接操作真实DOM(Document Object Model),但DOM操作本质上是昂贵的浏览器渲染行为。DOM表示页面元素树结构,每当元素样式或布局变化时,浏览器必须执行重排(reflow)和重绘(repaint)。重排涉及计算元素的新位置,重绘则更新像素到屏幕。一次简单的元素属性变更可能触发链式反应。例如,JavaScript中改变一个DOM节点的宽度:

const element = document.getElementById('myElement');
element.style.width = '50%'; // 触发重排和重绘

当DOM树庞大时,频繁操作会导致渲染线程(main thread)阻塞,造成UI卡顿。React团队的初衷是提供一种高性能抽象层——虚拟DOM(Virtual DOM)。它本质上是一个轻量级JavaScript对象树,描述真实DOM的结构(如节点类型、属性和子节点)。通过声明式UI编程(Declarative UI Programming),开发者只需描述期望的UI状态,React在内部基于Diffing算法找出最小变更集,实现批量提交。然而,React早期(15时代)的同步更新模型无法中断渲染任务,在面对复杂动画或异步数据加载时,导致主线程阻塞和新一代性能瓶颈(如交互延迟)。这成为驱动虚拟DOM进化的核心驱动力。


第一部分:奠基——基础虚拟DOM与Diffing算法 (React 15时代)

React 15奠定了虚拟DOM框架的核心,通过Diffing算法实现了高效UI更新。本部分详解其机制、优化和局限。

核心机制详解

虚拟DOM(Virtual DOM)是React的核心抽象层。它是JavaScript对象树,每个节点(节点类型:节点属性)映射真实DOM元素。当应用状态变更时,React重新执行渲染函数(render function),生成新虚拟DOM树。比较新旧树的过程称为协调(Reconciliation),通过Diffing算法计算差异(Diff),然后将最小变更集批量提交(Commit)到真实DOM。

以React组件为例,定义一个简单函数组件:

function MyComponent(props) {return (<div className="container"><p>{props.text}</p></div>);
}
// 调用:生成虚拟DOM树结构
const vdomTree = MyComponent({ text: 'Hello World' });
// vdomTree对象示例:{
//   type: 'div',
//   props: { className: 'container' },
//   children: [{ type: 'p', props: {}, children: ['Hello World'] }]
// }

Diffing算法在协调阶段进行同步递归比较:

  1. ​节点类型变更​​:如果节点类型不同(如从div变为p),则直接替换整个子树。

  2. ​属性变更​​:通过深度遍历比较props,收集差异(如添加、删除或更新属性)。

  3. ​子节点比较​​:算法在同层比较子节点列表,基于Key属性识别节点移动。

算法核心是启发式规则(Heuristic rules),避免O(n³)复杂度。其时间复杂度控制在O(n)级(n为树节点数),确保了性能基准值(Benchmark)。

关键优化与贡献:批量操作与同层比较

React 15引入两项核心优化,显著减少DOM操作:

  • ​批量操作(Batching)​​:多个状态更新在同一事件循环内被合并为一个渲染批次。这通过 事件委托(Event Delegation) 实现,减少直接DOM调用次数。如setState调用:

    setCount(1); // 第一次更新
    setCount(2); // 第二次更新,React 15合并为一次渲染
    
  • ​同层比较与Key作用​​:Diffing算法仅比较同层节点(而非跨层递归),Key属性用于标识节点稳定性(如列表渲染中避免不必要重新排序)。例:

    <ul>{items.map(item => <li key={item.id}>{item.name}</li>)}
    </ul>
    

    如果Key稳定,算法高效处理节点移动而非重建。

时代的局限性:全量Diff与同步阻塞

尽管优化有效,但React 15有两大局限:

  1. ​“全量”Diff成本​​:Diffing算法执行同步递归(Synchronous Recursion),即整个虚拟DOM树必须一次性比较完成。对于大型应用(如1000+节点树),协调时间可能超过16ms(浏览器帧时长),导致掉帧(Jank)。

    状态变更
    生成新VDOM树
    同步递归Diff
    生成变更集
    批量提交到真实DOM
  2. ​不可中断更新​​:渲染任务在主线程单线程运行,无法中断高优先级任务(如用户输入)。例如,一个长列表渲染阻塞输入响应,造成卡顿。性能指标如 FID(First Input Delay) 难以优化。

这推动了React团队重构底层架构,引入Fiber引擎。


第二部分:重构——Fiber架构:为并发而生的引擎 (React 16革命)

React 16的Fiber架构是引擎级革命,旨在实现可中断渲染(Interruptible Rendering),解决同步阻塞问题。它不仅仅是优化,而是将虚拟DOM协调模型重构为增量式。

突破瓶颈的雄心:可中断渲染的目标

核心目标是让渲染任务成为可中断工作单元(Work Unit),优先处理高优先级交互。例如,用户输入(如按键)应比后台数据渲染响应更快。这需要打破递归调用栈限制,实现暂停、恢复机制。Fiber架构为React提供了基础设施支持(Infrastructure Support),为后续并发特性铺路。

Fiber核心变革:工作单元拆解与链表结构

Fiber(纤程) 是新的协调引擎和数据结构,代表虚拟DOM节点的升级版(即每个节点对应一个Fiber对象)。核心变革包括:

  • ​工作单元拆解(Incremental Rendering)​​:整个渲染过程分解为基于单个Fiber节点的独立工作单元(Work Units)。每个工作单元很小(如比较一个节点),可逐步执行。

    启动渲染
    处理节点
    节点完成
    移至下一个节点
    全部完成
    中断(如高优先级任务)
    恢复后继续
    RenderRoot
    BeginWork
    CompleteWork
    Next
    Pause
    Resume
  • ​链表结构(Linked List Structure)​​:Fiber节点使用链表连接(而非递归栈),支持双向移动(如childsiblingreturn指针)。这打破了调用栈深度限制,实现暂停和回溯(Backtrack)。例如,一个Fiber对象定义:

    const FiberNode = {tag: 'HostComponent', // 节点类型key: 'key1',elementType: 'div', // 对应真实DOM元素类型stateNode: null, // 链接真实DOMreturn: parentFiber, // 父节点child: childFiber, // 首个子节点sibling: nextSibling, // 同级兄弟节点memoizedProps: { className: 'container' }, // 当前propsalternate: workInProgressFiber, // 指向备用树节点// 其他字段:优先级、更新队列等
    };
    

    在diff比较中,React从根节点开始,逐节点执行beginWorkcompleteWork函数。

  • ​双缓存策略(Double Buffering)​​:维护两棵树——当前树(Current Tree) 展示UI,工作树(WorkInProgress Tree) 在内存构建。完成后再一次性切换(swap),避免半成品渲染。

  • ​优先级调度(Scheduler)​​:工作单元按优先级分配。React Scheduler模块基于任务类型(如事件、动画)划分级别,优先处理高优先级工作。代码实现通过requestIdleCallback或宏任务模拟:

    // Scheduler简化实现
    function scheduleWork(priority, task) {if (priority === 'High') {requestAnimationFrame(task); // 高优先级(如输入)} else {setTimeout(task, 0);         // 低优先级(如数据加载)}
    }
    

虚拟DOM在Fiber中的演变

虚拟DOM在Fiber架构下不再是“原子操作”。Diff计算分散到各个Fiber节点的beginWork过程中:

  • ​增量协调​​:算法逐个处理Fiber节点,随时暂停响应高优先级更新。

  • ​VDOM树比较​​:无需全量生成新树;工作树逐步构建差异集。

如React DevTools可观察Fiber树结构,理解其高效性,而Fiber架构也成为了并发渲染的基石。


第三部分:腾飞——并发特性:智能化与流畅体验 (React 18+实践)

React 18引入并发渲染(Concurrent Rendering),利用Fiber架构实现智能化调度,显著提升复杂场景流畅度。

并发渲染的含义与机制

并发渲染指React同时准备多个UI状态,根据优先级智能选择提交时机。核心是 时间切片(Time Slicing)任务插队(Task Preemption)。例如,更新分为紧急Urgent,如输入)和非紧急Transition,如页面导航)。这通过Fiber的优先级系统实现,提升 INP(Interaction to Next Paint) 指标。

核心并发特性详解

React 18+提供API级优化,本部分结合代码和图形详解。

  • ​自动批处理(Automatic Batching)​​:

    ​问题解决​​:减少多次setState触发多余渲染(如事件循环内多个异步调用)。

    ​机制​​:React默认合并同一事件源的更新(如PromisesetTimeout)。代码示例:

    function MyComponent() {const [count, setCount] = useState(0);const handleClick = () => {fetchData().then(() => {setCount(1); // 第一个更新setCount(2); // 第二个更新,React 18+自动批处理为一次渲染});};return <button onClick={handleClick}>Click</button>;
    }
    

    ​对VDOM影响​​:基于合并状态计算一次Diff,减少协调开销。

    BrowserDeveloperReactSystemUser性能提升
    用户操作
    用户操作
    User
    点击按钮
    点击按钮
    System
    API请求
    API请求
    Developer
    setState调用
    setState调用
    React
    批处理更新
    批处理更新
    React
    渲染VDOM
    渲染VDOM
    Browser
    更新真实DOM
    更新真实DOM
    优化效果
    优化效果
    性能提升
    减少渲染次数
    减少渲染次数
    自动批处理用户交互流程
  • ​Transition(startTransition / useTransition)​​:

    ​问题解决​​:区分紧急和非紧急更新,避免低优先级任务阻塞交互。

    ​机制​​:用startTransition包裹非紧急更新(如页面跳转)。React可中断其渲染,优先处理紧急更新。代码示例:

    import { useState, useTransition } from 'react';function App() {const [resource, setResource] = useState(initialData);const [isPending, startTransition] = useTransition();const handleNavigate = () => {startTransition(() => { // 非紧急更新setResource(fetchNewData()); // 大数据加载});};return (<div>{isPending ? 'Loading...' : <DataView data={resource} />}<button onClick={handleNavigate}>Navigate</button></div>);
    }
    

    ​对VDOM影响​​:非紧急VDOM树的构建可中断丢弃,紧急树优先生成。时序图演示优先级处理:

    UserReactBrowser触发输入(紧急优先级)暂停非紧急Transition任务提交紧急VDOM变更响应输入(低延迟)恢复Transition任务提交非紧急变更UserReactBrowser
  • ​Suspense for Data Fetching​​:

    ​问题解决​​:改善数据加载体验(如“瀑布流”请求导致白屏)。

    ​机制​​:组件声明式表达等待状态(fallback UI),React暂停子树渲染。数据就绪后恢复。代码示例:

    import { Suspense } from 'react';function DataComponent() {const data = fetchData(); // 异步函数,支持Suspensereturn <div>{data}</div>;
    }
    function App() {return (<Suspense fallback={<Spinner />}> <DataComponent /> </Suspense>);
    }
    

    ​对VDOM影响​​:VDOM渲染暂停恢复,深度集成异步数据流。状态图展示:

    组件挂载
    数据未就绪,显示fallback
    数据就绪
    恢复渲染VDOM
    完成
    数据加载失败
    Mounting
    Suspended
    Ready
    Rendering
    Error

虚拟DOM新高度

虚拟DOM进化到优先级驱动(Priority-Driven)、可中断恢复和异步协作的新阶段。性能基准显示,并发特性提升 LCP(Largest Contentful Paint) 30%(来源:React Conf 2021)。开发者工具可监控并发行为,提供可视化洞察。


第四部分:回顾、总结与展望

本部分复盘虚拟DOM技术演进图谱,阐述其在React体系中的价值,并为开发者提供前瞻指导。

技术演进时间线梳理

React虚拟DOM的进化主线一致围绕“性能+体验”目标:

  • ​基础阶段(VDOM)​​:通过Diffing算法实现批量优化(Batching)

  • ​重构阶段(Fiber)​​:引入可中断协调(Interruptible Reconciliation)

  • ​腾飞阶段(并发特性)​​:智能化调度提升流畅性。

在这里插入图片描述

虚拟DOM在React体系中的核心地位

虚拟DOM始终是声明式UI的核心抽象。Fiber和并发特性是优化执行效率和智能度的手段,而非替代虚拟DOM。开发者应理解底层原理:

  • 通过React DevTools监控Fiber树结构。

  • 合理使用API:如useTransition减少卡顿。

开发者启示与实践建议
  • ​性能优化实践​​:优先用Suspense处理数据加载;对非紧急操作包裹startTransition

  • ​编写高效代码​​:避免大型组件树;稳定Key属性。

未来展望(React 19及未来)

React 19的正式发布标志着虚拟DOM技术进入新纪元,团队创新重心转向编译时优化、深度服务端集成和细粒度响应控制。本部分将基于React 19稳定版特性,前瞻技术演化方向。


1. ​编译时优化正式落地:React Compiler​

React 19的明星特性——React Compiler(原React Forget项目)完成从实验到生产的蜕变,实现对虚拟DOM运行时的颠覆性优化。

​核心革新原理:​

组件代码
React Compiler
静态分析
依赖图构建
变更路径预计算
生成优化后代码
运行时直接应用差分
  • ​备忘录模式编译器(Memoization Compiler)​​:通过静态分析JSX和Hook依赖,自动生成等效于useMemo/useCallback的高效代码

  • ​变更路径预计算​​:在编译阶段标记不可变数据路径,跳过运行时属性递归比较

  • ​基准效益​​:官方测试显示组件重渲染减少30-70%,虚拟DOM比较开销降低40%+

// 编译前代码
function UserCard({ user }) {return (<div><h2>{user.name}</h2><p>{user.bio}</p></div>);
}// 编译后等价代码(概念示意)
const _cached = memoize((user) => [user.name, user.bio]);
function UserCard_compiled({ user }) {return _cached(user, (name, bio) => (<div><h2>{name}</h2><p>{bio}</p></div>));
}

​开发者影响:​

  1. 告别手动记忆化优化,编译器自动处理组件纯度

  2. 虚拟DOM层更聚焦动态变更,静态子树直接被跳过

  3. 构建配置新增编译器集成:

    // vite.config.js
    import reactCompiler from 'react-compiler-plugin';export default {plugins: [reactCompiler()]
    }
    

官方资源:React Compiler深度指南


2. ​​服务端组件(RSC)生产级支持​

React 19宣布服务端组件(Server Components) 结束实验阶段,成为稳定特性,重塑虚拟DOM的分层协作模型。

​架构变革图示:​

在这里插入图片描述

​虚拟DOM新工作流:​

  1. ​服务端预渲染​​:服务器组件执行生成​​序列化虚拟DOM​​(非HTML)

  2. ​智能补丁传输​​:客户端只需拉取动态部分VDOM差异

  3. ​混合水合(Hydration)​​:客户端将静态VDOM绑定事件处理器

// 服务端组件:直接访问数据库
async function UserProfile({ id }) {const user = await db.users.get(id);  // 服务端执行return (<><h1>{user.name}</h1>{/* 客户端组件标记 */}<CommentsSection client:load />  </>);
}// 客户端组件:处理交互
'use client';
function CommentsSection() {const [comments, setComments] = useState([]);// ...交互逻辑
}

​性能突破:​

  • LCP(Largest Contentful Paint) 提升50%+,因首屏VDOM更小

  • 服务端树摇(Tree Shaking) 移除未使用JS代码

  • 全栈数据类型安全(通过TypeScript类型透传)


3. ​​响应式增强:细粒度更新原语​

React 19 引入 use Hook 和准标准​​信号(Signals)​​支持,实现虚拟DOM的靶向更新。

​信号(Signal)与虚拟DOM集成:​

SignalVDOMDOM状态变更通知标记脏组件路径仅更新相关子树SignalVDOMDOM

​示例:细粒度列表更新​

import { use, signal } from 'react';// 创建信号
const todos = signal([{ id: 1, text: 'Learn React 19', done: true }
]);function TodoList() {// 使用信号(自动追踪依赖)const list = use(todos); return (<ul>{list.map(todo => (// 仅当todo变更时重渲染此项<MemoizedTodo key={todo.id} todo={todo} />))}</ul>);
}function MemoizedTodo({ todo }) {// 内部使用use绑定,独立更新const t = use(todo);return <li>{t.text}</li>;
}// 更新:直接修改信号
todos.value[0].done = false; // 自动触发精准更新

​优化优势:​

  1. 避免全组件树虚拟DOM比较

  2. 长列表场景O(1)复杂度更新

  3. 与并发渲染深度集成:

    startTransition(() => {// 批处理信号更新todos.update(list => [...list, newItem]);
    });
    

4. ​​视觉性能突破:离屏渲染集成​

React 19利用 ​​OffscreenCanvas API​​ 实现隐藏态渲染,扩展虚拟DOM非阻塞渲染能力。

​应用场景实现:​

Canvas切换Offscreen CanvasReactUser
页面加载
页面加载
React
首屏渲染
首屏渲染
Offscreen Canvas
后台预渲染
后台预渲染
用户交互
用户交互
User
标签切换
标签切换
Canvas切换
瞬时显示
瞬时显示
离屏渲染用户旅程

​技术实现:​

import { useOffscreen } from 'react-offscreen';function Dashboard() {const { Offscreen, show } = useOffscreen();return (<div><Tabs onChange={show}><Tab label="报表" /><Tab label="设置" /></Tabs><Offscreen name="报表"><ComplexChart /> {/* 在后台Canvas渲染 */}</Offscreen><Offscreen name="设置"><SettingsPanel /></Offscreen></div>);
}

​性能收益:​

  • FPS(Frames Per Second) 稳定60+帧

  • 交互响应延迟<50ms(INP核心指标)

  • 内存复用虚拟DOM树,切换零成本


演进路线总结

在这里插入图片描述

React 19推动虚拟DOM进入「编译+服务端+响应式」三位一体时代:

  1. ​运行时优化​​:虚拟DOM比较负载显著降低

  2. ​架构范式迁移​​:从纯客户端到服务端驱动分层VDOM

  3. ​交互体验突破​​:通过信号实现靶向更新

团队技术展望表明,虚拟DOM模型将持续演进为更智能的UI协调层,与新兴Web标准(如View Transition API)深度集成,终极目标是实现零感知延迟的用户体验。


结语

React虚拟DOM的进化历程,展示了团队如何通过底层架构革新(如Fiber引擎)和用户中心特性(如并发渲染),从性能优化迈向极致体验。理解这些演变不仅提升技术储备,更是构建高性能应用的关键洞察:高效利用优先级调度减少Jank,优化核心Web Vitals指标。作为开发者,持续跟进React演进(如React 19前瞻),应用最佳实践,方能打造流畅、响应式的现代Web体验。


附录

  • ​权威链接​​:

    • React官方文档:列表渲染

    • MDN渲染性能指南:Web performance | MDN

  • ​开发者工具技巧​​:在Chrome DevTools安装React插件,观察Fiber树结构;监控 “Scheduling” 标签分析优先级。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/88885.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/88885.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

(7)机器学习小白入门 YOLOv:机器学习模型训练详解

— (1)机器学习小白入门YOLOv &#xff1a;从概念到实践 (2)机器学习小白入门 YOLOv&#xff1a;从模块优化到工程部署 (3)机器学习小白入门 YOLOv&#xff1a; 解锁图片分类新技能 (4)机器学习小白入门YOLOv &#xff1a;图片标注实操手册 (5)机器学习小白入门 YOLOv&#xff…

初识MySQL(三)之主从配置与读写分离实战

主重复制 主重复制原理master开启二进制日志记录slave开启IO进程&#xff0c;从master中读取二进制日志并写入slave的中继日志slave开启SQL进程&#xff0c;从中继日志中读取二进制日志并进行重放最终&#xff0c;达到slave与master中数据一致的状态&#xff0c;我们称作为主从…

RabbitMQ面试精讲 Day 2:RabbitMQ工作模型与消息流转

【RabbitMQ面试精讲 Day 2】RabbitMQ工作模型与消息流转 开篇 欢迎来到"RabbitMQ面试精讲"系列的第2天&#xff0c;今天我们将深入探讨RabbitMQ的工作模型与消息流转机制。这是面试中最常被问到的核心知识点之一&#xff0c;90%的RabbitMQ面试都会涉及消息流转流程…

基于SpringBoot3集成Kafka集群

1. build.gradle依赖引入 implementation org.springframework.kafka:spring-kafka:3.2.02. 新增kafka-log.yml文件 在resource/config下面新增kafka-log.yml&#xff0c;配置主题与消费者组 # Kafka消费者群组 kafka:consumer:group:log-data: log-data-grouptopic:log-data: …

wpf Canvas 导出图片

在WPF中将Canvas导出为图片主要涉及以下关键步骤和注意事项: ‌核心实现方法‌使用RenderTargetBitmap将Canvas渲染为位图,再通过PngBitmapEncoder保存为PNG文件。需注意临时移除Canvas的布局变换(LayoutTransform)以避免渲染异常‌1。示例代码片段:CanvasExporter.cs pu…

lvs负载均衡实操模拟

目录 一、配置准备 二、NET模式 修改LVS端 开启路由 修改对内网卡 ens160 修改对外网卡 ens224 加载网卡配置文件 修改web1端 修改网卡信息 重启网络 检测 配置web2 检测 验证配置是否正常 启动nginx服务 验证以上配置 添加lvs规则 验证 三、DR模式 修改…

Spring Boot 是如何简化 IoC 的配置的?

首先Spring Boot 并没有发明新的 IoC 理论&#xff0c;它做的也不是替换掉 Spring IoC 容器。相反&#xff0c;Spring Boot 是 Spring IoC 思想的实践者和简化者。它通过**“约定优于配置”&#xff08;Convention over Configuration&#xff09;**的理念&#xff0c;将原本繁…

Go语言中的组合式接口设计模式

文章目录Go语言中的组合式接口设计模式背景和需求组合式接口设计Go语言中的组合式接口设计模式 背景和需求 在微服务架构和复杂业务系统中&#xff0c;我们经常需要调用多个外部服务或内部模块。传统的做法是将所有方法都放在一个大接口中&#xff0c;但这种设计会导致接口臃…

React - createPortal

什么是createPortal&#xff1f;注意这是一个API&#xff0c;不是组件&#xff0c;他的作用是&#xff1a;将一个组件渲染到DOM的任意位置&#xff0c;跟Vue的Teleport组件类似。用法 import { createPortal } from react-dom;const App () > {return createPortal(<div…

Cursor的使用

Cursor的使用 Ctrl L 打开历史对话记录 Tab智能助手 1.单行/多行补全 已有代码片段&#xff1a; //需求&#xff1a;写一个工具类计算数组平均值 public class ArrayUtils {//按tab会完成补全 }按tab键- Cursor 自动生成代码: //需求&#xff1a;写一个工具类计算数组平均值 p…

17.使用DenseNet网络进行Fashion-Mnist分类

17.1 DenseNet网络结构设计import torch from torch import nn from torchsummary import summary #卷积层 def conv_block(input_channels,num_channels):netnn.Sequential(nn.BatchNorm2d(input_channels),nn.ReLU(),nn.Conv2d(input_channels,num_channels,kernel_size3,pad…

网安系列【16】之Weblogic和jboss漏洞

文章目录一 Weblogic1.1 Weblogic相关漏洞1.2 Weblogic漏洞发现1.3 Weblogic漏洞利用二 Jboss2.1 Jboss漏洞2.2 Jboss识别与漏洞利用一 Weblogic WebLogic 是由 Oracle公司 开发的一款基于Java EE&#xff08;现称Jakarta EE&#xff09;的企业级应用服务器&#xff0c;主要用…

Unity URP + XR 自定义 Skybox 在真机变黑问题全解析与解决方案(支持 Pico、Quest 等一体机)

在使用 Unity 的 URP 渲染管线开发 XR 应用&#xff08;如 Pico Neo、Pico 4、Quest 2/3 等一体机&#xff09;时&#xff0c;很多开发者遇到一个奇怪的问题&#xff1a;打包后&#xff0c;Skybox&#xff08;天空盒&#xff09;在某些角度下突然变黑&#xff0c;只在转动头部后…

Cursor、飞算JavaAI、GitHub Copilot、Gemini CLI 等热门 AI 开发工具合集

Cursor&#xff1a;代码编写的智能伙伴​Cursor 是 Anysphere 公司推出的一款 AI 编程工具&#xff0c;它基于微软开源代码编辑器 VS Code 开发&#xff0c;将 AI 技术深度整合到开发人员的工作流程中。Cursor 的功能十分强大&#xff0c;不仅能够自动用纯英文编写代码&#xf…

如何安装历史版本或指定版本的 git

背景 有的时候&#xff0c;我们需要安装指定版本的git&#xff0c;或者希望旧一点的&#xff0c;毕竟我就遇到最新的2.50.1在win10安装后打开就一闪而过&#xff0c;而安装2.49.1就不会 下载 官网可能比较难找&#xff0c;但是这个github仓库&#xff1a;https://github.com/gi…

LaCo: Large Language Model Pruning via Layer Collapse

发表&#xff1a;EMNLP_FINDING_2024 机构&#xff1a;Shanghai Jiao Tong University 连接&#xff1a;LaCo: Large Language Model Pruning via Layer Collapse - ACL Anthology 代码&#xff1a;https://github.com/yangyifei729/LaCo Abstract 基于 Transformer 的大语…

服务器内核级故障排查

目录 **检查内核级故障(Oops/Panic)的具体操作步骤****1. 查看完整 `dmesg` 日志(含时间戳)****2. 过滤关键错误信息****3. 检查系统日志中的内核消息****4. 分析最近一次启动的日志****5. 检查是否有 `vmcore` 转储文件****常见内核错误示例及含义**补充说明:检查内核级故…

Flink学习笔记:整体架构

开一个新坑&#xff0c;系统性的学习下 Flink&#xff0c;计划从整体架构到核心概念再到调优方法&#xff0c;最后是相关源码的阅读。 今天就来学习 Flink 整体架构&#xff0c;我们先看官网的架构图图中包含三部分&#xff0c;分别是 Client、JobManager 和 TaskManager。其中…

【LeetCode 热题 100】105. 从前序与中序遍历序列构造二叉树——(解法二)O(n)

Problem: 105. 从前序与中序遍历序列构造二叉树 给定两个整数数组 preorder 和 inorder &#xff0c;其中 preorder 是二叉树的先序遍历&#xff0c; inorder 是同一棵树的中序遍历&#xff0c;请构造二叉树并返回其根节点。 【LeetCode 热题 100】105. 从前序与中序遍历序列构…

完美卸载 Ubuntu 双系统:从规划到实施的完整指南

&#x1f4d6; 前言 最近成功完成了一次 Ubuntu 双系统的完整卸载&#xff0c;从最初的分区删除到最终解决 GRUB 引导问题&#xff0c;整个过程虽然有些曲折&#xff0c;但最终完美解决。本文将详细分享整个卸载过程&#xff0c;希望能帮助到有类似需求的朋友。 &#x1f3af…