Python并发编程大揭秘:打造你的多任务处理超能战队!

今天给大家带来的是学习如何构建一个能够同时处理海量任务的超级团队。从简单的线程和锁,到复杂的异步IO和多进程部署,每一个工具都像是你团队中的一员,各有所长,共同协作!

文章目录

  • Python进阶之并发和并行编程详解
    • 1. 引言
      • 并发与并行编程的重要性
      • Python在并发并行处理领域的应用前景
        • 故事开始的地方
        • 并发与并行的区别
        • CPU bound与I/O bound任务解析
        • Python的魔法
    • 2. 背景介绍
      • 2.1 并发与并行基础概念
        • 定义区分并发与并行
        • CPU bound与I/O bound任务解析
      • 2.2 Python GIL简介
        • Global Interpreter Lock的作用与限制
        • GIL对并发并行的影响
    • 3. Python并发编程工具
      • 3.1 threading 模块
      • 3.2 asyncio 异步IO
      • 3.3 concurrent.futures
    • 4. Python并行编程实现
      • 4.1 multiprocessing 模块
      • 4.2 使用joblib进行数据并行处理
      • 4.3 并行计算库对比
    • 5. 实战案例分析
      • 5.1 Web服务器并发处理优化
        • 异步IO提升请求处理能力
        • 多进程部署提升吞吐量
      • 5.2 数据处理并行化实例
        • 大数据集的并行分析
        • 图像处理任务的并发执行
    • 6. 性能评估与调试
      • 6.1 性能测试工具
        • cProfile与timeit模块使用
        • VisualVM等第三方性能监控
      • 6.2 并发编程常见问题与对策
        • 死锁、竞态条件与解决方案
        • 资源争抢与效率瓶颈分析
    • 7. 结论
      • 并发与并行在Python应用中的权衡
      • 未来发展方向与技术趋势展望

Python进阶之并发和并行编程详解

1. 引言

并发与并行编程的重要性

在编程的世界里,有这样一种魔法,能够让你的代码像拥有了分身术一样,同时在多个任务上施展拳脚。这种魔法,就是并发和并行编程。想象一下,如果你的电脑能够同时运行多个程序,而不仅仅是一个接一个地执行,那么工作效率会提升多少?这就是并发和并行编程的魅力所在。

Python在并发并行处理领域的应用前景

Python,这门语言以其简洁明了的语法和强大的库支持,成为了编程界的宠儿。它在并发和并行处理领域也有着广泛的应用。无论是处理海量数据,还是构建高性能的Web服务,Python都能提供相应的工具和框架,让开发者能够轻松应对各种挑战。

故事开始的地方

让我们从一个故事开始吧。想象一下,你是一个餐厅的老板,你的餐厅生意非常火爆,顾客络绎不绝。但是,如果你的厨房只有一个厨师,那么无论这个厨师多么努力,顾客的等待时间都会很长。这时候,你可能会考虑增加厨师的数量,或者让一个厨师同时处理多个订单。这其实就是并发和并行的现实版。在编程的世界里,我们也需要这样的策略来提高效率。

并发与并行的区别

在这个故事中,如果多个厨师同时在厨房里忙碌,这就像是并行编程,每个厨师都是一个独立的进程,他们可以同时工作,互不干扰。而如果一个厨师在处理多个订单,他可能需要在不同的任务之间快速切换,这就像是并发编程,一个厨师在同一时间只能处理一个任务,但他可以快速地在多个任务之间切换,给人一种同时处理多个任务的错觉。

CPU bound与I/O bound任务解析

在编程中,我们的任务可以分为CPU bound和I/O bound两种。CPU bound任务就像是那些需要厨师精心准备的复杂菜肴,它们需要大量的计算能力。而I/O bound任务则像是那些简单的快餐,它们需要等待顾客点单或者等待食材送达。并发和并行编程可以帮助我们更有效地处理这两种任务,让CPU和I/O设备都得到充分利用。

Python的魔法

