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

PYTHON专题-(10)基操之我要玩并发

什么是并发?

  • 并发指的是两个或多个事件在同一时间间隔内发生。在计算机科学中,并发通常指的是一个程序同时执行多个独立的任务。这些任务可以同时进行,而不会相互干扰或阻塞彼此。并发可以提高程序的执行效率和资源利用率,但也需要考虑并发控制和同步问题。

并发操作主要有哪些? 

并发操作主要有以下几种:

  1. 同步操作:在多个线程或进程中通过互斥锁、信号量等机制实现对共享资源的同步访问,保证其一致性和完整性。

  2. 异步操作:多个任务可以独立运行,不需要等待其他任务的完成。通过回调函数、事件驱动等方式实现。

  3. 并行操作:同时进行多个任务,利用多核处理器或多台机器的计算资源,加速任务的完成速度。

  4. 分布式操作:将一个任务分解为多个子任务,在不同的机器或网络节点上并行执行。

  5. 互斥操作:通过锁、信号量等机制实现对共享资源的互斥访问,保证同一时间只有一个线程或进程能够访问该资源。

  6. 条件变量操作:通过条件变量等机制实现线程之间的通信和协作,如等待、唤醒、通知等操作。

  7. 线程池操作:通过线程池管理线程的创建、销毁和复用,提高多线程程序的性能和可维护性。

  8. 异常处理操作:处理多线程或多进程中可能出现的异常情况,保证程序的稳定性和可靠性。

进程和线程是什么?

  • 进程(Process)是指在计算机中正在运行的程序实例。每个进程都有自己的地址空间、数据和代码段以及其他资源,它们相互独立运行,不会互相干扰。
  • 线程(Thread)是在进程内部执行的一个执行单元。与进程不同的是,多个线程可以共享同一个进程的资源,包括地址空间、文件描述符、设备等。线程是进程的一个实体,一个进程可以有多个线程。
  • 线程是进程的一部分,而进程则是操作系统分配资源的最小单位。一个进程可以包含多个线程,这些线程共享同一进程的资源,并能并发执行。

线程和进程在操作系统中具有不同的属性和区别。

  1. 资源占用:进程之间相互独立,每个进程有自己的地址空间和资源,而线程共享同一进程的资源。
  2. 切换开销:线程之间的切换开销比进程小,因为线程共享同一进程的地址空间,切换时只需切换线程的执行上下文。
  3. 并发性:多个线程可以同时执行,实现并发操作,而进程则需要通过进程调度实现并发。
  4. 通信与同步:进程之间通常使用进程间通信(IPC)机制进行通信,而线程之间可以直接共享同一进程的内存空间,可以通过共享内存进行通信,并且同步问题较容易解决。
  5. 独立性:进程之间相互独立,互不影响,而线程之间共享同一进程的资源,一个线程崩溃可能影响整个进程的稳定性。

 

什么是多进程和多线程?  

  • 多进程是指在操作系统层面上同时运行多个独立的进程。每个进程有独立的内存空间,程序计数器和其他资源。多进程之间相互独立,彼此不会影响。每个进程都有自己的执行流,可以同时执行多个任务。
  • 多线程是指在同一个进程内启动多个线程来执行任务。多个线程共享同一个进程的内存空间,程序计数器和其他资源。多线程之间可以共享数据,彼此之间可以进行通信和协作。多线程可以实现任务的并发执行。

区别:

  • 内存占用:多进程需要分配独立的内存空间,而多线程共享同一内存空间,所以多线程的内存占用较小。
  • 切换开销:多进程切换时需要切换上下文环境,开销较大;而多线程切换时只需要切换线程的上下文环境,开销较小。
  • 通信方便程度:多进程通信需要使用进程间通信的方式,如管道、消息队列等;而多线程通信直接共享进程的内存空间,通信更方便。
  • 编程模型:多进程编程需要考虑进程之间的同步和通信,而多线程编程需要考虑线程的同步和锁机制。

选择多进程还是多线程取决于具体的应用场景和需求。

