My studying notes for Java,Ruby,Ajax and other any interesting things.

星期五, 十二月 19, 2008

[fwd]Vim对中文编码的支持

1、支持中文编码的基础

Vim要更好地支持中文编码需要两个特性:+multi_byte和+iconv,可以用|:version|命令检查当前使用的Vim是否支持,否则的话需要重新编译。

2、影响中文编码的设置项

Vim中有几个选项会影响对多字节编码的支持:

  • encoding(enc):encoding是Vim的内部使用编码,encoding的设置会影响Vim内部的Buffer、消息文字等。在Unix环境下,encoding的默认设置等于locale;Windows环境下会和当前代码页相同。在中文Windows环境下encoding的默认设置是cp936(GBK)。
  • fileencodings(fenc):Vim在打开文件时会根据fileencodings选项来识别文件编码,fileencodings可以同时设置多个编码,Vim会根据设置的顺序来猜测所打开文件的编码。
  • fileencoding(fencs) :Vim在保存新建文件时会根据fileencoding的设置编码来保存。如果是打开已有文件,Vim会根据打开文件时所识别的编码来保存,除非在保存时重新设置fileencoding。
  • termencodings(tenc):在终端环境下使用Vim时,通过termencoding项来告诉Vim终端所使用的编码。

3、Vim中的编码转换

Vim内部使用iconv库进行编码转换,如果这几个选项所设置的编码不一致,Vim就有可能会转换编码。打开已有文件时会从文件编码转换到encoding所设置的编码;保存文件时会从encoding设置的编码转换到fileencoding对应的编码。经常会看到Vim提示[已转换],这是表明Vim内部作了编码转换。终端环境下使用Vim,会从termencoding设置的编码转换到encoding设置的编码。

可以用|:help encoding-values|列出Vim支持的所有编码。

4、具体应用环境的设置

  • 只编辑GBK编码的文件

set fileencodings=cp936
set fileencoding=cp936
set encoding=cp936

  • 只编辑UTF-8编码的中文文件

set fileencodings=utf-8
set fileencoding=utf-8
set encoding=cp936 或者 set encoding=utf-8

  • 同时支持GBK和UTF-8编码

set fileencodings=ucs-bom,utf-8,cp936
set fileencoding=utf-8
set encoding=cp936 或者 set encoding=utf-8

  • 如果在终端环境下使用Vim,需要设置termencoding和终端所使用的编码一致。例如:

set termencoding=cp936 或者 set termencoding=utf-8

Windows记事本编辑UTF-8编码文件时会在文件头上加上三个字节的BOM:EFBBBF。如果fileencodings中设置ucs-bom的目的就是为了能够兼容用记事本编辑的文件,不需要的话可以去掉。Vim在保存UTF-8编码的文件时会去掉BOM。去掉BOM的最大好处是在Unix下能够使用cat a b>c来正确合并文件,这点经常被忽略。

5、FAQ

  1. 为什么在Vim中一次只能删除半个汉字?

    因为encoding设置错误,把encoding设置为cp936就可以解决此问题。在Unix环境下Vim会根据locale来设置默认的encoding,如果没有正确设置locale并且没有设置encoding就会一次只能删除半个汉字。

  2. VIM为什么不能输入繁体字?

    把euc-cn或者GB2312改为cp936就可以了。euc-cn是GB2312的别名,不支持繁体汉字。cp936是GBK的别名,是GB2312的超集,可以支持繁体汉字。

  3. VIM为什么提示不能转换?

    因为在编译Vim时没有加入iconv选项,重新编译Vim才能解决。

  4. 如何打开一个GBK编码的文件并另存为UTf-8编码?

    保存文件时运行命令|:set fileencoding=utf-8|就可以了。
     

星期二, 十二月 16, 2008

[Java]链接数据库的方式总结

1、Oracle8/8i/9i数据库(thin模式)
Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();
String url="jdbc:oracle:thin:@localhost:1521:orcl";
//orcl为数据库的SID
String user="test";
String password="test";
Connection conn= DriverManager.getConnection(url,user,password);
 
2、DB2数据库
Class.forName("com.ibm.db2.jdbc.app.DB2Driver ").newInstance();
String url="jdbc:db2://localhost:5000/sample";
//sample为你的数据库名
String user="admin";
String password="";
Connection conn= DriverManager.getConnection(url,user,password);
 
3、Sql Server7.0/2000数据库
Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver").newInstance();
String url="jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=mydb";
//mydb为数据库
String user="sa";
String password="";
Connection conn= DriverManager.getConnection(url,user,password);
 
4、Sybase数据库
Class.forName("com.sybase.jdbc.SybDriver").newInstance();
String url =" jdbc:sybase:Tds:localhost:5007/myDB";
//myDB为你的数据库名
Properties sysProps = System.getProperties();
SysProps.put("user","userid");
SysProps.put("password","user_password");
Connection conn= DriverManager.getConnection(url, SysProps);
 
5、Informix数据库
Class.forName("com.informix.jdbc.IfxDriver").newInstance();
String url =
"jdbc:informix-sqli://123.45.67.89:1533/myDB:INFORMIXSERVER=myserver;
user=testuser;password=testpassword";
//myDB为数据库名
Connection conn= DriverManager.getConnection(url);
 
6、MySQL数据库
Class.forName("org.gjt.mm.mysql.Driver").newInstance();
String url ="jdbc:mysql://localhost/myDB?user=soft&password=soft1234&useUnicode=true&characterEncoding=8859_1"
//myDB为数据库名
Connection conn= DriverManager.getConnection(url);
 
7、PostgreSQL数据库
Class.forName("org.postgresql.Driver").newInstance();
String url ="jdbc:postgresql://localhost/myDB"
//myDB为数据库名
String user="myuser";
String password="mypassword";
Connection conn= DriverManager.getConnection(url,user,password);

星期三, 八月 06, 2008

菜鸟编程的十大好习惯



假如你和我一样是一只正在学习编程的菜鸟,那么下面的十个好习惯与你共勉之。
  1、设计规划

  现在是模块化程序设计的天下,应用程序要实现的目标就是金字塔尖,进行程序设计规划的意义就在于,对构成金字塔的基础模块进行划分,规划得越详细,模块分工越明确,越容易明白下一步该做什么,这好比搭积木的游戏,你可以把你的积木块组合成各种各样的形状,但首先要熟悉每个积木块的功能。

  2、有备无患

  实战之前,先找几个样例程序研究研究,最起码明白怎么开头,怎么结尾,别打无准备之仗。

  3、葵花宝典

  做一份所用程序语言的精简列表,包括基本数据类型、各类运算符说明、基本语句结构、常用关键词(保留字)、常用函数(控件)说明等等。

  4、自由独立

  为你的应用程序建立一个单独的目录,这样既方便应用程序文件的管理,而且如果你要给程序搬“家”,卷起铺盖就可以走人了。

  5、见名知意

  程序再小,用的变量也不会少,变量起名应当见名知意是个老话题了,好处是显而易见的。推荐程序员使用“匈牙利命名法”,它会使你的起名工作变得轻而易举,而且相当专业。

  6、对称之美

  中国人讲究对称之美,用在编程里也很合适,如果程序里用到A循环嵌套B判断,B判断又包含C循环之类的结构,记着使用缩进法,让A:ENDDO对齐A:ENDDO,B:ENDIF对齐B:IF……诸如此类,依次缩进,总之对称就等于美观加易读。

  7、多加注解

  对程序中自定义的变量、函数、子程序加以功能性的注释说明,别嫌麻烦。如果过了三月五月,连自己写的东西都看不明白了,那才大麻烦。

  8、环境保护

  如果应用程序需要修改系统设置,记着应用开始前先保存设置,应用结束后要恢复设置,千万别污染环境。

  9、拿来主义

  一个人的力量是有限的,大家的力量是无限的,平时多看看《中国电脑教育报》,如果碰巧有好的经验,巧的方法,用得上的段子,不妨拿来。

  10、忍者无敌

  当你认为程序代码写的“百分百”正确,而程序编译执行百分百有毛病,你基本属于晕菜的时候,千万要忍,歇口气,重头来,别放弃!相信最终的胜利是属于你的!

星期二, 八月 05, 2008

PHP中使用GD生成水印图片



  header ("Content-type: image/png");

  $logoImage = ImageCreateFromPNG('test.png');

  $photoImage = ImageCreateFromJpeg('back.jpg');

  ImageAlphaBlending($photoImage, true);

  $logoW = ImageSX($logoImage);

  $logoH = ImageSY($logoImage);

  ImageCopy($photoImage, $logoImage, 0, 0, 0, 0, $logoW, $logoH);

  ImageJPEG($photoImage); // output to browser

  ImageDestroy($photoImage);

  ImageDestroy($logoImage);

发现PHP出奇的强大和简单.

星期六, 七月 19, 2008

Linux内核优化 sysctl.conf



linux内核优化
来源: ChinaUnix博客   作者: 发布时间:2007-01-01


sysctl.conf 优化
The sysctl.conf of a server is something that is seldom optimized for
performance. You can get a tremendous boost in throughput by adjusting
these settings. This configuration has been written by Steve from
Rack911. I have applied this configuration to servers ranging from
Celeron 1.7Ghz to Dual Xeon 2.8Ghz servers, and on the whole, the load
on each lowered after making the changes.
First make a backup of your old /etc/sysctl.conf file by running the following command, logged in as root:
cp /etc/sysctl.conf /etc/sysctl.conf.bak
Now enter:
pico /etc/sysctl.conf
and replace the contents of the file with the following:
# Kernel sysctl configuration file for Red Hat Linux
#
# For binary values, 0 is disabled, 1 is enabled. See sysctl(8) and
# sysctl.conf(5) for more details.
# Disables packet forwarding
net.ipv4.ip_forward=0
# Disables IP source routing
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.lo.accept_source_route = 0
net.ipv4.conf.eth0.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0
# Enable IP spoofing protection, turn on source route verification
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.lo.rp_filter = 1
net.ipv4.conf.eth0.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
# Disable ICMP Redirect Acceptance
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.lo.accept_redirects = 0
net.ipv4.conf.eth0.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
# Enable Log Spoofed Packets, Source Routed Packets, Redirect Packets
net.ipv4.conf.all.log_martians = 0
net.ipv4.conf.lo.log_martians = 0
net.ipv4.conf.eth0.log_martians = 0
# Disables the magic-sysrq key
kernel.sysrq = 0
# Decrease the time default value for tcp_fin_timeout connection
net.ipv4.tcp_fin_timeout = 15
# Decrease the time default value for tcp_keepalive_time connection
net.ipv4.tcp_keepalive_time = 1800
# Turn off the tcp_window_scaling
net.ipv4.tcp_window_scaling = 0
# Turn off the tcp_sack
net.ipv4.tcp_sack = 0
# Turn off the tcp_timestamps
net.ipv4.tcp_timestamps = 0
# Enable TCP SYN Cookie Protection
net.ipv4.tcp_syncookies = 1
# Enable ignoring broadcasts request
net.ipv4.icmp_echo_ignore_broadcasts = 1
# Enable bad error message Protection
net.ipv4.icmp_ignore_bogus_error_responses = 1
# Log Spoofed Packets, Source Routed Packets, Redirect Packets
net.ipv4.conf.all.log_martians = 1
# Increases the size of the socket queue (effectively, q0).
net.ipv4.tcp_max_syn_backlog = 1024
# Increase the tcp-time-wait buckets pool size
net.ipv4.tcp_max_tw_buckets = 1440000
# Allowed local port range
net.ipv4.ip_local_port_range = 16384 65536
CTRL + X to exit and save the file
To make your changes take effect immediately, type this command:
/sbin/sysctl -p
引用自:FreeBSD下构建安全的Web服务器
作者:heiyeluren http://www.unixsky.net
编辑 /etc/sysctl.conf 文档,在里面加入如下内容:(有注释)
#最大的待发送TCP数据缓冲区空间
net.inet.tcp.sendspace=65536
#最大的接受TCP缓冲区空间
net.inet.tcp.recvspace=65536
#最大的接受UDP缓冲区大小
net.inet.udp.sendspace=65535
#最大的发送UDP数据缓冲区大小
net.inet.udp.maxdgram=65535
#本地套接字连接的数据发送空间
net.local.stream.sendspace=65535
#加快网络性能的协议
net.inet.tcp.rfc1323=1
net.inet.tcp.rfc1644=1
net.inet.tcp.rfc3042=1
net.inet.tcp.rfc3390=1
#最大的套接字缓冲区
kern.ipc.maxsockbuf=2097152
#系统中允许的最多文档数量
kern.maxfiles=65536
#每个进程能够同时打开的最大文档数量
kern.maxfilesperproc=32768
#当一台电脑发起TCP连接请求时,系统会回应ACK应答数据包。该选项配置是否延迟ACK应答数据包,把他和包含数据的数据包一起发送,在高速网络和低负载的情况下会略微提高性能,但在网络连接较差的时候,对方电脑得不到应答会持续发起连接请求,反而会降低性能。
net.inet.tcp.delayed_ack=0
#屏蔽ICMP重定向功能
net.inet.icmp.drop_redirect=1
net.inet.icmp.log_redirect=1
net.inet.ip.redirect=0
net.inet6.ip6.redirect=0
#防止ICMP广播风暴
net.inet.icmp.bmcastecho=0
net.inet.icmp.maskrepl=0
#限制系统发送ICMP速率
net.inet.icmp.icmplim=100
#安全参数,编译内核的时候加了options TCP_DROP_SYNFIN才能够用
net.inet.icmp.icmplim_output=0
net.inet.tcp.drop_synfin=1
#配置为1会帮助系统清除没有正常断开的TCP连接,这增加了一些网络带宽的使用,但是一些死掉的连接最终能被识别并清除。死的TCP连接是被拨号用户存取的系统的一个特别的问题,因为用户经常断开modem而不正确的关闭活动的连接
net.inet.tcp.always_keepalive=1
#若看到net.inet.ip.intr_queue_drops这个在增加,就要调大net.inet.ip.intr_queue_maxlen,为0最好
net.inet.ip.intr_queue_maxlen=1000
#防止DOS攻击,默认为30000
net.inet.tcp.msl=7500
#接收到一个已关闭的端口发来的任何包,直接drop,假如配置为1则是只针对TCP包
net.inet.tcp.blackhole=2
#接收到一个已关闭的端口发来的任何UDP包直接drop
net.inet.udp.blackhole=1
#为网络数据连接时提供缓冲
net.inet.tcp.inflight.enable=1
#假如打开的话每个目标地址一次转发成功以后他的数据都将被记录进路由表和arp数据表,节约路由的计算时间,但会需要大量的内核内存空间来保存路由表
net.inet.ip.fastforwarding=0
#kernel编译打开options POLLING功能,高负载情况下使用低负载不推荐SMP不能和polling一起用
#kern.polling.enable=1
#并发连接数,默认为128,推荐在1024-4096之间,数字越大占用内存也越大
kern.ipc.somaxconn=32768
#禁止用户查看其他用户的进程
security.bsd.see_other_uids=0
#配置kernel安全级别
kern.securelevel=0
#记录下任何TCP连接
net.inet.tcp.log_in_vain=1
#记录下任何UDP连接
net.inet.udp.log_in_vain=1
#防止不正确的udp包的攻击
net.inet.udp.checksum=1
#防止DOS攻击
net.inet.tcp.syncookies=1
#仅为线程提供物理内存支持,需要256兆以上内存
kern.ipc.shm_use_phys=1
# 线程可使用的最大共享内存
kern.ipc.shmmax=67108864
# 最大线程数量
kern.ipc.shmall=32768
# 程式崩溃时不记录
kern.coredump=0
# lo本地数据流接收和发送空间
net.local.stream.recvspace=65536
net.local.dgram.maxdgram=16384
net.local.dgram.recvspace=65536
# 数据包数据段大小,ADSL为1452。
net.inet.tcp.mssdflt=1460
# 为网络数据连接时提供缓冲
net.inet.tcp.inflight_enable=1
# 数据包数据段最小值,ADSL为1452
net.inet.tcp.minmss=1460
# 本地数据最大数量
net.inet.raw.maxdgram=65536
# 本地数据流接收空间
net.inet.raw.recvspace=65536
#ipfw防火墙动态规则数量,默认为4096,增大该值能够防止某些病毒发送大量TCP连接,导致不能建立正常连接
net.inet.ip.fw.dyn_max=65535
#配置ipf防火墙TCP连接空闲保留时间,默认8640000(120小时)
net.inet.ipf.fr_tcpidletimeout=864000

CENTOS使用setup工具



