Python运维-文本处理、系统和文件信息监控、外部命令

本节主要目录如下:

一、文本处理

1.1、Python编码解码

1.2、文件操作

1.3、读写配置文件

1.4、解析XML文件

二、系统信息监控

2.1、监控CPU信息

2.2、监控内存信息

2.3、监控磁盘信息

2.4、监控网络信息

2.5、获取进程信息

2.6、实例:常见的实用方法

三、文件系统监控

3.1、实例

四、执行外部命令subprocess

4.1、subprocess.run()方法*

4.2、Popen类

4.3、其他方法


一、文本处理

日常运维工作都离不开文本,如日志分析、编码转换、ETL加工等。

1.1、Python编码解码

  • 计算机只处理二进制数据,如果要处理文本,就需要将文本转换为二进制数据,再由计算机进行处理
  • 文本转换为二进制数据就是编码,将二进制数据转换为文本就是解码
  • 编码和解码要按一定的规则进行,这个规则就是字符集

常见的中文编码

  • GB2312GB2312-80是中国国家标准简体中文字符集,共收录6763个汉字,同时收录了包括拉丁字母、希腊字母。日文平假名字母、俄语西里尔字母在内的682个字符
  • GBK即汉字内码扩展规范,共收入21886个汉字和图形符号
  • GB8030与GB2312-1980和GBK兼容,共收录汉字70244个,是一二四字节变长编码

可看出支持的汉字范围:GB18030>GBK>GB2312

世界所有语言统一到一套编码中,这套编码就是Unicode编码。Unicode编码使用两个字节(16位bit)表示一个字符,比较偏僻的字符需要使用4个字节。

几乎所有的系统、编程语言都默认支持Unicode。如果一段纯英文文本,Unicode会占用比ASCII码多一倍的空间!UTF编码将一个Unicode字符编码成1-6个字节,常用的英文字母被编译成1个字节,汉字通常是3个字节,只有很生僻的字符才会被编码成4-6个字节。UTF编码有三种:

  • UTF-8:使用1、2、3、4个字节表示所有符号,优先使用1个字节,若无法满足,则增加一个字节,最多4个字节 。英文占1个字节、欧洲语系占2个字节、东亚占3个字节,其他特殊字符占4个字节。
  • UTF-16:使用2、4个字节表示所有符号,优先使用2个字节,否则使用4个字节表示。
  • UTF-32:使用4个字节表示所有字符。

 # 汉字的“汉”,在UTF-8字符集中3个字节list("汉".encode("UTF-8"))# [230, 177, 137]

而英文无论采用哪种编码,都是一致的。如果使用纯英文编写代码,就基本不会遇到编码问题:

 print(list("a".encode("ascii")))# [97]print(list("a".encode("gbk")))# [97]print(list("a".encode("utf-8")))# [97]

Python语言的with...as...用

 with open("a.txt") as file:data = file.read()

默认编码可以通过sys.getdefaultencoding()来查看Python解释器会用的默认编码

 import sysprint(sys.getdefaultencoding())# utf-8

说明电脑上Python解释器默认使用的是UTF-8编码,如果不指定Python解释器以何种编码解码,则默认以UTF-8方式解码源文件,因此在保存代码源文件时确保以UTF-8编码保存。

1.2、文件操作

1.2.1、普通文件操作

Python文件操作只需要一个open函数返回一个文件句柄,无需导入任何模块。

 f=open("a.txt")     # 打开文件,得到一个文件句柄,并赋值给一个变量print(f.read())     # 打印读取文件的内容 f.close()           # 关闭文件

