技术分享 | OMS 初识

news2024/11/24 20:57:44

作者:高鹏

DBA,负责项目日常问题排查,广告位长期出租 。

本文来源:原创投稿

*爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。


本文主要贡献者:进行OMS源码分析的@操盛春(北分之光)

一、走进OMS

本文以OMS社区版3.3.1为例

我们可以从官方的地址上获取到它的架构图,这是它大概的样子:

可以看到一个OMS数据迁移工具它包含了很多的组件,有DBCat、Store、Connector、JDBCWriter、Checker 和 Supervisor 等,组件的各个功能这里就不copy官方的叙述了,毕竟有手就行。接下来说点官网上没有的。

之前领导让我进行OMS性能测试时要顺便打印火焰图看一下,分析迁移过程中时间都用在了哪里,但是当我登录OMS容器后看到很多相关java进程,一时间分不清哪个进程是做什么的,那么接下里我们就对这些进程逐一说明

1.Ghana-endpoint

[ActionTech ~]# ps uax | grep Ghana-endpoint
root        61  3.1  0.5 20918816 1582384 pts/0 Sl  Feb07 1756:47 java -Dspring.config.location=/home/ds/ghana/config/application-oms.properties -server -Xms1g -Xmx2g -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -Xloggc:/home/admin/logs/ghana/gc.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=10M -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/home/admin/logs/ghana -jar /home/ds/ghana/boot/Ghana-endpoint-1.0.0-executable.jar

Ghana-endpoint负责提供OMS 后台管理界面、调度TaskJob和StructTaskJob程序

tips:

StructTaskJob:结构迁移任务调度程序

TaskJob:

  • TaskJob::scheduledTask(),负责正向切换步骤的子任务执行的调度
  • TaskJob::scheduleMigrationProject(),负责结构迁移项目所有步骤初始化 & 任务执行进度监控的调度

2.commons-daemon(CM)

[ActionTech ~]# ps uax | grep commons-daemon
root        50  297  1.7 25997476 4711620 pts/0 Sl  Feb07 163685:09 java -cp /home/ds/cm/package/deployapp/lib/commons-daemon.jar:/home/ds/cm/package/jetty/start.jar -server -Xmx4g -Xms4g -Xmn4g -Dorg.eclipse.jetty.util.URI.charset=utf-8 -Dorg.eclipse.jetty.server.Request.maxFormContentSize=0 -Dorg.eclipse.jetty.server.Request.maxFormKeys=20000 -DSTOP.PORT=8089 -DSTOP.KEY=cm -Djetty.base=/home/ds/cm/package/deployapp org.eclipse.jetty.start.Main

CM集群管理进程,为OMS 管理后台进程提供接口,用于创建拉取增量日志、全量迁移、增量同步、全量校验等任务,以及获取这些任务的执行进度

3.oms-supervisor

[ActionTech ~]# ps uax | grep oms-supervisor
ds          63  1.0  0.3 11780820 985860 pts/0 Sl   Feb07 566:35 java -server -Xms1g -Xmx1g -Xmn512m -verbose:gc -Xloggc:./log/gc.log -XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -Dserver.port=9000 -DconfigDir=/u01/ds/supervisor/config/ -Dspring.main.allow-circular-references=true -jar ./bin/oms-supervisor.jar

oms-supervisor进程用于启动执行拉取增量日志、全量迁移、增量同步、全量校验等任务的进程(组件),并监控这些进程的状态

4.store

store增量日志拉取进程,它是多进程协作,直接抓取store进程可能会看到下面一坨,其根进程为 ./bin/store,该进程有子进程及多个后代进程。

  • ./bin/store:模拟源节点的从库,从源节点接收增量日志
  • /u01/ds/store/store7100/bin/metadata_builder:进行过滤、转换,写入文件,并对DDL进行处理

这些进程会持续不断的把需要迁移表的增量日志拉取到 OMS 服务器上存储起来,以供增量同步任务使用。

5.全量迁移和全量校验

