2008年12月31日星期三

踏上2009

时间是个奇怪的东西,刚才还是08年,现在就变成09年,无论你在心里怎么拉也没用。不知不觉一只脚已经踏入2009。

2009我该做些什么?!Mark在这里:
1 论文 没办法,必须在开始的3-4个月完成,包括和论文相关的一个小项目,幸亏有个朋友帮忙。
2 EN 继续完成08年的事。
3 python语言本身没有什么,写出一个有特色的小网站(08年就一直运量)。
4 linux需要加强,mysql(网站必备)。
5 不会仅着眼于软件管理,主要为项目管理。绝对是大头,很枯燥。
6 需要在实践中加强设计能力(基本是废话),工作相关的(java方向)的知识点,如websphere和jboss,以前做项目用了好几年的websphere,还有点留恋(主要想看看集群知识,官方有5个level的集群,有点意思)。

看到自己列出的几点,基本体现自己对2009年的设想,逐渐转向网站方面。1点是必须完成,其实也是和网站相关的应用。3,4可以说也是。2,4不是一绰而就的事,需要全年关注,点滴积累。5其实是最需要花时间和耐心,也是必须面对事实,关注管理。6就是在工作相近的领域充电。

走过2008年

2008年是个不寻常的年头,天灾人祸不断,出现不少炙手可热的keys,艳*照、地震、雪灾、奥运、三鹿、胡*佳、股灾、房价、经济危机、警*察打*死*人等,年尾还有个高级香烟。对我来说没有一个是正面的key,我甚至怀疑这个社会是否能健康发展,这个社会真的“有病”。

2008 对我来说也是值得Mark的年,2003年开始在一家创业公司干了近5年离开,公司基本处于倒闭的边缘,有点悲壮,我不能在耗下去,于是选择离开。这5年的时间对我来说太重要,5年来一直习惯埋头干活,却忘记看路,失去太多,有迷失的感觉。但自己对互联网业还是比较感兴趣,所以放弃好几个不错的职位,以外包的名义来到一家互联网商务公司A。近半年来,虽然没学到多少新知识,但对互联网的认识比以前更加清晰。

来到A公司觉得好似进了一家国企,基本不忙,没有压力,和以前的感觉大不一样,早上上班,下班即可走人,有活(不多)就干,没活就看看自己喜欢的东西。和来之前对这家A公司的印象大不相同。

有个好处就是自己支配的时间比较多,再加上这段时间自己个人的事也比较多,正好合我心意。在闲暇时,补充了一下专业知识,学习了python和 django(其它的扫过,就选择这个)。以及以前(在小公司)从涉及不到的apache、lighttpd、ngnix等,可以说这些都是作网站 (web2.0)必备的。自己也开始使用maven2来构建和搭建开发环境,也正是确定以后开发java应用一定要使用的,加强了一下鸟枪。svn当然必不可少(以前是cvs)。

也看了A公司几个项目的设计,觉得对自己的帮助比较大。越来越感受到设计的过程就是解决问题的过程(如同解方程),由系统的全貌再到系统的局部,一步步的细化,使得问题清晰。可能开始只有大概的轮廓,很粗糙,当把问题分解后,会形成一个个小子域。在这个过程中通常体现在输出的一些设计图(有的叫做架构),能使用幻灯片的方式把解决方案阐述清楚。

其实在设计过程中没有必要特别提出什么架构设计、概要设计、详细设计,设计是没有必要分界限的,它是一个连续的过程,没有必要把这个过程切成3段。

设计的力度一般掌握在模块这一级,没有必要像日本(据说,我没和日本人大过交道),精确到类、方法、甚至是变量的命名,非常恐怖。个人认为只要到模块就可以,一个模块,对外提供服务(接口),也是通过调用其它模块接口获得服务。控制好接口就可以了,至于模块怎么实现,放手让程序员实现,这对他们成长有好处。也就是一些人所说的概要设计这一级,主要针对模块的。当然设计人员需要抽出一些重要的对象(领域对象),不要让程序员胡乱去编造一些领域对象(这在熟悉业务就要达成共识)。但是这种方式本身建立在小组成员的技术素质比较强的基础上。

2008年有遗憾的地方就是我的EN没有达到既定的目标。意外的收获就是python,很是喜欢。

2008年12月30日星期二

节省体力:Eclipse快捷键一览

不知道谁收集的(一个朋友转发给我的),shift+ctrl+l一堆的快捷键,平时也就使用10个。
时不时的瞅下,会有收获。

