Universal-Image-Loader,android-Volley,Picasso、Fresco和Glide五大Android开源组件加载网络图片的优缺点比较

在android中的加载网络图片是一件十分令人头疼的事情,在网上有着许多关于加载网络图片的开源库,可以让我们十分方便的加载网络图片。在这里我主要介绍一下我自己在使用Volley, Picasso, Universal-Imageloader的一些使用的感悟。以及最基本的用法介绍。 1.android-Volley 给ImageView设置图片源 // imageView是一个ImageView实例 // ImageLoader.getImageListener的第二个参数是默认的图片resource id // 第三个参数是请求失败时候的资源id,可以指定为0 ImageListener listener = ImageLoader.getImageListener(imageView, android.R.drawable.ic_menu_rotate, android.R.drawable.ic_delete); mImageLoader.get(url, listener); 复制代码 使用NetworkImageView Volley提供了一个新的控件NetworkImageView来代替传统的ImageView,这个控件的图片属性可以通过 mImageView.setImageUrl(url, imageLoader) 复制代码 来设定。而且,这个控件在被从父控件detach的时候,会自动取消网络请求的,即完全不用我们担心相关网络请求的生命周期问题。 mImageLoader = new ImageLoader(mRequestQueue, new BitmapLruCache()); .... ... if(holder.imageRequest != null) { holder.imageRequest.cancel(); } holder.imageRequest = mImageLoader.get(BASE_UR + item.image_url, holder.imageView, R.drawable.loading, R.drawable.error); 复制代码 总结:如果你的工程项目,是一个比较小的项目,或者要求不是很高的项目,处理比较简单的可以使用这个库,这个库是Google 2013 I/O 发布的一个开源库。使用这个库在图片的处理上,没有提供任何的图片处理的操作,个人感觉这个库主要在网络数据连接上比较好,在图片处理上还是不够完善,强大。 2.Picasso Picasso加载网络图片的使用很简单,只需要一行代码就可以搞定。 Picasso.with(context) .load(url).resize(50, 50).centerCrop().into(imageView) 复制代码 Picasso有如下特性: 处理Adapter中的 ImageView 回收和取消已经回收ImageView的下载进程 使用最少的内存完成复杂的图片转换,比如把下载的图片转换为圆角等 自动添加磁盘和内存缓存 总结:如果你的项目里面,对于图片有一些具体的要求的话,建议使用这个库,但是这个库当你需要对图片作一些具体的操作比如加载圆角矩形图片、裁剪图片为圆形时,需要你自己写一些操作,如果基础不够好的会感觉很困难。还有就是这个库我们只能看到结果,无法关心图片的下载过程。 3.Universal-ImageLoader 先要配置ImageLoaderConfiguration这个类实现全局ImageLoader的实现情况。可以选择在Application中初始化设置该类。 使用ImageLoader进行图片加载的时候,先要实例化ImageLoader 总结:这个库有着对加载网络图片的吵详细配置。可以根据个人的喜欢,进行一些配置等等。并且可以实现图片下载过程的监听。且可以支持图片下载完成后,显示圆形或者圆角矩形的图片。

什么是管态?什么事用户态?二者有何区别?

管态:又称系统态,是操作系统的管理程序执行时机器所处的状态。 用户态:又称目态,是用户程序执行时机器所处的状态。 两者区别: 在管态状态下,中央处理机可以使用全部机器指令,包括一组特权指令,可以使用所有的资源,允许访问整个存储区。 在用户态状态下,禁止使用特权指令,不能直接取用资源与改变及其状态,并且只允许用户程序访问自己的存储区域。 转载于:https://www.cnblogs.com/luo841997665/p/4658882.html

【特征检测】FAST特征点检测算法

简介 在局部特征点检测快速发展的时候,人们对于特征的认识也越来越深入,近几年来许多学者提出了许许多多的特征检测算法及其改进算法,在众多的特征提取算法中,不乏涌现出佼佼者。 从最早期的Moravec,到Harris,再到SIFT、SUSAN、GLOH、SURF算法,可以说特征提取算法层出不穷。各种改进算法PCA-SIFT、ICA-SIFT、P-ASURF、R-ASURF、Radon-SIFT等也是搞得如火如荼,不亦乐乎。上面的算法如SIFT、SURF提取到的特征也是非常优秀(有较强的不变性),但是时间消耗依然很大,而在一个系统中,特征提取仅仅是一部分,还要进行诸如配准、提纯、融合等后续算法。这使得实时性不好,降系了统性能。 Edward Rosten和Tom Drummond两位大神经过研究,于2006年在《Machine learning for high-speed corner detection》中提出了一种FAST特征点,并在2010年稍作修改后发表了《Features From Accelerated Segment Test》,简称FAST。注意:FAST只是一种特征点检测算法,并不涉及特征点的特征描述。 FAST详解 FAST特征的定义 FAST的提出者Rosten等将FAST角点定义为:若某像素与其周围邻域内足够多的像素点相差较大,则该像素可能是角点。 FAST算法的步骤 1、上图所示,一个以像素p为中心,半径为3的圆上,有16个像素点(p1、p2、...、p16)。 2、定义一个阈值。计算p1、p9、p5、p13与中心p的像素差,若它们的绝对值有至少3个超过阈值,则当做候选角点,再进行下一步考察;否则,不可能是角点; 3、若p是候选点,则计算p1到p16这16个点与中心p的像素差,若它们有至少连续9个超过阈值,则是角点;否则,不可能是角点。 4、对图像进行非极大值抑制:计算特征点出的FAST得分值(即score值,也即s值),判断以特征点p为中心的一个邻域(如3x3或5x5)内,计算若有多个特征点,则判断每个特征点的s值(16个点与中心差值的绝对值总和),若p是邻域所有特征点中响应值最大的,则保留;否则,抑制。若邻域内只有一个特征点(角点),则保留。得分计算公式如下(公式中用V表示得分,t表示阈值): 上面是FAST-9,当然FAST-10、FAST-11、FAST-12也是一样的,只是步骤3中,超过阈值的个数不一样。FAST算法实现起来简单,尤其是以速度快著称。 以上便是FAST特征检测的过程,清晰明了,而对于角点的定义也是做到了返璞归真,大师就是大师,还原本质的能力很强,估计以前这种简单想法被很多人忽略了。 实验 opencv代码 #include <opencv2/core/core.hpp> #include <opencv2/features2d/features2d.hpp> #include <opencv2/highgui/highgui.hpp> #include <cv.h> #include <vector> using namespace cv; using namespace std; int main() { Mat frame=imread("lena.jpg", 1); double t = getTickCount();//当前滴答数 std::vector<KeyPoint> keyPoints; FastFeatureDetector fast(50); // 检测的阈值为50 fast.detect(frame, keyPoints); drawKeypoints(frame, keyPoints, frame, Scalar(0,0,255), DrawMatchesFlags::DRAW_OVER_OUTIMG); t = ((double)getTickCount() - t)/getTickFrequency(); cout<<"

javascript俄罗斯方块小游戏

任务要求 用javascript实现一个经典的“俄罗斯方块小游戏” 要求:能计分,有不同关卡(速度不同),有高分榜, chrome 30+以上浏览器能正常玩,主流android,iphone手机能玩 设计思路 方块有如下几种基本形状,分别对应代码里的七个数组: 方块变换方式采用将每个方块的四种变换结果均预先存在数组, 例如: [[0,0,0,1,1,1,2,1], [1,0,1,1,1,2,0,2], [0,0,1,0,2,0,2,1], [0,0,1,0,0,1,0,2]];即对应上述 形状1 的四种变换。 每次移动方块,改变的均是(x, y)的值,然后以(x, y)为基坐标,绘制每个方块内部的小方块。下图对应上述数组的第一种变换。 任务进度: 用时约三天,前两天主要完成js部分,实现了基本游戏功能,移动端也做了简单的适配,接下来要就是添加css样式,以及一些页面动画。 (声明:方块变换方式有参考网上,但具体实现及全部代码均为自己所写,并没有UI designer,所以游戏界面如果不太美观的话,,,) 在线演示: http://husterxsp.sinaapp.com/tetris/ github:https://github.com/husterxsp/tetris

深度学习在图像识别中的应用--学习笔记2

控制论与机器学习 控制论的本质:在于利用已有的信息抑制系统熵的增加。 控制论所要做的,便是引入外力作用,即反馈,或者说控制环节,以之降低系统的混乱程度,得到我们的期望输出。 灰盒模型: 灰盒模型,即系统的一部分内容是未知的,另一部分内容是已知的的,例如这里,尽管R、L、C的精确值是未知的,但我们依然可以知道其数值的大致范围。 系统辨识领域的作用:如何解析出一个含有未知参数的系统结构,如果我们可以获取系统的输入输出样本,利用这些样本,配合上含有未知参数的系统结构方程,采取恰当的拟合方法,如最小二乘或极大似然等,最后可以获取未知参数的近似解,使得这个灰盒模型的灰色褪去(但不会褪为白盒模型),进一步便可设计系统的控制环节。 黑盒模型(对系统模型框架和参数都未知)

jenkins离线插件安装入门

在线安装jenkins插件时,很可能报这样的错误: 这是因为无法连接,具体原因我也不清楚,所以我采用了离线安装的方式。 首先我到网址http://updates.jenkins-ci.org/download/plugins/中下载了下面几个插件: 安装插件时,有时会因为依赖缺失的问题无法安装成功。如何知道这件插件的依赖呢?你可以在系统管理->插件管理->可选插件 中选中你要安装的插件,然后点击下方的直接安装,这时候虽然会因为无法连接的问题安装不成功,但是你会知道你要安装插件所需的所有依赖。你要把所有的依赖都下载下来(上面给出的网址)。然后下面介绍如何进行离线安装。 进入:系统管理->插件管理->高级 出现如下界面: 这时候我们是不是看到了中间有个上传插件的地方(其他地方我们的信息不一样可以不管)。 点击选择文件按钮,选中刚才我们下载的插件,注意每次只能选中一个文件,所以先选择依赖文件。然后点击上传按钮。这样依次就可以将所有的插件离线安装成功了!如下图所示: 后面截图我就不一一演示了!

如何把默认壁纸改为动态壁纸

在frameworks/base/core/res/res/values目录找到Config.xml文件,最后一行有定义: <string name="default_wallpaper_component">null</string> 将其修改为对应的live wallpaper的启动component即可,如要把默认壁纸设置为2.1自带的galaxy,这样写即可: <string name="default_wallpaper_component">com.android.wallpaper/com.android.wallpaper.galaxy.GalaxyWallpaper</string> 需要注意的是:静态的图片壁纸和live wallpaper是两个系统,加载的时候是完全两套机制,静态图片通过launcher里面的一个xml文件配置来管理系统默认静态壁纸,live wallpaper则是通过intent机制向系统搜寻所有匹配Activity,所以,这里的默认值为null,而不是那个系统默认静态壁纸的地址,系统是读config.xml文件的设置,若为null才继续查找静态壁纸配置内容. 如果只需要修改默认静态壁纸,替换frameworks/base/core/res/res/drawable/default_wallpaper.jpg即可,或者在源码中修改对应default_wallpaper地址.

Idea SpringMVC+Spring+MyBatis+Maven整合

创建项目 File-New Project 选中左侧的Maven,选中右侧上方的Create from archetype,然后选中下方列表中的webapp,然后点击Next 在GroupId和ArtifactId中填入指定内容,点击Next 直接点Next 输入项目名称,Finish Idea会自动开始下载所依赖的包,等待其完成。 项目结构 项目刚建好的时候是没有这些文件的,所以自己手动创建缺少的文件夹(包) 创建完后的项目框架: 修改pom.xml导入依赖包插件 依赖包需要如下: spring framework aspectj事务 c3p0数据源 servlet/jsp api junit4 mybatis mybatis spring整合 mysql driver jstl <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.elin4it.ssm</groupId> <artifactId>ssm</artifactId> <packaging>war</packaging> <version>1.0-SNAPSHOT</version> <name>ssm Maven Webapp</name> <url>http://maven.apache.org</url> <build> <finalName>ssm</finalName> <plugins> <!--mybatis 逆向工程插件--> <plugin> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-maven-plugin</artifactId> <version>1.3.2</version> <configuration> <verbose>true</verbose> <overwrite>true</overwrite> </configuration> </plugin> </plugins> </build> <properties> <spring.version>4.1.1.RELEASE</spring.version> </properties> <dependencies> <!-- springframe start --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.

