Booking.com Javaエンジニア面接体験記:ミドルウェアと分散システムの完全評価

面接体験記著者: BeautyResume チーム

4年経験のJava開発者によるBooking.com 3次面接の完全体験記。Spring Cloud、Dubbo、RocketMQ、分散トランザクションなどの実際の問題を詳細解説、2026年最新の面接体験を共有。

背景紹介

まず私の状況をお話しします。Java開発経験4年、以前は旅行会社でバックエンド開発を担当し、主に注文システムと決済システムを開発していました。4年間在籍し、ジュニアからシニア開発者まで成長しましたが、会社の技術スタックが古く、まだSpring Cloud Netflixのスタックを使っており、多くのコンポーネントがメンテナンスを終了していました。より良いエンジニアリング文化を持つプラットフォームを見つけたいと思っていました。今年の5月、リクルーターから楽天トラベル(Rakuten Travel)がJavaエンジニアを募集していると連絡があり、ミドルウェア方向のポジションで、私の分散システム経験と合致するため、面接を設定しました。

面接プロセスは技術面接3回+HR面接1回で、一次面接からオファー獲得まで約2週間でした。楽天トラベルの面接効率はかなり高く、各ラウンドの終了後1〜2日で結果が出ました。

一次面接:Java並行+JVM+MySQL

Java並行プログラミング

一次面接の面接官はミドルウェアチームの開発者で、まず自己紹介を求められ、その後すぐに技術的な質問に入りました。Java並行は重点的な評価分野で、かなり深く質問されました。

スレッドプール:面接官は「スレッドプールのコアパラメータは何か?それぞれの役割は?」と質問しました。私は7つのコアパラメータを挙げました:corePoolSize(コアスレッド数)、maximumPoolSize(最大スレッド数)、keepAliveTime(アイドルスレッドの生存時間)、unit(時間単位)、workQueue(タスクキュー)、threadFactory(スレッドファクトリー)、handler(拒否戦略)。面接官は「スレッドプールのワークフローはどうなっているか」と深掘りしました。私は:まずコアスレッドを作成→コアスレッドが満杯ならキューに入れる→キューが満杯なら非コアスレッドを作成→最大スレッド数に達したら拒否戦略を実行、と答えました。面接官はさらに「プロジェクトではどんなキューを使っているか」と質問し、私は有界LinkedBlockingQueueで容量を500に設定し、拒否戦略はCallerRunsPolicyを使用——タスクを提出したスレッド自身に実行させることで、ある程度のレートリミット効果があると答えました。

ロック機構:面接官は「synchronizedとReentrantLockの違いは?」と質問しました。私はいくつかの観点から回答しました:実装方式(synchronizedはJVMレベル、ReentrantLockはAPIレベル)、機能(ReentrantLockはフェアロック、割り込み可能性、複数の条件変数をサポート)、パフォーマンス(JDK 6以降のsynchronized最適化により、パフォーマンスの差はほぼない)。面接官は「synchronizedのロックアップグレードプロセスは?」と深掘りしました。私は:ロックなし→バイアスロック→軽量ロック→重量ロックと説明し、各段階のトリガー条件と適用シーンを解説しました。面接官はAQSの原理も質問し、私はAQSのコアはvolatile int stateとCLH双方向キューで、排他モードではstateが0ならロック解除、1ならロック中。共有モードではstateが利用可能なリソース数を表すと説明しました。

JVMチューニング

面接官は「JVMチューニングの経験は?どうやったか?」と質問しました。私は、決済サービスで頻繁にFull GCが発生しており、GCログの分析で老年代の空き容量不足が原因と判明したと説明しました。私たちの解決策は:ヒープサイズの調整(2Gから4Gへ)、新生代と老年代の比率調整(デフォルトの1:2から1:1.5へ——オブジェクトの大部分が短命だから)、CMSからG1コレクタへの切り替え。チューニング後、Full GCの頻度は1日3〜4回から週1〜2回に減少しました。

面接官は「OOM問題のトラブルシューティング方法は?」と深掘りしました。私はまずHeap DumpファイルをMATまたはVisualVMで分析し、メモリを最も占有しているオブジェクトと参照チェーンを見つけると説明しました。メモリリークの場合は、回収されるべきだが回収されていないオブジェクトを探し、メモリオーバーフローの場合はヒープサイズの増加やオブジェクト生成の最適化を検討します。面接官はよく使うJVMパラメータも質問し、私は-Xms、-Xmx、-Xmn、-XX:+UseG1GC、-XX:MaxGCPauseMillis、-XX:+HeapDumpOnOutOfMemoryErrorなどを挙げました。

MySQLインデックス最適化

面接官は「MySQLのインデックス構造は?なぜB+木を使うのか?」と質問しました。私はInnoDBはB+木を使用しており、その理由は:B+木のリーフノードがリンクリストで接続されており範囲検索が効率的、非リーフノードはキーのみを保存するため1ノードにより多くのキーを格納でき、木が低くなりIO回数が減少、検索パフォーマンスが安定していて毎回リーフノードに到達する必要があることだと説明しました。面接官は「複合インデックスの最左プレフィックス原則とは?」と深掘りしました。私は複合インデックス(a,b,c)は(a)、(a,b)、(a,b,c)の3つのインデックスを作成するのに相当し、検索条件は最左列からマッチングを開始する必要があると説明しました。面接官は実際のシーンを提示しました:「検索条件がa=1 AND c=3の場合、インデックスは使えるか?」私はa列はインデックスを使えるが、c列はb列をスキップしているため使えないと答えました。ただしc列のカーディナリティが高い場合は、インデックス列の順序の調整を検討できます。

二次面接:Spring Cloud+Dubbo+RocketMQ+分散トランザクション

Spring Cloudコンポーネント

二次面接の面接官はチームのアーキテクトで、質問はよりアーキテクチャとミドルウェアに焦点を当てていました。まずSpring Cloudコンポーネントの使用状況を質問され、私は以前Spring Cloud Netflix(Eureka+Ribbon+Hystrix+Zuul)を使用しており、現在Spring Cloud Alibaba(Nacos+Sentinel+Gateway)に移行中だと答えました。面接官は「なぜ移行するのか?」と質問し、私はNetflixコンポーネントは基本的にメンテナンスを終了しており、Alibabaエコシステムのコンポーネントはコミュニティサポートが良いこと、Nacosは設定センターとサービスレジストリの両方をサポートし、Eureka+Config Serverよりシンプルだと答えました。

Dubbo vs Spring Cloud

面接官は「DubboとSpring Cloudの違いは?どう選定するか?」と質問しました。私はDubboはRPCフレームワークで、Spring Cloudはマイクロサービスのフルスタックであり、両者は完全に同等ではないと説明しました。Dubboはパフォーマンスが良く(TCPベースのカスタムプロトコル)、内部サービス間の高頻度呼び出しに適している。Spring Cloudはエコシステムがより完全で、マイクロサービスアーキテクチャの迅速な構築に適している。実際のプロジェクトでは、パフォーマンス要件が高く、サービス間の呼び出しが頻繁な場合はDubboを選び、開発効率とエコシステムの完全性を重視する場合はSpring Cloudを選ぶと答えました。面接官は「Dubboのロードバランシング戦略は何があるか」と深掘りし、私はRandom(ランダム、デフォルト)、RoundRobin(ラウンドロビン)、LeastActive(最小アクティブ呼び出し)、ConsistentHash(一貫性ハッシュ)を挙げました。

RocketMQの原理

面接官は「なぜRocketMQをKafkaの代わりに選ぶのか?」と質問しました。私はいくつかの理由を挙げました:RocketMQはトランザクションメッセージをサポートし、注文システムの結果整合性シナリオに適している。RocketMQの遅延メッセージ機能を多用している(例:注文から30分未払いで自動キャンセル)。RocketMQはメッセージの信頼性が高く、メッセージのトレースをサポートしている。面接官は「RocketMQのトランザクションメッセージはどう実装されているか」と深掘りしました。私はコアのフローを説明しました:まずハーフメッセージを送信→ローカルトランザクションを実行→ローカルトランザクションの結果に基づいてメッセージをコミットまたはロールバック→長時間コミット/ロールバックがない場合、Brokerがローカルトランザクションのステータスを確認する。面接官はさらに「RocketMQはメッセージの損失をどう防ぐか」と質問し、私は3つのレベルで説明しました:Producer側は同期送信+リトライ、Broker側は同期フラッシュ+マスタースレーブレプリケーション、Consumer側は手動ACK。

分散トランザクション

面接官は「分散トランザクションのソリューションは?それぞれの長所と短所は?」と質問しました。私は3つの主流アプローチを詳しく説明しました:

2PC(二相コミット):強一貫性だが、同期的ブロッキングとコーディネーターの単一障害点の問題がある。一貫性の要件が極めて高いシナリオに適している。実際には直接使われることは少なく、XAは2PCの実装。

TCC(Try-Confirm-Cancel):ビジネスレイヤーの二相コミットで、各サービスがTry、Confirm、Cancelの3つのインターフェースを実装する必要がある。長所:パフォーマンスが良く、柔軟性が高い。短所:ビジネスへの侵入性が強く、開発コストが高い。私たちの決済システムはSeataフレームワークを通じてTCCを使用している。

Saga:長トランザクションパターンで、各ステップに対応する補償操作がある。ビジネスプロセスが長く、参加サービスが多いシナリオに適している。長所:パフォーマンスが良く、ブロッキングがない。短所:結果整合性のみで、中間状態が可視。

面接官は「実際のプロジェクトではどれを使っているか」と深掘りしました。私は決済システムはTCCを使用し、注文システムはRocketMQトランザクションメッセージで結果整合性を実現している。2つのシステムは一貫性の要件が異なるため、アプローチも異なると答えました。

三次面接:アーキテクチャ設計+高並行+本番問題+アルゴリズム

プロジェクトアーキテクチャ設計

三次面接の面接官は部門のテクニカルリーダーで、よりマクロな質問が中心でした。まず以前の注文システムの全体アーキテクチャを説明するよう求められ、その後いくつかの重要な設計決定について深掘りされました。私は注文システムがマイクロサービスアーキテクチャで、コアサービスは注文サービス、在庫サービス、決済サービス、通知サービスを含むと説明しました。サービス間はDubbo RPCで通信し、非同期シナリオではRocketMQを使用。面接官は「注文作成の完全なフローは?」と質問し、私は:ユーザーの注文→在庫確認→在庫ロック→注文作成→決済開始→決済コールバック→注文ステータス更新→在庫解放/在庫控除→通知送信と説明しました。各ステップには失敗処理と冪等設計があります。

高並行ソリューション

面接官は「フラッシュセールシナリオで瞬間的に10万QPSの場合、どう設計するか?」と質問しました。私はいくつかの防御レイヤーを説明しました:第1層CDN+Nginxレートリミットで大部分の無効リクエストをフィルタリング。第2層Redisでの在庫事前控除で、在庫が十分なリクエストのみ注文プロセスに進む。第3層メッセージキューでピークカット、注文リクエストをまずキューに入れてから非同期処理。第4層データベースレベルで楽観ロックで在庫のオーバーセルを防止。面接官は「Redisの在庫事前控除とデータベースの一致性をどう保証するか」と深掘りしました。私はLuaスクリプトで原子性を保証し、注文成功後にデータベースの在庫を同期的に更新し、注文失敗時はRedisの在庫を戻すと説明しました。同時に定期リコンシリエーションタスクでデータの照合を行い、結果整合性を保証しています。

本番問題のトラブルシューティング

面接官は「最も厄介な本番問題は何か?どうトラブルシューティングしたか?」と質問しました。私は、決済サービスのAPIが突然遅くなり、P99が200msから5sに急上昇したことがあると説明しました。トラブルシューティングのプロセス:まずモニタリングを確認しデータベースクエリの遅延を発見→スロークエリログで異常な実行時間のSQLを発見→EXPLAINで分析しインデックスが無効になっていることを発見(関数でインデックス列がラップされていた)→SQLを修正して復旧。根本原因は誰かがWHERE句でインデックス列に関数変換を適用するコードをコミットし、フルテーブルスキャンを引き起こしたことでした。面接官は「この問題の再発をどう防ぐか」と質問し、私はコードレビューのプロセスにSQLレビューを追加し、同時にSQL監査プラットフォームを導入してスロークエリとインデックス使用状況を自動検出していると答えました。

アルゴリズム問題

アルゴリズムは2問:TopK問題と二分探索木の検証。

TopK:面接官は「1億個の数から上位100個を見つける」という問題を出しました。私は3つのアプローチを説明しました:ミニヒープ(サイズ100のヒープを維持、時間計算量O(nlogk))、クイックセレクト(クイックソートのpartitionに基づく、平均O(n))、分割統治+マージ(分散シナリオに適している)。面接官はミニヒープのアプローチを書くよう求め、約10分で完了しました。面接官は問題ないと言ってくれました。

二分探索木の検証:二分木が与えられ、正当なBSTかどうかを判定する。私は inorder traversal + 前駆ノードのアプローチを使用しました。BSTの inorder traversal の結果は厳密に増加しているはずです。面接官は「木が非常に大きく、再帰でスタックオーバーフローする場合は?」と深掘りしました。私はMorris traversalを使用して空間計算量O(1)にするか、反復的な inorder traversal を使用できると答えました。

HR面接:キャリアプラン+給与+入社日

HR面接は比較的リラックスした雰囲気で、主にキャリアプラン、給与の希望、入社日について話しました。キャリアプランについては、短期的にはミドルウェア領域を深め、長期的にはアーキテクトの方向に進みたいと述べました。給与面では希望レンジを提示し、HRは楽天トラベルの給与構造がベース+パフォーマンスボーナス+ストックオプションで、具体的には等級決定後になると説明しました。入社日は最短1ヶ月と答えました。HRは他のオファーがあるかも聞き、私は他社も面接中だが楽天トラベルが第一志望だと答えました。

面接問題まとめ

Java並行

1. スレッドプールのコアパラメータとワークフロー

2. synchronizedとReentrantLockの違い

3. synchronizedのロックアップグレードプロセス

4. AQSの原理

JVM

5. JVMチューニングの経験

6. OOMトラブルシューティング方法

7. よく使うJVMパラメータ

MySQL

8. B+木インデックス構造と利点

9. 複合インデックスの最左プレフィックス原則

Spring CloudとDubbo

10. Spring Cloud NetflixからAlibabaへの移行理由

11. Dubbo vs Spring Cloudの選定基準

12. Dubboのロードバランシング戦略

RocketMQ

13. RocketMQ vs Kafkaの選定基準

14. RocketMQトランザクションメッセージの実装

15. RocketMQでメッセージ損失を防ぐ方法

分散トランザクション

16. 2PC、TCC、Sagaの違いと適用シーン

17. Seataフレームワークの使用

アーキテクチャ設計

18. フラッシュセールシステムの高並行設計

19. Redis在庫事前控除とデータベースの一致性

20. 本番問題のトラブルシューティング経験

アルゴリズム

21. TopK問題(ミニヒープ/クイックセレクト/分割統治)

22. 二分探索木の検証(inorder traversal/Morris traversal)

感想とアドバイス

1. Java基礎は確実に。楽天トラベルの面接はJava基礎への要求が高く、特に並行とJVM。教科書の暗記だけで通るものではなく、実際のプロジェクトと結びつけて説明できる必要があります。準備の際は各知識ポイントについて実際のケースを用意することをお勧めします。

2. ミドルウェアの原理を深く理解する。RocketMQやDubboなどのミドルウェアは、使い方を知っているだけでなく、基礎原理を説明できる必要があります。面接官はソースコードレベルの詳細まで深掘りします。例えばRocketMQのハーフメッセージメカニズムや、Dubboのサービスエクスポートと参照フローなど。

3. 分散トランザクションは高頻度のトピック。2PC、TCC、Sagaの3つのアプローチは確実に説明できるようにしてください。実際のプロジェクトと結びつけて、どれを選んだか、なぜ選んだか、どんな問題に直面したかを説明できるとなお良いです。

4. システム設計はレイヤー構造を持たせる。高並行の質問に答える際は、外から内へレイヤーごとに回答することをお勧めします:CDN/ゲートウェイ層→アプリケーション層→キャッシュ層→メッセージキュー層→データベース層。各層が何をするか、どう連携するかを明確な論理で説明してください。

5. 本番問題のトラブルシューティングには方法論が必要。結論だけを言うのではなく、トラブルシューティングのプロセスを説明してください:問題の発見→範囲の特定→原因の分析→仮説の検証→問題の修正→再発防止策。面接官はトラブルシューティングのアプローチをより重視します。

よくある質問FAQ

Q1:楽天トラベルのJava面接の重点は?

Java並行、JVM、ミドルウェア(RocketMQ、Dubbo)、分散トランザクションが重点です。システム設計と高並行ソリューションも問われることがありますが、毎回のラウンドにあるわけではありません。

Q2:ミドルウェア経験がなくても楽天トラベルの面接を受けられるか?

ミドルウェアチームのポジションはミドルウェア経験の要件が高いですが、ビジネス開発のポジションであれば基本原理を理解していれば大丈夫です。ポジションの要件に合わせて準備の重点を調整することをお勧めします。

Q3:楽天トラベルの面接のアルゴリズム難易度は?

中程度の難易度で、それほど難しくありません。TopK、LRU、二分木関連が高頻度の問題で、これらの定番問題を重点的に練習することをお勧めします。

Q4:楽天トラベルの給与水準は?

楽天トラベルの給与はIT企業の中では中程度で、4年経験でだいたいミドル〜シニアクラスです。具体的なデータは転職サイトを参照してください。

Q5:面接プロセスはどのくらいかかる?

今回、一次面接からオファー獲得まで約2週間で、各ラウンドの終了後1〜2日で結果が出ました。全体的に効率が高く、多くの企業より速い印象でした。

#携程#Java Interview# Distributed#面试 Real Questions