2006年01月08日

昨天完整的做完了一个模块,但是还有很多东西不太懂。主要是关于Spring的机制,最近连续看了22上晚上的书<J2EE without EJB>,传说中很好的书,看了2天看不下去了,可能是太深的关系,讲架构方面的特别多。好多概念不是特别清楚,今晚不想看了,休息一下,看看别的。老外写的书就是不好懂,是思维方式的不同吧,感觉比较散、乱。

今天下午找了半天关于用户界面方面的资料,发现有些界面真的做得很不错。找到了汉得公司做的管理系统,可能是引入了工作流,用户操作可以很清晰,明了。

好的用户体验是软件设计中很重要的一个方面,可是国内往往忽略它。

附:(今天浏览过的几个网站)

一个UI的网站

http://www.chinaui.com/

微软关于管理系统的一些示例解决方面

http://www.microsoft.com/china/msdn/Library/WhitePaperSolution/CaseStudy/bornsoft/default.mspx

汉得公司一个产品的预览版

http://www.hand-china.com/MASDemo/gld_01.htm

2006年01月07日

 解决web服务器各种应用的中文乱码问题
 (1)服务器端:
修改httpd.conf (在Redhat中放置的位置为/etc/httpd/conf/)
查找:
AddDefaultCharset ISO-8859-1
改成:
代码:
#AddDefaultCharset ISO-8859-1
AddDefaultCharset off
这种方式关掉了服务器的默认语言的发送,这样仅凭html文件头中设置的语言来决定网页语言。
很多文章都说通过修改为 AddDefaultCharset GB2312 把缺省语言改成GB2312来解决中文乱码,确实GB2312内码的网页可以正常显示了,但这并非万全之策。因为当你的网页内码不是GB2312,就算你在网页用下面的meta指定了正确的语言,如ISO8859-1,也不会解码为ISO8859-1,因为Apache已经先你一步将GB2312指定为网页的语言了,

(2)养成良好的习惯,在每个网页的<head></head>的最前面加入这行:
代码:
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
  一般的中文版网页编辑工具(例如FrontPage、Dreamweaver等)都会自动加上这行。

3、如何解决中文文件名无法访问
代码:
 在ie中选择 工具 -> internet选项 -> 高级 -> 取消“总是以UTF-8发送URL”。
UTF-8网页空白,在网页中加上metadata标识后,还需要手动调整编码為 utf-8 才能正常显示
如果使用的是Mozilla、Mozilla Firefox、Sarafi等其他目前流行的浏览器,通常就不会有这样的问题。
在网页的meta中指定用UTF-8:
代码:
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
在<head></head>之前,把"Content-Type"放在最前面,便可以解決这样的问题了。
原因:
IE 解析网页编码时是 HTML 內的标识优先的,然后是 HTTP header ;而mozilla 系列的浏览器刚刚好相反。
一般情况在,很多人是把<title></title>排在最前面,并且在title中就出现了UTF-8中文,这样, IE在解析时,就先遇到UTF-8,不往下解析了,因此必须把如果把meta放在UTF-8出现之前,这样IE才能判断这个网页是以UTF-8编码的。
总之:
无论是 PHP、JSP、ASP 或其他动态网页的脚本语言,如果需要作编码设定,最好放在最前面。
使用php,也可以定义php的默认语言.
php.ini中:
代码:
default_charset = "gb2312"
释掉此行,做了以上修改,一样是为了让浏览器根据网页头中的charset来自动选择语言,这样就可以在同台服务器上提供多种语言的网页服务。




java中文乱码的解决

在基于JAVA的编程中,经常会碰到汉字的处里及显示的问题,比如一大堆乱码或问号。
这是因为JAVA中默认的编码方式是UNICODE,而中国人通常使用的文件和DB都是基于GB2312或者BIG5等编码,故会出现此问题。
1、在网页中输出中文。
JAVA在网络传输中使用的编码是"ISO-8859-1",故在输出时需要进行转化,如:
String str="中文";
str=new String(str.getBytes("GB2312"),"8859_1");
但如果在编译程序时,使用的编码是“GB2312”,且在中文平台上运行此程序,不会出现此问题,一定要注意。
2、从参数中读取中文
这正好与在网页中输出相反如:
str=new String(str.getBytes("8859_1"),"GB2312");
3、操作DB中的中文问题
一个较简单的方法是:在“控制面扳”中,把“区域”设置为“英语(美国)”。如果还会出现乱码,还可进行如下设置:
取中文时:str=new String(str.getBytes("GB2312"));
向DB中输入中文:str=new String(str.getBytes("ISO-8859-1"));
4、在JSP中的中文解决:
在“控制面扳”中,把“区域”设置为“英语(美国)”.
在JSP页面中加入:
如果还不行正常显示,则还要进行下面的转换:
如:name=new String(name.getBytes("ISO-8859-1"),"GBK");
就不会出现中文问题了。


