Java程序员面试题集(151-180)

Java面试题集(151-180)
摘要:这部分包含了Spring、Spring MVC、MyBatis、Spring和其他框架整合以及测试相关的内容,除此之外还包含了大型网站技术架构相关面试内容。

  1. Spring中的BeanFactory和ApplicationContext有什么联系?
    答:Spring通过配置文件描述Bean以及Bean之间的依赖关系,利用Java的反射机制实现Bean的实例化,并建立Bean之间的依赖关系,在此基础上,Spring的IoC容器还提供了Bean实例缓存、生命周期管理、Bean实例代理、事件发布、资源装载等高级服务。BeanFactory是Spring框架最核心的接口,它提供了IoC容器的配置机制。ApplicationContext建立在BeanFactory之上,提供了更多面向应用的功能,包括对国际化和框架事件体系的支持。通常将BeanFactory称为IoC容器,而ApplicationContext称为应用上下文,前者更倾向于Spring本身,后者更倾向于开发者,因此被使用得更多。
    【补充】反射(reflection)又叫自省(introspection),是获得对象或类型元数据的方法,Java反射机制可以在运行时判断对象所属的类,在运行时构造任意一个类的对象,在运行时获得一个类的属性和方法,在运行时调用对象的方法,或者生成动态代理。在Java中,可以通过类的Class对象获得类的构造器、属性、方法等类的元数据,还可以访问这些属性或调用这些方法,和反射相关的类还包括:
    Constructor:代表类的构造器的类。通过Class对象的getConstructors方法可以获得类的所有构造器的数组,Java 5以后的版本还可以通过getConstrcutor(Class… parameterTypes)获得拥有特定参数的构造器对象。Constructor对象的一个主要方法是newInstance,通过该方法可以创建一个类的实例。
    Method:代表方法的类。通过Class对象的getDeclaredMethods方法可以获得所有方法的数组,Java 5以后的版本还可以通过getDeclaredMethod(String name, Class… parameterTypes)获得特定签名的方法,其中name是方法名,可变参数代表方法的参数列表。Method对象最重要的方法是invoke(Object obj, Object[] args),其中obj是调用该方法的目标对象,args是传给方法的参数,这样就可以调用指定对象的方法。此外,Method对象还包括以下重要方法:
    Class getReturnType():获取方法的返回类型。
    Class[] getParameterTypes():获取方法参数类型的数组。
    Class[] getExceptionTypes():获取方法异常类型数组。
    Annotation[][] getParameterAnnotations():获得方法参数注解信息的数组。
    Field:代表属性的类。通过Class对象的getDeclaredFields()方法可以获取类的属性数组。通过getDeclaredField(String name)则可以获取某个特定名称的属性。Field对象最重要的方法是set(Object obj, Object value),其中obj是目标对象,而value是要赋给属性的值。
    除此之外,Java还提供了Package类用于包的反射,Java 5以后的版本还提供了AnnotationElement类用于注解的反射。总之,Java的反射机制保证了可以通过编程的方式访问目标类或对象的所有元素,对于被private和protected访问修饰符修饰的成员,只要JVM的安全机制允许,也可以通过反射进行调用。下面是一个反射的例子:
    Car.java
    [java] view plaincopy
    package com.lovo;

public class Car {
private String brand;
private int currentSpeed;
private int maxSpeed;

public Car(String brand, int maxSpeed) {  
    this.brand = brand;  
    this.maxSpeed = maxSpeed;  
}  

public void run() {  
    currentSpeed += 10;  
    System.out.println(brand + " is running at " + currentSpeed + " km/h");  
    if(currentSpeed > maxSpeed) {  
        System.out.println("It's dangerous!");  
    }  
}  

}
CarTest.java
[java] view plaincopy
package com.lovo;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class CarTest {

public static void main(String[] args) throws Exception {  
    Constructor<Car> con = Car.class.getConstructor(String.class, int.class);  
    Car myCar = (Car) con.newInstance("Benz", 280);  
    Method m = myCar.getClass().getDeclaredMethod("run");  
    for(int i = 0; i < 10; i++) {  
        m.invoke(myCar);  
    }  
    Field f1 = myCar.getClass().getDeclaredField("maxSpeed");  
    Field f2 = myCar.getClass().getDeclaredField("brand");  
    f1.setAccessible(true);  
    f1.set(myCar, 80);  
    f2.setAccessible(true);  
    f2.set(myCar, "QQ");  
    m.invoke(myCar);  
}  

}
运行结果:

  1. Spring中Bean的作用域有哪些?
    答:在Spring的早期版本中,仅有两个作用域:singleton和prototype,前者表示Bean以单例的方式存在;后者表示每次从容器中调用Bean时,都会返回一个新的实例,prototype通常翻译为原型,而设计模式中的创建型模式中也有一个原型模式,原型模式也是一个常用的模式,例如做一个室内设计软件,所有的素材都在工具箱中,而每次从工具箱中取出的都是素材对象的一个原型,可以通过对象克隆来实现原型模式。Spring 2.x中针对WebApplicationContext新增了3个作用域,分别是:request(每次HTTP请求都会创建一个新的Bean)、session(同一个HttpSession共享同一个Bean,不同的HttpSession使用不同的Bean)和globalSession(同一个全局Session共享一个Bean)。
    需要指出的是:单例模式和原型模式都是重要的设计模式。一般情况下,无状态或状态不可变的类适合使用单例模式。在传统开发中,由于DAO持有Connection这个非线程安全对象因而没有使用单例模式;但在Spring环境下,所有DAO类对可以采用单例模式,因为Spring利用AOP和Java API中的ThreadLocal对非线程安全的对象进行了特殊处理。
    【补充】ThreadLocal为解决多线程程序的并发问题提供了一种新的思路。ThreadLocal,顾名思义是线程的一个本地化对象,当工作于多线程中的对象使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程分配一个独立的变量副本,所以每一个线程都可以独立的改变自己的副本,而不影响其他线程所对应的副本。从线程的角度看,这个变量就像是线程的本地变量。
    ThreadLocal类非常简单好用,只有四个方法,能用上的也就是下面三个方法:
    void set(T value):设置当前线程的线程局部变量的值。
    T get():获得当前线程所对应的线程局部变量的值。
    void remove():删除当前线程中线程局部变量的值。
    ThreadLocal是如何做到为每一个线程维护一份独立的变量副本的呢?在ThreadLocal类中有一个Map,键为线程对象,值是其线程对应的变量的副本,自己要模拟实现一个ThreadLocal类其实并不困难,代码如下所示:
    [java] view plaincopy
    package com.lovo;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

public class MyThreadLocal {
private Map

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值