面试总结

1.spring  @transactional的属性

 
属性 类型 描述
value String 可选的限定描述符,指定使用的事务管理器
propagation enum: Propagation 可选的事务传播行为设置
isolation enum: Isolation 可选的事务隔离级别设置
readOnly boolean 读写或只读事务,默认读写
timeout int (in seconds granularity) 事务超时时间设置
rollbackFor Class对象数组,必须继承自Throwable 导致事务回滚的异常类数组
rollbackForClassName 类名数组,必须继承自Throwable 导致事务回滚的异常类名字数组
noRollbackFor Class对象数组,必须继承自Throwable 不会导致事务回滚的异常类数组
noRollbackForClassName 类名数组,必须继承自Throwable 不会导致事务回滚的异常类名字数组


2.springAOP的事务的传播属性和隔离级别?

首先,什么是事务?

事务就是业务上的一个逻辑单元,它能够保证其中对数据所有的操作,要么成功,要么失败。


其次,事务的特性有哪些?

1.原子性。

例如,转账,A账户减少,B账户增加。虽然是两条 DML语句,但是被当做是一个整体,一次事务。两条语句只能同时成功或者同时失败。


2.一致性。

账户A和B,要么都是转账前的状态,要么都是转账后的状态。(不能A账户的钱减少了但是B账户的钱没有增加)。


3.隔离性。

虽然在某个时间段很多人都在转账,但是每个人的转账都是在一个自己的事务中,彼此不会影响。


4.持久性。

事务提交成功后,数据修改永远生效。


在考虑事务的隔离级别之前,需要认识到如果不考虑事务的隔离性,会发生的异常情况:

1.脏读

一个事务读取了另外一个事务未提交的数据。(会对系统的并发处理带来很大的隐患)


2.不可重复读

在同一个事务内,多次读同一个数据时,发现该数据已经 被另一个已经提交的事务修改。(在一个事务内两次读到的数据时是不一样的。)


3.幻读

一个事务根据相同的查询条件,重新执行查询,返回的记录中包含与前一次执行查询返回的记录不同的行。



以上这三种 情况都是同时进行的几个事务对相同的数据进行读取时造成的。

如何处理这几种异常呢?


Spring事务的隔离级别


 1. ISOLATION_DEFAULT: 这是一个PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别.
      另外四个与JDBC的隔离级别相对应(default)


 2. ISOLATION_READ_UNCOMMITTED: 这是事务最低的隔离级别,它充许令外一个事务可以看到这个事务未提交的数据。
      这种隔离级别会产生脏读,不可重复读和幻像读。(read_uncommitted)


 3. ISOLATION_READ_COMMITTED: 保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据(read_committed)


 4. ISOLATION_REPEATABLE_READ: 这种事务隔离级别可以防止脏读,不可重复读。但是可能出现幻像读。
      它除了保证一个事务不能读取另一个事务未提交的数据外,还保证了避免下面的情况产生(不可重复读)。(reperatable_read)


 5. ISOLATION_SERIALIZABLE 这是花费最高代价但是最可靠的事务隔离级别。事务被处理为顺序执行。
      除了防止脏读,不可重复读外,还避免了幻像读。(serializable  序列化)


springAOP事务的传播方式


如果两个在代码上不相关的操作,需要放在同一个事务中,这就需要利用到传播特性了。这时调用的传播特性的值就应该是PROPAGATION_REQUIRED。在spring中只需要进行这样的配置,就实现了声明式的事物处理。

      1. PROPAGATION_REQUIRED: 如果存在一个事务,则支持当前事务。如果没有事务则开启新的事物。(requierd)
      2. PROPAGATION_SUPPORTS: 如果存在一个事务,支持当前事务。如果没有事务,则非事务的执行。(support)
      3. PROPAGATION_MANDATORY: 如果已经存在一个事务,支持当前事务。如果没有一个活动的事务,则抛出异常。(mandatory)
      4. PROPAGATION_REQUIRES_NEW: 总是开启一个新的事务。如果一个事务已经存在,则将这个存在的事务挂起。(requiers_new)
      5. PROPAGATION_NOT_SUPPORTED: 总是非事务地执行,并挂起任何存在的事务。(supported)
      6. PROPAGATION_NEVER: 总是非事务地执行,如果存在一个活动事务,则抛出异常(never)
      7.(spring)PROPAGATION_NESTED:如果一个活动的事务存在,则运行在一个嵌套的事务中. 如果没有活动事务, 则按(newted)TransactionDefinition.PROPAGATION_REQUIRED 属性执行。


springAOP中事务抛出异常该怎么处理?


throw new RuntimeException("xxxxxxxxxxxx"); 事物回滚
throw new Exception("xxxxxxxxxxxx"); 事物没有回滚