Python怎么实现多进程 ?

  • Python中可以使用multiprocessing模块来实现多进程。multiprocessing模块提供了一个Process类,可以用来创建新的进程。
    import multiprocessingdef worker(num):"""子进程的任务"""print(f'Worker {num} is running')if __name__ == '__main__':# 创建4个子进程processes = []for i in range(4):p = multiprocessing.Process(target=worker, args=(i,))processes.append(p)p.start()# 等待子进程结束for p in processes:p.join()
    
  • 在这个例子中,我们定义了一个worker函数作为子进程的任务。然后使用multiprocessing.Process类创建4个子进程,并将worker函数作为进程的任务。调用start方法启动进程,调用join方法等待子进程结束。
  • 注意,在Windows系统中,multiprocessing模块的代码必须位于if __name__ == '__main__':条件判断内,以避免创建子进程时出现递归调用的问题。
  • 除了使用multiprocessing模块外,还可以使用concurrent.futures模块来实现多进程。concurrent.futures模块提供了一个ProcessPoolExecutor类,可以用来创建进程池,简化多进程编程的过程。

什么是子进程?

  • 子进程是指在一个父进程的控制下被创建的新进程。子进程复制了父进程的所有属性和代码,并在父进程的地址空间中执行。父进程可以创建多个子进程,每个子进程都有一个唯一的进程ID。子进程通常用于并发执行多个任务,实现进程间的并行处理。

什么是进程池Pool?

  • 进程池(Pool)是一种并发编程的技术,用于管理和重用一组进程,以便并行执行任务。进程池由一组预先创建的进程组成,这些进程可以从一个任务队列中获取任务,并在完成任务后将结果返回给调用者。
  • 进程池通常由一个主线程或进程创建,并在启动时创建指定数量的工作进程。工作进程可以同时处理多个任务,当一个任务完成后,工作进程可以立即获取并开始执行下一个任务。这样,可以减少创建和销毁进程的开销,并将重复利用进程提高效率。
  • 进程池的使用可以简化并发编程的复杂性,特别是在涉及大量计算或IO密集型任务时。通过使用进程池,可以提高任务的响应速度和整体性能。
  • 在Python中,可以使用multiprocessing模块中的Pool类来创建和管理进程池。

Python怎么使用multiprocessing模块中的Pool类 ?

  • 使用multiprocessing模块中的Pool类可以方便地实现并行计算。Pool类提供了一种简单的方式来并行地执行多个函数。
    import multiprocessing# 定义一个函数,用于计算平方
    def square(x):return x**2if __name__ == '__main__':# 创建一个Pool对象,指定最大进程数为4pool = multiprocessing.Pool(processes=4)# 使用Pool的map方法来并行地计算列表中每个元素的平方result = pool.map(square, [1, 2, 3, 4, 5])# 打印结果print(result)# 关闭Pool,表示不再接受新的任务pool.close()# 等待所有子进程执行完毕pool.join()
    
  • 在上述代码中,首先定义了一个函数square,用于计算一个数的平方。然后在if __name__ == '__main__':条件下创建了一个Pool对象,指定最大进程数为4。使用Pool的map方法并行地计算了列表[1, 2, 3, 4, 5]中每个元素的平方。最后打印了结果。
  • 注意,为了避免在Windows平台上出现死锁问题,必须将创建Pool对象的代码放在if __name__ == '__main__':条件下执行。

什么是进程间通信?

  • 进程间通信(Inter-Process Communication,简称IPC)是指操作系统或者计算机系统中,不同进程之间进行数据或者信息交换的机制和方式。进程是运行中的程序的实例,每个进程都有自己的内存空间,独立执行。进程间通信允许不同的进程共享数据,发送和接收消息,协调任务等。

进程间通信的方式有多种,主要包括以下几种:

  1. 管道(Pipe):管道是一个单向的通信通道,在父进程和子进程之间传递数据。

  2. 命名管道(Named Pipe):命名管道也是一个单向的通信通道,但是可以在不相关的进程之间进行通信。

  3. 共享内存(Shared Memory):共享内存允许不同进程在同一个物理内存区域中进行读写操作,实现高效的数据共享。

  4. 信号量(Semaphore):信号量是一种用于进程同步的机制,可以控制共享资源的访问。

  5. 消息队列(Message Queue):消息队列是一个消息的链表,进程可以将消息放入队列中,其他进程可以从队列中读取消息。

  6. 套接字(Socket):套接字可以在网络上进行进程间通信,常用于不同计算机之间的通信。

