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

数据库高安全—角色权限:权限管理权限检查

目录

3.3 权限管理

3.4 权限检查


书接上文数据库高安全—角色权限:角色创建角色管理,从角色创建和角色管理两方面对高斯数据库的角色权限进行了介绍,本篇将从权限管理和权限检查方面继续解读高斯数据库的角色权限。

3.3 权限管理

(1) 访问控制列表

访问控制列表(Access Control List,ACL)是实现数据库对象权限管理的基础,每个对象都具有ACL,存储该对象的所有授权信息。当用户访问对象时,只有用户在对象的ACL中并且具有所需的权限才能够访问该对象。

每个ACL是由1个或多个AclItem构成的链表,每1个AclItem由授权者、被授权者和权限位3部分构成,记录着可在对象上进行操作的用户及其权限。

数据结构AclItem:

typedef struct AclItem {    Oid ai_grantee;     // 被授权者的OID     Oid ai_grantor;     // 授权者的OID     AclMode ai_privs;  // 权限位:32位的比特位 } AclItem;

其中ai_privs字段是AclMode类型。AclMode是一个32位的比特位,其高16位为权限选项位,当该比特位取值为1时,表示AclItem中的ai_grantee对应的用户具有此对象的相应操作的授权权限,否则表示用户没有授权权限;低16位为操作权限位,当该比特位取值为1时,表示AclItem中的ai_grantee对应的用户具有此对象的相应操作权限,否则表示用户没有相应的权限。在AclMode的结构位图1中,Grant Option记录各权限的授权权限的授予情况。低16位记录各权限的授予情况,当授权语句使用ALL时,则表示对象的所有权限。

图片

图1 openGauss AclMode结构图

在openGauss的具体实现中,我们将对对象执行DML类操作和DDL类操作的权限分别记在两个AclMode结构中,并以第15位的值来区分二者,最终实现对于每一个数据库对象,相同的授权者和被授权者对应两个不同的AclMode,分别表示记录DML类操作权限和DDL类操作权限,实现方式如图2和图3所示。

图片

图2 openGauss记录DML类操作权限的AclMode结构

图片

图3 openGauss记录DDL类操作权限的AclMode结构

每个权限参数代表的权限如表1所示。

表1 权限参数

参数

对象权限

参数

对象权限

a

INSERT

T

TEMPORARY

r

SELECT

c

CONNECT

w

UPDATE

p

COMPUTE

d

DELETE

R

READ

D

TRUNCATE

W

WRITE

x

REFERENCES

A

ALTER

t

TRIGGER

P

DROP

X

EXECUTE

m

COMMENT

U

USAGE

i

INDEX

C

CREATE

v

VACUUM

(2)对象权限管理

数据库对象权限管理主要通过使用SQL命令GRANT/REVOKE授予或回收一个或多个角色在对象上的权限。GRANT/REVOKE命令都由函数ExecuteGrantStmt实现,该函数只有一个GrantStmt类型的参数,基本流程如图4。

图片

图4 openGauss对象权限管理代码接口

数据结构GrantStmt定义如下:

typedef struct GrantStmt {    NodeTag type;    bool is_grant;            // true = 授权, false = 回收    GrantTargetType targtype;  // 操作目标的类型    GrantObjectType objtype;  // 被操作对象的类型:表,数据库,模式函数等    List* objects;            // 被操作对象的集合    List* privileges;          // 要操作权限列表    List* grantees;           // 被授权者的集合    bool grant_option;       // true = with grant option/grant option for    DropBehavior behavior;   // 回收权限的行为:restrict,cascade} GrantStmt;

函数ExecuteGrantStmt首先将GrantStmt结构转化为InternalGrant结构,将权限列表转化为内部的AclMode表示形式。当privileges 取值为NIL时,表示授予或回收所有的权限,此时置InternalGrant的all_privs字段为true,privileges字段为ACL_NO_RIGHTS。

数据结构InternalGrant:

typedef struct InternalGrant {    bool is_grant;            // true=授权, false=回收    GrantObjectType objtype;  // 被操作对象的类型:表,数据库,模式函数等    List* objects;            // 被操作对象的集合    bool all_privs;           // 是否授予或回收所有的权限AclMode privileges;      // AclMode形式表示的DML类操作对应的权限AclMode ddl_privileges;  // AclMode形式表示的DDL类操作对应的权限List* col_privs;          // 对列执行的DML类操作对应的权限List* col_ddl_privs;      // 对列执行的DDL类操作对应的权限    List* grantees;          // 被授权者的集合    bool grant_option;      // true=with grant option/grant option for    DropBehavior behavior; // 回收权限的行为:restrict,cascade} InternalGrant;

函数ExecuteGrantStmt在完成结构转换之后,调用ExecGrantStmt_oids,根据对象类型分别调用相应对象的权限管理函数。接下来以表对象的权限管理过程为例,介绍权限管理的算法,函数ExecGrant_Relation的处理流程如图5所示。

图片

图5 openGauss表对象权限管理流程图

函数ExecGrant_Relation用来处理表对象权限的授予或回收操作,入参为InternalGrant类型的变量,存储着授权或回收操作的操作对象信息、被授权者信息和权限信息。

  • 首先从系统表pg_class中获取旧ACL,如果不存在旧的ACL,则新建一个ACL,并调用函数acldefault将默认的权限信息赋给该ACL。根据对象的不同,初始的缺省权限含有部分可赋予PUBLIC的权限。如果存在旧的ACL,则将旧的ACL存储为一个副本。

  • 然后调用select_best_grantor来获取授权者对操作对象所拥有的授权权限avail_goptions;将参数avail_goptions传入函数restrict_and_check_grant,结合SQL命令中给出的操作权限,计算出实际需要授予或回收的权限。

  • 再调用merge_acl_with_grant生成新的ACL,如果是授予权限,则将要授予的权限添加到旧ACL中;如果是回收权限,则将要被回收的权限从旧ACL中删除。

  • 最后将新的ACL更新到系统表pg_class对应元组的ACL字段,完成授权或回收过程。

具体的函数实现如下:

static void ExecGrant_Relation(InternalGrant* istmt){    . . .// 循环处理每一个表对象。    foreach (cell, istmt->objects) {        . . .// 判断所要操作的表对象是否存在,若不存在则提示报错。        tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relOid));        if (!HeapTupleIsValid(tuple))            ereport(                ERROR, (errcode(ERRCODE_CACHE_LOOKUP_FAILED), errmsg("cache lookup failed for relation %u", relOid)));        pg_class_tuple = (Form_pg_class)GETSTRUCT(tuple);. . .        // 系统表pg_class中获取旧ACL,若不存在旧的ACL,则新建一个ACL,若存在旧的ACL,则将旧的ACL存储为一个副本。        ownerId = pg_class_tuple->relowner;        aclDatum = SysCacheGetAttr(RELOID, tuple, Anum_pg_class_relacl, &isNull);        if (isNull) {            switch (pg_class_tuple->relkind) {                case RELKIND_SEQUENCE:                    old_acl = acldefault(ACL_OBJECT_SEQUENCE, ownerId);                    break;                default:                    old_acl = acldefault(ACL_OBJECT_RELATION, ownerId);                    break;            }            noldmembers = 0;            oldmembers = NULL;        } else {            old_acl = DatumGetAclPCopy(aclDatum);            noldmembers = aclmembers(old_acl, &oldmembers);        }        old_rel_acl = aclcopy(old_acl);
        // 处理表级别的权限。        if (this_privileges != ACL_NO_RIGHTS) {            AclMode avail_goptions;            Acl* new_acl = NULL;            Oid grantorId;            HeapTuple newtuple = NULL;            Datum values[Natts_pg_class];            bool nulls[Natts_pg_class] = {false};            bool replaces[Natts_pg_class] = {false};            int nnewmembers;            Oid* newmembers = NULL;            AclObjectKind aclkind;
            // 获取授权者grantorId和授权者对该操作对象所拥有的授权权限avail_goptions。            select_best_grantor(GetUserId(), this_privileges, old_acl, ownerId, &grantorId, &avail_goptions);
            switch (pg_class_tuple->relkind) {                case RELKIND_SEQUENCE:                    aclkind = ACL_KIND_SEQUENCE;                    break;                default:                    aclkind = ACL_KIND_CLASS;                    break;            }
            // 结合参数avail_goptions和SQL命令中给出的操作权限,计算出实际需要授予或回收的权限。            this_privileges = restrict_and_check_grant(istmt->is_grant,                avail_goptions,                istmt->all_privs,                this_privileges,                relOid,                grantorId,                aclkind,                NameStr(pg_class_tuple->relname),                0,                NULL);
            // 生成新的ACL,并更新到系统表pg_class对应元组的ACL字段。            new_acl = merge_acl_with_grant(old_acl,                istmt->is_grant,                istmt->grant_option,                istmt->behavior,                istmt->grantees,                this_privileges,                grantorId,                ownerId);. . .            replaces[Anum_pg_class_relacl - 1] = true;            values[Anum_pg_class_relacl - 1] = PointerGetDatum(new_acl);
            newtuple = heap_modify_tuple(tuple, RelationGetDescr(relation), values, nulls, replaces);
            simple_heap_update(relation, &newtuple->t_self, newtuple);. . .        }
        // 若存在列级授权或回收,则调用ExecGrant_Attribute 函数处理。. . .        if (have_col_privileges) {            AttrNumber i;
            for (i = 0; i < num_col_privileges; i++) {                if (col_privileges[i] == ACL_NO_RIGHTS)                    continue;                ExecGrant_Attribute(istmt,                    relOid,                    NameStr(pg_class_tuple->relname),                    i + FirstLowInvalidHeapAttributeNumber,                    ownerId,                    col_privileges[i],                    attRelation,                    old_rel_acl);            }        }    . . .    }
    heap_close(attRelation, RowExclusiveLock);    heap_close(relation, RowExclusiveLock);}