Python为我们提供了多种魔法工具,比如threading模块、asyncio异步IO、concurrent.futures等,这些都是我们提高编程效率的法宝。通过这些工具,我们可以像餐厅老板一样,合理分配资源,让代码运行得更加高效。

在接下来的章节中,我们将深入探讨这些魔法工具,看看它们是如何帮助我们提升编程效率的。同时,我们也会通过一些实战案例,来展示并发和并行编程在实际应用中的强大力量。让我们一步一步地揭开并发和并行编程的神秘面纱,探索Python在这一领域的无限可能。

在这里插入图片描述

2. 背景介绍

2.1 并发与并行基础概念

定义区分并发与并行

让我们继续我们的故事。想象一下,你是一个指挥家,站在一个大型交响乐团的前面。在你的指挥下,不同的乐器组可以同时发出美妙的音乐,这就是并行。但是,如果你让小提琴手在不同的时间点拉出不同的音符,虽然他们是一个人,却能创造出丰富的音乐层次,这就是并发。

在计算机科学中,并发是指多个任务在宏观上同时进行,但在微观上是交替执行的。这就像是我们的小提琴手,虽然他不能同时拉出多个音符,但他可以快速地在不同的音符之间切换,给人一种同时进行的错觉。

并行则是指多个任务在宏观上和微观上都同时进行。这就像是一个完整的交响乐团,每个乐器组都在同时演奏,共同创造出和谐的音乐。

CPU bound与I/O bound任务解析

回到我们的厨房比喻,CPU bound任务就像是那些需要厨师精心准备的复杂菜肴,它们需要大量的计算能力,比如图像处理、数据分析等。这些任务就像是指挥家需要精确控制的小提琴独奏,每一个音符都需要精确计算和处理。

而I/O bound任务则像是那些简单的快餐,它们需要等待顾客点单或者等待食材送达。这些任务的执行时间很大程度上取决于外部因素,比如网络请求、磁盘读写等。在这种情况下,我们的厨师可能大部分时间都在等待食材,而不是在烹饪。

2.2 Python GIL简介

Global Interpreter Lock的作用与限制

现在,让我们来谈谈Python中的一个独特现象——Global Interpreter Lock,简称GIL。GIL是Python解释器级别的一个锁,它确保在任意时刻,只有一个线程执行Python字节码。这就像是我们的餐厅在高峰时段,只有一个厨师被允许在厨房里烹饪,即使有多个厨师和多个顾客订单。

GIL的存在主要是为了简化CPython实现中的一些复杂性,尤其是在内存管理方面。但是,这也意味着在多线程环境中,即使有多个CPU核心,Python程序也可能无法实现真正的并行计算。

GIL对并发并行的影响

GIL对并发和并行编程有着显著的影响。在I/O bound任务中,由于线程大部分时间都在等待外部操作,GIL的存在对性能的影响较小。但是,在CPU bound任务中,GIL会限制多线程的性能,因为即使有多个线程,它们也不能真正地并行执行。

这就是为什么在处理CPU密集型任务时,我们可能会选择使用多进程而不是多线程。每个进程都有自己的Python解释器和内存空间,因此可以绕过GIL的限制,实现真正的并行计算。

在这一章节中,我们介绍了并发与并行的基本概念,解释了CPU bound和I/O bound任务的区别,并探讨了Python中GIL的作用和它对并发并行编程的影响。接下来,我们将深入探讨Python中的并发编程工具,看看如何克服GIL的限制,提高程序的性能。准备好了吗?让我们继续我们的探索之旅吧!

3. Python并发编程工具

3.1 threading 模块

想象一下,你是一个拥有超能力的程序员,可以同时在多个地方出现,处理不同的任务。这就是threading模块给我们带来的魔法。在这个模块中,Thread类就是我们的超能力源泉,它允许我们创建新的线程,就像在多个地方同时出现一样。

import threadingdef print_numbers():for i in range(1, 6):print(i)# 创建线程
t1 = threading.Thread(target=print_numbers)
t2 = threading.Thread(target=print_numbers)# 启动线程
t1.start()
t2.start()# 等待线程完成
t1.join()
t2.join()

