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

MySQL训练营-慢查询诊断问题

慢查询相关参数和建议配置

slow_query_log + long_query_time

日志开关,是否记慢查询日志以及超过多长时间判定为慢查询。

查看参数设置:

  • SHOW VARIABLES LIKE ‘slow_query_log’;
  • SHOW VARIABLES LIKE ‘long_query_time’;

实践建议:

  1. set global long_query_time=1;
  2. 分析型业务,set long_query_time=N;

全局设置为1,session级别针对耗时的分析型业务可以设置时间更长一点。

生成并查看一条慢查询日志:

先将slow_query_log开关打开:set global slow_query_log= on;,只能使用global级别。

再将long_query_time时间设置为1s:set global long_query_time= 1;set long_query_time= 1;都行。

在终端中执行select sleep(10);slow_query.log文件可以看到:

/usr/sbin/mysqld, Version: 8.0.18 (MySQL Community Server - GPL). started with:
Tcp port: 3306  Unix socket: /var/run/mysqld/mysqld.sock
Time                 Id Command    Argument
# Time: 2024-12-22T03:32:41.457742Z
# User@Host: root[root] @ localhost [127.0.0.1]  Id:    10
# Query_time: 10.000678  Lock_time: 0.000000 Rows_sent: 1  Rows_examined: 1
SET timestamp=1734838351;
select sleep(10);
  • Query_time: 10.000678

    表示整个查询从开始执行到执行完毕所花费的总时间,单位是秒。在这个例子中,查询总共耗时 10.000678 秒。

  • Lock_time: 0.000000

    指的是该查询在获取锁资源上所花费的时间,单位同样是秒。这里显示为 0 秒,意味着这个查询在执行过程中基本没有因为等待获取锁而耗费时间,即没有遇到锁等待的情况,能直接获取到所需的锁进行后续的操作。

  • Rows_sent: 1

    代表查询最终返回给客户端的行数。此例中返回了 1 行数据给客户端,说明查询结果的数据量比较小,不过查询耗时却很长,这就提示可能是查询执行过程中的其他环节(比如函数执行等情况)导致了整体的缓慢,而非数据量太大需要大量传输的原因。

  • Rows_examined: 1

    表示查询执行过程中数据库引擎扫描的数据行数。这里扫描了 1 行,结合返回行数等情况可以分析出数据库在执行该查询时的数据访问规模。

log_slow_extra

在MySQL中,log_slow_extra是一个与慢查询日志(Slow Query Log)相关的参数。它用于控制在慢查询日志中是否记录额外的信息。这些额外信息可以帮助数据库管理员(DBA)更深入地了解查询性能问题的原因。

同样的可以查看参数设置:

  • SHOW VARIABLES LIKE ‘log_slow_extra’;

实践建议:

打开参数后,CPU、内存、磁盘占用会比更多。但是可以提供更多的定位信息,建议稳定后打开。

5.7 和 8.0 关于慢查询日志差异

前值准备(建表准备数据):

drop table if exists t;CREATE TABLE t (id INT PRIMARY KEY AUTO_INCREMENT,c INT
);INSERT INTO t (c) VALUES (0), (0);

场景:

session1session2
begin;
update t set c=1 where id=1;
update t set c=2 where id=1;
//blocked
select sleep(10);
commit;
//updated,affected rows=1

问:session2是否记录慢查询?

答:5.7不会记,MySql会扣除行锁时间。8.0会记录。(答案存疑)

先使用mysql:8.0.18进行测试,慢查询日志中只有执行sleep(10)的记录:

怀疑是mysql的问题,再使用mysql:8.0.40进行测试,能复现该场景:

可见是mysql:8.0.x某个小版本引入的新特性,非mysql:8.0版本都有的。

样例分析(MySQL 8.0)
session1session2session3
lock table t write
begin;
update t set c=c+1 where id=1;
begin;
update t set c=c*10 where id=1;
unlock table;
commit;

解锁后,先执行session1再执行session3session1先获取到锁应该是,等待时间比session3长。

