Talendの面接では通常、2つのことが問われます。それは、適切なデータ統合ジョブを設計できるか、そしてジョブが遅い、あるいは壊れている原因を突き止められるかです。構成要素(コンポーネント、サブジョブ、tMap、コンテキスト変数)に関する質問が出たあと、エラー、パフォーマンス、デプロイに関するシナリオ問題が続きます。
Talendは現在Qlikの一部となっており、製品ラインは年々変化しています。求人票を確認して、そのチームがデータ統合ライセンスまたはビッグデータライセンスのTalend Studioを使っているのか、Talend Cloudを使っているのか、あるいは古いオープンソース構成を使っているのかを把握しましょう。以下の概念はそのすべてに当てはまりますが、コンポーネント名やデプロイの詳細は異なります。
よく聞かれる質問
Talendとは何か、どのようにコードを生成するのか?
Talendはデータ統合ツールです。キャンバス上でコンポーネントをつないでジョブを構築すると、Talend Studioがその設計からJavaコードを生成します。ジョブを実行すると、そのコードがコンパイルされて実行されます。これが面接で重要なのは、tJavaやtJavaRowコンポーネントに独自のJavaを書ける理由、ルーチンがJavaクラスである理由、そしてメモリ設定がJVM設定である理由を説明できるからです。
ジョブ、サブジョブ、ジョブレットの違いは何か?
ジョブはワークフロー全体です。サブジョブはデータフローリンクで接続されたコンポーネントのグループで、1つのジョブは通常、トリガーでリンクされた複数のサブジョブから成ります。ジョブレットは、一度保存して多くのジョブで使える再利用可能なコンポーネントのグループで、関数のようなものです。
OnSubjobOkとOnComponentOkの違いは何か?
どちらも、何かが成功した後に実行されるトリガーリンクです。OnSubjobOkはサブジョブ全体が正常に終了したときに発火します。OnComponentOkは1つのコンポーネントが終了した時点で発火するため、サブジョブの途中で発火することもあります。ほかにも、失敗時のOnSubjobErrorとOnComponentError、条件付きパス用のRun ifがあります。
tMapは何をするのか?
tMapは主要な変換コンポーネントです。メインフローを1つ以上のルックアップフローと結合し、式を適用し、行をフィルタリングし、複数の出力にデータを送ります。言及すべき主な機能は次のとおりです。
- ルックアップに対する内部結合と左外部結合
- 結合やフィルターに失敗した行のためのリジェクト出力
- 入力と出力に対するフィルター式
- 変数。これにより計算を一度書けば再利用できる
- ルックアップモデルのオプション:一度だけロード、行ごとにリロード、キー付きで行ごとにリロード
tMapで大きなルックアップを扱うにはどうするか?
デフォルトでは、ルックアップデータはメモリにロードされます。大きなルックアップの場合は、「Store temp data」を設定してtMapにディスクへ書き出させる、JVMメモリを増やす、あるいはデータベース側で結合してこの問題自体を避けるといった方法があります。また、入力行に依存するルックアップには「Reload at each row」を使えますが、1行ごとにクエリが発生するため、小さなメインフローにのみ適しています。
コンテキスト変数とは何か、なぜ使うのか?
コンテキスト変数は、ホスト名、スキーマ、ファイルパス、認証情報など、環境によって変わる値を保持します。一度定義してコンテキスト(Dev、Test、Prod)にグループ化し、実行時にコンテキストを選択します。良い回答には、パスワードをジョブ内に平文で保存すべきではないこと、そしてエクスポートした同じジョブがコンテキストファイルだけを変えてあらゆる環境で実行できるべきだという点を加えましょう。
ジョブ間で値を渡すにはどうするか?
tRunJobを使うと子ジョブにコンテキストパラメーターを渡せます。また子ジョブは、tBufferOutputコンポーネントやグローバル変数を使って親ジョブに値を返せます。1つのジョブ内では、値はglobalMapに保存されます。これはJavaのマップで、(String) globalMap.get("key")で読み取り、globalMap.putで書き込みます。
tFlowToIterateと通常のフローの違いは何か?
通常のフローは、すべての行をまとめてコンポーネント間で移動させます。tFlowToIterateは各行を1回のイテレーションに変えるため、後続のコンポーネントは1行につき1回実行されます。ファイル名やテーブルのリストをループ処理するのに便利ですが、イテレーションごとにサブジョブが開始されるため、大きなデータセットでは遅くなります。
Talendでエラーを処理するにはどうするか?
いくつかの層に分けて挙げましょう。
- OnSubjobErrorやOnComponentErrorなどのトリガーリンクで、失敗を別のパスへ送る
- tDieでエラーコードを付けてジョブを停止し、tWarnで警告をログに記録する
- tLogCatcherで、tDie、tWarn、Java例外によって発生した警告やエラーを収集する
- tMapやデータベース出力コンポーネントなどのコンポーネントのリジェクトリンクで、不正な行を処理する
- tPreJobとtPostJobで、リソースを開き、必ずクリーンアップする
失敗するジョブをデバッグするにはどうするか?
デバッグモードで実行するか、tLogRowを追加してコンポーネント間のデータを確認します。コンソールで正確なエラーとコンポーネント名を確認し、次に接続設定と使用中のコンテキスト値を確認します。データの問題であれば、リジェクトをファイルに出力して調べます。tStatCatcherやジョブの統計を使うと、コンポーネントごとの行数と所要時間も確認できます。
パフォーマンスに関する質問
100万行をロードするジョブが遅いです。何を確認しますか?
- どこに時間がかかっているか。コンポーネントごとの行数と処理時間を見れば、ボトルネックが分かります。
- その処理はデータベース側でやるべきか。結合や集計は、tMapでやるよりもSQLでやる方が速いことがよくあります。
- コミットサイズ。1行ごとにコミットすると遅いので、バッチ単位でコミットします。
- バルクコンポーネント。多くのデータベースには、行単位のINSERTよりもはるかに高速なバルクロード用コンポーネントがあります。
- tMapのルックアップ。大きなインメモリルックアップは、ガベージコレクションの停止やメモリ不足エラーを引き起こすことがあります。
- JVM設定。メモリが制約になっている場合は、最大ヒープ(Xmx値)を上げます。
- 並列処理。一部のコンポーネントやジョブは並列実行できますが、処理の順序に依存しない場合に限ります。
新規または変更されたレコードだけをロードするにはどうしますか?
最終更新タイムスタンプや増分IDなどのハイウォーターマークを保持し、それを管理テーブルやコンテキスト変数に保存して、それより大きい行だけを抽出します。ターゲット側の更新については、キーを比較してinsertまたはupdateアクションを使うか、データベースのMERGE文を使います。削除については、全キーの比較や変更データキャプチャ(CDC)フィードが必要になることがあります。
重複を削除するにはどうしますか?
tUniqRowは選択したカラムで重複を削除し、重複行を別の出力に送ることができます。tAggregateRowはグループ化して値を1つ選ぶことができます。巨大なデータセットの場合は、データベース側でウィンドウ関数を使って処理する方が良いことが多いです。
名前を覚えておきたいコンポーネント
| コンポーネント | 役割 |
|---|---|
| tFileInputDelimited、tFileOutputDelimited | 区切りファイルの読み書き |
| tDBInput、tDBOutput | データベーステーブルの読み書き(データベースごとに専用のバージョンがあります) |
| tMap | 結合、フィルタ、変換 |
| tAggregateRow | グループ化と集計 |
| tSortRow | 行のソート |
| tUniqRow | 重複の削除 |
| tReplicate | 同じフローを複数の出力に送る |
| tNormalize、tDenormalize | カラムを行に分割、または行をカラムにマージ |
| tRunJob | 別のジョブを呼び出す |
| tJava、tJavaRow、tJavaFlex | カスタムJavaコード |
| tLogRow | 行をコンソールに出力 |
| tDie、tWarn、tLogCatcher | エラーハンドリングとログ出力 |
| tPreJob、tPostJob | メインフローの前後に実行されるコード |
デプロイとスケジューリング
Studioから本番環境へジョブをどう持っていくかを説明できるようにしておきましょう。典型的な手順は、ジョブをスタンドアロンパッケージとしてビルドするかリポジトリに公開し、本番用コンテキストを設定し、チームのスケジューラ(Talend自身の管理ツール、cron、その他のオーケストレーターなど)でスケジュールするという流れです。バージョン管理、命名規則、ジョブのドキュメント化も、良い回答のうちに含まれます。
練習できるシナリオ
「毎日顧客ファイルを受け取ります。メールアドレスが欠けている行もあれば、すでにウェアハウスに存在する顧客もあります。このジョブを設計してください。」
優れた回答のアウトライン:
- 定義済みスキーマでtFileInputDelimitedを使ってファイルを読み込みます。
- tMapで、メールアドレスが欠けている行をリジェクトファイルに振り分け、ウェアハウステーブルで顧客キーをルックアップします。
- 既存顧客は更新パスへ、新規顧客は挿入パスへ送ります。
- 適切なコミットサイズで、バッチ単位でデータベースに書き込みます。
- tLogCatcherと管理テーブルを使って、実行ごとの行数とエラーをログに記録します。
- ファイルパスとデータベース接続にコンテキスト変数を使い、同じジョブがどの環境でも動くようにします。
ファイルサイズや履歴を保持する必要があるかなど、前提条件は口に出して伝えましょう。面接官はあなたの考え方を見たいのです。
準備の方法
できれば小さなジョブを一通り作ってみましょう。ファイルを読み込み、tMapでテーブルと結合し、リジェクトを処理し、データベースに書き込む、という流れです。50万行目で失敗したときにどうするかを説明できるようにしておきましょう。自分の経験から実際の例を1つか2つ、実行あたりの行数や削減できた時間などの数字とともに話せるようにしましょう。関連するデータエンジニアリングのトピックについては、DatabricksとSnowflakeの面接ガイドをご覧ください。
声に出して練習するのが効果的です。模擬面接でジョブ設計を説明し、その文字起こしを読んで、説明で手順が抜けている箇所を確認しましょう。本番の面接では、AIツールに関する雇用主のルールに従ってください。
YesToTheOfferでTalend面接回答を練習する
模擬技術面接を実行し、ジョブ設計を声に出して説明し、後でトランスクリプトを確認します。30分無料、サブスクリプションなし。



