hive学习笔记

一、Hive基本概念 1.1 hive是什么 hive是基于hadoop的一个数仓分析工具,hive可以将hdfs上存储的结构化的数据,映射成一张表,然后让用户写HQL(类SQL)来分析数据 tel up down 1383838438 1345 1567 1383838439 5345 1567 1383838440 1241 16577 1383838441 3453 15757 1383838434 35355 1567567 按照手机号 分组,统计每个手机号的总流量 select tel,up+down from test; hive的本质其实就是hadoop的一个客户端,hive底层不存储任何数据,hive表的数据存在hdfs上,hive表的元数据存在关系型数据库中 默认是derby,我们不一般不用默认的derby来存,一般都会修改为mysql。 元数据:描述数据的数据 Hive其实就是将用户写的HQL,给翻译成对应的mr模板,然后执行这些mr程序 hive底层执行引擎其实就是MapReduce,mr运行在yarn上 1.2 hive的优缺点 优点:操作简单,采用类sql的语法分析数据,门槛低,大大的降低了大数据分析的难度,通用性高 缺点:不够灵活,机翻粒度比较粗,调优困难。因为底层执行引擎还是mr,所以延迟较高,不能像关系型数据库那样,立马返回结果 并且底层存储是hdfs,不支持随机写,只能追加,所以hive不支持行级别的更新和删除(delete 和 update) 1.3 hive的架构原理 客户端:命令行客户端,jdbc客户端 数据存储:hdfs 底层执行引擎:mr 元数据库:hive将元数据默认存在derby中,我们一般在安装hive的时候,会修改成mysql dirver四个器 解析器:将hql语句转换成AST抽象语法树,解析sql是否有误 编译器:将解析后的hql编译成逻辑执行计划,暂时不执行 优化器:对逻辑计划进行优化,调优 执行器:将优化后的逻辑计划执行,其实就是翻译成对应的mr程序,在yarn上运行 1.4 hive和关系型数据库对比 hive不是数据库,不是数据库,不是数据库 hive除了查询语言HQL跟SQL很像之外,别的跟数据库再也没有半点相似可言 数据更新 数据规模 执行延迟 底层引擎 数据存储 二、Hive安装 2.1 hive访问 1)通过hive自带的beeline客户端访问 beeline -u jdbc:hive2://hadoop102:10000 -n logcat hive脚本访问

vue 前端导出xlsx文件

安装组件: npm install xlsx --save npm install --save xlsx file-saver html 代码: <el-table :data="tableData" id="outExcel"></el-table> js 代码: import * as XLSX from 'xlsx'; import FileSaver from 'file-saver' /**导出数据*/ handleOut() { /** 从表生成工作簿对象 out-table是表格的id */ const wb = XLSX.utils.table_to_book(document.querySelector("#outExcel")); /** 获取二进制字符串作为输出 */ const wbout = XLSX.write(wb, { bookType: "xlsx", bookSST: true, type: "array" }); try { FileSaver.saveAs( new Blob([wbout], {type: "application/octet-stream"}), //设置导出文件名称 "文件名称.xlsx" ); } catch (e) { if (typeof console !

关于幸运数字的解答

前两天看到一道题,题目是这样说的: 题目描述 小艺定义一个幸运数字的标准包含3条: 1、仅包含4或7。 2、幸运数字的前半部分数字等于后半部分数字。 3、数字的长度是偶数。 由于本人是初学,所以只能用c语言代码解答: 在看这道题的时候,由于要输入的数组不知道具体长度,所以我们定义一个字符型的数组,用 strlen 函数来确定他的长度len,对长度进行对2求余,第三个问题解决。 再看第二个问题,我们可以再定义一个字符型数组,用倒叙的方法赋值,再一对一地比较,具体操作如下: 当然,前面数组的名字自己定义,循环变量也要定义,再循环len 遍,一一比对; 最后一个问题,仅包含4或7,这里我们可以用定义宏常量的方法: 一定注意,在比对时,4或7是单个字符,要用’‘把它括起来; 再用一个变量flag 来确定结果。 最后是完整代码: #include <stdio.h> #include <stdlib.h> #define four '4' #define seven '7' void solution(char n[],int len) { char arr[1000]; int i,j,k,flag=0; if(len%2==0) { for(i=0,j=len-1;i<len,j>=0;i++, j--) { arr[i]=n[j]; } for(k=0;k<len;k++) { if(arr[k]==n[k]) { if(n[k]==four||n[k]==seven) { flag =1; } } } } if(flag==1) printf("Yes"); else printf("No"); } int main() { char n[1000]; scanf("%s",&n); int len =strlen(n);

vite4.0 vue-i8n踩坑记录

Uncaught (in promise) SyntaxError: Not available in legacy mode 解决办法: const i18n = createI18n({ locale: getLocale(), + legacy: false, messages: messages, }); export default i18n; You are running the esm-bundler build of vue-i18n. It is recommended to configure your bundler to explicitly replace feature flag globals with boolean literals to get proper tree-shaking in the final bundle. 解决办法: npm i @intlify/unplugin-vue-i18n vite // vite.config.ts import VueI18nPlugin from '@intlify/unplugin-vue-i18n/vite' export default defineConfig({ plugins: [ VueI18nPlugin({ /* options */ }), ], }) 如果对您有所帮助点赞走一波~~~

Chrome谷歌浏览器离线安装方法

在Chrome官网:https://www.google.cn/intl/zh-CN/chrome/ 里面下载的浏览器一般都是只有几MB的在线安装包。 如果想要下载Chrome的离线安装包,有两种方法。嫌麻烦的同学可以直接使用第一种方法,如果第一种方法的网址失效了,那么按照第二种方法一步一步来即可。 方法一: 直接打开下载地址即可。 离线包下载地址:https://www.google.com/intl/zh-CN/chrome/?standalone=1 方法二: 如果你想自己动手,那么根据下面的步骤来: 拉到官网的最底部,点击Chrome帮助。 然后在搜索栏中输入‘离线安装’,点击进入第一个页面。 点第二项计算机,并选择自己电脑对应的系统,我这里以windows为例。 然后点击‘备用Chrome安装程序’ 在弹出的页面点击‘下载Chrome’即可。

js之闭包(通俗、易懂)

一、闭包的定义 什么是闭包,那就是在一个函数里边再定义一个函数(这也是最常见的形式)。这个内部函数一直保持有对外部函数中作用域的访问(小盒子可以一直访问大盒子但大盒子不能访问小盒子)。 二、闭包的产生 当一个嵌套的内部(子)函数引用了嵌套的外部(父)函数的变量时,就产生了闭包。执行函数定义时便产生了闭包,不用等待执行产生。 三、闭包的作用 常见的作用有以下两点: 1、使用函数内部的变量在函数执行完,仍然存活在内存中(延长了局部变量的生命周期)2、让函数外部可以操作(读写)到函数内部的数据(变量/函数) function f1() { var n = 999; nAdd = function () { alert(n += 1); } function f2() { alert(n); } return f2; } var result = f1(); result(); //999 nAdd();//1000 result(); //1001 在这段代码中,result实际上就是闭包f2函数。它一共运行了两次,第一次的值是999,第二次的值是1000。这证明了,函数f1中的局部变量n一直保存在内存中,并没有在f1调用后被自动清除。 为什么会这样呢?原因就在于f1是f2的父函数,而f2被赋给了一个全局变量,这导致f2始终在内存中,而f2的存在依赖于f1,因此f1也始终在内存中,不会在调用结束后,被垃圾回收机制(garbage collection)回收。 这段代码中另一个值得注意的地方,就是"nAdd=function(){n+=1}"这一行,首先在nAdd前面没有使用var关键字,因此nAdd是一个全局变量,而不是局部变量。 其次,nAdd的值是一个匿名函数(anonymous function),而这个匿名函数本身也是一个闭包,所以nAdd相当于是一个操控者,可以在函数外部对函数内部的局部变量进行操作。 四、使用闭包的注意点 1、由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。 2、闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。

【Java】死锁

一、什么是死锁 死锁指多个线程在执行过程中,因争夺资源造成的一种相互等待的僵局。 进程死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。线程死锁是指由于两个或者两个以上的线程互相持有对方所需要的资源,导致这些线程处于等待状态,无法前往执行。 二、死锁的必要条件 互斥条件:同一资源同时只能由一个线程读取不可抢占条件:不能强行剥夺线程占有的资源请求和保持条件:请求其他资源的同时对自己手中的资源保持不放循环等待条件:在相互等待资源的过程中,形成一个闭环 三、预防死锁 想要预防死锁,只需要破坏其中一个条件即可,比如使用定时锁、尽量让线程用相同的加锁顺序,还可以用银行家算法,即可解决死锁问题; 破坏互斥条件和不剥夺条件,对sychronized来说,是JVM底层设定的,每个对象都有一个monitor(监视器),在同步操作中,一个线程(或进程)持有一个对象的monitor后,有monitorenter操作,同步方法结束或异常时,有monitorexit操作。所以我们是破坏不了这个2个条件的;如果不是sychronized,如通过Lock完成的互斥条件和不剥夺条件,就可以更改;破坏请求和保持条件,常见的操作有:加锁顺序(指定加锁的顺序或者线程执行的顺序)、加锁时限(对加锁的对象增加超时限制,避免一直占用);破坏环路等待条件:死锁检测:多线程对期望持有的锁对象不能形成相互(环状)依赖的情况。 如,上述死锁代码中: 线程01持有对象A后,去请求持有对象B; 线程02持有对象B后,去请求持有对象A,-------多线程持有的对象A、B是相互依赖的;造成死锁; 如果是这样,线程01持有对象A后,去请求持有对象B; 线程02持有对象B后,去请求持有对象C, ------------A、B、C之间没有相互依赖,不会死锁; 补充 银行家算法 银行家算法是操作系统的经典算法之一,用于避免死锁情况的出现。 它最初是为银行设计的(因此得名),通过判断借贷是否安全,然后决定借不借。 在银行中,客户申请贷款的数量是有限的,每个客户在第一次申请贷款时要声明完成该项目所需的最大资金量,在满足所有贷款要求时,客户应及时归还。银行家在客户申请的贷款数量不超过自己拥有的最大值时,都应尽量满足客户的需要。 用在操作系统中,银行家、出借资金、客户,就分别对应操作系统、资源、申请资源的进程。 每一个新进程进入系统时,必须声明需要每种资源的最大数目,其数目不能超过系统所拥有的的资源总量。当进程请求一组资源时,系统必须首先确定是否有足够的资源分配给该进程,若有,再进一步计算在将这些资源分配给进程后,是否会使系统处于不安全状态如果不会才将资源分配给它,否则让进程等待。

Axios异步请求 & json格式

Axios是Ajax的一个框架,简化Ajax操作。 需要axios.min.js 和vue.js的jar。 发送普通参数异步请求以及相应异常情况 客户端向服务器端异步发送普通参数值: - 基本格式: axios().then().catch() - 示例: axios({ // axios表示要发送一个异步请求 method : "POST", //请求方式 url : "....", // 发送地址(发给谁) params:{ //带的参数 uname:"lina", pwd:"ok" } }) .then(function ( value ){ }) //成功响应时执行的回调 value.data可以获取到服务器响应容 .catch(function(reason){}); //有异常时执行的回调reason.response.data可以获取到响应的内容 reason.message / reason.stack 可以查看错误的信息 html代码 <div id="div0"> uname:<input type="text" v-model="uname"/><br> pwd:<input type="text" v-model="pwd"/><br><br> <input type="button" value="发送一个带普通请求参数值的异步请求" @click="axios01"> </div> Axios和vue <script language="JavaScript" src="script/vue.js"></script> <script language="JavaScript" src="script/axios.min.js"></script> <script language="JavaScript"> window.onload=function (){ var vue=new Vue({ el:'#div0', data:{ uname:'lina', pwd:'true' }, methods:{ // 标签里面定义了 @click="

树莓派安装MQTT服务

运行以下命令安装Mosquitto及其客户端软件 sudo apt install mosquitto mosquitto-clients 可以使用下面的命令来验证它是否已经安装和运行。 sudo systemctl status mosquitto 这个篇文章更加详细:https://www.ncnynl.com/archives/202208/5391.html

js千分位转换

这里写自定义目录标题 js千分位转换转为千分位千分位转正常 js千分位转换 js千分位转换 转为千分位 function formatNum (num, n) { // 参数说明:num 要格式化的数字 n 保留小数位 num = num || 0 num = parseFloat(num) || 0 if (n) { num = num.toFixed(n) } else { num = String(num) } var re = /(-?\d+)(\d{3})/ while (re.test(num)) { num = num.replace(re, '$1,$2') } return num } 千分位转正常 function deFormatNum (str, n) { str = str || '0' str += '' if (n) { str = (Number(str.

mac使用sftp上传文件夹

mac使用sftp上传文件夹 合并分卷文件 1.mac使用sftp上传文件夹2.拆分、合并分卷文件3.校验文件md5码 1.mac使用sftp上传文件夹 在win中有很多好用的ftp工具,但是在mac中可以用自带工具上传ftp,也很方便。 情景:利用sftp中将本地文件夹/home/sentiment/Data (内包含子文件夹) ,复制到服务器的/home/work目录下 命令: put 步骤: 1.首先定位到远程/home/work/目录下: cd /home/work/ 2.在work目录下新建Data文件夹: mkdir Data 3.进入远程Data文件夹: cd Data 4.本地定位到sentiment文件夹下: lcd /home/sentiment/ (可以用命令lls查看下,Data应该是在本地这个目录下的) 5.执行命令: put -r Data/. 参考文章链接: 使用sftp上传文件夹. 2.拆分、合并分卷文件 场景:因文件太大需要拆分为分卷形式存储方便下载等,如拆分当前目录下的train.tar.gz, 在linux系统下指令如下: cat train.tar.gz.part-* > train.tar.gz 分解后如图所示: 但在使用时还需将其合并才能使用,在Linux系统下的指令如下: cat train.tar.gz.part-* 3.校验文件md5码 关于md5码可以自行了解,大概就是为了校验文件在传输过程中是否出现文件损坏、文件修改等与原文件不一致的情况。下面介绍如何在linux上校验压缩文件的md5码 md5sum xxxx 但是在mac中是没有这个命令的下载半天没下载下来,下面是快捷操作。 1.打开终端 2.输入md5加空格 3.将需要校验的文件拖入终端窗口(这一步就是相当于输入文件的目录地址) 4.按下回车,等待返回结果(文件越大,校验越慢)

Java的大端小端字节序

在计算机中,内存地址通常是按照地址递增的方式分配的,也就是说,低地址是指内存的起始位置,高地址是指内存的末尾位置。在大多数体系结构中,数据存储在内存中是以字节为单位进行的。例如,如果一个数据类型占用 4 个字节,那么它在内存中的存储位置将占用连续的 4 个字节。 在一般情况下,CPU 通过地址总线向内存发送地址信息,地址总线的位数决定了内存的寻址范围。例如,在一个 32 位系统中,CPU 可以访问的最大内存空间为 4GB,因为 32 位地址总线可以表示的最大地址为 2^32-1,即 0xFFFFFFFF。因此,在这个系统中,低地址是 0x00000000,高地址是 0xFFFFFFFF。 大端字节序(Big-Endian)和小端字节序(Little-Endian)是描述多字节数据在内存中的存储顺序的术语。这两个概念的区别在于字节存储的顺序。 大端字节序:在大端字节序中,一个多字节数据的高位字节存储在低地址处,而低位字节存储在高地址处。也就是说,字节的排列顺序是从左到右,高位字节在前,低位字节在后。这种字节序常用于网络传输和数据存储。 小端字节序:在小端字节序中,一个多字节数据的低位字节存储在低地址处,而高位字节存储在高地址处。也就是说,字节的排列顺序是从左到右,低位字节在前,高位字节在后。这种字节序常用于一些硬件架构,如英特尔x86处理器。 Java 采用的是网络字节序,也就是大端字节序(Big-Endian)。Java 的基本数据类型,比如 int、long、short、float、double 等,都采用大端字节序来存储数据。在进行网络传输时,需要进行字节序转换,将大端字节序转换成小端字节序,或将小端字节序转换成大端字节序。Java 中提供了一些字节序转换的方法,比如 ByteBuffer 类中的 order() 方法,可以指定字节序。另外,还可以使用 Java 库中的网络编程类,比如 Socket、ServerSocket、DatagramSocket 等,它们会自动进行字节序转换,以适应网络传输。

记账本App项目简记

目录 1、项目开发背景 2、需求分析 2.1、系统总体设计 2.2、系统功能模块设计 2.3、系统数据库设计(E-R图) 3、技术栈 4、项目主要功能模块 5、项目关键代码 1、项目开发背景 就拿记账来说,随着人们的生活丰富,对于金钱上花费的更是五花八门,金钱的掌控和把握是每个人的原生需求,自然而然的催生了记账的需求。记账的基本需求:收入支出功能统计与记录,通过每天的记账操作能够知道一段时间(一天、一周、一月、一年)里花了多少钱。 经过每天的记账产生消费记录之后,就会希望分析自己消费支出的情况,看看自己主要花费在什么方面,有什么是不必要的开支。因此,记账的进阶需求就是满足用户的消费分析,通过每日、每月的图表统计,了解消费结构,支出趋势以及支出排行榜。 2、需求分析 2.1、系统总体设计 2.2、系统功能模块设计 记账功能:用户通过该功能增删账本账单信息。 周期记账:用户提前录入在某月某日有一笔消费,并在该日自动将该支出与 收入记录录入,且在下月该笔记账会自动记录。 搜索/筛选:用户根据时间、类别或添加的备注搜索需求数据。 数据分析:统计每月数据生成柱形图。 账本管理:用户通过此功能增删账本。 2.3、系统数据库设计(E-R图) 3、技术栈 app采用java开发,数据库使用android常用的本地数据库sqlite。 4、项目主要功能模块 支持收入与支出的分类管理,如增加支出类型:餐饮、交通、走人户等;支持录入新的支出与收入记录;支持记录统计,如一周消费统计、一个月消费统计支持周期记账,如提前录入在某月某日有一笔消费,并在该日自动将该支出与收入记录录入;支持新建账本;支持查看历史账单;支持搜索账单,如可根据备注搜索含相关信息的账单; 主要功能模块具体实现 记账功能:用户通过该功能增删账本账单信息。 周期记账:用户提前录入在某月某日有一笔消费,并在该日自动将该支出与 收入记录录入,且在下月该笔记账会自动记录。 搜索/筛选:用户根据时间、类别或添加的备注搜索需求数据。 数据分析:统计每月数据生成柱形图。 账本管理:用户通过此功能增删账本。 5、项目关键代码 定时记账功能关键代码 //从定时表找到当天的数据 public static List<AccountBean>getAccountListCommonMonthDayFromdingshitb(int year,int month,int day,String name){ List<AccountBean>list = new ArrayList<>(); String sql = "select * from dingshitb where year =? and month=? and day=? and name=? order by id desc"; Cursor cursor = db.

死锁的四个必要条件

死锁在高并发中是一个常见的名词。产生的四个必要条件如下: 互斥条件:一个资源同一时间能且只能被一个线程访问; 不可掠夺:当资源被一个线程占用时,其他线程不可抢夺该资源; 请求与等待:当资源被一个线程占用时,其他线程只能等待资源的释放再拥有; 循环等待:指的是若干线程形成头尾相接的情况,将所有资源都占用导致的整体死锁或局部死锁。 图演示 线程1依次占用资源1和资源2,当尝试占用资源2时,发现该资源被线程2占用,此时只能等待线程2的释放,此时处于阻塞状态; 线程2依次占用资源2和资源1,当尝试占用资源1时,发现该资源被线程1占用,此时只能等待线程1的释放,此时处于阻塞状态。 这两个线程无限的等待对方资源的释放,则成为死锁。 代码演示 package com.lidantao.deadLock; import java.util.concurrent.TimeUnit; /** * @author Cola * @Date 2023年02月16日 10:41:00 */ public class Demo { public static void main(String[] args) throws InterruptedException { Object obj1 = new Object(); Object obj2 = new Object(); Thread t1 = new Thread(() -> { synchronized (obj1) { try { System.out.println("====线程1尝试占用资源1===="); obj1.hashCode(); System.out.println("====线程1已经占用资源1===="); TimeUnit.SECONDS.sleep(3); System.out.println("======线程1尝试占用资源2======"); synchronized (obj2) { obj2.hashCode(); System.out.println("====线程1已经占用资源2===="); } } catch (InterruptedException e) { e.

php微信公众号的token认证

<?php // 微信token认证 $signature = $_GET["signature"]; $timestamp = $_GET["timestamp"]; $nonce = $_GET["nonce"]; $echostr = $_GET["echostr"]; // 你的设置Token $token = "****"; // 1)将token、timestamp、nonce三个参数进行字典序排序 $tmpArr = array($nonce,$token,$timestamp); sort($tmpArr,SORT_STRING); // 2)将三个参数字符串拼接成一个字符串进行sha1加密 $str = implode($tmpArr); $sign = sha1($str); // 3)开发者获得加密后的字符串可与signature对比,标识该请求来源于微信 if ($sign == $signature) { echo $echostr; }

大数据毕业设计 股票量化分析与股票预测系统 - Python

文章目录 0 前言1 课题背景2 实现效果3 设计原理QTChartsarma模型预测K-means聚类算法算法实现关键问题说明 4 部分核心代码5 最后 0 前言 🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天要分享的是 🚩 基于大数据的股票量化分析与股价预测系统 🥇学长这里给一个题目综合评分(每项满分5分) 难度系数:3分工作量:3分创新点:4分 1 课题背景 基于大数据的股票可视化分析平台设计,对股票数据进行预处理,清洗以及可视化分析,同时设计了软件界面。 2 实现效果 价格可视化 魔梯访问与指标计算 聚类分析 3 设计原理 QTCharts 简介 QtCharts是Qt自带的组件库,其中包含折线、曲线、饼图、棒图、散点图、雷达图等各种常用的图表。而在地面站开发过程中,使用折线图可以对无人机的一些状态数据进行监测,更是可以使用散点图来模拟飞机所在位置,实现平面地图的感觉。 使用Qt Charts绘制,大概可以分为四个部分:数据(QXYSeries)、图表(QChart)、坐标轴(QAbstractAXis)和视图(QChartView)。这里就不一一给大家介绍了,下面给大家说一下QtCharts的配置安装。 QtCharts模块的C++类 arma模型预测 简介 ARMA模型,又称为ARMA (p,q)模型。其核心思想就是当前正如名字所显示的,整个模型的核心就是要确定p和q这两个参数。其中,p决定了我们要用几个滞后时期的价格数据,而q决定了我们要用几个滞后时期的预测误差。 简单来说,ARMA模型做了两件事。一是基于趋势理论,用历史数据来回归出一个当前的价格预测,这个预测反映了自回归的思想。但是这个预测必然是有差异的,所以ARMA模型根据历史的预测误差也回归出一个当前的误差预测,这个预测反映了加权平均的思想。用价格预测加上误差预测修正,才最终得到一个理论上更加精确的最终价格预测。 比起简单的自回归模型或者以时间为基础的简单趋势预测模型,ARMA模型最大的优势,在于综合了趋势理论和均值回归理论,理论上的精确度会比较高。 ''' 自回归滑动平均模型 ''' from statsmodels.tsa.arima_model import ARMA from itertools import product def myARMA(data): p = range(0, 9) q = range(0, 9) parameters = list(product(p, q)) # 生成(p,q)从(0,0)到(9,9)的枚举 best_aic = float('inf') result = None for param in parameters: try: model = ARMA(endog=data, order=(param[0], param[1])).

Vue 之 视频流 - Streamedian.js

目录 一、前情提要 1. 作用 2. 准备一 3. 准备二 4. 准备三 二、开始使用 1. 安装依赖 2. 下载streamedian.js文件 3. 代码 HTML JS 一、前情提要 1. 作用 作用 : 使用 streamedian 播放 rtsp 格式的视频流 2. 准备一 需要后端的支持 3. 准备二 rtsp流需要有对应的websock地址 拥有了rtsp流地址和websock地址这两样,才能播放 4. 准备三 若是现场环境,需要连接VPN 二、开始使用 1. 安装依赖 npm install long --- npm install babel-polyfill 2. 下载streamedian.js文件 我的资料库中可以下载,实在太长,这里放不下 网址 : streamedian.min.js 3. 代码 HTML <template> <div class="about-layout"> <input type="button" value="play" @click="onPlay" id="play" /> <div id="container"> <div id="

nmap 安装和使用

要在CentOS 7.6上安装nmap,可以按照以下步骤操作: 1. 打开终端并以root用户身份登录。 2. 运行以下命令更新yum包管理器: yum update 3. 运行以下命令安装nmap: yum install nmap 安装完成后,您可以使用以下常用命令来使用nmap: 4. 扫描单个主机: nmap [hostname or IP address] 5. 扫描多个主机: nmap [hostname or IP address1] [hostname or IP address2] ... 6. 扫描整个子网: nmap [IP address/cidr] 7. 要探测IP的所有端口是否开放,可以使用以下命令: nmap -p- [hostname or IP address] 该命令将扫描目标IP的所有端口,并列出哪些端口开放和关闭。 要使用UDP协议探测端口是否开放,可以使用以下命令: nmap -sU -p [port] [hostname or IP address] 其中,-sU参数表示使用UDP协议扫描,-p参数表示指定要扫描的端口。这将扫描指定端口的UDP协议,并列出哪些端口开放和关闭。请注意,由于UDP是一种不可靠的协议,因此UDP扫描可能会比TCP扫描慢得多。 要指定所有端口,可以使用 -p- 参数,表示扫描所有端口。所以,要扫描目标IP地址的所有UDP端口,可以使用以下命令: nmap -sU -p- ip 这将对目标IP地址的所有UDP端口进行扫描,而不仅仅是指定的端口80。请注意,扫描所有端口可能需要更长时间才能完成,具体取决于网络和目标主机的性能和响应速度。 8. 要实时显示Nmap的扫描结果 可以使用 -v 参数,它可以提供更详细的输出信息,包括每个扫描的主机和端口的状态以及Nmap正在执行的其他操作。结合使用-v参数和-Pn参数可以进行主机探测,并显示扫描进度和结果。

调度:setTimeout 和 setInterval

调度:setTimeout 和 setInterval setTimeout 允许我们将函数推迟到一段时间间隔之后再执行。 setInterval 允许我们重复运行一个函数,从一段时间间隔之后开始运行,之后以该时间间隔连续重复运行该函数。 setTimeout setTimeout let timerId = setTimeout(func|code, [delay], [arg1], [arg2], …) func|code 想要执行的函数或代码字符串。 一般传入的都是函数。由于某些历史原因,支持传入代码字符串,但是不建议这样做。 delay 执行前的延时,以毫秒为单位(1000 毫秒 = 1 秒),默认值是 0; arg1,arg2… 要传入被执行函数(或代码字符串)的参数列表(IE9 以下不支持) 用 clearTimeout 来取消调度setTimeout 在调用时会返回一个“定时器标识符(timer identifier)” 取消调度的语法: let timerId = setTimeout(...); clearTimeout(timerId); 总结 setTimeout(func, delay, …args) 和 setInterval(func, delay, …args) 方法允许我们在 delay 毫秒之后运行 func 一次或以 delay 毫秒为时间间隔周期性运行 func。 要取消函数的执行,我们应该调用 clearInterval/clearTimeout,并将 setInterval/setTimeout 返回的值作为入参传入。 嵌套的 setTimeout 比 setInterval 用起来更加灵活,允许我们更精确地设置两次执行之间的时间。 零延时调度 setTimeout(func, 0)(与 setTimeout(func) 相同)用来调度需要尽快执行的调用,但是会在当前脚本执行完成后进行调用。

python连接clickhouse

步骤一:安装包 pip install clickhouse-driver pip install clickhouse_sqlalchemy pip install sqlalchemy 步骤二:连接 from clickhouse_sqlalchemy import make_session from sqlalchemy import create_engine import pandas as pd conf = { "user": "ck", "password": "Eitmpou9", "server_host": "192.168.1.142", "port": "8123", "db": "szyx" } connection = 'clickhouse://{user}:{password}@{server_host}:{port}/{db}'.format(**conf) engine = create_engine(connection, pool_size=100, pool_recycle=3600, pool_timeout=20) sql = 'select * from dw_task_visit_log limit 10' session = make_session(engine) cursor = session.execute(sql) try: fields = cursor._metadata.keys df = pd.DataFrame([dict(zip(fields, item)) for item in cursor.

element ui tree组件setCheckedKeys报错

Error in nextTick: “TypeError: Cannot read properties of undefined (reading ‘setCheckedKeys’)” 记得把nextTick方法放在this.permsDialogVisible = true的后面 //打开分配权限对话框 allocatePerms(row) { //获取当前打开的用户所拥有的权限树 this.$http.get(`menu/checkedTree/${row.roleId}`).then(res => { if (res.data.code !== 1) { return this.$message.error('获取用户权限树失败') } this.permsDialogVisible = true this.$nextTick(()=>{ this.$refs.permissionTree.setCheckedKeys(res.data.data) }) }) },

30个HTML+CSS前端开发案例(完结篇)

30个HTML+CSS前端开发案例(完结篇) flex弹性布局-今日头条首页热门视频栏代码实现效果 flex弹性布局-微博热搜榜单代码实现效果 grid网格布局-360图片展示代码实现效果 综合实例-小米商城左侧二级菜单代码实现效果 资源包 flex弹性布局-今日头条首页热门视频栏 代码实现 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>flex弹性布局-今日头条首页热门视频栏</title> <style type="text/css"> body { margin: 0; padding: 0; } a{ text-decoration: none; } .show-monitor { width: 320px; height: 600px; /* border: 2px solid red; */ margin: 50px 0px 0px 50px; } .panel-head { display: flex; /* height: 100px; */ /* 解除图标变形 */ align-items: center; } .panel-head span.panel-head-title { /* 占满全部空间 */ flex-grow: 1; font-size: 20px; margin-left: 10px; } .

ProxyPool 代理池拉取、扫描、过滤教程

GitHub - Python3WebSpider/ProxyPool: An Efficient ProxyPool with Getter, Tester and Server 项目主要是做代理池采集入库到redis,我主要是通过搭建好的 /all 接口 获取到所有 ip ,通过一台高性能服务器来做代理池、拉取、验证、存储,项目的搭建教程请自行查看资料。 以下是我提供拉取、验证、存储的 shell 脚本包括了定时任务,如果需要修改任务请阅读一下代码 使用前需要先安装 nc yum install nc -y shell脚本的目录为 /home/ProxyPool , shell 名称为 FilterAgentPool.sh 定时任务创建时: # 设置定时任务,每小时执行一次 (crontab -l ; echo "0 * * * * /bin/bash /home/ProxyPool/FilterAgentPool.sh") | crontab - 创建命令是: mkdir -p /home/ProxyPool cd /home/ProxyPool touch FilterAgentPool.sh #!/bin/bash # 代理池源,默认从 "http://192.168.2.32:5555/all" 获取 proxy_pool_url="http://192.168.2.32:5555/all" # 代理池文件路径,支持本地文件和网络文件,如果当前路径文件不存在则走网络路径 proxy_pool_file="/home/ProxyPool/proxy_pool.txt" # 设置超时时间和线程数 timeout=3 threads=500 # 打印超时时间和线程数 echo "

Cortex-M0异常和中断

目录 1.概念2.异常类型3.异常优先级定义4.向量表5.异常流程概述接受异常请求压栈和出栈异常返回指令末尾连锁延迟到达 6.EXC_RETURN7.异常入口流程的细节压栈取出向量并更新PC寄存器更新 8.异常退出流程的细节 1.概念 异常是能够引起程序流偏离正常流程的事件,当异常发生时,正在执行的程序就会被挂起,处理器转而执行一块与该事件相关的代码(异常处理)。事件可以是外部输入,也可以是内部产生的,外部产生的事件通常被称作中断或中断请求(IRQ)。异常发生时执行的软件代码为异常处理,而当异常处理与中断事件相关时,又可称作中断处理或中断服务程序(ISR)。在编译好的程序映像中,异常处理是作为程序代码的一部分出现的。当异常处理执行完异常后,就会返回到中断前的程序,并且继续执行之前的任务。因此,异常处理程序需要有种手段来记录中断前程序的状态,并且在中断完成之后能够将这些信息恢复,这可以通过硬件机制或硬件和软件配合来实现。通常的做法是,异常会被划分为多个优先等级,在执行低优先级的异常处理时,更高优先级的异常可以被触发并且执行,这个过程一般被称为异常嵌套。异常的优先级可以是可编程的,也可以是固定的。除了优先级的设置,有些异常(包括多数的中断)可以由软件禁止或使能。 2.异常类型 Cortex-M0处理器内置了中断控制器,并且支持最多32个中断请求(IRQ)输入,以及1个不可屏蔽中断(NMI)输入。根据微控制器产生设计的不同,IRQ和NMI可以由外部产生,也可以由片上外设产生。此外,它还支持多个内部异常。 Cortex-M0的每个异常源都有一个单独的异常编号,NMI的编号为2,而片上外设和外部中断的则为16~47。1 ~ 15的其他编号,用于处理器内部的系统异常,这个范围内的有些编号还没有使用。 每种异常类型都有对应的优先级,有些异常的优先级是固定的,而有些则是可编程的。异常类型、编号和优先级如下: 不可屏蔽中断(NMI):NMI同IRQ类似,只是它不能被禁止,并且优先级仅次于复位,它对于工业控制和汽车之类的高可靠性系统非常有用。根据微控制器设计的不同,NMI可以用于掉电处理,也可以连接到看门狗单元,以便在系统停止响应时将系统复位。由于NMI不能被控制寄存器禁止,其响应的及时性就得到了保证。硬件错误:硬件错误异常用于处理程序执行时产生的错误,这些错误可以是试图执行未知的操作码、总线接口或存储器系统的错误,也可以是试图切换至ARM状态之类的非法操作。SVC(请求管理调用):SVC指令执行时就会产生SVC异常,其通常用在具有操作系统的系统中,为应用程序提供了访问系统服务的入口。PendSV(可挂起的系统调用):PendSV是用于带操作系统的应用程序的另外一个异常,SVC异常在SVC指令执行后会马上开始,PendSV在这点上有所不同,它可以延迟执行,在OS上执行PendSV可以确保高优先级任务完成后才执行系统调度。系统节拍:NVIC中的Sys Tick定时器为OS应用可以利用的另一个特性。几乎所有操纵系统的运行都需要上下文切换,而这一过程通常需要依靠定时器产生定时中断来完成。Cortex-M0处理器内集成了一个简单的定时器,这样就使得设备间移植操作系统更加容易。中断:Cortex-M0微控制器可以支持1 ~ 32个中断,中断信号可以连接到片上外设,也可以通过I/O端口连接到外部中断源上。外部中断只有在使能后才能使用,如果中断被禁止了,或者处理器正在运行另外一个相同或更高优先级的异常处理,则该中断请求会被存储在挂起状态寄存器中。当高优先级的中断处理完成或返回后,挂起的中断请求才可以执行。应该注意的是,在微控制器的外部接口中,外部中断信号可以是高电平也可以是低电平,或者可以通过编程配置。 3.异常优先级定义 在Cortex-M0处理器中,每个异常都对应一个优先级。优先级决定了异常是否执行或者是否延迟执行(处于挂起态),Cortex-M0处理器支持3个固定的最高优先级以及4个可编程的优先级。对于具有可编程优先级的异常,优先级配置寄存器为8位宽,而且只能使用最高两位,如下: 因为第0到5位没有使用,故它们读出始终为0,对它们的写操作没有意义。在这个设定下,可以使用的优先级为0x00(最高)、0x40、0x80和0xc0(最低),再加上3个固定的优先级,Cortex-M0总共具有7个优先级,如下: 为了使Cortex-M0/M3设备间的软件移植更为简单,处理器没有使用优先级寄存器的最低位,而是使用了最高位。这样在具有较宽优先级寄存器的设备上编写的程序,在优先级位数较少的设备上就可以正常工作。如果发生了已经使能的异常事件(例如中断、Sys Tick定时器等),此时也没有其他的异常处理正在运行,而且PRIMASK(中断屏蔽寄存器)没有屏蔽掉该异常,那么处理器就会接受该异常并且执行对应的异常处理。从当前正在运行的任务切换到异常处理的过程叫抢占。如果处理器已经在运行另外一个异常处理,而新异常的优先级大于正在执行的,这时就会发生抢占。正在运行的异常处理就会被暂停,转而执行新的异常,这个过程通常被称为中断嵌套或异常嵌套。新的异常执行完毕后,之前的异常处理会继续执行,并且在其结束后会返回到程序线程中。不过,如果处理器正在运行的另外一个异常处理的优先级相同或者更高,新的异常将会等待并且进入挂起状态。挂起的中断将会一直等到当前异常等级改变。可以通过NVIC中映射到存储空间的寄存器访问异常的挂起状态,对NVIC的一个寄存器执行写操作可以清除异常挂起状态,清除后,该异常将不再执行。如果两个异常同时发生,并且它们被赋予相同的优先级,异常编号较小的异常将会首先执行。Cortex-M0处理器对中断嵌套的支持无须任何软件干预。 4.向量表 对于Cortex-M0处理器,内置的中断控制器NVIC支持向量中断,这就意味着不同中断的异常向量是独立的,而且中断服务程序的入口自动分配,无须软件干预。 当Cortex-M0处理器要处理中断服务请求时,它需要首先确定异常处理的起始地址,所需的信息叫做向量表,它存储在存储器空间的开始位置。向量表包括了系统中可用异常的异常向量,以及主栈指针(MSP)的初始值。向量表如下: 异常向量的存储顺序同异常编号一致,由于每个向量表都是1个字(4字节),异常向量的地址为异常编号乘4。每个异常向量都是异常处理的起始地址,而且其最低位置1,表明异常处理为Thumb代码。 5.异常流程概述 接受异常请求 处理器要接受一个异常,需要满足以下条件: 对于中断和Sys Tick中断请求,中断必须使能。处理器正在执行的异常处理的优先级不能相同或更大。PRIMASK中断屏蔽寄存器没有屏蔽掉异常。 应该注意的是,对于SVC异常,如果用到SVC指令的异常处理的优先级与SVC异常本身相同或者更大,这种情况就会引起硬件错误异常处理的执行。 压栈和出栈 为了使被中断的程序能正确继续执行,在程序切换至异常处理前,处理器当前状态的一部分应该被保存。不同架构处理器的处理方法不同,Cortex-M0处理器采用了硬件自动处理的方法来备份和恢复处理器状态,如果有必要,程序中还需要增加软件处理过程。当Cortex-M0处理器接受了一个异常以后,寄存器组中的一些寄存器(R0到R3、R12和R14)、返回地址(PC)以及程序状态寄存器(xPSR)会被自动压入当前栈空间里。链接寄存器(LR/R14)则会被更新为异常返回时使用的特殊值(EXC_RETURN),然后异常向量被自动定位而且异常处理开始执行。异常处理过程执行到最后时,将会利用执行特殊值(EXC_RETURN)来触发异常返回机制。处理器还会查看当前是否还有其他异常需要处理,如果没有,处理器就会恢复之前存储在栈空间的寄存器值,并继续执行中断前的程序。自动保存和恢复寄存器内容的操作被称为“压栈”和“出栈”,这种机制使得异常处理可以跟普通的C函数一样处理,同时也减小了软件开销以及回路大小(无须另外的寄存器组),因此也就降低了系统的功耗。 自动压栈过程没有备份所有的寄存器,如果其他的寄存器在异常处理过程中被修改了,只能通过软件来保存和恢复。 异常返回指令 和其他的一些处理器不同,Cortex-M0的中断处理无须特殊的返回指令。相反地,Cortex-M0只是用普通返回指令,而加载到PC中的数值则会触发异常返回,这样就使得异常处理可以和普通C函数一样使用。 两个不同的指令可以用于异常返回: 当其中的一个指令执行,而且EXC_RETURN特殊值被加载到程序计数器(PC)中时,异常返回机制就会启动。如果加载到PC的值不是EXC_RETURN,则其会被当做普通的BX或POP指令。 末尾连锁 如果当其他的异常处理完成后,还有异常处于挂起状态,这时处理器不会返回到中断前的程序,而是重新进入异常处理流程,这也被称为末尾连锁。当末尾连锁发生时,处理器不必马上恢复栈的值,因为这么做的话还得将它们重新压栈。异常的末尾连锁降低了异常处理的开销,因此也提高了能耗效率。 延迟到达 延迟到达是Cortex-M0的优化机制,它可以加快高优先级异常的处理。如果在低优先级异常压栈过程中发生了高优先级异常,处理器就会首先处理高优先级异常。 由于每个中断都需要同样的压栈操作,后至的高优先级中断发生后将会继续之前的压栈过程。压栈完成后,高优先级的异常向量就会被取出以替代低优先级的那个。 如果没有延迟到达优化,在低优先级异常开始时,处理器就必须抢占并且重新进入异常处理流程,这样就会带来较长的延迟以及较大栈空间的使用。 6.EXC_RETURN EXC_RETURN为架构定义的特殊值,用于异常返回机制,这个值在异常被接受并且压栈完成后会自动存储到链接寄存器中(LR或R14)。EXC_RETURN为32位数值,并且高28位置1,第0位到第3位则提供了异常返回机制所需的信息。 Cortex-M0中EXC_RETURN的bit0保留,且必须为1。EXC_RETURN的bit2表示出栈恢复寄存器时使用的是主栈(MSP)还是进程栈(PSP)。EXC_RETURN的bit3表示处理器要返回线程模式还是处理模式。Cortex-M0处理器使用的EXC_RETURN的合法值如下: 由于EXC_RETURN的值在异常入口处被自动加载到LR中,异常处理会把它当成普通的返回地址。如果返回地址无须保存在栈上,异常处理也可以像普通函数一样,通过执行“BX LR”来触发异常返回并且返回到中断前的程序。另外,如果异常处理需要执行函数调用,就需要将LR压栈。 在异常处理的最后,已经压栈的EXC_RETURN值将会通过POP指令直接加载到PC,这样就能触发异常返回流程并且返回到中断前的程序。 下面是不同EXC_RETURN值的产生和使用情况: 如果线程正在使用主栈(CONTROL寄存器的第1位为0),在进入第一个异常时,LR的值被置为0xFFFFFFF9,而进入嵌套异常时则为0xFFFFFFF1。 如果线程使用进程栈(CONTROL寄存器的第1位为1),在进入第一个异常时,LR的值被置为0xFFFFFFFD,而进入嵌套异常时则为0xFFFFFFF1。 由于EXC_RETURN数值的特殊格式,正常返回指令如果返回到0xFFFFFFFX范围的地址,会被处理器当做异常返回,而不是普通的返回指令。 7.异常入口流程的细节 当异常发生时,以下的情况会随之发生: 压栈并且栈指针更新。处理器取出异常向量并且将其写入PC。寄存器更新(LR、IPSR和NVIC寄存器)。 压栈 如图所示,当异常发生时,8个寄存器会被自动压栈,这些寄存器包括R0到R3、R12、R14(链接寄存器)、返回地址(下一条指令的地址或程序计数器)和程序状态寄存器(xPSR)。用于压栈的栈为当前活动栈,如果异常发生时处理器处于线程模式,根据CONTROL寄存器第1位的不同,压栈可以使用进程栈或主栈,如果CONTROL[1]为0,则使用主栈。如果异常发生时处理器处于线程模式并且CONTROL[1]置1,则会使用进程栈。 对于嵌套异常,压栈时总会使用主栈,因为处理器当前处于处理模式,这种情况下只能使用主栈。 将寄存器R0—R3,R12,PC,LR和xPSR保存到栈中的原因是,这些寄存器被称为“调用者保存寄存器”。C函数不必保留这些寄存器的值。为了使异常处理能够像普通C函数一样使用,这些寄存器需要由硬件进行保存和恢复,这样在中断前的程序继续执行时,这些寄存器的值就能和异常发生以前一样。 如上图所示,压栈时保存到栈里的数据被统称为“栈帧”。在Cortex-M0处理器中,一个栈帧总是双字对齐的,这样就能确保栈的使用遵循AAPCS标准。如果上一个压入的数据可能会处于非双字对齐的,压栈机制就会将压栈的位置自动调整到下一个双字对齐的地址上,并且在栈中的xPSR寄存器中设置标志(第9位),表明发生了双字栈调整。 在出栈过程中,处理器会检查栈中的xPSR的标志,并且根据标志的不同对栈指针做出相应的调整。 寄存器的压栈顺序如下所示: 当压栈结束后,栈指针会得到更新,并且主栈指针会被选择为当前栈指针(处理模式总是使用主栈),然后异常向量也会被取出。 取出向量并更新PC 压栈结束后,处理器会从向量表中取出异常向量,然后将向量写到PC,并且将从这个地址中开始异常处理的取指。 寄存器更新 异常处理开始执行后,LR的值会被更新为相应的EXC_RETURN值,这个值将会被用作异常返回,IPSR也会被更改为当前处理异常对应的异常编号。

利用飞书来实现信息存储和在线远程预览

利用飞书来实现信息存储和在线远程预览 文章目录 利用飞书来实现信息存储和在线远程预览1. 需求2. 实现方法2.1 创建表格2.2 创建飞书捷径2.3 客户端上传数据 3. 实现远程预览 1. 需求 在传统的远程监控和存储数据的项目中,我们需要一台有公网IP的服务器来存储设备发上来的数据,同时为了让人能更好的预览数据,我们还需要一个预览的客户端程序,这是一种非常成熟的方案,对于企业来说也非常简单。 但是有的时候,我们不需要搞那么复杂,我们的需求就是定时记录一下设备数据,然后还可以简单的预览它们,这时候我们就需要去找现成的服务来搞这件事,比如用腾讯云、阿里云、华为云,都为个人提供些免费的服务。 本文要说的是利用飞书来实现实时记录的效果,即:实现用户程序向飞书发送报文,飞书将其记录到飞书表格,被授权的用户可以打开这个表格,来通过web查看被记录的信息,这样飞书既充当了服务器,用充当了可以被访问的web显示界面,成本极低,操作简单。 2. 实现方法 2.1 创建表格 首先在飞书中新建一个表格,这个表格将充当服务器的表,如下: 正如我们在服务器创建表一样,创建的表格也需要填充每个列的含义,要写在表格的第一行,后面会为每一列添加一个JSON里面的选项,如下: 2.2 创建飞书捷径 在创建表格完成后,下面我们在飞书上创建捷径。 方法是,点击左边列表内的工作台-》找到飞书捷径打开,如下: 点击创建飞书捷径,如下: 然后会出现下面界面,然后点击触发器的加号,如下: 按下图进行设置 选择应用选项选择webhook,选择触发器勾选catch hook,设置选项这个是重点,其中这个webhook地址就是你上传信息所使用的目的地址,而参数就是你用来传输数据的格式。 上图中这个参数的设置是有固定格式的,它是一个json格式,如下就是我当时填选的内容: { "data":{ "file_name": "---", "file_ver": "---", "time": "---", "APIVer": "---", "cDevID": "---" , "CSoftVer": "---" , "cHardVer": "---", "sDevID": "---", "bleSoftVer": "---" } } 然后点击确定,就会回到创建飞书捷径的界面,然后点击选择操作,如下: 按如下操作,在设置选项中选择前面创建的表格,这时候再创将表格的时候写好的title就会被列出来,通过点击右边的加号,将标题和json中的参数进行绑定,如下: 上一步绑定完成后,点击下面的确认,就会进入下面界面,点击创建,并给这个飞书捷径一个名字,在开启就可以了,如下: 2.3 客户端上传数据 上传数据的方法是通过http的post来实现的,因此只要是能联网的设备,不管是ESP32等支持wifi设备,还是4G网络等其它嵌入式,实现这个应该都不难,本文就是用python在pc机上来模拟http的post请求来实现,如下: # pip install requests import requests if __name__ == '__main__': # url是创建飞书捷径的webhook地址 url = "

BUUCTF-练习场-WEB-第一部分(8道)

[极客大挑战 2019]EasySQL 1 payload:1' or 1=1# '是闭合前面的查询语句,or 1=1恒成立,可以使用or句子绕过判断,#用于注释,注释后面的内容不再执行,所以该sql命令会返回表内所有内容,其实就是实现一个闭合查询,绕过判断,返回内容 [HCTF 2018]WarmUp F12查看源代码,发现注释中有一个source.php文件名称 访问这个文件,看到了源码,同时源码中还提及了一个hint.php的文件 访问hint.php,得到了flag所在的文件名 源码中有这样一段内容 如果有file值的传入,且file为字符串,而且通过了checkFile的验证,则将file文件包含,我们可以通过这个文件包含,回显ffffllllaaaagggg的内容。 注:include,包含并执行文件。被包含文件先按参数给出的路径寻找,如果没有给出目录(只有文件名)时则按照 include_path 指定的目录寻找。如果在 include_path 下没找到该文件则 include 最后才在调用脚本文件所在的目录和当前工作目录下寻找。如果最后仍未找到文件则include 结构会发出一条警告;这一点和 require 不同,require会发出一个致命错误。 那么,可以构造payload读取到文件,得到flag: ?file=source.php?../../../../../../../../../../../../ffffllllaaaagggg [极客大挑战 2019]Havefun 查看源代码,注释中包含一段源码,get传参,变量cat,当cat==dog时,回显Sys{cat_cat_cat} 那么,payload为: ?cat=dog //成功回显payload [ACTF2020 新生赛]Include 点击tips,发现url中file=flag.php,但是并没有回显flag 这里我们可以使用这样的payload格式去构造: php://filter/read=convert.base64-encode/resource=xxx.php php://filter 是php中独有的一个协议,可以作为一个中间流来处理其他流,可以进行任意文件的读取。 resource=<要过滤的数据流> 指定了你要筛选过滤的数据流。 read=<读链的筛选列表>可以设定一个或多个过滤器名称,以管道符(|)分隔。 write=<写链的筛选列表> 可以设定一个或多个过滤器名称,以管道符(|)分隔。 <;两个链的筛选列表> 任何没有以 read= 或write=作前缀 的筛选器列表会视情况应用于读或写链。 php://filter与包含函数结合时,php://filter流会被当作php文件执行。所以我们一般对其进行编码,阻止其不执行,从而读取文件内容。 read=convert.base64-encode,用base64编码输出,不然会直接当做php代码执行,看不到源代码内容。 payload: /?file=php://filter/read=convert.base64-encode/resource=flag.php 读取到了一段base64编码的字符串,将该字符串进行转码后,得到flag [ACTF2020 新生赛]Exec 打开后是一个ping的功能,我们尝试用|进行命令拼接,发现ls命令可以直接执行,并且读取到根目录下的文件信息,在根目录下有一个flag文件 命令:|ls ../../../../../../../../../../../../../ 使用命令,直接读取flag文件内容,获得flag: |cat ../../../../../../../../../../../../../flag [强网杯 2019]随便注 sql注入了,先来判断一下字段数 1' order by 1 # 和 1' order by 2 # 可以正常回显 1' order by 3 # 的时候报错,说明字段数为2 尝试union联合注入

接口自动化测试的概述及流程梳理~

接下来开始学习接口自动化测试。 因为之前从来没接触过,所以先了解一些基础知识。 1.接口测试的概述 2.接口自动化测试流程。 接口测试概述 接口,又叫API(Application Programming Interface,应用程序编程接口),用于系统与系统或代码模块与模块之间的交互和数据传输。 代码内部模块与模块之间的接口,叫程序接口。 系统与系统之间,通过网络数据的传递进行交互,叫做协议接口。 接口测试,即对接口之间交互和数据传输的稳定性、正确性等方面进行测试。一般指协议接口。 为什么要做(自动化)接口测试? 1、由于现在各个系统的复杂度不断上升,导致传统的测试方法成本上升且测试效率大幅下降,而接口测试相对于UI测试更加稳定,且相对容易实现自动化持续集成,可以减少人工回归测试的时间成本,缩短测试周期。 2、接口测试可以更早的介入到项目开发中,一般只要接口定义好了,就可以写代码了。而功能测试必须要等系统提供可测的界面后才能进行。 3、相对于UI测试(某些测试环境搞起来贼麻烦)来说,接口测试可以更简单全面地覆盖到底层的代码逻辑,从而发现一些隐藏bug。 4、从安全层面来说,现在大部分系统前后端框架是分离的,只依赖前端进行限制已经不能满足系统的安全要求,需要后端同步进行控制,所以测试也需要从接口层面进行验证。 5.越来越多的团队开始接收DevOps所倡导的高度协同,研发、测试、运维及交付一体化的思维,对测试效能提出了更高的要求。 接口测试原理 模拟客户端向服务器发送请求,服务器接收后进行处理并向客户端返回应答,客户端再接收应答的过程。 测试范围 业务功能(包括正常、异常场景是否实现) 业务规则(覆盖度是否全面) 参数验证(边界、业务规则是否达到要求) 异常场景(重复提交、并发提交、事务中断、多机环境、大数据量测试) 性能测试(响应时间、吞吐量、并发数、资源要求) 安全测试(权限验证、SQL注入等) 接口自动化测试流程 1、熟悉业务和需求,评估可行性和测试范围 并不是所有的业务都适合自动化,需要评估可行性、性价比、可持续性等等。比如一个项目,只做1.0版本,做完就结束了,还做什么自动化? 2、确定方案。 具体业务具体分析,与团队完成最适合的工具选型。 常用的方案有: ①现成的开源工具:postman/jmeter等 ②一些第三方平台(收费的) ③自己公司开发自动化测试平台(少,且平台质量很难把控) ④代码编辑自动化框架,pytest等 3、设计自动化测试执行框架搭建。 什么是框架?就是让接口测试脚本运行的一整套环境,包括脚本语言、工具、测试用例、执行策略、测试报告、日志收集、数据分析、报告可视化等。 4、执行测试 通过我们设计的框架执行测试用例,在过程中需要持续关注整个框架可优化的点。主要流程为:发送请求–获取结果–解析结果 5、输出测试报告 同样通过测试框架输出测试报告,报告应该注意要结果明确、结构清晰 6、持续集成 对接口测试而言,持续集成是自动化的关键。在初步实现接口自动化测试之后,还需要持续的加强自动化程度。 ①流程方面:在过程中不断加强接口异常场景覆盖度,并逐步向系统测试、冒烟测试方面延伸,最终达到全流程自动化 ②结果展示:更加丰富的结果展示、数据统计、质量分析等。 ③问题定位:通过报错信息、日志、截图等手段,降低开发定位问题的难度。 ④结果校验:不断提高结果的自动化校验能力,如数据库信息校验。 ⑤拓展:向性能测试/安全测试等方向拓展,通过自动化手段监控接口性能指标是否正常。 环境准备 开始系统学习前需要准备一些环境。 python环境 安装pytest、requests库 了解一款抓包工具,例如fiddler,charles postman/jmeter安装 学习安排上 如果你不想再体验一次学习时找不到资料,没人解答问题,坚持几天便放弃的感受的话,在这里我给大家分享一些自动化测试的学习资源,希望能给你前进的路上带来帮助。 视频文档获取方式: 这份文档和视频资料,对于想从事【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴我走过了最艰难的路程,希望也能帮助到你!以上均可以分享,点下方小卡片进群即可自行领取。

csdn积分怎么获得

CSDN积分可以通过以下方式获得: 发表原创文章并被审核通过,可以获得一定的积分奖励;在CSDN论坛上发布有价值的回复或帖子,也可以获得积分;参加CSDN举办的各种活动,如技术大赛、线下活动等,有机会获得积分;购买CSDN的付费服务或者付费课程,也可以获得相应的积分奖励。 总之,想要获得更多的CSDN积分,需要积极参与CSDN社区的各种活动,以及不断学习、分享、交流。

C语言学习笔记——自定义数据类型

目录 前言 一、结构体 1.结构体的声明 2.结构体的定义 3.结构体的自引用 4.结构体的内存对齐 5.结构体调用与传参 二、位段 1.位段的声明与调用 2.位段的内存分配 三、枚举类型 1.枚举类型的定义 2.枚举类型的优点 四、联合类型 1.联合类型的定义 2.联合类型的特点 3.联合体的大小计算 结束语 前言 C语言为我们提供了整型,浮点型两种基础的数据类型,同时为了方便程序员完成复杂的代码,C语言还提供了三种自定义数据类型——结构体,位段,枚举和联合体。 一、结构体 结构是一些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量。 1.结构体的声明 struct student { char name[20]; int age; double score; }stu1; 该段代码即声明一个名为"student"的结构体,该结构体中含有三个元素,分别为char类型的数组name,int类型的age,double类型的score。同时在声明完结构体类型后,直接创建了一个名为"stu1"的全局变量。 这就是结构体的简单声明,总结下来就是首先在"struct"后加上结构体类型名称,然后在后方大括号中声明该结构体各个元素的类型,最后在大括号后加上分号";"。 除了上述定义方式外,我们也可以采用下面这种不声明结构体名称的定义方式,称为匿名结构体类型。 注意,下方代码声明了两个看上去一模一样的匿名结构体,但实际上编译器会把它们当成两种不同的类型,因此不能使用“stu1”给“stu2”赋值或进行其他运算。 struct { char a; int b; double c; }stu1; struct { char a; int b; double c; }stu2; 2.结构体的定义 struct student { char name[20]; int age; double score; }stu1; struct student stu2; int main() { struct student stu3 = {"

华为模拟器ensp安装

记录一次自己安装ensp的完整过程,之前大学时安装过,这次用公司的电脑安装一下,准备用来做做实验。 在网上找了半天的安装包资源,想起来大学时保存过在网盘里,就直接用了,这里放上链接 链接:https://pan.baidu.com/s/1M3U4ENSygTbUk-5_P9sm5Q 提取码:mfwt 我的安装环境是一台windows11的笔记本电脑,为避免出错最好还是安装在win7或者win10的电脑系统上可能兼容问题会少一些,公司的电脑没时间重装,也就直接上手安装了 1.在安装edsp之前,先安装另外三个基础插件,否则安装不上ensp 基本都是傻瓜式安装,一直点下一步就可以,注意安装位置不要选择在系统盘 点击浏览修改安装目录 2.安装完三个插件后,打开ensp安装包,开始安装主程序,语言选择中文简体 点击下一步,还是注意下不要安装到系统盘 点击下一步,到检测环节,会检测是否有安装刚才的三个插件(如果没有安装,则会提醒需要安装后再安装ensp),点击下一步 安装持续3-4分钟左右 安装完成后打开提示放行防火墙 打开控制面板-防火墙-允许应用或功能通过防火墙,先点击更改设置,再找到ensp,把能√的都√上,然后点击确定,放行防火墙 如果没找到有ensp,点击右下角的 允许其他应用,找到ensp安装目录,点击ensp的应用程序文件 3.此时,已经完成了所有的准备工作,但还不算安装成功,打开ensp拉一个AR201出来,启动!!! 果然还是出现一点错误,满屏的####### 百度了一下,说是还需要再放行应用ensp_vboxserver,再次打开控制面板-防火墙-允许应用或功能通过防火墙,找到这个应用,打上√,点击确定(没有找到应用的需要点击右下角允许其他应用,找到ensp_vboxserver安装目录D:\Program Files\Huawei\eNSP\vboxserver\eNSP_VBoxServer.exe) 成功! 安装其实挺简单,只是ensp的报错总是奇奇怪怪的,有些甚至重装系统才能解决,还好只报了一个小错误,自己也没太注意,这次虽然算不上顺利,但也并不困难,中途不小心关掉了csdn的网页,吓死我了,还好在草稿里找到了,csdn的云端保存功能确实好用,优秀!至此完成了我的一次ensp安装过程的记录以及我的第一个csdn的文章。

Linux 进程调度机制详解

Linux进程调度机制是操作系统中的一个非常重要的组成部分,它负责在多个进程之间分配CPU时间片,以确保系统的公平性和高效性。在Linux中,进程调度机制使用CFS(完全公平调度器)算法来实现。下面将详细讲解Linux进程调度机制的相关内容。 进程状态 在Linux中,进程可以处于多个不同的状态中。这些状态包括运行状态、等待状态、休眠状态和停止状态等。进程调度器需要根据进程状态的变化来合理地分配CPU时间片。 运行状态:当进程正在使用CPU时,它处于运行状态。 等待状态:当进程正在等待某个事件的发生时,它处于等待状态。例如,当一个进程正在等待I/O操作完成时,它就处于等待状态。 休眠状态:当进程正在等待某个事件的发生时,并且它已经放弃了CPU的控制权,它就处于休眠状态。在这种状态下,进程不会占用任何CPU时间。 停止状态:当进程被停止时,它就处于停止状态。在这种状态下,进程不会占用任何CPU时间。 进程优先级 在Linux中,每个进程都有一个优先级。这个优先级是一个整数值,它的取值范围是-20到19。优先级较高的进程会在CPU时间片分配中优先获得更多的时间。进程的优先级可以通过nice命令进行设置,也可以在进程创建时指定。 在 Android 中设置优先级的方法: // 数值越小,优先级越高 Process.setThreadPriority(); 时间片分配 时间片是CPU分配给进程的一个单位。当进程处于运行状态时,进程调度器会给它分配一个时间片。当时间片用完时,进程会被暂停,CPU会分配给其他进程。时间片分配的大小会影响系统对进程的响应时间和CPU时间片的浪费程度。时间片分配越短,系统对进程的响应时间就越灵敏,但是这也可能导致CPU时间片的浪费。 CFS算法 在Linux中,采用的进程调度算法是CFS(完全公平调度器)算法。CFS算法通过使用红黑树来维护进程优先级和时间片的分配,使得每个进程都能公平地获得CPU时间片。CFS算法将所有可运行的进程按照优先级放置在红黑树上,每个进程的优先级被转化为一个虚拟运行时间,运行时间越短的进程优先级越高,运行时间越长的进程优先级越低。当一个进程运行时,它的虚拟运行时间会不断增加,表示它已经使用了一定的CPU时间片。进程调度器会选择虚拟运行时间最小的进程运行,如果有多个虚拟运行时间相同的进程,进程调度器会选择其中最先插入红黑树的进程运行。这样就能保证每个进程都能公平地获得CPU时间片。 实时进程 除了普通进程外,在Linux中还支持实时进程。实时进程需要在预定的时间内获得CPU时间片,以确保系统对实时任务的响应。Linux中支持两种类型的实时进程: 实时进程(SCHED_FIFO):实时进程的优先级最高,只有在其执行完毕或者阻塞时才能运行其他进程。 实时轮询进程(SCHED_RR):实时轮询进程的优先级次之,与普通进程共享CPU时间片。 在Linux中,进程调度器会优先调度实时进程。如果没有实时进程需要运行,则会调度普通进程。 总之,Linux的进程调度机制通过进程状态、进程优先级、时间片分配和CFS算法来合理地分配CPU时间片,以提高系统的响应速度和公平性。此外,Linux还支持实时进程,以确保系统对实时任务的响应。

文件二进制数组 base64相互转化

1. 文件转二进制 private static byte[] getFileByte(String imgUrl) throws Exception { InputStream inStream = new FileInputStream(imgUrl); ByteArrayOutputStream outStream = null; try { outStream = new ByteArrayOutputStream(); byte[] buffer = new byte[2048]; int len = 0; while ((len = inStream.read(buffer)) != -1) { outStream.write(buffer, 0, len); } return outStream.toByteArray(); } catch (Exception e) { e.printStackTrace(); } finally { if (inStream != null) { inStream.close(); } if (outStream != null) { outStream.close(); } } return null; } 2.

JAVA实现文件预览功能

近期做的项目要求实现文件在线预览功能,可支持多种文件类型,TXT,DOC,PDF,XLS , 最好支持压缩包的预览功能.没办法,只能网上找啊 看了个遍,都是些不靠谱的,转来转去的一个能用的都没有,付费的产品有永中啊,OFFICE 365啊,这些大概一搜都能搜到,价格也不是很贵 BUT能不用钱解决问题,就尽量自己来搞,毕竟这个项目目前还在试行期,前期投入还不值得,废话不多说,上图上代码. 西天取经的路上 在网上找到一个开源项目 https://gitee.com/kekingcn/file-online-preview.git 就是这个 因为现在大多数付费产品也是基于OpenOffice的 这个开源项目的存在着实解决了我的问题..感谢代码拥有者. 这个项目下下来的时间还是挺慢的 需要耐心等待下...(估计是我当时网络问题) 下完后 整个项目的结构如图,至于什么SpringBoot的 大家去搜好了 肯定比我讲的好,你们只要会用就行了. down下来 改了下配置 主要是 application-dev.properties这个文件需要改动 这个是楼主的配置 桌面上建立一个 demo 的文件夹 哦 差点忘记了 记得下载 Open office 安装就默认路径就行 图标如下图 网上的下载都比较慢 大家可以用我分享的链接下载 不用谢 安装一直下一步就行 链接: https://pan.baidu.com/s/1YSbOMFn62uF7lKYr4Yflfw 密码: ehi7 Redis 也不要忘了哈 怎么安装 这个大家都会 Redis 服务 和 OpenOffice服务开启后 直接启动项目 直接运行这个main 方法 楼主端口是8012 直接浏览器 直接上传文件就可以了 楼主传了个压缩包 来看下效果 完美预览成功 再试个 word 也是成功 好了 推荐大家试用下 有什么问题可以来问我 

介绍一款HCIA、HCIP、HCIE的刷题软件

华为认证考试分为三个等级,分别为工程师HCIA、高级工程师HCIP、专家HCIE,等级越高,考试难度越大。 本篇带大家详细了解华为数通题库刷题工具的详细操作步骤。 操作须知:本款刷题工具为一款刷题小程序,无需安装即可在线使用。 一、界面认知 从主页面看,包含章节练习、模拟考试、错题集等常用操作。 二、如何刷题 2.1 章节练习 点击主界面【章节练习】,如下图红色框所示: 2.2 选择题库 点击题库类别,选择对应科目题库章节。 举例:如数通HCIP(H12-821)题库第一章:IP路由基础 2.3 正式刷题 进入题目详情,有答题和背题两种模式。 2.3.1答题模式需自己先选择答案,如选择正确,则蓝色框标记,如答案错误,则红色框标记,并同步用蓝色框标记正确答案,可通过解析查看答案。 2.3.2 背题模式,直接显示正确答案和解析 2.3.3 连续刷题,可直接通过底部菜单【下一题】或题题目序号随机选择 刷完题后,反馈题库列表可继续选择其他章节。 如何考试 模拟考试完全按照正常考试的要求进行。 3.1 进入考试 点击【模拟考试】,点击【全真模拟】,选择对应模拟卷 3.2 开始答题 进入答题页面,选择答案后按顺序以此完成答题,答题结束,点击【交卷】,提交交卷后将显示你的分数和答题正确率。 原则来说,为了考试稳妥,尽量多次模拟考试分数均在900分以上。 如果想知道这款工具的详细信息,可关注+点赞后,私信【题库】了解。

Java指导书练习题——文件操作

文件操作 1.实验目的 (1)学习 File类的使用。 (2)学习在程序中新建文件。 (3)学习在程序中对文件读取和写人操作。 (4)学习在程序中获取文件信息。 (5)学习在程序中查看目录内容 (6)学习在程序中删除文件。 2.实验要求 编写六个 Java 程序,实现文件的常见操作3序模板(1)新建文件程序 Filel.java,序功能是创建新的文件。 File1.java public class File1 { public static void main(String[] args) { if (args.length==0) { System.out.println("未输入任何附带参数"); }else{ for (int i=0;i<args.length ; i++) { System.out.println(args[i]); } } } } File2.java import java.io.*; public class File2 { public static void main(String[] args) throws IOException { BufferedWriter out = new BufferedWriter(new FileWriter("d:\\a.txt")); out.write("岭南师范学院"); out.newLine(); out.write("Java 程序设计"); out.flush(); out.close(); } } File3.

罗德里格旋转公式的推导

罗德里格旋转公式是计算三维空间中,一个向量绕旋转轴旋转给定角度以后得到的新向量的计算公式。这个公式使用原向量,旋转轴及它们叉积作为标架表示出旋转以后的向量。可以改写为矩阵形式,被广泛应用于空间解析几何和计算机图形学领域,成为刚体运动的基本计算公式。 四元数可以很方便地表示旋转变换。但在很多场合中,使用矩阵形式和向量形式表达旋转更有利于推导。向量旋转公式最早由法国数学家本杰明·奥伦德·罗德里格(Benjamin Olinde Rodrigues(1795–1851))导出,后来被应用在很多领域。 设v是一个三维空间向量,k是旋转轴的单位向量,则v在右手螺旋定则意义下绕旋转轴k旋转角度θ得到的向量可以由三个不共面的向量v, k和k×v构成的标架表示: 推导过程如下: 如果被旋转向量v与旋转轴k(k为单位向量)相互垂直,那旋转变换不难表示。而对于与旋转轴k呈任意角度的向量v,可以通过正交分解,把被旋转向量转化为与旋转轴平行的分量和与旋转轴垂直的分量,其中与旋转轴平行的分量在旋转中是不变的,而与旋转轴垂直的分量则恰好旋转了角度θ,把与旋转轴平行的分量与旋转以后的与旋转轴垂直的分量加在一起,即可得到旋转以后的向量。 第一步是如何对向量v做正交分解: ​​​​​​​ 利用向量投影公式,可以得到的表达式: 通过做减法,得到 利用外积可以计算与 和k都垂直,且长度等于的向量w: 旋转以后的向量可以表示为: 与相加即可得到旋转以后的向量表达式: 在计算机图形学中,罗德里格向量旋转公式通常被用来填写旋转矩阵。如果把k和v分别写为列向量: 则旋转以后的向量可以表示为: 其中 其中E是3阶单位矩阵。需要注意的是,公式中的第二项不是点积,而是张量积,得到的是一个3行3列的矩阵。

Linux网络高级——Modbus TCP及Modbus库

Modbus是一种串行通信协议,是Modicon公司(现在的施耐德电气 Schneider Electric)于1979年为使用可编程逻辑控制器(PLC)通信而发表。Modbus已经成为工业领域通信协议的业界标准(De facto),并且现在是工业电子设备之间常用的连接方式。 Modbus协议是一项应用层报文传输协议,包括ASCII、RTU、TCP三种报文类型。 标准的Modbus协议物理层接口有RS232、RS422、RS485和以太网接口,采用master/slave方式通信。 Modbus TCP协议格式 ModbusTCP的数据帧可分为两部分:MBAP+PDU 1)报文头MBAP 2)功能代码 3)PDU详细结构 0x01:读线圈 在从站中读1~2000个连续线圈状态,ON=1,OFF=0 请求:MBAP 功能码 起始地址H 起始地址L 数量H 数量L(共12字节) 响应:MBAP 功能码 数据长度 数据(一个地址的数据为1位) 0x05:写单个线圈 将从站中的一个输出写成ON或OFF,0xFF00请求输出为ON,0x000请求输出为OFF 请求:MBAP 功能码 输出地址H 输出地址L 输出值H 输出值L(共12字节) 响应:MBAP 功能码 输出地址H 输出地址L 输出值H 输出值L(共12字节) 0x0F:写多个线圈 将一个从站中的一个线圈序列的每个线圈都强制为ON或OFF,数据域中置1的位请求相应输出位ON,置0的位请求响应输出为OFF 请求:MBAP 功能码 起始地址H 起始地址L 输出数量H 输出数量L 字节长度 输出值H 输出值L 响应:MBAP 功能码 起始地址H 起始地址L 输出数量H 输出数量L 0x02:读离散量输入 从一个从站中读1~2000个连续的离散量输入状态 请求:MBAP 功能码 起始地址H 起始地址L 数量H 数量L(共12字节) 响应:MBAP 功能码 数据长度 数据(长度:9+ceil(数量/8)) 0x04:读输入寄存器 从一个远程设备中读1~2000个连续输入寄存器

Cortex-M0存储器系统

目录 1.概述2.存储器映射3.程序存储器、Boot Loader和存储器重映射4.数据存储器5.支持小端和大端数据类型数据对齐访问非法地址多寄存器加载和存储指令的使用 6.存储器属性 1.概述 Cortex-M0处理器具有32位系统总线接口,以及32位地址线(4GB的地址空间)。系统总线基于AHB_Lite总线协议,外设总线一般采用APB协议。APB协议通过一个总线桥连接到AHB_Lite上,并且运行的时钟频率和AHB总线不同。APB的数据链路也是32位的,但由于外设的地址区域往往较小,因此地址线一般要少于32位。 由于主总线系统和外设总线是相互分离的,而且有些情况下时钟频率控制也是不同的,应用程序在访问外设前可能需要初始化微控制器的时钟控制硬件。有些情况下,一个微控制器可能有多个外设总线段,并且每个段运行在不同的时钟频率下。除了可以让系统的某些部分运行在较低频率下以外,独立的总线段还可以停止某些外设系统的时钟,这样也就可以降低功耗了。 2.存储器映射 Cortex-M0处理器的4GB存储器空间从架构上被分为多个区域,每个区域对应一种推荐的用途,而且各区域的操作方法也可能会有所不同。 尽管存储器映射已经被架构预先定义,存储器映射的实际用法却可以非常灵活,使用中的限制也不多。 每个区域的用途如下: 代码区域(0x00000000~0x1FFFFFFF) 代码区域的大小为512MB,主要用于存储代码,这其中也包括作为程序映像一部分的向量表,另外也可用作数据存储器(连接到RAM)。SRAM区域(0x20000000~0x3FFFFFFF) SRAM区域位于存储器映射的第二个512MB,其主要用于数据存储,这其中也包括栈,还可以用于程序代码存储。外设区域(0x40000000~0x5FFFFFFF) 外设区域的大小也为512MB,它主要用于外设以及数据存储。不过,外设区域中不允许执行程序。连接到该存储器区域的外设可以是AHB_Lite外设,也可以是APB外设(通过总线桥)。RAM区域(0x60000000~0x9FFFFFFF) RAM区域包括两个512MB的块,这样就得到了一个总共1GB的区域。这两个512MB存储器块主要用于数据存储,而且多数情况下RAM区域可使用1GB的连续存储器空间。RAM区域中还可以执行程序代码,这两个区域的唯一差异在于它们的存储器属性不同。如果设计中存在一个系统级的缓存(level-2缓存),这个差异就会带来缓存行为的差异。设备区域(0xA0000000~0xDFFFFFFF) 外部设备区域包括两个512MB的存储器块,这样就能总共得到1GB空间。两个512MB块主要用于外设和I/O,设备区域不允许程序执行,但可用作通用数据存储。同RAM区域类似,设备区域的两部分也有不同的存储器属性。内部私有外设总线(PPB)(0xE0000000~0xE00FFFFF) 内部PPB存储器空间用于处理器内部的外设,包括中断控制器、NVIC和调试部件等。内部PPB存储器空间的大小为1MB,且这个区域内不允许执行程序。 在PPB存储区域中,有一段特殊的存储器区域被定义为系统控制空间(SCS),其地址范围为0xE000E000~0xE000EFFF。该区域内包括中断控制寄存器、系统控制寄存器和调试控制寄存器等,NVIC寄存器也是SCS存储器空间的一部分。保留存储器空间(0xE0100000~0xFFFFFFFF) 存储器映射的最后511MB为保留存储器空间,这段空间在某些微控制器中预留为供应商特定的用途。 尽管Cortex-M0处理器的存储器映射是固定的,存储器的用法却可以非常灵活。例如,处理器可以在SRAM区域包含多个SRAM存储器块,CODE区域也是一样,而且外部RAM区域也可以执行程序。 在一个实际系统的存储器映射中,对于一个典型的Cortex-M0微控制器,通常可以在其中找到以下部分: Flash存储器(用于程序代码)内部SRAM(用于数据)内部外设外部存储器接口(用于外部存储器和外部外设,可选)其他外部外设的接口(可选) 将这些部件放到一起,就可以得到如下图所示的微控制器实例: 3.程序存储器、Boot Loader和存储器重映射 Cortex-M0的程序存储器一般使用片上Flash存储器,不过,程序也可以存储在外部或者使用其他类型的存储器设备(如EEPROM)。 当Cortex-M0处理器从复位中启动时,它会首先访问0地址的向量表,从而取得MSP的初始值和复位向量,然后它就可以从复位向量开始执行程序。要保证系统正常工作,系统中需要有合法的向量表和合法的程序存储器,这样处理器才不会执行恶意软件代码。 要实现这个目的,Flash存储器一般是从地址0开始的。不过,在用户编程以前,有些微控制器的Flash存储器中可能没有任何程序。为了保证处理器可以正确地启动,有些基于Cortex-M0的微控制器含有一个Boot loader,这是个位于微控制器芯片上的一小段程序,它会在处理器上电后执行并跳转,而且如果Flash存储器已编程的话,它会跳转到Flash中的用户程序执行。Boot loader由芯片供应商预先编程,有时它位于片上Flash存储器并且与用户程序是分离的(这样用户更新程序也不会影响到Boot loader),而其他情况下Boot loader则会位于和可编程程序存储器分离的非易失性存储器中(防止用户意外擦除Boot loader)。 当Boot loader存在时,微控制器通常会在系统总线上使用一种存储器映射切换特性,也就是重映射(remap)。存储器映射的切换由硬件寄存器控制,Boot loader执行时会重置这些寄存器。系统可以使用多种重映射方案,一种常见的处理是,Boot loader将会在上电阶段通过地址别名重映射到存储器的开头,如下图: ARM微控制器使用的另外一种重映射特性为,SRAM块可以重映射到地址0上。微控制器使用的非易失性存储器如Flash等要比SRAM慢,如果微控制器运行在较高的时钟频率下,Flash存储器中的程序在执行时就会需要插入等待状态。而将SRAM重映射到地址0后,程序就可以被复制到SRAM并以最快速度执行,这样会避免取向量表时出现等待,否则会增加中断等待的时间。 4.数据存储器 Cortex-M0处理器的数据存储器用于软件变量、栈存储,而且有些情况下还用于堆存储。应用程序使用需要动态内存分配的C函数时,堆存储就可以用上。 如果嵌入式应用中没有操作系统(OS),那么它只会使用一个栈(只需主栈)。在这种情况下,数据存储器的分配如下所示: 由于栈操作基于满减小的栈分配,而堆存储在分配时是增加的。为了使存储分配最具效率,通常将栈放在存储器块的尾部,而堆存储则紧跟在普通存储的后面。 而对于使用了嵌入式OS的嵌入式应用程序来说,每个任务可能都会有自己的栈存储区域。每个任务都可以有自己分配的存储器块,每个存储器块都可以包含有栈、堆和数据。 5.支持小端和大端 Cortex-M0处理器可以支持小端的存储器格式,也可以支持大端的。大小端在系统设计时由微控制器供应商选择,而软件不能修改。使用小端配置时,字数据的最低字节存储在字的位0到位7;而若采用大端配置,字数据的最低字节则会存储在位24到位31,如下所示。 这两种配置都支持不同大小的数据处理,Cortex-M0处理器可以产生字节、半字以及字传输。在访问存储器时,存储器接口会根据传输大小和地址的最低两位选择数据链路,如下所示: 应该注意大端配置有两种例外:取值总是小端的,且对私有外设总线(PPB)的访问总是小端的。 数据类型 Cortex-M0处理器支持各种不同的数据大小,提供了用于不同大小传输的各种存储器访问指令,而且还具有一个32位AHB_Lite接口,该接口支持32位、16位和8位传输。例如,C语言开发中常用到的数据类型如下所示: 如果使用了其他宽度更大的数据类型,C编译器会自动将这些数据传输转换为存储器访问指令。应该注意的是,对于外设寄存器访问,使用的数据类型应该同硬件寄存器大小相匹配。要不外设可能会忽略此次传输,或者运行结果同预想的不一致。 多数情况下,连接到APB的外设应该使用字传输来访问。这是因为APB协议没有定义传输宽度信号,所有的传输也就都被认为是字大小的。因此,通过APB访问的外设寄存器通常被声明为“volatile unsigned integer”。 数据对齐 Cortex-M0处理器支持的Thumb指令只能产生对齐访问。这就意味着传输地址只能是传输大小的整数倍。例如,字传输只能访问0x0、0x4、0x8和0xC之类的地址,与之类似,半字访问只能访问0x0、0x2、0x4等地址,所有的字节访问则都是对齐的。 如果程序试图进行一次非对齐访问,错误异常就会产生并且引发硬件错误处理的执行。 访问非法地址 在连接到Cortex-M0处理器的AHB系统中,地址解析逻辑会探测正在访问的地址,如果访问的是一个非法位置,总线系统就会回应一个错误信号,取值或数据访问都可以引起总线错误。 跳转影子指令的取值则是这种操作的一个例外,由于Cortex-M0处理器的流水线本性,指令会被提前取出。因此,如果程序执行到合法存储器区域的尾部,并且执行了一个跳转指令,这种情况下,处理器可能会预取一个合法指令存储器区域之外的地址,这就会导致AHB系统的总线错误。不过,如果由于跳转,错误指令没有得到执行,总线错误就会被忽略掉。 多寄存器加载和存储指令的使用 Cortex-M0处理器支持多寄存器加载和存储指令,如果使用正确的话,系统性能可以得到很大的提升。例如,它可以用于加快数据传输过程或者作为一种自动调整指针的方法。 6.存储器属性 Cortex-M0处理器可以使用多种存储器系统和设备,要使不同设备的软件移植更加容易,可以对存储器映射中的每个区域设置相应的存储器属性。存储器属性是存储器访问的特征,它们能够影响对存储器的数据和指令访问,对外设的访问也是一样。 在ARMv6-M架构中,不同的存储器区域可以定义多种存储器访问属性: 可执行(executable):这是个公用属性,它定义了程序是否允许在存储器区域中执行。根据ARM文档,如果一个存储器区域是不可执行的,它就会被标记为eXecuteNever(XN,永不执行)。可缓冲(bufferable):在一个可缓冲存储器区域上执行数据写操作,写传输可能会被缓存起来,这就意味着处理器不必等待当前的写传输完成,就可以继续执行下一条指令。可缓存(cacheable):如果系统中含有缓存设备,它可以在本地备份当前传输的数据,并可以下次在访问相同的存储器位置时重新使用,这样可以加速系统执行。缓存设备可以是一个缓存存储器单元,也可以是存储器控制器中的一个小的缓存。可共享(shareable):可共享属性定义了多个处理器是否可以访问公用存储器区域,如果一块存储器区域是可共享的,存储器系统需要确保多个处理器访问这一区域时的一致性。 基于这些存储器属性,处理器架构上定义了多种类型的存储器,以及每个存储器区域可以使用哪种类型的设备: 普通存储器:可以是共享也可以是不共享的,可以是缓存的也可以是不缓存的。对于可缓存的存储器,缓存行为可以分为写通(WT)以及写回写分配(WBWT)。设备存储器:设备存储器为不可缓存的,可以是共享的,也可以是不共享的。强序存储器:这种存储器是不可缓存以及不可缓冲的,对强序区域的读写操作会立即起作用。另外,在这种存储器接口的传输顺序必须和相应的存储器访问指令的顺序一致。强序存储器区域总是可共享的。 Cortex-M0处理器中每个存储器区域的属性由这些存储器类型定义来决定,在存储器访问中,属性通过AHB系统从处理器中输出。

数据结构与算法-二叉树的操作及应用C语言实现(超详细注释/设计/实验/作业)

目录 一、引言二、目的三、环境与设备四、存储结构五、函数六、核心代码七、调试界面八、总结 一、引言 感谢宝子们一键三连支持,火速更新中~~ 二叉树(Binary tree)(简写:BT):是指树中节点的度不大于2的有序树,它是一种最简单且最重要的树。 二叉树的递归定义:二叉树是一棵空树,或者是一棵由一个根节点和两棵互不相交的,分别称作根的左子树和右子树组成的非空树;左子树和右子树又同样都是二叉树。 二、目的 掌握二叉树的存储结构掌握二叉树的基本操作掌握二叉树的基本特性 三、环境与设备 操作系统:Windows 10 编译器:Visual Studio 2021 四、存储结构 1. typedef char DataType; 2. typedef struct node { DataType data; struct node *lchild,*rchild; //struct node *parent;//三叉链表 }BiTNode,*BTree; 五、函数 3. BTree Create()//非递归存储创建二叉树 4. void CreateBiTree(BTree T)//递归创建二叉树 5. void OutputFirstBiTree(BTree T)//递归先序遍历二叉树 6. void preOrder(BTree p)//非递归先序遍历二叉树 7. void OutputMidBiTree(BTree T)//递归中序遍历二叉树 8. void inOrder(BTree p)//非递归中序遍历二叉树 9. void OutputLastBiTree(BTree T)//递归后续遍历二叉树 10. void postOrder(BTree h)//非递归后续遍历二叉树 11. void Level(BTree p)//按层次遍历二叉树 12.

Java list排序

List list = new ArrayList<>(); list.add(“3”); list.add(“5”); list.add(“1”); list.add(“2”); list.add(“4”); //正序(升序、从小到大排序),加上.reversed()为倒序 List newList = list.stream().sorted(Comparator.comparing(String::valueOf)).collect(Collectors.toList()); for (String s : newList) { System.out.println(s); } 正序结果: 倒序结果: 说明:list<对象>,要根据对象某属性值排序时,Comparator.comparing(对象::get属性);

Cannot read properties of undefined (reading 'data')

"不能读取未定义的属性(读取'data')" 这个错误信息通常是指代码尝试读取一个未定义的变量或对象的属性。在这种情况下,代码试图读取名为'data'的变量或对象的属性,但是没有定义这个变量或对象,导致了这个错误。 解决方法是检查变量'data'是否被正确定义并初始化,然后再使用它。

Centos7.x Python3.7和pip3 快速安装脚本

这是一个安装 Python3.7 和 pip3 的 shell 脚本,命名为 install_python3.sh。 #!/bin/bash # 升级软件包和安装 Python3.7 依赖的软件包 yum -y groupinstall "Development tools" yum -y install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gdbm-devel db4-devel libpcap-devel xz-devel yum install -y libffi-devel zlib1g-dev yum install zlib* -y yum install wget curl tar -y # 下载 Python3.7 并解压 mkdir -p /home/download cd /home/download wget https://www.python.org/ftp/python/3.7.9/Python-3.7.9.tar.xz tar -xf Python-3.7.9.tar.xz cd Python-3.7.9 # 编译和安装 Python3.7 ./configure --enable-optimizations make altinstall # 安装 pip3 wget https://bootstrap.

图形系统之Wayland基础

良好的人机交互是一个系统成功的基础,其中图形系统也人机交互的重中之重。openharmony的显示系统是在近些年比较热门的Wayland的基础开发的。Wayland一直被认为是XWindow的继承者,被寄予众望,不过这些年也没有想象的发展迅猛,不温不火的过了这么多年,好比做了多年了太子,但是老皇帝一直健在。希望openharmony可以帮它烧起来。 一直想自己动手写一些文章,不过太懒了,拿着别人总结的整理了一下 1、Wayland和X Window 其实,Wayland是一套C/S框架的通信协议,他被内定为X图形系统的接班人。在涉及框架上要有明显的优势,在X系统中X Server作为中心服务,服务Client Composer,和内核打交道,如下图所示为X系统一个输入事件从输入到展示出来的流程, 1、内核从输入设备获取事件,并通过 evdev 输入驱动程序将其发送到 X 服务器。内核通过驱动设备并将不同的设备特定事件协议转换为 linux evdev 输入事件标准来完成所有繁重的工作。 2、X 服务器确定事件影响哪个窗口,并将其发送到为该窗口上的相关事件选择的客户端。 X 服务器实际上并不知道如何正确执行此操作,因为屏幕上的窗口位置由合成器控制,并且可能以 X 服务器无法理解的多种方式进行转换(缩小、旋转、摆动、等等)。 3、 客户端查看事件并决定要做什么。通常,UI 必须响应事件而更改 - 可能是单击了复选框或指针进入了必须突出显示的按钮。因此,客户端将渲染请求发送回 X 服务器。 4、当 X 服务器收到渲染请求时,它会将它发送给驱动程序,让它编程硬件来进行渲染。 X 服务器还计算渲染的边界区域,并将其作为损坏事件发送到合成器。 5、损坏事件告诉合成器窗口中的某些内容发生了变化,并且它必须重新合成该窗口可见的屏幕部分。合成器负责根据其场景图和 X 窗口的内容渲染整个屏幕内容。然而,它必须通过 X 服务器来呈现它。 6、X 服务器接收来自合成器的渲染请求,并将合成器后台缓冲区复制到前台缓冲区或执行翻页。在一般情况下,X 服务器必须执行此步骤,以便它可以考虑重叠窗口,这可能需要裁剪并确定它是否可以翻页。但是,对于始终全屏显示的合成器,这是另一个不必要的上下文切换。 如上所述,这种方法存在一些问题。 X 服务器没有信息来决定哪个窗口应该接收事件,也不能将屏幕坐标转换为窗口本地坐标。 即使 X 已将屏幕最终绘制的责任交给合成经理,但 X 仍控制前端缓冲区和模式设置。 X 服务器过去处理的大部分复杂性现在都可以在内核或自包含库(KMS、evdev、mesa、fontconfig、freetype、cairo、Qt 等)中使用。 总的来说,X 服务器现在只是一个中间人,它在应用程序和合成器之间引入了一个额外的步骤,在合成器和硬件之间引入了一个额外的步骤。 在WayLand中 他去掉了X Server,在合成器拥有KMS和evdev的控制权,这种设计从逻辑上比不上X系统,不过确实效率提高了不少 内核获取一个事件,并将其发送到合成器。这与X情况类似,这非常好,因为我们可以重用内核中的所有输入驱动程序。合成器通过其场景图进行查看,以确定应该接收该事件的窗口。场景图与屏幕上的内容相对应,并且合成器了解它可能已应用于场景图中的元素的转换。因此,合成器可以选择右窗口,并通过应用逆变换将屏幕坐标转换为窗口局部坐标。可以应用于窗口的转换类型仅限于合成器可以执行的操作,只要它可以计算输入事件的逆转换即可。与X情况一样,当客户端收到事件时,它会更新UI作为响应。但是在路途中,渲染发生在客户端中,并且客户端只是向合成器发送请求以指示已更新的区域。合成器从其客户端收集损坏请求,然后重新合成屏幕。然后,合成器可以直接发出ioctl来调度带有KMS的翻页。 从上面可以看出Wayland确实效率更高。 2、架构 Wayland的系统体系架构如上文所示,官方给出了一个源码实现Weston。Weston从内部体系结构来看,主要分为窗口管理(shell),合成器(compositor)和输入管理几个部分。可见,如果拿Android作类比,从功能上看它约等同于InputManagerService,WindowManagerService和SurfaceFlinger。从大体的流程上来看,输入管理模块接受用户输入,然后一方面shell作出相应的窗口管理操作(如窗口堆栈的改变,focus的变化等),另一方面将该input event传给之前注册了相应输入事件的client。client收到后会在handler中做相应动作,如调整视图然后重绘。如有重绘发生,新buffer渲染完成后client将其handle传给server,接着server端生成z-order序的窗口列表,之后compositor用renderer进行合成,最后输出(比如到framebuffer)。 Weston是主要服务进程,它的事件处理模型采用的是典型的Reactor模式。根据Linux中万物皆文件的原则,主循环通过epoll机制等待在一系列的文件fd上。这种模型与基于线程的binder不同,是一种串行的事件处理模型。在此模型上的过程调用在不加额外同步机制的情况下是异步的。好处是不会有竞争问题,数据同步开销较小。缺点是当有一个事件处理比较耗时或者在等待IO,则有可能使整个系统性能下降或响应不及时。 主循环上等待的几个核心fd包括: • Server/Client通信:listener fd在Weston启动时建立,并一直监听新的client连接。一个client连接后会与Weston建立一对domain socket,Wayland就是基于它来通信的。 • 输入处理:一方面通过udev monitor监听设备的添加删除事件。另一方面如有新设备添加时会将该设备打开并监听该fd来得到输入事件。

个人笔记Openstack中的常用命令

一、块存储(Cinder) 1.列出所有卷(ID、名称、状态、大小和挂载目录) openstack volume list 2.新建卷(size的单位为GB) openstack volume create --size <size> <name> 3.删除卷 openstack volume delete <id> 4.将卷连接到instance openstack server add volume <instance_id> <volume_id> 二、认证(Keystone) 1.列出所有用户 openstack user list 2.列出认证服务目录 openstack catalog list 三、镜像(Glance) 1.列出可以访问的镜像 openstack image list 2.删除指定镜像 openstack image delete <image_id> 3.查看指定镜像的详细信息 openstack image show <image_id> 4.更新镜像 openstack image set <image_id> 四、计算(nova) 1列出实例 openstack server list 2.创建规格 openstack flavor create --ram <ram_size_MB> --disk <disk_size_GB> --vcpus <vcpu_num> <flavor_name> 3.

如何使视频video自动播放

格式:<video src="***.mp4" ></video> 在PC端要自动播放插入两个代码即可: 把自动播放的属性加上 此时PC端并没有自动播放 只看到一张画面 然后加上 video的muted属性设置为true就可以正常播放了 <video src="./video/MIUI14_Pure2.mp4" autoplay muted="trun"></video>

selenium中driver退出,以及基础对象方法整理

退出 with webdriver.Chrome() as driver: #上下文管理器打开浏览器,不用关闭自动退出 driver.close() :关闭用户当前正在使用的Web浏览器窗口,即WebDriver当前正在访问的窗口。.close() 方法既不需要任何参数,也无任何返回值。 driver.quit() :不同于close(),quit()方法用于关闭程序已打开的所有窗口。该方法也不需要任何参数,也无任何返回值。 基础对象 webdriver对象、 浏览器对象、 webelement对象 webdriver的方法和操作 driver的方法和操作 element的方法和操作 <class 'selenium.webdriver.remote.webelement.WebElement'> ActionChains add_cookie clear Android application_cache click BlackBerry back find_element Chrome #浏览器(橙色为浏览器兼容性常用方法) capabilities find_element_by_class_name ChromeOptions #option选项 close find_element_by_css_selector Edge command_executor find_element_by_id Firefox # firefox浏览器 create_options find_element_by_link_text FirefoxOptions # firefox option选项 create_web_element find_element_by_name FirefoxProfile current_url find_element_by_partial_link_text Ie current_window_handle find_element_by_tag_name IeOptions delete_all_cookies find_element_by_xpath Opera delete_cookie find_elements PhantomJS #无头浏览器 desired_capabilities find_elements_by_class_name Proxy error_handler find_elements_by_css_selector Remote execute find_elements_by_id Safari execute_async_script find_elements_by_link_text TouchActions execute_cdp_cmd find_elements_by_name WebKitGTK execute_script find_elements_by_partial_link_text WebKitGTKOptions file_detector find_elements_by_tag_name __builtins__ file_detector_context find_elements_by_xpath __cached__ find_element #定位元素 1个祖宗方法 get_attribute __doc__ find_element_by_class_name get_property __file__ find_element_by_css_selector id __loader__ find_element_by_id is_displayed __name__ find_element_by_link_text is_enabled __package__ find_element_by_name is_selected __path__ find_element_by_partial_link_text location __spec__ find_element_by_tag_name location_once_scrolled_into_view __version__ find_element_by_xpath parent android find_elements #定位一组元素 rect blackberry find_elements_by_class_name screenshot chrome find_elements_by_css_selector screenshot_as_base64 common find_elements_by_id screenshot_as_png edge find_elements_by_link_text send_keys firefox find_elements_by_name size ie find_elements_by_partial_link_text submit opera find_elements_by_tag_name tag_name phantomjs find_elements_by_xpath text remote forward value_of_css_property safari fullscreen_window support get webkitgtk get_cookie get_cookies get_log get_network_conditions get_screenshot_as_base64 get_screenshot_as_file get_screenshot_as_png get_window_position get_window_rect get_window_size implicitly_wait launch_app log_types maximize_window minimize_window mobile name orientation page_source quit refresh save_screenshot service session_id set_network_conditions set_page_load_timeout set_window_position set_window_rect set_window_size start_client start_session stop_client switch_to switch_to_active_element switch_to_alert switch_to_default_content switch_to_frame switch_to_window title w3c window_handles

串口输出乱码问题的解决方法汇总(持续更新):

平时工作中程序员在调试时总会用到串口打印数据以及一些标志位查看程序是否出现问题。但是在使用时总会遇到各种各样的问题,最常见的就是输出乱码问题(指的是有收到数据但数据显示的是一堆不认识的汉字或字符),下面就我遇到过的串口乱码问题的相关几种解决方法: 方法一:检查GND线连接情况 电子系统接地非常重要,接地不当往往导致电子系统不能稳定工作。 在串口通信时地线是必须接的,比如串行数据通信接口标准(RS—232)的3线TX、RX、GND。虽然在使用RS-485总线工业标准时接两线TX、RX也能实现通信,但接Gnd 有利抑制干扰。RS-485的前身RS—422也一样。 一般建议在使用串口通信时需要把GND连接上,尤其是在长距离传输时。 方法二:查看串口助手和源程序就传输协议设置是否一致 串口通信最重要的参数是波特率、数据位、停止位和奇偶校验。在使用串口时这些参数必须要保持一致。下面大致介绍一些这些参数的意义: 一、波特率 波特率(bandrate)是衡量符号传输速率的参数,指的是串口通信的速率,也就是串口通信时每秒钟可以传输多少个二进制位。比如串口常用波特率9600指的是串口每秒钟可以传输9600个二进制(传输一个二进制位需要的时间是1/9600秒,也就是104us)。 注意波特率和比特率的区别: 情形一:一个信号码元有且仅有两种状态:0或1 此时每种状态含一位二进制数(0或1),在这种情况下比特率值=波特率值 情形二:一个码元有4种不同的状态:01、11、00或10 此时每种状态含两位二进制数(00、01、10、11),在这种情况下比特率值=波特率值×2 以此类推可以得到:比特率=波特率 * 单个调制状态对应的二进制位数 二、数据位 数据位是衡量通信中实际数据的参数。当计算机发送一个信息包,实际的数据不一定是8位的(标准的值是6、7和8位),如何设置取决于你想传送的信息。 比如,标准的ASCII码是0~127(7位),扩展的ASCII码是0~255(8位)。如果数据使用标准 ASCII码,那么每个数据包使用7位数据;如果数据使用扩展 ASCII码,那么每个数据包使用8位数据(每个包是指一个字节,包括开始/停止位,数据位和奇偶校验位)。 三、停止位 停止位是用于表示单个包的最后一位。典型的值为1,1.5和2位。 由于数据是在传输线上定时的,并且每一个设备有其自己的时钟,很可能在通信中两台设备间出现了小小的不同步。因此停止位不仅仅是表示传输的结束,并且提供计算机校正时钟同步的机会。适用于停止位的位数越多,不同时钟同步的容忍程度越大,但是数据传输率同时也相应越慢。 四、奇偶校验位 奇偶校验位是串口通信中在数据位后面加一位用于简单地检查数据发送是否有错。有四种检错方式:偶、奇、高和低。当然没有校验位也是可以的。 对于偶和奇校验的情况,串口会设置校验位(数据位后面的一位),用一个值确保传输的数据有偶个或者奇个逻辑高位。 例如,如果传输的数据是011,那么对于偶校验(校验位为0),则此时数据位 + 校验位的数据为:0110,保证逻辑高的位数是偶数个。如果是奇校验(校验位为1),则此时数据位 + 校验位的数据为:0110,这样就有3个逻辑高位。高位和低位不真正的检查数据,简单置位逻辑高或者逻辑低校验。这样使得接收设备能够知道一个位的状态,有机会判断是否有噪声干扰了通信或者是否传输和接收数据是否不同步。 在实际使用中要确保这四个参数在源程序和助手设置是一致的。 方法三:在源程序中查看主频设置是否有误 上面两个是一般会出现乱码的原因,除此之外在源程序里面也会出现一些大意操作导致串口乱码(最难且不容易想到的出错点)。我目前尚未遇到过这种情况导致串口乱码的但在不少大佬的博客和文章中看见有遇到过,这里也引用下来大家可以看看是否能解决你的串口乱码问题。 STM32F407系统时钟配置不准确导致串口发送数据乱码、定时器定时不准问题。 https://blog.csdn.net/lqj11/article/details/108058008 stm32f407等芯片(HAL库)时钟频率修改(乱码) https://blog.csdn.net/bulefire2009/article/details/119633701?spm=1001.2101.3001.6650.1&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1-119633701-blog-108058008.pc_relevant_recovery_v2&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1-119633701-blog-108058008.pc_relevant_recovery_v2&utm_relevant_index=2 方法四:Printf重定向函数 关于重定向导致数据输出乱码我遇到过几次,关于重定向引用一篇大佬的文章printf重定向原文链接:https://blog.csdn.net/RONG_YAO/article/details/115746940。这能解决大家关于重定向的一些疑惑。但我遇到过另外一种重定向导致输出乱码的情况。 在调试一个项目时一直出现乱码问题,虽然能接到数据但一直显示“IIIIIIIt”,看着不像乱码但与实际要显示的内容天差地别(不管输出的是汉字还是ASCII都一样),前面几个解决方法都检查过没有问题,但乱码现象依然没有改变。后面仔细研究源代码发现问题出在printf重定向上,不是没有添加重定向函数,而是添加了两个重定向函数(分别添加在了sys.c和usart.c中) 在sys.c函数中定义了一次: #pragma import(__use_no_semihosting) struct __FILE { int handle; }; #if( defined DEBUG) int fputc( int c, FILE *f ) { #if DEBUG == Debug_UART0 while( R8_UART0_TFC == UART_FIFO_SIZE ); /* 等待数据发送 */ R8_UART0_THR = c; /* 发送数据 */ #elif DEBUG == Debug_UART1 while( R8_UART1_TFC == UART_FIFO_SIZE ); /* 等待数据发送 */ R8_UART1_THR = c; /* 发送数据 */ #elif DEBUG == Debug_UART2 while( R8_UART2_TFC == UART_FIFO_SIZE ); /* 等待数据发送 */ R8_UART2_THR = c; /* 发送数据 */ #elif DEBUG == Debug_UART3 while( R8_UART3_TFC == UART_FIFO_SIZE ); /* 等待数据发送 */ R8_UART3_THR = c; /* 发送数据 */ #endif return( c ); } #endif 在usart.

Centos7.x Redis快速安装脚本

下面是一个 Centos7.x 系统下安装 Redis 并设置开机自启以及远程访问的 shell 脚本: #!/bin/bash # Update the system # yum update -y # --下载fedora的epel仓库 yum install epel-release -y # Install redis yum install redis -y # Enable Redis to start on boot systemctl enable redis # Start Redis systemctl start redis # Allow remote connections to Redis sed -i 's/bind 127.0.0.1/bind 0.0.0.0/' /etc/redis.conf # Restart Redis to apply changes systemctl restart redis # Check the status of Redis systemctl status redis 使用方法: