PostgreSQL 元组统计与 pgstattuple 优化

news2025/1/21 11:29:57

在这里插入图片描述

第1章 简介
1.1 参考文档
https://www.percona.com/blog/postgresql-tuple-level-statistics-with-pgstattuple/
1.2 关于pgstattuble
由于Postgres表膨胀会降低数据库性能,因此我们可以通过消除表膨胀来提高其性能。我们可以使用pgstattuple扩展来识别膨胀的表。
这个扩展提供了几个函数来获取元级统计信息。因为pgstattuple函数产生大量的页面级信息,所以默认情况下对它们的访问是有限的。默认情况下,只有pg_stat_scan_tables角色有能力执行pgstattuple函数。
使用pgstattuple函数,我们可以列出死元组百分比高的表,并运行手动VACUUM来回收死元组占用的空间。
第2章 pgstattuble 插件安装 & 测试
2.1 PG15 & pg_tde编译
2.1.1 操作系统信息
我的操作系统是CentOS 8.5,其内核信息如下
[root@pg-server01 ~]# uname -a
Linux pg-server01 4.18.0-348.el8.x86_64 #1 SMP Tue Oct 19 15:14:17 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
[root@pg-server01 ~]# cat /etc/redhat-release
CentOS Linux release 8.5.2111

2.1.2 配置阿里云 yum 源

参考如下链接 # 操作步骤略

https://www.cnblogs.com/hunttown/p/16287988.html

2.1.3 安装相关依赖
yum -y install gcc readline readline-devel zlib-devel openssl-devel libicu-devel make json-c-devel git wget

2.1.4 下载PG15 源码&编译
mkdir -p /data/software/pg/;
cd /data/software/pg/;
wget https://ftp.postgresql.org/pub/source/v15.4/postgresql-15.4.tar.gz

tar -xvf postgresql-15.4.tar.gz;
cd ./postgresql-15.4;
./configure
–prefix=/opt/pgsql
–with-openssl

make && make install

2.1.5 编译 pgstattuble 插件
cd /data/software/pg/postgresql-15.4/;
cd ./contrib/pgstattuple;
make && make install

2.1.6 编译 btree_gin 插件
cd /data/software/pg/postgresql-15.4/;
cd ./contrib/btree_gin;
make && make install

2.2 安装配置PG
2.2.1 添加 postgres用户并授权
useradd postgres

chown -R postgres:postgres /home/postgres;
chown -R postgres:postgres /opt/pgsql;

2.2.2 配置环境变量
vi /etc/profile # 添加如下内容

pg env

export PGHOME=/opt/pgsql
export PATH= P A T H : PATH: PATH:PGHOME/bin

2.2.3 初始化数据库

1. 创建相关目录,并授权

mkdir -p /data/pgdata/;
chown postgres:postgres /data/pgdata/;

2. 切换到 postgres 用户

su - postgres

3. 初始化数据库

initdb -D /data/pgdata/ -U postgres --encoding=UTF8 --lc-collate=en_US.UTF-8 --lc-ctype=en_US.UTF-8

4. 启动数据库

pg_ctl -D /data/pgdata/ start

2.3 测试 pgstattuble 插件

2.3.1 开启 pgstattuble 插件
su - postgres
psql
select * from pg_available_extensions where name=‘pgstattuple’;
create extension pgstattuple;
select * from pg_available_extensions where name=‘pgstattuple’;

我的操作输出类似如下:

[root@pg-server01 opt]# su - postgres
[postgres@pg-server01 ~]$ psql
psql (15.4)
Type “help” for help.

postgres=# select * from pg_available_extensions where name=‘pgstattuple’;
name | default_version | installed_version | comment
-------------±----------------±------------------±----------------------------
pgstattuple | 1.5 | | show tuple-level statistics
(1 row)

postgres=# create extension pgstattuple;
CREATE EXTENSION
postgres=# select * from pg_available_extensions where name=‘pgstattuple’;
name | default_version | installed_version | comment
-------------±----------------±------------------±----------------------------
pgstattuple | 1.5 | 1.5 | show tuple-level statistics
(1 row)

