java面试题

  1. Java基础部分

    1.1 Java中的方法覆盖(Overwrite)和方法重载(Overloading)是什么意思?
    重载Overload表示同一个类中可以有多个名称相同的方法,但这些方法的参数列表各不相同(即参数个数或类型不同)。
    重写Override表示子类中的方法可以与父类的某个方法的名称和参数完全相同,通过子类创建的实例对象调用这个方法时,将调用子类中的定义方法,这相当于把父类中定义的那个完全相同的方法给覆盖了,这也是面向对象编程的多态性的一种表现。

    1.2 接口和抽象类的区别是什么?
    抽象类:含有abstract修饰的类即为抽象类,抽象类不能创建实例对象。含有abstract方法的类必须定义为抽象类,抽象类中的方法不必是抽象的。抽象类中定义抽象方法必须在具体子类中实现,所以,不能有抽象构造方法或抽象静态方法。如果子类没有实现抽象父类中的所有抽象方法,那么子类也必须定义为abstract类型。
    接口:可以说成是抽象类的一种特例,接口中的所有方法都必须是抽象的。接口中的方法定义默认为public abstract类型,接口中的成员变量类型默认为public static final。
    下面比较一下两者的语法区别

    1. 抽象类可以有构造方法,接口中不能有构造方法。
    2. 抽象类中可以有普通成员变量,接口中没有普通成员变量
    3. 抽象类中可以包含非抽象的普通方法,接口中的所有方法必须都是抽象的,不能有非抽象的普通方法。
    4. 抽象类中的抽象方法的访问类型可以使public、protected和默认类型,但接口中的抽象方法只能是public类型的,并且默认修饰即为public abstract类型。
    5. 抽象类中可以包含静态方法,接口中不能包含静态方法
    6. 抽象类和接口中都可以包含静态成员变量,抽象类中的静态成员变量的访问类型可以任意,但接口中定义的变量只能是public static final类型,并且默认即为public static final类型。
    7. 一个类可以实现多个接口,但只能继承一个抽象类。

    1.3 创建线程有几种不通的方式?
    l 自定义类继承Thread类方式
    l 自定义类实现Runnable接口方式

    1.4 Java集合框架的基本接口有哪些?
    Collection接口
    Ø List接口
    Ø Set接口
    Map接口

    1.5 BlockingQueue是什么?
    1.BlockingQueue:支持两个附加操作的 Queue,这两个操作是:检索元素时等待队列变为非空,以及存储元素时等待空间变得可用。
    2.BlockingQueue 不接受 null 元素。
    3.BlockingQueue 可以是限定容量的。
    4.BlockingQueue 实现是线程安全的。Queue不是线程安全的。因此可以将Blockingqueue用于用于生产者-消费者模式。
    对于BlockingQueue队列而然,如果BlockQueue是空的,从BlockingQueue取东西的操作将会被阻断进入等待状态,直到BlockingQueue进了东西才会被唤醒,同样,如果BlockingQueue是满的,任何试图往里存东西的操作也会被阻断进入等待状态,直到BlockingQueue里有空间才会被唤醒继续操作。

    1.6 Java中的两种异常类型是什么?
    Error:称为错误,由java虚拟机生成并抛出,包括动态链接失败,虚拟机错误等,程序对其不做处理。
    Exception:所有异常类的父类,其子类对应了各种各样的可能出现的异常事件,一般需要用户显示的声明或捕获。
    Runtime Exception:一类特殊的异常,如被0除、数组下标超范围等,其产生比较频繁,处理麻烦,如果显示的声明或捕获将会对程序可读性和运行效率影响很大。因此由系统自动检测并将它们交给缺省的异常处理程序(用户可不必对其处理)。

    1.7 Final,finallyfinalize的区别?
    final用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。内部类要访问局部变量,局部变量必须定义成final类型。
    finally是异常处理语句结构的一部分,表示总是执行。
    finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提高垃圾收集时的其他资源回收,例如关闭文件等。JVM不保证此方法总被调用。

    1.8 Java中如何实现序列化,有什么意义?
    序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化。可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间。序列化是为了解决对象流读写操作时可能引发的问题(如果不进行序列化可能会存在数据乱序的问题)。
    要实现序列化,需要让一个类实现Serializable接口,该接口是一个标识性接口,标注该类对象是可被序列化的,然后使用一个输出流来构造一个对象输出流并通过writeObject(Object)方法就可以将实现对象写出(即保存其状态);如果需要反序列化则可以用一个输入流建立对象输入流,然后通过readObject方法从流中读取对象。序列化除了能够实现对象的持久化之外,还能够用于对象的深度克隆。

    1.9 都用过什么设计模式
    单例设计模式
    工厂设计模式
    模板设计模式
    装饰设计模式
    代理设计模式
    适配器设计模式

    1.10 写一个单例模式出来
    饿汉模式
    public class Single {
    //私有本类中的构造函数
    private Single(){}
    //创建本类对象
    private static Single s = new Single();
    //对外提供获取本来对象方法
    public static Single getInstance(){
    return s;
    }
    }
    注意问题:
      由于外界无法创建Single对象,没有对象,那就无法调用getInstance方法,这时需要将getInstance方法静态化,这样外界就可以通过类名直接调用该方法。

    懒汉模式
    public class Single
    {
    //私有构造函数
    private Single(){}
    //在本类中创建本类对象
    private static Single instance = null;
    //对外提供静态访问方法,获取本类实例对象
    public static Single getInstance(){  
    if(instance == null )  // 这里会有线程安全问题
    {
    instance = new Single();
    }
    return instance;
    }
    }
    class SingleDemo
    {
    public static void main(String[] args)
    {
    //获取Single类的实例对象s
    Single s = Single.getInstance();
    //获取Single类的实例对象s2
    Single s2 = Single.getInstance();
    System.out.println(s==s2); //true
    }
    }
    2.Javaweb阶段

    2.1 Ajax你以前用过么?简单介绍一下
    AJAX = 异步 JavaScript 和 XML。
       AJAX 是一种用于创建快速动态网页的技术。
    通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。
    传统的网页(不使用 AJAX)如果需要更新内容,必需重载整个网页面。
    有很多使用 AJAX 的应用程序案例:新浪微博、Google 地图、开心网等等。

    2.2 Ajax可以做异步请求么?
    可以.ajax请求默认是异步的.如果想同步 把 async设置为false就可以了默认是true
    如果是jquery
    $.ajax({
    url: some.php,
    async: false,
    success : function(){
    }
    });
    如果是原生的js
            xmlHttp.open(“POST”,url,false);
    2.3 一网站如果有大量的人登陆访问。那么会产生很多的session,如果你是程序员你该怎么办。

    session默认保存在内存中,内存资源宝贵,session数据量大导致内存利用率高,以下方案解决session内存存储问题:

    1、可以设置session超时时间,达到超时时间session自动清空

    20

      

    2、将session中的数据序列化到硬盘中

    3、不使用session,使用cookie(此方法存在安全性问题)

    2.4 Jsp有哪些内置对象?作用分别是什么?

    Page,pageContext,request,response,session,application,out,config,exception

    Page指的是JSP被翻译成Servlet的对象的引用.

    pageContext对象可以用来获得其他8个内置对象,还可以作为JSP的域范围对象使用.pageContext中存的值是当前的页面的作用范围》

    request代表的是请求对象,可以用于获得客户机的信息,也可以作为域对象来使用,使用request保存的数据在一次请求范围内有效。

    Session代表的是一次会话,可以用于保存用户的私有的信息,也可以作为域对象使用,使用session保存的数据在一次会话范围有效

    Application:代表整个应用范围,使用这个对象保存的数据在整个web应用中都有效。

    Response是响应对象,代表的是从服务器向浏览器响应数据.

    Out:JSPWriter是用于向页面输出内容的对象

    Config:指的是ServletConfig用于JSP翻译成Servlet后 获得Servlet的配置的对象.

    Exception:在页面中设置isErrorPage=”true”,即可使用,是Throwable的引用.用来获得页面的错误信息。

    2.5 什么是cookie?Session和cookie有什么区别?

    Cookie是会话技术,将用户的信息保存到浏览器的对象.

    Session也是会话技术,将Session的信息保存到服务器的对象.Session是基于Cookie的 利用Cookie向浏览器回写JSessionID.

    2.6 ajax如何实现异步定时5秒刷新?

    setInterval(function() {

        $(“#content”).load(location.href+” #content>*”,”“);

    }, 5000);
    SSH框架阶段SSH的优缺点,使用场景?

    Hibernate优点:

    (1) 对象/关系数据库映射(ORM)
    它使用时只需要操纵对象,使开发更对象化,抛弃了数据库中心的思想,完全的面向对象思想
    (2) 透明持久化(persistent)
    带有持久化状态的、具有业务功能的单线程对象,此对象生存期很短。这些对象可能是普通的JavaBeans/POJO,这个对象没有实现第三方框架或者接口,唯一特殊的是他们正与(仅仅一个)Session相关联。一旦这个Session被关闭,这些对象就会脱离持久化状态,这样就可被应用程序的任何层自由使用。(例如,用作跟表示层打交道的数据传输对象。)      
    (3) 事务Transaction(org.hibernate.Transaction)
    应用程序用来指定原子操作单元范围的对象,它是单线程的,生命周期很短。它通过抽象将应用从底层具体的JDBC、JTA以及CORBA事务隔离开。某些情况下,一个Session之内可
    能包含多个Transaction对象。尽管是否使用该对象是可选的,但无论是使用底层的API还是使用Transaction对象,事务边界的开启与关闭是必不可少的。
    (4) 它没有侵入性,即所谓的轻量级框架
    (5) 移植性会很好
    (6) 缓存机制,提供一级缓存和二级缓存
    (7) 简洁的HQL编程

    Hibernate缺点:
    (1)  Hibernate在批量数据处理时有弱势
    (2) 针对单一对象简单的增删查改,适合于Hibernate,而对于批量的修改,删除,不适合用Hibernate,这也是OR框架的弱点;要使用数据库的特定优化机制的时候,不适合用
    (3) 优化策略应用不当会导致大量的资源消耗.

    Spring优缺点  

    它是一个开源的项目,而且目前非常活跃;它基于IoC(Inversion of Control,反向控制)和AOP的构架多层j2ee系统的框架,但它不强迫你必须在每一层 中必须使用Spring,因

    为它模块化的很好,允许你根据自己的需要选择使用它的某一个模块;它实现了很优雅的MVC,对不同的数据访问技术提供了统一的 接口,采用IoC使得可以很容易的实现bean的装

    配,提供了简洁的AOP并据此实现Transcation Managment,等等

    spring优点:
    a. Spring能有效地组织你的中间层对象,不管你是否选择使用了EJB。如果你仅仅使用了Struts或其他为J2EE的 API特制的framework,Spring致力于解决剩下的问题。
    b. Spring能消除在许多工程中常见的对Singleton的过多使用。根据我的经验,这是一个很大的问题,它降低了系统的可测试性和面向对象的程度。
    c. 通过一种在不同应用程序和项目间一致的方法来处理配置文件,Spring能消除各种各样自定义格式的属性文件的需要。曾经对某个类要寻找的是哪个魔法般的属性项或系统属性

    感到不解,为此不得不去读Javadoc甚至源编码?有了Spring,你仅仅需要看看类的JavaBean属性。Inversion of Control的使用(在下面讨论)帮助完成了这种简化。
    d. 通过把对接口编程而不是对类编程的代价几乎减少到没有,Spring能够促进养成好的编程习惯。
    e. Spring被设计为让使用它创建的应用尽可能少的依赖于他的APIs。在Spring应用中的大多数业务对象没有依赖于Spring。
    f. 使用Spring构建的应用程序易于单元测试。
    g. Spring能使EJB的使用成为一个实现选择,而不是应用架构的必然选择。你能选择用POJOs或local EJBs来实现业务接口,却不会影响调用代码。
    h. Spring帮助你解决许多问题而无需使用EJB。Spring能提供一种EJB的替换物,它们适用于许多web应用。例如,Spring能使用AOP提供声明性事务管理而不通过EJB容器,如果你仅仅需要与单个数据库打交道,甚至不需要一个JTA实现。
    i. Spring为数据存取提供了一个一致的框架,不论是使用的是JDBC还是O/R mapping产品(如Hibernate)。
    Spring确实使你能通过最简单可行的解决办法来解决你的问题。而这是有有很大价值的。

    Spring缺点:

    无明显缺点
    Struts2 的优点:
    Struts2比Struts1已经有了很大的进步,优点很多,其中主要两个是:对框架API和ServletAPI的依赖减少,可扩展性提高。

    Struts2的Action可以实现框架提供的Action接口也可以不实现这个接口。实际上框架Strut2的Action的要求很低,只要一个类,包含一个无参的、返回值类型为String的方法就行。其实Struts2的Action就是一个POJO。如果用户写一个类实现框架提供的Action接口或者继承框架提供的ActionSupport类, 则可以利用框架中的其他一些功能。比如在,Action接口中定义了一些常量,这些常量通常作为返回值共处理方法调用。

    由于Struts2的Action对框架API和Servlet API的依赖减少,因此可测程度大大提高。

    Struts2的可扩展性提高了。Struts2的核心jar包中由一个struts-default.xml文件,在该文件中设置了一些默认的bean,resultType类型,默认拦截器栈等,所有这些默认设置,用户都可以利用配置文件更改,可以更改为自己开发的bean,resulttype等。

    因此用户开发了插件的话只要很简单的配置就可以很容易的和Struts2框架融合,这实现了框架对插件的可插拔的特性。

    面向切面编程的思想在Strut2中也有了很好的体现。最重要的体现就是拦截器的使用。拦截器就是一个一个的小功能单位,用户可以将这些拦截器合并成一个大的拦截器,这个合成的拦截器就像单独的拦截器一样,只要将它配置到一个、Action中就可以。

    Struts2 的缺点:
    在并发量比较大的场景中,.每次请求都要创建一个Action,并维护很长的调用链(至少18个拦截器+OGNL解析+Action+Result),资源消耗比较大.
    使用场景
    SSH对于中小型项目提供了一套完整的解决方案.在表关系相对简单,数据量不大,并发量不高的项目中,能够极大的提高开发效率.
    表关系复杂或数据量比较大时,可以使用Mybatis替换Hibernate.
    并发量很高时可以使用SpringMVC替换struts
    在Struts2框架中的处理大概分为以下几个步骤
    1 客户端初始化一个指向Servlet容器(例如Tomcat)的请求
    2 这个请求经过一系列的过滤器(Filter)(这些过滤器中有一个叫做ActionContextCleanUp的可选过滤器,这个过滤器对于Struts2和其他框架的集成很有帮助,例如:SiteMesh Plugin)
    3 接着StrutsPrepareAndExecuteFilter被调用,StrutsPrepareAndExecuteFilter询问ActionMapper来解析和判断该次请求是否需要由struts2框架来处理.
    4 如果ActionMapper判断需要struts2来处理请求,StrutsPrepareAndExecuteFilter会把请求的处理交给ActionProxy
    5 ActionProxy通过Configuration Manager加载框架的配置文件,找到需要调用的Action以及拦截器配置信息
    6 ActionProxy创建一个ActionInvocation的实例。
    7 ActionInvocation实例使用命名模式来调用,在调用Action的过程前后,涉及到相关拦截器(Intercepter)的调用。
    8 一旦Action执行完毕,ActionInvocation负责根据struts.xml中的配置找到对应的返回结果配置。根据配置找到对应的Result处理类来处理结果集.大多数情况输出会交由模版语言(JSP,FreeMarker)完成输出内容拼装

    简单介绍一下你对hibernate的理解?

        答:hibernate框架是一个ORM的持久层框架,ORM的含义是对象关系映射,简单理解就是通过对象和关系型数据库之间建立映射信息,以后再操作对象就相当于操作数据库了。hibernate框架是对JDBC进行了轻量级的封装,可以更方便简单的对数据库完成增删改查的操作。同时也提供了查询的方式和查询的策略。例如HQL和QBC的查询方式等。还提供了缓存的策略,效率会更高。

Hibernate和mybatis有什么区别?

1)mybatis是把sql语句与java代码分离了,sql语句在xml文件配置的
2)hibernate是ORM框架,它对jdbc进行了封装,在分层结构中处于持久化层,它能建立面向对象的域模型和关系数据模型之间的映射.它大大简化了dao层的编码工作
      3)  mybatis是半自动的,hibernate是全自动的,就是说mybatis可以配置sql语句,对于sql调优来说是比较好的,hibernate会自动生成所有的sql语句,调优不方便,hibernate用起来难度要大于mybatis

