React知识盲点——组件通信、性能优化、高级功能详解(大纲)

news2025/1/8 15:02:35

组件通信

React 组件通信详解

在 React 中,组件通信是一个核心概念,主要指的是如何让不同的组件共享和传递数据。React 提供了多种机制来实现组件间的数据传递和状态共享。以下是几种常见的组件通信方式,包括:父子组件通信(props)子父组件通信(回调函数传递数据)Context API(跨层级共享状态)自定义 Hooks(共享逻辑)


1. 父子组件通信(通过 props

概念:
在 React 中,父组件可以通过 props 向子组件传递数据。props 是只读的,因此子组件不能直接修改 props 的值,只能通过它来展示数据或传递给其他子组件。

如何工作:

  • 父组件通过在子组件的 JSX 标签中传递属性来向子组件传递数据。
  • 子组件通过 props 接收数据并渲染或执行其他逻辑。

使用场景:

  • 适用于父组件向子组件传递单向数据流。
  • 父组件控制的状态可以通过 props 传递给多个子组件。

示例:

function Parent() {
  const parentData = "Hello from parent!";
  
  return <Child data={parentData} />;
}

function Child(props) {
  return <h1>{props.data}</h1>;
}

在这个例子中,父组件 Parent 通过 props 向子组件 Child 传递了数据 parentData,而子组件则通过 props.data 来使用该数据。

注意:

  • props 是不可变的,子组件不能修改 props,只能读取和展示。
  • 数据是从父组件流向子组件的,遵循单向数据流。

2. 子父组件通信(通过回调函数传递数据)

概念:
子组件可以通过调用父组件传递给它的回调函数,向父组件发送数据。这是一种典型的 自下而上的通信方式,即子组件将数据传递回父组件。

如何工作:

  • 父组件定义回调函数,并通过 props 将回调函数传递给子组件。
  • 子组件通过调用该回调函数并传递参数,将数据发送给父组件。

使用场景:

  • 适用于需要在子组件中操作数据并将其反馈给父组件的场景。
  • 用于处理父组件中的状态更新。

示例:

function Parent() {
  const [data, setData] = useState("");

  const handleDataChange = (newData) => {
    setData(newData);
  };

  return (
    <div>
      <Child onDataChange={handleDataChange} />
      <p>Data from child: {data}</p>
    </div>
  );
}

function Child(props) {
  const sendDataToParent = () => {
    props.onDataChange("Hello from Child!");
  };

  return <button onClick={sendDataToParent}>Send Data to Parent</button>;
}

在这个例子中,父组件 Parent 定义了一个回调函数 handleDataChange,并通过 props.onDataChange 将其传递给子组件 Child。子组件在点击按钮时调用 props.onDataChange,将数据传递给父组件,从而更新父组件的状态。

注意:

  • 子组件通过调用父组件传递的回调函数来“通知”父组件更新数据。
  • 这种方式使得子组件不需要直接修改父组件的状态,保持了单向数据流。

3. Context API(跨层级共享状态)

概念:
Context API 是 React 提供的一个强大工具,用于跨多个组件传递数据。Context 可以让你在组件树的深层次直接共享数据,而无需通过逐层传递 props

如何工作:

  • 使用 React.createContext 创建一个上下文(Context),该上下文可以提供和消费数据。
  • 父组件通过 Context.Provider 向子组件树提供数据。
  • 子组件通过 Context.ConsumeruseContext 来消费数据。

使用场景:

  • 适用于全局数据(如主题、语言、认证状态等)的共享。
  • 解决了多层组件嵌套时需要传递 props 的问题,避免了“prop drilling”问题。

示例:

// 创建 Context
const ThemeContext = React.createContext('light');

function Parent() {
  return (
    <ThemeContext.Provider value="dark">
      <Child />
    </ThemeContext.Provider>
  );
}

function Child() {
  const theme = useContext(ThemeContext);
  return <h1>Current theme: {theme}</h1>;
}

在这个例子中,ThemeContext.Providertheme 的值传递给子组件 Child,而 Child 通过 useContext(ThemeContext) 获取该值并渲染。

注意:

  • 使用 Context API 时,任何使用 Context.ConsumeruseContext 的组件都会在上下文的值变化时重新渲染。
  • 如果需要频繁地更新上下文的值,可能会导致性能问题,因此可以考虑拆分多个 Context 来优化性能。

4. 自定义 Hooks(共享逻辑)

概念:
自定义 Hook 是 React 中的一种复用组件逻辑的方式。通过将逻辑封装到自定义 Hook 中,可以使多个组件共享相同的逻辑,而不需要通过传递 props 或使用 Context

如何工作:

  • 自定义 Hook 是一个 JavaScript 函数,它可以使用 React 内置的 Hook(如 useStateuseEffect 等),并返回一些状态或行为,供多个组件共享。
  • 自定义 Hook 可以用于封装业务逻辑,使其可以在多个组件之间复用。

使用场景:

  • 用于共享具有副作用的逻辑(如数据获取、事件处理、表单状态等)。
  • 用于避免代码重复,提高组件的可维护性。

示例:

// 自定义 Hook 用于获取窗口宽度
function useWindowWidth() {
  const [width, setWidth] = useState(window.innerWidth);

  useEffect(() => {
    const handleResize = () => setWidth(window.innerWidth);
    window.addEventListener('resize', handleResize);
    return () => window.removeEventListener('resize', handleResize);
  }, []);

  return width;
}

function App() {
  const width = useWindowWidth();

  return <h1>Window width: {width}px</h1>;
}

在这个例子中,useWindowWidth 是一个自定义 Hook,它封装了获取窗口宽度的逻辑,并可以在多个组件中复用。

注意:

  • 自定义 Hook 可以包含状态、生命周期方法(useEffect)和其他 React Hook。
  • 使用自定义 Hook 不会改变组件的渲染逻辑,它只是将逻辑从组件中提取出来,便于复用。

总结

React 提供了多种组件通信方式来管理和传递数据,以下是每种方式的简要总结:

  1. 父子组件通信(props:父组件通过 props 向子组件传递数据,保持单向数据流。
  2. 子父组件通信(回调函数传递数据):子组件通过调用父组件传递的回调函数来向父组件传递数据。
  3. Context API(跨层级共享状态):通过 Context 让数据跨越多个组件层级传递,避免 props 嵌套传递(prop drilling)。
  4. 自定义 Hooks(共享逻辑):通过自定义 Hook 提取并复用逻辑,使多个组件共享相同的行为或状态。

理解这些通信方式并合理应用,可以帮助你构建更灵活、可维护的 React 应用程序。

性能优化

React 性能优化详解

React 性能优化是前端开发中非常重要的一部分,尤其是在构建复杂的应用时。React 提供了多种优化技术和工具来提升渲染性能,减少不必要的渲染和更新,确保用户体验的流畅性。以下是 React 性能优化的几种常见方式,具体包括:React.memouseMemouseCallbackshouldComponentUpdateReact Profiler 以及懒加载与代码分割(React.lazy & Suspense)。


1. React.memo

概念:
React.memo 是 React 的一个高阶组件,用于优化函数组件的性能。它通过浅比较 props,避免在 props 不变时重新渲染组件。

如何工作:
React.memo 对组件进行包裹,使其在 props 未变化时跳过重新渲染。只有在 props 发生变化时,才会重新渲染组件。

使用场景:

  • React.memo 适用于纯函数组件(没有副作用的组件),特别是在高频渲染的场景下,能显著提高性能。

示例:

const MyComponent = React.memo(function MyComponent(props) {
  console.log("Rendering MyComponent");
  return <div>{props.name}</div>;
});

function App() {
  const [count, setCount] = useState(0);
  return (
    <div>
      <MyComponent name="React" />
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}

在这个例子中,MyComponent 组件只有在 name props 发生变化时才会重新渲染,点击按钮会更新 count,但是 MyComponent 不会因为 count 的变化而重新渲染。

注意:

  • React.memo 默认使用浅比较来检测 props 是否发生变化。如果需要更复杂的比较,可以提供自定义的 compare 函数。
const MyComponent = React.memo(function MyComponent(props) {
  return <div>{props.name}</div>;
}, (prevProps, nextProps) => prevProps.name === nextProps.name);

2. useMemo

概念:
useMemo 是 React 的一个 Hook,用于记忆计算结果。它能确保某些计算只在依赖项发生变化时重新计算,而在依赖项不变时直接返回缓存的值,从而减少不必要的计算。

如何工作:
useMemo 会返回一个记忆化的值,只有当依赖项发生变化时才会重新计算。如果依赖项没有变化,React 会返回之前计算的缓存值。

使用场景:

  • 适用于开销较大的计算,如复杂的排序、过滤、数据转换等。
  • 用来避免不必要的渲染和计算。

示例:

function App() {
  const [count, setCount] = useState(0);
  const [items, setItems] = useState([1, 2, 3]);

  const sortedItems = useMemo(() => {
    return [...items].sort();
  }, [items]); // 只有 items 发生变化时才会重新计算

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
      <ul>
        {sortedItems.map(item => (
          <li key={item}>{item}</li>
        ))}
      </ul>
    </div>
  );
}

在这个例子中,sortedItems 只在 items 数组发生变化时才会重新排序计算,否则它会返回之前的排序结果。

注意:

  • useMemo 只会在其依赖项发生变化时重新计算。它用于缓存值而不是缓存渲染。
  • 在某些情况下,useMemo 会增加额外的内存开销,因此需要根据具体情况来决定是否使用。

3. useCallback

概念:
useCallback 是 React 的一个 Hook,用于记忆回调函数。它的作用与 useMemo 类似,只是用于记忆函数,而不是值。useCallback 会返回一个记忆化的函数实例,只有在依赖项发生变化时才会重新创建该函数。

如何工作:
useCallback 确保只有在依赖项发生变化时,回调函数才会被重新创建。否则,React 会返回上次渲染时使用的同一个函数实例。

使用场景:

  • 当回调函数被传递给子组件,并且子组件使用 React.memo 时,可以通过 useCallback 来避免不必要的重新渲染。
  • 用于避免每次渲染时创建新的函数实例,尤其是那些作为 props 传递给子组件的函数。

示例:

function Parent() {
  const [count, setCount] = useState(0);

  const increment = useCallback(() => {
    setCount(c => c + 1);
  }, []); // `increment` 函数只有在 `count` 发生变化时才会重新创建

  return <Child onClick={increment} />;
}

const Child = React.memo(({ onClick }) => {
  console.log("Child rendered");
  return <button onClick={onClick}>Increment</button>;
});

在这个例子中,Child 组件只有在 increment 函数发生变化时才会重新渲染。通过 useCallbackincrement 函数只会在初始渲染时创建,之后会一直重用。

注意:

  • useCallback 适合用于回调函数的传递,但过度使用可能导致代码更复杂,性能优化的收益不明显。

4. shouldComponentUpdate

概念:
shouldComponentUpdate 是类组件中的一个生命周期方法,用于控制组件是否需要重新渲染。它接收 nextPropsnextState 作为参数,如果返回 false,React 会跳过该组件的渲染过程,从而优化性能。

如何工作:
shouldComponentUpdate 允许开发者在组件的 propsstate 变化时,手动决定是否执行重新渲染。该方法默认返回 true,表示每次更新都会重新渲染组件。如果返回 false,则会跳过渲染。

使用场景:

  • 用于优化高频渲染的组件。
  • 如果组件的 propsstate 没有变化,就可以通过返回 false 来避免不必要的渲染。

示例:

class MyComponent extends React.Component {
  shouldComponentUpdate(nextProps, nextState) {
    if (nextProps.value !== this.props.value) {
      return true;
    }
    return false;
  }

  render() {
    return <div>{this.props.value}</div>;
  }
}

在这个例子中,只有当 props.value 发生变化时,shouldComponentUpdate 会返回 true,否则返回 false,从而避免不必要的渲染。


5. React Profiler

概念:
React Profiler 是 React 的一个内置性能分析工具,用于帮助开发者识别组件的渲染性能瓶颈。它可以显示哪些组件渲染的时间过长,并提供有关渲染次数、渲染时间等详细信息。

如何工作:
React Profiler 是通过 Profiler 组件使用的。它允许你在开发过程中跟踪每个渲染的性能数据。

使用场景:

  • 用于分析和诊断 React 应用的性能瓶颈。
  • 适用于长时间运行的大型应用。

示例:

import { Profiler } from 'react';

function onRenderCallback(id, phase, actualDuration, baseDuration, startTime, commitTime) {
  console.log(`Rendered ${id} during ${phase} phase`);
  console.log(`Actual Duration: ${actualDuration}`);
  console.log(`Base Duration: ${baseDuration}`);
}

function App() {
  return (
    <Profiler id="App" onRender={onRenderCallback}>
      <MyComponent />
    </Profiler>
  );
}

在这个例子中,Profiler 会监控 MyComponent 的渲染性能,并通过 onRenderCallback 回调函数输出性能数据。

注意:

  • React Profiler 只在开发模式下启用,在生产模式下不会记录性能数据。
  • 它可以帮助定位性能瓶颈,但不能自动修复性能问题。

6. 懒加载与代码分割(React.lazy & Suspense)

概念:
懒加载和代码分割是一种优化性能的技术,通过将应用的代码拆分成更小的块,按需加载,从而减少初次加载时的 JavaScript 文件大小。

  • React.lazy:React 提供的一个 API,用于懒加载组件

  • Suspense:React 提供的一个组件,用于包装懒加载的组件,并在加载过程中提供回退界面(loading 状态)。

如何工作:

  • 使用 React.lazy 动态导入组件,并在 Suspense 中包裹它,指定加载过程中显示的 UI。

示例:

import React, { Suspense } from 'react';

// 使用 React.lazy 动态导入组件
const MyComponent = React.lazy(() => import('./MyComponent'));

function App() {
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <MyComponent />
    </Suspense>
  );
}

在这个例子中,MyComponent 组件会在实际需要的时候懒加载,加载过程中会显示 <div>Loading...</div> 作为回退界面。

使用场景:

  • 用于拆分大型应用,减少初始加载时间。
  • 适用于那些在初始渲染时不需要立即加载的部分。

总结

通过合理使用 React.memouseMemouseCallbackshouldComponentUpdateReact Profiler 和懒加载技术(如 React.lazySuspense),可以显著提高 React 应用的性能。这些工具和方法有助于减少不必要的渲染、避免性能瓶颈,并优化页面加载速度和响应时间。

高级功能

React 高级功能详解

React 提供了多种高级功能,使开发者能够更灵活、模块化地构建应用程序。以下是一些 React 中的高级功能及其详细解释,包括:动态导入(React.lazy)Suspense 与错误边界React Portals高阶组件(HOC)Render Props自定义 HooksContext API 优化


1. 动态导入(React.lazy)

概念:
React.lazy 允许你按需加载(懒加载)组件。它是 React 提供的一个 API,能够动态地加载模块,减少初始页面加载的文件大小,从而提高性能。React.lazy 配合 Suspense 使用可以优雅地处理异步组件加载。

如何工作:

  • React.lazy 通过 import() 来异步加载一个组件。Suspense 负责处理组件加载期间的状态,例如展示加载指示器。

使用场景:

  • 适用于大型应用,特别是在有多个路由或复杂的组件时,使用 React.lazy 可以按需加载,减少不必要的初始加载时间。

示例:

import React, { Suspense } from 'react';

// 动态导入组件
const MyComponent = React.lazy(() => import('./MyComponent'));

function App() {
  return (
    <div>
      <Suspense fallback={<div>Loading...</div>}>
        <MyComponent />
      </Suspense>
    </div>
  );
}

在这个示例中,MyComponent 会在需要的时候懒加载,Suspense 会在加载过程中显示 Loading...

注意:

  • React.lazy 只能用来加载默认导出的组件。
  • 当多个懒加载组件时,可以通过 Suspense 的 fallback 属性定制加载状态。

2. Suspense 与错误边界

概念:

  • Suspense:是 React 提供的一个组件,用于等待懒加载的组件加载完成。它可以包裹一个或多个懒加载组件,显示一个回退 UI(如 loading 状态)。
  • 错误边界(Error Boundaries):是 React 提供的一种捕获子组件渲染时出现错误的机制,允许开发者在应用崩溃时显示一个优雅的错误页面,而不是让整个应用崩溃。

如何工作:

  • Suspense 用于显示加载中的 UI。
  • 错误边界 使用 componentDidCatchgetDerivedStateFromError 来捕获 JavaScript 错误,防止应用崩溃。

示例:

// ErrorBoundary 组件
class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError(error) {
    return { hasError: true };
  }

  componentDidCatch(error, info) {
    console.log("Error caught:", error, info);
  }

  render() {
    if (this.state.hasError) {
      return <h1>Something went wrong!</h1>;
    }
    return this.props.children;
  }
}

