本文へ移動

ホーム / App / 第6部 面接の実践

第6部 面接の実践・第15章

設計・実技の面接

★★☆ 重要11トピック・面接 4問

アプリエンジニアの設計面接は、サーバーの設計より端末の側に重心があります。フィードやチャットのような定番のお題で、画面の状態・端末の保存・同期・通信の失敗をどう扱うかが見られます。ライブコーディングや持ち帰りの課題の進め方もここでまとめます。

設計面接は、正解を当てる場ではなく、要件を確かめ、選択肢を比べて決めていく過程を見せる場です。45分なら、要件の確認に5分、全体の構成に10分、端末の工夫と深掘りに20分、失敗と計り方に5分、質問に5分くらいが目安です。

45分の例:端末ならではの工夫に一番時間を使う要件5分画面とデータの流れ10分API とデータの形10分端末の工夫(深掘り)15分失敗・計測5分全部を浅く話すより、面接官が興味を持ったところを深く掘る
45分の設計面接の時間配分の例。端末の工夫に一番時間を使う

答え方の型

順番話すこと
1. 要件を確かめる主な機能、利用者の数、オフラインが必要か、対応する OS。範囲を絞る
2. 画面とデータの流れ主な画面、画面 → ViewModel → Repository → API・DB の構成
3. API とデータの形取りにいく API(ページ送りはカーソル方式など)、端末の DB の表
4. 端末の工夫キャッシュ・オフライン・同期・プッシュ・画像の読み込み
5. 失敗への備え回線が切れた・サーバーが落ちた・古い版が残る場合
6. 計り方どの数字(表示までの時間・クラッシュ率など)で良し悪しを見るか

途中で決め打ちせず、「A なら速いが通信が増える、B なら…」と選択肢を比べて理由を言うのがこつです。時間が限られるので、全部を浅く話すより、面接官が興味を持った部分を深く掘るほうが評価されます。

分類質問の例
機能必須の機能は何か、後回しでよい機能は何か(既読・画像・検索など)
利用者と規模1日の利用者数、1人あたりの件数、データの増え方
オフライン電波がないときに見たいか、編集したいか
鮮度どれくらい新しい情報が必要か(リアルタイムか、開いたときでよいか)
対応 OS・端末iOS・Android の両方か、タブレット、最低の OS の版
端末の制約通信量・電池・容量への配慮、性能の低い端末も対象か
サーバーAPI は自由に設計できるか、既存の API に合わせるか
その他ログインの有無、多言語、アクセシビリティ、プライバシーの決まり

全部を聞く必要はありません。お題にとって大事な3〜4個を聞き、答えがなければ「〜と仮定して進めます」と自分で決めて先に進みます。

項目目安
1コマの時間60Hz で 16.7ms、120Hz で 8.3ms
画像のメモリ縦 × 横 × 4バイト。1000×1000 で約 4MB
表示用の画像のファイルサムネイルで数十 KB、全画面で数百 KB くらい
一覧の1ページ20〜50件。JSON は1件あたり1〜数 KB
プッシュ通知の中身APNs・FCM とも 4KB まで
モバイル回線の往復数十〜数百 ms。不安定なときはさらに遅く、切れる
端末の DB数万〜数十万行なら、インデックスがあれば SQLite で十分に速い

例えば画像のフィードで、1ページ20件・サムネイル 50KB・JSON 2KB なら、1ページで約 1MB です。スクロールの先読みを2ページにすると、回線が遅いときに何秒かかるか、通信量が月に何 MB になるか、と話を進められます。数字は正確さより、桁と考え方を示すことが大事です。

お題中心になる論点
画像のフィード(SNS・EC)ページ送り、画像のキャッシュと縮小、先読み、いいねの楽観的な更新
チャットリアルタイムの受信、送信待ちのキュー、順番、既読、プッシュ
オフラインのメモ・ToDo端末の DB、同期と衝突、削除の墓標
写真・動画のアップロード大きなファイル、中断と再開、裏での実行
地図・位置情報電池、権限の求め方、裏での位置情報の制限
ニュース・記事の閲覧キャッシュ、オフラインで読む、リンクから記事を開く
決済・予約二重送信の防止、冪等キー、状態の確認、失敗時の戻し

どのお題でも、オフライン・失敗・古い版・計り方の4つは必ず聞かれると考えて準備しておきます。

「オフラインでも使えるチャットアプリ」の回答の骨組みです。端末の DB を正にすることを最初に宣言すると、話がぶれません。

論点答え方の例
表示画面は DB だけを読む。受信も送信も、まず DB に入れてから画面に流れる
送信DB と送信待ちのキューに同じトランザクションで入れ、「送信中」で表示。端末で作った ID を冪等キーにして送る
受信開いている間は WebSocket、閉じている間はプッシュ。戻ったらカーソルで差分を取る
順番サーバーが付けた順番を正にし、未送信のものは最後に並べる
既読どこまで読んだかの位置だけを送る。細かく送らずまとめる
失敗送れないものは再送ボタン。何度も失敗したら止めて知らせる
計り方送ってから相手に届くまでの時間、送信の失敗率、未送信の残り件数
画面は DB だけを読むチャット画面ViewModelRepository端末の DBメッセージ・送信待ちWebSocket(開いている間)送信 API(冪等キー)プッシュ(閉じている間)読む・書く送る受信知らせ → 差分
画面は DB だけを読む。送信はキュー経由、受信は WebSocket とプッシュ、戻ったら差分を取り直す

「SNS のような画像のフィード」の回答の骨組みです。データ(投稿の一覧)と画像を別の道として考えると整理しやすくなります。

論点答え方の例
ページ送りカーソル方式。残り数件で次を取りにいき、取得中の二重の要求は止める
データの保存結果を DB に入れ、画面は DB を読む。次に開いたとき前回の一覧をすぐ出す
新しい投稿上に引っ張って更新。新着は「新しい投稿があります」で知らせ、勝手に一覧を動かさない
画像表示の大きさを指定して CDN から取る。メモリとディスクの2段のキャッシュ。見えなくなった行の読み込みは取り消す
いいね先に画面に反映して裏で送り、失敗したら戻す(楽観的な更新)
性能行に安定した ID。画像の縮小は裏で。性能の低い端末でスクロールの滑らかさを計る
計り方最初の表示までの時間、スクロールのコマ落ち、画像の表示までの時間、通信量
データと画像は別の道で届くフィード画面ViewModel・PagingRepositoryAPI(カーソル方式)端末の DB(キャッシュ)画像ローダーメモリ → ディスク → 通信画像の CDN(大きさ指定)
API の結果は DB に入れて画面は DB を読む。画像は2段のキャッシュで表示の大きさに

「写真や動画をアップロードする機能」の回答の骨組みです。ポイントは、大きい・時間がかかる・途中で切れるの3つへの備えです。

論点答え方の例
送る前端末で縮めて圧縮する。位置情報などのメタデータを消すかも確かめる
送り方サーバーが発行する署名付きの URL にストレージへ直接送る。大きなファイルは分割して、切れたら続きから
裏での実行iOS はバックグラウンドの URLSession、Android は WorkManager。送る予定は DB に保存
状態の表示待ち・送信中(進み具合)・完了・失敗を一覧で見せる
失敗一時的な失敗は間をあけて再試行。何度も失敗したら知らせて、再送できるようにする
二重登録端末で作った ID を付けて、同じ写真を2回登録しない
計り方成功率、完了までの時間、途中で諦めた割合
縮めて、裏で、続きから送る写真を選ぶ送る予定を DB に縮める・圧縮端末で裏の仕組みに頼むOS の仕組みへ分割して送る切れたら続きから完了の確認サーバーで処理後署名付きの URL でストレージへ直接送ると、API サーバーを大きなファイルが通らない
端末で縮めてから、裏で動く仕組みに頼んで分割して送り、切れたら続きから
観点聞かれ方の例
オフライン電波がないときに操作されたら? つながったときの順番は?
一貫性2台の端末で同時に編集したら? 削除したものが復活しない?
古い版API を変えたら古いアプリはどうなる?
性能1万件あったら? 性能の低い端末では?
電池・通信量ずっと接続しておいてよい? モバイル回線で動画を送る?
セキュリティトークンはどこに? リンクから開いたときの確認は?
テストこの同期のロジックをどうテストする?
計測うまくいっているかを何で判断する?

深掘りされたら、まず質問の前提を確かめてから答えます。分からない部分は「その場合はこう考えます」と考え方を示せば十分です。

アプリエンジニアのライブコーディングは、アルゴリズムの問題のほかに、小さな画面や機能をその場で作る課題が出ることがあります。

動くものを先に、改善は後で問題を言い直す方針を話す素直に書く例で確かめる改善を話す考えていることを声に出し続ける。黙って書き続けない
前提を確かめ、素直に動くものを先に作り、例で確かめてから改善する
よく出る課題見られる点
API から一覧を取って表示する状態(読み込み中・成功・エラー)の扱い、再試行
検索欄で入力ごとに検索するデバウンス、前の要求の取り消し、古い結果で上書きしない
画像のキャッシュを作るLRU、上限、同時に同じ画像を取りにいかない
配列・文字列の処理計算量、境界の場合(空・1件)の扱い

コードの正しさだけでなく、考えを声に出しているか、例を使って確かめているか、つまったときに助けを求められるかも見られています。

見られることやること
設計画面・ViewModel・Repository を分ける。過剰に分けすぎない
状態の扱い読み込み中・空・エラー・再試行を作る
テスト主要なロジック(ViewModel・変換)に単体テスト
読みやすさ名前・小さな関数・不要なコメントを残さない
README設計の判断と理由、省いたこととその理由、動かし方
コミット意味のある単位で分ける

指定された時間を大きく超えて作り込むより、決めた範囲をきれいに仕上げて、省いたことを説明するほうが評価されます。面接では課題について質問されるので、自分の判断を説明できるようにしておきます。

15.11よくある失敗

★★☆ 重要
失敗こうする
要件を聞かずに書き始める最初の5分で大事な3〜4個を確かめる
サーバーの設計ばかり話す端末の側(状態・保存・同期・画像)に時間を使う
うまくいく場合だけ話すオフライン・失敗・古い版を自分から出す
ライブラリの名前を並べるそのライブラリが何をしてくれるか、仕組みで話す
1つの案に決め打ちする2つの案を比べて、選んだ理由を言う
全部を浅く話す面接官が興味を持ったところを深く掘る
黙り込む迷っていることも声に出す

この章のまとめ

🖨 まとめシート(印刷・PDF)
  • 要件を確かめてから、画面・データ・通信・端末の工夫の順に話す
  • オフライン・失敗・古い版・電池と通信量まで考える
  • ライブコーディングは考えを声に出し、動くものを先に作る

この章のクイズ

面接ではこう聞かれる

まず答えを見ずに声に出して答え、そのあと開いて比べる。

Q1オフラインでも使えるチャットアプリを設計してください。

模範回答

まず要件として、1対1かグループか、既読や画像の送信が要るか、規模はどれくらいかを確かめます。そのうえで、画面は端末の DB だけを読む形にし、送るメッセージは DB と送信待ちのキューに同じトランザクションで入れて、すぐ「送信中」として表示します。つながったら端末で作った ID を冪等キーにして古い順に送り、二重送信を防ぎます。

受信は、アプリが開いている間は WebSocket、閉じている間はプッシュ通知で知らせ、戻ったときにカーソルで差分を取り直して DB に入れます。並び順はサーバーが付けた順番を正にし、送信に失敗し続けたメッセージは再送のボタンを出します。最後に、届くまでの時間と送信の失敗率をどう計るかも話します。

深掘りされたら

  • メッセージの順番が入れ替わったらどうしますか?
  • 既読はどう同期しますか?

見られているポイント端末の DB を正にした同期・二重送信の防止・開いている間と閉じている間の使い分け

Q2写真のアップロード機能を設計してください。回線が途中で切れることもあります。

模範回答

まず、写真の大きさと枚数、動画も扱うか、アップロード中にアプリを閉じてもよいかを確かめます。写真は送る前に端末で縮めて圧縮し、通信量を減らします。大きなファイルは分割して送る方式か、サーバーが発行する署名付きの URL にストレージへ直接送る方式にし、途中で切れても続きから再開できるようにします。

アプリを閉じても続けたいので、iOS ならバックグラウンドの URLSession、Android なら WorkManager に頼み、送る予定は DB に保存しておきます。進み具合を画面に出し、何度も失敗したら利用者に知らせます。完了の通知はサーバーで処理が終わってから受け取り、同じ写真の二重登録は ID で防ぎます。

深掘りされたら

  • 何枚も同時に選ばれたら、どう順番を決めますか?
  • モバイル回線のときは止めるべきですか?

見られているポイント大きなファイル・中断と再開・裏での実行

Q3ライブコーディングで、すぐに解き方が分からないときはどうしますか?

模範回答

黙り込まずに、まず問題を自分の言葉で言い直して前提を確かめます。そのうえで、効率は悪くても確実に動く素直なやり方を先に書いてよいかを聞き、例を1つ手で動かして考えを声に出します。動くものができたら、計算量や読みやすさの改善を話します。

例えば検索欄の入力ごとに通信する課題なら、まず毎回呼ぶ形を書き、次にデバウンスで呼ぶ回数を減らし、古い結果が後から届いて上書きしないように前の要求を取り消す、と段階的に直します。行き詰まったときに、どこで迷っているかを言えることが評価につながります。

深掘りされたら

  • 時間内に終わらなかったらどうしますか?

見られているポイント考えを声に出す・段階的に良くする

Q4持ち帰りの課題で、どこに時間をかけますか?

模範回答

指定された機能を全部作るより、読みやすい設計とテスト、うまくいかない場面の扱いに時間をかけます。画面・ViewModel・Repository を分け、主要なロジックには単体テストを書き、読み込み中・空・エラーの表示と再試行を入れます。

そして README に、設計の判断とその理由、時間があればやりたかったこと、動かし方を書きます。例えば「オフラインのキャッシュは時間の都合で省いたが、入れるなら Repository で DB を正にする」のように書いておくと、面接での話のきっかけにもなります。

深掘りされたら

  • ライブラリはどこまで使ってよいと考えますか?

見られているポイント限られた時間の優先順位と、判断の説明