Javaインタビューの質問
1.はじめに
この記事では、コアJavaに関する就職の面接に関する最も重要な質問に対する回答を示します。それらのいくつかに対する答えは明白ではないかもしれないので、この記事は物事を片付けるのに役立ちます。
2.初心者向けのコアJava言語に関する質問
==== Q1。データはJavaで参照渡しか値渡しか
この質問に対する答えは非常に単純ですが、この質問は初心者には分かりにくいかもしれません。まず、質問の内容を明確にしましょう。
-
値渡し –
オブジェクトのコピーを** として渡すことを意味します
メソッドへのパラメータ。
-
参照渡し –
これは、参照を** に渡すことを意味します.
メソッドへのパラメータとしてのobject **
質問に答えるために、2つのケースを分析しなければなりません。これらは、メソッドに渡すことができる2つのタイプのデータを表します。プリミティブとオブジェクトです。
プリミティブをメソッドに渡すと、その値は新しい変数にコピーされます。オブジェクトに関しては、参照の値は新しい変数にコピーされます。つまり、Javaは厳密には値渡しです。
私達は私達の記事の1つでそれについてより多くを学ぶことができます。]。
==== Q2。インポートと静的インポートの違いは何ですか?
通常のインポートを使用して、特定のクラスまたは別のパッケージで定義されているすべてのクラスをインポートできます。
import java.util.ArrayList;//specific class
import java.util.** ;//all classes in util package
囲んでいるクラスの入れ子になったパブリッククラスをインポートするためにそれらを使用することもできます。
import com.baeldung.A.**
ただし、上記のインポートではクラス
A
自体はインポートされません。
静的メンバーや入れ子クラスをインポートするための静的インポートもあります。
import static java.util.Collections.EMPTY__LIST;
その結果、完全修飾クラス名を前に付けることなく、つまり現在のクラスで宣言されているかのように、静的変数EMPTY__LISTを使用できます。
==== Q3。 Javaで利用可能なアクセス修飾子とその目的は何ですか?
Java
には4つのアクセス修飾子があります。
-
プライバシー
-
default
(パッケージ) -
保護された
-
パブリック
-
private
修飾子は、クラスメンバーがクラスの外からアクセスできないことを保証します** メソッド、プロパティ、コンストラクタ、ネストクラスには適用できますが、トップレベルクラス自体には適用できません。
-
private
修飾子とは異なり、
default
修飾子はすべてのタイプのクラスメンバーとクラス自体に適用できます。アクセス修飾子をまったく追加しないことで
default
の可視性を適用できます。
default
可視性を使用する場合、私たちのクラスまたはそのメンバーは私たちのクラスのパッケージの中だけでアクセス可能になります。
デフォルトのアクセス修飾子は
default
キーワードと共通点がないことに注意してください。
default
修飾子と同様に、1つのパッケージ内のすべてのクラスは
protected
メンバーにアクセスできます。さらに、
protected
修飾子を使用すると、サブクラスがスーパークラスの保護されたメンバーにアクセスできます(同じパッケージ内にない場合でも)。
public
修飾子は、クラスキーワードおよびすべてのクラスメンバーと一緒に使用できます。 ** すべてのパッケージ内およびすべてのクラスからクラスとクラスメンバーにアクセスできるようにします。
詳しくはhttps://www.baeldung.com/java-access-modifiers[Java Access Modifiers]の記事をご覧ください。
==== Q4。 Javaで利用可能な他の修飾子とその目的は何ですか?
Javaには他に5つの修飾子があります。
-
静的
-
最後の
-
要約
-
同期
-
揮発性
これらは可視性を制御しません。
まず最初に、
static
キーワードをフィールドとメソッドに適用できます。
静的フィールドまたはメソッドはクラスメンバーですが、非静的フィールドまたはメソッドはオブジェクトメンバーです。クラスメンバーは、インスタンスを呼び出す必要はありません。
それらはオブジェクト参照名の代わりにクラス名で呼ばれます。
この記事
では、
static
キーワードについて詳しく説明しています。
それから、
final
キーワードがあります。フィールド、メソッド、そしてクラスでそれを使うことができます。
final
がフィールドで使用されている場合、それはそのフィールド参照が変更できないことを意味します。
final
がクラスまたはメソッドに適用されるとき、それはそのクラスまたはメソッドが拡張されたりオーバーライドされたりすることができないことを保証します。この記事]。
次のキーワードは
abstract
です。これはクラスとメソッドを記述できます。
クラスが
抽象
の場合、それらはインスタンス化できません
代わりに、それらはサブクラス化されることを意味します。メソッドが
abstract
の場合、それらは実装されずに残り、サブクラスでオーバーライドすることができます。
synchronized
キーワードが最も高度な場合があります。インスタンスや静的メソッドやコードブロックで使用できます。 ** このキーワードを使用すると、特定のコードフラグメントの同期を提供するためにJavaがモニタロックを使用するようになります。
これから説明する最後のキーワードは
volatile
です。インスタンスフィールドと一緒にしか使用できません。 ** フィールド値は、CPUキャッシュを迂回してメインメモリから読み書きする必要があることを宣言しています。 volatileキーワードについては、https://www.baeldung.com/java-volatile[この記事]で詳しく説明されています。
==== Q5。 JDK、JRE、およびJVMの違いは何ですか?
JDK
は
Java Development Kit
の略で、開発者がJavaでアプリケーションを書くのに必要なツールのセットです。 JDK環境には3つのタイプがあります。
-
Standard Edition – ポータブルデスクトップを作成するための開発キットまたは
サーバーアプリケーション
** Enterprise Edition – Standard Editionの拡張機能です。
分散コンピューティングまたはWebサービスのサポート
** Micro Edition – 組み込みおよびモバイル用の開発プラットフォーム
アプリケーション
JDKには、プログラマーがアプリケーションの作成、デバッグ、または保守を行うのに役立つツールがたくさんあります。最も一般的なものは、コンパイラ(
javac
)、インタプリタ(
java
)、アーカイバ(
jar
)、およびドキュメントジェネレータ(
javadoc
)です。
JRE
は、
Javaランタイム環境
です。これはJDKの一部ですが、
Javaアプリケーションを実行するための最小限の機能が含まれています
。これは、
Java仮想マシン
、コアクラス、およびサポートファイルで構成されています。たとえば、コンパイラはありません。
JVM
は、
Java Virtual Machine
の頭字語です。これは、バイトコードにコンパイルされたプログラムを実行できる仮想マシンです。異なる実装間の相互運用性を確保することが重要であるため、これはJVM仕様によって記述されています。 ** JVMの最も重要な機能は、ユーザーが同じJavaアプリケーションを異なるオペレーティングシステムや環境にデプロイできるようにすることです。
詳細については、https://www.baeldung.com/jvm-vs-jre-vs-jdk[JVM、JRE、およびJDKの違い]の記事を確認しましょう。
==== Q6。スタックとヒープの違いは何ですか?
すべての変数とオブジェクトがJVMによって格納されるメモリの2つの部分があります。 1つ目は
stack
、2つ目は
heap
です。
-
stack
は、JVMがローカル変数と追加データ** 用のブロックを予約する場所です。スタックは
LIFO
(後入れ先出し)構造です。つまり、メソッドが呼び出されるたびに、ローカル変数とオブジェクト参照用に新しいブロックが予約されます。新しいメソッド呼び出しのたびに、次のブロックが予約されます。メソッドが実行を終了すると、ブロックは開始時とは逆の方法で解放されます。
新しいスレッドはそれぞれ独自のスタックを持ちます。
私たちはスタックがヒープよりはるかに少ないメモリ空間を持っていることを知っておくべきです。そして、スタックがいっぱいになると、JVMは
StackOverflowError
をスローします。悪い再帰呼び出しがあり、再帰が深くなりすぎると発生する可能性があります。
-
すべての新しいオブジェクトは、動的割り当てに使用されるJavaの
heap
上に作成されます。未使用のオブジェクトを若いスペース(保育園)と古いスペースに分けて消去する役割を果たす
ガベージコレクタ
があります。ヒープへのメモリアクセスは、スタックへのアクセスより遅くなります。ヒープが一杯になると、JVMは
OutOfMemoryError
をスローします。
詳しくはhttps://www.baeldung.com/java-stack-heap[Javaのスタックメモリとヒープスペース]の記事を参照してください。
==== Q7。
__Comparable
と
Comparator__インタフェースの違いは何ですか?
新しいクラスを書くときに、そのクラスのオブジェクトを比較できるようにしたいことがあります。ソートされたコレクションを使いたいときに特に役立ちます。これを行うには2つの方法があります。それは
Comparable
インターフェースを使う方法と
Comparator
インターフェースを使う方法です。
まず、
Comparable
インターフェースを見てみましょう。
public interface Comparable<T> {
int compareTo(T var1);
}
オブジェクトをソートしたいクラスによってそのインターフェースを実装するべきです。
それは
compareTo()
メソッドを持ち、整数を返します。 -1、0、および1の3つの値を返すことができます。これは、このオブジェクトが比較対象オブジェクトよりも小さい、等しい、または大きいことを意味します。
オーバーライドされた
compareT0()
メソッドは
equals()
メソッドと整合性があるはずです。
一方、
Comparator
インターフェースを使うことができます。それは
Collection
インターフェースの
sort()
メソッドに、またはソートされたコレクションをインスタンス化するときに渡すことができます。これが、1回限りの並べ替え戦略を作成するために主に使用されてきた理由です。
さらに、Comparableインターフェイスを実装していないサードパーティのクラスを使用する場合にも便利です。
compareTo()
メソッドと同様に、オーバーライドされた
compare()
メソッドは
equals()
メソッドと整合性があるはずですが、オプションでnullとの比較を許可することもできます。
詳細については、https://www.baeldung.com/java-comparator-comparable[Comparator and Comparable in Java]の記事を参照してください。
==== Q8。
void
タイプとは何ですか?
Javaでメソッドを書くたびに、戻り型を持たなければなりません。メソッドに値を返させたくない場合は、
void
キーワードを使用できます。
Void
クラスがあることも知っておくべきです。これは、たとえばジェネリック医薬品を扱うときに使用できるプレースホルダクラスです。
Void
クラスはインスタンス化も拡張もできません。
==== Q9。オブジェクトクラスのメソッドとは何ですか?
Object
クラスに含まれるメソッドとそれらがどのように機能するかを知ることは重要です。これらのメソッドをオーバーライドするときにも非常に役立ちます。
-
clone()
– このオブジェクトのコピーを返す -
equals()
– このオブジェクトがオブジェクトと等しい場合に
true
を返します
パラメータとして渡される
**
finalize()
– ガベージコレクタはこのメソッドを呼び出します。
メモリをクリーニングする
**
getClass()
– このオブジェクトの実行時クラスを返します
-
hashCode()
– このオブジェクトのハッシュコードを返します。 ** 気をつけるべきです
equals()
メソッドと一致している必要があります
notify()
– 通知を待っているシングルスレッドに通知を送信する
オブジェクトのモニタ
**
notifyAll()
– 待機中のすべてのスレッドに通知を送信します。
オブジェクトのモニタ
**
toString()
– このオブジェクトの文字列表現を返す
-
wait()
– このメソッドには3つのオーバーロードバージョンがあります。それ
別のスレッドがこのオブジェクトに対して
notify()
または
notifyAll()
を呼び出すまで、現在のスレッドに指定された時間待機させます。
==== Q10。列挙型とは何ですか?
Enum
は、開発者が一連の定義済み定数値を指定できるようにするクラスの一種です。そのようなクラスを作成するには、
enum
キーワードを使用する必要があります。曜日の数え上げを想像してみましょう。
public enum Day {
SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY
}
すべての定数を繰り返すために、静的な__values()メソッドを使用できます。
さらに、列挙型を使用すると、プロパティなどのメンバーや通常のクラスなどのメソッドを定義できます。
-
これは特別なタイプのクラスですが、サブクラス化することはできません** ただし、列挙型はインターフェイスを実装できます。
Enums
のもう1つの興味深い利点は、それらがスレッドセーフであり、シングルトンとして広く使用されていることです。
Enumの詳細については、https://www.baeldung.com/a-guide-to-java-enums[ガイドの1つ]を参照してください。
==== Q11。
a
JARとは何ですか?
__JAR
は、
Java archive__へのショートカットです。 ZIPファイル形式でパッケージ化されたアーカイブファイルです。これを使って、アプリケーションに必要なクラスファイルと補助リソースを含めることができます。それは多くの機能があります。
-
セキュリティ –
JARファイルにデジタル署名できます -
圧縮 –
JARを使用している間、効率的にファイルを圧縮できます。
ストレージ
移植性 – ** 複数のプラットフォームで同じJARファイルを使用できます
-
バージョン管理 –
JARファイルはそれらのファイルに関するメタデータを保持できます
含む
Sealing – ** JARファイル内のパッケージをシールすることができます。この意味は
1つのパッケージからのすべてのクラスは同じJARファイルに含まれていなければなりません
拡張子 – ** モジュールをパッケージ化するのにJARファイルフォーマットを使うことができます。
既存のソフトウェアの拡張
==== Q12。 **
NullPointerException
とは何ですか?
NullPointerException
は、おそらくJavaの世界で最も一般的な例外です。これは未チェックの例外なので、
RuntimeException
を拡張しています。私たちはそれを処理しようとすべきではありません。
次の場合のように、変数にアクセスしようとしたり、null参照のメソッドを呼び出そうとしたりすると、この例外がスローされます。
-
null参照のメソッドを呼び出す
-
null参照のフィールドを設定または取得する
-
null配列参照の長さをチェックする
-
null配列参照の項目を設定または取得する
-
null
を投げる
==== Q13。 Javaにおける2つの型のキャストは何ですか?キャスト中にスローされる可能性のある例外どうすればそれを避けることができますか?
Javaでは、2種類のキャストを区別できます。オブジェクトをスーパータイプにキャストするアップキャスト、またはオブジェクトをサブタイプにキャストするダウンキャストを行うことができます。
Upcasting
はとても簡単です、私たちはいつもそうすることができます。たとえば、
String
インスタンスを
Object
タイプにアップキャストできます。
Object str = "string";
あるいは、変数をダウンキャストすることもできます。型チェックを伴うので、アップキャストほど安全ではありません。オブジェクトを誤ってキャストした場合、JVMは実行時に
ClassCastExcpetion
をスローします。 ** 幸い、無効なキャストを防ぐために
instanceof
キーワードを使用できます。
Object o = "string";
String str = (String) o;//it's ok
Object o2 = new Object();
String str2 = (String) o2;//ClassCastException will be thrown
if (o2 instanceof String) {//returns false
String str3 = (String) o2;
}
型キャストの詳細については、https://www.baeldung.com/java-type-casting[この記事]を参照してください。
3.上級プログラマ向けのコアJava言語に関する質問
==== Q1。文字列はなぜ不変クラスなのか
String
オブジェクトは
JVM
によって他のオブジェクトとは異なる方法で扱われることを知っておくべきです。 1つの違いは、
String
オブジェクトは不変であるということです。
一度作成すると変更できないことを意味します。
そのように動作するのにはいくつかの理由があります。
-
それらは
string pool
に格納されています.
ヒープメモリ多くのスペースを節約する責任があります。
-
String
クラスの不変性は、そのハッシュコードが
変わりません。
そのため、
Strings
はハッシュコレクションのキーとして効果的に使用できます。
ハッシュコードが変更されているため、データを上書きすることはできません。
-
それらはいくつかのスレッドで安全に使用できます. ** スレッドは変更できません
String
オブジェクトの値なので、スレッドセーフになります。
。深刻なセキュリティ問題を回避するために文字列は不変です。機密データ
パスワードなどの情報は、信頼性の低いソースまたは別のスレッドによって変更される可能性があります。
文字列の不変性についての詳細は、https://www.baeldung.com/java-string-immutable[この記事の中]を参照してください。
==== Q2。動的バインディングと静的バインディングの違いは何ですか?
Javaでのバインディングは、メソッド呼び出しを適切なメソッド本体に関連付けるプロセスです。 Javaでは、2種類のバインディングを区別できます。
静的および動的
静的バインディングと動的バインディングの主な違いは、静的バインディングはコンパイル時に発生し、動的バインディングは実行時に発生することです。
Static binding
はバインディングにクラス情報を使います。これは、
private
または
static
および
final
メソッドと変数であるクラスメンバーを解決する責任があります。また、静的バインディングはオーバーロードされたメソッドをバインドします。
一方、
動的バインディング
はオブジェクト情報を使用してバインディングを解決します。それが、仮想メソッドとオーバーライドメソッドの解決に責任がある理由です。
==== Q3。 JITとは
JIT
は「ジャストインタイム」を表します。ランタイムで実行され、アプリケーションのパフォーマンスを向上させるのはJREのコンポーネントです。
-
具体的には、プログラムの起動直後に実行されるコンパイラです。**
これは、アプリケーションが起動するずっと前にコードをコンパイルする通常のJavaコンパイラとは異なります。 JITはさまざまな方法でアプリケーションを高速化できます。
たとえば、JITコンパイラは、パフォーマンスを向上させるために、バイトコードをネイティブ命令にその場でコンパイルします。また、ターゲットのCPUとオペレーティングシステムに合わせてコードを最適化できます。
さらに、最適なパフォーマンスを得るために再コンパイルに使用される可能性のある多くのランタイム統計にアクセスできます。これにより、グローバルなコードの最適化やコードの再配置によってキャッシュを効率的に利用することもできます。
==== Q4。 Javaのリフレクションとは
反射はJavaの非常に強力なメカニズムです。リフレクションは、実行時にプログラマーがプログラムの内部状態(プロパティ、メソッド、クラスなど)を調べたり変更したりできるようにするJava言語のメカニズムです。 java.lang.reflectパッケージは、リフレクションを使用するために必要なすべてのコンポーネントを提供します。
この機能を使用すると、クラス定義内に含まれる可能性のあるすべてのフィールド、メソッド、コンストラクタにアクセスできます。アクセス修飾子に関係なく、それらにアクセスできます。それは、例えば私たちが個人会員にアクセスできることを意味します。そのために、私たちは彼らの名前を知る必要はありません。しなければならないのは、
Class
のいくつかの静的メソッドを使用することだけです。
リフレクションを介してアクセスを制限する可能性があることを知っておく価値があります。そのためには、JavaセキュリティマネージャとJavaセキュリティポリシーファイルを使用できます。それらは私達がクラスに許可を与えることを可能にします。
Java 9以降のモジュールで作業する場合、デフォルトでは、他のモジュールからインポートされたクラスにリフレクションを使用することはできません。他のクラスがリフレクションを使用してパッケージのプライベートメンバーにアクセスできるようにするには、「リフレクション」権限を付与する必要があります。
この記事
では、Java Reflectionについて詳しく説明します。
==== Q5。 ** クラスローダーとは
クラスローダー
は、Javaの最も重要なコンポーネントの1つです。これはJREの一部です。
簡単に言うと、クラスローダーはクラスをJVMにロードする責任があります。 3種類のクラスローダーを区別できます。
-
ブートストラップクラスローダー –
コアJavaクラスをロードします。彼らです
<JAVA
HOME>/jre/lib__ディレクトリにあります。
Extension classloader – ** にあるクラスをロードする
<JAVA
HOME>/jre/lib/ext
または
java.ext.dirs__で定義されたパス内
財産
システムクラスローダ – ** クラスパスにクラスをロードする
応用
クラスローダーはクラスを「要求に応じて」ロードします。つまり、クラスはプログラムによって呼び出された後にロードされます。さらに、クラスローダーは指定された名前のクラスを一度だけロードできます。ただし、同じクラスが2つの異なるクラスローダーによってロードされると、それらのクラスは等価性チェックに失敗します。
Javaでのクラスローダー
の記事にクラスローダーの詳細があります。
==== Q6。静的クラスと動的クラスのロードの違いは何ですか?
静的クラスのロードは、コンパイル時に利用可能なソースクラスがあるときに行われます。
new
キーワードを使ってオブジェクトインスタンスを作成することでそれを利用できます。
動的クラスロードとは、コンパイル時にクラス定義を提供できない状況を指します。それでも、実行時にそれを実行できます。クラスのインスタンスを作成するには、
Class.forName()
メソッドを使用する必要があります。
Class.forName("oracle.jdbc.driver.OracleDriver")
==== Q7。
Serializable
インターフェイスの目的は何ですか?
-
シリアル化は、オブジェクトの状態をバイトのシーケンスとして保存するためのメカニズムであり、逆シリアル化は、オブジェクトの状態をオブジェクトの状態から復元するためのメカニズムです。バイトのシーケンス直列化された出力は、オブジェクトの状態と、オブジェクトの型とそのフィールドの型に関するメタデータを保持します。
直列化可能クラスのサブタイプも直列化可能であることを知っておく必要があります。ただし、クラスをシリアライズ可能にしたいが、そのスーパータイプをシリアライズ不可能にする場合は、2つのことを行う必要があります。
-
Serializable
インターフェースを実装する -
引数なしのコンストラクタがスーパークラスに存在することを保証する
シリアライゼーションの詳細については、https://www.baeldung.com/java-serialization[1つの記事]を参照してください。