用 DolphinDB 和 Python Celery 搭建一个高性能因子计算平台

因子挖掘是量化金融研究和交易的核心工作。传统的开发流程中,通常使用 Python 从关系型数据库(如 SqlServer, Oracle 等)读取数据,在 Python 中进行因子计算。随着证券交易规模不断扩大以及交易数据量的激增,用户对因子计算平台的性能提出了更高的要求。传统的因子计算工程面临以下问题:

  • 因子数据量的增长以及 Python 作为计算平台导致的性能瓶颈问题

  • 传统的计算平台框架如何无缝替换问题

本教程聚焦于因子批量化计算这一实际业务场景,将 DolphinDB 作为一个核心的计算工具引入到传统的因子平台。以DolphinDB 为核心的因子计算平台包括:数据同步模块、因子批计算模块和因子调度模块。其中 dataX 作为数据同步工具,负责将原始数据以及增量数据从关系数据库同步存储到 DolphinDB 中;DolphinDB 作为因子计算与存储模块;Celery 作为任务调度框架模块。

DolphinDB 因子计算平台,可以为业务部门提供即时的因子计算服务、大数据批计算服务以及历史因子查询服务等。引入DolphinDB后,既能满足高中低频因子计算的要求,又有丰富的API以及ETL工具实现无缝集成。下文以 WorldQuant 101 Alpha 因子指标库中的1号因子 WQAlpha1 为例来展现出整个因子计算平台的构建流程。

1. 总体架构

基于 DolphinDB 与 Python Celery 框架的因子平台构建,主要包括基于 dataX 的 SQL Server Reader (历史数据同步模块)和 DolphinDB (数据存储与计算模块)的数据源注入,DolphinDB 因子函数的定义和调用,Celery 框架(因子平台调度模块)调用因子函数传递参数和最终以 Dataframe 格式的数据可视化展示等。其整体构图如下所示:

1.1 SQL Server 概述

  • 介绍:

SQL Server 是由 Microsoft 开发和推广的关系数据库管理系统。

SQL Server 为整个架构中原始数据来源部分。

  • 教程与下载、安装:

有关 SQL Server 的使用、下载、安装可以参考 SQL Server官方文档。

1.2 dataX 概述

  • 介绍:

dataX 是一个异构数据源离线同步工具,用于实现包括 MySQL, Oracle, SQL Server, Postgre 等各种异构数据源之间高效的数据同步功能。

本教程中的 dolphindbWriter 的 dataX 插件能够帮助用户将 SQL Server 数据导入到 DolphinDB 中。

  • 教程与下载、安装:

有关 dataX 的使用、安装可以参考 dataX 指南,下载请点击 dataX。

1.3 DolphinDB 概述

  • 介绍:

DolphinDB 是一款高性能的时序数据处理框架,用于计算高频因子以及因子存储等。

本教程将 DolphinDB 作为因子计算的主要工具,并结合自身所特有的函数视图功能实现预定义的因子函数在 Python 中调用 DolphinDB 的 Python API 。

  • 教程与下载、安装:

有关 DolphinDB 的安装指南可以参考 DolphinDB安装使用指南,点击下载链接下载。其中 Python api 的调用可以参考 Python API for DolphinDB。

1.4 Celery 概述

  • 介绍:

Celery 是一个基于 Python 开发的简单、灵活、可靠的分布式异步消息队列,用于实现异步任务(Async Task)处理,在实际使用过程中需要借助消息中间件(Broker)监控任务执行单元(Worker)的执行情况,并将任务执行结果最终存储到结果存储(Backend)中。

Celery 具有如下优势:

  • 能够实现异步发起并处理请求的功能,更方便实现了 Python 多线程;

  • 方便集成到诸如 rabbitMQ,DolphinDB 等组件,具有较强的扩展性。

本教程中将 Celery 作为任务调度的框架,并结合 redis 作为消息中间件和结果存储实现对因子计算的任务调用。

  • 教程与下载、安装:

有关 Celery 的使用、下载、安装可以参考 Celery 中文官方文档。

注:为了防止在使用 Celery 框架过程中出现诸如 TypeError: __init__() got an unexpected keyword argument 'username' 的报错,建议在安装 Celery 框架后卸载默认的 kombou 库并指定安装 5.1.0 版本的库。

2. 环境部署

