linux之perf(17)PMU事件采集脚本

Linux之perf(17)PMU事件采集脚本


Author: Once Day Date: 2025年2月22日

一位热衷于Linux学习和开发的菜鸟,试图谱写一场冒险之旅,也许终点只是一场白日梦…

漫漫长路,有人对你微笑过嘛…

全系列文章可参考专栏: Perf性能分析_Once_day的博客-CSDN博客。

参考文章:

  • Tutorial - Perf Wiki (kernel.org)
  • perf-top(1) - Linux manual page (man7.org)

文章目录

  • Linux之perf(17)PMU事件采集脚本
        • 1. Perf stat介绍
        • 2. 设计与实现
          • 2.1 采集事件来源
          • 2.2 使用CSV格式输出数据
          • 2.3 Python解析数据和保存数据
          • 2.4 制作图表
        • 3. 源码文件

1. Perf stat介绍

perf 是 Linux 内核提供的 性能分析工具,用于监控和分析 CPU、缓存、内存、I/O 等系统性能指标。

常用于统计 CPU 使用情况,分析函数调用热点(热点分析),监测硬件事件(如缓存未命中、指令执行),发现性能瓶颈。

在Linux系统上可以直接通过软件包管理器安装:

sudo apt install linux-tools-common linux-tools-$(uname -r)  # Ubuntu/Debian
sudo yum install perf                                        # CentOS/RHEL

perf statperf 的子命令,用于统计系统或进程的性能指标,比如指令执行数、CPU 时钟周期、缓存未命中等。

下面是一个基本用法示例:

root@linux:/var# perf stat      Performance counter stats for 'system wide':1969.215600      cpu-clock (msec)          #    2.000 CPUs utilized          24504      context-switches          #    0.012 M/sec                  0      cpu-migrations            #    0.000 K/sec                  1221      page-faults               #    0.620 K/sec                  1969063645      cycles                    #    1.000 GHz                    1085510412      instructions              #    0.55  insn per cycle         115590912      branches                  #   58.699 M/sec                  4341812      branch-misses             #    3.76% of all branches        0.984769200 seconds time elapsed       

常用选项:

