太阳雨

痛并快乐着

BlogJava 首页 新随笔 联系 聚合 管理
  40 Posts :: 3 Stories :: 11 Comments :: 0 Trackbacks

2009年7月4日 #

一个Eclipse骨灰级开发者总结了他认为最有用但又不太为人所知的快捷键组合。通过这些组合可以更加容易的浏览源代码,使得整体的开发效率和质量得到提升。

    1. ctrl+shift+r:打开资源

    这可能是所有快捷键组合中最省时间的了。这组快捷键可以让你打开你的工作区中任何一个文件,而你只需要按下文件名或mask名中的前几个字母,比如applic*.xml。美中不足的是这组快捷键并非在所有视图下都能用。

    2. ctrl+o:快速outline

    如果想要查看当前类的方法或某个特定方法,但又不想把代码拉上拉下,也不想使用查找功能的话,就用ctrl+o吧。它可以列出当前类中的所有方法及属性,你只需输入你想要查询的方法名,点击enter就能够直接跳转至你想去的位置。

    3. ctrl+e:快速转换编辑器

    这组快捷键将帮助你在打开的编辑器之间浏览。使用ctrl+page down或ctrl+page up可以浏览前后的选项卡,但是在很多文件打开的状态下,ctrl+e会更加有效率。

    4. ctrl+2,L:为本地变量赋值

    开发过程中,我常常先编写方法,如Calendar.getInstance(),然后通过ctrl+2快捷键将方法的计算结果赋值于一个本地变量之上。这样我节省了输入类名,变量名以及导入声明的时间。Ctrl+F的效果类似,不过效果是把方法的计算结果赋值于类中的域。

    5. alt+shift+r:重命名

    重命名属性及方法在几年前还是个很麻烦的事,需要大量使用搜索及替换,以至于代码变得零零散散的。今天的Java IDE提供源码处理功能,Eclipse也是一样。现在,变量和方法的重命名变得十分简单,你会习惯于在每次出现更好替代名称的时候都做一次重命名。要使用这个功能,将鼠标移动至属性名或方法名上,按下alt+shift+r,输入新名称并点击回车。就此完成。如果你重命名的是类中的一个属性,你可以点击alt+shift+r两次,这会呼叫出源码处理对话框,可以实现get及set方法的自动重命名。

    6. alt+shift+l以及alt+shift+m:提取本地变量及方法

    源码处理还包括从大块的代码中提取变量和方法的功能。比如,要从一个string创建一个常量,那么就选定文本并按下alt+shift+l即可。如果同一个string在同一类中的别处出现,它会被自动替换。方法提取也是个非常方便的功能。将大方法分解成较小的、充分定义的方法会极大的减少复杂度,并提升代码的可测试性。

    7. shift+enter及ctrl+shift+enter

    Shift+enter在当前行之下创建一个空白行,与光标是否在行末无关。Ctrl+shift+enter则在当前行之前插入空白行。

    8. Alt+方向键

    这也是个节省时间的法宝。这个组合将当前行的内容往上或下移动。在try/catch部分,这个快捷方式尤其好使。

    9. ctrl+m

    大显示屏幕能够提高工作效率是大家都知道的。Ctrl+m是编辑器窗口最大化的快捷键。

    10. ctrl+.及ctrl+1:下一个错误及快速修改

    ctrl+.将光标移动至当前文件中的下一个报错处或警告处。这组快捷键我一般与ctrl+1一并使用,即修改建议的快捷键。新版Eclipse的修改建议做的很不错,可以帮你解决很多问题,如方法中的缺失参数,throw/catch exception,未执行的方法等等。

    更多快捷键组合可在Eclipse按下ctrl+shift+L查看。

posted @ 2009-07-04 05:42 小虫旺福 阅读(12) | 评论 (0)编辑 收藏

2009年4月29日 #

 

                新的工作开始了,希望能有一个美好的开似乎,努力!努力!!努力!!!
                 
                付出总会有回报,加油吧!

                希望新的工作,新的环境,会有新的收获。
posted @ 2009-04-29 08:24 小虫旺福 阅读(20) | 评论 (0)编辑 收藏

2009年3月6日 #

一个简单的例子

  假定有两个JavaBean如下,分别为Foo和Bar
package mypackage;
public class Foo {
  public void addBar(Bar bar);
  public Bar findBar(int id);
  public Iterator getBars();
  public String getName();
  public void setName(String name);
}
public mypackage;
public class Bar {
  public int getId();
  public void setId(int id);
  public String getTitle();
  public void setTitle(String title);
}

  用下面的xml文件进行配置
<foo name="The Parent">
  <bar id="123" title="The First Child"/>
  <bar id="456" title="The Second Child"/>
</foo>

  用下面几行代码即可完成配置文件解析工作:
Digest解析代码 注释
Digester digester = new Digester();  
digester.setValidating(false); 不进行XML与相应的DTD的合法性验证
digester.addObjectCreate("foo", "mypackage.Foo"); 当遇到<foo>时创建一个mypackage.Foo对象,并将其放在栈顶
digester.addSetProperties("foo"); 根据<foo>元素的属性(attribute),对刚创建的Foo对象的属性(property)进行设置
digester.addObjectCreate("foo/bar", "mypackage.Bar"); 当遇到<foo>的子元素<bar>时创建一个mypackage.Bar对象,并将其放在栈顶。
digester.addSetProperties("foo/bar"); 根据<bar>元素的属性(attribute),对刚创建的Bar对象的属性(property)进行设置
digester.addSetNext("foo/bar", "addBar", "mypackage.Bar"); 当再次遇到<foo>的子元素<bar>时创建一个mypackage.Bar对象,并将其放在栈顶,同时调用第二栈顶元素(Foo对象)的addBar方法。
Foo foo = (Foo) digester.parse(); 分析结束后,返回根元素。

基本情况

  熟悉用SAX来处理XML文档的程序员,会发现Digester隐藏了遍历XML元素这些细节,而是提供了更高一层的、更友好的SAX事件接口,从而让程序员的精力放在对数据的处理过程中。
  使用Digester,须按照以下步骤:
  1. 创建一个org.apache.commons.digester.Digester实例。一个解析请求完成后,这个Digester可以被后面复用。但也不要试图在不同的线程中从共享一个Digester实例。
  2. 根据需要设置一些配置属性(configuration properties),以控制下一步的解析操作。
  3. 将一个或几个初始对象(initial object)压入Digester对象栈,本步骤不是必须的。
  4. 注册所有的元素匹配模板(elemet matching pattern)。当一个模板被从输入文档中识别出来以后,与其相联系的处理规则(processing rules)被激活。对一个特定的模板,可以定义任意多的规则,当识别出该模板后,这些规则依序依次执行。
  5. 调用digester.parse()方法,一个XML文档的引用(用多种方式供选择)要传给这个方法。注意,需要捕捉并处理IOException或SAXEception或处理过程中抛出的异常。

元素匹配模板

  Digester能自动遍历目标XML文档的元素形成的层次结构,这个过程无需程序员参与。程序员的任务是决定,在解析的过程中,当由嵌套的元素形成的一个特定序列被识别出时,如何处理它。用以描述这种序列的机制,就叫“元素匹配模板”。
  具体说来,元素和其子元素间,用”/”相隔,如果一些元素前没有”/”则其必为根元素。如例:
<a>         -- 匹配模板 "a"
  <b>       -- 匹配模板 "a/b"
    <c/>    -- 匹配模板 "a/b/c"
    <c/>    -- 匹配模板 "a/b/c"
  </b>
  <b>       -- 匹配模板 "a/b"
    <c/>    -- 匹配模板 "a/b/c"
    <c/>    -- 匹配模板 "a/b/c"
    <c/>    -- 匹配模板 "a/b/c"
  </b>
</a>

  字符”*”表示任意级别,如”*/a”表示任意级别的<a>都可匹配(不包括根元素级的).熟悉XLST的朋友,对这种思路一定不陌生。
  从上面的描述,可知某个元素同时满足多个匹配模板是非常可能的,在这种情况下,与各个模板相关联的处理规则(processing rule)的执行顺序如下:对begin或body方法,按照各个rule的注册顺序的先后,对end方法则是注册顺序的反序。

