《无所不能的JavaScript · 异步编程》

📢 大家好,我是 【战神刘玉栋】,有10多年的研发经验,致力于前后端技术栈的知识沉淀和传播。 💗 🌻 CSDN入驻不久,希望大家多多支持,后续会继续提升文章质量,绝不滥竽充数,欢迎多多交流。👍 文章目录 写在前面的话JavaScript 异步编程技术简介回调地狱Promiseasync、await其他用法 总结陈词 写在前面的话 异步编程允许我们在执行一个长时间任务时,程序不需要等待,而是继续执行之后的代码,直到任务完成后再通知你,通常是以回调函数的形式。 这种编程模式,避免了程序的阻塞,提高了CPU的执行效率,用户体验得到了提升。 以 Java 中异步编程为例,其用法丰富多彩,可以利用JUC等各种工具方法实现多线程效果,以此提升系统系统,比如下面示例代码。 自定义一个 Callable 接口,利用线程池提交,返回 Future 对象,通过调用 get 方法阻塞等待结果。 Future<?> future = executorService .submit(new MyCallable()); System.out.println("结果为:" + future.get()); 回到正题,接下来介绍一下 JavaScript 中异步编程的运用,让我们开始。 JavaScript 异步编程 技术简介 JavaScript从设计之初就是一个单线程的编程语言,浏览器无论在什么时候都有且只有一个线程在运行JavaScript程序,即同一时间只执行一条代码,所以每一个JavaScript代码执行块会“阻塞”其它异步事件的执行。 但依然不能阻止JavaScript实现异步编程效果,来一段示例代码: setTimeout(() => { console.log('Hello World') }, 1000) console.log('123') 很明显,先输出123,再输出Hello World,这里可以看一下之前的这篇博文:《setTimeout 简笔》 JavaScript的单线程的异步编程方式其实有诸多优点,由于所有操作都运行在同一个线程中,无须考虑线程同步和资源竞争的问题,从源头上避免了线程之间的频繁切换,降低了线程自身的开销。 回调地狱 JS 中常见的异步场景,除了 setTimeout,还有 AJAX、Axios、Fetch 等远程数据获取,都是利用回调函数实现异步效果。 回调函数虽然方便,但它有一个明显的缺点。 如果我们需要依次执行多个异步操作,代码可能变成下面这样,典型的“向右编程”,可读性和可控性都很差。 setTimeout(() => { console.log('Hello World') setTimeout(() => { console.log('Hello World') setTimeout(() => { console.

【数据分享】2013-2022年我国省市县三级的逐日SO2数据(excel\shp格式\免费获取)

空气质量数据是在我们日常研究中经常使用的数据!之前我们给大家分享了2000——2022年的省市县三级的逐日PM2.5数据和2013-2022年的省市县三级的逐日CO数据(均可查看之前的文章获悉详情)! 本次我们分享的是我国2013——2022年的省市县三级的逐日SO2数据,数据包括excel和shp两种数据格式,数据单位为µg/m3,数据坐标为WGS1984!该数据是基于之前分享的2013-2022年全国范围逐日SO2栅格数据(详情可查看之前分享的文章),依据行政边界数据(包括全国省份行政边界、地级市行政边界、区县行政边界),合计行政边界内每日SO2的平均值得到的。 大家可以在公众号回复关键词 254 免费获取该数据!无需转发文章,直接获取!以下为数据的详细介绍: 01 数据预览 ①省份层级的逐日SO2数据 首先,我们先来看看省份层级的逐日SO2数据,数据包括Excel和Shp两种格式! 需要说明的是: 2013至2022年的所有天数的逐日SO2数据汇总在一个Excel文件中,由于单个Shp文件能支持的字段有限制,所有年份的数据没办法保存到一个Shp文件中,因此每个年份的逐日SO2数据保存为一个Shp文件,每个Shp文件的属性表中包括当年的365天每天的SO2数据。地级市和区县同理! 我们以2022年1月1号——1月15号为例,来预览一下省份层级Excel格式的逐日SO2数据,数据字段包括省份名称、省份代码和每日SO2: 下面我们再以2022年6月1号的数据为例,来预览一下省份层级Shp格式的逐日SO2数据: ②地级市层级的逐日SO2数据 下面我们来看看地级市层级的逐日SO2数据,数据包括Excel和Shp两种格式! 我们先以2022年1月1号——1月15号为例,来预览一下地级市层级excel格式的逐日SO2数据,数据字段包括城市名称、城市代码、省份名称、省份代码和每日SO2: 下面我们再以2022年6月1号的数据为例,来预览一下地级市层级Shp格式的逐日SO2数据: ③区县层级的逐日SO2数据 下面我们来看看区县层级的逐日SO2数据,数据包括Excel和Shp两种格式! 我们先以2022年1月1号——1月12号为例,来预览一下地级市层级Excel格式的逐日SO2数据,数据字段包括区县名称、区县代码、城市名称、城市代码、省份名称、省份代码和每日SO2: 下面我们再以2022年6月1号的数据为例,来预览一下区县层级Shp格式的逐日SO2数据: 02 数据详情 数据来源: 原始数据来源于美国马里兰大学韦晶博士、李占清教授团队在国家青藏高原科学数据中心平台上分享的数据! 数据处理说明: 基于上述原始数据,我们采用国家地理信息公共服务平台(天地图)发布的审图号为GS(2024)0650号的2024年省市县三级行政区划Shp数据(可查看之前发布的文章),分别汇总各个省份(地级市和区县同理)内所有栅格日SO2的平均值,最终得到每个省份(地级市和区县同理)的日SO2数据。 时间范围: 2013-2022年(逐日) 空间范围: 省/市/县 数据格式: Excel/Shp 数据单位: ug/m3 数据坐标: WGS_1984 数据引用: 韦晶, 李占清. (2023). 中国高分辨率高质量地面SO2数据集(2013-2022). 国家青藏高原数据中心. https://doi.org/10.5281/zenodo.4641538. Wei, J., Li, Z. (2023). ChinaHighSO2: High-resolution and High-quality Ground-level SO2 Dataset for China (2013-2022). National Tibetan Plateau / Third Pole Environment Data Center. https://doi.org/10.5281/zenodo.4641538.

Vue从零到实战

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 非常期待和您一起在这个小小的网络世界里共同探索、学习和成长。💝💝💝 ✨✨ 欢迎订阅本专栏 ✨✨ 前言 本栏目是根据黑马程序员的网课来整理的笔记,也会结合我的一些个人见解,来记录自己学习Vue的过程,俗话说,好记性不如烂笔头,小郑喜欢在学习的过程中记笔记,记下自己在学习过程中难以理解的知识点,反复练习,加深印象,小郑打算在这个暑假的第一个月学习完Vue从0到1实现项目,希望广大网友一起监督学习,互相进步! 自定义指令 1.指令介绍 内置指令:v-html、v-if、v-bind、v-on... 这都是Vue给咱们内置的一些指令,可以直接使用 自定义指令:同时Vue也支持让开发者,自己注册一些指令。这些指令被称为自定义指令 每个指令都有自己各自独立的功能 2.自定义指令 概念:自己定义的指令,可以封装一些DOM操作,扩展额外的功能 3.自定义指令语法 全局注册 //在main.js中 Vue.directive('指令名', { "inserted" (el) { // 可以对 el 标签,扩展额外功能 el.focus() } }) 局部注册 //在Vue组件的配置项中 directives: { "指令名": { inserted () { // 可以对 el 标签,扩展额外功能 el.focus() } }} 使用指令 注意:在使用指令的时候,一定要先注册,再使用,否则会报错 使用指令语法: v-指令名。如:<input type="text" v-focus/> 注册指令时不用加v-前缀,但使用时一定要加v-前缀 4.指令中的配置项介绍 inserted:被绑定元素插入父节点时调用的钩子函数 el:使用指令的那个DOM元素 自定义指令-指令的值 1.需求 实现一个 color 指令 - 传入不同的颜色, 给标签设置文字颜色 2.语法 1.在绑定指令时,可以通过“等号”的形式为指令 绑定 具体的参数值 <div v-color="

ARP概述学习笔记

1.了解数据链路层 数据链路层位于网络层和物理层之间,可以向网络层的IP、IPv6等协议提供服务。数据链路层的PDU(ProtocolDataUnit-协议数据单元)被称为Frame(帧),也可称为数据帧。 以太网(Ethernet)是最常见的数据链路层协议。 以太网通常封装的是MAC: 例如:以太网封装---实验PC1 ping PC2 (1)配置PC1和PC2。 (2)在R1路由器上配置PC1和PC2的网关信息。 (3)右击PC1的Ethernet0/0/1端口,点击“开始抓包”,接着在PC1上去ping PC2,抓取到的报文显示二层的以太网通过封装MAC进行下一步通信的。 但并不是所有的二层封装的是MAC。 例如:二层使用PPP协议通信 实验R1与R2通过配置PPP协议进行ping抓包分析 (1)配置R1和R2,并且在Serial 0/0/0接口上启用ppp协议。 (2)右击R1的Serial0/0/0接口,点击“开始抓包”,弹窗出来选择链路类型PPP,接着点击“确定”,回到R1上去ping R2,抓取到的报文显示二层为PPP协议而不是以太网,因此封装的内容也不是MAC。 2.以太网与MAC地址 2.1以太网的定义 (1)以太网是一种广播式数据链路层协议,支持多点接入。 (2)个人电脑的网络接口遵循的就是以太网标准。 (3)一般情况下,一个广播域对应着一个IP网段。 2.2以太网MAC地址 (1)MAC (Media Access Control)地址在网络中唯一标识一个网卡,每个网卡都需要且会有唯一的一个MAC地址。 (2)MAC用于在一个IP网段内,寻址找到具体的物理设备。 (3)工作在数据链路层的设备。例如以太网交换机,会维护一张MAC地址表,用于指导数据帧转发。 3.地址解析协议(ARP) ARP (Address Resolution Protocol)地址解析协议: 根据已知的IP地址解析获得其对应的MAC地址。 主机A知道主机B的IP地址,但是不知道主机B的MAC地址,如果想要和主机B进行通信,需要知道主机B的MAC地址,前提是主机A和主机B要在同一个网段,如果不在同一个网段的话,主机A就要找网关,请求到网关的MAC就可以了。 4.ARP实验 4.1通过Cisco Packet Tracer实验环境去模拟理解ARP的工作原理 (1)拓扑搭建 (2)配置PC0、PC1、PC2和PC3的网卡信息,设置的IP都在同一个网段内,因此不需要配置网关。 (3)配置完之后,通过PC0访问PC1,检查ping是否联通。 结果ping通了,ARP只有在第一次访问的时候才能产生,一旦得到了对方的MAC地址,它就会缓存在自己的本地ARP缓存表里面。下次要去访问PC1的时候就可以直接在缓存表里面找到PC1的MAC。 查看ARP缓存表可以使用命令arp -a 删除ARP缓存表信息可以使用命令arp -d (4)通过模拟状态去查看ARP工作过程 接着让PC0访问PC2,PC2和PC0没有进行过通信,PC2的ARP缓存表默认是空的。 在PC0 ping PC2 把鼠标悬停在第一个报文上,可以看到是ICMP的报文 接着把鼠标悬停在第二报文上,可以看到是ARP的报文 Ping包为什么不能直接发出去?在同一网段的PC0和PC2通信,PC0知道PC2的IP地址,但是不知道PC2的MAC,所以需要先发送ARP报文去获得目标的目的MAC。 点击“播放按钮”,PC0会把报文发送到交换机上,到达交换机上,点击“暂停”。 点击交换机上的报文,可以看到这个是ARP的请求包,这个包最大的特点就是广播,它的目的MAC是全F。也就是说,会先发送一个ARP request。 因此,交换机会将这个包进行泛洪处理。点击“播放”,等报文到达PC1、PC2和PC3之后,点击“暂停”。泛洪后,PC1、PC2和PC3得到报文,PC1和PC3得到后会丢弃掉,PC2则会进行响应。 为什么PC2能响应呢?因为这个请求包里面,它指明了要192.168.1.3的MAC,所以不是192.168.1.3的MAC就会被丢弃。 PC2收到ARP请求报文之后,回复一个响应。点击PC2回到交换机的包,可以看到出站PDU详细信息回给PC0它的MAC信息。 PC0收到PC2发送回来的报文,就会缓存PC2的MAC地址。这个时候ping包就组建好了。 这样一来Ping包的二层目的MAC就封装了PC2的MAC,接着就行了ping 在ARP响应之后,就会缓存到对方的MAC 注意:ARP Request 报文是目的MAC为全F的广播报文。

数据结构----栈

前言 Hello,小伙伴们,今天我们继续数据结构的学习,前面我们学习了顺序表和链表的实现,今天的栈知识也是和前面的知识相辅相成。 如果你喜欢我的内容的话,就请不要吝啬自己手中的三连哟,万分感谢!!好,废话不多说,开始我们今天的正题。 1.栈的概念和结构 栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素的操作。进行数据插入和数据删除的一端,我们称之为栈顶,另一端我们称之为栈底。栈中的数据元素遵守后进先出的原则(Last In First Out) 压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶; 出栈:栈的删除操作就叫做出栈。出数据也在栈顶。 栈的底层结构选型: 栈的实现一般可以使用数组或者链表,相对而言数组的结构要更加的简洁。因为数组在尾上插入数据的代价比较小。 2.栈的实现 更前几期的数据结构实现一样,我们还是先在VS2022上创建三个文件: 2.1 栈的定义: 前面我们说到,栈的底层结构我们采用数组的方式是最好的,所以我们可以怎样来定义栈呢? 诶,我们是不是可以想到我们之前学习过的顺序表呢,他们们的底层逻辑都可以通过数组来实现,整体功能大同小异。 那我们就来试试这样定义栈的结构: typedef int SDataType; typedef struct Stack { SDataType* arr; int capacity; int top; }stack; 而在实现栈的功能时我们只要注意,栈的数据插入和数据删除都只是在一端进行就好了!! 2.2 栈的初始化 初始化栈,我们应当怎么来做呢? 我们先来看实现该功能的函数: 2.2.1 void InitStack(stack* ps)函数的定义和实现 /首先实现栈的初始化 void InitStack(stack* ps); 看到这这里有没有人觉得很熟悉呢? 对,其实这里的初始化就是和顺序表的初始化一样的所以开始的时候,我们需要 将 ps->arr置为NULL ps->capacity = ps->top = 0; 函数我们就可以这样实现: //首先实现栈的初始化 void InitStack(stack* ps) { assert(ps); ps->arr = NULL; ps->capacity = ps->top = 0; } 2.

适配器模式

文章目录 适配器模式适配器模式的角色类适配器案例代码被适配者目标接口适配器客户端使用 对象适配器案例代码适配器客户端 接口适配器案例代码接口抽象适配器客户端 适配器模式 适配器模式,客户端通过适配器返回客户端期望的接口。其中适配器将被适配者转化为客户端期望的接口。 比如充电,插座的电压为 220V(被适配者),手机(客户端)通过充电器(适配器)将插座的电压降到 5 V(目标接口)传输电压给手机(客户端)。 种类:类适配器,接口适配器,对象适配器。 适配器模式的角色 客户端:通过适配器访问目标接口适配器被适配器目标接口 类适配器 适配器 adapter 必须继承被适配者,实现目标接口。 案例 代码 被适配者 /** * 被适配者 * * @author: Hui **/ public class Adaptee { public String method(){ System.out.println("调用被适配者方法"); return "被适配者方法"; } } 目标接口 /** * 目标对象 * * @author: Hui **/ public interface ITarget { public String method1(); } 适配器 /** * 适配器 * * @author: Hui **/ public class Adapter extends Adaptee implements ITarget{ @Override public String method1() { //适配器方法,将原有的方法进行适配 System.

配置Hive元数据存储到MySQL

文章目录 配置Hive元数据存储到MySQL背景介绍配置步骤1) 在MySQL中新建 Hive 元数据库2) 将MySQL的JDBC驱动拷贝到Hive的lib目录下3) 更新guava包和hadoop一致4) 在$HIVE_HOME/conf目录下新建hive-site.xml文件5) 初始化Hive元数据库(修改为采用MySQL存储元数据)6) 验证是否成功配置 配置Hive元数据存储到MySQL 背景介绍 在安装完Hive之后,需要将Hive的元数据写入到MySQL的metastore数据库。 如果说MySQL中缺乏了关于Hive的相关配置,Hive是无法正常启动和运行的。 如果说MySQL进行重装,则需要对Hive服务进行重新的配置。 配置步骤 1) 在MySQL中新建 Hive 元数据库 #登录MySQL [atguigu@hadoop102 software]$ mysql -uroot -p123456 #创建Hive元数据库 mysql> create database metastore; mysql> quit; 2) 将MySQL的JDBC驱动拷贝到Hive的lib目录下 cp /opt/download/mysql-connector-j-8.0.33.jar lib/ 3) 更新guava包和hadoop一致 ls lib/|grep guava # guava-19.0.jar rm -f lib/guava-19.0.jar find /opt/software/hadoop313/ -name guava* #/opt/software/hadoop313/share/hadoop/common/lib/guava-27.0-jre.jar #/opt/software/hadoop313/share/hadoop/hdfs/lib/guava-27.0-jre.jar cp /opt/software/hadoop313/share/hadoop/hdfs/lib/guava-27.0-jre.jar lib/ 4) 在$HIVE_HOME/conf目录下新建hive-site.xml文件 [atguigu@hadoop102 software]$ vim $HIVE_HOME/conf/hive-site.xml 添加如下内容: <?xml version="1.0"?> <?xml-stylesheet type="text/xsl" href="configuration.xsl"?> <configuration> <!

《样式设计011:模组-瓷片区》

描述:在开发小程序过程中,发现一些不错的案例,平时使用也比较多,稍微总结了下经验,以下内容可以直接复制使用,希望对大家有所帮助,废话不多说直接上干货! 一、小程序:模组-瓷片区 (一)样式图 (二)代码部分 2.1:wxml <!-- --------------------------【序号003:瓷片区+弥散渐变】----------------------------------- --> <view style="height: 50rpx;background-color: #FFA07A;"><text>序号003:瓷片区+弥散渐变</text></view> <view class="tile-container"> <view class="tile" style="background: linear-gradient(to right, #ffcccc, #ccffff);"></view> <view class="tile" style="background: linear-gradient(to right, #ccffcc, #99ccff);"></view> <view class="tile" style="background: linear-gradient(to right, #ffcc99, #ccffff);"></view> <view class="tile" style="background: linear-gradient(to right, #FFD3B5, #FFB78C);"></view> <view class="tile" style="background: linear-gradient(to right, #9AD7E9, #B5E2FF);"></view> <view class="tile" style="background: linear-gradient(to right, #B4EDB9, #E0F9E0);"></view> </view> <!-- --------------------------【序号002:瓷片区+内容】----------------------------------- --> <view style="height: 50rpx;background-color: #FFA07A;"><text>序号002:瓷片区+内容</text></view> <view class="main-container2"> <view class="left-area2"> <view class="

在Jupyter Notebook中进行大数据分析:集成Apache Spark

在Jupyter Notebook中进行大数据分析:集成Apache Spark 介绍 Jupyter Notebook是一款广泛使用的数据科学工具,结合Apache Spark后,能够处理和分析大规模数据。Apache Spark是一个快速的统一分析引擎,支持大数据处理和分布式计算。本教程将详细介绍如何在Jupyter Notebook中集成和使用Spark进行大数据分析。 前提条件 基本的Python编程知识基本的Spark和大数据处理概念安装必要的软件:Jupyter Notebook、Apache Spark 教程大纲 环境设置Spark安装与配置Jupyter Notebook与Spark的集成Spark DataFrame基础操作数据处理与分析高级分析与机器学习总结与展望 1. 环境设置 1.1 安装Jupyter Notebook 在终端中执行以下命令来安装Jupyter Notebook: pip install jupyter 1.2 安装Apache Spark 从Apache Spark官网下载并解压Spark: wget https://downloads.apache.org/spark/spark-3.1.2/spark-3.1.2-bin-hadoop2.7.tgz tar -xzf spark-3.1.2-bin-hadoop2.7.tgz 1.3 配置环境变量 将Spark添加到环境变量中。在~/.bashrc或~/.zshrc文件中添加以下内容: export SPARK_HOME=~/spark-3.1.2-bin-hadoop2.7 export PATH=$SPARK_HOME/bin:$PATH 然后执行以下命令使配置生效: source ~/.bashrc 2. Spark安装与配置 2.1 安装PySpark 在终端中执行以下命令来安装PySpark: pip install pyspark 2.2 验证安装 在终端中执行以下命令验证安装是否成功: pyspark 如果进入了Spark Shell,说明安装成功。输入exit()退出Spark Shell。 3. Jupyter Notebook与Spark的集成 3.1 启动Jupyter Notebook 在终端中执行以下命令启动Jupyter Notebook:

CUE-云原生配置语言

CUE 是一种服务于云化配置的强类型配置语言,由 Go team 成员 Marcel van Lohiuzen 结合 BCL 及多种其他语言研发并开源,可以说是 BCL 思路的开源版实现CUE 是一种服务于云化配置的强类型配置语言,由 Go team 成员 Marcel van Lohiuzen 结合 BCL 及多种其他语言研发并开源,可以说是 BCL 思路的开源版实现 https://cuelang.org/docs/concept/popular-guides/#common-use-cases Cue的语法类似于JSON,但提供了更多的类型检查和验证功能。Cue不是基于Go语言,但是它的实现是用Go编写的,而且它可以与Go语言集成。 Cue语言的一个主要特点是它支持声明式的数据验证和约束。这意味着你可以用Cue来定义你的数据结构和数据的约束条件,然后Cue会根据这些约束条件进行类型检查和数据验证,以确保你的数据符合预期的规范。这些功能使得Cue非常适合用于数据处理和数据验证场景,例如配置文件、API参数验证、数据转换等。 在Cue中,你可以定义结构体、列表、枚举等数据类型,并且可以在这些数据类型中添加约束条件,例如正则表达式、最大长度、最小值等等。Cue还支持函数和表达式,这使得你可以编写复杂的验证逻辑和转换逻辑。 如果你想在Go程序中使用Cue,你可以使用Cue的Go SDK。Go SDK提供了一组API,用于加载和解析Cue定义的数据结构,进行类型检查和数据验证,并将验证结果返回给你的Go程序。你还可以使用Cue来生成Go代码,以便在Go程序中使用Cue定义的数据结构和验证规则。 在kubevela使用: template: | parameter: { domain: string http: [string]: int } // trait template can have multiple outputs in one trait outputs: service: { apiVersion: "v1" kind: "Service" spec: { selector: app: context.name ports: [ for k, v in parameter.

Java多线程-----线程安全问题(详解)

目录 🍇一.线程安全问题的引入: 🍒二.线程安全问题产生的原因: 🍌三.如何解决线程安全问题: 🎉1.synchronized关键字: 🦉sychronized关键字的特性: ✨2.volatile关键字: 🍇一.线程安全问题的引入: 首先我们来看下面一段代码,我们通过两个线程同时操作一个静态成员变量count,使其一共累加10w次,看看结果: public class Main { public static int count = 0; public static void main(String[] args) throws InterruptedException { Thread t1 = new Thread(()->{ for(int i = 0;i < 50000;i++){ count++; } }); Thread t2 = new Thread(()->{ for(int i = 0;i < 50000;i++){ count++; } }); t1.start(); t2.start(); //让主线程等待t1,t2线程结束,统计此时count的累加结果 t1.join(); t2.join(); System.out.println(count); } } 第一次执行结果: 59355 第二次执行结果: 54362 第三次执行结果: 53976 这是我们发现,三次累加count的结果都不一样,很明显,这里出现了bug!

USART串口理论知识总结

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 USART串口理论知识总结 1、通讯的串行和并行1.串口采用发送数据代码并用printf重代码 1、通讯的串行和并行 1.串口采用发送数据代码并用printf重代码 #include <stdint.h> #include <stdio.h> #include "gd32f30x.h" static void Usb2ComGpioInit(void) { rcu_periph_clock_enable(RCU_GPIOA); //配置TX引脚对于的管脚为复用推挽输出模式,输出模式有复用和一般模式的区别,而输出无这样的的区别。 gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_10MHZ, GPIO_PIN_9);//发送引脚 //配置TX引脚对于的管脚为上拉输入或者浮空输入 //why 串口默认输出高电平,读取数据是,空闲状态和数据起始位都为低电平。 gpio_init(GPIOA, GPIO_MODE_IPU, GPIO_OSPEED_10MHZ, GPIO_PIN_10);//接受引脚 } static void Usb2ComUartInit(uint32_t baudRate) { /* 使能UART时钟;*/ rcu_periph_clock_enable(RCU_USART0); /* 复位UART;*/ usart_deinit (USART0); /* 通过USART_CTL0寄存器的WL设置字长;*/ /* 初始默认WL字长为8bit*/ usart_word_length_set(USART0, USART_WL_8BIT); /* 通过USART_CTL0寄存器的PCEN设置校验位;*/ /* 初始默认无校验位*/ usart_parity_config(USART0, USART_PM_NONE); /* 在USART_CTL1寄存器中写STB[1:0]位来设置停止位的长度;*/ /*初始默认停止位1bit 可选0.5 1 1.5 2*/ usart_stop_bit_set(USART0, USART_STB_1BIT); /* 在USART_BAUD寄存器中设置波特率;*/ usart_baudrate_set(USART0, baudRate); /* 在USART_CTL0寄存器中设置TEN位,使能发送功能;*/ usart_transmit_config(USART0, USART_TRANSMIT_ENABLE); /* 在USART_CTL0寄存器中置位UEN位,使能UART;*/ usart_enable(USART0); } void Usb2ComTest(void) { for (uint8_t i = 0; i <= 250; i++) { usart_data_transmit(USART0, i);//发送数据 while (RESET == usart_flag_get(USART0, USART_FLAG_TBE)); //当TBE为0,等待,当TBE为0时,表示TXR数据寄存器有数据,需要继续等待 //当TBE为1,跳出循环,表示TXR数据寄存器无数据,可以继续向位移寄存器下一个数据。 总结:RENE和TBE标志位为1是都表示已经准备好的意思,可以开始接受和发送下一个数据。TC为1时表示数据发送完毕。 } // while (RESET == usart_flag_get(g_uartHwInfo.

如何判断自己的数据格式适合使用json还是Excel的形式存入neo4j数据库

判断自己的数据格式适合使用JSON还是Excel的形式存入Neo4j数据库,主要取决于数据的复杂性、规模、结构、以及你或你的团队对这两种格式的熟悉程度。以下是一些关键因素,可以帮助你做出决策: 数据的复杂性: 如果你的数据包含大量的嵌套结构、列表或字典(在JSON中)等复杂数据类型,那么JSON可能是更好的选择。Neo4j的Cypher查询语言可以很好地处理JSON格式的数据,尤其是在处理节点和关系的复杂关系时。如果你的数据主要是简单的表格形式,列与列之间关系明确,且不需要复杂的嵌套结构,那么Excel可能是一个更直观的选择。然而,即使在这种情况下,你也可能需要将Excel数据转换为JSON或其他格式才能高效地导入Neo4j。数据的规模: 对于大规模数据集,JSON文件通常比Excel文件更容易处理,因为Excel在处理大量行和列时可能会遇到性能问题。此外,Neo4j提供了针对JSON数据的批量导入工具,可以高效地处理大型JSON文件。如果你的数据集相对较小,那么Excel的直观性和易用性可能使其成为更好的选择。数据的结构: 如果你的数据自然地适合图数据库模型(即节点和关系),并且你希望直接以这种模型存储数据,那么JSON可能是一个更好的选择,因为它可以更直接地表示节点和关系。如果你的数据主要是表格形式,但你需要将其转换为图数据库模型,那么你可能需要在导入过程中进行额外的转换步骤,无论你选择哪种格式。熟悉度: 你和你的团队对JSON和Excel的熟悉程度也是一个重要因素。如果你或你的团队更熟悉JSON,并且已经习惯了使用JSON进行数据处理和交换,那么选择JSON可能更合适。相反,如果Excel是你或你的团队更熟悉和舒适的数据处理工具,那么使用Excel可能是更自然的选择。导入和处理的便利性: 考虑你如何将数据从原始格式导入到Neo4j中。Neo4j提供了多种数据导入选项,包括通过Cypher查询、使用Neo4j的批量导入工具(如neo4j-admin import,但这通常要求数据在特定的CSV格式中),或通过编写自定义脚本来处理JSON文件。你需要评估哪种方法最适合你的数据和需求。同时,考虑在Neo4j中处理数据时的便利性。如果你的查询经常需要处理复杂的JSON结构,那么直接在Neo4j中存储JSON数据可能更方便。 综上所述,没有一个绝对的答案可以适用于所有情况。你需要根据你的具体需求、数据的特性以及你或你的团队的熟悉度来做出决策。在某些情况下,你可能还需要考虑将Excel数据转换为JSON或其他格式,以便更高效地导入Neo4j。 JSON格式示例 Excel表格形式示例

Jmeter二次开发流程拆解与环境初始化工具类封装

Jmeter二次开发流程拆解与环境初始化工具类封装 前言 从之前几集里,我们完成了测试用例接口与测试模块接口的开发以及Jmeter二次开发的Demo。 这一集我们将会正式对Jmeter进行二次开发。 Jmeter二次开发流程拆解 那么在开发之前,我们要去对Jmeter二次开发进行步骤的拆解与分析。 那么还是先来继续看一下之前的Demo代码。 public class TestStress { @Test public void testJmeterScript()throws Exception{ // JMeter路径 String jmeterPath = "G:\\Jmeter\\apache-jmeter-5.6.3"; // JMeter根目录 File jmeterHome = new File(jmeterPath); // JMX文件路径 String jmxFilePath = "E:\\XXX\\JMX\\pay_json.jmx"; // JMX文件 File jmxFile = new File(jmxFilePath); // JMeter配置文件路径 File jmeterProperties = new File(jmeterHome.getPath() + File.separator + "bin" + File.separator + "jmeter.properties"); // 设置JMeter根目录 JMeterUtils.setJMeterHome(jmeterHome.getPath()); // 加载JMeter配置文件 JMeterUtils.loadJMeterProperties(jmeterProperties.getPath()); // JMeter标准引擎 StandardJMeterEngine jmeter = new StandardJMeterEngine(); // 测试计划树 HashTree testPlanTree = new HashTree(); // 设置文件服务器的基础脚本路径 FileServer.

FLINK-checkpoint失败原因及处理方式

在 Flink 或其他分布式数据处理系统中,Checkpoint 失败可能由多种原因引起。以下是一些常见的原因: 资源不足: 如果 TaskManager 的内存或磁盘空间不足,可能无法完成状态的快照,导致 Checkpoint 失败。 网络问题: 分布式系统依赖网络来传输状态快照数据。如果网络不稳定或带宽不足,可能会导致 Checkpoint 失败。 状态后端问题: 状态后端(如 RocksDB、FsStateBackend)配置错误,或者后端存储(如 HDFS、S3)不可用,也会导致 Checkpoint 失败。 任务故障: 如果在 Checkpoint 过程中有任务失败,可能会导致整个 Checkpoint 失败。 超时: Checkpoint 的执行时间超过了配置的超时时间,系统会自动标记为失败。 参数配置:SET execution.checkpointing.timeout = 10min; 并发限制: 如果同时进行的 Checkpoint 数量超过了系统配置的限制,可能会导致部分 Checkpoint 失败。 代码或数据问题: 用户代码中的 bug 或数据问题可能导致状态快照时出现异常,从而导致 Checkpoint 失败。 外部系统依赖: Checkpoint 过程中可能依赖外部系统(如数据库、消息队列等),如果这些系统出现问题,也可能导致 Checkpoint 失败。 配置错误: 错误的系统配置或 Checkpoint 相关配置可能导致 Checkpoint 无法正确执行。 系统错误: 由于系统错误,如 JVM 崩溃、硬件故障等,也可能导致 Checkpoint 失败。 版本兼容性问题: 在升级 Flink 或状态后端时,可能会出现版本不兼容的问题,影响 Checkpoint 的执行。 解决 Checkpoint 失败的问题通常需要仔细检查日志文件,找出失败的根本原因,并根据具体情况采取相应的措施。在某些情况下,可能需要优化配置,增加资源,或修复代码中的错误。

控制欲过强的Linux小进程

控制欲强?视奸?普通人那才叫视奸,您是皇帝,天下大事无一逃过您的耳目,您想看什么就看什么,臣怀疑他在朋友圈私养兵士,囤积枪甲,蓄意谋反,图谋皇位啊! 哈哈哈哈开个玩笑,这篇就主要讲讲Linux进程的控制吧~ fork( ) 由于fork()之前也说过啦(从已存在进程中创建一个新进程:新进程为子进程,原进程为父进程),所以下面主要讲内核的操作,进程调用fork,当控制转移到内核中的fork代码后,内核做: 1.分配新的内存块和内核数据结构给子进程 2.将父进程部分数据结构内容拷贝至子进程 3.添加子进程到系统进程列表当中 4.fork返回,开始调度器调度 当一个进程调用fork之后,就有两个二进制代码相同的进程。而且它们都运行到相同的地方。但每个进程都将可以 开始它们自己的旅程: #include <unistd.h> #include<stdio.h> int main(void) { pid_t pid; printf("Before: pid is %d\n", getpid()); if ((pid = fork()) == -1) perror("fork()"), exit(1); printf("After:pid is %d, fork return %d\n", getpid(), pid); sleep(1); return 0; } 先来下个定义: 进程=内核的相关管理数据结构(task_struct + mm_struct + 页表)+ 代码和数据 已知fork函数的返回值是这样的: 子进程返回0 父进程返回子进程的pid 那为什么捏? 原因其实也很简单,爹得知道儿子名,杀掉他啊等待他啊,爹总要知道的(为了方便父进程对紫禁城进行标识,进而进行管理) 进程具有独立性就在于紫禁城代码数据和父进程共享,但因为写时拷贝又不影响父进程 fork常规用法 一个父进程希望复制自己,使父子进程同时执行不同的代码段(父进程等待客户端请求,生成子 进程来处理请求) 一个进程要执行一个不同的程序(子进程从fork返回后,调用exec函数) fork调用失败原因 系统中有太多的进程 实际用户的进程数超过了限制 进程终止 终止是在做什么 进程终止就是在释放曾经的代码和数据所占据的空间,也是在释放内核数据结构(task_struct,当进程状态是Z就要释放对应PCB) 终止三种情况 先来看两段代码: #include<stdio.

重生之我们在ES顶端相遇第5章-常用字段类型

思维导图 前置 在第4章,我们提到了 keyword(一笔带过)。在本章,我们将介绍 ES 的字段类型。全面的带大家了解 ES 各个字段类型的使用场景。 字段类型 ES 支持以下字段类型(仅介绍开发中常用,更多内容请自行阅读 官方文档)。 Keyword 基本介绍 手动设置字段类型为 keyword PUT /test3 { "mappings": { "properties": { "tags": { "type": "keyword" } } } } 写入数据 PUT /test3/_doc/1 { "tags": "hello world" } keyword 其实就是字符串,输入什么,存储就是什么。 适用场景 keyword 适用于 排序、聚合、term(精确查询) 查询场景中。 例如 GET /test3/_search { "query": { "term": { "tags": { "value": "hello" } } } } 查询优化 有 2 个对查询优化重要的点: 数字类型(int, long)如果不需要使用范围查询,则建议设置为 keywordterm 查询在 keyword 上的搜索速度总是快于数字类型。 Text 基本介绍 与 keyword 相对的则是 text。在第三章,我们介绍了全文搜索 match 的用法。你可能会好奇,为啥默认写入的数据就可以使用全文搜索。因为当输入是无规则字符串时,字段类型就是 text。(别着急,默认的字段类型,一会我们就会详细介绍)

web学习笔记(八十二)uniapp

目录 1.介绍uniapp 2.uniapp项目结构 3.自定义tabBer 4.uniapp条件编译 使用方法 5.uniapp的路由跳转 (1)js跳转 (2)标签跳转 获取参数 6.生命周期 6.1 全局生命周期 6.2 页面生命周期 1.介绍uniapp uniapp是一个基于Vue.js框架的前端开发框架,它可以帮助开发者使用Vue.js一次编写代码,同时生成多个平台(如iOS、Android、Web等)的应用程序。Uni-app的出现使得开发者可以只使用一种语言(Vue.js语法),同时生成多个平台的应用,简化了跨平台开发的复杂度。 2.uniapp项目结构 ubiapp项目的结构和vue类似,都是在pages文件夹中放置页面的.vue文件,然后在static文件夹中放置静态文件(在上传项目的时候此处的文件会被压缩)。main.js是整个项目的入口文件,可以app.vue是在里配置全局样式(注意:配置全局样式的时候就不需要加scoped了),我们在pages.json文件中配置页面的路由(默认pages数组中第一项表示应用启动页)。需要注意的是uniapp项目中有一个特殊的文件——manifest.json,当我们需要将项目打包为app或者小程序时就需要在此进行相关配置(编译成网页不需要进行配置,直接编译即可)。 3.自定义tabBer 原生tabBar是相对固定的配置方式,可能无法满足所有场景,这就涉及到自定义tabBar。但注意除了H5端,自定义tabBar的性能体验会低于原生tabBar。App和小程序端非必要不要自定义。 4.uniapp条件编译 条件编译是用特殊的注释作为标记,在编译时根据这些特殊的注释,将注释里面的代码编译到不同平台。 使用方法 以 #ifdef 或 #ifndef 加 %PLATFORM% 开头,以 #endif 结尾。 #ifdef:if defined 仅在某平台存在#ifndef:if not defined 除了某平台均存在%PLATFORM%:平台名称 <view class="content"> <!-- #ifdef MP-WEIXIN--> <view class=""> 小程序 </view> <!-- #endif --> <!-- #ifdef APP||H5--> <view class=""> app </view> <!-- #endif --> </view> %PLATFORM% 可取值: 值生效条件版本支持VUE3uni-app js引擎版用于区分vue2和3,HBuilderX 3.2.0+VUE2uni-app js引擎版用于区分vue2和3,UNI-APP-X用于区分是否是uni-app x项目 HBuilderX 3.

玄机-第二章日志分析-apache日志分析

前言 出息了,这回0元玩玄机了,因为只是日志分析,赶紧导出来就关掉(五分钟内不扣金币) 日志分析只要会点正则然后配合Linux的命令很快就完成这题目了,非应急响应. 简介 账号密码 root apacherizhi ssh root@IP 1、提交当天访问次数最多的IP,即黑客IP: 2、黑客使用的浏览器指纹是什么,提交指纹的md5: 3、查看index.php页面被访问的次数,提交次数: 4、查看黑客IP访问了多少次,提交次数: 5、查看2023年8月03日8时这一个小时内有多少IP访问,提交次数: 应急开始 准备工作 找到apache的日志文件:/var/log/apache2/access.log (在题目靶机中日志文件为/var/log/apache2/access.log.1)迅速将文件导出来,还是心疼我的金币,不要浪费了:scp -r root@ip:/var/log/apache2/ /tmp/ 或者你可以使用xftp等等攻击直接导出来。我这里其实准备了360星图的工具,在真实的日志分析中会比较有用,我们这里根据题目要求来找flag的话其实Linux指令已经完全够用完成我们的任务了。 下面还是附上我星图扫完后的html结果吧,不得不说这界面做的真好看啊。 步骤 1 1、提交当天访问次数最多的IP,即黑客IP: 找到apache的日志文件 cd /var/log/apache2 中的 access.log.1文件就是题目保存下来的日志文件 使用Linux命令直接梭哈,直接就知道那个是访问次数多的ip了 awk '{print $1}' /var/log/apache2/access.log.1 | uniq -c | sort -n flag为: flag{192.168.200.2} 步骤 2 2、黑客使用的浏览器指纹是什么,提交指纹的md5: 已知黑客ip了,grep根据ip筛选日志记录即可知道,但是这里我在观察的时候发现这个黑客ip还使用了Firefox,你直接grep Firefox能够筛选出来的访问Agent中也有黑客ip的,他还用的是MacOS,我估计是出题人自己的Mac访问了一下,所以如果不确定就两个Agent都提交一下即可。grep -Ea "192.168.200.2" /var/log/apache2/access.log.1 指纹为:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36 flag为指纹的md5值 flag{2d6330f380f44ac20f3a02eed0958f66} 步骤 3 3、查看index.php页面被访问的次数,提交次数:

GraphRAG + GPT-4o mini 低成本构建 AI 图谱知识库

更好的效果,更低的价格,听起来是不是像梦呓? 限制 首先,让我们来介绍一个词:RAG。 简单来说,RAG(Retrieval-Augmented Generation,检索增强生成) 的工作原理是将大型文档分割成多个小段落或片段。主要原因是,大语言模型的上下文窗口长度有限,无法一次处理超过上下文窗口长度的信息。 当我提出一个问题时,RAG 技术可以先从这些片段中检索相关信息,根据我提问的内容与这些片段的相似度,找出若干个与问题相关的片段,组合成一个上下文,然后将这些信息,连同我的提问一起输入到大语言模型中,然后期待大语言模型「更为精准」的回答。 然而,我们需要考虑一些潜在的局限性。对于一个足够长的文档和一个非常复杂的问题,单靠这几个(仅仅是疑似相关的)片段可能是不够的。真正的答案,也许根本就不在里面。 我们之前讨论了很多关于私有知识库。例如 Quivr, Elephas, GPTs, Obsidian Copilot …… 用久了你会发现,私有知识库提供的回答结果与通过数据微调模型获得的结果可能差异很大 —— 微调后的模型往往能够依据私有数据回答非常复杂的问题,而 RAG 这种简单粗暴的拼接方式,很多时候得到的答案并不理想。 图谱 这些问题就催生了 GraphRAG。GraphRAG 是一种创新的技术,它结合了知识图谱结构和 RAG 方法,旨在解决传统 RAG 方法的局限性。 这是微软研发的一个创新产品,它代表了 RAG 技术的最新进展。微软还发布了相关的学术论文,详细阐述了 GraphRAG 的理论基础和技术实现。 那么,这里的 "Graph(图)" 究竟是什么意思呢?在 GraphRAG 的主页上,你会看到一个复杂的图谱。这个图谱不仅仅是一个简单的示意图,它代表了知识的结构化表示。在这个图谱中,每个节点可能代表一个概念或实体,而连接这些节点的边则表示它们之间的关系。 假设图谱中有一个节点是「老虎」,另一个是「兔子」,老虎与兔子之间连一条线,上面写着「吃」,代表二者的关联是「老虎吃兔子」。当然,这只是一个不够严谨的比喻。 有了这样的图谱,为什么要将其与刚才提到的 RAG 结合呢?因为之前提到的「满地找碎片」的传统 RAG 方式实际上效果不佳,所以我们希望将这些概念之间的复杂关系展现出来。在查询时,不再是大海捞针去找「可能相关」的信息碎片,而是根据图谱中已经掌握的关联,提取一整串相连的信息,让大语言模型来一并处理。 这里是 GraphRAG 的 GitHub 网址。它在 GitHub 上的受欢迎程度如何?已经获得超过一万一千颗星。 对于一个项目来说,这是一个非常好的成绩,我做梦都希望自己的项目能达到这样的水平。看来还得继续努力。 特点 我们来看看 GraphRAG 的特点。它融合了人工智能的两大流派,一个是深度学习,另一个是知识图谱。 曾经这两个流派是对立的。后来发现对立干啥啊? 你现在用深度学习直接回答效果不好,但如果结合图谱,效果就会强很多。 另一方面,构建知识图谱原来得人工根据规则去抽取其中的实体和关联,那是一个砸钱堆人力的活计。后来发现用上深度学习可以有效提升实体抽取效率。特别是有了大语言模型,人们发现抽取实体和关联变得更加准确、简单且低成本。所以,二者的融合,是大势所趋。 那么融合之后的 GraphRAG 擅长什么呢?它能够把实体之间的复杂关系和上下文串联起来。 正如刚才我们提到的这个过程,它可以连接多个信息点进行复杂查询。这种查询不是简单地提取一部分信息就能完成的。原先根据相似度找出来的这些信息碎片,可能根本不足以支撑问题解答。但现在,根据实际关联获取相关信息,效果要好很多。 另外 GraphRAG 由于对数据集有了整体的刻画,因此概念语义信息得到了充分的表达。 两个特点相夹持,使得 GraphRAG 的表现有了非常显著的改进。后面的例子里,你也能观察到这点。