首页 文章 精选 留言 我的

精选列表

搜索[学习],共10000篇文章
优秀的个人博客,低调大师

C++ template 学习归纳总结4

我们在这篇文章来说说typename关键字吧。这个关键字是在c++的标准化过程中引入的,目的在于说明template中的某个表示符号是一个类型,而不是其他的东西,看下面的代码: template <typename T> class MyClass { typename T::SubType * ptr; … }; 第一个typename我就不多说了,大家都知道,我来说一下第二个。他的意思是说T::SubType是class T内部定义的一个类型,从而ptr是一个指向【T:SubType类型】的指针。 如果在上面的代码中,没有第二个typename关键字的话,编译器会以为SubType是class Type的一个static成员。于是会被编译器理解为一个具体的东西,从而导致T::SubType * ptr 所表达的意思是两个数进行相乘。 关于这个知识的应用比较多的是STL中,比如: #include <iostream> // print elements of an STL container template <typename T> void printcoll (T const& coll) { typename T::const_iterator pos; // iterator to iterate over coll typename T::const_iterator end(coll.end()); // end position for (pos=coll.begin(); pos!=end; ++pos) { std::cout << *pos << ' '; } std::cout << std::endl; } 下面我们来看看另外一个有意思的问题。那就是”.template”,大家仔细查看下面的代码: template<int N> void printBitset (std::bitset<N> const& bs) { std::cout << bs.template to_string<char,char_traits<char>, allocator<char> >(); } 大家注意到没有,。这个例子中的“.template”比较怪,但是如果没有他的话,那么编译器无法知道后面的“<”是模板参数的开始。而不是一个小于号。注意,只有当位于 点号之前的物件取决于某一个template parameter的时候,这种情况才会发生,以上的例子中,bs受控于N。也就是显式指明模板函数调用。可以理解为指名点姓的调用模板成员函数而非普通的。 结论是“.template”或者”->template”记号只能在templates中使用。而且他们必须紧跟在于template parameter相关的某个物件。 其实这里关于这个”.template”,笔者也没有搞懂,不知道哪位大牛搞懂了,麻烦指教一下,谢谢了。 下面我们来看看成员模板: 先看看下面的例子: Stack<int> intStack1, intStack2; // stacks for ints Stack<float> floatStack; // stack for floats … intStack1 = intStack2; // OK: stacks have same type floatStack = intStack1; // ERROR: stacks have different types 默认的赋值运算要求左右两边拥有相等的类型。但是如果把赋值运算定义为一个模板,就可以使得类型不同,但是元素可以隐式转换,比如: template <typename T> class Stack { private: std::deque<T> elems; // elements public: void push(T const&); // push element void pop(); // pop element T top() const; // return top element bool empty() const { // return whether the stack is empty return elems.empty(); } // assign stack of elements of type T2 template <typename T2> Stack<T>& operator= (Stack<T2> const&); }; 我们来实现它看看:关键代码如下: template <typename T> template <typename T2> Stack<T>& Stack<T>::operator= (Stack<T2> const& op2) { if ((void*)this == (void*)&op2) { // assignment to itself? return *this; } Stack<T2> tmp(op2); // create a copy of the assigned stack elems.clear(); // remove existing elements while (!tmp.empty()) { // copy all elements elems.push_front(tmp.top()); tmp.pop(); } return *this; } 下面我们测试一下啊: Stack<int> intStack; // stack for ints Stack<float> floatStack; // stack for floats … floatStack = intStack; // OK: stacks have different types, // but int converts to float 当然这个运算并不改变stack和其元素的类型,赋值完成转换,floatstack返回的任然是float。但是这个技术并不是说任何两个类型都能进行赋值,比如下面的代码就不行: Stack<std::string> stringStack; // stack of ints Stack<float> floatStack; // stack of floats … floatStack = stringStack; // ERROR: std::string doesn't convert to float 你知道为什么了吗? 当然,和以前一样,你也可以在将内部容器的类型也参数化: template <typename T, typename CONT = std::deque<T> > class Stack { private: CONT elems; // elements public: void push(T const&); // push element void pop(); // pop element T top() const; // return top element bool empty() const { // return whether the stack is empty return elems.empty(); } // assign stack of elements of type T2 template <typename T2, typename CONT2> Stack<T,CONT>& operator= (Stack<T2,CONT2> const&); }; 此时的赋值运算实现代码为: template <typename T, typename CONT> template <typename T2, typename CONT2> Stack<T,CONT>& Stack<T,CONT>::operator= (Stack<T2,CONT2> const& op2) { if ((void*)this == (void*)&op2) { // assignment to itself? return *this; } Stack<T2> tmp(op2); // create a copy of the assigned stack elems.clear(); // remove existing elements while (!tmp.empty()) { // copy all elements elems.push_front(tmp.top()); tmp.pop(); } return *this; } ============================================================================== 本文转自被遗忘的博客园博客,原文链接:http://www.cnblogs.com/rollenholt/archive/2012/03/08/2384871.html,如需转载请自行联系原作者

优秀的个人博客,低调大师

C++学习第三天