postgres=#

注意:默认情况下,只有超级用户可以访问 pgstattuple 函数; 但是,您可以通过将 pg_stat_scan_tables 角色授予非超级用户来授予非超级用户访问权限。

grant pg_stat_scan_tables to ;

2.3.2 pgstattuble测试前准备
接下来,在使用 pgstattuple 函数之前,让我们创建一个表和索引来进行演示。
psql
create table workshop (jobno int);
insert into workshop values (generate_series(1,80000));
create index workshop_index on workshop (jobno);

我的操作输出类似如下:

[postgres@pg-server01 ~]$ psql
psql (15.4)
Type “help” for help.
postgres=# create table workshop (jobno int);
CREATE TABLE
postgres=# insert into workshop values (generate_series(1,80000));
INSERT 0 80000
postgres=# create index workshop_index on workshop (jobno);
CREATE INDEX
postgres=#

2.3.3 pgstattuple 功能
2.3.3.1 pgstattuple(regclass)
这个函数返回一个关系的物理长度,“死亡”元组的百分比,以及其他信息。这可以帮助用户确定是否需要真空。参数是目标关系的名称(可选的模式限定)或OID。例如:

显示 pg_catalog.pg_proc 表 的元组统计信息。

SELECT * FROM pgstattuple(‘pg_catalog.pg_proc’);

显示 workshop 表 的元组统计信息。

SELECT * FROM pgstattuple(‘workshop’);

注意: Pgstattuple 只获得关系上的读锁。因此,pgstattuple 输出并不表示瞬时快照。并发更新将改变 pgstattuple 的输出。

我的操作输出类似如下:

postgres=# \x
Expanded display is on.
postgres=# SELECT * FROM pgstattuple(‘pg_catalog.pg_proc’);
-[ RECORD 1 ]------±------
table_len | 786432
tuple_count | 3253
tuple_len | 731586
tuple_percent | 93.03
dead_tuple_count | 12
dead_tuple_len | 4790
dead_tuple_percent | 0.61
free_space | 22564
free_percent | 2.87

postgres=# SELECT * FROM pgstattuple(‘workshop’);
-[ RECORD 1 ]------±-------
table_len | 2899968
tuple_count | 80000
tuple_len | 2240000
tuple_percent | 77.24
dead_tuple_count | 0
dead_tuple_len | 0
dead_tuple_percent | 0
free_space | 10056
free_percent | 0.35

2.3.3.2 下面是pgstattuple输出列及其说明

| 字段名 | 类型 | 说明 |

| table_len | bigint | 物理关系长度,以字节为单位 |

| tuple_count | bigint | 活动元组的数量 |

| tuple_len | bigint | 活元组的总长度(以字节为单位) |

| tuple_percent | float8 | 活元组的百分比 |

| dead_tuple_count | bigint | 无效(死)元组的数量 |

| dead_tuple_len | bigint | 无效(死)元组的总长度(以字节为单位) |

| dead_tuple_percent | float8 | 无效(死)元组的百分比 |

| free_space | bigint | 总可用空间(以字节为单位) |

| free_percent | float8 | 可用空间百分比 |

2.3.3.3 让我们在删除或更新行时检查元组统计信息

1. 下面是引用的当前元组统计信息。

postgres=# SELECT * FROM pgstattuple(‘workshop’);
-[ RECORD 1 ]------±-------
table_len | 2899968
tuple_count | 80000
tuple_len | 2240000
tuple_percent | 77.24
dead_tuple_count | 0
dead_tuple_len | 0
dead_tuple_percent | 0
free_space | 10056
free_percent | 0.35

2. Delete the few ROWS from the table.

DELETE FROM workshop WHERE jobno % 8 = 0;

3. 在下面的输出中,dead_tuple_count 显示 Postgres 将这些行标记为已删除,但没有从表中删除它们,因为删除这些行后表的长度是相同的。