处理规则(processing rule)

  元素匹配模板用以识别什么时候采取行动,处理规则则用以定义行动的内容。
   从形式上讲,一个处理规则是一个java类,它扩展了org.apache.commons.digester.Rule类。每个处理规则,实现下列的 一个或几个事件处理方法(event method),当相应的模板匹配成功以后,在已定义的某个时刻,这些事件方法会被触发。
  1. begin(),在一个匹配元素被识别出后的“开始”时刻被调用,这个元素的所有属性放在一个数据结构中被传递给begin()
  2. body(),当元素的嵌套内容(如子元素)被识别出时被调用。在解析的过程中,前后的空白被去掉了
  3. end(),匹配元素的“结束”时刻被调用。如果子元素也匹配相关的规则,则这些规则的方法需都执行毕,才能达到该元素的“结束”时刻。
  4. finish(),解析结束时被调用,以提供给各个规则以清理临时数据的机会。

  在设置digester时,通过调用addRule()方法,来注册一个特定的元素匹配模板以及相应的一个Rule类的实例。如上所述,Rule类中的事件处理方法,会在适当的时间被调用。这个机制,允许动态地生成Rule的实现。
  另外,digester也提供了一些处理常见情况的处理规则类。
  1. ObjectCreateRule, 当begin()方法被调用时,这个规则类实例化一个指定的java类,并将其压入栈顶。这个被实例化的类的名字,默认是这个规则类构造函数得到的参数, 也可以通过指定正在处理的xml元素的属性来传递一个新的类的名字。当end()方法被调用 时,栈顶的对象被弹出,Digester中对它的任何引用将 被忽略。
  2. FactoryCreateRule,一个非常有用的ObjectCreateRule的变体。
  3. SetPropertiesRule, 当begin()方法被调用时,digester使用标准的Java Relection API来识别JavaBean的属性设置方法(setter method),这些方法名称中包含属性(property)的名字,这些属性与XML元素的属性(attribute)匹配,于是这些方法被调用并将相 应的属性值(attribute value)传给它们。这些自然的映射可以被重写。建议不要过度使用这项功能,在大多数情况下,使用标准的BeanInfo机制会更好。
  4. SetPropertyRule, 当begin()方法被调用时,digester调用栈顶对象的一个特定的属性设置方法(property setter)并传给它特定的值(property和值分别由两个attribute命名)。这对XML需要遵循一个指定的DTD时比较有用,你可以设置 一个特别的属性(property),虽然在指定DTD没有attribute与其相对应。
  5. SetNextRule, 当end()方法被调用时,digester分析第二栈顶元素,寻找一个特定属性(property)的设置方法(setter method),并接着调用这个方法,以栈顶的元素作参数。这个规则通常用来在两个对象间建立1对多的关系,所用的方法也常被叫做addChild什么 的。
  6. SetTopRule,当end()方法被调用时,digester分析栈 顶元素,寻找一个特定属性(property)的设置方法(setter method),并接着调用这个方法,以第二栈顶的元素作参数。这个规则通常用来在两个对象间建立1对多的关系,所用的方法也常被叫做setParent 什么的。
  7. CallMethodRule,这个规则设置当end()被调用时执行的栈顶对象的自定义方法,通过对这个规则的设置,来指定方法的名字、参数的数量以及定义的参数类型的Java类的名字。实际的参数值,来自激活这个方法的元素的子元素。
  8. CallParamRule,这个规则用来指定CallMethodRule的参数的值的来源,它可以来自一个特定的属性,或子元素的body的内容.
  9. NodeCreateRule,一个特殊的规则,将对象树的一部分转换成一个DOM结点(Node),并压入栈顶。

  对这些标准的规则类,可以创建它们的实例,并调用digester.addRule来注册它们。由于经常使用它们,所以digester定义了一些简便的方法来注册它们。如:
Rule rule = new SetNextRule(digester, "addChild","com.mycompany.mypackage.MyChildClass");
digester.addRule("a/b/c", rule);
可以用下列代码替换
digester.addSetNext("a/b/c", "addChild", "com.mycompany.mypackage.MyChildClass");

对象栈

   对digester技术最普通的应用,是用来动态创建一个由Java对象构成的树结构,各对象的属性以及对象间的关系,基于XML文档的内容来设置 (XML文档就是一棵树)。为实现这种应用,Digester提供了一个对象栈,以供在相关的模板识别后被激活的处理规则操作。此栈的基本操作包括:
  1. clear(),清空栈的内容
  2. peek(),返回对栈顶对象的引用
  3. pop(),将栈顶对象弹出并返回
  4. push(),将一个新的对象压入栈顶

  用栈的原因,就是当识别出一个XML元素的“开始”时,将相关对象生成并压入栈顶,这个对象在处理该元素的子元素的过程中一直在栈中,当所有子元素都处理完后,解析器遇到这个元素的“结束”时,则弹出此对象,并进行相关的处理。
   如何描述对象间的关系呢?将栈顶的对象做为一个参数,传递给第二栈顶(即先于栈顶对象入栈的那个对象,在栈顶对象的下面)的一个方法,就可以简单地建立 起一种“父子关系”,从而可以简单地建立起1:1的关系(第二栈顶对象与栈顶对象之间)和1:N的关系(第二栈顶对象不动,N次压栈顶弹栈顶对象).
  如果取得生成的第一个对象呢?可以让parse()方法返回,或者在调用parse()方法前,先行压入一个对象,在parse()方法结束后弹出这个对象,则其子对象即为我们想要的第一个对象。

日志(logging)


  日志是一个调试Digester规则集的非常重要的工具,它可以记录非常丰富的信息,因它在使用Digester之前有必要了解日志是如何工作的。
   Digester使用Jakarta Commons Logging,这个模块并不是具体的日志实现,而只是一个可设置的接口。可以设置它将各种日志信息传递它自身带的基本记录器,或者传递给其它的更复杂的 日志工具。具体请参考commons logging的文档,或
Jakarta Commons Logging学习笔记
  Digester主要使用两个记录器:
  1. SAX相关的信息,被送往org.apache.commons.digester.Digester.sax记录器,记录了Digester收到的SAX的事件的信息。
  2. 其它的所有信息,都被送往org.apache.commons.digester.Digester记录器,这个记录器在调试Digester时打开而在产品中常将其关闭

  假定用commons logging自带的基本日志工具,并以DEBUG级别记录Digester调试信息以及INFO级别记录SAX事件信息,则对logging的配置文件设置如下:
org.apache.commons.logging.Log=org.apache.commons.logging.impl.SimpleLog org.apache.commons.logging.simplelog.log.org.apache.commons.digester.Digester=debug org.apache.commons.logging.simplelog.log.org.apache.commons.digester.Digester.sax=info

Digester包中的例子

***********Example.xml**********
<address-book>
  <person id="1" category="acquaintance" try="would be ignored">
    <name>Gonzo</name>
    <email type="business">gonzo@muppets.com</email>
    <gender result="the whole tag would be ignored">male</gender>
  </person>
  <person id="2" category="rolemodel">
    <name>Kermit</name>
    <email type="business">kermit@muppets.com</email>
    <email type="home">kermie@acme.com</email>
  </person>
</address-book>**********Person.java************
import java.util.HashMap;
import java.util.Iterator;
public class Person {
  private int id;
  private String category;
  private String name;
  private HashMap emails = new HashMap();
  // 下面的两个方法的名字中set以后的部分,与<person>的属性名字对映。当从xml文件中识别出<person>的属性 时,如果有要求(即调用过addSetProperties方法),Digester会依据这种对映关系自动调用相应的方法。
  public void setId(int id) {
      this.id = id;
  }
  public void setCategory(String category) {
      this.category = category;
  }
  //对name而言,因为其值来自<name>标签的内容而非属性值,需要用addCallMethod指定识别<name>后的要调用此方法(想自动调用也要可以,需要addBeanPropertySetter,参见第下一个例子)。
  public void setName(String name) {
      this.name = name;
  }
  //同name,此时还要一一指定addEmail的参数值的来源。
  public void addEmail(String type, String address) {
      emails.put(type, address);
  }
  public void print() {
      System.out.println("Person #" + id);
      System.out.println("  category=" + category);
      System.out.println("  name=" + name);
      for(Iterator i = emails.keySet().iterator(); i.hasNext(); ) {
          String type = (String) i.next();
          String address = (String) emails.get(type);
          System.out.println("  email (type " + type + ") : " + address);
      }
  }
}
**********AddressBook.java***********
import java.util.LinkedList;
import java.util.Iterator;
public class AddressBook {
    LinkedList people = new LinkedList();
    public void addPerson(Person p) {
        people.addLast(p);
    }
    public void print() {
        System.out.println("Address book has " + people.size() + " entries");

        for(Iterator i = people.iterator(); i.hasNext(); ) {
            Person p = (Person) i.next();
            p.print();
        }
    }
}
************AddressBookDigester*********
import org.apache.commons.digester.Digester;
/**
 * Usage: java Example1 example.xml
 */
public class AddressBookDigester {
    public static void main(String[] args) {
        if (args.length != 1) {
            usage();
            System.exit(-1);
        }
        String filename = args[0];
        // 创建一个Digester实例
        Digester d = new Digester();
        // 创建AddressBook实例,并将其压入栈顶。
        AddressBook book = new AddressBook();
        d.push(book);
        // 增加规则
        addRules(d);
        // 处理输入的xml文件
        try {
            java.io.File srcfile = new java.io.File(filename);
            d.parse(srcfile);
        }
        catch(java.io.IOException ioe) {
            System.out.println("Error reading input file:" + ioe.getMessage());
            System.exit(-1);
        }
        catch(org.xml.sax.SAXException se) {
            System.out.println("Error parsing input file:" + se.getMessage());
            System.exit(-1);
        }
        
        
        // 将解析出的地址数据打印出来
        book.print();
    }
    
    private static void addRules(Digester d) {
        // 当遇到<person>时,创建类Person的一个实例,并将其压入栈顶
        d.addObjectCreate("address-book/person", Person.class);
        
        //  将<person>标签的属性(attribute)与栈顶Person类对象的属性(property)设置方法根据各自的名字进行映射, (例如,将标签属性id与属性设置方法setId进行映射,将标签属性category与属性设置方法setCategory进行映射),然后将属性的值 作参数传递给执行相应的方法。
        // 如果某标签属性没法通过名字找到相应的属性设置方法,则此标签属性被忽略(如example.xml中第一个<person>的try属性)。
        d.addSetProperties("address-book/person");

        // 调用第二栈顶对象(AddressBook实例)的addPerson方法,以栈对象(Person实例)的对象为参数
        d.addSetNext("address-book/person", "addPerson");        
        
        // 当遇到<person>的子元素<name>时,调用栈顶对象(Person实例)的setName方法。
        // 此处addCallMethod方法的第一参数是规则,第二个参数是方法的名字,第三个是参数的数量(为0时,表示只有一个参数,且参数的值是元素的内容)
        d.addCallMethod("address-book/person/name", "setName", 0);
        
        //  当遇到<person>的子元素<email>时,调用栈顶对象(Person实例)的addEmail方法,addEmail 方法有两个参数,取值分别来自<email>的属性type的值和<email>本身的内容。
        // 此处addCallParam方法的第一参数是规则,第二个参数是指明被调用方法(addEmail)参数的序号,第三个是参数为字符串时指属性的名字)
        d.addCallMethod("address-book/person/email", "addEmail", 2);
        d.addCallParam("address-book/person/email", 0, "type");
        d.addCallParam("address-book/person/email", 1);
    }

