React高级Hook

news2024/10/19 7:01:06

useReducer 

useReducer 是 React 提供的一个 Hook,用于在函数组件中使用 reducer 函数来管理组件的 state。它类似于 Redux 中的 reducer,但仅用于组件内部的状态管理。useReducer 可以使复杂的状态逻辑更加清晰和可维护。

基本用法

useReducer 接收一个 reducer 函数和一个初始状态,并返回当前的 state 和一个 dispatch 函数。你可以通过 dispatch 函数来触发 reducer 函数,并传递一个 action 对象,reducer 根据 action 来更新 state。

参数
  1. reducer (Function): 一个纯函数,它接收当前的 state 和一个 action 对象,并返回一个新的 state。
  2. initialState (any): 组件的初始状态。
  3. [init (Function)] (可选): 一个可选的初始化函数,如果提供,它将在 reducer 调用之前被调用,以生成初始 state。它接收 initialState 并返回经过初始化的 state。
返回值
  1. state (any): 当前的状态。
  2. dispatch (Function): 一个 dispatch 函数,它接收一个 action 对象,并调用 reducer 函数来更新 state。

示例

下面是一个简单的计数器组件示例,展示了如何使用 useReducer

seReducer 是 React 提供的一个 Hook,用于在函数组件中使用 reducer 函数来管理组件的 state。它类似于 Redux 中的 reducer,但仅用于组件内部的状态管理。useReducer 可以使复杂的状态逻辑更加清晰和可维护。

基本用法

useReducer 接收一个 reducer 函数和一个初始状态,并返回当前的 state 和一个 dispatch 函数。你可以通过 dispatch 函数来触发 reducer 函数,并传递一个 action 对象,reducer 根据 action 来更新 state。

参数
  1. reducer (Function): 一个纯函数,它接收当前的 state 和一个 action 对象,并返回一个新的 state。
  2. initialState (any): 组件的初始状态。
  3. [init (Function)] (可选): 一个可选的初始化函数,如果提供,它将在 reducer 调用之前被调用,以生成初始 state。它接收 initialState 并返回经过初始化的 state。
返回值
  1. state (any): 当前的状态。
  2. dispatch (Function): 一个 dispatch 函数,它接收一个 action 对象,并调用 reducer 函数来更新 state。

示例

下面是一个简单的计数器组件示例,展示了如何使用 useReducer

import React, { useReducer } from 'react';  
  
// 定义 action 类型  
const increment = () => ({ type: 'INCREMENT' });  
const decrement = () => ({ type: 'DECREMENT' });  
const reset = () => ({ type: 'RESET' });  
  
// 定义 reducer 函数  
const counterReducer = (state, action) => {  
  switch (action.type) {  
    case 'INCREMENT':  
      return { count: state.count + 1 };  
    case 'DECREMENT':  
      return { count: state.count - 1 };  
    case 'RESET':  
      return { count: 0 };  
    default:  
      throw new Error();  
  }  
};  
  
// 初始状态  
const initialState = { count: 0 };  
  
function Counter() {  
  const [state, dispatch] = useReducer(counterReducer, initialState);  
  
  return (  
    <div>  
      <h1>Count: {state.count}</h1>  
      <button onClick={() => dispatch(increment())}>Increment</button>  
      <button onClick={() => dispatch(decrement())}>Decrement</button>  
      <button onClick={() => dispatch(reset())}>Reset</button>  
    </div>  
  );  
}  
  
export default Counter;

详细说明

  1. 定义 action 类型:
    • incrementdecrementreset 是三个返回 action 对象的函数。每个 action 对象都有一个 type 属性,用于在 reducer 中识别 action。
  2. 定义 reducer 函数:
    • counterReducer 是一个纯函数,它接收当前的 state 和一个 action 对象,并返回一个新的 state
    • 根据 action.type,reducer 更新 state
  3. 初始状态:
    • initialState 是组件的初始状态,这里我们设置 count 为 0。
  4. 使用 useReducer:
    • 在 Counter 组件中,使用 useReducer Hook 传入 counterReducer 和 initialState
    • useReducer 返回当前的 state 和 dispatch 函数。
    • 通过 dispatch 函数调用不同的 action 来更新 state。

复杂示例

