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

JavaScript系列(41)--状态管理实现详解

JavaScript状态管理实现详解 🔄

今天,让我们深入探讨JavaScript的状态管理实现。状态管理是现代前端应用中的核心概念,它帮助我们有效地管理和同步应用数据。

状态管理基础概念 🌟

💡 小知识:状态管理是一种用于管理应用程序数据流的模式,它通过集中式存储和单向数据流来保持数据的一致性和可预测性。

基本实现 📊

// 1. 简单的状态存储
class SimpleStore {constructor(initialState = {}) {this.state = initialState;this.listeners = new Set();}getState() {return this.state;}setState(newState) {this.state = { ...this.state, ...newState };this.notify();}subscribe(listener) {this.listeners.add(listener);return () => this.listeners.delete(listener);}notify() {this.listeners.forEach(listener => listener(this.state));}
}// 2. 支持Action的Store
class ActionStore {constructor(reducer, initialState = {}) {this.reducer = reducer;this.state = initialState;this.listeners = new Set();}dispatch(action) {this.state = this.reducer(this.state, action);this.notify();}getState() {return this.state;}subscribe(listener) {this.listeners.add(listener);return () => this.listeners.delete(listener);}notify() {this.listeners.forEach(listener => listener(this.state));}
}// 3. 状态选择器
class StoreSelector {constructor(store) {this.store = store;this.selectors = new Map();this.cache = new Map();store.subscribe(() => this.updateSelectors());}addSelector(key, selectorFn) {this.selectors.set(key, selectorFn);this.updateSelector(key);}select(key) {return this.cache.get(key);}updateSelectors() {this.selectors.forEach((_, key) => this.updateSelector(key));}updateSelector(key) {const selector = this.selectors.get(key);const state = this.store.getState();const newValue = selector(state);if (!this.cache.has(key) || !this.shallowEqual(this.cache.get(key), newValue)) {this.cache.set(key, newValue);}}shallowEqual(obj1, obj2) {if (obj1 === obj2) return true;if (!obj1 || !obj2) return false;return Object.keys(obj1).every(key => obj1[key] === obj2[key]);}
}

高级功能实现 🚀

