物联网中的ESP8266该这么用!
🙌秋名山码民的主页
😂oi退役选手,Java、大数据、单片机、IoT均有所涉猎,热爱技术,技术无罪
🎉欢迎关注🔎点赞👍收藏⭐️留言📝
获取源码,添加WX
目录
- 1. 前言
- 2. 概述esp8266
- 3. AT命令来控制模块
- 4. MQTT协议的概述
- 5. 示例
- 最后
1. 前言
在学习物联网的过程中,大家首先想到的通信应该就是蓝牙和wifi了,而wifi中又属esp8266比较出名,包括esp32的快速崛起也离不开起本身内置wife和蓝牙,这个模块本身可以连接路由器,也可以作为热点让你的手机来连接他。
本文主要从以下几个方面来进行讲解:
- 简单概述esp8266
- 搞定其AT指令集
- MQTT协议的概述
- 示例
2. 概述esp8266
ESP8266是一款以太网控制器芯片,由乐鑫科技(Espressif Systems)推出。它是一种低成本、高性能的Wi-Fi模块,广泛应用于物联网和嵌入式系统领域。

- 完整的WIFE网络解决方案,可独立运行,也可作为模块从动装置搭载到其他soc
- ESP8266模块内部集成了Wi-Fi无线通信功能,支持802.11b/g/n标准,可以连接到无线网络并进行数据传输。它通过串口与主控设备通信,并提供了AT指令集,简化了与主控设备的交互
- 可以采用Arduino IDE、MicroPython、NodeMCU等多种开发环境
- ESP8266具有良好的可扩展性,可以通过外部Flash存储器扩展其储存容量,支持OTA(Over-The-Air)固件升级
- ESP8266 RTOS SDK,支持FreeRTOS操作系统
具体参数:


硬件接口介绍:

-
UART接口:UART(通用异步收发传输器)接口是ESP8266与其他设备进行串行通信的主要接口,它可通过RX和TX引脚连接到其他设备。通过UART接口,可以实现与计算机、传感器、其他微控制器等设备的数据收发和控制。
-
GPIO口:ESP8266具有多个GPIO(通用输入/输出)口,用于与其他外围设备进行交互。GPIO口支持数字输入输出和PWM功能,可以通过编程来控制各种外设,如LED灯、继电器、开关等。
-
I2C接口:I2C(Inter-Integrated Circuit)接口是一种串行通信接口,可以连接多个设备,使用两根线(SDA和SCL)实现数据传输。ESP8266通过I2C接口可以与其他I2C设备通信,如传感器、显示屏等。
-
SPI接口:SPI(Serial Peripheral Interface)接口也是一种串行通信接口,可以连接多个设备,使用四根线(MISO、MOSI、SCK和SS)实现数据传输。ESP8266通过SPI接口可以与其他SPI设备通信,如Flash存储器、LCD显示屏等。
-
ADC接口:ESP8266内部集成了一个ADC(模数转换器),用于将模拟信号转换为数字信号。ADC接口可以连接到传感器等模拟设备,读取模拟值并将其转换为数字数据。
-
PWM接口:ESP8266的GPIO口支持PWM(脉冲宽度调制)功能,可用于控制电机、灯光等外设的亮度和速度。
-
SDIO接口:SDIO(Secure Digital Input Output)接口是一种高速的串行数据接口,常用于SD卡和MMC卡的读写操作。ESP8266通过SDIO接口可以连接到SD卡或MMC卡,实现数据存储和读取。
3. AT命令来控制模块
esp8266按照乐鑫官方的指令有上百条,但是常用的就10来条,下面我列举一些,其他的读者若需要可以下载乐鑫的用户手册查看。
- AT:测试ESP8266模块是否在线,并返回“OK”表示模块正常工作。
- AT+RST:重置ESP8266模块,并返回“ready”表示模块已经准备好。
- AT+CWMODE=:设置ESP8266的工作模式,其中参数取值为1、2或3,分别对应STA模式、AP模式和STA+AP模式。
- AT+CWJAP=,:连接到指定的Wi-Fi网络,其中和分别为需要连接的Wi-Fi网络名称和密码。该指令执行成功后,ESP8266会自动获取IP地址。
- AT+CIFSR:获取ESP8266当前IP地址。
- AT+CIPMUX=:设置ESP8266的多连接模式,其中参数取值为0或1,分别表示单连接模式和多连接模式。
- AT+CIPSTART=,,:建立TCP或UDP连接,其中参数为“TCP”或“UDP”,参数为连接目标IP地址,参数为连接目标端口号。
- AT+CIPSEND=:设置ESP8266发送数据的长度,其中参数为待发送数据的长度,发送数据时需先执行该指令。
- AT+CIPCLOSE:关闭ESP8266当前连接。
记得把端口打开:Windows打开特定端口
使用的调试助手为野火多功能调试助手