setup工具是redhat系列的linux中的一个很强的工具,可以在其中配置防火墙规则、认证方式、服务器状态、IP地址等。但是如果你的linux语言环境是中文环境或者非ascii环境的时候就会出现乱码,解决办法:
#lang="en_US"
#setup
就可以了。

星期五, 七月 18, 2008

linux vsfftpd链接失败解决办法



故障现象:
linux vsftp ftp服务器连接失败 cannot change directory:/home/***
2008-01-07 23:10cannot change directory:/home/***
ftp服务器连接失败,错误提示:
500 OOPS: cannot change directory:/home/*******
500 OOPS: child died

解决方法:
在终端输入命令:
setsebool ftpd_disable_trans 1
service vsftpd restart
就OK了!

vsftpd登录失败can not change directory:/home/xxx的解决办法



故障现象:
linux vsftp ftp服务器连接失败 cannot change directory:/home/***
2008-01-07 23:10cannot change directory:/home/***
ftp服务器连接失败,错误提示:
500 OOPS: cannot change directory:/home/*******
500 OOPS: child died

解决方法:
在终端输入命令:
setsebool ftpd_disable_trans 1
service vsftpd restart
就OK了!

星期四, 七月 17, 2008

Apache 启动报错



错误提示如下:
httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1 for ServerName
解决方法:
1.修改httpd.conf这个文件
ServerName 127.0.0.1:80

2.修改httpd.conf这个文件
找到ServerName
写上你的服务器的IP地址和端口号
ServerName 12.34.56.78:80

此外,可以讲ServerName写成hostname:port。但是这样需要与实际的hostname保持一致,否则容易出现:
httpd: apr_sockaddr_info_get() failed for linux(在BSD上是apr_sockaddr_info_get() failed for freebsdla)
当然,出现这个错误的话就直接修改httpd.conf里面的ServiceName就可以了

星期二, 七月 08, 2008

2007开发语言回顾



2007没怎么注意就过去了。

本来觉得2007,在IT界索然无味。但一回顾就吓了我一跳。这种技术的繁荣,不亚于2002年。

2002年的COM+、EJB、设计模式、ORM、MVC、软件工程、UML、自动测试、BUG跟踪、发布配置、项目管理,讨论了好大一堆企业级开发技术和企业级开发过程管理。

2007年,发现技术遍地开

ROR,首先打了JAVA一枪。谁说企业级非要重型武器。从MVC、ORM、AJAX、自动化测试、日志、REST URL,浑然一体,简单的实现了JAVA一直想实现的完美企业解决方案。虽然ROR现在仅仅在自由的开源和穷人的WEB2.0世界中混,但它已经引起了企业级开发的大讨论大关注。即使ROR无法闯入企业级开发,那么JAVA也必然会出现这样的框架。JRUBY就是一个例子。

IDE工具的大战,borland一声叹息,在WIN32、.NET、JAVA均失利。SUN不是干IDE的料,居然NETBEANS做的有模有样,而且我用了最近的NETBEANS6.0,感叹大超eclipse。江山辈有新人出啊。谁说SUN做不好IDE,谁说做IDE没有空间和利益了。看来这世界规则不能老路径依赖。

年底,google发布了android,USB、蓝牙、红外、GPRS、投影仪接口、GPS,能接的都接上。地图、搜索、邮件、OFFICE应有尽有。工业设计不逊apple,代工也找的很牛。芯片设计也找的很牛,运营商也找的很牛,连中国移动都榜上有名。而且采用linux+JAVA这两大世界最大开源技术,又发动了1000万美金的社区编程大赛,整个产业链都有合作,想不火都难。所以MOTO要卖掉自己的手机部门,诺基亚要转型成为互联网企业,微软一直想在手机行业讨便宜都没有讨着。让我想起一句话:历史的车轮总会带走属于历史的东西。看看微软,在游戏机市场,在手机市场,在互联网市场均没有得到好处。微软辛辛苦苦建立起来的门槛壁垒和技术开发团队和软件开发过程管理模式,具体在新的未来面前毫无用处。真是,一个革命,就使多年营建的壁垒一下成了马其顿防线。

开发管理方法,过去追究工程化。现在讲究的是XP。但是,XP也过时了。从现在的发展趋势来看,虚公司将会产生。没有办公地点,不需要聚集在一起。互联网上的产品,互联网上的开发协作。我们需要音频会议、视频会议来加强沟通。邮件、IM、BBS、圈子、WIKI、BLOG这些沟通协作工具已经成熟。

Facebook的火,从运营上来说是校友录和大学生引起的火。但是从技术上来讲,Facebook代表了真正的web2.0。为什么这么说呢?邮件注册,是Facebook的ID认证和联系工具。邀请加入而非烂注册,是真实身份的基础保证。博客、视频、图片是内容产生工具。推荐好友是SNS的串联。Open API是应用开花的插件平台,是迎合未来WebOS,个人门户、聚合信息、SAAS的重要特征,是FaceBook巨型扩张的重要起飞。而搜索技术和故意拒绝google这样的搜索引擎,使真实信息搜索和私人性得到保证,免除了商业性故意关系营销的骚扰。所以说,FaceBook是google害怕的。google虽然有gmail\gtalk\goffice\gcode\gbbs\gblog\gearth等各种应用和社区,但google这种黑洞式聚合信息的优势,在真实性的呼声中变成了劣势。

FLEX是我2007年关注的技术。AJAX引爆了2006、2007。但AJAX是WEB时代的顶峰表现。我们经常会开发一套B/S版,也会开发一套C/S版,两版其实是两套代码,可能表现和使用上和功能上都不一样,维护也各维护各的,BUG也出现在不同地方,有了新需求就需要分别开发。实在成本无法下降,反应速度无法跟的上现实。所以如何开发一套,即是B/S又是C/S,这是我所关注的。而且不管过去开发C/S和B/S,业务层和表现层不管怎么分离都还有些代码混合在一起。ROR能强制解决这个问题,但ROR还是WEB开发框架。FLEX不一样了,它是B/S和C/S混合技术,而且只有表现技术,没有数据存取技术。这就也强制实现了业务只能实现成纯业务的WebService。而且这样实现出来的WebService,也是很好的SOA架构,在整合和聚合上面,表现了很好的Open API特性。

微软的D语言。听说微软又出了一个D语言,反复搜索信息很少。但它是面向业务专家的。这就让我很有兴趣。如何协同业务、页面表现、数据库设计、代码、测试、项目经理、文案。这是软件工程极其重要的问题。我们研究了大量的流程和工具来解决之间的理解鸿沟。前一段时间,炎黄盈动发布了一款流程描述软件,但可惜是面向eclipse的,不知道是谁用的?如果是给业务专家用的,建议简单再简单的安装和启动。

lua语言。游戏的火热,热了这门语言。但我并没有把它定位成一个游戏语言。我在N年前就在做业务平台,研究了大量元数据,反射的技术核心,希望能简单开发和编程。当时也尝试了PascalScript。我前一段时间还用了用安装软件InnoSetup,也是脚本驱动。这都是很好的引擎。未来在业务专家和架构师和开发人员之间存在的一种脚本,必定是这个趋势。

JAVASCRIPT语言。刚才说完了Lua。Lua是连接EXE软件的脚本。而JAVASCRIPT是连接WEB软件的脚本。现在的WEB开发技术,asp\asp.net\python\php\ror\jsp,层出不群。如何粘合这些不同的WEB语言,并且控制WEB元素,唯javascript莫属。

PHP语言。PHP语言在web2.0时代,LAMP组合大火。使oracle应用在大型应用,MSSQL应用在中小应用,MYSQL应用在小企业应用中,三者割据。

很多初入道的程序员都问我,现在技术这么多,该学什么才有前途?我说,你能应聘的企业是面向什么规模的客户,你就会用到相应的技术。我一般都是这么点拨的。

虽然看起来PHP因为没有框架和Mix代码,让人感觉它是ASP时代的产物。但是PHP的跨平台性、PHP的积极演化,现在的模板技术,已经能实现MVC和多语言和多风格。现在也模仿ROR进行了ORM、REST URL技术、WebService技术,跟得上时代的脚步。笔者用过ASP、asp.net、jsp,上手使用php,感觉非常顺手,很符合常规思路

webServcie与REST。记得当年使用COM+的时候,要整合个PB系统,要整合个CORBA,要整合个WebLogic,要包装成WEB应用,真是难死人,技术不稳定的N死。.NET技术的WebService,让我眼前一亮。ASP.net并没有让我感到开发web的爽(反而是asp和PHP),但是.Net的WebService是我用起来最顺心的。最近几年,微软是思想快,但步子慢。WPF、WCF都是非常好的技术,但都出师不利。代表未来的未来,但不代表未来。未来还在ROR和FLEX和WebService的手中。

3D互联网,google发布了google earth,也发布了3D建模工具。第二人生也发布了SDK,但都没有引起风暴。FaceBook走入了SAAS、Open API的时代,这算是web2.5技术了 。

看来,我们不要走的太快,只需要比现在前进一点,就有一个机会窗口。

[fwd]开发网站选择什么样的开发语言



作为一个全新的互联网项目,有时候会面临一个选择什么样的开发语言的问题。

我说的这个有时候,其实是指现有的团队中,没有技术开发的成员的情况。如果已经有了一个或者多个技术开发人员,当然是选择现有成员最熟悉和最擅长的语言了。

那么对于一个还没有技术成员的团队,应该选择什么样的开发语言呢?回答这个问题,首先应该搞清楚选择开发语言的时候应该从哪些方面考虑?

我认为作为一个项目选择开发语言应该考虑几个方面:

1、成本
一个互联网的项目,开发往往是前期投入的大头,而大多数创业团队前期的资金都不是很充裕,如何控制开发成本,就成为一个需要考虑的问题。开发成本又包括开发人员成本以及开发资源成本(开发设备、服务器带宽资源等等);

2、效率
现在的互联网发展,时间是最大的成本,是否能够快速的开发出可上线的产品,往往成为项目是否能够获得成功的一个重要因素;

3、可扩展性
很多项目都是分阶段实施的,如果一个项目的开发语言的可扩展性不强,可能会对项目后期的实施带来巨大的麻烦。

4、可移植性
作为服务器平台,早期用WINDOWS是比较方便、快速、“省钱”(主要是维护成本)的,但是当一个项目上升到一定阶段的时候,是否会需要换到Linux、Unix等平台呢?

5、性能
项目要搞大,一定要上规模,对于一个项目未来可能达到的规模需要有一个“预估”。如果一个语言不能支撑你未来项目的规模,那么肯定选择的时候就需要很慎重了。

最近遇到一个项目的项目语言选择的评估,按照以上几条分别进行考虑:

项目需求:1、需要尽量节省成本;2、对效率需求很大;3、有扩展性需求;4、需要考虑可移植性;5、属于用互联网的项目,性能方面不会要过高的要求。

太新、太偏的语言人力成本一般都较高,太新了,开发人员熟悉程度不高,影响效率。太偏了,可扩展性不高。所以,只选择主流语言:ASP、.Net、Java、PHP这类的语言。

ASP、.Net 属于微软的“个性”产品,可移植性不够,否掉。

Java语言,太“高端”,开发人员成本相对较高,而开发效率稍差一些,最终选择了PHP语言。

PHP语言,出现时间比较长,语言相对比较成熟。开发人员比JAVA成本略低一些,开发效率比JAVA快。

PHP与平台无关可移植性比较好,代码几乎可以不用修改的在WINDOWS、LINUX上通用。

PHP的性能比JAVA略差,但是从这个项目对性能的需求来看,在可预期的时间内,还足够应付。

最终选择: PHP!

星期四, 七月 03, 2008

关于Document.execCommand("BackgroundImageCache")

Pixy方法受到IE的cache bug影响会闪烁。其实并没有说清楚这个问题,但其实该bug是有条件的,即IE的cache设置为Every visit to the page,而不是默认的Automatically。基本上,只有开发者才会把cache设置为每次访问检查更新,所以这个bug其实不会影响真正的用户 (根据在winxpsp2的ie6下测试,虽然可能仍然调用了一次网络存取的api,但是并没有发生实际的请求,症状就是鼠标有极短时间的抖动,但是图像 不会闪烁)。此外有人发现了一个未公开的方法来让IE对背景图进行缓存: 
document.execCommand("BackgroundImageCache",false,true)

用这种方法甚至避免了api调用,貌似是直接缓存在IE内存中。 

IE6下设置背景图片是不会被真正cache住的,就算服务器做了cache,如果想cache住只能~~~

做过UI设计和开发的人一定知道,IE(不包括IE7)会经常从服务器端重新载入背景图片,好端端的UI界面在IE(不包括IE7)中就这样被折腾着......

Erik发现了一个简单的解决办法(针对IE7以下的IE有效,其实在IE7中已经修复了这个Bug)

 程序代码

document.execCommand("BackgroundImageCache", false, true);


/**
* update@2007-04-02
*/
今天阅读Ext的源码时发现Jack Slocum已经考虑到了这一点,在Ext.js中给出了他的实现,在其它Ajax框架中应该还没有这种类似的代码,从这一个细节上就能看出Ext的全面~

 程序代码

var isIE = ua.indexOf("msie") > -1, isIE7 = ua.indexOf("msie 7") > -1;
// remove css image flicker
if(isIE && !isIE7){
  try{
  document.execCommand("BackgroundImageCache", false, true);
  }catch(e){}
}


/**
* update@2007-04-10
*/
今 天阅读幻宇的dreamplayer播放器源码时发现幻宇也针对IE的背景缓存进行了修复,只是他并没考虑到IE7中已经不存在这个现象了,这是 evml.js中的一段相关代码~(顺便嘀咕两句:这家伙,写JS从来不加分号的,以前是这样,现在还是这样,这样的话怎么进行压缩呀,汗~下面的代码按 照我的习惯都已加上分号,哪怕只有两三句而已~)

 程序代码

window.isIE=navigator.appName.indexOf("Microsoft")==0;
if(isIE){
  document.documentElement.addBehavior("#default#userdata");
  document.execCommand("BackgroundImageCache",false,true);
}


/**
* 相关原文
* by eriK @2007-02-26
*/
A while back a lot of people where covering how to work around the bug that IE always
reloads background images from the server, leading to your UI flickering.
Dean wrote one and lots of others wrote the same thing. Today, I saw this simple workaround
(from a fellow Googler who worked at Microsoft before):

document.execCommand("BackgroundImageCache", false, true)

Much simpler but makes me wonder why this is not the default setting?

/**
* 相关回复
* by Nicholas C. Zakas @2007-02-26
*/
I've actually wondered about this "bug" for a while.
I'm sure somewhere along the line this decision was made for a logical reason…
maybe they didn't anticipate how much background images would be used, or maybe they thought
there was some use case under which it would be desirable not to cache the background image.
I'm generally not big on overriding things that seem to be design decisions (which this seems to be).
I've never really thought this was a "bug"…bugs don't usually have switches that say "turn off bug".

traceback:http://hi.baidu.com/pplboy/blog/item/af40442604a193128b82a12a.html

星期二, 六月 10, 2008

关于ThreadLocal



ThreadLocal可以为线程保存一个变量,这个变量只在该线程中可以被使用(如果是在该线程新建的话)。当线程销毁的时候,ThreadLocal对象也会被销毁。
可以用来存放该线程中共享的变量,比如Hibernate的Session,该线程中唯一存在的对象等...

ThreadLocal和同步没有本质关联,同步是指的多个线程在访问共享资源的时候应该考虑的数据完整性的内容。ThreadLocal则重点关注同一个线程,在不同地方可以方便快捷的访问到该线程中的变量。使用ThreadLocal用于保存数据库连接、事务处理等相关内容十分方便。

java多线程设计要点



1.多线程中有主内存和工作内存之分, 在JVM中,有一个主内存,专门负责所有线程共享数据;而每个线程都有他自己私有的工作内存, 主内存和工作内存分贝在JVM的stack区和heap区。

2.线程的状态有'Ready', 'Running', 'Sleeping', 'Blocked', 和 'Waiting'几个状态,
'Ready' 表示线程正在等待CPU分配允许运行的时间。


3.线程运行次序并不是按照我们创建他们时的顺序来运行的,CPU处理线程的顺序是不确定的,如果需要确定,那么必须手工介入,使用setPriority()方法设置优先级。

4.我们无从知道一个线程什么时候运行,两个或多个线程在访问同一个资源时,需要synchronized

5. 每个线程会注册自己,实际某处存在着对它的引用,因此,垃圾回收机制对它就“束手无策”了。

6. Daemon线程区别一般线程之处是:主程序一旦结束,Daemon线程就会结束。

