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

2.3.1(项目)kv存储——框架梳理(待定)

一、过一遍代码路线:

体会:(1)接口统一、测试标准统一,软件才会有量产的过程;(b)多层框架,实现业务部分和网络部分的完全剥离。

实现多层框架

(1)第一层是底层网络框架;(2)第二层是业务层的协议设计(发什么数据,以及收什么数据);(3)第三层是实现kvstore模式的核心层:为了适配第五层的kv引擎层(选取数据结构),做了第四层接口适配层(5[set, get, del, mod, exist]+2[create,destory])(4)测试用例

1. 底层网络框架

目的:通过定义函数建立网络层和业务层的联系,并从原有已以网络框架为主改造后以业务框架为main函数,确保此后网络层隔离和透明(以reactor.c为例)。

要求reactor.c(手写)、ntyco协程(看懂)、io_uring(看懂)。

做法:用做reactor的做法来做kvstore的网络框架

核心:是设置自定义的结构体,明确什么事件执行什么回调函数。while(1){}循环里,(a)EPOLLIN事件执行recv_callback,EPOLLOUT事件执行send_callback。(b)EPOLLIN事件包含sockfd和clientfd,分别执行accept函数和recv/send函数,可以通过recv_callback的index加以区分。

要点:

知识点(1):通过宏定义开启或关闭不同的功能,由此方便新功能编写。

#define ENABLE_KVSTORE        1
#if    ENABLE_KVSTOREkvs_request(&connect_list[fd]);
#endif#if    ENABLE_KVSTOREkvs_response(&connect_list[fd]);
#endif

知识点(2):(1) 协议处理 → 放到kvstore.c;(2)main入口函数 → 放到网络框架(reactor.c)里面?还是放到kvstore.c里面?

答:如果把main入口函数放到网络框架(reactor.c)就表明主要程序由网络框架实现,按照这个逻辑kvstore.c只是其中的一个业务,而流程不应该这样。所以main要放到kvstore.c里面,以保证网络层被完全的隔离。对于一个服务而言,我们要最终封装成:网络层仅需要传输端口(port)协议的接口(kvs_protocol)这两个端口过去,

知识点(3)网络框架(reactor.c)里如何与kvstore.c连接:

(a)定义kvs_request和kvs_response;

(b)send_cb和recv_cb分别设置kvs_request和kvs_response;

(c)send_cb里的kvs_request使用kvs_handler处理数据

kvs_handler通过“static msg_handler kvs_handler” 定义类型,在网络框架(reactor.c)主函数里被handler赋值 

handler作为网络框架(reactor.c)主函数里其中一个输入参数,被msg_handler结构体赋值   

结构体msg_handler在网络框架(reactor.c)被定义,包含*msg、length、*response,同时也在kvstore.h文件里。

作为在网络框架(reactor.c)主函数输入参数的handler,在kvstore.c里被定义为kvs_protocal。网络框架(reactor.c)的命令行 “static msg_handler kvs_handler” 为了 “kvs_handler = handler”。

网络层的编译命令

此处的代码:

server.h(基本没变化)

#ifndef __SERVER_H__
#define __SERVER_H__#define BUFFER_LENGTH		128#define ENABLE_KVSTORE              1typedef int  (*RCALLBACK)(int fd);struct conn {int       fd;char    rbuffer[BUFFER_LENGTH];int       rlength;char    wbuffer[BUFFER_LENGTH];int       wlength;RCALLBACK  send_callback;RCALLBACK  recv_callback;
};#if ENABLE_KVSTORE
int kvs_request(struct conn *c);
int kvs_response(struct conn *c);
#endif#endif

kvs_reactor.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <string.h>
#include <errno.h>
#include <sys/epoll.h>
#include <unistd.h>
#include <sys/time.h>
#include "server.h"//#define BUFFER_LENGTH       1024
#define CONNECT_SIZE           1048576
#define PORT_SIZE                   1#define TIME_SUB_MS(tv1, tv2)  ((tv1.tv_sec - tv2.tv_sec) * 1000 + (tv1.tv_usec - tv2.tv_usec) / 1000)#if ENABLE_KVSTOREtypedef int (*msg_handler)(char *msg, int length, char *response);
static msg_handler kvs_handler;int kvs_request(struct conn *c){//	printf("recv %d: %s\n", c->rlength ,c->rbuffer);c->wlength = kvs_handler(c->rbuffer, c->rlength, c->wbuffer);}#endifint kvs_response(struct conn *c){}//typedef int  (*RCALLBACK)(int fd);int accept_cb(int fd);
int recv_cb(int fd);
int send_cb(int fd);int epfd = 0;struct timeval begin;/*
struct conn {int       fd;char    rbuffer[BUFFER_LENGTH];int       rlength;char    wbuffer[BUFFER_LENGTH];int       wlength;RCALLBACK  send_callback;RCALLBACK  recv_callback;
};
*/struct conn connect_list[CONNECT_SIZE] = {0};int set_event(int fd, int event, int flag){if (flag == 1){ // non-zero addstruct epoll_event ev;ev.data.fd = fd;ev.events = event;epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev);} else {           // zero MODstruct epoll_event ev;ev.data.fd = fd;ev.events = event;epoll_ctl(epfd, EPOLL_CTL_MOD, fd, &ev);}}int event_register(int fd, int event){if (fd < 0){return -1;}connect_list[fd].fd = fd;connect_list[fd].recv_callback = recv_cb;connect_list[fd].send_callback = send_cb;memset(connect_list[fd].rbuffer, 0, BUFFER_LENGTH);connect_list[fd].rlength = 0;memset(connect_list[fd].wbuffer, 0, BUFFER_LENGTH);connect_list[fd].wlength = 0;set_event(fd, EPOLLIN, 1);}int accept_cb(int fd){struct sockaddr_in clientaddr;socklen_t len = sizeof(clientaddr);int clientfd = accept(fd, (struct sockaddr*)&clientaddr, &len);if (clientfd < 0){printf("accept error:  %d, %s\n", errno, strerror(errno));return -1;}event_register(clientfd, EPOLLIN);if((clientfd % 1000) == 0){struct timeval current;gettimeofday(&current, NULL);int time_used = TIME_SUB_MS(current, begin);memcpy(&begin, &current, sizeof(struct timeval));printf("Accept clientfd : %d, time_used: %d\n", clientfd, time_used);}return 0;
}int recv_cb(int fd){int count = recv(fd, connect_list[fd].rbuffer, BUFFER_LENGTH, 0);if (count ==0){printf("client disconnect: %d\n", fd);close(fd);epoll_ctl(epfd, EPOLL_CTL_DEL, fd, NULL);  // unfinishedreturn 0;}connect_list[fd].rlength = count;//	printf("rbuffer: %s, recv: %d\n", connect_list[fd].rbuffer, count);# if 0 //echoconnect_list[fd].wlength = connect_list[fd].rlength;memcpy(connect_list[fd].wbuffer, connect_list[fd].rbuffer, connect_list[fd].wlength);
#endif#if    ENABLE_KVSTOREkvs_request(&connect_list[fd]);
#endifset_event(fd, EPOLLOUT, 0);return count;
}int send_cb(int fd){#if    ENABLE_KVSTOREkvs_response(&connect_list[fd]);
#endifint count = 0;count = send(fd, connect_list[fd].wbuffer, connect_list[fd].wlength, 0);
//	printf("wbuffer: %s, send: %d\n", connect_list[fd].wbuffer, count);set_event(fd, EPOLLIN, 0);return count;}int r_init_server(unsigned short port){int sockfd = socket(AF_INET, SOCK_STREAM, 0);struct sockaddr_in servaddr;servaddr.sin_family = AF_INET;servaddr.sin_addr.s_addr= htonl(INADDR_ANY);  // uint32_tservaddr.sin_port = htons(port);if (-1 == bind(sockfd, (struct sockaddr*)&servaddr, sizeof(struct sockaddr))) {printf("bind failed: %s\n", strerror(errno));}listen(sockfd, 10);
//	printf("listen finished: %d\n", sockfd);return sockfd;
}int reactor_start(unsigned short port, msg_handler handler){epfd = epoll_create(1);//unsigned short port = 2000;kvs_handler =  handler;int i = 0;for (i = 0; i < PORT_SIZE; i ++){int sockfd = r_init_server(port + i);connect_list[sockfd].fd =  sockfd;connect_list[sockfd].recv_callback = accept_cb;printf("sockfd: %d\n", sockfd);set_event(sockfd, EPOLLIN, 1);}gettimeofday(&begin, NULL);while(1){struct epoll_event events[1024] = {0};int nready = epoll_wait(epfd, events, 1024, -1);
//		printf("epoll_wait is %d\n", nready);int i = 0;for (i = 0; i < nready; i ++){int connfd = events[i].data.fd;if (events[i].events & EPOLLIN){connect_list[connfd].recv_callback(connfd);}if (events[i].events & EPOLLOUT){connect_list[connfd].send_callback(connfd);}}}return 0;
}

kvstore.c

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "kvstore.h"/*
* msg: request message
* length: length of request message
* response:  need to seed
*@return: length of response
*/int kvs_protocal(char *msg, int length, char *response){printf("recv %d: %s\n", length, msg);memcpy(response, msg, length);return strlen(response);
}int main(int argc, char *argv[]){ //  input parametersif (argc != 2) return -1;// ./program Hello World: Number of arguments is 3int port = atoi(argv[1]);#if   (NETWORK_SELECT  ==  NETWORK_REACTOR)reactor_start(port, kvs_protocal);
#elif#endif}

kvstore.h

#ifndef   __KV_STORE_H__
#define  __KV_STORE_H__#define NETWORK_REACTOR     0#define NETWORK_SELECT        NETWORK_REACTORtypedef int (*msg_handler)(char *msg, int length, char *response);extern int reactor_start(unsigned short port, msg_handler handler);const char *command[] = {"SET", "GET", "DEL", "MOD", "EXIST"
};const char *response[] = {};#endif

2. 业务层的协议设计:

目的:在前面已经建立tcp公共协议连接的基础上,建立发什么数据和接收什么数据的私有协议 / 自定义协议 / 发数据的格式。

具体做法:对于网络部分已经实现了数据的接收和发送,所以接下来我们要在收数据的地方修改,在原有reactor.c的基础上,

(1)新建kvstore.c定义有关业务联系的函数(接收request和输出response);

(2)新建kvstore.h为函数(接收request和输出response)定义函数具体的协议、具体response

具体5个response格式:

command(命令)
服务器接收    SET         Key     Value
服务器发送    OK服务器接收    GET         Key
服务器发送    Value服务器接收    DEL         Key
服务器发送    OK服务器接收    MOD         Key     Value
服务器发送    OK服务器接收    EXIST       Key
服务器发送    Yes/No

(3)在上一部分网络已经封装基础上,以kvstore.c里的自定义kvs_protocol函数(也就是对应网络框架(reactor.c) 的主函数第2个输入参数)为入口函数,进行具体的协议解析功能(也就是定义接收和发送的数据规则含义,如下2种模式)

SET Key Value
Get Key

要点:

知识点(1):针对tcp的分包和粘包,问题1是什么是分包和粘包,问题2是怎么解决这个问题?

答1:由于send(fd, buffer, length, 0)的次数和recv(fd, buffer, length, 0)可能不一致,可能send()多次发送recv一次性都接收了(这就是粘包),所以要区分出每次的数据(分包解数据)。

答2:分包的时候需要和对方约定好格式,同时tcp连接满足假设(1) recv()先接收的数据就是对方先发送的数据,保证了接收数据的顺序;(2)  数据在传输过程中不会发生丢包情况,保证了数据必达性

方式1. send()在发包时就确定约定的长度,比如接收2次就可以接收完整的数据包,第一次接收2字节作为标志,第二次再接收数据包。

SEND:
[15]SET Key Value\r\n   // 15表示15个字符
第一次:接收开头的2个字符,同时通过这2个字符的值得知后面还要接收15字符
short length = 0;
recv(fd, &length, 2, 0);
第二次:接收剩余数据15个字符
recv(fd, buffer, length, 0);

方式2. 仿照Redis,先确定有多少(N)个token后就先发送字符N,具体发送格式如下:

Refis → SET Key Value
发送顺序如下
3\r\n     // 3表示“SET Key Value”一共是3个token(单词)
3\r\n     // 3表示第一个token(单词)“SET"是3个字符的长度
SET\r\n   // 发送一个token,“SET"
3\r\n     // 3表示第二个token(单词)“Key"也是3个字符的长度
Key\r\n   // 发送一个token,“Key"
5\r\n     // 5表示第三个token(单词)“Value"也是5个字符的长度
Value\r\n   // 发送一个token,“Value"

伪代码如下,最终要读(1+2*3)=7次

自行实现readline()函数,要求每一行读到"\r\n"就停止count = atoi(buffer);
for (i = 0; i < count; i ++){readline(fd, tokenlen);readline(fd, token);
}

3. 业务层的引擎设计(也就是数据结构,包括数组、红黑树、希哈)

目的:构建数据结构,通过私有协议在数据库中进行增删改查。

4. 测试用例

目的:用代码模拟自动化的流程,进行测试操作。

做法(1)tcp客户端建立网络连接;(2)客户端发送协议;(3)接收服务端返回的数据;(4)将预期数据 与 服务端 返回的数据对比,如果一致则用例通过,如果不一致则失败。

二、备注:

(1) “const char *command[] ={};” 什么意思?以及为什么是const以及为什么*?

答:const: 确保字符串内容不能被修改。*: 表示指针,每个数组元素都指向一个字符串。

(2) 定义函数不用分号";",而结构体需要,那么什么时候需要加“;”?

答:定义一个类型(例如 struct 或 typedef)告诉编译器这个类型存在但并不提供执行行为,需要以分号结束。

(a)需要分号的地方:变量声明、结构体定义、typedef 定义新类型

int a = 10; // 表示变量声明结束struct Point {int x;char y;
}; // 分号表示 `struct Point` 的定义结束typedef struct {int x;char y;
} PointType; // 分号表示 `typedef` 的结束

(b)不需要分号的地方:函数定义、#define 宏(宏是简单的文本替换)。

int add(int a, int b) {return a + b; // 函数体内语句的分号只是代码逻辑的一部分
}#define SQUARE(x) ((x) * (x)) // 宏定义

(3)为什么分为 .c 和 .h 文件?

答:每个 .c 文件负责一个模块的实现,多个模块通过 .h 文件互相调用。.h 文件只能声明接口,不能包含具体实现。自定义头文件使用双引号:#include "xxxx.h"。

(4)"int main(int argc, char *argv[]){}" 是一个标准的 C 语言程序入口函数。

答:argc表示参数个数 (Argument Count),argv表示参数向量 (Argument Vector)。用于获取命令行传递给程序的参数。

int main(int argc, char *argv[]) {printf("Number of arguments: %d\n", argc);for (int i = 0; i < argc; i++) {printf("Argument %d: %s\n", i, argv[i]);}return 0;
}
运行:
./program Hello World
输出:
Number of arguments: 3
Argument 0: ./program
Argument 1: Hello
Argument 2: World

(5)Makefile怎么写?

答:由于编译中涉及的文件和命令较多,所以建立Makefile文件进行编译。

编写Makefile的核心思路:“替代”,核心命令就是"all"后面的命令

all: $(SUBDIR) $(TARGET) $(TESTCASE)
CC = gcc
FLAGS = -I ./NtyCo/core/ -L ./NtyCo/ -lntyco -lpthread -luring -ldl
SRCS = kvstore.c ntyco.c proactor.c kvs_array.c kvs_rbtree.c kvs_hash.c
TESTCASE_SRCS = testcase.c
TARGET = kvstore
SUBDIR = ./NtyCo/
TESTCASE = testcaseOBJS = $(SRCS:.c=.o)all: $(SUBDIR) $(TARGET) $(TESTCASE)$(SUBDIR): ECHOmake -C $@ECHO:@echo $(SUBDIR)$(TARGET): $(OBJS)$(CC) -o $@ $^ $(FLAGS)$(TESTCASE): $(TESTCASE_SRCS)$(CC) -o $@ $^%.o: %.c$(CC) $(FLAGS) -c $^ -o $@clean:rm -rf $(OBJS) $(TARGET) $(TESTCASE)

(6)kvstore为什么用单线程?多线程呢?

答:单线程适用于请求较短、计算简单、高频操作的场景,比如 Redis 这种以 key-value 数据存储为主的系统。避免了多线程中需要加锁的情况,不需要复杂的锁管理。

(7)如何实现一个范围查询?用什么数据结构?

答:

相关文章:

2.3.1(项目)kv存储——框架梳理(待定)

一、过一遍代码路线&#xff1a; 体会&#xff1a;&#xff08;1&#xff09;接口统一、测试标准统一&#xff0c;软件才会有量产的过程&#xff1b;&#xff08;b&#xff09;多层框架&#xff0c;实现业务部分和网络部分的完全剥离。 实现多层框架&#xff1a; &#xff0…...

【YOLOv10改进[Backbone]】使用ConvNeXtV2替换Backbone

本文将进行在YOLOv10中使用ConvNeXtV2替换Backbone魔改v10的实践,文中含全部代码、详细修改方式。助您轻松理解改进的方法。 目录 一 ConvNeXtV2 二 魔改YOLOv10 1 整体修改 ① 添加python文件 ② 修改ultralytics/nn/tasks.py文件 2 配置文件...

在C#中添加I/O延时和持续时间

在C#中添加I/O延时和持续时间&#xff0c;可以通过以下方法实现。具体来说&#xff0c;延时可以通过Thread.Sleep、Task.Delay等方式来模拟延迟&#xff0c;而持续时间的控制可以通过循环结构来设定持续的时间。在执行I/O操作时&#xff0c;你可以在操作之间添加延时&#xff0…...

VUE之路由Props、replace、编程式路由导航、重定向

目录 1、路由_props的配置 2、路由_replaces属性 3、编程式路由导航 4、路由重定向 1、路由_props的配置 1&#xff09;第一种写法&#xff0c;将路由收到的所有params参数作为props传给路由组件 只能适用于params参数 // 创建一个路由器&#xff0c;并暴露出去// 第一步…...

RabbitMQ的消息可靠性保证

文章目录 1.环境搭建1.common-rabbitmq-starter 配置防止消费者抢消息&#xff08;基础配置&#xff09;2.common-rabbitmq-starter-demo下创建一个生产者一个消费者 2.生产者可靠性1.开启消息超时重试机制2.生产者开启ConfirmCallback消息确认机制1.application.yml2.TestConf…...

MySQL 很重要的库 - 信息字典

在做owasp SQL 注入的时候&#xff0c;有个很重要的库&#xff0c;那就是 信息库: 这个库就是: information_schema; &#xff08;准确的说&#xff0c;数据字典) mysql> show databases; -------------------- | Database | -------------------- | informa…...

使用C#对指定的MYSQL数据库进行备份以及常见问题

最近在开发过程中&#xff0c;需要做个MYSQL数据库的备份&#xff0c;大致总结了一下代码&#xff0c;以及常见的坑 string bakName "database" DateTime.Now.ToString("yyyyMMddHHmmss") ".sql";//备份后的数据库文件名var bakupFilePath &q…...

Appium(四)

一、app页面元素定位 1、通过id定位元素: resrouce-id2、通过ClassName定位&#xff1a;classname3、通过AccessibilityId定位&#xff1a;content-desc4、通过AndroidUiAutomator定位5、通过xpath定位xpath、id、class、accessibility id、android uiautomatorUI AutomatorUI自…...

jvm_threads_live_threads 和 jvm_threads_states_threads 这两个指标之间存在一定的关系,但它们关注的维度不同

jvm_threads_live_threads 和 jvm_threads_states_threads 这两个指标之间存在一定的关系&#xff0c;但它们关注的维度不同。以下是它们的详细关系和区别&#xff1a; 1. jvm_threads_live_threads 含义&#xff1a; 表示当前 JVM 中存活的线程总数&#xff08;即当前活动的线…...

docker 部署.netcore应用优势在什么地方?

目录 1. 环境一致性 2. 简化依赖管理 3. 快速部署与扩展 4. 资源利用率高 5. 版本控制与回滚 6. 安全性 7. 生态系统支持 8. 微服务架构支持 9. 降低成本 10. 开发体验提升 总结 使用 Docker 部署 .NET Core 应用有许多优势&#xff0c;特别是在开发、测试和生产环境…...

SpringBoot开发(一)应用jar包

1. SpringBoot开发 1.1. 目标及简介 1.1.1. 目标 &#xff08;1&#xff09;掌握微服务SpringBoot在实际项目开发中常用的核心技术栈及其在典型业务场景下的应用实战。   &#xff08;2&#xff09;掌握SpringBoot SpringMVC Mybatis在Java Web应用开发过程的技术干货以及…...

【Linux】深刻理解动静态库

1.什么是库 库是写好的现有的&#xff0c;成熟的&#xff0c;可以复⽤的代码。现实中每个程序都要依赖很多基础的底层库&#xff0c;不可能每个⼈的代码都从零开始&#xff0c;因此库的存在意义⾮同寻常。本质上来说库是⼀种可执⾏代码的⼆进制形式&#xff0c;可以被操作系统载…...

【spring 事务】事务的基本使用,事务隔离级别、事务传播机制

在Spring框架中&#xff0c;声明式事务管理是一种通过注解或配置文件自动管理事务的方式&#xff0c;而不需要手动编写事务管理代码。Transactional是Spring提供的一个注解&#xff0c;用于声明式事务管理&#xff0c;它使得事务的管理变得简单而清晰。 主要特性 自动事务管理…...

arkime 和elasticsearch安装方法二

这次试一下新的办法 先下载centOS 7 然后改成阿里云镜像 输入命令备份官方yum源配置文件 cp /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak 下载阿里云源配置&#xff0c;覆盖原文件 curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirr…...

GitCode 助力 AutoTable:共创 MyBatis 生态的自动表格管理新篇章

项目仓库https://gitcode.com/dromara/auto-table 解放双手&#xff0c;专注业务&#xff1a;MyBatis 生态的“自动表格”创新 AutoTable 是一款致力于为 MyBatis 生态赋予“自动表格”功能的创新插件。其核心理念是通过 Java 实体类自动生成和维护数据库的表结构&#xff0c…...

日历热力图,月度数据可视化图表(日活跃图、格子图)vue组件

日历热力图&#xff0c;月度数据可视化图表&#xff0c;vue组件 先看效果&#x1f447; 在线体验https://www.guetzjb.cn/calanderViewGraph/ 日历图简单划分为近一年时间&#xff0c;开始时间是 上一年的今天&#xff0c;例如2024/01/01 —— 2025/01/01&#xff0c;跨度刚…...

ue5 制作,播放,停止动画蒙太奇

右键&#xff0c;动画蒙太奇 新建插槽 把默认插槽选择为&#xff0c;自己新建的插槽 然后拖一个动画进去 input换成玩家0 就可以接收键盘事件 pawn 自动控制玩家换成玩家0 找到动画蓝图 把它化成我们那边蒙太奇里面的槽 第三步&#xff1a;第三人称角色蓝图 按下F…...

Genetic Prompt Search via Exploiting Language Model Probabilities

题目 利用语言模型概率的遗传提示搜索 论文地址&#xff1a;https://www.ijcai.org/proceedings/2023/0588.pdf 项目地址&#xff1a;https://github.com/zjjhit/gap3 摘要 针对大规模预训练语言模型(PLMs)的即时调优已经显示出显著的潜力&#xff0c;尤其是在诸如fewshot学习…...

mysql之表的外键约束

MySQL表的外键约束详细介绍及代码示例 外键约束是数据库中用于维护数据完整性和一致性的重要机制。它确保一个表中的数据与另一个表中的数据相关联&#xff0c;防止无效的数据引用。本文将详细介绍了外键约束的各个方面&#xff0c;并通过具体的代码示例进行演示。 1. 外键约束…...

linux环境变量配置文件区别 /etc/profile和~/.bash_profile

在 Linux 系统中&#xff0c;环境变量可以定义用户会话的行为&#xff0c;而这些变量的加载和配置通常涉及多个文件&#xff0c;如 ~/.bash_profile 和 /etc/profile。这些文件的作用和加载时机各有不同。以下是对它们的详细区别和用途的说明&#xff1a; 文章目录 1. 环境变量…...

C++----STL(vector)

vector的介绍 vector的文档介绍&#xff1a;cplusplus.com/reference/vector/vector/ 1.基本概念 简单来说&#xff0c;vector是表示可以改变大小的数组的顺序容器。使用连续的存储位置来存储元素&#xff0c;因此可以通过常规指针的偏移量来高效访问。 2.内部机制 vector…...

springboot项目适配电科金仓数据库

又接到了信创适配任务,话不多说,直接开始干货 首先安装一下电科金仓的数据库,直接官网下,对应的授权也下90天的专业版,客户肯定是整个采购,365天的开发版本连接数有限制 KES相关下载地址:电科金仓-成为世界卓越的数据库产品与服务提供商 安装就不做赘述了 启动数据库…...

C# 动态创建Label和ComboBox控件并修改Text获取Text

背景&#xff1a;在做项目的时候可能需要根据一定数量创建某些控件并修改其属性&#xff0c;本文以控件label、ConboBox控件进行动态创建。 程序运行前后的的Form动态图 代码如下&#xff1a; using System; using System.Collections.Generic; using System.ComponentModel; …...

HP 笔记本重新安装 Windows 11 无法启动

相信你搜到这篇文章的时候&#xff0c; 你已经看过了网上各种关于如何在 HP 笔记本电脑上安装 Windows 11 的文章。你遇到的问题肯定不是网上那些文章讲的那么简单的问题。你遇到的一定不是你不懂如何安装 Windows&#xff0c;不懂如何对硬盘分区等等小白问题。 问题描述 问…...

BUUCTF_Web( XSS COURSE 1)xss

XSS即跨站脚本攻击&#xff08;Cross-Site Scripting&#xff09;&#xff0c;是一种常见的网络安全漏洞. 定义 XSS攻击指攻击者在目标网站中注入恶意脚本&#xff0c;当用户访问该网站时&#xff0c;浏览器会执行这些恶意脚本&#xff0c;从而导致用户信息泄露、被控制等安全问…...

STM32补充——IAP

0 前置知识&#xff1a; FLASH相关内容&#xff1a;前往STM32补充——FLASH STM32三种烧录方式&#xff08;看看就行&#xff09;&#xff1a; 1.ISP&#xff1a;In System Programming&#xff08;在系统编程&#xff09; 执行芯片厂商的 Bootloader 程序进入 ISP 模式&…...

APP加固的那些事

APP加固是保护APP代码逻辑的重要手段&#xff0c;通过隐藏、混淆、加密等操作提高软件的逆向成本&#xff0c;降低被破解的几率&#xff0c;保障开发者和用户利益。本文将介绍APP加固常见失败原因及解决方法&#xff0c;以及处理安装出现问题的情况和资源文件加固策略选择。 引…...

数据分析 基础定义

一、大数据的定义 数据分析是基于商业等目的&#xff0c;有目的的进行收集、整理、加工和分析数据&#xff0c;提炼有价值信息的过程。 大数据分析即针对海量的、多样化的数据集合的分析 大数据分析是一种利用大规模数据集进行分析和挖掘知识的方法。随着互联网、社交媒体、移动…...

PyTorch广告点击率预测(CTR)利用深度学习提升广告效果

目录 广告点击率预测问题数据集结构广告点击率预测模型的构建1. 数据集准备2. 构建数据加载器3. 构建深度学习模型4. 训练与评估 总结 广告点击率预测&#xff08;CTR&#xff0c;Click-Through Rate Prediction&#xff09;是在线广告领域中的重要任务&#xff0c;它帮助广告平…...

嵌入式入门(二)-STM32CubeMX项目开发

使用STM32CubeMX创建项目 本文使用STM32CubeMX模拟器创建一个嵌入式项目的详细流程。 New Project 根据型号搜索 搜索型号&#xff1a; STM32F103C8T6 启动项目 选择STM32F103C8T6后点击 Start Project 配置时钟 切换到 Clock Configuration 修改HCLK -->72MHZ 修改Input fr…...

MATLAB绘图时线段颜色、数据点形状与颜色等设置,介绍

MATLAB在绘图时&#xff0c;设置线段颜色和数据点的形状与颜色是提高图形可读性与美观性的重要手段。本文将详细介绍如何在 MATLAB 中设置这些属性。 文章目录 线段颜色设置单字母颜色表示法RGB 值表示法 数据点的形状与颜色设置设置数据点颜色和形状示例代码 运行结果小结 线段…...

Java菜鸟养成计划(java基础)--java运算符

java中的运算符 1、java中的运算符1.1 、 、-、 * 、/ 、 %1.2 、、-、 *、/、%1.3 、、--【自增\自减运算符】1.4、>、 <、 > 、< 、 、! 、! 1.5、&&、||、|、&1.6、&、|、~、^1.7、>> 、 <<、>>>位运算1.8、?:三目运算符…...

学习笔记——动态规划

递推 1.递推和动态规划有什么关系&#xff1f; 递推问题包括动态规划&#xff0c;动态规划一定是递推&#xff0c;递推不一定是动态规划。 动态规划是一种决策性的问题&#xff0c;是在状态中做最优决策的一种特殊递推算法&#xff0c;通常的问法包括求最大最小值等&#xff…...

蓝桥杯备考:红黑树与map和set

搜索二叉树 我们三种树只了解原理&#xff0c;不写代码&#xff0c;因为我们竞赛不做要求&#xff0c;只是为了使用set和map做铺垫 原理记不住&#xff0c;没关系&#xff0c;我们只要会各种操作的时间复杂度 二叉搜索树的定义 1若左子树非空&#xff0c;左子树所有结点的权…...

第二届生成式人工智能与信息安全国际学术会议(GAIIS 2025)

在线投稿&#xff1a; 学术会议-学术交流征稿-学术会议在线-艾思科蓝 【征文主题】&#xff08;包括但不限于&#xff09; 深度学习 自然语言处理 算法应用 计算机视觉 视觉识别 模式识别 强化学习 生成对抗网络 生成建模技术 语言预训练 视觉预训练 联合预训练…...

后端面试题分享第一弹(状态码、进程线程、TCPUDP)

后端面试题分享第一弹 1. 如何查看状态码&#xff0c;状态码含义 在Web开发和调试过程中&#xff0c;HTTP状态码是了解请求处理情况的重要工具。 查看状态码的步骤 打开开发者工具&#xff1a; 在大多数浏览器中&#xff0c;您可以通过按下 F12 键或右键单击页面并选择“检查…...

Python 常用运维模块之OS模块篇

Python 常用运维模块之OS模块篇 OS 模块获取当前工作目录更改当前工作目录返回当前目录路径返回上一级目录路径递归生成目录路径删除目录创建目录删除目录列出特定目录下文件和子目录删除某个特定文件重命名某个文件获取某个文件/目录的信息输出目录路径分隔符输出文件行终止符…...

前沿技术趋势洞察:2024年技术的崭新篇章与未来走向!

引言 时光飞逝&#xff0c;2024年已经来临&#xff0c;回顾过去一年&#xff0c;科技的迅猛进步简直让人目不暇接。 在人工智能&#xff08;AI&#xff09;越来越强大的今天&#xff0c;我们不再停留在幻想阶段&#xff0c;量子计算的雏形开始展示它的无穷潜力&#xff0c;Web …...

HTML语言的数据结构

HTML语言的数据结构 引言 HTML&#xff08;超文本标记语言&#xff09;是构建网页的标准语言。尽管HTML本身不是一种编程语言&#xff0c;它为我们提供了一种结构化的信息表示方法&#xff0c;使得网页内容能够有序地展现给用户。HTML的核心在于其标记&#xff08;标签&#…...

怎么创建一个能在线测试php的html5网页?

代码示例&#xff1a; 一、搭建服务器环境 首先&#xff0c;你需要在服务器上搭建 PHP 运行环境。如果你使用的是 Linux 服务器&#xff0c;可以使用 Apache 或 Nginx 作为 Web 服务器&#xff0c;并安装 PHP 解释器。对于 Windows 服务器&#xff0c;可以使用 WAMP&#xff08…...

docker安装elk6.7.1-搜集nginx-json日志

docker安装elk6.7.1-搜集nginx-json日志 如果对运维课程感兴趣&#xff0c;可以在b站上、A站或csdn上搜索我的账号&#xff1a; 运维实战课程&#xff0c;可以关注我&#xff0c;学习更多免费的运维实战技术视频 0.规划 192.168.171.130 nginxfilebeat 192.168.171.131 …...

常见的社交媒体平台有哪些?

社交媒体平台有哪些&#xff1f;在跨境电商和全球营销的过程中&#xff0c;海外社交媒体平台是提高品牌曝光率的重要工具。为了有效管理多个平台的账户&#xff0c;并防止账户之间的关联问题&#xff0c;OKBrow指纹指纹浏览器凭借其强大的多账户管理、防关联技术和隐私保护功能…...

nslookup在内网渗透的使用

1. 什么是 nslookup&#xff1f; nslookup&#xff08;Name Server Lookup&#xff09;是一个用于查询 DNS&#xff08;域名系统&#xff09;记录的命令行工具。通过该工具&#xff0c;用户可以查询域名的解析结果&#xff0c;例如获取某个域名对应的 IP 地址或查找域名的相关记…...

Linux:修改用户名

Linux&#xff1a;修改用户名 0. 注意事项1.创建并切到临时用户tempuser2.更改用户名3.删除临时用户tempuser 更多内容&#xff1a;XiaoJ的知识星球 在Ubuntu系统中&#xff0c;更改用户名。 0. 注意事项 备份重要数据&#xff1a;在更改用户名之前&#xff0c;建议备份重要数…...

IP协议特性

在网络层中&#xff0c;最重要的协议就是IP协议&#xff0c;IP协议也有两个特性&#xff0c;即地址管理和路由选择。 1、地址管理 由于IPv4地址为4个字节&#xff0c;所以最多可以支持42亿个地址&#xff0c;但在现在&#xff0c;42亿明显不够用了。这就衍生出下面几个机制。…...

开发环境搭建-3:配置 nodejs 开发环境 (fnm+ node + pnpm)

在 WSL 环境中配置&#xff1a;WSL2 (2.3.26.0) Oracle Linux 8.7 官方镜像 node 官网&#xff1a;https://nodejs.org/zh-cn/download 点击【下载】&#xff0c;选择想要的 node 版本、操作系统、node 版本管理器、npm包管理器 根据下面代码提示依次执行对应代码即可 基本概…...

14_音乐播放服务_字典缓存避免重复加载

首先在游戏根入口下创建空节点 F2重命名为BGAudio 作为播放 背景音乐的对象 在BGAudio对象上挂载组件 AudioSource 关掉PlayOnAwake 因为我们需要通过代码来控制音效 音量大小设置为0.5 Ctrl d 再复制一份背景播放对象BGAudio 重命名为UIAudio 作为UI窗口操作的播放对象 创建…...

pgsql中处理数组类型字段

1、代码中存入和读取 需要使用自定义转换器 Slf4j public class ArrayTypeHandler extends BaseTypeHandler<List<String>> {Overridepublic void setNonNullParameter(PreparedStatement ps, int i, List<String> parameter, JdbcType jdbcType)throws SQL…...

新年好(Dijkstra+dfs/全排列)

1135. 新年好 - AcWing题库 思路&#xff1a; 1.先预处理出1,a,b,c,d,e到其他点的单源最短路&#xff0c;也就是进行6次Dijkstra 2.计算以1为起点的这6个数的全排列&#xff0c;哪种排列方式所得距离最小&#xff0c;也可以使用dfs 1.Dijkstradfs #define int long longusing …...

vscode导入模块不显示类型注解

目录结构&#xff1a; utils.py&#xff1a; import random def select_Jrandom(i:int, m:int) -> int:"""随机选择一个不等于 i 的整数"""j iwhile j i:j int(random.uniform(0, m))return jdef clip_alpha(alpha_j:float, H:float, L:f…...