在这个例子中,我们创建了两个线程,它们都会执行print_numbers函数。这就像是你在两个不同的电脑上同时运行相同的程序,但它们是分开的,互不干扰。

但是,当多个线程需要共享资源时,问题就来了。这就像是两个厨师同时想要使用同一个炒锅,如果没有规则,他们就会争抢,甚至可能把炒锅打翻。这就是为什么我们需要锁(Locks)、条件变量(Condition Variables)和线程同步。

# 创建一个锁
lock = threading.Lock()def print_numbers_with_lock():with lock:for i in range(1, 6):print(i)# 创建线程
t1 = threading.Thread(target=print_numbers_with_lock)
t2 = threading.Thread(target=print_numbers_with_lock)# 启动线程
t1.start()
t2.start()# 等待线程完成
t1.join()
t2.join()

在这个改进的例子中,我们使用了锁来确保每次只有一个线程可以打印数字。这就像是在炒锅旁边放了一个牌子,上面写着“使用中”,这样其他厨师就会知道需要等待。

3.2 asyncio 异步IO

现在,让我们来谈谈asyncio,这是Python中的另一个超能力——异步IO。它允许我们编写单线程并发代码,通过协程(Coroutine)来管理不同的任务。这就像是你有一个超级助手,他可以在不同的任务之间快速切换,而不需要你亲自去处理。

import asyncioasync def fetch_data():print("开始获取数据...")await asyncio.sleep(2)  # 模拟网络请求print("数据获取完成!")async def main():print("程序开始运行...")await fetch_data()print("程序结束运行。")# 运行事件循环
asyncio.run(main())

在这个例子中,fetch_data函数是一个协程,它使用await来暂停执行,模拟网络请求。main函数也是一个协程,它等待fetch_data完成。asyncio.run是启动事件循环的魔法,它让整个程序运行起来。

3.3 concurrent.futures

最后,我们有concurrent.futures,这是一个高级的并发编程工具,它提供了ThreadPoolExecutorProcessPoolExecutor来帮助我们管理线程和进程。这就像是你有一个团队,他们可以帮你完成各种任务。

from concurrent.futures import ThreadPoolExecutordef task(n):return n * n# 创建一个线程池
with ThreadPoolExecutor(max_workers=5) as executor:# 提交任务results = list(executor.map(task, range(10)))print(results)

在这个例子中,我们创建了一个线程池,并使用map方法来提交任务。线程池会智能地分配任务给线程,这样可以更有效地利用资源。

在这一章节中,我们探索了Python中的并发编程工具,包括threading模块、asyncio异步IO和concurrent.futures。我们通过一些简单的例子和代码,展示了如何使用这些工具来提高我们的编程效率。接下来,我们将深入探讨Python中的并行编程实现,看看如何让代码在多个CPU核心上同时运行。准备好了吗?让我们继续前进,探索Python的并行世界!

4. Python并行编程实现

4.1 multiprocessing 模块

想象一下,你是一家工厂的老板,你的工厂有多个车间,每个车间都可以独立生产产品。这就是multiprocessing模块给我们的魔法——它允许我们创建多个进程,每个进程就像是一个独立的车间,可以并行地执行任务。

from multiprocessing import Processdef print_numbers():for i in range(1, 6):print(f"进程 {Process().pid} 正在打印 {i}")# 创建进程
p1 = Process(target=print_numbers)
p2 = Process(target=print_numbers)# 启动进程
p1.start()
p2.start()# 等待进程完成
p1.join()
p2.join()

在这个例子中,我们创建了两个进程,它们都会执行print_numbers函数。这就像是你的工厂有两个车间,每个车间都在生产自己的产品,互不干扰。

在这里插入图片描述

4.2 使用joblib进行数据并行处理

现在,让我们来谈谈joblib,这是一个专门用于数据并行处理的库。它非常适合于处理那些可以被分解成多个小任务的大数据集。这就像是你有一个大型的拼图,你可以把它分成多个小块,然后让不同的人同时去拼这些小块。

