DSL - Wire 实现-ApiHug101

news2024/11/24 20:55:52

  🤗 ApiHug × {Postman|Swagger|Api...} = 快↑ 准√ 省↓

  1. GitHub - apihug/apihug.com: All abou the Apihug   
  2. apihug.com: 有爱,有温度,有质量,有信任
  3. ApiHug - API design Copilot - IntelliJ IDEs Plugin | Marketplace

docs/handbook/004_dsl_implement_wire.md · dearxuecom/apihug.com - Gitee.comicon-default.png?t=N7T8https://gitee.com/dearxuecom/apihug.com/blob/master/docs/handbook/004_dsl_implement_wire.md#api

API

Service 概念对应 GRPC 中 Service 供应方。 方法对应具体服务, 对应 OAS中的Paths Object

Service

hope.swagger.svc 定义服务元信息扩展:

extend google.protobuf.ServiceOptions {

    ServiceSchema svc = 1044;
}

message ServiceSchema {
    //The tag of this service
    Tag tag = 1;

    //The base path of this service
    string path = 2;

    // Description of this Service
    string description = 1044;
}
名词用途说明
tag服务标签对象Tag
path服务基础前缀,默认/string
description服务描述string

Method

hope.swagger.operation 定义方法元信息扩展:

extend google.protobuf.MethodOptions {
    Operation operation = 1042;
}

MethodOptions operation 描述, Operation 对象

字段类型说明
request_name输入参数命名单 input 对象在函数中的命名,如果有parameter说明这个不需要,否则会自动推算 _0(1,2,3) 这样子比较丑,帮助代码生成器用
priorityPriority 枚举devops 流程控制,参考
pageable是否支持pageable入参有PageRequest, 结果自动分页包装 参考
raw是否原始值如非原始包装,会统一Result 风格封装
request是否带原始的request比如servlet 协议手动处理
response是否带原始的response比如servlet协议手动处理
session是否带session视具体框架实现
input_plural输入是数组输入对象数组包装 List, 避免proto 对象定义爆炸
out_plural输出是数组输出对象数组包装 List, 避免proto 对象定义爆炸
patternget/put/post/delete/patch目前只支持者几个对象 oneof, http action 语义
parameters参数对象是一个 Parameter 数组对象
Priority 枚举类型

开发流程审批规范:

字段类型说明
LOW重要度低开发者交叉审批
MIDDLE重要度中等开发组长审批
HIGH重要度高项目管理者审批
CRITICAL重要度很高总监审批
FATAL重要度致命CTO审批
Parameter 参数对象

⚠️ 0.2.6-RELEASE 以后版本: 如果是 GET 类型

  1. 禁止 input type 定义非引用对象, 复杂对象一律通过引用对象定义
  2. 预定义对象(number/string/date 等)可以通过 parameters 定义

否则在 wire 阶段会报错:

proto illegal define @service.proto  TestService#GetUserInfo

It is a GET action, only support [google.protobuf.Empty] input or an reference Object while we got: google.protobuf.IntValue

all primitive types(int,long,date etc) please define in the [parameters] part, otherwise may mess the parameter judge!

因为在 input 定义, 然后又在 parameters 定义(没有语法错误), 导致难判断, 到底用那个?

在非 post 传递, 非 body 对象时候使用,

  1. RPC 定义 input 最好是个 Empty, 所有参数都在 hope.swagger.operation#parameters 中定义(⚠️最标准做法⚠️)
  2. 如果是 Message 这个 Message 也会被当做 parameter 而非 RequestBody!
  3. 可以承接多个对象,
    1. 可以是原始对象: int/string/date/uuid 等,
    2. 或者是封装对象 MessageEnum
rpc DeleteOrder (google.protobuf.Empty) returns (google.protobuf.StringValue) {
        option (hope.swagger.operation) = {
            post: "/delete-order";
            description: "删除订单",
            tags: "order";
            priority: CRITICAL;
            parameters: {
                parameter: {
                    name: "order-id";
                    in: QUERY;
                    scheme: {
                        type: STRING;
                        empty: {
                            value: false;
                        }
                        field_configuration: {
                            path_param_name: "orderId"
                        }
                    }
                }
            }
        };

};
字段类型说明
name参数名词写标准点, 转换成方法字段会自动推理, 比如 hello-world --> helloWorld
in参数类型参考下面枚举
schemeJSONSchemaJSONSchema
plural是否列表boolean
IN 参数