    private static void usage() {
        System.out.println("Usage: java Example1 example.xml");
    }
}

运行结果如下(运行时可能需要xml-crimson,一个源sun的XML解析器,可到http://xml.apache.org/crimson/下载)
Address book has 2 entries
Person #1
  category=acquaintance
  name=Gonzo
  email (type business) : gonzo@muppets.com
Person #2
  category=rolemodel
  name=Kermit
  email (type business) : kermit@muppets.com
  email (type home) : kermie@acme.com

配置属性

  Digester用来解析应用系统的配置文件,其本身也有很可配置的属性。
属性 描述
classLoader 指 定类装载器(class loader)。ObjectCreateRule 和 FactoryCreateRule两个规则中,需要动态加载一些类(如那些盛放XML解析出来的数据的javaBean等),装载器可以在次指定。如果 不指定,对这此类的加载将会利用线程上下文中的加载器(当useContextClassLoader值为真时)或利用加载Digester的那个加载 器。
errorHandler 指定 SAX ErrorHandler,以在出现此类错误时调用。默认情况下,任何解析错误都会被记入日志,Digest会继续进行解析。
namespaceAware 一个布尔值,为真时对XML文件的解析时会考虑元素的域名空间(如不同的域名空间的同名元素会视为不同的元素)
ruleNamespaceURI 指定后续加入的规则所属的命名空间,如果此值为null,则加入的规则不与任何命名空间相联系。
rules 设定规则模板与XML元素的匹配处理程序。由于这个匹配程序是插件式的,所以匹配工作的完成可以用用户定义的匹配程序未完成。默认情况下,使用Digester提供的匹配器。
useContextClassLoader 一个布尔值,为真时FactoryCreateRule 和 ObjectCreateRule 两个规则中对类的装载将会采用当前线程上下文中指定的加载器。默认情况下,对类的动态加载会利用加载Digester的那个装载器。
validating 一个布尔值,为真时解析器会根据DTD内容对XML文档进行合法性检查,默认值是假,解析器只是检查XML是否格式良好(well formed).

  除了上述属性外,还可以注册一个本地DTD,以供DOCTYPE声明引用。这样的注册告诉XML解析器,当遇到DOCTYPE声明时,应使用刚注册的DTD的内容,而不是DOCTYPE声明中的标识符(identifier)。
   例如,Struect框架控制器中,使用下述的注册,告诉Structs使用一个本地的DTD中的相关内容来处理Structs配置文件,这样可以适用 于那些没有连接到互联网的应用环境,而在连到互联网的环境中可以加快运行速度(因为它避免了通过网络去取相关的资源)。
URL url = new URL("/org/apache/struts/resources/struts-config_1_0.dtd");
digester.register("-//Apache Software Foundation//DTD Struts Configuration 1.0//EN",url.toString());

规则集打包


   通常情况下,一个规则被创建后,接着便注册,然后等在event时被调用,这些规则集很难为其它应用程序直接复用。一个解决方法是将所有规则都放在一个 类中,此由这些规则可以很简单地被装载然后被注册使用。RuleSet接口就是为些而设计,一般是通过扩展RuleSetBase类来开发规则集类。如 例:
public class MyRuleSet extends RuleSetBase {
  public MyRuleSet() {
    this("");
  }
  public MyRuleSet(String prefix) {
    super();
    this.prefix = prefix;
    this.namespaceURI = "http://www.mycompany.com/MyNamespace";
  }
  protected String prefix = null;
  public void addRuleInstances(Digester digester) {
    digester.addObjectCreate(prefix + "foo/bar",
      "com.mycompany.MyFoo");
    digester.addSetProperties(prefix + "foo/bar");
  }
}
可以这样使用这个规则集
Digester digester = new Digester();
... 一些配置Digester ...
digester.addRuleSet(new MyRuleSet("baz/"));

带命名空间的XML解析


  这种情况下,使用Digester的步骤为:
  1. 在Digester初始化部分,指明要考虑命名空间。
    digester.setNamespaceAware(true);

  2. 指明一些规则的命名空间,如
    digester.setRuleNamespaceURI("http://www.mycompany.com/MyNamespace");

  3. 接下来定义一些与此命名空间有关的规则,此时可以省却前缀,如
    digester.addObjectCreate("foo/bar", "com.mycompany.MyFoo");
    digester.addSetProperties("foo/bar");

  4. 对其它命名空间,重复前面的2步

  另外,在指明要digester考虑命名空间之后,在定义匹配模板时,可以将命名空间别名加“:”作为元素名称的一部分使用。这与无命名空间时是一致的。

开发定制的匹配处理过程


  通过实现 org.apache.commons.digester.Rules接口或扩展org.apache.commons.digester.RulesBase类来达到定制匹配过程的目的。
   Digester提供ExtendedBaseRules来扩展了匹配模板的定义,引入了特殊通配字符?和*以及!,提供RegexRules来支持以 正则式的语法定义匹配模板,提供WithDefaultsRulesWrapper来支持默认规则(即其它规则都不匹配时的处理规则)。

一些认识


  通过看说明材料,尤其在学习Digester包中的Catalog例子以后,有一些认识:
  1、由于xml对属性名字的定义要求,与Java中对方法名字的定义要求不一致,导致出现不能自动映射的情况,如year-made标签属性,就不可能有方法setYear-made;
  2、对于根元素,与其子元素建立联系,有几种办法:一种是先生成根元素实例,压入栈,然后解析,将调用方法规则建立联系;另一种是解析的过程中第一个创建它,然后用getRoot的方法得到。
  3、如果某对象类构造都要参数,则此时需要扩展AbstractObjectCreationFactory类为这种对象建立一个Factory,在这个Factory中取得初始化参数值然后再创建一个对象实例。
   4、设有某个标签,要想自动用该标签子元素的内容填充该标签对应的对象的属性,则需要用digester.setRules(new ExtendedBaseRules()),然后addRules(),然后再调用addBeanPropertySetter ("bala/lala/?");进行规则定义,注意此模板中有通配符。
  5、如果对象的属性是整型,则Digester自动将xml文件中字符串值转换为整型。
  6、在指明要digester考虑命名空间之后,如果不会引起歧义,完全可以忽略命名空间的存在,除非你要针对特定的命名空间进行特定的处理。
posted @ 2009-03-06 17:26 小虫旺福 阅读(42) | 评论 (0)编辑 收藏

2009年3月4日 #

一:SQL tuning 类
  1:列举几种表连接方式
  2:不借助第三方工具,怎样查看sql的执行计划
  3:如何使用CBO,CBO与RULE的区别
  4:如何定位重要(消耗资源多)的SQL
  5:如何跟踪某个session的SQL
  6:SQL调整最关注的是什么
  7:说说你对索引的认识(索引的结构、对dml影响、对查询影响、为什么提高查询性能)
  8:使用索引查询一定能提高查询的性能吗?为什么
  9:绑定变量是什么?绑定变量有什么优缺点?
  10:如何稳定(固定)执行计划
  11:和排序相关的内存在8i和9i分别怎样调整,临时表空间的作用是什么
  12:存在表T(a,b,c,d),要根据字段c排序后取第21—30条记录显示,请给出sql

  二:数据库基本概念类

  1:pctused and pctfree 表示什么含义有什么作用
  2:简单描述table / segment / extent / block之间的关系
  3:描述tablespace和datafile之间的关系
  4:本地管理表空间和字典管理表空间的特点,ASSM有什么特点
  5:回滚段的作用是什么
  6:日志的作用是什么
  7:SGA主要有那些部分,主要作用是什么
  8racle系统进程主要有哪些,作用是什么

  三:备份恢复类

  1:备份如何分类
  2:归档是什么含义
  3:如果一个表在2004-08-04 10:30:00 被drop,在有完善的归档和备份的情况下,如何恢复
  4:rman是什么,有何特点
  5:standby的特点
  6:对于一个要求恢复时间比较短的系统(数据库50G,每天归档5G),你如何设计备份策略

  四:系统管理类

  1:对于一个存在系统性能的系统,说出你的诊断处理思路
  2:列举几种诊断IO、CPU、性能状况的方法
  3:对statspack有何认识
  4:如果系统现在需要在一个很大的表上创建一个索引,你会考虑那些因素,如何做以尽量减小对应用的影响
  5:对raid10 和raid5有何认识

  五:综合随意类

  1:你最擅长的是oracle哪部分?
  2:喜欢oracle吗?喜欢上论坛吗?或者偏好oracle的哪一部分?
  3:随意说说你觉得oracle最有意思的部分或者最困难的部分
  4:为何要选择做DBA呢?
 
 
参考解答:

  一:SQL tuning 类

  1:列举几种表连接方式

  hash join/merge join/nest loop(cluster join)/index join

  2:不借助第三方工具,怎样查看sql的执行计划

  set autot on
  explain plan set statement_id = &item_id for &sql;
  select * from table(dbms_xplan.display);
  http://download-west.oracle.com/ ... /b10752/ex_plan.htm

  3:如何使用CBO,CBO与RULE的区别

  在optimizer_mode=choose时,如果表有统计信息(分区表外),优化器将选择CBO,否则选RBO。RBO遵循简单的分级方法学,使用15种级别要点,当接收到查询,优化器将评估使用到的要点数目, 然后选择最佳级别(最少的数量)的执行路径来运行查询。

  CBO尝试找到最低成本的访问数据的方法,为了最大的吞吐量或最快的初始响应时间,计算使用不同 的执行计划的成本,并选择成本最低的一个,关于表的数据内容的统计被用于确定执行计划。

  4:如何定位重要(消耗资源多)的SQL

select sql_text
from v$sql
where disk_reads > 1000 or (executions > 0 and buffer_gets/executions > 30000);

  5:如何跟踪某个session的SQL

exec dbms_system.set_sql_trace_in_session(sid,serial#,&sql_trace);
select sid,serial# from v$session where sid = (select sid from v$mystat where rownum = 1);
exec dbms_system.set_ev(&sid,&serial#,&event_10046,&level_12,'');

  6:SQL调整最关注的是什么

  查看该SQL的response time(db block gets/consistent gets/physical reads/sorts (disk))

  7:说说你对索引的认识(索引的结构、对dml影响、为什么提高查询性能)

  b-tree index/bitmap index/function index/patitional index(local/global) 索引通常能提高select/update/delete的性能,会降低insert的速度,

  8:使用索引查询一定能提高查询的性能吗?为什么

  索引就是为了提高查询性能而存在的, 如果在查询中索引没有提高性能, 只能说是用错了索引,或者讲是场合不同

  9:绑定变量是什么?绑定变量有什么优缺点?

  绑定变量是相对文本变量来讲的,所谓文本变量是指在SQL直接书写查询条件,这样的SQL在不同条件下需要反复解析,绑定变量是指使用变量来代替直接书写条件,查询bind value在运行时传递,然后绑定执行。优点是减少硬解析,降低CPU的争用,节省shared_pool ;缺点是不能使用histogram,sql优化比较困难

  10:如何稳定(固定)执行计划

  query_rewrite_enabled = true
  star_transformation_enabled = true
  optimizer_features_enable = 9.2.0

  创建并使用stored outline

  http://download-west.oracle.com/ ... /outlines.htm#26854

 

11:和排序相关的内存在8i和9i分别怎样调整,临时表空间的作用是什么

  8i中sort_area_size/sort_area_retained_size决定了排序所需要的内存

  如果排序操作不能在sort_area_size中完成,就会用到temp表空间

  9i中如果workarea_size_policy=auto时,

  排序在pga内进行,通常pga_aggregate_target的1/20可以用来进行disk sort;

  如果workarea_size_policy=manual时,排序需要的内存由sort_area_size决定

  在执行order by/group by/distinct/union/create index/index rebuild/minus等操作时,

  如果在pga或sort_area_size中不能完成,排序将在临时表空间进行(disk sort),

  临时表空间主要作用就是完成系统中的disk sort.

  12:存在表T(a,b,c,d),要根据字段c排序后取第21—30条记录显示,请给出sql

  create table t(a number(,b number(,c number(,d number();
  /
  begin
  for i in 1 .. 300 loop
  insert into t values(mod(i,2),i/2,dbms_random.value(1,300),i/4);
  end loop;
  end;
  /
  select * from (select c.*,rownum as rn from (select * from t order by c desc) c) where rn between 21 and 30;
  /
  select * from (select * from test order by c desc) x where rownum < 30
  minus
  select * from (select * from test order by c desc) y where rownum < 20 order by 3 desc

  相比之 minus性能较差

  数据库基本概念类

  1:pctused and pctfree 表示什么含义有什么作用

  pctused与pctfree控制数据块是否出现在freelist中,

  pctfree控制数据块中保留用于update的空间,当数据块中的free space小于pctfree设置的空间时,

  该数据块从freelist中去掉,当块由于dml操作free space大于pct_used设置的空间时,该数据库块将

  被添加在freelist链表中。

  2:简单描述table / segment / extent / block之间的关系

  table创建时,默认创建了一个data segment,

  每个data segment含有min extents指定的extents数,

  每个extent据据表空间的存储参数分配一定数量的blocks

  3:描述tablespace和datafile之间的关系

  一个tablespace可以有一个或多个datafile,每个datafile只能在一个tablespace内,

  table中的数据,通过hash算法分布在tablespace中的各个datafile中,

  tablespace是逻辑上的概念,datafile则在物理上储存了数据库的种种对象。

  4:本地管理表空间和字典管理表空间的特点,ASSM有什么特点

  本地管理表空间(Locally Managed Tablespace简称LMT)

  8i以后出现的一种新的表空间的管理模式,通过位图来管理表空间的空间使用。

  字典管理表空间(Dictionary-Managed Tablespace简称DMT)

  8i以前包括以后都还可以使用的一种表空间管理模式,通过数据字典管理表空间的空间使用。

  动段空间管理(ASSM),

  它首次出现在Oracle920里有了ASSM,链接列表freelist被位图所取代,它是一个二进制的数组,

  能够迅速有效地管理存储扩展和剩余区块(free block),因此能够改善分段存储本质,

  ASSM表空间上创建的段还有另外一个称呼叫Bitmap Managed Segments(BMB 段)。

 

5:回滚段的作用是什么

  事务回滚:当事务修改表中数据的时候,该数据修改前的值(即前影像)会存放在回滚段中,

  当用户回滚事务(ROLLBACK)时,ORACLE将会利用回滚段中的数据前影像来将修改的数据恢复到原来的值。

  事务恢复:当事务正在处理的时候,例程失败,回滚段的信息保存在undo表空间中,

  ORACLE将在下次打开数据库时利用回滚来恢复未提交的数据。

  读一致性:当一个会话正在修改数据时,其他的会话将看不到该会话未提交的修改。

  当一个语句正在执行时,该语句将看不到从该语句开始执行后的未提交的修改(语句级读一致性)

  当ORACLE执行SELECT语句时,ORACLE依照当前的系统改变号(SYSTEM CHANGE NUMBER-SCN)

  来保证任何前于当前SCN的未提交的改变不被该语句处理。可以想象:当一个长时间的查询正在执行时,

  若其他会话改变了该查询要查询的某个数据块,ORACLE将利用回滚段的数据前影像来构造一个读一致性视图。

  6:日志的作用是什么

  记录数据库事务,最大限度地保证数据的一致性与安全

  重做日志文件:含对数据库所做的更改记录,这样万一出现故障可以启用数据恢复,一个数据库至少需要两个重做日志文件

  归档日志文件:是重做日志文件的脱机副本,这些副本可能对于从介质失败中进行恢复很必要。

  7:SGA主要有那些部分,主要作用是什么

  SGA:db_cache/shared_pool/large_pool/java_pool
  db_cache:

  数据库缓存(Block Buffer)对于Oracle数据库的运转和性能起着非常关键的作用,

  它占据Oracle数据库SGA(系统共享内存区)的主要部分。Oracle数据库通过使用LRU

  算法,将最近访问的数据块存放到缓存中,从而优化对磁盘数据的访问.

  shared_pool:

  共享池的大小对于Oracle 性能来说都是很重要的。

  共享池中保存数据字典高速缓冲和完全解析或编译的的PL/SQL 块和SQL 语句及控制结构

  large_pool:

  使用MTS配置时,因为要在SGA中分配UGA来保持用户的会话,就是用Large_pool来保持这个会话内存

  使用RMAN做备份的时候,要使用Large_pool这个内存结构来做磁盘I/O缓存器

  java_pool:

  为java procedure预备的内存区域,如果没有使用java proc,java_pool不是必须的

  8 Oracle系统进程主要有哪些,作用是什么

  数据写进程(dbwr):负责将更改的数据从数据库缓冲区高速缓存写入数据文件
  日志写进程(lgwr):将重做日志缓冲区中的更改写入在线重做日志文件
  系统监控(smon) :检查数据库的一致性如有必要还会在数据库打开时启动数据库的恢复
  进程监控(pmon) :负责在一个Oracle 进程失败时清理资源
  检查点进程(chpt):负责在每当缓冲区高速缓存中的更改永久地记录在数据库中时,更新控制文件和数据文件中的数据库状态信息。
  归档进程(arcn) :在每次日志切换时把已满的日志组进行备份或归档
  作业调度器(cjq) :负责将调度与执行系统中已定义好的job,完成一些预定义的工作.
  恢复进程(reco) :保证分布式事务的一致性,在分布式事务中,要么同时commit,要么同时rollback;

  备份恢复类

  1:备份如何分类

  逻辑备份:exp/imp

  物理备份:

  RMAN备份

  full backup/incremental backup(累积/差异)

  热备份:alter tablespace begin/end backup;

  冷备份:脱机备份(database shutdown)

  2:归档是什么含义

  关于归档日志:Oracle要将填满的在线日志文件组归档时,则要建立归档日志(archived redo log)。

  其对数据库备份和恢复有下列用处:

  数据库后备以及在线和归档日志文件,在操作系统和磁盘故障中可保证全部提交的事物可被恢复。

  在数据库打开和正常系统使用下,如果归档日志是永久保存,在线后备可以进行和使用。

  数据库可运行在两种不垃圾广告式下:

  NOARCHIVELOG方式或ARCHIVELOG 方式数据库在NOARCHIVELOG方式下使用时,不能进行在线日志的归档,如果数据库在ARCHIVELOG方式下运行,可实施在线日志的归档。3:如果一个表在2004-08-04 10:30:00 被drop,在有完善的归档和备份的情况下,如何恢复?

  手工拷贝回所有备份的数据文件

  startup mount;
  sql alter database recover automatic until time '2004-08-04:10:30:00';
  alter database open resetlogs;

 

4:rman是什么,有何特点?

  RMAN(Recovery Manager)是DBA的一个重要工具,用于备份、还原和恢复oracle数据库, RMAN 可以用来备份和恢复数据库文件、归档日志、控制文件、系统参数文件,也可以用来执行完全或不完全的数据库恢复。RMAN有三种不同的用户接口:

  COMMAND LINE方式、GUI 方式(集成在OEM 中的备份管理器)、API 方式(用于集成到第三方的备份软件中)。

  具有如下特点:

  1)功能类似物理备份,但比物理备份强大N倍;
  2)可以压缩空块;
  3)可以在块水平上实现增量;
  4)可以把备份的输出打包成备份集,也可以按固定大小分割备份集;
  5)备份与恢复的过程可以自动管理;
  6)可以使用脚本(存在Recovery catalog 中)
  7)可以做坏块监测

  5:standby的特点

  备用数据库(standby database):ORACLE推出的一种高可用性(HIGH AVAILABLE)数据库方案,

  在主节点与备用节点间通过日志同步来保证数据的同步,备用节点作为主节点的备份

  可以实现快速切换与灾难性恢复,从920开始,还开始支持物理与逻辑备用服务器

  9i中的三种数据保护模式分别是:

  1)、MAXIMIZE PROTECTION :最大数据保护与无数据分歧,LGWR将同时传送到备用节点,

  在主节点事务确认之前,备用节点也必须完全收到日志数据。如果网络不好,引起LGWR不能传送数据,将引起严重的性能问题,导致主节点DOWN机。

  2)、MAXIMIZE AVAILABILITY :无数据丢失模式,允许数据分歧,允许异步传送。

  正常情况下运行在最大保护模式,在主节点与备用节点的网络断开或连接不正常时,自动切换到最大性能模式,

  主节点的操作还是可以继续的。在网络不好的情况下有较大的性能影响。

  3)、MAXIMIZE PERFORMANCE:这种模式应当可以说是从8i继承过来的备用服务器模式,异步传送,

  无数据同步检查,可能丢失数据,但是能获得主节点的最大性能。9i在配置DATA GUARD的时候默认就是MAXIMIZE PERFORMANCE

  6:对于一个要求恢复时间比较短的系统(数据库50G,每天归档5G),你如何设计备份策略

  rman/每月一号 level 0 每周末/周三 level 1 其它每天level 2

 四:系统管理类

  对于一个存在系统性能的系统,说出你的诊断处理思路

  1 做statspack收集系统相关信息

  了解系统大致情况/确定是否存在参数设置不合适的地方/查看top 5 event/查看top sql等

  2 查v$system_event/v$session_event/v$session_wait

  从v$system_event开始,确定需要什么资源(db file sequential read)等

  深入研究v$session_event,确定等待事件涉及的会话

  从v$session_wait确定详细的资源争用情况(p1-p3的值:file_id/block_id/blocks等)

  3 通过v$sql/v$sqltext/v$sqlarea表确定disk_reads、(buffer_gets/executions)值较大的SQL

  2:列举几种诊断IO、CPU、性能状况的方法

  top/vmstat

  statspack

  sql_trace/tkprof

  查v$system_event/v$session_event/v$session_wait

  查v$sqlarea(disk_reads或buffer_gets/executions较大的SQL)

  3:对statspack有何认识

  StapSpack是Oracle公司提供的一个收集数据库运行性能指标的软件包,该软件包从8i起,在9i、10g都有显著的增强 。该软件包的辅助表(存储相关参数与收集的性能指标的表)由最初的25个增长到43个。收集级别参数由原来的3个(0、5、10)增加到5个(0、5、6、7、10)通过分析收集的性能指标,数据库管理员可以详细地了解数据库目前的运行情况,对数据库实例、等待事件、SQL等进行优化调整。利用statspack收集的snapshot,可以统计制作数据库的各种性能指标的统计趋势图表。

  4:如果系统现在需要在一个很大的表上创建一个索引,你会考虑那些因素,如何做以尽量减小对应用的影响

  在系统比较空闲时;nologging选项(如果有dataguard则不可以使用nologging)大的sort_ared_size或pga_aggregate_target较大

  5:对raid1+0 和raid5有何认识

  RAID 10(或称RAID 1+0)与RAID 0+1不同,它是用硬盘驱动器先组成RAID 1阵列,然后在RAID 1阵列之间再组成RAID 0阵列。RAID 10模式同RAID 0+1模式一样具有良好的数据传输性能,但却比RAID 0+1具有更高的可靠性。RAID 10阵列的实际容量为M×n/2,磁盘利用率为50%。RAID 10也需要至少4个硬盘驱动器构成,因而价格昂贵。 RAID 10的可靠性同RAID 1一样,但由于RAID 10硬盘驱动器之间有数据分割,因而数据传输性能优良。RAID 5与RAID 3很相似,不同之处在于RAID 5的奇偶校验信息也同数据一样被分割保存到所有的硬盘驱动器,而不是写入一个指定的硬盘驱动器,从而消除了单个奇偶校验硬盘驱动器的瓶颈问题。RAID 5磁盘阵列的性能比RAID 3有所提高,但仍然需要至少3块硬盘驱动器。其实际容量为M×(n-1),磁盘利用率为(n-1)/n 。

posted @ 2009-03-04 19:16 小虫旺福 阅读(68) | 评论 (0)编辑 收藏

2009年2月27日 #

Iframe跨域访问的问题,困扰了我两三天

1.框架的Iframe 自动适应高度的问题.

2.Iframe框架包含的页面提交到服务器的session 丢失的问题.

 

解决办法.

1. 在iframe包含的页面 加上

<script language="javascript">document.domain=www.域名.com;</script>

2.在iframe 保航的页面服务器(resin)写一个filter 设置一下返回的((HttpServletResponse)response).setHeader("P3P","CP=CAO PSA OUR");

 

这样就可以解决以上两个问题了..

posted @ 2009-02-27 14:37 小虫旺福 阅读(221) | 评论 (0)编辑 收藏

2009年2月20日 #

马上要做信息知识库了,可能会用到这个东东,提交写好,到时候方便使用(最近实在是太忙了!-_- )在ORACLE数据字典视图user_tab_columns 中提供了表的字段详细信息

用如下语句即可得到基本的信息

select column_id, column_name, data_type, data_length, data_precision, data_scale,nullable,data_default from user_tab_columns where table_name = 'Tablename' order by column_id


另外可能有一个需求一直没有想到好的解决方案,希望哪位高手能够提供建议:
我们要根据传来的数据库连接的基本信息,去连接到数据源,然后根据表名,查询出来这张表的结构(上面已经做了,不难),然后在我们的信息库中根据该表结构创建表。并复制数据。到这位置,都没有什么难的,只是方便大家理解。
后面的事情是这样,在查询出来的数据库信息中,需要显示成一个列表,但是其中有部分不是业务信息,而是另一张表的外键,这个时侯,我们要再根据这个外键来查询出来相对应的表的信息。有点像报表。
疑惑的地方在于如果是一对一的,很简单,把这个字段信息做成一个url,先不考虑性能问题,方案是可行的。但是如果是一对多的时候,就会比较麻烦。
posted @ 2009-02-20 17:28 小虫旺福 阅读(290) | 评论 (0)编辑 收藏

