首页 文章 精选 留言 我的

精选列表

搜索[知识资产沉淀],共10000篇文章
优秀的个人博客,低调大师

JSP必备知识点

servlet VS CGI 1)servlet 可移植 跨平台 CGI 不行 2)在传统 CGI 中每个请求都要启动一个新进程,若 CGI 程序的本身执行时间较短,启动进程所需要的进行所需要的开销很可能反而超过实际执行的时间;servlet,每个请求由轻量级的 java 线程处理 3)在传统 CGI 中,若有 N 个并发的对同一个 CGI 的请求,该 CGI 的程序代码在内存中重载了 N 次,对于 servlet,处理请求的是 N 个线程,只要一份 servlet 类代码 如何实现 servlet 单线程模式 要实现单线程模式,可以在配置文件中修改 isThreadSafe 属性,比如,<%@page isThreadSafe=”false”%> servlet 页面间对象传递的方法有几种 用 request,session,application。Cookie 等方法实现页面间的对象传递。 jsp VS servlet jsp 是 servlet 技术的扩展,本质上是 servlet 的简单方式,jsp 编译后是“类 servlet”。他们最主要额不同在于:servlet 的应用逻辑在 java 文件中,并且完全从表示层中的 html 分离出来。Jsp 是 java 和 html 可以组合为一个扩展名为.jsp 的文件。Jsp 侧重视图, servlet 侧重控制逻辑。 <jsp:include page=”include.jsp” flash=”true”> <jsp:forword page=”next.jsp”> 前者页面不会转向 include 所指向的页面,只显示该页的结果,主页面还是原来的页面,指向完以后还会回来,相当于函数调用,并且可以带参数。后者完全转向新页面,不会再回来,相当于 goto 语句。 内置对象 1)request:用户端的请求,此请求会包含来着 get or post 请求的参数。 2)response:网页传回用户端的响应。 3)pageContext:网页的属性 4)session:与请求有关的会话 5)application:servlet 正在执行的内容 6)out:传送回应的输出 7)conig:servlet 的部件 8)page:gsp 网页本身 9)exception:网页错误 哪些动作(6 个) 1)jsp:include 在页面被请求时,引入一个文件 2)jsp:useBean 寻找 or 实例化一个 JavaBean 3)jsp:setProperty 这只 javaBean 的属性 4)jsp:getProperty 输出某个 javaBean 的属性 5)jsp:forword 把请求转到一个新页面 6)jsp:plugin 根据浏览器类型为 java 插件生成 object or embed 标配 动态 include 与静态 include 动态 include 用 jsp:include 动作实现,它总是会检查所包含文件中的变化,使用于包含动态页面 静态 include 用 include 伪码实现,不会检查所含文件的变化,适用于包含静态页面。

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

PHP知识点笔记

显示错误:PDOException could not find driver. 是表示PDO没有安装对应数据库的扩展,比如没有安装PDO_mysql http://pecl.php.net/package/PDO_MYSQL 下载源码 phpize ./configure --with-php-config=/usr/local/php/bin/php-config ./make ./make install phpExcel的使用需要使用到php的xmlreader和xmlwriter扩展 如果你是使用yum安装php 就直接使用yum install php-xml来进行安装 php的define不能重复定义 比如: 1 2 3 4 5 6 7 <?php define( "TEST" , "11" ); define( "TEST" , "22" ); echo TEST; 1 1 2 3 4 5 6 7 [yejianfeng@xen193v ~/handcode]$ php test.php PHP Notice: Constant TEST already defined in /home/yejianfeng/handcode/test.php on line 4 Notice: Constant TEST already defined in /home/yejianfeng/handcode/test.php on line 4 11 PHP如何获取本地所有变量 $localVariables = compact(array_keys(get_defined_vars())); 安装php模块可以这么安装 PHP_PDO_SHARED=1 pecl install pdo_mysql mysql的字符编码 mysql一般默认的客户端字符编码为:latin1 mysql的字符编码有几种: mysql> show variables like "character_set_%"; +--------------------------+----------------------------+ | Variable_name | Value | +--------------------------+----------------------------+ | character_set_client | utf8 | | character_set_connection | utf8 | | character_set_database | latin1 | | character_set_filesystem | binary | | character_set_results | utf8 | | character_set_server | latin1 | | character_set_system | utf8 | | character_sets_dir | /usr/share/mysql/charsets/ | +--------------------------+----------------------------+ 其中信息输入路径是 client - connection - server 信息输出路径是 server - connection - result 输入set names utf8是临时设置client和connection的字符编码 如何在PHP中初始化mysql的字符编码? 有两种方法可以初始化设置: 1 1 2 3 $pdo = new PDO( "mysql:host={$config['host']};dbname={$config['dbname']};port={$config['port']}" , $config [ 'user' ], $config [ 'password' ], array (PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8" )); 2 1 2 3 4 5 $pdo = new PDO( "mysql:host={$config['host']};dbname={$config['dbname']};port={$config['port']}" , $config [ 'user' ], $config [ 'password' ]); $pdo -> exec ( 'set names utf8' ); PHP的PDO扩展 使用php如果要使用PDO,你需要安装的扩展除了PDO,还要各种数据库的驱动,PDO扩展是定义了一系列接口,但是你不可以使用PDO扩展直接操作数据库,需要安装制定PDO驱动扩展 PDO扩展的说明:http://www.php.net/manual/en/intro.pdo.php PDO扩展只能在PHP 5.0之上使用(使用了php的OO属性) 针对不同的数据库的扩展有: 为什么PDO的prepare不能打出最后的sql 使用PDO一直有一个郁闷的地方,就是使用prepare的时候想要将最后执行的sql打出来做log,发现没有方法。。。 后来想了想,prepare是mysql的语句,那么PDO的prepare和execute实际上是对mysql发送了几次请求,prepare,set,execute mysql> PREPARE stmt1 FROM 'SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse'; mysql> SET @a = 3; mysql> SET @b = 4; mysql> EXECUTE stmt1 USING @a, @b; +------------+ | hypotenuse | +------------+ | 5 | +------------+ mysql> DEALLOCATE PREPARE stmt1; 所以,如果要打出log,只有自己拼sql了。。。 本文转自轩脉刃博客园博客,原文链接:http://www.cnblogs.com/yjf512/archive/2013/05/10/3070760.html,如需转载请自行联系原作者

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

C#基础知识