[ActionTech ~]# ps -ef | grep VEngine
UID          PID    PPID  C STIME TTY          TIME       CMD
ds         32635       1 99 11:21 pts/0    00:00:02       /opt/alibaba/java/bin/java -server -Xms8g -Xmx8g -Xmn4g -Xss512k -XX:ErrorFile=/u01/ds/bin/..//run//10.186.17.106-9000:90230:0000000016/logs/hs_err_pid%p.log -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/u01/ds/bin/..//run//10.186.17.106-9000:90230:0000000016/logs -verbose:gc -Xloggc:/u01/ds/bin/..//run//10.186.17.106-9000:90230:0000000016/logs/gc_%p.log -XX:+PrintGCDateStamps -XX:+PrintGCDetails -classpath lib/verification-core-1.2.54.jar:lib/verification-OB05-1.2.54.jar:lib/verification-TIDB-1.2.54.jar:lib/verification-MySQL-1.2.54.jar:lib/verification-OB-Oracle-Mode-1.2.54.jar:lib/verification-OB10-1.2.54.jar:lib/verification-Oracle-1.2.54.jar:lib/verification-DB2-1.2.54.jar:lib/verification-Sybase-1.2.54.jar:lib/verification-common-1.2.54.jar:lib/apache-log4j-extras-1.2.17.jar:lib/slf4j-log4j12-1.7.21.jar:lib/oms-conditions-3.2.3.12-SNAPSHOT.jar:lib/oms-common-3.2.3.12-SNAPSHOT.jar:lib/log4j-1.2.17.jar:lib/dws-rule-1.1.6.jar:lib/dws-schema-1.1.6.jar:lib/oms-record-3.2.3.12-SNAPSHOT.jar:lib/commons-io-2.6.jar:lib/metrics-core-4.0.2.jar:lib/connect-api-2.1.0.jar:lib/kafka-clients-2.1.0.jar:lib/slf4j-api-1.7.25.jar:lib/dss-transformer-1.0.10.jar:lib/calcite-core-1.19.0.jar:lib/dss-record-1.0.0.jar:lib/avatica-core-1.13.0.jar:lib/jackson-datatype-jsr310-2.11.1.jar:lib/jackson-databind-2.11.1.jar:lib/esri-geometry-api-2.2.0.jar:lib/jackson-dataformat-yaml-2.9.8.jar:lib/jackson-core-2.11.1.jar:lib/jackson-annotations-2.11.1.jar:lib/mysql-connector-java-5.1.47.jar:lib/oceanbase-1.2.1.jar:lib/druid-1.1.11.jar:lib/etransfer-0.0.65-SNAPSHOT.jar:lib/commons-lang3-3.9.jar:lib/aggdesigner-algorithm-6.0.jar:lib/commons-lang-2.6.jar:lib/fastjson-1.2.72_noneautotype.jar:lib/commons-beanutils-1.7.0.jar:lib/log4j-1.2.15.jar:lib/mapdb-3.0.8.jar:lib/kotlin-stdlib-1.2.71.jar:lib/annotations-16.0.3.jar:lib/calcite-linq4j-1.19.0.jar:lib/guava-29.0-jre.jar:lib/maven-project-2.2.1.jar:lib/maven-artifact-manager-2.2.1.jar:lib/maven-reporting-api-3.0.jar:lib/doxia-sink-api-1.1.2.jar:lib/doxia-logging-api-1.1.2.jar:lib/maven-settings-2.2.1.jar:lib/maven-profile-2.2.1.jar:lib/maven-plugin-registry-2.2.1.jar:lib/plexus-container-default-1.0-alpha-30.jar:lib/groovy-test-2.5.5.jar:lib/plexus-classworlds-1.2-alpha-9.jar:lib/junit-4.12.jar:lib/commons-dbcp2-2.5.0.jar:lib/httpclient-4.5.6.jar:lib/commons-logging-1.2.jar:lib/commons-collections4-4.1.jar:lib/oms-operator-3.2.3.12-SNAPSHOT.jar:lib/retrofit-2.9.0.jar:lib/jsr305-3.0.2.jar:lib/servlet-api-2.5.jar:lib/org.osgi.core-4.3.1.jar:lib/protobuf-java-3.11.0.jar:lib/maven-plugin-api-2.2.1.jar:lib/okhttp-3.14.9.jar:lib/maven-artifact-2.2.1.jar:lib/wagon-provider-api-1.0-beta-6.jar:lib/maven-repository-metadata-2.2.1.jar:lib/maven-model-2.2.1.jar:lib/plexus-utils-3.0.16.jar:lib/javax.annotation-api-1.3.2.jar:lib/javassist-3.20.0-GA.jar:lib/xml-apis-1.3.03.jar:lib/error_prone_annotations-2.3.4.jar:lib/easy-random-core-4.2.0.jar:lib/objenesis-3.1.jar:lib/commons-collections-3.2.2.jar:lib/lombok-1.18.16.jar:lib/antlr4-runtime-4.9.1.jar:lib/ojdbc8-19.7.0.0.jar:lib/orai18n-19.3.0.0.jar:lib/oceanbase-client-1.1.10.jar:lib/db2jcc-db2jcc4.jar:lib/jtds-1.3.1.jar:lib/javax.ws.rs-api-2.1.1.jar:lib/groovy-ant-2.5.5.jar:lib/groovy-cli-commons-2.5.5.jar:lib/groovy-groovysh-2.5.5.jar:lib/groovy-console-2.5.5.jar:lib/groovy-groovydoc-2.5.5.jar:lib/groovy-docgenerator-2.5.5.jar:lib/groovy-cli-picocli-2.5.5.jar:lib/groovy-datetime-2.5.5.jar:lib/groovy-jmx-2.5.5.jar:lib/groovy-json-2.5.5.jar:lib/groovy-jsr223-2.5.5.jar:lib/groovy-macro-2.5.5.jar:lib/groovy-nio-2.5.5.jar:lib/groovy-servlet-2.5.5.jar:lib/groovy-sql-2.5.5.jar:lib/groovy-swing-2.5.5.jar:lib/groovy-templates-2.5.5.jar:lib/groovy-test-junit5-2.5.5.jar:lib/groovy-testng-2.5.5.jar:lib/groovy-xml-2.5.5.jar:lib/groovy-2.5.5.jar:lib/sketches-core-0.9.0.jar:lib/json-path-2.4.0.jar:lib/janino-3.0.11.jar:lib/commons-compiler-3.0.11.jar:lib/hamcrest-core-1.3.jar:lib/gson-2.8.5.jar:lib/httpcore-4.4.13.jar:lib/commons-codec-1.15.jar:lib/ini4j-0.5.2.jar:lib/backport-util-concurrent-3.1.jar:lib/plexus-interpolation-1.11.jar:lib/failureaccess-1.0.1.jar:lib/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar:lib/checker-qual-2.11.1.jar:lib/j2objc-annotations-1.3.jar:lib/classgraph-4.8.65.jar:lib/zstd-jni-1.3.5-4.jar:lib/lz4-java-1.5.0.jar:lib/snappy-java-1.1.7.2.jar:lib/ant-junit-1.9.13.jar:lib/ant-1.9.13.jar:lib/ant-launcher-1.9.13.jar:lib/ant-antlr-1.9.13.jar:lib/commons-cli-1.4.jar:lib/picocli-3.7.0.jar:lib/qdox-1.12.1.jar:lib/jline-2.14.6.jar:lib/junit-platform-launcher-1.3.2.jar:lib/junit-jupiter-engine-5.3.2.jar:lib/testng-6.13.1.jar:lib/avatica-metrics-1.13.0.jar:lib/commons-pool2-2.6.0.jar:lib/snakeyaml-1.23.jar:lib/memory-0.9.0.jar:lib/eclipse-collections-forkjoin-11.0.0.jar:lib/eclipse-collections-11.0.0.jar:lib/eclipse-collections-api-11.0.0.jar:lib/lz4-1.3.0.jar:lib/elsa-3.0.0-M5.jar:lib/okio-1.17.2.jar:lib/junit-platform-engine-1.3.2.jar:lib/junit-jupiter-api-5.3.2.jar:lib/junit-platform-commons-1.3.2.jar:lib/apiguardian-api-1.0.0.jar:lib/jcommander-1.72.jar:lib/kotlin-stdlib-common-1.2.71.jar:lib/opentest4j-1.1.1.jar:conf com.alipay.light.VEngine -t 10.186.17.106-9000:90230:0000000016 -c /home/ds//run/10.186.17.106-9000:90230:0000000016/conf/checker.conf start