选项作用
-e <event>指定监测的事件(如 cycles, cache-misses
-a监视整个系统
-C <cpu>监视指定 CPU
-p <pid>监视指定进程
-I <ms>ms 毫秒输出一次统计数据
-x <sep><sep> 分隔字段(如 CSV 格式)
2. 设计与实现
2.1 采集事件来源

perf listperf 工具的一个子命令,用于列出所有可用的性能监控事件(PMU 事件),包括 CPU 指令、缓存、内存、软件计数等。

perf list 事件分类:

事件类型说明示例
硬件事件(hardware events)由 CPU 直接提供的性能指标cycles, instructions, cache-misses
软件事件(software events)由内核统计的操作系统事件context-switches, cpu-clock, page-faults
缓存事件(cache events)监测 CPU 缓存访问情况L1-dcache-loads, LLC-load-misses
Tracepoint 事件监测内核行为(调度、系统调用等)sched:sched_switch, syscalls:sys_enter_read
PMU(Performance Monitoring Unit) 事件处理器特定的硬件计数器armv8_pmuv3/l1d_cache/, intel_pt//

通过使用 perf list 找到要监测的事件,然后用 perf stat -e <event> 进行分析

例如,在设备上找到了以下与cache相关的事件:

硬件事件bus-cycles: 总线周期数cache-misses: cache miss次数cache-references: cache访问次数
硬件cache事件L1-dcache-load-misses: L1数据cache读miss次数L1-dcache-loads: L1数据cache读次数L1-dcache-store-misses: L1数据cache写miss次数L1-dcache-stores: L1数据cache写次数L1-icache-load-misses: L1指令cache读miss次数L1-icache-loads: L1指令cache读次数branch-load-misses: 分支预测表读miss次数branch-loads: 分支预测表读次数dTLB-load-misses: 数据TLB读miss次数iTLB-load-misses: 指令TLB读miss次数
内核PMU事件armv8_pmuv3/br_immed_retired/: 直接分支指令数armv8_pmuv3/br_mis_pred/: 预测失败分支数armv8_pmuv3/br_pred/: 预测成功分支数armv8_pmuv3/bus_access/: 总线访问事件armv8_pmuv3/bus_cycles/: 总线周期armv8_pmuv3/cid_write_retired/: 上下文ID寄存器写入事件armv8_pmuv3/cpu_cycles/: CPU周期armv8_pmuv3/exc_return/: 异常返回事件armv8_pmuv3/exc_taken/: 发生异常事件armv8_pmuv3/inst_retired/: 执行指令数armv8_pmuv3/l1d_cache/: L1数据cache访问事件armv8_pmuv3/l1d_cache_refill/: L1数据cache refill事件armv8_pmuv3/l1d_cache_wb/: L1数据cache写回事件armv8_pmuv3/l1d_tlb_refill/: L1数据TLB refill事件armv8_pmuv3/l1i_cache/: L1指令cache访问事件armv8_pmuv3/l1i_cache_refill/: L1指令cache refill事件armv8_pmuv3/l1i_tlb_refill/: L1指令TLB refill事件armv8_pmuv3/l2d_cache/: L2数据cache访问事件armv8_pmuv3/l2d_cache_refill/: L2数据cache refill事件armv8_pmuv3/l2d_cache_wb/: L2数据cache写回事件armv8_pmuv3/ld_retired/: 执行的load指令数armv8_pmuv3/mem_access/: 数据内存访问事件armv8_pmuv3/memory_error/: memory error事件armv8_pmuv3/pc_write_retired/: 执行的PC寄存器写指令数armv8_pmuv3/st_retired/: 执行的store指令数armv8_pmuv3/sw_incr/: 软件增加事件计数armv8_pmuv3/unaligned_ldst_retired/: 执行的非对齐的load/store指令数

然后分类为不同组,每组4-6个事件,不能太多,设备的PMU单元有限。当事件数超过硬件计数器支持的数量时,perf 会采用 多路复用(Multiplexing) 机制,导致每个事件只能在部分时间窗口内进行测量。

下面拆分为8个组事件:

# 定义以上提到的PMU事件, 单次最多支持6个事件
THIS_PMU_EVENTS = {"base-events": ["cycles", "instructions", "bus-cycles", "cache-misses", "cache-references"],"L1-dcache-events": ["L1-dcache-load-misses", "L1-dcache-loads", "L1-dcache-store-misses", "L1-dcache-stores", "dTLB-load-misses"],"L1-icache-events": ["L1-icache-load-misses", "L1-icache-loads", "iTLB-load-misses"],"armv8-base-events": ["bus_cycles", "bus_access", "mem_access", "memory_error", "cpu_cycles", "inst_retired"],"armv8-dcache-events": ["l1d_cache", "l1d_cache_refill", "l1d_cache_wb", "l1d_tlb_refill"],"armv8-icache-events": ["l1i_cache", "l1i_cache_refill", "l1i_tlb_refill"],"armv8-l2cache-events": ["l2d_cache", "l2d_cache_refill", "l2d_cache_wb"],"armv8-ldst-events": ["ld_retired", "st_retired", "unaligned_ldst_retired"],
}
2.2 使用CSV格式输出数据

perf stat支持输出CSV格式数据,我们不选择聚合数据,而是按照CPU分别输出,且每1s输出一次数据,如下:

perf stat -a -A -I 1000 -x , -e {events_str} sleep 10.5 2>&1

选项说明:

  • -a:系统范围(system-wide),监控所有 CPU,而不仅限于当前进程。
  • -A:每个 CPU 单独显示统计数据(per-CPU statistics)。
  • -I 1000:以 1000 毫秒(1 秒)为间隔,定期输出统计数据(定时采样)。
  • -x ,:使用逗号(,)作为字段分隔符,以 CSV 格式输出数据,便于解析。
  • -e {events_str}:指定要监控的硬件/软件事件,{events_str} 需要替换为具体的事件列表(如 cpu-cycles,instructions,cache-misses)。
  • sleep 10.5:让 perf stat 运行 10.5 秒,然后退出。
  • 2>&1:重定向标准错误输出到标准输出,确保所有输出信息都可以被捕获(例如写入文件或管道处理)。

下面是一个运行示例:

root@linux:/var# perf stat -e unaligned_ldst_retired,l2d_cache_refill -a -A -I 1000 -x ,# time,cpu,counter,unit,event,duration(ns),unit,,1.000226480,CPU0,73480,,unaligned_ldst_retired,1000147600,100.00,,1.000226480,CPU1,2807316,,unaligned_ldst_retired,1000158640,100.00,,1.000226480,CPU0,1343260,,l2d_cache_refill,1000152080,100.00,,1.000226480,CPU1,1282233,,l2d_cache_refill,1000149120,100.00,,

perf stat 命令定期(每秒)采样两个硬件事件 unaligned_ldst_retired(未对齐的加载/存储指令退役)和 l2d_cache_refill(L2 数据缓存未命中导致的填充),并按 CPU(CPU0 和 CPU1)分别统计。

从示例数据来看,在 1 秒内:

  • 未对齐的加载/存储指令退役 (unaligned_ldst_retired),CPU0 发生 73,480 次,CPU1 发生 2,807,316 次,CPU1 远高于 CPU0,可能存在未对齐内存访问较多的任务。
  • L2 数据缓存填充 (l2d_cache_refill),CPU0 发生 1,343,260 次,CPU1 发生 1,282,233 次,两个 CPU 的 L2 缓存填充次数接近,说明 L2 缓存访问特性相似。

采样时间间隔 约 1 秒duration(ns) 约 1,000,000,000 纳秒)。