慢日志:

# Time: 2024-12-25T13:43:04.675707Z
# User@Host: root[root] @ localhost []  Id:     9
# Query_time: 37.684517  Lock_time: 0.000004 Rows_sent: 0  Rows_examined: 1
SET timestamp=1735134146;
update t set c=c+1 where id=1;
# Time: 2024-12-25T13:43:19.938977Z
# User@Host: root[root] @ localhost []  Id:    13
# Query_time: 43.321374  Lock_time: 15.263238 Rows_sent: 0  Rows_examined: 1
SET timestamp=1735134156;
update t set c=c*10 where id=1;

可知Lock_time中只记录了行锁的等待时间。Query_time-Lock_time不仅包括SQL语句的执行时间,还包括等待表锁的时间。

log_queries_not_using_indexes

log_queries_not_using_indexes是 MySQL 中的一个参数。当这个参数设置为ON时,MySQL 会将没有使用索引的查询语句记录到慢查询日志(slow query log)中。

前置准备:

drop table if exists t;CREATE TABLE t(id int NOT NULL,c int DEFAULT NULL,d int DEFAULT NULL,e int DEFAULT NULL,PRIMARY KEY(id ),KEY c(c),KEY d(d)
);insert into t values(1,833,10,1),(2,2,2,2),(3,3,3,3);

练习:update t set e=e*10 where e = 2;锁多少行?

答案锁全表,可以在一个实物中更新update t set e=e*10 where e = 2;,另一个事物执行update t set e=e*10 where e = 1;可以看到在等待:

session1session2
begin;
update t set e=e*10 where e = 1;
update t set e=e*10 where id = 2;

在默认隔离级别(可重复读)下,会阻塞锁全表。在读提交下,不会阻塞。

可以查看:https://tech.meituan.com/2014/08/20/innodb-lock.html,了解锁释放的实际。

通过刚刚的例子,可以看到没有走索引的语句会存在潜在的风险,所以这个参数建议打开。

那么,参数打开后导致慢查询日志过多,如以下对系统表的查询也会记录慢日志:

select * from information_schema.processlist;
select * from information_schema.innodb_trx;
show engine innodb status\G # 实测不会记

解决办法:

  1. log_queries_not_using_indexes+log_throttle_queries_not_using_indexes
    log_throttle_queries_not_using_indexes:限制每分钟无主键语句的记录条数上限。容易误伤需要记录的慢查询日志。
  2. log_queries_not_using_indexes+min_examined_row_limit
    min_examined_row_limit:扫描行数少于这个值的语句,不记入慢查询日志。

方案2,是否可行?先分析select count(*) from t;在8.0.17版本以前是3,新版本为0。新版本优化为由存储层计算结果直接返回给SQL层。

# Time: 2024-12-25T14:15:46.264553Z
# User@Host: root[root] @ localhost []  Id:    12
# Query_time: 40.595383  Lock_time: 0.000006 Rows_sent: 1  Rows_examined: 0
SET timestamp=1735136105;
select count(*) from t;

所以方案2会导致,该语句不记录。此外在以下场景:

先创建表与存储过程:

drop table if exists t;CREATE TABLE t (id INT,c INT
);INSERT INTO t (id, c) VALUES (0,0), (1,0), (2,0), (3,0), (4,0);//准备一个存储过程,对id=3这一行做5万次更新
delimiter ;;
create procedure udata3() begin
declare i int; set i=1; while(i<=50000) doupdate t set c=c+1 where id=3;set i=i+1;
end while;
end;;
delimiter ;

再进行以下操作:

session1(隔离级别RR)session2
begin;
select * from t where id = 1;
call udata3();
select * from t where id = 3; // 查询Q

可以在 MySQL 客户端连接到数据库后,使用SET语句来设置当前会话的事务隔离级别为 RR,示例代码如下:

-- 设置当前会话的事务隔离级别为RR
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;-- 开始事务
START TRANSACTION;
-- 这里编写事务中的SQL语句,例如查询、插入、更新等操作
SELECT * FROM your_table;
-- 提交事务
COMMIT;
  1. 查询Q的row_examined是多少?