1.c#概述,c#语言及其特点;c#与.net框架关系 C#概述:C#是微软公司发布的一种面向对象的、运行于.NET Framework之上的高级程序设计语言,C#是一种安全的、稳定的、简单的、优雅的,由C和C++衍生出来的面向对象的编程语言 特点:1.简单 2.现代 3.面向对象 4.类型安全 5.相互兼容性 6.可伸缩性和可升级性 关系:.NET框架是由微软开发的,致力于敏捷软件开发、快速应用开发、平台无关性和网络透明化的软件开发平台。 C#只是用于编写运行在该平台上的一种语言。 2.编写第一个c#程序(注释,命名空间,类,Main方法,标识符,关键字,输入,输出语句,) [csharp] view plain copy using System; namespace ConsoleApp2 { class Program { static void Main(string[] args) { //输出 Hello word Console.WriteLine("Hello word"); //输入 Console.ReadLine(); } } } 3.变量与常量(值类型,引用类型,两者区别,枚举类型,类型转换,变量声明,变量作用域,变量赋值,常量) 值类型 引用类型 1、值类型的数据存储在内存的栈中;引用类型的数据存储在内存的堆中 2、值类型表示实际数据,引用类型表示指向存储在内存堆中的数据的指针或引用 枚举: 枚举使用enum关键字来声明,与类同级。 枚举是值类型,隐式继承自System.Enum,不能手动修改。System.Enum本身是引用类型,继承自System.ValueType。 枚举都是隐式密封的,不允许作为基类派生子类。 枚举类型的枚举成员均为静态,且默认为Int32类型。 每个枚举成员均具有相关联的常数值。 枚举成员不能相同,但枚举的值可以相同。 枚举最后一个成员的逗号和大括号后面的分号可以省略 类型转换: 1.(int)变量名[强制类型转换] 2.int.Parse(string 变量名) 3.int.TryParse(string s, out int result) Convert.ToInt32 变量赋值: 值类型变量的赋值:值类型变量中保存的是实际数据,在赋值的时候只是把数据复制一份,然后赋给另一个变量。 引用类型变量的赋值: 引用类型变量中保存的是“指向实际数据的引用指针”。在进行赋值操作的时候,它和值类型一样,也是先有一个复制的操作,不过它复制的不是实际的数据,而是引用(真实数据的内存地址)。所以引用类型的变量在赋值的时候,赋给另一变量的实际上是内存地址。这样赋值完成后,2个引用变量中保存的是同一引用,他们的指向完全一样。 变量声明: 数据类型 变量名=值; 常量: C#常量主要分为两种:编译时和运行时常量 1、编译时常量,在编译时便用该常量的值代替常量变量。 2、运行时常量,在运行时返回一个运行时常量的变量引用 4.表达式与运算符(表达式概念,运算符种类,运算符优先级) 表达式概念:变量常量运算符组成 1.带( )号,[ ]号, . 号的,new,typeof,sizeof,checked,x++,x--级别最高,先计算. 2.++x,--x,+,! 3.算术运算符,先,/,%,再+,- 4.关系运算符,先>,<,>=,<=,is ,as再==和!= 5.条件逻辑运算符&&和|| 6.条件运算符b?x:y 7,赋值运算符=,=,/=,+=,-= 5.字符与字符串(Char类,Char类的使用,String的基本使用,StringBulider的使用) 字符串是由多个字符组成,字符串是引用类型 字符:Char类在C#中表示一个Unicode字符。 3)ToUpper(转换为大写)和ToLower(转换为小写) string s="RaSer"; string s1=s.ToUpper();//s1="RASER"; string s2=s.ToLower();//s2="raser"; Trim() 出去两边的空格 string str=" dd "; string s=str.Trim();//s="dd"; Substring 截取字符<str>以index开始截取,并截取lenth个字符(string <str>.Substring(index,lenth)) string str="还在下雨"; string s=str.Substring(2,2);//s="下雨"; Remove删除字符串(字符) 在字符串中移除从startIndex开始,长度为length的字符串,剩下的字符合为一个新的字符串 、Insert 插入 在字符串的index位置上插入字符,原来的字符依次后移,变成一个新的字符串 string str="夜深了"; string s=str.Insert(1,"已经");// s="夜已经深了" Replace 字符串(字符也是可以的)替换,返回新的字符串 string str="好困呀"; string s=str.Replace("困","精神");//s="好精神呀"; 、Equals 比较两个字符串是否相等 6.流程控制语句(选择包括switch,迭代语句即循环(搞明白为什么可以循环),跳转(break,continue,goto,return)) [csharp] view plain copy int a=6; switch(a) { case:"4" console.writeline("4"); break; case:"5" console.writeline("5"); break; default console.writeline("666"); break; } break从循环体跳出 continue结束本次循环 goto无条件转移语句 return 跳出循环的同时也做函数返回 7.数组和集合(一维数组和二维数组的声明以及使用,ArrayList类,HashTable,List,Directory字典等常用集合(泛型和非泛型)) [csharp] view plain copy string[] names = new string[5];//动态初始化 string[] names1 = new string[3] { "张三", "李四", "王二" };//定义并且赋予初值 动态初始化 int[] array = { 1, 2, 3, 4, 5 };//静态初始化变量,系统会自动分配内存空间 int[,] array = new int[2, 3];//声明一个两行3列的数组 声明并且进行初始化 [csharp] view plain copy int[,] array = new int[2, 3] { { 1, 2, 3 }, { 1, 3, 4 } }; ArrayList类是一个特殊的数组。通过添加和删除元素,就可以动态改变数组的长度。 Dictionary表示键和值的集合。 8.属性和方法(属性和方法的概念以及使用,注意,新特性中的自动属性,方法的重载) 1、类的属性:对象所拥有的特征,在类中表示时称为类的属性。 2、类的方法:对象执行的操作称为类的方法。 重载: 方法名相同。 方法的参数类型、个数、顺序至少有一项不相同。 方法的返回类型可以不相同,但只有返回类型不同是不可以的。 方法的修饰符可以不相同,但只有修饰符不同是不可以的 9.结构和类(结构的概念,类的概念,声明,构造函数,对象的实例化,类和对象的关系,实例的和静态的) 10.密封类和密封方法 密封类使用sealed关键字进行修饰,它不能用作其他类的基类,并且他没有派生类,密封类的作用是防止其他类继承该类,密封方法是使用sealed关键字进行修饰的方法,他并不能影响类的继承,但它可以防止重写基类中特定的虚方法。 [csharp] view plain copy public sealed class SealClass { } public sealed override void MyMethod() { Console.WriteLine("这是一个密封方法!"); } 本文转自 宁金峰 51CTO博客,原文链接:http://blog.51cto.com/13243523/2047608,如需转载请自行联系原作者

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

Activity的基础知识