2.3 Python解析数据和保存数据

get_pmu_eventsrecord_pmu_events 是两个用于收集和记录PMU(性能监控单元)事件数据的函数。

def get_pmu_events(events_str: str) -> dict[str, list[dict[str, str]]]:cmd_str = f"perf stat -a -A -I 1000 -x , -e {events_str} sleep 10.5 2>&1"logging.info(f"Start to collect PMU event data, command: {cmd_str}")result = os.popen(cmd_str).read()pmu_events = {}for line in result.split("\n"):line_data = line.strip().split(",")if len(line_data) != 9:logging.debug(f"Invalid data, skip: {line}")continuetimestamp, cpu, counter, _, event_name, duration, _, _, _ = line_datatimestamp = timestamp.strip()logging.info(f"Collect PMU event data: {timestamp}: {cpu}, {duration}, {event_name}: {counter}")event_data = {"timestamp": timestamp, "cpu": cpu, "cycles": duration, "counter": counter}if event_name not in pmu_events:pmu_events[event_name] = []pmu_events[event_name].append(event_data)return pmu_events

get_pmu_events 函数的作用是执行 perf stat 命令来收集指定的PMU事件数据,并解析结果,返回一个包含解析后数据的字典。

解析 perf stat 数据的步骤:

  1. 构建 perf stat 命令字符串,指定要收集的事件、采集间隔和持续时间。
  2. 使用 os.popen 异步执行 perf stat 命令,并读取输出结果。
  3. 将结果按行分割,并逐行解析数据。
  4. 每行数据按逗号分隔,提取时间戳、CPU编号、事件值和事件名称等信息。
  5. 将解析后的数据存入字典中,字典的键是事件名称,值是包含事件数据的列表。

record_pmu_events 函数的作用是遍历指定的PMU事件组,逐个采集数据,并将数据保存到指定的文件中。