---------------------------------------------------------------------------------------
Ctrl+1 快速修复(最经典的快捷键,就不用多说了)
Ctrl+D: 删除当前行
Ctrl+Alt+↓ 复制当前行到下一行(复制增加)
Ctrl+Alt+↑ 复制当前行到上一行(复制增加)
Alt+↓ 当前行和下面一行交互位置(特别实用,可以省去先剪切,
再粘贴了)
Alt+↑ 当前行和上面一行交互位置(同上)
Alt+← 前一个编辑的页面
Alt+→ 下一个编辑的页面(当然是针对上面那条来说了)
Alt+Enter 显示当前选择资源(工程,or 文件 or文件)的属性
Shift+Enter 在当前行的下一行插入空行(这时鼠标可以在当前行的任一位置,不一定是最后)
Shift+Ctrl+Enter 在当前行插入空行(原理同上条)
Ctrl+Q 定位到最后编辑的地方
Ctrl+L 定位在某行 (对于程序超过100的人就有福音了)
Ctrl+M 最大化当前的Edit或View (再按则反之)
Ctrl+/ 注释当前行,再按则取消注释
Ctrl+O 快速显示 OutLine
Ctrl+T 快速显示当前类的继承结构
Ctrl+W 关闭当前Editer
Ctrl+K 参照选中的Word快速定位到下一个
Ctrl+E 快速显示当前Editer的下拉列表(如果当前页面没有显示的用黑体表示)
Ctrl+/(小键盘) 折叠当前类中的所有代码
Ctrl+×(小键盘) 展开当前类中的所有代码
Ctrl+Space 代码助手完成一些代码的插入(但一般和输入法有冲突,可以修改输入法的热键,也可以暂用Alt+/来代替)
Ctrl+Shift+E 显示管理当前打开的所有的View的管理器(可以选择关闭,激活等操作)
Ctrl+J 正向增量查找(按下Ctrl+J后,你所输入的每个字母编辑器都提供快速匹配定位到某个单词,如果没有,则在stutes line中显示没有找到了,查一个单词时,特别实用,这个功能Idea两年前就有了)
Ctrl+Shift+J 反向增量查找(和上条相同,只不过是从后往前查)
Ctrl+Shift+F4 关闭所有打开的Editer
Ctrl+Shift+X 把当前选中的文本全部变味小写
Ctrl+Shift+Y 把当前选中的文本全部变为小写
Ctrl+Shift+F 格式化当前代码
Ctrl+Shift+P 定位到对于的匹配符(譬如{}) (从前面定位后面时,光标要在匹配符里面,后面到前面,则反之)

下面的快捷键是重构里面常用的,本人就自己喜欢且常用的整理一下(注:一般重构的快捷键都是Alt+Shift开头的了)
Alt+Shift+R 重命名 (是我自己最爱用的一个了,尤其是变量和类的Rename,比手工方法能节省很多劳动力)
Alt+Shift+M 抽取方法 (这是重构里面最常用的方法之一了,尤其是对一大堆泥团代码有用)
Alt+Shift+C 修改函数结构(比较实用,有N个函数调用了这个方法,修改一次搞定)
Alt+Shift+L 抽取本地变量( 可以直接把一些魔法数字和字符串抽取成一个变量,尤其是多处调用的时候)
Alt+Shift+F 把Class中的local变量变为field变量 (比较实用的功能)
Alt+Shift+I 合并变量(可能这样说有点不妥Inline)
Alt+Shift+V 移动函数和变量(不怎么常用)
Alt+Shift+Z 重构的后悔药(Undo)

编辑
作用域 功能 快捷键
全局 查找并替换 Ctrl+F
文本编辑器 查找上一个 Ctrl+Shift+K
文本编辑器 查找下一个 Ctrl+K
全局 撤销 Ctrl+Z
全局 复制 Ctrl+C
全局 恢复上一个选择 Alt+Shift+↓
全局 剪切 Ctrl+X
全局 快速修正 Ctrl1+1
全局 内容辅助 Alt+/
全局 全部选中 Ctrl+A
全局 删除 Delete
全局 上下文信息 Alt+?
Alt+Shift+?
Ctrl+Shift+Space
Java编辑器 显示工具提示描述 F2
Java编辑器 选择封装元素 Alt+Shift+↑
Java编辑器 选择上一个元素 Alt+Shift+←
Java编辑器 选择下一个元素 Alt+Shift+→
文本编辑器 增量查找 Ctrl+J
文本编辑器 增量逆向查找 Ctrl+Shift+J
全局 粘贴 Ctrl+V
全局 重做 Ctrl+Y


查看
作用域 功能 快捷键
全局 放大 Ctrl+=
全局 缩小 Ctrl+-


窗口
作用域 功能 快捷键
全局 激活编辑器 F12
全局 切换编辑器 Ctrl+Shift+W
全局 上一个编辑器 Ctrl+Shift+F6
全局 上一个视图 Ctrl+Shift+F7
全局 上一个透视图 Ctrl+Shift+F8
全局 下一个编辑器 Ctrl+F6
全局 下一个视图 Ctrl+F7
全局 下一个透视图 Ctrl+F8
文本编辑器 显示标尺上下文菜单 Ctrl+W
全局 显示视图菜单 Ctrl+F10
全局 显示系统菜单 Alt+-


导航
作用域 功能 快捷键
Java编辑器 打开结构 Ctrl+F3
全局 打开类型 Ctrl+Shift+T
全局 打开类型层次结构 F4
全局 打开声明 F3
全局 打开外部javadoc Shift+F2
全局 打开资源 Ctrl+Shift+R
全局 后退历史记录 Alt+←
全局 前进历史记录 Alt+→
全局 上一个 Ctrl+,
全局 下一个 Ctrl+.
Java编辑器 显示大纲 Ctrl+O
全局 在层次结构中打开类型 Ctrl+Shift+H
全局 转至匹配的括号 Ctrl+Shift+P
全局 转至上一个编辑位置 Ctrl+Q
Java编辑器 转至上一个成员 Ctrl+Shift+↑
Java编辑器 转至下一个成员 Ctrl+Shift+↓
文本编辑器 转至行 Ctrl+L


搜索
作用域 功能 快捷键
全局 出现在文件中 Ctrl+Shift+U
全局 打开搜索对话框 Ctrl+H
全局 工作区中的声明 Ctrl+G
全局 工作区中的引用 Ctrl+Shift+G


文本编辑
作用域 功能 快捷键
文本编辑器 改写切换 Insert
文本编辑器 上滚行 Ctrl+↑
文本编辑器 下滚行 Ctrl+↓