为1,存储层最会返回最新的一行数据

  1. 查询Q的的查询时间更接近那个数值?

A:0.01s B:1.01s

答案是B,现在数据库都实现了MVCC会保留历史版本,为了找到最新的数据会从最新的版本遍历找到最老的版本(可重复读隔离级别)。

测试结果:

# Time: 2025-01-08T12:28:58.505518Z
# User@Host: root[root] @ localhost []  Id:    15
# Query_time: 0.000387  Lock_time: 0.000004 Rows_sent: 1  Rows_examined: 5
SET timestamp=1736339338;
select * from t where id = 1;# Time: 2025-01-08T12:32:38.671135Z
# User@Host: root[root] @ localhost []  Id:    16
# Query_time: 209.297586  Lock_time: 0.000000 Rows_sent: 0  Rows_examined: 250000
SET timestamp=1736339558;
call udata3();# Time: 2025-01-08T12:33:16.075252Z
# User@Host: root[root] @ localhost []  Id:    15
# Query_time: 0.058057  Lock_time: 0.000004 Rows_sent: 1  Rows_examined: 5
SET timestamp=1736339596;
select * from t where id = 3;

可以看到执行查询时间虽然没有1s那么夸张,但是也用了0.058s。也比执行存储过程前的0.0003慢了很多。这种情况也应该记录慢查询日志,但是因为min_examined_row_limit的配置可能不记录日志。

生产建议:min_examined_row_limit不应该在生产环境上设置。

内核改进思路(Mysql官方不提供):

  1. set global log_queries_not_using_indexes_white_user = ‘xxx’ (模拟)

白名单管理,将监控相关的用户查询屏蔽。

  1. 改为 global,session 变量

set global log_queries_not_using_indexes=on 监控应用端:

set log_queries_not_using_indexes=off(模拟)

生产建议:根据业务情况可以先不开,稳定后打开。

慢查询影响性能嘛?

慢查询日志影响性能吗?

A. 影响 B. 不影响

A

执行错误的语句记不记入慢查询日志?

A. 记录 B. 不记录

A

如何验证?

锁等待,A线程开启事务,更新一行。B线程更新同一行,会报错。验证结果:

# Time: 2025-01-08T13:01:37.382271Z
# User@Host: root[root] @ localhost []  Id:    15
# Query_time: 0.000530  Lock_time: 0.000004 Rows_sent: 0  Rows_examined: 5
SET timestamp=1736341297;
update t set c=c+1 where id=3;
# Time: 2025-01-08T13:02:30.110640Z
# User@Host: root[root] @ localhost []  Id:    16
# Query_time: 50.019117  Lock_time: 50.018677 Rows_sent: 0  Rows_examined: 0
SET timestamp=1736341300;
update t set c=c+1 where id=3;

慢查询日志是在语句执行的哪个阶段写入的?

A. 语句执行开始阶段 B. 语句执行结束,发查询结果给客户端前 C. 语句执行结束,发查询结果给客户端后

C

可以使用下面方法测试:

gdb -p <pid of mysqld>
(gdb) b my_error
(gdb) c
root@devops_db 15:07: [test]> select a;

看此时slow log还没有输出 select a 这个语句

结论:slowlog 是在语句结果返回给客户端后再输出的

疑问:那为什么开slow log会影响性能?

因为在记录慢日志时,线程无法处理新来的请求。

怎么减少突发慢查询对系统的影响

  1. 提前发现慢查询

业务回归测试时提前发现。测试环境中使用:set global long_query_time = 0;set global log_slow_extra = on;

  1. 审计日志采集

  2. 分析和预警

怎么判断慢查询语句是否有优化空间?

对比执行过程的消耗,跟输出结果。如创建表并插入数据:

drop table if exists a;create table a(id int primary key AUTO_INCREMENT, c int , d int,e text, index(c))engine=innodb;DROP PROCEDURE IF EXISTS insert_data;-- 创建存储过程
DELIMITER //
CREATE PROCEDURE insert_data()
BEGINDECLARE i INT DEFAULT 1;WHILE i <= 100 DOINSERT INTO a ( c, d, e)SELECT  i, i, REPEAT('a', 16000);SET i = i + 1;END WHILE;
END //
DELIMITER ;-- 调用存储过程来执行插入操作
CALL insert_data();
  • select * from a;

    表本身很大,没有优化空间

  • select * from a where c>10 and c<20 and d>=15;

读了9行,但是只返回了5行。

# User@Host: root[root] @ localhost []  Id:    34
# Query_time: 0.000679  Lock_time: 0.000006 Rows_sent: 5  Rows_examined: 9
SET timestamp=1737638707;
select * from a where c>10 and c<20 and d>=15;

优化语句:

select * from a where id in (select id from a where c>10 and c<20 and d>=15);

慢查询日志:

# Time: 2025-01-23T13:25:41.458971Z
# User@Host: root[root] @ localhost []  Id:    34
# Query_time: 0.000880  Lock_time: 0.000004 Rows_sent: 5  Rows_examined: 14
SET timestamp=1737638741;
select * from a where id in (select id from a where c>10 and c<20 and d>=15);