CGI:
找到CGI.pm,找到$self->charset(‘ISO-8859-1′);将它改为$self->charset(‘GB2312′);



补充:
如果使用php,也可以定义php的默认语言.
php.ini中:
;default_charset = "gb2312"
注意这里是注释掉此行,做了以上修改,目的是为让浏览器根据网页头中的charset来自动选择语言,这样就可以在同台服务器上提供多种语言的网页服务。





彻底解决Tomcat 5.0.19中文乱码
  一、Include的页面乱码
  现象:include进来的页面出现乱码,其它页面正常。
  原因:Tomcat在缺省情况下使用ISO-8859-1编码,但是在include时有时Tomcat不能正确根据外层.jsp文件的编码解析include进来的文件,造成include进来的文件中的中文乱码。
  解决:这儿可以有很多解决办法,但是对于我们的中文环境,从根本上的解决办法是将Tomcat 5.0.19的核心缺省编码从ISO-8859-1修改为GBK 。
  二、提交的数据乱码
  现象:通过表单提交的数据出现乱码。
  原因:原因未明。可能是Tomcat在接收到请求后,并没有能够根据request中的信息提前正确的编码方式。
  解决:可以添加一个设置字符集的Filter。
代码:
package filters;

import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.UnavailableException;

public class SetCharacterEncodingFilter implements Filter {
 protected String encoding = null;
 protected FilterConfig filterConfig = null;
 protected boolean ignore = true;

 public void destroy() {
  this.encoding = null;
  this.filterConfig = null;
 }

public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain)
throws IOException, ServletException {

 // Conditionally select and set the character encoding to be used
 if (ignore || (request.getCharacterEncoding() == null)) {
  String encoding = selectEncoding(request);
  if (encoding != null)
   request.setCharacterEncoding(encoding);
 }

 // Pass control on to the next filter
 chain.doFilter(request, response);

}

public void init(FilterConfig filterConfig) throws ServletException {

 this.filterConfig = filterConfig;
 this.encoding = filterConfig.getInitParameter("encoding");
 String value = filterConfig.getInitParameter("ignore");
 if (value == null)
  this.ignore = true;
 else if (value.equalsIgnoreCase("true"))
  this.ignore = true;
 else if (value.equalsIgnoreCase("yes"))
  this.ignore = true;
 else
  this.ignore = false;
}

protected String selectEncoding(ServletRequest request) {
 return (this.encoding);
}
}
  

配置web.xml

代码:
<filter>
 <filter-name>Set Character Encoding</filter-name>
 <filter-class>filters.SetCharacterEncodingFilter</filter-class>
 <init-param>
  <param-name>encoding</param-name>
  <param-value>GBK</param-value>
 </init-param>
</filter>

