Java编程testing面试

这是面试中使用的编程testing。 我发现它有一个非常奇怪的非面向对象的观点,并想知道为什么有人会从这个angular度来看待构造函数。 作为一个非常有经验的Java程序员,我立即质疑编写这个代码的人的能力和这个问题的奇怪的视angular。

我在面试中发现这些奇怪的问题。 我会喜欢其他有经验的OO Java程序员的反馈。

完成Solver构造函数,以便对resolveAll的调用返回包含平方根和作为parameter passing的整数的倒数的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; } } 

这是通过使用最简单的方法来testing您的devise模式。 我认为这可能是战略(或其他一些行为模式)。 看到这些:

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

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

如果您要参加Java面试,您应该能够确定他们所暗示的devise模式,并且应该能够防止您太不稳定!

要回答这个问题,创build两个按需实现MathFunction类,然后创build两个实例并将它们存储在functionList

这里的重点不是 “你能用这种奇怪的方式来做计算吗”,而是“你能确定devise模式”吗?

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

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

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

你知道我的答案,但是为了什么值得…

 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); } }); } 

恕我直言,这确实是一个奇怪的做法。 Solver这个名称是通用的,它不应该默认实现特定的操作。 但是,也许这是面试的一部分? 第一部分:简单地完成请求。 第二部分:说这样做很奇怪。

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

我想他们希望你在函数列表中添加两个项目。 每个实现MathFunction接口,一个用于平方根,一个用于反函数。 细节在于:

1-你有一个返回2个值的函数,因为它做了两件不同的事情,那是不好的

2-如果你想拥有这个“全力以赴”的课程,那么接受Mathfunctions作为一个参数将是有趣的,所以你可以做任何types的MathFunctions,MathFunctions将是可参数化的

这是我的解决scheme。 这是一个工厂类的简单说明。

 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); } 

这个问题显示了两件事情:

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

虽然我同意这可能不是最好的方式,或者大多数OO的方式来做到这一点,但我不得不假设这个练习的重点是看你有多了解inheritance,接口和可能是匿名的内部类。 这是我唯一可以确定的事情。

好吧,我把解决scheme编码到我自己的问题上。 我的本能,没有什么应该是在构造似乎是正确的。 functionList不是静态的,所以你需要一个实例来初始化它。 它指定整数,所以我四舍五入到整数。 反函数不以任何方式高级math。

 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); } 

有点做作,似乎更接近装饰模式给我。 不知道我会在面试时说些什么,但是这里是我如何编码的:

 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; } } } 

在构造函数中做这一切只是不好的做法。 无论如何,我的所有function于一身的解决scheme。

 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)); } }