又创新作!阿里内部SpringBoot高阶手册爆火,简直不要太香

前言 当前我们都会说SpringBoot是Spring框架对“约定优先于配置理念的最佳实践的产物,一个典型的SpringBoot应用本质上其实就是一个基于Spring框架的应用,而如果大家对Spring框架已经了如指掌,那么,在我们一步步揭开SpringBoot微框架的面纱之后,大家就会发现“阳光之下,并无新事”。 至于Spring Boot的一些用途、特色、支持的开发语言,以及它的学习前景,网络上有各种各样的博文对此有过解释,在这里我就不多说了,Springboot的重要性不言而喻。下面我们就通过一份阿里大牛的SpringBoot经典之作来深入了解SpringBoot以及它的编程思想。 SpringBoot经典之作 进入Spring Boot世界 准备开发环境搭建开发工具 基础 Spring Boot基础分层开发Web应用程序响应式编程 进阶 Spring Boot进阶用ORM操作SQL数据库接口架构风格——RESTful集成安全框架,实现安全认证和授权集成Redis,实现高并发集成RabbitMQ,实现系统间的数据交换集成 NoSQL 数据库,实现搜索引擎 项目实战 开发企业级通用的后台系统实现一个类似“京东”的电子商务商城 以上就是SpringBoot的实战文档内容了,由于篇幅限制就只能这样展示出来了,下面我们来看看SpringBoot的编程思想。需要两份资料的小伙伴点赞文章,关注我后到文末查看免费获取方式 SpringBoot编程思想 由于文章在这里篇幅就很长了,这份文档就只能展示目录供大家参考了,还请海涵 目录一览: 以上就是这两份文档的主要内容了,由于篇幅限制只能这样展示出来了,这两份文档具备以下条件的都可以不太费力学习。 具有一定英文基础的大中专院校计算机相关专业的学生。 Java语言初学者。 在培训机构学习过几个月Java语言的学生。 需要提高动手能力的技术人员。 了解过Java框架,如SSH ( Struts+Spring+Hibernate )、SSM ( Spring+SpringMVC+MyBatis )、JFinal、SpringMVC、Struts、Hibernate等,想了解新技术的开发、测试、项目管理的人员。 已经熟练使用Java EE、Java SE,想转而使用Spring Boot的技术人员。 使用过其他语言,如:PHP、C#、Python的开发人员。 使用过其他语言框架,如Laravel、Yii、Thinkphp、Symfony和Zend,想转而使用Java语言的开发人员(这种类型的开发人员转入Spring Boot尤为轻松)。 会使用Scala、Java、Groovy和 Kotlin 等JVM语言的开发人员。 写在最后 Spring Boot是当前后端开发的极佳框架。它在如今纷繁的技术中尤为突出。如果你想加入到SpringBoot的学习中来,或者想更深入的了解SpringBoot,那么这两份文档一定能帮到你。俗话说:种一棵树最好的时间是十年前,其次是现在。如果你想学习进步,需要这两份文档作为参考,只需要点赞文章,关注我后添加助理即可免费获取!大家一起学习进步,迈向新的高峰!

一分钟解决this.$refs.xxx 取值为undefined问题