前言 长风破浪会有时,直挂云帆济沧海。 关于Activity的启动和关闭 一个Android应用程序通常都包含多个Activity,但只有一个Activity会作为程序的入口——当该Android应用运行时将会自动启动并执行该Activity。至于应用中的其他Activity,通常都由入口Activity启动,或由入口Activity启动的Activity启动。 Activity启动其他Activity有如下两个方法。 startActivity(Intent intent):启动其他Activity。 startActivityForResult(Intent intent,int requestCode):以指定的请求码(requestCode)启动Activity,而且程序将会获取新启动的Activity返回的结果(通过重写OnActivityResult(...)方法)。 上面两个方法都用到了Intent参数,Intent是Android应用里各组件之间同通信的重要方式,一个Activity通过Intent来表达自己“意图”——想要启动哪个组件,被启动的组件既可是Activity组件,也可是Service组件。 Android为关闭Activity准备了如下两个方法。 finish():结束当前Activity。 finishActivity(int requestCode):结束以startActivityForResult(Intent intent,int requestCode)方法启动的Activity。 代码示例 FirstActivity.java public class FirstActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.first_layout); Button bt = (Button) findViewById(R.id.bt); bt.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { //创建需要启动的Activity对应的Intent Intent intent = new Intent(FirstActivity.this,SecondActivity.class); //启动intent对应的Activity startActivity(intent); } }); } } SecondActivity.java public class SecondActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.seconde_layout); Button back = (Button) findViewById(R.id.back); Button back_finish = (Button) findViewById(R.id.back_finish); back.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { //创建需要启动的Activity对应的Intent Intent intent = new Intent(SecondActivity.this,FirstActivity.class); //启动intent对应的Activity startActivity(intent); } }); back_finish.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { //创建需要启动的Activity对应的Intent Intent intent = new Intent(SecondActivity.this,FirstActivity.class); //启动intent对应的Activity startActivity(intent); //结束当前Activity finish(); } }); } } 提示 上述程序的布局文件就只包含简单的按钮来实现跳转,第二个Activity唯一的区别就是finish()方法,它表明该Activity会结束自己。 使用Bundle在Activity之间交换数据 当一个Activity启动另一个Activity时,常常会有一些数据需要传过去。这时Intent就相当于一个“信使”,我们将需要传送的数据存入Intent中即可。、 Intent提供了多个方法来“携带”额外的数据,如下所示。 putExtras(Bundle data):向Intent中放入需要“携带”的数据包。 Bundle getExtras():取出Intent中所“携带”的数据包。 putExtra(String name,Xxx value):向Intent中按key-value对的形式存入数据。 getXxxExtra(String name):从Intent中按key取出指定类型的数据。 上述方法中的Bundle就是一个简单的数据携带包,该Bundle对象包含了多个方法来存入数据。 putXxx(String key, Xxx value):向Bundle中放入Int、Long等各种类型的数据。 putSerializable(String key, Serializable data):向Bundle中放入一个可序列化的对象。 getXxx(String key):从Bundle中取出Int、Long等各种类型的数据。 getSerializable(String key):从Bundle中取出一个可序列化的对象。 下面我通过一个实例来介绍Activity之间如何通过Bundle交换数据。 本程序包含两个Activity,其中第一个Activity用于收集用户的输入信息,当用户单击该Activity的“注册”按钮时,应用进入第二个Activity,第二个Activity将会获取第一个Activity中的数据。 代码示例 FirstActivity.java public class FirstActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.first_layout); Button bn = (Button) findViewById(R.id.bn); bn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { EditText name = (EditText) findViewById(R.id.name); EditText passwd = (EditText) findViewById(R.id.passwd); RadioButton male = (RadioButton) findViewById(R.id.male); String gender = male.isChecked() ? "男" : "女"; Person p = new Person(); p.setName(name.getText().toString()); p.setPasswd(passwd.getText().toString()); p.setGender(gender); //创建一个Bundle对象 Bundle data = new Bundle(); data.putSerializable("person", p); //创建一个Intent Intent intent = new Intent(FirstActivity.this,SecondActivity.class); intent.putExtras(data); //启动intent对应的Activity startActivity(intent); } }); } } first_layout.xml <?xml version="1.0" encoding="utf-8"?> <TableLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="请输入您的注册信息" android:textSize="20sp" /> <TableRow> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="用户名:" android:textSize="16sp" /> <EditText android:id="@+id/name" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="请填写想注册的账号" android:selectAllOnFocus="true" /> </TableRow> <TableRow> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="密码:" android:textSize="16sp" /> <EditText android:id="@+id/passwd" android:layout_width="match_parent" android:layout_height="wrap_content" android:password="true" android:selectAllOnFocus="true" /> </TableRow> <TableRow> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="性别:" android:textSize="16sp" /> <RadioGroup android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <RadioButton android:id="@+id/male" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="男" android:textSize="16sp" /> <RadioButton android:id="@+id/female" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="女" android:textSize="16sp" /> </RadioGroup> </TableRow> <Button android:id="@+id/bn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="注册" android:textSize="16sp" /> </TableLayout> SecondActivity.java public class SecondActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.seconde_layout); TextView name = (TextView) findViewById(R.id.name); TextView passwd = (TextView) findViewById(R.id.passwd); TextView gender = (TextView) findViewById(R.id.gender); //获取启动该Activity的Intent Intent intent = getIntent(); //直接通过Intent取出它所携带的Bundle数据包中的数据 Person p = (Person) intent.getSerializableExtra("person"); name.setText("您的用户名为:" + p.getName()); passwd.setText("您的密码为:" + p.getPasswd()); gender.setText("您的性别为:" + p.getGender()); } } seconde_layout.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:gravity="center_horizontal" > <TextView android:id="@+id/name" android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="18sp" /> <TextView android:id="@+id/passwd" android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="18sp" /> <TextView android:id="@+id/gender" android:layout_width="match_parent" android:layout_height="wrap_content" android:textSize="18sp" /> </LinearLayout> 效果 [图片上传失败...(image-e4b6ea-1514096470518)] [图片上传失败...(image-2ca6b1-1514096470519)] 提示 需要传送数据如果是对象,这个对象应该实现Serializable接口。 启动其他Activity并返回结果 前面已经提到,Activity还提供了一个startActivityForResult(Intent intent,int requestCode)方法来启动其他Activity。该方法用于启动指定Activity,而且期望获取指定Activity返回的结果。这种情况很常见,例如应用程序第一个界面需要用户进行选择,但需要选择的列表数据比较复杂,必须启动另一个Activity让用户选择。当用户在第二个Activity中选择完成后,程序返回第一个Actvity,第一个Activity必须能获取并显示用户在第二个Activity中选择的结果。在这种应用场景下,也通过Bundle进行数据交换的。 为了获取被启动的Activity所返回的结果,需要从两方面着手。 当前Activity需要重写onActivityResult(int requestCode,int resultCode,Intent intent),当被启动的Activity返回结果时,该方法会被触发,其中requestCode代表请求码,而resultCode代表Activtiy返回的结果码,由开发者自行设定。 被启动的Activtiy需要调用setResult()方法设置处理结果。 一个Activity中可能包含多个按钮,并调用多个startActivityForResult()方法来打开多个不同的Activity处理不同的业务,当这些新Activity关闭后,系统将回调前面Activity的onActivityResult(int requestCode,int resultCode,Intent data)方法。为了知道该方法是由哪个请求的结果所触发的,可利用requestCode请求码;为了知道返回的数据来自于哪个新的Activity,可利用resultCode结果码。 代码示例 FirstActivity.java public class FirstActivity extends Activity { Button bt; EditText city; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.first_layout); bt = (Button) findViewById(R.id.bt); city = (EditText) findViewById(R.id.city); bt.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { //创建需要对应于目标Activity的Intent Intent intent = new Intent(FirstActivity.this, SelectCityActivity.class); //启动指定Activity并等待返回的结果,其中0是请求码,用于标识该请求 startActivityForResult(intent, 0); } }); } //重写该方法,该方法以回调的方式来获取指定Activity返回的结果 @Override protected void onActivityResult(int requestCode, int resultCode, Intent intent) { //当requestCode、resultCode同时为0时,也就是处理特定的结果 if(requestCode == 0 && resultCode == 0) { //取出Intent里德Extras数据 Bundle data = intent.getExtras(); //取出Bundle中的数据 String resultCity = data.getString("city"); //修改city文本框的内容 city.setText(resultCity); } } } SelectCityActivity.java public class SelectCityActivity extends ExpandableListActivity { //定义省份数组 private String[] provinces = new String[] {"广西","广东","湖南","云南"}; private String[][] cities = new String[][] { {"桂林","柳州","南宁","北海"}, {"广州","深圳","珠海","中山"}, {"长沙","岳阳","衡阳","株洲"}, {"昆明","玉溪","大理","丽江"} }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ExpandableListAdapter adapter = new BaseExpandableListAdapter() { @Override public boolean isChildSelectable(int groupPosition, int childPosition) { return true; } @Override public boolean hasStableIds() { return true; } private TextView getTextView() { AbsListView.LayoutParams lp = new AbsListView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 64); TextView textView = new TextView(SelectCityActivity.this); textView.setLayoutParams(lp); textView.setGravity(Gravity.CENTER_VERTICAL|Gravity.LEFT); textView.setPadding(36, 0, 0, 0); textView.setTextSize(20); return textView; } @Override public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) { LinearLayout ll = new LinearLayout(SelectCityActivity.this); ll.setOrientation(LinearLayout.HORIZONTAL); ImageView logo = new ImageView(SelectCityActivity.this); logo.setImageResource(R.drawable.ic_launcher); ll.addView(logo); TextView textView = getTextView(); textView.setText(getGroup(groupPosition).toString()); ll.addView(textView); return ll; } @Override public long getGroupId(int groupPosition) { return groupPosition; } @Override public int getGroupCount() { return provinces.length; } @Override public Object getGroup(int groupPosition) { return provinces[groupPosition]; } @Override public int getChildrenCount(int groupPosition) { return cities[groupPosition].length; } @Override public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) { TextView textView = getTextView(); textView.setText(getChild(groupPosition, childPosition).toString()); return textView; } @Override public long getChildId(int groupPosition, int childPosition) { // TODO Auto-generated method stub return childPosition; } @Override public Object getChild(int groupPosition, int childPosition) { // TODO Auto-generated method stub return cities[groupPosition][childPosition]; } }; setListAdapter(adapter); //为列表项设置监听 getExpandableListView().setOnChildClickListener(new OnChildClickListener() { @Override public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) { //获取启动该Activity之前的Activity对应的Intent Intent intent = getIntent(); intent.putExtra("city", cities[groupPosition][childPosition]); //设置该SelectCityActivity的结果码,并设置结束之后退回的Activity SelectCityActivity.this.setResult(0, intent); //结束SelectCityActivity SelectCityActivity.this.finish(); return false; } }); } } 效果 Screenshot_20171101-145622.png Screenshot_20171101-145711.png Screenshot_20171101-145743.png 提示 别忘记每创建一个新的Activity,都要去清单文件里注册这个Activity。

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

Docker基础知识(一)

Docker简介: Docker 是一个开源的应用容器引擎,以轻松的为任何应用创建一个轻量级的、可移植的、自给自足的容器。开发者在笔记本上编译测试通过的容器可以批量地在生产环境中部署,包括VMs(虚拟机)、bare metal、OpenStack 集群和其他的基础应用平台。 Docker与传统的虚拟化技术 传统虚拟化技术(VMware、Xen、Kvm)等技术 纯软件的虚拟化是通过对于硬件层的模拟从而实现允许运行多个操作系统; 硬件辅助虚拟化需要硬件层面对于虚拟化的支持,类似Inter-VT等,具有更高的运行效率。 传统虚拟化技术商业解决方案 商业解决方案:VMware VSphere VMvare Fusion 开源解决方案:OpenStack KVM 容器技术: LXC: OpenVZ: Docker: ImctfyGoogle的开源技术 Docker存在的一些问题 Docker是基于Linux 64bit的,无法在32bit的linux/Windows/unix环境下使用 LXC是基于cgroup等linux kernel功能的,因此container的guest系统只能是linux base的 隔离性相比KVM之类的虚拟化方案还是有些欠缺,所有container公用一部分的运行库 网络管理相对简单,主要是基于namespace隔离 cgroup的cpu和cpuset提供的cpu功能相比KVM的等虚拟化方案相比难以度量(所以dotcloud主要是按内存收费) docker对disk的管理比较有限 container随着用户进程的停止而销毁,container中的log等用户数据不便收集 传统的虚拟化技术和docker的比较 Docker的应用场景: 1、 部署应用简单,灵活性高 主要解决环境不一致等问题,还有多套环境部署,生产环境、测试环境、预测试环境等多套环境等问题。 2、 开发人员开发环境配置 3、 应用的隔离 4、 服务器的整合 5、 快速的部署 6、 代码流水线的管理 将测试好的代码,放置在容器里面,可以在很多地方的运行 7、 开发调试工作 8、 产品的发布模式 部署文档比较多,即使很详细,但是还是会出现问题。 本文转自 tianya1993 51CTO博客,原文链接:http://blog.51cto.com/dreamlinux/1837882,如需转载请自行联系原作者

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

云计算基础知识

1云计算分层 1.1IaaS(Infrastructureass Service) Iaas表示基础设施即服务,是云服务里最重要的也是最基础的一块,经常提到的云计算,云存储等等,都属于这个领域。 1.2PaaS(Platform asa Service) PaaS表示平台即服务,它可以提供软件开发(包括APP)所需的基础功能模块。例如提供一些开发的环境及工具。 1.3SaaS(Software asaService) SaaS表示软件即服务,主要给用户提供一些云应用,例如云CRM、云笔记、OA、ERP软件应用等等。 2常见虚拟化技术 虚拟化技术(如VMware、XenServer、Hyper-V、KVM、XEN等) 3常见云管理平台 比较经典的开源云平台有OpenStack、CloudStack、Hadoop、Apache Mesos、基于Docker的kubernetes、swarm等,商业云平台有VMware vCloud、微软、Redhat、HP、IBM以及Citrix的企业云解决方案 OpenStack、CloudStack都可以让用户快速和方便地在现有的架构上建立自己的云服务。OpenStack、CloudStack可以帮助用户更好地协调服务器、存储、网络资源,从而构建一个IaaS平台。 4NSP网络管理系统 NSP包含三大功能:首先是网络虚拟化,负责网络的部署和管理;其次是网络功能虚拟化,主要提供2-7层的网络服务;然后是网络运维,提供网络流量检测和分析,保证网络故障的快速定位和修复。 本文转自 老鹰a 51CTO博客,原文链接:http://blog.51cto.com/laoyinga/1962910

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

zabbix监控基础知识

Zabbix 一、Zabbix是什么? Zabbix是一个高度集成的网络监控套件;它能监视各种网络参数,保证服务器系统的安全运营;并提供灵活的通知机制以让系统管理员快速定位/解决存在的各种问题。是一个基于WEB界面的提供分布式系统监视以及网络监视功能的企业级的开源解决方案。 二Zabbix的特性: 数据收集、历史数据存储、实时绘图 配置简单、灵活的阀值定义、高级告警配置 三、Zabbix工作原理 一个监控系统运行的大概的流程是这样的: zabbix agent需要安装到被监控的主机上,它负责定期收集各项数据,并发送到zabbix server端,zabbix server将数据存储到数据库中,zabbix web根据数据在前端进行展现和绘图。这里agent收集数据分为主动和被动两种模式: 主动:agent请求server获取主动的监控项列表,并主动将监控项内需要检测的数据提交给server/proxy 被动:server向agent请求获取监控项的数据,agent返回数据。 四、Zabbix的重要组件以及进程 zabbix由以下几个组件部分构成: 1、Zabbix Server:负责接收agent发送的报告信息的核心组件,所有配置,统计数据及操作数据均由其组织进行; 2、Database Storage:专用于存储所有配置信息,以及由zabbix收集的数据; 3、Web interface:zabbix的GUI接口,通常与Server运行在同一台主机上; 4、Proxy:可选组件,常用于分布监控环境中,代理Server收集部分被监控端的监控数据并统一发往Server端; 5、Agent:部署在被监控主机上,负责收集本地数据并发往Server端或Proxy端; 注:zabbix node也是 zabbix server的一种 。 zabbix进程介绍:(默认情况下zabbix包含5个程序) 1、zabbix_agent:客户端守护进程,此进程收集客户端数据,例如cpu负载、内存、硬盘使用情况等 2、zabbix_get:zabbix工具,单独使用的命令,通常在server或者proxy端执行获取远程客户端信息的命令。通常用户排错。例如在server端获取不到客户端的内存数据,我们可以使用zabbix_get获取客户端的内容的方式来做故障排查。 3、zabbix_sender:zabbix工具,用于发送数据给server或者proxy,通常用于耗时比较长的检查。很多检查非常耗时间,导致zabbix超时。于是我们在脚本执行完毕之后,使用sender主动提交数据。 4、zabbix_server:zabbix服务端守护进程。zabbix_agentd、zabbix_get、zabbix_sender、zabbix_proxy、zabbix_java_gateway的数据最终都是提交到server 备注:当然不是数据都是主动提交给zabbix_server,也有的是server主动去取数据。 5、zabbix_proxy:zabbix代理守护进程。功能类似server,唯一不同的是它只是一个中转站,它需要把收集到的数据提交/被提交到server里。为什么要用代理?代理是做什么的? 6、zabbix_java_gateway是可选的,这个需要另外安装 这个进程是zabbix2.0之后引入的一个功能。顾名思义:Java网关,类似agentd,但是只用于Java方面。需要特别注意的是,它只能主动去获取数据,而不能被动获取数据。它的数据最终会给到server或者proxy。 五、zabbix监控环境中基本概念 1、主机(host):要监控的网络设备,可由IP或DNS名称指定; 2、主机组(host group):主机的逻辑容器,可以包含主机和模板,但同一个组织内的主机和模板不能互相链接;主机组通常在给用户或用户组指派监控权限时使用; 3、监控项(item):一个特定监控指标的相关的数据;这些数据来自于被监控对象;item是zabbix进行数据收集的核心,相对某个监控对象,每个item都由"key"标识; 4、触发器(trigger):一个表达式,用于评估某监控对象的特定item内接收到的数据是否在合理范围内,也就是阈值;接收的数据量大于阈值时,触发器状态将从"OK"转变为"Problem",当数据再次恢复到合理范围,又转变为"OK"; 5、事件(event):触发一个值得关注的事情,比如触发器状态转变,新的agent或重新上线的agent的自动注册等; 6、动作(action):指对于特定事件事先定义的处理方法,如发送通知,何时执行操作; 7、报警升级(escalation):发送警报或者执行远程命令的自定义方案,如每隔5分钟发送一次警报,共发送5次等; 8、媒介(media):发送通知的手段或者通道,如Email、Jabber或者SMS等; 9、通知(notification):通过选定的媒介向用户发送的有关某事件的信息; 10、远程命令(remote command):预定义的命令,可在被监控主机处于某特定条件下时自动执行; 11、模板(template):用于快速定义被监控主机的预设条目集合,通常包含了item、trigger、graph、screen、application以及low-level discovery rule;模板可以直接链接至某个主机; 12、应用(application):一组item的集合; 13、web场景(web scennario):用于检测web站点可用性的一个活多个HTTP请求; 14、前端(frontend):Zabbix的web接口; 六、Zabbix的监控架构 在实际监控架构中,zabbix根据网络环境、监控规模等 分了三种架构: 1、server-client架构 是zabbix的最简单的架构,监控机和被监控机之间不经过任何代理 ,直接由zabbix server和zabbix agentd之间进行数据交互。适用于网络比较简单,设备比较少的监控环境。 2、server-proxy-client架构 其中proxy是server、client之间沟通的一个桥梁,proxy本身没有前端,而且其本身并不存放数据,只是将agentd发来的数据暂时存放,而后再提交给server 。该架构经常是和master-node-client架构做比较的架构 ,一般适用于跨机房、跨网络的中型网络架构的监控。 3、master-node-client架构 该架构是zabbix最复杂的监控架构,适用于跨网络、跨机房、设备较多的大型环境 。每个node同时也是一个server端,node下面可以接proxy,也可以直接接client 。node有自已的配置文件和数据库,其要做的是将配置信息和监控数据向master同步,master的故障或损坏对node其下架构的完整性。 本文转自西鼠 51CTO博客,原文链接:http://blog.51cto.com/10630401/1976053,如需转载请自行联系原作者

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

iOS:XMPP即时聊天知识

XMPP即时聊天框架:XMPPFramework XMPP The Extensible Messaging and Presence Protocol(可扩展通讯和表示协议)。 基于XML XMPP是一个典型的C/S架构,而不是像大多数即时通讯软件一样,使用P2P客户端到客户端的架构 服务器:OpenFire 测试客户端:spark iOS开发框架:XMPPFramework XMPP的地址叫做JabberID(简写为JID),它用来标示XMPP网络中的各个XMPP实体。 JID由三部分组成:domain,node identifier和resource。JID中domain是必不可少的部分。注意:domain和user部分是不分大小写的,但是resource区分大小写。 jid= [ node "@" ] domain [ "/" resource ] domain:通常指网络中的网关或者服务器。 node identifier:通常表示一个向服务器或网关请求和使用网络服务的实体(比如一个客户端),当然它也能够表示其他的实体(比如在多用户聊天系统中的一个房间)。 resource:通常表示一个特定的会话(与某个设备),连接(与某个地址),或者一个附属于某个节点ID实体相关实体的对象(比如多用户聊天室中的一个参加者)。 JID种类有: bare JID:user@domain.tld full JID:user@domain.tld/resource XMPP通信原语有3种:message、presence和iq。 message是一种基本推送消息方法,它不要求响应。主要用于IM、groupChat、alert和notification之类的应用中 presence用来表明用户的状态 (Info / Query)一种请求/响应机制,从一个实体从发送请求,另外一个实体接受请求,并进行响应 共同属性: to属性:标识消息的接收方。 from属性:指发送方的名字或标示 type属性 实现功能: 登录、注册 个人状态通知 联系人列表(花名册) 添加、删除好友 收发消息 消息存储 修改个人资料 程序猿神奇的手,每时每刻,这双手都在改变着世界的交互方式! 本文转自当天真遇到现实博客园博客,原文链接:http://www.cnblogs.com/XYQ-208910/p/5007873.html ,如需转载请自行联系原作者

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

苹果开发基础知识

App ID(应用ID) App ID是识别不同应用程序的唯一标示符。每个app都需要一个App ID或者app标识。 目前有两种类型的App标识:一个是精确的App ID(explicit App ID),一个是通配符App ID(wildcard App ID)。 使用通配符的App ID可以用来构建和安装多个程序。尽管通配符App ID非常方便,但是一个精确的App ID也是需要的, 尤其是当App使用iCloud 或者使用其他iOS功能的时候,比如Game Center、Push Notifications或者IAP。 如果你不确定什么样的App ID适合你的项目,我推荐你读下苹果关于这一主题的文档:Technical Note QA1713。 Distribution Certificate(发布证书) iOS应用都有一个安全证书用于验证开发者身份和签名。为了可以向App Store提交app,你需要创建一个iOS provisioning profile 。 首先需要创建一个distribution certificate(发布证书),过程类似于创建一个development certificate(开发证书)。 如果你已经在实体设备上测试你的App,那么你对创建development certificate就已经很熟悉了。 如果对此不熟悉,我建议你读下苹果关于signing certificates和provisioning profiles的详细指导。 Provisioning Profile(配置文件) 一旦你创建了App ID和distribution certificate,你可以创建一个iOS provisioning profile以方便在App Store中销售你的App。 不过,你不能使用和ad hoc distribution相同的provisioning profile。 你需要为App Store分销创建一个单独的provisioning profile,如果你使用通配符App ID,那么你的多个app就可以使用相同的provisioning profile。 Build Settings(生成设置) 配置App ID、distribution certificate 和provisioning profile已经完成,是时候配置Xcode中target的build settings了。 在Xcode Project Navigator的targets列表中选择一个target,打开顶部的Build Settings选项,然后更新一下Code Signing来跟之前创建的distribution provisioning profile相匹配。 最近添加的provisioning profiles有时候不会立马就在build settings的Code Signing中看到,重启一下Xcode就可以解决这个问题。 Deployment Target(部署目标) 非常有必要说下deployment target,Xcode中每个target都有一个deployment target,它可以指出app可以运行的最小版本。 不过,一旦应用在App Store中生效,再去修改deployment target,你要考虑到一定后果。 如果你在更新app的时候提高了deployment target,但是已经购买应用的用户并没有遇到新的deployment target,那么应用就不能在用户的移动设备上运行。 如果用户通过iTunes (不是设备)下载了一个更新过的app,然后替代了设备上原先的版本,最后却发现新版本不能在设备上运行,这确实是个问题。 证书主要分为两类 Development和Production, Development证书用来开发和调试应用程序, Production主要用来分发应用程序(根据证书种类有不同作用),下面是证书的分类信息:(括号内为证书有效期) Development App Development (1年):用来开发和真机调试应用程序。 Push Development (1年):用来调试Apple Push Notification Production In-House and Ad Hoc (3年):用来发布In-House和AdHoc的应用程序。 App Store :用来发布提交App Store的应用程序。 MDM CSR Push Production (1年):用来在发布版本中使用Apple Push Notification。 Pass Type ID Certificate:用于通行证类证书 Website Push ID Certificate 有一些类型的证书我没有使用过,所以也不了解具体的作用。 证书 1)Developer Certification(开发证书) 2)Distribution Certification(发布证书) 授权文件 1)Developer Provisioning Profile(开发授权文件) 2)Distribution Provisioning Profile(发布授权文件)

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