Hibernate中的update()和saveOrUpdate()的区别
    答:update是修改的方法,saveOrUpdate是保存或者更新
        saveorupdate()如果传入的对象在数据库中有就做update操作,如果没有就做save操作。
        save()在数据库中生成一条记录,如果数据库中有,会报错说有重复的记录。
        update()就是更新数据库中的记录

谈谈Spring的ioc、aop?
        IoC
                Inversion of Control 控制反转。
                我们以前开发,在一个类中使用其他类对象的时候都是采用new的方式直接获取,或者高级一点是通过反射的方式的得到需要的对象实例。这就造成了程序的耦合度非常高,一个类的运行,严重依赖于其他的类。并且还会出现程序中硬编码的情况。
                而spring中的IoC很好的解决了该问题,我们在一个类中使用其他类对象时,只需要定义一个接口类型的类成员变量,由使用者在使用时为我们注入具体的实现类对象,从而降低了程序的耦合度。
                实现IoC的思想就只有两种:依赖注入(Dependency Injection,简称DI)和依赖查找(Dependency Lookup)。
                而依赖注入使用的更广泛一些。例如:构造函数注入,set方法注入等等。

        AOP
                Aspect Oriented Programming 面向切面编程。
                我们之前学习的java语言,号称是面向对象编程,它有自己的优势。但是也存在着一些弊端。
                举例说明,在实际开发中,我们都会有一根业务主线,即客户(甲方)的需求。而程序员要做的就是围绕业务主线上的需求,实现功能(实现功能的方法我们叫做业务核心方法)。但是不可避免的,会有一些功能与业务主线没有关系,却又不能不做,比如权限的控制,事务的控制,日志的记录等等,这些功能绝大多数时候和业务主线没有关系,但是却和很多业务核心方法交织在一起,使我们的开发变得麻烦,并且冗余代码增多。
                而spring的提供了一种思想,把这些和业务主线没有关系的功能剥离出来,而在需要使用这些公共方法时,适时适地的把它加到我们的代码中去,使程序员在开发时,把更多的精力放在理解需求,实现业务核心功能上,并且让我们的代码变得简洁。这种思想就是面向切面编程。
                Spring实现面向切面编程使用的是动态代理技术,并且会根据实际情况来选择使用基于子类的还是基于接口的动态代理。