类型 OAS 参数对象

字段类型说明
QUERYparameterpath/arg1=123, arg1 参数
HEADERHTTP 协议头比如JWT, 或者扩展字段
PATH路径/path/{arg}/helloarg 记得必须是 {}, 目前没有强制校验
COOKIE来自cookie 参数视底层框架
SESSION来自session 参数视底层框架

Resource

Message

hope.swagger.schema 为 MessageOptions 用来描述类型对象: OAS Schema对象

extend google.protobuf.MessageOptions {
    Schema schema = 1042;
}
message QueryTenantRoleRequest {
  option (hope.swagger.schema) = {
    json_schema: {
      description: "查询角色列表";
    };
  };
}

消息整体的描述, 侧重消息的基本描述 descriptionexamplediscriminator,read_onlyexternal_docs 当前未做解析 ⚠️。

JSONSchema

字段描述 hope.swagger.field 为 FieldOptions, 扩展 JSONSchema 上面:

extend google.protobuf.FieldOptions {
    JSONSchema field = 1042;
}

扩展字段:

字段类型说明
descriptionstring描述
defaultstring默认值
examplestring示例
multiple_ofgoogle.protobuf.DoubleValue倍数
maximumgoogle.protobuf.DoubleValue最大值
exclusive_maximumgoogle.protobuf.BoolValue区间是否包含最大值
minimumgoogle.protobuf.DoubleValue最小值
exclusive_minimumgoogle.protobuf.BoolValue区间是否包含最小值
max_lengthgoogle.protobuf.UInt64Value最大长度,string类型
min_lengthgoogle.protobuf.UInt64Value最小长度,string类型
max_itemsgoogle.protobuf.UInt64Valuerepeated 集合类型字段,最多元素数目
min_itemsgoogle.protobuf.UInt64Valuerepeated 集合类型字段,最多元素数目
unique_itemsgoogle.protobuf.BoolValuerepeated 集合类型字段,元素是否唯一,List vs Set
typeJSONSchemaTypeHint😢
formatstringJSONSchemaFormat
field_configurationFieldConfiguration✋ 参考
emptygoogle.protobuf.BoolValue是否可以为空-校验
patternstringvalidation 扩展:正值表达式验证 javax.validation.constraints.Pattern("^A-z$")
assertgoogle.protobuf.BoolValuevalidation 扩展: javax.validation.constraints.AssertTrue\AssertFalse
decimal_maxstringvalidation 扩展:javax.validation.constraints.DecimalMax(value = "0.0", inclusive = false)
decimal_minstringvalidation 扩展:javax.validation.constraints.DecimalMin(value = "0.0", inclusive = false)
digits_integergoogle.protobuf.Int32Valuevalidation 扩展:javax.validation.constraints.Digits(integer=3, fraction=2)
digits_fractiongoogle.protobuf.Int32Valuevalidation 扩展:javax.validation.constraints.Digits(integer=3, fraction=2)
emailgoogle.protobuf.BoolValuevalidation 扩展:javax.validation.constraints.Email
time_constraint_typeTimeConstraintTypevalidation 扩展:枚举参考下面 TimeConstraintType
date_formatDateFormat日期format: 日期枚举类型参考下面 DateFormat
customized_date_formatstring定制日期类型:符合标准日期定义规范(未强校验)
mockMockMock规则 🏗️
read_onlybool未用 🚧
extensionsmap<string, google.protobuf.Value>未用 🚧,扩展说明
enumrepeated string未用 🚧
requiredrepeated string未用 🚧, 范围选择,通过枚举对象实现
arrayrepeated string未用 🚧, 列表元素可选范围,通过枚举对象实现
refstring未用 🚧, 外部对象引用,需全路径指定 parameter配置时,如引用 Enum 对象
titlestring未用 🚧, 标题, 字段名称替代
max_propertiesgoogle.protobuf.UInt64Value未用 🚧,Map元素最多key?
min_propertiesgoogle.protobuf.UInt64Value未用 🚧,Map元素最多key?

