|
2008年2月20日
#
安装前需要先联上线,并且您需要取得root权限。
perl -MCPAN -e shell
初次运行CPAN
时需要做一些设置,如果您的机器是直接与internet相联(拨号上网、专线,etc.),那么一路回车就行了,只需要在最后选一个离您最近的CPAN
镜像站点。例如我选的是位于国内的中国自由软件库ftp://freesoft.cgi.gov.cn/pub/languages/perl/CPAN
。否则,如果您的机器位于防火墙之后,还需要设置ftp代理或http代理。
获得帮助
cpan>h
列出CPAN上所有模块的列表
cpan>m
安装模块
cpan>install DBI
自动完成DBI模块从下载到安装的全过程。
退出
cpan>q
今天Google的mp3搜索上线了,与百度不同的是,全是正版……
玩了一下泡泡选歌,非常有趣。
从Gmail开始,然后是Gtalk,在线的Office,加上Task,calendar
Google把大家的桌面搬上Web的愿景,正在一步步实现。
http://labs.mozilla.com/2008/08/introducing-ubiquity/
最近需要使用Perl,就随便总结一下。
首先当然是环境的建立了,linux下不用管,都是自带了,直接就可以编写Perl脚本去了。
在Windows下需要去下载并且安装一个Active Perl,可以到这个网站 http://www.activestate.com/Products/activeperl/index.mhtml去下载。
关于开发工具,已经存在一个Eclipse的插件,里面还带有正则表达式测试等功能,但是不是很成熟。其实只用带有代码着色的文本工具即可,然后在命令行调用Perl yourPerl.PL就可以了。
Perl最具特点是它有很多包含各种功能的Module可以被使用,你可以到 http://www.cpan.org/去Search,downlads它们。
这些模块下载下来以后是一个压缩文件,将其解压缩以后,里面一般会有Makefile.PL,用perl命令去运行这个脚本即
perl Makefile.PL
接下来如果是在linux下,依次打入命令:
make
make test
make install
注意make test会提示你这个模块所依赖的模块是否已经被安装,最好把它依赖的模块也一起安装了,否则后面可能会出问题。
不知道有没有ANT里面 fetch-depends类似的功能,暂时没有找到。
如果你在windows下,make就要换成nmake了。
有少数的模块里面并没有Makefile.PL而是一个Build.PL,需要特殊的模块来安装,这个模块叫什么记不清了,可以去上面那个网站去搜索一下。
好了,环境工具都搞定了,找本书吧,O'Relly 的Learning Perl是很好的入门读物,甚者那个骆驼标志已经成为事实上Perl的代言人了。
然后就开始你的Perl旅程吧。
问:如何对私有方法进行单元测试?
答:重点在于,你不应该有任何方法是从一开始设计出来就是private的,因为你的每段程序都应该在单元测试的驱动之下产生,而测试是不可能驱动出
来一个private方法的。那么private方法从哪里来?只能从重构而来。所以答案是:private方法是不需要测试的,因为它是重构的产物,而
重构是不改变程序可观察之行为的。既然行为不改变,测试自然也不需要有任何改变,所以不需要针对private方法建立任何新的测试。
问:但是,如果private方法确实出现问题了怎么办?如果确实希望用测试来弄清一个private方法里面到底发生了什么,该怎么办?
答:如果一个private方法复杂到你不能一眼看清它,那它就太复杂了,你应该把它重构成为一个独立的class,然后针对这个class来建立单元测试。
浏览器彻底换成了FireFox
编程用的是IDE是Eclipse
Server用的是Jboss
Office用的是Open Office
等待…………梦想中的Gphone
mysql的procedure不支持数组参数,在网上找了个强人的代码,与大家分享。
http://www.phpx.com/happy/thread-111759-1-1.html
DELIMITER ;
DROP DATABASE IF EXISTS PRO;
USE MYSQL
CREATE DATABASE PRO;
USE PRO
DROP TABLE IF EXISTS TEMP;
CREATE TABLE TEMP (
ID INT(8) NOT NULL AUTO_INCREMENT,
FOREIGN_KEY INT(8) NOT NULL,
PRIMARY KEY (ID)
) TYPE=MyISAM AUTO_INCREMENT=1 COMMENT='测试';
DELIMITER ;
DELIMITER //
DROP PROCEDURE IF EXISTS DNA //
CREATE PROCEDURE DNA (IN THE_CNT INT(8), IN THE_STR VARCHAR(10000))
BEGIN
DECLARE i INT(8) DEFAULT 0;
REPEAT SET i = i + 1;
INSERT INTO TEMP VALUES (NULL, SUBSTRING_INDEX(SUBSTRING_INDEX(THE_STR, ',', i), ',', -1));
UNTIL i >= THE_CNT END REPEAT;
END
//
DELIMITER ;
CALL DNA(7, '231,24,1114,151,7831241,9134,989');
SELECT * FROM TEMP;
+----+-------------+
| ID | FOREIGN_KEY |
+----+-------------+
| 1 | 231 |
| 2 | 24 |
| 3 | 1114 |
| 4 | 151 |
| 5 | 7831241 |
| 6 | 9134 |
| 7 | 989 |
+----+-------------+
刚才试图搞mysql的存储过程,被郁闷了一回,最简单的存储过程,只要加上begin 和end就有莫名其妙的错误。
比如
CREATE PROCEDURE p()
BEGIN
SELECT * FROM T;
END;
够简单了吧?就是报错,其实是分号的问题,说的正规点叫分隔符。
应该这样
1. delimiter //
2. CREATE PROCEDURE p()
3. BEGIN
4. SELECT * FROM T;
5. END//
6.
7. delimiter ;
第一行把分隔符改成双杠,这样到中间 FROM T的时候mysql不会认为SQL命令已经结束了;
第七行把分隔符再改回来,不然以后不习惯。
粗粗看完一遍设计模式的时候,觉得Builder Pattern和Factory Method Pattern有点混淆,好像这两者都是将复杂的构造过程屏蔽掉,最终返回一个Client满意的对象,但他们的本质是不一样的。
Builder Pattern只针对一个类,这个类的特点是构造起来过程特别复杂,所以将构造的部分独立出来,专门用一个BuilderClass来负责生成对象。
Factory Method更多的是针对生成实现同一接口的一组类中的某个。有点拗口,就是在运行时生成正确的对象。
总结下来,就是Builder针对一个Class,Factory Method针对从一组Class中挑选一个。
看设计模式看到Prototype Pattern,老实说觉得这个模式并不是特别重要,但其中提到的Java中的clone()方法,却值得仔细看一看,其中涉及到浅拷贝和深拷贝(shallow copy & deep copy),Sun的一篇技术文档已经写的很清楚了,推荐。
http://java.sun.com/developer/JDCTechTips/2001/tt0410.html#making
Meaning
A means of estimation made according to a rough and ready practical rule, not based on science or exact measurement.
Origin
This
has been said to derive from the belief that English law allowed a man
to beat his wife with a stick so long as it is was no thicker than his
thumb.
Meaning里面已经写得很清楚,表示一个粗略的原则,毕竟打老婆的时候不会仔细丈量自己用的棍子的粗细到底有没有超过自己的拇指。
在书中它是这么用的:
The rule of thumb is that...
我想应该翻译成:大体的原则是...
Java中一共有四个类加载器,之所以叫类加载器,是程序要用到某个类的时候,要用类加载器载入内存。
这四个类加载器分别为:Bootstrap ClassLoader、Extension ClassLoader、AppClassLoader
和URLClassLoader,他们的作用其实从名字就可以大概推测出来了。其中AppClassLoader在很多地方被叫做System ClassLoader
Bootstrap ClassLoader是在JVM开始运行的时候加载java的核心类,是用C++编写的,它用来加载核心类库,在JVM源代码中这样写道:
static const char classpathFormat[] =
"%/lib/rt.jar:"
"%/lib/i18n.jar:"
"%/lib/sunrsasign.jar:"
"%/lib/jsse.jar:"
"%/lib/jce.jar:"
"%/lib/charsets.jar:"
"%/classes";
Extension ClassLoader是用来加载扩展类,即/lib/ext中的类。
AppClassLoader用来加载Classpath的类,是和我们关系最密切的类。
URLClassLoader用来加载网络上远程的类,暂且不讨论。
它们之间的关系:
1.Parent-Child,按顺序从大到小。不是简单的继承关系。
2.ClassLoader有个getParent的方法,但是Ext ClassLoader调用后得到的是null,bootstrap是JVM自己的,用户看不到。
3.classloader的委托机制:当等级比较低的ClassLoader要加载某个类的时候,它首先会请求Parent加载器来加载,Parent再请求它的Parent
比如现在Ext要加载了,它往上请求。如果最大的Bootstrap找不到,那么Boot会叫Ext自己找找,Ext找不到,是不会让下一级的App去找的,此时就报出ClassNotFoundException
4.类A调用类B,B会要求调用它的类的类加载器来加载它,也就是B会要求加载A的加载器来加载B。这就会有个问题,如果他们在一起,那没关系,肯定某个classloader会把它们俩都加载好。但是如果A在/lib/ext文件夹中,而B在Classpath中呢?过程是这样的首先加载A,那么一层层上到Bootstrap Classloader,boot没找到所以ext自己找,找到了,没问题;加载B,因为A调用了B,所以也从bootstrap来找,没找到,然后A的ext classloader来找还是没找到,但是再也不会往下调用了,于是报出ClassNotFoundException。
但是现实生活中有很多应用,比如JDBC核心方法在核心库而驱动在扩展库,是必定在两个地方的,那怎么办呢?要用到Context ClassLoader我们在建立一个线程Thread的时候,可以为这个线程通过setContextClassLoader方法来指定一个合适的classloader作为这个线程的context classloader,当此线程运行的时候,我们可以通过getContextClassLoader方法来获得此context classloader,就可以用它来载入我们所需要的Class。默认的是system classloader。利用这个特性,我们可以“打破”classloader委托机制了,父classloader可以获得当前线程的context classloader,而这个context classloader可以是它的子classloader或者其他的classloader,那么父classloader就可以从其获得所需的 Class,这就打破了只能向父classloader请求的限制了。这个机制可以满足当我们的classpath是在运行时才确定,并由定制的 classloader加载的时候,由system classloader(即在jvm classpath中)加载的class可以通过context classloader获得定制的classloader并加载入特定的class(通常是抽象类和接口,定制的classloader中是其实现),例如web应用中的servlet就是用这种机制加载的.
|