swift基础知识二

//1.if语句以及强制解析 //可以使用if语句和nil比较来判断一个可选值是否包含值,可以使用“==”,'!= ' 来执行比较 //如果可选类型有值,它将不等于nil var num:Int? = 3 if num != nil { print("值不为空") } //感叹号 ! //当你判断一个可选类型确实包含值之后,你可以在可选的名字后面加上感叹号(!)来获取值,这个感叹号表示“我知道这个可选类型有值,请使用它”。这个被称为可选值的强制解析。 //注意:使用!来获取一个不存在的可选值会导致运行时错误。使用!来强制解析值之前,一定要确定可选包含一个非nil的值。 //2.可选绑定 //使用可选绑定来判断可选类型是否包含值,如果包含,就把值赋值给一个临时常量或者变量。可选绑定可以用在if和while语句中,这条语句不仅可以用来判断可选类型是否有值,同时把可选类型的值赋给常量或者变量。 let empty:String? = nil if let constName = num { print(constName) } if let em = empty { print("aaaaaa") }else{ print("判断为假") } if let firstNumber = Int("4"), let secondNumber = Int("42"), firstNumber < secondNumber && secondNumber < 100 { print("\(firstNumber) < \(secondNumber) < 100") } // 输出 "4 < 42 < 100" if let firstNumber = Int("4") { if let secondNumber = Int("42") { if firstNumber < secondNumber && secondNumber < 100 { print("\(firstNumber) < \(secondNumber) < 100") } } } // 输出 "4 < 42 < 100" //注意:在if条件语句中使用常量和变量来创建一个可选绑定,仅在if语句的句中(body)中才可以获取可选绑定的值。 //相反,在guard语句中使用常量和变量来创建一个可选绑定,仅在guard语句外且在语句后才能获取到值。 //3.隐式解析可选类型 /* 如上所述,可选类型暗示了常量或者变量可以“没有值”。可选可以通过 if 语句来判断是否有值,如果有值的话可以通过可选绑定来解析值。 有时候在程序架构中,第一次被赋值之后,可以确定一个可选类型总会有值。在这种情况下,每次都要判断和解析可选值是非常低效的,因为可以确定它总会有值。 这种类型的可选状态被定义为隐式解析可选类型(implicitly unwrapped optionals)。把想要用作可选的类型的后面的问号(String?)改成感叹号(String!)来声明一个隐式解析可选类型。 当可选类型被第一次赋值之后就可以确定之后一直有值的时候,隐式解析可选类型非常有用。隐式解析可选类型主要被用在 Swift 中类的构造过程中 */ let possibleString :String? = "An optional string" let forcedString :String = possibleString! //需要感叹号来获取值,没有感叹号会报错 let assumeString :String! = "一个隐式解析可选值" let implicitString :String = assumeString //不需要感叹号 //你可以把隐式解析可选类型当做一个可以自动解析的可选类型。你要做的只是声明的时候把感叹号放到类型的结尾,而不是每次取值的可选名字的结尾。 //注意: //如果你在隐式解析可选类型没有值的时候尝试取值,会触发运行时错误。和你在没有值的普通可选类型后面加一个惊叹号一样。 //4.错误处理 //可以使用 错误处理来应对程序执行中可能遇到的错误条件。

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

