Javaプログラマであるかを見分ける10の質問-回答編

想定を超えた反応がありましたので、予定はしていなかった回答編をお送りします。ですが、正確な解答を書いても面白くないので、これをネタに面談をした場合に、自分ならどんなポイントを持って選考するかをまとめてみました。

はじめに

このエントリーの質問の意図は「優れたJavaプログラマ」を見つける事ではありません。「最低限のスキルを持った戦力が欲しい」という状況です。したがって、優れた指摘をしてくるのであれば超したことありません。設問について議論が発生するならば、この設問を投げる必要がなかったということです。
Javaを詳しく知っている人からすれば間違いでは?曖昧な質問では?と感じる設問があるのは確かです。しかし、優秀な人をテストしたい訳ではないのです。したがって、正確性とか厳密性については求めません。「だいたいあっている」ならば前提条件である「中堅プログラマの補充」の条件を満たすからです。

中堅プログラマの定義

「こんなの出来て当たり前だ」とか「半年でできるだろ」といったコメントもありましたが、それは事実かも知れません。しかし、全ての開発現場で事実というわけではありません。プロジェクトに優秀なプログラマが多くいれば良いソフトウェアが作れるかもしれませんが、コストの問題や現実的な問題としてある程度のスキルレベルで押さえる必要も出てきます。優秀な人を探してるうちに納期が過ぎてしまったら本末転倒ですし、優秀な人は捕まえにくいのが現実でしょう。しかし、まったく技術レベルがないPGは逆にプロジェクトを進めるのに障害となります。この設問で見極めたいのは最低限の知識をもっているかであり、それを「中堅プログラマ」と定義しています。

傾向と対策

ブクマ・トラバ・Twitterの反応・妄想などを考慮すると回答パターンはだいたい次のように分類できるのではないでしょうか?

さっぱり解らない…

プログラマでないか、まだまだ経験不足であるかのどちらかです。
このエントリーを読んでいるならば後者だと思います。恥じることなく、経験と学習を積めば良いと思います。

なんとなくは解るけどはっきり答えられない ==

半分程度はあっている、言いたいことはなんとなく解るが用語が正しくないなどといった所です。おそらくは経験が少し足りないか、他の言語での経験が多いのでしょう。正確に表現できるようになるように目標を立てると良いかもしれません。
プログラマは自分で理解しているだけで他人に説明できない事があります。正確に用語を覚え、背景や理由も含めて説明できるようになることは大切です。

概ね答えられている

80%と書いたラインです。問題の意図を間違えた/用語が少し曖昧などはあるものの、基本的な概念は理解しているという所でしょうか。おそらくは日々の学習をおろそかにしていないプログラマだと思います。

この、質問おかしいんじゃね?

見極めが必要ですが、代わりにプロジェクトを進めてもらって良いと思います。投げっぱなし批判をコメントするくらいなら正確な記事をブログに書いて欲しい人達です。

開発現場の現実と理想

コメントにも幾つかありましたが、面接などでやってくる「自称Java経験者」には驚かされます。「すべて答えられるのは当然」という反応もありましたが、開発現場をなめてもらっては困ります。もし、これらの質問を社内で行う勇気があるならば、その会社は素晴らしいと思います。しかし、現場では怖くて実施できないというのが現実でしょう。
また、自分はこの「概ね答えられている」層が一番少なく、「難なく答えられる」層と「まったく答えられない」層に二極化している傾向があると感じます。要はプログラマとして学習しているならば、「概ね答えられる」のは一時的な通過点ですから、数年で「難なく答えられる」事になるからです。一方、「まったく答えられれない」人は10年後も変わらないか、システム開発などしていないでしょう。
尚、システム開発はチームで行うものです。誰もがギークであるチームが作れるのであればベストと考えがちですが、チームや組織の血を巡らせる為にも新人をいれて経験を積ませたり、中堅を育ててエキスパートへのパスを作ったりする必要があります。「できるのが当然」と考える人は、上から目線ではなく一度「出来なかった頃」を思い出してみるとより良いチームができると思います。

設問のポイント

模範解答ではなくポイントを書くことにしました。詳しい解説が必要ならば、Effective Javaを読めばいいと思います。簡単にキーワードを拾っていきます。尚、解答ではなく回答としたのは、テストをしているわけではないからです。間違っている事はあまり問題ではなく、答えられないことが問題です。勘違いや細かいミスであればプロジェクトの中で修正していけばいいのです。

1. ==演算子とequalsメソッドの違いは何か?

インスタンスの同一性」が述べられていれば文句ないでしょう。「インスタンスの比較」と「インスタンスの中のフィールドの比較」と言った内容が書かれていれば充分です。