一些基础就可以略过了,看书不能太呆板。 如果把一本书看完了,剩下的就是在实际项目中进行整合,训练,然后整理成笔记。 每天敲点程序,记点笔记。 变量作用域 代码: #include <iostream> #include <string> #include <conio.h> std::string s1 = "hello"; //全局 int main(){ std::string s2 = "world"; //局部 std::cout<<s1<<" "<<s2<<std::endl; int s1 = 42; //局部+隐式全局 std::cout<<s1<<" "<<s2<<std::endl; getch(); return 0; } 结果:hello world42 world判断代码输出结果 代码: #include <iostream> #include <string> #include <conio.h> int i = 42; int main(){ int i = 100,sum = 0; for(int i = 0;i!=10;++i) sum += i; std::cout<<i<<" "<<sum<<std::endl; getch(); return 0; } 结果:100 45 用class和struct关键字定义类的唯一差别在于默认访问级别:默认情况下,struct的成员为public,而class的成员为private。一旦使用了using声明,我们就可以直接引用名字,而不需要再引用改名字的命名空间了。 代码: #include <iostream> #include <string> #include <conio.h> using std::cin; using std::string; using std::cout; int main(){ string s; cin>>s; cout<<s; getch(); return 0; } #include <iostream> #include <string> #include <conio.h> using std::cin; using std::string; using std::cout; using std::endl; int main(){ string st("The expense of spirit\n"); cout<<"The size of "<<st<<"is"<<st.size() <<" characters,including the newline"<<endl; getch(); return 0; } 结果:The size of The expense of spiritis22 characters,including the newline 本文转自TBHacker博客园博客,原文链接:http://www.cnblogs.com/jiqing9006/archive/2013/04/11/3014962.html,如需转载请自行联系原作者

优秀的个人博客,低调大师

学习大数据前提,制造linux环境

大数据,linux环境是必须的,基本的linux操作也是必须的,如果不会,可以学下,很快就上手。 获得linux环境方式: windows上部署虚拟机,然后虚拟机中搭载linux,运行速度慢,不方便。 双系统,windows10 + censOS ,大数据需要集群,这个也不方便。 安装方式可以看这里 http://xueliang.org/article/detail/20160912181035032 购买云主机,然后远程连接,最接近企业开发,方便增加计算机集群。我用的这种方式。我使用的阿里云的esc,按量计费,很便宜。 选择按量计费 按固定宽带 然后你可以用浏览器的远程连接 阿里云自带浏览器远程连接 putty连接 也可以用xshell连接,随你

优秀的个人博客,低调大师

c语言基础学习02_helloworld