2009年1月7日 #

今天在部署应用的时候,发现Tomcat报错:java.lang.OutOfMemoryError: PermGen space,第一感觉就是Tomcat内存分配的太小了。上网Google了一把发现了一堆资料,就不多说了,大家可以自己查。下面主要说我的解决办法。
先说我的机器的环境:
cpu                  双核2.66GHz * 2
内存                8G 
操作系统       Win2003

修改Tomcat\bin\catalina.bat文件。
找到set JAVA_OPTS=%JAVA_OPTS% -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.util.logging.config.file="%CATALINA_BASE%\conf\logging.properties"这句话。在前面加上rem注释掉。
在它下面加入:
set JAVA_OPTS=-server -Xms1024m -Xmx1024m -Xss512k -XX:PermSize=64M -XX:MaxNewSize=256m -XX:MaxPermSize=128m -Djava.awt.headless=true
重新启动Tomcat,正常启动了
posted @ 2009-01-07 11:46 小虫旺福 阅读(274) | 评论 (3)编辑 收藏

2008年12月22日 #

一、避免在循环条件中使用复杂表达式


在不做编译优化的情况下,在循环中,循环条件会被反复计算,如果不使用复杂表达式,而使循环条件值不变的话,程序将会运行的更快。

例子:
import java.util.Vector;
class CEL {
    void method (Vector vector) {
        for (int i = 0; i < vector.size (); i++)  // Violation
            ; // ...
    }
}

更正:
class CEL_fixed {
    void method (Vector vector) {
        int size = vector.size ()
        for (int i = 0; i < size; i++)
            ; // ...
    }
}

