PostgreSQL15安装和实现物理复制(主从配置)全程指南

1 概述

本文介绍如何在centos7或rocky9下安装postgresql15,并配置物理复制的全过程。postgresql安装采用shell脚本安装,一键执行,通俗易懂。

2 环境说明

序号IP操作系统用途备注
0110.10.0.41rockylinux9.3主库
0210.10.0.42rockylinux9.3从库

3 部署步骤

3.1 主库安装postgresql

将附录5.1脚本拷贝执行:

sh install.sh

验证:

/usr/pgsql-15/bin/psql -h /opt/apps/postgresql/run -p 5432 -U postgresql -d postgres

3.2 从库安装postgresql

将附录5.1 脚本拷贝:并注释init()方法内的pg_init db_init

#初始化方法
function init(){os_init;pg_install;#pg_init;sh_init;#db_init;
}
init

3.3 使用pg_basebackup导出基准备份

在从库执行。

pg_basebackup -h 10.10.0.41 -U repuser -D /root/bak -p 5432 --wal-method=stream

3.4 将基准备份拷贝至从库数据目录中

从库执行。

rm -rf /opt/apps/postgresql/data
cp -r /root/bak /opt/apps/postgresql/data
chown -R postgresql:postgresql /opt/apps/postgresql/data

3.5 处理主从复制

从库执行。

3.5.1 postgresql.auto.conf增加primary_conninfo

/opt/apps/postgresql/data/postgresql.auto.conf

# Do not edit this file manually!
# It will be overwritten by the ALTER SYSTEM command.
primary_conninfo='host=10.10.0.41 port=5432 user=repuser password=repuser123456'
recovery_target_timeline='latest'

3.5.2 创建standby.signal

su - postgresql -c "touch /opt/apps/postgresql/data/standby.signal"

3.5.3 启动从库

cd /opt/apps/postgresql && sh start.sh

3.5.4 查看从库日志

日志目录:/opt/apps/postgresql/data/pg_log/

4 验证

4.1 主库创建表,观察从库是否同步过去

略。

4.2 查询主从状态

4.2.1 主库查询

主库并不直接存储从库的复制状态。我们可以通过查看主库的 pg_stat_replication 视图,它会列出所有已连接并正在进行复制的从库信息

[root@localhost scripts]# /usr/pgsql-15/bin/psql -h /opt/apps/postgresql/run -p 5432 -U postgresql -d postgres
psql (15.5)
Type "help" for help.postgres=# \x
Expanded display is on.
postgres=# SELECT * FROM pg_stat_replication;
-[ RECORD 1 ]----+------------------------------
pid              | 13823
usesysid         | 16384
usename          | repuser
application_name | walreceiver
client_addr      | 10.10.0.42
client_hostname  | 
client_port      | 38120
backend_start    | 2024-01-25 13:00:52.184683+08
backend_xmin     | 
state            | streaming
sent_lsn         | 0/503EB18
write_lsn        | 0/503EB18
flush_lsn        | 0/503EB18
replay_lsn       | 0/503EB18
write_lag        | 
flush_lag        | 
replay_lag       | 
sync_priority    | 0
sync_state       | async
reply_time       | 2024-01-25 14:29:38.472977+08postgres=# 

4.2.2 从库查询

[root@localhost scripts]# /usr/pgsql-15/bin/psql -h /opt/apps/postgresql/run -p 5432 -U postgresql -d postgres
psql (15.5)
Type "help" for help.postgres=# \x
Expanded display is on.
postgres=# SELECT pg_last_wal_receive_lsn(), pg_last_wal_replay_lsn();
-[ RECORD 1 ]-----------+----------
pg_last_wal_receive_lsn | 0/503EB18
pg_last_wal_replay_lsn  | 0/503EB18postgres=# 

5 附录

5.1 安装脚本

5.1.1 脚本示例