文件
作用域 功能 快捷键
全局 保存 Ctrl+X
Ctrl+S
全局 打印 Ctrl+P
全局 关闭 Ctrl+F4
全局 全部保存 Ctrl+Shift+S
全局 全部关闭 Ctrl+Shift+F4
全局 属性 Alt+Enter
全局 新建 Ctrl+N


项目
作用域 功能 快捷键
全局 全部构建 Ctrl+B


源代码
作用域 功能 快捷键
Java编辑器 格式化 Ctrl+Shift+F
Java编辑器 取消注释 Ctrl+\
Java编辑器 注释 Ctrl+/
Java编辑器 添加导入 Ctrl+Shift+M
Java编辑器 组织导入 Ctrl+Shift+O
Java编辑器 使用try/catch块来包围 未设置,太常用了,所以在这里列出,建议自己设置。
也可以使用Ctrl+1自动修正。


运行
作用域 功能 快捷键
全局 单步返回 F7
全局 单步跳过 F6
全局 单步跳入 F5
全局 单步跳入选择 Ctrl+F5
全局 调试上次启动 F11
全局 继续 F8
全局 使用过滤器单步执行 Shift+F5
全局 添加/去除断点 Ctrl+Shift+B
全局 显示 Ctrl+D
全局 运行上次启动 Ctrl+F11
全局 运行至行 Ctrl+R
全局 执行 Ctrl+U


重构
作用域 功能 快捷键
全局 撤销重构 Alt+Shift+Z
全局 抽取方法 Alt+Shift+M
全局 抽取局部变量 Alt+Shift+L
全局 内联 Alt+Shift+I
全局 移动 Alt+Shift+V
全局 重命名 Alt+Shift+R
全局 重做 Alt+Shift+Y

2008年12月27日星期六

使用maven2构建多环境

这种解决办法有别于maven的官方解决方法。


软件的开发,一般有3个环境:开发(dev)、测试(test)、生产(live)。
dev:开发人员在本机上开发,如也许数据库是本机上,log的级别一般在DEBUG;
test:测试专用,完成构建工作,有专门的测试的库(不允许使用生产环境的库),log级别一般在INFO;
live:实际部署的环境。

每种环境有作一些差异,尤其对于dev来说,每个开发人员环境差异就更大,所以每个开发人员都可以配置自己独特的环境。在每种环境下只需要针对该环境配置一次即可,不需要在每次环境切换时修改配置。

这种情况下,使用maven很容易解决上述问题。文字描述比较难懂,还是例子来说话。

下面的工作前提是安装好maven2。在某目录下创建2个工程,这里只是例子组织名以及工程名根据自己喜好设置:
  • mvn archetype:create -DgroupId=com.kiwiyard.shamrock -DartifactId=shamrock-namenode-dal
工程名:shamrock-namenode-dal,后面简称为dal
创建好工程,即创建一个同工程名的目录,所有工程信息都在此目录下,
并自动创建好java的package:com.kiwiyard.shamrock
  • mvn archetype:create -DgroupId=com.kiwiyard.shamrock -DartifactId=shamrock-namenode-service
创建一个shamrock-namenode-service工程,简称为service。

再在此目录下创建一个pom.xml和一个和该项目相关的环境配置文件shamrock.properties(文件名可自己随意取),后面会用到。一切完成后目录的结构如下:

|--shamrock.properties
|--pom.xml
|--shamrock-namenode-dal
****|--pom.xml
|--shamrock-namenode-service
****|--pom.xml

需要说明的是service依赖dal,service和dal都继承一个父pom,就是顶层的pom.xml。

  • 父pom.xml内容如下:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.kiwiyard.shamrock</groupId>
<artifactId>shamrock</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>

<modules>
<module>shamrock-namenode-dal</module>
<module>shamrock-namenode-service</module>
</modules>

</project>


分别到dal和service目录下,创建目录src/main/resources和src/test/resources。到dal的src/main/resources/下创建一个数据库文件datasource.properties,因为在dal里需要访问数据库,这正是我们需要对不同情况处理的。

分别在dal和service的
src/main/resources和src/test/resources下创建log4j.properties的日志配置文件。
  • dal的pom.xml内容如下:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

<parent>
<groupId>com.kiwiyard.shamrock</groupId>
<artifactId>shamrock</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>

<modelVersion>4.0.0</modelVersion>
<artifactId>shamrock-namenode-dal</artifactId>
<packaging>jar</packaging>
<name>shamrock-namenode-dal</name>
<url>http://www.kiwiyard.com</url>

<dependencies>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.2.2</version>
<scope>run</scope>
</dependency>

<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
<scope>run</scope>
</dependency>

<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.13</version>
<scope>run</scope>
</dependency>

<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<directory>${basedir}</directory>
<filters>
<filter>../shamrock.properties</filter>
</filters>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/test/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>

</project>

注意这里的
<directory>${basedir}</directory>
若不加这个配置,很难指向上级目录里的文件,maven对下面的解析就行不通:
<filter>../shamrock.properties</filter>
就解析成:dal工程所在的目录/../shamrock.properties,这个解析有点傻,当然就无法识别。加上上面的配置就可以了,不会出现上面情况。 就这个问题害的我花了不少时间。
  • service的pom.xml内容如下:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

<parent>
<groupId>com.kiwiyard.shamrock</groupId>
<artifactId>shamrock</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>

<modelVersion>4.0.0</modelVersion>
<artifactId>shamrock-namenode-service</artifactId>
<packaging>jar</packaging>
<name>shamrock-namenode-service</name>
<url>http://www.kiwiyard.com</url>

<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>

