风控系统之普通规则条件,使用LiteFlow实现
个人博客:无奈何杨(wnhyang)
个人语雀:wnhyang
共享语雀:在线知识共享
Github:wnhyang - Overview
提要
参考:智能风控筑基手册:全面了解风控决策引擎
前面有可配置输入参数的接口如何设计和风控系统指标计算/特征提取分析与实现01,Redis、Zset、模版方法两篇文章,分别提出:
1、风控系统服务动态选择,根据配置处理输入参数,转换为系统参数
2、使用Redis的zset结构完成简单的指标计算(特征提取)
他们都是一次风控决策流程的一部分,当然完成的风控系统,比较复杂,涉及的功能模块更多,以下仅仅是我的简单梳理。

如上,服务选择和入参处理可配置输入参数的接口如何设计是这篇文章讨论的内容,风控系统指标计算/特征提取分析与实现01,Redis、Zset、模版方法讨论的是规则集内普通指标计算。
本篇文章讨论通过LiteFlow这款规则引擎框架实现风控系统的普通规则条件。
规则条件
规则条件是什么?
我将规则划分如下(未来会逐渐完善),规则条件是规则的一部分。

需要注意的是规则条件应该都是灵活可配置,并不是上面这样并列,可以任意复杂的组合。
为什么只是规则条件灵活可配置呢?操作难道不是吗?
可以,但没必要。
如下,是规则(最近24小时转账次数>=10次)示例。

观察可知,其实右半边可以作为一个新的规则独立出去的,所以说,规则操没必要和规则条件混在一起。

