软件是对质量的不懈追求

2009年12月18日 #

linux du 查看文件夹占用空间


du -sh *

posted @ 2011-04-15 08:39 BlakeSu 阅读(274) | 评论 (0)编辑 收藏

Building Standalone Application with Maven2

If you are building standalone application in Java, Maven is your friend when packing your application,
There are two way to let Maven package your application, either as a single jar with all your dependencies jar.


 <plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-assembly-plugin</artifactId>
  <configuration>
   <descriptorRefs>
    <descriptorRef>jar-with-dependencies</descriptorRef>
   </descriptorRefs>
  </configuration>
 </plugin>



One advantage if you choose to do this way is if you need to sign your application jar.
This is needed if you are building a Java Web Start client and you need more access than connecting back to the server.
To read more about have Maven signing your jar read http://maven.apache.org/plugins/maven-jar-plugin/usage.html.
But if you choose to go this way, make sure that all license agreement are shipped with your one single jar.

Another way is to let Maven package your source code only and then referring the dependent jar file from the MANIFEST file.


 <plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-jar-plugin</artifactId>
  <configuration>
   <archive>
    <manifest>
     <addClasspath>true</addClasspath>
     <mainClass>se.msc.adapter.Main</mainClass>
     <classpathPrefix>lib/</classpathPrefix>
    </manifest>
   </archive>
  </configuration>
 </plugin>

posted @ 2011-02-24 13:03 BlakeSu 阅读(318) | 评论 (0)编辑 收藏

eclipse 终于有了列编辑功能

eclipse 3.5之后终于有了列编辑,快捷键是alt+shift+a,再次按此快捷键返回常规编辑状态。


posted @ 2010-10-15 11:33 BlakeSu 阅读(1472) | 评论 (0)编辑 收藏

LineNumberReader 指定文件编码


import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.LineNumberReader;


public class Main {
    
    
public static void main(String[] args) throws IOException {

        InputStreamReader isr 
= new InputStreamReader(new FileInputStream("15370720.pdf4"), "utf-16");
        LineNumberReader lnr
=new LineNumberReader(isr);
        String line 
= null;
        
while((line=lnr.readLine())!=null){  
           System.out.println(lnr.getLineNumber()
+"\t"+line);
        }
   }
}

posted @ 2010-08-05 09:13 BlakeSu 阅读(1037) | 评论 (0)编辑 收藏

Class.getResourceAsStream 和 ClassLoader.getResourceAsStream

两个方法的区别是资源的定义不同, 一个主要用于相对与一个object取资源,而另一个用于取相对于classpath的
资源,用的是绝对路径。

在使用Class.getResourceAsStream 时, 资源路径有两种方式, 一种以 / 开头,则这样的路径是指定绝对
路径, 如果不以 / 开头, 则路径是相对与这个class所在的包的。

在使用ClassLoader.getResourceAsStream时, 路径直接使用相对于classpath的绝对路径。

举例,下面的三个语句,实际结果是一样的:
   com.explorers.Test.class.getResourceAsStream("abc.jpg")
= com.explorers.Test.class.getResourceAsStream("/com/explorers/abc.jpg")
= ClassLoader.getResourceAsStream("com/explorers/abc.jpg")

posted @ 2010-07-28 16:31 BlakeSu 阅读(284) | 评论 (0)编辑 收藏

Standalone Java CAS Client

There's a variety of clients for CAS. The Java-based clients (JA-SIG, Yale, see JA-SIG website) typically handle the browser-based client interaction with CAS very well through ServletFilter implementations.

Now what about programmatic authentication, i.e. achieving authentication through non-browser based applications? There exists a CAS .NET client but I did not manage to find the appropriate Java implementation. So here goes - it is based on the Apache HttpClient.

In case I missed any existing implementation achieving the same purpose, let's look at the bright side: at least now I understand the CAS protocol :-)

My CAS client works within any application. It uses the HttpClient and behaves like a browser client as CAS requires cookie support.

Here's the code:
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.log4j.Logger;

/**
* The CasClient allows users to programmatically login
* to CAS protected services based on the CAS 2 protocol.
* This client behaves like a browser-client in terms of
* cookie handling.<br>
*
@author Mathias Richter
*/
public class CasClient
{
  
   
public static Logger LOG = Logger.getLogger( CasClient.class  );

   
public static final String LOGIN_URL_PART = "login";
   
public static final String SERVICE_VALIDATE_URL_PART = "serviceValidate";
   
public static final String TICKET_BEGIN = "ticket=";
   
private static final String LT_BEGIN = "name="lt" value="";
   public static final String CAS_USER_BEGIN = "<cas:user>";
   
public static final String CAS_USER_END = "</cas:user>";
  
   
private HttpClient fClient;
   
private String fCasUrl;
  
   
/**
    * Construct a new CasClient.
    *
    * 
@param casUrl The base URL of the CAS service to be used.
    
*/
   
public CasClient( String casBaseUrl )
   {
       
thisnew HttpClient(), casBaseUrl );
   }
  
   
/**
    * Construct a new CasClient which uses the specified HttpClient
    * for its HTTP calls.
    *
    * 
@param client
    * 
@param casBaseUrl
    
*/
   
public CasClient( HttpClient client, String casBaseUrl )
   {
       fClient 
= client;
       fCasUrl 
= casBaseUrl;
   }
  
   
/**
    * Authenticate the specified username with the specified password.
    * This will not yield any ticket, as no service is authenticated
    * against. This wil just set the CAS cookie in this client upon
    * successful authentication.
    *
    * 
@param username
    * 
@param password
    
*/
   
public void authenticate( String username, String password )
   {
       authenticate( 
null, username, password );
   }
  
   
/**
    * Validate the specified service ticket against the specified service.
    * If the ticket is valid, this will yield the clear text user name
    * of the autenticated user.<br>
    * Note that each service ticket issued by CAS can be used exactly once
    * to validate.
    *
    * 
@param serviceUrl
    * 
@param serviceTicket
    *
    * 
@return Clear text username of the authenticated user.
    
*/
   
public String validate( String serviceUrl, String serviceTicket )
   {
       String result 
= null;
       PostMethod method 
= new PostMethod( fCasUrl + SERVICE_VALIDATE_URL_PART );
       method.setParameter( 
"service", serviceUrl );
       method.setParameter( 
"ticket", serviceTicket );
       
try
       {
           
int statusCode = fClient.executeMethod(method);
           
if (statusCode != HttpStatus.SC_OK)
           {
               LOG.error( 
"Could not validate: " + method.getStatusLine() );
               method.releaseConnection();
           } 
else
           {   
               result 
= extractUser( new String( method.getResponseBody() ) );
           }
       } 
catch ( Exception x )
       {
           LOG.error( 
"Could not validate: " + x.toString () );
           x.printStackTrace();
       }
       method.releaseConnection();
       
return result;
   }
  
   
/**
    * Authenticate the specified user with the specified password against the
    * specified service.
    *
    * 
@param serviceUrl May be null. If a url is specified, the authentication will happen against this service, yielding a service ticket which can be validated.
    * 
@param username
    * 
@param password
    * 
@return A valid service ticket, if and only if the specified service URL is not null.
    
*/
   
public String authenticate( String serviceUrl, String username, String password )
   {
       String lt 
= getLt( serviceUrl );
       
if ( lt == null )
       {
           LOG.error( 
"Cannot retrieve LT from CAS. Aborting authentication for '" + username + "'" );
           
return null;
       }
       String result 
= null;
       PostMethod method 
= new PostMethod( fCasUrl + LOGIN_URL_PART );
       
if ( serviceUrl != null ) // optional
           method.setParameter( "service", serviceUrl );
       method.setParameter( 
"_eventId""submit" );
       method.setParameter(
"username", username );
       method.setParameter(
"password", password );
       method.setParameter(
"lt", lt );
       method.setParameter( 
"gateway""true" );
       
try
       {
           fClient.executeMethod(method);
           
if ( serviceUrl == null )
           {
               
if ( extractLt( new String( method.getResponseBody() ) ) != null ) // if CAS does not return a login page with an LT authentication was successful
               {
                   LOG.error( 
"Authentication for '" +  username + "' unsuccessful" );
                   
if ( LOG.isDebugEnabled() )
                       LOG.debug( 
"Authentication for '" + username + "' unsuccessful." );
               } 
else
               {
                   
if ( LOG.isDebugEnabled() )
                       LOG.debug( 
"Authentication for '" + username + "' unsuccessful." );
               }
           } 
else
           {
               Header h 
= method.getResponseHeader( "Location" );
               
if ( h != null )
                   result 
= extractServiceTicket( h.getValue() );
               
if ( result == null )
                   LOG.error( 
"Authentication for '" + username + "' unsuccessful." );
           }
       } 
catch ( Exception x )
       {
           LOG.error( 
"Could not authenticate'" + username + "':" + x.toString () );
       }
       method.releaseConnection();
       
return result;
   }
  
   
/**
    * Helper method to extract the user name from a "service validate" call to CAS.
    *
    * 
@param data Response data.
    * 
@return The clear text username, if it could be extracted, null otherwise.
    
*/
   
