有哪些网站可以学做糕点的/推广网站要注意什么

有哪些网站可以学做糕点的,推广网站要注意什么,wordpress扫码验证下载,福建省政府门户网站建设记录一下 CAT1 模块EC800 HTTP 使用后续遇到的问题 by 矜辰所致目录 前言一、一些功能的完善1.1 新的交互指令添加1.2 连不上网络处理 二、问题出现三、分析及解决3.1 定位问题3.2 问题分析与解决3.2.1 查看变量在内存中的位置 3.3 数据类型说明3.3.1 常用格式化输出符号…
记录一下 CAT1 模块EC800 HTTP 使用后续遇到的问题       by  矜辰所致

目录

  • 前言
  • 一、一些功能的完善
    • 1.1 新的交互指令添加
    • 1.2 连不上网络处理
  • 二、问题出现
  • 三、分析及解决
    • 3.1 定位问题
    • 3.2 问题分析与解决
      • 3.2.1 查看变量在内存中的位置
    • 3.3 数据类型说明
      • 3.3.1 常用格式化输出符号
      • 3.3.2 不同平台数据类型定义
  • 结语

前言

此前我写过一篇文章 CAT1模块 EC800M HTTP使用总结记录 详细讲述了,如何使用 EC800M HTTP协议 的应用。

在后续的过程中,根据客户的不同需求,应用有一定的改变,所以进行了一些定制的修改,同时也发现了以前留下的一个 bug , 觉得还是有必要来记录一下,这不是也太久没写文章了,都要生锈了。

所以本文就继续来说明一下CAT1模块 EC800M HTTP 应用的后续问题吧。

我是矜辰所致,全网同名,尽量用心写好每一系列文章,不浮夸,不将就,认真对待学知识的我们,矜辰所致,金石为开!

目录

  • 前言
  • 一、一些功能的完善
    • 1.1 新的交互指令添加
    • 1.2 连不上网络处理
  • 二、问题出现
  • 三、分析及解决
    • 3.1 定位问题
    • 3.2 问题分析与解决
      • 3.2.1 查看变量在内存中的位置
    • 3.3 数据类型说明
      • 3.3.1 常用格式化输出符号
      • 3.3.2 不同平台数据类型定义
  • 结语

一、一些功能的完善

在前面的使用文章中,我们主要的目的在于介绍 EC800M HTTP 的使用,对于正式使用的产品来说,有一些问题还是需要考虑到的。

1.1 新的交互指令添加

使用 HTTP 协议,客户端想要和服务器交换数据,也只能等到 HTTP POST 以后通过服务器返回的响应来进行交互。这个其实在上一篇文章已经讲到过,所以呢,如果是后续有和服务器数据交互的需求,也只能在 HTTP POST 以后来实现,那对于我们来说,都是在读取 HTTP 响应之后,通过 strstr 函数找到我们需要的数据进行处理,比如下面一段代码:

...
else if(!strcmp(cmd,"AT+QHTTPREAD=2\r\n")){printf("%s\r\n", EC800_RX_BUF);   //打印出响应用来参考char* position = strstr((char*)EC800_RX_BUF, "\"expectGear\":");//先找到expectGear 的位置if (position != NULL) {// Use sscanf to extract the integer value after "expectGear"sscanf(position + strlen("\"expectGear\":"), "%hd", &Http_set_mode);if((Http_set_mode > 0)&&(Http_set_mode < 5)&&(Http_set_mode != Value_Mode)) need_change = TRUE;// printf("Http_set_mode is %d\r\n",Http_set_mode);} else {printf("not found expectGear!!\r\n");}position = strstr((char*)EC800_RX_BUF, "\"voice\":");//先找到 voice 的位置if (position != NULL) {// Use sscanf to extract the integer value after "expectGear"sscanf(position + strlen("\"voice\":"), "%hhu", &Http_set_voice);// printf("Http_set_voice is %d\r\n",Http_set_voice);  if(Http_set_voice)//这里要关闭声音{Voice_close_state = TRUE;Voice_close_count = 0;}} else {}CLEAR_EC800_Buffer(EC800_RX_Data);return 0;}
...

这个问题说明一下即可,没什么难点,可能需要注意的点就是 HTTP 的响应数据量会稍微有点多,达到几百个字节,需要注意自己的串口缓存区的大小,这个在上一篇文章也有说明。但是这一块的代码有个问题确实也是本文要说明的地方,上看的代码已经是修改过的版本。

1.2 连不上网络处理

对于有些网络产品,它具备本地功能,所以在实际工作的时候要根据需求来判断它如果连不上网络是不停联网还是保持本地功能完善。
如果是必须要连上网络才能运行,很简单,可以开启看门口,然后在配网的过程中如果失败重试的时间长一点,那么就能够不停的自动复位。
如果是需要保证没有网络也要使得本地功能正常,然后设备自动定时连接网络,那么就需要考虑好配网失败重试的时间,超时返回标志位,不能等到看门狗自动复位。再在程序中根据配网成功或者失败的标志位进行判断需不需要再次连接网络。比如本次我们就是要修改成这种状态。

所以我们需要在配网操作的时候做一个超时,同时还需要返回状态值,所以我们把配网联网的状态定义一个结构体:

typedef struct
{uint8		Ec800_init_state;	uint8		Ec800_pdp_prepare_state;	uint8		Http_set_url_state;	
} cat1_state_struct;extern char IMEI[15];
extern cat1_state_struct My_4g_state;

上面的 3个状态分别对应 ec800_initec800_pdp_preparehttp_set_url 3个函数的状态,以前函数没有返回值,现在我们需要加上返回值:

uint8 ec800_init();
int Iot_SendCmd(const char* cmd, char* reply, int wait);
void Iot_SendNOCheck(char* cmd);uint8 ec800_pdp_prepare();
uint8 http_set_url(char *url);
void http_post_message(const char *message); 

这里使用 ec800_init 作为示例看一下超时的实现:

uint8 ec800_init()
{u16 cat1_timeout = 0;while(Iot_SendCmd(AT,"OK", 200)){HAL_Delay(1);cat1_timeout ++;if(cat1_timeout >= 2000){printf("uart false\r\n");return false;   }}cat1_timeout = 0;
...

上面这个原始的逻辑是有点问题的, cat1_timeout 应该是一个重试的次数,每次尝试会等待 200ms ,然后再等待 1ms,再次尝试,一共要尝试 2000 次,那么不考虑程序运行指令的时间来算,都需要 201* 2000 ms 才会超时,除了时间太久了,失败后1ms 就重试也不是那么合理。所以我们简单修改一下:

  while(Iot_SendCmd(AT,"OK", 200)){HAL_Delay(100);cat1_timeout ++;if(cat1_timeout >= 30){printf("uart false\r\n");return false;   }}cat1_timeout = 0;printf("\r\nuart ok\r\n");while(Iot_SendCmd(CPIN,"READY", 200)){HAL_Delay(100);cat1_timeout ++;if(cat1_timeout >= 30){return false;   }}

具体的可以根据自己看门狗的设定时间来确定每次 AT 指令的重试次数。

然后我们在具体使用的时候,先定义一个结构体变量,保存我们的联网状态,然后在开机的时候进行配网联网操作,不管成功与否,我们可以得到对应的状态,示例如下:

cat1_state_struct My_4g_state;...
//省略
...
int main(void)
{
//初始化省略MX_IWDG_Init();My_4g_state.Ec800_init_state = ec800_init();HAL_IWDG_Refresh(&hiwdg);printf("Ec800_init_state:%d\r\n",My_4g_state.Ec800_init_state);My_4g_state.Ec800_pdp_prepare_state = ec800_pdp_prepare();HAL_IWDG_Refresh(&hiwdg);printf("Ec800_pdp_prepare_state:%d\r\n",My_4g_state.Ec800_pdp_prepare_state);My_4g_state.Http_set_url_state = http_set_url(url);HAL_IWDG_Refresh(&hiwdg);printf("Http_set_url_state:%d\r\n",My_4g_state.Http_set_url_state);...//省略...//我这里使用了初始化状态确定是否需要 postif(My_4g_state.Ec800_init_state) http_post_message(message);while(1){...//定时发送,如果网络状态异常,就重新连接网络,再尝试发送if(send_count >= 180){send_count = 0;snprintf(message, sizeof(message), pm_message, IMEI,PM10_Data,PM25_Data,PM1_Data,Value_Mode);if(My_4g_state.Ec800_init_state) {http_post_message(message);}else {  //重新连接My_4g_state.Ec800_init_state = ec800_init();      HAL_IWDG_Refresh(&hiwdg);My_4g_state.Ec800_pdp_prepare_state = ec800_pdp_prepare();HAL_IWDG_Refresh(&hiwdg);My_4g_state.Http_set_url_state = http_set_url(url); HAL_IWDG_Refresh(&hiwdg);      if(My_4g_state.Ec800_init_state) http_post_message(message);}}...}
}

上面是设备初始化上电后的联网配置示例,上电先配网,然后读取一次数据进行上传,在主函数的 while 循环中,根据自己的需要的周期,定时的进行数据上传,或者根据 My_4g_state.Ec800_init_state 状态,进行重新配置网络操作。

整体来说就是这么一个流程,不复杂,但是用起来却出现了一个小 bug 。

二、问题出现

如果我们 SIM 卡正常,网络信号正常,我们会经历正常的初始化了,得到的My_4g_state3个成员变量都为1,然后他可以正常的进行 POST 操作,但是我测试的时候发现,设备还是会定期联网,但是奇怪的是,它能够正常的进行 POST 操作。

确定的问题是只要运行过了http_post_message函数 ,My_4g_state.Ec800_init_state 就会变成 0 ,如下图:

在这里插入图片描述

简单一想,在实际代码中,http_post_message函数里根本没有改变这个变量的值, 那么出这种问题极大概率的就是数据溢出,最开始想的是不是串口缓存数据溢出,尝试过加大串口缓冲区,没有用。测试下来发现这个 bug 只会改变 1个字节,所以期间采用了一个办法,就是在结构体成员变量上加上一个预留位置,如下图:

typedef struct
{uint8       Reserved_state;uint8		Ec800_init_state;	uint8		Ec800_pdp_prepare_state;	uint8		Http_set_url_state;	
} cat1_state_struct;

倒是能够解决,程序逻辑正常的跑,但是这是治标不治本的方式,还是存在 bug 。

三、分析及解决

3.1 定位问题

还是得进一步的分析问题,于是进一步的修改了一下 http_post_message 函数,在每次操作后把My_4g_state.Ec800_init_state 值打印出来,如下 :

void http_post_message(const char *message) {int length = strlen(message);char at_post[32];u16 cat1_timeout = 0;snprintf(at_post, sizeof(at_post), "AT+QHTTPPOST=%d,%d,%d\r\n", length, 5, 10);printf("five:%d\r\n",My_4g_state.Ec800_init_state);while(Iot_SendCmd(at_post,"CONNECT", 500)){HAL_Delay(100);cat1_timeout ++;if(cat1_timeout >= 10){return;   }}cat1_timeout = 0; printf("\r\nready to send post message!\r\n%s\r\n", message);printf("six:%d\r\n",My_4g_state.Ec800_init_state);while(Iot_SendCmd(message,"+QHTTPPOST:", 5000)){  // HAL_Delay(100);cat1_timeout ++;if(cat1_timeout >= 3){printf("http post wrong\r\n");return;   }}cat1_timeout = 0;printf("\r\nhttp post OK\r\n");printf("seven:%d\r\n",My_4g_state.Ec800_init_state);HAL_IWDG_Refresh(&hiwdg);while(Iot_SendCmd("AT+QHTTPREAD=2\r\n","+QHTTPREAD:", 2000)){HAL_Delay(100);cat1_timeout ++;if(cat1_timeout >= 5){printf("read wrong\r\n");return;   }}cat1_timeout = 0;printf("\r\nHTTPREAD OK\r\n");printf("eight:%d\r\n",My_4g_state.Ec800_init_state); 
}

测试结果如下:

在这里插入图片描述

通过上面测试,已经可以直接定位到云运行过while(Iot_SendCmd("AT+QHTTPREAD=2\r\n","+QHTTPREAD:", 2000)) 后,My_4g_state.Ec800_init_state 的值就变成了 0 ,我们看看上面这条语句会做什么工作,我只把 HTTPREAD 相关的部分代码截取出来:

int Iot_SendCmd(const char* cmd, char* reply, int wait)
{u8 i=0;char* rss_str;int rssi,res;CLEAR_EC800_Buffer(EC800_RX_Data);Uart3_sendBuffer((u8*)cmd,strlen(cmd));/*此处串口回的不止是一帧数据,所以使用 IDLE 中断不合适*/if ((!strcmp(reply,"+QHTTPREAD:"))||(!strcmp(reply,"+QHTTPPOST:"))){//读取和发送的处理,直接等一段时间HAL_Delay(1000);// 500 600 800 1000 一直加大   }/*另外的设置指令大多都是等待一个 OK 返回,属于一帧数据所以可以用 IDLE 中断*/else{...}EC800ReceiveState = false;if (!strcmp(reply,"+CSQ")){...}else if (strstr((char*)EC800_RX_BUF, reply)){  if (!strcmp(cmd,"AT+CGSN\r\n")){}else if(!strcmp(cmd,"AT+QHTTPREAD=2\r\n")){printf("%s\r\n", EC800_RX_BUF);   //打印出响应用来参考char* position = strstr((char*)EC800_RX_BUF, "\"expectGear\":");//先找到expectGear 的位置if (position != NULL) {// Use sscanf to extract the integer value after "expectGear"sscanf(position + strlen("\"expectGear\":"), "%d", &Http_set_mode);if((Http_set_mode > 0)&&(Http_set_mode < 5)&&(Http_set_mode != Value_Mode)) need_change = TRUE;} else {printf("not found expectGear!!\r\n");}CLEAR_EC800_Buffer(EC800_RX_Data);return 0;}CLEAR_EC800_Buffer(EC800_RX_Data);return 0;}return 1;  
}

从上面可以看到,在这个操作中我们只会改变变量 Http_set_modeneed_change 的值,但是 need_change 并不是每次都改变,所以基本上可以判断是 Http_set_mode 的值变化使得My_4g_state.Ec800_init_state 变化了。

3.2 问题分析与解决

那我们前文也说过,此类问题极大概率的就是数据溢出问题,这两个数据在内存中存放的地址应该是靠在一起的才会出现这种问题,为了更加直观的说明这个问题,我们可以查看一下他们在内存中存放的位置。

3.2.1 查看变量在内存中的位置

如何查看变量的存放位置?那就是查看编译过后的 .map 文件!

我们打开 .map 文件 搜索一下我们的变量,如下图:

在这里插入图片描述

果然他们是紧靠着的,他们在内存中如下图分部:

在这里插入图片描述

那我们回去看一下问题,Http_set_mode 我们定义的为一个字节的数据,怎么影响到了后面的数据,我们在出问题的地方有一条语句,注意看:

sscanf(position + strlen("\"expectGear\":"), "%d", &Http_set_mode);

expectGear 字符位置后面的数值,放到变量Http_set_mode 的地址,也就是 0x2000046d 位置处,放的数据类型为 %d 类型 !!!

%d 类型是几个字节? 在 32 位系统中,%d 通常表示 4 字节(32 位)的有符号整数(int 类型)。

所以问题我们已经确定了,就是因为这个sscanf函数中的 %d导致的,比如我们收到的是一个 2 ,我们知道 STM32 为小端模式,那么操作过后我们的内存中的数据会变成如下这样:

在这里插入图片描述

到这里,问题已经很明了了,我们没有注意数据类型,导致我们改变了存放在地址 0x20000470 处的My_4g_state.Ec800_init_state 变量的值。

对于这个问题,我们只需要把 %d改成 %hh , 就解决了这个问题了!如下:

sscanf(position + strlen("\"expectGear\":"), "%hhu", &Http_set_mode);

3.3 数据类型说明

那既然遇到了这个问题,在解决的过程中,我也发现有一些值得说明的地方,所以接下来就顺带做做一个笔记说明把。

3.3.1 常用格式化输出符号

首先,先来看一看我们常用的格式化输出符号,这里只需要记住这张表格就好了:

格式符含义对应数据类型位数(典型情况)
%d有符号十进制整数int32位(4字节)
%u无符号十进制整数unsigned int32位(4字节)
%hd有符号短整数short16位(2字节)
%hu无符号短整数unsigned short16位(2字节)
%ld有符号长整数long32/64位(平台相关)
%lu无符号长整数unsigned long32/64位(平台相关)
%lld有符号长长整数long long64位(8字节)
%llu无符号长长整数unsigned long long64位(8字节)
%hhd有符号单字节整数char8位(1字节)
%hhu无符号单字节整数unsigned char8位(1字节)
%f十进制浮点数float32位(4字节)
%lf十进制双精度浮点数double64位(8字节)
%c单个字符char8位(1字节)
%s字符串char[](以\0结尾)动态长度
%p指针地址任意指针类型32/64位(平台相关)

3.3.2 不同平台数据类型定义

对于本文遇到的问题,除了上面的解决办法,我们其实还可以修改一下Http_set_mode 的数据类型,如下:

在这里插入图片描述

这样处理的话其实也能够解决问题。但是我这里要说的一个问题是,我在修改的过程中,有把 Http_set_mode 定义为 u16 的数据类型,但是呢他还是占用 4 个字节,实际上这里就让我发现了另外一个问题,按理来说u16 类型我本意是定义为 16位 的数据。

于是查看了一下u16 的定义:

在这里插入图片描述

我第一印象是,确实是 4 个字节的,为什么会这么定义? 想了一下,这个头文件是在上次 51 单片机项目中复制过来的……

在 8 位的单片机中:

unsigned int 通常是16 位(2字节)
unsigned long 为 32 位
unsigned char 8位

所以这里我忽略了平台的变换,直接使用 8 位单片机上的数据类型定义,如果要在 32 位单片机上定义 16位数据类型 ,建议使用uint16_t(无符号) 和 int16_t(有符号),因为这是在标准 C 语言库文件 <stdint.h> 中定义的,在所有平台上都明确表示16位,可以避免因编译器差异导致的问题。

其实,即便我们真的记不得某一个数据类型到底占多少个字节,我们可以直接通过 sizeof 来判断,示例如下:

printf("Size: %d bytes\n", (int)sizeof(uint16_t)); 

在这里插入图片描述

结语

本文我们讲到的问题,是数据类型处理不当的问题,对数据类型的应用不够熟练严谨导致的数据覆盖。

我们通过问题,复习了一遍数据类型的一些基础知识,也说明了如何通过 .map 文件检查数据溢出或者覆盖问题。希望对大家以后的产品开发有一定的帮助。

好了,本文就到这里,谢谢大家!

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

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

相关文章

单纯形法之大M法

1. 问题背景与标准化 在求解某些线性规划问题时&#xff0c;往往难以直接找到初始的基本可行解。特别是当约束中存在等式或 “≥” 类型的不等式时&#xff0c;我们需要引入人工变量来构造一个初始可行解。 考虑如下标准形式问题&#xff08;假设为最大化问题&#xff09;&am…

Springboot集成Debezium监听postgresql变更

1.创建springboot项目引入pom <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>io.debezium</groupI…

报错 standard_init_linux.go:228: exec user process caused: exec format error

docker logs 容器名 报错&#xff1a; standard_init_linux.go:228: exec user process caused: exec format error 或者 standard_init_linux.go:228: exec user process caused: input/output error 排查思路 1、检查源镜像的框架是否正确&#xff0c;是否amd64&#x…

Go 代理爬虫

现在注册&#xff0c;还送15美金注册奖励金 --- 亮数据-网络IP代理及全网数据一站式服务商 使用代理服务器&#xff0c;通过 Colly、Goquery、Selenium 进行网络爬虫的基础示例程序 本仓库包含两个分支&#xff1a; basic 分支包含供 Go Proxy Servers 这篇文章改动的基础代码…

STM32实现智能温控系统(暖手宝):PID 算法 + DS18B20+OLED 显示,[学习 PID 优质项目]

一、项目概述 本文基于 STM32F103C8T6 单片机&#xff0c;设计了一个高精度温度控制系统。通过 DS18B20 采集温度&#xff0c;采用位置型 PID 算法控制 PWM 输出驱动 MOS 管加热Pi膜&#xff0c;配合 OLED 实时显示温度数据。系统可稳定将 PI 膜加热至 40℃&#xff0c;适用于…

从零开始:使用Luatools工具高效烧录Air780EPM核心板项目的完整指南

本文将深入讲解如何使用Luatools工具烧录一个具体的项目到Air780EPM开发板中。如何使用官方推荐的Luatools工具&#xff08;一款跨平台、命令行驱动的烧录利器&#xff09;&#xff0c;通过“环境配置→硬件连接→参数设置→一键烧录”四大步骤&#xff0c;帮助用户实现Air780E…

2024年认证杯SPSSPRO杯数学建模C题(第二阶段)云中的海盐全过程文档及程序

2024年认证杯SPSSPRO杯数学建模 C题 云中的海盐 原题再现&#xff1a; 巴黎气候协定提出的目标是&#xff1a;在2100年前&#xff0c;把全球平均气温相对于工业革命以前的气温升幅控制在不超过2摄氏度的水平&#xff0c;并为1.5摄氏度而努力。但事实上&#xff0c;许多之前的…

大疆上云api介绍

概述 目前对于 DJI 无人机接入第三方云平台,主要是基于 MSDK 开发定制 App,然后自己定义私有上云通信协议连接到云平台中。这样对于核心业务是开发云平台,无人机只是其中一个接入硬件设备的开发者来说,重新基于 MSDK 开发 App 工作量大、成本高,同时还需要花很多精力在无人…

云原生之开源遥测框架OpenTelemetry(在 Gin 框架中使用 OpenTelemetry 进行分布式追踪和监控)

文章目录 云原生之开源遥测框架OpenTelemetry背景什么是可观测性&#xff1f; 什么是 OpenTelemetry&#xff1f;Opentelemetry的主要优势有以下几点&#xff1a;理解分布式链路日志Spans分布式链路 在 Gin 框架中使用 OpenTelemetry 进行分布式追踪和监控0. 整体思路1. 初始化…

2.(vue3.x+vite)使用vue-router

前端技术社区总目录(订阅之前请先查看该博客) 效果预览 路由配置的“/”与“helloWorld”都可以访问到以下内容 http://10.11.0.87:4000/#/ http://10.11.0.87:4000/#/helloWorld 1:安装vue-router npm i vue-router 2:创建router文件 在src的目录下创建router文件夹…

VUE3 路由配置

1.下载 VueRouter 模块 在命令行中输入 yarn add vue-router 2.导⼊相关函数 在自己创建的router/index.js 文件中 import { createRouter, createWebHashHistory } from vue-router 3.创建路由实例 在自己创建的router/index.js 文件中 const theFirstRouter ()>{return…

NetMizer-日志管理系统-远程命令执行漏洞挖掘

漏洞描述&#xff1a;NetMizer 日志管理系统 cmd.php中存在远程命令执行漏洞&#xff0c;攻击者通过传入 cmd参数即可命令执行 1.fofa搜素语句 title"NetMizer 日志管理系统" 2.漏洞验证 网站页面 验证POC /data/manage/cmd.php?cmdid

Contactile三轴触觉传感器:多维力感赋能机器人抓取

在非结构化环境中&#xff0c;机器人对物体的精准抓取与操作始终面临巨大挑战。传统传感器因无法全面感知触觉参数&#xff08;如三维力、位移、摩擦&#xff09;&#xff0c;难以适应复杂多变的场景。Contactile推出的三轴触觉力传感器&#xff0c;通过仿生设计与创新光学技术…

OpenCV三维解算常用方法C++

如果标定过程是通过OpenCV张正友标定法实现的&#xff0c;得到的内参外参保存在.txt文件中是这样的形式&#xff1a; ① 内参intrinsics.txt&#xff1a; ② 外参extrinsics.txt&#xff1a; 那么可以通过如下方法读取.txt文件获取左右相机内外参&#xff0c;主要包括三维解算…

【实战案例】永洪vividime:精准赋能零售行业,实现数据洞察与业务增长

在零售食品行业变革加速、市场竞争白热化的背景下&#xff0c;XX集团作为休闲食品领域头部企业&#xff0c;面临消费趋势变化、宏观经济承压及业绩增长乏力的多重挑战。为破解增长困境&#xff0c;集团将“收入增长金额”确立为核心战略指标&#xff08;北极星指标&#xff09;…

面试题分享-多线程顺序打印奇偶数

目录 1.题目详情 2.解题思路 2.1.分析题目 2.2.解析思路 3.代码实现 4.运行结果 1.题目详情 昨天刷抖音&#xff0c;遇到一个面试题&#xff0c;描述如下&#xff1a; 请使用两个线程&#xff0c;分别顺序交替打印奇数和偶数&#xff0c;直到10为止。例如有两个线程&#…

模型 杜根定律

系列文章分享模型&#xff0c;了解更多&#x1f449; 模型_思维模型目录。信心>能力、行动导向、未来时态。 1 杜根定律的应用 1.1 公共政策博弈——底特律市长杜根的保险改革攻坚战 核心挑战&#xff1a;底特律市长Mike Duggan面临汽车保险费率畸高导致居民陷入贫困循环的…

关于在vscode中的Linux 0.11 应用程序项目的生成和运行

首先我们需要需要查看镜像文件 查看软盘镜像文件 floppyb.img 中的内容 在 VSCode 的“Terminal”菜单中选择“Run Build Task...”&#xff0c;会在 VSCode 的顶部中间位置弹出一个 可以执行的 Task 列表&#xff0c;选择其中的“打开 floppyb.img”后会使用 Floppy Editor …

使用CSS3实现炫酷的3D视差滚动效果

使用CSS3实现炫酷的3D视差滚动效果 这里写目录标题 使用CSS3实现炫酷的3D视差滚动效果项目概述核心技术实现1. 3D空间的创建2. 视差层级设置3. 动画效果实现流星动画月亮发光效果 技术难点与解决方案1. 层级重叠问题2. 性能优化3. 响应式适配 开发心得总结 项目概述 在这个项目…

【ESP32S3】esp32获取串口数据并通过http上传到前端

通过前面的学习&#xff08;前面没发过&#xff0c;因为其实就是跑它的demo&#xff09;了解到串口配置以及开启线程实现功能的工作流程&#xff0c;与此同时还有esp32作为STA节点&#xff0c;将数据通过http发送到服务器。 将这两者联合 其实是可以得到一个&#xff1a;esp32获…