在实际应用中,useReducer 通常用于管理更复杂的状态。例如,假设我们有一个待办事项列表。

import React, { useReducer } from 'react';  
  
// 定义 action 类型  
const addTodo = (text) => ({ type: 'ADD_TODO', text });  
const toggleTodo = (id) => ({ type: 'TOGGLE_TODO', id });  
  
// 定义 reducer 函数  
const todoReducer = (state, action) => {  
  switch (action.type) {  
    case 'ADD_TODO':  
      return {  
        ...state,  
        todos: [...state.todos, { id: Date.now(), text: action.text, completed: false }],  
      };  
    case 'TOGGLE_TODO':  
      return {  
        ...state,  
        todos: state.todos.map((todo) =>  
          todo.id === action.id ? { ...todo, completed: !todo.completed } : todo  
        ),  
      };  
    default:  
      throw new Error();  
  }  
};  
  
// 初始状态  
const initialState = { todos: [] };  
  
function TodoApp() {  
  const [state, dispatch] = useReducer(todoReducer, initialState);  
  
  const handleAddTodo = (e) => {  
    const text = e.target.value.trim();  
    if (text) {  
      dispatch(addTodo(text));  
      e.target.value = '';  
    }  
  };  
  
  return (  
    <div>  
      <h1>Todo List</h1>  
      <input type="text" onKeyDown={(e) => e.key === 'Enter' ? handleAddTodo(e) : null} />  
      <button onClick={handleAddTodo}>Add Todo</button>  
      <ul>  
        {state.todos.map((todo) => (  
          <li key={todo.id} style={{ textDecoration: todo.completed ? 'line-through' : 'none' }}>  
            <span onClick={() => dispatch(toggleTodo(todo.id))}>  
              {todo.text}  
            </span>  
          </li>  
        ))}  
      </ul>  
    </div>  
  );  
}  
  
export default TodoApp;

 useMemo

useMemo是React提供的一个自定义Hook,它允许你在渲染过程中执行一些昂贵的计算,并且仅在依赖项发生变化时重新计算。这有助于优化性能,避免在每次渲染时都重新计算相同的数值或对象。

基本语法
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
  • 第一个参数是一个返回需要记忆值的函数。
  • 第二个参数是一个依赖项数组,这个数组中的值会决定何时重新计算记忆值。
使用场景

useMemo适用于以下场景:

  • 当你有一个计算成本高昂的值,并且这个值在组件的某些渲染中可能保持不变时。
  • 当你想要避免在每次渲染时都重新执行昂贵的计算时。
注意事项
  • useMemo主要用于性能优化,不要滥用。
  • 只有当你确定计算是昂贵的且结果可以安全地在渲染之间共享时才应该使用。
  • useMemo不会阻止渲染,它只会优化计算过程。
使用案例

以下是一个使用useMemo的示例,假设我们有一个React组件,用于显示一个列表中所有项目的名称,并且这个列表可能非常大。我们可以使用useMemo来优化过滤操作,避免在每次渲染时都重新执行过滤逻辑。

import React, { useEffect, useState, useMemo } from 'react';  
  
const LargeListComponent = () => {  
  const [list, setList] = useState([]);  
  const [filterText, setFilterText] = useState('');  
  
  // 模拟一个大型列表的加载  
  useEffect(() => {  
    // 这里通常是从API获取数据,但为了简化,我们使用一个静态数组  
    const largeList = Array.from({ length: 10000 }, (_, i) => ({  
      id: i + 1,  
      name: `Item ${i + 1}`,  
    }));  
    setList(largeList);  
  }, []);  
  
  // 使用useMemo来优化过滤操作  
  const filteredList = useMemo(() => {  
    return list.filter(item =>  
      item.name.toLowerCase().includes(filterText.toLowerCase())  
    );  
  }, [list, filterText]);  
  
  return (  
    <div>  
      <input  
        type="text"  
        value={filterText}  
        onChange={(e) => setFilterText(e.target.value)}  
        placeholder="Filter items..."  
      />  
      <ul>  
        {filteredList.map(item => (  
          <li key={item.id}>{item.name}</li>  
        ))}  
      </ul>  
    </div>  
  );  
};  
  
export default LargeListComponent;

