面试2

项目开发经历了哪几个阶段?

  1. 1.         需求分析:需求规格说明书(确定项目功能用例图)

  2. 2.         软件概要设计:概要设计说明书(软件模块划分,软件开发技术)

  3. 3.         软件详细设计:详细设计说明书(类图、序列图、数据库模型)

  4. 4.         编码:最终代码

  5. 5.         测试:测试计划、测试用例

  6. 6.         实施:用户安装手册、用户使用手册

  7. 7.         维护

  8. 2.白盒测试和黑盒测试

 从测试是否针对系统的内部结构和具体实现算法的角度来看,可分为白盒测试和黑盒测试;

1、黑盒测试

黑盒测试也称功能测试或数据驱动测试,它是在已知产品所应具有的功能,通过测试来检测每个功能是否都能正常使用,在测试时,把程序看作一个不能打开的黑盆子,在完全不考虑程序内部结构和内部特性的情况下,测试者在程序接口进行测试,它只检查程序功能是否按照需求规格说明书的规定正常使用,程序是否能适当地接收输入数锯而产生正确的输出信息,并且保持外部信息(如数据库或文件)的完整性。

黑盒测试方法主要有等价类划分、边值分析、因―果图、错误推测等,主要用于软件确认测试。“黑盒”法着眼于程序外部结构、不考虑内部逻辑结构、针对软件界面和软件功能进行测试。“黑盒”法是穷举输入测试,只有把所有可能的输入都作为测试情况使用,才能以这种方法查出程序中所有的错误。实际上测试情况有无穷多个,人们不仅要测试所有合法的输入,而且还要对那些不合法但是可能的输入进行测试。

2、白盒测试

  白盒测试也称结构测试或逻辑驱动测试,它是知道产品内部工作过程,可通过测试来检测产品内部动作是否按照规格说明书的规定正常进行,按照程序内部的结构测试程序,检验程序中的每条通路是否都有能按预定要求正确工作,而不顾它的功能,白盒测试的主要方法有逻辑驱动、基路测试等,主要用于软件验证。

“白盒”法全面了解程序内部逻辑结构、对所有逻辑路径进行测试。“白盒”法是穷举路径测试。在使用这一方案时,测试者必须检查程序的内部结构,从检查程序的逻辑着手,得出测试数据。贯穿程序的独立路径数是天文数字。但即使每条路径都测试了仍然可能有错误。第一,穷举路径测试决不能查出程序违反了设计规范,即程序本身是个错误的程序。第二,穷举路径测试不可能查出程序中因遗漏路径而出错。第三,穷举路径测试可能发现不了一些与数据相关的错误。

3.面向对象设计原则有哪些

面向对象设计原则是面向对象设计的基石,面向对象设计质量的依据和保障,设计模式是面向对象设计原则的经典应用

  1. 1.         单一职责原则SRP

  2. 2.         开闭原则OCP

  3. 3.         里氏替代原则LSP

  4. 4.         依赖注入原则DIP

  5. 5.         接口分离原则ISP

  6. 6.         迪米特原则LOD

  7. 7.         组合/聚合复用原则CARP

开闭原则具有理想主义的色彩,它是面向对象设计的终极目标。其他设计原则都可以看作是开闭原则的实现手段或方法

4.写出简单工厂模式的示例代码

publicclass SimpleFactory {

    publicstatic Product createProduct(String pname){

        Productproduct=null;

        if("p1".equals(pname)){

            product= new Product1();

        }elseif("p2".equals(pname)){

            product= new Product2();

        }elseif("pn".equals(pname)){

            product= new ProductN();

        }

        return product;

    }

}

基本原理:由一个工厂类根据传入的参数(一般是字符串参数),动态决定应该创建哪一个产品子类这些产品子类继承自同一个父类或接口)的实例,并以父类形式返回

优点:客户端不负责对象的创建,而是由专门的工厂类完成;客户端只负责对象的调用,实现了创建和调用的分离,降低了客户端代码的难度;

缺点:如果增加和减少产品子类,需要修改简单工厂类,违背了开闭原则;如果产品子类过多,会导致工厂类非常的庞大,违反了高内聚原则,不利于后期维护

5.写出单例模式的示例代码