不同的进程间通信方式适用于不同的场景和需求,开发者可以根据具体的应用场景选择合适的进程间通信方式。

怎么实现进程间通信?

  • 管道(Pipe):使用multiprocessing模块中的Pipe函数可以创建一个管道对象,用于在两个进程之间传递数据。其中一个进程作为发送方,将数据写入管道,另一个进程作为接收方,从管道中读取数据。
    from multiprocessing import Process, Pipedef sender(conn):# 发送数据conn.send('Hello')def receiver(conn):# 接收数据data = conn.recv()print(data)if __name__ == '__main__':# 创建管道对象parent_conn, child_conn = Pipe()# 创建发送进程sender_process = Process(target=sender, args=(parent_conn,))# 创建接收进程receiver_process = Process(target=receiver, args=(child_conn,))# 启动进程sender_process.start()receiver_process.start()# 等待进程结束sender_process.join()receiver_process.join()
    
  • 队列(Queue):使用multiprocessing模块中的Queue类可以创建一个进程安全的队列,用于在多个进程之间传递数据。其中一个进程作为发送方,调用put方法将数据放入队列,另一个进程作为接收方,调用get方法从队列中取出数据。
    from multiprocessing import Process, Queuedef sender(queue):# 发送数据queue.put('Hello')def receiver(queue):# 接收数据data = queue.get()print(data)if __name__ == '__main__':# 创建队列对象queue = Queue()# 创建发送进程sender_process = Process(target=sender, args=(queue,))# 创建接收进程receiver_process = Process(target=receiver, args=(queue,))# 启动进程sender_process.start()receiver_process.start()# 等待进程结束sender_process.join()receiver_process.join()
    
  • 共享内存(Shared Memory):使用multiprocessing模块中的ValueArray类可以创建共享内存,多个进程可以直接读写这块内存,实现数据共享。
    from multiprocessing import Process, Value, Arraydef writer(shared_value, shared_array):# 写入共享内存shared_value.value = 123shared_array[0] = 456def reader(shared_value, shared_array):# 读取共享内存value = shared_value.valuearray_value = shared_array[0]print(value, array_value)if __name__ == '__main__':# 创建共享内存对象shared_value = Value('i')shared_array = Array('i', range(10))# 创建写入进程writer_process = Process(target=writer, args=(shared_value, shared_array))# 创建读取进程reader_process = Process(target=reader, args=(shared_value, shared_array))# 启动进程writer_process.start()reader_process.start()# 等待进程结束writer_process.join()reader_process.join()
    
  • 套接字(Socket):使用socket模块可以在网络中传递数据,也可以在同一台机器上不同的进程之间传递数据。通过创建套接字并使用bind方法绑定到本机的一个端口,然后使用sendrecv方法进行数据传输。
    import socket
    import multiprocessingdef sender():with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:# 绑定到本机的一个端口s.bind(('localhost', 8888))s.listen(1)
    

管道和队列的区别?

管道和队列都是用于进程间通信的机制,但它们有一些区别。

  1. 数据结构:管道是一种特殊的文件,具有固定的读端和写端,进程通过读端从管道中读取数据,通过写端向管道中写入数据。而队列是一种数据结构,有头部和尾部,元素按照一定的顺序放入和取出。

  2. 通信方式:管道是一种半双工的通信方式,即同一时刻只能有一个进程进行读或写操作。而队列可以是单向的或双向的,可以同时有多个进程进行入队或出队操作。

  3. 通信对象:管道只能用于具有亲缘关系的进程间通信,即父子进程或兄弟进程。而队列可以用于任意进程间通信,不受关系限制。

  4. 数据传输:管道通常是字节流的形式,不保留边界信息,进程需要自行解析数据。而队列通常是以消息的形式进行传输,每个消息包含一个完整的数据包。

  5. 复杂性:队列通常比管道更复杂,需要维护队列的头部和尾部指针,以及处理并发访问的问题。而管道相对简单,只需处理读写两个操作。