postgres=# SELECT * FROM pgstattuple(‘workshop’);
-[ RECORD 1 ]------±-------
table_len | 2899968
tuple_count | 70000
tuple_len | 1960000
tuple_percent | 67.59
dead_tuple_count | 10000
dead_tuple_len | 280000
dead_tuple_percent | 9.66
free_space | 10056
free_percent | 0.35

2.3.3.4 在表上执行VACUUM命令

1. 运行普通VACUUM后,我们看到:

vacuum workshop;
SELECT * FROM pgstattuple(‘workshop’);

2. 在运行VACUUM FULL命令后,我们可以看到 table_len 减少了。显示运行VACUUM FULL后,os级空间被回收。

vacuum full workshop;
SELECT * FROM pgstattuple(‘workshop’);

我的操作输出类似如下:

postgres=# vacuum workshop;
VACUUM
postgres=# SELECT * FROM pgstattuple(‘workshop’);
-[ RECORD 1 ]------±-------
table_len | 2899968
tuple_count | 70000
tuple_len | 1960000
tuple_percent | 67.59
dead_tuple_count | 0
dead_tuple_len | 0
dead_tuple_percent | 0
free_space | 330412
free_percent | 11.39

postgres=# vacuum full workshop;
VACUUM
postgres=# SELECT * FROM pgstattuple(‘workshop’);
-[ RECORD 1 ]------±-------
table_len | 2539520
tuple_count | 70000
tuple_len | 1960000
tuple_percent | 77.18
dead_tuple_count | 0
dead_tuple_len | 0
dead_tuple_percent | 0
free_space | 10840
free_percent | 0.43

2.3.3.5 pgstattuple 查询检查表膨胀

1. 我们可以使用下面的查询列出死元组百分比高的表。

注意:如果pg16.0 版本的话, 下面查询语句将报错 “ERROR: only heap AM is supported”,是pg16 的一个 bug,参考:https://www.postgresql.org/message-id/202309200826.z3ckjb4g7auj%40alvherre.pgsql

select relname,(pgstattuple(oid)).dead_tuple_percent
from pg_class
where relkind = ‘r’
order by dead_tuple_percent desc limit 10;

我的查询输出类似如下:

postgres=# \x
Expanded display is off.
postgres=#
postgres=# select relname,(pgstattuple(oid)).dead_tuple_percent
postgres-# from pg_class
postgres-# where relkind = ‘r’
postgres-# order by dead_tuple_percent desc limit 10;
relname | dead_tuple_percent
-----------------------±-------------------
pg_init_privs | 2.56
pg_extension | 1.28
pg_class | 0.75
pg_proc | 0.61
pg_depend | 0.47
pg_statistic | 0.36
pg_type | 0.29
pg_attribute | 0.06
pg_user_mapping | 0
pg_statistic_ext_data | 0
(10 rows)

2. 下面的查询将向您详细显示死元组百分比高的表的元组统计信息。

SELECT relname, oid, relowner,
(pgstattuple(oid)).*
FROM pg_class
WHERE relkind = ‘r’ order by dead_tuple_percent desc limit 5;

我的操作输出类似如下:

postgres=# SELECT relname, oid, relowner,
postgres-# (pgstattuple(oid)).*
postgres-# FROM pg_class
postgres-# WHERE relkind = ‘r’ order by dead_tuple_percent desc limit 5;
-[ RECORD 1 ]------±-------------
relname | pg_init_privs
oid | 3394
relowner | 10
table_len | 24576
tuple_count | 222
tuple_len | 17316
tuple_percent | 70.46
dead_tuple_count | 9
dead_tuple_len | 630
dead_tuple_percent | 2.56
free_space | 4568
free_percent | 18.59
-[ RECORD 2 ]------±-------------
relname | pg_extension
oid | 3079
relowner | 10
table_len | 8192
tuple_count | 2
tuple_len | 210
tuple_percent | 2.56
dead_tuple_count | 1
dead_tuple_len | 105
dead_tuple_percent | 1.28
free_space | 7816
free_percent | 95.41
-[ RECORD 3 ]------±-------------
relname | pg_class
oid | 1259
relowner | 10
table_len | 114688
tuple_count | 412
tuple_len | 79912
tuple_percent | 69.68
dead_tuple_count | 5
dead_tuple_len | 860
dead_tuple_percent | 0.75
free_space | 28656
free_percent | 24.99
-[ RECORD 4 ]------±-------------
relname | pg_proc
oid | 1255
relowner | 10
table_len | 786432
tuple_count | 3253
tuple_len | 731586
tuple_percent | 93.03
dead_tuple_count | 12
dead_tuple_len | 4790
dead_tuple_percent | 0.61
free_space | 22564
free_percent | 2.87
-[ RECORD 5 ]------±-------------
relname | pg_depend
oid | 2608
relowner | 10
table_len | 114688
tuple_count | 1854
tuple_len | 90846
tuple_percent | 79.21
dead_tuple_count | 11
dead_tuple_len | 539
dead_tuple_percent | 0.47
free_space | 2288
free_percent | 1.99

2.3.4 pgstatindex(regclass)

2.3.4.1 这个函数返回一条显示b树索引信息的记录

1. 例如

SELECT * FROM pgstatindex (‘workshop_index’);

我的查询输出类似如下:

postgres=# SELECT * FROM pgstatindex (‘workshop_index’);
-[ RECORD 1 ]------±-------
version | 4
tree_level | 1
index_size | 1589248
root_block_no | 3
internal_pages | 1
leaf_pages | 192
empty_pages | 0
deleted_pages | 0
avg_leaf_density | 89.74
leaf_fragmentation | 0

2.3.4.2 输出列及其描述

| 字段名 | 类型 | 说明 |

| version | integer | b树版本号 |

| tree_level | integer | 根页面的树级别 |

| index_size | bigint | 总索引大小(以字节为单位) |

| root_block_no | bigint | 根页面的位置(如果没有则为零) |

| internal_pages | bigint | “内部”(上层)页面的数量 |

| leaf_pages | bigint | 叶子结点的个数 |

| empty_pages | bigint | 空页的个数 |

| deleted_pages | bigint | 删除页面数 |

2.3.5 pgstatginindex(regclass)

2.3.5.1 这个函数返回一条显示GIN索引信息的记录
GIN索引参考:https://pganalyze.com/blog/gin-index

1. 例1

1.1 前期 建表、索引等相关 SQL

– DROP TABLE IF EXISTS test;
CREATE TABLE test (
id bigserial PRIMARY KEY,
data jsonb
);
INSERT INTO test(data) VALUES (‘{“field”: “value1”}’);
INSERT INTO test(data) VALUES (‘{“field”: “value2”}’);
INSERT INTO test(data) VALUES (‘{“other_field”: “value42”}’);
– CREATE INDEX ON test USING gin(data jsonb_path_ops);
CREATE INDEX test_data_gin_idx ON test USING gin(data jsonb_path_ops);
EXPLAIN SELECT * FROM test WHERE data @> ‘{“field”: “value1”}’;

1.2 测量GIN挂起列表开销和大小

1.2.1 首先,我们可以将pgstatginindex函数与类似psql的\watch命令一起使用,以密切关注特定索引

SELECT * FROM pgstatginindex(‘test_data_gin_idx’);

我的操作输出类似如下:

postgres=# SELECT * FROM pgstatginindex(‘test_data_gin_idx’);
version | pending_pages | pending_tuples
---------±--------------±---------------
2 | 0 | 0
(1 row)

注意:如果在创建索引的时候不指定”索引名称”,类似语句 “CREATE INDEX ON test USING gin(data jsonb_path_ops);”,需要先执行类似如下查询,查到其信息(包括索引名称),再根据其查询到的索引名称,将其传参到上面查询(当然:其实如果不指定索引名称的话,其索引命名也是有规律的)。

