MQTT协议分析
目录
一、前言
二、MQTT协议概述
概念
基本原理
MQTT协议的结构
MQTT的QoS机制
QoS 0:最多一次传输
QoS 1:至少一次传输
QoS 2:恰好一次传输
三、MQTT的应用场景
四、MQTT的优点和缺点
五、MQTT协议的实现
六、实战体验MQTT
七、MQTT协议的未来发展
一、前言
随着物联网和智能化应用的快速发展,对于通信协议的需求越来越多样化和复杂化,对于物联网应用来说,基于TCP/IP的协议MQTT(Message Queuing Telemetry Transport)正逐渐成为主流的协议之一。本文将对MQTT协议的相关概念、基本原理、应用场景等进行介绍和分析。
二、MQTT协议概述
概念
MQTT(Message Queuing Telemetry Transport)是一种轻量级的发布/订阅消息传输协议,它被设计用于低带宽和不稳定的网络环境中,比如远程传感器和移动设备等。它支持一对多的消息传输,可以被广泛应用于物联网、移动应用程序、工业自动化、金融服务等领域。
基本原理
MQTT使用基于TCP/IP协议的可靠传输机制来实现消息传输,并采用发布/订阅模式来处理消息。在MQTT中,发布者将消息发布到一个主题(Topic)上,订阅者则可以订阅该主题,以接收发布者发布的消息。MQTT Broker充当一个中间件来传递这些消息。MQTT支持三种QoS(服务质量)等级,从而实现不同的消息传输可靠性和实时性。此外,MQTT还支持各种各样的客户端,包括C语言、Java、Python等等,因此它被广泛用于物联网、移动应用程序、工业自动化等领域。
MQTT协议的结构
MQTT协议主要由三部分组成,分别是固定头部、可变头部和消息体,其中固定头部和可变头部的长度是固定的,消息体的长度是可变的。
固定头部:固定头部由两个部分组成,第一个字节的前四位表示消息类型(MessageType),剩下的四位是标识符标志(Flag)。前四位二进制可表示16种消息类型,如下图所示:
第一个字节后四位中,DUP表示发布消息的副本,用来保证消息的可靠传输。消息重传时,DUP标志被设置为1。而两位的Qos则表示消息的服务质量(以二进制表示):
- 00:最多一次传输
- 01:至少一次传输
- 10:恰好一次传输
- 11:预留标识
RETAIN作为发布保留标识,发布保留标识,表示服务器要保留这次推送的信息,如果有新的订阅者出现,就把这消息推送给它,如果设有那么推送至当前订阅者后释放。
第二个字节为剩余长度,用来保存变长头部和消息体的总大小的,但不是直接保存的。这一字节是可以扩展,其保存机制,前7位用于保存长度,后一部用做标识。当最后一位为 1时,表示长度不足,需要使用二个字节继续保存。
可变头部:可变头部长度根据消息类型不同而不同,一般包括报文标识符(Packet Identifier)和主题(Topic)等信息。
消息体:消息体的长度也根据消息类型不同而不同,主要包括消息正文和可选的附加属性等信息。
对于MQTT协议而言,有以下四种类型的消息体:
- CONNECT:消息体内容主要是:客户端的ClientID、订阅的Topic、Message以及用户名和密码。
- SUBSCRIBE:消息体内容是一系列的要订阅的主题以及QoS。
- SUBACK:消息体内容是服务器对于SUBSCRIBE所申请的主题及QoS进行确认和回复。
- UNSUBSCRIBE:消息体内容是要订阅的主题。
MQTT的QoS机制
MQTT协议支持三种不同的QoS(服务质量)等级,分别为0、1和2,它们分别代表不同的消息传输可靠性和实时性。下面是三种QoS等级的详细说明:
QoS 0:最多一次传输
消息发布者只发送一次消息,无论它是否被接收。此时消息传输的效率最高,但消息的可靠性最低。
消息丢失情况:当我们使用 QoS 0 传递消息时,消息的可靠性完全依赖于底层的 TCP 协议。而 TCP 只能保证在连接稳定不关闭的情况下消息的可靠到达,一旦出现连接关闭、重置,仍有可能丢失当前处于网络链路或操作系统底层缓冲区中的消息。这也是 QoS 0 消息最主要的丢失场景。
QoS 1:至少一次传输
为了保证消息到达,QoS 1加入了应答与重传机制,发送方只有在收到接收方的 PUBACK 报文以后,才能认为消息投递成功,在此之前,发送方需要存储该 PUBLISH 报文以便下次重传。此时消息传输的效率较高,且消息的可靠性较高。
消息重复情况:对于发送方而言,没有收到回传的PUBACK报文有一下两种情况。
- 第一种情况:接收方未收到消息。
- 第二种情况:接收方收到了消息,回传的PUBACK报文未到达发送方。
如果是第一种情况,发送方将会重传报文,接收方相当于只收到了一次消息。如果是第二种情况,发送方重传报文,但此时接收方已经收到了这个消息,这就导致接收方收到了重复的消息。虽然在重传时,PUBLUSH报文的DUP标志会被设置为1.表示这是一个重传的报文、但是接收方不能假定自己曾经接受过这个消息,仍然需要将其视作一个全新的消息。
QoS 2:恰好一次传输
发送方和接收方之间进行一个消息确认(PUBREC、PUBREL、PUBCOMP)的三步握手,以确保消息的可靠传输。每一次的QoS 2消息投递,都要求发送方与接收方进行至少两次请求/响应流程。此时消息传输的效率较低,但消息的可靠性最高。
下面是设置QoS为2时的消息发送流程:
- 首先,发送方存储并发送QoS 为 2的 PUBLISH 报文以启动一次QoS 2消息的传输,然后等待接收方回复 PUBREC 报文。这一部分与QoS 1基本一致,只是响应报文从 PUBACK 变成了 PUBREC。
- 当发送方收到 PUBREC 报文,即可确认对端已经收到了 PUBLISH 报文,发送方将不再需要重传这个报文,并且也不能再重传这个报文。所以此时发送方可以删除本地存储的 PUBLISH 报文,然后发送一个 PUBREL 报文,通知对端自己准备将本次使用的 Packet ID 标记为可用了。与 PUBLISH 报文一样,我们需要确保 PUBREL 报文到达对端,所以也需要一个响应报文,并且这个 PUBREL 报文需要被存储下来以便后续重传。
- 当接收方收到 PUBREL 报文,也可以确认在这一次的传输流程中不会再有重传的 PUBLISH 报文到达,因此回复 PUBCOMP 报文表示自己也准备好将当前的 Packet ID 用于新的消息了。
- 当发送方收到 PUBCOMP 报文,这一次的 QoS 2 消息传输就算正式完成了。在这之后,发送方可以再次使用当前的 Packet ID 发送新的消息,而接收方再次收到使用这个 Packet ID 的 PUBLISH 报文时,也会将它视为一个全新的消息。
消息去重原理:QoS 2 规定,发送方只有在收到 PUBREC 报文之前可以重传 PUBLISH 报文。一旦收到 PUBREC 报文并发出 PUBREL 报文,发送方就进入了 Packet ID 释放流程,不可以再使用当前 Packet ID 重传 PUBLISH 报文。同时,在收到对端回复的 PUBCOMP 报文确认双方都完成 Packet ID 释放之前,也不可以使用当前 Packet ID 发送新的消息。因此,对于接收方来说,能够以 PUBREL 报文为界限,凡是在 PUBREL 报文之前到达的 PUBLISH 报文,都必然是重复的消息;而凡是在 PUBREL 报文之后到达的 PUBLISH 报文,都必然是全新的消息。一旦有了这个前提,我们就能够在协议层面完成 QoS 2 消息的去重。
三、MQTT的应用场景
MQTT协议被广泛应用于各种领域,如下所示:
物联网应用:MQTT是物联网应用中最常用的协议之一,它支持低带宽、低功耗设备,并且可以轻松地扩展到海量设备。
移动应用程序:MQTT是移动应用程序中使用最广泛的协议之一,它可以为移动应用程序提供可靠的消息传输机制,而且消耗的带宽和电量很低。
工业自动化:MQTT可以被广泛应用于工业自动化领域,用于实时监控和控制生产过程中的各种设备。
金融服务:MQTT可以为金融服务提供可靠的消息传输机制,以保证消息的安全性和可靠性。
四、MQTT的优点和缺点
MQTT协议有以下优点:
- 灵活性高。MQTT协议是基于发布/订阅模式来处理消息的,可以很方便地支持一对多的通信模式。
- 可扩展性强。MQTT协议支持可靠的消息传输机制,并且可以轻松地扩展到海量设备。
- 轻量级。MQTT协议是一种轻量级的协议,适用于低带宽和不稳定的网络环境中,消耗的带宽和电量很低。
- 易于实现。MQTT协议具有简单的结构和易于实现的特点,可以在各种硬件平台上运行。
MQTT协议的缺点包括以下几点:
- 安全性较低。MQTT协议没有内置的安全机制,需要使用TLS/SSL等加密协议来保证通信的安全性。
- 可靠性较低。QoS等级为0的消息只能保证最多一次传输,可能会出现消息丢失的情况。
- 消息头较大。MQTT协议的消息头比较大,占用了较大的带宽资源。
- 无序传输。MQTT协议的消息传输是无序的,不能保证消息的顺序性。
五、MQTT协议的实现
MQTT协议的实现需要以下几个组件:
MQTT客户端:MQTT客户端可以是任何设备,包括PC、手机、传感器等,它用于连接到MQTT Broker,并发布或订阅消息。
MQTT Broker:MQTT Broker是消息代理服务器,负责接收、存储和转发MQTT消息。
MQTT订阅者:MQTT订阅者用于订阅消息,并接收发布者发布的消息。
MQTT发布者:MQTT发布者用于发布消息,并将消息发送给MQTT Broker。
MQTT协议的实现可以使用多种编程语言,如Java、Python、C++等,还可以使用各种MQTT客户端库和MQTT Broker实现,如Eclipse Mosquitto、EMQ X等。
六、实战体验MQTT
实战体验MQTT协议,我们首先需要一个MQTT Broker,建议使用EMQX作为MQTT Broker,具体的安装方式请自行搜索(建议通过docker安装)。安装完成后,浏览器访问localhost:18083,登录之后出现如下界面,表示安装成功。
可在右上角设置中设置中文。
Maven依赖
<dependency><groupId>org.springframework.integration</groupId><artifactId>spring-integration-mqtt</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency>
想要发送消息,我们需要用到一个消息发送者,一个消息接受者,一个消息代理服务器。消息发送者和接受者代码如下:
ClientMQTT代码:
@Data
public class ClientMQTT {private String topic;private String clientId;private MqttClient mqttClient;private MqttConnectOptions mqttConnectOptions;private static String host = "tcp://127.0.0.1:1883";// 协议地址private static String userName = "admin";// 账号private static String passWord = "123456";// 密码public static void main(String[] args) throws MqttException {ClientMQTT oneClientMQTT = ClientMQTT.getOneClientMQTT("topic123", "clientId123");}public ClientMQTT() {this.topic = "test";//设置默认的topic 和 clientId;this.clientId = "testClientId-003";}public ClientMQTT(String topic, String clientId) throws MqttException {this.topic = topic;this.clientId = clientId;}/*** 连接到服务器*/private void start() {try {// host为主机名,clientid即连接MQTT的客户端ID,一般以唯一标识符表示,MemoryPersistence设置clientid的保存形式,默认为以内存保存mqttClient = new MqttClient(host, clientId, new MemoryPersistence());// MQTT的连接设置mqttConnectOptions = new MqttConnectOptions();// 设置是否清空session,这里如果设置为false表示服务器会保留客户端的连接记录,这里设置为true表示每次连接到服务器都以新的身份连接mqttConnectOptions.setCleanSession(true);// 设置连接的用户名mqttConnectOptions.setUserName(userName);// 设置连接的密码mqttConnectOptions.setPassword(passWord.toCharArray());// 设置超时时间 单位为秒mqttConnectOptions.setConnectionTimeout(10);// 设置会话心跳时间 单位为秒 服务器会每隔1.5*20秒的时间向客户端发送个消息判断客户端是否在线,但这个方法并没有重连的机制mqttConnectOptions.setKeepAliveInterval(20);mqttConnectOptions.setAutomaticReconnect(true);// 设置回调mqttClient.setCallback(new PushCallback());MqttTopic mqttTopic = mqttClient.getTopic(topic);//setWill方法,如果项目中需要知道客户端是否掉线可以调用该方法。设置最终端口的通知消息mqttConnectOptions.setWill(mqttTopic, "close".getBytes(), 2, true);mqttClient.connect(mqttConnectOptions);//订阅消息int[] Qos = {2};String[] topic1 = {topic};mqttClient.subscribe(topic1, Qos);} catch (Exception e) {e.printStackTrace();}}/*** 返回一个Client*/public static ClientMQTT getOneClientMQTT(String topic, String clientId) throws MqttException {ClientMQTT client = new ClientMQTT(topic, clientId);client.start();return client;}
}
ServerMQTT代码:
@Data
public class ServerMQTT {private static Scanner input = new Scanner(new BufferedInputStream(System.in));private static PrintWriter pw = new PrintWriter(System.out);private String topic;private String clientId;private MqttClient mqttClient;private MqttTopic mqttTopic;private MqttMessage mqttMessage;private static String host = "tcp://127.0.0.1:1883";// 协议地址private static String userName = "admin";// 账号private static String passWord = "123456";// 密码public static void main(String[] args) throws MqttException {ServerMQTT oneServerMQTT = ServerMQTT.getOneServerMQTT("topic123", "client321");while (true) {String str = input.next();int Qos = input.nextInt();ServerMQTT.sendMsg(oneServerMQTT, str, Qos);}}public ServerMQTT() throws MqttException {this.topic = "test";//设置默认的topic 和 clientId;this.clientId = "testClientId-001";mqttClient = new MqttClient(host, clientId, new MemoryPersistence());connect();}public ServerMQTT(String topic, String clientId) throws MqttException {this.topic = topic;this.clientId = clientId;mqttClient = new MqttClient(host, clientId, new MemoryPersistence());connect();}/*** 用来连接服务器*/private void connect() {MqttConnectOptions options = new MqttConnectOptions();// 设置是否清空session,这里如果设置为false表示服务器会保留客户端的连接记录,这里设置为true表示每次连接到服务器都以新的身份连接options.setCleanSession(false);options.setUserName(userName);// 设置用户密码options.setPassword(passWord.toCharArray());options.setConnectionTimeout(10);// 设置超时时间options.setKeepAliveInterval(20);// 设置会话心跳时间options.setAutomaticReconnect(true);try {mqttClient.setCallback(new PushCallback());mqttClient.connect(options);mqttTopic = mqttClient.getTopic(topic);} catch (Exception e) {e.printStackTrace();}}public void publish(MqttTopic topic, MqttMessage message) throws MqttPersistenceException, MqttException {MqttDeliveryToken token = topic.publish(message);token.waitForCompletion();}/*** 返回一个Server*/public static ServerMQTT getOneServerMQTT(String topic, String clientId) throws MqttException {ServerMQTT server = new ServerMQTT(topic, clientId);return server;}/*** 发送消息*/public static boolean sendMsg(ServerMQTT server, String msg, int qos) throws MqttException {server.mqttMessage = new MqttMessage();server.mqttMessage.setQos(qos);server.mqttMessage.setRetained(true);server.mqttMessage.setPayload(msg.getBytes());server.publish(server.mqttTopic, server.mqttMessage);return server.mqttMessage.isRetained();}
}
PushBack代码:
public class PushCallback implements MqttCallback {public void connectionLost(Throwable cause) {System.out.println("连接断开,可以做重连");}public void deliveryComplete(IMqttDeliveryToken token) {}public void messageArrived(String topic, MqttMessage message) throws Exception {System.out.println("接收到topic为:" + topic + " Qos = " + message.getQos() + " 内容为:" + new String(message.getPayload()));}
}
首先启动ClientMQTT,然后启动ServerMQTT,可直接通过控制台输入消息和Qos等级发送消息。
七、MQTT协议的未来发展
随着物联网技术的不断发展和应用,MQTT协议将继续发挥重要作用。未来,MQTT协议可能会有以下几个发展趋势:
- 安全性和可靠性的提升。MQTT协议的未来发展方向之一是提高安全性和可靠性,例如加强数据加密、身份认证和消息确认等功能。
- 实时性的提高。MQTT协议将会逐步优化,提高消息传输的实时性,适用于更多实时应用场景。
- 扩展性的增强。MQTT协议将会逐步增强其可扩展性,以满足海量设备的连接和通信需求。
- 集成性的提高。MQTT协议将会逐步与其他物联网技术集成,例如传感器、无线网络、云计算等,以支持更多的应用场景。
参考资料
MQTT QoS 0, 1, 2 介绍 | EMQ (emqx.com)
MQTT 协议快速体验 | EMQ (emqx.com)
相关文章:
MQTT协议分析
目录 一、前言 二、MQTT协议概述 概念 基本原理 MQTT协议的结构 MQTT的QoS机制 QoS 0:最多一次传输 QoS 1:至少一次传输 QoS 2:恰好一次传输 三、MQTT的应用场景 四、MQTT的优点和缺点 五、MQTT协议的实现 六、实战体验MQTT …...
基于树莓派4B设计的音视频播放器(从0开始)
一、前言 【1】功能总结 选择树莓派设计一款家庭影院系统,可以播放本地视频、网络视频直播、游戏直播、娱乐直播、本地音乐、网络音乐,当做FM网络收音机。 软件采用Qt设计、播放器引擎采用ffmpeg。 当前的硬件选择的是树莓派4B,烧写官方系统,完成最终的开发。 本篇文章主…...
MSF手机渗透实验(未成功)(CVE-2019-2215 Binder UA)
1. 前言 最近想利用metasploit对手机进行依次渗透实验。 通过查看最近三年的安卓漏洞,我对CVE-2019-2215这个漏洞很感兴趣。 幸运的是,metasploit里就有这个漏洞的攻击payload,于是我就开始试试了。 msf6 > search binderMatching Mod…...
系列十二、MySQL管理
一、系统数据库 Mysql数据库安装完成后,自带了一下四个数据库,具体作用如下:二、常用工具 2.1、mysql 2.1.1、概述 该mysql不是指mysql服务,而是指mysql的客户端工具。 2.1.2、语法 # 语法 : mysql [options] [dat…...
[游戏架构] 有限状态机的实际应用
什么是有限状态机 有限状态机(Finite State Machine,简称FSM)是一种常用的计算机科学中的建模工具,用于描述由离散状态和状态之间的转换组成的系统。它主要由一个有限的状态集合、一个初始状态、一个输入事件集合、状态之间的转换…...
【站外SEO】如何利用外部链接来提高你的网站排名
随着互联网的快速发展,越来越多的企业开始注重SEO优化,以提升自己的网站排名,增加流量和曝光度。 而站外SEO作为SEO的重要组成部分,对于提升网站排名具有不可忽视的作用。 站外SEO主要是通过外部链接来提高网站的排名。而GPB外链…...
OSCP-课外4(修复web访问、Mysql UDF提权)
目录 难度 一、主机发现与端口扫描 二、Web信息收集 站点目录扫描 搜索phpmailer的漏...
深信服面经---云计算方向(附问题知识点解析)
深信服面经---云计算高级开发一、一面问题概览二、实操相关三、复盘对问题答案进行整理(查漏补缺)3.1、go语言简单了解3.2、项目中成就感最大或挑战最大的地方3.3、项目问题---协议头引入之后,包的大小增加了多少3.4、如何建立缓存3.5、cache…...
MySQL面试题-基础篇
目录 前言 数据库基础 1.什么是关系型数据库和非关系型数据库? 2.什么是 SQL? 3.MySQL 有什么优点? 4.MySQL 的基础架构? 存储引擎 1.MySQL 支持哪些存储引擎?默认使用哪个? 2.MySQL 存储引擎架构了解吗&…...
高通平台开发系列讲解(摄像头篇)QCM6490 上摄像头驱动开发
文章目录 一、Camera 硬件简介二、内核驱动移植2.1、确定设备树2.2、增加 camera 节点2.3、配置相关 GPIO沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇将介绍 qcm6490 摄像头驱动开发。 一、Camera 硬件简介 摄像头连接器一般会包含 Mipi 信号、mclk、供电、re…...
MOV压敏电阻应用推荐及选型要点说明
ESD器件-MOV压敏电阻是一种非线性的电阻元器件产品,具有瞬态电压抑制功能,能够吸收电路中多余的电流,可保护一些敏感电路及其他电子产品设备的电路不受ESD、雷击瞬态浪涌电流的危害。对于它的一些应用范围,优恩小编在这里举例说明…...
Pytorch学习笔记(8):正则化(L1、L2、Dropout)与归一化(BN、LN、IN、GN)
目录 一、正则化之weight_decay(L2正则) 1.1 正则化及相关概念 1.2 正则化策略(L1、L2) (1)L1正则化 (2)L2正则化 1.3 L2正则项——weight_decay 二、正则化之Dropout 2.1 Dr…...
Azure OpenAI 官方指南 01|GPT-3 的原理揭秘与微调技巧
Azure OpenAI 服务在微软全球 Azure 平台正式发布后,迅速成为众多用户最关心的服务之一。 Azure OpenAI 服务允许用户通过 REST API 访问 OpenAI 的强大语言模型,包括 GPT-3、Codex 和 Embeddings 模型系列。本期,我们将为您揭秘 Azure Open…...
神垕古镇景区三方背后的博弈,争夺许昌第一家5A景区主导权
钧 瓷 内 参 第37期(总第368期) 2023年3月2日 神垕古镇景区景域,建业,孔家三方背后的博弈,争夺许昌第一家5A景区主导权 在博弈论(Game Theory)经济学中,“智猪博弈”是一个著名的…...
【C++】vector的模拟实现(SGI版本)
吃不了自律的苦,又接受不了平庸的罪。想让自己变好,但又想舒服些。 你啊你……要么就不要去想,想了又不去做,犹犹豫豫,徘徊不前,患得患失… 文章目录一、四种构造函数1.vector的框架和无参构造2.构造函数调…...
【9】SCI易中期刊推荐——工程技术-计算机:软件工程(中科院4区)
🚀🚀🚀NEW!!!SCI易中期刊推荐栏目来啦 ~ 📚🍀 SCI即《科学引文索引》(Science Citation Index, SCI),是1961年由美国科学信息研究所(Institute for Scientific Information, ISI)创办的文献检索工具,创始人是美国著名情报专家尤金加菲尔德(Eugene Garfield…...
SOTA!目标检测开源框架YOLOv6 3.0版本来啦
近日,美团视觉智能部发布了 YOLOv6 3.0 版本,再一次将目标检测的综合性能推向新高。YOLOv6-L6 检测精度和速度超越 YOLOv7-E6E,取得当前实时目标检测榜单 SOTA。本文主要介绍了 YOLOv6 3.0 版本中引入的技术创新和优化,希望能为从…...
svn使用
一、SVN概述 1.1为什么需要SVN版本控制软件 1.2解决之道 SCM:软件配置管理 所谓的软件配置管理实际就是对软件源代码进行控制与管理 CVS:元老级产品 VSS:入门级产品 ClearCase:IBM公司提供技术支持,中坚级产品 1.…...
LeetCode 1487. Making File Names Unique【字符串,哈希表】中等
本文属于「征服LeetCode」系列文章之一,这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁,本系列将至少持续到刷完所有无锁题之日为止;由于LeetCode还在不断地创建新题,本系列的终止日期可能是永远。在这一系列刷题文章…...
Java——电话号码的字母组合
题目链接 leetcode在线oj题——电话号码的字母组合 题目描述 给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。 给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。 题目示例…...
LDR6028市面上最具有性价比的Type-C OTG音频协议方案
目前市面上的大部分手机都取消了3.5mm音频耳机接口,仅保留一个Type-C接口,但是追求音质和零延迟的用户仍然会选择3.5mm有线耳机,因为在玩手机游戏的时候,音画不同步真的很影响游戏体验,所以Type-C转3.5mm接口线应运而生…...
SpringMVC-0228
一、SpringMVC简介1、什么是MVCMVC是一种软件架构的思想,将软件按照模型、视图、控制器来划分M:Model,模型层,指工程中的JavaBean,作用是处理数据补充:框架其实就是配置文件jar包JavaBean分为两类ÿ…...
【测试岗】那个准点下班的人,比我先升职了...
前言 陈双喜最近心态很崩。和他同期一道进公司的陈琪又升了一级,可是明明大家在进公司时,陈琪不论是学历还是工作经验,样样都不如自己,眼下不过短短的两年时间便一跃在自己的职级之上,这着实让他有几分不甘心。 程双…...
【C++】适配器模式 -- stack/queue/dqueue
一、适配器模式 设计模式 设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结;Java 语言非常关注设计模式,而 C 并没有太关注,但是一些常见的设计模式我们还是要学习。 迭代器模式 其实我们在前面学习 strin…...
sql server 分页查询
sql server 分页查询[toc]前言SQL server 2012版本。下面都用pageIndex表示页数,pageSize表示一页包含的记录。并且下面涉及到具体例子的,设定查询第2页,每页含10条记录。首先说一下SQL server的分页与MySQL的分页的不同,mysql的分…...
RV1126新增驱动IMX415 SENSOR,实现v4l2抓图
RV1126新增驱动IMX415 SENSOR,实现v4l2抓图。1:内核dts修改&csi_dphy0 {status "okay";ports {#address-cells <1>;#size-cells <0>;port0 {reg <0>;#address-cells <1>;#size-cells <0>;mipi_in_uca…...
Hive 数据倾斜
数据倾斜,即单个节点任务所处理的数据量远大于同类型任务所处理的数据量,导致该节点成为整个作业的瓶颈,这是分布式系统不可能避免的问题。从本质来说,导致数据倾斜有两种原因,一是任务读取大文件,二是任务…...
2月刚上岸字节跳动测试岗面经
这时候发应该还不算太晚,金三银四找工作的小伙伴需要的可以看看。 一、测试工程师的工作是什么? 测试工程师简单点说就是找bug,然后反馈给开发人员,不要小看这个工作。 首先很明显的bug开发人员有时候自己就能找到,测…...
图解KMP算法
子串的定位操作通常称作串的模式匹配。你可以理解为在一篇英语文章中查找某个单词是否存在,或者说在一个主串中寻找某子串是否存在。朴素的模式匹配算法假设我们要从下面的主串S "goodgoogle" 中,找到T "google" 这个子串的位置。…...
Java Map和Set
目录1. 二叉排序树(二叉搜索树)1.1 二叉搜索树的查找1.2 二叉搜索树的插入1.3 二叉搜索树的删除(7种情况)1.4 二叉搜索树和TreeMap、TreeSet的关系2. Map和Set的区别与联系2.1 从接口框架的角度分析2.2 从存储的模型角度分析【2种模型】3. 关于Map3.1 Ma…...
如何做音乐分享类网站/百度推广客户端app
测试前先启动hadoop [hadoopmini-yum ~]$ start-dfs.sh [hadoopmini-yum ~]$ start-yarn.sh 1在一堆给定的文本文件中统计输出每一个单词出现的总次数 代码 package cn.feizhou.wcdemo;import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.Path; impo…...
区政府网站建设方案/最新百度新闻
之前便一直想把它整理出来, 可惜这除了懒就剩下了更懒 , 所以才拖到现在~希望可以对大家有那么一点的帮助~ ---阿鸟 …...
山东众德建设项目管理公司网站/360搜索首页
转:http://www.cocoachina.com/bbs/read.php?tid12760 之前写过类似的文章,这篇以做总结,希望能帮助刚上船的兄弟。^_^ iPhone系统中的Objective-C的内存管理机制是比较灵活的,即可以拿来像C/C一样用,也可以加个Aut…...
网站的优化和推广方案/网页设计免费模板
我的其他博客,说经济,说变革。引用三大招五年根除雾霾 现在的事实,同左派政治经济说法,恰好相反。 先说,所有独裁,都用一套维稳的教材,这个为低级的唯心。想别人想的,为了他自己。 …...
有服务器和域名怎么做网站/搜索排名提升
推荐: 从屏幕中间弹出的Dialog底部滑出的Dialog从屏幕右侧滑出的Dialog从屏幕顶部滑出的 Dialog 日常工作中,自己定义了 Dialog 的工具类,以便使用,下面从底部滑出的 Dialog,效果图如下: 下面主要讲的是&a…...
如何建立一家公司网站/今天nba新闻最新消息
2019独角兽企业重金招聘Python工程师标准>>> 要对一张模版图片进行处理,替换其中的部分,包括文字和图片。 1、主要使用 imagecreatefromjpeg 从JPG文件创建图像对象、 imagecreatefrompng从PNG文件创建图像对象、 getimagesize获取图像对象的…...