def record_pmu_events(event_groups: dict[str, list[str]], output_file: str, tag: str):for group_name, events in event_groups.items():logging.info(f"Start to collect PMU events data for group: {group_name} - {events}")events_str = ",".join(events)pmu_events = get_pmu_events(events_str)with open(output_file, "a+") as f:for event_name, event_data in pmu_events.items():for data in event_data:f.write(f"{tag},{event_name},{data['timestamp']},{data['cpu']},{data['cycles']},{data['counter']}\n")logging.info(f"Save PMU events {group_name} data to file: {output_file}")logging.info(f"Record PMU events data finished, save to file: {output_file}")

保存数据到文件的步骤:

  1. 遍历事件组,逐个采集PMU事件数据。
  2. 调用 get_pmu_events 函数获取指定事件组的PMU事件数据。
  3. 将解析后的数据以CSV格式保存到文件中。每条记录包含标签、事件名、时间戳、CPU编号、统计时长和计数器值。
  4. 如果文件不存在,则创建文件并写入CSV表头。
  5. 记录完成后,日志记录保存文件的操作。
2.4 制作图表

在设备上运行脚本后,可以生成CSV文件,信息如下:

tag,event_name,timestamp,cpu,cycles,counter
skip_soft_checksum,cycles,1.000446320,CPU0,1000195920,1000054507
skip_soft_checksum,cycles,1.000446320,CPU1,1000217200,1000190918
skip_soft_checksum,cycles,2.001181600,CPU0,1000808960,1000729035
skip_soft_checksum,cycles,2.001181600,CPU1,1000796640,1000787052
skip_soft_checksum,cycles,3.001844080,CPU0,1000659440,1000584718
skip_soft_checksum,cycles,3.001844080,CPU1,1000659520,1000649955
......

但这个数据不够形象,需要转换为图表,有很多种方式,比如python处理成图表,导入Excel处理等。

我们这里选择导入飞书多维数据表格,然后生成需要的图表。

在这里插入图片描述