3.4 权限检查

用户在对数据库对象进行访问操作时,数据库会检查用户是否拥有该对象的操作权限。通常数据库对象的所有者和初始用户(superuser)拥有该对象的全部操作权限,其他普通用户需要被授予权限才可以执行相应操作。数据库通过查询数据库对象的访问控制列表(ACL)检查用户对数据库对象的访问权限,数据库对象的ACL保存在对应的系统表中,当被授予或回收对象权限时,系统表中保存的ACL权限位会被更新。常用的数据库对象权限检查函数、ACL检查函数、ACL所在系统表以及对象所有者检查函数对应关系如表2所示。

表2 数据库对象函数对应关系表

对象

权限检查

ACL检查

所有者检查

系统表

table

pg_class_aclcheck

pg_class_aclmask

pg_class_ownercheck

pg_class

column

pg_attribute_aclcheck

pg_attribute_aclmask

NA

pg_attribute

database

pg_database_aclcheck

pg_database_aclmask

pg_database_ownercheck

pg_database

function

pg_proc_aclcheck

pg_proc_aclmask

pg_proc_ownercheck

pg_proc

language

pg_language_aclcheck

pg_language_aclmask

pg_language_ownercheck

pg_language

largeobject

pg_largeobject_aclcheck_snapshot

pg_largeobject_aclmask_snapshot

pg_largeobject_ownercheck

pg_largeobject_metadata

namespace

pg_namespace_aclcheck

pg_namespace_aclmask

pg_namespace_ownercheck

pg_namespace

tablespace

pg_tablespace_aclcheck

pg_tablespace_aclmask

pg_tablespace_ownercheck

pg_tablespace

foreign data wrapper

pg_foreign_data_wrapper_aclcheck

pg_foreign_data_wrapper_aclmask

pg_foreign_data_wrapper_ownercheck

pg_foreign_data_wrapper

foreign server

pg_foreign_server_aclcheck

pg_foreign_server_aclmask

pg_foreign_server_ownercheck

pg_foreign_server

type

pg_type_aclcheck

pg_type_aclmask

pg_type_ownercheck

pg_type

下面以表的权限检查为例进行权限检查过程说明。表权限检查函数pg_class_aclcheck定义如下:

AclResult pg_class_aclcheck(Oid table_oid, Oid roleid, AclMode mode, bool check_nodegroup){    if (pg_class_aclmask(table_oid, roleid, mode, ACLMASK_ANY, check_nodegroup) != 0)        return ACLCHECK_OK;    else        return ACLCHECK_NO_PRIV;}

pg_class_aclcheck函数有4个入参,其中table_oid用于表示待检查的表,roleid用于表示待检查的用户或角色,mode表示待检查的权限,此权限可以是一种权限也可以是多种权限的组合。第4个参数check_nodegroup用于表示是否检查nodegroup逻辑集群权限,如果调用时不给此参数赋值则默认为true。函数返回值为枚举类型AclResult,如果检查结果有权限返回ACLCHECK_OK,无权限则返回ACLCHECK_NO_PRIV。

pg_class_aclcheck函数通过调用pg_class_aclmask函数实现对象权限检查。pg_class_aclmask函数有5个参数,其中第4个参数how为AclMaskHow枚举类型,包括ACLMASK_ALL和ACLMASK_ANY两种取值,ACLMASK_ALL表示需要满足待检查权限mode中的所有权限,ACLMASK_ANY表示只需满足待检查权限mode中的一种权限即可。pg_class_aclmask函数的其余4个参数table_oid、roleid、mode和check_nodegroup直接由pg_class_aclcheck函数传入。pg_class_aclmask函数从“pg_class”系统表中获取ACL权限信息并调用aclmask函数完成权限位校验,通过AclMode数据类型返回权限检查结果。

以上内容从权限管理和权限检查两方面对角色权限进行了介绍,下篇将从传统审计和统一审计两方面对高斯数据库的审计追踪技术进行解读,敬请期待~

相关文章:

数据库高安全—角色权限:权限管理权限检查

目录 3.3 权限管理 3.4 权限检查 书接上文数据库高安全—角色权限&#xff1a;角色创建角色管理&#xff0c;从角色创建和角色管理两方面对高斯数据库的角色权限进行了介绍&#xff0c;本篇将从权限管理和权限检查方面继续解读高斯数据库的角色权限。 3.3 权限管理 &#x…...

spring boot controller放到那一层

在 Spring Boot 应用程序中&#xff0c;Controller 层通常被放置在应用程序的 表示层&#xff08;Presentation Layer&#xff09; 或 用户界面层&#xff08;UI Layer&#xff09; 中。Controller 层的主要职责是处理用户的 HTTP 请求&#xff0c;并将请求转发给服务层进行业务…...

报错 - cannot import name ‘ExportOptions‘ from ‘torch.onnx._internal.exporter‘

调用库时出现错误&#xff1a; ImportError: cannot import name ‘ExportOptions’ from ‘torch.onnx._internal.exporter’ 尝试更新 onnx&#xff0c; onnxscript&#xff0c;diffusers 均没有解决问题 将 torch 升级&#xff08;从 2.1.0 到 2.5.1&#xff09;后解决了 具…...

恒压恒流原边反馈控制芯片 CRE6289F

CRE6289F 系列产品是一款内置高压 MOS 功率开关管的高性能多模式原边控制的开关电源芯片。较少的外围元器件、较低的系统成本设计出高性能的交直流转换开关电源。CRE6289F 系列产品提供了极为全面和性能优异的智能化保护功能&#xff0c;包括逐周期过流保护、软启动、芯片过温保…...

ffmpeg视频抽帧和合成

FFMPEG 抽取视频场景转换帧 ffmpeg -i input.mp4 -vf "selectgt(scene,0.4),showinfo" -vsync vfr output_%04d.jpg ffmpeg -i input.mp4 -vf "selectgt(scene,0.4),scale1280:720" -vsync vfr output_%03d.jpg # -vsync 已经弃用&#xff0c;最新版本不…...

七、Hadoop环境搭建之安装JDK

文章目录 一、卸载自带JDK二、传输jdk到服务器中三、解压四、配置JDK环境变量 一、卸载自带JDK 注意&#xff1a;安装JDK前&#xff0c;一定确保提前删除了虚拟机自带的JDK。 以下操作&#xff0c;请切换至root权限进行操作 输入&#xff1a;rpm -qa | grep jdk 会查询出系统…...

RocketMQ消息积压问题如何解决?

大家好&#xff0c;我是锋哥。今天分享关于【RocketMQ消息积压问题如何解决?】面试题。希望对大家有帮助&#xff1b; RocketMQ消息积压问题如何解决? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 RocketMQ 消息积压问题通常是指消息队列中的消息堆积过多&…...

【Java基础】进程与线程的关系、Tread类;讲解基本线程安全、网络编程内容;JSON序列化与反序列化

1. 进程和线程 1.1 进程 几乎所有的操作系统都支持进程的概念&#xff0c;所有运行中的任务通常对应一个进程&#xff08;Process&#xff09;。 当一个程序进入内存运行时&#xff0c;即变成一个进程。 进程是处于运行过程中的程序&#xff0c;并且具有一定的独立功能&…...

CDN防御如何保护我们的网络安全?

在当今数字化时代&#xff0c;网络安全成为了一个至关重要的议题。随着网络攻击的日益频繁和复杂化&#xff0c;企业和个人都面临着前所未有的安全威胁。内容分发网络&#xff08;CDN&#xff09;作为一种分布式网络架构&#xff0c;不仅能够提高网站的访问速度和用户体验&…...

深度学习驱动的蛋白质设计技术与实践

通过设计特定的蛋白质结构&#xff0c;可以实现预期的生物功能&#xff0c;如催化特定化学反应、识别和结合特定分子、调控生物信号传导等&#xff0c;为生物医学、药物研发、生物技术等领域提供重要工具和解决方案。传统的蛋白质设计方法主要依赖于已知蛋白质结构的同源建模、…...

Centos7使用yum工具出现 Could not resolve host: mirrorlist.centos.org

在 CentOS 7 中使用 yum 工具时&#xff0c;出现 "Could not resolve host: mirrorlist.centos.org" 的错误&#xff0c;一般情况是因为默认的镜像源无法访问。 以下是一些常用的解决方法&#xff1a; 检查网络连接&#xff1a;首先使用 ping 命令测试网络连接是否…...

iOS - 原子操作

在 Objective-C 运行时中&#xff0c;原子操作主要通过以下几种方式实现&#xff1a; 1. 基本原子操作 // 原子操作的基本实现 #if __has_feature(c_atomic)#define OSAtomicIncrement32(p) __c11_atomic_add((_Atomic(int32_t) *)(p), 1, __ATOMIC_RELAXED) #define …...

PHP二维数组去除重复值

Date: 2025.01.07 20:45:01 author: lijianzhan PHP二维数组内根据ID或者名称去除重复值 代码示例如下&#xff1a; // 假设 data数组如下 $data [[id > 1, name > Type A],[id > 2, name > Type B],[id > 1, name > Type A] // 重复项 ];// 去重方法 $dat…...

【Flink部署】-- 部署 flink 1.19.1 standalone 集群

目录 1、环境准备 2、部署步骤 2.1、下载 flink 二进制包 2.2、配置全局环境变量 2.3、验证 flink 版本 2.4、配置 config.yaml 2.5、启动和停止本地 standalone 集群 2.6、提交测试作业 2.7、查询作业 3、参考 1、环境准备 jdk 11apache flink 1.19.1 安装包2、部署…...

关于物联网的基础知识(二)——物联网体系结构分层

成长路上不孤单&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a; 【14后&#x1f60a;///计算机爱好者&#x1f60a;///持续分享所学&#x1f60a;///如有需要欢迎收藏转发///&#x1f60a;】 今日分享关于物联网的基础知识&#xff08;二&a…...

使用Paddledetection进行模型训练【Part2:数据准备+模型训练】

目录 写在前面 数据准备 模型优化 1. 使用自定义数据 2. 加载预训练模型 3. 启动训练 写在前面 在目标检测算法产业落地过程中&#xff0c;常常会出现需要额外训练以满足实际使用的要求&#xff0c;项目迭代过程中也会出先需要修改类别的情况。本文档详细介绍如何使用Pa…...

使用最广泛的FastAPI项目结构推荐,命名规范等

使用最广泛的FastAPI项目结构推荐&#xff0c;命名规范等 一、FastAPI项目结构如下&#xff1a;二、组件管理&#xff1a;使用依赖注入三、命名约定四、建议分层架构的设计五、文档和测试六、版本控制和持续集成七、环境和配置管理工具八、性能优化与权限安全 一、FastAPI项目结…...

【JAVA】java中将一个list进行拆解重新组装

一、使用场景 1、当需要对一个list中的元素属性进行重新赋值&#xff0c;比如一个list中存储了订单数据&#xff0c;我们需要改变list中每个订单的id&#xff0c;然后再重新输出订单list if(CollectionUtils.isNotEmpty(orderList)){ orderList.forEach(p->{ …...

怎样修改el-table主题样式

起因&#xff1a;el-table有主题样式&#xff0c;部分需要单独设置 环境&#xff1a;ideanodejs插件谷歌浏览器 第一步&#xff1a;找到scss文件&#xff1a; 谷歌浏览器打开表格页面&#xff0c;ctrlshifti打开开发者工具&#xff0c;点击后鼠标移动到表格单元格上单击一下…...

【Docker项目实战】使用Docker部署gallery轻量级图片管理系统