1).Spring的AOP即声明式事务管理默认是针对unchecked exception回滚。也就是默认对RuntimeException()异常或是其子类进行事务回滚;checked异常,即Exception可try{}捕获的不会回滚,如果使用try-catch捕获抛出的unchecked异常后没有在catch块中采用页面硬编码的方式使用spring api对事务做显式的回滚,则事务不会回滚, “将异常捕获,并且在catch块中不对事务做显式提交=生吞掉异常” ,要想捕获非运行时异常则需要如下配置:

解决办法:
1.在针对事务的类中抛出RuntimeException异常,而不是抛出Exception。
2.在txAdive中增加rollback-for,里面写自己的exception,例如自己写的exception:
<tx:advice id="txAdvice" transaction-manager="transactionManager">
   <tx:attributes>
     <tx:method name="*" rollback-for="com.cn.untils.exception.XyzException"/>
   </tx:attributes>
 </tx:advice>
 
或者
定义不会滚的异常
<tx:advice id="txAdvice">
    <tx:attributes>
       <tx:method name="update*" no-rollback-for="IOException"/>
       <tx:method name="*"/>
    </tx:attributes>
 </tx:advice>


2).spring的事务边界是在调用业务方法之前开始的,业务方法执行完毕之后来执行commit or rollback(Spring默认取决于是否抛出runtime异常).
 如果抛出runtime exception 并在你的业务方法中没有catch到的话,事务会回滚。 
 一般不需要在业务方法中catch异常,如果非要catch,在做完你想做的工作后(比如关闭文件等)一定要抛出runtime exception,否则spring会将你的操作commit,这样就会产生脏数据.所以你的catch代码是画蛇添足。
 
如:
try {  
    //bisiness logic code  
} catch(Exception e) {  
    //handle the exception  
}  

 由此可以推知,在spring中如果某个业务方法被一个 整个包裹起来,则这个业务方法也就等于脱离了spring事务的管理,因为没有任何异常会从业务方法中抛出!全被捕获并吞掉,导致spring异常抛出触发事务回滚策略失效。
 不过,如果在catch代码块中采用页面硬编码的方式使用spring api对事务做显式的回滚,这样写也未尝不可。
 
 3).基于注解的事物:
 Transactional的异常控制,默认是Check Exception 不回滚,unCheck Exception回滚
 如果配置了rollbackFor 和 noRollbackFor 且两个都是用同样的异常,那么遇到该异常,还是回滚
 rollbackFor 和noRollbackFor 配置也许不会含盖所有异常,对于遗漏的按照Check Exception 不回滚,unCheck Exception回滚


3.怎么快速排序?

public class Test03 {
    // 快速排序法
    public static void main(String[] args) {
        int[] a = new int[5];
        System.out.print("排序前: ");

<!--随机产生100以内的随机数-->
        for (int i = 0; i < a.length; i++) {
            a[i] = (int) (Math.random() * 99 1);
            System.out.print(a[i] + "  ");
        }
        System.out.print("\n排序后:");
<!-- 使用sort方法进行排序 -->
        Arrays.sort(a); // 进行排序
<!-- 循环输出新的集合里面的元素 -->
        for (int x : a) {
            System.out.print(x + "  ");
        }
    }
}

2.冒泡排序

public class aaa {
public static void main(String[] args) {
<!-- 声明一个数组-->
int score[] = { 67, 69, 75, 87, 89, 90, 99, 100 };
<!--第一层循环控制第一个数字的位置-->
for (int i = 0; i < score.length - 1; i++) { // 最多做n-1趟排序
for (int j = 0; j < score.length-1-i; j++) { // 对当前无序区间score[0......length-i-1]进行排序(j的范围很关键,这个范围是在逐步缩小的)
<!-- 核心大的数字替代小的数字的位置-->
if (score[j] < score[j + 1]) { // 把小的值交换到后面
int temp = score[j];
score[j] = score[j + 1];
score[j + 1] = temp;
}
}

  <!--System.out.print("第" + (i + 1) + "次排序结果:");
for (int a = 0; a < score.length; a++) {
System.out.print(score[a] + "\t");
}
System.out.println("");-->
}

System.out.print("最终排序结果:");
for (int a = 0; a < score.length; a++) {
System.out.print(score[a] + "\t");
}
}
}


4.MVC各个字母的含义,以及使用mvc框架的好处?

1. 视图:视图代表用户交互界面,用于向用户显示相关的数据,并能接受用户的输入数据,它不执行任何实际的业务处理;
      视图还能接受模型发出的数据更新事件,从而对用户界面进行同步更新。(view)

2.控制器:控制器即是控制请求的处理逻辑,对请求进行处理,负责请 求转发; Controller

3·模型:模型代表着一种企业规范,就是业务流程/状态的处理以及业务规则的规定。业务流程的处理过程对其他层来说是不透明的,模型接受        视图数据的请求,并返回最终的处理结果。业务模型的设计可以说是MVC的核心Model

JSP Model1是JavaWeb早期的模型,它适合小型Web项目,开发成本低!Model1第一代时期,服务器端只有JSP页面,所有的操作都在JSP页面中,连访问数据库的API也在JSP页面中完成。也就是说,所有的东西都耦合在一起,对后期的维护和扩展极为不利。
(也就是最开始的jsp+servlet,所有的东西都耦合在一起)