3. 源码文件
'''
SPDX-License-Identifier: BSD-3-ClauseCopyright (c) 2025 Once Day <once_day@qq.com>, All rights reserved.FilePath: /linux/perf/pmu-collect/pmu-collect.py
@Author: Once Day <once_day@qq.com>.
Date: 2025-02-22 12:57
@info: Encoder=utf-8,Tabsize=4,Eol=\n.@Description:收集指定的PMU事件数据, 使用perf stat命令收集数据, 并将数据保存到指定的文件中.@History:2025-02-22: 支持 【收集 + 触发开关 + 收集】 的简易控制变量模型'''from math import log
import os
import sys
import logging# 日志配置, 默认INFO级别, 格式: 时间 <级别> 文件名-代码行: 消息, 重定向到标准输出
logging.basicConfig(level=logging.INFO, format="%(asctime)s <%(levelname)s> %(filename)s-%(lineno)d: %(message)s", stream=sys.stdout)# PMU事件列表
"""
硬件事件bus-cycles: 总线周期数cache-misses: cache miss次数cache-references: cache访问次数
硬件cache事件L1-dcache-load-misses: L1数据cache读miss次数L1-dcache-loads: L1数据cache读次数L1-dcache-store-misses: L1数据cache写miss次数L1-dcache-stores: L1数据cache写次数L1-icache-load-misses: L1指令cache读miss次数L1-icache-loads: L1指令cache读次数branch-load-misses: 分支预测表读miss次数branch-loads: 分支预测表读次数dTLB-load-misses: 数据TLB读miss次数iTLB-load-misses: 指令TLB读miss次数
内核PMU事件armv8_pmuv3/br_immed_retired/: 直接分支指令数armv8_pmuv3/br_mis_pred/: 预测失败分支数armv8_pmuv3/br_pred/: 预测成功分支数armv8_pmuv3/bus_access/: 总线访问事件armv8_pmuv3/bus_cycles/: 总线周期armv8_pmuv3/cid_write_retired/: 上下文ID寄存器写入事件armv8_pmuv3/cpu_cycles/: CPU周期armv8_pmuv3/exc_return/: 异常返回事件armv8_pmuv3/exc_taken/: 发生异常事件armv8_pmuv3/inst_retired/: 执行指令数armv8_pmuv3/l1d_cache/: L1数据cache访问事件armv8_pmuv3/l1d_cache_refill/: L1数据cache refill事件armv8_pmuv3/l1d_cache_wb/: L1数据cache写回事件armv8_pmuv3/l1d_tlb_refill/: L1数据TLB refill事件armv8_pmuv3/l1i_cache/: L1指令cache访问事件armv8_pmuv3/l1i_cache_refill/: L1指令cache refill事件armv8_pmuv3/l1i_tlb_refill/: L1指令TLB refill事件armv8_pmuv3/l2d_cache/: L2数据cache访问事件armv8_pmuv3/l2d_cache_refill/: L2数据cache refill事件armv8_pmuv3/l2d_cache_wb/: L2数据cache写回事件armv8_pmuv3/ld_retired/: 执行的load指令数armv8_pmuv3/mem_access/: 数据内存访问事件armv8_pmuv3/memory_error/: memory error事件armv8_pmuv3/pc_write_retired/: 执行的PC寄存器写指令数armv8_pmuv3/st_retired/: 执行的store指令数armv8_pmuv3/sw_incr/: 软件增加事件计数armv8_pmuv3/unaligned_ldst_retired/: 执行的非对齐的load/store指令数
"""
# 定义以上提到的PMU事件, 单次最多支持6个事件
THIS_PMU_EVENTS = {"base-events": ["cycles", "instructions", "bus-cycles", "cache-misses", "cache-references"],"L1-dcache-events": ["L1-dcache-load-misses", "L1-dcache-loads", "L1-dcache-store-misses", "L1-dcache-stores", "dTLB-load-misses"],"L1-icache-events": ["L1-icache-load-misses", "L1-icache-loads", "iTLB-load-misses"],"armv8-base-events": ["bus_cycles", "bus_access", "mem_access", "memory_error", "cpu_cycles", "inst_retired"],"armv8-dcache-events": ["l1d_cache", "l1d_cache_refill", "l1d_cache_wb", "l1d_tlb_refill"],"armv8-icache-events": ["l1i_cache", "l1i_cache_refill", "l1i_tlb_refill"],"armv8-l2cache-events": ["l2d_cache", "l2d_cache_refill", "l2d_cache_wb"],"armv8-ldst-events": ["ld_retired", "st_retired", "unaligned_ldst_retired"],
}# 采集PMU事件并且解析结果, 存入文件里面
"""
root@linux:/var# perf stat -e unaligned_ldst_retired,l2d_cache_refill -a -A -I 1000 -x ,# time,cpu,counter,unit,event,duration(ns),unit,,1.000226480,CPU0,73480,,unaligned_ldst_retired,1000147600,100.00,,1.000226480,CPU1,2807316,,unaligned_ldst_retired,1000158640,100.00,,1.000226480,CPU0,1343260,,l2d_cache_refill,1000152080,100.00,,1.000226480,CPU1,1282233,,l2d_cache_refill,1000149120,100.00,,
"""
def get_pmu_events(events_str: str) -> dict[str, list[dict[str, str]]]:"""执行perf stat命令, 并且解析结果, 返回解析后的结果-a -A: 收集所有CPU的数据, 且按照CPU编号进行区分-I 1000: 每隔1s收集一次数据-x ,: 使用逗号分隔数据sleep 60: 收集60s的数据返回数据格式:{"unaligned_ldst_retired": [{"timestamp": "1.000226480", "cpu": "CPU0", "counter": "1000147600"},{"timestamp": "1.000226480", "cpu": "CPU1", "counter": "1000158640"}],......}"""cmd_str = f"perf stat -a -A -I 1000 -x , -e {events_str} sleep 10.5 2>&1"# 异步执行perf stat命令, 并且将结果保存到文件中(添加到文件末尾)logging.info(f"Start to collect PMU event data, command: {cmd_str}")# 使用pipe读取数据result = os.popen(cmd_str).read()# logging.debug(f"Collect PMU event data finished, output result: {result}")# 解析结果pmu_events = {}for line in result.split("\n"):# 解析每一行数据line_data = line.strip().split(",")# 数据格式: time,cpu,counter,unit,event,duration,unit,, 9个数据if len(line_data) != 9:logging.debug(f"Invalid data, skip: {line}")continue# 时间戳, CPU编号, 事件值, 事件名称timestamp, cpu, counter, _, event_name, duration, _, _, _ = line_data# 去除timestamp中的空格timestamp = timestamp.strip()logging.info(f"Collect PMU event data: {timestamp}: {cpu}, {duration}, {event_name}: {counter}")# 保存数据event_data = {"timestamp": timestamp, "cpu": cpu, "cycles": duration, "counter": counter}if event_name not in pmu_events:pmu_events[event_name] = []pmu_events[event_name].append(event_data)return pmu_eventsdef record_pmu_events(event_groups: dict[str, list[str]], output_file: str, tag: str):"""遍历PMU事件组, 逐个采集数据, 并且将数据保存到文件中."""for group_name, events in event_groups.items():# 采集PMU事件数据logging.info(f"Start to collect PMU events data for group: {group_name} - {events}")events_str = ",".join(events)pmu_events = get_pmu_events(events_str)# 解析数据, 保存到文件中, 记录为CSV格式: 标签, 事件名, 时间戳(s), CPU编号, 统计时长(us), 计数器值with open(output_file, "a+") as f:for event_name, event_data in pmu_events.items():for data in event_data:f.write(f"{tag},{event_name},{data['timestamp']},{data['cpu']},{data['cycles']},{data['counter']}\n")logging.info(f"Save PMU events {group_name} data to file: {output_file}")logging.info(f"Record PMU events data finished, save to file: {output_file}")if __name__ == "__main__":save_file = "this_pmu_events.csv"# 如果文件不存在, 则创建文件if not os.path.exists(save_file):with open(save_file, "w") as f:# CSV格式: 标签, 事件名, 时间戳(s), CPU编号, 统计时长(us), 计数器值f.write("tag,event_name,timestamp,cpu,cycles,counter\n")logging.info(f"Create new file: {save_file}")else:logging.info(f"Use existing file: {save_file}")# 标签名称来自于命令行参数if len(sys.argv) > 1:tag_str = sys.argv[1]else:tag_str = "default"logging.info(f"Start to collect PMU events data, tag: {tag_str}")# 采集THIS_PMU_EVENTS中定义的PMU事件, 并且保存到文件中record_pmu_events(THIS_PMU_EVENTS, save_file, tag_str)