简单介绍一下你对spring的理解?
        任何框架在植入项目之中都不能带来效率的提升,反而是会带来效率的下降。因为java核心机制的问题,内存中多创建一个对象,就会造成性能降低。
        但是,spring带来的好处还是显而易见的:
                1、它的核心之一IoC,降低了我们程序的耦合度,使我们可以把项目设计成为一个可插拔的组件式工程。
                2、它的另一大核心AOP,使我们在开发过程中,精力得到释放,可以更专注的去理解客户的需求。并且在后期维护时,可以只维护很少的一部分。
                3、它提供的事务管理机制,采用声明的方式来配置事务,从而在维护时无需改动源码,解决了程序硬编码的弊端。
                4、它提供的DAO模板使我们的持久层开发又多了一种途径。
                5、它可以整合其他时下流行的框架,使我们在管理项目时,更加清晰,明确。
        并且以现在计算机的水平,使用spring框架造成的这点下降对程序的影响是微乎其微的。
        所以,总体来说spring框架的使用还是利大于弊的。

Spring是干嘛的?
        它是一个full-stack框架,提供了从表现层到业务层再到持久层的一套完整的解决方案。我们在项目中可以只使用spring一个框架,它就可以提供表现层的mvc框架,持久层的Dao框架。
        它的两大核心IoC和AOP更是为我们程序解耦和代码简洁易维护提供了支持。