理论分析,因为e字段笔记大,这里用到了mysql的行外存储(https://www.cnblogs.com/better-farther-world2099/articles/14717436.html),所以第一个语句返回的是9行完整的数据行,再进行d字段的过滤。而第二个语句返回的是9个不完整的的数据行,然后再回表获取5个完整的数据行。

测试结果与实际测试结果不一致,应该是当前数据行的大小还不够大。理论分析是成立的。建立c和d的联合索引应该是更好的,存储层只会给sql层返回5行完整数据。

课堂练习

题目1

RR隔离级别下,表t的建表结构和初始化数据如下:

create table t(id int primary key,c int)engine=innodb;
insert into t values(1,1),(11,11),(21,21);

在会话1 执行如下语句:

begin;
select * from t lock in share mode;

那么,会话2的以下哪些语句会被进入“等待行锁”的状态?

A: insert into t values(15,15);

B: update t set c=c+1 where id=15;

C: delete from t where id=15;

D: alter table t add d int;

A

A会被锁住,RR隔离级别要保证可重复读,会加间隙锁

B、C不会,没有相关行,不会锁任何行

D也不会,因为D需要的是表结构锁。

题目2

表t1使用InnoDB引擎,以下哪个场景会导致语句Q1: select * from t1 limit 1 被堵住?

A:另一个线程在Q1执行之前,执行了 alter table t1 add index(f1),当前处于“拷贝数据到临时表”阶段

B:另一个线程在Q1执行之前,执行了 truncate table t1,当前处于waiting for metadata lock阶段

C:另一个线程在Q1执行之前,执行了 delete from t1,且未执行完成

D:另一个线程在Q1执行之前,执行了 lock table t1 write,并执行完成

A:Mysql实现在线加索引

B:

MDL机制简介

MDL是 MySQL 为了保证数据定义语言(DDL)和数据操纵语言(DML)操作之间的数据一致性而引入的一种锁机制。当一个事务对表执行 DDL 操作(如 TRUNCATE TABLE)时,会获取该表的元数据写锁;而当执行DML操作(如SELECT)时,会获取该表的元数据读锁。

具体阻塞原因

TRUNCATE TABLE 操作:TRUNCATE TABLE 是一个 DDL 操作,执行时会获取表 t1 的元数据写锁。元数据写锁是排他锁,意味着在持有该锁期间,其他事务无法获取该表的任何元数据锁(包括读锁和写锁)。
SELECT 操作:SELECT * FROM t1 LIMIT 1 是一个 DML 操作,执行时需要获取表 t1 的元数据读锁。但由于之前的 TRUNCATE TABLE 操作已经持有了元数据写锁,所以 SELECT 操作无法获取到元数据读锁,只能进入等待状态,即 waiting for metadata lock。

C:不影响Q1的第一行数据的读取

D:也会阻塞,因为加的是表的排他锁。

相关文章:

MySQL训练营-慢查询诊断问题

慢查询相关参数和建议配置 slow_query_log long_query_time 日志开关&#xff0c;是否记慢查询日志以及超过多长时间判定为慢查询。 查看参数设置&#xff1a; SHOW VARIABLES LIKE ‘slow_query_log’;SHOW VARIABLES LIKE ‘long_query_time’; 实践建议&#xff1a; …...

如何给自己的域名配置免费的HTTPS How to configure free HTTPS for your domain name

今天有小伙伴给我发私信&#xff0c;你的 https 到期啦 并且随手丢给我一个截图。 还真到期了。 javapub.net.cn 这个网站作为一个用爱发电的编程学习网站&#xff0c;用来存编程知识和面试题等&#xff0c;平时我都用业余时间来维护&#xff0c;并且还自费买了服务器和阿里云…...

.Net Core微服务入门全纪录(六)——EventBus-事件总线

系列文章目录 1、.Net Core微服务入门系列&#xff08;一&#xff09;——项目搭建 2、.Net Core微服务入门全纪录&#xff08;二&#xff09;——Consul-服务注册与发现&#xff08;上&#xff09; 3、.Net Core微服务入门全纪录&#xff08;三&#xff09;——Consul-服务注…...

1/20赛后总结

1/20赛后总结 T1『讨论区管理员』的旅行 - BBC编程训练营 算法&#xff1a;IDA* 分数&#xff1a;0 damn it! Ac_code走丢了~~&#xff08;主要是没有写出来&#xff09;~~ T2华强买瓜 - BBC编程训练营 算法&#xff1a;双向DFS或者DFS剪枝 分数&#xff1a;0 Ac_code…...

PVE 虚拟机安装 Debian 无图形化界面服务器

Debian 安装 Debian 镜像下载 找一个Debian镜像服务器&#xff0c;根据需要的版本和自己硬件选择。 iso-cd/&#xff1a;较小&#xff0c;仅包含安装所需的基础组件&#xff0c;可能需要网络访问来完成安装。有镜像 debian-12.9.0-amd64-netinst.isoiso-dvd/&#xff1a;较…...

第17篇:python进阶:详解数据分析与处理

第17篇&#xff1a;数据分析与处理 内容简介 本篇文章将深入探讨数据分析与处理在Python中的应用。您将学习如何使用pandas库进行数据清洗与分析&#xff0c;掌握matplotlib和seaborn库进行数据可视化&#xff0c;以及处理大型数据集的技巧。通过丰富的代码示例和实战案例&am…...

三天急速通关Java基础知识:Day1 基本语法

三天急速通关JAVA基础知识&#xff1a;Day1 基本语法 0 文章说明1 关键字 Keywords2 注释 Comments2.1 单行注释2.2 多行注释2.3 文档注释 3 数据类型 Data Types3.1 基本数据类型3.2 引用数据类型 4 变量与常量 Variables and Constant5 运算符 Operators6 字符串 String7 输入…...

Python的进程和线程

ref 接受几个设定: 进程是一家almost密不透风的公司,缅甸KK园区 线程里面工作的…人 进程**[园区]**内公共资源对于进程来说,可以共享. 别的园区[进程],一般不能和自己的园区共享人员资源,除非… 好的,现在再接受设定: 单个CPU在任一时刻只能执行单个线程&#xff0c;只有…...

【Mysql】记录锁、间隙锁和临键锁的区别

InnoDB通过MVCCNext-Key Locks&#xff0c;解决了可重复读的事务隔离级别出现的幻读问题。 记录锁 记录锁就是为某行数据进行加锁&#xff0c;它封锁该行的索引记录 SELECT * FROM table WHERE id 1 FOR UPDATE id为1的记录行会被锁住。需要注意的的&#xff1a;id列必须为…...

神经网络|(二)sigmoid神经元函数

【1】引言 在前序学习进程中&#xff0c;我们已经了解了基本的二元分类器和神经元的构成&#xff0c;文章学习链接为&#xff1a; 神经网络|(一)加权平均法&#xff0c;感知机和神经元-CSDN博客 在此基础上&#xff0c;我们认识到神经元本身在做二元分类&#xff0c;是一种非…...

w-form-select.vue(自定义下拉框组件)(与后端字段直接相关性)

文章目录 1、w-form-select.vue 组件中每个属性的含义2、实例3、源代码 1、w-form-select.vue 组件中每个属性的含义 好的&#xff0c;我们来详细解释 w-form-select.vue 组件中每个属性的含义&#xff0c;并用表格列出它们是否与后端字段直接相关&#xff1a; 属性解释表格&…...

【JVM】垃圾收集器详解

你将学到 1. Serial 收集器 2. ParNew 收集器 3. Parallel Scavenge 收集器 4. Serial Old 收集器 5. Parallel Old 收集器 6. CMS 收集器 7. G1 收集器 在 Java 中&#xff0c;垃圾回收&#xff08;GC&#xff09;是自动管理内存的一个重要机制。HotSpot JVM 提供了多种…...

python创建一个httpServer网页上传文件到httpServer

一、代码 1.server.py import os from http.server import SimpleHTTPRequestHandler, HTTPServer import cgi # 自定义请求处理类 class MyRequestHandler(SimpleHTTPRequestHandler):# 处理GET请求def do_GET(self):if self.path /:# 响应200状态码self.send_response(2…...

【Maui】提示消息的扩展

文章目录 前言一、问题描述二、解决方案三、软件开发&#xff08;源码&#xff09;3.1 消息扩展库3.2 消息提示框使用3.3 错误消息提示使用3.4 问题选择框使用 四、项目展示 前言 .NET 多平台应用 UI (.NET MAUI) 是一个跨平台框架&#xff0c;用于使用 C# 和 XAML 创建本机移…...

租车骑绿岛

租车骑绿岛 真题目录: 点击去查看 E 卷 100分题型 题目描述 部门组织绿岛骑行团建活动。租用公共双人自行车&#xff0c;每辆自行车最多坐两人&#xff0c;最大载重M。给出部门每个人的体重&#xff0c;请问最多需要租用多少双人自行车。 输入描述 第一行两个数字m、n&…...

Pytorch - YOLOv11自定义资料训练

►前言 本篇将讲解目前最新推出的YOLOv11搭配Roboflow进行自定义资料标注训练流程&#xff0c;透过Colab上进行实作说明&#xff0c;使大家能够容易的了解YOLOv11的使用。 ►YOLO框架下载与导入 ►Roboflow的资料收集与标注 进行自定义资料集建置与上传 透过Roboflow工具进行…...

微服务与docker

准备工作 在课前资料中给大家提供了黑马商城项目的资料,我们需要先导入这个单体项目。不过需要注意的是,本篇及后续的微服务学习都是基于Centos7系统下的Docker部署,因此你必须做好一些准备: Centos7的环境及一个好用的SSH客户端装好Docker会使用Docker如果是学习过上面Doc…...

1.23 消息队列

使用消息队列&#xff0c;实现两个终端相互聊天 程序代码&#xff1a; w1.c #include <stdio.h> #include <string.h> #include <unistd.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h&g…...

【华为路由的arp配置】

华为路由的arp配置 ARP&#xff1a;IP地址与MAC地址的映射。 R1: g0/0/0:10.1.1.254/24 g0/0/1:10.1.2.254/24 PC1: 10.1.1.1/16 PC2: 10.1.1.2/16 PC3: 10.1.2.3/16 动态ARP 查看PC1的arp表&#xff0c;可以看到&#xff0c;列表为空。 查看R1的arp表 在PC3上ping命令测…...

绘制决策树的尝试1

代码复制 import pydotplus 复制 - 这一行代码用于导入pydotplus模块&#xff0c;这是一个用来在Python中创建图形的工具。2. python from IPython.display import Image 这一行代码用于从IPython显示模块中导入Image类&#xff0c;它允许我们在Jupyter笔记本中显示图像。…...

概率论里的特征函数,如何用卷积定理去理解

概率论里的特征函数&#xff0c;如何用卷积定理去理解_哔哩哔哩_bilibili...

Spring 是如何解决循环依赖问题

Spring 框架通过 三级缓存 机制来解决循环依赖问题。循环依赖是指两个或多个 Bean 相互依赖&#xff0c;形成一个闭环&#xff0c;例如 Bean A 依赖 Bean B&#xff0c;而 Bean B 又依赖 Bean A。Spring 通过提前暴露未完全初始化的 Bean 来解决这个问题。 以下是 Spring 解决…...

Linux 目录操作详解

Linux目录操作详解 1. 获取当前工作目录1.1 getcwd()1.2 get_current_dir_name() 2. 切换工作目录2.1 chdir() 3. 创建和删除目录3.1 mkdir()3.2 rmdir() 4. 获取目录中的文件列表4.1 opendir() 打开目录4.2 readdir() 读取目录内容4.3 closedir() 关闭目录 5. dirent 结构体6.…...

Elasticsearch的经典面试题及详细解答

以下是一些Elasticsearch的经典面试题及详细解答&#xff1a; 一、基础概念与原理 什么是Elasticsearch&#xff1f; 回答&#xff1a; Elasticsearch是一个基于Lucene的分布式搜索引擎&#xff0c;提供了RESTful API&#xff0c;支持多租户能力。它能够快速、近实时地存储、搜…...

Linux-arm(1)ATF启动流程

Linux-arm(1)ATF启动流量 Author&#xff1a;Once Day Date&#xff1a;2025年1月22日 漫漫长路有人对你微笑过嘛… 全系列文章可查看专栏: Linux实践记录_Once_day的博客-CSDN博客 参考文档&#xff1a; ARM Trusted Firmware分析——启动、PSCI、OP-TEE接口 Arnold Lu 博…...

C#编程:List.ForEach与foreach循环的深度对比

在C#中&#xff0c;List<T>.ForEach 方法和传统的 foreach 循环都用于遍历列表中的元素并对每个元素执行操作&#xff0c;但它们之间有一些关键的区别。 List<T>.ForEach 方法 方法签名&#xff1a;public void ForEach(Action<T> action)类型&#xff1a;…...

C语言文件操作:标准库与系统调用实践

目录 1、C语言标准库文件操作 1.1.题目要求&#xff1a; 1.2.函数讲解&#xff1a; fopen 函数原型 参数 常用的打开模式 返回值 fwrite函数 函数原型 参数 返回值 注意事项 fseek函数 函数原型 参数 返回值 fread函数 函数原型 参数 返回值 fclose 函数…...

代码随想录 栈与队列 test 7

347. 前 K 个高频元素 - 力扣&#xff08;LeetCode&#xff09; 首先想到哈希&#xff0c;用key来存元素&#xff0c;value来存出现次数&#xff0c;最后进行排序&#xff0c;时间复杂度约为o(nlogn)。由于只需求前k个&#xff0c;因此可以进行优化&#xff0c;利用堆来维护这…...

C语言练习(21)

有一行电文&#xff0c;已按下面规律译成密码&#xff1a; A→Za→Z B→Yb→y C→Xc→X 即第1个字母变成第26个字母&#xff0c;第2个字母变成第25个字母&#xff0c;第i个字母变成第&#xff08;26-i十1&#xff09;个字母。非字母字符不变。假如已知道密码是Umtorhs&…...

智能手机“混战”2025:谁将倒下而谁又将突围?

【潮汐商业评论原创】 “去年做手机比较艰难&#xff0c;几乎每个品牌都在调价、压货&#xff0c;像华为这种以前都不给我们分货的厂商&#xff0c;也开始成为我的主要库存。不过今年开头比较好&#xff0c;20号国补一开始&#xff0c;店里的人流和手机销量就明显涨了不少&…...