実務で着手する順に構成。
すべての土台。クラウド環境の問題も、実態はLinuxレベルの問題であることが多い。
- 操作:ファイルシステムのナビゲーション / パーミッション管理(chmod / chown) / ポート管理(lsof / ss) / 環境変数
- プロセス管理:ps / kill / バックグラウンド実行(nohup / &) / ゾンビプロセスの検出と対処
- サービス管理:systemdによるサービスの起動・停止・自動再起動設定(systemctl enable / start / status)
- リソース監視:
- CPU:top / htop / mpstat
- メモリ:free / vmstat
- ディスク:df / du / iostat
- ネットワーク:iftop / nethogs
- ログ調査:grep / tail -f / less / journalctl / awk によるフィルタリングと集計
- 自動化:シェルスクリプト / cron による定期実行 / xargs によるバッチ処理
- パッケージ管理:apt(Debian系) / yum・dnf(RHEL系)
本番環境の障害の多くは、名前解決・接続・ルーティング・ハンドシェイクのいずれかの失敗に起因する。
- プロトコル:
- TCP:コネクション指向、信頼性あり。ほとんどのWeb通信の基盤
- UDP:コネクションレス、低レイテンシ。DNS問い合わせ、動画ストリーミング、リアルタイム通信向き
- HTTP/1.1:テキストベース、keep-alive対応
- HTTP/2:バイナリフレーム、多重化、ヘッダー圧縮。gRPCの基盤
- HTTP/3(QUIC):UDPベース、接続確立の高速化
- TLS:暗号化通信。HTTPS = HTTP + TLS
- WebSocket:双方向リアルタイム通信(チャット、通知、ライブ更新)
- 名前解決:
- DNS:ドメイン名 → IPアドレスの変換
- 主要レコード:A(IPv4) / AAAA(IPv6) / CNAME(エイリアス) / MX(メール) / TXT(検証用)
- TTL:キャッシュ有効期間。短すぎると負荷増、長すぎると切り替え遅延
- 通信制御:
- ロードバランサー:L4(TCP/UDPレベル、高速) vs L7(HTTPレベル、パスベースルーティング可能)
- リバースプロキシ:Nginx / HAProxy。SSL終端、キャッシュ、リクエスト振り分け
- CDN:静的コンテンツのエッジ配信。レイテンシ削減とオリジンサーバーの負荷軽減
- ファイアウォール / セキュリティグループ:ポート・IP単位のアクセス制御
- NAT:プライベートIPからの外部通信を可能にする
- デバッグツール:
- ping:疎通確認
- traceroute:経路追跡
- curl:HTTPリクエストの手動テスト
- dig / nslookup:DNS解決の確認
- ss / netstat:ポート・接続状態の確認
- tcpdump / Wireshark:パケットキャプチャ
バックエンドの問題の多くはデータベース設計の問題に帰着する。本番障害が起きる前に、データ設計の破綻点を把握しておく。
| 判断軸 | RDBMS(PostgreSQL / MySQL) | NoSQL |
|---|---|---|
| データ構造 | 明確なスキーマ、リレーション多い | スキーマレス、ネスト構造、非定型 |
| 整合性要件 | トランザクション必須(決済、在庫等) | 結果整合性で許容できる |
| アクセスパターン | 複雑な結合クエリが多い | キーによる単純な読み書きが中心 |
| スケール方向 | 垂直スケール中心(水平は複雑) | 水平スケールが容易 |
- NoSQL分類と用途:
- ドキュメントDB(MongoDB / DynamoDB):柔軟なスキーマ、アプリケーション単位のデータ
- KVS(Redis / DynamoDB):セッション、キャッシュ、カウンター
- カラム指向(Cassandra / HBase):時系列データ、大量書き込み
- グラフDB(Neo4j):関係性が主要なクエリ対象(SNS、推薦)
- トランザクション(ACID):Atomicity(原子性) / Consistency(一貫性) / Isolation(分離性) / Durability(永続性)
- インデックス設計:
- B-Treeインデックス:範囲検索・ソートに有効
- 複合インデックス:カラム順序がクエリパターンと一致する必要がある(左端一致の原則)
- カバリングインデックス:インデックスだけでクエリを完結させ、テーブルアクセスを回避
- 過剰なインデックスは書き込み性能を劣化させる
- 正規化と非正規化:正規化でデータ整合性を保ち、読み取り性能が要件を満たさない場合に非正規化を検討する
- スロークエリの検出:slow query log / EXPLAIN / EXPLAIN ANALYZE でクエリの実行計画を確認する
- N+1問題:ループ内で個別クエリを発行する代わりに、JOINまたはIN句でまとめて取得する
- コネクションプーリング:PgBouncer / HikariCP等。DB接続の生成コストを抑える。プールサイズはCPUコア数 × 2 + ディスク数が目安
- デッドロック:複数トランザクションが互いのロックを待つ状態。テーブル・行のロック順序を統一して防ぐ
- リードレプリカ:読み取り負荷の分散。書き込みはプライマリに集中。レプリカラグに注意
- パーティショニング:
- 水平(シャーディング):行を分割。シャードキーの選定が偏りを決める
- 垂直:カラム群を別テーブルに分割。アクセスパターンが異なるカラムの分離
- 一貫性のトレードオフ:強い一貫性(レイテンシ増)vs 結果整合性(一時的に古いデータを許容)
- マイグレーション:スキーマ変更はバージョン管理する。大規模テーブルの ALTER はロック時間に注意。オンラインDDLツール(gh-ost / pt-online-schema-change)の利用を検討
- バックアップ戦略:論理バックアップ(pg_dump等)と物理バックアップ(WALアーカイブ等)の使い分け。リストア手順の定期テスト
初回リリース時だけでなく、多様なクライアントからの利用に長期的に耐えるAPIを設計する。
| 判断軸 | REST | gRPC | GraphQL |
|---|---|---|---|
| 通信形式 | JSON over HTTP | Protocol Buffers over HTTP/2 | JSON over HTTP |
| 適するケース | 外部公開API、CRUD中心 | 内部マイクロサービス間通信、低レイテンシ要件 | フロントエンド主導の柔軟なデータ取得 |
| スキーマ定義 | OpenAPI(任意) | .protoファイル(必須) | SDL(必須) |
| ストリーミング | 非対応(SSE / WebSocketで補完) | 双方向ストリーミング対応 | Subscription(実装依存) |
| 学習コスト | 低い | 中〜高 | 中〜高 |
| 弱点 | オーバーフェッチ / アンダーフェッチ | ブラウザ直接呼び出し困難 | キャッシュ戦略が複雑、N+1問題 |
- 冪等性(idempotency):同じリクエストを複数回送信しても結果が変わらないこと。POST等の非冪等メソッドには冪等性キーを導入する
- ページネーション:
- offset / limit:実装が単純。大量データではoffsetが深くなるほど性能劣化
- cursor-based:最後に取得した要素のIDを基準に次ページを取得。大規模データに適する
- バージョニング:
- URLパス(/v1/users):シンプルで明示的。主流
- ヘッダー(Accept: application/vnd.api.v1+json):URLが汚れない。運用がやや複雑
- 破壊的変更時のみバージョンを上げる。非破壊的変更(フィールド追加)ではバージョンを維持
- レートリミティング:Token bucket / Sliding window方式。429 Too Many Requestsで返却。Retry-Afterヘッダーで再試行タイミングを通知
- エラーハンドリング:
- HTTPステータスコード:4xx(クライアント起因) / 5xx(サーバー起因)を正しく使い分ける
- エラーレスポンス:コード・メッセージ・詳細を統一フォーマットで返却する
- 内部エラーの詳細をクライアントに露出しない
- 認証・認可:
- OAuth 2.0:外部サービス連携、委譲認可
- JWT:ステートレスなトークン認証。署名検証のみでセッションストア不要。トークンの有効期限とリフレッシュ戦略を設計する
- APIキー:サーバー間通信やサービス識別用。ユーザー認証には不十分
- API Gateway:認証・レートリミティング・ログ・ルーティングなどの横断的関心事を集約
独立した専門領域だが、バックエンドエンジニアとしての基本防御ラインは設計初期から組み込む。後付けのセキュリティ対策はコストが高い。
- 入力:
- すべての外部入力をバリデーション(ホワイトリスト方式が原則)
- SQLインジェクション → プリペアドステートメントで防ぐ
- コマンドインジェクション → 外部入力をシェルコマンドに渡さない
- Web:
- XSS:出力時のエスケープ / Content-Security-Policyヘッダー
- CSRF:CSRFトークン / SameSite Cookie属性
- CORS:許可オリジンを明示的に指定。ワイルドカード(*)は原則避ける
- データ保護:
- in transit:TLSで暗号化(HTTPS必須)
- at rest:ディスク暗号化 / カラムレベル暗号化(クレジットカード番号等)
- シークレット管理:ソースコードにハードコードしない。Vault / AWS Secrets Manager / 環境変数を使用。ローテーション戦略を設ける
- パスワード保存:bcrypt / Argon2 によるハッシュ化。平文保存・MD5・SHA単体は不可
- 原則:
- 最小権限の原則:必要最小限のアクセス権のみ付与
- 多層防御:単一の防御に依存せず、複数レイヤーで守る
- 依存関係管理:既知の脆弱性を持つライブラリの検出(Dependabot / Snyk / Trivy)
パフォーマンス最適化の主要手段。導入効果が大きい反面、整合性の問題を生みやすい。
| 判断軸 | Redis | Memcached |
|---|---|---|
| データ構造 | 文字列・リスト・セット・ハッシュ・Sorted Set等 | 文字列のみ |
| 永続化 | RDB / AOFで永続化可能 | なし(純粋なキャッシュ) |
| 用途 | キャッシュ + セッション + キュー + ランキング等 | 単純なキャッシュに特化 |
| スケーリング | Redis Cluster(シャーディング) | クライアント側シャーディング |
- cache-aside(Lazy Loading):アプリがキャッシュを確認 → ミス時にDBから取得してキャッシュに書く。最も一般的。読み取り頻度が高く、更新頻度が低いデータに適する
- write-through:書き込み時にキャッシュとDBを同時更新。データの鮮度が高いがレイテンシ増
- write-behind(write-back):キャッシュに書き、非同期でDBに反映。書き込み性能は高いがデータ損失リスクあり
- read-through:キャッシュ自体がDBからのデータ取得を担当。アプリ側のロジックが簡潔になる
- TTL戦略:データの更新頻度に応じて設定。全キーで同一TTLを避ける(一斉失効による負荷集中を防ぐため、ジッターを加える)
- キャッシュインバリデーション:データ更新時にキャッシュを削除または更新する。「いつ無効化するか」は設計段階で決めておく
- ホットキー対策:特定キーにアクセスが集中する場合、ローカルキャッシュの併用 / キーの分散(キーにサフィックスを付けて複数に分散)
- stale data:古いデータの残存。ビジネスロジックで許容範囲を定義する
- thundering herd:キャッシュ失効時に大量リクエストがDBに集中。ロック取得による1リクエストだけの再取得(cache stampede対策)で防ぐ
- cache penetration:存在しないキーへの繰り返しアクセス。空の結果もキャッシュする / Bloom Filterで存在チェック
- cache avalanche:大量のキーが同時に失効。TTLにランダムなジッターを加えて分散
同期処理では対応できないスループット要件や、サービス間の疎結合化に必要な領域。
| 判断軸 | Kafka | RabbitMQ | SQS |
|---|---|---|---|
| モデル | 分散ログ(Pub/Sub) | メッセージブローカー(キュー / Pub/Sub) | マネージドキュー |
| 順序保証 | パーティション内で保証 | キュー内で保証 | FIFOキューで保証(標準キューは不保証) |
| スループット | 非常に高い | 中程度 | 中程度 |
| 適するケース | イベントストリーム、ログ集約、大量データパイプライン | タスクキュー、リクエスト/リプライ、ルーティングが複雑なケース | AWSネイティブ、マネージドで運用負荷を下げたい |
| メッセージ保持 | 設定期間保持(消費後も残る) | 消費後に削除 | 消費後に削除 |
| 運用負荷 | 高い(ZooKeeper / KRaft、ブローカー管理) | 中程度 | 低い(フルマネージド) |
- 配信保証:
- at-most-once:メッセージ損失あり得る。ログ等の損失許容ケース
- at-least-once:重複あり得る。コンシューマー側で冪等処理を実装する(最も一般的)
- exactly-once:Kafkaのトランザクション機能等で実現可能だが、性能コストが高い
- dead letter queue(DLQ):処理失敗メッセージの退避先。リトライ上限超過時に移送し、後から調査・再処理する
- バックプレッシャー:コンシューマーの処理速度を超える流入を制御する仕組み。流量制限 / バッファリング / プルベースの消費
- 順序保証が必要な場合:パーティションキー / メッセージグルーピングで同一エンティティのイベントを同一パーティションに集約する
- 冪等なコンシューマー:メッセージIDによる重複排除 / 処理済みIDの記録 / DB操作のUPSERT化
アプリケーションがコンテナ内でどのように実行され、どのように失敗するかを理解する。
- Dockerfile設計:
- マルチステージビルド:ビルド環境と実行環境を分離し、最終イメージサイズを削減
- レイヤーキャッシュ:変更頻度の低い命令(依存インストール)を先に、変更頻度の高い命令(ソースコピー)を後に配置
- .dockerignore:不要ファイルをビルドコンテキストから除外
- イメージ管理:コンテナレジストリ(ECR / GCR / Docker Hub)でバージョン管理。タグにlatestを本番で使わない(再現性が失われる)
- セキュリティ:rootユーザーで実行しない。Trivy等でイメージの脆弱性スキャン
- 基本リソース:
- Pod:最小デプロイ単位。1Pod = 1アプリコンテナが基本
- Deployment:Podのレプリカ数管理、ローリングアップデート
- Service:Pod群への安定したネットワークエンドポイント(ClusterIP / NodePort / LoadBalancer)
- ConfigMap / Secret:設定値と機密情報の外部化
- Namespace:環境やチーム単位のリソース分離
- PersistentVolume / PersistentVolumeClaim:ステートフルなデータの永続化
- ヘルスチェック:
- liveness probe:失敗時にPodを再起動。デッドロック検出等
- readiness probe:失敗時にServiceからの振り分けを停止。起動完了前のリクエスト流入を防ぐ
- startup probe:起動に時間がかかるアプリケーション用。起動完了までliveness probeを遅延
- リソース管理:
- requests(最低保証)/ limits(上限)でCPU・メモリを設定。未設定だとノード全体に影響するリスク
- HPA(Horizontal Pod Autoscaler):CPU/メモリ使用率やカスタムメトリクスに基づく自動スケール
- 管理ツール:Helm(Kubernetesパッケージ管理、テンプレートによるマニフェスト生成)
- ネットワーク:Pod間通信 / Ingress(外部トラフィックのルーティング) / サービスメッシュ(Istio / Linkerd:トラフィック制御、mTLS、可観測性)
コミットから本番環境まで、コードを安全に届けるパイプラインを構築・運用する。
- ソース:コードプッシュ / PR作成をトリガーに起動
- ビルド:コンパイル / コンテナイメージのビルド
- テスト:ユニットテスト → 統合テスト → E2Eテスト(ピラミッド型に量を調整)
- 静的解析:リンター / セキュリティスキャン(SAST) / 依存関係の脆弱性チェック
- アーティファクト管理:ビルド成果物をレジストリに保存(タグ = コミットハッシュ等で一意に識別)
- 環境プロモーション:dev → staging → production の段階的デプロイ。各段階で承認ゲートを設ける
| 戦略 | 仕組み | 適するケース | リスク |
|---|---|---|---|
| blue-green | 新旧2環境を用意し、切り替え | ダウンタイムゼロが必要 | インフラコスト2倍 |
| カナリア | 一部トラフィックだけ新バージョンに流す | 段階的な検証が必要 | ルーティング設定の複雑さ |
| ローリング | Podを順次入れ替え | K8s標準、多くのケースで十分 | 新旧バージョンが一時的に混在 |
| フィーチャーフラグ | コード内でフラグにより機能を切り替え | デプロイとリリースを分離したい | フラグの管理負債化 |
- ロールバック:問題発生時に前バージョンに即時切り戻す手順を事前に準備・テストしておく。DBマイグレーションの前方互換性を担保しておかないとロールバックが困難になる
- 統合テスト:外部依存(DB / API)を含めたテスト。Testcontainers等でローカルに依存を再現
- 負荷テスト:k6 / Locust / JMeter。本番と同等のデータ量・トラフィックパターンで実施。ピーク時の2〜3倍を目安にする
AWS・GCP・Azureでサービス名は異なるが、基本的な構成要素は共通している。
- VPC:仮想プライベートネットワーク。サービスを論理的に隔離
- サブネット:パブリック(インターネット接続あり) / プライベート(内部通信のみ)に分離
- セキュリティグループ / NACL:インバウンド・アウトバウンドのトラフィック制御
- CDN(CloudFront / Cloud CDN):エッジでの静的コンテンツ配信
- IAM:ユーザー・ロール・ポリシーによるアクセス制御。サービス間通信にはロールベースのアクセスを使用し、長期アクセスキーを避ける
| 選択肢 | 適するケース | トレードオフ |
|---|---|---|
| VM(EC2 / GCE) | フルコントロールが必要、レガシーアプリ | 運用負荷が高い |
| コンテナ(ECS / EKS / Cloud Run) | マイクロサービス、ポータビリティ重視 | オーケストレーションの学習コスト |
| サーバーレス(Lambda / Cloud Functions) | イベント駆動、低頻度・短時間の処理 | コールドスタート、実行時間制限 |
| 選択肢 | 適するケース |
|---|---|
| オブジェクトストレージ(S3 / GCS) | 画像・動画・バックアップ・静的ファイル |
| ブロックストレージ(EBS / Persistent Disk) | VM / コンテナにマウントするディスク |
| ファイルストレージ(EFS / Filestore) | 複数インスタンスからの共有アクセス |
- リージョン / アベイラビリティゾーン:リージョン = 地理的領域、AZ = リージョン内の独立したデータセンター群。マルチAZ構成で単一AZ障害に耐える
- マルチリージョン構成:災害対策(DR) / グローバルユーザーへの低レイテンシ提供。データの同期方式と一貫性モデルの設計が必要
- リザーブドインスタンス / Savings Plans:長期利用のコミットメントで割引(1年 / 3年)
- スポットインスタンス:中断許容のバッチ処理向き。最大90%割引
- Right Sizing:実使用量に基づいてインスタンスサイズを最適化
- 予算アラート:想定外のコスト発生を早期検知
インフラをレビュー可能・再現可能にし、手動操作や個人の記憶に依存しない状態を維持する。
| ツール | 言語 | 特徴 |
|---|---|---|
| Terraform | HCL | クラウド非依存、最大のエコシステム、宣言的 |
| Pulumi | TypeScript / Python / Go等 | 汎用言語でインフラを記述、テストが書きやすい |
| AWS CDK | TypeScript / Python等 | AWS特化、CloudFormationを生成 |
| Ansible | YAML | 構成管理寄り、エージェントレス、手続き的 |
- 状態管理(state):Terraformの場合、リモートバックエンド(S3 + DynamoDBロック等)で状態ファイルを管理。ローカルのstateファイルはチーム開発で競合する
- モジュール化:再利用可能な単位に分割(ネットワーク / コンピュート / DB等)。環境ごとの差異は変数で吸収
- ドリフト検出:手動変更によるコードと実態の乖離を定期的に検出し、コード側に反映する
- 変更の安全性:plan → レビュー → apply の手順を徹底。破壊的変更(replace / destroy)は事前に確認
- GitOps:Gitリポジトリをインフラの唯一の真実源(single source of truth)とし、PRベースで変更を管理する
- Policy as Code:OPA(Open Policy Agent) / HashiCorp Sentinelで、インフラ構成のルール(タグ必須、パブリックアクセス禁止等)を自動検証
- 機密情報:Terraformのstateにシークレットが平文で保存される問題に注意。Vault統合やsopsによる暗号化を検討
負荷下での実システムの挙動を推論できる能力が求められる。
- 基本構成:ロードバランシング / シャーディング / リーダー・フォロワーレプリケーション / サービスディスカバリ
- CAP定理:Consistency(一貫性) / Availability(可用性) / Partition tolerance(分断耐性)のうち、ネットワーク分断時にCとAの両立はできない。実際の設計ではCとAのバランスをユースケースごとに調整する
- 結果整合性(eventual consistency):書き込み直後は古いデータを返す可能性があるが、最終的に全ノードが一致する。書き込み後に即時読み取りが必要なケースでは read-your-writes一貫性を個別に担保する
- 耐障害パターン:
- サーキットブレーカー:下流サービスの障害を検知し、一定期間リクエストを遮断して連鎖障害を防ぐ(Closed → Open → Half-Open の3状態遷移)
- バルクヘッド:リソースを分離し、一部の障害が全体に波及するのを防ぐ(スレッドプール分離、コネクションプール分離)
- タイムアウト設計:すべての外部呼び出しにタイムアウトを設定する。タイムアウトなしはリソースリークの原因になる
- リトライ:exponential backoff + jitter。リトライ回数の上限設定。リトライストームに注意
- 分散トランザクション:
- Sagaパターン:各サービスがローカルトランザクションを実行し、失敗時に補償トランザクションで打ち消す。コレオグラフィ方式(イベント駆動)とオーケストレーション方式(中央制御)がある
- 2PC(Two-Phase Commit):強い一貫性を保証するが、コーディネーターが単一障害点になる。レイテンシも大きい
パターン名の知識ではなく、特定の状況においてある設計が優れている理由・劣っている理由を説明できることが重要。
| 判断軸 | モノリス | マイクロサービス |
|---|---|---|
| 適する段階 | 初期〜中規模。チームが小さい | 大規模。チーム間の独立デプロイが必要 |
| デプロイ | 全体を一括デプロイ | サービス単位で独立デプロイ |
| データ管理 | 単一DB | サービスごとにDB分離が原則 |
| 複雑性の所在 | コードベース内部 | インフラ・ネットワーク・運用 |
| 最初の選択肢 | チームが小さく、ドメイン境界が不明確なうちはモノリスで始め、必要になった時点で分割する |
- 一貫性 vs 可用性:決済・在庫は一貫性優先。SNSフィード・レコメンドは可用性優先
- パフォーマンス vs コスト:キャッシュ・CDN・リードレプリカで性能を向上できるが、各層の運用コストが加算される
- シンプルさ vs 柔軟性:抽象化レイヤーを増やすと柔軟性は上がるが、デバッグ難度も上がる。YAGNI原則(今必要でないものは作らない)
- CQRS(Command Query Responsibility Segregation):書き込みモデルと読み取りモデルを分離。読み取り性能の個別最適化が可能。導入の判断基準は、読み取りと書き込みのスケール要件やデータモデルが大きく異なるかどうか
- イベントソーシング:状態の変更をイベントの列として保存。任意の時点の状態を再構築可能。監査要件がある領域(金融・決済)に適する。イベントスキーマのバージョニングが運用上の課題になる
構築した成果物だけでなく、劣化の兆候の検知・障害原因の特定・悪化させない復旧ができるかが評価対象となる。
| 柱 | 役割 | ツール例 |
|---|---|---|
| ログ | 個別イベントの記録。what happened | 構造化ログ(JSON形式) / Elasticsearch + Kibana / CloudWatch Logs / Loki |
| メトリクス | 数値の時系列データ。集約・傾向把握 | Prometheus + Grafana / Datadog / CloudWatch Metrics |
| トレース | リクエストのサービス横断的な追跡。where is the bottleneck | OpenTelemetry / Jaeger / Datadog APM / X-Ray |
- 構造化ログ:key-value形式で出力し、検索・集計を容易にする。timestamp / request_id / user_id / severity / message を最低限含める
- 分散トレーシング:リクエストにtrace IDを付与し、サービス間で伝播させる。レイテンシのボトルネック特定に必須
- SLI(Service Level Indicator):サービス品質の計測指標。例:リクエスト成功率、p99レイテンシ
- SLO(Service Level Objective):SLIの目標値。例:月間可用性99.9%、p99レイテンシ 200ms以下
- エラーバジェット:SLO達成に許容される障害量。残りが少ない → リリース速度を落として安定性に注力
- アラート設計:
- SLOベースのアラート:症状(ユーザー影響)に基づく通知。原因ベース(CPU使用率等)より誤報が少ない
- アラート疲れを避ける:対応不要なアラートは削除する。すべてのアラートにランブック(対応手順書)を紐付ける
- ダッシュボード:RED(Rate / Error / Duration)メソッド、またはUSE(Utilization / Saturation / Errors)メソッドで構成
- インシデント対応:検知 → トリアージ → 緩和 → 根本原因分析(RCA) → 再発防止策。ポストモーテムは非難なし(blameless)で実施する
- データをモデリングする
- APIを設計する
- 障害に対処する
- ボトルネックをスケールさせる
- システムを観測する
- アーキテクチャを簡素化する
- 繰り返す