当前位置: 首页 > news >正文

React 之 Redux =》 理解+应用

文章目录

  • Redux基础介绍
    • 一、概述
    • 二、元素组成
      • 1. Action(动作)
      • 2. Reducer(纯函数)
      • 3. Store(仓库)
    • 三、原理结构
    • 四、场景应用
      • 1. 大型复杂的单页应用(SPA)
      • 2. 多用户协作的应用
      • 3. 数据持久化和缓存管理
    • 五、实例
      • 1. 简单的计数器应用
      • 2. 待办事项列表应用
    • Redux 之 React
    • 在React中使用Redux
      • 一、安装Redux相关库
      • 二、创建Redux Store和相关逻辑
      • 三、在React组件中使用Redux
    • 类组件connect具体应用
      • **导出复用原理**
      • **实例**
      • 1. 安装依赖
      • 2. 创建Redux相关文件
        • actions.js
        • reducers.js
        • store.js
      • 3. 创建React类组件
        • Product.js
        • CartItem.js
        • Cart.js
        • App.js
      • 4. 总结
    • redux 中间件应用及介绍

Redux基础介绍

一、概述

Redux是一个可预测的JavaScript应用程序状态管理容器。它主要用于JavaScript应用,特别是在React、Angular、Vue等框架中,但也可以与其他视图库一起使用。Redux遵循单向数据流的原则,使得应用的状态变化可预测,方便调试和维护。

二、元素组成

1. Action(动作)

  • 定义:是一个包含type属性的普通JavaScript对象,用于描述发生了什么事情。type通常是一个字符串常量,用于唯一标识这个动作。例如:
const ADD_TODO = 'ADD_TODO';
const addTodo = (text) => {return {type: ADD_TODO,payload: text};
}
  • 作用:它是改变状态的唯一途径,就像一个“指令”,告诉Redux需要进行什么样的操作。

2. Reducer(纯函数)

  • 定义:是一个纯函数,它接收两个参数,当前的state(应用的状态)和一个action。根据actiontype来决定如何更新state,并返回新的state。例如:
const initialState = {todos: []
};
const todoReducer = (state = initialState, action) => {switch (action.type) {case ADD_TODO:return {...state,todos: [...state.todos, {text: action.payload, completed: false}]};default:return state;}
}
  • 特点
    • 纯函数特性:给定相同的输入(相同的stateaction),总是返回相同的输出。没有副作用,如不会修改传入的参数,不会进行异步操作,也不会直接操作DOM。
    • 不可变性:在更新state时,应该返回一个新的对象,而不是直接修改原有的state。这有助于追踪状态的变化,并且在React等视图层中可以更高效地检测组件是否需要重新渲染。

3. Store(仓库)

  • 定义:是一个对象,它将actionreducer联系在一起。通过createStore函数创建(在Redux核心库中)。例如:
import { createStore } from 'redux';
const store = createStore(todoReducer);
  • 功能
    • 保存状态:它存储着整个应用的状态树。可以通过store.getState()方法获取当前的状态。
    • 分发动作:提供store.dispatch(action)方法,用于将action发送给reducer,从而触发状态的更新。
    • 订阅更新:通过store.subscribe(listener)方法,可以订阅状态的变化。当状态更新时,会调用listener函数,通常用于更新UI等操作。

三、原理结构

Redux的工作流程是单向数据流:

  1. 动作触发:视图层(如React组件)通过用户交互或者其他事件(例如点击按钮)触发一个action
  2. 动作分发:这个actionstore.dispatch()方法分发到reducer
  3. 状态更新reducer根据传入的action和当前state,计算并返回一个新的state。这个新的state会替换掉旧的state存储在store中。
  4. 通知订阅者store会通知所有订阅了状态变化的监听器(通过store.subscribe()注册的函数)。这些监听器通常会更新视图层,使得UI能够反映最新的状态。

四、场景应用

1. 大型复杂的单页应用(SPA)

  • 在大型SPA中,应用状态可能会非常复杂,涉及多个模块和组件之间的交互。例如,一个电商单页应用,有商品列表展示、购物车管理、用户登录状态等多个功能模块。
  • 商品列表:当用户进行搜索操作时,会触发一个SEARCH_PRODUCTS类型的actionreducer会根据这个action更新商品列表的状态。
  • 购物车管理:添加商品到购物车会触发ADD_TO_CART类型的action,从购物车移除商品会触发REMOVE_FROM_CART等动作,这些动作通过reducer来更新购物车状态。Redux可以很好地管理这些复杂的状态变化,确保每个模块的状态更新是可预测的。

2. 多用户协作的应用

  • 考虑一个实时文档编辑应用,多个用户可以同时编辑一个文档。
  • 当一个用户输入内容时,会触发UPDATE_DOCUMENT类型的action。Redux可以协调各个用户的操作,通过服务器同步数据,使得每个用户看到的文档状态都是最新的。reducer会根据这些操作更新文档的内容状态,并且通过store的订阅机制,及时更新每个用户的视图。

3. 数据持久化和缓存管理

  • 对于一些需要离线支持或者频繁请求相同数据的应用。例如,一个新闻阅读应用,它可以使用Redux来管理已缓存的新闻文章。
  • 当应用首次加载新闻文章时,会触发FETCH_ARTICLES类型的actionreducer更新状态来存储获取到的文章列表。如果应用离线,它可以从Redux存储的状态中读取已缓存的文章,提供给用户阅读。同时,当用户手动刷新文章列表或者设置了定时更新时,又会触发新的FETCH_ARTICLES动作来更新缓存。

