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

探索Python编程的技巧:多线程魔法、网络舞台、正则魔法阵与递归迷宫

一 多线程

1.1 进程和线程

  • 进程: 就是一个程序,运行在系统之上,称这个程序为一个运行进程,并分配进程ID方便系统管理。
  • 线程:线程是归属于进程的,一个进程可以开启多个线程,执行不同的工作,是进程的实际工作最小单位。
  • 操作系统中可以运行多个进程,即多任务运行
  • 一个进程内可以运行多个线程,即多线程运行

  • 进程之间是内存隔离的, 即不同的进程拥有各自的内存空间。
  • 线程之间是内存共享的,线程是属于进程的,一个进程内的多个线程之间是共享这个进程所拥有的内存空间的。
    在这里插入图片描述

1.2 并行、并发执行概念

  • 在Python中,多线程用于实现并行和并发执行任务。虽然多线程可以让你同时执行多个任务,但由于Python的全局解释锁(Global Interpreter Lock,GIL)的存在,多线程并不能实现真正的多核并行。然而,多线程仍然可以用于执行I/O密集型任务,因为在这些任务中,线程可能会在等待I/O操作完成时释放GIL,从而允许其他线程运行。

  • 并行执行:

    • 并行执行是指多个任务在同一时刻同时运行,各自独立地占用一个CPU核心。
    • 在Python中,由于GIL的存在,多线程并不适合用于CPU密集型任务的并行执行。
    • 多个进程同时在运行,即不同的程序同时运行,称之为:多任务并行执行
    • 一个进程内的多个线程同时在运行,称之为:多线程并行执行
  • 并发执行:

    • 并发执行是指多个任务交替执行通过快速切换执行任务的上下文来实现“同时”执行的错觉。
    • 这在处理I/O密集型任务时非常有效,因为线程可能会在等待I/O完成时让出CPU资源给其他线程。

1.3 多线程编程

  • 在Python中,可以使用threading模块来创建和管理多线程。

  • threading.Thread类可以创建一个线程对象,用于执行特定的任务函数。

  • threading.Thread类的一般语法和一些常用参数:

    thread_obj = threading.Thread(target=function_name, args=(), kwargs={}, daemon=False)
    # 启动线程
    thread_obj.start() 
    
  • target: 必需的参数用于指定线程要执行的函数(任务)。函数会在新线程中运行。

  • args: 可选参数用于传递给目标函数的位置参数,以元组形式提供。如果函数不需要参数,可以传递一个空元组或省略这个参数。

  • kwargs: 可选参数用于传递给目标函数的关键字参数,以字典形式提供。如果函数不需要关键字参数,可以传递一个空字典或省略这个参数。

  • daemon: 可选参数,布尔值,用于指定线程是否为守护线程。守护线程会在主线程结束时被终止,而非守护线程会等待所有线程完成后再终止。

  • 使用threading.Thread类创建线程对象并启动线程

import threading
import timedef print_numbers():for i in range(1, 6):print(f"Number: {i}")time.sleep(1)def print_letters():for letter in ['a', 'b', 'c', 'd', 'e']:print(f"Letter: {letter}")time.sleep(1)if __name__ == "__main__":thread1 = threading.Thread(target=print_numbers)thread2 = threading.Thread(target=print_letters)thread1.start()  # Start the first threadthread2.start()  # Start the second threadthread1.join()   # 用于阻塞当前线程,直到被调用的线程完成其执行thread2.join()   # 用于阻塞当前线程,直到被调用的线程完成其执行print("All threads completed")
  • 在这个示例中,创建了两个线程对象,每个线程对象都关联一个不同的任务函数(print_numbersprint_letters)。然后启动这两个线程,并等待它们完成。最后,我们输出一个提示,表示所有线程都已完成。

  • thread1thread2 是两个线程对象,而 thread1.join()thread2.join() 是在主线程中调用的。当调用这些方法时,主线程会阻塞,直到对应的线程(thread1thread2)完成了它们的执行。

  • thread1.join()thread2.join() 语句确保在两个子线程执行完成后,主线程才会输出 “All threads completed” 这条消息。如果不使用 join(),主线程可能会在子线程还没有完成时就继续执行,导致输出消息的时机不确定。

