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

STM32MP157-Linux输入设备应用编程-多点触摸屏编程

文章目录

  • 前言
  • 多点触摸屏
    • tslib库简介
    • tslib库移植
    • tslib库函数使用
      • 打开触摸屏设备
      • 配置触摸屏设备
      • 打开并配置触摸屏设备
      • 读取触摸屏设备
    • 多点触摸屏程序编写
      • 触点数据结构体定义
      • 事件定义
      • 计算触点数量
      • 判断单击、双击
      • 判断长按、移动
      • 判断放大、缩小
      • 外部调用
    • 代码流程图(草图)
    • 实现效果
  • 源代码(转载请注明出处)


前言

本篇分享:

Linux应用编程之多点触摸屏编程,识别用户在触摸屏上的操作,如:单击、双击、长按、移动、放大、缩小。

环境介绍:

系统:Linux
硬件:正点原子STM32MP157开发板


多点触摸屏

实现目标:识别用户在触摸屏上的操作,如:单击、双击、长按、移动、放大、缩小。

tslib库简介

触摸屏是现代电子设备中常见的输入方式之一,tslib库是一个软件工具,可以帮助开发者在Linux系统上方便地处理触摸屏的输入数据。

tslib库提供了一组API函数,可以让开发者轻松地获取触摸屏输入的坐标、压力等信息,并进行相应的处理。使用tslib库,开发者不需要直接与底层硬件交互,而是通过标准的接口进行操作,从而提高了代码的可移植性和可维护性。

除了常见的输入处理功能外,tslib库还提供了一些额外的功能,如校准、手势识别等,可以帮助开发者更好地适配不同类型的触摸屏设备。

总之,tslib库是一个非常实用的工具,可以方便地处理触摸屏输入数据,是开发Linux平台下触摸屏应用程序的重要组成部分。

tslib库移植

正点STM32MP157开发板出厂已移植(非广告!),需要请参考其他教程。

tslib官方网站:http://www.tslib.org/

tslib库函数使用

打开触摸屏设备

函数:

函数原型:
struct tsdev *ts_open(const char *dev_name, int nonblock)参数:
dev_name -- 触摸屏的设备节点
nonblock -- 是否以阻塞的方式打开,1为非阻塞,0为阻塞作用:
打开触摸屏设备,返回触摸屏设备句柄

配置触摸屏设备

函数:

函数原型:
int ts_config(struct tsdev *ts)参数:
ts -- 触摸屏设备句柄作用:
调用该函数对触摸屏进行配置

打开并配置触摸屏设备

函数(本项目使用):

函数原型:
struct tsdev *ts_setup(const char *dev_name, int nonblock)参数:
dev_name -- 触摸屏的设备节点,该参数设置为NULL时,ts_setup()函数内部会读取
TSLIB_TSDEVICE环境变量,获取该环境变量的内容以得知触摸屏的设备节点。
nonblock -- 是否以阻塞的方式打开,1为非阻塞,0为阻塞作用:
打开并配置触摸屏设备

读取触摸屏设备

函数:

函数原型:
int ts_read(struct tsdev *ts, struct ts_sample *samp, int nr)参数:
ts -- 触摸屏设备句柄
samp -- 保存触点信息
nr -- 对一个触摸点的采样数,设置为1即可作用:
读取触摸屏设备数据

struct ts_sample 结构体:

struct ts_sample {int x; //X 坐标int y; //Y 坐标unsigned int pressure; //按压力大小struct timeval tv; //时间
};

函数(本项目使用):

函数原型:
int ts_read_mt(struct tsdev *ts, struct ts_sample_mt **samp, int max_slots, int nr)参数:
ts -- 触摸屏设备句柄
samp -- 保存触点信息
max_slots -- 触摸屏支持最大触点数
nr -- 对一个触摸点的采样数,设置为1即可作用:
读取触摸屏设备数据,一次读取多个触点数据

struct ts_sample_mt结构体(主要用到的):

struct ts_sample_mt {int x; //触点X坐标int y; //触点Y坐标unsigned int pressure; //按压力大小 255/0int slot; //触摸点slotint tracking_id; //ID......struct timeval tv; //时间戳short pen_down; //BTN_TOUCH 的状态short valid; //触摸点数据是否发生更新
};

多点触摸屏程序编写