你知道依赖注入么?简单介绍一下

        首先,明确依赖注入是实现控制反转的一种思想(另一种是依赖查找)。
        其次,在开发过程中,我们需要某个类的实例时,是由使用者为我们提供该类的实例。而不是自己去获取。
        最后,实现依赖注入的方式可以是使用构造方法注入或者set方法注入两种方式。
        在spring中注入的方式就有很多了,比如constructor-arg元素,property元素,p名称空间等等。

你知道控制反转么?简单介绍一下
        它是spring的核心之一。或者说是spring的基础核心,spring的其余核心功能都必须有IoC的支持。
        控制反转指的是,我们在获取对象的时候,由之前的主动出击,变成了被动接收。也就是说,在编写某个类时,只需要提供一个接口类型的类成员,并不需要关系具体的实现类,而是由使用者在使用时提供。这就降低了类和类之间的耦合度。

spring中自动装配的方式有哪些?
        1、 No:
                即不启用自动装配。
        2、 byName:
                通过属性的名字的方式查找JavaBean依赖的对象并为其注入。比如说类Computer有个属性printer,指定其autowire属性为byName后,Spring IoC容器会在配置文件中查找id/name属性为printer的bean,然后使用Seter方法为其注入。
        3、 byType:
                通过属性的类型查找JavaBean依赖的对象并为其注入。比如类Computer有个属性printer,类型为Printer,那么,指定其autowire属性为byType后,Spring IoC容器会查找Class属性为Printer的bean,使用Seter方法为其注入。
        4、 constructor:
                通byType一样,也是通过类型查找依赖对象。与byType的区别在于它不是使用Seter方法注入,而是使用构造子注入。
        5、 autodetect:
                在byType和constructor之间自动的选择注入方式。
        6、 default:
                由上级标签的default-autowire属性确定。

spring和hibernate管理事务有啥区别
        1、从编码上说,hibernate的事务管理是硬编码,是写在程序之中的。这就造成了,如果需要调整,就要修改源码,重新编译。
        2、从事务控制的位置来说:        hibernate是持久层框架,事务是控制在持久层的,这样就造成了越权操作。事务应放在业务层,而非持久层
        3、从代码维护上来说:hibernate控制事务,需要在每个需要事务支持的地方编写代码,后期维护不便。

spring管理事务有几种方式
        有两种方式:
                1、编程式事务,在代码中硬编码。(不推荐使用)
                2、声明式事务,在配置文件中配置(推荐使用)
                        声明式事务又分为两种:
                                a、基于XML的声明式事务
                                b、基于注解的声明式事务
SpringMvc简单介绍下你对springMVC的理解?

Spring MVC Framework有这样一些特点:
它是基于组件技术的.全部的应用对象,无论控制器和视图,还是业务对象之类的都是java组件.并且和Spring提供的其他基础结构紧密集成.
不依赖于Servlet API(目标虽是如此,但是在实现的时候确实是依赖于Servlet的)
可以任意使用各种视图技术,而不仅仅局限于JSP
支持各种请求资源的映射策略
它应是易于扩展的

2) SpringMVC的工作流程?

  1. 用户发送请求至前端控制器DispatcherServlet
  2. DispatcherServlet收到请求调用HandlerMapping处理器映射器。
  3. 处理器映射器根据请求url找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。
  4. DispatcherServlet通过HandlerAdapter处理器适配器调用处理器
  5. 执行处理器(Controller,也叫后端控制器)。
  6. Controller执行完成返回ModelAndView
  7. HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet
  8. DispatcherServlet将ModelAndView传给ViewReslover视图解析器
  9. ViewReslover解析后返回具体View
  10. DispatcherServlet对View进行渲染视图(即将模型数据填充至视图中)。
  11. DispatcherServlet响应用户