【Docker项目实战】使用Docker部署gallery轻量级图片管理系统 一、SFPG介绍1.1 应用简介1.2 主要特点1.3 主要使用场景二、本次实践规划2.1 本地环境规划2.2 本次实践介绍三、本地环境检查3.1 检查Docker服务状态3.2 检查Docker版本3.3 检查docker compose 版本四、下载gallery…...

缓存-Redis-常见问题-缓存击穿-永不过期+逻辑过期(全面 易理解)

缓存击穿&#xff08;Cache Breakdown&#xff09; 是在高并发场景下&#xff0c;当某个热点数据在缓存中失效或不存在时&#xff0c;瞬间大量请求同时击中数据库&#xff0c;导致数据库压力骤增甚至崩溃的现象。为了解决这一问题&#xff0c;“永不过期” “逻辑过期” 的策略…...

【0x006D】HCI_Write_LE_Host_Support命令详解

目录 一、命令概述 二、命令格式及参数说明 2.1. HCI_Write_LE_Host_Support命令格式 2.2. LE_Supported_Host 三、生成事件及参数 3.1. HCI_Command_Complete 事件 3.2. Status 四、命令执行流程 4.1. 命令发起阶段&#xff08;主机端&#xff09; 4.2. 命令处理阶段…...

尚硅谷· vue3+ts 知识点学习整理 |14h的课程(持续更ing)

vue3 主要内容 核心&#xff1a;ref、reactive、computed、watch、生命周期 常用&#xff1a;hooks、自定义ref、路由、pinia、miit 面试&#xff1a;组件通信、响应式相关api ----> 笔记&#xff1a;ts快速梳理&#xff1b;vue3快速上手.pdf 笔记及大纲 如下&#xff…...

