Skip to content

Commit 1562654

Browse files
author
Atsushi Ambo
committed
Fix: クイズ機能の改善、見出しの重複修正、ナビゲーション整理
- クイズの正誤表示と解説表示を改善 - 重複していた見出しを整理 - ナビゲーションの重複を解消 - ヘッダーの不要なテキストを非表示に
1 parent b8ce628 commit 1562654

File tree

7 files changed

+162
-46
lines changed

7 files changed

+162
-46
lines changed

docs/ops-essentials/hands-on.md

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# Hands-on: ラボの遊び方
2+
3+
!!! tip "クイックスタート"
4+
```bash
5+
# ラボ環境を起動
6+
docker compose --profile game up -d
7+
# ネットワーク演習を開始
8+
python3 tools/cli/game.py play 01-network
9+
```
10+
11+
## ラボの特徴
12+
13+
- **実践的なシナリオ**: 実際のトラブルシューティングを想定した課題
14+
- **段階的な学習**: 基礎から応用までステップバイステップで学べる
15+
- **即時フィードバック**: 解答チェックで理解度を確認
16+
17+
## 収録ゲーム
18+
19+
| ID | テーマ | 学ぶこと | 想定時間 |
20+
|----|--------|----------|----------|
21+
| **01-network** | ポートマッピングデバッグ | Docker ネットワーク基礎・Nginx | 20分 |
22+
| **02-monitor** | 監視入門 | Prometheus Exporter 追加 | 30分 |
23+
| _Coming soon_ | ログ分析 | ELKスタック | - |
24+
25+
## 各ラボの進め方
26+
27+
### 1. ラボの開始
28+
29+
```bash
30+
# 特定のラボを開始
31+
python3 tools/cli/game.py play 01-network
32+
```
33+
34+
### 2. 課題の確認
35+
36+
- 表示される問題文をよく読み、何を解決すべきか理解します
37+
- 必要に応じて、ヒントを参照できます
38+
39+
### 3. 課題に取り組む
40+
41+
- 指示に従って環境を操作します
42+
- 複数の方法で解決できる場合がありますので、自由に試してみてください
43+
44+
### 4. 解答チェック
45+
46+
```bash
47+
# 解答をチェック
48+
python3 tools/cli/game.py check
49+
```
50+
51+
## トラブルシューティング
52+
53+
- **Dockerが起動しない場合**: `docker compose down` で一度クリーンアップしてから再起動
54+
- **問題が表示されない場合**: ラボIDが正しいか確認してください
55+
- **その他**: `python3 tools/cli/game.py --help` でヘルプを表示
56+
57+
## ラボの終了
58+
59+
```bash
60+
# ラボ環境を停止
61+
python3 tools/cli/game.py stop
62+
63+
# すべてのコンテナを削除
64+
# docker compose down
65+
```
66+
67+
## フィードバック
68+
69+
問題や改善点がありましたら、GitHubのIssueでお知らせください。
70+
71+
[新しいIssueを作成](https://github.com/your-username/skillmap.dev/issues/new)

docs/ops-essentials/level1.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,9 @@
5353
- **スケーラビリティ**: ペタバイト級のデータを水平分散して保存可能で、トラフィック増加に応じて自動的にスケールします。
5454
- **コスト効率**: オンデマンド課金モデルで、使用した分だけのコストで済みます。
5555

56-
## 1-C ケーススタディ: GitHubの初期アーキテクチャ
56+
## 1-C ケーススタディ & アーキテクチャ図
57+
58+
### GitHubの初期アーキテクチャ
5759

5860
GitHubの初期の2層アーキテクチャは、シンプルながらも堅牢な設計で知られています。
5961

@@ -71,7 +73,7 @@ GitHubの初期の2層アーキテクチャは、シンプルながらも堅牢
7173

7274
**学び**: シンプルな設計から始め、必要に応じて複雑化していく進化的アーキテクチャの好例です。
7375

74-
## 1-C アーキテクチャ図
76+
### アーキテクチャ図
7577

7678
```mermaid
7779
graph TD

docs/ops-essentials/level2.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -163,21 +163,21 @@ Airbnbは、初期段階ではcronを多用していましたが、スケーラ
163163
<summary>クイズ: 監視の基本</summary>
164164
<p>システム監視において、リソース監視に含まれるのは?</p>
165165
<ul class="quiz-options">
166-
<li data-correct="true">CPU使用率</li>
167-
<li data-correct="true">メモリ使用量</li>
168-
<li data-correct="false">HTTPステータスコード</li>
169-
<li data-correct="true">ディスクI/O</li>
166+
<li data-correct="true" data-explain="CPU使用率はシステムの処理能力を計測する重要なリソース監視項目です。ボトルネックの特定やキャパシティプランニングに役立ちます。">CPU使用率</li>
167+
<li data-correct="true" data-explain="メモリ使用量はシステムのパフォーマンスに直結する重要なリソース指標で、メモリリークの検出にも役立ちます。">メモリ使用量</li>
168+
<li data-correct="false" data-explain="HTTPステータスコードはアプリケーション監視の項目で、リソース監視には含まれません。">HTTPステータスコード</li>
169+
<li data-correct="true" data-explain="ディスクI/Oはストレージのパフォーマンスを計測する重要なリソース監視項目です。">ディスクI/O</li>
170170
</ul>
171171
</details>
172172

173173
<details class="quiz">
174174
<summary>クイズ: ログ管理</summary>
175175
<p>ログ管理で重要な「3-2-1ルール」とは?</p>
176176
<ul class="quiz-options">
177-
<li data-correct="false">3つのログレベル、2つの保存先、1つのバックアップ</li>
178-
<li data-correct="true">3つのコピー、2つのメディア、1つはオフサイト</li>
179-
<li data-correct="false">3時間ごとのログ取得、2時間の保持、1週間のアーカイブ</li>
180-
<li data-correct="false">3つの監視項目、2つのアラート、1つのダッシュボード</li>
177+
<li data-correct="false" data-explain="ログレベルの数や保存先の数は、3-2-1ルールとは関係ありません。">3つのログレベル、2つの保存先、1つのバックアップ</li>
178+
<li data-correct="true" data-explain="3-2-1ルールとは、データ保護のベストプラクティスで、3つのコピーを2つの異なるメディアに保存し、そのうち1つはオフサイトに保管するというものです。これにより、災害時やシステム障害時のデータ損失リスクを最小限に抑えられます。">3つのコピー、2つのメディア、1つはオフサイト</li>
179+
<li data-correct="false" data-explain="ログの取得間隔や保持期間は、3-2-1ルールとは異なる概念です。">3時間ごとのログ取得、2時間の保持、1週間のアーカイブ</li>
180+
<li data-correct="false" data-explain="監視項目やアラートの数は、3-2-1ルールとは無関係です。">3つの監視項目、2つのアラート、1つのダッシュボード</li>
181181
</ul>
182182
</details>
183183

docs/ops-essentials/level3.md

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -187,30 +187,30 @@ Netflixは、マイクロサービスアーキテクチャとクラウドネイ
187187
<summary>クイズ: スケーリング戦略</summary>
188188
<p>スケールアウトのメリットとして正しいものは?</p>
189189
<ul class="quiz-options">
190-
<li data-correct="true">耐障害性が向上する</li>
191-
<li data-correct="false">サーバー1台あたりの処理能力が向上する</li>
192-
<li data-correct="false">初期コストが安い</li>
193-
<li data-correct="false">メンテナンスが簡単</li>
190+
<li data-correct="true" data-explain="スケールアウトでは複数のサーバーで負荷を分散するため、1台が停止しても他がカバーでき、耐障害性が向上します。">耐障害性が向上する</li>
191+
<li data-correct="false" data-explain="サーバー1台あたりの処理能力はスケールアップで向上します。スケールアウトは台数を増やすことで全体の処理能力を向上させます。">サーバー1台あたりの処理能力が向上する</li>
192+
<li data-correct="false" data-explain="スケールアウトは複数のサーバーが必要なため、初期コストは高くなりがちです。">初期コストが安い</li>
193+
<li data-correct="false" data-explain="複数のサーバーを管理する必要があるため、メンテナンスは相対的に複雑になります。">メンテナンスが簡単</li>
194194
</ul>
195195
</details>
196196

197197
<details class="quiz">
198198
<summary>クイズ: ロードバランサー</summary>
199199
<p>L7ロードバランサーの特徴として正しいものは?</p>
200200
<ul class="quiz-options">
201-
<li data-correct="true">HTTPヘッダーに基づいたルーティングが可能</li>
202-
<li data-correct="false">TCPレベルでのみ動作する</li>
203-
<li data-correct="false">SSL終端ができない</li>
204-
<li data-correct="false">レイヤー4で動作する</li>
201+
<li data-correct="true" data-explain="L7ロードバランサーはアプリケーション層(HTTP/HTTPS)で動作するため、HTTPヘッダーやURLパスに基づいた高度なルーティングが可能です。">HTTPヘッダーに基づいたルーティングが可能</li>
202+
<li data-correct="false" data-explain="TCPレベルでのみ動作するのはL4ロードバランサーの特徴です。">TCPレベルでのみ動作する</li>
203+
<li data-correct="false" data-explain="L7ロードバランサーはSSL/TLS終端が可能で、バックエンドサーバーの暗号化処理を軽減できます。">SSL終端ができない</li>
204+
<li data-correct="false" data-explain="レイヤー4で動作するのはL4ロードバランサーで、L7はアプリケーション層(レイヤー7)で動作します。">レイヤー4で動作する</li>
205205
</ul>
206206
</details>
207207
<details class="quiz">
208208
<summary>クイズ: 高可用性</summary>
209209
<p>高可用性を実現するための要素でないものは?</p>
210210
<ul class="quiz-options">
211-
<li data-correct="false">冗長化</li>
212-
<li data-correct="false">フェイルオーバー</li>
213-
<li data-correct="true">単一障害点の導入</li>
214-
<li data-correct="false">ヘルスチェック</li>
211+
<li data-correct="false" data-explain="冗長化は、システムの重要なコンポーネントを複数用意することで、1つが故障してもサービスを継続できるようにする重要な要素です。">冗長化</li>
212+
<li data-correct="false" data-explain="フェイルオーバーは、障害発生時に自動的に予備システムに切り替える仕組みで、高可用性に不可欠です。">フェイルオーバー</li>
213+
<li data-correct="true" data-explain="単一障害点の導入は、システムの信頼性を低下させる要因であり、高可用性を実現するための要素ではありません。むしろ排除すべきものです。">単一障害点の導入</li>
214+
<li data-correct="false" data-explain="ヘルスチェックは、システムの健全性を監視し、異常を検知するために重要な要素です。">ヘルスチェック</li>
215215
</ul>
216216
</details>

docs/theme/extra.css

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,50 @@ details.quiz summary:hover {
4747
line-height: 1.5;
4848
}
4949

50+
/* Hide redundant skip to content text in header */
51+
.md-header-nav__title {
52+
display: none;
53+
}
54+
55+
/* Quiz result labels and explanations */
56+
.result-label {
57+
font-weight: 700;
58+
margin-left: 8px;
59+
display: inline-block;
60+
padding: 2px 6px;
61+
border-radius: 4px;
62+
font-size: 0.85em;
63+
}
64+
65+
.quiz-options li.correct .result-label {
66+
color: #22c55e;
67+
background-color: rgba(34, 197, 94, 0.1);
68+
}
69+
70+
.quiz-options li.incorrect .result-label {
71+
color: #ef4444;
72+
background-color: rgba(239, 68, 68, 0.1);
73+
}
74+
75+
.explain {
76+
margin-top: 8px;
77+
padding: 8px 12px;
78+
background-color: #f8fafc;
79+
border-radius: 6px;
80+
border-right: 3px solid #e2e8f0;
81+
font-size: 0.9rem;
82+
color: #475569;
83+
line-height: 1.5;
84+
}
85+
86+
.quiz-options li.correct .explain {
87+
border-right-color: #22c55e;
88+
}
89+
90+
.quiz-options li.incorrect .explain {
91+
border-right-color: #ef4444;
92+
}
93+
5094
/* Quiz explanation styles */
5195
.quiz-options li {
5296
position: relative;

docs/theme/quiz.js

Lines changed: 22 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,19 @@
11
// Quiz interaction functionality with explanations
22
document.addEventListener("DOMContentLoaded", () => {
3+
// Mark function to handle quiz answer feedback
4+
const mark = (li, ok) => {
5+
li.classList.add(ok ? "correct" : "incorrect");
6+
if (!li.querySelector(".result-label")) {
7+
li.insertAdjacentHTML("beforeend",
8+
`<span class="result-label">${ok ? "✔ 正解" : "✖ 不正解"}</span>`
9+
);
10+
const exp = li.dataset.explain || "";
11+
if (exp) li.insertAdjacentHTML("beforeend",
12+
`<div class="explain">${exp}</div>`
13+
);
14+
}
15+
};
16+
317
// Initialize all quiz options
418
document.querySelectorAll(".quiz-options").forEach((list) => {
519
list.querySelectorAll("li").forEach((li) => {
@@ -8,38 +22,22 @@ document.addEventListener("DOMContentLoaded", () => {
822
if (li.classList.contains("clicked")) return;
923

1024
const isCorrect = li.dataset.correct === "true";
11-
const explanation = li.dataset.explain || "";
1225

13-
// Add appropriate class based on answer
14-
li.classList.add(isCorrect ? "correct" : "incorrect");
15-
li.classList.add("clicked");
26+
// Mark the clicked answer
27+
mark(li, isCorrect);
1628

17-
// Add explanation if exists
18-
if (explanation) {
19-
const explainEl = document.createElement("div");
20-
explainEl.className = "explanation";
21-
explainEl.textContent = explanation;
22-
li.appendChild(explainEl);
23-
}
24-
25-
// Disable further clicks on all options and show explanations
29+
// Mark all other options as disabled
2630
list.querySelectorAll("li").forEach((option) => {
2731
option.style.pointerEvents = "none";
2832

2933
// Show correct answer with explanation if user clicked wrong one
30-
if (option.dataset.correct === "true") {
31-
if (!isCorrect) {
32-
option.classList.add("correct");
33-
if (option.dataset.explain) {
34-
const correctExplain = document.createElement("div");
35-
correctExplain.className = "explanation";
36-
correctExplain.textContent = option.dataset.explain;
37-
option.appendChild(correctExplain);
38-
}
39-
}
34+
if (option.dataset.correct === "true" && !isCorrect) {
35+
mark(option, true);
4036
}
4137
});
42-
38+
});
39+
});
40+
});
4341
// Prevent event bubbling
4442
e.stopPropagation();
4543
});

mkdocs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,4 @@ nav:
4545
- Level 1 – Foundations: ops-essentials/level1.md
4646
- Level 2 – Ops Routine: ops-essentials/level2.md
4747
- Level 3 – Scale & HA: ops-essentials/level3.md
48+
- Hands-on ラボ: ops-essentials/hands-on.md

0 commit comments

Comments
 (0)