<filter-mapping>
 <filter-name>Set Character Encoding</filter-name>
 <url-pattern>/*</url-pattern>
</filter-mapping>





java Servlet 中文乱码问题
代码:
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class GetFormData extends HttpServlet
{
public void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException
{
String paramValues;
paramValues=request.getParameter("UserName";
response.setContentType("text/html;charset=gb2312";
PrintWriter out=response.getWriter();
out.println("<html><title>test</title><body>";
out.println("以下是收到的数据<br>";
out.println("UserName="+paramValues);
out.println("<br>接收结束";
out.println("</body>";
}
public void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException
{
doGet(request,response);
}
}


只需要把
代码:
paramValues=request.getParameterValues("UserName"改成下面的就可以了
paramValues=request.getParameter("UserName";

代码:
当然这句是必須的 response.setContentType("text/html;charset=gb2312"

在jsdk2.1 tomcat及Domino5.8上的Servlet引擎运行通过了






Weblogic Server中如何解决中文显示乱码问题
《世界计算机》IT.ICXO.COM ( 日期:2004-09-29 16:07)
——————————————————————————–

由于操作系统、浏览器、数据库、JVM采用的字符集都不一样,基于Weblogic Server开发的应用经常出现中文显示乱码问题,其实在Weblogic Server上运行的WEB应用有很多与字符集有关的设置,下面做一个总结,为了正确处理中文,最好把这些设置都设上。

1. 在JSP文件头加入
代码:
<%@ page contentType=text/html; charset=GBK %>
指定该JSP采用的字符集。
2.在Weblogic.xml文件的中加入:
引用:
encoding
GBK
指定JSP文件中采用的字符集,在JSP文件中的<%@ page contentType=text/html; charset=GBK %>会覆盖该设置
3.在Weblogic.xml文件的中加入
代码:
compilerSupportsEncoding
true
如果为TRUE,指定在编译JSP文件时,采用在JSP文件中定义的
<%@ page contentType=text/html; charset=GBK %>或中定义的encoding参数中定义的字符集进行编码,如果为FALSE,则采用JVM中默认指定的字符集进行编码。
4. Weblogic Server需要把HTTP request(GET 和POST)中的数据从它的原始编码转化为Unicode,以便Java servlet API进行处理,为了做这种转换,Weblogic Server需要知道HPPT request中的数据的编码方式。这可以通过在Weblogic.xml的中设置.
代码:
〈INPUT-charset>
/
GBK
5.从ORACLE数据库中检索出来的中文显示不正确时,在这种情况下,如果数据库使用的是中文字符集,并使用的是Type 2 JDBC Driver时,可加入Weblogic.codeset=GBK的属性来解决这个问题。代码如下:
代码:
java.util.Properties props = new java.util.Properties();
props.put(Weblogic.codeset, GBK);
props.put(user, scott);
props.put(password, tiger);
String connectUrl = jdbc:Weblogic:oracle;
Driver myDriver = (Driver)
Class.forName(Weblogic.jdbc.oci.Driver).newInstance();
Connection conn =
myDriver.connect(connectUrl, props);
6. 如果是采用WTC调用Tuxedo中的服务,在JSP页面中无法正确显示中文,必须使安装Tuxedo的服务器上的NLS_LANG环境变量与数据库中的字符集的设置一样。如后台Oracle数据库中的字符集设置为 SIMPLIFIED CHINESE_CHINA.ZHS16GBK,那么Tuxedo应用服务器上的NLS_LANG环境变量应设置为:
代码:
export NLS_LANG=SIMPLIFIED CHINESE_CHINA.ZHS16GBK

来源: CU
  

2005年12月28日

待解决的问题:printJob.setCopies(1)
hibernate 的拦截机 :代码还没有实现.

2005年12月20日

 最近被分配研究DB,我很高兴可以更深入一点了解数据库,以前只学习了一些皮毛,只是sql语句。其它只是泛泛了解了一下,完全不够用。

关于数据库调优是我以后的学习方向,公司用的是MS SQL和ORACLE,所以这2 方面的知道都需要补充。

最近要解决的问题是:

  • 数据库中重要表的数据备份及操作日志,实现办法:
    • 在DB层面通过触发器实现。
    • 在服务器端通过增加2 个表,2 个类,在要实现备份的类的Manager里通过DAO来完成数据历史记录表和操作日志的数据操作。

「转载」mssql数据库管理的简单介绍

摘自:http://blog.itpub.net/post/1626/15010
一、四个系统数据库的介绍
二、三种备份和恢复
三、两种数据导入导出方法
四、数据库维护计划和作业的应用(前提都是sqlserver agent服务要启动)
五、安全性介绍
六、sql脚本的生成
七、事件探查器的应用
八、日志的截断

一、四个系统数据库的介绍
  1、Master数据库
  Master数据库记录了Sqlserver所有的服务器级系统信息,所有的注册帐户和密码,以及所有的系统设置信息,还记录了所有用户定义数据库的存储位置和初始化信息。
  2、Tempdb数据库
  Tempdb记录了所有的临时表、临时数据和临时创建的存储过程。Tempdb数据库是一个全局资源,没有专门的权限限制,允许所有可以连上Sqlserver服务器的用户使用。
  在Tempdb数据库存放的所有数据信息都是临时的。每当连接断开时,所有的临时表和临时存储过程都将自动丢弃。每次系统启动时Sqlserver都会根据Model数据库重新创建Tempdb数据库。
  3、Model数据库
  Model数据库是用户建立新数据库的模板,它包含了将复制到每个用户数据库中去的系统表。每当创建数据库的语句create database执行时,服务器总是通过复制model数据库来建立新数据库的前面部分,新数据库的后面部分被初始化成空白的数据页,以供用户存放数据。
  4、Msdb数据库
  Msdb数据库主要被sqlserver agent用来进行复制、作业调度以及管理报警等活动。该数据库常被用来通过调度任务排除故障。
  5、说明:在具体应用中可以在企业管理器里将这四个系统数据库隐藏起来,可以避免用户误操作,也可以起到让用户知道操作系统数据库带来的后果。

 

二、三种备份和恢复
1、通过企业管理器的备份和还原数据库。
2、在查询分析器里执行sp_detach_db ‘dbname’,true分离数据库,将操作系统文件*.mdf(主数据文件)和*.ldf(日志文件)拷贝出来,当然你也可以通过停止sqlserver服务来拷贝操作系统文件。
  通过sp_attach_db(两个操作系统文件都完好)或sp_attach_single_file_db(主数据文件完好,日志文件破坏)来附加数据库(如果在附加中有问题,执行下列步骤)。

mssql里附加数据库出错的解决方法在QA里执行sp_attach_db或者sp_attach_single_file_db,出现提示:错误1813:未能打开新数据库’dbname’,create database 将终止。设备激活错误。物理文件名’d:\sql server\mssql\data\dbname _log.ldf’可能有误! 按下面的步骤处理:1.新建一个同名的数据库2.再停掉sqlserver服务(注意不要分离数据库)3.用原数据库的数据文件覆盖掉这个新建的数据库4.再重启sqlserver服务5.此时打开企业管理器时会出现置疑,先不管,执行下面的语句(注意修改其中的数据库名)6.完成后一般就可以访问数据库中的数据了。这时,数据库本身一般还有问题,解决办法是:利用数据库的脚本创建一个新的数据库,然后通过DTS将数据导进去就行了use mastergosp_configure ‘allow updates’,1 reconfigure with overridegoupdate sysdatabases set status =32768 where name=’置疑的数据库名’gosp_dboption ‘置疑的数据库名’, ’single user’, ‘true’godbcc checkdb(‘置疑的数据库名’) goupdate sysdatabases set status =28 where name=’置疑的数据库名’gosp_configure ‘allow updates’, 0 reconfigure with overridego sp_dboption ‘置疑的数据库名’, ’single user’, ‘false’go  也可以通过企业管理器来附加数据库。3、查询分析器里执行backup database ‘dbname’ to disk=’路径’来备份数据库,restore database ‘dbname’ from disk=’路径’来还原数据库。(以上提到的sql语句里的符号如”等都应该是半角的。这里的操作实际上是上面1里对应的sql语句操作。)
三、两种数据导入导出方法
1、通过DTS来做
2、bcp实用工具来做
     例如(hostname表示机器名,user表示sqlserver登陆用户名,resu表示对应的用户登陆的密码):
     exec master..xp_cmdshell ‘bcp dbname..table_name out d:\test.xls -c -Shostname -Uuser -Presu’

四、数据库维护计划和作业的应用(前提都是sqlserver agent服务要启动)
1、数据库维护计划
2、作业
/*在远程机器操作系统的计算机管理里建立一个用户名为kyle的用户,密码为1234,同时在那台机器的非系统盘里建一个名为backup的共享文件夹,为了安全另外设置这个文件夹只有这个kyle用户可以访问。*/
declare @sql varchar(500)
select @sql=’\\10.2.0.12\backup\dbname’+'_db_’+convert(varchar(10),getdate(),112) +
              substring(convert(varchar(10),getdate(),108),1,2) +’.bak’