Alt

Once Day

也信美人终作土,不堪幽梦太匆匆......

如果这篇文章为您带来了帮助或启发,不妨点个赞👍和关注,再加上一个小小的收藏⭐!

(。◕‿◕。)感谢您的阅读与支持~~~

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

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

相关文章

Java数据结构-排序

目录 一.本文关注焦点 二.七大排序分析及相关实现 1.冒泡排序 2.简单选择排序 3.直接插入排序 4.希尔排序 5.堆排序 ​编辑 6.归并排序 7.快速排序 一.本文关注焦点 各种排序的代码实现及各自的时间空间复杂度分析及稳定性。 时间复杂度&#xff1a;在比较排序中主…

改进收敛因子和比例权重的灰狼优化算法【期刊论文完美复现】(Matlab代码实现)

2 灰狼优化算法 2.1 基本灰狼优化算法 灰狼优化算法是一种模拟灰狼捕猎自然群体行为的社会启发式优化算法&#xff0c;属于一种新型的群体智能优化算法。灰狼优化算法具有高度的灵活性&#xff0c;是当前较为流行的优化算法之一。灰狼优化算法主要分为三个阶段&#xff1a;追…

创建Linux虚拟环境并远程连接

目录 下载VMware软件 下载CentOS 创建虚拟环境 远程连接Linux系统 下载VMware软件 不会的可以参考 传送门 下载CentOS 不会的可以参考 传送门 创建虚拟环境 打开VMware软件&#xff0c;创建虚拟机 选择典型安装 找到我们安装好的centOS文件&#xff0c;之后会自动检…