<dependency>
<groupId>com.kiwiyard.shamrock</groupId>
<artifactId>shamrock-namenode-dal</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>

<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.13</version>
<scope>run</scope>
</dependency>

<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>

</dependencies>

<build>
<directory>${basedir}</directory>
<filters>
<filter>../shamrock.properties</filter>
</filters>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/test/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>

</project>

dal和service的log4j.properties配置内容如下:
log4j.rootCategory=${log4j.level}, stdout
log4j.appender.stdout=${log4j.appender}
log4j.appender.stdout.layout=${log4j.layout}
log4j.appender.stdout.layout.ConversionPattern=${log4j.pattern}

dal的datasource.properties(其实也可以是其它类型的文件如spring的datasource配置文件)。内容如下:
username = ${db.name}
password = ${db.password}
url = ${db.url}
driverClassName = ${db.driver}
#connectionProperties
defaultAutoCommit = true
#defaultReadOnly
#defaultTransactionIsolation
#defaultCatalog
initialSize = ${db.initialSize}
maxActive = ${db.maxActive}
maxIdle = ${db.maxIdle}
minIdle = ${db.minIdle}
maxWait = ${db.maxWait}
#validationQuery
#testOnBorrow
#testOnReturn
#testWhileIdle
#timeBetweenEvictionRunsMillis
#numTestsPerEvictionRun
#minEvictableIdleTimeMillis
poolPreparedStatements = true
maxOpenPreparedStatements = 0

在这里的log4j和datasource的配置是关键,对于${}符号就是变量,是在不同的环境需要替换成和环境匹配的值。这些匹配的值就需要根据每种环境配置,配置文件为
shamrock.properties,内容如下:
#日志配置================================================
log4j.level = DEBUG
log4j.appender = org.apache.log4j.ConsoleAppender
log4j.layout = org.apache.log4j.PatternLayout
log4j.pattern = %5p %c{2}- %m%n

#数据库配置================================================
db.name = 用户名
db.password = 密码
db.url = jdbc:mysql://dev.kiwiyard.com:3306/shamrock?useUnicode=true&characterEncoding=ut8
db.driver = com.mysql.jdbc.Driver
db.initialSize = 2
db.maxActive = 10
db.maxIdle = 8
db.minIdle = 2
db.maxWait = 2

这里配置的就是环境变量,在编译时就根据这些值替换数据库配置和log4j配置。

项目工程的根目录下(就是顶极pom.xml存在的目录下)
#>mvn resources:resources
再到dal和service
工程的target/classes下,看看其datasource.properties和log4j.properties的内容已经被替换。


例子好像很长,
其实就是几个配置文件里一些关键参数需要替换,配置的关键地方用粗题标出。只要你对maven2有一点了解,理解起来就不是难题。这种实现方式个人觉得比官方的对同一文件创建多个针对环境的版本要好,如按官方办法datasource可能就有datasource.dev、datasource.test、datasource.live这么几个文件,显得很罗嗦。

还有若把你的工程放入svn中(99%是这样),最好不要把和环境相关的信息提交到svn上,如开发者A把自己的提交后,开发者B拿到后很可能要修改才能使用,这些配置之适合特定的个体,不要分发出去。如下是一种解决办法,把指向环境配置文件shamrock.properties(以此为例),改为.shamrock.properties(注意文件名前加了一个点)。
<filter>../shamrock.properties</filter>
=>
<filter>../.shamrock.properties</filter>
shamrock.properties是受svn版本控制的,他代表一些配置的共性,也可能是由项目主管提交的一份参考配置。

其它开发人员拿到shamrock.properties后,cp
shamrock.properties .shamrock.properties,自己所有的配置就可以在.shamrock.properties上改动,不用把该文件提交到svn上,所有人的环境配置都在本地,不会找成混乱


官方的另外一种方式,你可以参考对照2种方式:
http://maven.apache.org/guides/mini/guide-building-for-different-environments.html

2008年12月26日星期五

ubuntu下的词典:StartDICT星际译王

就这名字实在太...那个啥。

安装星际软件
#sudo apt-get install stardict
已经安装一个简明英汉词典,够用了。

只有在选中一个词时,才显示解释,有时屏幕取词死活不出来(2次取词之间若取同一个词,第二次出不来,可能有意为之),有点小问题。

还有短文翻译,但驴头不对马嘴,一头雾水。

2008年12月25日星期四

在linux下安装MySQLdb

想试用一下django,使用到mysql,需要安装MySQLdb模块,才能访问数据库,linux是ubuntu。

1 下载:http://sourceforge.net/project/showfiles.php?group_id=22307
下载的文件为:MySQL-python-1.2.2.tar.gz

2 安装
先安装一个包(就这个问题把我折磨半天):
#sudo apt-get install libmysqlclient15-dev

#tar zxvf MySQL-python-1.2.2.tar.gz
#cd MySQL-python-1.2.2
#vi site.cfg
在安装libmysqlclient15-dev时会产生一个文件mysql_config,需要在此配置文件里指明(去掉前面的注释,把值设为下面的值):
mysql_config = /usr/bin/mysql_config

#sudo python ./setup.py build
#sudo python ./setup.py install
完成。

3 试用一下
#python
Python 2.5.2 (r252:60911, Oct 21 2008, 19:50:08)
[GCC 4.2.3 (Ubuntu 4.2.3-2ubuntu7)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import MySQLdb
>>>

一切OK!!!

4 补记
我估计另外一种安装可能更方便。
#sudo apt-get install libmysqlclient15-dev
#sudo apt-get install python-mysqldb
一开始就apt-get安装python-mysqldb,装完后却不能用,可能是由于没有安装libmysqlclient15-dev有关。
所以就转到源码安装,也错误一堆,现在想想都是没有安装libmysqlclient15-dev引起的。按照上面的步骤安装好后,可以使用了,就没有尝试apt-get install python-mysqldb是否也好使,你可以试试apt-get安装,若不行的话,转到源码安装。


没想到一个小安装问题,花了4个小时,网上的一些类似问题眼花缭乱,但适用的不多,但有时能寻到一些蛛丝马迹,就是费时。

互联网相关的几张拓扑图

放大观看,疑似繁星点点:
看到光纤就知道,中国还需多努力,接入点似乎只有香港和上海,老M是世界中心啊:
再看看老M的:

以前记得一个网站可查到比较新的internet的结构,这个网站一直在探测internet结构,现在找不到了,郁闷!

2008年12月24日星期三

支付宝终于要收费了

据称每月使用相关服务超过5000元,超过部分会收取一定的费用。这对大部分“散户”(据说是99.99%)的确没有影响,但对于依靠Taobao、alipay经营的个人和商家来说要割点肉。

alipay收费了,taobao还会远吗?!!

在这之前阿里的taobao(淘宝)和alipay(支付宝)这2大平台一直采用免费策略,不是没有商务模式,而是不敢。一旦收费其它电子商务平台就会看到机会,taobao凭借免费干掉易趣(ebay),别来个XXX干掉Taobao。

taobao借助alipay打造一个具有绝对优势的交易平台。但就这么2个活宝,对阿里巴巴来说是“负债”经营,但也是最吸引眼球的2个平台。巨大的交易量和垄断性的用户群,足以使CV疯狂。老马豪言:阿里不缺钱(储备了XX亿)!!!

收费是不是上市的号角?但如果要作一个上市公司,没有盈利会死的很惨,上市之前使公司盈利这是非常关键的事。

相信不久的将来Taobao和alipay都会上市!!!

2008年12月23日星期二

java和json

  • json是一个数据表示协议,或数据格式,如同xml一样。协议参看:http://www.json.org/。
  • 基本所有的语言都支持json,java有很多实现,请参看:http://www.json.org。我这里用的是json-lib(http://json-lib.sourceforge.net/),并不是org.json。
  • 创建测试代码
创建2个java数据类(google会把格式给干掉了,请复制出并用ide格式化后阅读),一般是用于传输
User.java,类容如下:
import java.io.Serializable;
public class User implements Serializable{
private static final long serialVersionUID = -8604848876542493025L;

private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}

CpxUser.java类内容:
import java.io.Serializable;
import java.util.Date;

public class CpxUser implements Serializable{
private User user;
private int age;
private String nickname;
private Date birDay;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
public Date getBirDay() {
return birDay;
}
public void setBirDay(Date birDay) {
this.birDay = birDay;
}
}

Test.java类内容:
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

public class Test {
/**
* @param args
*/
public static void main(String[] args) {
System.out.println("1.简单对象->json");
User u = new User();
u.setUsername("zzz");
u.setPassword("hhhh");
JSONObject jo = JSONObject.fromObject(u);
System.out.println(jo.toString());

System.out.println("2.map->json (结果和1一样)");
Map mu = new HashMap();
mu.put("username", "zzz");
mu.put("password", "hhhh");
JSONObject jo1 = JSONObject.fromObject(mu);
System.out.println(jo1.toString());

System.out.println("3.复杂对象->json");
CpxUser cpxUser = new CpxUser();
cpxUser.setUser(u);
cpxUser.setAge(26);
cpxUser.setNickname("a chu");
cpxUser.setBirDay(new Date());
JSONObject jo2 = JSONObject.fromObject(cpxUser);
System.out.println(jo2.toString());

System.out.println("4.json->复杂对象 (可以debug看对象内容)");
String json_str = jo2.toString();
CpxUser cpxUser1 = (CpxUser)JSONObject.toBean(jo2, CpxUser.class);
System.out.println(cpxUser1.getAge());

System.out.println("5.简单对象数组->json");
User u1 = new User();
u1.setUsername("zzz1");
u1.setPassword("hhhh1");
User u2 = new User();
u2.setUsername("zzz2");
u2.setPassword("hhhh2");
User[] users = new User[]{u1,u2};
JSONArray arrs = JSONArray.fromObject(users);
System.out.println(arrs.toString());
}
}
  • 输出结果
非常简单,无需多说:

1.简单对象->json
{"username":"zzz","password":"hhhh"}

2.map->json (结果和1一样)
{"username":"zzz","password":"hhhh"}

3.复杂对象->json
{"nickname":"a chu","age":26,"birDay":{"time":1230096693386,"minutes":31,"seconds":33,"hours":13,"month":11,"year":108,"timezoneOffset":-480,"day":3,"date":24},"user":{"username":"zzz","password":"hhhh"}}

4.json->复杂对象 (可以debug看对象内容)
26

5.简单对象数组->json
[{"username":"zzz1","password":"hhhh1"},{"username":"zzz2","password":"hhhh2"}]


可以看出Java处理json非常简单,转换自如,相对xml描述精简很多,尤其在网络传输具有非常大的优势。java json包也非常轻量级,尤其是org.json(很遗憾该例没有使用该包)共有15个类,没有依赖,可以把源码放入工程。

注:不太喜欢org.json的实现,json-lib更面向对象,符合程序员的编码习惯(从上边的例子可以看出),缺点是依赖其它包。

2008年12月22日星期一

google报一个奇怪的错误

在使用google时突然出现一个错误页面:

扫描病毒并删除cookie后还是一样,不知道google吃错了什么药,认定我是软件请求,我用的是firefox,结果我换成google浏览器和IE还是一样。

情况少见。

2008年12月19日星期五

maven2创建一个eclipse工程,设置M2_REPO

用maven创建一个支持eclipse的工程非常简单,在mvn的项目目录下:
mvn eclipse:eclipse
即可。

再打开eclipse->import->General:Existing Projects into Workspace->包含该工程的目录,eclipse会自动搜寻到刚刚创建的eclipse工程。

导入工程后会发现eclipse报"找不到M2_REPO"的错误,其实这是个环境变量,就是指向你的本地库。在linux和windows下都是$HOME/.m2/repository

把该变量加入eclipse,方法为:
Window -> Preferences -> Java -> Build Path -> Classpath Variables
-> New,Name输入M2_REPO,Path输入/home/名用户/.m2/repository(以我的为例)。确认后错误消失。

2008年12月18日星期四

Spring配置中的引用

在实际的项目中bean之间引用非常普片,该项目有数十个Spring配置,相互引用也比较复杂,列出几个:





看得有点乱,方式还真多(不知道还有没有遗漏)。
ref bean="":这种格式是引用其它bean,该bean的定义可能存在其它配置文件中(同一个Spring容器中)或本文件中(如上2)。

ref local="" :只能引用同以文件中定义的Bean,初始化的时候同时检测(如上1、5)。

对于在属性或构造器等引用,写法有差别,但都是使用的ref bean=""(如上3和4,3和4是等价)。

idref的local、bean与ref同样的情况。但idref的输出不是一个bean的实例,仅仅是一个字符串,和你写一个字符常量没什么区别。但是idref一个好处就是,他会检查这个bean是否存在,若不存在会报错,若该bean存在才给出该bean的ID。

idref有用吗?!我看没用。

local有用吗?!似乎有点用,也是官方推荐的,在某些人认为太有用了,其实没有也不是一个天大的事。ref bean="bBean"一定要得。

2008年12月17日星期三

youku正式进军视频门户

今天打开youku,点击一个视屏进入youku的资讯中心,眼前一亮,还以为在浏览sina、yahoo等门户网站。这也表明youku正式进军视频门户,野心不小。不出意外国内老牌的门户会跟风,就像现在他们正在推出视频频道一样。

未来传统的媒体,如那个CCTV,我觉得都会遭到互联网的侵袭(现在已经开始),视频门户很有前途,广告也会大量从传统模式走向网络。未来一定会诞生网络版的CCTV,是不是youku就不得知。

近来诞生的视频网站如雨后春笋,但由于高昂的运维费用,缺乏商务模式,再加上经济不景气,会死掉一批。希望youku能挺过去。

我看好youku的这一步。

Show一张截图,Mark一下:

2008年12月15日星期一

顶级动态DNS解析

在网上搜了一下申请固定IP费用确实惊人,于是就转向动态域名解析,由于我的域名是在万网上申请,用Oray可定不行,是不同的2家域名注册商,除非包我的域名迁出到Oray,这是我不愿干的事。但是在网上搜索出一条有用的信息,试试还可以,暂时用用。

先申请Oray的免费域名如 OK.XCIP.NET,然后在万网那边的域名 设置CNAME 指向OK.XCIP.NET,最后启动你的花生壳客户端即可。

路径是这样的:
互联网用户 -> 访问万网的域名 -> 万网自动跳转到OK.XCIP.NET由Oray的DNS服务解析 -> 跳转到花生壳绑定的IP(也就是你的PC)

2008年12月12日星期五

mysql初步记录

1 在ubuntu上一般默认就安装好mysql,可以在命令行
$mysql
试试,若进入mysql控制台说明已经安装。我的输出信息如下:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 9
Server version: 5.0.51a-3ubuntu5.1 (Ubuntu)

2 若没有安装,在ubuntu下安装软件是件愉悦的事:
$sudo apt-get install mysql
不再多说。

3 启停
/etc/init.d/mysql stop|start|restart
或 sudo /usr/sbin/mysqld

4 修改root密码
参看:http://www.linuxdiyf.com/bbs/thread-104290-1-8.html
下面的简要引述。
登录到安全模式下:
$sudo /etc/init.d/mysql stop
$sudo mysqld_safe --user=mysql --skip-grant-tables --skip-networking &
$sudo mysql -u root mysql
mysql> UPDATE user SET Password=PASSWORD('新密码') where USER='root';
mysql> FLUSH PRIVILEGES;
mysql> quit

# /etc/init.d/mysql restart
# mysql -u root -p
Enter password:
以root身份登录到控制台。

5 修改权限
mysql> GRANT ALL PRIVILEGES ON *.* TO root@localhost;
给root用户付所有权限,也可以使用
GRANT ALL PRIVILEGES ON *.* TO root@localhost IDENTIFIED BY "新密码";
赋值和修改密码。

6 创建一个用户以及库
mysql>create database 库名;
mysql>GRANT ALL PRIVILEGES ON 库名.* TO 用户名@localhost IDENTIFIED BY "密码";
或下面语句,给予从其它机器上执行的权力:
mysql>GRANT ALL PRIVILEGES ON 库名.* TO 用户名@"%" IDENTIFIED BY "密码";

7 一些常用的命令
mysql>show engines;
#显示支持哪些存储引擎
mysql>show databases;
mysql>use 库名;
mysql>create database 库名;
mysql>drop database 库名;

mysql>create table 表名 engine=
mysql>show tables;
mysql>desc 表名; 或 describe 表名
#查看表的元信息
mysql>load '文件';
#执行文件里的sql(批量执行)

创建表时后面加上 ENGINE=InnoDB 或 Type=InnoDB,指定该表使用InnoDB存储引擎,默认是使用MyISAM,不支持事务。
也可以使用 alter table engine=InnoDB 或 MyISAM

8 配置
mysql默认安装在/etc/mysql下,主要配置文件my.cnf也是在此目录下。
需要修改的并不多,处于优化和定制目的,可能需要修改的列出如下:

#使得远程机器也能访问,活指定一个具体地址
bind-address = 0.0.0.0

#指定数据存放的目录(建议把数据文件存放在不同的物理分区上,会得到更好的性能)
innodb_data_home_dir = /ibdata
innodb_data_file_path=ibdata1:50M;ibdata2:50M:autoextend:max:500M
innodb_data_file_path=ibdata1:50M;ibdata2:50M:autoextend:max:1G
还有些和innodb相关的参数。
请参考详细的参数的含义:
http://dev.mysql.com/doc/refman/5.1/zh/storage-engines.html#innodb-init

注:默认的一些数据文件存放在/var/lib/mysql/下,如ibdata1是数据文件,ib_logfile0、ib_logfile1为日志文件。


9 参考
更多参考手册:
http://dev.mysql.com/doc/refman/5.1/zh/index.html

2008年12月9日星期二

用maven构建一个小型的复杂项目

若你还对maven2不太了解,快速获得一些信息。
http://maven.apache.org/guides/getting-started/index.html

本来想写个多个工程的项目,写了一点发现和“getting-started”的“How do I build more than one project at once?”类似(只不过是10来个工程的项目),所以作罢。


--------------------------------------------------------------------------
在某个目录下创建工程

mvn archetype:create -DgroupId=com.kiwiyard.shamrock -DartifactId=shamrock-clientSDK-java
工程名:
shamrock-clientSDK-java
创建好工程,创建一个目录同工程名,
并自动创建好java的package:com.kiwiyard.shamrock
在package下还有一个测试类,基本没用直接删除。



构建多个项目可以参考下面的文章,还可以实现不同的环境:

使用maven2构建多环境

Stripes,一个不错的web框架

Stripes一个和JSF很类似,但比JSF轻量多了。以前使用过JSF开发过,比较喜欢事件触发和绑定,相对于struts等是一个进步,不用再每次获得ActionForm,一坨的form.get.....,再set到具体的数据对象。但jsf过于厚重,并且其tag异常难用。

Stripes使得写页面变得简单,不再有恼人的处理表单,抛弃那些如struts的配置文件,关注你的业务吧。若你使用jsf开发过,这个基本就小菜。
简要介绍
http://www.theserverside.com/tt/articles/article.tss?track=NL-461&ad=679286&l=Stripes15&asrc=EM_NLN_5242511&uid=5665674
官方
http://www.stripesframework.org/display/stripes/Home

注:好久没关注java相关的东西,以为这是个新出来的框架,没想到出来有段时间。

ubuntu下替换jdk

发现ubuntu自带安装的jdk是1.5,现在需要安装一个jdk1.6,有个很简单的方法。
1 安装jdk1.6
$sudo apt-get install sun-java6-jdk
一般需要30分钟。

2 配置
$sudo update-alternatives --config java
选择安装的jdk6即可,看图便知:


已经设置成1.6。

2008年12月8日星期一

构建公司的maven私服中心

1 在windows下搭建
1.1 下载apache-maven-2.0.9
配置环境变量,我是直接放在c盘下,变量及其值如下:
mvn_home C:\apache-maven-2.0.9
Path .;%mvn_home%\bin #添加的信息
打开命令窗口,键入:mvn -v,若出现版本信息,则配置成功。

1.2 下载安装nexus
到http://nexus.sonatype.org/downloads/下载nexus-1.1.1-bundle.zip,解压后会产生一个目录nexus-webapp-1.1.1sonatype-work。到该目录下的\bin\jsw\windows-x86-32里,双击InstallNexus.bat安装,把nexus添加到服务里去,每次系统启动后就启动nexus服务。
双击Nexus.bat运行该服务,要30秒的样子。

1.3 访问
http://localhost:8081/nexus/index.html
管理的用户:admin
默认密码:admin123
登陆后修改此信息。

1.4 配置nexus
选择Administrator下的Repositories,如图:


在3个中心代理库分别:右键->reindex,并把这3个库的属性“Download Remote Indexes”,设置为“True”。
说明:我们正在建的库就是代理上面设置的3个库,一般一个公司搭建一个这样的中心库即可,避免开发人员乱下载包,造成项目混乱。若在该“公司中心库”没找到的自动到远程库下载。

1.5 配置mvn
个人开发者的本地库是在$HOME/.m2/repository下,若你不做任何设置,maven会自动从远程库加载依赖的包,不会从“公司中心库”加载。为了速度也是为了开发上的管理,要求必须切只能从“公司中心库”加载依赖包到本地库。设置如下:
在.m2目录下添加文件settings.xml,内容如下(google不能贴xml,改下载文件):
https://sites.google.com/site/zhuxuezheng/fen-xiang-haha
注:把里面的所有的localhost改写为前面搭建“公司中心库”的服务ip(即按装nexus的机器)。

1.6 尝试
在你的机器上,某个目录下运行:
mvn archetype:create -DgroupId=org.xyz.app1 -DartifactId=simple -DpackageName=org.xyz.app1
是不是从服务器下载东西,注意看日志。

再到中心库的sonatype-work目录下,看看其sonatype-work\nexus\storage\central-m1下是否下载了很多。你的本地库的包就是从此来,由公司中心库代理下载。所有的程序员都从此下载包,公司内部速度当然有保障。

可再访问,选择Browse Repositories,挨个Repositorie点击看看,maven central会有很多。
http://localhost:8081/nexus/index.html


2 在ubuntu下搭建
2.1 安装maven2
若输入$ mvn -v 没有任何版本信息,则说明没有安装:
sudo apt-get install maven2
$ mvn -v 会有版本信息输出。

2.2 安装nexus
到http://nexus.sonatype.org/downloads/下载nexus-1.1.1-bundle.tar.gz。
详细的具体配置参看(《maven权威指南》),不一定会成功,若不成功请参考我在下面写得:
http://books.sonatype.com/maven-book/reference_zh/repository-manager.html

这里做简要叙述。
在某个目录下解压(我的是$HOME/tools/) $ tar xvzf nexus-1.0.0-beta-3-bundle.tgz,产生nexus-wepapp-1.1.1和sonatype-work目录。nexus-wepapp-1.1.1/bin/jsw/linux-x86-32/nexus start,启动nexus,但出错:
NO JSP Suport for /nexus, did not find org.apache.jasper.servlet.JspServlet以及io等等一堆错误。
反复尝试各种方法都不行,后来把nexus-1.0.0-beta-3-bundle.tgz复制到windows下,解开运行,完全可以。一时很费解,大半天就这样溜走。无意中发现我的windows上是jdk6,而ubuntu是自带的jdk5,于是就在ubuntu上再install一个jdk6,好开始:
$sudo apt-get install sun-java6-jdk
时间比较长等。
安装完毕,把系统默认的jdk5设置成jdk6,只需一个命令即可:
$sudo update-alternatives --config java
选则sun-java6,就是刚装的。

这时再运行nexus,好使了,都说nexus 10分钟就能搭好,我费了10小时,呵呵。

总算好了,赶快试试:
http://localhost:8081/nexus/

2.3 设置一下
不能老去安装目录下运行,如:/home/.../nexus start|stop,设置一个简单的方法。如:
$cd /usr/bin
$sudo ln -s /home/用户名/tools/nexus-webapp-1.1.1/bin/jsw/linux-x86-32/nexus nexus
这样做了个连接,以后不管在那个目录下就可以使用:
$nexus start|stop

后面的操作就和windows一样。

2008年12月7日星期日

svn server配置记录

前面安装了apache2,现在就用上了。
请参看:http://zhuxuezheng.blogspot.com/2008/12/apache2.html

1.安装subversion(ubuntu一般自带就安装好了)
sudo apt-get install subversion

2.使用套件
sudo apt-get install libapache2-svn

3.建立svn仓库(svn server端)
sudo svnadmin create /work/svnrepos/shamrock
这里在目录/work/svnrepos/下创建一个svn库shamrock。以后可以在svnrepos下创建更多的库,所有的都集中在svnrepos下,好管理。对一个公司来说规划版本库也是一项小的工作,非常有必要。

4.设置权限
这里的对版本库的权限要和apache2的用户权限一样(是文件/etc/apache2/envvars里配置的),要不然会报权限错误。apache2是www-data:www-data,
所以在svnrepos目录下执行sudo chown -R www-data:www-data shamrock

5.配置apache2
编辑/etc/apache2/下的httpd.conf(其实修改apache2.conf是一样的,但这样作更好点),这个文件默认是空的。添加的内容如下:


这里最好使用SVNParentPath,指向/work/svnrepos,以后访问库时,可统一使用url为:http://ip/svn/库名,不用每个库都配置一个url。
例如访问shamrock库:http://ip/svn/shamrock。

6.访问svn用户
上图你可能已经注意到
AuthUserFile /etc/subversion/passwd

这个文件是没有的,创建passwd文件,用来存放访问svn的用户名和密码。
执行命令sudo /usr/local/apache2/htpasswd /etc/subversion/passwd [在此输入用户名]
回车后输入密码。多次使用创建多个帐号。

7.启动apache2
sudo /etc/init.d/apache2 restart

访问
http://localhost/svn/shamrock

8.结构化库
在某一目录(如home)下执行svn co http://localhost/svn/shamrock
发现server上的shamrock被checkout(上面的co就是checkout)到本地。
到shamerock下,执行
svn mkdir trunk
svn mkdir branches
svn mkdir tags

再刷新http://localhost/svn/shamrock页面,是不是已经看到这个结构。
操作完home下的shamrock就可以删除了。其余的事情就是开发了。

apache2配置记录

系统为ubuntu

1.安装apache2
sudo apt-get install apache2
安装的目录在/etc/apache2下,配置文件apache2.conf。
在conf.d目录下,存在charset文件,可把设置编码,如:AddDefaultCharset UTF-8

日志文件在/var/log/apache2下,注意log文件的一定有可写权限。

/etc/apache2/envvars文件是一些环境参数,看看内容就知道:
export APACHE_RUN_USER=www-data
export APACHE_RUN_GROUP=www-data
export APACHE_PID_FILE=/var/run/apache2.pid

注:若想修改这些信息,就在这些文件里修改。

2.启动
sudo /etc/init.d/apache2 restart|start|stop

3.http://localhost/
出现It works!页面即表示正常运行。
看到的这个页面是在/var/www下的index.html。


不用配置任何即可使用。

运行起来后可使用命令查看进程信息:
ps -ef|grep apache2