二、MVC的优点 
1、可以为一个模型在运行时同时建立和使用多个视图。变化-传播机制可以确保所有相关的视图及时得到模型数据变化,从而使所有关联的视图和控制器做到行为同步。 
2、视图与控制器的可接插性,允许更换视图和控制器对象,而且可以根据需求动态的打开或关闭、甚至在运行期间进行对象替换。 
3、模型的可移植性。因为模型是独立于视图的,所以可以把一个模型独立地移植到新的平台工作。需要做的只是在新平台上对视图和控制器进行新的修改。 
4、潜在的框架结构。可以基于此模型建立应用程序框架,不仅仅是用在设计界面的设计中。 

三、MVC的不足之处 
1、增加了系统结构和实现的复杂性。对于简单的界面,严格遵循MVC,使模型、视图与控制器分离,会增加结构的复杂性,并可能产生过多的更新操作,降低运行效率。 
2、视图与控制器间的过于紧密的连接。视图与控制器是相互分离,但确实联系紧密的部件,视图没有控制器的存在,其应用是很有限的,反之亦然,这样就妨碍了他们的独立重用。 
3、视图对模型数据的低效率访问。依据模型操作接口的不同,视图可能需要多次调用才能获得足够的显示数据。对未变化数据的不必要的频繁访问,也将损害操作性能。 
4、目前,一般高级的界面工具或构造器不支持模式。改造这些工具以适应MVC需要和建立分离的部件的代价是很高的,从而造成MVC使用的困难。

总结:视图层:就是如js,html页面显示给客户,接受客户输入的数据,它不涉及任何的业务处理;
   控制层:接收前台发起的请求,并交给模型层处理,然后在转发处理的结果;
           模型层:主要是业务的处理,接收视图层的数据并进行处理,然后返回处理结果;
好处:层次分明,可以单独开发任何一个模块,提高了开发效率;提高了代码的复用性和可移植性;降低代码之间的耦合,便于维 护;
坏处:增加了系统结构和实现的复杂性。对于简单的界面,严格遵循MVC,使模型、视图与控制器分离,会增加结构的复杂性,并            可能产生过多的更新操作,降低运行效率。

springMVC和struts2的区别?

Struts2 处理请求是为每个请求都创建一个单独的Action类,Action类当中的Field属性参数作为输入和输出参数用IOC来依赖注入的方式,
是基于类的
SpringMVC 则采用输入Request和Reponse作为参数,返回ModelAndView的方式,是单例的模式,且是基于方法的模式。

我们用struts2时采用的传统的配置文件的方式,并没有使用传说中的0配置 
spring3 mvc可以认为已经100%零配置了(除了配置springmvc-servlet.xml外)
 
   

spring bean的几种状态?

singleton: 在Spring的IoC容器中只存在一个对象实例,所有该对象的引用都共享这个实例。Spring 容器只会创建该bean定义的唯一实例,这个实例会被保存到缓存中,并且对该bean的所有后续请求和引用都将返回该缓存中的对象实例,一般情况下,无状态的bean使用该scope。

prototype:每次对该bean的请求都会创建一个新的实例,一般情况下,有状态的bean使用该scope。request:每次http请求将会有各自的bean实例,类似于prototype。session:在一个http session中,一个bean定义对应一个bean实例。global session:在一个全局的http session中,一个bean定义对应一个bean实例。典型情况下,仅在使用portlet context的时候有效。其次说明spring的默认scope(bean作用域)是singleton

①问:scope类型什么时候声明为singleton,何时声明为prototype?

默认scope是singleton。

无状态的bean使用该scope。

有状态的bean使用prototype。

有状态和无状态会话bean的本质区别是它们的生命期。

bean保持了用户的信息,即“有状态”

无状态会话bean :bean一旦实例化就被加进会话池中,各个用户都可以共用。由于没有特定的用户,那么也就不能保持某一用户的状态,所以叫无状态bean。但无状态会话bean 并非没有状态,如果它有自己的属性(变量),那么这些变量就会受到所有调用它的用户的影响,这是在实际应用中必须注意的。

在ssh2 项目中 , struts2的action交由spring管理的时候 ,spring默认是singleton的 ,而struts2的action显然是有状态的 ,所以必须显示设置为 scope=“prototype”;但是对那些Dao的实现类推介scope=“singleton” ,因为这些类没有状态,用singleton只需维护一个实例,显然性能高一些。

③比较:

用singleton 的性能要高一些 ,因为只有一个实例;

④实际应用举例:

之前在开发过程中遇到了一个问题,当request发起下一个请求的时候,action中的属性值并没有清除,而是继续采用上次使用过的参数值进行查询并响应,导致数据查询不真实或失败。对此,有同事告诉我说,需要在spring配置文件的bean中添加属性scope=prototype。结果还真的有用。

例如:user这个bean,默认的Scope属性我们没有配置,也就是singleton模式