在这个例子中,useMemo接收一个过滤函数和一个依赖项数组[list, filterText]。每当listfilterText发生变化时,useMemo会重新执行过滤函数,并返回一个新的过滤后的列表。如果listfilterText都没有变化,那么useMemo会返回上一次计算的结果,从而避免不必要的过滤操作。

这个优化对于大型列表来说是非常有用的,因为它可以减少不必要的计算量,提高组件的渲染性能。

在React和Vue中,useMemo(React)和computed(Vue)都是用于计算派生状态(或称为“计算属性”)的工具,但它们在使用方式和底层实现上有所不同。

React中的useMemo

useMemo是React的一个Hook,它用于在函数组件中优化性能。当你有一个计算成本高昂的值,并且这个值在组件的某些渲染中可能保持不变时,useMemo可以帮助你避免不必要的计算。

useMemo接收一个创建函数和一个依赖项数组。当依赖项数组中的任何一个值发生变化时,创建函数会重新运行,并返回一个新的值。如果依赖项没有变化,那么useMemo会返回上一次计算的值,从而避免不必要的计算。

需要注意的是,useMemo主要用于性能优化,并且只有在你能确定计算是昂贵的且结果可以安全地在渲染之间共享时才应该使用。

Vue中的computed

在Vue中,computed属性用于声明式地计算派生状态。当你有一个基于组件响应式数据计算出来的值,并且你希望这个值在响应式数据变化时自动更新时,computed是非常有用的。

computed属性可以是基于一个或多个响应式依赖的函数,这些依赖可以是组件的data属性、props或其他computed属性。当这些依赖发生变化时,computed属性会自动重新计算,并且Vue会确保它的值是最新的。

useMemo不同,computed在Vue中是声明式的,并且它总是会在依赖变化时重新计算,而不是基于性能优化的考虑。此外,computed属性还可以被用作模板中的绑定,并且它们具有缓存行为,这意味着如果依赖没有变化,那么computed属性的值也不会变化。

总结

  • useMemo(React):一个性能优化工具,用于避免不必要的昂贵计算。它返回一个记忆化的值,这个值在依赖项没有变化时保持不变。
  • computed(Vue):一个声明式的计算属性,用于基于响应式依赖计算派生状态。它总是会在依赖变化时重新计算,并且具有缓存行为。

React.momo

默认渲染:父组件渲染子组件一起渲染

momo:props不变化时,子组件跳过渲染

父组件重新渲染,正常数组会生成新的引用,如果缓存需要用useMemo

在React中,实际上并不存在名为“React.momo”的API或组件。可能您想要了解的是与“React.momo”名称相近或功能相似的React特性,比如React.memo。以下是对React.memo的详细介绍:

一、定义与用途

React.memo是一个高阶组件(Higher Order Component,简称HOC),它用于缓存组件的渲染结果,从而避免在props相同的情况下进行不必要的重新渲染。这有助于提高应用的性能,特别是在处理大型组件树或频繁更新的场景时。

二、使用方式

React.memo接受一个函数组件作为参数,并返回一个新的组件。这个新的组件会检查其props是否发生变化,如果没有变化,则不会重新渲染内部的函数组件。

import { memo } from 'react';  
  
function MyComponent(props) {  
  // 组件代码  
}  
  
export default memo(MyComponent);

三、深度比较与自定义比较函数

默认情况下,React.memo会对props进行浅比较(shallow comparison)。如果props中的对象或数组包含深层数据结构,并且这些深层数据发生了变化,但引用没有变化(即对象或数组的引用地址没有改变),那么React.memo可能不会触发重新渲染。

为了解决这个问题,可以向React.memo传递一个自定义的比较函数作为第二个参数。这个比较函数将用于确定何时应该重新渲染组件。

function arePropsEqual(prevProps, nextProps) {  
  // 自定义比较逻辑  
  // 例如,进行深度比较  
  return prevProps.someValue === nextProps.someValue;  
}  
  
export default memo(MyComponent, arePropsEqual);

四、注意事项

  1. React.memo只能用于函数组件,不能用于类组件。
  2. 当使用React.memo时,应确保传递给组件的props是可比较的(例如,避免使用函数或undefined作为props的值,因为这些值在浅比较中可能无法准确判断)。
  3. 虽然React.memo可以提高性能,但过度使用也可能导致代码复杂性的增加。因此,应根据实际情况谨慎使用。