=============================================================================涉及到的知识点有:include有两种用法、{}大括号用法解释、C语言自定义名字的要求、c语言库函数printf的解释、编译错误有两种、调用system函数、c语言编译过程、操作系统结构、指令集中的cpu架构 、QT常用快捷键、vs常用快捷键 =============================================================================将windows的可执行文件上传到linux,看能够执行吗?sftp> put a.exe 出现下面错误:没有权限;拒绝访问-bash: ./a.exe: Permission denied那我们提升下a.exe的权限试试chmod u+x a.exe 则出现下面错误:不能执行二进制文件:执行格式错误-bash: ./a.exe: cannot execute binary file: Exec format error说明windows的可执行文件不能再linux系统下执行 fatal error 致命错误 =============================================================================#include的意思是头文件包含,使用c语言库函数需要提前包含所用到的库函数对应的头文件c语言中如果要用到printf函数,在使用前必须 #include <stdio.h>-----------------------------------------------------------------------------include有两种用法:1、#include <文件名> 说明需要包含的文件在系统目录下2、#include “文件名” 说明需要包含的文件在当前目录下-----------------------------------------------------------------------------可执行代码必须放在{}大括号里面; 在c语言中一行只写一个分号是可以的,表示是空语句。c语言中一组大括号里也可以再有多组大括号。-----------------------------------------------------------------------------int a; //定义一个变量。extern int b; //声明一个变量。-----------------------------------------------------------------------------C语言自定义名字的要求:可以使用大小写字母、下划线、数字,但第一个字母必须是字母或者下划线。且字母区分大小写。(注意:BASIC语言不区分大小写)----------------------------------------------------------------------------- printf 是c语言库函数,功能是:向标准输出设备输出一个字符串(注意:标准输出设备不仅仅指的是控制台、屏幕,还有打印机等等什么的。)printf 函数只能用在控制台程序里面(就是字符界面下的),不能用在图形界面下,即不能把一个字符串输出到窗口里面。可以通过命令 man 3 printf 来查看。 -----------------------------------------------------------------------------编译错误有两种warning 不影响编译,只是警告。error 编译器彻底罢工了,不干活了。----------------------------------------------------------------------------- 第一种写法: int main(){ return 0;} 第二种写法: void main(){ return ; //或者可以这句话不用写} 对c语言,两种写法都对,但对于C++来讲,只支持第一种写法。-----------------------------------------------------------------------------在main函数中return 0; 代表程序执行成功,return -1; 代表程序执行失败。-----------------------------------------------------------------------------c语言文件的扩展名是.c,C++文件的扩展名就是cpp linux系统并不用后缀名来区分文件;Linux不像Windows一样区分文件后缀的,所以是可以改的,而且不影响使用的。 1,mv可以移动文件,也可以用作更改文件名。 2,修改命名:mv fileName.type fileName.newType就可以更改文件后缀了。 3,但是一些特定的文件不要随意更改,例如配置文件。=============================================================================在使用system之前需要包含stdlib.h这个头文件,调用system函数,可以在c语言的代码中执行另外一个程序-----------------------------------------------------------------------------如果在命令行执行一个程序,那么这个程序的调用者就是操作系统; 如果在代码中通过system,执行一个程序,那么这个程序的调用者就是自己写的代码本身。 c语言所有的库函数调用,只能保证语法是一致的,但不能保证执行结果是一致的,同样的,库函数在不同的操作系统下执行结果可能是一样的,也可能是不一样的。 不同平台下的c语言的库函数只能保证调用语法一样,但不能保证执行结果也是一样的。(因为c语言对硬件的要求、对操作系统的要求太多啦!)所以用C语言在不同的平台写代码的时候,可能会有一些移植的工作量。-----------------------------------------------------------------------------POSIX是一个标准,只要符合这个标准的函数,在不同的系统下执行的结果就可以一致。如果有符合posix标准的函数,尽量使用。 Unix和Linux很多库函数都是支持POSIX的,但windows支持的比较差。(曾经微软说过要表示大力支持,但说得多做得少!)所以说,如果将Unix代码移植到Linux一般代价很小,如果把windows代码移植到Unix或者linux就比较麻烦。-----------------------------------------------------------------------------system 返回的是一个整数。即system的返回值就是所被调用程序中main函数的return的值。 =============================================================================c语言编译过程1、预编译 --> 2、编译 --> 3、链接-----------------------------------------------------------------------------预编译命令:gcc -o cc1.c c1.c -E 或者 gcc -o cc1.c -E c1.c 或者 gcc -E c1.c -o cc1.c(注意:-o 作用是指定输出文件的名字,如果不加-o的话,则生成的文件名字总叫a.out)预编译c1.c,预编译之后得到的文件的名字叫cc1.c。(注意:编译后的名字可以随意起,但是呢我们知道预编译后的文件还是文本的.c文件,所以为了好区分起名字为 xxx.c)在c语言中#开头的语句又叫预编译指令。#include <stdio.h>预编译的功能之一:会把include包含的头文件内容做一个简单的替换,即替换到.c文件里面去。......//此处省略1万行......预编译的功能之二:会把代码中的注释去掉。-----------------------------------------------------------------------------编译的命令:gcc -o cc1.o cc1.c -c 或者 gcc -o cc1.o -c cc1.c 或者gcc -c cc1.c -o cc1.o编译cc1.c,编译之后得到的文件名字叫cc1.o.编译的功能是:把文本的c语言编译为二进制指令。-----------------------------------------------------------------------------链接的命令:gcc -o c1 cc1.o 或者 gcc cc1.o -o c1(注意:gcc没有单独的链接参数) 将系统库函数与cc1.o进行链接(简言之合并),得到可执行的程序,该程序的名字叫c1。 我们想知道在linux系统下到底链接来了什么库来呢?(即可执行程序需要用到什么库呢?)使用命令 ldd c1 查看。 (注意;用c语言写的代码依赖的库最少,如果使用其他语言依赖的库更多哦!!需要装好多包包。)那么在windows系统下的可执行程序需要用到什么库呢?使用一个小软件Depends.exe可以查看的到。 =============================================================================操作系统结构 1、用户模式 我们目前写的程序都是在用户模式下运行的。2、内核模式 操作系统本身、设备驱动等这些软件是在内核模式下运行的。-----------------------------------------------------------------------------一个CPU的一个寄存器可以放8个二进制位。例如:0000 00001111 1111则这个CPU就是8位的CPU。-----------------------------------------------------------------------------一个CPU的一个寄存器可以放16个二进制位。0000 0000 0000 00001111 1111 1111 1111则这个CPU就是16位CPU。-----------------------------------------------------------------------------总线有三种:数据总线、地址总线、控制总线。总线在大多数时候和CPU的寄存器位数是相同的。 8位CPU的总线是8位。1111 1111f f256BYTE(255字节) 16位CPU的总线是16位。1111 1111 1111 1111f f f f65536BYTE(64k字节) 32位CPU的总线是32位。1111 1111 1111 1111 1111 1111 1111 1111f f f f f f f f32位CPU管理内存有一个最大值,4G字节 = 4 x 1024M = 4 x 1024 x 1024 x 1024Byte(字节)。 64位CPU的总线是64位。1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111f f f f f f f f f f f f f f f f理论上64位CPU管理内存是:2^64个字节,但同时又取决于综合的指标:比如主板、操作系统的支持等等。但至少是远远大于4G的。 如果寄存器是64位,但总线是32位,这种cpu叫准64位CPU。(即里面可以做到很宽,但是外面的工艺却达不到) 若在64位的CPU架构上运行了64位的软件操作系统,那么这个系统是64位的;若在64位的CPU架构上运行了32位的软件操作系统,那么这个系统是32位的。-----------------------------------------------------------------------------指令集中的cpu架构 精简指令集RISC(服务器端用的)比如:SPARC、ARM属于精简指令集。 复杂指令集CISC(比如Inter的CPU)比如:X86属于典型的复杂指令集。-----------------------------------------------------------------------------cpu内部里面所有的计算都得在寄存器里面来完成。 cpu内部的寄存器还有名字哦:8位cpu(x86构架) 16位CPU 32位CPU 64位CPU a ax,al,ah eax rax b bx,bl,bh ebx rbx c cx ecx rcx d dx edx rdx-----------------------------------------------------------------------------使用Qt时,再用到system函数时,会出现一个控制台的窗口。为什么呢?答:因为system函数在windows系统下就是一个基于控制台的函数(就是字符界面的函数),所以即使在图形界面下调用system也会出现一个控制台窗口。那么如何在图形界面下调用该函数又不显示控制台呢?答:可以换另外一个函数啊!该函数是 WinExec("notepad",SW_NORMAL); 但是该函数需要包含一个头文件是 #include <windows.h>。 QT常用快捷键Ctrl + I 自动格式化代码Ctrl + / 注释代码/取消注释代码Ctrl + r 不调试运行代码Ctrl + b 编译代码但不运行代码Alt + enter 自动完成类函数定义F9 设置断点F5 调试运行F10 next调试F11 step调试-----------------------------------------------------------------------------vs常用快捷键Ctrl + F5 不调试运行代码Ctrl + k,Ctrl + f 自动格式化代码Ctrl + k,Ctrl + c 注释代码Ctrl + k,Ctrl + u 取消注释代码Ctrl + Shift + b 编译,不运行代码F5 调试运行F9 设置断点 注意:C语言以分号结尾的,而不是以行结尾的。=============================================================================我的GitHub地址: https://github.com/heizemingjun 我的博客园地址: http://www.cnblogs.com/chenmingjun 我的蚂蚁笔记博客地址: http://blog.leanote.com/chenmingjun Copyright ©2018 黑泽明军 【转载文章务必保留出处和署名,谢谢!】

优秀的个人博客,低调大师

[Android学习笔记二] View转化Bitmap