1.4 补充:join()方法

  • 在多线程编程中,join() 方法用于阻塞当前线程,直到被调用的线程完成其执行。具体来说,thread1.join() 表示当前线程(通常是主线程)会等待 thread1 线程完成后再继续执行。

  • 这种等待的机制可以确保主线程在所有子线程执行完成后再继续执行,从而避免可能出现的线程之间的竞争条件和不确定性。这在需要等待所有线程完成后进行进一步操作或获取线程执行结果时非常有用。

1.5 并行、并发实现演示

  • 并行执行多个任务演示:
import threadingdef task1():print("Task 1 started")# ... some code ...print("Task 1 finished")def task2():print("Task 2 started")# ... some code ...print("Task 2 finished")if __name__ == "__main__":thread1 = threading.Thread(target=task1)thread2 = threading.Thread(target=task2)thread1.start()thread2.start()thread1.join()thread2.join()print("All tasks completed")

  • 并发执行演示:
import threading
import timedef task1():print("Task 1 started")time.sleep(2)  # Simulate I/O operationprint("Task 1 finished")def task2():print("Task 2 started")time.sleep(1)  # Simulate I/O operationprint("Task 2 finished")if __name__ == "__main__":thread1 = threading.Thread(target=task1)thread2 = threading.Thread(target=task2)thread1.start()thread2.start()thread1.join()thread2.join()print("All tasks completed")

1.6 Thread参数传递使用演示

  • 当使用threading.Thread创建线程对象时,可以通过argskwargsdaemon参数传递不同类型的信息给线程。
  • 以下是针对每种参数的示例:
  1. 使用 args 参数传递位置参数:
import threadingdef print_numbers(start, end):for i in range(start, end + 1):print(f"Number: {i}")if __name__ == "__main__":thread1 = threading.Thread(target=print_numbers, args=(1, 5))thread2 = threading.Thread(target=print_numbers, args=(6, 10))thread1.start()thread2.start()thread1.join()thread2.join()print("All threads completed")
  1. 使用 kwargs 参数传递关键字参数:
import threadingdef greet(name, message):print(f"Hello, {name}! {message}")if __name__ == "__main__":thread1 = threading.Thread(target=greet, kwargs={"name": "Alice", "message": "How are you?"})thread2 = threading.Thread(target=greet, kwargs={"name": "Bob", "message": "Nice to meet you!"})thread1.start()thread2.start()thread1.join()thread2.join()print("All threads completed")
  1. 使用 daemon 参数设置守护线程:
import threading
import timedef count_seconds():for i in range(5):print(f"Elapsed: {i} seconds")time.sleep(1)if __name__ == "__main__":thread = threading.Thread(target=count_seconds)thread.daemon = True  # 设置线程为守护线程thread.start()# No need to join daemon threads, they will be terminated when the main thread endsprint("Main thread completed")
  • 将线程 thread 设置为守护线程(daemon = True)。这意味着当主线程结束时,守护线程也会被终止,而无需使用 join() 等待它完成。

二 网络编程

2.1 Socket初识

  • Python的套接字(Socket)编程是一种基本的网络编程技术,它可以在网络上建立连接并进行数据传输。
  • socket (简称 套接字) 是进程之间通信一个工具,进程之间想要进行网络通信需要socket。Socket负责进程之间的网络数据传输,是数据的搬运工。
    在这里插入图片描述

2.2 客户端和服务端

  • 2个进程之间通过Socket进行相互通讯,就必须有服务端和客户端
    • Socket服务端:等待其它进程的连接、可接受发来的消息、可以回复消息
    • Socket客户端:主动连接服务端、可以发送消息、可以接收回复
      在这里插入图片描述