二、为'Vectors' 和 'Hashtables'定义初始大小


JVM为Vector扩充大小的时候需要重新创建一个更大的数组,将原原先数组中的内容复制过来,最后,原先的数组再被回收。可见Vector容量的扩大是一个颇费时间的事。
通常,默认的10个元素大小是不够的。你最好能准确的估计你所需要的最佳大小。

例子:
import java.util.Vector;
public class DIC {
    public void addObjects (Object[] o) {
        // if length > 10, Vector needs to expand
        for (int i = 0; i< o.length;i++) {    
            v.add(o);   // capacity before it can add more elements.
        }
    }
    public Vector v = new Vector();  // no initialCapacity.
}

更正:
自己设定初始大小。
    public Vector v = new Vector(20);  
    public Hashtable hash = new Hashtable(10);

参考资料:
Dov Bulka, "Java Performance and Scalability Volume 1: Server-Side Programming
Techniques" Addison Wesley, ISBN: 0-201-70429-3 pp.55 – 57

三、在finally块中关闭Stream


程序中使用到的资源应当被释放,以避免资源泄漏。这最好在finally块中去做。不管程序执行的结果如何,finally块总是会执行的,以确保资源的正确关闭。
         
例子:
import java.io.*;
public class CS {
    public static void main (String args[]) {
        CS cs = new CS ();
        cs.method ();
    }
    public void method () {
        try {
            FileInputStream fis = new FileInputStream ("CS.java");
            int count = 0;
            while (fis.read () != -1)
                count++;
            System.out.println (count);
            fis.close ();
        } catch (FileNotFoundException e1) {
        } catch (IOException e2) {
        }
    }
}
         
更正:
在最后一个catch后添加一个finally块

参考资料:
Peter Haggar: "Practical Java - Programming Language Guide".
Addison Wesley, 2000, pp.77-79

四、使用'System.arraycopy ()'代替通过来循环复制数组


'System.arraycopy ()' 要比通过循环来复制数组快的多。
         
例子:
public class IRB
{
    void method () {
        int[] array1 = new int [100];
        for (int i = 0; i < array1.length; i++) {
            array1 [i] = i;
        }
        int[] array2 = new int [100];
        for (int i = 0; i < array2.length; i++) {
            array2 [i] = array1 [i];                 // Violation
        }
    }
}
         
更正:
public class IRB
{
    void method () {
        int[] array1 = new int [100];
        for (int i = 0; i < array1.length; i++) {
            array1 [i] = i;
        }
        int[] array2 = new int [100];
        System.arraycopy(array1, 0, array2, 0, 100);
    }
}
         
参考资料:
http://www.cs.cmu.edu/~jch/java/speed.html

五、让访问实例内变量的getter/setter方法变成”final”


简单的getter/setter方法应该被置成final,这会告诉编译器,这个方法不会被重载,所以,可以变成”inlined”

例子:
class MAF {
    public void setSize (int size) {
         _size = size;
    }
    private int _size;
}

更正:
class DAF_fixed {
    final public void setSize (int size) {
         _size = size;
    }
    private int _size;
}

参考资料:
Warren N. and Bishop P. (1999), "Java in Practice", p. 4-5
Addison-Wesley, ISBN 0-201-36065-9

六、避免不需要的instanceof操作


如果左边的对象的静态类型等于右边的,instanceof表达式返回永远为true。
         
例子:         
public class UISO {
    public UISO () {}
}
class Dog extends UISO {
    void method (Dog dog, UISO u) {
        Dog d = dog;
        if (d instanceof UISO) // always true.
            System.out.println("Dog is a UISO");
        UISO uiso = u;
        if (uiso instanceof Object) // always true.
            System.out.println("uiso is an Object");
    }
}
         
更正:         
删掉不需要的instanceof操作。
         
class Dog extends UISO {
    void method () {
        Dog d;
        System.out.println ("Dog is an UISO");
        System.out.println ("UISO is an UISO");
    }
}

七、避免不需要的造型操作


所有的类都是直接或者间接继承自Object。同样,所有的子类也都隐含的“等于”其父类。那么,由子类造型至父类的操作就是不必要的了。
例子:
class UNC {
    String _id = "UNC";
}
class Dog extends UNC {
    void method () {
        Dog dog = new Dog ();
        UNC animal = (UNC)dog;  // not necessary.
        Object o = (Object)dog;         // not necessary.
    }
}
         
更正:         
class Dog extends UNC {
    void method () {
        Dog dog = new Dog();
        UNC animal = dog;
        Object o = dog;
    }
}
         
参考资料:
Nigel Warren, Philip Bishop: "Java in Practice - Design Styles and Idioms
for Effective Java".  Addison-Wesley, 1999. pp.22-23

八、如果只是查找单个字符的话,用charAt()代替startsWith()


用一个字符作为参数调用startsWith()也会工作的很好,但从性能角度上来看,调用用String API无疑是错误的!
         
例子:
public class PCTS {
    private void method(String s) {
        if (s.startsWith("a")) { // violation
            // ...
        }
    }
}
         
更正         
将'startsWith()' 替换成'charAt()'.
public class PCTS {
    private void method(String s) {
        if ('a' == s.charAt(0)) {
            // ...
        }
    }
}
         
参考资料:
Dov Bulka, "Java Performance and Scalability Volume 1: Server-Side Programming
Techniques"  Addison Wesley, ISBN: 0-201-70429-3

九、使用移位操作来代替'a / b'操作


"/"是一个很“昂贵”的操作,使用移位操作将会更快更有效。

例子:
public class SDIV {
    public static final int NUM = 16;
    public void calculate(int a) {
        int div = a / 4;            // should be replaced with "a >> 2".
        int div2 = a / 8;         // should be replaced with "a >> 3".
        int temp = a / 3;
    }
}

更正:
public class SDIV {
    public static final int NUM = 16;
    public void calculate(int a) {
        int div = a >> 2;  
        int div2 = a >> 3;
        int temp = a / 3;       // 不能转换成位移操作
    }
}

十、使用移位操作代替'a * b'


同上。
[i]但我个人认为,除非是在一个非常大的循环内,性能非常重要,而且你很清楚你自己在做什么,方可使用这种方法。否则提高性能所带来的程序晚读性的降低将是不合算的。

例子:
public class SMUL {
    public void calculate(int a) {
        int mul = a * 4;            // should be replaced with "a << 2".
        int mul2 = 8 * a;         // should be replaced with "a << 3".
        int temp = a * 3;
    }
}

更正:
package OPT;
public class SMUL {
    public void calculate(int a) {
        int mul = a << 2;  
        int mul2 = a << 3;
        int temp = a * 3;       // 不能转换
    }
}

十一、在字符串相加的时候,使用 ' ' 代替 " ",如果该字符串只有一个字符的话



例子:
public class STR {
    public void method(String s) {
        String string = s + "d"  // violation.
        string = "abc" + "d"      // violation.
    }
}

更正:
将一个字符的字符串替换成' '
public class STR {
    public void method(String s) {
        String string = s + 'd'
        string = "abc" + 'd'   
    }
}

十二、不要在循环中调用synchronized(同步)方法


方法的同步需要消耗相当大的资料,在一个循环中调用它绝对不是一个好主意。

例子:
import java.util.Vector;
public class SYN {
    public synchronized void method (Object o) {
    }
    private void test () {
        for (int i = 0; i < vector.size(); i++) {
            method (vector.elementAt(i));    // violation
        }
    }
    private Vector vector = new Vector (5, 5);
}

更正:
不要在循环体中调用同步方法,如果必须同步的话,推荐以下方式:
import java.util.Vector;
public class SYN {
    public void method (Object o) {
    }
private void test () {
    synchronized{//在一个同步块中执行非同步方法
            for (int i = 0; i < vector.size(); i++) {
                method (vector.elementAt(i));   
            }
        }
    }
    private Vector vector = new Vector (5, 5);
}

十三、将try/catch块移出循环


把try/catch块放入循环体内,会极大的影响性能,如果编译JIT被关闭或者你所使用的是一个不带JIT的JVM,性能会将下降21%之多!
         
例子:         
import java.io.FileInputStream;
public class TRY {
    void method (FileInputStream fis) {
        for (int i = 0; i < size; i++) {
            try {                                      // violation
                _sum += fis.read();
            } catch (Exception e) {}
        }
    }
    private int _sum;
}
         
更正:         
将try/catch块移出循环         
    void method (FileInputStream fis) {
        try {
            for (int i = 0; i < size; i++) {
                _sum += fis.read();
            }
        } catch (Exception e) {}
    }
         
参考资料:
Peter Haggar: "Practical Java - Programming Language Guide".
Addison Wesley, 2000, pp.81 – 83

十四、对于boolean值,避免不必要的等式判断


将一个boolean值与一个true比较是一个恒等操作(直接返回该boolean变量的值). 移走对于boolean的不必要操作至少会带来2个好处:
1)代码执行的更快 (生成的字节码少了5个字节);
2)代码也会更加干净 。

例子:
public class UEQ
{
    boolean method (String string) {
        return string.endsWith ("a") == true;   // Violation
    }
}

更正:
class UEQ_fixed
{
    boolean method (String string) {
        return string.endsWith ("a");
    }
}

十五、对于常量字符串,用'String' 代替 'StringBuffer'


常量字符串并不需要动态改变长度。
例子:
public class USC {
    String method () {
        StringBuffer s = new StringBuffer ("Hello");
        String t = s + "World!";
        return t;
    }
}