// 使用 Suspense 和 ErrorBoundary
const MyComponent = React.lazy(() => import('./MyComponent'));

function App() {
  return (
    <ErrorBoundary>
      <Suspense fallback={<div>Loading...</div>}>
        <MyComponent />
      </Suspense>
    </ErrorBoundary>
  );
}

在这个例子中,Suspense 处理组件的懒加载,ErrorBoundary 捕获并处理可能出现的错误。

注意:

  • 错误边界仅能捕获生命周期方法、事件处理函数、构造函数和渲染方法中的错误,不会捕获异步函数中的错误(如 setStateuseEffect 中的错误)。
  • 错误边界仅在类组件中使用,函数组件需要使用其他方法(如 try-catch)来处理错误。

3. React Portals

概念:
React Portals 提供了一种将子组件渲染到父组件 DOM 结构以外的方式。通常,React 会将子组件渲染为父组件的 DOM 树的一个子节点,而 Portals 允许你将子组件渲染到其他 DOM 节点中。

使用场景:

  • 常用于模态框(modals)、提示框(tooltips)、弹出层等 UI 元素,它们通常需要渲染到 body 元素中,而不是嵌套在父组件的 DOM 树中。

如何工作:

  • 使用 ReactDOM.createPortal 来创建 Portal,传递子组件和目标 DOM 节点。