本项目编写程序要实现触摸屏数据的非阻塞读取和判断,并且外部调用该函数时能判断用户执行了怎样的操作。
当用户操作为(单击/双击/长按)时,外部能获取触点的坐标数据
当用户操作为(移动)时,外部能获取触点坐标数据以及坐标偏移量
当用户操作位(放大/缩小)时,外部能获取两指间中心点坐标以及间距的偏移量

代码大致的流程是:
以非阻塞方式打开触摸屏设备->读取触摸屏设备数据->判断触点数量->根据触点数量不同执行不同操作

外部调用的大致流程是:
初始化触摸屏设备->循环执行触点数据处理函数并传入外部处理函数->在用户操作后在外部处理函数对用户的行为进行判断进而进行相关操作

触点数据结构体定义

结构体内数据包括触摸事件、单个触点数据结构体以及多触点数据结构体。

typedef struct one_clickStruct
{int x;          /*当前触点x坐标*/int y;          /*当前触点y坐标*/int offset_x;   /*x坐标偏移量*/int offset_y;   /*y坐标偏移量*/
}one_clickStruct;typedef struct more_clickStruct
{int centre_x;       /*中心点x坐标*/int centre_y;       /*中心点y坐标*/int offset_distance;/*两点间距离偏移量*/
}more_clickStruct;typedef struct touch_struct
{uint16_t event;                 /*触摸事件*/one_clickStruct one_clickData;  /*单个触点数据*/more_clickStruct more_clickData;/*多触点数据*/
}touch_struct;

事件定义

使用不同位上的1代表不同事件。

#define TOUCH_CLICK         0X0001  /*单击事件*/
#define TOUCH_DOUBLECLICK   0X0002  /*双击事件*/
#define TOUCH_LONGPRESS     0X0004  /*长按事件*/
#define TOUCH_LOOSE         0X0008  /*长按松开事件*/
#define TOUCH_MOVE          0X0010  /*移动事件*/
#define TOUCH_MAGNIFY       0X0020  /*放大事件*/
#define TOUCH_SHRINK        0X0040  /*缩小事件*

计算触点数量

在程序中创建一个压力数组保存各个触点的压力数据,当触点数据更新时,将该触点压力数据保存至数组对应位置。再通过判断该数组的值来确定当前的触点数量。

代码:

/*保存所有触点压力大小(255按下/0松开)*/
static int pressure_data[5] = {0};     /*读取触摸屏数据*/
ret = ts_read_mt(ts, &mt_ptr, max_slots, 1);
/*如果读取到数据*/
if (0 < ret) 
{/*保存触点压力数据*/for(i = 0; i < max_slots; i++) {if(mt_ptr[i].valid) {pressure_data[i] = mt_ptr[i].pressure;}}/*计算触点数量*/finger_num = 0;for(i = 0; i < max_slots; i++) {if(pressure_data[i] == 255) {finger_num++;}}
}

判断单击、双击

思路:

大致的判断依据是在用户点击并离开屏幕后的200ms内点击的次数(包括这一次,即点击再离开后200ms内无再次点击为单击操作,若再次点击则为双击操作)。

大致实现步骤:

在用户点击离开时若click_num为0则记录下当前时间戳(触点结构体中有),使click_num++。在外部(这个外部是指触点数据处理函数内,读取触点数据判断外)循环获取当前时间戳,若间隔超过200ms时click_num依然为1则为单击,200ms内click_num>1则为双击。

代码:

/*判断单击/双击:点击次数大于0,并且触点状态为0时继续判断*/
if(click_num > 0 && touch_statue == 0)
{/*获取时间戳*/struct timeval tv;gettimeofday(&tv, NULL);/*按下时间小于200ms时不断判断click_num数值*/if(((tv.tv_sec - sec_click) * 1000000 + tv.tv_usec - usec_click < 200000)){/*双击*/if(click_num > 1){/*次数清零*/click_num = 0;/*双击事件*/touch_data->event |= TOUCH_DOUBLECLICK;/*调用外部事件处理函数*/touch_handle(touch_data);/*事件位清零*/touch_data->event ^= TOUCH_DOUBLECLICK;}}/*超过200ms && click_num==1为单击*/else{/*次数清零*/click_num = 0;/*单击事件*/touch_data->event |= TOUCH_CLICK;/*调用外部事件处理函数*/touch_handle(touch_data);/*事件位清零*/touch_data->event ^= TOUCH_CLICK;}
}

判断长按、移动

思路:

长按的判断:当用户点击且未离开屏幕时长达500ms即为长按。
移动的判断:触点坐标发生改变则为移动。

大致实现步骤:

在用户按下时记录当前时间戳,在外部(这个外部是指触点数据处理函数内,读取触点数据判断外)循环读取当前时间戳,判断时间间隔是否大于500ms,是则为长按。
用户按下后记录下当前触点坐标和触点数量,若触点数量为1、触点BTN_TOUCH状态为-1(移动、除第一触点外新增触点)、且触点坐标发生改变则为移动。

判断长按代码:

/*判断长按:当一个手指按下,并且触点状态为0时继续判断按下时长是否满足长按标准*/
if((finger_num == 1) && (touch_statue == 0))
{/*获取时间戳*/struct timeval tv;gettimeofday(&tv, NULL);/*按下时间大于500ms小于3s判断为长按*/if(((tv.tv_sec - sec_press) * 1000000 + tv.tv_usec - usec_press > 500000) && (tv.tv_sec - sec_press < 3)){/*长按事件*/touch_data->event |= TOUCH_LONGPRESS;/*调用外部事件处理函数*/touch_handle(touch_data);/*事件位清零*/touch_data->event ^= TOUCH_LONGPRESS;/*当前状态为长按*/touch_statue |= TOUCH_LONGPRESS;}
}

判断移动代码:

/*读取触摸屏数据*/
ret = ts_read_mt(ts, &mt_ptr, max_slots, 1);
/*如果读取到数据*/
if (0 < ret) 
{/*保存触点压力数据*/.../*计算触点数量*/.../*如果触点数量等于1:移动/长按*/else if(finger_num == 1){   /*用队列保存最新两个触点下标*/for(i = 0; i < max_slots; i++) {if(mt_ptr[i].valid) {/*触点状态为触点按下:首个触点*/if(mt_ptr[i].pen_down == 1){touch_data->one_clickData.x = mt_ptr[i].x;touch_data->one_clickData.y = mt_ptr[i].y;sec_press = mt_ptr[i].tv.tv_sec; usec_press = mt_ptr[i].tv.tv_usec; x_old = mt_ptr[i].x;y_old = mt_ptr[i].y;}/*触点状态为触点离开:多指变单指*/else if(mt_ptr[i].pressure == 0){/*坐标清零:单指->多指->单指*/x_old = 0;}/*触点状态为移动*/else if(mt_ptr[i].pen_down == -1){/*如果上次触点坐标不为0*/if(x_old != 0){/*保存坐标和偏移量*/touch_data->one_clickData.x = mt_ptr[i].x;touch_data->one_clickData.y = mt_ptr[i].y;touch_data->one_clickData.offset_x = mt_ptr[i].x - x_old;touch_data->one_clickData.offset_y = mt_ptr[i].y - y_old;/*移动事件*/touch_data->event |= TOUCH_MOVE;/*调用外部事件处理函数*/touch_handle(touch_data);/*事件位清零*/touch_data->event ^= TOUCH_MOVE;}/*当前状态为移动*/touch_statue |= TOUCH_MOVE;x_old = mt_ptr[i].x;y_old = mt_ptr[i].y;}}}}
}

判断放大、缩小

思路:

用户执行放大、缩小操作时,根据俩触点坐标计算两点间距离,保存该值,在下一次触点坐标变化时,根据判断该值是增大还是减小决定用户操作时放大或缩小。

大致实现步骤:

用户执行放大或缩小操作时,可能是两指也可能是多指,这时候需要用一个队列来存储最新变化的两个触点的数据。若上次间距不为0,则根据这两个触点的数据来进行放大或缩小的判断,并得到两次间距的偏移量和两点间中心坐标;若为0则保存当前两点间间距。若用来控制放大或缩小的两指发生变化,则重置上次间距为0。

判断放大、缩小代码:

/*读取触摸屏数据*/
ret = ts_read_mt(ts, &mt_ptr, max_slots, 1);
/*如果读取到数据*/
if (0 < ret) 
{/*保存触点压力数据*/.../*计算触点数量*/.../*如果触点数量大于1:放大/缩小*/if(finger_num > 1){/*用队列保存最新触点下标*/for(i = 0; i < max_slots; i++) {if(mt_ptr[i].valid && (i != click_index_new[0]) && (i != click_index_new[1])) {click_index_new[0] = click_index_new[1];click_index_new[1] = i;}}/*当前两触点下标与上次两触点下标相同:多指接触时用最新移动的两个触点作为判断*/if((click_index_new[0] == click_index_old[0] || click_index_new[0] == click_index_old[1]) && (click_index_new[1] == click_index_old[0] || click_index_new[1] == click_index_old[1])){/*计算两点间距离*/distance_new = sqrt(pow(fabs(mt_ptr[click_index_new[0]].y-mt_ptr[click_index_new[1]].y),2)+                                    pow(fabs(mt_ptr[click_index_new[0]].x-mt_ptr[click_index_new[1]].x),2));/*如果上次两指间距离不为0*/if(distance_old != 0){/*判断距离如何变化*/if(distance_new > distance_old){/*放大事件*/touch_data->event |= TOUCH_MAGNIFY;/*调用外部事件处理函数*/touch_handle(touch_data);/*事件位清零*/touch_data->event ^= TOUCH_MAGNIFY;/*当前状态为放大*/touch_statue |= TOUCH_MAGNIFY;}else{/*缩小事件*/touch_data->event |= TOUCH_SHRINK;/*调用外部事件处理函数*/touch_handle(touch_data);/*事件位清零*/touch_data->event ^= TOUCH_SHRINK;/*当前状态为缩小*/touch_statue |= TOUCH_SHRINK;}/*保存中心点坐标、两点间距离偏移量*/touch_data->more_clickData.centre_x = fabs(mt_ptr[click_index_new[0]].x-mt_ptr[click_index_new[1]].x)/2;touch_data->more_clickData.centre_y = fabs(mt_ptr[click_index_new[0]].y-mt_ptr[click_index_new[1]].y)/2;touch_data->more_clickData.offset_distance = fabs(distance_new - distance_old);}/*保存当前两指间距离*/distance_old = distance_new;}/*当前两触点下标与上次两触点下标不同*/else{click_index_old[0] = click_index_new[0];click_index_old[1] = click_index_new[1];distance_old = 0;}  } 
}

外部调用

在外部执行触点数据处理函数时需要传递一个函数地址(函数名)作为参数,以便在处理函数内部回调传入的函数。

初始化以及释放函数:

/*触摸屏初始化*/
void touch_init(void);
/*触摸屏释放*/
void touch_free(void);

触点数据处理函数:

/*外部调用接口函数*/
int touch_process(touch_opt_handle_t handle);

函数指针结构定义:

/*指向外部处理函数指针结构定义*/
typedef void (*touch_opt_handle_t)(touch_struct *touch_data);
结构名为touch_opt_handle_t,参数为触点数据结构体指针。

外部调用示例:

void touch_event_handler(touch_struct *touch_data)
{uint16_t m_event = touch_data->event;/*单击*/if(0 != (m_event & TOUCH_CLICK)){printf("操作:单击,坐标:(%d,%d)\n",touch_data->one_clickData.x,touch_data->one_clickData.y);}/*双击*/else if(0 != (m_event & TOUCH_DOUBLECLICK)){printf("操作:双击,坐标:(%d,%d)\n",touch_data->one_clickData.x,touch_data->one_clickData.y);}/*长按*/else if(0 != (m_event & TOUCH_LONGPRESS)){printf("操作:长按,坐标:(%d,%d)\n",touch_data->one_clickData.x,touch_data->one_clickData.y);}/*长按松开*/else if(0 != (m_event & TOUCH_LOOSE)){printf("操作:长按松开,坐标:(%d,%d)\n",touch_data->one_clickData.x,touch_data->one_clickData.y);}/*移动*/else if(0 != (m_event & TOUCH_MOVE)){printf("操作:移动,坐标:(%d,%d),坐标偏移:(%d,%d)\n",touch_data->one_clickData.x,touch_data->one_clickData.y,touch_data->one_clickData.offset_x,touch_data->one_clickData.offset_y);}/*放大*/else if(0 != (m_event & TOUCH_MAGNIFY)){printf("操作:放大,中心坐标:(%d,%d),距离偏移:%d\n",touch_data->more_clickData.centre_x,touch_data->more_clickData.centre_y,touch_data->more_clickData.offset_distance);}/*缩小*/else if(0 != (m_event & TOUCH_SHRINK)){printf("操作:缩小,中心坐标:(%d,%d),距离偏移:%d\n",touch_data->more_clickData.centre_x,touch_data->more_clickData.centre_y,touch_data->more_clickData.offset_distance);}
}void *touch_thread(void *arg)
{while(1){touch_process(touch_event_handler);}
}int main()
{pthread_t pid;/*创建屏幕数据处理线程*/pthread_create(&pid,NULL,touch_thread,NULL);/*分离线程*/pthread_detach(pid);/*初始化*/touch_init();while(1){sleep(1);}/*释放*/touch_free();
}