oepn函数:

 open(file, mode='r', buffering=None, encoding=None, errors=None, newline=None, closefd=True, opener=None)

  • 参数file是一个文件名称的字符串,如果文件不在程序当前的路径下,就需要在前面加上相对路径或绝对路径
  • 参数mode是一个可选参数,指示打开文件的方式,若不指定,则默认以读文本的方式打开文件:

    字符串含义
    'r'的方式打开(默认)
    'w'的方式打开文件,会先清空文件
    'X'创建一个新文件,以写方式打开
    'a'以写的方式打开文件,如果文件已存在,就在文件最后位置追加内容
    'b'以二进制方式打开,可以和读写命令共用
    't'以文本方式(默认)
    '+'以读和写方式打开文件,用于更新文件
    'U'通用的换行模式(弃用)
  • buffering是一个可选的参数,buffering=0表示关闭缓冲区(仅在二进制方式打开可用),buffering=1表示选择缓冲区(仅在文本方式打开时可用);buffering大于1时,其值代表固定大小的块缓冲区的大小。当不指定该参数时:二进制文件使用固定大小的块缓冲区,文本文件使用行缓冲区。

注意:

  • 记得使用完毕后及时关闭文件,释放资源。推荐傻瓜式操作方式:使用with关键字来帮我们管理上下文,系统会自动为我们关闭文件和处理异常

     with open('a.txt','w') as f:f.write("hello world")
  • open()函数是操作系统打开文件,如果没有指定编码,那么以操作系统默认编码打开;Windos下是gbk,在Linux下使utf-8。

常见的文件操作方法:

名称功能
f.read()读取所有内容,光标移动到文件末尾
f.readline()读取一行内容,光标移动到第二行首部
f.readlines()读取每一行内容,存于列表中
f.write('1111\n222\n')针对文本模式的写,需要自己写换行符
f.write('1111\n222\n'.encode('utf-8'))针对b模式的写,需要自己写换行符
f.writelines(['333\n','444\n'])文件模式
f.write([bytes('333\n',encoding='utf-8'),'444\n'.encode('utf-8')])b模式
f.readable()文件是否可读
f.writable()文件是否可写
f.closed文件是否关闭
f.encoding如果文件打开模式为b,则没有该属性
f.flush()立刻将文件内容从内存刷到硬盘

读取文件内位置的定位方法:

  • 通过read方法传输参数
  • 以字节为单位定位,如seek、tell等。
    • seek(x,0)表示从起始位置即文件首行首字符开始移动x个字符。
    • seek(x,1)表示从当前位置向后移动x个字符.
    • seek(-x,2)表示从文件的结尾向前移动x个字符。

# 基于seek实现类似Linux命令tail-f的功能import timewith open('tmp.txt','rb') as f:f.seek(0,2)         # 将光标移动至文件末尾while True:         # 实时显示文件新增加的内容line = f.read()if line:print(line.decode('utf-8'),end='')else:time.sleep(0,2) # 读取完毕后短暂的睡眠# 当tmp.txt追加新的内容时,新内容会被程序立即打印出来

1.2.2、大文件的读取

当文件较小时,我们可以一次性全部读入内存,对文件的内容做出任意修改,再保存至磁盘:

with open('a.txt') as read_f,open('.a.txt.swap','w') as write_f:data = read_f.read()	# 全部读入内存,如果文件很大,则会很卡data = data.replace('str1','str2')	# 在内存中完成修改write_f.write(data)	# 一次性写入新文件
os.remove('a.txt')
os.rename('.a.txt.swap','a.txt')

当文件很大时,如GB级的文本文件,我们需要用文件的可迭代方式将文件的内容逐行读入内存,在逐行写入新文件,最后使用新文件覆盖源文件。

with open('a.txt') as read_f,open('.a.txt.swap','w') as write_f:for line in read_f:	# 可迭代对象f逐行操作,防止内存溢出line=line.replace('str1','str2')write_f.write(line)
os.remove('a.txt')
os.rename('.a.txt.swap','a.txt')

处理大数据还有多种方法:

  1. 通过read(size)增加参数,指定读取的字节数。

    while True:block = f.read(1024)if not block:break
  2. 通过readline(),每次只读一行。

    while True:line = f.readline()if not line:break

file对象常用的参数:

函数功能
file.close()关闭文件。关闭后不能再进行读写操作
file.flush()刷新文件内部缓冲,直接把内部缓冲区的数据立刻写入文件,而不是被动等待输出缓冲区写入
file.fileno()返回一个整型的文件描述符,可以用在如os模块的read方法等一些底层操作上
file.isatty()如果文件连接到一个终端设备,则返回True,否则False
file.next()返回文件下一行
file.read([size])从文件读取指定的字节数,如果为给定或为负,则读取所有
file.readline([size])读取整行,包括"\n"字符
file.readlines([sizeint])读取所有行并返回列表,若给定sizeint>0,则返回总和为sizeint字节的行,实际读取值的可能比sizeint大,因为要填充缓冲区
file.seek(offset[,whence])设置文件当前位置
file.tell()返回文件当前位置
file.truncate([size])根据size参数截取文件,size参数可选
file.write(str)将字符串写入文件,没有返回值
file.writelines(sequence)向文件写入一个序列字符串列表,如果需要换行,则加入每行的换行符

1.2.3、序列化和反序列化

  • 序列化:将数据结构或对象转换成二进制串的过程
  • 反序列化:将在序列化过程中所生成的二进制串转换成数据结构或对象的过程

Python的pickle模块实现了基本的数据序列和反序列化。

# 序列化(将对象obj保存至文件中)。
pickle.dump(obj,file,[,protocal])# 反序列化(从文件中恢复对象,并重构为原来的Python对象)
x=pickle.load(file)

序列化实例:

import pickle# 使用pickle模块将数据对象保存到文件# 字符串
data0 = "hello world"
# 列表
data1 = list(range(20))[1::2]
# 元组
data2 = ("x","y","z")
# 字典
data3 = {"a":data0,"b":data1,"c":data2}print(data0)
print(data1)
print(data2)
print(data3)output = open("data.pk1","wb")# 使用默认的protocal
pickle.dump(data0,output)
pickle.dump(data1,output)
pickle.dump(data2,output)
pickle.dump(data3,output)
output.close()

反序列化演示:

import pickle# 使用pickle模块从文件中重构Python对象
pkl_file = open("data.pk1","rb")data0 = pickle.load(pkl_file)
data1 = pickle.load(pkl_file)
data2 = pickle.load(pkl_file)
data3 = pickle.load(pkl_file)print(data0)
print(data1)
print(data2)
print(data3)pkl_file.close()

1.3、读写配置文件

配置文件是供程序运行时读取配置信息的文件,用于将配置信息与程序分离

Python内置的配置文件解析器模块configparser类来解析基本的配置文件。

常见的pip配置文件如下:

[global]
index-url = https://pypi.doubanio.com/simple
trusted-host = pypi.doubanio.com

读取配置文件的信息的实例:

import configparser
config = configparser.ConfigParser()    # 实例化ConfigParser类
config.read(r"lesson/pip.ini")
print("遍历配置信息")
for section in config.sections():print(f"section is [{section}")for key in config[section]:print(f"key is [{key}],value is [{config[section][key]}]")  # 打印键和值print("通过键获取相对应的值:")
print(f"index-url is [{config['global']['index-url']}]")
print(f"trusted-host is [{config['global']['trusted-host']}]")# 上述代码通过实例化ConfigParser类读取配置文件,遍历配置文件中的section信息及键值信息,通过索引获取值信息。

相关信息写入配置文件实例:

import configparser
config = configparser.ConfigParser()config["DEFAULT"] = {"ServerAliveInterval":"45","Compression":"yes","CompressionLevel":"9"
}config["bitbucket.org"] = {}
config["bitbucket.org"]["User"] = "hg"config["topsecret.server.com"] = {}
topsecret = config["topsecret.server.com"]
topsecret["Port"] = "50022"
topsecret["ForwardX11"] = "no"config["DEFAULT"]["ForwaldX11"] = "yes"with open("example.ini","w") as configfile:config.write(configfile)
with open("example.ini","r") as f:print(f.read())

configparser模块的接口非常直接、明确。注意以下几点:

  • section名称是区分大小写的
  • section下的键值对中键是不区分大小写的,config["bitbucket.org"]在写入时会统一变成小写user保存在文件中
  • section下的键值对中的值是不区分类型的,都是字符串,具体使用时需要转换成想要的数据类型
  • section的名称是[DEFAULT]时,其他section的键值会继承[DEFAULT]的键值信息