exec master..xp_cmdshell ‘net use \\10.2.0.12\backup 1234 /user:remotehost\kyle’
backup database dbname to disk=@sql –备份数据库,这里的10.2.0.12为远程机器的ip,remotehost为远程机器的机器名,dbname为本地sqlserver服务器要备份的数据库
go

declare @sql varchar(500)
select @sql=’del ‘+’\\10.2.0.12\backup\dbname’+'_db_’+convert(varchar(10),dateadd(day,-7,getdate()),112) +              substring(convert(varchar(10),dateadd(day,-7,getdate()),108),1,2) +’.bak’
exec master..xp_cmdshell @sql –删除7天前的备份,也就是只保留7个最新备份
go
  
五、安全性介绍
1、两种登陆方式:
  标准登陆方式(sqlserver和windows),采用sqlserver提供的用户名和密码登陆连接,可用sp_denylogin ‘builtin\administrators’拒绝操作系统管理员登陆连接(sp_grantlogin ‘builtin\administrators’反转),也称非信任登陆机制;这种认证方式是两种方式中最安全的。
  集成登陆方式(仅windows),将windows的用户和工作组映射为sqlserver的登陆方式,也称信任机制。
2、一个特殊帐户:sa,为系统默认帐户,不能删除,拥有最高的管理权限,可以执行sqlserver服务器范围内的所有操作,所以一定要给sa加上密码,密码推荐不少于6位,最后是字母、数字和特殊符号的组合。
3、两个特殊数据库用户:
  dbo,数据库的拥有者,在安装sqlserver时,被设置到model数据库中,不能被删除,所以dbo在每个数据库中都存在。dbo是数据库的最高权力者,对应于创建该数据库的登陆用户,即所有的数据库的dbo都对应于sa帐户;
  guest,这个用户可以使任何已经登陆到sqlserver服务器的用户都可以访问数据库,即使它还没有成为本数据库的用户。所有的系统数据库除model以外都有guest用户。所有新建的数据库都没有这个用户,如果油必要添加guest用户,请用sp_grantdbaccess来明确建立这个用户。