7. 一个对象中的所有synchronized方法都共享一把锁,这把锁能够防止多个方法对通用内存同时进行的写操作。synchronized static方法可在一个类范围内被相互间锁定起来。

8. 对于访问某个关键共享资源的所有方法,都必须把它们设为synchronized,否则就不能正常工作。

9. 假设已知一个方法不会造成冲突,最明智的方法是不要使用synchronized,能提高些性能。

10. 如果一个"同步"方法修改了一个变量,而我们的方法要用到这个变量(可能是只读),最好将自己的这个方法也设为 synchronized。

11. synchronized不能继承, 父类的方法是synchronized,那么其子类重载方法中就不会继承“同步”。

12. 线程堵塞Blocked有几个原因造成:

(1)线程在等候一些IO操作
(2)线程试图调用另外一个对象的“同步”方法,但那个对象处于锁定状态,暂时无法使用。

13.原子型操作(atomic), 对原始型变量(primitive)的操作是原子型的atomic. 意味着这些操作是线程安全的, 但是大部分情况下,我们并不能正确使用,来看看 i = i + 1 , i是int型,属于原始型变量:

(1)从主内存中读取i值到本地内存.
(2)将值从本地内存装载到线程工作拷贝中.
(3)装载变量1.
(4)将i 加 1.
(5)将结果给变量i.
(6)将i保存到线程本地工作拷贝中.
(7)写回主内存.

注意原子型操作只限于第1步到第2步的读取以及第6到第7步的写, i的值还是可能被同时执行i=i+1的多线程中断打扰(在第4步)。

double 和long 变量是非原子型的(non-atomic)。数组是object 非原子型。


14. 由于13条的原因,我们解决办法是:

class xxx extends Thread{

//i会被经常修改
private int i;

public synchronized int read(){ return i;}

public synchronized void update(){ i = i + 1;}

..........

}

15. Volatile变量, volatile变量表示保证它必须是与主内存保持一致,它实际是"变量的同步", 也就是说对于volatile变量的操作是原子型的,如用在long 或 double变量前。

16. 使用yield()会自动放弃CPU,有时比sleep更能提升性能。

17. sleep()和wait()的区别是:wait()方法被调用时会解除锁定,但是我们能使用它的地方只是在一个同步的方法或代码块内。

18. 通过制造缩小同步范围,尽可能的实现代码块同步,wait(毫秒数)可在指定的毫秒数可退出wait;对于wait()需要被notisfy()或notifyAll()踢醒。

19. 构造两个线程之间实时通信的方法分几步:
(1). 创建一个PipedWriter和一个PipedReader和它们之间的管道;
PipedReader in = new PipedReader(new PipedWriter())
(2). 在需要发送信息的线程开始之前,将外部的PipedWriter导向给其内部的Writer实例out
(3). 在需要接受信息的线程开始之前,将外部的PipedReader导向给其内部的Reader实例in
(4). 这样放入out的所有东西度可从in中提取出来。

20. synchronized带来的问题除性能有所下降外,最大的缺点是会带来死锁DeadLock,只有通过谨慎设计来防止死锁,其他毫无办法,这也是线程难以驯服的一个原因。不要再使用stop() suspend() resume()和destory()方法

21. 在大量线程被堵塞时,最高优先级的线程先运行。但是不表示低级别线程不会运行,运行概率小而已。

22. 线程组的主要优点是:使用单个命令可完成对整个线程组的操作。很少需要用到线程组。

23. 从以下几个方面提升多线程的性能:

检查所有可能Block的地方,尽可能的多的使用sleep或yield()以及wait();

尽可能延长sleep(毫秒数)的时间;

运行的线程不用超过100个,不能太多;

不同平台linux或windows以及不同JVM运行性能差别很大。

24. 推荐几篇相关英文文章:

Use Threading Tricks to Improve Programs

星期四, 六月 05, 2008

大型网站的体系分析



大型网站的架构体系分析
2008-01-12 07:11by somebody


一. 结构、表现、行为

1. 良好的应用程序架构是保证网站成功的关键
2. 网站的表现形式反馈于用户的眼睛,手,耳朵;从而产生情感。

二. 高效的团队

1. 时间,沟通,配合,水准。
2. 如果说人多嘴杂,一旦说多过做,项目就会受到影响,而且还会影响同事情绪,工作质量,效益。
3. 合理的项目计划,目标,执行,流程,方法,周期,最终的拍板确认。
4. 产生的冲突?项目思想者与项目的施行者?二者皆互相影响,相辅相佐。

三. 网站内容

1. 慎用内容突出,质量,新颖,关注社会热点,网民方向性。
2. 原创的方向性

四. 页面的质量

1. 目的:让网站有效的呈现于网民
2. 首页,频道页,内容页,分类页的类别,如h1到h6在这各环节上的定位
3. 用户的使用习惯,可认识度,方易。
4. 网站目录名,文件名,样式名,代码的规范,与有利SEO的命名。
5. Tag的必要性
6. 头部的页面声明,提高关键词密度,图片替换,链接说明
7. 正确使用内容容器,如段落p,列表ul, ol, li, dl, dt, dd
8. 简洁有语义的url
9. 图片的质量,速度,小图标处理

五. 用户爱好

1. 什么样的文字,有诱导,吸引的作用。如:色彩,是否加粗,下划等?
2. 视觉权重较高的字符与图形。如:大小,色彩,形状
3. 有交互暗示的字符或图形。如路标,箭头
4. 常见表单 按钮,单复选,下拉等
5. 图类 如,美女照,清晰图,有吸引力的。
6. Icon 图标 或称ui类

六. 以用户为中心,用户体验

1.网站提供给用户的可行路径
2.用户在所有路径中的行为
3.用户行为在网站中产生的结果
4.用户体验的四方面:结构,标识,搜索,导航(明确,易用,方便)

七. 灵活性,可扩展性

八. 标准与非标准

1. 面向机器(指搜索)与面向人(指用户)。

浅析大型网站的架构



浅析大型网站的架构

一个小型的网站,比如个人网站,可以使用最简单的html静态页面就实现了,配合一些图片达到美化效果,所有的页面均存放在一个目录下,这样的网站对系统架构、性能的要求都很简单,随着互联网业务的不断丰富,网站相关的技术经过这些年的发展,已经细分到很细的方方面面,尤其对于大型网站来说,所采用的技术更是涉及面非常广,从硬件到软件、编程语言、数据库、WebServer、防火墙等各个领域都有了很高的要求,已经不是原来简单的html静态网站所能比拟的。

大型网站,比如门户网站。在面对大量用户访问、高并发请求方面,基本的解决方案集中在这样几个环节:使用高性能的服务器、高性能的数据库、高效率的编程语言、还有高性能的Web容器。但是除了这几个方面,还没法根本解决大型网站面临的高负载和高并发问题。

上面提供的几个解决思路在一定程度上也意味着更大的投入,并且这样的解决思路具备瓶颈,没有很好的扩展性,下面我从低成本、高性能和高扩张性的角度来说说我的一些经验。

1、HTML静态化

其实大家都知道,效率最高、消耗最小的就是纯静态化的html页面,所以我们尽可能使我们的网站上的页面采用静态页面来实现,这个最简单的方法其实也是最有效的方法。但是对于大量内容并且频繁更新的网站,我们无法全部手动去挨个实现,于是出现了我们常见的信息发布系统CMS,像我们常访问的各个门户站点的新闻频道,甚至他们的其他频道,都是通过信息发布系统来管理和实现的,信息发布系统可以实现最简单的信息录入自动生成静态页面,还能具备频道管理、权限管理、自动抓取等功能,对于一个大型网站来说,拥有一套高效、可管理的CMS是必不可少的。

除了门户和信息发布类型的网站,对于交互性要求很高的社区类型网站来说,尽可能的静态化也是提高性能的必要手段,将社区内的帖子、文章进行实时的静态化,有更新的时候再重新静态化也是大量使用的策略,像Mop的大杂烩就是使用了这样的策略,网易社区等也是如此。

同时,html静态化也是某些缓存策略使用的手段,对于系统中频繁使用数据库查询但是内容更新很小的应用,可以考虑使用html静态化来实现,比如论坛中论坛的公用设置信息,这些信息目前的主流论坛都可以进行后台管理并且存储再数据库中,这些信息其实大量被前台程序调用,但是更新频率很小,可以考虑将这部分内容进行后台更新的时候进行静态化,这样避免了大量的数据库访问请求。

2、图片服务器分离

大家知道,对于Web服务器来说,不管是Apache、IIS还是其他容器,图片是最消耗资源的,于是我们有必要将图片与页面进行分离,这是基本上大型网站都会采用的策略,他们都有独立的图片服务器,甚至很多台图片服务器。这样的架构可以降低提供页面访问请求的服务器系统压力,并且可以保证系统不会因为图片问题而崩溃,在应用服务器和图片服务器上,可以进行不同的配置优化,比如apache在配置ContentType的时候可以尽量少支持,尽可能少的LoadModule,保证更高的系统消耗和执行效率。

3、数据库集群和库表散列

大型网站都有复杂的应用,这些应用必须使用数据库,那么在面对大量访问的时候,数据库的瓶颈很快就能显现出来,这时一台数据库将很快无法满足应用,于是我们需要使用数据库集群或者库表散列。

在数据库集群方面,很多数据库都有自己的解决方案,Oracle、Sybase等都有很好的方案,常用的MySQL提供的Master/Slave也是类似的方案,您使用了什么样的DB,就参考相应的解决方案来实施即可。

上面提到的数据库集群由于在架构、成本、扩张性方面都会受到所采用DB类型的限制,于是我们需要从应用程序的角度来考虑改善系统架构,库表散列是常用并且最有效的解决方案。我们在应用程序中安装业务和应用或者功能模块将数据库进行分离,不同的模块对应不同的数据库或者表,再按照一定的策略对某个页面或者功能进行更小的数据库散列,比如用户表,按照用户ID进行表散列,这样就能够低成本的提升系统的性能并且有很好的扩展性。sohu的论坛就是采用了这样的架构,将论坛的用户、设置、帖子等信息进行数据库分离,然后对帖子、用户按照板块和ID进行散列数据库和表,最终可以在配置文件中进行简单的配置便能让系统随时增加一台低成本的数据库进来补充系统性能。

4、缓存

缓存一词搞技术的都接触过,很多地方用到缓存。网站架构和网站开发中的缓存也是非常重要。这里先讲述最基本的两种缓存。高级和分布式的缓存在后面讲述。

架构方面的缓存,对Apache比较熟悉的人都能知道Apache提供了自己的缓存模块,也可以使用外加的Squid模块进行缓存,这两种方式均可以有效的提高Apache的访问响应能力。

网站程序开发方面的缓存,Linux上提供的Memory Cache是常用的缓存接口,可以在web开发中使用,比如用Java开发的时候就可以调用MemoryCache对一些数据进行缓存和通讯共享,一些大型社区使用了这样的架构。另外,在使用web语言开发的时候,各种语言基本都有自己的缓存模块和方法,PHP有Pear的Cache模块,Java就更多了,.net不是很熟悉,相信也肯定有。

5、镜像

镜像是大型网站常采用的提高性能和数据安全性的方式,镜像的技术可以解决不同网络接入商和地域带来的用户访问速度差异,比如ChinaNet和EduNet之间的差异就促使了很多网站在教育网内搭建镜像站点,数据进行定时更新或者实时更新。在镜像的细节技术方面,这里不阐述太深,有很多专业的现成的解决架构和产品可选。也有廉价的通过软件实现的思路,比如Linux上的rsync等工具。

6、负载均衡

负载均衡将是大型网站解决高负荷访问和大量并发请求采用的终极解决办法。

负载均衡技术发展了多年,有很多专业的服务提供商和产品可以选择,我个人接触过一些解决方法,其中有两个架构可以给大家做参考。

硬件四层交换

第四层交换使用第三层和第四层信息包的报头信息,根据应用区间识别业务流,将整个区间段的业务流分配到合适的应用服务器进行处理。 第四层交换功能就象是虚 IP,指向物理服务器。它传输的业务服从的协议多种多样,有HTTP、FTP、NFS、Telnet或其他协议。这些业务在物理服务器基础上,需要复杂的载量平衡算法。在IP世界,业务类型由终端TCP或UDP端口地址来决定,在第四层交换中的应用区间则由源端和终端IP地址、TCP和UDP端口共同决定。

在硬件四层交换产品领域,有一些知名的产品可以选择,比如Alteon、F5等,这些产品很昂贵,但是物有所值,能够提供非常优秀的性能和很灵活的管理能力。Yahoo中国当初接近2000台服务器使用了三四台Alteon就搞定了。

软件四层交换

大家知道了硬件四层交换机的原理后,基于OSI模型来实现的软件四层交换也就应运而生,这样的解决方案实现的原理一致,不过性能稍差。但是满足一定量的压力还是游刃有余的,有人说软件实现方式其实更灵活,处理能力完全看你配置的熟悉能力。

软件四层交换我们可以使用Linux上常用的LVS来解决,LVS就是Linux Virtual Server,他提供了基于心跳线heartbeat的实时灾难应对解决方案,提高系统的鲁棒性,同时可供了灵活的虚拟VIP配置和管理功能,可以同时满足多种应用需求,这对于分布式的系统来说必不可少。

一个典型的使用负载均衡的策略就是,在软件或者硬件四层交换的基础上搭建squid集群,这种思路在很多大型网站包括搜索引擎上被采用,这样的架构低成本、高性能还有很强的扩张性,随时往架构里面增减节点都非常容易。这样的架构我准备空了专门详细整理一下和大家探讨。

对于大型网站来说,前面提到的每个方法可能都会被同时使用到,我这里介绍得比较浅显,具体实现过程中很多细节还需要大家慢慢熟悉和体会,有时一个很小的squid参数或者apache参数设置,对于系统性能的影响就会很大,希望大家一起讨论,达到抛砖引玉之效。

[fwd]MySpace的体系架构



大型网站架构之:MySpace的体系架构
2008-06-03 11:08
MySpace.com有着6500万的订阅者,是因特网上增长最快的网站之一,每天还有260,000新用户注册。它经常因为性能问题而受指责,MySpace不得不处理其他网站很少碰到的或大或小的一些问题。它们是怎么做的呢?
Site: http://myspace.com
站点:http://myspace.com

平台
• ASP.NET 2.0
• Windows
• IIS
• SQL Server

内部运行情况?
• MySpace 每天处理15亿的页面页面查看,白天处理230万并发的用户

• 会员用户里程碑
- 500,000用户:简单的磕磕绊绊的体系结构
- 1百万用户:痛苦的垂直分割解决伸缩性
- 3百万用户:Scale-Out 胜过Scale-Up(按比例增加)
- 9百万用户:站点迁移到ASP.NET,增加虚拟存储
- 260万用户:MySpace拥有了64位技术
• 500,000 个帐号对于两个web服务器和一个数据库来说负担太大了
• 100-200万个帐号

- 他们使用了一种数据库体系结构,围绕着垂直分割的概念,提供不同服务比如界面登录,用户资料和博客等的网站的各部分都有单独的数据库。
- 垂直分割方案有助于分开数据库读和写的工作量,并且当用户需要一个新特征时,MySpace 将会加入一个新的在线数据库来支持它。
- MySpace 从直接使用附着于它的数据库的服务器的存储设备转换到一个存储区域网络(SAN),里面大量的磁盘存储设备由一个高速,专用网络联系到一块,同时数据库连接到SAN。到SAN的改变提高了性能,正常运行时间和可靠性。

• 300万个帐号
- 垂直分割解决方案并没有持续很长时间因为它们重复了一些水平的信息像跨过所有垂直片的用户帐号。有这么多的重复它会使系统变慢,肯定要失败。
- 个人应用比如Web站点子部分上的博客将会增长到对于单独一个数据库服务器来说太大的程度
- 在逻辑上重组所有核心数据到一个数据库里
- 把它的用户基本信息分成100万帐号一个的块,然后把所有有键的数据放到SQL Server不同实例的这些帐号中

• 900万-1700万帐号
- 迁移到ASP.NET后,使用了比先前的体系结构更少的资源。150个服务器运行新的代码就能够做原来246个服务器做的同样的工作。
- 再看看存储瓶颈。实施SAN解决了原来的一些性能问题,但是现在Web站点的需求开始间歇性地超过了SAN的I/O能力-它从磁盘存储读写的速度
- 使用每个数据库100个帐号的分开方式达到了极限,因为这已经超过了极限;
- 迁移到一个虚拟存储体系结构,那里整个SAN被当作一个大的存储池来对待,不需要特定的磁盘为特定的应用服务。现在
MySpace在设备上从相对新的SAN厂商,3PARdata方面已经标准化了。增加了一个高速缓存层—服务器放在Web服务器和数据库服务器之间,它唯一的工作就是捕获内存中频繁访问的数据对象的副本,然后把它们用于Web应用,不需要数据库查询。

• 2600万帐号
- 迁移到64位SQL server以解决它们的内存瓶颈问题。它们的标准数据库服务器配置使用64GB的RAM。

Myspace的经验能够说明什么?
• 你可以使用微软的技术构建大型网站。
• 从一开始就应该使用缓存。
• 高速缓存是一个更好的地方存储临时数据,比如Web站点上跟踪一个特定用户的会话产生的临时文件,就不再需要记录到数据库里,
• 嵌入OS特征来检测拒绝服务攻击会产生无法解释的错误
• 把数据分布到地理位置不同的数据中心,以免发生断电事故。
• 从开始就考虑使用虚拟存储/簇文件系统。它能让你大量并行IO访问,而且不需要任何重组就能够增加所需要的磁盘。
MySpace网站架构的变迁
MySpace 经历了六个里程碑的过程。
在每个里程碑,站点负担都会超过底层系统部分组件的最大载荷,特别是数据库和存储系统。接着,功能出现问题,用户失声尖叫。最后,技术团队必须为此修订系统策略。
  虽然自2005年早期,站点账户数超过7百万后,系统架构到目前为止保持了相对稳定,但MySpace仍然在为SQL Server支持的同时连接数等方面继续攻坚,Benedetto(技术总监)说,"我们已经尽可能把事情做到最好"。

1. 里程碑一:50万账户
  按Benedetto 的说法,MySpace最初的系统很小,只有两台Web服务器和一个数据库服务器。那时使用的是Dell双CPU、4G内存的系统。
  单个数据库就意味着所有数据都存储在一个地方,再由两台Web服务器分担处理用户请求的工作量。但就像MySpace后来的几次底层系统修订时的情况一样,三服务器架构很快不堪重负。此后一个时期内,MySpace基本是通过添置更多Web服务器来对付用户暴增问题的。  但到在2004年早期,MySpace用户数增长到50万后,数据库服务器也已开始汗流浃背。
  但和Web服务器不同,增加数据库可没那么简单。如果一个站点由多个数据库支持,设计者必须考虑的是,如何在保证数据一致性的前提下,让多个数据库分担压力。
  在第二代架构中,MySpace运行在3个SQL Server数据库服务器上:一个为主,所有的新数据都向它提交,然后由它复制到其他两个;另两个全力向用户供给数据,用以在博客和个人资料栏显示。这种方式在一段时间内效果很好。只要增加数据库服务器,加大硬盘,就可以应对用户数和访问量的增加。

2. 里程碑二:1-2百万账户MySpace

注册数到达1百万至2百万区间后,数据库服务器开始受制于I/O容量--即它们存取数据的速度。
而当时才是2004年中,距离上次数据库系统调整不过数月。用户的提交请求被阻塞,就像千人乐迷要挤进只能容纳几百人的夜总会,站点开始遭遇"主要矛盾",Benedetto说,这意味着MySpace永远都会轻度落后于用户需求。"有人花5分钟都无法完成留言,因此用户总是抱怨说网站已经完蛋了。"他补充道。
  这一次的数据库架构按照垂直分割模式设计,不同的数据库服务于站点的不同功能,如登录、用户资料和博客。
于是,站点的扩展性问题看似又可以告一段落了,可以歇一阵子。
  垂直分割策略利于多个数据库分担访问压力,当用户要求增加新功能时,MySpace将投入新的数据库予以支持它。账户到达2百万后,MySpace还从存储设备与数据库服务器直接交互的方式切换到SAN(Storage Area Network,存储区域网络)--用高带宽、专门设计的网络将大量磁盘存储设备连接在一起,而数据库连接到SAN。这项措施极大提升了系统性能、正常运行时间和可靠性,Benedetto说。

3. 里程碑三:3百万账户
  当用户继续增加到3百万后,垂直分割策略也开始难以为继。尽管站点的各个应用被设计得高度独立,但有些信息必须共享。在这个架构里,每个数据库必须有各自的用户表副本--MySpace授权用户的电子花名册。这就意味着一个用户注册时,该条账户记录必须在9个不同数据库上分别创建。但在个别情况下,如果其中某台数据库服务器临时不可到达,对应事务就会失败,从而造成账户非完全创建,最终导致此用户的该项服务无效。
  另外一个问题是,个别应用如博客增长太快,那么专门为它服务的数据库就有巨大压力。2004 年中,MySpace面临Web开发者称之为"向上扩展"对"向外扩展"(译者注:Scale Up和Scale Out,也称硬件扩展和软件扩展)的抉择--要么扩展到更大更强、也更昂贵的服务器上,要么部署大量相对便宜的服务器来分担数据库压力。一般来说,大型站点倾向于向外扩展,因为这将让它们得以保留通过增加服务器以提升系统能力的后路。
  但成功地向外扩展架构必须解决复杂的分布式计算问题,大型站点如Google、Yahoo和Amazon.com,都必须自行研发大量相关技术。以Google为例,它构建了自己的分布式文件系统。
  另外,向外扩展策略还需要大量重写原来软件,以保证系统能在分布式服务器上运行。"搞不好,开发人员的所有工作都将白费",Benedetto说。
  因此,MySpace首先将重点放在了向上扩展上,花费了大约1个半月时间研究升级到32CPU服务器以管理更大数据库的问题。Benedetto说,"那时候,这个方案看似可能解决一切问题。"如稳定性,更棒的是对现有软件几乎没有改动要求。
  糟糕的是,高端服务器极其昂贵,是购置同样处理能力和内存速度的多台服务器总和的很多倍。而且,站点架构师预测,从长期来看,即便是巨型数据库,最后也会不堪重负,Benedetto说,"换句话讲,只要增长趋势存在,我们最后无论如何都要走上向外扩展的道路。" 
 因此,MySpace最终将目光移到分布式计算架构--它在物理上分布的众多服务器,整体必须逻辑上等同于单台机器。拿数据库来说,就不能再像过去那样将应用拆分,再以不同数据库分别支持,而必须将整个站点看作一个应用。现在,数据库模型里只有一个用户表,支持博客、个人资料和其他核心功能的数据都存储在相同数据库。
  既然所有的核心数据逻辑上都组织到一个数据库,那么MySpace必须找到新的办法以分担负荷--显然,运行在普通硬件上的单个数据库服务器是无能为力的。这次,不再按站点功能和应用分割数据库,MySpace开始将它的用户按每百万一组分割,然后将各组的全部数据分别存入独立的SQL Server实例。目前,MySpace的每台数据库服务器实际运行两个SQL Server实例,也就是说每台服务器服务大约2百万用户。Benedetto指出,以后还可以按照这种模式以更小粒度划分架构,从而优化负荷分担。
  当然,还是有一个特殊数据库保存了所有账户的名称和密码。用户登录后,保存了他们其他数据的数据库再接管服务。特殊数据库的用户表虽然庞大,但它只负责用户登录,功能单一,所以负荷还是比较容易控制的。

4. 里程碑四:
9百万到1千7百万账户2005 年早期,账户达到9百万后,MySpace开始用Microsoft的C#编写ASP.NET程序。C#是C语言的最新派生语言,吸收了C++和Java 的优点,依托于Microsoft .NET框架(Microsoft为软件组件化和分布式计算而设计的模型架构)。ASP.NET则由编写Web站点脚本的ASP技术演化而来,是 Microsoft目前主推的Web站点编程环境。
  可以说是立竿见影, MySpace马上就发现ASP.NET程序运行更有效率,与ColdFusion相比,完成同样任务需消耗的处理器能力更小。据技术总监 Whitcomb说,新代码需要150台服务器完成的工作,如果用ColdFusion则需要246台。Benedetto还指出,性能上升的另一个原因可能是在变换软件平台,并用新语言重写代码的过程中,程序员复审并优化了一些功能流程。
  最终,MySpace开始大规模迁移到 ASP.NET。即便剩余的少部分ColdFusion代码,也从Cold-Fusion服务器搬到了ASP.NET,因为他们得到了 BlueDragon.NET(乔治亚州阿尔法利塔New Atlanta Communications公司的产品,它能将ColdFusion代码自动重新编译到Microsoft平台)的帮助。
  账户达到1千万时,MySpace再次遭遇存储瓶颈问题。SAN的引入解决了早期一些性能问题,但站点目前的要求已经开始周期性超越SAN的I/O容量--即它从磁盘存储系统读写数据的极限速度。
  原因之一是每数据库1百万账户的分割策略,通常情况下的确可以将压力均分到各台服务器,但现实并非一成不变。比如第七台账户数据库上线后,仅仅7天就被塞满了,主要原因是佛罗里达一个乐队的歌迷疯狂注册。
  某个数据库可能因为任何原因,在任何时候遭遇主要负荷,这时,SAN中绑定到该数据库的磁盘存储设备簇就可能过载。"SAN让磁盘I/O能力大幅提升了,但将它们绑定到特定数据库的做法是错误的。"Benedetto说。
  最初,MySpace通过定期重新分配SAN中数据,以让其更为均衡的方法基本解决了这个问题,但这是一个人工过程,"大概需要两个人全职工作。"Benedetto说。长期解决方案是迁移到虚拟存储体系上,这样,整个SAN被当作一个巨型存储池,不再要求每个磁盘为特定应用服务。MySpace目前采用了一种新型SAN设备--来自加利福尼亚州弗里蒙特的3PARdata。
  在3PAR的系统里,仍能在逻辑上按容量划分数据存储,但它不再被绑定到特定磁盘或磁盘簇,而是散布于大量磁盘。这就使均分数据访问负荷成为可能。当数据库需要写入一组数据时,任何空闲磁盘都可以马上完成这项工作,而不再像以前那样阻塞在可能已经过载的磁盘阵列处。而且,因为多个磁盘都有数据副本,读取数据时,也不会使SAN的任何组件过载。
  当2005年春天账户数达到1千7百万时,MySpace又启用了新的策略以减轻存储系统压力,即增加数据缓存层--位于Web服务器和数据库服务器之间,其唯一职能是在内存中建立被频繁请求数据对象的副本,如此一来,不访问数据库也可以向 Web应用供给数据。
换句话说,100个用户请求同一份资料,以前需要查询数据库100次,而现在只需1次,其余都可从缓存数据中获得。当然如果页面变化,缓存的数据必须从内存擦除,然后重新从数据库获取--但在此之前,数据库的压力已经大大减轻,整个站点的性能得到提升。
  缓存区还为那些不需要记入数据库的数据提供了驿站,比如为跟踪用户会话而创建的临时文件--Benedetto坦言他需要在这方面补课,"我是数据库存储狂热分子,因此我总是想着将万事万物都存到数据库。"但将像会话跟踪这类的数据也存到数据库,站点将陷入泥沼。
  增加缓存服务器是"一开始就应该做的事情,但我们成长太快,以致于没有时间坐下来好好研究这件事情。"Benedetto补充道。

5. 里程碑五:
2千6百万账户2005 年中期,服务账户数达到2千6百万时,MySpace切换到了还处于beta测试的SQLServer 2005。转换何太急?主流看法是2005版支持64位处理器。但Benedetto说,"这不是主要原因,尽管这也很重要;主要还是因为我们对内存的渴求。"支持64位的数据库可以管理更多内存。
  更多内存就意味着更高的性能和更大的容量。原来运行32位版本的SQL Server服务器,能同时使用的内存最多只有4G。切换到64位,就好像加粗了输水管的直径。升级到SQL Server 2005和64位Windows Server 2003后,MySpace每台服务器配备了32G内存,后于2006年再次将配置标准提升到64G。
意外错误
  如果没有对系统架构的历次修改与升级,MySpace根本不可能走到今天。但是,为什么系统还经常吃撑着了?很多用户抱怨的"意外错误"是怎么引起的呢?

  原因之一是MySpace对Microsoft的Web技术的应用已经进入连Microsoft自己也才刚刚开始探索的领域。比如11月,超出SQL Server最大同时连接数,MySpace系统崩溃。Benedetto说,这类可能引发系统崩溃的情况大概三天才会出现一次,但仍然过于频繁了,以致惹人恼怒。一旦数据库罢工,"无论这种情况什么时候发生,未缓存的数据都不能从SQL Server获得,那么你就必然看到一个'意外错误'提示。"他解释说。

  去年夏天,MySpace的Windows 2003多次自动停止服务。后来发现是操作系统一个内置功能惹的祸--预防分布式拒绝服务攻击(黑客使用很多客户机向服务器发起大量连接请求,以致服务器瘫痪)。MySpace和其他很多顶级大站点一样,肯定会经常遭受攻击,但它应该从网络级而不是依靠Windows本身的功能来解决问题--否则,大量 MySpace合法用户连接时也会引起服务器反击。"我们花了大约一个月时间寻找Windows 2003服务器自动停止的原因。"Benedetto说。最后,通过Microsoft的帮助,他们才知道该怎么通知服务器:"别开枪,是友军。"

  紧接着是在去年7月某个周日晚上,MySpace总部所在地洛杉矶停电,造成整个系统停运12小时。大型Web站点通常要在地理上分布配置多个数据中心以预防单点故障。本来,MySpace还有其他两个数据中心以应对突发事件,但Web服务器都依赖于部署在洛杉矶的SAN。没有洛杉矶的SAN,Web服务器除了恳求你耐心等待,不能提供任何服务。Benedetto说,主数据中心的可靠性通过下列措施保证:可接入两张不同电网,另有后备电源和一台储备有30天燃料的发电机。但在这次事故中,不仅两张电网失效,而且在切换到备份电源的过程中,操作员烧掉了主动力线路。2007年中,MySpace在另两个后备站点上也建设了SAN。这对分担负荷大有帮助--正常情况下,每个SAN都能负担三分之一的数据访问量。而在紧急情况下,任何一个站点都可以独立支撑整个服务,Benedetto说。MySpace仍然在为提高稳定性奋斗,虽然很多用户表示了足够信任且能原谅偶现的错误页面。" 作为开发人员,我憎恶Bug,它太气人了。"Dan Tanner这个31岁的德克萨斯软件工程师说,他通过MySpace重新联系到了高中和大学同学。"不过,MySpace对我们的用处很大,因此我们可以原谅偶发的故障和错误。" Tanner说,如果站点某天出现故障甚至崩溃,恢复以后他还是会继续使用。

  这就是为什么Drew在论坛里咆哮时,大部分用户都告诉他应该保持平静,如果等几分钟,问题就会解决的原因。Drew无法平静,他写道,"我已经两次给MySpace发邮件,而它说一小时前还是正常的,现在出了点问题……完全是一堆废话。"另一个用户回复说,"毕竟它是免费的。"Benedetto坦承100%的可靠性不是他的目标。"它不是银行,而是一个免费的服务。"他说。

  换句话说,MySpace的偶发故障可能造成某人最后更新的个人资料丢失,但并不意味着网站弄丢了用户的钱财。"关键是要认识到,与保证站点性能相比,丢失少许数据的故障是可接受的。"Benedetto说。所以,MySpace甘冒丢失2分钟到2小时内任意点数据的危险,在SQL Server配置里延长了"checkpoint"操作--它将待更新数据永久记录到磁盘--的间隔时间,因为这样做可以加快数据库的运行。Benedetto 说,同样,开发人员还经常在几个小时内就完成构思、编码、测试和发布全过程。这有引入Bug的风险,但这样做可以更快实现新功能。而且,因为进行大规模真实测试不具可行性,他们的测试通常是在仅以部分活跃用户为对象,且用户对软件新功能和改进不知就里的情况下进行的。因为事实上不可能做真实的加载测试,他们做的测试通常都是针对站点。"我们犯过大量错误,"Benedetto说,"但到头来,我认为我们做对的还是比做错的多。"

星期三, 五月 28, 2008

修改Emacs的文件存储编码



C-x c 输入编码名称,如utf-8 可以改变文件的存储编码.
或C-x f 输入编码名称
M-x revert-buffer 重新加载缓冲区
也可以用M-x set-buffer-file-coding-system 来设置。然后一样的用 revert-buffer 来重读文件即可

星期六, 五月 24, 2008

ls指令说明



ls

ls 命令可以说是linux下最常用的命令之一。它有众多的选项,其中有很多是很有用的,你是否熟悉呢?下面列出了 ls 命令的绝大多数选项。


