当我们页面需要重置数据时 会发现quill-editor的验证自动触发提示信息
很显然这个自动获取特别讨厌 以下是我在网络上收集来的解决方法
第一步 初始化时令vue-quill-editor失效 mounted() { this.$refs.text.quill.enable(false) }, 第二步 点击富文本框时令quill-editor生效,并聚焦
<quill-editor ref="text" v-model="form.question" class="myQuillEditor" :options="editorOption" @change="changeQuillEditor" @blur="changeQuillEditor" @click.native="handleEditAblequestion" /> </el-form-item> 第三步 在定义方法与判断数据
qillInit: true,//data里面属性 //methods里面 // 点击富文本重新获取焦点 handleEditAblequestion () { if (this.qillInit) { this.$refs.text.quill.enable(true) console.log(111) this.$refs.text.quill.focus() this.qillInit = false } },
1.前言 最近对物联网产品自组网技术选型,找到合适的组网技术,让产品自行组网并完成数据的传输。
2.参数对比 3.优缺点描述 3.1.蓝牙 优点:
(1)低功率,便于电池供电设备工作
(2)便宜,可以应用到低成本设备上,降低产品的成本
(3)同时支持文本、图片、音视频的传输
(4)传输速率快,低延时 缺点:
(1)传输距离有限
(2)穿透性能差
(3)不同设备间协议不兼容
(4)联网耗时比较久
3.2.LoRa 优点:
(1)传输距离远:灵敏度-148dBm,通讯距离可达几千米
(2)工作能耗低:Aloha方法有数据时才连接,电池可工作几年
(3)组网节点多:组网方式灵活,可以连接多个节点
(4)抗干扰性强:协议里面有LBT的功能,基于aloha的方式,有自动的频点跳转和速率自适应功能
(5)低成本:非授权频谱,节点/终端成本低
缺点:
(1)频谱干扰:随着LoRa的不断发展,LoRa设备和网络部署不断增多,相互之间会出现一定的频谱干扰。
(2)需要新建网络:LoRa在布设过程中,需要用户自己组建网络。
(3)有效负载较小:LoRa传输数据有效负载比较小,有字节限制。
3.3.WiFi 优点
(1)灵活性和移动性:无线局域网在无线信号覆盖区域内的任何一个位置都可以接入网络。连接到无线局域网的用户可以移动且能同时与网络保持连接。
(2)安装便捷:一般只要安装一个或多个接入点设备,就可建立覆盖整个区域的局域网络。
(3)故障定位容易:无线网络很容易定位故障,只需更换故障设备即可恢复网络连接。
缺点
(1)性能:无线局域网依靠无线电波进行传输。这些电波通过无线发射装置进行发射,而建筑物、车辆、树木和其他障碍物都可能阻碍电磁波的传输,影响网络的性能。
(2)速率:无线信道的传输速率低,最大传输速率为54Mb/s,只适合于个人终端和小规模网络应用。
3.4.NB-IOT 优点:
(1)海量接入:相同基站覆盖条件下,NB-IoT 技能是其它无线技能接入数的 50 至 100 倍,现有NB-IoT网络单小区基站可接入5万个终端设备,这样的超大连接能使物联网真正做到“万物互联”。
(2)功耗较低:NB-IoT有三种不同的省电模式:PSM模式、DRX模式、eDRX模式,设备可以根据自己的需求选择省点模式,达到功耗最小的目的,可以延长电池的使用寿命,在针对许多使用电池供电的设备和局面,NB-IoT 的低功耗特性能够保证设备续航时间,从几个月大幅提升到几年,因此大大降低了频繁更换电池带来的不便。
(3)覆盖超强:NB-IoT 的覆盖能力是 LTE 的 100 倍。NB-IoT网络具有超大覆盖范围与超强穿透能力,这样不但能够满足地广人稀地区的大范围覆盖需求,同样适用于对深度覆盖有要求的地下应用。
(4)成本低廉:NB-IoT支持在现有的LTE网络上改造,大大的降低了网络建设成本,NB-IoT 无需重新建网,射频和天线也基本上都能够复用。再 NB-IoT 低功耗、低带宽和低速率的特性,同样降低了芯片和模组成本。
缺点:
(1)数据传输少:基于低功耗,导致 NB-IoT 只能传输少了数据;
(2)通信成本高:除了 NB-IoT 通信模块的价格之外,运营商还将收取运营费用;
(3)技术并不成熟:虽然 NB-IoT 技术被大范围应用,但在实际应用过程中,经常出现各类故障,导致通信中断;
3.5.ZigBee 优点:
(1)低功耗:工作模式下,ZigBee技术的传输速率低,传输数据量很小,因此信号的收发时间很短。其次,在非工作模式情况下,ZigBee的节点处于休眠状态。设备搜索延迟一般为30ms,休眠激活时延为15ms,活动设备接入信道时延为15 ms。由于工作时间较短,收发信息功耗较低且采用了休眠模式,使得ZigBee节点非常省电。
(2)低时延:ZigBee响应速度较快,一般从睡眠转入工作状态只需要15ms。节点连接进入网络只需30ms,进一步节省了电能。相比较蓝牙需要3-10秒,WIFI需要3秒。
#!/bin/bash int=1 until [ $int -ge 11 ] do sq=`expr $int \* $int` echo $sq int=`expr $int + 1` done
内容摘抄自runoob.com
1.Lua特性 1 轻量化
2 可扩展: 提供了非常易于使用的扩展接口和机制,宿主语言C/C++提供功能,Lua可以直接使用。
3 其它:
支持面向过程和函数式编程自动内存管理:只提供一种通用类型的表(table),用它可以实现数组,哈希表,集合,对象语言内置模式匹配,闭包,函数也可以看作一个值,提供多线程(协同进程,并非操作系统所支持的线程)支持通过闭包和table可以很方便地支持面向对象编程所需要的一些关键机制,比如数据抽象,虚函数,继承与重载。 2.基本语法 1 所有变量定义是默认为全局,如果访问一个没有定义的变量不会发生错误,得到的结果为nil
2 删除一个全局变量,只需要将变量赋值为nil
3 交互式编程,在命令行中输入程序就可以立即看到效果
4 脚本式编程,可以将lua程序保存到以lua结尾的文件中,使用$ lua xxx.lua可以得到结果。
5 单行注释--,多行注释--[[ xxxxx --]]
3.数据类型 Lua为动态类型语言,变量不需要类型定义,只需要为变量赋值。值可以存储在变量中,作为参数传递或结果返回。共8个基本类型变量。
3.1 nil (空类型) nil类型与C/C++中的nullptr相类似。表示没有任何的有效值,例如打印一个没有赋值或者声明的变量那么就会输出一个nil值。
注意: 对于全局变量和table,nil还有删除作用,将全局变量或table中的某一个变量赋为nil,那么就相当于把这个值删除。
nil做比较时需要加上双引号,因为使用type(xxx) == "nil"作比较时,type(xxx)的返回值为字符串类型。
3.2 string (字符串类型) 表示字符串的几种方式
单引号 'xxxxxx'双引号 "xxxxxx"一块字符串 [[xxx 可以是多行]] 注意: 在对一个数字字符串进行算数操作时,Lua会自动将该数字字符串转换成为一个数字,并进行计算。
字符串连接使用 .. 进行连接,字符串计算使用#计算
示例:
>print(2 + "2") >10:48:23.13-346: 4 >print("2" + "2") >10:48:33.107-949: 4 >print("2 + 2") >10:48:46.700-762: 2 + 2 >print("-2e2" * 3) >10:49:00.
一、介绍
SecureCRT支持vbs,vbe,js,pl,py。 SecureCRT支持VB、JavaScript、Python等多种脚本语言。
可以通过编写脚本实现自动调试,自动测试,这里主要介绍上面运行python
教程
https://www.cnblogs.com/OnOwnRoad/
二、编写脚本
# $language = "python" # $interface = "1.0" #官方的实例可以在未连接任何服务器的情况下进行ssh连接 #你要连接的ssh服务器ip host = '139.196.53.1**' #ssh用户名 user = 'root' #ssh密码 passwd = 'Jinx0007' def main(): #进行cmd操作连接创建新的session连接 cmd = "/SSH2 /L %s /PASSWORD %s /C 3DES /M MD5 %s" % (user, passwd, host) crt.Session.Connect(cmd) #使用默认弹窗提示信息 crt.Dialog.MessageBox('登录成功!') main() 三、运行脚本
题目描述: 若在长度大于1的循环链表中,既无头结点也无头指针。s为指向链表中某个结点的指针,试编写算法删除结点*s的直接前驱。 头结点:
头结点指的是链表中物理上的第一个结点
头结点是为了操作的统一和方便而设立的,放在第一个元素的结点之前,其数据域一般无意义;
头结点存在的意义是:
在链表操作理论上第一个节点时(有头结点的链表里的第二个节点 不用直接改变头指针的地址 这样保持了操作的一致性)若链表为空(头节点的指针域为空) 存在头结点的链表的处理 非空链表,空链表 的方法一致 头指针:
头指针指的是指向物理上第一个结点的指针(存放该结点地址的变量)
头指针是指链表指向第一个结点的指针,若链表有头结点,则是指向头结点的指针
结构体定义 #define ElemType int #define Status int typedef struct LNode{ ElemType data; struct LNode *next; }LNode,*LinkList; 算法实现: Status ListDelete_CL(LinkList &S){ LinkList p,q; if(S==S->next) return 0; q=S; p=S->next; while(p->next!=S){ q=p; p=p->next; } q->next=p->next; free(p); return OK; }
文章目录 介绍代码如下(部分注释)执行结果如下输入错误情况如下-- 文明 使人进步 -- 介绍 输入一个日期,输出当前日期是这一年的第几天
注意考虑平年闰年问题
2021.3.24
输出:2021年3月24日是2021年的第83天
代码如下(部分注释) #include <stdio.h> int main(int argc, const char *argv[]) { int year = 0; int month = 0; int month2 = 0; int day = 0; //int temp = 0; printf("请输入年月日(用回车分割):\n"); scanf("%d%d%d",&year,&month,&day); printf("您输入的日期是:%d年 %d月 %d日\n ",year,month,day); //判断年月日的合法性 if(year <0 ||month >12 ||month < 1) { printf("xia TM xie\n"); return 0; } //判断是不是31天的合法性 if(month == 1 ||month == 3||month == 5||month == 7||month ==8||month==10||month==12) { if(day > 31) { printf("
对象的特征--属性(静态特征)对象具有的各种特征
每个对象的每个属性都拥有特定值(属性-属性值)
对象的特征--方法(动态特征)对象执行的操作
类和对象的关系
对象:(用来描述客观事物的一个实体)由一组属性值和方法构成,是一个具体的实例
类:具有相同属性和方法的一组对象的集合。
类是对象的抽象,对象是类的具体实现
类的创建及步骤:
public class 类名{ //1.定义类名,通过class定义自定义的数据类型(类名首字母大写)
属性类型 属性名; //2.编写类的属性
方法(){ //3.编写类的方法
//方法体
}
}
对象的创建与使用:
类型 对象名=new 类型(); //关键字为new,用于创建对象(类中的属性和方法使用对象名去调用)
对象名.属性=值; //属性的赋值
对象名.方法(); //调用属性的方法
方法的定义:(实现功能、存储过程、函数)
访问修饰符类型 返回值类型 方法名(){ //方法名要遵循驼峰命名规则且有意义
//方法体
//返回值类型若不是void(该方法没有返回值),必须有return语句
//return的目的要把返回值类型对应的值返回到方法外部,返回值只能有一个
}
有返回值的方法在调用时必须被对应返回值类型接收,否则相当于没有返回值
String name(进行接受)=s.getName() //返回值;
System.out.println(name); //输出
方法的调用:
1、在同一个类调用同一类中的方法,只需要通过方法名()就可以直接调用
(main方法除外 无论在类中还是类外都要先声明对象)
2、在不同类中调用方法,需要先new一个需要调用方法的类的对象,然后通过对象名.方法名的方式去调用方法
调用方法的时候,实际上就是去执行方法体中的代码
学习计算机网络编程 一、思路和学习方法 本文学习于:C语言技术网(www.freecplus.net),在 b 站学习于 C 语言技术网,并加以自己的一些理解和复现,如有侵权会删除。
接下来对网络编程继续深入学习。通过上篇文章学习,感觉对每个点都记录会很花费时间,但是不记录又对有些地方理解一知半解,综合考虑,先运行出来,对每行代码如何执行要明白,实现什么功能也要明白,freecplus 框架里面知识,后面再仔细学习。
二、网络编程继续深入 2.1 搭建多线程网络服务框架 使用多线程方式搭建网络服务框架,在实际应用中会广泛一些,但是难度也会高一些。下面开始进行学习,在这之前有一些前置知识,要对多线程网络通信等知识进行学习。其中服务端程序如下,
/* * 程序功能: * 作者:C语言技术网(www.freecplus.net) 日期:20190525 */ #include "_freecplus.h" void *pthmain(void * arg); // 线程主函数 vector<long> vpthid; // 存放线程 id 的容器 void mainexit(int sig); // 信号 2 和 15 的处理函数 void pthmainexit(void * arg); // 线程清理函数 CLogFile logfile; CTcpServer TcpServer; // 创建服务端对象 // 处理业务的主函数 bool _main(const char *strrecvbuffer, char *strsendbuffer); // 心跳报文 bool biz000(const char *strrecvbuffer, char *strsendbuffer); // 身份验证业务处理函数 bool biz001(const char *strrecvbuffer, char *strsendbuffer); // 查询余业务处理函数 bool biz002(const char *strrecvbuffer, char *strsendbuffer); int main(int argc, char *argv[]){ if(argc !
题目描述: 已知单链表L是一个递增有序表,试编写一高效算法删除表中值大于min且小于max的结点(若表中有这样的结点),同时释放被删除结点的空间,这里min和max是两个参数。请分析算法的时间复杂度。 定义结构体 struct LNode{ int data;//数据域 struct LNode *next; }; typedef struct LNode LNode,* LinkList; 初始化链表 LinkList InitLNode(void){ LinkList head; head = (LinkList)malloc(LEN);//生成有一个结构体大小的动态存储空间 if(!head){ printf("内存空间申请失败!\n"); exit(ERROR); } head->data = 0;//头结点的数据域用来存放实际表长 head->next = NULL; return head; } 创建一个链表 int CreatList(LinkList head){ LinkList pleft,pright; pleft = head; pright = (LinkList)malloc(LEN);//指向新开辟的一段内存空间 要保证pleft和pright一前一后 printf("请按照递增的顺序向链表中赋值:(输入-1认为输入终止)\n"); scanf("%d",&pright->data); while(pright->data!=-1){ head->data++;//表长加1 pleft->next = pright;//pleft永远指向当前链表的最后一个结点 pright指向当前新生成的一个结点 pleft = pright; pright = (LinkList)malloc(LEN); scanf("%d",&pright->data); } pleft->next = NULL; free(pright);//pright的数据域是-1指针域没有赋值 也就是说pright所指结点并未链入到链表中 没有用了 return OK; } 删除结点 int delLNode(LinkList head,int num){ if(!
1、网络:是由网络连接设备(路由器、交换机等)通过传输介质(网线、光纤等)将网络终端设备(计算机、服务器等)连接起来进行数据交换、资源共享的平台
注释:服务器:指一台安装了服务操作系统的电脑
2、OSI七层参考模型(开放式系统互联模型)
OSI被分为七层:
1、应用层:通过人机交互来实现各种各样的服务
2、表示层 :编码 解码 加密 解密
3、会话层:发现 建立 维持 终止会话进程
4、传输层:通过端口号来区分不同的服务
端口号(0-65535)又分为:1、静态端口号 2、动态端口号
1、静态端口号(1-1023):
一个端口号代表一个服务,且成永久绑定关系
2、动态端口号(1024-65535):
一个端口号代表一个服务,且呈暂时性绑定关系
0-—特殊端口号—保留端口号(在网络编程中使用代表所有端口号)
提供可靠的传输
可靠机制:确认 重传 排序 流控
TCP--传输控制协议
面向连接的可靠传输协议
UDP--用户数据报文协议
非面向连接的不可靠传输协议
面向连接---三次握手 四次挥手
三次握手:
四次挥手:
FIN--请求断开连接
ACK--确认
1、为什么要进行三次握手,握手为什么需要三次?
答:为了防止无效的连接请求报文到达服务器而引起错误
详细解释:
假设A给服务器发送了一个请求,但是由于网络原因迟迟没有到达B服务器。由于一直没收到服务器端的回复确认,所以就进行超时重传,上个就舍弃了,
然后新的请求很快的到达了B服务器,然后B服务器也很快的进行了响应,如果是两次握手的话,这样就建立了连接,但是上次因网络问题迟迟未到的第一个请求这时到达了B服务器,服务器依然会当成新的连接请求进行响应,(服务器只要响应,第二次握手就完成了)这时又会建立连接,这就会出现建立了两个连接的局面,然后这就会出现很多问题,例如服务器端认为完成了握手,可以发送数据了,于是一直处于等待数据状态,而发送端不理睬服务器端发来的请求(因为发送端的那个请求早就被清除了),不去发送数据,后果就是服务器一直等,这样就会浪费很多服务器资源
如果是三次握手的话,就会避免这个问题,因为比如第二次的新请求
2、挥手为什么需要四次?三次不可以吗?
答:确保数据能够完整传输。
当被动方收到主动方的FIN报文通知时,它仅仅表示主动方没有数据再发送给被动方了。
但未必被动方所有的数据都完整的发送给了主动方,所以被动方不会马上关闭SOCKET,它可能还需要发送一些数据给主动方后,(按照常理的话,第二次和第三次挥手应该一起回复FIN=1和ACK=1的,但是因为服务器端可能有数据没发完,所以不能也立刻去主动申请关闭,所以要把ACK和FIN分开)
再发送FIN报文给主动方,告诉主动方同意关闭连接,所以这里的ACK报文和FIN报文多数情况下都是分开发送的。
5、网络层:
根据IP地址来进行逻辑寻址
IPv4地址---有限的--用完了
IPv6地址---
IP协议--网际网络协议
6、数据链路层:
---交换机
LLC 逻辑链路控制子层
为上层服务提供FCS校验 --封装和解封装
MAC 媒介访问控制子层
根据MAC地址来进行物理寻址
MAC地址--物理地址---设备在出场之后烧录在网卡上的
7、物理层:
定义:电气电压 光学特性 接口规范
tcp报头: Resv---预留位--保留出来的----服务质量---
来源 | http://www.fly63.com/
在项目开发中需要js实现千位分隔符来分割一个整数,比如我想将数字 1234567 显示为“1,234,567”。我该怎么实现呢?
方法一、利用循环 实现思路是将数字转换为字符数组,再循环整个数组, 每三位添加一个分隔逗号,最后再合并成字符串。
function numberWithCommas(x) { x = x.toString(); var pattern = /(-?\d+)(\d{3})/; while (pattern.test(x)) x = x.replace(pattern, "$1,$2"); return x; } numberWithCommas(12312124545);//'12,312,124,545' numberWithCommas(123121245.45);//'123,121,245.45' 方法二、toLocaleString Number.prototype.toLocaleString。它是在 JavaScript 1.5(于 1999 年推出)中实现的,因此基本上所有主要浏览器都支持它。
var num = 12345.1234 num.toLocaleString();//'12,345.123' 注意的是这个函数在没有指定区域的基本使用时,返回使用默认的语言环境和默认选项格式化的字符串,所以不同地区数字格式可能会有一定的差异。最好确保使用 locales 参数指定了使用的语言。
注:我测试的环境下小数部分会根据四舍五入只留下三位。比如:
var b=1234.4542; b.toLocaleString();//'1,234.454' 方法三、正则表达式和replace函数 使用正则表达式和replace函数,相对前两种我更喜欢这种方法,虽然正则有点难以理解。
function numberWithCommas(x) { return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","); } 正则表达式使用 2 个前瞻断言:
一个正数,用于在字符串中查找其后连续 3 位数字的任何点,
一个否定断言,以确保该点只有 3 位数字的倍数。替换表达式在那里放置一个逗号。
注意:这个函数如果小数点后有超过3位数字的话,会在不需要的地方添加逗号。如果这是一个问题,您可以使用此功能。
function numberWithCommas(x) { var parts = x.
一、问题描述 如果给出了遍历二叉树的前序序列和中序序列,则可以构造出唯一的一棵二叉树。试编写实现上述功能的程序。
【基本要求】
已知一棵二叉树的前序和中序序列,试设计完成下列任务的一个算法:
(1)构造一棵二叉树;
(2)证明构造正确(即分别以前序和中序遍历该树,将得到的结果与给出的序列进行比较)。
(3)对该二叉树进行后序遍历,输出后序遍历序列。
(4)用凹入法输出该二叉树。
【测试数据】
(1)前序序列为ABDEGCFHIJ,中序序列为DBGEAHFIJC。
(2)前序序列为-+abc/de,中序序列为a+bc-d/e 。
【拓展内容】
由原表达式构造二叉树。测试数据(a+b) ×c-d/e
二、需求分析 需要设计有以下几个功能的程序:
1:由已知的前序和后续序列构建二叉树2:分别用三种序列(前中后)输出二叉树3:用凹入法输出二叉树 输入:分别输入前序序列和后序序列
输出:四种方法分别输出该二叉树
拓展功能:根据输入的中缀表达式(四则运算),创建二叉树
三、设计 3.1 概要设计 (1)数据结构设计
根据题目要求易知本程序采用树结构作为基本结构,但在操作过程中也要用字符数组或者字符串类型储存计算过程中的表达式,考虑到需要多次使用截取部分字符串的
(2)算法设计
根据前序遍历的特点, 知前序序列(PreS)的首个元素(PreS[0])为二叉树的根(root), 然后在中序序列(InS)中查找此根(root), 根据中序遍历特点, 知在查找到的根(root) 前边的序列为根的左子树的中序遍历序列, 后边的序列为根的右子树的中序遍历序列。 设在中序遍历序列(InS)根前边有left个元素. 则在前序序列(PreS)中, 紧跟着根(root)的left个元素序列(即PreS[1…left]) 为根的左子树的前序遍历序列, 在后边的为根的右子树的前序遍历序列.而构造左子树问题其实跟构造整个二叉树问题一样,只是此时前序序列为PreS[1…left]), 中序序列为InS[0…left-1], 分别为原序列的子串, 构造右子树同样, 显然可以用递归方法解决。
建立完二叉树之后,很容易建立三个函数用递归的算法遍历输出已经建立的二叉树的前中后三种序列,对于凹入法,可以基于前序遍历输出,在输出的时候控制格式,即根据层高判断字符前面输出的空格数,在字符后输出与空格对应的点或其他字符,保持总的字符数不变。
3.2 详细设计 1.类的设计 由于本算法基于树来实现,首先要设计树的节点类,包括数据域和指针域,指针域包括左子树和右子树。树类包括一个指向树的节点类的指针和其他若干函数
2. 遍历函数设计 void PreOrderTraverse(BiNode* t) { if (t == NULL) return; cout << t->Data; PreOrderTraverse(t->L_Child); PreOrderTraverse(t->R_Child); }//前序遍历 遍历的算法如上,基于递归的思想,首先把t等于NULL作为递归出口
输出当前数据之后,依次递归访问左孩子和右孩子
对于中序和后续遍历仅需改变输出语句与访问左右孩子的顺序
3. 创建二叉树函数设计 void CreateBiTree(BiNode* t, string Pres, string Ins)//t为要建立的二叉树,pres和ins分别为前序和中序序列
在前后端分离开发中,我们前后端交互的内容都是json数据,为了规范我们之间的交互,我们就可以统一结果返回和请求的数据格式。以便我们交流。
统一结果:
@Data public class RespBean implements Serializable { @ApiModelProperty(value = "状态码") private Integer code; @ApiModelProperty(value = "时间戳") private Date timestamp; @ApiModelProperty(value = "提示信息") private String msg; @ApiModelProperty(value = "具体数据") private Map<String,Object> data = new HashMap<String,Object>(); //构造方法私有化 private RespBean(){ } //成功方法 public static RespBean success() { RespBean respBean = new RespBean(); respBean.setCode(RespCode.SUCCESS); respBean.setTimestamp(new Date()); respBean.setMsg("成功了"); return respBean; } //失败方法 public static RespBean error() { RespBean respBean = new RespBean(); respBean.
Solidworks里面扭簧的安装 在solidworks里面进行motion仿真时,点击添加弹簧,可以添加线性弹簧和扭转弹簧。对于线性弹簧,只需要点击两个圆柱面就可以添加这两个圆柱面之间的弹簧了,然后可以设置弹簧原长等参数。 对于扭转弹簧,第一个选项框提示的内容很多人不知道应该怎么选择。选择方法如下: 第一个框的内容可以选添加扭簧的轴,比如对于连杆机构,可以选择下面截图中的杆1的轴处圆柱面作为第一个框内的内容,这个是选择扭簧扭转的轴线方向。
然后第二个框内选择和该杆配合、扭簧力要作用的另一个零件。即杆2。
然后在参数框里,可以设置扭簧的原始角度,其原始角度的0度意思是以仿真开始0时刻时的角度作为0度,因此要注意,很多人都是添加了扭簧后仿真发现两个杆根本不动,这是因为初始时认为扭簧角度是0度,此时扭簧不对外提供力,所以就不会动。
最近想玩玩javap反编译然后捣鼓来捣鼓去,出现了这个问题,解决方案之一
1.打开【File - Project Structure】
2.修改【Module SDK】
3.点击OK 完成
一。Trie 树
**1.基本作用:**高效地存储和查找字符串集合的数据结构。用Trie树存储字符串的时候,字符串一般都是全小写或者是全大写并且字母的个数不会很多即限制只有26个或52个。
例如:
构造的Trie树如下:
注意,在每一个单词的最后一个字母后面打一个标记星号,说明到此为一个单词的结束。即要把每一个单词的最后一个字母打标记
2.代码如下:
#include<iostream> using namespace std; const int N=100010; //son表示N个节点的子节点,因为字符串都是小写字母,所以一个节点最多就只有26个子节点 //cnt[N]表示以N字符结束的单词有多少个,即结尾的标记 //idx 表示给当前节点分配一个序号下标 int son[N][26],cnt[N],idx;//注意下表为0的点,既是根节点又是空节点 char str[N];//存储输入的字符串 //存储字符串 void insert(char str[])//str[]存储的是字符串 { int p=0;//指向根节点 for(int i=0;str[i];i++)//因为字符串的最后一个字符是0,所以可以这样去判断 { int u=str[i]-'a';//提取出字符串中的每一个字符,转换到0-25 if(!son[p][u]) son[p][u]=++idx;//如果没有就创建 p=son[p][u];//然后就指向下一个,注意这里没有else,因为无论如何都要指向下一个 } cnt[p]++;//以p字符结尾的单词数量增加 } //查询字符串 int query(char str[]) { int p=0; for(int i=0;str[i];i++) { int u=str[i]-'a'; if(!son[p][u]) return 0;//如果没有的话就直接return p=son[p][u];//注意这个没有else,因为无论如何都要指向下一个 } return cnt[p]; } //学会该处理输入输出的方法 int main() { int n; scanf(“%d”,&n); while(n—) { char op[2];//细节,都用字符串读入 scanf(“%s%s”,op,str); if(op[0]==‘I’) insert(str); else printf(“%d\n”,query(str)); } return 0; } 二。并查集
距离分辨率表示为△R,是描述雷达将距离非常接近的目标检测为不同目标的能力。雷达系统工作在最小距离Rmin和Rmax之间。Rmin和Rmax之间的距离划分为M个距离单元(门),每个门的宽度为△R。
有多少个距离门??可以自行计算。又兴趣可以发消息咨询
相同距离单元的目标可以使用信号处理技术在横向距离上进行分辨。在相同距离单元内的目标可以使用信号处理技术在横向距离(方位)上进行分辨。考虑位于距离R1和R2处的两个目标,分别对应的时间延迟为t1和t2。则两者的距离差表示为:
△R=R1-R2=C*(t2-t1)/2=c*δt/2
问题1:两个目标在距离上是可以完全分辨的(距离单元不同)的最小δ是多少??最小 △R是多少??
假设两个目标,分析回波是否有重叠可以容易得知:
△R=c*t/2=c/2B
其中,B为雷达带宽,一般来说,寻求小的雷达分辨率就是减小△R。上式可知,为了获得更好的距离分辨率,必须减小脉冲宽度。然而,这样减小平均发射功率并且增加工作带宽。为了获得更好的距离分辨率的同时维持足够的平均发射功率,可以通过脉冲压缩技术来实现。
前言 参考《JS获取中文拼音首字母,并通过拼音首字母快速查找页面内的中文内容》
自己写的在线示例
目前CICFlowMeter主要有3个版本
(1)CICFlowMeter-4.0.zip,可执行版本,不要编译等,但提取生成流有问题,比如一个完整的ssh会话应该生成一条流信息,但这个工具却生成了2条流信息,识别fin包的时候存在问题
(2)CICFlowMeter-python版本,python setup install后可以使用,使用python3.7和3.8进行尝试运行过程中都存在问题,且生成的流特征中的TCP flag存在问题
(3)CICFlowMeter-java版本,这个版本目前没有问题,需要自己编译,下面讲解这个版本的编译,https://github.com/CanadianInstituteForCybersecurity/CICFlowMeter
第一步
进入以下目录,然后打包编译
//linux :at the pathtoproject/jnetpcap/linux/jnetpcap-1.4.r1425
//windows: at the pathtoproject/jnetpcap/win/jnetpcap-1.4.r1425
mvn install:install-file -Dfile=jnetpcap.jar -DgroupId=org.jnetpcap -DartifactId=jnetpcap -Dversion=1.4.1 -Dpackaging=jar
第二步
回退到工程根目录
mvn install
运行后会在target目录下生成
第三步
将dll(window)或者.so文件(linux)放入该目录后运行即可
如果使用eclipse 运行app.java来执行,那么除了做第一步外,还需要将dll或者so文件目录添加到库中
第一步:下载源码 地址 https://github.com/Microsoft/Detours/releases ,并解压至自己选择好的目录。例如 C:\work\detours\
第二步:编译
x86 ,32位的编译
打开VS 32位的命令行工具。这个可以是在开始——应用程序——vs2017找到。
输入:
cd C:\work\Detours
nmake -f makefile
即可得到32位的编译结果。
x64,64位的编译
选择x64的cmd。
输入:
cd C:\work\Detours
nmake -f makefile
即可得到64位的编译结果。
VS2017 设置Detour库
编译成功后会得到Detours 如下目录:
在vs2017里面设置项目属性,在Include目录里面添加上述的include的路径,在库目录添加lib.X64(64位编译器)或lib.X86(win32编译器)目录的路径,在链接器——输入——添加依赖项detours.lib
%% 该函数执行 MDH参数下正运动学求解功能 function [result] = myfkine_MDH(q,a,alpha,d,offset) % q为输入的关节转角,a为杆件长度,alpha为杆件扭角,d为关节距离 ,offset为关节变量偏移(MDH参数) % 注意:矩阵计算是现成的,但是记得加上关节变量的偏移量offset [N,D] = size(q); result=[]; for j = 1:1:N for i = 1:1:6 T(:,:,i) = [ cos(q(j,i) + offset(i)) -sin(q(j,i)+ offset(i)) 0 a(i); sin(q(j,i)+ offset(i))*cos(alpha(i)) cos(q(j,i)+ offset(i))*cos(alpha(i)) -sin(alpha(i)) -d(i)*sin(alpha(i)); sin(q(j,i)+ offset(i))*sin(alpha(i)) cos(q(j,i)+ offset(i))*sin(alpha(i)) cos(alpha(i)) d(i)*cos(alpha(i)); 0 0 0 1 ]; end result(:,:,j) = T(:,:,1)*T(:,:,2)*T(:,:,3)*T(:,:,4)*T(:,:,5)*T(:,:,6); end
目录 1.Text (文字)1.1 属性1.2 通过脚本设置Text的属性 2. Image(图片)2.1 属性2.2 注意:图片导入 3.Button(按钮)3.1 属性3.2 使用时 4. Toggle4.1 Toggle与Button的不同4.2 OnChangeValue属性4.3 IsOn属性4.4 Toggle Group 5.DropDown (下拉菜单)5.1 绑定监听事件 7.InputFiled (输入组件)7.1 属性7.2 示例 8.Raw Image (未加工图片)8.1 显示图片8.2 搭配相机显示相机画面8.3 播放视频 9.Canvas(画布)9.1 Canvas: Render Mode属性9.2 Canvas Scaler: 画布缩放模式 10.Scroll View (滚动视图)10.1 Movement Type: 运动类型10.2 Visibility: 能见度10.3 Mask: 掩饰 11.Slider (滑动器)12.Scrollbar (滚动条)12.1 Number Of Steps属性 1.Text (文字) 用来像是文字并对其进行处理,最常用。
1.1 属性 1.2 通过脚本设置Text的属性 using UnityEngine; using UnityEngine.UI; public class Text : MonoBehaviour { public Text TestText; //定义一个Text组件 void Start() { TestText.
在线测试工具:https://the-x.cn/cryptography/Aes.aspx
加解密方法 /** * aes 加密方法 * data 字符串 */ AesEncrypt(data) { var key = "1234123412341234"; var keyHex = CryptoJS.enc.Utf8.parse(key); var encrypted = CryptoJS.AES.encrypt(data, keyHex, { iv: [], mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 }); var encryptData = encrypted.ciphertext.toString().toUpperCase(); // 转为hex格式,转为Base64的字符串,如果转为base64格式,解密的方式就配置不同 var oldHexStr = CryptoJS.enc.Hex.parse(encryptData); // 将密文转为Base64的字符串 var base64Str = CryptoJS.enc.Base64.stringify(oldHexStr); return base64Str }, /** * aes 解密方法 */ AesDecrypt(decodedData) { var key = "1234123412341234"; var keyHex = CryptoJS.enc.Utf8.parse(key); var decrypted = CryptoJS.
目录 0、环境准备1、下载docker_toolbox工具1、2安装docker_toolbox1、3 使用虚拟机1、4 端口映射1、5 目录挂载: 示意图:
后面安装的docker_toolbox工具,其实类似于Windows的VMware一样,docker_toolbox提供了一个Linux系统,可以在里面进行docker的使用(和平时在Linux环境使用docker一样)
0、环境准备 Docker 在 window 上需要你的 Cpu 支持虚拟化。打开任务管理器,选择性能就可以查看:
1、下载docker_toolbox工具 注:(Windows server 2012版本需要该工具支持才能运行docker)
附上安装包:提取码:vmxv【点我下载】,也可自行去官网下载。
1、2安装docker_toolbox 双击运行下载好的docker_toolbox程序进行安装;
安装路径自行选择;
遇到下面界面建议勾选,其余默认下一步即可。
1、3 使用虚拟机 双击下面安装好的虚拟机管理工具,进入后默认有一个名为default的虚拟机,右击运行;
虚拟机默认信息一般是:
host:192.168.99.100
user:docker
password:tcuser
(1)可以使用自带的终端窗口进行操作(不支持中文显示,不推荐);
(2)也可以使用自己的xshell类工具连接(推荐)
1、4 端口映射 例如:
如果需要将docker容器内部的服务的端口8001映射出来,需要在docker_toolbox 工具里设置,才能在自己的Windows server宿主机浏览器访问使用:
1、5 目录挂载: 如果需要将docker内部的目录映射到Windows server本地。需要:
1、先将Windows本地目录映射到Linux虚拟机
登录虚拟机Linux,执行下面命令挂载
# 切换root sudo -i # 将Windows本地目录d/dian_lian/program/logs映射到虚拟机目录/mnt/docker/logs sudo mount -t vboxsf d/dian_lian/program/logs /mnt/docker/logs 2、再将docker内部目录映射到虚拟机Linux的目录。
# 将镜像启动成一个容器(将容器目录映射到虚拟机目录) docker run --name=u8 --privileged=true -p 8001:8001 -v /mnt/docker/logs:/web/u8_data/logs -itd u8 /usr/sbin/init
RocketMQ学习与分析 1. 架构图2. 设计2.1 设计理念2.2 设计目标 1. 架构图 NameServer:
类似注册中心,存储了协调治理Broker所需的所有信息(如<borker:Topic路由信息>,HashMap存储)NameServer集群各节点之间没有信息同步(producer和consumer轮询所有NameServer节点直到拿到所需信息)通过定期心跳来管理Broker信息,并对外提供接口给producer/consumer访问broker信息。 Broker:
消息中枢,持久化消息数据,保存订阅关系、消费进度等。Broker的核心在于消息存储:其通过内存映射、顺序写、索引查询保证效率 Topic:
topic就是一个消息主题,是一个逻辑概念,实际包含多个属于同一个topic下的消息。在rocketmq中,一个topic会分片到多个broker上,且在每个broker上继续分片成多个Queue,如下图。
分片到多个broker上是为了突破单点的资源限制(CPU、带宽、内存等),从而实现水平扩展。
分片到多个Queue上是为了负载均衡,rockermq限制了对于N个Queue,只允许<N的Consumer来访问,且这些Consumer会均衡到各个Queue上。
此外,topic对应的消息数据并非真的消息数据,而是指向物理数据的消息索引。
Producer:
生产者,主要用于推送数据,并且有一些默认的定时任务(比如定期获取broker)
Consumer:
消费者,拉模式,定期(!while(this.isStopped(){拉消息})从broker上拉取可消费信息。拉取时机由Rebalance均衡器进行平衡控制。
2. 设计 2.1 设计理念 消息中间件的理想状态是,一条消息能且仅能被消费一次,但要做到这一点,必须牺牲性能。RocketMQ的设计思路是,不去解决这一问题,保证消息至少被消费一次(可能被消费者多次消费),消息消费的幂等由消费者自己实现,这样简化了设计内核,提高了整体性能。NameServer极其简单,集群各节点之间互补通信,Topic路由信息无需在集群中保持强一致,只要求最终一致性,且容忍分钟级别的不一致。高效的IO存储,RocketMQ追求消息发送的高吞吐量, RocketMQ将消息存储文件设计成文件组的概念,组内单个文件大小固定,方便引人内存映射机制,所有topic的消息存储基于顺序写,极大地提供了消息写性能,同时为了兼顾消息消费与消息查找,引入了消息消费队列文件与索引文件。 2.2 设计目标 顺序消息:保证消息消费者按照消息到达存储服务器的顺序消费消息过滤:消费者只消费自己感兴趣的消息(broker过滤 or 消费者过滤)消息存储:考量维度(消息堆积能力以及消息存储性能)高可用:同步刷盘确保消息不丢失,异步复制(同步双写)避免单点故障At-least-once:通过ACK机制确保消息至少被消费一次消息到达低延迟:通过长轮询的机制实现准实时的消息推送消息回溯:消费者想要重新消费已经被消费过的消息消息堆积:削峰的必备能力定时消息:只有到达某个时间点,才能被消费者看到消息重试:消费消息时投递失败,重新投递 参考
消息存储详解
概念模型
rocketmq重点记录
《RocketMQ技术内幕》
文章目录 举例讲解transformer的输入输出细节encoderpaddingPadding MaskPositional EmbeddingattentionFeedForwardadd/Normencoder输入输出 decoderSequence Mask测试 Transformer pytorch代码实现数据准备参数设置定义位置信息Mask掉停用词Decoder 输入 Mask计算注意力信息、残差和归一化前馈神经网络encoder layer(block)Encoderdecoder layer(block)DecoderTransformer定义网络训练Transformer测试 参考 举例讲解transformer的输入输出细节 数据从输入到encoder到decoder输出这个过程中的流程(以机器翻译为例子):
encoder 对于机器翻译来说,一个样本是由原始句子和翻译后的句子组成的。比如原始句子是: “我爱机器学习”,那么翻译后是 ’i love machine learning‘。 则该一个样本就是由“我爱机器学习”和 “i love machine learning” 组成。
这个样本的原始句子的单词长度是length=4,即‘我’ ‘爱’ ‘机器’ ‘学习’。经过embedding后每个词的embedding向量是512。那么“我爱机器学习”这个句子的embedding后的维度是[4,512 ] (若是批量输入,则embedding后的维度是[batch, 4, 512])。
padding 假设样本中句子的最大长度是10,那么对于长度不足10的句子,需要补足到10个长度,shape就变为[10, 512], 补全的位置上的embedding数值自然就是0了
Padding Mask 对于输入序列一般要进行padding补齐,也就是说设定一个统一长度N,在较短的序列后面填充0到长度为N。对于那些补零的数据来说,attention机制不应该把注意力放在这些位置上,所以需要进行一些处理。具体的做法是,把这些位置的值加上一个非常大的负数(负无穷),这样经过softmax后,这些位置的权重就会接近0。Transformer的padding mask实际上是一个张量,每个值都是一个Boolean,值为false的地方就是要进行处理的地方。
Positional Embedding 得到补全后的句子embedding向量后,直接输入encoder的话,那么是没有考虑到句子中的位置顺序关系的。此时需要再加一个位置向量,位置向量在模型训练中有特定的方式,可以表示每个词的位置或者不同词之间的距离;总之,核心思想是在attention计算时提供有效的距离信息。
初步理解参考我的博客【初理解】Transformer中的Positional Encoding
attention 参考我的博文(2021李宏毅)机器学习-Self-attention
FeedForward 略,很简单
add/Norm 经过add/norm后的隐藏输出的shape也是[10,512]。
encoder输入输出 从输入开始,再从头理一遍单个encoder这个过程:
输入xx 做一个层归一化: x1 = norm(x)进入多头self-attention: x2 = self_attention(x1)残差加成:x3 = x + x2再做个层归一化:x4 = norm(x3)经过前馈网络: x5 = feed_forward(x4)残差加成: x6 = x3 + x5输出x6
1、定义两个select选项框,一个存放以及下拉列表,一个存放联动下拉列表。
<!--联动选择省份后选择城市--> <el-form-item label="选择省份:"> <el-select size="small" style="width: 100px" v-model="selectProv" placeholder="请选择省份" v-on:change="getProv($event)"> <el-option v-for="item in provs" :label="item.label" :value="item.value"> </el-option> </el-select> <el-select size="small" style="width: 100px" v-if="selectProv!=''" v-model="selectCity" placeholder="请选择城市" v-on:change="getCity($event)"> <el-option v-for="item in citys" :label="item.label" :value="item.value"> </el-option> </el-select> </el-form-item> 2、js部分分别定义数据和实现联动的方法
export default { data() { return { provs:[ {label:"北京市",value:"北京市"}, {label:"天津市",value:"天津市"}, {label:"河北省",value:"河北省"}, {label:"山西省",value:"山西省"}, {label:"内蒙古自治区",value:"内蒙古自治区"}, {label:"辽宁省",value:"辽宁省"}, {label:"吉林省",value:"吉林省"}, {label:"黑龙江省",value:"黑龙江省"}, {label:"上海市",value:"上海市"}, {label:"江苏省",value:"江苏省"}, {label:"浙江省",value:"浙江省"}, {label:"安徽省",value:"安徽省"}, {label:"福建省",value:"福建省"}, {label:"江西省",value:"江西省"}, {label:"山东省",value:"山东省"}, {label:"河南省",value:"河南省"}, {label:"湖北省",value:"湖北省"}, {label:"湖南省",value:"湖南省"}, {label:"广东省",value:"广东省"}, {label:"广西壮族自治区",value:"广西壮族自治区"}, {label:"海南省",value:"海南省"}, {label:"重庆市",value:"重庆市"}, {label:"四川省",value:"四川省"}, {label:"贵州省",value:"贵州省"}, {label:"
1.某天打开发先 无论什么环境,请求头很多东西没有发送,preview一片空白,response 提示 “this request has no response data available”
2.分析最后结果是!!!!忘了关mock.将这里启用mock 选中取消即可
3.分析
请求头中Referer 请求头包含了当前请求页面的来源页面的地址,即表示当前页面是通过此来源页面里的链接进入的
我们的referer:fake 此时应该是代理不对。此时就要检查自己的代理网络,包括mock之类
正常referer:“http://xxxxxxxxxxx”应该是一个url
帖一个正常请求头
docker run -e ‘ACCEPT_EULA=Y’ -e ‘MSSQL_SA_PASSWORD=’ -p 1401:1433 -v :/var/opt/mssql --name sql1 -d microsoft/mssql-server-linux:2017-latest
其中ACCEPT_EULA=Y的意思是同意许可协议,必选;MSSQL_SA_PASSWORD为密码,要求是最少8位的强密码,要有大写字母,小写字母,数字以及特殊符号,不然会有一个大坑(docker启动sqlserver容器后过几秒就停止了);
关键字:
数据类型、时间类型
Oracle日期时间类型有两类,一类是日期时间类型,包括Date, Timestamp with time zone,Timestamp with local time zone。另一类是Interval类型,主要有Interval year to month 和Interval day to second两种。
KingbaseES也有类似的两类时间类型。其中日期时间类型包括Timestamp with time zone, Timestamp without time zone,Date,Time with time zone , Time without time zone五种。Interval类型为Interval。此外,KingbaseES扩展了Date数据类型,在兼容oracle模式时date的值“年月日时分秒”与oracle一致,在pg模式下则为“年月日”。
1、 日期时间类型
1.1. Date 类型
Oracle的Date类型包括年、月、日、时、分、秒六个字段,时间跨度是公元前4712年1月1日~公元9999年12月31日。
Oracle date:
SQL> create table o_test(value date);
Table created.
SQL> insert into o_test values(to_date(’-4712-01-01 00:30:45’, ‘syyyy-mm-dd hh24:mi:ss’));
1 row created.
SQL> insert into o_test values(to_date(’-4712-01-01 00:30:45’, ‘syyyy-mm-dd hh24:mi:ss’) - interval ‘1’ day);
Flex 布局教程 Flex是Flexible Box的缩写,意为"弹性布局",用来为盒状模型提供最大的灵活性。
任何一个容器都可以指定为Flex布局。
.box{ display: flex; } 行内元素也可以使用Flex布局。Webkit 内核的浏览器,必须加上-webkit前缀。
.box{ display: -webkit-flex; /* Safari */ display: flex; } 注意,设为Flex布局以后,子元素的float 、clear和vertical-align属性将失效。
父元素开启弹性后,父元素有6个可设置属性(紫色大盒子): flex-directionflex-wrapflex-flowjustify-contentalign-itemsalign-content 1. flex-direction 决定主轴方向
flex-direction 是用来决定主轴方向的。flex-direction有四个属性值:
row(默认值)∶主轴为水平方向,起点在左端。 row-reverse:主轴为水平方向,起点在右端。 column:主轴为垂直方向,起点在上沿。 column-reverse :主轴为垂直方向,起点在下沿。 2. flex-wrap 设置换行
默认情况下,项目都排在一条线(又称"轴线")上。 flex-wrap属性定义,如果一条轴线排不下,如何换行。flex-wrap有三个属性值:
nowrap(默认值):不换行。
wrap:换行,第一行在上方。
wrap-reverse:换号,第一行在下方
3. flex-flow
flex-flow属性是flex-direction属性和flex-wrap属性的简写形式,默认值为row nowrap 。
flex-wrap主轴换行。
4. justify-content
justify-content属性定义了项目在主轴上的对齐方式。它有五个属性值:
flex-start(默认值):左对齐flex-end:右对齐center:居中space-between:两端对齐,项目之间的间隔都相等。space-around:每个项目两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍。
5. align-items
align-items属性定义项目在交叉轴上如何对齐。它有五个属性值:
flex-start:交叉轴的起点对齐。flex-end:交叉轴的终点对齐。center:交叉轴的中点对齐。baseline :项目的第一行文字的基线对齐。stretch(默认值):如果项目未设置高度或设为auto ,将占满整个容器的高度。
6. align-content
align-content属性定义了多根轴线的对齐方式。它有六个属性值:
flex-start:与交叉轴的起点对齐。flex-end :与交叉轴的终点对齐。center:与交叉轴的中点对齐。space-between :与交叉轴两端对齐,轴线之间的间隔平均分布。space-around :每根轴线两侧的间隔都相等。所以,轴线之间的间隔比轴线与边框的间隔大一倍。stretch(默认值)︰轴线占满整个交叉轴。
子元素也有6个属性设置(橙色小盒子): orderflex-growflex-shrinkflex-basisflexalign-self 1. order属性
用于将dll和有效负载插入新进程的api DetourCreateProcessWithDllExDetourCreateProcessWithDllsDetourCopyPayloadToProcessDetourCopyPayloadToProcessExDetourFinishHelperProcessDetourIsHelperProcessDetourRestoreAfterWith 一、DetourCreateProcessWithDllEx 创建一个新进程并将DLL加载到其中。根据目标进程选择适当的32位或64位DLL。
替换DetourCreateProcessWithDll。
定义 BOOL DetourCreateProcessWithDllEx(_In_opt_ LPCTSTR lpApplicationName, _Inout_opt_ LPTSTR lpCommandLine, _In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes, _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, _In_ BOOL bInheritHandles, _in_dword dwCreationFlags, _In_opt_ LPVOID lpEnvironment, _In_opt_ LPCTSTR lpCurrentDirectory, _in_lpstartupinfo,_Out_ LPPROCESS_INFORMATION lpProcessInformation, _In_ LPCSTR lpDllName, _In_opt_ PDETOUR_CREATE_PROCESS_ROUTINEW pfCreateProcessW); 参数 lpApplicationName:为CreateProcess API定义的应用程序名称。
lpCommandLine: CreateProcess API定义的命令行。
lpProcessAttributes:为CreateProcess API定义的流程属性。
lpThreadAttributes:为CreateProcess API定义的线程属性。
bInheritHandles:继承CreateProcess API定义的句柄标志。
dwCreationFlags:为CreateProcess API定义的创建标志。
lpEnvironment:为CreateProcess API定义的进程环境变量。
lpCurrentDirectory:为CreateProcess API定义的进程当前目录。
lpStartupInfo:为CreateProcess API定义的进程启动信息。
lpProcessInformation:为CreateProcess API定义的进程句柄信息。
lpDllName:要插入到新进程的DLL的路径名。要同时支持32位和64位应用程序,如果DLL包含32位代码,则DLL名称应该以"32"结尾,如果DLL包含64位代码,则应该以"64"结尾。如果目标进程与父进程大小不同,Detours将自动将路径名中的“32”替换为“64”或“64”替换为“32”。
pfCreateProcessW:指向特定程序的CreateProcess API替换的指针,如果应该使用标准的CreateProcess API创建新进程,则为NULL。
返回值 如果创建了新进程,则返回TRUE;否则返回FALSE。
错误代码 请参阅CreateProcess返回的错误代码。
由于某些原因,在 macOS 安装最新版本的 adobe 应用,比如 Photoshop 之类,不想用最新的版本,要安装以前老旧的版本。本文提供一个在 macOS 安装老旧版本 adobe 应用的思路。关键在于使用 ccdl.py 脚本下载古老的 adobe 软件版本,这个脚本需要 Create Cloud App 的支持,所以先安装 Create Cloud App。
Create Cloud App 官方网址
https://creativecloud.adobe.com/apps/all/desktop
登录,下载 Create Cloud App 或者 Adobe Photoshop,选择免费试用,安装完成后 Create Cloud App 启动就 OK。
ccdl.py 这是 ayyybe 在 Gist 上分享的脚本,thpryrchn 进行了更新,Adobe Offline Package Generator v0.1.4 (macOS only)
https://gist.github.com/thpryrchn/c0ea1b6793117b00494af5f05959d526#file-ccdl-py
https://download.csdn.net/download/zhangyingda/35314168
创建一个 python venv,激活 venv,运行 ccdl.py,选择软件,版本,语言,存放位置。
z@iMac ~/code/python/ccdl python -m venv ven z@iMac ~/code/python/ccdl ls ccdl.
书接上回-《串行总线技术(一)-串行总线结构(以PCIe为例)串行总线技术(二)-串行总线中的先进设计理念及SerDes/PMA介绍
简介 SATA(Serial Advanced Technology Attachment,高级技术附加装置)是在2002年作为并行ATA(Parallel ATA,PATA)的替代技术而引人的。由于SATA是一种串行协议,与并行ATA相比,它所需要的引脚数少、连接器尺寸也小。第一代SATA(也被称为SATA1.0)以1.5Gbps速度运行。SATA2.0的运行速度翻倍至3.0Gbps,在SATA3.0中,运行速度进一步翻倍至6.0GbpS。
SATA架构 SATA组成部分包括两种类型:SATA宿主(SATA host)和SATA设备(SATA device),如图所示。
SATA宿主通常位于个人计算机中。SATA宿主可以有一个或者多个端口。SATA宿主的每一个端口连接一个SATA设备。即使SATA宿主具有多个端口,各个端口的运行也是彼此独立的,同时每一个SATA设备的运行都独立于其他SATA设备。
SATA宿主集成在芯片组内部,在芯片组内部,SATA宿主的前端连接至芯片组内部的PCle总线或AHB/AXI总线上。SATA宿主采用寄存器接口层进行数据通信,该寄存器接口层被称为高级宿主控制器接口(Advanced Host Controller Interface,AHCI)。AHCI为DMA数据传送提供了基于寄存器的接口。在软件中有操作指令,软件存储在存储器中。然后,软件对宿主寄存器空间进行置位表示指令已就绪。SATA宿主从存储器中取出指令并将它们传送给SATA设备。
SATA设备接收到来自宿主的指令并加以执行。在SATA设备的后端,通常是硬盘控制器。SATA协议层将SATA指令传递给硬盘控制器,由它来执行指令(从硬盘中读出数据或者将数据写入硬盘)。SATA支持本地命令排序(Native Command Queuing,NCQ),即硬盘控制器通过SATA协议接收多条指令、并按照最佳顺序加以执行。
SATA协议分为三层(复杂协议都具有分层管理机制):传输层、链路层和物理层。物理层最接近物理链路,具有8b/10b编解矶、扰码/解扰等功能。另外,它还关注链路训练和初始化。数据链路层是中间层次,关注链路对链路的通信。数据链路报文长度同定(4字节),称为原语(primitive)。SATA采用全双工通信协议,但与PCle类似,发送和接收线路不同时进行数据传送。当一方将数据发送到TX通道上时,另一方发送原语。原语用于传递控制信息,如R-OK(接收数据无差错)、R_ERR(接收数据有差错)、HOLD(发给发送方的流控信,让其暂停发送数据)。
最上面一层被称为传输层,它与应用层相连。它接收来自应用层的指令和数据,并以帧信息结构(Frame Information Structure,FIS)的形式传递给另一方。FIS中包括头部、净载荷数据和循环冗余检验码,其净载荷长度可变。
SATA的其他变种 eSATA eSATA代表外部SATA(External SATA)。它采用更好的连接器和更长的屏蔽线缆,最长可达2米,如图所示。它针对的是外部硬盘。
mSATA mSATA代表小型化SATA(mini-SATA)。它针对的是移动应用和小型固态电子存储设备。它有类似于mini-PCIe卡的外形尺寸,面向笔记本和上网本设备,如图所示。
快速SATA SATA Express代表快速SATA。它是将SATA协议和PCIe接口结合在一起的新协议。SATA Express连接器可以接插一个x2的PCIe设备或者两个SATA设备,如图所示。
带宽最高可达16Gbps带宽(现在最快的SATA 3.2标准带宽为16Gbps),SATA Express标准将会如其名称所描述的,把SATA软件架构和PCI-Express高速界面结合在一起。SATA国际组织称SATA Express标准将会带来新一代更快的存储装置和对应的主板接口,并且还能兼容现有的SATA设备。SATA国际组织主席Mladen Luksic称该标准将使固态与混合硬盘受益于新一代PCI-Express 3.0的高带宽从而打破性能瓶颈,标准的具体细节将在年内制定完成。SATA国际组织同时表示除SATA Express外,还有针对集成在主板上的嵌入式单芯片SSD存储解决方案的SATA µSSD标准,面向移动设备如平板电脑等。
NOW现在行动!
学习Xilinx FPGA最好的资料其实就是官方手册,下表总结了部分手册的主要介绍内容,关注我,持续更新中......
文件名主标题内容简单介绍是否有中文版UG4767 Series FPGAs GTX/GTH TransceiversGTX和GTH介绍,PCIe、serdes等学习必备否UG4717 Series FPGAs SelectIO Resources描述 7 系列 FPGA 中可用的 SelectIO资源。否UG1114PetaLinux Tools DocumentatonPetaLinux 工具文档 参考指南是,V2019.2UG949UltraFAST 设计方法指南(适用于 Vivado Design Suite)赛灵思® UltraFast™ 设计方法是用于为当今器件优化设计进程的一套最佳实践。这些设计的规模与复杂性需要执行特定的步骤与设计任务,从而确保设计每一个阶段的成功开展。依照这些步骤,并遵循最佳实践,将帮助您以最快的速度和最高的效率实现期望的设计目标是,V2018.1IP手册pg057FIFO GeneratorFIFO生成器IP使用手册否pg104Complex Multiplier复数乘法器IP使用手册否pg122RAM-Based Shift Register 移位寄存器IP使用手册否 推荐阅读
发生异常: TypeError (note: full exception trace is shown but execution is paused at: )
init() got an unexpected keyword argument ‘datasets’
查看loader中自己写的dataset,是不是多写了一个s
train_loader = Data.DataLoader( datasets= train_data, batch_size=BATCH_SIZE, shuffle=True, num_workers=2 ) j
将上述代码修改为:
train_loader = Data.DataLoader( dataset= train_data, batch_size=BATCH_SIZE, shuffle=True, num_workers=2 )
一、Pythont如何打开 txt 格式的文件? 1.首先我使用pycharm创建一个项目,然后在这个项目里面再创建一个python的包,然后在里面创建一个demo1.txt的文件吗,里面写一些我看过的小说,然后使用python对这个txt文件进行内容的读取.
txt的内容如下:
这一个txt文件的创建是和.py文件创建在同样的一个包里面的:
目录如下:
然后如何进行读取呢,首先需要使用到open()和read().
代码如下:
c1 = open('demo1.txt', 'r') print(c1.read()) 在open()里面的’r’是以read的方式进行打开,没有这个也是可以进行读取文件里面的内容的
代码的运行结果如下:
可以看到的是,这是整个文件.txt都被读下来了.
也可以使用python的 with … open … as … 的句子对文件进行打开,并且把文件进行打开后的重命名.
代码如下:
with open('demo1.txt', 'r') as file1: contents = file1.read() print(contents) 运行之后可以看到代码的运行结果和第一次的运行结果是相同的.
运行结果如下:
—————————————————————————————————
二、什么是相对路径,什么是绝对路径? 1.相对路径:相对于目录(程序文件所在的目录),一般无盘符起始
2.绝对路径:将文件在计算机中的准确位置告诉python,一般由盘符起始
(上面我创建的demo1.txt就是在程序文件的包内的,使用在程序里面open(‘demo1.txt’, ‘r’))就是相对路经,但是假如我使用的是绝对路径的话,那么使用的路径就是(我创建demo1.txt的在C盘里面)那么我写就要写成如下:
open('C\Demo1\demo1.txt', 'r') —————————————————————————————————
三、如何进行逐行提取数据? file2 = 'demo1.txt' with open(file2) as lines: for line in lines print("\n" + line.strip()) #strip()是用于去除字符串里面的空格.这个可以上网查一下相关的资料. 代码运行结果:
—————————————————————————————————
四、创建一个包含文件各行内容的列表 使用关键字with时,open()返回的文件对象只在with代码块内可用。如果要在with代码块外访问文件的内容,可在with代码块内将文件的各行存储在一个列表中,并在with代码块外使用该列表:你可以立即处理文件的各个部分,可推迟到程序后面再处理。
使用readlines()的方法,进行将读取的每一行数据传进lines这一个数组当中.
代码如下:
with open(file2) as file_work: line3 = file_work.
solidworks中弹簧与圆柱体如何配合?五步教会你 在solidworks装配过程中,会遇到各种各样的配合,然而有时也会遇到弹簧与螺杆,弹簧与轴类之间的配合,这种情况应该用哪种配合方式呢?用同轴心?事实上并不行,接下来我会说一下具体的配合方法。
1.首先建立装配体,同时导如一个圆柱体和弹簧如下图所示。
2.尝试用配合,然而发现只能用相切配合,但是却不是我们想要的配合形态。
3.退出配合,在左侧设计树右击弹簧选择在当前状态下打开零件。
4.点击编辑前视基准面。在坐标中心画一个任意直径的圆,要确保这个中心和弹簧所形成的圆是同轴心。然后保存,关闭当前零件回到之前的装配体。
5.点击弹簧上的圆和圆柱使它们的配合是同轴心,如下图所示。然后点击钩出现如下形态。然后点击圆圈使它隐藏即可。
用于路由目标函数的api DetourTransactionBeginDetourUpdateThreadDetourAttachDetourAttachExDetourAllocateRegionWithinJumpBoundsDetourDetachDetourSetIgnoreTooSmallDetourSetRetainRegionsDetourSetSystemRegionLowerBoundDetourSetSystemRegionUpperBoundDetourTransactionAbortDetourTransactionCommitDetourTransactionCommitEx 一、DetourTransactionBegin 开始一个附加或分离弯道的新事务。
定义 LONG DetourTransactionBegin(VOID); 返回值 如果成功返回NO_ERROR;否则返回ERROR_INVALID_OPERATION。
错误代码 ERROR_INVALID_OPERATION:一个挂起的事务已经存在。
说明 DetourTransactionBegin开始一个新的事务,用于附加或分离弯道。
在开始一个事务之后,程序调用DetourAttach或DetourAttachEx API将一个DetourAttach附加到一个目标函数,调用DetourDetach API将一个DetourDetach API从一个目标函数中分离出来,或者调用DetourUpdateThread API在事务更新中包含一个线程。
在程序使用DetourTransactionCommit或DetourTransactionCommitEx API提交事务之前,附加、分离和线程操作不会生效。或者,程序可以使用DetourTransactionAbort API中止事务。
有关使用Detours拦截函数调用的更多信息,请参阅Detours概述中的拦截二进制函数或使用Detours。
相关的实例 commmem, Cping, Dtest, Excep, FindFunc, Member, Simple, Slept, Traceapi, Tracebld, Tracelnk, Tracemem, Tracereg, Traceser, Tracetcp, Tryman。
二、DetourUpdateThread 在当前事务中征募用于更新的线程。
定义 LONG DetourUpdateThread( _In_ HANDLE hThread ); 参数 hThread:要用挂起的事务更新的线程句柄。如果hThread等于当前线程的伪句柄(由GetCurrentThread()返回),则不执行任何操作,并返回NO_ERROR。
返回值 如果成功返回NO_ERROR;否则,返回错误代码。
错误代码 ERROR_NOT_ENOUGH_MEMORY:没有足够的内存来记录线程的标识。
说明 当由DetourTransactionBegin API打开的当前事务提交时,DetourUpdateThread登记指定的线程进行更新。
当一个DetourUpdateThread事务提交时,Detours确保通过DetourUpdateThread API在事务中注册的所有线程都被更新,如果它们的指令指针位于重写的代码中目标函数或trampoline函数中。
事务提交时,未在事务中登记的线程不会更新。因此,他们可能会试图执行旧代码和新代码的非法组合。
目前不支持对当前线程使用非伪句柄调用DetourUpdateThread,并将导致应用程序挂起。
有关使用Detours拦截函数调用的更多信息,请参阅Detours概述中的拦截二进制函数或使用Detours。
相关的实例 commmem, Cping, Dtest, Excep, FindFunc, Member, Simple, Slept, Traceapi, Tracebld, Tracelnk, Tracemem, Tracereg, Traceser, Tracetcp, Tryman。
记录一下服务器访问域名出去连接超时问题。
网络连接超时: 网络正常:
一开始从网上看设置nginx超时时间proxy_connect_timeout,原来是10s,改为30秒。
发现nginx日志显示依旧会在30秒后超时。
其中通过ping和telnet发现网络大部分时间正常(比nginx超时少),所以怀疑是外网网络开通问题。
因为是域名访问,所以必须要用到dns解析。
我这用的是114.114.114.114和119.29.29.29,查看外网防火墙发现有配置dns解析的地方,并且用到的了3个dns,其中一个是114,所以感觉像是服务器用其他dns解析出来的ip地址,在经过防火墙的时候,防火墙不给过。
最后通过服务器配置的dns和防火墙配置的dns保持一致,网络恢复正常。
ubuntu内核升降级 h1. Ubuntu 降级内核 当前使用高版本的内核,需要安装低版本的内核。
如 CDM 一体机需要从 4.11.0-14 降级到 4.4.0-157 。
早期出货的一体机内核版本较高,但是其是公共源的内核,其内置的 zfs 模块为 0.6.5 版本,而内部编译的内核 4.4.0-157 对内核进行了稳定性方面的优化,并内置了 0.7.9 版本的 zfs 模块。
h2. Ubuntu 16.04下从 4.11.0-14 降级到 4.4.0-157 #先安装低版本内核。
参照[[Ubuntu升级内核]]的方法安装内核。
#默认情况下,系统使用高版本内核启动,通过设置 grub 默认的引导菜单来使用低版本的内核启动系统。如果可以连接显示器或者 IPMI 管理口,也可以手工选择。
操作流程 操作1
##查询启动的菜单,如下所示,实际或有所不同。
第 131 行是菜单 0 (从0开始计数),148 行是菜单 1,而且其包含6个子菜单。
则对应 4.4.0-157 内核的子菜单是 2 ,所以选择 4.4.0-157-generic 内核依次是 1>2
root@ubuntu1604:~# grep -nE "menuentry |submenu" /boot/grub/grub.cfg 131:menuentry 'Ubuntu' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-simple-30d0e024-403e-4c94-9edd-ebb2bb5687aa' { 148:submenu 'Advanced options for Ubuntu' $menuentry_id_option 'gnulinux-advanced-30d0e024-403e-4c94-9edd-ebb2bb5687aa' { 149: menuentry 'Ubuntu, with Linux 4.
ftp搭建 一、什么是ftp?
FTP 是File Transfer Protocol(文件传输协议)的英文简称,而中文简称为“文传协议”。用于Internet上的控制文件的双向传输。同时,它也是一个应用程序(Application)。基于不同的操作系统有不同的FTP应用程序,而所有这些应用程序都遵守同一种协议以传输文件。在FTP的使用当中,用户经常遇到两个概念:“下载”(Download)和"上传"(Upload)。“下载"文件就是从远程主机拷贝文件至自己的计算机上;“上传"文件就是将文件从自己的计算机中拷贝至远程主机上。用Internet语言来说,用户可通过客户机程序向(从)远程主机上传(下载)文件。
二、搭建FTP服务器步骤(以win7为例)
为windows开启ftp功能:控制面板–>程序和功能–>打开或关闭Windows功能将如图的选框选中
2、添加FTP站点:打开控制面板–>管理工具–>双击Internet信息服务(IIS)管理器如下图添加FTP站点
3、设置站点名称和想要公开的路径
4、绑定IP地址和ssl设置:
IP地址填本机地址,端口默认21,ssl是一种数字加密证书,可申请,在此没有可选择无。
5、设置权限,建议设置成读取状态,点击完成就大功告成了。
6、如何登陆测试
1>从网页登陆:输入命令ftp://本地IP如下图
登陆成功会出现如下界面,输入用户名和密码即可登陆
注:用户名和密码可右击计算机–>管理–>本地用户和组–>用户–>administrator–>右击修改密码设置即可如下图
用户和密码输入正确的话就会出现你公开的路径
2>通过cmd命令进入ftp来下载或上传
开始栏输入cmd或者按快捷键win+R出现如图界面
输入"ftp"切换到到ftp下面.然后输入"open 服务器地址”.点击回车键.会提示你输入用户名和密码.登陆成功后.输入"cd"命令.会显示"远程目录”,输入"dir"命令会显示目录下的文件,权限等相关信息.可以通过"cd 文件名"命令进入到要下载的文件目录下.然后输入"ls"命令 显示文件夹下的所有文件.如图
输入"lcd 本地文件目录"(就是要下载到那个文件夹下 就输入那个目录,如果不输入就是默认c盘的当前系统用户目录下)输入"prompt"命令(打开交互模式,如果是打开的就不需要),最后输入"mget 服务其上要下载的文件名",回车键.这样就可以进行下载了.看到"Transfer complete"就表示下载成功了.到本地路径下就能看到下载的文件了.
Centos 7的开机菜单设置主要是能过 /etc/grub2.cfg ( /etc/grub2.cfg -> ../boot/grub2/grub.cfg)
timeout=5 为等待用户选择时间,当5秒钟没有选择,系统会启动默认的菜单
与centos 6不同的是centos 7在设置默认启动项时不能通过 default=? 来设置,而是通过以下命令:
若要列出系统开机时显示的所有选项,请执行以下指令:
[root@host ~]# awk -F\' '$1=="menuentry " {print i++ " : " $2}' /etc/grub2.cfg 0 : CentOS Linux 7 (Core), with Linux 3.10.0-229.14.1.el7.x86_64 1 : CentOS Linux 7 (Core), with Linux 3.10.0-229.4.2.el7.x86_64 2 : CentOS Linux 7 (Core), with Linux 3.10.0-229.el7.x86_64 3 : CentOS Linux 7 (Core), with Linux 0-rescue-605f01abef434fb98dd1309e774b72ba 查看当前默认启动项
# grub2-editenv list
设置默认启动项
在做单选框的时候,遇见了Error in v-on handler: "TypeError: Cannot read property ‘id’ of null"这个问题,找了一上午才找到,原来找的方法不对。图片是我报错的提示
最开始是全局找id,怎么着都不对,改好了才发现是直接从下面的地方找,
点击进入后可以打印所有的数据,当你操作后有的数据会出现null的时候,在进行判断就不会报错了。
之前提示
```
You must use Visual Studio to build a python extension on windows. If you are getting this error it means you have not installed Visual C++. Note that there are many flavors of Visual Studio, like Visual Studio for C# development. You need to install Visual Studio for C++.
```
于是就去官网装了VS2019。接着装cmake和boost
```
pip install cmake boost
```
装dlib的时候倒是成功了
```
Successfully built dlib
Installing collected packages: dlib
Successfully installed dlib-19.
Detours API 函数参考 The Table of Contents provides an alphabetical listing of the available API functions, which can be grouped as follows: 目录按字母顺序列出可用的API功能,可分为以下类别:
APIs For Detouring Target Functions 用于路由目标函数的api DetourTransactionBeginDetourUpdateThreadDetourAttachDetourAttachExDetourAllocateRegionWithinJumpBoundsDetourDetachDetourSetIgnoreTooSmallDetourSetRetainRegionsDetourSetSystemRegionLowerBoundDetourSetSystemRegionUpperBoundDetourTransactionAbortDetourTransactionCommitDetourTransactionCommitEx APIs For Finding Target Functions 用于查找目标函数的api DetourFindFunctionDetourCodeFromPointer APIs For Accessing Loaded Binaries and Payloads 用于访问已加载的二进制文件和有效负载的api DetourEnumerateModulesDetourGetEntryPointDetourGetModuleSizeDetourEnumerateExportsDetourEnumerateImportDetourEnumerateImportExDetourFindPayloadDetourFindPayloadExDetourFindRemotePayloadDetourGetContainingModuleDetourGetSizeOfPayloads APIs For Modifying Binaries 用于修改二进制文件的api DetourBinaryOpenDetourBinaryEnumeratePayloadsDetourBinaryFindPayloadDetourBinarySetPayloadDetourBinaryDeletePayloadDetourBinaryPurgePayloadsDetourBinaryEditImportsDetourBinaryResetImportsDetourBinaryWriteDetourBinaryClose APIs For Inserting DLLs and Payloads Into New Processes 用于将dll和有效负载插入新进程的api DetourCreateProcessWithDllExDetourCreateProcessWithDllsDetourCopyPayloadToProcessDetourCopyPayloadToProcessExDetourFinishHelperProcessDetourIsHelperProcessDetourRestoreAfterWith
使用Detours 为了达到拦截和截获绕过目标函数,有两件事是必要的:一个包含目标函数地址的目标指针和一个detour函数。为了正确拦截目标函数、detour函数和目标指针,必须具有完全相同的调用签名,包括参数数量和调用约定。使用相同的调用约定可以确保正确地保存寄存器,并确保在detour函数和目标函数之间正确地对齐堆栈
下面的代码片段说明了Detours库的用法。用户代码必须包含detours.h头文件并链接到detours.lib库。
#include <windows.h> #include <detours.h> static LONG dwSlept = 0; // Target pointer for the uninstrumented Sleep API. 静态长dwSlept =0; //未检测的Sleep API的目标指针。 // static VOID (WINAPI * TrueSleep)(DWORD dwMilliseconds) = Sleep; // Detour function that replaces the Sleep API. //用来替换Sleep API的Detour函数。 // VOID WINAPI TimedSleep(DWORD dwMilliseconds) { // Save the before and after times around calling the Sleep API. //保存调用Sleep API前后的次数。 DWORD dwBeg = GetTickCount(); TrueSleep(dwMilliseconds); DWORD dwEnd = GetTickCount(); InterlockedExchangeAdd(&dwSlept, dwEnd - dwBeg); //DllMain函数将TimedSleep绕道附加和分离到 } // DllMain function attaches and detaches the TimedSleep detour to the // Sleep target function.
前言 大家好,牧码心今天给大家推荐一篇数据结构与算法系列(四)—插入排序的文章,希望对你有所帮助。大纲如下:
插入排序基本介绍插入排序图文说明插入排序时空复杂度和稳定性插入排序具体实现 插入排序基本介绍 插入排序 是一种较简单的排序算法,排序过程类似于打扑克牌,将手中的牌进行排序,举个例子,比如我手中有黑桃6,7,9,10这四张牌,此时我又抓到了一张黑桃8,自然会在已经有序的四张牌中找到黑桃8应该插入的位置,也就是7和9之间,把黑桃8插入进去完成排序。其基本思想是:把n个待排序的元素看成为一个有序表和一个无序表。开始时有序表中只包含1个元素,无序表中包含有n-1个元素,排序过程中每次从无序表中取出第一个元素,将它插入到有序表中的适当位置,使之成为新的有序表,重复n-1次可完成排序过程。。
插入排序图文说明 下面以数列{20,40,30,10,60,50}为例,演示插入排序过程
排序流程说明: 给定无序数组{20,40,30,10,60,50},从小到排序,并把数组的首元素20作为有序区,此时有序区只有这一个元素: 第1趟:让元素30与有序区比较,20<30 ,无交换。此时有序去增加到2个元素:20,30第2趟:让元素40与有序区比较,30<40 ,无交换;20<40,无交换。此时有序去增加到3个元素:20,30,40第3趟:让元素10与有序区比较,40>10 ,交换;30>10,交换;20>10 交换。此时有序去增加到4个元素:10,20,30,40以此类推,插入排序一共会进行(数组长度-1)轮比较 插入排序时空复杂度和稳定性 时间复杂度空间复杂度稳定性O(n^2)O(1)稳定 说明 时间复杂度:假设被排序的数列中有N个数。遍历一趟的时间复杂度是O(N),需要遍历多少次呢?N-1!因此,直接插入排序的时间复杂度是O(N2)。;空间复杂度 :选择排序是原地排序,没有产生额外的空间,则为O(1) ; 插入排序实现 插入排序(java版) /** * @Author:greekw * @Desc: 插入排序:维护一个有序区,将元素一个一个插入到有序区适当的位置,直到所有元素有序。类比:玩扑克 * 时间复杂度:O(n^2) * 空间复杂度:O(1) * @Date 0:07 2020/7/22 * @Param [array] * @return void **/ public static void insertSort(int[] array){ for(int i = 1;i < array.length;i++){ // 将需要比较的元素放入暂存区 int insertValue = array[i]; int j = i-1; // 与前面i-1个元素进行比较 for (; j>=0 && insertValue < array[j]; j--) { array[j+1] = array[j]; } array[j+1] = insertValue; } } // 测试用例 public static void main(String[] args) { int[] selectArray= new int[]{20,40,30,10,60,50}; insertSort(selectArray); System.
http://laizhefa.com/layer/index.html
已经不是第一次出现这个问题了,去网上求助多是说环境变量的问题,改完之后发现keil闪退,又看到有人说没法生成.o文件就手动添加进去,但直觉告诉我这并是最正确的选择,查阅资料后发现问题出现有下面这几种情况。
一种错误原因是因为你的计算机用户名为中文导致的,这也就是环境变量的问题,但我运行例程没报错,说明我环境没有问题;
还有就是因为之前有安装过低版本的keil软件,卸载后没有删除注册表。这种时候,删掉就好了。
我的是因为新建工程时没注意,直接复制的例程,然后又手动添加文件,导致已经存在.o文件,这时候再进行编译,导致出现问题。因为预处理、编译、汇编、链接4个过程,缺一不可,.o文件在汇编阶段生成。若是已经存在,感觉就会触发那个报错,这里想提醒大家,注意新建工程不要像我一样 图省事,要一步一步来
文章目录 一.创建动画效果二.在css选择器中引用三.参数解释animation(调用动画以及参数的解释,与-webkit-animation通用)duration(动画执行的时间)timing-function(动画执行的速度)delay(动画延迟多久开始)iteration-count(动画执行的次数)direction(是否轮流播放) 四.题外话(一些css函数)1.缩放函数2.旋转函数3.倾斜函数 **今天又是咸鱼的一天!!!** 一.创建动画效果 css动画效果创建:
百分比(0%、100%)表示动画执行到该进度时运行的样式代码
@keyframes rotateAnimate1 { 0% { transform: rotateX(45deg) rotateZ(0deg); } 100% { transform: rotateX(45deg) rotateZ(360deg); } } @-webkit-keyframes rotateAnimate1 { 0% { transform: rotateY(45deg) rotateX(-45deg) rotateZ(0deg); } 100% { transform: rotateY(45deg) rotateX(-45deg) rotateZ(-360deg); } } 二.在css选择器中引用 代码如下(示例):
-webkit-animation: rotateAnimate1 2s infinite linear; animation: rotateAnimate1 2s infinite linear; rotateAnimate1 :上方自己编写的动画名称
2s:表示执行的时间(总时间)
infinite:这里是播放次数;(infinite表示播放无限次,也可以用数字进行代替,代表执行多少次)
linear:表示执行的速率;(这里linear表示全程匀速执行)
三.参数解释 这是官方给出的案例(自我解释一下)
animation: name duration timing-function delay iteration-count direction;
animation: (动画名称) (动画执行的时间)(动画执行的速度 )(动画延迟多长时间执行)(播放次数) (是否轮流播放) ;
2021.10.27
1、下列哪一个方法你认为是新线程开始执行的点,也就是从该点开始线性n被执行(B)
A public void start()
B pulic void run()
C public void int()
D public static void main(string srgs[])
E public void runnable()
线程:
2、下列关于容器集合类的说法正确的是(C)
A LinkedList 继承自List
B AbstractSet 继承自Set
C HashSet继承自AbstractSet
D weekMap继承自HashMap
集合
3、有关线程的叙述正确的是(CD)
A 可以获取对任何对象的互斥锁定
B 通过继承Thread类或实现Runable接口,可以获得对类中方法的互斥锁定
C 线程通过使用synchronized关键字可获得对象的互斥锁定
线程
D 线程调度算法是平台独立的
4、下列关于Java package的描述,哪个是正确的(B)
A 包不提供将所有类名分区为更易管理的块机制
B 包提供可见性控制机制
C 包的一个重要属性是包内定义的所有类都可以通过该包外的代码访问
D 什么为包的一部分的类的.class文件可以存储在多个目录中
包
管理java文件 类似于文件夹
5、下列程序最后的结果为(D)
A 10
B 0
C 19
D 编译出错
在计算机领域,如果是初入行就算了,如果是多年的老码农还不懂 CAP 定理,那就真的说不过去了。CAP可是每一名技术架构师都必须掌握的基础原则啊。
现在只要是稍微大一点的互联网项目都是采用 分布式 结构了,一个系统可能有多个节点组成,每个节点都可能需要维护一份数据。那么如何维护各个节点之间的状态,如何保障各个节点之间数据的同步问题就是大家急需关注的事情了。
CAP定理是分布式系统中最基础的原则。所以理解和掌握了CAP,对系统架构的设计至关重要。
一、什么是 CAP?
「 CAP定理 」又被称为 布鲁尔定理,它提出对于一个分布式系统而言,不能同时满足以下三点:
Consisteny(一致性)Availability(可用性)Partition tolerance(分区容错性) 也就是说CAP定理指明了,任何分布式系统只能同时满足这三项中的两项。
如上图,如果是最多同时满足两项,那我们可以有三个组合:CA、CP、AP。在聊这三个组合之前,我们先分别看一下 Consisteny(一致性)、Availability(可用性)、Partition tolerance(分区容错性)的含义。
假设某个系统当前有两个节点A和B,两个节点分别可以由Actor进行读写,两个节点之间的数据会自动完成同步。
Consisteny(一致性)
一致性的要求是指,对于任何客户端(上图Actor)来说,每次的读操作,都能获得最新的数据。即,当有客户端向A节点写入了新数据之后,其它客户端从B节点中进行读操作所获得的数据必须也是最新的,是与A节点数据保持一致的。Availability(可用性)
可用性的要求是指,每个请求都能在合理的时间内获得符合预期的响应(不保证获取的结果是最新的数据)。
按照上图来看就是,客户端只要向A节点或B节点发起请求后,只要这两个节点收到了请求,就必须响应给客户端,但不需要保证响应的值是否正确。Partition tolerance(分区容错性)
分区容错性是指,当节点之间的网络出现问题之后,系统依然能正常提供服务。 讲完了C、A、P的含义和要求,我们继续来看看它们之间如何组合使用。
二、CAP 怎么应用?
先把视野回到这张图上:
虽然我们知道有 CA、CP、AP 三种组合方式,但是在分布式系统的结构下,网络是不可能做到100%可靠的。既然网络不能保证绝对可靠,那 P(分区容错性)就是一个必选项了。原因如下:
如果选择 CA组合,放弃 P(分区容错性)。还是以最上面的图中A和B节点来举例,当发生节点间网络故障时,为了保证 C(一致性),那么就必须将系统锁住,不允许任何写入操作,否者就会出现节点之间数据不一致了。但是锁住了系统,就意味着当有写请求进来的时候,系统是不可用的,这一点又违背了 A(可用性)原则。
因此分布式系统理论上是不可能有CA组合的,所以我们只能选择 CP 和 AP组合架构。
下面我们来详细看一下 CP架构 和 AP架构的特点:
CP 架构
CP架构即 Consisteny(一致性)与 Partition tolerance(分区容错性)的组合。 如上图,由于网络问题,节点A和节点B之前不能互相通讯。当有客户端(上图Actor)向节点A进行写入请求时(准备写入Message 2),节点A会不接收写入操作,导致写入失败,这样就保证了节点A和节点B的数据一致性,即保证了Consisteny(一致性)。
然后,如果有另一个客户端(上图另一个Actor)向B节点进行读请求的时候,B请求返回的是网络故障之前所保存的信息(Message 1),并且这个信息是与节点A一致的,是整个系统最后一次成功写入的信息,是能正常提供服务的,即保证了Partition tolerance(分区容错性)。
上述情况就是保障了CP架构,但放弃了Availability(可用性)的方案。
AP 架构
AP架构即 Availability(可用性)与 Partition tolerance(分区容错性)的组合架构。 如上图,由于网络问题,节点A和节点B之前不能互相通讯。当有客户端(上图Actor)向节点A进行写入请求时(准备写入Message 2),节点A允许写入,请求操作成功。但此时,由于A和B节点之前无法通讯,所以B节点的数据还是旧的(Message 1)。手机游戏当有客户端向B节点发起读请求时候,读到的数据是旧数据,与在A节点读到的数据不一致。但由于系统能照常提供服务,所以满足了Availability(可用性)要求。
因此,这种情况下,就是保障了AP架构,但其放弃了 Consisteny(一致性)。
在计算机网络中,路由器的一个很重要责任就是要在端对端的节点中找出一条最佳路径出来,通过自己与相邻节点之间的信息,来计算出从自己位置到目的节点之间的最佳线路,这种算法我们可以理解为路由算法。
路由的模式又主要分为「静态路由」和「动态路由」。静态路由协议是由网络管理员手动输入配置的,适用于小型的不太复杂的网络环境中,或者有特定需求的网络场景中。而动态路由协议是现代计算机网络中最为常用的一种方式。动态路由算法能够根据网络拓扑结构去适应流量的变化。
本文主要聊的就是「动态路由算法」,你知道动态路由算法有哪些吗?
动态路由算法大致可以分为两类:
距离矢量路由算法链路状态路由算法 下面我们来看一下这两类算法的特点:
一、距离矢量路由算法 距离矢量路由算法(Distance Vector Routing),它是网络上最早使用的动态路由算法,也称为Bellman-Ford或者Ford-Fulkerson算法。基于这类算法实现的协议有:RIP、BGP等。
如图,
这类算法的基本思路是:网络中每一个路由器都要维护一张 矢量表 ,这个 矢量表 中的每一行都记录了从当前位置能到达的目标路由器的最佳出口(接口)和距离(跳数)。
每隔一段时间当前路由器会向所有的邻居节点发送自己的这个表,同时它也会接收每个邻居发来的它们的表。并会将邻居的表和自己的表做一个对比更新。
比如当前 路由器X 离 邻居Y路由器 的距离是m,此时收到 邻居Y 发来的表中写到了“ 邻居Y离路由器Z的距离是n ”,那 当前路由器X 就知道它离 路由器Z 的距离可能就是 m+n 了,如图:
就这样继续类推,要不了多久,每个路由器就可以将网络中所有路由节点和子网线路都汇聚起来了。这样的话,每个路由器只需要查找自己的表就可以很容易的知道到达目的地的最佳出口(接口)是哪个了。
当然,当网络结构发生变化的时候,各个路由器中的矢量表也会随之动态更新。
好了,讲到这里,基本上对「距离矢量路由算法」大概原理有个认识了,现在我们再来仔细分析分析这个算法的名字,可以发现,它的名字取的还是蛮有意思的,非常贴切。“距离”这个词就基本表明了这个算法是通过 距离(跳数/时间)来度量2个路由网络之间的线路的,而“矢量”这个词,可以看出线路是有方向性的,且路由表中只记录了数据包去往目的地应该走哪个出口方向,并不会记录到达目的地的整条路径。
「距离矢量路由算法」的优点很明显:非常简单清晰,且任何加入到网络中的新节点都能很快的与其它节点建立起联系获得补充信息。
缺点呢,首先就是每次发送信息的时候,要发送整个全局路由表,太大了,因为每个路由器需要在矢量表中记录下整个网络的信息,导致需要较大存储、CPU、网络开销,对资源的要求越来越高。还有一个问题就是收敛时间太慢,手游账号买号也就是路由器共享路由信息并使各台路由器掌握的网络情况达到一致所需的时间比较久,收敛速度慢会导致有些路由器的表更新慢,从而造成路由环路的问题。
二、链路状态路由算法 链路状态路由算法(Link State Routing ),基于Dijkstra算法,它是以图论作为理论基础,用图来表示网络拓扑结构,用图论中的最短路径算法来计算网络间的最佳路由。基于这类算法实现的协议有:OSPF 等。
如图,
这类算法的基本思路是:采用的是不停的拼接地图的方式。每一个路由器首先都会发现自己身边的邻居节点,然后将自己与邻居节点之间的链路状态包广播出去,发送到整个网络。这样,当某个路由器收到从网络中其它路由器广播来的路由信息包(链路状态包)之后,会将这个包中的信息与自己路由器上的信息进行拼装,最终形成一个全网的拓扑视图。
当路由器中形成了全网的拓扑视图后,它就可以通过最短路径算法来计算当前节点到其它路由器之间的最短路径了。当某台路由器的链路状态发生变化时,路由器采用洪泛法向所有路由器发送此信息,其它路由器使用收到的信息重新计算最佳路径,重新生成路由表(拓扑图)。
这里可以做一个类比,有一个路人甲人去问路,然后本地人A只知道A自己生活方圆5公里的地图,本地人B只知道B自己生活的方圆5公里的地图,但是路人甲要去的地方需要穿过A和B所在区域,那么就把A和B的2份地图拿来拼装在一起,然后去往目的地的完整路线就可以查出来了。
链路状态路由算法简单而言就是五个步骤:
发现邻居节点,并了解邻居网络地址测量到邻居节点的距离或成本度量值构建一个包含自己所拥有信息的链路状态包将这个包广播到网络中,并接收其它路由器的链路状态包计算出当前节点到其它节点之间的最短路径(基于Dijkstra算法) 链路状态路由算法 不会像 距离矢量路由算法 那样发送整个路由表,链路状态路由协议只会广播更新的或者改变了的网络拓扑,这样传播的信息量会少很多,同时对带宽和CPU资源也是一种节省。
「链路状态路由算法」具有很好的扩展能力,也具有更快的收敛速度,能够快速的适应网络变化,且由于一个路由器的链路状态只涉及与其相邻的路由器的联通状态,因而与整个互联网的规模并无直接关系,因此链路状态路由算法可以用于大型的或者路由信息变化剧烈的互联网环境。
将上述两种算法做一个简单的对比:
图片来源网络,经供参考。
以上,就是对计算机网络中的动态路由算法的基本讲解了,欢迎大家一起交流。
项目场景: 提示:Hadoop部署到k8s,需要在各个节点之间共享,而且各个节点都需要能编辑文件内容,所以需要支持ReadWriteMany的PersistentVolume,这里我选择使用NFS
使用NSF来存放配置文件,hadoop-config-nfs-pvc将挂载到所有的Hadoop集群中的POD中
问题描述: 创建动态pvc失败
External provisioner is provisioning volume for claim "hadoop/hadoop-config-nfs-pvc" Warning ProvisioningFailed 100s (x6 over 9m25s) cluster.local/nfs-client-provisioner_nfs-client-provisioner-68b846887c-7bvjw_0a464304-cd77-11eb-9000-8e6640c99276 failed to provision volume with StorageClass "nfs-client": unable to create directory to provision new pv: mkdir /persistentvolumes/hadoop-hadoop-config-nfs-pvc-pvc-ab7453e4-3d32-4ea1-8f75-71b6c1dab592: read-only file system 原因分析: 主要是以下报错:
mkdir /persistentvolumes/hadoop-hadoop-config-nfs-pvc-pvc-ab7453e4-3d32-4ea1-8f75-71b6c1dab592: read-only file system
1、查看nfs挂载 :showmount -e
Export list for k8s-master01: /nfs * 没有/persistentvolumes/
2、vim etc/exports加上挂载
3、在另一台机器上验证挂载并创建文件夹成功
mount -t nfs 192.168.2.167:/persistentvolumes /pers
mkdir aaa
4、重新创建pvc ,这时候还是报一样的错误。排查了很久。
一、Spring-AOP的作用 在实际开发中,我们往往会遇到对已有功能做扩展的情况,我们需要在不对源码进行修改的情况下扩展功能,在没有spring-aop的情况下我们应该这么做:
情景1:我们现在要对AServiceImpl(实现了AService接口)中的login方法进行扩展,这种情形我们可以使用代理模式来做,过程如下:创建一个BServiceImpl类并实现AService接口,并重现doLogin方法。
class BServiceImpl implements AService{ private AService trueObj; BServiceImpl(AService service){ trueObj = service; } @override public void doLogin(){ sout("扩展前"); trueObj.doLogin(); sout("扩展后"); } } 而AOP的出现就可以省略BServiceImpl的创建,我们指定一个类的方法为切点,然后我们需要对这个切点进行扩展,扩展又分为扩展前、扩展后、环绕、和异常等部分,我们可以对其进行声明然后指向切点。
id为before的bean是前置通知,在真实方法(doLogin)执行前执行,id为after的bean是后置通知在真实方法执行后执行
代码如下
<bean id="before" class="com.codeXie.MyBefore"></bean> <bean id="after" class="com.codeXie.MyBefore"></bean> <aop:config> <aop:pointcut id="lg" expression="execution(* com.codeXie.service.Impl.AServiceImpl.doLogin(..))"/> <aop:advisor advice-ref="before" pointcut-ref="lg"></aop:advisor> <aop:advisor advice-ref="after" pointcut-ref="lg"></aop:advisor> </aop:config> 二、spring-aop的专业概念 真实对象:要进行功能扩展的对象,相当于AServicImpl对象
代理对象:完成功能扩展的对象,相当于BServiceImpl对象
在spring-aop中,代理对象是动态创建的
切点:要进行功能扩展的方法,相当于doLogin方法
前置通知方法:在切点执行之前就执行的扩展方法
后置通知方法:在切点执行后才执行的扩展方法
切面:有前置通知+切点+后置通知形成的横向切面
织入:形成切面的过程
AOP:面相切面编程
三、spring-aop的SchemaBase方法详解 一、 前置通知 使用:
声明一个普通Java类,实现BeforeAdvice接口。在Spring配置文件中配置前置通知的bean对象配置组装 方法:
方法名:before调用者:代理对象中的扩展方法调用方法体:声明切点之前执行的扩展代码 参数:
Method method:切点的方法对象Object[] objects:代理方法接收的实参的数组Object o:真实对象 public class LoginBefore implements MethodBeforeAdvice { @Override public void before(Method method, Object[] objects, Object o) throws Throwable { System.
**环境:**Windows Server系统使用的docke。
**目的:**将docker容器里面的目录挂载到Windows目录下,以便于管理。
**挂载流程:**Windows目录——挂载——>docker虚拟机目录——挂载——>docker容器内部目录
1、打开Oracle VM VirtualBox管理器,虚拟机——设置。
2、在设置——共享文件夹——添加共享文件。
3、选择要挂载到虚拟机里的Windows文件夹。
4、进入虚拟机,这里显示还不是root用户(需要切换权限)
输入:sudo -i切换到root账户。
5、输入:sudo mount -t vboxsf docker /mnt/docker进行挂载。
注释:这里的docker目录,就是刚刚在虚拟机管理器里设置要共享的Windows目录的名称
6、然后在虚拟机的/mnt/docker/目录下就可以看到Windows的D://docker目录的文件了。(说明挂载成功了!!)
<!--解决idea提示springboot配置注解处理器(@ConfigurationProperties)没有找到--> <!--导入配置文件处理器,配置文件进行绑定就会有提示,需要重启--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency>
目录
shell条件判断语句
if分支结构
case语句
echo语句
日期
date命令
日历cal
循环语句
循环含义
for循环
for循环从1加到100
while和until
while从1加到100的和
until 总结
shell条件判断语句 if分支结构 单分支语法结构
单分支:
if 判断条件;
then 条件为真的分支代码
fi
判断主机的的连通性,$?=0,则网络通顺,否则不通
#!/bin/bash ping -c 3 192.168.37.1 &>/dev/null if [ $? = 0 ] then echo "And the real network smooth" return 1 fi echo "The network is not smooth with the real machine" 运行结果,网络不通顺
[root@xiaobin /data]# bash test2.sh The network is not smooth with the real machine 双分支语法结构 双分支
指针就是地址。
指针变量:是个变量,用来存放一个地址编号。(32位下,指针变量是4个字节)
对应类型的指针变量,只能存放对应类型的变量的地址。
扩展:char ch; ch占一个字节,它有一个地址编号,这个地址编号就是ch的地址。
int a; a占4个字节,它占有4个字节的储存单元,有4个地址编号。
指针的定义:
数据类型 * 指针变量名;
int *p; (*用来修饰变量的,说明p是个指针变量)。
关于指针的运算符
&:取地址(获取变量的地址)。*:取值(在定义指针变量时起标识作用,除此之外表示获取一个指针变量保存的地址里面的内容)。
代码1:
#include <stdio.h> int main(int argc,char *argv[]) { int a = 100; int* p; p = &a; printf("a=%d\n", a); printf("*p=%d\n", *p); printf("&a=%d\n", &a); printf("p=%d\n", p); system("pause"); return 0; } 结果:
a=100 *p=100 &a=1898480 p=1898480 扩展:如果在一行中定义了多个指针变量,每个指针变量前面都需要加*来修饰。
int *p,*q;说明定义了两个指针。
int *p,q;说明只定义了一个指针。
指针和变量的关系:
int p;
int a;
p=&a;
就可得到p与a是一样的,改变其中任意一个的值,另一个也会跟着改变。
注:1.指针变量可以在定义的时候初始化
int a;
int *p=&a;
看到这个bug,检查你的redis基本配置。 前几天遇到了这个bug,很崩溃…
找了半天是服务器的redis崩了,
换成自己的redis
它就可以正常跑了…
就很emo…
- Application run failed org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'keyExpiredListener' defined in file : Invocation of init method failed; nested exception is org.springframework.data.redis.RedisConnectionFailureException: Unable to connect to Redis; nested exception is io.lettuce.core.RedisConnectionException: Unable to connect to 49.235.202.61:6379 at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1778) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:593) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515) at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320) at org.springframework.beans.factory.support.AbstractBeanFactory$$Lambda$129/1609116238.getObject(Unknown Source) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:845) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:877) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549) at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140) at org.
文章目录 1.验证方法学概述1.1验证情况概述1.2 SV1.3 UVM 2 类库地图2.1类库地图概述2.2 UVM核心类(10个)2.3 UVM类库地图 3 工厂机制3.1工厂机制是软件的一种典型设计模式;3.2工厂机制意义3.3 uvm_component和uvm_object3.4 uvm_coreservicr_t类 4 覆盖方法4.1override概述4.2 set_type_override()4.3 set_inst_override()4.4 覆盖实例4.5 确保正确覆盖的代码要求 修改日志 1.验证方法学概述 1.1验证情况概述 验证结构的复用和代码的复用很难;原有HDL缺乏随机约束和功能覆盖率;EDA公司开发出平台限定性语言 Specman/e和Vera; 1.2 SV 从2002年的SV3.0标准逐步发展成为IEEE-1800 SV2017标准;SV的核心是面向对象、随机约束、线程通信、功能覆盖率收集等; 1.3 UVM UVM1.0在2011年发布,目前用的是UVM1.2;UVM在eRM、AVM、OVM的基础上发展的;所有验证方法学的目的都在于提供一些可重用的类,减轻项目之间水平复用和垂直复用的工作量;UVM提供了一套可靠的验证框架;面向所有的数字设计,从模块级到芯片级、从ASIC到FPGA;UVM自定义的框架构建类和测试类能够帮助验证人员减轻环境构建的负担,将更多的精力集中在制订验证计划和创建测试场景; 2 类库地图 2.1类库地图概述 在SV中,验证环境整体的构建是从底层模块的验证组件搭建到通信和测试激励生成;这些元素无论是软件对象的创建、访问、修改、配置,还是组件之间的通信等都是通过用户自定义的方式来实现的;UVM将验证过程中可以重用和标准化的部分都规定在其方法学的类库中,通过标准化的方式减轻构建环境的负担;验证环境的共同需求是:1、组件的创建和访问 2、环境的结构创建、组件之间的连接和运行 3、不同阶段的顺序安排 4、激励的生成、传递和控制 5、测试的报告机制;在组件通信中,UVM提供了功能丰富的TLM(transaction level model)接口,从而保证相邻组件的通信不再通过显式句柄引用,而是独立于组件的通信方式;对于测试序列sequence的生成和传输也是利用TLM传输在sequence和driver之间完成;UVM的报告机制可以将来自于不同组件、不同级别的信息并且加以过滤,最终生成测试报告; 2.2 UVM核心类(10个) 2.3 UVM类库地图 3 工厂机制 3.1工厂机制是软件的一种典型设计模式; 3.2工厂机制意义 factory存在的目的是更方便地替换验证环境中的实例或者注册了的类型,同时工厂的注册机制也带来了配置的灵活性;实例或者类型替换,在UVM中称作覆盖(override);UVM验证环境由两部分构成,一部分是uvm_component类,构成了环境的层次,另一部分是uvm_object类,构成了环境的属性和数据传输;(uvm_component继承自uvm_object);factory的目的是用来创建对象,在创建对象之前要先进行类型注册;工厂注册的类型有两种,一个是uvm_component,另一个是uvm_object; 3.3 uvm_component和uvm_object factory三个步骤:定义、注册、创建;
创建uvm_component
//创建uvm_component class comp1 extends uvm_component;//定义 `uvm_component_utils(comp1) //注册 function new(string name = "comp1", uvm_component parent=null); //上一层是parent super.new(name, parent); //继承父类 $display($sformatf("
node_modules_gulp-imagemin@8.0.0@gulp-imagemin\index.js:1
(function (exports, require, module, __filename, __dirname) { import {createRequire} from ‘node:module’;
https://www.npmjs.com/package/gulp-imagemin,查看gulp-imagemin历史版本号
gulp-imagemin 引入报错,uninstall原来的,或直接删掉,降低版本号试试,原gulp-imagemin 版本8.0.0,降到7.1.0解决
@Transactional放在controller中无法回滚的问题 如下代码:
调用该接口,预期的结果是会报异常并且添加操作进行回滚。但是结果却是事务没有回滚,数据正常加入数据库中。
原因分析:(个人理解,不晓得对不对)
因为spring的context和mvc是分开的,spring的是父容器,springMVC是子容器。子容器可以取到父容器中的bean,而父容器不能取到子容器中的bean。大致如下:
因为事务是由spring管理的,而controller是由springMVC来管理的。在springmvc扫描controller的时候,无法识别@Transactional注解,所以无法生效。
所以放在Service中就能生效:spring扫描@Service的时候可以识别到@Transactional注解。
下载压缩包
使用xftp上传到/usr/local目录下
解压–删除–重命名
cd /usr/local tar -xvf mysql-8.0.26-linux-glibc2.12-x86_64.tar.xz rm -rf mysql-8.0.26-linux-glibc2.12-x86_64.tar.xz mv mysql-8.0.26-linux-glibc2.12-x86_64 mysql 在 /usr/local/ 目录下,有个mysql文件夹,然后开始mysql用户组和mysql用户,添加完使用groups mysql查看是否添加成功 groupadd mysql useradd -r -g mysql mysql groups mysql 修改mysql目录拥有者为刚建立的mysql用户 [root@freely local]# cd mysql/ [root@freely mysql]# chown -R mysql:mysql ./ 初始化 /usr/local/mysql/bin/mysqld --initialize --user=mysql --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data 注意记下临时生成的数据库密码,我这里为’&k0m=inJgNC.’
这个版本默认是没有my.cnf配置文件的,mysql在启动时没有指定配置文件时会使用/etc/my.cnf配置文件。
但是,没有配置文件并不影响启动和安装。
启动mysql ./support-files/mysql.server start 若报错
Starting MySQL.2021-10-27T08:48:49.191961Z mysqld_safe error: log-error set to ‘/var/log/mariadb/mariadb.log’, however file don’t exists. Create writable for user ‘mysql’.
ERROR! The server quit without updating PID file (/var/lib/mysql/localhost.
文章目录 1. 安装插件2. 调整任务栏(Dash)3. 美化系统主题(1)应用主题(GTK3/4 Themes)(2)图标主题(Full Icon Themes)(3)登录界面(GDM Themes)(4)开机动画(Plymouth Themes)(5)系统选择界面(GRUB Themes) 1. 安装插件 参考:https://blog.csdn.net/m0_37407587/article/details/87911749
apt install gnome-tweak-tool apt install gnome-shell-extensions 打开软件GNOME Tweak(中文名为“优化”):
如果shell那里显示感叹号,无法设置主题,如下图:
则用以下方法解决:
使用火狐浏览器访问 https://extensions.gnome.org
网页提示需要完成安装浏览器插件和本地应用两步, 直接点click here to install brower extension安装浏览器插件。
终端通过以下命令安装软件
apt install chrome-gnome-shell 安装后打开 https://extensions.gnome.org/extension/19/user-themes/
这时候已经多了一个按钮,不用选择版本,直接点按钮,稍等之后有一个弹窗提示是否安装,点安装。
关闭tweak-tool再打开,感叹号已经没有了。
2. 调整任务栏(Dash) 选择底部(或者左侧,看你喜好),并且取消面板模式(看你喜好)
3. 美化系统主题 https://www.opendesktop.org/s/Gnome 在这个网站里找自己喜欢的各类主题。
(1)应用主题(GTK3/4 Themes) 评分排名最高的GTK 3/4 Themes是这个主题:https://www.opendesktop.org/s/Gnome/p/1357889。
选择这个主题,名字叫Orchis,还有其他的一些微调版本,如Orchis-light、Orchis-light-compact。
下载解压,将对应文件移动到/usr/share/themes
然后在“优化”中设置主题(应用程序和shell):
(2)图标主题(Full Icon Themes) 我选择的是这个主题:https://www.pling.com/p/1279924
下载解压,将对应文件移动到/usr/share/icons
然后在“优化”中设置图标:
(3)登录界面(GDM Themes) GDM,即GNOME Display Manager(GNOME显示管理器)。
开机动画之后就是登录界面(锁屏解锁后的登录界面也是这个样式)。
文件位置在/usr/share/gnome-shell/theme/ubuntu.css,背景在/usr/share/backgrounds。
题目:
5. 使用 字符流和和GUI类 编程实现以下功能:
(1)设计图形化界面,至少包括文本类控件类。接收从键盘输入姓名、学号、成绩,并保存到文本文件中,重复进行。(2)从文件中读取各学生的成绩,并计算所有学生成绩的平均值、最大值和最小值,排序后输出到另一文本文件。
插件选用了Eclipse的windowbuilder,所以代码看起来好多,但大部分都是自动化生成的
文件的输入输出选用了RandomAccessFile类,详细教程:
https://blog.csdn.net/akon_vm/article/details/7429245
参考代码:
package scoreframe1; import java.text.SimpleDateFormat; import javax.swing.*; import java.awt.*; import java.util.*; import java.util.List; import java.util.stream.Collectors; import javax.swing.Timer; import java.io.*; public class Student1{//一定是ApplicationWindow!!! private static JFrame frame; private static JTextField textField,textField_1; public static JTextField textField_2; private static RandomAccessFile random1; private static File file1; public static int result1,average1; private static JLabel lblNewLabel_4;/**Launch the application.*/ public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { public void run(){ try{Student1 window = new Student1(); window.
RS485只有两根数据线,只能实现半双工传输
系统框图
1.按键模块
module key_debounce( //按键消抖 input sys_clk, //外部50M时钟 input sys_rst_n, //外部复位信号,低有效 input [3:0] key, //外部按键输入 output reg key_flag, //按键数据有效信号 output reg [3:0] key_value //按键消抖后的数据 ); //reg define reg [31:0] delay_cnt; //按键消抖计数器 reg [ 3:0] key_reg; //按键值寄存器 //***************************************************** //** main code //***************************************************** /*******按键消抖*******************/ always @(posedge sys_clk or negedge sys_rst_n) begin if (!sys_rst_n) begin key_reg <= 4'b1111; delay_cnt <= 32'd0; end else begin key_reg <= key; if(key_reg != key) //一旦检测到按键状态发生变化(有按键被按下或释放) delay_cnt <= 32'd1000000; //给延时计数器重新装载初始值(计数时间为20ms) else if(key_reg == key) begin //在按键状态稳定时,计数器递减,开始20ms倒计时 if(delay_cnt > 32'd0) delay_cnt <= delay_cnt - 1'b1; else delay_cnt <= delay_cnt; end end end /**************得到按键值*******************/ always @(posedge sys_clk or negedge sys_rst_n) begin if (!
最近有个项目需要实现和windows桌面类似的图标拖拽功能,找了很多组件都没找到一个合适的,但通过本博主的不懈努力最后发现了两款不错的插件:
sortablejsvue-grid-layout
本来一开始我使用的是第一个,但是可能是有点转不过来,最终放弃了第一个插件,但是第二个也确实香,虽然也有不少bug但是也不是不能解决的,下面就回到正题上来给大家粗略说一下: 先上代码吧,怕大家等不及往下拉:
<template> <div> <grid-layout :layout.sync="layout" :col-num="8" :row-height="100" :is-draggable="true" :is-resizable="false" :vertical-compact="false" :margin="[20, 24]" :use-css-transforms="true"> <grid-item v-for="(item,index) in layout" :key="index" :item="watchitem(item)" :static="item.static" :x="item.x" :y="item.y" :w="item.w" :h="item.h" :i="item.i" @move="moveEvent" @moved="movedEvent" > <span class="text">{{item.i}}</span> </grid-item> </grid-layout> </div> </template> <script> var historyLayout = [ {"x":0,"y":0,"w":1,"h":1,"i":"0", static: false}, {"x":1,"y":0,"w":1,"h":1,"i":"1", static: false}, {"x":2,"y":0,"w":1,"h":1,"i":"2", static: false}, {"x":3,"y":0,"w":1,"h":1,"i":"3", static: false}, {"x":4,"y":0,"w":1,"h":1,"i":"4", static: false}, {"x":5,"y":0,"w":1,"h":1,"i":"5", static: false}, {"x":6,"y":0,"w":1,"h":1,"i":"6", static: false}, {"x":7,"y":0,"w":1,"h":1,"i":"7", static: false}, {"x":0,"y":1,"w":1,"h":1,"i":"8", static: false}, {"
作为一个自媒体从业人员,经常少不了发文来分享个人经验、传授专业知识。既然要发文肯定少不了插图,插图辅助理解、增强文章阅读性。提到插图基本有俩个来源,一是自己创作或者自己拍摄的原始照片,还有就是从网上搜罗比较接近主题的照片。但无论是哪种来源,我们的图片一般都需要经过修剪才会显得更美观、更突出主题。
所以说修图是自媒体人员必不可少的技能。修图可以用本地修图软件像PS、美图秀秀等,也可以在线直接修图,即改即用。
对于自媒体人员来说,大多都不是专业的设计人员出身,不具备专业的PS修图技能,这时更优的选择便是网上快捷修图,不需要很专业的修图功底就可以快速完成图片处理。在线修图显然容易使用、非常适合随改随用的快消习惯。
在线修图工具有很多,比如 稿定设计、老馒头修图等。
一个高效的作业人员,一定是有高效的工具辅助。对于自媒体人员来说,收藏一两个顺手的修图工具很有必要,就像一个设计人员一定会有属于自己偏好的素材网站,以备不时之需。
目录 前言GPIO是什么GPIO的八大模式输入模式浮空输入上拉输入下拉输入模拟输入 输出模式开漏输出推挽输出复用开漏输出复用推挽输出 GPIO的输出速率 前言 学习了这么久的单片机,说来羞愧,直到写这篇文章之前,我都没有仔细去理解GPIO的八种使用模式,之前只是傻傻的用着,直到把模电,数电学完,到今天重新回顾了一遍这一个知识,发现自己终于看懂了之前没有理解透彻的知识,特此总结下来。
GPIO是什么 从最基础的51单片机,Arduino,到STM32,树莓派等等,这些上面都会有GPIO口这么一个概念,如果你点开了我这个博客,说明你大概率开始学习单片机,那么你应该了解的就是这些口可以输出高低电平,或者是读取引脚上的输入电平。
GPIO的总述功能如下
GPIO(general porpose intputoutput):通用输入输出端口的简称。可以通过软件控制其输出和输入。stm32芯片的GPIO引脚与外部设备连接起来,从而实现与外部通信,控制以及数据采集的功能。
———GPIO简介
下面摆一张以STM32内部GPIO口为例的内部原理图,大伙也不要着急,先有一个这个图的概念,下面就是开始讲怎么理解GPIO口。
先来一点最基础的知识
上拉和下拉:
当我们闭合上拉电阻的开关,断开下拉电阻的开关的时候,也就是此时为上拉通路导通。根据我们最基础的电路知识,如果I/O口断开不接外设,或者接了外设但是电路也断开,此时整条回路是断路的时候,电阻相当于不存在,此时O点的电位,也就被钳制在了VDD(供电电压正极),于是O点就处于高电平。
同理,闭合上拉电阻的开关,断开下拉电阻的开关,那么在电路断开的时候,根据电路知识,电阻相当于不存在,O点的电压就就被钳制**在了VSS(GND),也就是O点处于低电平。
数字信号和模拟信号:
数字信号:就是根据一些规则,将一个范围内的电压规定为1,一个范围内的电压规定为0,也就是一连串的0,1信号
模拟信号:就是连续的读取到的电压值。
关于图上的TTL施密特触发器和P-MOS和N-MOS,后面讲到对应部分的时候会讲到。
GPIO的八大模式 GPIO可以分为输入或者输出,加起来一共有八种模式。
输入模式 在输入模式下,一共有四种输出模式,分别是
模拟输入上拉输入下拉输入浮空输入 浮空输入 浮空输入需要走的路径如图所示。首先得知道,浮空输出走的这一条路径,是对一个数字信号的读取。
需要的电路如下:
VDD和VSS所在路径的两个开关同时断开。此时没有上拉和下拉的情况,所以当IO口没有接输入的时候,此时的电平会是一个不确定的值,也就是我们所说的浮空。电平会处于一个跳变的状态,一会高,一会低。只有输入了一个高/低电平才会确定下来。
注意: 上拉和下拉电阻电路的开关在实际应用中一般使用MOS管来代替开关来提到。
再往前面走,就是走到了TTL施密特触发器这一个部分。我们知道,由于电源的特性,或者是由于外部开关输入的特性,输入的数字信号,极有可能会出现脉冲等噪声的影响,为了让我们的波形更好看,或者信号更加清晰,所以就设置了TTL施密特触发器这个东西。经过之后,我们就会把这个数字信息存储在输入数据寄存器中。
这样我们就读到了IO过来的数字信号
优势: 这一种输入模式的电平会完全取决于外部电路而与内部电路无关。有时候会用作对开关按键的读取。
但是在没有外部电路接入的时候,IO脚浮空会使得电平不确定
上拉输入 上拉输入需要走的路径如图所示。首先得知道,上拉输出走的这一条路径,是对一个数字信号的读取。
需要的电路如下:
VDD所在上拉电阻开关闭合,下拉电阻的开关断开。
根据前面浮空输入里面所提的,在没有信号输入的时候,根据电路知识,此时的电平就是VDD的电平,此时读取到的电平就是高电平。如果输入了一个高电平,VDD和O点(最上面的图中的O点)之间就几乎没有电势差,此时O点的电平就仍然是高电平,读取到的电平就是高电平。但是由于在没有电压输入的时候,电平也是高电平,所以这一种输入情况下是没有办法确定信号是否输入了。
当输入信号是一个低电平的时候,此时O点的电平的电平就会变成低电平,那么VDD和O点之间形成了电势差,但是因为上拉电阻的存在,所以不会出现一个大电流。此时单片机读取到的一个电平就是一个低电平。在上拉输入的情况下,低电平的是能够非常明显的读取到的。
上拉输入的好处就是输入的电平不会上下浮动而导致输入信号不稳定,在没有信号输入的情况下可以稳定在高电平。
下拉输入 下拉输入需要走的路径如图所示。首先得知道,下拉输出走的这一条路径,是对一个数字信号的读取。
需要的电路如下:
VDD所在上拉电阻开关断开,下拉电阻的开关闭合。
根据前面浮空输入里面所提的,在没有信号输入的时候,根据电路知识,电平就是VSS的电平,此时读取到的电平就是低电平。此时输入的电平如果是一个低电平,就没有办法和之前的情况进行区分。但如果输入的是一个高电平,O点和VSS之间同样形成了电势差,O点的电平会变成外部的高电平,那么单片机得到的就是一个高电平信号。
下拉输入的好处就是输入的电平不会上下浮动而导致输入信号不稳定,在没有信号输入的情况下可以稳定在低电平。
模拟输入 模拟输入需要走的路径如图所示。首先得知道,模拟输出走的这一条路径,是我们需要对一个模拟信号进行读取。
在我们使用单片机的时候,我们有时候需要用AD采集到IO口上面的真实电压。这就有了我们所需要的模拟输入。为了让外部的电压真实的读取到单片机的AD模块,我们既不能闭合上拉和下拉的开关,也不能让信号经过施密特触发器。
优势:可以让AD读取电压。还可以在低功耗模式下运行,实现省电的作用。
输出模式 在输出模式下,同样也有四种输出模式,分别是
开漏输出
推挽输出
复用开漏输出
复用推挽输出
开漏输出 ④⑤⑥⑦是读取的过程,此处不管。
开漏输出的电路路径是①②③④,②前面的步骤就是一个对输出信号的控制,不是重点,开漏输出里面最重要的是③,也就是N-MOS这一部分,下面来补充一下模电知识。
我们可以把这一个MOS管当成一个三极管,对于图中所示的这种三极管我们可以简单的理解成一个水龙头,左侧就是一个水龙头开关,当给一个高电平的时候, O点和GND就会导通。(O点的输出就是一种反向器的输出,也就是O点的电平会和左侧MOS的栅极(三极管的基极)相反)
所以说,开漏输出就很好理解了。当我们给一个低电平的时候,MOS管关闭,此时输出的电压就是一个浮空,即不确定的电压。如果给一个高电平,那么MOS管导通,相当于IO口与VSS相连,此处就输出了一个低电平电压。
优势①
虽然我们可以看到开漏输出是没有办法在内部输出一个高电平,但是这一个看似是缺点。其实实际上是一种优点。我们可以得到,当给一个低电平的时候,MOS管没有导通,此时电压不确定导致无法输出高电平,但是一旦我们在外部增加一个上拉,那么这一个缺点就会被有效避免。并且,因为是我们自己设计一个上拉,这个上拉的电压是由我们自己确定,这样我们就可以根据外部电路需要多少V的高电平来给这一个上拉的电压,可以更好的适应更多情况。 如下图,我们可以给定任意的VDD电压,来适应我们实际所需要的情况。
文章目录 一、拷贝并分析 Android 中的 /system/lib/libc.so 动态库二、拷贝并分析 Android 中的 /system/lib/libc++.so 动态库三、拷贝并分析 Android 中的 /system/lib/libstdc++.so 动态库总结 一、拷贝并分析 Android 中的 /system/lib/libc.so 动态库 /system/lib/libc.so 是 C 函数标准库 ;
执行
cp /system/lib/libc.so /sdcard/Pictures 命令 , 将 libc.so 拷贝到手机的 SD 卡中 , 从 SD 卡可以将该动态库拷贝到 Windows 文件中 ;
使用 64 位的 IDA 打开上述动态库 ;
libc.so 中有以下几个导入库 , dlopen , dlerror , dlclose ;
加载 libc.so 库之前 , 要先加载 /system/bin/linker 库 , 这是 so 动态库的加载模块 , 该动态库中 , 主要是实现了 dlopen 方法 ;
vue中class类名根据绑定的值三元表达式或字符串拼接动态添加类名
有2种实现方法:
1、数组方法
<span :class='["gender","bg-muted",data.gender===1 ? "fa-nanxing" : "fa-nvxing"]'></span> 提示:数组中的gender和bg-muted我这里是要加引号的,因为我这里就是字符串,
如果不加引号的,代表的是data中的一项数据。
2、字符串拼接方法
<span :class="'gender '+'bg-muted '+(data.gender===1 ? 'fa-nanxing' : 'fa-nvxing')"></span> 提示:gender和bg-muted后加一个空格(必须有),原理可以看开始位置的class类名格式,就很好理解。
介绍手机测试
对于手机端测试,按照平台来分,分为Android和IOS两大主流系统, 对于 ios 和 Android ,二者有区别,我就说一下我在测试这两款手机 app 的感受吧 1 、两者运行机制不同: IOS 采用的是沙盒运行机制,安卓采用的是虚拟机运行机制。 2 、两者后台制度不同: IOS 中任何第三方程序都不能在后台运行;安卓中任何程序都能在后台运行,直到没有 内存才会关闭。 3 、 IOS 中用于 UI 指令权限最高,安卓中数据处理指令权限最高。 Android 开源导致碎片化比较严重,(手机品牌众多,系统版本各异,分辨率不统一,主流手机型号上千。无法保证应用、游戏对于所有手机的适配兼容。)bug 比较多,而 IOS 通常 bug 会少一些。 Android 介绍 Android 是一种基于 Linux 的自由及开放源代码的操作系统,主要使用于移动设备,如智能手机和平板电 脑,由Google 公司和开放手机联盟领导及开发。尚未有统一中文名称,中国大陆地区较多人使用 “ 安卓 ” 。 Android 之四大组件 Android 四大组件分别为 activity 、 service 、 content provider 、 broadcast receiver 。 ADB 介绍 ADB 全称 Android Debug Bridge, 是 android sdk 里的一个工具 , 用这个工具可以直接操作管理android模拟器或者真实的 andriod 设备 ( 如 G1 手机 ) 它的主要功能有 : * 运行设备的 shell( 命令行 ) * 管理模拟器或设备的端口映射 * 计算机和设备之间上传 / 下载文件 * 将本地 apk 软件安装至模拟器或 android 设备 配置 ADB 环境变量 1 :在系统变量中新建ANDROID_HOME变量 2:在系统变量path中添加%ANDROID_HOME%\platform-tools 3:验证adb配置是否成功ADB常用指令
Mysql 锁类型 一、锁类型介绍: MySQL有三种锁的级别:页级、表级、行级。
表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。
行级锁:开销大,加锁慢;会出现死锁;锁定粒度最小,发生锁冲突的概率最低,并发度也最高。
页面锁:开销和加锁时间界于表锁和行锁之间;会出现死锁;锁定粒度界于表锁和行锁之间,并发度一般
算法:
next KeyLocks锁,同时锁住记录(数据),并且锁住记录前面的Gap
Gap锁,不锁记录,仅仅记录前面的Gap
Recordlock锁(锁数据,不锁Gap)
所以其实 Next-KeyLocks=Gap锁+ Recordlock锁
二、死锁产生原因和示例 1、产生原因: 所谓死锁:是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去.此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。表级锁不会产生死锁.所以解决死锁主要还是针对于最常用的InnoDB。
死锁的关键在于:两个(或以上)的Session加锁的顺序不一致。
那么对应的解决死锁问题的关键就是:让不同的session加锁有次序
2、产生示例: 案例一
需求:将投资的钱拆成几份随机分配给借款人。
起初业务程序思路是这样的:
投资人投资后,将金额随机分为几份,然后随机从借款人表里面选几个,然后通过一条条select for update 去更新借款人表里面的余额等。
例如两个用户同时投资,A用户金额随机分为2份,分给借款人1,2
B用户金额随机分为2份,分给借款人2,1
由于加锁的顺序不一样,死锁当然很快就出现了。
对于这个问题的改进很简单,直接把所有分配到的借款人直接一次锁住就行了。
Select * from xxx where id in (xx,xx,xx) for update
在in里面的列表值mysql是会自动从小到大排序,加锁也是一条条从小到大加的锁
例如(以下会话id为主键):
Session1:
mysql> select * from t3 where id in (8,9) for update;
+----+--------+------+---------------------+
| id | course | name | ctime |
+----+--------+------+---------------------+
| 8 | WA | f | 2016-03-02 11:36:30 |
卷帘快门与全局快门的区别 1.曝光方式定义2.卷帘曝光方式常见问题1.部分曝光现象(partial exposure)2.斜坡现象(skew)3.晃动现象(wobble) 1.曝光方式定义 **卷帘快门(Rolling shutter):**通常用于CMOS传感器。使用这种快门,传感器在曝光时并不是所有像素同时感光的,而是每行像素按照顺序依次感光。
**全局快门(Global shutter):**所有像素同时感光,在任意一个时间点,所有像素都接受相同的光量。
CCD传感器多用全局快门,CMOS传感器多用卷帘快门。传感器曝光方式不同对相机采图的方式影响较大,特别是对动态运行的图对曝光方式要求的更加苛刻,高速运动的物体检测全局曝光的方式能够最大限度的避免拖影等干扰。
2.卷帘曝光方式常见问题 1.部分曝光现象(partial exposure) 2.斜坡现象(skew) 斜坡现象通过卷帘曝光的方式成图表现的更加明显,当我们采用卷帘曝光的相机来采集高速运行的物体,物体在图像中经常会发生变形,如方形变成平行四边形,严总的甚至出现波浪条纹
3.晃动现象(wobble) 晃动的机理与斜坡相同,只是更为复杂,往往与相机的不稳定有关。
前言:https://blog.csdn.net/weixin_46366744/article/details/107047703 一些解决流氓弹窗、广告、挖矿等问题的小技巧。
环境:win10。
均为本人搜索、总结出来的一些简单方法。
计算机小白,如有问题请及时提出,见谅。
侵删。
【小技巧】专栏中,有关于卸载2345、劫持chrome浏览器主页、劫持edge浏览器主页的文章,感兴趣的话可在博客主页寻找查看。
该文是在2345已被消灭(但未完全消灭)的情况下,对残留的部分进行处理。
原本以为已经摆脱了流氓,今天看任务管理器的时候,突然发现内存被吃的特别很。
不知道哪个软件在后台打开了IE浏览器,而且后台无法关闭。
点进去看才发现,这浏览器主页看的我血压飙升。瞬间燃起来了,赶紧消灭掉。
首先要提的是,微软很早前就公布了要放弃IE浏览器,EDGE浏览器将取而代之,所以现在的计算机,尤其是win10系统,除了商业、工作需要,日常很少再有人使用IE浏览器。
所以之前我知道自己电脑的IE浏览器有流氓劫持的问题,但是因为从来不会使用,所以也就没有管他,现在看来,还是有必要解决一下的。
注意:不建议卸载IE浏览器,因为微软仍有不少系统软件与它有关联,卸载的话可能会造成不必要的麻烦。这里的建议是,把IE浏览器所有性能调到最低,摆在一旁不适用就OK了。
打开控制面板,选择Internet选项。
这里就是之前残留的流氓网页。因为我电脑的2345已经清理的差不多了,所有现在修改完主页,也不会再被篡改了。
如果不使用IE浏览器的话建议改成空白页about:NewsFeed。
缓存和临时文件这里修改一下,避免占用太多C盘空间。
修改临时文件的缓存位置,从C盘改到其他盘。
最终结果,就让它躺在那里不要管它了。
目录
1.重投影误差的概念
2.基于摄像机模型的重投影误差
3.畸变校正算法
3.1利用畸变模型正向求解
3.2利用畸变模型反向求解
1.重投影误差的概念 在相机标定后,我们可以通过计算重投影误差来判断标定地精准程度。在标定后每个三维点根据相机的投影矩阵计算得到的图像位置与实际图像位置之间总存在一个距离,这个距离的累加和就是重投影误差。重投影误差不仅考虑的单应矩阵间的计算误差,也考虑了图像的测量误差,因此适合用来评价标定结果。重投影误差受镜头畸变等因素的影响,因此本文比较了畸变矫正前后的重投影误差大小。
2.基于摄像机模型的重投影误差 我们知道有限射影摄像机模型下,三维点X和图像点x之间的映射关系如下:
则计算得到的图像点位置可以用世界坐标系坐标表示为:
将求得的图像点与实际图像点间求二范数即反投影误差,各点反投影误差之和即重投影误差。笔者猜想,这就是OpenCV中调用projectPoints()函数时,令畸变系数为0时所采用的算法,笔者通过实验发现结果与猜想基本一致。
值得注意的是,这里没有考虑镜头的畸变。 3.畸变校正算法 我们在相机标定结束后获得的五个畸变系数:k1,k2,k3,p1,p2分别代表了径向畸变和切向畸变的系数,公式如下:
径向畸变公式 切向畸变公式 综合径向畸变和切向畸变的公式 注意,为理想坐标,为畸变后的坐标,且两个坐标均在归一化平面上。因此原始图像的已知坐标为,畸变矫正的过程就是根据原始图像计算理想坐标的过程。
笔者在OpenCV官方文档上找到了使用该模型的矫正算法。
3.1利用畸变模型正向求解 OpenCV官方文档由理想坐标点到带畸变坐标点的正向求解的算法如下:
该算法的基本思路为:
理想图像坐标系,转移到相面坐标,再通过归一化,得到归一化平面上的坐标,利用畸变模型(图中的畸变参数暂未用到,默认为0)得到畸变后的坐标(如果是双目相机模型,还需要利用相机间的旋转矩阵,得到该点在某一相机相面上的图像位置)。再利用图像坐标系和相面坐标系的关系还原到图像系中,得到畸变后的,从而得到了畸变前后图像坐标系的映射关系,利用这种映射关系就能对图像进行矫正。
该算法的对应OpenCV函数为:initUndistortRectifyMap(),函数原型如下:
CV_EXPORTS_W void initUndistortRectifyMap( InputArray cameraMatrix, // computed camera matrix InputArray distCoeffs, InputArray R, InputArray newCameraMatrix, Size size, int m1type, OutputArray map1, OutputArray map2); 得到映射后,调用remap()来矫正每幅图像。
CV_EXPORTS_W void remap( InputArray src, OutputArray dst, InputArray map1, InputArray map2, int interpolation, int borderMode = BORDER_CONSTANT, const Scalar& borderValue = Scalar()); 如果仅需要矫正一幅图像,可以将两个函数组合起来方便调用,OpenCV提供了这种函数undistort(),其函数原型如下:
聊聊Lucene的创始人 我们在了解ElasticSearch的时候,必将绕不开Lucene。因为ElasticSearch是基于Luence开发的。因为Luence又是Doug Cutting开发的,所以我们先了解一下Doug Cutting这个人。
本故事内容来自公众号:酸枣课堂
聊聊Doug Cutting 大数据就两个问题:存储+计算。
1998年9月4日,Google公司在美国硅谷成立。正如大家所知,它是一家做搜索引擎起家的公司。
无独有偶,一位叫Doug Cutting的美国工程师,也迷上了搜索引擎。他做了一个用于文本搜索的函数库(姑且理解为软件的功能组件),命名为Lucene。
Lucene是用Java编写的,其作用是为各种中小型应用软件加入全文检索功能。因为好用而且开源(代码公开),非常受广大开发者们的欢迎。
早期的时候,这个项目被发布在Doug Cutting的个人网站和SourceForge(一个开源的软件网站)。后开,2001年底,lucene成为Apache软件基金会Jakarta项目的一个子项目。
2004年,Doug Cutting再接再厉,在Lucene的基础上和Apache开源伙伴Mike Cafarella合作,开发了一款可以替代当时的主流搜索的开源搜索引擎,命名为Nutch。
Nutch是一个建立在lucene核心之上的网页搜索应用程序,可以下载下来直接使用。它在lucene的基础上加了网络爬虫和一些网页相关的功能,目的就是从一个简单的站内检索推广到全球网络的搜索上,就像Google一样。
Nutch在业内的影响力比Lucene更大。
大批网站采用了Nutch平台,大大降低了技术门槛,使低成本的普通计算机取代高价的Web服务器成为可能。甚至有一段时间,在硅谷有了一股用Nutch低成本的创业的潮流。
随着时间的推移,无论是Google还是Nutch,都面临搜索对象“体积”不断增大的问题。尤其是Google,作为互联网搜索引擎,需要存储大量的网页,并不断优化自己的搜索算法,提升搜索效率。
在这个过程中,Goolge确实找到了不少好办法,并且无私地分享了出来。
2003年,Google发表了一篇技术学术论文,公开介绍了自己的谷歌文件系统GFS(Google File System)。这是Google公司为了存储海量搜索数据而设计的专用文件存储系统。
第二年,也就是2004年,Doug Cutting基于Google的GFS论文,实现了分布式文件存储系统,并将它命名为NDFS(Nutch Distributed File System)。
还是2004年,Google又发表了一篇技术学术论文,介绍了自己的MapReduce编程模型。这个编程模型,用于大规模数据集(大于1TB)的并行分析运算。
第二年(2005年),Doug Cutting又基于MapReduce,在Nutch搜索引擎实现了该功能。
2006年,当时依然很厉害的Yahoo(雅虎)公司,招安了Doug Cutting。
加盟Yahoo之后,Doug Cutting将NDFS和MapReduce进行了升级改造,并重新命名为Hadoop(NDFS也改名为HDFS,Hadoop Distributed File)。
这个,就是后来大名鼎鼎的大数据框架系统———Hadoop的由来。而Doug Cutting,则被人们称为Hadoop之父。
Hadoop这个名字,实际上使Doug Cutting他儿子的黄色玩具大象的名字。所以,Hadoop的Logo,就是一只奔跑的黄色大象。
我们继续往下说。还是2006年,Google又发表论文了。这次,他们介绍了自己的BigTable。这是一种分布式数据存储系统,一种用来处理海量数据的非关系型数据库。 Doug Cutting当然没有放过,在自己的hadoop系统里面,引入了BigTable,并命名为Hbase。
好吧,反正就是跟紧Google时代的步伐,你出什么,我学什么。所以,Hadoop的核心部分,基本上都有Google的影子。
2008年1月,Hadoop成功上位,正式称为Apache基金会的顶级项目。
同年2月,Yahoo宣布建成了一个拥有一万个内核的Hadoop集群,并将自己的搜索引擎产品部署在上面。7月,Hadoop打破世界纪录,称为最快排序1TB数据的系统,用时209秒。
聊聊Shay Banon 通过上述介绍我们了解到Lucence的由来,并且知道了Lucene是一套信息检索工具包。是一个基于Java编写的jar包。不包含搜索引擎系统。
包含的:索引结构!读写索引的工具!排序,搜索规则。。。工具类!
Lucene和ElasticSearch关系: ElasticSearch是基于Lucene做了一些封装和增强(我们上手是十分简单的)。
历史由来: 多年前,一个叫做Shay Banon的刚结婚不久的失业开发者,由于妻子要去伦敦学习厨师,他便跟着也去了。他在找工作的过程中,为了给妻子构建一个食谱的搜索引擎,他开始构建一个早期版本的Lucene。
直接基于Luence工作会比较困难,所以Shay开始抽象Lucene代码以便java程序员可以在应用中添加搜索功能。他发布的第一个开源项目,叫做“Compass”。
后开Shay找到一份工作,这份工作处在高性能和内存数据网络的分布式环境中,因此高性能的、实时的、分布式的搜索引擎也就是利索当然需要的。然后他决定重写Compass库使其成为一个独立的服务叫做Elasticsearch。
第一个公开版本出现在2010年2月,在那之后Elasticsearch已经成为GitHub上最受欢用的项目之一,代码贡献者超过300人。一家主营ElasicSearch的公司就此成立,他们一边提供商业支持一边开发新功能,不过Elasticseach将永远开源且对所有人可用。
不过,Shay的妻子依旧等待者她的搜索食谱......
文章目录 一、拷贝 /system/lib/ 中的 Android 系统 so 动态库 一、拷贝 /system/lib/ 中的 Android 系统 so 动态库 将 Android 系统的 /system/lib/libc.so 动态库 , 拷贝到 /sdcard/Pictures/lib/ 目录中 ;
首先 , 在 /sdcard/Pictures/ 目录下创建 lib 目录 ;
mkdir /sdcard/Pictures/lib 然后 , 将 /system/lib/libc.so 动态库 , 拷贝到 /sdcard/Pictures/lib/ 目录中 ;
cp /system/lib/libc.so /sdcard/Pictures/lib/ 拷贝后 , 可以从 SD 卡中 , 将 libc.so 动态库拷贝出来 ;
注意 , 获取动态库后 , 32 位的动态库要使用 32 位的 IDA 打开 , 64 位的动态库使用 64 位的 IDA 打开 ;
【学习背景】
本文主要分享一下MySQL日常开发运维当中,关于配置文件my.cnf中[client]、[mysqld]、[mysql]、[mysqld_safe]四个组下比较常见的参数、参数值以及参数值说明。
学习目录 一、[client]组下参数二、[mysqld]组下参数三、[mysql]组下参数四、[mysqld_safe]组下参数 一、[client]组下参数 [client]
#客户端端口号
port=3306 #套接字文件,本地连接使用 socket=/data/mysqldata/mysql.sock
#客户端字符集
default-character-set=utf8mb4
二、[mysqld]组下参数 [mysqld]
#数据库服务器id,这个id主要用在主从数据库服务器之间标记唯一mysql标识
server-id=8008 #数据库提供对外的端口 port=3306
#mysql启动时使用的用户
user=mysql
#服务器的默认字符集
character-set-server=utf8mb4
#软件介质安装目录
basedir=/opt/mysql/mysql-5.7.29
#数据库数据目录
datadir=/data/mysqldata/3306
#数据库临时文件目录
tmpdir=/data/mysqltmp
#套接字文件,本地连接使用
socket=/data/mysqldata/mysql.sock
#进程号文件
pid-file=/data/mysqldata/mysqld.pid
#默认数据库存储引擎
default-storage-engine=Innodb
#大小写是否敏感,1为不区分
lower_case_table_names=1
#默认数据库隔离级别,读提交
transaction_isolation=READ-COMMITTED
#数据库可拥有的未完成连接请求数
back_log=400
#数据库允许的最大连接数
max_connections=1000
#数据库关闭一个交互的连接之前所要等待的秒数
interactive_timeout=28800
#数据库关闭一个非交互的连接之前所要等待的秒数
wait_timeout=28800
#备库等待主库发送数据的超时时间,如果超过这个时间主库还未发送任何消息,开始尝试重连操作
slave_net_timeout=300
#二进制binlog日志文件存放位置及文件名前缀
log_bin=/data/mysqllog/bin-log/mysql-bin
#relaylog的存放位置及文件名前缀
relay-log=/data/mysqllog/relay-log/mysql-relay
#binlog日志的保留天数
expire_logs_days=7
#二进制binglog日志缓冲大小
binlog_cache_size=8M
#二进制日志的格式,row格式为记录每行数据的变化
binlog_format=ROW
#自动清理relaylog开启
relay_log_purge=1
#控制是否可以信任存储函数创建者,1为信任
log-bin-trust-function-creators=1
#指定延迟时间内,一次组提交允许等待的最大事务数量
binlog_group_commit_sync_no_delay_count=20
#控制在二进制日志文件同步到磁盘之间等待多少微秒以把事务合并到一个binloggroup中一次性提交(单位:us)
binlog_group_commit_sync_delay=10
#开启GTID模式的复制
gtid_mode=on
#强制GTID的一致性
参考了以下文章:
https://github.com/lixiaolia/commonapi_someip_demo
https://blog.csdn.net/u010743397/article/details/107892463
提前说明,整个安装过程需要下载和安装一些程序,总耗时较长。
我的安装环境是ubuntu20.04
安装依赖:
sudo apt-get install cmake cmake-qt-gui libexpat-dev expat default-jre
编译和安装 boost:(可以去网上下载最新的版本)
https://www.boost.org/users/download/
例如:
cd boost_1_57_0
./bootstrap.sh
./b2 link=shared
sudo ./b2 install
编译和安装 vsomeip:
创建一个目录作为工作目录,以下行为都在工作目录下操作
git clone https://github.com/GENIVI/vsomeip.git
cd vsomeip
mkdir build
cd build
cmake -DENABLE_SIGNAL_HANDLING=1 -DDIAGNOSIS_ADDRESS=0x10 …
关于选项有以下说明,直接贴原文:
With ENABLE_SIGNAL_HANDLING=1 the signal handling of vsomeip (SIGINT/SIGTERM) is enabled; that you can abort vsomeip applications by ctrl-c. 第一个选项表示vsomeip接收SIGINT/SIGTERM信号,用ctro+c可以成功退出程序。
The second parameter DIAGNOSIS_ADDRESS specifies the first byte of the SOME/IP client ID (don’t care if you do not know at the moment what it is).
代码中实现了两种图的构建方法:RBF和KNN labelpropagation.py
import time import numpy as np def navie_knn(dataSet, query, k): numSamples = dataSet.shape[0] # 1. 计算欧氏距离 diff = np.tile(query, (numSamples, 1)) - dataSet squaredDiff = diff ** 2 squaredDist = np.sum(squaredDiff, axis=1) # 2. 对距离进行排序 sortedDistIndices = np.argsort(squaredDist) if k > len(sortedDistIndices): k = len(sortedDistIndices) # 返回排序后的距离 return sortedDistIndices[0:k] # 建立一个大图 def buildGraph(MatX, kernel_type, rbf_sigma=None, knn_num_neighbors=None): num_samples = MatX.shape[0] affinity_matrix = np.zeros((num_samples, num_samples), np.float32) # 判断是否满足条件,是否为rbf类型 if kernel_type == 'type': if rbf_sigma == None: raise ValueError('You should input a sigma of rbf kernel!
这些是自己在看Java书籍时从书上摘抄的,主要是为了加强自己对知识点的记忆,同时也是对这个知识点不太懂所以记录一下,就是自己的学习笔记。
1.1 lambda表达式简介 理解lambda表达式的Java实现,有两个结构十分关键:第一个是lambda表达式自身,第二个是函数式接口。
lambda表达式本质上就是一个匿名(即未命名)方法。但是,这个方法不是独立执行的,而是用于实现由函数式接口定义的另一个方法。因此,lambda表达式会产生一个匿名类。lambda表达式也常被称为闭包。
函数式接口是仅包含一个抽象方法的接口。这个方法指明了接口的目标用途。因此,函数式接口通常表示单个动作。例如:标准接口Runnable是一个函数式接口,因为它只定义了一个方法run(),run()定义了Runnable的动作。此外,接口式函数定义了lambda表达式的目标类型。特别注意:lambda表达式只能用于其目标类型已被指定的上下文中。
1.1.1 lambda表达式的基础知识 lambda表达式在Java语言中引入了一个新的语法元素和操作符。这个操作符是-> ,操作符被称为lambda操作符或者是箭头操作符。它将lambda表达式分成两个部分,左侧指定了lambda表达式需要的所有参数(如果不需要参数,则使用空的参数列表“()”),右侧指定了lambda体,即lambda表达式要执行的动作。
Java定义了两种lambda体:一种包含单独一个表达式,另一种包含一个代码块。
看一个简单的lambda表达式的例子,它的计算结果是一个常量值,如下所示:
() -> 123.45 这个lambda表达式没有参数,所以参数列表为空,它返回常量值123.45。因此,这个表达式的作用类似于下面的方法;
double myMath(){ return 123.45; } lambda表达式定义的方法没有名称
下面在看一个lambda表达式:
() -> Math.random() * 100 这个lambda表达式使用Math.random()获得一个随机数,将其乘以100,然后返回结果。这个lambda表达式也不需要参数。
当lambda表达式需要参数时,需要在操作符左侧的参数列表中加以指定,下面是一个简单的例子:
(n) -> (n % 2) == 0 如果参数n的值是偶数,这个lambda表达式会返回true。尽管可以显式指定参数的类型,例如本例中的n,但是通常不需要这么做,因为很多时候,参数的类型是可以从上下文中推断出来。与命名方法一样,lambda表达式可以指定需要用到的任意数量的参数。
1.1.2 函数式接口 函数式接口是仅指定了一个抽象方法的接口。从JDK8开始,可以为接口声明的方法指定默认行为(默认的方法实现),即所谓的默认方法,只有当没有指定默认实现时,接口的方法才是抽象方法。因为没有指定默认实现的接口方法隐式的是抽象方法,所以没有必要使用abstract修饰符。
下面是函数式接口的一个例子:
public interface MyNumber { double getValue(); } 在本例中,getValue()方法隐式的是抽象方法,并且是MyNumber定义的唯一方法,所以MyNumber是一个函数式接口,其功能由getValue()定义。
lambda表达式不是独立执行的,而是构成了一个函数式接口定义的抽象方法的实现,该函数式接口定义了它的目标类型,只有在定义了lambda表达式的目标类型的上下文中,才能使用该表达式。当把一个lambda表达式赋给一个函数式接口引用时,就创建了这样的上下文。
下面通过一个例子来说明如何在参数上下文中使用lambda表达式。首先,声明对函数式接口MyNumber的一个引用
MyNumber myNum; 接下来,将一个lambda表达式赋给该接口引用:
myNum = () -> 123.45; 当目标类型上下文中出现lambda表达式时,会自动创建实现了函数式接口的一个类的实例,函数式接口声明的抽象方法的行为由lambda表达式定义。当通过目标调用该方法时,就会执行lambda表达式。因此,lambda表达式提供了一种将代码片段转换为对象的方法。
在前面的例子中,lambda表达式成了getValue()方法的实现,所以,下面的代码将显示123.45:
System.out.println(myNum.getValue()); //结果如下: //123.45 因为赋给myNum的lambda表达式返回值为123.45,所以调用getValue()方法返回的值也是123.45
为了在目标类型上下文中使用lambda表达式,抽象方法的类型和lambda表达式的类型必须兼容。例如:如果抽象方法指定了两个int类型的参数,那么lambda表达式也必须指定两个参数,其类型要么被显式的指定为int类型,要么在上下文中可以隐式的推断为int类型。总的来说,lambda表达式的参数类型和数量必须与方法的参数兼容;返回类型必须兼容;并且lambda表达式可能抛出的异常必须能被方法接受。
package lambda; interface NumericTest{ boolean test(int n); } public class LambdaDemo2 { public static void main(String[] args) { NumericTest isEven = (n) -> (n % 2) == 0; if (isEven.
【学习背景】
Linux CentOS 6.5版本以前,默认防的火墙是iptables,CentOS6.5版本及以后版本,防火墙都由iptables升级为了firewall,不过底层还是基于iptables的指令,因此还是有必要了解了解。
本文主要介绍iptables的基本命令以及如何开放和阻止iptables防火墙常用端口,如22、80、8080、3306等常用端口号。
目录 一、iptables安装二、iptables基本操作2.1 防火墙服务2.2 systemctl基本命令2.3 service基本命令 三、防火墙端口(开放/阻止)3.1 查询防火墙开放端口3.2 开放防火墙指定端口3.2.1 允许所有服务器访问指定端口3.2.2 防火墙指定IP(允许/禁止)访问3.2.3 防火墙指定IP(允许/禁止)访问指定端口 四、删除防火墙端口 一、iptables安装 查看是否安装
iptables -V 安装(已安装的跳过)
yum install iptables-services 二、iptables基本操作 2.1 防火墙服务 #查看防火墙的服务 chkconfig --list | grep iptables #永久关闭防火墙 chkconfig iptables off #永久开启防火墙 chkconfig iptables on 2.2 systemctl基本命令 #查看防火墙的状态 systemctl status iptables.service #停止防火墙 systemctl stop iptables.service #启动防火墙 systemctl start iptables.service #重启防火墙 systemctl restart iptables.service #重载防火墙等价于restart systemctl reload iptables.service #禁止开机启动防火墙 systemctl disable iptables.service #开机启动防火墙 systemctl enable iptables.
solidworks路径配合如何使用?七步教会你 solidworks中有一种配合叫路径配合,它主要使装配零件沿着既定的路线移动,就像有轨小车沿着轨道移动,人爬山沿着山路移动。具体如何操作呢?
1.首先画路径任意画,越夸张越好。可以用样条曲线画。如下图所示。画完后保存。
2.再建立个零件这个零件形状任意。随后插入图形的中心点。如下图所示。
3.选择要插入点的图形,点击面中心如下图所示。点击确定并保存。
4.建立装配体,将路径以及零件导入到装配体中。点击右侧菜单栏中的眼睛,再点击当中的点,显示图形的中心点。
5.在配合中点击高级配合。在高级配合中选择路径配合。
6.零件顶点选择图中的零件中心点,点1,路径选择所画的波浪线。然后点击确定即可。
7.拖拽图形,你会发现图形中心点沿着曲线移动。
STM32学习笔记——HC-SR04超声波测距模块 碰巧学校老师要求做个HC-SR04超声波的实验,笔者在完成实验报告的同时,也顺带完成一篇STM32驱动超声波模块记录。
HC-SR04模块使用 STM32学习笔记——HC-SR04超声波测距模块前言一、HC-SR04介绍二、使用步骤1.接口定义2.阅读时序图3.原理4.代码 前言 HC-SR04作为简单的外设模块,广泛应用于简单的课设项目中,十分适合入门STM32。
一、HC-SR04介绍 HC-SR04的介绍,这里就不做累述了,大家可以上某宝上找店家要下用户手册,或者到其他博主的博客中看个大概的介绍。
二、使用步骤 1.接口定义 VCC -------> 5V TRIG -------> PA6 ECHO -------> PA7 GND -------> GND TRIG和ECHO两个接口也可以使用其他的IO口继续驱动,在这篇文章中,博主用的是PA6和PA7。当然也可以使用其他的IO口,只需要所使用的IO口可以输出输入高低电平即可。
2.阅读时序图 如图,驱动HC-SR04需要先向TRIG口输入一段超过10us的高电平。此时模块会自动输出脉冲信号来检测是否接收到了信号的返回。若接收到了返回信号,则会将ECHO段拉高并持续一段时间,而持续的时间便是超声波信号发出到接收到返回的超声波信号的时间。
3.原理 原理:IO口发送触发信号拉高Trig,延迟超过10us之后,再拉低Trig,作为超声波模块的启动信号,此时模块不断自动发出一段40khz的信号,当收到返回的超声波信号时,ECHO口则输出回响信号 。回响信号的脉冲宽度与所测的距离成正比。由此通过发射信号到收到的回响信号时间间隔可以计算得到距离.
4.代码 hscr.c下的代码:
#include "hcsr.h" void TIM2_Count_Configuration(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); TIM_TimeBaseStructure.TIM_Period = 0xFFFF; //999+1 =1000 TIM_TimeBaseStructure.TIM_Prescaler = 71; //71+1= 72分频 //TIM_TimeBaseStructure.TIM_ClockDivision = 0x0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); TIM_Cmd(TIM2, ENABLE); //暂时先关闭TIM2时钟,等全部初始化结束后正式使用定时器前再开启 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, DISABLE); } //PB6(output):TRIG PB7(input):ECHO void HCSR04_GPIO_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); GPIO_InitStructure.
题目链接
今天做的第二题,感觉比较经典,详细记录一下吧!
Monkey and Banana 一个 n 阶方阵的元素是1,2,…,n^2,它的每行,每列和2条对角线上元素的和相等,这样
的方阵叫魔方。n为奇数时我们有1种构造方法,叫做“右上方” ,例如下面给出n=3,5,7时
的魔方.
3
8 1 6
3 5 7
4 9 2
5
17 24 1 8 15
23 5 7 14 16
4 6 13 20 22
10 12 19 21 3
11 18 25 2 9
7
30 39 48 1 10 19 28
38 47 7 9 18 27 29
46 6 8 17 26 35 37
GPU状态的监控 nvidia-smi: 是Nvidia显卡命令行管理套件,基于NVML库,旨在管理和监控Nvidia GPU设备。nvidia-smi命令的输出中最重要的两个指标:显存占用和GPU利用率。
显存占用和GPU利用率是两个不一样的东西,显卡是由GPU计算单元和显存等组成的,显存和GPU的关系有点类似于内存和CPU的关系。
gpustat:它基于nvidia-smi,可以提供更美观简洁的展示,还可以结合 watch 命令,可以动态实时监控 GPU 的使用情况。直接pip install gpustat即可安装。
1)gpustat -I
2)watch --color -n1 gpustat -cpu 显存 显存可以看成是空间,类似于内存。
显存用于存放模型,数据显存越大,所能运行的网络也就越大 GPU计算单元类似于CPU中的核,用来进行数值计算。衡量计算量的单位是****flop: the number of floating-point multiplication-adds,浮点数先乘后加算一个flop。计算能力越强大,速度越快。衡量计算能力的单位是flops: 每秒能执行的flop数量。
1*2+3 1 flop 1*2 + 3*4 + 4*5 3 flop 1. 显存分析 1.1 存储指标 1Byte = 8 bit 1K = 1024 Byte 1M = 1024 K 1G = 1024 M 1T = 1024 G 10 K = 10*1024 Byte 除了K、M,G,T等之外,我们常用的还有KB 、MB,GB,TB 。二者有细微的差别。
概要 本为主要讲解生成法线贴图的基本方法,并在 unity 中进行实现和测试。
预备知识 法线贴图和基本的图形学知识,基本的向量和极限的知识。
高度图或灰度图 一张二维纹理有两个维度 u 和 v,但其实,高度(h)可以算第三个维度。有了高度,一张二维纹理就可以想象成一个三维的物体了。
先来考虑只有 u 方向的情况,如图所示, A 和 B 是纹理中的两个点, uv 坐标分别是 (0, 0) 和 (1, 0),上方黑线表示点对应的高度,那么显然,只要求出 u 方向上的高度函数在某一点的切线,就能求出垂直于他的法线了。同理, v 方向也是如此。也就是说,如果有纹理的高度信息,那么就能计算出纹理中每一个像素的法线了。
所以计算法线需要一张高度图,它表示纹理中每一个点对应的高度。
但其实并不需要求出每个纹理像素上 uv 方向各自的法线,只需要求出 uv 方向上高度函数的切线,再做一个叉积,即可计算出对应的法线了。
如果没有高度图,也可以用灰度图代替,灰度图就是把 rgb 三个颜色分量做一个加权平均,有很多种算法提取灰度值,这里用一个比较常用的基于人眼感知的灰度值提取公式。
color.r * 0.2126 + color.g * 0.7152 + color.b * 0.0722 这个公式是由人眼对不同颜色敏感度不同得来的,这里无需过多计较,直接把提取出来的灰度值作为高度值即可。
计算方法 当需要求一个点的函数图像切线的时候,只要求出该点的函数斜率即可,即是导数,这需要和它相临的点进行计算。显然,两个点越接近,结果越精确。所以有如下公式:
求出切线后,就得到了两个方向上的切线向量 和 。之所以是这种形式的二维向量,是因为这里是按照 uoh 平面和 voh 平面分别计算的,具体的向量形式需要根据实际情况去组合。这里可以做一个优化,在求导数的时候公式里做了一个除法,因为法线最终会归一化,切线向量长度不影响叉积后的结果向量方向,所以其实可以直接把求导数时候的除法去掉,即直接将切线向量乘以 和 ,变为 和
。如果你觉得乱,没关系,后面看具体的代码就明白了。
接下来是将两个向量做叉积,叉积的顺序会影响计算出的法线的方向,这个要根据实际情况去决定。
实例 这个例子使用 unity shader 去动态的生成一张纹理中每一个像素的法线,并当作颜色输出出来,最终在屏幕上会看到一张动态生成的法线贴图。将纹理放置成平行于屏幕的方向,如下图所示:
如何用addRoute实现子路由动态添加?前几天遇见过这个问题,记录一下我的解决方案。
routers=[{ path: "/", name: "layout", component: layout, meta: { }, children: [ { path: "/door", name: "door", redirect: "/door/homePage", component: door, meta: { name: "首页", }, }, ] }] 我要再children里面通过动态路由的方式添加一个子路由。
{ path: '/get', component: get}; 使用this.$router.addRoute();
经过实践发现 addRoute 只能添加第一级的路由。
然后又想到把父级路和子级路由拼接好,全部都重新给覆盖一遍,这样确实解决了问题,但是会出现name重复的警告。
最后又去看了看文档,只要router.matcher属性做修改,即新的routes机会替换老的routers,其实就是replaceRoutes()的含义(官方没有提供这个api)
//替换以前的 router 保证名字不重复 router.matcher = new VueRouter({ mode: "hash" }).matcher router.addRoute(routers) 这样就解决了动态给子路由添加新路由了。也不会出现name重复的警告了。
目前我就想到了这种解决方法,还有什么解决方法欢迎一起来交流啊!
问题 D: algorithm-沙子的质量
时间限制 : 1.000 sec 内存限制 : 128 MB
题目描述
设有N堆沙子排成一排,其编号为1,2,3,…,N(N< =300)。每堆沙子有一定的数量,可以用一个整数来描述,现在要将N堆沙子合并成为一堆,每次只能合并相邻的两堆,合并的代价为这两堆沙子的数量之和,合并后与这两堆沙子相邻的沙子将和新堆相邻,合并时由于选择的顺序不同,合并的总代价也不相同,如有4堆沙子分别为1 3 5 2我们可以先合并1、2堆,代价为4,得到4 5 2又合并1,2堆,代价为9,得到9 2,再合并得到11,总代价为4+9+11=24,如果第二步是先合并2,3堆,则代价为7,得到4 7,最后一次合并代价为11,总代价为4+7+11=22;问题是:找出一种合理的方法,使总的代价最小。输出最小代价。
输入
第一行一个数N表示沙子的堆数N。 第二行N个数,表示每堆沙子的质量。 a[i]< =1000。
输出
合并的最小代价。
样例输入
4
1 3 5 2
样例输出
22
#include<iostream> using namespace std; int dp[310][310]; int a[310]; int n; int add(int* a, int i, int j) { int sum = 0; for (i; i - 1 < j; i++) { sum += a[i - 1]; } return sum; } int main() { cin >> n; for (int i = 0; i < n + 1; i++) { for (int j = 0; j < n + 1; j++) { dp[i][j] = 0xffffff; //初始化 } } int* a = NULL; a = new int[n]; for (int i = 0; i < n; i++) { cin >> a[i]; //初始化 } for (int i = 1; i <= n; i++) { dp[i][i] = 0; } for (int L = 2; L <= n; L++)//算法与矩阵相乘类似 { for (int i = 1; i <= n; i++) { int j = i + L - 1; if (j > n) break; for (int k = i; k < j; k++) { int min = dp[i][j]; int temp = dp[i][k] + dp[k + 1][j] + add(a, i, j);//和矩阵相乘的递归式区别 //在于将递归定义中的+Pi-1*Pk*Pj替换为第i个数到第j个数的加和 if (temp < min) { dp[i][j] = temp; min = temp; } } } } cout << dp[1][n]; return 0; } 题目的解法类似于矩阵相乘,数的连加是完全加括号的,通过划定一个范围dp[i][j]表示沙堆i到j的最优合并情况,最终我们所需要的结果是dp[1][n]。
String path="//sdcard//DCIM//a31.jpg"; File file = new File(path); if(file.exists()){ Bitmap bm = BitmapFactory.decodeFile(path); pruductImg.setImageBitmap(bm); } private ImageView pruductImg; pruductImg.setImageURI( Uri.fromFile(newFile(CommonParameter.getMyproduct().getmImg())) );
定义两个栈,一个a栈用来存放数字,另一个b栈用来存放运算符,遇见数字将数字压入a栈,遇见运算符将运算符压入b栈,当第二次压入运算符之前 先与此时b栈栈顶的运算符'x' 优先级进行比较,如果'x'优先级大于栈顶优先级,将'x'压栈,若小于,取出a栈中的栈顶元素a[top]和a[top-1]与b栈中栈顶运算符 'y' 进行运算,将运算结果result再次压入a的栈顶,将b栈顶运算符'y'弹出,将'x'运算符插入栈中。
当循环遍历完之后,可能栈中可能还会有剩余的运算符和整数没有运算,判断是否还有运算符,若有继续运算,没有则结束。
#include <iostream> #include<cstring> #include<stack> using namespace std; int compare(char front,char rear){//定义比较优先级函数,只需判断小于等于和大于 if((front=='+'&&rear=='+')||(front=='-'&&rear=='-')||(front=='*'&&rear=='*')||(front=='/'&&rear=='/')||(front=='+'&&rear=='*')||(front=='-'&&rear=='*')||(front=='+'&&rear=='/')||(front=='-'&&rear=='/')||(front=='/'&&rear=='*')||(front=='*'&&rear=='/')||(front=='+'&&rear=='-')||(front=='-'&&rear=='+')) { return 1; } else{ return 0; } } int main() { string s1; cin >> s1; stack<long long int> a; stack<char> b; double result; for (int i = 0; i < s1.length(); i++) { if (isdigit(s1[i])) { long long int integer=0; while(1){//数字不一定只有一位数 integer=integer*10+(s1[i]-'0'); if(isdigit(s1[i+1])==0) { break; } i++; } integer=integer%10000; a.
创建script标签的方法(定义自定义组件) 代码如下(示例):
export default { components: { tabVue, 'remote-js': { render (createElement) { return createElement('script', { attrs: { type: 'text/javascript', src: this.src } }); }, props: { src: { type: String, required: true }, }, }, }, } 引用组件:
这里引用的是three.js这个外部js
<remote-js src="https://lf9-cdn-tos.bytecdntp.com/cdn/expire-1-M/three.js/71/three.min.js"></remote-js> src中使用的既是链接形式的js文件
查看效果:
dom创建完成并且插件使用正常
非常nice!!!
npm i --legacy-peer-deps
前提:插件版本以及所用插件 通过命令行进行安装
npm install --save vue-video-player npm install --save videojs-flash 注意!!!安装建议使用npm安装,不要使用cnpm安装,不知道何种原因cnpm安装可能会导致一些错误,使用npm安装则一点毛病没有
一、导入依赖包 import 'video.js/dist/video-js.css' import { videoPlayer } from 'vue-video-player' import 'videojs-flash' import SWF_URL from 'videojs-swf/dist/video-js.swf' 二、配置videoPlayer vue组件代码如下:
<videoPlayer ref="videoPlayer" class="vjs-custom-skin videoPlayer" :options="videoOptions" :playsinline="true" webkit-playsinline="" controls x5-video-player-fullscreen="true" x5-playsinline @play="onPlayerPlay($event)" style="object-fit:fill;" /> js代码如下:
export default { data () { return { videoOptions: { live: true, autoplay: true, fluid: true, muted: true, // 默认情况下将会消除任何音频。 //**关键问题** ios开启静音才能自动播放 notSupportedMessage: '暂时无法播放', aspectRatio: "16:9", // 将播放器置于流畅模式,并在计算播放器的动态大小时使用该值。值应该代表一个比例 - 用冒号分隔的两个数字(例如"
#! https://zhuanlan.zhihu.com/p/424678728
【操作系统概念-作业12】File-System Implementation Operating System Concepts Exercises 12 File-System Implementation 操作系统作业12
12.1, 12.3, 12.4, 12.7, 12.812.10, 12.11, 12.15, 12.16, 12.19 每题最后一个引用块是老师提供的参考答案
Practice Exercises 12.1, 12.3, 12.4, 12.7, 12.8
12.1 Consider a file currently consisting of 100 blocks. Assume that the file-control block (and the index block, in the case of indexed allocation) is already in memory. Calculate how many disk I/O operations are required for contiguous, linked, and indexed (single-level) allocation strategies, if, for one block, the following conditions hold.