4、还原数据库的时候之所以要删除本数据库的用户如user,然后在安全性→登陆里重新建这个用户和指定相应的访问权限,是因为这个用户在master里不存在。当然你也可以用sp_addlogin ‘user’,'resu’来新建user用户,sp_change_users_login ‘update_one’,'user’,'user’来指定在master中的对应。
5、具有system administrators服务器角色的成员拥有与sa一样的权限,具有db_owner数据库角色的用户具有对本数据库的完全操作权限。

六、sql脚本的生成
说明:可以选择生成某个具体数据库对象的脚本,也可以生成整个数据库对象的脚本。

七、事件探查器的应用
说明:追踪对后台数据库的每一个请求,以此可以定位前台页面的哪个属性对应后台表的哪个字段。

八、日志的截断
backup log dbname with no_log
dbcc shrinkdatabase(‘dbname’)

2005年10月04日

spring 学习资源

http://tech.sina.com.cn/s/2005-01-21/0936510931.shtml

Spring Framework 开发参考手册

http://www.jactiongroup.net/reference/html/index.html

2005年09月30日
  JAVA日期问题总结

 

   

1、获取服务器端当前日期:
<%@ page import="java.util.Date"%>
<%
Date myDate = new Date();
%>

2、获取当前年、月、日:

<%@ page import="java.util.Date"%>

<%
Date myDate = new Date();
int thisYear = myDate.getYear() + 1900;//thisYear = 2003
int thisMonth = myDate.getMonth() + 1;//thisMonth = 5
int thisDate = myDate.getDate();//thisDate = 30
%>


3、按本地时区输出当前日期

<%@ page import="java.util.Date"%>
<%
Date myDate = new Date();
out.println(myDate.toLocaleString());
%>


输出结果为:
2003-5-30


4、获取数据库中字段名为"publish_time"、类型为Datetime的值


<%@ page import="java.util.Date"%>
<%
…连接数据库…
ResultSet rs = …
Date sDate = rs.getDate("publish_time");
%>
[code]


5、按照指定格式打印日期


[code]
<%@ page import="java.util.Date"%>
<%@ page import="java.text.DateFormat"%>
<%
Date dNow = new Date();

SimpleDateFormat formatter = new SimpleDateFormat("E yyyy.MM.dd 'at' hh:mm:ss a zzz");
out.println("It is " + formatter.format(dNow));
%>

 

输出的结果为:
It is 星期五 2003.05.30 at 11:30:46 上午 CST
(更为详尽的格式符号请参看SimpleDateFormat类)


6、将字符串转换为日期

<%@ page import="java.util.Date"%>
<%@ page import="java.text.DateFormat"%>
<%
String input = "1222-11-11";
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
Date t = null;

try{

  t = formatter.parse(input);

  out.println(t);

  }catch(ParseException e){

  out.println("unparseable using" + formatter);

  }

%>

输出结果为:
Fri Nov 11 00:00:00 CST 1222


7、计算日期之间的间隔

 

<%@ page import="java.util.Date"%>
<%@ page import="java.text.DateFormat"%>
<%
String input = "2003-05-01";
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
Date d1 = null;
trycatch(ParseException e)

Date d2 = new Date();

long diff = d2.getTime() - d1.getTime();
out.println("Difference is " + (diff/(1000*60*60*24)) + " days.");
%>


输出结果为:
Difference is 29 days.


8、日期的加减运算
方法:用Calendar类的add()方法


<%@ page import="java.util.*"%>
<%@ page import="java.text.*"%>
<%
Calendar now = Calendar.getInstance();
SimpleDateFormat formatter = new SimpleDateFormat("E yyyy.MM.dd 'at' hh:mm:ss a zzz");
out.println("It is now " + formatter.format(now.getTime()));
now.add(Calendar.DAY_OF_YEAR,-(365*2));
out.println("<br>");
out.println("Two years ago was " + formatter.format(now.getTime()));
%>

 

输出结果为:
It is now 星期五 2003.05.30 at 01:45:32 下午 CST
Two years ago was 星期三 2001.05.30 at 01:45:32 下午 CST