五、实例

1. 简单的计数器应用

  • 创建Action
// 定义action类型
const INCREMENT = 'INCREMENT';
const DECREMENT = 'DECREMENT';
// 创建action创建函数
const increment = () => {return {type: INCREMENT};
}
const decrement = () => {return {type: DECREMENT};
}
  • 创建Reducer
const initialState = {count: 0
};
const counterReducer = (state = initialState, action) => {switch (action.type) {case INCREMENT:return {...state,count: state.count + 1};case DECREMENT:return {...state,count: state.count - 1};default:return state;}
}
  • 创建Store并使用
import { createStore } from 'redux';
const store = createStore(counterReducer);
// 订阅状态变化并更新UI(这里简单打印)
const unsubscribe = store.subscribe(() => {console.log(store.getState().count);
});
// 分发动作
store.dispatch(increment()); 
store.dispatch(increment()); 
store.dispatch(decrement()); 
// 取消订阅
unsubscribe();

2. 待办事项列表应用

  • 创建Action
const ADD_TODO = 'ADD_TODO';
const TOGGLE_TODO = 'TOGGLE_TODO';
const addTodo = (text) => {return {type: ADD_TODO,payload: text};
}
const toggleTodo = (index) => {return {type: TOGGLE_TODO,payload: index};
}
  • 创建Reducer
const initialState = {todos: []
};
const todoReducer = (state = initialState, action) => {switch (action.type) {case ADD_TODO:return {...state,todos: [...state.todos, {text: action.payload, completed: false}]};case TOGGLE_TODO:const newTodos = [...state.todos];newTodos[action.payload].completed =!newTodos[action.payload].completed;return {...state,todos: newTodos};default:return state;}
}
  • 创建Store并使用
const store = createStore(todoReducer);
// 订阅状态变化并更新UI(这里简单打印)
const unsubscribe = store.subscribe(() => {console.log(store.getState().todos);
});
// 分发动作
store.dispatch(addTodo("Buy milk"));
store.dispatch(addTodo("Read a book"));
store.dispatch(toggleTodo(0));
unsubscribe();

Redux 之 React

在React中使用Redux

一、安装Redux相关库

  1. 首先需要安装reduxreact-redux库。
    • 如果使用npm,可以在项目目录下的终端中运行以下命令:
    npm install redux react-redux
    
    • 如果使用yarn,则运行:
    yarn add redux react-redux
    

二、创建Redux Store和相关逻辑

  1. 定义Actions(动作)
    • 在React项目中,通常在一个单独的文件(如actions.js)中定义动作。例如,对于一个简单的计数器应用,定义增加和减少计数的动作:
    // actions.js
    export const INCREMENT = 'INCREMENT';
    export const DECREMENT = 'DECREMENT';
    export const increment = () => {return {type: INCREMENT};
    };
    export const decrement = () => {return {type: DECREMENT};
    };
    
  2. 创建Reducers(纯函数)
    • 同样在一个单独的文件(如reducers.js)中创建。以计数器应用为例,创建一个简单的reducer来处理计数状态的更新:
    // reducers.js
    import { INCREMENT, DECREMENT } from './actions';
    const initialState = {count: 0
    };
    const counterReducer = (state = initialState, action) => {switch (action.type) {case INCREMENT:return {...state,count: state.count + 1};case DECREMENT:return {...state,count: state.count - 1};default:return state;}
    };
    export default counterReducer;
    
  3. 创建Store(仓库)
    • 在项目的入口文件(如index.js)或者专门的store.js文件中创建store。例如:
    // store.js
    import { createStore } from 'redux';
    import counterReducer from './reducers';
    const store = createStore(counterReducer);
    export default store;
    

三、在React组件中使用Redux

  1. 使用Provider组件包裹根组件
    • index.js文件中,将整个React应用包裹在Provider组件内,使得应用中的所有组件都可以访问Redux store。Providerreact - redux库提供的组件。
    import React from 'react';
    import ReactDOM from 'react - dom';
    import App from './App';
    import { Provider } from 'react - redux';
    import store from './store';
    ReactDOM.render(<Provider store={store}><App /></Provider>,document.getElementById('root')
    );
    
  2. 在组件中连接Redux(使用connect函数)
    • 功能性组件(使用useSelectoruseDispatch
      • 对于功能性组件,可以使用react - redux提供的useSelectoruseDispatch钩子函数来获取状态和分发动作。例如,在一个计数器组件中:
      import React from 'react';
      import { useSelector, useDispatch } from 'react - redux';
      import { increment, decrement } from './actions';
      const Counter = () => {const count = useSelector((state) => state.count);const dispatch = useDispatch();return (<div><p>Count: {count}</p><button onClick={() => dispatch(increment())}>Increment</button><button onClick={() => dispatch(decrement())}>Decrement</button></div>);
      };
      export default Counter;
      
    • 类组件(使用connect函数)
      • 对于类组件,使用connect函数来连接Redux。例如,将上面的计数器组件改写为类组件:
      import React, { Component } from 'react';
      import { connect } from 'react - redux';
      import { increment, decrement } from './actions';
      class Counter extends Component {render() {const { count, increment, decrement } = this.props;return (<div><p>Count: {count}</p><button onClick={increment}>Increment</button><button onClick={decrement}>Decrement</button></div>);}
      }
      const mapStateToProps = (state) => ({count: state.count
      });
      const mapDispatchToProps = {increment,decrement
      };
      export default connect(mapStateToProps, mapDispatchToProps)(Counter);
      
    • mapStateToProps函数
      • 这个函数用于将Redux store中的状态映射到组件的props中。它接收整个Redux状态树作为参数,返回一个对象,对象中的属性会被合并到组件的props中。例如,在上面的类组件中,mapStateToPropsstate.count映射为组件的count属性。
    • mapDispatchToProps函数(或对象)
      • 这个函数(或对象)用于将动作创建函数映射到组件的props中,使得组件可以通过props来分发动作。在类组件的例子中,mapDispatchToProps是一个对象,它将incrementdecrement动作创建函数直接作为属性,这些属性会被添加到组件的props中,从而可以在组件中通过this.props.incrementthis.props.decrement来分发动作。在功能性组件中,useDispatch钩子函数返回的dispatch函数用于手动分发动作,更加灵活。

类组件connect具体应用

导出复用原理

  • connect函数的作用机制
    • 在React - Redux中,connect函数是一个高阶函数,用于将React组件与Redux的store连接起来。它接收两个参数:mapStateToPropsmapDispatchToProps(这两个参数也可以是函数或者对象,用于不同的映射方式)。
    • mapStateToProps原理:这个函数用于将Redux store中的状态映射到组件的props中。它会在store状态发生变化时被调用,每次调用都会重新计算返回的对象。返回对象中的属性会作为props传递给组件。例如,如果mapStateToProps返回{ count: state.count },那么组件就会通过props.count来访问Redux中的count状态。
    • mapDispatchToProps原理:这个函数(或对象)用于将Redux中的action创建函数映射到组件的props中。当它是一个函数时,接收dispatch作为参数,返回一个对象,对象中的属性是action创建函数,这些函数内部会调用dispatch来分发action。当它是一个对象时,对象中的属性直接就是action创建函数,connect函数会自动将它们绑定到dispatch上,这样组件就可以通过props来调用这些action创建函数。
  • 组件复用原理
    • 当一个通过connect函数连接了Redux的组件被导出后,它可以在多个地方被复用。因为mapStateToPropsmapDispatchToProps的映射关系是基于组件的使用场景和Redux的store结构来定义的,所以只要Redux store的结构和组件所需的状态及action保持一致,组件就可以在不同的地方复用。例如,一个显示用户信息的组件,它通过mapStateToProps获取用户状态,通过mapDispatchToProps获取更新用户信息的action函数,只要在其他地方也有相同的Redux store结构和对用户信息的操作需求,这个组件就可以直接复用。

实例

1. 安装依赖

确保项目中安装了 reduxreact-redux

npm install redux react-redux

2. 创建Redux相关文件

actions.js

定义购物车相关的 action 类型和 action 创建函数。

// actions.js
export const ADD_ITEM = 'ADD_ITEM';
export const REMOVE_ITEM = 'REMOVE_ITEM';
export const INCREMENT_QUANTITY = 'INCREMENT_QUANTITY';
export const DECREMENT_QUANTITY = 'DECREMENT_QUANTITY';export const addItem = (product) => ({type: ADD_ITEM,payload: product
});export const removeItem = (productId) => ({type: REMOVE_ITEM,payload: productId
});export const incrementQuantity = (productId) => ({type: INCREMENT_QUANTITY,payload: productId
});export const decrementQuantity = (productId) => ({type: DECREMENT_QUANTITY,payload: productId
});
reducers.js

创建购物车的 reducer,处理各种 action 对购物车状态的更新。

// reducers.js
import { ADD_ITEM, REMOVE_ITEM, INCREMENT_QUANTITY, DECREMENT_QUANTITY } from './actions';const initialState = {cart: []
};const cartReducer = (state = initialState, action) => {switch (action.type) {case ADD_ITEM:return {...state,cart: [...state.cart, {...action.payload,quantity: 1}]};case REMOVE_ITEM:return {...state,cart: state.cart.filter(item => item.id!== action.payload)};case INCREMENT_QUANTITY:return {...state,cart: state.cart.map(item =>item.id === action.payload? {...item,quantity: item.quantity + 1} : item)};case DECREMENT_QUANTITY:return {...state,cart: state.cart.map(item =>item.id === action.payload && item.quantity > 1? {...item,quantity: item.quantity - 1} : item)};default:return state;}
};export default cartReducer;
store.js

创建Redux的 store

// store.js
import { createStore } from'redux';
import cartReducer from './reducers';const store = createStore(cartReducer);export default store;

3. 创建React类组件

Product.js

定义商品展示组件,该组件可以触发添加商品到购物车的操作。

// Product.js
import React, { Component } from'react';
import { connect } from'react - redux';
import { addItem } from './actions';class Product extends Component {render() {const { product, addItem } = this.props;return (<div><h3>{product.name}</h3><p>{product.price}</p><button onClick={() => addItem(product)}>Add to Cart</button></div>);}
}const mapDispatchToProps = {addItem
};export default connect(null, mapDispatchToProps)(Product);
CartItem.js

定义购物车中商品项的展示组件,该组件可以触发移除商品、增加和减少商品数量的操作。

// CartItem.js
import React, { Component } from'react';
import { connect } from'react - redux';
import { removeItem, incrementQuantity, decrementQuantity } from './actions';class CartItem extends Component {render() {const { item, removeItem, incrementQuantity, decrementQuantity } = this.props;return (<div><p>{item.name}</p><p>Quantity: {item.quantity}</p><button onClick={() => incrementQuantity(item.id)}>Increment</button><button onClick={() => decrementQuantity(item.id)}>Decrement</button><button onClick={() => removeItem(item.id)}>Remove</button></div>);}
}const mapDispatchToProps = {removeItem,incrementQuantity,decrementQuantity
};export default connect(null, mapDispatchToProps)(CartItem);
Cart.js

定义购物车展示组件,复用 CartItem 组件展示购物车中的所有商品。

// Cart.js
import React, { Component } from'react';
import { connect } from'react - redux';
import CartItem from './CartItem';class Cart extends Component {render() {const { cart } = this.props;return (<div><h2>Shopping Cart</h2>{cart.map(item => (<CartItem key={item.id} item={item} />))}</div>);}
}const mapStateToProps = (state) => ({cart: state.cart
});export default connect(mapStateToProps)(Cart);
App.js

App 组件中复用 ProductCart 组件,展示商品列表和购物车。

// App.js
import React, { Component } from'react';
import { Provider } from'react - redux';
import store from './store';
import Product from './Product';
import Cart from './Cart';const products = [{ id: 1, name: 'Product 1', price: 10 },{ id: 2, name: 'Product 2', price: 15 }
];class App extends Component {render() {return (<Provider store = {store}><div><h1>Redux Shopping Cart Example</h1><div><h2>Products</h2>{products.map(product => (<Product key={product.id} product={product} />))}</div><Cart /></div></Provider>);}
}export default App;

4. 总结

在上述代码中,Product 组件和 CartItem 组件都通过 connect 函数与Redux建立连接,能够触发Redux中的方法(action)。Cart 组件复用了 CartItem 组件来展示购物车中的商品。整个应用通过 Provider 组件将Redux的 store 提供给所有子组件,实现了状态管理和组件间的交互。

redux 中间件应用及介绍

  1. Redux-Thunk
    • 作用
      • 用于处理异步操作。它允许action创建函数返回一个函数,而不是一个普通的action对象。这个返回的函数可以接收dispatchgetState作为参数,从而在函数内部执行异步操作(如网络请求),并根据异步操作的结果来分发action
    • 实例
      • 假设我们要从一个API获取用户数据并更新Redux状态。
      • 首先,定义action类型和action创建函数:
        // actions.js
        const FETCH_USER_SUCCESS = 'FETCH_USER_SUCCESS';
        const FETCH_USER_FAILURE = 'FETCH_USER_FAILURE';
        const fetchUser = () => {return async (dispatch) => {try {const response = await fetch('https://example.com/api/user');const userData = await response.json();dispatch({type: FETCH_USER_SUCCESS,payload: userData});} catch (error) {dispatch({type: FETCH_USER_FAILURE,payload: error.message});}};
        };
        
      • 然后,创建reducer来处理action
        // reducers.js
        const initialState = {user: null,error: null
        };
        const userReducer = (state = initialState, action) => {switch (action.type) {case FETCH_USER_SUCCESS:return {...state,user: action.payload};case FETCH_USER_FAILURE:return {...state,error: action.payload};default:return state;}
        };
        export default userReducer;
        
      • 最后,在创建store时应用redux - thunk中间件:
        // store.js
        import { createStore, applyMiddleware } from 'redux';
        import thunkMiddleware from 'redux - thunk';
        import userReducer from './reducers';
        const store = createStore(userReducer,applyMiddleware(thunkMiddleware)
        );
        
  2. Redux-Saga
    • 作用
      • 也是用于处理异步操作,它基于Generator函数。Redux - Saga将异步操作看作是可以被暂停和恢复的一系列步骤,通过Generator函数的yield关键字来暂停Saga的执行,等待异步操作完成后再恢复执行。这样可以更方便地处理复杂的异步流程,如并发请求、轮询等。
    • 实例
      • 同样是获取用户数据的例子。
      • 首先,定义Saga函数:
        // sagas.js
        import { call, put, takeEvery } from 'redux - saga/effects';
        const FETCH_USER_SUCCESS = 'FETCH_USER_SUCCESS';
        const FETCH_USER_FAILURE = 'FETCH_USER_FAILURE';
        function* fetchUserSaga() {try {const response = yield call(fetch, 'https://example.com/api/user');const userData = yield call([response, 'json']);yield put({type: FETCH_USER_SUCCESS,payload: userData});} catch (error) {yield put({type: FETCH_USER_FAILURE,payload: error.message});}
        }
        function* rootSaga() {yield takeEvery('FETCH_USER', fetchUserSaga);
        }
        export default rootSaga;
        
      • 然后,创建reducer(和上面Redux - Thunk例子中的reducer类似):
        // reducers.js
        const initialState = {user: null,error: null
        };
        const userReducer = (state = initialState, action) => {switch (action.type) {case FETCH_USER_SUCCESS:return {...state,user: action.payload};case FETCH_USER_FAILURE:return {...state,error: action.payload};default:return state;}
        };
        export default userReducer;
        
      • 最后,在创建store时应用Redux - Saga中间件:
        // store.js
        import { createStore, applyMiddleware } from 'redux';
        import createSagaMiddleware from 'redux - saga';
        import userReducer from './reducers';
        import rootSaga from './sagas';
        const sagaMiddleware = createSagaMiddleware();
        const store = createStore(userReducer,applyMiddleware(sagaMiddleware)
        );
        sagaMiddleware.run(rootSaga);
        
  3. Redux - Logger
    • 作用
      • 用于日志记录,它可以在action被分发、reducer处理action以及状态更新的过程中记录相关信息。这对于调试Redux应用非常有帮助,可以清楚地看到action的流向和状态的变化情况。
    • 实例
      • 定义logger中间件:
        // loggerMiddleware.js
        const loggerMiddleware = (store) => (next) => (action) => {console.log('dispatching', action);const result = next(action);console.log('next state', store.getState());return result;
        };
        export default loggerMiddleware;
        
      • 在创建store时应用logger中间件:
        // store.js
        import { createStore, applyMiddleware } from 'redux';
        import loggerMiddleware from './loggerMiddleware';
        import rootReducer from './reducers';
        const store = createStore(rootReducer,applyMiddleware(loggerMiddleware)
        );
        
      • action被分发时,例如在一个计数器应用中:
        // actions.js
        const INCREMENT = 'INCREMENT';
        const increment = () => ({type: INCREMENT
        });
        
        // counterReducer.js
        const initialState = {count: 0
        };
        const counterReducer = (state = initialState, action) => {switch (action.type) {case INCREMENT:return {...state,count: state.count + 1};default:return state;}
        };
        export default counterReducer;
        
        // index.js
        import React from 'react';
        import ReactDOM from 'react - dom';
        import { Provider } from 'react - redux';
        import store from './store';
        import Counter from './Counter';
        ReactDOM.render(<Provider store={store}><Counter /></Provider>,document.getElementById('root')
        );
        
        • 当点击按钮触发increment动作时,logger中间件会在控制台打印出分发的action{type: 'INCREMENT'})以及更新后的状态({count: 1}等)。

