Linux--网络基础

计算机网络背景 计算机网络背景是一个复杂而丰富的领域,涵盖了从计算机单机模式到网络互联的演变过程,以及网络技术的不断发展和创新。 计算机单机模式和独立发展 在早期,计算机主要以单机模式存在,即每台计算机都是独立的,它们之间无法直接进行通信和数据共享。这种模式下,计算机之间的协同工作非常困难,效率也极低。例如,当多个计算机需要共同完成某项任务时,它们只能通过物理媒介(如光盘、磁带等)来传递数据,这大大限制了计算机的应用范围和效率。 网络互联的兴起与发展 随着计算机技术的不断发展,人们开始意识到将多台计算机连接在一起的重要性。于是,网络互联的概念应运而生。网络互联不仅实现了计算机之间的数据共享和通信,还大大提高了计算机系统的整体性能和效率。 局域网(LAN)的出现: 局域网是指在一个较小区域内(如一个楼层、一栋楼或一个校园)的计算机相互连接形成的网络。它主要使用交换机和路由器等设备进行数据转发和路由选择。 广域网(WAN)的扩展: 广域网则是指覆盖多个远距离区域的远程网络。它通常跨越城市、国家甚至全球范围,通过长途通信线路(如光缆、卫星等)将多个局域网连接起来。 城域网(MAN)的补充: 城域网是连接整个城市的网络,它比局域网更大但比广域网更小。城域网为城市范围内的计算机提供了高效、稳定的数据传输服务。 互联网的形成与普及 互联网是计算机网络发展的高级阶段,它是一个由全球范围内的众多计算机网络相互连接而成的庞大网络。互联网的形成经历了多个阶段,包括ARPANET的创建、TCP/IP协议的普及以及互联网的商业化等。 ARPANET的创建: ARPANET是美国国防部高级研究计划局在20世纪60年代末创建的第一个分组交换网络。它最初只连接了四台计算机,但为后来的互联网发展奠定了基础。TCP/IP协议的普及: TCP/IP协议是互联网的核心协议之一,它规定了互联网中数据传输的格式和规则。随着TCP/IP协议的普及和应用,越来越多的计算机和网络开始支持该协议,从而实现了互联网的互连和互通。互联网的商业化: 随着互联网的不断发展,其商业化进程也逐渐加速。越来越多的公司开始提供互联网接入服务、网站建设服务以及电子商务等应用服务。这些服务的出现不仅丰富了互联网的应用场景和功能,还推动了互联网产业的快速发展。 协议 在计算机网络中,协议是一种“约定”,它规定了数据在网络中传输的方式、格式、顺序以及双方进行通信的交互规则。这些规则确保了不同设备和系统之间能够相互理解和协作,从而实现了信息的有效传递和共享。 协议的作用 确保数据传输的正确性:协议规定了数据的传输格式和顺序,确保了数据在传输过程中不会出现错误或丢失。提高通信效率:通过规定数据传输的方式和顺序,协议可以优化通信过程,减少不必要的等待和重传,从而提高通信效率。保障安全性:协议中通常包含安全性的规定,如数据加密、身份认证等,以保障数据传输的安全性。 协议的分类 计算机中的协议可以根据不同的标准进行分类,常见的分类方式包括: 1.按协议的功能分类: 应用层协议:如HTTP(超文本传输协议)、FTP(文件传输协议)、SMTP(简单邮件传输协议)等,这些协议为应用程序提供了网络服务。传输层协议:如TCP(传输控制协议)和UDP(用户数据报协议),这些协议负责向用户提供端到端的通信服务,实现流量控制和差错控制。网络层协议:如IP(互联网协议),它定义了能够标识所有结点的逻辑地址,还定义了路由实现的方式和学习的方式。数据链路层协议:如以太网协议,它定义了如何在单个链路上传输数据。物理层协议:定义了数据传输的物理介质和接口标准,如RS-232、USB等。 2.按协议的开放性分类: 开放式协议:如TCP/IP协议族,这些协议是公开的、标准化的,任何厂商都可以按照标准开发支持这些协议的产品。私有协议:某些厂商为了保持技术领先或实现特定功能,可能会开发自己的私有协议,这些协议通常不公开或只在小范围内使用。 协议的实现 协议的实现通常涉及软件编程和硬件支持两个方面。在软件方面,开发人员需要按照协议规范编写相应的程序代码,以实现协议规定的功能。在硬件方面,则需要提供相应的接口和物理介质来支持协议的运行。 协议的标准化 协议的标准化是计算机网络发展的重要保障。通过制定统一的协议标准,可以确保不同厂商的设备能够相互通信和协作,从而实现网络的互联互通。国际标准化组织(ISO)和互联网工程任务组(IETF)等机构在协议标准化方面发挥了重要作用。 OSI模型 OSI模型,即开放式系统互联(Open Systems Interconnection)模型,是由国际标准化组织(ISO)在1985年研究并提出的网络互连模型。该模型是一个分层的网络通信协议体系结构,它定义了网络互连的七层框架,每一层都完成特定的功能,并将其整合到更高层次的通信过程中。 OSI模型从低到高依次分为以下七层: 1.物理层(Physical Layer) 主要功能:负责传输数据比特流,即将数据从发送方传输到接收方,通过物理介质(如网线、无线信号等)实现。传输单位:比特(bit)。常用设备:集线器、中继器、调制解调器、网线、双绞线、同轴电缆等。 2.数据链路层(Data Link Layer) 主要功能:负责数据包的传输和接收,错误检测和纠正,确保数据的可靠传输。该层将比特组合成字节,再将字节组合成帧,使用链路层地址(如以太网使用MAC地址)来访问介质,并进行差错检测。传输单位:帧(Frame)。 重要协议:ISO1745、HDLC(高级数据链路控制)等。 常用设备:交换机、网卡等。 3.网络层(Network Layer) 主要功能:通过IP地址和路由器实现数据包的传输,负责数据包的寻址和路由选择,实现不同网络之间的通信。传输单位:数据包(Packet)。重要协议:IP协议(Internet Protocol)、ICMP(Internet Control Message Protocol)、ARP(Address Resolution Protocol)、RARP(Reverse Address Resolution Protocol)等。常用设备:路由器。 4.传输层(Transport Layer) 主要功能:提供端到端的可靠数据传输,确保数据包按顺序到达目的地。该层还负责处理差错控制和流量控制等问题。传输单位:段(Segment)或报文(Message)。重要协议:TCP(Transmission Control Protocol,传输控制协议)、UDP(User Datagram Protocol,用户数据报协议)等。 5.会话层(Session Layer) 主要功能:建立、管理和终止会话,确保数据流的正确传输,如会话控制和同步。传输单位:会话(Session)。 6.表示层(Presentation Layer)

无人机反制:车载侦测干扰一体设备技术详解