from joblib import Parallel, delayeddef process_data(data_chunk):# 模拟数据处理return [x * x for x in data_chunk]# 一个大的数据集
data = range(100)# 使用joblib进行数据并行处理
results = Parallel(n_jobs=-1)(delayed(process_data)(chunk) for chunk in np.array_split(data, 4))print(results)

在这个例子中,我们使用joblibParalleldelayed函数来并行处理数据。n_jobs=-1表示使用所有可用的CPU核心。这就像是你让工厂的所有车间同时开始工作,每个车间处理一部分数据。

4.3 并行计算库对比

最后,让我们来比较一下Python中的几个并行计算库。NumPySciPy都提供了一些并行加速的特性,而Dask则是一个分布式计算框架,它可以让你在多个机器上进行并行计算。

  • NumPy:它是一个强大的科学计算库,它的数组操作在内部是高度优化的,可以自动利用多核CPU进行并行计算。

  • SciPy:它建立在NumPy之上,提供了更多的科学计算功能,其中一些函数也支持并行计算。

  • Dask:它是一个灵活的并行计算库,可以让你轻松地扩展到多台机器。Dask的数组(dask.array)和数据帧(dask.dataframe)可以看作是NumPy和Pandas的并行版本。

import dask.array as da# 创建一个大型的Dask数组
x = da.random.random((10000, 10000), chunks=(1000, 1000))# 计算数组的总和
result = x.sum().compute()
print(result)

在这个例子中,我们使用dask.array来创建一个大型数组,并使用compute方法来计算它的总和。Dask会自动地将数组分割成多个块,并在多个核心上并行计算。


在这一章节中,我们探索了Python中的并行编程实现,包括multiprocessing模块、joblib数据并行处理和几个并行计算库的对比。我们通过一些简单的例子和代码,展示了如何使用这些工具来提高我们的编程效率,并行地处理任务。接下来,我们将通过一些实战案例来展示这些工具在实际应用中的强大力量。准备好了吗?让我们继续前进,看看这些工具如何在实战中发挥作用!

5. 实战案例分析

5.1 Web服务器并发处理优化

想象一下,你拥有一家非常受欢迎的在线餐厅,顾客络绎不绝,订单像雪片一样飞来。但是,如果你的厨房(服务器)只有一个厨师(处理线程),那么即使厨师再快,也难以满足所有顾客的需求。这就是并发处理的重要性所在。

异步IO提升请求处理能力

使用异步IO,我们可以像拥有一个超级厨师团队,他们可以同时处理多个订单。每个厨师不需要等待一个订单完全完成后才能开始下一个,他们可以同时准备多个订单的不同部分。

# 假设我们有一个异步Web服务器框架
from aiohttp import webasync def handle_request(request):name = request.match_info.get('name', "Anonymous")text = f"Hello, {name}"return web.Response(text=text)app = web.Application()
app.router.add_get('/greet/{name}', handle_request)# 运行服务器
web.run_app(app)

在这个例子中,我们使用aiohttp创建了一个异步Web服务器。每个请求都是异步处理的,这意味着服务器可以在等待网络响应时处理其他请求,大大提高了效率。

多进程部署提升吞吐量

如果你的在线餐厅实在太火了,一个厨房(服务器)已经不够用了,那么可以考虑多进程部署。这就像是开设多个分店,每个分店都有自己的厨房和厨师团队。

from multiprocessing import Process
from your_web_server import run_serverdef run_server_on_port(port):run_server(port=port)if __name__ == "__main__":processes = []for port in range(8000, 8003):  # 假设我们有三个分店p = Process(target=run_server_on_port, args=(port,))p.start()processes.append(p)for p in processes:p.join()

在这个例子中,我们使用multiprocessing来运行多个服务器实例,每个实例监听不同的端口。这样,我们的在线餐厅就可以同时服务更多的顾客了。

5.2 数据处理并行化实例