/**

 * 饿汉式的单例模式

 * 在类加载的时候创建单例实例,而不是等到第一次请求实例的时候的时候创建

* 1、私有的无参数构造方法Singleton(),避免外部创建实例

 * 2、私有静态属性instance

 * 3、公有静态方法getInstance()

 */

publicclass Singleton {

    privatestatic Singleton instance = new Singleton();   

    private Singleton(){    }

    publicstatic SingletongetInstance(){ 

        returninstance;

    }

}

/**

 * 懒汉式的单例模式

 *在类加载的时候不创建单例实例,只有在第一次请求实例的时候的时候创建

*/

publicclass Singleton {   

    privatestatic Singleton instance

    private Singleton(){    }

    /**

     * 多线程情况的单例模式,避免创建多个对象

    */

    publicstatic SingletongetInstance(){

        if(instance ==null){//避免每次加锁,只有第一次没有创建对象时才加锁

            synchronized(Singleton.class){//加锁,只允许一个线程进入

                if(instance==null){ //只创建一次对象

                    instance = new Singleton();

                }          

            }

        }

        returninstance;

    }

}

6.请对你所熟悉的一个设计模式进行介绍

分析:建议挑选有一定技术难度,并且在实际开发中应用较多的设计模式。此处挑选动态代理设计模式。讲解思路:生活案例引入、技术讲解、优缺点分析、典型应用。

1、生活案例引入

生活中托人办事,代理人可以在办理被托付之事的前后同时办理其他事情。

1、  技术讲解

代理模式的定义:对其他对象提供一种代理以控制对这个对象的访问。代理模式的思想是为了提供额外的处理或者不同的操作而在实际对象与调用者之间插入一个代理对象。这些额外的操作通常需要与实际对象进行通信。

代理模式一般涉及到的角色

  • 抽象角色:真实对象和代理对象的共同接口

  • 真实角色:真实对象,最终要引用的对象

  • 代理角色

  • 内部含有对真实对象的引用,从而可以操作真实对象

  • 提供与真实对象相同的接口以便在任何时刻代替真实对象

  • 可在执行真实对象操作前后附加其他操作,相当于对真实对象进行封装

wKioL1Q1JCfQ0odxAACCQO-mEQA395.jpg

包括静态代理模式和动态代理模式,在实际开发中应用广泛的是动态代理模式,关键代码如下。

publicclass AuthLogHandler implementsInvocationHandler {

    private Object target//目标对象

    publicAuthLogHandler(Object target) {//注入目标对象

        super();

        this.target = target;

    }  

    public Objectinvoke(Object proxy, Method method, Object[] args)

            throws Throwable {

        doBefore();//前置操作      

        Objectresult =method.invoke(target, args);//调用目标对象   

        doAfter();  //后置操作

        return result;

    }

    /**

     * 返回动态代理对象

     */

    public Object getProxy(){

  return Proxy.newProxyInstance(target.getClass().getClassLoader(),

                target.getClass().getInterfaces(),this);

    }

}

3、优缺点分析

1)    优点:不需要修改目标对象就实现了功能的增加

2)   缺点(静态代理)

a)   真实角色必须是事先已经存在的,并将其作为代理对象的内部属性。如果事先并不知道真实角色则无法使用

b)   一个接口(或者一个真实角色)必须对应一个代理角色,大量使用会导致类的急剧膨胀

3)   静态代理和动态代理的比较

a)   静态代理类确实存在,动态代理类在运行期动态生成

b)   一个真实角色必须对应一个静态代理角色,而动态代理大大减少了代理类的数量

c)         动态代理类不会作实质性的工作,在生成它的实例时必须提供一个handler,由它接管实际的工作(会自动执行handler的invoke方法)

4、典型应用

  • 使用代理实现Hibernate中的延迟加载:通过代理模式来降低系统的内存开销、提升应用的运行性能。Hibernate 充分利用了代理模式的这种优势,并结合了 Javassist CGLIB 来动态地生成代理对象,这更加增加了代理模式的灵活性。

  • 使用动态代理实现SpringAOP功能:如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP;如果目标对象实现了接口,可以强制使用CGLIB实现AOP;如果目标对象没有实现了接口,必须采用CGLIB库,spring会自动在JDK动态代理和CGLIB之间转换。


你可能感兴趣的:(面试2)