1
2
3
4
5
6
< bean  name = "user"  class = "com.fz.entity.User"  >
     < property  name = "id"  value = "1" ></ property >
     < property  name = "username"  value = "fangzheng" ></ property >
     < property  name = "password"  value = "123456" ></ property >
     < property  name = "role"  ref = "role" ></ property >
</ bean >

测试singleton,结果为true

1
2
3
4
5
6
7
@Test
public  void  getProperties(){
     ApplicationContext ctx =  new  ClassPathXmlApplicationContext( "applicationContext.xml" );
     User user1 = (User) ctx.getBean( "user" );
     User user2 = (User) ctx.getBean( "user" );
     System.out.println(user1 == user2); //结果为true   
}


添加scope=prototype

在<bean>上加入scope=prototype之后。

1
2
3
4
5
6
< bean  name = "user"  class = "com.fz.entity.User"  scope = "prototype" >
     < property  name = "id"  value = "1" ></ property >
     < property  name = "username"  value = "fangzheng" ></ property >
     < property  name = "password"  value = "123456" ></ property >
     < property  name = "role"  ref = "role" ></ property >
</ bean >

测试prototype,结果为false

1
2
3
4
5
6
7
@Test
public  void  getProperties(){
     ApplicationContext ctx =  new  ClassPathXmlApplicationContext( "applicationContext.xml" );
     User user1 = (User) ctx.getBean( "user" );
     User user2 = (User) ctx.getBean( "user" );
     System.out.println(user1 == user2); //结果为false
}

springMVC限制上传文件的大小?

在applicationContext.xml中添加:

[html]  view plain  copy
  1. <span style="font-size:18px;">    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">   
  2.          <!-- 指定所上传文件的总大小不能超过20M。注意maxUploadSize属性的限制不是针对单个文件,而是所有文件的容量之和 -->   
  3.          <property name="maxUploadSize" value="2000000"/><!-- 1G  1073741824 -->  
  4.          <property name="defaultEncoding" value="utf-8"></property>  
  5.          <property name="resolveLazily" value="true"></property>  
  6.      </bean></span>  

只需在控制层
[java]  view plain  copy
  1.     @ExceptionHandler  
  2.     public ModelAndView doException(Exception e, HttpServletRequest request) throws Exception {  
  3.         Map<String, Object> map = new HashMap<String, Object>();  
  4.         if (e instanceof MaxUploadSizeExceededException) {  
  5.             long maxSize = ((MaxUploadSizeExceededException) e).getMaxUploadSize();  
  6.             map.put("error""上传文件太大,不能超过" + maxSize / 1024 + "k");  
  7. //          response.setHeader("Content-type", "text/html;charset=UTF-8");  
  8. //          // 设置默认编码  
  9. //          response.setCharacterEncoding("UTF-8");  
  10. //          response.getWriter().write("上传文件太大,不能超过" + maxSize / 1024 + "k");  
  11.         } else if (e instanceof RuntimeException) {  
  12.             map.put("error""未选中文件");  
  13.         } else {  
  14.             map.put("error""上传失败");  
  15.         }  
  16.         return new ModelAndView("upload", map);  
  17.   
  18.     }  
即可拦截到上传文件大小

一个项目的生命周期?

 项目的生命周期:调研——需求分析——项目概要设计——项目详细设计——编码——单元测试——打包——测试人员——发布生产环境 

用递归的方式求n的阶乘?

public class aaa {  public static int Factorial(int n) {        if (n < 0) {            System.out.println("无效输入,请重新输入!");            return 0;        } else if (n == 1 || n == 0) {            return 1;        } else            return n * Factorial(n - 1);    }    public static void main(String[] args) {        System.out.println("请输入一个数字: ");        Scanner scanner = new Scanner(System.in);        int n = scanner.nextInt();        System.out.println("数字 "+n+"的阶乘是: "+Factorial(n));    }}

1.2.3.4随机产生3为不重复的随机数?

