[香橙派开发系列]使用蓝牙和手机进行信息的交换
文章目录
- 前言
- 一、HC05蓝牙模块
- 1.HC05概述
- 2.HC05的连接图
- 3.进入HC05的命令模式
- 4.常用的AT指令
- 4.1 检查AT是否上线
- 4.2 重启模块
- 4.3 获取软件版本号
- 4.4 恢复默认状态
- 4.5 获取蓝牙的名称
- 4.6 设置蓝牙模块的波特率
- 4.7 查询蓝牙的连接模式
- 4.8 查询模块角色
- 5.连接电脑
- 6.通过HC05发送消息
- 7.stm32完整代码
- 二、香橙派串口通讯
- 1.打开串口设备
- 2.接线
- 3.串口函数
- 3.1 打开串口文件
- 3.2 关闭串口文件
- 3.3 发送一个字符
- 3.4 发送一个规定好的字符串
- 3.5 printf
- 3.6 返回等待读取的字符数
- 3.7 读取字符
- 3.8 缓冲区函数
- 4.输出内容
- 5.接收内容
- 6.接收字符串
- 三、使用hc05连接香橙派
- 1.通过蓝牙发送字符串给手机
- 2.手机发送内容给香橙派
- 总结
前言
隔了这么久我准备再玩一下香橙派,最近这段时间还是比较的忙,我搭建了个论坛和博客,经常被网络攻击,所以我也是一直在弄网络去了,然后今天比较空闲就想着把单子做一下,这个单子需要使用到HC05蓝牙模块,所以我准备写一篇博客来使用香橙派控制HC05蓝牙模块。
一、HC05蓝牙模块
这个模块是非常经典的一个蓝牙模块,我之前有一单也是使用到这个模块,可以看一下我的这个视频【作息控制系统使用说明】,这个项目也是使用到蓝牙模块的,只不过当时时间紧任务重所以就没有写一篇博客来好好记录一下这个项目,等后面我会单独拿一个模块来介绍一下我做的这些小项目。
1.HC05概述
HC05是嵌入式蓝牙串口通讯模块,也就是使用串口就可以和HC05进行通讯并发送信息给蓝牙的接收端,这个模块有两种工作方式:
1 命令响应工作模式
2 自动连接工作模式
在自动连接的工作模式下又可以分为主、从、回环这三种模式,当传输数据时,根据事先设定的方式连接并传输数据。
在命令模式下,用户可以使用串口连接模块,并发送AT指令对模块进行设置。
2.HC05的连接图
这里我直接使用TTL to USB进行连接,因为我要设置一下这个模块的一些传输和内容。

这里和串口连接的模式一样
| HC05 | TTL |
|---|---|
| 3.3 | VCC |
| TXD | RXD |
| RXD | TXD |
| GND | GND |
3.进入HC05的命令模式
首先我们需要通过AT指令来设置模块的一些内容,然后我们才好进入下面的一些操作,首先在这个模块上有一个按钮

在上电之前需要长按这个按键,然后再上电就可以进入命令模式,在进入命令模式后,模块上的LED等会缓慢的闪烁,如果没有进入就会闪得很快。
4.常用的AT指令
AT指令列表已经烂大街了,所以这里不全部说明,我只拿出一些常用的来说明即可。
4.1 检查AT是否上线
AT\r\n
如果模块在就会返回OK

4.2 重启模块
AT+RESET\r\n
如果执行成功就会返回OK,并进入自动连接模式

4.3 获取软件版本号
AT_VERSION?\r\n
执行完成后会返回版本信息和OK

4.4 恢复默认状态
AT+ORGL\r\n
执行完成后会返回OK,并将模块恢复为出厂设置。
4.5 获取蓝牙的名称
AT+NAME?\r\n
执行完成后会返回蓝牙名称并返回OK