-a 列出目录下的所有文件,包括以 . 开头的隐含文件。
-b 把文件名中不可输出的字符用反斜杠加字符编号(就象在C语言里一样)的形式列出。
-c 输出文件的 i 节点的修改时间,并以此排序。
-d 将目录象文件一样显示,而不是显示其下的文件。
-e 输出时间的全部信息,而不是输出简略信息。
-f -U 对输出的文件不排序。
-g 无用。
-i 输出文件的 i 节点的索引信息。
-k 以 k 字节的形式表示文件的大小。
-l 列出文件的详细信息。
-m 横向输出文件名,并以“,”作分格符。
-n 用数字的 UID,GID 代替名称。
-o 显示文件的除组信息外的详细信息。
-p -F 在每个文件名后附上一个字符以说明该文件的类型,“*”表示可执行的普通
文件;“/”表示目录;“@”表示符号链接;“|”表示FIFOs;“=”表示套
接字(sockets)。
-q 用?代替不可输出的字符。
-r 对目录反向排序。
-s 在每个文件名后输出该文件的大小。
-t 以时间排序。
-u 以文件上次被访问的时间排序。
-x 按列输出,横向排序。
-A 显示除 “.”和“..”外的所有文件。
-B 不输出以 “~”结尾的备份文件。
-C 按列输出,纵向排序。
-G 输出文件的组的信息。
-L 列出链接文件名而不是链接到的文件。
-N 不限制文件长度。
-Q 把输出的文件名用双引号括起来。
-R 列出所有子目录下的文件。
-S 以文件大小排序。
-X 以文件的扩展名(最后一个 . 后的字符)排序。
-1 一行只输出一个文件。
--color=no 不显示彩色文件名
--help 在标准输出上显示帮助信息。
--version 在标准输出上输出版本信息并退出。

  只列出子目录
1. ls -F | grep /$ 或者 alias sub = "ls -F | grep /$"(linux)
2. ls -l | grep "^d" 或者 ls -lL | grep "^d" (Solaris)

  计算当前目录下的文件数和目录数
下面命令可以分别计算当前目录下的文件和目录个数:
# ls -l * |grep "^-"|wc -l ---- to count files
# ls -l * |grep "^d"|wc -l ----- to count dir

  显示彩色目录列表
打开/etc/bashrc, 加入如下一行:
alias ls="ls --color"
下次启动bash时就可以像在Slackware里那样显示彩色的目录列表了, 其中颜色的含义如下:
1. 蓝色-->目录
2. 绿色-->可执行文件
3. 红色-->压缩文件
4. 浅蓝色-->链接文件
5. 灰色-->其他文件

ls -tl --time-style=full-iso sshd
ls -ctl --time-style=long-iso

How to enable mouse wheel in Ubuntu on VMware



Steps to Enable Mouse Wheel Scrolling in Ubuntu Hardy under VMware Fusion

Launch a Terminal (Applications menu -> Accessories -> Terminal).

Type:

sudo gedit /etc/X11/xorg.conf

Scroll down (it’s not far, perhaps 20 - 30 lines) till you see a block that looks like this:

Section "InputDevice"
Identifier "Configured Mouse"
Driver "vmmouse"
[.. blah blah blah ..]
EndSection

Replace that whole section with this:

Section "InputDevice"
Identifier "Configured Mouse"
Driver "vmmouse"
Option "CorePointer"
Option "Device" "/dev/input/mice"
Option "Protocol" "ImPS/2"
Option "Buttons" "5"
Option "ZAxisMapping" "4 5"
EndSection

Save the file, then close all your apps and hit Ctrl+Alt+Backspace. X restarts within a few seconds, and you’re back up and running. Scrolling should now be possible!

I haven’t gotten to the bottom of horizontal scrolling yet. I thought a ZAxisMapping of “4 5 11 12″ would do it, but I suspect either VMware Fusion’s mouse driver does things a different way, or maybe it’s mouse specific (not likely). I’ll update this post if I work it out.

星期三, 五月 21, 2008

[fwd]Freemarker和Velocity的分析

1,需求
最近要开发新闻发布系统,新闻信息量比较大,访问也相对比较频繁,对服务器造成的压力也很大。考虑到新闻内容更新频率小,内容相对比较简单,我们决定将新闻版块生成静态页面,这样可以加快访问速度,同时也减轻服务器的负担。 

2,备选技术分析、对比:Velocity和Freemarker
这两个模板技术我们都做了尝试,Velocity和Freemarker非常相似,它们都是可以在Servlet容器外使用的模版语言。Velocity相对来说比较简单,轻便一点,语法要求也没Freemarker那么严格,而Freemarker相对功能也比较强大一些。
VelocityStruts是VelocityTools提供的,它与Struts实现了很好的衔接。当然,除了语法上简洁以外,还因为它对struts的form的处理,如下所示:
<form action='$link.setAction("/login")' method="post">
  <td>账户:</td>
  <td><input type="text" name="login" value="$!loginForm.login" size="50" maxlength="100"/></td>
  <td>密码:</td>
  <td><input type="text" name="password" value="$!loginForm.password" size="50" maxlength="100"/></td>
  <td colspan="2" align="center"><input type="submit" value="test"/></td>
  </form> 

注意这点:<input type="text" name="login" value="$!loginForm.login" size="50" maxlength="100"/>,这样的优点不言而遇,就是不影响页面的表达,自然是能得到Dreamweaver等工具的良好支持。这也是我比较看中的。
以下是Freemarker的例子:
<#global html=JspTaglibs["/WEB-INF/tld/struts-html.tld"]>
<#global bean=JspTaglibs["/WEB-INF/tld/struts-bean.tld"]>
<title>新闻发布</title>
<meta http-equiv="Content-Type" content="text/html; charset=GBK" />
<link href="style/style.css" rel="stylesheet" type="text/css">
<@bean.page id="request" property="request"/>
<#assign contextPath = request.contextPath/>
  <@html.form method="post" action="/newsList.do?method=insertNews"> <tr>
  <td width="36%" height="25">&nbsp;</td>
  <td width="64%" height="25"><@html.errors/></td>
  </tr>
  <tr>
  <td height="25" align="right">新闻标题:</td>
  <td height="25"><@html.text property="newsTitle" styleClass="input1"/></td>
  </tr>
  <tr>
  <td height="25" align="right">新闻内容:</td>
  <td height="25">
  <@html.textarea property="newsContent" cols="80" rows="10"/>
  </td>
  </tr>
  <tr>
  <td height="25" align="right">&nbsp;</td>
  <td height="25"><@html.submit value="确 定" styleClass="button1"/>&nbsp;&nbsp;<@html.button value="重 置" styleClass="button1"/></td>
  </tr>
  </@html.form> 

FreeMarker的表单域是这样声名的
<@html.form method="post" action="/newsList.do?method=insertNews">
<@html.text property="newsDate" styleClass="input1"/>
显然从这方面来说,我觉得Freemarker页面不如Velocity那么清爽。另外可从网上获取Velocity的Dreamweaver的插件,这样在Dreamweaver中设计和调整页面都很爽,而Freemarker找了半天也没找到其相应的插件。当然,这并不代表Freemarker不如Velocity,Freemarker功能显然比Velocity强一些,也就是说,Velocity能做到的,Freemarker基本也能做到,Velocity在某些方面不能做到的,Freemarker也能做到。
以下是我从网上摘自同仁的分析:
  Velocity是一个简单而且更加轻量级的工具,但是它没有达到FreeMarker能够做的许多任务,而且它的模板语言不是很强大 
 我们认为对于大多数应用程序,FreeMarker比Velocity工作更简单,因为: 
 使用Velocity,你需要寻找特定工具或各种工作环境来一次次的解决典型的模板创作任务,结果会浪费更多时间 
 工作环境经常意味着在Velocity模板中直接使用Java对象的方法,这违反了简单、无编程HTML设计的观念 
 或者将表示任务移到控制器代码中,这违反了MVC模式 
 使用FreeMarker,可以以out-of-the-box(如何翻译确切?)的方式实现Velocity所能做的 

2、特性比较清单 
下面是一个使用FreeMarker能够实现,而Velocity不能实现的不太全面的特性清单: 
(1)数字和日期支持 
 可以对任何数字类型进行算术运算和比较,包括精度类型 
 可以比较和显示(格式化)日期/时间值 
(2)国际化 
 根据各种内建和定制的数字格式,格式化本地敏感的数字 
 根据各种内建和定制的日期格式,格式化本地敏感和时区敏感的日期 
 标识(变量名)可以包含非英语字符,如重音字符、阿拉伯字符、中文字符等 
(3)循环处理 
 可以跳出循环 
 可以在循环外访问循环体内的控制变量 
 可以测试是否达到最后一次循环 
(4)模板级别的数组处理 
 可以使用类似[i]语法的索引方式访问数组元素 
 可以查询数组长度 
(5)宏 
 宏可以有局部变量 
 可以递归调用宏,同样可以在模板的后面定义要调用的宏 
 调用宏时,可以按位置或名字的方式传递参数 
 宏参数可以有缺省值,使得在调用时忽略参数也有效 
 调用的宏可以有嵌套的体内容(<@myMacro>body</@myMacro>),能够在宏被调用时进行处理 
 宏是纯变量的,可以基于表达式来执行宏,或者作为参数传递给另一个宏 
(6)命名空间 
 可以对变量使用多命名空间,这对创建宏库很重要,因为这可以避免应用程序中指定的变量和宏库中变量的名字冲突 
(7)使用内建的函数/操作符维护Java无关的string、list和map 
 可以将字符串转换成大/小写、首字符大/小写,对HTML、XML或RTF进行转义处理,substring、split、查询字符串长度、find/replace子串等等 
 通过索引访问list元素,获得子list,合并list,查询list长度,对list排序 
 通过key变量访问map元素,检查map是否为空,获得key或值的list 
(8)揭示模板中的错误 
 当访问一个未定义的变量,FreeMarker不会沉默;你可以配置FreeMarker来停止render模板显示错误信息,或者跳过错误部分;无论哪种,FreeMarker会记录问题(日志) 
 在写错指令名时,FreeMarker会抛出异常 
(9)高级render控制 
 可以使用一组标记来封装模板的一块区域,以便在块区中所有要修改的地方应用HTML或XML转义(或其它使用FreeMarker表达式表示的转换) 
 FreeMarker有转换器,它们是模板的一块区域,在render时,通过转换过滤;内建的转换器包括空白字符压缩、HTML和XML转义;你可以实现自己的转换器;当然转换器可以嵌套 
 可以使用flush指令显式的flush输出 
 可以使用stop指令停止render 
(10)文字 
 除了通常的字符串、数字和布尔值文字,也可以在模板中定义list和map文字 
 支持所有的Java转义文字:\b、\t、\n、\f、\r、\"、\'、\\,也支持\xXXXX使用UNICODE指定字符 
(11)高级空白字符移除 
 FreeMarker坚持移除各行只包含不输出FreeMarker标记的空白字符 
 对于明显要整修掉不需要的空白字符的指令来说,空白字符是个大问题 
(12)集成其它技术 
 可以在模板中使用JSP标记库 
 可以直接在Python工程中使用 
(13)强大的XML转换能力 

 在2.3版本中,FreeMarker具有强大的新XML转换能力,使得替代XSLT成为可能 

 Velocity在这方面是无法真正竞争的,除非改进核心引擎,如支持宏库映射到名字空间,宏中支持局部变量 

(14)高级模板元程序 
 可以捕获输出的任何部分到context变量中 
 可以解释任何context变量,如果它是一个模板定义 
 上述两者的结合使用 
由于我们项目是基于Struts的,而两种模板在数据输出上基本上都大同小异,所以我把重点放到了form处理的对比上了,由于是刚学了不久,仅仅参考了一些网上资料和个人的看法。所以以上的并不是很全面,至于项目组中要使用哪个,还是要看其它成员的意见。 

3,放弃JSP而选模板技术。
我们用JSP也蛮长时间了,JSP有时要在页面嵌入代码,使页面看起来很混乱,而模板可以让页面很整洁,也便于我们调试,不仅如此,模板的语法更简明、更好用,也比JSP功能强大,据说性能也比JSP好,据说也很接近静态页面输出速度.

trackback:

http://weishuwei.spaces.live.com/blog/cns!C55C1C27B8EE0730!204.entry

[fwd]Struts2 Freemarker Jmesa(表格、分页) 使用的一点心得


最近做一个应用的时候用到了Jmesa(至于Jmesa的详细介绍,请Google),但是关于Struts2和Jmesa的资料特别少,费尽周折总算让他们两个正常运行了,现在把使用他们的一些心得写下来与大家分享。
    版本:
    Struts2          : 2.0.11
    Spring           : 2.5.1
    Freemarker  : 2.3.12
    Jmesa           : 2.2.9
 
    Eclipse 3.3
    对应Eclipse3.3的插件(没用MyEclipse,我依然活得不错,哈哈~)
    
    Tomcat 6.0.*
 
    Struts2与Freemarker的配置非常简单――根本不用配置,呵呵,关键点就在:怎么在Struts2环境下使用Jmesa?当然我只用到了Jmesa提供的Taglib,没用使用到其他高级功能。
    (1)、Jmesa实现的Taglib只需要在页面给它一个 List等集合类型的变量就可以正常显示。使用分页功能需要加入下面这段脚本: <script type="text/javascript">
    function onInvokeAction(id) ...{
        setExportToLimit(id, '');
        createHiddenInputFieldsForLimitAndSubmit(id);
    }
</script>
    (2)、使用导出功能,此处以Excel为例。需要加入以下脚本:     <script type="text/javascript">

        function onInvokeExportAction(id) ...{
            var parameterString = createParameterStringForLimit(id);
            alert(parameterString);
            location.href = '${request.getContextPath()}/(此处为Action的Url)?' + parameterString;
        }
    </script>
    还有关键的一点就是:Action要实现ServletRequestAware,ServletResponseAware这两个接口,并且加入以下代码:     private HttpServletRequest request;
    private HttpServletResponse response;
    
    
    public void setServletRequest(HttpServletRequest request) ......{
        this.request = request;
    }
    
    public void setServletResponse(HttpServletResponse response) ......{
        this.response = response;
    }
    以上变量定义了实例变量request 和 response,为什么要这样做呢?看一下Jmesa的Tag example就知道了,如下:         
        TableFacade tableFacade = new TableFacadeImpl(id, request);
        tableFacade.setItems(items);
        tableFacade.setColumnProperties("password", "nickname");
        tableFacade.setExportTypes(response, CSV, EXCEL); // Tell the tableFacade what exports to use.    
        Limit limit = tableFacade.getLimit();
        if (limit.isExported()) ...{
            tableFacade.getTable().setCaption("user");
            tableFacade.getTable().getRow().getColumn("password").setTitle("password");
            tableFacade.getTable().getRow().getColumn("nickname").setTitle("nickname");
            tableFacade.render();
            return null;
        }
    最关键的就是这两句了: TableFacade tableFacade = new TableFacadeImpl(id, request);
tableFacade.setExportTypes(response, CSV, EXCEL); // Tell the tableFacade what exports to use.
    第一句中如果没有request对象的话,不能实例化TableFacade类型的对象。
    第二句中如果没有response对象的话,就没有数据。
    除此之外还有一点要注意的就是页面中定义的tableFacade的id一定要与Action中的id的值相同,此id起标识导出文件的文件名的作用,也唯一标识一个table。
    好了只要注意以上这些Jmesa的这个Taglib就可以使用了。
    至于在Freemarker中使用Jmesa的这个Taglib,有以下注意事项:
    (1)、items的值(即数据集合)直接写变量名就可以
    (2)、maxRows属性写为maxRows=8 不用加引号
    以上两处注意事项不知道是不是Freemarker版本的问题,呵呵,有待检验。
    注:Jmesa的功能非常强大,可以实现复杂的表格 。。。。。。 好东西 思想先进

track:

http://blog.csdn.net/jockCreate/archive/2008/02/20/2110310.aspx


Freemarker简介

FreeMarker是一个模板引擎,一个基于模板生成文本输出的通用工具,使用纯Java编写 


FreeMarker被设计用来生成HTML Web页面,特别是基于MVC模式的应用程序 


虽然FreeMarker具有一些编程的能力,但通常由Java程序准备要显示的数据,由FreeMarker生成页面,通过模板显示准备的数据 

FreeMarker不是一个Web应用框架,而适合作为Web应用框架一个组件 


FreeMarker与容器无关,因为它并不知道HTTP或Servlet;FreeMarker同样可以应用于非Web应用程序环境 

FreeMarker更适合作为Model2框架(如Struts)的视图组件,你也可以在模板中使用JSP标记库 

FreeMarker是免费的 


1、通用目标 