public class test {public static void main(String[] args) {int i=0;  //保存百位上的数int j=0;  //保存十位上的数int k=0;  //保存各位上的数int t=0;  //保存数字个数 for(i=1;i<=4;i++){   for(j=1;j<=4;j++){   for(k=1;k<=4;k++){    if(i!=j && j!=k && i!=k){         t+=1;        System.out.println(i*100+j*10+k);    }      }     }}System.out.println (t);}}

log4j的日志级别和输出地址

#设置logger级别DEBUG、INFO、WRNING、ERROR和输出格式A、B、C或D
log4j.rootLogger=DEBUG, A

#输出到控制台
log4j.appender.A=org.apache.log4j.ConsoleAppender
log4j.appender.A.layout=org.apache.log4j.PatternLayout
log4j.appender.A.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} [%c]-[%p] %m%n

#输出到E盘的log.log文件
log4j.appender.B=org.apache.log4j.FileAppender
log4j.appender.B.File=E:\\log.log
log4j.appender.B.layout=org.apache.log4j.SimpleLayout

#输出到E盘的log.html文件
log4j.appender.C=org.apache.log4j.RollingFileAppender
log4j.appender.C.File=E:\\log.html
log4j.appender.C.MaxFileSize=1000KB
log4j.appender.C.MaxBackupIndex=10
log4j.appender.C.layout=org.apache.log4j.HTMLLayout

log4j.appender.D=org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File=E:\\log.log
log4j.appender.D.layout=org.apache.log4j.TTCCLayout

1. 配置log输出目的地:

org.apache.log4j.ConsoleAppender(控制台)

org.apache.log4j.FileAppender(文件)

org.apache.log4j.DailyRollingFileAppender(每天产生一个日志文件)

org.apache.log4j.RollingFileAppender(文件大小到达指定尺寸的时候产生一个新的文件)

org.apache.log4j.WriterAppender(将日志信息以流格式发送到任意指定的地方)

2. log信息的格式:

org.apache.log4j.HTMLLayout(HTML表格形式)

org.apache.log4j.SimpleLayout(简单格式的日志,只包括日志信息的级别和指定的信息字符串 ,如:DEBUG - Hello)

org.apache.log4j.TTCCLayout(日志的格式包括日志产生的时间、线程、类别等等信息)

org.apache.log4j.PatternLayout(灵活地自定义日志格式)

当使用org.apache.log4j.PatternLayout来自定义信息格式时,可以使用log4j.appender.A1.layout.ConversionPattern=%d{yyyy-MM-ddHH:mm:ss} %p-%m%n 来格式化信息


基本数据类型和引用数据类型的区别?

基本类型:存储在栈(stack)中的简单数据段,它们的值直接存储在变量访问的位置。这是因为基本类型占据的空间是固定的,所以可将他们存储在较小的内存区域 – 栈中,这样存储便于迅速查询变量的值。

引用类型:存储在堆(heap)中的对象,存储在栈中的值是一个指针(point)用于指向存储对象的内存地址,这是因为引用类型值的大小会改变,所以不能把它放在栈中,否则会降低变量查寻的速度。相反存在栈中的值是该对象地址而地址的大小是固定的,所以把它存储在栈中对变量性能无任何影响。


在javascript中是不允许直接访问保存在堆内存中的对象的,所以在访问一个对象时,首先访问内存栈得到这个对象在内存堆中的地址,然后再按照这个地址去获得这个对象中的值,这就是传说中的按引用访问,而基本类型的值则是直接内存栈中。 

基本类型:在将一个保存着原始值的变量复制给另一个变量时,会将原始值的副本赋值给新变量,此后这两个变量是完全独立的,他们只是拥有相同的value而已。 

引用类型:在将一个保存着对象内存地址的变量复制给另一个变量时,会把这个内存地址赋值给新变量,也就是说这两个变量都指向了堆内存中的同一个对象,他们中任何一个作出的改变都会反映在另一个身上。(这里要理解的一点就是,复制对象时并不会在堆内存中新生成一个一模一样的对象,只是多了一个保存指向这个对象指针的变量)多了一个指针。

ECMAScript中所有函数的参数都是按值来传递的,但是为什么涉及到原始类型与引用类型的值时仍然有区别呢?还不就是因为内存分配时的差别。  
基本数据类型:只是把变量里的值复制一个副本然后传递给参数,之后参数和这个变量互不影响。
引用类型:因为它传递的值是内存地址,所以都是指向同一个对象;

Arrlist和vector在存储和删除上有什么区别?

