神经网络模型(Backbone)--从AlextNet讲起

目录 1. LeNet-52. AlexNet3.ZFNet3. VGGNet4. GoogLeNet4.1 GoogLeNet V14.2 GoogLeNet V2, V34.3 GoogLeNet V4 5. ResNet6. DenseNet7. SqueezeNet8. MobileNet8.1 MobileNet V18.3 MobileNet V3 9 ShuffleNet9.1 shuffleNet V19.2 shuffleNet V2 自己搭建神经网络时,一般都采用已有的网络模型,在其基础上进行修改。从2012年的AlexNet出现,如今已经出现许多优秀的网络模型,如下图所示。 主要有三个发展方向: Deeper:网络层数更深,代表网络VggNet Module: 采用模块化的网络结构(Inception),代表网络GoogleNet Faster: 轻量级网络模型,适合于移动端设备,代表网络MobileNet和ShuffleNet Functional: 功能型网络,针对特定使用场景而发展出来。如检测模型YOLO,Faster RCNN;分割模型FCN, UNet 其发展历史可以分为三个阶段: 这些模型在ImageNet上的表现效果对比如下: 1. LeNet-5 LeNet-5是LeCun在1998年的论文中Gradient-Based Learning Applied to Document Recognition 提出的网络模型,其结构如下:(其中卷积为55的kernel,下采样为22的MaxPooling),其结构比较简单,关于LeNet-5结构设计的详细分析,参见:参考一,参考二 2. AlexNet AlexNet是Alex Krizhevsky在2012的文章ImageNet Classification with Deep Convolutional Neural Networks中提出,其结构模型如下:(分上下两部分卷积,计算力不足,放在两块GPU上) AlexNet的特色:(参考1,参考2) (1) Training on Multiple Gpus: 受于当时的算力限制,Alexnet创新地将图像分为上下两块分别训练,然后在全连接层合并在一起 (2) ReLU Nonlinearity: 采用ReLU激活函数代替Sigmoid或tanh, 解决了梯度饱和的问题

多线程之死锁介绍及预防

综述 在遇到线程安全问题的时候,我们会使用加锁机制来确保线程安全,但如果过度地使用加锁,则可能导致锁顺序死锁(Lock-Ordering Deadlock)。或者有的场景我们使用线程池和信号量来限制资源的使用,但这些被限制的行为可能会导致资源死锁(Resource DeadLock)。 我们知道Java应用程序不像数据库服务器,能够检测一组事务中死锁的发生,进而选择一个事务去执行;在Java程序中如果遇到死锁将会是一个非常严重的问题,它轻则导致程序响应时间变长,系统吞吐量变小;重则导致应用中的某一个功能直接失去响应能力无法提供服务,这些后果都是不堪设想的。因此我们应该及时发现和规避这些问题。 死锁产生的条件 死锁的产生有四个必要的条件 互斥使用,即当资源被一个线程占用时,别的线程不能使用不可抢占,资源请求者不能强制从资源占有者手中抢夺资源,资源只能由占有者主动释放请求和保持,当资源请求者在请求其他资源的同时保持对原有资源的占有循环等待,多个线程存在环路的锁依赖关系而永远等待下去,例如T1占有T2的资源,T2占有T3的资源,T3占有T1的资源,这种情况可能会形成一个等待环路 对于死锁产生的四个条件只要能破坏其中一条即可让死锁消失,但是条件一是基础,不能被破坏。 各种死锁 锁顺序死锁 死锁 当多个线程同时需要同一个锁,但是以不同的方式获取它们。 例如,如果线程1持有锁A,然后请求锁B,线程2已经持有锁B,然后请求锁A,这样一个死锁就发生了。线程1永远也得不到锁B,线程2永远也得不到锁A。它们永远也不知道这种情况。 public class TreeNode { TreeNode parent = null; List children = new ArrayList(); ​ public synchronized void addChild(TreeNode child){ if(!this.children.contains(child)) { this.children.add(child); child.setParentOnly(this); } } public synchronized void addChildOnly(TreeNode child){ if(!this.children.contains(child){ this.children.add(child); } } public synchronized void setParent(TreeNode parent){ this.parent = parent; parent.addChildOnly(this); } ​ public synchronized void setParentOnly(TreeNode parent){ this.parent = parent; } } 如果一个线程(1)调用parent.

程序员成长之旅——进程间通信(IPC)

程序员成长之旅——进程间通信 pipe/msgqueue/sems/shm代码及总结管道消息队列信号量共享内存 练习ipcs -q/m/s于ipcrm -q/m/s的使用,并总结将二元信号量P/V操作,封装成动态/静态库,并分别使用并测试调研同步与互斥概念原理,了解生产者消费者原理。 pipe/msgqueue/sems/shm代码及总结 再讲进程间通信的方式之前,我们首先要知道为啥要存在进程间的通信以及其目的。 存在进程间通信的理由: 进程之间具有独立性,无法直接沟通,所以需要操作系统提供公共的媒介,也就是让进程看到同一份资源。 进程间通信的四个目的: 数据传输:一个进程需要将它的数据发送给另一个进程 资源共享:多个进程之间共享同样的资源 通知事件:一个进程需要向另一个或一组进程发送消息,通知它们发生了某种事件(比如进程终止的时候要告诉父进程) 进程控制:有些进程希望完全控制另一个进程的执行(如debug进程),此时控制进程希望能够拦截另一个进程的所有陷入和异常,并能够及时知道它的状态改变 管道 什么是管道 管道是Unix中最古老的进程间通信的形式。我们把从一个进程连接到另一个进程的数据流称之为一个“管道”。 管道的分类 管道可以分为匿名管道和命名管道 1.匿名管道 匿名管道所需要的函数 #include<unistd.h> int pipe(int fd[2]) //功能:创建一个无名管道 参数: fd:文件描述符数组,其中fd[0]表示读端,fd[1]表示写端 返回值:成功返回0,失败返回错误代码 代码实现 简单的键盘读取数据写入管道读取管道写到屏幕的操作 #include<stdio.h> #include<unistd.h> #include<stdlib.h> #include<sys/types.h> #include<string.h> #include<errno.h> int main() { int fds[2]; char buf[100] = {0}; int len; if(pipe(fds) == -1){ perror("pipe()"); exit(1); } //read from stdin while(fgets(buf,100,stdin)){ len = strlen(buf); //write to pipe if(write(fds[1],buf,len) != len){ perror("write to pipe"

Java 模拟考试系统(Swing + IO)

编程语言:Java 14.0.1IDE:intelliJ IDEA 2020.1.2 使用了MVC分层架构思想,并且仅涉及JavaSE内容 功能:登录 + 考试UI:Swing数据库:以文件充当数据库的功能,使用集合实现缓存机制 单例模式效果的两种实现 懒汉式(延迟加载)IOC控制权反转实现生命周期托管 重点在于考试功能的设计: 题库中有若干个题目,存储在文件中,一行一个。每一行就是一个String,使用特殊符号来分割题干(题目、选项)、答案和图片路径。 需要一个方法生成考卷,在题库中随机抽取若干个题目,使用ArrayList集合存储考卷。 在其中需要做到无序不重复,可以使用set HashSet,决定于hashCode、equals方法TreeSet,决定于compareTo方法 在考试窗口上展示题目,对于选项按钮、切换按钮、提交按钮的事件绑定设计 添加倒计时功能,使用线程处理时间倒计时问题 展示 编辑器的编码设置 idea编辑器 --> File --> Settings --> Editor --> File Encodings 这个 Java demo 中涉及到使用 idea 编辑器创建文件、读取文件;有关编码问题,请参考上图。 完整代码获取 代码:github如果你会使用github,可以看一下我的commit哦,功能逐步实现,并且分功能实现commit

win10 远程桌面服务不见了解决办法

由于员工操作错误,导致某杀毒软件把remote desktop services服务整个搞不见了,其他服务什么的都在,应该开的都开了,查了N多网上CTRL+V后,发现注册表中termservice消失了,然后把其他版本相同的win10的termservice导出,在有问题的主机重新注册后就重启可以了。 现象:服务中的remote desktop services消失,其他相关服务依然存在 解决办法:其他相同版本的系统导出注册表termservice,路径如下, HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\TermService ,右键导出,在问题机注册重启即可。

【目标检测】Towards Accurate One-Stage Object Detection with AP-Loss

摘要 one-stage目标探测器通过同时优化分类损失和定位损失进行训练,前者由于锚的数量众多而遭受极端的前景-背景类别失衡问题。本文提出了一个新颖的框架,以分级任务代替one-stage检测器中的分类任务,并采用平均精度损失(AP-loss)解决分级问题,从而缓解了这一问题。由于其不可微性和非凸性,AP损耗无法直接优化。为此,我们开发了一种新颖的优化算法,该算法将感知器学习中的错误驱动更新方案与深度网络中的反向传播算法无缝结合。我们从理论和经验上验证了所提出算法的良好收敛性。实验结果表明,在不改变网络体系结构的情况下,基于APloss one-stage检测器在各种基准上效果可超过各种分类loss,从而显着提高了性能。 1、Introduction 目标检测需要同时从大背景中定位和识别对象,由于前景和背景之间的不平衡,因此仍然具有挑战性。基于深度学习的检测解决方案通常采用多任务架构,该架构可处理具有不同损失功能的分类任务和定位任务。分类任务旨在识别给定框中的对象,而定位任务旨在预测对象的精确边界框。两级检测器[24、7、2、14]首先生成有限数量的对象框建议,因此可以通过对这些建议采用分类任务来解决检测问题。但是,对于one-stage检测器,情况有所不同,one-stage检测器需要直接从密集设计的候选框中直接预测对象类别。大量的框会导致前景和背景之间的不平衡,这会使分类任务的优化容易产生偏差,从而影响检测性能。可以看出,对于一个简单的解决方案,分类指标可能很高,该解决方案预测几乎所有候选框都带有负标签,而检测性能却很差。图1a展示了一个这样的例子。 为了解决one-stage目标检测器中的这一问题,一些工作引入了新的分类损失,例如平衡损失[22],焦点损失[15]以及量身定制的训练方法,例如在线硬示例挖掘(OHEM)[18,29] ]。这些损失独立地为每个样本(锚定框)建模,并尝试在分类损失中对前景样本和背景样本进行重新加权,以适应不平衡状况。这样做无需考虑不同样本之间的关系。设计的平衡权重是手工制作的超参数,无法在数据集中广泛推广。我们认为分类任务和检测任务之间的差距阻碍了one-stage检测器的性能。在本文中,我们建议在one-stage检测器中用分级任务代替分类任务,在分级检测器中,相关联的分级损失可以显式地建模样本关系,并且不依赖于正样本与负样本的比率。如图1b所示,我们采用平均精度(AP)作为我们的目标损耗,这在本质上与目标检测的评估指标更加一致。 但是,由于不可微性和不可分解性,直接优化AP损失并非易事,因此标准梯度下降方法不适用于这种情况。 这个问题有三个方面的研究。 首先,在结构化SVM模型中研究了基于AP的损耗[34,19],它限制了线性SVM模型,从而限制了性能。 其次,提出了一种结构化的铰链损耗[20]来优化AP损耗的上限而不是损耗本身。 第三,提出了近似梯度法[31,9]来优化AP损失,由于AP的非凸性和非准凸性,即使对于线性模型,效率也较低,并且容易陷入局部最优 -失利。 因此,对于AP损耗的优化仍然是一个未解决的问题。 在本文中,我们通过用分级任务代替one-stage检测器中的分类任务来解决这一难题,以便我们使用基于分级的损失AP-loss来处理类不平衡问题。此外,我们提出了一种新颖的错误驱动学习算法,可以有效地优化基于不可微AP的目标函数。更具体地说,将一些额外的变换添加到one-stage检测器的得分输出中以获得AP损失,其中包括将得分转换为成对差异的线性变换以及非线性且不可微的“激活函数”将成对的差异转换为AP损失的主要条件。然后,可以通过主要项和标记向量之间的点积获得AP损失。值得注意的是,对AP损失使用梯度法的困难在于使梯度通过不可微分的激活函数。受感知器学习算法启发[25],我们采用错误驱动的学习方案,将更新信号直接通过不可微分的激活函数传递。与梯度方法不同,我们的学习方案为每个变量提供一个与其所产生的误差成比例的更新信号。然后,我们采用反向传播算法将更新信号传递给神经网络的权重。我们从理论上和实验上证明了所提出的优化算法不会遭受目标函数的不可微性和非凸性。本文的主要贡献概述如下: 我们提出了一种在one-stage对象检测器中的新颖框架,该框架采用排名损失来处理类不平衡问题。我们提出了一种错误驱动的学习算法,该算法可以通过理论和实验验证来有效地优化基于不可微和非凸AP的目标函数。在不改变模型架构的情况下,针对不同种类的分类损失,采用最新的one-stage检测器提出的方法,我们显示出显着的性能提升。 2. Related Work 3. Method 我们的目标是在RetinaNet [15]等一级检测器中用基于AP损失的排名任务代替分类任务。 图2显示了我们方法的两个关键组成部分,即排名程序和错误驱动的优化算法。 下面,我们将首先介绍如何从传统得分输出中得出AP损失。 然后,我们将介绍误差驱动的优化算法。 最后,我们还对提出的优化算法进行了理论分析,并概述了训练细节。 请注意,所有更改都是在分类分支的损失部分进行的,而不更改主干模型和定位分支。 3.1. Ranking Task and AP-Loss 3.1.1 Ranking Task 在传统的一级检测器中,给定输入图像I,假设预定义的框(也称为锚)集为B,每个框bi∈B将被分配标签ti∈{-1,0,1,。 。 。 ,K}基于GT和IoU策略[7,24],其中标签1〜K表示对象类别ID,标签“ 0”表示背景,标签“ -1”表示忽略的框。在训练和测试阶段,检测器为每个box bi输出一个得分矢量(s0i,…,sKi)。 在我们的框架中,不是用一个具有K + 1个维度得分预测的盒子,而是将每个盒子bi复制了K次以获得bik,其中k = 1,···,K和第k个盒子负责第k类。通过相同的IoU策略(标记-1不计入排名损失),将为每个box bik分配标签tik∈{-1,0,1}。因此,在训练和测试阶段,检测器将仅预测每个盒形块的一个标量得分sik。图3说明了我们的标签配方以及与传统包装的区别。 排名任务规定,每个肯定框的排名应高于所有负面框的得分。请注意,我们的排名结果的AP是根据所有类的分数计算得出的。这与对象检测系统的评估指标meanAP略有不同,后者针对每个类别计算AP并获得平均值。我们之所以这样计算AP,是因为应该为所有班级统一分数分布,而对每个类分别排名不能达到此目标。 3.1.2 AP-Loss 为简单起见,我们仍使用B表示复制后的锚框集,而bi表示不带复制下标的第i个锚框。 因此,每个框bi对应于一个标量分数si和一个二进制标签ti。 如图2所示,需要进行一些转换以形成等级损失。首先,差异转换将分数si转换为差异形式。 其中s(bi;θ)是基于CNN的得分函数,其中框bi具有权重θ。 排序标签转换将标签ti转换为相应的成对排序形式。 其中1是一个指标函数,仅当下标条件成立(即ti = 1,tj = 0)时才等于1,否则为0。然后,我们定义向量值激活函数L(·)来生成主要项 AP损失为 当不存在两个均等得分的样本时(即),则该排名被称为适当排名。 在不失一般性的前提下,我们将通过任意打破联系来将所有排名视为适当的排名。 现在,我们可以将AP-lossLAP公式表示为 这里直接看公式理解还是很有难度,我看了好几遍才勉强理解一点。可以参考一下https://cloud.tencent.com/developer/article/1633043里的介绍。 首先明确这个AP-Loss核心是通过对score进行排名来,这里这个Lij分母是得分大于等于它的数量+1,实际上就是它的排名。当j对应的得分大于等于它时分子为1,否则为0。LAP就很好理解了,直接看最后一行的公式,其实就是负样本的中的score如果大于正样本则会产生loss,最终计算的是每个正样本被负样本超过的平均loss。 作者后来还提出了一种AUC-loss,但是证明AP-Loss更好。

12. 离线处理之业务数据采集、生成用户画像、推广效果分析以及知识点总结

离线处理之业务数据采集、生成用户画像、推广效果分析以及知识点总结 1. Azkaban周期性调度任务1.1. 总览1.2. 调度脚本1.3. [Azkaban安装并设置定时任务Schedule以及邮件发送接收](https://blog.csdn.net/aizhenshi/article/details/80828726?utm_source=blogxgwz5) 2. 业务数据采集2.1. 后台通过`logback`把业务接口日志写入到本地文件2.1.1. logback配置文件2.1.2. 拦截器当中记录接口日志2.1.3. 本地日志目录2.1.4. 日志格式 2.2. 通过Flume采集数据到Kafka2.2.1. Flume配置文件 2.3. Storm消费Kafka数据,写入Hbase2.3.1. `LogReaderSpout.java`2.3.2. `UserLogBolt.java`2.3.3 `ToHbaseBolt.java` 2.4. [Hive和Hbase的整合](https://blog.csdn.net/fanjianhai/article/details/106016931)2.4.1. HIve和Hbase的表关联2.4.2. Hive数据样式2.4.3. Hbase数据样式2.4.4. `Hive和Hbase关联后,操作一方同样会影响另一方数据` 2.5. 通过Sqoop把业务数据从PostgreSql导入Hive数仓 3. 生成用户画像3.1. hive分区设置3.2. 用户登录日志3.3. 用户终端类型和机型3.4. 用户最高委员会职务3.5. 用户信息3.6. 画像信息3.7. 生成用户画像 4. 推广效果分析4.1. 采集微论文曝光数据4.2. 采集广告曝光数据4.3. 曝光量多维度统计4.4. 不同维度进行曝光量的统计4.5. 统计日汇总维度4.6. 同步统计结果 5. 知识点总结5.1. Tomcat5.1.1. [Tomcat使用详细教程](https://blog.csdn.net/weixin_39657319/article/details/83268378)5.1.2. [用脚本实现windows与linux之间文件的传输 ](https://blog.csdn.net/xqhrs232/article/details/78403080) 5.2. Hive Hql常用方法总结5.2.1. [ROW_NUMBER() OVER函数的基本用法](https://jingyan.baidu.com/article/9989c74604a644f648ecfef3.html)5.2.2. [SQL语言-- SELECT CASE WHEN THEN](https://blog.csdn.net/qq_34777600/article/details/81699270)5.2.3. [Hive列转行 (Lateral View + explode)详解](https://zhuanlan.zhihu.com/p/115913870)5.2.4. [HiveSQL行转列lateral view explore()以及连接concat_ws()和列转行collect_list()&collect_set()区别的使用案例](https://blog.

【内核调度】【休眠进程的唤醒】【wake_up_process】

wake_up_process 一般当队列里面为空的时候,核心调度器(是否是核心调度器还需要后续去confirm)会在已经睡眠的task中通过调用wake_up_process函数将其唤醒,然后选择合适的cpu来运行 /** * wake_up_process - Wake up a specific process * @p: The process to be woken up. * * Attempt to wake up the nominated process and move it to the set of runnable * processes. * * Return: 1 if the process was woken up, 0 if it was already running. * * It may be assumed that this function implies a write memory barrier before * changing the task state if and only if any tasks are woken up.

Python用27行代码绘制一幅满天星!送给女朋友,省时省力!

前言 每一个孩子都像星空中的一颗星星,散发着自己所特有的光芒照亮着整个夜空。今天就带大家用27行Python代码绘制一幅满天星吧。 全局设置 在绘制满天星的过程中要运用到turtle工具,它是Python的标准库,也可以形象的称它为海龟库,它可以描绘绘图的轨迹,操作简单、快捷。首先,我们要做一些有关全局的设置 这一步主要是对turtle的画笔大小、绘画延迟以及画布大小进行设置。 绘制一个五角星 绘制满天星的关键就在于如何绘制出一个五角星,接下来通过创建一个有关绘画五角星的函数 上述代码中主要涉及了turtle库的api,在代码注释中已经做了详细的说明,就不再进行赘述了。 重复绘制 绘制出一个五角星之后,就可以通过不断的调用stars函数来实现满天星的效果了,详细代码如下 效果展示 接下来让我们将分散的代码组合起来,一起看看效果吧 源码获取加群哦:850591259

js使用split()方法处理截取以逗号分隔的字符串

var yourString=“1,2,3,4,234,”; var result=yourString.split(","); for(var i=0;i<result.length;i++){ console.log(result[i]); } split使用方法如下: stringObject.split(separator,howmany) separator 必需。字符串或正则表达式,从该参数指定的地方分割 stringObject。 howmany 可选。该参数可指定返回的数组的最大长度。如果设置了该参数,返回的子串不会多于这个参数指定的数组。如果没有设置该参数,整个字符串都会被分割,不考虑它的长度。 返回值 一个字符串数组通过在 separator 指定的边界处将字符串 stringObject 分割成子串创建的。 返回的数组中的字串不包括 separator 自身。 如果 separator 是包含子表达式的正则表达式,那么返回的数组中包括与这些子表达式匹配的字串(但不包括与整个正则表达式匹配的文本)。 注意:如果把空字符串 ("") 用作 separator,那么 stringObject 中的每个字符之间都会被分割。

DataX与DataX web入门

1.DataX3.0简介 DataX 是一个异构数据源离线同步工具,致力于实现包括关系型数据库(MySQL、Oracle等)、HDFS、Hive、ODPS、HBase、FTP等各种异构数据源之间稳定高效的数据同步功能。 设计理念 为了解决异构数据源同步问题,DataX将复杂的网状的同步链路变成了星型数据链路,DataX作为中间传输载体负责连接各种数据源。当需要接入一个新的数据源的时候,只需要将此数据源对接到DataX,便能跟已有的数据源做到无缝数据同步。当前使用现状 DataX在阿里巴巴集团内被广泛使用,承担了所有大数据的离线同步业务,并已持续稳定运行了6年之久。目前每天完成同步8w多道作业,每日传输数据量超过300TB。 2.DataX3.0框架设计 DataX本身作为离线数据同步框架,采用Framework + plugin架构构建。将数据源读取和写入抽象成为Reader/Writer插件,纳入到整个同步框架中。 Reader:Reader为数据采集模块,负责采集数据源的数据,将数据发送给Framework。Writer: Writer为数据写入模块,负责不断向Framework取数据,并将数据写入到目的端。Framework:Framework用于连接reader和writer,作为两者的数据传输通道,并处理缓冲,流控,并发,数据转换等核心技术问题。 详情可参照官方文档说明: https://github.com/alibaba/DataX/blob/master/introduction.md 3.dataX安装部署文档 推荐环境: Linux JDK(1.8以上,推荐1.8) Python(推荐Python2.6.X) Apache Maven 3.x (Compile DataX) 部署 方式1:直接下载DataX工具包 http://datax-opensource.oss-cn-hangzhou.aliyuncs.com/datax.tar.gz 方式2:下载DataX源码,自己编译 https://github.com/alibaba/DataX 下载DataX源码: $ git clone git@github.com:alibaba/DataX.git 通过maven打包: $ cd {DataX_source_code_home} $ mvn -U clean package assembly:assembly -Dmaven.test.skip=true 打包成功后的DataX包位于 {DataX_source_code_home}/target/datax/datax/ 4.dataX示例 reader–MySQL writer–HIVE 准备MySQL数据源表信息hive中创建表结构构建json文件,用于数据抽取 { "job": { "content": [ { "reader": { "name": "mysqlreader", "parameter": { "column": [ "*" ], "connection": [ { "

geoserver图层样式

Styled Layer Descriptor 标准描述了稳当的结构合使用规则。一个文档包含了符号定义和绘制规则,那么这个文档就叫做Styled Layer Desciptor(SLD)样式,它是一个text/Xml文件,扩展名为.sld。SLD基于XML标记语言,附加的标准是一个XSD schema,XSD schema定义了SLD语法。样式文档结构 样式最外层不分包含如下代码: <?xml version="1.0" encoding="ISO-8859-1"?> <StyledLayerDescriptor version="1.0.0" xsi:schemaLocation="http://www.opengis.net/sld StyledLayerDescriptor.xsd" xmlns="http://www.opengis.net/sld" xmlns:ogc="http://www.opengis.net/ogc" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 第一行包含xml定义,每一个样式文件的根节点都为StyledLayerDescriptor,包含了样式标准的版本属性version(Geoserver可使用1.0.0和1.1.0 SLD版本),还包含了命名空间和模型属性。 StyledLayerDescriptor节点包含了一个NameLayer或者UserLayer的集合,这两个节点下面又包含了UserStyle节点集合。 UserStyle节点下包含FeatureTypeStyle或者CoverageStyle节点。它们下面都包含了rule集合元素。rule节点定义了怎样绘制feature。下面是一个简单的样式文件: <?xml version="1.0" encoding="UTF-8"?> <StyledLayerDescriptor version="1.0.0" xsi:schemaLocation="http://www.opengis.net/sld http://schemas.opengis.net/sld/1.0.0/StyledLayerDescriptor.xsd" xmlns="http://www.opengis.net/sld" xmlns:ogc="http://www.opengis.net/ogc" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <NamedLayer> <Name>capitals</Name> <UserStyle> <Name>capitals</Name> <Title>Capital cities</Title> <FeatureTypeStyle> <Rule> <Title>Capitals</Title> <PointSymbolizer> <Graphic> <Mark> <WellKnownName>circle</WellKnownName> <Fill> <CssParameter name="fill"> <ogc:Literal>#FFFFFF</ogc:Literal> </CssParameter> </Fill> <Stroke> <CssParameter name="stroke"> <ogc:Literal>#000000</ogc:Literal> </CssParameter> <CssParameter name="stroke-width"> <ogc:Literal>2</ogc:Literal> </CssParameter> </Stroke> </Mark> <Opacity> <ogc:Literal>1.0</ogc:Literal> </Opacity> <Size> <ogc:Literal>6</ogc:Literal> </Size> </Graphic> </PointSymbolizer> </Rule> </FeatureTypeStyle> </UserStyle> </NamedLayer> </StyledLayerDescriptor> UserStyle定义了一个circle符号使用白色填充,黑色边界。WellKnownName包括:circle、square、triangel、star、cross、x。

交叉编译opencv4移植到ARM

文章目录 前言(逼逼叨)环境准备1.系统环境准备2.编译环境准备2.1下载交叉编译工具:gcc、runtime、sysroot2.2 下载后解压并**合并**2.3 设置环境变量 配置编译makemake install 移植打包opencv拷贝到armARM端操作opencv解压安装链接库文件 可能产生的问题libstdc++.so.6 not found解决方法: 本文主要参考:https://blog.csdn.net/nila101/article/details/87367595 前言(逼逼叨) opencv在我虚拟机中轻松的就编译成功了,顺利的装上了。但是交叉编译真的搞死我了,难就难在CMake配置上,搞了3天,第三天终于琢磨出来了。期间找过无数篇帖子和博客,各种千奇百怪的办法都有,按照他们的奇葩方法我试了n次,不知道他们用这奇葩方法是怎么成功的???写这篇博客主要作为记录,顺便回馈给广大网友,没有广大道友的博客和帖子,我也无法突破! 现在已经是晚上11:47分了,写完这个博客又得直接睡觉了,没时间消遣了。 在arm机上运行opencv拍下我帅气照片的那一刻,我开心地笑了~ 2月初,正是2019-nCov爆发的时候,请各位保重! 环境 宿主机:Ubuntu18.04 x86_64(虚拟机)目标机:nanoPi neo2ARM芯片架构:aarch64opencv版本:opencv 4.2.0交叉编译器:gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu 交叉编译工具链下载地址:https://releases.linaro.org/components/toolchain/binaries/6.3-2017.05/aarch64-linux-gnu/ 准备 1.系统环境准备 opencv中文文档:https://www.w3cschool.cn/opencv/opencv-123j28z4.html 使用终端运行以下命令 # 如果电脑上没有C/C++编译环境,执行: sudo apt install build-essential # 使64位系统兼容32位的库: sudo apt install lib32ncurses5 lib32z1 # 安装相关工具 sudo apt install cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev # 安装cmake-gui sudo apt install cmake-qt-gui # 下载opencv mkdir nanopi_neo2 #建立一个目录 cd nanopi_neo2 git clone https://github.com/opencv/opencv.git opencv可以选择版本下载 opencv GitHub地址: https://github.

【行人重识别】Unsupervised Salience Learning for Person Re-identification

Abstract 人眼可以基于​​一些较小的显着区域来识别人的身份。然而,当使用现有方法计算图像的相似度时,通常会隐藏这种有价值的显着信息。此外,许多现有的方法学习区别性特征并以监督的方式处理急剧的视点变化,并要求为不同的摄像机视图对标注新的训练数据。在本文中,我们提出了一种基于无监督显着性学习的人员重新识别的新颖视角。在训练过程中无需识别标签即可提取出独特的特征。首先,我们应用邻接约束补丁匹配来建立图像对之间的密集对应,这显示了在处理由较大视点和姿势变化引起的未对准方面的有效性。其次,我们以无人监督的方式学习人类的显着性。为了提高人员重新识别的性能,将人的显着性纳入补丁匹配中,以找到可靠且有区别的匹配补丁。我们的方法的有效性在广泛使用的VIPeR数据集和ETHZ数据集上得到了验证。 1. Introduction 行人重识别可处理非重叠摄像机视图中的行人匹配和排列。 通过节省大量人力从大量视频序列中搜索人的工作量,它在视频监控中具有许多重要的应用。 但是,这也是一项非常具有挑战性的任务。 监控摄像头可以在一天之内观察数百名公共区域的行人,其中一些人的外表相似。 在不同的摄像机视图中观察到的同一个人通常在视点,姿势,摄像机设置,照明,遮挡和背景方面会发生显着变化,通常使不同视角下人的差异甚至比不同人差异更大,如图1所示。 我们的工作主要来自三个方面。 现有的大多数作品[25、15、8、29、16、24]通过采用监督模型来处理交叉视图变异问题并提取区分特征,监督模型需要带有身份标签的训练数据。 另外,由于不同的摄像机视图对的交叉视图转换不同,因此大多数摄像机在更改摄像机设置时都需要标记新的训练数据。 这在许多应用中是不切实际的,尤其是对于大型摄像机网络。 在本文中,我们提出了一种通过无监督学习来学习区分和可靠描述行人的新方法。 因此,它对一般摄像机视图设置具有更好的适应性。 在人物重新识别中,视点变化和姿势变化会导致图像之间不可控的不对齐。 例如,在图1中,图像(a1)的中心区域是相机视图A中的背包,而它变成相机视图B中图像(b1)中的手臂。因此,无法直接比较空间未对齐的特征向量。 在我们的方法中,应用补丁匹配来解决不对齐问题。 另外,基于对行人结构的先验知识,在补丁匹配中增加了一些约束条件,以提高匹配精度。 通过贴片匹配,我们可以将女士手提包上的蓝色倾斜条纹对准图1中黑色虚线框。 行人图像中的显着区域为识别提供了宝贵的信息。但是,如果尺寸较小,则在计算图像相似度时通常会隐藏显着性信息。在本文中,显着性意味着不同的特征:1)在使人从同伴中脱颖而出时是有区别的,2)在不同的观点中找到同一人是可靠的。例如,在图1中,如果数据集中的大多数人穿着相似的衣服和裤子,则很难识别它们。但是,人眼很容易识别匹配对,因为它们具有不同的特征,例如人(a1-b1)的背包带有倾斜的蓝色条纹,人(a2-b2)的手臂下有一个红色文件夹,人(a3-b3)的手中有一个红色的瓶子。这些独特的功能在区分一个人和其他人时具有区别性,并且可以在不同的相机视图之间进行匹配。凭直觉,如果一个摄像机视图中的身体部位是突出的,那么在另一摄像机视图中的身体部位也通常是突出的。此外,我们的显着性计算是基于与来自大型参考数据集而不是一小群人的图像的比较。因此,它在大多数情况下都非常稳定。但是,现有方法可能会将这些明显的特征视为要去除的遗留物,因为其中一些特征(例如行李或文件夹)不属于身体部位。衣服和裤子通常被认为是重新识别人身的最重要区域。在补丁匹配的辅助下,这些具有区别性和可靠性的功能已在本白皮书中用于人员重新识别。 本文的贡献可以概括为三个方面。首先,提出了一种无监督的框架来提取个性特征以供人员重新识别,而无需在训练过程中手动标记人员身份。其次,利用补丁匹配和邻接约束来处理由视点改变,姿势变化和打手势引起的错位问题。我们表明,受约束的补丁匹配极大地提高了人员重新识别的准确性,因为它可以灵活地处理较大的视点变化。第三,以无人监督的方式学习人类的显着性。与一般的图像显着性检测方法[4]不同,我们的显着性是专为人体匹配而设计的,具有以下特性。 1)对视点变化,姿势变化和清晰度具有鲁棒性。 2)仅当两个摄像机视图中的色块匹配且不同时,才将它们视为突出。 3)人的显着性本身是行人匹配的有用描述。例如,只有上身显着的人和只有下身显着的人必须具有不同的身份。 2. Related Work 3. Dense Correspondence 密集对应已应用于人脸和场景对齐[23,20]。 继承了基于零件和基于区域的方法的特征,细粒度的方法(包括像素级的光流,关键点特征匹配和局部面片匹配)通常是更好的选择,可以实现更可靠的对齐。 在我们的方法中,考虑到远场监视摄像机捕获的人像的中等分辨率,我们采用中级本地补丁来匹配人员。 为了确保匹配的鲁棒性,在每个图像中都对局部斑块进行了密集采样。 与一般的补丁匹配方法不同,对匹配的补丁搜索施加了一个简单但有效的水平约束,这使得补丁匹配在人的重新识别方面更具适应性。 mid-level local patches a simple but effective horizontal constraint is imposed on searching matched patches 3.1. Feature Extraction Dense Color Histogram 每个人的图像被密集地分割成局部补丁的网格。 从每个色标中提取一个LAB颜色直方图。 为了可靠地捕获颜色信息,还应在降采样后的比例上计算LAB颜色直方图。 为了与其他功能组合,将所有直方图进行L2归一化。 LAB color histograms Dense SIFT 为了处理视点和照明变化,SIFT描述符用作颜色直方图的补充功能。 与提取密集的颜色直方图的设置相同,在每个人的图像上采样密集的补丁网格。 我们将每个面片划分为4×4个单元,将局部梯度的方向量化为8个面元,并获得4×4×8 = 128的三维SIFT特征。 SIFT特征也经过L2标准化。

多线程中的乐观锁、悲观锁

多线程中,共享变量存放于共享内存,各个线程会将其copy到自己的线程内存中,更改数据,最后把线程内存中的数据复制给共享内存。 应用于多线程的乐观锁 乐观的以为每次拿取数据时别人都不会更改数据,但在更新的时候也会以某种方法判断一下有没有人更新这个数据。乐观锁应用于多读少写的场景。 判断有没有人更新数据有两种方法:版本号控制 和 CAS(compare and swap)比较和交换 版本号控制 比如,给数据加一个版本字段,凡线程对其进行数据更新后,版本号+1,当另一个线程对其更新时,会比对一下,共享内存中该数据的版本号,和当前线程中的版本号是否一致,不一致则说明有其他线程对其进行了更新,之后他要重新从内存中获取数据,再进行后续操作。 这个套路也可以用于数据库中数据的更改。 CAS CAS有三个参考值 V:变量在共享内存中的值 A:线程本地内存的值 B:线程模拟修改变量后的值 CAS机制在更新一个变量的时候,只有当变量在线程本地内存的值A和共享内存地址V当中的实际值相同时,才会将内存地址V对应的值修改为B。它与版本号控制原理类似,只不过它比较的是值而不是版本号。CAS的开销很大,它的底层有一个自旋锁(其实就是一个while判断),如果V不等于A的时候,它会一直循环,直到V等于A。CAS不能保障代码块的原子性。 CAS会引起ABA问题 假设,三个线程,一个共享变量A,线程1、3会把A变成C,如果线程1执行完后,共享变量变为C,线程3发现共享内存的值C 与 我线程内存的值A 不相等,所以线程3就不会执行,但是这时出现了一个线程2,它在线程1之后、线程3之前,将C又变回了A,那么之后线程3在执行时,发现原本内存的值A又和线程3内存值A相等了,线程3又会执行了,它将A变成了C,但这个C不是通过线程1得到的C。 实际场景,假设有100元,我开启了两个线程,他们执行的内容是,当有100元时,减去50元,这样,理论上两个线程都执行完后,还剩下50元,也就是只扣了一个50元。如果执行当中恰巧有另一个线程乱入了,这个线程执行的内容是增加50元,这个线程刚好排在了那两个线程中间执行,那么,最后一个线程执行时,他发现,-50又+50,共享内存中是100,那他符合执行条件,V=A,它也会执行一遍,最终得到的结果却是,100元被扣了2次50元。 ABA问题 通常的解决办法是添加版本号或时间戳,每次修改操作时版本号加一,这样数据对比的时候就不会出现 ABA 的问题了。 CAS在JAVA中的应用:java.util.concurrent.atomic包 比如 i++ 在多线程中的操作,如不使用sychronize修饰,将会出现问题。 假设100个线程执行对共享内存变量A=0的+1操作,得到结果往往会小于100,因为执行过程中,某个线程+1后,可能后面另一个线程已将其结果存在了共享内存中,当前线程再去存结果值,这样就会导致共享内存中的结果值变小(因为它有可能覆盖了另一个的结果值,这导致结果值比真实结果少了1) public class Counter { public volatile static int count = 0; public static void inc(){ try{ Thread.sleep(1); //延迟1毫秒 }catch (InterruptedException e){ //catch住中断异常,防止程序中断 e.printStackTrace(); } count++;//count值自加1 } public static void main(String[] args) throws InterruptedException { final CountDownLatch latch = new CountDownLatch(100); for(int i=0;i<100;i++){ new Thread(new Runnable() { @Override public void run() { Counter.

搞它!!!CentOS 7.6 安装和配置samba文件共享服务

文章目录 一、samba概述1.1 Samba是在Linux和UNIX系统上实现SMB协议的一个免软件,由服务器及客户端程序构。1.2 Samba监听端口1.3 samba进程1.4 samba用户1.5 samba配置文件 二、samba配置实例1.安装核心软件2.将samba配置文件备份一份,在进行修改3.在opt目录下创建abc文件,并且赋予777最大权限4.切换到客户机win10这边,在搜索框输入服务端的地址\192.168.100.485.回到服务端这边在abc目录下有一个sha文件,并查看6.指定用户读写共享文件的权限,在配置文件底行加入内容7.创建TEST1,2 用户并给他们设置smb密码8、在opt目录下创建test目录,并给其权限9.回到客户端,清空缓存;服务端重启服务 三. 利用smb服务访问win10的共享目录1、 设置来宾账户guest策略权限2.选择WIN10本地共享文件夹及修改属性3.在LINUX端查看及挂载WIN10共享文件夹4.可以正常访问使用win10共享文件夹了 一、samba概述 1.1 Samba是在Linux和UNIX系统上实现SMB协议的一个免软件,由服务器及客户端程序构。 在此之前我们已经了解了NFS,NFS与samba一样,也是在网络中实现文件共享的一种实现,但不幸的是,其不支持windows平台,而这次要提到的samba是能够在任何支持SMB协议的主机之间共享文件的一种实现,当然也包括windows。 SMB(Server Messages Block,信息服务块)是一种在局域网上共享文件和打印机的一种通信协议,它为局域网内的不同计算机之间提供文件及打印机等资源的共享服务。 SMB协议是C/S型协议,客户机通过该协议可以访问服务器上的共享文件系统、打印机及其他资源。 1.2 Samba监听端口 1.3 samba进程 winbindd + ldap 对应Windows AD活动目录 1.4 samba用户 设置 //smbpasswd命令: -a Sys_User //添加系统用户为samba用户并为其设置密码 -d //禁用用户帐号 -e //启用用户帐号 -x //删除用户帐号 [root@localhost ~]# yum -y install samba-* [root@localhost ~]# useradd tom [root@localhost ~]# smbpasswd -a tom New SMB password: Retype new SMB password: Added user tom. 1.5 samba配置文件 /etc/samba/smb.

(十一)OpenStack的neutron-网络服务介绍及安装配置

CONTENTS 1、neutron网络介绍 2、neutron配置 2.1 安装并配置controller节点 2.2 安装并配置network节点 2.3 安装并配置compute节点 2.4 配置外部网络 1、neutron网络介绍 (1)neutron基本概念 网络连接服务面向租户API接口,用于创建虚拟网络、路由器、负载均衡、关联网络接口至指定网络和路由通过API接口管理虚拟或物理交换机提供Plugin架构来支持不同的技术平台Neutron Private Network——提供固定私网地址Neutron Public Network——提供浮动IP 地址 (2)neutron关键概念 Network 一个L2网络单元租户可通过Neutron API创建自己的网络 Subnet 一段IPV4/IPV6 地址段为Instance提供私网或公网地址 Router 三层路由器为租户的Instance 提供路由功能 Port 虛拟交换机上的端口管理Instance 的网卡 (3)组件架构 (4)neutron plugin Open vSwitchLinux BridgeCiso NX1000Nicira NVPRyuNEC OpenFlowFloodnight (5)neutron+Nova架构 (6)neutron组件 组件沟通方式 (7)neutron常见的构建类型 Single FLAT NetworkMulti FLAT Ne tworkMixed FLAT and Private NetworkProvider Router with Private NetworkPer-tenant Routers with Private Network 2、neutron配置 2.1 安装并配置controller节点 (1)创建数据库,完成下列步骤: #a.使用root用户连接mysql数据库 mysql -u root -p #b.

全网最全经典卷积神经网络架构汇总——深度学习之ILSVRC竞赛(ImageNet竞赛)优胜网络结构

近年来,卷积神经网络在图像分类领域取得了巨大进展,主要表现在ILSVRC竞赛中优胜冠军从经典的机器学习算法转向深度学习算法,尤其是卷积神经网络结构。在卷积神经网络发展的历史过程中,ILSVRC竞赛功不可没,从2012年到2017年,不断涌现出新的卷积神经网络结构,并将ILSVRC竞赛中ImageNet数据集图像分类错误率降至很低的水平,一度达到甚至超越人类的水平。 ILSVRC全称ImageNet Large-Scale Visual Recognition Challenge,从2010年开始举办,2017年为最后一届比赛,历届比赛结果如下图所示: 下面总结了经典或者具有里程碑意义的卷积神经网络结构: 1. LeNet5——卷积神经网络开山之作 由LeCun发表于1998年,是CNN的鼻祖。 网络详解: 原始论文翻译: 2. AlexNet——ILSVRC 2012年冠军 网络亮点: 采用ReLU激活函数引入Dropout数据增强多GPU并行计算 网络详解:深度学习之卷积神经网络经典网络之AlexNet 原始论文翻译:ImageNet Classification with Deep Convolutional Neural Networks 8. ZFNet——ILSVRC 2013年冠军 网络亮点: 通过反卷积可视化CNN学习到的特征 网络详解: 原始论文翻译: 3. VGGNet——ILSVRC 2014年亚军 网络亮点: 重复使用3*3的卷积核和2*2的池化层加深网络 网络详解:深度学习之卷积神经网络经典网络之VGGNet 原始论文翻译:Very Deep Convolutional Networks for Large-Scale Image Recognition 4. GoogLeNet——ILSVRC 2014年冠军 网络亮点: 提出Inception模块,同时增加网络深度和宽度 网络详解:深度学习之卷积神经网络经典网络之GoogLeNet 5. ResNet——ILSVRC 2015年冠军 网络亮点: 提出残差模块 网络详解:深度学习之卷积神经网络经典网络之ResNet 6. DenseNet 7. SENet——ILSVRC 2017年冠军 网络详解:深度学习之卷积神经网络经典网络之SENet

Sutton reinforcement learning _ Chapter 2 Multi-armed Bandits

打算看英文版Sutton的《强化学习》,从第二章开始记录下对每一章的理解,对每一块的内容大致介绍,留个纪念。 这一章围绕着多臂赌博机问题,介绍了基本的强化学习算法(value based),并探讨了利用(exploit)和探索(explore)问题。 2.1 A k-armed Bandit Problem 有k个赌博机,每次的操作就是拉下其中一个控制杆,随后你会得到一个奖励。通过多次的选择,你要使得总收益最大化。其中每个赌博机的收益服从一个分布。k个动作的每一个被选择时都有一个期望奖励,称为这个动作的价值。在时刻的动作为,对应的奖励为。任一动作对应的价值,记为。如果知道每个动作的价值,那么每次选择价值最高的动作就行。假设不知道动作的价值,我们就要进行估计。我们对动作在时刻的价值的估计记为,我们期望它接近。 2.2 Action-value Methods 这是一个估计动作价值的方法,用这些动作价值的估计来选择。一种简单的方法就是通过计算实际收益的平均值来作为动作价值的估计。 其中,当为真时值为1,反之为0。当分母为0时,我们将定义为一个默认值,比如0。 最简单的的方案是选择具有最高估计值的动作,及贪心(greedy)。如果有多个贪心动作,则选择任意一个,即,其中,是使得最大的动。这种方案总是利用当前的知识最大化眼前的收益,只有利用(exploit)没有探索(explore)。一个简单的代替是,以的概率从所有动作中随机选一个动作,的概率用贪心策略,这样每一个动作就有可能被采样到。 2.3 The 10-armed Testbed 评估算法和的性能,这部分比较好理解。 2.4 Incremental Implementation 我们用观测到的奖励的样本均值来估计action-value,这里介绍了一种高效的方法来计算样本均值。表示某一动作第次被选中获得的奖励,表示该动作被选择n-1次后它的估计的action-value。 可以换一种方式来计算这个式子 一个使用以增量式计算的样本均值和动作选择的多臂赌博机算法如下 2.5 Tracking a Nonstationary Problem 前面讨论的问题前提是每个赌博机的奖励概率分布是固定的(stationary),如果奖励概率是不固定的(随着时间变化,unstationary),那么取平均的方法就不适用。这时比较流行的方法是去固定步长,即,其中 2.6 Optimistic Initial Values 目前我们讨论的方法都在一定程度上依赖于初始动作的值,这些方法是有偏的(biased)。但实际中,这通常并不是一个问题。 初始动作的价值同时也提供了一种简单的探索(explore)方式,如果初始值设置的比较大,那么刚开始算法会倾向于探索每一个动作,会进行大量的探索(explore),我们把这种初始值的设定称为乐观初始价值。它适用于固定奖励概率分布问题,而不适用与非固定的情况,因为它探索的动因是暂时的。 2.7 Upper-Confidence-Bound Action Selection 这里提出了一种根据动作的潜力来选择可能事实上是最优的动作,这要考虑它们的估计有多接近最大值,以及这些估计的不确定性。按如下公式选择动作 表示在时刻之前动作被选中的次数,如果他为0,那么被认为是最好的动作。这方法叫置信度上限(UCB,Upper-Confidence-Bound)),平方根项是对动作值估计的不确定性或方差的度量。最大值的大小是动作的可能真实值的上限,是置信水平。下图是UCB算法与的比较 2.8 Gradient Bandit Algorithms 本节中,针对每个动作,考虑一个数值化的偏好函数。偏好函数越大,动作就越频繁地被选择。 和表示在时刻选择动作的概率。 基于梯度上升,提出一中自然的学习方法。每个步骤中,在选择动作并获得后,偏好函数会更新 其中,是一个大于0的树,表示步长,是在时刻内所有收益的平均值。作为一个基准,收益高于它,那么未来选择动作的概率会增加,反之减少。基准项的作用可以用下图来表示 实际上梯度赌博机算法可以理解为梯度上升的随机近似,证明过程如下 至此证明了该算法的期望更新与期望奖励的梯度是相等的,因此该算法是随机梯度上升算法的一种。这保证了算法的收敛性。 对于基准项,只要要求它与所选的动作无关即可。可以为一个固定的数0或1000,该算法仍是梯度上升算法的特例。基准项不影响算法的更新,但它会影响更新值的方查,从而影响收敛速度。采用奖励的平均可能不是最好的,但是它简单,在实践中很有效。 2.9 Associative Search (Contextual Bandits) 以上所考虑的问题都是非关联的,没有必要将不同的动作与不同的情境联系起来。在一般的强化学习问题中,往往有不止一种情境,他们的目标是学习一种策略:一个从特定情境到最优动作的映射。 关于这个问题不是本章的重点,就不介绍了。 2.10 Summary 在这一章介绍了几种平衡exploit和explore的方法,比较了几种算法的性能,并在最后提及了更复杂的平衡exploit和explore的方法(贝叶斯方法)。

串口传输速率计算

串口数据格式 起始位1bit,数据位8bit,停止位1bit,无校验,无流控; 计算 波特率115200(bps) = 115200 (位/秒),没有校验位时,起始位1bit+数据位8bit+停止位1bit=10bit 波特率115200(bps) = 115200 (位/秒) = 11.25 (KB/秒) = 11520 (字节/秒) 串口通道可参考%80利用率计算,根据实际需求*0.8。 参考:https://blog.csdn.net/sinat_23338865/article/details/52873429 提问:提升波特率能增加带宽? 链接1:https://blog.csdn.net/xchbx/article/details/11537951 链接2:https://blog.csdn.net/Reborn_Lee/article/details/80745218?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-6.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-6.nonecase

图像连通域的计算

OpenCV 4中connectedComponents函数对图像连通域的计算 先说一下函数的原型 int cv::connectedComponents(InputArray image, OutputArray labels, int connectivity=8, int ltype=CV_32S ) image:为输入图像,必须为单通道类型(CV_8U) labels:标记不同连通域的输出图像,与原图像尺寸相同 connectivity:标记连通域时使用的邻域种类,4表示4邻域,8表示8邻域 ltype:输出图像的数据类型,目前支持CV_32S和CV_16U 首先把我的实验图片放上去,需要实验图片的自行下载 下面是使用OpenCV函数connectedComponents函数实现的图像连通域的计算 #include<opencv2/core/core.hpp> #include<opencv2/imgproc/imgproc.hpp> #include<opencv2/ximgproc.hpp> #include<vector> #include<time.h> using namespace std; using namespace cv; void connect() { //读入图像 Mat image = imread("test01.jpg"); //判断图像是否读入成功 if (image.empty()) { cout << "图片读入出错,请检查路径是否存在" << endl; return; } //转换为灰度图像 Mat imageGray; cvtColor(image, imageGray, COLOR_BGR2GRAY); //得到阈值图像 Mat imageTredh; threshold(imageGray,imageTredh,50,255,THRESH_BINARY); //使用时间种子随机生成的颜色区分不同的连通域 RNG rng(time(NULL)); Mat outImage; int count = connectedComponents(imageTredh, outImage, 8, CV_16U); vector<Vec3b> colors; for (int i = 0; i < count; i++) { Vec3b vec3 = Vec3b(rng.

C语言:力扣:378. 有序矩阵中第K小的元素

给定一个 n x n 矩阵,其中每行和每列元素均按升序排序,找到矩阵中第 k 小的元素。 请注意,它是排序后的第 k 小元素,而不是第 k 个不同的元素。 matrix = [ [ 1, 5, 9], [10, 11, 13], [12, 13, 15] ], k = 8, 返回 13。 该题目在力扣中属于中等难度,因此确实是有些难到我了😂,不过没事,最终在答案和思考的双重攻势下,还是搞出来了。这里我总共有两种方法 1 放入一堆数组后排序 开始的时候,我是直接暴力遍历放入数组,利用选排排序之后,直接return,但是最大数据时超时了,这让我意识到果然中等题目不是这么简单,但是我换了一种qsort方法之后它却并未过时,所以我想还是我用的算法时间太高了。 这里我并不推荐使用stdlib.h文件中的qsort函数,因为该函数虽然可以对多种数据结构进行排序,但是就算法角度来说属于取巧 一般我们需要手写一个函数对其进行配套使用 int cmp(const void*a,const void*b)//降序,qsort函数默认升序,而实现升序规则只需调换成a-b的形式即可 { return *(int*)b-*(int*)a; } void qsort(rec, num, sizeof(int), cmp); 这样的qsort函数可以直接对数组进行排序,答案代码: int cmp(const void *a, const void *b) { return (*(int *)a - *(int *)b); } //a-b为升序,b-a为降序 这里我们使用升序 int kthSmallest(int **matrix, int matrixSize, int *matrixColSize, int k) { int *b = (int *)malloc(matrixSize * matrixSize * sizeof(int)); int num = 0;//这里的num用来计数,表示总元素数量 for (int i = 0; i < matrixSize; i++) { for (int j = 0; j < matrixSize; j++) { b[num++] = matrix[i][j]; } } qsort(b, num, sizeof(int), cmp); //cmp为函数指针 return b[k - 1]; } 2 二分法求值 二分法我觉得就算法角度来说是最适合的做这道题目的。

学习笔记之Linux学习(一):Linux安装以及目录介绍、Xshell终端的安装

目录 1、Linux的介绍2、Linux的安装文件介绍3、VMware Workstation Pro 的安装4、Linux目录介绍5、Xshell终端的安装注意: 1、Linux的介绍 2、Linux的安装文件介绍 首先介绍一下本次学习需要安装的软件: VMware Workstation Pro (VMware-workstation-full-12.1.0-3272444) CentOS-6.5-x86_64-bin-DVD1.iso Xshell5.exe 下载地址为: 链接:https://pan.baidu.com/s/1QIzxgQAY1wNttaxOxwoZEg 提取码:pcra 里面有整理好的笔记以及后续学习所需要的安装包,包括有以下: apache-tomcat-7.0.47.tar.gz VMware12及密钥 CentOS-6.5-x86_64-bin-DVD1.iso FileZilla_3.23.0.2_win64-setup.exe jdk-8u11-linux-x64.tar.gz mysql-community-release-el6-5.noarch.rpm Xshell5.exe 好了,不多BB了,开始下面的学习。 3、VMware Workstation Pro 的安装 打开下载的文件夹, 找到VMware12及密钥下的VMware-workstation-full-12.1.0-3272444.exe 双击运行。 然后一直点击下一步,选择合适的安装目录,直接安装即可,安装完成之后需要输入密钥,在文件夹中有密钥,复制粘贴即可。 VMware 12 专业版永久许可证密钥: 5A02H-AU243-TZJ49-GTC7K-3C61N 4、Linux的安装 打开安装好的VMware Workstation Pro ,点击新建虚拟机。 然后选择典型,下一步 这里是要选择镜像文件,选择我们下载的镜像文件,在文件夹中,点击下一步 填写好用户名和密码,密码建议短一点,不要太长,填写完毕之后点击下一步。 之后就是选择安装的位置,建议不要装在C盘,建议在其他盘新建一个文件夹专门用来放虚拟机文件,然后点击下一步 这里我们选择默认的。 这里也选择默认的,点击完成,接下来便是等待安装。 安装期间会出现下图所示,这个时候鼠标点进去按回车就行了,鼠标如果想切换出来按Ctrl+Alt 等待的时间可能会稍微有点长,这个时候不要关闭程序,耐心等待… 最后出现以下界面就说明安装成功了,这里我们点击other,输入root 和密码,使用root角色进入虚拟机。 进入之后出现这个弹框,勾选以后不再弹出就行了。 这样我们虚拟机就安装完成了。。。。 4、Linux目录介绍 1.1.1 : / 根目录.Unix 和 Linux 中,没有盘符. 一个硬盘,一个根. 1.1.2 :/bin 系统的常用命令目录. 包括控制台命令, 系统可执行文件, 系统的核心二进制文件等.

Python中的映射类型详解

泛映射类型 collections.abc模块中有Mapping和MutableMapping这两个抽象基类,它们的作用事为dict和其他类似的类型定义形式接口 非抽象映射类型一般不会直接继承这些抽象基类,它们会直接对dict或者是collections.UserDict进行扩展.这些抽象基类的主要作用事作为形式化的文档,它们定义了构建一个映射类型所需要的最基本的接口.然后它们还可以跟isinstance一起被用来判定某个数据是不是广义上的映射类型: from collections.abc import Mapping, MutableMapping 标准库里的所有映射类型都是利用dict来实现的,因此它们有个共同的限制,即只有<可散列的>数据类型才能用作这些映射里的键. 什么是可散列的数据类型? 如果一个对象是可散列的,那么在这个对象的生命周期中,它的散列值是不变的,而且这个对象需要实现__hash__()方法. 另外可散列对象还要有__eq__()方法,这样才能跟其他键作比较.如果两个可散列对象是相等的,那么它们的散列值一定是一样的. 原子不可变数据类型(str,bytes和数值类型)都是可散列类型,frozenset也是可散列的,因为根据其定义,frozenset里只能容纳可散列类型. 元组的话,只有当一个元组包含的所有元素都是可散列类型的情况下,它才是可散列的. tt = (1, 2, (30, 40)) print(hash(tt)) # 8027212646858338501 tl = (1, 2, [30, 40]) # print(hash(tl)) # TypeError: unhashable type: 'list' tf = (1, 2, frozenset([30, 40])) print(hash(tf)) # 985328935373711578 一般来讲,用户自定义的类型的对象都是可散列的,散列值就是它们的id()函数的返回值,所以所有这些对象在比较的时候都是不相等的. 如果一个对象实现了__eq__方法,并且在方法中用到了这个对象的内部状态的话,那么只有当所有这些内部状态都是不可变的情况下,这个对象踩死可散列的. ''' 遇到问题没人解答?小编创建了一个Python学习交流QQ群:531509025 寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书! ''' class A: def __init__(self, a_): self.a = a_ class B: def __init__(self, a_): self.a = a_ def __hash__(self): return hash(self.

IntelliJ Idea 注释模板

IntelliJ Idea 注释模板 IntelliJ Idea 添加类文件注释1.第一步 File ——>Settings——>Editor——>Life and Code Templates IntelliJ Idea 添加函数注释模板1.第一步 File ——>Settings——>Editor——>Life Templates2.添加函数注释模板3.点击Edit variables设置表达式和默认值4.添加完成 输入 \ ** 按TAB键(效果图) IntelliJ Idea 添加类文件注释 1.第一步 File ——>Settings——>Editor——>Life and Code Templates PS:Class、Interface、Enum都适用这套模板 将模板复制到类文件中即可 #if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end #parse("File Header.java") /** * @ClassName ${NAME} * @Description TODO * @author ${USER} * @create ${YEAR}-${MONTH}-${DAY} ${TIME} */ public class ${NAME} { } 到这就完成了,在新建文件的时候,注释会自动加上(附上效果图) IntelliJ Idea 添加函数注释模板 1.第一步 File ——>Settings——>Editor——>Life Templates 2.

SSH整合Ureport2报表工具

SSH整合Ureport2报表工具 Ureport2报表工具: UReport2是一款基于架构在Spring之上纯Java的高性能报表引擎,通过迭代单元格可以实现任意复杂的中国式报表。相比UReport1,UReport2重写了全部代码,弥补了UReport1在功能及性能上的各种不足。 在UReport2中,提供了全新的基于网页的报表设计器,可以在Chrome、Firefox、Edge等各种主流浏览器运行(IE浏览器除外)。使用UReport2,打开浏览器即可完成各种复杂报表的设计制作。 UReport2是第一款基于Apache-2.0开源协议的中式报表引擎 GitHub地址:https://github.com/youseries/ureport 文档:http://wiki.bsdn.org/pages/viewpage.action?pageId=76448364 (w3cschool也有相同的文档) 配置使用 加入相关依赖 <!--ureport2报表引擎依赖--> <dependency> <groupId>com.bstek.ureport</groupId> <artifactId>ureport2-console</artifactId> <version>2.2.3</version> </dependency> web.xml配置 <!--ureport2报表的url访问路径--> <servlet> <servlet-name>ureportServlet</servlet-name> <servlet-class>com.bstek.ureport.console.UReportServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>ureportServlet</servlet-name> <!--此处的/ureport/*为固定写法,否则无法访问--> <url-pattern>/ureport/*</url-pattern> </servlet-mapping> spring配置文件加入 <import resource="classpath:ureport-console-context.xml" /> 配置完成后在浏览器输入:localhost:8080/{项目地址}/ureport/designer (我的是localhost:8080/ureport/designer)

Java手机号码,身份证号码加密隐藏中间几位并且*显示(正则,密文显示)

原本打算用字符串截取来做这种效果,但是最近看了一些关于正则的知识,所以就用正则来试试水,比较简单就直接上代码吧 //手机号保留前3后4 中间4个*号显示 String phone = "15645621235"; System.out.println(phone.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2")); //手机号保留前3后1 中间7个*号显示 String phone1 = "17805631269"; System.out.println(phone1.replaceAll("(\\d{3})\\d{7}(\\d{1})", "$1*******$2")); String idCard = "430529199607166698"; System.out.println(idCard.replaceAll("(\\d{4})\\d{10}(\\d{4})", "$1****$2"));

WPF 界面实现多语言支持 中英文切换 动态加载资源字典

1、使用资源字典,首先新建两个字典文件en-us.xaml、zh-cn.xaml。定义中英文的字符串在这里面【注意:添加xmlns:s="clr-namespace:System;assembly=mscorlib】 zh-cn.xam如下: <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:local="clr-namespace:WpfApplication"> <s:String x:Key="buttonNewTaskWindow">新建任务</s:String> <s:String x:Key="buttonProperty">任务属性</s:String> < /ResourceDictionary> en-us.xaml如下: <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:local="clr-namespace:WpfApplication"> <s:String x:Key="buttonNewTaskWindow">New Task</s:String> <s:String x:Key="buttonProperty">Task Property</s:String> </ResourceDictionary> 2、讲两个资源字典添加到App.xaml中,这里注意下,因为两个字典中有同样字符,如果没有动态更改,默认后添加的生效 App.xaml如下: <Application x:Class="WpfApplication.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" StartupUri="MainWindow.xaml"> <Application.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="Resources\en-us.xaml"/> <ResourceDictionary Source="Resources\zh-cn.xaml"/> </ResourceDictionary.MergedDictionaries> </ResourceDictionary> </Application.Resources> < /Application> 3、在界面设计器中需要显示的位置添加动态资源 例如: <Button x:Name="buttonNewTaskWindow" Content="{DynamicResource buttonNewTaskWindow}"/> <Button x:Name="buttonProperty" Content="{DynamicResource buttonProperty}"/> 4、动态切换,重新加载资源文件 代码如下: List<ResourceDictionary> dictionaryList = new List<ResourceDictionary>(); foreach (ResourceDictionary dictionary in Application.Current.Resources.MergedDictionaries) { dictionaryList.Add(dictionary); } string requestedCulture = @"

AMBARI2.7.3安装(ubuntu18&centos)

MBARI2.7.3安装(ubuntu18&centos) centos: https://www.rookiegao.top/ 1.首页 2.环境准备 先下载需要用到的官方安装包,分别有如下4个文件: 项目 Value ambari http://public-repo-1.hortonworks.com/ambari/centos7/2.x/updates/2.6.2.2/ambari-2.6.2.2-centos7.tar.gz HDP http://public-repo-1.hortonworks.com/HDP/centos7/2.x/updates/2.6.5.0/HDP-2.6.5.0-centos7-rpm.tar.gz HDP-UTILS http://public-repo-1.hortonworks.com/HDP-UTILS-1.1.0.22/repos/centos7/HDP-UTILS-1.1.0.22-centos7.tar.gz HDP-GPL http://public-repo-1.hortonworks.com/HDP-GPL/centos7/2.x/updates/2.6.5.0/HDP-GPL-2.6.5.0-centos7-gpl.tar.gz ambari http://public-repo-1.hortonworks.com/ambari/ubuntu18/2.x/updates/2.7.3.0/ambari-2.7.3.0-ubuntu18.tar.gz HDP http://public-repo-1.hortonworks.com/HDP/ubuntu18/3.x/updates/3.1.0.0/HDP-3.1.0.0-ubuntu18-deb.tar.gz HDP-UTILS http://public-repo-1.hortonworks.com/HDP-UTILS-1.1.0.22/repos/ubuntu18/HDP-UTILS-1.1.0.22-ubuntu18.tar.gz HDP-GPL http://public-repo-1.hortonworks.com/HDP-GPL/ubuntu18/3.x/updates/3.1.0.0/HDP-GPL-3.1.0.0-ubuntu18-gpl.tar.gz 3.配置HTTP服务 完成软件源的更新后,输入以下的命令进行安装Apache服务器。 #sudo apt-get install apache2 #mkdir -p /var/www/html 将上文的 ambari HDP HDP-GPL HDP-UTILS 解压后放入 /var/www/html 4.配置APT本地安装 在/etc/apt/sources.list.d目录下,新增以下文件 ambari.list deb http://127.0.0.1/ambari/ubuntu18/2.7.3.0-139/ Ambari main ambari-hdp.list deb http://127.0.0.1/HDP-GPL/ubuntu18/3.1.0.0-78/ HDP-GPL main deb http://127.0.0.1/HDP-UTILS/ubuntu18/1.1.0.22/ HDP-UTILS main deb http://127.0.0.1/HDP/ubuntu18/3.1.0.0-78/ HDP main 在浏览器输入url进行简单验证 最后运行 apt-get update 进行更新 5.安装AMBARI-SERVER 5.1 AMBARI配置 执行 apt-get install ambari-server成功后,执行

AntD Select 选择器设置默认选中项

没什么可说的直接放代码 :default-value="{ key: defaultSheet }" <template> <div class="wrapper"> <a-select :default-value="{ key: defaultSheet }" class="new-from-preview-title-item" label-in-value style="width: 120px" @change="onSelectSheet" > <a-select-option v-for="(item,index) in file.sheetList" :key="index" :value="index">{{ item }}</a-select-option> </a-select> </div> </template> <script> export default { data() { return { file: { sheetList: ['sheet1', 'sheet2','sheet3'] }, defaultSheet: 0 } }, methods: { onSelectSheet(val) { console.log(val) } } } </script>

Element-Ui组件 单选框(Radio) 修改点击激活时的文本颜色,填充色和边框色

Element-Ui组件 单选框(Radio) 修改点击激活时的文本颜色,填充色和边框色 官方组件显示的效果: 需要的效果: 直接添加样式: /* 选中后的字体颜色 */ .el-radio__input.is-checked + .el-radio__label { color: #28d4c1 !important; } /* 选中后小圆点的颜色 */ .el-radio__input.is-checked .el-radio__inner { background: #28d4c1 !important; border-color: #28d4c1 !important; } 这是我自己添加的边框,没有用官方的,官方的我暂时还有试过 效果图: <style lang="scss" scoped> //修改单选的颜色 /deep/ { .el-radio { //添加边框 border: 1px solid rgb(207, 204, 204); //选中时边框的颜色 &.is-checked { border: 1px solid #28d4c1 !important; } //鼠标滑过改变字体和小圆圈边框的样式 &:hover { border-color: #28d4c1 !important; color: #28d4c1 !important; //鼠标滑过时小圆点边框显示 .el-radio__inner { border-color: #28d4c1; } } .

conda | An HTTP error occurred when trying to retrieve this URL 解决方案

问题描述 conda安装包的时候, 下载中断, 导致安装失败, 报错信息如下所示: Error: CondaHTTPError: HTTP 000 CONNECTION FAILED for url <https://repo.anaconda.com/pk gs/pro/noarch/repodata.json.bz2> Elapsed: - An HTTP error occurred when trying to retrieve this URL. HTTP errors are often intermittent, and a simple retry will get you on your way. If your current network has https://www.anaconda.com blocked, please file a support request with your network engineering team. ConnectionError(MaxRetryError("HTTPSConnectionPool(host='repo.anaconda.com', por t=443): Max retries exceeded with url: /pkgs/pro/noarch/repodata.json.bz2 (Cause d by NewConnectionError('<urllib3.

排序算法Java版本(1)

冒泡排序 public class PaixuMaoPao { public static void main(String[] args) { int[] arr=[24,69,80,57,13]; Maopao(arr); System.out.println(arr); } private static int Maopao(int[] arr){ for(int j=0;i<=arr.length-1;j++){ for(int i=0;j<=arr.length-1-j;i++){ if(arr[i]>arr[i+1]){ int t=arr[i]; arr[i+1]=t; arr[i]=arr[i+1]; } } } return arr; } } 选择排序 import java.util.Arrays; public class PaixuXuanZe { public static void main(String[] args) { int[] arr={1,4,23,2,45,5}; int temp=0; for(int i=0;i<arr.length;i++){ for(int j=i+1;j<arr.length;j++){ if(arr[i]<arr[j]){ temp=arr[i]; arr[i]=arr[j]; arr[j]=temp; } } } System.out.println(Arrays.toString(arr)); } } 堆排序

如何判断一个对象是数组还是对象

一、typeof判断数据类型(判断数组跟对象都返回object) console.log(typeof null); // "object" console.log(typeof function () { return 1; }); // "function" console.log(typeof 1); // "number" console.log(typeof a); // "undefined" console.log(typeof undefined); // "undefined" console.log(typeof []); // "object" console.log(typeof NaN); // "number" console.log(typeof {}); // "object" 二、instanceof判断对象的原型链是否是指向构造函数的prototype var arr = [1,2,3,1]; console.log(arr instanceof Array)//true 三、对象的constructor属性 var arr = [1,2,3,1]; console.log(arr.constructor === Array)//true 四、Object.prototype.toString.call(arr) 利用对象的toString可以准确判断是什么类型,call()改变this指向,这里是借用Object的方法,然后有人可能会问为什么不直接用arr.toString而要借用Object的方法, console.log(Object.prototype.toString.call(“jerry”));//[object String] console.log(Object.prototype.toString.call(12));//[object Number] console.log(Object.prototype.toString.call(true));//[object Boolean] console.log(Object.prototype.toString.call(undefined));//[object Undefined] console.log(Object.prototype.toString.call(null));//[object Null] console.log(Object.prototype.toString.call({name: “jerry”}));//[object Object]

SpringBoot2.* GateWay网关中关闭security验证

package com.petkit.gateway.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity; import org.springframework.security.config.web.server.ServerHttpSecurity; import org.springframework.security.web.server.SecurityWebFilterChain; /** * @author menglinjie * @date Created in 2020/6/22 12:01 * @description: 注意:webflux环境下要生效必须用注解@EnableWebFluxSecurity使其生效 * cloud gateway采用的webflux技术(此处与web不同) */ @Configuration @EnableWebFluxSecurity public class WebSecurityConfig { @Bean SecurityWebFilterChain webFluxSecurityFilterChain(ServerHttpSecurity http) throws Exception { http.authorizeExchange() .anyExchange() .permitAll(); // 一些配置 http .csrf().disable() .httpBasic().disable() .logout().disable() .formLogin().disable(); return http.build(); } } 注意:gateway网关项目和普通springboot项目关闭security验证的方式不同。原因是gateway采用的webflux技术,不是servlet。

利用OpenCV实现对车流量的统计

此文在我的个人博客地址:https://sublimerui.top/archives/48ab4a6e.html 目录 调试平台汽车识别原理——背景/前景分割算法整体结构整体流程框架图主要参数主要函数 测试结果结论附:程序源代码 闲话少絮。开始正题——OpenCV的车流量统计。 调试平台 OpenCV 4.2VS 2019 汽车识别原理——背景/前景分割算法 如今,检测和提取车辆时候,常用的方法有MOG2算法和KNN算法。MOG算法是以高斯混合模型(GMM)为基础的背景/前景分割算法。它是以2004年和2006年Z.Zivkovic的两篇文章为基础的。这个算法的一个特点是它为每一个像素选择一个合适数目的高斯分布。其主要原理为:在一个固定位置和角度固定的视频或图像中,提取分割图像或视频中运动的成分。此算法使用背景建模的方式,将整张图片或一帧视频分为前景和后景。此算法运行时,会将动态的前景与静止的后景相减,得出结果即为徐提取的运动物体的图像。 K最近邻算法(KNN)是属于机器学习的一种算法。其主要原理为:给定一个已训练数据集,对新的输入实例,在训练数据集中找到与该实例最邻近(注:衡量邻近的标准以具体选取的某个特征而言,例如下面示意图中使用的特征为欧式距离)的K个实例,这K个实例的多数属于某个类,则判定该输入实例同属此类。如下图所示:训练者取k值,计算以欧氏距离k为半径的圆内其他类别的个数,图中中心小红点以k为半径的圆内三角形个数最多,则判定中心小红点为三角形。 整体结构 整体流程框架图 本程序的主要运行流程为:程序运行开始,首先从文件中获取上次保存的光流量检测矩形框数据(顶点坐标和矩形的长宽);其后,分别初始化背景提取对象,使用MOG2和KNN两种算法。与此同时,建立一个鼠标回调函数,用于捕获鼠标左键(绘制矩形框)、中键(取消操作)和右键(保存矩形框数据到文件)的操作。 此后,程序进入主循环状态。程序循环从视频中获取一帧的图像,先进行压缩处理,以提高后续运算速度。之后,将这一帧图片从RGB转为灰度图片。为了祛除灰度后可能出现的小毛刺杂点,再进行平滑滤波处理。此后,分别通过MOG2和KNN算法提取前景,并将提取后的视频显示出来。与此同时,获取每个矩形框中积分后的亮度和。 最后,两个算法中,分别将实时得到的亮度和与所预设的阈值进行比较,当满足条件后,便认为一辆汽车通过矩形框,使得计数器加一。如此重复,统计整个视频中的车流量。 主要参数 int detectTHD 此参数为预设的亮度阈值。确定是否有汽车经过检测框中,其需要联合上一帧积分亮度和本次积分亮度后综合做出决定。 cv::Size newSize(frame.cols / 2, frame.rows / 2); 此参数可以储存一帧视频缩小后的大小。 cv::Mat showMat; 此参数用于储存最终显示的图像矩阵。 主要函数 static void onMouse(int event, int x, int y, int flags, void\*) 此函数主要用于检测鼠标左键、滑轮(中键)和右键的一些操作,用于绘制矩形检测框。 cv::resize(frame, newframe, newSize); 此函数主要用于缩小原视频比例,提高计算机运算速度。 bgMOG2-\>apply(greyFrame, mog2RES, update_bg_model ? -1 : 0);以及bgKNN-\>apply(greyFrame, KNN, update_bg_model ? -1 : 0); apply函数主要用于两种算法的前景提取。此后,前景提取后的这帧视频保存于bgMOG2和bgKNN之中。 cv::rectangle(showMat, myLanneRect.at(k), cv::Scalar(255, 255, 255), 3); 此函数主要用于前景提取后在其上面绘制矩形框。

Visual Studio 开发入门

Visual Studio 开发入门 1. 版本2. 高效性的常用功能3. 安装Visual Studio IDE4. 创建一个程序5. 使用重构和IntelliSense6. 调试代码7. 自定义Visual Studio8. 下一步 Visual Studio集成开发环境是一个创造性的启动板,可用于编辑,调试和生成代码,然后发布应用程序。集成开发环境(IDE)是功能丰富的程序,可用于软件开发的许多方面。除了大多数IDE提供的标准编辑器和调试器之外,Visual Studio还包括编译器,代码完成工具,图形设计器以及许多简化软件开发过程的功能。 此图显示了带有打开项目的Visual Studio和您可能会使用的几个关键工具窗口: 解决方案资源管理器(右上方)使您可以查看,导航和管理代码文件。解决方案资源管理器可以通过将文件分组到解决方案和项目中来帮助组织代码。您可能会花费大部分时间的编辑器窗口(中心)显示文件内容。您可以在此处编辑代码或设计用户界面,例如带有按钮和文本框的窗口。使用团队资源管理器(右下),您可以使用版本控制技术(例如Git和Team Foundation版本控制(TFVC))跟踪工作项并与其他人共享代码。 1. 版本 Visual Studio 适用于Windows和Mac。 Visual Studio for Mac具有许多与Visual Studio 2019相同的功能,并且针对开发跨平台和移动应用程序进行了优化。本文重点介绍Windows版本的Visual Studio 2019。 Visual Studio 2019有三种版本:社区,专业和企业。请参阅比较Visual Studio版本以了解每个版本支持哪些功能。 2. 高效性的常用功能 Visual Studio中一些高效性的常用功能可帮助您在开发软件时提高工作效率,这些功能包括: 花样和快速动作 花样是波浪线状的下划线,可在您键入时提醒您错误或代码中的潜在问题。这些直观的线索使您可以立即解决问题,而不必等待在构建过程中或运行程序时发现错误。如果将鼠标悬停在花体上,则会看到有关该错误的其他信息。灯泡也可能会出现在左边距中,并带有称为“快速操作”的操作来纠正错误。 代码清理 单击按钮,格式化代码并应用代码风格设置,.editorconfig 约定和 Roslyn分析器建议的所有代码修复。代码清理可帮助您在进行代码审查之前解决代码中的问题。(当前仅适用于C#代码。) 重构 重构包括诸如变量的智能重命名,将一行或多行代码提取到一种新方法中,更改方法参数的顺序等操作。 智能感知 IntelliSense是一组功能的术语,这些功能可以直接在编辑器中显示有关您的代码的信息,在某些情况下,还可以为您编写少量代码。就像在编辑器中内联基本文档一样,这使您不必在其他地方查找类型信息。 IntelliSense功能因语言而异。有关更多信息,请参见C#IntelliSense,Visual C ++ IntelliSense,JavaScript IntelliSense和Visual Basic IntelliSense。下图显示了IntelliSense如何显示类型的成员列表: 搜索框 如此众多的菜单,选项和属性,有时Visual Studio似乎不堪重负。搜索框是在Visual Studio中快速找到所需内容的好方法。当您开始键入要查找的内容的名称时,Visual Studio会列出结果,使您准确到达所需的位置。如果需要向Visual Studio添加功能(例如,添加对其他编程语言的支持),则搜索框将提供打开Visual Studio安装程序以安装工作负载或单个组件的结果。 按Ctrl + Q作为搜索框的快捷方式。

创建一个 C++ 控制台应用程序项目

创建一个 C++ 控制台应用程序项目 1. 先决条件2. 创建您的应用程序项目 C++ 程序员的通常起点是在命令行上运行的"Hello, world!"应用程序。这就是您将在此步骤中在 Visual Studio 中创建的内容。 1. 先决条件 在计算机上安装并运行带有 C++ 工作负载的 Visual Studio。如果尚未安装,请参阅在 Visual Studio 中安装 C++ 支持。 2. 创建您的应用程序项目 Visual Studio 使用 projects 来组织应用程序的代码,并使用 solutions 来组织项目。项目包含用于构建应用程序的所有选项,配置和规则。它管理所有项目文件和任何外部文件之间的关系。要创建您的应用程序,首先,您将创建一个新的项目和解决方案。 在 Visual Studio 中,打开File菜单,然后选择New > Project以打开Create a new Project对话框。选择具有C++,Windows 和 Console 标记的 Console App 模板,然后选择Next。 在Configure your new project对话框中,在Project name编辑框中输入HelloWorld。选择Create以创建项目。 Visual Studio 将创建一个新项目。准备好添加和编辑源代码了。默认情况下,Console App 模板使用 "Hello World" 应用程序填充您的源代码: 当代码在编辑器中看起来像这样时,您就可以继续下一步并构建您的应用程序了。

ARM体系架构—ARMv7-A处理器模式及寄存器

一、ARMv7-A处理器模式 ARMv7架构支持安全扩展,如果使能了安全扩展,ARMv7-A架构分为安全模式(Secure State)和非安全模式(Non-secure State)两个世界。 在非安全模式下,存在三种运行特权PL0,PL1和PL2(privilege level)。 If the Virtualization Extensions are implemented there is a privilege model different to that of previous architectures. In Non-secure state there can be three privilege levels, PL0, PL1 and PL2. 特权等级描述PL0PL0运行在用户模式(User),用于运行应用程序。该模式程序受限访问系统资源。对应Linux用户态。PL1PL1运行非用户模式和Hyp模式外的所有模式。Linux内核运行在PL1。包含了ARMv6架构中的System,SVC,FIQ,IRQ,UNDEF及Abort模式。此外,安全模式中的Montior也运行在PL1等级,管理安全模式和非安全模式的切换。PL2PL2用于虚拟化。虚拟化超级管理程序(Hypervisor)运行在PL2。 二、ARMv7-A通用寄存器 ARMv7-A架构提供了16个32位通用寄存器(R0-R15)和一个程序状态寄存器CPSR(Current Program Status Register),在异常模式下,可以访问SPSR(Saved Program Status Register),在异常模式下,SPSR用于保存当前CPSR寄存器值。其中R0-R14可以用于普通数据存储,R15是程序计数器PC(program counter)。 以上寄存器可能因运行模式不同而对应不同的物理存储位置,上图中蓝色区域即如此,它们使用不同的物理存储,通常只有在进程以特定模式执行时才可访问。 R0-R7在任何模式下都对应相同的物理存储,称之为未分组寄存器;R8-R14根据模式不同对应不同的物理存储,称之为分组寄存器;R13(SP)在User和Sys模式下对应相同的物理存储,FIQ,IRQ,ABT,SVC,UND,MON,HYP模式分别对应不同的物理存储。R13在ARM架构中用于SP堆栈指针(stack pointer)。MON模式用于管理安全与非安全模式,HYP模式用于管理虚拟操作系统(GuestOS)。R14(LR)在User,Sys和HYP模式下对应相同的物理存储,FIQ,IRQ,ABT,SVC,UND,MON模式分别对应不同的物理存储。R14在ARM架构中用于LR链接寄存器,在每种模式下,R14用于保存子程序返回地址。执行BL指令时,R14用于备份R15寄存器的值。R15(PC)保存当前程序执行的地址。在所有模式下,R15(PC)共享相同的物理存储。在ARM状态下,[1:0]为0,[31:2]用于保存PC。在Thumb状态下,[0]为0,[31:1]用于保存PC。CPSR是程序状态寄存器,保存条件标志位,中断禁止位,当前处理器模式等控制和状态位。每种异常模式下还存在SPSR,保存进入异常模式前的CPSR寄存器值,用于异常处理完成后恢复CPSR的状态。User和Sys不属于异常模式,没有CPSR寄存器,在User模式下,受限的CPSR寄存器称谓APSR( Application Program Status Register)。ARMv7-A中CPSR寄存器的信息如下图所示。 各Field代表含义如下: Field作用NALU返回运算结果是否为负数ZALU返回运算结果是否为0CALU运算是否发生进位VALU运算是否发生溢出Qcumulative saturationJARM是否处于 Jazelle 状态E控制load/store字节序Adisables asynchronous aborts,User模式不能操作I使能/去使能IRQ,User模式不能操作F使能/去使能FIQ,User模式不能操作TARM和Thumb状态标志位GE用于某些SIMD(Single Instruction, Multiple Data)指令M[4:0]处理器模式:FIQ,IRQ,ABT,SVC,UND,MON,HYP。User模式不能操作 三、ARMv7-A协处理器CP15寄存器 ARMv7-A架构保护系统控制协处理器CP15,主要用于处理存储系统相关的功能。CP15只能在特权模式下访问。CP15提供了16个32位主寄存器,命名为c0-c15。c0-c15寄存器可能对应多个不同的物理寄存器。 registerphysical register描述c0MIDR主ID寄存器,用于记录厂商版本信息MPIDRMultiprocessor Affinity Registerc1SCTLR系统控制寄存器ACTLR辅助控制寄存器CPACR协处理器访问控制寄存器,控制访问除了CP14和CP15的协处理器SCR安全配置寄存器c2 c3TTBR0一级转换页表基址寄存器0TTBR1一级转换页表基址寄存器1TTBCR页表转换控制寄存器c5 c6DFSR数据异常(Data Fault)状态寄存器IFSR指令异常(Instruction Fault)状态寄存器DFAR数据异常(Data Fault)地址寄存器IFAR指令异常(Instruction Fault)地址寄存器c7 predictorcache及分支预测barrier数据及指令屏障c8TLBTLB操作c9performance monitors性能监视器c12 VBAR非安全模式异常基址寄存器MVBAR安全模式异常基址寄存器c13 ASID上下文ID寄存器,软件线程ID寄存器c15CBAR配置基址寄存器,用于GIC(Generic Interrupt Controller)和定时器类型外设 协处理器CP15寄存器访问包括读和写操作。

手动下载依赖使用 pip 安装 wxPython

1. 下载 wxPython 的依赖 下载地址:https://download.csdn.net/download/Wh1teMaster/12606562 numpy-1.18.1-cp37-cp37m-win_amd64.whl Pillow-7.0.0-cp37-cp37m-win_amd64.whl six-1.14.0-py2.py3-none-any.whl wxPython-4.0.6-cp37-cp37m-win_amd64.whl 2. 使用 pip 安装下载的 whl pip install numpy-1.18.1-cp37-cp37m-win_amd64.whl Pillow-7.0.0-cp37-cp37m-win_amd64.whl six-1.14.0-py2.py3-none-any.whl wxPython-4.0.6-cp37-cp37m-win_amd64.whl 3. 测试安装 >>> import wx >>> wx.version() '4.0.6 msw (phoenix) wxWidgets 3.0.5'

我给面试官讲解了单例模式后,他对我竖起了大拇指!

单例模式相信大家都有所听闻,甚至也写过不少了,在面试中也是考得最多的其中一个设计模式,面试官常常会要求写出两种类型的单例模式并且解释其原理,废话不多说,我们开始学习如何很好地回答这一道面试题吧。 1. 什么是单例模式 面试官问什么是单例模式时,千万不要答非所问,给出单例模式有两种类型之类的回答,要围绕单例模式的定义去展开。 单例模式是指在内存中只会创建且仅创建一次对象的设计模式。在程序中多次使用同一个对象且作用相同时,为了防止频繁地创建对象使得内存飙升,单例模式可以让程序仅在内存中创建一个对象,让所有需要调用的地方都共享这一单例对象。 2. 单例模式的类型 单例模式有两种类型: 懒汉式:在真正需要使用对象时才去创建该单例类对象饿汉式:在类加载时已经创建好该单例对象,等待被程序使用 懒汉式创建单例对象 懒汉式创建对象的方法是在程序使用对象前,先判断该对象是否已经实例化(判空),若已实例化直接返回该类对象。,否则则先执行实例化操作。 根据上面的流程图,就可以写出下面的这段代码 public class Singleton { private static Singleton singleton; private Singleton(){} public static Singleton getInstance() { if (singleton == null) { singleton = new Singleton(); } return singleton; } } 没错,这里我们已经写出了一个很不错的单例模式,不过它不是完美的,但是这并不影响我们使用这个“单例对象”。 以上就是懒汉式创建单例对象的方法,我会在后面解释这段代码在哪里可以优化,存在什么问题。 饿汉式创建单例对象 饿汉式在类加载时已经创建好该对象,在程序调用时直接返回该单例对象即可,即我们在编码时就已经指明了要马上创建这个对象,不需要等到被调用时再去创建。 关于类加载,涉及到JVM的内容,我们目前可以简单认为在程序启动时,这个单例对象就已经创建好了。 public class Singleton{ private static final Singleton singleton = new Singleton(); private Singleton(){} public static Singleton getInstance() { return singleton; } } 注意上面的代码在第3行已经实例化好了一个Singleton对象在内存中,不会有多个Singleton对象实例存在

华为交换机路由器最新默认密码大全

华为交换机路由器最新默认密码大全包括console、telnet、web、bootrom登陆,框式与合式设备,是目前最全的密码大全 忘记密码了肿么办? 1.恢复Console口登录密码 方法一:通过Telnet登录交换机修改Console口密码。 如果小伙伴们拥有Telnet账号,并且具有管理员权限,则可以通过Telnet登录到交换机后修改Console口密码,然后保存配置。 步骤1:用Telnet账号登录交换机。 步骤2:修改Console用户的密码。 以修改为password认证,密码为“023wg@com”为例。 system-view [HUAWEI] user-interface console 0 [HUAWEI-ui-console0] authentication-mode password [HUAWEI-ui-console0] set authentication password cipher 023wg@com [HUAWEI-ui-console0] return 步骤3:用save命令保存配置,防止重启后配置丢失。 方法二:通过 BootROM清除Console口密码登录后,修改Console口密码。 要是交换机是双主控,小伙伴们就需要在重启交换机之前将备主控板拔下,待按照下面的操作执行完后,将备主控板插上,再执行save操作保证主用主控板和备用主控板配置一致。 交换机的BootROM提供了清除Console口密码的功能,可以在用户使用Console口登录的时候跳过密码检查。交换机启动后修改Console口密码,然后保存配置。 步骤1:通过Console口连接交换机,然后重启交换机。当出现“Press Ctrl+B to enter Boot Menu…”打印信息时,按下组合键“Ctrl+B”并输入BootROM密码(缺省为“Admin@huawei.com”),进入BootROM主菜单。 步骤2:在BootROM主菜单下选择“Clear password for console user”清除Console口登录密码。 步骤3:根据交换机的提示,在BootROM主菜单下选择“Boot with default mode”启动设备。 不可以凭自己的想象选择"Reboot"哦,否则此次清除密码将失效。 步骤4:完成系统启动后,通过Console口登录时不需要认证,登录后配置Console口密码,以修改为password认证,并修改密码为“023wg@com”为例。 system-view [HUAWEI] user-interface console 0 [HUAWEI-ui-console0] authentication-mode password [HUAWEI-ui-console0] set authentication password cipher 023wg@com [HUAWEI-ui-console0] return 步骤5:用save命令保存配置,防止重启后配置丢失。 2.恢复Telnet登录密码 telnet登录密码丢失,可以通过其他方式(例如Console口)登录交换机后重新进行配置。 步骤1:通过其他方式(例如Console)登录交换机。 步骤2:修改用户密码。 以针对VTY0~4配置AAA验证方式,原用户名为“huawei”,密码配置为“023wg@com”为例。 system-view

python的分支和循环语句

python的分支和循环语句 分支语句循环语句while循环for循环 案例 分支语句 分支语句: 计算机三种基础语句(顺序、分支、循环)之一,用于描述“如果满足什么条件,就怎么样,否则就怎么样”的语法。语法格式 格式一: if 条件: 条件成立执行的代码 格式二: if 条件: 条件成立执行的代码 else : 条件不成立执行的代码 格式三: if 条件1: 条件1成立执行的代码 elif 条件2: 条件2成立执行的代码 elif 条件3: 条件3成立执行的代码 else : 条件都不成立执行的代码 注意 分支语句可以嵌套,即分支语句的执行代码内可以包含全新的分支语句结构 循环语句 while循环 循环概念:循环是程序设计语言中反复执行某些代码的一种计算机处理过程语法 while循环 while 条件: 需要重复执行的代码 while…else while 条件: 需要重复执行的代码 else : 循环正常运行结束后执行的操作 循环的终止与跳出 ①break break可以用于终止循环的执行,当执行到break语句后,程序将跳出循环,执行循环语句后面的代码 eg: i=0 while i<10: # 当i==5时,跳出循环,最终的打印结果为01234 if i==5: break print(i) i=i+1 ②continue continue可以用于提前结束本轮循环的执行,当执行到continue语句后,程序将跳到判定循环是否向下执行的条件处,进行下一轮循环是否执行的判定与后续代码执行 eg: i=0 while i<9: i=i+1 # 当i==5时,跳出本次循环,进入下一次循环的判断,最终的打印结果为12346789 if i==5: continue print(i) 注意 如果循环语句未设置合理的退出条件,则循环语句将构成死循环,程序将永久执行下去。循环语句可以嵌套 for循环 作用:用于对数据进行遍历访问语法 for循环

jol使用

jol含义 Java object layout java对象内存布局 使用方式 本人jar包管理工具是gradle compile group: 'org.openjdk.jol', name: 'jol-core', version: '0.9' 些测试案例 public static void main(String[] args) { Object o = new Object(); System.out.println(ClassLayout.parseInstance(o).toPrintable()); } 运行结果 可以看到new object() 一共被分配16个字节 前8个对象头, markword与锁有关 后4个:class point,Java默认开启类型指针压缩,原本为8,压缩后4个字节 最后4个:对齐 自动补全为8的整数位

【STM32F103】GPIO_Remap1_CAN1与GPIO_Remap2_CAN1区别

1.问题描述 最近在画一个小板子,引脚有点多,使用的芯片是STM32F103VET6,100脚的封装。在选择脚的的时候,没有仔细看 Default和Remap这两栏,就直接把PD0和PD1当作了CAN的收发脚。结果码代码的时候发现这玩意居然需要重映射(如下图), 欲哭无泪,只好硬着头皮学习一波了. 参考了一波原子PWM引脚重映射的程序,我以为是这样的就完事了。 第一步: RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD|RCC_APB2Periph_AFIO, ENABLE);//使能PORTD时钟,使能引脚复用时钟 第二步: RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);//使能CAN1时钟 第三步: GPIO_PinRemapConfig(GPIO_Remap1_CAN1, ENABLE); //定时器1部分重映射:CH1->PE9 CH1N->PE8 当我好奇的在Keil里跳转到GPIO_Remap1_CAN1这个参数时,我开始懵了,奇怪的东西出现了,这里有GPIO_Remap1_CAN1和GPIO_Remap2_CAN1,让我在这两个中选一个!难道我要抓阄? 2.解决问题 冷静一波,开始解决问题,首先还是做做功课,说一说stm32的引脚重映射功能。虽然别人讲的比我好,但我还是要自己写,哈哈哈。 2.1 端口复用和重映射 端口复用好比我有一把瑞士军刀,我拿出啥他就是啥功能。类似的,stm32的一个IO除了做普通IO口,一般会有多个功能,普通功能就是输出高低电平,读取输入高低电平之类,串口,CAN,IIC等属于高级功能,也就是端口可以复用的功能。 重映射,从本质上来讲,相当于一个水池连接了很多根管道,本来我默认从某一管道接水喝,但是某一天,这根管道坏了或者被占用了,我只好从另外一根管道接水,但是注意水还是原来的水。回到32上来。一个外设的引脚除了具有默认的端口外,还可以通过设置重映射寄存器的方式,把这个外设的引脚映射到其它的端口。意思是假设本来我串口默认脚是PA9,PA10,我可以通过重映射,把串口的脚变成PD10,PD11(只做举例) 2.2 寄存器(AFIO_MAPR) 通过查看《STM32中文参考手册》8.4.2,我们知道复用重映射由AFIO_MAPR寄存器配置,而CAN引脚的重映射,由该寄存器的14位和13位配置,如下图所示,回到我的问题,我需要把CAN重映射到PD0和PD1引脚,需要配置该寄存器的第14位和13位为1,该寄存器是32位的,也就是0000 0000 0000 0000 0110 0000 0000 0000,即0x6000。 然而,库函数里面给的是0x001D4000和0x001D6000. 而0X1D6000=0000 0000 0001 1101 0110 0000 0000 0000 ,第13位14位是11,使用PD0,PD1 而0x1D4000=0000 0000 0001 1101 0100 0000 0000 0000, 第13位14位是01,使用PB8,PB9 #define GPIO_Remap1_CAN1 ((uint32_t)0x001D4000) /*!< CAN1 Alternate Function mapping */ #define GPIO_Remap2_CAN1 ((uint32_t)0x001D6000) /*!< CAN1 Alternate Function mapping */ 至此,谜团解开,不过其他位也被配置了,有兴趣的同学可以自己去深究~

Android屏幕刷新——源码分析

Android屏幕刷新原理——源码分析 文章目录 Android屏幕刷新原理——源码分析概述VSync信号三级缓冲源码分析消息队列的同步屏障参考资料 概述 Android系统每16ms(一般的安卓手机的FPS(每秒的帧数)是60)会请求一次VSync(垂直同步)信号,进行一次屏幕刷新。在请求到VSync信号后系统会向主线程发送一个异步消息,为了保证UI的流畅,系统使用了消息队列的同步屏障来优先处理这个屏幕重绘的异步消息。 VSync信号 VSync是Vertical Synchronization的缩写,译作垂直同步,是一种在PC上已经很早就广泛使用的技术。垂直同步信号简单来说就是周期性的中断。 使用VSync信号的作用 强制帧率和显示器刷新频率同步。也就是让CPU和GPU在Choreographer(编舞者,名字起地还挺文艺)的协调下在VSync信号到来后进行一次屏幕刷新,即view的重绘。 没有使用VSync信号的情况: 可能因为CPU和GPU处理不协调、CPU或GPU处理任务过多等因素而导致丢帧现象发生。 使用VSync信号的情况 CPU或GPU处理任务过多还是会导致丢帧现象发生。 三级缓冲 Android4.0之后基本都是默认硬件加速,CPU跟GPU都是并发处理任务的,CPU处理完之后就完工,等下一个VSYNC到来就可以进行下一轮操作。也就是CPU、GPU、显示都会用到Buffer,VSYNC+双缓冲在理想情况下是没有问题的,但如果某个环节出现问题,那就不一样了如下(帧耗时超过16ms): 可以看到在第二个阶段,存在CPU资源浪费,为什么呢?双缓冲Surface只会提供两个Buffer,一个Buffer被DisPlay占用(SurfaceFlinger用完后不会释放当前的Buffer,只会释放旧的Buffer,直观的想一下,如果新Buffer生成受阻,那么肯定要保留一个备份给SF用,才能不阻碍合成显示,就必定要一直占用一个Buffer,新的Buffer来了才释放老的),另一个被GPU处理占用,所以,CPU就无法获取到Buffer处理当前UI,在Jank的阶段空空等待。一般出现这种场景都是连续的:比如复杂视觉效果每一帧可能需要20ms(CPU 8ms +GPU 12ms),GPU可能会一直超负荷,CPU跟GPU一直抢Buffer,这样带来的问题就是滚雪球似的掉帧,一直浪费,完全没有利用CPU与GPU并行处理的效率,成了串行处理。 解决的办法就是再增加一个Buffer给CPU用,让它提前忙起来,这样就能做到三方都有Buffer可用,CPU跟GPU不用争一个Buffer,真正实现并行处理。如下: Android屏幕刷新本质上来说就是view周期性地重新绘制到屏幕上的过程,而与这个过程有着密切关系的就是View的invalidate方法,下面就深入源码分析这个方法背后的原理。 源码分析 View.invalidate() public void invalidate() { invalidate(true); } public void invalidate(boolean invalidateCache) { invalidateInternal(0, 0, mRight - mLeft, mBottom - mTop, invalidateCache, true); } void invalidateInternal(int l, int t, int r, int b, boolean invalidateCache, boolean fullInvalidate) { if (mGhostView != null) { mGhostView.invalidate(true); return; } if (skipInvalidate()) { //跳过不可见和不再执行动画的view return; } // Reset content capture caches mCachedContentCaptureSession = null; //下面会对是否缓存做一些判断 if ((mPrivateFlags & (PFLAG_DRAWN | PFLAG_HAS_BOUNDS)) == (PFLAG_DRAWN | PFLAG_HAS_BOUNDS) || (invalidateCache && (mPrivateFlags & PFLAG_DRAWING_CACHE_VALID) == PFLAG_DRAWING_CACHE_VALID) || (mPrivateFlags & PFLAG_INVALIDATED) !

服务提供者无法注册到nacos服务器

问题可能是这样的 get service name from nacos server fail //或 No service to register for nacos client... // 或 nacos NoSuchMethodError // 或 nacos registry, qit-service-provider register failed...NacosRegistration{nacosDiscoveryProperties=NacosDiscoveryProperties{serverAddr='', endpoint='', namespace='', watchDelay=30000, logName='', ... 原因 这两个参数没有被正确的识别到。 spring: application: name: qit-provider cloud: nacos: discovery: server-addr: 10.100.100.100:8848 解决方法 我试过好多种(application.properties/boostrap.properties/bootstrap.yml等组合)都没有成功,最后在application.yml中添加这两个属性,注意是根据提示回车获取填写,这样不会出错。 仅供参考。

SNMP

SNMP 全称为simple network management protocol 中文为简单网络管理协议. 1简介功能 简单管理所有设备 ①管理端需要获取被管理端的一个状态信息时,管理端就发送一个获取指令给被管理端,被管理端收到此指令后把管理端要获取的信息封装成报文后返回给管理端; ②当管理端需要修改被管理端上的一些配置参数时,管理端就发送一个修改指令给被管理端,被管理端收到后修改相应的配置,如果修改成功,则返回修改成功的信息给管理端,如果未修改成功,则返回相应的错误信息给管理端; ③如果被管理端自己知道自己发生了故障,那它就主动发生一个消息给管理端,说明自己哪里出现了故障。 2 snmp协议的版本 snmp v1(版本1):有三个community认证, 分别是read-only( 只能获取信息 )、read-write( 能获取信息,也能发送控制指令 )、trap( agent主动联机nms ); snmp v2(版本2):功能增强,但仍基于community的认证; 因此又称2c版本; snmp v3(版本3):这个版本认证加强,但少人用. 3 snmp的服务器NMS(管理端) ① snmp的服务器主要被人称为nms(network management station,网络管理工作站), 因为它可以用来收集各种信息; ②snmp的服务器并不一定需要监听某个端口,因为一般来说,都是服务器主动去向客户端要求获取一些信息; 当服务器有监听端口的时候,那就是客户需要主动发送信息给服务器。这时信息的交流的主动双向的。 ③snmp服务器端可以做的操作( get, getnext, getbulk, set, getresponse ) 4snmp的客户端AGENT(被管理端) 1snmp的客户端主要被人称为agent. 2snmp的客户端相对于其它客户端来讲比较特殊,因为它需要监听某个端口(netstat -tlunp,snmp客户端主要监听的是UDP161端口), 一般像ftp, http等服务都是服务器端才需要监听端口; 5 snmp的工作原理 snmp的nms通过指令向正在监听某个端口的客户( agent )发送查询、控制指令; 从上图中可知SNMP的由三部份组成,NMS、Agent、MIB。管理端(NMS)要想获取到监控数据时就向Agent(被监控端)发送get操作,Agent通过MIB库抓取到数据后就返还给NMS,如果是Agent主动向NMS发送信息,那就采用trap操作。 MIB:管理信息库 6 snmp的mib( snmp的mib是比较难理解的一个方面 ); 1 snmp获取信息最终是靠oid来获取的,oid类似于ip。 ip区别主机,oid区别资源。 2 ip比较难记,于是产生了dns服务器. oid也比较难记,于是有了mib,mib维护着oid和名字之间的对应关系; 3 mib的文件主要存放在/usr/share/snmp/mibs/这个目录中,其中,mib2的名字为SNMPv2-MIB ICMP ICMP网际控制报文协议 用来使主机或路由器报告差错情况和提供有关异常情况的报告。这样就可以更有效的转发IP数据报和提高交付成功的机会。 功能:

生产环境内存泄露(Redirect)的问题排查分析过程

生产环境内存泄露(Redirect)的问题排查分析过程 问题说明 服务升级框架由原来的Spring-4.0.4.RELEASE+SpringMVC-4.0.4.RELEASE升级为SpringBoot-2.0.2.RELEASE服务有原来的外置Tomcat+jsp改成内置Tomcat+jsp 问题分析解决思路 生产环境过一两天出现内存溢出,观察发现,老年代的内存一直在飙高,触发的Full Gc并不会让老年代的内存减少太多,慢慢的积累,最终导致服务挂掉,内存溢出;通过dump生产的堆快照,然后使用MemoryAnalyzer进行堆栈分析,发现问题所在找到大量Redirect的内存占用,并且没有的得到释放,出现一定量的ConnectionException(zipkin中对mq的连接验证)并还在不断的增加发现大部分堆内存占用都是被Redirect所导致的,还有一部分是被ConnectionException导致的修改SpringMvc的Redirect重定向方式,修改zipkin的通信方式(http或者rabbitmq)我修改代码放弃了return "redirect:http://www.baidu.com?param=1"的书写方式改成response.sendRedirect(response.encodeRedirectURL(redirectUrl)); return null;这种方式;然后先去掉了zipkin的依赖引用; 分析过程 查看服务运行情况 查看服务信息(内存占用等情况) jps -l[v] 查看运行的服务的一些基础信息,进程id确定服务(命令的v可选,查看更想起的服务信息) 使用top 或者top -Hp pid查看内存或者cpu使用情况 top:查看多个服务的基础运行情况,内存,cpu的占用情况【可使用z盖面面板颜色,x进行排序操作,shift+<或者>进行不同属性值排序】top -Hp pid:查看某个服务的线程基础运行情况,内存,cpu的占用情况【可使用z盖面面板颜色,x进行排序操作,shift+<或者>进行不同属性值排序】 使用jmap进行项目内存情况分析(我当时就是根据这个看出老年代内存的不停增加) jmap -heap:查看命令帮助jmap -heap pid:查看进程的内存情况(新生代老年代的占用使用情况)jmap -histo:live pid|sort -k 3 -g -r |less:(查看现在存活的对象内存占用情况,按照占用内存大小进行排序,-g按照数字排序,r反转倒序)【3是内存大小,2是对象数量大小】jmap -dump:live,file=./web_01_202007110930_dump.hprof pid:查看进程为pid存活的堆内存的快照,后续可以用MemoryAnalyzer进行分析或者jprofiler【这两个需要下载下来来分析】进行分析,当然也可以在线上用jhat进行对堆内存分析 查看服务的gc情况 -jstat -gcutil 25376 1s [次数]:查看gc的汇总情况,1s为1秒输出一次,次数缺省无限输出,1s如果不写s默认为毫秒可写为1000 -jstat -gc 25376 1s [次数]:查看gc的详细情况,1s为1秒输出一次,次数缺省无限输出,1s如果不写s默认为毫秒可写为1000 服务分析过程 首先是通过一段时间( jmap -heap, jmap -histo:live)观察老年代内存的不断增长,查看(jstat )gc的情况原本以为是修改之后内存占用多,堆内存由原来的1G修改为现在的2G,后来发现依然出现内存溢出进行dump( jmap -dump:live,file=./web_01_202007110930_dump.hprof pid)进行dump线上内存快照,然后使用的是Eclipse的一个插件,这里下载了一个单独版进行分析MemoryAnalyzer,查出问题所在,分析图见下面;找到内存泄露点,分别为Redirect的动态参数如return “redirect /index.jsp?userId=111”,后面的参数是动态的,这样Springmvc中间在解析视图的时候会做一个缓存,也会把后面的参数进行缓存,这样每次缓存的路径大部分都是不一样的,时间久了就可能导致内存泄露的问题,晚上也找到的不同的解决方案,最终采用的是该代码的其中一种方案;这里随便从网上搜了一个连接丢到这了还有一个点就是观察有一个异常ConnectException异常在不停的增加,通过Dump发现是MQ的连接的异常,刚开始项目引进了Rabiitmq但是没有开启Rabbitmq配置,启动还没有报错,但是在Dump中却发现连接Mq的异常不停的增加,(期间使用SpringBoot的排除RabbitMq的自动配置,删除掉Mq的配置,问题重现),最后通过依赖关系查出猫腻,发现zipkin链路追踪中需要RabbitMq的连接;zipkin可以有选择的http,rabbitnq与zipkin进行通信,这里可以配置通信方式为http,我这边直接把zipkin的依赖暂时去掉了,其他方式自测,这里丢一个链接是解决此方式的方法修改Redirect其他跳转方式之后,去掉zipkin依赖之后,问题解决,老年代内存平稳,不在持续增加到很高,并没有在此出现内存溢出; MemoryAnalyzer内存溢出分析图 查看内存的基本占用情况查看内存占用树情况,观察出问题所在

实战简历编写,打造硬核敲门砖

实战简历编写,打造硬核敲门砖 1.自我介绍2. 技能描述3.工作经历4.项目经历4.1 商城4.2 进销存 自我评价教育经历 1.自我介绍 简历开篇就是介绍自己,忌长篇大论,那么点时间,相信你自己作为面试官,也不想去看阅读理解 忌讳 不要写杂事获得了什么证书之类,像计算机几级或者mysql认证证书什么的4、6级英语及个别例如acm奖项等,可写之前见有人写去养老院献爱心之类的,确实,人不错,但是和你的工作联系不是那么大 建议 条理清晰,最好有序号学历高要写前边,例如硕士,低于本科的话就先不要写,放在整体简历的最后 示例 简要,该体现的基本全都体现了,也可以放上去自己的籍贯,碰上老乡也是一种幸运 2. 技能描述 为何把这一项放在第二处? 因为你的技能,是占比最高的,例如公司想招一个会Spring Cloud和 Docker的,你全都没写,或者写在了后面,这就是重心没放在重点上,因为你做的项目很大概率和新公司的并不相同,甚至跨行业,技术才是通用的,所以建议放在第二处。 建议 做过多久的后端或者前端开发,或是全栈,这个也是面试官最想了解你的技术栈的先后顺序,例如你想做后端,那就要先写后端的技术,前端的技术你会,那就是锦上添花不要写精通,除非你自己觉得真的精通了,山外有山像一些技术,例如Vue、React你只是自己去看博客或者视频,写了一个demo,不要去写熟练,写了解,不然碰到个练家子,基本就会问你生命周期与组件等写一个框架或者一门技术时,一定一定去看看面试题,不然问到一些稍微深入的地方,你会懵逼 想到哪里先写到哪里,后面的想起来再去写一篇补充 一份Java技术栈示例 上面的技术没什么新鲜的,但是一条一条罗列出来,貌似比写证书什么的有用,当然,如果你熟悉热门的技术,例如 Python 爬虫、K8S、Spark、Oauth等等都是可以自行组装的,再次强调,不要写精通,技术面试官程序猿,或多或少都是心里有点犟的,你写个精通,今天不给你上一课,就不爽 3.工作经历 这个如果有大厂经历,可以替换掉第二处,优先级更上一层 其实也是写写时间点,公司职位,尽量用数字或者比率来写工作内容 反例 上海xxxxx有限公司 送外卖的 20xx.10-20xx.10 送送外卖,一天能送多少单,好评率达99% 上海xxxxx有限公司 Java研发 20xx.3-20xx.3 整理需求文档,设计数据库,搭框架学习,独立负责后端模块 前一个是不要写与你要找工作无关的工作经历,后者是太平常了,大家都这么写了 正常 北京****公司 JAVA 开发工程师 20xx.09-20xx.03 通过自学设计模式与数据库调优参与公司旧项目重构,完成后项目整体性能提升20% 在职期间,新项目的单元测试覆盖率达到80%,文档需求整理明确。 北京****公司 前端开发工程师 20xx.09-20xx.03 通过使用新技术Vue对公司旧项目重构,完成后项目页面流畅度提升20% 在职期间,对新项目的组件模块化,划分明确,文档需求整理明确。 这里你所写的,就要落实了,一般就会问你用到了哪些设计模式,还有数据库调优的解决方案,细化到 如设计模式解决了哪些问题,数据库索引等 前端就会涉及到模块的封装与重用,前端页面的缓存与热重载问题 4.项目经历 列出两个常见的且容易直接pass的项目 4.1 商城 不要写仿京东商城、易买网、 xx商城、信用贷,关于商城的还是不要写了,为什么? 除非你有真实的去亲身做过,比如举例一个购物车 写了购物车的后果就是… 还写么,没做过的就要考虑考虑了,是非能够自圆其说,所以还是自己做过什么就去写什么,真想包装,也请拿一些简单的业务去写,当然了,自己也要去做,亲身体验一个业务,不是看几个文章就能理解的 4.2 进销存 不是说不能写,一定要真的做过才要写,这个业务更为复杂,然后你就在项目模块三言两语给带过了 看到这里,估计会有人讲了,这也不让写那也不让写,到底写什么,其实,这个不是我说了算,是你说了算的,总之,如果就是你自己单独下班手撸一个项目,只要你对业务熟悉的很,一样,能做到这个程度的人,一样不一般 简历模板推荐