汽车智能制造企业数字化转型SAP解决方案总结

一、项目实施概述 项目阶段划分&#xff1a; 蓝图设计阶段主数据管理方案各模块蓝图设计方案下一阶段工作计划 关键里程碑&#xff1a; 2022年6月6日&#xff1a;项目启动会2022年12月1日&#xff1a;系统上线 二、总体目标 通过SAP实施&#xff0c;构建研产供销协同、业财一…

《Head First设计模式》读书笔记 —— 命令模式

文章目录 本节用例餐厅类比点餐流程角色与职责从餐厅到命令模式 命令模式第一个命令对象实现命令接口实现一个命令 使用命令对象NoCommand与空对象 定义命令模式支持撤销功能使用状态实现撤销多层次撤销 One One One …… more things宏命令使用宏命令 队列请求日志请求 总结 《…

基于YOLO11深度学习的运动鞋品牌检测与识别系统【python源码+Pyqt5界面+数据集+训练代码】

《------往期经典推荐------》 一、AI应用软件开发实战专栏【链接】 项目名称项目名称1.【人脸识别与管理系统开发】2.【车牌识别与自动收费管理系统开发】3.【手势识别系统开发】4.【人脸面部活体检测系统开发】5.【图片风格快速迁移软件开发】6.【人脸表表情识别系统】7.【…

DAY08 List接口、Collections接口、Set接口