在View类中的onDraw方法的参数Canvas是View绘制的背景,要将View转换为Bitmap实际上就是让Canvas上的绘制操作绘制到Bitmap上。 View转化为Bitmap也称为截屏,让用户看到的View视图转化为图片的过程。 关于View转化Bitmap涉及到的View类中的方法有: 1 2 3 4 5 protected void onDraw(Canvascanvas) public void buildDrawingCache() public void destroyDrawingCache() public BitmapgetDrawingCache() public void setDrawingCacheEnabled( boolean enabled) 下面是常见的几个View截屏的示例: 1.View转Bitmap 1 2 3 4 5 6 7 8 9 10 11 public final BitmapscreenShot(Viewview){ if ( null ==view){ throw new IllegalArgumentException( "parametercan'tbenull." ); } view.measure(View.MeasureSpec.UNSPECIFIED,View.MeasureSpec.UNSPECIFIED); view.layout( 0 , 0 ,view.getMeasuredWidth(),view.getMeasuredHeight()); view.setDrawingCacheEnabled( true ); view.buildDrawingCache(); Bitmapbitmap=view.getDrawingCache(); return bitmap; } 2. Activity转Bitmap,不带状态栏 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 public final BitmapscreenShot(Activityactivity){ if ( null ==activity){ throw new IllegalArgumentException( "parametercan'tbenull." ); } Viewview=activity.getWindow().getDecorView(); view.setDrawingCacheEnabled( true ); view.buildDrawingCache(); Bitmapb1=view.getDrawingCache(); Rectframe= new Rect(); view.getWindowVisibleDisplayFrame(frame); int statusBarHeight=frame.top; Pointpoint= new Point(); activity.getWindowManager().getDefaultDisplay().getSize(point); int width=point.x; int height=point.y; Bitmapb2=Bitmap.createBitmap(b1, 0 ,statusBarHeight,width,height-statusBarHeight); view.destroyDrawingCache(); return b2; } 3. ScrollView转长Bitmap(类似锤子便签的截长图) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public final BitmapscreenShot(ScrollViewscrollView){ if ( null ==scrollView){ throw new IllegalArgumentException( "parametercan'tbenull." ); } int height= 0 ; Bitmapbitmap; for ( int i= 0 ,s=scrollView.getChildCount();i<s;i++){ height+=scrollView.getChildAt(i).getHeight(); scrollView.getChildAt(i).setBackgroundResource(android.R.drawable.screen_background_light); } bitmap=Bitmap.createBitmap(scrollView.getWidth(),height,Bitmap.Config.ARGB_8888); final Canvascanvas= new Canvas(bitmap); scrollView.draw(canvas); return bitmap; } 本文转自 secondriver 51CTO博客,原文链接:http://blog.51cto.com/aiilive/1711443,如需转载请自行联系原作者

优秀的个人博客,低调大师

openstack学习笔记九 cinder基础配置