能够生成各种文本:HTML、XML、RTF、Java源代码等等 


易于嵌入到你的产品中:轻量级;不需要Servlet环境 


插件式模板载入器:可以从任何源载入模板,如本地文件、数据库等等 


你可以按你所需生成文本:保存到本地文件;作为Email发送;从Web应用程序发送它返回给Web浏览器 




2、强大的模板语言 


所有常用的指令:include、if/elseif/else、循环结构 


在模板中创建和改变变量 


几乎在任何地方都可以使用复杂表达式来指定值 


命名的宏,可以具有位置参数和嵌套内容 


名字空间有助于建立和维护可重用的宏库,或者将一个大工程分成模块,而不必担心名字冲突 


输出转换块:在嵌套模板片段生成输出时,转换HTML转义、压缩、语法高亮等等;你可以定义自己的转换 



3、通用数据模型 


FreeMarker不是直接反射到Java对象,Java对象通过插件式对象封装,以变量方式在模板中显示 


你可以使用抽象(接口)方式表示对象(JavaBean、XML文档、SQL查询结果集等等),告诉模板开发者使用方法,使其不受技术细节的打扰 




4、为Web准备 


在模板语言中内建处理典型Web相关任务(如HTML转义)的结构 


能够集成到Model2 Web应用框架中作为JSP的替代 


支持JSP标记库 


为MVC模式设计:分离可视化设计和应用程序逻辑;分离页面设计员和程序员 




5、智能的国际化和本地化 


字符集智能化(内部使用UNICODE) 


数字格式本地化敏感 


日期和时间格式本地化敏感 


非US字符集可以用作标识(如变量名) 


多种不同语言的相同模板 




6、强大的XML处理能力 


<#recurse> 和<#visit>指令(2.3版本)用于递归遍历XML树 


在模板中清楚和直觉的访问XML对象模型




Freemarker的模板文件内容