protected String extractUser( String data )
   {
       String user 
= null;
       
int start = data.indexOf( CAS_USER_BEGIN  );
       
if ( start >= 0 )
       {
           start 
+= CAS_USER_BEGIN.length();
           
int end = data.indexOf( CAS_USER_END );
           
if ( end > start )
               user 
= data.substring( start, end );
           
else
               LOG.warn( 
"Could not extract username from CAS validation response. Raw data is: '" + data + "'" );
       } 
else
       {
           LOG.warn( 
"Could not extract username from CAS validation response. Raw data is: '" + data + "'" );
       }
       
return user;
   }
  
   
/**
    * Helper method to extract the service ticket from a login call to CAS.
    *
    * 
@param data Response data.
    * 
@return The service ticket, if it could be extracted, null otherwise.
    
*/
   
protected String extractServiceTicket( String data )
   {
       String serviceTicket 
= null;
       
int start = data.indexOf( TICKET_BEGIN  );
       
if ( start > 0 )
       {
           start 
+= TICKET_BEGIN.length();
           serviceTicket 
= data.substring( start );
       }
       
return serviceTicket;
   }
  
   
/**
    * Helper method to extract the LT from a login form from CAS.
    *
    * 
@param data Response data.
    * 
@return The LT, if it could be extracted, null otherwise.
    
*/
   