相关文章:

React 之 Redux =》 理解+应用

文章目录 Redux基础介绍一、概述二、元素组成1. Action&#xff08;动作&#xff09;2. Reducer&#xff08;纯函数&#xff09;3. Store&#xff08;仓库&#xff09; 三、原理结构四、场景应用1. 大型复杂的单页应用&#xff08;SPA&#xff09;2. 多用户协作的应用3. 数据持…...

生成excel文件(有备注和表头的情况)

要使用 Java 导出 Excel 文件&#xff0c;并且通过 ExcelProperty 注解进行列的映射&#xff0c;可以利用 EasyExcel 库。EasyExcel 是阿里巴巴开源的一款高性能 Excel 读写工具&#xff0c;它支持通过注解将类与 Excel 的列进行映射&#xff0c;简化了 Excel 操作的复杂性。 …...

Docker 安装全攻略:从入门到上手

Docker 安装全攻略&#xff1a;从入门到上手 在当今的软件开发与部署领域&#xff0c;Docker 已经成为了一项不可或缺的关键技术。它能够将应用程序及其依赖项打包成轻量级、可移植的容器&#xff0c;极大地简化了开发、测试和部署的流程。本文将详细讲解在不同操作系统下 Doc…...

@Scheduled注解的使用-SpringBoot-Springtask