cinder 就是 云硬盘 配置cinder步骤 1 安装软件包,然后到keystone注册 创建必要的用户名 密码 服务 endpoint 2 设置配置文件 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 yum install openstack-cinder-y keystoneuser-create--namecinder--passhequan keystoneuser-role-add--usercinder--roleadmin--tennatservices keystoneservice-create--namecinder-- type volume--descriptioncinderxxx 例子关于cul keystoneservice-list |d1271040fa9144318a836a0b476d1e66|cinder|volume|CinderService| keystoneendpoint-list| grep d1271040fa9144318a836a0b476d1e66 |8e18c46fc51c4a6287ea740a37537a59|RegionOne|http: //115 .29.107.17:8776 /v1/ %(tenant_id)s|http: //115 .29.107.17:8776 /v1/ %(tenant_id)s|http: //115 .29.107.17:8776 /v1/ %(tenant_id)s|d1271040fa9144318a836a0b476d1e66| keystoneendpoint-create--service- id d1271040fa9144318a836a0b476d1e66--publicul 'http://115.29.107.17:8776/v1/%(tenant_id)s' --internalurl 'http://115.29.107.17:8776/v1/%(tenant_id)s' --adminurl 'http://115.29.107.17:8776/v1/%(tenant_id)s' [root@hequan~(keystone_admin)] #cd/etc/cinder/ [root@hequancinder(keystone_admin)] #ls api- paste .inipolicy.jsonrootwrap.d cinder.confrootwrap.confvolumes [root@hequancinder(keystone_admin)] #cpcinder.confcinder.conf.bak##备份 [root@hequan~(keystone_admin)] #cp/usr/share/cinder/cinder-dist.conf/etc/cinder/cinder.conf##复制配置文件 [root@hequancinder(keystone_admin)] #chownroot.cindercinder.conf##记得修改权限 [root@hequancinder(keystone_admin)] #openstack-db--init-servicecinder--passwordhequan--rootpw123456##创建数据库 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 [root@hequancinder(keystone_admin)] #vimcinder.conf [DEFAULT] logdir= /var/log/cinder state_path= /var/lib/cinder lock_path= /var/lib/cinder/tmp volumes_dir= /etc/cinder/volumes iscsi_helper=lioadm rootwrap_config= /etc/cinder/rootwrap .conf auth_strategy=keystone [database] connection=mysql: //cinder :hequan@115.29.107.17 /cinder [keystone_authtoken] admin_tenant_name=services admin_user=cinder admin_password=hequan auth_host=115.29.107.17 auth_port=35357 auth_protocol=http [root@hequancinder(keystone_admin)] #grep^rabbit/etc/keystone/keystone.conf rabbit_host=localhost rabbit_port=5672 rabbit_hosts=localhost:5672 rabbit_use_ssl=False rabbit_userid=guest rabbit_password=guest rabbit_virtual_host=/ rabbit_ha_queues=False ##把这些写到上面的配置文件里,通信用 [root@hequancinder(keystone_admin)] #systemctllist-unit-files|grepcinder openstack-cinder-api.serviceenabled ##用户接口 openstack-cinder-backup.serviceenabled ##备份 openstack-cinder-scheduler.serviceenabled ##调度 openstack-cinder-volume.serviceenabled ##后端存储卷 [root@hequancinder(keystone_admin)] #systemctlis-activeopenstack-cinder-api.service active [root@hequancinder(keystone_admin)] #systemctlstartopenstack-cinder-api.serviceopenstack-cinder-backup.serviceopenstack-cinder-scheduler.serviceopenstack-cinder-volume.service [root@hequancinder(keystone_admin)] #systemctlenableopenstack-cinder-api.serviceopenstack-cinder-backup.serviceopenstack-cinder-scheduler.serviceopenstack-cinder-volume.service 再创建一个cinderv2和上面一样 |8fe36f49892447679bc5433b21591906|cinderv2|volumev2|CinderServicev2| |75a8f5bbf35a42a0bfcd2e6a0d4cea9c|RegionOne|http: //115 .29.107.17:8776 /v2/ %(tenant_id)s|http: //115 .29.107.17:8776 /v2/ %(tenant_id)s|http: //115 .29.107.17:8776 /v2/ %(tenant_id)s|8fe36f49892447679bc5433b21591906| 2 修改配置 1 2 3 4 5 [root@hequancinder(keystone_admin)] #cinderlist +----+--------+------------------+------+------+-------------+----------+-------------+-------------+ |ID|Status|MigrationStatus|Name|Size|VolumeType|Bootable|Multiattach|Attachedto| +----+--------+------------------+------+------+-------------+----------+-------------+-------------+ +----+--------+------------------+------+------+-------------+----------+-------------+-------------+ 1 2 3 4 5 6 创建VG [root@hequancinder(keystone_admin)] #pvcreate/dev/xvdb [root@hequancinder(keystone_admin)] #vgcreatecinder-volumes/dev/xvdb [root@hequancinder(keystone_admin)] #vgs VG #PV#LV#SNAttrVSizeVFree cinder-volumes100wz--n-20.60g20.60g 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 [root@hequancinder(keystone_admin)] #cindercreate--display-namevoll1 +---------------------------------------+--------------------------------------+ |Property|Value| +---------------------------------------+--------------------------------------+ |attachments|[]| |availability_zone|nova| |bootable| false | |consistencygroup_id|None| |created_at|2016-07-27T15:14:07.000000| |description|None| |encrypted|False| | id |7f778803-41cd-492f-b3b7-baa349b9c3dc| |metadata|{}| |migration_status|None| |multiattach|False| |name|voll| |os-vol-host-attr:host|None| |os-vol-mig-status-attr:migstat|None| |os-vol-mig-status-attr:name_id|None| |os-vol-tenant-attr:tenant_id|ddac36f63e4547e0a8619574dbc41534| |os-volume-replication:driver_data|None| |os-volume-replication:extended_status|None| |replication_status|disabled| |size|1| |snapshot_id|None| |source_volid|None| |status|creating| |user_id|9382216e2ea540a2af70216577dbed00| |volume_type|None| +---------------------------------------+--------------------------------------+ [root@hequancinder(keystone_admin)] #cinderlist +--------------------------------------+-----------+------------------+------+------+-------------+----------+-------------+-------------+ |ID|Status|MigrationStatus|Name|Size|VolumeType|Bootable|Multiattach|Attachedto| +--------------------------------------+-----------+------------------+------+------+-------------+----------+-------------+-------------+ |7f778803-41cd-492f-b3b7-baa349b9c3dc|available|-|voll|1|-| false |False|| +--------------------------------------+-----------+------------------+------+------+-------------+----------+-------------+-------------+ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ##添加到上面的配置cinder.conf中作为单独字段 [lvm] iscsi_helper=lioadm volume_group=cinder-volumes ##那个组决定默认存储 iscsi_ip_address=115.29.107.17 volume_driver=cinder.volume.drivers.lvm.LVMVolumeDriver ##云硬盘默认存储LVM volumes_dir= /var/lib/cinder/volumes iscsi_protocol=iscsi volume_backend_name=lvm [root@hequancinder(keystone_admin)] #lvs LVVGAttrLSizePoolOriginData%Meta%MoveLogCpy%SyncConvert volume-7f778803-41cd-492f-b3b7-baa349b9c3dccinder-volumes-wi-a-----1.00g [root@hequancinder(keystone_admin)] #lvscan ACTIVE '/dev/cinder-volumes/volume-7f778803-41cd-492f-b3b7-baa349b9c3dc' [1.00GiB]inherit 1 2 3 4 5 6 更换名字 volume_group=vg0 [root@hequancinder(keystone_admin)] #vgrenamecinder-volumesvg0##更改名字 [root@hequan~] #vgs VG #PV#LV#SNAttrVSizeVFree vg0120wz--n-20.60g9.60g 1 2 3 4 5 6 7 8 9 10 11 待测试ceph做后端存储具体ceph配置可看我前一篇glance volume_driver=cinder.volume.drivers.rbd.RBDDriver rbd_pool=cinder #ceph卷名字 rbd_ceph_conf= /etc/ceph/ceph .conf rbd_flatten_volume_from_snapshot= false rbd_max_clone_depth=5 rbd_stone_chunk_size=4 rados_connect_timeout=-1 glance_api_version=2 setfacl-mu:cinder:r-- /etc/ceph/ceph .client.admin.keyring ##cinder可读 本文转自 295631788 51CTO博客,原文链接:http://blog.51cto.com/hequan/1830981,如需转载请自行联系原作者

优秀的个人博客,低调大师

Android UI学习 - FrameLayou和布局优化