现在,让我们谈谈数据处理。假设你是一位数据科学家,你的任务是对一个巨大的数据集进行分析。如果数据集足够大,单线程处理可能需要很长时间。

大数据集的并行分析

使用并行处理,我们可以将数据集分割成多个小块,然后在多个核心上同时处理。

import pandas as pd
from multiprocessing import Pool# 假设我们有一个大型数据集
df = pd.read_csv('large_dataset.csv')def process_chunk(chunk):# 对数据块进行一些处理return chunk.sum()if __name__ == "__main__":pool = Pool(processes=4)  # 创建一个拥有4个进程的池result = pool.map(process_chunk, np.array_split(df, 4))  # 并行处理total_sum = sum(result)  # 合并结果print(total_sum)

在这个例子中,我们使用pandas读取了一个大型数据集,并使用multiprocessing.Pool来并行处理数据块。

图像处理任务的并发执行

如果你的任务是图像处理,比如对一批图片进行滤镜效果,那么并发执行可以大大加快处理速度。

from PIL import Image
import os
from concurrent.futures import ThreadPoolExecutordef apply_filter(image_path):with Image.open(image_path) as img:img = img.filter(ImageFilter.BLUR)  # 应用模糊滤镜img.save(f"{image_path}_blur.jpg")  # 保存处理后的图片if __name__ == "__main__":executor = ThreadPoolExecutor(max_workers=5)  # 创建线程池executor.map(apply_filter, image_paths)  # 并发应用滤镜

在这个例子中,我们使用PIL库来处理图像,并使用concurrent.futures.ThreadPoolExecutor来并发执行图像处理任务。


在这一章节中,我们通过一些实战案例来展示了并发和并行编程在实际应用中的强大力量。我们看到了如何使用异步IO来提升Web服务器的请求处理能力,如何通过多进程部署来提升吞吐量,以及如何使用并行处理来加速大数据集的分析和图像处理任务。这些案例只是冰山一角,实际上,并发和并行编程的应用远不止这些。准备好了吗?让我们继续探索,并发和并行编程的更多可能性!

在这里插入图片描述

6. 性能评估与调试

6.1 性能测试工具

想象一下,你是一名赛车手,准备在赛道上驰骋。但在比赛之前,你需要对你的赛车进行一系列的测试,确保它能够在最佳状态下运行。同样,在编程世界中,我们也需要对我们的代码进行性能测试,以确保它能够高效地完成任务。

cProfile与timeit模块使用

cProfile是Python的一个内置性能分析工具,它就像是一个精密的赛车计时器,能够告诉我们代码中每个函数的调用次数和执行时间。

import cProfiledef some_function():# 一些复杂的计算result = [x * x for x in range(10000)]return result# 性能分析
cProfile.run('some_function()')

在这个例子中,我们使用cProfile.run()来分析some_function()的性能。它会生成一个详细的性能报告,包括每个函数的调用次数、总执行时间等。

timeit模块是另一个有用的工具,它可以用来测量小代码片段的执行时间。这就像是在赛道上的秒表,用来测量每个小段赛道的完成时间。

import timeit# 测量代码执行时间
execution_time = timeit.timeit('sum([x*x for x in range(1000)])', number=1000)
print(f"执行时间: {execution_time} 秒")
VisualVM等第三方性能监控

除了Python内置的工具外,还有一些第三方的性能监控工具,如VisualVM,它提供了一个图形界面,可以实时监控应用程序的性能。

6.2 并发编程常见问题与对策

在并发编程的世界中,我们可能会遇到一些问题,比如死锁、竞态条件等。这些问题就像是赛车比赛中的意外,需要我们采取策略来避免或解决。

死锁、竞态条件与解决方案

死锁发生在多个线程因为争夺资源而相互等待,最终导致程序无法继续执行。这就像是两辆车在赛道上相互阻挡,导致比赛无法进行。