9、比较日期
方法:用equals()、before()、after()方法

 

<%@ page import="java.util.*"%>
<%@ page import="java.text.*"%>
<%
DateFormat df = new SimpleDateFormat("yyy-MM-dd");
Date d1 = df.parse("2000-01-01");
Date d2 = df.parse("1999-12-31");

String relation = null;
if(d1.equals(d2))
relation = "the same date as";
else if(d1.before(d2))
relation = "before";
else
relation = "after";
out.println(d1 +" is " + relation + ' ' + d2);
%>


输出结果为:
Sat Jan 01 00:00:00 CST 2000 is after Fri Dec 31 00:00:00 CST 1999


10、记录一件事所花费的时间
方法:调用两次System.getTimeMillis()方法,求差值

 

<%@ page import="java.text.*"%>
<%
long t0,t1;
t0 = System.currentTimeMillis();
out.println("Cyc starts at " + t0);
int k = 0;
for(int i =0;i<100000;i++)
t1 = System.currentTimeMillis();
out.println("<br>");
out.println("Cyc ends at " + t1);
out.println("<br>");
out.println("This run took " + (t1-t0) + "ms.");
%>


输出结果为:
Cyc starts at 1054275312432
Cyc ends at 1054275312442
This run took 10ms.

其它:如何格式化小数

 

<%@ page import="java.text.*"%>
<%
DecimalFormat df = new DecimalFormat(",###.00");
double aNumber = 33665448856.6568975;
String result = df.format(aNumber);
out.println(result);
%>


输出结果为:
33,665,448,856.66

2005年09月27日

程序优化的三个级别
HouSisong@263.net  2004.11.07整理

文章来源于abp论坛中的一篇帖子:http://bbs.allaboutprogram.com/viewtopic.php?t=1063
(原文章写于2003.10.14晚)

到了allaboutprogram后被人叫做"性能狂人",我也不知道为什么会有这个称号,其实我并不是一个偏激的人,相反我很随和,平易近人…(哈哈)。为了与新的身份大致相符,所以尝试写篇文章,写写自己理解的优化的三个级别。

有人不谈优化,甚至憎恶优化,我只能说那只是因为他没有能力做到!那是他还不能按时写出程序、不能写出正确的程序、不能写出规范的程序。很多优秀的程序员都喜欢追求最快的程序速度,我想大多数程序员可能都想使自己写的程序能够比别人写的程序运行得更快;

优化前需要问自己的几个问题:为什么要优化 、优化的目标是什么、哪些部分才需要优化、能够接受由此带来的可能的资源消耗(人力、维护、空间等)吗?

程序优化有三个层级;它们依次产生更显著的优化代码,在考虑优化方案时可以尝试从不同的层级着手思考优化的方案:
(也许有人表达过这些观点了,但这也是我对优化的实际理解 ;我的分类方法主要依据了具体去实现一个优化时思考问题的切入角度来划分的,有时候他们之间的界限也并不明显,具体是不是产生更显著的优化效果也不是确信的)

第一级:代码调整
 代码调整是一种局部的思维方式;基本上不触及算法层级;它面向的是代码,而不是问题;
 所以:语句调整,用汇编重写、指令调整、换一种语言实现、换一个编译器、循环展开、参数传递优化等都属于这一级;
  这个级别的优化需要掌握大量的小的优化技巧和知识,需要不断的积累;
  简单的语句调整、公共表达式提取、废代码删除等当前的很多编译器也能做到了,但也需要了解一些编译器的优化能力使自己的代码配合编译器做好优化;
  用汇编重写并不是简单把高级语言改写为汇编实现,那样写的汇编很可能没有当今的编译器产生的代码好,所以如果决定用汇编实现,那就应该按照汇编的角度来规划自己的实现,适当的参考编译器生成的汇编码也是可取的(特别是新手,我也一样);在某些领域,使用CPU的新特性和新的指令集等将产生巨大的性能收益,这些地方经常采用汇编来实现。

第二级:新的视角
   新的视角强调的重点是针对问题的算法;即选择和构造适合于问题的算法;(冒泡排序还是快排的选择问题是这一级早就应该完成的)很多经典算法都对问题作了一些假设(包括我们当前已经完成的算法实现),而在面对实际问题时“新的视角”提示我们应该重新检视这些假设,并尝试不同的思考问题的角度,寻求适合于问题的新算法;
发掘问题的本来意义,从不同的角度思考面对的问题,使用适合于问题的的算法; 尝试打破一些规则,发掘和怀疑自己的某些假定,恢复问题的本来面目;