注:
1.本教程所介绍的是测试环境的部署,因此所部署的 DolphinDB 服务为单节点版,具体部署教程可以参考 DolphinDB 单节点部署教程;
2.本教程所使用的 Celery 版本为4.3.0.

硬件环境:

硬件名称

配置信息

主机名

cnserver9

外网 IP

xxx.xxx.xxx.122

操作系统

Linux(内核版本3.10以上)

内存

64 GB

CPU

x86_64(12核心)

软件环境:

软件名称

版本信息

DolphinDB

V2.00.7

SQL Server

2019最新版

dataX

3.0

JDK(安装dataX必备)

1.8.0_xxx

Maven(安装dataX必备)

3.6.1+

Python(安装dataX必备)

2.x

Python(包含需要预先安装 numpy、pandas、Celery 等库以及 DolphinDB 的 Python api )

3.7.9

redis

6.2.7

3. 开发使用范例

3.1 数据介绍

本教程选取了 2020.01.01 - 2021.01.01 间多只股票的每日收盘价格,总数据条数为 544174 条。以下是收盘价格表在 SQL Server 和 DolphinDB 中的数据结构:

字段名

字段含义

数据类型(SQL Server)

数据类型(DolphinDB)

SecurityID

股票代码

varchar

SYMBOL

TradeDate

交易日期

date

DATE

Value

收盘价格

float

DOUBLE

3.2 业务场景与指标介绍

本教程选取了 WorldQuant 101 Alpha 因子指标库中的1号因子 WQAlpha1 为案例进行计算,有关该指标库的详细内容和该因子的引用方法可以参考 WorldQuant 101 Alpha 因子指标库。

3.3 dataX 同步 SQL Server 数据到 DolphinDB

本节介绍如何将 SQL Server 的数据同步到 DolphinDB 中。

注:
1.本教程中默认已经预先构建好了存有数据的 SQL Server 数据库,在以下的流程介绍中不再描述其构建过程;
2.本教程中部署的单节点版的 DolphinDB 服务的对应端口为 8848
  • DolphinDB 数据库表构建:

在数据导入到 DolphinDB 之前,需要预先在部署的 DolphinDB 服务中构建数据库表,执行如下 DolphinDB 脚本建立数据库 dfs://tick_close 和其中的数据表 tick_close