代码流程图(草图)

在这里插入图片描述

实现效果

单击、双击:
在这里插入图片描述

长按、长按松开:
在这里插入图片描述

移动:
在这里插入图片描述

放大、缩小:

在这里插入图片描述


源代码(转载请注明出处)

在这里插入图片描述

相关文章:

STM32MP157-Linux输入设备应用编程-多点触摸屏编程

文章目录前言多点触摸屏tslib库简介tslib库移植tslib库函数使用打开触摸屏设备配置触摸屏设备打开并配置触摸屏设备读取触摸屏设备多点触摸屏程序编写触点数据结构体定义事件定义计算触点数量判断单击、双击判断长按、移动判断放大、缩小外部调用代码流程图&#xff08;草图&am…...

mybatis-plus的一般实现过程(超详细)

MyBatis-Plus 是 MyBatis 的增强工具&#xff0c;在 MyBatis 的基础上提供了许多实用的功能&#xff0c;如分页查询、条件构造器、自动填充等。下面是 MyBatis-Plus 的完整代码实现流程&#xff1a; ①、引入 MyBatis-Plus 依赖 在 Maven 中&#xff0c;可以通过以下方式引入 …...

Spark(5):RDD概述

目录 0. 相关文章链接 1. 什么是RDD 2. RDD核心属性 3. 执行原理 0. 相关文章链接 Spark文章汇总 1. 什么是RDD RDD&#xff08;Resilient Distributed Dataset&#xff09;叫做弹性分布式数据集&#xff0c;是 Spark 中最基本的数据处理模型。代码中是一个抽象类&#x…...

面向对象 - 继承

Hello , 各位同学朋友大家好啊, 今天给大家分享的技术呢, 是面向对象三大特征之一的继承&#xff0c;我们今天主要按照以下几个点, 展开继承的讲解。目录 :* 继承的介绍* 继承的好处和弊端* 继承中成员访问特点 - 成员变量* 继承中成员访问特点 - 成员方法* 方法重写* 继承中成…...

计算机网络的166个概念你知道几个 第十二部分

计算机网络安全安全通信的四大要素&#xff1a;机密性、保温完整性、端点鉴别和运行安全性。机密性&#xff1a;报文需要在一定程度上进行加密&#xff0c;用来防止窃听者截取报文。报文完整性&#xff1a;在报文传输过程中&#xff0c;需要确保报文的内容不会发生改变。端点鉴…...

【RabbitMQ】RabbitMQ各版本的兼容性与技术支持时限

今天在研究RabbitMQ的监控时&#xff0c;发现这个消息队列软件的版本真的很令人崩溃&#xff0c;版本众多&#xff0c;且组件之间还存在版本的兼容性&#xff0c;此外各个组件还对操作系统存在兼容性关系。为了帮大家节省一些查阅官方文档的时间&#xff0c;我把官方文档里面涉…...

【Git】P5 Git 远程仓库(3)pull 发生冲突

pull 发生冲突冲突在什么场景下发生&#xff1f;为什么要先 pull 再 push构建一个冲突场景初始开始操作&#xff1a;程序员2&#xff1a;程序员1&#xff1a;程序员2&#xff1a;发生冲突&#xff1a;查看冲突&#xff1a;解决冲突&#xff1a;冲突在什么场景下发生&#xff1f…...

关于世界坐标系,相机坐标系,图像坐标系,像素坐标系的一些理解

关于世界坐标系&#xff0c;相机坐标系&#xff0c;图像坐标系&#xff0c;像素坐标系的一些理解前言一、各坐标系的含义二、坐标系转换1.世界坐标系与相机坐标系&#xff08;旋转与平移&#xff09;2.相机坐标系与图像坐标系&#xff08;透视&#xff09;3.图像坐标系与像素坐…...

企业防护ddos的注意事项,你知道吗?

DDoS&#xff0c;分布式拒绝服务攻击&#xff0c;是指处于不同位置的多个攻击者同时向一个或数个目标发动攻击&#xff0c;或者一个攻击者控制了位于不同位置的多台机器并利用这些机器对受害者同时实施攻击。在当下&#xff0c;DDoS 攻击是非常常见的一种攻击方式&#xff0c;大…...