全量迁移和全量校验这两个任务的启动命令相同,但它其实是两个进程,所以我们无法从ps命令中分辨出该进程是全量迁移还是全量校验

想要区分需要看 /home/ds//run/10.186.17.106-9000:90230:0000000016/conf/checker.conf 文件,该文件就是上述启动命令中-c 参数所指定的配置文件。

condition.whiteCondition=[{"name":"sakila","all":false,"attr":{"dml":"d,i,u"},"sub":[{"name":"city"},{"name":"country"}]}]
condition.blackCondition=[{"name":"sakila","all":false,"sub":[{"name":"DRC_TXN*","func":"fn"},{"name":"drc_txn*","func":"fn"}]}]
datasource.master.type=MYSQL
......
task.split.mode=false
task.type=verify
task.checker_jvm_param=-server -Xms8g -Xmx8g -Xmn4g -Xss512k
task.id=90230
task.subId=3
task.resume=false

配置文件中的task.type 配置项的值代表了进程类型

  • task.type=migrate:全量迁移进程
  • task.type=verify:全量校验进程

6.增量同步进程

[ActionTech ~]# ps aux | grep "coordinator\.Bootstrap"
ds       58500 34.7  0.9 44600844 2575092 pts/0 Sl  Feb08 18483:51 java -server -XX:+DisableExplicitGC -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/u01/ds/bin/../run/10.186.17.104-9000:p_4gmn723gtt28_dest-000-0:0002000001 -Djava.library.path=/u01/ds/bin/../plugins/jdbc_connector/ -Duser.home=/home/ds -Dlogging.path=/u01/ds/bin/../run/10.186.17.104-9000:p_4gmn723gtt28_dest-000-0:0002000001/logs -cp jdbc_connector.jar:jdbc-source-store.jar:jdbc-sink-ob-mysql.jar com.oceanbase.oms.connector.jdbc.coordinator.Bootstrap -c conf -s com.oceanbase.oms.connector.jdbc.source.store.StoreSource -d com.oceanbase.oms.connector.jdbc.sink.obmysql.OBMySQLJdbcSink -t 10.186.17.104-9000:p_4gmn723gtt28_dest-000-0:0002000001 start