总的来说,管道适用于具有亲缘关系的进程间通信,对于简单的数据传输任务较为合适;而队列则适用于任意进程间通信,对于复杂的消息传输场景更为适用。

什么是套接字?

  • 套接字(Socket)是计算机网络中一种通信机制,它允许在不同主机间的进程进行通信。套接字提供了一个抽象层,使得进程可以通过发送和接收数据来进行通信,无需关注底层网络细节。
  • 套接字可以用于实现不同的通信协议,如TCP(传输控制协议)和UDP(用户数据报协议)。在使用套接字进行通信时,通常有一个客户端和一个服务器端。客户端通过创建一个套接字来发起连接请求,而服务器端通过监听一个套接字来接受连接请求。
  • 套接字通常使用IP地址和端口号来标识通信的双方。IP地址用于找到目标主机,而端口号用于找到目标进程。在进行通信前,双方需要协商好使用的协议和端口号。
  • 套接字的使用方式可以分为阻塞和非阻塞。在阻塞模式下,套接字会一直等待直到有数据可以读取或写入。在非阻塞模式下,套接字会立即返回结果,并根据返回值来判断是否有数据可读取或写入。

Python怎么实现多线程 ? 

  • 在Python中,可以使用threading模块来实现多线程。
    import threading# 线程1的执行函数
    def thread1_func():print("Thread 1 is running")# 线程2的执行函数
    def thread2_func():print("Thread 2 is running")# 创建线程对象
    thread1 = threading.Thread(target=thread1_func)
    thread2 = threading.Thread(target=thread2_func)# 启动线程
    thread1.start()
    thread2.start()# 等待线程执行完毕
    thread1.join()
    thread2.join()print("All threads have finished")
    
  • 在这个例子中,我们首先定义了两个函数thread1_functhread2_func,它们将作为线程1和线程2的执行函数。然后,我们使用threading.Thread类创建了两个线程对象thread1thread2,并将执行函数分别传递给它们。最后,我们调用start方法启动线程,然后调用join方法等待线程执行完毕。
  • 需要注意的是,Python中的多线程并不是真正的并行执行,而是通过线程切换来实现的。这是由于Python解释器的全局锁(GIL)的限制。如果需要实现真正的并行执行,可以考虑使用multiprocessing模块来创建多个进程。

 

什么是全局锁(GIL)? 

  • 全局锁(GIL)是指在Python解释器中的一种机制,用于确保在多线程环境下同一时刻只有一个线程在执行Python字节码。这意味着在多线程环境下,无论有多少个CPU核心,同一时刻只能有一个线程在执行Python代码。
  • GIL的存在是为了简化Python解释器的实现,因为它可以避免多线程环境下对共享数据的竞争和冲突问题。然而,由于GIL的存在,Python的多线程并不是真正的并行执行,而是通过在不同线程之间切换来模拟并发执行。这也是为什么Python在处理CPU密集型任务时效率较低的原因。但对于I/O密集型任务,Python的多线程仍然可以带来一定程度的性能提升。

什么是CPU密集型任务和I/O密集型任务?

  • CPU密集型任务是指需要大量CPU计算资源的任务,例如高性能计算、科学模拟、图像处理等。这类任务主要依赖于CPU处理能力,对CPU的计算速度要求较高,通常不涉及大量的数据读写操作。
  • I/O密集型任务是指需要大量I/O操作的任务,包括文件读写、网络通信、数据库访问等。这类任务主要涉及数据的输入输出操作,对CPU的计算能力要求相对较低,但对I/O设备的响应速度要求较高,尤其是涉及大量的数据读写操作。

什么是ThreadLocal? 

  • 在Python中,ThreadLocal是一个线程局部变量,可以让每个线程都拥有自己独立的变量副本,互相之间不会干扰。
  • ThreadLocal通常用于解决多线程环境下数据共享的问题。在多线程环境下,如果多个线程共享同一个变量,可能会导致数据不一致或竞争条件的发生。而使用ThreadLocal可以为每个线程创建一个独立的变量副本,保证了每个线程都操作自己的变量,从而避免了这些问题。
  • 通过ThreadLocal,每个线程都可以独立地操作自己的变量副本,而无需关心其他线程的操作。这样可以提高多线程程序的效率和安全性。
  • 在Python中,可以使用threading模块的ThreadLocal类来创建ThreadLocal变量。可以通过ThreadLocal的set()方法设置变量的值,通过get()方法获取变量的值。