⚠️ 由于框架层引入常量设计机制, 所以很多需要通过 enumrequiredarray 控制的,通过枚举控制均都可弱化和替代掉。

FieldConfiguration
message FieldConfiguration {
        string path_param_name = 47;
}

在Parameter 参数对象 中定义灵活对象时, 在路径参数上对象和宿主语言命名有时候有冲突; 比如 参数 {user-id} 在java 中无法使用 user-id 命名参数, 中划线 - 为字段命名非法字符,如果不设定,会隐式的转换成 userId, 但是同时也可以自己定义:

field_configuration: {
    path_param_name: "orderIdAnother"
}
JSONSchemaFormat

为避免复杂度, JSONSchemaTypeHint 自 0.3.3.RELEASE 被合并到 format

和 format 合并了OpenApi format (OpenAPI Specification v3.1.0,2023-12) + 部分自有扩展。

一般 Message 字段定义已经包含 显式 类型定义: 内置类型或者引用类型, 但是在 option 里的定义无法设定,比如在Parameter 参数对象。

所以需要这里 隐式 的制定类型, 或者需要强制将内置类型对象转换成语言特定对象, 比如 string 隐式 成一个 DateTime, 方便代码生成器推导宿主语言对象类型。

字段类型说明OAS format
BOOLEANbool类型booleanbool
INTEGERinteger整型int32
DOUBLE数字doubledouble
STRINGstring字符串-
FLOATfloat浮点类型float
BIG_DECIMALbigDecimal精度数字big-decimal
LONGlong长整型int64
DATEdate日期date
DATE_TIMEdateTime日期时间date-time
TIMEtime时间time
UUIDuuidUUID 对象uuid
PASSWORDpassword密码对象password
EMAILemail邮箱对象email
BINARYbinary文件对象binary

⚠️ 谨慎使用,这也是为什么我们推崇,复杂对象通过 Message 定义, 避免这种 Ad-hoc Path/Query/Header 隐式推断; 固然通过强制 仅支持 post可以尽量避免, 但是 ApiHug 还是兼容了这些古老的做法。

TimeConstraintType
字段类型说明
FUTURE时间校验@javax.validation.constraints.Future
FUTURE_OR_PRESENT时间校验@javax.validation.constraints.FutureOrPresent
PAST时间校验@javax.validation.constraints.Past
PAST_OR_PRESENT时间校验@javax.validation.constraints.PastOrPresent
DateFormat 枚举类型

预定义formatter java.time.format.DateTimeFormatter

或自定义 customized_date_format, 最好用预定义的, 通过了校验测试。

如果使用 customized_date_format 推导宿主语言类型有不确定性⚠️, 而预定义可以分化: DateTimeTimeDate 更细的分类 ⭐⭐⭐。

字段类型说明
BASIC_ISO_DATEyyyyMMdd比如 20111203 类型 LocalDate
ISO_LOCAL_DATEyyyy-MM-dd比如 2011-12-03 类型 LocalDate
ISO_LOCAL_TIMEHH:mm:ss比如 10:15:30 类型 LocalTime
ISO_LOCAL_DATE_TIMEyyyy-MM-dd T HH:mm:ss比如 2011-12-03T10:15:30 类型 LocalDateTime
YYYY_MM_DD_HH_MM_SSyyyy-MM-dd HH:mm:ss类型 LocalDateTime
YYYY_MM_DD_HH_MM_SS_SSSyyyy-MM-dd HH:mm:ss:SSS类型 LocalDateTime
SLASH_YYYY_MM_DDyyyy/MM/dd类型 LocalDate
SLASH_YYYY_MM_DD_HH_MM_SSyyyy/MM/dd HH:mm:ss类型 LocalDateTime
SLASH_YYYY_MM_DD_HH_MM_SS_SSSyyyy/MM/dd HH:mm:ss:SSS类型 LocalDateTime
HH_MMHH:mm类型 LocalTime