更正:
把StringBuffer换成String,如果确定这个String不会再变的话,这将会减少运行开销提高性能。

十六、用'StringTokenizer' 代替 'indexOf()' 和'substring()'


字符串的分析在很多应用中都是常见的。使用indexOf()和substring()来分析字符串容易导致StringIndexOutOfBoundsException。而使用StringTokenizer类来分析字符串则会容易一些,效率也会高一些。

例子:
public class UST {
    void parseString(String string) {
        int index = 0;
        while ((index = string.indexOf(".", index)) != -1) {
            System.out.println (string.substring(index, string.length()));
        }
    }
}

参考资料:
Graig Larman, Rhett Guthrie: "Java 2 Performance and Idiom Guide"
Prentice Hall PTR, ISBN: 0-13-014260-3 pp. 282 – 283

十七、使用条件操作符替代"if (cond) return; else return;" 结构


条件操作符更加的简捷
例子:
public class IF {
    public int method(boolean isDone) {
        if (isDone) {
            return 0;
        } else {
            return 10;
        }
    }
}

更正:
public class IF {
    public int method(boolean isDone) {
        return (isDone ? 0 : 10);
    }
}

十八、使用条件操作符代替"if (cond) a = b; else a = c;" 结构


例子:
public class IFAS {
    void method(boolean isTrue) {
        if (isTrue) {
            _value = 0;
        } else {
            _value = 1;
        }
    }
    private int _value = 0;
}

更正:
public class IFAS {
    void method(boolean isTrue) {
        _value = (isTrue ? 0 : 1);       // compact expression.
    }
    private int _value = 0;
}

十九、不要在循环体中实例化变量


在循环体中实例化临时变量将会增加内存消耗

例子:         
import java.util.Vector;
public class LOOP {
    void method (Vector v) {
        for (int i=0;i < v.size();i++) {
            Object o = new Object();
            o = v.elementAt(i);
        }
    }
}
         
更正:         
在循环体外定义变量,并反复使用         
import java.util.Vector;
public class LOOP {
    void method (Vector v) {
        Object o;
        for (int i=0;i<v.size();i++) {
            o = v.elementAt(i);
        }
    }
}

二十、确定 StringBuffer的容量


StringBuffer的构造器会创建一个默认大小(通常是16)的字符数组。在使用中,如果超出这个大小,就会重新分配内存,创建一个更大的数组,并将原先的数组复制过来,再丢弃旧的数组。在大多数情况下,你可以在创建 StringBuffer的时候指定大小,这样就避免了在容量不够的时候自动增长,以提高性能。

例子:         
public class RSBC {
    void method () {
        StringBuffer buffer = new StringBuffer(); // violation
        buffer.append ("hello");
    }
}
         
更正:         
为StringBuffer提供寝大小。         
public class RSBC {
    void method () {
        StringBuffer buffer = new StringBuffer(MAX);
        buffer.append ("hello");
    }
    private final int MAX = 100;
}
         
参考资料:
Dov Bulka, "Java Performance and Scalability Volume 1: Server-Side Programming
Techniques" Addison Wesley, ISBN: 0-201-70429-3 p.30 – 31

二十一、尽可能的使用栈变量


如果一个变量需要经常访问,那么你就需要考虑这个变量的作用域了。static? local?还是实例变量?访问静态变量和实例变量将会比访问局部变量多耗费2-3个时钟周期。
         
例子:
public class USV {
    void getSum (int[] values) {
        for (int i=0; i < value.length; i++) {
            _sum += value[i];           // violation.
        }
    }
    void getSum2 (int[] values) {
        for (int i=0; i < value.length; i++) {
            _staticSum += value[i];
        }
    }
    private int _sum;
    private static int _staticSum;
}     
         
更正:         
如果可能,请使用局部变量作为你经常访问的变量。
你可以按下面的方法来修改getSum()方法:         
void getSum (int[] values) {
    int sum = _sum;  // temporary local variable.
    for (int i=0; i < value.length; i++) {
        sum += value[i];
    }
    _sum = sum;
}
         
参考资料:         
Peter Haggar: "Practical Java - Programming Language Guide".
Addison Wesley, 2000, pp.122 – 125

二十二、不要总是使用取反操作符(!)


取反操作符(!)降低程序的可读性,所以不要总是使用。

例子:
public class DUN {
    boolean method (boolean a, boolean b) {
        if (!a)
            return !a;
        else
            return !b;
    }
}

更正:
如果可能不要使用取反操作符(!)

二十三、与一个接口 进行instanceof操作


基于接口的设计通常是件好事,因为它允许有不同的实现,而又保持灵活。只要可能,对一个对象进行instanceof操作,以判断它是否某一接口要比是否某一个类要快。

例子:
public class INSOF {
    private void method (Object o) {
        if (o instanceof InterfaceBase) { }  // better
        if (o instanceof ClassBase) { }   // worse.
    }
}

class ClassBase {}
interface InterfaceBase {}
posted @ 2008-12-22 12:05 小虫旺福 阅读(32) | 评论 (0)编辑 收藏

1、单独备份一个或多个用户:
D:>exp scott/tiger file=导出文件
D:>exp system/manager owner=(用户1,用户2,…,用户n) file=导出文件

2、单独备份一个或多个表:
D:>exp 用户/密码 tables=表
D:>exp 用户/密码 tables=(表1,…,表2)
D:>exp system/manager tables=(用户.表)
D:>exp system/manager tables=(用户1.表1,用户2.表2)

3、导入指定表
D:>exp scott/tiger file=a.dmp
D:>imp test/test fromuser=scott tables=emp file=a.dmp
D:>imp test/test tables=dept file=a.dmp
(说明:如果导出用户没有DBA权限,则导入用户可以不用指定fromuser、touser参数如果导出用户拥有DBA权限,则导入用户也必须拥有DBA权限)

4、给表、列加注释
SQL>comment on table 表 is '表注释';
注释已创建。
SQL>comment on column 表.列 is '列注释';
注释已创建。
SQL> select * from user_tab_comments where comments is not null;
SQL> select * from user_col_comments where comments is not null;

5、查看当前用户下有什么对象(表、视图、同义词、快照)
SQL> select * from tab;
查看表结构
SQL> describe 表名
简写以上命令
SQL> desc 表名

6、
DDL、数据定义语言:create、alter、drop、truncate(创建、修改结构、删除、截断)(其他:rename)
DML、数据操纵语言:insert、delete、select、update(增、删、查、改)
DCL、数据控制语言:grant、revoke(授权、回收)、set role
事务控制:commit、rollback、savepoint(其他:lock table、set constraint(s)、set transaction)
审计控制:audit、noaudit
系统控制:alter system
会话控制:alter session
其他语句:comment(添加注释)、explain plan、analyze(收集统计)、validate、call

7、
1)、查看当前所有对象
SQL> select * from tab;

2)、建一个和a表结构一样的空表
SQL> create table b as select * from a where 1=2;
SQL> create table b(b1,b2,b3) as select a1,a2,a3 from a where 1=2;

3)、察看数据库的大小,和空间使用情况
SQL> col tablespace format a20
SQL> select b.file_id 文件ID,
b.tablespace_name 表空间,
b.file_name 物理文件名,
b.bytes 总字节数,
(b.bytes-sum(nvl(a.bytes,0))) 已使用,
sum(nvl(a.bytes,0)) 剩余,
sum(nvl(a.bytes,0))/(b.bytes)*100 剩余百分比
from dba_free_space a,dba_data_files b
where a.file_id=b.file_id
group by b.tablespace_name,b.file_name,b.file_id,b.bytes
order by b.tablespace_name
/
dba_free_space --表空间剩余空间状况
dba_data_files --数据文件空间占用情况

4)、查看现有回滚段及其状态
SQL> col segment format a30
SQL> SELECT SEGMENT_NAME,OWNER,TABLESPACE_NAME,SEGMENT_ID,FILE_ID,STATUS FROM DBA_ROLLBACK_SEGS;

5)、查看数据文件放置的路径
SQL> col file_name format a50
SQL> select tablespace_name,file_id,bytes/1024/1024,file_name from dba_data_files order by file_id;

6)、显示当前连接用户
SQL> show user

7)、把SQL*Plus当计算器
SQL> select 100*20 from dual;

8)、连接字符串
SQL> select 列1||列2 from 表1;
SQL> select concat(列1,列2) from 表1;

9)、查询当前日期
SQL> select to_char(sysdate,'yyyy-mm-dd,hh24:mi:ss') from dual;

10)、用户间复制数据
SQL> copy from user1 to user2 create table2 using select * from table1;

11)、视图中不能使用order by,但可用group by代替来达到排序目的
SQL> create view a as select b1,b2 from b group by b1,b2;

12)、通过授权的方式来创建用户
SQL> grant connect,resource to test identified by test;

13)、备份
create table yhda_bak as select * from yhda;

14)、提出相同的记录
select sid,count(*) from yhda a group by sid having count(*)>1

15)、select的函数
ORDER BY – 按照指定列排序返回结果的子句
DISTINCT – 只返回结果集合内唯一行的关键词
COUNT -- 返回匹配查询的数据行总数数值的函数
AVG – 该函数返回指定列的平均值
SUM –该函数把指定的列中的数字加起来
MIN – 该函数返回列中最小的非NULL值
MAX –该函数返回列中的最大值
GROUP BY – 按列汇集查询函数结果的子句