select *
from pg_indexes
where tablename = ‘test’;

1.2.2 其次,如果您运行自己的数据库服务器,您可以使用 “perf”动态跟踪点 来测量对 Postgres 中 ginInsertCleanup 函数的调用

dnf install perf
sudo perf probe -x /opt/pgsql/bin/postgres ginInsertCleanup
sudo perf stat -a -e probe_postgres:ginInsertCleanup – sleep 60

2. 例2

2.1 前期 建表、索引等相关 SQL

– DROP TABLE IF EXISTS records;
CREATE TABLE records (
id bigserial PRIMARY KEY,
customer_id int4,
data jsonb
);

CREATE EXTENSION btree_gin;
CREATE INDEX ON records USING gin (data, customer_id);

EXPLAIN SELECT * FROM records WHERE customer_id = 123 AND data @> ‘{ “location”: “New York” }’;
EXPLAIN SELECT * FROM records WHERE customer_id = 123;

select *
from pg_indexes
where tablename = ‘records’;

注意:如下查询中的 “records_data_customer_id_idx” 就是 上面查询结果的 indexname 字段值

SELECT * FROM pgstatginindex(‘records_data_customer_id_idx’);

3. pganalyze索引顾问中的GIN索引支持

注意:在 https://pganalyze.com/index-advisor 页面测试

现在,我们已经向pganalyze index Advisor添加了对GIN和GIST索引建议的初始支持

下面是一个为现有的tsvector列推荐GIN索引的示例

CREATE TABLE post(
id SERIAL PRIMARY KEY,
title TEXT NOT NULL,
content TEXT NOT NULL,
author_id INT NOT NULL,
language text NOT NULL DEFAULT(‘english’),
document tsvector
);

SELECT id, title FROM post
WHERE post.document @@ to_tsquery(‘english’, ‘Endangered & Species’)
ORDER BY ts_rank(post.document, to_tsquery(‘english’, ‘Endangered & Species’)) DESC

2.3.6 pgstathashindex(regclass)

2.3.6.1 参考文档
https://postgrespro.com/blog/pgsql/4161321
https://postgrespro.com/docs/postgrespro/15/demodb-bookings-installation

2.3.6.2 测试

1. 例如

1.1 前期准备

1.1.1 从 https://postgrespro.com/docs/postgrespro/15/demodb-bookings-installation 下载 demo-small-en.zip 文件到 /data/software/pg/demo-data/ 并解压(解压后生成 demo-small-en-20170815.sql 文件

1.1.2 postgres 用户下执行如下命令

cd /data/software/pg/demo-data/;
psql -f demo-small-en-20170815.sql

1.2 为 demo 数据库的 flights 表的 flight_no 字段 创建 hash 索引 & 相关测试

1.2.1 创建 hash 索引

psql
\c demo
create index on flights using hash(flight_no);

1.2.2 创建 pgstattuple 扩展

因为切换到 demo 数据库了,所以需要重新创建 pgstattuple 扩展

create extension pgstattuple;
select * from pg_available_extensions where name=‘pgstattuple’;

1.2.3 查询刚才创建的索引

select *
from pg_indexes
where tablename = ‘flights’;

1.2.4 查看相关 sql 执行计划 & 查看相关索引信息

explain (costs off) select * from flights where flight_no = ‘PG0001’;
select * from pgstathashindex(‘flights_flight_no_idx’);

最后:我的查询输出类似如下

demo=# explain (costs off) select * from flights where flight_no = ‘PG0001’;
QUERY PLAN

Bitmap Heap Scan on flights
Recheck Cond: (flight_no = ‘PG0001’::bpchar)
-> Bitmap Index Scan on flights_flight_no_idx
Index Cond: (flight_no = ‘PG0001’::bpchar)
(4 rows)

demo=# select * from pgstathashindex(‘flights_flight_no_idx’);
version | bucket_pages | overflow_pages | bitmap_pages | unused_pages | live_items | dead_items | free_percent
---------±-------------±---------------±-------------±-------------±-----------±-----------±------------------
4 | 128 | 13 | 1 | 0 | 33121 | 0 | 42.36979656038809
(1 row)

#PG数据库工程师的摇篮#PostgreSQL考试#PostgreSQL培训
在这里插入图片描述

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

DenseNet分类网络改进(添加SPP)--亲测有效

最近,我在做多分类问题。在针对基模型的选择中,我使用了DenseNet作为基本模型。我在阅读论文时,遇到了一种改进方式: 如上图所示,在全连接层之前引入SPP模块: 代码如下: SPP模块代码&#x…

VMware 虚拟机 电脑重启后 NAT 模式连不上网络问题修复

问题描述: 昨天 VMware 安装centos7虚拟机,网络模式配置的是NAT模式,配置好后,当时能连上外网,今天电脑重启后,发现连不上外网了 检查下各个配置,都没变动,突然就连不上了 网上查了…

Flink Flink数据写入Kafka

一、环境准备 flink 1.14写入Kafka&#xff0c;首先在pom.xml文件中导入相关依赖 <properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><flink.version>1.14.6</flink.version><spark.version>2.4.3</spa…

MySQL联合查询、最左匹配、范围查询导致失效

服务器版本 客户端&#xff1a;navicat premium16.0.11 联合索引 假设有如下表 联合索引就是同时把多列设成索引&#xff0c;如(empno&#xff0c;ename)在查询的时候就会先按照empno进行查询&#xff0c;再按照ename进行查询其中empno是全局有序&#xff0c;ename是局部有…

java数字千分位格式转换