#!/bin/bash
set -x
#定义变量
base_dir="/opt/apps"
user_name="postgresql"
port="5432"
appuser_name="pguser"
appuser_password="pguser123456"
appdb_name="pgdb"
repuser_name="repuser"
repuser_password="repuser123456"
default_python_version=$(python --version 2>&1 | cut -d' ' -f2 | cut -d. -f1)
if [ "$default_python_version" -eq "2" ]; thenappuser_password_encoded=$(python -c "import urllib; print(urllib.quote('$appuser_password'))")
elif [ "$default_python_version" -eq "3" ]; thenappuser_password_encoded=$(python -c "import urllib.parse; print(urllib.parse.quote('$appuser_password'))")
elseecho "无法识别的 Python 版本"
fi
# 获取OS版本信息
os_version=$(cat /etc/redhat-release | grep -oP '\d+' | head -1)
#获取Ip
host_ip=$(python -c "import socket;print([(s.connect(('8.8.8.8', 53)), s.getsockname()[0], s.close()) for s in [socket.socket(socket.AF_INET, socket.SOCK_DGRAM)]][0][1])")
#操作系统初始化
function os_init(){
# 获取 firewalld 的详细状态信息
systemctl stop firewalld
systemctl disable firewalld
# 获取当前 SELinux 状态
selinux_status=$(getenforce)
# 判断 SELinux 状态并执行相应操作
if [ "$selinux_status" == "Disabled" ]; thenecho "当前 SELinux 状态为 disabled"
elif [ "$selinux_status" == "Enforcing" ]; thensetenforce 0sed -i 's#SELINUX=enforcing#SELINUX=disabled#g' /etc/selinux/configecho "SELinux 已禁用并配置为 disabled"
elif [ "$selinux_status" == "Permissive" ]; thensed -i 's#SELINUX=enforcing#SELINUX=disabled#g' /etc/selinux/configecho "SELinux 已配置为 disabled"
elseecho "未知的 SELinux 状态: $selinux_status"
fi# 检查 limits.conf 文件是否包含所需配置
if grep -q "^\*\s*soft\s*nofile\s*65536" /etc/security/limits.conf && \grep -q "^\*\s*hard\s*nofile\s*65536" /etc/security/limits.conf && \grep -q "^\*\s*soft\s*nproc\s*65536" /etc/security/limits.conf && \grep -q "^\*\s*hard\s*nproc\s*65536" /etc/security/limits.conf; thenecho "文件描述符限制已优化"
else# 执行配置命令echo "* soft nofile 65536" >> /etc/security/limits.confecho "* hard nofile 65536" >> /etc/security/limits.confecho "* soft nproc 65536" >> /etc/security/limits.confecho "* hard nproc 65536" >> /etc/security/limits.confecho "文件描述符限制已优化"
fi# 检查 systemd 配置文件是否包含所需配置
if grep -q "^\s*DefaultLimitNOFILE=1000000" /etc/systemd/system.conf && \grep -q "^\s*DefaultLimitNPROC=65535" /etc/systemd/system.conf; thenecho "Systemd 文件描述符和进程数限制已优化"
else# 执行配置命令cat >> /etc/systemd/system.conf << EOF
DefaultLimitNOFILE=1000000
DefaultLimitNPROC=65535
EOFsystemctl daemon-reexececho "Systemd 文件描述符和进程数限制已优化"
fi
#创建用户
if id "$user_name" &>/dev/null; thenecho "User $user_name already exists."
else# 如果用户不存在,则创建用户useradd "$user_name"echo "User $user_name created successfully."
fi
#创建pg目录
mkdir -p $base_dir/$user_name/data
mkdir -p $base_dir/$user_name/run
mkdir -p $base_dir/$user_name/archive
mkdir -p $base_dir/$user_name/backup
mkdir -p $base_dir/$user_name/scripts
#更改目录权限
chown -R $user_name:$user_name $base_dir/$user_name
}
function pg_install(){
# 判断操作系统版本号,安装postgresql15-server
if [ "$os_version" == "7" ]; thencat /etc/redhat-release#配置epel源curl -o /etc/yum.repos.d/epel.repo https://mirrors.aliyun.com/repo/epel-7.repo#增加postgresql源cat > /etc/yum.repos.d/postgresql.repo << EOF
[postgresql]
name=postgresql
baseurl=https://download.postgresql.org/pub/repos/yum/15/redhat/rhel-7.9-x86_64/
enabled=1
gpgcheck=0
EOF#安装依赖包rpm -ivh https://download-ib01.fedoraproject.org/pub/epel/7/x86_64/Packages/l/libzstd-1.5.5-1.el7.x86_64.rpm#安装postgresql15-serveryum install postgresql15-server postgresql15-contrib -y
elif [ "$os_version" == "9" ]; thencat /etc/redhat-release#增加postgresql源cat > /etc/yum.repos.d/postgresql.repo << EOF
[postgresql]
name=http
baseurl=https://download.postgresql.org/pub/repos/yum/15/redhat/rhel-9.3-x86_64/
enabled=1
gpgcheck=0
EOF#安装postgresql15-serveryum install postgresql15-server postgresql15-contrib -y
elseecho "This script is intended to run on CentOS 7."
fi
}
function pg_init(){
#initdb
su - $user_name -c "/usr/pgsql-15/bin/initdb --username=$user_name --encoding=UTF8 --lc-collate=C --lc-ctype=en_US.utf8  --data-checksums -D $base_dir/$user_name/data"
#配置pg_hba.conf文件
cat >> $base_dir/$user_name/data/pg_hba.conf << EOF
host    replication     $repuser_name   0.0.0.0/0               md5
host    all             all             0.0.0.0/0               md5
EOF
#配置postgresql.conf
cat > $base_dir/$user_name/data/postgresql.conf << EOF
# basic
listen_addresses='0.0.0.0'
port=$port                                                  # 端口
unix_socket_directories='$base_dir/$user_name/run'          # socket目录
max_connections = 9999                                      # 最大连接数
superuser_reserved_connections = 10                         # 给超级用户预留的连接数
shared_buffers = 1GB                                        # 共享内存,一般设置为内存的1/4
effective_cache_size = 2GB                                  # 查询优化器估计的可用于缓存数据文件系统的总内存量,一般设置为内存的1/2
max_worker_processes = 48                                   # 最大工作线程,和cpu核数一致
max_parallel_workers_per_gather = 4                         # 单个查询在执行过程中可以使用的最大并行工作进程数,CPU核心数的1/12
max_parallel_workers = 24                                   # 整个数据库实例允许的最大并行进程数,CPU核心数的1/2到2/3之间
max_parallel_maintenance_workers = 6                        # 维护操作期间允许的最大并行进程数,CPU核心数的1/8
work_mem = 16MB                                             # 设置在写入临时磁盘文件之前查询操作(例如排序或哈希表)可使用的最大内存容量
maintenance_work_mem = 256MB                                # 在维护性操作(例如VACUUM、CREATE INDEX和ALTER TABLE ADD FOREIGN KEY)中使用的 最大的内存量
timezone = 'Asia/Shanghai'                                  # 系统时区
hot_standby = on                                            # 打开热备
# optimizer                                                 
default_statistics_target = 500                             # 默认100,ANALYZE在pg_statistic中存储的信息量,增大该值,会增加ANALYZE的时间,但会让解释计划更精准
# wal                                                       
max_wal_size = 1GB                                          # 建议与shared_buffers保持一致
min_wal_size = 80MB                                         # 建议max_wal_size/12.5
wal_log_hints = on                                          # 控制WAL日志记录的方式,建议打开
wal_level = replica                                         # wal日志写入级别,要使用流复制,必须使用replica或更高级别
wal_sender_timeout = 60s                                    # 设置WAL发送者在发送WAL数据时等待主服务器响应的超时时间
# archive                                                   
archive_mode = on                                           # 开启归档日志
archive_command = 'gzip < %p > $base_dir/$user_name/archive/%f.gz'
# log 近7天轮询
log_destination = 'stderr'                                  # 日志格式
logging_collector = on                                      # 日志收集器
log_directory = 'pg_log'                                    # 日志目录 $PGDATA/pg_log
log_filename = 'postgresql-%Y-%m-%d.log'                    # 日志名称格式
log_rotation_age = 43200                                    # 日志保留时间单位是分钟  
log_file_mode = 0600                                        # 日志文件的权限
log_rotation_size = 0                                       # 日志的最大尺寸,设置为零时将禁用基于大小创建新的日志文件
log_truncate_on_rotation = on                               # 这个参数将导致PostgreSQL截断(覆盖而不是追加)任何已有的同名日志文件
log_min_duration_statement = 0                              # 如果语句运行至少指定的时间量,将导致记录每一个这种完成的语句的持续时间
log_duration = on                                           # 每一个完成的语句的持续时间被记录
log_lock_waits = on                                         # 控制当一个会话为获得一个锁等到超过deadlock_timeout时,是否要产生一个日志消息
log_statement = 'mod'                                       # 控制哪些 SQL 语句被记录。有效值是 none (off)、ddl、mod和 all(所有语句)。ddl记录所有数据定义语句,例如CREATE、ALTER和 DROP语句。mod记录所有ddl语句,外加数据修改语句例如INSERT, UPDATE、DELETE、TRUNCATE, 和COPY FROM
log_timezone = 'Asia/Shanghai'                              # 设置在服务器日志中写入的时间戳的时区
# sql                                                       
statement_timeout = 300000                                  # 语句执行超时时间 5分钟
idle_in_transaction_session_timeout = 300000                # 事务空闲超时时间 5分钟
idle_session_timeout = 1800000                              # 会话空闲超时时间 30分钟
lock_timeout = 60000                                        # 等锁超时时间 1分钟
EOF
}
#启动和开机自启动
function sh_init(){
#启动服务
su - $user_name -c "/usr/pgsql-15/bin/pg_ctl -D $base_dir/$user_name/data -l $base_dir/$user_name/pg.log start"
#配置开机自启动
chmod +x /etc/rc.d/rc.local
cat >> /etc/rc.d/rc.local << EOF
su - $user_name -c "/usr/pgsql-15/bin/pg_ctl -D $base_dir/$user_name/data -l $base_dir/$user_name/pg.log start"
EOF
#创建启动、停止、重启脚本
cat > $base_dir/$user_name/start.sh << EOF
#!/bin/bash
su - $user_name -c "/usr/pgsql-15/bin/pg_ctl -D $base_dir/$user_name/data -l $base_dir/$user_name/pg.log start"
EOF
cat > $base_dir/$user_name/stop.sh << EOF
#!/bin/bash
su - $user_name -c "/usr/pgsql-15/bin/pg_ctl -D $base_dir/$user_name/data -l $base_dir/$user_name/pg.log stop"
EOF
cat > $base_dir/$user_name/restart.sh << EOF
#!/bin/bash
su - $user_name -c "/usr/pgsql-15/bin/pg_ctl -D $base_dir/$user_name/data -l $base_dir/$user_name/pg.log restart"
EOF
#创建备份脚本
cat > $base_dir/$user_name/scripts/backup.sh << EOF
#!/bin/bash
set -ex
cmd="/usr/bin/pg_dump -Fc -v --dbname=postgresql://$appuser_name:$appuser_password_encoded@$host_ip:$port/$appdb_name -f $base_dir/$user_name/backup/$appdb_name-\$(date +%Y-%m-%d).dmp"
\$cmd
find $backup_dir -name "*.dmp" -mtime +30 -exec rm -f {} \;
EOF
#添加定时任务脚本
cat > $base_dir/$user_name/scripts/crontab.sh << EOF
#!/bin/bash
# 检查是否存在 crontab,如果不存在,创建一个空的 crontab
if [ -z "$(crontab -l)" ]; thenecho "" | crontab -
fi
(crontab -l ; echo "0 23 * * * sh $base_dir/$user_name/scripts/backup.sh > $base_dir/$user_name/backup/backup.log 2>&1")|crontab -
EOF
chmod +x $base_dir/$user_name/scripts/crontab.sh
/bin/sh $base_dir/$user_name/scripts/crontab.sh
#创建恢复脚本
cat > $base_dir/$user_name/scripts/pg_restore.sh << EOF
#!/bin/bash
pg_restore -v --dbname=postgresql://$appuser_name:$appuser_password_encoded@$host_ip:$port/$appdb_name $base_dir/$user_name/backup/$appdb_name.dmp
EOF
#创建psql命令示例
cat > $base_dir/$user_name/scripts/psql.txt << EOF
/usr/pgsql-15/bin/psql -h $base_dir/$user_name/run -p $port -U $user_name -d postgres
EOF
}
function db_init(){
#创建init.sql文件
cat > $base_dir/$user_name/scripts/init.sql << EOF
create USER $repuser_name with login replication encrypted password '$repuser_password';
-- 创建数据库
CREATE DATABASE $appdb_name;
-- 连接到新创建的数据库
\c $appdb_name;
-- 创建用户
CREATE USER $appuser_name WITH PASSWORD '$appuser_password';
-- 赋予用户所有权限
GRANT ALL PRIVILEGES ON DATABASE $appdb_name TO $appuser_name;
-- 将 appdb 的所有权(OWNER)设置为 $appuser_name
ALTER DATABASE $appdb_name OWNER TO $appuser_name;
EOF
#创建drop.sql
cat > $base_dir/$user_name/scripts/drop.sql << EOF
drop database $appdb_name;
drop user $appuser_name;
EOF
#执行sql
/usr/pgsql-15/bin/psql -h $base_dir/$user_name/run -p $port -U $user_name -d postgres -f $base_dir/$user_name/scripts/init.sql
}
#初始化方法
function init(){os_init;pg_install;pg_init;sh_init;db_init;
}
init