import threading# 死锁示例
lock1 = threading.Lock()
lock2 = threading.Lock()def thread1():with lock1:print("线程1获取了锁1")with lock2:print("线程1获取了锁2")def thread2():with lock2:print("线程2获取了锁2")with lock1:print("线程2获取了锁1")# 启动线程
t1 = threading.Thread(target=thread1)
t2 = threading.Thread(target=thread2)
t1.start()
t2.start()

在这个例子中,如果thread1thread2同时运行,它们会相互等待对方释放锁,导致死锁。

为了避免死锁,我们可以采取一些策略,比如总是以相同的顺序获取锁,或者使用超时来尝试获取锁。

竞态条件发生在多个线程访问共享数据时,由于访问顺序的不同,导致数据不一致。这就像是在赛车比赛中,由于计时器的不同步,导致成绩统计错误。

# 竞态条件示例
balance = 0def deposit(amount):global balancebalance += amount# 启动多个线程进行存款操作
threads = []
for _ in range(10000):t = threading.Thread(target=deposit, args=(1,))t.start()threads.append(t)for t in threads:t.join()print(balance)  # 输出可能不是10000

在这个例子中,由于多个线程同时修改balance,导致竞态条件,最终的balance值可能不是我们期望的10000。

为了避免竞态条件,我们可以使用锁来同步对共享资源的访问,或者使用原子操作。

资源争抢与效率瓶颈分析

资源争抢是并发编程中的另一个常见问题,它会导致线程频繁地等待资源,从而降低程序的效率。这就像是赛车比赛中,由于赛车之间的争抢,导致比赛节奏变慢。

为了解决资源争抢问题,我们可以对资源进行合理的分配和管理,比如使用线程池来限制同时运行的线程数量。

效率瓶颈分析是识别并发程序中的性能瓶颈,然后进行优化。这就像是赛车手通过分析比赛数据,找出赛车性能的瓶颈所在,然后进行调整。


在这一章节中,我们探讨了性能评估与调试的一些工具和策略。我们了解了如何使用cProfiletimeit来测量代码的性能,以及如何使用第三方工具如VisualVM来监控应用程序。此外,我们还讨论了并发编程中常见的问题,如死锁、竞态条件和资源争抢,并提供了一些解决方案。通过这些工具和策略,我们可以确保我们的并发程序能够高效、稳定地运行。准备好了吗?让我们继续前进,优化我们的并发程序,让它们像赛车一样飞驰!

7. 结论

并发与并行在Python应用中的权衡

经过了前面几章的冒险,我们就像是一位经验丰富的船长,驾驭着Python这艘大船,在并发和并行的海洋中乘风破浪。现在,让我们来总结一下这次航行的收获。

在Python中,并发并行是两个强大的工具,它们可以帮助我们提升程序的性能,处理更复杂的任务。但是,就像任何强大的工具一样,它们也需要谨慎使用。

  • 并发适用于I/O密集型的任务,比如网络请求、文件读写等。通过threading模块或者asyncio,我们可以轻松地实现并发,让程序在等待I/O操作时也能做其他事情。

  • 并行则适用于CPU密集型的任务,比如数值计算、图像处理等。这时,multiprocessing模块或者joblibDask等库就能大显身手,让多个CPU核心同时工作,大大加快处理速度。

但是,使用这些工具时,我们也需要考虑GIL(Global Interpreter Lock)的影响。虽然GIL限制了Python多线程的CPU并行,但它在I/O密集型任务中的影响并不大。而在需要CPU并行时,我们可以通过多进程或者使用支持并行计算的库来绕过GIL的限制。

未来发展方向与技术趋势展望

展望未来,Python在并发和并行领域的发展前景非常广阔。随着多核处理器的普及和云计算的发展,我们有理由相信,Python的并发和并行编程将会变得更加重要。

  • 异步编程可能会成为主流,因为异步IO能够更好地利用单线程在I/O等待时的空闲时间。

  • 多进程和分布式计算也将继续发展,随着云计算资源的丰富,我们可能会看到更多的分布式计算框架和工具的出现。

  • 性能分析和调试工具也将不断进步,提供更详细的性能数据和更智能的分析建议,帮助开发者优化代码。

  • 新的编程模型和范式可能会出现,比如利用量子计算、机器学习等新技术,为并发和并行编程带来新的思路。


