React 之 Redux 第三十一节 useDispatch() 和 useSelector()使用以及详细案例
使用 Redux
实现购物车案例
由于 redux 5.0 已经将 createStore 废弃
,我们需要先将 @reduxjs/toolkit
安装一下;
yarn add @reduxjs/toolkit// 或者
npm install @reduxjs/toolkit
使用 vite 创建 React
项目时候 配置路径别名
:
// 第一种写法
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import path from 'path';
import { resolve } from 'path';
export default defineConfig({plugins: [react()],
...resolve: {alias: {'@': path.resolve(__dirname, './src') // 例如,设置一个别名路径 @ 指向 src 目录}}
...
})
// 第二种写法
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import path from 'path';
import { resolve } from 'path';
const projectRoot = resolve(__dirname); // 获取项目根目录的绝对路径
const srcPath = resolve(projectRoot, 'src'); // 获取 src 目录的绝对路径
export default defineConfig({plugins: [react()],
...resolve: {alias: {'@': srcPath, // 例如,设置一个别名路径 @ 指向 src 目录}}
...
})
1、创建 购物车 store
分别新建
action/carAction.js 文件
reducer/carReducer.js 文件
1.1、添加action
常量类型
// store/action/carAction.js 文件
// action type 常量
const ADD_CART = 'ADD_CART' // 新增商品
const REMOVE_CART = 'REMOVE_CART' // 删除商品
const ADD_NUM_CART = 'ADD_NUM_CART' // 增加数量
const REDUCE_NUM_CART = 'REDUCE_NUM_CART' // 减少数量
const EDIT_NUM_CART = 'REDUCE_NUM_CART' // 直接修改数量
const CHECKED_CART = 'CHECKED_CART' // 选中要结算的单据
1.2、添加 修改 state 的 action
方法
每个 action 中 必须包含一个 type
属性的 常量,返回一个
对象,其余参数可以自行定义
抛出需要使用的方法
// store/action/carAction.js 文件
const addCart = (list, order={name: `商品${list.length + 1}`,id: `sss_${list.length + 1}` ,num: 1,price: 12.00,totalPrice: 12.00,
}) => ({type: ADD_CART,payload: {order: order,list: list}
})const removeCart = (id) => ({type: REMOVE_CART,payload: id
})
const addNumCart = (id, num) => ({type: ADD_NUM_CART,payload: {id, num}
})
const reduceNumCart = (id, num) => ({type: REDUCE_NUM_CART,payload: {id, num}
})
const editNumCart = (id, num) => ({type: EDIT_NUM_CART,payload: {id, num}
})
const checkedCart = (id) => ({type: CHECKED_CART,payload: {id}
})export {addCart,removeCart,addNumCart,reduceNumCart,editNumCart,checkedCart
}
1.3、添加 购物车 reducer
方法
自定义的 reducer
中接收两个参数
state
: 当前的数据状态
action
: 使用dispatch() 触发的 action对象
// store/reducer/carReducer.js 文件
// 如果有初始值,我们可以这样定义初始值
const initState = {list:[]
}// 购物的 reducer 根据action.type 类型进行业务逻辑处理
const carReducer = (state=initState, action) => {console.log('==carReducer=', state, action)let newLists = []switch (action.type) {case 'ADD_CART':return {list: [action.payload.order, ...state.list]}case 'REMOVE_CART':return {list: state.list.filter(itm => itm.id !== action.payload.id)}case 'ADD_NUM_CART':// 不可以直接修改 state.list 中的数据,这里的数据是只读的state.list.map(itm => {if (itm.id === action.payload.id) {newLists.push({...itm,num: itm.num + 1,totalPrice: (itm.num + 1) * itm.price})} else {newLists.push({...itm})}})return {list: [...newLists]}case 'REDUCE_NUM_CART':state.list.map(itm => {if (itm.id === action.payload.id) {newLists.push({...itm,num: (itm.num > 0 ? itm.num - 1 : 0),totalPrice: (itm.num > 0 ? itm.num - 1 : 0) * itm.price})} else {newLists.push({...itm})}})return {list: [...newLists]}case 'EDIT_NUM_CART':// 直接修改 数量state.list.map(itm => {if (itm.id === action.payload.id) {newLists.push({...itm,num: action.payload.num,totalPrice: action.payload.num * itm.price})} else {newLists.push({...itm})}})return {list: [...newLists]}case 'CHECKED_CART':// 选中state.list.map(itm => {if (itm.id === action.payload.id) {newLists.push({...itm,isChecked: !itm?.isChecked})} else {newLists.push({...itm})}})return {list: [...newLists]}default :return {list: state.list}}
}export {carReducer
}
1.4、抛出 store 实例
当有多个 reducer
时,我们需要使用 combineReducers
将所有reducer 合并
// import { createStore } from 'redux';
// createStore 这种方案 在 5.0中已经弃用
import { configureStore } from '@reduxjs/toolkit'
import { combineReducers } from 'redux';
import { textReducer } from './reducer'
import { carReducer } from './reducer/carReducer.js'
const rootReducer = combineReducers({textReducer: textReducer,carReducer: carReducer,});
const store = configureStore({reducer: rootReducer
})export default store
2、使用触发 购物车 store 数据更新
2.1、引入需要使用的 Action
方法
import { addCart,removeCart,addNumCart,reduceNumCart,editNumCart,checkedCart
} from '@/store/action/carAction.js'
2.2、获取 useDispatch的dispatch 和 useSelector 中的 reducer
import { useDispatch, useSelector } from 'react-redux'
// useDispatch Hook 触发 action 中方法
const dispatch = useDispatch()
// useSelector 获取最新的 state 中购物车数据
const selector = useSelector(state => {console.log('=---selector-', state)return state.carReducer.list
})
2.3、完整案例代码
import React, {useState, useEffect, useId} from 'react'
import './index.scss'
import { useDispatch, useSelector } from 'react-redux'
import { addCart,removeCart,addNumCart,reduceNumCart,editNumCart,checkedCart
} from '@/store/action/carAction.js'
export default function ShoppingCar() {const dispatch = useDispatch()const selector = useSelector(state => {console.log('=---selector-', state)return state.carReducer.list})const [totalNum, setTotalNum] = useState(0)const [totalPerice, setTotalPerice] = useState(0)const [list, setList] = useState([])const handleChangeNum = (type, id, num) => {if(type === 'ADD') {// 使用 dispatch 调用 action 中的 addNumCart 方法进行累加dispatch(addNumCart(id, num))} else{dispatch(reduceNumCart(id, num))}}const handleChangeCheckbox = (e, id) =>{// 使用 dispatch 调用 action 中的 checkedCart 获取选中 反选操作dispatch(checkedCart(id))}const handleAdd = () => {// 新增商品dispatch(addCart([...selector]))}useEffect(() => {let isSelectedLists = []selector.map(itm => {if (itm.isChecked) {isSelectedLists.push(itm)}})console.log('=isSelectedLists==', isSelectedLists)const curNum = isSelectedLists && isSelectedLists.length &&isSelectedLists.reduce((total, item) => total + item.num, 0) || 0const curTotal = isSelectedLists && isSelectedLists.length && isSelectedLists.reduce((total, item) => total + item.totalPrice, 0) || 0console.log('==curNum==', curNum)console.log('==curTotal==', curTotal)setTotalNum(curNum)setTotalPerice(curTotal)console.log('=000=selector=', selector)setList([...selector])}, [selector])return (<div className='list'>{list.map(itm => {return (<div className="li" key={itm.id}><div className='commodity'><input type="checkbox" name="" id="" value={itm.isChecked} onClick={(e) => handleChangeCheckbox(e, itm.id)}/><span>{itm.name}</span></div><div className="price">单价:{itm.price}</div><div className='num'><span className='handle-icon' onClick={() => handleChangeNum('ADD', itm.id, itm.num)}>+</span><span className='itm-num'>{itm.num}</span><span className='handle-icon' onClick={() => handleChangeNum('REDUCE', itm.id, itm.num)}>-</span></div><div className='total'>总价:{itm.totalPrice}</div></div>)})}<div className='total'><span className='total-num'>共计:{totalNum}件</span><span className='total-price'>合计:{totalPerice}元</span></div><button className="btn" onClick={handleAdd}>增加商品</button></div>)
}
3、总结
1、使用 redux 方便在 reducer 中集中式管理业务代码,提升代码的维护性;
2、使用 store 统一管理 购物车的状态,方便代码进行复用,只需要传入对应参数即可;
3、如果是简单的逻辑,使用redux 进行状态管理,会增加代码的负责性,不如 直接使用 React 中自带的 HOOKS 进行实现;
4、多页面共享数据状态,业务逻辑复杂的,使用 redux 更方便一些;
相关文章:
React 之 Redux 第三十一节 useDispatch() 和 useSelector()使用以及详细案例
使用 Redux 实现购物车案例 由于 redux 5.0 已经将 createStore 废弃,我们需要先将 reduxjs/toolkit 安装一下; yarn add reduxjs/toolkit// 或者 npm install reduxjs/toolkit使用 vite 创建 React 项目时候 配置路径别名 : // 第一种写法…...
RHCSA Linux系统 vim 编辑器
1.使用 vi/vim 编辑文件 [rootlocalhost ~]# vim /etc/passwd 默认进入命令模式 2.命令模式下的常用快捷键 (1) 光标跳转快捷键 (2)复制、粘贴、删除 3.编辑模式 4.末行模式 (1)查找关键字替换 (2&…...
ABAP小白开发操作手册+(十)验证和替代——下
目录 一、前言 二、替代步骤详解 1、新建替换 2、新建步骤 3、创建先决条件 4、补充替换 5、ZRGGBS000 三、传输请求 四、DEBUG 一、前言 本章内容分为上下两篇,包括验证和替代, 上篇:验证步骤、传输验证请求、DEBUG 下篇…...
鸿蒙小案例---心情日记
效果演示 代码实现 import { router, window } from kit.ArkUIEntry Component struct Index {async aboutToAppear(): Promise<void> {let w await window.getLastWindow(getContext())w.setWindowSystemBarProperties({statusBarColor: #00C6C3,statusBarContentColo…...
一种单脉冲雷达多通道解卷积前视成像方法【论文阅读】
一种单脉冲雷达多通道解卷积前视成像方法-李悦丽-2007 1. 论文的研究目标与实际意义1.1 研究目标1.2 实际问题与产业意义2. 论文提出的思路、方法及模型2.1 多通道解卷积(MCD)技术的核心思想2.1.1 数学模型与公式推导2.1.2 针对单脉冲雷达的改进2.2 方法与传统技术的对比3. 实…...
React中使用dnd-kit实现拖拽排序
使用dnd-kit实现拖拽排序 效果展示 实现源码 安装依赖 dad-kit github地址 yarn add dnd-kit/core dnd-kit/sortable dnd-kit/utilities dnd-kit/modifiers这几个包的作用 dnd-kit/core:核心库,提供基本的拖拽功能。dnd-kit/sortable:扩…...
深度学习总结(3)
数据批量的概念 通常来说,深度学习中所有数据张量的第一个轴(也就是轴0,因为索引从0开始)都是样本轴[samples axis,有时也叫样本维度(samples dimension)]。深度学习模型不会一次性处理整个…...
Android Studio Narwhal | 2025.1.1新功能
Android Studio 中的 Gemini 支持多模式图像附件 现在,您可以在 Android Studio 中将图像直接附加到 Gemini 提示中。您可以即时获取复杂技术图表的洞察,或使用设计模型生成相应的代码框架。这种将视觉环境无缝集成到 AI 辅助工作流程中的设计方式&…...
XML语法指南——从入门到精通
1、引言 XML(可扩展标记语言)是一种用于存储和传输数据的标记语言,它被设计为具有自我描述性且易于理解。本文将全面介绍XML的语法规则,包括元素、属性、命名规则、转义字符等核心概念。 2、XML文档基本结构 一个完整的XML文档…...
利用高阶函数实现AOP
如大家所熟悉的,AOP(面向切面编程)的主要作用是把一些跟核心业务逻辑模块无关的功能抽离出来,这些跟业务逻辑无关的功能通常包括日志统计、安全控制、异常处理等。 把这些功能抽离出来之后,再通过“动态织入”的方式掺…...
原生SSE实现AI智能问答+Vue3前端打字机流效果
实现流程: 1.用户点击按钮从右侧展开抽屉(drawer),打开模拟对话框 2.用户输入问题,点击提问按钮,创建一个SSE实例请求后端数据,由于SSE是单向流,所以每提一个问题都需要先把之前的实…...
windows11下pytorch(cpu)安装
先装anaconda 见最下方 Pytorch 官网:PyTorch 找到下图(不要求版本一样)(我的电脑是集显(有navdia的装gpu),装cpu) 查看已有环境列表 创建环境 conda create –n 虚拟环境名字(…...
C++【string类】(一)
string类 1.为什么要学string?2.标准库类型的string类2.1 string类的构造2.2string类的析构2.3读写string类2.4string类的赋值重载2.5string的遍历 1.为什么要学string? 在C语言中字符出串是以‘/0’结尾的一些字符的结合,为了操作方便&…...
yarn:error Error: certificate has expiredERR_OSSL_EVP_UNSUPPORTED解决
yarn:error Error: certificate has expired 报错 error Error: certificate has expiredat TLSSocket.onConnectSecure (node:_tls_wrap:1679:34)at TLSSocket.emit (node:events:519:28)at TLSSocket._finishInit (node:_tls_wrap:1078:8)at ssl.onhandshakedon…...
Git Cherry-pick:核心命令、实践详解
Git Cherry-pick:核心命令、实践详解 一、Cherry-pick 1. 简介 在多分支协作开发中,我们常常只想把某个分支上的单个或若干次提交,合并到另一个分支,而不需要合并整个分支。Git 提供的 cherry-pick 命令,正是为此而…...
ffmpeg播放音视频流程
文章目录 🎬 FFmpeg 解码播放流程概览(以音视频文件为例)1️⃣ 创建结构体2️⃣ 打开音视频文件3️⃣ 查找解码器并打开解码器4️⃣ 循环读取数据包(Packet)5️⃣ 解码成帧(Frame)6️⃣ 播放 / …...
OSPF的数据报文格式【复习篇】
OSPF协议是跨层封装的协议(跨四层封装),直接将应用层的数据封装在网络层协议之后,IP协议包中协议号字段对应的数值为89 OSPF的头部信息: 所有的数据共有的信息字段 字段名描述版本当前OSPF进程使用的版本(…...
Spark大数据分析与实战笔记(第四章 Spark SQL结构化数据文件处理-04)
文章目录 每日一句正能量第4章 Spark SQL结构化数据文件处理章节概要4.4 RDD转换DataFrame4.4.1 反射机制推断Schema4.4.2 编程方式定义Schema 每日一句正能量 一个人若想拥有聪明才智,便需要不断地学习积累。 第4章 Spark SQL结构化数据文件处理 章节概要 在很多情…...
设计模式 --- 状态模式
状态模式是一种行为型设计模式,允许对象在内部状态改变时动态改变其行为,使对象的行为看起来像是改变了。该模式通过将状态逻辑拆分为独立类,消除复杂的条件分支语句,提升代码的可维护性和扩展性。 状态模式的…...
将外网下载的 Docker 镜像拷贝到内网运行
将外网下载的 Docker 镜像拷贝到内网运行,可以通过以下步骤实现: 一、在有外网访问权限的机器上操作 下载镜像 使用docker pull命令下载所需的镜像。例如,如果你需要下载一个名为nginx的镜像,可以运行以下命令:docke…...
Seq2Seq - GRU补充讲解
nn.GRU 是 PyTorch 中实现门控循环单元(Gated Recurrent Unit, GRU)的模块。GRU 是一种循环神经网络(RNN)的变体,用于处理序列数据,能够更好地捕捉长距离依赖关系。 ⭐重点掌握输入输出部分输入张量&#…...
从0到1构建工具站 - day6 (在线编程工具-docker)
从0到1构建工具站 网页在线编程工具构建(php、go、python)搜集其他在线编程网站构建php8运行环境Dockerfiledocker-compose.yaml 构建python运行环境Dockerfiledocker-compose.yml 核心调用python的docker-sdk包执行命令执行文件流程执行命令流程pythonp…...
C++面向对象编程优化实战:破解性能瓶颈,提升应用效率
🧑 博主简介:CSDN博客专家、CSDN平台优质创作者,高级开发工程师,数学专业,拥有高级工程师证书;擅长C/C、C#等开发语言,熟悉Java常用开发技术,能熟练应用常用数据库SQL server,Oracle…...
JavaWeb 课堂笔记 —— 06 Maven
本系列为笔者学习JavaWeb的课堂笔记,视频资源为B站黑马程序员出品的《黑马程序员JavaWeb开发教程,实现javaweb企业开发全流程(涵盖SpringMyBatisSpringMVCSpringBoot等)》,章节分布参考视频教程,为同样学习…...
【Linux】网络层协议 IP
网络层协议 IP 一. 基本概念二. IP 协议格式三. 网段划分 (重点)1. 传统方法2. 子网掩码 四. 特殊 IP 地址五. IP 地址的数量限制六. 私有 IP 地址和公网 IP 地址七. 运营商1. 基本网络情况2. 全球网络情况 八. 路由九. IP 报文的分片和组装 网络层:在复杂的网络环境…...
嵌入式系统中如何构建事件响应架构
在复杂的嵌入式系统中,串口、BLE、定时器、中断等多种事件源并存,如何高效地统一调度这些异步事件,是系统稳定性和可维护性的关键。本文将结合 BLE 系统架构的经验,讲解如何构建一个通用的事件响应架构。 🧩 一、什么是事件响应架构? 事件响应架构(Event-Driven Archi…...
Flutter报错:Warning: CocoaPods is installed but broken
最近在做Flutter开发,在跑iOS的时候报错: 结论:CocoaPods安装有问题 解决办法: 先卸载本地CocoaPods,然后重新安装 查看当前版本 gem list | grep cocoapods执行卸载 sudo gem uninstall cocoapods直到 which -a…...
JdbcTemplate基本使用
JdbcTemplate概述 它是spring框架中提供的一个对象,是对原始繁琐的JdbcAPI对象的简单封装。spring框架为我们提供了很多的操作模板类。例如:操作关系型数据的JdbcTemplate和MbernateTemplate,操作nosql数据库的RedisTemplate,操作消息队列的…...
地图服务热点追踪:创新赋能,领航出行与生活
在数字化时代,地图服务早已超越了传统的导航范畴,成为智能出行、生活服务乃至应急救援等多领域的关键支撑。近期,地图服务领域热点不断,从技术创新到应用拓展,每一次突破都在重塑我们与世界交互的方式。本文将深入剖析…...
Flutter Invalid constant value.
0x00 问题 参数传入变量,报错! 代码 const Padding(padding: EdgeInsets.all(20),child: GradientProgressIndicator(value: _progress), ),_progress 参数报错:Invalid constant value. 0x01 原因 这种情况,多发生于ÿ…...
网络基础-路由技术和交换技术以及其各个协议
四、路由技术和交换技术 4.1路由技术 静态与动态协议的关系: 1,静态路由:由网络管理员手工填写的路由信息。 2,动态路由:所有路由器运行相同路由协议,之后,通过路由器之间的沟通,协…...
替换jeecg图标
替换jeecg图标 ant-design-vue-jeecg/src/components/tools/Logo.vue <!-- <img v-else src"~/assets/logo.svg" alt"logo">-->...
C#里使用WPF的MaterialDesignThemes
先要下载下面的包: <?xml version="1.0" encoding="utf-8"?> <packages><package id="MaterialDesignColors" version="5.2.1" targetFramework="net48" /><package id="MaterialDesignTheme…...
四六级听力考试播音系统:构建播放控制智能化、发射系统双备份、发射功率有冗余、安全稳定可靠的英语四六级听力播音系统使用环境
四六级听力考试播音系统:构建播放控制智能化、发射系统双备份、发射功率有冗余、安全稳定可靠的英语四六级听力播音系统使用环境 北京海特伟业科技有限公司任洪卓于2025年4月9日发布 传统的四六级听力考试播音系统往往存在信号不稳定、容易受干扰、无发射备份、无功率冗余、更…...
JavaScript性能优化(下)
1. 使用适当的算法和逻辑 JavaScript性能优化是一个复杂而重要的话题,尤其是在构建大型应用时。通过使用适当的算法和逻辑,可以显著提高代码的效率和响应速度。以下是一些关键策略和实践,用于优化JavaScript性能: 1.1. 采用适当…...
优先级队列的应用
第一题: 题解思路: 1、建立降序的优先级队列(底层是通过大堆来实现); 2、取最大的两个数来相减得到的结果再加入到优先级队列中(优先级队列会自动的排序); 3、返回队列的头部或者0即可; 题解代…...
从 macos 切换到 windows 上安装的工具类软件
起因 用了很多年的macos, 已经习惯了macos上的操作, 期望能在windows上获得类似的体验, 于是花了一些时间来找windows上相对应的软件. 截图软件 snipaste windows和macos都有的软件, 截图非常好用 文件同步软件 oneDrive: 尝试了不同的同步软件, 还是微软在各…...
探索原生JS的力量:自定义实现类似于React的useState功能
1.写在前面 本方案特别适合希望在历史遗留的原生JavaScript项目中实现简单轻量级数据驱动机制的开发者。无需引入任何框架或第三方库,即可按照此方法封装出类似于React中useState的功能,轻松为项目添加状态管理能力,既保持了项目的轻量性&am…...
Android系统深度定制:源码级拦截adb install的完整解决方案
一、需求背景与技术挑战 在Android 12.0系统定制开发中,我们面临一个关键需求:需要实现设备级应用安装管控,要求彻底禁用adb install安装方式。这种管控需要满足以下技术指标: 系统级全局拦截,覆盖所有adb install安装…...
基于大模型的非阵发性室性心动过速风险预测与诊疗方案研究报告
目录 一、引言 1.1 研究背景与意义 1.2 研究目的 1.3 国内外研究现状 二、非阵发性室性心动过速概述 2.1 定义与分类 2.2 发病机制 2.3 临床症状与诊断方法 三、大模型在预测中的应用原理 3.1 大模型简介 3.2 数据收集与预处理 3.3 模型训练与优化 3.4 预测原理与…...
HttpServletRequest是什么
HttpServletRequest 是 Java Servlet API 中的一个接口,表示 HTTP 请求对象。它封装了客户端(如浏览器)发送到服务器的请求信息,并提供了访问这些信息的方法。 1. 基本概念 作用: HttpServletRequest 提供了一种机制&…...
【现代深度学习技术】循环神经网络02:文本预处理
【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈PyTorch深度学习 ⌋ ⌋ ⌋ 深度学习 (DL, Deep Learning) 特指基于深层神经网络模型和方法的机器学习。它是在统计机器学习、人工神经网络等算法模型基础上,结合当代大数据和大算力的发展而发展出来的。深度学习最重…...
【微服务】SpringBoot 整合 Lock4j 分布式锁使用详解
目录 一、前言 二、Lock4j 概述 2.1 Lock4j 介绍 2.1.1 Lock4j 是什么 2.1.2 Lock4j 主要特征 2.1.3 Lock4j 技术特点 2.2 Lock4j 支持的锁类型 2.3 Lock4j 工作原理 2.4 Lock4j 应用场景 三、springboot 整合 lock4j 3.1 前置准备 3.1. 1 导入依赖 3.2 基于Redis…...
如何将前端组件封装并发布到npm的步骤详解
以下是封装前端组件并发布至npm仓库的完整步骤指南,结合多个最佳实践和常见问题解决方案: 一、环境准备与项目初始化 创建项目结构 • 使用Vue CLI或Create React App初始化项目: vue create my-component-lib # Vue npx create-react-app my-component-lib --template ty…...
【QT】QWidget 概述与核心属性(API)
🌈 个人主页:Zfox_ 🔥 系列专栏:Qt 目录 一:🔥 控件概述 🦋 控件体系的发展阶段 二:🔥 QWidget 核心属性 🦋 核心属性概览🦋 用件可用(…...
vue + uniapp 实现仿百度地图/高德地图/美团/支付宝 滑动面板 纯css 实现
概要 使用百度地图、各种单车APP时,对地图上的滑动面板很感兴趣,于是根据自己的理解实现了一下 之前用的js实现,滑动的时候没有原生好 这一次用的css实现 代码 <template><view class"container"><mapstyle"…...
124. 二叉树中的最大路径和
https://leetcode.cn/problems/binary-tree-maximum-path-sum/description/?envTypestudy-plan-v2&envIdtop-interview-150对于这题我开始的思路是路径我们可以看作是一条线,我们确定一个点后可以往两侧延伸(就是左右子树的方向)&#x…...
spark运行架构
运行架构:Spark采用master - slave结构,Driver作为master负责作业任务调度,Executor作为slave负责实际执行任务。 核心组件: Driver:执行Spark任务的main方法,负责将用户程序转化为作业、调度任务、跟踪E…...
开源的7B参数OCR视觉大模型:RolmOCR
1. 背景介绍 早些时候,Allen Institute for AI 发布了 olmOCR,这是一个基于 Qwen2-VL-7B 视觉语言模型(VLM)的开源工具,用于处理 PDF 和其他复杂文档的 OCR(光学字符识别)。开发团队对该工具的…...
Http代理服务器选型与搭建
代理服务器选型-Squid 缓存加速 缓存频繁访问的网页、图片等静态资源,减少对原始服务器的重复请求,提升响应速度支持HTTP、HTTPS、FTP等协议,通过本地缓存直接响应客户端请求 访问控制 基于ACL(访问控制列表)实现精细…...