2. 文字列の+演算子による連結とStringBuilderを使った連結の違いを説明せよ。

元はこうでした。

文字列の連結は原則として+演算子を使ってはならない理由を説明せよ。

ブクマやコメントでも指摘のあった部分ですが、設問に語弊を生む部分があったので、設問を変更します。設問の意図としては、オブジェクトの生成に関して触れて欲しい設問でした。コンパイラによる最適化云々の話が書かれていたらベターですが、それはやや応用的なものであると自分は思っています。SJC-P(OJC-P)やEffective Javaを基準とした知識レベルを想定しています。

簡単な文字列結合に StringBuilder/Buffer 使ってるコードを大量に見て、うんざりしたことがある。

こんなブクコメもありましたが、それはコードレビューやプロジェクトの進め方の問題ではないでしょうか?

3. Listのようにジェネリクス型を使う主たる目的は何か?

これはJavaの1.4以前に触れたことのないJavaプログラマにとっては難しい質問です。2011年でJava経験3年だとすれば、Java6しか触ったことないプログラマは充分に考えられます。この設問では「キャストの安全性」について触れられていれば充分です。

4. オブジェクトがガベージコレクションGC)される主たる条件は何か?

同じく主たる条件ですので、「オブジェクトの参照がどこからもなくなる」という事が書かれていれば良いでしょう。実際にGCされるタイミングについてはVMに依存するわけですが、その点について触れていればベターです。

5. チェック例外と非チェック例外の違いを型と例外処理の観点で説明せよ。

例外処理の観点で、チェック例外と非チェック例外の特徴を説明します。したがって、「チェック例外はtry-catch句で処理されるかthrows句で呼び出し元に伝搬する必要がある」という点について書かれていれば充分です。

6. フィールドのアクセス修飾子をprivateにしgetter/setterメソッドを提供する事でフィールドを参照する設計方針を取る主な理由を説明せよ

オブジェクト指向プログラミングを学んでいれば、「カプセル化」というキーワードが頭に浮かぶはずです。もしくはJavaBeansという規格(規約)について触れられれているというのもありです。直接フィールドを参照しないことによるメリットなどが何か書いてあってもいいと思います。

7. NullPointerExceptionが発生するのは主にどういう状況か?

ほとんどの人は状況は理解できるものの、正確な用語を使用して説明するのは意外と難しい設問です。回答例としては、「nullを参照している変数のフィールドやメソッドを呼び出そうとした場合」になります。「nullに対してメソッドを呼ぶ」とか「null変数に対してー」とか「変数がnullの場合にー」などはニュアンスは伝わりますのでOKです。

8. オーバーロードとオーバーライドの違いは何か?

継承に触れられている事と、同じ名前のメソッドという事が書かれていれば十分かと思います。

9. コンストラクタとは何か?

インスタンスの初期化時に行われる処理という点が書かれていれば充分です。尚、Javaではコンストラクタはメソッドではないため「インスタンスの初期化時に実行されるメソッド」は厳密には間違いです。自分はよく「インスタンスの初期化時に実行されるメソッドのようなもの」と説明します。

10. インターフェイスを利用する目的を1つ説明せよ

色々と目的はあると思いますが、自分ならば「仕様と実装を分離するため」と答えます。ポリモーフィズムに関連する事に触れているのも良い回答かと思います。

補足

ブクマコメなどに幾つか補足しておきます。
「なぜこの10問?」というコメントがありましたが、基準はEffective Javaを読んでおり、なんとなく理解している事としました。同じくらいの理解度としてSJC-P(OJC-P)を理解して取得していると考えても良いと思います。
「これで中堅?」という意見もありましたが、分類を「新人」「中堅」「ベテラン」とすれば、新人を卒業してベテランになるまでは「中堅」です。勿論、ぎりぎり答えられるかというラインだと中堅の下の方だし、楽に答えられれば中堅の上の方でしょう。
「文字列の連結は微妙」との指摘は多くありましたが、Effective Java準拠としています。コンパイラの最適化を指摘するならば超したことはありません。ただ、設問に語弊があるので訂正します。

結論

Javaプログラマ名乗るならEffective Javaを読みましょうという事です。必須ではないけど、効率よく学習したいならばEffective Javaを読むべきです。また、ある程度の回答が出てくるのであれば、一緒に仕事をして経験を積んで欲しい人かもしれないので自分であれば歓迎します。正しい解答は必要な事ではありません。

Effective Java 第2版 (The Java Series)

Effective Java 第2版 (The Java Series)