dbName = "dfs://tick_close"
tbName = "tick_close"
if(existsDatabase(dbName)){
	dropDatabase(dbName)
}
db = database(dbName, RANGE, date(datetimeAdd(2000.01M,0..50*12,'M')))
name = `SecurityID`TradeDate`Value
type = `SYMBOL`DATE`DOUBLE
schemaTable = table(1:0, name, type)
db.createPartitionedTable(table=schemaTable, tableName=tbName, partitionColumns=`TradeDate)
  • 撰写导入配置文件:

在启动 dataX 执行数据导入命令时,需要先撰写以 json 为格式的配置文件,用来指定数据同步过程中的数据源相关配置。

在一般情况下,对每一张数据表的同步往往需要对应撰写一个配置文件。本教程中针对 tick_close 数据表分别撰写了如下的 tick_close.json 文件:

{
    "job": {
        "content": [
            {
                "writer": {
                    "parameter": {
                        "dbPath": "dfs://tick_close",
                        "tableName": "tick_close",
                        "batchSize": 100,
                        "userId": "admin",
                        "pwd": "123456",
                        "host": "127.0.0.1",
                        "table": [
                            {
                                "type": "DT_SYMBOL",
                                "name": "SecurityID"
                            },
                            {   "type": "DT_DATE",
                                "name": "TradeDate"
                            },
                            {
                                "type": "DT_DOUBLE",
                                "name": "Value"
                            }
],
                        "port": 8848
                    },
                    "name": "dolphindbwriter"
                },
                "reader": {
                    "name": "sqlserverreader",
                    "parameter": {
                        "username": "SA",
                        "password": "Sa123456",
                        "column": [
                            "*"
                        ],
                        "connection": [
                            {
                                "table": [
                                    "tick_close"
                                ],
                                "jdbcUrl": [
                                "jdbc:sqlserver://127.0.0.1:1234;DatabaseName=tick_close"
                                ]
                                
                            }
                        ]
                    }
                }
            }
        ],
        "setting": {
            "speed": {
                "channel": 1
            }
        }
    }
}

注:本教程涉及到的数据同步仅为历史数据的全量同步,在实际过程中如果有增量同步等的需要,在 writer 配置中要增加 saveFunctionNamesaveFunctionDef 两个配置,具体用法可以参考 基于 DataX 的 DolphinDB 数据导入工具。

  • 执行数据导入命令:

进入 dataX 的 bin 目录下,分别执行如下命令向 DolphinDB 的 tick_close 数据表中导入数据:

$ python datax.py ../conf/tick_close.json

参数解释:

  • datax.py:用于启动dataX的脚本,必选

  • ../conf/tick_close.json:存放配置文件的路径,必选

预期输出:

3.4 Celery 框架触发 DolphinDB 预定义函数计算

本节介绍如何使用 DolphinDB 脚本实现计算区间收益率的因子函数并使用 Celery 框架调用和触发框架。

  • 消息中间件和结果存储模块 redis 服务的构建:

Celery 框架需要一个消息中间件来发送消息实现任务的调度,同时需要一个结果存储的工具用来存储结果。本教程中我们推荐使用 redis 作为消息中间件和结果存储工具,其部署的端口为 6379 。在实际使用过程中用户可以根据实际情况选择所使用的的工具和部署方法。本教程中关于 redis 的部署流程省略。

  • DolphinDB 因子函数实现流程:

登录机器或使用 DolphinDB GUI 或 VScode 插件连接 DolphinDB 服务使用 DolphinDB 脚本预定义函数。本教程封装了 WorldQuant 101 Alpha 因子指标库中的1号因子 WQAlpha1,并以之为案例,其代码实现如下:

/**
 * 因子:WorldQuant 101 Alpha 因子指标库中的1号因子 WQAlpha1
参数:
       security_id:STRING VECTOR,股票代码序列
       begin_date:DATE,区间开始日期
       end_date:DATE,区间结束日期
 */
use wq101alpha
defg get_alpha1(security_id, begin_date, end_date){
	if (typestr(security_id) == 'STRING VECTOR' && typestr(begin_date) == `DATE && typestr(end_date) == `DATE){
	tick_list = select * from loadTable("dfs://tick_close", "tick_close") where TradeDate >= begin_date and TradeDate <= end_date and SecurityID in security_id
	alpha1_list=WQAlpha1(panel(tick_list.TradeDate, tick_list.SecurityID, tick_list.Value))
	return table(alpha1_list.rowNames() as TradeDate, alpha1_list)
	}
	else {
		print("What you have entered is a wrong type")
		return `NULLValue
	}
}

参数解释:

  • 请求参数:

字段

说明

类型(dolphindb)

备注

是否必填

security_id

股票代码序列

STRING VECTOR

该时间序列中的各元素以日划分

begin_date

区间开始日期

DATE

end_date

区间结束日期

DATE

  • 返回参数:

字段

说明

类型(dolphindb)

备注

returntable

在一定时间区间内某支基金的最大回撤率

IN-MEMORY TABLE

在异常情况下会返回一个类型为STRING的值wrongNum

由于在 Python 代码中使用 Python api 调用 DolphinDB 预定义的函数和在 server 服务内预定义函数的操作属于不同的 session,为了使得 Python api 可以成功调用到 DolphinDB 脚本定义的函数,本教程中我们引入了 functionView(即函数视图)功能,需要先将函数添加到函数视图中,将函数视图的执行权限给某研究员(admin 用户是不需要赋予权限),具体代码实现如下:

//将该函数加入到函数视图中
addFunctionView(get_alpha1)
//将该函数的调用权限赋予给xxx用户
grant("xxx", VIEW_EXEC, "get_alpha1")
  • Celery 调用因子函数项目构建流程:

本节介绍如何构建一个基于 Celery 框架的项目,本教程所使用的 Celery 安装方式是 pip 命令,登录机器执行如下命令。用户也可以使用其它安装方法:

$ pip install celery==4.3.0 && pip install redis==3.2.0

注:如果出现诸如 TypeError: __init__() got an unexpected keyword argument 'username' 类似的错误,说明安装 Celery 框架同时安装的组件 kombu 库的版本出了问题,建议卸载掉原有版本的库,执行 pip3 install kombu==5.1.0 安装 5.1.0 版本的库。

安装好所需库后,在特定目录下执行如下命令构建项目目录架构和所需文件:

$ mkdir celery_project && touch celery_project/tasks.py celery_project/app.py

执行 tree ./celery_project 命令查看项目目录结构如下:

./celery_project ├── app.py └── tasks.py  0 directories, 2 files