8.Oracle数据直接导出到文本文件的方法
利用Oracle中的Spool缓冲池技术可以实现Oracle数据导出到文本文件。
1)、在Oracle PL/SQL中输入缓冲开始命令,并指定输出的文件名:
spool d:output.txt

2)、在命令行中随便输入你的SQL查询:
select mobile from customer;
select mobile from client;
……

3)、在命令行中输入缓冲结果命令:
spool off;
则系统将缓冲池中的结果都输出到"output.txt"文件中。
以TAB键分隔
posted @ 2008-12-22 11:56 小虫旺福 阅读(38) | 评论 (0)编辑 收藏

2008年12月9日 #

1. 如何让选中的一行记录高亮显示?
http://topic.csdn.net/t/20050105/09/3699823.html
2. 如何在下拉列表框里选择一个值后跳出新窗口?
http://topic.csdn.net/t/20050107/15/3707444.html
3. 如何在JSP中启动execl?
http://community.csdn.net/Expert/TopicView1.asp?id=4909154
http://community.csdn.net/Expert/TopicView1.asp?id=4685297
4. 两级联动菜单
http://topic.csdn.net/t/20040730/16/3227437.html
5. java中如何把一个目录下的文件移到另一个指定的目录?
http://topic.csdn.net/t/20050112/13/3719237.html
6. 如何制作表格线?
http://community.csdn.net/Expert/TopicView1.asp?id=5130862
7. jsp如判别一个字符在A到Z之间?
http://topic.csdn.net/t/20050113/08/3721286.html
8. 得到一浮点数小数点后4位,如何写以函数截取为两位
http://topic.csdn.net/t/20050117/14/3731712.html
9. 整型转字符?
http://topic.csdn.net/t/20030526/22/1837632.html
10. 显示数据库的记录,点击哪个标题栏,就按照哪个标题排序
http://topic.csdn.net/t/20041226/15/3677011.html
11. 制作两个按钮
??
12. 用什么sql语句将数据库中的一条记录,复制为两条?
http://topic.csdn.net/t/20050120/17/3741746.html
13. 有兩個按鈕A,B,其中A按下去,A就不可以再按,另外B按下去,A可以再按..請問如何用javascript控制.?
http://topic.csdn.net/t/20050120/17/3741568.html
14. 请问jsp中的数据库的连接方式
http://topic.csdn.net/t/20030107/11/1334377.html
15. 在jsp中,怎么实现按回车就可提交表单?
http://topic.csdn.net/t/20050121/11/3743133.html
16. 在JSP中如何传递数组?
http://topic.csdn.net/t/20030624/17/1952227.html
17. 如何按地址取图片?
http://community.csdn.net/Expert/TopicView1.asp?id=4894525
http://community.csdn.net/Expert/TopicView1.asp?id=4990451
18. JSP中如何上传图片到数据库字段?
http://community.csdn.net/Expert/TopicView1.asp?id=4923127
19. 页面自动刷新?
http://topic.csdn.net/t/20040430/16/3025697.html
20. 表单自动提交?
http://community.csdn.net/Expert/TopicView1.asp?id=4681334
21. 如何从JSP传数据的到JAVABEAN里?
这个不就是参数传递么??
22. weblogic 数据池连接? 数据源 JNDI名字 mysource
http://topic.csdn.net/t/20040915/22/3376617.html
23. 三级联动菜单?
http://blog.csdn.net/overmind/archive/2005/10/27/517856.aspx
24. 在JSP中如何调用浏览器中的"另存为"功能?
http://topic.csdn.net/t/20050509/09/3990931.html
25. 网页全屏显示
http://community.csdn.net/Expert/TopicView1.asp?id=5057245
26. 求两个日期相隔了多少天:输入时间格式为(yyyy-mm-dd)
http://topic.csdn.net/t/20050516/10/4009546.html
27. 上传文件对话框
http://community.csdn.net/Expert/TopicView1.asp?id=4961980
28. 分页测试
http://community.csdn.net/Expert/TopicView1.asp?id=4925123
29. 下载文件
http://community.csdn.net/Expert/TopicView1.asp?id=5019146
30. 简单汉字判断
http://blog.csdn.net/duanxd/archive/2005/05/19/376481.aspx
31. 可否将JSP的变量或者bean传递给JAVASCRIPT使用?
http://topic.csdn.net/t/20050520/14/4022667.html
32. 怎么把一种格式(如yyyy-mm-dd)的日期变量转换成另外一种格式(如dd-mm-yyyy)的日期变量!
http://topic.csdn.net/t/20050602/21/4055209.html
33. 如何实现在页面上添加一行输入对话框
??
34. 如何制作验证码图片?
http://community.csdn.net/Expert/TopicView1.asp?id=4857455
35. 图片缩小放大功能
http://topic.csdn.net/t/20041227/09/3678138.html
36. 如何点击输入框弹出日期选择?
http://community.csdn.net/Expert/TopicView1.asp?id=5020494
http://www.dynarch.com/projects/calendar/
37. 如何在图片上传前查看自己要上传的图片?
http://community.csdn.net/Expert/TopicView1.asp?id=4825282
38. 如何在图片排列的页面上选中一个图片,然后把它删掉?
http://community.csdn.net/Expert/TopicView1.asp?id=5162107
39. 显示某目录下的所有文件
http://community.csdn.net/Expert/TopicView1.asp?id=5056503
40. 如何把复选框中选中的值直接显示在输入文本框中?
http://community.csdn.net/Expert/TopicView1.asp?id=5004830
41. 如何选择路径下的文件直接显示文件内容?
http://community.csdn.net/Expert/TopicView1.asp?id=5194181
http://community.csdn.net/Expert/TopicView1.asp?id=5121413
42. 如何制作进度条?
http://topic.csdn.net/t/20051120/03/4405364.html
43. 如何对较长字符省略显示?
http://community.csdn.net/Expert/TopicView1.asp?id=5124078
44. 如何制作日历?
这个太多了
45. 点击文本弹出一个选择框,选中值后返回并显示
http://community.csdn.net/Expert/TopicView1.asp?id=4979197
http://community.csdn.net/Expert/TopicView1.asp?id=4988006
46. 如何关闭框架页面回到没框架的页面?
http://community.csdn.net/Expert/TopicView1.asp?id=4970057
47. 如何选中多条记录一次性删除?
http://community.csdn.net/Expert/TopicView1.asp?id=4762839
48. 如何自动获取页面文件名?
http://community.csdn.net/Expert/TopicView1.asp?id=4945500
49. 如何在JSP中调用ActiveX控件?
http://community.csdn.net/Expert/TopicView1.asp?id=4919689
50. 如何使用SmartUpload实现文件上传?
http://community.csdn.net/Expert/TopicView1.asp?id=4911791
51. 如何使用iReport和Jasperreport开发报表?
http://community.csdn.net/Expert/TopicView1.asp?id=5038328
52. 如何使用iText生成PDF?
http://www.lowagie.com/iText/tutorial/ch07.html#htmlparsing
http://java.ccidnet.com/art/3565/20050309/480327_1.html
53. 如何制作图片水印?
http://community.csdn.net/Expert/TopicView1.asp?id=5212770
http://community.csdn.net/Expert/TopicView1.asp?id=4885889
54. 如何在页面中屏蔽键盘功能键?
http://community.csdn.net/Expert/TopicView1.asp?id=4356360
55. 如何禁止用户复制网页内容?
http://community.csdn.net/Expert/TopicView1.asp?id=4356360
56. 如何实现不在地址拦中显示当前URL?
http://community.csdn.net/Expert/TopicView1.asp?id=4678351
http://community.csdn.net/Expert/TopicView1.asp?id=4863808
57. 如何获取用户的真实IP地址?
http://community.csdn.net/Expert/TopicView1.asp?id=4718686
58. 如何获取用户浏览器信息?
http://community.csdn.net/Expert/TopicView1.asp?id=4987045
http://community.csdn.net/Expert/TopicView1.asp?id=4898974
59. 如何获取当前绝对路径?
http://community.csdn.net/Expert/TopicView1.asp?id=5157921
http://community.csdn.net/Expert/TopicView1.asp?id=5178848
60. 如何将HTML文件转换成XML文件?
http://community.csdn.net/Expert/TopicView1.asp?id=4542984
61. 如何结合XML和XSL输出HTML页面?
http://community.csdn.net/Expert/TopicView1.asp?id=4355891
62. 如何制作动态树型菜单制作?
http://www.blogjava.net/rickhunter/articles/59742.html
http://community.csdn.net/Expert/TopicView1.asp?id=4966014
63. 如何制作类似QQ的短消息提示?
http://community.csdn.net/Expert/TopicView1.asp?id=4702037
http://community.csdn.net/Expert/TopicView1.asp?id=5087584
64. 如何用jfreechat制作拄、饼、曲线图型?
http://www.inspiresky.com/Article/ShowArticle.asp?ArticleID=731
65. 文本框怎么只容许输入数字?
http://community.csdn.net/Expert/TopicView1.asp?id=4927727
66. 如何打开Word和Execl文件?
http://community.csdn.net/Expert/TopicView1.asp?id=5194181
http://community.csdn.net/Expert/TopicView1.asp?id=4685297
67. 如何生成Word 和 Excel文档?
http://sourceforge.net/project/showfiles.php?group_id=15255&release_id=167948
68. JSP如何读取Word内容?
http://topic.csdn.net/t/20030217/13/1435281.html
posted @ 2008-12-09 18:35 小虫旺福 阅读(91) | 评论 (0)编辑 收藏

仅列出标题  下一页