Scheduled 注解是 Spring 框架中用于定时任务调度的核心注解之一。通过 Scheduled 注解&#xff0c;开发者可以非常方便地在 Spring 应用程序中定义和配置各种定时任务&#xff0c;包括固定速率执行、固定延迟执行、cron 表达式执行等。本文将详细讲解 Scheduled 注解的各个方面…...

Elasticsearch:使用 Ollama 和 Go 开发 RAG 应用程序

作者&#xff1a;来自 Elastic Gustavo Llermaly 使用 Ollama 通过 Go 创建 RAG 应用程序来利用本地模型。 关于各种开放模型&#xff0c;有很多话要说。其中一些被称为 Mixtral 系列&#xff0c;各种规模都有&#xff0c;而一种可能不太为人所知的是 openbiollm&#xff0c;这…...

Linux 下 Mamba 环境安装踩坑问题汇总(重置版)

导航 安装教程导航 Mamba 及 Vim 安装问题参看本人博客&#xff1a;Mamba 环境安装踩坑问题汇总及解决方法&#xff08;初版&#xff09;Linux 下Mamba 及 Vim 安装问题参看本人博客&#xff1a;Mamba 环境安装踩坑问题汇总及解决方法&#xff08;重置版&#xff09;Windows …...

(免费送源码)计算机毕业设计原创定制:Java+springboot+MySQL springboot 线上线下一体化的宠物交易

摘 要 网络发布信息有其突出的优点&#xff0c;即信息量大&#xff0c;资源丰富&#xff0c;更新速度快等&#xff0c;很符合人们希望以捷、便利的方式获得最多最有效信息的要求。本系统就是一个线上线下一体化的宠物交易&#xff0c;为商家提供一个信息发布的平台&#xff0…...

【Rust自学】7.4. use关键字 Pt.2 :重导入与换国内镜像源教程

喜欢的话别忘了点赞、收藏加关注哦&#xff0c;对接下来的教程有兴趣的可以关注专栏。谢谢喵&#xff01;(&#xff65;ω&#xff65;) 7.4.1. 使用pub use重新导入名称 使用use将路径导入作用域内后。该名称在词作用域内是私有的。 以上一篇文章的代码为例&#xff1a; m…...

自动生成关于软件程序开发的100个文件并可提供下载入口

创建一个包含100个关于软件程序开发的文件并提供下载入口是一个庞大的任务&#xff0c;因为这需要编写大量的代码、文档和示例。不过&#xff0c;我可以提供一个大致的框架和指导&#xff0c;帮助你生成这些文件&#xff0c;并说明如何设置下载入口。 文件生成思路 编程语言文…...

Linux下基本指令

一、什么是指令 指令本质是可执行程序&#xff0c;在执行指令前&#xff0c;先在系统中查找对应的指令。在Linux系统中指令存在于/usr/bin/路径下 二、ls 指令 1、语法 ls [选项][目录或文件] 2、功能 对于目录&#xff0c;该命令列出该目录下的所有子目录与文件。 对于文…...

2024-12-25-sklearn学习(20)无监督学习-双聚类 料峭春风吹酒醒,微冷,山头斜照却相迎。

文章目录 sklearn学习(20) 无监督学习-双聚类1 Spectral Co-Clustering1.1 数学公式 2 Spectral Biclustering2.1 数学表示 3 Biclustering 评价 sklearn学习(20) 无监督学习-双聚类 文章参考网站&#xff1a; https://sklearn.apachecn.org/ 和 https://scikit-learn.org/sta…...

编程考古-传奇的开始Delphi(下)含所有版本.iso

概览 Delphi 的最新版本&#xff0c;即 Delphi 12&#xff0c;勾勒出了自公司创立以来的一条进化之路。该平台不断通过提升开发者生产力、扩展其支持的平台范围以及引入前沿技术来实现自我完善。作为 Embarcadero 提供的主要快速应用开发&#xff08;RAD&#xff09;环境&…...

集合stream

1.Collection集合 1.1数组和集合的区别【理解】 相同点 都是容器,可以存储多个数据 不同点 数组的长度是不可变的,集合的长度是可变的 数组可以存基本数据类型和引用数据类型 集合只能存引用数据类型,如果要存基本数据类型,需要存对应的包装类 1.2集合类体系结构【理解】…...

Xshell 和 Xftp 更新提示问题的解决方法及分析

Xshell 和 Xftp 更新提示问题的解决方法及分析 在个人使用 Xshell 和 Xftp 的过程中&#xff0c;通过官网注册使用一段时间后&#xff0c;往往会遇到这样的问题&#xff1a;软件提示“要继续使用此程序&#xff0c;你必须应用最新的更新或使用新版本”。对于那些觉得更新比较麻…...

Docker安装MongoDB

Docker安装MongoDB 1、拉取镜像2、创建容器3、启动容器4、进入容器内部5、进入admin数据库6、添加管理员&#xff0c;其拥有管理用户和角色的权限7、进行认证8、通过admin添加普通用户 1、拉取镜像 docker pull mongo:4.0.32、创建容器 docker create --name mongodb-server …...

解锁自动化新高度,zTasker v2.0全方位提升效率

zTasker 是一款集强大功能与高效操作于一体的自动化任务管理软件&#xff0c;以其简单直观的设计和一键完成操作的特性深受用户喜爱。软件体积小巧&#xff0c;运行速度极快&#xff0c;支持超过 100 种不同的任务类型&#xff0c;并提供 30 多种定时或条件触发方式&#xff0c…...

Windows Server 安装 MySQL 8.0 详细指南

文章目录 Windows Server 安装 MySQL 8.0 详细指南准备工作安装步骤1. 解压安装包2. 初始化数据目录3. 安装 MySQL 服务4. 启动 MySQL 服务 MySQL 配置文件 (my.ini)5. 设置 root 密码6. 配置远程访问 安全建议常见问题排查性能优化提示结语 &#x1f449;洛秋资源小站 Windows…...

uniapp小程序使用webview 嵌套 vue 项目

uniapp小程序使用webview 嵌套 vue 项目 小程序中发送 <web-view :src"urlSrc" message"handleMessage"></web-view>export default {data() {return {urlSrc: "",};},onLoad(options) {// 我需要的参数比较多 所以比较臃肿// 获取…...

高效搭建Nacos:实现微服务的服务注册与配置中心

一、关于Nacos 1.1 简介 Nacos&#xff08;Dynamic Naming and Configuration Service&#xff09;是阿里巴巴开源的一款动态服务发现、配置管理和服务管理平台。它旨在帮助开发者更轻松地构建、部署和管理分布式系统&#xff0c;特别是在微服务架构中。Nacos 提供了简单易用…...

JavaScript 实现动态产品展示网页

JavaScript 实现动态产品展示网页 1. HTML 页面结构2. CSS 样式设计3. JavaScript 实现功能功能总结 本文设计了一个基于 JavaScript 的动态产品展示网页案例&#xff0c;核心功能包括&#xff1a; 动态产品分类过滤&#xff1a;通过点击分类按钮&#xff0c;仅显示属于该分类…...

小程序配置文件 —— 13 全局配置 - window配置

全局配置 - window配置 这里讲解根目录 app.json 中的 window 字段&#xff0c;window 字段用于设置小程序的状态栏、导航条、标题、窗口背景色&#xff1b; 状态栏&#xff1a;顶部位置&#xff0c;有网络信号、时间信息、电池信息等&#xff1b;导航条&#xff1a;有一个当…...

【小程序】wxss与rpx单位以及全局样式和局部样式

目录 WXSS 1. 什么是 WXSS 2. WXSS 和 CSS 的关系 rpx 1. 什么是 rpx 尺寸单位 2. rpx 的实现原理 3. rpx 与 px 之间的单位换算* 样式导入 1. 什么是样式导入 2. import 的语法格式 全局样式和局部样式 1. 全局样式 2. 局部样式 WXSS 1. 什么是 WXSS WXSS (We…...

矩阵的因子分解1-奇异值分解

文章目录 矩阵的因子分解1-奇异值分解求法归纳例1. 对矩阵 A ( 0 1 − 1 0 0 2 1 0 ) A \begin{pmatrix} 0 & 1 \\ -1 & 0 \\ 0 & 2 \\ 1 & 0 \end{pmatrix} A ​0−101​1020​ ​ 进行奇异值分解1. 计算 A H A A^H A AHA 的特征值和特征向量2. 将奇异值按…...

Hive其十,优化和数据倾斜

目录 Hive优化 1、开启本地模式 2、explain分析SQL语句 3、修改Fetch操作 4、开启hive的严格模式【提高了安全性】 5、JVM重用 6、分区、分桶以及压缩 7、合理设置map和reduce的数量 合理设置map数量&#xff1a; 设置合理的reducer的个数 8、设置并行执行 9、CBO优…...

云原生后端开发(一)

云原生后端开发 云原生&#xff08;Cloud-Native&#xff09;是指一种构建和运行应用程序的方式&#xff0c;它充分利用了云计算的特点&#xff0c;比如弹性伸缩、自动化部署、容器化等。在云原生的架构下&#xff0c;后端应用通常具备高度可扩展、可维护、易于自动化管理的特…...

Python常用模块详解:从操作系统接口到日志记录

Python常用模块详解&#xff1a;从操作系统接口到日志记录 1. os模块&#xff1a;操作系统接口主要功能示例 2. io模块&#xff1a;流操作主要功能示例 3. time模块&#xff1a;时间操作主要功能示例 4. argparse模块&#xff1a;命令行参数解析主要功能示例 5. logging模块&am…...

修改成清华镜像源解决Anaconda报The channel is not accessible源通道不可用问题

修改成清华镜像源解决Anaconda报The channel is not accessible源通道不可用问题 最近在通过pycharm开发python程序&#xff0c;引用anaconda环境建立虚拟环境时报错&#xff0c;报UnavailableInvalidChannel: The channel is not accessible or is invalid.应该是镜像源访问通…...

Python之Web开发

一、基本概念 Web开发是指创建和维护网站或Web应用的过程。一个典型的Web应用包括前端&#xff08;客户端&#xff09;和后端&#xff08;服务器端&#xff09;。前端负责用户界面的设计和交互&#xff0c;而后端则处理业务逻辑、数据存储和与数据库的通信。Python作为一门功能…...

CDN如何抵御DDoS攻击

一、DDoS攻击的定义 DDoS&#xff08;Distributed Denial of Service&#xff0c;分布式拒绝服务&#xff09;攻击是一种常见且破坏性较大的网络攻击方式。攻击者通过控制大量分布在全球各地的受感染设备&#xff08;称为“僵尸网络”&#xff09;&#xff0c;同时向目标服务器…...

基于进程信号量的多线程同步机制研究与实现

1 信号量 1.1 原理与概念 信号量机制本质是对于资源的预订操作&#xff0c;线程或者进程预订了之后&#xff0c;确保未来有一段时间&#xff0c;资源是属于我的。 对于预订资源&#xff0c;会有一个最小单位&#xff0c;资源都是以这个最小单位为整体被使用的。 信号量需要做…...

七、队列————相关概念详解

队列————相关概念详解 前言一、队列1.1 队列是什么?1.2 队列的类比 二、队列的常用操作三、队列的实现3.1 基于数组实现队列3.1.1 基于环形数组实现的队列3.1.2 基于动态数组实现的队列 3.2 基于链表实现队列 四、队列的典型应用总结 前言 本篇文章&#xff0c;我们一起来…...

钉钉h5微应用鉴权配置客户端 API 鉴权步骤

这里记录一下使用的钉钉h5微应用 配置客户端 API 鉴权的内容 注意不是所有的都功能都需要鉴权。 先要引入钉钉环境 见下链接 https://blog.csdn.net/KLS_CSDN/article/details/144794982?spm1001.2014.3001.5501 引入鉴权代码到前端页面并配置以下参数&#xff1a; dd.con…...

04.HTTPS的实现原理-HTTPS的混合加密流程

04.HTTPS的实现原理-HTTPS的混合加密流程 简介1. 非对称加密与对称加密2. 非对称加密的工作流程3. 对称加密的工作流程4. HTTPS的加密流程总结 简介 主要讲述了HTTPS的加密流程&#xff0c;包括非对称加密和对称加密两个阶段。首先&#xff0c;客户端向服务器发送请求&#xf…...

Python中构建终端应用界面利器——Blessed模块

在现代开发中&#xff0c;命令行应用已经不再仅仅是一个简单的文本输入输出工具。随着需求的复杂化和用户体验的重视&#xff0c;终端界面也逐渐成为一个不可忽视的设计环节。 如果你曾经尝试过开发终端UI&#xff0c;可能对传统的 print() 或者 input() 函数感到不满足&#…...

【Python】 基于Python实现日志聚合与分析工具:利用Logstash与Fluentd构建高效分布式日志系统

《Python OpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门! 解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 在分布式系统中,日志数据的生成速度和数量呈指数级增长,传统的日志管理方式已无法满足现代企业对实时性、可扩展性和高效性的需求。本文深…...

汽车网络安全基线安全研究报告

一、引言 随着汽车行业朝着智能网联方向飞速发展&#xff0c;汽车网络安全已成为保障用户安全和行业健康发展的关键要素。本报告将深入探讨汽车网络安全相关内容&#xff0c;以及国际、国内重要的汽车网络安全标准基线和相应防护措施等内容。 二、汽车网络安全的重要性 &…...

[pdf、epub]260道《软件方法》强化自测题业务建模需求分析共216页(202412更新)

DDD领域驱动设计批评文集 做强化自测题获得“软件方法建模师”称号 《软件方法》各章合集 260道《软件方法》强化自测题业务建模需求分析共216页&#xff08;202412更新&#xff09; 已上传到本CSDN账号的资源 如果下载不到&#xff0c;也可以访问以下链接&#xff1a; ht…...

工业4.0和MES(制造执行系统)方案(附实践资料)

工业4.0和MES&#xff08;制造执行系统&#xff09;方案是智能制造领域中的关键组成部分&#xff0c;它们共同推动着制造业的数字化转型。以下是工业4.0和MES方案的一些核心要点&#xff1a; 智能制造背景&#xff1a; 工业4.0是第四次工业革命&#xff0c;它结合了信息通信技术…...

机器视觉中的单线程、多线程与跨线程:原理与应用解析

在机器视觉应用中&#xff0c;程序的运行效率直接影响到系统的实时性和稳定性。随着任务复杂度的提高&#xff0c;单线程处理往往无法满足高性能需求&#xff0c;多线程技术因此被广泛应用。此外&#xff0c;跨线程操作&#xff08;如在多线程中更新界面或共享资源&#xff09;…...

性能测试瓶颈:CPU 问题的深度分析和调优

&#x1f345; 点击文末小卡片 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 我们做性能测试的时候&#xff0c;除了使用工具编写脚本并执行之外&#xff0c;最核心的工作就是做性能测试结果分析和问题调优。然后在做性能测试的时候&#xf…...

云手机与Temu矩阵:跨境电商运营新引擎

云手机与 Temu 矩阵结合的基础 云手机技术原理 云手机基于先进的 ARM 虚拟化技术&#xff0c;在服务器端运行 APP。通过在服务器上利用容器虚拟化软件技术&#xff0c;能够虚拟出多个独立的手机操作系统实例&#xff0c;每个实例等同于一部单独的手机&#xff0c;可独立运行各…...

Oracle考试多少分算通过?

OCP和OCM认证的考试及格分数并不是固定的&#xff0c;而是根据考试的难度和考生的整体表现来确定。对于OCP认证&#xff0c;考生需要全面掌握考试要求的知识和技能&#xff0c;并在考试中表现出色才有可能通过。而对于OCM认证&#xff0c;考生则需要在每个模块中都达到一定的水…...

【UE5.3.2】安装metahuman插件

Unable to find plugin ‘MetaHuman’报错 Unable to find plugin MetaHuman (referenced via RPect_5_3.uproject). Install it and try again, or remove it from the required plugin list. 10>Microsoft.MakeFile.Targets(44,5): Error MSB3073 :...

python lambda函数用法

在Python中&#xff0c;lambda函数是一种用于创建匿名函数的简便方式。它允许你快速定义一个简单的函数&#xff0c;而不需要使用传统的def语句。lambda函数通常用于一次性的操作或作为参数传递给其他函数。 lambda函数的语法&#xff1a; lambda 参数1, 参数2, ... : 表达式l…...

acitvemq AMQP:因为消息映射策略配置导致的MQTT接收JMS消息乱码问题 x-opt-jms-dest x-opt-jms-msg-type

使用ActiveMQ&#xff08;5.14.5&#xff09;作消息系统服务的场景下&#xff0c; 当我用Apache Qpid Proton发送消息(使用AMQP协议)发送JMS消息&#xff0c;用Paho MQTT接收消息的时候&#xff0c; 收到的消息前面总是有一串乱码&#xff0c;大概就是这样&#xff1a; 4Sp?AS…...

ida的使用

一.ida的基本设置 在IDA的安装根目录下有许多文件夹&#xff0c;各个文件夹存储不同的内容 1.目录结构 cfg&#xff1a;包含各种配置文件&#xff0c;基本IDA配置文件ida.cfg,GUI配置文件idagui.cfg&#xff0c;文本模式用户界面配置文件idatui.cfg, idc&#xff1a;包含…...

archery docker安装

#下载Archery-1.11.3.tar.gz https://codeload.github.com/hhyo/Archery/tar.gz/refs/tags/v1.11.3 cd /root tar -zxvf Archery-1.11.3.tar.gz cd /root/Archery-1.11.3/src/docker-compose #启动 docker compose -f docker-compose.yml up -d#表结构初始化 docker exec -ti a…...

【zookeeper核心源码解析】第四课:客户端与服务端读写的io核心流程

系列文章目录 【zookeeper核心源码解析】第一课&#xff1a;zk启动类核心流程序列图 【zookeeper核心源码解析】第二课&#xff1a;俯瞰QuorumPeer启动核心流程&#xff0c;实现选举关键流程 【zookeeper核心源码解析】第三课&#xff1a;leader与follower何时开始同步&#…...

影刀进阶指令 | Kimi (对标ChatGPT)

文章目录 影刀进阶指令 | Kimi &#xff08;对标ChatGPT&#xff09;一. 需求二. 流程三. 实现3.1 流程概览3.2 流程步骤讲解1\. 确定问题2\. 填写问题并发送3\. 检测答案是否出完 四. 运维 影刀进阶指令 | Kimi &#xff08;对标ChatGPT&#xff09; 简单讲讲RPA调用kimi实现…...

Linux第99步_Linux之点亮LCD

主要学习如何在Linux开发板点亮屏&#xff0c;以及modetest命令的实现。 很多人踩坑&#xff0c;我也是一样。关键是踩坑后还是实现不了&#xff0c;这样的人确实很多&#xff0c;从群里可以知道。也许其他人没有遇到这个问题&#xff0c;我想是他运气好。 1、修改设备树 1)、…...