今天在公交车上,由于拥挤一男一女发生了碰撞。
时髦女郎回头飞眼道:“你有病啊?”
男子觉得莫名其妙回道:“你有药吗?”
车上人窃笑!
女子觉得生气回道:“你有精神病啊?”
男子冷面对道:“你能治啊?”
全车人爆笑!
公交司机停车,趴在方向盘上大笑!
这是珠江路上上班的朋友遇见的
公交车上超挤,有一女人站在门口,
从车后面挤过来一个GG要下车,
跟那女的说了一句“让一下,下车”,那个女滴木有动。
GG挤过去时就踩到她了。
结果那女人好厉害的,不停的骂“神经病啊你!神经病啊你!~~”,还超大声,搞得全车都看呀。
GG一直木有说话,下车时忍不了了,回头对那女人说,“复读机呀你!”
全车人暴笑~!
后边有几个搞笑的小孩,不停的伴演刚才的一幕,
甲说“你神经病呀你!。。。。。乙说“你复读机呀你”。。。。。。 新浪乐居论坛:
全车人暴笑~!
后来,有个小MM也要下车,挤过去怯怯滴说“偶~偶~偶想下去,偶不是神经病~!”
全车人再次暴笑~!
那个女人木有说话,可是从边上飘来一句话“你是不是没电了”
全车人暴笑不止~!
月度归档:2010年08月
windows下安装mongodb及php驱动
mongodb是nosql的典型了,采用是json类似的存储格式
mongodb官网下载windows平台下的服务端: http://www.mongodb.org/downloads
mongodb的php驱动:http://github.com/mongodb/mongo-php-driver/downloads
mongodb下载后,解压到D盘,最终地址是:D:\mongodb\bin
php驱动 php_mongo.dll 解压至php的ext文件夹下,然后修改php.ini,添加 extension=php_mongo.dll 新建数据库存放文件夹 D:\mongodb\db
mongodb的启动:
在命令行输入 D:\mongodb\bin\mo\mongod –dbpath D:\mongodb\db
到这里,mongodb已启动,打开http://127.0.0.1:28017/ 可以看到mongodb运行情况
为了方便以后每次不必启动mongod,可以把mongod注册成windows服务
mongodb php使用方法:
3 用PHP操作Mongondb
简单列子 //这里采用默认连接本机的27017端口,当然你也可以连接远程主机如192.168.0.4:27017,如果端口是27017,端口可以省略
$m = new Mongo();
// 选择comedy数据库,如果以前没该数据库会自动创建,也可以用
$db = $m->comedy;
//选择comedy里面的collection集合,相当于RDBMS里面的表,也-可以使用
$collection = $db->collection;
$db->selectCollection("collection");
/* —– 添加一个元素 —–*/
$obj = array( "title" => "Calvin and Hobbes", "author" => "Bill Watterson" );
$collection->insert($obj); //将$obj 添加到$collection 集合中
/* —– 添加另一个元素 —–*/
$obj = array(
"title" => "XKCD",
"online" => true
);
$collection->insert($obj);
$cursor = $collection->find();
//遍历所有集合中的文档
foreach ($cursor as $obj) {
echo $obj["title"] . "\n";
}
//断开MongoDB连接
$m->close();
3.2 常用函数
$query = array( "i" => 71 ); $cursor = $collection->find( $query ); // 在$collectio集合中查找满足$query的文档 while( $cursor->hasNext() ) { var_dump( $cursor->getNext() ); } $collection -> findOne(); //返回$collection集合中第一个文档 $collection -> count(); //返回$collection集合中文档的数量 $coll->ensureIndex( array( "i" => 1 ) ); // 为i “这一列”加索引 降序排列 $coll->ensureIndex( array( "i" => -1, "j" => 1 ) ); // 为i “这一列”加索引 降序排列 j升序
3.3 查询时,每个Object插入时都会自动生成一个独特的_id,它相当于RDBMS中的主键,用于查询时非常方便
如:
<?php $person = array("name" => "joe"); $people->insert($person); $joe = $people->findOne(array("_id" => $person['_id'])); ?>
在淘宝上开了家小店,卖些小家电
昨天mysql生成了100w条文章数据(2G数据)做测试用
昨天写了个php程序,给mysql插入随机的文章数据,仿照真实文章,中文数据,主要是测试在100w级数量时查询上的优化及测试mysql内置的全文检索与其它类似全文检索引擎的差距等。总数据量:article 101w左右 user表10w左右,总计占用硬盘2G左右
今天开始测试在海量数据查询时的优化手段
-
测试添加索引对数据查询的影响:
sql语句:select * from article as article order by time limit 10;
没有对time字段建立索引时查询所花时间:31.237657s
新建time字段的索引,花掉近二分钟,建立了111298条索引,没有建立完phpmyadmin就timeout了。
建立time索引后,同样的sql语句执行只花了:0.380957s,不过time索引没有建完,但是时间相差不大;
总结:在关键字段的索引上,建与不建速度相差近100倍!
-
测试limit在不同的基数上的影响:
sql语句:select * from article as article order by id limit 0,10
当limit的基数为0时【limit 0,10】,执行时间:0.001557s
当limit的基数为20000时【limit 20000,10】,,执行时间:0.572288s
当limit的基数为100000时,执行时间:2.793380s
当limit的基数为50W 时,执行时间:14.444422s
当limit的基数为100W时,执行时间:28.270054s
总结:在海量数据中要想查找比较靠后的数据时,要注意limit的基数,因为随着数据量的加大,查找时间继续增长!在取比较后面的数据时,可以通过desc方式把数据反向查找,以减少对前段数据的扫描,让limit的基数越小越好!
-
测试field为*或是id对查询速度的影响:
sql语句:select id from article as article order by id limit 100000,10
为了数据更真实,所以通过limit让sql执行时间长些,以便更容易看出区别
当field为id时,执行时间:2.617519s
当field为*时,执行时间:2.867721s
总结:由数量可见,二者在sql执行时间上相差并不大,但是限定field可以大幅度的减少内存开支
-
测试limit限定结果与between限定结果上的区别:
当用limit select * from article as article order by id limit 1000000,10 [31.163212s]
当用between select * from article as article where id between 1000000 and 1000010 order by id [0.001433s]
总结:between 限定上比limit快太多了,所以当在海量数据访问时,建议用between或是where把limit替换掉,但是between也有缺陷,如果id中间有断行或是中间部分id不读取的话,总读取的数量会少于预计数量!
-
测试left join对读取数据的影响
user表,数据为100000条
select id from article as article order by id limit 500000 [14.980397s]
select article.id from article as article left join user as user on user.uid=article.uid order by article.id,user.username limit 500000 [60.488099s]
总结:当数据量比较大时,用left join做连接是非常慢的,速度是查单表的4倍多,所以如果在大数据量的情况下,如果要实现刚实现用户表与文章表的连表功能,还是把全部的会员数据预先存入memcache等内存缓存中,10万条用户数据也不过5m不到,用户更新资料或登陆时,把用户的数据更新入memcache的指定用户中就ok了。这样速度就快了!
最后附上一截图
写了三个简单的算法,都是比较常用的
第一个是二分法查找,只能对有顺序的数组进行查找,速度应该是所有查找算法里最快的,
原理就是不停的做对折,以查找到目标!
第二个是冒泡排序,比较有名了,大学里c语言课必有的一个算法
第三个是从字符串中查找子串,也比较常用,以前用它做词频排序。
<?php //二分法 $arr 数组,$k 要查找的值,$m 最小,$b最大 function dichotomy($arr,$k,$m=0,$b=0) { $total=count($arr); if($total!=0 && $b==0) $b=$total; if($m<=$b){ $avg=intval(($m+$b)/2); if($arr[$avg]==$k) return $avg; elseif($k<$arr[$avg]) return dichotomy($arr,$k,$m,$avg-1); else return dichotomy($arr,$k,$avg+1,$b); } return false; } echo "<hr>二分法查找<br>"; $arr=array(0,1,2,3,4,5,6,7,8,9,10); var_dump(dichotomy($arr,1)); //冒泡排序 function bubblesort($arr) { $total=count($arr); for($i=0;$i<$total-1;$i++){ for($l=$i+1;$l<$total;$l++){ if($arr[$i]>$arr[$l]){ list($arr[$l],$arr[$i])=array($arr[$i],$arr[$l]); } } } return $arr; } echo "<hr>冒泡排序<br>"; $arr=array(1,100,23,434,22,12,3,5); var_dump(bubblesort($arr)); //从字符串中搜索子串 $text 字符串,$str 要搜索的子串 function search($text,$str){ $strLen=strlen($str); $textLen=strlen($text); for($i=0;$i<$textLen-$strLen;$i++){ if(substr($text,$i,$strLen)==$str) return $i; } return false; } echo "<hr>字符串中搜索子串<br>"; $text="pdsofuapdoi3409729fhydish"; var_dump(search($text,"7")); ?>
比较实用的Java基本语法
Java的基本符号(token)
Java的单词符号有五种:关键字、标识符、常量、分隔符和操作符。
Java的字符集
Java 采用一种称为unicode的字符集,该字符集合是一种新的编码标准,与常见的ASCII码的区别在于:
unicode使用16位二进制而不是8位来表示一个字符。
unicode字符集中增加了许多非拉丁语字符。
标识符
Java标识符必须以字母,数字,美元符号"$",下划线"_"组成,标识符第一个字符不可用数字。
Java语言对字母的大小写是敏感的,在语法中严格区分大小写。
关键字
关键字是为特定目的而保留的保留字,程序员不要将关键字作为自己的标识符。 Java的关键字有:
abstract boolean break byte case catch char class continue do double else extends false
find finally float for implements import instanceof int interface long native new null
package private public return short static super switch synchronized this throw true try void while
常量
常量可分为整型常量,浮点数常量,字符常量,字符串常量和布尔常量。
整型常量:可分为int型和long型两种,缺省为int型,long型数值后加L。 整型常量可用10、8和16进制表示。
如:123(十进制) 052(八进制) 0x3c(十六进制)
浮点数常量:有单精度和双精度之分,缺省为双精度,单精度在数值后加f。另外,浮点数常量也可用普通计数法和科学计数法来表示。
如:1.23f 1.1E-2
字符常量:用' '括起来的一个字符。如'a','H'。
使用16位的unicode字符集。
Java 语言可使用转义字符'\'来标记特殊字符。如'\n'表示换行符。
字符串常量用" "包括,如"Hello World"。
布尔常量只有两个值,true和false。
分隔符
分隔符起分隔单词符号的作用。包括分号";"、花括号"{}"和空白符号。
Java的注释
Java的注释有三种形式:
单行注释
如://Comment on one line
多行注释
如:/* Comment on one
or more lines */
文档注释
如:/** Document
Comment */
Java的数据类型和变量
Java的基本数据类型
Java的基本数据类型有8种,见下表:
数据类型 类别 宽度(位) 取值范围
boolean 逻辑型 1 true/false
char 文字型 16
byte 整数类型 8 -27 ~ 27-1
short 整数类型 16 -215 ~ 215-1
int 整数类型 32 -231 ~ 231-1
long 整数类型 64 -263 ~ 263-1
float 浮点型 32
double 浮点型 64
Java的变量
Java的变量在使用前必须声明。如 int radios, color;
Java为所有基本数据类型的变量作了预定义(预设置的值)。如
类型名 boolean char byte short int long float double
预置值 false '\u0000' (byte)0 (short)0 0 0L 0.0f 0.0
数据类型的转换
Java是一种强类型的语言,在赋值和参数传递时,都要求类型的匹配。类型转换有三种情况:自动转换、强制转换和使用类的方法转换。
自动转换:往往低精度类型到高精度类型能自动转换。
如: byte b1=10, b2=20;
int b3=b1+b2;
强制转换:高精度类型到低精度类型必须强制转换。这时数据可能会丢失部分信息。
如:char key=(char)(12+55) //变量key被赋值为unicode值为67的字符'c'
方法转换:如
String str = "123";
int a = Integer.parseInt(str);
使用Integer类的方法parseInt将String转换为对应的整数。
Java编程的习惯约定
为了提高程序的可读性,Sun公司推荐在Java编程时使用以下的习惯约定:
类名(classes):有一个或若干个名词组成,开头大写,名词间的区分也用大写,其他小写。
如:class AccountBook
class ComplexVariable
接口(Interfaces):规则同类名。
如:Interface Account
方法(methods): 由一个或多个动词组成,开头小写,动词间区分用大写,其他小写。
如:balanceAccount()
变量:小写字母开头,单词间用大写字母分隔
如:currentCustomer
常量:所有字母大写,单词间用下划线区分
如:MAXIMUM_SIZE
Java的操作符
根据操作对象的个数操作符可分为一元、二元或三元操作符。根据操作符的功能,又可分为算术、逻辑、关系等操作符。
算术操作符
一元: + – ++ —
二元: + – * / %
值得注意的是 ++ 和– 操作符,
如:int a,x=1,y=5;
a = ++x;b=y++;
此时a的值为2(先加1,后赋值),b的值为5(先赋值,后加1)。
二元操作符两侧的操作对象数据类型不同时,先自动进行类型转换,再进行操作。
赋值操作符与复合赋值操作符
可将 变量 = 变量 op 表达式
写成 变量 op = 表达式
如:x+=20 与 x=x+20 结果一致,但更简洁。
注意:= 与 = = 的不同。
位操作符和移位操作符
位操作符
&(按位与) |(按位或) ^(按位异或)
移位操作符
E<
E>>n 右移n位,空位用原最高位的位值补足,相当于E/2
E>>>n 右移n位,空位补0
关系操作符
关系操作符共六个:
>(大于) >=(大于等于) <(小于)<=(小于等于) !=(不等于) = =(相等)
关系操作符的结果为boolean型数据(true或false)。
注:= = 操作符只有在比较双方均完全一致时,其值为true,如比较的是两个对象,即使两个对象的内容相同,结果也为false,
只有这两个对象为同一对象时才为true。
逻辑操作符
逻辑操作符的操作对象和结果均为boolean型,共六个:
!(逻辑非) && (逻辑与) ||(逻辑或)
^(逻辑并或) & (逻辑与) | (逻辑或)
按位与'&'也可作为逻辑与使用,但未作优化,而'&&'操作符是经过优化的。对'|'操作符也类似。
其他操作符
条件操作符 E1?E2:E3
表达式E1若成立,执行表达式E2,否则执行E3。
逗号操作符
","可用于分隔语句。
如 int x,y;
for (x=0,y=0;x<10;x++) {…};
操作符的优先级和结合规则
优先级:
一元 〉算术 〉移位 〉关系 〉按位 〉逻辑 〉三元 〉(复合)赋值 〉逗号
结合规则:
除一元、三元和赋值操作符是自右至左结合外,其他均自左至右结合。
语句的分类
Java语句按是否改变运行的状态可分为执行语句(如表达式语句)和非执行语句(如声明语句)。任何语句的末尾都以“;”结束。
执行语句按其组成可分三类:
空语句
只有一个语句结束符“;” ,无任何内容。
基本语句(单语句)
独立的、完整的不能再分割为更小的可执行单元。
复合语句(块语句)
包含在{ }内的一条或若干条语句。
Java的基本语句的结构可分为4类:
(1)顺序结构语句 (2)分支语句 (3)循环语句 (4)例外处理语句
后三种语句又称为流控制语句,我们将主要介绍分支语句和循环语句,而例外处理语句包括try、catch、finally以及throw语句。
这些语句是Java所特有的。我们将在后面作专门的介绍。
分支语句
分支语句包括if-else, break, switch, return等语句。分支语句提供了一种控制机制,使得程序可以跳过一些语句,转去执行特定的语句。
条件语句 if-else.
if-else语句根据判定条件的真假来执行两种操作中的一种,其格式为:
if (boolean-expression)
statement1;
else
statement2;
其中,要注意的有:
布尔表达式boolean-expression是任意一个返回布尔型数据的表达式(这比C、C++的限制要严格)。
每个单一的语句后都必须有分号。
语句statement1, statement2可以是复合语句,这时要用花括号{}。{}外面不加分号。
else子句是任选的。
若布尔表达式的值为true,则程序执行statement1,否则执行statement2。
if-else语句的一种特殊形式为:
if (expression1){
statement1
} else if (expression2){
statement2
}……
}else if (expressionN){
statementN
}
else子句不能单独作为语句使用,它必须和if配对使用。else总是与离它最近的if配对。可以通过使用花括号{}来改变配对关系。
例3.1: 比较两个数的大小,并按从小到大的次序输出。
public class CompareTwo{
public static void main (String args[]){
double d1=23.4;
double d2=35.1;
if (d2>=d1)
System.out.println(d2+">="+d1);
else
System.out.println(d1+">="+d2);
}
}
例3.2:判断某一年是否为闰年。
闰年的条件是符合下面二者之一: ①能被4整除,但不能被100整除; ②能被400整除。
public class LeapYear{
public static void main (String args[]){
int year=1989; //method1
if ((year%4==0 && year0!=0) || (year@0==0))
System.out.println(year+"is a leap year.");
else
System.out.println(year+"is not a leap year.");
year=2000; //method2
boolean leap;
if (year%4 != 0)
leap=false;
else if (year0 != 0)
leap=true;
else if (year@0 != 0)
leap=false;
else
leap=true;
if(leap==true)
System.out.println(year+" is a leap year.");
else
System.out.println(year+"is not a leap year.");
}
}
该例中,方法1用一个逻辑表达式包含了所有的闰年条件,方法2使用了if-else语句的特殊形式。
多分支语句switch
switch语句是一种多分支选择语句,它可根据switch中表达式的值,来执行多个操作中的一个,它的一般格式如下:
switch (expression){
case value1: statement1;
break;
case value2: statement2;
break;
…………
case valueN: statemendN;
break;
[default: defaultStatement;]
}
表达式expression可以返回任一简单类型的值(如整型、字符型),多分支语句把表达式返回的值与每个case子句中的值(一个常量)相比。
如果匹配成功,则执行该case子句后的语句序列。
default子句是任选的。当表达式的值与任一case子句中的值都不匹配时,程序执行default后面的语句。如果表达式的值与任一case子句
中的值都不匹配且没有default子句,则程序不做任何操作,直接跳出switch语句。
break语句用来在执行完一个case分支后,使程序跳出switch语句,即终止switch语句的执行。
switch语句的功能可以用if-else来实现,但在某些情况下,使用switch语句更简炼,且程序的执行效率提高。
例3.3 根据考试成绩的等级打印出百分制分数段。
public class GradeLevel {
public static void main(String args[]){
System.out.println("\nOutPut is:");
char grade='C'; //normal use
switch (grade){
case 'A': System.out.println(grade+"is 85~100");
break;
case 'B': System.out.println(grade+"is 70~84");
break;
case 'C': System.out.println(grade+"is 60~69");
break;
case 'D': System.out.println(grade+"is <60");
break;
default: System.out.println("inputerror");
}
}
}
break语句
在switch语中,break语句用来终止switch语句的执行。使程序在switch语句后的第一个语句开始执行。
在Java中,可以为每个代码块加一个括号。一个代码块通常是用花括号{}括起来的一段代码。加标号的格式如下:
BlockLabel: {codeBlock}
break语句的第二种使用情况就是跳出它所指定的块,并从紧跟该块的第一条语句处执行。其格式为: break BlockLabel;
例如:
a: {…… //标记代码块a
b: {…… //标记代码块b
c: {…… //标记代码块c
break a;
……//will not be executed
}
……//will not be executed
}
……//will not be executed
}
…… //execute from here
与C、C++不同, Java中没有goto语句来实现任意的跳转, 因为goto语句破坏程序的可读性, 而且影响编译的优化。Java用break来实现goto语句所特有的一些功能。
返回语句return
return语句用于从当前执行的方法中退出, 并返回到调用该方法的语句处继续程序的执行。返回语句有两种格式:
return expression
返回一个值给调用该方法的语句, 返回值的数据类型必须与方法声明中的返回值类型一致。可以使用强制类型转换来使类型一致。
return
当方法说明中用void声明返回类型为空时, 可以使用这种格式, 它不返回任何值。不带参数的return语句有时可省略。
return语句通常用在一个方法体的最后。
循环语句
循环语句包括 while, do-while, for, continue 等语句。循环语句的作用是反复执行一段代码,直到满足循环终止条件为止,
一个循环一般应包括四部分内容:
初始化部分(initialization): 用来设置循环的一些初始条件,计数器清零等。
循环体部分(body): 这是反复循环的一段代码,可以是单一的一条语句,也可以是复合语句。
迭代部分(iteration): 这是在当前循环结束,下一次循环开始前执行的语句,常常用来使计数器加1或减1。
终止部分(termination): 通常是一个布尔表达式,每一次循环要对该表达式求值,以验证是否满足循环终止条件。
下面分别介绍Java中的while语句,do-while语句和for语句。
while语句
while语句的一般格式为:
[初始化]
while (条件表达式E){
语句S; //循环体
}
当条件表达式E的值为true时,循环执行花括号中的语句S。S中包括迭代部分。
while语句首先计算条件表达式E是否成立,当条件成立(true)时,才去执行循环中的语句。所以有可能循环体一次也不执行。
do-while语句
do-while语句的一般格式为:
[初始化]
do {
语句S; //循环体
} while (条件表达式E);
do-while语句首先执行循环体, 然后再计算终止条件, 若结果为true, 则循环执行语句S, 直到条件表达式E的结果为false。
与while语句不同的是, do-while语句的循环体至少执行一次。
for语句
for语句的一般格式为:
for (初始表达式; 条件表达式; 迭代表达式) {
语句S; //循环体
}
for语句执行时,首先执行初始化操作,然后判断终止条件是否满足,如果满足,则执行循环体中的语句,最后执行迭代部分。
完成一次循环后,重新判断终止条件。
可以在for语句的初始化部分声明变量,它的作用域为整个for语句。
for语句通常用来执行循环次数确定的情况(如对数组元素进行操作)。
在初始化部分和迭代部分可以使用逗号语句来分隔多个操作。例如:
for (i=0,j=10; i<j; i++,j–) {
……
}
continue语句
continue语句用来结束本次循环, 跳过循环体中下面尚未执行的语句, 接着进行终止条件的判断, 以决定是否继续循环。
也可以用continue跳转到括号指明的外层循环中,这时的格式为
continue outerLable;
例3.4:下例分别用while、do-while和for语句实现累计求和。
public class Sum{
public static void main(String args[]){
System.out.println("\n**while statement**");
int n=10,sum=0; ∥initialization
while (n>0){ ∥termination
sum+=n; ∥body
n–; ∥iteration
}
System.out.println("sum is"+sum);
System.out.println("\n**do_while statement**");
n=0; ∥initialization
sum=0;
do{
sum+=n; ∥body
n++; ∥iteration
} while(n<=10); ∥termination
System.out.println("sum is"+sum);
System.out.println("\n**for statement**");
sum=0;
for (int i=1;i<=10;i++){
sum+=i;
}
System.out.println("sum is"+sum);
}
}
可以从中来比较这三种循环语句,从而在不同的场合选择合适的语句。
数组
数组是有序数据的集合, 数组中的每个元素具有相同的类型。数组名和下标可唯一地确定数组中的元素。数组可分为一维数组和多维数组。
一维数组
声明方式:
type arrayName[];
或 type[] arrayName;
type可以是Java中任意的数据类型, arrayName为数组名。
如: int intArray[];
声明了一个名为intArray的整型数组, 数组中的每个元素为int型数据。
Java在数组的声明中并不为数组元素分配内存, 因此 [ ] 中不用指出数组中元素个数, 即数组长度。
在访问数组的任何元素之前,我们必须为它分配内存空间, 这可用new操作符, 其格式如下:
arrayName = new type[arraySize];
其中,arraySize指明数组的长度。
如: intArray = new int[3]; 为该数组分配了3个int型整数所需的内存空间。
通常, 这两部分可以合在一起, 格式如下:
type arrayName[] = new type[arraySize];
如: int intArray[] = new int[3];
用new操作符为数组分配内存空间后,就可以引用数组中的每一个元素。数组元素的引用方式为: arrayName[index]
其中: index为数组下标,它可以为整型常数或表达式。如a[3], b(i为整型), c[6*I]等。下标从0开始, 一直到数组的长度减1。
对于上面例子中的intArray数组来说,它有3个元素,分别为:
intArray[0], intArray[1], intArray[2]。(注意: 没有intArray[3]。)
另外,与C、C++中不同,Java对数组元素要进行越界检查以保证安全性。同时,对于每个数组都有一个属性length指明它的长度。
例如: intArray.length指明数组intArray的长度。
数组的初始化
对数组元素可以按照上述的例子进行赋值。也可以在定义数组的同时进行初始化。
如: int a[]={1,2,3,4,5};
用逗号(,)分隔数组的各个元素,系统自动为数组分配一定的内存空间。
例3.5:数组的使用:
public class ArrayTest{
public static void main(String args[]){
int i;
int a[]=new int[5];
for (i=0;i<5;i++)
a=i;
for (i=a.length-1;i>=0;i–)
System.out.println("a["+i+"]="+a);
}
}
多维数组
与C、C++一样, Java中多维数组可被看作数组的数组。例如二维数组就可看成是一个特殊的一维数组, 该数组的每个元素又是一个一维数组。下面我们主要以二维数组为例来说明多维数组。
二维数组的声明方式如下:
type arrayName[][];
如: int intArray[][];
与一维数组一样,这时对数组元素也没有分配内存空间,同要使用运算符new来分配内存,然后才可以访问每个元素。
对二维数组中每个元素,引用方式为:
arrayName[index1][index2]
其中index1、index2为下标, 可为整型常数或表达式, 如a[2][3]等。数组每一维的下标也都从0开始。
在声明二维数组的同时也可对它进行初始化。
如:int a[][]={{2,3},{1,5},{3,4}};
定义了一个3×2的数组,并对每个元素赋值。
数组的越界
如果使用数组分量时,其下标超过规定的值,则会发生数组的越界。这时,虽然程序能通过编译,但在运行时会产生一个名为ArrayIndexOutOfBoundsException 的例外,所以编程时要注意检查数组下标。
通过php web方式更新服务器svn[新]
主要的功能为二点:1、签出svn,2、更新svn;
需事前注意:apache或是nginx+php 用户要有svn程序执行的权限,如果没有的话,就需要通过visudo进行sudo授权,让apache用户(例www-data)可以执行svn程序
visudo文件最后加上:(意思:sudo无需输入密码可执行/usr/bin/svn命令)
www-data ALL = NOPASSWD:/usr/bin/svn
界面:
注意:如果通过visudo的方式让apache等执行svn命令,则下面的php代码中的svn 需改成sudo svn …..
<?php //author 冻番茄 www.phpd.cn session_start(); //echo $_SERVER['REQUEST_URI']; //print_r($_SERVER); //location.reload(); function update(){ echo '<h2>svn update ...</h2>'; //echo "svn up --username {$_SESSION['username']} --password {$_SESSION['password']} "; $hl=popen("svn up --username {$_SESSION['username']} --password {$_SESSION['password']} ","r"); $read=stream_get_contents($hl); echo "<pre>"; printf($read); echo "</pre>"; pclose($hl); } function co($url,$username,$password){ echo '<h2>svn checkout ...</h2>'; $command="svn co $url --username {$_SESSION['username']} --password {$_SESSION['password']} ".$_SERVER['DOCUMENT_ROOT']; exec($command); echo 'checkout Success!'; } if(isset($_POST['sub']) && $_POST['sub']=="登录"){ if($_POST['password']=="7279915"){ $_SESSION['login']=true; echo '<script>location.href="'.$_SERVER['PHP_SELF'].'";</script>'; }else{ echo '<script>alert("PASSWORD ERROR");location.href="'.$_SERVER['PHP_SELF'].'";</script>'; } exit; }elseif(isset($_POST['sub']) && $_POST['sub']=='执行'){ if(empty($_POST['username']) || empty($_POST['password'])){ echo '<script>alert("SVN服务器的用户名或是密码不能为空");location.href="?a=update";</script>'; }else{ $_SESSION['username']=$_POST['username']; $_SESSION['password']=$_POST['password']; echo '<script>location.href="?a=update";</script>'; } exit; } if(isset($_GET['a']) && $_GET['a']=='logout'){ unset($_SESSION['login']); unset($_SESSION['username']); unset($_SESSION['password']); echo '<script>location.href="?a=co";</script>'; exit; } ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <title>svn更新 | Author:常州亚萌 冻番茄</title> <style> *{ margin:0px; padding:0px; font-size:12px;font-family:Arial,Helvetica,sans-serif} a:link,a:visited,a:active{ color:#5A5A5A; text-decoration:none;font-size:14px;} a:hover{ color:#33A9D0; text-decoration:none;} .login{margin:0px auto;margin-top:200px;border:1px solid #666600;width:300px;height:90px;background:#FFFFD0} input{border:1px solid #666600;background:#fff;width:160px;padding:3px;} .in1{border:1px solid #666600;background:#fff;width:120px;padding:2px;font-size:9px;} .run{margin:20px auto;;width:700px;height:90px} h2{padding-bottom:8px;} </style> </head> <body> <?php if(!isset($_SESSION['login'])){ ?> <div class="login"> <FORM METHOD=POST ACTION=""> <div style="font-size:14px;margin:10px;border-bottom:1px solid #666600;padding-bottom:10px;text-align:center">svn更新操作 [管理员登录]</div> <div style="margin:10px;clear:both;text-align:center"><INPUT TYPE="password" NAME="password"> <INPUT TYPE="submit" name="sub" value="登录" style="width:70px;height:25px;"></div> </FORM> </div> <?php }else{ ?> <div class="run"> <div style="font-size:14px;margin:10px;border-bottom:1px solid #666600;padding-bottom:10px;"> [<a href="?a=update">svn刷新/upload</a>] [<a href="?a=co">svn签出/checkout</a>] [<a href="/svn.php?a=logout">退出</a>]</div> <div style="margin:10px;clear:both;"> <?php if(isset($_GET['a']) && $_GET['a']=='update'){ if(!isset($_SESSION['username']) || !isset($_SESSION['password'])){ echo '<FORM METHOD=POST ACTION=""> <h2>SVN更新操作</h2> <div>svn用户名:<INPUT TYPE="text" NAME="username" class="in1"> svn密码:<INPUT TYPE="password" NAME="password" class="in1"> <INPUT TYPE="submit" name="sub" value="执行" style="width:70px;background:#eee" class="in1"> </div> </FORM>'; }else{ update(); } }elseif(isset($_GET['a']) && $_GET['a']=='co'){ if(isset($_POST['sub']) && $_POST['sub']=='签出'){ if(empty($_POST['username']) || empty($_POST['password']) || empty($_POST['svn']) ){ echo '<script>alert("签出的svn地址、用户名、密码不能为空");location.href="?a=co";</script>'; }else{ $_SESSION['username']=$_POST['username']; $_SESSION['password']=$_POST['password']; co($_POST['svn']); } exit; } echo '<FORM METHOD=POST ACTION=""> <h2>SVN签出操作 <注:已签出的项目,第二次签出无效!></h2> <div>svn地址:<INPUT TYPE="text" NAME="svn" class="in1" value="svn://"> svn用户名:<INPUT TYPE="text" NAME="username" class="in1"> svn密码:<INPUT TYPE="password" NAME="password" class="in1"> <INPUT TYPE="submit" name="sub" value="签出" style="width:70px;background:#eee" class="in1"> </div> </FORM>'; }else{ echo '欢迎进入svn更新程序!Author:冻番茄<br />'; } ?> <div style="clear:both;height:10px"></div> </div> </div> <?php } ?> </body> </html>
源代码下载:
快速开发一个PHP扩展 [转heiyeluren]
本文通过非常快速的方式讲解了如何制作一个PHP 5.2 环境的扩展(PHP Extension),希望能够在图文的方式下让想快速学习的朋友了解一下制作过程。
需求:比如开发一个叫做 heiyeluren 的扩展,扩展里就一个函数 heiyeluren_test(),输入一个字符串,函数返回:Your input string: xxxxx。
要求:了解C/C++编程,熟悉PHP编程
环境:下载一份php对应版本的源码,我这里是 php-5.2.6,先正常安装php,假设我们的php安装在 /usr/local/php 目录,源码在 /root/soft/php/php-5.2.6/,现在开始!
步骤一:生成扩展框架
cd /root/soft/php/php-5.2.6/ext
./ext_skel –extname=heiyeluren
cd /root/soft/php/php-5.2.6/ext/heiyeluren
vi config.m4
打开文件后去掉 dnl ,获得下面的信息:
PHP_ARG_ENABLE(heiyeluren, whether to enable heiyeluren support,
[ –enable-heiyeluren Enable heiyeluren support])
保存退出.
(图01)
第二步:编写代码
vi php_heiyeluren.h
找到:PHP_FUNCTION(confirm_heiyeluren_compiled); ,新增一行:
PHP_FUNCTION(heiyeluren_test);
保存退出。
(图02)
vi heiyeluren.c
数组里增加我们的函数,找到 zend_function_entry heiyeluren_functions[],增加:
PHP_FE(heiyeluren, NULL)
(图03)
再到 heiyeluren.c 文件最后面增加如下代码:
PHP_FUNCTION(heiyeluren_test)
{
char *arg = NULL;
int arg_len, len;
char *strg;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &arg, &arg_len) == FAILURE) {
return;
}
len = spprintf(&strg, 0, "Your input string: %s\n", arg);
RETURN_STRINGL(strg, len, 0);
}
保存退出。
(图04)
第三步:编译安装
cd /root/soft/php/php-5.2.6/ext/heiyeluren
/usr/local/php/bin/phpize
./configure –with-php-config=/usr/local/php/bin/php-config
make
make test
make install
现在看看是不是有个 /usr/local/php/lib/php/extensions/no-debug-non-zts-20060613/heiyeluren.so
编辑php.ini,把扩展加入进去:
vi /usr/local/php/lib/php.ini
在[PHP]模块下增加:
extension = heiyeluren.so
保存退出。
(图05)
注意:如果你不存在扩展文件目录,或者安装报错,那么可以自行建立这个目录,然后把扩展拷贝到目录下,然后记得把 php.ini 文件中的 extension_dir 修改为该目录:
extension_dir = "/usr/local/php/lib/php/extensions/no-debug-non-zts-20060613/"
(图06)
第四步:检查安装结果
现在看看模块加载了没有:
/usr/local/php/bin/php -m,应该会打印出:
[PHP Modules]
…
heiyeluren
…
[Zend Modules]
然后重启apache,输出 phpinfo() ,应该能够看到:
heiyeluren
heiyeluren support enabled
(图07)
看看函数是否存在并且调用,在web目录下建立:heiyeluren.php
<?php
echo "<pre>";
print_r(get_loaded_extensions());
print_r(get_extension_funcs('heiyeluren'));
echo heiyeluren_test('My first php extension');
echo "</pre>";
?>
访问apache,应该能够看到:
Array
(
…
[33] => heiyeluren
)
Array
(
[0] => confirm_heiyeluren_compiled
[1] => heiyeluren_test
)
Your input string: heiyeluren
(图08)
扩展制作成功!
新写的一个.net小程序,用于批量搜索源码内容
主要是解决在工作中,有些需要在大批量的源文件或是html中搜索文本中包括一些关键词的操作。比如搜索全部的html,查找出哪个文章被挂了马,又比如说查看一个开源软件源码时,要找到一个函数定义所在文件。有了这个小软件,就方便多了
目前是第一版只支持utf-8编码,过段时间,加上编码转换功能,就可以支持其它编码了!编码只在搜索中文时有影响,英文不受影响
程序截图
程序下载