示例:

import ReactDOM from 'react-dom';

function Modal() {
  return ReactDOM.createPortal(
    <div className="modal">This is a modal</div>,
    document.getElementById('modal-root') // 将 modal 渲染到 modal-root 节点
  );
}

function App() {
  return (
    <div>
      <h1>React Portal Example</h1>
      <Modal />
    </div>
  );
}

在这个示例中,Modal 组件被渲染到 modal-root 节点,而不是 App 组件的 DOM 树中。

注意:

  • Portals 可以在任何组件内使用。
  • 通过 Portals 渲染的组件仍然遵循 React 的事件冒泡机制。

4. 高阶组件(HOC)

概念:
高阶组件(HOC,Higher-Order Component)是一个函数,它接收一个组件作为输入并返回一个新的增强版组件。HOC 可以用来复用组件逻辑、提高组件的可组合性。

使用场景:

  • 适用于跨多个组件共享逻辑,如权限验证、日志记录、数据获取等。

如何工作:

  • HOC 是通过包装原组件,增强原组件的功能。

示例:

// HOC: withUserData
function withUserData(Component) {
  return function WrappedComponent(props) {
    const [user, setUser] = useState(null);

    useEffect(() => {
      fetch('/user')
        .then(res => res.json())
        .then(data => setUser(data));
    }, []);

    return <Component {...props} user={user} />;
  };
}

