Binary XML file line #0: Error inflating class TextView

catch exception:android.view.InflateException: Binary XML file line #0: Error inflating class TextView at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:714) at android.view.LayoutInflater.rInflate(LayoutInflater.java:756) at android.view.LayoutInflater.rInflate(LayoutInflater.java:759) at android.view.LayoutInflater.inflate(LayoutInflater.java:492) at android.view.LayoutInflater.inflate(LayoutInflater.java:397) 这个问题花了2个小时…,AndroidStudio的提示坑了,行数都没有指对。 问题是因为textview 的背景引用了一个shape,但是这个shape放在了drawable-21文件夹下。导致在Api 19上直接崩溃。 当然这种崩溃可能还有其他原因,我这个算是比较坑的了,一般可能因为你在xml中使用了某些attribute但是只在高API才会生效也会报这个错,或者自定义的view中出现了问题。

WIN7自定义管理员账户无法创建或使用设备

主题: 拥有管理权限,不一定等同于管理员, 都是安全策略捣的乱 出现问题的条件: 1)自定义属于Administrators组的用户登录win7 2)安装了一台USB 数据采集器,且驱动程序正常 现象: 运行厂家自带的测试软件出现: CreateDevice Error! 解决方案: 1)启用Administrator用户登录,运行正常 2)改用具有属于Administrators组的用户登录,问题依旧 最终解决方案: 1)打开本地安全策略,将 以管理批准模式运行所有管理员 改为禁用 2)重启电脑,以自定义用户登录,运行正常

linux内存映射 mmap munmap

我之前接触过windows下的内存映射文件,当时接触那个主要是要用它来实现程序crash之后的现场恢复。能恢复部分需要恢复部分内存的数据,这个时候内存映射文件就体现了作用,将需要的内存数据放到映射文件上,这样就可以实现了部分内存的持久化了,当然性能也是有很大的损失的。 现在有一个需求,需要linux的进程在遇到突发意外的时候能够恢复现场,读取之前的内存,这样意外重启之后能够让用户最小的损失体验。这种需求到我手上的时候,我自然想到了以前我在windows下的积累的经验,肯定有对应的内存映射来处理,我网上找了一下,自然有一个mmap来实现我所说的。一下我官网翻译了一点,并且加上了自己的理解总结了mmap的东西,作为马上要开展的工作的准备,具体能不能实现我也不太清楚 Name mmap 的英文名是map files or devices into memeory 英文名很好的解释了他的含义,比中文名更好的理解,他是将文件映射到内存上,我们可以读写内存一样来读写这个文件 定义 #include <sys/mman.h> void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);//用来 int munmap(void *addr, size_t length); mmap() 该函数可以从创建进程的的虚拟内存中创建一个映射。 参数: addr 指定我从虚拟内存中创建映射的其实地址,使用的时候一般设置成NULL length 指定我创建内存映射的内存长度 prot 这个指定我创建内存映射使用进程的对该内存的权限,可以有多个权限。PROT_EXEC,PROT_READ,PROT_ERITE以及PROT_NONE意思很简单,对应的执行,读,写权限。这个模式权限不能跟你对应的文件相冲突,如果这边配置可写,但是打开的文件是不可写,就会出现问题 flag 指定映射对象的类型,有很多含义。这个文件主要用来设置该映射文件的所属进程,以及其余进程打开这个文件的权限设定 例如WAP_SHARED 当进程对这个映射区域写入数据会复制到文件内,并且其他进程可以读取修改的数据,当然这个是我需要的。 fd 这个指定我内存映射关联的物理文件,一般是一个文件打开的句柄,fopen文件的时候的返回值。 offset 被映射文件的偏移值,这个可以直接填0 返回值 如果成功,mmap返回一个指向已经映射的内存区域首地址。如果错误返回MAP_FAILED((void*)-1),错误可以通过errno来查询错误。 应用场景 目的:内存的持久化 现场环境:一个比较大map需要内存持久化,map里面有指针。直接拷贝内存不可行。并且该map命中率较高,更新频繁,但是保持定时更新。持久化村是内存不需要实时持久化。 计划实现: 1.创建映射文件 进程内创建映射文件,并且保持可读写,并且落地到相关文件中,独立该文件到IO操作并不大的盘符 2.实现 启动定时器,定时器中将map内存连续化,即转换json,将json写入到内存映射中 3.启动进程 读取内存映射,并且解析,读入到map中,实现现场的恢复 官方例子 #include <sys/mman.h> #include <sys/stat.h> #include <fcntl.h> #include <stdio.

Spring boot-应用打包部署

1、Spring Boot内置web Spring Boot 其默认是集成web容器的,启动方式由像普通Java程序一样,main函数入口启动。其内置Tomcat容器或Jetty容器,具体由配置来决定(默认Tomcat)。当然你也可以将项目打包成war包,放到独立的web容器中(Tomcat、weblogic等等),当然在此之前你要对程序入口做简单调整。 对server的几个常用的配置做个简单说明: # 项目contextPath,一般在正式发布版本中,我们不配置 server.context-path=/myspringboot # 错误页,指定发生错误时,跳转的URL。请查看BasicErrorController源码便知 server.error.path=/error # 服务端口 server.port=9090 # session最大超时时间(分钟),默认为30 server.session-timeout=60 # 该服务绑定IP地址,启动服务器时如本机不是该IP地址则抛出异常启动失败,只有特殊需求的情况下才配置 # server.address=192.168.16.11 Tomcat Tomcat为Spring Boot的默认容器,下面是几个常用配置: pom.xml依赖配置: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <!--<scope>provided</scope>--> </dependency> # tomcat最大线程数,默认为200 server.tomcat.max-threads=800 # tomcat的URI编码 server.tomcat.uri-encoding=UTF-8 # 存放Tomcat的日志、Dump等文件的临时文件夹,默认为系统的tmp文件夹(如:C:\Users\Shanhy\AppData\Local\Temp) server.tomcat.basedir=H:/springboot-tomcat-tmp # 打开Tomcat的Access日志,并可以设置日志格式的方法: #server.tomcat.access-log-enabled=true #server.tomcat.access-log-pattern= # accesslog目录,默认在basedir/logs #server.tomcat.accesslog.directory= # 日志文件目录 logging.path=H:/springboot-tomcat-tmp # 日志文件名称,默认为spring.log logging.file=myapp.log Jetty 如果你要选择Jetty,也非常简单,就是把pom中的tomcat依赖排除,并加入Jetty容器的依赖,如下: <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jetty</artifactId>

c语言中如何使用true和false

在C99之前,我想很多人都是自己定义bool类型,以及true和false的值, 比如typedef int bool或者#define bool int #define true 1 #define false 0 在C99出来后,没必要这样做了, C99定义了一个_Bool的类型, 你可能会问了,为啥不是bool,如果想用bool的话,也可以,C99提供了头文件stdbool.h,包含即可, 我们可以看下stdbool.h里怎么写的, #ifndef _STDBOOL_H #define _STDBOOL_H #ifndef __cplusplus #define bool _Bool #define true 1 #define false 0 #else /* __cplusplus */ ... #endif ... #endif 这样你就明白了。

eclipse屏蔽xml文件报错

eclipse会自动去验证xml文件的语法格式是否正确,但是有的时候我们写的xml文件正常运行,可是文件上总是报错,这个时候可以关闭eclipse内的验证! 1.菜单【Windows】 -【Preperences】-【Validation】 2.在右边找到“XML Validator”,把取消【Bulid】复选框的选中状态,保持【Manual】 的选中状态,因为我们最后还需要确保XML的正确性,这个可以通过选择XML文件,在右键菜单中选择【Validate】手工来验证,如果XML有错,会弹出窗口提示,但如果把【Manual】复选框也取消的话,再手工验证,即使XML真有错,也不会正确提示。

logstash使用之日期处理

概述 日期插件Date filter plugin用于对logstash接收到的字段中的日期进行处理,可以使用处理后的日期作为logstash的timestamp. 日期进行处理后,可以在kibana中用于统计和分析. 参考 logstash帮助文档 简单使用 input{ stdin{ } } filter{ date{ match => ["message","yyyyMMdd"] } } output{ stdout{codec => rubydebug} } 从标准控制台接收输入使用date插件过滤,这里是一个简单的配置,使用match对message字段中的内容进行时间转化,默认将转化后的结果放到了@timestamp中.使用标准控制台输出,输出使用了rubydebug插件,目的是输出调试结果看起来方便,内容也全面一些. 使用效果: 20171124 { "@version" => "1", "host" => "localhost", "@timestamp" => 2017-11-23T16:00:00.000Z, "message" => "20171124" } 20171120 { "@version" => "1", "host" => "localhost", "@timestamp" => 2017-11-19T16:00:00.000Z, "message" => "20171120" } 如上,20171124和20171120是控制台输入的,其余内容时rubydebug插件输出的内容.可以看到: * 输入的内容默认保存在了message字段中 * @timestamp随着message中的日期而改变了. * @timestamp虽然改变了,但是和设置的时间不一样. date插件默认的是将时间转化为 Zulu/UTC标准时间,也就是说,上面的时间我设置的是20171120,指的是当前时区的时间的20171120 00:00:00 但是,到了logstash中,被转为标准时间,也就是当前时区的时间-8小时,为20171119 16:00:00. 选项 date插件特有的选项如下:

logstash配置之自动重载配置文件

自动重新加载配置 为了可以自动检测配置文件的变动和自动重新加载配置文件,需要在启动的时候使用以下命令: ./bin/lagstash -f configfile.conf --config.reload.automatic 默认,检测配置文件的间隔时间是3秒,可以通过以下命令改变 --config.reload.interval <second> 如果已经运行了没有提供自动重启的logstash,可以发送一个挂起命令给logstash重新加载配置文件: kill -1 <pid> 配置文件自动重载工作原理 检测到配置文件变化通过停止所有输入停止当前pipline用新的配置创建一个新的管道检查配置文件语法是否正确检查所有的输入和输出是否可以初始化检查成功使用新的pipeline替换当前的pipeline,检查失败,使用旧的继续工作. 在重载过程中,jvm没有重启. 注意事项 stdin输入插件不支持自动重启.syslog作为输入源,当重载配置文件时,会崩溃.请看: https://github.com/logstash-plugins/logstash-input-syslog/issues/40

logstash使用之json输入输出