综上所述,React.memo是React中用于优化函数组件渲染性能的一个有用工具。通过缓存渲染结果和避免不必要的重新渲染,它可以帮助开发者提高应用的响应速度和用户体验。

useCallback

props传函数,保证子组件不重新渲染

useCallback是React提供的一个Hook函数,主要用于优化函数组件的性能,通过缓存回调函数避免不必要的重复创建和重新渲染。以下是对useCallback的详细解析:

一、基本用法

useCallback接受两个参数:一个回调函数和一个依赖数组。当依赖数组中的任何一个值发生变化时,useCallback会返回一个新的回调函数;否则,它会返回之前缓存的回调函数。

  • 回调函数:这是需要被缓存的函数,通常是在组件中需要多次调用的函数。
  • 依赖数组:这是一个包含依赖项的数组。当这些依赖项发生变化时,useCallback会重新创建一个新的回调函数。

二、示例代码

以下是一个简单的示例,展示了如何使用useCallback:

import React, { useCallback, useState } from 'react';  
  
function MyComponent() {  
  const [count, setCount] = useState(0);  
  
  // 使用useCallback缓存回调函数  
  const handleClick = useCallback(() => {  
    console.log(`Clicked ${count} times`);  
  }, [count]);  
  
  return (  
    <>  
      <div>Count: {count}</div>  
      <button onClick={() => setCount(count + 1)}>Increment</button>  
      <button onClick={handleClick}>Click me</button>  
    </>  
  );  
}

在上面的代码中,handleClick回调函数依赖于count状态,因此每次count状态改变时,useCallback都会返回一个新的回调函数。

三、使用场景

useCallback通常用于以下场景:

  1. 将回调函数传递给子组件:当父组件将回调函数传递给子组件时,如果回调函数在每次父组件渲染时都重新创建,那么子组件可能会因为接收到新的函数引用而重新渲染。使用useCallback可以缓存回调函数,避免子组件的不必要重新渲染。
  2. 优化性能:在组件中频繁调用同一个回调函数时,使用useCallback可以避免每次调用都重新创建函数实例,从而提高性能。

四、注意事项

  1. 不要过度使用:虽然useCallback可以提高性能,但过度使用可能会导致代码变得复杂和难以维护。因此,应该根据实际需求合理使用。
  2. 依赖项要准确:在使用useCallback时,要确保依赖项数组中的值是准确的。如果遗漏了某个依赖项,可能会导致回调函数在依赖项变化时没有更新,从而引发bug。
  3. 与memo配合使用:useCallback通常与React.memo一起使用,以实现更高效的组件渲染。React.memo可以对组件的props进行浅层比较,如果props没有变化,则不会重新渲染组件。

五、性能优化讨论

关于useCallback的性能优化效果,存在一些不同的观点。一方面,使用useCallback可以避免不必要的函数重复创建和渲染,从而提高性能;另一方面,React的性能优化机制已经足够智能,可以自动处理很多情况下的函数重复创建。因此,在某些情况下,不使用useCallback也不会对性能产生显著影响。然而,在大型应用中或当回调函数被频繁调用时,使用useCallback仍然是一个值得考虑的优化手段。

综上所述,useCallback是React中一个非常有用的Hook函数,它可以帮助开发者优化函数组件的性能。通过合理使用useCallback和依赖项数组,可以避免不必要的函数重复创建和渲染,从而提高应用的性能和响应速度。

forwardRef

向父组件暴露DOM

React中的forwardRef是一个重要的API,它允许将ref自动地通过组件传递给其子组件。以下是对forwardRef的详细解析:

一、基本概念

forwardRef是React提供的一个高阶组件(HOC)或称为一个函数,用于解决在函数组件中无法直接使用ref的问题。在React中,refs通常用于访问DOM节点或组件实例,但在函数组件中,由于它们没有实例,因此无法直接使用ref。forwardRef允许我们将ref从父组件传递到子组件中的DOM元素或函数式组件。

二、工作原理

forwardRef的工作原理是接受一个渲染函数作为参数,该函数接收props和ref作为参数,并返回React元素。这样,父组件就可以通过ref属性将ref传递给被forwardRef包装的组件,而该组件则可以将这个ref转发给其内部的DOM元素或另一个组件。