java数字千分位格式转换 public static void main(String[] args) {System.out.println(thousandsSeparator("123123131"));}public static String thousandsSeparator(String value) {if (isNotNull(value)) {String[] arr value.split("");for (int i …

Kotlin Flow 操作符

前言 Kotlin 拥有函数式编程的能力&#xff0c;使用Kotlin开发&#xff0c;可以简化开发代码&#xff0c;层次清晰&#xff0c;利于阅读。 然而Kotlin拥有操作符很多&#xff0c;其中就包括了flow。Kotlin Flow 如此受欢迎大部分归功于其丰富、简洁的操作符&#xff0c;巧妙使…

top K问题(C语言)

目录 前言 top K问题 模拟数据 建堆 验证&#xff08;简单了解即可&#xff09; 最终代码 调试部分 前言 在大小堆的实现&#xff08;C语言&#xff09;中我们讨论了堆的实际意义&#xff0c;在看了就会的堆排序&#xff08;C语言&#xff09;中我们完成了堆排序&#…

MYSQL全语法速查(含示例)

文章目录 1.从简单的查询开始查找所有记录(SELECT *)查找记录中的所有登录名(SELECT)查找登录名为admin的密码(WHERE)查找电话号码非空的记录(IS NOT NULL)查找所在城市为北京或者用户名字是李四的记录(OR)查找所在城市为北京并且用户名字是张三的记录(AND)查找用户名字是李四或…

6个实用又好用的交互原型工具!

在 UI/UX 设计中&#xff0c;原型设计是至关重要的一步。正如用户体验中的其它环节一样&#xff0c;有无数的交互原型工具可以帮助你完成原型设计。市场上有太多的交互原型工具&#xff0c;如果你不知道选择哪一种&#xff0c;那么我们将为你介绍 6 个实用又好用的交互原型工具…

C++ day56 两个字符串的删除操作 编辑距离

题目1&#xff1a;583 两个字符串的删除操作 题目链接&#xff1a;两个字符串的删除操作 对题目的理解 返回使两个单词word1和word2相同的最少删除多少个元素&#xff0c;两个单词至少包含一个字母&#xff0c;且仅包含小写字母 思路1&#xff1a;这道题与昨天的不同子序列…

Dagger2使用

在android引入Dagger2库 //引入Dagger2implementation("com.google.dagger:dagger:2.48.1")annotationProcessor ("com.google.dagger:dagger-compiler:2.48.1") 构造器注入 创建一个类 public class Car {//在构造器上面添加dagger的Inject即可Injectp…

现代雷达车载应用——第2章 汽车雷达系统原理 2.1节

经典著作&#xff0c;值得一读&#xff0c;英文原版下载链接【免费】ModernRadarforAutomotiveApplications资源-CSDN文库。 2.1 基本雷达功能 雷达系统通过天线或天线阵列向空间辐射电磁能量。辐射的电磁能量“照亮”周围的目标。“被照亮”的目标拦截一些辐射能量&#xff0…

二十章总结

20.1线程介绍 世间有很多工作都是可以同时完成的。例如&#xff0c;人体可以同时进行呼吸、血液循环、思考问题等活动&#xff1b;用户既可以使用计算机听歌&#xff0c;也可以使用它打印文件。同样&#xff0c;计算机完全可以将多种活动同时进行&#xff0c;这种思想放在 Jav…

配置主机与外网时间服务器同步时间

目录 NTP服务简介 时间管理命令 第一步&#xff1a;更改当前主机所在地的时间 方法一&#xff1a;使用tzselect命令查询需要的时区 1、使用tzselect命令查询需要的时区 2、添加变量到 ~/.bash_profile 文件中&#xff0c;即追加类似的内容&#xff1a; 3、重新连接一个…

Flink(九)【时间语义与水位线】

前言 2023-12-02-20:05&#xff0c;终于写完啦&#xff0c;最近状态不错。刚写完又收到了她的消息哈哈哈哈&#xff0c;开心。 再去全力打拼一次&#xff0c;奋战一场&#xff0c;就算最后打了败仗也无所谓&#xff0c;至少你留下了足迹。 《解忧杂货店》 1、时间语义 …

团队git操作流程

项目的开发要求&#xff1a;&#xff08;1&#xff09;项目组厉员代码提交不少于20次 &#xff08;2&#xff09;项目组厉员每天提交不少于20次 &#xff08;3&#xff09;企业项目开发代码的每天的提交一般提交3-5次 &#xff08;4&#xff09;代码仓库的管理 git的基础操作流…

【CSP】202305-1_重复局面Python实现

文章目录 [toc]试题编号试题名称时间限制内存限制题目背景问题描述输入格式输出格式样例输入样例输出样例说明子任务提示Python实现 试题编号 202305-1 试题名称 重复局面 时间限制 1.0s 内存限制 512.0MB 题目背景 国际象棋在对局时&#xff0c;同一局面连续或间断出现3次或3…

会声会影2024软件还包含了视频教学以及模板素材

会声会影2024中文版是一款加拿大公司Corel发布的视频编软件。会声会影2024官方版支持视频合并、剪辑、屏幕录制、光盘制作、添加特效、字幕和配音等功能&#xff0c;用户可以快速上手。会声会影2024软件还包含了视频教学以及模板素材&#xff0c;让用户剪辑视频更加的轻松。 会…

【Linux 进度条小程序】缓冲区+回车换行

文章目录 回车与换行缓冲区举个栗子fflush函数倒计时小程序进度条小程序 回车与换行 回车和换行是不同的两个概念 回车&#xff1a;\r 使光标回到本行行首。 换行&#xff1a;\n使光标下移一格。 一般我们的键盘上的Enter键是回加换行键 在c语言中 \n 表示回车换行 效果和Ent…

iNet Network Scanner for Mac:简洁高效的WiFi网络扫描软件

随着无线网络的普及&#xff0c;WiFi网络已经成为我们日常生活中必不可少的一部分。无线网络的稳定性和速度对我们的工作和娱乐体验至关重要。因此&#xff0c;一款功能强大、简洁高效的WiFi网络扫描软件非常重要。今天&#xff0c;我们向大家推荐一款优秀的Mac平台WiFi网络扫描…