  1. Vector与ArrayList一样,也是通过数组实现的,不同的是它支持线程的同步,即某一时刻只有一个线程能够写Vector,避免多线程同时写而引起的不一致性,但实现同步需要很高的花费,因此,访问它比访问ArrayList慢。
  2. vector是线程(Thread)同步(Synchronized)的,所以它也是线程安全的,而Arraylist是线程异步(ASynchronized)的,是不安全的。如果不考虑到线程的安全因素,一般用Arraylist效率比较高。
  3. 如果集合中的元素的数目大于目前集合数组的长度时,vector增长率为目前数组长度的100%,而arraylist增长率为目前数组长的50%.如过在集合中使用数据量比较大的数据,用vector有一定的优势。
  4. ArrayList 和Vector是采用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,
    都允许直接序号索引元素,但是插入数据要设计到数组元素移动 等内存操作,所以索引数据快插入数据慢,
    Vector由于使用了synchronized方法(线程安全)所以性能上比ArrayList要差

什么是线程安全?

如果你的代码所在的进程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。

sleep和wait()方法的区别?

1.  Java中sleep和wait的区别

① 这两个方法来自不同的类分别是,sleep来自Thread类,和wait来自Object类。

sleep是Thread的静态类方法,谁调用的谁去睡觉,即使在a线程里调用b的sleep方法,实际上还是a去睡觉,要让b线程睡觉要在b的代码中调用sleep。

② 锁: 最主要是sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法。

sleep不出让系统资源;wait是进入线程等待池等待,出让系统资源,其他线程可以占用CPU。一般wait不会加时间限制,因为如果wait线程的运行资源不够,再出来也没用,要等待其他线程调用notify/notifyAll唤醒等待池中的所有线程,才会进入就绪队列等待OS分配系统资源。sleep(milliseconds)可以用时间指定使它自动唤醒过来,如果时间不到只能调用interrupt()强行打断。

Thread.sleep(0)的作用是“触发操作系统立刻重新进行一次CPU竞争”。

③ 使用范围:wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在任何地方使用。

如何理解线程池?

线程池是预先创建线程的一种技术,线程池在还没有任务到来之前,创建一定数量的线程,放入到空闲队列中,然后对这些资源进行复用,每个工作线程都可以被重复利用,可执行多个任务。减少频繁的创建和销毁消耗资源,耗时间因为有的线程执行的时间比创建和销毁一个线程的时间还短那么线程池的作用就体现出来了.

线程池的属性
  • corePoolSize:核心池的大小,这个参数跟后面讲述的线程池的实现原理有非常大的关系。在创建了线程池后,默认情况下,线程池中并没有任何线程,而是等待有任务到来才创建线程去执行任务,除非调用了prestartAllCoreThreads()或者prestartCoreThread()方法,从这2个方法的名字就可以看出,是预创建线程的意思,即在没有任务到来之前就创建corePoolSize个线程或者一个线程。默认情况下,在创建了线程池后,线程池中的线程数为0,当有任务来之后,就会创建一个线程去执行任务,当线程池中的线程数目达到corePoolSize后,就会把到达的任务放到缓存队列当中;
  • maximumPoolSize:线程池最大线程数,这个参数也是一个非常重要的参数,它表示在线程池中最多能创建多少个线程;
  • keepAliveTime:表示线程没有任务执行时最多保持多久时间会终止。默认情况下,只有当线程池中的线程数大于corePoolSize时,keepAliveTime才会起作用,直到线程池中的线程数不大于corePoolSize,即当线程池中的线程数大于corePoolSize时,如果一个线程空闲的时间达到keepAliveTime,则会终止,直到线程池中的线程数不超过corePoolSize。但是如果调用了allowCoreThreadTimeOut(boolean)方法,在线程池中的线程数不大于corePoolSize时,keepAliveTime参数也会起作用,直到线程池中的线程数为0;
  • unit:参数keepAliveTime的时间单位,有7种取值,在TimeUnit类中有7种静态属性:


spring的事务是如何进行的?

事务的实现方式:实现方式共有两种:编码方式;声明式事务管理方式

基于AOP技术实现的声明式事务管理,实质就是:在方法执行前后进行拦截,然后再目标方法开始之前创建并加入事务,执行完目标方法后根据执行情况提交或回滚事务.

声明式事务管理又有两种实现方式:基于xml配置文件的方式;另一个实在业务方法上进行@Transaction注解,将事务规则应用到业务逻辑中

一种常见的事务管理配置:事务拦截器TransactionInterceptor和事务自动代理BeanNameAutoProxyCreator相结合的方式

 


spring现在使用的是哪个版本和之前有什么不一样?

springMVC的字符集编码

<!-- filters -->
  <filter>
    <filter-name>CharacterEncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
      <param-name>encoding</param-name>
      <param-value>UTF-8</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>CharacterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>


spring beanfactory和beanfactory?

org.springframework.beansorg.springframework.context包是Spring IoC容器的基础。BeanFactory提供的高级配置机制,使得管理任何性质的对象成为可能。ApplicationContextBeanFactory的扩展,功能得到了进一步增强,比如更易与Spring AOP集成、消息资源处理(国际化处理)、事件传递及各种不同应用层的context实现(如针对web应用的WebApplicationContext)。(它里面就只有6个方法,getbean(),issingleton(),contansbean(),gettype(), getAliases()),可以看出来它只关心,如何得到bean,是否为单利模式等等;至于bean在哪里根本不关心。

简而言之, BeanFactory提供了配制框架及基本功能,而 ApplicationContext则增加了更多支持企业核心内容的功能。 ApplicationContext完全由 BeanFactory扩展而来,因而 BeanFactory所具备的能力和行为也适用于 ApplicationContext
 
org.springframework.beans.factory.BeanFactory是Spring IoC 容器的实际代表者,IoC容器负责容纳此前所描述的bean,并对bean进行管理。
在Spring中, BeanFactory是IoC容器的核心接口。它的职责包括:实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。
Spring为我们提供了许多易用的 BeanFactory实现, XmlBeanFactory就是最常用的一个。该实现将以XML方式描述组成应用的对象以及对象间的依赖关系。 XmlBeanFactory类将持有此XML 配置元数据,并用它来构建一个完全
可配置的系统或应用。


spring  beanfactory是一个工厂类的接口,它提供了配置框架及基本的功能,但我们一般使用的它的实现类applicationContext,它具备beanfactory所有的功能和行为,同时也加入了一下企业级的应用。

在我们使用的过程中
我们首先会 private static ClassPathXmlApplicationContext applicationContext = null;  声明一个applicationContext的一个对象,也就是beanfactory的实现类.

然后用这个对象扫描applicationContext.xml文件,把配置文件中的bean扫描进去。
  applicationContext = new ClassPathXmlApplicationContext(new String[] { "applicationContext.xml" });

做完这两步之后,就可以调用这个对象的getbean()的方法,从容器中获得bean,这就是spring管理一个bean的整个过程

spring的bean 一般是在在bean的属性被调用的时候才会被加载进容器?

笼统的说
spring管理的bean在默认情况下是会在服务器启动的时候初始化的。
往细了的说
spring什么时候实例化bean,首先要分2种情况 

