音乐基本术语 velocity (i.e. bar or body speed)A tempo is how fast the beats go by in a particular piece of music.quality:音程性质 音乐符号化表示(Symbolic) 最基本的音乐信息(Events):在何时起止(Onset、Offset)什么绝对音高(MIDI pitch)。元信息:该音乐数据的名称是什么,包含什么声部、使用什么音色播放。基本音乐学信息:基本的如小节线、速度、拍号、调式等,以及进一步的信息如表情记号(连线、跳音、延长音、重音、强弱)、反复、临时升降号等。高层音乐学信息:乐句、和弦、分段、情绪。 因为最基础的MIDI文件只需要起止(Onset、Offset)、绝对音高(MIDI pitch)就可以播放了(音色之类的都可以设为默认如钢琴),因此才会造成数据如此杂乱。MusicXML格式就好得多,因为其是一个面向乐谱显示或排版的格式,包含基本音乐学信息是其基础。
MIDI(Musical Instrument Digital Interface) Channel通道:是指定的0~15的一个值,因为MIDI文件给我们提供了默认的16个通道,每一个通道可以对应一种乐器,相当于midi支持一首歌曲里同时使用16种乐器进行演奏Track音轨:音轨与通道并不是一一对应,而是可以多对多的关系。音轨是逻辑上的划分,比如可以将钢琴的左手演奏放在track 1,右手演奏放在track 2。但是输出时候,都是对应输出到钢琴的通道。你也可以只设置一个track 1,并且在里面记录着不同通道的消息。另外,还经常将track 0用来存储midi的作者、版权、音轨名、乐器名等元信息Event事件:事件也叫做消息(在mido库中使用message表示)。包括三种事件 meta event元消息,midi event主消息, sysex event系统消息。元消息上文有提及是作者,版权,音乐名等信息的存在track0中,系统消息是存储midi系统不同版本的信息,主要需要留意的就是midi消息。 midi有多种信息类型: MIDI Events Piano-Roll MusicXML MusicXML文件分为两种类型:score-partwise与score-timewise,其中较为常见的是score-partwise。
score-partwise 谱子信息,XML文件信息 各声部信息 声部1全曲: 小节1: 属性 音符1 音符2 …… REMI(revamped MIDI-derived events) 基于节拍事件(Beat-based)
REMI用时值取代MIDI编码里的音符关(Note off),用小节(Bar)和位置(Position)取代MIDI编码里的时移,并且增加了音乐速度与和弦信息。REMI编码将音乐编码成按照小节、位置、和弦、音乐速度、音高、时值、力度依次排列的离散token序列
The Bar, Position and Tempo-related events entail the use of audio domain downbeat and beat tracking algorithms 相比MIDI-like,REMI的异同:
监控 GPU 常用命令:nvidia-smi,nvidia-smi -l可以每五秒输出一次GPU信息 ;
watch --color -n1 gpustat -cpu # 动态事实监控 GPU,linux会一直处于监测状态,ctrl+z中止;
GPU的内存占用率主要由两部分组成:
一是优化器参数,模型自身的参数,模型中间每一层的缓存,都会在内存中开辟空间来进行保存,所以模型本身会占用很大一部分内存。模型自身的参数指的就是各个网络层的 Weight 和Bias,显存在模型加载完成之后就会被占用,有些层是有参数的,如CNN, RNN,有些层是无参数的, 如激活层, 池化层等。Pytorch 执行 model.to(device) , 模型就加载完毕了。
二是batch size的大小,模型结构固定时,将batch size设置大,会充分利用GPU内存。
计算模型参数量 import torch as t
from torchsummary import summary
rgb = t.randn(1,3,352,480).cuda()
net = FCN(12).cuda()
out = net(rgb)
summary(net,input_size=(3,352,480),batch_size=1)
GPU使用率低 训练模型时GPU的利用率有时会很低,而CPU的利用率却非常高。通常 CPU 进行数据读取和预处理,GPU 做模型的正向传播和反向传播。CPU数据读取跟不上(读到内存+多线程+二进制文件),而 GPU 处理速度太快,导致GPU的利用率不高。
模型训练慢并不是因为显卡不行或者模型太大,而是在跑模型过程中有一些其他的操作导致速度很慢,尤其是文件的IO操作,这会导致GPU得不到连续性使用,整体速度特别慢。
此时解决方法:
· 关闭一些日志记录,减少日志IO操作频率。
· NVIDA提供了DALI库,可将数据处理转移到GPU上。
GPU内存占用通常是由模型的大小以及batch size的大小决定。如果GPU占用率很低,通常只需要改变batch size的大小。合理的batch size可以提高显存的效率和数据的处理速度,跑完一次epoch需要迭代的次数也会随之减少,并且训练过程中的loss震荡也会减小。但batch size太小会导致模型震荡且不收敛,batch size太大则会导致训练速度慢且模型不易收敛。
不是IO操作导致的GPU使用率低,可考虑如下办法:
1、提高batch_size;
2、提高模型输入尺寸;
3、增加模型深度;
1.简介 阿里巴巴云计算技术有限公司(简称阿里云),成立于2009年9月10日;
#:IOE
I :指的是IBM,服务器的提供商,龙头老大;
O :指的是oracle ,数据库提供商;
E :指的是EMC,存储设备的供应商,提供的是集中式存储;
#:BGP:(Border Gateway Protocol),边界网关协议;
CDN:内容分发网络,将用户请求导向距离最近的服务器,快速响应,提高用户体验,如果访问的内容没有就会从主站中同步过来;
优势:集群规模大,弹性扩展能力强大,按需服务,成本较低,安全稳定:容灾强大;
设计理念:
1.大规模效应降低成本
2.多地域,对可用区容灾
3.服务化方式开放
2.阿里云基础应用架构介绍 阿里云四大件:ECS,SLB,RDS,OSS
ECS相当于是一台一台的服务器,此处为SAAS服务级别;
三个服务级别:IAAS,PAAS,SAAS
垂直扩展:在几分钟内扩展内存大小,CPU大小;
水平扩展:几分钟内创建数百个实例并且可以销毁;
云服务器ECS操作步骤: 第一步:创建实例
#:点击创建实例,这里有一个前提,前提是你的账户必须已经充值100元,否则你无法使用该产品;
第二步:选择合适的基础配置,不同的配置价格是不一样的,按需配置;
第三步:选择镜像以及版本,添加系统盘,可选,可在此处添加,也可以创建完成之后添加,都可以完成硬盘添加操作;
第四步:配置对应的网络相关设置,一般默认即可,有需要按需填写;
第五步:系统配置,密码可以选择生成密钥文件的方式,也可以直接采用账户密码的方式;
(1):密钥文件认证方式
#:选择生成的密钥文件即可;
(2) :密码认证方式:
#:这种方式比较简单,推荐,完成配置之后确认订单即可,点击实例就可以看到创建好的实例对象,点击远程登陆,有三种登录方式,都比较的容易,可以根据引导自行登录;
#:ECS快照最多创建64个快照,如果想要继续创建,那么最早的就会被删除;ECSd的快照是增量快照,只有两个快照之间变化的数据块才会被拷贝出来,
SLB根据负载调度的算法决定由哪个服务器来响应;
OSS文件存储:
对象存储服务,适合存放任意类型的文件,可靠性高,服务性能高,提供很多的API接口,可供其他的应用程序调用,弹性,自主扩展,按需服务;
RDS关系型数据库
也可用MySQL等等数据库应用,RDS和传统的相比,更加便宜,高可用,稳定性,可靠性都比较高;
专业的管理平台DMS,轻松实现数据回溯,专业的数据库优化建议,完整的监控体系;
RDS实例目前支持的最大内存为48GB,最大磁盘容量为1TB;
RDS建议一般和ECS再同一地域,以实现最高的访问性能,地区不影响,没有实质性区别;
RDS创建操作演示: 步骤一:基础配置
步骤二:实例配置
#:数据库一般不需要配置公网IP,因为数据库一般是不向外暴漏的,有内网的IP 就可以了,这个页面按需操作,一般为默认即可,没问题点击提交订单即可; RDS数据迁移操作演示: 规划:创建ECS实例,安装MySQL,创建表;创建RDS数据库服务器,将ECS数据迁移到RDS;
步骤一:基本配置,其他的没什么不同之处,区别在于,要添加3306端口
添加3306端口:
安装mariadb:
简单配置:
创建数据库表:
#:源库 就配置完成了,接下类创建目标库;
RDS实例创建在上面已经完成了,可以参考,下面还要进行一系列的配置:
进入到管理页面:创建一个普通账号;
创建数据库:
可以修改用户的权限:
可以设置添加白名单:
也可以登录DMS实现web界面管理:
准备工作完成,开始数据迁移:
选择自己对应的源配置(ECS数据库的配置)和 RDS数据库服务器的配置即可完成;
文章路标👉 文章解决问题主题内容 文章解决问题 1️⃣
在嘉立创EDA专业版中,很多时候需要自行建立元器件并绘制对应的器件原理图。对于一些引脚极其丰富的元件,引脚颜色千篇一律(均为黑色)时,难以辨认,增加了连线时的枯燥感。本文主要讲述如何修改器件原理图引脚标识颜色,本文将此过程记录,以供有需要的读者参考。
主题内容 2️⃣
✒️进入器件编辑界面,笔者以一个USB 3.1元件为例,可以看到修改引脚标识颜色前,颜色均为黑色,千篇一律,较难辨认重要引脚;
✒️笔者该例将电源正极引脚标识为红色,将DPx引脚标识为绿色,将DNx引脚标识为银色。对目标引脚标识,右键–属性;
✒️在右侧弹出的基础属性中,将字体颜色进行对应修改;
✒️修改完成的例子展示:
🔖🔖🔖
谷歌浏览器翻译不能使用解决教程 谷歌翻译退出了中国市场,但它还是保留了一些服务器,每个服务器都有对应的 IP 地址,将 IP 地址写入电脑里的 hosts 文件即可正常连接到谷歌翻译。
但是这些服务器可能会逐步关闭,所以 IP 地址可能会在一段时间后失效,失效之后使用另一个IP替换就可以了。
一、复制IP 108.177.97.100 translate.googleapis.com
142.250.157.90 translate.googleapis.com
142.251.10.90 translate.googleapis.com
172.253.118.90 translate.googleapis.com
142.251.12.90 translate.googleapis.com
142.251.8.90 translate.googleapis.com
142.250.99.90 translate.googleapis.com
142.250.107.90 translate.googleapis.com
142.251.160.90 translate.googleapis.com
142.250.125.90 translate.googleapis.com
172.253.117.90 translate.googleapis.com
172.253.114.90 translate.googleapis.com
142.250.103.90 translate.googleapis.com
142.250.100.90 translate.googleapis.com
142.250.159.90 translate.googleapis.com
142.250.1.90 translate.googleapis.com
142.250.115.90 translate.googleapis.com
172.217.214.90 translate.googleapis.com
142.250.114.90 translate.googleapis.com
142.251.6.90 translate.googleapis.com
142.251.116.90 translate.googleapis.com
142.250.128.90 translate.googleapis.com
142.250.113.90 translate.googleapis.com
172.217.203.90 translate.googleapis.com
142.251.162.90 translate.googleapis.com
172.217.215.90 translate.googleapis.com
142.251.16.90 translate.googleapis.com
142.251.120.90 translate.googleapis.com
142.251.163.90 translate.
Vue Axios Post Json 实现步骤:以登录注册功能为例 1.后端controller层代码代码 我采用的接收形式数据是json格式
@PostMapping("/login") public Resp login(@RequestBody User user){ User login = userService.login(user.getStudentid(),user.getPassword()); return Resp.success(login); } @PostMapping("/regist") public Resp regist(@RequestBody User user){ userService.regist(user); return Resp.success(null); } 2.前端登录注册界面代码 <body> <div id="app"> <form> 账号:<input type="text" name="studentid" v-model="registform.studentid"><br> 密码:<input type="text" name="password" v-model="registform.password"><br> 用户名:<input type="text" name="username" v-model="registform.username"><br> <input type="button" value="denglu" @click="tologin"> </form> </div> </body> <script type="text/javascript" src="../js/jquery.min.js"></script> <script src="../js/vue.js"></script> <script src="../js/axios-0.18.0.js"></script> <script> var vue = new Vue({ el:"#app", data:{ registform:{ studentid: "
@Configuration public class JacksonConfig { /** * Jackson全局转化long类型为String,解决jackson序列化时long类型缺失精度问题 * @return Jackson2ObjectMapperBuilderCustomizer 注入的对象 */ @Bean public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() { Jackson2ObjectMapperBuilderCustomizer cunstomizer = new Jackson2ObjectMapperBuilderCustomizer() { @Override public void customize(Jackson2ObjectMapperBuilder jacksonObjectMapperBuilder) { jacksonObjectMapperBuilder.serializerByType(Long.TYPE, ToStringSerializer.instance); jacksonObjectMapperBuilder.serializerByType(Long.class, ToStringSerializer.instance); } }; return cunstomizer; } } @Configuration @EnableWebFlux public class WebConfig implements WebFluxConfigurer { @Autowired private CommonConfig commonConfig; @Autowired private ObjectMapper objectMapper; @Override public void configureHttpMessageCodecs(ServerCodecConfigurer configurer) { SynchronossPartHttpMessageReader partReader = new SynchronossPartHttpMessageReader(); partReader.setMaxParts(Integer.parseInt(commonConfig.getMaxparts())); //字节bytes partReader.
概述 随着互联网的高速发展,云产业的快速突起,基础架构网络逐渐偏向基于通用计算平台或模块化计算平台的架构融合,来支持多样化的网络功能,传统的PC机器在分布式计算平台上的优势更为明显。在这些针对海量数据处理或海量用户的服务场景,高性能编程显得尤为重要。
全文路线
分析了目前的传统服务器结构以及可能存在的问题引出需求
提出DPDK开发套件如何突破操作系统限制
之后分析了dpdk的整体结构
最后对相关联的技术和场景做扩展.
背景分析 前10年中,网络程序性能优化的目标主要是为了解决C10K问题,其研究主要集中在如何管理数万个客户端并发连接,各种I/O框架下如何进行性能优化,以及操作系统参数的一些优化。当前,解决C10K问题的服务器已经非常多。Nginx和Lighttpd两款非常优秀的基于事件驱动的web服务框架,Tornado和Django则是基于python开发的非阻塞的web框架这些软件使得C10K已经不再是问题了。
从整体上看 为了满足日益增长的需求主要采用分布式集群来分担负荷,应对大量的用户请求.
集群
从结构上来看一个节点的服务器框架包含
网络模块
事件驱动模块
隔离,多核业务分发模块
业务层
在单个节点上,核的使用来看,主要包括
单线程服务器 优点是无竞争,缺点是没有充分利用系统资源
多进程模型 隔离性好,利用了系统更多的资源,缺点是进程间资源共享难
多线程模型 充分利用系统资源,竞争需要小心处理
需求分析 1.dpdk PCI原理与testpmd/l3fwd/skeletion
2.kni数据流程
3.dpdk实现dns
4.dpdk高性能网关实现
5.半虚拟化virtio/vhost的加速
DPDK相关学习资料需要的可以点击 C++后端学习资料 免费领取
综合分析
在应对网络密集型的巨大数据量时,一般选择是横向扩展节点,但是节点的增多会变相的增加设备成本和技术风险,且当集群节点到一定的量后,节点之间的交互成本本身就会成为瓶颈。
在特定场合下,譬如嵌入式设备上的后台服务,服务器不可能搭建集群。
因此提升服务器本身性能同样重要。
具体分析 传统服务器可能有下面的潜在问题
异步模式的弊端 一般我们使用epoll来高效的处理网络读写事件。在基于多线程的服务器设计框架中,在没有请求到来的时候,线程将会休眠,当数据到来时,将由操作系统唤醒对应的线程,也就是说内核需要负责线程间频繁的上下文切换,我们是在依靠操作系统调度系统来服务网络包的调度。在网络负载很大的场景下只会造成核满转且不断相互切换,进一步增加负荷.那么就需要回到最原始的方式,使用轮询方式来完成一切操作,来提升性能。
协议栈的扩展性 Linix诞生之初就是为电话电报控制而设计的,它的控制平面和数据转发平面没有分离,不适合处理大规模网络数据包。并且为了全面的支持用户空间的各个功能,协议栈中嵌入了大量用于对接的接口,如果能让应用程序直接接管网络数据包处理、内存管理以及CPU调度,那么性能可以得到一个质的提升。为了达到这个目标,第一个要解决的问题就是绕过Linux内核协议栈,因为Linux内核协议栈性能并不是很优秀,如果让每一个数据包都经过Linux协议栈来处理,那将会非常的慢。像Wind River和6 Wind Gate等公司自研的内核协议栈宣称比Linux UDP/TCP协议栈性能至少提高500%以上,因此能不用Linux协议栈就不用。 不用协议栈的话当然就需要自己写驱动了,应用程序直接使用驱动的接口来收发报文。PF_RING,Netmap和intelDPDK等可以帮助你完成这些工作,并不需要我们自己去花费太多时间。 Intel官方测试文档给出了一个性能测试数据,在1S Sandbridge-EP 8*2.0GHz cores服务器上进行性能测试,不用内核协议栈在用户态下吞吐量可高达80Mpps(每个包处理消耗大约200 cpu clocks),相比之下,使用Linux内核协议栈性能连1Mpps都无法达到。
多核的可扩展性 多核的可扩展性对性能提升也是非常重要的,因为服务器中CPU频率提升越来越慢,纳米级工艺改进已经是非常困难的事情了,但可以做的是让服务器拥有更多的CPU和核心,像国家超级计算中心的天河二号使用了超过3w颗Xeon E5来提高性能。在程序设计过程中,即使在多核环境下也很快会碰到瓶颈,单纯的增加了处理器个数并不能线性提升程序性能,反而会使整体性能越来越低。一是因为编写代码的质量问题,没有充分利用多核的并行性,二是服务器软件和硬件本身的一些特性成为新的瓶颈,像总线竞争、存储体公用等诸多影响性能平行扩展的因素。那么,我们怎样才能让程序能在多个CPU核心上平行扩展:尽量让每个核维护独立数据结构;使用原子操作来避免冲突;使用无锁数据结构避免线程间相互等待;设置CPU亲缘性,将操作系统和应用进程绑定到特定的内核上,避免CPU资源竞争;在NUMA架构下尽量避免远端内存访问
内存的可扩展性 内存的访问速度永远也赶不上cache和cpu的频率,为了能让性能平行扩展,最好是少访问。 从内存消耗来看,如果每个用户连接占用2K的内存,10M个用户将消耗20G内存,而操作系统的三级cache连20M都达不到,这么多并发连接的情况下必然导致cache失效,从而频繁的访问内存来获取数据。而一次内存访问大约需要300 cpuclocks,这期间CPU几乎被空闲。因此减少访存次数来避免cachemisses是我们设计的目标。 指针不要随意指向任意内存地址,因为这样每一次指针的间接访问可能会导致多次cache misses,最好将需要访问的数据放到一起,方便一次性加载到cache中使用。 按照4K页来计算,32G的数据需要占用64M的页表,使得页表甚至无法放到cache中,这样每次数据访问可能需要两次访问到内存,因此建议使用2M甚至1G的大页表来解决这个问题。
解决方案 控制层留给Linux做,其它数据层全部由应用程序来处理。 减少系统调度、系统调用、系统中断,上下文切换等
摒弃Linux内核协议栈,将数据包传输到用户空间定制协议栈
基于stable - diffusion 的本地部署AI绘画教程 自从Stable Diffusion 1.0模型发布以来,“AI文本图片生成”真正的变成普通人也能使用的技术。同时各种国内外AI绘图软件,也不断频繁更新,AI绘画的关注度也越来越高。
以下是本人自己生成出来的一些AI绘图(夹带私货木木枭^ ^)
对应的提示语prompt为:
"a cute portrait of rowlet,anime,warm style,suit , highly detailed, oil painting, concept art, smooth, sharp focus,high quality artwork" 那么如果我们想要本地部署一个真正属于自己的AI绘画模型,需要哪些东西呢。
要完成本次部署,我们需要导入一些包并且用里面封装好的参数来实现相应的功能,从而实现我们要的文字出图的功能.
接下来详细介绍一下大概的步骤。
操作环境:python 3.8.13操作软件:VsCode文件格式:ipynb 需要下载的包在后面会有讲到
1. 连接显卡 !nvidia-smi 首先要让GPU连接到notebook上
单独运行该语句后,成功后会显示如下提示
2. 本地下载transformershe和diffusers包: %pip install diffusers==0.4.0 %pip install transformers scipy ftfy 由于这里是jupyter所以和python 的pip的方式有点不一样
或者通过conda下载也可以
下载成功后会有如上提示
如果后面有
RuntimeError: CUDA error: no kernel image is available for execution on the device
类似这种提示,则说明一般是cuda或者python的版本出了问题
可能是版本不对,一般要求是3.8
目录
一、@staticmethod和@classmethod的基本概念
二、@staticmethod和@classmethod的区别
三、@classmethod的应用场景
四、@staticmethod的应用场景
五、代码实现和对比
5.1 不使用@staticmethod和@classmethod
5.2 使用@classmethod
5.3 使用staticmethod
5.4 @classmethod与@staticmethod对比
小结
一、@staticmethod和@classmethod的基本概念 在常用的Python方法中,我们调用类的方法,每次都需要进行实例化,然后用实例化.方法进行调用。Python方法@staticmethod和@classmethod,可以被类直接调用,也可以被所有实例化对象共享。只要在某个方法前面加上@staticmethod或@classmethod就可以了,该方法通过调用staticmethod并且这样子还有利于组织代码,把某些应该属于某个类的函数给放到那个类里去,同时有利于命名空间的整洁。
二、@staticmethod和@classmethod的区别 两种方法的区别
既然@staticmethod和@classmethod都可以直接类名.方法名()来调用,那他们之间又有什么区别呢?别急,看下面
首先 staticmethod(静态方法),需要一个装饰器语法(@staticmethod)将一个普通方法转换为静态方法classmethod(类方法),需要一个装饰器语法(@classmethod)将一个普通方法转换为类方法然后 @staticmethod不需要表示自身对象的self和自身类的cls参数,就跟使用函数一样。@classmethod也不需要self参数,但第一个参数需要是表示自身类的cls参数。最后 @staticmethod没有表示自身对象的self参数和自身类的cls参数,所以如果在@staticmethod中要调用到这个类的一些属性方法,如果我们使用实例化对象.方法名的时候,实例被忽略而类被使用,所以实际上还是类调用。而@classmethod因为有cls参数,当然是可以实例化对象.方法名,来避免硬编码。 三、@classmethod的应用场景 @classmethod 是 Python 中的一个装饰器(decorator),用于定义类方法。类方法是与类相关联的方法,而不是与类的实例相关联的方法。类方法在调用时,第一个参数是类本身,通常将其命名为 cls。使用 @classmethod 装饰器可以让 Python 解释器知道这是一个类方法,从而正确地处理它。
类方法可以通过类名调用,也可以通过类的实例调用。当使用类名调用类方法时,会自动将类作为第一个参数传递给方法。当使用类的实例调用类方法时,同样会自动将类作为第一个参数传递给方法。
四、@staticmethod的应用场景 @staticmethod也是一个Python中的装饰器(decorator),用于标记一个静态方法。
静态方法是一种在类中定义的方法,它与实例无关,因此可以在不创建类实例的情况下调用。与普通方法不同,静态方法没有self参数,因此它不能访问实例属性和方法。
在Python中,使用@staticmethod装饰器可以将一个方法转换为静态方法,即使该方法定义在类中。使用静态方法的主要优点是可以在不创建类实例的情况下调用该方法,从而提高代码的灵活性和可重用性。
五、代码实现和对比 5.1 不使用@staticmethod和@classmethod class Cat: def __init__(self,i): print('__init__: %d'%i) @staticmethod def eat(): print('@staticmethod不需要self参数,实例调用函数实例不传入做参数') c = Cat(1) Cat.eat() 输出结果:
__init__: 1 @staticmethod不需要self参数,实例调用函数实例不传入做参数 5.2 使用@classmethod class Cat: def __init__(self,i): print('__init__: %d'%i) @classmethod def eat(cls): print('@classmethod也不需要self参数,但第一个参数需要是表示自身类的cls参数') c = Cat(1) Cat.
记录@ConfigurationProperties注解注入集合配置的报错 分析总结 分析 现象:项目中使用@ConfigurationProperties(prefix = “xxx”)注入配置类中存在集合成员变量时,项目启动报错
分析:网上查到都说yml配置存在空格的问题,但是本人项目是使用的properties文件,所以排除,在本地写测试代码复现这个报错,启动项目报错如下
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled. 2023-03-28 18:00:03.559 ERROR 14660 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPLICATION FAILED TO START *************************** Description: Binding to target [Bindable@5b44318 type = java.util.List<com.tcxm.panda.demo.controller.HostConfig>, value = 'provided', annotations = array<Annotation>[[empty]]] failed: Property: test.host[0].charset Value: UTF-8 Origin: class path resource [application.properties] - 4:24 Reason: The elements [test.host[0].charset,test.host[0].desc,test.host[0].ip,test.host[0].port] were left unbound. Property: test.
模块配置的基本流程
1)general:主要是一些使能开关的配置,如Adc_ReadGroup Api,此功能如果禁用则无法实现正常的ADC功能;
2)时钟和使能:一般来说模块的时钟和使能都在MCU进行配置,时钟的配置依据需参考S32DS的clock选项,以ADC模块为例,适配时钟为系统时钟(CORE CLOCK),在当前配置下为128兆hz,同时模块的使用需要在MCU进行使能,将不需要的模块或硬件资源禁能,提升CPU效率且降低能耗
各模块时钟源选择
MCU时钟配置选项卡
模块使能与禁能
3)中断设置:部分模块在执行相关功能时需要对中断(通知)函数进行配置,这部分在platform内进行配置,中断通知函数配置方式有两种:
法一:先使能中断,在generic isr setting中对调用的中断通知函数进行申明;
法二:使能中断,然后使用代码install 中断通知函数
中断使能
法一的中断使用方法
法二的中断使用方法
4)时钟参考点:部分模块需要使用的时钟,但是没有直接配置时钟,而是以参考点的形式使用时钟,在MCU设置时钟参考点,时钟参考点设置的依据同样来源于clock配置
5)硬件和软件抽象:这部分是模块配置的核心部分,需要将AUTOSAR抽象的软件接口或定义绑定到硬件资源。
首先说一句不要靠近word,会变得不幸。最好用latex写,不过我当时懒得下载latex了,于是后期改格式花了点时间
写论文之前 事先把所有的论文都查好并且整理好,论文第一、二章写起来就会很快;
把实验做顺溜,实验过程理顺溜,论文第3.4.5章就会写得很快。(主要工作章)
写作 把论文中每一章、每一节、每一小节的逻辑理清楚,写起来就很快了。在吃饭路上好好理理自己这一小节要怎么写,先写什么再写什么、怎么引出xx、怎么过渡,想好之后语音转文字记录下来,写的时候照着这个思路写就完事了总分结构,每一小节先总体介绍该小节内容,再详细介绍。这样审稿人读起来比较顺畅。图在文字前面,审稿人喜欢先看图再看文字,对照着图看文字多用(1)(2)这样的序号,比“首先其次”要清晰一点,对审稿人友好 查重 paperyy每天中午11:11 - 11:22 免费paperyy创建班级,邀请10人或是班级人满,会有两次免费查重机会学信网有一次免费查重机会 我的情况是,第一次用paperyy查,结果paperyy把前面的独创性声明都查了,7.6%,然后稍微改了一下,用学信网万方查(只查了摘要+正文),1.6%,又用paperyy查(只查了摘要+正文),5.2%。删掉了350字抄书的内容就交上去了,最后学校知网查重2.6%
降重 字多,直接删掉重复部分
格式 一般学校都会有《学位论文撰写规范》文档的,格式已经调好,直接写就完事
参考文献 参考文献格式 英文文献+英文著作:Google学术
中文文献:中国知网
中文著作:百度学术
Word在引用3个及以上参考文献的时候如何合并 Word在引用3个及以上参考文献的时候如何合并
引用参考文献与自动更新 先在【参考文献】这一章把参考文献格式弄顺溜,再 插入-(链接)交叉引用 - 找到自己要引用的参考文献
参考文献编号发生变化后更新:选中 - 右键 - 更新域
注意如果要在当前参考文献前面插入新文献,比如在【1】后面插入新文献,应该是在①处回车,而不是②处回车!①处回车相当于插入新的参考文献,②处回车相当于修改当前参考文献【2】为新内容
伪代码 使用Overleaf在毕业论文中插入算法伪代码,高效美观
流程图 用PPT画,复制,在word粘贴为图片;或者QQ长截图
图片大小调为一致 点击一个图片,设置好图片大小,然后对其他图片按CTRL+Y,这个快捷键意思是重复上一次操作,不同电脑快捷键可能不一样
改论文时要修改词汇:直接查找替换CTRL+H 论文图表自动编号,引用自动更新 论文图片/表格自动编号-引用自动更新 - 知乎 (zhihu.com)
图一-1改为图1-1 方法1 等最后确定了不会再加图片的时候,查找替换将图 一-1改为图1-1,对word锁定域(快捷键CTRL+f11),这样导出成PDF也不会更新域
方法2 切换域代码,将
图 { STYLEREF 1 \s }-{ SEQ 图 \* ARABIC \s 1 } 改为
图 1-{ SEQ 图1- \* ARABIC \s 1 } 缺点是:改了之后就不能交叉引用了,所以需要交叉引用之后改,改完后交叉引用会自动更新
目录
JQuery介绍
1.1 JQuery概述
1.2 JQuery框架的引入
1.3 JQuery的优势
1.4 JQuery的引入
1.5 演示代码树状图:
1.6 具体代码演示 01-Dom对象与Jquery包装对象.html
02-Jquery基础选择器.html
03-Jquery层次选择器.html
04-Jquery表单选择器.html
05-Jquery操作元素的属性.html
06-Jquery操作元素的样式.html
07-Jquery操作元素的内容.html
08-Jquery创建元素和添加元素.html
09-Jquery删除元素和遍历元素.html
10-Jquery-ready加载事件.html
11-Jquery绑定事件.html
一、JQuery介绍 1.1 JQuery概述 JQuery是一个简洁快速的JavaScript框架。jQuery的设计宗旨是“write less,do more”,倡导写更少的代码,做更多的事。jQuery封装了一些常用的JavaScript的代码,提供了一套易于使用的API,实现了跨浏览器工作,使HTML文档的遍历操作、事件处理、动画设计和Ajax交互操作变得简单易行。
1.2 JQuery框架的引入 JQuery的官方地址:htttp://www.jquery.com
1.3 JQuery的优势 一款轻量级的JS框架。jQuery核心js文件才几十kb,不会影响页面加载速度。丰富的DOM选择器,jQuery的选择器用起来很方便,比如要找到某个DOM对象的相邻元素,JS可能要写好几行代码,而jQuery一行代码就搞定了,再比如要将一个表格的隔行变色,jQuery也是一行代码搞定。链式表达式。jQuery的链式操作可以把多个操作写在一行代码里,更加简洁。事件、样式、动画支持。jQuery还简化了js操作css的代码,并且代码的可读性也比js要强。Ajax操作支持。jQuery简化了AJAX操作,后端只需返回一个JSON格式的字符串就能完成与前端的通信。跨浏览器兼容。jQuery基本兼容了现在主流的浏览器,不用再为浏览器的兼容问题而伤透脑筋。插件扩展开发。jQuery有着丰富的第三方的插件,例如:树形菜单、日期控件、图片切换插件、弹出窗口等等基本前端页面上的组件都有对应插件,并且用jQuery插件做出来的效果很炫,并且可以根据自己需要去改写和封装插件,简单实用。 1.4 JQuery的引入 方式一:导入本地Jquery
在需要使用jQuery的地方以js引入方式引入(本地导入)
<script type="text/javascipt" src="jquery-x-x-x.js"></script>
注:src路径位置为你本机JQuery存放地址
方式二:导入在线Jquery
我们可以通过在script的src属性中写一个网址来导入在线的jquery代码。 事实上,现在应用jquery的网站非常非常多,浏览器会在加载之前使用jquery的网站时就预先下载过jquery,因此到了我们这里就不用再次下载了,就算我们的jquery版本是一个新的没被浏览器加载过的版本,jquery的代码下载也会进行的很快,不过,如果你还是担心影响加载速度,本地导入jquery文件确实是最好的办法。
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script>//在此书写你的jquery代码 </script>
1.5 演示代码树状图: 1.6 具体代码演示 01-Dom对象与Jquery包装对象.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Dom对象与Jquery包装对象</title> </head> <body> <!-- Dom对象 通过js方式获取的元素对象(document) Jquery对象 通过jquery的核心js文件,返回的是jquery包装集 --> <div id="
系列文章目录 参考我的opencv配置博客
参考我的orbslam3配置博客
文章目录 系列文章目录前言一、电脑EdgeSlam安装配置1.错误12.错误23.错误34.错误4 二、jetson nano安装ORB SLAM31、jetson nano问题问题1问题2 2、jetson nano的自带opencv问题1.卸载opencv3.3.02.安装opencv4.4.0 3、ros问题问题1 4、orbslam3问题1.问题12.问题2 5、zed问题问题1问题2 三、jetson nano EdgeSlam安装测试1、测试1.在移动设备上2.在边缘设备上3.IP和端口号通信 四、ORB_SLAM3调整1、更新cv_bridge报错1报错2 2、编译调用报错1报错2报错3 AdapSLAM实现安装步骤报错1:报错2:报错3:报错4:重装ROS 前言 众所周知,视觉 SLAM 在内存和处理时间方面是资源密集型的。此外,一些操作随着时间的推移变得越来越复杂,这使得在移动设备上连续运行变得具有挑战性。边缘计算为移动设备提供额外的计算和内存资源,以允许卸载某些任务,而不会出现卸载到云时出现的大延迟。 Edge-SLAM是一种使用边缘计算资源来卸载部分 Visual-SLAM 的系统。使用 ORB-SLAM3 作为原型 Visual-SLAM 系统,并将其修改为边缘和移动设备之间的分离架构。将跟踪计算保留在移动设备上,并将其余计算(即局部映射和闭环)移动到边缘,可以允许 Visual-SLAM 系统在资源有限的情况下长期运行,而不会影响操作的准确性。它还使移动设备上的计算和内存成本保持不变,这将允许部署其他使用 Visual-SLAM 的终端应用程序。
Edge-SLAM 是一种边缘辅助视觉同步定位和建图。Edge-SLAM 将 Visual-SLAM 适配到边缘计算架构中,以实现 Visual-SLAM 在移动设备上的长时间运行。这是通过将计算密集型模块卸载到边缘来实现的。因此,Edge-SLAM 减少了移动设备上的资源使用并保持不变。Edge-SLAM 是在ORB-SLAM2之上实现的。
我本来构思自己该怎么去实现的,后来逛github时发现了一个新项目AdapSLAM,发现有人和我的想法不谋而合且思路更成熟并已实现,真np啊。
EdgeSlam源码
EdgeSlam论文
一、电脑EdgeSlam安装配置 安装EdgeSlam前先安装好ORB-SLAM3
1.错误1 执行build.sh最后的
cmake .. -DCMAKE_BUILD_TYPE=Release 出现:
Found package configuration file:
/usr/local/lib/cmake/Pangolin/PangolinConfig.cmake
but it set Pangolin_FOUND to FALSE so package “Pangolin” is considered to
📚故事背景:最近在开发一个python的脚本 🌲,闲着没事就研究了一下如何将python项目部署上线, 📝记录一下自己踩过的坑,希望本片文章可以帮助到你 👍。 🔧使用工具: 1、Pycharm 2、阿里云服务器 0️⃣打包Python项目 1、打开pycharm终端,在需要打包的目录下,输入:
pip freeze > requirements.txt 2、检查目录下是否有requirements.txt文件,有则成功。
3、将需要打包的目录压缩成zip格式,一定要是zip格式,linux系统不支持rar格式的压缩文件。
注意:(1)我的根文件叫website,其中还有个website文件夹。第一个website是我的项目名字,可随意更改。第二个website是不可以修改名字的,存储的是django的必需文件。(2)还有一个注意点,如果你是python web的项目,那么需要将settings.py中的ALLOWED_HOSTS = []改为ALLOWED_HOSTS = ['*']。否则打开网页会出现报错提示,是django的自带安全机制。
python文件打包成功
🎈则此步完成🎈
1️⃣领取并配置阿里云免费服务器 1、避免文章过长,具体步骤撰写于此博客:学生免费领取、配置阿里云服务器_GarsonW的博客-CSDN博客
2️⃣上传python压缩包到云服务器 1、点击远程连接云服务器。(位置在实例右侧操作下方)
2、立即登陆。
3、根据需求设置密码,并且登陆。
4、文件,打开新文件树。
5、将之前打包的python项目.zip文件上传到/home/目录中。
6、解压zip文件:在命令行中输入。
unzip /home/你的项目名称.zip 例如:unzip /home/website.zip 7、项目会自动解压到/root/中,我的项目解压完目录为/root/website。
python项目完整在服务器上出现
🎈则此步骤成功🎈
3️⃣配置Anaconda 👍因为服务器配置Anaconda和windows上一致,所以不多赘述。提供以下资料辅助。 1、避免文章过长,具体指令撰写于此博客:Linux/Windows服务器Anaconda指令
2、可能输入conda指令会出现conda:command not found错误。解决方法:[Linux] 解决conda: command not found
当我们可以顺利的创建conda虚拟环境
🎈则此步骤成功🎈
4️⃣配置云服务器端口 1、打开云服务器的防火墙对应 (如:4321) 端口。打开了对应的端口别人才可以访问。具体指令:Linux服务器防火墙指令_GarsonW的博客-CSDN博客
❗注意:安全组中的对应端口 (如:4321) 也需要配置!!
2、使用nohup挂载python应用。
❗注意:挂载的地址是0.0.0.0,端口号是之前设置的端口号,我的是4321
nohup python manage.py runserver 0.0.0.0:4321 & 3、输入命令,查询端口是否挂载应用。
netstat -ntulp 5、访问网络,输入对应ip与端口号进行访问。
文章目录 前言一、遇到的问题二、解决办法1. 明确方向2. 解决方法① 方案一② 方案二③ 方案三 三、原因及相关原理1. 为什么需要require方法2. 为什么require方法失效了3. new URL() 为什么就可以4. Vite插件介绍 总结扩展阅读 前言 Vite是一种轻量快速的前端构建工具,能够显著提升前端开发体验,而且官方已经发布v4版本,相对比较稳定。在把VueCli搭建的项目迁移到Vite的过程中遇到了个问题,下面分享一下问题及解决办法。
一、遇到的问题 在script标签里面引入的图片资源没生效,然后一看控制台,报错显示 require is not defined …
二、解决办法 1. 明确方向 经过查找Vite相关文档,看到官方文档静态资源处理目录,发现需要使用new URL()这个方法才能处理动态引入的URL,才能保证图片资源在经过打包和资源哈希后仍指向正确的地址。
2. 解决方法 ① 方案一 既然如此,那么直接改为new URL() 的写法。
原本写法是:
url: require("../assets/images/banner@2x.png"), 那么使用 new URL() 的写法: url: new URL(`../assets/images/banner@2x.png`, import.meta.url).href; 或者是 import 的写法 : import banner from "../assets/images/banner@2x.png"; url: banner, ② 方案二 由于上面的方法都要一个个修改过于麻烦了,而且项目图片都位于src/assets/images/下,那么直接封装成一个函数,像hooks那样调用应该方便很多。
在utils文件下下新建useImgUrl.js文件,简简单单,只需要传入图片文件名及类型即可 const getImgUrl = file => { return new URL(`.
文章目录 一、创建drag.js文件
二、使用步骤
1.全局使用,在main.js中引入drag
2.代码中使用
一、创建drag.js文件 import Vue from 'vue' // 自定义指令使弹窗可拖动 // 使用方式: <a-modal v-drag-modal destroyOnClose V-model="a"></a-modal> // 加上v-drag-modal 一定要加上destroyoncLose属性,否则弹窗不会回到初始位置 Vue.directive('drag-modal', (el, bindings, vnode) => { Vue.nextTick(() => { let { visible, destroyOnClose } = vnode.componentInstance // 防止未定义 destroyOnClose 关闭弹窗时dom未被销毁,指令被重复调用 if (!visible) return let modal = el.getElementsByClassName('ant-modal')[0] let header = el.getElementsByClassName('ant-modal-header')[0] let footer = el.getElementsByClassName('ant-modal-footer')[0] let left = 0 let top = 0 // 未定义 destroyOnClose 时,dom未被销毁,关闭弹窗再次打开,弹窗会停留在上一次拖动的位置 if (!
一、简单介绍 1. 自编码器 自动编码器(AE)的结构与原理:
由编码器和解码器组成,编码器和解码器通常是神经网络模型。
输入的数据经过神经网络降维到一个编码,再通过一个神经网络去解码得到一个与输入原始数据一模一样的生成数据,然后通过比较这两个数据去最小化它们之间的差异来训练编码器和解码器的参数。
自动编码器特点:
与数据相关程度高,因为使用神经网络提取的特征一般是与原始训练集高度相关,意味着自动编码器只能压缩与训练数据相似的数据。压缩数据是有损的。因为在降维的过程中不可避免的要丢失信息。 自动编码器的应用:
数据去噪;可视化降维;生成数据。 2. 变分自编码器VAE 2.1 VAE简介 变分自动编码器(VAE):
在自动编码器中需要输入一张图片,然后将图片编码之后得到隐含向量,隐含向量解码得到与原始图片对应的照片。
变分自动编码器可以自己去构造隐藏向量,生成任意图片,只需要给它一个标准正态分布的随机隐含向量,通过解码器就能够生成想要的图片,而不需要给它一个原始的图片。实际情况中需要在准确率与隐含向量服从标准正态分布之间去做一个权衡。KL divergence可以用来权衡两者分布的相似程度。越小表示两种概率分布越接近。
可变自动编码器能够通过正则化潜在空间,使其像下面这样连续地生成新的数据,因此,允许在不同属性之间实现平滑的插值,并消除可能返回不理想输出的间隙。
可变自动编码器以概率方式(分布)编码输入的潜在属性,而不是像普通的自动编码器那样以确定性方式(单值)编码。
2.2 VAE结构 VAE在AE的基础上对均值的encoder添加高斯噪声(正态分布的随机采样),使得decoder(就是右边那个生成器)有噪声鲁棒性;为了防止噪声消失,将所有 p(Z|X) 趋近于标准正态分布,将encoder的均值尽量降为 0,而将方差尽量保持住。这样一来,当decoder训练的不好的时候,整个体系就可以降低噪声;当decoder逐渐拟合的时候,就会增加噪声。
3. 生成对抗网络 GAN 生成对抗网络(Generative Adversarial Networks,GANs)结构与原理:
GANs由生成模型和对抗模型两部分组成。自动编码器就是一般的生成模型。对抗模型就是一个判断真假的判别器。
在训练的时候,先训练判别器。将假的和真的数据都给判别器,优化判别模型。然后训练生成器,具体做法就是固定判别器的参数,通过反向传播优化生成器的参数,希望它得到数据在经过判别器后结果尽可能地接近1,这时只需要通过调整损失函数就可以了。JS Divergence是对称的,它能够用于衡量两种分布之间的差异。
VAE和GAN的本质都是概率分布的映射
CycleGAN CycleGAN可以看做是2个GAN的融合,一个GAN由生成器G和判别器DY构成,实现从X域到Y域的图像生成和判别;另一个GAN由生成器F和判别器DX构成,实现从Y域到X域的图像生成和判别,两个网络构成循环(cycle)的过程。
4. 扩散模型 扩散模型 是受非平衡热力学的启发。它们定义一个扩散步骤的马尔可夫链,逐渐向数据添加随机噪声,然后学习逆扩散过程,从噪声中构建所需的数据样本。与VAE或流动模型不同,扩散模型是用固定的程序学习的,而且隐变量具有高维度(与原始数据相同)。
马尔科夫链的性质:平稳性。一个概率分布如果随时间变化,那么在马尔可夫链的作用下,它一定会趋于某种平稳分布(例如高斯分布)。只要终止时间足够长,概率分布就会趋近于这个平稳分布。并且,基于马尔可夫链的前向过程,其每一个epoch的逆过程都可以近似为高斯分布。高斯分布是一种很简单的分布,运算量小,这一点是diffusion快的最重要原因。
文本生成,Li X L, Thickstun J, Gulrajani I, et al. Diffusion-LM Improves Controllable Text Generation[J]. arXiv preprint arXiv:2205.14217, 2022.少样本条件生成,Sinha A, Song J, Meng C, et al. D2c: Diffusion-decoding models for few-shot conditional generation[J].
系统架构 随着互联网的发展,网站应用的规模也在不断的扩大,进而导致系统架构也在不断的进行变化。 从互联网早起到现在,系统架构大体经历了下面几个过程: 单体应用架构--->集群应用架构--->垂直应用架构--->SOA 架构--->微服务架构. 单体应用架构 集群应用架构 垂直应用架构 SOA 架构 微服务架构介绍 微服务架构有哪些优势 独立开发 – 所有微服务都可以根据各自的功能轻松开发 独立部署 – 基于其服务,可以在任何应用程序中单独部署它们 故障隔离 – 即使应用程序的一项服务不起作用,系统仍可继续运行 混合技术堆栈 – 可以使用不同的语言和技术来构建同一应用程序的不同服务 粒度缩放 – 单个组件可根据需要进行缩放,无需将所有组件缩放在一起 微服务架构的常见问题 一旦采用微服务系统架构,就势必会遇到这样几个问题: 这么多小服务,如何管理他们? 这么多小服务,他们之间如何通讯? 这么多小服务,客户端怎么访问他们? 这么多小服务,一旦出现问题了,应该如何自处理? 这么多小服务,一旦出现问题了,应该如何排错? 对于上面的问题,是任何一个微服务设计者都不能绕过去的,因此大部分的微服务产品都针对每一个问题提供了相应的组件来解决它们。 微服务架构的常见概念 服务治理 :服务治理就是进行服务的自动化管理,其核心是服务的自动注册与发现。 服务注册: 服务实例将自身服务信息注册到注册中心。 服务发现: 服务实例通过注册中心,获取到注册到其中的服务实例的信息,通过这些信息去请求它们提 供的服务。 服务剔除: 服务注册中心将出问题的服务自动剔除到可用列表之外,使其不会被调用到。 服务调用 在微服务架构中,通常存在多个服务之间的远程调用的需求。 目前主流的远程调用技术有基于 HTTP 的 RESTful 接口以及基于 TCP 的 RPC协议。 REST(Representational State Transfer) 这是一种 HTTP 调用的格式,更标准,更通用,无论哪种语言都支持 http 协议. RPC(Remote Promote Call) 一种进程间通信方式。允许像调用本地服务一样调用远程服务。RPC 框架的主要目标就是让远程服 务调用更简单、透明。RPC框架负责屏蔽底层的传输方式、序列化方式和通信细节。开发人员在使 用的时候只需要了解谁在什么位置提供了什么样的远程服务接口即可,并不需要关心底层通信细节 和调用过程。 服务网关 随着微服务的不断增多,不同的微服务一般会有不同的网络地址,而外部客户端可能需要调用多个服务的接口才能完成一个业务需求,如果让客户端直接与各个微服务通信可能出现: 客户端需要调用不同的 url 地址,增加难度 在一定的场景下,存在跨域请求的问题 每个微服务都需要进行单独的身份认证 针对这些问题,API 网关顺势而生。 API 网关直面意思是将所有 API 调用统一接入到 API 网关层,由网关层统一接入和输出。 一个网关的 基本功能有:统一接入、安全防护、协议适配、流量管控、长短链接支持、容错能力。有了网关之后, 各个 API 服务提供团队可以专注于自己的的业务逻辑处理,而 API 网关更专注于安全、流量、路由等问题。 服务容错 在微服务当中,一个请求经常会涉及到调用几个服务,如果其中某个服务不可用,没有做服务容错 的话,极有可能会造成一连串的服务不可用,这就是雪崩效应。 我们没法预防雪崩效应的发生,只能尽可能去做好容错。 链路追踪 随着微服务架构的流行,服务按照不同的维度进行拆分,一次请求往往需要涉及到多个服务。互联 网应用构建在不同的软件模块集上,这些软件模块,有可能是由不同的团队开发、可能使用不同的编程 语言来实现、有可能布在了几千台服务器,横跨多个不同的数据中心。因此,就需要对一次请求涉及的 多个服务链路进行日志记录,性能监控即链路追踪.
pytorch中的to_tensor会对图像进行归一化操作 lr处理前:
lr处理后:
pytorch中的to_tensor会对图像进行归一化操作
解释说明:
https://blog.csdn.net/qimo601/article/details/112526722?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522167998895316800215012387%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=167998895316800215012387&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_ecpm_v1~rank_v31_ecpm-1-112526722-null-null.142v76insert_down38,201v4add_ask,239v2insert_chatgpt&utm_term=pytorch%E4%B8%AD%E7%9A%84to_tensor%E6%9C%89%E5%BD%92%E4%B8%80%E5%8C%96%E7%9A%84%E4%BD%9C%E7%94%A8%EF%BC%9F&spm=1018.2226.3001.4187
PB通过SatWeb可以轻松开发BS程序,SatWeb集成了登录、用户管理、菜单管理、权限管理等模块。只需要简单配置即可实现数据窗口所见即所得支持增删查改等操作
特性
主体是纯H5页面,运行在浏览器中用户无需了解html、css, 通过配置就可以快速开发BS支持集成H5DW, 实现用户自定义复杂表单和报表通过H5DW实现数据窗口转为html5方便快速将现有的CS程序Web化 #下载地址:
群文件下载 SatRDA_V2023XXXX
QQ群:836173975 PB的数据窗口可以直接显示在Html,所见即所得支持增删查改等操作。流程如下:
在PB中导出数据窗口到特定的目录通过框架的菜单管理添加菜单,并设置权限配置数据窗口需要操作的数据库(可选) 说明: 示例默认连接satrda中配置的名称为erp的数据库, 如果需要连接其它数据库,修改server/plugins/erp/h5dw.js中的数据库名
#导出数据窗口 在PB中选择要使用的数据窗口,编辑好后,找到数据窗口点右键,export保存地址选择server/plugins/data/ 目录下 说明: 示例的数据窗口名称为d_test1,前端页面请求报表文件时,插件代码会查找该目录的报表
#添加菜单 在菜单管理模块可以添加菜单,我们以添加一个显示数据窗口的菜单为例,演示如何添加菜单。
打开菜单管理,点击新增按钮,弹出增加菜单界面。分别选择菜单图标,输入菜单名称、显示排序、路由地址。 点击确定在新增加的菜单行,点击该菜单右边的增加按钮,新增菜单。 在添加菜单界面录入如下: 组件路径 : amis 路由地址 : /data/page/testdw.js&dw=d_test1
提示: 组件路径必须填amis,表示加载amis配置。程序打开后,会加载/data/page/testdw.js的配置界面, 可以自行参考amis文档进行界面配置,testdwjs会根据传入的参数dw=d_test1调用接口获取导出的d_test1数据窗口
刷新浏览器后可以看到左侧增加了菜单,点击菜单看到界面:
到这里已经完成了一个完整表单的功能,并实现了新增、删除、查询、保存等操作。不需要任何代码,非常简单。
目录
一、如何在Vue中引入基础高德地图
步骤一:注册并登录高德地图开发平台,申请密钥编辑
步骤二:安装高德地图加载器
二、 项目效果图
三、完整项目代码 1、子组件 position.vue(看这个)
2.在父组件引入position.vue
四、总结-------项目避坑(踩坑)
1、第一个坑:因为我用的element-ui的dialog组件,vue 页面或者弹窗使用 高德地图组件 map组件 不能加载 。
2、第2个坑 搜索的时候 关键字列表出不来
3、补充知识点:Z-index属性详解
一、如何在Vue中引入基础高德地图 根据官网提示,在Web端,我们需要高德地图加载器:npm i @amap/amap-jsapi-loader -S 步骤一:注册并登录高德地图开发平台,申请密钥 步骤二:安装高德地图加载器 npm i @amap/amap-jsapi-loader -S 二、 项目效果图 三、完整项目代码 1、子组件 position.vue(看这个) <template> <div> <el-dialog :close-on-click-modal="false" title="选取打卡地址" :visible="positionDialog" :before-close="closePositionDialog" @close="closePositionDialog" append-to-body width="800px" > <div class="content"> <div class="search-box"> <div class="label">关键字搜索</div> <el-input v-model="input" placeholder="请输入内容" id="tipinput" ></el-input> </div> <div ref="map" id="map-container"></div> </div> <span slot="footer"> <el-button @click="closePositionDialog" size="medium">取消</el-button> <el-button type="
1. 前言
本篇文章我们讲解下关于https及证书的相关知识,因为我发现不理解证书感觉很难理解https,所以本篇会花大量的篇幅来讲证书,我们一开始会讲解一些相关概念帮助大家理解下,然后我们自己签发一个证书来理解这个过程,最后通过实例和抓包帮助大家理解https。因为本篇文章有很多代码及配置文件相关,最好通过电脑打开查看,篇幅很长,感谢耐心。
2. 概念区分
见到https时就会有很多不知道的概念,我们这里来区分下:
HTTPS:https即为http及其下边一层的可靠的安全加密的传输协议(tls/ssl),它主要思想是传输的双发验证对端的证书是否可以通过(被信任),以此生成加密的密钥,通过此密钥加密传输的内容,后边会详解。
SSL:Secure Socket Layer, 安全套接字层,http层下新增加的这一层构成了https
TLS:Transport Layer Security,同样是为了保证数据安全的加密协议层,是SSL的增强版,SSL有1.0,2.0,3.0版本,TLS目前1.0,1.1,1.2,1.3,TLS的1.0版本就是SSL的3.0
Key:https中有公钥和私钥,用公钥加密的内容,可以使用私钥解密,反之亦然,不过我们平常所说的key文件是指私钥文件
CRT: certificate证书文件,是证书机构颁发的保证安全通信的文件,由域名、公司信息、序列号和签名信息等组成
CER:也是证书文件,和CRT相比只是缩写不同,CRT缩写常见于类uninx系统,CER缩写常见于windows系统
X.509:这里特指颁发的证书的格式,而其根据不同的编码格式分为PEM和DER:
PEM - Privacy Enhanced Mail,打开看文本格式,以"-----BEGIN…"开头, "-----END…"结尾,内容是BASE64编码.Apache和*NIX服务器偏向于使用这种编码格式,这种也是我们所常见的
DER - Distinguished Encoding Rules,打开是二进制格式,不可读.Java和Windows服务器偏向于使用这种编码格式
CSR:Certificate Signing Request 证书签名请求,里面包含公钥等个体信息,这个发给公证机构作为申请,通过这个公证机构颁发证书给你
CA:Catificate Authority 证书颁发机构,它的作用就是给各个用户签发证书等,比如说Symantec、Comodo、Godaddy、GolbalSign 和 Digicert等
openssl:相当于SSL的一个实现,如果把SSL规范看成OO中的接口,那么OpenSSL则认为是接口的实现,个人理解openssl是作为针对SSL/TLS的一个工具,包括对证书的解析,个人颁发,证书编码转化等
3. CA和证书颁发
使用https进行通信,就需要一个证书,那么证书哪里来,就是来自于CA(证书颁发机构)颁发。所谓证书就是比较有公信的机构颁发给你,然后你用他来进行通信,另外一端验证通过后就会信任你,进行信息通信。举例来说如果你的服务器没有证书,浏览器访问你的网址时,会提示不安全。
那么如果有一个服务器,如何才能获取到证书呢,如果要从证书颁发机构申请的话,需要提供CSR文件及钱,然后机构就会颁发证书给你。如果你想要自己给自己颁发,只是用来本地玩玩,或者局域网各个机器之间的相互交流,便可以自己建立一个CA,使用这个CA来给自己颁发证书。我们下面以给自己颁发证书的全过程来描述下,我们使用openssl来进行构建。
CA角色也是需要一个自身的pair,pair包括key(private)和certificate,而最原始的被称为root pair,通常情况下,root CA 不会直接为服务器或者客户端签证,它们会先为自己生成几个中间 CA(intermediate CAs),这几个中间 CA 作为 root CA 的代表为服务器和客户端签证。自己实操的过程中其实也可以直接使用root pair来给服务器签发,为了演示全面,我们来使用intermediate CA来签发证书。
3.1 新建目录:
$ cd /etc/pki/ $ mkdir leap && cd leap $ mkdir ca && cd ca 3.
首先申明下,本文为笔者学习《Eclipse插件开发学习笔记》的笔记,并加入笔者自己的理解和归纳总结。
1. 创建引导页 扩展点【org.eclipse.ui.newWizards】
在【org.eclipse.ui.newWizards】中添加【wizard】,在【class】中指定向导页类,继承INewWizard类。
<extension point="org.eclipse.ui.newWizards"> <wizard class="com.plugin.blog.demo.wizard.DemoNewWizard" icon="icons/icon_add.png" id="com.plugin.blog.demo.wizard.DemoNewWizard" name="DemoNew"> </wizard> </extension> DemoNewWizard类
public class DemoNewWizard extends Wizard implements INewWizard { private IWorkbench mWorkbench; public DemoNewWizard() { setWindowTitle("新建Demo"); } @Override public boolean performFinish() { return false; } @Override public void init(IWorkbench workbench, IStructuredSelection selection) { mWorkbench = workbench; } } 2. 打开向导页 在菜单【File】->【New】->【Other…】
可以在菜单中调用代码直接打开
DemoNewWizard wizard = new DemoNewWizard(); wizard.init(mViewPart.getSite().getWorkbenchWindow().getWorkbench(), null); WizardDialog dialog = new WizardDialog(mViewPart.getSite().getShell(), wizard); dialog.
前言 在之前的「基于声网 Flutter SDK 实现多人视频通话」里,我们通过 Flutter + 声网 SDK 完美实现了跨平台和多人视频通话的效果,那么本篇我们将在之前例子的基础上进阶介绍一些常用的特效功能,包括虚拟背景、色彩增强、空间音频、基础变声功能。
本篇主要带你了解 SDK 里几个实用的 API 实现,相对简单。
01 虚拟背景 虚拟背景是视频会议里最常见的特效之一,在声网 SDK 里可以通过enableVirtualBackground方法启动虚拟背景支持(点击这里查看虚拟背景接口文档)。
首先,因为我们是在 Flutter 里使用,所以我们可以在 Flutter 里放一张assets/bg.jpg图片作为背景,这里有两个需要注意的点:
assets/bg.jpg图片需要在pubspec.yaml文件下的assets添加引用 assets: - assets/bg.jpg 需要在pubspec.yaml文件下添加path_provider: ^2.0.8和path: ^1.8.2依赖,因为我们需要把图片保存在 App 本地路径下 如下代码所示,首先我们通过 Flutter 内的rootBundle读取到bg.jpg,然后将其转化为bytes, 之后调用getApplicationDocumentsDirectory获取路径,保存在的应用的/data"目录下,然后就可以把图片路径配置给enableVirtualBackground方法的source,从而加载虚拟背景。
Future<void> _enableVirtualBackground() async { ByteData data = await rootBundle.load("assets/bg.jpg"); List<int> bytes = data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes); Directory appDocDir = await getApplicationDocumentsDirectory(); String p = path.join(appDocDir.path, 'bg.jpg'); final file = File(p); if (!(await file.exists())) { await file.
首先申明下,本文为笔者学习《Eclipse插件开发学习笔记》的笔记,并加入笔者自己的理解和归纳总结。
1. 标准消息对话框 MessageBox可以方便地生成标准消息对话框。
setText()方法设置MessageBox的标题,setMessage()方法设置显示消息。
MessageBox的图标样式,
SWT.ICON_ERROR,显示错误消息。SWT.ICON_WARNING,显示警告消息。SWT.ICON_INFORMATION,显示提示信息。SWT.ICON_WORKING,显示正在进行信息。SWT.ICON_QUESTION,显示问题信息。 MessageBox的按钮样式,默认是SWT.OK。也可以是下列组合,只能选择一种组合或同一组合中几个按钮,否则只会显示确定按钮。
SWT.OK | SWT.CANCEL,确定 | 取消SWT.YES | SWT.NO | SWT.CANCEL,是 | 否 | 取消SWT.ABORT | SWT.RETRY | SWT.IGNORE,中止 | 重试 | 忽略 获取open()方法的返回值,判断用户单击的按钮。
Button defaultButton = new Button(shell, SWT.NONE); defaultButton.setText("MessageBox"); defaultButton.setBounds(10, 10, 150, 25); defaultButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { // 普通消息对话框,默认显示确认按钮 MessageBox mb = new MessageBox(shell, SWT.ICON_SEARCH); mb.setText("MessageBox"); mb.setMessage("MessageBox open, MessageBox open!"); mb.open(); } }); Button okOrCancelButton = new Button(shell, SWT.
Focal and Global Knowledge Distillation for Detectors(CVPR2022) 目标检测中的全局与局部的知识蒸馏
原文链接:https://arxiv.org/abs/2111.11837
代码github:github.com/yzd-v/FGD
文章目录 **Focal and Global Knowledge Distillation for Detectors**(CVPR2022)前要知识:KD(Knowlege Distillation)目标检测(Object Detection) 主要的贡献和方法:Global DistillationFocal Distillation 前要知识: KD(Knowlege Distillation) 目前最流行的模型压缩技术之一,能够满足大模型轻量化部署的要求,并且将大模型的训练效果同步到小模型中,类似于迁移学习,又与迁移学习的迁移内容和流程都不同。数据蒸馏的目前主流的两个方向:模型压缩和模型增强。下图是Hinton知识蒸馏论文中提出的经典教师-学生模型。这里原理不做赘述,可以参考论文原文Distilling the Knowledge in a Neural Network
目前的知识蒸馏集中在Feature-based Distillation,大致意思是将教师模型中的某一层的特征信息提取出来去训练学生模型,那么蒸馏的层怎么进行选取,并且提取出的迁移信息怎么处理都是知识蒸馏目前发展的痛点。
目标检测(Object Detection) 目标检测作为CV最重要的下游任务之一,就将分类和定位集为一体的CV技术,目标检测的模型分为one-stage,two-stage,one stage anchor-based,one stage anchor-free。典型的模型YOLO,FasterRcnn,MaskRcnn等等。特别地,现在很多的目标检测模型都会发布多个参数量的版本号,Large模型自然能识别出更好的效果,但自然而然也带来了硬件上的成本开销和部署的困难,所以目标检测领域也需要将模型压缩放在应用部署的首要位置考虑,因为往往深度学习特别是CV领域,训练和预测是分两步走的,所以训练和预测的硬件差异让更多地轻量化需求得以体现。虽然目标检测的模型的预测头部和模型结构不都相同,但是input都是特征图,每个层进行处理的也是特征图的信息进行输入,所以可以形成一个统一的基于特征的蒸馏方法来实现模型压缩
主要的贡献和方法: 就像题目所说的那样,作者提出了两种不同的蒸馏方式,作者认为在目标检测领域,全局的特征联系关联特征和局部的细节特征感知信息一样重要,所以不仅要关注前景图也要关注背景图。
Global Distillation 借鉴了GCnet中的GCBlock模块来获取全局的上下文关联信息,将教师模型中学习到的关联信息传递给学生模型进行学习
transform模块代码:
##transform模块(学生和教师) ##①1x1conv,通道数/2 ②LN+Relu ③1*1conv,通道数还原 self.channel_add_conv_s = nn.Sequential( nn.Conv2d(teacher_channels, teacher_channels//2, kernel_size=1), nn.LayerNorm([teacher_channels//2, 1, 1]), nn.ReLU(inplace=True), # yapf: disable nn.Conv2d(teacher_channels//2, teacher_channels, kernel_size=1)) self.
使用requests爬取英雄联盟英雄皮肤 自己做的
import requests response = requests.get("https://game.gtimg.cn/images/lol/act/img/js/heroList/hero_list.js") result = response.json() hero_name = [] for x in result['hero']: hero_name.append(x['heroId']) print(hero_name) for y in hero_name: url = f'https://game.gtimg.cn/images/lol/act/img/js/hero/{y}.js' resp = requests.get(url).json() # print(resp) list = resp['skins'] for i in list: name = i['name'] if i['mainImg'] != '': req = requests.get(i['mainImg']) result = req.content try: with open(f'files\heroes\{name}.jpg', 'wb') as f: f.write(result) except FileNotFoundError: name = name.replace('/','1') with open(f'files\heroes\{name}.jpg', 'wb') as f: f.write(result) print("
重定向 在Linux中,标准输入是从键盘读入数据或命令等,标准输出是将命令的结果等输出到屏幕。
类型设备文件路径文件描述符描述标准输入0键盘/proc/self/fd/00从键盘获得输入标准输出1屏幕/proc/self/fd/11输出到屏幕错误输出2屏幕/proc/self/fd/22输出到屏幕 但使用 Linux 终端时,经常需要将命令的输出重定向到文件或其他命令中,这时需要使用到重定向技术。
重定向是一种非常有用的技术,可以将命令的输出从标准输出流发送到文件或其他进程的输入流。
在 Linux 中有三种常见重定向方式:输出重定向、输入重定向和错误重定向。
输出重定向 将某个命令默认指向的输出文件转而指向一个文件,即使得命令输出到某个指定文件中,而不是输出到终端屏幕或终端窗口。
Linux 中使用 > 和 >> 来重定向标准输出。
输出重定向 输出重定向是将命令输出的内容写入到文件或其他进程中。
在 Linux 中,我们可以使用 > 符号来将命令的输出重定向到一个文件中。
如,下面的命令将会把 "s 命令的输出写入到 files.txt 的文件中。
ls > files.txt 若 file.txt 文件不存在,则文件将被创建;否则,文件内容将被强制覆盖。
输出追加重定向 如果想要将输出追加到文件末尾而不是覆盖它,可以使用 >> 符号。
如,下面的命令将会将 ls 命令的输出追加到 files.txt 文件的末尾:
ls >> files.txt 使用重定向在bash中写入文件 有一条有意思的命令是cat >file <<EOF,该命令使用了输出重定向,可以用脚本非交互式的编写文件并显示内容。如:
用户可以一直输入文本,直到输入 "EOF"为止。
输入重定向 输入重定向是将文件的内容发送到命令中,而不是从键盘输入。使用 < 符号来将文件中的内容重定向到命令中。
如,下面的命令将会将 input.txt 文件的内容发送给 sort 命令进行排序:
sort < input.txt 错误重定向 错误重定向是将命令的错误输出重定向到文件或其他进程中。使用 2> 符号将命令的错误输出重定向到文件中。
一、创建一个maven项目 1.file->new->project 2.创建maven项目 3.删除src文件夹 4.在pom.xml文件中引入springboot和cloudAlibaba依赖 <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>2021.0.1</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-alibaba-dependencies</artifactId> <version>2021.0.1.0</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>2.6.3</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.2.0</version> </dependency> </dependencies> </dependencyManagement> 注意:这里springboot和springcloud版本号要相匹配 不清楚可以去官网官网查询
二、创建公共服务(manage-common) 用于放置其他微服务共同的文件资源以及工具类
1.项目名右键->new->Module 2.引入公共依赖 根据自己情况而定
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.22</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.27</version> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> </dependency> <dependency> <groupId>com.
topic 创建/opt/kafka/bin/kafka-topics.sh --create \ --zookeeper zookeeper.example.com \ --replication-factor 1 \ --partitions 1 \ --topic KafkaTopicName 查询/opt/kafka/bin/kafka-topics.sh --list \ --zookeeper zookeeper.example.com:2181 删除/opt/kafka/bin/kafka-topics.sh \ --delete \ --zookeeper zookeeper.example.com:2181 \ --topic KafkaTopicName topic权限: 增加/opt/kafka/bin/kafka-acls.sh \ --authorizer-properties zookeeper.connect=zookeeper.example.com:2181 \ --add \ --allow-principal User:"kafkaclient" \ --operation Read \ --topic KafkaTopicName 移除/opt/kafka/bin/kafka-acls.sh \ --authorizer-properties zookeeper.connect=zookeeper.example.com:2181 \ --remove \ --allow-principal User:"kafkaclient" \ --operation Describe \ --topic KafkaTopicName \ --force 查询/opt/kafka/bin/kafka-acls.sh \ --authorizer-properties zookeeper.connect=zookeeper.example.com:2181 \ --list \ --topic KafkaTopicName
从键盘任意输入a,b,c的值,编程计算并输出一元二次方程ax2+bx+c=0的根(较小的先输出,即先输出p-q,后输出p+q)。根据一元二次方程的求根公式,令 p=−b2a,q=b2−4ac√2a 假设a,b,c的值能保证方程有两个不相等的实根(即b2-4ac>0) **输入提示信息:"Please enter the coefficients a,b,c:" **输入格式要求:"%f,%f,%f" **输出格式要求: "x1=%7.4f, x2=%7.4f\n" #include<stdio.h> #include<math.h> #include <stdlib.h> int main() { float a, b, c,p,q, disc; float x1,x2; printf("Please enter the coefficients a,b,c:"); scanf("%f,%f,%f" , &a, &b, &c); disc = b * b - 4 * a * c; q = -b / (2 * a); p = sqrt(fabs(disc)) / (2 * a); x1=q-p; x2=p+q; printf("x1=%7.4f, x2=%7.4f\n", x1, x2); } C语言题库交这个上去是正确的,但这个输入出来,结果可能有点小瑕疵,大家稍微改一改,第一次做也不太会
简介 我们都知道秒杀是一个高并发,大量请求的场景,如果每次秒杀,我们都直接去操作数据库,校验库存,扣减库存,大量请求的话,数据库肯定扛不住,会出现各种问题。那怎么办?数据库虽然扛不住,但是redis能抗,所以我们可以使用定时任务,提前将秒杀商品的库存同步到redis中,每次秒杀请求,扣减redis中的库存,然后异步修改数据库的库存。到这里,大量请求又会出现一个问题,假如redis中某秒杀库存为1,这时候有两台服务器查询,发现都是1,都执行了redis库存扣减操作,这个时候,redis中的商品库存会变成-1,产生了超卖问题。这个如何解决呢?可以配合lua脚本来解决,众所周知,redis保证lua脚本以原子性的方式执行:当某个脚本正在运行的时候,不会有其他脚本或 redis命令被执行。扣减库存操作写在lua脚本中,即可防止超卖。
完整流程:首先使用定时任务,将数据库秒杀商品库存同步到redis中,秒杀时,使用lua脚本扣减redis中的库存,然后将订单信息打入阻塞队列中,之后异步处理阻塞队列中的订单信息,进行数据库的库存扣减,订单信息生成等等操作。
流程图 下单流程
异步处理订单流程
实现 lua脚本 -- 存活时间 local expire = tonumber(ARGV[2]) local value = tonumber(ARGV[1]) local key = KEYS[1] -- 加锁 local ret = redis.call("SET", key, value, "NX", "EX", expire) local strret = tostring(ret) if strret == 'false' then return 0 else return 1 end if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end --商品id local goodsId = tostring(ARGV[1]) --用户id local userId = ARGV[2] --购买数量 local num = ARGV[3] --商品库存 local stock = "
这里写目录标题 1.编址方式①存储元,存储单元,存储体/存储矩阵,存储器/存储系统。②按字编址和按字节编址 2.各种易混淆的"长度概念"①字,字长/机器字长,指令字长,存储字长。 3.常见硬件对应位数及原因。 1.编址方式 ①存储元,存储单元,存储体/存储矩阵,存储器/存储系统。 ①存储元:能够完成一个二进制读写的叫做存储元。
②存储单元:每行/列(具体这行/列有多少个存储元要看编制方式)存储元叫做一个存储单元,也叫存储字/存储字长。
③存储体/存储矩阵:所有的存储单元组成的叫做存储体或存储矩阵。
④存储器:由存储体、地址译码器和控制电路组成。
⑤存储系统:存储系统是指计算机中由存放程序和数据的各种存储设备、控制部件及管理信息调度的设备(硬件)和算法(软件)所组成的系统。
存储系统>存储器>存储体>存储单元>存储元
②按字编址和按字节编址 其实就是每行划分的存储元的个数不同。
1.按字节编址:1B=8bit,需要用8个存储元件/存储元构成。即一个存储单元8位。
2.按字编址:假设告知一个字16位。则位为16bit,需要用16个存储元件/存储元构成一个存储单元。
假设主存大小1KB:
按字节编址:1KB=213bit。共有213/8=210个存储单元。(8个存储元为一个存储单元)则寻址范围为:0-210-1。即0000000000-1111111111。其中每一个地址(共210个地址),代表一个存储单元,代表8bit,代表1B。这就是按字节编址。
按字编址:假设一个字16位。共有213bit(存储元件)。共有213/16=29个存储单元(16个存储元位一个存储单元)则寻址范围为:0-29-1。即000000000-111111111。其中每一个地址(共29个地址),代表一个存储单元,代表16bit,代表2B,代表一个字。这就是按字编址。
2.各种易混淆的"长度概念" ①字,字长/机器字长,指令字长,存储字长。 1.字长:也称机器字长,通常指CPU内部用于整数运算的数据通路的宽度,因此机器字长等于CPU内部用于整数运算的运算器位数和通用寄存器宽度。
2.字:用来表示被处理信息的单位,用来“度量”数据类型的宽度。就好比,用G度量文件大小一样,是一个度量单位。
3.指令字长:一条指令中包含的二进制代码的位数。
4.存储字长:一个存储单元存储的二进制代码长度,即包含多少个存储元,多少个存储元件。
3.常见硬件对应位数及原因。 硬件名称位数MAR(地址寄存器)对应存储单元个数MDR(数据寄存器)存储字长ALU(运算逻辑元件)机器字长通用寄存器组机器字长IR(指令寄存器)指令字长PC(程序计数器)对应存储单元个数,MAR位数 ①通用寄存器位数组
ALU操作数的来源通常是通用寄存器,因此
通用寄存器位数=输入ALU的操作数的位数=机器字长。
②IR指令寄存器位数
IR用于保存当前正在执行或解码的指令。在简单的处理器中,每条要执行的指令都被加载到IR中,其位数取决于指令字长。
③PC程序计数器位数
用于存放下一条要执行的指令在主存中的地址。位数取决于可寻址内存,例如,PC宽度为32位 能够寻址2^32个存储单元。所以PC的位数n反映了主存的容量。
④MAR地址寄存器位数
MAR里保存着需要访问的数据的内存位置。位数同PC,由存储单元的个数决定。
⑤MDR数据寄存器位数
MDR充当处理器和内存单元之间的缓冲区,存放指令或地址(间接寻址)。一个要存储的字必须传送到MDR ,从那里转到特定的内存位置。MDR的位数由存储字长决定。
介绍 什么是Nuxt3 Nuxt3是一个基于Vue.js的应用框架,它提供了一些默认的配置和约定,使得开发者可以更快速地构建出高质量的Vue.js应用程序。Nuxt3是Nuxt.js的下一代版本,它采用了全新的架构和设计,提供了更好的性能和可扩展性。
Nuxt3 的优势 1、更快的启动和渲染速度
2、更好的性能和可扩展性
3、更灵活的配置和插件系统
4、更好的开发体验和文档支持
Nuxt3 的生态 Nuxt3的生态非常丰富,包括了许多插件、模块、组件库、工具等等。可以在Nuxt3官方网站的生态页面(https://nuxt.com/modules)上找到相关的Nuxt3生态。
安装 安装 Nuxt3 在安装Nuxt3之前,你需要保证你的node.js大于16.10.0 或者最新版本
创建一个nuxt项目
npx nuxi init <project-name> 切换到刚创建的项目根目录
cd <project-name> 下载相关依赖
npm install 基础 Nuxt3 的目录结构 assets/: 存放静态资源文件,如样式、图片、字体等。components/: 存放组件文件,可以在页面中引用。layouts/: 存放布局文件,可以在页面中引用。middleware/: 存放中间件文件,可以在路由中使用。composables/: 存放可重用的逻辑代码,可以在页面、组件和插件中使用。pages/: 存放页面文件,每个文件对应一个路由。plugins/: 存放插件文件,可以在应用程序中使用。static/: 存放静态文件,如 robots.txt、favicon.ico 等。store/: 存放 Vuex store 文件。server/: 存放服务器端代码,包括中间件、API、插件等等。utils/: 存放工具函数文件。nuxt.config.ts: Nuxt3 的配置文件,使用 TypeScript 编写。package.json: 项目的依赖和脚本配置文件。tsconfig.json: TypeScript 的配置文件。 页面和路由 Nuxt3的页面和路由是基于文件系统的路由系统,它允许开发者通过在pages目录下创建.vue文件来定义页面和路由。每个.vue文件对应一个路由,Nuxt3会根据文件名自动生成路由路径。例如,pages/index.vue对应的路由路径为/,pages/about.vue对应的路由路径为/about。此外,Nuxt3还支持动态路由和嵌套路由,可以通过在文件名中使用[]和_来定义动态路由和嵌套路由。例如,pages/posts/[id].vue对应的动态路由路径为/posts/:id,pages/posts/_slug/comments.vue对应的嵌套路由路径为/posts/:slug/comments。
动态路由 -| pages/ ---| index.vue ---| users-[group]/ -----| [id].vue // 你可以通过使用$route.params来获取传递的参数 <template> <p>{{ $route.
一、导语 相信很多人对 https 弄不清楚,只是知道 https是网络传输安全加密用的,背后的原理和过程并不是很清楚。
如果对https的过程一知半解,在每次面试时,面试官很可能就问你这个问题。答不对或者答的面试官不满意,就比较难受了。
其实https 的原理过程,并没有那么复杂,只是有些文章没有说清楚,这样的文章看多了,就迷糊了。
在了解https原理的过程之前,我们先来了解一下加密的知识。
二、加密知识 加密按照加密方式,可以分为以下三种方式。单向加密、对称加密、非对称加密。
(1)单向加密 也叫做不可逆加密,对明文的加密产生一个密文,并不能再通过密文,解出来对应的明文一般用于产生消息摘要,密钥加密等,常见的单向加密有: MD5 : 相信这个大家都都熟悉了,一个明文,md5以后,对应一个唯一的密文
SHA : 其中又分为 sha192 , sha256
特点:
不可逆。
输入一样,输出必然相同。
(2) 对称加密 对称加密,用一个密钥,对明文进行加密,同理,同这把密钥,也可以对密文进行解密。 也就是说加密和解密,可以用同一个密钥,这种加密方法就是对称加密 常用的对称加密方法有:
DES、3DES、AES
特点:
加密方和解密使用同一密钥;
加密解密的速度比较快。
(3) 非对称加密 非对称加密,使用公钥和私钥进行加密解密,可以使用私钥加密,公钥进行解密。同理,也可以使用公钥加密,私钥进行解密 常见非对称加密方式的有:
RSA、DSA(我们平时最常用的就是 RSA)。
特点:
公钥和私钥进行加密和解密(公钥加密私钥解密,私钥加密公钥可以解密);
加密或者解密,速度非常慢;
私钥和公钥是成对出现的。
下一篇,讲解加密🔐过程。
加关注,持续更新。
效果 Idea右击Dockerfile文件,直接在服务器构建docker镜像
开整 1、下载docker插件
2、编写Dockerfile文件
# 基础镜像 FROM openjdk:8-jdk-alpine # 工作目录 WORKDIR /opt/apps/gateway/logs/ # 文件拷贝,把target目录下的jar报拷贝到镜像的/APP/目录下 ADD ./target/sifan-erp-core.jar /App/ # 暴露的端口号,没有实际作用 EXPOSE 8080 # 指定JVM大小 ENTRYPOINT ["java","-Xmx2048m","-jar"] # 运行Jar包 CMD ["/App/sifan-erp-core.jar"] 注意:sifan-erp-core.jar是target目录下的jar包名称,根据自己而定
pom文件指定生成的jar包名
<build> <!--生成jar包的名称--> <finalName>sifan-erp-core</finalName> </build> 3、配置
右键Dockerfile文件,点击Modify Run Configuration...
点击...
点击...
输入服务区ip与用户名密码
测试连接
连续点击两个ok回到这个界面
填好Dockerfile文件位置和镜像名称
点击+号
选择Run Maven Goal
选择子项目,命令行填入package,点击ok
注意:如果是微服务则不需要配置这一个,否则公共模块的依赖不会引入
ok,现在Dockerfile文件设置好了
打包父项目,如果是单体应用直接打包
打包之后运行Dockerfile文件
如果出现了一下情况,表示连接已断开
只需要断开重连即可
继续运行Dockerfile文件,可以看到正在构建镜像
构建成功后可以看到docker中已经出现了需要制作的镜像,镜像制作好之后随便自己怎么运行了
错误 在MySQL中,可能会遇到You can't specify target table '表名' for update in FROM clause这样的错误它的意思是说,不能在同一语句中,先select出同一表中的某些值,再update这个表,即不能依据某字段值做判断再来更新某字段的值。
--查询user_id为空并且 按照account_no分组account_no 大于1条的,删除记录
delete form xx_table where user_id in( select id from xx_table where user_id is null and account_no in( select account_no FROM xx_table GROUP BY account_no HAVING count(account_no)>1 ) ); 解决方案 select 的结果再通过一个中间表 select 多一次,就可以避免这个错误.
delete form xx_table where user_id in( select id from xx_table ( select id from xx_table where user_id is null and account_no in( select account_no FROM xx_table GROUP BY account_no HAVING count(account_no)>1 ) )A );
今天换了一台电脑打开从另一个电脑复制过来的vmdk文件,开启虚拟机VMware logo闪过之后就一直黑屏
查找资料后我的解决方法很简单,如下:
编辑虚拟机设置,找到左下角的显示器选项,将右上角的加速3D图形的勾取消,再打开虚拟机就OK啦!
目录 Makefile实战前言1.介绍2.Makefile文件分析3.Makefile文件修改3.1 定义编译器3.2 定义源文件和目标文件3.3 定义头文件路径、库文件路径和库名称3.4 定义导出和运行时路径3.5 定义编译选项3.6 添加头文件依赖3.7 编译CUDA和C++程序3.8 其它 4.完整Makefile总结 Makefile实战 前言 学习完了杜老师推荐的Makefile教程视频,链接。来个实战先。
针对https://github.com/shouxieai/infer仓库中的Makefile进行分析和修改,完成该项目在Jetson nano上的编译和运行。
1.介绍 infer框架是杜老师最近推出的全新tensorrt封装,轻易继承各类任务,其优点有
轻易实现各类任务的生产者消费者模型,并进行高性能推理没有复杂的封装,彻底解开耦合! 除去多余的文件,完整的目录结构如下
src 存放源文件,包括6个文件,分别为cpm.hpp、infer.hpp以及yolo.hpp三个头文件;infer.cu和yolo.cu两个CUDA文件;main.cpp一个源文件 workspace inference 存放待推理的图片 build.sh,脚本文件,利用trtexec工具将ONNX模型编译生成enginev8trans.py,python文件,用于在yolov8的onnx模型中添加transpose节点yolov8n.transd.onnx和yolov8n-seg.b1.transd.onnx为yolov8导出的检测和分割模型 Makefile 说明
我们尽量只关注Makefile文件中的内容,先分析原Makefile内容然后修改满足我们的需求
文件虽然少但是包含的内容多,具体包括C++和CUDA的混合编程,以及tensorRT和OpenCV等库文件的链接,还是非常值得学习的。
本次使用的设备是Jetson nano嵌入式
对于该项目感兴趣的可以查看如何高效使用TensorRT视频
对于该项目应用在Jetson nano嵌入式感兴趣的可以查看Jetson nano部署YOLOv8
2.Makefile文件分析 首先来看下该仓库的Makefile文件具体内容:
cc := g++ nvcc = /root/.kiwi/lib/cuda-11.8/bin/nvcc include_paths := src \ /root/.kiwi/lib/opencv4.2/include \ /root/.kiwi/lib/TensorRT-8.5.3.1-cuda11x/include \ /root/.kiwi/lib/cuda-11.8/include \ /root/.kiwi/lib/cudnn8.6.0.163-cuda11/lib library_paths := /root/.kiwi/lib/opencv4.2/lib \ /root/.kiwi/lib/TensorRT-8.5.3.1-cuda11x/lib \ /root/.kiwi/lib/cuda-11.8/lib64 \ /root/.kiwi/lib/cudnn8.6.0.163-cuda11/lib link_librarys := opencv_core opencv_imgproc opencv_videoio opencv_imgcodecs \ nvinfer nvinfer_plugin nvonnxparser \ cuda cublas cudart cudnn \ stdc++ dl cppstrict := -Wall -Werror -Wextra -Wno-deprecated-declarations -Wno-unused-parameter custrict := -Werror=all-warnings cpp_compile_flags := -std=c++11 -fPIC -g -fopenmp $(cppstrict) -O0 cu_compile_flags := -std=c++11 $(custrict) -O0 -Xcompiler "
小程序上传图片需要进行压缩,可以使用wx.getFileSystemManager()方法将图片转换成base64格式,再使用canvas将图片压缩成指定大小。
//选择图片 wx.chooseImage({ count: 1, //最多选择1张图片 success: function(res) { var tempFilePaths = res.tempFilePaths; //获取图片本地路径 //将图片转换成base64格式 wx.getFileSystemManager().readFile({ filePath: tempFilePaths[0], encoding: 'base64', success: function(data) { //创建canvas进行压缩 var imgData = 'data:image/png;base64,' + data.data; var image = new Image(); image.src = imgData; image.onload = function() { //压缩图片,并绘制到canvas上 var canvas = document.createElement('canvas'); var context = canvas.getContext('2d'); var originWidth = this.width; var originHeight = this.height; var maxWidth = 1280, //设置最大的宽度 maxHeight = 1280, //设置最大的高度 targetWidth = originWidth, targetHeight = originHeight; if (originWidth > maxWidth || originHeight > maxHeight) { if (originWidth / originHeight > maxWidth / maxHeight) { targetWidth = maxWidth; targetHeight = Math.
1.问题 当我们在ubuntu系统中使用命令 sudo apt-get update 或者 sudo apt-get upgrade 更新时,有可能出现如下问题: 正在读取软件包列表… 完成 E: 无法获得锁 /var/lib/apt/lists/lock。锁正由进程 1688(packagekitd)持有 N: 请注意,直接移除锁文件不一定是合适的解决方案,且可能损坏您的系统。 E: 无法对目录 /var/lib/apt/lists/ 加锁 2.原因 造成这样的问题是因为其它的程序如系统的自动更新、新立得等正在使用apt-get进程,进程1688占用了这个锁,linux系统一次只允许一个进程执行apt-get 3.解决方案 方案一 强制解锁(比较暴力) sudo rm /var/lib/apt/lists/lock 方案二 ps aux 列出当前进程列表 找到 apt-get 那个被lock住的进程记下PID,sudo kill PID 即可,因为linux只允许开一个apt-get,当然apt-get和新立得也是只能同时开一个,具体命令如下: //1.列出当前进程列表 ps -aux | grep apt-get //2.找到最后一列以apt-get 开头的进程,然后sudo kill PID sudo kill PID //3.执行升级命令 sudo apt-get update sudo apt-get dist-upgrade 好了,Ubuntu系统更新时,出现错误:无法获得锁 _var_lib_apt_lists_lock 已解决
通过一键重装系统可以很快的就把一台电脑装好系统,但在使用小白一键重装系统的过程中仍然可能出现一些常见问题。以下是一些可能出现的问题和对应的解决方法。
安装失败
安装失败是使用小白一键重装系统时最常见的问题之一。可能的原因包括系统兼容性问题、软件下载不完整等。解决方法包括:
检查系统兼容性:小白一键重装系统支持的系统版本和硬件配置要求较高,需要满足一定的条件。如果不满足要求,就无法成功安装。用户需要检查自己的系统版本和硬件配置是否满足要求,如需升级硬件或操作系统版本,则需要进行相应的升级。
重新下载软件:如果下载的软件不完整或损坏,就无法成功安装。用户需要重新下载小白一键重装系统,确保软件完整并未被破坏。
无法启动
有时候,用户使用小白一键重装系统安装系统后,会发现无法启动计算机。可能的原因包括系统启动引导程序损坏、硬盘损坏等。解决方法包括:
检查启动引导程序:用户需要检查系统启动引导程序是否损坏。可以使用系统自带的修复工具修复启动引导程序。
检查硬盘是否损坏:如果硬盘损坏,就会导致系统无法启动。用户需要使用硬盘检测工具检查硬盘是否损坏。官网入口(小白一键重装系统)
无法识别硬件
小白一键重装系统可能无法识别某些硬件,如网卡、声卡、显卡等,导致无法正常使用。解决方法包括:
下载并安装驱动程序:用户需要下载并安装对应的驱动程序,以使系统能够正常识别硬件设备。用户可以到硬件厂商的官网上下载最新的驱动程序。
更新小白一键重装系统版本:如果小白一键重装系统版本较旧,就可能无法识别某些新型硬件设备。用户需要更新小白一键重装系统版本,以支持更多的硬件设备。
综上所述,小白一键重装系统虽然操作简单,但在使用过程中仍然可能出现一些常见问题。用户需要针对具体问题,采取相应的解决方法,才能顺利完成系统重装。
PROFIBUS是一种工业通信协议,包括多种变种,其中PROFIBUS-DP(即分布式的控制器-程序控制器)、PROFIBUS-PA(即过程自动化)和PROFIBUS-FMS(即领域消息规范)是最常见的三种变种。它们都是基于同一个物理层的通信协议,但在应用方面有所不同。
PROFIBUS-DP (Decentralized Peripherals):
DP是PROFIBUS协议的最常用变体之一,用于连接分散的自动化设备,例如PLC、I/O模块、驱动器和传感器。DP支持高速数据传输,允许实时控制和监控,并具有高度可靠性。DP使用RS-485物理层,支持多主机连接,最大传输距离为1200米。
PROFIBUS-PA (Process Automation):
PA是专门为过程自动化而设计的PROFIBUS变体,可用于连接传感器和执行器,例如温度传感器、流量计和执行阀。PA具有较低的数据传输速率,但支持长距离传输和有源器件供电。PA使用了特殊的物理层(MBP),允许在一个线路上连接多个设备,最大传输距离为1900米。
PROFIBUS-FMS (Fieldbus Message Specification):
FMS是PROFIBUS的第三个变体,可用于连接分布式控制系统(DCS)和其他上层控制设备。FMS提供了高级控制和监控功能,支持大量数据和消息的传输。FMS使用了不同的物理层(ISO/IEC 8802-2),最大传输距离为100米。
PROFIBUS-DP、PROFIBUS-PA和PROFIBUS-FMS分别用在什么场景?
PROFIBUS-DP用于控制系统
PROFIBUS-DP是用于控制系统和生产自动化应用的变种,它支持快速数据传输和实时控制,通常用于连接PLC和其他工业设备。例如,可以将它用于连接传感器、执行器、电机、传动器等设备,实现快速准确的控制。
PROFIBUS-PA用于过程自动化
PROFIBUS-PA是用于过程自动化应用的变种,例如化工、制药、石油和天然气工业中的过程控制。它支持长距离通信和多点连接,可以连接分布式的传感器和执行器。例如,可以将它用于连接温度、压力、流量等传感器,或控制阀门和执行器。
PROFIBUS-FMS用于工厂自动化和信息管理
PROFIBUS-FMS是用于工厂自动化和信息管理的变种,它支持高速通信和消息传输,可以用于连接生产线上的各种设备,例如传感器、编码器、计量器等。它还可以用于连接制造执行系统(MES)和企业资源计划(ERP)等上层系统,实现工厂自动化和信息管理的集成。
如何选择取决于应用场景和需求。如果需要实时控制和快速数据传输,则PROFIBUS-DP是一个不错的选择。如果需要连接分散的传感器和执行器,则PROFIBUS-PA可以满足需求。如果需要高速通信和信息管理,则PROFIBUS-FMS可能更适合。
Chain of Responsibility模式 What "Chain of Responsibility":责任推卸
Chain of Responsibility模式是一种为了避免请求发送者与多个请求处理者耦合在一起,于是将所有请求的处理者通过前一对象记住其下一个对象的引用而连成一条链;当有请求发生时,可将请求沿着这条链传递,直到有对象处理它为止的设计模式
Why 适用场景 当请求和处理者之间的关系是不确定的,而且对处理速度没有太高的要求时,可以使用Chain of Responsibility模式
优点 弱化了发出请求的人和处理请求的人之间的关系
可以动态的改变职责链
专注于自己的工作
How 定义一个抽象类Handler,内有next和request方法
实现Handler接口以适应不用的处理方法
使用者定义职责链
Handler public abstract class Support { private String name; private Support next; public Support(String name) { this.name = name; } public Support setNext(Support next) { this.next = next; return next; } public final void support(Trouble trouble) { if (resolve(trouble)) { done(trouble); } else if (next != null) { next.
在很长一段时间里用Python绘图,matplotlib都不能很好的显示中文,起初是认为我的pycharm里的设置问题,但是发现同样的问题在spyder里也同样的出现了,虽然有的地方可以用英文实在不行用拼音。。。但是在作图这里没有中文真的是太不方便了,机缘巧合下在年前终于找到问题的根源了,于是乎爱刨根问底儿的我把整个过程的解决方法分享给大家~~
一共有两种解决方案,我强烈推荐第一种,因为更为方便,绘图时不用再写别的参数,调用一次即可,第二种方法也会写出来但是更多的是作为了解,主要因为相比之下太麻烦
方法一: 示例:绘制每月的商品数量
X轴月份显示为中文增加X轴Y轴中文,图标标题 from matplotlib import pyplot as plt a = ["一月份","二月份","三月份","四月份","五月份","六月份"] b=[56.01,26.94,17.53,16.49,15.45,12.96] plt.figure(figsize=(20,8),dpi=80) plt.bar(range(len(a)),b) #绘制x轴 plt.xticks(range(len(a)),a) plt.xlabel("月份") plt.ylabel("数量") plt.title("每月数量") plt.show() 不出意外绘制出来的图是这样的。。。。。
绘制出来的图片,在所有应该显示为中文的地方均显示乱码
之前一直以为是系统中字符集支持的问题,其实并不是这样,根本原因是matplotlib内置的原因,直到我知道了 matplotlib.rc 这个方法,其实这个我也不太会用,那么我们看一下这个的源码写的是该如何使用(学会看源码真的很重要!!)
首先它肯定是能设置字体和颜色的,有关字体我们怎么设置呢?我们接着往下看
有关字体的设置找到了,可以接收为字典,它利用了font接收了一下字典,其实我们我们完全可以一行搞定,当然我更喜欢横着写,例如下面这样其实也是OK的~~**
matplotlib.rc("font",family='MicroSoft YaHei',weight="bold") 那么我们加入这行代码在跑一下试试
果不其然产生了一个报错,那么我们为什么把MicroSoft YaHei(这个不就是微软雅黑吗,电脑里都有啊)这个加进去会报错呢?
重点来了
其实报错只有一个原因就是他没有这个字体,虽然电脑里有这个字体但是不代表matplotlib里也有这个字体,所以解决matplotlib中的中文显示问题主要就是要找到它所内置支持的字体,那么我们首先查看一下它的内置字体,运行以下代码查看所支持的字体
# 查询当前系统所有字体 from matplotlib.font_manager import FontManager import subprocess mpl_fonts = set(f.name for f in FontManager().ttflist) print('all font list get from matplotlib.font_manager:') for f in sorted(mpl_fonts): print('\t' + f) 运行后他会显示出所有支持的字体,大约100多种。。。。具体的我就不一一列举了
但是你会发现这个都是英文字体啊,中文字体在哪里,其实我当时也非常困扰,但是细心的我发现了其中的奥秘,>>>其实他是有中文的只不过是用拼音写的…<<<
其中你会发现有如下字体:
DengXianFangSongKaiTiLiSuYouYuanAdobe Fan Heiti StdAdobe Fangsong StdAdobe Heiti StdAdobe Kaiti Std 其实这些都是中文啊啊啊啊啊啊~~~~激动的我把代码增加一行再试试,随便选了个字体
之前有介绍HTTPS协议,那wireshark可以抓包分析吗?基于好奇,查阅了下相关资料分享给大家。
在讲解密之前先来看下HTTPS与HTTP的不同之处,HTTPS是在TCP/IP与HTTP之间,增加一个安全传输层协议,而这个安全传输层协议一般用SSL或TLS,类似于下图。即我们所说的HTTPS=HTTP+SSL/TLS。
SSL协议分为SSL记录协议层和SSL握手协议层。SSL握手协议建立在SSL记录协议之上,用于在实际的数据传输开始前,通讯双方进行身份认证、协商加密算法、交换加密密钥等。
SSL记录协议将数据块进行拆分压缩,计算消息验证码,加密,封装记录头然后进行传输。如下图显示,这里不展开,有兴趣的童鞋可以继续自行深入了解。
Wireshark在对HTTP请求分析时,一般是通过选定数据右键鼠标,查看Follow TCP Stream。
即可以看到请求的详细内容了。
Wireshark对HTTPS请求数据又是如何分析的呢,实际操作了下,以访问CSDN首页为例,可以看到抓取的数据包如下:
根据截图会发现2个略“神奇”的东东:
(1)虽然过滤条件设置了SSL,但过滤结果满屏都是TLS的身影,随机找了其他一些网站也都是用TLS。简单查阅了下资料,发现TLS是以建立在SSL V3.0的基础上,两者的加密算法和MAC算法都不一样,而协议本身差异性不大。TLS协议也是由两层组成: TLS 记录协议(TLS Record)和 TLS 握手协议(TLS Handshake)。较低的层为 TLS 记录协议。忽略协议的差异性,后面会拿TLS来解密。
(2)好多hello呀,Client Hello和Server Hello好多,这是什么呢?这是TLS的握手。整个握手阶段如下,可分为5步:
第1步,浏览器给出协议版本号、一个客户端生成的随机数,以及客户端支持的加密方法。
第2步,服务器确认双方使用的加密方法,使用的tls版本号和一个随机数。
第3步,并给出数字证书、以及一个服务器运行Diffie-Hellman算法生成的参数,比如pubkey。
第4步,浏览器获取服务器发来的pubkey,计算出另一个pubkey,发给服务器。
第5步,服务器发给浏览器一个session ticket。
具体握手过程也可以通过Wireshark的抓包一步步验证,这里不再详述,还是专心来看看如何使用Wireshark来数据解密。
我们现在获取到的Wireshark抓包数据在握手完成之后,还是各种TLSv1.2的东东,都是加密后的数据。
解密方式有好几种,介绍我觉得最简单的,通过浏览器保存的TLS 会话中使用的对称密钥来进行数据解密。在浏览器接收到数据之后,会使用秘钥对数据进行解密,部分浏览器会在某个地方会存储这个密钥,我们只要获取浏览器中的会话密钥就能解密数据。
以windows系统+Chrome浏览器为例,首先要导出浏览器存储的密钥,通过计算机属性——高级系统设置——环境变量,新建一个变量名“SSLKEYLOGFILE”的变量,变量值是导出的密钥具体文件地址。
设置后可以通过Chrome浏览器打开任意一个HTTPS网址,此时查看变量值对应路径,已经生成sslkey.log。
密钥成功导出到本地啦。现在可以将密钥应用到Wireshark了。具体路径如下:菜单栏Edit——Preferences——Protocols——SSL(注意,不论是SSL还是TLS这里都是SSL,没有单独的TLS选项),在(Pre)-Master-Secretlog filename中选择刚才设置的变量值。
配置完成,看下效果:
看到有HTTP了,之前都是TLSv1.2。同时,WireShark下面会有一个“Decrypted SSL data”即已解密的SSL Data的标签,点击之后你就可以如上图所示的看到已经解密的TLS数据包的相信信息了。
觉得这样太难看了?OK,也可以像HTTP一样,通过鼠标右键在菜单栏中选择“Follow SSL Stream”,查看完整的HTTPS解密之后的请求数据哦。
除此之外,上面还有很多TLSv1.2的东东,比如:client_key_exchange、Session Ticket,这是最初提到过的TLS握手过程的第四步和第五步,并不是请求数据包的内容,因此看到其中像是没有解密的内容也不要奇怪哦。
以上就是我的分享,如果小伙伴们有什么疑问,可以在评论区留言,也欢迎各位与我们分享自己的看法~
首先申明下,本文为笔者学习《Python学习手册》的笔记,并加入笔者自己的理解和归纳总结。
1. 变量 1.1 变量命名规则 变量名必须以下划线或字母开头,而后面接任意数目的字母、数字或下划线。区分大小写,"Hello"与"hello"是不同的。禁止使用保留字。 1.2 保留字 False class finally is return None continue for lambda try True def from nonlocal while and del global not with as elif if or yield assert else import pass break except in raise 1.3 变量赋值 基本形式
一个对象赋值给一个变量。
>>> val = 12 # 整型 >>> val = 1.23 # 浮点型 >>> val = "Hello World" # 字符串 序列赋值
右侧可以是任何类型的序列,但左侧的变量数量必须与右侧一致。
>>> a, b = "
第31讲 | 你了解Java应用开发中的注入攻击吗? 安全是软件开发领域永远的主题之一,随着新技术浪潮的兴起,安全的重要性愈发凸显出来,对于金融等行业,甚至可以说安全是企业的生命线。不论是移动设备、普通 PC、小型机,还是大规模分布式系统,以及各种主流操作系统,Java 作为软件开发的基础平台之一,可以说是无处不在,自然也就成为安全攻击的首要目标之一。
今天我要问你的问题是,你了解 Java 应用开发中的注入攻击吗?
典型回答
注入式(Inject)攻击是一类非常常见的攻击方式,其基本特征是程序允许攻击者将不可信的动态内容注入到程序中,并将其执行,这就可能完全改变最初预计的执行过程,产生恶意效果。
下面是几种主要的注入式攻击途径,原则上提供动态执行能力的语言特性,都需要提防发生注入攻击的可能。
首先,就是最常见的 SQL 注入攻击。一个典型的场景就是 Web 系统的用户登录功能,根据用户输入的用户名和密码,我们需要去后端数据库核实信息。
假设应用逻辑是,后端程序利用界面输入动态生成类似下面的 SQL,然后让 JDBC 执行。
Select * from use_info where username = “input_usr_name” and password = “input_pwd” 但是,如果我输入的 input_pwd 是类似下面的文本,
“ or “”=” 那么,拼接出的 SQL 字符串就变成了下面的条件,OR 的存在导致输入什么名字都是复合条件的。
Select * from use_info where username = “input_usr_name” and password = “” or “” = “” 这里只是举个简单的例子,它是利用了期望输入和可能输入之间的偏差。上面例子中,期望用户输入一个数值,但实际输入的则是 SQL 语句片段。类似场景可以利用注入的不同 SQL 语句,进行各种不同目的的攻击,甚至还可以加上“;delete xxx”之类语句,如果数据库权限控制不合理,攻击效果就可能是灾难性的。
第二,操作系统命令注入。Java 语言提供了类似 Runtime.exec(…) 的 API,可以用来执行特定命令,假设我们构建了一个应用,以输入文本作为参数,执行下面的命令: