zoukankan      html  css  js  c++  java
  • Java面试题集(五)

    三、开源框架

    什么是mybaties?

    Mybaties是支持普通sql查询,存储过程和高级映射的优秀持久层框架。Mybaties消除了几乎所有的jdbc代码和参数的手工设置以及结果集的检索。Mybaties使用简单的xml或注解用于配置和原始映射,将接口和Java的pojos(Plan Old Java Objects 普通的Java对象)映射成数据库中的记录。

    Mybaties的动态sql语句是基于ognl表达式的,可以方便的在sql语句中实现某些逻辑,总体来说mybaties动态sql语句主要有以下几类:

    1:if语句(简单的条件判断)

    2:choose(when otherwise),相当于Java语言中的switch与jstl中的choose很类似。

    3:trim(where,set,对包含的内容加上prexif或者suffix等,前缀后缀)

    4:where(主要是用来简化sql语句中where条件判断,能只能的处理and ,or,不必担心多余导致语法报错)

    5:set(主要用于更新操作)

    6:foreach 主要用在构建in条件中,它可以在sql语句中进行迭代一个集合。Foreach元素的属性主要有item,index,collector,open,separator,close.

    Item表示集合中每一个元素进行迭代时的别名;

    Index指定一个名字,用于表示在迭代过程中,每次迭代到的位置;

    Open表示该语句以什么开始;

    Separator表示在每次进行迭代之间以什么符号作为分隔符;

    Close表示该语句以什么结束。

    注意:collector 若是list则为list,若为数组则为array,默认为map

    Mybaties与hibernate的区别?

    相对于hibernate的O/R而言,mybaties是一种“sql mapping”的ORM实现。

    Hibernate对数据库结构提供了较为完整的封装,hibernate的o/r mapping实现了pojo和数据库之间的映射,以及sql的自动生成和执行。程序员往往只需定义好pojo到数据库表的映射关系,即可通过hibernate提供的办法完成持久层操作。程序员甚至不需要对sql熟练掌握,hibernate会根据制定的存储逻辑,自动生成对应的sql并调用jdbc接口加以执行。

    而mybaties着力点则在于pojo与sql之间的映射关系。也就是说mybaties并不会为程序员在运行期间自动执行生成sql执行,具体的sql语句需要程序员自己写,然后通过映射配置文件,将sql所需的参数以及返回的结果字段映射到指定pojo。

    Hibernate是一个全自动的orm映射工具,它可以自动生成sql语句,而mybatis 需要我们自己在xml配置文件中写sql语句,hibernate要比ibatis功能负责和强大很多。因为hibernate自动生成sql语句,我们 无法控制该语句,我们就无法去写特定的高效率的sql。对于一些不太复杂的sql查询,hibernate可以很好帮我们完成,但是对于特别复杂的查 询,hibernate就很难适应了,这时候用mybatis就是不错的选择,因为mybatis还是由我们自己写sql语句。

    springMVC工作原理(重点)

    在整个springMVC框架中,dispatcherServlet处于核心位置,负责协调和组织不同组件以完成请求处理并返回响应工作

    1.客户端发送一个请求匹配dispatcherServlet的请求映射路径(web.xml),web容器将该请求转交给dispatcherServlet处理。

    2.dispatcherServlet接收到请求后,将请求信息(包括url,http,请求头,请求参数,cook等)以及HandlerMapping的配置找到处理请求的处理器Handler

    3.dispatcherServlet根据HandlerMapping得到对应请求的Handler后,通过HandlerAdapter对Handler进行封装,再以统一的适配器接口调用Handler。

    4.处理器完成业务逻辑的处理后将返回一个ModelAndView给dispatcherServlet,ModelAndView包含视图逻辑名和模型数据信息。

    5.dispatcherServlet借助ViewResoler完成逻辑视图名到真实视图对象的解析。

    6.得到真实视图对象后,dispatcherServlet使用这个view对ModelAndView中的模型数据进行视图渲染。

    SpringMVC注解

    1.@RequestMapping(value="url请求地址")写在类的上面,表示该类的url请求地址

    2.@RequestMaping(value="请求路径",method={RequestMethod.GET})写在方法的上面,方法的路径。

    3.@RequestParam 绑定单个请求数据,可以是url中的数据,表单提交的数据或者上传的文件。

    4.@ResponseBody 用来返回数据给客户端。例如:

        @ResponseBody

        @RequestMapping(value = "/getGoodsByType", method = RequestMethod.POST)

        public ResultModel<Goods> getGoodsByType(@RequestParam int typeId) {

           return “modelresult”

        }

    5.@RequestBody 用来处理Content-type不是application/x-www-form-urlencoded编码的内容,例如application/json ,application/xml等。

    6.@PathVariable 绑定url模板变量值,@PathVariable(value="id")Integer id这里value值必须和请求参数一致。

    7.@ModelAttribute 绑定数据到Model

    8.@SessionAttributes 绑定数据到session

    9.@RequestPart 绑定multipart/data数据,并可以根据类型进行对象转换。

    10.@RequestHeader 绑定请求头数据

    11.@CookieValue 绑定Cookie数据

    Springmvc常用标签?

    首先在jsp页面引入springmvc标签标识符

    <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>

    form标签:<form:form modelAttribute=”contentModel” method=”post”>

    input标签:<form:input path=”username”>

    password标签:<form:password path=”password”>

    checkbox标签:

    <form:checkbox path=”selectArray” value=${contentModel.testArray}>

    SpringMVC与Struts2比较(重点)

    1.springmvc是方法级别的拦截,拦截到方法后根据参数上的注解,把request数据注入进去,一个方法对应一个request上下文,而方法同时又跟一个url对应,而struts2是类级别的拦截,每次来了请求就创建一个Action,然后调用setter getter方法把request中的数据注入,struts2中一个Action对象对应一个request上下文,struts2中action一个方法对应一个url,但是其类的属性被所有方法所共享。

    2.springmvc的方法之间基本上独立的,独享request response数据,请求数据通过参数获取,方法之间不共享变量。而struts2虽然方法之间也是独立的,但其所有Action变量是共享的,这不会影响程序运行,却给我们编码读程序时带来麻烦。

    3.springmvc的验证也是一个亮点,支持JSR303,处理ajax的请求更是方便只需一个注解@ResponseBody然后直接返回响应文本即可,如下:

    @RequestMapping(value=“/whitelists”)  
    public String index(ModelMap map) {  
      Account account = accountManager.getByDigitId(SecurityContextHolder.get().getDigitId());  
      List groupList = groupManager.findAllGroup(account.getId());  
      map.put(“account”, account);  
      map.put(“groupList”, groupList);  
      return “/group/group-index”;  
    }  
     
    
    // @ResponseBody ajax响应,处理Ajax请求也很方便
     

    Spring最核心的2点:IOC和AOP(重点)

    Spring是一个轻量级的控制反转和面向切面的容器框架。

    IOC(控制反转也称为 DI依赖注入):一个对象依赖的其对象通过被动的方式传递进来,而不是这个对象自己创建或者查找依赖对象,spring容器初始化时就将依赖传递给对象。

    IOC(控制反转):获得依赖对象被反转,即获得依赖对象的过程由自身管理变为由IOC容器主动注入。依赖注入就是由IOC容器在运行期间,动态地将某种依赖关系注入到对象中。

    一个对象依赖的其他对象通过被动的方式传递过来,而不是这个对象自己创建或者查找依赖对象,容器在对象初始化时不等对象请求就主动将依赖传递给它。

    AOP:面向方面编程。能够将那些与业务无关,却为业务模块所共同调用的逻辑或责任,例持久化管理,事务管理、日志管理、权限控制,调试管理等封装起来,便于减少系统的重复代码,降低模块间的耦合度,提高开发和调试效率

    Spring的目的就是让对象与对象之间的关系没有通过代码来关联,都是通过配置类说明管理的(spring根据配置,内部通过反射去动态组装对象)。

    项目中如何体现spring的AOP和IOC的?

    项目中体现AOP:

    主要是横切一个关注点,将一个关注点模块化成一个切面,在切面上声明一个通知(Advice)和切入点。通知中定义了要插入的方法,切入点内容是一个表达式,以描述需要在哪些对象的哪些方法上插入通知定义的方法。

    项目中用到的spring中的切面编程最多的地方是声明式事务管理。

    1.定义一个事务管理

    2.配置事务特性(相当于声明通知,一般在业务层的类的一些方法上定义事务)

    3.配置哪些类的哪些方法需要配置事务(相当于切入点,一般在业务类的方法上)

    例如:

    1.注解方式配置事务

    @AspectJ风格的切面可以通过@Compenent注解标识其为Spring管理Bean,而@Aspect注解不能被Spring自动识别并注册为Bean,

     必须通过@Component注解来完成,如下:

    @Component    
    @Aspect    
    public class TestAspect {    
        @Pointcut(value="execution(* *(..))")    
        private void pointcut() {}    
        @Before(value="pointcut()")    
        public void before() {    
            System.out.println("=======before");    
        }    
    }   

    2.拦截方式配置事务(在spring-hibernate.xml中配置)

     Spring的声明式事务配置:

    首先配置sessionfactory

    <bean id=”sessionFactory” class=”org.springframework.orm.hibernate4.LocalSessionFactoryBean”>  
       <property name=”configLocation”>  
         <value>/WEB/INF/classes/hibernate.cfg.xml</value>  
       </property>  
    </bean>  
     
     

    然后配置事务管理器

    <bean id=”transactionManager” class=”org.springframework.orm.hibernate4.HibernateTransactionManager”>  
       <property name="sessionFactory" ref="sessionFactory"></property>  
    </bean>  

    配置事务特征

    1. <tx:advice id=”txAdvice” transaction-manager=”transactionManager”>  
         <tx:attributes>  
            <tx:method:nametx:method:name=”add.*” progagation=”REQUIRED”>  
            <tx:method:nametx:method:name=”update.*” progagation=”SUPPORTS”>  
            <tx:method name="delete*" rollback-for="Exception" />  
         </tx:attributes>  
      </tx:advice>  

    配置哪些类的哪些方法配置事务

    <aop:config>  
      <aop:pointcut id=”transactionPoitcut”expression=”execution(*.com.ftsc.service.impl.*.*(..))”/>  
       <aop:advisor advice-ref=”txAdvice”pointcut-ref=”transactiomPointcut”>  
    </aop:config>  

    Spring的传播机制:progagation定义了7个事务传播机制。

    REQUIRED:如果存在一个事务,则支持当前事务。如果没有事务则开启一个新的事务

    SUPPORTS:如果存在一个事务,支持当前事务。如果没有事务,则非事务的执行,但是对于事务同步的事务管理器,supports与不使用有少许不同。

    REQUIRES_NEW:总是开启一个新的事务如果一个事务已经存在,则将当前事务挂起

    NOT_SUPPORTED:总是非事务执行,并挂起任务存在的事务

    NEVER:总是非事务的执行,如果存在一个活动事务,则抛出异常

    NESTED:如果一个活动的事务存在,则运行在一个嵌套的事务中,如果没有活动事务,则按

    TransactionDefinition.PROPAGATION_REQUIRED属性执行

    注:嵌套事务一个非常的概念及时内层事务依赖于外层事务。外层事务失败时,会回滚内层事务所做的动作。而内层事务操作失败并不会引起外层事务的回滚。

    项目中体现IOC:

    例如spring整合struts,让spring的IOC容器管理struts2的action

    首先在web.xml中引入struts配置文件如struts的过滤器,spring的配置文件如:

    <context-parm>  
      <param-name>contextConfigLocation</param-name>  
      <param-name>classpath:applicationContext.xml</param-name>  
    </context-parm>  

    启动IOC容器的listener:

    <listener>  
      <listener-class>  
         org.springframework.web.context.ContextLoaderListener  
      </listener-class>  
    </listener>  

    spring整合struts的插件struts-spring-plugin,该插件包的作用是:覆盖struts的objectFactory来增强核心框架对象的创建,当创建一个对象的时候,它会用struts配置文件的class属性去和spring配置文件中的id属性进行关联,如果能找到,则由spring创建,否则由struts框架自身创建,然后由spring来装配

    接着在spring的配置文件中配置struts的action实例,(注意需要配置scope属性为prototype,因为struts的action是单例,这是为了解决线程安全问题。)在struts配置文件中配置action,但其class属性不再指向该action的实现类,而是指向spring容器中action实例的ID

    Spring依赖注入方式?

    spring注入有3中方法:属性名称,setter方法,构造方法

    开发中主要使用spring的什么技术?

    1.IOC容器管理各层组件

    2.使用aop配置事务

    3.整合其他框架

    Spring注解?

    @Component:通用注解,可用于任何bean

    @Repository:通常用于注解dao类,即持久层

    @Service:通常用于注解service类,即服务层。

    @Controller:通常用于controller类,即控制层(MVC)

    在声明action时,需要指定为多例,解决线程安全问题。

    Spring过滤器和拦截器区别?

    Spring的拦截器与servlet的filter有相似之处,比如二者都是AOP编程思想的体现,都能实现权限检查,日志记录等。

    区别:

    1.使用范围不同:filter是servlet规范规定的,只能用于web程序中,而拦截器既可以用于web程序,也可以用于application,swing程序中;

    2.规范不同:filter是在servlet规范中定义的,是servlet容器支持的,而拦截器是在spring容器内的,是spring框架支持的;

    3.使用资源不同:同其他的代码块一样,拦截器也是一个spring的组件,归spring管理,配置在spring文件中,因此能使用spring里的任何资源,对象。例如service对象,数据源,事务管理等,通过ioc注入到拦截器即可,而过滤器则不能;

    4.深度不同:filter只在servlet前后起作用,而拦截器能够深入到方法前后,异常抛出前后等,因此拦截器的使用具有更大的弹性,所以在spring框架的程序中,要优先使用拦截器。

    案例:在web.xml中使用filter如字符集编码

     

    Struts2工作原理?

    1.客户端发送一个请求给strtusPrepareAndExecueFilter(在web.xml中),

    2.strutsPrepareAndExecuteFilter询问ActionMapper:该请求是否是一个strtus2的请求,

    3.若actionMapper认为该请求是一个strtus请求,则strutsPrepareAndExecuteFilter把请求的处理交给actionProxy,

    4.ActionProxy通过ConfigurationManager询问框架的配置文件,确定需要调用action类及action方法,

    5.actionProxy创建一个actionInvocation的实例,并进行初始化,

    6.actionInvocation实例在调用action过程前后,涉及到相关拦截器(Intercepter)的调用,

    7.Action执行完毕,actionInvocation负责根据strtus.xml找到对应的返回结果。调用结果的execute方法,渲染结果,在渲染的过程中可以使用strtus2框架的标签,

    8.执行各个拦截器invocation.invoke()之后的代码

    9.把结果发送给客户端

    Struts2:注意在页面中展示的数据,都一视同仁的成为字符串在页面上展现出来。

    Struts2常用标签?

    首先在jsp页面中引入strtus2标签库<%@taglib prefix=”s”uri=”/struts-tags”>

    1.往action传值:<input name=”userName” type=”text” >

    2.显示标签property用于输出指定值:<s:property value=”userName”>

    3.用于从页面往action中(user)的对象传值:

    <s:text name=”user.userName”id=”userName”>

    4.迭代<s:iterator>用于将list,Map,ArrayList等集合数据循环遍历

    <s:iterator id=”user”status=”u”value=”userList”>

      <s:property value=”userName”>

    </s:iterator>

    5.Set标签用于将某个值放入指定范围内如application,session

    <s:set name=”user”value=”userName” scope=”request”>

    El表达式:如

    <s:set name=”name” value=”<%=request.getParamter(“name”)%>”/>

    拦截器和过滤器的区别?

    1.过滤器依赖于servlet容器,而拦截器不依赖于servlet容器。

    2.Struts2拦截器只能对action请求起作用,而过滤器则对所有请求起作用。

    3.拦截器可以访问action的上下文,值栈里的对象,而过滤器不能。

    4.在action的生命周期中,拦截器可以调用多次,而过滤器只能在容器初始化时被调用一次。

    谈谈你对MVC的理解?

    MVC即Model-View-Controller的缩写

    Model:表示业务数据和业务处理,相当于Javabean,一个模型为多个视图提供数据

    View:用户看到并与之交互的页面,向用户显示相关数据,并接受用户的输入,如jsp

    Controller:接受用户请求并调用相应模型去处理请求,然后根据处理的结果调用相应的视图来显示处理的结果如servlet,struts2

    MVC处理过程:首先控制器接受用户的请求,并决定应该调用哪个模型来进行处理;然后根据用户请求进行相应的业务逻辑处理,并返回数据;最后控制器调用相应的视图格式化返回的数据,并通过视图呈现给用户。

    Action 是单例还是多例?为什么?

    Action是单例,当多个用户访问一个请求时候,服务器内存中只有一个与之对应的 action类对象。因为当服务器第一次加载struts的配置文件时,创建一个action后,每发送一个请求,服务器都会去检索相应的范围是否存在这 样一个action实例,如果存在,则使用这个实例,否则创建一个action实例。

    Hibernate的缓存机制:一级缓存session缓存和二级缓存sessionfactory缓存?

    hibernate:一个基于元数据的轻量级(占用资源少,没有浸入性)orm(对象关系数据库映射)框架。

    Session是一级缓存,它是属于事务范围的缓存,由Hibernate管理,无需进行干预。

    SessionFactory是二级缓存,它是属于进程范围或群集范围的缓存,可以进行配置和更改.

    一级缓存又叫session缓存,轻量级的,创建和销毁不需要消耗太多资源,但是它是线程不安全的,要避免多个线程共享一个session实例。我们框架使用的get,load,save,update,delete等都支持一级缓存的。

    二级缓存又叫sessionfactory缓存,重量级的,创建和销毁需要消耗太多资源,它是线程安全的,一个实例可以被应用的多个线程共享。

    需要在配置文件中启用二级缓存

    <!--启用二级缓存 -->

    <property name="hibernate.cache.use_second_level_cache">true</property>

    缓存的操作数据原理:

    查询数据时,会首先从一级缓存中取数据,如果取上,则直接使用,否则到二级缓存中取,如果取到则直接使用,否则,就会发送语句查询数据库。这样利用一级和二级缓存会提高访问效率。

    lazy(Hibernate的延迟加载功能):表示查询当前对象或关联对象数据时,不真正访问数据库,当使用对象非主键属性时,才真正发送查询语句,访问数据库。

    Hibernate工作原理?

    1.读取并解析配置文件

    2.读取并解析映射信息,创建sessionfantory

    3.打开session

    4.创建事务transaction

    5.持久化操作

    6.提交事务

    7.关闭session

    8.关闭sessionfactory

    Hibernate的核心接口有5个:session,sessionFactory,transaction,query,configuration?

    Session接口:负责进行被持久化对象的crud操作。Session是一级缓存,轻量级的,线程不安全的。

    SessionFactory接口:负责初始化Hibernate,它充当数据存储源的代理,并负责创建session对象,这里用到工厂模式,sessionFactory是二级缓存,重量级的。

    Configuration接口:负责配置并启动Hibernate,创建sessionFactory对象。在Hibernate启动过程中,configuration类的实例首先定义映射文件位置,读取配置,然后创建sessionFactory对象。

    Transact接口:负责相关事务相关的操作。

    Query和criteria接口:负责各种数据库查询,用sql或者hql语句表达方式。

    Hibernate中Java对象的状态有哪些?

    1.临时态(transient)不处于session缓存中。Oid为null或等于id的unsaved-value属性值

    2.持久态(persistent)加入session缓存中

    3.游离态(detached)已经被持久化,但不再处于session的缓存中

    Session的清理和清空有什么区别?

    清理缓存调用的是session.flush()方法,而清空调用的是session.clean()方法。

    Session清理缓存是指按照缓存中对象的状态变化来同步更新数据库,但不清空缓存。而清空则是把session的缓存置空,不同步更新到数据库。

    Hibernate的load()方法与get()方法的区别?

    Get加载数据不支持延迟加载,若没有oid对象则返回的是null,而load加载数据支持延迟加载,返回的是一个代理对象

    Hibernate优缺点?

    优点:

    1.对JDBC访问数据库的代码做了封装,简化了数据访问层繁琐的重复性代码

    2.映射的灵活性, 它支持各种关系数据库,从一对一到多对多的各种复杂关系.

    3.非侵入性、移植性会好

    4.缓存机制: 提供一级缓存和二级缓存。

    缺点:

    1.无法对 SQL 进行优化

    2.框架中使用 ORM 原则, 导致配置过于复杂

    3.执行效率和原生的JDBC相比偏差: 特别是在批量数据处理的时候

    4.不支持批量修改、删除

    Hibernate的openSessionView问题?

    用于解决懒加载异常问题,主要功能就是把hibernate session和一个请求的线程绑定在一起,直到页面完整输出,这样就可以保证页面读取数据的时候session一直处于开启状态,如果去获取延迟加载对象也不会报错。

    注意配置filter要放在strtus2过滤器的前面,因为它要页面显示完后再退出。

    Hibernate的getCurrentSession()和openSession()的区别?

    1.getCurrentSession()它会先检查当前线程中是否绑定了session如果有则直接返回,没有再创建,而openSession()则是直接new一个新的session并返回。

    2.使用ThreadLocal来实现线程session的隔离。

    3.getCurrentSession()在事务提交的时候会自动关闭session,而openSession()要手动关闭。


    项目中为什么使用SSH?

    1.使用struts2是因为struts2是基于MVC设计模式,很好的将应用程序进行分层,使开发者更关注业务逻辑实现,其次struts有丰富的taglib,灵活运用,大大提高开发效率。

    2.使用hibernate是因为它是基于orm模式的轻量级框架。

    3.使用spring是因为基于IOC和AOP架构多层j2ee框架,采用IOC使得很容易实现bean的装配,采用AOP实现事务管理。

    Hibernate的update()和saveOrUpdate()的区别?

    Update()和saveOrUpdate()是用来对跨session的po进行状态管理的。

    Update()方法操作的对象必须是持久化的对象,如果此对象在数据库中不存在的话,就不能使用update()方法。

    saveOrUpdate()方法操作的对象即可以是持久化的,也可以是未持久化的对象,如果该对象是已经持久化的则调用该方法会更新数据库对象,如果该对象是未持久化的则调用该方法会save到数据库。

    什么是hibernate的并发机制?怎么去处理并发问题?

    Hibernate的并发机制:1.hibernate的session对象是非线程安全的,对于单个请求,单个会话,单个工作单元,它通常只使用一次然后就丢弃。如果一个session实例会话允许共享的话,那些支持并发运行的,例如http request,session bean将会导致出现资源争用。如果在http session中hibernate的session话,就可能出现同步访问http session,只要用户足够快点击浏览器的“刷新”。2.多个事务并发访问同一块资源,可能会引发第一类丢失更新,脏读,幻读,不可重复读,第二类丢失更新一系列的问题。

    解决方案:

    1.设置事务隔离级别

    Serializable串行化。隔离级别最高

    Repeatable read:可重复读

    Read committed:已提交数据读

    Read uncommitted:未提交数据读。隔离级别最差

    设置锁:乐观锁和悲观锁。

    乐观锁:使用版本号或者时间戳检测更新丢失,在<class>映射中设置optimistic-lock=“all”可以在没有版本或者时间戳属性映射的情况下实现版本检查,此时hibernate将比较一行记录的每个字段的状态行。

    悲观锁:hibernate总是使用数据库的锁定机制,从不在内存中锁定对象,只要为jdbc连接指定一下隔离级别,然后让数据库去搞定一切就够了。类LockMode定义了hibernate所需的不同的锁定级别:

    LockMode.UPGRADE,LockMode.UPGRADE_NOWAIT,LockMode.READ

  • 相关阅读:
    根据文件名或文件扩展名获取文件的默认图标
    TreeView实现类似Outlook在收件箱后面显示新邮件数
    取每组数据的第一条记录的SQL语句
    Stream 和 byte[] 之间的转换
    使用HttpWebRequest提交ASP.NET表单并保持Session和Cookie
    C# 创建临时文件
    Tomcat 服务不能启动的问题
    VS2008 椭圆曲线签名(ECDSA)
    2007年12月23日在博客园的排名进入了前300名
    现代软件工程 作业 3 团队作业
  • 原文地址:https://www.cnblogs.com/qlqwjy/p/7683812.html
Copyright © 2011-2022 走看看