5.1.2 脚本解析

上述脚本包含了在Linux环境中安装和配置PostgreSQL 15数据库的详细步骤,同时涵盖了数据库初始化、用户与权限设置、日志管理、备份恢复策略以及操作系统层面的优化等内容。以下是详细的解析:

  1. 环境变量定义
    • 定义了如base_dir(基础目录)、user_name(PostgreSQL运行用户)、port(数据库服务端口)、appuser_nameappuser_password(应用连接数据库的用户名和密码)、appdb_name(应用数据库名)等变量。
    • 使用Python确定默认版本,并编码应用程序用户的密码以确保安全地存储和使用。
  2. 操作系统初始化
    • 关闭并禁用firewalld防火墙服务。
    • 检查并根据需要调整SELinux状态,使其变为disabled。
    • 设置文件描述符和进程数限制,以便PostgreSQL可以打开足够多的文件句柄和并发处理更多连接。
    • 创建名为postgresql的系统用户及其相关的目录结构,并赋予相应的权限。
  3. PostgreSQL安装
    • 根据不同的Red Hat/CentOS版本配置Yum仓库源。
    • 安装依赖包,例如libzstd库。
    • 安装PostgreSQL 15服务器和contrib扩展包。
  4. PostgreSQL初始化
    • 初始化数据库集群,创建数据目录,使用initdb命令指定用户名、字符集、校验和、时区和其他参数。
    • 配置pg_hba.conf文件以控制不同用户的认证方式,包括从任何IP地址通过md5认证进行复制和一般连接。
    • 编辑postgresql.conf以设置监听地址、端口、socket路径、最大连接数、内存相关参数(如shared_buffers、effective_cache_size、work_mem等),以及WAL相关参数(如wal_level、max_wal_size、min_wal_size等)。
    • 设置日志记录相关的参数,包括日志级别、时间戳时区、语句记录类型(如仅记录DDL和修改数据的SQL语句)以及日志文件轮转策略。
  5. 数据库和用户管理
    • db_init函数中,创建了一个SQL脚本用于初始化数据库和用户账号,包括创建一个具有特定权限的应用程序用户和数据库,并为复制设置一个专用用户。
    • 提供了创建和删除数据库及用户的SQL脚本示例。
  6. 服务启动与自启动配置
    • 创建启动、停止、重启PostgreSQL服务的bash脚本,方便操作。
    • 配置系统自启动脚本,保证系统重启后自动启动数据库服务。
  7. 备份与恢复
    • 创建一个定期执行的备份脚本,使用pg_dump工具对数据库进行完整备份,并按日期命名备份文件,同时清理超过30天的旧备份。
    • 创建一个用于恢复数据库的pg_restore脚本。
  8. 定时任务
    • 添加到crontab的定时任务,每天晚上11点执行备份脚本,将备份输出重定向到日志文件。