该进程用于读取增量日志,构造成SQL语句在目标节点进行回放

7.进程之间关系

二、迁移流程

上述是组成OMS的各个组件进程以及它们之间的关系。接下来我们用一个例子来简述下OMS内部工作流程。

以增量迁移任务为例:

通过同事对源码的分析,可得出迁移流程大致如下:

那么我们知道了迁移流程,接下来如何去剖析OMS迁移快慢的问题想必是每一个运维同事最为关心的点。

众所周知OMS的操作界面是十分简洁,明明用到了influxDB,但是展示出来的信息还是非常的少,几乎帮不上什么忙。

登录influxDB中可以看到如下相关监控项

["checker.dest.rps"]
["checker.dest.rt"]
["checker.dest.write.iops"]
["checker.source.read.iops"]
["checker.source.rps"]
["checker.source.rt"]
["checker.verify.dest.read.iops"]
["checker.verify.dest.rps"]
["checker.verify.dest.rt"]
["checker.verify.source.read.iops"]
["checker.verify.source.rps"]
["checker.verify.source.rt"]
["jdbcwriter.delay"]
["jdbcwriter.iops"]
["jdbcwriter.rps"]
["store.conn"]
["store.delay"]
["store.iops"]
["store.rps"]

除此之外OMS还使用了io.dropwizard.metrics5 做部分监控,由coordinator进程每10秒打印一次metrics,metrics的日志路径:/u01/ds/run/$test_id/logs/msg/metrics.log,日志内容为json格式,记录较为详细。