// 使用 HOC
function UserProfile({ user }) {
  if (!user) return <div>Loading...</div>;
  return <div>Welcome, {user.name}</div>;
}

const EnhancedUserProfile = withUserData(UserProfile);

function App() {
  return <EnhancedUserProfile />;
}

在这个例子中,withUserData 是一个高阶组件,它将 user 数据作为 props 传递给 UserProfile 组件。

注意:

  • HOC 不会改变原组件的 props 结构,而是包装并返回一个新的组件。
  • 在 HOC 中使用 hooks 时,需要确保正确使用 useStateuseEffect 等 hooks,避免副作用的错误。

5. Render Props

概念:
Render Props 是一种通过传递一个函数作为 props 来共享组件之间的代码的技术。该函数会返回一个 React 元素,通常用于动态渲染组件内容。

使用场景:

  • 适用于需要动态渲染某些内容的组件(如处理表单输入、动画等)。

如何工作:

  • 使用一个接受 render 函数的组件,返回 UI 的同时可以将状态和行为作为参数传递给该函数。

示例:

function MouseTracker({ render }) {
  const [position, setPosition] = useState({ x: 0, y: 0 });

  const handleMouseMove = (event) => {
    setPosition({
      x: event.clientX,
      y: event.clientY
    });
  };

  return (
    <div style={{ height: '100vh' }} onMouseMove={handleMouseMove}>
      {render(position)}
    </div>
  );
}