在python中,多进程和多线程的区别和应用场景是什么? 

区别:

  1. 多进程是指在操作系统中同时执行多个独立的进程,每个进程有自己独立的内存空间,它们之间没有共享的内存;而多线程是指在同一个进程中执行多个独立的线程,它们共享相同的内存空间。
  2. 多进程的切换开销较大,因为切换进程需要保存和恢复进程的上下文,而多线程的切换开销较小,因为切换线程只需要保存和恢复线程的上下文。
  3. 多进程可以更好地利用多核处理器的优势,因为每个进程可以在不同的核上并行执行;而多线程不能同时在多个核上并行执行,因为操作系统会将多个线程分配到同一个核上执行。

适用场景:

  1. 多进程适合用于CPU密集型任务,即需要大量的计算资源的任务,因为多个进程可以在多个核上同时进行计算,从而提高整体的运算速度。
  2. 多线程适合用于I/O密集型任务,即需要频繁进行I/O操作的任务,比如网络通信、文件读写等,因为在I/O操作时,线程可以释放CPU资源,从而充分利用CPU的时间片,提高整体的吞吐量。
  3. 在需要进行大规模并行计算的场景中,可以同时使用多进程和多线程,即将任务分为多个子任务,每个子任务使用一个进程,而每个进程内部使用多个线程来进行计算,以充分利用多核和多线程的优势,提高计算效率。

什么是协程?

  • 协程是一种并发编程的技术,也被称为轻量级线程。它是一种在单个线程中实现并发的方式,不同于传统的线程或进程。协程可以在程序中进行切换执行,即在一个协程执行过程中,可以暂停执行并切换到另一个协程中执行,然后再返回到原来的协程继续执行。
  • 协程的一个主要特点是可以在执行过程中保存上下文,包括变量的值、指令的位置等等,使得在切换到其他协程执行后可以恢复到之前的状态。这样可以避免了多线程中频繁地进行上下文切换所带来的开销,从而提高了程序的性能。
  • 协程的应用场景包括异步编程、高并发处理、事件驱动等领域。在异步编程中,协程可以用于实现协作式多任务处理,使得多个任务可以按照一定的顺序依次执行,而不是同时执行。在高并发处理中,协程可以帮助实现高效的请求处理,提高系统的吞吐量和响应速度。在事件驱动中,协程可以用于处理事件的触发和响应,提供更加灵活的事件处理方式。总之,协程是一种强大的并发编程技术,可以帮助提高程序的性能和可维护性。

为什么需要协程?

协程是一种轻量级的并发编程方式,它可以在一个线程中实现多个任务的并发执行。相比于线程或进程,协程有以下优势:

  1. 轻量级:协程的创建和切换开销很小,不像线程和进程需要操作系统的支持和上下文切换的开销,因此可以高效地使用系统资源。

  2. 高并发:由于协程是在单个线程中运行,因此可以同时运行多个协程,实现高并发的效果。而线程或进程的数量受限于系统的硬件资源,不能无限增加。

  3. 高效率:由于协程是在单个线程中切换执行的,避免了线程切换的开销和同步的复杂性,因此可以提高程序的运行效率。

  4. 简化编程模型:协程通过使用异步操作和事件循环,解决了传统多线程编程中的并发问题。它可以将并发任务拆分为多个独立的协程,每个协程只处理自己的任务,简化了程序的编写和维护。

  5. 更低的资源消耗:由于协程的创建和切换开销很小,因此可以创建更多的协程来处理任务,而不像线程或进程那样受限于系统资源。这样可以更充分地利用系统资源,提高任务的处理能力。

因此,协程在并发编程中具有重要的作用,可以提高程序的运行效率和并发处理能力,简化编程模型,减少资源消耗。