2.3 创建socket对象详解

  • 在创建套接字对象时,通常是可以不指定参数的。如果没有指定参数,将会使用默认的参数,这些参数在 socket 模块中预先定义。默认情况下,socket 函数将创建一个 IPv4 的流式套接字。

  • 例如,以下代码将创建一个默认的 IPv4 TCP 套接字:

    import socket# 创建一个默认的 IPv4 TCP 套接字
    default_socket = socket.socket()# 后续代码中可以使用 default_socket 进行操作
    
  • 这种方式在很多情况下都是适用的,特别是当你只需要一个简单的 IPv4 TCP 套接字时。

    socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    
    1. socket:Python 的内置套接字模块,它提供了在网络上进行通信的基本功能。
    2. socket.AF_INET:表示套接字地址簇(Address Family),用于指定套接字使用的地址类型。AF_INET 表示使用 IPv4 地址。还可以使用 AF_INET6 来表示 IPv6 地址。
    3. socket.SOCK_STREAM:表示套接字的类型。SOCK_STREAM 表示这是一个流式套接字,它基于 TCP 协议提供了可靠的、面向连接的、双向的数据流传输。
  • 综合起来,socket.socket(socket.AF_INET, socket.SOCK_STREAM) 创建了一个基于 IPv4 地址和 TCP 协议的流式套接字对象,你可以使用这个套接字对象来建立连接、发送和接收数据。

  • 如果需要创建基于 UDP 协议的套接字,可以使用 socket.SOCK_DGRAM,例如:

    udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    

2.4 accept()方法详解

  • accept() 方法是在服务器端套接字上调用的方法,用于接受客户端的连接请求。它会阻塞程序,直到有客户端尝试连接到服务器,然后返回一个新的套接字用于与该客户端进行通信,以及客户端的地址信息。

    client_socket, client_address = server_socket.accept()
    
    • accept():接受客户端的连接请求。当调用这个方法时,它会阻塞程序,直到有客户端连接到服务器。一旦有连接请求到达,该方法将返回两个值:一个是表示与客户端通信的新套接字对象,另一个是客户端的地址信息。
    • client_socket新创建的套接字对象,用于与连接的客户端进行通信(可以使用这个套接字来接收和发送数据)
    • client_address:元组类型,包含客户端的 IP 地址和端口号。例如,('192.168.1.100', 54321)
  • 一般来说,服务器在一个循环中使用 accept() 方法,以便能够接受多个客户端的连接。每当有新的客户端连接到服务器时,accept() 方法会返回一个新的套接字和客户端的地址,然后服务器可以将新套接字添加到连接池,与客户端进行通信。

  • 注意:accept() 方法在没有连接请求时会一直阻塞程序。如果你希望设置超时或者非阻塞的连接等待,你可以在创建服务器套接字后设置相应的选项。这样,在没有连接请求时调用 accept() 方法将立即返回,不会阻塞程序的执行。

  • 例如,在创建服务器套接字后可以使用以下代码将其设置为非阻塞模式:

    server_socket.setblocking(False)
    

2.5 发送信息方法详解

  • send() 方法和 sendall() 方法都用于在套接字上发送数据,但它们有一些不同之处。

send(data) 方法:

  • send() 方法是用于发送数据的基本方法,它接受一个字节流(bytes)作为参数,并尝试将数据发送到连接的对方。
  • 如果成功发送全部数据,该方法将返回发送的字节数。如果没有发送完全部数据,可能返回一个小于请求发送数据的字节数。
  • 如果在发送过程中出现问题(例如连接中断),send() 方法可能会引发异常。

sendall(data) 方法:

  • sendall() 方法也用于发送数据,但它更加健壮,会自动处理数据分片和重试。

  • 无论数据有多大,sendall() 方法会尽力将所有数据都发送出去,直到全部数据都被发送成功或发生错误。

  • 方法不会立即返回,而是在所有数据都发送成功后才返回 None。如果发生错误,它可能引发异常。

  • sendall() 方法在发送数据时会自动处理数据的分片,确保数据都被正确发送。

  • 在大多数情况下,如果想要简单地发送一小段数据,可以使用 send() 方法。然而,如果需要发送大量数据或者确保数据被完整、可靠地发送,那么使用 sendall() 方法会更好,因为它会自动处理数据分片和错误处理。

  • 使用 send() 方法:

    client_socket.send(b"Hello, server!")
    
  • 使用 sendall() 方法:

    data = b"Hello, server!"
    client_socket.sendall(data)
    