[2023-03-18 22:49:18.101] [{"jvm":{"JVM":"jvm:[heapMemory[max:30360MB, init:2048MB, used:677MB, committed:1980MB], noHeapMemory[max:0MB, init:2MB, used:58MB, committed:63MB], gc[gcName:ParNew, count:2643, time:64034ms;gcName:ConcurrentMarkSweep, count:8, time:624ms;], thread[count:88]]"},"sink":{"sink_worker_num":0,"sink_total_transaction":4.5654123E7,"rps":0.0,"tps":0.0,"iops":0.0,"sink_total_record":4.5654123E7,"sink_commit_time":0.0,"sink_worker_num_all":64,"sink_execute_time":0.0,"sink_total_bytes":2.8912799892E10},"source":{"StoreSource[0]source_delay":5,"p_4gmn723gtt28_source-000-0source_record_num":1.36962569E8,"p_4gmn723gtt28_source-000-0source_iops":198.98,"StoreSource[0]source_status":"running","p_4gmn723gtt28_source-000-0source_dml_num":4.5654123E7,"p_4gmn723gtt28_source-000-0source_dml_rps":0.0,"p_4gmn723gtt28_source-000-0source_rps":0.0},"dispatcher":{"wait_dispatch_record_size":0,"ready_execute_batch_size":0},"frame":{"SourceTaskManager.createdSourceSize":1,"queue_slot1.batchAccumulate":0,"forward_slot0.batchAccumulate":0,"forward_slot0.batchCount":4.7873212E7,"queue_slot1.batchCount":4.7873212E7,"queue_slot1.rps":0.6999300122261047,"SourceTaskManager.sourceTaskNum":0,"forward_slot0.recordAccumulate":0,"forward_slot0.rps":0.6999300122261047,"queue_slot1.tps":0.6999300122261047,"forward_slot0.tps":0.6999300122261047,"queue_slot1.recordAccumulate":0,"queue_slot1.recordCount":4.7873212E7,"forward_slot0.recordCount":4.7873212E7}}]

metrics.log是分析迁移瓶颈的重要工具,重点取source、dispatch、sink三个部分的监控值进行分析。

1.source阶段

作用:主要用于连接源端数据库,拉取增量日志,单线程运行,读取SQL以事务形式向下游输出,由于是单线程运行,因此整个动作只能串行完成。

TransactionAssembler::TransactionAssemblerInner::generateTransaction()将读到的SQL拼接成事务;

TransactionAssembler::TransactionAssemblerInner::putTransaction()发送到QueuedSlot队列中。

通过metrics.log可以获取到如下监控值:

  • source_record_num: Source阶段, 处理的行记录的总数 (在处理行记录(将行记录拼接为事务)时统计, TransactionAssembler.notify)
  • source_rps: Source阶段, 每秒处理的行记录数 (TransactionAssembler.notify)
  • source_iops: Source阶段, 每秒处理的行记录的大小 (TransactionAssembler.notify)
  • source_dml_num: Source阶段, 处理的DML的行记录的总数 (TransactionAssembler.notify)
  • source_dml_rps: Source阶段, 每秒处理的DML的行记录数 (TransactionAssembler.notify)
  • StoreSource[0]source_status: Source阶段的状态, running/stopped
  • StoreSource[0]source_delay: Source阶段的延迟, 处理数据的时间

可以利用influxDB将其制作成监控展示图,如下所示(部分):

2.dispatcher阶段

作用:协调生产和消费之间的速度,负责从 QueuedSlot 队列读取事务,然后写入事务调度队列(DefaultTransactionScheduler::readyQueue),队列大小默认值为16384,单线程。

  • dispatcher_ready_transaction_size: DefaultTransactionScheduler::readyQueue 队列中积压的事务数量,等待 SinkTaskManager 线程处理。
  • coordinator_dispatch_record_size: DefaultTransactionScheduler::readyQueue 队列中积压的事务的记录数量之和,等待 SinkTaskManager 线程处理。

3.sink阶段

作用:从上游的事务调度队列中获取数据,然后在目标数据库进行回放。多线程,线程数由workerNum配置项指定,默认16。

  • sink_tps: 每秒回放完成多少事务(在事务回放完成时统计)
  • sink_total_transaction: 回放事务的总数
  • sink_worker_num: 工作线程中忙碌线程的数量
  • sink_worker_num_all: 工作线程的总数
  • sink_rps: 每秒回放完成多少行记录
  • sink_total_record: 回放的行记录总数
  • sink_execute_time: 行记录的平均执行时间 = 事务的SQL执行时间 / 事务的记录数
  • sink_commit_time: 事务的提交阶段的平均时间
  • sink_iops: 每秒回放的事务的行记录大小, 单位为 kb/s
  • sink_total_bytes: 回放的事务的行记录大小总数

三、OMS优化

OMS留给运维的优化空间并不多,本期我们只围绕迁移链路进行优化,下文列举出了两个最直接的优化方式。

1.sink_worker_number

通过一组监控图来看查看OMS是否存在性能问题

在压测过程中,sink_worker_number和wait_dispatch_record监控视图呈现出来的曲线几乎一致。很明的可以看出是因为下游的消费能力的不足导致事务全部积压在dispatch的队列中,并且将dispatch的队列都打满了。

找到问题原因后优化也就变得简单了,只需要调大sink_worker_number的线程数就可以,修改如下图所示。

运维监控 – 组件 – 更新

找到“JDBCWriter.worker_num”值,建议修改成宿主机CPU逻辑核数,最大不超过CPU逻辑核数*4(具体数值可根据环境动态调整)。

2.迁移选项

OMS在创建迁移任务时,如果迁移任务中包含全量迁移的话可以选择“全量迁移并发速度”,档位越高占用的系统资源也就越多,如果宿主机资源丰富,可以选择“快速”。

如下是不同档位所需要的资源,这是官方自带的模板,也可以根据实际情况调整。

注:如果仅仅选择增量迁移是没有该选项的。

3.其他优化方式只能具体原因具体分析了。

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

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

相关文章

GPT-4,大增长时代的序幕

虽然我们早在 2017 年就预测了超大模型的到来,因此才搞了分布式深度学习框架 OneFlow(github.com/Oneflow-Inc/oneflow/),且 2020 年的 GPT-3 也掀起了大模型热潮(OneFlow—— 让每一位算法工程师都有能力训练 GPT&…

BGP相关实验

实验要求及其拓扑图 划分好IP的拓扑图 实验分析 1,AS1存在两个环回,一个地址为192.168.1.0/24该地址不能在任何协议中宣告,AS3中存在两个环回,一个地址为192.168.2.0/24该地址不能在任何协议中宣告,最终要求这两个环回可以互相…

30天学会《Streamlit》(4)

30学会《Streamlit》是一项编码挑战,旨在帮助您开始构建Streamlit应用程序。特别是,您将能够: 为构建Streamlit应用程序设置编码环境 构建您的第一个Streamlit应用程序 了解用于Streamlit应用程序的所有很棒的输入/输出小部件 第4天 - st…

【NLP】自然语言处理_NLP入门——分词和词性标注

【NLP】自然语言处理_NLP入门——分词和词性标注 文章目录 【NLP】自然语言处理_NLP入门——分词和词性标注1. 介绍2. 概念和工具2.1 分词2.2 词性标注2.3 NLTK2.4 Jieba2.5 LAC 3. 代码实现举例3.1 分词3.1.1 使用nltk进行分词3.1.2 使用jieba进行分词3.1.3 使用LAC进行分词 3…

定义全局变量property与getprop

authordaisy.skye的博客_CSDN博客-Qt,嵌入式,Linux领域博主 adb调试 adb shell getprop .adb logcat 报错 init: sys_prop: permission denied uid:1006 name:ro.camera.gc02m1 在linux驱动中查找 find ./ -name *.c | xargs grep -n "property_set" find ./ -n…

《2023金融科技·校园招聘白皮书》新鲜出炉|牛客独家

数智创新时代,科技人才为先。 眼下,在建设“数字中国”的时代背景下,金融行业全面数智化转型已箭在弦上。政策端,金融行业为中共中央、国务院印发《数字中国建设整体布局规划》的7大重点行业之一。 资本端,仅2022年三…

【C++ 四】函数、指针

函数、指针 文章目录 函数、指针前言1 函数1.1 概述1.2 函数定义1.3 函数调用1.4 值传递1.5 函数常见样式1.6 函数声明1.7 函数分文件编写 2 指针2.1 指针基本概念2.2 指针变量定义和使用2.3 指针所占内存空间2.4 空指针和野指针2.5 const 修饰指针2.6 指针和数组2.7 指针和函数…

Cross compiling Windows binaries from Linux

IntroductionWhy? SpeedCostContainers k8sRejected Strategies Using x86_64-pc-windows-gnuUsing wine to run the MSVC toolchainHow? Prerequisites1. Setup toolchain(s)2. Acquire Rust std lib3. Acquire CRT and Windows 10 SDK4. Override cc defaults5. ProfitBon…

机器学习 探索性数据分析

文章目录1. 数据总览1.1 查看数据的维度1.2 查看列的数据类型1.3 查看索引1.4 获取数据值1.5 数据集相关信息概览1.6 查看数据的统计信息1.7 查看前3行数据2. 缺失值查看与处理2.1 缺失值查看2.2 缺失值处理3. 异常值检测与处理3.1 异常值检测3.2 异常值处理4. 特征分析4.1 查看…

计算机网络考试复习——第4章 4.6

理想的路由算法:几个特点 1.算法必须是正确和完善的 2.算法在计算上应该简单 3.算法能适应通信量和网络拓扑的变化具有自适应性也称为稳健性 4.算法应该具有稳定性 5。算法应该是公平的 6.算法应该是最佳的 关于“最佳路由”——不存在一种绝对的最佳路由算法…

第二章 法的内容与形式

目录 第一节 法的内容与形式的概念 一、法的内容与形式的含义 二、法的内容和形式的关系 第二节 法律权利与法律义务 一、权利和义务的概念 二、权利和义务的分类 三、权利与义务的联系 第三节 法的成文形式与不成文形式 一、历史上各种法的表现形式 二、成文法与不成文…

defaultdict 默认值

文章目录 前言语法setdefault()和defaultdict()的区别setdefault()defaultdict() 前言 在字典中查找某一个值的时候,若key不存在就会返回一个keyerror错误而不是一个默认值,如果想要返回一个默认值可以使用defaultdict函数。 defaultdict是python内建dic…

从0搭建Vue3组件库(三): 组件库的环境配置

本篇文章将在项目中引入 typescript,以及手动搭建一个用于测试组件库组件 Vue3 项目 因为我们是使用 ViteTs 开发的是 Vue3 组件库,所以我们需要安装 typescript、vue3,同时项目将采用 Less 进行组件库样式的管理 pnpm add vuenext typescript less -D -w 使用pnpm如果要安装在…

【C语言】void 和 void* 类型

一. void 类型 1. 为何不能定义 void 类型的变量 为什么不能定义 void 类型的变量?因为它是空类型,不能够为变量提供空间吗? 定义变量的本质是开辟空间,我们用 sizeof 来计算 void 类型的大小: 在vs2017下&#xf…

Direct3D 12——模板——平面阴影效果

平行光阴影 图展示了由平行光源经物体所投射岀的阴影。给定方向为L的平行光源,并用r(t)p tL来表 示途经顶点p的光线。光线r (t)与阴影平面(n,d)的交点为S。以此光源射出的光线照射到物体的各个顶点&#x…

Stable Diffusion本地搭建windows and linux(附搭建环境)

linux搭建过程以centos为例 1.使用git工具下载项目文件到本地文件夹,命令如下: git clone https://github.com/IDEA-CCNL/stable-diffusion-webui.git然后进入该文件夹: cd stable-diffusion-webui2.运行自动化脚本 运行webui.sh安装一些p…

2023最新接口自动化测试面试真题详解,看完轻松拿捏HR

目录 一.有接口测试工具为什么还需要开发自动化框架或自动化平台。 二.接口自动化中如果一个接口请求不通该如何排查 三.你平常做接口自动化的过程中发现过哪些bug?多吗? 四.你在接口自动化中是怎么校验接口返回结果是否正确? 五、接口自动化回归过程中…

【C生万物】 操作符篇

欢迎来到 Claffic 的博客 💞💞💞 前言: 我觉得学习语言,最直接的就是懂不懂符号,而符号中最突出的就是操作符,这期带大家认识认识C语言中的操作符及其使用。 目录 Part1:算数操作符 Part2:移…

直方图均衡化(调节图像亮度、对比度)

直方图均衡化(调节图像亮度、对比度) 本篇目录 🦄 一、前言 🦄 二、直方图均衡化概念 🦄 三、直方图均衡化实例 (1)、灰度图像的均衡处理实例 ①、卡通人物灰度图像均衡处理 ②、卡通猫头…

音频编辑开发SDK Audio DJ Studio for .NET Crack

11.7版本--Audio DJ Studio for .NET是 MultiMedia Soft 开发的 .NET Windows Forms 自定义控件,可以轻松地向使用Microsoft Visual Studio编写的Winform和WPF 应用程序添加声音播放和混音功能;由于与 DirectShow 编解码器和 BASS 库的集成,两…