function App() {
  return (
    <MouseTracker
      render={(position) => (
        <h1>The mouse is at ({position.x}, {position.y})</h1>
      )}
    />
  );
}

在这个例子中,MouseTracker 组件通过 render props 将 position 信息传递给父组件,并根据鼠标的坐标动态渲染内容。

注意:

  • Render PropsHOC 类似,也用于组件间的逻辑共享。
  • 它通过一个函数的形式传递动态内容,通常用于需要共享行为的场景。

6. 自定义 Hooks

概念:
自定义 Hooks 允许开发者将组件逻辑提取到独立的函数中,增强代码的复用性和可维护性。通过 useStateuseEffect 等 Hooks,开发者可以实现自己的业务逻辑封装。

使用场景:

适用于多个组件之间共享逻辑,例如处理表单、动画等。

如何工作:

  • 创建一个函数,使用内建的 React hooks,然后返回需要共享的状态或行为。

示例:

function useWindowWidth() {
  const [width, setWidth] = useState(window.innerWidth);

  useEffect(() => {
    const handleResize = () => setWidth(window.innerWidth);
    window.addEventListener('resize', handleResize);
    return () => window.removeEventListener('resize', handleResize);
  }, []);

  return width;
}

function App() {
  const width = useWindowWidth();

  return <h1>Window width: {width}px</h1>;
}