2.6 Socket编程演示

  • 服务器端代码:

    import socket# 1. 创建Socket对象
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)# 2. 绑定服务器地址和端口
    server_address = ('127.0.0.1', 12345)
    server_socket.bind(server_address)# 3. 开始监听端口 backlog=5 标识允许的连接数量,超出的会等待,可以不填,不填自动设置一个合理的值
    server_socket.listen(5)print("Waiting for a connection...")
    # 4. 接收客户端连接,获得连接对象
    client_socket, client_address = server_socket.accept()
    print(f"Connected to {client_address}")# 5. 客户端连接后,通过recv方法 接收并发送数据
    while True:data = client_socket.recv(1024).decode('utf-8')# recv接受的参数是缓冲区大小,一般给1024即可# recv方法的返回值是一个字节数组也就是bytes对象,不是字符串,可以通过decode方法通过UTF-8编码,将字节数组转换为字符串对象if not data:breakprint(f"Received: {data}")# 6. 通过client_socket对象(客户端再次连接对象),调用方法,发送回复消息msg = input("请输入你要和客户端回复的消息:")if msg == 'exit':breakclient_socket.sendall(msg.eccode("UTF-8"))# 7.关闭连接
    client_socket.close()
    server_socket.close()
    

  • 客户端代码:
    import socket# 1.创建socket对象
    client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)# 2.连接服务器地址和端口
    server_address = ('127.0.0.1', 12345)
    client_socket.connect(server_address)# 3.发送数据
    while True:# 发送消息msg = input("请输入要给服务端发送的消息:")if msg == 'exit':breakclient_socket.sendall(msg.encode("UTF-8"))# 4.接收返回消息recv_data = client_socket.recv(1024)  # 1024是缓冲区的大小,一般1024即可。 同样recv方法是阻塞的      print(f"服务端回复的消息是:{recv_data.decode('UTF-8')}")# 5.关闭连接
    client_socket.close()
    

三 正则表达式

3.1 正则表达式概述

  • 正则表达式,又称规则表达式(Regular Expression),是使用单个字符串来描述、匹配某个句法规则的字符串,常被用来检索、替换那些符合某个模式(规则)的文本。
  • 正则表达式就是使用:字符串定义规则,并通过规则去验证字符串是否匹配。
  • 比如,验证一个字符串是否是符合条件的电子邮箱地址,只需要配置好正则规则,即可匹配任意邮箱。通过正则规则: (^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$) 即可匹配一个字符串是否是标准邮箱格式

3.2 Python正则表达式使用步骤

  • 使用正则表达式的一些基本步骤和示例:
  1. 导入re模块:
import re
  1. 使用re.compile()编译正则表达式:
# `pattern_here`应该替换为实际正则表达式
pattern = re.compile(r'pattern_here')
  1. 使用编译后的正则表达式进行匹配:
text = "This is an example text for pattern matching."
result = pattern.search(text)
if result:print("Pattern found:", result.group())
else:print("Pattern not found.")

3.3 正则的基础方法

  • Python正则表达式,使用re模块,并基于re模块中基础方法来做正则匹配。

  • 匹配(Match):使用match()来从字符串的开头开始匹配。匹配成功返回匹配对象(包含匹配的信息),匹配不成功返回空

result = pattern.match(text)
  • 搜索(Search):使用search()来查找文本中的第一个匹配项。整个字符串都找不到,返回None
result = pattern.search(text)
  • 查找所有(Find All):使用findall()来找到所有匹配项,并返回一个列表。找不到返回空list: []
results = pattern.findall(text)
  • 替换(Replace):使用sub()来替换匹配项。