3) 如果你也用过struts2.简单介绍下springMVC和struts2的区别有哪些?

  1. springmvc的入口是一个servlet即前端控制器,而struts2入口是一个filter过虑器。
  2. springmvc是基于方法开发(一个url对应一个方法),请求参数传递到方法的形参,可以设计为单例或多例(建议单例),struts2是基于类开发,传递参数是通过类的属性,只能设计为多例。
  3. Struts采用值栈存储请求和响应的数据,通过OGNL存取数据, springmvc通过参数解析器是将request请求内容解析,并给方法形参赋值,将数据和视图封装成ModelAndView对象,最后又将ModelAndView中的模型数据通过reques域传输到页面。Jsp视图解析器默认使用jstl。
    SpringMvc简单介绍下你对springMVC的理解?

Spring MVC Framework有这样一些特点:
它是基于组件技术的.全部的应用对象,无论控制器和视图,还是业务对象之类的都是java组件.并且和Spring提供的其他基础结构紧密集成.
不依赖于Servlet API(目标虽是如此,但是在实现的时候确实是依赖于Servlet的)
可以任意使用各种视图技术,而不仅仅局限于JSP
支持各种请求资源的映射策略
它应是易于扩展的

2) SpringMVC的工作流程?

  1. 用户发送请求至前端控制器DispatcherServlet
  2. DispatcherServlet收到请求调用HandlerMapping处理器映射器。
  3. 处理器映射器根据请求url找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。
  4. DispatcherServlet通过HandlerAdapter处理器适配器调用处理器
  5. 执行处理器(Controller,也叫后端控制器)。
  6. Controller执行完成返回ModelAndView
  7. HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet
  8. DispatcherServlet将ModelAndView传给ViewReslover视图解析器
  9. ViewReslover解析后返回具体View
  10. DispatcherServlet对View进行渲染视图(即将模型数据填充至视图中)。
  11. DispatcherServlet响应用户