swift基础知识一

import UIKit var str = "Hello, playground" //1.变量,常量 let max = 10 var current = 0 if current < max { print(current) } var x = 0,y = 0.0 //2.类型标注 var message:String message = "Hello" //常量和变量的命名可以使任何喜欢的字符,但是,不能包含数学符号,箭头,保留的(或者非法的)Unicode 码位,连线与制表符,也不能以数字开头 let pai = 3.14 let 你好 = "中国🇨🇳" let = "" let ww2 = "heihei" let bool = false //3.分号 //并不强求在每一行的末尾添加分号,也可以根据自己习惯添加,但是有一种情况必须添加,你打算在同一行添加多条独立语句的时候,必须用分号隔开 let first = 0; var second = "haahhaah";print(first,second) //4.整数:没有小数部分的数字,包括有符号整数(正,负,零)和无符号整数(正,零) //swift提供 8,16,32,64位有符号和无符号整数类型 //整数范围:可以访问不同类型整数的最大值和最小值 let minValue = UInt8.min let maxValue = UInt8.max //(2的8次方) let min16 = UInt16.min let max16 = UInt16.max //(2的16次方) //Int //一般情况下,不需要专门指定整数长度,Int的长度与当前平台的原生字长相同 let minInt = Int.min //(本机最小字长,64位) let maxInt = Int.max //数值型字面量 //十进制:没有前缀 //二进制:0b //八进制:0o //十六进制:0x //如果一个十进制数的指数为 exp,那这个数相当于基数和10^exp的乘积: print(1.25e2)//1.25*10^2 print(1.25e-2)//1.25*10^-2 //如果一个十六进制数的指数为exp,那这个数相当于基数和2^exp的乘积: print(0xFp2) //15*2^2 print(0xFp-2) //15*2^-2 相当于15*1/4 //整数类型转换,其他类型转换类似 let twoThousand:UInt16 = 2_000 let one:UInt8 = 1 let sum = twoThousand + UInt16(one) //5.类型别名,typealias //给现有类型起一个别的名字,当你想要给现有类型起一个更有意义的名字时,类型别名非常有用。 typealias AudioSample = UInt16 var maxAudioS = AudioSample.max //6.BOOL 布尔值 true false let yes = true let no = false //Bool类型和整型不可以转换,非零即真在swift中是不适用的 //7.元组 //元组把多个值组合成一个复合值,元组内的值可以使任意类型,并不要求是相同类型 let httpError = (404,"Not Found") //httpError的类型是(Int,String),值是(404,"Not Found") //可以将元组内容分解成单独的常量和变量,然后就可以使用它们了 let (statusCode,statusMessage) = httpError print("错误码:(statusCode),错误信息:(statusMessage)") //如果你只需要一部分的元组值,分解的时候可以把要忽略的部分用(_)标记 let (justCode,_) = httpError print("错误 \(justCode)") //可以通过下标访问元组中的元素,下标从0开始 print(httpError.0) print(httpError.1) //定义元组的时候给单个元素命名,命名后可以通过名字访问元组元素的值 let httpOK = (code:200,desc:"OK") print(httpOK.code) print(httpOK.desc) //作为函数返回值的时候,元组是非常有用的 //8.可选类型 optionals //使用可选类型来处理值可能缺失的情况,可选类型表示: //1》有值,等于x //2》没有值 //例如:String转Int,有可能成功,也有可能失败 let possibleNum = "123" let possibleStr = "Hello" let converNum = Int(possibleNum) let converStr = Int(possibleStr) print(possibleNum) print(possibleStr) var cc = converNum! + 1 //var dd = converStr! + 1 //报错 //上面的转换还可以这么写 let conver:Int? = Int(possibleNum) let conver2:Int? = Int(possibleStr) var ee = converNum! + 1 //var ff = converStr! + 1 报错 //你可以给一个可选变量赋值为nil表示它没有值 var serverResCode:Int? = 404 serverResCode = nil //现在serverResCode不包含值 //注意:nil不能用于非可选的变量或者常量 //如果你声明一个可选的常量或者变量但是没有赋值,它们会自动设置成nil var surverAnswer:String? //注意:Swift的nil和OC的nil的意义是不一样的,OC中的nil是指向不存在对象的指针。在Swift中,nil不是指针,它是一个确定的值,表示值缺失。任何类型的值缺失都可以被设置成nil,而不只是对象类型。

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