问题场景是这样, 我们设定一个组件的ref = ‘a’,根据生命周期,我们是可以在mounted中访问的,但是console.log(this.$refs.a)是undefined,而我们this.$refs打印出来,这个a是存在的,这是为什么呢? 可能你还没有注意到,Vue 在更新 DOM 时是异步执行的。只要侦听到数据变化,Vue 将开启一个队列,并缓冲在同一事件循环中发生的所有数据变更。如果同一个 watcher 被多次触发,只会被推入到队列中一次。这种在缓冲时去除重复数据对于避免不必要的计算和 DOM 操作是非常重要的。然后,在下一个的事件循环“tick”中,Vue 刷新队列并执行实际 (已去重的) 工作。Vue 在内部对异步队列尝试使用原生的 Promise.then、MutationObserver 和 setImmediate,如果执行环境不支持,则会采用 setTimeout(fn, 0) 代替。 具体查看官方文档的 异步更新队列 因为我的使用场景这个a组件是条件渲染的,所以我们首先一定要在满足这个条件的时候调用,其次,我们也应该做一下异步处理,vue给我们提供了vue.$nextTick()这个API,官方给的解释是 在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。 2.1.0 起新增:如果没有提供回调且在支持 Promise 的环境中,则返回一个 Promise。请注意 Vue 不自带 Promise 的 polyfill,所以如果你的目标浏览器不原生支持 Promise (IE:你们都看我干嘛),你得自己提供 polyfill。 所以这里我采用了异步函数async/await async function (){ await this.$nextTick(); this.$refs.a //操作a组件 } 12345 或者回调 this.$nextTick(function(){ //xxx } ); } 12345 这里不知道为什么, 我用回调没有反应,不知道bug还是有其他的奥妙

PHP与JSON的一些常用操作

PHP把数据写入JSON文件 <?php // 生成一个PHP数组 $data = array (); $data ["fruit"] = "apple" ; $data ["animal"] = "tiget"; // 把PHP数组转成JSON字符串,写入文件 $json_string = json_encode( $data ); ?> PHP读取JSON数据? <?php // 从文件中读取数据到PHP变量 $str = file_get_contents ( 'one.json' ); // 把JSON字符串转成PHP数组,并显示 $data = json_decode( $str , true); print_r($data); ?> js通过getElementByID获取PHP数据 <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <style> </style> <script type="text/JavaScript"> function test() { alert(document.getElementById("hid").value) } </script> </head> <body> <?php $data = array("

业务应用数据库压力过大解决方案

业务应用数据库压力解决方案 引言一、原因分析二、在代码层面消化数据库压力创建索引转移压力 三、给数据库请个保姆——中间件RedisMQ 四、忍法——数据库分身术分布式架构主从读写分离架构 五、总结 注意:原创文章,转载请注明出处。 引言 数据库炸了,加CPU加内存?或许还有更合适的方法,例如优化代码逻辑、合理利用中间件、横向扩展数据库配置。 之前在做业务应用系统压力测试项目的时候,发现性能不达标的应用,问题大多出在数据库上,服务器的资源才用了30%不到,数据库资源已经跑满的情况比比皆是。 应用系统数据库压力过大是每个业务经理都多多少少面临过的问题,那么解决的办法除了纵向提高数据库配置(扩容CPU、内存)之外,是否还有其他更高效的途径呢? 一、原因分析 众所周知,单台数据库实例配置的提升是有瓶颈的,特别是关系型数据库,当CPU和内存配置提高到一定程度后,性能就很难再有提高,即使对数据库的内核进行优化,也只能稍微抬高这个瓶颈线。 在我所经历过的应用系统压力测试工作中,发现大厂研发的应用产品,通常服务器压力和数据库压力是基本持平的,而中小型的软件开发商提供的产品,往往服务器还没体现出明显的压力,数据库却已经炸了。 有经验的软件开发工程师会思考如何在代码层面合理规划数据库和服务器所承受的压力,把一部分推拉数据库数据的功能模块转化为通过服务器缓存或计算来完成,从而将数据库压力转移到服务器上。 另外,我们还可以利用Redis、MQ等中间件的数据缓存、内容分发等功能,作为数据缓存站或中转站来分担数据库压力。 当已经无法再通过上述方案降低数据库压力后,我们还可以凭借分布式数据库、主从读写分离数据库支持横向扩展的能力,来提升数据库性能。理论上横向扩展数据库性能是可以无上限地提高数据库承压能力的。 综上所述,我准备从代码层、中间件、分布式三块来分享如何优化应用对数据库的使用,从而提升应用系统性能。 二、在代码层面消化数据库压力 在代码层面可以通过创建索引和转移压力两种方式给数据库减压。 创建索引 索引是MySQL和Oracle等数据库本身提供的功能,合理创建索引可以提高数据的检索效率,降低数据库服务器IO和CPU的消耗。 但由于索引也会降低更新表的速度,经常增删改的表或字段不适合创建索引,所以在开发初期,我们就应该根据数据库模型表和字段的作用来决定是否为该表建立索引,为数据记录较多的表中,频繁作为查询条件的字段建立索引。 转移压力 在代码层把数据库压力转移到服务器上,要求我们在编写代码的时候,时刻留意代码中是否有过多与数据库进行交互的行为,是否可以通过缓存或计算,来减少与数据库交互的次数。 例如一个功能模块的代码写下来,发现多次连接数据库,可以调整为一次性取出所有需要的数据,减少对数据库的查询次数。又例如模块中的某一个值,既可以通过逻辑运算得出,也可以通过数据库读取,在为减轻数据库压力的场景下,我们会选择前者。 三、给数据库请个保姆——中间件 能否合理使用中间件是考量一个开发技术经理能力的标准之一,利用各种中间件的优势,可以有效提高产品性能,减少资源消耗。在数据读取压力较大的场景中,往往会引入Redis和MQ中间件。 Redis Redis缓存数据库是将数据以键值对的形式缓存在内存中的高效数据库。在开发中,我们可以将一些频繁读取的数据临时存放到Redis,例如中签公告、人员名单、产品清单等,用户在访问这些数据的时候,如果发现缓存中有数据,则无需调用数据库,直接从Redis获取。同时,由于内存的读写速率是普通机械硬盘的几百倍,使用Redis作为数据缓存不仅减轻了数据库的压力,数据的存取速度还特别快,可以有效提高数据的调取速率。 MQ MQ消息队列中间件常用于流量消峰和消息分发。利用MQ将同一时刻的大量请求分散成一段时间来处理,可以有效减轻数据库负担;另外把消息发布到MQ中供多个客户端监听,也能达到减少数据查询次数的效果。 四、忍法——数据库分身术 上面几种方法是在应用系统的软实力上做文章,达到为数据库减压的目的,但面对真正庞大的流量袭来时,还是得下硬功夫——提升数据库自身的读写性能。 纵向提高数据库配置,加CPU、加内存,对性能的提升是有限的,幸运的是,目前大部分数据库都支持分布式架构,或主从读写分离架构。 分布式架构 分布式架构数据库由多个计算机系统设备共同组成一个数据库,提供完整的数据库服务,例如Oracle、MongoDB、TDSQL等,增加计算机系统的数量,就能提升整体数据库性能,理论上分布式架构数据库的性能可以无限提高,这就是为什么天猫能承受双十一几十亿并发压力的原因之一。 主从读写分离架构 主从读写分离架构是专门一个主数据库用来写入数据,另外搭建几个从数据库用于读取数据,主数据库会把数据的变更同步给几个从数据库,这样就能将数据库的读取压力分散到多台从数据库中,从而实现数据库的减压。 相比于前面几种方案,横向提高数据库性能的成本高昂,并且“本体”的能力到位了,“分身”才更能体现价值,产品本身优化到位了,分布式架构横向扩展的性价比才高,“软实力”和“硬功夫”两者需要有机结合。 五、总结 目前我参与开发的项目体量都比较小,数据库性能问题还没有凸显,但经过几次压力测试的项目工作,提前对大体量业务应用存在的性能障碍有了一定了解,并且经过一系列思考和查阅相关资料,总结了一些数据库压力过大的处理方法,在此分享给大家。如果各位还有其他的方案,或在工作中遇到了类似的问题,欢迎找我沟通探讨,互相学习。

k8s集群安装Kuboard进行管理

文章目录 简介安装kuboard获取token访问kuboard服务器进行容器副本的验证如何正确的删除pod 简介 上一篇博客中已经将k8s群集搭建完毕了,这一篇中将安装Kuboard 方便管理k8s群集。 如果想了解k8s群集的搭建可以看我的上一篇博客 安装kuboard 使用下面的命令安装kuboard [root@master ~]# kubectl apply -f https://kuboard.cn/install-script/kuboard.yaml 官网里有这个yaml文件的详细介绍 我这里下载下来了 apiVersion: apps/v1 kind: Deployment metadata: name: kuboard namespace: kube-system annotations: k8s.eip.work/displayName: kuboard k8s.eip.work/ingress: "true" k8s.eip.work/service: NodePort k8s.eip.work/workload: kuboard labels: k8s.eip.work/layer: monitor k8s.eip.work/name: kuboard spec: replicas: 1 selector: matchLabels: k8s.eip.work/layer: monitor k8s.eip.work/name: kuboard template: metadata: labels: k8s.eip.work/layer: monitor k8s.eip.work/name: kuboard spec: containers: - name: kuboard image: eipwork/kuboard:latest imagePullPolicy: Always tolerations: - key: node-role.kubernetes.io/master effect: NoSchedule --- apiVersion: v1 kind: Service metadata: name: kuboard namespace: kube-system spec: type: NodePort ports: - name: http port: 80 targetPort: 80 nodePort: 32567 selector: k8s.

快速解决 vue 项目 build 打包之后出现源代码的问题

浏览器通过按F12 然后打开控制台,点击 Source ,再点击 webpack:// ,点击相应的 vue 文件,竟然发现了 vue 的代码竟然完全显示出来了,啊这。。。。好吧,有点坑了,而且官方的文档中也没有说(或许我自己太菜了)。 其实这样是为了方便前端程序员在正式环境调试用的,默认是开启的,在 vue 的学习官网没有过多的介绍,因为使用的是 vue-cli 进行打包,所以在 vue-cli 文档中有介绍,具体查看 https://cli.vuejs.org/zh/config/#productionsourcemap 解决办法有两种: 方法一:如果项目中有 vue.config.js 文件,那么可以在该文件中配置,如果没有请移步方法二。 module.exports = { ... productionSourceMap: false // false 表示关闭 ... } 方法二:在 package.json 中增加 vue属性,在里面进行配置,一定要符合 JSON 的语法 【注】在 vue-cli 3.0 之后 vue.config.js 就变成了一个可选的配置文件,默认是没有的,但是呢,我们可以在 package.json 中进行配置,相关配置如下: { ... "dependencies": { ... }, "vue": { "productionSourceMap": false // false 表示关闭 }, ... } 以后真的要多去文档查阅一下:vue-cli 配置文档 个人博客:Roc’s Blog

离散时间序列的傅里叶变换和基本性质

目录 离散时间序列的傅里叶变换和基本性质 1、由连续时间序列的傅里叶变换: 2、DTFT的一些·常用性质 (1)时移性质 (2)频移性质 3、序列的对称性(这个比较重要) (1)实部与虚部的奇偶性 (2)序列的表示 (3)序列FT的对称性 1、由连续时间序列的傅里叶变换: 可以以此类推离散时间序列的傅里叶变换为 由于序列是离散的,所以求FT公式的时候用的累加;由于离散时间系统的FT是周期连续函数,且周期是2π(所以下面我们上下限选择的是+π),则可以直接用连续时间系统的FT公式带入。下面对离散时间系统的x(n)公式做一下验证: 至于这个2π周期,简要写一下: 其中M是整数 下面是一个具体实例,附加matlab代码: n=-10:10; x=[(n>=0)&(n<10)]; k=-200:200; w=(pi/200)*k; X=x*(exp(-j*pi/200)).^(n'*k); magX=abs(X); angX=angle(X); subplot(4,1,1); stem(n,x); xlabel('n'); ylabel('x'); grid on; subplot(4,1,2); plot(w,X,'LineWidth',1); xlabel('Frequency'); ylabel('X'); grid on; subplot(4,1,3); plot(w,magX,'LineWidth',1); xlabel('Frequency'); ylabel('|X|'); grid on; subplot(4,1,4); plot(w,angX,'LineWidth',1); xlabel('Frequency'); ylabel('ang(X)'); grid on; 2、DTFT的一些·常用性质 (1)时移性质 证明: 推导过程中使用了一步换元法: (2)频移性质 证明: 3、序列的对称性(这个比较重要) 首先介绍两个概念: 共轭对称序列条件: ,记做 共轭反对称序列条件: ,记做 (1)实部与虚部的奇偶性 由共轭对称序列与共轭反对称序列的条件可知: (1)若一个序列为共轭对称序列,那么 即实部为偶函数 即虚部为奇函数 (2)若一个序列是共轭反对称序列,那么 即实部是奇函数 即虚部是偶函数 (2)序列的表示 任何一个序列都可以由共轭对称序列和共轭反对称序列的和表示,即:

使用贝叶斯进行新闻分类

贝叶斯新闻分类任务 新闻数据集处理 爬取的新闻数据,需要我们对文本数据进行很多预处理才能使用 文本分词 通常我们处理的都是词而不是一篇文章 去停用词 停用词会对结果产生不好的影响,所以一定得把他们去剔除掉 构建文本特征 如何构建合适特征是自然语言处理中最重要的一步,这俩我们选择两种方案来进行对比 贝叶斯分类 基于贝叶斯算法来完成最终的分类任务 import csv import jieba.analyse import pandas as pd from sklearn.feature_extraction.text import CountVectorizer from sklearn.feature_extraction.text import TfidfVectorizer from sklearn.model_selection import train_test_split from sklearn.naive_bayes import MultinomialNB df_news = pd.read_table(filepath_or_buffer='./bayes/data.txt',names=['category','theme','URL','content'],encoding='UTF-8') df_news.dropna() df_news.tail() categorythemeURLcontent4995时尚常吃六类食物快速补充水分http://lady.people.com.cn/GB/18248366.html随着天气逐渐炎热,补水变得日益重要。据美国《跑步世界》杂志报道,喝水并不是为身体补充水分的唯...4996时尚情感:你是我的那盘菜 吃不起我走【2】http://lady.people.com.cn/n/2012/0712/c1014-18...我其实不想说这些话刺激他,他也是不得已。可是,我又该怎样说,怎样做?我只能走,离开这个伤心地...4997时尚揭秘不老女神刘晓庆的四任丈夫(图)http://lady.people.com.cn/n/2012/0730/c1014-18...58岁刘晓庆最新嫩照O衷诘牧跸庆绝对看不出她已经58岁了,她绝对可以秒杀刘亦菲、范冰冰这类美...4998时尚样板潮爸 时尚圈里的父亲们http://lady.people.com.cn/GB/18215232.html导语:做了爸爸就是一种幸福,无论是领养还是亲生,更何况出现在影视剧中。时尚圈永远是需要领军人...4999时尚全球最美女人长啥样?中国最美女人酷似章子怡(图)http://lady.people.com.cn/BIG5/n/2012/0727/c10...全球最美女人合成图::国整形外科教授李承哲,在国际学术杂志美容整形外科学会学报发表了考虑种族... stopwords = pd.read_table(filepath_or_buffer='./bayes/stopwords.txt',names=['stopword'],sep='\t',quoting=csv.QUOTE_NONE,encoding='UTF-8') stopwords = stopwords['stopword'].values.tolist() content_arr = df_news['content'].values.tolist() content_arr[0] '经销商\u3000电话\u3000试驾/订车U憬杭州滨江区江陵路1780号4008-112233转5864#保常叮00万9阒菔邪自魄白云大道北1361号;广州市天河区黄埔大道西100号富力盈泰大厦105室4008-112233转9915#保常福00万I蕉省淄博市张店区山泉路89号4008-112233转5156#保常叮00万4罅保税区黄海西三路101号4008-112233转2603#保玻埃00万L粕绞新纺锨复兴路21号4008-112233转3043#保常叮00万V泄云南昆明市度假区滇池路1268号4008-112233转7312#保常叮00万R川市兴庆区丽景北街800号4008-112233转3269#保常叮00万9尔滨市道外区先锋路469号4008-112233转2029#保矗福00万3ど呈刑煨那桂花坪街道雀园路口/星沙中南汽车世界A区05号4008-112233转7666#保常梗00万N浜菏信塘城经济开发区盘龙汽车城#矗埃埃福112233转7524#保常叮00万9阒莘禺区市广路989号(祈福食街旁)#矗埃埃福112233转9963#保常叮00万F侄新区御桥路1377号4008-112233转6337#保常福00万0不帐『戏适邪河工业区纬一路22号138.00万I虾J斜ι角江杨南路1381号4008-112233转6722#保常叮00万t奚蕉路198号4008-112233转5933#保常叮00万1本┦谐阳区北四环望京街68号4008-112233转8615#保玻福00万1本┦胁平区立汤路亚北博晟汽车汇展中心#保埃福86万=西省南昌市青山湖区科技大道599号136.00万I苄耸信劢工业区康宁路车管所对面#保常叮00万D暇┦薪宁区天元中路111号4008-112233转5501#保常叮00万3ご菏形餍戮济技术开发区长沈路4222号136.00万J家庄市北二环东路86号河北国际汽车贸易园区#矗埃埃福112233转3178#保矗福00万8壅⑶城港路99号广达车城永兴路3号136.00万I蜓羰刑西区北二中路11号4008-112233转2498#保常叮00万3啥际星嘌虼蟮溃保福负牛ㄐ挛幕宫对面)#保矗常80万A赡省沈阳市皇姑区鸭绿江街32号甲(长客总站北行1500米)#保矗福00万I钲谑新藓区罗芳立交六星汽车园进口大众4S店4008-112233转9866#保担埃00万3ご憾环城路10056号136.00万' content_words = [] for line in content_arr: current_segment = jieba.lcut(line) if len(current_segment) > 1 and current_segment !

opencv查看图像的任意像素位置、RGB值与HSV值等

在windows系统下,运行如下的python代码,可以直接查看图片的pixel值,BGR值,GRAY值,HSV值; # -*- coding:utf-8 -*- import cv2 img = cv2.imread('11_13/120002.jpg') gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) def mouse_click(event, x, y, flags, para): if event == cv2.EVENT_LBUTTONDOWN: # 左边鼠标点击 print('PIX:', x, y) print("BGR:", img[y, x]) print("GRAY:", gray[y, x]) print("HSV:", hsv[y, x]) if __name__ == '__main__': cv2.namedWindow("img") cv2.setMouseCallback("img", mouse_click) while True: cv2.imshow('img', img) if cv2.waitKey() == ord('q'): break cv2.destroyAllWindows() 附一张opencv下HSV范围图片:

派生类与基类 指针指向

https://juejin.im/post/6844904054930292749 派生类和基类的关系并不是两个独立的类型,在派生关系中, 派生类型“是一个”基类类型(Derived class is a base class)。在C++语法里规定:基类指针可以指向一个派生类对象, 但派生类指针不能指向基类对象。 用问题里的例子来说 DerivedClass is a BaseClass 派生类型之间的数据结构类似于这样: BaseClass : [Base Data] DerivedClass : [Base Data][Derived Data] 派生类型的数据附加在其父类之后,这意味着当使用一个父类型指针指向其派生类的时候,父类访问到的数据是派生类当中由父类继承下来的这部分数据 对比起见,我们再定义一个派生类的派生类 class DerivedDerivedClass : public DerivedClass 它的数据结构如下: DerivedDerivedClass : [Base Data][Derived Data][DerivedDerived Data] 而通过基类指针 BaseClass *pbase 访问每一个类型的数据部分为: [Base Data] [Base Data][Derived Data] [Base Data][Derived Data][DerivedDerived Data] 通过派生类指针 DerivedClass *pderived 访问每一个类型的数据部分为: [Base Data] 不能访问,派生类型指针不能指向基类对象(因为数据内容不够大,通过派生类指针访问基类对象会导致越界) [Base Data][Derived Data] [Base Data][Derived Data][DerivedDerived Data] 函数重载、函数隐藏、函数覆盖 函数重载只会发生在同作用域中(或同一个类中),函数名称相同,但参数类型或参数个数不同。 函数重载不能通过函数的返回类型来区分,因为在函数返回之前我们并不知道函数的返回类型。 函数隐藏和函数覆盖只会发生在基类和派生类之间。

目标检测的图像特征提取之(二)LBP特征

原文:https://blog.csdn.net/zouxy09/article/details/7929531(侵删) 目标检测的图像特征提取之(二)LBP特征 zouxy09@qq.com http://blog.csdn.net/zouxy09 LBP(Local Binary Pattern,局部二值模式)是一种用来描述图像局部纹理特征的算子;它具有旋转不变性和灰度不变性等显著的优点。它是首先由T. Ojala, M.Pietikäinen, 和 D. Harwood 在1994年提出,用于纹理特征提取。而且,提取的特征是图像的局部的纹理特征; 1、LBP特征的描述 原始的LBP算子定义为在3*3的窗口内,以窗口中心像素为阈值,将相邻的8个像素的灰度值与其进行比较,若周围像素值大于中心像素值,则该像素点的位置被标记为1,否则为0。这样,3*3邻域内的8个点经比较可产生8位二进制数(通常转换为十进制数即LBP码,共256种),即得到该窗口中心像素点的LBP值,并用这个值来反映该区域的纹理信息。如下图所示: LBP的改进版本: 原始的LBP提出后,研究人员不断对其提出了各种改进和优化。 (1)圆形LBP算子: 基本的 LBP算子的最大缺陷在于它只覆盖了一个固定半径范围内的小区域,这显然不能满足不同尺寸和频率纹理的需要。为了适应不同尺度的纹理特征,并达到灰度和旋转不变性的要求,Ojala等对 LBP 算子进行了改进,将 3×3邻域扩展到任意邻域,并用圆形邻域代替了正方形邻域,改进后的 LBP 算子允许在半径为 R 的圆形邻域内有任意多个像素点。从而得到了诸如半径为R的圆形区域内含有P个采样点的LBP算子; (2)LBP旋转不变模式 从 LBP 的定义可以看出,LBP 算子是灰度不变的,但却不是旋转不变的。图像的旋转就会得到不同的 LBP值。 Maenpaa等人又将 LBP算子进行了扩展,提出了具有旋转不变性的 LBP 算子,即不断旋转圆形邻域得到一系列初始定义的 LBP值,取其最小值作为该邻域的 LBP 值。 图 2.5 给出了求取旋转不变的 LBP 的过程示意图,图中算子下方的数字表示该算子对应的 LBP值,图中所示的 8 种 LBP模式,经过旋转不变的处理,最终得到的具有旋转不变性的 LBP值为 15。也就是说,图中的 8种 LBP 模式对应的旋转不变的 LBP模式都是 00001111。 (3)LBP等价模式 一个LBP算子可以产生不同的二进制模式,对于半径为R的圆形区域内含有P个采样点的LBP算子将会产生P2种模式。很显然,随着邻域集内采样点数的增加,二进制模式的种类是急剧增加的。例如:5×5邻域内20个采样点,有220=1,048,576种二进制模式。如此多的二值模式无论对于纹理的提取还是对于纹理的识别、分类及信息的存取都是不利的。同时,过多的模式种类对于纹理的表达是不利的。例如,将LBP算子用于纹理分类或人脸识别时,常采用LBP模式的统计直方图来表达图像的信息,而较多的模式种类将使得数据量过大,且直方图过于稀疏。因此,需要对原始的LBP模式进行降维,使得数据量减少的情况下能最好的代表图像的信息。 为了解决二进制模式过多的问题,提高统计性,Ojala提出了采用一种“等价模式”(Uniform Pattern)来对LBP算子的模式种类进行降维。Ojala等认为,在实际图像中,绝大多数LBP模式最多只包含两次从1到0或从0到1的跳变。因此,Ojala将“等价模式”定义为:当某个LBP所对应的循环二进制数从0到1或从1到0最多有两次跳变时,该LBP所对应的二进制就称为一个等价模式类。如00000000(0次跳变),00000111(只含一次从0到1的跳变),10001111(先由1跳到0,再由0跳到1,共两次跳变)都是等价模式类。除等价模式类以外的模式都归为另一类,称为混合模式类,例如10010111(共四次跳变)(这是我的个人理解,不知道对不对)。 通过这样的改进,二进制模式的种类大大减少,而不会丢失任何信息。模式数量由原来的2P种减少为 P ( P-1)+2种,其中P表示邻域集内的采样点数。对于3×3邻域内8个采样点来说,二进制模式由原始的256种减少为58种,这使得特征向量的维数更少,并且可以减少高频噪声带来的影响。 2、LBP特征用于检测的原理 显而易见的是,上述提取的LBP算子在每个像素点都可以得到一个LBP“编码”,那么,对一幅图像(记录的是每个像素点的灰度值)提取其原始的LBP算子之后,得到的原始LBP特征依然是“一幅图片”(记录的是每个像素点的LBP值)。 LBP的应用中,如纹理分类、人脸分析等,一般都不将LBP图谱作为特征向量用于分类识别,而是采用LBP特征谱的统计直方图作为特征向量用于分类识别。 因为,从上面的分析我们可以看出,这个“特征”跟位置信息是紧密相关的。直接对两幅图片提取这种“特征”,并进行判别分析的话,会因为“位置没有对准”而产生很大的误差。后来,研究人员发现,可以将一幅图片划分为若干的子区域,对每个子区域内的每个像素点都提取LBP特征,然后,在每个子区域内建立LBP特征的统计直方图。如此一来,每个子区域,就可以用一个统计直方图来进行描述;整个图片就由若干个统计直方图组成; 例如:一幅100*100像素大小的图片,划分为10*10=100个子区域(可以通过多种方式来划分区域),每个子区域的大小为10*10像素;在每个子区域内的每个像素点,提取其LBP特征,然后,建立统计直方图;这样,这幅图片就有10*10个子区域,也就有了10*10个统计直方图,利用这10*10个统计直方图,就可以描述这幅图片了。之后,我们利用各种相似性度量函数,就可以判断两幅图像之间的相似性了;

一项一项教你测等保2.0——Windows入侵防范

一项一项教你测等保2.0——Windows入侵防范 原创 科技兴 2020-09-23 18:32:55 一、前言 随着社会的进步和科技的发展,新技术、新业务下的产品与服务不断创新与升级,云服务、大数据、物联网、移动互联及工业控制等新技术广泛应用,使用多年的等保1.0相关系列标准在适用性、时效性、易用性、可操作性上已经无法满足新时代的要求,并且以“勒索病毒”为代表的新型攻击席卷全球,使传统安全防护手段已经难以有效保护网络空间安全,网络安全保护体系需要全面升级,以便配合《网络安全法》的实施,下面结合我多年的等保测评经验,为大家解读等保测评2.0的相关内容。 二、 测评项 a)应遵循最小安装的原则,仅安装需要的组件和应用程序; b)应关闭不需要的系统服务、默认共享和高危端口; c)应通过设定终端接入方式或网络地址范围对通过网络进行管理的管理终端进行限制; d)应提供数据有效性检验功能,保证通过人机接口输入或通过通信接口输入的内容符合系统设定要求; e)应能发现可能存在的已知漏洞,并在经过充分测试评估后,及时修补漏洞; f)应能够检测到对重要节点进行入侵的行为,并在发生严重入侵事件时提供报警。 三、测评项a a)应遵循最小安装的原则,仅安装需要的组件和应用程序; 这一项比较简单,但是也是最容易扣分的一项,最小安装原则因人而异,要具体情况具体分析,哪些是安装服务器所必需的的组件和应用程序,哪些组件和应用程序应该删除或者停用,需要通过访谈了解服务器的主要用途和业务需求再做判断。 我们可以在控制面板-程序-程序和功能中查看服务器或计算机已经安装的程序和功能,如下图所示: 程序和功能 在测评的过程中,我们很少见到把工作和生活分得非常清楚的情况,这最直接的反应就是服务器或者计算机中安装了一些与生活相关的应用程序,比如微信、QQ、迅雷等,这些软件比较常见,如果是一些不常见或者不清楚用途的软件,需要通过访谈来进行确认。 四、测评项b b)应关闭不需要的系统服务、默认共享和高危端口; 这一项的主要目的是为了限制外部对服务器或者计算机的访问进行限制,来达到最小化的管理,开启的服务、共享和端口越多对外部的访问就越难控制。 这一项与上一项紧密相连,如果上一项没有遵循最小安装原则,那么这一项也不会通过的,因为程序是和服务、进程以及端口是相关的,运行某个程序,就需要开启某项服务,开启某项服务就会运行某项进程,运行某项进程就会监听某项端口,所以如果安装了某款不必要的应用程序,不可避免的就会开启各项服务和端口,我们可以在任务管理器中直观的查看他们的关系。 程序-进程-服务 4.1. 不需要的系统服务 系统服务我们可以在控制面板-系统和安全-管理工具-服务中查看,如下图所示: 服务 一般来说Telnet服务如果开启,它会允许远程终端访问服务器,对服务器进行管理和控制,当然需要输入用户名和密码,如果没有远程控制需求最好不要开启此项功能,另外IIS服务是网站服务器和应用服务器所必需的,如果服务器没有承担这两项任务,那么开启IIS服务也是不必要的,其他的要视情况而定。 4.2. 默认共享 至于默认共享,我们可以先看看共享服务是否开启了,如下图所示开启了共享服务: 共享服务 然后我们可以在命令提示符里输入命令:net share,查看开启的共享到底有哪些,如下图所示: 开启的共享 对于windows系统而言,默认是会开启共享的,一个磁盘一个共享,c盘多一个ADMIN$共享,然后都会有一个IPC$共享,这里我自己开的就只有Users共享了。 默认共享和一般共享的区别在于,它的共享名后面会有一个$,这代表它是一个隐藏共享,也就是说在计算机的网络中是看不到的,但是,仅仅是隐藏而已,可以在文件夹地址栏中输入地址进行正常的共享访问(期间要输入用户名、口令)。 对于默认共享,有几种关闭的方式: 直接关闭Server服务,这个是将共享服务全部关闭了,要注意是否会影响到实际业务需要的共享。 使用net share 共享名 /delete命令删除共享,比如net share ipc$ /delete。这里说删除ipc$共享,不会对其它的共享造成影响。另外这只是暂时的删除,服务器重启后又会关闭。 4.3. 高危端口或多余端口 其实端口如果不做终端ip限制,那么基本都存在漏洞,至于监听了多余的端口,那就更危险了。 那么这里说一下常见的多余端口(就是那种windows默认给你开启的端口): 80端口,对于windows而言,大概率是开启了IIS服务,如果本身没有这个业务,即为多余端口; 135端口,是微软RPC远程过程调用使用的端口号,没有涉及到远程过程调用的,即为多余端口。WebService是RPC的一种实现,这里是一个公用的WebService接口,看了之后就知道大概是干嘛的了:http://www.webxml.com.cn/WebServices/WeatherWebService.asmx; 137、138、139端口(TCP、UDP),是NetBIOS名称服务(NetBIOS Name Service)使用的端口号,用于局域网中提供计算机的名字或IP地址查询服务以及文件共享服务。换句话说,共享服务可能使用这三个端口,如果没有业务上不需要共享服务,那么肯定是多余端口; 445端口,共享服务可能使用的端口,如果没有业务上不需要共享服务,那么肯定是多余端口; 47001端口,Windows Remote Management服务用到的端口,只能说一般用不到,大概率是多余端口。 常见的高危端口: 一些流行病毒的后门端口(如 TCP 2745、3127、6129 端口),还有593端口,是针对DCOM(Distributed Component Object Model,分布式组件对象模型)协议的。它允许C/S结构的应用通过DCOM使用RPC over HTTP service。

Intellij idea 实战中top5快捷键(Mac)

受文章https://blog.jetbrains.com/idea/2020/09/top-5-navigation-keyboard-shortcuts-in-intellij-idea-shortcuts/的启发:,我也写了一篇我自己再开发中经常使用的快捷键。 1:打开文件:⌘⇧O 2:展示文件结构 ⌘= 快捷键使用的展示效果: 3:跳到实现类:⌥⌘B 4: 查询方法的使用⌥F7 由于现在mac F功能建默认需要按住Fn才能出来,所以这个功能建也可以用⌘B 功能键代替, 如果想将touch bar默认显示成功能键。可以在系统偏好设置–>键盘–>触控栏显示里定义。 5: 切换git分支 Ctrl +B

力扣#43 字符串相乘(C++)

题目如下:官网oj 题目意思就是让我们自己去模拟乘法,因为两个相乘的数字很大,long long类型都存储不下,只能拿字符串模拟乘法的过程得到答案。 算法简述:首先考虑特殊情况,当num1或者num2为0的时候,返回0。考虑特殊情况之后把num1和num2反转过来,令num1[0]即num1的低位的位权最低,num1[num1.length()-1]即num1的高位的位权最高,这样方便我们计算求解。我们在做乘法的时候,比如1234 * 567的时候,将567的每一位与1234相乘之后,再错位相加得到答案。如下图 1234 * 567 : 利用上述思想,可以编写两层for循环来模拟,接下来要考虑进位问题,当相乘的结果大于10就会产生进位,进到下一位,定义一个int变量carry来存放上述进位信息,容易得到这样的代码: int tmp = (num1[i] - '0') * (num2[j] - '0') + carry+ans[i+j]-'0'; carry = tmp / 10; ans[i + j] = tmp % 10+'0'; 在固定一次b与a进行一次乘法之后,还可能产生进位,此时已经跳出了b的循环,这时候的进位应进到相应的位上,而不能丢弃,如下: if (carry) { ans[i + num2.length()] += carry; carry = 0; } 所有的计算结束之后,我们还需要把答案reverse一下,因为我们一开始把num1和num2都reverse了,还记得嘛。要reverse,就需要传入开头和结尾的迭代器,这时候就需要计算得到的答案的长度,具体代码见如下代码: class Solution { public: string multiply(string num1, string num2) { //考虑特殊情况 if(num1=="0"||num2=="0") return string("0"); //ans长度230肯定够了 string ans(230, '0'); //反转数字 reverse(num1.begin(), num1.

1001 害死人不偿命的(3n+1)猜想 PAT乙级真题 C++

1001 害死人不偿命的(3n+1)猜想 卡拉兹(Callatz)猜想: 对任何一个正整数 n,如果它是偶数,那么把它砍掉一半;如果它是奇数,那么把 (3n+1) 砍掉一半。这样一直反复砍下去,最后一定在某一步得到 n=1。卡拉兹在 1950 年的世界数学家大会上公布了这个猜想,传说当时耶鲁大学师生齐动员,拼命想证明这个貌似很傻很天真的命题,结果闹得学生们无心学业,一心只证 (3n+1),以至于有人说这是一个阴谋,卡拉兹是在蓄意延缓美国数学界教学与科研的进展…… 我们今天的题目不是证明卡拉兹猜想,而是对给定的任一不超过 1000 的正整数 n,简单地数一下,需要多少步(砍几下)才能得到 n=1? 输入格式: 每个测试输入包含 1 个测试用例,即给出正整数 n 的值。 输出格式: 输出从 n 计算到 1 需要的步数。 输入样例: 3 输出样例: 5 解题思路 分情况讨论,添加一个计数常量即可。 代码如下: #include<iostream> #include<string> using namespace std; int main() { int a[10] = { 0 }; int n; cin >> n; int count = 0; while (n != 1) { if (n % 2 == 0) { n /= 2; count++; } else if (n % 2 == 1) { n = (3 * n + 1)/2; count++; } } cout << count << endl; }

三款优秀的替代Xshell的SSH软件

在之前的文章介绍个, 由于公司禁止使用xshell, 让我很是难受了一阵, 因为一直无法找到好的工具来替代xshell, 前面文章中提到的那些对我来时功能还是太单一了, 界面也不够友好, 但是经过我不懈的努力和大家的提点, 最终我还是发现了这三款同样优秀的终端工具来替代xshell. 这三款软件就是: terminus, electerm和windterm. 他们各有千秋, 同样优秀, 下面就我的使用体验简单介绍一下. 1. terminus 这里要注意, 是terminus而不是termius, 当然termius也是一款类似的工具, 但是它只有ssh, 并没有集成终端工具, 没法使用telnet和串口, 因为我没深入用过这里就不多说它了, 还是主要说一说terminus吧. terminus是github上的一款开源软件, 它的介绍是 Terminus is a highly configurable terminal emulator for Windows, macOS and Linux 它集成有ssh client, 支持PowerShell (and PS Core), WSL, Git-Bash, Cygwin, Cmder and CMD, 而且支持日志保存到文件, 功能可以说是很全面了, 但是目前还不支持sftp(termius支持sftp, 但没有集成cmd这些), 这也是我平时会用到的功能, 所以说还是有些欠缺的. 如果把上面这些作为我选择类似工具的基本条件的话, 那terminux漂亮的界面就是它的加分项, 咱也不知道它和前面提到的termius是什么关系, 但是他们的界面风格倒是很相像, 磨砂界面, 丰富的主题配色, 都能够让颜值至上的同学对它爱不释手. 总结: 功能比较全面, 界面非常美观. 启动速度相对较慢, 不支持sftp. 图片.png 2.

Track R-CNN代码 使用作者的运行环境顺利运行

create requirements_conda.txt _libgcc_mutex=0.1=main _tflow_select=2.1.0=gpu absl-py=0.8.0=py36_0 astor=0.8.0=py36_0 blas=1.0=openblas c-ares=1.15.0=h7b6447c_1001 ca-certificates=2019.10.16=0 certifi=2019.9.11=py36_0 cloudpickle=1.2.2=py_0 cudatoolkit=10.0.130=0 cudnn=7.6.0=cuda10.0_0 cupti=10.0.130=0 cycler=0.10.0=py36_0 cython=0.29.13=py36he6710b0_0 cytoolz=0.10.0=py36h7b6447c_0 dask-core=2.6.0=py_0 dbus=1.13.6=h746ee38_0 decorator=4.4.0=py36_1 expat=2.2.6=he6710b0_0 fontconfig=2.13.0=h9420a91_0 freetype=2.9.1=h8a8886c_1 gast=0.3.2=py_0 glib=2.56.2=hd408876_0 grpcio=1.16.1=py36hf8bcb03_1 gst-plugins-base=1.14.0=hbbd80ab_1 gstreamer=1.14.0=hb453b48_1 h5py=2.9.0=py36h7918eee_0 hdf5=1.10.4=hb1b8bf9_0 icu=58.2=h9c2bf20_1 imageio=2.6.1=py36_0 intel-openmp=2019.4=243 joblib=0.13.2=py36_0 jpeg=9b=h024ee3a_2 keras-applications=1.0.8=py_0 keras-preprocessing=1.1.0=py_1 kiwisolver=1.1.0=py36he6710b0_0 libedit=3.1.20181209=hc058e9b_0 libffi=3.2.1=hd88cf55_4 libgcc-ng=9.1.0=hdf63c60_0 libgfortran-ng=7.3.0=hdf63c60_0 libopenblas=0.2.20=h9ac9557_7 libpng=1.6.37=hbc83047_0 libprotobuf=3.9.2=hd408876_0 libstdcxx-ng=9.1.0=hdf63c60_0 libtiff=4.0.10=h2733197_2 libuuid=1.0.3=h1bed415_2 libxcb=1.13=h1bed415_1 libxml2=2.9.9=hea5a465_1 markdown=3.1.1=py36_0 matplotlib=3.1.1=py36h5429711_0 mkl=2019.4=243 mkl-service=2.3.0=py36he904b0f_0 mock=3.0.5=py36_0 ncurses=6.1=he6710b0_1 networkx=2.4=py_0 numpy=1.14.2=py36_nomklh2b20989_1 olefile=0.46=py36_0 openssl=1.1.1d=h7b6447c_3 pcre=8.43=he6710b0_0 pillow=6.2.0=py36h34e0f95_0 pip=19.3.1=py36_0 protobuf=3.9.2=py36he6710b0_0 pyparsing=2.4.2=py_0 pyqt=5.9.2=py36h05f1152_2 python=3.6.9=h265db76_0 python-dateutil=2.8.0=py36_0 pytz=2019.3=py_0 pywavelets=1.

[C计划—03] 数组指针 与 指针数组

数组指针 与 指针数组 只看题目可能大家觉得有一点拗口,但是其实只要理解一点:指针也是一个变量,他存放的时所指向的目标的地址。这样其实就会明朗许多。下面结合一个例子来进行说明。 指针数组 //指针数组 char* p[2] = { "一切皆有可能","To be No.1" }; for (int i = 0; i < 2; i++) { printf("%d: %s\n",i,p[i]);// %s 只要传入字符串的地址即可 } 根据C语言运算优先等级表,指针也是一个变量,这里的 char* p[2] 指的是定义了一个一维数组,数组里存放的是指针变量,而指针指向的则是后面字符串的首个字符的地址。后面printf()中,打印字符串只需要给出首个字符地地址即可。 一维数组的指针 int temp1[2] = { 1,2 }; int* sp1 = temp1;//一维数组指针,这个指针,其实指向的是一个变量,指针的值是这个变量的地址 for (int i = 0; i < 2; i++) { printf("%d: %d\n", i, *(sp1+i)); } 这里是只一维数组指针,这个指针,其实指向的是一个变量,指针的值是这个变量的地址。 指向一维数组的指针 int(*sp2)[2];//指向数组的指针,指针里存储的是这个数组的地址,所以对于一维数组,应该 &temp sp2 = &temp1; for (int i = 0; i < 2; i++) { printf("

vue3.0-router的使用

请安装vue最新版本 cnpm install vue-router@4.0.0-beta.9 --save 结合setup使用 import { useRouter } from "vue-router"; export default{ name:"APP", setup(){ const { push } = useRouter(); push('/home') } } 注意: const {params} = userRouter() //这个返回undefined 暂时没有次api createWebHashHistory hash 路由 createWebHistory history 路由 createMemoryHistory 带缓存 history 路由 parseQuery 查询参数反序列化 stringifyQuery 查询参数序列化 onBeforeRouteLeave 路由离开钩子 to 目标路由信息from 当前路由信息next 跳转函数useRoute 返回当前路由, 子属性都被ref包装

Mybatis-plus简单的入门

前言: mybatis在持久层框架中还是比较火的,一般项目都是基于ssm。虽然mybatis可以直接在xml中通过SQL语句操作数据库,很是灵活。但正其操作都要通过SQL语句进行,就必须写大量的xml文件,很是麻烦。mybatis-plus就很好的解决了这个问题。 一、mybatis-plus简介: Mybatis-Plus(简称MP)是一个 Mybatis 的增强工具,在 Mybatis 的基础上只做增强不做改变,为简化开发、提高效率而生。这是官方给的定义,关于mybatis-plus的更多介绍及特性,可以参考mybatis-plus官网。那么它是怎么增强的呢?其实就是它已经封装好了一些crud方法,我们不需要再写xml了,直接调用这些方法就行,就类似于JPA。 二、spring整合mybatis-plus: 正如官方所说,mybatis-plus在mybatis的基础上只做增强不做改变,因此其与spring的整合亦非常简单。只需把mybatis的依赖换成mybatis-plus的依赖,再把sqlSessionFactory换成mybatis-plus的即可。接下来看具体操作: 1、pom.xml: 核心依赖如下: <!-- spring --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.3.14.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>4.3.14.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>4.3.14.RELEASE</version> <scope>test</scope> </dependency> <!-- mp 依赖 --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus</artifactId> <version>2.3</version> </dependency> 注意:这些是核心依赖,本项目还用到了mysql驱动、c3p0、日志(slf4j-api,slf4j-log4j2)、lombok。集成mybatis-plus要把mybatis、mybatis-spring去掉,避免冲突;lombok是一个工具,添加了这个依赖,开发工具再安装Lombok插件,就可以使用它了,最常用的用法就是在实体类中使用它的@Data注解,这样实体类就不用写set、get、toString等方法了。关于Lombok的更多用法,请自行百度。 2、log4j.xml: <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"> <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender"> <param name="Encoding" value="UTF-8" /> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%-5p %d{MM-dd HH:mm:ss,SSS} %m (%F:%L) \n" /> </layout> </appender> <logger name="