检测手机屏幕的旋转

在特别的场景下,需要针对屏幕旋转作特殊处理。在ios系统下实现相关的功能还是比较方便的。 我下面介绍两种方法: 1.注册UIApplicationDidChangeStatusBarOrientationNotification通知(举例:在一个viewcontroller类的viewdidload中注册该通知),示例代码如下: [[NSNotificationCenterdefaultCenter] addObserver:selfselector:@selector(statusBarOrientationChange:)name:UIApplicationDidChangeStatusBarOrientationNotificationobject:nil]; - (void)statusBarOrientationChange:(NSNotification *)notification { UIInterfaceOrientation orientation = [[UIApplicationsharedApplication] statusBarOrientation]; if (orientation ==UIInterfaceOrientationLandscapeRight) // home键靠右 { // } if ( orientation ==UIInterfaceOrientationLandscapeLeft)// home键靠左 { // } if (orientation ==UIInterfaceOrientationPortrait) { // } if (orientation ==UIInterfaceOrientationPortraitUpsideDown) { // } } 注意这种方式监听的是StatusBar也就是状态栏的方向,所以这个是跟你的布局有关的,你的布局转了,才会接到这个通知,而不是设备旋转的通知。 当我们关注的东西和布局相关而不是纯粹设备旋转,我们使用上面的代码作为实现方案比较适合。 2.注册UIDeviceOrientationDidChangeNotification通知(举例:我们同样在一个viewcontroller类的viewdidload中注册该通知),示例代码如下: [[NSNotificationCenter defaultCenter] addObserver:selfselector:@selector(orientChange:)name:UIDeviceOrientationDidChangeNotificationobject:nil]; - (void)orientChange:(NSNotification *)noti { NSDictionary* ntfDict = [noti userInfo]; UIDeviceOrientation orient = [UIDevicecurrentDevice].orientation; /* UIDeviceOrientationUnknown, UIDeviceOrientationPortrait, // Device oriented vertically, home button on the bottom

图像的泊松(Poisson)编辑、泊松融合完全详解

在之前的文章中,我们详细介绍了基于泊松方程的图像编辑与融合技术的算法原理。本部分是该系列文章的最后一篇,这里我们将讨论算法的离散化数值实现,并给出相应的MATLAB代码,实现结果如图下图(左图)所示,可见图像融合的效果还是非常理想。 全文完。

textfield实现类似 Wechat 登录 按钮的状态

//实时监测textfield中的内容 当输入的内容是一个手机号后 并且textfieldpassword输入内容时将发送验证码button的颜色变红 - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{ UITextField *textfield1 = (UITextField *)[self.view viewWithTag:555];//手机号码 UITextField *textfield2 = (UITextField *)[self.view viewWithTag:666];//密码 NSString *str1 = [NSString stringWithFormat:@"%@",textfield1.text]; NSString *str2 = [NSString stringWithFormat:@"%@%@",textfield2.text,string]; if (textField.tag == 666 && [str1 isMobilePhoneNumber] && str2.length > 0) { buttonLogin_.backgroundColor = DCOLOR_RED_5_0; } //对组件增加监听器 [textField addTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged]; return YES; } //textfield实时监测的回调函数,作用为当textfield.length == 0 时将按钮变为不可点击状态 - (void) textFieldDidChange:(id) sender { UITextField *_field = (UITextField *)sender; NSLog(@"

UVM:8.2.3 复杂的重载

1.UVM支持连续的重载: 结果: 2.替换的重载:从bird 派生出了新的鸟sparrow: 输出: 1)组后一个有效。 2)前提是replace参数为1。(默认为1) 3)如果为0。 第二次无效。 在创建bird 时,factory 查询到两条相关的激励,它要看到最后一条,然后建立sparrow 实例。 3.所以下列也是可以的: 输出: 1)与第三条违背,前提是最终的类要与被重载的类有派生关系。 2)没有例化parrot,否则会错。 replace为0应该不成功才对呀!!

textfield在实际开发中用到的代理方法

#pragma mark - UItextFieldDelegate //点空白收键盘 -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { [self.view endEditing:YES]; } //点done收键盘 - (BOOL)textFieldShouldReturn:(UITextField *)textField { [textField resignFirstResponder]; return YES; } //实时监测textfield中的内容 当输入的内容是一个手机号后 将发送验证码button的颜色变红 - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{ NSString *str1 = [NSString stringWithFormat:@"%@%@",textField.text,string];//str1:手机号 if([str1 isMobilePhoneNumber]) { buttonCode_.backgroundColor = DCOLOR_RED_5_0; }else{ } return YES; }

test

sed 是一个比较古老的,功能十分强大的用于文本处理的流编辑器,加上正则表达式的支持,可以进行大量的复杂的文本编辑操作。sed 本身是一个非常复杂的工具,有专门的书籍讲解 sed 的具体用法,但是个人觉得没有必要去学习它的每个细节,那样没有特别大的实际意义。网上也有很多关于 sed 的教程,我也是抱着学习的心态来学习 sed 的常见的用法,并进行系统的总结,内容基本覆盖了 sed 的大部分的知识点。文中的内容比较简练,加以实际示例来帮助去理解 sed 的使用。 一、写在前边 1、sed介绍 sed 全名为 stream editor,流编辑器,用程序的方式来编辑文本,功能相当的强大。是贝尔实验室的 Lee E.McMahon 在 1973 年到 1974 年之间开发完成,目前可以在大多数操作系统中使用,sed 的出现作为 grep 的继任者。与 vim 等编辑器不同,sed 是一种非交互式编辑器(即用户不必参与编辑过程),它使用预先设定好的编辑指令对输入的文本进行编辑,完成之后再输出编辑结构。sed 基本上就是在玩正则模式匹配,所以,玩sed的人,正则表达式一般都比较强。 2、sed工作原理 sed会一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,成为"模式空间",接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有改变,除非你使用重定向存储输出。 3、正则表达式概念 在编写处理字符串的程序或网页时,经常会有查找符合某些复杂规则的字符串的需要。正则表达式就是用于描述这些规则的工具,换句话说,正则表达式就是记录文本规则的代码。许多程序设计语言都支持利用正则表达式进行字符串操作。在很多文本编辑器里,正则表达式通常被用来检索、替换那些符合某个模式的文本。 4、正则表达式的匹配过程 简单描述一下正则表达式的匹配过程,就是拿正则表达式所表示的字符串去和原文字符串内容去匹配,直到匹配到原文内容字符串中的一个完整子串就表示匹配成功。举个例子,有一行文件内容"this is better desk",这里用"esk"去匹配,匹配过程是这样的:首先拿e去匹配文件行内容,从this开始,直到better的e,第一个字符匹配成功,接着s去匹配better字符e后边的t字符,没有匹配成功;然后重新拿esk中的e去和better的第二个t去匹配,没有成功,接着原始内容的下一个字符,直到desk中的e字符,逐个匹配s,k字符,到此为止,esk成功匹配,正则表达式匹配完毕,整个过程就是这样,即使再复杂的正则表达式的匹配过程也是按照此过程来进行的。 二、基本正则表达式 关于正则表达式的内容挺多的,掌握好下文中提及的内容就能满足正常工作中的需要,如果是专门做正则编程的,可以去买本正则表达式的书籍来看好了^_^。只有多动手多练习,才是学开发编程的最好姿势。 1. 符号"." 匹配任意一个字符,除了换行符,但是需要注意的是,在sed中不能匹配换行符,但是在awk中可以匹配换行符。类似shell通配符中的"?",匹配一个任意字符。 2. 符号"*" "*"表示前边字符有0个或多个。".*"表示任意一个字符有0个或多个,也就是能匹配任意的字符。类似shell通配符中的"*",可以匹配任意字符。 3. 符号"[]" "[ ]"中括号中可以包含表示字符集的表达式。使用方法大概有如下几种。 [a-z]:表示a-z字符中的一个,也就是小写字母。 [0-9]:表示0-9字符中的一个,也就是表示数字。 [A-Z]:表示大写字母。 [a-zA-Z]:表示字符集为小写字母或者大写字母。 [a-zA-Z0-9]:表示普通字符,包括大小写字母和数字。 [abc]:表示字符a或者字符b或者字符c。 [^0-9]:表示非数字类型的字符,^表示取反意思,只能放在中括号的开始处才有意义。 [-cz]:表示字符-或者字符c或者字符z,注意与[c-z]的区别,因为-符号没有放在e和f之间。 4. 符号"^" "^"表示行首的意思,也就是每一行的开始位置。在这里并不是上边字符范围中取反的意思,^符号只有在"[]"符号的开头处才能表示字符取反。 ^abc:表示以abc开头的字符串abc。 ^abc.*:表示以abc开头的字符串abcxxx。 5. 符号"$"

如何扩展大规模Web网站的性能?

Reduce Data广告服务网站如何扩展到每天300K QPS请求?分享经验如下: 为大规模设计,广告服务平台从一开始增长就很惊人,因此,系统开始就为大规模设计,系统为水平和垂直伸缩扩展。 选择CAP定理中的AP(可用性和分区容错性)二不是CA(一致性和可用性),因为广告拍卖与服务平台是追求低延迟和高性能,数据的高一致性不是非常关键。 没有锁定专门厂商软件或专利技术的限制使用,积极使用开源软件,开源软件已经达到非常成熟的程度。 基于Mechanical Sympathy(顺硬件之势而为)构建系统,一个软件的建立应该是基于理解硬件如何工作以及如何更好利用硬件。 云技术的限制使用,他们很早就决定对云技术的有限使用,因为a)EC2和计数部分往往非常昂贵;b)在对EC2早期的测试中发现网络抖动jitter、磁盘虚拟化等会增加延迟。 延迟总是存在,对付它而不是设法消除它。所有查找都应该发生在1ms以下。 利用RocksDB和各种其他解决方案作为主要的缓存/嵌入式数据库。 使用SSD固态硬盘降低延迟。 没有虚拟化硬件,充分利用高配置硬件(256G内存和24核机器)并行化许多计算。 磁盘写操作,每N秒定时flush写入大块数据。 Nginx用于支持keep-alive连接,而Netty优化支持大型并发负载。 为了保证广告服务器中关键数据始终是立即可用(访问延迟以微秒计),所有这些数据都是存储内存中库/数据结构中。 架构应该使用share nothing,当我们增减服务器时,系统应该是丝毫不受影响,眼睛都不会眨一下。 所有关键数据 结果都需要复制。 保持每天的原始记录日志拷贝。 如果数据有点脏,系统发生数据不一致性,这一切也是正常。 消息系统应该是容错的,它们可以崩溃但是不会丢失数据。 下面是具体设施情况: 跨3个数据中心的40–50节点(primarily US and two nodes in Germany) 其中30台运行高计算(128–256G RAM, 24 cores, top of the line CPUS and where possible SSDs) 其余机器配置低一些, 32G RAM, Quadcore 机器 10G 私有网 + 10G 公网 小型 Cassandra, Hbase 和 Spark 集群 使用关键技术是: HBase 和 Cassandra 用于计数聚合,以及管理用户和账号数据集, Hbase 因为其高性能写操作,能够很好处理计数器,并提供近实时的分析。 后端主要语言是 Java. 尽管有C++ 和 Erlang经验,但是Java有更可用的成熟技巧以及过去几年JVM相当成熟。

