GoogleフロントエンドエンジニアL4面接体験記:ReactとNode.jsフルスタック評価

フロントエンド中途著者: BeautyResume チーム

フロントエンド4年経験者がGoogle L4面接の全プロセスを共有。1次はReact+TypeScript、2次はNode.js+エンジニアリング、3次はプロジェクトアーキテクチャ(マイクロフロントエンド/コンポーネントライブラリ/SSR)、HR面接、最終的にオファーを獲得。

背景紹介

まずは私の状況から:フロントエンド開発4年の経験があり、現在は中規模インターネット企業でフロントエンドテックリードを務めています。技術スタックは主にReact + TypeScriptで、ここ2年はNode.js BFFレイヤーにも取り組んでおり、半分フルスタックと言えます。今回転職で応募したのは楽天のL4フロントエンドエンジニアです。正直、L4は私にとって挑戦でした——楽天のL4は単にページを書くだけでなく、エンジニアリング能力とアーキテクチャ思考が求められます。

楽天の中途採用プロセスは:履歴書選考 → 技術1次面接 → 技術2次面接 → 技術3次面接(クロスチーム面接)→ HR面接です。全体で約4週間かかり、ペースは速くも遅くもありませんでした。最も緊張したのはクロスチーム面接で、面接官が別の部門から来るため、どのようなスタイルの質問が来るか全く分かりませんでした。

以下、各ラウンドを詳細に振り返り、当時の会話の状況をできるだけ再現します。

面接プロセスの振り返り

技術1次面接:React + TypeScriptの深い評価(約70分)

1次面接は電話面接でした。面接官はターゲットチームのフロントエンド開発者で、早口ですがとても親切な方でした。

1. React Fiberアーキテクチャの原理は?

React 15のStack Reconcilerの問題から始めました——再帰的更新は中断できず、長時間タスクがレンダリングをブロックする問題。その後、Fiberの核心的なアイデアを説明しました:レンダリング作業を小さなfiberノードに分割し、リンクリスト構造で繋ぎ、タイムスライススケジューリングにより中断可能な非同期更新を実現する。面接官はFiberの優先度メカニズムについて深掘りし、レーンモデルについて説明しました——異なるタイプの更新には異なる優先度があり、高優先度の更新は低優先度の更新を中断できます。

2. React Hooksの実装原理は?

HooksのデータはfiberノードのmemoizedStateリンクリストに保存され、各レンダリング時に順番に値を取得するため、条件文の中でHooksを使えないと説明しました。面接官はuseCallbackとuseMemoの違いについて深掘りし、useCallbackは関数参照をキャッシュし、useMemoは計算結果をキャッシュし、本質的にはどちらもObject.isで依存関係が変化したかを比較して再計算するかどうかを決定すると述べました。

3. TypeScriptの高度な型は?

面接官はよく使われる高度な型をいくつか挙げるよう求めました。Partial、Required、Pick、Omit、Record、ReturnType、Parametersを挙げ、Conditional TypesとMapped Typesについても言及しました。DeepPartial型を手書きするよう求められ、再帰的条件型を使って実装しました。面接官はこの回答に満足し、inferキーワードの使用シーンについて深掘りしました。条件型で型変数を推論するために使い、例えばReturnTypeはinfer Rを使って関数の戻り値の型を推論すると説明しました。

4. Reactのパフォーマンス最適化にはどんな手段がありますか?

いくつかのレベルから説明しました:コンポーネントレベルではReact.memo、useMemo、useCallbackで不要な再レンダリングを回避、リストレベルでは仮想リスト(react-window)を使用、状態レベルではuseReducerで複数のuseStateを置き換え、状態を最小コンポーネントに押し下げる、コードレベルではReact.lazy + Suspenseでコード分割を行う。面接官はReact.memoとPureComponentの違いについて深掘りし、React.memoは関数コンポーネント用、PureComponentはクラスコンポーネント用で、どちらもpropsの浅い比較を行うと答えました。

5. コーディング:useDebounce Hookを実装してください。

useRefでタイマーを保存し、useEffectでタイマーをクリアする方法でこのHookを実装しました。面接官はなぜuseStateではなくuseRefを使うのかと聞き、タイマーIDは再レンダリングをトリガーする必要がなく、useStateを使うと余分なレンダリングオーバーヘッドが発生すると答えました。

技術2次面接:Node.js + エンジニアリングの深い評価(約80分)

2次面接はビデオ面接でした。面接官はチームのフロントエンドテックリードで、質問はエンジニアリングとNode.jsに重点を置いていました。

1. Node.jsのイベントループの仕組みは?

Node.jsイベントループの6つのフェーズを説明しました:timers → pending callbacks → idle/prepare → poll → check → close callbacks。pollフェーズに焦点を当て、タイマーが期限切れの場合はtimersフェーズに入ってコールバックを実行、そうでなくてsetImmediateコールバックがあればcheckフェーズに入る、どちらもない場合は新しいIOイベントを待つためにブロックすると説明しました。面接官はprocess.nextTickの実行タイミングについて深掘りし、各フェーズの切り替え間で実行され、Promise.thenよりも優先度が高いと答えました。

2. Node.jsのメモリリークをどう調査するか?

いくつかの方法を挙げました:process.memoryUsage()でメモリ変化を監視、heapdumpでヒープスナップショットを生成してChrome DevToolsで分析、clinic.jsでパフォーマンス診断。面接官は一般的なメモリリークシーンについて深掘りし、解放されていないグローバル変数、大きなオブジェクトを参照するクロージャ、削除されていないイベントリスナー、無制限に成長するキャッシュを挙げました。

3. Webpackのビルド最適化は?

速度とサイズの2つの次元から説明しました。速度最適化:thread-loaderでマルチスレッドコンパイル、cache-loaderでキャッシュ、excludeでビルド範囲を絞り込む、aliasでモジュール検索パスを減らす、dllで不変モジュールを事前コンパイル。サイズ最適化:tree-shakingで未使用コードを削除、splitChunksで共通コードを分割、動的importでオンデマンド読み込み、圧縮(terser/gzip/brotli)。面接官はtree-shakingの原理について深掘りし、ES Moduleの静的解析に基づき、未使用のexportをマークし、圧縮フェーズで削除すると説明しました。なぜCommonJSはtree-shakingできないかと聞かれ、CommonJSは動的ロードのため、コンパイル時にモジュール依存関係を確定できないと答えました。

4. チームのCI/CDプロセスはどうなっていますか?

Jenkins + Dockerの構成を説明しました:コードpushがJenkinsビルドをトリガー → ユニットテストとE2Eテストを実行 → Dockerイメージをビルド → イメージレジストリにプッシュ → K8sクラスタにデプロイ。面接官はカナリアリリースについて深掘りし、K8sのローリングアップデート戦略を使い、まず少数のPodを更新して検証し、問題なければ全量更新すると述べました。また、feature flagを使った機能のカナリアリリースについても触れ、再デプロイなしに機能のオンオフを制御できると説明しました。

5. フロントエンドモニタリングソリューションをどう設計するか?

3つの次元から説明しました:パフォーマンスモニタリング(FCP/LCP/CLSなどのWeb Vitals指標)、エラーモニタリング(JSエラー/未処理のPromise拒否/リソース読み込み失敗)、ビジネスモニタリング(PV/UV/キーパスコンバージョン率)。データ収集はPerformanceObserverでパフォーマンス指標をキャプチャ、window.onerrorとunhandledrejectionでエラーをキャプチャ、カスタムトラッキングでビジネスデータをキャプチャ。データ報告はsendBeaconを使ってページアンロード時のデータ損失を防止。面接官はエラー集約について深掘りし、エラースタックのトップフレームでフィンガープリントを作成し、同じフィンガープリントのエラーを1つのエントリに集約すると答えました。

技術3次面接:プロジェクトアーキテクチャの深い評価(約60分)

3次面接はクロスチーム面接で、面接官は別の部門から来ており、よりマクロな質問でアーキテクチャ設計に焦点を当てていました。

1. フロントエンドアーキテクチャはどうなっていますか?

マイクロフロントエンドアーキテクチャで、qiankunをベースに使用し、各ビジネスモジュールが独立したサブアプリケーションであると説明しました。利点は各チームが独立して開発・デプロイでき、技術スタックに制限がないこと。欠点はスタイル分離と通信が複雑なこと。面接官はマイクロフロントエンドの通信ソリューションについて深掘りし、CustomEvent、props渡し、パブサブパターン、共有状態(ベース経由で中継)を挙げました。スタイル分離についても聞かれ、qiankunはデフォルトでShadow DOMを使いますが、一部のUIライブラリと互換性がないため、ランタイムで動的にCSSプレフィックスを追加する方式に切り替えたと説明しました。

2. コンポーネントライブラリをどう設計するか?

いくつかの側面から説明しました:設計仕様(色/間隔/タイポグラフィ/角丸などのDesign Token)、コンポーネントの階層化(基本コンポーネント/ビジネスコンポーネント/テンプレート)、開発ツールチェーン(Storybookドキュメント + ユニットテスト + E2Eテスト)、ビルド成果物(ES Module + CommonJS + UMDの3形式)、バージョン管理(semver + changelog自動生成)。面接官はコンポーネントライブラリのオンデマンド読み込みについて深掘りし、ES Moduleのtree-shakingとbabel-plugin-importによる自動インポートパス変換の2つのアプローチを挙げました。

3. SSRとCSRの選択は?

それぞれの長所と短所を説明しました:SSRは初回描画が速くSEOに有利だがサーバー負荷が高くTTFBが長い、CSRはサーバー負荷が低いが初回描画が遅くSEOに不利。その後、SSR + CSRのハイブリッドアプローチを説明しました——初回画面はSSRで読み込み速度とSEOを確保し、その後のインタラクションはCSRで行う。面試官はSSRのハイドレーションプロセスについて深掘りし、Reactがクライアント側でコンポーネントツリーを再実行し、サーバー側でレンダリングされたHTMLにイベントと状態をバインドしてページをインタラクティブにすると説明しました。

HR面接(約25分)

HR面接では以下の質問がありました:

1. なぜ現在の会社を離れるのか?

2. キャリアプランは?

3. 希望年収は?

4. 残業に対する態度は?

5. 何か質問はありますか?

退職理由については、前の会社の悪口を言わず、より大きなプラットフォームと技術的挑戦を求めていると答えました。給与については、法外な要求をせず、妥当な昇給幅の範囲を提示しました。

全問題一覧

1. React Fiberアーキテクチャの原理とレーン優先度モデル

2. React Hooksの実装原理

3. TypeScriptの高度な型と手書きDeepPartial

4. Reactパフォーマンス最適化手法

5. useDebounce Hookの実装(手書き)

6. Node.jsイベントループの6フェーズ

7. Node.jsメモリリークの調査

8. Webpackビルド最適化(速度+サイズ)

9. tree-shakingの原理とCommonJSの制限

10. CI/CDプロセスとカナリアリリース

11. フロントエンドモニタリングソリューションの設計

12. マイクロフロントエンドアーキテクチャと通信/スタイル分離

13. コンポーネントライブラリの設計アプローチ

14. SSRとCSRのトレードオフとハイドレーションプロセス

学びとアドバイス

1. L4は単にページを書くことではありません。楽天のL4はエンジニアリング思考とアーキテクチャ能力を求めており、コンポーネントとページのレベルにとどまることはできません。面接ではより高い次元から問題を見る必要があります——なぜこのように設計するのか、どのようなトレードオフがあるのか、効果をどう測定するのか。日常業務で「なぜ」について多く考えることをお勧めします。「どうやるか」だけでなく。

2. Reactの基盤原理を理解しましょう。Fiber、Hooksの実装、スケジューリングメカニズムはほぼ確実に聞かれます。Reactのソースコードを読むことをお勧めします——少なくともreconcilerとschedulerの核心的なロジックは一通り見てください。全部読む必要はありませんが、核心的なフローは理解しましょう。

3. TypeScriptの高度な型を書けるようにしましょう。楽天のTypeScript要件は高く、interfaceとtypeが分かるだけでは不十分です。条件型、マップ型、inferなどの高度な機能も書ける必要があります。type-challengesリポジトリで練習することをお勧めします。

4. Node.jsとエンジニアリングは大きな差別化要因です。L4面接ではNode.jsとエンジニアリング関連の問題が大きな割合を占めます。BFFやツールチェーンの経験があれば、重点的に準備してください。なければ、少なくともNode.jsイベントループ、メモリ管理、Webpack最適化の基礎知識は理解しておきましょう。

5. アーキテクチャ設計には自分の考えを持ちましょう。面接官がアーキテクチャの質問をするのは標準解答を求めているのではなく、あなたの思考プロセスを見たいからです。回答する際は、まず全体的なアプローチを述べ、次に詳細に展開しましょう。各決定ポイントで、なぜこのアプローチを選んだのか、どのような代替案があるのか、それぞれの長所と短所は何かを明確に説明してください。

6. クロスチーム面接でパニックにならないでください。クロスチーム面接官は別の部門から来ており、前のラウンドとは全く異なるスタイルの質問をするかもしれません。落ち着いて、同じように答えましょう——まずアプローチを述べ、次に詳細に展開する。

FAQ

Q:楽天のL4面接は通常何回ありますか?

A:技術3回 + HR面接、合計4回です。クロスチーム面接は楽天の特色で、面接官は別の部門から来ます。

Q:L4とL5の違いは何ですか?

A:L4は実行寄りで、複雑なモジュールの設計と開発を独立して行えること。L5はアーキテクチャ寄りで、プロジェクトの技術ソリューションとチームの技術方向を主導できること。L5面接にはより多くのアーキテクチャ設計問題があります。

Q:面接の言語は?

A:全編中国語で、英語面接はありません。

Q:中途採用に学歴要件はありますか?

A:学士以上ですが、プロジェクト経験と技術の深さがより重視されます。L4は通常3〜5年の経験が必要です。

Q:給与の範囲はどのくらいですか?

A:L4の給与範囲はかなり広く、ベースは約30〜50k、ストックオプションと年末ボーナスを含めた年収パッケージは約50〜80wです。具体的には面接の評価と交渉力によります。

#Alibaba#Frontend P6#React#TypeScript#Node.js#Engineering#Micro Frontends#中途採用