其中,对两个文件中的内容编写分别如下:

tasks.py:该文件用来与 DolphinDB 建立 session 封装调用因子函数,并声明封装的函数为一个可以被 Celery 框架异步调度的任务。

首先,导入所需的 Python 库:

from celery import Celery
import dolphindb as ddb
import numpy as np
import pandas as pd
from datetime import datetime

其次,调用 DolphinDB 的 Python api 与之前 DolphinDB 服务建立 session

s = ddb.session()
s.connect("127.0.0.1", 8848, "admin", "123456")

同时,实例化一个 Celery 对象,并设置相关配置:

app = Celery(
    'celeryApp',
    broker='redis://localhost:6379/1',
    backend='redis://localhost:6379/2'
)
app.conf.update(
    task_serializer='pickle',
    accept_content=['pickle'], 
    result_serializer='pickle',
    timezone='Asia/Shanghai',
    enable_utc=True,
)

注:由于在本次计算过程中涉及到 datetimeDataFrame 格式数据的传递和返回,而 Celery 默认的序列化方式 json 无法支持这类数据的序列化,因此要设置 task_serializeraccept_contentresult_serializer 三个参数设置指定序列化方式为 pickle

最后,将调用 DolphinDB 的预定义函数封装成一个函数以供调用,并添加 @app.task() 装饰器以说明执行的任务是可供 Celery 调用的异步任务:

@app.task()
def get_alpha1(security_id, begin_date, end_time):
    return s.run("get_alpha1", security_id, begin_date, end_time)

注:这里我们使用了 Python 中的数据类型的参数进行传递,其中的 Python 和 DolphinDB 的数据类型的对应关系和使用 DolphinDB 中的数据类型的传参可以参考 Python API for DolphinDB 的1.3节。

  • app.py:该文件用来与 DolphinDB 建立 session 封装调用因子函数,并声明封装的函数为一个可以被 Celery 框架异步调度的任务。

如下是代码实现。这里我们使用了循环语句并调用 Celery 中的 delay() 函数向 Celery 框架发送两个任务调用请求,同时在每次循环中打印出任务 id

import numpy as np
from tasks import get_alpha1
security_id_list=[["600020", "600021"],["600022", "600023"]]
if __name__ == '__main__':
  for i in security_id_list:
    result = get_alpha1.delay(i, np.datetime64('2020-01-01'), np.datetime64('2020-01-31'))
    print(result)
  • Celery 调用因子函数任务实现流程:

在命令行执行如下语句运行 Celery 框架的 worker 端:

$ celery -A tasks worker --loglevel=info

预期输出:

 -------------- celery@cnserver9 v4.3.0 (rhubarb)
---- **** -----
--- * ***  * -- Linux-3.10.0-1160.53.1.el7.x86_64-x86_64-with-centos-7.9.2009-Core 2022-11-11 00:10:34
-- * - **** ---
- ** ---------- [config]
- ** ---------- .> app:         celeryApp:0x7f597a1d4e48
- ** ---------- .> transport:   redis://localhost:6379/1
- ** ---------- .> results:     redis://localhost:6379/2
- *** --- * --- .> concurrency: 64 (prefork)
-- ******* ---- .> task events: OFF (enable -E to monitor tasks in this worker)
--- ***** -----
 -------------- [queues]
                .> celery           exchange=celery(direct) key=celery


[tasks]
  . tasks.max_drawdown

[2022-11-11 00:10:37,413: INFO/MainProcess] Connected to redis://localhost:6379/1
[2022-11-11 00:10:37,437: INFO/MainProcess] mingle: searching for neighbors
[2022-11-11 00:10:38,465: INFO/MainProcess] mingle: all alone
[2022-11-11 00:10:38,488: INFO/MainProcess] celery@cnserver9 ready.

由于使用该命令运行 worker 后会一直保持在交互模式,因此我们需要和机器建立一个新的会话,在进入Celery 项目目录后执行如下命令向 Celery 框架发送异步任务调用请求:

$ python3 app.py

预期输出:

400a3024-65a1-4ba6-b8a9-66f6558be242
cd830360-e866-4850-aba0-3a07e8738f78

这时我们查看之前处在运行状态的 worker 端,可以查看到异步任务的执行情况和返回的结果信息:

 -------------- celery@cnserver9 v4.3.0 (rhubarb)