AT参考
4. MQTT协议的概述
MQTT(Message Queuing Telemetry Transport)是一种轻量级的、基于发布/订阅模型的消息传输协议,适用于物联网和移动应用等场景,他们之间的关系大概就像下面这张图一样:

具体协议介绍,后续有机会,单独开一篇来讲解。
5. 示例
代码取自野火,完整代码在野火论坛,公开资料
通用代码:
- 初始化函数
void ESP8266_Init ( void )
{ESP8266_GPIO_Config (); ESP8266_USART_Config (); macESP8266_RST_HIGH_LEVEL();macESP8266_CH_ENABLE();}
- 初始化GPIO
static void ESP8266_GPIO_Config ( void )
{/*定义一个GPIO_InitTypeDef类型的结构体*/GPIO_InitTypeDef GPIO_InitStructure;/* 配置 CH_PD 引脚*/macESP8266_CH_PD_APBxClock_FUN ( macESP8266_CH_PD_CLK, ENABLE ); GPIO_InitStructure.GPIO_Pin = macESP8266_CH_PD_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init ( macESP8266_CH_PD_PORT, & GPIO_InitStructure ); /* 配置 RST 引脚*/macESP8266_RST_APBxClock_FUN ( macESP8266_RST_CLK, ENABLE ); GPIO_InitStructure.GPIO_Pin = macESP8266_RST_PIN; GPIO_Init ( macESP8266_RST_PORT, & GPIO_InitStructure ); }
- 初始化串口
static void ESP8266_USART_Config ( void )
{GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;/* config USART clock */macESP8266_USART_APBxClock_FUN ( macESP8266_USART_CLK, ENABLE );macESP8266_USART_GPIO_APBxClock_FUN ( macESP8266_USART_GPIO_CLK, ENABLE );/* USART GPIO config *//* Configure USART Tx as alternate function push-pull */GPIO_InitStructure.GPIO_Pin = macESP8266_USART_TX_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(macESP8266_USART_TX_PORT, &GPIO_InitStructure); /* Configure USART Rx as input floating */GPIO_InitStructure.GPIO_Pin = macESP8266_USART_RX_PIN;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(macESP8266_USART_RX_PORT, &GPIO_InitStructure);/* USART1 mode config */USART_InitStructure.USART_BaudRate = macESP8266_USART_BAUD_RATE;USART_InitStructure.USART_WordLength = USART_WordLength_8b;USART_InitStructure.USART_StopBits = USART_StopBits_1;USART_InitStructure.USART_Parity = USART_Parity_No ;USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;USART_Init(macESP8266_USARTx, &USART_InitStructure);/* 中断配置 */USART_ITConfig ( macESP8266_USARTx, USART_IT_RXNE, ENABLE ); //使能串口接收中断 USART_ITConfig ( macESP8266_USARTx, USART_IT_IDLE, ENABLE ); //使能串口总线空闲中断 ESP8266_USART_NVIC_Configuration ();USART_Cmd(macESP8266_USARTx, ENABLE);}
- 配置中断
static void ESP8266_USART_NVIC_Configuration ( void )
{NVIC_InitTypeDef NVIC_InitStructure; /* Configure the NVIC Preemption Priority Bits */ NVIC_PriorityGroupConfig ( macNVIC_PriorityGroup_x );/* Enable the USART2 Interrupt */NVIC_InitStructure.NVIC_IRQChannel = macESP8266_USART_IRQ; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);}
常规的结束,接下来就是移植代码,ESP8266,接收发送模块化代码
/** 函数名:ESP8266_Rst* 描述 :重启WF-ESP8266模块* 输入 :无* 返回 : 无* 调用 :被 ESP8266_AT_Test 调用*/
void ESP8266_Rst ( void )
{#if 0ESP8266_Cmd ( "AT+RST", "OK", "ready", 2500 ); #elsemacESP8266_RST_LOW_LEVEL();Delay_ms ( 500 ); macESP8266_RST_HIGH_LEVEL();#endif}/** 函数名:ESP8266_Cmd* 描述 :对WF-ESP8266模块发送AT指令* 输入 :cmd,待发送的指令* reply1,reply2,期待的响应,为NULL表不需响应,两者为或逻辑关系* waittime,等待响应的时间* 返回 : 1,指令发送成功* 0,指令发送失败* 调用 :被外部调用*/
bool ESP8266_Cmd ( char * cmd, char * reply1, char * reply2, u32 waittime )
{ strEsp8266_Fram_Record .InfBit .FramLength = 0; //从新开始接收新的数据包macESP8266_Usart ( "%s\r\n", cmd );if ( ( reply1 == 0 ) && ( reply2 == 0 ) ) //不需要接收数据return true;Delay_ms ( waittime ); //延时strEsp8266_Fram_Record .Data_RX_BUF [ strEsp8266_Fram_Record .InfBit .FramLength ] = '\0';macPC_Usart ( "%s", strEsp8266_Fram_Record .Data_RX_BUF );if ( ( reply1 != 0 ) && ( reply2 != 0 ) )return ( ( bool ) strstr ( strEsp8266_Fram_Record .Data_RX_BUF, reply1 ) || ( bool ) strstr ( strEsp8266_Fram_Record .Data_RX_BUF, reply2 ) ); else if ( reply1 != 0 )return ( ( bool ) strstr ( strEsp8266_Fram_Record .Data_RX_BUF, reply1 ) );elsereturn ( ( bool ) strstr ( strEsp8266_Fram_Record .Data_RX_BUF, reply2 ) );}/** 函数名:ESP8266_AT_Test* 描述 :对WF-ESP8266模块进行AT测试启动* 输入 :无* 返回 : 无* 调用 :被外部调用*/
//void ESP8266_AT_Test ( void )
//{
// macESP8266_RST_HIGH_LEVEL();
//
// Delay_ms ( 1000 );
//
// while ( ! ESP8266_Cmd ( "AT", "OK", NULL, 500 ) ) ESP8266_Rst (); //}
void ESP8266_AT_Test ( void )
{char count=0;macESP8266_RST_HIGH_LEVEL(); Delay_ms ( 1000 );while ( count < 10 ){if( ESP8266_Cmd ( "AT", "OK", NULL, 500 ) ) return;ESP8266_Rst();++ count;}
}/** 函数名:ESP8266_Net_Mode_Choose* 描述 :选择WF-ESP8266模块的工作模式* 输入 :enumMode,工作模式* 返回 : 1,选择成功* 0,选择失败* 调用 :被外部调用*/
bool ESP8266_Net_Mode_Choose ( ENUM_Net_ModeTypeDef enumMode )
{switch ( enumMode ){case STA:return ESP8266_Cmd ( "AT+CWMODE=1", "OK", "no change", 2500 ); case AP:return ESP8266_Cmd ( "AT+CWMODE=2", "OK", "no change", 2500 ); case STA_AP:return ESP8266_Cmd ( "AT+CWMODE=3", "OK", "no change", 2500 ); default:return false;}}/** 函数名:ESP8266_JoinAP* 描述 :WF-ESP8266模块连接外部WiFi* 输入 :pSSID,WiFi名称字符串* :pPassWord,WiFi密码字符串* 返回 : 1,连接成功* 0,连接失败* 调用 :被外部调用*/
bool ESP8266_JoinAP ( char * pSSID, char * pPassWord )
{char cCmd [120];sprintf ( cCmd, "AT+CWJAP=\"%s\",\"%s\"", pSSID, pPassWord );return ESP8266_Cmd ( cCmd, "OK", NULL, 5000 );}/** 函数名:ESP8266_BuildAP* 描述 :WF-ESP8266模块创建WiFi热点* 输入 :pSSID,WiFi名称字符串* :pPassWord,WiFi密码字符串* :enunPsdMode,WiFi加密方式代号字符串* 返回 : 1,创建成功* 0,创建失败* 调用 :被外部调用*/
bool ESP8266_BuildAP ( char * pSSID, char * pPassWord, ENUM_AP_PsdMode_TypeDef enunPsdMode )
{char cCmd [120];sprintf ( cCmd, "AT+CWSAP=\"%s\",\"%s\",1,%d", pSSID, pPassWord, enunPsdMode );return ESP8266_Cmd ( cCmd, "OK", 0, 1000 );}/** 函数名:ESP8266_Enable_MultipleId* 描述 :WF-ESP8266模块启动多连接* 输入 :enumEnUnvarnishTx,配置是否多连接* 返回 : 1,配置成功* 0,配置失败* 调用 :被外部调用*/
bool ESP8266_Enable_MultipleId ( FunctionalState enumEnUnvarnishTx )
{char cStr [20];sprintf ( cStr, "AT+CIPMUX=%d", ( enumEnUnvarnishTx ? 1 : 0 ) );return ESP8266_Cmd ( cStr, "OK", 0, 500 );}/** 函数名:ESP8266_Link_Server* 描述 :WF-ESP8266模块连接外部服务器* 输入 :enumE,网络协议* :ip,服务器IP字符串* :ComNum,服务器端口字符串* :id,模块连接服务器的ID* 返回 : 1,连接成功* 0,连接失败* 调用 :被外部调用*/
bool ESP8266_Link_Server ( ENUM_NetPro_TypeDef enumE, char * ip, char * ComNum, ENUM_ID_NO_TypeDef id)
{char cStr [100] = { 0 }, cCmd [120];switch ( enumE ){case enumTCP:sprintf ( cStr, "\"%s\",\"%s\",%s", "TCP", ip, ComNum );break;case enumUDP:sprintf ( cStr, "\"%s\",\"%s\",%s", "UDP", ip, ComNum );break;default:break;}if ( id < 5 )sprintf ( cCmd, "AT+CIPSTART=%d,%s", id, cStr);elsesprintf ( cCmd, "AT+CIPSTART=%s", cStr );return ESP8266_Cmd ( cCmd, "OK", "ALREAY CONNECT", 4000 );}/** 函数名:ESP8266_StartOrShutServer* 描述 :WF-ESP8266模块开启或关闭服务器模式* 输入 :enumMode,开启/关闭* :pPortNum,服务器端口号字符串* :pTimeOver,服务器超时时间字符串,单位:秒* 返回 : 1,操作成功* 0,操作失败* 调用 :被外部调用*/
bool ESP8266_StartOrShutServer ( FunctionalState enumMode, char * pPortNum, char * pTimeOver )
{char cCmd1 [120], cCmd2 [120];if ( enumMode ){sprintf ( cCmd1, "AT+CIPSERVER=%d,%s", 1, pPortNum );sprintf ( cCmd2, "AT+CIPSTO=%s", pTimeOver );return ( ESP8266_Cmd ( cCmd1, "OK", 0, 500 ) &&ESP8266_Cmd ( cCmd2, "OK", 0, 500 ) );}else{sprintf ( cCmd1, "AT+CIPSERVER=%d,%s", 0, pPortNum );return ESP8266_Cmd ( cCmd1, "OK", 0, 500 );}}/** 函数名:ESP8266_Get_LinkStatus* 描述 :获取 WF-ESP8266 的连接状态,较适合单端口时使用* 输入 :无* 返回 : 2,获得ip* 3,建立连接* 3,失去连接* 0,获取状态失败* 调用 :被外部调用*/
uint8_t ESP8266_Get_LinkStatus ( void )
{if ( ESP8266_Cmd ( "AT+CIPSTATUS", "OK", 0, 500 ) ){if ( strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "STATUS:2\r\n" ) )return 2;else if ( strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "STATUS:3\r\n" ) )return 3;else if ( strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "STATUS:4\r\n" ) )return 4; }return 0;}/** 函数名:ESP8266_Get_IdLinkStatus* 描述 :获取 WF-ESP8266 的端口(Id)连接状态,较适合多端口时使用* 输入 :无* 返回 : 端口(Id)的连接状态,低5位为有效位,分别对应Id5~0,某位若置1表该Id建立了连接,若被清0表该Id未建立连接* 调用 :被外部调用*/
uint8_t ESP8266_Get_IdLinkStatus ( void )
{uint8_t ucIdLinkStatus = 0x00;if ( ESP8266_Cmd ( "AT+CIPSTATUS", "OK", 0, 500 ) ){if ( strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "+CIPSTATUS:0," ) )ucIdLinkStatus |= 0x01;else ucIdLinkStatus &= ~ 0x01;if ( strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "+CIPSTATUS:1," ) )ucIdLinkStatus |= 0x02;else ucIdLinkStatus &= ~ 0x02;if ( strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "+CIPSTATUS:2," ) )ucIdLinkStatus |= 0x04;else ucIdLinkStatus &= ~ 0x04;if ( strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "+CIPSTATUS:3," ) )ucIdLinkStatus |= 0x08;else ucIdLinkStatus &= ~ 0x08;if ( strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "+CIPSTATUS:4," ) )ucIdLinkStatus |= 0x10;else ucIdLinkStatus &= ~ 0x10; }return ucIdLinkStatus;}/** 函数名:ESP8266_Inquire_ApIp* 描述 :获取 F-ESP8266 的 AP IP* 输入 :pApIp,存放 AP IP 的数组的首地址* ucArrayLength,存放 AP IP 的数组的长度* 返回 : 0,获取失败* 1,获取成功* 调用 :被外部调用*/
uint8_t ESP8266_Inquire_ApIp ( char * pApIp, uint8_t ucArrayLength )
{char uc;char * pCh;ESP8266_Cmd ( "AT+CIFSR", "OK", 0, 500 );pCh = strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "APIP,\"" );if ( pCh )pCh += 6;elsereturn 0;for ( uc = 0; uc < ucArrayLength; uc ++ ){pApIp [ uc ] = * ( pCh + uc);if ( pApIp [ uc ] == '\"' ){pApIp [ uc ] = '\0';break;}}return 1;}/** 函数名:ESP8266_UnvarnishSend* 描述 :配置WF-ESP8266模块进入透传发送* 输入 :无* 返回 : 1,配置成功* 0,配置失败* 调用 :被外部调用*/
bool ESP8266_UnvarnishSend ( void )
{if ( ! ESP8266_Cmd ( "AT+CIPMODE=1", "OK", 0, 500 ) )return false;return ESP8266_Cmd ( "AT+CIPSEND", "OK", ">", 500 );}/** 函数名:ESP8266_ExitUnvarnishSend* 描述 :配置WF-ESP8266模块退出透传模式* 输入 :无* 返回 : 无* 调用 :被外部调用*/
void ESP8266_ExitUnvarnishSend ( void )
{Delay_ms ( 1000 );macESP8266_Usart ( "+++" );Delay_ms ( 500 ); }/** 函数名:ESP8266_SendString* 描述 :WF-ESP8266模块发送字符串* 输入 :enumEnUnvarnishTx,声明是否已使能了透传模式* :pStr,要发送的字符串* :ulStrLength,要发送的字符串的字节数* :ucId,哪个ID发送的字符串* 返回 : 1,发送成功* 0,发送失败* 调用 :被外部调用*/
bool ESP8266_SendString ( FunctionalState enumEnUnvarnishTx, char * pStr, u32 ulStrLength, ENUM_ID_NO_TypeDef ucId )
{char cStr [20];bool bRet = false;if ( enumEnUnvarnishTx ){macESP8266_Usart ( "%s", pStr );bRet = true;}else{if ( ucId < 5 )sprintf ( cStr, "AT+CIPSEND=%d,%d", ucId, ulStrLength + 2 );elsesprintf ( cStr, "AT+CIPSEND=%d", ulStrLength + 2 );ESP8266_Cmd ( cStr, "> ", 0, 1000 );bRet = ESP8266_Cmd ( pStr, "SEND OK", 0, 1000 );}return bRet;}/** 函数名:ESP8266_ReceiveString* 描述 :WF-ESP8266模块接收字符串* 输入 :enumEnUnvarnishTx,声明是否已使能了透传模式* 返回 : 接收到的字符串首地址* 调用 :被外部调用*/
char * ESP8266_ReceiveString ( FunctionalState enumEnUnvarnishTx )
{char * pRecStr = 0;strEsp8266_Fram_Record .InfBit .FramLength = 0;strEsp8266_Fram_Record .InfBit .FramFinishFlag = 0;while ( ! strEsp8266_Fram_Record .InfBit .FramFinishFlag );strEsp8266_Fram_Record .Data_RX_BUF [ strEsp8266_Fram_Record .InfBit .FramLength ] = '\0';if ( enumEnUnvarnishTx )pRecStr = strEsp8266_Fram_Record .Data_RX_BUF;else {if ( strstr ( strEsp8266_Fram_Record .Data_RX_BUF, "+IPD" ) )pRecStr = strEsp8266_Fram_Record .Data_RX_BUF;}return pRecStr;}
最后
参考资料:
《乐鑫ESP8266用户手册》
《ESP8266作为TCP服务器端使用心得》
《野火ESP8266部分例程》
如果本文对你有所帮助,还请三连支持一下博主!