5.3 启停脚本

  • 启动:/opt/apps/postgresql/start.sh
  • 停止:/opt/apps/postgresql/stop.sh
  • 重启:/opt/apps/postgresql/restart.sh

5.4 编写python3脚本向库中插入数据

建表语句

CREATE TABLE "t1" ("c1" INTEGER NULL DEFAULT NULL
);

安装psycopg包

若没有pip3命令请执行:yum install python3-pip -y
pip3 install psycopg

脚本示例:向主库中插入10000条数据

#!/usr/bin/python3
import psycopg
host = '10.10.0.41'
port = '5432'
database = 'pgdb'
user = 'pguser'
password = 'pguser123456'
# 创建连接和游标
conn = psycopg.connect(host=host, port=port, dbname=database, user=user, password=password)
cursor = conn.cursor()
# 假设有一批数据要插入,这里以列表形式表示
data_to_insert = [(i,) for i in range(1, 100001)]
# 批量插入数据的 SQL 语句模板
insert_query = """INSERT INTO t1 (c1) VALUES (%s);
"""
# 执行批量插入操作
cursor.executemany(insert_query, data_to_insert)
# 提交事务
conn.commit()
# 关闭游标和连接
cursor.close()
conn.close()
print("数据已成功批量插入到 t1 表中!")