在这个示例中,useWindowWidth 是一个自定义 Hook,用于共享窗口宽度的状态。

注意:

  • 自定义 hooks 是普通的 JavaScript 函数,但它们必须以 use 开头。
  • 自定义 Hooks 可以用来提取组件内部的逻辑,增强代码的复用性。

7. Context API 优化详解

概念:
Context API 是 React 用来在组件树中共享数据的机制。它可以让你在整个组件树中传递数据,而无需手动通过每个中间组件传递 props。

优化策略:

  • 避免不必要的重新渲染:通过将 context 分成更小的部分来避免每个上下游组件都重新渲染。
  • Memoization:可以使用 React.memouseMemo 来优化 Context 的提供和消费,避免每次提供的数据变动时都重新渲染消费者组件。

使用场景:

  • 适用于全局共享数据,如认证信息、主题设置、语言等。

示例:

const ThemeContext = React.createContext();

function App() {
  const [theme, setTheme] = useState('light');

  return (
    <ThemeContext.Provider value={theme}>
      <div>
        <button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>
          Toggle Theme
        </button>
        <ThemedComponent />
      </div>
    </ThemeContext.Provider>
  );
}

function ThemedComponent() {
  const theme = useContext(ThemeContext);
  return <div>Current theme: {theme}</div>;
}

在这个例子中,ThemeContext 用来在整个应用中共享当前主题,并通过 useContext 来消费该数据。

注意:

  • 如果 Context 的值变化,所有使用该 Context 的组件都会重新渲染。
  • 使用 React.memouseMemo 优化性能,避免过多的重新渲染。

总结

React 提供的高级功能如 动态导入(React.lazy)Suspense 与错误边界React Portals高阶组件(HOC)Render Props自定义 HooksContext API 优化 为开发者提供了强大的工具来构建更高效、可维护和可复用的组件。掌握这些技术可以帮助你更好地管理组件的行为和状态,优化性能,并提高开发的灵活性和可维护性。

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

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