FreeMarker模版文件主要由如下几个部分组成: 
1.文本:直接输出的部分。 
2.注释:即<#-- ... -->格式部分,不会输出。 
3.插值(Interpolation:即${...},或#{...}格式的部分,将使用数据模型中的部分替代输出。 
4.FTL指令:FreeMarker指令,和HTML标记类似,名字前加#予以区分,不会输出。 

一. 模版结构 
上面四个部分,文本部分和注释部分都比较简单,此处不再赘述,这里主要介绍插值(Interpolation)和FTL指令。 
下面就是FreeMarker模版的例子: 
<html><br> 
<head><br> 
<title>Welcome!</title><br> 
</head><br> 
<body><br> 
<#-- 注释部分 --><br> 
<#-- 下面使用插值 --> 
<h1>Welcome ${user}!</h1><br> 
<p>We have these animals:<br> 
<ul><br> 
<#-- 使用FTL指令 --> 
<#list animals as being><br> 
<li>${being.name} for ${being.price} Euros<br> 
</#list><br> 
</ul><br> 
</body><br> 
</html> 
上面的FTL模版是一个典型的HTML模版,该模版中包含了注释、FTL指令、插值和基本文本四个组成部分。 

二. FTL指令规则 
在FreeMarker中,使用FTL标签来使用指令,FreeMarker有三种FTL标记,这和HTML标签是完全类似的: 
1.开始标签:<#directivename parameters> 
2.结束标签:</#directivename> 
3.空标签:<#directivename parameters/> 
实际上,使用标签时前面的#符号也可能变成@,如果该指令是一个用户指令而不是系统内建指令时,应将#符号改为@符号。 
使用FTL标签时,应该有正确的嵌套,而不是交叉使用,这与XML标签的用法完全一样。因此,下面的代码是错误: 
<ul> 
<#list animals as being> 
<li>${being.name} for ${being.price} Euros 
<#if use = "Big Joe"> 
(except for you) 
</#list> 
</#if> 
<#-- 上面的list指令和if指令没有形成正确嵌套 --> 
</ul> 
如果使用不存在的指令,FreeMarker不会使用模板输出,而是产生一个错误消息。 
FreeMarker会忽略FTL标记中的空白字符,如下面的例子: 
<#list[BR] 
animals as[BR] 
being[BR] 
>[BR] 
${being.name} for ${being.price} Euros[BR] 
</#list > 
值得注意的是:<、</和指令之间不允许有空白字符。 

三. 插值规则 
FreeMarker的插值有如下两种类型: 
1.通用插值:${expr} 
2.数字格式化插值:#{expr}或#{expr; format} 
通用插值 
对用通用插值,又可分为如下三种情况: 
1.插值结果为字符串值:直接输出表达式结果 
2.插值结果为数字值:根据缺省格式(由#setting指令设置)将表达式结果转换成文本输出;可以使用内建的字符串函数格式化单个插值,看下面的模版页面。 
<#setting number_format="currency"/> 
<#assign answer=42/> 
${answer} 
${answer?string} <#-- the same as ${answer} --> 
${answer?string.number} 
${answer?string.currency} 
${answer?string.percent} 
输出结果是: 
$42.00 
$42.00 
42 
$42.00 
4,200% 
q 插值结果为日期值:根据缺省格式(由#setting指令设置)将表达式结果转换成文本输出;可以使用内建的字符串函数格式化单个插值,下面是一个使用格式模式的例子: 
${lastUpdated?string("yyyy-MM-dd HH:mm:ss zzzz")} 
${lastUpdated?string("EEE, MMM d, ''yy")} 
${lastUpdated?string("EEEE, MMMM dd, yyyy, hh:mm:ss a '('zzz')'")} 
输出的结果如下: 
2003-04-08 21:24:44 Pacific Daylight Time 
Tue, Apr 8, '03 
Tuesday, April 08, 2003, 09:24:44 PM (PDT) 
插值结果为布尔值:根据缺省格式(由#setting指令设置)将表达式结果转换成文本输出;可以使用内建的字符串函数格式化单个插值,下面是一个例子: 
<#assign foo=true/> 
${foo?string("yes", "no")} 
输出结果是: 
yes 
数字格式化插值 
数字格式化插值可采用如下#{expr; format}形式可以用来格式化数字,其中format可以是: 
mX:小数部分最小X位 
MX:小数部分最大X位 
看下面的FreeMarker模版: 
<#assign x=2.582/> 
<#assign y=4/> 
#{x; M2} <#-- 输出2.58 --> 
#{y; M2} <#--输出4 --> 
#{x; m1} <#-- 输出2.6 --> 
#{y; m1} <#-- 输出4.0 --> 
#{x; m1M2} <#-- 输出2.58 --> 
#{y; m1M2} <#-- 输出4.0 -->


--
----------------------------------

   你的支持 我的坚持
  Lead to The IT Future

----------------------------------

JMesa简介-ExtremeTable的下一代


说到ExtremeTable(以下简称ET,呃,,,ET.....),可以说不知道的人甚少.不过估计用的也未必多罢了.今天,给大家介绍一个由ET的作者重新实现的一套关于Table的API.JMesa.
我是一个偶然的机会知道Jmesa,我在做一个数据展现系统的时候想寻找ET的帮忙,但发现ET己不再更新,作者把精力转移到了新的项目中,也就是这个 JMesa.这个项目的目的是为开发者提供更有效的表格展现的API,而不是简单的TagLib.无论从灵活性,易扩展性,易用性,均比ET上了一个层 次.最近Release的版本里面,并不包括TagLib.而在下一个版本(2.1.0)将会加入TagLib,目前TagLib己经可用,在SVN里已 有.只是等待下一个版本的发布,其间会有一些更新,不过会兼容目前的TagLib的.
假如我从API开始介绍JMesa,恐怕并不是个好的办法,像我以前的文章里面有介绍,结果反响不大.这次决定从TagLib入手,来给大家介绍一下Jmesa.
大家可以从附件里拿到一个Demo.注意Demo依赖JMesa以及其他Lib.在Lib文件夹下有详细说明.
现在来看看JMesa的使用:
xml 代码
 
<jm:table id="product" items="products" caption="product listing">   
  <jm:column property="name" sortable="true" filterable="true"/>   
  <jm:column property="price" />   
  <jm:column property="createdTime" />   
  <jm:column property="id" title="edit">   
  <a href="viewProduct.action?id="><jm:property name="name"/></a>   
  </jm:column>   
</jm:table>   

估计比较容易看得懂的代码吧.
Jmesa 的检签规范当中只有三个Tag:Table,Row,Column.而当前的TagLib实现中只实现了Table和Column两个(Row是可选 的).另加一个Property的Tag.此阶段,Property的Tag是很有用的,其起到的作用与Webwork的PropertyTag相差无几, 用来获得对象的某个属性.之所以使用Property Tag是因为当前的TagLib有个限制就是暂时不支持如JSTL的${}这种写法.将来会支持,届时Property Tag也会继续获得兼容.Jeff比较倾向于使用迭代的方式实现Tag,那样可以支持${}这样的写法.不过作为TagLib的开始,问题不大.有时间再 重构一下TagLib,支持JSTL的写法.
好了,来说一说这些Tag的使用方法:
Table:Attribute Description 
id 表格的ID(必须) 
items 对象或者Map的集合 (必须)
caption 表格的标题 
theme 表格的主题,自定义样式
exportTypes 使用逗号分割导出的类型,目前支持导出类型有CSV,Excel 
width 表格宽度
style 即表格的Style属性
styleClass 使用的Css的Class名字
border 表格宽
cellpadding 表格属性
cellspacing 表格属性

实际上,真正Release的版本里面将会加上var以及Limit属性.
var属性值即在Column标签里可以获得的对象变量.
Limit属性是保存在当前请求的Limit的对象名.
Row:Attribute Description 
highlighter 是否高亮显示
onclick 点击事件
onmouseout 鼠标移出事件
onmouseover 鼠标移入事件

该Tag是可选的.实际上Jmesa提供了一系列默认的事件响应,有必要的情况下才使用.
Column:Attribute Description 
property Java对象或Map的属性名 
title 列的名称 
filterable 是否可按过滤条件查找
sortable 是否要排序
width 列宽
style Style属性
styleClass 使用的Css的Class的名字

ColumnTag的使用方法有下面几种:
xml 代码
 
<jm:column property="name"/>   

将仅仅输出对象中Name属性值.列名是Name
xml 代码
 
<jm:column property="name" title="名字" sortable="true" filterable="false"/>   

这样可以得到自定义的列名,可以让列可查找,可排序,当然你Server端需要相应提供排序及查找功能.不过就算你不提供,客户端也会把当前结果排序和查找的.
xml 代码
 
<jm:column property="id" title="edit">   
  <a href="viewProduct.action?id="><jm:property name="name"/></a>   
</jm:column>   

这里结合了PropertyTag.实现自定义列显示.可以灵活定制自己的单元格.
在ColumnTag里面,使用PropertyTag的时候,可以指定Name属性,如果不指定则使用当前Column的Property属性值.
以后将支持:

xml 代码
 
<jm:column property="id" title="edit">   
  <a href="viewProduct.action?id=${id}">${name}</a>   
</jm:column>   
这样的写法.当然会继续兼容PropertyTag,尽管不是Tag规范里的东西.

相信经过上面的一番介绍,大家对Jmesa有一定的感性认识了吧.还没有?下载Demo,扔进Tomcat 的App里跑一下就明白了.
有什么建议,请一定要告诉我 :).
 

--
----------------------------------

   你的支持 我的坚持
  Lead to The IT Future

----------------------------------

OGNL表达式语言浅谈


OGNL(Object Graphic Navigation Language,对象图导航语言)是一种功能强大的EL(Expression Language,表达式语言,JSP2.0规范),Struts2的核心表达式语言,OGNL是一个开源JAVA项目,但因为使用Struts2,我们完全不需要知道OGNL到底里面是什么东东,只需要按照Struts2的规则知道如何使用就OK了!第二章已经说过(请参看第二章的OGNL结构图),Struts2将Action中的实例压入值栈(ValueStack,值栈,Struts2的根对象,可以把它简单的理解为List,只不过它遵循堆栈的特点,先进后出!),session等放入Context Map中,然后使用OGNL遍历对象结构图进行操作。 

在JSP中,session、request、application、attr(如果可以就从pageContext查找,否则就依次到request、session、application中查找)、parameters(用于取URL上的参数,同名的变量可以使用索引)等对象取值时要使用前缀 # 告诉Struts2不要到值栈中查找,例如:(1.)#session.infomation,#session['student-information'],OGNL中使用 . 或者['']访问对象的属性,两者的区别是当属性中有"-"等特殊字符时,我们需要使用['']; 
(2.)URL为http://locaohost:9999/struts01/HelloWorld.ok?name=gold&&password=jsmart,如果我想取name的值,需要这样写#parameters.name,取password的值就是#parameters.password;如果是http://localhost:9999/struts01/HelloWorld.ok?password=gold&&password=jsmart,#parameters.password[0]取的就是gold,#parameters.password[1]=jsmart; 
(3.)%{A}所有基于这种形式的内容,都会被解析并到值栈中求值,也就是会到Value Stack中查找A所代表的值;如果你想A被当作字符串原样传递,那么可以这样表示%{'A'},当然你直接使用A有的时候也是可以的,但为了通用性,建议使用%{'A'},以免产生不必要的麻烦。 
(4.)OGNL操作集合,例如值栈中存在map,我们可以这样访问map['a'],表示访问Map中key值为a的value值是多少,map.size访问大小等等。 
(5.)OGNL访问类中的静态变量和静态方法:@完整类名@属性名,@完整类名@方法名,例如: 
Package net.ilkj.ognl 
Public Class A{ 
Public static final String a="1"; 

Public static String findA() 

Return "2"; 

,我们就可以在页面上使用<:sproperty value="@net.ilkj.ognl.A@a"/>尽心输出! 

从上面可以看出,在Struts2中使用OGNL,可以简单看作就是对象.属性。


星期二, 五月 20, 2008

让图片黑白的css





星期一, 五月 19, 2008

Hibernate的get和load的区别



1、hibernate中get方法和load方法的根本区别在于:如果你使用load方法,hibernate认为该id对应的对象(数据库记录)在数据库中是一定存在的,所以它可以放心的使用,它可以放心的使用代理来延迟加载该对象。在用到对象中的其他属性数据时才查询数据库,但是万一数据库中不存在该记录,那没办法,只能抛异常,所说的load方法抛异常是指在使用该对象的数据时,数据库中不存在该数据时抛异常,而不是在创建这个对象时。由于session中的缓存对于hibernate来说是个相当廉价的资源,所以在load时会先查一下session缓存看看该id对应的对象是否存在,不存在则创建代理。所以如果你知道该id在数据库中一定有对应记录存在就可以使用load方法来实现延迟加载。
对于get方法,hibernate会确认一下该id对应的数据是否存在,首先在session缓存中查找,然后在二级缓存中查找,还没有就查数据库,数据库中没有就返回null。

2、虽然好多书中都这么说:“get()永远只返回实体类”,但实际上这是不正确的,get方法如果在session缓存中找到了该id对应的对象,如果刚好该对象前面是被代理过的,如被load方法使用过,或者被其他关联对象延迟加载过,那么返回的还是原先的代理对象,而不是实体类对象,如果该代理对象还没有加载实体数据(就是id以外的其他属性数据),那么它会查询二级缓存或者数据库来加载数据,但是返回的还是代理对象,只不过已经加载了实体数据。

3 get方法首先查询session缓存,没有的话查询二级缓存,最后查询数据库;反而load方法创建时首先查询session缓存,没有就创建代理,实际使用数据时才查询二级缓存和数据库。

总之对于get和load的根本区别,一句话,hibernate对于load方法认为该数据在数据库中一定存在,可以放心的使用代理来延迟加载,如果在使用过程中发现了问题,只能抛异常;而对于get方法,hibernate一定要获取到真实的数据,否则返回null。

星期日, 五月 18, 2008

调整



〔调整落差〕

在学校里,自己的成绩好,也只是与同班同学相比。

出了社会,自己的工作的成绩,是与不同国家、不同年纪、不同背景的人比。

可能一下子会有很大的落差。

你可能说,人生不是比来比去的。

但是好朋友一定要跟你说,你可以不比,不过你不能不知道:你究竟输在那里?

找到一群可以帮助你成长的好朋友和聪明的竞争者,你就赢了别人好几步。

有一位很有智能的长者说过:「今天每一个家长都会说,『孩子,我要你赢!』但是,
却很少有家长教导说,『孩子,你该怎么输!输的原因怎么检讨出来!怎么原地爬起来
!怎样渡过人生的各种难关!』

〔工作态度〕

每天上班最好有正面的心情。用快乐的心情面对每个人,你会有很多朋友,老板也会想
教你东西,乐于与你沟通。如果与老板无法沟通,你觉得你会有加薪机会吗﹖
就算你不缺那份薪水,你也得不到新增的工作机会,来帮助你日后的发展。

【静静的吃三碗饭】

绝对没错,不要一出社会,就一天到晚与人计较或说谁谁谁没做他的工作。

真正的赢家是不出声的。

〔把掌声留给别人〕

把掌声留给别人,投资在别人的身上。
把掌声留给自己,你的荷包不会变多一点,但你的朋友会少一个。
而把掌声留给自己的伙伴,你会多一个朋友,你的荷包不会变少一点。

〔永远不要说---我已经尽力了!〕

我们可以安慰受挫折的朋友:『你已经尽力了!』

但当我们说出『我已经尽力了!』时,任何人都可以质疑你。
人们会问:『喔!真的吗?如果你是这么尽力,为什么成果是如此不堪!!』

如果你真的已经尽力了,那万一下一次不能再加力,那成果岂不更糟?!

通常,只有失败者、逃避者,才会大言不惭地说:『我已经尽力了!』

社会上的人,很务实地,从来就不会谅解一个一味地说『我已经尽力了!』的人!

你要不相信,换个说法,说『对不起!我应该可以做的更好的!如果能再有机会,我一
定尽力做好!』


你将发现,机会将源源而至。

再提醒一句,说『我已经够认真了!』、『我真的很不错!』,跟说『我已经尽力
了!』,有异曲同工之「坏」结果。

〔薪水〕

薪水与能力是相关的,但不是绝对的。
我有一个女性朋友,硕士毕业后领3万2仟的薪水;10年后,增加不到25%。

最后她的工作是被另一个刚刚硕士毕业的女生换掉。

她的问题很简单,毕业后就停止进修,她的履历表多了很多年资,但并没有很多经验。

聪明的你,一定要好好的做一张履历表。

而且你一定要知道自己那一张履历表值多少钱,说句不中听的话,至少遇到结婚或丧
事,别人才知道要怎么介绍你嘛!


很多东西不能规划,但是自己的履历表,一定要好好的规划。


〔跟对人〕

虽然【跟对人】很重要,但我要跟你说如果没跟对人,也要在他身上挤出东西来学。

我以前有一个老板,日本作风,不但吹毛求疵,还蔽护他自己的人。前一两年,我好气
他喔。

但是我发现,虽然他不是我的贵人,可是我在他身上学到他的扎实和彻底执行的工作能
力。

对那老板而言,因为我很年轻,还有很多机会。

但是有些人没被裁培,他们一辈子都起不来,他们将来都会面临被裁员的可能。

所以老板并没有错。有时候,看事情要设身处地,换成老板的眼光还看自己,往大方向
看。

〔读书〕
读书是增加知识,但也不要太相信书里面的人。

有些人读了太多书,但是不知变通,不能拿出来适应瞬息万变的社会,结果是变成读死
书了。

但是不能不读书,因为这社会,有时候很复杂,你会需要些书当精神食粮。

〔婚姻〕
家庭结构是脆弱的,禁不起任何人的刻意攻击。

婚姻是可以经营的,放弃自我主见、偶而多迁就对方一些,有时候是解决问题的好办
法。

感情是没有绝对的!不如意时,至少谢谢他
/她陪你走过往日的春夏秋冬。

但女人不能没钱,婚姻或感情出了问题,还可以有尊严地走出家门晒晒和煦的冬阳。

如果又没钱,又不会经营感情,这种问题,只能在家看韩剧哭死你。


〔金钱观〕
金钱是重要工具,但不是生命的全部。

人人要设法让家人丰衣足食,更要知道你钱花去那,要会管理你的收支表。

百分之90的人赚的都是计算式的财富Calculated Wealth
(相信我,英文跟计算机一样,都只是沟通的工具)。

计算式的财富就是你今年赚24万,明年你的目标应该是多少?

稳健收入的前题,是不乱换工作,而且你与你的上司
/工作伙伴合作愉快。

一定要有投资观念,投资不一定是股票那些,而是如投资外文能力,计算机能力,投资自
己的presentation
skills,或沟通能力。

投资未来,不要投资过去。


〔人格〕
人格比薪水或什么都还重要。成功的人大部份都具有好的人格特质。
许多年薪好几百万和千万的人,虽然不是每个人都是白手起家,但是只有好的人格特质
才会在业界长长久久。


只有好的人格,才能在社会上备受尊重。


〔好习惯〕
好的人格又是如何培养的呢?简单说,就是多多培养一些好习惯。以下列举21种可以改
变人生的好习惯。


1 当一个人生活枯燥的时候,他忘了用心体会是一种习惯。

2 当一个人觉得人生乏味的时候,他忘了培养幽默是一种习惯。

3 当一个人体力日差的时候,他忘了运动建身是一种习惯。

4 当一个人工作疲惫的时候,他忘了认真休息是一种习惯。

5 当一个人孤傲狂放的时候,他忘了感恩惜福是一种习惯。

6 当一个人志得意满的时候,他忘了谦冲为怀是一种习惯。

7 当一个人钱不够用的时候,他忘了投资理财是一种习惯。

8 当一个人觉得工作低迷的时候,他忘了激励自己是一种习惯。

9 当一个人怀疑自己的时候,他忘了建立自信是一种习惯。

10 当一个人忽略家人的时候,他忘了爱与关怀是一种习惯。

11 当一个人浑噩度日的时候,他忘了阅读好书是一种习惯。

12 当一个人忙于工作的时候,他忘了安排休闲是一种习惯。

13 当一个人目中无人的时候,他忘了不断学习是一种习惯。

14 当一个人服务不佳的时候,他忘了让顾客满意是一种习惯。

15 当一个人慌张失措的时候,他忘了万全准备是一种习惯。

16 当一个人推诿责任的时候,他忘了勇于承担是一种习惯。

17 当一个人肠枯思竭的时候,他忘了转型思考是一种习惯。

18 当一个人沮丧失意的时候,他忘了检讨改进是一种习惯。

19 当一个人畏惧调职的时候,他忘了提升自己是一种习惯。

20 当一个人沟通障碍的时候,他忘了真诚倾听是一种习惯。

21 当一个人业绩消退的时候,他忘了积极行动是一种习惯。

星期一, 五月 05, 2008

工作流相关术语和定义



1.1.1. 工作流
就是工作从开始到完成的过程。工作流由流程逻辑和路线规则组成。流程逻辑定义了任务的顺序和必须遵循的路线规则,还有截止期限以及由工作流引擎实现的其他业务规则
1.1.2. 流程定义(process definition)
一个图形流程定义或流程图,代表工作流的流程逻辑元素以及各元素之间的关系
1.1.3. 流程实例(process instance):
一个流程实例,通常称为工作,是一个流程定义的运行实例
1.1.4. 状态(state,或者说等待状态):
代表一种对外部参与者的依赖;这意味着在流程运行时流程引擎必须等待,直到外部参与者通知工作流系统指定的状态完成了
1.1.5. 动作(action):
在流程运行过程中,工作流系统为响应指定事件运行的一段程序逻辑;当流程运行过程中指定的事件发生时,工作流系统启动并执行这些动作
1.1.6. 流程上下文变量(process context variable):
保存每一个流程运行的上下文信息;通常在流程定义中声明这些变量,然后在流程实例生成时被实例化
1.1.7. 参与者
以下类型之一:资源集、特定资源、组织单元、角色(一个人在组织内部的作用)、人或系统(自动代理)。
1.1.8. 活动
组成流程定义中的一个逻辑步骤的任务。可以是自动的或人工的。自动指在流程操作过程中定义脚本和触发器的能力。流程定义中的特定活动可以作为无人参与的任务来运行,自动化可以在手工或人力驱动的任务中执行业务规则。常见的一种自动活动就是截止期限管理,如果某个工作项在预定的截止期限之前未能完成,该管理可以自动发送一条提醒消息或触发一个延期程序。
1.1.9. 活动所有者
活动所有者是有权宣布一个活动结束,然后推进工作到流程中的下一个活动的参与者
1.1.10. 工作所有者
工作所有者是有权整体控制流程实例执行过程的参与者
1.1.11. 工作项
代表流程实例中活动的参与者将要执行的工作

星期三, 三月 05, 2008

使用telnet登陆smtp服务发邮件


使用telnet登陆smtp服务发邮件(带身份验证)。
2008-02-18 13:32[root@newsclub east]# telnet smtp.163.com 25 //登陆 smtp.163.com 端口号为 25
Trying 202.108.44.205...
Connected to smtp.163.com (202.108.44.205).
Escape character is '^]'.
220 163.com Coremail SMTP(Anti Spam) System
HELO localhost // 与服务器打招呼,并告知客户端使用的机器名字,可以随便填写
250 OK
AUTH LOGIN //使用身份认证登陆指令
334 dXNlcm5hbWU6
cmVkc29zMw== //输入已经base64_encode()过的用户名.
334 UGFzc3dvcmQ6
MbM2MDQ3NQ== //输入已经base64_encode()过的密码
235 Authentication successful
MAIL FROM:<redsos3@163.com> //告诉服务器发信人的地址
250 Mail OK
RCPT TO:<yourframe@21cn.com> //告诉服务器收信人的地址
250 Mail OK
DATA //正面开始传输信件的内容,且最后要以只含有 . 的特殊行结束。
354 End data with <CR><LF>.<CR><LF>
To:yourframe@21cn.com
From:redsos3@163.com
Subject:test mail
From:redsos3@163.com
test body
. //结束传输信件
250 Mail OK queued as smtp14,F0CPBFsuzUOvoDwE.41582S2
QUIT //断开连接
221 Bye
Connection closed by foreign host.
状态码说明:
220 : 服务就绪
250 :请求邮件动作正确,完成(HELO,MAIL FROM,RCPT TO,QUIT 指令执行成功会返回此信息)
235 :认证通过
221 :正在处理
354 :开始发送数据,结束以 .(DATA指令执行成功会返回此信息)
500 :语法错误,命令不能识别
550 :命令不能执行,邮箱无效
552 :中断处理:用户超出文件空间


--
----------------------------------

   你的支持 我的坚持
  Lead to The IT Future

----------------------------------

星期三, 二月 27, 2008

[fwd]论java架构设计

软件架构作为一个概念,体现在技术和业务两个方面。
从技术角度来说:软件架构随着技术的革新不断地更新其内容,软件架构建立于当前技术和一些基本原则的基础之上。
先说一些基本原则:
分层原则:分层是为了降低软件深度复杂性而使用的关键思想,就像社会有了阶级一样,软件有了层次结构。
模块化原则:模块化是化解软件广度复杂的必然手段,模块化的目的就是让软件分工。
接口实现分离原则随着软件模块化的不断深入改进,面向接口编程而不是面向实现编程可以让复杂度日趋增高的软件降低模块之间的耦合度,从而让各模块更轻松改进。从这个原则出发,软件也从微观进行了细致的规范化。
还有两个比较小但很重要的原则:
细节隐藏原则很显然把复杂问题简化,把难看的细节隐去,能让软件结构更清晰。其实这个原则使用很普遍,java/c++语言中的封装原则以及设计模式中的Facade(外观)模式就很能体现这个原则的精神。
依赖倒置原则随着软件结构的进一步发展,层与层之间、模块与模块之间的依赖逐渐加深,而层、模块的动态可插拔要求不端增大。依赖倒置原则可看视为接口实现分离原则的深化,根据此原则的精神,软件进入了工具时代。这个原则有点类似于知名的好莱坞法则:Don't call us, we'll call you。

以上这些原则奠定了我们的软件架构的价值指标。但软件架构毕竟是建立在当前技术之上的。而每一代技术都有架构模式。过去的不再说了,让我们现在就来看一下当前流行的技术,以及当前我们能采用的架构。

因为面向对象是当前最流行开发技术,且设计模式的大量使用使面向对象的走向成熟,而数据库是当前最有效的存储结构、web界面是当前最流行的用户接口,所以当前最典型的三层次架构就架构在以上几项技术的基础之上,用数据库作存储层、用面向对象来实现业务层、用web来作为用户接口层。我们从三层次架构谈起:
因为面向对象技术和数据库技术不适配,所以在标准三层次架构的基础上,我们增加了数据持久层,来管理O-R双向映射,但目前一直没有最理想的实现技术。cmp和entity bean技术因为其实现复杂,功能前景有限,已接近被淘汰的边缘。JDO及hibernate作为o-r映射的后期之秀,尤其是hibernate,功能相当完备。推荐作为持久层的首选
在业务层,因为当前业务日趋负载,且变动频繁,所以我们必须有足够敏捷的技术来保证我们的适应变化的能力,在标准j2ee系统中session bean负责业务处理,且有不错的性能表现,但采用ejb系统对业务架构模式改变太大,且其复杂而昂贵,业务代码移植性差。而spring 作为一个bean配置的轻量级架构,漂亮的IOC模式实现,对业务架构影响小,所以推荐作为中间层业务框架。
在用户结构层,虽然servlet/jsp/jstl/javaBean 能够实现MVC架构,但终究过于粗糙。struts对MVC架构的实现就比较完美,Taperstry也极好地实现MVC架构,且采用基于事件的方式,非常诱人,惜其不够成熟,我们仍旧推荐struts作为用户接口层基础架构。
因为业务层是三层次架构中最有决定意义的,所以让我们回到业务层细致地分析一下,在复杂的业务我们常常需要以下基础服务的一种或几种:事务一致性服务acid(tool:jta/jts)、并发加锁服务concurrent&&lock、池化管理服务cache、访问控制服务(tool:jaas)、流程控制服务workflow、动态实现服务IOC,串行化消息服务(tool:jms)、负载平衡服务blance等。如果我们不采用重量级应用服务器(如weblogic,websphere,jboss等)及重量级组件(EJB),我们必须自己实现其中一些服务。虽然我们大多情况下,不需要所有这些服务,但实现起来却非易事。幸运的是我们有大量的开源实现代码,但采用开源代码却常常是件不轻松的事。

随着xml作为结构化信息传输和存储地位日渐重要,一些xml文档操作工具(DOM,Digester,SAX等)的使用愈发重要,而随着xml schema的java binding工具(jaxb,xmlbean等)工具的成熟,采用xml schema来设计xml文档格式,然后采用java binding来生成java bean 会成为主要编程模式,而这又进一步使数据中心向xml转移,使在中小数据量上,愈发倾向于以xquery为查询语言的xml数据库。最近还有一个趋势,microsoft,ibm等纷纷大量开发中间软件如(microsoft office之infopath),可以直接从xml schema 生成 录入页面等非常实用的功能。还有web service 的广泛应用,都将对软件的架构有非常重大的影响。至于面向服务架构(SOA)前景如何,三层次架构什么时候走入历史,现在还很难定论。

aop的发展也会对软件架构有很深的影响,但在面向对象架构里,无论aspectJ还是jboss-aop抑是aspectWerks、nanning都有其自身的严重问题:维护性很差,所以说它将很难走远。也许作为一个很好的思想,它将在web service里大展身手。

rdf,owl作为w3c语义模型的标志性的语言,也很难想象能在当前业务架构发挥太大影响。但如果真如它所声称那样,广泛地改变着信息的结构。那么对软件架构也会有深远影响。

有关架构设计的一些忠告:
尽量建立完整的持久对象层.可获得高回报
尽量将各功能分层,分块,每一模块均依赖假定的其它模块的外观
不能依赖静态数据来实现IOC模式,应该依赖数据特征接口,静态数据仅是数据特征接口实现方式之一
架构设计时xml是支持而不是依赖.但可以提供单一的xml版本的实现

从业务角度说:软件架构应是深刻体现业务内部规则的业务架构,但因为业务变化频纴,所以软件架构很难保持恒定不变,但业务的频繁变化不应是软件架构大规模频繁变化的原因,软件架构应是基于变化的架构。
一种业务有其在一段时间内稳定存在的理由(暂且不谈),业务内部有许多用例,每一种用例都有固定的规则,每一规则都有一些可供判定的项,每一项从某一维度来观察都是可测量的,我们的架构首先必须保证完美适应每一项每一种测量方式,很多失败的架构都是因为很多项的测量方式都发生变更这种微观变化中。

每个用例都有规则,我们在作业务用例分析,常常假定一些规则是先验的,持久稳定的,然而后来的业务改变常常又证明这种看法是错误的,然而常常我们的架构已经为之付出了不可挽回的代价。大量事实证明:规则的变化常常用例变化的根本原因。所以我们的架构要尽可能适应规则的变化,尽可能建立规则模版。

每个用例都关系着不同的角色。每一个用例的产生都必然是因为角色的变更(注意:不是替换,而是增强或减弱),所以注意角色的各种可能情况,对架构的设计有举足轻重的意义。在我们当前的三层架构里,角色完美地对应接口概念。

在一个系统里很多用例都相互关联,考虑到每个用例均有可能有不同的特例,所以在架构设计中,尽量采用依赖倒置原则。如架构许可可采用消息通信模式(JMS)。这样可降低耦合度。

现在我们谈一下业务稳定存在理由对业务的影响。存在即是合理,在这里当然是正确的。业务因人而存在,所以问业务存在的理由即是问不同角色的需要这项业务的理由以及喜欢不喜欢当前业务用例的理由,所有这样的角色都应该在系统里预留。《待续》
在架构设计中有几个原则可以考虑:
用例尽量细分
用例尽量抽象
角色尽量独立
项测量独立原则
追求简单性
这里未提供相关的例子,例子会在以后的更新时提供。

业务和模式之间的关系
业务中的一些用例之间的关系常常和一些常规的模式很相似。但随着时间的演化,慢慢地和先前的模式有了分歧。这是个正常的现象。但这对系统架构却要求非常高,要求系统架构能适应一些模式的更替。在这里我们尽可能早地注意到用例之间的相互角色变化,为架构更新做好准备.
第一部分完.

lazet
lazett@gmail.com

星期二, 一月 22, 2008

[fwd]Erlang快速入门



Erlang超快速入门

日期:2007-04-06

目录
1 开始使用erlang
2 使用Erlang作为计算器
3 编辑前面的表达式
4 编译你的第一个程序
5 深入了解Erlang

1 开始使用erlang

如果你在unix系统下输入 erl ,或者在Window$系统下双击Erlang的图标,你可以看到一些提示:
os prompt > erl
Eshell V5.5.4 (abort with ^G)
1> _

其中 “>”提示符意味着系统正在等待输入。

2 使用Erlang作为计算器
1> 213183682167*12937192739173917823.
27579983733990928813319999135233
2> _

记住每个表达式以英文句号结束

3 编辑前面的表达式

可以使用简单的emacs命令获取前面的表达式。常见的几个如下:Unix键 Win$键 说明
^P Up 获取前一行(previous)
^N Down 获取下一行(next)
^A Home 到行首
^E End 到行尾
^D Del 删除光标前字符
^F Left 向前移动一个字符
^B Right 向后移动一个字符
Return Enter 执行当前命令


注意:^X意味着Control+X 。

尝试按下Control+P来查看结果。

译者注:一位朋友提示如上的快捷键是在unix系统之下的,Window$下的快捷键附在了如上列表后的括号内。另外,在Unix系统下使用Control+G的退出方式,在Window$下使用Control+C来退出。

4 编译你的第一个程序

把如下内容输入到一个文件里:
-module(test).
-export([fac/1]).

fac(0) -> 1;
fac(N) -> N * fac(N-1).

把这些存储到文件 test.erl 中,文件名必须与模块名相同。

编译这个程序使用如下命令,并且运行:
3> c(test).
{ok,test}
4> test:fac(20).
2432902008176640000
5> test:fac(40).
815915283247897734345611269596115894272000000000
6> _

现在可以做些其他有趣的事情了。

[fwd]Erlang初体验



久闻erlang大名,随着身边的一些项目开始采用erlang,看来不得不好好学习一下erlang了,以后也可以跟人说,今天你lang了吗

1.编译
在mac下,安装还是很简单的
引用
port install erlang
一切ok了

2.erlang的交互环境
由于一直搞python,所以很喜欢语言拥有一个shell交互环境,erlang也为我们提供了一个,在命令行下输入:
引用
erl
http://www.haokanbu.com/p/49620/

3.编辑器
工欲善其事必先利其器,我的开发环境:
http://www.haokanbu.com/p/49619/

4.尝试erlang的分布式编程
学习erlang,主要的目的就是学习他在分布式方面的使用
概念:
引用
节点是分布式Erlang的核心概念。在一个分布式Erlang应用中,术语(term)节点(node)意味着一个可以加入分布式 transactions的运行系统。通过一个称为net kernal的特殊进程,一个独立的Erlang系统可以成为一个分布式Erlang系统的一部分。当net kernal进程启动的时候,我们称系统是alive的。
在erlang中创建一个节点,非常容易:
引用
erl -sname node1
给一个节点发送消息:
引用
{Name, Node} ! Mess.
更详细的说明参见这里:
http://dennis-zane.javaeye.com/blog/94015

5.Unit Test in Erlang
除了写代码,我们还要保证质量,erlang也有相应的unitest方案:
https://support.process-one.net/doc/display/CONTRIBS/EUnit
中文说明:
http://erlang-china.org/start/unit_test_in_erlang.html

参考资料:
Erlang超快速入门
http://erlang-china.org/start/fast-start.html

星期二, 一月 15, 2008

商场商户管理



客商是出租式商场的衣食父母。客商管理是商场营销体系的重要组成部分,是企业的重要资产之一。客商管理的实质就是如何有效地运营客商这项资产,对它进行开发、维护、运用并使其增值。

  一、对客商地位和特性的认识

  1、真正尊重客商 

  真正尊重客商,围绕客商开展工作是客商管理的基石,没有这个前提,谈有效地管理客商只是空中楼阁,尊重客商是最起码的商业道德。 

  2、长久合作 

  在客商管理上,一定要有长远眼光,而不能考虑一时一事的利益。因为客商稳定是商场稳定并发展的前提,客商群体的稳定对于商场运营政策的连贯性和市场维护都是必不可少的。实际工作也证明,稳定的客商给商场带来的收益远大于经常变动的客商。客商的每一次变动都意味着风险和费用。不到万不得已,不要考虑换客商。这就要求我们在选择客商时一定要慎重,在最初选择时就从长远角度考虑。 

  3、日常性工作 

  客商管理需要常抓不懈,搞突击是没有任何效果的。客商管理是商场管理的一个重要组成部分,因而不可放松,应由专人负责,并进行考核。 

  4、确保客商的利益

  一些商场提出“客商是上帝”,然后小心翼翼地去伺候“上帝”,不敢提出合理要求,对一些屡屡违规的客商不敢提出批评。这种认识是造成企业无法对客商进行有效管理的重要原因。其实,对商场与入驻客商而言,只有一个共同的上帝,即消费者。客商是商场的合作伙伴,双方把消费者视为上帝,然后努力使其满意并积极地购买客商的产品。因为客商的销售政策是商家运营的灵魂。双方应一起共同开发市场、管理市场。 

  天津环渤海建材中心对客商地位的认识有独到之处。环渤海过去片面僵化地理解“客商是上帝”,造成强调客商利益多,责任制约少,其结果“上帝给企业制造了麻烦”。局面有些失控。1999年,环渤海开始按新标准对客商重新筛选,将客商由800余家减少至600余家,制定了新的如常标准,确定了淘汰率,由招商改为选商,以客商的经营手段,品牌含量,经营理念等作为入住的标准。这样,客商 “上帝的感觉”没有了,“合作伙伴的感觉”产生了。这种对客商表面的限止其实为客商营造了一个更好的经营环境,不少客商的积极性更高了。更好的客商引来了,实践让环渤海认识到,商场与客商是承担相应利益、责任和义务的利益共同体。环渤海认为,把客商由上帝“降格”为利益共同体,是一种双赢的策略。商场与客商的关系有三种:一加一等于二;一加一小于二;一加一大于二。商场把客商视为合作伙伴,其目的就是要发挥出一加一大于二的作用。 

  二、客商的管理

  有人说,一粒麦子有三种命运:一是磨成面,被人们消费掉,实现其自身价值;二是作为种子,播种后结出新的麦粒,创造出新的价值;三是由于保管不善,发霉变质,丧失其价值。这就是说,麦子管理好了,就会为人类创造出价值;管理不好,就会失去其价值甚至会带来负价值。客商也是这样。客商有其双重性:企业管理得好,客商忠诚于企业,他就会为企业做出贡献;管理不好,他会对企业造成损失。客商管理的目的就是要培养能够给企业带来价值的好客商。 

  1、客商可分为四类: 

  A、销售量小、对商场也不忠诚的客商。这些客商是没有价值的客商,商场对待此类客商的对策就是该出手时就出手,该淘汰的就淘汰。没有进行对差的客商的淘汰,就不能培养出一批好客商。 

  B、品牌好、销售量大但对商场不忠诚的客商。这些客商常常会成为商场最危险的敌人。此类客商“挟品牌以令商场”,他们以自己拥有的品牌和销售额为资本向商场讲条件、提要求,商场不能满足他们的愿望,他们就还商场以“颜色”――退租或是长期拖欠租金,最后拍拍屁股走人,因为其他商场已经必恭必敬应在门口请他去呢。如果对这些客商管理稍有疏忽,他们就会给商场造成很大的损失。如果商场所拥有的客商中这些客商占有较大的比重,那么企业的销售和市场就很危险了。 

  C、销售量小但对企业忠诚的客商。这是可以培养的明日之星。对此类客商,企业要多扶持、培养,努力使其成为一个好客商。 

  D、销售量大、对企业也忠诚的客商。这是企业最宝贵的财富。一个企业拥有的这类客商越多,市场就越稳定、越有发展潜力。 

  客商管理的目的就是多多培养好客商。商场通过对客商的培养、辅导和支持,以确保客商与企业共同成长、共同进步,企业有责任努力使客商与企业共同发展,建立长期的业务伙伴关系。 

  2、经营能力 

  客商的实质工作是卖货,因而经营能力的强弱标志着其销售能力的大小,也直接影响我们未来销售业绩的好坏,衡量客商经营能力的大小有几个指标: 

  (1)经营手段的灵活性:好的客商往往很有经营头脑,管理组织都很有章法,而不是跟着别人走。
  (2)分销能力的大小:主要是看其有多少下家(客商),市场覆盖面有多大,与下家的合作关系是否良好等。经销能力强的客商能将商品分销到区域市场的每个角落。 

  (3)资金是否雄厚。这是衡量客商能力强弱的一个硬指标。 

  (4)手中畅销品牌的多少。好的客商往往有多个畅销品牌的经销权。 

  (5)仓储和车辆、人员的多少。这也是衡量客商实力的一个硬指标。尤其是今后销售工作向细的方向、扎实的方向发展,这个指标就更为重要。 

  (6)解决售后问题的能力。好的客商对售后服务都很重视,而且自身都拥有完善的售后服务体系,大部分售后问题可以自行消化,不会因售后问题闹到商场管理部门。

  三、客商的评价与对策 

  为了确保客商能够成为好客商,商场就要定期地对客商进行评价,对好客商进行奖励,对有潜力的客商提出目标和要求,进行帮助;对不符合企业要求的客商,坚决淘汰。 

  过去许多商场对客商的评价标准是单一的,以租金到位率为惟一标准。今天,越来越多的商场强调要通过多种指标对客商进行评价,其目的是引导客商成为一个好客商。一位卖场销售专家提出商场可以从客商的品牌开发能力、销售管理水平、销售网络、促销能力、售后服务、展位水平、营业员水平、与本公司的关系等方面对客商进行评价。 

  当然,商场可以根据自己的情况确定客商评价标准。对客商做出评价后,商场应采取的对策是:重点与好客商进行交往,并扩大摊位或提供好的位置。如果商场把大量人力、资金、时间、精力用在与差的客商的交往上,就永远无法提高商场的销售业绩。对此,商场可采取的对策是积极开发能取代该客商的新客商。 

  商场要对客商情况进行具体分析: 

  1、信用好但销售能力差、品牌力度弱的客商。他们的经营意识和经营能力严重不足,是典型的坐商,只凭老招牌与固定的客商做生意。这些客商虽然不能够促进业务发展。但足以稳定经营,对营业员来说,这也很具吸引力。租金收取不成问题,但他可能跟不上商场连锁化经营的脚步。 

  2、销售能力强但信用差的客商。他们可能在较短的时间内使业务急剧增长。这些客商的经营思想新颖、开发能力强,但是商场管理者要注意,这些客商的基础较弱,信用条件差,租金收取要预留足够的时间。 

  3、销售能力和信用都好的客商。这是最受商场欢迎的客商。提升商场运营质量的重点就是增加这类客商。商场必须检讨:自己拥有多少这样的客商?是否比竞争对手的多?拥有这些客商可获得以下的好处:能销售优秀品牌的产品;增加商场的吸引力;支付租金干脆;自我推广意识足;吸引更多的消费者前来购物;会提供各种有用的信息。 

  如果客商目前的经营状况一般,但有发展潜力,商场就要去辅导、扶持客商发展,促进客商的成长。 

  对盈利较差但信誉较好的客商应采取帮助、扶持、关怀的态度。商场管理人员应该深入客商,想其所想,急其所急。应多听听盈利较差客商的意见,在不影响公司整体运营的基础上,应尽可能的为他们多做些工作。不能因为我们有大量的储备客商而对他们采取放弃的态度。这样会对现有客商造成不安全感。 

  四、客商管理的内容

  (一)利益管理——商场必须让客商赚到钱。利益是联系商场与客商的纽带,如果客商在本商场不能赚到钱或赚钱太少,客商就会离我们而去,精心构造的运营策略就会土崩瓦解。商场要管理好客商,首先就要确保客商赚到钱。 

  让客商赚钱,今天许多商场都是这样说,但并不是所有的商场都能做到这一点。这主要取决于商场的市场开发与管理能力,以及更多的运营思想。为客商营造一个畅销的局面和一个良好的交易秩序,是让客商赚钱所必不可少的条件。 

  (二)支援和辅导客商——商场不仅要给客商以鱼,更要让客商掌握钓鱼的方法。我们不仅要让客商赚钱,而且要教会客商赚钱的方法。商场要支持和辅导客商发展,客商的经营管理水平提高了,销售能力提高了,商场的对消费者、对社会的感召力也就会随之而上升。 

  1、辅导培训客商,提高客商的经营素质,强化其销售能力。 一句话是“授人以鱼,不如授人以渔”,让客商掌握促进销售的技能,使之赚钱,比减免租金更有效果。商场对客商的培训方法是多种多样的:既可以将集中在一起进行“集合强化训练”,也可以通过企业内部刊物进行训练及信息交流等等。 

  2、支援客商。 

  (1)提供同业动向、行业动态等信息;对市场调查与分析的指导与协助;

  (2)以商场的名义发布各项促销举措,制作广告宣传单及DM;支援客商所举办的活动;并在媒体广告上提及客商;

  (3)与广告、公关有关的指导、支援。如支援允许客商使用商场制作的广告;支援、协助客商召开消费者座谈会;分担客商的广告费等。 

  (4)指导客商店铺装修、商品陈列设计。如支援制作店铺招牌;支援开设展示窗、陈列室;提供商品展示、陈列技术;指导制作POP广告;协助提供展示台、陈列台;协助提供或选择各种陈列工具;对店内装修或布置提供技术指导等。 

  (5)拟定并推动与促销活动有关的节目。

  (6)指导由各种刊物或大众传媒获取信息的做法。如发行供客商参考的内部信息刊物;传递有关同行业的信息等。 

  如上所述,客商支援行动的内容相当广泛,因此,企业可经根据不同的客商采取不同的支援方法。 这些方法的采用其实就是在帮客商赚钱。

  目前,商场在对客商进行支援时,有以下发展趋势:对产品销售,给予经营管理、促销活动策划方面的指导,并表明诚意,让客商的个体销售行为变成商场的整体运营行为的一部分,使客商乐于合作。对展位,重点则放在指导改进店铺陈列、公关、广告策划等方面。 

  (三)感情关系 ——感情关系是客商管理的重要手段。感情关系可以弥补利益的不足之处。可口可乐公司在其一份销售手册中提出业务员的三大职责,第一就是与客商建立良好的感情关系。 

  商场管理的核心是营销,营销的核心是客商管理。但是在实际工作中,很多商场的客商管理做得很糟糕,一方面是没有认识到客商管理的重要性,另一方面是在客商管理方面,缺乏真正系统性的策略规划和必要的技术手段。 

  (四)合同管理

  1.建立规章制度 

  要求所有的入驻客商都签署进场合同,没有制度的约束,就很难落实到实际工作中去。同时规定合同的签署、流程,确保合同的严肃性、科学性,堵塞漏洞。 

  2.建立标准、规范的合同文本 

  3.专人管理 

  合同必须由专人保管,一方面涉及到商业秘密,另一方面便于使用。由专人分门别类建立档案,集中保管,才能保证合同的严肃性、完整性。

Blog Archive