面试的Java编程测试

时间:2012-08-21 14:46:26

标签: java oop

这是在求职面试中使用的编程测试。我发现它有一个非常奇怪的非OO视角,并想知道为什么有人会从这个角度来看待构造函数。作为一名非常有经验的Java程序员,我立即质疑编写此代码的个人的能力以及该问题的奇怪观点。

我发现这些奇怪的脱离背景问题令人不安。我希望得到其他经验丰富的OO Java程序员的反馈。

  

完成Solver构造函数,以便对solveAll的调用返回包含2个值的列表   包括平方根和作为参数传递的整数的倒数。

public interface MathFunction {
    double calculate(double x);
}

public class Solver {

    private List<MathFunction> functionList;

    public Solver() { 

        //Complete here

    }

    public List<Double> solveAll(double x) {
        List<Double> result = new ArrayList<Double>();
        for (MathFunction function : this.functionList) {
            result.add(new Double(function.calculate(x)));
        }

        return result;
    }
} 

9 个答案:

答案 0 :(得分:38)

这是通过使用最简单的方法测试您的设计模式。我认为这可能是战略(或其他一些行为模式)。见这些:

http://en.wikipedia.org/wiki/Strategy_pattern

http://en.wikipedia.org/wiki/Behavioral_pattern

如果您正在进行Java面试,您应该能够确定他们所暗示的设计模式,这样可以防止您过于不稳定!

要回答这个问题,请根据需要创建两个实现MathFunction的类,然后创建两个实例并将它们存储在functionList中。

这里的要点是'你可以用这种奇怪的方式进行计算',它是'你可以识别设计模式'。

答案 1 :(得分:31)

我同意这是令人困惑和过度设计的。

但我确实认为代码是合理的面向对象的。这是战略模式的一个实例。生成答案列表的代码并不关心如何计算答案 - 这两个问题是分开的,可以应用不同的计算策略而无需触及生成列表的代码。 / p>

为了使类更有用,这些函数应该从外部传递(即依赖注入),而不是在构造函数中实例化。

我知道答案,但我认为这是值得的......

public Solver() {
    functionList = new ArrayList<MathFunction>();

    functionList.add(new MathFunction() {

        @Override
        public double calculate(double x) {
            return 1d/x;
        }
    });

    functionList.add(new MathFunction() {

        @Override
        public double calculate(double x) {
            return Math.sqrt(x);
        }
    });
}

答案 2 :(得分:6)

恕我直言,这确实是一种奇怪的做法。名称Solver是通用名称,默认情况下不应实现特定操作。然而,也许这是采访的一部分?第一部分:简单地完成请求。第二部分:说这样做很奇怪。

我想说一个更好的方法是使用addMathFunction(MathFunction mf)方法。如果需要,可以创建扩展Solver类的子类,并在其构造函数中添加MathFunction。

答案 3 :(得分:3)

虽然我同意这可能不是最好的方式,或者大多数OO方式来做到这一点,但我必须假设这个练习的目的是看你对继承,接口和匿名内部类的理解程度。这是我唯一能想到的。

答案 4 :(得分:3)

我认为他们希望你在功能列表中添加两个项目。每个都将实现MathFunction接口,一个用于平方根,一个用于反向。 问题在于细节:

1-你有一个返回2个值的函数,因为它有两个不同的东西,那就是坏的

2-如果你想要这个“do-it-all”类,那么接收Mathfunctions作为参数会很有趣,这样你可以做任何类型的MathFunctions,MathFunctions可以参数化

答案 5 :(得分:3)

这是我的解决方案。这是factory class的简单说明。

public Solver() { 
    functionList = new ArrayList<MathFunction>();
    MathFunction sqrt = new MathFunction() {
        @Override
        public double calculate(double x) {
            return Math.sqrt(x);
        }

    };
    functionList.add(sqrt);
    MathFunction inverse = new MathFunction() {
        @Override
        public double calculate(double x) {
            return 1.0D / x;
        }

    };
    functionList.add(inverse);
}

这个问题显示了两件事:

  • 程序员是否理解像逆的数学术语。
  • 程序员是否理解接口或类的实例可以存储在列表中,并在以后进行迭代。

答案 6 :(得分:3)

好的,我将解决方案编码为我自己的问题。我的本能是构造函数中没有任何东西似乎是正确的。 functionList不是静态的,因此您需要一个实例来初始化它。它指定整数,所以我舍入到整数。反函数不是任何高级数学。