随着我们的旅程即将结束,我们不仅学会了如何使用Python进行并发和并行编程,还学会了如何权衡和选择最合适的工具。在未来的编程之路上,无论是面对I/O密集型的任务,还是CPU密集型的任务,我们都能够游刃有余,写出既高效又优雅的代码。

就像一位赛车手在赛道上不断追求速度与激情,我们也将在编程的赛道上不断追求性能与创新。让我们带着这次航行的收获,继续前进,探索编程世界的无限可能吧!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/841911.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Linux-INPUT输入的子系统】

Linux-INPUT输入的子系统 ■ input 子系统简介■ input 驱动编写流程■ ■ input 子系统简介 input 子系统就是管理输入的子系统, input 子系统分为 input 驱动层、 input 核心层、 input 事件处理层,最终给用户空间提供可访问的设备节点 ■ input 驱…

React类组件生命周期详解

在React的类组件中,从组件创建到组件被挂载到页面中,这个过程react存在一系列的生命周期函数,最主要的生命周期函数是componentDidMount、componentDidUpdate、componentWillUnmount 生命周期图例如下 1. componentDidMount组件挂载 如果你…

S1E45:单链表1 课后作业

测试题:0. 相比起数组来说,单链表具有哪些优势呢? 答:长度非固定,可以申请添加长度 答案:对于数组来说,随机插入或者删除其中间的某一个元素,都是需要大量的移动操作,而…

网络攻击攻击之-远程命令执行/RCE告警运营分析篇

在各种网络安全产品的告警中,远程命令执行是一种非常常见的告警。本文将从远程命令执行的定义,远程命令执行利用的流量数据包示例,远程命令执行的suricata规则,远程命令执行的告分析警研判,远程命令执行的处置建议等几个方面阐述如何通过IDS/NDR,态势感知等流量平台的远程…

深入解析RPC技术:原理、实现与应用

RPC(Remote Procedure Call,远程过程调用)是一种计算机通信协议,允许一个程序(客户端)在本地调用另一个程序(服务器)中的函数或方法,并获取返回结果,就像调用…

C++:STL简介和容器string用法篇

一、STL简介 STL是C中的标准模板库(Standard Template Library)的缩写。它是C标准库的一部分,提供了一系列的数据结构和算法模板,包括各种容器、算法、迭代器、仿函数等,用于简化和加速C程序的开发过程。STL的设计理念…

shell脚本开发基础

shell脚本开发基础 什么是linux内置命令?什么是外置命令 内置命令:在系统启动时就加载入内存,常驻内存,执行效率更高,但是占用资源,cd 外置命令:系统需要从硬盘中读取程序文件,再读…

第八篇【传奇开心果系列】Python微项目技术点案例示例:以微项目开发为案例,深度解读Dearpygui 编写图形化界面桌面程序的优势

传奇开心果博文系列 系列博文目录Python微项目技术点案例示例系列 博文目录前言一、开发图形化界面桌面程序的优势介绍二、跨平台特性示例代码和解析三、高性能特性示例代码和解析四、简单易用特性示例代码和解析五、扩展性强示例代码和解析六、现代化设计示例代码和解析七、知…

什么是云渗透测试?