Android 应用基础知识

Android 应用采用 Java 编程语言编写,Android SDK 工具将代码连同任何数据和资源文件编译到一个 APK(Android 软件包)当中,即带有 .apk 后缀的存档文件中。一个 APK 文件包含 Android 应用的所有内容,它是基于 Android 系统的设备用来安装应用的文件 安装到设备后,每个 Android 应用都运行在自己的安全沙箱内: Android 操作系统是一种多用户 Linux 系统,其中的每个应用都是一个不同的用户 默认情况下,系统会为每个应用分配一个唯一的 Linux 用户 ID(该 ID 仅由系统使用,应用并不知晓)。系统为应用中的所有文件设置权限,使得只有分配给该应用的用户 ID 才能访问这些文件 每个进程都具有自己的虚拟机 (VM),因此应用代码是在与其他应用隔离的环境中运行 Android 系统可以通过这种方式实现最小权限原则。也就是说,默认情况下,每个应用都只能访问执行其工作所需的组件,而不能访问其他组件。 这样便营造出一个非常安全的环境,在这个环境中,应用无法访问系统中其未获得权限的部分 不过,应用仍然可以通过一些途径与其他应用共享数据以及访问系统服务: 可以安排两个应用共享同一 Linux 用户 ID,在这种情况下,它们能够相互访问彼此的文件。 为了节省系统资源,可以安排具有相同用户 ID 的应用在同一 Linux 进程中运行,并共享同一 VM(应用还必须使用相同的证书签署) 应用可以请求访问设备数据(如用户的联系人、短信、可装载存储装置 [SD 卡]、相机、蓝牙等)的权限。 用户必须明确授予这些权限 一、核心框架组件 应用组件是 Android 应用的基本构建基块。每个组件都是一个不同的点,系统可以通过它进入应用中。 并非所有组件都是用户的实际入口点,有些组件相互依赖,但每个组件都以独立实体形式存在,并发挥特定作用 — 每个组件都是唯一的构建基块,有助于定义应用的总体行为 共有四种不同的应用组件类型。每种类型都服务于不同的目的,并且具有定义组件的创建和销毁方式的不同生命周期 以下便是这四种应用组件类型: Activity Activity 表示具有用户界面的单一屏幕。例如,电子邮件应用可能具有一个显示新电子邮件列表的 Activity、一个用于撰写电子邮件的 Activity 以及一个用于阅读电子邮件的 Activity。 尽管这些 Activity 通过协作在电子邮件应用中形成了一种紧密结合的用户体验,但每一个 Activity 都独立于其他 Activity 而存在。 因此,其他应用可以启动其中任何一个 Activity(如果电子邮件应用允许)。 例如,相机应用可以启动电子邮件应用内用于撰写新电子邮件的 Activity,以便用户共享图片 服务 服务是一种在后台运行的组件,用于执行长时间运行的操作或为远程进程执行作业。 服务不提供用户界面。 例如,当用户位于其他应用中时,服务可能在后台播放音乐或者通过网络获取数据,但不会阻断用户与 Activity 的交互。 诸如 Activity 等其他组件可以启动服务,让其运行或与其绑定以便与其进行交互 内容提供者 内容提供程序管理一组共享的应用数据,可以将数据存储在文件系统、SQLite 数据库、网络上或应用可以访问的任何其他永久性存储位置。 其他应用可以通过内容提供程序查询数据,甚至修改数据(如果内容提供程序允许)。 例如,Android 系统可提供管理用户联系人信息的内容提供程序。 因此,任何具有适当权限的应用都可以查询内容提供程序的某一部分(如 ContactsContract.Data),以读取和写入有关特定人员的信息 内容提供程序也适用于读取和写入您的应用不共享的私有数据。 例如,记事本示例应用使用内容提供程序来保存笔记 广播接收器 广播接收器是一种用于响应系统范围广播通知的组件。 许多广播都是由系统发起的 。例如,通知屏幕已关闭、电池电量不足或已拍摄照片的广播。应用也可以发起广播 ,例如,通知其他应用某些数据已下载至设备,并且可供其使用。 尽管广播接收器不会显示用户界面,但它们可以创建状态栏通知,在发生广播事件时提醒用户。 但广播接收器更常见的用途只是作为通向其他组件的“通道”,设计用于执行极少量的工作。 例如,它可能会基于事件发起一项服务来执行某项工作 Android 系统设计的独特之处在于,任何应用都可以启动其他应用的组件。 例如,如果想让用户使用设备的相机拍摄照片,很可能有另一个应用可以执行该操作,那么你的应用就可以利用该应用,而不是开发一个 Activity 来自行拍摄照片。 不需要集成甚至链接到该相机应用的代码,而是只需启动拍摄照片的相机应用中的 Activity。 完成拍摄时,系统甚至会将照片返回您的应用,以便应用使用。对用户而言,就好像相机真正是应用的组成部分。 当系统启动某个组件时,会启动该应用的进程(如果尚未运行),并实例化该组件所需的类。 例如,如果你的应用启动相机应用中拍摄照片的 Activity,则该 Activity 会在属于相机应用的进程,而不是你的应用的进程中运行。因此,与大多数其他系统上的应用不同,Android 应用并没有单一入口点(例如,没有 main() 函数) 由于系统在单独的进程中运行每个应用,且其文件权限会限制对其他应用的访问,因此你的应用无法直接启动其他应用中的组件, 但 Android 系统却可以。因此,要想启动其他应用中的组件,你必须向系统传递一则消息,说明想启动特定组件的 Intent。 系统随后便会为你启动该组件 二、Intent 四种组件类型中的三种:Activity、服务和广播接收器 ,都通过名为 Intent 的异步消息进行启动。Intent 会在运行时将各个组件相互绑定(可以将 Intent 视为从其他组件请求操作的信使),无论组件属于你的应用还是其他应用。 Intent 使用 Intent 对象创建,它定义的消息用于启动特定组件或特定类型的组件 — Intent 可以是显式的,也可以是隐式的 对于 Activity 和服务, Intent 定义要执行的操作(例如,“查看”或“发送”某个内容),并且可以指定要执行操作的数据的 URI(以及正在启动的组件可能需要了解的信息)。 例如, Intent 传达的请求可以是启动一个显示图像或打开网页的 Activity。 在某些情况下,可以启动 Activity 来接收结果,在这种情况下,Activity 也会在 Intent 中返回结果(例如,可以发出一个 Intent,让用户选取某位联系人并将其返回给应用,返回 Intent 包括指向所选联系人的 URI) 对于广播接收器, Intent 只会定义要广播的通知(例如,指示设备电池电量不足的广播只包括指示“电池电量不足”的已知操作字符串) Intent 不会启动另一个组件类型:内容提供程序,后者会在成为 ContentResolver 的请求目标时启动。 内容解析程序通过内容提供程序处理所有直接事务,使得通过提供程序执行事务的组件可以无需执行事务,而是改为在 ContentResolver 对象上调用方法。 这会在内容提供程序与请求信息的组件之间留出一个抽象层(以确保安全) 每种类型的组件有不同的启动方法: 可以通过将 Intent 传递到 startActivity() 或 startActivityForResult()(当想让 Activity 返回结果时使用)来启动 Activity(或为其安排新任务) 可以通过将 Intent 传递到 startService() 来启动服务(或对执行中的服务下达新指令)。 或者,也可以通过将 Intent 传递到 bindService() 来绑定到该服务 可以通过将 Intent 传递到 sendBroadcast()、sendOrderedBroadcast() 或 sendStickyBroadcast() 等方法来发起广播 可以通过在 ContentResolver 上调用 query() 来对内容提供程序执行查询 三、清单文件 在 Android 系统启动应用组件之前,系统必须通过读取应用的 AndroidManifest.xml 文件("清单"文件)确认组件存在。应用必须在此文件中声明其所有组件,该文件必须位于应用项目目录的根目录中。 除了声明应用的组件外,清单文件还有许多其他作用,如: 确定应用需要的任何用户权限,如互联网访问权限或对用户联系人的读取权限 根据应用使用的 API,声明应用所需的最低 API 级别 声明应用使用或需要的硬件和软件功能,如相机、蓝牙服务或多点触摸屏幕 应用需要链接的 API 库(Android 框架 API 除外),如 Google 地图库 其他功能 四、声明组件 清单文件的主要任务是告知系统有关应用组件的信息。例如,清单文件可以像下面这样声明 Activity: <?xml version="1.0" encoding="utf-8"?> <manifest ... > <application android:icon="@drawable/app_icon.png" ... > <activity android:name="com.example.project.ExampleActivity" android:label="@string/example_label" ... > </activity> ... </application> </manifest> 在< application >元素中,android:icon 属性指向标识应用的图标所对应的资源 在< activity >元素中,android:name 属性指定 Activity 子类的完全限定类名,android:label 属性指定用作 Activity 的用户可见标签的字符串。 通过以下方式声明所有应用组件: Activity 的 < activity > 元素 服务的 < service > 元素 广播接收器的 < receiver > 元素 内容提供者的 < provider > 元素 包含在源代码中,但未在清单文件中声明的 Activity、服务和内容提供者对系统不可见,因此也永远不会运行。 不过,广播接收器可以在清单文件中声明或在代码中动态创建(如 BroadcastReceiver 对象)并通过调用 registerReceiver() 在系统中注册 五、声明组件功能 如上文启动组件中所述,可以使用 Intent 来启动 Activity、服务和广播接收器。 你可以通过在 Intent 中显式命名目标组件(使用组件类名)来执行此操作。 不过,Intent 的真正强大之处在于隐式 Intent 概念。 隐式 Intent 的作用无非是描述要执行的操作类型(还可选择描述想执行的操作所针对的数据),让系统能够在设备上找到可执行该操作的组件,并启动该组件。 如果有多个组件可以执行 Intent 所描述的操作,则由用户选择使用哪一个组件 系统通过将接收到的 Intent 与设备上的其他应用的清单文件中提供的 Intent 过滤器进行比较来确定可以响应 Intent 的组件。 当在应用的清单文件中声明 Activity 时,可以选择性地加入声明 Activity 功能的 Intent 过滤器,以便响应来自其他应用的 Intent。 可以通过将 < intent-filter > 元素作为组件声明元素的子项进行添加来为组件声明 Intent 过滤器 例如,如果你开发的电子邮件应用包含一个用于撰写新电子邮件的 Activity,则可以像下面这样声明一个 Intent 过滤器来响应“send” Intent(以发送新电子邮件): <manifest ... > ... <application ... > <activity android:name="com.example.project.ComposeEmailActivity"> <intent-filter> <action android:name="android.intent.action.SEND" /> <data android:type="*/*" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity> </application> </manifest> 然后,如果另一个应用创建了一个包含ACTION_SEND操作的 Intent,并将其传递到 startActivity(),则系统可能会启动你的 Activity(因为系统中可能有多个应用能提供该服务,所以需要用户来选定使用哪个Activity),以便用户能够用来发送电子邮件 六、声明应用要求 基于 Android 系统的设备多种多样,并非所有设备都提供相同的特性和功能。 为防止将应用安装在缺少应用所需特性的设备上,必须通过在清单文件中声明设备和软件要求,为应用支持的设备类型明确定义一个配置文件。 其中的大多数声明只是为了提供信息,系统不会读取它们,但 Google Play 等外部服务会读取它们,以便当用户在其设备中搜索应用时为用户提供过滤功能 例如,如果应用需要相机,并使用 Android 2.1(API 级别 7)中引入的 API,则应该像下面这样在清单文件中以要求形式声明这些信息: <manifest ... > <uses-feature android:name="android.hardware.camera.any" android:required="true" /> <uses-sdk android:minSdkVersion="7" android:targetSdkVersion="19" /> ... </manifest> 现在,没有相机且 Android 版本低于 2.1 的设备将无法从 Google Play 安装该应用。 不过,你也可以声明应用有使用到相机,但并不要求必须使用。 在这种情况下,应用必须将 required 属性设置为 "false",并在运行时检查设备是否具有相机,然后根据需要停用任何相机功能 七、应用资源 Android 应用并非只包含代码,它还需要与源代码分离的资源,如图像、音频文件以及任何与应用的视觉呈现有关的内容。 例如,你应该通过 XML 文件定义 Activity 用户界面的动画、菜单、样式、颜色和布局。 使用应用资源能够在不修改代码的情况下轻松地更新应用的各种特性,并可通过提供备用资源集让你能够针对各种设备配置(如不同的语言和屏幕尺寸)优化应用。 对于Android 项目中包括的每一项资源,SDK 构建工具都会定义一个唯一的整型 ID,你可以利用它来引用应用代码或 XML 中定义的其他资源中的资源。 例如,如果应用包含一个名为 logo.png 的图像文件(保存在 res/drawable/ 目录中),则 SDK 工具会生成一个名为 R.drawable.logo 的资源 ID,可以利用它来引用该图像并将其插入用户界面当中 提供与源代码分离的资源的其中一个最重要优点在于,您可以提供针对不同设备配置的备用资源。 例如,通过在 XML 中定义 UI 字符串,可以将字符串翻译为其他语言,并将这些字符串保存在单独的文件中。 然后,Android 系统会根据向资源目录名称追加的语言限定符(如为法语字符串值追加 res/values-fr/)和用户的语言设置,应用相应的语言字符串 Android 支持许多不同的备用资源限定符。限定符是一种加入到资源目录名称中,用来定义这些资源适用的设备配置的简短字符串。 再举一例,你应该经常会根据设备的屏幕方向和尺寸为 Activity 创建不同的布局。 例如,当设备屏幕为纵向(长型)时,你可能想要一种垂直排列按钮的布局;但当屏幕为横向(宽型)时,应按水平方向排列按钮。 要想根据方向更改布局,你可以定义两种不同的布局,然后对每个布局的目录名称应用相应的限定符。 然后,系统会根据当前设备方向自动应用相应的布局

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

Swift入门基础知识

var //代表变量,变量的值可以改变 let//代表常量类型不可改变 //声明常量heh类型Swift会自动根据你的值来自动判断该变量的类型也可以指定类型(个人感觉还是指定类型的比较好,可能会减少系统的开销),值为10 //自动判断变量的类型 let heh = 10//假如在下面的代码中没有用到该变量Swift就会提示将let改为下划线,因为下划线代表忽略该变量,就相当于OC中提示并没有用该属性或者变量一样,估计没用到的变量一般人也不会写,只是给刚入门的说一下并不是你写错了或者Xcode有问题,只是Swift提示很细 //声明指定变量的类型 let heh:Double = 10.000 //声明变量hehe类型Swift会自动根据你的值来自动判断该变量的类型也可以指定类型(个人感觉还是指定类型的比较好),值为10 var heh:Double = 10//假如声明的变量没有改变的话Swift也会提示将其改为let //修改变量的值 heh = 12 //输出打印信息 print(heh) Swift还可以用中文当作变量的名字,因为Swift支持unicode编码,所以变量名可以是中文甚至是表情(感觉中文还是好一点,和java一样代码的风格也都和java一样) 比如: var 测试:Double = 10 测试 = 12 print(测试) 而且Swift的字符串不用带@,直接""就可以了 //遍历字符串 let zifu:String="abcdefghijk" for zf in zifu.characters { print(zf) } 或者也可以这样直接将字符串进行遍历(因为Swift会自动把字符串判断成String类型) for zf in "abcdefghijk".characters { print(zf) } //合并字符串(表示和java基本上就是一样啊)直接用加号就可以了字符串a,b。合成字符串c就是c=a+b let zifu:String="abcdefghijk" let zf2="xyz" let zf3 = zifu+zf2 print(zf3) print(zifu+zf2) //转义输出就是5*10=50 let a = 5 let b = 10 let js = "\(a)*\(b)=\(a*b)" print(js) //数组数组元素必须统一这个就不说了 let names = ["赵","钱","孙","李","周","吴","正","王"] print(names) //字典假如键所对应的值类型都是一样就照着下面写就可以 let zidian = ["a":1,"b":2,"c":3,"d":4,"e":5,"f":6,"g":7,"h":8,"i":9,"j":10,"k":11] print(zidian) 假如值的类型有很多种那么Swift就会提示变成下面这种 let zd = ["jian":"zhi","hehe":5,"sds":8,"sdffd":43,"fdss":"dsdds","dasa":"dsdsd","cdsd":454] as [String : Any] 一看就知道了,后面语句的意思就是键是String类型的,而值为任意类型的 //循环(基本上其他语言有的这里都有) for zf in "abcdefghijk".characters { print(zf) } //1...5代表遍历1到5包括1和5(三个点代表全闭区间) for number in 1...5 { print(number) } //1..5代表遍历1到5包括1但不包括5(两个点代表半开半闭区间不包含右边的区尾) fornumberin1..5{ print(number) } //遍历字典,可以一下就把键和值都遍历出来 let zd = ["jian":"zhi","hehe":5,"sds":8,"sdffd":43,"fdss":"dsdds","dasa":"dsdsd","cdsd":454] as [String : Any] for (j,z) in zd { print("键=\(j),值=\(z)") } //数组操作 //数组数组元素必须统一这个就不说了 var names = ["赵","钱","孙","李","周","吴","正","王"] //显示元素 print(names[0]) //增加元素 names.append("冯") //修改元素 names[0]="陈" //把第三个元素到第五个元素替换掉 names[3...5]=["楚","魏"] //字典 //定义一个可变字典 var zidian = ["a":1,"b":2,"c":3,"d":4,"e":5,"f":6,"g":7,"h":8,"i":9,"j":10,"k":11] //修改字典某个键的值 zidian["a"]=8 //方法,Swift中的方法是这样的 //参数和返回值都为空的一个方法 func kong() { print("空") } //带参数的方法,但是没有返回值 func hello(hehe:String) { print("\(hehe)") } //带参数并且有返回值 func fanhuizhi(name:String) -> String { return name } //多参数多返回值 func duofanhuizhi() -> (Int,String) { return(200,"haha") } //多参数多返回值第二种类型 func duofanhuizhi2() -> (code:Int,name:String) { return(200,"haha") }

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