规则引擎LiteFlow
规则引擎是为了解耦,编排而生。
LiteFlow官网:🍤LiteFlow简介 | LiteFlow
LiteFlow官方文档写的已经非常清晰,花费不到一上午的时间就可以了完全了解了,所以我也不多说些什么了。
为什么需要规则引擎
因为独立组件+灵活编排的需求和规则引擎不谋而合。
设计与实现
组件
组件是规则引擎中最重要的一部分,他是所有规则表达式最终业务的实现。
不使用规则引擎时
在不使用规则引擎时,针对前面普通规则条件,可以设计如下的结构。
一条规则关联一组规则条件,规则条件又最多分为两级,一级指明了二级规则条件“与或非”关系,二级是具体的规则条件。具体的规则条件关键字段是:系统字段(property)、字段类型(property_data_type)、操作(operator)、希望的值(value)。
有了如下的结构该怎么使用也很清晰了
1、查规则
2、查规则条件组
3、根据父条件,确定子条件关系
4、代码解析操作类型,返回条件结果
| id | uuid | rule_uuid | parent_uuid | logic_operator | property | property_data_type | operator | value | 
|---|---|---|---|---|---|---|---|---|
| 1 | 270a8dc859a940008539f270ae596ad6 | 86cbd8adff914f67b576f0046b5b337d | ||||||
| 2 | bfbe53d6b5ae4895aef1c4c453e3e16e | 86cbd8adff914f67b576f0046b5b337d | 270a8dc859a940008539f270ae596ad6 | && | ||||
| 3 | cf46348d533a48db8f027e4db4f6bb7a | 86cbd8adff914f67b576f0046b5b337d | bfbe53d6b5ae4895aef1c4c453e3e16e | S_N_EVENTHOUR | INT | >= | 22 | |
| 4 | f759541121664847bbc7d944ad1a553f | 86cbd8adff914f67b576f0046b5b337d | bfbe53d6b5ae4895aef1c4c453e3e16e | S_N_EVENTHOUR | INT | <= | 24 | |
| 5 | ec1e79cc18734fa4ab3daa51fe8597c8 | 86cbd8adff914f67b576f0046b5b337d | bfbe53d6b5ae4895aef1c4c453e3e16e | C_S_FINANCIALCLIENTS | STRING | == | 是 | |
| 6 | 5a3b35c7d1d04466b16ae2da64383e21 | 86cbd8adff914f67b576f0046b5b337d | 270a8dc859a940008539f270ae596ad6 | && | ||||
| 7 | 1bed61e83d7e4ad0a813f2fa3bd7b8a9 | 86cbd8adff914f67b576f0046b5b337d | 5a3b35c7d1d04466b16ae2da64383e21 | S_N_EVENTHOUR | INT | >= | 0 | |
| 8 | 9446d7a9ec284c1ab52c600ac1cfad26 | 86cbd8adff914f67b576f0046b5b337d | 5a3b35c7d1d04466b16ae2da64383e21 | S_N_EVENTHOUR | INT | < | 6 | |
| 9 | 690e668a2e7c445c80b04ef5e30d3fa4 | 86cbd8adff914f67b576f0046b5b337d | 5a3b35c7d1d04466b16ae2da64383e21 | C_S_FINANCIALCLIENTS | STRING | == | 是 | 
使用规则引擎后
首先我们定义组件可以完成字段的比较并返回true/false。
那么上面作为组件的只有id为3、4、5、7、8、9,然后将这些编排成如下表达式即可。
这里简单介绍一些IF表达式,一共三个参数,第一个为条件,后面两个为true执行,false执行,跟三元表达式一样。
IF(OR(AND(3,4,5),AND(7,8,9)),x,y)
是不是很简单,看着确实,但有一个设计必须要搞通,也就是下面我要说的数据上下文。
数据上下文
🍄说明 | LiteFlow
数据上下文这个概念在LiteFlow框架中非常重要,你所有的业务数据都是放在数据上下文中。
要做到可编排,一定是消除每个组件差异性的。如果每个组件出参入参都不一致,那就没法编排了。
LiteFlow对此有独特的设计理念,平时我们写瀑布流的程序时,A调用B,那A一定要把B所需要的参数传递给B,而在LiteFlow框架体系中,每个组件的定义中是不需要接受参数的,也无任何返回的。
每个组件只需要从数据上下文中获取自己关心的数据即可,而不用关心此数据是由谁提供的,同样的,每个组件也只要把自己执行所产生的结果数据放到数据上下文中即可,也不用关心此数据到底是提供给谁用的。这样一来,就从数据层面一定程度的解耦了。从而达到可编排的目的。关于这个理念,也在LiteFlow简介中的设计原则有提到过,给了一个形象的例子,大家可以再去看看。
一旦在数据上下文中放入数据,整个链路中的任一节点都是可以取到的。
我简单说明一下。
如下,表示瀑布流程,从开始到结束,每步调用都需要将数据传递给下一步调用者,完成整个流程。

而对于LiteFlow,更像是下面这样,整个流程存在这样的数据上下文,每个组件只需要去数据上下文中取自己关心的数据,结果也是一样,放进数据上下文即可。