3) 如果你也用过struts2.简单介绍下springMVC和struts2的区别有哪些?

  1. springmvc的入口是一个servlet即前端控制器,而struts2入口是一个filter过虑器。
  2. springmvc是基于方法开发(一个url对应一个方法),请求参数传递到方法的形参,可以设计为单例或多例(建议单例),struts2是基于类开发,传递参数是通过类的属性,只能设计为多例。
  3. Struts采用值栈存储请求和响应的数据,通过OGNL存取数据, springmvc通过参数解析器是将request请求内容解析,并给方法形参赋值,将数据和视图封装成ModelAndView对象,最后又将ModelAndView中的模型数据通过reques域传输到页面。Jsp视图解析器默认使用jstl。
    数据库部分

    sql语句优化?

    1.查询的模糊匹配
    尽量避免在一个复杂查询里面使用 LIKE ‘%parm1%’—— 红色标识位置的百分号会导致相关列的索引无法使用,最好不要用。
    2.索引问题

    在做性能跟踪分析过程中,经常发现有不少后台程序的性能问题是因为缺少合适索引造成的,有些表甚至一个索引都没有。这种情况往往都是因为在设计表时,没去定义索引,而开发初期,由于表记录很少,索引创建与否,可能对性能没啥影响,开发人员因此也未多加重视。然一旦程序发布到生产环境,随着时间的推移,表记录越来越多。这时缺少索引,对性能的影响便会越来越大了。
    法则:不要在建立的索引的数据列上进行下列操作:
    避免对索引字段进行计算操作
    避免在索引字段上使用not,<>,!=
    避免在索引列上使用IS NULL和IS NOT NULL
    避免在索引列上出现数据类型转换
    避免在索引字段上使用函数
    避免建立索引的列中使用空值

    3.复杂操作

    部分UPDATE、SELECT 语句 写得很复杂(经常嵌套多级子查询)——可以考虑适当拆成几步,先生成一些临时数据表,再进行关联操作。

    4.update

    同一个表的修改在一个过程里出现好几十次,如:
    update table1  
    set col1=…  
    where col2=…;  
    update table1  
    set col1=…  
    where col2=…  

    这类脚本其实可以很简单就整合在一个UPDATE语句来完成(前些时候在协助xxx项目做性能问题分析时就发现存在这种情况)

    5.在可以使用UNION ALL的语句里,使用了UNION

    UNION 因为会将各查询子集的记录做比较,故比起UNION ALL ,通常速度都会慢上许多。一般来说,如果使用UNION ALL能满足要求的话,务必使用UNION ALL。还有一种情况大家可能会忽略掉,就是虽然要求几个子集的并集需要过滤掉重复记录,但由于脚本的特殊性,不可能存在重复记录,这时便应该使用 UNION ALL,如xx模块的某个查询程序就曾经存在这种情况,见,由于语句的特殊性,在这个脚本中几个子集的记录绝对不可能重复,故可以改用UNION ALL)。

    6.在WHERE 语句中,尽量避免对索引字段进行计算操作

    这个常识相信绝大部分开发人员都应该知道,但仍有不少人这么使用,我想其中一个最主要的原因可能是为了编写写简单而损害了性能,那就不可取了。9月份在对XX系统做性能分析时发现,有大量的后台程序存在类似用法,如:where trunc(create_date)=trunc(:date1),虽然已对create_date 字段建了索引,但由于加了TRUNC,使得索引无法用上。此处正确的写法应该是where create_date>=trunc(:date1) and create_date< pre=”“><>或者是where create_date between trunc(:date1) and trunc(:date1)+1-1/(24*60*60)。
    注意:因between 的范围是个闭区间(greater than or equal to low value and less than or equal to high value.),故严格意义上应该再减去一个趋于0的小数,这里暂且设置成减去1秒(1/(24*60*60)),如果不要求这么精确的话,可以略掉这步。

    7.对Where 语句的法则

    7.1 避免在WHERE子句中使用in,not  in,or 或者having。

    可以使用 exist 和not exist代替in和not in。
    可以使用表链接代替 exist。Having可以用where代替,如果无法代替可以分两步处理。
    例子
    SELECT * FROM ORDERS WHERE CUSTOMER_NAME NOT IN   
    (SELECT CUSTOMER_NAME FROM CUSTOMER)  
    优化
    SELECT * FROM ORDERS WHERE CUSTOMER_NAME not exist   
    (SELECT CUSTOMER_NAME FROM CUSTOMER)

    7.2 不要以字符格式声明数字,要以数字格式声明字符值。(日期同样)否则会使索引无效,产生全表扫描。

    例子使用:
    SELECT emp.ename, emp.job FROM emp WHERE emp.empno = 7369;
    –不要使用:
    SELECT emp.ename, emp.job FROM emp WHERE emp.empno = ‘7369’

    8.对Select语句的法则

    在应用程序、包和过程中限制使用select * from table这种方式。看下面例子
    –使用
    SELECT empno,ename,category FROM emp WHERE empno = ‘7369’
    –而不要使用
    SELECT * FROM emp WHERE empno = ‘7369’

    1. 排序

    避免使用耗费资源的操作,带有DISTINCT,UNION,MINUS,INTERSECT,ORDER BY的SQL语句会启动SQL引擎 执行,耗费资源的排序(SORT)功能. DISTINCT需要一次排序操作, 而其他的至少需要执行两次排序。

    10.临时表

    慎重使用临时表可以极大的提高系统性能。

    11.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。

    12.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,

    如:select id from t where num is null
    可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:
    select id from t where num=0

    13.应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。

    14.应尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描,

    如:select id from t where num=10 or num=20
    可以这样查询:
    select id from t where num=10
    union all
    select id from t where num=20

    15.in 和 not in 也要慎用,否则会导致全表扫描,如:

    select id from t where num in(1,2,3)
    对于连续的数值,能用 between 就不要用 in 了:
    select id from t where num between 1 and 3

    16.下面的查询也将导致全表扫描:

    select id from t where name like ‘%abc%’

    17.应尽量避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描。

    如:select id from t where num/2=100
    应改为:
    select id from t where num=100*2

    18.应尽量避免在where子句中对字段进行函数操作,这将导致引擎放弃使用索引而进行全表扫描。

    如:select id from t where substring(name,1,3)=’abc’–name以abc开头的id
    应改为:
    select id from t where name like ‘abc%’

    19.不要在 where 子句中的“=”左边进行函数、算术运算或其他表达式运算,否则系统将可能无法正确使用索引。

    20.在使用索引字段作为条件时,如果该索引是复合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,否则该索引将不会被使用,并且应尽可能的让字段顺序与索引顺序相一致。

    21.不要写一些没有意义的查询,如需要生成一个空表结构:

    select col1,col2 into #t from t where 1=0
    这类代码不会返回任何结果集,但是会消耗系统资源的,应改成这样:
    create table #t(…)

    22.很多时候用 exists 代替 in 是一个好的选择:

    select num from a where num in(select num from b)
    用下面的语句替换:
    select num from a where exists(select 1 from b where num=a.num)

    23.并不是所有索引对查询都有效,SQL是根据表中数据来进行查询优化的,当索引列有大量数据重复时,SQL查询可能不会去利用索引,如一表中有字段sex,male、female几乎各一半,那么即使在sex上建了索引也对查询效率起不了作用。

    24.索引并不是越多越好,索引固然可以提高相应的 select 的效率,但同时也降低了 insert 及 update 的效率,
    因为 insert 或 update 时有可能会重建索引,所以怎样建索引需要慎重考虑,视具体情况而定。
    一个表的索引数最好不要超过6个,若太多则应考虑一些不常使用到的列上建的索引是否有必要。

    25.尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并会增加存储开销。这是因为引擎在处理查询和连接时会逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了。

    26.尽可能的使用 varchar 代替 char ,因为首先变长字段存储空间小,可以节省存储空间,其次对于查询来说,在一个相对较小的字段内搜索效率显然要高些。

    27.任何地方都不要使用 select * from t ,用具体的字段列表代替“*”,不要返回用不到的任何字段。

    28.避免频繁创建和删除临时表,以减少系统表资源的消耗。

    29.在新建临时表时,如果一次性插入数据量很大,那么可以使用 select into 代替 create table,避免造成大量 log ,以提高速度;如果数据量不大,为了缓和系统表的资源,应先create table,然后insert。

    30.尽量避免使用游标,因为游标的效率较差,如果游标操作的数据超过1万行,那么就应该考虑改写。

    31.使用基于游标的方法或临时表方法之前,应先寻找基于集的解决方案来解决问题,基于集的方法通常更有效。

    32.尽量避免大事务操作,提高系统并发能力。

    33.尽量避免向客户端返回大数据量,若数据量过大,应该考虑相应需求是否合理。

    什么是存储过程?
    存储过程是由流控制和SQL语句书写的过程,这个过程经编译和优化后存储在数据库服务器中,应用程序使用时只要调用即可。在ORACLE中,若干个有联系的过程可以组合在一起构成程序包。

    存储过程优点

    1. 速度快。存储过程只在创造时进行编译,以后每次执行存储过程都不需再重新编译,而一般SQL 语句每执行一次就编译一次,所以使用存储过程可提高数据库执行速度。
    2. 写程序简单。采用存储过程调用类,调用任何存储过程都只要1-2行代码。
    3. 升级、维护方便。存储过程会使得维护起来更加方便,因为通常修改一个存储过程要比在一个已经发布的组件中修改SQL语句更加方便;
    4. 能够缓解网络带宽。因为可以批量执行SQL语句而不是从客户端发送超负载的请求。尤其对于较为复杂的逻辑,减少了网络流量之间的消耗。
    5. 可保证数据的安全性和完整性。通过存储过程可以使没有权限的用户在控制之下间接地存取数据库,从而保证数据的安全。通过存储过程可以使相关的动作在一起发生,从而可以维护数据库的完整性。
    6. 增强安全性。
      a) 通过向用户授予对存储过程(而不是基于表)的访问权限,它们可以提供对特定数据的访问。
      b) 提高代码安全,防止 SQL注入(但未彻底解决,例如,将数据操作语言--DML,附加到输入参数)。
      c) SqlParameter 类指定存储过程参数的数据类型,作为深层次防御性策略的一部分,可以验证用户提供的值类型(但也不是万无一失,还是应该传递至数据库前得到附加验证)。

    存储过程缺点

    1. 可移植性差。由于存储过程将应用程序绑定到 SQL Server,因此使用存储过程封装业务逻辑将限制应用程序的可移植性。如果应用程序的可移植性在您的环境中非常重要,则将业务逻辑封装在不特定于 RDBMS 的中间层中可能是一个更佳的选择。
    2. 代码可读性差,相当难维护。
    3. 不支持群集
    4. 大量采用存储过程进行业务逻辑的开发致命的缺点是很多存储过程不支持面向对象的设计,无法采用面向对象的方式将业务逻辑进行封装,从而无法形成通用的可支持复用的业务逻辑框架。
    5. 如果在一个程序系统中大量的使用存储过程,到程序交付使用的时候随着用户需求的增加会导致数据结构的变化,接着就是系统的相关问题了,最后如果用户想维护该系统可以说是很难很难、而且代价是空前的,维护起来更麻烦。

    使用原则

    1. 当一个业务同时对多个表进行处理的时候采用存储过程比较合适。
    2. 复杂的数据处理用存储过程比较合适,如有些报表处理。
    3. 多条件多表联合查询,并做分页处理,用存储过程也比较适合。
    4. 使用存储过程,等需求变动,需要维护的时候,麻烦就来了。不应该大规模使用。
    5. 适当的使用存储过程,能够提高我们SQL查询的性能,以便于提高我们的工作效率。

    说说mysql的分页查询.分别是怎么实现的?
    MySQL:

    1. MySQL数据库实现分页比较简单,提供了 LIMIT函数。一般只需要直接写到sql语句后面就行了。
    2. LIMIT子 句可以用来限制由SELECT语句返回过来的数据数量,它有一个或两个参数,如果给出两个参数, 第一个参数指定返回的第一行在所有数据中的位置,从0开始(注意不是1),第二个参数指定最多返回行数。例如:
      select * from table WHERE … LIMIT 10; #返回前10行
      select * from table WHERE … LIMIT 0,10; #返回前10行
      select * from table WHERE … LIMIT 10,20; #返回第10-20行数据
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值