学习目标 能够说出List集合特点1.有序2.允许存储重复的元素3.有带索引的方法(练习 add,remove,set,get) 能够使用集合工具类Collections类:static void sort(List<T> list) 根据元素的自然顺序 对指定列表按升序进行排序。static <T> void sort(List<T> lis…

shell编程总结

前言 shell编程学习总结&#xff0c;1万3千多字带你学习shell编程 往期推荐 14wpoc&#xff0c;nuclei全家桶&#xff1a;nuclei模版管理工具Nuclei 哥斯拉二开&#xff0c;免杀绕过规避流量检测设备 fscan全家桶&#xff1a;FscanPlus&#xff0c;fs&#xff0c;fscan适用…

OpenAI ChatGPT在心理治疗领域展现超凡同理心,通过图灵测试挑战人类专家

近期&#xff0c;一项关于OpenAI ChatGPT在心理治疗领域的研究更是引起了广泛关注。据报道&#xff0c;ChatGPT已经成功通过了治疗师领域的图灵测试&#xff0c;其表现甚至在某些方面超越了人类治疗师&#xff0c;尤其是在展现同理心方面&#xff0c;这一发现无疑为AI在心理健康…

【智能客服】ChatGPT大模型话术优化落地方案

本文原创作者:姚瑞南 AI-agent 大模型运营专家,先后任职于美团、猎聘等中大厂AI训练专家和智能运营专家岗;多年人工智能行业智能产品运营及大模型落地经验,拥有AI外呼方向国家专利与PMP项目管理证书。(转载需经授权) 目录 一、项目背景 1.1 行业背景 1.2 业务现…

【JavaWeb12】数据交换与异步请求:JSON与Ajax的绝妙搭配是否塑造了Web的交互革命?

文章目录 &#x1f30d;一. 数据交换--JSON❄️1. JSON介绍❄️2. JSON 快速入门❄️3. JSON 对象和字符串对象转换❄️4. JSON 在 java 中使用❄️5. 代码演示 &#x1f30d;二. 异步请求--Ajax❄️1. 基本介绍❄️2. JavaScript 原生 Ajax 请求❄️3. JQuery 的 Ajax 请求 &a…

[Android]APP自启动

APP添加自启动权限&#xff0c;重启设备后自动打开APP。 1.AndroidManifest.xml <?xml version"1.0" encoding"utf-8"?> <manifest xmlns:android"http://schemas.android.com/apk/res/android"xmlns:tools"http://schemas.an…

Moonshot AI 新突破:MoBA 为大语言模型长文本处理提效论文速读

前言 在自然语言处理领域&#xff0c;随着大语言模型&#xff08;LLMs&#xff09;不断拓展其阅读、理解和生成文本的能力&#xff0c;如何高效处理长文本成为一项关键挑战。近日&#xff0c;Moonshot AI Research 联合清华大学、浙江大学的研究人员提出了一种创新方法 —— 混…

cs224w课程学习笔记-第2课

cs224w课程学习笔记-第2课 传统图学习 前言一、节点任务1、任务背景2、特征节点度3、特征节点中心性3.1 特征向量中心性&#xff08;Eigenvector Centrality&#xff09;3.2 中介中心性&#xff08;Betweenness Centrality&#xff09;3.3 接近中心性&#xff08;Closeness Cen…

Centos虚拟机扩展磁盘空间

Centos虚拟机扩展磁盘空间 扩展前后效果1 虚拟机vmware关机后&#xff0c;编辑2 扩展2.1 查看2.2 新建分区2.3 格式化新建分区ext42.3.1 格式化2.3.2 创建2.3.3 修改2.3.4 查看 2.4 扩容2.4.1 扩容2.4.1 查看 扩展前后效果 df -h1 虚拟机vmware关机后&#xff0c;编辑 2 扩展 …

1.13作业

1 if(!preg_match("/[0-9]|\~|\|\|\#|\\$|\%|\^|\&|\*|\&#xff08;|\&#xff09;|\-|\|\|\{|\[|\]|\}|\:|\|\"|\,|\<|\.|\>|\/|\?|\\\\/i", $c)){eval($c); 构造数组rce ?ceval(array_pop(next(get_defined_vars()))); post传参:asystem("c…

如何在 SpringBoot 项目使用 Redis 的 Pipeline 功能

本文是博主在批量存储聊天中用户状态和登陆信息到 Redis 缓存中时&#xff0c;使用到了 Pipeline 功能&#xff0c;并对此做出了整理。 一、Redis Pipeline 是什么 Redis 的 Pipeline 功能可以显著提升 Redis 操作的性能&#xff0c;性能提升的原因在于可以批量执行命令。当我…

力扣LeetCode: 2209 用地毯覆盖后的最少白色砖块

题目&#xff1a; 给你一个下标从 0 开始的 二进制 字符串 floor &#xff0c;它表示地板上砖块的颜色。 floor[i] 0 表示地板上第 i 块砖块的颜色是 黑色 。floor[i] 1 表示地板上第 i 块砖块的颜色是 白色 。 同时给你 numCarpets 和 carpetLen 。你有 numCarpets 条 黑…

RabbitMQ 消息队列

1. 消息队列是什么&#xff1f; 当用户注册成功后&#xff0c;就发送邮件。当邮件发送成功了&#xff0c;接口才会提示注册成功信息。但由于发送邮件&#xff0c;依赖于其他厂商的服务&#xff0c;有可能他们的接口会非常耗时。那么用户就一直要等着邮件发送成功了&#xff0c;…

【SQL实验】触发器

下载素材文件”tsgl”、“成绩管理”,将tsgl.bak和成绩管理.bak数据库还原到库中【导入操作在之前的文章中详细讲过】 触发器 1、为图书表设置更新触发器&#xff0c;根据总编号来更新书名、作者、出版社、分类号和单价(根据总编号找到相应记录&#xff0c;然后更新书名、作者…