怎么实现协程?

  • 在Python中,可以使用asyncio模块来实现协程。
    import asyncioasync def foo():print('Foo')await asyncio.sleep(1)print('End Foo')async def bar():print('Bar')await asyncio.sleep(2)print('End Bar')async def main():task1 = asyncio.create_task(foo())task2 = asyncio.create_task(bar())await task1await task2asyncio.run(main())
    
  • 在上面的例子中,foo()bar()函数都是协程,使用async关键字进行定义。这些协程函数可以使用await关键字来等待其他协程的运行结果。在main()函数中,我们通过asyncio.create_task()函数创建了两个协程任务,并使用await关键字等待它们完成。最后,通过调用asyncio.run()函数来运行main()函数,从而启动协程的执行。
  • 在上面的例子中,foo()bar()协程函数分别打印一些信息,并使用await asyncio.sleep()来模拟协程的执行时间。

什么是aiohttp? 

  • aiohttp是一个用于构建基于Python的异步Web应用程序的库。它是基于Python的asyncio库开发的,为开发者提供了构建高性能、可伸缩、异步Web应用程序的工具。aiohttp提供了HTTP客户端和服务器功能,支持HTTP/1.1和WebSocket协议,并具有请求和响应处理、路由、中间件、模板等功能。通过使用aiohttp,开发者可以轻松地构建基于异步IO的高性能Web应用程序。

 

相关文章:

PYTHON专题-(10)基操之我要玩并发

什么是并发? 并发指的是两个或多个事件在同一时间间隔内发生。在计算机科学中,并发通常指的是一个程序同时执行多个独立的任务。这些任务可以同时进行,而不会相互干扰或阻塞彼此。并发可以提高程序的执行效率和资源利用率,但也需要…...

双指针实现删除字符串中的所有相邻重复项

class Solution:def removeDuplicates(self, s: str) -> str:res list(s)slow fast 0length len(res)while fast < length:# 如果一样直接换&#xff0c;不一样会把后面的填在slow的位置res[slow] res[fast]# 如果发现和前一个一样&#xff0c;就退一格指针if slow …...

vue(vue2和vue3)项目打包去除console.log