Android studio 使用Menu(菜单)

转载请注明出处: http://blog.csdn.net/lb377463323/article/details/46722831 1,打开res目录下的mune文件夹,如下图 2,在menu_main.xml中添加如下代码: <menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" tools:context=".MainActivity"> <item android:id="@+id/add_item" android:title="Add" /> <item android:id="@+id/remove_item" android:title="Remove" /> </menu> 3,在MainActivity中重写onCreatOptionsMenu()方法,如下: @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.menu_main, menu); return true; } 4,在MainActivity中重写on=OptionsItemSelected()方法,如下: @Override public boolean onOptionsItemSelected(MenuItem item) { switch(item.getItemId()){ case R.id.add_item: Toast.makeText(this,"you clicked Add",Toast.LENGTH_SHORT).show(); break; case R.id.remove_item: Toast.makeText(this,"you clicked Remove",Toast.LENGTH_SHORT).show(); break; default: } return true; } } 5,运行程序,如下显示:

斯坦福兔子和其他图形学模型数据下载

常见模型的下载地址:http://www.cc.gatech.edu/projects/large_models/ 斯坦福兔子的下载地址:http://www.cc.gatech.edu/projects/large_models/bunny.html 斯坦福兔子的官方主页:http://www.cc.gatech.edu/~turk/bunny/bunny.html http://graphics.stanford.edu/data/3Dscanrep/ 其他的一些模型:http://www.cc.gatech.edu/~turk/zipper/zipper.html

matlab读入三维点云数据斯坦福兔子

其中点云数据是斯坦福兔子,做三维点云重构后的人可以好好看看,只是简单读入程序,作为初学者比较好些,进一步的研究还在后边,有机会的话会继续上传,比如说delauny三角网格划分,还想进一步研究snake曲线 下载地址:http://download.csdn.net/detail/u013467442/8847911 function point_cloud() clc; A=importdata('bunny.txt'); [IX,IY]=size(A); %IX x=A(:,1); y=A(:,2); z=A(:,3); plot3(x,y,z,'.') grid on 资源链接:http://www.codeforge.cn/article/244921

Objective-C中的hasPrefix

Objective-C中的hasPrefix hasPrefix:方法的功能是判断创建的字符串内容是否以某个字符开始,其语法形式如下: -(BOOL)hasPrefix:(NSString*)aString; 其中,(NSString *)aString;用来指定字符串。该方法的返回值为BOOL,当BOOL为YES或者为1时, 则字符串是以某个字符开始;当BOOL为NO或者为0时,则字符串不是以某个字符开始。 【示例】以下程序通过使用hasPrefix:方法来判断使用stringWithCString: 方法创建的字符串是否以字母B开始,如果是以字母B开始,输出开头为字母B;如果不是, 输出开头不为字母B。程序代码如下: #import <Foundation/Foundation.h> int main(int argc,constchar* argv[]) { @autoreleasepool{ NSString*a=[NSString stringWithCString:"ABCDEF" encoding:NSASCIIStringEncoding]; if([a hasPrefix:@"B"]==YES){//判断字符串是否以B字符开始 NSLog(@"开头为字母B"); }else{ NSLog(@"开头不为字母B"); } } return0; } 运行结果如下: 2013-03-1918:10:02.0874-13[751:303]开头不为字母B

向右滑动返回上一级界面

/* 向右滑动返回上一级界面,将代码写在第一级界面,那么后面的界面也都可以实现此功能, if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) { self.navigationController.interactivePopGestureRecognizer.enabled = YES; self.navigationController.interactivePopGestureRecognizer.delegate = self; } if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) { self.navigationController.interactivePopGestureRecognizer.delegate = self; } */

Cortex_m3的启动过程

一.arm的启动过程 arm的启动代码一般是用汇编写的,在堆栈建立以后才可以运行C代码,因为C函数调用需要把参数,函数返回地址入栈,堆栈没有建立不能运行C代码。 应用程序启动过程 应用程序启动过程: 1.映像入口地址,一般为0X00000000地址,也可以指定为其他的地址,硬件复位起来,从地址0x00000000处取指,地址0x00000000处放的复位服务函数的地址,就会进入复位服务函数。在复位函数里做一些系统的初始化,然后调用系统函数_main(); 2._main 直接跳转到 __scatterload,__scatterload 执行代码和数据复制以及 ZI 数据的清零。根据分散加载文件,拷贝RW数据到RAM,在RAM空间里建立ZI的数据空间,建立运行时的映像存储器映射,然后跳转到 __rt_entry(运行时的入口)则负责初始化 C 库。还设置应用程序的栈和堆,初始化库函数及其静态数据。 3.这时应用程序的堆栈建立了,跳转到main()函数,运行用户代码。 二. 存储器映射的建立 1.编译链接生成的ELF文件 ELF文件格式 链接器根据输入节的属性在一个区内对它们进行排序。 具有相同属性的输入节在区内形成相邻块。链接生成的ELF文件里的数据节。 RO:包括代码和只读数据(.init .text .rodata) RW:读写数据(.data) ZI:未初始化的数据,在装载区不分配空间,执行区才分配空间。(.bss) 2. 映像的加载区和执行区 加载区: 根据映像加载到内存时所在的地址(即映像开始执行之前的位置)。 执行区: 映像执行时所在的地址。 根区: 加载区和执行区的地址相同。 加载区和执行区 一般下载到FLASH里的2进制文件就放在加载区,上图中的0X0000-0X4000空间。应用程序启动时,__scatterload函数根据分散加载文件把RW数据节拷贝到RAM空间,然后在RAM空间分配ZI数据节的空间。因为对RAM空间里数据的读写比FLASH快。一般把RW的数据拷贝到RAM。RO节的数据不做处理。这样运行时的存储器空间就建立起来了。 二.堆栈的设置 __user_initial_stackheap() 可用 C 或 ARM 汇编语言来编写。它必须返回以下参数: • r0 中的堆基址; • r1 中的栈基址; • r2 中的堆限制(双区模型); • r3 中的栈限制(双区模型)。 堆栈的模式有2种:单区模式,双区模式。 1.单区模型 默认情况下为单区模型,应用程序的堆和栈在同一存储器区中互相朝向对方增长,其中栈从地址 0x40000 向下增长,堆从地址 0x20000 向上增长。将相应的值加载到寄存器 r0 和 r1,然后返回。r2 和 r3 保持不变,因为在单区模型中不使用堆限制和栈限制。 EXPORT __user_initial_stackheap

mysql下sql语句 update 字段=字段+字符串 拼接

mysql下sql语句 update 字段=字段+字符串 mysql下sql语句令某字段值等于原值加上一个字符串 update 表明 SET 字段= 'feifei' || 字段; (postgreSQL 用 || 来连贯字符串) MySQL连贯字符串不能利用加号(+),而利用concat。 比方在aa表的name字段前加字符'x',利用: update aa set name=concat('x',name) YEARWEEK(date_format(FOrderDate,'%Y-%m-%d'),1) = YEARWEEK(now(),1) 本周 date_format(Date,'%Y-%m-%d') 日期 TO_DAYS(NOW()) select count(FId) from TcOrder where date_format(FOrderDate,'%Y-%m')=date_format(now(),'%Y-%m') 本月 select count(FId) from TcOrder where YEARWEEK(date_format(FOrderDate,'%Y-%m-%d'),1) = YEARWEEK(now(),1) 本周 select count(FId) from TcOrder where TO_DAYS(NOW()) - TO_DAYS(FOrderDate)=1 昨日 select count(FId) from TcOrder where TO_DAYS(NOW()) = TO_DAYS(FOrderDate) 今日 select count(FId) as f,sum(FReceivableAmount) as r from TcOrder where (FStatus='Payed' or FStatus='Finished') "

在SAS数据集中插入列并赋值

data students1; input name$ major$ t1 t2 t3; cards; 张三 math 62 82 92 李四 eng 73 83 93 王五 geo 66 76 86 刘六 history 80 90 100 ; run; proc sql ; alter table students1 /*alter是数据集结构修改关键字,后有详解*/ add avg num label='平均值' format=5.2 /*add 字段名 变量类型 标签名 格式*/ ; update students1 set avg=(t1+t2+t3)/3 ; quit; Alter详述: alter是数据集结构修改关键字 如将字段改成字符型: Alter table work.test modify fname CHAR(12) 删除字段: Alter table work.test drop age,height,weight

Android 关闭应用程序的6种方法

1.方法一killProcess结束进程 android.os.Process.killProcess(android.os.Process.myPid()); android中所有的activity都在主进程中,在Androidmanifest.xml中可以设置成启动不同进程,Service不是一个单独的进程也不是一个线程。当你Kill掉当前程序的进程时也就是说整个程序的所有线程都会结束,Service也会停止,整个程序完全退出。 2.方法二exit结束java虚拟机 System.exit(0); 这个方法是用来结束当前正在运行中的java虚拟机。如何status是非零参数,那么表示是非正常退出。当调用System.exit(0)时,杀死了整个进程,这时候活动所占的资源也会被释放。 和return 相比有以下不同点:return是回到上一层,而System.exit(status)是回到最上层。进一步探索System.exit被调用后的行为,它在虚拟机在退出前会执行两个清除任务。第一,它会执行所有通过Runtime.addShutdownHook注册的shutdownhooks.它能有效的释放JVM之外的资源。第二,执行清除任务,运行相关的finalizer方法终结对象。 在android手机中查看当前正在运行的进程时可以发现还可以查看"后台缓存的进程",你会发现很多退出了的程序还在后台缓存的进程中,如果不要让程序在后台缓存那么就可以用System.exit(0);来退出程序了,可以清除后台缓存的本进程,对于有些手机也是没有用的。这是退出Java程序的方法,也可以用来退出Android。 3.方法三通过activity管理器重启,这个方法已经过时,不建议再使用 ActivityManager activitymanager= (ActivityManager)getSystemService (Context.ACTIVITY_SERVICE); activitymanager.restartPackage(getPackageName()); 注意:需要注册的权限<uses-permission android:name=\"android.permission.RESTART_PACKAGES\"></uses- permission> 在android2.2版本之后则不能再使用restartPackage()方法,而应该使用killBackgroundProcesses()方法 ActivityManager manager = (ActivityManager)getSystemService(ACTIVITY_SERVICE); manager.killBackgroundProcesses(getPackageName()); //需要在xml中加入权限声明 <uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES"/> 注意:在android2.2以后,如果服务在ondestroy里加上了start自己,用kill backgroudprocess通常无法结束自己。 定外一种方法:利用反射 Method forceStopPackage = am.getClass().getDeclaredMethod("forceStopPackage", String.class); forceStopPackage.setAccessible(true); forceStopPackage.invoke(am, yourpkgname); <uses-permission android:name="android.permission.FORCE_STOP_PACKAGES"></uses-permission> 需要在manifest里加上shareduid定义 android:sharedUserId="android.uid.system" 并且采用系统platform签名 因为需要用FORCE_STOP_PACKAGES权限,该权限只赋予系统签名级程序 4.方法四根据Activity的生命周期 我们知道Android的窗口类提供了历史栈,我们可以通过stack的原理来巧妙的实现,这里我们在A窗口打开B 窗口时在Intent中直接加入标志 Intent.FLAG_ACTIVITY_CLEAR_TOP,这样开启B时将会清除该进程空间的所有Activity。 Intent intent = new Intent(); intent.setClass(MainActivity.this, SecondActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); //注意本行的FLAG设置 startActivity(intent); 5.方法五finish()将活动推向后台 finish();finish是Activity的类,仅仅针对Activity,当调用finish()时,只是将活动推向后台,并没有立即释放内存,活动的资源并没有被清理; 6.方法六 比较常用的方法,使用Activity栈管理Activity package com.example.test; import java.util.ArrayList; import java.util.List; import java.

Java数组求平均数且输出大于平均数的数字