# `replacement`应该是希望替换匹配项的内容
new_text = pattern.sub(replacement, text)
  • 分割(Split):使用split()来根据匹配项分割字符串。
parts = pattern.split(text)
  • 在正则表达式中,你可以使用不同的元字符(例如.*+?[]()等)来构建复杂的模式,以便进行更精确的匹配。

  • 演示使用正则表达式从文本中提取所有的电子邮件地址

import retext = "Contact us at: john@example.com or jane@example.org for more information."pattern = re.compile(r'\b[\w.-]+@[\w.-]+\.\w+\b')
email_addresses = pattern.findall(text)for email in email_addresses:print(email)

3.4 元字符匹配

  • 单字符匹配
    在这里插入图片描述
    示例:
    字符串 s = "itheima1 @@python2 !!666 ##itcast3"
  • 找出全部数字: re.findall(r '\d', s)
  • 字符串的r标记,表示当前字符串是原始字符串,即内部的转义字符无效而是普通字符
  • 找出特殊字符: re.findall(r '\W', s)
  • 找出全部英文字母:re.findall(r '[a-zA-Z]', s)
  • []内可以写:[a-zA-Z0-9] 这三种范围组合或指定单个字符如[aceDFG135]

  • 数量匹配
    在这里插入图片描述
  • 边界匹配
    在这里插入图片描述
  • 分组匹配
    在这里插入图片描述

四 递归

  • 递归是一种编程技术(算法),即方法(函数)自己调用自己的一种特殊编程写法。在Python中,可以使用递归来解决许多问题,特别是那些可以被分解为相同或类似子问题的问题。
    在这里插入图片描述

  • 在使用递归时,需要确保定义递归基(base case),这是递归结束的条件,以避免无限循环。每次递归调用都应该将问题规模减小,使其朝着递归基的条件靠近。

  • 使用递归计算阶乘:

    def factorial(n):if n == 0:return 1  # 递归基else:return n * factorial(n - 1)  # 递归调用num = 5
    result = factorial(num)
    print(f"The factorial of {num} is {result}")
    
    • factorial 函数通过不断地调用自身来计算阶乘。当 n 达到递归基条件 n == 0 时,递归结束,不再调用自身。
  • 然而,递归并不总是最有效的解决方法,因为它可能会导致函数调用的嵌套层数过深,从而消耗大量的内存和处理时间。在一些情况下,使用循环或其他方法可能更有效。

  • 在编写递归函数时,要确保递归调用朝着递归基靠近,避免陷入无限循环,同时考虑性能方面的问题。

相关文章:

探索Python编程的技巧:多线程魔法、网络舞台、正则魔法阵与递归迷宫

一 多线程 1.1 进程和线程 进程: 就是一个程序,运行在系统之上,称这个程序为一个运行进程,并分配进程ID方便系统管理。线程:线程是归属于进程的,一个进程可以开启多个线程,执行不同的工作&…...

uniapp-微信小程序篇

uniapp-微信小程序篇 一、创建项目(以Vue3TS 项目为示例) 可以通过命令行的方式创建也可以通过HBuilderX进行创建(通过HBuilderX创建的项目建议选择最简单的模板),个人建议使用命令行方式。 (1) 命令行方式: npx degit dcloudio…...

使用pymupdf实现PDF内容搜索并显示功能

简介: 在日常工作和学习中,我们可能需要查找和提取PDF文件中的特定内容。本文将介绍如何使用Python编程语言和wxPython图形用户界面库来实现一个简单的PDF内容搜索工具。我们将使用PyMuPDF模块来处理PDF文件,并结合wxPython构建一个用户友好的…...

Dalsa线阵相机说明(Linea Color GigESeries 2k and 4K)

文章目录 一. Dalsa相机软件整体架构二. 相机编号说明以及软件要求三. 相机硬件参数三. 相机基本参数四. 软件参数设置列表1. Sensor Control Category2. I/O Control Category3. Counter and Timer Control Category4. Advanced Processing Control Category(1) 平场校正介绍(…...

图神经网络 day2 图的分类

图神经网络基础算法 1 GCN2 GraphSAGE2.1 采样:采样固定长度的邻居2.2 聚合2.3 GraphSAGE_minibatch2.4 GraphSAGE_embedding 3 GAT4. 图网络的分类4.1 递归图神经网络 RGNN4.2 图卷积神经网络GCN4.3 图注意力网络 GAT4.4 图自动编码 GAE4.5 图时空网络 GSTN4.6 图生…...

CentOS防火墙操作:开启端口、开启、关闭、配置

一、基本使用 启动: systemctl start firewalld 关闭: systemctl stop firewalld 查看状态: systemctl status firewalld 开机禁用 : systemctl disable firewalld 开机启用 : systemctl enable firewalld systemctl是…...

Chromium 如何在c++里面控制扩展加载

扩展安装 主要是通过UserMayLoad 函数控制,true允许加载,否则禁用 引自chromiun参考。【一般可以根据扩展ID禁用】 chrome\browser\extensions\standard_management_policy_provider.cc bool StandardManagementPolicyProvider::UserMayLoad( const Ext…...

分类预测 | MATLAB实现MTBO-CNN多输入分类预测

分类预测 | MATLAB实现MTBO-CNN多输入分类预测 目录 分类预测 | MATLAB实现MTBO-CNN多输入分类预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 1.MATLAB实现MTBO-CNN多输入分类预测 2.代码说明:基于登山队优化算法(MTBO)、卷积神经…...

操作符和表达式求值

目录 1.运算符的优先级和结合性 1.1运算符的优先级 1.2结合性 2.操作符的使用最终带来的是一个表达式的值 2.1.隐式类型转换(整型提升) 2.1.1整形提升的例子 2.2算术转换 1.运算符的优先级和结合性 运算符是编程语言中的基本元素之一,主…...

Unity Spine帧事件

SpinePro中添加事件帧 首先 选中右上角的层级树 然后选择事件选项 最后在右下角看到 新建 点击它 新建一个事件 点击左上角的设置按钮 弹出编辑窗口 编辑窗口 在右上角 动画栏 可以切换对应的动画 点坐边的那个小灰点来切换 亮点代表当前动画 选中帧 添加事件 点击对应事件…...

AE使用(一)

打开AE 点击“新建合成” 注意参数:宽度高度是视频是横屏还是竖屏。发布在抖音上,需要做出来竖屏效果;发布在视频网站中需要做出横屏效果。没用特殊需求,默认参数就行。 导入素材:左键双击“导入素材区”的空白部分。 …...

YOLOv5、YOLOv8改进:MobileViT:轻量通用且适合移动端的视觉Transformer

MobileViT: Light-weight, General-purpose, and Mobile-friendly Vision Transformer 论文:https://arxiv.org/abs/2110.02178 1简介 MobileviT是一个用于移动设备的轻量级通用可视化Transformer,据作者介绍,这是第一次基于轻量级CNN网络性…...

06-4_Qt 5.9 C++开发指南_MDI应用程序设计

文章目录 1. MDI简介2. 文档窗口类 QFormDoc 的设计3. MDI主窗口设计与子窗口的使用3.1 主窗口界面设计3.2 MDI子窗口的创建与加入3.3 QMdiArea 常用功能函数3.4 MDI的信号 4. 源码4.1 qwmainwindow.h4.2 qwmainwindow.cpp 1. MDI简介 传统的应用程序设计中有多文档界面(Multi…...

【SCI征稿】3区SCI,正刊,智能传感、机器学习、智能检测与测量等均可

影响因子:IF:2.0-3.0 期刊分区:JCR3区,中科院4区 检索情况:SCIE在检,正刊 征稿领域:智能技术在测量与检测中的应用研究,如: ● 复杂系统的智能传感和高级故障诊断 ●…...

神经网络ANN(MLP),CNN以及RNN区别和应用

1. Artificial Neural Network(ANN) 又称为Multilayer Perception Model(MLP) 2. CNN AAA 3. RNN 22 先占坑,后期再整理 References [1] CNN vs.RNN vs.ANN——浅析深度学习中的三种神经网络 - 知乎 [2] https://www.youtube.com/watch?vu7obuspdQu4 [3] 深…...

CUDA、cuDNN以及Pytorch介绍

文章目录 前言一、CUDA二、cuDNN三、Pytorch 前言 在讲解cuda和cuDNN之前,我们首先来了解一下英伟达(NVIDA)公司。 NVIDIA是一家全球领先的计算机技术公司,专注于图形处理器(GPU)和人工智能(…...

使用shift关键字,写一个带二级命令的脚本(如:docker run -a -b -c中的run)

省流:shift关键字 探索思路 最近有一个小小的需求,写一个类似于docker run -a -b -c这样的脚本,这个脚本名为doline,它本身可以执行(doline -a -b -c),同时又带有几个如run、init、start这样的…...

MySQL学习笔记 - 进阶部分

MySQL进阶部分 字符集的相关操作:字符集和比较规则:utf8与utf8mb4:比较规则:常见的字符集和对应的Maxlen: Centos7中linux下配置字符集:各个级别的字符集:执行show variables like %character%语…...

微信小程序实现左滑删除

一、效果 二、代码 实现思路使用的是官方提供的 movable-area:注意点,需要设置其高度,否则会出现列表内容重叠的现象。由于movable-view需要向右移动,左滑的时候给删除控件展示的空间,故 movable-area 需要左移 left:…...

安防视频监控有哪些存储方式?哪种存储方式最优?

视频监控系统涉及到大量的视频数据,需要对这些数据进行存储,以备日后查看或备份。视频监控的存储需求需要根据场所的实际情况进行选择,以保证监控数据的有效存储和日后的调阅、回溯。 当前视频监控的存储方式,通常有以下几种&…...

OpenLayers 可视化之热力图

注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 热力图(Heatmap)又叫热点图,是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...

反向工程与模型迁移:打造未来商品详情API的可持续创新体系

在电商行业蓬勃发展的当下,商品详情API作为连接电商平台与开发者、商家及用户的关键纽带,其重要性日益凸显。传统商品详情API主要聚焦于商品基本信息(如名称、价格、库存等)的获取与展示,已难以满足市场对个性化、智能…...

SCAU期末笔记 - 数据分析与数据挖掘题库解析

这门怎么题库答案不全啊日 来简单学一下子来 一、选择题(可多选) 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘:专注于发现数据中…...

Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!

一、引言 在数据驱动的背景下,知识图谱凭借其高效的信息组织能力,正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合,探讨知识图谱开发的实现细节,帮助读者掌握该技术栈在实际项目中的落地方法。 …...

CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云

目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...

Caliper 配置文件解析:config.yaml

Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...

JVM 内存结构 详解

内存结构 运行时数据区: Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器: ​ 线程私有,程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 ​ 每个线程都有一个程序计数…...

Java求职者面试指南:计算机基础与源码原理深度解析

Java求职者面试指南:计算机基础与源码原理深度解析 第一轮提问:基础概念问题 1. 请解释什么是进程和线程的区别? 面试官:进程是程序的一次执行过程,是系统进行资源分配和调度的基本单位;而线程是进程中的…...

解读《网络安全法》最新修订,把握网络安全新趋势

《网络安全法》自2017年施行以来,在维护网络空间安全方面发挥了重要作用。但随着网络环境的日益复杂,网络攻击、数据泄露等事件频发,现行法律已难以完全适应新的风险挑战。 2025年3月28日,国家网信办会同相关部门起草了《网络安全…...

前端调试HTTP状态码

1xx(信息类状态码) 这类状态码表示临时响应,需要客户端继续处理请求。 100 Continue 服务器已收到请求的初始部分,客户端应继续发送剩余部分。 2xx(成功类状态码) 表示请求已成功被服务器接收、理解并处…...