自定义格式日期时间判断方式:

  1. Date 判断包含任何一个:
    1. yyyy
    2. MM
    3. dd
  2. Time 判断包含任何一个:
    1. HH
    2. mm
    3. ss
    4. SSS

Enum

Hope 框架里,引入了 枚举常量的设计, 大大减少了常量的硬编码, Enum 在宿主语言 JavacGo 等都有完整的支持。

同时在 Enum 上又扩展了:错误码 Error + Authority类型。

hope.swagger.enm 为 EnumOptions 用来描述常量对象:

extend google.protobuf.EnumOptions {
    JSONSchema enm = 1042;
}

hope.constant.field 为 EnumValueOptions 用来描述常量值对象:

extend google.protobuf.EnumValueOptions {
  Meta field = 37020;
}
message Meta {

  int32 code = 1;
  string message = 2;
  string cn_message = 3;

  Error error = 4;
}
名词用途说明
code错误代码int
message错误信息string
cn_message错误信息(中)string
Error

错误枚举,在枚举上扩展 Error error = 4; 字段包含;

字段类型说明
titlestring简单标题
tipsstring提示
http_statusHttpStatusHttp 错误码
phasePhase阶段,参考下面文档
severitySeverity严重程度,参考下面文档
错误阶段
字段类型说明
CONTROLLERController表单层
SERVICEService服务层
DOMAINDomain领域层
错误严重性
字段类型说明
LOW低,无影响
WARN警告警告,业务错误可重试
ERROR错误错误,业务无法进行
FATAL灾难灾难,数据破坏
Authority

Authority 为标准 Enum 类型, 在 Wire项目的元信息中指定 authority meta:

 "authority" : {
    "enumClass" : "hope.we.proto.infra.enumeration.authority.SystemAuthorityEnum",
    "codePrefix" : 11000000
  }
Map

对于Map类型字段,处理比较头疼, 如果混合宿主语言特征,会非常棘手, 比如 key, value 都有 Generic 特性。 综合:OAS Dictionaries, HashMaps and Associative Arrays, Protobuf: Maps Features 如下约束:

  1. Key, Value 不能 Generic 也就是只能固定类型, 宿主语言内的变幻, 无法控制,比如子类判断。
  2. 参考 Protobuf Map 将 key, value 转换成独立 Message 对象。

Meta

项目基本元信息 resources\hope-wire.json

{
  "packageName": "hope.we",
  "name": "bigger-project-proto",
  "application": "bigger-project",
  "domain": "hope",
  "persistence" : {
    "identifyType" : "LONG",
    "tenantType" : "LONG"
  },
  "authority" : {
    "enumClass" : "hope.we.proto.infra.enumeration.authority.SystemAuthorityEnum",
    "codePrefix" : 11000000
  },
  "createdAt": "2023-01-01",
  "createdBy" : "Aaron",
  "api": {
    "openapi" : "3.0.1",
    "info" : {
      "contact" : {
        "name" : "developer@apihug.com",
        "url" : "https://github.com/hope/apihug",
        "email" : "developer@apihug.com"
      }
    },
    "externalDocs" : {
      "description" : "Hope is the best thing",
      "url" : "https://github.com/hope/apihug/"
    },
    "tags" : [ {
      "name" : "tenant",
      "description" : "租户操作"
    }, {
      "name" : "platform",
      "description" : "平台操作"
    }]
  }
}
名称说明类型值(默认)备注
packageName包名Sting必须项目包名,符合java包命名规范,不可包含预留: wirestub 关键字
name项目名称Sting必须项目标识,符合 artifact ID, 小写,中文标识,proto后缀比如: user-info-proto
application应用项目Sting必须和proto配套项目名称, 一般是name 去掉 proto 后缀比如: user-info
module模块名称Sting必须用在运行时 service locator定位, 如无设置 name替代, domain+module需要保证运行时唯一
domain领域名Sting必须属于领域
description描述Sting可选描述
persistence.identifyType数据库,账号类型Sting可选数据设计,有账号ID标识时启用, STRING|INTEGER|LONG
persistence.tenantType数据库,租户类型Sting可选数据设计,有多租户标识时启用, STRING|INTEGER|LONG
authority.enumClass验权,权限类型枚举Sting可选验权设计,权限枚举类,必须在 proto 有定义,编译时校验
authority.codePrefix验权,权限标识段Long可选验权设计,多模块下,权限标识代码分段,避免重复,比如100000 为user权限区间段,100001为第一个

OAS

只包含基本的 OAS 说明:

  1. openapi OAS 兼容 版本
  2. info OAS 基本 Info
  3. tag OAS 标签 Tag

⚠️其他信息,请勿这里定义,定义也会被忽略!

文件上传

协议定义✏️:

  1. 方法:POST (必须)
  2. consumes 类型: multipart/form-data (必须)
  option (hope.swagger.operation) = {
    post: "/upload-meta";
    consumes: "multipart/form-data";
  };

字段定义 format: "binary":

  // Binary format meaning a file.
  string file = 5 [(hope.swagger.field) = {
    format: "binary"
  }];

  repeat bytes files = 6;

支持单文件, 多文件批量上传;

  1. format: "binary" 自身类型 string 将被忽略;
  2. bytes 类型,自动被识别为 binary 文件类型;
  3. 支持 repeat 多文件批量上传;
  4. 支持附带属性。
message SampleUploadRequest {
  option (hope.swagger.schema) = {
    json_schema: {
      description: "An example to upload a single file";
    };
  };

  string name = 4 [(hope.swagger.field) = {
    description: "new name of this upload file";
    example: "just_another_file"
    max_length: {
      value: 64
    }
  }];


  // Binary format meaning a file.
  string an_file = 5 [(hope.swagger.field) = {
    format: "binary"
  }];
}

Command

配置 wire 项目模块 build.gradle

plugins {
    id "java-library"
    id "com.apihug.wire"
}


hopeWire {
    verbose = true
}

刷新本模块的 gradle 后, 在task 列表可以看到 wire 命令被添加进来, 运行此模块下的 wire 命令 gradlew wire

  1. main\wire 生成运行时代码
  2. main\resources 生成编译元信息
名称说明类型(默认)备注
disable插件调试booleanfalse依赖注入完成,不添加额外 Task,调试测试用
smock插件调试booleanfalse上面步骤完成 + Task 注入完毕, 不执行最后的生成动作,调试测试用
debug插件调试booleanfalse上面步骤完成 + 执行生成动作第一阶段准备, 不最终触发动作,调试测试用
restrict非扩展类型是否隐式转换booleanfalsegoogle.protobuf.Timestamp 定义是否支持默认转换到 local time
verbose执行过程log打开booleanfalse出问题打开,过程全log打开调试
generatedVersion是否携带生成插件版本booleanfalse生成代码 @Generated 说明是否携带插件版本
generatedTime是否携带生成时间戳booleanfalse生成代码 @Generated 说明是否携带生成时间戳
pluginMainVersion插件辅助版本Stringwire 插件版本运行时依赖版本,非必要勿设置,Apihug整体包BOM发行,勿手动设置这个版本
pluginMainClass插件辅助入口MainString如非扩展了插件,勿设置
local本地插件booleanfalse依赖自己扩展插件,如不是,勿设置
protocVersionprotoc版本StringWire发行时候自带,可以自行定义(可能导致不兼容风险)
grpcVersiongrpc版本StringWire发行时候自带,可以自行定义(可能导致不兼容风险)
keepProto是否包含proto原编译文件booleanfalsewire项目发行时候是否携带protoc编译结果,除项目间有深度逻辑依赖,共享的应局限在POJO对象这层
wireProtoBufGradlePluginVersionprotobuf插件版本String未启用
validationVersionValidation版本String未启用
swaggerVersionSwagger版本String未启用

Refer

  1. The OpenAPI Specification
  2. OpenAPI Specification Version 3.1.0 since 2023.
  3. Spring file upload
  4. ApiHug101-Bilibili
  5. ApiHug101-Youtube