  第一:如果你使用BeanFactory作为Spring Bean的工厂类,则所有的bean都是在第一次使用该Bean的时候实例化 

  第二:如果你使用ApplicationContext作为Spring Bean的工厂类,则又分为以下几种情况:
 
       (1):如果bean的scope是singleton的,并且lazy-init为false(默认是false,所以可以不用设置),则ApplicationContext启动的时候就实例化该

Bean,并且将实例化的Bean放在一个map结构的缓存中,下次再使用该Bean的时候,直接从这个缓存中取 

       (2):如果bean的scope是singleton的,并且lazy-init为true,则该Bean的实例化是在第一次使用该Bean的时候进行实例化 

       (3):如果bean的scope是prototype的,则该Bean的实例化是在第一次使用该Bean的时候进行实例化 


要配置在服务器启动加载applicationcontext通常有两种方法:

(1)ContextLoaderListener

具体配置是在web.xml中增加:

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


(2)ContextLoaderServlet

具体配置是在web.xml中增加:

<servlet> 
    <servlet-name>context</servlet-name> 
    <servlet-class> 
       org.springframework.web.context.ContextLoaderServlet 
    </servlet-class> 
    <load-on-startup>1</load-on-startup> 
</servlet>

无论通过上面的哪一种配置都可以达到服务器启动即实例化bean的目的


如果要想指定applicationContext.xml的位置可以在增加:

<context-param> 
    <param-name>contextConfigLocation</param-name> 
    <param-value>/WEB-INF/appContext.xml</param-value> 
</context-param>

通过以上配置就可以达到在服务器启动时实例化指定的applicationContext.xml配置文件了。



maven的生命周期?