车载侦测干扰一体设备是一种综合性的无人机反制解决方案,旨在有效应对各种复杂场景下的无人机威胁。 侦测技术: 1. 雷达侦测 - 脉冲雷达:通过发射短脉冲电磁波,根据回波的时间和强度来确定无人机的位置、速度和形状。 - 连续波雷达:包括调频连续波(FMCW)雷达,利用频率的变化来测量距离和速度,具有较高的分辨率和精度。 - 相控阵雷达:通过电子控制天线阵列的相位,实现快速扫描和多目标跟踪。 2. 无线电频谱侦测 - 宽带频谱监测:对宽频段进行实时扫描,捕捉无人机通信信号的频谱特征。 - 信号解调与分析:对侦测到的信号进行解调,提取通信内容和协议信息,以确定无人机的类型和工作模式。 - 频率捷变侦测:能够适应无人机通信频率的快速变化,确保有效侦测。 3. 光学侦测 - 可见光摄像机:采用高分辨率、高帧率的摄像机,配合图像识别算法,识别无人机的外形和特征。 - 长焦镜头:用于远距离观测和跟踪。 - 红外热成像:利用无人机飞行时产生的热量,在低光或无光条件下进行侦测。 4. 声学侦测 - 麦克风阵列:多个麦克风组成阵列,通过声波到达时间和强度的差异,计算声源方向和位置。 - 音频特征分析:分析无人机发动机和螺旋桨产生的特定声音频率和模式。 干扰技术: 1. 全频段阻塞式干扰 - 宽带干扰源:产生覆盖较宽频率范围的强干扰信号,全面阻断无人机的通信链路。 - 功率放大技术:确保干扰信号具有足够的强度,以有效覆盖目标区域。 2. 瞄准式干扰 - 数字信号处理(DSP)技术:精确生成与无人机通信信号频率和特征匹配的干扰信号。 - 自适应干扰算法:根据侦测到的无人机信号实时调整干扰参数,提高干扰效果。 3. 卫星导航信号干扰 - 伪卫星信号生成:模拟虚假的卫星导航信号,干扰无人机对真实卫星信号的接收。 - 窄带干扰:针对卫星导航频段进行精准的窄带干扰。 数据处理与融合: 1. 多传感器数据同步:确保来自不同侦测手段的数据在时间上的精确同步,以便进行准确的融合分析。 2. 数据滤波与去噪:采用各种滤波算法去除噪声和异常值,提高数据质量。 3. 目标识别与分类:运用机器学习和模式识别算法,对侦测到的目标进行自动识别和分类,区分无人机与其他飞行物体。 4. 态势感知与预警:将处理后的数据以直观的方式呈现给操作人员,提供实时的态势感知和预警信息。 定位与跟踪技术: 1. 多点定位:结合多个侦测点的数据,通过三角测量或多边测量算法确定无人机的精确位置。 2. 惯性导航辅助:利用车载设备自身的惯性导航系统,对目标的运动轨迹进行预测和修正。 3. 跟踪滤波算法:如卡尔曼滤波、粒子滤波等,对目标的位置和速度进行平滑估计和预测。 系统控制与操作: 1. 智能化操作界面:具备直观的图形用户界面(GUI),方便操作人员进行参数设置、模式选择和任务执行。

ubuntu22 部署zookeeper + kafka集群 & 配置开机自启动

ufw disabled #关闭防火墙 或者 放开指定端口 这里部署的是双节点:node1:10.3.1.96 , node2:10.3.1.97 #1.所有机器安装jdk apt install openjdk-8-jdk -y java -version #export JAVA_HOME=/usr/lib/jvm/jdk1.8.0_202 #2.部署zookeeper集群(这里使用的外置zookeeper) ps:也可以使用kafka内置zookeeper (kafka_2.13-3.7.0/bin/zookeeper-server-start.sh kafka_2.13-3.7.0/config/zookeeper.properties) cd /usr/local wget https://dlcdn.apache.org/zookeeper/zookeeper-3.8.4/apache-zookeeper-3.8.4-bin.tar.gz tar -zxvf apache-zookeeper-3.8.4-bin.tar.gz mv apache-zookeeper-3.8.4-bin zookeeper-3.8.4 cd /usr/local/zookeeper-3.8.4/conf && cp zoo_sample.cfg zoo.cfg mkdir -p /usr/local/zookeeper-3.8.4/logs mkdir -p /usr/local/zookeeper-3.8.4/data vim zoo.cfg tickTime=2000 initLimit=10 syncLimit=5 dataDir=/usr/local/zookeeper-3.8.4/data dataLogDir=/usr/local/zookeeper-3.8.4/logs clientPort=2181 #客户端访问zk的端口 server.1=10.3.1.96:2888:3888 server.2=10.3.1.97:2888:3888 #说明:2888为组成zookeeper服务器之间的通信端口,3888为用来选举leader的端口,server后面的数字与后面的myid相对应 #注意前后不要有空格 否则报错Invalid config, exiting abnormally 可以通过:set list显示隐藏字符来处理 vim /etc/profile export ZOOKEEPER_HOME=/usr/local/zookeeper-3.8.4 export PATH=$ZOOKEEPER_HOME/bin:$PATH source /etc/profile #10.

探索编程世界的乐趣:《C++青少年趣味编程108例》

💂 个人网站:【 摸鱼游戏】【网址导航】【神级代码资源网站】🤟 一站式轻松构建小程序、Web网站、移动应用:👉注册地址🤟 基于Web端打造的:👉轻量化工具创作平台💅 想寻找共同学习交流,摸鱼划水的小伙伴,请点击【全栈技术交流群】 探索编程世界的乐趣:《C++青少年趣味编程108例》 在当今数字化时代,编程已经成为一项重要的技能,不仅有助于未来的职业发展,更能培养青少年的逻辑思维和解决问题的能力。《C++青少年趣味编程108例》是一部专为青少年设计的编程教材,通过108个趣味案例,帮助他们轻松愉快地掌握C++编程基础。 为什么选择C++? C++是一门功能强大且灵活的编程语言,广泛应用于游戏开发、系统软件、嵌入式系统和高性能应用程序开发。学习C++可以为青少年提供坚实的编程基础,使他们在未来学习其他编程语言时更加得心应手。《C++青少年趣味编程108例》通过有趣的案例和项目,循序渐进地引导青少年了解和掌握C++编程。 教材亮点 案例丰富:书中包含了108个有趣的编程案例,涵盖了从简单的控制结构到复杂的数据结构和算法,每个案例都精心设计,既有趣又具有挑战性。全视频微课:每个案例都配有详细的视频讲解,青少年可以通过观看视频,直观地了解每一个编程步骤,这种学习方式不仅能够加深他们的理解,还可以提高学习的兴趣。实践为主:教材注重实践,通过动手编程,青少年可以在实际操作中巩固所学知识,逐步培养编程思维和解决问题的能力。循序渐进:从基础知识到高级概念,教材内容安排循序渐进,适合不同程度的学习者,通过逐步增加难度,使青少年能够稳步提升自己的编程水平。 具体案例示例 1. 猜数字游戏 这个游戏会随机生成一个1到100之间的数字,玩家需要通过猜测来找到这个数字。每次猜测后,程序会告诉玩家猜的数字是太大了还是太小了,直到玩家猜中为止。 #include <iostream> #include <cstdlib> #include <ctime> int main() { std::srand(std::time(0)); // 生成随机数种子 int number = std::rand() % 100 + 1; // 生成1到100之间的随机数 int guess = 0; int attempts = 0; std::cout << "欢迎来到猜数字游戏!" << std::endl; std::cout << "我已经想好了一个1到100之间的数字,你能猜到它是什么吗?" << std::endl; while (guess != number) { std::cout << "请输入你的猜测:"; std::cin >> guess; attempts++; if (guess < number) { std::cout << "

【送书活动十期】从零开始node.js制作CLI工具

这篇博客的由来是源于工作中一个java项目的配置项是加密后的私钥,私钥是由其他项目中调用web3生成随机账号得到的,而加密方法只是简单在java项目中执行代码得到。这便导致两步操作有点割裂,需要有一个脚本来完成生成私钥和加密私钥,减少重复操作且方便不同服务器执行。 【好看的灵魂千篇一律,有趣的鲲志一百六七!】- 可查看详情~~ 作者:鲲志说 (公众号、B站同名,视频号:鲲志说996) 后端研发:java、go,前电商、现web3 博客专家:阿里云社区、CSDN博客专家 超级个体:COC杭州开发者社区主理人 AI爱好者: AI电影共创社杭州核心成员 科技博主:极星会 星辉大使 目录 CLI工具是什么操作步骤创建项目创建可执行文件package.json中设置bin入口文件运行npm link发布到npm登录npm 通过命令安装CLI工具 至此,艺术已成书籍推荐书籍名称:《Ubuntu Linux运维从零开始学》内容介绍适合人群如何领书方式一 博客送书方式二 公众号送书方式三 粉丝群送书 自主购买 最后 由于是将java代码中的逻辑搬到了js上,所以考虑到了制作CLI工具 CLI工具是什么 CLI 工具,即命令行界面(Command-Line Interface)工具,是一种允许用户通过文本命令与计算机程序或操作系统交互的界面。CLI 工具通常在终端或控制台窗口中运行,用户输入文本命令来执行特定的操作或获取信息。 简单理解是一种通过命令行来在运行一些代码,来实现某些功能的工具或者应用。可以减少开发中的一些低级重复劳动,或者规范开发工作流,提高开发效率。 操作步骤 创建项目 创建一个新的项目目录 mkdir generateEthKeys 进入项目目录后,初始化npm npm init -y 创建可执行文件 可执行文件即真正的代码逻辑文件,如我是加解密的代码,则创建了generateEthKeys.js文件,代码内容不需要解释了,注释应该很清晰了。 #!/usr/bin/env node console.log('Hello, CLI world!'); const CryptoJS = require('crypto-js'); const Web3 = require('web3'); const web3 = new Web3(Web3.givenProvider || 'http://localhost:8545'); // AES 加密密钥,长度必须为16字节 const AES_KEY = 'kunzhiSayNodeCLI'; // 生成随机私钥 const account = web3.

C语言-链表

文章目录 🎯引言👓链表1.链表的概念与分类1.1链表的概念 :1.2链表的分类: 2.单链表(不带头节点的单向非循环链表)2.1概念与结构2.2单链表的实现 3.双向链表(带头节点的双向循环链表)3.1结构3.2双向链表的实现 4.顺序表和链表的对比4.1 存储结构4.2 内存管理4.3 适用场景 🥇结语 🎯引言 欢迎来到HanLop博客的C语言数据结构初阶系列。在这个系列中,我们将深入探讨各种基本的数据结构和算法,帮助您打下坚实的编程基础。本次我将为你讲解链表。链表是一种线性数据结构,它由一系列节点组成,每个节点包含数据和指向下一个节点的指针。由于其灵活的内存分配方式,链表在动态数据存储和处理方面有着独特的优势。在本篇文章中,我们将介绍链表的基本概念、链表的创建和操作方法,以及其优缺点。通过一些实际的代码示例,您将更好地掌握链表在C语言中的应用,从而为后续学习其他数据结构打下坚实的基础。 👓链表 1.链表的概念与分类 1.1链表的概念 : 链表是一种动态数据结构,由一系列节点(Node)组成。每个节点包含两部分:数据域(存储数据)和指针域(存储下一个节点的地址)。根据指针域的数量和方向 1.2链表的分类: 链表结构有很多种,如下图(2*2*2种): 1. 带头节点的单向非循环链表 带头节点的单向非循环链表在链表的开头有一个特殊的头节点,该头节点不存储实际数据,只用于指向第一个真正存储数据的节点。 特点: 增加了对链表操作的统一性,尤其是在链表为空或者操作第一个节点时更为方便。尾节点指针为NULL,表示链表的结束。 2. 带头节点的单向循环链表 带头节点的单向循环链表在链表的开头有一个头节点,尾节点的指针指向头节点,形成一个环。 特点: 可以从链表的任何一个节点回到头节点,形成一个闭环。常用于需要循环遍历的场景。 3. 带头节点的双向非循环链表 带头节点的双向非循环链表在链表的开头有一个头节点,每个节点有两个指针,分别指向前一个节点和后一个节点。 特点: 可以从链表的任何一个节点向前或向后遍历。尾节点的后指针为NULL,表示链表的结束。 4.带头节点的双向循环链表 带头节点的双向循环链表在链表的开头有一个头节点,每个节点有两个指针,尾节点的后指针指向头节点,头节点的前指针指向尾节点,形成一个环。 特点: 形成一个双向闭环,可以从链表的任何一个节点双向遍历回到头节点。常用于需要双向循环遍历的场景。 5. 不带头节点的单向非循环链表 不带头节点的单向非循环链表没有特殊的头节点,链表的第一个节点就是存储实际数据的节点。 特点: 节省了一个节点的内存,但在操作第一个节点时需要特殊处理。尾节点指针为NULL,表示链表的结束。 6. 不带头节点的单向循环链表 不带头节点的单向循环链表没有头节点,尾节点的指针指向第一个节点,形成一个环。 特点: 可以从链表的任何一个节点回到第一个节点,形成一个闭环。常用于需要循环遍历的场景。 7. 不带头节点的双向非循环链表 不带头节点的双向非循环链表没有头节点,每个节点有两个指针,分别指向前一个节点和后一个节点。 特点: 可以从链表的任何一个节点向前或向后遍历。尾节点的后指针为NULL,表示链表的结束。 8. 不带头节点的双向循环链表 不带头节点的双向循环链表没有头节点,每个节点有两个指针,尾节点的后指针指向第一个节点,第一个节点的前指针指向尾节点,形成一个环。 特点: 形成一个双向闭环,可以从链表的任何一个节点双向遍历回到第一个节点。常用于需要双向循环遍历的场景。 如此多的种类,我们下面只实现两种,单向链表(不带头节点的单向非循环链表)和双向链表(带头节点的双向循环链表)学会这两种之后其他种类的链表也可以自己去实现 2.单链表(不带头节点的单向非循环链表) 2.1概念与结构 概念: 不带头节点的单链表没有特殊的头节点,链表的第一个节点就是存储实际数据的节点。所有操作均直接作用于链表的第一个节点。 节点: 在链表(特别是单链表)中,节点是链表的基本组成单位。每个节点包含两个主要部分:数据域和指针域。下面是对节点的详细解释。 节点的定义 在C语言中,节点通常使用结构体(struct)来定义。一个典型的单链表节点结构如下: struct Node { int data; // 数据域,用于存储节点的数据 struct Node* next; // 指针域,用于存储指向下一个节点的指针 }; 节点的组成

【GraphRAG】微软 graphrag 效果实测

GraphRAG 本文将基于以下来源,对Microsoft GraphRAG分析优缺点、以及示例实测分析。 1. Source 代码仓库: Welcome to GraphRAGhttps://microsoft.github.io/graphrag/ 微软文章1(2024.2.13):GraphRAG: Unlocking LLM discovery on narrative private data Microsoft First Bloghttps://www.microsoft.com/en-us/research/blog/graphrag-unlocking-llm-discovery-on-narrative-private-data/ 微软文章2(2024.7.2):GraphRAG: New tool for complex data discovery now on GitHub Second Bloghttps://www.microsoft.com/en-us/research/blog/graphrag-new-tool-for-complex-data-discovery-now-on-github/ 论文: From Local to Globalhttps://arxiv.org/pdf/2404.16130 2. Advantages 使用新闻文章中的暴力事件信息(VIINA)数据集进行调查。选择此数据集是因为其复杂性以及存在不同意见和部分信息。这是一个混乱的现实世界测试用例,它是最近才出现的,不包括在LLM基础模型的训练中。 这里平分秋色,但是追加一步的提问,由于不存在对应的直接上下文,所以Baseline没检索到。 除了论文中提到的相对性比较之外,还使用SelfCheckGPT对可信度进行绝对测量,以帮助确保基于源材料的事实、连贯的结果。结果表明,GraphRAG的忠实度与基线RAG相似。 而在7月的文章中,再次强调: 当在社区层次结构的任何级别使用社区摘要时,GraphRAG在全面性和多样性方面都优于朴素的RAG(约70-80%的获胜率)。 使用中级和低级社区摘要的GraphRAG在这些指标上也比源文本摘要表现更好,token成本更低(每次查询约20-70%的令牌使用率)。性能与最高级别社区的分层源文本摘要具有竞争力,令牌成本大大降低(每次查询约2-3%的令牌使用率)。如图所示。 翻译一下就是: 问题:哪些公众人物在各种娱乐文章中被反复提及? 简单 RAG 回复 被反复提及的公众人物包括<公众人物1, 2, 3和4>。这些人物因各种原因被突出,从他们的职业成就到个人生活。 <公众人物1> [...]<公众人物2> [...]<公众人物3> [...]<公众人物4> [...] 这些人物因其高调的地位和公众对其职业和个人生活的兴趣而频繁被报道。他们的活动,无论是在音乐、体育还是个人关系中,都具有显著的文化和经济影响,媒体报道和公众反应证明了这一点。 GraphRAG 回复 娱乐行业广泛且多样,涵盖电影、电视、音乐、体育和数字媒体。某些公众人物由于在这些领域中的重要贡献和影响力而脱颖而出。以下总结了在各种娱乐文章中反复提及的重要人物,反映了他们在行业中的影响力和存在感。 演员和导演 [... 20个人物 ...]争议中的公众人物 [... 3个人物 ...]音乐家和高管 [.

UNIX中sigaction和sigevent有啥区别

sigaction和sigevent在UNIX和类UNIX系统(如Linux)的信号处理机制中扮演着不同的角色。 sigaction 功能: sigaction是一个用于查询或设置信号处理方式的函数。它允许进程为特定的信号指定一个信号处理函数,以及设置信号处理时的其他行为,如信号屏蔽和信号处理方式的重置。 参数: signum:指定要处理的信号编号。 act:指向sigaction结构体的指针,该结构体定义了信号处理的方式、信号屏蔽集以及信号处理的其他标志。 oldact:如果不为空,则用于保存对相应信号之前处理方式的描述。 返回值: 成功时返回0,失败时返回-1并设置errno以指示错误。 用途: sigaction主要用于细致地控制信号处理的行为,包括在信号处理函数执行期间哪些信号应该被阻塞,以及信号处理函数执行完毕后是否应该重置为默认行为等。 sigevent 功能: sigevent结构体主要用于与timer_create函数等系统调用配合使用,以定义定时器到期时应如何通知进程。它指定了定时器到期时是通过信号、线程还是其他方式通知进程。 成员: sigev_notify:指定通知方式,可以是SIGEV_NONE(不通知)、SIGEV_SIGNAL(发送信号)、SIGEV_THREAD(创建线程)等。 sigev_signo:当sigev_notify为SIGEV_SIGNAL时,指定发送的信号。 sigev_value:传递给通知函数的值,通常用于区分不同的定时器或信号源。 sigev_notify_function和sigev_notify_attributes:当sigev_notify为SIGEV_THREAD时,分别指定线程函数和线程属性。 用途: sigevent结构体主要用于设置定时器到期时的通知方式,特别是当需要通过发送信号来通知进程时。它允许进程为定时器指定一个特定的信号,以便在定时器到期时接收通知。 区别总结 功能不同: sigaction用于设置信号处理函数和其他信号处理行为,而sigevent用于定义定时器到期时的通知方式。 参数和返回值: sigaction接受信号编号和sigaction结构体指针作为参数,并返回操作结果; sigevent是一个结构体,用于timer_create等系统调用的参数,没有返回值。 用途不同: sigaction直接关联到信号处理机制,用于细致地控制信号处理的行为;sigevent则与定时器通知机制相关,用于定义定时器到期时如何通知进程

使用Java和Apache Kafka Streams实现实时流处理应用

使用Java和Apache Kafka Streams实现实时流处理应用 大家好,我是微赚淘客系统3.0的小编,是个冬天不穿秋裤,天冷也要风度的程序猿! 引言 实时流处理已经成为现代应用开发中不可或缺的一部分。Apache Kafka Streams是一个强大的库,它允许开发者使用Java来构建实时流处理应用程序,处理来自Kafka的数据流。本文将深入探讨如何使用Java和Apache Kafka Streams实现实时流处理应用,包括基本概念、核心API以及实际示例。 步骤1:准备工作 在开始之前,确保你已经安装了Java开发环境和Apache Kafka。此外,你还需要添加Apache Kafka Streams的依赖。 package cn.juwatech.example; import org.apache.kafka.common.serialization.Serdes; import org.apache.kafka.streams.StreamsBuilder; import org.apache.kafka.streams.StreamsConfig; import org.apache.kafka.streams.kstream.Consumed; import org.apache.kafka.streams.kstream.KStream; import org.apache.kafka.streams.kstream.Produced; import java.util.Properties; public class KafkaStreamsApplication { public static void main(String[] args) { Properties config = new Properties(); config.put(StreamsConfig.APPLICATION_ID_CONFIG, "my-streams-app"); config.put(StreamsConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092"); StreamsBuilder builder = new StreamsBuilder(); KStream<String, String> sourceStream = builder.stream("input-topic", Consumed.with(Serdes.String(), Serdes.String())); // 处理流数据 KStream<String, String> processedStream = sourceStream.mapValues(value -> value.

Navicat社区版终于来了!!!

前言 2024年6月26日,知名数据库管理工具 Navicat 推出了全新的免费版本——Navicat Premium Lite,专为小企业和初创公司打造。作为一款功能强大且易于使用的数据库管理解决方案,Navicat Premium Lite 现已正式上线 TitanIDE 模板市场,供广大用户学习和使用。在这篇文章中,我们将为您介绍如何在 TitanIDE 上使用 Navicat Premium Lite,以及在TitanIDE上使用Navicat多便捷,多安全。 一、使用 Navicat Premium Lite 使用 Navicat Premium Lite非常简单,只需几个步骤即可开始您的数据库管理之旅: 登录 TitanIDE:只需要打开 TitanIDE 并登录。 创建项目:在TitanIDE模板市场市场下载Navicat以后,创建项目,输入项目名,选择Nacivat,点击创建即可 二、新建连接 新建连接:进入Navicat以后,Navicat Premium Lite的操作跟本地客户端的Navicat是没有任何区别的 选择MySQL 输入链接名以及数据库密码,默认password 三、新建数据库 新建数据库:Navicat Premium Lite创建数据库的方式和本地客户端Navict同样没有任何差异 输入数据库名,选择编码格式 接下来将展示在TitanIDE使用Navicat有多便捷 新建查询,输入需求,打开TitanIDE智能助手,点击生成sql一键生成, 需求:创建一个学生信息表,字段名sno是主键代表学生的学号,sname是学生的姓名,sex是学生的性别,只有男女,sage是学生的年龄,sdept是学生的专业 生成后的sql语句,支持一键插入 CREATE TABLE student_info( sno INT PRIMARY KEY NOT NULL, sname VARCHAR(20) NOT NULL, sex CHAR(2) CHECK(sex IN ('男', '女')), sage INT NOT NULL, sdept VARCHAR(30) ); 接下来给新建的数据表添加数据,再次输入需求,同样一键生成sql语句

Python基础语法:注释和代码风格(PEP 8)详解③

文章目录 一、注释1.1 单行注释1.2 多行注释1.3 文档字符串(docstrings) 二、PEP 8代码风格2.1 缩进2.2 每行字符数限制2.3 空行2.4 引号2.5 空格2.6 注释2.7 命名约定2.8 其他建议 三、综合复杂示例四、结论 在编写Python代码时,注释和代码风格是两个至关重要的方面。良好的注释能够帮助开发者更好地理解代码,提高代码的可读性和可维护性;遵循Python的官方代码风格指南(PEP 8)可以使代码更加整洁、规范,便于团队协作。本文将详细介绍Python中的注释和PEP 8代码风格,并附上一个综合复杂的例子。 一、注释 注释是编程中的重要组成部分,用于解释代码的功能、逻辑或其他需要特别说明的地方。Python中主要有三种注释方式:单行注释、多行注释和文档字符串(docstrings)。 1.1 单行注释 单行注释使用 # 符号,适用于注释单行代码或在代码行末进行简单说明。单行注释应简洁明了,尽量避免冗长。 # 这是一个单行注释 x = 42 # 在代码行末的注释 1.2 多行注释 多行注释可以使用多个单行注释或使用三个连续的引号(单引号或双引号)。前者适用于简单的多行注释,后者适用于较长的注释或说明性文字。 # 这是多行注释的第一行 # 这是多行注释的第二行 """ 这是使用三个连续引号的多行注释 可以包含多行说明性文字 """ 1.3 文档字符串(docstrings) 文档字符串用于为模块、类和函数提供说明,通常使用三个双引号(""")包裹。文档字符串是Python官方推荐的注释方式,尤其在编写库和框架时,可以通过自动化工具生成文档。 def add(a, b): """ 计算两个数的和 参数: a (int, float): 第一个数 b (int, float): 第二个数 返回: int, float: 两数之和 """ return a + b 二、PEP 8代码风格 PEP 8是Python增强提案(Python Enhancement Proposal)之一,专门用于定义Python代码的风格指南。遵循PEP 8可以使代码更加规范、易读,便于团队协作。以下是PEP 8中的一些关键要点。

免费开源 | AI绘画 数字人工具合集大放送!六款超强AI数字人工具使用测评!

在数字化浪潮汹涌澎湃的今天,技术的飞速发展正以前所未有的方式重塑着我们的生活、工作与娱乐体验。其中,“数字人”作为这一时代浪潮中的璀璨明珠,正逐步从科幻电影走进现实,成为连接物理世界与数字世界的桥梁。 数字人,这一融合了人工智能、计算机图形学、深度学习、自然语言处理等多领域技术的产物,不仅拥有高度拟真的外观,更能实现智能交互、情感表达乃至自主学习,为教育、娱乐、零售、医疗等多个行业带来了革命性的变革。 咱们直接举个栗子:今年4月中旬,京东刘强东的数字人“采销东哥”亮相京东的直播间,不仅复刻了刘强东的语速、口音,习惯性动作也一模一样。 在讲话时偶尔搓动手指,强调某件事时会配合更大幅度的手部动作,还有时不时地点头等。围观网友表示,都不太能看得出这个东哥竟然是数字人! 这场首秀不到1小时,直播间观看量就超过了2000万,整场直播累计成交额超5000万。 这样巨大的收益,让很多人都开始关注数字人。要实现这样的效果,目前还是价值不菲,但AI技术持续在进步,开源领域产生的数字人也越来越强了! 1、Wav2lip Wav2Lip算法是一种基于深度学习的语音驱动面部动画生成算法,是最早期数字人运用的技术,该算法的核心思想是将语音信号中的信息映射到面部动画参数中,从而生成逼真的面部动画。 生成案例: 以下是使用Wav2Lip生成的数字人案例,可以看到其实只有嘴唇在活动,数字人的成熟度相对较差。 配置要求:Wav2Lip相对不太吃机器性能,只需要有4G小显存即可运行;生成1个1分钟左右的数字人视频,需要处理5~15分钟。 使用方法: 下载解压整合包,准备音频和视频文件,分别命名为“1.wav”和“1.mp4”,并放置在解压文件夹的根目录,双击“一键启动”等待即可。 02、SadTalk SadTalker是西安交通大学开源的一个项目,它通过从音频中学习生成3D运动系数,使用全新的3D面部渲染器来生成头部运动,可以实现图片+音频就能生成高质量的视频。 生成案例: 以下是使用SadTalker生成的数字人案例,效果相对Wav2Lip有一些进步,不再是只有嘴唇在动,而是头部有了一些动作。但仔细看在边缘部分会有错位的情况。 配置要求: 因为SadTalker生成的数字人效果好了一些,因此对机器配置的要求也有所提高,大概需要有6G显存的电脑可以流畅运行,显存小于6G或者使用CPU都会比较慢。生成1个1分钟左右的数字人视频,需要处理10~20分钟。 使用方法: 步骤可以拆分成三步:合成语音+照片生成+视频合成。 感兴趣的小伙伴,赠送全套AIGC学习资料,包含AI绘画、AI人工智能、数字人工具合集等前沿科技教程和软件工具,具体看这里。 03、MuseTalk MuseTalk是腾讯推出的一款数字人项目,支持实时音频驱动的唇部同步数字人,MuseTalk的核心技术能根据音频信号自动调整数字人物的面部图像,确保唇形与音频内容高度一致,只需输入音频,你的数字角色就能实现完美的口型同步。 生成案例: 以下是使用MuseTalk生成的数字人案例,效果相对SadTalker又有了一些进步,头部脸部动作更加自然,边缘部分的错位也有所缓解。但嘴唇动画方面,还是有些粗糙。 配置要求: 使用MuseTalk大概需要有6G显存的电脑可以流畅运行,生成1个1分钟左右的数字人视频,需要处理10~20分钟,跟SadTalker差不多。 使用方法: 1. 输入视频文件2. 输入音频文件3. 设置参数(一般默认参数即可) 04、Halo Hallo是一款由百度联手复旦大学、苏黎世联邦理工学院和南京大学共同研发的数字人项目,在音频驱动的肖像动画生成方面取得了令人瞩目的进展。它利用先进的AI技术,根据语音输入生成逼真且动态的肖像图像视频。这种技术通过分析语音输入,同步生成人像的面部动作,包括嘴唇、表情和头部姿势,最终呈现出效果惊艳的数字人。 生成案例: 以下是使用Hallo生成的数字人案例,无论是画面的清晰度、头部动作多样性、面部表情精细度方面,Hallo生成的数字人都相对于前面几个要好了很多。 配置要求: Hallo生成的数字人效果虽然好,但真的,它非常吃机器性能,据我的评测,需要10G显存以上的显卡才能跑得动。而且,生成1个1分钟左右的数字人视频,需要处理30~40分钟。 使用方法: 1. 输入视频2. 输入音频3. 设置各种参数:一般选择默认的参数即可4. 点击提交按钮 感兴趣的小伙伴,赠送全套AIGC学习资料,包含AI绘画、AI人工智能、数字人工具合集等前沿科技教程和软件工具,具体看这里。 05、LivePortrait LivePortrait是快手开源了一个让人惊艳的数字人项目,它的神奇之处在于,它不仅能够精确控制眼睛的注视方向和嘴唇的开合动作,还能处理多个人物肖像的无缝拼接。 生成案例: 以下是使用LivePortrait生成的数字人案例,可以看到数字人过渡非常平滑自然,不会产生任何突兀的边界效果。 配置要求: 相比Hallo,LivePortrait生成的数字人效果不但好,而且,对于配置要求也降低了很多,据我的评测,需要8G显存的显卡即可流畅运行,6G显存也可运行。生成1个1分钟左右的数字人视频,需要处理10~20分钟。 使用方法: 1. 输入图片2. 输入参考视频,主要是为了迁移控制数字人表情3. 点击提交按钮 06、EchoMimic 传统的数字人技术,要么依赖音频驱动,要么依赖面部关键点驱动,各有利弊。而EchoMimic则巧妙地结合了这两种驱动方式,通过音频和面部关键点的双重训练,实现了更加逼真、自然的动态肖像生成。 生成案例: 以下是使用EchoMimic生成的数字人案例,数字人相当平滑自然。 配置要求: EchoMimic生成的数字人,基本看不出是假人,可以说是相当真实了。而且它对于配置要求也没有增加,8G显存的显卡即可流畅运行。不过生成时长略微增加了,生成1个1分钟左右的数字人视频,大概需要处理15~30分钟。 使用方法: 1. 输入图片:选择你想要生成动态视频的肖像图片。2. 输入音频:提供与图片匹配的音频文件,EchoMimic会根据音频内容驱动肖像的动态效果。3. 设置参数:一般保持默认设置即可,当然,你也可以根据自己的需求进行调整。4. 点击提交按钮:接下来,就是见证奇迹的时刻。

ctfshow-web入门-php特性(web127-web131)

目录 1、web127 2、web128 3、web129 4、web130 5、web131 1、web127 代码审计: $ctf_show = md5($flag); 将 $flag 变量进行 MD5 哈希运算,并将结果赋值给 $ctf_show。 $url = $_SERVER['QUERY_STRING']; 获取当前请求的查询字符串(query string),查询字符串是 URL 中位于问号 (?) 之后的部分,通常包含一个或多个参数和值。 之后对查询字符串采用正则匹配过滤掉了一些符号,符合要求则会将 $_GET 数组中的键值对作为变量导入到当前的符号表中。换句话说,extract($_GET); 会将 URL 查询参数中的每个键值对转换成同名的变量。 最后要求 $ctf_show==='ilove36d' 就会输出 flag。 由于下划线被过滤掉了,我们采用非法字符参数名转换绕过,payload: ?ctf show=ilove36d 原本空格、点都是非法的,中括号也是可行的,但是中括号和点被过滤了,因此这里使用空格。 2、web128 代码审计: check($str) 函数检查字符串 $str 是否包含数字或字母,如果包含,返回 false,否则返回 true。 也就是说传入的 f1 不能包含大小写字母和数字。 var_dump(call_user_func(call_user_func($f1,$f2))); call_user_func 函数:用于调用指定的回调函数,并可以传递参数给该回调函数,第一个参数是被调用的回调函数,其余参数是回调函数的参数。 这里还进行了嵌套: (1)内层 call_user_func($f1, $f2) 首先调用 $f1 函数,并传递参数 $f2,结果是 $f1($f2) 的返回值。 (2)外层 call_user_func(...) 外层 call_user_func 接收内层调用的返回值作为它的第一个参数,要正确执行,内层返回值应该是一个函数名或可调用的回调,外层 call_user_func 将再次调用这个返回的回调函数,不传递任何额外的参数。

C语言中for、while、do while、break、continue、goto的使用方法

目录 一、while循环 二、for循环 三、do while循环 四:break和continue语句 break语句 continue语句 goto语句 今天介绍一下循环函数for、while、do while 然后再看一看break、continue、goto语句 循环结构是必须要学习好的,几乎所有代码都会应用到循环结构 一、while循环 while语句书写格式如下: while (表达式) { 语句; } 在使用while循环时,确保循环前已完成了初始化,并在循环体内适当地调整循环控制变量。 例题:使用while循环执行n行hello打印 int main() { int n = 0; scanf("%d", &n); while (n>0) { printf("hello\n"); n--; } return 0; } 代码意思:输入一个变量,如果输入的n大于0那么就执行while语句,直到n>0才执行,每循环一次函数,n就减一,因为 n-- 在 printf 函数的后面,所以无论是先减 n-- 还是后减,循环都能正常结束。” 二、for循环 for循环是使用最多的循环函数 for循环也是很简单的,语法如下: for(表达式1; 表达式2; 表达式3) { 语句; } 写for循环体我们必须写三个条件: 表达式1、初始化 。 表达式2、⽤于循环结束条件的判断。 表达式3、⽤于循环变量的调整 例题:使用for循环打印1-10。 int main() { int i = 0; for ( i = 1; i <=10; i++) { printf("

【数据结构】树和二叉树——Lesson1

Hi~!这里是奋斗的小羊,很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎 ~~ 💥💥个人主页:奋斗的小羊 💥💥所属专栏:C语言 🚀本系列文章为个人学习笔记,在这里撰写成文一为巩固知识,二为展示我的学习过程及理解。文笔、排版拙劣,望见谅。 目录 前言一、树1、树的概念和结构2、相关术语3、树的表示4、树形结构应用场景 二、二叉树1、概念和结构2、特殊的二叉树3、二叉树的存储3.1顺序存储3.2链式存储 4、顺序结构实现二叉树4.1堆的结构和概念4.2堆的实现4.2.1向上调整算法4.2.2向下调整算法 4.3堆的应用4.3.1堆排序4.3.2 TOP-K问题 5、完整代码 总结 前言 一、树 1、树的概念和结构 树是一种非线性的数据结构,它是由n(n>=0)个有限节点组成的一个具有层次关系的集合。它包含一个根节点以及若干子节点,子节点又可以有自己的子节点,以此类推。 根节点: 根节点没有前驱结点子节点: 除根节点外,其余节点被分为m(m>0)个互不相交的集合,其中每一个集合又是一棵结构与树类似的子树。每棵子树的根节点有且只有一个前驱节点,可以有0个或多个后继节点。因此,树是递归定义的。 与现实中的树相比,这里的树更像是一棵倒挂的树。 树形结构中,子树之前不能有交集,否则就不是树形结构。 非树结构: 子树是不相交的除了根节点,每个节点有且只有一个父节点一棵N个节点的树有N-1条边 2、相关术语 树有很多的术语,基本都是根据现实中的树和人类亲缘关系命名的,其中红色标记的是比较重要的概念。 父节点/双亲节点: 若一个节点有子节点,这个节点就是子节点的父节点(相对的),上图中A是B的父节点子节点: 一个节点含有的子树的根节点称为该节点的子节点,上图B是A的子节点节点的度: 一个节点有几个孩子,它的度就是多少树的度: 一棵树中,最大节点的度就是树的度,上图树的度为2叶子节点/终端节点: 度为0的节点称为叶子节点分支节点/非终端节点: 度不为0的节点兄弟节点: 具有相同父亲的节点就是兄弟节点(亲兄弟)节点的层次: 从根开始定义起,根为第一层,其子节点为第二层,以此类推树的高度/深度: 树中节点的最大层次,上图树的深度为5节点的祖先: 从根到该节点所经分支上的所有节点路径: 一条从树中任意节点出发,沿父节点-子节点连接,达到任意节点的序列子孙: 以某节点为根的子树中任意一节点都称为该节点的子孙森林: 由m (m>0)棵互不相交的树(多棵树)的集合称为森林 3、树的表示 树结构相对线性表复杂的多,既要保存值域,还要保存节点和节点之间的关系,最常用的表示法是左孩子右兄弟表示法。 struct TreeNode { struct Node* child;//左边开始的第一个孩子节点 struct Node* brother;//右边的下一个兄弟节点 int data; }; 4、树形结构应用场景 文件系统是计算机存储和管理文件的一种方式,它利用树形结构来组织和管理文件好文件夹。在文件系统中,树结构被广泛应用,它通过父节点和子节点之间的关系来表示不同层级的文件和文件夹之间的关联。 二、二叉树 1、概念和结构 二叉树是一种特殊的树,在树形结构中,我们最常用的就是二叉树,一棵二叉树是节点的一个有限集合,该集合由一个根节点加上两棵别称为左子树和右子树的二叉树组成或者为空。 上图就是二叉树的基本结构。从上图可以看到,二叉树有以下特点: 二叉树的特点: 二叉树不存在度大于2的节点二叉树的子树有左右之分,次序不能颠倒,因此二叉树是有序树 对于任意二叉树都是由以下几种情况复合而成的: 2、特殊的二叉树 满二叉树: 一个二叉树,如果每一层的节点数都达到最大值,则这个二叉树就是满二叉树。一个层数为N的满二叉树的节点数为2^N-1。完全二叉树: 完全二叉树的前N-1层都是满的,最后一层不满且子节点从左到右必须是连续的。完全二叉树是效率很高的数据结构,完全二叉树是由满二叉树引出来的,因此满二叉树是一种特殊的完全二叉树。 3、二叉树的存储 3.

【QT】鼠标按键事件 - QMouseEvent & QKeyEvent

qt 事件 事件1. 事件概念2. 事件的处理3. 按键事件(1)单个按键(2)组合按键 4. 鼠标事件(1)鼠标单击事件(2)鼠标释放事件(3)鼠标双击事件(4)鼠标移动事件(5)滚轮事件 事件 1. 事件概念 事件是应用程序内部或者外部产生的事情或者动作的统称。在 Qt 中使用⼀个对象来表⽰⼀个事件。所有的 Qt 事件均继承于抽象类 QEvent。事件是由系统或者 Qt 平台本⾝在不同的时刻发出的。当用户按下⿏标、敲下键盘,或者是窗⼝需要重新绘制的时候,都会发出⼀个相应的事件。⼀些事件是在用户操作时发出,如键盘事件、⿏标事件等,另⼀些事件则是由系统本⾝⾃动发出,如定时器事件。常见的 Qt 事件如下: 常见事件描述: 2. 事件的处理 事件处理⼀般常用的方法为:重写相关的 Event 函数。 在 Qt 中,几乎所有的 Event 函数都是虚函数,所以可以重新实现。如:在实现⿏标的进⼊和离开事件时,直接重新实现 enterEvent() 和 leaveEvent() 即可。enterEvent() 和 leaveEvent() 函数原型如下: 代码示例1: 1、新建 Qt 项目,基类选择 QWidget,同时勾选 UI 界面文件; 2、设计 UI 文件,在 ui 文件中拖入一个 Label,给 Label 加一个边界框,方便观察鼠标进入和移动,如下图; 3、在项目中新添加⼀个类:MyLabel; 先选中项⽬名称 qt_event,点击⿏标右键,选择 add new … ,弹出如下对话框: 接下来弹出以下界面,按照下面的操作即可: 此时项⽬中会新添加以下两个文件件: 4、将 enterEvent() 添加到项目文件 “mylabel.h” 中: #ifndef MYLABEL_H #define MYLABEL_H #include <QWidget> class MyLabel : public QWidget { Q_OBJECT public: explicit MyLabel(QWidget *parent = nullptr); // 鼠标进入事件 void enterEvent(QEvent* event); signals: }; #endif // MYLABEL_H 5、在 mylabel.

【多线程】线程安全的单例模式

文章目录 什么是单例模式饿汉实现方式饿汉实现模式的特点 懒汉实现方式懒汉实现方式的特点 什么是单例模式 单例模式是一个设计模式,其目的是确保一个类只有一个实例,并提供一个全局的访问点来访问该实例。单例模式常用于需要控制资源数量的场景,比如数据库连接池、日志管理器等。下面介绍常见的单例模式的实现方式。 饿汉实现方式 观察下面代码: class EagerSingleton { private: // 私有构造函数,防止外部实例化 EagerSingleton() {} // 禁用拷贝构造函数和赋值运算符 EagerSingleton(const EagerSingleton&) = delete; EagerSingleton& operator=(const EagerSingleton&) = delete; // 静态实例,类加载时初始化 static EagerSingleton instance; public: // 提供全局访问点 static EagerSingleton& getInstance() { return instance; } }; // 初始化静态实例 EagerSingleton EagerSingleton::instance; 要想实现单例,从两个方面入手:1.如何实现禁止构造2个或者2个以上的实例化对象。2.如何实现只构造一个对象。 对于前者,我们可以将构造函数私有化,这样就不能在类外部构造对象了。那怎么保证拥有一个实例化对象呢?这一点可以在类中使用static修饰一个该类的实例对象,这样就能在程序加载的时候自动创建一个实例化对象,由于static成员属于类本身的特性,所以能使用私有的构造函数,且只会加载一次。 要想使用这个单例,就需要一个static修饰的成员方法专门用来提供全局的访问点,因为static成员函数可以直接通过类名使用,不需要创建实例化对象。 此外静态成员变量需要在类外部初始化。 饿汉实现模式的特点 类加载的时候实例化私有化构造函数线程安全:由于实例化是在类加载的时候完成的,且类加载的过程中由C++标准保证了线程安全,因此不需要额外的同步机制来保证线程安全。 懒汉实现方式 观察下面代码 class LazySingleton { private: // 私有的静态指针变量,用于指向唯一的实例 static LazySingleton* instance; // 私有构造函数,防止外部实例化 LazySingleton() {} public: // 提供全局访问点 static LazySingleton* getInstance() { if (instance == nullptr) { instance = new LazySingleton(); } return instance; } }; // 初始化静态指针变量 LazySingleton* LazySingleton::instance = nullptr; 注意其中和饿汉实现方式的区别,懒汉实现单例模式中static修饰的是一个实例对象的指针。这样一来,类加载的时候就不会构造自动一个实例化对象。具体的观察这一段代码:

基于C语言从0开始手撸MQTT协议代码连接标准的MQTT服务器,完成数据上传和命令下发响应(华为云IOT服务器)

文章目录 一、前言二、搭建开发环境三、网络编程基础概念科普3.1 什么是网络编程3.2 TCP 和 UDP协议介绍3.3 TCP通信的实现过程 四、Windows下的网络编程相关API介绍4.1 常用的函数介绍4.2 函数参数介绍4.3 编写代码体验网络编程 五、访问华为云IOT服务器创建一个产品和设备5.2 开通物联网服务5.3 创建产品(1)创建产品(2)填写产品信息(3)产品创建成功(4)添加自定义模型 3.4 添加设备(1)注册设备(2)根据自己的设备填写(3)保存设备信息 3.5 MQTT协议主题订阅与发布(1)华为云平台MQTT协议使用限制(2)主题订阅格式(3)主题发布格式 3.6 MQTT三元组(1)MQTT服务器地址(2)生成MQTT三元组(3)MQTT登录测试参数总结 六、开始学习MQTT协议6.1 先了解下MQTT协议6.2 MQTT协议官网介绍6.3 需要实现的3个函数6.4 查看协议文档,了解如何组合协议报文6.5 实现`MQTT_Connect`函数【1】固定报文头【2】协议名【3】协议级别【4】连接标志【5】保持连接的时间【6】 可变报头非规范示例【7】最后部分:填写客户端ID、用户名、密码。【8】响应【9】完整代码 6.6 实现MQTT_PublishData函数【1】查看文档说明【2】固定报文头【3】剩余字段长度【4】可变报头【5】完整代码【6】发布确认 6.7 实现 MQTT_SubscribeTopic 函数【1】查看文档:订阅主题的格式【2】查看文档:取消订阅的格式【3】固定报头【4】可变报头【5】完整代码 七、运行项目、连接华为云服务器7.1 整个项目的完整代码7.2 代码里核心的地方7.3 编译运行代码7.4 登录华为云IOT云端查看数据 八、下发命令的处理8.1 添加命令8.2 下发命令测试8.3 编写代码8.4 运行代码测试 九、总结 从0开始编写MQTT协议代码连接标准MQTT服务器(精讲MQTT协议) 一、前言 近年来,物联网的发展如火如荼,已经渗透到我们生活的方方面面。从智能家居到工业自动化,从智慧城市到智慧农业,物联网正在以前所未有的速度改变着我们的生活。 大家现在可能已经习惯了通过手机控制家里的灯光、空调和电视,这就是物联网在智能家居领域的应用,如果在10年前看到这种设备的应用肯定觉得很牛批,而现在只要是个设备都能上云,这种家电设备的远程控制已经成了大家习以为常的配置了。而在工业领域,物联网技术可以帮助企业实现自动化生产、设备监控和预防性维护,提高生产效率和产品质量。在智慧城市建设中,物联网技术可以用于交通管理、环境监测和公共安全等方面,提升城市管理和居民生活的质量。 从物联网开始兴起的时候,各大厂家都纷纷推出了自家的IOT物联网平台。 比如: 机智云、中国移动的onenet、阿里云的IOT、百度的天工物接入、华为云的IOT、腾讯云IOT等等。 这些大厂家的物联网服务器都支持标准的MQTT协议接入,大家不用自己搭建MQTT服务器可以直接使用这些现成的服务器接入设备开发是非常的方便的。 我在这几年也写了很多物联网开发的案例,不管是、中国移动的onenet、阿里云的IOT、百度的天工物接入、华为云的IOT、腾讯云IOT 这些服务器都写了很多教程,演示设备接入平台,完成设备上云,手机APP对接,电脑程序对接,微信小程序接入,实现远程数据监测控制等等。这些案例都放在了智能家居与物联网项目实战专栏里。 这些案例里设备实现上云的方式主要是两种方式:HTTP协议、MQTT协议方式上云。 MQTT协议是标准的物联网协议,支持双向数据传输,也就是可以上传数据到服务器,也可以接收服务器下发的控制命令完成远程控制。 我写的这些案例里硬件端联网的模块主要是用到了4G模块、ESP8266-WIFI模块、GSM模块、NBIOT模块等等,通过它们联网,让单片机设备实现上云。 这些设备中有些是支持MQTT协议的(也就是本身的固件就支持MQTT协议),有些不支持的(可能有固件支持,需要自己烧写)。 如果说固件不支持MQTT协议,但只要设备支持TCP协议,那么我们也可以自己封装MQTT协议完成与MQTT服务器之间的通信。 比如:ESP8266-WIFI模块,正常的官方默认固件中,ESP8266-WIFI是不支持MQTT协议的,如果我们不烧写固件的情况下,如何自己实现MQTT协议上云? 这篇文章就介绍,通过TCP协议自己封装MQTT协议报文,完成数据上云。 直接从0开始手撸MQTT协议报文,组合报文,完成与服务器之间的通信。 MQTT协议也是分为两种,分MQTT和MQTTS,就像HTTP协议一样也分HTTP和HTTPS,那么区别呢? 带S就是要支持SSL协议,支持认证,更加安全,那么复杂度自然就上来了。 MQTT协议的端口是1883,MQTTS的端口是8883。 当前这篇文章介绍非加密的MQTT协议,也就是1883端口。MQTTS协议也手撸不了,这玩意涉及到SSL协议,那就很复杂了,如果要用,直接使用现成的开源库就行,但本篇文章不讨论这个,后面文章再单独介绍如何实现MQTTS协议。 本篇文章的环境是在windows下,利用VS2022开发程序,使用windows下网络编程接口作为基础,封装MQTT协议连接华为云MQTT服务器,完成数据上云。 所以,大家只要有一台windows电脑,电脑上安装了VS开发环境,任何版本都可以(VS2010、VS2013、VS2015、VS2017、VS2019、VS2022等等都可以的) 跟着这篇文章进行学习,不需要其他任何硬件设备,我们现在是单纯的去学习MQTT协议。

Python分布式机器学习全指南:框架、优化与未来趋势

本文收录于专栏:精通AI实战千例专栏合集 https://blog.csdn.net/weixin_52908342/category_11863492.html 从基础到实践,深入学习。无论你是初学者还是经验丰富的老手,对于本专栏案例和项目实践都有参考学习意义。 每一个案例都附带关键代码,详细讲解供大家学习,希望可以帮到大家。正在不断更新中~ 一.Python分布式机器学习全指南:框架、优化与未来趋势 分布式机器学习在处理大规模数据和训练复杂模型时变得越来越重要。本文将介绍如何在Python中实现分布式机器学习,包括使用一些流行的分布式计算框架,如Dask、Apache Spark和TensorFlow。 一、为什么需要分布式机器学习? 数据规模:随着数据规模的不断增长,单节点计算资源无法满足需求。计算复杂度:复杂的模型(如深度学习模型)的训练需要大量计算资源。时间效率:分布式计算能够加快训练速度,减少训练时间。 二、分布式计算框架 1. Dask Dask是一个灵活的并行计算库,旨在使大数据处理变得简单。它能让你在本地计算机上模拟分布式环境,也能扩展到多节点集群。 安装 pip install dask[complete] 基本用法 import dask.array as da # 创建一个10000x10000的随机矩阵 x = da.random.random((10000, 10000), chunks=(1000, 1000)) # 计算矩阵乘法 y = x @ x.T # 计算结果 result = y.compute() 2. Apache Spark Apache Spark是一个快速、通用的分布式计算系统,特别适合大数据处理和机器学习任务。 安装 pip install pyspark 基本用法 from pyspark.sql import SparkSession # 创建SparkSession spark = SparkSession.builder.appName("Distributed ML").getOrCreate() # 创建DataFrame data = spark.createDataFrame([(1, 'Alice', 50), (2, 'Bob', 40)], ['id', 'name', 'age']) # 展示数据 data.

前端GIS开发详细指南

前端GIS(地理信息系统)开发是一个融合了地理信息和前端开发技术的领域,主要用于在网页上展示和操作地理空间数据。本文将详细介绍前端GIS开发的关键技术和工具,以及如何使用这些工具来创建交互式地图和地理应用。 一、前端GIS开发的基础 1. 地理信息系统简介 GIS是用于捕捉、存储、管理、分析和展示地理空间数据的系统。它结合了地理科学、计算机科学和信息科学,用于解决与地理位置相关的问题。 2. 前端GIS开发的核心技术 HTML/CSS:用于创建和美化网页结构和布局。JavaScript:用于实现交互功能和数据处理。Web地图库:例如Leaflet、OpenLayers和Mapbox GL JS,用于在网页中展示和操作地图。GIS数据格式:如GeoJSON、Shapefile,用于存储和传输地理空间数据。 二、常用的前端GIS开发工具 1. Leaflet Leaflet是一个轻量级的开源JavaScript库,用于在网页上展示交互式地图。它具有简单易用、插件丰富等特点,适合中小型GIS应用。 安装和基本使用 <!DOCTYPE html> <html> <head> <title>Leaflet Map</title> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="https://unpkg.com/leaflet/dist/leaflet.css" /> <style> #map { height: 600px; } </style> </head> <body> <div id="map"></div> <script src="https://unpkg.com/leaflet/dist/leaflet.js"></script> <script> var map = L.map('map').setView([51.505, -0.09], 13); L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution: '&copy; OpenStreetMap contributors' }).addTo(map); </script> </body> </html> 2. OpenLayers OpenLayers是另一个强大的开源JavaScript库,用于创建复杂和定制化的地图应用。它比Leaflet更强大,适合大型GIS应用。 安装和基本使用 <!DOCTYPE html> <html> <head> <title>OpenLayers Map</title> <meta charset="