面接でバックエンドの設計について聞かれた時どう答えるか?
概要
面談時にバックエンドの知識を問われることが多かったのでメモ。
モバイルアプリが専門でもお構いなし。
面接官の世代はRDBMS全盛期のことが多く、DBの設計の知識を全てエンジニアが持つべきとの考えの方が多い。
以下のような回答をすれば、ある程度知識のある人材とみなされるので便利。
Q.データベース設計において意識していることを教えてください。
A.「データベース設計では、可読性・正規化・拡張性・パフォーマンス・運用性の5点を意識しています。」
- 要件の把握
「まず業務要件を正しく理解し、どんなデータが必要か、どう関連するかを整理します。」
可読性
カラムは単数形のスネークケースで統一し、これは個人的好みですが省略した単語は避けます。
論理値はis_/has_という名目から始めます。
また、時間を表すカラムには_atで終わるように命名したり、数値であれば_countなど一目でデータ型が分かる命名も効果的です。
これらの規則を守ることにより可読性を高めます。
正規化による整合性の担保
「重複を避け、データ整合性を保つために第3正規形を基本に設計します。」
「ただし読み込み頻度の高い画面では、JOIN のコストを考慮して非正規化やキャッシュ戦略も検討します。」
5. パフォーマンス・クエリ頻度の考慮
拡張性と変更耐性
「将来的な要件変更に強くなるよう、安易に固定値を持たず、設定テーブルを分けるなどの工夫をします。」
7. インデックスやユニーク制約の設計
「検索条件に応じたインデックス設計や、一意制約・外部キー制約などで業務ルールを担保します。」
パフォーマンス
AWSであれば、Auroraを使えばある程度のパフォーマンスは最初から担保されます。パフォーマンスの工場は複雑さ、コストと反比例するため要件に合わせて設計します。
インスタンスサイズを増やす、(CPUやメモリリソースが増え、処理速度が向上します)
リーダーインスタンスの活用(Auroraはリードレプリカを複数立てられるため、読み取り処理を分散し高速化出来ます。)
Aurora サーバレス(v2)の利用。スケールイン・アウトが自動で行われるため、アクセス負荷に応じて性能を自動調整出来ます。(トラフィックに波がある場合)
キャッシュの導入(ElastiCache)によりDBアクセスを減らす。ランキング系APIに効果大。
単純だがバックアップを取った上で使われていないデータの削除。論理削除にしようか迷うデータはそもそも削除しない。
運用性
管理しやすく、安全で、障害対応しやすい設計が大事になります。
定期的な自動バックアップの設定や監視・アラート
また、ステージング環境とは別に検証用DBもあれば、より運用しやすいかなと考えています。
マスターDB(書き込み専門)、レプリカDB(読み取り専門)を用意し、プロジェクトごとにレプリカDBを作るのも、障害が発生したときの問題の切り分けが行いやすくおすすめです。
リレーションについて教えてください
中間テーブルの特徴
外部キー(foreign id)を二つ持つ。
主キー(main id)は複合キーにするのが一般的(PRIMARY KEY (user_id, item_id))
必要に応じて登録日などの追加カラム持たせられる
面談では基本的に以上を答えれば問題ない。
第4正規形、第5正規形については知っているが詳しくないでも大丈夫。
命名規則は、テーブルは複数形のスネークケース、カラムは単数形のスネークケースと答えておけば何とかなる。
Q. AWSでどのデータベースを選択しますか?
A. Aurora一択。
ここでMySQL、PostgreSQLと答えると不採用。
AuroraはMySQL, PostgresQLに互換がある。そのため性能的に劣るMySQL, PostgresQLと回答するのは知識がないと言っているようなもの。
なぜAuroraが良いかと聞かれたら、以下比較表の中から
・パフォーマンスが5倍
・高可用性・自動復旧
・通常のインスタンスモードに加え、サーバレスモードもあり柔軟性が高い。
・MySQL, PostgresQLモードがあり、MySQL, PostgresQLと完全な互換。
などと答える。
MySQL/PostgresQLの方が良い場合について聞かれたら、
・Auroraよりもコストが安い
・どうしてもMySQL/PostgresQLが必要
などと答える。
| 項目 | Amazon Aurora | Amazon RDS for MySQL |
|---|---|---|
| パフォーマンス | MySQLの最大5倍、PostgreSQLの最大3倍高速(公式) | Auroraより低速。ただし軽量アプリには十分 |
| 可用性・耐障害性 | マルチAZ、6つのコピー、自動修復、自ー己診断機能あり | マルチAZ可能だが、Auroraほどの冗長性はない |
| スケーラビリティ | リードレプリカ最大15台、Auto Scalingが可能 | リードレプリカ最大5台、スケーリングには時間がかかる |
| 起動時間 | 数秒でインスタンス起動可能 | 起動に時間がかかることがある |
| ストレージ | 自動スケーリング(10GB〜128TB) | 手動で容量指定(最大64TB) |
| 価格 | 高め(約20〜30%上乗せ) | Auroraより安価 |
| 互換性 | MySQL 5.6/5.7/8.0 と互換 | 本家MySQLなので完全互換 |
| メンテナンス性 | フルマネージド、高可用性のため運用負担少 | 運用次第ではAuroraより手間がかかる |
| フェイルオーバー | 30秒未満で自動フェイルオーバー | マルチAZ構成ならフェイルオーバー可(時間は長め) |
アーキテクチャーについて教えて。
[ Controller Layer ] ← プレゼンテーション層(HTTPルーティング)
↓
[ Service Layer ] ← ビジネスロジック層(ユースケースの中心)
↓
[ Repository Layer ] ← データアクセス層(DBや外部APIとのやりとり)
キャッシュについて教えて
キャッシュは計算コストが高い、繰り返しアクセスされるデータを一時的に保存して、高速に応答するための仕組みです。
つまり重い処理を減らし、レスポンスを早くしたい場面で使用したいです。
例えば更新頻度が少なくて良い、商品一覧、ランキング、プロフィール情報。
外部APIのレスポンス(今日の天気)など
例えば以下のサービスを使ってキャッシュを実現します。
ElastiCache for Redis
DBクエリの結果をキャッシュ
最近だとValkey(ヴァルキー)も選択肢に入るようですが、こちらは知見がありません。
CloudFront (エッジキャッシュ)
性的ファイル、APIレスポンスをキャッシュ。
S3、API Gatewayと組み合わせて利用。
API Gatewayキャッシュ
APIレスポンスをキャッシュ。
Lambda/APIのレスポンスをTTL(Time To Live データの有効期限)付きでキャッシュ。
GoでAPIを作るなら?
Gin(一番人気)
特徴:超軽量・高速・ドキュメント豊富
・パフォーマンスが高い(net/http の上位ラッパー)
・ミドルウェアやルーティングが簡単
・ドキュメント・サンプルが豊富
Node.jsでAPIを作るなら?
機能 ライブラリ例
ルーティング nestjs
認証・認可 passport / jsonwebtoken
DB操作 prisma / mongoose / TypeORM
バリデーション express-validator / zod
環境変数管理 dotenv
ログ出力 morgan / winston
CORS対策 cors
NestJSについて聞かれたら?
TypeScriptファーストの設計。型安全なコードが書きやすい。
レイヤードアーキテクチャが標準構成
中小規模であれば問題がなく、何より標準のアーキテクチャのため情報が方法。積極的に採用したい。
Service層が肥大化する問題に関しては、ドメインサービスの分離で対応する。ドメインサービス層は、純粋なロジックのみで構成され、単体テストが行いやすい。
Controller(プレゼンテーション層)
HTTPリクエストの受け付け、レスポンスの返却
↓
Service(ビジネスロジック層)
データの成形、検証、ルール処理など。
↓
Repository(データアクセス層)
DBアクセス専用。ORMやクエリビルダを用いたDB操作に特化
NestJSの @Controller, @Injectable(Service, Repository), @Module(Controller, Service, Repositoryをまとめる。)
@Controller
ルーティング。どのリクエストがどの関数を呼び出すかを決めるところ。
import { Controller, Get, Post, Body, Param } from '@nestjs/common';
@Controller('users') // ルートパス /users に対応
export class UsersController {
@Get() // GET /users
findAll() {
return this.userService.findAll();
@Injectable
// user.service.ts
@Injectable()
export class UserService {
async getUser(id: string) {
return this.userRepository.findById(id);
}
}
// user.repository.ts
@Injectable()
export class UserRepository {
constructor(private readonly prisma: PrismaService) {}
async findById(id: string) {
return this.prisma.user.findUnique({ where: { id } });
}
}
DDDについて教えて
ドメイン駆動設計(Domain-Driven Design)は以下三つの概念を基に構築されている。
- ドメインモデルの構築:
ソフトウェアが扱う問題領域(ドメイン)を理解し、それをモデル化します。このモデルは、ビジネスルールや概念を表現し、開発者とビジネス関係者間の共通言語として機能します。 - ユビキタス言語の活用:
ドメインモデルを基に、開発チームとビジネス関係者が共通の言葉(ユビキタス言語)でコミュニケーションを取り、認識のずれをなくします。 - コードとドメインの緊密な連携:
ドメインモデルをコードに反映させ、ビジネスロジックをドメインモデルに集約することで、システム全体の整合性を高めます。
具体的にはユビキタス言語をスプレッドシートで管理します。
このユビキタス言語を関数名、変数名に使用することでとても
また、開発の会議であっても専門家に同席してもらい、専門用語を用いて業務ロジックへの理解を深めながら開発を行います。
DDDは、複雑なビジネスロジックを持つシステム開発において、特に有効な設計手法とされています。
DDDのメリット:
ビジネス要件への適合:
ドメインモデルを基に開発を進めるため、ビジネス要件に合致したシステムを構築できます。
保守性の向上:
ドメインモデルが明確になり、ビジネスロジックがコードに反映されるため、システムの保守性が向上します。
開発効率の向上:
共通言語を用いることで、開発チームとビジネス関係者間のコミュニケーションがスムーズになり、開発効率が向上します。
その他
以下などが良く聞かれる。
基本言語によらないバックエンドの知識を問われるため、Docker, データベース、インフラ周りの質問が多い。
・Fargateはサーバレスですか?
・Dockerの基本的な概念について説明してください。
・TCPとUDPの違いについて説明して下さい。
TCP = HTTP/HTTPS, SMTP(メール転送), FTP(ファイル転送)
接続指向: 通信前に接続を確立(3-way handshake)
信頼性: データの到達保証、順序保証、重複排除
フロー制御: 受信側の処理能力に合わせて送信速度を調整
エラー検出・修正: 失われたパケットを再送信
UDP = 動画ストリーミング、オンラインゲーム、DNSクエリ
コネクションレス: 接続確立なしで即座にデータ送信
高速: TCPより軽量でオーバーヘッドが少ない
信頼性なし: データ到達保証なし、順序保証なし
リアルタイム性: 遅延が少ない
・キャッシュについて解説してください。また、XXXの構成でどのようにキャッシュを入れますか?
AWSには以下のようなキャッシュがあります。
| キャッシュ | Amazon ElastiCache(Redis or Memcached) | Redisのマネージド版。完全互換でAWSが運用管理を肩代わり。 |
| | Amazon DAX(DynamoDB Accelerator) | DynamoDB専用の高速キャッシュ。Redisより簡単で高速なケースもある。 |
|
・プライベートサブネットとパブリックサブネットの違いについて説明してください。
プライベートサブネット = 公開されていない DB, 内部API、バックエンドなど
パブリックサブネット = 公開されている、Webサーバーなど
ec2など
意外と言語化しにくい質問なので注意
IGWとは?
Internate Gatewayの略
・VPNとは何の略ですか?
Virtual Private Network
・AuroraのWriterインスタンス、Readerインスタンスについて説明してください。
RDS(特に Aurora)では、データベースの構成が以下のような単位で管理されています:
✅ クラスター(Cluster)
Aurora 専用の概念。
データベースの「論理的なまとまり」であり、ストレージ層を共有します。
クラスターには複数の DB インスタンス(ノード)を含めることができます。
リージョンごとにクラスターを配置可能で、グローバルデータベース構成もできます。
✅ ライターインスタンス(Writer Instance)
クラスター内のインスタンスのうち、書き込みが可能な唯一のインスタンス。
他のインスタンス(リーダー)はリードレプリカとして読み込み専用。
クラスターのフェイルオーバー時には、リーダーがライターに昇格することも可能。
図解(イメージ)
nginx
コードをコピーする
Aurora クラスター(例: ap-northeast-1)
├── Writer Instance(書き込み可)
└── Reader Instance(読み込み専用)
グローバルクラスター構成の場合:
scss
コードをコピーする
グローバルクラスター
├── クラスター (ap-northeast-1)
│ └── Writer
└── クラスター (us-west-2)
└── Reader
用途の違い
種別 用途
クラスター データベースのストレージと全体の論理構成
Writer インスタンス 書き込み処理を担当する DB ノード
Reader インスタンス 負荷分散やリードレプリカ(読み取り専用)
必要であれば、RDS コンソールの表示や設計例も説明可能です。
Discussion