RocketMQ如何测试

RocketMQ如何测试MQ简介RocketMQRocketMQ测试点MQ简介 MQ&#xff1a;Message Queue&#xff0c;即消息队列&#xff0c;是一种应用程序之间的消息通信&#xff0c;简单理解就是A服务不断的往队列里发布信息&#xff0c;另一服务B从队列中读取消息并执行处理&#xff0c;消息发…...

SpringBoot中的bean注入方式和原理介绍

Spring Boot是一个非常流行的Java框架&#xff0c;它可以帮助开发者快速地构建高效、健壮的应用程序。其中一个重要的功能就是依赖注入&#xff0c;也就是将一个对象注入到另一个对象中&#xff0c;以便它们可以相互协作。在Spring Boot中&#xff0c;依赖注入是通过bean实现的…...

ESP32设备驱动-RFID-RC522模块驱动

RFID-RC522模块驱动 文章目录 RFID-RC522模块驱动1、RFID-RC522介绍2、硬件准备3、软件准备4、驱动实现1、RFID-RC522介绍 基于 NXP 的 MFRC522 IC 的 RC522 RFID 模块通常带有一个 RFID 卡标签和具有 1KB 内存的密钥卡标签。 最重要的是,它可以写一个标签,这样你就可以在里…...

SMETA认证有些客户是需要做窗口期的

【SMETA认证有些客户是需要做窗口期的】SMETA审核是常见的社会责任审核标准之一&#xff0c;中文全称为“Sedex 会员道德贸易审核”&#xff0c;英文为“Sedex Members Ethical Trade Audit”. SEDEX 官网&#xff1a;网页链接Sedex 作为目前市场流行的CSR审核标准&#xff0c;…...

面向对象设计模式:创建型模式之原型模式

文章目录一、引入二、代理模式&#xff0c;Prototype Pattern2.1 Intent 意图2.2 Applicability 适用性2.3 类图2.4 应用实例&#xff1a;使用下划线或消息框展示字符串2.4 应用实例&#xff1a;JDK java.lang.Object java.lang.Cloneable一、引入 二、代理模式&#xff0c;Pr…...

三维重建(单目、双目、多目、点云、SFM、SLAM)

1 相机几何与标定1.1 相机模型中的坐标系1.2 四种坐标系之间的转换1.3 相机内参1.4 相机标定2 单目三维重建2.1 NeuralRecon三维重建定义 在计算机视觉中, 三维重建是指根据单视图或者多视图的图像重建三维信息的过程. 由于单视频的信息不完全,因此三维重建需要利用经验知识. 而…...

Java中的final和权限修饰符

目录 final 常量 细节&#xff1a; 权限修饰符 Java权限修饰符用于控制类、方法、变量的访问范围。Java中有四种权限修饰符&#xff1a; 权限修饰符的使用场景&#xff1a; final 方法 表明该方法是最终方法&#xff0c;不能被重写。类 表明该类是最终类&#xff0c;不能被继…...

MySQL的基本语句(SELECT型)

基本MySQL语句SELECTSELECT FROM 列的别名去除重复行空值着重号算术运算符加法( )减法( - )乘法( * )除法&#xff08; / 或DIV)求模&#xff08; % 或MOD)比较运算符等于&#xff08; &#xff09;安全等于&#xff08; <> &#xff09;不等于&#xff08; ! 或 <…...

日志服务搭建-ES-FileBeat-Kibana

1次订单量突增问题&#xff0c;导致了有几个数据没有录库&#xff0c;但是确有支付的记录&#xff0c;啥玩意&#xff0c;还能有这个操作&#xff0c;组内安排问题定位&#xff0c;解决&#xff0c;一看打出来的日志&#xff0c;只有支付有&#xff0c;生成订单这边没有&#x…...

大数据架构设计与数据计算流程

大数据架构设计Hadoop有3个核心组件&#xff1a;分布式文件系统HDFS&#xff1b;分布式运算编程框架MapReduce&#xff1b;分布式资源调度平台YARN。HBase&#xff0c;Hadoop dataBase&#xff0c;基于HDFS的NoSQL数据库&#xff0c;面向列式的内存存储&#xff0c;定期将内存数…...

207. 课程表