package scaner; import java.io.InputStream; import java.util.Scanner; public class Arr { public static void main(String[] args) { // TODO Auto-generated method stub Scanner in = new Scanner(System.in); double sum= 0; int cnt = 0; cnt = in.nextInt();//用户输入数组的长度 if(cnt>0){ int[] number = new int [cnt];//定义cnt长度的数组 //输入数组并且遍历 for(int i = 0;i<number.length;i++){ number[i] = in.nextInt(); sum += number[i]; } double avr = sum*1.0/cnt;//平均数 <span style="white-space:pre"> </span>//遍历数组,输出大于平均数的数字 for(int i = 0;i<number.length;i++){ if(number[i]>avr){ System.out.println(number[i]); } } System.

SAS数据步常用语句

一、 DATA语句 DATA语句的作用是表明数据步的开始并给出数据集 的名称。 DATA语句的格式为: DATA 数据集的名称; 数据集的名称必须以英文字母开始,最长不超过8个字符。 二、CARDS语句 CARDS语句的作用是与“;”呼应,标志数据行的开始与结束。 CARDS语句的格式为: CARDS; 数据行 ; 如果使用CARS语句,在CARDS的后面必须紧跟数据行,并且在一个数据步中最多只能使用一个CARDS语句。 三、INPUT语句 INPUT语句的作用是描述输入记录中的数据,并把输入值赋给相应的变量。 INPUT语句的格式为: INPUT 数据的变量名、顺序及类型; 用INPUT语句是为了读取外部文件的数据或跟在CARDS语句后面的数据。 SAS默认用INPUT语句读取的是数值类型变量的值。若在变量后加’$’,则该变量为字符串类型变量。 为从一行读入多个观测值,应使用行保持符’@@’限制度数指针,使其保持在这一行上读数,知道数据读完为止。 例如: Inputx y@@; Cards; 23 4 5 6 7 8 ; 列方式: input name$ 1-8 age 11-12 /* 变量name所属的列为1-8列;变量age所属的列为11-12列*/ 格式化方式: input a $ 9 b 3 /*变量a的长度为9个字符,变量b的长度为3个字符*/ 四、INFILE语句 Infile语句的作用是指明外部数据文件的名称,并从这个外部数据文件中读取数据。 INFILE语句的格式为: INFILE ‘外部数据文件名’; 例如,在D盘上有一个名称为xiao.txt的数据文件, 其中数据排列为: A 3.16 B 2.9 B 5.8B 3 A 4.9 A 4.17 用 INFILE语句读取数据的代码为:

Malloc size的大小

在做Asan的时候,遇到了False Positive的问题,对于应用程序,如果其malloc了一段空间,如: void *ptr = malloc(3); Asan会将ptr所对应的Shadow Memory 置为0x03,来标记该地址只有3Bytes可以被访问,加上RedZone的Shadow Memory。 如果我们将libc中的API也用Asan来监视是否有Memory overflow,那么便会造成Asan False Positive的问题。究其原因是由于在libc在实现malloc(size_t size)时,会对size进行对齐,并增加size的大小以维护所分配block的信息,而该信息块所对应的Memory正好被Asan标记为不可访问的。 顺便研究了下libc中在实现malloc(size_t size)时,对不同的size,所分配的总空间的大小。 对于malloc(size_t size),我们可以访问超过size空间的大小: char *ptr = (char *)malloc(3); ptr[5] = 'B'; 这说明我们在调用malloc申请memory的时候,往往会得到一块比我们所申请的空间大的memory,那么大多少呢,这里涉及到libc中malloc的算法。实际上当我们使用malloc申请一段大小为size的Memory时,libc会对size的大小进行调整: 加上信息块大小。32bit系统中为4Byte,64bit系统中为8Byte。size += 4;orsize += 8;对齐。#define MALLOC_ALIGNMENT (2 * sizeof(size_t))以MALLOC_ALIGNMENT进行对齐,在32bit系统中为8 Byte,在64 bit系统中多为16Byte。分配内存。 malloc所分配的内存最小为16Byte(for 32bit system)或32Byte(for 64bit system)。因此最终当我们调用malloc申请size大小的memory时,总共会得到: malloced_size = max(16, RoundUpTo(size + 4, 8)); // for 32 bit systemor malloced_size = max(32, RoundUpTo(size + 8, 16)); // for 64 bit system 虽然我们能够读写超过我们所申请的size大小的内存,但是一旦我们改变了该block的信息块,我们将无法free所申请的内存空间,会造成内存泄露问题。

SAS中关于PDV的总结

什么是PDV 个人认为可以把PDV想象成一排用于存放变量值的盒子。每个盒子代表一个变量。 提交一个DATA步后,SAS会对这个DATA步进行编译,然后执行。 首先,PDV是在DATA步的编译阶段生成的。(编译会进行语法检查并创建一排整齐摆放的”盒子”); 然后,在DATA步的执行阶段,根据不同语句对PDV中变量的值进行清空或更改。(将盒子清空或换上新的物品); 最后,在RUN;语句或者OUTPUT;语句将PDV中变量的当前值输出到目标数据集中。KEEP,DROP语句或KEEP=,DROP=数据集选项会影响输出到目标数据集中变量的个数。(如果没有KEEP/DROP,将新建变量和数据集变量对应的盒子搬出到目标数据集;如果只有KEEP,则只搬KEEP指定的盒子;如果只有DROP,则不搬DROP指定的盒子;如果KEEP/DROP同时存在,则只搬KEEP-DROP后剩下的盒子) PDV中变量的个数及顺序 DATA步中所涉及到的所有的变量,包括新创建的、从其他数据集读取的(SET)、以及自动生成的变量。自动生成的变量包括:_ERROR_,_N_; 或是FIRST.VAR,_IORC_等由某个语句或选项所自动产生的变量。默认情况下,自动生成的变量不会输出到目标数据集中。 PDV中变量按照先来后到的原则,是根据其在DATA步中第一次出现的位置决定整个PDV中的变量顺序。同样,这是在DATA步的编译阶段确定的。(在SET语句中,数据集选项IN=所指定的变量会在数据集变量之前)PUT _ALL_; 语句会将PDV中所有的变量按照其在PDV中的顺序输出到log中。 例如下面这个例子: data test; aaa=1; set sashelp.class(keep=name sex in=in1); by name; bbb="bbb"; set sashelp.class(keep=age weight height in=in2); put _all_; run; 在PDV中共有13个变量,包括两个新创建的(aaa,bbb),5个数据集中的,6个自动生成的(in1,first.name,last.name,in2, _error_, _n_)。 顺序为:aaa, in1, name, sex, first.name, last.name, bbb, in2, age, weight, height, _error_,_n_。 关于PDV中变量值的 RETAIN 一般情况下,DATA步的执行是一个循环的过程,也就是SAS运行到DATA步最后一句后会默认回到DATA语句继续执行。在回到DATA语句再次执行这个DATA步的代码的时候,就会涉及到是否对PDV中变量已有的值清空,这就是RETAIN要做的。 ( 这里用“一般情况下”,是因为有些情况下,SAS不会回到DATA语句,而是在RUN;语句就结束了。如: *** No data read from outside; data a; put _all_; x=1; run; *** No data read from the first iteration(_N_=1); data b; x=2; put _all_; if x=1 then set sashelp.

CentOS中安装JDK与Intellij idea

卸载CentOS中自带openjdk CentOS自带openjdk,可以先用java –version检测是否存在jdk版本。如果存在,最好在安装oracle的jdk之前最好卸载,可以使用如下指令 yum -y remove java java-1.4.2-gcj-compat-1.4.2.0-40jpp.115 yum -y remove java java-1.6.0-openjdk-1.6.0.0-1.7.b09.el5 安装JDK 先从oracle官网下载对应的JDK版本 http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 本人选择的是linux x86 .tar.gz版本 下载完成后在/usr 中创建java目录,用来存放跟java有关的文件。然后把下载jdk压缩包的文件解压到该路径下 tar –xzvf jdk jdk-8u45-linux-i586.tar.gz 顺便重命名一下,方便以后写路径 mv jdk1.8.0_45 jdk1.8 配置环境变量 vim /etc/profile 然后添加环境变量 export JAVA_HOME=/usr/java/jdk1.8 export CLASSPATH=.:$JAVA_HOME/jre/lib/rt.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar export PATH=$PATH:$JAVA_HOME/bin 让其立刻生效 source /etc/profile 然后可以执行 java –version 看其版本号是否为1.8,如果有结果了且为1.8,至此jdk安装成 安装idea 到https://www.jetbrains.com/idea 下载对应版本的文件,然后将其解压。然后进入到解压后文件夹的bin目录下执行 ./idea.sh 将进入安装程序,因为该程序为gui界面的程序,所以不能在command界面下安装。 切记,在安装前必须配置好JAVA环境变量。 安装tomcat 从http://tomcat.apache.org/下载需要的版本,下载完后将其解压到/usr/java中,然后进入到bin目录下执行 ./startup.sh 然后在浏览器访问127.0.0.1:8080,如果显示tomcat的管理页面,就表示安装成功了。

db2 sequences值

1、创建sequence CREATE SEQUENCE TEST_SEQ AS bigint START WITH 1 INCREMENT BY 1 NO MAXVALUE CYCLE CACHE 20; 2、查看 select * from syscat.sequences 其中NEXTCACHEFIRSTVALUE是 下一个缓冲的第一个序列值,按照创建定义,缓冲大小为20,那么本次缓冲为1-20,下一个缓冲首值就是21,让缓冲值超过20,那么此值将会增长为21+20=41; ==== values nextval for $SEQNAME 使sequence值增长========= 此时的NEXTCACHEFIRSTVALUE情况: 因此可以通过此值来大致判断当前的sequence的范围值在NEXTCACHEFIRSTVALUE-CACHE内。 在巡检数据库时,可以以此为参考,知道现在的sequence是不是太大。 select * from syscat.sequences 查看NEXTCACHEFIRSTVALUE的值即可。

linux命令详解——tar

tar [-cxtzjvfpPN] 文件与目录 .... 【参数】: -c :建立一个压缩文件的参数指令(create 的意思); -x :解开一个压缩文件的参数指令! -t :查看 tarfile 里面的文件! -r:向压缩归档文件末尾追加文件 -u:更新原压缩包中的文件 特别注意,在参数的下达中, c/x/t 仅能存在一个!不可同时存在! 这五个是独立的命令,压缩解压都要用到其中一个,可以和别的命令连用但只能用其中一个。下面的参数是根据需要在压缩或解压档案时可选的: -z :是否同时具有 gzip 的属性,亦即是否需要用 gzip 压缩。 -j :是否同时具有 bzip2 的属性,亦即是否需要用 bzip2 压缩。 -Z: 是否同时具有 compress的属性,亦即是否需要用 compress压缩。 -v :压缩的过程中显示文件!这个常用,但不建议用在背景执行过程! -O:将文件解开到标准输出 -p :使用原文件的原来属性(属性不会依据使用者而变),恢复字段到它们的原始方式,忽略现有的用户权限屏蔽位(umask)。 加了-p之后,tar进行解压后,生成的文件的权限,是直接取自tar包里面文件的权限(不会再使用该用户的umask值进行运算),那么不加-p参数,将还要再减去umask的值(位运算的减),但是如果使用root用户进行操作,加不加-p参数都一样。 -P :不剥离起始路径的“/”目录,可以使用绝对路径来压缩!一般情况下,待压缩的目录如果是一个绝对路径,压缩后会将根目录符号/去掉,这样,在解压时,得到的目录结构是以当前目录为基础目录的,如果在压缩时加上-P,则解压时还是以根目录为基础目录。 -N :比后面接的日期(yyyy/mm/dd)还要新的才会被打包进新建的文件中! -C:解压到某个目录 --exclude FILE:在压缩的过程中,不要将 FILE 打包! 下面的参数-f是必须的: -f: 使用档案名字,切记,这个参数是最后一个参数,后面只能接档案名。例如使用『 tar -zcvfP tfile sfile』就是错误的写法,要写成 『 tar -zcvPf tfile sfile』才对! 【范例】: 范例一:将整个 /etc 目录下的文件全部打包成为 /tmp/etc.tar [root@linux ~]# tar -cvf /tmp/etc.

Linux 搭建 GIT 仓库 Gitblit

Linux 搭建 Gitblit 使用 gitblit,服务器文档: http://gitblit.com/setup_go.html 。先安装好 JDK:http://blog.csdn.net/jerome_s/article/details/26094135#t0 。 Git 客户端操作文档: http://git-scm.com/doc。 Git 起动命令: nohup ./gitblit.sh & 安装好一般修改管理员密码和添加用户。 使用 Eclipse 创建项目并上传到 Gitblit 1. 在 GitBlit 后台创建版本库 2. 在 Eclipse 右击要上传的项目→Team→Share Project→Git,Create Reposition等操作。 3. 把项目先提交到本地, 右击项目→Team→Commit。 4. 提交到 Github 服务器,右击项目→Team→Push 并输入对应配置。 也可以通过命名的方式,进入项目根目录,右击打开 Git 命名行(需要安装 Git 客户端链接: http://pan.baidu.com/s/1qWJXowk 密码:9n0e) 1 2 git remote add origin ssh : //suzhida @182.92.218.9:29418 /claim .git git push -u origin master 基本操作 1. commit 提交到本地以后,要提交到服务器前先 pull,看是否有冲突。 2.

HTML5,不只是看上去很美(第二弹:打造最美3D机房)

前言 最近项目开发任务告一段落,刚好有时间整理这大半年的一些成果。使用html5时间还不久,对js的认识还不够深入。没办法,以前一直搞java,对js的一些语言特性和概念一时还转换不过来。 上一篇第一弹介绍了项目中做的一个彩虹爆炸图,主要用了 html5的canvas的2d绘制技术。这一回我想介绍一下项目中的一个亮点技术:html5的3D,以及如何用它打造精美的3D机房监控系统。 ------------------------10月27日更新----------------------------- 没想到这篇的点击率这么高,感谢大家给予的厚爱。 受到大家的启发和鼓励,这个3D机房系列已经有了长足的进步。 补上后续两篇的传送门: 第二季:场景和功能的丰富,包括机柜、设备、走线、路径规划等功能 第三季:功能的进一步丰富,包括资产管理,动环监控等的可视化管理 另外,录了两个视频,懒得看长文的朋友可以直接戳: http://v.youku.com/v_show/id_... http://v.youku.com/v_show/id_... 插播一则广告(长期有效) MONO哥需要在武汉招JavaScript工程师若干 要求:对前端技术(JavasScript、HTML、CSS),对可视化技术(Canvas、WebGL)有浓厚的兴趣 基础不好的可培养,基础好的可共谋大事 感兴趣的给我发邮件:hr@servasoft.com 目标效果图 下图是领导给找的一张的效果参考图,客户希望机房至少能达到下面的3D效果。 懂的人都知道,这可是一张设计公司出的装修效果图啊,就算是用max建模,也需要大量的工作,何况咱可是程序员在做数据中心的可视化项目啊。。。强忍心中奔腾的万千头**马,静下心来思考,那就先从搭建一个webGL的场景开始吧。 WebGL基本场景搭建 在html5里面使用3D已经不是什么高深技术,它的基础是WebGL,一个OpenGL的浏览器子集,支持大部分主要3D功能接口。目前最新的浏览器都有比较好的支持,IE需要到11(是的,你没有看错)。 要检测你的浏览器是否支持webGL,可直接访问网页http://get.webgl.org/ 看是否能看到一个旋转的立方体。如果能看到,说明你的浏览器支持webgGL,否则,可以下一个最新的chrome试试吧。相对来说chrome对webGL的支持最好,效率也很优秀。 要在浏览器里面使用webGL,就要研究webGL相关的技术和用法。做3D应用并不是一件轻松的事。就算最简单的搭建一下webGL场景,也需要下面这些代码: var width = window.innerWidth; var height= window.innerHeight; var container = document.createElement( 'div' ); document.body.appendChild( container ); var webglcanvas = document.createElement('canvas'); container.appendChild(webglcanvas); var gl = webglcanvas.getContext("experimental-webgl"); function updateFrame () { gl.viewport ( 0, 0, width, height ); gl.clearColor(0.4, 0.4, 0.7, 1); gl.clear ( gl.COLOR_BUFFER_BIT ); setTimeout( function(){updateFrame()}, 20); } setTimeout( function(){ updateFrame(); }, 20); 和html一样,需要先创建一个canvas元素,并获得其webgl上下文:

多服务器之间Session共享

原理:多个服务器间想共享session,就相当于共享取多台主机上的一个变量,所以共享的思路就是让大家都能读取变量,实现的方法可以通过将session保存到专门的一个服务器上,所有服务器都去请求数据,也memcache实现session共享 将这些服务器都配置成使用同一组Memcached服务器就可以, 一、提出问题: 为了满足足够大的应用,满足更多的客户,于是我们架设了N台Web服务器(N>=2),在多台Web服务器的情况下,我们会涉及到一个问题:用户登陆一台服务器以后,如果在跨越到另一台服务器的时候能够继续使用客户的Session? 二、解决方案: 1. 写客户端Cookie的方式 当用户登陆成功以后,把网站域名、用户名、密码、token、 session有效时间全部采用cookie的形式写入到客户端的cookie里面,如果用户从一台Web服务器跨越到另一台服务器的时候,我们的程序主动去检测客户端的cookie信息,进行判断,然后提供对应的服务,当然,如果cookie过期,或者无效,自然就不让用户继续服务了。当然,这种方法的弊端就不言而喻了,比如客户端禁用了cookie或者cookie被黑客窃取了呢?这些都可以解决,目前淘宝session框架就是基于client cookie做开发,不见得他们就出了很大的问题?也许是最可行的方式,可以配合memcached来实现。 2. 服务器之间Session数据同步的方式 假设Web服务器A是所有用户登陆的服务器,那么当用户验证登陆一下,session数据就会写到A服务器里,那么就可以自己写脚本或者守护进程来自动把session数据同步到其他Web服务器,那么当用户跳转到其他服务器的时候,那么session数据是一致的,自然就能够直接进行服务无须再次登陆了。缺点是,可能会速度慢,不稳定,如果是单向同步的话,登陆服务器出现问题,那么其他服务器也无法服务,当然也可以考虑双向同步的问题。这个方案都可以解决,目前zookeeper可以实现。 3. 利用NFS共享Session数据的方式 其实这个方案和下面的Mysql方案类似,只是存储方式不一 样。大致就是有一台公共的NFS服务器(Network File Server)做共享服务器,所有的Web服务器登陆的时候把session数据写到这台服务器上,那么所有的session数据其实都是保存在这台 NFS服务器上的,不论用户访问哪台Web服务器,都要来这台服务器获取session数据,那么就能够实现共享session数据了。缺点是依赖性太强,如果NFS服务器down掉了,那么大家都无法工作了,当然,可以考虑多台NFS服务器同步的形式。这个方案都可以解决,目前zookeeper可以实现,当然memcached也可以实现session共享。 4. 利用Mysql数据库共享Session数据的方式 这个方式与NFS的方式类似,也是采用一台Mysql服务器做共享服务器,把所有的session的数据保存到Mysql服务器上,所有Web服务器都来这台Mysql服务器来获取Session 数据。缺点也是依赖性太强,Mysql无法工作了影响所有的Web服务器,当然,可以考虑多太Mysql数据库来共享session,使用同步Mysql 数据的方式。这种方式跟方式3类似,同样可以采用memcached来做,nosql也可以实现,这些都不是问题。 5. 使用硬件设备 这个算是比较成熟的解决方案了,使用类似BIG-IP的负载设备来实现资源共享,那么就能够又稳定又合理的的共享Session了。目前很多门户网站采用这种方式。缺点很明显了,就是要收费了,硬件设备肯定需要购买成本的,不过对于专业或者大型应用来讲,是比较合理并且值得的,这种方式可以放到最后面考虑。 使用Memcached实现Session共享 由于Cookie是保存的用户客户端的,安全性存在问题,为保证用户数据的安全性,我们必须使用Session机制来保存用户登录后的一些信息。 如果我们使用LVS对Apache实现负载均衡,就无法保证用户每次都能被分配到同一台Apache Server上,以取到自己的Session,虽然LVS可以加-p参数来保证客户端每次都被分配到同一台Apache Server上,但这种方式存在一些弊端,比如必须设置一个保持时间,如果时间太长了,LVS就需要缓存大量信息,时间太短了,又不能保证用户每次被分配到同一台Server上,而且这种方式也不易实现Session的冗余备份。 因此,我们需要Session共享,也就是说每台Apache都可以访问到所有的Session,这样用户被分配到哪台Server就不重要了。 Session共享主要有多种实现方式:  Session复制。Apache可以实现把Session同步到其他Server上去,但这种技术太复杂,而且影响性能,占用内存,所以不推荐使用。  Session集中存储。存储介质可以是NFS文件系统、数据库、Memcached,从性能上考虑,当然是Memcached最好,推荐使用。 1.3 实现 1.3.1 安装Memcached Memcached是基于libevent实现的,所以要首先确保已经安装libevent。 安装libevent tar zxvf libevent-1.4.13-stable.tar.gz cd libevent-1.4.13-stable ./configure --prefix=/usr make && make install 安装Memcached tar zxvf memcached-1.4.4.tar.gz cd memcached-1.4.4 ./configure --prefix=/usr/local/memcached --with-libevent=/usr make && make install 启动Memcached /usr/local/memcached/bin/memcached -d -m 10 -u root -l 192.

iOS常量、变量、属性及其特性

1.Objective-C中声明常量使用关键字const。如:const double PI = 3.1514; 2.Objective-C中变量可以分为成员变量、局部变量和全局变量(用的很少,尽量不要用)。 //————————------------常量—————————————————// 方法一: #define kDetailKey @“detail text” #define DOWNLOAD_TIMEOUT 60.0 #define degresssToRadian(x) (M_PT*(X)/180.0) 这种方法直接使用#define定义函数、字符串和数字,和普通的C/C++一样,唯一的区别是字符串需要在前面加上“@”符号。 方法二: typedef enum{ kTagLanguageView = 100, kTagSeriesView, kTagSeriesDetailView, kTagThumbView, kTagVideoView, kTagFullPhotoView, }TagSystemViews; 使用枚举定义常量,在这里kTagSeriesView等于101,在程序中直接使用kTagSeriesView来表示这个常量,这和C/C++一样。 方法三: 在.m或者.mm文件中使用静态常量声明,和C/C++使用方法一样,例如: static NSString *BlockColorAlphaComponentKey =@"blockColorAlphaComponent”; //————————------------变量—————————————————// 1.为了强制一个对象隐藏其数据,编译器限制实例变量范围以限制其在程序中的可见性。 但是为了提供灵活性,苹果也让开发者显示设置范围(四选一)。 2.四种编译指令如下: @private 实例变量只能被声明它的类访问。 @protected 实例变量能被声明它的类和子类,所有没有显示指定范围的实例变量都是@protected。 @public 实例变量可以在任何地方被访问。 @packge 使用modern运行时,一个@package实例变量在实现这个类的可执行文件镜像中实际上是@public的,但是在外面就是@private。 OC中的@package与C语言中的变量和函数的private_extern类似。任何在实现类的镜像之外想使用这个实例变量都会引发link error。 这个类型最常用于框架类的实例变量,使用@private太限制,使用@protected或者@public又太开放。 //——————————————属性—————————————————// 属性:@property:@property只不过是给编译器看的一种指令,它可以编译之后自动为你生成相应的getter和setter方法。 1.公共属性表示你打算如何使用这一类的对象。 2.属性声明是一个指令,它告诉编译器如何为变量生成存取方法。(添加属性声明后,你将了解到有关存取方法的信息) 3.id类型是一个通用类型,OC使用id表示任意类型的对象,它可以作为一个占位符表示这是一个不确定的类型的对象或者引用。因此,所有的对象都可以用id来表示。 4.编译器指令@property可以为一个类声明属性,这是一个偷懒的好方法,用@property声明属性相当于同时声明并实现了对应的实例变量的访问器方法。当然,也可以通过指定属性的特性(Attribute)类控制自动生成的访问器方法的行为。 5.OC里的实例变量默认都是私有的。私有变量只在类自身和子类的实例方法里可见。 6.iOS OC声明变量在@interface括号中和使用@proper的区别: 方式一:直接在@interface中的大括号中声明。 @interface MyTest:NSObject { NSString *mystr; }

移动设备支持方式-移动设备管理MDM

一、 MDM的作用和功能 1、 最关键作用:保障文件和数据安全;将来可能是试用企业分配移动设备+自带设备进行办公 2、 包含如下,还不断拓展中 1) MDM (Mobile Device Management ) 2) MAM (Mobile Application Management) 3) MEM(Mobile Email Management) 4) MCM (Mobile Content Management) 3、 实现用户及设备管理,配置管理,安全管理,资产管理等功能 二、 厂商产品的选择依据 1、 可支持任何形式的无线网络:GPRS/EDGE/3G 、WIFI、红外、蓝牙 2、 可在线(OTA)分发 1) 将软件和操作系统(OS)升级包无线发送至一个或多个远程设备上,而不需要将设备连接至电脑上进行同步更新。 2) 远程注册,配置和管理设备,或甚至使设备退役; 3) 也可以远程锁定设备,以及选择性地清除或者完全清除设备上的数据,改变设备设置,或进行远程修复 3、 支持多种移动OS 1) iOS 2) android 3) 黑莓 4) WindowsPhone 4、 设有安全机制 1) 为设备设置各类安全功能,例如:密码保护、数据加密、GPS定位 2) 远程清除企业数据 5、 可管理企业移动应用 1) 使IT管理员能够建立企业内部应用商店,通过该商店分配和下载受认可的应用。 2) 企业内部应用商店可确保用户获得正确的应用版本,以及确保之后的升级顺利进行。 3) 企业应用商店可以在企业内部系统上运行,或者挂靠在某服务提供商的系统上,这两种方法皆可简化应用到设备的分配过程。 6、 可控制网络访问 1) 限制未经认证设备的访问,至少限制此类设备对互联网的访问

