19

このコードを実行せずに、Foo呼び出されるメソッドを特定します。

class A
{
   public void Foo( int n )
   {
      Console.WriteLine( "A::Foo" );
   }
}

class B : A
{
   /* note that A::Foo and B::Foo are not related at all */
   public void Foo( double n )
   {
      Console.WriteLine( "B::Foo" );
   }
}

static void Main( string[] args )
{
   B b = new B();
   /* which Foo is chosen? */
   b.Foo( 5 );
}

どの方法ですか?なぜ?コードを実行しても不正行為はありません。

このパズルは Web で見つけました。私はそれが好きで、インタビューの質問として使用するつもりだと思います...意見はありますか?

編集:私はこれを間違って候補者を判断するつもりはありません.C#とCLR自体についてより完全な議論を開く方法としてそれを使用するので、候補者の能力をよく理解することができます.

ソース: http://netpl.blogspot.com/2008/06/c-puzzle-no8-beginner.html

4

15 に答える 15

57

私は本当にこれをインタビューの質問として使用しません. 私はその答えとその背後にある理由を知っていますが、このようなことはめったに起こらないので、問題にはなりません。答えを知っていても、受験者のコーディング能力はあまりわかりません。

A.Foo が virtual であり、B がそれをオーバーライドする場合でも、同じ動作が得られることに注意してください。

C# のパズルや奇妙なものが好きなら、私もいくつか持っています (これも含めて)

于 2008-09-30T17:37:25.257 に答える
26

あまりにもハード?いいえ、しかし、質問の目的は何ですか? 面接官から何を得ることを期待していますか。彼らがこの特定の構文の癖を知っているということですか? それは、彼らが仕様/言語をよく研究したか (彼らにとって良いことです)、またはこの問題に遭遇したことを意味します (彼らが書いたものからではないことを願っていますが、彼らがそうした場合は - うんざりです)。どちらの場合も、確かなプログラマー/エンジニア/アーキテクトが手元にあることを示しているわけではありません。重要なのは質問ではなく、質問をめぐる議論だと思います。

私が候補者に面接するとき、私は通常、言語の意味の癖に基づいた一見単純な質問を 1 つ尋ねます。しかし、面接を受ける人がそれを知っているかどうかは気にしません。私の候補者が几帳面かどうか、彼らのコミュニケーションスタイル、彼らが「わからない」と言うことをいとわないかどうか、彼らは自分の足で考えることができるかどうか、彼らは言語設計と機械アーキテクチャを理解しているかどうか、彼らはプラットフォームと移植性を理解しているかどうか問題 - 要するに、私は「彼らはそれを理解できますか?」につながる多くの成分を探しています. このプロセスには 1 時間以上かかります。

結局のところ、彼らが私の質問に対する答えを知っているかどうかは、実際には気にしません。この質問は、質問することなく、残りのすべての情報を間接的に取得できるようにするための策略です。この質問に価値のある秘密がない場合は、それを尋ねることさえ気にしないでください。あなたと候補者の時間を無駄にしています.

于 2008-09-30T18:41:58.860 に答える
12

そこでジョエルに同意することはできませんでした。私は 20 年以上の設計とコーディングの経験があり、それを見たときに最初に考えたのは、コンパイルすらできないということでした。

単一のデータ型だけが異なるオーバーロードを回避しようとしており、コードを見ても int/double の違いに気付かなかったので、私はその仮定をしました。B で再定義できるようにするには、新しい演算子が必要だと思いました。

実際のところ、テキスト ファイルの生成を処理するために仲間のプログラマーが作成したライブラリを使用していましたが、メソッドの 1 つには 8 つの異なるオーバーロードがあり、そのうちの 2 つには最後の引数のデータ型だけが異なっていたため、少し混乱しました。1 つは文字列で、もう 1 つは文字でした。パラメータの文字列バージョンに必要な値が 1 文字の長さである可能性は非常に高いので、これがどこに向かっているのかがわかると思います。ライブラリのコンシューマーが、single と double の違いを引用するために誤って間違った呼び出しをトリガーしたため、問題をデバッグするのに非常に時間がかかりました。

話の教訓として、候補者が答えを知らないことに感謝してください。

于 2008-09-30T18:43:38.763 に答える
10

それを使用することに反対票を投じますが、別の理由があります。

このように突っ込まれると、本当に優秀なプログラマーの多くが間違った答えを思いつきますが、それは彼らが概念を知らなかったり、理解できなかったりしたからではありません。何が起こるかというと、彼らはこのようなものを見て「あはは、ひっかけ問題だ!」と考えてから、応答で自分自身を考え抜くことに進みます. これは特に、IDE や Google など、プログラマーが日々のプログラミングで当然のことと考えているその他の利点がない面接の設定で当てはまります。

于 2008-09-30T18:18:29.197 に答える
7

ちょっとしたひっかけ質問なので、面接の質問としてはあまり公平ではありません。私がインタビュー対象者に望む良い答えは、「リファクタリングが必要です」のようなものです。

誰かを雇ってコンパイラの作業をするつもりでない限り、CLR についてそこまで深く掘り下げる必要があるかどうかはわかりません。

インタビューの質問については、コーダーの理解度を回答で示すものを探します。これは奇妙な/パズルです。

于 2008-10-02T12:24:36.100 に答える
7

Console.WriteLine( "B::Foo");

自動的にキャストし、継承をさらに進めずに最初のものを使用するためです。

面接での良い質問だとは思いませんが、コードをコンパイルせずに解決しようとするのは面白いかもしれません。

于 2008-09-30T17:36:57.597 に答える
6

これは実際にはトリックの質問です。

何が「起こるべきか」についての答えはあいまいです。確かに、C#コンパイラは、具体的な曖昧さの領域からそれを取り除きます。ただし、これらのメソッドは相互にオーバーロードしており、オーバーライドもシャドウイングも行わないため、ここでは「最適な引数」が適用されると想定するのが妥当です。したがって、A :: Foo(int n)が必要であると結論付けます。引数として整数が提供されたときに呼び出されます。

「すべき」ことが不明確であることを証明するために、VB.NETで実行した場合のまったく同じコードは逆の結果になります。

Public Class Form1
    Private Sub Button1_Click(ByVal sender As System.Object, _
                              ByVal e As System.EventArgs) _
                              Handles Button1.Click
        Dim b As New B
        b.Foo(5)   ' A::Foo
        b.Foo(5.0) ' B::Foo
    End Sub
End Class

Class A
    Sub Foo(ByVal n As Integer)
        MessageBox.Show("A::Foo")
    End Sub
End Class

Class B
    Inherits A

    Overloads Sub Foo(ByVal n As Double)
        MessageBox.Show("B::Foo")
    End Sub
End Class

私は、C#プログラマーがC#に準拠していないためにVB.NETを「bash」する機会を開いていることを認識しています。しかし、ここで適切な解釈を行っているのはVB.NETであるという非常に強い議論をすることができると思います。

さらに、C#IDE内のIntelliSenseは、クラスBに2つのオーバーロードがあることを示唆しています(存在するか、少なくとも存在する必要があるためです!)が、B.Foo(int n)バージョンを実際に呼び出すことはできません(最初に呼び出さないわけではありません)。クラスAに明示的にキャストします)。その結果、C#IDEは実際にはC#コンパイラと同期していません。

これを見る別の方法は、C#コンパイラが意図されたオーバーロードを取得し、それをシャドウメソッドに変換していることです。(これは私には正しい選択ではないようですが、これは明らかに単なる意見です。)

面接の質問として、ここで問題について話し合うことに興味があれば大丈夫だと思います。「正しい」または「間違っている」ということに関しては、間違った理由で簡単に見落とされたり、正しくなったりする可能性のあるトリックの質問に差し掛かっていると思います。実際、「あるべき」という質問に対する答えは、実際には非常に議論の余地があります。

于 2008-10-01T00:55:13.690 に答える
3

ひどい質問だと思います。本当の答えが「実行して見てください」である場合、どんな質問もひどい質問だと思います。

これを実際に知る必要がある場合は、まさにそれを実行します。テストプロジェクトを作成し、キー入力して調べます。そうすれば、抽象的な推論やC#仕様の細かい点について心配する必要はありません。

ちょうど今日、私はそのような質問に遭遇しました:同じ型のDataTableに同じ行を2回入力すると、どうなりますか?行のコピーを1つ、または2つ?そして、私がそれを変更したとしても、それは最初の行を上書きしますか?誰かに聞いてみようと思ったのですが、DataSetsを使ったテストプロジェクトを簡単に立ち上げて、小さなメソッドを書いてテストできることに気づきました。

答え:

...ああ、でも私があなたに言うなら、あなたは要点を見逃すでしょう。:)要点は、プログラミングでは、これらを仮説として残す必要はなく、合理的にテストできるかどうかを判断するべきではないということです。

ですから、それはひどい質問だと思います。衰退した記憶からそれを浚渫しようとする開発者や、他の誰かに尋ねて答えを受け入れる開発者よりも、それを試して何が起こるかを知っている開発者を雇うほうがいいと思いませんか?間違っているかもしれませんか?

于 2008-09-30T21:50:31.637 に答える
3

これはばかげた質問です。Snippet Compiler を使用して 60 秒未満で答えることができました。機能に依存するコード ベースで作業したことがあれば、すぐにリファクタリングされて存在しなくなります。

最良の答えは、「それはばかげた設計です。そうしないでください。言語仕様を解析して、それが何をするかを知る必要はありません」です。

もし私がインタビュー対象者だったら、あなたのオタクのトリビアの評判を非常に高く評価し、次のゲームの Geek Trivial Pursuit にあなたを招待するでしょう。しかし、私はあなたと一緒に/あなたのために働きたいかどうか確信が持てません. それがあなたの目標なら、ぜひ聞いてください。

  • 非公式の状況では、このようなオタクのトリビアは楽しくて面白いものになる可能性があることに注意してください. しかし、インタビュー対象者にとって、インタビューは楽しいものでも非公式なものでもありません。あなたが真剣に受け止めているかどうかを、インタビュー対象者が知らない些細な質​​問で、さらに煽る必要があるでしょうか。
于 2008-10-01T03:41:22.933 に答える
2

これは私にとってトリックの質問のスマックです。この言語を十分長い間使用している場合は、おそらく問題に遭遇し、答えを知っているでしょう。しかし、どれくらいの長さで十分ですか?

それはまた、あなたの経歴があなたに不利に働くかもしれない場所の問題でもあります。C ++ではBの定義がAの定義を非表示にすることは知っていますが、C#でも同じように機能するかどうかはわかりません。実生活では、それが疑わしい領域であったことを知っていて、それを調べてみてください。インタビューでは、その場に置かれたので、推測しようとするかもしれません。そして、私はおそらくそれを間違えるでしょう。

于 2008-09-30T19:00:23.950 に答える
2

候補者が自分の考えていることを説明するときに自分の思考プロセスを教えてくれると期待する場合にのみ、質問として使用してください。問題の実際のコードの正誤を気にする人-現実の世界では、候補者はこのようなコードを見つけ、それが機能していないことを見つけ、デバッガーと書き込みラインの呼び出しの組み合わせでデバッグするので、必要に応じて役に立たない質問です正しい答えを知っている(または推測している)候補者。

しかし、彼らが何が起こると思うかを説明できる人は、それは別の問題です。彼らがそれを間違えたとしても彼らを雇う。

于 2008-09-30T19:07:02.887 に答える
2

実際の作業状況では、問題の原因を突き止めるのに 5 秒もかかりません。コンパイル、テスト、おっと。

誰かが優れた保守可能なコードを構築できるかどうか、私ははるかに心配しています。のような質問をする

  • これをどのように設計し、単純な抽象的な設計を記述し、コードはありませんか。
  • こちらがオブジェのデザインです。お客様が来て、これが欲しいと言いました。新しい設計を策定するか、要件が実際の顧客のニーズを満たさない理由について話し合います。
于 2012-01-25T17:06:26.967 に答える
0

以下に示す同様のサンプルを試してください。

class Program
{
    class P
    {}
    class Q : P
    {}

    class A 
    { 
        public void Fee(Q q)
        {
            Console.WriteLine("A::Fee");
        }
    }

    class B : A 
    {   
        public void Fee(P p)
        {
            Console.WriteLine("B::Fee");
        }
    }

    static void Main(string[] args) 
    { 
        B b = new B();   
        /* which Fee is chosen? */  

        b.Fee(new Q());
        Console.ReadKey();
    }
}

コンパイラは、継承されたメソッド (基本型のメソッド) ではなく、そのようなメソッドに一致するようにパラメーターを暗黙的にキャストできる場合、「b.Fee()」呼び出しをその型の使用可能なメソッドにリンクすることを好むようです。つまり、パラメーターの暗黙的なキャストは、基本クラス メソッドのリンクよりも優先されます。

正直なところ、私にとっては、継承されたメソッドは直接導入されたメソッドと同じくらい優れているため、反対の方がより直感的です。

于 2008-10-19T06:44:48.767 に答える
0

多くの人がすでに述べているように、私が誰かにインタビューするとき、その候補者が意思疎通ができるかどうか、意味のあるコードを書く能力があるかどうか、他の人が簡単に理解できるコードを書く能力があるかどうか、コードを保守できるかどうかなどを調べたいと思います。私は個人的に、提案されたような演習に時間を費やすのは好きではありません. 代わりに、候補者が自分でコードを書く演習を行います (通常のテキスト エディターでも)。そこから、コード レビューや改善などに基づくディスカッションを開始します。コードをコンパイルする必要はありません。最終的にはコンパイラがその仕事をします。多くの人がこのアプローチに同意しないことは承知していますが、これまでのところ、これが良い候補者を見つける最良の方法であることがわかりました.

于 2012-11-03T11:34:04.570 に答える
0

問題のコードが出力されますB::Foo

于 2009-10-23T08:24:33.373 に答える