47

これは就職の面接で使用されるプログラミングテストです。私はそれが非常に奇妙な非OOの観点を持っていることを発見し、なぜ誰もがこの観点からコンストラクターにアプローチするのだろうかと思います。非常に経験豊富なJavaプログラマーとして、私はすぐにこのコードを書いた個人の能力と質問の奇妙な見方に疑問を投げかけます。

面接に関するこれらの奇妙な文脈外の質問は気がかりです。他の経験豊富なOOJavaプログラマーからのフィードバックが欲しいです。

ソルバーコンストラクターを完成させて、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;
    }
} 
4

9 に答える 9

38

これは、可能な限り単純な方法を使用して、デザインパターンをテストしています。これは戦略(または他の行動パターン)である可能性があると思います。これらを参照してください:

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

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

Javaの面接に行く場合は、彼らが示唆しているデザインパターンを特定できるはずです。これにより、不安になりすぎないようにすることができます。

質問に答えるには、MathFunction必要に応じて実装する2つのクラスを作成してから、2つのインスタンスを作成し、それらをに格納しますfunctionList

ここでのポイントは、 「この奇妙な方法で計算を実行できるか」ではなく、「デザインパターンを識別できるか」です

于 2012-08-21T14:51:13.747 に答える
6

私見、それは確かに奇妙なアプローチです。名前Solverは一般的であり、デフォルトで特定の操作を実装するべきではありません。しかし、それはインタビューの一部だったのでしょうか?パート1:要求を満たすだけです。パート2:そうするのは奇妙だと言ってください。

もっと良いアプローチは、addMathFunction(MathFunction mf)メソッドを持つことだと思います。また、必要に応じて、クラスを拡張するサブクラスを作成Solverし、コンストラクターにMathFunctionsを追加します。

于 2012-08-21T14:53:18.233 に答える
3

これがおそらく最善の方法ではない、またはこれを行うためのほとんどのOOの方法ではないことに同意しますが、この演習のポイントは、継承、インターフェイス、およびおそらく匿名の内部クラスをどれだけよく理解するかを確認することであると想定する必要があります。それが私が理解できる唯一のことです。

于 2012-08-21T14:52:15.047 に答える
3

関数リストに2つの項目を追加してほしいと思っていたと思います。それぞれがMathFunctionインターフェースを実装し、1つは平方根用、もう1つは逆関数用です。問題は詳細にあります:

1- 2つの異なることを行うため、2つの値を返す関数があります。これは悪いことです。

2-この「すべてを行う」クラスが必要な場合は、Mathfunctionsをパラメーターとして受け取り、あらゆる種類のMathFunctionsを実行できるようにすることをお勧めします。これにより、MathFunctionsはパラメーター化可能になります。

于 2012-08-21T14:53:36.760 に答える
3

これが私の解決策です。これは、ファクトリ クラスの簡単な図です。

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

この質問は、次の 2 つのことを示しています。

  • プログラマーが逆数などの数学用語を理解しているかどうか。
  • インターフェイスまたはクラスのインスタンスをリストに格納し、後で反復できることをプログラマーが理解しているかどうか。
于 2012-08-21T14:56:42.857 に答える
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;
        }
    }
}
于 2013-01-06T01:50:29.047 に答える
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));

}

}
于 2015-01-09T23:48:24.320 に答える