第三级:表驱动状态机
    将问题抽象为另一种等价的数学模型或假想机器模型,比如构造出某种表驱动状态机;这一级其实是第二级的延伸,只是产生的效果更加明显,但它有其本身的特点(任何算法和优化活动都可以看作是他的投影);这一级一般可以产生无与伦比的快速程序,
   要达到这一级需要大量修炼的;并且思考时必须放弃很多已有的概念或者这些概念不再重要,比如:变量、指针、空间、函数、对象等,剩下的只应该是那个表驱动状态机; 我想把这种境界描述为:空寂中,一些输入驱动着一个带有状态的机器按设定好的最短路线运转着;除此之外have nothing; 既:把解决一个问题的算法看作一个机器,它有一些可变的状态、有一些记忆、有一些按状态运行的规则,然后一些输入驱动这个机器运转;这就是第三级要求的思考优化问题的切入点,也就是寻找一部机器,使它运行经过的路径最短(可能是速度也可能是空间等等)


   要掌握一级优化,是很多人经过努力都能够达到的层次,需要的是不断的积累各方面的技巧就行了(虽然很繁琐),写出的代码可以称为“好的代码”;
   要掌握二级优化,需要的是对问题的理解能力和一些创造力,能够针对问题产生新的见解;写出的代码可以称为“优秀的代码”;
   要掌握三级优化,必须具有丰富的想象力和创造力,需要大量的修炼和对问题本质的苦苦思索;写出的代码可以称为“非凡的代码”;
   能够将这三个层级的优化熟练运用(我想把这种境界称作“综级优化”)的人必须掌握比别人更多的知识、了解更多的知识领域、了解最底层的技术和最高层的抽象;并且还要求有丰富的实践经验、想象能力和创造能力; 这些都是不可或缺的;


警示:不是所有的代码(项目)都需要优化
警示:不是每个人都要去做优化工作
警示:优化是有方向和侧重点的,不只是单纯的速度
警示:首先是正确,然后才有优化
警示:简洁的代码,很多时候就是最好的代码
警示:优化不是一种理论,它是一种实践
警示:充分优化的笨拙算法实现始终比不上一个更好的算法的普通实现,即优化首先是设计的优化
警示:代码优化是门黑色艺术,代码的优化永无止境
警示:无论是谁,他的资源也不是无限的,代码优化要避免过犹不及
警示:如果确信不需要优化,那根本不进行优化,就是最好的优化!

2005年08月09日

struts专题

http://www-128.ibm.com/developerworks/cn/java/j-strutscol/

struts 学习起歩问答
www.wenhui.org  2003-2-11  CSharp vs Java


1 JSP Framework – Struts介绍
Struts是采用Java Servlet/JavaServer Pages技术,开发Web应用程序的开放源码的framework。

采用Struts能开发出基于MVC(Model-View-Controller)设计模式的应用构架。

Struts有如下的主要功能:

1. 包含一个controller servlet,能将用户的请求发送到相应的Action对象。

2. JSP自由tag库,并且在controller servlet中提供关联支持,帮助开发员创建交互式表单应用。

3. 提供了一系列实用对象:XML处理、通过Java reflection APIs自动处理JavaBeans属性、国际化的提示和消息。

Struts是Jakarta项目的一部分,主页在http://jakarta.apache.org/struts.

Version 0.5的下载地址:http://jakarta.apache.org/builds/jakarta-struts/release/v0.5


1.1 1、什么是MVC模式。
MVC(Model/View/Controller)模式是国外用得比较多的一种设计模式,好象最早是在Smaltalk中出现。MVC包括三类对象。Model是应用对象,View是它在屏幕上的表示,Controller定义用户界面对用户输入的响应方式。

1.2 2、是否所有JSP应用都该采用MVC模式?
不一定所有的JSP应用都该采用MVC模式。但对于大型应用来说,我认为还是该采用MVC模式。不使用MVC模式,用户界面界面设计往往将这些对象混在一起,而MVC则将它们分离以提高灵活性和复用性。

1.3 3、Struts中能做XML吗,与Cocoon相比有何优点?
Struts把主要精力放在JSP上了。Cocoon才是专业级的XML Framework。


2. Struts的安装
2.1 安装Struts需要的软件