【JAVA】Java开发小游戏 - 简单的2D平台跳跃游戏 基本的2D平台跳跃游戏框架,适合初学者学习和理解Java游戏开发的基础概念

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c; 忍不住分享一下给大家。点击跳转到网站 学习总结 1、掌握 JAVA入门到进阶知识(持续写作中……&#xff09; 2、学会Oracle数据库入门到入土用法(创作中……&#xff09; 3、手把…...

C++ constexpr(八股总结)

答&#xff1a;这个关键字用于指示一个变量、函数或者对象可以在编译时求值&#xff08;即它们是常量表达式&#xff09;。这意味着当程序编译时&#xff0c;编译器会尝试计算出该表达式的值&#xff0c;而不是在程序运行时计算它&#xff0c;从而提高了程序的性能。 常量表达…...

继承(5)

大家好&#xff0c;今天我们继续来学习继承的相关知识&#xff0c;来看看子类构造方法&#xff08;也叫做构造器&#xff09;是如何做的。 1.6 子类构造方法 父子父子,先有父再有子,即:子类对象构选时,需要先调用基类构造方法,然后执行子类的构造方法 ★此时虽然执行了父类的…...

Oracle Dataguard(主库为 RAC 双节点集群)配置详解(1):安装 Oracle11g RAC 双节点集群

Oracle Dataguard&#xff08;主库为 RAC 双节点集群&#xff09;配置详解&#xff08;1&#xff09;&#xff1a;安装 Oracle11g RAC 双节点集群 目录 Oracle Dataguard&#xff08;主库为 RAC 双节点集群&#xff09;配置详解&#xff08;1&#xff09;&#xff1a;安装 Orac…...

基于Matlab的变压器仿真模型建模方法(13):单相升压自耦变压器的等效电路和仿真模型

1.单相升压自耦变压器的基本方程和等效电路 单相升压自耦变压器的接线原理图如图1所示。在建立自耦变压器的基本方程时,仍然把它看成是从双绕组变压器演变而来。在图1中,设节点a到节点b部分的绕组的匝数为,对应于双绕组变压器的原边绕组;节点c到节点a部分的绕组的绕组匝数为…...

ffmpeg 常用命令

更详细请参考ffmpeg手册&#xff0c;下载ffmpegrelease版后在doc中就有&#xff0c;主页面。video filter 参考ffmpeg-filters.html -version -formats -demuxers -protocols -muxers -filters -devices —pix_fmts -codecs -sample_fmts -decoders -layouts -encoders -colors…...

c#集成itext7导出pdf,包含表格

在Nuget解决方案中搜索itext7&#xff0c;进行安装 同时还要安装 itext7.bouncy-castle-adapter。 否则 PdfWriter writer new PdfWriter(pdfOutputPath);执行时会报错unknown PdfException&#xff0c;然后生成一个空白的pdf&#xff0c;且显示已损坏。 捕获异常发现 ex.In…...

STM32-WWDG/IWDG看门狗

WWDG/IWDG一旦开启不能关闭&#xff0c;可通过选项字节在上电时启动硬件看门狗&#xff0c;看门狗计数只能写入不能读取。看门狗启用时&#xff0c;T6bit必须置1&#xff0c;防止立即重置。 一、原理 独立看门狗-超时复位 窗口看门狗-喂狗&#xff08;重置计数器&#xff0c;…...

后台管理系统引导功能的实现

引导是软件中经常见到的一个功能&#xff0c;无论是在后台项目还是前台或者是移动端项目中。 那么对于引导页而言&#xff0c;它是如何实现的呢&#xff1f;通常情况下引导页是通过 聚焦 的方式&#xff0c;高亮一块视图&#xff0c;然后通过文字解释的形式来告知用户该功能的作…...

Flink如何设置合理的并行度

一个Flink程序由多个Operator组成(source、transformation和 sink)。 一个Operator由多个并行的Task(线程)来执行, 一个Operator的并行Task(线程)数目就被称为该Operator(任务)的并行度(Parallel)。即并行度就是相对于Operator来说的。 合理设置并行度可以有效提高Flink作业…...

【JMeter】单接口

1. HTTPS接口 前置准备: ​​​​​​​下载被测网站的证书在cmd利用java工具keytool.exe重新生成store证书 先进入存放该程序的盘 使用命令: keytool -import -alias "xxxx.store" -file "D:\xxx.cer" -keystore xx.store 根据提示信任证书 在JMeter菜…...

安科瑞Acrel-1000DP分布式光伏监控系统在浙江安吉成3234.465kWp分布式光伏发电项目中的应用

摘 要&#xff1a;分布式光伏发电站是指将光伏发电组件安装在用户的建筑物屋顶、空地或其他适合的场地上&#xff0c;利用太阳能进行发电的一种可再生能源利用方式&#xff0c;与传统的大型集中式光伏电站相比&#xff0c;分布式光伏发电具有更灵活的布局、更低的建设成本和更高…...

电子应用设计方案87:智能AI收纳箱系统设计

智能 AI 收纳箱系统设计 一、引言 智能 AI 收纳箱系统旨在为用户提供更高效、便捷和智能的物品收纳与管理解决方案&#xff0c;通过融合人工智能技术和创新设计&#xff0c;提升用户的生活品质和物品整理效率。 二、系统概述 1. 系统目标 - 实现物品的自动分类和整理&#xf…...

C++泛型编程:多参数函数模版、动态数组类

在多参数函数模版中&#xff0c;有以下几点&#xff1a; 第一点是函数模版支持多个类型参数 第二点是一旦有类型不能推导&#xff0c;就会导致编译失败 第三点是返回值类型无法作为推导依据 其中第二点和第三点&#xff0c;在下面代码中有体现&#xff0c;首先是第三点&…...

点亮一个esp32 的led

最近入了一个ESP32 兄弟们&#xff0c;这玩意还可以&#xff0c;买来肯定是给它点亮啊对吧 我就是点灯侠&#x1f387; &#x1f62d;千万不要不接天线啊&#xff0c;不然你会一直找不到你的wifi 1.点灯第一步你得有IDE Arduino 就是这个绿东西 可是怎么下载安装呢&#xff…...

【计算机视觉】单目深度估计模型-Depth Anything-V2

概述 本篇将简单介绍Depth Anything V2单目深度估计模型&#xff0c;该模型旨在解决现有的深度估计模型在处理复杂场景、透明或反射物体时的性能限制。与前一代模型相比&#xff0c;V2版本通过采用合成图像训练、增加教师模型容量&#xff0c;并利用大规模伪标签现实数据进行学…...

新年感悟:2025年1月7日高铁随想

2025年1月7日&#xff0c;乘坐在从珠海去广州南的C7676高铁上&#xff0c;突然悟明白两个事情。 首先&#xff0c;不管学习任何东西&#xff0c;总结是一个非常关键的经验。以前&#xff0c;总是幻想着能找到一本书&#xff0c;或者一个特别优秀的老师&#xff0c;仅仅通过看看…...

C++ 入门第25天:线程池(Thread Pool)基础

往期回顾&#xff1a; C 学习第22天&#xff1a;智能指针与异常处理-CSDN博客 C 入门第23天&#xff1a;Lambda 表达式与标准库算法入门-CSDN博客 C 入门第24天&#xff1a;C11 多线程基础-CSDN博客 C 入门第25天&#xff1a;线程池&#xff08;Thread Pool&#xff09;基础 前…...

嵌入式驱动开发详解10(MISC杂项实现)

文章目录 前言MISC设备驱动简介重要结构体API函数MISC实现框架后续参考文献 前言 MISC 驱动也叫做杂项驱动&#xff0c;也就是当我们板子上的某 些外设无法进行分类的时候就可以使用 MISC 驱动。MISC 驱动其实就是最简单的字符设备驱 动&#xff0c;通常嵌套在 platform 总线驱…...

CSS语言的编程范式

CSS语言的编程范式 前言 随着互联网的快速发展&#xff0c;前端开发逐渐演变为一个复杂而多元化的领域。作为前端开发的重要组成部分&#xff0c;CSS&#xff08;层叠样式表&#xff09;在网页设计和用户体验中扮演着至关重要的角色。CSS不仅仅是一种样式表语言&#xff0c;更…...

游戏引擎学习第77天

仓库: https://gitee.com/mrxiao_com/2d_game 回顾昨天的 bug 今天我们继续开发进度&#xff0c;进行调试昨天代码的问题&#xff0c;主要是关于如何跟踪玩家和敌人在世界中的高度位置。虽然我们做的是一款 2D 游戏&#xff0c;但我们希望能够处理多层的房间&#xff0c;玩家…...

Python编程实例-机器学习中的Hinge Loss编程实现

机器学习中的Hinge Loss编程实现 文章目录 机器学习中的Hinge Loss编程实现1、机器学习中的损失函数是什么?2、什么是 Hinge Loss?3、Hinge Loss如何工作?4、Hinge Loss的优缺点5、Python语言实现6、总结Hinge Loss(铰链损失)在分类任务中至关重要,广泛应用于支持向量机 …...

算法练习----2025/1/7

题目 计算素数函数f(N)代表素数的个数小于等于N例如 f(17)7 , 因为前7个素数为 2&#xff0c;3&#xff0c;5&#xff0c;7&#xff0c;11&#xff0c;13&#xff0c;17思路 1、首先创建一个布尔类型的数组&#xff08;Python 中用列表模拟&#xff09;来标记每个数是否为素…...

【C++】穿越编程岁月,细品C++进化轨迹,深化入门基石(续章)——揭秘函数缺省参数的魅力、函数重载的艺术、引用的奥秘与内联函数的效率

文章目录 一、函数缺省参数二、函数重载三、引用1.引用的概念和定义2.引用的特性3.引用的使用4.const引用5.指针和引用的关系 四、inline内联函数和nullptr1.inline2.nullptr 一、函数缺省参数 缺省参数其实就是默认参数&#xff0c;它是声明或定义函数时为函数的参数指定⼀个缺…...

1/7 Spring三级缓存

首先我们来spring创建bean首先通过反射创建bean原始对象&#xff0c;然后通过 填充里面的属性&#xff0c;然后如果有AOP的话&#xff0c;那么就会创建这个代理对象&#xff0c;最后将代理对象传入这个单例池中 如何解决循环依赖问题的 比如A依赖B,B依赖A 如果在单例池没有找…...

【RK3568笔记】Android修改开机动画

概述 Android 的开机动画是由一系列连续的 PNG 图片作为帧组成的动画形式&#xff0c;不是一张 GIF 图片。将各帧 PNG 图片以压缩方式进行保存&#xff08;压缩方式要求是存储压缩&#xff09;&#xff0c;并将保存的文件名命名为 bootanimation.zip&#xff0c;这个 bootanim…...

牛客网刷题 ——C语言初阶(5操作符)——JZ15 二进制中1的个数

1.题目描述 题目OJ链接 描述 输入一个整数 n &#xff0c;输出该数32位二进制表示中1的个数。其中负数用补码表示。 2.思路 求2进制中1的个数&#xff0c;可以转换为求每一位&#xff0c;1的个数&#xff0c;1&1还是1 所以判断如果该数值&1为真&#xff0c;我们就co…...