protected String extractLt( String data )
   {
       String token 
= null;
       
int start = data.indexOf( LT_BEGIN  );
       
if ( start < 0 )
       {
           LOG.error( 
"Could not obtain LT token from CAS: LT Token not found in response." );
       } 
else
       {
           start 
+= LT_BEGIN.length();
           
int end = data.indexOf( """, start );
           token = data.substring( start, end );
       }       
       
return token;
   }
  
   
/**
    * This method requests the original login form from CAS.
    * This form contains an LT, an initial token that must be
    * presented to CAS upon sending it an authentication request
    * with credentials.<br>
    * If a service URL is provided (which is optional), this method
    * will post the URL such that CAS authenticates against the
    * specified service when a subsequent authentication request is
    * sent.
    *
    * 
@param serviceUrl
    * 
@return The LT token if it could be extracted from the CAS response.
    
*/
   
protected String getLt( String serviceUrl )
   {
       String lt 
= null;
       HttpMethod method 
= null;
       
if ( serviceUrl == null )
           method 
= new GetMethod( fCasUrl + LOGIN_URL_PART );
       
else
       {
           method 
= new PostMethod( fCasUrl + LOGIN_URL_PART );
           ( ( PostMethod ) method ).setParameter( 
"service", serviceUrl );
       }
       
try
       {
           
int statusCode = fClient.executeMethod(method);
           
if (statusCode != HttpStatus.SC_OK)
           {
               LOG.error( 
"Could not obtain LT token from CAS: " + method.getStatusLine() );
               method.releaseConnection();
           } 
else
           {
               Object o 
= method.getResponseHeaders() ;
               
return extractLt( new String( method.getResponseBody() ) );
           }
       } 
catch ( Exception x )
       {
           LOG.error( 
"Could not obtain LT token from CAS: " + x.toString () );
       }
       method.releaseConnection();
       
return lt;
   }
  
}

posted @ 2010-07-15 17:59 BlakeSu 阅读(406) | 评论 (0)编辑 收藏

java取文件换行符

System.getProperty("line.separator")

posted @ 2010-06-30 15:45 BlakeSu 阅读(303) | 评论 (0)编辑 收藏

禁止浏览器缓存

html
  <meta http-equiv="pragma" content="no-cache">
  
<meta http-equiv="cache-control" content="no-cache">
  
<meta http-equiv="expires" content="0">


servlet
          response.setHeader("pragma","no-cache");
          response.setHeader(
"cache-control","no-cache");
          response.setDateHeader(
"expires"0);


posted @ 2010-06-25 09:06 BlakeSu 阅读(246) | 评论 (0)编辑 收藏

frame 中跨域访问cookie(java)

response.addHeader("P3P","CP=CAO PSA OUR");

posted @ 2010-06-25 09:04 BlakeSu 阅读(404) | 评论 (0)编辑 收藏

vim的复制粘贴小结

原文地址 http://lsong17.spaces.live.com/blog/cns!556C21919D77FB59!603.trak


用vim这么久 了,始终也不知道怎么在vim中使用系统粘贴板,通常要在网上复制一段代码都是先gedit打开文件,中键粘贴后关闭,然后再用vim打开编辑,真的不 爽;上次论坛上有人问到了怎么在vim中使用系统粘贴板,印象里回复很多,有好几页的回复却没有解决问题,今天实在受不了了又在网上找办法,竟意外地找到 了,贴出来分享一下。

如果只是想使用系统粘贴板的话直接在输入模式按Shift+Inset就可以了,下面讲一下vim的粘贴板的基础知识,有兴趣的可以看看, 应该会有所收获的。
vim帮助文档里与粘贴板有关的内容如下:

  1. vim有12个粘贴板,分别是0、1、2、...、9、a、“、+;用:reg命令可以查看各个粘贴板里的内容。在vim中简单用y只是复制到 “(双引号)粘贴板里,同样用p粘贴的也是这个粘贴板里的内容;

  2. 要将vim的内容复制到某个粘贴板,需要退出编辑模式,进入正常模式后,选择要复制的内容,然后按"Ny完成复制,其中N为粘 贴板号(注意是按一下双引号然后按粘贴板号最后按y),例如要把内容复制到粘贴板a,选中内容后按"ay就可以了,有两点需要说明一下:
    • “号粘贴板(临时粘贴板)比较特殊,直接按y就复制到这个粘贴板中了,直接按p就粘贴这个粘贴板中的内容;
    • +号粘贴板是系统粘贴板,用"+y将内容复制到该粘贴板后可以使用Ctrl+V将其粘贴到其他文档(如firefox、gedit) 中,同理,要把在其他地方用Ctrl+C或右键复制的内容复制到vim中,需要在正常模式下按"+p;

  3. 要将vim某个粘贴板里的内容粘贴进来,需要退出编辑模式,在正常模式按"Np,其中N为粘贴板号,如上所述,可以按"5p将 5号粘贴板里的内容粘贴进来,也可以按"+p将系统全局粘贴板里的内容粘贴进来。

注意:在我这里,只有vim.gtk或vim.gnome才能使用系统全局粘贴板,默认的 vim.basic看不到+号寄存器。

posted @ 2010-06-18 14:21 BlakeSu 阅读(251) | 评论 (0)编辑 收藏

Linux下mail使用技巧

登录LINUX系统后,经常会看到"you have mail",却苦于不知道如何查看,相信菜鸟们都遇到过,偶在网上用“linux mail"找了很久,但大都是介绍mail服务器的,黄天总算没负有心人,在洪恩在找到一篇介绍基础的文章,不敢独享。
 
系统提供了用户 之间通信的邮件系统,当用户打开终端注册登录时发现系统给出如下信息:
    you have mail.

    这时用户可通过键入mail命令读取信件:

    $ mail

    mail程序将逐个显示用户的信件,并依照时间顺序,显示最新的信件。每显示一段信件,mail都询问用户是否要对该信件作些处理。若用户回答d,则表示 删除信件;若仅按回车键,表示对信件不作任何改动(信件仍旧保存,下次还可读这一信件);若回答p,则要求重复显示信件;s filename表示要把信件存入所命名的文件;若回答q,表示要从mail退出。

    我们在本章的第一个例子中演示了如何写一封信,作为练习,你可送信件给自己,然后键入mail读取自己发的信件,看看会有什么效果。(发信给自己是一种设 置备忘录的方法)。

    $mail frank 给自己写信

    subject: test

    This is a mail test

    CRL-d

    EOT

    $

    $mail 查看信件

    “/var/spool/mail/frank:”1 message 1 new

    >Nfrank@xteam.xteamlinux.comThu Mar 25 11:00 13/403 “test”

    &

    Message 1:

    From frank Thu Mar 25 11:00:25 1999/3/25

    Received: (fromfrank@localhost)

    by xteam.xteamlinux.com(8.8.4/8.8.4)

    id LAA05170 for frank;Thu 25 Mar 1999 11:00:25 GMT

    Date: Thu,25 Mar 1999 11:00:25 GMT

    From:RHS Linux User <frank@xteam.xteamlinux.com>

    Message-Id:<199903251142.LAA05170@xteam.xteamlinux.com>

    To:frank@xteam.xteamlinux.com

    Subject:test

    Status:R

    This is a mail test

    &

    mail命令还有很多其它用法,例如发送事先准备好的信件,或一次送信给若干人。还可以用其它方法送信件。

posted @ 2010-06-18 11:05 BlakeSu 阅读(187) | 评论 (0)编辑 收藏

Mysql中limit的用法详解

    Mysql中limit的用法:在我们使用查询语句的时候,经常要返回前几条或者中间某几行数据,这个时候怎么办呢?
  不用担心,mysql已经为我们提供了这样一个功能。

  SELECT * FROM table LIMIT [offset,] rows | rows OFFSET offset

LIMIT 子句可以被用于强制 SELECT 语句返回指定的记录数。LIMIT 接受一个或两个数字参数。参数必须是一个整数常量。
  如果给定两个参数,第一个参数指定第一个返回记录行的偏移量,第二个参数指定返回记录行的最大数目。初始记录行的偏移量是 0(而不是 1):
  为了与 PostgreSQL 兼容,MySQL 也支持句法: LIMIT # OFFSET #。

mysql> SELECT * FROM table LIMIT 5,10; // 检索记录行 6-15

//为了检索从某一个偏移量到记录集的结束所有的记录行,可以指定第二个参数为 -1:

mysql> SELECT * FROM table LIMIT 95,-1; // 检索记录行 96-last.

//如果只给定一个参数,它表示返回最大的记录行数目:

mysql> SELECT * FROM table LIMIT 5; //检索前 5 个记录行

//换句话说,LIMIT n 等价于 LIMIT 0,n。

注意limit 10和limit 9,1的不同:

例如:

1.Select * From cyclopedia Where ID>=(
    Select Max(ID) From (
      Select ID From cyclopedia Order By ID limit 90001
    ) As tmp
  ) limit 100;

2.Select * From cyclopedia Where ID>=(
    Select Max(ID) From (
      Select ID From cyclopedia Order By ID limit 90000,1
    ) As tmp
  ) limit 100;

 

    第1句是先取了前90001条记录,取其中最大一个ID值作为起始标识,然后利用它可以快速定位下100条记录

第2句择是仅仅取90000条记录后1条,然后取ID值作起始标识定位下100条记录

第1句执行结果.100 rows in set (0.23) sec

第2句执行结果.100 rows in set (0.19) sec

其实第2句完全可以简化成:
    Select * From cyclopedia Where ID>=(
   Select ID From cyclopedia limit 90000,1
)limit 100;

直接利用第90000条记录的ID,不用经过Max运算,这样做理论上效率因该高一些,但在实际使用中几乎看不到效果,
   因为本身定位ID返回的就是1条记录,Max几乎不用运作就能得到结果,但这样写更清淅明朗,省去了画蛇那一足.


Select Top 100 * From cyclopedia Where ID>=(
Select Top 90001 Max(ID) From (
Select ID From cyclopedia Order By ID
) As tmp
)

但不管是实现方式是存贮过程还是直接代码中,瓶颈始终在于MS-SQL的TOP总是要返回前N个记录,这种情况在数据量不大时感受不深,
   但如果成百上千万,效率肯定会低下的.相比之下MySQL的limit就有优势的多,执行:


Select ID From cyclopedia limit 90000
Select ID From cyclopedia limit 90000,1

的结果分别是:


90000 rows in set (0.36) sec
1 row in set (0.06) sec

而MS-SQL只能用Select Top 90000 ID From cyclopedia 执行时间是390ms,执行同样的操作时间也不及MySQL的360ms.

limit的offset(偏移量)用于记录较多的时候,记录较少时,偏移offset较小,直接使用limit较优。offset越大,后者越优。
 

1、offset比较小的时候。

select * from yanxue8_visit limit 10,10

多次运行,时间保持在0.0004-0.0005之间


Select * From yanxue8_visit Where vid >=(
  Select vid From yanxue8_visit Order By vid limit 10,1
) limit 10

多次运行,时间保持在0.0005-0.0006之间,主要是0.0006

结论:偏移offset较小的时候,直接使用limit较优。这个显示是子查询的原因。

2、offset大的时候。

select * from yanxue8_visit limit 10000,10

多次运行,时间保持在0.0187左右

Select * From yanxue8_visit Where vid >=(
  Select vid From yanxue8_visit Order By vid limit 10000,1
) limit 10

多次运行,时间保持在0.0061左右,只有前者的1/3。可以预先offset越大,后者越优。

mysql> SELECT * FROM table LIMIT 95,-1; // 检索记录行 96-last.

//如果只给定一个参数,它表示返回最大的记录行数目.

posted @ 2010-06-02 14:43 BlakeSu 阅读(447) | 评论 (0)编辑 收藏

枚举类型enum示例




public enum OrderStatus {
    A(
1), B(2), C(3), D(4), F(5), INCOMPLETE(6);
    
    
private final int value;
    
/**
     * Constructor.
     
*/
    
private OrderStatus(int value) {
        
this.value = value;
    }
    
    
/**
     * Get the value.
     * 
@return the value
     
*/
    
public int getValue() {
        
return value;
    }

}


posted @ 2010-06-02 13:33 BlakeSu 阅读(144) | 评论 (0)编辑 收藏

JS try.....catch的使用

<script language="javascript">
try
{
throw new Error(10,"asdasdasd")
}
catch (e)
{
alert(e.message);
alert(e.description)
alert(e.number)
alert(e.name)
throw new Error(10,"asdasdasd")
}

</script>  

在JavaScript可以使用try...catch来进行异常处理。例如:  

 

try {
foo.bar();
} catch (e) {
alert(e.name + ": " + e.message);
}

目前我们可能得到的系统异常主要包含以下6种:

  • EvalError: raised when an error occurs executing code in eval()  
  • RangeError: raised when a numeric variable or parameter is outside of its valid range  
  • ReferenceError: raised when de-referencing an invalid reference  
  • SyntaxError: raised when a syntax error occurs while parsing code in eval()  
  • TypeError: raised when a variable or parameter is not a valid type  
  • URIError: raised when encodeURI() or decodeURI() are passed invalid parameters  

上面的六种异常对象都继承自Error对象。他们都支持以下两种构造方法:

 

new Error();
new Error("异常信息");

手工抛出异常的方法如下:

 

try {
throw new Error("Whoops!");
} catch (e) {
alert(e.name + ": " + e.message);
}

如要判断异常信息的类型,可在catch中进行判断:

 

try {
foo.bar();
} catch (e) {
if (e instanceof EvalError) {
   alert(e.name + ":" + e.message);
}
else if (e instanceof RangeError) {
   alert(e.name + ": " + e.message);
}
// etc
}

Error具有下面一些主要属性:

  • description: 错误描述 (仅IE可用).  
  • fileName: 出错的文件名 (仅Mozilla可用).  
  • lineNumber: 出错的行数 (仅Mozilla可用).  
  • message: 错误信息 (在IE下同description)  
  • name: 错误类型.  
  • number: 错误代码 (仅IE可用).  
  • stack: 像Java中的Stack Trace一样的错误堆栈信息 (仅Mozilla可用).  

因此为了更好的了解错误信息我们可以将catch部分改为如下形式:  

 

try {
foo.bar();
} catch (e) {
if (browserType != BROWSER_IE) {                            
   alert("name: " + e.name +
    "message: " + e.message +
    "lineNumber: " + e.lineNumber +
    "fileName: " + e.fileName +
    "stack: " + e.stack);        
}
else {                    
   alert("name: " + e.name +     
    "errorNumber: " + (e.number & 0xFFFF ) +
    "message: " + e.message");        
}
}

JavaScript中的throw命令事实上可以抛出任何对象,并且我们可以在catch接受到此对象。例 如:

 

try {
throw new Date(); // 抛出当前时间对象
} catch (e) {
alert(e.toLocaleString()); // 使用本地格式显示当前时间
}

posted @ 2010-06-02 10:38 BlakeSu 阅读(330) | 评论 (0)编辑 收藏

深拷贝

import java.io.*;

public class ObjectCloner
{
   
// so that nobody can accidentally create an ObjectCloner object
   private ObjectCloner(){}
   
// returns a deep copy of an object
   static public Object deepCopy(Object oldObj) throws Exception
   {
      ObjectOutputStream oos 
= null;
      ObjectInputStream ois 
= null;
      
try
      {
         ByteArrayOutputStream bos 
= new ByteArrayOutputStream(); 
         oos 
= new ObjectOutputStream(bos); 
         
// serialize and pass the object
         oos.writeObject(oldObj);   
         oos.flush();               
         ByteArrayInputStream bin 
= new ByteArrayInputStream(bos.toByteArray()); 
         ois 
= new ObjectInputStream(bin);
         
// return the new object
         return ois.readObject();
      }
      
catch(Exception e)
      {
         System.out.println(
"Exception in ObjectCloner = " + e);
         
throw(e);
      }
      
finally
      {
         oos.close();
         ois.close();
      }
   }
   
}

posted @ 2010-05-25 09:30 BlakeSu 阅读(173) | 评论 (0)编辑 收藏

mysql convert int to char/varchar

select cast(1 as char)

char 不能换成varchar,否则会报错。

posted @ 2010-05-12 17:12 BlakeSu 阅读(2893) | 评论 (0)编辑 收藏

How to check Linux distribution and version?

If u are on an unknown server and keen to know it’s linux distribution info, you can check the linux distribution info by just a single command (eg. version, codename, etc). Just tested this command in UBuntu and CentOS, both return as what i expected. :)

To check linux distribution and version, follow the steps below:-

  • Start your terminal and enter the command below to show your the linux distribution info:-
    $ cat /etc/*-release
  • Here’s my result in one of my my Ubuntu box:-
    $ cat /etc/*-release
    DISTRIB_ID=Ubuntu
    DISTRIB_RELEASE=9.10
    DISTRIB_CODENAME=karmic
    DISTRIB_DESCRIPTION="Ubuntu 9.10"

    Cool right!

posted @ 2010-05-08 13:29 BlakeSu 阅读(683) | 评论 (0)编辑 收藏

Eclipse集成windows资源管理器简单方法

Run-->External Tools-->External tools configurations
new 一个 program
location 里面填 :C:\WINDOWS\explorer.exe
Arguments 里面填: ${container_loc}
点击 Run

posted @ 2010-05-08 08:40 BlakeSu 阅读(260) | 评论 (0)编辑 收藏

commons lang 比较有用的类

ArrayUtils                 //简化数组的操作
LocaleUtils
SerializationUtils
StringEscapeUtils
StringUtils
SystemUtils
Validate                   //输入参数验证
NestableException
NestableRuntimeException
StopWatch          //秒表类

posted @ 2010-04-26 10:16 BlakeSu 阅读(206) | 评论 (0)编辑 收藏

xmind 当真不错

xmind是绘制思维导图的工具。
使用之后,发现绘制组织结构图和wbs都很方便。
软件基于eclipse框架开发,反应速度和操作性也都很不错。
更重要的,图形的效果也是专业级的 :)

posted @ 2010-04-23 09:51 BlakeSu 阅读(247) | 评论 (0)编辑 收藏

Java 中serialVersionUID的解释

serialVersionUID作用:
       序列化时为了保持版本的兼容性,即在版本升级时反序列化仍保持对象的唯一性。
有两种生成方式:
       一个是默认的1L,比如:private static final long serialVersionUID = 1L;
       一个是根据类名、接口名、成员方法及属性等来生成一个64位的哈希字段,比如:
       private static final   long     serialVersionUID = xxxxL;

当你一个类实现了Serializable接口,如果没有定义serialVersionUID,Eclipse会提供这个
     提示功能告诉你去定义 。在Eclipse中点击类中warning的图标一下,Eclipse就会
     自动给定两种生成的方式。如果不想定义它,在Eclipse的设置中也
      可以把它关掉的,设置如下:
        Window ==> Preferences ==> Java ==> Compiler ==> Error/Warnings ==>
        Potential programming problems
        将Serializable class without serialVersionUID的warning改成ignore即可。

如果你没有考虑到兼容性问题时,就把它关掉,不过有这个功能是好的,只要任何类别实现了Serializable这个接口的话,如果没有加入 serialVersionUID,Eclipse都会给你warning提示,这个serialVersionUID为了让该类别 Serializable向后兼容。

如果你的类Serialized存到硬盘上面后,可是后来你却更改了类别的field(增加或减少或改名),当你Deserialize时,就会出现 Exception的,这样就会造成不兼容性的问题。

但当serialVersionUID相同时,它就会将不一样的field以type的预设值Deserialize,可避开不兼容性问题。

posted @ 2010-04-08 10:37 BlakeSu 阅读(153) | 评论 (0)编辑 收藏

spring 相关

ApplicationContext wac = WebApplicationContextUtils          .getRequiredWebApplicationContext(config.getServletContext());

posted @ 2010-04-06 13:01 BlakeSu 阅读(150) | 评论 (0)编辑 收藏

wesphere6.1修改默认端口

环境->虚拟主机->default_host->其它属性(主机别名)->修改端口
服务器->应用程序服务器->server1->端口->WC_defaulthost->修改端口

posted @ 2010-04-02 10:36 BlakeSu 阅读(221) | 评论 (0)编辑 收藏

jquery validate自定义验证方法


 /* 追加自定义验证方法 */   
 
// 身份证号码验证   
 jQuery.validator.addMethod("idcardno"function(value, element) {
   
return this.optional(element) || isIdCardNo(value);   
 }, 
"请正确输入身份证号码");
 
  
//字母数字
 jQuery.validator.addMethod("alnum"function(value, element) {
   
return this.optional(element) || /^[a-zA-Z0-9]+$/.test(value);
 }, 
"只能包括英文字母和数字");
 
  
// 手机号码验证   
 jQuery.validator.addMethod("cellphone"function(value, element) {
   
var length = value.length;
   
return this.optional(element) || (length == 11 && /^(1\d{10})$/.test(value));
 }, 
"请正确填写手机号码"); 
 
  
// 电话号码验证   
 jQuery.validator.addMethod("telephone"function(value, element) {
   
var tel = /^(\d{3,4}-?)?\d{7,9}$/g;
   
return this.optional(element) || (tel.test(value));
 }, 
"请正确填写电话号码");
 
 
// 邮政编码验证
 jQuery.validator.addMethod("zipcode"function(value, element) {
   
var tel = /^[0-9]{6}$/;
   
return this.optional(element) || (tel.test(value));
 }, 
"请正确填写邮政编码");
 
  
// 汉字
 jQuery.validator.addMethod("chcharacter"function(value, element) {
   
var tel = /^[\u4e00-\u9fa5]+$/;
   
return this.optional(element) || (tel.test(value));
 }, 
"请输入汉字");
 
 
/**
 * 身份证号码验证
 *
 
*/
function isIdCardNo(num) {

 
var factorArr = new Array(7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2,1);
 
var parityBit=new Array("1","0","X","9","8","7","6","5","4","3","2");
 
var varArray = new Array();
 
var intValue;
 
var lngProduct = 0;
 
var intCheckDigit;
 
var intStrLen = num.length;
 
var idNumber = num;
   
// initialize
     if ((intStrLen != 15&& (intStrLen != 18)) {
         
return false;
     }
     
// check and set value
     for(i=0;i<intStrLen;i++) {
         varArray[i] 
= idNumber.charAt(i);
         
if ((varArray[i] < '0|| varArray[i] > '9') && (i != 17)) {
             
return false;
         } 
else if (i < 17) {
             varArray[i] 
= varArray[i] * factorArr[i];
         }
     }
     
     
if (intStrLen == 18) {
         
//check date
         var date8 = idNumber.substring(6,14);
         
if (isDate8(date8) == false) {
            
return false;
         }
         
// calculate the sum of the products
         for(i=0;i<17;i++) {
             lngProduct 
= lngProduct + varArray[i];
         }
         
// calculate the check digit
         intCheckDigit = parityBit[lngProduct % 11];
         
// check last digit
         if (varArray[17!= intCheckDigit) {
             
return false;
         }
     }
     
else{        //length is 15
         //check date
         var date6 = idNumber.substring(6,12);
         
if (isDate6(date6) == false) {

             
return false;
         }
     }
     
return true;
     
 }
/**
 * 判断是否为“YYYYMM”式的时期
 *
 
*/
function isDate6(sDate) {
   
if(!/^[0-9]{6}$/.test(sDate)) {
      
return false;
   }
   
var year, month, day;
   year 
= sDate.substring(04);
   month 
= sDate.substring(46);
   
if (year < 1700 || year > 2500return false
   
if (month < 1 || month > 12return false
   
return true
}
/**
 * 判断是否为“YYYYMMDD”式的时期
 *
 
*/
function isDate8(sDate) {
   
if(!/^[0-9]{8}$/.test(sDate)) {
      
return false;
   }
   
var year, month, day;
   year 
= sDate.substring(04);
   month 
= sDate.substring(46);
   day 
= sDate.substring(68);
   
var iaMonthDays = [31,28,31,30,31,30,31,31,30,31,30,31]
   
if (year < 1700 || year > 2500return false
   
if (((year % 4 == 0&& (year % 100 != 0)) || (year % 400 == 0)) iaMonthDays[1]=29;
   
if (month < 1 || month > 12return false
   
if (day < 1 || day > iaMonthDays[month - 1]) return false
   
return true
}




posted @ 2010-03-30 11:30 BlakeSu 阅读(3018) | 评论 (2)编辑 收藏

Mozilla Thunderbird的一些设置

为了在windows和linux平台公用相同的邮件客户端和邮件内容,主要是有时候切换操作系统又要看以前的邮件。最后找到了 thunderbird(下面简称TB)客户端。这个客户端就是有点慢,倒是能满足我的要求。但是它的默认设置有时候有点不符合我们的使用习惯,我对它的 设置作了下面的一些修改:

    1:转发邮件
       默认的设置转发把邮件的内容作为附件转发。这样有两个不好的地方:第一,如果邮件有附件,这个附件不能转发;第二,接收方必须要用TB客户端了,否则打不 开。
       修改:编辑 -> 首选项 -> 编写 -> 常规:转发消息改成内联
   
    2:其它邮件客户端接收TB发的中文附件是乱码
       这个是标准问题,TB使用的是新的标准,但是别的客户端使用的是旧的标准(具体那个标准忘了,google一下就可以了)。这样就会出现乱码了。
       修改:编辑 -> 首选项 -> 高级 -> 配置编辑器:mail.strictly_mime.parm_folding 改成0或者1

    3:自动打开附件
       TB默认的是在打开邮件的时候同时自动打开邮件的附件。这样的话,如果附件大就很头痛。
       修改:编辑 -> 首选项 -> 高级 -> 配置编辑器:
          mail.inline_attachments   改成faulse
          mail.content_disposition.type   改成1

    4:回复邮件时回复的邮件内容在下面
       TB默认的回复邮件的回复内容是在下面的,这样如果邮件来回几次,回复比较多,看起来很不方便。
       修改:编辑 -> 首选项 -> 高级 -> 配置编辑器:Mail.identify.default.reply_on_top值由0改为1
  
    还有一个问题没有解决,就是有时候在TB中打开一个文件夹,它会重新建索引还是什么的,这时候打开一个文件夹比较慢。看网上有说把这个文件夹重命名,再创 建一个同名的文件夹,最后把老的文件夹的内容拷贝到新的里面就好了,这个没有试过。不过这个也不是特别大的问题,就没有继续搞了,什么时候有空再看看,到 时候再贴上来。

posted @ 2010-03-19 16:39 BlakeSu 阅读(691) | 评论 (0)编辑 收藏

tar命令详解

格式:  tar  选项  文件目录列表
功能:  对文件目录进行打包备份
选项:
-c  建立新的归档文件
-r  向归档文件末尾追加文件
-x  从归档文件中解出文件
-O  将文件解开到标准输出
-v  处理过程中输出相关信息
-f  对普通文件操作
-z  调用gzip来压缩归档文件,与-x联用时调用gzip完成解压缩
-Z  调用compress来压缩归档文件,与-x联用时调用compress完成解压缩  
例如:
1.将当前目录下所有.txt文件打包并压缩归档到文件this.tar.gz,我们可以使用
tar czvf this.tar.gz ./*.txt
2.将当前目录下的this.tar.gz中的文件解压到当前目录我们可以使用
tar xzvf this.tar.gz ./

posted @ 2010-03-18 17:21 BlakeSu 阅读(198) | 评论 (0)编辑 收藏

websphere6.1 设定虚拟机参数

Application Servers > server1 > Process Definition > Java Virtual Machine > Custom Properties

虚拟机参数在命令行的形式为 -Dproperty=value,在程序中可以用System.getProperty("property")取值。
利用这个特性可以对程序运行进行控制,避免代码的修改。




posted @ 2010-03-15 09:57 BlakeSu 阅读(256) | 评论 (0)编辑 收藏

firefox3.6扩展和插件安装位置

地址栏输入about:support,在打开的页面有打开配置文件夹的按钮;
扩展在Extensions文件夹下,插件在安装文件夹下的plugin和其他目录。

posted @ 2010-03-15 09:22 BlakeSu 阅读(414) | 评论 (0)编辑 收藏

xfire 动态客户端


import java.net.URL;

import org.codehaus.xfire.client.Client;

public class XfireClient
{

    
public static void main(String[] args)
    {
        DyClient();
    }

    
/**
     * You get a DynamicClient when you create a Client with the URL of a WSDL
     
*/
    
public static void DyClient()
    {
        
try
        {
            Client client 
= new Client(
                    
new URL(
                            
"http://www.webxml.com.cn/webservices/qqOnlineWebService.asmx?wsdl"));
            Object[] results 
= client.invoke("qqCheckOnline",
                    
new Object[] { "31506173" });
            System.out.println((String) results[
0]);

        }
        
catch ( Exception e)
        {
            e.printStackTrace();
        }
    }
}




必须jar:
commons-codec-1.3.jar
commons-httpclient-3.0.jar
commons-logging-1.0.4.jar
jdom-1.0.jar
wsdl4j-1.6.1.jar
xfire-all-1.2.6.jar
XmlSchema-1.1.jar

posted @ 2010-03-08 16:00 BlakeSu 阅读(337) | 评论 (0)编辑 收藏

汉字与utf8编码相互转换


import java.io.UnsupportedEncodingException;


public class UTF {

    public static void main(String[] args) {
        String s 
= "非常好";
        
try {
            
byte[] b = s.getBytes("UTF-8");
            
for(int i=0; i< b.length; i++){
                System.out.println(Integer.toHexString(b[i]).substring(
6));
                
            }
            System.out.println(
new String(b, "UTF-8"));

        } 
catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } 
        

    }

}

输出:
e9
9d
9e
e5
b8
b8
e5
a5
bd
非常好

posted @ 2010-02-26 13:39 BlakeSu 阅读(197) | 评论 (0)编辑 收藏

状态模式与策略模式的重要区别

是否需要在State类或Strategy类中访问Context.
状态模式通常需要调用Context中的方法,以改变Context的状态。
Strategy通常不需要。

posted @ 2010-02-23 17:50 BlakeSu 阅读(309) | 评论 (0)编辑 收藏

linux正则表达式


记号 含义 举例 匹配
. 任何字符 a.. a后两个字符
^ 行首 ^wood 位于行首的wood
$ 行尾 x$
^INSERT$
^$
位于行尾的x
只包含字符串INSERT的行
不包含任何字符的行
* 前导的正则表达式重复0或若干次 x*
xx*
.*
w.*s
0或若干次连续的x
1或多个连续的x
0或若干个字符
以w开始,s结尾的任何字符串
[字符表] 字符表中的任一 [tT]
[a-z]
[a-zA-Z]
小写或大写的t
小写字母
字母(大写或小写)
[^字符表] 任一不在字符表中的字符 [^0-9]
[^a-zA-Z]
任何数字
非字母
\{min,max\} 前导的正则表达式重复至少min次,最多max次 X\{1,5\}
[0-9]\{3,9\}
[0-9]\{3\}
[0-9]\{3,\}
最少1个,最多5个x
3到9个数字
正好3个数字
至少3个数字
\(…\) 将小括号中匹配的字符串存储到下一个寄存器中(1-9) ^\(.\)
^\(.\)\1
行中第1个字符存到1号寄存器
行首两个字符,且它们相同

如下命令含有正则表达式: cut paste sed tr grep sort uniq

posted @ 2010-02-11 15:01 BlakeSu 阅读(272) | 评论 (0)编辑 收藏

开源框架(spring struts2 tomcat)源码下载地址

spring

svn checkout https://src.springframework.org/svn/spring-framework/trunk spring-framework

  ant resolve

struts2

svn checkout http://svn.apache.org/repos/asf/struts/struts2/trunk struts2
svn checkout http://svn.apache.org/repos/asf/struts/xwork/trunk/ xwork

 mvn install
 mvn eclipse:eclipse

tomcat6

svn checkout http://svn.apache.org/repos/asf/tomcat/tc6.0.x/trunk tc6.0.x
 1.下载ant 1.6.x
 2. 命令行下执行 ant download,下载依赖jar.

posted @ 2010-02-07 10:41 BlakeSu 阅读(459) | 评论 (0)编辑 收藏

spring 计时器类 StopWatch

 StopWatch

posted @ 2010-02-05 16:08 BlakeSu 阅读(535) | 评论 (0)编辑 收藏

[李琨]REST的主要优势到底是什么?

在JavaEye论坛上回答网友joyjiang的疑问:“REST的优势到底是什么?开发效率?文档的管理?url的直观?还是其它的什么优势呢?”

REST的主要优势在我看来其实在于它是一种对于服务器的更加有效的抽象方式。

对于基于网络的应用来说,你怎么样看待服务器,就会产生什么样的架构风格,随之产生与该架构风格相关的交互模式。

RPC架构风格将服务器看作是由一些过程组成,客户端调用这些过程来执行特定的任务。SOAP就是RPC风格的一种架构。过程是动词性的(做某件事),因此RPC建模是以动词为中心的。

分布式对象架构风格认 为服务器是由一些对象和对象上的方法组成,客户端通过调用这些对象上的方法来执行特定的任务。并且客户端调用这些对象上的方法应该就像是调用本地对象上的 方法一样,这样开发就可以完全按照统一的面向对象方法来做。但是很可惜,这样的抽象并不是很有效,因为分布式对象与本地对象存在着巨大的本质差别,想要掩 盖这些差别很多时候甚至是有害无益的。

REST架构风格并 没有试图掩盖这些差别,而是将服务器抽象为一组离散资源的集合。资源是一个抽象的概念,而不是代表某个具体的东西。注意:要真正理解REST,就一定要增 强自己的抽象思维能力,充分理解到资源是抽象的。如果完全不具有抽象思维的能力,一定要将资源与数据库中的一张表或服务器端的一个文件(HTML、 Servlet、JSP、etc.)一一挂起钩来,就无法真正理解REST了。资源是名词性的,因此REST建模是以名词为中心的。

上述 是目前基于网络的应用的主要的三种抽象方式。这三种不同的抽象方式会严重影响客户端与服务器的交互模式,而不同交互模式的交互效率差别相当大。分布式对象 的交互模式很多时候效率很低,因为掩盖了分布式对象与本地对象的差别,很多时候都会导致细粒度的API(需要一再强调才能让一些不明就里的架构初哥按照正 确的方式来做设计)。实践已经证明,与RPC和分布式对象相比,REST是一种对于服务器更加有效的抽象方式,将会带来粒度更大和更有效率的交互模式。这 样的效果与Fielding设计REST的初衷是吻合的,REST就是专门为交互的性能和可伸缩性进行过优化的一种架构风格。而SOAP在设计的时候优先 考虑的从来不是性能和可伸缩性,而是互操作性。除非出现奇迹,否则你种什么,就应该长出来什么。你种的是瓜,长出来的就是瓜;你种的是豆,长出来的就是 豆。

Fielding写到:“REST提供了一组架构约束,当作为一个整体来应用时,强调组件交互的可伸缩性、接口的通用性、组件的独立部署、以及用来减少交互延迟、增强安全性、封装遗留系统的中间组件。

有 人认为REST不是面向对象的,其实REST虽然没有分布式对象那么面向对象,在我看来至少比RPC更加面向对象。按照《企业应用架构模式》,以动词为中 心建模是什么?是不是就是事务脚本?以名词为中心建模是什么?是不是就是领域模型?这就扯远了,网络通信是否一定需要实现为面向对象的形式,我认为是不需 要的。

“REST的主要优势在我看来其实在于它是一种对于服务器的更加有效的抽象方式。”
这句话等于是,我先把一个骨架放在这里,还没有用血肉来充实它,也就是还没有举出具体的实例来。具体的实例以后我们还需要来详细讨论。REST是非常简练的,同时又是一种非常强大的抽象方式,在我看来就是从根本上简化Web开发的一味良药。

posted @ 2010-02-05 10:57 BlakeSu 阅读(231) | 评论 (0)编辑 收藏

取用户所有表的所有索引

select index_name from dba_indexes where table_name
in (select table_name from user_tables)

posted @ 2010-01-29 10:08 BlakeSu 阅读(127) | 评论 (0)编辑 收藏

oracle优化新知识

1.位图索引用于数据仓库,不能用于普通系统
2.使用组合索引. 当大量字段同同时作为过滤条件时,使用组合索引会大大提高性能。
建立组合索引时,注意小基数字段在前,大基数字段在后。
3.同一字段出现在不同表要保持类型一致(确有需要,可使用函数索引)
4.使用count(*)
5.使用返回单个结果的查询改写外连接能取得较好的性能

posted @ 2010-01-22 13:22 BlakeSu 阅读(189) | 评论 (0)编辑 收藏

Oracle中表连接的运行原理

Oracle优化器会自动选择以下三种方式的一种运行表连接,但在数据环境上配合强化选择合适的方式或强制使用某种方式是SQL优化的需要:
 
   NESTED LOOP

对于被连接的数据子集较小的情况,nested loop连接是个较好的选择。nested loop就是扫描一个表,每读到一条记录,就根据索引去另一个表里面查找,没有索引一般就不会是 nested loops。

一般在nested loop中, 驱动表满足条件结果集不大,被驱动表的连接字段要有索引,这样就走nested loop。如果驱动表返回记录太多,就不适合nested loops了。如果连接字段没有索引,则适合走hash join,因为不需要索引。

可用ordered提示来改变优化器默认的驱动表,可用USE_NL(table_name1 table_name2)提示来强制使用nested loop。

HASH JOIN

hash join是优化器做大数据集连接时的常用方式。优化器扫描小表(或数据源),利用连接键(也就是根据连接字段计算hash 值)在内存中建立hash表,然后扫描大表,每读到一条记录就来探测hash表一次,找出与hash表匹配的行。

当 小表可以全部放入内存中,其成本接近全表扫描两个表的成本之和。如果表很大不能完全放入内存,这时优化器会将它分割成若干不同的分区,不能放入内存的部分 就把该分区写入磁盘的临时段,此时要有较大的临时段从而尽量提高I/O 的性能。临时段中的分区都需要换进内存做hash join。这时候成本接近于全表扫描小表+分区数*全表扫描大表的代价和。

至于两个表都进行分区,其好处是可以使用parallel query,就是多个进程同时对不同的分区进行join,然后再合并。但是复杂。

使用hash join时,HASH_AREA_SIZE初始化参数必须足够的大,如果是9i,Oracle建议使用SQL工作区自动管理,设置WORKAREA_SIZE_POLICY 为AUTO,然后调整PGA_AGGREGATE_TARGET即可

以下条件下hash join可能有优势:

两个巨大的表之间的连接。

在一个巨大的表和一个小表之间的连接。

可用ordered提示来改变优化默认的驱动表,可用USE_HASH(table_name1 table_name2)提示来强制使用hash join。

SORT MERGE JOIN

sort merge join的操作通常分三步:对连接的每个表做table access full;对table access full的结果进行排序;进行merge join对排序结果进行合并。sort merge join性能开销几乎都在前两步。一般是在没有索引的情况下,9i开始已经很少出现了,因为其排序成本高,大多为hash join替代了

通常情况下hash join的效果都比sort merge join要好,然而如果行源已经被排过序,在执行sort merge join时不需要再排序了,这时sort merge join的性能会优于hash join。

在全表扫描比索引范围扫描再通过rowid进行表访问更可取的情况下,sort merge join会比nested loops性能更佳。

可用USE_MERGE(table_name1 table_name2)提示强制使用sort merge join。

posted @ 2010-01-15 12:05 BlakeSu 阅读(372) | 评论 (0)编辑 收藏

java 运行windows命令 并获取输出

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

public class ProcessTest {

    
public static void main(String[] args) {
        
         ProcessBuilder pb 
= new  ProcessBuilder ( "tasklist");  
         try {
            Process process 
= pb.start();
            InputStream fis 
= process.getInputStream();
            BufferedReader br 
= new BufferedReader(new InputStreamReader(fis));

            String line 
= null;
            StringBuffer cmdout 
= new StringBuffer();
            
while ((line = br.readLine()) != null) {
                cmdout.append(line).append(
"\n");
            }
            System.out.println(cmdout.toString().trim());
        } 
catch (IOException e) {
            e.printStackTrace();
        }
    }
}

输出如下:

图像名                       PID 会话名           会话#       内存使用
========================= ====== ================ ======== ============
System Idle Process            0 Console                 0         28 K
System                         4 Console                 0        324 K
smss.exe                    1076 Console                 0        812 K
csrss.exe                   1152 Console                 0      3,296 K
winlogon.exe                1176 Console                 0     31,580 K
services.exe                1220 Console                 0      4,684 K
lsass.exe                   1232 Console                 0      1,672 K
svchost.exe                 1408 Console                 0      6,236 K
svchost.exe                 1496 Console                 0      5,036 K
svchost.exe                 1656 Console                 0     38,656 K
spoolsv.exe                 1872 Console                 0      8,000 K
explorer.exe                 332 Console                 0     18,888 K
avp.exe                      376 Console                 0     24,960 K
db2dasrrm.exe                460 Console                 0     34,652 K
TSVNCache.exe                672 Console                 0     12,476 K
igfxtray.exe                1380 Console                 0      7,344 K
hkcmd.exe                   1236 Console                 0      4,056 K
igfxpers.exe                1428 Console                 0      3,468 K
db2mgmtsvc.exe              1444 Console                 0     10,072 K
RTHDCPL.exe                 1460 Console                 0     32,480 K
igfxsrvc.exe                1572 Console                 0      3,772 K
avp.exe                     1680 Console                 0      6,008 K
db2systray.exe              1700 Console                 0     32,512 K
ctfmon.exe                  1780 Console                 0      4,892 K
picpick.exe                 1984 Console                 0      3,600 K
QQ.exe                      2024 Console                 0     34,648 K
dsNcService.exe              264 Console                 0      3,880 K
365日历.EXE                 1952 Console                 0     43,788 K
CLCL.exe                    1028 Console                 0      8,252 K
klnagent.exe                1052 Console                 0      3,196 K
thunderbird.exe              352 Console                 0     38,692 K
rtxc.exe                     472 Console                 0     29,968 K
db2rcmd.exe                 1836 Console                 0     11,832 K
TXPlatform.exe              2488 Console                 0      3,808 K
firefox.exe                 2724 Console                 0    195,912 K
cmd.exe                     2716 Console                 0         52 K
sh.exe                      3936 Console                 0        152 K
conime.exe                  2752 Console                 0      3,424 K
eclipse.exe                 3060 Console                 0      2,592 K
JAVAW.EXE                   2984 Console                 0    446,692 K
EXCEL.EXE                   3232 Console                 0      1,936 K
wmiprvse.exe                4084 Console                 0      6,368 K
JAVAW.EXE                    320 Console                 0      6,860 K
tasklist.exe                2936 Console                 0      4,812 K

当运行其他命令 ,如dir等时,用如下写法:

 
ProcessBuilder pb = new  ProcessBuilder ( "cmd""/c""dir");


posted @ 2010-01-13 13:49 BlakeSu 阅读(584) | 评论 (0)编辑 收藏

Ubuntu9.10正确有效关闭IPV6的方法

Ubuntu下上网解析DNS慢有很大程度上是和IPV6有关,而目前国内大部分地方都还没有IPV6网络,所以一般用户应该需要关闭IPV6

网上流传着很多IPV6的关闭方法,但是经过测试大部分都是针对老版本的,而且效果不好。

这里提供一种方法作为参考

/proc/sys/net/ipv6/conf/lo/disable_ipv6

这个档案,用cat指令可以看到 0 这个数字,将他设定为1就可以了。
因为已经将ipv6编入kernel,因此在proc里面就可以看得到相关的设定。

设定的方式有很多种,有的是用echo 1 >> [路径]/档桉名称
的方式,这种方式是每次开机以后就得要打一次。
所以延伸出第二个方法,在rcS.d里面设定一个连结,去执行这个指令的script。
第3个方法,就是设定sysctl.conf档桉,也是最正统的做法。
位置在
/etc/sysctl.conf
这个档桉可以设定很多,包括要当成NAT时的封包转发等等。
要设定
/proc/sys/net/ipv6/conf/lo/disable_ipv6
这个档桉,就是在sysctl.conf里面加上

net.ipv6.conf.lo.disable_ipv6 = 1

posted @ 2010-01-09 14:53 BlakeSu 阅读(559) | 评论 (0)编辑 收藏

Git: Branch from a tag

In git, you can’t update a tag directly, but you can branch the code to create a new tag. Here’s how you would do that:

First, you need to checkout the tag:

git checkout <tag_name> 

Then create a branch:

git branch -b <branch_name>

After you make your changes, commit them (there are a few ways to do this, keeping it simple):

git commit -am 'my descriptive comment on this commit'

You can create a new tag:

git tag <new_tag_name>

Then you can push the tag:

git push --tags

posted @ 2010-01-08 08:37 BlakeSu 阅读(1095) | 评论 (0)编辑 收藏

'git revert' Is Not Equivalent To 'svn revert'

I just learned that if you have some changes in your working tree that you want to get rid of, you don't type 'git revert' like you might guess. No, that's what cvs, subversion, mercurial, and bazaar (to name a few) use revert to mean, but not git. With git, revert is used to undo actual commits. Thankfully, you can undo your revert with another 'git revert', I just learned. So let me repeat to be clear, if you have changes to your working files that you want to abandon, DO NOT do this:

git revert HEAD

That will undo your last commit. Do this instead:

git reset --hard HEAD

I'm glad I have that straightened out now. I'm wondering if /etc was really a good place for me to start out playing with git.

UPDATE: Nearly two years later and I'm still getting comments on this. I'm glad I've been able to help people out this way. The discussion in the comments is good, and one thing I'd like to point out is that I now always use and recommend:

git checkout filename

(as recommended by Anonymous and others below) instead of git reset. I think the git stash trick from Nicolas is pretty cool too.

posted @ 2010-01-06 14:48 BlakeSu 阅读(657) | 评论 (0)编辑 收藏

Linux内核版本号的意义

内核版本指的是在Linus领导下的开发小组开发出的系统内核的版本号。第一数字叫主版本号,第二个叫次版本号,第三个叫修订版本号。一般说来次版本号还 有特定的意义,以序号的第二位为偶数的版本表明这是一个可以使用的稳定版本,如2.0.35,而序号的第二位为奇数的版本一般有一些新的东西加入,是不一 定很稳定的测试版本,如2.1.88。这样稳定版本来源于上一个测试版升级版本号,而一个稳定版本发展到完全成熟后就不再发展。
总结一下:
第一个数字表示大版本,相当于大升级了.
第二个数字有两个含义:大版本的小版本;偶数表示生产版(奇数表示测试版);
第三个数字表示指定小版本的补丁包;如2.6.10 Linux内核的推出,表明一年中已经发布了10个版本.
不过,2.6.x系列以前版本没有带有次小数点的版本号,即没有四个数字组成的版本号,而在2.6.x系列中,从2.6.8.1内核开始,一直持续到2.6.11,较小的内核隐患和安全补丁被赋予了次小数点版本号(例如2.6.11.1)。
但 值得注意的是.readhat linux内核的版本稍有不同如2.4.20-10,可以发现多了一组数字(10),该数字是建立(build)号。每个建立可以增加少量新的驱动程序或 缺陷修复。一些readhat 内核还带“pp”,就是“pre-patch”的意思,是个内核的测试版本。

posted @ 2010-01-05 11:40 BlakeSu 阅读(588) | 评论 (0)编辑 收藏

技术领导之路

 理解问题

 管理思维

 保证质量

posted @ 2009-12-30 16:03 BlakeSu 阅读(160) | 评论 (0)编辑 收藏

PV,评判网站的标准

PV(pageview),即页面浏览量,或点击量;通常是衡量一个网络新闻频道或网站甚至一条网络新闻液没涤的主要指标;当然,有时还会同时考察另外一个指标,即uv(unique visitor),指访问某个站点或点击某条新闻的不同IP地址的人数。

    PV之于网站,就像收视率之于电视,从某种程度上已成为投资者衡量商业网站表现的最重要尺度。从长远看,很多网站也意识到,PV的追求需要和品牌的打造结合起来;但现代商业行为在投资者急功近利的评判压力下,往往无奈为了使PV提升而不择手段。

    一条新闻发布以后,其PV便可以加以跟踪,通常是每5分钟统计一次。不同网站的不 同频道,对其所发布新闻的PV表现有一个大致的评判尺度。新闻发布后,一般PV值总有一个上升的过程。可以从不同时段来计算PV的单位时间变化幅度,有经 验的网络编辑,经过几个5分钟的数据积累,便能大致预料到这条新闻的PV峰值水平。如果这个水平不能令人满意,则编辑就要采取一些手段,如“优化”标题、 增加图片、挪动位置等。一般来说,通过这样的“处理”,一条新闻的PV表现能有所改善,达到新的高峰。也就是说,网络新闻的编辑手段影响着PV值。

    还有哪些因素对PV有影响呢?至少还有这些因素:新闻发布的时间。不同的时间段,上网的人数不同,访问该站点的人数也不同,因此,有时PV的涨落,其主要贡献,在于不同时段上网人数的自然波动。同样一条新闻,在不同的时段发布,PV就会有差别。

    不同时段上网的人,其人口特征(性别、年龄、教育程度、阅读旨趣等)不同,所以,同样是一万个上网的人,甚至同样是对某个网站的一万次访问,不同时段,这一万次访问在不同频道/内容上的分布是有差别的。所以PV的变化,与这些因素导致的变化有关。

    访问的周期。对于一些常浏览的网站,我们可能一天之中会访问几次,这中间有一定的 时间间隔。这个间隔,很多时候和人们的现实工作节奏有关系。比如,不少人一上班会抽空浏览一下新闻,第二次再来看看又有什么新闻的时候,往往是上午中间休 息时,甚至是午饭后的休息时间。因此,即使其他因素不变,由于人们回访网站的周期性,也会对新闻或网站的PV带来影响。当然,由于不同的人回访的周期长短 不一、时段不一,这个影响因素未必会导致明显的波动,而可能分散在不同时段的PV表现中,但可以肯定的是,任何一个PV数据,也有这种回访周期的因素所起 的作用。

    搭便车因素。比如一些突发事件,会导致人们对某一网站的访问增加,但这些访问的 初衷,本只是突发事件相关新闻。然而由于人们的新闻消费,往往具有不可预期性,所以常见的现象是,人们在看完想看的新闻后,还会顺带看看其他的。这一因 素,也可能对某条新闻(与突发事件无关)的PV有所贡献。

    最后,偶然因素也对PV有一定影响,比如天气因素,比如非典期间等等。

    由此看来,一个简单的PV数据,其实是多种因素综合贡献的结果,所以有时的PV涨 落,实在不是完全可以通过编辑手段来加以引导和影响的。知道这一点很重要,因为这告诉我们,盲目地、不加具体分析地以PV来衡量成败好坏,是不合理的。在 社会科学研究中,这种区分不同因素对某一个现象的贡献,就是所谓的详析模式。很多看似不变的东西,其实内部构成比例上发生了很大的变化。而有些看似变化的 东西,其相对关系其实没有什么变化,只是一种单纯的数量上的涨落。

    这使我想到那本《统计陷阱》,一本由一个记者所写的通俗读物。这本书的英文名称直译,叫“如何用统计数据说谎”。

posted @ 2009-12-21 11:42 BlakeSu 阅读(172) | 评论 (0)编辑 收藏

彻底理解JavaHelp结构的好处

Sun微系统的JavaHelp系统是一种应用程序帮助技术,它可以在所有支持Java的平台和浏览器中运行只要它是一个纯粹的Java产品。通过 applet和Java应用程序,在其他环境下,比如在互联网或企业内部互联网中,它是理想的使用对象。在本文中,我将回顾JavaHelp的主要作用, 并阐明它的简单使用方法。

    优点

    JavaHelp通过使用Java基础类(JFC) 软件组件来实现,这使得开发户自定义界面和功能变得灵活轻松。您可以轻而易举地将应用程序的帮助信息嵌入到应用程序之中,或者嵌入到另一个独立的窗口里。JFC 还具有通过自定义导航控件拓展帮助功能的能力。

    JavaHelp使动态更新帮助数据或将其存储在一个便利的位置变得简单易行,不管是在客户端还是服务器端。内容窗口使用HTML 3.2格式显示话题,使内容设计变得简单。标准导航提供内容表单(TOC)、索引和全文搜索。(TOC和索引都遵循W3C标准。)

    JavaHelp Data Sheet提供以下信息:TOC提供层叠式和扩展式话题展示,无限量等级层次和多重TOC的合并。TOC与内容阅读器同步显示,也就是说显示的话题在 TOC中被突出。索引支持多重索引的合并。全文搜索被设计得很灵活,并且可以配置。搜索引擎也可置于用户或服务器中的任一方。

    帮助内容和搜索引擎被压缩成一个使用标准JAR格式的单个文件。尽管为了使存储和访问更具灵活性,推荐将所有文件压缩成一个单独的文件,但是您仍然可以将 所有文件以扩展的格式保存在目录中。您可以在自定义编写的导航器、搜索引擎、标准JavaHelp阅读器或在任何HTML显示中,包括标准Web浏览器 中,查看和导航内容。

    JavaHelp API提供一个上下文敏感帮助和ID映射的机制。您可以将多重组件的帮助信息用JavaHelp API合并,这样用户就看到一个单独的完整文档。合并机制可以应用于TOC、索引和搜索数据库。

    特性

    JavaHelp有两个主要版本:1.1.3和2.0版。最早支持JavaHelp 2.0的Java版本是J2SE 1.2.2,因此您无需担心自己的代码是否支持JavaHelp。JavaHelp系统由一个特性完整的、可扩展的规范、API以及一个参考执行组成。

    标准JavaHelp系统的主窗口:有三个显示窗口,在您退出窗口时并未被关闭,依然可配置。在默认情况下,一个主要窗口有以下三个窗格:工具栏、导航窗口和内容窗口。见图表1。

    用户可以应用多种方式通过内部应用程序调用在线帮助,例如,当一个用户从帮助菜单中选择一项,或在应用程序GUI中点击帮助按钮,JavaHelp系统提 供一个简便的界面,通过这个界面,应用程序要求话题的ID 得以显示。然后JavaHelp系统将话题ID与相应的URL相连接并将其显示出来。

    ID被映射到一个被称作映射文件的JavaHelp系统元数据文件中的URL上。例如,当为文件选择对话框编码时,开发人员要求话题ID fc_help在当对话框底部的帮助按钮被点击时显示。在映射文件中,ID fc_help被定义为名为 FileChooser.html的文件,使用以下XML句法:

    将文件名(或URL)的规范从程序代码分离为内容的作者提供了控制与话题ID相关的信息的自由。

    工具提示是一个显示给用户的简短信息,当光标停留在一个按钮上的时间间隔长于阈值时它就会出现。您还可以将工具提示信息纳入JavaHelp系统数据。

    JavaHelp系统数据具有调用在线帮助的能力,能够在应用程序GUI中描述图形组件。用户操纵激活语境敏感帮助,然后将组件以问题形式特定化。与组件相联系的ID被显示。您可以从TOC、索引导航或主要窗口的内容窗格中显示帮助话题。

    轻型组件

    轻型组件能够向帮助话题添加功能。这些组件与Java的applet相似,但它们的加载和执行更为迅速。一个帮助的创作者能够使用已经在JavaHelp 中执行的轻型组件;这个组件执行弹出窗口和次级窗口。在HTML 话题文件中使用轻型组件,您可以使用HTML<object>标记,正如列表A中的例子所显示的。

    在例子中,弹出的对象包括文件../topicB/glossary_def.html,用户点击的对象(viewerActivator)是个链接,窗 口类型属于弹出型,窗口大小为300x400,用户在链接中看到的内容是“Click here(点击这里)”。

    Java开发商还可以创造新的轻型组件。例如,这样的组件可能为帮助话题添加动画和多媒体功能。

    要求抽象查看的轻型组件必须执行javax.javahelp.impl.ViewAwareComponen。这些组件执行setViewData() 方法。这个组件能够根据抽象查看中的信息决定它所执行的环境。(注意:要访问抽象查看,您应该使用JavaHelp API。)在列表B中,文档对象下面的编码片断来自于抽象查看。

    需要更多关于创造Java轻型组件的信息,请参阅相关文件。

    JavaHelp编写工具

    有很多通过商业途径可以得到的编写工具能够为您的应用程序编写和维护一个完美的帮助系统。最有名的三个是Software7 Gmbh的Helen 1.5、Solutionsoft的HelpBreeze和Pivotonic的JawaHelpAuthor。所有这些第三方产品都支持Java 2 和Java 1.1标准。需要更多关于编写工具的信息,请参阅Sun的帮助编写工具页面。

    试试看吧

    如果JavaHelp听起来像是一个您认为您的用户和伙伴开发商都喜欢的系统的话,那么从Sun Microsystem公司的网站上立刻下载吧。这个地址提供了安装过程所需要的所有信息。

posted @ 2009-12-21 09:23 BlakeSu 阅读(197) | 评论 (0)编辑 收藏

在Linux中开启IP转发

本文源地址: http://easwy.com/blog/archives/enable-ip-forward-on-linux/

Linux系统缺省并没有打开IP转发功能,要确认IP转发功能的状态,可以查看/proc文件系统,使用下面命令:

cat /proc/sys/net/ipv4/ip_forward

如果上述文件中的值为0,说明禁止进行IP转发;如果是1,则说明IP转发功能已经打开。

要想打开IP转发功能,可以直接修改上述文件:

echo 1 > /proc/sys/net/ipv4/ip_forward

把文件的内容由0修改为1。禁用IP转发则把1改为0。

上面的命令并没有保存对IP转发配置的更改,下次系统启动时仍会使用原来的值,要想永久修改IP转发,需要修改/etc/sysctl.conf文件,修改下面一行的值:

net.ipv4.ip_forward = 1

修改后可以重启系统来使修改生效,也可以执行下面的命令来使修改生效:

sysctl -p /etc/sysctl.conf

进行了上面的配置后,IP转发功能就永久使能了

posted @ 2009-12-18 13:41 BlakeSu 阅读(1940) | 评论 (0)编辑 收藏

linux库管理

 Linux下的库文件分为共享库和静态库两大类,它们两者的差别仅在程序执行时所需的代码是在运行时动态加载的,
  还是在编译时静态加载的。区分库类型最好的方法是看它们的文件后缀,通常共享库以.so(Shared Object的缩写)结尾,
  静态链接库通常以.a结尾(Archive的缩写)。在终端缺省情况下,共享库通常为绿色,而静态库为黑色。

库操作命令

  Linux库操作可以使用命令完成,目前常用的命令是ldd和ldconfig。

 1.ldd
  ldd是Library Dependency Display缩写,它的作用是显示一个可执行程序必须使用的共享库。

  $ ldd /usr/bin/mesg
  libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7eaf000)
  /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0xb7feb000)

 2.ldconfig
  库安装到系统以后,为了让动态链接库为系统所认识及共享,就需要运行ldconfig。ldconfig命令的用途,
  主要是在默认搜寻目录(/lib和/usr/lib)以及动态库配置文件/etc/ld.so.conf内所列的目录下,搜索出可共享的动态链接库(格式如lib*.so*),
  进而创建出动态装入程序(ld.so)所需的连接和缓存文件。缓存文件默认为/etc/ld.so.cache,此文件保存已排好序的动态链接库名字列表,
  ldconfig通常在系统启动时运行,而当用户安装了一个新的动态链接库时,就需要手工运行这个命令。

 (1)命令格式
   ldconfig [选项] [libs]

 (2)主要选项
   -v或–verbose ldconfig将显示正在扫描的目录、搜索到的动态链接库,以及它所创建的连接的名字。

   -f CONF 指定动态链接库的配置文件为CONF,系统默认为/etc/ld.so.conf。

   -C CACHE 指定生成的缓存文件为CACHE,系统默认的是/etc/ld.so.cache,文件存放已排好序的可共享的动态链接库的列表。

   -p或–print-cache 让ldconfig打印出当前缓存文件所保存的所有共享库的名字。

   -r ROOT 改变应用程序的根目录为ROOT。

   -n ldconfig仅扫描命令行指定的目录,不扫描默认目录(/lib、/usr/lib),也不扫描配置文件/etc/ld.so.conf所列的目录。

  运行没有选项的ldconfig命令时,用于更新高速缓冲文件。这个命令主要用于高速缓冲DNS服务器(Caching DNS Server)。
  高速缓冲DNS服务器的原理是提供查询的历史记录,并且利用这些记录来提高查询的效率。

  当某个查询是第一次被发送到高速缓冲DNS服务器时,高速缓冲DNS服务器就将此查询的整个过程记录下来,
  在一定的时期内用它来回答所有相同的查询,从而减少整个DNS系统的负担并且提高查询速度。

库的升级

  Linux系统软件更新很快,新的核心几乎每几个星期就公布一次,其它软件的更新也是非常频繁。多数情况下,
  盲目跟随潮流的升级并不必要,如果确实需要新版本的特性时再升级。换句话说,不要为了升级而升级。
  Linux系统中多数软件都是用共享库来编译的,其中包含了在不同程序之间共享的公用子例程。

  在运行某个程序时,如果看到如下信息:“Incompatible library version.”则表明需要将该库升级到程序所需要的版本。
  库是向下兼容的,也就是说,用老版本库编译的程序可以在新安装的版本库上运行,反之则不行。

  Linux库函数的升级是一项重要的工作,往往与其它软件包的升级有一定关联作用,所以操作前一定要备份文件。
  下面看一下如何把Glibc 2.2.4.13升级至2.3.2版本,其过程如下:

  1.下载.gz压缩文件并解压

    在GUN C网站下载的四个.gz压缩文件,解压至一临时目录中:
    cd /usr/caolinux
    tar xzvf glibc-2.3.2.tar.gz
    cd glibc-2.3.2
    tar xzvf ../glibc-linuxthreads-2.3.2.tar.gz
    tar xzvf ../glibc-crypt-2.3.2.tar.gz
    tar xzvf ../glibc-localedata-2.3.2.tar.gz

  2.建立库函数的安装目录
    mkdir /usr/higlibc
    cd /usr/higlibc

  3.建立编译目录
    mkdir cao
    cd cao
    ./configure –enable-add-ons=linuxthreads,crypt,localedata -prefix=/usr/higlibc

  4.编译与安装
    make
    make check
    make install

  5.改变数据库的链接
    ln -s /usr/higlibc/lib/ld-linux.so.2 /lib/ld-linux.so.2

    然后,修改/etc/ld.so.conf,加入一行/usr/higlibc/lib,执行下面代码:
    ldconfig -v

    更新/etc/ld.so.cache的内容,列出每个库的版本号,扫描目录和所要创建及更新的链接。

  6.更改GCC设置
    cd /usr/lib/gcc-lib
    cp -r i386-redhat-linux higlibc

  7.更新符号链接
    cd /usr/higlibc/include
    ln -s /usr/src/linux/include/linux
    ln -s /usr/src/linux/include/asm
    ln -s /usr/X11R6/include/X11

  8.测试并完成

posted @ 2009-12-18 09:25 BlakeSu 阅读(154) | 评论 (0)编辑 收藏