数据中心机房与IDC机房相比优势所在

N 比较项目 数据中心机房 IDC机房 1 故障相应速度 快,及时响应,最短时间全力排除 较快,且需要视乎机房所在地,视乎IDC的故障申告流程 2 服务流程 统一标准 视乎每家IDC机房不同 3 操作规范、标准 统一标准 视乎每家IDC机房不同 4 机房环境安全性 高(严格按照标准建设) 较高 5 应用限制 按照集团用户需求而定 高,需要符合IDC要求 6 设备管理合理化 应用及测试的设备合理的分区摆放 根据IDC自身管理划分 7 数据库等的维护 操作系统、中间件、数据库的也是由数据中心专人负责 IDC只负责网络、服务器环境等 8 数据安全性 数据存放在集团直接管理和拥有下,安全和符合audit规定,极少遭受盗取或破坏,最大程度保证数据安全 数据存放在IDC,用户存取需要符合IDC规定 9 维护、巡检、排查问题的便捷性 根据需要随时可以对硬件、环境、网络、应用系统等综合分析 需要申请和按IDC相关规定 10 人员安全性 集团专人负责,遵循相关标准和规范操作,保证环境和数据安全 IDC人员负责,集团相关标准难以约束 11 用户需求 根据用户需求而定,服务器、网络架构、UAT等,限制少,可自由安排 必须按照IDC要求和规定 12 运行性价比>10年 高 较低 13 使用效果和资源分配最佳化 更好考虑用户使用效果,致力实现资源配置最佳化 IDC只是出售资源 14 管理 数据、系统、环境易于统一管理 分散不同的IDC,不同的管理方式,人员操作等