---- **** -----
--- * ***  * -- Linux-3.10.0-1160.53.1.el7.x86_64-x86_64-with-centos-7.9.2009-Core 2022-11-11 00:10:34
-- * - **** ---
- ** ---------- [config]
- ** ---------- .> app:         celeryApp:0x7f597a1d4e48
- ** ---------- .> transport:   redis://localhost:6379/1
- ** ---------- .> results:     redis://localhost:6379/2
- *** --- * --- .> concurrency: 64 (prefork)
-- ******* ---- .> task events: OFF (enable -E to monitor tasks in this worker)
--- ***** -----
 -------------- [queues]
                .> celery           exchange=celery(direct) key=celery


[tasks]
  . tasks.max_drawdown

[2022-11-11 00:10:37,413: INFO/MainProcess] Connected to redis://localhost:6379/1
[2022-11-11 00:10:37,437: INFO/MainProcess] mingle: searching for neighbors
[2022-11-11 00:10:38,465: INFO/MainProcess] mingle: all alone
[2022-11-11 00:10:38,488: INFO/MainProcess] celery@cnserver9 ready.
[2022-11-11 00:12:44,365: INFO/MainProcess] Received task: tasks.max_drawdown[400a3024-65a1-4ba6-b8a9-66f6558be242]
[2022-11-11 00:12:44,369: INFO/MainProcess] Received task: tasks.max_drawdown[cd830360-e866-4850-aba0-3a07e8738f78]
[2022-11-11 00:12:44,846: INFO/ForkPoolWorker-63] Task tasks.get_alpha1[400a3024-65a1-4ba6-b8a9-66f6558be242] succeeded in 0.04292269051074982s:    TradeDate  600020  600021
0  2020-01-01     NaN     NaN
1  2020-01-02     NaN     NaN
2  2020-01-03     NaN     NaN
3  2020-01-06     NaN     NaN
4  2020-01-07     0.5     0.0
5  2020-01-08     0.5     0.0
6  2020-01-09     0.0     0.5
7  2020-01-10     0.0     0.5
8  2020-01-13     0.0     0.5
9  2020-01-14     0.0     0.5
10 2020-01-15     0.5     0.0
11 2020-01-16     0.5     0.0
12 2020-01-17     0.5     0.0
13 2020-01-20     0.5     0.0
14 2020-01-21     0.0     0.5
15 2020-01-22     0.5     0.0
16 2020-01-23     0.5     0.0
17 2020-01-24     0.5     0.0
18 2020-01-27     0.5     0.0
19 2020-01-28     0.0     0.5
20 2020-01-29     0.0     0.5
21 2020-01-30     0.0     0.5
22 2020-01-31     0.0     0.5

[2022-11-11 00:12:45,054: INFO/ForkPoolWorker-1] Task tasks.get_alpha1[cd830360-e866-4850-aba0-3a07e8738f78] succeeded in 0.06510275602340698s:     TradeDate  600022  600023
0  2020-01-01     NaN     NaN
1  2020-01-02     NaN     NaN
2  2020-01-03     NaN     NaN
3  2020-01-06     NaN     NaN
4  2020-01-07     0.0     0.0
5  2020-01-08     0.0     0.0
6  2020-01-09     0.0     0.0
7  2020-01-10     0.0     0.0
8  2020-01-13     0.0     0.0
9  2020-01-14     0.0     0.0
10 2020-01-15     0.0     0.5
11 2020-01-16     0.0     0.0
12 2020-01-17     0.0     0.5
13 2020-01-20     0.5     0.0
14 2020-01-21     0.5     0.0
15 2020-01-22     0.5     0.0
16 2020-01-23     0.5     0.0
17 2020-01-24     0.0     0.5
18 2020-01-27     0.0     0.0
19 2020-01-28     0.5     0.0
20 2020-01-29     0.5     0.0
21 2020-01-30     0.5     0.0
22 2020-01-31     0.5     0.0

在任务执行结束后,我们也可以查看存储在 redis 中任务执行结果的相应信息。

注:在未启动 Celery 框架终端时我们也可以向 Celery 框架发送异步任务调用请求,但此时由于未启动 worker 端不能查看任务执行的状况和结果,只能返回一个任务 id

4. 总结

本教程着重讲述了如何将 DolphinDB 引入到传统因子计算平台中来解决传统因子平台的性能瓶颈问题。在经过实际测试后,我们将 Celery 框架的任务异步调用的优势和 DolphinDB 计算存储一体的强大性能优势结合起来,为实际生产过程提供了一个解决案例。

同时,由于篇幅有限,涉及到 SQL Server, dataX, DolphinDB 和 Celery 框架的一些其它操作未能更进一步展示,用户在使用过程中需要按照实际情况进行调整。也欢迎大家对本教程中可能存在的纰漏和缺陷批评指正。

附件

  • 原始数据文件: tick_close.zip

  • DolphinDB 脚本:ddb_function.txt

  • Celery项目:celery_project

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

QT VTK开发 (一、下载编译)

Vtk&#xff0c;&#xff08;visualization toolkit&#xff09;是一个开源的免费软件系统&#xff0c;主要用于三维计算机图形学、图像处理和可视化。Vtk是在面向对象原理的基础上设计和实现的&#xff0c;它的内核是用C构建的&#xff0c;包含有大约250,000行代码&#xff0c…

计算机组成原理实验一(完整)

在VC中使用调试功能将下列语句运行的内存存放结果截图&#xff0c;每运行一句需截图一次。 #include<stdio.h> int main() {int a 你的学号末两位-100; //0x&#xff1f;&#xff1f;&#xff1f;&#xff1f;&#xff1f;&#xff1f;&#xff1f;&#xff1f;&#x…

关于Anaconda的下载和安装方法及报错说明

初学者接触python时&#xff0c;常会因各种环境问题、各种包的安装问题而苦恼&#xff0c;Anaconda则可以解决这一切繁琐的问题&#xff0c;但很多人不知道如何下载安装配置&#xff0c;本文详细讲述下载和安装配置过程&#xff0c;也汇总常见安装过程中的错误&#xff08;零基…

【3】核心易中期刊推荐——人工智能计算机仿真

🚀🚀🚀NEW!!!核心易中期刊推荐栏目来啦 ~ 📚🍀 核心期刊在国内的应用范围非常广,核心期刊发表论文是国内很多作者晋升的硬性要求,并且在国内属于顶尖论文发表,具有很高的学术价值。在中文核心目录体系中,权威代表有CSSCI、CSCD和北大核心。其中,中文期刊的数…

【Kubernetes】第二十八篇 - 实现自动构建部署

一&#xff0c;前言 上一篇&#xff0c;介绍了 Deployment、Service 的创建&#xff0c;完成了前端项目的构建部署&#xff1b; 希望实现&#xff1a;推送代码 -> 自动构建部署-> k8s 滚动更新&#xff1b; 本篇&#xff0c;实现自动构建部署 二&#xff0c;推送触发构…

28个案例问题分析---15---登陆之后我加入的课程调用接口报错--ArrayList线程不安全。占用内存情况

ArrayList线程不安全。占用内存情况故事背景方案&思路解决线程不安全的问题方案一&#xff1a;在这两个方法之前添加 synchronized 关键字。方案二&#xff1a;使用ThreadLocal变量。解决重复创建对象问题。总结&升华故事背景 存入redis的值&#xff0c;可能会出现错误…

黑马《数据结构与算法2023版》正式发布

有人的地方就有江湖。 在“程序开发”的江湖之中&#xff0c;各种技术流派风起云涌&#xff0c;变幻莫测&#xff0c;每一位IT侠客&#xff0c;对“技术秘籍”的追求和探索也从未停止过。 要论开发技术哪家强&#xff0c;可谓众说纷纭。但长久以来&#xff0c;确有一技&#…

实用调试技巧【详细介绍】

实用调试技巧1. 什么是bug&#xff1f;2. 调试是什么&#xff1f;有多重要&#xff1f;2.1 调试是什么&#xff1f;2.2 调试的基本步骤2.3 Debug和Release的介绍3. Windows环境调试介绍3.1 调试环境的准备3.2 学会快捷键3.3 调试的时候查看程序当前信息3.3.1 查看临时变量的值3…

Java中的异常

程序错误一般分为三种&#xff1a;编译错误&#xff1a; 编写程序时没有遵循语法规则&#xff0c;编译程序能够自己发现错误并提示位置和原因。运行错误&#xff1a;程序在执行的时候运行环境发现了不能执行的操作。比如&#xff0c;JVM出错了&#xff0c;内存溢出等。逻辑错误…

Docker常用项目实战演练

docker镜像源的修改 linux环境下编辑 /etc/docker/daemon.json vi /etc/docker/daemon.json #如添加如下网易镜像源 { "registry-mirrors": ["http://hub-mirror.c.163.com"] }docker run命令详细解释 日常工作中用的比较多的是docker run命令&#xff…

2023年目标检测毕业设计(yolov5车辆识别、车辆检测、车牌识别、行人识别)

车辆识别视频yolov5车辆识别视频yolov5 yoloR对比行人车辆识别视频yolov8识别视频订阅专栏获得源码:http://t.csdn.cn/zsG47 ​​​​​​​先看一下yolo发展史 二、单目测距原理 图中有一个车辆&#xff0c;且车辆在地面上&#xff0c;其接地点Q必定在地面上。那么Q点的深度便…

少儿Python每日一题(23):楼梯问题

原题解答 本次的题目如下所示&#xff1a; 楼梯有n阶台阶&#xff0c;上楼可以一步上1阶&#xff0c;也可以一步上2阶&#xff0c;走完n阶台阶共有多少种不同的走法&#xff1f; 输入格式&#xff1a; 输入楼梯的阶梯数n 输出格式&#xff1a; 输出不同走法的个数 输入样例&am…

Unity学习日记12(导航走路相关、动作完成度返回参数)

目录 动作的曲线与函数 创建遮罩 导航走路 设置导航网格权重 动作的曲线与函数 执行动作&#xff0c;根据动作完成度返回参数。 函数&#xff0c;在代码内执行同名函数即可调用。在执行关键帧时调用。 创建遮罩 绿色为可效用位置 将其运用到Animator上的遮罩&#xff0c;可…

嵌入式学习笔记——STM32寄存器编程实现外部中断

外部中断前言EXTI的介绍EXTI是什么EXTI的主要特性数量对应中断源的命名EXTI的框图配置流程寄存器介绍编程思路编程效果前言 上一篇中&#xff0c;介绍了关于STM32的中断管理以及具体配置&#xff0c;本文就使用之前的配置流程来实现一下外部中断的功能。 EXTI的介绍 EXTI是什…

SDIO读写SD卡速度有多快?

前两天测试了SPI方式读写SD卡的速度《SPI方式读写SD卡速度测试》&#xff0c;今天来测试一下SDIO方式的读写速度。测试条件&#xff1a;单片机&#xff1a;STM32F407VET6编译环境&#xff1a;MDK 5.30HAL库SD卡&#xff1a;闪迪32GB/64GB TF卡文件系统&#xff1a;FatFS R0.12c…

SpringCloud详解01-SpringCloudAlibaba、Nacos

文章目录前言一、架构演进1、web1.0阶段2、web2.0阶段3、垂直架构4、分布式架构二、SpringCloud基本概念1.特点2.SpringCloud和SpringCloudAlibaba3.SpringCloudAlibaba体系核心组件三、SpringCloudAlibaba1、注册中心Nacos2、Nacos安装和启动总结前言 本篇记录一下SpringClou…

ChatGPT研究分享:机器第一次开始理解人类世界

0、为什么会对ChatGPT感兴趣一开始&#xff0c;我对ChatGPT是没什么关注的&#xff0c;无非就是有更大的数据集&#xff0c;完成了更大规模的计算&#xff0c;所以能够回答更多的问题。但后来了解到几个案例&#xff0c;开始觉得这个事情并不简单。我先分别列举出来&#xff0c…

每日学术速递3.17

CV - 计算机视觉 | ML - 机器学习 | RL - 强化学习 | NLP 自然语言处理 Subjects: cs.CV 1.Breaking Common Sense: WHOOPS! A Vision-and-Language Benchmark of Synthetic and Compositional Images 标题&#xff1a;打破常识&#xff1a;哎呀&#xff01;合成和合成图像…

【Redis】搭建哨兵集群

目录 集群结构 准备实例和配置 启动 测试 集群结构 这里我们搭建一个三节点形成的Sentinel集群&#xff0c;来监管之前的Redis主从集群。如图&#xff1a; 三个sentinel实例信息如下&#xff1a; 节点IPPORTs1192.168.150.10127001s2192.168.150.10127002s3192.168.150.…

python并发编程多线程

在传统操作系统中&#xff0c;每个进程有一个地址空间&#xff0c;而且默认就有一个控制线程 线程顾名思义&#xff0c;就是一条流水线工作的过程&#xff0c;一条流水线必须属于一个车间&#xff0c;一个车间的工作过程是一个进程 车间负责把资源整合到一起&#xff0c;是一个…