1. 5 nodes, v2 has 3 votes (majority)
  2. 3 different values, no majority
  3. 1 vote out of 3 is not majority
  4. all same value
  5. tie 2-2 in 4 nodes returns empty
  6. 5 nodes, 3 of same value with 2 down
コース一覧
コンピューターサイエンス入門:理論編
CAP の availability 模擬

コンピューターサイエンス入門:理論編

2 進数、論理演算、ビット演算、データ構造、計算量、メモリモデルなど、プログラミングの土台となるコンピュータサイエンスの理論知識を学べるコースです。プログラミングを始めたばかりの学習者や、CS の体系的な土台を作りたい現役エンジニアを対象としています。約 13 時間 (1 日 30 分 × 26 日) で 53 レッスンを修了でき、修了後はコードのパフォーマンスや設計判断の根拠を理解した上で実装できるようになります。

1
2進数とビット演算
01. 2進数から10進数への変換5分
02. 10進数から2進数への変換5分
03. ビットAND演算でフラグ判定5分
04. OR / XOR でフラグを操作する5分
05. popcount で 1 のビット数を数える5分
06. シフト演算で 2 倍 / 半分5分
07. 16 進数から 10 進数への変換5分
08. 第 1 章まとめクイズ5分
2
文字コードと真偽値ロジック
01. 文字 → ASCII コード5分
02. コード → 文字5分
03. UTF-8 のバイト長を返す5分
04. AND / OR の真理値表5分
05. NOT / XOR の真理値表5分
06. 含意 (→) を AND/OR/NOT で表現5分
07. ド・モルガンの法則5分
08. 第2章まとめクイズ5分
3
計算量とBig-O
01. forループの実行回数を返す5分
02. 入れ子ループの実行回数5分
03. 線形探索 (O(n))5分
04. 二分探索 (O(log n))5分
05. バブルソート5分
06. 配列の最大と最小5分
07. 累積和で範囲合計5分
08. 第3章まとめクイズ5分
4
データ構造 (基本)
01. スタック (push/pop) を実装する5分
02. キュー (enqueue / dequeue) を実装する5分
03. カッコのバランス判定 (スタック応用)5分
04. set で重複を除去する5分
05. map で出現回数を数える5分
06. 二数の和 (map で O(n))5分
07. アナグラム判定5分
08. 第 4 章クイズ — データ構造 (基本)5分
5
ファイル / メモリ / IO 概念
01. バイト → KB 変換5分
02. ディスクサイズフォーマット5分
03. キャッシュヒット率5分
04. LRU 簡易シミュレーション5分
05. エンディアンの入れ替え (uint32)5分
06. バッファ範囲チェック5分
07. 第5章まとめクイズ5分
6
ネットワークと符号化
01. Base64 エンコード後の長さ計算5分
02. URL エンコード対象文字数5分
03. IPv4 アドレスを 32bit 整数に変換5分
04. 32bit 整数を IPv4 アドレスに変換5分
05. CIDR プレフィックスからネットマスクを作る5分
06. 単純チェックサム5分
07. 第6章まとめクイズ5分
7
設計と DB 基礎
01. 重複データを 1NF に変換 (フラットなリスト化)5分
02. キーで join (map 利用)5分
03. 残高転送のトランザクション風処理5分
04. CAP の availability 模擬5分
05. URL ルーティング5分
06. 疎結合と密結合 — 依存性注入で設計を変える12分
07. コース総まとめクイズ5分

CAP の availability 模擬

通信が切れた瞬間、どちらかを諦めることになる

同じデータを 3 台のサーバーに置いて、1 台が壊れても続けられるようにしておきます。ここまでは誰も反対しません。厄介なのは、サーバーが壊れるのではなく、サーバー同士をつなぐ回線が切れるときです。

東京の 2 台と大阪の 1 台がつながらなくなったとします。東京側で値を v2 に更新しても、大阪には届きません。

Python

tokyo1 = "v2" tokyo2 = "v2" osaka = "v1" # 分断中で、更新が届かなかった

この状態で、大阪のサーバーに読みに来た人がいます。返せるものは 2 つしかありません。

  • 手元にある v1 を返す。応答は返るが、その値は古い
  • 「今は答えられない」とエラーを返す。古い値は出さないが、そのユーザーにとってサービスは止まっている

どちらを選んでも何かを失います。前者は正しさ(Consistency)を、後者は答えを返し続けること(Availability)を諦めています。回線が切れている間は、両方は取れません。CAP 定理が言っているのはこれで、覚えるべきは 3 文字の名前ではなく、この二択が必ず来るという事実のほうです。