此模式下,要非常注重数据上下文的管理,数据隔离和共享要非常注意。
相同组件数据问题
对于规则条件组件的问题在于:每个规则里的条件非常多,组件该怎么获取当前组件参数(如:appName==Phone)。如IF(OR(AND(3,4,5),AND(7,8,9)),x,y)此表达式转换为我们使用的规则表达式应该是这样的IF(OR(AND(ruleConditionIF,ruleConditionIF,ruleConditionIF),AND(ruleConditionIF,ruleConditionIF,ruleConditionIF)),x,y),ruleConditionIF为规则条件组件。一个表达式中有多个相同的组件意味着他们需要不同的处理,那么数据怎么获取?
LiteFlow提供了三种不同方式:
1、🍉组件参数 | LiteFlow,定义EL表达式时声明数据并传入组件
2、🍍组件标签 | LiteFlow,定义组件tag区别组件
3、🍕私有投递 | LiteFlow,用于私有独有数据传递
下面使用方式二(组件标签)来实现普通条件组件。
表结构与数据
chain表
create table de_chain
(id               bigint auto_increment comment '主键'primary key,application_name varchar(32)                 default ''                not null comment '应用名',chain_name       varchar(64)                 default ''                not null comment 'chain名',el_data          text                                                  not null comment 'el数据',enable           bit                         default b'0'              not null comment 'chain状态',description      varchar(64) charset utf8mb4 default ''                null comment '描述',creator          varchar(64) charset utf8mb4 default ''                null comment '创建者',create_time      datetime                    default CURRENT_TIMESTAMP not null comment '创建时间',updater          varchar(64) charset utf8mb4 default ''                null comment '更新者',update_time      datetime                    default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间',deleted          bit                         default b'0'              not null comment '是否删除',constraint uk_codeunique (chain_name)
)comment 'chain表';INSERT INTO coolGuard.de_chain (id, application_name, chain_name, el_data, enable, description, creator, create_time, updater, update_time, deleted) VALUES (1, 'coolGuard', 'mainChain', 'THEN(chain1);', true, '', '', '2024-04-04 22:35:36', '', '2024-04-04 22:40:30', false);
INSERT INTO coolGuard.de_chain (id, application_name, chain_name, el_data, enable, description, creator, create_time, updater, update_time, deleted) VALUES (2, 'coolGuard', 'chain1', 'IF(OR(AND(ruleConditionIf.tag("1"),ruleConditionIf.tag("2")),ruleConditionIf.tag("3")),orderMode,worstMode);', true, '', '', '2024-04-04 22:31:16', '', '2024-04-05 13:25:49', false);
规则条件表
create table de_rule_condition
(id           bigint auto_increment comment '主键'primary key,chain_name   varchar(64)                 default ''                not null comment 'chain名',field_name   varchar(32)                 default ''                not null comment '字段名',operate_type int                         default 0                 not null comment '操作类型',expect_value varchar(32)                 default ''                not null comment '期望值',description  varchar(64) charset utf8mb4 default ''                null comment '描述',creator      varchar(64) charset utf8mb4 default ''                null comment '创建者',create_time  datetime                    default CURRENT_TIMESTAMP not null comment '创建时间',updater      varchar(64) charset utf8mb4 default ''                null comment '更新者',update_time  datetime                    default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间',deleted      bit                         default b'0'              not null comment '是否删除'
)comment '规则条件表';INSERT INTO coolGuard.de_rule_condition (id, chain_name, field_name, operate_type, expect_value, description, creator, create_time, updater, update_time, deleted) VALUES (1, 'chain3', 'appName', 2, 'Phone', '', '', '2024-04-04 22:32:25', '', '2024-04-05 12:24:03', false);
INSERT INTO coolGuard.de_rule_condition (id, chain_name, field_name, operate_type, expect_value, description, creator, create_time, updater, update_time, deleted) VALUES (2, 'chain4', 'customerId', 2, '123456', '', '', '2024-04-05 12:24:03', '', '2024-04-05 12:24:03', false);
INSERT INTO coolGuard.de_rule_condition (id, chain_name, field_name, operate_type, expect_value, description, creator, create_time, updater, update_time, deleted) VALUES (3, 'chain5', 'money', 5, '15', '', '', '2024-04-05 12:24:03', '', '2024-04-05 12:24:03', false);
依赖
<dependency><groupId>com.yomahub</groupId><artifactId>liteflow-spring-boot-starter</artifactId><version>${liteflow.version}</version>
</dependency>
<dependency><groupId>com.yomahub</groupId><artifactId>liteflow-rule-sql</artifactId><version>${liteflow.version}</version>
</dependency>
<dependency><groupId>com.yomahub</groupId><artifactId>liteflow-script-groovy</artifactId><version>${liteflow.version}</version>
</dependency>
配置
liteflow:rule-source-ext-data-map:url: jdbc:mysql://localhost:3306/coolGuard?allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=truedriverClassName: com.mysql.cj.jdbc.Driverusername: wnhyangpassword: 123456applicationName: ${spring.application.name}#是否开启SQL日志sqlLogEnabled: true#是否开启SQL数据轮询自动刷新机制 默认不开启pollingEnabled: truepollingIntervalSeconds: 60pollingStartSeconds: 60#以下是chain表的配置,这个一定得有chainTableName: de_chainchainApplicationNameField: application_namechainNameField: chain_nameelDataField: el_datachainEnableField: enable#以下是script表的配置,如果你没使用到脚本,下面可以不配置#    scriptTableName: script
#    scriptApplicationNameField: application_name
#    scriptIdField: script_id
#    scriptNameField: script_name
#    scriptDataField: script_data
#    scriptTypeField: script_type
#    scriptLanguageField: script_language
#    scriptEnableField: enable
自定义数据上下文
可以改善,先这样贴出来。
FieldContext表示经过入参处理后的所有字段集合,后面的规则/指标都会用到的。
/*** @author wnhyang* @date 2024/4/3**/
public class FieldContext {private final Map<String, String> stringFields = new ConcurrentHashMap<>();private final Map<String, Integer> numberFields = new ConcurrentHashMap<>();private final Map<String, Boolean> booleanFields = new ConcurrentHashMap<>();private final Map<String, String> enumFields = new ConcurrentHashMap<>();private final Map<String, LocalDateTime> dateFields = new ConcurrentHashMap<>();private final Map<String, BigDecimal> floatFields = new ConcurrentHashMap<>();public void setStringData(String key, String value) {stringFields.put(key, value);}public String getStringData(String key) {return stringFields.get(key);}public boolean hasStringData(String key) {return stringFields.containsKey(key);}}
普通规则条件组件
当前还不是很完善,TODO已有说明。
对了,我使用的jdk17,所有switch表达式是下面这样,与jdk8有点区别。
/*** @author wnhyang* @date 2024/4/4**/
@Slf4j
@LiteflowComponent
@RequiredArgsConstructor
public class RuleConditionIf extends NodeIfComponent {private final RuleConditionMapper ruleConditionMapper;@Overridepublic boolean processIf() throws Exception {// 获取当前chainNameString tag = this.getTag();log.info("当前tag:{}", tag);// 获取当前chainName对应的条件RuleCondition ruleCondition = ruleConditionMapper.selectById(tag);log.info("当前chainName对应的条件:{}", ruleCondition);// 获取上下文FieldContext fieldContext = this.getContextBean(FieldContext.class);// 获取条件字段String fieldName = ruleCondition.getFieldName();log.info("条件字段:{}", fieldName);// 获取字段值// TODO 支持String、Integer、BigDecimal、Boolean等String stringData = fieldContext.getStringData(fieldName);log.info("字段值:{}", stringData);OperateType byType = OperateType.getByType(ruleCondition.getOperateType());log.info("操作类型:{}", byType);// TODO 当前是常量,之后要考虑变量String expectValue = ruleCondition.getExpectValue();log.info("期望值值:{}", expectValue);return switch (Objects.requireNonNull(byType)) {case NULL:yield StrUtil.isBlank(stringData);case NOT_NULL:yield !StrUtil.isBlank(stringData);case EQ:yield stringData.equals(expectValue);case NOT_EQ:yield !stringData.equals(expectValue);case CONTAINS:yield stringData.contains(expectValue);case NOT_CONTAINS:yield !stringData.contains(expectValue);case GT:yield Integer.parseInt(stringData) > Integer.parseInt(expectValue);case GTE:yield Integer.parseInt(stringData) >= Integer.parseInt(expectValue);case LT, LTE:yield false;case IN:String[] split1 = expectValue.split(",");for (String s : split1) {if (stringData.equals(s)) {yield true;}}case NOT_IN:String[] split2 = expectValue.split(",");for (String s : split2) {if (stringData.equals(s)) {yield false;}}case PREFIX:yield stringData.startsWith(expectValue);case NOT_PREFIX:yield !stringData.startsWith(expectValue);case SUFFIX:yield stringData.endsWith(expectValue);case NOT_SUFFIX:yield !stringData.endsWith(expectValue);};}
}
操作类型枚举
/*** @author wnhyang* @date 2024/4/3**/
@AllArgsConstructor
@Getter
public enum OperateType {NULL(0),NOT_NULL(1),EQ(2),NOT_EQ(3),GT(4),GTE(5),LT(6),LTE(7),IN(8),NOT_IN(9),CONTAINS(10),NOT_CONTAINS(11),PREFIX(12),NOT_PREFIX(13),SUFFIX(14),NOT_SUFFIX(15);private final Integer type;public static OperateType getByType(Integer type) {for (OperateType operateType : OperateType.values()) {if (operateType.getType().equals(type)) {return operateType;}}return null;}
}
测试
@Slf4j
@RestController
@RequestMapping("/field")
@RequiredArgsConstructor
public class FieldController {private final FieldService fieldService;private final FlowExecutor flowExecutor;@GetMapping("/test")public CommonResult<String> test(@RequestParam("appName") String appName, @RequestParam("customerId") String customerId, @RequestParam("money") String money) {FieldContext fieldContext = new FieldContext();fieldContext.setStringData("appName", appName);fieldContext.setStringData("customerId", customerId);fieldContext.setStringData("money", money);LiteflowResponse main1 = flowExecutor.execute2Resp("mainChain", null, fieldContext);log.info(String.valueOf(main1));return success("test");}
}

结果
mainChain的EL表达式为THEN(chain1);,chain1为子流程
IF(OR(AND(ruleConditionIf.tag("1"),ruleConditionIf.tag("2")),ruleConditionIf.tag("3")),orderMode,worstMode);,ruleConditionIf为上面的规则条件组件。
最终应该是这样的:THEN(IF(OR(AND(ruleConditionIf.tag("1"),ruleConditionIf.tag("2")),ruleConditionIf.tag("3")),orderMode,worstMode));

参数为:appName:Phone,customerId:235246,money:35时
此时执行流程为:ruleConditionIf<17>==>ruleConditionIf<2>==>ruleConditionIf<2>==>orderMode<0>
 参数为:
参数为:appName:Phone,customerId:235246,money:3时
此时执行流程为:ruleConditionIf<42>==>ruleConditionIf<2>==>ruleConditionIf<1>==>worstMode<0>

总结
LiteFlow可玩性还是很强的,未来我还会继续完善打造自己设计并实现的风控系统。冲冲冲!!!
写在最后
拙作艰辛,字句心血,望诸君垂青,多予支持,不胜感激。
个人博客:无奈何杨(wnhyang)
个人语雀:wnhyang
共享语雀:在线知识共享
Github:wnhyang - Overview

相关文章:
 
风控系统之普通规则条件,使用LiteFlow实现
个人博客:无奈何杨(wnhyang) 个人语雀:wnhyang 共享语雀:在线知识共享 Github:wnhyang - Overview 提要 参考:智能风控筑基手册:全面了解风控决策引擎 前面有可配置输入参数的接…...
 
在一套Dockerfile中完成编译和运行环境部署
大纲 解释型语言编译环境解释环境编译型语言编译环境运行环境 方法编译环境安装系统安装编译依赖下载代码特殊处理(可以忽略)编译准备(可以忽略)编译打包依赖(编译结果) 运行环境安装操作系统安装运行时依赖…...
ubuntu系统里克隆github代码到本地,提示fatal: unable to connect to github.com的解决方案
打开命令行终端生成一个新的SSH密钥对。如果你还没有SSH密钥或者想创建一个新的,可以使用以下命令: ssh-keygen -t rsa -b 4096 -C "your_emailexample.com"当系统提示你“Enter a file in which to save the key”,时,…...
常见docker使用命令
#搭建镜像 “”" sudo docker build -t es_refresh:V1.20230303 . “”" #启动容器 “”" docker run -d --namepara_classify -v /etc/localtime:/etc/localtime -v /data/chenhw/multi_label_classification:/edb2vec -p 8066:8066 --gpus ‘“device0”’…...
 
Ubuntu系统中设置中文输入法的教程
1、Ubuntu介绍: (https://cn.ubuntu.com/) (Ubuntu | 全球领先的用于个人电脑、平板及手机的操作系统) Ubuntu是一款基于Debian的开源Linux操作系统,由英国Canonical公司赞助支持的全球性社区共同开发。U…...
 
练习14 Web [极客大挑战 2019]Upload
phtml格式绕过,burp修改content-type绕过,常见的文件上传存放目录名 题目就叫upload,打开靶机 直接上传一个图片格式的一句话木马,返回如下: 提交练习5和9中的两种可以执行图片格式php代码的文件,修改con…...
 
3.6k star, 免费开源跨平台的数据库管理工具 dbgate
3.6k star, 免费开源跨平台的数据库管理工具 dbgate 分类 开源分享 项目名: dbgate -- 免费开源跨平台的数据库管理工具 Github 开源地址: GitHub - dbgate/dbgate: Database manager for MySQL, PostgreSQL, SQL Server, MongoDB, SQLite and others. Runs under…...
2024.3.2力扣每日一题——受限条件下可到达节点的数目
2024.3.2 题目来源我的题解方法一 深度优先搜索方法二 并查集 题目来源 力扣每日一题;题序:2368 我的题解 方法一 深度优先搜索 使用深度优先搜索实现,在搜索过程中根据restricted进行截停。 时间复杂度:O(n) 空间复杂度&#…...
 
在云端遇见雨云:一位服务器寻觅者的指南
引言:寻觅一座云端归宿 当我踏入数字世界的边缘,带着对网络的探索与期待,我迫切需要一座安全可靠的数字栖息地。云计算技术正如一场魔法般的变革,而在这片广袤的云端中,雨云就像是一位友善的向导,引领我穿越…...
 
Pygame基础10-物理模拟
PyMunk PyMunk是一个模拟物理的库。 注意,PyMunk只是进行物理模拟,不包含可视化的功能。如果需要可视化,可使用pygame等库。 可用pip安装pymunk pip install pymunk pymunk中的概念: space: 物理空间。 包含gravity 模…...
 
蓝桥杯 --- 日期问题模板
目录 1.如何判断闰年 2.如何遍历当前年份的每一天 3.如果想要输出某一年某一天到某一年某一天之间一共有多少天。 4.精确到具体周几到周几的问题分析 5.如何直接通过一层for循环枚举年月日 习题: 蓝桥杯竞赛特别喜欢考日期问题,今天给大家分享一下…...
 
Java 处理Mysql获取树形的数据
Mysql数据: 代码如下: Entity: Data Accessors(chain true) public class Region {private BigInteger id;//名称private String name;//父idprivate BigInteger parentId;private List<Region> children;private Integer createTim…...
 
前端三剑客 —— CSS ( 坐标问题 、定位问题和图片居中 )
前期内容回顾: 1.常见样式 text-shadow x轴 y轴 阴影的模糊程度 阴影的颜色 box-shadow border-radio 实现圆角 margin 内边距 padding 外边距 background 2.特殊样式 媒体查询:media 自定义字体:font-face { font-family:自定义名称&#…...
 
向量数据库 | AI时代的航道灯塔
向量数据库 | AI时代的航道灯塔 什么是向量检索服务拍照搜商品 你使用过向量数据库吗?使用体验?为什么向量数据库能借由大模型引起众多关注向量数据库在当前AI热潮中是昙花一现,还是未来AI时代的航道灯塔? 今天的话题主要是讨论向…...
Linux中的conntrack命令深入解析
在Linux网络管理和监控领域,conntrack命令是一个强大的工具,它提供了对netfilter连接跟踪系统的直接访问🔍。这篇文章将深入探讨conntrack的由来、底层原理、参数意义,以及其常见用法,并对返回结果的每个字段进行详细解…...
 
反截屏控制技术如何防止信息通过手机拍照泄漏?
反截屏控制技术为企业数据安全提供了重要的防护措施。通过以下几点,有效阻止了信息通过拍照等方式的泄漏: 反截屏控制开启,用户启动截屏操作时,允许非涉密内容截屏操作,但所有涉密内容窗口会自动隐藏,防止涉…...
0.k8s简介
目录 k8s是什么 k8s不是什么 云原生 微服务 整体式架构与微服务架构 微服务的特性 微服务的优势 k8s是什么 Kubernetes 是一个可移植、可扩展的开源平台,用于管理容器化的工作负载和服务,可促进声明式配置和自动化。 Kubernetes 拥有一个庞大且快…...
 
VScode 集成终端设置默认打开当前文件夹 mac系统
一.快捷键设置 搜索 openInIntegratedTerminal 如图: 二.设置cmd 默认打开位置 点击设置 搜索 ntegrated:cwd 如下图: 三.查看ip 快捷指令: ipconfig getifaddr en0...
 
HDLbits 刷题 -- Alwaysblock2
学习: For hardware synthesis, there are two types of always blocks that are relevant: Combinational: always (*)Clocked: always (posedge clk) Clocked always blocks create a blob of combinational logic just like combinational always blocks, but…...
 
一、Docker部署GitLab(详细步骤)
Docker部署GitLab(详细步骤) 一、拉取镜像二、启动容器三、修改配置四、修改密码五、浏览器访问 一、拉取镜像 docker安装教程:https://qingsi.blog.csdn.net/article/details/131270071 docker pull gitlab/gitlab-ce:latest二、启动容器 …...
 
label-studio的使用教程(导入本地路径)
文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...
 
【Oracle APEX开发小技巧12】
有如下需求: 有一个问题反馈页面,要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据,方便管理员及时处理反馈。 我的方法:直接将逻辑写在SQL中,这样可以直接在页面展示 完整代码: SELECTSF.FE…...
 
UE5 学习系列(三)创建和移动物体
这篇博客是该系列的第三篇,是在之前两篇博客的基础上展开,主要介绍如何在操作界面中创建和拖动物体,这篇博客跟随的视频链接如下: B 站视频:s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...
oracle与MySQL数据库之间数据同步的技术要点
Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异,它们的数据同步要求既要保持数据的准确性和一致性,又要处理好性能问题。以下是一些主要的技术要点: 数据结构差异 数据类型差异ÿ…...
 
Cinnamon修改面板小工具图标
Cinnamon开始菜单-CSDN博客 设置模块都是做好的,比GNOME简单得多! 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...
根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:
根据万维钢精英日课6的内容,使用AI(2025)可以参考以下方法: 四个洞见 模型已经比人聪明:以ChatGPT o3为代表的AI非常强大,能运用高级理论解释道理、引用最新学术论文,生成对顶尖科学家都有用的…...
JAVA后端开发——多租户
数据隔离是多租户系统中的核心概念,确保一个租户(在这个系统中可能是一个公司或一个独立的客户)的数据对其他租户是不可见的。在 RuoYi 框架(您当前项目所使用的基础框架)中,这通常是通过在数据表中增加一个…...
【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论
路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中(图1): mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...
git: early EOF
macOS报错: Initialized empty Git repository in /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/.git/ remote: Enumerating objects: 2691797, done. remote: Counting objects: 100% (1760/1760), done. remote: Compressing objects: 100% (636/636…...
比特币:固若金汤的数字堡垒与它的四道防线
第一道防线:机密信函——无法破解的哈希加密 将每一笔比特币交易比作一封在堡垒内部传递的机密信函。 解释“哈希”(Hashing)就是一种军事级的加密术(SHA-256),能将信函内容(交易细节…...
