【Python语言基础】24、并发编程
文章目录
- 1. 多线程(threading模块)
- 1.1 多线程的实现(threading 模块)
- 1.2 多线程的优缺点
- 1.3 线程同步与锁
- 2. 多进程(multiprocessing模块)
- 2.1 多进程实现(multiprocessing模块)
- 2.2 多进程的优缺点
- 2.3 进程间通信(IPC)
- 3.异步编程(asyncio模块)
- 3.1 异步编程的实现(asyncio 模块)
- 3.2 异步编程的优缺点
- 3.3 异步编程中的重要概念
- 3.4 异步编程的应用场景
Python 的并发编程是指在同一时间段内处理多个任务的编程方式。
并发编程能显著提升程序的性能和响应能力,尤其适用于 I/O 密集型和 CPU 密集型任务。
下面将详细介绍 Python 并发编程的几种常见方式。
1. 多线程(threading模块)
想象你在一家餐厅当服务员,你要同时为好几桌客人服务。
如果按单线程的方式,你得先为第一桌客人点完菜、上完菜、结完账,再去服务第二桌客人,这样效率会很低。
而多线程就像是你同时能照顾好几桌客人,在第一桌客人下单后等待厨房做菜的时间里,你可以去第二桌客人那里点单,等第一桌菜做好了再去上菜,这样就能在相同时间内服务更多客人,提高了整体的工作效率。
在编程里,一个线程就是程序执行的一条路径。
单线程程序就像一个只能一次做一件事的人,而多线程程序就像是有多个分身,能同时处理多个任务。
在 Python 中,多线程可以让程序在同一时间执行多个不同的代码块。
多线程是指在一个进程内创建多个线程,每个线程可以独立执行不同的任务。在 Python 里,threading模块可用于实现多线程编程。
原理:
多线程适合 I/O 密集型任务,比如网络请求、文件读写等。
在执行 I/O 操作时,线程会进入阻塞状态,此时 CPU 可切换到其他线程继续执行,从而提高程序的整体效率。
1.1 多线程的实现(threading 模块)
Python 提供了 threading 模块来实现多线程编程。下面我们通过一个简单的例子来看看如何使用多线程。
import threading
import time# 定义一个函数,模拟一个任务
def print_numbers():for i in range(5):print(f"Number {i}")time.sleep(1) # 暂停 1 秒,模拟耗时操作# 定义另一个函数,模拟另一个任务
def print_letters():for letter in 'abcde':print(f"Letter {letter}")time.sleep(1)# 创建线程对象
thread1 = threading.Thread(target=print_numbers)
thread2 = threading.Thread(target=print_letters)# 启动线程
thread1.start()
thread2.start()# 等待线程执行完毕
thread1.join()
thread2.join()print("Both threads have finished.")
代码解释
- 导入模块:import threading 和 import time,threading 模块用于创建和管理线程,time 模块用于模拟耗时操作。
- 定义任务函数:
- print_numbers 函数会打印 0 到 4 的数字,每次打印后暂停 1 秒。
- print_letters 函数会打印字母 ‘a’ 到 ‘e’,每次打印后也暂停 1 秒。
- 创建线程对象:使用 threading.Thread 类创建线程对象,target 参数指定线程要执行的函数。
- 启动线程:调用线程对象的 start 方法来启动线程。一旦调用 start 方法,线程就会开始执行指定的函数。
- 等待线程执行完毕:调用线程对象的 join 方法,它会阻塞当前线程,直到被调用的线程执行完毕。这样可以确保在主线程继续执行之前,所有子线程都已经完成任务。
- 主线程继续执行:当所有子线程都执行完毕后,主线程会继续执行,打印出 “Both threads have finished.”。
1.2 多线程的优缺点
优点
- 提高效率:对于 I/O 密集型任务,比如网络请求、文件读写等,在等待 I/O 操作完成的时间里,CPU 可以去执行其他线程的任务,从而提高了程序的整体执行效率。
- 响应性更好:在 GUI 程序中,使用多线程可以避免界面在执行耗时任务时出现卡顿,保证用户界面的流畅性。
缺点
- 全局解释器锁(GIL):在 Python 中,由于 GIL 的存在,同一时刻只有一个线程可以执行 Python 字节码。这意味着对于 CPU 密集型任务,多线程并不能充分利用多核 CPU 的优势,反而可能因为线程切换的开销而导致性能下降。
- 线程安全问题:当多个线程同时访问和修改共享资源时,可能会出现数据不一致的问题,比如多个线程同时对一个变量进行加 1 操作,可能会导致最终结果不正确。为了解决线程安全问题,需要使用锁机制(如 threading.Lock)来保证同一时刻只有一个线程可以访问共享资源。
1.3 线程同步与锁
为了避免多个线程同时访问和修改共享资源时出现问题,我们可以使用锁机制。
下面是一个使用 threading.Lock 的例子:
import threading# 共享资源
counter = 0
# 创建锁对象
lock = threading.Lock()# 定义一个函数,用于对共享资源进行操作
def increment():global counterfor _ in range(100000):# 获取锁lock.acquire()try:counter += 1finally:# 释放锁lock.release()# 创建线程对象
thread1 = threading.Thread(target=increment)
thread2 = threading.Thread(target=increment)# 启动线程
thread1.start()
thread2.start()# 等待线程执行完毕
thread1.join()
thread2.join()print(f"Final counter value: {counter}")
在这个例子中,我们使用 threading.Lock 来保证同一时刻只有一个线程可以对 counter 变量进行加 1 操作。lock.acquire() 用于获取锁,lock.release() 用于释放锁。使用 try…finally 语句可以确保即使在出现异常的情况下,锁也能被正确释放。
2. 多进程(multiprocessing模块)
为了更好地理解多进程,我们可以把计算机比作一个大型工厂。
在这个工厂里,每个车间就是一个进程,每个车间都有自己独立的设备、原材料和工作区域,它们可以同时进行不同的生产任务,彼此之间互不干扰。
在编程领域,进程是程序在操作系统中的一次执行过程,是系统进行资源分配和调度的基本单位。
多进程编程就是让程序同时启动多个进程,每个进程都可以独立执行不同的任务,以此来提高程序的运行效率和处理能力。
多进程是指在操作系统中同时运行多个进程,每个进程有自己独立的内存空间和系统资源。
Python 的multiprocessing模块可用于实现多进程编程。
原理
多进程适合 CPU 密集型任务,例如大量的数值计算。由于 Python 的全局解释器锁(GIL),多线程在 CPU 密集型任务中无法充分利用多核 CPU 的优势,而多进程可以绕过 GIL 的限制,让每个进程在不同的 CPU 核心上并行执行。
2.1 多进程实现(multiprocessing模块)
下面通过一个简单的例子来展示如何使用多进程:
import multiprocessing
import time# 定义一个函数,模拟一个任务
def print_numbers():for i in range(5):print(f"Number {i}")time.sleep(1)# 定义另一个函数,模拟另一个任务
def print_letters():for letter in 'abcde':print(f"Letter {letter}")time.sleep(1)if __name__ == "__main__":# 创建进程对象process1 = multiprocessing.Process(target=print_numbers)process2 = multiprocessing.Process(target=print_letters)# 启动进程process1.start()process2.start()# 等待进程执行完毕process1.join()process2.join()print("Both processes have finished.")
代码解释
- 导入模块:import multiprocessing 和 import time,multiprocessing 模块用于创建和管理进程,time 模块用于模拟耗时操作。
- 定义任务函数:
- print_numbers 函数会打印 0 到 4 的数字,每次打印后暂停 1 秒。
- print_letters 函数会打印字母 ‘a’ 到 ‘e’,每次打印后也暂停 1 秒。
- 创建进程对象:使用 multiprocessing.Process 类创建进程对象,target 参数指定进程要执行的函数。
- 启动进程:调用进程对象的 start 方法来启动进程。一旦调用 start 方法,进程就会开始执行指定的函数。
- 等待进程执行完毕:调用进程对象的 join 方法,它会阻塞当前进程,直到被调用的进程执行完毕。这样可以确保在主进程继续执行之前,所有子进程都已经完成任务。
- 主进程继续执行:当所有子进程都执行完毕后,主进程会继续执行,打印出 “Both processes have finished.”。
2.2 多进程的优缺点
优点
- 充分利用多核 CPU:与 Python 多线程受全局解释器锁(GIL)的限制不同,多进程可以绕过 GIL 的限制,每个进程都可以在不同的 CPU 核心上并行执行,因此非常适合 CPU 密集型任务,例如大量的数值计算、图像处理等。
- 稳定性高:由于每个进程都有自己独立的内存空间和系统资源,一个进程的崩溃不会影响其他进程的运行,提高了程序的稳定性。
缺点
- 资源开销大:创建和销毁进程需要消耗较多的系统资源,包括内存和 CPU 时间。因此,在需要频繁创建和销毁进程的场景下,性能可能会受到影响。
- 进程间通信复杂:由于每个进程都有自己独立的内存空间,进程之间不能直接共享数据,需要使用特定的方式进行通信,例如管道(Pipe)、队列(Queue)等,这增加了编程的复杂度。
2.3 进程间通信(IPC)
下面是一个使用 multiprocessing.Queue 进行进程间通信的例子:
import multiprocessing# 定义一个函数,用于向队列中添加数据
def producer(queue):for i in range(5):print(f"Producing {i}")queue.put(i)time.sleep(1)# 定义一个函数,用于从队列中取出数据
def consumer(queue):while True:item = queue.get()if item is None:breakprint(f"Consuming {item}")if __name__ == "__main__":# 创建队列对象queue = multiprocessing.Queue()# 创建进程对象producer_process = multiprocessing.Process(target=producer, args=(queue,))consumer_process = multiprocessing.Process(target=consumer, args=(queue,))# 启动进程producer_process.start()consumer_process.start()# 等待生产者进程执行完毕producer_process.join()# 向队列中放入 None,表示数据生产结束queue.put(None)# 等待消费者进程执行完毕consumer_process.join()print("All processes have finished.")
在这个例子中,producer 函数负责向队列中添加数据,consumer 函数负责从队列中取出数据。通过 multiprocessing.Queue 实现了进程间的数据传递。
3.异步编程(asyncio模块)
为了更好地理解异步编程,我们可以把它类比成日常生活中的场景。
假设你在餐厅用餐,当你点完菜后,服务员不会一直站在你桌前等菜做好,而是会去服务其他客人,等菜做好了再把菜端给你。这种在等待某个任务完成的同时可以去做其他事情的方式,就是异步的思想。
在编程中,异步编程是一种非阻塞的编程方式。
传统的同步编程中,程序会按照代码的顺序依次执行,当遇到一个耗时的操作(如网络请求、文件读写)时,程序会暂停执行,直到该操作完成。
而异步编程允许程序在等待这些耗时操作完成的同时,继续执行其他任务,从而提高程序的并发性能和响应能力。
3.1 异步编程的实现(asyncio 模块)
Python 提供了 asyncio 模块来支持异步编程,并且引入了 async 和 await 关键字来定义异步函数和协程。
下面是一个简单的例子:
import asyncio# 定义一个异步函数(协程)
async def task(name, delay):print(f"Task {name} started")await asyncio.sleep(delay) # 模拟耗时操作print(f"Task {name} finished")# 定义主函数,也是一个协程
async def main():# 创建多个协程对象tasks = [task("A", 2),task("B", 1)]# 并发运行多个协程await asyncio.gather(*tasks)# 运行异步程序
asyncio.run(main())
代码解释
- 导入模块:import asyncio,asyncio 模块是 Python 实现异步编程的核心模块。
- 定义异步函数(协程):使用 async 关键字定义异步函数,异步函数也被称为协程。在上面的例子中,task 函数就是一个协程,它模拟了一个耗时的操作,通过 await asyncio.sleep(delay) 暂停执行一段时间。
- 定义主函数(协程):main 函数也是一个协程,它创建了多个协程对象,并使用 asyncio.gather 函数并发运行这些协程。asyncio.gather 会等待所有协程执行完毕后才会继续执行后续代码。
- 运行异步程序:使用 asyncio.run 函数来运行异步程序,它会自动创建事件循环并运行指定的协程。
3.2 异步编程的优缺点
优点
- 高并发性能:异步编程非常适合 I/O 密集型任务,特别是高并发的网络请求场景。在等待 I/O 操作完成的时间里,程序可以继续执行其他任务,从而显著提高程序的并发性能。
- 资源开销小:与多线程和多进程相比,异步编程不需要创建额外的线程或进程,因此资源开销更小,更适合处理大量的并发连接。
缺点
- 编程模型复杂:异步编程的编程模型相对复杂,需要理解异步函数、协程、事件循环等概念。编写和调试异步代码时,可能会遇到一些难以排查的问题。
- 兼容性问题:一些旧的库和代码可能不支持异步编程,需要进行额外的适配工作。
3.3 异步编程中的重要概念
-
协程(Coroutine)
协程是异步编程的核心概念之一,它是一种可以暂停和恢复执行的函数。
在 Python 中,使用 async 关键字定义的函数就是协程函数,调用协程函数会返回一个协程对象。
协程可以在执行过程中通过 await 关键字暂停执行,等待某个异步操作完成后再继续执行。 -
事件循环(Event Loop)
事件循环是异步编程的调度器,它负责管理和调度所有的协程。
事件循环会不断地检查哪些协程已经准备好执行,然后依次执行这些协程。在 Python 中,asyncio 模块会自动创建和管理事件循环。 -
await 关键字
await 关键字用于暂停协程的执行,等待一个可等待对象(如另一个协程、asyncio.Future 等)的结果。
当遇到 await 时,协程会暂停执行,事件循环会去执行其他协程,直到等待的对象完成后,协程才会继续执行。
3.4 异步编程的应用场景
-
网络爬虫:在爬取大量网页时,网络请求是一个典型的 I/O 密集型任务。使用异步编程可以在等待一个网页响应的同时,发起其他网页的请求,从而大大提高爬取效率。
-
Web 服务器:对于高并发的 Web 服务器,异步编程可以处理大量的客户端请求,避免线程或进程的创建和销毁带来的开销,提高服务器的性能和响应能力。
异步编程是一种强大的编程技术,尤其适用于 I/O 密集型的高并发场景,但在使用时需要掌握其复杂的编程模型
相关文章:
【Python语言基础】24、并发编程
文章目录 1. 多线程(threading模块)1.1 多线程的实现(threading 模块)1.2 多线程的优缺点1.3 线程同步与锁 2. 多进程(multiprocessing模块)2.1 多进程实现(multiprocessing模块)2.2 多进程的优缺点2.3 进程…...
MySQL-自定义函数
自定义函数 函数的作用 mysql数据库中已经提供了内置的函数,比如:sum,avg,concat等等,方便我们日常的使用,当需要时mysql支持定义自定义的函数,方便与我们对于需用复用的功能进行封装。 基本…...
实时操作系统在服务型机器人中的关键作用
一、服务型机器人的发展现状与需求 近年来,服务型机器人市场呈现出蓬勃发展的态势。据国际机器人联合会(IFR)2024 年度报告显示,全球人形机器人市场规模预计在 2025 年达到 38.7 亿美元,年复合增长率达 19.2%。服务型机…...
智能电网第5期 | 老旧电力设备智能化改造:协议转换与边缘计算
随着电力行业数字化转型加速,大量在役老旧设备面临智能化升级需求。在配电自动化改造过程中,企业面临三大核心挑战: 协议兼容难题:传统设备采用Modbus等老旧协议,无法接入智能电网系统 数据处理瓶颈:设备本…...
【UML建模】starUML工具
一.概述 StarUML是一款UML工具,允许用户创建和管理UML(统一建模语言)模型,广泛应用于软件工程领域。它的主要功能包括创建各种UML图:如用例图、类图、序列图等,支持代码生成与反向工程,以及提供…...
【技术笔记】Cadence实现Orcad与Allegro软件交互式布局设置
【技术笔记】Cadence实现Orcad与Allegro软件交互式布局设置 更多内容见专栏:【硬件设计遇到了不少问题】、【Cadence从原理图到PCB设计】 在做硬件pcb设计的时候,原理图选中一个元器件,希望可以再PCB中可以直接选中。 为了达到原理图和PCB两两…...
第十七届山东省职业院校技能大赛 中职组网络建设与运维赛项
第十七届山东省职业院校技能大赛 中职组网络建设与运维赛项 赛题 B 卷 第十七届山东省职业院校技能大赛中职组网络建设与运维赛项 1 赛题说明 一、竞赛项目简介 “网络建设与运维”竞赛共分为以下三个模块: 网络理论测试; 网络建设与调试…...
深入详解人工智能数学基础——概率论中的KL散度在变分自编码器中的应用
🧑 博主简介:CSDN博客专家、CSDN平台优质创作者,高级开发工程师,数学专业,10年以上C/C++, C#, Java等多种编程语言开发经验,拥有高级工程师证书;擅长C/C++、C#等开发语言,熟悉Java常用开发技术,能熟练应用常用数据库SQL server,Oracle,mysql,postgresql等进行开发应用…...
Docker配置DNS方法详解及快速下载image方法
根据错误信息,Docker 在拉取镜像时遇到网络连接超时(Client.Timeout exceeded),通常与 代理配置错误、DNS 解析失败、镜像源访问受限 或 网络防火墙限制 有关。以下是详细解决方案: 1. 检查并修复代理配置 如果你使用了 HTTP 代理: 确认代理地址是否有效(替换 speed.ip…...
Rundeck 介绍及安装:自动化调度与执行工具
Rundeck介绍 概述:Rundeck 是什么? Rundeck 是一款开源的自动化调度和任务执行工具,专为运维场景设计,帮助工程师通过统一的平台管理和执行跨系统、跨节点的任务。它由 PagerDuty 维护(2016 年收购)&#…...
济南国网数字化培训班学习笔记-第二组-6-输电线路现场教学
输电线路现场教学 杆塔组装 角钢塔 角钢-连扳-螺栓 螺栓(M): 脚钉-螺栓(螺栓头-无扣长-螺纹-螺帽)-垫片-螺帽/防盗帽/防松帽M20*45 表示直径20mm,长度45mm螺栓级别由一个类似浮点数表示,如…...
数据结构——二叉树,堆
目录 1.树 1.1树的概念 1.2树的结构 2.二叉树 2.1二叉树的概念 2.2特殊的二叉树 2.3二叉树的性质 2.4二叉树的存储结构 2.4.1顺序结构 2.4.2链式结构 3.堆 3.1堆的概念 3.2堆的分类 3.3堆的实现 3.3.1初始化 3.3.2堆的构建 3.3.3堆的销毁 3.3.4堆的插入 3.3.5…...
PostgreSQL 分区表——范围分区SQL实践
PostgreSQL 分区表——范围分区SQL实践 1、环境准备1-1、新增原始表1-2、执行脚本新增2400w行1-3、创建pg分区表-分区键为创建时间1-4、创建24年所有分区1-5、设置默认分区(兜底用)1-6、迁移数据1-7、创建分区表索引 2、SQL增删改查测试2-1、查询速度对比…...
第八节:进阶特性高频题-Pinia与Vuex对比
优势:无嵌套模块、Composition API友好、TypeScript原生支持 核心概念:state、getters、actions(移除mutation) 深度对比 Pinia 与 Vuex:新一代状态管理方案的核心差异 一、核心架构设计对比 维度VuexPinia设计目标集…...
路由交换网络专题 | 第七章 | BGP练习 | 次优路径 | Route-Policy | BGP认证
基本部分配置讲解: 配置BGP相关部分: // BGP区域配置: 用作环回口创建BGP对等体// “ipv4-family unicast”是指进入BGP的IPv4单播地址族视图。 // 配置完后仅仅只在IPV4地址簇下建立对等体。* [AR3]bgp 100 [AR3-bgp]peer 1.1.1.1 as-number 100 [AR…...
序论文42 | patch+MLP用于长序列预测
论文标题:Unlocking the Power of Patch: Patch-Based MLP for Long-Term Time Series Forecasting 论文链接:https://arxiv.org/abs/2405.13575v3 代码链接:https://github.com/TangPeiwang/PatchMLP (后台回复“交流”加入讨…...
【mongodb】系统保留的数据库名
目录 1. admin2. config3. local4. test(非严格保留,但常作为默认测试数据库)5. 注意事项6. 其他相关说明 1. admin 1.用途:用于存储数据库的权限和用户管理相关数据。2.特点:该数据库是 MongoDB 的超级用户数据库&am…...
js 的call 和apply方法用处
主要用于ECMAScript与宿主环境(文档对象(DOM)、浏览器对象(BOM))的交互中; 例子:function changeStyle(attr, value){ this.style[attr] value; } …...
济南国网数字化培训班学习笔记-第二组-2节-输电线路施工及质量
输电线路施工及质量 质量管控基本规定 基本规定 项目分类 土石方(测量挖坑)、基础、杆塔、架线、接地、线路防护 检验项目分类原则: 1.主控项目:影响工程性能、强度、安全性和可靠性,且不易修复和处理 2.一般项…...
“Daz to Unreal”将 G8 角色(包括表情)从 daz3d 导入到 UE5。在 UE5 中,我发现使用某个表情并与闭眼混合后,上眼睑出现了问题
1) Bake & Export Corrective Morphs from Daz before you go into UE5 1) 在进入 UE5 之前,从 Daz 烘焙并导出修正型变形 In Daz Studio 在 Daz Studio 中 Load your G8 head, dial in the exact mix (e.g. Smile 1.0 Eyes Closed 1.0). 加载你的 G8 头部&am…...
Linux系统之----进程优先级、调度与切换
在开启本篇文章的学习之前,我们先要熟悉如下两个事 1.概念 进程优先级指的是进程能得到某种资源的先后顺序,要理解好它与权限的关系,优先级是 能,拥有资源的先后顺序,权限是 能还是不能的问题 2.为什么要有优先级…...
Web3钱包开发功能部署设计
Web3钱包开发功能部署设计全景指南(2025技术架构与实战) ——从核心模块到多链生态的完整解决方案 一、核心功能模块设计 1.1 资产管理体系 Web3钱包的核心功能围绕资产存储、交易验证、多链兼容展开: • 密钥管理:…...
【含文档+PPT+源码】基于SpringBoot的开放实验管理平台设计与实现
项目介绍 本课程演示的是一款基于SpringBoot的开放实验管理平台设计与实现,主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的 Java 学习者。 1.包含:项目源码、项目文档、数据库脚本、软件工具等所有资料 2.带你从零开始部署运行本套系统…...
小刚说C语言刷题——1317正多边形每个内角的度数?
1.题目描述 根据多边形内角和定理,正多边形内角和等于:( n-2 ) 180∘ ( n 大于等于 3且 n 为整数) 请根据正多边形的边数,计算该正多边形每个内角的度数。(结果保留1位小数&#x…...
Spring—AOP
AOP是在不惊动原有的代码的基础上对功能进行增强操作 连接点:JoinPoint,可以被AOP控制的方法 通知:Advice,增强的逻辑,共性功能 切入点:PointCut,匹配连接点的条件,表明连接点中哪…...
算法训练营第二天| 209.长度最小的子数组、59.螺旋矩阵II、区间和
209.长度最小的子数组 题目 思路与解法 **第一想法:**无 carl的讲解: 滑动窗口 class Solution:def minSubArrayLen(self, target: int, nums: List[int]) -> int:ij0lens len(nums)sum 0res lens 1while j < lens:# for m in range(i, j1)…...
【C++ 真题】P3456 [POI2007] GRZ-Ridges and Valleys
[POI2007] GRZ-Ridges and Valleys 题面翻译 题目描述 译自 POI 2007 Stage 2. Day 0「Ridges and Valleys」 给定一个 n n n \times n nn 的网格状地图,每个方格 ( i , j ) (i,j) (i,j) 有一个高度 w i j w_{ij} wij。如果两个方格有公共顶点,…...
Vue3 中 computed的详细用法
Vue 3 中 computed 是一个非常重要的响应式 API,它是基于其依赖项的值来计算得出的值,当依赖项发生变化时,计算属性会自动更新 基本用法 在选项式 API 中,computed 通常作为一个选项直接在组件的选项对象中定义。例如 <temp…...
位带和位带别名区
位带区域和位带别名区域 位带区域(Bit-banding)是一种技术, 允许开发者直接访问和修改内存中的单个位。 这种技术在某些微控制器(如ARM Cortex-M系列)中特别有用,因为它可以简化对寄存器位的访问和修改。 …...
DRF凭什么更高效?Django原生API与DRF框架开发对比解析
一、原生 Django 开发 API 的局限性 虽然 Django 可以通过 JsonResponse 和视图函数手动构建 API,但存在以下问题: 手动序列化与反序列化 需要手动将模型实例转换为 JSON,处理复杂数据类型(如嵌套关系)时代码冗长且易…...
Agent智能体应用详解:从理论到实践的技术探索
一、Agent智能体是什么? 1. 核心定义 Agent智能体是能够感知环境、自主决策并执行动作以实现目标的软件实体。其核心特征包括: 自主性:无需外部指令持续运行。 反应性:实时响应环境变化。 目标导向:基于预设或学习…...
Windows下使用 VS Code + g++ 开发 Qt GUI 项目的完整指南
🚀 使用 VS Code g 开发 Qt GUI 项目的完整指南(Windows MSYS2) 本指南帮助你在 Windows 下使用 VS Code g CMake Qt6 快速搭建 Qt GUI 项目,适合熟悉 Visual Studio 的开发者向跨平台 VS Code 工具链迁移。 🛠️…...
arm64适配系列文章-第三章-arm64环境上mariadb的部署
ARM64适配系列文章 第一章 arm64环境上kubesphere和k8s的部署 第二章 arm64环境上nfs-subdir-external-provisioner的部署 第三章 arm64环境上mariadb的部署 第四章 arm64环境上nacos的部署 第五章 arm64环境上redis的部署 第六章 arm64环境上rabbitmq-management的部署 第七章…...
YOLOv8融合CPA-Enhancer【提高恶略天气的退化图像检测】
1.CPA介绍 CPA-Enhancer通过链式思考提示机制实现了对未知退化条件下图像的自适应增强,显著提升了物体检测性能。其插件式设计便于集成到现有检测框架中,并在物体检测及其他视觉任务中设立了新的性能标准,展现了广泛的应用潜力。 关于CPA-E…...
编译 C++ 报错“找不到 g++ 编译器”的终极解决方案(含 Windows/Linux/macOS)
前言 在使用终端编译 C 程序时,报错: 或类似提示,意味着你的系统尚未正确安装或配置 g 编译器。本篇将从零手把手教你在 Windows / Linux / macOS 下安装并配置 g,适用于新手或 C 入门阶段的你。 什么是 g? g 是 GN…...
Spring 过滤器详解:从基础到实战应用
Spring 过滤器详解:从基础到实战应用 引言 在 Spring 框架中,过滤器(Filter)是处理 HTTP 请求和响应的重要组件。它们为开发者提供了一种在请求到达控制器之前或响应返回客户端之前进行操作的机制。本文将深入探讨 Spring 中常见…...
达梦并行收集统计信息
达梦收集统计信息速度如何? 答:1分钟1G 大库收集起来可能比较慢,想并行收集需要一些条件 3个参数先了解一下 我把max_parallel_degree改为16 相关说明可以看一下 对一个3G的表收集 收集方法 DBMS_STATS.GATHER_TABLE_STATS( TEST,T1,…...
AOSP CachedAppOptimizer 冻结方案
背景 Android 一直面临一个核心难题:如何优化进程对有限系统资源(如 CPU、电量)的使用,同时保证用户体验。 当进程进入后台后,它们虽不再贡献用户体验,却仍可能消耗资源。传统的杀后台方案虽然节省资源&a…...
JVM-类加载机制
类加载 前言:为什么需要了解类加载?什么是类加载?生命周期概览类加载过程详解3.1 加载 (Loading)3.2 连接 (Linking)3.2.1 验证 (Verification)3.2.2 准备 (Preparation)3.2.3 解析 (Resolution) 3.3 初始化 (Initialization)3.3.1 <clini…...
【小白福音】SFTP限制权限登录
下面以在 Linux 环境(例如 Ubuntu 或 CentOS)上配置 SFTP chroot 为例,给出详细的步骤说明。即使你不熟悉服务器运维,也可以按照以下步骤进行配置,保证指定的 SFTP 用户只能访问预设目录,而无法触碰其他文件。 目录 一、配置SFTP权限1. 创建专用 SFTP 用户和用户组2. 搭建…...
海量数据笔试题--Top K 高频词汇统计
问题描述: 假设你有一个非常大的文本文件(例如,100GB),文件内容是按行存储的单词(或其他字符串,如 URL、搜索查询词等),单词之间可能由空格或换行符分隔。由于文件巨大&…...
Postman设置环境变量与Token
设置环境变量 设置某个Collection下的变量...
项目中数据结构为什么用数组,不用List
总结 1,从内存和性能角度,数组占用更小的内存(),访问性能更高() 分配效率:数组在内存中是连续分配的一块固定空间 访问速度:直接操作内存,数组的读写操作是…...
Linux常见指令介绍下(入门级)
1. head head就和他的名字一样,是显示一个文件头部的内容(会自动排序),默认是打印前10行。 语法:head [参数] [文件] 选项: -n [x] 显示前x行。 2. tail tail 命令从指定点开始将文件写到标准输出.使用t…...
从Kafka读取数据
用Spark-Streaming从Kafka读取数据 在大数据处理领域,Spark-Streaming和Kafka都是明星技术。今天咱们就来聊聊怎么用Spark-Streaming从Kafka读取数据并做处理,就算你是小白,也保证能看懂!先讲讲从Kafka获取数据的两种方式。早期有…...
硬件工程师面试常见问题(7)
第三十一问:RTC电路,电池寿命估算 上图可知,该电路有两个供电一个是电池供电,一个是其他供电,已知电池大小为120mAh,该电路在电池供电下吃3uA的电流,计算 120*(10^3)/ 3…...
二分小专题
P1102 A-B 数对 P1102 A-B 数对 暴力枚举还是很好做的,直接上双层循环OK 二分思路:查找边界情况,找出最大下标和最小下标,两者相减1即为答案所求 废话不多说,上代码 //暴力O(n^3) 72pts // #include<bits/stdc.h> // usin…...
Explain详解与索引最佳实践
Explain工具介绍 使用EXPLAIN关键字可以模拟优化器执行SQL语句,分析你的查询语句或是结构的性能瓶颈 在 select 语句之前增加 explain 关键字,MySQL 会在查询上设置一个标记,执行查询会返回执行计划的信息,而不是执行这条SQL 注意…...
【Qt6 QML Book 基础】07:布局项 —— 锚定布局与动态交互(附完整可运行代码)
引言 在 QML 界面开发中,** 锚定布局(Anchors)** 是实现响应式设计的核心机制。通过声明式的锚定规则,开发者无需手动计算坐标,即可让元素与父容器或其他元素保持动态位置关联。本文结合官方示例,详细解析…...
rocky9.4部署k8s群集v1.28.2版本(containerd)(纯命令)
文章目录 前言三个节点的主机名 所有节点操作主机名和ip解析关闭交换分区,关闭防火墙,关闭selinux更换阿里云yum源时间同步修改内核参数修改系统最大打开文件数开启bridge网桥过滤,加载br_netfilter模块,加载配置文件安装ipset及i…...