BugFree环境搭建及使用

一、认识Bugfree BugFree基于PHP和MySQL开发,是免费且开发源代码的缺陷管理系统。服务器端在Linux和Windows平台上都可以运行;客户端无需安装任何软件,通过IE、FireFox等浏览器就可以自由使用。 二、搭建BugFree系统 1)认识和安装XAMPP XAMPP(Apache+MySQL+PHP+PERL)是一个功能强大的建XAMPP软件站集成软件包。这个软件包原来的名字是LAMPP,但是为了避免误解,最新的几个版本就改名为XAMPP了。它可以在Windows、Linux、MacOSX 等多种操作系统下安装使用,支持多语言:英文、简体中文、繁体中文、韩文、俄文、日文等。许多人通过他们自己的经验认识到安装 Apache服务器是件不容易的事儿。如果您想添加MySQL、PHP和Perl,那就更难了。XAMPP 是一个易于安装且包含MySQL、PHP 和 Perl 的 Apache 发行版。XAMPP的确非常容易安装和使用,只需下载,解压缩,启动即可。 2)安装配置Bugfree 1.准备BugFree2安装包,解压后复制到XAMPP系统的htdocs子目录下。 2.进入bugfree的Include安装目录,复制文件Config.inc.Sample.php为新文件Config.inc.php,编辑新创建的文件,修改配置文件如下: /* 3. Define the username andpassword of the BugFree database. */ $_CFG['DB']['User'] = 'root'; // 数据库登录用户名 $_CFG['DB']['Password'] = ''; // 数据库登录用户密码 $_CFG['DB']['Host'] = 'localhost'; // 数据库服务器地址 $_CFG['DB']['Database'] = 'bugfree2'; // 指定BugFree数据库名称 $_CFG['DB']['TablePrefix']= 'bf_'; // 数据库表前缀,默认为bf_。$_CFG['DBCharset'] = 'UTF8'; // 数据库编码设置,保留默认值 3. 在浏览器访问http://<servername>/bugfree。如果设置的数据库不存在,按照提示创建数据库,再点击继续安装,点击“安装全新的BugFree2”,安装成功后,使用系统提供的默认用户名和密码登录系统。 三、Bugfree的使用 1)后台使用 1.新建用户:新建两个用户,分别为开发人员和测试人员,按照XXX_KF和XXX_CS方式命名用户; 2.新建用户组:新建一个用户组,按照开发和测试方式命名用户,将上步骤中新建的两个用户添加到该用户组中; 3.新建项目:每个人新建自己的项目,将上步骤中新建的用户组,添加到项目中。 4.添加项目模块:Bug模块和Case模块。 2)前台使用 1.新建Case 2.执行Case 3.创建Bug 3)统计 测试完成后,统计缺陷,在查询结果框右上角,点击“统计报表”链接打开新窗口。统计报表可以显示Bug,Test Case或TestResult当前查询结果的统计信息。在统计报表页面的左侧选择统计项,点击”查看统计”按钮,右侧显示统计图表。

为什么选择scala而不用java开发spark

你可能会认为我根本无法对前面一小节那个畸形的函数给出个合理的解释。我开始学习函数式编程时就是这么认为的。不过我是错了。有很好的理由使用这种风格,当然其中一些属主观因素。例如,函数式程序被认为更容易阅读。因为连街上乱跑的娃娃都知道,是否容易理解是个见仁见智的判断,所以我将略去这些主观方面的理由。幸运的是,还有很多的客观理由。 单元测试 因为函数式编程的每一个符号都是 final 的,没有函数产生过副作用。因为从未在某个地方修改过值,也没有函数修改过在其作用域之外的量并被其他函数使用(如类成员或全局变量)。这意味着函数求值的结果只是其返回值,而惟一影响其返回值的就是函数的参数。 这是单元测试者的梦中仙境(wet dream)。对被测试程序中的每个函数,你只需在意其参数,而不必考虑函数调用顺序,不用谨慎地设置外部状态。所有要做的就是传递代表了边际情况的参数。如果程序中的每个函数都通过了单元测试,你就对这个软件的质量有了相当的自信。而命令式编程就不能这样乐观了,在 Java 或 C++ 中只检查函数的返回值还不够——我们还必须验证这个函数可能修改了的外部状态。 调试 如果一个函数式程序不如你期望地运行,调试也是轻而易举。因为函数式程序的 bug 不依赖于执行前与其无关的代码路径,你遇到的问题就总是可以再现。在命令式程序中,bug 时隐时现,因为在那里函数的功能依赖与其他函数的副作用,你可能会在和 bug 产生无关的方向探寻很久,毫无收获。函数式程序就不是这样——如果一个函数的结果是错误的,那么无论之前你还执行过什么,这个函数总是返回相同的错误结果。 一旦你将那个问题再现出来,寻其根源将毫不费力,甚至会让你开心。中断那个程序的执行然后检查调用栈,和命令式编程一样,栈里每一次函数调用的参数都呈现在你眼前。但是在命令式程序中只有这些参数还不够,函数还依赖于成员变量,全局变量和其他类的状态(它们也依赖着同样多的其他东西)。函数式程序里函数只依赖于它的参数,而那些信息就在你注视的目光下!还有,在命令式程序里,只检查一个函数的返回值不能够让你确信这个函数已经正常工作了,你还要去查看那个函数作用域外数十个对象的状态来确认。对函数式程序,你要做的所有事就是查看其返回值! 沿着堆栈检查函数的参数和返回值,只要发现一个不尽合理的结果就进入那个函数然后一步步跟踪下去,重复这一个过程,直到它让你发现了 bug 的生成点。 并行 函数式程序无需任何修改即可并行执行。不用担心死锁和临界区,因为你从未用锁!函数式程序里没有任何数据被同一线程修改两次,更不用说两个不同的线程了。这意味着可以不假思索地简单增加线程而不会引发折磨着并行应用程序的传统问题。 事实既然如此,为什么并不是所有人都在需要高度并行作业的应用中采用函数式程序?嗯,他们正在这样做。 爱立信公司设计了一种叫作 Erlang 的函数式语言并将它使用在需要极高抗错性和可扩展性的电信交换机上。还有很多人也发现了 Erlang 的优势并开始使用它。我们谈论的是电信通信控制系统,这与设计华尔街的典型系统相比对可靠性和可升级性要求高得多。实际上,Erlang 系统并不是“可伸缩”和“可靠”——Java 系统才是——Erlang 系统是“坚如磐石”。 关于并行的故事还没有就此停止,即使你的程序本身就是单线程的,那么函数式程序的编译器仍然可以优化它使其运行于多个 CPU 上。请看下面这段代码: 1String s1 = somewhatLongOperation1(); 2String s2 = somewhatLongOperation2(); 3String s3 = concatenate(s1, s2); 在函数式是编程语言中,编译器会分析代码,辨认出潜在耗时的创建字符串 s1 和 s2 的函数,然后并行地运行它们。 这在命令式语言中是不可能的,因为在那里,每个函数都有可能修改了函数作用域以外的状态并且其后续的函数又会依赖这些修改。 在函数式语言里,自动分析函数并找出适合并行执行的候选函数简单的像自动进行的函数内联化!在这个意义上,函数式风格的程序是“不会过时的技术(future proof)”(虽然不喜欢用行业广告语,但这里要破例一次)。硬件厂商已经无法让 CPU 运行得更快了,于是他们增加了处理器核心的速度并因并行而获得了四倍的速度提升。当然他们也顺便忘了提及:我们多花的钱只对支持并行运行的软件有用,只有一小部分的命令式程序可以(不加修改地)并行运行在这些新的硬件上,而 100% 的(纯)函数式程序都可以,因为函数式程序天生支持并行处理。 代码热部署 过去要在 Windows 上安装更新,重启计算机是难免的,而且还不只一次,即使只是安装了一个新版的媒体播放器。Windows XP 大大改进了这一状态,但仍不理想(我今天工作时运行了 Windows Update,现在一个烦人的图标总是显示在托盘里除非我重启一次机器)。

