kotlin 03flow-stateFlow和sharedFlow企业中使用
一 stateFlow和sharedFlow企业中使用
在企业级 Kotlin 项目中,StateFlow
和 SharedFlow
是 状态管理 与 事件分发 的核心工具,尤其在 MVVM 架构中扮演着极为关键的角色。
✅ 企业中如何使用 StateFlow
和 SharedFlow
场景 | 工具 | 示例 |
---|---|---|
UI 状态同步(如加载中、错误、成功) | ✅ StateFlow | 显示进度条、内容或错误页 |
表单数据、选择器、筛选条件 | ✅ StateFlow | 用户输入姓名、选择性别 |
一次性事件(Toast、导航) | ✅ SharedFlow | 登录成功跳转、提示 |
通用事件总线(EventBus 替代) | ✅ SharedFlow | 多页面间通信 |
✅ 核心概念回顾
StateFlow
- 持有一个状态值
value
- 是热流,始终存储并发射最新状态
- 类似于
LiveData
,但更强大 - 适合 UI 状态同步
private val _uiState = MutableStateFlow(UiState.Loading)
val uiState: StateFlow<UiState> = _uiState.asStateFlow()
SharedFlow
- 不持有状态,没有
value
- 默认不回放旧值(除非设置 replay)
- 适合“一次性事件”传递(Toast、导航)
private val _events = MutableSharedFlow<UiEvent>()
val events = _events.asSharedFlow()
✅ 常用的高级操作符(transforming 操作)
这些 API 和普通 Flow
的操作符完全一样,只不过用在 StateFlow
/SharedFlow
上。
1. map
—— 映射转换值
val userNameLength: StateFlow<Int> = userName.map { it.length }.stateIn(viewModelScope, SharingStarted.Eagerly, 0)
- 将字符串长度映射为 Int 状态
stateIn
是将转换结果转为新的StateFlow
2. filter
/ filterNot
—— 条件过滤
val nonEmptyName: Flow<String> = userName.filter { it.isNotBlank() }
- 仅当用户名非空时,才往下游传递
3. combine
—— 多个 Flow 合并成一个
val canSubmit: StateFlow<Boolean> = combine(userName, password) { name, pwd ->name.isNotBlank() && pwd.length >= 6
}.stateIn(viewModelScope, SharingStarted.Eagerly, false)
- 多表单条件满足才能提交
4. distinctUntilChanged
—— 状态去重,避免重复 UI 更新
val state = userName.distinctUntilChanged()
- 如果两次值一样,不发射;适合 UI 避免重复绘制
5. debounce
—— 延迟发射(防抖)
val searchQuery = MutableStateFlow("")val debouncedQuery = searchQuery.debounce(300).filter { it.isNotBlank() }.distinctUntilChanged()
- 防止用户快速输入触发大量搜索请求
- 类似 RxJava 的 debounce 功能
6. onEach
—— 收到值时做一些操作(比如打日志)
val filtered = userName.onEach {Log.d("Flow", "Username changed to $it")
}
7. flatMapLatest
—— 响应式请求场景(新请求来了取消旧的)
val userDetails = userId.flatMapLatest { id -> repository.loadUserDetail(id) }.stateIn(viewModelScope, SharingStarted.Lazily, null)
- 类似 Retrofit 请求,用户快速切换 ID 时,自动取消旧请求
8. stateIn
/ shareIn
—— Flow → StateFlow / SharedFlow
这些是 Flow 转为热流的关键:
val state: StateFlow<Int> = coldFlow.stateIn(viewModelScope, SharingStarted.Eagerly, 0)
val shared: SharedFlow<String> = coldFlow.shareIn(viewModelScope, SharingStarted.Lazily, 1)
✅ 实战建议(企业级写法)
🔒 封装可变性
private val _uiState = MutableStateFlow(UiState())
val uiState: StateFlow<UiState> = _uiState
🚀 触发事件
viewModelScope.launch {_events.emit(UiEvent.ShowToast("保存成功"))
}
💡 在 UI 中 collect
lifecycleScope.launchWhenStarted {viewModel.uiState.collect { state ->// render UI}
}
✅ 小结对比
操作符 | 用途 | 建议 |
---|---|---|
map | 转换数据类型 | 构造只读 ViewModel 状态 |
combine | 多源合并 | 复杂表单、多个依赖状态 |
filter | 条件筛选 | 防止无效数据流动 |
distinctUntilChanged | 避免重复 UI 渲染 | 性能优化 |
debounce | 防止快速频繁事件 | 搜索输入场景 |
flatMapLatest | 请求取消与替换 | API 请求、搜索 |
stateIn/shareIn | Flow 转热流 | ViewModel 转发数据给 UI |
二 关于distinctUntilChanged和debounce方法
在 300ms 内发射最后一个值
- 关于
distinctUntilChanged()
:
- "两次"指的是连续两次发射的值,没有时间间隔的概念
- 只要前一次发射的值和后一次发射的值相同(通过
equals()
比较),就不会再次发射 - 示例:如果
userName
依次发射 “A”, “A”, “B”, “B”, “B”, “A”- 实际发射:“A”, “B”, “A” (连续重复的被过滤)
- 适合 UI 避免重复绘制:比如用户名没变化时就不需要重新绘制界面
- 关于
debounce(300)
和distinctUntilChanged
组合:
debounce(300)
:防抖 300 毫秒- 只有在 300ms 内没有新值时,才会发射最后一个值
- 示例:快速输入 “abc”(假设每个字母间隔 100ms)
- 只会在停止输入 300ms 后发射最后的 “abc”
filter { it.isNotBlank() }
:过滤掉空字符串distinctUntilChanged()
:确保最终发射的值与前一次不同- 示例:输入 “test” → 删除 → 再输入 “test”
- 如果两次 “test” 之间没有其他值,第二次 “test” 不会被发射
- 示例:输入 “test” → 删除 → 再输入 “test”
总结区别:
debounce
:处理高频事件,只关心稳定后的值distinctUntilChanged
:过滤连续重复的值- 组合使用时:先防抖,再过滤连续重复,非常适合搜索框等场景
这种组合能有效优化性能,避免不必要的网络请求或 UI 更新。
三 distinctUntilChanged()与时间间隔没有关系
-
关于时间间隔的影响:
- 即使两次发射间隔半小时(或任意长时间),只要中间没有发射过其他不同的值,第二次发射的
A
不会触发界面刷新。 distinctUntilChanged()
只比较相邻两次发射的值,与时间间隔完全无关。- 示例流程:
// 时间轴 | 发射值 | 是否触发下游/界面刷新 t0 | A | 是 (首次发射) t30min | A | 否 (与前一次相同) t35min | B | 是 (与前一次不同) t60min | B | 否 (与前一次相同)
- 即使两次发射间隔半小时(或任意长时间),只要中间没有发射过其他不同的值,第二次发射的
-
关于比较规则:
- ✅ 只与内容有关:默认通过
equals()
方法比较值是否相同 - ❌ 与以下因素无关:
- 发射时间间隔
- 发射次数
- 流的生命周期
- 特殊用法:可以自定义比较器
.distinctUntilChanged { old, new ->// 例如:忽略大小写比较字符串old.equals(new, ignoreCase = true) }
- ✅ 只与内容有关:默认通过
典型应用场景:
// 用户输入搜索词时避免重复请求
searchTermFlow.debounce(300).distinctUntilChanged() // 连续输入相同词时只发一次.collect { term ->fetchResults(term) // 网络请求}
总结:distinctUntilChanged()
是一个内容感知而非时间感知的操作符,它的唯一职责就是过滤掉连续的重复值。
四 企业中使用stateflow和sharedFlow示例
import android.os.Bundle
import android.view.View
import android.widget.Toast
import androidx.activity.R
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.lifecycle.ViewModel
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch// 表示 UI 的状态数据类,包括加载中、数据内容和错误信息
data class UiState(val loading: Boolean = false,val data: String = "",val error: String? = null
)// UI 事件的封装类,使用密封类进行分类表示
sealed class UiEvent {data class ShowToast(val message: String) : UiEvent() // 显示 Toast 消息事件object NavigateToNext : UiEvent() // 导航事件
}class MainViewModel : ViewModel() {// 可变的状态流,用于内部更新 UI 状态private val _uiState = MutableStateFlow(UiState())// 暴露只读的 StateFlow 给 UI 层,避免外部修改状态val uiState: StateFlow<UiState> = _uiState.asStateFlow()// 用于发送一次性事件的 SharedFlow,配置了缓冲策略private val _uiEvent = MutableSharedFlow<UiEvent>(replay = 0,extraBufferCapacity = 1,onBufferOverflow = BufferOverflow.DROP_OLDEST)val uiEvent: SharedFlow<UiEvent> = _uiEvent.asSharedFlow()fun loadData() {viewModelScope.launch {Log.d("MainViewModel", "Start loading data")_uiState.update { it.copy(loading = true) } // 更新状态为加载中try {delay(1000) // 模拟网络延迟val response = fetchRemoteData() // 获取模拟数据_uiState.update { it.copy(loading = false, data = response) } // 更新数据加载完成_uiEvent.emit(UiEvent.ShowToast("加载成功")) // 发送 Toast 事件} catch (e: Exception) {Log.e("MainViewModel", "Error loading data", e)_uiState.update { it.copy(loading = false, error = e.message) } // 出现错误时更新错误信息}}}private suspend fun fetchRemoteData(): String {// 模拟网络请求返回的数据return "Hello Flow!"}fun onNavigateClicked() {viewModelScope.launch {Log.d("MainViewModel", "Navigate button clicked")_uiEvent.emit(UiEvent.NavigateToNext) // 发送导航事件}}
}class MainFragment : Fragment() {private val viewModel: MainViewModel by viewModels() // 通过委托方式获取 ViewModel 实例override fun onViewCreated(view: View, savedInstanceState: Bundle?) {super.onViewCreated(view, savedInstanceState)// 启动生命周期感知的协程作用域viewLifecycleOwner.lifecycleScope.launch {viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {// 收集 UI 状态流并处理更新launch {viewModel.uiState.collect { state ->Log.d("MainFragment", "uiState collected: $state") // 打印当前 UI 状态// 此处可绑定 UI 状态到视图控件}}// 收集 UI 事件流并执行相应操作launch {viewModel.uiEvent.collect { event ->Log.d("MainFragment", "uiEvent collected: $event")when (event) {is UiEvent.ShowToast ->Toast.makeText(requireContext(), event.message, Toast.LENGTH_SHORT).show()is UiEvent.NavigateToNext -> {// 使用传统 Intent 方式跳转 Activityval intent = Intent(requireContext(), NextActivity::class.java)startActivity(intent)}}}}}}Log.d("MainFragment", "Calling viewModel.loadData()")viewModel.loadData() // 启动加载数据逻辑}
}
相关文章:
kotlin 03flow-stateFlow和sharedFlow企业中使用
一 stateFlow和sharedFlow企业中使用 在企业级 Kotlin 项目中,StateFlow 和 SharedFlow 是 状态管理 与 事件分发 的核心工具,尤其在 MVVM 架构中扮演着极为关键的角色。 ✅ 企业中如何使用 StateFlow 和 SharedFlow 场景工具示例UI 状态同步ÿ…...
【机器学习|学习笔记】决策树Decision Tree(DT)的起源、原理、发展、改进和应用(附代码)
【机器学习|学习笔记】决策树Decision Tree(DT)的起源、原理、发展、改进和应用(附代码) 【机器学习|学习笔记】决策树Decision Tree(DT)的起源、原理、发展、改进和应用(附代码) 文…...
Kotlin-空值和空类型
变量除了能引用一个具体的值之外,还有一种特殊的值,那就是 null, 它代表空值, 也就是不引用任何对象 在Kotlin中, 对空值的处理是非常严格的,正常情况下,我们的变量是不能直接赋值为 null 的,否则无法编译通过, 这直接在编译阶段就避免了空指针问题 Kotlin中所有的类型默认都是…...
Java 企业级开发设计模式全解析
Java 企业级开发设计模式全解析 在 Java 企业级开发的复杂领域中,设计模式如同精湛的工匠工具,能够帮助开发者构建高效、可维护、灵活且健壮的软件系统。它们是无数开发者在长期实践中总结出的解决常见问题的最佳方案,掌握这些模式对于提升开…...
高并发内存池
文章目录 前言一、项目介绍二、内存池介绍1.池化技术2.内存池3.malloc视角下内存的管理 三、定长内存池3.1 设计思路3.2 数据结构 四、高并发内存池整体框架设计4.1 thread cachethreadcache哈希桶映射对齐规则threadcache TLS无锁访问 4.2 central cachecentral cache结构设计…...
常用对称加密算法的Python实现及详解
文章目录 **常用对称加密算法的Python实现及详解****1. 对称加密概述****1.1 对称加密的基本原理****1.2 对称加密的分类****1.3 对称加密的应用** **2. DES(Data Encryption Standard)****2.1 算法原理****2.2 Python实现****2.3 安全性分析** **3. 3DE…...
ByteArrayInputStream 类详解
ByteArrayInputStream 类详解 ByteArrayInputStream 是 Java 中用于从字节数组读取数据的输入流,位于 java.io 包。它允许将内存中的字节数组当作输入流来读取,是处理内存数据的常用工具。 1. 核心特性 内存数据源:从字节数组(b…...
MySQL C API高效编程:C语言实现数据库操作的深入解析
知识点【MySQL C API】 1、头文件及MYSQL * 句柄 //头文件 #include <mysql/mysql.h>1、MYSQL MYSQL是一个结构体,封装了与数据库连接相关的所有状态,配置和数据。 2、MYSQL *的本质 类似于 FILE*,代表一个与数据库连接的通道&…...
字符串,数组,指针之间的关系
在C语言中,字符串、指针和数组之间有着紧密且复杂的关系,它们在内存存储、操作方式等方面相互关联,以下为你详细介绍: 字符串 定义:字符串是由字符组成的序列,以空字符(\0)作为结束…...
2025流感疫苗指南+卫健委诊疗方案|高危人群防护+并发症处理 慢性肾脏病饮食指南2025卫健委版|低盐低磷食谱+中医调理+PDF 网盘下载 pdf下载
2025 年卫健委发布的《成人肥胖食养指南(2024 年版)》为减肥提供了科学的饮食指导。 📢提示:文章排版原因,资源链接地址放在文章结尾👇👇,往下翻就行 📢提示࿱…...
学习路线(机器人软件架构)
机器人软件系统架构从入门到专家学习路线 一、基础阶段(6-12个月)基础知识储备机器人基础概念:编程技能必备语言:工具链: 入门框架推荐资源: 中级阶段(1-2年)系统架构基础ROS进阶架构…...
Stellaris 群星 [DLC 解锁] CT 表 [Steam] [Windows SteamOS macOS]
Stellaris 群星 [DLC 解锁] & CT 表 [Steam] [Windows & SteamOS & macOS] DLC 版本 至最新全部 DLC 后续可能无法及时更新文章,具体最新版本见下载文件说明; DLC 解锁列表(仅供参考) 《群星》 - Symbols of Domina…...
题目 3321: 蓝桥杯2025年第十六届省赛真题-画展布置
题目 3321: 蓝桥杯2025年第十六届省赛真题-画展布置 时间限制: 2s 内存限制: 192MB 提交: 673 解决: 130 题目描述 画展策展人小蓝和助理小桥为即将举办的画展准备了 N 幅画作,其艺术价 值分别为 A1, A2, . . . , AN。他们需要从这 N 幅画中挑选 M 幅,并…...
Excel 查询之 iNDEX与MATCH组合
在Excel日常工作中,数据查询是最常见的操作之一。虽然VLOOKUP函数广为人知,但它有一个明显的局限性——要求查询值必须位于返回值的左侧。今天我要介绍一个更灵活、更强大的组合:INDEX和MATCH函数。 为什么选择INDEXMATCH? VLOO…...
【Leetcode 每日一题 - 补卡】1128. 等价多米诺骨牌对的数量
问题背景 给你一组多米诺骨牌 d o m i n o e s dominoes dominoes。 形式上, d o m i n o e s [ i ] [ a , b ] dominoes[i] [a, b] dominoes[i][a,b] 与 d o m i n o e s [ j ] [ c , d ] dominoes[j] [c, d] dominoes[j][c,d] 等价 当且仅当 ( a c a c …...
【Elasticsearch入门到落地】12、索引库删除判断以及文档增删改查
接上篇《11、RestClient初始化索引库》 上一篇我们完成了使用RestHighLevelClient创建索引库的代码实现,本篇将讲解如何判断索引库是否存在并删除它,以及如何对索引库中的文档进行增删改查操作。 一、索引库判断与删除 在操作索引库时,有时…...
36、C#中的⽅法声明参数关键字params,ref,out的意义及⽤法
在C#中,params、ref 和 out 是方法声明中用于修饰参数的关键字,它们各自有不同的用途和语义。以下是它们的详细说明和用法: 1、 params 关键字 意义 params 允许方法接受可变数量的参数,这些参数会被编译为一个数组。适用于参数…...
DEX平台引领风尚 XBIT让数字资产回归简单与透明
近日,全球加密货币市场持续升温,Dex 交易平台成为众多投资者关注焦点,其中XBIT去中心化交易所平台凭借独特优势脱颖而出。 图片来源:币界网 在当今加密货币领域,交易平台的安全性与便捷性至关重要。XBIT去中心化交易所…...
基于Python+MongoDB猫眼电影 Top100 数据爬取与存储
前言:从猫眼电影排行榜页面(TOP100榜 - 猫眼电影 - 一网打尽好电影 )爬取 Top100 电影的电影名称、图片地址、主演、上映时间和评分等关键信息,并将这些信息存储到本地 MongoDB 数据库中,🔗 相关链接Xpath&…...
Linux文件复制命令精要指南:cp与scp详解
大家好,欢迎来到程序视点!我是你们的老朋友.小二! Linux文件复制命令精要指南:cp与scp详解 一、cp命令(本地文件复制) 核心功能 复制文件/目录到目标路径,支持重命名及批量操作。 关键参数 …...
Qt实现网页内嵌
文章目录 一、环境准备 二、代码实现 三、测试 一、环境准备 首先,确保你的Qt安装包含了QtWebEngine模块。我的Qt是5.12.9并且使用MSVC来编译项目。在项目文件中需要添加以下配置,其中在Qt中配置MSVC,建议去看看这位大佬的博客:…...
Kotlin中 StateFlow 或 SharedFlow 或 LiveData的区别
在Android开发中,处理数据流是常见的需求,特别是在UI更新和数据共享方面。Kotlin提供了几种不同的工具来帮助开发者实现这一需求,包括StateFlow、SharedFlow和LiveData。每种工具都有其特点和使用场景,下面我们将逐一比较它们的区…...
jupyter notebook运行简单程序
一. 使用 cmd 创建虚拟环境 1.创建虚拟环境 (1)创建新的虚拟环境(本项目名设置为zhineng),并设置python版本 conda create -n zhineng python3.6 (2)查看python版本 python --version &am…...
查看Ubuntu版本
1. 使用 lsb_release 命令(推荐) lsb_release -a输出示例: ubuntuVM-0-6-ubuntu:~$ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 22.04 LTS Release: 22.04 Codename: jamm…...
《算法导论(第4版)》阅读笔记:p7-p8
《算法导论(第4版)》学习第 5 天,p7-p8 总结,总计 2 页。 一、技术总结 1.算法解决什么问题? DNA测序问题(Dynamic Programming, 动态规划),寻找路径问题,加密问题,利益最大化问题(linear programming, …...
AI笔记-1
Halide Perovskites (HPs) 卤化物钙钛矿 卤化物钙钛矿(HPs)已被 公认为 光伏和发光器件 中最有前途的材料之一 在本观点中,我们将探讨钙钛矿的定义,主要聚焦于由 较重卤素(Cl、Br和I)组成的钙钛矿亚群&…...
【C++重载操作符与转换】成员访问操作符
目录 一、点操作符(.) 1.1 基本概念 1.2 点操作符不能被重载 二、箭头操作符(->) 2.1 基本概念 2.2 箭头操作符的重载 2.3 箭头操作符重载的特殊规则 三、成员指针操作符(.*)和指向成员指针的箭…...
java单元测试代码
import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; import java.util.List;public class UserServiceTest {Testpublic void testSearchUserByTags() {// 模拟标签列表List<String> tagNameList List.of("tag1", "…...
Vue中的过滤器参数:灵活处理文本格式化
🤍 前端开发工程师、技术日更博主、已过CET6 🍨 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 🕠 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》、《前端求职突破计划》 🍚 蓝桥云课签约作者、…...
【神经网络与深度学习】深度学习中的生成模型简介
深度学习中的生成模型 openai 的一个古早介绍 引言 深度学习中的生成模型能够学习数据分布并生成新数据,在人工智能的多个领域中都有重要应用。不同类型的生成模型在原理和结构上各有特点,适用于不同的任务,如图像生成、文本生成和时间序列…...
Docker(三):DockerFile
一、DockerFile介绍 1、DockerFile 介绍 DockerFile 是一种能够被Docker 程序解释的文件(一般为了方便理解称之为“剧本”)。 DockerFile 由一条一条的指令组成,并且有自己的书写格式和支持的命令。当我们需要在容器 镜像中指定自己额外的需…...
使用OpenCV 和 Dlib 实现疲劳检测
文章目录 引言1.相关技术介绍2. 系统原理2.1 眼睛纵横比(EAR)算法2.2 系统工作流程 3.代码解析3.1 关键函数说明3.2 主循环逻辑 4.实际应用效果5.参数调优建议6.总结 引言 疲劳驾驶是交通事故的主要原因之一。本文将介绍如何使用Python和计算机视觉技术构建一个实时疲劳驾驶检…...
Python格式化字符串的四种方法
Python格式化字符串的四种方法 1.使用 % 运算符 %s 是一个字符串的占位符,而 “World” 是替换它的值 print("Hello, %s!" % "World") # 输出:Hello, World!你可以使用多个占位符 注意:多个变量占位,变量要…...
蓝桥杯 18. 积木
积木 原题目链接 题目描述 小明用积木搭了一个城堡。为了方便,小明使用的是大小相同的正方体积木,并将其搭建在一个 n 行 m 列的方格图上。每个积木占据方格图中的一个小格子。 小明的城堡是立体的,可以将积木垒在其他积木上。当某个格子…...
解决因字段过长使MYSQL数据解析超时导致线上CPU告警问题
1.首先发生CPU告警 占有率到98.8% 2.DBA找到最终的原因是这条SQL导致 select * from trade_order_sku_071 where order_id in ( P760205793431071471 ) and user_id in ( 67d9158c000000000e0134ff );” 3.观察系统指标,发现CPU和网络同时飙升,同时网络…...
Python中的客户端和服务端交互的基本内容
目录 网络协议 网络的通信方式 需要安装的组件和需要导入的包模块 安装的组件 导入包模块 如何创建客户端 如何创建服务端 网络协议 IPV4:是互联网协议的第四版,也是目前广泛使用的网络协议。它使用32位地址格式,理论上可以提供约43亿…...
Compose 中使用 WebView
在 Jetpack Compose 中,我们可以使用 AndroidView 组件来集成传统的 Android WebView。以下是几种实现方式: 基础 WebView 实现 Composable fun WebViewScreen(url: String) {AndroidView(factory { context ->WebView(context).apply {// 设置布局…...
PyCharm 安装教程
## 简介 PyCharm 是由 JetBrains 公司开发的一款优秀的 Python 集成开发环境(IDE),提供了代码分析、图形化调试器、集成测试器和版本控制系统等功能。PyCharm 有两个版本: - **专业版(Professional)**&am…...
基于MATLAB的图像色彩识别项目,彩色图像矩阵识别
一、项目背景 在本次IP Lab项目中,我们模拟了游戏“Lego’s Life of George”的玩法。游戏要求玩家在屏幕短暂展示图像后,凭借记忆重建乐高结构。我们面临的任务是处理一系列存在各种缺陷的图像,像噪声干扰、旋转以及投影问题等,…...
springboot应用大批量导出excel产生oom处理措施实践(适用于poieasyexcel)
一、背景: 在某些信息管理场景中,存在大批量导出需求,例如一次性导出10~100w行excel数据,如果不做特殊的处理,很容易导致Out Of Memory,特别是堆内存溢出。 oom复现 例如修改IDEA运行配置,VM…...
OpenCV 第6课 图像处理之几何变换(透视)
1、透视变换 2、数学公式 3、透视变换矩阵的生成 4、图像变换函数 5、例程 1、透视变换 OpenCV中的透视变换是一种几何变换,用于将图像从一个平面映射到另一个平面。它通过4个对应点之间的映射关系来变换图像,使得变换后的图像看起来像从不同角度观看。透视变换常用于图像…...
SpringMVC 框架核心知识点详解与实战
文章目录 引言一、响应数据和结果视图1.1 开发环境搭建1.2 返回值类型1.3 转发与重定向1.4 响应 json 数据1.5 静态资源处理 二、SpringMVC 实现文件上传2.1 准备工作2.2 传统方式文件上传 三、SpringMVC 的异常处理3.1 异常处理思路3.2 实现异常处理 四、SpringMVC 框架中的拦…...
Web前端开发:Grid 布局(网格布局)
一、Grid 是什么? Grid(网格布局) 是 CSS 中一种二维布局系统,可以同时控制行和列的排列方式。相比传统的浮动布局和 Flexbox(一维布局),Grid 更适合构建复杂的网页结构(比如仪表盘、…...
时间同步服务
时间同步:多主机协作工作时,各个主机的时间同步很重要,时间不一致会造成很多重要应用的故障,如:加密协议,日志,集群等,利用NTP(Network Time Protocol )协议使网络中的各个计算机 时间达到同步。目前NTP协议…...
全球化电商平台Azure云架构设计
业务需求: 支撑全球三大区域(北美/欧洲/亚洲)用户访问,延迟<100ms处理每秒50,000订单的峰值流量混合云架构整合本地ERP系统全年可用性99.99%满足GDPR和PCI DSS合规要求 建议在实施时使用Azure Landing Zone框架进行部署&…...
【SaaS多租架构】数据隔离与性能平衡
SaaS多租户架构:数据隔离与性能平衡 一、技术背景及发展二、技术特点:数据隔离与性能优化的双核心三、技术细节:实现路径与关键技术四、实际案例分析五、未来发展趋势结语一、技术背景及发展 多租户架构是云计算与SaaS(软件即服务)模式的核心技术,其核心目标是通过共享基…...
ARM介绍及其体系结构
目录 一、ARM介绍 (一)公司层面 (二)技术层面 (三)微处理器芯片或产品方面 二、ARM体系结构 (一)指令集 (二)寄存器组织 (三)存…...
3DGS-slam:splatam公式
配套讲解视频:https://www.bilibili.com/video/BV1ZgfBYdEpg/?spm_id_from333.1387.homepage.video_card.click&vd_sourced4c3e747c32049ddd90dcce17208f4e0 1、多维高斯分布公式: 对于多维(多变量)高斯分布,概率密度函数的…...
阿里云服务器深度科普:技术架构与未来图景
阿里云服务器深度科普:技术架构与未来图景 一、起源与演进:从虚拟化到云原生 阿里云服务器(Elastic Compute Service, ECS)诞生于阿里巴巴集团对云计算技术的早期探索。2009年,阿里云团队启动自主研发,…...
物联网之对接MQTT最佳实践
小伙伴们,你们好呀,我是老寇,跟我一起学习对接MQTT 安装EMQX 采用docker-compose一键式,启动!!! 还没有安装docker朋友,参考文章下面两篇文章 # Ubuntu20.04安装Docker # Cento…...