解説

現場の話 — 銀行の残高は後者を選びます。古い残高を見せるくらいならエラー画面を出して止めます。SNS のいいね数は前者です。少し古い数字が見えても誰も困らないので、止めるほうが損だと判断されています。いいね数が一瞬戻って見えるのは、この設計の副作用です。

何台が同じことを言えば信じるか

答えを返すほうを選んだシステムでも、たまたま聞いた 1 台の言い分をそのまま信じるわけではありません。全台に聞きに行って、過半数が同じ値を答えたらそれを採用します。多数決なので quorum read と呼ばれます。

5 台のうち 3 台が v2、1 台が v1、1 台は落ちていて答えない、という状況なら v2 を採ります。1 台落ちていても答えが出せるので、止まらずに済みます。

ここでの過半数は「半分」ではなく「半分より多い」です。台数ごとに書くと次のようになります。

  • 3 台なら 2 票
  • 4 台なら 3 票
  • 5 台なら 3 票

台数を 2 で割って切り捨て、1 を足すとこの数が出ます。半分ちょうどで合意にしてしまうと、4 台が 2 票と 2 票に割れたときに両方とも合意扱いになり、どちらを返すかがその場の順番で決まってしまいます。

割れたときは、答えないという答えを返す

a が 2 票、b が 2 票。どちらも過半数に届いていません。ここで無理に多いほうを選ぶと、たまたま同点だった値を「全員が合意した値」として配ることになります。届かなかったのなら、合意なしとして返すのが正しい振る舞いです。

課題では、答えないノードを空文字で表します。票の集計には入れません。ただし、過半数を計算するときの台数は、落ちている台も含めた全体のままにします。落ちている台が増えるほど合意が成立しにくくなる、という関係をそのまま再現するためです。

Python

replicas = ["v2", "v2", "", "v1", "v2"] # 答えたのは 4 台。過半数は 4 ではなく 5 から計算する

やってみよう

quorumRead(replicas) を完成させてください。

  1. 空文字は集計から外す。過半数の計算に使う台数は replicas の長さのまま
  2. 残った値ごとに票数を数える
  3. 過半数に届いた値があればそれを返す。無ければ空文字を返す

票を数える部分は、第 4 章でやった出現回数の数え上げと同じ形です。新しく覚えることはありません。

要件

  1. 空文字(dead node)は集計から除外する
  2. 過半数は len // 2 + 1 で計算する
  3. 過半数を取った値があれば返し、なければ空文字を返す

入出力例

quorumRead(["v2","v2","v1","v2",""]) → "v2" quorumRead(["v1","v2","v3"]) → "" quorumRead(["v1","",""]) → "" quorumRead(["v1","v1","v1"]) → "v1" quorumRead(["a","a","b","b"]) → "" quorumRead(["x","x","x","",""]) → "x"

ヒント

辞書(dict / Object)で値の出現回数を集計するのが基本

Python なら `collections.Counter` も使えるが、`dict` + `get` で十分

閾値を `len // 2` にすると半分丁度でも合意になってしまうので注意。`+ 1` が必要

生田 陸人
監修生田 陸人
ゆめさくエンジニア / 現役ソフトウェアエンジニア監修者プロフィールを見る →
編集 ゆめさく編集部·公開 2026/05/19·更新 2026/08/26

関連レッスン

  • URL ルーティング

    URL パスを `Controller#action` の文字列に振り分けるルーティングを実装し、MVC の「Controller の入口」を体感します。

  • 疎結合と密結合 — 依存性注入で設計を変える

    疎結合と密結合の違いを比喩・図・コードで理解する。依存性注入(DI)で結合度を下げると、テスト容易性と変更耐性が同時に上がる。

  • コース総まとめクイズ

    cs-theory コース全 7 章の応用問題。2 進数からビット演算、計算量、データ構造、ネットワーク、DB 設計まで横断的に振り返ります。

このレッスンに出てくる用語

意味があいまいなまま進んだ語は、ここから読み直せます。

  • サーバークライアント(ブラウザなど)がリクエストを送り、サーバーがレスポンスを返す。
  • 判断YES/NO 分岐を表す菱形
  • 設計何をどう作るかを決める前工程
  • 副作用描画以外の処理(API・タイマー等)の総称
main.py
学習モード
エディタを読み込んでいます

メモ

CAP の availability 模擬

⌘S で保存