1.4、解析XML文件*

XML的全称是eXtensible Markup Language,意为可扩展的标记语言,是一种用于标记电子文件使其具有结构性的标记语言。被设计用来传输和存储数据,例如:

<note><to>George</to><form>John</form><heading>Reminder</heading><body>Don't forget the meeting!</body>
</note>

Python有三种方法解析XML:SAX、DOM、ElementTree

1.4.1、SAX(simple API for XML)

SAX是一种基于事件驱动的API,使用时涉及两个部分:解析器事件处理器。解析器负责读取XML文件,并向事件处理器发送相应的事件。事件处理器对相应的事件做出相应,对数据做出处理。

  • 创建一个新的XMLReader对象,parser_list是可选参数,是解析器列表xml.sax.make_parser([parser_list])
  • 自定义事件处理器,继承ContentHandler类

ContenHandler类的方法:

名称功能
characters(content)从行开始,遇到标签之前,存在字符,content的值为这些字符串 从下一个标签,遇到下一个标签之前,存在字符,content的值为这些字符串
startDocument()文档启动时调用
endDocument()解析器到达文档结尾时调用
startElement(name,attrs)遇到XML开始标签时调用,name是标签的名字,attrs是标签属性值字典
endElement(name)遇到XML结束标签时调用

语法:

xml.sax.parse(xmlfile,contenthandler[,errorhandler])
# 参数说明:
xmlstring:xml字符串
contenthandler:必须是一个ContentHandler的对象
errorhandler:如果指定该参数,则errorhandler必须是一个SAXErrorHandler对象

解析XML的例子:首先有一个example.xml:

<?xml version="1.0" encoding="UTF-8"?>
<library><book id="1"><title>Book Title One</title><author>Author A</author><year>2021</year></book><book id="2"><title>Book Title Two</title><author>Author B</author><year>2022</year></book><!-- More books can be added here -->
</library>

解析代码实例:

import xml.saxclass MySAXHandler(xml.sax.ContentHandler):def __init__(self):self.current_data = ""def startElement(self, tag, attributes):print(f"Start Element: {tag}")def endElement(self, tag):print(f"End Element: {tag}")if tag == "title":print(f"Title: {self.current_data}")self.current_data = ""elif tag == "author":print(f"Author: {self.current_data}")self.current_data = ""elif tag == "year":print(f"Year: {self.current_data}")self.current_data = ""def characters(self, content):self.current_data += content.strip()# 创建SAX解析器
parser = xml.sax.make_parser()
# 将我们自定义的处理类注册到解析器
parser.setContentHandler(MySAXHandler())# 解析XML文档
parser.parse("example.xml")

SAX用事件驱动模型,通过在解析XML的过程中触发一个个的事件并调用用户定义的回调函数来处理XML文件,一次处理一个标签,无需事先全部读取整个XML文档,处理效率较高。适用场景:

  • 对大型文件进行处理
  • 只需要文件的部分内容,或者只需从文件中得到特定信息
  • 想建立自己的对象模型时

1.4.2、DOM(Document Object Model)

文件对象模型是W3C组织推荐的处理可扩展置标语言的标准编程接口。

实例:使用xml.dom.minidom解析xml文件

import xml.dom.minidom
from xml.dom.minidom import parse# 假设我们有一个XML字符串,也可以从文件中读取
xml_string = """
<?xml version="1.0" encoding="UTF-8"?>
<library><book id="1"><title>Book Title One</title><author>Author A</author><year>2021</year></book><book id="2"><title>Book Title Two</title><author>Author B</author><year>2022</year></book>
</library>
"""# 解析XML字符串
dom = xml.dom.minidom.parseString(xml_string)
# 文档方式:
dom = xml.dom.minidom.parse("example.xml")# 获取<library>元素
library = dom.documentElement# 遍历所有的<book>元素
for book in library.getElementsByTagName('book'):# 获取<book>的id属性book_id = book.getAttribute('id')# 获取并打印<title>元素的文本title = book.getElementsByTagName('title')[0].firstChild.data# 获取并打印<author>元素的文本author = book.getElementsByTagName('author')[0].firstChild.data# 获取并打印<year>元素的文本year = book.getElementsByTagName('year')[0].firstChild.data# 打印信息print(f"Book ID: {book_id}")print(f"Title: {title}")print(f"Author: {author}")print(f"Year: {year}")print()  # 打印空行以便区分每本书的信息# 代码使用minidom解析器打开文档,使用getElementsByTagName方法获取所有标签并遍历子标签,逻辑上比SAX直观