FrameLayout 先来看官方文档的定义:FrameLayout是最简单的一个布局对象。它被定制为你屏幕上的一个空白备用区域,之后你可以在其中填充一个单一对象 — 比如,一张你要发布的图片。所有的子元素将会固定在屏幕的左上角;你不能为FrameLayout中的一个子元素指定一个位置。后一个子元素将会直接在前一个子元素之上进行覆盖填充,把它们部份或全部挡住(除非后一个子元素是透明的)。 我的理解是,把FrameLayout当作画布canvas,固定从屏幕的左上角开始填充图片,文字等。看看示例,原来可以利用 android:layout_gravity来设置位置的: <?xmlversion="1.0"encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent"> <ImageView android:id="@+id/image" android:layout_width="fill_parent" android:layout_height="fill_parent" android:scaleType="center" android:src="@drawable/candle" /> <TextView android:id="@+id/text1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:textColor="#00ff00" android:text="@string/hello" /> <Button android:id="@+id/start" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom" android:text="Start" /> </FrameLayout> 效果图 布局优化 使用tools里面的hierarchyviewer.bat来查看layout的层次。在启动模拟器启动所要分析的程序,再启动hierarchyviewer.bat,选择模拟器以及该程序,点击“Load View Hierarchy”,就会开始分析。可以save as png。 <merge>减少视图层级结构 从上图可以看到存在两个FrameLayout,红色框住的。如果能在layout文件中把FrameLayout声明去掉就可以进一步优化布局代码了。 但是由于布局代码需要外层容器容纳,如果 直接删除FrameLayout则该文件就不是合法的布局文件。这种情况下就可以使用<merge> 标签了。 修改为如下代码就可以消除多余的FrameLayout了: <?xmlversion="1.0"encoding="utf-8"?> <mergexmlns:android="http://schemas.android.com/apk/res/android"> <ImageView android:id="@+id/image" android:layout_width="fill_parent" android:layout_height="fill_parent" android:scaleType="center" android:src="@drawable/candle" /> <TextView android:id="@+id/text1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:textColor="#00ff00" android:text="@string/hello" /> <Button android:id="@+id/start" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="bottom" android:text="Start" /> </merge> <merge>也有一些使用限制: 只能用于xml layout文件的根元素;在代码中使用LayoutInflater.Inflater()一个以merge为根元素的 布局文件时候,需要使用 View inflate (int resource, ViewGroup root, boolean attachToRoot)指定一个ViewGroup 作为其容器,并且要设置attachToRoot 为true。 <include>重用layout代码 如果在某个布局里面需要用到另一个相同的布局设计,可以通过<include> 标签来重用layout代码: <?xmlversion="1.0"encoding="utf-8"?> <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <includeandroid:id="@+id/layout1"layout="@layout/relative"/> <includeandroid:id="@+id/layout2"layout="@layout/relative"/> <includeandroid:id="@+id/layout3"layout="@layout/relative"/> </LinearLayout> 效果图 这里要注意的是, "@layout/relative"不是引用Layout的id,而是引用res/layout/relative.xml,其内容是前面文章介绍RelativeLayout的布局代码。 另外,通过<include>,除了可以覆写id属性值,还可以修改其他属性值,例如android:layout_width,android:height等。 <viewstub> 延迟加载 (转自 http://rainhomepage.appspot.com/2010/01/use-viewstub-to-optimize-the-layout-of) ViewStub 是一个不可见的,大小为0的View,最佳用途就是实现View的延迟加载,在需要的时候再加载View,可Java中常见的性能优化方法延迟加载一样。 当调用ViewStub的setVisibility函数设置为可见或则调用 inflate初始化该View的时候,ViewStub引用的资源开始初始化,然后引用的资源替代ViewStub自己的位置填充在ViewStub的 位置。因此在没有调用setVisibility(int) 或则 inflate()函数之前 ViewStub一种存在组件树层级结构中,但是由于ViewStub非常轻量级,这对性能影响非常小。 可以通过ViewStub的inflatedId属性来重新定义引用的layout id。 例如: <ViewStubandroid:id="@+id/stub" android:inflatedId="@+id/subTree" android:layout="@layout/mySubTree" android:layout_width="120dip" android:layout_height="40dip"/> 上面定义的ViewStub ,可以通过id “stub”来找到,在初始化资源“mySubTree”后,stub从父组件中删除,然后"mySubTree"替代stub的位置。初始资源"mySubTree"得到的组件可以通过inflatedId 指定的id "subTree"引用。 然后初始化后的资源被填充到一个120dip宽、40dip高的地方。 推荐使用下面的方式来初始化ViewStub: ViewStubstub=(ViewStub)findViewById(R.id.stub); Viewinflated=stub.inflate(); 当调用inflate()函数的时候,ViewStub 被引用的资源替代,并且返回引用的view。 这样程序可以直接得到引用的view而不用再次调用函数 findViewById()来查找了。 ViewStub目前有个缺陷就是还不支持 <merge /> 标签。 layoutopt (Layout Optimization工具) 这工具可以分析所提供的Layout,并提供优化意见。在tools文件夹里面可以找到layoutopt.bat。 用法: layoutopt <list of xml files or directories> 参数: 一个或多个的Layout xml文件,以空格间隔;或者多个Layout xml文件所在的文件夹路径 例子: layoutopt G:\StudyAndroid\UIDemo\res\layout\main.xml layoutopt G:\StudyAndroid\UIDemo\res\layout\main.xml G:\StudyAndroid\UIDemo\res\layout\relative.xml layoutopt G:\StudyAndroid\UIDemo\res\layout 本文转自 Icansoft 51CTO博客,原文链接: http://blog.51cto.com/android/308090

优秀的个人博客,低调大师

Android开发学习笔记:浅谈DDMS视图