三、使用场景

  1. 访问DOM元素:当需要从父组件直接访问子组件的DOM元素时,可以使用forwardRef。例如,当需要直接操作子组件的焦点、触发动画或测量子DOM节点的尺寸时,forwardRef非常有用。
  2. 高阶组件:在高阶组件中,经常需要将被包装的组件的ref传递给内部的某个子组件。这时,forwardRef可以确保ref能够正确地传递。
  3. 组件库开发:在设计可重用的组件库时,通常组件内部的实现细节是不暴露给使用者的。但有时外部需要对这些封装后的子组件进行操作,这时forwardRef可以提供一个简单而有效的解决方案。

四、示例代码

以下是一个使用forwardRef的示例代码:

import React, { forwardRef, useRef } from 'react';  
  
// 定义一个使用forwardRef的组件  
const FancyButton = forwardRef((props, ref) => (  
  <button ref={ref} className="FancyButton">  
    {props.children}  
  </button>  
));  
  
// 在父组件中使用FancyButton并传递ref  
const App = () => {  
  const buttonRef = useRef();  
  
  const handleClick = () => {  
    // 通过ref直接访问DOM元素并触发点击事件  
    buttonRef.current.click();  
  };  
  
  return (  
    <div>  
      <FancyButton ref={buttonRef}>Click me!</FancyButton>  
      <button onClick={handleClick}>Programmatically click FancyButton</button>  
    </div>  
  );  
};  
  
export default App;

在上面的代码中,FancyButton组件使用了forwardRef来接收父组件传递的ref,并将其转发给内部的button元素。在父组件App中,通过useRef创建了一个ref,并将其传递给FancyButton组件。然后,通过ref直接访问了FancyButton组件内部的button元素,并触发了其点击事件。

五、注意事项

  1. 正确使用ref:在使用forwardRef时,需要确保将ref正确地传递给相应的子组件或DOM元素。否则,将无法访问到子组件的实例或DOM元素。
  2. 避免过度使用:虽然forwardRef提供了在函数组件中使用ref的能力,但过度使用可能会导致代码变得复杂和难以维护。因此,应该根据实际需求合理使用。
  3. 与类组件的区别:在类组件中,可以直接使用ref来访问组件实例。但在函数组件中,由于它们没有实例,因此需要使用forwardRef来间接访问DOM元素或子组件。

综上所述,forwardRef是React中一个非常有用的API,它允许在函数组件中通过ref访问子组件的DOM元素或实例。通过合理使用forwardRef,可以实现更精细化的UI控制和组件管理。

useImperativeHandle 

向外暴露方法

useImperativeHandle 是 React 中的一个 Hook,它允许你在使用 ref 时自定义暴露给父组件的实例值。以下是对 useImperativeHandle 的详细解析:

一、作用

useImperativeHandle 的主要作用是让子组件能够选择性地暴露给父组件某些属性或方法,而不是将所有属性和方法都暴露出去。这对于需要在父组件中调用子组件方法或访问子组件状态的场景非常有用。

二、使用场景

当父组件需要使用子组件的方法或属性时,可以通过 ref 和 useImperativeHandle 来实现。例如,父组件可能需要调用子组件的 focus 方法来聚焦输入框,或者访问子组件的某些状态。

三、使用步骤

  1. 父组件中创建 ref

    • 使用 useRef(函数组件)或 createRef(类组件)创建一个 ref 对象。
  2. 子组件中使用 forwardRef

    • 使用 React.forwardRef 包装子组件,以便能够接收和使用 ref。
  3. 子组件中使用 useImperativeHandle

    • 在子组件内部,使用 useImperativeHandle 钩子函数来定义要暴露给父组件的属性或方法。
    • useImperativeHandle 的第一个参数是 ref,第二个参数是一个函数,该函数返回一个对象,该对象包含要暴露给父组件的属性或方法。
  4. 父组件中通过 ref 访问子组件

    • 父组件可以通过 ref 的 current 属性来访问子组件暴露的属性或方法。

四、示例代码

以下是一个简单的示例,展示了如何使用 useImperativeHandle:

import React, { useRef, useImperativeHandle, forwardRef } from 'react';  
  
// 子组件  
const FancyInput = React.forwardRef((props, ref) => {  
  const inputRef = useRef();  
  useImperativeHandle(ref, () => ({  
    focus: () => {  
      inputRef.current.focus();  
    }  
  }));  
  return <input ref={inputRef} type="text" />;  
});  
  
// 父组件  
const App = () => {  
  const fancyInputRef = useRef();  
  return (  
    <div>  
      <FancyInput ref={fancyInputRef} />  
      <button onClick={() => fancyInputRef.current.focus()}>父组件调用子组件的 focus</button>  
    </div>  
  );  
};  
  
export default App;

 

 

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

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

相关文章

【SQL实验】数据库、表、模式的SQL语句操作

完整代码在文章末尾 1、数据库的建立、删除和修改操作 &#xff08;1&#xff09;使用SQL语句创建数据库EDUC&#xff0c;并进行如下设置&#xff1a; 数据库文件和日志文件的逻辑名称分别为&#xff1a;Student_data和Student_log&#xff1b;数据文件的物理文件名为‘C:\DA…

【Linux】:线程概念

朋友们、伙计们&#xff0c;我们又见面了&#xff0c;本期来给大家带来线程概念相关代码和知识点&#xff0c;如果看完之后对你有一定的启发&#xff0c;那么请留下你的三连&#xff0c;祝大家心想事成&#xff01; C 语 言 专 栏&#xff1a;C语言&#xff1a;从入门到精通 数…

Oracle T5-2 ILOM配置

ILOM管理口ip地址配置 连接控制器&#xff08;SP&#xff09;串口&#xff08;RJ45)&#xff0c;进行系统设置 (缺省&#xff1a;9600&#xff0c;8-n-1&#xff0c;root/changeme) …………………. ORACLESP-AK02566506 login: root Password: Detecting screen size; pl…

CSS3 动画相关属性实例大全(1)(@keyframes ,background属性,border 属性)

CSS3 动画相关属性实例大全&#xff08;1) (CSS 中有动画效果的属性图例大全) 本文目录&#xff1a; 零、时光宝盒 一、CSS3 动画基本概念 &#xff08;1&#xff09;、CSS3的动画基本属性 &#xff08;2&#xff09;、keyframes 规则和所有动画属性 二、CSS 中有动画效果…

SQLI LABS | Less-1 GET - Error based - Single Quotes - String

关注这个靶场的其它相关笔记&#xff1a;SQLI LABS —— 靶场笔记合集-CSDN博客 0x01&#xff1a;过关流程 输入下面的链接进入靶场&#xff08;如果你的地址和我不一样&#xff0c;按照你本地的环境来&#xff09;&#xff1a; http://localhost/sqli-labs/Less-1/ 靶场提示 …

CyberRT通信介绍与基于Reader、Writer的通信实践(apollo9.0)

目录 数据通信场景 CyberRT中的通信方式 ​编辑 通信模式 话题通信 服务通信 参数通信 protobuf protobuf简介 protobuf文件编写 topic通信实验 实验环境 实验准备 代码编写 定义消息格式 发送消息 接收消息 定义编译规则 程序编译 运行程序 数据通信场景 …

STM32-Modbus协议(一文通)

Modbus协议原理 RT-Thread官网开源modbus RT-Thread官方提供 FreeModbus开源。 野火有移植的例程。 QT经常用 libModbus库。 Modbus是什么&#xff1f; Modbus协议&#xff0c;从字面理解它包括Mod和Bus两部分&#xff0c;首先它是一种bus&#xff0c;即总线协议&#xff0c;和…

开发一个微信小程序要多少钱?

在当今数字化时代&#xff0c;微信小程序成为众多企业和个人拓展业务、提供服务的热门选择。那么&#xff0c;开发一个微信小程序究竟需要多少钱呢&#xff1f; 开发成本主要取决于多个因素。首先是功能需求的复杂程度。如果只是一个简单的信息展示小程序&#xff0c;功能仅限…

使用HIP和OpenMP卸载的Jacobi求解器

Jacobi Solver with HIP and OpenMP offloading — ROCm Blogs (amd.com) 作者&#xff1a;Asitav Mishra, Rajat Arora, Justin Chang 发布日期&#xff1a;2023年9月15日 Jacobi方法作为求解偏微分方程&#xff08;PDE&#xff09;的基本迭代线性求解器在高性能计算&#xff…

Java实现油画滤镜效果【参数可调】

油画滤镜的基本原理 油画滤镜的基本思想是通过改变图像的像素&#xff0c;将每个像素用周围随机选择的像素来代替&#xff0c;从而产生类似油画笔触的效果。这种处理方式可以模糊图像的细节&#xff0c;使得图像的色块更加连贯&#xff0c;从而模仿油画的艺术效果。 核心步骤…

后台管理员登录实现--系统篇

我的小系统后台原来就有一个上传图片的功能还夹带个删除图片的功能&#xff0c;还嵌到了一个菜单里面。之前效果如下 那么现在为了加大安全力度&#xff0c;想增加一个登录页面。通过登录再到这个页面。看着貌似很简单&#xff0c;但是听我细细说来&#xff0c;要新增些什么东西…

OpenLayers:构建现代Web地图应用

&#x1f493; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4dd; Gitee主页&#xff1a;瑕疵的gitee主页 ⏩ 文章专栏&#xff1a;《热点资讯》 OpenLayers&#xff1a;构建现代Web地图应用 文章目录 OpenLayers&#xff1a;构建现代Web地图应用1. 简介2. 为什么选择 OpenLa…

Redis 高可用:从主从到集群的全面解析

目录 一、主从复制 (基础)1. 同步复制a. 全量数据同步b. 增量数据同步c. 可能带来的数据不一致 2. 环形缓冲区a. 动态调整槽位 3. runid4. 主从复制解决单点故障a. 单点故障b. 可用性问题 5. 注意事项a. Replica 主动向 Master 建立连接b. Replica 主动向 Master 拉取数据 二、…

腾讯云宝塔面板前后端项目发版

后端发版 1. 打开“网站”页面&#xff0c;找到java项目&#xff0c;点击状态暂停服务 2.打开“文件”页面&#xff0c;进入jar包目录&#xff0c;删除原有的jar包&#xff0c;上传新jar包 3. 再回到第一步中的网站页面&#xff0c;找到jar项目&#xff0c;启动项目即可 前端发…

C#的小数位保留以及四舍五入

C#使用Math.Round("数值","保留位","保留方式")进行小数位保留以及四舍五入 //1.MidpointRounding.ToEven(四舍六入五成双) //当保留小数位后一位为0~4时&#xff0c;舍去末位 var x1 Math.Round(1.124, 2, MidpointRo…

立仪科技:光谱共焦传感器精准测量玻璃

光谱共焦测量技术作为一种创新的光学检测方法&#xff0c;近年来在工业领域引起了广泛关注。 它以其高精度、非接触式的特点&#xff0c;特别适用于透明或半透明材料如玻璃的厚度和表面形貌测量。 接下来&#xff0c;立仪科技小编将深入探讨光谱共焦技术在玻璃测量上的应用及其…

计算机毕业设计Hadoop+Hive+Spark+Flink广告推荐系统 广告预测 广告数据分析可视化 广告爬虫 大数据毕业设计 深度学习 机器学习

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 专业 小四号宋体 班级 小…

飞机大战告尾

参考 PPO算法逐行代码详解 链接 通过网盘分享的文件&#xff1a;PlaneWar 链接: https://pan.baidu.com/s/1cbLKTcBxL6Aem3WkyDtPzg?pwd1234 提取码: 1234 10.17关于博客发了又改这件事 悲催的事 今天训练了一早上ppo模型&#xff0c;满怀期待的检测成果时发现一点长进都…

mac安装brew时踩坑解决方案

安装包 mac上如果按照git等工具可能会使用brew&#xff0c;例如使用&#xff1a;$ brew install git命令&#xff0c;如果电脑没有按照brew&#xff0c;则会提示&#xff1a;zsh: command not found: brew 解决方案 需要我们打开brew的官网https://brew.sh/&#xff0c;复制…

动态规划一>下降路径最小和

1.题目&#xff1a; 2.解析&#xff1a; 代码&#xff1a; /**1.创建dp表2.初始化3.填表4.返回值*/public int minFallingPathSum(int[][] matrix) {int n matrix.length;int[][] dp new int[n1][n2];int minNum Integer.MAX_VALUE; for(int i 1; i < n; i) dp[i][0]…