4.6 设置蓝牙模块的波特率
AT+UART=波特率,停止位,校验位\r\n
这里我们设置一个比较常见的,波特率9600,停止位1位,无校验位
AT+UART=9600,1,0
这样就可以了。
4.7 查询蓝牙的连接模式
AT+CMODE?\r\n
返回当前模式,1代表任意模式,也就是蓝牙名称和蓝牙地址都可以连接,这里就不多说了,一般默认是1就可以了。
4.8 查询模块角色
AT+ROLE?
这里默认的是Slave从角色,也就是被动连接,不用动。
5.连接电脑
这里我踩了个大坑,因为我之前的设置是将波特率改为9600了,所以在串口的时候我就用9600进行连接,结果没有任何的反应,后面查了一下手册才发现它默认的波特率是38400,就很尴尬。
这里连接好电脑后先发送个AT指令来查看一下是否返回OK,如果没返回有可能是因为坏了或者是你没长按按键进入命令模式。
然后修改一下波特率,因为我们后面初始化串口不想给那么大的波特率

初始化完成后要记得重启一下模块,然后模块的波特率就设置好看,但是AT指令模式下还是那个波特率(又踩坑了,当不想改文章)。
6.通过HC05发送消息
这里我先用stm32来演示,因为我还在做单子所以先拿这个演示。
首先先写串口的初始化函数,这里我使用的是USART1,初始化代码就不展示了,因为今天的主题不是stm32,然后在main函数中我们使用重写的printf来通过串口发送数据。不知道的可以看我这篇博客异步通讯点灯。
int main(){OLED_Init();MX_Init_KEY();MX_Init_HC05();while(1){printf("hello\r\n");OLED_ShowString(1, 1, "hello");}
}
然后需要在手机上下载蓝牙调试宝,在应用商城都可以下载,这我就不给你们压缩包了,要不然我老喜欢挂码。
首先要把蓝牙模块连接到面包板上,然后就用手机连接好蓝牙

记住串口反接并且要接地即可。
然后打开蓝牙助手的界面

找到里面有一个HC-05,然后连接即可,第一次连接需要你输入一个配对码,这里输入1234或者0000都可以

然后给单片机上电后就会显示出hello来

学到这你已经会使用蓝牙进行发送信息了,stm32就先不再出现了,后面就是香橙派的内容了。
7.stm32完整代码
usart.c
#include "hc05.h"void MX_Init_HC05(){GPIO_InitTypeDef GPIO_InitStruct = {0};USART_InitTypeDef USART_InitStruct = {0};RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9;GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStruct);GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;GPIO_Init(GPIOA, &GPIO_InitStruct);USART_InitStruct.USART_BaudRate = 9600;USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;USART_InitStruct.USART_Parity = USART_Parity_No;USART_InitStruct.USART_StopBits = USART_StopBits_1;USART_InitStruct.USART_WordLength = USART_WordLength_8b;USART_Init(USART1, &USART_InitStruct);USART_Cmd(USART1, ENABLE);
}int fputc(int ch, FILE *f)
{ while((USART1->SR&0X40)==0); USART1->DR = (u8) ch; return ch;
}
二、香橙派串口通讯
在介绍使用香橙派使用HC05模块前先介绍一下串口通讯,并如何配置串口通讯。
1.打开串口设备
在香橙派中,串口通讯是使用设备来进行传输的, 所以我们需要在系统设置中将串口进行打开。
在打开之前先了解一下香橙派的串口引脚分布

在3b中有3个串口可供选择,然后通过
sudo orangepi-config
来开启设备,进入到设置页面

然后选择第一个,按一下回车即可,然后在下面的页面中选择Hardware

然后找到你要开启的串口

我这选择的是UART7,使用方向键移动到那后按一下空格就选中,然后按一下回车保存,之后会提示是否重启,然后按一下回车就可以重启了。
重启完成后使用
ls /dev/ ttyS*
来查看可操作的设备文件,这里只会显示你开启的设备

我们刚才选择了UART7后它这里就会有相应的设备,那个ttyS1是默认开启的,我们不用理他。
2.接线
这里就需要非常非常注意了,我在测试的时候就是这里没有弄好,线接反了,导致一直发送不了。
按照前面给的那张图进行接线后我们就可以写代码了。
注意:这里很重要,很多人玩51单片机来玩这个会忽略一个问题就是GND必须要和单片机的GND接在一起,很多人会单独给这个引脚接GND是错误的。
3.串口函数
这里使用的串口函数库是
#include <wiringSerial.h>
3.1 打开串口文件
int serialOpen(const char* path, int butrl);
第一个参数是设备的路径,比如说我们这需要使用到UART1,那设备地址就是/dev/ttyS7。
第二个参数是波特率,比如9600。
这个函数的返回值是一个文件描述符,我们使用一个变量来接收就可以了。
3.2 关闭串口文件
void serialClose(int fd);
参数是打开的设备描述符。
3.3 发送一个字符
void serialPutchar(int fd, char c);
将一个字符发送到打开的文件描述符fd所对应的设备文件。
3.4 发送一个规定好的字符串
void serialPuts(int fd, char* s);
发送一个规定好的字符串,然后以0结尾。
3.5 printf
void serialPrintf(int fd, char* message, ...);
这个和printf的用法类似。
3.6 返回等待读取的字符数
int serialDataAvail(int fd);
返回的是等待读取的字符数。
3.7 读取字符
int serialGetChar(int fd);
返回下一个待读取的字符,如果这个在10s内没有读取到字符就会返回-1。
3.8 缓冲区函数
void serialFlush(int fd);
抛弃所有接收的数据或者等待写入设备完成。
4.输出内容
通过学习了上面的内容后我们可以简单写一个输出字符的代码来输出0~9
#include <stdio.h>
#include <wiringPi.h>
#include <wiringSerial.h>int main(){int fd = -1, i;wiringPiSetup();fd = serialOpen("/dev/ttyS7", 9600); // 设置串口设备和波特率if (fd < 0){// 设备打开失败printf("设备打开失败\n");return -1;}serialFlush(fd);for (i = 0; i < 10; i++){serialPutchar(fd, i + '0');}serialClose(fd); // 关闭设备
}
运行效果如下:

然后也可以使用printf来个高级一点的输出
#include <stdio.h>
#include <wiringPi.h>
#include <wiringSerial.h>int main(){int fd = -1, i;wiringPiSetup();fd = serialOpen("/dev/ttyS7", 9600); // 设置串口设备和波特率if (fd < 0){// 设备打开失败printf("设备打开失败\n");return -1;}serialFlush(fd);for (i = 0; i < 10; i++){serialPrintf(fd, "this is%d\r\n", i);}serialClose(fd); // 关闭设备
}
输出的内容如下:

5.接收内容
我们可以通过串口来接收一下用户输入的内容,并判断输入的字符是不是我们需要的,然后通过串口返回
#include <stdio.h>
#include <wiringPi.h>
#include <wiringSerial.h>int main(){int fd = -1, i;int c;wiringPiSetup();fd = serialOpen("/dev/ttyS7", 9600); // 设置串口设备和波特率if (fd < 0){// 设备打开失败printf("设备打开失败\n");return -1;}serialFlush(fd);while(1){c = serialGetchar(fd);if (c == -1){break;}if (c == '1'){serialPrintf(fd, "this is 1");}printf("%c", c);}serialClose(fd); // 关闭设备
}
输出的内容:

这里大家可以看到我在这个while循环中添加了一个printf,但是没有截屏给出效果,是因为在这个串口运行的过程中一直在读取的是串口的设备,没有使用输入输出流设备,所以导致我们在输入后没办法显示出内容来,这个的解决办法我还不太清楚,等我研究好了我在出一篇文章来介绍。
6.接收字符串
做串口最让人沉醉的就是读取字符串的操作了,在wiringSerial中有一个函数可以获取缓冲区的长度,我们可以判断这个来读取输入的数据的长度,然后使用一个for循环来循环读取和放置在一个数组中,之后进行输出即可,代码如下:
#include <stdio.h>
#include <wiringPi.h>
#include <wiringSerial.h>int main(){int fd = -1;int i, ch, j = 0, len;char str[1024];wiringPiSetup();fd = serialOpen("/dev/ttyS7", 9600);if (fd < 0){printf("打开设备文件失败\n");return -1;}while(1){len = serialDataAvail(fd); // 获取缓冲区的长度if (len == -1){// 超时退出循环break;}else if(len > 0){serialPrintf(fd, "%d\n", len); // 这一行是测试的for (i = 0; i < len; i++){ch = serialGetchar(fd); // 读取字符str[j++] = ch;}break;}}str[j] = '\0';printf("%s\n", str);serialClose(fd);return 0;
}
三、使用hc05连接香橙派
学会了上面的操作后我们就可以来用香橙派连接hc05了,这个操作也非常非常的简单,和单片机的连接一致,注意不要连错就行了。

1.通过蓝牙发送字符串给手机
本质的思路还是一样的,就是使用串口是输入输出就可以搞定,代码如下:
#include <stdio.h>
#include <wiringPi.h>
#include <wiringSerial.h>int main(){int fd = -1, i;int c;wiringPiSetup();fd = serialOpen("/dev/ttyS7", 9600); // 设置串口设备和波特率if (fd < 0){// 设备打开失败printf("设备打开失败\n");return -1;}serialFlush(fd);while(1){serialPrintf(fd, "hello\r\n");delayMicroseconds(30000); // 延时函数,免得发送得过快}serialClose(fd); // 关闭设备
}
然后在调试助手中就可以看到蓝牙模块发送的内容了:

2.手机发送内容给香橙派
这里可以使用刚才我们测试的接收字符串,只不过这里有一个问题就是这个工具只能发送字符所对应的ascii码,不能正常的输入字符进行输出。
比如我们手机输入字符0,那就得输入ascii码的30

然后在香橙派中就会显示:

然后我们还可以用这个来输入0~9

然后显示

学会了这个后我们就可以编写一个用蓝牙点灯的程序了,其实就是使用蓝牙接收到关键字后给LED灯高低电平,这里就直接给代码了,不展示图片了
#include <stdio.h>
#include <wiringPi.h>
#include <wiringSerial.h>
#include <string.h>int main(){int fd = -1;int i, ch, j = 0, len;char str[1024];wiringPiSetup();fd = serialOpen("/dev/ttyS7", 9600);if (fd < 0){printf("打开设备文件失败\n");return -1;}while(1){len = serialDataAvail(fd);if (len == -1){break;}else if(len > 0){serialPrintf(fd, "%d\n", len);for (i = 0; i < len; i++){ch = serialGetchar(fd);str[j++] = ch;}break;}}str[j] = '\0';printf("%s\n", str);if (strcmp(str, "0")){// 点灯}else{// 灭灯}serialClose(fd);return 0;
}
总结
串口很好玩,蓝牙模块也好玩,学会了这一节我们就可以使用蓝牙做一个简单的远程开关灯的项目了,当然拿香橙派做这个项目就很浪费,毕竟香橙派可以直接使用网络来实现,做一个网页,然后内网穿透,这样可以很容易的在远程进行控制了,等我最近忙完有时间我做一个。
大家可以关注一下我的论坛和博客,有不懂的或者有趣的问题可以放在我的论坛中进行提问
马桶论坛
马桶博客
相关文章:
[香橙派开发系列]使用蓝牙和手机进行信息的交换
文章目录 前言一、HC05蓝牙模块1.HC05概述2.HC05的连接图3.进入HC05的命令模式4.常用的AT指令4.1 检查AT是否上线4.2 重启模块4.3 获取软件版本号4.4 恢复默认状态4.5 获取蓝牙的名称4.6 设置蓝牙模块的波特率4.7 查询蓝牙的连接模式4.8 查询模块角色 5.连接电脑6.通过HC05发送…...
Jmeter 01 -概述线程组
1、Jmeter:概述 1.1 是什么? Jmeter是Apache公司使用Java 开发的一款测试工具 1.2 为什么? 高效、功能强大 模拟一些高并发或多次循环等特殊场景 1.3 怎么用? 下载安装 1、下载jmeter,解压缩2、安装Java环境(jmet…...
大数据Zookeeper--案例
文章目录 服务器动态上下线监听案例需求需求分析具体实现测试 Zookeeper分布式锁案例原生Zookeeper实现分布式锁Curator框架实现分布式锁 Zookeeper面试重点选举机制生产集群安装多少zk合适zk常用命令 服务器动态上下线监听案例 需求 某分布式系统中,主节点可以有…...
VS编译器对scanf函数不安全报错的解决办法(详细步骤)
📚博客主页:爱敲代码的小杨. ✨专栏:《Java SE语法》 | 《数据结构与算法》 | 《C生万物》 ❤️感谢大家点赞👍🏻收藏⭐评论✍🏻,您的三连就是我持续更新的动力❤️ 🙏小杨水平有…...
vscode连接ssh报错
关于vscode更新版本至1.86后,导致无法连接服务器问题的记录 原因:vscode1.86更新了对glibc的要求,需要最低2.28版本,导致各种旧版本的linux发行版(比如最常见的centos 7)都无法用remote-ssh来连接了&#…...
C++ 哈希+unordered_map+unordered_set+位图+布隆过滤器(深度剖析)
文章目录 1. 前言2. unordered 系列关联式容器2.1 unordered_map2.1.1 unordered_map 的概念2.1.2 unordered_map 的使用 2.2 unordered_set2.2.1 unordered_set 的概念2.2.2 unordered_set 的使用 3. 底层结构3.1 哈希的概念3.2 哈希冲突3.3 哈希函数3.4 哈希冲突的解决3.4.1 …...
深入理解Netty及核心组件使用—下
目录 ChannelHandler ChannelHandler 接口 ChannelInboundHandler 接口 ChannelHandler 的适配器 Handler 的共享和并发安全性 资源管理和 SimpleChannelInboundHandler Bootstrap ChannelInitializer ChannelOption ChannelHandler ChannelHandler 接口 从开发人员的…...
vscode 突然连接不上服务器了(2024年版本 自动更新从1.85-1.86)
vscode日志 ll192.168.103.5s password:]0;C:\WINDOWS\System32\cmd.exe [17:09:16.886] Got some output, clearing connection timeout [17:09:16.887] Showing password prompt [17:09:19.688] Got password response [17:09:19.688] "install" wrote data to te…...
element-ui link 组件源码分享
link 组件的 api 涉及的内容不是很多,源码部分的内容也相对较简单,下面从以下这三个方面来讲解: 一、组件结构 1.1 组件结构如下图: 二、组件属性 2.1 组件主要有 type、underline、disabled、href、icon 这些属性,…...
序列化和反序列化、pytest-DDT数据驱动
序列化 序列化就是将对象转化成文件 python转成json import jsondata {"数字": [1, 1.1, -1],"字符串": ["aaaa", bbbb],"布尔值": [True, False],"空值": None,"列表": [[1, 2, 3], [4, 5, 6], [7, 8, 9]],&…...
Spring Boot整合MyBatis Plus实现基本CRUD与高级功能
文章目录 1. 引言2. 项目搭建与依赖配置2.1 添加MyBatis Plus依赖2.2 配置数据源与MyBatis Plus 3. 实现基本CRUD功能3.1 创建实体类3.2 创建Mapper接口3.3 实现Service层3.4 控制器实现 4. 高级功能实现4.1 自动填充功能4.2 乐观锁功能4.3 逻辑删除功能 5. 拓展:My…...
CSS 闪电按钮效果
<template><view class="const"><div class="voltage-button"><button>闪电按钮</button><svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" viewBox=&q…...
【Go-Zero】Error: only one service expected goctl一键转换生成rpc服务错误解决方案
【Go-Zero】Error: only one service expected goctl一键转换生成rpc服务错误解决方案 大家好 我是寸铁👊 总结了一篇Error: only one service expected goctl一键转换生成rpc服务错误解决方案的文章✨ 喜欢的小伙伴可以点点关注 💝 问题背景 今天寸铁在…...
从头开始构建和训练 Transformer(上)
1、导 读 2017 年,Google 研究团队发表了一篇名为《Attention Is All You Need》的论文,提出了 Transformer 架构,是机器学习,特别是深度学习和自然语言处理领域的范式转变。 Transformer 具有并行处理功能,可以实现…...
JVM-JVM内存结构(一)
程序计数器 Program Counter Register程序计数器(寄存器) 程序计数器在物理层上是通过寄存器实现的 作用:记住下一条jvm指令的执行地址特点 是线程私有的(每个线程都有属于自己的程序计数器)不会存在内存溢出 虚拟机栈 每个线程运行时所需要的内存称为虚拟机栈…...
React Emotion 如何优雅的使用样式(一)
简介 Emotion 是一个专为使用 JavaScript 编写 css 样式而设计的库。它提供了强大且可预测的样式组合,以及源映射、标签和测试实用程序等功能为开发人员提供了出色的体验,并且支持字符串和对象样式。 与框架无关的样式应用包 Emotion中提供了一个与框…...
1+X运维试题样卷A卷(初级)
云计算A卷 单选题(200分) 1.在OSI模型中,HTTP协议工作在第()层,交换机工作在第()层。(10分) (答案正确:10分) A、7/3 B、7/2 (正确答案) C、6/3 D、6/2 2.Linux有三个查看文件的命令,若希望在查看文件内容过程中可以用光标上下移动来查看文件内容,应使用命令。(10分…...
QT QDialog 中的按钮,如何按下后触发 accepted 消息?
QT 作为跨平台的系统,对话框并没有采用 Windows API 那种模式,通过返回 mrOK、mrCancel 等结果告诉调用方结果,而是采用了 accepted、rejected 等信号确定执行结果。下面介绍几种出发这些信号的方法。 1. 在按钮的 clicked 槽函数中触发 acc…...
seata分布式事务
文章目录 1、分布式事务1.1 事务的ACID原则原子性一致性隔离性持久性 1.2 分布式事务的问题示例代码准备环境1. seata_demo数据库2. 启动nacos seata-demo父工程pom.xml order-servicepom.xmlapplication.ymlOrderApplicationOrderControllerOrderServiceImplAccountClientStor…...
Python HttpServer 之 简单快速搭建本地服务器,并且使用 requests 测试访问下载服务器文件
Python HttpServer 之 搭建本地服务器,并且使用requests访问下载服务器文件测试 目录 Python HttpServer 之 搭建本地服务器,并且使用requests访问下载服务器文件测试...
在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能
下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能,包括动画效果、数据同步和交互优化。 1. 基础点赞功能实现 1.1 创建数据模型 // VideoModel.ets export class VideoModel {id: string "";title: string ""…...
【磁盘】每天掌握一个Linux命令 - iostat
目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat(I/O Statistics)是Linux系统下用于监视系统输入输出设备和CPU使…...
将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?
Otsu 是一种自动阈值化方法,用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理,能够自动确定一个阈值,将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...
python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)
更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...
【单片机期末】单片机系统设计
主要内容:系统状态机,系统时基,系统需求分析,系统构建,系统状态流图 一、题目要求 二、绘制系统状态流图 题目:根据上述描述绘制系统状态流图,注明状态转移条件及方向。 三、利用定时器产生时…...
DBAPI如何优雅的获取单条数据
API如何优雅的获取单条数据 案例一 对于查询类API,查询的是单条数据,比如根据主键ID查询用户信息,sql如下: select id, name, age from user where id #{id}API默认返回的数据格式是多条的,如下: {&qu…...
多种风格导航菜单 HTML 实现(附源码)
下面我将为您展示 6 种不同风格的导航菜单实现,每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...
如何在最短时间内提升打ctf(web)的水平?
刚刚刷完2遍 bugku 的 web 题,前来答题。 每个人对刷题理解是不同,有的人是看了writeup就等于刷了,有的人是收藏了writeup就等于刷了,有的人是跟着writeup做了一遍就等于刷了,还有的人是独立思考做了一遍就等于刷了。…...
Redis的发布订阅模式与专业的 MQ(如 Kafka, RabbitMQ)相比,优缺点是什么?适用于哪些场景?
Redis 的发布订阅(Pub/Sub)模式与专业的 MQ(Message Queue)如 Kafka、RabbitMQ 进行比较,核心的权衡点在于:简单与速度 vs. 可靠与功能。 下面我们详细展开对比。 Redis Pub/Sub 的核心特点 它是一个发后…...
HDFS分布式存储 zookeeper
hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架,允许使用简单的变成模型跨计算机对大型集群进行分布式处理(1.海量的数据存储 2.海量数据的计算)Hadoop核心组件 hdfs(分布式文件存储系统)&a…...