DDMS 的全称是Dalvik Debug Monitor Service,即Dalvik调试监控服务,是一个可视化的调试监控工具。它主要是对系统运行后台日志的监控,还有系统线程,模拟器状态的监控。此外,它还可以模拟收发短信,拨打电话和发送GPS位置信息等。 在eclipse中启动DDMS 1.在eclipse界面的右上角,点击,出现下面的界面 2.选择other,这时界面如下图所示,双击DDMS就可以启动 DDMS各部分组成的功能简介 1.Devices 可以查看到所有与DDMS连 接的模拟器详细信息,以及每个模拟器正在运行的APP进程,每个进程最右边相对应的是与调试器链接的端口。 2.Emulator Control可以实现对模拟器的控制,比如:接听电话,根据选项模拟各种不同网络情况,模拟接受SMS消息和发送虚拟地址坐标用于测试GPS功能等。 Telephony Status:通过选项模拟语音质量以及信号连接模式。 Telephony Actions:模拟电话接听和发送SMS到测试终端。 Location Control:模拟地理坐标或者模拟动态的路线坐标变化并显示预设的地理标识,可以通过以下3种方式: (1)Manual:手动为终端发送二维经纬坐标。 (2)GPX:通过GPX文件导入序列动态变化地理坐标,从而模拟行进中GPS变化的数值。 (3)KML:通过KML文件导入独特的地理标识,并以动态形式根据变化的地理坐标显示在测试终端。 3.LogCat主要输出模拟器的一些信息 4.Filter功能类似过滤器,能过滤一些调试的信息 5. V:输出所有的信息 D:输出Debug信息 I:输出info信息 W:输出警告信息 E:输出错误的信息 :能删除当前LogCat输出的信息 6.Threads、Heap、File Exporler,最常用的就是File Exporler文件浏览器,通过File Exporler可以查看Android模拟器中的文件,可以很方便的导入/出文件。 本文转自 lingdududu 51CTO博客,原文链接: http://blog.51cto.com/liangruijun/631061

优秀的个人博客,低调大师

【Android进阶学习】Http编程之HttpClient