1.Vue2去除 module.exports { configureWebpack: (config) > {// 取消console打印config.optimization.minimizer[0].options.terserOptions.compress.drop_console truereturn {name: "项目名称",resolve: {alias: {"": resolve("src")}}…...

Visual Studio 2022社区版、专业版、企业版功能对比表

https://visualstudio.microsoft.com/zh-hans/vs/compare/...

Codeforces 888 div3 A-G

A. Escalator Conversations 分析 二者身高差为k的倍数且不超过m-1倍&#xff0c;身高差不能为0&#xff08;即不能在同一个阶梯&#xff09; C代码 #include<iostream> using namespace std; void solve(){int n,m,k,H,ans0;cin>>n>>m>>k>>H;…...

IDEA如何去掉编辑框右侧的竖线

打开 IntelliJ Idea 软件 依次找到 File—>Settings—>Editor—>General—>Appearance 去掉勾选 Show hard wrap and visual guides (configured in Code Style options)...

3DCoat v2023 激活版下载与安装教程 (数字雕刻程序)

前言 3DCoat 是一款数字雕塑软件&#xff0c;由乌克兰开发。该软件专注于游戏模型的细节设计&#xff0c;集三维模型实时纹理绘制和细节雕刻功能为一身&#xff0c;可以加速细节设计流程&#xff0c;在更短的时间内创造出更多的内容。 一、下载地址 下载链接&#xff1a;分享…...

【Unity/XLua】xlua自带教程示例分析(一)——打印Hello world

第一步 创建Monobehavior脚本 public class Helloworld : MonoBehaviour {void Start(){} }第二步 在类中或Start函数中创建Lua虚拟机环境 LuaEnv luaenv new LuaEnv();第三步 使用LuaEnv的DoString方法直接运行字符串存储的lua语句&#xff08;字符串前使用可强制不进行转义…...

虚拟机(VMware16)安装rocky9.2详细过程,附镜像下载链接

rocky官方站点 链接: 官方站点 rocky9.2镜像下载路径 链接: Rocky-x86_64-dvd.iso 打开虚拟机&#xff0c;选择新建虚拟机 新建虚拟机 选择典型 由于VMware16没有rocky的版本&#xff0c;所以我们这里选择其他liunx 5.x 内核 64位 因为rocky9默认内核版本就是5开头的&#xf…...

C语言新手小白详细教程(6)函数

希望文章能够给到初学的你一些启发&#xff5e; 如果觉得文章对你有帮助的话&#xff0c;点赞 关注 收藏支持一下笔者吧&#xff5e; 阅读指南&#xff1a; 开篇说明为什么要使用函数&#xff1f;1.定义一个函数2.调用函数3.定义函数详解 开篇说明 截止目前&#xff0c;我们已…...

力扣1488.避免洪水泛滥

力扣1488.避免洪水泛滥 贪心 二分 将所有晴天存入集合用哈希表存每次池子上一次下雨的日期当下雨并且池子满了时&#xff0c;二分找到上一次下雨之后最近的晴天 class Solution {unordered_map<int,int> mp;public:vector<int> avoidFlood(vector<int>&a…...

System类、BigDecimal类、Calendar类 用法详解

System类 System 类是Java中的一个核心类&#xff0c;提供了访问与系统相关的一些属性和方法。它包含了一些静态字段和静态方法&#xff0c;用于获取系统的标准输入、标准输出、标准错误流&#xff0c;以及加载动态链接库和系统属性等功能。 常见方法&#xff1a; public stat…...

SQLTools插件下载与使用说明

SQLTools是一个专注于SQL优化与管理的plsql developer插件&#xff0c;目的是把一些常用的SQL收集在一起&#xff0c;方便快速解决问题&#xff0c;提高工作效率。 当在SQL或PACKAGE窗口,或者选中表时&#xff0c;会有两个右键菜单&#xff1a; SQLTools聚焦在SQL方面&#xf…...

【人脸识别】数据集宝藏合集,速看!

本文将为您介绍10个经典、热门的数据集&#xff0c;希望对您在选择适合的数据集时有所帮助。 1 26,090张人脸肤质缺陷采集数据【数据堂】 发布方&#xff1a; 数据堂&#xff08;北京&#xff09;科技股份有限公司 发布时间&#xff1a; 2021 简介&#xff1a; 26,090张人脸…...

mysql操作(进阶)

1.数据库约束 数据库自动对数据的合法性进行校验检查的一系列机制&#xff0c;目的是为了保证数据库中能够避免被插入或者修改一些非法数据。 &#xff08;1&#xff09;mysql中提供了以下的约束&#xff1a; a.NOT NULL&#xff1a;指定某列不能为null b.UNIQUE&#xff1…...

[000-01-025].第07节:WorkBench

我的后端学习大纲 我的Drools学习大纲 8. WorkBench 8.1 WorkBench简介: 1.WorkBench是KIE组件中的元素&#xff0c;也称为KIE-WB&#xff0c;是Drools-WB与JBPM-WB的结合体。它是一个可视化的规则编辑器。WorkBench其实就是一个war包&#xff0c;安装到tomcat中就可以运行。…...

JavaScript - 变量声明(let、const 和其他)

目录 一、引言 1. let 的作用 2. const 的作用 3. let 与 const 的选择 4. let 和 const 的性能 5. var, let, const 的对比 6. 常见误区 二、其他变量定义 1. var 关键字 2. 全局对象属性 3. 使用 IIFE&#xff08;立即调用函数表达式&#xff09; 4. ES6 模块 总结 …...

AC800PEC PC D231 3BHE025541R0101控制模块面价

AC800PEC PC D231 3BHE025541R0101控制模块面价 AC800PEC PC D231 3BHE025541R0101控制模块面价 AC800PEC PC D231 3BHE025541R0101控制模块面价 AC800PEC PC D231 3BHE025541R0101控制模块引脚线 AC800PEC PC D231 3BHE025541R0101控制模块说明书 AC800PEC PC D231 3BHE0…...

2024年3款免费录屏软件,你的电脑桌面上缺哪一个?

现在&#xff0c;不管是上网课、在家工作&#xff0c;还是拍视频&#xff0c;录屏软件都变得越来越重要了。想做个教学视频、录个操作指南&#xff0c;或者录个游戏的高光时刻&#xff0c;好的录屏软件都能帮你轻松搞定。这篇文章就是要聊聊免费录屏软件一般都有啥功能&#xf…...

Python爬虫新手指南及简单实战

网络爬虫是自动化获取网络信息的高效工具&#xff0c;Python因其强大的库支持和简洁的语法成为编写网络爬虫的首选语言。本教程将通过一个具体的案例&#xff08;基于Microsoft Edge浏览器的简单爬取&#xff09;&#xff0c;指导你使用Python实现一个完整的网络爬虫&#xff0…...

如何有效开展产业链招商?

产业链招商是一种以产业大数据为依托、以产业链图谱为基础、以产业链分析为核心、以完善产业链结构为目标的招商引资方式。相比于传统招商模式&#xff0c;产业链招商比拼的并不是土地、政策优惠&#xff0c;而是以产业链分析为核心&#xff0c;诊断区域产业链结构及长短板&…...

爬虫中使用多进程、多线程的混合方式遇到的数据丢失问题

项目场景&#xff1a; 网络爬虫项目&#xff0c;主要实现多进程、多线程方式快速缓存网页资源到MongoDB&#xff0c;并解析网页数据&#xff0c;将信息写入到csv文件中。 问题描述 在单独使用多线程的过程中&#xff0c;是没有问题的&#xff0c;比如这个爬虫示例是爬取豆瓣电…...

多云应用安全平台RegData利用MongoDB简化数据控制和合规流程

在高度规范化市场中&#xff0c;为了保障数据安全&#xff0c;企业可能需要部署一系列繁琐且成本高昂的IT基础设施系统。随着各项数据安全保护措施的出台&#xff0c;企业需要遵守的法规数量越多&#xff0c;尤其是跨越多个地域的企业&#xff0c;其IT基础设施就会越复杂。如今…...

VUE实现TAB切换不同页面

VUE实现TAB切换不同页面 实现效果 资源准备 ReceiveOrderList, TodoListMulti, SignList 这三个页面就是需要切换的页面 首页代码 <template><div><el-tabs v-model"activeTab" type"card" tab-click"handleTabClick"><…...

C++ 80行 极简扫雷

一共5346个字符&#xff0c;MinGW编译通过&#xff08;强烈不建议写这种代码&#xff01;&#xff01;&#xff01;&#xff09; 压行规则&#xff1a;一行不超过80个字符 代码&#xff1a; #include<windows.h> #include<stdio.h> #include<time.h> #def…...

常见VPS服务器附加组件一览

网络主机行业竞争非常激烈&#xff0c;因此主机服务提供商竭尽全力为客户提供完整的解决方案&#xff0c;其中包含构建和管理在线项目所需的一切。但客户通常有特定需求&#xff0c;因此需要不同的附加组件。在管理自己的网络服务器时尤其如此。 今天&#xff0c;我们将介绍您…...

Electron 使用Electron-build 进行打包

看完下面两篇就可以完成&#xff01; 基于vue3vite的web项目改为Electron桌面应用&#xff08;一&#xff09;_vue3转electron-CSDN博客 将web项目打包成electron桌面端教程&#xff08;二&#xff09;vue3vitets_vue3 打包桌面端-CSDN博客 打包报错 1. 首先确定依赖包 npm …...

Springboot+Websocket+Security+Vue 实现弹幕推送功能

后端部分 (Spring Boot) 1. 创建一个 Spring Boot 项目 创建一个新的 Spring Boot 项目并添加以下依赖&#xff1a; <dependencies><!-- Spring Boot Starter Web --><dependency><groupId>org.springframework.boot</groupId><artifactId…...

LangChain之网络爬虫

网络爬虫 概述 网络爬虫是LangChain中的一项关键功能&#xff0c;允许用户自动从互联网上收集信息。这项功能对于研究和数据收集尤其有价值&#xff0c;因为它可以大幅减少手动搜索和信息整理的工作量。 从网络收集内容有几个主要组件&#xff1a; Search搜索&#xff1a;使用…...

VueRouter 相关信息

VueRouter 是Vue.js官方路由插件&#xff0c;与Vue.js深度集成&#xff0c;用于构建单页面应用。构建的单页面是基于路由和组件&#xff0c;路由设定访问路径&#xff0c;将路径与组件进行映射。VueRouter有两中模式 &#xff1a;hash 和 history &#xff0c;默认是hash模式。…...