在NR中,只有当SSB 的波束扫描信号“覆盖”到UE时,UE 才有机会发送PRACH 随机接入。即这次的PRACH 的发送时刻RO 需要和SSB建立映射关系。然后基站可以根据UE上行PRACH 的资源位置,决定下行RAR 发送的波束。
该字段表示有两个参数信息。1. ssb-perRACH-Occasion N表示SSB与RO的映射关系。oneEight表示1个SSB关联与8个RACH时机,oneFourth表示于1个SSB与4个RACH场合关联的,依此类推。枚举部分的值指示每个SSB基于竞争的preamble数。值n4表示每个SSB基于竞争的4个前导码,值n8对应于每个SSB基于竞争的8个前导码,依此类推。2.RACH时机中的CB前导码总数由CB-preambles-per-SSB * max(1, SSB-per-rach-occasion)给出。
38213 8.1节
对于普通UE
如果N<1 ,代表一个SSB映射到多个RO上,每个RO都有R个连续的CB preamble index (0~R-1)。例如totalNumberOfRA-Preambles =64 ssb-perRACH-OccasionAndCB-PreamblesPerSSB为1/8:12,即N=1/8,R=12,N=1/8,代表一个SSB 映射到8个RO,每个RO都有连续的12个CB Preamble。
如果N>=1,即一个RO映射到多个SSB。SSB n就有R个连续的CB preamble,每个RO 的起始preamble index 是,有totalNumberOfRA-Preambles参数提供。例如totalNumberOfRA-Preambles =64,ssb-perRACH-OccasionAndCB-PreamblesPerSSB =2:12 即N=2,R=12,N=2代表2个SSB 映射到一个RO(64个preamble),每个SSB 分得 32 个preamble:SSB 0 的起始preamble index =0*64/2 =0 preamble 0~31(其中0~11 是CB preamble), SSB 1 的起始preamble index =1*64/2 =32 preamble 32~63(其中32~44 是CB preamble)。N>1时参数 totalNumberOfRA-Preambles 配置是N的整数倍。
对于redcap UE
ssb-SharedRO-MaskIndex,具体值在38321的7.4节。指示redcap preamble在哪个RO上。当每个SSB有多个RO时(N>1,多个SSB关联到一个RO上),将配置此字段。如果该字段不存在,即缺省为0。
startPreambleForThisPartition,指示redcap preamble起始位置。当N<1时,即一个SSB映射到多个RO上,redcap preamble起始位置为startPreambleForThisPartition。当N>1时,即一个RO映射到N个SSB上。第n()个SSB对应的redcap preamble起始位置为。
文章目录 Abstract3. Proposed Method3.1 Network Structure3.2. Pyramid Color Embedding (PCE)3.3. Objective Function Abstract 微光图像增强(LLIE)研究了如何细化光照,获得自然的正常光照图像。目前的LLIE方法主要侧重于提高光照,而没有合理地将颜色信息纳入LLIE过程中来考虑颜色的一致性。因此,增强后的图像与地面真值之间往往存在色差。
为了解决这个问题,我们提出了一种新的深颜色一致性网络,称为DCC-Net,以保持LLIE的颜色一致性。提出了一种新的“分而治之”的协同策略,该策略可以共同保存颜色信息,同时增强光照。
具体来说,我们的DCC-Net解耦策略将每个彩色图像解耦为两个主要成分,即灰度图像和颜色直方图。使用灰度图像生成合理的结构和纹理,颜色直方图有利于保持颜色的一致性。即利用两者协同完成LLIE任务。
为了匹配图像的颜色特征和内容特征,减小增强后图像与真实图片的颜色一致性差距,我们还设计了一种新的金字塔颜色嵌入(PCE)模块,可以更好地将颜色信息嵌入LLIE过程中。
在6个真实数据集上的大量实验表明,我们的DCC-Net增强后的图像更加自然和丰富多彩,与目前最先进的方法相比效果更好。
3. Proposed Method 在本节中,我们将介绍DCC-Net的框架(见图2)和细节,其目的是在获取正常光图像时保持颜色的一致性和自然性。DCC-Net有三个子网(即G-Net、C-Net、R-Net)和一个金字塔颜色嵌入(PCE)模块。
DCC-Net的总体框架。可以看出,有三个子网G-Net, C-Net和R-Net,其中G-Net的目标是恢复内容信息丰富的灰度图像,C-Net的重点是学习颜色分布,R-Net将灰度图像和颜色信息结合起来,恢复自然且颜色一致的正常光图像。
3.1 Network Structure G-Net
给定一个输入的微光图像,G-Net的目标是预测包含丰富结构和纹理信息的正常光图像的灰度图像,而不包含颜色信息。此过程表述为
G pre = G N e t ( S low ) G_{\text {pre }}=G N e t\left(S_{\text {low }}\right) Gpre =GNet(Slow )
式中, G p r e G_{pre} Gpre为预测灰度图像, S l o w S_{low} Slow为输入微光图像,GNet为G-Net的变换。具体来说,G-Net采用了encoder-decoder pipeline ,这与经典的U-Net类似。
对于G-Net,我们使用l1 loss来重建灰度图像:
l g = 1 H × W ∥ G p r e − G high ∥ 1 , l_g=\frac{1}{H \times W}\left\|G_{p r e}-G_{\text {high }}\right\|_1, lg=H×W1∥Gpre−Ghigh ∥1,
文章目录 1 HTML介绍2 第一个网页2.1、点击左面开始按钮,找到notepad,代开记事本2.2、编辑页面源码2.3、保存到桌面2.4 、如图2.5、打开index.html2.6、检查页面源代码 3、标签4、注释5、标签的属性5.1 概念5.2 案例5.3 运行结果 6、网页的结构6.1 基本结构如下6.2 文档声明: <!DOCTYPE html>6.3 网页根标签(根元素)< html >6.4 网页头标签< head >标签6.4.1 < meta >标签6.4.2 < title >标签:网页标题 6.5 网页主体标签 < body > 7、HTML实体7.1 什么是实体7.2 常用实体 8、meta标签8.1 meta标签作用8.2 meta标签中的属性 9、HTML语义化标签9.1 标题标签(六级)9.2 段落标签 p 标签9.3 标题分组 hgroup 标签9.4 em 标签9.5 strong标签 10、块元素和行元素10.1 相关概念10.2 案例10.3 运行查看结果 11、 块元素布局标签11.1 标签含义11.2 案例11.3 展示结果 12、列表标签12.1 列表分类12.2 案例12.3 运行结果13 超链接13.1 超链接定义13.2 案例13.3 运行结果 14、相对路径14.1 ./ 和../14.2 案例14.3 运行结果 15、超链接的其他用法15.
文章目录 1、背诵知识点1.1、近现代教育的变化和表现1.2、经济发展水平对教育的制约作用:1.3、学校教育在人的发展中起主导作用:1.4、教学过程的基本规律:1.5、教学原则:1.6、贯彻理论联系实际教学原则基本要求1.7、如何组织和培养班集体1.8、班级管理的原则1.9、简述教师劳动的特点1.10、德育原则1.11、贯彻疏导原则的基本要求1.12、贯彻长善救失德育原则的基本要求1.13、导向性原则的贯彻要求1.14、尊重学生和严格要求相结合原则的贯彻要求1.15、启发性教育原则的贯彻要求1.16、一堂好课的标准:1.17、皮亚杰的道德发展阶段理论:1.18、影响态度和品德学习的一般条件1.19、科尔伯格道德发展阶段理论(三水平六阶段)1.20、影响个体身心发展的因素1.21、生产力对教育的影响1.22、政治经济制度对教育的影响1.23、文化对教育的影响1.24、人口对教育的影响1.25、社会对教育的影响1. 26、教育对社会的影响1.27、三种学制类型1.28、本位论1.29、综合实践活动1.30、课程内容的文本表现形式1.31、教学组织形式1.32、教学评价1.33、德育方法评价法1.34、疏导原则1.35、教育影响的一致性和连贯性1.37、理论联系实际原则1.38、长善救失原则1.39、注意分散、注意集中,注意分配,注意转移1.40、行为主义、人本主义、认知主义、建构主义1.41、学习动机----奥苏泊尔1.42、皮亚杰的认知发展阶段理论1.43、普雷马克原则----强化的作用1.44、课堂气氛的类型1.45、 教学操作、教学归因,教学反思,教学迁移1.46、影响人的身心发展的因素1.47、我国古代社会教育的特征1.48、中国“六艺”、欧洲“七艺”1.49、形势教育和实质教育1.50、教学评价1.51、德育方法(考点)1.52、德育过程的基本规律(考点)1.53、注意的分类1.54、人倾向于将活动的成败归结原因1.55、耶克斯-多德森---最佳动机和任务难度1.56、记忆1.57、道德发展---科尔伯格1.58、性格、能力、情绪、气质1.59、强迫症=强迫概念+强迫行为1.60、中学生的情绪1.61、教师的需求和不同时期的关注点1.62、替代强化、直接干预、团体警觉、处理转换1.63、影响教学效能感的因素1.64、提高教学效能感的方法1.65、教育的政治、经济、文化,生态功能 2、20年下真题2.1、20年下选择题2.2、20年下辨析题2.2.1、母猴带着小猴爬树也是教育 (辨析题)2.2.2、对学生进行思想品德教育只是思想品德老师的工作2.2.3、顺向迁移就是正迁移2.2.4、思维定势对问题的解决可能是积极的。也可能是消极的 2.3、20年下解答题2.3.1、简述教育的文化功能2.3.2 、班主任工作的基本内容有哪些2.3.4、简述能力发展的个体差异2.3.5、教师职业倦怠的主要特征有哪些 2.4、20年下材料分析题2.4.1、周老师贯彻了哪些教学原则2.4.2、请结合材料对这些教学原则加以分析2.4.3、请根据自我效能感理论分析学生存在的问题以及产生的原因2.4.4、如果你是许老师,你应该如何帮助该学生? 3、19年下真题3.1 选择题3.2 解析题3.2.1.教材编写的直接依据是课程计划3.2.2 遗传在人的发展中起决定作用3.2.3 问题解决不受情绪影响3.2.4 心理健康的标准是相对的 3.3 问答题3.3.1 一堂好课的基本标准有哪些3.3.2 简述学校美育的基本任务3.3.3 简述元认知策略的种类3.3.4 简述品德的心理结构 3.4、材料分析题3.4.1 材料中老师贯彻了哪些德育原则3.4.2 请结合材料加以分析3.4.3 简述学生应该如何进行有效复习3.4.5 请指出晓宁复习中存在的主要问题 4、19年上真题4.0 选择题4.1 辨析题4.1.1 教育在人的身心发展中起决定性作用4.1.2 教育的任务就是向学生传授知识4.1.3 学习动机与学习效果成正比4.1.4 品德形成受情感影响 4.2 辨析题4.2.1简述当前我国教育方针的基本内容4.2.2 教学过程有哪些基本规律4.2.3 简述知觉的基本特征4.2.4 简述发散思维的基本特征 4.3 材料分析题4.3.1 该班主任贯彻了哪些主要的德育原则,请简要分析4.3.2 该班主任主要采用了哪些德育方法,请简要分析4.3.3 材料中晓辉的表现反映了他情绪发展的那些特点4.3.4 作为教师,针对晓辉的问题提出指导建议 5、18年下真题5.1 选择题5.2 辨析题5.2.1 教育对人的发展作用总是积极的5.2.2 总体而言,学校课程内容主要由间接经验构成5.2.3 根据皮亚杰理论,在良好的外界环境作用下,学生的认知发展可以从前运算阶段直接跨越至形式运算阶段5.2.4 学习材料的难度越大,越难产生迁移 5.3 简答题5.3.1 简述教育的政治功能5.3.2 描述贯彻科学性和思想性相统一教学原则的基本要求5.3.3 简述弗洛伊德的人格发展阶段理论5.3.4 简述促进知识获得和保持的方法 5.4 材料分析题5.4.1结合材料,说明该班主任老师培养班集体的主要方法5.4.2 请根据青少年学生异性交往特点分析案例中马英的问题5.4.3 如果你是马英的班主任,你会给马英提出什么建议 6、18年上真题6.1 选择题6.2 辨析题6.2.1 教育具有历史继承性6.2.2 教学是学校实现教育目的的基本途径6.2.3 注意的分配就是注意分散6.2.4 学生掌握的知识越多,说明学生的学习能力越强 6.3 简答题6.
目录
qrcode.vue
快速开始
使用
全部代码
qrcode.vue https://github.com/scopewu/qrcode.vue/blob/main/README-zh_cn.mdhttps://github.com/scopewu/qrcode.vue/blob/main/README-zh_cn.md
⚠️ 如果你正在使用 Vue 3,请升级 qrcode.vue 到 3.x;
🔒 如果你正在使用 Vue 2,请保持 qrcode.vue 的版本为 1.x;
一款 Vue.js 二维码组件.
快速开始 快速添加 qrcode.vue 组件到项目中
npm install --save qrcode.vue # yarn add qrcode.vue dist/ |--- qrcode.vue.cjs.js // CommonJS |--- qrcode.vue.esm.js // ES module |--- qrcode.vue.browser.js // UMD for browser or require.js or CommonJS |--- qrcode.vue.browser.min.js // UMD Minimum size 使用 import { createApp } from 'vue' import QrcodeVue from 'qrcode.
统计性能测试结果一定会关注TPS,TPS表示:每秒处理事务数,JMeter默认每个事务对应一个请求。我们可以用逻辑控制器中的事务控制器将多个请求统计为一个事务。
1、添加事务控制器
2、事务控制器参数说明
Generate parent sample:如果事务控制器下有多个取样器,勾选它,那么在“擦看结果树”中我们不仅可以看到事务控制器,还可以看到每个取样器
并且事务控制器定义的事务是否成功取决于子事务是否都成功,子事务其中任何一个失败即代表整个事务失败。
Include duration of timer and pre-post processors in generated sample:是否包括定时器、预处理和后期处理延迟的时间
3、运用事务控制器
察看结果树中的运行结果
聚合报告中的运行结果
下面是配套学习资料,对于做【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴我走过了最艰难的路程,希望也能帮助到你!
软件测试面试小程序 被百万人刷爆的软件测试题库!!!谁用谁知道!!!全网最全面试刷题小程序,手机就可以刷题,地铁上公交上,卷起来!
涵盖以下这些面试题板块:
1、软件测试基础理论 ,2、web,app,接口功能测试 ,3、网络 ,4、数据库 ,5、linux
6、web,app,接口自动化 ,7、性能测试 ,8、编程基础,9、hr面试题 ,10、开放性测试题,11、安全测试,12、计算机基础
资料获取方式 :
后端使用Response出现的跨域问题
今天联调文件下载的接口,由于自己用postman测试一直都没问题,但是在和前端联调的时候前端就会出现如下跨域的报错
@ApiOperation("下载附件")
@PostMapping(value = "/download")
public void downloadFile(@RequestBody List<Long> fileId) {
ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
HttpServletResponse response = servletRequestAttributes.getResponse();
FileBinary fileBinary= fileReportApiClient.download(fileId);
byte[] bytes = fileBinary.getData();
try {
// 清空response
// response.reset();
response.setContentType("application/octet-stream;charset=UTF-8");
response.setCharacterEncoding("UTF-8");
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(new Date().getTime() + ".zip", "utf-8"));
OutputStream ouputStream = response.getOutputStream();
ouputStream.write(bytes);
ouputStream.flush();
ouputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
项目的框架本身就是加了跨域处理的
@Configuration
public class CorsConfig {
@Bean
public CorsFilter corsFilter() {
文章目录 Abstract1. Introduction2. Related Work2.1. Low-light Image Enhancement2.2. Semantic-Guided Methods 3. Method3.1 Motivation and Overview3.2 Semantic-Aware Embedding Module3.3 Semantic-Guided Color Histogram Loss3.4 Semantic-Guided Adversarial Loss 4. Experiments4.1 Experimental Settings4.2 Quantitative Evaluation4.3 Qualitative Evaluation4.4. Ablation Study 5. Conclusion 论文地址:《Learning Semantic-Aware Knowledge Guidance for Low-Light Image Enhancement》
代码地址:https://github.com/langmanbusi/Semantic-Aware-Low-Light-Image-Enhancement
Abstract 弱光图像增强(LLIE)研究如何提高照明和产生正常光图像。现有的方法大多采用全局统一的方式对微光图像进行改进,而没有考虑不同区域的语义信息。如果没有语义先验,网络很容易偏离区域的原始颜色。
为了解决这一问题,我们提出了一种新的语义感知知识引导框架(semantic-aware knowledge-guided framework, SKF),该框架可以帮助弱光增强模型学习包含在语义分割模型中的丰富和多样化的先验。
我们专注于从三个关键方面整合语义知识 :
一个语义感知的嵌入模块(semantic-aware embedding module),在特征表示空间中整合语义先验;
一个语义引导的颜色直方图损失(semantic-guided color histogram loss),保持各种实例的颜色一致性;
一个语义引导的对抗损失(semantic-guided adversarial loss),通过语义先验产生更自然的纹理。
我们的SKF在充当LLIE任务的一般框架方面很有吸引力。大量的实验表明,在多个数据集上,使用SKF的模型显著优于基线,我们的SKF可以很好地推广到不同的模型和场景。
1. Introduction 在现实世界中,由于不可避免的环境或技术限制(如照明不足和曝光时间有限),微光成像相当普遍。微光图像不仅对人类感知具有较差的可视性,而且不适合后续的多媒体计算和为高质量图像设计的下游视觉任务[4,9,36]。因此,我们提出了微光图像增强(LLIE)来揭示微光图像中隐藏的细节,并避免在后续视觉任务中降低性能。主流的传统LLIE方法包括基于直方图均衡化的方法[2]和基于Retinex模型的方法[18]。
最近,许多基于深度学习的LLIE方法被提出,如端到端框架[5,7,34,45,46,48]和基于retainex的框架[29,41,43,44,49,53,54]。deep LLIE方法得益于其对微光和高质量图像之间映射的建模能力,通常比传统方法获得更好的结果。然而,现有的方法通常对微光图像进行全局统一的改进,而没有考虑不同区域的语义信息,而语义信息是增强的关键。如图1(a)所示,缺乏语义先验利用的网络很容易偏离区域的原始色调[22]。
资源下载地址:https://download.csdn.net/download/sheziqiong/86769526
资源下载地址:https://download.csdn.net/download/sheziqiong/86769526
目录
杭州电子科技大学信息工程学院 1
《数据库课程设计》课程设计手册 1
1 需求分析 8
1.1 需求分析 8
1.2 业务流程概述 9
1.3 数据流分析 13
1.3.1 数据流程顶层 13
1.3.2 数据流程一层 15
1.3.3 数据流程二层住宿管理 17
1.3.4 数据流程二层变更管理 18
1.3.5 数据流图二层门禁管理 19
1.3.6 数据流程二层服务管理 20
1.4 数据字典 22
1.4.1 数据项 22
1.4.2 数据结构 23
1.4.3 数据流 24
1.4.4 数据存储 27
1.4.5 处理过程 29
1.4.6 外部实体 30
2 概念结构设计 32
3 逻辑结构设计 34
3.1 关系模式 34
3.2 模式 34
Jetson Nano部署YOLO V8 刷JetPack镜像Step1:格式化SD卡Step2:下载镜像文件Step3:烧录镜像文件 Python环境配置Solution1:更改默认的Python环境Solution2:使用conda管理Python环境 YOLO V8部署Step1:源码下载Step2:trtexec环境变量设置Step3:pt权重文件导出为ONNX格式Step4:ONNX文件生成engine Reference 刷JetPack镜像 Step1:格式化SD卡 下载NVIDIA官方推荐的 SD Card Formatter 软件对SD卡进行格式化。
Step2:下载镜像文件 从官网的 Jetson下载中心 下载Jetson Nano对应版本的JetPack镜像文件。
Step3:烧录镜像文件 下载NVIDIA官方推荐的 balenaEtcher 软件将JetPack镜像烧录到SD卡中。
值得注意的是,最新版本的balenaEtcher可能会烧录镜像失败(暂时不知道是由于什么原因),因此建议使用更加稳定的一些版本。在部署过程中我使用了[1]中提供的 balenaEtcher安装包,提取码:28pm。
Python环境配置 Jetson Nano自带的Python版本为3.6.9,而很多库(尤其是更新较快的库)依赖的Python版本较高。
因此自带的Python环境并不推荐使用,针对这样的情况共有如下两种解决方案:
Solution1:更改默认的Python环境 这样做比较麻烦,且有可能使Jetson Nano中的Python环境更糟。
Solution2:使用conda管理Python环境 这样做比较方便,而且有利于不同任务的Python开发(强烈推荐!)。
但要注意的是,Jetson Nano的系统架构为aarch架构(arm64),而Anaconda官方并不存在aarch64的相关编译版本,因此我们需要使用的是GitHub上的开源项目:Archiconda。
当下载完成后,使用如下命令进行安装:
# 1、为文件赋可执行权限755 sudo chmod 755 ArchicondaXXX.sh(XXX为Archiconda的版本号) # 2、执行安装脚本 ./ArchicondaXXX.sh(XXX为Archiconda的版本号) Archiconda的命令与Anaconda的命令使用方法一致。
YOLO V8部署 YOLO V8的TensorRT部署主要参考了[3]中的方法。
打开Jetson Nano的Terminal,逐行输入以下命令:
conda create -n yolo8 python=3.7 pip install --upgrade pip pip intsall cmake pip install onnx==1.13.1 -i https://pypi.
读完这篇文章里你能收获到 1.Mybatis动态SQL语句大全 2.Mybatis中如何定义变量 3.Mybatis中如何提取公共的SQL片段 1、if语句 需求:根据作者名字和博客名字来查询博客,如果作者名字为空,那么只根据博客名字查询,反之,则根据作者名来查询: <select id="queryBlogIf" parameterType="map" resultType="blog"> select * from blog where <if test="title != null and title != '' "> title = #{title} </if> <if test="author != null and author != '' "> and author = #{author} </if> </select> 这样写我们可以看到,如果 author 等于 null,那么查询语句为 select * from user where title=#{title} ,但是如果title为空呢?那么查询语句为 select * from user where and author=#{author} ,这是错误的SQL 语句,如何解决呢?请看下面的 where 语句!
2、where语句: 修改上面的SQL语句:
<select id="queryBlogIf" parameterType="
众所周知,openai没有对国内开放使用权限,因此国内的用户是不可以使用直接使用chatgpt的,部分朋友想要通过使用网络工具使用其对话服务,这种行为显然是不可取的。其实也有好用的中国版的chatGPT网站,只是大家可能之前没有听说过!下面小编给大家分享3个.
1.Super Chat
Hei GPT是基于Openai官方GPT-3.5语言模型构架,通过在海量的文本数据上进行训练,具备了强大的自然语言处理能力,可以用于生成文本、回答问题等任务。ChatGPT能够与用户进行对话,理解用户输入并生成相应的回复。它能够生成连贯、有逻辑的语言,并具备一定的上下文理解能力。在性能方面丝毫不逊于chatgpt。您可以通过其官网了解更多:chat.l4s.cn
推荐指数: ★ ★ ★ ★ ★ ★
2.Hei GPT
ToBe Chat 翻译成中文是:等待聊天。基于大规模的互联网文本数据进行训练的。这些数据包括从各种网站和文本资源中搜集到的大量文本,以便模型能够学习到广泛的语言知识和语言表达方式。通过这样的大规模数据训练,能够生成更准确、连贯和有逻辑的回答。可以轻松地帮助人类完成各种写作,文章,代码,甚至可以沟通感情。您可以通过其官网了解更多:gpt.l4s.cn
推荐指数: ★ ★ ★ ★ ★
3.AI COG
AI COG模拟人类对话的方式,为用户提供有用的回答和指导,使用自然语言处理和机器学习算法,通过分析用户的输入和上下文来理解用户的意图,并生成相应的回复。 能够回答各种类型的问题,包括常见问题、事实性问题、地理位置、历史事件、体育比分、天气预报等。它还可以提供产品推荐、旅行建议、餐厅推荐等个性化的建议。您可以通过其官网了解更多:aicog.cn
推荐指数: ★ ★ ★ ★ ★
以上分享了3个国内好用的创作软件,并且小编根据自己的使用体验分别给出了不同推荐指数。
小编感觉最好用的是 Super Chat 因为它的回复更加全面和详细,对问题的理解程度最高,非常强大,因此小编给出六星。这个有些像chatgpt的原型各方面体验都很棒!
文章目录 论文详解Overall pipelineMulti-Dconv Head Transposed AttentionGated-Dconv Feed-Forward Network 代码详解 论文:《Restormer: Efficient Transformer for High-Resolution Image Restoration》
代码:https://github.com/swz30/Restormer
论文详解 本文的目标是开发一个高效的Transformer模型,该模型可以处理高分辨率的图像,用于恢复任务。为了缓解计算瓶颈,我们引入了multi-head SA layer的关键设计和一个比单尺度网络Swin-IR的计算需求更小的multi-scale hierarchical module。
我们首先展示了我们的Restormer architecture的整体结构(见图2)。
然后我们描述了提出的Transformer Block的核心组件:
(a) multi-Dconv head transposed attention (MDTA)
(b)gated-Dconv feed-forward network (GDFN)
最后,我们提供详细的渐进训练方案,以有效地学习图像统计。
Overall pipeline 给定低质量图像 I ∈ R H × W × 3 I∈R^{H×W×3} I∈RH×W×3, Restoremer首先进行卷积,得到底层特征嵌入 F 0 ∈ R H × W × C F_0∈R^{H×W×C} F0∈RH×W×C; 其中 H×W为空间维数,C为通道数。接下来,这些浅层特征 F 0 F_0 F0经过一个4级对称encoder-decoder,转化为深层特征 F d ∈ R H × W × 2 C F_d∈R^{H×W×2C} Fd∈RH×W×2C。
1、效果图 2、 实现过程 1、登录高德地图开发者平台 高德开放平台 | 高德地图API,申请接口Key 2、在高德开发平台下载微信小程序SDK,https://lbs.amap.com/api/wx/download 解压下载的文件得到 amap-wx.js ,在创建的项目中,新建一个名为 libs 目录,将 amap-wx.js 文件拷贝到 libs 的本地目录下。
3、微信小程序后台添加安全域名(这个必须设置,不然无法使用定位功能) 登录微信公众平台,在 "设置" → "开发设置" 中设置 request 合法域名,将 https://restapi.amap.com 中添加进去,如下图所示:
4、具体代码 <template> <view class="content"> <!-- <view class="btns"> <view @click="back">取 消</view> <view @click="getCurrentLocation">获取当前地址</view> </view> --> <view class="inputCon"> <view class="searchView"> <text class="iconfont icon-sousuo" @click="searchFn"></text> <input type="text" placeholder="搜索地点" v-model="searchWords" confirm-type="search" @confirm="searchFn" /> <text @click="cancel">取消</text> </view> </view> <!-- 地图部分 --> <view class="content-map"> <map style="width: 100%;height: 100%;" v-if="
语言:python 3
用法:选择PDF文件所在的目录,点击 确定 后,自动将该目录下的所有PDF转换成单个图片,图片名称为: pdf文件名.page_序号.jpg
如运行中报错,需要自行根据报错内容按照缺失的库
例如:
#安装库 pip install pyautogui #安装库 pip install pillow 这里提供两种源码,第一种是在代码中手动添加pdf所在目录
import os import glob from PyPDF2 import PdfReader from pdf2image import convert_from_path pdf_dir = "path/to/pdf_dir/" #pdf目录 # 遍历目录中的PDF文件 pdf_files = glob.glob(os.path.join(pdf_dir, "*.pdf")) # 遍历每个PDF文件,并将其转换为图片 for pdf_file in pdf_files: # 创建PdfReader对象 pdf = open(pdf_file, 'rb') pdf_reader = PdfReader(pdf) # 遍历PDF的页面并将其转换为图片 for page_num in range(len(pdf_reader.pages)): # 获取页面对象 page = pdf_reader.pages[page_num] # 将PDF页面转换为图像 images = convert_from_path(pdf_file, first_page=page_num+1, last_page=page_num+1) # 定义图像保存路径 filename = os.
生成树协议:
企业网三层架构—》冗余----》线路冗余—》二层桥接环路
导致问题:
1、广播风暴
2、MAC地址表翻滚 —在一台交换机上,同一个MAC地址只能映射唯一的接口;但同一个接口可以映射多个不同的MAC地址;
3、同一数据帧的重复拷贝
4、以上3个条件最终导致设备工作过载,导致重启保护
生成树:在一个二层交换网络中,生成一棵树型结构,逻辑的阻塞部分接口,使得从根到所有的节点仅存在唯一的路径;当最佳路径故障时,自动打开部分阻塞端口,来实现线路备份的作用;
生成树在生成过程中,应该尽量的生成一棵星型结构,且最短路径树;
存在算法: 802.1D PVST PVST+(CISCO) RSTP(802.1w) MSTP(802.1S)
一、802.1D 一个交换网络内仅存在一棵生成树实例;
交换机间使用BPDU—桥协议数据单元 – 交换机间沟通互动收发的数据
配置BPDU—只有根网桥可以发送,在交换网络初始状态时,所有交换机均定义本地为根网桥,进行BPDU的发送;使得网络中所有交换机均收到其他设备的BPDU,之后基于数据中的参数进行比对,选举出根网桥;再所有非根网桥不再发送BPDU,而是仅接收和转发根网桥的BPDU;周期2s发送,hold time 20s;
TCN—拓扑变更消息(也是BPDU): 本地交换机链路故障后,STP重新收敛,为了快速刷新全网所有交换机的MAC表,将向本地所有STP接口发送TCN(标记位中的TCN位置1),邻居交换机收到TCN后,先标记为ACK位为回复,用于可靠传输消息;之后将TCN逐级转发到根网桥处,由根网桥回复TC消息来逐级回复到所有交换机;使所有交换机临时将MAC表的老换时间修改为15s(默认的,转发延时)
选举— 根网桥 根端口 指定端口 非指定端口(阻塞端口)
【1】根网桥 – 在一棵生成树实例中,有且仅有一台交换机为root;
BPDU中的桥ID来决定
桥ID= 网桥优先级(0-65535公有) 默认32768 + MAC地址(只有存在svi接口的交换机才拥有mac地址,若存在多个mac选数值最小)
根网桥的选举 先比较优先级,小优; 若优先级相同,比较mac,数值小优;
即1、比较BPDU中的BID=网桥优先级+MAC地址(背板地址池中数值最小一透明交换机无MAC二层交换机存在一个三层以上交换机存在多个)
网桥优先级0-65535默认32768越小越好
先比较网桥优先级,数值越小越好
若优先级相同,比较mac地址,数值越来越小
PID=端口ID=接口优先级+接口编号优先级O-255 默认128新折
【2】根端口—在每台非根网桥上,有且仅有一个接口;本地离根网桥最近的接口(最短、星型),接收来自根网桥的BPDU,转发用户的流量(该接口不阻塞)
规则:
1、比较从根网桥发出后,通过该接口进入时最小的cost值;
2、入向cost值相同,比较该接口对端设备的BID,小优
3、对端BID也相同,比较该接口对端设备的接口的PID;先优先级小,若优先级一致,编号小
4、连对端PID也相同,比较本地PID,小优;
PID=端口ID 接口优先级(0-240,步长16,默认128) 接口编号
【3】指定端口,在每一段存在STP的物理链路上,有且仅有一个;转发来自根网桥的BPDU,同时可以转发用户流量(不阻塞);默认根网桥上所有接口为指定端口;
1、比较从根网桥发出后,通过该接口进入这段链路时的cost值最小(出向)
2、若出向cost值相同,必须本地的BID,小优;
3、本地BID相同,比较本地的PID;
4、本地PID,相同,直接阻塞该端口;
【4】非指定端口(阻塞端口)当以上所有角色全部选举完成后,剩余没有任何角色的接口为非指定;
该接口逻辑阻塞,实际可以接收到信息,但不转发;
cost值:不同带宽 存在不同cost
802.1d标准: 802.1T标准
[SW1]disp current-configuration #
sysname SW1
#
vlan batch 2 100
#
stp instance 0 root primary
stp instance 2 root secondary
#
dhcp enable
#
stp region-configuration
region-name aa
instance 2 vlan 2
active region-configuration
#
drop-profile default
#
ip pool vlan1
gateway-list 172.16.1.250
network 172.16.1.0 mask 255.255.255.0
#
ip pool vlan2
gateway-list 172.16.2.250
network 172.16.2.0 mask 255.255.255.0
#
interface Vlanif1
ip address 172.16.1.1 255.255.255.0
vrrp vrid 1 virtual-ip 172.
YAML是一种常用的数据序列化格式,在Java应用程序中读写YAML数据是常见的任务。本文介绍了三个受欢迎的Java工具包:SnakeYAML、Jackson Dataformat YAML和YAMLBeans,它们都提供了读写YAML数据的功能。本文将逐一介绍这些工具包的特点、Maven依赖配置,并给出使用示例。最后,本文总结了它们各自的优缺点,以帮助您选择适合您项目需求的工具包。
工具包介绍 1. SnakeYAML SnakeYAML是一个功能强大且流行的Java库,用于读取和写入YAML数据。提供简单而灵活的API,可以将YAML数据转换为Java对象,或将Java对象转换为YAML数据。官方网站:https://bitbucket.org/asomov/snakeyamlMaven 依赖 <dependency> <groupId>org.yaml</groupId> <artifactId>snakeyaml</artifactId> <version>1.28</version> </dependency> 2. Jackson Dataformat YAML Jackson Dataformat YAML是Jackson库的扩展,提供对YAML格式的支持。允许使用相同的API来处理JSON和YAML数据。官方网站:https://github.com/FasterXML/jackson-dataformat-yamlMaven 依赖 <dependency> <groupId>com.fasterxml.jackson.dataformat</groupId> <artifactId>jackson-dataformat-yaml</artifactId> <version>2.12.5</version> </dependency> 3. YAMLBeans YAMLBeans是一个轻量级的Java库,用于读取和写入YAML数据。提供简单的API,可将YAML数据映射到Java对象,并将Java对象转换为YAML数据。官方网站:https://github.com/EsotericSoftware/yamlbeansMaven 依赖 <dependency> <groupId>net.sourceforge.yamlbeans</groupId> <artifactId>yamlbeans</artifactId> <version>1.14</version> </dependency> 使用示例 SnakeYAML 示例 // 读取 YAML 文件 try (InputStream inputStream = new FileInputStream("example.yaml")) { Yaml yaml = new Yaml(); Map<String, Object> data = yaml.load(inputStream); // 处理 YAML 数据 System.out.println(data); } catch (IOException e) { e.
1. mysql主从同步定义 主从同步使得数据可以从一个数据库服务器复制到其他服务器上,在复制数据时,一个服务器充当主服务器(master),其余的服务器充当从服务器(slave)。因为复制是异步进行的,所以从服务器不需要一直连接着主服务器,从服务器甚至可以通过拨号断断续续地连接主服务器。通过配置文件,可以指定复制所有的数据库,某个数据库,甚至是某个数据库上的某个表。
使用主从同步的好处:
1.通过增加从服务器来提高数据库的性能,在主服务器上执行写入和更新,在从服务器上向外提供读功能,可以动态地调整从服务器的数量,从而调整整个数据库的性能。2.提高数据安全-因为数据已复制到从服务器,从服务器可以终止复制进程,所以,可以在从服务器上备份而不破坏主服务器相应数据3.在主服务器上生成实时数据,而在从服务器上分析这些数据,从而提高主服务器的性能 1.2 什么是 Binlog MySQL 的二进制日志可以说 MySQL 最重要的日志了,它记录了所有的 DDL 和 DML(除 了数据查询语句)语句,以事件形式记录,还包含语句所执行的消耗的时间,MySQL 的二进制日志是事务安全型的。
一般来说开启二进制日志大概会有 1%的性能损耗。二进制有两个最重要的使用场景:
其一:MySQL Replication 在 Master 端开启 Binlog,Master 把它的二进制日志传递给 Slaves 来达到 Master-Slave 数据一致的目的。
其二:自然就是数据恢复了,通过使用 MySQL Binlog 工具来使恢复数据。
二进制日志包括两类文件:二进制日志索引文件(文件名后缀为.index)用于记录所有 的二进制文件,二进制日志文件(文件名后缀为.00000*)记录数据库所有的 DDL 和 DML(除 了数据查询语句)语句事件。
1.2 Binlog 的分类 MySQL Binlog 的格式有三种,分别是 STATEMENT,MIXED,ROW。在配置文件中可以选择配 置 binlog_format= statement|mixed|row。三种格式的区别:
1)statement:语句级,binlog 会记录每次一执行写操作的语句。相对 row 模式节省空间,但是可能产生不一致性,比如“update tt set create_date=now()”,如果用 binlog 日志 进行恢复,由于执行时间不同可能产生的数据就不同。
优点:节省空间。缺点:有可能造成数据不一致。 2)row:行级, binlog 会记录每次操作后每行记录的变化。
优点:保持数据的绝对一致性。因为不管 sql 是什么,引用了什么函数,他只记录 执行后的效果。
缺点:占用较大空间。
大家好,小编为大家解答手机python编程软件怎么运行的问题。很多人还不知道在手机上如何运行python,现在让我们一起来看看吧!
广告关闭
2017年12月,云+社区对外发布,从最开始的技术博客到现在拥有多个社区产品。未来,我们一起乘风破浪,创造无限可能伪原创小发猫怎么样。
前言 在手机上运行python需要用一个软件,叫qpython3l,当然还有别的软件也是可以运行python的,不过我认为qpython3l是其中相对较好的一个。 首先声明一下...终端? 这个终端是python的终端,不是linux的,只能执行python代码。 编辑器? 这个编辑器可以在你的手机里编写py文件,也可打开已有的py文件,然后可以直接...
这里介绍一个软件—qpython3,集成了python3解释器,既可以命令行运行python,还可以编辑源文件后运行,支持代码高亮、语法检查等功能,下面我简单介绍一下这个软件的安装和使用:下载qpython3,直接在手机应用中搜索就行,如下,大概也就12兆左右,直接点击下载安装就行:? python编程的软件 alt=手机上python编程的...
生活中除了给男神女神表白,还会遇到朋友过生日,所以小编今天就给大家带来了一个送给朋友的生日祝福程序。 2准备本次程序还是用python编写,第三方库用到了pygame。 安装方式在命令行运行以下代码即可。 pip install pygame3主要步骤 首先是导入所需模块以及初始化pygame:#导入模块import randomimport pygame...
那如何按要求 批量生成 一些真实的手机号码呢? 本篇文章的目的是带大家利用 python 批量生成手机号码。 2编 写 代 码要批量生成手机号码,首先需要了解 11 位手机号码的组成规律,即:手机号码一共有 11 位,以 1 开头第 2 位的数值是 3、4、5、7、8 中的一个第 3 位根据第 2 位的数字,对应运营商的生成规律后 8 位...
它实际是一款linux系统模拟器,安装好termux后还要再安装python,并且是全命令行操作,一些读者使用起来有障碍。 今天安利一款更友好的qpython。? qpython是一个python引擎,只能运行在安卓系统上,相比termux,它可以全图形界面操作,非常友好。 内置了一个python编辑器,可以直接在手机上写python代码,支持缩进...
函数体如上所示在 python 中定义一个函数需要使 def 语句,一次写出函数名称、括号、括号中的参数列表和冒号,然后使用缩进块编写函数体。 无参数函数定义...就想我们现在使用的手机大多数人都不了解手机是如何制造出来的,但是这并不影响我们的使用,我们只是将它当做一个工具来使用。 同样我们也可以将函数看做...
(本文经原作者授权转载,不得二次转载)python 里的规则python是一门初见简单、深入后愈觉复杂的语言。 拿 python 里最重要的“对象”概念来说,python 为其定义了多到让你记不全的规则,比如:定义了 __str__ 方法的对象,就可以使用 str() 函数来返回可读名称定义了 __next__ 和 __iter__ 方法的对象,就可以被.
resultset 转换成对象 resultset 转换成对象 resultset 转换成对象 public JSONArray executeSQL(String sql) { Connection con = null; PreparedStatement pstm = null; ResultSet rs = null; JSONArray jsonArray = new JSONArray(); try { con = DbUtil.getConnection(); con.setAutoCommit(false); pstm = con.prepareStatement(sql); rs = pstm.executeQuery(); ResultSetMetaData metaData = rs.getMetaData(); int colCnt = metaData.getColumnCount(); while (rs.next()) { JSONObject jsonObject = new JSONObject(); for(int i=1;i<=colCnt;i++){ jsonObject.put(metaData.getColumnName(i),rs.getObject(i)); } jsonArray.add(jsonObject); } con.commit(); } catch (Exception e) { e.printStackTrace(); } finally { DbUtil.
Hadoop、Spark与Flink的基础架构及其关系和优异 前言Hadoop基础架构优点不足 Spark基础架构优点不足 Flink基础架构优点不足 结语:大数据框架的选择 前言 Hadoop、Spark和Flink是目前重要的三大分布式计算系统。它们都可以用于大数据处理,但在处理方式和应用场景上有所不同。
Hadoop专为批处理而生,一次将大量数据集输入到输入中,进行处理并产生结果。它用于离线复杂的大数据处理。
Spark定义是一个批处理系统,但也支持流处理。它用于离线快速的大数据处理。
Flink为流和批处理提供了一个运行时。它用于在线实时的大数据处理。
这三个框架在不同的大数据处理场景当中,表现各有优势。因此,最好的方案就是将各自的优势结合起来,实现更高效率地完成大数据处理任务。
*注:
①在线与离线:在线大数据处理是指在应用程序由用户输入驱动时,需要及时响应用户的处理方式。例如,社交网络新闻提要、实时广告服务器、分析工具和CRM应用程序都属于在线大数据处理的范畴。离线大数据处理是指在没有承诺响应用户的情况下进行的处理方式。离线大数据处理提供了对大量数据进行转换、管理或分析的能力。
②批处理与流处理:批处理是指在数据被收集完成后再进行处理。这种方式适用于离线复杂的大数据处理,例如账单、客户订单、工资单等。批处理通常需要较长时间,更适合大量数据的处理。流处理是指实时地对数据进行处理,数据是分段发送到分析工具中的。这种方式适用于在线实时的大数据处理,例如欺诈检测、日志监控、客户行为分析和社交媒体分析等。流处理的延迟通常以秒或毫秒为单位,因为在流处理中,数据在到达磁盘之前会被分析。
Hadoop 基础架构 Hadoop是一个分布式计算系统,它由多个元素构成。最底层是Hadoop Distributed File System(HDFS),它存储Hadoop集群中所有存储节点上的文件。HDFS的上一层是MapReduce引擎,该引擎由JobTrackers和TaskTrackers组成。此外,Hadoop还包括YARN(Yet Another Resource Negotiator)资源管理器和Common库。
① HDFS:Hadoop Distributed File System(HDFS)是一种分布式文件系统,它能够在多个计算机之间存储大量数据。
② MapReduce:MapReduce是一种编程模型,用于处理大量数据。它将计算任务分解为多个小任务,分别在不同的计算节点上执行,然后将结果汇总起来。
③ YARN:YARN(Yet Another Resource Negotiator)是Hadoop的资源管理器,负责管理集群中的计算资源,并调度用户提交的作业。
④ Common:Common库包含了Hadoop所需的各种通用组件和工具,例如配置管理、日志记录和安全管理等。
这些组件共同构成了Hadoop这个强大的分布式计算系统。它们协同工作,能够处理海量数据,并提供高可靠性、高扩展性和高容错性等特性。
优点 ① 高可靠性:Hadoop按位存储和处理数据的能力值得人们信赖。
② 高扩展性:Hadoop是在可用的计算机集簇间分配数据并完成计算任务的,这些集簇可以方便地扩展到数以千计的节点中。
③ 高效性:Hadoop能够在节点之间动态地移动数据,并保证各个节点的动态平衡,因此处理速度非常快。
④ 高容错性:Hadoop能够自动保存数据的多个副本,并且能够自动将失败的任务重新分配。
不足 ① 所有的metadata操作都要通过集中式的NameNode来进行,NameNode有可能是性能的瓶颈。
② 单一NameNode、单一Jobtracker的设计严重制约了整个Hadoop可扩展性和可靠性。首先,NameNode和JobTracker是整个系统中明显的单点故障源。再次,单一NameNode的内存容量有限,使得Hadoop集群的节点数量被限制到2000个左右,能支持的文件系统大小被限制在10-50PB,最多能支持的文件数量大约为1.5亿左右。
③ 部分hadoop集群的NameNode重启需要数小时,这大大降低了系统的可用性。
④ 随着Hadoop被广泛使用,面对各式各样的需求,人们期望Hadoop能提供更多特性,比如完全可读写的文件系统、Snapshot、Mirror等等。这些都是当前版本的Hadoop不支持,但是用户又有强烈需求的。
Spark 基础架构 Apache Spark是一个围绕速度、易用性和复杂分析构建的大数据处理框架,最初在2009年由加州大学伯克利分校的AMPLab开发,并于2010年成为Apache的开源项目之一。Spark由SparkCore、Spark SQL、Spark Streaming、GraphX、MLlib等模块组成。
Spark运行架构包括集群资源管理器(Cluster Manager)、多个运行作业任务的工作结点(Worker Node)、每个应用的任务控制结点(Driver)和每个工作结点上负责具体任务的执行进程(Executor)。
① Cluster Manager:在Standalone模式中即为Master(主节点),控制整个集群,监控Worker。 在YARN模式中为资源管理器。
专业创新实践报告
题目 YOLO v3算法详解以及和Faster-RCNN的比较 YOLO V3算法详解以及和Faster-RCNN的比较
参考来源:目标检测 - 飞桨AI Studio
一、目标检测的发展 图像识别和分类:计算机不同于人类,计算机只能够“看到”的是图像被编码之后的数字。例如下图1(右边),人类可以一眼看出图片中有一只狗,而计算机看到的是编码数字(左边)。图像分类任务的目的就是识别图像为哪一个类别。
图1计算机处理得到像素
常规图像分类流程图如下:
图2常规图像分类流程图
可以描述为:对输入的图片进行特征提取,利用提取到的特征预测分类概率,根据训练样本标签来建立起分类损失函数,并以此开启训练,以实现图像分类的目的。
图像分类的结果:将图3-1 识别为狗,右图3-2识别为猫。
图3-1 狗 图 3-2 猫
目标检测的实现依赖于图像分类,它是一种图像分类技术。目标检测通常分为通用型目标检测和单一型目标检测:①通用型:主要是将一幅图像中的所有类别全部检测出来,并标注出其类别和位置。②单一型:主要是将固定的类别检测出来,并标注出其类别和位置。例如人脸检测、文本检测、车牌检测等。
从目标检测的类型中可以看出,目标检测和图像分类有很大的不同。目标检测需要检测出一幅图像中的所有目标,并标注它的位置和类别。如下图4所示,标识出了dog、cat以及它们的位置;而在图像分类的任务中,对于一张图图像来说,提取特征的过程并没有体现出不同目标之间的区别,也没法分别标示出每个物体和类别和它的位置。所以,目标检测是基于图像分类的成功经验,将图像上可能包含目标物体的区域当成一幅单独的图像处理,使用图像分类的模型对该区域进行类别检测,这些区域也称为候选区域(candidate area),使用其他方法表示目标的位置。
图4 目标检测(检测猫,狗的类别和位置)
目标检测问题的关键就在候选区域的生成,最暴力的方法就是穷举:列出图像上的所有区域。穷举法虽然可能可以得到正确的预测结果,但其计算量是非常大,在实际应用中很难实现。2013年,目标检测的任务迎来了突破:Ross Girshick 等人于首次将CNN的方法应用在目标检测任务上,采用传统图像算法selective search产生候选区域,这一算法迎来了重大的突破,这就是对目标检测领域影响深远的区域卷积神经网络(R-CNN)模型。2015年,Ross Girshick 又对此方法进行了改进,提出了Fast RCNN模型,将不同区域的物体共用卷积层的计算,这大大缩减了计算量,并且提高了处理的速度,还引入了调整目标物体位置的回归方法,进一步提高了位置预测的准确性。同年,Shaoqing Ren 等人提出了Faster RCNN模型,提出了RPN(Regional Proposal)的方法来产生物体的候选区域,也第一次提出了anchor boxes这一概念,anchor boxes是学习卷积神经网络用于目标识别过程中最重要且最难理解的一个概念,此后在SSD、YOLOv2、YOLOv3等优秀的目标识别模型中得到了广泛的应用,这一方法里面不再需要使用传统的图像处理算法来产生候选区域,进一步提升了处理速度。
本次实验,我们主要是使用了YOLOv3模型架构来实现对人的检测。我们将拓展展开 YOLO v3标检测方法的具体的实现和Faster-RCNN的框架介绍。主要是介绍单一型的目标检测。
二、YOLO v3介绍及实现 2.1 YOLO v3的网络架构的解析: YOLO v1提出了YOLO算法的通用架构,YOLO v2改进了设计并利用预定义的锚框来生成正负样本来训练,而YOLO v3又在YOLO v2的基础上进一步完善了模型架构和训练过程,它的网络架构如下图5所示:
图5 YOLO v3的网络架构
从图中看出,YOLO v3检测目标的步骤为:
输入一批形状为 (m, 416, 416, 3)(416为32的倍数) 的图像。将此图像传递给卷积神经网络 (CNN)。将上述输出的最后两个维度展平,得到输出量 (19, 19, 425)(指19*19个网格中,每个网格都有425个参数,425是根据每个网格中锚框的数量、锚框的位置类别信息和总共检测的类别数计算得出):输出是边界框列表以及已识别的类。每个边界框的标签中包含置信度、位置和类别信息。进行 IoU(Intersection over Union)和 Non-Max Suppression 丢弃冗余框,保留置信度最高的预测框。 详细步骤在本文中将展开描述。
一、聚水潭单据同步需求 聚水潭作为领先的电商ERP有很多快销、零售企业使用,同时作为以订单为核心的电商ERP系统企业还需要在本地配合其他业务系统一起使用完全整个业务的协同和财务结算,作为中大型企业随着业务发展企业会在聚水潭中沉淀大量的业务数据,这些数据需要接取到本地业务系统如金碟云星空、用友NC中进行发货、生成凭证、统计分析等需求,如果这些数据没有同步将会影响企业的业务运行,阻碍企业的业务创新能力。
二、传统硬编码同步方式: 聚水潭开放平台提供了主要的业务单据同步API接口,企业可以通过调用这些API接口实现数据的拉取和推送来实现业务状态的同步,通过编码方式主要通过以下几个步骤来完成
(聚水潭开放平台)
注册聚水潭商家账号后访问接口获取授权码;通过代码发送鉴权请求获取token,并根据响应的token剩余时间将token进行缓存;每个接口都需要进行请求体的封装,并且需要根据响应结果对数据进行解析处理;需要将数据持久化时要使用代码实现;对每个接口访问请求都需要进行调试以确保响应的结果符合期望。编要编写代码对数据进行清洗、转换、拆单等复杂操作才能实现单据的同步当接口出现故障时还需要编写相应的告警通知代码,还需要编写重发代码等等 要实现上述聚水潭的数据同步,企业需要具有丰富经验的工程来进行开发,同时运维工作量也非常大。
三、使用零代码ETL工具实现同步: 借助成熟的ETL工具下,聚水潭开放平台可以作为数据源或目标,通过ETL工具无需代码开发即可进行各项数据处理和集成操作,节省开发成本。将聚水潭开放平台纳入ETL数据处理流程中,企业只需要普通用户即可以实现单据数据的拉取同步,并快速写入到本地数据库中或者数据仓库中,对于本地中间数据库中整理好的数据可以快速同步到金碟云星空、用友NC中。
四、将聚水潭销售同库单拉取到本地数据仓库场景 使用情景:商家需要将聚水潭中的销售出库单数据拉取到本地的数据库中,方便同步到业务系统或者数仓中进行BI分析。
以下是使用ETL工具搭建的一个自动化流程,实现将数据拉取到本地数据库中。
通过双击节点进入聚水潭节点属性配置界面并填入公共配置变量
(聚水潭登录信息填写)
(要拉取的销售出库单的范围填写)
然后点击库表输出选择本地对应表并配置字段
在选择表后组件会根据表自动生成字段,如果不需要部分字段信息,可以删除该列,这一列的数据就不会保存到数据库中
配置完节点后,点击运行流程,就可以把聚水潭的销售出库单数据拉取到本地数据库中了,可以看到通过上述ETL的流程可以简单通过配置即可实现聚水潭单据数据拉取同时也可以实现单据数据的状态同步推送等操作,无需编程只需拖、拉、拽即可快速实现。
对于复杂的数据拆单、转换、补全、合并、求和等操作ETLCloud均提供了相应的组件,对于复杂的数据计算还可以通过编写Java代码来实现。
五、更多聚水潭单据同步场景示例: 从聚水潭中同步采购退货单、销售退货单、撤销发货单等等单据通过ETL工具全部同步到本地数据库仓库中,并把清洗准备好的数据通过ETL再次同步到ERP、WMS、CRM系统中。
(聚水潭+ETL+ERP数据同步示意)
五、ETLCloud介绍 ETLCloud是一款零代码ETL工具,可以快速对接上百种数据源和主流电商应用系统,无需编码即可快速完成数据同步和传输,企业IT人员只需简单几步即可快速完成各种数据抽取同步并配合BI工具实现数据的统计分析。
(ETLCloud可视化流程同步界面)
ETLCloud社区版本永久免费下载使用 ETLCloud数据集成社区
各位同学,今天有三来发布新书了,名为《深度学习之图像识别:核心算法与实战案例(全彩版)》,本次书籍为我写作并出版的第6本书籍。
前言
2019年5月份我写作了《深度学习之图像识别:核心技术与案例实战》,迄今已经重印5次,被众多读者所认可。可见如下:言有三新书预售,不贵,有料
2019年版(全黑白印刷,正文267页)
只是这是笔者第一次执笔写书,当时笔者在互联网公司上班,时间非常紧,加之自身能力不足和水平所限,所写内容还不算太成熟和完备,仍然有大量可以改进、扩展和深入的空间。近几年,笔者进一步对相关技术进行了潜心研究和实践,对相关技术有了更加深入和全面的认识,其间还出版了几本相关图书,还与大量读者和技术爱好者进行过多次线上和线下交流,并在各大平台上进行过多场直播,收集了大量的反馈和建议,因此觉得有必要重新写一本书,分享更新、更系统、更细致和更深入的计算机视觉技术。
2022年笔者终于有一段较为空闲的时间,便投入到这本书的写作中,经过大半年时间的编写,终于完成了本书的写作任务。这本书相对于2019年版,成为了一本更系统、更细致的书籍。(2019年的书已经停止印刷,不会再提供支持,请大家直接购买2023年的新书)
本次出版的新书虽然不敢说是完美的,但的确是尽最大努力去争取做到完美,从最终呈现的效果也要远好于之前出版的图书,尤其是全彩色印刷,用的纸张还非常上档次,最终呈现的效果我还是比较满意的。我想,只要我还在这个领域,这本书我一定会持续维护下去,争取把这本书做成一本内容丰富、主体很齐全、配套很超值的经典图书,让这本书成为业内有口皆碑的书。
2023年版(全彩色印刷,正文382页)
2023年版相对于2019年版的提升
在本次出版的书籍中,我们保留了2019年版本的主要目录结构,但是重点进行了几处修改,包括:将全书所有的案例统一调整为Pytorch框架代码,新增了许多图表以及关键技术细节的描述,新增了若干重要领域的应用实践代码。
具体而言,2023年版和2019年版的不同之处主要有:
修改:给第1章和第2章新增了大量插图,便于初学者更好地进行学习。
修改:给第3章新增了大量插图,将原来第7章中的数据可视化内容移动到本章。
修改:给第4章新增了大量插图和最新研究与应用,将案例代码统一调整为Pytorch框架格式。
调整:调整了目标检测与图像分割的顺序,将目标检测放置在图像分割之前,使得本书的阅读顺序更加合理。
修改:给第5章新增了大量插图和最新研究与应用(如添加了YOLO v4和v5等内容),将案例代码统一调整为Pytorch框架格式。
修改:给第6章新增了大量插图和最新研究与应用,将案例代码统一调整为Pytorch框架格式。
修改:将原来第7章中的数据可视化内容移动到第3章,添加了3个全新的案例实践。
修改:给第8章新增了大量插图和最新研究与应用,删除了原来的案例,添加了3个全新的案例实践(结构化模型剪枝,8bit模型量化,经典知识蒸馏)。
删除:删除了原来第9章损失函数,并将相关内容融入到其他章节中。
修改:优化调整了原来第10章模型部署的内容。
本书内容
本书从深度学习的背景和基础理论开始讲起,然后介绍了深度学习中的数据使用,以及计算机视觉的三大核心领域,图像分类、图像分割、目标检测,并介绍了深度学习模型的可视化、模型的优化和部署。
全书正文约382页,共计9章,目录如下:
第1章 神经网络与卷积神经网络基础
本章首先介绍了神经网络的生物基础与数学模型,然后介绍了卷积神经网络的基础知识,这也是当前深度学习模型的基础。
第2章 深度学习优化基础
本章首先介绍了深度学习优化相关的内容,包括激活函数、标准化方法、正则化方法、最优化方法、参数初始化方法等。然后介绍了深度学习主流开源框架,包括Pytorch等,并对其特点与性能做了对比;本章旨在让大家对深度卷积神经网络的优化有一个较为全面的认识,给后续章节的学习打好基础。
第3章 深度学习中的数据
本章首先介绍了深度学习发展过程中的几个数据集,给读者展示了数据集对深度学习的重要性;接着介绍了几大重要发展方向中的数据集;接着讲述了数据的收集、整理及标注、数据增强等相关问题;最后讲述了数据的可视化与分析。本章是工业项目中非常重要的环节,也是实践性很强的内容。
第4章 图像分类
本章首先介绍了图像分类的基础、然后详细介绍了图像分类的各个研究领域,包括多类别图像分类,细粒度图像分类,多标签图像分类,半监督与无监督图像分类,零样本图像分类;在案例实践部分,首先以一个从零搭建的图像分类模型和从零准备的数据集为例,展示了如何实现一个完整的工业级图像分类任务的实践流程;然后介绍了一个细粒度级别的图像分类任务,以一个较好的基准模型,展示了较难的图像分类任务特点以及模型训练调优。
第5章 目标检测
本章首先介绍了目标检测的基础和基本流程,并讲述了一个经典的V-J目标检测框架;然后介绍了基于深度学习的目标检测任务的研究方法与发展现状,并重点总结了其中的二阶段目标检测方法与一阶段目标检测方法;最后给出了一个目标检测任务实践,使用当下比较主流的YOLO系列中的YOLO v3框架来进行模型训练与测试。
第6章 图像分割
本章首先介绍了图像分割基础与研究方向,简单回顾了经典的图像分割方法;然后介绍了基于深度学习的图像分割方法的基本原理与核心技术,并重点总结了语义分割模型、实例分割模型、Image Matting模型;在案例实践部分,以一个从零搭建的图像分割模型和从零准备的数据集为例,展示了如何实现一个完整的工业级图像分割任务的实践流程;然后介绍了一个更加复杂的人像软分割任务,展示了典型Image Matting框架的代码实现与模型训练。
第7章 模型可视化
本章首先对深度学习中的模型结构可视化做了介绍,然后对具有代表性的模型可视化分析方法进行了介绍;在案例实践部分,分别对梯度法可视化、反卷积可视化、激活热图可视化方法进行了代码分析与实践。
第8章 模型压缩
本章首先介绍了轻量级模型设计的代表性方法,然后依次详细介绍了模型剪枝、模型量化、模型蒸馏的代表性模型;在案例实践部分,分别进行了基于缩放因子的结构化模型剪枝、基于KL散度的8bit模型量化、以及经典的知识蒸馏框架的代码实现与模型训练和压缩。
第9章 模型部署
本章依托微信小程序平台从3个方面介绍了模型部署的问题。首先介绍了微信小程序的前端开发基础,然后介绍了微信小程序的服务端开发基础,最后介绍服务端算法功能代码的实现,完成了一个可供所有读者验证的工业级线上模型的部署。
详细内容请大家直接阅读书籍。本书内容由浅入深,讲解图文并茂,紧随工业界和学术界的最新发展,理论和实践紧密结合,给出了大量的图表与案例分析。本书抛开了过多的数学理论,完整地剖析了深度学习在图像识别领域中各个维度的重要技术,而不是只停留于理论的阐述和简单的结果展示,更是从夯实理论到完成实战一气呵成。相信读者跟随着本书进行学习,将会对深度学习领域的图像识别技术和其在实际开发中的应用有更深的理解。本书所有实战代码统一使用Pytorch框架,适合新手使用学习。
本书内容邀请了业内资深专家进行阅读,并获得了推荐,推荐语如下:
——中国科学院半导体研究所研究员 鲁华祥
本书作者是一位在深度学习图像识别领域工作多年的有为青年,他根据自己的工作经历和经验编写了本书。本书以理论结合案例的方式系统地介绍计算机视觉中的图像分类、目标检测和图像分割几个核心方向的研究方法,并对模型的可视化分析和压缩方法进行比较深入的介绍,是一本不可多得的图像识别技术读物,推荐给那些对深度学习和图像识别技术感兴趣的人阅读,一定大有裨益。
——阿里巴巴达摩院计算机视觉大模型负责人 赵德丽
本书对深度学习的基础知识做了详细的介绍,并且配了大量的示意图,做到了图文并茂,读起来通俗易懂。本书知识和实践并重,结合多个具体的应用案例讲解,适合学习深度学习基础知识和常见理解类任务的读者阅读。本书作者著有多本相关技术图书,经验丰富,相信这本图像识别类的图书也会给AI的普及带来助力。
——虾皮技术总监 陈强
一个好的算法工程师必须要有扎实的理论基础和丰富的实战经验。本书重点介绍了计算机视觉领域近几年的一些新进展,另外还详细地阐述了如何完成工业界的一些实用且通用的视觉任务。如果你想要成为一名计算机视觉算法工程师,那么建议你系统地阅读本书,在作者的引领下提高自己的水平。
——高途AI算法负责人 邱学侃
随着多模态大模型的技术发展,AI的能力在不断进化,我们马上就要进入真正的AI时代。以感知世界为目标的视觉图像分析算法为切入口,言有三的这本书是我们学习AI技术的一个很好的敲门砖,该书对图像识别领域中多个实际任务的数据集、任务目标、基本方法和工具框架都进行了详细介绍。读者朋友可以通过阅读本书快速理解深度学习的基础概念和理论,并能够根据相关的实战案例介绍亲自动手实践,从而提高学习效率,提升学习效果。
问题描述 当你在JavaScript中使用模块导入,你可以选择导入默认导出或者命名导出,这取决于你想要使用的功能和你的模块是如何组织的。两者之间具体有什么区别?
默认导出如下所示:
import getData from '@/api/base' 命名导出如下所示:
import { getData } from '@/api/base' 表面上两者只相差一对{},但是在区别和用法还是很不一样的。
解决方案: import { getData } from ‘@/api/base’:这种语法用于导入名为getData的命名导出。在@/api/base模块中,getData必须是一个命名导出。这意味着在@/api/base.js文件中,你会找到类似export const getData = …或者export function getData(){…}的代码。这些代码都是将getData作为一个命名导出,可以被其他模块导入和使用。
如代码:
export function getData(url, data) { return request({ url: url, method: 'get', params: data }) } import getData from ‘@/api/base’:这种语法用于导入默认导出。在@/api/base模块中,getData应该是默认导出。这意味着在@/api/base.js文件中,你会找到类似export default …的代码。这个代码将某个值(可以是一个函数、一个对象、一个类等)作为默认导出,可以被其他模块导入和使用。导入默认导出的时候,你可以给它任何你喜欢的名字,例如在这个例子中,你选择了getData作为名字。
如代码:
function getData(url, data) { return request({ url: url, method: 'get', params: data }) } export default { getData } 在JavaScript模块系统中,一个模块可以有一个默认导出和任意数量的命名导出。默认导出用export default语句导出,而命名导出则用export语句导出。默认导出在导入时可以使用任何名字,而命名导出在导入时必须使用导出时的名字,或者使用as关键字来重命名。
小白学爬虫,费了一番功夫终于成功了哈哈!本文将结合本人踩雷经历,分享给各位学友~
一、导包 import time import csv from selenium import webdriver 二、创建csv文件 用写入方式打开名为data的csv文件,并确定将要提取的五项数据。
f = open('data.csv',mode = 'w',encoding ='utf-8',newline = '') #将表头信息写入文件 csv_writer = csv.DictWriter(f,fieldnames = ['标题','价格','评论','店名','详情页']) csv_writer.writeheader() 三、搜索商品页并加载数据 #实例化浏览器对象 driver = webdriver.Edge('C:\Windows\SystemApps\Microsoft.MicrosoftEdge_8wekyb3d8bbwe\msedgedriver.exe') #访问京东网址 driver.get('https://www.jd.com/') #定位搜索框,并输入查找内容‘七夕’ driver.find_element_by_id('key').send_keys('七夕') #点击搜索按钮 driver.find_element_by_class_name('button').click() #等待界面数据加载 driver.implicitly_wait(10) #有些网页是鼠标一边下移一边加载,该函数使页面数据全部加载 def drop_down(): for x in range(1,12,2): time.sleep(1) j = x / 9 # document.documetnElement,scrollTop 指定滚动条的位置 # document.documentElement.scrollHeight 获取浏览器页面的最大高度 js = 'document.documentElement.scrollTop = document.documentElement.scrollHeight * %f' % j driver.execute_script(js) 上面第一行代码值得一提,driver = webdriver.
任务类型 线程池执行的任务可以分为两种:CPU密集型任务和IO密集型任务。在实际的业务场景中,我们需要根据任务的类型来选择对应的策略,最终达到充分并合理地使用CPU和内存等资源,最大限度地提高程序性能的目的。
CPU密集型任务 CPU密集型任务也称为计算密集型任务,包括加密、解密、压缩和计算等一系列需要大量耗费CPU资源的任务。对于CPU密集型的任务,并不是设置越多的线程性能越高,其最佳核心数是逻辑CPU核心数的1~2倍。因为对于计算任务较重的任务,CPU的每个核心基本都是满负荷的,设置更多的线程不仅不会提升性能,反而由于线程之间对CPU资源的争抢造成不必要的上下文切换导致性能下降。
IO密集型任务 IO密集型任务的特点是不会特别消耗CPU资源,但IO操作比较耗时,导致总体占用较多时间,数据库读写、文件读写、网络通信等任务都属于IO密集型任务。对于IO密集型任务,一般会将最大线程数设置为CPU核心数很多倍。IO读写速度相比于CPU计算的速度要慢很多,如果设置的线程数较少,线程可能都在处理IO操作,导致CPU资源的浪费。如果设置较多的线程数,当一部分线程在等待IO的时候,这部分线程不需要CPU资源,其他的线程就可以利用CPU资源去执行其他任务。
线程数计算方法 可以通过下面的公式计算出一个合理的线程数量。
线程数 = CPU核心数 × (1 + 任务平均等待时间/CPU平均工作时间) 可以看出线程数与任务平均等待时间成正比,任务的平均等待时间越长,线程数就越多;与CPU平均工作时间成反比,CPU平均工作时间越长,线程数就越少。例如CPU密集型任务的特点是CPU平均工作时间较长,而任务的平均等待时间较短,因此此类型所需的线程数较少;IO密集型任务的特点是任务平均等待时间较长,CPU平均工作时间较短,因此此类型所需的线程数较多。
分治算法 分治算法的基本思想是将一个规模较大的问题分解为多个规模较小的子问题,这些子问题之间相互独立且与原问题的性质相同。将所有子问题的解求出来,原问题的解也就求出来了。
分治算法的步骤如下:
分解:将要解决的问题划分成若干规模较小的同类子问题;求解:当子问题划分得足够小时,可以用很简单的方式计算出子问题的解;合并:将子问题的解逐层合并,最终得到原问题的解。 以上过程可以表示如下图:
ForkJoin框架 传统的线程池ThreadPoolExecutor有以下两个缺点:
无法对大任务进行拆分,即只能由单个线程去完成某项任务;工作线程从队列中获取任务时存在竞争。 为了解决以上问题,JDK1.7引入了ForkJoin框架。ForkJoin框架允许其他线程向其提交任务,并将任务拆分成粒度更细的子任务,这些子任务由ForkJoin框架内部的工作线程来并行执行,并且这些工作线程之间可以互相窃取任务执行。
主要API ForkJoin框架主要包含两部分:
分治任务的线程池ForkJoinPool类;分治任务ForkJoinTask类。 ForkJoinPool ForkJoinPool是用于执行ForkJoinTask任务的执行池,继承了AbstractExecutorService类。ForkJoinPool的构造函数有多个,此处我们介绍其中参数最全的一个,其实现如下:
public ForkJoinPool(int parallelism, ForkJoinWorkerThreadFactory factory, UncaughtExceptionHandler handler, boolean asyncMode) { this(checkParallelism(parallelism), checkFactory(factory), handler, asyncMode ? FIFO_QUEUE : LIFO_QUEUE, "ForkJoinPool-" + nextPoolId() + "-worker-"); checkPermission(); } parallelism:表示指令的并行级别,ForkJoinPool将根据这个值来决定工作线程的数量,默认使用Runtime.getRuntime().availableProcessors()来设置;factory:ForkJoinPool内部创建线程使用的线程工厂,需要注意的是,此处的线程工厂的类型是ForkJoinWorkerThreadFactory而不是ThreadFactory,默认使用DefaultForkJoinWorkerThreadFactory;handler:异常处理器,主要用于处理任务运行中出现的异常;asyncMode:队列的工作模式,为true时使用先进先出模式,为false时使用先进后出模式。 ForkJoinPool提交任务的方法主要有以下几种:
execute():在提交任务后不会返回结果,支持ForkJoinTask类型和Runnable两种类型的任务; public void execute(ForkJoinTask<?> task); public void execute(Runnable task); invoke():在任务执行结束后返回泛型执行结果,支持ForkJoinTask类型的任务; public <T> T invoke(ForkJoinTask<T> task); submit():在提交任务后返回ForkJoinTask类型的结果,如果任务不能按计划执行则抛出任务拒绝异常,支持ForkJoinTask类型、Callable类型和Runnable类型的任务。 public <T> ForkJoinTask<T> submit(Callable<T> task); public <T> ForkJoinTask<T> submit(Runnable task, T result); public ForkJoinTask<?
阻塞队列BlockingQueue 阻塞队列与其他类型的队列不同的地方在于阻塞,即对于生产者和消费者两端来说,有任何一端的速度过快时,阻塞队列可以把过快的速度降下来。例如对于一个大小为10的阻塞队列,当生产者线程过快时,在某个时刻队列就会被装满,此时生产者线程被阻塞直到队列中有空的位置;当消费者线程过快时,在某个时刻队列是空的,此时消费者线程被阻塞直到队列中有元素。
Java中的阻塞队列的定义是BlockingQueue,它继承了队列Queue接口,我们先来了解下Queue接口。
Queue Queue是队列的顶级接口,定义了一些出队和入队的操作,这些操作以及它们的作用如下:
boolean add(E e):向队列中添加元素,成功返回true,队列满时抛异常;boolean offer(E e):向队列中添加元素,成功返回true,队列满时返回false;E remove():删除队首的元素并返回,队列为空时抛异常;E poll():删除队首的元素并返回,队列为空时返回null;E element():返回队首元素,队列为空时抛异常;E peek():返回队首元素,队列为空时返回null。 BlockingQueue BlockingQueue继承了Queue接口,在其基础上添加了几个用于支持阻塞特性的方法,其中最关键的是take()方法和put()方法。
take():作用是获取并移除队列的头节点。当队列中有数据的时候take()方法可以正确移除;当队列中没有数据时,则阻塞,直到队列有至少一个数据。put():作用是向队列中插入一个元素。当队列有空闲空间时put()方法可以正确插入;当队列已满时,则阻塞,直到队列中至少有一个空闲空间。offer(E e,long timeout,TimeUnit unit):向队列中插入一个元素,可以设置阻塞时间。插入元素时如果队列已满则阻塞,超过阻塞时间返回false。poll(long timeout,TimeUnit unit):获取并删除队首元素,可以设置阻塞时间。获取元素时如果队列为空则阻塞,超过阻塞时间返回null。 Queue接口和BlockingQueue接口的方法都是出队、入队或访问队首元素的方法,总结如下表:
作用\效果
不满足时抛异常
不满足时返回特定值
阻塞
阻塞指定时间
入队
add(e)
offer(e)
put(e)
offer(e,time,unit)
获取队首元素并出队
remove()
poll()
take()
poll(time,unit)
获取队首元素
element()
peek()
不支持
不支持
是否有界 阻塞队列根据其容量的大小,可以分为有界和无界两种。其中无界队列并不是真正的无界,只是表示可以容纳非常多的元素,例如LinkedBlockingQueue阻塞队列的上限是Integer.MAX_VALUE;有界队列的容量是有限的,例如ArrayBlockingQueue是由数组实现的,如果容量满了也不会扩容。
应用场景 BlockingQueue是线程安全的,因此即便生产者和消费者都是多线程的,使用阻塞队列时也不会发生线程安全问题。
队列还能起到隔离的作用,将具体任务与执行任务解耦,即将任务放到阻塞队列中,放任务的线程与执行任务的线程是不相关的,提高了安全性。
常见阻塞队列 BlockingQueue接口的实现类都在JUC包中,它们的区别主要体现在存储结构和元素操作的不同。常见的阻塞队列如下:
ArrayBlockingQueue:基于数组结构实现,有界阻塞队列;LinkedBlockingQueue:基于链表结构,无界阻塞队列;PriorityBlockingQueue:支持按优先级排序,无界阻塞队列;DelayQueue:基于优先级队列,无界阻塞队列;SynchronousQueue:不存储元素的阻塞队列;LinkedTransferQueue:基于链表结构,无界阻塞队列;LinkedBlockingDeque:基于链表结构,双端阻塞队列。 ArrayBlockingQueue ArrayBlockingQueue是最典型的有界阻塞队列,其内部是用数组来存储元素的,因此初始化时需要指定容量大小。在生产者-消费者模型中,如果生产速度和消费速度基本匹配,可以优先考虑使用ArrayBlockingQueue。
成员变量 ArrayBlockingQueue是基于数组实现的,因此内部有一个数组类型的属性items以及表示数组实际存储元素的数量count。
final Object[] items; int count; ArrayBlockingQueue遵循队列“先进先出”的原则,在队尾将元素入队,在队首将元素出队,因此还需要两个“指针”来分别表示出队的数组下标和入队的数组下标。
int takeIndex;//出队指针 int putIndex;//入队指针 ArrayBlockingQueue实现线程安全的方式是使用一个ReentrantLock独占锁,由于队列为空或队列满的时候需要分别阻塞消费者线程和生产者线程,因此还需要两个条件队列。
final ReentrantLock lock; private final Condition notEmpty;//当队列为空时,阻塞消费者线程 private final Condition notFull;//当队列已满时,阻塞生产者线程 构造函数 ArrayBlockingQueue由于是基于数组实现的,因此至少要传入数组的容量大小。
CyclicBarrier翻译过来是回环栅栏,它可以实现让一组线程等待至某个状态之后再全部同步执行,这个状态叫屏障点。当所有等待线程都被释放后,CyclicBarrier可以重置再次使用。
CyclicBarrier的功能是由ReentrantLock和Condition共同实现的,因此在其内部拥有ReentrantLock类型的lock属性和Condition类型的trip属性。此外,还有用于保存该屏障拦截的线程数parties属性和当前剩余等待的线程数count属性。这些属性的作用在后面我们详细介绍源码时再详细介绍。
CyclicBarrier的构造函数如下:
//parties表示当前屏障拦截的线程数 public CyclicBarrier(int parties) { this(parties, null); } //barriesAction表示当所有线程都到达屏障时首先执行的行为 public CyclicBarrier(int parties, Runnable barrierAction) { if (parties <= 0) throw new IllegalArgumentException(); this.parties = parties; this.count = parties; this.barrierCommand = barrierAction; } 常用方法如下:
public int await() throws InterruptedException, BrokenBarrierException:当前线程阻塞,直到parties个线程全部调用await()方法时再唤醒。BrokenBarrierException异常表示栅栏已被破坏,可能是由于其中的一个线程await()时被中断或超时;public void reset():重置屏障计数器的值,并将条件队列的所有线程唤醒。 由于CyclicBarrier的计数器可以重置,屏障可以重复使用,因此当paries的整数倍数量的线程调用await()方法时程序都是可以正常结束的,否则由于还有线程在阻塞,程序会一直阻塞不会结束。例如下面的程序中定义了屏障的拦截线程数paties=3,随后分别在7个线程中调用CyclicBarrier的await()方法。
public class CyclicBarrierTest { public static void main(String[] args) { CyclicBarrier cyclicBarrier = new CyclicBarrier(3); for (int i = 0; i < 7; i++) { new Thread(() -> { try { System.
发现的问题 在微服务开发中,gRPC 的应用绝对少不了,一般情况下,内部微服务交互,通常是使用 RPC 进行通信,如果是外部通信的话,会提供 https 接口文档
对于 gRPC 的基本使用可以查看文章 gRPC介绍
对于 gRPC ,我们需要基本知道如下的一些知识点:
gRPC 的基本四种模式的应用场景
请求响应模式客户端数据流模式服务端数据流模式双向流模式 Proto 文件的定义和使用 gRPC 拦截器的应用 , 基本的可以查看这篇 gRPC 拦截器
实际上有客户端拦截器 和 服务端拦截器,具体详细的可以自行学习 gRPC 的设计原理细节 Go-Kit 的使用 当然今天并不是要聊 gRPC 的应用或者原理,而是想聊我们在开发过程中很容易遇到的问题:
未复用 gRPC 客户端连接,影响性能 最近审查各个服务代码中,发现整个部门使用 gRPC 客户端请求服务端接口的时候,都是会新建一个连接,然后调用服务端接口,使用完毕之后就 close 掉, 例如这样
这会有什么问题呢?
正常简单的使用不会有啥问题,但如果是面临高并发的情况,性能问题很容易就会出现,例如我们在做性能测试的时候,就会发现,打一会性能测试,客户端请求服务端的时候就会报错:
rpc error: code = Unavailable desc = all SubConns are in TransientFailure, latest connection error: connection error: desc = "transport: Error while dialing dial tcp xxx:xxx: connect: connection refused
实验拓扑图 如图1所示,本次实验使用了6台路由器(R1-R6),其中R3、R4、R5作为运营商网络中的P或PE路由器,R1、R2作为VPN客户端(CE)路由器,R6作为VPN客户端要访问的目标路由器。运营商网络使用OSPF作为IGP协议,并开启MPLS LDP功能。PE路由器使用MP-BGP协议发布VPN路由信息,并创建两个VRF实例(1和2)对应两个VPN客户。CE路由器使用静态路由与PE路由器互通。
实验目的和需求 本次实验旨在通过以下几个方面达到以下目的:
了解MPLS VPN的基本原理和配置方法,包括MPLS LDP、MP-BGP、VRF、RD、RT等概念和功能.。 掌握VRF、RD和RT的作用和配置方法,包括如何创建VRF实例、如何指定RD和RT值、如何将接口划分到VRF中等。
验证MPLS VPN的功能和效果,包括如何测试不同VPN之间的连通性和隔离性。
实验步骤 1. 配置IP地址和路由协议
- 在CE、PE和P路由器上配置IP地址和路由协议,使得各个路由器之间可以互相ping通
- 在PE路由器上配置loopback0接口,作为BGP的源地址
- 在P路由器上配置MPLS LDP,使得P路由器之间可以建立标签交换路径
2. 配置VRF和RD
- 在PE路由器上创建两个VRF实例,分别命名为1和2,分别对应两个VPN客户
- 在每个VRF实例下配置RD值,使得同一VPN内的IP地址可以区分开来
- 在PE路由器上将连接CE的接口划分到相应的VRF中,使得不同VPN之间可以隔离
3. 配置MP-BGP和RT
- 在PE路由器上配置MP-BGP,并激活VPNv4邻居会话,使得PE之间可以交换VPN路由信息
- 在每个VRF实例下配置RT值,使得不同VPN之间可以根据需要导入或导出路由信息
- 在PE和CE之间配置相应的动态或静态路由协议,并根据需要重新分发路由信息
1. 配置IP地址和路由协议 在CE、PE和P路由器上配置IP地址和路由协议,使得各个路由器之间可以互相ping通
在PE路由器上配置loopback0接口,作为BGP的源地址
在P路由器上配置MPLS LDP,使得P路由器之间可以建立标签交换路径
(首先要在系统界面下开启mpls ldp)
在R3、R4、R5上开启MPLS LDP功能,并配置OSPF协议,如下:
r3 r4 r5上操作 [r3][r4][r5]mpls [r3][r4][r5]mpls ldp [r3][r4][r5]qui [r3] ospf 1 router-id 3.3.3.3 area 0.0.0.0 # interface GigabitEthernet0/0/2 ip address 34.1.1.3 255.255.255.0 ospf enable 1 area 0.
一、OpenGL介绍 OpenGL是一个用来加速渲染显示2D、3D 矢量图形的编程接口。这个接口底层依赖于硬件GPU,底层硬件接口的驱动都是由GPU厂家提供。
openGl也支持跨平台,windows、Linux、MAC 平台都可以使用。
QT封装有QOpenGLWidget可以更加方便的调用GPU 来渲染图片。
下面例子代码就介绍QOpenGLWidget类的使用说明,并编写一个例子代码,调用GPU加速渲染一张QImage加载的图片。
二、QOpenGLWidget类介绍 下面是来至官方帮助的文档的介绍,我这里做了简单的调整,并翻译了一下:
QOpenGLWidget类是一个用于呈现OpenGL图形的小部件。
QOpenGLWidget提供了显示集成到Qt应用程序中的OpenGL图形的功能。它的使用非常简单:使你的类继承自它,并像任何其他QWidget一样使用子类,但你可以选择使用QPaint和标准OpenGL渲染命令。
QOpenGLWidget提供了三个方便的虚拟函数,你可以在子类中重新实现这些函数以执行典型的OpenGL任务:
paintGL()-渲染OpenGL场景。每当小部件需要更新时调用。
resizeGL()-设置OpenGL视口、投影等。每当小部件调整大小时(以及首次显示时,因为所有新创建的小部件都会自动获得调整大小事件),都会调用该小部件。
initializeGL()-设置OpenGL资源和状态。在第一次调用resizeGL()或paintGL()之前调用一次。
如果需要从paintGL()以外的位置触发重新绘制(典型示例是使用计时器设置场景动画),则应调用小部件的update()函数来安排更新。
调用paintGL()、resizeGL()或initializeGL()时,小部件的OpenGL呈现上下文将变为当前。如果需要从其他位置(例如,在小部件的构造函数或自己的绘制函数中)调用标准OpenGL API函数,则必须首先调用makeCurrent()。
所有渲染都发生在OpenGL帧缓冲区对象中。makeCurrent()确保它在上下文中绑定。在paintGL()中的渲染代码中创建和绑定其他帧缓冲区对象时,请记住这一点。永远不要重新绑定ID为0的帧缓冲区。相反,调用defaultFramebufferObject()获取应该绑定的ID。
QOpenGLWidget允许在平台支持时使用不同的OpenGL版本和配置文件。只需通过setFormat()设置请求的格式。但是请记住,在同一窗口中有多个QOpenGLWidget实例需要它们都使用相同的格式,或者至少使用不会使上下文不可共享的格式。要解决此问题,请首选使用QSurfaceFormat::setDefaultFormat()而不是setFormat()。
注意:在某些平台(例如macOS)上,当请求OpenGL核心概要文件上下文时,在构造QApplication实例之前调用QSurfaceFormat::setDefaultFormat()是必需的。这是为了确保上下文之间的资源共享保持功能,因为所有内部上下文都是使用正确的版本和概要文件创建的。
绘画技巧
如上所述,子类QOpenGLWidget以以下方式呈现纯3D内容:
重新实现initializeGL()和resizeGL()函数,以设置OpenGL状态并提供透视转换。
重新实现paintGL()以绘制3D场景,仅调用OpenGL函数。
还可以使用QPaint在QOpenGLWidget子类上绘制2D图形: 在paintGL()中,不要发出OpenGL命令,而是构造一个QPainter对象以在小部件上使用。
使用QPaint的成员函数绘制基本体。仍然可以发出直接的OpenGL命令。但是,你必须确保调用画家的BeginativePainting()和endNativePainting()来包含这些内容。
当仅使用QPaint执行绘制时,也可以像对普通小部件一样执行绘制:通过重新实现paintEvent()。 重新实现paintEvent()函数。构造一个针对小部件的QPaint对象。将小部件传递给构造函数或QPaint::begin()函数。 使用QPaint的成员函数绘制基本体。绘制完成后,QPaint实例将被销毁。或者,显式调用QPaint::end()。
三、例子代码 3.1 头文件: 重载QOpenGLWidget ifndef MYGLWIDGET_H #define MYGLWIDGET_H #include <QObject> #include <QOpenGLWidget> #include <GL/gl.h> #include <GL/glu.h> #include <QOpenGLFunctions> #include <QOpenGLShaderProgram> #include <QOpenGLTexture> #include <QGLWidget> #include <QImage> class MyGLWidget : public QOpenGLWidget, protected QOpenGLFunctions { Q_OBJECT public: explicit MyGLWidget(QWidget *parent = 0); signals: public slots: void initializeGL() Q_DECL_OVERRIDE; void resizeGL(int w, int h) Q_DECL_OVERRIDE; void paintGL() Q_DECL_OVERRIDE; void setImage(const QImage &image); void initTextures(); void initShaders(); private: QVector<QVector3D> vertices; QVector<QVector2D> texCoords; QOpenGLShaderProgram program; QOpenGLTexture *texture; QMatrix4x4 projection; }; #endif // MYGLWIDGET_H 3.
机器学习笔记之优化算法——经典牛顿法 引言回顾:下降方向下降方向的几何意义 经典牛顿法整体介绍关于牛顿方向判断牛顿方向是否为下降方向 引言 本节将介绍优化算法——经典牛顿法 ( Newton Method ) (\text{Newton Method}) (Newton Method)。
回顾: 下降方向 在线搜索方法——方向角度中介绍了下降方向 ( Descent Direction ) (\text{Descent Direction}) (Descent Direction)的概念。首先,通过推导得到如果更新方向 P k \mathcal P_k Pk与梯度方向 ∇ f ( x k ) \nabla f(x_k) ∇f(xk)之间满足如下关系:
[ ∇ f ( x k ) ] T ⋅ P k < 0 [\nabla f(x_k)]^T \cdot \mathcal P_k <0 [∇f(xk)]T⋅Pk<0
那么称将更新方向 P k \mathcal P_k Pk称作下降方向。
需要注意的是,下降方向是线搜索方法关于方向角度的一个概念,而不是仅存在于梯度下降法。而最速下降方向是与梯度方向相反的方向,也是梯度下降法的选择方向。
下降方向的几何意义 观察上述不等式左侧是向量 ∇ f ( x k ) \nabla f(x_k) ∇f(xk)与向量 P k \mathcal P_k Pk的内积形式,将其展开:
项目管理过程中,会使用并产生两大类文件:项目管理计划和项目文件。内容一般如下:
整个项目生命周期需要收集、分析和转化大量的数据。从各个过程收集项目数据,并在项目团队内共享。在各个过程中所收集的数据经过结合相关背景的分析、汇总,并加工成项目信息。信息通过口头形式进行传达,或以各种格式的报告存储和分发。关于这一主题的更多信息,请参见 4.3 节。
一、项目文件 1、活动属性 活动属性是指每项活动所具有的多重属性,用来扩充对活动的描述。
活动属性随时间演进:
在项目初始阶段,活动属性包括唯一活动标识 (ID)、WBS 标识和活动标签或名称;
在活动属性编制完成时,活动属性可能包括活动描述、紧前活动、紧后活动、逻辑关系、提前量和滞后量、资源需求、强制日期、制约因素和假设条件。
活动属性可用于识别开展工作的地点、编制开展活动的项目日历,以及相关的活动类型。活动属性还可用于编制进度计划。根据活动属性,可在报告中以各种方式对计划进度活动进行选择、排序和分类。
2、活动清单 活动清单包含项目所需的进度活动,包括每个活动的标识及工作范围详述,使项目团队成员知道需要完成什么工作。
对于使用滚动式规划或敏捷技术的项目,活动清单会在项目进展过程中得到定期更新。
3、假设日志 假设日志用于记录整个项目生命周期中的所有假设条件和制约因素。
高层级的战略和运营假设条件与制约因素,在项目启动之前,进行可行性研究和论证时,即开始识别,然后纳入项目章程;低层级的,在项目开展期间生成。
假设日志基于当前被认为正确、真实的信息,提出这些制约因素,让相关方的期望趋于合理。如天气的影响,下雨将导致项目不能正常进行。只有尽早澄清这些假设日志,才不会让相关方觉得这种情况项目没有进行是可接受的。
特点:假设日志越多,项目风险越大。
4、估算依据 估算依据说明不同估算是如何得出的,用于决定如何应对偏差。
项目管理中包含进度估算、成本估算和资源估算三种类型,估算依据是在项目估算当中,所用依据的一个支持性的文件。包含假设条件、制约因素、详细级别、估算区间和置信水平。
置信水平是指特定个体对待特定命题真实性相信的程度,也就是概率,是对个人信念合理性的量度。(令人难以置信)
5、变更日志 变更日志用于记录项目期间发生的变更。十大知识领域都有可能发生变更。
6、成本估算 成本估算所需的支持信息的数量和种类,因应用领域而异,不论其详细程度如何,支持性文件都应该清晰、完整地说明成本估算是如何得出的。
成本估算的支持信息可包括:
关于估算依据的文件(如估算是如何编制的);
关于全部假设条件的文件;
关于各种已知制约因素的文件;
有关已识别的、在估算成本时应考虑的风险的文件;
对估算区间的说明(如“10,000美元 ±10%”就说明了预期成本的所在区间);
对最终估算的置信水平的说明。
7、持续时间估算 持续时间估算是对完成某项活动、阶段或项目所需的工作时段数的定量评估,其中并不包括任何滞后量,但可指出一定的变动区间。例如:
2 周 ± 2 天,表明活动至少需要 8 天,最多不超过 12 天(假定每周工作 5 天);
超过 3 周的概率为 15%,表明该活动将在 3 周内(含 3 周)完工的概率为 85%。
8、问题日志 问题日志。作为实施风险应对过程的一部分,已识别的问题会被记录到问题日志中。用于记录和监督问题的解决。
问题日志强调的是干系人对项目上的关注和关心(concern),这些关注和关心的英文是“Issue”,这些“issue”可能是项目的问题(Problem)也可能是项目的风险(risk)。
PM在和关键干系人沟通时会借助问题日志进行沟通,例如针对这个issue已经提出了变更请求或者已经作为风险进行应对了等等,这些都是针对该issue的解决措施。
答案是:A/A/A
9、经验教训登记册 经验教训登记册可以记录遇到的挑战、问题、意识到的风险和机会,或其他适用的内容。
经验教训登记册在项目早期创建,作为本过程的输出。因此,在整个项目期间,它可以作为很多过程的输入,也可以作为输出而不断更新。参与工作的个人和团队也参与记录经验教训。可以通过视频、图片、音频或其他合适的方式记录知识,确保有效吸取经验教训。
在项目或阶段结束时,把相关信息归入经验教训知识库,成为组织过程资产的一部分。
10、里程碑清单 里程碑是项目中的重要时点或事件,里程碑清单列出了所有项目里程碑,并指明每个里程碑是强制性的(如合同要求的)还是选择性的(如根据历史信息确定的)。里程碑的持续时间为零,因为它们代表的是一个重要时间点或事件。
1、简述: mysql数据迁移有多种方式,最常见的就是先把数据库导出,然后导入新的数据库。拷贝数据目录data是另外一种方式。
尤其是当数据库启动不了,或者大型数据库迁移的时候,可以考虑这个方式。
2、场景: 从老的mysql(mysqlA)迁移到新的mysql(mysqlB)。mysqlA对应的数据路径为:/var/lib/mysql-old,mysqlB对应的数据路径为:/var/lib/mysql。
3、迁移示意图: 4、步骤: 1、停止mysqlB。
2、移除 /var/lib/mysql 路径下除 performance_schema 文件夹的其余文件。
3、拷贝 /var/lib/mysql-old 路径下所有文件到 /var/lib/mysql,除了 performace_schema、iblogfile_0,iblogfile_1。
4、现在/var/lib/mysql下面的文件来源和作用是:
performace_schema: 新,性能监控,它在5.6及其之前的版本中,默认没有启用,从5.7及其之后的版本才修改为默认启用。数据库目录:老,具体存储数据的目录,每个数据库对应一个文件夹,文件夹的名字和数据库的名称一致。ibdata1: 老,用来构建innodb系统表空间的文件,这个文件包含了innodb表的元数据、undo日志、修改buffer和双写buffer。iblogfile_0,iblogfile_1: 新,日志文件,被删除了,重启后会重新生成。 5、重启mysqlB。
(1)Alt+F11进入VBA (2)点击插入——模块 (3)复制以下代码 Function pinyin(p As String) As String i = Asc(p) Select Case i Case -20319 To -20318: pinyin = "a" Case -20317 To -20305: pinyin = "ai" Case -20304 To -20296: pinyin = "an" Case -20295 To -20293: pinyin = "ang" Case -20292 To -20284: pinyin = "ao" Case -20283 To -20266: pinyin = "ba" Case -20265 To -20258: pinyin = "bai" Case -20257 To -20243: pinyin = "
渗透测试介绍 渗透测试就是模拟攻击者入侵系统,对系统进行一步步地渗透,发现系统地脆弱环节和隐藏风险。最后形成测试报告提供给系统所有者。系统所有者可根据该测试报告对系统进行加固,提升系统的安全性,防止真正的攻击者入侵。
渗透测试的前提一定是得经过系统所有者的授权!
未经过授权的渗透测试,就是违法行为!
渗透测试意义 信息安全评估的重要方法,有利于掌握系统整体安全强度。
模拟黑客攻击和思维,评估计算机潜在风险。
发现系统薄弱环节和可能利用的路径,提前防范。
有授权,不存在入侵风险。
渗透测试方法 --白盒测试
在知道目标整体信息和源码的情况下进行渗透,类似于代码审计。
--黑盒测试
仅知道目标,其余信息均不知道,完全模拟黑客入侵。
--灰盒测试
知道目标部分信息,例如架构和网络拓扑,进行渗透的方式。
(若按照其他方式还可分为人工测试和自动化测试)
渗透测试一般流程 准备阶段—>信息收集—>漏洞检测—>漏洞利用—>内网转发—>内网渗透—>痕迹清除—>撰写报告
--准备阶段
获得授权 制定方案 目标确定 测试环境确定 测试范围和深度 测试时间确定 测试风险管理
--信息收集
信息收集两种方法
主动信息收集:对目标进行访问或扫描。
被动信息收集:通过第三方收集目标信息。
主要收集的信息
1.域名信息,ip,子域名,DNS记录 是否存在CDN。子域名收集可利用工具:Layer子域名挖掘机,findmain等
2.公网信息。目标相关信息。员工信息,邮箱,注册人等;在Github等代码托管平台查找敏感信息。
3.网站指纹识别。服务器类型(Windows\Linux) 网站容器(Apache\Nginx\Tomcat\IIS)
脚本类型(php\jsp\asp\aspx) 数据库类型(mysql\oracle\access\sqlserver\redis)
4.服务器端口开放情况。可以使用nmap 御剑等工具
ssh弱口令 22 mysql弱口令 3306 redis未授权 6379
weblogic反序列化漏洞 7001 web中间件漏洞 80
5.敏感目录。可以使用御剑,wwwscan,dirmap等扫描
后台目录,默认路径。
6.旁站和c段
旁站指同一服务器上的其他网站。可利用旁站进行渗透。
c段指同一网段内的其他服务器。对同目标C段内的服务器进行渗透提权,再对目标进行渗透。
常见扫描工具:Nessus,X-SCAN NAMP --漏洞检测
主要根据PWASP Top10
1.注入 sql注入,XXE注入,LDAP注入,系统命令注入,远程代码执行
2.失效的身份认证和会话管理 弱口令暴力破解,cookie伪造和cookie绕过,逻辑绕过登录,会话劫持
3.跨站脚本攻击XSS
4.失效的访问控制 未授权访问 ,越权访问(水平越权和垂直越权),文件操作(文件上传,文件包含,任意文件下载)
数学中矩的概念来自物理学。在物理学中,矩是表示距离和物理量乘积的物理量,表征物体的空间分布。矩在统计学和图像中都有很重要作用,我们常用的Adam优化器其全称为自适应矩估计优化器。本文将介绍各阶矩的理解和不同场景的应用。
Key Words:矩的意义、统计矩、图像矩
1、矩的物理意义 在物理学中,矩是表示距离和物理量乘积的物理量,表征物体的空间分布。矩通常需要一个参考点(基点或参考系)来定义距离。如力和参考点距离乘积得到的力矩(或扭矩),原则上任何物理量和距离相乘都会产生矩,如:质量,电荷分布等。
如果点表示质量:
零阶矩:表示总质量。一阶原点矩:表示质心。二阶原点矩:表示转动惯量。 如果点表示高度:
零阶矩:表示所有点高度之和。一阶原点矩:表示点的位置和对应高度乘积之和,表示所有高度的中心。二阶中心矩:表示所有点的高度波动范围。 2、矩的数学意义 数学上,矩是一组点组成的模型的特定的数量测度。
定义:设 X X X 和 Y Y Y 是离散随机变量, c c c 为场数, k k k 为正整数,
如果 E ( ∣ X − c ∣ k ) E(|X-c|^{k}) E(∣X−c∣k) 存在,则称 E ( ∣ X − c ∣ k ) E(|X-c|^{k}) E(∣X−c∣k) 为 X X X 关于点 c c c 的 k k k 阶矩。
c = 0 c=0 c=0 时,称为 k k k 阶原点矩; c = E ( X ) c=E(X) c=E(X) 时,称为 k k k 阶中心距。 如果 E ( ∣ X − c 1 ∣ p ⋅ ∣ Y − c 2 ∣ q ) E(|X-c_{1}|^{p} \cdot |Y-c_{2}|^{q}) E(∣X−c1∣p⋅∣Y−c2∣q) 存在,则称其为 X , Y X,Y X,Y 关于 c c c 点的 p + q p+q p+q 阶矩。
文章目录 前言一、Loading白名单二、取消请求1. 自动处理2. 手动操作2.1 调用方式2.2 错误处理 总结 前言 之前写过一篇关于axios封装的文章(axios封装—vue3项目),最近又有一点新的收获,关于loading提示的控制以及取消请求的逻辑,所以赶紧写写文章总结记录下来,顺便分享给大家。
一、Loading白名单 关于接口请求Loading的部分,贴一下之前写的部分代码:
// loading 次数 let loadingCount = 0; service.interceptors.request.use( config => { // 加入Loading showLoadingToast({ message: '加载中...', //禁止背景点击 forbidClick: true, }); loadingCount++; return config; }, error => { return Promise.reject(error); } ); 由于之前是在axios的请求拦截器里加入Loading的,这样相当于给所有接口都加上了,不够灵活,所以需要改进一下,给某些接口一个escape hatch(安全舱口):
// 定义白名单,里面的接口请求不会有Loading图标 const whiteList = ['getList']; // 请求拦截器 service.interceptors.request.use( config => { // 加入Loading,白名单控制; let url = config.url; let index = url.lastIndexOf('/'); let endIndex = url.
渗透测试介绍 渗透测试就是模拟攻击者入侵系统,对系统进行一步步地渗透,发现系统地脆弱环节和隐藏风险。最后形成测试报告提供给系统所有者。系统所有者可根据该测试报告对系统进行加固,提升系统的安全性,防止真正的攻击者入侵。
渗透测试的前提一定是得经过系统所有者的授权!
未经过授权的渗透测试,就是违法行为!
渗透测试意义 信息安全评估的重要方法,有利于掌握系统整体安全强度。
模拟黑客攻击和思维,评估计算机潜在风险。
发现系统薄弱环节和可能利用的路径,提前防范。
有授权,不存在入侵风险。
渗透测试方法 --白盒测试
在知道目标整体信息和源码的情况下进行渗透,类似于代码审计。
--黑盒测试
仅知道目标,其余信息均不知道,完全模拟黑客入侵。
--灰盒测试
知道目标部分信息,例如架构和网络拓扑,进行渗透的方式。
(若按照其他方式还可分为人工测试和自动化测试)
渗透测试一般流程 准备阶段—>信息收集—>漏洞检测—>漏洞利用—>内网转发—>内网渗透—>痕迹清除—>撰写报告
--准备阶段
获得授权 制定方案 目标确定 测试环境确定 测试范围和深度 测试时间确定 测试风险管理
--信息收集
信息收集两种方法
主动信息收集:对目标进行访问或扫描。
被动信息收集:通过第三方收集目标信息。
主要收集的信息
1.域名信息,ip,子域名,DNS记录 是否存在CDN。子域名收集可利用工具:Layer子域名挖掘机,findmain等
2.公网信息。目标相关信息。员工信息,邮箱,注册人等;在Github等代码托管平台查找敏感信息。
3.网站指纹识别。服务器类型(Windows\Linux) 网站容器(Apache\Nginx\Tomcat\IIS)
脚本类型(php\jsp\asp\aspx) 数据库类型(mysql\oracle\access\sqlserver\redis)
4.服务器端口开放情况。可以使用nmap 御剑等工具
ssh弱口令 22 mysql弱口令 3306 redis未授权 6379
weblogic反序列化漏洞 7001 web中间件漏洞 80
5.敏感目录。可以使用御剑,wwwscan,dirmap等扫描
后台目录,默认路径。
6.旁站和c段
旁站指同一服务器上的其他网站。可利用旁站进行渗透。
c段指同一网段内的其他服务器。对同目标C段内的服务器进行渗透提权,再对目标进行渗透。
常见扫描工具:Nessus,X-SCAN NAMP --漏洞检测
主要根据PWASP Top10
1.注入 sql注入,XXE注入,LDAP注入,系统命令注入,远程代码执行
2.失效的身份认证和会话管理 弱口令暴力破解,cookie伪造和cookie绕过,逻辑绕过登录,会话劫持
3.跨站脚本攻击XSS
4.失效的访问控制 未授权访问 ,越权访问(水平越权和垂直越权),文件操作(文件上传,文件包含,任意文件下载)
李松斌,刘鹏著,科学出版社
2023年5月20日16:32:38开始阅读,2023年7月12日读完。
1.基础知识 获得泛化能力是深度学习的最终目标。泛化能力是指处理未被观察个的数据的能力(即不包含在训练数据中的数据)。
训练集:训练模型
测试集:测试模型的泛化能力
验证集:验证模型是否过拟合
数据增强的常用方法:
● 翻折(类似于镜面的翻折);
● 旋转
● 缩放
● 裁剪
● 平移
● 添加噪声
神经网络学习的目的就是为了找出能使得损失函数的值达到最小的权重参数。
深度学习中常见的两大类问题:分类和回归。
分类问题是依据已有的信息进行整合,最后输出离散的类别值;
回归是指通过已知去预测未知,输出是连续的。
最优化的方法:
● 梯度下降法(寻找最小值)
● 梯度上升法 (寻找最大值)
● 随机梯度下降法 SGD
● 自适应梯度法(AdaGrad):对每个参数乘以不同的系数,每个参数所乘的系数通过之前积累的梯度大小的平方和来决定,对于更新频率高的参数,可以设置较小的学习率,更新慢一点;对于更新频率低的参数可以设置较大一点的学习率,更新快一点。
【具体做法】将每一维参数各自的历史梯度的平方叠加起来,然后在更新的时候除以该历史梯度值。
● 自适应矩估计(Adam)
2.深度学习图像分类算法核心 图像分类要解决的**“是什么”**的问题,也就是输入一张图像,输出该图像所属的类别。
基于深度学习的图像分类属于一种端到端的模型。
图像分类的难点可以分为:实例层次、类别层次、语义层次。
● 实例层次:尺度、光照、视角、变形、遮挡
● 类别层次:类内差别、类间模糊、背景干扰
● 语义层次:多重稳定。
基于深度学习图像分类算法的诞生——LeNet5,1998年开创基于深度学习图像分类算法的新局面——AlexNet,2012年基于小卷积核的图像分类算法——VGGNet,2014年基于最优局部稀疏结构的图像分类算法——Inception系列
● Inception-v1,2014年
● Inception-v2、v3,2016年基于恒等映射残差单元的图像分类算法——ResNet,2015年基于聚合转换残差单元的图像分类算法——ResNeXt,2016年,在ResNet的基础上同时采用VGGNet和Inception的思想,提出一种可扩展性更强的“聚合转换残差单元”,可以在增加准确率的同时降低或者不改变模型的复杂度。基于多层密集连接的图像分类算法——DenseNet,2017年,受ResNet的启发,提出一种更加密集的前馈式跳跃连接。从特征的角度出发,通过增加网络信息流的隐性深层监督和特征复用极大程度上缓解了梯度消失的问题,也使得模型的性能得到大幅度的提升。基于特征通道重标定的图像分类算法——SENet,2018年。并非是一个完整的网络,可以嵌入到任何主干网络中的子模块。基于通道压缩与扩展的图像分类算法——SqueezeNet,2016年。开启了模型轻量化的开端,对神经网络走向实际化具有重要的意义。基于深度可分离卷积的图像分类算法——MobileNet,2017年。一种专注于资源受限的移动设备或嵌入式设备的轻量级卷积神经网络。基于逐点群卷积与通道混洗的图像分类算法——ShuffleNet,2017年。基于神经架构自动搜索的图像分类算法——NASNet,2018年。 从图像中提取关键信息并转化为能够进行分类的特征是图像分类算法的最基本的要求,关键信息提取是完成图像分类最基本的先决条件。图像分类的本质实际上就是滤除非关键信息,保留关键信息的过程。
3.深度学习目标检测算法核心 目标检测是计算机视觉领域一个基础但十分重要的研究方向。
如何充分利用深度卷积神经网络产生的浅层和深层特征来增强网络对多尺度目标的检测性能,并在一定检测精度的前提下降低网络的时间复杂度,是当前基于深度学习的目标检测算法的主要研究目标。
目标检测要解决目标定位的回归问题,又要解决目标分类的问题。
为评估定位精度,需要计算交并比IoU(预测框与真实框之间的重叠程度)。
R-CNN,2014年(候选区域推荐 -> 候选区域特征提取 -> 候选区域分类 -> 候选区域边界框回归)基于空间金字塔池化的目标检测算法——SPPNet, 2015年。基于R-CNN和SPPNet改进的目标检测算法—— Fast R-CNN,2015年。基于语义分割和Faster R-CNN的目标检测网络——Mask R-CNN,2017年。解决图像实例分割问题。一步式目标检测算法的提出——YOLO系列,2015年。基于特征金字塔的目标检测算法——FPN,2017年。利用特征图间不同的表达特性,提出对输入图像生成多维度特征表达的方法,从而生成更具有代表性、表达能力更强的特征图以供后续使用。本质上说,FPN是一种加强骨干网络特征表达的方法。基于单发细化目标的检测算法——RefineDet,基于SSD,融合了一步式和两步式的思想,在保持一步式方法速度的前提下,获得了二步式的精度。(Faster R-CNN两步式,YOLO一步式)。该算法由锚框优化模块ARM和目标检测模块ODM两个模块,由转换连接模块TCB连接。基于主干架构搜索的目标检测算法——DetNAS,基于单步检测网络空间提出搜索目标检测骨干网络框架。基于神经架构搜索的目标检测算法——NAS-FPN,FPN是一种有效表达深度卷积网络特征的方法,通过提取多维度特征形成强表达特征,可缓解不同尺度检测的难题,能极大提升小物体的检测效果。NAS-FPN基于RetinaNet一步式网络(两个主要模块:骨干网络模块和FPN网络模块)。 4.
VisualStudio运行程序出现
xx.exe拒绝访问
解决方案为
cmd下输入命令
taskkill /F /IM xx.exe
实验目的: 本节视频的目的是掌握EMIFA的使用,了解AD7606的芯片特性和使用,并实现基于AD7606采集正弦波。
AD9833原理图 找到波形发生器,可查看相关控制引脚。本次实验采集的波形是由AD9833输出的。
AD7606原理图 找到AD采集,可查看相关控制引脚,同时可看到ADC输入的V1~V8通道分别对应CON29 - CON36口。
波形发生器 TL6748-PlusTEB实验箱采用板载波形信号发生器,波形信号发生器采用的芯片是AD9833。
AD9833是一款低功耗、可编程波形发生器,能够产生正弦波、三角波和方波输出。各种类型的检测、信号激励和时域反射应用都需要波形发生器。输出频率和相位可通过软件进行编程,调整简单。频率寄存器为28位,时钟速率为25MHz时,可以实现0.1Hz的分辨率;而时钟速率为1MHz时,则可以实现0.004Hz的分辨率。AD9833的输出电源范围是38mV~650mV。
AD9833 AD9833具有一个标准串行接口,使得该器件可以直接与数个微处理器接口。该器件采用外部串行时钟来向器件中写入数据或控制信息。通过该串行接口DSP可使用程序控制AD9833产生正弦波、三角波和方波输出。
A/D转换 A/D转换,即模数转换,是指将一个输入电压信号转换为一个输出的数字信号。一般分为四个步骤进行:取样、保持、量化和编码。前两个步骤在取样-保持电路中完成,后两步骤则在ADC中完成。
AD7606 TL6748-PlusTEB实验箱上的AD采集是基于 ADI AD7606 芯片进行设计的,具体特性如下:
· 八通道;
· 16bit采样;
· 支持串行和并行读取方式;
· 支持全部通道200K 采样率并行采集和转换;
· 支持真正±10V 或±5V 的双极性信号输入。
模数转换工作过程 AD7606上8个通道的数据是同时采集,轮流转换的。
模数转换模块接到启动转换信号后,按照排序器的设置,开始转换第一个通道的数据;经过一个采样时间的延迟后,将采样结果放入转换结果寄存器保存;按顺序进行下一个通道的转换;如果为连续转换方式则从新开始转换过程;否则等待下一个启动信号。
EMIFA (External Memory Interface)
即外部存储器接口,可实现DSP与不同类型存储器(SRAM、Flash RAM、DDR-RAM等)的连接。具体可以分为EMIFA和EMIFB。
外部存储器接口主要用来同并行存储器连接,这些存储器包括SDRAM、SBSRAM、Flash、SRAM存储器等,外部存储器接口还可以同外部并行设备进行连接,这些设备包括并行A/D、D/A转换器、具有异步并行接口的专用芯片,并可以通过外部存储器接口同FPGA、CPLD等连接。
EMIFA接口特性 (1)异步操作: 支持SRAM,NAND Flash ,NOR Flash,FPGA等,包括AD7606
最大支持16位数据总线 和23位地址总线,在C6748中只能支持到16位
具有4个片选(EMA_CS[5:2]),只能用于异步操作
连接NAND Flash时, NAND Flash控制器支持1-bit和4-bit的ECC校验
(2)同步操作: 支持16-bit的SDRAM
有一个单独的SDRAM(EMA_CS[0])
EMIFA功能框图 EMIFA的请求信号的有三个来源:CPU、EDMA和主外设。
右侧的三部分接口分别是:SDRAM的控制信号管脚和异步操作模式下的控制信号管脚以及共用部分的数据总线和地址总线。
EMIFA与AD7606的连接 连接异步设备时可以有4个片选:EMA_CS[n],n=2,3,4,5
控制信号引脚要根据外设的时序要求使用,AD7606的连接中只用到了片选信号,其他的没有用到。
程序流程设计 程序流程设计中首先要进行外设使能配置和DSP中断初始化,接着初始化LCD的显示与触摸,然后初始化AD7606,接着初始化AD9833并输出波形,启动AD7606采集并将采集的波形显示到LCD上。最后进行触摸检测,控制AD7606启动和暂停。
方向配置源码 管脚方向配置 使用StarterWare 库函数将 GPIO 口配置为输出模式。相关函数通过“gpio.
目录
模块
对于浏览器:
模块核心功能
始终使用 “use strict”
模块级作用域
模块代码仅在第一次导入时被解析
import.meta
在一个模块中,“this” 是 undefined
浏览器特定功能
模块脚本是延迟的,常规脚本是立即进行的
Async 适用于内联脚本(inline script)
外部脚本
不允许裸模块(“bare” module)
兼容性,“nomodule”
构建工具
导入导出
导出 export
导入 import *
Export default
重新导出
重新导出默认导出
动态导入
import() 表达式
模块 模块:一个模块(module)就是一个文件。一个脚本就是一个模块
模块可以相互加载,并可以使用特殊的指令 export 和 import 来交换功能,从另一个模块调用一个模块的函数:
export 关键字标记了可以从当前模块外部访问的变量和函数。import 关键字允许从其他模块导入功能。 对于浏览器: 由于模块支持特殊的关键字和功能,因此我们必须通过使用 <script type="module"> 特性(attribute)来告诉浏览器,此脚本应该被当作模块(module)来对待。
<!doctype html> <script type="module"> import {sayHi} from './say.js'; document.body.innerHTML = sayHi('John'); </script> 浏览器会自动获取并解析(evaluate)导入的模块(如果需要,还可以分析该模块的导入),然后运行该脚本。模块只通过 HTTP(s) 工作,而非本地 如果你尝试通过 file:// 协议在本地打开一个网页,你会发现 import/export 指令不起作用。你可以使用本地 Web 服务器,例如 static-server,或者使用编辑器的“实时服务器”功能,例如 VS Code 的 Live Server Extension 来测试模块。 模块核心功能 始终使用 “use strict” 模块始终在严格模式下运行。例如,对一个未声明的变量赋值将产生错误(译注:在浏览器控制台可以看到 error 信息) <script type="
实现京东商品详细信息爬虫可以分为以下几个步骤:
发起 HTTP 请求获取商品页面 HTML;使用网页解析库解析 HTML,提取商品详细信息;存储提取的信息。 下面是一个简单的 Python 示例,使用 requests 库发起 HTTP 请求,使用 Beautiful Soup 解析 HTML,提取商品信息,最后将提取的信息存储到 CSV 文件中。
import requests from bs4 import BeautifulSoup import csv # 商品 URL url = 'https://item.jd.com/100008348542.html' # 发起 HTTP 请求 response = requests.get(url) # 使用 Beautiful Soup 解析 HTML soup = BeautifulSoup(response.text, 'html.parser') # 提取商品信息 sku = url.split('/')[-1].split('.')[0] # 商品 ID name = soup.select_one('div.sku-name').text.strip() # 商品名称 price = soup.select_one('span.price.J-p-' + sku).text.strip() # 商品价格 comments = soup.
这篇文章讲的很清楚 https://www.zhihu.com/tardis/zm/art/159135478?source_id=1003
epoll中有两种触发模式,分别为
1、水平触发
水平触发为Level Triggered,简称LT。
水平触发关心的是缓冲区的状态,当缓冲区可读的时候,就会发出通知,也就是当缓冲区中只要有数据就会发出通知。
2、边缘触发
边缘触发为Edge Triggered,简称ET。
边缘触发关心的是缓冲区状态的变化,当缓冲区状态发生变化的时候才会发出通知,比如缓冲区中来了新的数据。
从上述表述可能不太看得出他们之间的区别,我们设想这样一个场景,当一次read()读取没有读取完缓冲区中的数据时,LT和ET的区别:
1、LT,此时缓冲区中还有数据,会继续发通知
2、ET,此时缓冲区状态并没有发生变化,并没有来新的数据,就不会发通知,在新数据到来之前,之前剩余的数据就无法取出。
所以在ET模式下,当读取数据的时候,一定要循环读取数据,直到缓冲区中的数据全部读取完成,一次性将数据取出。
选择题 2017 2017 2017 年 10 10 10 月 1 1 1 日是星期日, 1999 1999 1999 年 10 10 10 月 1 1 1 日是( )。
A. 星期三
B. 星期二
C. 星期日
D. 星期五 【解析】 1999 1999 1999到 2017 2017 2017年一共是 18 18 18年, 18 × 365 % 7 = ( 18 % 7 × 365 % 7 ) % 7 = 4 18\times 365 \ \% 7=(18\%7\times365\%7)\%7=4 18×365 %7=(18%7×365%7)%7=4,中间有 5 5 5个闰年: 2000 , 2004 , 2008 , 2012 , 2016 2000,2004,2008,2012,2016 2000,2004,2008,2012,2016, ( 4 + 5 ) % 7 = 2 (4+5)\%7=2 (4+5)%7=2。也就是说 1999 1999 1999
传参 1. 使用Props2.使用事件:3.使用Vuex(状态管理):4. 使用Provide/Inject5. 使用$route对象: 在Vue中,你可以使用多种方式来传递参数,以便在组件之间进行数据交流和共享。以下是一些常用的Vue中传参的方式: 1. 使用Props Props是一种允许父组件向子组件传递数据的机制。在父组件中通过属性的方式将数据传递给子组件,并在子组件中通过props选项接收和使用这些数据。 父组件中的模板:
<template> <ChildComponent :message="helloMessage" /> </template> 父组件中的数据:
data() { return { helloMessage: 'Hello, World!', } } 子组件中的props选项:
props: { message: String, } 子组件中使用props传递的数据:
<template> <div>{{ message }}</div> </template> 在父组件中,通过:或v-bind指令将helloMessage数据传递给子组件的message属性。在子组件中,通过props选项声明接收的属性类型,并在模板中使用message属性显示传递的数据。
2.使用事件: 事件是一种允许子组件向父组件传递消息的机制。
在子组件中通过$emit方法触发自定义事件,并将数据作为事件的参数传递。在父组件中通过监听子组件的自定义事件,并在事件处理函数中获取传递的数据。 子组件中触发自定义事件:
methods: { sendData() { this.$emit('customEvent', 'Hello, Parent!'); } } 父组件中监听子组件的自定义事件:
<template> <ChildComponent @customEvent="handleEvent" /> </template> 父组件中的事件处理函数:
methods: { handleEvent(data) { console.log(data); // 输出:Hello, Parent! } } 在子组件中,通过$emit方法触发名为customEvent的自定义事件,并将数据’Hello, Parent!
一、str和&str和String的区别 1.存放位置,可变不可变: str来源于Rust本身的数据类型,而String类型来自于标准库。首先看一下str 和 String之间的区别:String是一个可变的、堆上分配的UTF-8的字节缓冲区。而str是一个不可变的固定长度的字符串,如果是从String解引用而来的,则指向堆上,如果是字面值,则指向静态内存。
2.来看一个比较奇怪的例子 let s:&str="abcd"; char *s="abcd"; 在C语言中,s是一个指针类型,指向一个字符串,但是它不知道长度,操作不安全。
在Rust中,s的类型是&str,而“abcd”是str类型,这里的“abcd”就是字符串字面值,存放在Stack上的。s 是切片,切片是一个结构体,包含两个字段,一个是指向数据的指针,另一个是数据的长度。因此,我们有可能采用必要的措施,安全的使用变量 s,这就是比C语言更安全的地方。
3.String #[derive(PartialOrd, Eq, Ord)] pub struct String { vec: Vec<u8>, } 切片 &str 虽然可以安全使用,但是,我们很难动态修改其内容 —— 其地址、长度都是固定的。于是 Rust 提供了数据类型 String。String 包含了数据指针、数组容量、数据长度等三个字段。如果新修改的数据长度在其容量范围内,数据可以原地修改。如果新修改的数据长度超出了容量范围,它可以重新申请更大的内存。于是我们看到,String 和 &str 是两个完全不一样的结构体。为什么字符串要保留这两种形式?原因就是效率。Rust 希望在数组容量不会变化的时候,用 &str。在数组长度可能发生变化的情况下,使用 String。
补充几点关于String的:String 总是 “有效的” UTF-8,Rust字符串只能是UTF-8的类型。另外,不能用索引访问 String,因为有些字符的编码可能是多个字节,取到中间就是没有意义的。
4.&str或str转String let s: String = "hello".to_string(); let t: String = String::from("hello"); 5.String转&str或str 在 Rust 中,凡是需要用 &str 的地方,都可以直接用 &String 类型的数据。&String和&str其实也是差不多的。
fn greet(s: &str) { ... } fn main() { let s: String = String::from("