在Android开发中,Android SDK附带了Apache的HttpClient,它是一个完善的客户端。它提供了对HTTP协议的全面支持,可以使用HttpClient的对象来执行HTTP GET和HTTP POST调用。 HTTP工作原理: 1.客户端(一般是指浏览器,这里是指自己写的程序)与服务器建立连接 2.建立连接后,客户端向服务器发送请求 3.服务器接收到请求后,向客户端发送响应信息 4.客户端与服务器断开连接 HttpClient的一般使用步骤: 1.使用DefaultHttpClient类实例化HttpClient对象 2.创建HttpGet或HttpPost对象,将要请求的URL通过构造方法传入HttpGet或HttpPost对象。 3.调用execute方法发送HTTP GET或HTTP POST请求,并返回HttpResponse对象。 4.通过HttpResponse接口的getEntity方法返回响应信息,并进行相应的处理。 最后记得要在AndroidManifest.xml文件添加网络权限 <uses-permission android:name="android.permission.INTERNET" /> 下面是具体的例子: 1.使用HttpClient来执行GET调用 在LogCat窗口就能看到输出的信息 packagecom.lingdududu.http; importjava.io.InputStream; importorg.apache.http.HttpResponse; importorg.apache.http.HttpStatus; importorg.apache.http.client.HttpClient; importorg.apache.http.client.methods.HttpGet; importorg.apache.http.impl.client.DefaultHttpClient; importandroid.app.Activity; importandroid.os.Bundle; importandroid.util.Log; publicclassHttpGetActivityextendsActivity{ Stringuri="http://developer.android.com/"; finalStringTAG_STRING="TAG"; @Override publicvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.main); try{ //得到HttpClient对象 HttpClientgetClient=newDefaultHttpClient(); //得到HttpGet对象 HttpGetrequest=newHttpGet(uri); //客户端使用GET方式执行请教,获得服务器端的回应response HttpResponseresponse=getClient.execute(request); //判断请求是否成功 if(response.getStatusLine().getStatusCode()==HttpStatus.SC_OK){ Log.i(TAG_STRING,"请求服务器端成功"); //获得输入流 InputStreaminStrem=response.getEntity().getContent(); intresult=inStrem.read(); while(result!=-1){ System.out.print((char)result); result=inStrem.read(); } //关闭输入流 inStrem.close(); }else{ Log.i(TAG_STRING,"请求服务器端失败"); } }catch(Exceptione){ //TODOAuto-generatedcatchblock e.printStackTrace(); } } } 使用HTTP GET调用有一个缺点就是,请求的参数作为URL一部分来传递,以这种方式传递的时候,URL的长度应该在2048个字符之内。如果超出这个这范围,就要使用到HTTP POST调用。 2.使用HttpClient来执行POST调用 使用POST调用进行参数传递时,需要使用NameValuePair来保存要传递的参数。NameValuePair封装了一个键/值组合。另外,还需要设置所使用的字符集。 packagecom.androidbook.services.httppost; importjava.io.BufferedReader; importjava.io.IOException; importjava.io.InputStreamReader; importjava.util.ArrayList; importjava.util.List; importorg.apache.http.HttpResponse; importorg.apache.http.NameValuePair; importorg.apache.http.client.HttpClient; importorg.apache.http.client.entity.UrlEncodedFormEntity; importorg.apache.http.client.methods.HttpPost; importorg.apache.http.impl.client.DefaultHttpClient; importorg.apache.http.message.BasicNameValuePair; importandroid.app.Activity; importandroid.os.Bundle; publicclassHttpPostActivityextendsActivity{ Stringuri="http://developer.android.com/"; @Override publicvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.main); BufferedReaderin=null; try{ HttpClientclient=newDefaultHttpClient(); HttpPostrequest=newHttpPost("http://code.google.com/android/"); //使用NameValuePair来保存要传递的Post参数 List<NameValuePair>postParameters=newArrayList<NameValuePair>(); //添加要传递的参数 postParameters.add(newBasicNameValuePair("id","12345")); postParameters.add(newBasicNameValuePair("username","dave")); //实例化UrlEncodedFormEntity对象 UrlEncodedFormEntityformEntity=newUrlEncodedFormEntity( postParameters); //使用HttpPost对象来设置UrlEncodedFormEntity的Entity request.setEntity(formEntity); HttpResponseresponse=client.execute(request); in=newBufferedReader( newInputStreamReader( response.getEntity().getContent())); StringBufferstring=newStringBuffer(""); StringlineStr=""; while((lineStr=in.readLine())!=null){ string.append(lineStr+"\n"); } in.close(); StringresultStr=string.toString(); System.out.println(resultStr); }catch(Exceptione){ //Dosomethingaboutexceptions }finally{ if(in!=null){ try{ in.close(); }catch(IOExceptione){ e.printStackTrace(); } } } } } 本文转自 lingdududu 51CTO博客,原文链接: http://blog.51cto.com/liangruijun/803097

优秀的个人博客,低调大师

【Android进阶学习】屏蔽,捕获Home键

在Level5以上(包含)中,Activity类中的方法:public void onAttachedToWindow ()就能对Home键进行捕获。具体代码如下: MainActivity.java packagecom.lingdududu.test; importandroid.app.Activity; importandroid.os.Bundle; importandroid.view.KeyEvent; importandroid.view.WindowManager; importandroid.widget.Toast; publicclassMainActivityextendsActivity{ /**Calledwhentheactivityisfirstcreated.*/ privatebooleancatchHomeKey=false; publicvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.main); } @Override publicvoidonAttachedToWindow(){ //TODOAuto-generatedmethodstub if(!catchHomeKey){ this.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD); } super.onAttachedToWindow(); } @Override publicbooleanonKeyDown(intkeyCode,KeyEventevent){ //TODOAuto-generatedmethodstub if(keyCode==KeyEvent.KEYCODE_HOME){ Toast.makeText(MainActivity.this,"你点击了HOME键",Toast.LENGTH_LONG).show(); } returnsuper.onKeyDown(keyCode,event); } } 当我们点击Home键的时候,程序并没有回到主界面,而是停留在当前的页面,并且能捕获到Home键,调用Toast显示信息。 效果图: 本文转自 lingdududu 51CTO博客,原文链接:http://blog.51cto.com/liangruijun/732092

优秀的个人博客,低调大师

openstack学习笔记二 网络设置基础

租用这个服务的机构,我们称之"租户/tenant/项目/project" 租户 用户 vxlan划分租户 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 [root@h1~] #ipaddr 1:lo:<LOOPBACK,UP,LOWER_UP>mtu65536qdiscnoqueuestateUNKNOWN link /loopback 00:00:00:00:00:00brd00:00:00:00:00:00 inet127.0.0.1 /8 scopehostlo valid_lftforeverpreferred_lftforever 2:eth0:<BROADCAST,MULTICAST,UP,LOWER_UP>mtu1500qdiscmqstateUPqlen1000 link /ether 00:50:56:a0:b6:6bbrdff:ff:ff:ff:ff:ff inet192.168.1.201 /24 brd192.168.1.255scopeglobaleth0 valid_lftforeverpreferred_lftforever 3:ovs-system:<BROADCAST,MULTICAST>mtu1500qdiscnoopstateDOWN link /ether 36:26:25:65:14:9cbrdff:ff:ff:ff:ff:ff 4:br-ex:<BROADCAST,MULTICAST,UP,LOWER_UP>mtu1500qdiscnoqueuestateUNKNOWN link /ether de:4c:6d:9c:15:4dbrdff:ff:ff:ff:ff:ff 5:br-int:<BROADCAST,MULTICAST>mtu1500qdiscnoopstateDOWN link /ether ce:0b:9b:b5:c1:4dbrdff:ff:ff:ff:ff:ff 6:br-tun:<BROADCAST,MULTICAST>mtu1500qdiscnoopstateDOWN link /ether ae:75:26:fb:f8:42brdff:ff:ff:ff:ff:ff 你想把哪个网络作为数据包的出口,那么你就应该把那个网卡桥接到 br-ex openvswitch 简称 ovs 配置网卡 重点 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 [root@h1network-scripts] #catifcfg-eth0 DEVICE=eth0 DEVICETYPE=ovs TYPE=OVSPort OVS_BRIDGE=br-ex ONBOOT= yes BOOTPROTO=none [root@h1network-scripts] #catifcfg-br-ex DEVICE=br-ex DEVICETYPE=ovs TYPE=OVSBridge ONBOOT= yes BOOTPROTO=none IPADDR=192.168.1.201 NETMASK=255.255.255.0 GATEWAY=192.168.1.1 DNS1=202.106.0.20 1 2 3 4 5 6 7 8 9 10 查看网卡 2:eth0:<BROADCAST,MULTICAST,UP,LOWER_UP>mtu1500qdiscmqmasterovs-systemstateUPqlen1000 link /ether 00:50:56:a0:b6:6bbrdff:ff:ff:ff:ff:ff 3:ovs-system:<BROADCAST,MULTICAST>mtu1500qdiscnoopstateDOWN link /ether d2:18:7d:5e:5e:b9brdff:ff:ff:ff:ff:ff 5:br-ex:<BROADCAST,MULTICAST,UP,LOWER_UP>mtu1500qdiscnoqueuestateUNKNOWN link /ether 00:50:56:a0:b6:6bbrdff:ff:ff:ff:ff:ff inet192.168.1.201 /24 brd192.168.1.255scopeglobalbr-ex valid_lftforeverpreferred_lftforever 管理员登陆http://192.168.1.201/dashboard 选择系统--网络--创建网络 创建,点击网络名称put-ex 下一步 创建一个项目,创建一个新的用户,新用户关联项目。 用新的用户登录,创建网络 先创建网络,然后创建路由,连到网络上,最后添加端口 本文转自 295631788 51CTO博客,原文链接:http://blog.51cto.com/hequan/1795705,如需转载请自行联系原作者

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

用户登录
用户注册