1.4.3、ElementTree

ElementTree将XML数据在内存中解析成,通过树来操作XML。

import xml.etree.ElementTree as ETtree = ET.parse("example.xml")
root = tree.getroot()
print(f"这是一个早餐菜单\n{root.attrib['year']}")for child in root:print("Book:",child[0].text)print("Title:",child[1].text)

二、系统信息监控

Python获取系统信息的模块是psutil(process and system utilities)。

2.1、监控CPU信息

import psutilpsutil.cpu_times()				# 获取CPU(逻辑CPU的平均)占用时间的详细信息
psutil.cpu_times(percpu=True)   # 获取每个CPU占用时间的详细信息
psutil.cpu_count()      		# CPU逻辑数量
psutil.cpu_count(logical=False) # CPU物理数量
psutil.cpu_percent()        	# CPU占比
psutil.cpu_percent()        	# 每个CPU的占比

2.2、监控内存信息

psutil.virtual_memory()     # 数值以字节为单位显示,自行转换

2.3、监控磁盘信息

psutil.disk_partitions()
psutil.disk_usage('/')      # 磁盘使用情况

2.4、监控网络信息

psutil.net_io_counters()    # 获取网络读写字节数/包的个数
psutil.net_if_addrs()       # 获取网络接口信息
psutil.net_if_stats()       # 获取网络接口状态
psutil.net_connections()    # 获取当前网络连接信息

2.5、获取进程信息

for pid in psutil.pids():	# 获取所有进程的pidprint(pid,end=',')
for proc in psutil.process_iter(attrs=['pid','name','username']):if proc.info['name'].startswith('Wechat'):	# 查找微信程序的相关信息print(proc.info)# psutil.process_iter返回的是一个可迭代对象,每个元素的info是一个字典,通过其可以获取我们关心的信息:
psutil.Process(12476).cpu_times()   # 获取CPU占用
psutil.Process(12476).memory_info() # 获取内存占用,rss就是实际占用的内存
psutil.Process(12476).num_threads() # 获取线程数
psutil.Process(12476).memory_percent()  # 获取内存占比

2.6、实例:常见的实用方法

import import os
import psutil
import signal# 按名称查找进程相关信息 1
def find_procs_by_name1(name):"Return a list of processes matching 'name'."ls = []for p in psutil.process_iter(attrs=['name']):if p.info['name'] == name:ls.append(p)return ls# 按名称查找进程相关信息 2
def find_procs_by_name2(name):ls = []for p in psutil.process_iter(attrs=["name","exe","cmdline"]):if name == p.info['name'] or \p.info['exe'] and os.path.basename(p.info['exe']) == name or \p.info['cmdline'] and p.info['cmdline'][0] == name:ls.append(p)return ls# 杀掉进程树
def kill_proc_tree(pid,sig=signal.SIGTERM,include_parent=True,timeout=None,on_terminate=None):if pid == os.getpid():raise RuntimeError("I refuse to kill myself")parent = psutil.Process(pid)children = parent.children(recursive=True)if include_parent:children.append(parent)for p in children:p.send_signal(sig)gone,alive = psutil.wait_procs(children,timeout=timeout,callback=on_terminate)return (gone,alive)# 杀掉子进程
def reap_children(tiemout=3):def on_terminate(proc):print("process {} terminated with exit code {}".format(proc,proc.returncode))procs = psutil.Process().children()# send SIGTERMfor p in procs:p.terminate()gone,alive = psutil.wait_procs(procs,timeout=tiemout,callback=on_terminate)if alive:# send SIGKILLfor p in alive:print("process {} survived SIGTERM;trying SIGKILL" % p)p.kill()gone,alive = psutil.wait_procs(alive,timeout=tiemout,callback=on_terminate)if alive:# give upfor p in alive:print("process {} survived SIGKILL;giving up" % p)

三、文件系统监控

如某个目录被删除,或者某个文件被修改、移动、删除时需要执行一定的操作或发出警报。Python使用watchdog库来实现文件系统监控,其原理是通过操作系统的事件触发

3.1、实例

import time
from watchdog.events import *
from watchdog.observers import Observerclass FileEventHandler(FileSystemEventHandler):def __init__(self):FileSystemEventHandler.__init__(self)def on_moved(self, event):now = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())if event.is_directory:print(f"{now}文件夹由{event.src_path}移动至{event.dest_path}")else:print(f"{now}文件由{event.src_path}移动至{event.dest_path}")def on_created(self, event):now = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())if event.is_directory:print(f"{now}文件夹{event.src_path} 创建")else:print(f"{now}文件{event.src_path} 创建")def on_deleted(self, event):now = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())if event.is_directory:print(f"{now}文件夹{event.src_path} 删除")else:print(f"{now}文件{event.src_path} 删除")def on_modified(self, event):now = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())if event.is_directory:print(f"{now}文件夹{event.src_path} 修改")else:print(f"{now}文件{event.src_path} 修改")if __name__ == '__main__':observer = Observer()path = r"d:/test"event_handler = FileEventHandler()observer.schedule(event_handler, path, True)  # True表示递归子目录print(f"监控目录{path}")observer.start()observer.join()

适用场景:

  • 监控文件系统中文件或目录的增、删、改情况
  • 当特定的文件被创建、删除、修改、移动时执行相应的任务

四、执行外部命令subprocess

subprocess是Python自带的模块,主要用来取代一些旧的模块或方法,如os.system等。适用subprocess模块更方便地执行操作系统支持的命令,可与其他应用程序结合适用

4.1、subprocess.run()方法*

这是官方推荐使用的方法,查看其原型:

subprocess.run(args,*,stdin=None,input=None,stdout=None,stderr=None,shell=False,cwd=None,timeout=None,check=False,encoding=None,errors=None)

该函数返回一个CompletedProcess类的实例,其常用参数:

  • args代表需要在操作系统中执行的命令。可以是字符串形式(要去shell=True),也可以是列表list类型
  • *代表可变参数,一般是列或字典形式
  • stdin、stdout、stderr指定了可执行程序的标准输入、标准输出、标准错误文件句柄。
  • shell代表程序是否需要在shell上执行
  • check设置为True表示检车命令的返回值,当返回值为非0时,就抛出CalledProcessError异常
  • timeout设置超时时间,如果超时,则强制kill掉子进程

在Linux系统中操作,实例自行查找

4.2、Popen类

Popen类的构造函数:

class subprocess.Popen(args,bufsize=-1, 	# 0无缓冲、1行缓冲,其他正值,缓冲区大小,负值,默认系统缓冲executable=None,# 一般不用stdin=None, 	# None没有任何重定向,继承父进程。PIPE创建管道...stdout=None,stderr=None,preexec_fn=None, 	# 钩子函数close_fds=True,		shell=False, cwd=None, env=None, universal_newlines=None,startupinfo=None, creationflags=0)

使用方法:

subprocess.Popen(["getit","abc.txt"])
subprocess.Popen("getit abc.txt")

Popen类的对象还有其他实用方法:

名称功能
poll()检查是否结束,设置返回值
wait()等待结束,设置返回值
communicate()参数是标准输入,返回标准输出和标准出错
send_signal()发送信号(主要在unix下有用)
terminate()终止进程,unix对应的SIGTERM信号,windows下调用api函数TerminateProcess()
kill()杀死进程(unix对应SIGKILL信号),windows同上
stdin stdout stderr参数中指定PIPE时,可以使用
pid进程ID
returncode进程返回值

4.3、其他方法

  • subprocess.call(*popenargs,**kwargs):call方法调用Popen()执行程序,并等待它完成
  • subprocess.check_call(*popenargs,**kwargs):调用前面的call(),如果返回值非0,则抛出异常
  • subprocess.check_output(*popenargs,**kwargs):调用Popen()执行程序,并返回其标准输出

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

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

相关文章

报表控件Stimulsoft在JavaScript报告工具中的事件:查看器事件(下)

Stimulsoft Ultimate &#xff08;原Stimulsoft Reports.Ultimate&#xff09;是用于创建报表和仪表板的通用工具集。该产品包括用于WinForms、ASP.NET、.NET Core、JavaScript、WPF、PHP、Java和其他环境的完整工具集。无需比较产品功能&#xff0c;Stimulsoft Ultimate包含了…

PCIE协议-1

1. PCIe结构拓扑 一个结构由点对点的链路组成&#xff0c;这些链路将一组组件互相连接 - 图1-2展示了一个结构拓扑示例。该图展示了一个称为层级结构的单一结构实例&#xff0c;由一个根复合体&#xff08;Root Complex, RC&#xff09;、多个端点&#xff08;I/O设备&#xf…

Amazon Bedrock 托管 Llama 3 8B70B

Amazon Bedrock 托管 Llama 3 8B&70B&#xff0c;先来体验&#xff1a;&#xff08;*实验环境账号有效期为1天&#xff0c;到期自动关停&#xff0c;请注意重要数据保护&#xff09; https://dev.amazoncloud.cn/experience/cloudlab?id65fd86c7ca2a0d291be26068&visi…

iOS与android坐标映射不一致问题

iOS与android坐标映射不一致问题 背景背景 为什么同一份着色器代码、同样的cvmat数据,Android和iOS两个平台处理之后会得到不一样的结果呢? 这主要是因为iOS和Android使用的渲染图形库不一样,iOS使用的是Metal,而Android使用的是OpenGL ES,而两个图形库的纹理坐标系又不一…

『51单片机』AT24C02[IIC总线]

存储器的介绍 ⒈ROM的功能⇢ROM的数据在程序运行的时候是不容改变的&#xff0c;除非你再次烧写程序&#xff0c;他就会改变&#xff0c;就像我们的书本&#xff0c;印上去就改不了了&#xff0c;除非再次印刷&#xff0c;这个就是ROM的原理。 注→在后面发展的ROM是可以可写可…

【ITK配准】第七期 尺度(Metric)- 均方Metric

很高兴在雪易的CSDN遇见你 VTK技术爱好者 QQ:870202403 公众号:VTK忠粉 前言 本文分享ITK中的均方Metric,即itk::MeanSquaresImageToImageMetricv4,希望对各位小伙伴有所帮助! 感谢各位小伙伴的点赞+关注,小易会继续努力分享,一起进步! 你的点赞就是我的动力…

54.HarmonyOS鸿蒙系统 App(ArkTS)tcp socket套接字网络连接收发测试

工程代码https://download.csdn.net/download/txwtech/89258409?spm1001.2014.3001.5501 54.HarmonyOS鸿蒙系统 App(ArkTS)tcp socket套接字网络连接收发测试 import socket from ohos.net.socket; import process from ohos.process; import wifiManager from ohos.wifiMana…

网络基础(1)详解

目录 1.计算机网络背景 2.网络协议 3.网络中的地址管理 1.计算机网络背景 1.1 网络发展 (1)计算机从独立模式到网络互联(多态计算机连接共享数据)再到局域网LAN(通过交换机和路由器连接)接着是广域网WAN 1.2 协议 协议就是双方的一种约定. 为什么要有协议? 因为在数据长距…

Python专题:一、安装步骤

1、下载地址&#xff1a;Welcome to Python.org 勾选这个add 其他的全部下一步即可。 运行出现这个即代表安装成功。 Python自带编辑器。 2、推荐使用的sublime 编辑器下载 全部下一步安装。

苹果可能将OpenAI技术集成至iOS/iPadOS 18

&#x1f989; AI新闻 &#x1f680; 苹果可能将OpenAI技术集成至iOS/iPadOS 18 摘要&#xff1a;苹果正在与OpenAI就将GPT技术部署在iOS/iPadOS 18中进行谈判。这项技术被视为可能增强的Siri功能&#xff0c;即“AI聊天机器人”。除Siri外&#xff0c;新技术还可能改善Spotl…

直播产品实习生实习体验报告,笔灵AI生成模版分享

实习体验报告&#xff1a;直播产品实习生 如果有不同的岗位需要写的话可以去笔灵生成一下 网址&#xff1a;https://ibiling.cn/scene/inex?fromcsdnsx 一、实习背景我是XXX&#xff0c;作为一名直播产品实习生&#xff0c;我在XX公司进行了为期X个月的实习。在这段时间里&…

unreal engine5.3.2 Quixel bridge无法登陆

UE5系列文章目录 文章目录 UE5系列文章目录前言一、问题定位二、解决方法 前言 这几天unreal engine5.3.2 Quixel bridge无法登陆&#xff0c;输入epic 账号和密码&#xff0c;然后在输入epic发送的验证码&#xff0c;总是提示登录失败。就算是使用科学上网依然无法登录。而且…

高企文档电子章怎么盖

为高企&#xff08;高新技术企业&#xff09;文档加盖电子章&#xff0c;需要遵循一套专业的流程&#xff0c;确保电子章的合法性和安全性。以下是详细的步骤&#xff1a; 准备电子章实体印章的数字化&#xff1a; 将企业的实体印章通过扫描或高清拍照的方式转换为电子格式&…

当前主机使用的磁盘以及带宽情况

今日看到有用户在论坛留言反馈他买了Hostease Linux虚拟主机&#xff0c;想要查看当前主机使用的磁盘以及带宽情况&#xff0c;但是不知道如何查看。因为这边也是对于Hostease的虚拟主机产品是有所了解的&#xff0c;知道他们都是默认带管理面板的操做起来很方便的&#xff0c;…

The provided password or token is incorrect or your account

IDEA使用git技巧 【/n】 01 问题出现场景 我的gitlab上个月生成的token到期了,于是今天推上去的时候报了这个错误 The provided password or token is incorrect or your account has 2FA enabled and you must use a personal access token instead of a password. See ht…

前端传递list(数组)类型参数,后端接收失败

一顿报错,我之前遇到的list都是Long类型 貌似用GET也是可以的,但是很奇怪一直报错 就是不可以 后来去百度 查询到可以用两种方法解决这个问题 1、拆开 传 以GET方式&#xff0c;后端GetMappingRequestParam接收。 2、以Post方式传&#xff0c;后端创建dto PostMappingReques…

【JavaWeb】网上蛋糕项目商城-我的订单,退出功能

概念 上一文中&#xff0c;我们实现了注册&#xff0c;登录&#xff0c;提交订单以及修改个人信息等功能。本文在登录的状态下&#xff0c;实现订单列表以及退出登录功能等。 我的订单 在head.jsp头部页面中&#xff0c;当用户处于登录状态&#xff0c;则会显示“我的订单”…

算法-并查集

目录 什么是并查集 并查集基础 &#xff08;1&#xff09;原理 &#xff08;2&#xff09;初始化 &#xff08;3&#xff09;查询 &#xff08;4&#xff09;合并 &#xff08;5&#xff09;判断是否同一集合 并查集优化 路径压缩 启发式合并 并查集模板 模板 例题…

WPF之多种视图切换

1&#xff0c;View切换&#xff0c;效果呈现 视图1 视图2 视图3 2&#xff0c;在Xaml中添加Listview控件&#xff0c;Combobox控件。 <Grid ><Grid.RowDefinitions><RowDefinition Height"143*"/><RowDefinition Height"30"/>&l…

绘画作品3d数字云展厅提升大众的艺术鉴赏和欣赏能力

3D虚拟展厅作为未来艺术的展示途径&#xff0c;正逐渐成为文化创意产业蓬勃发展的重要引擎。这一创新形式不仅打破了传统艺术展览的局限性&#xff0c;更以其独特的魅力吸引着全球观众的目光。 3D虚拟艺术品展厅以其独特的魅力&#xff0c;助力提升大众的艺术鉴赏和欣赏能力。观…