搭建Janus的HTTPS环境

1、前言 基于安全隐私问题,现在Webkit内核的浏览器共享视频、语音、经纬度坐标等必须通过HTTPS形式访问! Chrome浏览器使用的是Webkit内核,所以很不幸,如果你要在最新的Chrome浏览器上通过HTTP形式分享本地的视频、语音,就会出现如《Chrome浏览器调用摄像头失败》 中所述的问题。 那么,如何解决呢?答案很简单,就是将应用的HTTP服务方式改造成HTTPS方式,本文将就Janus的Demos范例的HTTPS改造进行说明。 2、改造过程 2.1 安装Janus 若还没有部署Janus环境,可以参考《Ubuntu中安装部署Janus》 一文进行部署。 2.2 修改Janus配置 1、修改Janus的配置文件janus.jcfg,命令如下 root@webrtc:~# vi /opt/janus/etc/janus/janus.jcfg 确认Janus所使用的DTLS证书配置,如下图所示 2、修改Janus的配置文件janus.janus.transport.http.jcfg,命令如下 root@webrtc:~# vi /opt/janus/etc/janus/janus.janus.transport.http.jcfg 修改或增加的内容,如下图所示 2.3 安装Nginx Ubuntu下安装很简单,使用下面命令: sudo apt-get install nginx -y 安装完成后,可以通过下面命令查看 sudo netstat -ntlp | grep nginx 执行结果如下,可以看到nginx已经运行起来 root@webrtc:~# sudo netstat -ntlp | grep nginx tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 1471/nginx: master tcp6 0 0 :::80 :::* LISTEN 1471/nginx: master 可以通过浏览器访问,如 http://172.16.0.17 就可以看到Nginx的首页,如下图所示 2.4 修改Nginx配置 修改Nginx的默认配置文件,命令如下 root@webrtc:~# vi /etc/nginx/conf.

正负样本不均衡

样本不均衡 类别不均衡是指在分类学习算法中,不同类别样本的比例相差悬殊,它会对算法的学习过程造成重大的干扰。比如在一个二分类的问题上,有1000个样本,其中5个正样本,995个负样本,在这种情况下,算法只需将所有的样本预测为负样本,那么它的精度也可以达到99.5%,虽然结果的精度很高,但它依然没有价值,因为这样的学习算法不能预测出正样本。这里我们可以知道不均衡问题会导致样本较少那一类的高错分率,即较少一类的样本会有较大的比例会被预测成样本数量较多的那一类。 随机森林更适用于样本不均衡问题 降采样( 优 先 选 择 \color{red}{优先选择} 优先选择) 原来990个正样本,10个负样本。抽取50个正样本,10个负样本使样本比例在一个数量级。 重采样 990个样本不变,10个样本 重复采样50次。获得990个正样本,500个负样本。 10 个 负 样 本 , 可 能 会 有 异 常 值 。 1 个 负 样 本 异 常 值 , 采 集 50 次 , 就 有 50 个 异 常 值 。 故 降 采 样 质 量 好 。 \color{red}{10个负样本,可能会有异常值。1个负样本异常值,采集50次,就有50个异常值。故降采样质量好。} 10个负样本,可能会有异常值。1个负样本异常值,采集50次,就有50个异常值。故降采样质量好。 降采样50个正样本,10个负样本,共60个样本。 重采样990个正样本,500个负样本。共1400多个样本 故降采样 效 率 高 \color{red}{效率高} 效率高。 基于聚类的A类分割 对于990个正样本做cluster聚类处理。之后对于每个类,抽取一定比例正样本。可提高训练程度。

通过document方法来获取标签对象

<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>通过document方法来获取标签对象</title> <script> /** * 通过document方法来获取标签对象 * 1)getElementByld("id属性值"); 返回的是某个标签对象//id一定要唯一 * 2)getElementsByName("name属性值"); 返回的标签对象集合 * 3)getElementsByTagName("标签名称"); //通过标签名称获取标签对象 */ function init(){ //获取标签对象 var username = document.getElementById("user_name").value; //通过name属性来获取标签对象 //var username = document.getElementsByName("username")[0].value; //var username = document.getElementsByTagName("input")[0].value; var username = document.getElementsByClassName("haha")[0].value; alert(username); } </script> </head> <body onload="init()"> 用户名:<input type="text"class="haha"name="username"onblur="init()"id="user_name" /> </body> </html>

python中的__new__方法与单例模式

本文将简单地介绍__new__方法的使用,然后引出单例模式。 __new__方法就是初始化实例对象的,假如和__init__一起存在的话,会先执行___new__方法, 简单地看个例子: class A: def __init__(self, name): self.name = name def __new__(cls, *args, **kw): print('bbb') return object.__new__(cls) a = A('张三') print(a.name) # 结果 # bbb # 张三 什么时候使用__new__方法呢?参考链接 单例模式 什么是单例模式:对象只会被实例化一次,从第二次开始其实就是用的第一次实例化的对象,相当于全局。可根据地址判断看一下 class A: def __init__(self, name): self.name = name # 实例化三个对象 a = A('张三') b = A('李四') c = A('王五') # 打印结果地址是不同的,既实例化了三个对象 print(a) # <__main__.A object at 0x029CE5B0> print(b) # <__main__.A object at 0x00A009B0> print(c) # <__main__.A object at 0x00A00C10> # 将 a 的名字改成阿黄,查看一下 b 和 c 的名字 a.

解决Access denied for user 'root'@'localhost'(using password:YES)问题

原文链接:https://blog.csdn.net/weixin_41092717/article/details/83344420 在Eclipse中开发Web项目时,使用heidisql连接MYSQL数据库,出现问题:Access denied for user 'root'@'localhost'(using password:YES)。 解决方案: 1、打开MySQL目录下的my.ini文件,在文件的最后添加一行“skip-grant-tables”,保存并关闭文件。(WIN7默认安装) 2、重启MySQL服务。 3、通过命令行进入MySQL的BIN目录,输入“mysql -u root -p”(不输入密码),回车即可进入数据库。 4、执行“use mysql;”,使用mysql数据库。 5、执行“update user set password=PASSWORD("123456") where user='root';”(修改root的密码) 6、重启MySQL服务。 7、再次使用heidisql连接MYSQL数据库

Dubbo的容错机制原理

本文是基于 apache dubbo 2.7.0 版本的源码和参考官网的集群章节而成。 为了避免单点故障,现在的应用通常至少会部署在两台服务器上。对于一些负载比较高的服务,会部署更多的服务器。这样,在同一环境下的服务提供者数量会大于1。对于服务消费者来说,同一环境下出现了多个服务提供者。这时会出现一个问题,服务消费者需要决定选择哪个服务提供者进行调用。另外服务调用失败时的处理措施也是需要考虑的,是重试呢,还是抛出异常,亦或是只打印异常等。为了处理这些问题,Dubbo 定义了集群接口 Cluster 以及 Cluster Invoker。集群 Cluster 用途是将多个服务提供者合并为一个 Cluster Invoker,并将这个 Invoker 暴露给服务消费者。这样一来,服务消费者只需通过这个 Invoker 进行远程调用即可,至于具体调用哪个服务提供者,以及调用失败后如何处理等问题,现在都交给集群模块去处理。集群模块是服务提供者和服务消费者的中间层,为服务消费者屏蔽了服务提供者的情况,这样服务消费者就可以专心处理远程调用相关事宜。比如发请求,接受服务提供者返回的数据等。这就是集群的作用。 一 选择集群容错方式 集群容错机制是交由 org.apache.dubbo.rpc.cluster.Cluster 接口的子类处理,为了清楚该接口有哪些扩展类,不妨打开该类的 Dubbo SPI 配置文件(扩展点的全限定名)一观: mock=org.apache.dubbo.rpc.cluster.support.wrapper.MockClusterWrapper failover=org.apache.dubbo.rpc.cluster.support.FailoverCluster failfast=org.apache.dubbo.rpc.cluster.support.FailfastCluster failsafe=org.apache.dubbo.rpc.cluster.support.FailsafeCluster failback=org.apache.dubbo.rpc.cluster.support.FailbackCluster forking=org.apache.dubbo.rpc.cluster.support.ForkingCluster available=org.apache.dubbo.rpc.cluster.support.AvailableCluster mergeable=org.apache.dubbo.rpc.cluster.support.MergeableCluster broadcast=org.apache.dubbo.rpc.cluster.support.BroadcastCluster registryaware=org.apache.dubbo.rpc.cluster.support.RegistryAwareCluster 理论上来说,Dubbo 的集群容错机制就有以上 10 种,且还可从 Cluster 接口上的 @SPI 可知,其默认的扩展类为 FailoverCluster。 @SPI(FailoverCluster.NAME) public interface Cluster { @Adaptive <T> Invoker<T> join(Directory<T> directory) throws RpcException; } 那么在真正调用时,可通过设置 <dubbo:service> 标签中 cluster 属性,其值分别对应Cluster 扩展点配置文件中的 key,以匹配对应的容错机制。 二 前置动作 集群容错真正发生在消费端。当消费端发起调用时,会先从服务目录查询满足需求的服务提供者信息,在此基础上进行路由,路由后的结果才会真正进行容错处理。所以,就会有如下的活动图:

干货|计算机专业大学生毕业后找工作应该考哪些证书

大学生计算机专业毕业后,找工作前如果考取了某项证书,一般会被优秀的大公司看中,很容易从众多的毕业生中脱颖而出,因为刚毕业的大学生如果没有工作经验,那么他的优势就是考取的证书与所在学校是否是名牌。学校是无法改变了,能改变的就是证书了。而现在的证书五花八门,只有适合自己的才是最好的。 下面我给大家介绍正规的四大类证书: 步骤阅读 第一类证书 大学校园里最常见的计算机证书——全国计算机等级考试,英文是National Computer Rank Examination,简称NCRE。这个证书简单的说,是非计算机专业学生必考的证书。这款证书共分为四个等级:一级、二级、三级、四级。一般的大学生考到二级、三级就差不多了。其中的最高级——四级相当于全国软考的初级水平。总之,如果是针对计算机专业的学生来讲,此证书含金量不高。 步骤阅读 第二类证书 计算机软件水平考试(软考),平时行业直接叫软考。这个证书是国内针对计算机专业的最高水平考试,专业水平比上述讲的第一类水准要高出许多。它的等级:初级、中级、高级。考试方向有很多:软件、网络、应用技术、信息系统与信息服务。一般情况都是走的第一类方向。下面稍微介绍一下第一类方向。 步骤阅读 步骤阅读 程序员,初级证书。此证书,对大学生在校编程能力与算法有一定的要求,考试的最后一个大题基本上每年都是一道编程题,所以虽然是初级,但并不容易。本人当年考取程序员(满分100分),考了96分,估计是错了两道选择题。 步骤阅读 软件设计师,中级证书。这个证书,几乎不考编程的题目,但是它的涉及范围很广,几乎囊括了大二、大三的大部分核心计算机课程,像数据机构、软件工程、编译原理等。基本上都是理论的东西,所以死记硬背的东西比较多。咬咬牙,还是可以过的。一般的大学生顶峰都是考到中级。考到中级了,的确说明学习用心了,是个好学生。 步骤阅读 系统分析师,高级证书。很少有大学生能够考过这门证书,因为这门证书对工作经验有一定要求,需要写计算机论文的。所以一般工作两三年的人士会去考这门证书。 步骤阅读 第三类证书 思科证书。思科证书是目前国内最吃香的证书,这个证书的认知度达到全球通用,也只能说思科这家公司太牛了。不过思科方向都是网络方向的,面向的是思科的网络设备。它的具体分类:CCNA、CCDA、CCNP、CCDP、CCSP、CCIP、CCVP、CCIE。分支比较多。常见考取等级:初级CCNA,中级CCNP,高级CCIE。 步骤阅读 初级CCNA。大学生如果考了这门证书,面试公司肯定会对你另眼相看的。考试费用不高,二千附近。考试地点国内。 步骤阅读 中级CCNP。考试费用四千左右。考试地点国内。 步骤阅读 高级CCIE。应该说最实用的证书。考取这个证书等于直接拿到了起步价10年薪的工作。笔试费用250美元,考点在国内。实验室考试费用1w多人民币,而且考点只有北京与香港。邻居家有个小孩,学校刚毕业就报了培训班,花费了五六万,考了两次,最后考到CCIE证书。在上海的第一份工作就月薪1W。可见此证书的威力啊! 步骤阅读 第四类证书 ORALCE证书。是甲骨文公司数据库方向的一个证书。含金量没有思科来的实用,但是如果考取的话,也是可以加分的。此类证书一般都必须要实地培训后才可以考取。所以适合有工作经验的人士。它分为三类:OCA证书、OCP证书、OCM证书。 步骤阅读 OCA英文全称Oracle Certified Associate,是入门级别的资格证书。 步骤阅读 OCP英文全称Oracle Certified Professionals,是专业证书。 步骤阅读 OCM英文全称Oracle Certified Master,是高级资格证书。 步骤阅读

豆瓣电影改版,翻页方式从页码变成加载更多,简易爬虫方式不灵了。求大神指教!

豆瓣电影好像刚刚改版了,原来最简单的爬虫方式现在也不灵了。附上原来在windows系统中的R爬虫代码,有大神指教一下怎么改嘛?感激不尽 这是现在的页面 library(dplyr) library(rvest) library(stringr) # 自定义函数 getMovList <- function(pgnum, intv_time=5){ # 采集单个电影链接的列表的函数 # pgnum是页面数量, intv_time是间隔时间 # 首先设置一个空向量 list_res <- as.character() for(i in 0:pgnum){ urlnum <- i*20 list_url <- str_c('https://movie.douban.com/explore#!type=movie&tag=%E5%8D%8E%E8%AF%AD&sort=time&page_limit=20&page_start=', urlnum, '&type=R') # 按照 css标签确定爬虫内容 list_p <- read_html(list_url) %>% html_nodes('div.list') %>% html_attr('href') %>% .[str_detect(., 'https://movie.douban.com/subject')] # 单个页面上的url列表添加到总列表中 list_res <- c(list_res, list_p) Sys.sleep(intv_time) cat('page', i, 'Done ') } list_res <- unique(list_res) return(list_res) } getMovData <- function(url){ # 根据单个电影url,采集具体信息 # 目前初步设定 标题、年份、信息、剧情、评分等字段,可进一步优化 prs <- read_html(url) title <- prs %>% html_nodes('h1 span') %>% html_text() %>% .

微信小程序 WXBizDataCrypt 解密 报错

在使用微信官方WXBizDataCrypt.js解密encryptedData获取敏感数据的时候,偶尔会报错。 DeprecationWarning: Buffer() is deprecated due to security and usability issues. Please use the Buffer.alloc(),Buffer.allocUnsafe(), or Buffer.from() methods instead. message: Illegal Buffer, stack: Error: Illegal Buffer at WXBizDataCrypt.decryptData 这种错误一定概率出现,一般出现在项目初始化的时候。 我一开始还以为是Buffer库的问题,使用了safer-buffer替换,还是没有解决。 网上还有人说需要encodeURIComponent对参数包裹,这也不能解决。 其实,最后的解决办法,就是在小程序端通过open-type="getUserInfo"获取参数之前,必须要wx.login。 所以,重要的事情说三遍: wx.login wx.login wx.login必须先执行。

爬虫实战2(下):爬取豆瓣影评

上篇笔记我详细讲诉了如何模拟登陆豆瓣,这次我们将记录模拟登陆+爬取影评(复仇者联盟4)实战。本文行文结构如下: 模拟登陆豆瓣展示 分析网址和源码爬取数据 进行面对对象重构 总结 一、模拟登陆豆瓣 模拟登陆在上文已经详细介绍如何利用post方式登陆,这里不再赘述,直接给出源码如下: import requests # 1.设置URL 和 headers loginURL = "https://accounts.douban.com/j/mobile/login/basic" headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0" } # 2.分析表单 data = { "ck": "", "name": "你的账号", "password": "你的密码", "remember": "false", "ticket": "" } # 3.创建session对象保存对话 session = requests.Session() session.post(url=loginURL, headers=headers, data=data) # 4.开始登陆豆瓣 # (测试)比如获取登陆后我的主页信息 personalURL = "https://www.douban.com/people/195562116/" r = session.

idea 使用maven构建项目时,target bytecode version经常自动变化

idea 使用maven构建项目时,target bytecode version经常自动变化 解决方法:在工程的pom.xml中添加 <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build> 或者:添加properties节点 <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> <encoding>UTF-8</encoding> </properties> posted @ 2019-04-30 21:29 巡山小妖N 阅读(...) 评论(...) 编辑 收藏

前后端不分离之分页 url

//将对象转成url 参数 var urlEncode = function(param, key, encode) { if (param==null) return ''; var paramStr = ''; var t = typeof (param); if (t == 'string' || t == 'number' || t == 'boolean') { paramStr += '&' + key + '=' + ((encode==null||encode) ? encodeURIComponent(param) : param); } else { for (var i in param) { var k = key == null ? i : key + (param instanceof Array ?

Python实现中文文档的简体与繁体互相转换

本文重点是一个第三方工具的使用,首先从下面的地址下载这两个文件并存放于程序文件所在文件夹。 https://raw.githubusercontent.com/skydark/nstools/master/zhtools/langconv.py https://raw.githubusercontent.com/skydark/nstools/master/zhtools/zh_wiki.py 然后编写下面的代码: 结合扩展库python-docx,下面的代码用来对Word文档中的中文进行转换,简体变繁体: 书稿转换前: 书稿转换后: 温馨提示 关注本公众号“Python小屋”,通过菜单“最新资源”==>“历史文章”可以快速查看分专题的800篇技术文章列表(可根据关键字在页面上搜索感兴趣的文章),通过“最新资源”==>“微课专区”可以免费观看300节Python微课,通过“最新资源”==>“培训动态”可以查看近期Python培训安排,通过“最新资源”==>“教学资源”可以查看Python教学资源。

移动端适配:动态设置html元素的font-size(页面使用rem做单位)

一、前言: 首先我们要了解的知识点: 1.物理像素(physical pixel) 我们看到的每个屏幕都是由一颗颗我们肉眼难以看到的小颗粒(物理像素)组成的。 2.逻辑像素(设备独立像素(density-independent pixel)) 是计算机坐标系统中的一个点,这个点代表一个可以由程序使用的虚拟像素(比如说CSS像素)。 3.设备的像素比(device pixel ratio)简称DPR 它的数值体现了物理像素和逻辑像素之间的关系,用公式可以计算出该设备的DPR的大小: DPR = 物理像素 / 逻辑像素 那么了解了上面这些概念,就可以知道,为什么css在pc上写着font-size=12px;但是换到手机上却变小了?因为手机端的DPR变大了。 没错,我们在电脑屏幕上的DPR是1,但是手机却不同,可能是它可能是2,也可能是3。 获取设备DPR的方法还是有的: 1.在JavaScript中,通过window.devicePixelRatio来获取 2.在css中,可以通过-webkit-device-pixel-ratio,-webkit-min-device-pixel-ratio和 -webkit-max-device-pixel-ratio进行媒体查询,对不同DPR的设备,做一些样式适配(这里只针对webkit内核的浏览器和webview)。 二、页面适配开发 1、设置页面的viewport视口 <meta name="viewport" content="width=device-width,user-scalable=no,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0" /> 2、我们以iPhone6设计稿来进行移动端的开发(设计稿是750px) 那么我们得到的deviceWidth = 375px; 为了方便在开发的时候量尺寸好算,我们设置html的font-size为50px。 那么本来根据设计稿量出来的div是80px的话我们要先除以2,得到实际的宽度px,然后要转换为rem,我们还要除以html的font-size,即再除以50,即可得到单位rem的数值。 也就是说:拿到一个iPhone6设计图,量到的px像素值来除以100,那么得到的值就是多少rem。 deviceWidth = 320,font-size = 320 / 7.5 = 42.6667px deviceWidth = 375,font-size = 375 / 7.5 = 50px deviceWidth = 414,font-size = 414 / 7.5 = 55.2px deviceWidth = 500,font-size = 500 / 7.

使用Python把BT种子转化为磁力链接

经常下载电影的朋友肯定对BT种子不陌生,但是BT种子文件相对磁力链来说存储不方便,而且在网站上存放BT文件容易引起版权纠纷,而磁力链相对来说则风险小一些。 将BT种子转换为占用空间更小,分享更方便的磁力链还是有挺大好处的。 今天咱们来看下如何将种子转换成磁力链接,方案是:利用python的bencode模块,用起来比较简单 首先要安装这个模块,安装命令: pip install bencode bt2url.py #! /usr/local/bin/python # @desc python通过BT种子生成磁力链接 # @date 2015/11/10 # @author pythontab.com import bencode import sys import hashlib import base64 import urllib #获取参数 torrentName = sys.argv[1] #读取种子文件 torrent = open(torrentName, 'rb').read() #计算meta数据 metadata = bencode.bdecode(torrent) hashcontents = bencode.bencode(metadata['info']) digest = hashlib.sha1(hashcontents).digest() b32hash = base64.b32encode(digest) #打印 print 'magnet:?xt=urn:btih:%s' % b32hash python bt2url.py test.torrent magnet:?xt=urn:btih:MWXFHXOGE2UMR7WBFZYEJPM3LF2VIHNH 最后,推荐一个BT搜索引擎 www.sobt.vip,大部分的bt种子都能找到

ArrayList 和 LinkedList 的区别是什么?

• 数据结构实现: ArrayList 是动态数组的数据结构实现,而 LinkedList 是双向链表的数据结构实现。 • 随机访问效率: ArrayList 比 LinkedList 在随机访问的时候效率要高, 因为 LinkedList 是线性的数据存储方式,所以需要移动指针从前往后依次查找。 • 增加和删除效率: 在非首尾的增加和删除操作,LinkedList 要比 ArrayList 效率要高, 因为 ArrayList 增删操作要影响数组内的其他数据的下标。 • 综合来说: 在需要频繁读取集合中的元素时,更推荐使用 ArrayList, 而在插入和删除操作较多时,更推荐使用 LinkedList。

文字和数字的垂直(竖着)排列

一、文本垂直(竖向)排列 -webkit-writing-mode: vertical-rl; writing-mode: vertical-rl; 二、数字垂直或者(竖向)排列 text-orientation: upright; 三、可以参考下面属性 四、我自己弄的效果图

安卓7.0以上的手机拍照报错exposed beyond app through ClipData.Item.getUri()

js中调用手机系统的摄像头在安卓原生的壳子,7.0以上的手机里报exposed beyond app through ClipData.Item.getUri(),找了半天问题不是那个FileProvider的问题,在Application的onCreate()方法中加入以下代使竟然好使了,有些东西还是要试一下才知道 : StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder(); StrictMode.setVmPolicy(builder.build()); builder.detectFileUriExposure();

springboot文件上传保存路径问题

springboot文件上传保存路径问题 最近使用springboot整合富文本编辑器wangeditor,在整合的时候,对于图片上传时候保存路径出现了一些问题,代码如下 @PostMapping("/upload") public Result upload(MultipartFile[] file, HttpServletRequest request) throws IOException { Result result = new Result(); String path = request.getServletContext().getRealPath("/public/image/upload"); System.out.println(file.length); for (MultipartFile f : file) { String name = f.getOriginalFilename(); f.transferTo(new File(path+File.separator+name)); result.getData().add("/public/image/upload/"+name); } return result; } 报了如下异常 java.io.IOException: java.io.FileNotFoundException: C:\Users\22374\AppData\Local\Temp\ tomcat-docbase.262090075120668420.9003\public\image\upload\demo0.png (系统找不到指定的路径。) 我到了相应路径下查看,路径下确实没有这些文件,因为springboot直接以jar包的方式直接运行,应该是jar包运行时生成的相关路径,并没有深入研究原理。这里并不像tomcat下部署那样,文件夹确实存在,并且可读取。所以只能采用其他方案。 在我们在tomcat下做文件上传时候,我们也并不会直接在项目下面的相关路径下保存上传的文件,因为如果这样保存,项目重新部署,文件就没了。通常是配置tomcat,映射一个静态文件夹,用来存放上传的文件,这样在项目升级重新部署,文件依然存在。现在要解决的问题是,如何使用springboot配置静态文件夹。配置代码如下 spring: mvc: static-path-pattern: /** resources: static-locations: - classpath:/META-INF/resources/ - classpath:/static - classpath:/resources/ - file:${upload-path} upload-path: F:/Java/upload/ 关键的代码就是file:${web.upload-path},这个file是配置一个文件路径做作为静态资源映射,而upload-path: F:/Java/upload/是配置路径的实际位置。其余的代码,因为自己重新配置静态资源映射,所以默认配置失效,自己要重新配置一下。 当然除了配置文件配置,还可以自己继承WebMvcConfigurerAdapter类来配置静态资源映射,当然这是低版本的springboot,高版本的继承WebMvcConfigurerationSupport实现。

安卓与ESP8266串口WIFI模块的通信实现

软件简介 结合一个控制实例,简要介绍一下安卓客户端软件。 主界面非常简洁,左边一个方向控制盘,和右边4个Button。方向盘是一个自定义的View,可以转动任意角度,程序里只响应4个方向,已经足够。四个Button分别对应相应的功能键。 通信实现原理 使用基于tcp协议的socket通信。串口WiFi模块配置成tcp Service模式,然后安卓连接串口wifi模块的热点,客户端作为tcp client 连接。连接成功后就可以相互发送数据。 具体实现 串口WiFi模块配置成tcp Service模式,IP设置为192.168.4.1,端口号3824。 (安卓需要先连接到串口WiFi模块所创建的热点。) 客户端的连接方式如下: private void Connect() { // 开启线程来发起网络请求 new Thread(new Runnable() { @Override public void run() { try { socket = new Socket(); socket.connect(new InetSocketAddress(HOST, PORT), 4000); if(socket != null){ Message message = new Message(); message.what = CONNECTED_RESPONSE; handler.sendMessage(message); } }catch (IOException ex) { ex.printStackTrace(); Message message = new Message(); message.what = RESPONSE_TIMEOUT; handler.sendMessage(message); } } }).start(); } 网络操作需要在非UI线程中进行。程序开启一个线程进行连接操作,连接结果通过一个Handler通知主线程,以便UI更新连接状态指示。

解决移动端中audio多个可以同时播放的问题

先说明一下,内容是ueditor富文本,本来是只有一个音频的,后来按照产品需求,去掉一个音频的限制,结果在移动端发现,多个音频可以同时播放,这个就比较尴尬了,清理思路发现要实现这个效果就必须在渲染文本完成之后获取到所有的audio标签,在标签上面添加播放事件,当a、b、c三个audio标签中,a已经在播放,如果点击b播放之前我需要去关闭a标签的播放,这样就可以实现只有一个播放的修改。代码如下 1.在文本渲染之后获取到所有的audio标签,并且绑定了pauseAll()事件 vm.audioList = document.getElementsByTagName("audio");//获取到所有音频 if(vm.audioList.length>0){//给音频添加点击事件 // console.log(vm.audioList,"...",vm.articleInfo); //想办法给所有的audio添加点击播放事件 // 给play事件绑定暂停函数 [].forEach.call(vm.audioList, function (i) { i.addEventListener("play", vm.pauseAll.bind(i)); }); } 2.pauseAll()事件的具体实现,注意e.target才能获取到当前点击的audio标签就是js中的this标签 pauseAll: function(e){//多个音频点击的时候,禁止已经播放的,然后播放点击的 // // console.log(e.target,"...",this); var self = e.target;//获取到当前的点击的audio [].forEach.call(this.audioList, function (i) { // 将audios中其他的audio全部暂停 i !== self && i.pause(); }) }

Eclipse设置Theme主题颜色

设置Eclipse的代码编辑区背景为暗黑色系: 如需转载,请注明转载自:blog.csdn.net/it1988888 相关文件下载:http://guari.github.io/eclipse-ui-theme/ 方案一--下载颜色主题配置文件,离线导入配色方案的设置: 1. 下载颜色配置文件: http://www.eclipsecolorthemes.org 推荐选择配色方案:Tomorrow Night - by Chris Kempson - Website Eclipse Color Theme (XML) - for Eclipse Color Theme Plugin Eclipse Preferences (EPF) - for Eclipse Import 推荐下载".EPF"文件格式,可以离线导入Eclipse软件设置。 2.导入颜色配置文件至Eclipse: Eclipse -> File -> Import -> General -> Preferences -> (定位至已经下载的“.EPF”文件) -> Finish. 即可生效。 方案二--下载“Eclipse Color Theme”离线安装包: 1.下载导入"Eclipse Color Theme"的离线安装包: http://eclipse-color-theme.github.io/update/ Note: You can download this update site as a zip archive for offline installation.

java:程序包com.sun.tools.javac.util不存在问题解决

com.sun.tools.javac.util工具包是jdk自带的,位置在jdk安装路径下的lib文件里。本人电脑的地址是:C:\Java\jdk1.8.0_121\lib\tools.jar。使用的的IDEA编辑器。 在出现这个问题后,点击File->Project Structure。 然后选择Libraries点击右侧的“+”,选择自己的tools.jar。 然后点击确认,把项目重新编译即可。

Hive内存溢出常见问题

1 MR作业运行过程中内存溢出错误分类 1.1 Mapper/Reducer阶段JVM内存溢出(一般都是堆) 1.1.1 JVM堆(Heap)内存溢出:堆内存不足时,一般会抛出如下异常: 1)-“java.lang.OutOfMemoryError: ” GC overhead limit exceeded;2)-"Error: Java heapspace" 异常信息3)-"running beyondphysical memory limits. Current usage: 2.1 GB of 2.0 GB physical memory used; 3 GB of 8.4 GB virtual memory used. Killing container" 1.1.2 栈内存溢出:抛出异常为 java.lang.StackOverflowError 常会出现在SQL中(SQL语句中条件组合太多,被解析成为不断的递归调用),或MR代码中有递归调用。这种深度的递归调用在栈中方法调用链条太长导致的。出现这种错误一般说明程序写的有问题。 1.2 MRAppMaster内存不足 如果作业的输入的数据很大,导致产生了大量的Mapper和Reducer数量,致使MRAppMaster(当前作业的管理者)的压力很大,最终导致MRAppMaster内存不足,作业跑了一般出现了OOM信息。 异常信息为: Exception: java.lang.OutOfMemoryError thrown from theUncaughtExceptionHandler in thread "Socket Reader #1 for port 30703 Halting due to Out Of Memory Error... Halting due to Out Of Memory Error.

Java CompareTo方法使用及详解

compareTo方法有两种: compareTo(String str) 按字典顺序比较两个字符串。 compareToIgnoreCase(String str) 按字典顺序比较两个字符串,不考虑大小写。 compareTo大多数时候用作于排序,相对一般排序而言,用compareTo就够了,不考虑大小写的情况很少。compareTo是按照按字典顺序去比较两个字符串的,一般常用的字符串类型无非3个,阿拉伯数字格式,英文字母格式以及中文格式。其中数字格式的顺序最简单,英文字母格式次之,当然,最复杂的还是我们的国语,在忽略多音字的前提下,有多少个汉字?反正我是不知道了。字典表对汉字的排序规律我也不知道,太复杂,所有只研究了英文字母格式,在第二篇中具体说明。 先把代码和结果放出来: 排序是根据两个字符串之间的顺序比值来排列的,在此不补充排序方法,只对CompareTo方法解说。 (变量1).<方法>(变量2),返回的值是变量1比变量2的字典顺序。 注意点: 1、 顺序相等,则返回0,变量1的顺序在变量2之前则返回负值数,变量1的顺序在变量2之后则返回正值数。以此比较! 2、 比较的时候,相等则继续比较下一位数,直到有一位数不等,进行比较,但要注意,只会比较一次,以这一次的值作为比较数据;如果两个变量位数相等、顺序一致,则返回零; 3、 如果顺序相等,位数不等,则位数之间相减(多减少),其余规则不变。(如图中的:顺序相等,位数不同的比较) 字典顺序: 1、 阿拉伯数字:阿拉伯数字的顺序很简单,因为阿拉伯数字总体只有10个数字,从0到9。国际通用,顺序就是顺着来的。 2、 英文字母:代码本身就是西方人设计出来的,相对的,对他们的语言的基础(26字母)的编码也就更标准了,本人对26字母的字典顺序还是有一点点的不解。不影响分析。26字母区分大小写,大写字母的顺序排在小写字母之前。按字母顺序排列,大小写字母的顺序之间没有间隔,但在边界有一样的间隔,具体在第二篇讲。有兴趣的同学去查一下,本人有点懒。 3、 中文:中文的格式表示惹不起,具体排列没去查过,但在排序方法中,中文一般不作为比较值(出现的位数是一致的),比较的是数字或者字母为主。你若是作死,那没办法了。换个说法,以中文作为比较去排序没有意义!汉字在字典表中的顺序是非常庞大的,可以用中文去比较,但排序出来的顺序不是你想要的结果(结果未知性),因为字典顺序只比较一次!因此,在用CompareTo方法排序时,一般中文的比较值在各变量中都是相同的(同一个中文)比如都是用员工1,员工2等等,排序用到的是后面的数字;注意一般真正比较的值(位数)不是中文,是数字或者字母这些可以按想要顺序排列的值(位数) 补充说明一下: 在方法使用中(变量1).<方法>(变量2),得到的值是变量1在变量2的字典顺序之前还是之后,决定是正值还是负值,比如在图中的:阿拉伯数字格式,第一位数都是1,就跳过,然后1在9之前,得到的就是负值,1在9前8位,所以返回-8,只比较一次,所以,在比较不等值时只比较一次(上面说过相等就跳过,直到不等的位数进行比较,或者都相等就返回0),因为值比较一次,所以也就排序作用了。也许还能遍历出来所有的比较呢?没试过,有兴趣的童鞋可以尝试。 可以了解规律,实用性不是很高,可以自行判断相差值,排序方法时电脑已经计算好了的,所有更多的是理解作用,先上代码,有点懒,全部结合在一张图了。 声明一下,不介绍不区分大小写的,不区分后,没啥好说的,个人感觉compareToIgnoreCase就是为了填区分大小写时字典表的顺序问题的,compareTo的字典表顺序整体有点怪怪的感觉。 a与A的比较顺序是32,既是字典顺序中a在A的后32位,反过来比较就是-32.算是字母顺序中的一个中间数。相同的,其余两个也是一样的。 a与Z的比较顺序是7,既是字典顺序中a在Z的后7位,反过来比较就是-7. z与A的比较顺序是57,既是字典顺序中z在A的后57位,反过来比较就是-57. a与A的比较顺序是32,在这三个比较值中,算是中间位置,峰值是57,在字典表中,57是最后一个了,当然具体排序不清楚,57只是a在A顺序后57位(大写A在字母顺序中是第一个,小写z是最后一个),a与Z的比较顺序是7,别问我为啥中间空了7位数,我也不知道,理应Z之后下一个字典顺序就是a才对。所以某些时候要比较时有点乱,compareToIgnoreCase就应运而生了,修改字典表太麻烦,但能加呀!有不少方法就是亡羊补牢弄出来的。 虽然不知道字典表的具体排序顺序,但字母表的顺序除了前后有点怪,别的都正常。<z←→B>比较是56,按字母顺序递加,<z←→Y>比较是33, <z←→Z>比较又回到了32,<a←→Z>比较是7,反过来,<a←→Y>比较是8,按字母顺序递减,<a←→B>比较是31,<a←→A>比较是32,又回到了中间值,来来回回就是在26字母之间加减,只是中间多出了一些不存在于字母顺序的位数,不用纠结太多,别像我一样了。 研究了半天。区分大小写的情况下,逃不出57,比较值只会在-57到57之间产生,因为只比较一次,就算比较多次,也就多几个57到57之间的比值而已。区分大小写的话,逃不出25,比较值只会在-25到25之间产生。 还是要注意一下:compareTo的比较是比较不同点(或者说是找区别),并且是只比较一次。之后又多少不同点都不管的。就像是在区分对象,抓住一点不同就好,能区分就行。同等同值时就成了类了,比如都是男生,知道了,返回个零表示没区别。同值位数不等,就像是这一边有3个男生,那一边有1个男生,区别就是个数,就返回2,表示区别。正负值是看这个位数是在比较值之前还是之后,反过来就是了。

Java对HBase的CRUD操作的小demo

import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.*; import org.apache.hadoop.hbase.client.*; import org.junit.After; import org.junit.Before; import org.junit.Test; public class HBaseDemo { private String tn = "teacher"; HBaseAdmin admin = null; HTable table = null; @Before public void init() throws Exception { Configuration conf = new Configuration(); conf.set("hbase.zookeeper.quorum","master,slave1,slave2,slave3,slave4,slave5,slave6,slave7"); admin = new HBaseAdmin(conf); table = new HTable(conf,tn.getBytes()); } @Test public void createTable() throws Exception { HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(tn)); HColumnDescriptor addFamily = new HColumnDescriptor("teacherInfo".getBytes()); desc.addFamily(addFamily); if(admin.

EtherCAT学习笔记:周期性过程数据通信

*如有不对之处欢迎留言指正,不胜感激 周期性过程数据通信 周期性过程数据模式区分主站同步运行模式和从站同步运行模式。 从站周期性同步模式 Free RUN 自由运行: 从站本地设置定时器产生本地中断,定时间隔也可以由主站设定; 自由运行模式就是每个slave根据自己的时间中断(未同步的timer)来处理EtherCAT数据,跟主站的运行周期其他从站的周期以及EtherCAT帧的到达时间都没关系;主站发送数据帧与从站处理数据帧不同步。 同步于数据输入或输出事件: 主站将过程数据帧发送周期同步给从站,从站可以选择是否支持该周期,或对本地周期时间优化,通常同步于输出事件,只有输入事件时候,同步于输入事件。也就是在输入输出事件产生时,接收数据帧; 同步于分布时钟同步事件: 本地时钟有SYNC事件触发,主站必须在SYNC事件触发前完成数据帧的发送,因此主站也需要同步于参考时钟; 在此基础上,从站可以在数据收发事件发生时将接收到的数据缓存,完成数据的交换和相关运算,等待SYNC信号后马上执行输出操作,同步性大大增强。 主站周期性同步模式 Free Run 自由运行: 同从站介绍 SMx Mode 同步管理器(SM),同步管理器同步时的数据而不是时间,即同步于数据的输入和输出,与从站介绍的第二种同步方式对应 DC Mode DC Mode(Distributed Clock)是一种高精度时间同步的模式,取第一次支持DC的从机作为参考时钟,主站及从站同步于参考时钟,与从站介绍的第三种同步模式类似,DC模式会在SYNC事件到来前完成数据帧的接收和运算;可预先计算的固定偏移量包括以下几点: 控制程序执行时间数据帧传输时间数据帧传输延时从站延时时间的抖动和控制程序执行抖动

安装 aconda 后Linux的终端界面前部出现(base)字样

转载 https://www.cnblogs.com/devilmaycry812839668/p/10349602.html 安装 aconda 后Linux的终端界面前部出现(base)字样 aconda 是做什么用的这里就不说了,一般玩Python的都知道这东西,最早接触这东西是因为它把NVIDIA中cuda计算和Python互连的一个库拿下了,是买下来了还是专业,还是唯一合作的也就记不清了,那就是 numba , 那些年头Python想要原生态调用cuda代码是比较难的,numba提供了一种较好的支持,虽然当时要我好个激动但是后来发现也没啥太大意义和价值,后来随着Python的各种各种版本泛滥,各种库对不同环境的依赖关系难以搞定等问题,当然这都是后来才逐渐凸显出来的问题,现在由于深度学习的各种大火,各种版本的管理又是要人头疼的很,于是我又用起了aconda, 这东西除了太大,太占磁盘空间,下载耗时,安装耗时,太占地方以外还是比较好用的。 aconda下载地址 https://www.anaconda.com/distribution/ 下载、安装过程不讲。 这一次安装以后突然间发现了一个问题,那就是Linux终端变样了,无端的在终端前部分出现了(base)字样,如下图: 这突然要我感觉是十分的神奇又有些不爽, 凭感觉打开了 ~/.bashrc 文件, 发现如下: 复制代码 export PATH=/home/devil/anaconda3/bin:$PATH added by Anaconda3 2018.12 installer >>> conda init >>> !! Contents within this block are managed by ‘conda init’ !! __conda_setup="$(CONDA_REPORT_ERRORS=false ‘/home/devil/anaconda3/bin/conda’ shell.bash hook 2> /dev/null)" if [ KaTeX parse error: Expected 'EOF', got '\eval' at position 21: … 0 ]; then \̲e̲v̲a̲l̲ ̲"__conda_setup" else if [ -f “/home/devil/anaconda3/etc/profile.

当tomcat中的webapps文件夹中没了ROOT

部署项目包时,发现没有报错。但访问不到项目,各种百度。 看了这个大佬的博客,修改了自己的server.xml。root粗线了。 转自:https://blog.csdn.net/qq_36631900/article/details/85706364 在server.xml中,host标签下加上 <Context path="/" docBase="/usr/tomcat/apache-tomcat/webapps/XX-web/" reloadable="true" crossContext="true" /> 解决。

WPF MVVM应用:动态加载菜单项

目录 View ViewModel 效果 View <Menu x:Name="MainMenu" ItemsSource="{Binding MenuItems}" ></Menu> ViewModel using Prism.Mvvm; using SqlHelp; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Data; using System.Linq; using System.Windows.Controls; namespace WPFSale.ViewModels { public class MainWindowViewModel : BindableBase { private ObservableCollection<MenuItem> menus; public ObservableCollection<MenuItem> MenuItems { get { return menus; } set { SetProperty(ref menus, value); } } public MainWindowViewModel() { LoadMenus(); } private void LoadMenus() { //读取菜单数据库数据 DataTable dataTable = Database.ExecSqlReturnDataTable("select * from Fun order by OrderID asc"

【Java基础】BIO 与 NIO 的区别

文章目录 1. 基础概念1.1 阻塞与非阻塞1.2 同步与异步 2. BIO 与 NIO2.1 BIO2.1.1概念2.1.2 实现机制2.1.3 工作原理 2.2 NIO2.2.1 概念2.2.1 实现机制2.2.2 为什么使用NIO2.2.3 三大主要组件2.2.3.1 通道 Channel2.2.3.2 选择器 Selector2.2.3.3 缓冲区 Buffer 2.2.4 有关缓冲的一些概念或技术 3. 面向流和面向缓冲4. 为什么NIO比BIO效率高5.总结 在进入主题之前,先说一下BIO的发展史, 一开始我们使用的BIO,但是BIO是同步阻塞的,即这个线程没有处理完数据的话,是无法进行其他操作的;于是用多线程处理进行了改造,即每个请求开启一个新线程,但是这样又存在一个问题:线程过多(每个线程对象都是占用内存的,32位系统1个线程对象默认最大需要320kb内存,64位系统最大需要1M,如果并发高的话,内存是不够的,会出现内存爆满情况);接着又用线程池改造,限定线程的数量,此时又会出现一个问题,比如线程池设置的并发数量为100,这100个线程都是处理大文件,101只是处理几kb的文件,但是要等待好久为了解决以上问题,出现了NIO 1. 基础概念 1.1 阻塞与非阻塞 阻塞和非阻塞是进程访问数据时,数据是否准备就绪的一种处理方式: 阻塞:当数据没有准备好,进程必须等待缓冲区的数据准备好才能返回做其他事情,否则一直处于等待,无法进行其他事情 非阻塞:当数据没有准备好,直接返回不会等待,如果数据已经准备好,则直接返回 1.2 同步与异步 同步和异步是基于应用程序和操作系统处理IO时事件所采用的方式: 同步:应用程序直接参与IO读写操作 异步:所有的IO读写操作交给操作系统处理,应用程序只需要等待通知 2. BIO 与 NIO 首先先明白连接请求和IO请求,客户端和服务端进行通信时,首先服务端会监听到有一个客户端请求,为其创建创建通信套接字(Socket),此时可能只是建立了一个连接,不做什么的数据传输即IO操作,所以要明白 连接请求和IO请求不是必然的关系,即有连接 一定有IO 2.1 BIO 2.1.1概念 同步阻塞IO,服务器实现模式为一个连接一个线程,即客户端有连接请求时,服务端为其建立一个线程进行处理,如果这个线程不做任何事情,这个线程就一直空闲,但也不会做其他事情,这样造成了线程的浪费 2.1.2 实现机制 面向流,即I/O系统以流的形式处理数据,一次一个字节的处理数据,一个输入流产生一个字节的数据,一个输出流消费一个字节的数据。 2.1.3 工作原理 由一个专门的线程处理所有的IO事件,并负责分发事件驱动机制:事件到的时候触发,而不是同步的去监视事件线程通讯:线程之间同过wait,notify等方式通讯,保证每次上下文切换都是有意义的,减少五位的线程切换 2.2 NIO 2.2.1 概念 同步非阻塞,服务器实现模式为一个连接一个线程,即客户端有连接请求时,都会注册到多路复用器上,多路复用器轮询到有IO请求时,才启动一个线程处理 2.2.1 实现机制 面向块,即面向块,即I/O系统以块的形式处理数据,一次一个数据块,线程这样比流快,但是面向块的I/O不如面向流I/O优雅和简单 2.2.2 为什么使用NIO 目的是为了让 Java 程序员可以实现高速 I/O ,NIO 将最耗时的 I/O 操作(即填充和提取缓冲区)转移回操作系统,因而可以极大地提高速度

vim使用教程

转载 https://blog.csdn.net/qq_30748863/article/details/84669058 文章目录 一、什么是VIM 二、VIM入门 三、常用命令介绍 移动选择复制粘贴删除(剪切)撤销恢复查找替换(修改)缩进标记查看历史进入插入模式进入底行模式其他tips 一、什么是VIM 在说vim之前,先说下什么是vi。vi是visual interface的简称,是Linux中最经典的文本编辑器。vi的核心设计思想是:让程序员的手始终保持在键盘的核心区域就能够完成所有的编辑操作。而Vim又是从 vi 发展出来的一个文本编辑器,即vi improved,它在代码补全、编译及错误跳转等方便编程的功能上特别丰富,在程序员中被广泛使用。 为方便理解,也给出上图的英文版 从这张图就可以看出,vim的命令繁多,不过灵活使用后将会大大提高效率。对于新手可先不必理会上图,下文会把常用的使用方法一一道来,助你入门。 二、VIM入门 首先你要明白的一点是,VIM有3种主要的工作模式: 命令模式(Command mode) 用户启动vim时,首先进入的便是命令模式。命令模式可认为是vim的入口,此模式下敲击键盘的字符都会被当做命令,而非在文本中插入字符。比如,我想打出我的名字kevin,我敲下键盘上的k kk键,屏幕上并不会显示出k kk字符,事实上,屏幕上什么反应也没有。这时候,不要怀疑电脑坏了,而是你并没有进入插入模式,暂时还不能进行插入的操作。那命令模式下都有哪些命令呢?诸如移动、选择、复制、粘贴、删除、查找、替换、缩进、撤销、恢复、定位、翻页……都是在命令模式下完成的。关于这些命令后面还会介绍,这里大家先掌握进入插入模式的命令之一:i。当在命令模式下输入i后,便进入了插入模式,然后就可以正常地编辑文字了。 插入模式(Insert mode) 此模式下可以正常地编辑文字,与平时使用习惯差别不大。 底行模式(Last line mode) 此模式下可以执行保存、退出以及其他的一些功能。按下Shift+:即可进入底行模式。输入wq为保存退出,输入q!为不保存退出。 此外,还有其他一些模式,如可视模式(Visual)、替换模式(Replace)等,将会在下文进行介绍。 三、常用命令介绍 移动 方位移动 h:光标左移一格 j:光标下移一格 k:光标上移一格 l:光标右移一格 当然,关于上下左右的移动使用方向键也是允许的。 行内移动 0:光标移至行首 $:光标移至行尾 ^:光标移到当前行的第一个非空字符 g_:光标移到当前行的最后一个非空字符 b:光标到上一个字的开头 w:光标到下一个字的开头 e:光标移到下一个字的结尾 ge:光标移到上一个字的结尾 fa:移到下一个a出现的位置('F’与之相反) ta:移到下一个a出现位置的前一个位置(‘T’与之相反) 行间移动 G:光标移至文末 gg:光标移至开头 Ngg或NG:光标移至N行开头 语义移动 (:光标移至上一句首 ):光标移至下一句首 {:光标移至段首 }:光标移至段尾 屏幕移动 H:将光标移到屏幕的最顶行 M:将光标移到屏幕中间 L:将光标移到屏幕最底行 Ctrl+b:向上翻页 Ctrl+f:向下翻页 选择 此功能需进入可视模式,方法为按下键盘上的v键。然后搭配上面移动的想关命令即可实现文本的选择。读者可自行探索使用技巧,如ggvG可实现全选,v$可实现选中某行等。 补充:使用Ctrl+v可进入可视块模式,允许垂直方向选择文本。 复制 y:复制(可与移动命令搭配使用,自行探索,如yw可复制光标至词尾的内容)

canvas生成海报

虽然之前也做过类似的生成海报的项目,但是这个项目我又网上查找了一下,发现一个插件挺好用的 html2canvas.js http://html2canvas.hertzen.com/这里可以下载这个插件 用起来很方面 优先引入这个js <script type="text/javascript" src="js/html2canvas.min.js"></script> 然后需要定义canvas容器,编写你需要生成的html <canvas id="myCanvas" width="1125" height="1180" style="display: none;"></canvas>//定义canvas <div class="bigImg" style="display: none;width: 100%;height: auto;position: absolute;left:0;top: 0;z-index:8;overflow-y: auto;"></div>//生成图片展示的地方 <div class="wrap-con" style="width: 100%;z-index:-1;">//需要转换成图片的html <img src="images/p901.png" class="p901"> <div class="people-photo 902" style="margin-top: -0.5rem;"> <img src="images/photo-zh2.png" class="photo3"> <img src="images/photo.png" class="photo1"> <img src="images/photo-zh1.png" class="photo2"> </div> <div class="changeContent"></div> <img src="images/erma.png" class="p903"> <img src="images/p903.png" class="p904"> <img src="images/p905.png" class="p905" style="margin-bottom:0;position: absolute; bottom: 0;"> </div> 下面是如何使用js去把html生成图片 var canvas = document.getElementById("myCanvas"); var _canvas = document.

hive NullPointerException null

insert overwrite table table_name select '2019-04-12' min_date, '2019-04-12' conf_date 在hivesql里这样写,可能会报空指针错误。 需要加上from default.dual 以防万一

移动端h5 实现多个音频播放

前一段时间做到一个项目,其中用到很多之前没用过的东西,其中一个就是h5的多音频实现,背景音频和说话同时播放,其中出现了很多问题,不过总算找到了解决方案。 平时做H5如果只有一个音乐的话就直接在页面里面添加一个audio标签,具体这个标签怎么使用,有哪些属性可以参考http://www.runoob.com/tags/ref-av-dom.html <audio id="backMusic" src="music.mp3" autoplay loop></audio> <!--音乐--> 今天就来解决一下,怎么播放多个音频文件 刚开始我的方法是在H5页面放很多音频,也就是很多audio标签,发现苹果手机不兼容,它只能播放一个音频,暂停上一个,下一个也不会播放,后面网上查找了一下,说苹果微信自带播放音频的只能同时播放一个,然后只能暂停背景音乐去播放说话的声音 这个我是通过动态修改audio标签的src属性 下面是我定义的音乐的文件,打开页面自动播放背景音乐 var backMusic = document.getElementById("backMusic"); setTimeout(function(){ backMusic.play(); music.play(); },100) document.addEventListener('DOMContentLoaded', function () { function audioAutoPlay() { music.play(); backMusic.play(); document.addEventListener("WeixinJSBridgeReady", function () { music.play(); backMusic.play(); }, false); 然后我又在需要说话的时候把这个背景音乐的src的值动态改变为需要播放的音频 music.pause(); music.src="fumu.mp3";//父母唠叨 setTimeout (function(){ music.play(); },2000); 这样只能实现单个音频播放,但是要实现多个音频同时播放还是没解决,后来又看了别人发的一个项目参考了一下,进行了尝试,发现居然可以了 //定义 <div class="audiopalyer" style="display: none"> <audio id="backMusic" src="music.mp3" autoplay loop></audio> <!--背景音乐--> </div> <div class="talkplay" style="display: none"> <audio id="audios" src="music.mp3" ></audio>//中间穿插的和背景音乐同时播放的音频 </div> //js var music = document.

WebGL three.js学习笔记 法向量网格材质MeshNormalMaterial的介绍和创建360度全景天空盒的方法

WebGL学习----Three.js学习笔记(5) 点击查看demo演示 Demo地址:https://nsytsqdtn.github.io/demo/360/360 简单网格材质 MeshNormalMaterial MeshNormalMaterial是一种不受渲染时使用的颜色影响的材质,它只与自己每一个面从内到外的法向量有关。法向量在webgl中用处十分广泛,光的反射,以及三维图形的纹理映射都与这个有关。 从图中可以看到,网格的每一面渲染的颜色都是不一样的,如果我们想要在物体表面添加法向量,我们可以使用的THREE.ArrowHelper去表示每一个法向量,它的参数为 THREE.ArrowHelper(dir, origin, length, color, headLength, headWidth) 其中参数的意义为: dir:方向,默认是法向量 origin:开始的坐标位置 length:辅助线的长度 color:辅助线的颜色 headLength:头部的长度 headWidth:头部的宽度 对于一个球体,要描述它每一个面的法向量,首先需要对它的每一个面进行遍历,取出这个面上的三个顶点(因为webgl的面都是三角形,所以是三个顶点),通过divideScalar(3)这个函数计算它的中心位置,我们就可以在这个中心位置点上,从内向外引出一个ArrowHelper,来模拟法向量。 for(let i=0;i<sphereGeometry.faces.length;i++){//在每一个面上面循环 let face = sphereGeometry.faces[i];//得到每个面的对象 let centroid = new THREE.Vector3(); //先创建一个vector3对象,要使用这个对象找到每个面的中心 centroid.add(sphereGeometry.vertices[face.a]); // 将这该面的三个顶点的索引传给sphereGeometry.vertices找到其顶点的坐标 //再添加进centroid centroid.add(sphereGeometry.vertices[face.b]); centroid.add(sphereGeometry.vertices[face.c]); centroid.divideScalar(3);//三角形的中心点坐标 let arrow = new THREE.ArrowHelper( face.normal,//face这个面的法向量 centroid, 2, 0xffcc55, 0.5, 0.5);//箭头辅助线,相当于把法向量用箭头表示出来 sphere.add(arrow); } 其中,centroid.add(sphereGeometry.vertices[face.a])这段代码中的sphereGeometry.vertices存有几何体的所有顶点信息,通过[ ]索引可以取得其中的某一个顶点。face.a还有下面的face.b和c都是该面的顶点索引号,表示这个面是由顶点编号为face.a,face.b,face.c的三个顶点所构成的一个三角形(webgl的面都是三角形),然后我们再计算这三个顶点的中心点。 菜单面板的设置 在菜单面板中设置一些MeshNormalmaterial的一些属性,便于去测试这种材质的一些特质 其中: this.visible = meshMaterial.visible;//是否可见 this.wireframe = meshMaterial.wireframe;//是否以线框的方式渲染物体 this.wireframeWidth = meshMaterial.wireframeLinewidth;//线框的宽度 this.transparent = meshMaterial.

redhat7 rhel7怎么修改镜像源 阿里源 源

由于redhat商业化,注册才能使用其源,这里用阿里的centos源代替 https://blog.csdn.net/xlnhaha/article/details/82049379 1 .下载CentOS-Base.repo文件 该文件会下载到 /etc/yum.repos.d 这个目录下面 wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo 将$releaseserve替换为7, 双击CentOS-Base.repo文件打开后按ctr+h键 查找后全部替换 执行 yum clean all 清楚原来的缓存 执行 yum makecache 建立元数据缓存 配置成功啦

浅谈分布式事务的解决方案

一、分布式事务 分布式事务就是指事务的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于不同的分布式系统的不同节点之上。以上是百度百科的解释,简单的说,就是一次大的操作由不同的小操作组成,这些小的操作分布在不同的服务器上,且属于不同的应用,分布式事务需要保证这些小操作要么全部成功,要么全部失败。本质上来说,分布式事务就是为了保证不同数据库的数据一致性。 画外音:提起分布式系统,我们不得不想起CAP理论。这里不展开讨论,可以参考前篇文章分布式系统理解之CAP理论的发展 以商品流水账单为例,我们拆分为商品购买系统,订单系统,支付系统。 用户看中一件商品,点击购买。商品购买系统响应用户的点击,向订单系统插入一条订单信息。跳转到支付系统完成支付。 在用户整个购买商品的过程中,我们需要保证事件1,2,3在没有异常的情况下全部执行成功,一旦某个系统抛出异常,都需要回滚。 那么,如何保证各个子系统的操作具有一致性呢?这就是我们下面提到的分布式事务的解决方案。 在这里,文章中没有提到分布式一致性协议,下面简单列举一下,有兴趣的读者可以参考其他详细资料: 两阶段提交协议三阶段提交协议Paxos协议Raft协议 二、分布式事务的解决方案 1.两阶段提交方案/XA方案 该方案基于两阶段提交协议,因此也叫做两阶段提交方案。在该分布式系统中,其中 需要一个系统担任协调器的角色,其他系统担任参与者的角色。主要分为Commit-request阶段和Commit阶段 请求阶段:首先协调器会向所有的参与者发送准备提交或者取消提交的请求,然后会收集参与者的决策。提交阶段:协调者会收集所有参与者的决策信息,当且仅当所有的参与者向协调器发送确认消息时协调器才会提交请求,否则执行回滚或者取消请求。 (上图摘自网上) 该方案的缺陷: 同步阻塞:所有的参与者都是事务同步阻塞型的。当参与者占有公共资源时,其他第三方节点访问公共资源不得不处于阻塞状态。单点故障:一旦协调器发生故障,系统不可用。数据不一致:当协调器发送commit之后,有的参与者收到commit消息,事务执行成功,有的没有收到,处于阻塞状态,这段时间会产生数据不一致性。不确定性:当协调器发送commit之后,并且此时只有一个参与者收到了commit,那么当该参与者与协调器同时宕机之后,重新选举的协调器无法确定该条消息是否提交成功。 XA方案的实现方式可以使用Spring+JTA来实现,可以参考文章:Springboot+atomikos+jta实现分布式事务统一管理 2.TCC方案 TCC方案分为Try Confirm Cancel三个阶段,属于补偿性分布式事务。 Try:尝试待执行的业务 这个过程并未执行业务,只是完成所有业务的一致性检查,并预留好执行所需的全部资源Confirm:执行业务 这个过程真正开始执行业务,由于Try阶段已经完成了一致性检查,因此本过程直接执行,而不做任何检查。并且在执行的过程中,会使用到Try阶段预留的业务资源。Cancel:取消执行的业务 若业务执行失败,则进入Cancel阶段,它会释放所有占用的业务资源,并回滚Confirm阶段执行的操作。 以一个电商系统用户购买商品的流水线为例。 Try阶段: 在Try阶段成功之后进入Confirm阶段,如有任何异常,进入Cancel阶段。 Confirm阶段 Cancel阶段 假设库存扣减失败,此时需要回滚取消事务。 TCC方案适用于一致性要求极高的系统中,比如金钱交易相关的系统中,不过可以看出,其基于补偿的原理,因此,需要编写大量的补偿事务的代码,比较冗余。不过现有开源的TCC框架,比如TCC-transaction。 3. 本地消息表 本地消息表分布式事务解决方案是国外的eBay提出的一套方案。 需要注意的是,该方案中,在A系统中,我们首先写入业务表,然后写入消息表,然后将消息发送到MQ中,在B系统中需要先写入消息表,这是为了保证消息重复消费,为了保证消息消费的幂等性,我们可以使用数据的唯一键来约束。 当B系统执行成功之后,需要通知A系统执行成功,此时可以使用一个监听器,如Zookeeper,ZK监听到执行成功更新A系统成功。然后开始发送下一条消息。 A系统中需要有一个后台线程,不断的去判断A系统的状态为待确认的消息,设置超时机制,如果超时,重新发送到MQ中。直到执行成功。 可以看出,本地消息表方案需要写入消息表中,如果在高并发的场景下会进行大量的磁盘IO,因此该方案不适用于高并发场景。 4.可靠消息最终一致性方案 该方案基于本地消息表进行优化,不使用本地消息表,而是基于MQ,比如阿里的RocketMQ就支持消息事务。 在该方案中,首先A系统需要向MQ中发送prepare消息,然后执行A系统的业务,写入数据库成功之后向MQ发送confirm消息,当消息为confirm状态时,B系统就可以消费到消息,消费成功之后返回ACK确认消息给MQ。 需要注意的是。需要保证B系统消费消息的幂等性,可以借助第三方系统。比如在redis中设置标识,标明已经消费过该消息,或者借助ZK基于分布式锁的原理,创建节点,重复消费消息,创建失败。 5.最大努力通知方案 最大努力通知型( Best-effort delivery)是最简单的一种柔性事务,适用于一些最终一致性时间敏感度低的业务,且被动方处理结果 不影响主动方的处理结果。典型的使用场景:如银行通知、商户通知等。 在该系统中,A系统执行完本地事务,向MQ发送消息,最大努力通知服务消费消息,比如消息服务,然后调用B系统的接口,执行B系统的本地事务,如果B系统执行成功则OK,否则不断重试,重复多次之后还是失败的话就放弃执行。 参考文章: http://www.tianshouzhi.com/api/tutorials/distributed_transaction/387 https://blog.csdn.net/u010425776/article/details/79516298

【Qt编程笔记】采用遍历方式删除QList中全部元素的方法

QList类是Qt提供的链表模板类,在日常工作和学习中经常会用到,虽然QList操作十分便利,但是在用遍历方式删除全部元素时很可能会因为疏忽造成没有将元素全部删除,从而给程序留下隐患。下面小结一下采用遍历方式删除QList中全部元素的方法,避免重走弯路。 下面将比较for循环和foreach循环两种方式下的不同,并给出正确的删除方式。 在比较之前,首先构建一个QList对象,其中包含若干QString类型的元素: QList<QString> qlist; qlist<<"a"<<"b"<<"c"<<"d"; qDebug()<<"qlist.size()="<<qlist.size(); 此时程序可以得到如下结果: qlist.size()= 4 for循环删除方式 很多人可能会出于习惯选择这个方式来删除元素,例如: for(int i=0;i<qlist.size();++i) { qlist.removeAt(i); qDebug()<<"qlist.size()="<<qlist.size(); } 这时程序的显示结果为: qlist.size()= 3 qlist.size()= 2 打印qlist中的全部元素: foreach(auto item,qlist) { qDebug()<<item; } 得到: “b” “d” 由此可以看出,该方式不能删除QList对象中的全部元素,原因是在每次循环过程中,使用removeAt成员函数删除一个指定元素之后,QList对象的元素个数也随之减1,即size成员函数的返回值在每次循环过程中都会发生变化,因此导致无法成功删除全部元素。 foreach循环删除方式 采用foreach方式删除全部元素: foreach(auto item,qlist) { qlist.removeOne(item); qDebug()<<"qlist.size()="<<qlist.size(); } 采用这种方式可以得到如下结果: qlist.size()= 3 qlist.size()= 2 qlist.size()= 1 qlist.size()= 0 由此可见,该方式可以成功遍历删除QList对象中的全部元素,因此,在QList类的实际使用过程中,推荐使用foreach循环的方式删除链表中的全部元素。

算法科普:什么是约瑟夫环

1 问题描述 约瑟夫环(约瑟夫问题)是一个数学的应用问题:已知 n 个人(以编号1,2,3…n分别表示)围坐在一张圆桌周围。从编号为 k 的人开始报数,数到 m 的那个人出圈;他的下一个人又从 1 开始报数,数到 m 的那个人又出圈;依此规律重复下去,直到剩余最后一个胜利者。 例如:有10个人围成一圈进行此游戏,每个人编号为 1-10 。若规定数到 3 的人出圈。则游戏过程如下。 (1)开始报数,第一个数到 3 的人为 3 号,3 号出圈。 1, 2, 【3】, 4, 5, 6, 7, 8, 9, 10。 (2)从4号重新从1开始计数,则接下来数到3的人为6号,6号出圈。 1, 2, 【3】, 4, 5, 【6】, 7, 8, 9, 10。 (3)从7号重新从1开始计数,则接下来数到3的人为9号,9号出圈。 1, 2, 【3】, 4, 5, 【6】, 7, 8, 【9】, 10。 (4)从10号重新从1开始计数,由于10个人称环形结构,则接下来数到3的人为2号,2号出圈。 1, 【2】, 【3】, 4, 5, 【6】, 7, 8, 【9】, 10。 (5)从4号重新从1开始计数,则接下来数到3的人为7号,7号出圈。 1, 【2】, 【3】, 4, 5, 【6】, 【7】, 8, 【9】, 10。

ffmpeg h265(flv封装) 转码成 h264 (flv封装)

ffmpeg h265(flv封装) 转码成 h264 (flv封装) ffmpeg -y -vcodec hevc -i glw265.flv -acodec copy -vcodec libx264 glw264.flv 指定输出码率是2Mbps ffmpeg -y -vcodec hevc -i glw265.flv -acodec copy -vcodec libx264 -vb 2048000 glw264.flv 匀速转码命令: -re ffmpeg -y -re -i glw264.flv -acodec copy -vcodec libx264 -vb 2048k glw264_transcode.flv

Python 使用input保证输入的必须是整数

在Python3.x中input()的返回值是‘str’类型,采用eval()函数保证输入的持续为整数 关于eval()函数的理解,可以参考博客:https://blog.csdn.net/ChaoFeiLi/article/details/89387782 def inputInt(content='请输入整数:'): while True: data = input(content) try: inputData = eval(data) if type(inputData) == int: # break return inputData except: pass if __name__ == "__main__": print(inputInt())

CentOS 7.4 安装 CDH5.14.4 详细过程

环境及软件说明 环境说明 本人PC虚拟机VM10,里面安装了3台CentOS7.4 .集群环境规划如下: CPU IP 主机名 角色 内存 2核心2线程 192.168.1.31 cdh1 CM server,agent 8G 2核心2线程 192.168.1.32 cdh2 agent 2G 2核心2线程 192.168.1.33 cdh3 agent 2G 我的电脑16G内存,只能上面这样规划了,最后CDH是能安装成功的,只不过没法用,资源太少了。 所需软件及说明 1:JDK1.8 2:Cloudera Manager cloudera-manager-centos7-cm5.14.0_x86_64.tar.gz 下载地址: https://archive.cloudera.com/cm5/cm/5/ 3:CDH CDH-5.14.4-1.cdh5.14.4.p0.3-el7.parcel.sha1,CDH-5.14.4-1.cdh5.14.4.p0.3-el7.parcel, manifest.json 下载地址:http://archive.cloudera.com/cdh5/parcels/5.14/ 这里要注意CM和CDH,大版本应该要一致,比如CM为5.14,CDH也是5.14,至于如果不一致是否会出问题,比如CM为5.13,CDH为5.14,这个需要由大神来测试了 4:Mysql mysql-5.6.26-linux-glibc2.5-x86_64.tar.gz 5:.数据库驱动 mysql-connector-java-xxx.jar 6:mysql-community-libs-compat-5.7.23-1.el7.x86_64.rpm 说明:这是MySQL的一个组件的安装包,不是核心组件,不安装也不影响MySQL使用。但是如果缺少这个包,后面hue安装的时候很可能报错,所以先下载下来备用。 以上这些软件,我都已经下载到百度云盘了,链接:https://pan.baidu.com/s/1suG4AxqpAd2Bsry0E6iwjA 提取码:nb0p 安装前的主机准备 一.安装JDK。(每台主机都要做) rpm -e --nodeps java-1.7.0-openjdk-headless-1.7.0.141-2.6.10.5.el7.x86_64 rpm -e --nodeps java-1.7.0-openjdk-1.7.0.141-2.6.10.5.el7.x86_64 rpm -e --nodeps java-1.8.0-openjdk-headless-1.8.0.131-11.b12.el7.x86_64 rpm -e --nodeps java-1.8.0-openjdk-1.8.0.131-11.b12.el7.x86_64 tar -zxvf jdk-8u151-linux-x64.tar.gz mkdir -p /usr/java

typedef关键字

typedef是C语言的一个关键字,我们实际使用的时候可以理解成是一个绑定器,把若干标识符绑定在一起形成一个新类型,它是给编译器看的,编译器看到这个就直接将其当做一个新的类型看待了。当然了,如果有些人写的编译器并不是这么看待的,那就只能说明他对于C语言标准还没有彻底整明白。 1. typedef unsigned char u8; //u8就代表unsigned char类型了 举例: u8 var1;//定义了一个名为var1的unsigned char型变量。 2. typedef unsigned int u16; //u16就代表unsigned int类型了 举例: u16 var1;//定义了一个名为var1的unsigned int型变量。 3. typedef与define是不同的,因为typedef是给编译器看的,而define是给预编译器看的,编译器遇到typedef时就会按照一个新类型来处理一件事,而预编译器遇到define时仅仅只是替换。 #define u8Ptr unsigned char * //这里在预编译器眼里u8Ptr仅仅只是为了编程方便临时文本替换成unsigned char * 举例:u8Ptr p1,p2; //此时p1是指针类型变量,而p2是unsigned char型变量,这里足以数码u8Ptr仅仅只是文本替换。 思考:如果上面写成 #define U8PTR (unsigned char *)的形式,结果会怎么样? typedef unsigned char * u8Ptr; //u8Ptr就代表unsigned char *了,编译器把u8Ptr当做一个新类型,它就是unsigned char * 举例:u8Ptr p1,p2; //此时p1和p2都是指针变量,因此这足以说明u8Ptr是一个新类型,至少在编译器眼里就是这样的。 4. 思考下面代码是否有问题: typedef char * PSTR; char string[2] = "xy"; const char * ptr1=string;

VS2017+Qt5.12.0+PCL1.9.1开发环境配置过程详细记录

VS2017+Qt5.12.0+PCL1.9.1开发环境配置过程详细记录 文章目录 VS2017+Qt5.12.0+PCL1.9.1开发环境配置过程详细记录系统环境说明VS2017安装Qt5.12.0安装在VS2017上实现搭建Qt环境PCL1.9.1安装1.下载2.安装 重新安装VTK为其添加Qt支持1.下载对应版本的VTK源码 2.下载安装Cmake3.利用CMake生成VS工程2.在VS中编译VTK VS2017+Qt5.12.0配置PCL1.9.11.系统环境变量配置2.配置相关项目属性添加包含目录添加库目录添加预处理器定义设置SDL检查添加附加依赖项 PCL官方例程 系统环境说明 Windows 10 64位 VS2017安装 Visual Studio 2017采用Community(社区)版本,可前往微软官网下载:Visual Studio官方下载地址,可根据个人喜好选择安装路径,本人的安装路径为D:\ProgramFile\VS2017,仅供参考。 Qt5.12.0安装 Qt5.12.0可前往Qt官网下载Qt官方下载地址,选择的是Open Source版本。安装路径可依个人喜好选择,本人的安装路径为C:\Qt\Qt5.12.0,仅供参考。 在VS2017上实现搭建Qt环境 这需要在VS中,通过“工具->扩展和更新->联机->Qt Visual Studio Tools”,安装Qt Visual Studio Tools,并进行相关配置,网上有大量相关教程,此处不再赘述。 PCL1.9.1安装 1.下载 Point Cloud Library (PCL)可以在其Github网站上的发布页获取Windows下的安装包,链接如下:https://github.com/PointCloudLibrary/pcl/releases/tag/pcl-1.9.1 根据自己的编译器环境下载win64或者win32版本,本人下载的是64位版本的安装文件,即PCL-1.9.1-AllInOne-msvc2017-win64.exe和pcl-1.9.1-pdb-msvc2017-win64.zip两个文件。GitHub下载页面如下面两幅图所示: 2.安装 首先双击文件“PCL-1.9.0-AllInOne-msvc2017-win64.exe”进行安装,注意下面这一步建议选择第二个“Add PCL to the system PATH for all users”,它可以自动添加系统路径,不过也可以安装结束后自行添加。 选择安装路径时,如果选择默认文件夹“C:\Program Files\PCL 1.9.1”,则在VS项目属性中可以直接借用本人采用的项目属性配置文件,如果选择其他路径,也可以根据后面的讲解自行修改。 后面的步骤建议全部采用默认设置。安装快结束时会弹出安装第三方库OpenNI的提示,这里也可以全部采用默认安装设置,这样后续的VS项目属性配置中可以借用本人采用的属性配置文件,本人的OpenNI安装路径如下:C:\Program Files\OpenNI2。 OpenNI安装完之后点击确定后,PCL也就很快安装成功了。然后需要解压文件“pcl-1.9.1-pdb-msvc2017-win64.zip”,将解压得到的文件夹中的多个pdb文件(程序数据库文件)添加到PCL安装目录,如:C:\Program Files\PCL 1.9.1\bin。 PCL的安装到此结束。 重新安装VTK为其添加Qt支持 要想使用Qt为PCL项目制作UI,需要让Qt能够调用VTK生成的QVTKWidget组件,而“QVTKWidget”只有在VTK编译时添加了Qt之后才会生成,“PCL-1.9.1-AllInOne-msvc2017-win64.exe”安装包里的VTK是没有编译Qt支持的。要解决这个问题,可以在本地利用CMake重新编译VTK,并为其添加Qt支持。这一过程需要本地已经安装好Qt。 1.下载对应版本的VTK源码 PCL 1.9.1版本对应的VTK版本为8.1,VTK 8.1.0版本的源码可以通过其GitLab主页进行下载,https://gitlab.kitware.com/vtk/vtk/tree/v8.1.0,下载页面如下所示,选择“Download zip”,即可得到得到源代码压缩文件“vtk-v8.1.0.zip”。 在合适的目录建立3个文件夹,分别命名为: 1.vtk_SRC:将VTK的源码存放在此处,作为CMake的代码源路径 2.vtk_build:CMake创建工程的目标路径 3.vtk_install:编译后版本的发布路径 本人将上述3个目录建立在路径“D:\VTK_8_1_0”下,其中vtk_SRC目录如下图所示: 如果采用同样的目录进行vtk的安装,则在VS项目属性中可以直接借用本人采用的属性配置文件,如果选择其他路径,也可以根据后面的讲解自行修改。 2.下载安装Cmake 可以在CMake官网下载合适的Windows安装程序,对于64位Windows系统,可以进行如下选择: 按照默认设置安装即可。

centos7设置服务为开机自启动(以crond.serivce为例)

本文转自:https://blog.51cto.com/mrxiong2017/2084790 一、设置crond.serivice服务为开机自启动 步骤1:查看crond.serivce服务的自启动状态 [root@localhost ~]# systemctl is-enabled crond.service disabled 此时crond.serivce的自启动状态为disabled 步骤2:开启crond.serivce服务自启动 [root@localhost ~]# systemctl enable crond.service [root@localhost ~]# systemctl is-enabled crond.service enabled 列出所有的启动文件: systemctl list-unit-files 列出所有状态为enable的启动文件 systemctl list-unit-files | grep enable 关闭crond.serivce的自启动状态 systemctl disable crond.service 二、开启和关闭crond.service服务 步骤1:查看crond.service的启动状态 systemctl status crond.service 开启crond.service服务命令 systemctl start crond.service 停止crond.service服务命令 systemctl stop crond.service 转载于:https://www.cnblogs.com/yadongliang/p/10727981.html

如何修复Windows系统上出现的无法访问Internet错误问题

让我们先快速概述一下步骤,然后我们将详细介绍每个步骤: 确认其他设备无法连接 重新启动电脑 重新启动调制解调器和路由器 运行Windows网络疑难解答 检查您的IP地址设置 检查您的ISP的状态 尝试一些命令提示符命令 禁用安全软件 更新无线驱动程序 重置您的网络 这个错误是什么意思? 在我们继续之前,我们应该在您看到此错误时解释网络上究竟发生了什么。为此,有必要解释家庭网络的一些基础知识。 当您使用笔记本电脑等无线设备时,它会连接到您的路由器。路由器是一种处理家庭设备之间连接的设备。您的路由器插入调制解调器,这是一种桥接家庭网络和互联网流量的设备。 当您在计算机上看到已连接,无法访问互联网 或类似错误时,表示您的计算机已正确连接到路由器但无法连接到互联网。相反,如果您看到未连接,没有互联网或没有互联网连接消息,则表示您的计算机根本没有连接到路由器。 步骤1:确认其他设备无法连接 在进行任何故障排除之前,确定是否只有您的PC出现问题非常重要。抓住您的手机或同样位于Wi-Fi上的其他计算机,看看它是否已连接。在Android上,您会在Wi-Fi符号上看到一个X图标,并注意到您已连接到移动网络。iOS用户可以访问“设置”>“Wi-Fi”并检查“ 无Internet连接”消息。 如果您的计算机是唯一无法连接的设备,则可能是由于该设备上的配置设置错误。但如果您无法在线获取任何信息,则问题在于您的网络设备,因此您可以跳过下面的一些仅限PC的步骤。 在继续操作之前,如果问题影响到您的所有设备,则应执行快速测试。断开将调制解调器连接到路由器的以太网电缆,并使用它将PC连接到调制解调器。如果您可以使用此设置联机,则问题出在您的路由器上。如果您继续执行以下故障排除而无法解决问题,则路由器可能存在故障。 第2步:重新启动您的PC 与许多问题一样,重新启动计算机是您应该尝试的第一个故障排除步骤。如果你很幸运,你可以通过重新启动来解决一些暂时的故障。 第3步:重新启动调制解调器和路由器 由于大多数网络问题涉及您的调制解调器和/或路由器,因此重新启动它们是有道理的 但是,不要像使用计算机那样通过界面重新启动它们。只需从两个设备上拔下电源插头,然后将其拔下一两分钟。 首先插入调制解调器,让它启动,然后再次插入路由器。等几分钟让他们整理出来。在执行此操作时,请确认您的路由器和调制解调器是否正常工作。如果您在其中一台设备上看不到任何指示灯,则可能是硬件坏了。 请注意,您正在重新启动,而不是重置设备。重置意味着将设备恢复为出厂默认设置 - 您还不需要这样做! 第4步:运行Windows网络疑难解答 如果您的Windows PC出现问题,则计算机的网络设置出现问题。虽然内置的Windows疑难解答通常无法解决问题,但在继续之前值得一试。 要访问网络疑难解答,请访问设置>网络和互联网>状态。选择网络疑难解答,然后按照步骤查看Windows是否可以解决问题。在Windows 7上,您可以在“ 开始”>“控制面板”>“故障排除”>“网络和Internet”>“网络连接”中找到相同的工具。 第5步:检查您的IP地址设置 接下来,值得检查以确保您的计算机具有有效的IP地址。在正常情况下的大多数家庭网络中,路由器在连接时向设备分发地址。如果您的计算机的IP设置不正确,则可能导致您遇到的问题。 在Windows 10上,右键单击系统托盘中的网络图标,然后选择“ 打开网络和Internet设置”。单击“ 更改适配器选项”条目,然后双击您正在使用的连接。 第6步:检查您的ISP的状态 此时,如果您无法在线获取任何设备,则值得检查您的互联网服务提供商(ISP)是否存在问题。虽然这种情况很少见,但这可能就是您无法上网的原因。 使用手机的数据连接查看您所在地区提供服务的人是否报告过停机。 第7步:尝试几个命令提示命令 Windows 在命令提示符中具有多个网络命令。你应该尝试其中一些,看看他们是否能解决你的问题。在“开始”菜单中键入cmd,然后右键单击它并选择“以管理员身份运行”以打开提升的“ 命令提示符”窗口。 要重置Windows保持访问Internet的某些文件,请使用以下两个命令: netsh winsock resetnetsh int ip reset 如果这不起作用,请尝试释放计算机的IP地址,并使用这两个命令逐个获取一个新的: ipconfig /releaseipconfig /renew 最后,使用以下命令刷新计算机的DNS设置: ipconfig /flushdns 此时再次重启PC并没有什么坏处。如果您仍无法上网,还可以尝试其他一些步骤。 第8步:禁用安全软件 另一个不常见但似乎有道理的情况是,您的PC上有一些安全软件阻止访问互联网。 禁用您可能已安装的任何第三方防病毒应用程序,并查看您的连接是否恢复。虽然我们讨论的是安全问题,但值得对恶意软件进行扫描。恶意程序可能会破坏您的互联网连接。 第9步:更新无线驱动程序 通常,您不需要更新计算机驱动程序,因为这样做通常会导致更多问题而不是它的价值。但是,由于您仍然遇到问题,因此应检查驱动程序更新。