Java開発における面接で頻出する核心技术知識点について、基礎概念から応用までを体系的に整理します。
1. Java基礎概念とメモリ管理
JVM、JRE、JDKの関係性:
JDK(Java Development Kit)は開発者向けのツールセットであり、JRE(Java Runtime Environment)を含みます。JREはJavaプログラムの実行環境を提供し、その核心となるのがJVM(Java Virtual Machine)です。Javaが「プラットフォーム独立」である理由は、ソースコードがバイトコード(.classファイル)にコンパイルされ、各OS固有のJVM上で解釈実行されるためです。
データ型とラッパークラス:
基本データ型にはbyte、short、int、long、float、double、char、booleanがあります。これらに対応する参照型がラッパークラス(Integer、Double等)です。intは効率的ですが、Integerはオブジェクトとしての機能(null許容、コレクションでの利用)を持ちます。Java 5以降、自動ボクシング/アンボクシングにより相互変換が自動化されていますが、比較演算時には注意が必要です。
Integer a = 100;
Integer b = 100;
System.out.println(a == b); // true (キャッシュ範囲内)
Integer c = 200;
Integer d = 200;
System.out.println(c == d); // false (異なるオブジェクト参照)
System.out.println(c.equals(d)); // true (内容比較)
2. オブジェクト指向とクラス設計
抽象クラスとインターフェース:
抽象クラスは共通の実装を持つことができるが、単一継承のみ可能です。インターフェースは多重実装が可能で、契約(API仕様)を定義するのに適しています。Java 8以降、インターフェースもdefaultメソッドを持つことができ、実装の柔軟性が増しました。
メソッドのオーバーライドとオーバーロード:
オーバーライドは親クラスのメソッドを子クラスで再定義し(戻り値・引数は同一)、動的ポリモーフィズムを実現します。オーバーロードは同一クラス内で同名のメソッドを引数の型や数を変えて定義し、静的な多態性を提供します。
3. コレクションフレームワーク
List, Set, Mapの特徴:
List(ArrayList, LinkedList)は順序を保持し重複を許可します。Set(HashSet)は重複を禁止し順序を保証しません(LinkedHashSetやTreeSetは順序あり)。Map(HashMap)はキーと値のペアを保持し、キーの重複を許可しません。
HashMapの内部構造:
HashMapは配列と連結リスト(または赤黒木)の組み合わせで実装されます。ハッシュ衝突が発生した場合、JDK 1.8では連結リストの長さが8を超えると赤黒木へ変換し検索効率を改善します。初期容量と負荷係数は拡容のタイミングを決定します。
ArrayListとLinkedList:
ArrayListは動的配列であり、検索は高速(O(1))ですが、要素の追加削除には配列のコピーが必要な場合があり低速です。LinkedListは双方向連結リストであり、追加削除は高速ですが、検索には要素を順次辿る必要があります。
4. マルチスレッドと並行性
スレッドの状態遷移:
スレッドはNew(新規)、Runnable(実行可能)、Blocked(ブロック)、Waiting(待機)、Timed_Waiting(時間待機)、Terminated(終了)の状態を持ちます。sleep()は時間経過で復帰しロックを解放しませんが、wait()は通知を待ちロックを解放します。
synchronizedとLock:synchronizedはJVMレベルの Monitor Enter/Exit 命令により排他制御を行います。JDK 6以降は偏向ロック、軽量ロック、重量ロックへの段階的昇格により効率化されています。ReentrantLockはAPIレベルで制御し、公平ロック、割り込み可能性、条件変数などの高度な機能を提供します。
// 排他制御の例
private final Object mutex = new Object();
public void criticalSection() {
synchronized (mutex) {
// 共有リソースへの安全なアクセス
System.out.println("Processing...");
}
}
volatileキーワード:volatileは変数の変更を他のスレッドに即座に通知し(可視性)、命令の並べ替えを抑制しますが、原子性は保証しません。単純な状態フラグなどに利用されます。
スレッドプールのパラメータ:
ThreadPoolExecutorはcorePoolSize(常駐スレッド数)、maximumPoolSize(最大数)、workQueue(待機队列)、handler(拒否策略)により動作を制御します。タスク拒否時にはAbortPolicy(例外)、CallerRunsPolicy(呼び出し元で実行)などの策略が選択可能です。
5. Springフレームワークの核心
IoC(Inversion of Control)とDI:
Springはオブジェクトの生成と依存関係の注入をコンテナに委譲します。これによりコンポーネント間の結合度が低下し、テスト容易性が向上します。注入方式にはコンストラクタ注入、Setter注入、フィールド注入があります。
AOP(Aspect-Oriented Programming):
ログ記録、トランザクション管理などの横断的関心事をビジネスロジックから切り離します。主にJDK動的プロキシ(インターフェース必須)またはCGLIB(クラス継承)によりプロキシオブジェクトを生成し、メソッド前後で共通処理を実行します。
Spring MVCのフロー:
DispatcherServletが中央制御を行い、HandlerMappingでControllerを特定、実行結果(ModelAndView)をViewResolverが解決し、Viewがレンダリングを行います。
Spring Boot自動構成:@EnableAutoConfigurationはクラスパス上の依存関係を検出し、事前定義された構成を自動適用します。例えば、spring-boot-starter-webが存在すればTomcatとSpring MVCの設定が自動完了します。
6. トランザクション管理
伝播属性(Propagation):REQUIRED(既存トランザクションに参加、なければ新規作成)、REQUIRES_NEW(常に新規作成)、SUPPORTS(あれば参加)などが定義されています。rollbackFor属性により、特定の例外発生時のロールバックを制御できます。
7. データベースとミドルウェア
MySQL InnoDBとMyISAM:
InnoDBはトランザクション、行レベルロック、外部キー制約をサポートし、高頻度更新に適しています。MyISAMは読み取り専用向けで、テーブルロックを使用しトランザクション非対応です。
Redisのデータ型:
String(単純値)、List(順序付きリスト)、Set(集合)、Hash(フィールドと値)、ZSet(順序付き集合)をサポートし、キャッシュ、ランキング、セッション管理に多用されます。
メッセージキュー(MQ):
MQはアプリケーション間の非同期通信、デカップリング、トラフィック平準化を実現します。RabbitMQはAMQPプロトコルに基づき、Kafkaは高吞吐量なログ収集に適します。メッセージの信頼性確保には、確認応答(ACK)、持久化、冪等性処理が重要です。
8. 設計パターンと実践
単一実例:
システム全体で唯一のインスタンスを保証します。実装には事前初期化(Eager)、遅延初期化(Lazy)、ダブルチェック・ロッキング(DCL)があります。
public class AppConfig {
private static volatile AppConfig instance;
private AppConfig() {}
public static AppConfig getInstance() {
if (instance == null) {
synchronized (AppConfig.class) {
if (instance == null) {
instance = new AppConfig();
}
}
}
return instance;
}
}
プロキシパターン:
元のオブジェクトへのアクセスを制御する代理オブジェクトを提供します。Spring AOPやRPC呼び出しの基礎となる技術です。
9. 例外処理機構
Java例外はError(システム障害、VMレベル)とException(アプリケーションレベル)に大別されます。Exceptionは検査例外(必須処理)と非検査例外に分かれます。try-catch-finally構文により資源の解放を保証し、throw、throwsで例外の伝播を制御します。