Java新知识系列 七

    1. 抽象类和接口的区别和特点
    2. java的JDK中包含的五个工具
    3. 编译型语言和解释型语言
    4. Java和C++的区别`
    5. 常见的ASCII的值
    6. Forward和Redirect之间的对比
    7. Web Service 概念和特点
    8. Servlert包源码的解析
    9. java中GC的触发条件
    10. Ant和Maven构建工具的理解
     
    []抽象类和接口的区别和特点
    区别1:抽象类体现继承关系,一个类只能単继承。接口体现实现关系,一个类可以多实现。
    区别2:抽象类中可以定义非抽象方法和抽象方法,子类继承后可以直接使用非抽象方法。接口的方法都 是抽象的,必须由子类去实现。接口中的成员都有固定的修饰符。
    区别3:抽象类有构造方法,用于给子类对象初始化。而接口没有构造方法。
    特点1:抽象类不可以实例化,即不能用new创建对象。抽象类必须由其子类覆盖了所有的抽象方法后,该子类才可以实例化,否则,这个子类也是抽象类。
    特点2:抽象类abstract关键字不能和哪些关键字共存:
    final 因为final修饰的方法不能被继承。
    static因为类.方法(),此方法没有方法体,没有意义。
    private 因为抽象方法是要被子类覆盖的,加上private子类就不知道这个方法了。
    特点3:接口中声明变量必须是final、public 、static的,接口中定义的方法都是abstract、public的。接口里的数据成员必须初始化,且全是常量,不是变量。
    特点4:接口是抽象类的 变体( 你没看错 ), 接口也可以通过关键字extends来继承其他接 口。格式如下所示:
    1.   class 类名称 implements 接口A,接口B{   //接口的实现}
    2.    interface 子接口名称 extends 父接口1,父接口2,...{}
    []java的JDK中包含的五个工具
    1. javac.exe是编译.java文件
    2. java.exe是执行编译好的.class文件
    3. javadoc.exe是生成Java说明文档
    4. jdb.exe是Java调试器
    5. javaprof.exe是剖析工具
     
    []编译型语言和解释型语言
    编译型语言和解释性语言:编译型语言在程序执行之前,先会通过编译器对程序执行一个编译的过程,把程序转变成机器语言。运行时就不需要翻译,而直接执行就可以了。最典型的例子就是C语言。
    解释型语言就没有这个编译的过程,而是在程序运行的时候,通过解释器对程序逐行作出解释,然后直接运行,最典型的例子是Ruby。但是,随着Java等基于虚拟机的语言的兴起,我们又不能把语言纯粹地分成解释型和编译型这两种,用Java来举例,Java首先是通过编译器编译成字节码文件,然后在运行时通过解释器给解释成机器文件。所以我们说Java是一种先编译后解释的语言。
     
    []Java和C++的区别
    1. Java是解释型语言,所谓的解释型语言,就是源码会先经过一次编译,成为中间码,中间码再被解释器解释成机器码。对于Java而言,中间码就是字节码(.class),而解释器在JVM中内置了。
    2. C++是编译型语言,所谓编译型语言,就是源码一次编译,直接在编译的过程中链接了,形成了机器码。
    3. C++比Java执行速度快,但是Java可以利用JVM跨平台。
    4. Java是纯面向对象的语言,所有代码(包括函数、变量)都必须在类中定义。而C++中还有面向过程的东西,比如是全局变量和全局函数。
    5. C++中有指针,Java中没有,但是有引用。
    6. C++支持多继承,Java中类都是单继承的。但是继承都有传递性,同时Java中的接口是多继承,类对接口的实现也是多实现。
    7. C++中,开发需要自己去管理内存,但是Java中JVM有自己的GC机制,虽然有自己的GC机制,但是也会出现OOM和内存泄漏的问题。C++中有析构函数,Java中Object的finalize方法
    8. C++运算符可以重载,但是Java中不可以。同时C++中支持强制自动转型,Java中不行,会出现ClassCastException(类型不匹配)。
     
    []常见的ASCII的值
    空格的ASCII码值为32;
    数字0到9的ASCII码值分别为48到57;
    大写字母“A”到“Z”的ASCII码值分别为65到90;
    小写字母“a”到“z”的ASCII码值分别为97到到122。
     
    []Forward和Redirect之间的对比
    1.从地址栏显示来说
    forward是服务器请求资源,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,然后把这些内容再发给浏览器.浏览器根本不知道服务器发送的内容从哪里来的,所以它的地址栏还是原来的地址.
    redirect是服务端根据逻辑,发送一个状态码,告诉浏览器重新去请求那个地址.所以地址栏显示的是新的URL.
    2.从数据共享来说
    forward:转发页面和转发到的页面可以共享request里面的数据.
    redirect:不能共享数据.
    3.从运用地方来说
    forward:一般用于用户登陆的时候,根据角色转发到相应的模块.
    redirect:一般用于用户注销登陆时返回主页面和跳转到其它的网站等.
    4.从效率来说
    forward:高.
    redirect:低.
     
    []Web Service 概念和特点
    Web service顾名思义是基于web的服务,它是一种跨平台,跨语言的服务。
    我们可以这样理解它,比如说我们可以调用互联网上查询天气信息的web服务,把它嵌入到我们的B/S程序中,当用户从我们的网点看到天气信息时,会认为我们为他提供很多的服务,但其实我们什么也没做,只是简单的调用了一下服务器上的一端代码而已。Web service 可以将你的服务发布到互联网上让别人去调用,也可以调用别人发布的web service,和使用自己的代码一样。
    1. 它是一种跨平台,跨语言的服务。
    2. 它是采用XML传输格式化的数据,
    3. 它的通信协议是SOAP(简单对象访问协议)
     
    []Servlert包源码的解析
    javax.servlet 包中包含了 7 个接口 ,3 个类和 2 个异常类 , 它们分别是 :
    接口 :RequestDispatcher,Servlet,ServletConfig,ServletContext,ServletRequest,ServletResponse 和 SingleThreadModel
    类 :GenericServlet,ServletInputStream 和 ServletOutputStream
    异常类 :ServletException 和 UnavailableException
    Servlet 的生命周期
    在 Servlet 的接口中定义了一个 Servlet 的生命周期方法 , 分别是 Init,Service 和 Destroy
    演示了 Servlet 生命周期方法的简单 Servlet:
    import javax.servlet.*;
    import java.io.IOException;
    public class PrimitiveServlet implements Servlet {
      public void init(ServletConfig config) throws ServletException {
        System.out.println("init");
      }
    public void service(ServletRequest request, ServletResponse response)
        throws ServletException, IOException {
        System.out.println("service");
      }  
      public void destroy() {
        System.out.println("destroy");
      }
      public String getServletInfo() {
        return null;
      }
      public ServletConfig getServletConfig() {
        return null;
      }
    }
    View Code
    在 Servlet 中如何获取 ServletConfig 对象 ?
    在 Servlet 的 Init 方法中 ,Servlet Container 将会传入一个 ServletConfig 对象 , 开发人员可以通过这个对象获取在 web.xml 文件中定义的 Servlet 初始化参数 .
    下面是一个获取 Servlet 初始参数的示例 :
    import javax.servlet.*;
    import java.util.Enumeration;
    import java.io.IOException;
    public class ConfigDemoServlet implements Servlet {
      public void init(ServletConfig config) throws ServletException {
        Enumeration parameters = config.getInitParameterNames();
        while (parameters.hasMoreElements()) {
          String parameter = (String) parameters.nextElement();
          System.out.println("Parameter name : " + parameter);
          System.out.println("Parameter value : " +
            config.getInitParameter(parameter));
        }
      }
      public void destroy() {
      }
      public void service(ServletRequest request, ServletResponse response)
        throws ServletException, IOException {
      }
      public String getServletInfo() {
        return null;
      }
      public ServletConfig getServletConfig() {
        return null;
      }
    }
    View Code
    如何获取 ServletContext 对象 ?
    可以通过 ServletConfig 对象的 getServletContext 方法获取 ServletContext 对象
    import javax.servlet.*;
    import java.util.Enumeration;
    import java.io.IOException;
    public class ContextDemoServlet implements Servlet {
      ServletConfig servletConfig;
      public void init(ServletConfig config) throws ServletException {
        servletConfig = config;
      }
      public void destroy() {
      }
      public void service(ServletRequest request, ServletResponse response)
        throws ServletException, IOException {
        ServletContext servletContext = servletConfig.getServletContext();
        Enumeration attributes = servletContext.getAttributeNames();
        while (attributes.hasMoreElements()) {
          String attribute = (String) attributes.nextElement();
          System.out.println("Attribute name : " + attribute);
          System.out.println("Attribute value : " +
            servletContext.getAttribute(attribute));
        }
        System.out.println("Major version : " +
    servletContext.getMajorVersion());
        System.out.println("Minor version : " +
    servletContext.getMinorVersion());
        System.out.println("Server info : " + servletContext.getServerInfo());
      }
      public String getServletInfo() {
        return null;
      }
      public ServletConfig getServletConfig() {
        return null;
      }
    }
    View Code
    如何在 Servlet 之间共享信息 ?
    我们可以通过 ServletContext 来维护在不同 Servlet 之间共享的信息 .
    如何解决 Servlet 的多 Thread 问题 ?
    如果 Servlet 需要读写外部资源 , 我们需要考虑 Thread 的问题 , 我们可以使用声明性接口 SingleThreadModel 来避免多 Thread 之间的资源冲突问题 . 但是需要注意的是 , 如果 Servlet 仅仅只是读外部资源的话 , 我们通常不应该实现这个接口 . 如果实现这个接口 ,Servlet 在同一时刻只能服务一个用户请求 , 后至的用户请求必须在队列中等待
     
    []java中GC的触发条件
    先备知识:
    年轻代的GC 叫 young GC ,有时候也叫  minor GC 。年老代或者永久代的 GC ,叫  full GC ,也叫 major GC 。
     
    full GC触发的条件
    除直接调用System.gc外,触发Full GC执行的情况有如下四种
    1. 旧生代空间不足
    旧生代空间只有在新生代对象转入及创建为大对象、大数组时才会出现不足的现象,当执行Full GC后空间仍然不足,则抛出如下错误:
    java.lang.OutOfMemoryError: Java heap space 
    为避免以上两种状况引起的FullGC,调优时应尽量做到让对象在Minor GC阶段被回收、让对象在新生代多存活一段时间及不要创建过大的对象及数组。
    2. Permanet Generation空间满
    PermanetGeneration中存放的为一些class的信息等,当系统中要加载的类、反射的类和调用的方法较多时,Permanet Generation可能会被占满,在未配置为采用CMS GC的情况下会执行Full GC。如果经过Full GC仍然回收不了,那么JVM会抛出如下错误信息:
    java.lang.OutOfMemoryError: PermGen space 
    为避免Perm Gen占满造成Full GC现象,可采用的方法为增大Perm Gen空间或转为使用CMS GC。
    3. CMS GC时出现promotion failed和concurrent mode failure
    对于采用CMS进行旧生代GC的程序而言,尤其要注意GC日志中是否有promotion failed和concurrent mode failure两种状况,当这两种状况出现时可能会触发Full GC。
    promotionfailed是在进行Minor GC时,survivor space放不下、对象只能放入旧生代,而此时旧生代也放不下造成的;concurrent mode failure是在执行CMS GC的过程中同时有对象要放入旧生代,而此时旧生代空间不足造成的。
    应对措施为:增大survivorspace、旧生代空间或调低触发并发GC的比率,但在JDK 5.0+、6.0+的版本中有可能会由于JDK的bug29导致CMS在remark完毕后很久才触发sweeping动作。对于这种状况,可通过设置-XX:CMSMaxAbortablePrecleanTime=5(单位为ms)来避免。
    4. 统计得到的Minor GC晋升到旧生代的平均大小大于旧生代的剩余空间
    这是一个较为复杂的触发情况,Hotspot为了避免由于新生代对象晋升到旧生代导致旧生代空间不足的现象,在进行Minor GC时,做了一个判断,如果之前统计所得到的Minor GC晋升到旧生代的平均大小大于旧生代的剩余空间,那么就直接触发Full GC。
    例如程序第一次触发MinorGC后,有6MB的对象晋升到旧生代,那么当下一次Minor GC发生时,首先检查旧生代的剩余空间是否大于6MB,如果小于6MB,则执行Full GC。
    当新生代采用PSGC时,方式稍有不同,PS GC是在Minor GC后也会检查,例如上面的例子中第一次Minor GC后,PS GC会检查此时旧生代的剩余空间是否大于6MB,如小于,则触发对旧生代的回收。
    除了以上4种状况外,对于使用RMI来进行RPC或管理的Sun JDK应用而言,默认情况下会一小时执行一次Full GC。可通过在启动时通过- java-Dsun.rmi.dgc.client.gcInterval=3600000来设置Full GC执行的间隔时间或通过-XX:+ DisableExplicitGC来禁止RMI调用System.gc。
     
     
    []Ant和Maven构建工具的理解
    Ant和Maven都是基于Java的构建(build)工具。理论上来说,有些类似于(Unix)C中的make ,但没有make的缺陷。Ant是软件构建工具,Maven的定位是软件项目管理和理解工具。  
    Ant特点  
    1. 没有一个约定的目录结构 必须明确让ant做什么,什么时候做,然后编译,打包 
    2. 没有生命周期,必须定义目标及其实现的任务序列 
    3. 没有集成依赖管理  
    Maven特点  
    1. 拥有约定,知道你的代码在哪里,放到哪里去 。
    2. 拥有一个生命周期,例如执行 mvn install 就可以自动执行编译,测试,打包等构建过程。
    3.  只需要定义一个pom.xml,然后把源码放到默认的目录,Maven帮你处理其他事情 。
    4. 拥有依赖管理,仓库管理。

原文地址:https://www.cnblogs.com/liguo-wang/p/9752126.html