  Maven生命周期阶段详解

clean周期:

pre-clean:准备清理

clean:真正的清理工作

post-clean:执行清理后的一些后续工作

default周期:

validate:验证

initialize:初始化配置

generate-sources:生成源代码编译目录

process-sources:处理项目主资源文件,复制资源文件到outputclasspath

generate-resources:生成资源目录

process-resources:处理资源文件

complie:编译源代码

process-classes:处理编译后文件

generate-test-sources:生成测试目录

process-test-sources:处理项目测试资源文件,复制测试资源文件到outputclasspath

generate-test-resources:生成测试资源文件

process-test-resources:处理测试资源文件

test-compile:编译测试代码

process-test-classes:处理测试代码

test:单元测试运行测试代码

prepare-package:打包前的准备

package:将编译好的代码打包成为jar或者war或者ear等等

pre-integration-test:准备整体测试

integration-test:整体测试

post-integration-test:为整体测试收尾

verify:验证

install:安装到本地Maven库

deploy:将最终包部署到远程Maven仓库

site周期:

pre-site:准备生成站点

site:生成站点及文档

post-site:站点收尾

site-deploy:将生成的站点发布到服务器上


maven打包的方式和区别?

war是一个web模块,其中需要包括WEB-INF,是可以直接运行的WEB模块。

而jar一般只是包括一些class文件 在声明了Main_class之后是可以用java命令运行的.

它们都是压缩的包,拿Tomcat来说,将war文件包放置它的\webapps\目录下,启动Tomcat,这个包可以自动进行解压,
也就是你的web目录,相当于发布了。


war包:是做好一个web应用后,通常是网站,打成包部署到容器中。
jar包:通常是开发时要引用通用类,打成包便于存放管理。


mybatis各个标签

1、批量添加:

[html]  view plain  copy
  1. <insert id="batchInsert" parameterType="java.util.List">  
  2.     INSERT INTO STUDENT (id,name,sex,tel,address)  
  3.     VALUES   
  4.     <foreach collection="list" item="item" index="index" separator="," >  
  5.         (#{item.id},#{item.name},#{item.sex},#{item.tel},#{item.address})  

  6.     </foreach>  
  7. </insert>  

2、批量修改:

[html]  view plain  copy
  1. <update id="batchUpdate" parameterType="java.util.List">  
  2.     UPDATE STUDENT SET name = "250" WHERE id IN  
  3.     <foreach collection="list" item="item" index="index" open="(" separator="," close=")" >  
  4.         #{item}  
  5.     </foreach>  
  6. </update>  

3、批量删除:

[html]  view plain  copy
  1. <delete id="batchDelete" parameterType="java.util.List">  
  2.     DELETE FROM STUDENT WHERE id IN  
  3.     <foreach collection="list" index="index" item="item" open="(" separator="," close=")">   
  4.         #{item}   
  5.     </foreach>  
  6. </delete>  

  1. <choose> <when> <otherwise>

  1. <select id="findUserInfoByOneParam" parameterType="Map" resultMap="UserInfoResult">  
  2.         select * from userinfo   
  3.         <choose>  
  4.             <when test="searchBy=='department'">  
  5.                 where department=#{department}  
  6.             </when>  
  7.             <when test="searchBy=='position'">  
  8.                 where position=#{position}  
  9.             </when>  
  10.             <otherwise>  
  11.                 where gender=#{gender}  
  12.             </otherwise>  
  13.         </choose>  
  14.     </select>    
  
    otherwise必须要加上,如果没有加上的话就会把表中所有的数据都返回,这是一种极为不推荐的做法。实际生产环境下,如果该表的数据量非常大,这条语句被执行,就是一个巨大的坑!

d.请注意观察;这里的“searchBy”是一个自定义的字符串,读者也可以按照自己的命名习惯,重新定义

e.再特别说明一下,请注意,每一个等号后面的参数都带有单引号。这是这种用法必须必须必须有的。否则,就是直接抛异常!


mybatis中的if标签和choose标签的区别?

choose标签 如果达成一个条件就不再执行下一个条件,if标签一个还会执行下去、

Mybatis中#与$的区别

Mybatis中的#{}用于传递查询的参数,用于从dao层传递一个string参数过来(也可以是其他参数),select * from 表名 order by age=#{age}

Mybatis会把这个参数转换成一个字符串。select * from 表名 order by age="age" 相当于jdbc中的预编译,安全。

而${}一般用于order by的后面,Mybatis不会对这个参数进行任何的处理,直接生成了sql语句。例:传入一个年龄age的参数,select * from 表名 order by ${age}

Mybatis生成的语句为 select * from 表名 order by age Mybatis不会对$传递的参数做任何处理,相当于jdbc中的另外一种编译方式。

一般我们使用#{},不使用${},原因:

会引起sql注入,${}会直接参与sql编译。会影响sql语句的预编译。

需要写成 select * from ${tableName} where user_code = #{userCode}

所以,$符是直接拼成sql的 ,#符则会以字符串的形式 与sql进行拼接。


<![CDATA[   ]]> 是什么,这是XML语法。在CDATA内部的所有内容都会被解析器忽略。

如果文本包含了很多的"<"字符 <=和"&"字符——就象程序代码一样,那么最好把他们都放到CDATA部件中。

但是有个问题那就是 <if test="">   </if>   <where>   </where>  <choose>  </choose>  <trim>  </trim> 等这些标签都不会被解析,所以我们只把有特殊字符的语句放在 <![CDATA[   ]]>  尽量缩小 <![CDATA[  ]]> 的范围。

实例如下:

[java]  view plain  copy
  1. <select id="allUserInfo" parameterType="java.util.HashMap" resultMap="userInfo1">  
  2.   <![CDATA[  
  3.   SELECT newsEdit,newsId, newstitle FROM shoppingGuide  WHERE 1=1  AND  newsday > #{startTime} AND newsday <= #{endTime}  
  4.   ]]>  
  5.   <if test="etidName!=''">  
  6.    AND newsEdit=#{etidName}  
  7.   </if>  
  8.  </select>  
因为这里有 ">"  "<=" 特殊字符所以要使用 <![CDATA[   ]]> 来注释,但是有<if> 标签,所以把<if>等 放外面

springmvc中如何获取request,response,session

1.使用servlet api
  1. @RequestMapping(value = "manager/logout.do",method = RequestMethod.GET)  
  2.     public String logout(HttpSession httpSession){  
  3.         httpSession.getAttribute("manager"); 

1
public String hello(HttpServletRequest request,HttpServletResponse response) 

2.@session Attributes

springMVC如何去数组类型,集合类型,对象类型的数据?

获取数组类型的两种方式

1.声明一个数组,用json.stringify()转换为json类型,controller里用@requestBody(数组类型  【】数组名)
   如果有int,double,float等基本数据类型要用其包装类,否则当值为null的时候会报错
          例子

2.用@requestParam
$(function(){

var contacts = []; 
 contacts[0] = 'xiaoming'
 contacts[1] = 'daming';

$.ajax({ type:'GET'
 url:'demo/sendContacts'
 data:contacts,
success:function(result){ alert(result); } });})

controller
public String sendContents(@RequestParam(value = "contacts[]") String[] contacts)
value=" "一定要写  不写会报错的


获取集合数据的方式

  • 接收List<String>集合参数
  • 接收List<User>、User[]集合参
  • 接收List<Map<String,Object>>集合参数
和获得数组的方式一样,

 接收List<User>、User[]集合参数:
 接收List<User>、User[]集合参数:
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值