Java Development Kit – 你需要download和install 1.2(或之后)版本的JDK。下载地址:http://java.sun.com/j2se
Servlet Container – 通常的选择是下载Tomcat(至少是3.1版,推荐使用3.2版)。下载地址:http://jakarta.apache.org/tomcat
Ant Build System – 如果你通过Struts源码发布包安装,你必须下载1.1或之后版本的ant build system。在你通过Struts来开发你自己的Web应用程序是,我也推荐使用ant来build你的应用。下载地址:http://jakarta.apache.org/ant
Servlet API Classes – 为了编译Structs自己,或应用程序使用Struts,你需要一个包含Servlet和JSP API对象的servlet.jar包。大多数Servlet container(例如Tomcat)已经自带了这个文件。否则,你必需下载:http://jakarta.apache.org/builds/jakarta-servletapi
XML Parser – Structs需要一个与Java API for XML Parsing(JAXP)规格兼容的XML处理器。我推荐使用Xerces。下载地址:http://xml.apache.org/xerces-j
Xalan XSLT Processor – 如果你通过Structs源码发布版来构造你的Structs系统,你必须下载和安装1_2_D01或之后版本的Xalan XSLT处理器(Xerces中已自带Xalan)。这个处理器用于将基于XML的Structs文档转换为Html文档。


2.2 通过源码构造Structs

1.下载Structs的源码发布包。
2.设置ANT_HOME环境变量,指向你的Ant目录。
3.设置JAVA_HOME环境变量,指向你的JDK目录。
4.设置SERVLETAPI_HOME环境变量,指向你的Servlet API目录(如果你的CLASSPATH已经包含了servlet.jar,就不需要指定该目录)
5.将Structs的源码发布包进行解包。
6.进入Structs目录,运行以下命令:
./build.sh dist
该命令将创建Struts的二进制发布包,目录在../dist/structs(相对于你的编译目录)。


2.3 通过Struts的二进制发布包安装Structs

1.下载Struts的二进制发布版。
2.将Struts的二进制发布版进行解包。(如果你是通过Struts源码构造Struts,build的结果就已经是已解包的Struts)。解包后的Struts包含以下内容:
lib/struts.jar – 这个文件包含了Struts的所有Java对象。你需要把它拷贝到你的Web应用的WEB-INF/lib目录。
lib/structs.tld – 这是一个"tag library descriptor"文件,它描述了Struts库的自由tag。需要将它拷贝到你的Web应用的WEB-INF目录。
webapps/struts-documentation.war – 这是一个"web application archive"文件,包含了所有的Struts文档。你可以将它安装到支持Servlet API 2.2或之后版本的servlet container(推荐使用tomcat)中。
webapps/struts-example.war – 这是一个web应用实例,它广泛地演示了Struts的许多功能。你可以将它安装到兼容Servlet2.2或之后版本以及JSP1.1或之后版本规范的servlet容器中(推荐使用tomcat)。
webapps/struts-test.war – 这个web应用包含了Struts支持的许多tag的测试网页,可以作为使用Struts tag的例子。

可通过以下的步骤在你自己的应用程序中使用Struts:
1.将Struts目录的lib/struts.jar拷贝到web应用的WEB-INF/lib目录。
2.将Struts目录的lib/struts*.tld拷贝到web应用的WEB-INF目录。
3.修改Web应用目录的WEB-INF/web.xml文件,增加一个<servlet>元素来定义controller servlet,增加一个<servlet-mapping>元素来建立URI请求与servlet的对应关系。可以参照Struts例子中的WEB-INF/web.xml文件来了解详细的语法要求。
4.修改Web应用目录的WEB-INF/web.xml文件,使之包含以下的tag库定义:
<taglib>
<taglib-uri>/WEB-INF/struts.tld</taglib-uri>
<taglib-location>/WEB-INF/struts.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>/WEB-INF/struts-bean.tld</taglib-uri>
<taglib-location>/WEB-INF/struts-bean.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>/WEB-INF/struts-logic.tld</taglib-uri>
<taglib-location>/WEB-INF/struts-logic.tld</taglib-location>
</taglib>
5.创建一个WEB-INF/action.xml文件来定义你的web应用的action映射关系。可以参照Struts例子中的action.xml文件来了解详细的语法要求。
6.在使用Struts tag库的JSP网页中加入以下tag库定义:
<@ taglib uri="/WEB-INF/struts.tld" prefix="struts" %>
<@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
<@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>
7.最后,在编译你的web应用的java程序时,不要忘了在CLASSPATH中包含struts.jar文件哟。

查了一上午的关于JAVA书籍

发现图书馆里也有不少好书,以前居然不知道,一下子有7,8本书需要看,可惜只有3本书的名额,不知从哪本看起,头疼。

Java Bug模式详解 (美) Eric Allen著

http://www-900.cn.ibm.com/developerWorks/cn/java/j-diag/index.shtml