相关文章:
物联网中的ESP8266该这么用!
🙌秋名山码民的主页 😂oi退役选手,Java、大数据、单片机、IoT均有所涉猎,热爱技术,技术无罪 🎉欢迎关注🔎点赞👍收藏⭐️留言📝 获取源码,添加WX 目录 1. 前言…...
django中循环生成的多个btn,只有第一个btn会弹出模态框
django中循环生成的多个btn,只有第一个btn会弹出模态框 需求:为每个button按钮都绑定同一点击事件,点击每个btn都可弹出模态框 原因 问题代码 <button idbtnDel type"button" class"btn btn-primary btn-lg" > […...
JVM第二十三讲:Java动态调试技术原理
Java动态调试技术原理 本文是JVM第二十三讲,Java动态调试技术原理。转载自 美团技术团队胡健的Java 动态调试技术原理及实践,通过学习java agent方式进行动态调试,了解目前很多大厂开源的一些基于此的调试工具 (例如来自阿里开源的Arthas)。 …...
制造企业如何三步实现进销存管理?
制造企业如何三步实现进销存管理? 一、什么是进销存软件? 进销存软件是一种针对制造业企业设计的管理软件系统,旨在协调和优化企业的生产、采购、销售以及库存管理等方面的活动。该系统的主要目标是提高企业的生产效率、降低库存成本、优化…...
封装localstorage为对象 js
export const LocalStorageManager {recordKey: "Record",// 获取本地存储中的值get(key) {try {const value localStorage.getItem(key);if (value null || value undefined || value "") {return null;}return JSON.parse(localStorage.getItem(key…...
算法通关村第五关|白银|队栈和Hash的经典算法题【持续更新】
1.用栈实现队列 用两个栈实现队列。 class MyQueue {Deque<Integer> inStack;Deque<Integer> outStack;public MyQueue() {inStack new LinkedList<Integer>();outStack new LinkedList<Integer>();}public void push(int x) {inStack.push(x);}pu…...
java--构造器
1.构造器是什么样子 构造器分为无参构造(就相当于你有车子,但是里面是空的)和带参构造(就相当于你有车子,里面还有几个妹纸,你真该死啊) 2.构造器有什么特点 创建对象时,对象会去调用构造器。 3.构造器的常见应用场景 创建对象…...
纪念基于JavaScript 实现的后台桌面 UI 设计
目录 前言 C/S 到 B/S ASP Builder 的诞生 关于 Craneoffice.net 开发环境配置 后台界面的 UI 区域要素 桌面系统的想法和设计 搜索引擎 导航面板 快捷访问 二级导航 小组件及其它 设置桌面壁纸 小时钟 附件小程序 计算器界面设计 日历与任务 系统设置 天气小…...
C++11 auto限制
限制: auto 不能用于函数参数auto 不能用于非静态成员变量auto 无法定义数组auto 无法推导出模板参数 推荐一个零声学院项目课,个人觉得老师讲得不错,分享给大家: 零声白金学习卡(含基础架构/高性能存储/golang云原生…...
公司老项目springmvc jsp 自定义多数据源 转到springboot 整理
真实完整步骤,踩坑整理 有同样的坑,欢迎补充整理 网上的案例老是少了很多配置,本案例涉及到 spring-mvc,自定义多数据源,统一前缀,事务,mybatis,jsp访问异常,静态文件。…...
Java之SpringCloud Alibaba【七】【Spring Cloud微服务网关Gateway组件】
一、网关简介 大家都都知道在微服务架构中,一个系统会被拆分为很多个微服务。那么作为客户端要如何去调用这么多的微服务呢?如果没有网关的存在,我们只能在客户端记录每个微服务的地址,然后分别去用。 这样的架构,会存在着诸多…...
探讨jdk源码中的二分查找算法返回值巧妙之处
文章目录 1.什么是二分查找算法1.1 简介1.2 实现思路 2.二分查找的示例3.jdk 中的 Arrays.binarySearch()4.jdk 中核心二分查找方法解析4.1 为什么 low 是插入点4.2 为什么要进行取反:-(low 1)4.3 为什么不直接返回 插入点 low 的相反数&…...
深度学习实战:基于TensorFlow与OpenCV的手语识别系统
文章目录 写在前面基于TensorFlow与OpenCV的手语识别系统安装环境一、导入工具库二、导入数据集三、数据预处理四、训练模型基于CNN基于LeNet5基于ResNet50 五、模型预测基于OpenCV 写在后面 写在前面 本期内容:基于TensorFlow与OpenCV的手语识别系统 实验环境&…...
学习整理nginx常用屏蔽规则,让网站更安全
学习整理nginx常用屏蔽规则,让网站更安全 注意一、防止文件被下载二、屏蔽非常见蜘蛛(爬虫)三、禁止某个目录执行脚本四、屏蔽某个IP或IP段 注意 在开始之前,希望您已经熟悉的Nginx常用命令(如停止,重启等…...
四十一、【进阶】索引使用SQL提示
1、SQL提示使用情景 在使用MySQL时,当一个字段参在于多个索引中时,默认情况下,MySQL会自动选择一个索引,但我们可以指定索引吗?可以忽略某一种索引吗? 答案是可以的。 前提:profession字段已经…...
AI智能分析网关高空抛物算法如何实时检测高楼外立面剥落?
高楼外立面剥落是一种十分危险的行为,会造成严重的人身伤害和财产损失。TSINGSEE青犀智能分析网关利用高楼外立面剥落的信息,结合高空抛物算法来进行处理就可很好解决此问题。 1. 数据收集 首先,需要收集关于高楼外立面剥落的数据。这可以通…...
微信小程序 - 页面继承(非完美解决方案)
微信小程序 - 面页继承(非完美解决方案) 废话思路首页 indexindex.jsindex.jsonindex.wxml 父页面 page-basepage-base.jspage-base.wxml 子页面 page-apage-a.jspage-a.wxml 子页面 page-bpage-b.jspage-b.wxml 其它app.jsapp.jsonapp.wxss 参考资料 废…...
智能配件管理系统有什么用?企业如何实现管理数字化转型?
在当今高度信息化的时代,企业运营的各个环节都离不开准确及时的数据支持。特别是在制造业中,生产数据的记录和管理对于提高生产效率、降低成本、优化资源配置等方面具有至关重要的作用。然而,许多企业仍在采用纸质流转卡来记录生产数据&#…...
@SuppressWarnings注解使用说明
在Java编程中,我们常常会遇到一些警告(warnings),这些警告通常是对某些潜在问题的提示,虽然这些问题可能不会立即影响程序的运行,但可能会在将来引发问题。为了消除这些警告,我们可以使用Suppre…...
算法从入门到入土cpp版
1. 排序 1. 快速排序 # include<iostream> using namespace std;const int N 100010;int q[N];void quick_sort(int q[], int l, int r) {if(l>r) return;int il-1,jr1,tempq[l];while(i<j){do i;while(q[i]<temp);do j--;while(q[j]>temp);if(i<j)swa…...
uniapp 对接腾讯云IM群组成员管理(增删改查)
UniApp 实战:腾讯云IM群组成员管理(增删改查) 一、前言 在社交类App开发中,群组成员管理是核心功能之一。本文将基于UniApp框架,结合腾讯云IM SDK,详细讲解如何实现群组成员的增删改查全流程。 权限校验…...
Linux应用开发之网络套接字编程(实例篇)
服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...
synchronized 学习
学习源: https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖,也要考虑性能问题(场景) 2.常见面试问题: sync出…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
使用Spring AI和MCP协议构建图片搜索服务
目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式(本地调用) SSE模式(远程调用) 4. 注册工具提…...
华为OD机试-最短木板长度-二分法(A卷,100分)
此题是一个最大化最小值的典型例题, 因为搜索范围是有界的,上界最大木板长度补充的全部木料长度,下界最小木板长度; 即left0,right10^6; 我们可以设置一个候选值x(mid),将木板的长度全部都补充到x,如果成功…...
【Java多线程从青铜到王者】单例设计模式(八)
wait和sleep的区别 我们的wait也是提供了一个还有超时时间的版本,sleep也是可以指定时间的,也就是说时间一到就会解除阻塞,继续执行 wait和sleep都能被提前唤醒(虽然时间还没有到也可以提前唤醒),wait能被notify提前唤醒…...
当下AI智能硬件方案浅谈
背景: 现在大模型出来以后,打破了常规的机械式的对话,人机对话变得更聪明一点。 对话用到的技术主要是实时音视频,简称为RTC。下游硬件厂商一般都不会去自己开发音视频技术,开发自己的大模型。商用方案多见为字节、百…...
【多线程初阶】单例模式 指令重排序问题
文章目录 1.单例模式1)饿汉模式2)懒汉模式①.单线程版本②.多线程版本 2.分析单例模式里的线程安全问题1)饿汉模式2)懒汉模式懒汉模式是如何出现线程安全问题的 3.解决问题进一步优化加锁导致的执行效率优化预防内存可见性问题 4.解决指令重排序问题 1.单例模式 单例模式确保某…...
中国政务数据安全建设细化及市场需求分析
(基于新《政务数据共享条例》及相关法规) 一、引言 近年来,中国政府高度重视数字政府建设和数据要素市场化配置改革。《政务数据共享条例》(以下简称“《共享条例》”)的发布,与《中华人民共和国数据安全法》(以下简称“《数据安全法》”)、《中华人民共和国个人信息…...