概述 如果发送给logstash的数据内容为json格式,那么可以通过解析json内容,根据具体内容生成字段.方便分析和储存,比如: 有一个json内容为: {"name":"nihao"},我们需要获取这个记录然后通过logstash分析后,放到mysql数据库中. 一个简单的logstash输出内容为: { "@version" => "1", "host" => "localhost", "@timestamp" => 2017-11-23T08:40:16.868Z, "message" => "{\"name\":\"nihao\"}" } 也就是说,如果存到数据库中,会保存以上四个字段到表中,而我们的记录的内容被简单的记录到message字段中,如果我们需要分析这条 记录,还得自己取出来进行处理. 如果使用了logstash的json解析,那么会是这个样子: { "@version" => "1", "host" => "localhost", "@timestamp" => 2017-11-23T08:40:16.868Z, "message" => "name=nihao", "name" => "nihao" } 这样存到数据库中就多了name字段,分析这条记录的时候只要取出来就可以.如果不想要message字段,也可以省去: { "@version" => "1", "host" => "localhost", "@timestamp" => 2017-11-23T08:40:16.868Z, "name" => "nihao" } json输出 如果将一个输入的记录处理后,输出为json串: 比如输入: “nihao”, 那么输出的结果为: {"@version":"1","host":"localhost","@timestamp":"2017-11-23T09:42:14.798Z","message":"nihao"} 配置信息如下: input { stdin{} } output{ stdout{ codec => json } } 除了输入的内容外,还添加了一些额外的信息.

libevent http server multithread

Libevent是一个轻量级高效的开源高性能网络库,很多公司都基于该网络库进行开发,我之前参与过的几个的项目客户端的网络底层以及服务端的网络库都是基于该网络库的开发,并且取得良好的性能,并未遇到明显的性能瓶颈。我相信很多大公司也是跟我一样做出相同明智的选择。因此,基于该库进行一系列的扩展也是理所当然。前几天我们客户提出了需求,需要服务器提供http服务,以便接受各种http的请求,这种http请求有其特殊性,一般是短链接,瞬间流量较大,需要抵抗瞬间峰值流量。因为我们服务器是基于libevent的开发,很自然想到了利用libevent的原始库进行支持,因为他底层是支持http服务器的一些接口,很自然写起来代码。传统的代码还是类似的写法,都是基于单线程的,意思是说,一个线程监听在ip以及对外开放的http端口上。伪代码如下: short http_port = 8081; char *http_addr = "127.0.0.1"; if (argc > 1) { strcpy(filename,argv[1]); printf("Using %s\n",filename); } else { strcpy(filename,DEFAULT_FILE); } struct event_base * base = event_base_new(); struct evhttp * http_server = evhttp_new(base); if(!http_server) { return -1; } int ret = evhttp_bind_socket(http_server,http_addr,http_port); if(ret!=0) { return -1; } evhttp_set_gencb(http_server, generic_handler, NULL); read_file(); load_file(base); printf("http server start OK! \n"); event_base_dispatch(base); evhttp_free(http_server); 以上基本上能满足很多初级用户需求,也是在网上能找到最多的处理方法,但是并不能得到大多数用户满意,因为跑在一台32核,带宽千兆的一台服务器上,只有一个线程接受前端大量的http请求,是一种浪费,也不能给发薪水的老板交代。所以很自然我想到要提高性能,以便抵抗更大的http请求的压力。我的设想是这样的,前端多个线程监听http的端口上,接受各种http的请求,一旦有新的http请求来了,其中一个线程立即接受处理,并且解析请求的性质以及请求的合法性。处理好之后,立即交给一个任务线程池,待任务线程处理好任务之后,立即返回给原线程处理以reply给http请求的客户端。如下图所示: 之所以这样设计的原因是因为 1. 多个线程监听在这个端口上,可以达到同时能处理多个http请求,而不像单线程的条件,同时只能处理一个http请求 2. 当一个线程处理http请求时候,解析数值,交出任务给任务处理线程之后,马上可以接着处理新的http请求,这样加大了http请求的处理性能 这两点是我认为可以大幅提高处理http请求性能的关键所在,所以势必要修改老的逻辑处理方式,我认为做到我说的目的,有两个难点 但是我的做法有两点比较麻烦 第一:如何利用多线程监听同一个端口上,而不至于出现线程错误。

Fabric 远端 批量部署

公司有二十多台服务器,每次到了版本发布的时候,非常辛苦,一台台去拷贝可执行程序,然后一台台改配置,之后一台台检测校验程序的正确性,最后一台台启动上线,这是一件非常繁琐和枯燥的事情。对于一两台机器这个工作量倒没什么,但是如果批量到了几十台的基础上,对于部署人员是一个不小的挑战,要保证重复操作20次不错,其实是一件很难的事情。那么批量远端部署成了一件有必要去完成的事情。这就引入了fabric工具。这个工具最大的好处是基于ssh以及python做的开发,对于远端linux机器,不需要装任何客户端可以直接兼容,基本上支持ssh的机器都可以进行远端控制。当然,任何东西不会完美,他也有一些问题,正是因为是基于ssh的处理,所以他的效率并不是很高,并不适合大批量的机器多端部署,体量应该在100台之内没啥问题。 下面简单介绍一下Fabric以及其入门 一.依赖库安装: 主机作为Fabric的使用端是基于Python的,官方要求版本2.7以上,我是使用2.7.5,亲自测试过好用,但是在一台2.7.3机器上出现了python的一个库不存在,我并没有去深究,应该是版本的问题。可以通过python -V来查看自己的python版本。如果报错的,那就是python,我们先安装python。如果出现问题的需要安装python,yum install python。 由于fabric源码是在git库上的,我们还需要安装一个git。检测git是否安装成功git –version,这里对git的版本没有要求,只需要可以安全下载代码即可。 二.下载源码: 两个依赖库安装好之后,就可以下载源码了,源码路径在https://github.com/fabric/fabric git clone https://github.com/fabric/fabric.git 我们会看到git下载下来的fabric目录,进入这个目录,通过python这个命令执行setup脚本。$python setup.py develop 或者可以yum install fabric也可以用来执行安装(yum安装会默认给你安装好Paramiko) 完成上面几步之后,我们基本上是安装好了。如何是否安装成功,执行这个命令fab -V。如果出现版本就说明安装OK了。否则得退回去一步步查到底哪里出现了问题。 安装OK那么接下来就开始实际操作 三.使用: 什么东西都从hello world开始。我们创建一个python文件。这个文件名有一定的要求,默认必须要fabfile.py。否则会出现找不到fabfile.py的提示。这个文件主要执行在本地完成shell命令,简单代码如下 fromfabric.api import local defhello(): local('ls-l /home/bjhee/') 如何执行,直接可以 fab hello 这个命令很简单,fab是默认打开fabfile.py文件,执行hello任务。如果想后面带入参数也可以,例如 fromfabric.api import local defhello(name1, name2): print"%s and %s say Hello Fabric!" % (name1, name2) 看到现在为止,肯定有人有疑惑,这样的意义是什么,关键是如何在远端执行脚本,因为多机部署的关键还是远端控制 远端并再使用适用刚刚提到的fabric.api的local库,而是使用fabric.api的run这个库,并且在这个文件前,要定义我需要远端的机器名,如果之前配置好代理跳转,并且首次成功跳转的条件下,可以直接ssh过去,而不需要输入用户名密码。否则需要输入用户名密码,整体语法如下(我这里加入了密码身份验证信息,以便密码用户可以直接使用): fromfabric.api import run, env//使用fabric.api的run库和env库 env.hosts= ['10.10.10.10', '10.10.10.11']//指定服务器的列表,可以是域名,也可以是ip env.user= 'userecho'//身份验证的用户名 env.password= 'hock'//身份验证的密码 defhello(): run('ls -l /home/userecho/')//run表示在远端执行ls -l 等命令

H2数据库连接缓慢,无响应

jdbc:h2:tcp://localhost:9092/D:/db;MULTI_THREADED=1;DB_CLOSE_ON_EXIT=FALSE;MVCC=TRUE 项目中遇到h2数据库800M后页面无响应,用Dbever工具连接h2数据库文件没有任何异常,仔细查询项目代码后发现是因为我们首页有糟糕的sql,在数据量大时耗时3分钟以上,默认h2是单线程模式,在有耗时sql执行时,所有后续查询都排队等候导致页面长时间无响应 可加入以下参数解决,后两个可根据需要取舍; MULTI_THREADED:默认下为0(禁用),也就是说无论你连接池开多大,sql执行都是单线程串行执行,当有一个耗时sql执行时,其他连接的sql一样要等候,改为1开启多线程模式,不会导致耗时sql影响其他查询,不过文档描述此参数目前是实验性的,稳定性还不得而知 DB_CLOSE_ON_EXIT:退出时关闭数据库默认为TRUE,默认值存在的问题是当程序退出时可能会有一些日志记录,或者清理数据库的操作,此时数据库先关闭会报错:database already closed! MVCC=TRUE:多版本并发控制,默认为false,开启后并发更新不会采用老式的加写锁模式,会改为读锁,更新的操作都会带着自己要更新的值与更新前值的版本号,当版本号对应时更新成功同时修改值对应的版本号,其他并发的数据再来时因为所持有的版本号已经不对应,所以会更新失败,类似于java的乐观锁机制,目的就是容忍小部分的失败换取更大的吞吐量(没有锁的上下文切换换耗时)

大型场景裁剪渲染

原文: http://nvidia.e-works.net.cn/document/200908/article8917.htm 3D游戏特别是网络在线游戏中,室外大场景渲染是一块非常重要的内容,它也是3D图形引擎的核心。它是图形学和图像处理理论最直接的应用,其涉及的技术还可以应用于其它领域,比如虚拟现实、3D GIS、数据可视化等,其重要性不容置疑。随着硬件的不断发展,行业对渲染场景的规模和真实感提出了更高的要求。 第一章 绪论 1.1概述 众所周知,近几年以电子游戏为主的计算机互动娱乐产业迅猛发展,已成为国民经济的重要组成部分。然而,由于我国的软件业起步较晚,3D游戏的核心技术被欧美、日韩等牢牢占据。如何掌握相关核心技术已成为中国电子娱乐产业的当务之急。 室外场景渲染是指对户外所有景物的真实绘制,相对于室内场景渲染,它更为复杂。在3D游戏特别是网络在线游戏中,室外大场景渲染是一块非常重要的内容,它也是3D图形引擎的核心(见图1.1)。游戏引擎中大场景的渲染技术是图形学和图像处理理论的最直接应用,其涉及的技术还可以应用于其它领域,比如虚拟现实、3D GIS、数据可视化等,其重要性不容置疑。 1.1.1室外场景渲染研究的内容和难点 真实感的室外场景除包括地表的基本几何形状绘制,还包括地表上的生物如:草、岩石、树等的渲染以及对光影效果的表现。其中的难点主要在大规模地表的数据处理和真实感的仿真。地形场景中模型图元的数量是以场景大小平方的速度增长的。一个8193×8193维数的地形,如果不考虑减低细节程度和裁剪,绘制一帧将要渲染128M个三角形,这样的三角形量在PC级别的机器上目前还是远不能实现交互式帧率的。所以,如何减少渲染地形的图元数目一度成为室外场景实时渲染的关键问题。随着硬件技术的发展,每秒钟处理上亿个三角形已不再困难。很多计算如几何变换和光栅处理都可以交给GPU去计算。在GPU数据吞吐量很大的情况下,如果~个算法在剔除渲染图元的过程中占用了太多CPU资源,出现GPU等待CPU的情况,那么即使算法在剔除多余顶点方面做得很好,总体绘制效率也不是高效的。所以在目前的显卡硬件架构下,能充分发挥CPU与GPU性能,消除局部效率瓶颈的算法才是最好的算法。 在真实感仿真上,比如对草丛的模拟,如果全部用细节三角形面片,那即使一片草地需要渲染的三角形个数也是难以想像的。目前对物体细节的表现还主要是运用纹理贴图的方式来实现。光影效果的表现涉及局部光照模型、全局光照模型、光照贴图、阴影生成等相关算法和技术。 1.1.2国内外技术发展历程和现状 在国外,3D游戏中场景渲染技术的发展大致可以分为三个阶段: 三维真实感场景渲染领域的研究在国外起步很早,很多相关算法在80—90年代就已提出,并建立了非常严密的理论体系。比如对场景渲染非常重要的多边形LOD算法,场景空间管理的BSP、四叉树、八叉树等算法,光照模型,阴影算法等。但是这些算法在资源有限的微机上受到各方面限制。当时的这些算法还仅限于在大型机和图形工作站上实现。 92年,随着ID Soft公司一款游戏Quake(雷神之锤)的发布,标志着第一款支持多边形模型、动画、粒子系统的全三维游戏在个人计算机上正式诞生。在随后发布的QuakeII、Unreal、Half Life等游戏中,场景渲染相关的LOD技术、BSP空间管理技术、光照贴图、凹凸贴图、多重贴图等相继应用在3D游戏中。随后出现的Quake、Unrea]游戏引擎,更是标志着3D游戏引擎技术走向成熟。 现阶段,随着显卡技术的发展,GPU不但支持标准的(固定的)变换与光照(T&L)管道线,还支持顶点着色(vertex shader)和像素着色(pixel shader) 方式,开发人员因此有了更大的自主空间,可以实现更真实的绘制功能。在此环境下,各大公司都着手开发新一代3D游戏引擎。其中商业引擎以QuakeIII、UnrealII最为出名。此外,软件开源社区的不断壮大,也诞生出一些比较好的开源3D引擎,比如OGRE等。运用这些引擎中的场景渲染技术能生成真实感更强的水波、天气系统、茂密的森林、流熔岩的火山等效果,场景的规模也更大,顶点动态光照技术也开始在室外场景中应用。 3D游戏的趋势是往超大规模场景,真实感表现的虚拟世界发展。大规模场景表现和游戏的虚拟仿真,自然也成为了世界上3D游戏行业非常热门和前沿的研究领域与方向。比如美国暴雪公司的“魔兽世界"和韩国NCSOFT公司的“天堂2"已经在这两个方而取得了相当的突破和进展。暴雪的“魔兽世界"按人的比例来计算,世界地图已达到35km×35km。 随着电子娱乐业的迅猛发展,国内目前从事3D引擎研究和开发的公司也多了起来。比如目标软件的GFX3D引擎,盛大公司的3D引擎,网易公司的3D引擎,锦大科技的AURORA引擎等,还有一些游戏工作组的3D引擎,比如WIN3D系列,Origo系列,TUAM9系列引擎等。但总体上来说,国内还处在使用和模仿优秀引擎的阶段,很多都是在国外优秀引擎上做一些延伸。真正严格意义上自主开发产品还几乎没有,或者说自主开发产品的质量和欧美日韩还有一定差距。这种差距在一定程度上反映在3D大场景渲染技术方面,因此深入的展开这方面的研究十分必要。 1.2课题研究的目的 本课题希望通过剖析多款成熟3D游戏、引擎,对3D引擎的核心部分一室外场景渲染技术进行探讨,并设计和实现自己的一些方案,给我国商业游戏引擎的开发带来一些启示。 1.3论文的篇章结构 本文本着注重实际应用的前提,通过剖析开源3D引擎并运用推测验证的方法,对室外场景渲染的主要技术进行了研究和实现,在很多章节也提出了自己的方案和优化方法。以下对各章的内容进行简要描述。 第一章绪论。介绍3D室外场景渲染的基本概念,介绍国内外在这一领域的研究现状,阐述课题的意义和研究内容。 第二章介绍3D图形渲染的基础知识,包括图形渲染的原理、流程以及实现图形渲染可以应用的类库OpenGL。 第三章研究室外超大场景地形网格的生成与简化算法,比较各种基于LOD思想的网格简化算法的优劣,提出基于几何多重映射(GeoMipMap)的地形绘制优化方案,并得以实现。研究也涉及到地形的空间管理算法、可见性剔除算法、超大场景的数据加载方式研究等。 第四章研究场景的真实感渲染技术。主要涉及应用多层纹理混合贴图模拟融合性地表技术,室外场景的光影效果处理技术,天空、树、草、雾等的渲染方案和技术。 第五章描述本设计实现的室外渲染软件Demo OSRender,以及程序编写过程中可用的优化技术。 第六章对全文进行总结,介绍开题论文的完成情况,客观评价优点和不足,并给出改进的方向。 第二章 3D游戏场景渲染的基础知识 室外场景渲染从基本原理上来说可以分为两类:基于体素的渲染方法和基于多边形的渲染方法。早期的3D游戏,如三角洲特种部队就是采用的体素渲染法。体素法类似光线跟踪渲染,它从屏幕空间出发,找到地形与屏幕像素发出的射线交点,然后确定该像素的颜色。这种方法不依赖具体的图形硬件,整个渲染过程完全使用CPU处理,因此它不能使用图形卡硬件来加速,并且对于一个场景来说,往往不只是地形,还有其他使用多边形描述的物体,体素法渲染的图像很难与硬件渲染的多边形进行混合,因此这种方法现在用得极少,而多边形渲染方法则成为一种主流。选择多边形来描述和渲染地形有很多优点,最主要的是它能够很好地使用硬件加速,并且能够和其他多边形对象一起统一管理。因此本课题仅对基于这种多边形面片的场景渲染技术进行研究。 2.1基于多边形面片的3D渲染原理 2.1.1基于多边形面片的图形绘制流程 用多边形面片来建立物体的三维模型有容易表示、计算简单、容易绘制几个方面的好处,因此在游戏三维图形渲染中被广泛采用(通常是三角形面片)。从模型的顶点送入渲染管道到最后形成二维图像的过程如下图2.1所示: 2.1.2变换 渲染管道中大部分工作是把对象模型的顶点在一个坐标系中的表示转化为另一坐标系中的表示,一般需要经过模型变换和相机变换两个过程。 通常,几何模型被保存在自身的建模空间,即每个模型拥有单独的局部坐标系统。为了建立场景几何关系,模型将统一放置到世界坐标系中,从建模坐标系变换到世界坐标系叫模型变换。几何模型的最终成像是在摄像机坐标下,将场景物体从世界坐标系变换到摄像机坐标系叫相机变换。相机的外部参数决定了相机坐标系,因此场景在屏幕上的成像位置与形状和相机的外部参数有关。模型和相机变换采用4×4齐次矩阵表示,其形式如下: 比如平移变换可表示如下: 点(x,y,z)平移(tx,ty,tz)后的坐标为(x",y",z")。此外还有旋转、缩放变换,这三种基本的变换可以合成任意几何变换。 通常把模型变换和相机变换的矩阵复合成一个矩阵处理,便于提高效率。在所有的图形绘制库中,都提供了程序接口供应用程序设置模型和相机变换对应的矩阵。其中,模型变换由场景物体的平移和旋转、缩放变换组成,相机变换则通过设置相机的位置、相机方向和向上向量来决定。 2.1.3裁剪 相机的参数包括投影方式、近平面、远平面、视野和屏幕的长宽比率,它们决定了物体从相机坐标系投影变换到屏幕坐标系的位置。这些参数实际上定义了一个视域四棱锥,也叫做视锥体。 位于视锥体之外的场景部分不需要送入后续阶段处理。因此,对完全位于规一化的设备空间之外的几何元素,可简单地舍弃。而部分位于规一化的设备空间之外的几何元素则需要进行裁剪操作。由于裁剪的面就是立方体的6个表面,实现起来非常简便。应用程序也可以定义额外的平面对场景进行裁剪。视域裁剪通常由底层图形AP]自动完成。注意这里所说的裁剪是比后面章节要介绍的视锥体剔除更底层的裁剪。 2.1.4投影 把三维物体变为二维图形表示的过程称为投影,其又分为平行投影和透视投影。透视投影是所有投影线交于投影中心;而平行投影是投影线平行,投影中心在无穷远。在游戏虚拟场景模拟中主要应用透视投影。透视投影可分为一点透视、二点透视和三点透视。 针对一点透视投影如下图: 从上图P点在观察平面上的投影我们可以得到描述尸点的参数方程: 2.1.5光栅化 从顶点组成的几何模型变换到像素的过程称为光栅化(Rasterization)。它的机理与得名来源于CRT显示器的电子枪发射方式。光栅化可分为四个子阶段,即消隐、逐像素光照明计算、纹理映射和颜色融合。 (1)消隐 消隐的目的是解决场景的可见性问题。所谓可见性计算,是指计算物体投射到投影平面如果有交叠,观察者应该看到哪个投影点。图形学中经典的解决方案是物体空间Z一缓冲器算法和图像空间的光线跟踪算法。由于Z-缓冲器算法易于在图形硬件中实现,逐渐演化称标准的图形硬件消隐技术。在深度缓冲器中,每个像素上始终保留最接近视点的深度。当光栅化产生新的像素后,该像素的深度和保存在深度缓冲器的像素深度进行比较,如果小于已有的像素深度,则用像素的颜色和深度替换分别保存在颜色缓冲器的像素颜色和深度缓冲器中的像素深度,反之保持不变。在绘制之前,深度缓冲器必须初始化为最远的深度,以保证可见性计算的正确性。 (2)光照计算 光照计算影响物体的外观。进行光照计算的几个要素包括光源位置、光源属性、光照模型、物体表面材质属性、纹理和物体表面几何属性(包括法向、微几何结构)等。最简单的光照明计算技术是在物体建模时指定每个顶点的颜色和纹理坐标,在绘制时直接利用颜色和纹理映射融合为最终颜色。这种方法称为平坦渲染(Flat shading)模式,它的速度快,但效果欠佳,是早期游戏中最常用的技术。 真正意义上的光照计算必须指定每个光源本身的属性,包括光源的类型(点、线、面光源)、位置和光源的漫反射/镜面反射的颜色,然后根据光照模型(分局部光照明模型和全局光照明模型,前面所述直接指定顶点颜色的方法可看作最简单的局部光照明模型)在物体的每个顶点计算每个光源对该顶点的光亮度贡献,最后在光栅化层插值顶点上的颜色。这种处理模式称为Gouraud渲染模式,著名游戏guakeEi就使用了Gouraud渲染模式。 逐顶点的光照计算对应于Gouraud渲染模式,而逐像素光照计算则对应于法向渲染模式(也称为Phong渲染模式)。Phong模式在游戏场景渲染中也被广泛采用。在游戏三维引擎设计中,必须根据图形硬件配置和场景复杂度选择合适的光照渲染模式。 (3)纹理映射 纹理映射是增强场景真实感的一种简单有效的技术。它将预生成的图像直接贴在物体表面,模拟物体表面外观,因此也叫贴图法。纹理映射的扩展技术有很多,包括环境映射、光照图、球面映射、立方体映射、凹凸映射、位移映射等,是图形渲染加速中最重要的手段。在真实感渲染章节会有更详细的讨论。 (4)颜色融合 对于每一个像素,前面步骤可能产生光照计算和纹理映射两类颜色值。不仅如此,光照明计算的结果可能来自多个光源,而每个光源可导致漫反射和镜面反射的光亮度。此外,同一像素也可能采集来自多个纹理的值,如多通道纹理映射和单通道多重纹理映射。所有这些颜色值将根据各自的不透明度融合出最终结果。颜色融合不仅能加强场景真实感,还能产生半透明绘制、景深、基于alpha缓冲器的反走样、软阴影等特效。 2.2图形绘制库OpenGL 2.

我的学习资源

1、ppt制作: 锐普:http://www.rapidbbs.cn/ 无忧ppt:http://www.51ppt.com.cn/ 51ppt模板:http://www.51pptmoban.com/ 2、web界面 uimaker:http://www.uimaker.com/ 3、java学习: 爱酷学习网:http://www.icoolxue.com/ 4、大数据 厦大数据库实验室:http://dblab.xmu.edu.cn/ 5、个人博客

Substring()、lastIndexOf()的用法

前言 在牛腩做新闻评论的时候,把评论人ip的最后一位用*来表示。 但是我想评论人不用ip,而是使用网名或者实名,并且隐藏的不是最后一位,而是除了前后两个字符中间的用三个*来表示。 就像淘宝商品评价一样,这样不仅隐藏了用户名,连用户名长度都不知道。 正文 视频中使用的是IndexOf()方法 简单的查了一下,目前了解的截取字符串有三种方法,stringOf()、lastIndexOf()和Substring()用法 今天就介绍两种,视频中的stringOf()和作者所用的Substring()。 lastIndexOf() 例如: string str = "abcdefg"; str = str.Substring(0, str.LastIndexOf("c")); Response.Write(str); 输出效果: 就是截取c前面的字符串。 Substring() 例如: string qian = null; string hou = null; string str = "abcdefg"; qian = str.Substring(0, 1);//从第一个开始截取,共截取一位 hou = str.Substring(str.Length - 1, 1);//从最后一个开始截取,共截取一位 Response.Write(qian + "***" + hou); 输出效果: asp.net中代码为: 评论人:<%#Eval("userIp").ToString().Substring(0,1)+"***" + Eval("userIp").ToString().Substring(Eval("userIp").ToString().Length - 1, 1) %> 输出效果:

解决ImageView的selector失效

Imageview 的selector失效一般有一下几个原因: 1.imageView的clickable没有设置成true。默认的clickable是false。但是在实际应用中,会出现一个问题,就是在ListView或者GridView或其他可以把imageView作为一个Item的容器中,如果把当前容器的item的imageView的clickable属性设置成true那么该item的OnClick事件会被拦截掉。我采取的解决方案是在容器的OnItemClickListener中执行以下操作: @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { //获取当前View的holder,获取到当前Item中的imageView的引用 MyAdapter.ViewHolder holder = (MyAdapter.ViewHolder)view.getTag(); //把imageVeiw的clickable设置成true holder.imageView.setClickable(true); boolean isSelected = holder.imageView.isSelected(); //imageView的selected状态取反,修改imageView的selected状态,等于切换图片操作 holder.imageView.setSelected( isSelected ? false : true); //把imageView的clickable设置成false,以保证父容器的OntiemClickListener能响应后续的点击操作 holder.imageView.setClickable(false) }; 2.imageView要能使用selector还有一个必须要注意的是,设置selector必须是background不能是src。 3.还有些人说selector文件中默认的显示图片应该写在下面,比如 <?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android" > <item android:drawable="@drawable/icon_airbox_checked" android:state_selected="true"></item> <item android:drawable="@drawable/icon_airbox_unchecked"></item> </selector>、 但在实际开发中发现,这个顺序对结果没有什么影响。

Android 混淆之后出现java.lang.InternalError

项目中引用了 compile 'io.reactivex:rxjava:1.1.3' 在混淆之后,运行崩溃,日志显示 java.lang.InternalError 添加混淆代码: ##解决java.lang.InternalError -keepclassmembers class rx.internal.util.unsafe.*ArrayQueue*Field* { long producerIndex; long consumerIndex; } -keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueProducerNodeRef { rx.internal.util.atomic.LinkedQueueNode producerNode; } -keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueConsumerNodeRef { rx.internal.util.atomic.LinkedQueueNode consumerNode; }

这一次,彻底弄懂 JavaScript 执行机制

本文的目的就是要保证你彻底弄懂javascript的执行机制,如果读完本文还不懂,可以揍我。 不论你是javascript新手还是老鸟,不论是面试求职,还是日常开发工作,我们经常会遇到这样的情况:给定的几行代码,我们需要知道其输出内容和顺序。因为javascript是一门单线程语言,所以我们可以得出结论: javascript是按照语句出现的顺序执行的 看到这里读者要打人了:我难道不知道js是一行一行执行的?还用你说?稍安勿躁,正因为js是一行一行执行的,所以我们以为js都是这样的: let a = '1'; console.log(a); let b = '2'; console.log(b);复制代码 然而实际上js是这样的: setTimeout(function(){ console.log('定时器开始啦') }); new Promise(function(resolve){ console.log('马上执行for循环啦'); for(var i = 0; i < 10000; i++){ i == 99 && resolve(); } }).then(function(){ console.log('执行then函数啦') }); console.log('代码执行结束');复制代码 依照js是按照语句出现的顺序执行这个理念,我自信的写下输出结果: //"定时器开始啦" //"马上执行for循环啦" //"执行then函数啦" //"代码执行结束"复制代码 去chrome上验证下,结果完全不对,瞬间懵了,说好的一行一行执行的呢? 我们真的要彻底弄明白javascript的执行机制了。 1.关于javascript javascript是一门单线程语言,在最新的HTML5中提出了Web-Worker,但javascript是单线程这一核心仍未改变。所以一切javascript版的"多线程"都是用单线程模拟出来的,一切javascript多线程都是纸老虎! 2.javascript事件循环 既然js是单线程,那就像只有一个窗口的银行,客户需要排队一个一个办理业务,同理js任务也要一个一个顺序执行。如果一个任务耗时过长,那么后一个任务也必须等着。那么问题来了,假如我们想浏览新闻,但是新闻包含的超清图片加载很慢,难道我们的网页要一直卡着直到图片完全显示出来?因此聪明的程序员将任务分为两类: 同步任务异步任务 当我们打开网站时,网页的渲染过程就是一大堆同步任务,比如页面骨架和页面元素的渲染。而像加载图片音乐之类占用资源大耗时久的任务,就是异步任务。关于这部分有严格的文字定义,但本文的目的是用最小的学习成本彻底弄懂执行机制,所以我们用导图来说明: 导图要表达的内容用文字来表述的话: 同步和异步任务分别进入不同的执行"场所",同步的进入主线程,异步的进入Event Table并注册函数。当指定的事情完成时,Event Table会将这个函数移入Event Queue。主线程内的任务执行完毕为空,会去Event Queue读取对应的函数,进入主线程执行。上述过程会不断重复,也就是常说的Event Loop(事件循环)。 我们不禁要问了,那怎么知道主线程执行栈为空啊?js引擎存在monitoring process进程,会持续不断的检查主线程执行栈是否为空,一旦为空,就会去Event Queue那里检查是否有等待被调用的函数。 说了这么多文字,不如直接一段代码更直白: let data = []; $.ajax({ url:www.javascript.com, data:data, success:() => { console.

Java设计模式——抽象工厂(Abstract Factory)以及工厂模式总结

抽象工厂和工厂方法的区别 工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个抽象产品类。 工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个具体产品类。(与上面呼应)【个人认为】抽象工厂和工厂方法最明了的区别就是【抽象工厂有多个产品】 结构类图 先上图分析一波 【与工厂方法最主要的区别在于 iHeroFactory多了Wear()方法,多了 Iequipment这个产品】 前言 这篇文章主要来分析一下【简单工厂】【工厂方法】【抽象工厂】三者的区别。 因为我感觉抽象工厂和工厂方法的代码相似度比较大,所以这里就不PO上代码了。用图片来解释会更直白一些。 简单工厂 工厂类有必要的逻辑判断,可以决定具体创建类,使用者免除直接创建对象的责任。 工厂方法 定义一个创建产品对象的工厂接口,让子类决定实例化哪一个类,将实际创建工作推迟到子类当中。【解耦,方便后期修改摸个框架使用,如图片加载】 抽象工厂 当抽象工厂的产品只有一个的时候,抽象工厂即变为工厂模式当工厂模式的产品变为多个的时候,工厂模式即变为抽象工厂 参考 :【http://ichennan.com/2016/08/09/DesignPattern.html】 转载于:https://my.oschina.net/JiangTun/blog/1575931

not exists、left join/is null、not in 行为

测试数据 20:25:52[test](;)> select * from t; +------+------+ | id | b | +------+------+ | 1 | NULL | | 2 | 1 | | 3 | 4 | +------+------+ 3 rows in set (0.00 sec) 实现查询t表中id 的值不存在b中的id记录,有三种实现方式,分别为left join、not exists、not in 其中前两种对null值的处理机制相同 20:37:02[test](;)> select t.id,t.b from t left join t tmp on t.id=tmp.b where tmp.b is null; +------+------+ | id | b | +------+------+ | 2 | 1 | | 3 | 4 | +------+------+ 2 rows in set (0.

linux iscsi initiator 安装配置

环境:远程:centos 6.5 x64 安装所需文件:iscsi-initiator-utils-6.2.0.872-16.el5.x86_64.rpm , 如果是32位操作系统,就下载一个32位的rpm包; 在根目录下,上传rpm包;注意:所有的操作都是基于[root@localhost /]# 进行的,也就是root下操作 [root@localhost /]# rz 上传完成之后,安装(此处注意:我安装的时候,报error: Failed dependencies: 之后查询得知,要在后面加--force --nodeps,目的是:解决依赖关系,加上后表示强制不查找依赖关系,这样安装就不会报错了) rpm -ivh iscsi-initiator-utils-6.2.0.872-16.el5.x86_64.rpm --force --nodeps 之后:用chkconfig检查iscsi和iscsid服务在运行级别3和5中随系统的启动而自动启动 chkconfig --list |grep iscsi 如果iscsid和iscsi没有随系统的启动而启动,则用chkconfig设置这两个服务在系统运行级别为3和5时随系统启动而启动 chkconfig iscsi --level 35 on chkconfig iscsid --level 35 on设置好之后,查看下 InitiatorName more /etc/iscsi/initiatorname.iscsi如果为空,则要编辑 用vi编辑/etc/iscsi/initiatorname.iscsi文件,文件内容如下 InitiatorName=iqn.1994-05.com.redhat:e5c68f913d74 注意: InitiatorName这个单词必须注意大小写,同时,必须顶格写,xxxx代表要设 置的initiator名称,请遵循iqn命名规范。 之后:启动服务,用service iscsi start启动iSCSI服务 启动成功,登录存储: iscsiadm -m discovery -t sendtargets -p 10.0.0.130:3260 这里-T后面跟target名称,最后的-l(英文字母中小写的L),是login的意思,10.0.0.130,是我存储的私有地址,3260是端口 可以看到,我这边是华为的存储; 之后:登录存储 iscsiadm -m node -T iqn.2006-08.com.huawei:oceanstor:21000022a10af9df::10.0.0.130 -p 10.0.0.130:3260 -l 出现successful,就证明已经成功了,之后使用 fdisk -l就可以发现存储的磁盘了;

git: missing xcrun

把Mac升级到了macOS High Sierra,发现终端下git用不了了: xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrun 直接重新安装xcode解决: xcode-select –install

select * from 的一些心得

如何简单运用好 select * from语句,在不同的函数下,有不同的先后顺序。 语法格式 (代表先后顺便) (2)select 字段名 查询什么东西 (1)from 表名,从哪个表查询 例如:查询所有学生姓名 select name from stu; (3)select 字段名 查询什么东西 (1)from 表名,从哪个表查询 (2)where 表达式,条件 要通过什么来查询 例如:查询所有女学生的信息 select * from stu where sex ='女'; (3)select 字段名 查询什么东西 (1)from 表名,从哪个表查询 (2)where 表达式,条件 要通过什么来查询 (4)order by 字段名 or desc/asc 降序和升序,默认是升序 查询选修了课程编号为‘105‘的学生的学生编号,成绩,结果以降序排列 select student_no,grade from sc where course_no ='105' order by grade desc; (4)select 字段名 查询什么东西 (1)from 表名,从哪个表查询 (2)where 表达式,条件 要通过什么来查询 (3) group by 字段名 (having函数)

基于 OpenWrt 实现 tcpdump 抓包并在 Windows 系统上的 Wireshark 中格式化显示

工具: Openwrt 系统下的 tcpdumpWindows 系统下的 Wireshark 和 plink 快捷键 在路由器的 Openwrt 系统下安装 tcpdump 工具 在 Windows 系统下安装 Wireshark 程序,并不下载的 plink 工具放入 Wireshark 的安装目录下在 Windows 系统下打开命令窗口,进入 Wireshark 安装目录,运行 plink -ssh USER@HOST -pw PASS "tcpdump -s 0 -U -n -i br-lan -w - not port 22" | wireshark -k -i - 说明: USER: 是路由器 Openwrt 系统的登录用户名 HOST: 是路由器的远程登录 IP PASS: 是路由器 Openwrt 系统的登录密码 br-lan: 是需要抓取路由器数据包的网络接口,可以选择其他接口 tcpdump 参数说明: -i: 指定网络接口,不指定则默认抓取第一个网络接口 port:指定截获端口 host:指定截获的主机 not:不包括 -s 0: 抓取数据包默认抓取长度为68字节, -S 0:可以抓取到完整的数据包 -c 100: 只抓取100个数据包 -U:让数据包打印时直接输出到stdout而不是在输出缓存满后再输出,当文件名是”-“时,输出原数据包到stdout -n:不把主机的网络地址转换为名字 -w:把数据包数据写入指定的文件

spring mvc执行过程

springMVC执行的过程 流程如下: 用户发起请求到前端控制器(DispatcherServlet),该控制器会过滤出哪些请求可以访问Servlet、哪些不能访问。就是url-pattern的作用,并且会加载springmvc.xml配置文件。前端控制器会找到处理器映射器(HandlerMapping),通过HandlerMapping完成url到controller映射的组件,简单来说,就是将在springmvc.xml中配置的或者注解的url与对应的处理类找到并进行存储,用map<url,handler>这样的方式来存储。HandlerMapping有了映射关系,并且找到url对应的处理器,HandlerMapping就会将其处理器(Handler)返回,在返回前,会加上很多拦截器。DispatcherServlet拿到Handler后,找到HandlerAdapter(处理器适配器),通过它来访问处理器,并执行处理器。执行处理器处理器会返回一个ModelAndView对象给HandlerAdapter通过HandlerAdapter将ModelAndView对象返回给前端控制器(DispatcherServlet)前端控制器请求视图解析器(ViewResolver)去进行视图解析,根据逻辑视图名解析成真正的视图(jsp),其实就是将ModelAndView对象中存放视图的名称进行查找,找到对应的页面形成视图对象返回视图对象到前端控制器。视图渲染,就是将ModelAndView对象中的数据放到request域中,用来让页面加载数据的。通过第8步,通过名称找到了对应的页面,通过第10步,request域中有了所需要的数据,那么就能够进行视图渲染了。最后将其返回即可。

静态成员变量初始化问题。关于 error LNK2005 static int:已经在***.obj中定义

这两天一直做C++的内容,我在一个类里使用了一个静态成员函数,但是在使用的时候总是报错 比如这样子 错误 1 error LNK2005: "public: static int c1::i" (?i@c1@@2HA) 已经在 c1.obj 中定义 根据我在网上查资料,主要原因有以下三种: 1.重复定义全局变量。 2.头文件的包含重复。 3.使用第三方的库造成的。 但是我的原因不属于刚才所提到的三种,我的程序代码并没有太多了.h文件,也没有复杂的包含关系。 大家都知道,在类里定义静态对象的时候,必须立刻在类外初始化,否则就会报错。给大家举个例子。 c2类是c1类的子类,如下: c1.h [cpp] view plain copy #pragma once class c1 { public: c1(void); ~c1(void); static int i; }; int c1::i=0; c1.cpp [cpp] view plain copy #include "c1.h" c1::c1(void) { } c1::~c1(void) { } c2.h [cpp] view plain copy [cpp] view plain copy #pragma once #include "c1.h" class c2 : public c1 { public: c2(void); ~c2(void); }; c2.

Macfee与ESET哪个好?

以下是网上搜集的信息,大家可以做个参考! 个人:ESETNOD32(资源占用少,适合个人使用,很好很强大,但自我保护少了点。容易被强力病毒直接kill) 懂电脑的使用:macfee(因为macfee的界面和杀毒很复杂,一般不建议菜鸟使用。杀毒效果和ESET媲美) -------------------------------------------------------------------------------------- 如果说防御,没有任何一个杀软好,防御好的是HIPS,建议comodo或者ESET和卡巴斯基开交互(交互比较烦) ESET,高启发查杀,查杀能力比较好,一旦查杀被过,交互HIPS打开或者带规则的自动模式里有合理的规则的情况下,仍然可以阻止病毒,但是ESET的HIPS比较不智能,小白很难上手,所以一般人也不开,可以视为杀毒一旦被过,就失去抵抗能力 诺顿属于比较厚重的杀软,没有什么出色的特点,但是各方面也都不弱 卡巴斯基,配置不高的笔记本还是别用了,那就是卡吧死机 咖啡(Macfee)如果有好规则,那就是钢铁防线,不会弄规则,那就什么也不是,小白不要用 最合理的搭配,一款高查杀不带墙的杀软+HIPS 如果上网习惯恶劣,单奔任何杀软都不保险 如果上网习惯好,装个MSE单奔都不会中毒

margin auto 实现居中,与text-align:center的区别

本文导读:一个元素在水平方向上所占的长度,由width ,padding ,和margin 决定。这些值中,只有width和margin-left,margin-right可以设为auto,text-align是用于设置或对象中文本的对齐方式。一般情况下我们设置文本对齐方式的时候需要用此属性进行设置。 一、margin:0 auto;的意思 上下边界为0,左右根据宽度自适应!这就是水平居中的意思,使用 margin:0px auto; 也是大家在做css div定位时的最常用方法。 但是在使用过程中,常有居中不了的情况,下面介绍几种不居中的情况。 1、与 margin:100px 混用,导致无法居中 这种情况下,因为前面设了margin:0px auto; 但是后面又设了margin:100px,这明显是相矛盾的,不仅如此,如果同时使用了margin:0px auto ; 和 float:left ,也一样都不生效。 2、没有指定DOCTYPE DOCTYPE是指定浏览器以哪一种标准解析html代码,如果不指定,极有可能会不生效。 我们常见有人写html,是直接以<html>开头的,这种情况,我们只要再加上DOCTYPE头即可以,最好是直接从dw中新建一个html头,然后从中再做修改。完整的html头如下: HTML 代码 复制 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>无标题文档</title> </head> <body> 主题内容 </body> </html> 3、DOCTYPE前还有代码,导致不生效 在<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 这一句前加了一个<!-- 说明文字 -->这样的注释,也同样出现了margin:0px auto;无法居中的情况。 4、如果上面的几种方法还是不能够居中,则可以用 text-align:center 这是下下之策,如果上面margin:0px auto;用了怎么都不行,那到body中加上text-align:center;吧,如此一下不仅是div,文字也会居中显示。 然后可以再到细化的css中,把相应容器再设成text-align:left再达到文字靠左的效果。

MATLAB控制系统校正工具sisotool的使用

前言 对于单输入单输出的控制系统矫正,性能指标的分析,使用MATLAB自带的sisotool GUI工具非常方便,他的主要功能如下: 时域、频域性能指标可视化绘制根轨迹,零极点配置PID的自动矫正等 最大的方便的地方是,当你在校正的参数改变后,系统的根轨迹,bode图,相应曲线能够同步更新。 注:本文使用的 MATLAB 版本是 2014a 目录 文章目录 前言目录1 使用步骤2 工作界面介绍2.1 architecture界面2.2 compensator editor界面2.3 graphic tuning界面2.4 analysis plot界面2.5 automated tuning 3 实例:单闭环直流调速系统PID校正3.1 建立模型3.2 打开sisotool导入模型3.3 显示图形3.4 PI自动校正 1 使用步骤 编写M文件,建立各环节的传递函数命令行输如sisotool回车,打开GUI界面将workspace中的模型导入sisotool进行分析或设计 2 工作界面介绍 2.1 architecture界面 该界面用于选择合适的模型结构,导入模型data。点击control architecture选择模型的结构,点击system data导入模型各环节数据。 2.2 compensator editor界面 该界面是校正器编辑界面,用于选择校正的参数,调整参数,同步参数的变化.比如,在graphic tuning的root locus图中使用鼠标在图中增加了开环零极点或改变了闭环极点的未知,响应的变化会在该界面同步更新,显示增益,所增加的开环零极点的具体数值.当然,如果当前打开analysis plot,其中的响应曲线也会响应的变化。 2.3 graphic tuning界面 用于控制要显示的图像,根轨迹校正肯定要选择根轨迹,频域校正选择开环bode图。可以在一个窗口中显示多种类型的图形。 设计工作就是在所显示的图形上完成的。 2.4 analysis plot界面 参数调整后效果好不好,需要看相应曲线图,该界面控制要显示那些用于分析系统性能的图形。 2.5 automated tuning 提供了PID自动整定的功能,实际上PID校正是开环零极点配置,PI控制增加了一个位于原点的开环极点,减小稳态误差,同时,也增加了位于左半平面的开环零点,使相应迅速。 3 实例:单闭环直流调速系统PID校正 3.1 建立模型 编写M脚本 clc % clear all Kp=[]; Ti=[]; Ks=44; Ts=.

《算法4》图&深度优先与广度优先算法

图 一系列点以及把它们连起来的边就构成了一幅图,图是现实生活中许多东西的抽象比如地图或者电路图,在数学中也有图论这一分支专门研究图的性质,这一篇以及接下来的几篇都是和图相关的。 上图是一幅图的示例。 这里我们先研究无向图,就是图中的边是没有方向的。还要介绍几个定义: 度数:某一个顶点的度数即为依附于它的边的总数。 路径:由边顺序连接起来的一系列顶点。 环:该路径上的任意一个顶点都可以沿着这条路径回到原来的顶点。 连通图:如果从任意一个顶点都存在一条路径到达另一个任意定点,那么这幅图是连通图。 我们这里不考虑自环和平行边。 图的表示方式 图的表示有很多种,比如领接矩阵,但是这种表示方式浪费了很大的空间,所以我们采用邻接表的方式,就是维护一个数组adj[],adj[]里的每一个元素对应于一个顶点,里面保存的是一个指向一个Bag<>泛型数组的引用,这个Bag数组里面包含的是和某个顶点v相连的所有顶点。 一个无向图的邻接表的实现方式如上图所示,使用邻接表可以只保留有效信息,从而大大减少空间的需求。 Graph实现的代码为: public class Graph { private final int V; // number of vertex private int E; // number of edge private Bag<Integer>[] adj; //adjacent list public Graph(int V){ this.V = V; this.E = 0; adj = (Bag<Integer>[]) new Bag[V]; for (int v=0;v<V;v++){ adj[v] = new Bag<Integer>(); } } public Graph(In in){ this(in.readInt()); int E = in.readInt(); for(int i=0;i<E;i++){ int v = in.

HTML-JavaScript--单击按钮改变背景颜色

/* *Copyright (c) 2017,烟台大学计算机学院 All rights reserved. *文件名称:关于HTML的练习 *作 者:张晴晴 *完成日期:2017年11月11日 *版 本 号:v1.0 * *问题描述:HTML5-JavaScript *输入描述: 无 *程序输出: 无 */ <!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>单击按钮改变背景颜色</title> <script> function changecolor(color){ document.bgColor=color; } </script> </head> <body> <input type="button" value="不许碰我" onClick="changecolor('yellow')"> <input type="button" value="警告你别碰我" onClick="changecolor('red')"> <input type="button" value="给你点颜色看看" onClick="changecolor('black')"> </body> </html> 运行结果: 

解决windows adb 脆弱的问题

最近做测试的时候遇到了adb总是卡死的情况,每次执行测试前都需要手动杀掉adb的进程,由于测试任务是通过Jenkins自动触发每天执行的,所以想在windows中添加一个定时任务,在每天的测试之前执行定时任务重启adb和appium的服务。具体怎么添加定时任务可以参考这篇文章: http://blog.csdn.net/cdnight/article/details/53841921 把定时任务指到需要执行的bat脚本,下面是我的bat脚本: taskkill /F /IM node.exe taskkill /f /IM adb.exe adb connect 196.2.23.84 appium --address 196.2.19.46 --port 4723 --log D:\AutoTest\appium-log\appiumlog.txt 执行后的结果:

开启nginx目录文件列表显示功能

正常访问nginx的时,显示nginx欢迎页,也就是我们目录首页(/nginx/html/index.html文件),不会显示项目目录列表,这对于本人代码也起到一定的保护作用; 但我们在开发阶段为了快速浏览列表,可设置目录列表的【显示】 那么重要的时刻到了-----在nginx.conf主配置文件中http或location代码段中,配置一段代码即可实现: http { include mime.types; default_type application/octet-stream; autoindex on; autoindex_exact_size off; autoindex_localtime on; } [参数说明] 1、autoindex on; # 自动显示目录 2、autoindex_exact_size off; [ 默认为on,显示出文件的确切大小,单位是bytes 改为off后,显示出文件的大概大小,单位是kB或者MB或者GB ] 3、autoindex_localtime on; [ 默认为off,显示的文件时间为GMT时间。 改为on后,显示的文件时间为文件的服务器时间 ]

数据库为何要有复合主键(多主键)

最近学习一点数据库的基本知识,被一个问题困惑了许久:主键是唯一的索引,那么为何一个表可以创建多个主键呢? 其实“主键是唯一的索引”这话有点歧义的。举个例子,我们在表中创建了一个ID字段,自动增长,并设为主键,这个是没有问题的,因为“主键是唯一的索引”,ID自动增长保证了唯一性,所以可以。 此时,我们再创建一个字段name,类型为varchar,也设置为主键,你会发现,在表的多行中你是可以填写相同的name值的,这岂不是有违“主键是唯一的索引”这句话么? 所以我才说“主键是唯一的索引”是有歧义的。应该是“当表中只有一个主键时,它是唯一的索引;当表中有多个主键时,称为复合主键,复合主键联合保证唯一索引”。 为什么自增长ID已经可以作为唯一标识的主键,为啥还需要复合主键呢。因为,并不是所有的表都要有ID这个字段啊哈哈,比如,我们建一个学生表,没有唯一能标识学生的ID,怎么办呢,学生的名字、年龄、班级都可能重复,无法使用单个字段来唯一标识,这时,我们可以将多个字段设置为主键,形成复合主键,这多个字段联合标识唯一性,其中,某几个主键字段值出现重复是没有问题的,只要不是有多条记录的所有主键值完全一样,就不算重复。 1、数据库的每张表只能有一个主键,不可能有多个主键。 2、所谓的一张表多个主键,我们称之为联合主键。 注:联合主键:就是用多个字段一起作为一张表的主键。 3、主键的主键的作用是保证数据的唯一性和完整性,同时通过主键检索表能够增加检索速度。 下面聊聊怎么创建联合主键: 1、GUI中同时选中多列,点击设置为主键。 2、sql语句将多列设置为主键: 一种是在建表时就写出,语句如下: Create Table 表名 (字段名1 Int Not Null, 字段名2 nvarchar(13) Not Null Primary Key (字段名1, 字段名2), 字段名3………… 字段名N………… ) 另一种是在建表后更改,语句如下: ALTER TABLE 表名 WITH NOCHECK ADD CONSTRAINT [PK_表名] PRIMARY KEY NONCLUSTERED ( [字段名1], [字段名2] )

更新NVIDIA显卡的CUDA驱动出错,You appear to be running an X server; please exit X before

(一)错误信息: You appear to be running an X server; please exit X before... 原来,更新驱动需要关闭图形桌面。赶紧查看一下,是不是真的有X: ps aux | grep X 看到 $ ps aux | grep X root 2242 1.6 0.0 154212 35820 tty7 Ss+ 04:10 0:01 /usr/lib/xorg/Xorg -core :0 -seat seat0 -auth /var/run/lightdm/root/:0 -nolisten tcp vt7 -novtswitch cc 4677 0.0 0.0 11284 1016 pts/8 S+ 04:11 0:00 grep --color=auto X (二)关闭X的方式有两种: (1)gdm类型的桌面系统 sudo /etc/init.d/gdm stop sudo /etc/init.d/gdm status (2)light类型的桌面系统 sudo /etc/init.

Allegro导入网表报错

文章首发于同名微信公众号:DigCore 欢迎关注同名微信公众号:DigCore,及时获取最新技术博文。 E- (SPMHGE-82): Pin numbers do not match between symbol and component. Run dev_check on device file for more information. 错误号82:原理图引脚号与封装引脚号对应不上 ERROR(SPMHNI-195): Symbol 'CONN3-PWR-PJ102A' for device 'USBPORT_CONN3-PWR-PJ102A_USBPOR' is missing pin '6'. 错误号195:封装库中的标号比原理图库中的引脚号 少一根“6”号引脚 ERROR(SPMHNI-196): Symbol 'TFT60P1530X436-45' for device 'TFT_4.3_A43036N60LL_TFT60P1530X' has extra pin '47'. 错误号196:封装库中的标号比原理图库中的引脚号 多一根“47”号引脚

Linux系统安装Nginx

一、安装编译工具及库文件 yum -y install make zlib zlib-devel gcc-c++ libtool openssl openssl-devel 如果是Ubuntu系统,请使用 sudo apt-get install openssl sudo apt-get install libssl-dev 二、安装make(如果已有请略过) # 将ubuntu-make加入apt软件仓库的列表 sudo add-apt-repository ppa:ubuntu-desktop/ubuntu-make # 升级apt的软件仓库,为了加入刚才的ubuntu-make sudo apt update # 安装ubuntu-make sudo apt install ubuntu-make 三、安装 GCC 和 G++ C++ 开发环境 1.先安装 :sudo apt-get install build-essential 2.查看 gcc 版本 然后安装 统一版本的 g++ gcc --version gcc (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5 Copyright (C) 2010 Free Software Foundation, Inc. This is free software; see the source for copying conditions.

ubuntu安装make

首先,我们安装最新版ubuntu-make。 # 将ubuntu-make加入apt软件仓库的列表 sudo add-apt-repository ppa:ubuntu-desktop/ubuntu-make # 升级apt的软件仓库,为了加入刚才的ubuntu-make sudo apt update # 安装ubuntu-make sudo apt install ubuntu-make

ubuntu使用yum命令时报错解决方法

root@i-ka9tolv1:/home/ubuntu/local/nginx-1.6.2# yum -y install openssl openssl-devel There are no enabled repos. Run "yum repolist all" to see the repos you have. You can enable repos with yum-config-manager --enable <repo> 原因ubuntu14.0 不支持yum下载按装机制 正确的命令是: sudo apt-get install openssl sudo apt-get install libssl-dev

authentication failure的解决办法

Ubuntu linux系统下 su:出现: authentication failure的解决办法 $ sudo passwd root Enter new UNIX password: //输入密码 Retype new UNIX password: //再次输入密码 passwd: password updated successfully 此时再用su命令,就可以获取到root权限了。

opencv+GDAL 遥感影像滤波

参考: 1、https://docs.opencv.org/3.2.0/ 1、python版 其中m1 参考:http://blog.csdn.net/wc781708249/article/details/78394933 #!/usr/bin/env python # -*- coding: UTF-8 -*- """ 数据:遥感图像 16bit 4波段 对应opencv数据格式为CV_16UC4,转成float32对应的数据格式为CV_32FC4 操作:滤波操作 """ from scipy import ndimage try: from osgeo import gdal except: import gdal import gdalnumeric from osgeo.gdalconst import * import numpy as np from datetime import datetime import m1 import cv2 start_time=datetime.now() # 为了支持中文路径,请添加下面这句代码 gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8","NO") gdal.AllRegister() #注册驱动 img1_path="D:/test.tiff" img=m1.Multiband2Array(img1_path) raster_fn="D:/test_2.tif" # 各种滤波处理 dst=cv2.blur(img,(15,15)) # 均值滤波 可以处理CV_32FC4 dst=cv2.GaussianBlur(img,(5,5),0) # 高斯滤波 可以处理CV_32FC4 dst=cv2.medianBlur(img,5) # 中值滤波 可以处理CV_32FC4 # 双边过滤 只能处理CV_32FC3数据 只取前3个波段处理,处理CV_32FC4报错 dst=cv2.

大数据经典学习路线(学习中)

文章地址:http://www.haha174.top/article/details/253234 文章来源:http://blog.csdn.net/yuexianchang/article/details/52468291 1.Linux基础和分布式集群技术 学完此阶段可掌握的核心能力: 熟练使用Linux,熟练安装Linux上的软件,了解熟悉负载均衡、高可靠等集群相关概念,搭建互联网高并发、高可靠的服务架构; 学完此阶段可解决的现实问题: 搭建负载均衡、高可靠的服务器集群,可以增大网站的并发访问量,保证服务不间断地对外服务; 学完此阶段可拥有的市场价值: 具备初级程序员必要具备的Linux服务器运维能力。 1.内容介绍: 在大数据领域,使用最多的操作系统就是Linux系列,并且几乎都是分布式集群。该课程为大数据的基础课程,主要介绍Linux操作系统、Linux常用命令、Linux常用软件安装、Linux网络、防火墙、Shell编程等。 2.案例:搭建互联网高并发、高可靠的服务架构。 2.离线计算系统课程阶段 离线计算系统课程阶段 HADOOP核心技术框架 学完此阶段可掌握的核心能力: 1、通过对大数据技术产生的背景和行业应用案例了解hadoop的作用;2、掌握hadoop底层分布式文件系统HDFS的原理、操作和应用开发;3、掌握MAPREDUCE分布式运算系统的工作原理和分布式分析应用开发;4、掌握HIVE数据仓库工具的工作原理及应用开发。 学完此阶段可解决的现实问题: 1、熟练搭建海量数据离线计算平台;2、根据具体业务场景设计、实现海量数据存储方案;3、根据具体数据分析需求实现基于mapreduce的分布式运算程序; 学完此阶段可拥有的市场价值: 具备企业数据部初级应用开发人员的能力 1.1 HADOOP快速入门 1.1.1 hadoop知识背景 什么是hadoop、hadoop产生背景、hadoop在大数据云计算中的位置和关系、国内hadoop的就业情况分析及课程大纲介绍 国内外hadoop应用案例介绍 分布式系统概述、hadoop生态圈及各组成部分的简介 1.1.2 HIVE快速入门 hive基本介绍、hive的使用、数据仓库基本知识 1.1.3 数据分析流程案例 web点击流日志数据挖掘的需求分析、数据来源、处理流程、数据分析结果导出、数据展现 1.1.4 hadoop数据分析系统集群搭建 集群简介、服务器介绍、网络环境设置、服务器系统环境设置、JDK环境安装、hadoop集群安装部署、集群启动、集群状态测试 HIVE的配置安装、HIVE启动、HIVE使用测试 1.2 HDFS详解 1.2.1 HDFS的概念和特性 什么是分布式文件系统、HDFS的设计目标、HDFS与其他分布式存储系统的优劣势比较、HDFS的适用场景 1.2.2 HDFS的shell操作 HDFS命令行客户端启动、HDFS命令行客户端的基本操作、命令行客户端支持的常用命令、常用参数介绍 1.2.3 HDFS的工作机制 HDFS系统的模块架构、HDFS写数据流程、HDFS读数据流程 NAMENODE工作机制、元数据存储机制、元数据手动查看、元数据checkpoint机制、NAMENODE故障恢复、DATANODE工作机制、DATANODE动态增减、全局数据负载均衡 1.2.4 HDFS的java应用开发 搭建开发环境、获取api中的客户端对象、HDFS的java客户端所具备的常用功能、HDFS客户端对文件的常用操作实现、利用HDFS的JAVA客户端开发数据采集和存储系统 1.3 MAPREDUCE详解 1.3.1 MAPREDUCE快速上手 为什么需要MAPREDUCE、MAPREDUCE程序运行演示、MAPREDUCE编程示例及编程规范、MAPREDUCE程序运行模式、MAPREDUCE程序调试debug的几种方式 1.3.2 MAPREDUCE程序的运行机制 MAPREDUCE程序运行流程解析、MAPTASK并发数的决定机制、MAPREDUCE中的combiner组件应用、MAPREDUCE中的序列化框架及应用、MAPREDUCE中的排序、MAPREDUCE中的自定义分区实现、MAPREDUCE的shuffle机制、MAPREDUCE利用数据压缩进行优化、MAPREDUCE程序与YARN之间的关系、MAPREDUCE参数优化 通过以上各组件的详解,深刻理解MAPREDUCE的核心运行机制,从而具备灵活应对各种复杂应用场景的能力 MAPREDUCE实战编程案例:通过一个实战案例来熟悉复杂MAPREDUCE程序的开发。该程序是从nginx服务器产生的访问服务器中计算出每个访客的访问次数及每次访问的时长。原始数据样例如下: 通过一系列的MAPREDUCE程序——清洗、过滤、访问次数及时间分析,最终计算出需求所要的结果,用于支撑页面展现: 1.4 HIVE增强 1.4.1 HIVE基本概念 HIVE应用场景、HIVE内部架构、HIVE与hadoop的关系、HIVE与传统数据库对比、HIVE的数据存储机制、HIVE的运算执行机制 1.

获取图片实际渲染的宽度、高度与图片原始的宽度和高度

在写页面时经常会遇到需要获取图片的宽度、高度等情况。然而以前总是获取的是图片实际渲染的宽度和高度,也就是你用css或js设置后的图片的宽度和高度,并不是图片原始的尺寸。今天突然遇到这个问题,一时之间不知如何做,查了下资料,自己摸索了一下。特此总结一下。 例如。有这样一张图片,代码如下: <img src="创建ajax的过程.png" alt="" > 1、获取图片渲染的宽度和高度(可用js或jQuery实现)。 (1)、使用js获取图片实际渲染的宽度、高度。 这里也有两种方式: 一种是: document.getElementsByTagName("img")[0].width // 获取实际渲染宽度 document.getElementsByTagName("img")[0].height // 获取实际渲染高度 另一种: document.getElementsByTagName("img")[0].offsetWidth // 获取实际渲染宽度 document.getElementsByTagName("img")[0].offsetHeight // 获取实际渲染高度 (2)、使用jQuery·获取图片实际渲染宽度和高度。 $("img").width() // 获取实际渲染宽度 $("img").height() // 获取实际渲染高度 然而当我们通过css或者js重新设置了图片的宽度和高度后,再用上述方法并不能获取图片的原始尺寸,它获取的是图片实际渲染的宽度和高度,为了达到目的,我们需要使用下面这种方法。 2、获取图片原始的尺寸,也就是无论你是否用css、js设置过图片的宽度、高度,始终获取的是图片的原始尺寸。 HTML5提供了新属性naturalWidth/naturalHeight可以直接获取图片的原始宽、高,这两个属性在Firefox/Chrome/Safari/Opera及IE9+里已经实现。 直接就是 document.getElementsByTagName("img")[0].naturalWidth document.getElementsByTagName("img")[0].naturalHeight 由于该属性对于IE8及以下不支持,所以这里需要做一个兼容性处理。 html代码: <img src="完整的http请求过程.png" alt="" style="width:400px" id="img"> js代码为: <script> // 获取图片原始尺寸的兼容性写法。 window.onload = function(){ function getNaturalSize (img) { if(window.naturalWidth && window.naturalHeight) { naturalWidth = img.naturalWidth; } else { // 兼容IE8及以下版本 var image = new Image(); image.

TensorFlow 完整的TensorFlow入门教程

1:你想要学习 TensorFlow,首先你得安装Tensorflow,在你学习的时候你最好懂以下的知识: a:怎么用python编程; b:了解一些关于数组的知识; c:最理想的情况是:关于机器学习,懂一点点;或者不懂也是可以慢慢开始学习的。 2:TensorFlow提供很多API,最低级别是API: TensorFlow Core,提供给你完成程序控制,还有一些 高级别的API,它们是构建在 TensorFlow Core 之上 的,这些高级别的API更加容易学习和使用, 于此同时,这些高级别的API使得重复的训练任务更加容易, 也使得多个使用者操作对他保持 一致 性, 一个高级别的API像 tf.estimator 帮助你管理数据集合,估量,训练和推理。 3: Tensors TensorFlow的数据中央控制单元是 tensor(张量),一个tensor由一系列的原始值 组成,这些值被形成一个任意维数的数组。 一个tensor的 列就是它的维度。 4: import tensorflow as tf 上面的是TensorFlow 程序典型的导入语句,作用是:赋予Python访问TensorFlow类(classes),方法(methods),符号(symbols) 5 : The Computational Graph TensorFlow核心程序由2个独立部分组成: a:Building the computational graph构建计算图 b:Running the computational graph运行计算图 一个computational graph(计算图)是一系列的TensorFlow操作排列成一个节点图。 node1 = tf.constant(3.0, dtype=tf.float32) node2 = tf.constant(4.0)# also tf.float32 implicitly print(node1, node2) 最后打印结果是: Tensor("Const:0", shape=(), dtype=float32) Tensor("Const_1:0",shape=(), dtype=float32) 要想打印最终结果,我们必须用到 session:一个session封装了TensorFlow运行时的控制和状态 sess = tf.

shell脚本入门

shell脚本入门 菜单栏编写方法; cat << EOF 1) .............................................................................. 2) ..................................................................................... EOF 脚本第一行必须写#!/bin/bash 这一行说明这是一个脚本文件,如果写在第二行,就会认为是一个注释行 vim打开语法高亮:syntax enable 用户交互命令:read -p "提示用户" var read -p -p是提示,从键盘读取内容放到变量var中。 内置变量:一般大写 $UID是用户ID 用id命令可以查看uid gid 和组 [ $UID -ne 0 ] $UID表示执行这个脚本的UID是多少 查看UID的方法,UID都是在/etc/passwd tail -5 /etc/passwd 查看配置文件/etc/passwd的最后5行 sync:x:4:65534:sync:/bin:/bin/sync 冒号隔开,第一列是用户名,第二个是密码(x表示有密码),第三个是uid,第四个是gid, 判断语句; [ 2 -eq 3 ] && echo 0 #中括号两边必须要有空格,-eq是等于的意思,假设2等于3,就会执行后面的echo 0 [ 2 -ne 3 ] && echo 0 #同上,-ne表示不等于。 [ 2 -eq 3 ] && echo 0 || echo 1 #前面的语句执行失败了,将要执行echo 1 gt:是大于;lt 是小于;ge是大于等于;le是小于等于 只能比较数字,不能比较字符串 但是双中括号有时候出问题 [[ $line > 10 ]] && echo 1 #这样用就可以直接用大于号小于号不等于之类的。双中括号。有些系统不支持 [[ $line = 10 ]] && echo 0 比较字符串 一个问题: #!

HTML5-网页标栏的下拉菜单

/* *Copyright (c) 2017,烟台大学计算机学院 All rights reserved. *文件名称:关于HTML的练习 *作 者:张晴晴 *完成日期:201711月5日 *版 本 号:v1.0 * *问题描述:HTML5的新特性 *输入描述: 无 *程序输出: 无 */ <!doctype html> <html> <head> <meta charset="utf-8"> <title>网页横栏-下拉列表</title> <style> body{ font-size:16px; font-family:"仿宋";/*body里面设置字体*/ } #nav{ line-height:40px; list-style-type:none; padding:0px; width:100%; } #nav ul{ line-height:40px; position:absolute; left:-100000px; padding:0px;/*定义元素边框和元素内容之间的距离*/ } #nav li{ float:left; /*display:inline;*//*使之在一行上显示*/ background-color:red; width:100px; } #nav a{ padding:10px 30px;/*一层网络连接的相对位置*/ color:yellow;/*链接本来的颜色*/ text-decoration:none; } #nav a:hover{/*hover设置鼠标移动到a上面时的样式*/ color:white;/*鼠标指向链接显示的颜色*/ background-color:blue;/*鼠标指示背景显示颜色*/ list-style-type:none; } #nav li:hover ul{/*指定下拉列表出现的位置*/ left:auto; /*left 属性规定元素的左边缘。该属性定义了定位元素左外边距边界与其包含块左边界之间的偏移。*/ } #nav ul li{/*下拉子菜单中所有内容*/ background-color:green; list-style-type:none; clear:left;/*规定哪一侧不允许浮动元素*/ } #nav ul a{/*二层下拉列表中的样式*/ text-decoration:none; padding:5px; color:black;}/*链接本来的颜色*/ </style> </head> <body> <ul id="

4领域-8领域-m领域

关于像素的邻接,连接和连通 4邻域,8邻域之分。其中8邻域=4邻域+对角邻域。 邻接:两个像素接触,则它们是邻接的。一个像素和它的邻域中的像素是接触的。邻接仅考虑像素的空间关系。 连接:(1)是邻接的。(2)灰度值(或其他属性)满足某个特定的相似准则(灰度相等或在某个集合中等条件)。 这样我们就有了4-连接,8-连接和m-连接的概念 (1)4-连接:2个像素p和r在灰度集合V中取值且r在N4(p)—p的4邻域中。 (2)8-连接:概念类似(1)。 (3)m-连接:也叫混合连接,2个像素p和r在灰度集合V中取值且满足<1>r在N4(p)中;<2>r在Nd(p)中且N4(p)与N4(r)的交集元素不在V中。 “混合连接实质上是在像素间同时存在4-连接和8-连接时,优先采用4-连接,并屏蔽两个和同一像素间存在4-连接的像素之间的8-连接。”《图像工程》。 m-连接的引入目的之一就是消除8-连接的多路问题(二义性)。8-连接在像素距离的选择时有多种路径,引发歧义,而m-连接则没有。 连通:说白了和图里的节点连通性道理一样。就是两个像素之间,如果有一条通路能把它们连接起来,那么就是连通的了。当然,连接是连通的一种特例,就是在两个邻近的像素之间的连通。对应连接的概念,连通也分4-连通和8-连通。 在像素的邻接和连通定义我们都熟知后,其实还有比较复杂点的概念引入,那就是像素集合的邻接和连通。如果把一幅图像看做是所有像素的集合,那么根据像素间的关系则可把像素结合成图像的子集合。那么显然这些子集也满足像图像像素元素那样的连通和连接性质。 对图像子集S中的任何一个像素p,所有和p相连通又在S中的像素的集合合起来称为S中的一个连通组元。如果S只有一个连通组元,即S中所有像素都互相连通,那么S就是一个连通集。如果一幅图像的所有像素都分属于几个连通集,则可以说这几个连通集是整个图像的连通组元。图像里的每个连通集构成图像的一个区域,这样我们就引入了区域的概念。 复习考试记录:重新理解 1.邻域:数字图像中,邻域分为4邻域和8邻域,4邻域就是某个(x,y)点的上下左右四个点,8邻域再加上左上右上左下右下四个点。如果p在q周围的8个点内,就是p在q的8邻域内。 2.邻接:邻接算是包含了邻域,如果说p和q是邻接,那么p和q必须互在邻域内,而且这两个的像素还要都在同一个集合V1内。(什么叫都在集合V1内:假如集合V1包含{012345},这五个数代表的是像素值,而p值为2,q值为6,那它们两个就不在同一个集合V1内,当然如果有个集合V2,它俩可能也在另一个集合V2内)数字图像中常见的邻接有三种,4邻接、8邻接和m邻接。如果p在q的4邻域内,且q和p的值都在V中,那么p和q是4邻接的,8邻接概念一样。m邻接不太一样,如果q和p互在8邻域内,p和q都在V内,且q的4邻域和p的4邻域的共同覆盖的点不在V内,则p和q是m邻接的。m邻接是为了消除8邻接的二义性而引进的。 比如有个3*3矩阵 {0,1,1;0,1,0;0,0,1},假设对于V={1}的集合而言,如果两个点能构成邻接,就算有一条路可以通过,那么右上角的1走到右下角的1,如果按照8邻接有两条路,而按照m邻接,只有一条路,这就是m邻接提出的意义。 3.通路:如果从(x0,y0)点到(xn,yn)点,其中的每个点与前后都是K邻接的(K代表4、8、m),则说这两个点之间存在一条K通路,注意一定要强调明白K,而n是这个通路的长度,如果(x0,y0)和(xn,yn)是重合的,那么说这是一条闭合通路。 4.连通:对于图像中的某一个像素子集U和其中的两个点p和q,如果p和q之间有一个有U中全部元素构成的通路,那就说p和q是连通的。 5.连通集:接上,对于U中的元素p,U中能连通到p的元素的集合叫做U的连通分量,如果U只有一个连通分量,那么U就是一个连通集。 6.区域:令T是图像中的某一个子集,如果T是一个连通集,那么称T是一个区域。 理解这些概念的时候,不能孤立的看,要和图像分割的过程结合起来看,比如图像的前景和背景,就是跟区域有关的。假设一幅图像中有M个不连接的区域,且它们都不接触图像的边界,令R1代表这M个区域的并集,令R2代表其补集,那么R1中的所有点就是图像中的前景,而R2中的所有点就是图像的背景

HTML-表格的奇数偶数行颜色不同

/* *Copyright (c) 2017,烟台大学计算机学院 All rights reserved. *文件名称:关于HTML的练习 *作 者:张晴晴 *完成日期:201711月5日 *版 本 号:v1.0 * *问题描述:HTML5的新特性 *输入描述: 无 *程序输出: 无 */ <!doctype html> <html> <head> <meta charset="utf-8"> <title>10-25 work</title> <style> body{ background-color:#CCC; font-size:12px; font-family:"宋体"; } table{ margin:5px auto; width:60%; padding:5px; } th{ background-color:#76B7BC; font-size:14px; padding:5px; } .even td{/*必须加td,代表的是一行进行*/ background-color:#BCD7DA; padding:5px 6px; } .odd td{ background-color:#FFF;; padding:5px 6px;} </style> </head> <body> <table width="200" border="0"> <tr> <th>序号</td> <th>姓名</td> <th>班级</td> <th>性别</td> <th>电话</td> </tr> <tr class="

HTML-做一个网页的注册登记表单

/* *Copyright (c) 2017,烟台大学计算机学院 All rights reserved. *文件名称:关于HTML的练习 *作 者:张晴晴 *完成日期:201711月5日 *版 本 号:v1.0 * *问题描述:HTML5的新特性 *输入描述: 无 *程序输出: 无 */ <!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>表单练习</title> <style> body{ font-size:12px; font-family:"宋体"; } .bule{ border-color:#ABFEFE;} .font1{ color:#666;} </style> </head> <body> <table width="1400" height="29" border="0" align="center"> <tr> <td width="80" height="29"><img src="img/p1.png" height="29" border="0"></td> <td bgcolor="#B9EDF7"><b>用户注册</b></td> </tr> </table> <br><br> <table width="800" border="0" align="center"> <tr> <td width="80"><b>用户名:</b></td> <td><input type="text" name="name" class="

RabbitMQ 笔记一

前言 过往使用一些简单队列功能,直接上redis,包括pub/sub也都可以使用redis完成简单功能。不过既然RabbitMQ作为消息队列非常成熟的组件,还是值得学习使用。演示环境Centos7,MacOS,所有演示代码可去github上下载demo code,演示代码匀为python实现,所用版本python 3.5 概述 简介 Wiki中给出的介绍是:RabbitMQ是实现了高级消息队列协议(AMQP) 的开源消息代理软件(亦称面向消息的中间件)。 AMQP – Advanced Message Queuing Protocol,一个提供统一消息服务的消息队列协议,属于应用层协议。 RabbitMQ官网 RabbitMQ安装 CentOS 7 CentOS 7中可以直接通过yum源安装 # 依赖 erlang等,如果不能自动安装,手动yum安装下各个依赖 yum install -y rabbitmq-server systemctl startrabbitmq-server 手动安装可以去RabbitMQ官网下载 wget https://github.com/rabbitmq/rabbitmq-server/releases/download/rabbitmq_v3_6_12/rabbitmq-server-3.6.12-1.el7.noarch.rpm # 缺少依赖使用yum安装即可 rpm -i rabbitmq-server-3.6.12-1.el7.noarch.rpm docker启动RabbitMQ docker hub上直接有RabbitMQ的镜像,可以直接使用docker来启动RabbitMQ服务。并且docker RabbitMQ镜像有很多种版本,选用带有RabbitMQ官方提供管理界面的RabbitMQ镜像启动,docker-compose.yml文件内容如下: services: rbmq: image: "rabbitmq:3-management" container_name: test_rbmq ports: - "15672:15672" - "5672:5672" environment: - RABBITMQ_DEFAULT_USER=tester - RABBITMQ_DEFAULT_PASS=test_password restart: always 直接启动 # docker启动RabbitMQ docker-compose up -d docker的相关内容可以参见之前的博文:docker 笔记一,docker 笔记二 服务启动后,可以直接访问界面 http://localhost:15672/#/ 实际效果: 注意: 1.