// 1. 中间件系统
class MiddlewareStore {constructor(reducer, initialState = {}) {this.reducer = reducer;this.state = initialState;this.listeners = new Set();this.middlewares = [];}use(middleware) {this.middlewares.push(middleware);}dispatch(action) {const middlewareAPI = {getState: () => this.state,dispatch: (action) => this.dispatch(action)};const chain = this.middlewares.map(middleware => middleware(middlewareAPI));const composedDispatch = this.compose(...chain)(this.baseDispatch.bind(this));composedDispatch(action);}baseDispatch(action) {this.state = this.reducer(this.state, action);this.notify();}compose(...funcs) {if (funcs.length === 0) return arg => arg;if (funcs.length === 1) return funcs[0];return funcs.reduce((a, b) => (...args) => a(b(...args)));}// ... 其他基本方法同ActionStore
}// 2. 时间旅行调试器
class TimeTravel {constructor(store) {this.store = store;this.history = [{ state: store.getState(), action: '@@INIT' }];this.currentIndex = 0;store.subscribe(() => {if (this.isTimeTraveling) return;this.history = this.history.slice(0, this.currentIndex + 1);this.history.push({state: store.getState(),action: this.lastAction});this.currentIndex = this.history.length - 1;});}recordAction(action) {this.lastAction = action;}undo() {if (this.currentIndex > 0) {this.isTimeTraveling = true;this.currentIndex--;this.store.setState(this.history[this.currentIndex].state);this.isTimeTraveling = false;}}redo() {if (this.currentIndex < this.history.length - 1) {this.isTimeTraveling = true;this.currentIndex++;this.store.setState(this.history[this.currentIndex].state);this.isTimeTraveling = false;}}getHistory() {return this.history;}jumpTo(index) {if (index >= 0 && index < this.history.length) {this.isTimeTraveling = true;this.currentIndex = index;this.store.setState(this.history[index].state);this.isTimeTraveling = false;}}
}// 3. 状态持久化
class PersistentStore {constructor(store, options = {}) {this.store = store;this.options = {key: 'app_state',storage: localStorage,serialize: JSON.stringify,deserialize: JSON.parse,...options};this.init();}init() {// 加载持久化的状态const savedState = this.options.storage.getItem(this.options.key);if (savedState) {try {const state = this.options.deserialize(savedState);this.store.setState(state);} catch (error) {console.error('Failed to load persisted state:', error);}}// 订阅状态变化this.store.subscribe(() => this.persist());}persist() {try {const state = this.store.getState();const serialized = this.options.serialize(state);this.options.storage.setItem(this.options.key, serialized);} catch (error) {console.error('Failed to persist state:', error);}}clear() {this.options.storage.removeItem(this.options.key);}
}

性能优化技巧 ⚡

// 1. 批量更新优化
class BatchUpdateStore {constructor(initialState = {}) {this.state = initialState;this.listeners = new Set();this.pendingUpdates = new Map();this.isUpdating = false;}setState(key, value) {this.pendingUpdates.set(key, value);this.scheduleBatchUpdate();}scheduleBatchUpdate() {if (!this.isUpdating) {this.isUpdating = true;Promise.resolve().then(() => this.processBatchUpdate());}}processBatchUpdate() {const newState = { ...this.state };this.pendingUpdates.forEach((value, key) => {newState[key] = value;});this.state = newState;this.pendingUpdates.clear();this.isUpdating = false;this.notify();}
}// 2. 选择器优化
class MemoizedSelector {constructor() {this.cache = new Map();this.lastArgs = new Map();}createSelector(dependencies, combiner) {return (...args) => {const key = JSON.stringify(args);const depValues = dependencies.map(dep => dep(...args));// 检查依赖是否改变if (this.shouldUpdate(key, depValues)) {const result = combiner(...depValues);this.cache.set(key, result);this.lastArgs.set(key, depValues);}return this.cache.get(key);};}shouldUpdate(key, newArgs) {if (!this.cache.has(key)) return true;const lastArgs = this.lastArgs.get(key);return !lastArgs || !this.shallowEqual(lastArgs, newArgs);}shallowEqual(arr1, arr2) {return arr1.length === arr2.length &&arr1.every((item, index) => item === arr2[index]);}
}// 3. 状态分片
class SlicedStore {constructor() {this.slices = new Map();this.listeners = new Map();}createSlice(name, reducer, initialState) {if (this.slices.has(name)) {throw new Error(`Slice ${name} already exists`);}this.slices.set(name, {state: initialState,reducer});this.listeners.set(name, new Set());}dispatch(sliceName, action) {const slice = this.slices.get(sliceName);if (!slice) {throw new Error(`Slice ${sliceName} not found`);}const newState = slice.reducer(slice.state, action);if (newState !== slice.state) {slice.state = newState;this.notifySliceListeners(sliceName);}}subscribe(sliceName, listener) {const listeners = this.listeners.get(sliceName);if (!listeners) {throw new Error(`Slice ${sliceName} not found`);}listeners.add(listener);return () => listeners.delete(listener);}notifySliceListeners(sliceName) {const listeners = this.listeners.get(sliceName);const state = this.slices.get(sliceName).state;listeners.forEach(listener => listener(state));}
}

最佳实践建议 💡

  1. 状态设计模式
// 1. 状态隔离
class IsolatedStore {constructor() {this.stores = new Map();}createStore(name, initialState) {if (this.stores.has(name)) {throw new Error(`Store ${name} already exists`);}const store = new SimpleStore(initialState);this.stores.set(name, store);return store;}getStore(name) {const store = this.stores.get(name);if (!store) {throw new Error(`Store ${name} not found`);}return store;}
}// 2. 状态同步
class SyncedStore {constructor(stores) {this.stores = stores;this.syncListeners = new Map();}sync(sourceStore, targetStore, mapper) {const unsubscribe = sourceStore.subscribe(state => {const mappedState = mapper(state);targetStore.setState(mappedState);});this.syncListeners.set(`${sourceStore.name}-${targetStore.name}`,unsubscribe);}unsync(sourceStore, targetStore) {const key = `${sourceStore.name}-${targetStore.name}`;const unsubscribe = this.syncListeners.get(key);if (unsubscribe) {unsubscribe();this.syncListeners.delete(key);}}
}// 3. 状态验证
class ValidatedStore {constructor(schema) {this.schema = schema;this.store = new SimpleStore();}setState(newState) {const validationResult = this.validateState(newState);if (validationResult.isValid) {this.store.setState(newState);} else {throw new Error(`Invalid state: ${validationResult.errors.join(', ')}`);}}validateState(state) {const errors = [];let isValid = true;Object.entries(this.schema).forEach(([key, validator]) => {if (!validator(state[key])) {isValid = false;errors.push(`Invalid value for ${key}`);}});return { isValid, errors };}
}

结语 📝

状态管理是现代JavaScript应用中的核心概念,通过本文,我们学习了:

  1. 状态管理的基本概念和实现
  2. 高级功能如中间件和时间旅行
  3. 性能优化技巧
  4. 最佳实践和设计模式
  5. 状态验证和同步策略

💡 学习建议:在实践中,要根据应用的规模和复杂度选择合适的状态管理方案。对于小型应用,简单的状态存储就足够了;对于大型应用,则需要考虑使用更完整的状态管理解决方案。


如果你觉得这篇文章有帮助,欢迎点赞收藏,也期待在评论区看到你的想法和建议!👇

终身学习,共同成长。

咱们下一期见

💻

相关文章:

JavaScript系列(41)--状态管理实现详解

JavaScript状态管理实现详解 &#x1f504; 今天&#xff0c;让我们深入探讨JavaScript的状态管理实现。状态管理是现代前端应用中的核心概念&#xff0c;它帮助我们有效地管理和同步应用数据。 状态管理基础概念 &#x1f31f; &#x1f4a1; 小知识&#xff1a;状态管理是一…...

flume和kafka整合 flume和kafka为什么一起用?

‌Flume和Kafka一起使用的主要原因是为了实现高效、可靠的数据采集和实时处理。‌‌12 实时流式日志处理的需求 Flume和Kafka结合使用的主要目的是为了完成实时流式的日志处理。Flume负责数据的采集和传输,而Kafka则作为消息缓存队列,能够有效地缓冲数据,防止数据堆积或丢…...

【深度学习】 自动微分

自动微分 正如上节所说&#xff0c;求导是几乎所有深度学习优化算法的关键步骤。 虽然求导的计算很简单&#xff0c;只需要一些基本的微积分。 但对于复杂的模型&#xff0c;手工进行更新是一件很痛苦的事情&#xff08;而且经常容易出错&#xff09;。 深度学习框架通过自动…...

什么是三高架构?

大家好&#xff0c;我是锋哥。今天分享关于【什么是三高架构?】面试题。希望对大家有帮助&#xff1b; 什么是三高架构? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 “三高架构”通常是指高可用性&#xff08;High Availability&#xff09;、高性能&#xff…...

IOS 自定义代理协议Delegate

QuestionViewCell.h文件代码&#xff0c;定义代理协议 protocol QuestionViewCellDelegate <NSObject>- (void)cellIsOpenDidChangeAtIndexPath:(NSIndexPath *)indexPath;endinterface QuestionViewCell : UITableViewCellproperty (nonatomic, weak) id<QuestionVi…...

【flutter版本升级】【Nativeshell适配】nativeshell需要做哪些更改

flutter 从3.13.9 升级&#xff1a;3.27.2 nativeshell组合库中的 1、nativeshell_build库替换为github上的最新代码 可以解决两个问题&#xff1a; 一个是arg("--ExtraFrontEndOptions--no-sound-null-safety") 在新版flutter中这个构建参数不支持了导致的build错误…...

C#编程:List.ForEach与foreach循环的深度对比

在C#中&#xff0c;List<T>.ForEach 方法和传统的 foreach 循环都用于遍历列表中的元素并对每个元素执行操作&#xff0c;但它们之间有一些关键的区别。 List<T>.ForEach 方法 方法签名&#xff1a;public void ForEach(Action<T> action)类型&#xff1a;…...

leetcode_2762. 不间断子数组

2762. 不间断子数组 - 力扣&#xff08;LeetCode&#xff09; 运用滑动窗口和multise(平衡二叉树实现) 符合条件 右窗口向右扩展 不符合条件 左窗口向左扩展 class Solution { public:long long continuousSubarrays(vector<int>& nums) {int max, min; //表示窗…...

Java学习教程,从入门到精通,JDBC创建数据库语法知识点及案例代码(99)

JDBC创建数据库语法知识点及案例代码 一、JDBC创建数据库语法 在JDBC中&#xff0c;创建数据库主要通过执行SQL语句来实现。其基本语法如下&#xff1a; CREATE DATABASE database_name;CREATE DATABASE 是固定的SQL语句关键字&#xff0c;用于指定创建数据库的操作。databa…...

进阶——第十六届蓝桥杯(sscanf的运用)

声明变量 char tx_buf[30];char rx_buf[30];char car_type[5];char car_num[5];char car_time[15]; int sscanf(const char *str, const char *format,...); sscanf函数功能 sscanf 函数从字符串 str 中读取数据&#xff0c;根据 format 所指定的格式将数据存储到后续的变量中…...

嵌入式硬件篇---ADC模拟-数字转换

文章目录 前言第一部分&#xff1a;STM32 ADC的主要特点1.分辨率2.多通道3.转换模式4.转换速度5.触发源6.数据对齐7.温度传感器和Vrefint通道 第二部分&#xff1a;STM32 ADC的工作流程&#xff1a;1.配置ADC2.启动ADC转换 第三部分&#xff1a;ADC转化1.抽样2.量化3.编码 第四…...

Spark Streaming编程基础

文章目录 1. 流式词频统计1.1 Spark Streaming编程步骤1.2 流式词频统计项目1.2.1 创建项目1.2.2 添加项目依赖1.2.3 修改源目录1.2.4 添加scala-sdk库1.2.5 创建日志属性文件 1.3 创建词频统计对象1.4 利用nc发送数据1.5 启动应用&#xff0c;查看结果 2. 编程模型的基本概念3…...

android wifi AsyncChannel(WifiManager和WifiP2pManager)

AynscChannel的讲解 [Android]AsyncChannel介绍-CSDN博客 WifiP2pManager里的channel的使用理解 WifiP2pManager.java public void createGroup(Channel c, ActionListener listener) {checkChannel(c);c.mAsyncChannel.sendMessage(CREATE_GROUP, WifiP2pGroup.NETWORK_ID_PE…...

生存网络与mlr3proba

在R语言中,mlr3包是一个用于机器学习的强大工具包。它提供了一种简单且灵活的方式来执行超参数调整。 生存网络是一种用于生存分析的模型,常用在医学和生物学领域。生存分析是一种统计方法,用于研究事件发生的时间和相关因素对事件发生的影响。生存网络可以用来预测个体在给…...

C#Object类型的索引,序列化和反序列化

前言 最近在编写一篇关于标准Mes接口框架的文章。其中有一个非常需要考究的内容时如果实现数据灵活和可使用性强。因为考虑数据灵活性&#xff0c;所以我一开始选取了Object类型作为数据类型&#xff0c;Object作为数据Value字段&#xff0c;String作为数据Key字段&#xff0c…...

【动态规划】记忆化搜索

Ban or Problem - A - Codeforces 【CCPC】2022年绵阳站部分题解&#xff08;ACGM&#xff09;_ban or pick, whats the trick-CSDN博客 #include<iostream> using namespace std; #include<cstring> #include<algorithm> #define inf -0x3f3f3f3f #defi…...

深度学习 DAY1:RNN 神经网络及其变体网络(LSTM、GRU)

实验介绍 RNN 网络是一种基础的多层反馈神经网络&#xff0c;该神经网络的节点定向连接成环&#xff0c;其内部状态可以展示动态时序行为。相比于前馈神经网络&#xff0c;该网络内部具有很强的记忆性&#xff0c;它可以利用它内部的记忆来处理任意时序的输入序列&#xff0c;…...

BW复制ERP数据源跑程序激活后才可见

场景&#xff1a; BW提取ERP数据走ODP通道之后&#xff0c;数据源需要用下列程序激活加入白名单后才能被BW系统访问到&#xff1b; 检查&#xff1a; 1、RSA6检查数据源是否可正常使用&#xff0c;若为绿√表示可正常访问&#xff0c;反之&#xff0c;则不行。 2、白名单表ROO…...

MarsCode青训营打卡Day10(2025年1月23日)|稀土掘金-147.寻找独一无二的糖葫芦串、119.游戏队友搜索

资源引用&#xff1a; 147.寻找独一无二的糖葫芦串 119.游戏队友搜索 今日小记&#xff1a; 回乡聚会陪家人&#xff0c;休息一天~ 稀土掘金-147.寻找独一无二的糖葫芦串&#xff08;147.寻找独一无二的糖葫芦串&#xff09; 题目分析&#xff1a; 给定n个长度为m的字符串表…...

无人机 PX4 飞控 | PX4源码添加自定义参数方法并用QGC显示与调整

无人机 PX4 飞控 | PX4源码添加自定义参数方法并用QGC显示与调整 0 前言 之前文章添加了一个自定义的模块&#xff0c;本篇文章在之前的自定义模块中&#xff0c;添加两个自定义参数 使用QGC显示出来&#xff0c;并通过QGC调整参数值&#xff0c;代码实现参数更新 新增的参…...

【全栈】SprintBoot+vue3迷你商城-扩展:vue3项目创建及目录介绍

【全栈】SprintBootvue3迷你商城-扩展&#xff1a;vue3项目创建及目录介绍 往期的文章都在这里啦&#xff0c;大家有兴趣可以看一下 【全栈】SprintBootvue3迷你商城&#xff08;1&#xff09; 【全栈】SprintBootvue3迷你商城&#xff08;2&#xff09; 【全栈】SprintBootvu…...

Linux系统 C/C++编程基础——基于Qt的图形用户界面编程

ℹ️大家好&#xff0c;我是练小杰&#xff0c;今天周四了&#xff0c;距离除夕只有4天了&#xff0c;各位今年卫生都搞完了吗&#xff01;&#x1f606; 本文是接着昨天Linux 系统C/C编程的知识继续讲&#xff0c;基于Qt的图形用户界面编程概念及其命令&#xff0c;后续会不断…...

23.日常算法

1. 最小绝对差 题目来源 给你个整数数组 arr&#xff0c;其中每个元素都 不相同。请你找到所有具有最小绝对差的元素对&#xff0c;并且按升序的顺序返回。 每对元素对 [a,b] 如下&#xff1a; a , b 均为数组 arr 中的元素 a < b b - a 等于 arr 中任意两个元素的最小绝对…...

迅为RK3568开发板篇OpenHarmony实操HDF驱动控制LED-添加内核编译

编译内核时将该 HDF 驱动编译到镜像中&#xff0c;接下来编写驱动编译脚本 Makefile&#xff0c;代码如下所示&#xff1a; 加入编译体系&#xff0c;填加模块目录到 drivers/hdf_core/adapter/khdf/linux/Makefile 文件 更多内容可以关注&#xff1a;迅为RK3568开发板篇OpenHa…...

为AI聊天工具添加一个知识系统 之54 为事务处理 设计 基于DDD的一个 AI操作系统 来处理维度

本文要点 要点 Architecture程序 它被设计为一个双面神结构的控制器&#xff0c;它的两侧一侧编译执行另一侧 解释执行&#xff0c;自已则是一个 翻译器--通过提供两个不同取向之间 的 结构映射的显示器&#xff08;带 图形用户接口GUI和命令行接口CLI 两种 接口&#xff09…...

Golang 中除了加锁还有哪些安全读写共享变量的方式?

Golang 中除了加锁还有哪些安全读写共享变量的方式&#xff1f; 在 Golang 中&#xff0c;除了使用 Mutex 锁来保护共享变量外&#xff0c;还可以通过 Channel 和 原子性操作 来实现安全读写共享变量。 1. 使用 Channel 原理 Channel 是 Golang 中用于 Goroutine 之间通信的…...

【优选算法】8----四数之和

有看过我上篇算法博客并且去做过的铁子们&#xff0c;对这道题的话应该就不会那么陌生了&#xff0c;因为这两道题 的解题思路有着异曲同工之妙~ -----------------------------------------begin------------------------------------- 题目解析&#xff1a; 跟三数之和就多了…...

订单状态定时处理、来单提醒和客户催单(day10)

Spring Task 介绍 Spring Task 是 Spring 框架提供的任务调度工具&#xff0c;可以按照约定的时间自动执行某个代码逻辑。 定位&#xff1a; 定时任务框架 作用&#xff1a; 定时自动执行某段Java代码 为什么要在 Java 程序中使用 Spring Task&#xff1f; 应用场景&#xff1…...

备赛蓝桥杯之第十五届职业院校组省赛第一题:智能停车系统

提示&#xff1a;本篇文章仅仅是作者自己目前在备赛蓝桥杯中&#xff0c;自己学习与刷题的学习笔记&#xff0c;写的不好&#xff0c;欢迎大家批评与建议 由于个别题目代码量与题目量偏大&#xff0c;请大家自己去蓝桥杯官网【连接高校和企业 - 蓝桥云课】去寻找原题&#xff0…...

【2024年华为OD机试】(C卷,100分)- 查找接口成功率最优时间段 (JavaScriptJava PythonC/C++)

一、问题描述 题目解析 题目描述 服务之间交换的接口成功率作为服务调用关键质量特性&#xff0c;某个时间段内的接口失败率使用一个数组表示。数组中每个元素都是单位时间内失败率数值&#xff0c;数组中的数值为 0~100 的整数。给定一个数值 minAverageLost&#xff0c;表…...

Linux进度条实现

Linux进度条实现 1.\r\n2.缓冲区3.缓冲区分类4.进度条实现 &#x1f31f;&#x1f31f;hello&#xff0c;各位读者大大们你们好呀&#x1f31f;&#x1f31f; &#x1f680;&#x1f680;系列专栏&#xff1a;【Linux的学习】 &#x1f4dd;&#x1f4dd;本篇内容&#xff1a;\…...

Java如何实现反转义

Java如何实现反转义 前提 最近做的一个需求&#xff0c;是热搜词增加换一批的功能。功能做完自测后&#xff0c;交给了测试伙伴&#xff0c;但是测试第二天后就提了一个bug&#xff0c;出现了未知词 levis。第一眼看着像公司售卖的一个品牌-李维斯。然后再扒前人写的代码&…...

计算机网络 (57)改进“尽最大努力交付”的服务

前言 计算机网络中的“尽最大努力交付”服务是网络层的一种数据传输方式。这种服务的特点是网络层只负责尽力将数据报从源端传输到目的端&#xff0c;而不保证数据传输的可靠性。 一、标记与分类 为数据分组打上标记&#xff1a; 给不同性质的分组打上不同的标记&#x…...

Java 基于 SpringBoot 的校园外卖点餐平台微信小程序(附源码,部署,文档)

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…...

重构(4)

&#xff08;一&#xff09;添加解释性变量&#xff0c;使得代码更容易理解&#xff0c;更容易调试&#xff0c;也可以方便功能复用 解释性的变量 总价格为商品总价&#xff08;单价*数量&#xff09;-折扣&#xff08;超过100个以上的打9折&#xff09;邮费&#xff08;原价的…...

【Arduino】语言参考功能

前言 翻译Arduino 参考处列出的常用函数。文中为了减少篇幅&#xff0c;达到能快速翻到查询的目标&#xff0c;在介绍函数中&#xff0c;对部分内容进行了省略&#xff0c;不会列出函数输入参数类型&#xff0c;以及使用注意事项等等&#xff0c;所以若是首次使用或者是调试时出…...

CMake使用CPack制作安装程序

CPack的功能很强大&#xff0c;笔者前面有一博文使用CMake的CPack工具打包项目介绍了一下使用CPack来打包成7z压缩文件&#xff0c;不仅如此&#xff0c;它还可以生成各平台的安装包。 CPack支持以下类型的生成器&#xff1a; 名称文件类型平台及说明STGZSTGZ(.sh)自解压文件…...

Flink运行时架构

一、系统架构 1&#xff09;作业管理器&#xff08;JobManager&#xff09; JobManager是一个Flink集群中任务管理和调度的核心&#xff0c;是控制应用执行的主进程。也就是说&#xff0c;每个应用都应该被唯一的JobManager所控制执行。 JobManger又包含3个不同的组件。 &am…...

平衡二叉树(力扣110)

所谓平衡二叉树&#xff0c;就是每一个节点的左右子树的高度差不大于1。而一个子树的高度&#xff0c;就是父节点的最大高度。这道题的思路其实和二叉树的最大深度(力扣104)-CSDN博客有很大的相似之处&#xff0c;都需要将左右子树的高度返回给父节点&#xff0c;因此也是采用后…...

【玩转全栈】---基于YOLO8的图片、视频目标检测

本篇主要讲YOLO8的具体操作&#xff0c;想要了解YOLO的具体原理&#xff0c;可以去官网查询 目录 下载ultralytics库 开始检测 介绍 YOLOv8&#xff08;You Only Look Once Version 8&#xff09;是 YOLO 系列的最新版本&#xff0c;由 Ultralytics 开发并发布&#xff0c;是一…...

ES6+新特性,var、let 和 const 的区别

在 JavaScript 中&#xff0c;var、let 和 const 都用于声明变量&#xff0c;但它们有一些重要的区别&#xff0c;主要体现在 作用域、可变性和提升机制 等方面。 1. 作用域&#xff08;Scope&#xff09; var: var 声明的变量是 函数作用域&#xff0c;也就是说&#xff0c;它…...

汇编实验·分支程序设计

一、实验目的: 1.能够熟练的进行分支程序的编写,掌握条件语句对应的汇编语言指令的实现 2.掌握多个条件的分支语句的实现原理,理解C语言中的逻辑运算“短路”特征 二、实验内容 1.对2和3任务中的C代码在VS2022中运行,设置生成对应的汇编代码,观察生成代码的不同,着重…...

激光线扫相机无2D图像的标定方案

方案一&#xff1a;基于运动控制平台的标定 适用场景&#xff1a;若激光线扫相机安装在可控运动平台&#xff08;如机械臂、平移台、旋转台&#xff09;上&#xff0c;且平台的运动精度已知&#xff08;例如通过编码器或高精度步进电机控制&#xff09;。 步骤&#xff1a; 标…...

【Python・机器学习】多元回归模型(原理及代码)

前言 自学笔记&#xff0c;分享给语言学/语言教育学方向的&#xff0c;但对语言数据处理感兴趣但是尚未入门&#xff0c;却需要在论文中用到的小伙伴&#xff0c;欢迎大佬们补充或绕道。ps&#xff1a;本文最少限度涉及公式讲解&#xff08;文科生小白友好体质&#xff09;&am…...

ubuntu20.04安装使用direct_visual_lidar_calibration标定雷达和相机

官方链接GitHub - koide3/direct_visual_lidar_calibration: A toolbox for target-less LiDAR-camera calibration [ROS1/ROS2] 官方安装方式 Installation - direct_visual_lidar_calibration 安装依赖 sudo apt install libomp-dev libboost-all-dev libglm-dev libglfw…...

Android 自定义View时四个构造函数使用详解

该文章我们以自定义View继承TextView为例来讲解 创建自定义View命名MyTextView&#xff0c;并使其继承TextView 1、自定义View时第一个构造函数 // 第一个构造函数主要是在Java代码中声明一个MyTextView时所用 // 类似这种(MyTextView myTextViewnew MyTextView(this);) // 不…...

linux中关闭服务的开机自启动

引言 systemctl 是 Linux 系统中用于管理 systemd 服务的命令行工具。它可以用来启动、停止、重启服务&#xff0c;管理服务的开机自启动&#xff0c;以及查看服务的状态等。 什么是 systemd&#xff1f; systemd 是现代 Linux 发行版中默认的 初始化系统&#xff08;init sys…...

【go语言】go的卸载与安装

一、卸载go sudo rm -rf /usr/local/go sudo apt-get remove golang sudo apt-get remove golang-go sudo apt-get autoremove wget https://dl.google.com/go/go1.19.linux-amd64.tar.gz sudo tar -xzf go1.19.linux-amd64.tar.gz -C /usr/local go env -w GOPROXY"http…...

微软Win10 RP 19045.5435(KB5050081)预览版发布!

系统之家1月20日最新报道&#xff0c;微软面向Release Preview频道的Windows Insider项目成员&#xff0c;发布了适用于Windows10 22H2版本的KB5050081更新&#xff0c;更新后系统版本号将升至19045.5435。本次更新增加了对GB18030-2022标准的支持&#xff0c;同时新版日历将为…...

VUE elTree 无子级 隐藏展开图标

这4个并没有下级节点&#xff0c;即它并不是叶子节点&#xff0c;就不需求展示前面的三角展开图标! 查阅官方文档如下描述&#xff0c;支持bool和函数回调处理&#xff0c;这里咱们选择更灵活的函数回调实现。 给el-tree结构配置一下props&#xff0c;注意&#xff01; :pr…...