Javaフロー制御インタビューの質問(+回答)
1. 序章
制御フローステートメントを使用すると、開発者は意思決定、ループ、および分岐を使用して、特定のコードブロックの実行フローを条件付きで変更できます。
この記事では、面接中にポップアップする可能性のあるフロー制御面接の質問と、必要に応じて、いくつかの質問について説明します。 回答をよりよく理解するために例を実装します。
2. 質問
Q1。 if-thenおよびif-then-elseステートメントについて説明します。 条件として使用できる式の種類は何ですか?
両方のステートメントは、特定の条件がtrueと評価された場合にのみそれらの内部のコードを実行するようにプログラムに指示します。 ただし、 if-then-else ステートメントは、if句が false と評価された場合に備えて、実行の2次パスを提供します。
if (age >= 21) {
// ...
} else {
// ...
}
他のプログラミング言語とは異なり、Javaは条件としてboolean式のみをサポートします。 別のタイプの式を使用しようとすると、コンパイルエラーが発生します。
Q2。 switchステートメントについて説明してください。 switch 句で使用できるオブジェクトタイプは何ですか?
スイッチを使用すると、変数の値に基づいて複数の実行パスを選択できます。
各パスにはcaseまたはdefaultのラベルが付いており、 switchステートメントは各case式の一致を評価し、次のすべてのステートメントを実行します。 breakステートメントが見つかるまでラベルを一致させます。 一致するものが見つからない場合は、代わりにdefaultブロックが実行されます。
switch (yearsOfJavaExperience) {
case 0:
System.out.println("Student");
break;
case 1:
System.out.println("Junior");
break;
case 2:
System.out.println("Middle");
break;
default:
System.out.println("Senior");
}
byte 、 short 、 char 、 int 、それらのラップされたバージョン、 enum 、およびを使用できます] String s as switch値。
Q3。 break ステートメントを[X63X]スイッチのケース句に入れるのを忘れるとどうなりますか?
switchステートメントは失敗します。 これは、 break ステートメントが見つかるまで、すべての case ラベルの実行を継続することを意味します。これらのラベルは、式の値と一致しません。
これを示す例を次に示します。
int operation = 2;
int number = 10;
switch (operation) {
case 1:
number = number + 10;
break;
case 2:
number = number - 4;
case 3:
number = number / 3;
case 4:
number = number * 10;
break;
}
コードを実行した後、numberは6ではなく20の値を保持します。 これは、同じアクションを複数のケースに関連付けたい場合に役立ちます。
Q4。 I f-Then-ElseステートメントよりもSwitch を使用する方が望ましいのはいつですか?
switch ステートメントは、単一の変数を多数の単一の値に対してテストする場合、または複数の値が同じコードを実行する場合に適しています。
switch (month) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
days = 31;
break;
case 2:
days = 28;
break;
default:
days = 30;
}
if-then-else ステートメントは、値の範囲または複数の条件をチェックする必要がある場合に適しています。
if (aPassword == null || aPassword.isEmpty()) {
// empty password
} else if (aPassword.length() < 8 || aPassword.equals("12345678")) {
// weak password
} else {
// good password
}
Q5。 Javaはどのタイプのループをサポートしていますか?
Javaは、 for 、 while 、およびdo-whileの3種類のループを提供します。
for ループは、値の範囲を反復処理する方法を提供します。 タスクが何回繰り返されるかを事前に知っていると、最も役立ちます。
for (int i = 0; i < 10; i++) {
// ...
}
while ループは、特定の条件が true であるときに、ステートメントのブロックを実行できます。
while (iterator.hasNext()) {
// ...
}
do-while は、 while ステートメントのバリエーションであり、boolean式の評価がループの最下部にあります。 これにより、コードが少なくとも1回実行されることが保証されます。
do {
// ...
} while (choice != -1);
Q6。 拡張forループとは何ですか?
for ステートメントの別の構文は、コレクション、配列、列挙型、またはIterableインターフェイスを実装するオブジェクトのすべての要素を反復処理するように設計されています。
for (String aString : arrayOfStrings) {
// ...
}
Q7。 ループから予期して終了するにはどうすればよいですか?
break ステートメントを使用すると、ループの実行をすぐに終了できます。
for (int i = 0; ; i++) {
if (i > 10) {
break;
}
}
Q8。 ラベルなしとラベル付きのbreakステートメントの違いは何ですか?
ラベルのないbreakステートメントは、最も内側の switch 、 for 、 while 、または do-while ステートメントを終了しますが、 break というラベルが付いていると、外部ステートメントの実行が終了します。
これを示す例を作成しましょう。
int[][] table = { { 1, 2, 3 }, { 25, 37, 49 }, { 55, 68, 93 } };
boolean found = false;
int loopCycles = 0;
outer: for (int[] rows : table) {
for (int row : rows) {
loopCycles++;
if (row == 37) {
found = true;
break outer;
}
}
}
番号37が見つかると、ラベル付きの break ステートメントは、最も外側の for ループを終了し、それ以上のサイクルは実行されません。 したがって、loopCyclesは値5で終了します。
ただし、ラベルのない break は最も内側のステートメントを終了するだけで、制御フローを最も外側の for に戻し、の次の行にループを続けます。 ] table 変数、loopCyclesを値8で終了させます。
Q9。 ラベルなしとラベル付きのcontinueステートメントの違いは何ですか?
ラベルのないcontinueステートメントは、最も内側の for 、 while 、または do-while ループで、現在の反復の最後にスキップします。ラベル付きのcontinueは、指定されたラベルでマークされた外側のループにスキップします。
これを示す例を次に示します。
int[][] table = { { 1, 15, 3 }, { 25, 15, 49 }, { 15, 68, 93 } };
int loopCycles = 0;
outer: for (int[] rows : table) {
for (int row : rows) {
loopCycles++;
if (row == 15) {
continue outer;
}
}
}
理由は前の質問と同じです。 ラベル付きのcontinueステートメントは、最も外側のforループを終了します。
したがって、 loopCycles は値5の保持を終了しますが、ラベルのないバージョンは最も内側のステートメントのみを終了し、loopCyclesを値9で終了します。
Q10。 try-catch-finallyコンストラクト内の実行フローを説明します。
プログラムがtryブロックに入り、その中に例外がスローされると、 try ブロックの実行が中断され、制御フローはcatchで続行されます。 スローされた例外を処理できるブロック。
そのようなブロックが存在しない場合、現在のメソッドの実行は停止し、呼び出しスタック上の前のメソッドに例外がスローされます。 または、例外が発生しない場合は、すべての catch ブロックが無視され、プログラムの実行は正常に続行されます。
finally ブロックは、 try ブロックの本体内で例外がスローされたかどうかに関係なく、常に実行されます。
Q11。 最終的にブロックが実行されない可能性があるのはどのような状況ですか?
tryまたはcatchブロックの実行中にJVMが終了した場合、たとえば、 System.exit()、を呼び出した場合、または実行中のスレッドが中断された場合、またはkilledの場合、finallyブロックは実行されません。
Q12。 次のコードを実行した結果はどうなりますか?
public static int assignment() {
int number = 1;
try {
number = 3;
if (true) {
throw new Exception("Test Exception");
}
number = 2;
} catch (Exception ex) {
return number;
} finally {
number = 4;
}
return number;
}
System.out.println(assignment());
コードは数値3を出力します。 finally ブロックは常に実行されますが、これはtryブロックが終了した後にのみ発生します。
この例では、 return ステートメントは、try-catchブロックが終了する前に実行されます。 したがって、finallyブロックのnumberへの割り当ては、変数がsignmentメソッドの呼び出し元コードにすでに返されているため効果がありません。
Q13。 例外がスローされない場合でも、 try-finally ブロックが使用される可能性があるのはどのような状況ですか?
このブロックは、 break 、 continue 、または return が発生して、コードで使用されているリソースのクリーンアップを誤ってバイパスしないようにする場合に役立ちます。声明:
HeavyProcess heavyProcess = new HeavyProcess();
try {
// ...
return heavyProcess.heavyTask();
} finally {
heavyProcess.doCleanUp();
}
また、スローされた例外をローカルで処理できない状況に直面する可能性があります。または、リソースを解放しながら、現在のメソッドで例外をスローしたい場合があります。
public void doDangerousTask(Task task) throws ComplicatedException {
try {
// ...
task.gatherResources();
if (task.isComplicated()) {
throw new ComplicatedException("Too difficult");
}
// ...
} finally {
task.freeResources();
}
}
Q14。 try-with-resources はどのように機能しますか?
try-with-resources ステートメントは、 try ブロックを実行する前に、1つ以上のリソースを宣言して初期化し、ブロックが正常に完了したか突然完了したかに関係なく、ステートメントの最後で自動的に閉じます。 。 AutoCloseableまたはCloseableインターフェースを実装する任意のオブジェクトをリソースとして使用できます。
try (StringWriter writer = new StringWriter()) {
writer.write("Hello world!");
}
3. 結論
この記事では、制御フローステートメントに関して、Java開発者向けの技術インタビューに登場する最もよくある質問のいくつかを取り上げました。 これは、完全なリストとしてではなく、さらなる調査の開始としてのみ扱われるべきです。
面接で頑張ってください。