import java.util.ArrayList;
import java.util.List;
import java.lang.Math;

public class Solver {

    private List<MathFunction> functionList = new ArrayList<MathFunction>();;

    public Solver() { 

// Complete here

    }

    public void initFunctionList() {

        MathFunction functionSquareRoot = new MathFunction(){

            @Override
            public double calculate(double x) {
                return (x<0 ? 0: Math.sqrt(x));  // maybe we need throw an exception here for negative numbers, but we'll just set it to 0
            }};

        MathFunction functionInverse = new MathFunction(){

            @Override
            public double calculate(double x) {
                return (x!=0.0 ? 1/x : 0);
            }

        };

        functionList.add(functionSquareRoot);
        functionList.add(functionInverse);

    }

    public List<Double> solveAll(double x) {
        List<Double> result = new ArrayList<Double>();

        for (MathFunction function : this.functionList) {
            result.add(new Double(function.calculate(x)));
        }

        return result;
    }

}


public interface MathFunction {
     double calculate(double x);
}


public class TestSolver {

    /**
     * @param args
     */
    public static void main(String[] args) {
        Solver s = new Solver();
        s.initFunctionList();
        System.out.println(s.solveAll(16.0));

    }

}

我误导了构造函数可以

public Solver() { 

// Complete here
        MathFunction functionSquareRoot = new MathFunction(){

            @Override
            public double calculate(double x) {
                return (x<0 ? 0: Math.sqrt(x));  // maybe we need throw an exception here for negative numbers, but we'll just set it to 0
            }};

        MathFunction functionInverse = new MathFunction(){

            @Override
            public double calculate(double x) {
                return (x!=0.0 ? 1/x : 0);
            }

        };

        functionList.add(functionSquareRoot);
        functionList.add(functionInverse);

    }

答案 7 :(得分:2)

有点做作,似乎更接近装饰模式给我。 我不确定在采访中我会说些什么,但这是我将如何编码:

package math;

import java.util.ArrayList;
import java.util.List;

public class DecoratorMath 
{

    interface MathFunction 
    {
        double calculate(double x);
    }

    public static void main(String[] args) 
    {
        DecoratorMath decoratorMath =  new DecoratorMath();
        decoratorMath.go();
    }

    public void go() 
    {
        Solver solver = new Solver();
        decorate(solver);
        List<Double> results = solver.solveAll(02);
        for (Double d :results) 
        {
            System.out.println(d);
        }
    }

    public void decorate(Solver solver)
    {
        solver.addFunction(new MathFunction() 
        {
            @Override
            public double calculate(double x) 
            {
                return Math.sqrt(x);
            }
        });

        solver.addFunction(new MathFunction() 
        {
            @Override
            public double calculate(double x) 
            {
                return 1d/x;
            }
        });
    }

    class Solver
    {
        private List<MathFunction> mathFunctions = new ArrayList<MathFunction>();

        public void addFunction(MathFunction mathFunction)
        {
            mathFunctions.add(mathFunction);
        }

        public List<Double> solveAll(double x) 
        {
            List<Double> result = new ArrayList<Double>();
            for (MathFunction function : mathFunctions) 
            {
                result.add(new Double(function.calculate(x)));
            }
            return result;
        }
    }
}

答案 8 :(得分:0)

在构造函数中执行此操作只是一种不好的做法。无论如何,我的一体化解决方案。

import java.util.*;
import java.math.*;

//sqrt / inverse

public class Solver{

  private List<MathFunction> functionList;

  public interface MathFunction{
     double calculate(double x);
  }

  class X implements MathFunction {
    public double calculate(double x) {
      return Math.sqrt(x); 
  } 
  }

    class Y implements MathFunction {
    public double calculate(double y) {
      return 1/y; 
  } 
  }



  public Solver(){
  //here
    functionList = new ArrayList<MathFunction>();

    MathFunction f =  (MathFunction) new X();
    functionList.add(f);  

    MathFunction f2 =  (MathFunction) new Y();
    functionList.add(f2);

  }


  public List<Double> solveAll(double x){ 

  List<Double> result=new ArrayList<Double>();

    for (MathFunction function : this.functionList){

      result.add(new Double(function.calculate(x)));

    }

    return result;

  }

public static void main(String... args) {

    System.out.println("result="+new Solver().solveAll(123));

}

}