发布新日志

  • (转)Java学习从入门到精通

    2008-09-19 13:13:26

    Java Learning Path (一)、工具篇 
    一、
     JDK (Java Development Kit) 

    JDK
    是整个
    Java的核心,包括了Java运行环境(Java Runtime Envirnment),一堆Java工具和Java基础的类库(rt.jar)。不论什么Java应用服务器实质都是内置了某个版本的JDK。因此掌握JDK是学好Java的第一步。最主流的JDKSun公司发布的JDK,除了Sun之外,还有很多公司和组织都开发了自己的JDK,例如IBM公司开发的JDKBEA公司的Jrocket,还有GNU组织开发的 JDK等等。其中IBMJDK包含的JVMJava Virtual Machine)运行效率要比Sun JDK包含的JVM高出许多。而专门运行在x86平台的Jrocket在服务端运行效率也要比Sun JDK好很多。但不管怎么说,我们还是需要先把Sun JDK掌握好。 

    1
     JDK的下载和安装
     
    JDK
    又叫做J2SEJava2 SDK Standard Edition),可以从SunJava网站上下载到,http: //java.sun.com/j2se/downloads.html JDK当前最新的版本是J2SDK1.4.2,建议下载该版本的JDK,下载页面在这里:http://java.sun.com/j2se/1.4.2/download.html
     

    下载好的JDK是一个可执行安装程序,默认安装完毕后会在C:\Program Files\Java\目录下安装一套JRE(供浏览器来使用),在C:\j2sdk1.4.2下安装一套JDK(也包括一套JRE)。然后我们需要在环境变量PATH的最前面增加java的路径C:\ j2sdk1.4.2\bin。这样JDK就安装好了。
     

    2
     JDK的命令工具
     
    JDK
    的最重要命令行工具:
     
    java
     启动JVM执行
    class 
    javac
     Java编译器
     
    jar
     Java打包工具
     
    javadoc
     Java文档生成器
     
    这些命令行必须要非常非常熟悉,对于每个参数都要很精通才行。对于这些命令的
    学习JDK Documentation上有详细的文档。 


    二、
     JDK Documentation 

    Documentation
    JDK的下载页面也有下载连接,建议同时下载DocumentationDocumentation是最最重要的编程手册,涵盖了整个Java所有方面的内容的描述。可以这样说,学习Java编程,大部分时间都是花在看这个Documentation上面的。我是随身携带的,写Java代码的时候,随时查看,须臾不离手。
     


    三、 应用服务器
    (App Server) 

    App Server
    是运行Java企业组件的平台,构成了应用软件的主要运行环境。当前主流的App ServerBEA公司的 Weblogic ServerIBM公司的Websphere以及免费的Jboss,选择其中一个进行学习就可以了,个人推荐Weblogic,因为它的体系结构更加干净,开发和部署更加方便,是Java企业软件开发人员首选的开发平台。下面简要介绍几种常用的App Server
     

    1
     Tomcat 
    Tomcat
    严格意义上并不是一个真正的App Server,它只是一个可以支持运行Serlvet/JSPWeb容器,不过Tomcat也扩展了一些App Server的功能,如JNDI
    数据库连接池,用户事务处理等等。Tomcat被非常广泛的应用在中小规模的Java Web应用中,因此本文做一点下载、安装和配置Tomcat的介绍: 

    Tomcat
    Apache组织下Jakarta项目下的一个子项目,它的主网站是:http: //jakarta.apache.org/tomcat/ Tomcat最新版本是Tomcat4.1.27,软件下载的连接是:http: //www.apache.org/dist/jakarta/tomcat-4/binaries/ 
     

    下载Tomcat既可以直接下载zip包,也可以下载exe安装包(个人建议zip更干净些),不管哪种情况,下载完毕安装好以后(zip直接解压缩就可以了)。需要设置两个环境变量:
     

    JAVA_HOME=C:\j2sdk1.4.2 
    CATALINA_HOME=D:\tomcat4 (
    你的Tomcat安装目录


    这样就安装好了,启动Tomcat运行CATALINA_HOME\bin\startup.bat,关闭Tomcat运行 shutdown.bat脚本。Tomcat启动以后,默认使用8080端口,因此可以用浏览器访问http://localhost:8080
    测试 Tomcat是否正常启动。 

    Tomcat
    提供了两个Web界面的管理工具,URL分别是:
     
    http://localhost:8080/admin/index.jsp 
    http://localhost:8080/manager/html 
    在启用这两个管理工具之前,先需要手工配置一下管理员用户和口令。用一个文本工具打开CATALINA_HOME\conf\tomcat-users.xml这个文件,加入如下几行:
     

    <role rolename="manager"/> 
    <role rolename="admin"/> 
    <user username="robbin" password="12345678" roles="admin,manager,tomcat"/> 

    这样用户“robbin”就具备了超级管理员权限。重新启动Tomcat以后,你就可以使用该用户来登陆如上的两个管理工具,通过Web方式进行Tomcat的配置和管理了。
     

    2
     BEA Weblogic 
    Weblogic
    可以到BEA的网站上免费注册之后下载到最新的Weblogic8.1企业版,License可以免费使用1年时间,其实这已经完全足够了。Weblogic的下载连接:http://commerce.bea.com/index.jspWeblogic的在线文档: http://edocs.bea.com/ 
     

    3
     IBM Webshpere 
    Websphere
    同样可以下载到免费的试用版本,到IBMdeveloperWorks网站可以看到Websphere试用产品的下载和相关的Websphere的资料,developerWorks中文网站的连接是:http://www- 900.ibm.com/developerWorks/cn/wsdd/ Websphere的下载连接:http: //www7b.software.ibm.com/wsdd/downloads/WASsupport.html 
     

    4
     Jboss 
    Jboss
    是免费开源的App Server,可以免费的从Jboss网站下载:http: //www.jboss.org/index.html,然而Jboss的文档是不免费,需要花钱购买,所以为我们学习Jboss设置了一定的障碍。在 Jdon上有几篇不错的Jboss配置文档,可以用来参考:
    http://www.jdon.com/idea.html 


    四、 Java应用的运行环境
     

    Java
    的应用可以简单分为以下几个方面:
     

    1
     Java的桌面应用
     
    桌面应用一般仅仅需要JRE的支持就足够了。
     

    2
     Java Web应用
     
    Java
    Web应用至少需要安装JDK和一个web容器(例如Tomcat),以及一个多用户数据库,Web应用至少分为三层:
     
    Browser
    层:浏览器显示用户页面
     
    Web
    层:运行
    Servlet/JSP 
    DB
    层:后端数据库,向Java程序提供数据访问服务
     

    3
     Java企业级应用
     
    企业级应用比较复杂,可以扩展到n层,最简单情况会分为4层:
     
    Browser
    层:浏览器显示用户页面
     
    Client
    层:Java客户端图形程序(或者嵌入式设备的程序)直接和Web层或者EJB层交互
     
    Web
    层:运行
    Servlet/JSP 
    EJB
    层:运行EJB,完成业务逻辑运算
     
    DB
    层:后端数据库,向Java程序提供数据访问服务
     

    4
     Java嵌入式应用
     
    Java
    嵌入式应用是一个方兴未艾的领域,从事嵌入式开发,需要从Sun下载J2ME开发包,J2ME包含了嵌入式设备专用虚拟机KVM,和普通的JDK中包含的JVM有所不同。另外还需要到特定的嵌入式厂商那里下载模拟器。
     


    Java Learning Path
    (二)、书籍篇
     

    学习一门新的知识,不可能指望只看一本,或者两本书就能够完全掌握。需要有一个循序渐进的阅读过程。我推荐Oreilly出版的Java系列书籍。
     

    在这里我只想补充一点看法,很多人学习Java是从《Thinking in Java》这本书入手的,但是我认为这本书是不适合初学者的。我认为正确的使用这本书的方法应该是作为辅助的读物。《Thinking in Java》并不是在完整的介绍Java的整个体系,而是一种跳跃式的写作方法,是一种类似tips的方法来对Java很多知识点进行了深入的分析和解释。
     

    对于初学者来说,最好是找一本Java入门的书籍,但是比较完整的循序的介绍Java的语法,面向对象的特性,核心类库等等,在看这本书的同时,可以同步来看《Thinking in Java》,来加深对Java的理解和原理的运用,同时又可以完整的了解Java的整个体系。
     

    对于Java的入门书籍,蔡学镛推荐的是Oreilly的《Exploring Java, 2nd Edition 或者《Java in a Nutshell,2nd Edition(针对C++背景)》,我并没有看过这两本书。其实我觉得电子工业出版社的《Java 2编程详解》或者《Java 2从入门到精通》就很不错。
     

    在所有的Java书籍当中,其实最最有用的,并不是O'reilly Java Serials,真正最最有用处是JDK Documentation!几乎你想获得的所有的知识在Documentation里面全部都有,其中最主要的部分当然是Java基础类库的API文档,是按照package来组织的,对于每一个class都有详细的解释,它的继承关系,是否实现了某个接口,通常用在哪些场合,还可以查到它所有的 public的属性和方法,每个属性的解释,意义,每个方法的用途,调用的参数,参数的意义,返回值的类型,以及方法可能抛出的异常等等。可以这样来说,所有关于Java编程方面的书籍其实都不过是在用比较通俗易懂的语言,和良好的组织方式来介绍Documentation里面的某个package里面包含的一些类的用法而已。所以万变不离其宗,如果你有足够的能力来直接通过Documentation来学习Java的类库,那么基本上就不需要看其他的书籍了。除此之外,Documentation也是编程必备的手册,我的桌面上有三个Documentation的快捷方式,分别是J2SDK1.4.1 DocumentationServlet2.3DocumentationJ2SDKEE1.3.1Documentation。有了这个三个 Documentation,什么其他的书籍都不需要了。
     

    对于Java Web 编程来说,最核心的是要熟悉和掌握HTTP协议,这个就和Java无关了,在熟悉HTTP协议之后,就需要熟悉Java的实现HTTP协议的类库,也就是Servlet API,所以最重要的东西就是Servlet API。当然对于初学者而言,直接通过 Servlet API来学习Web编程有很大的难度,我推荐O'reilly的《Java Server Pages 》这本书来学习Web 编程。
     

    EJB
    的书籍当中,《Enterprise JavaBeans, 2nd Edition》是一本很不错的书, EJB的学习门槛是比较高,入门很难,但是这本书完全降低了学习的难度,特别重要的一点是,EJB的学习需要结合一种App Server的具体实现,所以在学习EJB的同时,必须同步的学习某种App Server,而这本书相关的出了三本书,分别是Weblogic6.1Websphere4.0JBoss3.0上面部署书中例子的实做。真是既有理论,又有实践。在学习EJB的同时,可以边看边做,EJB的学习会变得很轻松。
     

    但是这本书也有一个问题,就是版本比较旧,主要讲EJB1.1规范和部分EJB2.0的规范。而Ed Roman写的《Mastering EJB 2.0》这本书完全是根据EJB2.0规范写的,深入浅出,覆盖了EJB编程的各个方面,并且还有很多编程经验tips,也是学习EJB非常推荐的书籍之一。
     

    如果是结合Weblogic来学习J2EE的话,《J2EE应用与BEA Weblogic Server》绝对是首选读物,虽然是讲述的 Weblogic6.0,仍然值得购买,这本书是BEA官方推荐的教材,作者也是BEA公司的工程师。现在中文版已经随处可见了。这本书结合 Weblogic介绍了J2EE各个方面的技术Weblogic平台上的开发和部署,实践指导意义非常强。
     

    在掌握了Java平台基础知识和J2EE方面的知识以后,更进一步的是学习如何运用OO的方法进行软件的设计,那么就一定要学习设计模式 Sun公司出版了一本《J2EE核心模式》,是每个开发Java企业平台软件的架构师必备的书籍。这本书全面的介绍了J2EE体系架构的各种设计模式,是设计师的必读书籍。
     

    Java Learning Path
    (三)过程篇
     

    每个人的学习方法是不同的,一个人的方法不见得适合另一个人,我只能是谈自己的学习方法。因为我学习Java是完全自学的,从来没有问过别人,所以学习的过程基本上完全是自己摸索出来的。我也不知道这种方法是否是比较好的方法,只能给大家提供一点参考了。
     

     
    其实JDK的学习没有那么简单,关于JDK有两个问题是很容易一直困扰
    J学习Java的第一步是安装好JDK,写一个Hello World Java程序员的地方:一个是CLASSPATH的问题,其实从原理上来说,是要搞清楚JREClassLoader是如何加载Class的;另一个问题是packageimport问题,如何来寻找类的路径问题。把这两个问题摸索清楚了,就扫除了学习Java和使用JDK的最大障碍。推荐看一下王森的《Java深度历险》,对这两个问题进行了深入的探讨。 

    第二步是学习Java的语法。Java的语法是类C++的,基本上主流的编程语言不是类C,就是类C++的,没有什么新东西,所以语法的学习,大概就是半天的时间足够了。唯一需要注意的是有几个不容易搞清楚的关键字的用法,publicprotectedprivatestatic,什么时候用,为什么要用,怎么用,这可能需要有人来指点一下,我当初是完全自己琢磨出来的,花了很久的时间。不过后来我看到《Thinking in Java》这本书上面是讲了这些概念的。
     

    第三步是学习Java的面向对象的编程语言的特性的地方。比如继承,构造器,抽象类,接口,方法的多态,重载,覆盖,Java的异常处理机制。对于一个没有面向对象语言背景的人来说,我觉得这个过程需要花很长很长时间,因为学习Java之前没有C++的经验,只有C的经验,我是大概花了一个月左右吧,才彻底把这些概念都搞清楚,把书上面的例子反复的揣摩,修改,尝试,把那几章内容反复的看过来,看过去,看了不下5遍,才彻底领悟了。不过我想如果有 C++经验的话,应该一两天时间足够了。那么在这个过程中,可以多看看《Thinking in Java》这本书,对面向对象的讲解非常透彻。可惜的是我学习的时候,并没有看到这本书,所以自己花了大量的时间,通过自己的尝试和揣摩来学会的。
     

    第四步就是开始熟悉Java的类库。Java
    的基础类库其实就是JDK安装目录下面jre\lib\rt.jar这个包。学习基础类库就是学习rt.jar。基础类库里面的类非常非常多。据说有3000多个,我没有统计过。但是真正对于我们来说最核心的只有4个,分别是 
    java.lang.*; 
    java.io.*; 
    java.util.*; 
    java.sql.*; 

    这四个包的学习,每个包的学习都可以写成一本厚厚的教材,而O'reilly也确实是这样做的。我觉得如果时间比较紧,是不可能通过读四本书来学习。我觉得比较好的学习方法是这样的: 
    首先要通读整个package的框架,了解整个packageclassinterfaceexception的构成,最好是能够找到介绍整个包框架的文章。这些专门介绍包的书籍的前几章应该就是这些总体的框架内容介绍。 

    对包整体框架的把握并不是要熟悉每个类的用法,记住它有哪些属性,方法。想记也记不住的。而是要知道包有哪些方面的类构成的,这些类的用途是什么,最核心的几个类分别是完成什么功能的。我在给人培训的时候一般是一次课讲一个包,所以不可能详细的介绍每个类的用法,但是我反复强调,我给你们讲这些包的不是要告诉你们类的方法是怎么调用的,也不要求你们记住类的方法调用,而是要你们了解,Java给我们提供了哪些类,每个类是用在什么场合,当我遇到问题的时候,我知道哪个类,或者哪几个类的组合可以解决我的问题,That'all!,当我们具体写程序的时候,只要你知道该用哪个类来完成你的
    工作就足够了。编码的时候,具体的方法调用,是边写代码,边查Documentation,所有的东西都在Documentation里面,不要求你一定记住,实际你也记不住3000多个类的总共将近10万个方法调用。所以对每个包的总体框架的把握就变得极为重要。 

    第五步,通过上面的学习,如果学的比较扎实的话,就打好了Java的基础了,剩下要做的工作是扫清Documentation里面除了上面4个包之外的其他一些比较有用处的类。相信进展到这一步,Java的自学能力已经被培养出来了,可以到了直接学习Documentation的水平了。除了要做 GUI编程之外,JDK里面其他会有用处的包是这些: 
    java.text.*; 
    java.net.*; 
    javax.naming.*; 
    这些包里面真正用的比较多的类其实很少,只有几个,所以不需要花很多时间。 

    第六步,Java Web 编程 
    Web
    编程的核心是HTTP协议,HTTP协议和Java无关,如果不熟悉HTTP协议的话,虽然也可以学好Servlet/JSP编程,但是达不到举一反三,一通百通的境界。所以HTTP协议的学习是必备的。如果熟悉了HTTP协议的话,又有了Java编程的良好的基础,学习 Servlet/JSP简直易如反掌,我学习Servlet/JSP就用了不到一周的时间,然后就开始用JSP来做项目了。 

    Servlet/JSP的学习中,重头仍然是Servlet DocumentationServlet API最常用的类很少,花比较少的时间就可以掌握了。把这些类都看一遍,多写几个例子试试。Servlet/JSP编程本质就是在反复调用这些类来通过HTTP协议在Web Server Brower之间交谈。另外对JSP,还需要熟悉几个常用JSP的标记,具体的写法记不住的话,临时查就是了。 

    此外
    Java Web编程学习的重点要放在Web Application的设计模式上,如何进行业务逻辑的分析,并且进行合理的设计,按照 MVC设计模式的要求,运用ServletJSP分别完成不同的逻辑层,掌握如何在ServletJSP之间进行流程的控制和数据的共享,以及 Web Application应该如何配置和部署。 

    第七步,J2EE编程 
    以上的学习过程如果是比较顺利的话,进行到这一步,难度又陡然提高。因为上面的知识内容都是只涉及一个方面,而像EJBJMSJTA等核心的J2EE规范往往是几种Java技术的综合运用的结晶,所以掌握起来难度比较大。 

    首先一定要学习好JNDIJNDIApp Server定位服务器资源(EJB组件,DatasouceJMS)查找方法,如果对JNDI 不熟悉的话,EJBJMS这些东西几乎学不下去。JNDI其实就是javax.naming.*这个包,运用起来很简单。难点在于服务器资源文件的配置。对于服务器资源文件的配置,就需要看看专门的文档规范了,比如web.xml的写法,ejb-jar.xml的写法等等。针对每种不同的 App Server,还有自己的服务资源配置文件,也是需要熟悉的。 

    然后可以学习JTA,主要是要理解JTA对于事务的控制的方法,以及该在什么场合使用JTA。这里可以简单的举个例子,我们知道一般情况可以对于一个数据库连接进行事务控制(conn.setAutoCommit(false),....,conn.commit()),做为一个原子操作,但是假设我的业务需求是要把对两个不同数据库的操作做为一个原子操作,你能做的到吗?这时候只能用JTA了。假设操作过程是先往A数据库插一条记录,然后删除B 数据库另一个记录,我们自己写代码是控制不了把整个操作做为一个原子操作的。用JTA的话,由App Server来完成控制。 

    在学习EJB之前要学习对象序列化和RMIRMIEJB的基础。接着学习JMSEJB,对于EJB来说,最关键是要理解EJB是如何通过RMI来实现对远端对象的调用的,以及在什么情况下要用到EJB 

    在学习完EJBJMS这些东西之后,你可能会意识到要急不可待学习两个领域的知识,一个是UML,另一个是Design Pattern Java企业软件的设计非常重视框架(Framework)的设计,一个好的软件框架是软件开发成功的必要条件。在这个时候,应该开始把学习的重点放在设计模式和框架的学习上,通过学习和实际的编程经验来掌握EJB的设计模式和J2EE的核心模式。 

    J2EE
    规范里面,除了EJBJMSJTAServlet/JSPJDBC之外还有很多很多的企业技术,这里不一一进行介绍了。 

    另外还有一个最新领域Web ServicesWeb Services也完全没有任何新东西,它像是一种黏合剂,可以把不同的服务统一起来提供一个统一的调用接口,作为使用者来说,我只要获得服务提供者给我的WSDL(对服务的描述),就够了,我完全不知道服务器提供者提供的服务究竟是EJB 组件,还是.Net组件,还是什么CORBA组件,还是其他的什么实现,我也不需要知道。Web Services最伟大的地方就在于通过统一的服务提供方式和调用方式,实现了整个Internet服务的共享,是一个非常令人激动的技术领域。Web Services好像目前还没有什么很好的书籍,但是可以通过在网络上面查资料的方式来学习。 

    Java Learning Path
    (四) 方法篇 

    Java
    作为一门编程语言,最好的学习方法就是写代码。当你学习一个类以后,你就可以自己写个简单的例子程序来运行一下,看看有什么结果,然后再多调用几个类的方法,看看运行结果,这样非常直观的把类给学会了,而且记忆非常深刻。然后不应该满足把代码调通,你应该想想看如果我不这样写,换个方式,再试试行不行。记得哪个高人说过学习编程就是个破坏的过程,把书上的例子,自己学习Documentation编写的例子在运行通过以后,不断的尝试着用不同的方法实现,不断的尝试破坏代码的结构,看看它会有什么结果。通过这样的方式,你会很彻底的很精通的掌握Java 

    举个例子,我们都编过Hello World 

    public class HelloWorld { 
    public static void main(String[] args) { 
    System.out.println("Hello World"); 



    很多初学者不是很理解为什么main方法一定要这样来定义public static void main(String[] args),能不能不这样写?包括我刚学习Java的时候也有这样的疑问。想知道答案吗?很简单,你把main改个名字运行一下,看看报什么错误,然后根据出错信息进行分析;把mainpublic取掉,在试试看,报什么错误;static去掉还能不能运行;不知道main方法是否一定要传一个String[]数组的,把String[]改掉,改成int[],或者String试试看;不知道是否必须写args参数名称的,也可以把args改成别的名字,看看运行结果如何。 

    我当初学习Java的时候就是这样做的,把Hello World程序反复改了七八次,不断运行,分析运行结果,最后就彻底明白为什么了main方法是这样定义的了。 

    此外,我对于staicpublicprivateExceptiontry{ }catch {}finally{}等等等等一开始都不是很懂,都是把参考书上面的例子运行成功,然后就开始破坏它,不断的根据自己心里面的疑问来重新改写程序,看看能不能运行,运行出来是个什么样子,是否可以得到预期的结果。这样虽然比较费时间,不过一个例子程序这样反复破坏几次之后。我就对这个相关的知识彻底学通了。有时候甚至故意写一些错误的代码来运行,看看能否得到预期的运行错误。这样对于编程的掌握是及其深刻的。 

    其中特别值得一提的是JDK有一个非常棒的调试功能,-verbose 
    java –verbose 
    javac –verbose 
    以及其它很多JDK工具都有这个选项 
    -verbose 
    可以显示在命令执行的过程中,JVM都依次加载哪里Class,通过这些宝贵的调试信息,可以帮助我们分析出JVM在执行的过程中都干了些什么。 

    另外,自己在学习过程中,写的很多的这种破坏例程,应该有意识的分门别类的保存下来,在工作中积累的典型例程也应该定期整理,日积月累,自己就有了一个代码库了。遇到类似的问题,到代码库里面 Copy & Paste Search & Replace,就好了,极大提高了开发速度。最理想的情况是把一些通用的例程自己再抽象一层,形成一个通用的类库,封装好。那么可复用性就更强了。 

    所以我觉得其实不是特别需要例程的,自己写的破坏例程就是最好的例子,如果你实在对自己写的代码不放心的话,我强烈推荐你看看JDK基础类库的 Java源代码。在JDK安装目录下面会有一个src.zip,解开来就可以完整的看到整个JDK基础类库,也就是rt.jarJava源代码,你可以参考一下Sun是怎么写Java程序的,规范是什么样子的。我自己在学习Java的类库的时候,当有些地方理解的不是很清楚的时候,或者想更加清晰的理解运作的细节的时候,往往会打开相应的类的源代码,通过看源代码,所有的问题都会一扫而空。 

    Java Learning Path
    (五)资源篇 

    1
     http://java.sun.com/ (英文
    Sun
    Java网站,是一个应该经常去看的地方。不用多说。 

    2
    http://www-900.ibm.com/developerWorks/cn/ 
    IBM
    developerWorks网站,英语好的直接去英文主站点看。这里不但是一个极好的面向对象的分析设计网站,也是Web ServicesJava
    Linux极好的网站。强烈推荐!!! 

    3
    http://www.javaworld.com/ (英文
    关于Java很多新技术的讨论和新闻。想多了解Java的方方面面的应用,这里比较好。 

    4
    http://dev2dev.bea.com.cn/index.jsp 
    BEA
    的开发者园地,BEA作为最重要的App Server厂商,有很多独到的技术,在Weblogic上做开发的朋友不容错过。 

    5
    http://www.huihoo.com/ 
    灰狐动力网站,一个专业的中间件网站,虽然不是专业的Java网站,但是在J2EE企业应用技术方面有深厚的造诣。 

    6
    http://www.theserverside.com/home/ (英文
    TheServerSide
    是一个著名的专门面向Java Server端应用的网站。 

    7
    http://www.javaresearch.org/ 
    Java
    研究组织,有很多优秀的Java方面的文章和教程,特别是在JDO方面的文章比较丰富。 

    8
    http://www.cnjsp.org/ 
    JSP
    技术网站,有相当多的Java方面的文章和资源。 

    9
    http://www.jdon.com/ 
    Jdon
    论坛,是一个个人性质的中文J2EE专业技术论坛,在众多的Java的中文论坛中,Jdon一个是技术含量非常高,帖子质量非常好的论坛。 

    10
    http://sourceforge.net/ 
    SourgeForge
    是一个开放源代码软件的大本营,其中也有非常非常丰富的Java的开放源代码的著名的软件。

    ----注:本文内容转自“chinabear2008的个人空间

     

  • 什么是Ajax技术

    2008-04-17 16:41:36

    Ajax(Asynchronous Javascrīpt and XML)是一个结合了Java技术、XML、以及Javascrīpt的编程技术,可以让你构建基于Java技术的Web应用,并打破了使用页面重载的惯例。

    页面重载提出了一个在Web应用开发中最大的可用性障碍,对于java开发来说也是一个重大的挑战。

    Ajax,异步Javascrīpt与XML,是使用客户端脚本与Web服务器交换数据的Web应用开发方法。这样,Web页面不用打断交互流程进行重新加裁,就可以动态地更新。使用Ajax,你可以创建接近本地桌面应用的,直接的、高可用的、更丰富的、更动态的Web用户接口界面。

    Ajax不是一个技术,它更像是一个模式—标志并描述有用的设计技巧的一种方法。对于刚了解它的许多开发人员来说,它是一种新的感觉,但是实现Ajax的所有组件都已存在了许多年。当前的热闹是因为在2004与2005年出现了一些基于Ajax的非常动态的WebUI,尤其是Google的GMail与Maps应用系统、与照片共享网站Flickr。这些UI充分地使用了后台通道,也被一些开发者称为“Web 2.0”,并导致了大家对Ajax应用兴趣的猛涨

  • JAVA基础:Java变量类型之间的相互转换

    2008-04-11 14:23:29

    我们知道,Java的数据类型分为三大类,即布尔型、字符型和数值型,而其中数值型又分为整型和浮点型;相对于数据类型,Java的变量类型为布尔型boolean;字符型char;整型byte、short、int、long;浮点型float、double。其中四种整型变量和两种浮点型变量分别对应于不同的精度和范围。此外,我们还经常用到两种类变量,即String和Date。对于这些变量类型之间的相互转换在我们编程中经常要用到,在我们今天的这篇文章中,我们将来看看如何实现这些转换。

    一、 整型、实型、字符型变量中的相互转换
      在Java中整型、实型、字符型被视为同一类数据,这些类型由低级到高级分别为(byte,short,char)??int??long??float??double,低级变量可以直接转换为高级变量,例如,下面的语句可以在Java中直接通过:
    byte b;
    int i=b;
      而将高级变量转换为低级变量时,情况会复杂一些,你可以使用强制类型转换。即你必须采用下面这种语句格式:
    int i;
    byte b=(byte)i;
      可以想象,这种转换肯定可能会导致溢出或精度的下降,因此我们并不推荐使用这种转换。

    二、Java的包装类
      在我们讨论其它变量类型之间的相互转换时,我们需要了解一下Java的包装类,所谓包装类,就是可以直接将简单类型的变量表示为一个类,在执行变量类型的相互转换时,我们会大量使用这些包装类。Java共有六个包装类,分别是Boolean、Character、Integer、Long、Float和 Double,从字面上我们就可以看出它们分别对应于 boolean、char、int、long、float和double。而String和Date本身就是类。所以也就不存在什么包装类的概念了。

    三、简单类型变量和包装类之间的相互转换
      简单类型的变量转换为相应的包装类,可以利用包装类的构造函数。即:
    Boolean(boolean value)、Character(char value)、Integer(int value)、Long(long value)、Float(float value)、Double(double value)
      而在各个包装类中,总有形为××Value()的方法,来得到其对应的简单类型数据。利用这种方法,也可以实现不同数值型变量间的转换,例如,对于一个双精度实型类,intValue()可以得到其对应的整型变量,而doubleValue()可以得到其对应的双精度实型变量。

    四、String类和其它数据类型的相互转换
      对于上面的这些包装类,除了Character以外,都有可以直接使用字符串参数的构造函数,这也就使得我们将String类转换为这些数据类型变得相当之简单,即:
    Boolean(String s)、Integer(String s)、Long(String s)、Float(String s)、Double(String s)
      而将String类转换为Date类也可以使用这样的构造函数:Date(String s)
      现在我们还剩下一个字符型变量,事实上String类可以理解为一个char型数组,因此我们可以在String类中找到这样的方法来实现这种转换: charAt(int index)可以得到String类中某一位置上的字符,toCharArray()更可以将整个String类转换成一个char的数组。
      对于所有的包装类都存在一个名为toString()的方法可以将其转换成对应的String类,而对于整型类和长整型类,还可以使用 toBinaryString(int i)、toHexString(int i)、toOctalString(int i)分别以二进制、十六进制和八进制的形式进行到String类的转换。

    五、将字符型直接做为数值转换为其它数据类型
      将字符型变量转换为数值型变量实际上有两种对应关系,在我们在第一部分所说的那种转换中,实际上是将其转换成对应的ASCII码,但是我们有时还需要另一种转换关系,例如,‘1’就是指的数值1,而不是其ASCII码,对于这种转换,我们可以使用Character的getNumericValue(char ch)方法。

    六、Date类与其它数据类型的相互转换
      整型和Date类之间并不存在直接的对应关系,只是你可以使用int型为分别表示年、月、日、时、分、秒,这样就在两者之间建立了一个对应关系,在作这种转换时,你可以使用Date类构造函数的三种形式:
    Date(int year, int month, int date):以int型表示年、月、日
    Date(int year, int month, int date, int hrs, int min):以int型表示年、月、日、时、分
    Date(int year, int month, int date, int hrs, int min, int sec):以int型表示年、月、日、时、分、秒
      在长整型和Date类之间有一个很有趣的对应关系,就是将一个时间表示为距离格林尼治标准时间1970年1月1日0时0分0秒的毫秒数。对于这种对应关系,Date类也有其相应的构造函数:Date(long date)
      获取Date类中的年、月、日、时、分、秒以及星期你可以使用Date类的getYear()、getMonth()、getDate()、 getHours()、getMinutes()、getSeconds()、getDay()方法,你也可以将其理解为将Date类转换成int。
      而Date类的getTime()方法可以得到我们前面所说的一个时间对应的长整型数,与包装类一样,Date类也有一个toString()方法可以将其转换为String类。
      在Java的数据类型转换中,你还有一些其它方法可用,但是,上面所介绍的这些方法对于你的实际编程已经足够了,不是吗?


  • C#与Java相似之处的对比

    2008-04-11 14:21:41

     C#和Java都是很不错的语言。他们通过类似的方式达到了类似的目的,尽管C#比Java多出来一些和句法相关的东西,例如foreach关键字和一些更加让人高兴的扩展/实现架构。不幸的是,这些改进的光芒被削弱的东西掩盖掉了。在本文里,我将比较两种语言,并尽量避免深入到JVM和CLR层。

      Java:无可争辩地具有C++所有的精华

      在比较Java和C#的时候,你不可能不注意到它们诸多的相似之处,这在某种程度上要归结于它们共同的来源:C和C++。但是,当Gosling和他的同事们坐下来创造Java的时候,他们不仅吸取了C++的能力,而且更重要的是,他们减掉了一些无用特性,后者让C++更容易出错误而且更难学习。C#的设计者加入了很多C++的特性,而Java也加入了这些特性,但是C#却没有去掉C++的最糟糕的一些特性。其结果就是这样一门语言,它仍然为所有人提供了所有的特性,但其结局是内部冲突不断,而且过于复杂。

      散漫的句法缺陷

      最容易找出的错误是流控制和句法。C#提供了goto command,将其作为更改程序执行点的机制。自从Edsger W. Dijkstra在1968年出版了他的《关于Go to陈述式害处的考虑(Go To Statement Considered Harmful)》。Goto语句导致代码难以调试,而且很难被测试工具处理。

      在另一种不同的情况下,操作符过载同样也有很大问题,只不过层次不一样罢了。当“+”根据操作数的类型而代表任何东西的时候,代码的功能就不再透明,难以预料的副作用就会发生。

      C#在安全上的削弱

      C#有一个用于将代码区域标示为不安全的简单机制。在这些不安全的区域里,Java以及后来的C#安排到位了一些安全措施,用以防止程序员直接修改内存位置,以及使用点运算,但是这些措施是值得怀疑的。在使用具有垃圾清理功能的高级语言时,如果下到内存地址这一层,就会把对象/内存之间有意作出分离弄混。错误就会容易出现,调试成了恶梦,缓冲区溢出再次抬头,C和C++里著名的安全漏洞再次现身。

      C#还允许对主机系统上本机库的简单访问。这个与非.NET对象相结合的访问同Java本机接口(JNI)所提供的功能类似,但是它更加危险。JNI被设计用来小心地限制Java代码以及本机代码同已定义好的接口之间的交互操作,.NET使得调用本机对象文件变得极其简单,结果导致开发人员在做这的时候,无法意识到他们在这一过程中把平台的可移植性也扔出了窗外。

      SOAP的集成

      C#,及其更大的扩展.NET,已经同SOAP Web服务紧密地集成在一起。SOAP是使用XML指定参数和结果值来进行远程过程调用的好标准,但是它并不是唯一的方式。利用用于Web服务的外部库能够允许Java开发人员轻易地更改其Web服务的风格,使其成为SOAP、XML-RPC,或者什么还没有发明的东西。当然,C#的开发人员总是能够选择将外部库用于SOAP的Web服务,但是由SOAP标准的紧密集成所造成的限制要比它能够做的东西更多。

      所有者的恐慌

      C#里最令人恐慌的特性可能就是其所有者了。微软已经为将C#和.NET用于非Windows平台进行了精心的展示,但是这在很大程度上还只是作秀。其用于非Windows平台的CLR是问题多多,错误多多。它通过ECMA标准化过程来运行C#??这一步连Sun也不敢在Java上迈出。其担心来自于微软对此可能封锁的程度,如果它愿意的话。微软已经申请了一个专利,以排斥他人编写第三方的CRL,例如Mono计划。如果微软决定对免费的C#和.NET社区施压,它就有能力拿票子和法律的大棒把其开发活动赶回到Win32平台??当然这也不是它想看到的情况。

      而Java语言则相反,不是ECMA标准的,真可惜Sun没有遵从这一标准。但是,它是可以实现的,而且没有专利的阻碍,其虚拟机和核心类库都有来自第三方的开放和封闭源代码的实现。C#看起来是免费的,其实不然,而Java看起来限制很多,但是它能够依据法律通过免费的途径来实现。

      最后,我从来都没有想到我会说这个,但是Java具有更好工具的支持,即使是在考虑到集成开发环境(IDE)的情况下。Visual Studio .NET是一个很不错的IDE。它代表了多年的努力,而且特性很丰富。但是,Eclipse IDE包括了对Java的支持,它在稳定性、易用性和所提供的特性上超过了Visual Studio。IBM对Eclipse的贡献举足轻重,而且如果你信奉原来的软件格言“创建一个扔掉的(Build one to throw away)”,那么你可以把Visual Age作为第一个(被抛弃掉了的)尝试。对于使用C#的开发人员来说幸运的是,Eclipse的.NET版本正在开发中。

      不是那么差,但是还不是Java

      客观一点评价,C#里并没有什么很恐怖的东西。它没有Visual Basic里的那些很恐怖的东西,而且它事实上也没有继承像C里的一些东西,而这些东西会让开发人员开枪却打中自己脚。但是,底线是,C#并没有做很多东西,如果有任何东西比Java更好的话。它在某些方面很明显的要更差。在这两个非常类似的语言之间作选择的时候,请选择稍稍更好且经历风雨的那个:Java。

  • Java基础入门 初学Java编程的一些小技巧

    2008-04-11 14:20:16

    本文就java基础部分容易混淆的一些知识点进行了一下总结。因为Java本身知识点非常多,不可能在很短的篇幅就能叙述完,而且就某一个点来讲,如欲仔细去探究,也能阐述的非常多。这里不做全面仔细的论述,仅做为一个引子,抛砖引玉。具体个例,还需各位看官自己验证一下,以增进理解和记忆。
     
      欢迎就这一部分各位朋友与我进行探讨,共同进步。
    1、虽然有很多朋友可能进行了多年的java开发老手,但可能仍旧对某些点缺乏仔细探究。
    2、去一些公司求职面试或笔试时的技术题目中,也往往会涉及到这里的一些内容。
      所以,希望下边的这些总结能够对一些学习java或求职的朋友有些许帮助。


       
      1、 关于java类中的缺省的构造器
      如果一个java类没有显式定义没有参数的构造器,将有一个默认缺省的构造器。如果定义了一个有参数的构造器,那么原来的缺省的构造器将不在有效。
    public class A{
    }
    此时如果用 new A(); java编译器将使用缺省的构造器。
    public class A{
    public A(int i){
    }
    }
      如果此时用 new A(); 将产生一个编译错误,因为此时显式定义了,一个有参数的构造器。


    2、Java中的类名与文件名
    1、在一个java文件中可以有多于一个类定义(更常见于某些组件的监听器类),但只能有一个public class定义,且与文件同名。
    2、如果一个java源文件中没有public类,那么每个类的名字没特殊规则,即不必与文件同名。
    3、在编译后产生的class文件中,仍旧是多个单独分开的class文件。


    3、import关键字
    1、import语句必须定义在所有的class定义之前。
    2、import语句只是为编译器指明了一个路径,并不像C或C++中的#include,所以用import .*并不影响性能


    4、Java中的几个特殊关键字
    Java中的关键字许多大家都比较熟悉,而有几个就不是很常用,如:
    1、goto和const是保留关键字,在java中没使用
    2、strictfp和volatile不常用; sizeof、zhen不是关键字。
    3、true,false,null不是严格意义上的关键字,而是literals。


    5、java方法中的传递值参
      在Java方法中传递参数,对于基本类型来讲传递的是值参数,相当于建立的一个参数的拷贝,不影响原来变量的值。
      在引用方法中可以改变传递对象的内容,但对象引用(像A@5d87b2)从来不会改变。

    public class tt{
    public static void main (String args[]){
      A aa = new A();
      aa.num =5;
      tt t = new tt();
      System.out.println("11 aa="+aa + "num="+aa.num);
      t.test(aa);
      System.out.println("22 aa="+aa + "num="+aa.num);
    }
    void test(A a){
      A ab = new A();
      a = ab;
      System.out.println("33 ab="+ab + "num="+ab.num);
    }
    }
    class A{
    int num;
    }
     
    6、变量初始化
      java中的变量在使用之前必须被初始化,当创建一个对象的时候一些类的变量会自动初始化并赋予缺省值。
      数字类赋值0;char类型赋值'\u0000'; boolean类型赋值false;引用对象赋值null;
      注意的是在方法之外的类变量的值是自动赋初始值,而方法内的局部变量必须手工初始化。

    class AA{
    int num;
    void test(){
      int j;
      j =5;//没有这一行则编译不会通过。
      j = j+num;
    }
    }
     
    7、switch语句
      这个点经常在求职笔试题目中出现。default放在最上边编译没问题;碰到符合分支的,如果没有break会一直向下运行。

    public class tt{
    public static void main (String args[]){
      tt t = new tt();
      t.test(2);//可改变成3运行一下看一下结果
    }
    void test(int i){
      switch (i){
        default:
        System.out.println("default");
        case 1:
        System.out.println("111");
        break;
        case 2:
        System.out.println("222");
        break;
      }
    }
    }
     
    8、关于java中的label使用
    ? break [label]
    ? continue[lbele]
    ? lable: statement; //这里的statement必须是一个loop循环
    public class tt{
    public static void main (String args[]){
      tt t = new tt();
      t.test();
    }
    void test(){
      System.out.println("0000");
      lb1:for (int i=0;i<10;i++){
        lb2:for (int j=0; j<2; j++){
          if (i==2) continue lb1;
          System.out.println("i="+i +" j="+j);
        }
      }
      System.out.println("111111");
    }
    }
     
    9、类型转换校正
    class Employee
          |
    class Manager
    向上校正,总是允许的,Manager直接使用父类Employee的方法。
    向下校正,必须用instanceof检验,才能将一个Employee转换为Manager对象。

    public void test(Employee e){
    if (e instanceof Manager){
      Manager m = (Mnager)e;
      ...
    }
    }



  • Java基础入门 初学Java编程的一些小技巧

    2008-04-11 14:17:09

      学JAVA时间短了,可总没有一点自己原创的东西,今天就以写IDE开发工具的使用技巧作为我原创的开始吧,希望大家能喜欢这篇文章,也希望鄙文能对广大初学JAVA的朋友有一点帮助!在使用JCRETOR过程中,自己摸索出了一点点使用技巧,在这里供广大和我一样的初学者参考!

    技巧1: 建立空项目进行JAVA编程;

            在进行编程的时候最好首先建立一个空项目,然后在这个空项目里,编辑自己的JAVA程序;其实这是一个很好的习惯,你可以在这个项目里建立你自己的包,把你所编辑的源程序程序,按功能的不同分别放进不同的包里;这样在你学习JAVA一定长的时间后,你就拥有了一个属于你自己的包,这对你以后学习或查相关代码就很方便。

            建立空项目的方法,或许大家都知道,不过在这里我还是罗嗦一下:):

            按JCRETOR的菜单顺序,创建方法如下:

    File??>New??>Project??>EmptyProject;

            哈,其实很简单!祝你也早日拥有自己的类库!

            技巧2: Jcretor对JDK的帮助文档提供了很好的支持;

            通过Jcretor你可以很方便的即时查阅JDK帮助文档!且这个功能可以实现网页直接在Jcreator的编辑窗口里显示,而不用另外打开任何浏览器进行浏览。(Jcreator的这个特点我十分喜欢,据我所知Eclipse好象没有提供这个功能)哈,说了这么久相信大家一定会问,你这个功能到底怎么使用了! OK!别急,马上你也会掌握这个技巧。

            不知道大家是否记得在我们装完Jcreator后,第一次运行Jcreator时,系统会要求你指定JDK的安装路径;其实如果大家记得的话,在设置好了JDK的安装路径后,还会要求你提供一个DOCS的路径。哈,对头,要的就是这个拉!呵呵……下面让我来告诉你怎么设置这个路径:

            首先,从SUN公司网站下载对应的JDK文档;

            其次,在JDK安装目录(如,我的安装目录为D:j2sdk1.4.2_06)中建立一个名为docs的文件夹,然后将所下载的JDK文档解压到刚才建立的文件夹里,解压完成后,然后在安装Jcretors时在相应地方选择刚才JDK文档所在的目录即可;(应注意的是:要保证docs文件夹下面不要再有docs文件夹)当你设置好后启动Jcreator,你是否会发现你的Jcreator有什么变化没有了?哈,其实有的,不信你看看Jcreator菜单栏中的Help下拉菜单,仔细看看是不是多了个什么东西?呵呵……是不是多了个“JDK Help Ctrl+F1”菜单项!如果有,那么恭喜你,配置成功拉!下面我将告诉你怎么使用这个功能;

            再次,就是使用Jcretor发挥JDK帮助文档的作用拉!这正是我要说的重点,OK,让我来告诉你具体怎么使用这个功能吧:

            当你在Jcreator中编写程序或看别人的原代码的时候,肯定会碰到不熟悉或不知道的类或方法,这个时候你用鼠标选中你要查询的类名或方法名,然后点击Jcretor菜单栏里的Help菜单下面的JDK Help,这时你会发现你所要查询的资料马上就在Jcreator中以网页的形式显示出来了! 呵呵……是不是发现很简单,是不是觉得可以跟CHM格式的JDK文档媲美!哈,就是这么简单!

            技巧3: 这个技巧似乎和技巧2有点类似,归跟揭底就是为了实现网页文件直接在Jcreator编辑窗口中显示,而免去另外打开其他浏览器工具的麻烦。其实这个功能主要是为了方便编写JAVA APPLET小程序的程序员的。当编写好一个APPLET程序后,总要通过网页来观察程序的结果,这时用Jcretor编写一个HTML原文件并保存!这时会发现在Jcreator编辑窗口最左边的File View窗口中会出现相应的文件名,选中这个文件,单击右键再点击其中的View in Browser菜单项,不久你所选的HTML文件即在Jcretor中显示出来。OK,用这个方法比起你用浏览器来打开这个HTML文件,是不是方便多拉!呵呵,就是这么简单!

            以上就是我在用Jcreator进行JAVA编程总结出来的一点点使用技巧,或许有些朋友已经知道了这里面的功能,班门弄斧,写得不好也请大家见凉!同时我还期望大家能把自己在使用Jcretor过程中总结出来的经验贴上来供大家一起参考!

  • Java基础知识:初学者必须理解的六大问题

    2008-04-11 14:14:51

      对于这个系列里的问题,每个学Java的人都应该搞懂。当然,如果只是学Java玩玩就无所谓了。如果你认为自己已经超越初学者了,却不很懂这些问题,请将你自己重归初学者行列。

    问题一:我声明了什么!

    String s = "Hello world!";

            许多人都做过这样的事情,但是,我们到底声明了什么?回答通常是:一个String,内容是“Hello world!”。这样模糊的回答通常是概念不清的根源。如果要准确的回答,一半的人大概会回答错误。

            这个语句声明的是一个指向对象的引用,名为“s”,可以指向类型为String的任何对象,目前指向"Hello world!"这个String类型的对象。这就是真正发生的事情。我们并没有声明一个String对象,我们只是声明了一个只能指向String对象的引用变量。所以,如果在刚才那句语句后面,如果再运行一句:

    String string = s;

            我们是声明了另外一个只能指向String对象的引用,名为string,并没有第二个对象产生,string还是指向原来那个对象,也就是,和s指向同一个对象。

    问题二:"=="和equals方法究竟有什么区别?

    ==操作符专门用来比较变量的值是否相等。比较好理解的一点是:

    int a=10;

    int b=10;

    则a==b将是true。

            但不好理解的地方是:

    String a=new String("foo");

    String b=new String("foo");

    则a==b将返回false。

            根据前一帖说过,对象变量其实是一个引用,它们的值是指向对象所在的内存地址,而不是对象本身。a和b都使用了new操作符,意味着将在内存中产生两个内容为"foo"的字符串,既然是“两个”,它们自然位于不同的内存地址。a和b的值其实是两个不同的内存地址的值,所以使用"=="操作符,结果会是false。诚然,a和b所指的对象,它们的内容都是"foo",应该是“相等”,但是==操作符并不涉及到对象内容的比较。

            对象内容的比较,正是equals方法做的事。

            看一下Object对象的equals方法是如何实现的:

    boolean equals(Object o){

    return this==o;

    }

            Object对象默认使用了==操作符。所以如果你自创的类没有覆盖equals方法,那你的类使用equals和使用==会得到同样的结果。同样也可以看出,Object的equals方法没有达到equals方法应该达到的目标:比较两个对象内容是否相等。因为答案应该由类的创建者决定,所以Object把这个任务留给了类的创建者。

            看一下一个极端的类:

    Class Monster{

    private String content;

    ...

    boolean equals(Object another){ return true;}

    }

            我覆盖了equals方法。这个实现会导致无论Monster实例内容如何,它们之间的比较永远返回true。

            所以当你是用equals方法判断对象的内容是否相等,请不要想当然。因为可能你认为相等,而这个类的作者不这样认为,而类的equals方法的实现是由他掌握的。如果你需要使用equals方法,或者使用任何基于散列码的集合(HashSet,HashMap,HashTable),请察看一下java doc以确认这个类的equals逻辑是如何实现的。

    问题三:String到底变了没有?

            没有。因为String被设计成不可变(immutable)类,所以它的所有对象都是不可变对象。请看下列代码:

    String s = "Hello";

    s = s + " world!";

            s所指向的对象是否改变了呢?从本系列第一篇的结论很容易导出这个结论。我们来看看发生了什么事情。在这段代码中,s原先指向一个String对象,内容是"Hello",然后我们对s进行了+操作,那么s所指向的那个对象是否发生了改变呢?答案是没有。这时,s不指向原来那个对象了,而指向了另一个String对象,内容为"Hello world!",原来那个对象还存在于内存之中,只是s这个引用变量不再指向它了。

            通过上面的说明,我们很容易导出另一个结论,如果经常对字符串进行各种各样的修改,或者说,不可预见的修改,那么使用String来代表字符串的话会引起很大的内存开销。因为String对象建立之后不能再改变,所以对于每一个不同的字符串,都需要一个String对象来表示。这时,应该考虑使用StringBuffer类,它允许修改,而不是每个不同的字符串都要生成一个新的对象。并且,这两种类的对象转换十分容易。

            同时,我们还可以知道,如果要使用内容相同的字符串,不必每次都new一个String。例如我们要在构造器中对一个名叫s的String引用变量进行初始化,把它设置为初始值,应当这样做:

    public class Demo {

    private String s;

    ...

    public Demo {

    s = "Initial Value";

    }

    ...

    }


    而非

    s = new String("Initial Value");

            后者每次都会调用构造器,生成新对象,性能低下且内存开销大,并且没有意义,因为String对象不可改变,所以对于内容相同的字符串,只要一个String对象来表示就可以了。也就说,多次调用上面的构造器创建多个对象,他们的String类型属性s都指向同一个对象。

            上面的结论还基于这样一个事实:对于字符串常量,如果内容相同,Java认为它们代表同一个String对象。而用关键字new调用构造器,总是会创建一个新的对象,无论内容是否相同。

            至于为什么要把String类设计成不可变类,是它的用途决定的。其实不只String,很多Java标准类库中的类都是不可变的。在开发一个系统的时候,我们有时候也需要设计不可变类,来传递一组相关的值,这也是面向对象思想的体现。不可变类有一些优点,比如因为它的对象是只读的,所以多线程并发访问也不会有任何问题。当然也有一些缺点,比如每个不同的状态都要一个对象来代表,可能会造成性能上的问题。所以Java标准类库还提供了一个可变版本,即StringBuffer。


  • java文件操作大全

    2008-04-11 14:05:29

    java文件操作大全
      本文为本人在工作学习中的总结,每个方法都经过测试,记在博客上一方面是为了自己日后工作方便,另一方面是为了给大家提供方便,节约时间。

     .获得控制台用户输入的信息

    /** *//**获得控制台用户输入的信息
         * 
    @return
         * 
    @throws IOException
         */

        
    public String getInputMessage() throws IOException...{
            System.out.println("
    请输入您的命令∶");
            
    byte buffer[]=new byte[1024];
            
    int count=System.in.read(buffer);
            
    char[] ch=new char[count-2];//最后两位为结束符,删去不要
            for(int i=0;i<count-2;i++)
                ch[i]=(
    char)buffer[i];
            String str=
    new String(ch);
            
    return str;
        }

            可以返回用户输入的信息,不足之处在于不支持中文输入,有待进一步改进。

    .复制文件

    1.以文件流的方式复制文件

    /** *//**以文件流的方式复制文件
         * 
    @param src 文件源目录
         * 
    @param dest 文件目的目录
         * 
    @throws IOException  
         */

        
    public void copyFile(String src,String dest) throws IOException...{
            FileInputStream in=
    new FileInputStream(src);
            File file=
    new File(dest);
            
    if(!file.exists())
                file.createNewFile();
            FileOutputStream out=
    new FileOutputStream(file);
            
    int c;
            
    byte buffer[]=new byte[1024];
            
    while((c=in.read(buffer))!=-1)...{
                
    for(int i=0;i<c;i++)
                    out.write(buffer[i]);        
            }
            in.close();
            out.close();
        }

            该方法经过测试,支持中文处理,并且可以复制多种类型,比如txtxmljpgdoc等多种格式

    .写文件

    1.利用PrintStream写文件

    /** *//**
         * 
    文件输出示例
         */

        
    public void PrintStreamDemo()...{
            
    try ...{
                FileOutputStream out=
    new FileOutputStream("D:/test.txt");
                PrintStream p=
    new PrintStream(out);
                
    for(int i=0;i<10;i++)
                    p.println("This is "+i+" line");
            } 
    catch (FileNotFoundException e) ...{
                e.printStackTrace();
            }
        }

    2.利用StringBuffer写文件

    public void StringBufferDemo() throws IOException......{
            File file=
    new File("/root/sms.log");
            
    if(!file.exists())
                file.createNewFile();
            FileOutputStream out=
    new FileOutputStream(file,true);        
            
    for(int i=0;i<10000;i++)......{
                StringBuffer sb=
    new StringBuffer();
                sb.append("
    这是第"+i+":前面介绍的各种方法都不关用,为什么总是奇怪的问题 ");
                out.write(sb.toString().getBytes("utf-8"));
            }        
            out.close();
        }

            该方法可以设定使用何种编码,有效解决中文问题。

     

  • Eclipse插件安装!

    2008-04-08 08:46:49

    Eclipse 是一个开源的、可扩展的集成开发环境,已经吸引了业界的很多注意力,而且Eclipse 的支持者源源不断。Eclipse有着非常强大的功能,对于编码、调试、重构、单元测试等都提供了完美的实现。

            Eclipse 可以与任何一种IDE匹敌,甚至比它们还要好。Eclipse 有代码补足、代码模板的功能,以及对重构、Ant、CVS 和 JUnit 的支持。除了这些基本功能之外,Eclipse 的优点之一就是它的源代码是开放的,可扩展性很好,可以扩充很多插件,开源插件和商业插件都可以用来扩充 Eclipse。如果用户需要基本的 Eclipse IDE 所不具备的特性,一般都可以找到需要的插件。在大部分情况下,用户都可以找到免费的插件。

            由于 Eclipse 的流行性和开源特性,它已经在 IDE 领域成为一把尖刀,一方面,Eclipse在一步一步完善自己的功能,另一方面,Eclipse正在大刀阔斧抢占IDE开发的应用领域。数据表明Eclipse是现在最流行的Java开发环境之一,为了更好的使用Eclipse进行开发,就有必要了解Eclipse插件的机制,以及如何安装和使用插件。

            Eclipse插件

            Eclipse 是一个已经完全设计好的平台,是用于构建和集成应用的开发工具。平台本身不会提供大量的最终用户功能,平台的价值在于它的促进作用:根据插件模型来快速开发集成功能部件。

            平台本身是内置在插件层中的,每个插件定义下层插件的扩展,同时对自己的扩展进行进一步的定制。每种类型的扩展允许插件开发者向基本工具平台添加各种功能,每个插件的部件(例如文件和其他数据)由公共平台资源来协调。

            Eclipse最有魅力的地方就是它的插件体系结构,由于有了插件,Eclipse系统的核心部分在启动的时候要完成的工作十分简单:启动平台的基础部分和查找系统的插件。

            Eclipse的核心是动态发现、懒惰装入(Lazy)与运行的,平台用户界面提供标准的用户导航模型。于是每个插件可以专注于执行少量的任务,例如定义、测试、制作动画、发布、编译、调试和图解等,只要用户能想象得到的就会应有尽有。

            当Eclipse插件实现了一个扩展点,就创建了一个扩展,此外,使用此扩展点的插件还可以创建自己的扩展点。这种插件模式的扩展和扩展点是递归的,而且被证明是非常灵活的。事实上,Eclipse核心就是构建在插件之上的,这样随着使用Eclipse构建Eclipse插件的累积,这种插件模式就变得日渐成熟。

    插件安装注意事项

            初学者可能会对插件有恐惧心理,认为这是Eclipse底层的东西。其实不然,安装插件非常容易,安装插件时注意如下的几个问题就可以了。

            1.  插件的依赖关系

            如果用户要安装的插件还需要其他插件的支持,则需要安装依赖的插件才能使新安装的插件正常运行。例如用户要安装一个图形编辑的插件,但此插件需要图形编辑框架(GEF)插件的支持,只有先安装了GEF才能使新的插件安装成功。

            2.  缓存

            Eclipse会通过缓存的机制加载插件,有时用户刚安装的插件可能没有正常启动(特别是links方式安装),清除缓存后再重新启动Eclipse就行了。清除缓存最简单的方式是删除Eclipse的configuration目录下的所有文件夹(保留config.ini文件),还可以通过启动参数-clean启动。

            注意:如果是通过Update方式安装的插件,不能把Update方式安装的目录删除掉,否则这种方式安装的插件启动不了了。

            3.  版本

            当用户安装的插件要求某一个特定版本的Eclipse,或依赖某个特定版本的插件时,也可能会使插件安装不成功。

            安装插件要和依赖插件的版本号和依赖的Eclipse版本号对应,例如要安装的图形编辑插件依赖GEF 插件,版本号为3.2,而GEF 3.2只能在Eclipse3.2及更高版本运行,所以只有安装了GEF 3.2和Eclipse3.2才能正确安装此图形编辑插件。

            用户在安装插件之前,要看看插件依赖的插件列表和特定版本信息的帮助文档。通常在插件发布时,同时会发布一个插件依赖的列表,有了这些信息,用户就可以正确安装插件了。


  • apache 性能调优-2.2版中文手册(转)

    2008-02-14 14:26:40

    http://www.51testing.com/?199/action_viewspace_itemid_65511.html

    硬件和操作系统

    影响web服务器性能的最大的因素是内存。一个web服务器应该从不使用交换机制,因为交换产生的滞后使用户总感觉"不够快",所以用户就可能去按"停止""刷新",从而带来更大的负载。你可以,也应该,控制MaxClients的设置,以避免服务器产生太多的子进程而发生交换。这个过程很简单:通过top命令计算出每个Apache进程平均消耗的内存,然后再为其它进程留出足够多的内存。

    其他因素就很普通了,装一个足够快的CPU,一个足够快的网卡,几个足够快的硬盘,这里说的"足够快"是指能满足实际应用的需求。

    操作系统是很值得关注的又一个因素,已经被证实的很有用的经验有:

    • 选择能够得到的最新最稳定的版本并打好补丁。近年来,许多操作系统厂商都提供了可以显著改善性能的TCP协议栈和线程库。
    • 如果你的操作系统支持sendfile()系统调用,则务必安装带有此功能的版本或补丁(译者注:Linux2.4内核支持sendfile()系统调用,但2.6内核已经不再支持;对Solaris8的早期版本,则需要安装补丁)。在支持sendfile的系统中,Apache2可以更快地发送静态内容而且占用较少的CPU时间。

    运行时的配置

    相关模块

    相关指令

    HostnameLookups 和其他DNS考虑

    Apache1.3以前的版本中,HostnameLookups默认被设为 On 。它会带来延迟,因为对每一个请求都需要作一次DNS查询。在Apache1.3中,它被默认地设置为 Off 。如果需要日志文件提供主机名信息以生成分析报告,则可以使用日志后处理程序logresolve ,以完成DNS查询,而客户端无须等待。

    推荐你最好是在其他机器上,而不是在web服务器上执行后处理和其他日志统计操作,以免影响服务器的性能。

    如果你使用了任何"Allow from domain""Deny from domain"指令(也就是domain使用的是主机名而不是IP地址),则代价是要进行两次DNS查询(一次正向和一次反向,以确认没有作假)。所以,为了得到最高的性能,应该避免使用这些指令(不用域名而用IP地址也是可以的)

    注意,可以把这些指令包含在<Location /server-status>段中使之局部化。在这种情况下,只有对这个区域的请求才会发生DNS查询。下例禁止除了.html.cgi以外的所有DNS查询:

    HostnameLookups off
    <Files ~ "\.(html|cgi)$">
    HostnameLookups on
    </Files>

    如果在某些CGI中偶尔需要DNS名称,则可以调用gethostbyname来解决。

    FollowSymLinks SymLinksIfOwnerMatch

    如果网站空间中没有使用 Options FollowSymLinks ,或使用Options SymLinksIfOwnerMatch Apache就必须执行额外的系统调用以验证符号连接。文件名的每一个组成部分都需要一个额外的调用。例如,如果设置了:

    DocumentRoot /www/htdocs
    <Directory />
    Options SymLinksIfOwnerMatch
    </Directory>

    在请求"/index.html"时,Apache将对"/www""/www/htdocs""/www/htdocs/index.html"执行lstat()调用。而且lstat()的执行结果不被缓存,因此对每一个请求都要执行一次。如果确实需要验证符号连接的安全性,则可以这样:

    DocumentRoot /www/htdocs
    <Directory />
    Options FollowSymLinks
    </Directory>

    <Directory /www/htdocs>
    Options -FollowSymLinks +SymLinksIfOwnerMatch
    </Directory>

    这样,至少可以避免对DocumentRoot路径的多余的验证。注意,如果AliasRewriteRule中含有DocumentRoot以外的路径,那么同样需要增加这样的段。为了得到最佳性能,应当放弃对符号连接的保护,在所有地方都设置FollowSymLinks ,并放弃使用SymLinksIfOwnerMatch

    AllowOverride

    如果网站空间允许覆盖(通常是用.htaccess文件),则Apache会试图对文件名的每一个组成部分都打开.htaccess ,例如:

    DocumentRoot /www/htdocs
    <Directory />
    AllowOverride all
    </Directory>

    如果请求"/index.html",则Apache会试图打开"/.htaccess""/www/.htaccess""/www/htdocs/.htaccess"。其解决方法和前面所述的 Options FollowSymLinks 类似。为了得到最佳性能,应当对文件系统中所有的地方都使用 AllowOverride None

    内容协商

    实践中,内容协商的好处大于性能的损失,如果你很在意那一点点的性能损失,则可以禁止使用内容协商。但是仍然有个方法可以提高服务器的速度,就是不要使用通配符,如:

    DirectoryIndex index

    而使用完整的列表,如:

    DirectoryIndex index.cgi index.pl index.shtml index.html

    其中最常用的应该放在前面。

    还有,建立一个明确的type-map文件在性能上优于使用"Options MultiViews",因为所有需要的信息都在一个单独的文件中,而无须搜索目录。请参考内容协商文档以获得更详细的协商方法和创建type-map文件的指导。

    内存映射

    Apache2.0需要搜索被发送文件的内容时,比如处理服务器端包含时,如果操作系统支持某种形式的mmap() ,则会对此文件执行内存映射。

    在某些平台上,内存映射可以提高性能,但是在某些情况下,内存映射会降低性能甚至影响到httpd的稳定性:

    • 在某些操作系统中,如果增加了CPUmmap还不如read()迅速。比如,在多处理器的Solaris服务器上,关闭了mmap Apache2.0传送服务端解析文件有时候反而更快。
    • 如果你对作为NFS装载的文件系统中的一个文件进行了内存映射,而另一个NFS客户端的进程删除或者截断了这个文件,那么你的进程在下一次访问已经被映射的文件内容时,会产生一个总线错误。

    如果有上述情况发生,则应该使用 EnableMMAP off 关闭对发送文件的内存映射。注意:此指令可以被针对目录的设置覆盖。

    Sendfile

    Apache2.0能够忽略将要被发送的文件的内容的时候(比如发送静态内容),如果操作系统支持sendfile() ,则Apache将使用内核提供的sendfile()来发送文件。译者注:Linux2.4内核支持sendfile()系统调用,但2.6内核已经不再支持。

    在大多数平台上,使用sendfile可以通过免除分离的读和写操作来提升性能。然而在某些情况下,使用sendfile会危害到httpd的稳定性

    • 一些平台可能会有Apache编译系统检测不到的有缺陷的sendfile支持,特别是将在其他平台上使用交叉编译得到的二进制文件运行于当前对sendfile支持有缺陷的平台时。
    • 对于一个挂载了NFS文件系统的内核,它可能无法可靠的通过自己的cache服务于网络文件。

    如果出现以上情况,你应当使用"EnableSendfile off"来禁用sendfile 。注意,这个指令可以被针对目录的设置覆盖。

    进程的建立

    Apache1.3以前,MinSpareServers, MaxSpareServers, StartServers的设置对性能都有很大的影响。尤其是为了应对负载而建立足够的子进程时,Apache需要有一个"渐进"的过程。在最初建立StartServers数量的子进程后,为了满足MinSpareServers设置的需要,每一秒钟只能建立一个子进程。所以,对一个需要同时处理100个客户端的服务器,如果StartServers使用默认的设置5,则为了应对负载而建立足够多的子进程需要95秒。在实际应用中,如果不频繁重新启动服务器,这样还可以,但是如果仅仅为了提供10分钟的服务,这样就很糟糕了。

    "一秒钟一个"的规定是为了避免在创建子进程过程中服务器对请求的响应停顿,但是它对服务器性能的影响太大了,必须予以改变。在Apache1.3中,这个"一秒钟一个"的规定变得宽松了,创建一个进程,等待一秒钟,继续创建第二个,再等待一秒钟,继而创建四个,如此按指数级增加创建的进程数,最多达到每秒32个,直到满足MinSpareServers设置的值为止。

    从多数反映看来,似乎没有必要调整MinSpareServers, MaxSpareServers, StartServers 。如果每秒钟创建的进程数超过4个,则会在ErrorLog中产生一条消息,如果产生大量此消息,则可以考虑修改这些设置。可以使用mod_status的输出作为参考。

    与进程创建相关的是由MaxRequestsPerChild引发的进程的销毁。其默认值是"0",意味着每个进程所处理的请求数是不受限制的。如果此值设置得很小,比如30,则可能需要大幅增加。在SunOS或者Solaris的早期版本上,其最大值为10000以免内存泄漏。

    如果启用了持久链接,子进程将保持忙碌状态以等待被打开连接上的新请求。为了最小化其负面影响,KeepAliveTimeout的默认值被设置为5秒,以谋求网络带宽和服务器资源之间的平衡。在任何情况下此值都不应当大于60秒,参见most of the benefits are lost

    编译时的配置

    选择一个MPM

    Apache 2.x 支持插入式并行处理模块,称为多路处理模块(MPM)。在编译Apache时你必须选择也只能选择一个MPM,这里有几个针对非UNIX系统的MPMbeos, mpm_netware, mpmt_os2, mpm_winnt。对类UNIX系统,有几个不同的MPM可供选择,他们都会影响到httpd的速度和可伸缩性:

    • workerMPM使用多个子进程,每个子进程中又有多个线程。每个线程处理一个请求。该MPM通常对高流量的服务器是一个不错的选择。因为它比preforkMPM需要更少的内存且更具有伸缩性。
    • preforkMPM使用多个子进程,但每个子进程并不包含多线程。每个进程只处理一个链接。在许多系统上它的速度和workerMPM一样快,但是需要更多的内存。这种无线程的设计在某些情况下优于workerMPM:它可以应用于不具备线程安全的第三方模块(比如php3/4/5),且在不支持线程调试的平台上易于调试,而且还具有比workerMPM更高的稳定性。

    关于MPM的更多内容,请参考其文档

    模块

    既然内存用量是影响性能的重要因素,你就应当尽量去除你不需要的模块。如果你将模块编译成DSO ,取消不必要的模块就是一件非常简单的事情:注释掉LoadModule指令中不需要的模块。

    如果你已经将模块静态链接进Apache二进制核心,你就必须重新编译Apache并去掉你不想要的模块。

    增减模块牵涉到的一个问题是:究竟需要哪些模块、不需要哪些模块?这取决于服务器的具体情况。一般说来,至少要包含下列模块:mod_mime, mod_dir, mod_log_config 。你也可以不要mod_log_config ,但是一般不推荐这样做。

    原子操作

    一些模块,比如mod_cacheworker使用APR(Apache可移植运行时)的原子API。这些API提供了能够用于轻量级线程同步的原子操作。

    默认情况下,APR在每个目标OS/CPU上使用其最有效的特性执行这些操作。比如许多现代CPU的指令集中有一个原子的比较交换(compare-and-swap, CAS)操作指令。在一些老式平台上,APR默认使用一种缓慢的、基于互斥执行的原子API以保持对没有CAS指令的老式CPU的兼容。如果你只打算在新式的CPU上运行Apache,你可以在编译时使用 --enable-nonportable-atomics 选项:

    ./buildconf
    ./configure --with-mpm=worker --enable-nonportable-atomics=yes
    查看(1057) 评论(0) 收藏 分享 管理

  • apache httpd相关

    2008-02-14 14:23:09

    lsof |grep apache

    Apache是运行在Linux操作系统上的头号Web服务器。很多小地方都可以用来调整Apache的性能,并降低它对系统资源的影响。其中一个就是调整内存使用率,当然达到这一目的可能还是需要花点功夫的。

    例如,通过ps来确定httpd线程的内存使用率,可以输入下面的命令:

    # ps -U apache -u apache u
    USERPID %CPU %MEMVSZRSS TTYSTAT START TIME COMMAND
    apache130670.05.3 149704 54504 ?SOct071:53 /usr/sbin/httpd -f /etc/httpd/conf/httpd.conf -DAPACHE2
    ...

    上面这段输出显示了单个httpd进程使用了50 MB的RSS(驻留集大小)内存(或者非交换物理内存),以及149 MB的VSZ(虚拟)内存。这当然在很大程度上取决于你在Apache里加载和运行的模块数量。这决不是一个固定的数字。由于这个数字里还包含了共享库包,所以不是100%的准确。我们可以认为RSS数字的一半是httpd线程真正使用的内存数,这可能还有点保守,但是离我们的目的已经非常接近了。

    在本文里,我们假设每个httpd进程都在使用了27 MB内存。然后,你需要确定可以让httpd真正使用的内存数。根据运行在机器上的其他进程,你可能希望要求50%的物理内存都供Apache使用。在一个装有1GB内存的系统上,就有512MB的内存可以被划分为多个27MB的内存,也就是大约19个并发的httpd内存。有些人坚持认为每个httpd 线程“真正”使用大约5MB的内存,所以从理论上讲你可以把512MB的内存划分出102个并发进程供Apache使用(要记住的是,除非你的网站需要极其巨大的流量,否则这种情况是非常罕见的)。

    在默认状态下,Apache会分配最大256个并发客户端连接,或者256个进程(每一个都对应一个请求)。按照这种设置,一个流量巨大的网站会在顷刻间崩溃(即使你假设每个进程占用5MB内存,那也需要1.3GB的内存来满足请求的数量)。如果不采取其它措施,系统会通过硬盘来尝试使用交换空间以处理它无法在物理内存中完成的任务。

    其他可以调整的项目包括KeepAlive、KeepAliveTimeout和MaxKeepAliveRequests等设置。可以放在httpd.conf文件里的推荐设置有:

    ServerLimit 128MaxClients 128KeepAlive OnKeepAliveTimeout 2MaxKeepAliveRequests 100

    通过将KeepAliveTimeout从15秒减到2秒,可以增加MaxClients命令;19太小,而128要好得多。通过减少进程存活的秒数,你可以在相同的时间内允许更多的连接。

    当然,如果没有真正的测试在背后支持,数字就是毫无意义的,这就是ab的作用之所在。使用ab对Apache配置文件(MaxClients等于 256、ServerLimit等于256、KeepAliveTimeout等于15)进行调整,使其能够满足1000个请求(100个连续请求并发产生)的调整方法如下。(在执行测试的时候要确保服务器上有一个终端打开以观察系统的负载。)

    $ ab -n 1000 -c 100 -k http://yoursite.com/index.php

    现在把上面的服务器设置改为更加保守的设置,重新启动Apache,试着再次测试(总是从远程计算机上进行,而不是本机)。

    在这里的测试中,不同的设置导致执行所消耗的时间产生了一倍的差距(分别为27.8s和16.8s),但是负载的平均值为0.03和0.30。这可能会使得你的网站变得稍慢,但是会确保它不会在高负载的情况下崩溃。还要记住的是,你将需要进行多次测试,以便取得一个平均值。

    使用ab是测试调整Apache配置的一个极佳方法,应该在你每次做出影响性能的更改时使用它。

  • 配置工具CVS学习笔记(转)

    2007-09-14 18:05:02

    一、CVS部署

         总体操作流程:

                (1)    在服务器端和客户端安装CVS软件,创建仓库;

                (2)   crypt创建用户(其中一个是管理员);

                (3)   用系统用户Admin登录取出CVSRoot目录(客户端进行);

                (4)   在服务器的CVSRoot中增加passwdgroup文件并写入相关信息(服务器端进行);

                (5)   在取出的CVSRoot中修改config文件并提交(客户端);

                (6)   在服务器的CVSRoot增加.owner.perms并修改(服务器端完成)[若为cvsnt2.5版本,则更改CVSRoot\cvs\ fileattr.xml文件,改为新的管理员名称]

                (7)   用新管理员登录(客户端);

                (8)   删除Admin取出来的CVSRoot目录­(客户端完成);

                (9)   用新管理员登录取出CVSRoot目录,增加admin文件commit,修改checkoutlist文件并commit

                (10) 在服务器端增加history文件,[cvsnt2.5版本才要执行此步],为使用cvstracnt作准备.

                (11)用新管理员创建新模块(客户端进行);

                (12)  设置用户权限;

                (13)  进入使用。

     

          1.环境配置

     

            1.1   服务器端

            1)、安装CVSNT,http://61.143.38.136:8383下载CVSNT-2.0.4 CVSNT-2.0.51(本次安装实例是使用2.0.51版本)。安装完成后(选择Full Install,其它按照默认安装),重启(必须重启),此时右击“我的电脑——管理”,打开“计算机管理”窗口,选择“服务和应用程序——服务”,右边的服务控制器中多了2个服务:cvsntcvslocking

            2)、安装完成后可通过在Windows控制台(cmd)中任意位置执行cvs/cvs.exe来检验是否安装成功。在开始菜单中选择“运行”,输入“cmd”,在弹出的命令提示窗中输入CVSCVS.exe,出现CVS相关信息就表示安装成功。

             3)、在开始菜单中把“Service Control Panel”发送到桌面。不发送也可以。

     

    1.2客户端

    在客户端直接安装TortoiseCVS即可。

     

    1.3创建CVSNT仓库

    服务器端与客户端的安装完成后,就可创建CVSNT仓库。步骤如下:

    1)、运行“Service Control Panel”,在Service Status页面,确认2个服务(cvsntcvslocking)正常和稳定运行。

    2)、选择Repository页面,如下图:

    3)、单击“Add”添加要创建仓库的路径,其中“Location”是指创建仓库的路径。

    4)、选择Advanced页面,勾上【Use local users for pserver authentication instead of domain users】(这是让CVSNT使用本地账户作为pserver认证方式),Temporary栏选择存放临时文件(cookies)的文件夹,确认。

    5)、创建完成后,在【F:\CVStest】下面自动创建了【CVSROOT】目录,这是CVS默认的管理目录(默认模块),仓库创建成功。如果报错,那是系统Path路径未设置正确。

     

    2.  创建用户

    CVS通过Crypt来创建和编辑用户。

    注释: crypt是个密码加密函数,它是基于Data Encryption Standard(DES)演算法。crypt基本上是One way encryption,因此它只适用于密码的使用,不适合于资料加密。 

    21新增用户(其中一个是管理员)

    1)、在开始菜单选择“运行”,输入“cmd”,在弹出的窗口中输入“cd(dos命令)  F:\cryptcrypt存放的路径)”按回车键;

    2)、然后再输入“F:”按回车;

    3)、开始创建用户,输入“crypt(命令) user_A(用户名) abc123(用户密码)”按回车,系统自动生成一个加密的暗码。如图:

    4)、将创建的用户信息及产生的暗码按“用户名:暗码:NT上创建的新用户组:用户密码”的顺序记录下来(便于在以后的passwd文件中使用)。

    按以上方法继续创建所需的用户。

     

    22修改用户

    步骤如下:

    前两步跟新增用户相同;若要修改密码,直接改密码即可,如修改用户user_A的密码“crypt user_A 234回车即可;若要修改用户名,其实是删除用户user_A后再新增用户user_B

    同样的,修改后也要把相关的信息(用户名:暗码:用户密码)记录下来(同时在passwd文件中作相应的修改)。

     

    23删除用户

    1)、利用windows自带的搜索功能搜索出所有passwdgroup文件;

    2)、将该用户在passwdgroup文件中存放的用户和密码字符串逐一删除。

     

    3.  用系统用户Administrator登录取出CVSRoot目录(客户端进行)

      

    4.  设置passwdgroup文件

    1)、在cvsroot文件夹中增加passwdgroup两个文件;

    2)、将已建立的用户与密码信息,写入在passwd中,按“用户名:暗码:NT上创建的新用户组:用户密码”的顺序输入。

    3)、group的作用是分组,为更好地设置权限,有相同权限的用户可以放在同一组,如开发人员可能同一组,项目经理为一组,管理员为一组。录入的方式为“组名:用户名1 用户名2 用户名3…,每行为一组.若不要组名,只写用户名,则表示没有对用户进行分组。(不建议这样去做,因为这样做会导致在设置权限时出现混乱,不便于管理,特别是用户多的时候。)

    写入后保存,设置成功。

     

    5.  权限配置

    5.1 CVS中目录权限介绍

     系统支持的目录权限列表:

     r  (读取权限)     c (创建和删除权限)

     w  (写入权限)     n (没有任何权限)

     默认情况下,任何用户都拥有任何目录的所有权限。

     任何情况下只有目录的拥有者和Administrator才有权力更改目录的使用权限。

     

    5.2权限设置

    举例说明(部署流程)

    【『例子』:产品A

    库权限需求说明

    1)        【产品A】是项目名称;

    2)        在项目名称为根目录,且根目录下有三大子目录:01开发库、02基线库、03<SPAN style="FONT-SIZE: 10pt; FONT-FAMILY: 宋体; mso-ascii-font-famil

  • 几个在VB中调用系统程序的例子

    2007-07-06 17:49:39

    原创]几个在VB中调用系统程序的例子

    调用windows系统图标
    [.ShellClassInfo]
    IconFile=%SystemRoot%\system32\shell32.dll
    IconIndex=-173
    LocalizedResourceName=@shell32.dll,-12693
    收藏夹的五角星图标就是这么调用的

    获得vb当前路径:
    curdir是当前目录,app.path是程序运行的路径,两者是不同的

    调用当前目录下的帮助文件
    Dim path As String
    path = Trim(App.path)
    Shell "c:\windows\hh.exe " & path & "/ca.chm", vbMaximizedFocus

    调用系统服务管理器
    Shell "mmc.exe " & Environ("windir") & "\system32\services.msc"

    调用系统数据源管理器
    Shell Environ("windir") & "\system32\odbcad32.exe"

    调用windows网络连接窗口
    Shell "RunDLL32.EXE   shell32.dll,Control_RunDLL   ncpa.cpl"

  • 什么是weblogic?

    2007-06-25 09:15:40

    BEA WebLogic是用于开发、集成、部署和管理大型分布式Web应用、 网络应用和数据库应
    用的Java应用服务器。将Java的动态功能和Java Enterprise标准的安全性引入大型网络应用的
    开发、集成、部署和管理之中。
    BEA WebLogic Server拥有处理关键Web应用系统问题所需的性能 、可扩展性和高可用性。
    与BEA WebLogic Commerce ServerTM配合使用, BEA WebLogic Server可为部署适应性个性化
    电子商务应用系统提供完善的解决方案。
    BEA WebLogic Server具有开发和部署关键任务电子商务Web应用系统 所需的多种特色和优
    势,包括:
    1)领先的标准
    对业内多种标准的全面支持,包括EJB、JSB、JMS、JDBC、XML和WML,使Web应用系统的实
    施更为简单,并且保护了投资,同时也使基于标准的解决方案的开发更加简便。
    2)无限的可扩展性
    BEA WebLogic Server以其高扩展的架构体系闻名于业内,包括客户机连接的共享、资源
    pooling以及动态网页和EJB组件群集。
    3)快速开发
    凭借对EJB和JSP的支持,以及BEA WebLogic Server 的Servlet组件架 构体系,可加速投
    放市场速度。这些开放性标准与WebGain Studio配 合时,可简化开发,并可发挥已有的技能,
    迅速部署应用系统。
    4)部署更趋灵活
    BEA WebLogic Server的特点是与领先数据库、操作系统和Web服务器 紧密集成。
    5)关键任务可靠性
    其容错、系统管理和安全性能已经在全球数以千记的关键任务环境中得以验证。
    6)体系结构
    BEA WebLogic Server是专门为企业电子商务应用系统开发的。企业电 子商务应用系统需
    要快速开发,并要求服务器端组件具有良好的灵活性和安全性,同时还要支持关键任务所必需
    的扩展、性能、和高可用性。BEA WebLogic Server简化了可移植及可扩展的应用系统的开发,
    并为其它应用 系统和系统提供了丰富的互操作性。
    凭借其出色的群集技术,BEA WebLogic Server拥有最高水平的可扩展 性和可用性。BEA
    WebLogic Server既实现了网页群集,也实现了EJB组件 群集,而且不需要任何专门的硬件或
    操作系统支持。网页群集可以实现透明的复制、负载平衡以及表示内容容错,如Web购物车;
    组件群集则处理复杂的复制、负载平衡和EJB组件容错,以及状态对象(如EJB实体)的恢复。
    无论是网页群集,还是组件群集,对于电子商务解决方案所要求的可扩展性和可用性都是至关
    重要的。共享的客户机/服务器和数据库连接以及数据缓存和EJB都增强了性能表现。这是其它
    Web应用系统所不具备的。
  • 基本排序的几种算法总结

    2007-06-14 11:42:31

    基本排序的几种算法总结

    字体:        | 上一篇 下一篇 | 打印

    #include <stdio.h>
    #include <time.h>
    #include<stdlib.h>
    #include<dos.h>
    #define n 10000
    typedef int keytype;
    typedef struct{
        keytype key;
      }rectype;//待排序的文件的记录类型
    typedef rectype seqlist[n+1];
    seqlist r;
    int m;
    main()//主程序
      {
      int i,j;

      //选择一种数据输入形式
      printf("1---random data\n");
      printf("2---inscre data\n");
      printf("3---descre data\n");
      printf("4---input data\n");
      scanf("%d",&j);
      if (j==1) randoming();//产生一组随机数据

      if (j==2)//产生一组递增序列
       for (m=1;m<=n;m++)
        r[m].key=m;

      if (j==3)//产生一组递减序列
       for(m=1;m<=n;m++)
        r[m].key=n-m+1;

      if (j==4){//由用户自己输入数据序列,设这组数据中不含0,以0作为结束
        printf("please input the sort data:(end of 0)\n");
        r[0].key=1;
        m=0;
        while((m<=n)&&(r[m].key)){
          m++;
          scanf("%d",&(r[m].key));
         }//end of while
        m--;
       }//end of if

      printf("1-----insertsort\n");
      printf("2-----bubblesort\n");
      printf("3-----selectsort\n");
      printf("4-----quicksort\n");
      printf("5-----heapsort\n");
      scanf("%d",&j);

      //输出排序前的序列
      printf("the source data:\n");
      for(i=1;i<=m;i++)
       printf("%d ",r[i].key);
      printf("\n");

      //选择一种方法进行排序
      if (j==1) insertsort(m);//直接插入排序
      if (j==2) bubblesort(m);//冒泡排序
      if (j==3) selectsort(m);//直接选择排序
      if (j==4) quicksort(1,m);//快速排序
      //if (j==5) heapsort(m);//堆排序

      //以下输出排序结果
      printf("the answer data:\n");
      for(i=1;i<=m;i++)
        printf("%d ",r[i].key);
     }//end of main


     insertsort(int m)
      {//直接插入排序
       int i,j;
       for(i=2;i<=m;i++)
        if (r[i].key<r[i-1].key){
          r[0].key=r[i].key;j=i-1;
          do{
             r[j+1].key=r[j].key;
             j--;
           }while (r[0].key<r[j].key);
          r[j+1].key=r[0].key;
         }//end of if
      }//end of insertsort

     bubblesort(int m){
       //冒泡排序
       int i,j;
       int exchange;
       for(i=1;i<m;i++){
         exchange=0;//设置未交换过标记
         for(j=m-1;j>=1;j--)
          if(r[j+1].key<r[j].key){//若逆序
            r[0].key=r[j+1].key;//以r[0]为辅助空间交换
            r[j+1].key=r[j].key;
            r[j].key=r[0].key;
            exchange=1;//设置做过交换标志
           }//end of if
         if (!exchange) return;
        }//end of for
      }//end of bubblesort

     selectsort(int m)
       {//直接选择排序
        int i,j,k;
        for(i=1;i<m;i++){
          k=i;
          for(j=i+1;j<=m;j++)//在无序区r[j..m]中查找最小关键字位置k
           if(r[j].key<r[k].key)
             k=j;
          if (k!=i){//若k<>i,则交换,扩大有序区
            r[0].key=r[i].key;
            r[i].key=r[k].key;
            r[k].key=r[0].key;
           }//end of if
         }//end of for
       }//end of selectsort

     quicksort(int low,int high)
      {//对r[low..high]进行快速排序
       int pivotpos;
       if(low<high){
        pivotpos=partition(low,high);//对r[low..high]进行一次快速排序,
                //以pivotpos为划分点,分成两个无序区r[low..pivotpos-1]和r[pivotpos+1..high]
            quicksort(low,pivotpos-1);//对r[low..pivotpos-1]进行快速排序
         quicksort(pivotpos+1,high);//对r[pivotpos+1..high]进行快速排序
        }//end of if
        }//end of quicksort
Open Toolbar