相关文章

【数据结构】链表(2):双向链表和双向循环链表

双向链表&#xff08;Doubly Linked List&#xff09; 定义&#xff1a; 每个节点包含三个部分&#xff1a; 数据域。前驱指针域&#xff08;指向前一个节点&#xff09;。后继指针域&#xff08;指向下一个节点&#xff09;。 支持从任意节点向前或向后遍历。 #define dat…

指针 const 的组合

1、首先来了解一下常量 const int num 5&#xff1b; 那么num的值是5&#xff0c; num的值不可修改 2、来了解一下指针 int value 5; int* p &value; 我喜欢吧指针和类型放一起&#xff0c;来强调p是一个指针类型&#xff0c; 而赋值的时候就得赋值一个int类型的地址…

Tableau数据可视化与仪表盘搭建-数据可视化原理

目录 内容 做个小实验 数据如何变成图表 1 2 维度和度量定义 3 度量映射图形&#xff0c;维度负责区分 1 可映射的数据类型 2 可视化字典 3 使用Tableau将数据变成图表(Tableau可视化原理) 1 2 拖拽 3 具体操作 4 总结 内容 点击左下角的工作表 tableau可以自动…

【WRF数据准备】气象驱动数据-ERA5是否需要单层位势数据?

目录 气象驱动数据-ERA5是否需要单层位势(Geopotential)数据?位势(Geopotential)输入的重要性Vtable的管理参考气象驱动数据-ERA5是否需要单层位势(Geopotential)数据? 本博客参考WRF论坛中讨论内容-How to use ERA5 Data From Copernicus Database,总结位势(Geopot…

用ResNet50+Qwen2-VL-2B-Instruct+LoRA模仿Diffusion-VLA的论文思路,在3090显卡上训练和测试成功

想一步步的实现Diffusion VLA论文的思路&#xff0c;不过论文的图像的输入用DINOv2进行特征提取的&#xff0c;我先把这个部分换成ResNet50。 老铁们&#xff0c;直接上代码&#xff1a; from PIL import Image import torch import torchvision.models as models from torch…

常见中间件漏洞(tomcat,weblogic,jboss,apache)

先准备好今天要使用的木马文件 使用哥斯拉生成木马 压缩成zip文件 改名为war后缀 一&#xff1a;Tomcat 1.1CVE-2017-12615 环境搭建 cd vulhub-master/tomcat/CVE-2017-12615 docker-compose up -d 1.首页抓包&#xff0c;修改为 PUT 方式提交 发送shell.jsp 和木马内容 …

嵌入式科普(26)为什么heap通常8字节对齐

目录 一、概述 二、newlibc heap 2.1 stm32cubeide .ld heap 2.2 e2studio .ld heap 三、glibc源码 3.1 Ubuntu c heap 四、总结 一、概述 结论&#xff1a;在嵌入式c语言中&#xff0c;heap通常8字节对齐 本文主要分析这个问题的分析过程 二、newlibc heap newlibc…

大数据-240 离线数仓 - 广告业务 测试 ADS层数据加载 DataX数据导出到 MySQL

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; Java篇开始了&#xff01; 目前开始更新 MyBatis&#xff0c;一起深入浅出&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff0…

CTF杂项——[NSSRound#4 SWPU]Pixel_Signin

得到一个像素点 提取像素点 脚本 from PIL import Image result open(1.txt,w) img Image.open("Pixel_Signin.png") img img.convert(RGB) for i in range(31):for j in range(31):r,g,b img.getpixel((j,i))print(r,g,b,end ,fileresult) 运行之后得到 把它…

Harmony开发【笔记1】报错解决(字段名写错了。。)

在利用axios从网络接收请求时&#xff0c;发现返回obj的code为“-1”&#xff0c;非常不解&#xff0c;利用console.log测试&#xff0c;更加不解&#xff0c;可知抛出错误是 “ E 其他错误: userName required”。但是我在测试时&#xff0c;它并没有体现为空&#xff0c;…

springCloudGateWay使用总结

1、什么是网关 功能: ①身份认证、权限验证 ②服务器路由、负载均衡 ③请求限流 2、gateway搭建 2.1、创建一个空项目 2.2、引入依赖 2.3、加配置 3、断言工厂 4、过滤工厂 5、全局过滤器 6、跨域问题

韩国机场WebGIS可视化集合Google遥感影像分析

目录 前言 一、相关基础数据介绍 1、韩国的机场信息 2、空间数据准备 二、Leaflet叠加Google地图 1、叠加google地图 2、空间点的标记及展示 3、韩国机场空间分布 三、相关成果展示 1、务安国际机场 2、有同类问题的机场 四、总结 前言 12月29日8时57分左右务安国际机…

电子电气架构 --- 设计车载充电机的关键考虑因素

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 简单,单纯,喜欢独处,独来独往,不易合同频过着接地气的生活,除了生存温饱问题之外,没有什么过多的欲望,表面看起来很高冷,内心热情,如果你身…

python进阶06:MySQL

课后大总结 Day1 一、数据库命令总结 1.连接数据库 连接数据库进入mysql安装目录打开bin文件夹&#xff0c;输入cmd(此命令后无分号)mysql.exe -u root -ppassword命令后输入密码:root 设置密码set passwordpassword("root123"); 查看所有数据库show databases; …

php反序列化原生态 ctfshow练习 字符串逃逸

web262 拿着题审计一下 <?php error_reporting(0); class message{public $from;public $msg;public $to;public $tokenuser;public function __construct($f,$m,$t){$this->from $f;$this->msg $m;$this->to $t;} }$f $_GET[f]; $m $_GET[m]; $t $_GET[t…

探秘前沿科技:RFID 与 NFC,开启智能识别新篇

RFID&#xff08;射频识别&#xff09;与NFC&#xff08;近场通信&#xff09;作为两种基于射频技术的无线通信方式&#xff0c;在现代社会中发挥着越来越重要的作用。尽管它们都具备非接触式识别和通信的能力&#xff0c;但在工作原理、应用场景、技术细节等方面存在着显著的差…

【04】优雅草央千澈详解关于APP签名以及分发-上架完整流程-第四篇安卓APP上架之vivo商店-小米商店,oppo商店,应用宝

【04】优雅草央千澈详解关于APP签名以及分发-上架完整流程-第四篇安卓APP上架之vivo商店-小米商店&#xff0c;oppo商店&#xff0c;应用宝 背景介绍 接第三篇上架华为&#xff0c;由于华为商店较为细致&#xff0c;本篇幅介绍其他4类商店相对简要一点&#xff0c;剩下其他更…

OpenCV计算机视觉 06 图像轮廓检测(轮廓的查找、绘制、特征、近似及轮廓的最小外接圆外接矩形)

目录 图像轮廓检测 轮廓的查找 轮廓的绘制 轮廓的特征 面积 周长 根据面积显示特定轮廓 轮廓的近似 给定轮廓的最小外接圆、外接矩形 外接圆 外接矩形 图像轮廓检测 轮廓的查找 API函数 image, contours, hierarchy cv2.findContours(img, mode, method) 代入参…

ROS2 跨机话题通信问题(同一个校园网账号)

文章目录 写在前面的话校园网模式&#xff08;失败&#xff09;手机热点模式&#xff08;成功&#xff09; 我的实验细节实验验证1、ssh 用户名IP地址 终端控制2、互相 ping 通 IP3、ros2 run turtlesim turtlesim_node/turtle_teleop_key4、ros2 multicast send/receive5、从机…

web3与AI结合-Sahara AI 项目介绍

背景介绍 Sahara AI 于 2023 年创立&#xff0c;是一个 "区块链AI" 领域的项目。其项目愿景是&#xff0c;利用区块链和隐私技术将现有的 AI 商业模式去中心化&#xff0c;打造公平、透明、低门槛的 “协作 AI 经济” 体系&#xff0c;旨在重构新的利益分配机制以及…