秒懂 ApiHug -005 加个对象

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

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

相关文章

javaScript手写专题——防抖/节流/闭包/Promise/深浅拷贝

目录 目录 一、 防抖/节流/闭包/定时器 编写一个组件&#xff0c;在input中输入文本&#xff0c;在给定的数据中查找相关的项目&#xff0c;并渲染搜索结果列表 1.新增InputSearch.vue组件 key的作用 2.新增 InputView.vue 3.添加路由 4.效果演示 follow up加上防抖怎么处理 1.…

如何从头开始编写LoRA代码,这有一份教程

ChatGPT狂飙160天&#xff0c;世界已经不是之前的样子。 新建了免费的人工智能中文站https://ai.weoknow.com 新建了收费的人工智能中文站https://ai.hzytsoft.cn/ 更多资源欢迎关注 作者表示&#xff1a;在各种有效的 LLM 微调方法中&#xff0c;LoRA 仍然是他的首选。 LoRA&…

机器学习-随机森林算法预测温度

文章目录 算法简介解决问题获取数据集探索性数据分析查看数据集字段信息查看数据集综合统计结果查看特征值随时间变化趋势 数据预处理处理缺失数据字符列编码数据集分割训练集、验证集、测试集数据集分割 构建模型并训练结果分析与评估进一步优化实际使用经验总结 算法简介 随…

基于遗传优化的SVD水印嵌入提取算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 5.完整程序 1.程序功能描述 基于遗传优化的的SVD水印嵌入提取算法。对比遗传优化前后SVD水印提取性能&#xff0c;并分析不同干扰情况下水印提取效果。 2.测试软件版本以及运行结果展示 MA…

深度学习实践(一)基于Transformer英译汉模型

本文目录 前述一、环境依赖二、数据准备1. 数据加载2. 构建单词表程序解析&#xff08;1&#xff09;将列表里每个子列表的所有单词合并到一个新列表&#xff08;没有子列表&#xff09;中。&#xff08;2&#xff09;Counter&#xff08;&#xff09;-- 统计迭代对象各元素出现…

【Spring AOP】@Aspect结合案例详解(一): @Pointcut使用@annotation + 五种通知Advice注解(已附源码)

文章目录 前言AOP与Spring AOPAspect简单案例快速入门 一、Pointcutannotation 二、五种通知Advice1. Before前置通知2. After后置通知3. AfterRunning返回通知4. AfterThrowing异常通知5. Around环绕通知 总结 前言 在微服务流行的当下&#xff0c;在使用SpringCloud/Springb…

Mogdb双网卡同步最佳实践

大家都知道Oracle数据库无论是单机还是RAC集群在进行生产部署实施时&#xff0c;我们都会对网卡做冗余考虑&#xff0c;比如使用双网卡&#xff0c;比如public、心跳网络。这样的目的主要是为了安全&#xff0c;避免淡点故障。当然也网卡Bond不仅是可以做主备还可以支持负载均衡…

redis分布式锁+redisson框架

目录 &#x1f9c2;1.锁的类型 &#x1f32d;2.基于redis实现分布式 &#x1f953;3. 基于redisson实现分布式锁 1.锁的类型 1.本地锁&#xff1a;synchronize、lock等&#xff0c;锁在当前进程内&#xff0c;集群部署下依旧存在问题2.分布式锁&#xff1a;redis、zookeeper等…

OLAP介绍

OLAP OLAP介绍 Rollup OLAP&#xff08;在线分析处理&#xff09;的上下文中&#xff0c;"Rollup"是一个重要的概念&#xff0c;它指的是在多维数据集中自动地聚合数据到更高的层次或维度的过程。这种操作通常用于快速计算和展示汇总数据&#xff0c;以便于用户进…

包和final.Java

1&#xff0c;包 包就是文件夹。用来管理不同功能的Java类&#xff0c;方便后期代码的维护。 &#xff08;1&#xff09;包名的规则是什么&#xff1f; 公司域名反写报的作用&#xff0c;需要全部英文小写&#xff0c;见名知意。com.itheima.domain &#xff08;2&#xff…

15.队列集

1.简介 在使用队列进行任务之间的“沟通交流”时&#xff0c;一个队列只允许任务间传递的消息为同一种数据类型&#xff0c;如果需要在任务间传递不同数据类型的消息时&#xff0c;那么就可以使用队列集。FreeRTOS提供的队列集功能可以对多个队列进行“监听”&#xff0c;只要…

Redis高级-分布式缓存

分布式缓存 – 基于Redis集群解决单机Redis存在的问题 单机的Redis存在四大问题&#xff1a; 0.目标 1.Redis持久化 Redis有两种持久化方案&#xff1a; RDB持久化AOF持久化 1.1.RDB持久化 RDB全称Redis Database Backup file&#xff08;Redis数据备份文件&#xff09;…

QT drawPixmap和drawImage处理图片模糊问题

drawPixmap和drawImage显示图片时&#xff0c;如果图片存在缩放时&#xff0c;会出现模糊现象&#xff0c;例如将一个100x100 的图片显示到30x30的区域&#xff0c;这个时候就会出现模糊。如下&#xff1a; 实际图片&#xff1a; 这个问题就是大图显示成小图造成的像素失真。 当…

FPGA(Verilog)实现按键消抖

实现按键消抖功能&#xff1a; 1.滤除按键按下时的噪声和松开时的噪声信号。 2.获取已消抖的按键按下的标志信号。 3.实现已消抖的按键的连续功能。 Verilog实现 模块端口 key_filter(input wire clk ,input wire rst_n ,input wire key_in , //按下按键时为0output …

[NKCTF2024]-PWN:leak解析(中国剩余定理泄露libc地址,汇编覆盖返回地址)

查看保护 查看ida 先放exp 完整exp&#xff1a; from pwn import* from sympy.ntheory.modular import crt context(log_leveldebug,archamd64)while True:pprocess(./leak)ps[101,103,107,109,113,127]p.sendafter(bsecret\n,bytes(ps))cs[0]*6for i in range(6):cs[i]u32(p…

6.模板初阶(函数模板、类模板、类模板声明与定义分离)

1. 泛型编程 如何实现一个通用的交换函数呢&#xff1f; 使用函数重载虽然可以实现&#xff0c;但是有一下几个不好的地方&#xff1a; 重载的函数仅仅是类型不同&#xff0c;代码复用率比较低&#xff0c;只要有新类型出现时&#xff0c;就需要用户自己增加对应的函数代码的…

线性、逻辑回归算法学习

1、什么是一元线性回归 线性&#xff1a;两个变量之间的关系是一次函数&#xff0c;也是数据与数据之间的关系。 回归&#xff1a;人们在测试事物的时候因为客观条件所限&#xff0c;求的都是测试值&#xff0c;而不是真实值&#xff0c;为了无限接近真实值&#xff0c;无限次的…

HarmonyOS开发实例:【状态管理】

状态管理 ArkUI开发框架提供了多维度的状态管理机制&#xff0c;和UI相关联的数据&#xff0c;不仅可以在组件内使用&#xff0c;还可以在不同组件层级间传递&#xff0c;比如父子组件之间&#xff0c;爷孙组件之间等&#xff0c;也可以是全局范围内的传递&#xff0c;还可以是…

【考研数学】1800还是660还是880?

关于这几本习题册如何选择&#xff0c;肯定是根据他们的不同特点以及我们的需求结合选择&#xff0c;给大家的建议如下&#xff1a; 1800适合初期&#xff0c;可以帮助你熟悉数学公式和基础定义&#xff0c;迅速上手用。刚开始觉得难很正常&#xff0c;存在一个上手的过程&…

VRRP虚拟路由实验(思科)

一&#xff0c;技术简介 VRRP&#xff08;Virtual Router Redundancy Protocol&#xff09;是一种网络协议&#xff0c;用于实现路由器冗余&#xff0c;提高网络可靠性和容错能力。VRRP允许多台路由器共享一个虚拟IP地址&#xff0c;其中一台路由器被选为Master&#xff0c;负…