码字不易,喜欢本文请点赞。

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

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

相关文章

【electron】安装网络问题处理

目录 场景排查问题排查结论electron 安装失败解决方案 新的问题electron-builder 打包失败处理 场景 在mac上使用electron进行代码开发的时候&#xff0c;无法正常下载与electron、electron-builder相关的依赖 排查问题 是不是因为没有翻墙导致资源无法下载是不是没有设置正…

软件门槛之算法

软件门槛之算法 1.背景2.算法定义3.特征4.基本要素5.常用设计模式6.常用实现方法7.复杂度时间复杂度空间复杂度8.分类9.算法常用的一些工具10.算法的检验标准1.背景 一入行业深似海 再回首已是白发生! 工作这么多年了,感觉算法是比较难搞的。 写代码最重要的可能是框架和算法…

【Linux环境配置】core dump配置和快速gdb调试core文件

文章目录 0. 在Ubuntu系统中直接运行导致coredump的程序并没有生成core文件1. core dump 设置1.1 设置core文件格式1.2 设置core 大小限制 2. 写个代码测一下2.1 示例代码放入 test.c 中2.2 编译运行2.3 gdb调试一下core 3. 参考资料 0. 在Ubuntu系统中直接运行导致coredump的程…

MC3172 串口模块

MC3172 支持12个串口对应关系如下 串口模块初始化 第一个是uart0~11 inpin RX 脚 管脚号 outpin TX脚 管脚号 baud 波特率 read_ptr ,数据读取指针 void uart_init(u32 uart_num,u8 in_pin,u8 out_pin,u32 baud,u8* read_ptr) {INTDEV_SET_CLK_RST(uart_num,(INTDEV_RUN|…

React中antd的使用技巧

1.antd的基本使用&#xff1a; (1).yarn add antd(2).引入样式&#xff1a;import antd/dist/antd.css;(3).根据文档引入组件2.antd按需引入样式 (1).yarn add react-app-rewired customize-cra babel-plugin-import(2).修改package.json&#xff0c;内容如下&#xff1a;.....…

HCIP-三层架构实验

实验拓扑 实验需求 实验思路 配置IP地址 链路聚合 vlan配置 配置生产树 实验步骤 配置IP地址 以R1为例 <Huawei>sys [Huawei]sys r1 [r1]int g0/0/02 [r1-GigabitEthernet0/0/2]ip address 12.1.1.1 24 Jan 28 2024 17:09:03-08:00 r1 %%01IFNET/4/LINK_STATE(l…

一天吃透面试八股文

内容摘自我的学习网站&#xff1a;topjavaer.cn 分享50道Java并发高频面试题。 线程池 线程池&#xff1a;一个管理线程的池子。 为什么平时都是使用线程池创建线程&#xff0c;直接new一个线程不好吗&#xff1f; 嗯&#xff0c;手动创建线程有两个缺点 不受控风险频繁创…

vue中使用jweixin-module

目录 一&#xff1a;安装jweixin-module 二&#xff1a;后端配置 三&#xff1a;获取签名并注入配置 四&#xff1a;调用微信JS接口 在Vue项目中使用jweixin-module&#xff08;或通常称为jweixin&#xff0c;即微信JS-SDK的封装&#xff09;来调用微信提供的JS接口&#x…

二叉树

目录 1翻转二叉树 2对称二叉树 3二叉树的深度 最大深度 最小深度 4二叉树的结点数量 完全二叉树的结点数量 5平衡二叉树 6 中序 后序求前序 二叉树结构体如下&#xff1a; struct freenode {int data;struct freenode *lchild, *rchild;//左孩子 右孩子 }T; 1翻转二…

每日OJ题_算法_前缀和②_牛客DP35 【模板】二维前缀和

目录 二维前缀和原理 ②牛客DP35 【模板】二维前缀和 解析代码 二维前缀和原理 在一维数组前缀和算法的基础上&#xff0c;想到&#xff1a;计算二维数组前缀和&#xff0c;不就和计算一维数组前缀和一样&#xff0c;即计算每一个位置的前缀和就相当于&#xff1a; 此位置的…

qt学习:json数据文件读取写入

目录 什么是json 基本格式 例子 解析json文件数据到界面上 组合json数据文档对象 什么是json json是一种轻量级的数据交互格式&#xff0c;简单来说&#xff0c;json就是一种在各个编程语言中流通的数据格式&#xff0c;负责不同编程语言中的数据传递和交互 基本格式 以…

Top100 子串

1.560. 和为 K 的子数组 给你一个整数数组 nums 和一个整数 k &#xff0c;请你统计并返回 该数组中和为 k 的子数组的个数 。 子数组是数组中元素的连续非空序列。 示例 1&#xff1a; 输入&#xff1a;nums [1,1,1], k 2 输出&#xff1a;2示例 2&#xff1a; 输入&#…

VUE引入DataV报错记录

DataV官网&#xff08;不支持Vue3&#xff09;&#xff1a;Welcome | DataV 一、按照官网引入后报错 【1】 Failed to resolve entry for package "dataview/datav-vue3". The package may have incorrect main/module/exports specified in its package.json. 将…

服务器托管与虚拟主机租用有哪些区别?

服务器托管又称为主机托管&#xff0c;是用户自身拥有一台服务器放置在数据中心的机房里&#xff0c;主要是由客户自己进行维护&#xff0c;用户自身就可以进行操作系统&#xff0c;企业将服务器放置在专用的托管服务器机房中&#xff0c;可以享受到稳定舒适的机房环境&#xf…

ARC143D Bridges

题目 把 i i i 和 i n in in 看作一个点&#xff0c;对所有 a i a_i ai​ 和 b i b_i bi​ 连边&#xff0c;得到的图称为 G G G&#xff0c;则 G G G 的割边 ( a i , b i ) (a_i,b_i) (ai​,bi​) 在原图中 ( a i , b i n ) (a_i,b_in) (ai​,bi​n) 或 ( a i n ,…

【Matlab】音频信号分析及FIR滤波处理——凯泽(Kaiser)窗

一、前言 1.1 课题内容: 利用麦克风采集语音信号(人的声音、或乐器声乐),人为加上环境噪声(窄带)分析上述声音信号的频谱,比较两种情况下的差异根据信号的频谱分布,选取合适的滤波器指标(频率指标、衰减指标),设计对应的 FIR 滤波器实现数字滤波,将滤波前、后的声音…

贪吃蛇/链表实现(C/C++)

本篇使用C语言实现贪吃蛇小游戏&#xff0c;我们将其分为了三个大部分&#xff0c;第一个部分游戏开始GameStart&#xff0c;游戏运行GameRun&#xff0c;以及游戏结束GameRun。对于整体游戏主要思想是基于链表实现&#xff0c;但若仅仅只有C语言的知识还不够&#xff0c;我们还…

Compose开发No virtual method at(Ljava/lang/Object;I)错误【已解决】

此问题主要是在用CircularProgressIndicator时报错的&#xff0c;其他没遇到。 在升级不同版本时出现了不少问题&#xff0c;现在记录一下 1、mutableIntStateOf()函数的出现 要将此条版本更新到2.6.2及以上 implementation("androidx.lifecycle:lifecycle-runtime-ktx:…

学习笔记推荐:极客时间《Java常见错误100例》

最近&#xff0c;我有幸接触了一套非常精彩的学习笔记&#xff0c;《Java常见错误100例》。&#xff08;手册链接在文末&#xff01;&#xff01;&#xff01;&#xff09; 这套学习笔记出自极客时间&#xff0c;对于想要在 Java 开发领域深耕细作的朋友们来说&#xff0c;它无…

SpringBoot内置工具类

Collections java.util包下的Collections类&#xff0c;该类主要用于操作集合或者返回集合 一、排序 List<Integer> list new ArrayList<>();list.add(2);list.add(1);list.add(3);Collections.sort(list);//升序System.out.println(list);Collections.reverse(…