207. 课程表https://leetcode.cn/problems/course-schedule/ 难度中等1526 你这个学期必须选修 numCourses 门课程&#xff0c;记为 0 到 numCourses - 1 。 在选修某些课程之前需要一些先修课程。 先修课程按数组 prerequisites 给出&#xff0c;其中 prerequisites[i] [a…...

2023-03-08 mysql列存储数据库-查询执行过程分析

摘要: 在mysql的sql层和存储引擎的交互模式中, 存储引擎实现handler接口, 由SQL层负责调用接口, 所以执行的过程可以看作是在sql层中, innodb仅提供接口。 但是在mysql列存储引擎中, TMD直接替换掉了sql层的执行接口,并且将sql层的查询树转换成了自己的一套查询树, 然后根据…...

各种激活函数的计算公式、图像以及实现代码

激活函数已经成为神经网络中非常重要的一部分&#xff0c;随着各种类型的神经网络模型被人们开发出来&#xff0c;各种激活函数也应运而生&#xff0c;在不同的场景中&#xff0c;取得良好的效果。本文跟据著名的YOLO系列目标检测模型的源码 AlexeyAB Darknet&#xff0c;整理出…...

ArangoDB

介绍 ArangoDB 是一个原生的多模型开源数据库&#xff0c;具有灵活的文档、图形和键值数据模型。使用方便的类似 SQL 的查询语言或 JavaScript 扩展构建高性能应用程序。主要特点 在集群上安装 ArangoDB —— 安装简单灵活的数据建模&#xff1a;数据建模为键值对、文档或图表的…...

MySQL8.0Linux安装及主从的搭建

MySQL8.0Linux安装教程 下载并安装 需要说明的一点是我使用的是SSH secure shell Client连接linux系统的&#xff0c;它的用法和命令窗口差不多。界面如图&#xff1a;一样的使用Linux命令操作。 话不多说 第一步&#xff1a; 1&#xff09;、切换到 /usr/local下 cd /usr/…...

苹果新专利实现无线技术传输睡眠数据,蓝牙在智能家居中的应用

苹果于 2017 年 5 月收购了芬兰科技公司 Beddit&#xff0c;只是在过去 6 年时间里并没有太大的动作。根据美国商标和专利局本周公示的清单&#xff0c;苹果获得了一项 Beddit 相关的技术专利。 根据专利描述&#xff0c;苹果使用一根或者多根天线&#xff0c;利用电磁辐射的…...

银行数字化转型导师坚鹏:数字化转型为什么需要致良知与知行合一

在银行数字化转型过程中&#xff0c;特别需要致良知与知行合一哲学思想的指导。 知中有行&#xff0c;行中有知&#xff1b;行极而知&#xff0c;知极而行&#xff1b;知行无端&#xff0c;知行无始。知与行是一件事&#xff0c;做事与培养本体&#xff08;修心&#xff09;也是…...

Web前端学习:章三 -- JavaScript预热(二)

六五&#xff1a;作用域与function function&#xff1a;函数&#xff0c;不是数学上的函数&#xff0c;与写代码有关 JS中的函数&#xff1a;运用它&#xff0c;起个名字&#xff0c;然后对函数进行调用&#xff0c;即可将函数中的内容执行一遍 1、function 最基本的作用域…...

Excel绘制数据对比表格-表格可视化

Word中生成的表格一般比较单调&#xff0c;若一组数据存在对比的情况时&#xff0c;读者/审稿人难以直接通过详细对比数据来分析&#xff0c;此时若可以将该组数据可视化来对比则为好&#xff0c;Excel则可实现该功能。 关于有些期刊需要提供表格中的数据便于复制等情况时&…...

究竟是谁负了谁,来自底层测试的2022年终总结

前言 说实话坐在椅子前&#xff0c;都想好了&#xff0c;该怎么去写&#xff0c;甚至感觉有好多要写的&#xff0c;但是当我坐在椅子上时&#xff0c;却不知道该怎么开头了&#xff0c;不知道是不是紧张&#xff1f;还是不舍&#xff1f;难道还没有跟过去挥手告别的勇气吗&…...

C++——IO流

目录 C语言的输入与输出 流是什么 CIO流 C标准IO流 C文件IO流 二进制读写 文本读写 stringstream的简单介绍 C语言的输入与输出 C语言中我们用到的最频繁的输入输出方式就是scanf ()与printf()。 scanf(): 从标准输入设备(键 盘)读取数据&#xff0c;并将值存放在变量中。…...