推荐阅读: 什么是安全态势? 什么是人肉搜索 什么是恶意软件? 什么是数字取证? 什么是语音网络钓鱼? 什么是网络安全中的社会工程? 什么是网络安全中的威胁情报? 什么是端点检测和响应 (…

linux 阿里云服务器安装ImageMagick和php扩展imagick

操作系统版本 Alibaba Cloud Linux 3.2104 LTS 64位 # 1.安装ImageMagick yum install -y ImageMagick ImageMagick-devel # 没有pecl要先安装pecl 和头文件 sudo yum install php-devel # 2.pecl 安装扩展 pecl install imagick #寻找所有php.ini文件 find / -name php.…

静态随机存储器(SRAM)

目录 介绍 基本的 SRAM 存储单元阵列 1. SRAM 存储单元 2. SRAM 阵列 3. SRAM 阵列的读写操作 4. SRAM 阵列的扩展 5. SRAM 阵列的应用 6. SRAM 阵列的优缺点 基本的 SRAM 逻辑结构 1. 存储单元 2. 存储单元阵列 3. 译码器 4. 读写电路 5. 控制逻辑 6. SRAM 逻辑…

【前端之ES6语法】

前端之ES6语法 1. ES6简介2. ES6新特性3.ES6不支持,使用babel3.1 参考文献 4.let和const命令5. 模版字符串6.函数之默认值、剩余参数7. 函数之扩展运算符、箭头函数8.箭头函数this指向和注意事项9.解构赋值10.对象扩展11.Symbol类型12.Set集合类型13.Map数据类型14.…

React自定义Componment和State深层次理解-07

本节主要从底层原理上分析下React开发相关的内容和注意事项,本节会围绕使用展开,而非源码讲解。 Componment详解 什么是组件 在 MVVM架构出现之前,组件主要分为两种。 狭义上的组件,又称为 UI 组件,比如 Tabs 组件、…

Java计算日期相差天数的几种方法

Java计算日期相差天数的几种方法 🗓️ Java计算日期相差天数的几种方法摘要引言一、使用java.util.Date和java.util.Calendar📅1. 使用java.util.Date示例代码 2. 使用java.util.Calendar示例代码 二、使用java.time.LocalDate📆示例代码 三、…

微信小程序文本框输入显示已经输入的字数

我们遇到这样的需求,就是微信小程序的输入框下面需要显示输入的字数: 我们通常会使用bindinput事件,让显示的字数等于value的长度,看下面的图: 但在实践中,真机测试中,我们会发现以下问题: 这个…

IP编址、进制转换、IP地址分类、变长子网掩码VLSM、无类域间路由CIDR

前言 网络层位于数据链路层与传输层之间。网络层中包含了许多协议,其中最为重要的协议就是IP协议。网络层提供了IP路由功能。理解IP路由除了要熟悉IP协议的工作机制之外,还必须理解IP编址以及如何合理地使用IP地址来设计网络。 IP编址 每个网段上都有两…

Java的类路径究竟是什么?

回答 问了chatgpt这个问题,首先类路径的定义是: 是指一组路径,这些路径告诉Java虚拟机(JVM)和类加载器在哪里可以找到应用程序所需的类和资源文件。说白了就是在运行java程序的时候需要先将java源代码编译成class文件…

基础IO用户缓冲区 、inode、硬软链接【Linux】

文章目录 用户缓冲区磁盘磁盘分区EXT2文件系统的存储方案 inode软链接硬链接 用户缓冲区 代码一&#xff1a; 1 #include<stdio.h>2 #include<unistd.h>3 #include<string.h> 4 int main()5 {6 const char * fstr &…

基于FIDO2和USBKEY硬件的SSH认证

在 8.2&#xff08;最新为 8.3&#xff09;版本中&#xff0c;OpenSSH 提供了对 FIDO 和 UAF 的支持。从此用户就可以用硬件 USBKEY 证书进行 SSH 原生认证。这样可以实现简捷、有效和安全的 SSH 认证。本文我们就就少一下 FIDO2 以及 OpenSSH 对其的支持&#xff0c;并尝试一下…

【调试笔记-20240521-Linux-编译 QEMU/x86_64 可运行的 OpenWrt 固件】

调试笔记-系列文章目录 调试笔记-20240521-Linux-编译 QEMU/x86_64 可运行的 OpenWrt 固件 文章目录 调试笔记-系列文章目录调试笔记-20240521-Linux-编译 QEMU/x86_64 可运行的 OpenWrt 固件 前言一、调试环境操作系统&#xff1a;Ubuntu 22.04.4 LTS编译环境调试目标 二、调…