mapreduce知识点记录

selfMapper extends Mapper< LongWritable, Text, Text, IntWritable> 其中LongWritable是某一行起始位置相对于文件起始位置的偏移量 FileSplit 继承extends InputSplit FileSplit fileSplit=(FileSplit) context.getInputSplit(); Stringpathname=fileSplit.getPath().getName();//获取目录名字 intdepth=fileSplit.getPath().depth();//获取目录深度 Classclass1=fileSplit.getClass();//获取当前类 longlength=fileSplit.getLength();//获取文件长度 SplitLocationInfo[]locationInfo=fileSplit.getLocationInfo();//获取位置信息 String[]locations=fileSplit.getLocations();//获取位置 longstart=fileSplit.getStart();//Thepositionofthefirstbyteinthefiletoprocess. 多文件输入与输出 1.多文件输入 FileInputFormat.setInputPaths() 方法:static void setInputPaths(Job job, Path... inputPaths)、 static void setInputPaths(Job job, String commaSeparatedPaths) 2.多文件输出(MultipleOutputs) public static class AlphabetOutputFormat extends MultipleOutputFormat { @Override protected String generateFileNameForKeyValue(Text key, IntWritable value, Configuration conf) { charc = key.toString().toLowerCase().charAt(0); if(c >='a'&& c <='z') { returnc +".txt"; } return"other.txt"; } } Combiner 作为map和reduce的中间环节,它的作用是聚合map task的磁盘,减少map端磁盘写入,减少reduce端处理的数据量,对于有大量shuffle的job来说,性能往往取决于reduce端。因为reduce 端要经过从map端copy数据、reduce端归并排序,最后才是执行reduce方法,此时如果可以减少map task输出将对整个job带来非常大的影响。 什么时候可以使用Combiner? 比如你的Job是WordCount,那么完全可以通过Combiner对map 函数输出数据先进行聚合,然后再将Combiner输出的结果发送到reduce端。 什么时候不能使用Combiner? WordCount在reduce端做的是加法,如果我们reduce需求是计算一大堆数字的平均数,则要求reduce获取到全部的数字进行计算,才可以得到正确值。此时,是不能使用Combiner的,因为会其会影响最终结果。 注意事项:即使设置Combiner,它也不一定被执行(受参数min.num.spills.for.combine影响),所以使用Combiner的场景应保证即使没有Combiner,我们的MapReduce也能正常运行。 shuffle与排序 Mapreduce的map结束后,把数据重新组织,作为reduce阶段的输入,该过程称 之为shuffle---洗牌。 而数据在Map与Reduce端都会做排序。 Map •Map 的输出是由collector控制的 •我们从collect函数入手 Reduce •reduce的Shuffle过程,分成三个阶段:复制Map输出、排序合并、reduce处理。 •主要代码在reduce的 run函数 JVM重用 启动JVM是一个比较耗时的工作,所以在MapReduce中有JVM重用的机制。 •条件是统一个作业的任务。 •可以通过mapred.job.reuse.jvm.num.tasks定义重用次数,如果属性是-1那么为无限制 StringTokenizer 1、构造函数。 1.StringTokenizer(String str):构造一个用来解析str的StringTokenizer对象。java默认的分隔符是“空格”、“制表符(‘\t’)”、“换行符(‘\n’)”、“回车符(‘\r’)”。 2.StringTokenizer(String str, String delim):构造一个用来解析str的StringTokenizer对象,并提供一个指定的分隔符。 3.StringTokenizer(String str, String delim, boolean returnDelims):构造一个用来解析str的StringTokenizer对象,并提供一个指定的分隔符,同时,指定是否返回分隔符。 2、方法。 说明: 1. 所有方法均为public; 2. 书写格式:[修饰符] <返回类型> <方法名([参数列表])> 如: static int parseInt(String s) 表示:此方法(parseInt)为类方法(static),返回类型为(int),方法所需参数为String类型。 1.int countTokens():返回nextToken方法被调用的次数。如果采用构造函数1和2,返回的就是分隔符数量(例2)。 2.boolean hasMoreTokens():返回是否还有分隔符。 3.boolean hasMoreElements():结果同2。 4.String nextToken():返回从当前位置到下一个分隔符的字符串。 5.Object nextElement():结果同4。 6.String nextToken(String delim):与4类似,以指定的分隔符返回结果。 待续。。。。。。。。。。。。。。。

资源下载

更多资源
Mario

Mario

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

Spring

Spring

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

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册