HTML5,不只是看上去很美 (第一弹:彩虹爆炸图)

25年过去了,Brooks博士著名的“没有银弹”的论断依旧没有被打破。HTML5也是一样。但这并不妨碍HTML5是一个越来越有威力的“炸弹”:发展迅速、势不可挡。随着HTML5技术的普及,用HTML5做可视化呈现的项目越来越多了。HTML5的优势明显:网页上直接运行无需插件、手机平板方便兼容、代码开发和维护相对容易,等等。一大波一大波的做Java、.NET甚至C++桌面的程序老手们都纷纷开始研究javascript了,而初出茅庐的新一代程序猿更是义无反顾的直奔HTML5这个技术大热点而来。 HTML5涵盖的技术点很多,甚至延伸到了前端、后端、通讯等各个层面。前端的canvas绘图这块无疑是它的核心内容。Canvas的API虽然不是很复杂很强大,但是做一般的2d绘图基本都够用了。基于这些API,一大堆的2d绘图组件纷纷出炉。Echarts、d3.js都是很不错的项目。Echarts主要是chart组件,而d3相对杂一些,很多呈现方式很有创意,值得研究。研究d3的起因是最近有一个项目,用户截了一张效果图让我们用HTML5做一下: 看着很眼熟,搜了一下,感觉就是d3例子中的sunburst效果,程序在这里: http://bl.ocks.org/mbostock/4063423 看上去似乎也不难,就是一圈一圈的饼图,把树状结构数据按占比一层一层绘制上去就行了。所以引起了自己动手做一个的兴趣。“sunburst”英文里应该是“云开日出”的意思,类似强烈的光芒从云层背后透射出来,不知为何中文里大多把它翻译成“日落”。比如这把Fender Telecaster吉他型号是Brown Sunburst款,就会被大家翻译成“日落色”。 关于日出和日落更喜欢哪一个的问题,网上还真有这样的调查。有意思的是,选择喜欢日落的远多于选择日出的。日出代表希望,日落代表成熟,都是一种美,哪个更美要看你个人的心境,因为它的美丽是由心生。为了不在这个问题上站错对,我们还是给他重新起一个更加响亮霸气的中文名字:“彩虹爆炸图”,怎么样? 仔细研究一下彩虹爆炸图的结构,无非就是一个树形结构,并采用发射状的布局。根节点在中间(也可以认为没有唯一的根,而是一堆根节点围绕在第一圈),一次向外发散排列。每一个节点有名称、数值。节点可以按照自身数值在扇区所占比例进行绘制,这样就不用管节点具体数值有多大多小了。这种图最先是由布朗大学教授John T. Stasko设计。 http://www.cc.gatech.edu/~john.stasko/ 经过一天的折腾,终于做出了一个还算过得去的“彩虹爆炸图”。先上个图看看: 主要功能包括了: · 可以通过json来定义数据和样式(类似百度的echarts那样); · 颜色可以固定,也可以自动彩虹色; · 自动计算数值及角度占比; · 动态显示导航路径; · 鼠标动态高亮显示路径; · 动画飞入、展开导航路径; · 文字显示及角度控制; · 全矢量,可鼠标缩放、平移,不失真; 下面咱们来看下折腾过程中的几个重点: 一、定义节点对象 首先定义每一个小扇片节点。每个扇片可以用一段饼图来绘制。为了简单方便,这里用了最简单高效偷懒的方法:用一个半径很粗的线画一段角度的arc,即可。如下图: 另外还有文字等内容。所以定义它的json结构大概如下: var item = {name: '名称', color: 'red', angle: '45', …}; 此外,下一圈的数据,可直接定义为这个节点的“孩子节点”,直接在item中定义一个data的子节点数据: var item = {name: '名称', color: 'red', angle: '45', data:[ {name:’孩子一’,color:’green’,…}, {name:’孩子二’, color:’yellow’,…}, ]}; 这样就可以组成一个树状结构。接下来要在canvas上绘制图形了。为了方便,这里直接使用了矢量图进行定义: twaver.Util.registerImage('node', { v:[{ shape: 'circle', r: ... lineColor: function(data,view){return data.

虚拟机处理器核数与物理cpu的关系

vCPU,顾名思义,是虚拟CPU。 创建虚拟机时,需要配置vCPU资源。 因此vCPU是虚拟机的部件。 因此脱离VM,谈论vCPU是没有意义的。 虚拟化管理系统如何调度vCPU,取决于系统内的虚拟机数目以及虚拟机配置的vCPU的情况。 大致的情况如下: 1、当系统内VM所需的vCPU总数少于物理CPU的核数(包括超线程Core)时,虚拟化管理系统为vCPU分配的资源不超过一个物理CPU核。 vCPU与物理核的分配关系可以是绑定的,也可能是动态的。 比如服务器有20个核心,你创建了2个VM,每个VM 4个vCPU,那么这两个VM最多能够使用服务器的8个核心。 2、当系统内的VM所需要的vCPU核大于物理CPU核数时,虚拟化管理系统首先按照时间片轮流调度一遍,然后如果还有剩余的CPU资源,则给所需要的vCPU。 比如系统配置了40个vCPU,只有20个物理核。那么平均每个vCPU获取一个核心50%的资源。由于一些VM忙,一些VM空闲,虚拟化系统会在一个调度周期内,划分出若干时间片,轮流给每个vCPU使用。忙的vCPU可以使用完整个时间片,而闲的vCPU用不完整个时间片,会提前释放资源。这样在一个调度周期内,对每个vCPU都调度一遍后还有空闲的时间,调度器会把用这剩余的资源去调度忙的vCPU。 这样兼顾公平和效率。 这中调度算法具体下来,大致是如下效果:系统有1个CPU 2.0 Ghz,两个VM,分配1个vCPU。 如果VM1 和 VM2都忙,那么各自相当于拥有一个1.0 Ghz的CPU。 如果VM1很忙,VM1只需要 500Mhz的处理能力,那么在VM1看来,相当于暂时获得了 1.5Ghz的处理器。 3、通过对Xen的测试,系统所有虚拟机的vCPU的总数目小于和等于CPU核数时,VM的性能是比较稳定的。 VM的vCPU基本上绑定到了一个CPU核。 当vCPU数目大于物理核数时,VM的性能稳定性变差。

TC(Linux下流量控制工具)详细说明及应用

TC的安装 TC是Linux自带的模块,一般情况下不需要另行安装,可以用 man tc 查看tc 相关命令细节,tc 要求内核 2.4.18 以上 ##注意:64位机器上,先执行下面命令 ln -s /usr/lib64/tc /usr/lib/tc TC原理介绍 Linux 操作系统中的流量控制器 TC(Traffic Control) 用于Linux内核的流量控制,它利用队列规定建立处理数据包的队列,并定义队列中的数据包被发送的方式,从而实现对流量的控制。TC 模块实现流量控制功能使用的队列规定分为两类,一类是无类队列规定,另一类是分类队列规定。无类队列规定相对简单,而分类队列规定则引出了分类和过滤器等概念,使其流量控制功能增强。 无类队列规定是对进入网络设备(网卡)的数据流不加区分统一对待的队列规定。使用无类队列规定形成的队列能够接收数据包以及重新编排、延迟或丢弃数据包。这类队列规定形成的队列可以对整个网络设备(网卡)的流量进行整形,但不能细分各种情况。常用的无类队列规定主要有 pfifo_fast(先进先出)、TBF(令牌桶过滤器)、SFQ(随机公平队列)、ID(前向随机丢包)等等。这类队列规定使用的流量整形手段主要是排序、限速和丢包。 分类队列规定是对进入网络设备的数据包根据不同的需求以分类的方式区分对待的队列规定。数据包进入一个分类的队列后,它就需要被送到某一个类中,也就是说需要对数据包做分类处理。对数据包进行分类的工具是过滤器,过滤器会返回一个决定,队列规定就根据这个决定把数据包送入相应的类进行排队。每个子类都可以再次使用它们的过滤器进行进一步的分类。直到不需要进一步分类时,数据包才进入该类包含的队列排队。除了能够包含其他队列规定之外,绝大多数分类的队列规定还能够对流量进行整形。这对于需要同时进行调度(如使用SFQ)和流量控制的场合非常有用。 Linux流量控制的基本原理如下图所示。 接收包从输入接口(Input Interface)进来后,经过流量限制(Ingress Policing)丢弃不符合规定的数据包,由输入多路分配器(Input De-Multiplexing)进行判断选择。如果接收包的目的地是本主机,那么将该包送给上层处理,否则需要进行转发,将接收包交到转发块(Forwarding Block)处理。转发块同时也接收本主机上层(TCP、UDP等)产生的包。转发块通过查看路由表,决定所处理包的下一跳。然后,对包进行排列以便将它们传送到输出接口(Output Interface)。 一般我们只能限制网卡发送的数据包,不能限制网卡接收的数据包,所以我们可以通过改变发送次序来控制传输速率。Linux流量控制主要是在 输出接口排列时进行处理和实现的。 TC规则 1.流量控制方式 流量控制包括一下几种方式: SHAPING(限制) 当流量被限制时,它的传输速率就被控制在某个值以下。限制值可以大大小于有效带宽,这样可以平滑突发数据流量,使网络更为稳定。SHAPING(限制)只适用于 向外的流量。 SCHEDULING(调度) 通过调度数据包的传输,可以在带宽范围内,按照优先级分配带宽。SCHEDULING(调度)也只适用于向外的流量。 POLICING(策略) SHAPING(限制)用于处理向外的流量,而POLICING(策略)用于处理接收到的数据。 DROPPING(丢弃) 如果流量超过某个设定的带宽,就丢弃数据包,不管是向内还是向外。 2.流量控制处理对象 流量的处理由三种对象控制,它们是 :qdisc(排队规则)、class(类别)和filter(过滤器)。 qdisc(排队规则)是 queueing discipline的简写,它是理解流量控制(traffic control)的基础。 无论何时,内核如果需要通过某个网络接口发送数据包,它都需要按照为这个接口配置的qdisc(排队规则)把数据包加入队列。然后,内核会尽可能多的从qdisc里面取出数据包,把它们交给网络适配器驱动模块。最简单的qdisc是pfifo他不对进入的数据包做任何的处理,数据包采用先进先出的方式通过队列。不过,它会保存网络接口一时无法处 理的数据包。 qddis(排队规则)分为 CLASSLESS QDISC和 CLASSFUL QDISC 类别如下: CLASSLESS QDISC (无类别QDISC) 1.无类别QDISC包括: [ p | b ]fifo,使用最简单的qdisc(排队规则),纯粹的先进先出。只有一个参数:limit ,用来设置队列的长度,pfifo是以数据包的个数为单位;bfifo是以字节 数为单位。 pfifo_fast,在编译内核时,如果打开了高级路由器(Advanced Router)编译选项,pfifo_fast 就是系统的标准qdisc(排队规则)。它的队列包括三个波段 (band)。在每个波段里面,使用先进先出规则。而三个波段(band)的优先级也不相同,band 0 的优先级最高,band 2的最低。如果band 0里面有数据包, 系统就不会处理band 1 里面的数据包,band 1 和 band 2 之间也是一样的。数据包是按照服务类型(Type Of Service,TOS )被分配到三个波段(band)里面 的。 red,red是Random Early Detection(随机早期探测)的简写。如果使用这种qdsic,当带宽的占用接近与规定的带宽时,系统会随机的丢弃一些数据包。他非常适合高带宽的应用。 sfq,sfq是Stochastic Fairness Queueing 的简写。它会按照会话(session --对应与每个TCP 连接或者UDP流)为流量进行排序,然后循环发送每个会话的 数据包。 tbf,tbf是 Token Bucket Filter 的简写,适用于把流速降低到某个值。 2.

Dart on Android语言体验

Dart on Android项目又称为sky语言,google将在未来用它替换掉原有的安卓开发语言(Java) 目前大部分中文媒体只是转载了外媒前半部分,下面个人来补充一下 下面摘录的英文来自:http://arstechnica.com/gadgets/2015/05/googles-dart-language-on-android-aims-for-java-free-120-fps-apps/ The Dart team brought along a demo app, and it was rendering entire frames in 1.2ms. While it was a simple example, it appears Sky has plenty of headroom for silky-smooth animation on more complicated apps and makes that 120FPS goal (8ms rendering time) seem like a possibility. The Dart team says Sky is "Jank-free by design" with APIs that don't block the main UI thread, meaning that even if the app slows down, the UI will still be fast and responsive.

spss交叉表分析 + SPSS卡方检验

spss中交叉分析主要用来检验两个变量之间是否存在关系,或者说是否独立,其零假设为两个变量之间没有关系。在实际工作中,经常用交叉表来分析比例是否相等。例如分析不同的性别对不同的报纸的选择有什么不同。 spss交叉表分析方法与步骤: 1、在spss中打开数据,然后依次打开:analyze--descriptive--crosstabs,打开交叉表对话框 2、将性别放到行列表,将对读物的选择变量放到列,这样就构成了一个交叉表 3、设置输出的结果,点击statistics,打开一个新的对话框 4、勾选chi-square(卡方检验),勾选phi and cramer's V(衡量交互分析中两个变量关系强度的指标),点击continue,回到交叉表对话框 5、点击cells,设置cell中要展示的数据 6、在这里勾选observed(各单元格的观测次数),勾选row(行单元格的百分比),点击continue,回到交叉表对话框 7、点击ok按钮,输出检验结果 8、先看到的第一个表格就是交叉表,性别为行、选择的读物为列 9、卡方检验结果:主要看pearson卡方检验,sig值小于0.05,因此认为不同的性别的人对周末读物的选择有显著的差别 10、最后一个表格,输出的是phi值和V值,两个都代表两个变量之间的关系的紧密度,数值小于0.1说明关系不紧密,即性别与周末读物的选择没有明显的关系,这个结论和上面的卡方检验有出入,所以需要进一步进行两两比较。 来源:百度文库http://wenku.baidu.com/view/c659b1e3172ded630b1cb6a3.html 数据分析联盟:http://www.52analysis.com/SPSS_SAS/292.html ▼2、将性别放到行列表,将对读物的选择变量放到列,这样就构成了一个交叉表 ▼4、勾选chi-square(卡方检验),勾选phi and cramer's V(衡量交互分析中两个变量关系强度的指标),点击continue,回到交叉表对话框 ▼6、在这里勾选observed(各单元格的观测次数),勾选row(行单元格的百分比),点击continue,回到交叉表对话框 ▼8、先看到的第一个表格就是交叉表,性别为行、选择的读物为列 ▼9、卡方检验结果:主要看pearson卡方检验,sig值小于0.05,因此认为不同的性别的人对周末读物的选择有显著的差别 ▼10、最后一个表格,输出的是phi值和V值,两个都代表两个变量之间的关系的紧密度,数值小于0.1说明关系不紧密,即性别与周末读物的选择没有明显的关系,这个结论和上面的卡方检验有出入,所以需要进一步进行两两比较。 中文: 是否死亡放置于行好一些;“精确”为默认,“统计量”选卡方和Phi;“单元显示”将计数和百分比全选,“格式”为默认。 结果: Value=卡方值;df=自由度;ASYMP.sig=P值=相伴性概率。p大于0.05(自己设定的显著性水平),接受原假设,否则拒绝,即P值小于0.05认为结果有显著性差异。注意表格下面的注解:b. 0 cells (.0%) have expected count less than 5. The minimum expected count is 191.89,这句话很重要,关系到结果是否可靠!理论频数小于5的cells(格子)比例不超过20%,结果可靠,采用Pearson Chi-Square的P值-ASYMP.sig。当理论频数小于5的cells(格子)比例超过20%,应看Exact Test(确切概率法)。 给出的Asymp. Sig 是通过卡方值算的。 最常用的医学统计: TTest - 独立样板T检验,推断两个总体的总体的独立样本均值是否存在显著差异 交叉表 - 不同的性别对不同疾病的选择有什么不同用此分析法,即卡方检验,卡方检验 Logist 回归 - 确定两种或两种以上变数间是否相关、相关方向与强度,即相互依赖的定量关系

Dubbo和Spring集成Demo

Zookeeper安装和启动 http://mirrors.hust.edu.cn/apache/zookeeper/下载,我的版本是 3.4.5。 解压到 D:\zookeeper-3.4.5 配置 到目录conf 下创建 zoo.cfg 文件,默认就是加载这个文件,文件内容 我直接copy 的sample里面的 zoo.cfg 的内容 # 心跳检查的时间 2秒 tickTime=2000 # 初始化时 连接到服务器端的间隔次数,总时间10*2=20秒 initLimit=10 # ZK Leader 和follower 之间通讯的次数,总时间5*2=10秒 syncLimit=5 # 存储内存中数据库快照的位置,如果不设置参数,更新事务日志将被存储到默认位置。 dataDir=D:\zk\tmp\zookeeper # 错误日志的存放位置 dataLogDir=D:\zk\logs\zookeeper # ZK 服务器端的监听端口 clientPort=2181 运行 然后 cd 到bin 目录下 执行zkServer.cmd 就启动成功了。利用jps命令行命令可以验证zookeeper是否启动成功。 Dubbo服务注册 建立WEB项目,引入相应Jar文件。 配置web.xml文件 <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>dubbo-service</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> <context-param> <param-name>contextConfigLocation</param-name> <param-value> WEB-INF/dubbo-provider.

kvm虚拟机vcpu资源绑定

kvm虚拟出来的虚拟机(vm)是运行在单独的一个逻辑cpu还是可以分别在各个cpu之间运行?虚拟机cpu(vcpu)是什么概念?物理机(host)怎么看待kvm和vcpu? 为了搞懂这个概念我们还是要回到命令行中看。举例说明: 我这里有一个虚拟机叫core8,它含有8个虚拟cpu它的进程编号是20736。就是说core8在host看来就是一个进程而已,这个集成的编号是20736.那么现在提出一个问题,这个core8的8个vcpu是怎么个情况呢?在哪里运行呢?这时还是得借助命令行。我们在host里使用ps指令,但是不能单纯用ps,还要借助于参数: ps -eL (e的意思是打印所有进程,L的意思是连县城也不放过)。我这里只显示一下和我们的20736进程相关的信息: 你会看到和20736相关的有九行,那么这九行是什么呢?首先第一列都是20736,第二列里只有第一行是20736,后面的都不是。那么我们这时就应该明白了,对于host来说,kvm虚拟机是一个进程(20736),虚拟机的vcpu都是这个进程衍生出来的线程。这就是为什么除了20736还有另外八行的原因。 那么我们接着询问,这八个线程是跑在同一个逻辑cpu里吗?为了回答这个问题,我们接着做实验: 还是借助于ps指令 :ps -eLo ruser,pid,ppid,lwp,psr| awk ‘{if($5==1) print $0}’。解释为:ps命令显示当前系统的进程信息的状态,它的“-e”参数用于显示所有的进程,“-L”参 数用于将线程(LWP,light-weight process)也显示出来,“-o”参数表示以用户自定义的格式输出(其中“psr”这列表示当前分配给进程运行的处理器编号,“lwp”列表示线程的 ID,“ruser”表示运行进程的用户,“pid”表示进程的ID,“ppid”表示父进程的ID,)。结合ps和 awk工具的使用,是为了分别打印出来运行在不同的逻辑cpu上的进程线程情况。上面的指令就是打印出1号(从0开始编号)cpu的进行线程情况,我们这里只列出和我们相关的: 这时看到,20736号进程衍生出来的线程只有一部分运行在逻辑cpu1上,其它的线程在其它的cpu上了。 这时就大概明白了,不同的vcpu只是不同的线程,而不同的线程是跑在不同的cpu上的。 Qemu/kvm为客户机提供一套完整的硬件系统环境,在客户机看来其所拥有的cpu即是vcpu(virtual CPU)。在KVM环境中,每个客户机都是一个标准的Linux进程(qemu进程),而每一个vCPU在宿主机中是Qemu进程派生的一个普通线程。 KVM中的一个客户机作为一个用户空间进程(qemu-kvm)运行的,它和其他普通的用户进程一样由内核来调度使其运行在物理cpu上,不过它由KVM模块控制。多个客户机就是宿主机中的多个QEMU进程,而一个客户机的多个vCPU就是一个QEMU进程中的多个线程。在客户机系统中,同样分别运行着客户机的内核和客户机的用户空间应用程序。 疑问: KVM环境下的smp的架构是如何处理时限的,也就是cores * 2,socket * 2 ,threads * 2与 cores * 1,socket * 8,thread * 1 有什么本质的区别? 因为为虚拟机提供计算的vcpu在宿主机上实际为一个线程,线程上并不会对cores、sockets或者threads做明确区分,也就是整体设置2*2*2 和 1*8*1是没区别的。 不过在虚拟机内部,可能会有系统倾向于(服务器的设别程度)多物理插槽,或者多物理核心。(之前遇到的win2k8(非Datacenter)的情况就是,无法识别超过8个的vcpu,但是设置成2*6*1 即可实现12个vcpu的服务器) 进程的处理器亲和性和VCPU绑定 什么是进程亲和性:简单的一句话就是我这个Linux进程到底可以在哪几个cpu上做负载均衡。 KVM虚拟机是一个普通的linux进程,vcpu是一个线程,我们可以在宿主机上将vcpu线程对应的tid绑定到指定的cpu上。 应用场景 用户希望把虚拟机的VCPU绑定在特定物理CPU上,VCPU只在绑定的物理CPU上调度,达到隔离VCPU并提升虚拟机性能的目的。如果没有作VCPU绑定,则虚拟机的VCPU可以在所有物理CPU上调度。 绑定vcpu到指定的cpu上,的确会提高性能,因为在vcpu的线程在物理cpu做负载均衡的时候,会有一些必要的数据结构初始化(vmlaunch)相对于VM-Entry来说是比较奢侈的,加上cache的命中,性能必然会有所提高,但破坏了负载均衡。当绑定在同一cpu上的两个vcpu同时高负载的时候,性能就会大打折扣,而其他的cpu也没有得到充分的利用。 在KVM环境中,一般并不推荐手动设置qemu进程的处理器亲和性来绑定vCPU,但是,在非常了解系统硬件架构的基础上,根据实际应用的需求,可以将其绑定到特定的CPU上,从而提高客户机中的CPU执行效率或实现CPU资源独享的隔离性。 为了实现这个功能,你首先得会 taskset命令,直观上来说,taskset就是设置任务,也就是制定任务运行的情况,是一个很好用的工具。 taskset -p [mask] pid taskset绑定进程到某个CPU是很方便的: #taskset -pc 0,1 1249 这会绑定1249进程到0号跟1号cpu上。 #cat /proc/1249/status Cpus_allowed: 3 Cpus_allowed_list: 0-1 重新绑定下: #taskset -pc 1 1249 #cat /proc/1249/status Cpus_allowed: 2 Cpus_allowed_list: 1 注意这里的Cpu_allowed用的是 二进制掩码,3的二进制是11,2的二进制是10。前一个表示可在两个CPU上运行,第二个表示仅在第二个CPU上运行。 那么我们这里就可以使用taskset了,只需把这九个线程都绑定在同一个cpu上即可。假设我们把这个虚拟机绑定到1号cpu上: