Spaces:
Running
Running
Sync from GitHub 37f011465a0aa2abdfdd94d8bd5f31cfe932c669
Browse files- CHANGELOG.md +10 -0
- cert_study_app/content/__init__.py +0 -0
- cert_study_app/content/azure/lessons.json +1213 -0
- cert_study_app/content/azure/practices.json +152 -0
- cert_study_app/content/azure/quizzes.json +1058 -0
- cert_study_app/content/linux/lessons.json +1448 -0
- cert_study_app/content/linux/practices.json +428 -0
- cert_study_app/content/linux/quizzes.json +1076 -0
- cert_study_app/content/loader.py +34 -0
- cert_study_app/content/tool_docs/lessons.json +529 -0
- cert_study_app/content/tool_docs/practices.json +530 -0
- cert_study_app/content/tool_docs/quizzes.json +1032 -0
- cert_study_app/services/docs_source_service.py +395 -0
- cert_study_app/services/official_docs_service.py +210 -0
CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
| 1 |
# Changelog
|
| 2 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3 |
## 2026-07-04
|
| 4 |
|
| 5 |
- Fixed AI quiz assistant crashing the page when ChromaDB collection is empty (added `min(k, count)` guard).
|
|
|
|
| 1 |
# Changelog
|
| 2 |
|
| 3 |
+
## 2026-07-04 (2)
|
| 4 |
+
|
| 5 |
+
- Set difficulty (easy/medium/hard) on 49 Linux quizzes that were previously unclassified.
|
| 6 |
+
- Added `level` (์
๋ฌธ/์ค๊ธ/๊ณ ๊ธ) to all 50 Azure lessons (was None for all).
|
| 7 |
+
- Linked `related_practices` on 20 Azure lessons to their corresponding practice task IDs.
|
| 8 |
+
- Added cumulative lesson/quiz/practice progress count (N/์ด๊ฐ์) to home mode cards.
|
| 9 |
+
- Added overall quiz progress bar (ํด์ฆ N/์ด๊ฐ์ ์๋ฃ) to the top of the `ํ์ธ ํด์ฆ` screen.
|
| 10 |
+
- Added overall practice progress bar (์ค์ต N/์ด๊ฐ์ ์๋ฃ) to the top of the `์ค์ตํ๊ธฐ` screen.
|
| 11 |
+
- Added "๊ด๋ จ ์ด๋ก ๋ค์ ๋ณด๊ธฐ" button on practice failure, routing to the linked lesson (reverse `related_practices` lookup).
|
| 12 |
+
|
| 13 |
## 2026-07-04
|
| 14 |
|
| 15 |
- Fixed AI quiz assistant crashing the page when ChromaDB collection is empty (added `min(k, count)` guard).
|
cert_study_app/content/__init__.py
ADDED
|
File without changes
|
cert_study_app/content/azure/lessons.json
ADDED
|
@@ -0,0 +1,1213 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[
|
| 2 |
+
{
|
| 3 |
+
"id": "azure-rg",
|
| 4 |
+
"certification": "AZ-104",
|
| 5 |
+
"title": "Resource Group โ ๋ฆฌ์์ค ๊ทธ๋ฃน",
|
| 6 |
+
"summary": "Azure ๋ฆฌ์์ค๋ฅผ ๋
ผ๋ฆฌ์ ์ผ๋ก ๋ฌถ๋ ์ปจํ
์ด๋์
๋๋ค. ๋์ผ RG์ ๋ฆฌ์์ค๋ ํจ๊ป ๋ฐฐํฌยท๊ด๋ฆฌยท์ญ์ ๋๋ฉฐ, ์์น(region)๊ฐ ์๋ก ๋ฌ๋ผ๋ ๊ฐ์ RG์ ์ํ ์ ์์ต๋๋ค.",
|
| 7 |
+
"example": "az group create --name myRG --location koreacentral\naz group list --output table\naz group delete --name myRG --yes",
|
| 8 |
+
"common_mistake": "RG๋ฅผ ์ญ์ ํ๋ฉด ์์ ์ํ ๋ชจ๋ ๋ฆฌ์์ค๊ฐ ํจ๊ป ์ญ์ ๋ฉ๋๋ค. RG ์์น์ ๋ด๋ถ ๋ฆฌ์์ค ์์น๋ ๋ณ๊ฐ์
๋๋ค.",
|
| 9 |
+
"keywords": [
|
| 10 |
+
"resource group",
|
| 11 |
+
"container",
|
| 12 |
+
"lifecycle",
|
| 13 |
+
"region",
|
| 14 |
+
"az group"
|
| 15 |
+
],
|
| 16 |
+
"source_id": "azure-vm-overview",
|
| 17 |
+
"details": [
|
| 18 |
+
"RG๋ ๋ฆฌ์์ค์ ์๋ช
์ฃผ๊ธฐ๋ฅผ ํจ๊ป ๊ด๋ฆฌํ๊ธฐ ์ํ ๋จ์์
๋๋ค. ํ๋ก์ ํธ๋ณ, ํ๊ฒฝ๋ณ(dev/prod), ๋๋ ํ๋ณ๋ก ๋ถ๋ฆฌํ๋ ๊ฒ์ด ์ผ๋ฐ์ ์
๋๋ค.",
|
| 19 |
+
"RG ์์ฒด์ ์์น๋ ๋ฉํ๋ฐ์ดํฐ ์ ์ฅ ์์น์ด๋ฉฐ, ๋ด๋ถ ๋ฆฌ์์ค๋ ๋ค๋ฅธ region์ ์์ด๋ ๋ฉ๋๋ค.",
|
| 20 |
+
"์ํ ํจํด: RG ์ญ์ ์ ์ํฅ ๋ฒ์, RG์ RBACยทLockยทTag๋ฅผ ์ ์ฉํ๋ ์๋๋ฆฌ์ค, RG ์ด๋ ์ ํ ์ฌํญ์ด ์ถ์ ๋ฉ๋๋ค."
|
| 21 |
+
],
|
| 22 |
+
"level": "์
๋ฌธ",
|
| 23 |
+
"related_practices": [
|
| 24 |
+
"azure-lab-1"
|
| 25 |
+
]
|
| 26 |
+
},
|
| 27 |
+
{
|
| 28 |
+
"id": "azure-storage",
|
| 29 |
+
"certification": "AZ-104",
|
| 30 |
+
"title": "Storage Account โ ์คํ ๋ฆฌ์ง ๊ณ์ ",
|
| 31 |
+
"summary": "Blob, File, Queue, Table 4๊ฐ์ง ์คํ ๋ฆฌ์ง ์๋น์ค๋ฅผ ์ ๊ณตํ๋ ์ต์์ ๋ค์์คํ์ด์ค์
๋๋ค. SKU(Standard/Premium)์ ์ค๋ณต์ฑ(LRS/GRS ๋ฑ)์ ์์ฑ ์ ๊ฒฐ์ ํฉ๋๋ค.",
|
| 32 |
+
"example": "az storage account create \\\n --name mystorageacct \\\n --resource-group myRG \\\n --sku Standard_LRS \\\n --kind StorageV2",
|
| 33 |
+
"common_mistake": "Storage Account ์ด๋ฆ์ ์ ์ธ๊ณ์์ ์ ์ผํด์ผ ํ๋ฉฐ ์๋ฌธ์ยท์ซ์๋ง ์ฌ์ฉ ๊ฐ๋ฅํฉ๋๋ค(3~24์). SKU๋ ์์ฑ ํ ๋ณ๊ฒฝํ ์ ์์ต๋๋ค.",
|
| 34 |
+
"keywords": [
|
| 35 |
+
"storage account",
|
| 36 |
+
"Blob",
|
| 37 |
+
"Files",
|
| 38 |
+
"LRS",
|
| 39 |
+
"GRS",
|
| 40 |
+
"SKU",
|
| 41 |
+
"StorageV2"
|
| 42 |
+
],
|
| 43 |
+
"source_id": "azure-storage-account",
|
| 44 |
+
"details": [
|
| 45 |
+
"StorageV2(๋ฒ์ฉ v2)๊ฐ ํ์ฌ ๊ถ์ฅ ํ์์ผ๋ก ๋ชจ๋ ์คํ ๋ฆฌ์ง ์๋น์ค์ ์ต์ ๊ธฐ๋ฅ์ ์ง์ํฉ๋๋ค.",
|
| 46 |
+
"์ค๋ณต์ฑ: LRS(๋จ์ผ datacenter 3๋ณต์ ), ZRS(3 AZ), GRS(๋ค๋ฅธ region์ผ๋ก ๋น๋๊ธฐ ๋ณต์ ), GZRS(ZRS+GRS).",
|
| 47 |
+
"์ํ ํจํด: ์ค๋ณต์ฑ ์์ค๋ณ ํน์ง, ์คํ ๋ฆฌ์ง ๊ณ์ ์ข
๋ฅ(Blob์ ์ฉ/StorageV2 ๋ฑ), ๋ณด์ ์ค์ (HTTPS ๊ฐ์ , ๋ฐฉํ๋ฒฝ) ๋ฌธ์ ๊ฐ ์ถ์ ๋ฉ๋๋ค."
|
| 48 |
+
],
|
| 49 |
+
"level": "์
๋ฌธ",
|
| 50 |
+
"related_practices": [
|
| 51 |
+
"azure-lab-2"
|
| 52 |
+
]
|
| 53 |
+
},
|
| 54 |
+
{
|
| 55 |
+
"id": "azure-vnet",
|
| 56 |
+
"certification": "AZ-104",
|
| 57 |
+
"title": "Virtual Network โ ๊ฐ์ ๋คํธ์ํฌ",
|
| 58 |
+
"summary": "Azure์์ ๋ฆฌ์์ค๊ฐ ํต์ ํ๋ ๊ฒฉ๋ฆฌ๋ ์ฌ์ค ๋คํธ์ํฌ์
๋๋ค. ์๋ธ๋ท์ผ๋ก ๋๋๋ฉฐ, ์จํ๋ ๋ฏธ์ค ์ฐ๊ฒฐ(VPN Gateway, ExpressRoute)๊ณผ ํผ์ด๋ง์ ํตํด ํ์ฅํฉ๋๋ค.",
|
| 59 |
+
"example": "az network vnet create \\\n --name myVNet \\\n --address-prefix 10.0.0.0/16 \\\n --subnet-name default \\\n --subnet-prefix 10.0.0.0/24",
|
| 60 |
+
"common_mistake": "VNet ์ฃผ์ ๊ณต๊ฐ์ด ๊ฒน์น๋ฉด ํผ์ด๋ง์ด ๋ถ๊ฐ๋ฅํฉ๋๋ค. ์ค๊ณ ์ด๊ธฐ์ IP ๋ฒ์๋ฅผ ์๋ก ๊ฒน์น์ง ์๊ฒ ์ก์์ผ ํฉ๋๋ค.",
|
| 61 |
+
"keywords": [
|
| 62 |
+
"VNet",
|
| 63 |
+
"subnet",
|
| 64 |
+
"address space",
|
| 65 |
+
"CIDR",
|
| 66 |
+
"peering",
|
| 67 |
+
"NSG"
|
| 68 |
+
],
|
| 69 |
+
"source_id": "azure-vnet-overview",
|
| 70 |
+
"details": [
|
| 71 |
+
"VNet ๋ด ๋ชจ๋ ๋ฆฌ์์ค๋ ๊ธฐ๋ณธ์ ์ผ๋ก ์๋ก ํต์ ๊ฐ๋ฅํฉ๋๋ค. ์ธ๋ถ ์ธํฐ๋ท ํต์ ์ Public IP ๋๋ NAT Gateway๋ฅผ ํตํฉ๋๋ค.",
|
| 72 |
+
"์๋ธ๋ท์ VNet ์ฃผ์ ๊ณต๊ฐ์ ์ผ๋ถ. Azure๊ฐ ๊ฐ ์๋ธ๋ท์์ 5๊ฐ IP๋ฅผ ์์ฝํฉ๋๋ค(์ฒซ 4๊ฐ + ๋ง์ง๋ง).",
|
| 73 |
+
"์ํ ํจํด: VNet/์๋ธ๋ท ์ฃผ์ ๋ฒ์ ๊ณ์ฐ, NSG์ ์๋ธ๋ท ์ฐ๊ฒฐ, ํผ์ด๋ง ์กฐ๊ฑด(์ฃผ์ ๋น์ค์ฒฉ) ๋ฌธ์ ๊ฐ ์์ฃผ ์ถ์ ๋ฉ๋๋ค."
|
| 74 |
+
],
|
| 75 |
+
"level": "์
๋ฌธ",
|
| 76 |
+
"related_practices": [
|
| 77 |
+
"azure-lab-3"
|
| 78 |
+
]
|
| 79 |
+
},
|
| 80 |
+
{
|
| 81 |
+
"id": "azure-rbac",
|
| 82 |
+
"certification": "AZ-104",
|
| 83 |
+
"title": "Azure RBAC โ ์ญํ ๊ธฐ๋ฐ ์ ๊ทผ ์ ์ด",
|
| 84 |
+
"summary": "๋๊ฐ(Who), ์ด๋ค ๋ฆฌ์์ค์(Scope), ๋ฌด์์ ํ ์ ์๋์ง(Role)๋ฅผ ์ ์ํฉ๋๋ค. ์ญํ ํ ๋น์ ๊ตฌ๋
ยทRGยท๋ฆฌ์์ค ๋ ๋ฒจ์์ ์์๋ฉ๋๋ค.",
|
| 85 |
+
"example": "az role assignment create \\\n --assignee alice@example.com \\\n --role 'Contributor' \\\n --scope /subscriptions/SUB_ID/resourceGroups/myRG",
|
| 86 |
+
"common_mistake": "RBAC๋ ๊ด๋ฆฌ ํ๋ฉด(Azure Portal/API) ์ ๊ทผ ์ ์ด์
๋๋ค. VM ๋ด๋ถ OS ์ ๊ทผ์ด๋ Storage ๋ฐ์ดํฐ ์ ๊ทผ์ ๋ณ๋ ์ค์ ์ด ํ์ํฉ๋๋ค.",
|
| 87 |
+
"keywords": [
|
| 88 |
+
"RBAC",
|
| 89 |
+
"role assignment",
|
| 90 |
+
"Owner",
|
| 91 |
+
"Contributor",
|
| 92 |
+
"Reader",
|
| 93 |
+
"scope",
|
| 94 |
+
"principal"
|
| 95 |
+
],
|
| 96 |
+
"source_id": "azure-rbac-overview",
|
| 97 |
+
"details": [
|
| 98 |
+
"๋ด์ฅ ์ญํ 3๊ฐ์ง: Owner(๋ชจ๋ ๊ถํ+์ญํ ํ ๋น), Contributor(๋ฆฌ์์ค CRUD, ์ญํ ํ ๋น ๋ถ๊ฐ), Reader(์ฝ๊ธฐ๋ง).",
|
| 99 |
+
"์ญํ ํ ๋น ๋ฒ์: ๊ด๋ฆฌ ๊ทธ๋ฃน > ๊ตฌ๋
> RG > ๋ฆฌ์์ค. ์์ ๋ฒ์ ์ญํ ์ ํ์๋ก ์์๋ฉ๋๋ค.",
|
| 100 |
+
"์ํ ํจํด: ์ต์ ๊ถํ ์์น์ ๋ฐ๋ฅธ ์ญํ ์ ํ, ๋ฒ์๋ณ ์ญํ ์์ ๊ฒฐ๊ณผ, Owner vs Contributor ์ฐจ์ด ๋ฌธ์ ๊ฐ ์์ฃผ ์ถ์ ๋ฉ๋๋ค."
|
| 101 |
+
],
|
| 102 |
+
"level": "์
๋ฌธ",
|
| 103 |
+
"related_practices": [
|
| 104 |
+
"azure-lab-5"
|
| 105 |
+
]
|
| 106 |
+
},
|
| 107 |
+
{
|
| 108 |
+
"id": "azure-policy",
|
| 109 |
+
"certification": "AZ-104",
|
| 110 |
+
"title": "Azure Policy โ ์ ์ฑ
",
|
| 111 |
+
"summary": "๋ฆฌ์์ค๊ฐ ์กฐ์ง์ ๊ท์ ์ ์ค์ํ๋๋ก ๊ฐ์ ํฉ๋๋ค. ํน์ region๋ง ํ์ฉ, ํ๊ทธ ๊ฐ์ , SKU ์ ํ ๋ฑ์ ์ ์ฑ
์ ์๋ก ๋ง๋ค์ด ๊ตฌ๋
ยทRG์ ํ ๋นํฉ๋๋ค.",
|
| 112 |
+
"example": "# ํ์ฉ location ์ ํ ์ ์ฑ
ํ ๋น ์\naz policy assignment create \\\n --name 'allowed-locations' \\\n --policy 'e56962a6-4747-49cd-b67b-bf8b01975c4f' \\\n --params '{\"listOfAllowedLocations\":{\"value\":[\"koreacentral\"]}}'",
|
| 113 |
+
"common_mistake": "Policy๋ ์ด๋ฏธ ์กด์ฌํ๋ ๋น์ค์ ๋ฆฌ์์ค๋ฅผ ์๋์ผ๋ก ์์ ํ์ง ์์ต๋๋ค. ์์ ์ด ํ์ํ๋ฉด remediation task๋ฅผ ๋ณ๋๋ก ์คํํด์ผ ํฉ๋๋ค.",
|
| 114 |
+
"keywords": [
|
| 115 |
+
"Azure Policy",
|
| 116 |
+
"policy definition",
|
| 117 |
+
"initiative",
|
| 118 |
+
"compliance",
|
| 119 |
+
"deny",
|
| 120 |
+
"audit",
|
| 121 |
+
"remediation"
|
| 122 |
+
],
|
| 123 |
+
"source_id": "azure-policy-overview",
|
| 124 |
+
"details": [
|
| 125 |
+
"ํจ๊ณผ(effect) ์ ํ: Deny(๊ฑฐ๋ถ), Audit(๊ฐ์ฌ๋ง), AuditIfNotExists, DeployIfNotExists(์๋ ๋ณด์ ๋ฐฐํฌ), Disabled.",
|
| 126 |
+
"Initiative(์ด๋์
ํฐ๋ธ)๋ ์ฌ๋ฌ Policy๋ฅผ ๋ฌถ์ ์งํฉ. NIST, CIS ๋ฑ ๊ท์ ์ค์ ํ๋ ์์ํฌ๊ฐ ์ด๋์
ํฐ๋ธ๋ก ์ ๊ณต๋ฉ๋๋ค.",
|
| 127 |
+
"์ํ ํจํด: Policy์ RBAC ์ฐจ์ด(RBAC๋ ํ์ ์ ์ด, Policy๋ ๋ฆฌ์์ค ์์ฑ ์ ์ด), ํจ๊ณผ ์ ํ๋ณ ๋์, ์ด๋์
ํฐ๋ธ vs ๋จ๋
์ ์ฑ
๋ฌธ์ ๊ฐ ์ถ์ ๋ฉ๋๋ค."
|
| 128 |
+
],
|
| 129 |
+
"level": "์
๋ฌธ"
|
| 130 |
+
},
|
| 131 |
+
{
|
| 132 |
+
"id": "azure-vm",
|
| 133 |
+
"certification": "AZ-104",
|
| 134 |
+
"title": "Virtual Machine โ ๊ฐ์ ๋จธ์ ",
|
| 135 |
+
"summary": "Azure์์ ์ ๊ณตํ๋ IaaS ์ปดํจํ
์
๋๋ค. VM ํฌ๊ธฐ(SKU), OS ์ด๋ฏธ์ง, ๊ฐ์ฉ์ฑ ๊ตฌ์ฑ, ๋์คํฌ ์ ํ์ ์ ํํด ๋ฐฐํฌํฉ๋๋ค.",
|
| 136 |
+
"example": "az vm create \\\n --name myVM \\\n --resource-group myRG \\\n --image Ubuntu2204 \\\n --size Standard_B2s \\\n --admin-username azureuser \\\n --generate-ssh-keys",
|
| 137 |
+
"common_mistake": "VM์ '์ค์ง(Stop)'ํด๋ ํ ๋น ํด์ (deallocated)๊ฐ ์๋๋ฉด ์ปดํจํ
์๊ธ์ด ๊ณ์ ์ฒญ๊ตฌ๋ฉ๋๋ค. ๋น์ฉ ์ ๊ฐ์ ์ํด '์ค์ง(ํ ๋น ํด์ )'๋ฅผ ์ฌ์ฉํด์ผ ํฉ๋๋ค.",
|
| 138 |
+
"keywords": [
|
| 139 |
+
"VM",
|
| 140 |
+
"SKU",
|
| 141 |
+
"availability set",
|
| 142 |
+
"managed disk",
|
| 143 |
+
"deallocate",
|
| 144 |
+
"NSG",
|
| 145 |
+
"public IP"
|
| 146 |
+
],
|
| 147 |
+
"source_id": "azure-vm-overview",
|
| 148 |
+
"details": [
|
| 149 |
+
"VM ํฌ๊ธฐ ์๋ฆฌ์ฆ: B(๋ฒ์คํธ, ์ ๋น์ฉ), D(๋ฒ์ฉ), E(๋ฉ๋ชจ๋ฆฌ ์ต์ ํ), F(์ปดํจํ
์ต์ ํ), N(GPU). ์ซ์๋ vCPU ์๋ฅผ ์๋ฏธํฉ๋๋ค.",
|
| 150 |
+
"VM ์์ฑ ์ ์๋์ผ๋ก NIC, OS ๋์คํฌ, Public IP(์ ํ)๊ฐ ํจ๊ป ์์ฑ๋ฉ๋๋ค.",
|
| 151 |
+
"์ํ ํจํด: ์ค์ง vs ํ ๋น ํด์ ์๊ธ ์ฐจ์ด, VM ํฌ๊ธฐ ๋ณ๊ฒฝ ์ ์ฌ์์ ํ์ ์ฌ๋ถ, ๊ฐ์ฉ์ฑ SLA 99.9/99.95/99.99% ๊ตฌ์ฑ ๋ฐฉ๋ฒ์ด ์์ฃผ ์ถ์ ๋ฉ๋๋ค."
|
| 152 |
+
],
|
| 153 |
+
"level": "์
๋ฌธ"
|
| 154 |
+
},
|
| 155 |
+
{
|
| 156 |
+
"id": "azure-vmss",
|
| 157 |
+
"certification": "AZ-104",
|
| 158 |
+
"title": "Virtual Machine Scale Sets โ ๊ฐ์ ๋จธ์ ํ์ฅ ์งํฉ",
|
| 159 |
+
"summary": "๋์ผํ VM์ ์๋์ผ๋ก ํ์ฅยท์ถ์ํ๋ ๊ทธ๋ฃน์
๋๋ค. ๋ถํ์ ๋ฐ๋ผ ์ธ์คํด์ค ์๋ฅผ ์๋ ์กฐ์ (Autoscale)ํ๊ณ , ๋ถํ ๋ถ์ฐ ์ฅ์น์ ํตํฉํฉ๋๋ค.",
|
| 160 |
+
"example": "az vmss create \\\n --name myVMSS \\\n --resource-group myRG \\\n --image Ubuntu2204 \\\n --instance-count 2 \\\n --vm-sku Standard_B2s",
|
| 161 |
+
"common_mistake": "VMSS์ ๊ฐ๋ณ ์ธ์คํด์ค๋ ์
๊ทธ๋ ์ด๋ ์ ์ฑ
(์๋/์๋/๋กค๋ง)์ ๋ฐ๋ผ ๋ค๋ฅด๊ฒ ์
๋ฐ์ดํธ๋ฉ๋๋ค. ์๋ ์ ์ฑ
์ ์ธ์คํด์ค๋ฅผ ์์ฐจ์ ์ผ๋ก ์ฌ์์ํฉ๋๋ค.",
|
| 162 |
+
"keywords": [
|
| 163 |
+
"VMSS",
|
| 164 |
+
"scale set",
|
| 165 |
+
"autoscale",
|
| 166 |
+
"instance count",
|
| 167 |
+
"upgrade policy",
|
| 168 |
+
"load balancer"
|
| 169 |
+
],
|
| 170 |
+
"source_id": "azure-vmss-overview",
|
| 171 |
+
"details": [
|
| 172 |
+
"Orchestration ๋ชจ๋: Uniform(๋์ผ VM, ์๋ ํ์ฅ ์ต์ ํ) vs Flexible(ํผํฉ VM ํฌ๊ธฐ ๊ฐ๋ฅ, Availability Zone ์ง์ ๊ฐํ).",
|
| 173 |
+
"Autoscale ๊ท์น: CPU%, ๋ฉ๋ชจ๋ฆฌ, ํ ๊ธธ์ด ๋ฑ ๋ฉํธ๋ฆญ ๊ธฐ๋ฐ์ผ๋ก scale-out/in ์๊ณ๊ฐ์ ์ค์ ํฉ๋๋ค.",
|
| 174 |
+
"์ํ ํจํด: VMSS vs Availability Set ์ฐจ์ด(AS๋ ์๋ ํ์ฅ ์์), ์
๊ทธ๋ ์ด๋ ์ ์ฑ
์ ํ, ๋ถํ ๋ถ์ฐ๊ธฐ ํตํฉ ๋ฐฉ๋ฒ์ด ์ถ์ ๋ฉ๋๋ค."
|
| 175 |
+
],
|
| 176 |
+
"level": "์ค๊ธ"
|
| 177 |
+
},
|
| 178 |
+
{
|
| 179 |
+
"id": "azure-nsg",
|
| 180 |
+
"certification": "AZ-104",
|
| 181 |
+
"title": "Network Security Group โ ๋คํธ์ํฌ ๋ณด์ ๊ทธ๋ฃน",
|
| 182 |
+
"summary": "์ธ๋ฐ์ด๋/์์๋ฐ์ด๋ ํธ๋ํฝ์ ํฌํธยทํ๋กํ ์ฝยท์๋ณธIP๋ก ํ์ฉ/๊ฑฐ๋ถํ๋ ๊ท์น ์งํฉ์
๋๋ค. ์๋ธ๋ท ๋๋ NIC์ ์ฐ๊ฒฐํฉ๋๋ค.",
|
| 183 |
+
"example": "az network nsg rule create \\\n --nsg-name myNSG \\\n --name allow-ssh \\\n --priority 100 \\\n --access Allow \\\n --protocol Tcp \\\n --destination-port-ranges 22",
|
| 184 |
+
"common_mistake": "์ฐ์ ์์ ์ซ์๊ฐ ๋ฎ์์๋ก ๋จผ์ ์ ์ฉ๋ฉ๋๋ค(100์ด 200๋ณด๋ค ๋์ ์ฐ์ ์์). ๊ท์น ์ถฉ๋ ์ ๋ฎ์ ๋ฒํธ ๊ท์น์ด ์ด๊น๋๋ค.",
|
| 185 |
+
"keywords": [
|
| 186 |
+
"NSG",
|
| 187 |
+
"inbound",
|
| 188 |
+
"outbound",
|
| 189 |
+
"priority",
|
| 190 |
+
"allow",
|
| 191 |
+
"deny",
|
| 192 |
+
"subnet",
|
| 193 |
+
"NIC"
|
| 194 |
+
],
|
| 195 |
+
"source_id": "azure-nsg-overview",
|
| 196 |
+
"details": [
|
| 197 |
+
"NSG์๋ ๊ธฐ๋ณธ ๊ท์น์ด ์์ต๋๋ค: AllowVNetInbound(65000), AllowAzureLoadBalancerInbound(65001), DenyAllInbound(65500).",
|
| 198 |
+
"NSG๋ฅผ ์๋ธ๋ท๊ณผ NIC ์์ชฝ์ ์ฐ๊ฒฐํ๋ฉด ํธ๋ํฝ์ด ๋ NSG๋ฅผ ๋ชจ๋ ํต๊ณผํฉ๋๋ค. ์ธ๋ฐ์ด๋๋ ์๋ธ๋ทNSGโNIC NSG ์์.",
|
| 199 |
+
"์ํ ํจํด: ํน์ ํฌํธ ํ์ฉ/์ฐจ๋จ ๊ท์น ์ค๊ณ, ์ฐ์ ์์ ์ถฉ๋ ๊ฒฐ๊ณผ, ์๋ธ๋ท vs NIC ์ฐ๊ฒฐ ์ฐจ์ด ๋ฌธ์ ๊ฐ ์์ฃผ ์ถ์ ๋ฉ๋๋ค."
|
| 200 |
+
],
|
| 201 |
+
"level": "์
๋ฌธ",
|
| 202 |
+
"related_practices": [
|
| 203 |
+
"azure-lab-4"
|
| 204 |
+
]
|
| 205 |
+
},
|
| 206 |
+
{
|
| 207 |
+
"id": "azure-app-gateway",
|
| 208 |
+
"certification": "AZ-104",
|
| 209 |
+
"title": "Application Gateway โ ์ ํ๋ฆฌ์ผ์ด์
๊ฒ์ดํธ์จ์ด",
|
| 210 |
+
"summary": "HTTP/HTTPS ๋ ์ด์ด(L7) ๋ถํ ๋ถ์ฐ ์ฅ์น์
๋๋ค. URL ๊ธฐ๋ฐ ๋ผ์ฐํ
, SSL ์ข
๋ฃ, WAF(์น ๋ฐฉํ๋ฒฝ)๋ฅผ ์ง์ํฉ๋๋ค.",
|
| 211 |
+
"example": "# ๊ตฌ์ฑ ์์: Frontend IP โ Listener โ Rule โ Backend Pool โ HTTP Settings\n# URL ๊ธฐ๋ฐ ๋ผ์ฐํ
์:\n# /images/* โ image-pool\n# /api/* โ api-pool",
|
| 212 |
+
"common_mistake": "Application Gateway๋ L7, Azure Load Balancer๋ L4์
๋๋ค. URL ๊ฒฝ๋ก๋ ํธ์คํธ ํค๋ ๊ธฐ๋ฐ ๋ผ์ฐํ
์ด ํ์ํ๋ฉด App Gateway๋ฅผ ์๋๋ค.",
|
| 213 |
+
"keywords": [
|
| 214 |
+
"Application Gateway",
|
| 215 |
+
"L7",
|
| 216 |
+
"WAF",
|
| 217 |
+
"SSL termination",
|
| 218 |
+
"URL routing",
|
| 219 |
+
"backend pool"
|
| 220 |
+
],
|
| 221 |
+
"source_id": "azure-app-gateway-overview",
|
| 222 |
+
"details": [
|
| 223 |
+
"๊ตฌ์ฑ ํ๋ฆ: Frontend IP โ Listener(ํฌํธ/ํ๋กํ ์ฝ) โ Routing Rule โ Backend Pool(VM/VMSS/IP) โ HTTP Settings.",
|
| 224 |
+
"WAF SKU๋ OWASP ๊ท์น์
์ผ๋ก SQL injection, XSS ๋ฑ ์น ๊ณต๊ฒฉ์ ํ์งยท์ฐจ๋จํฉ๋๋ค.",
|
| 225 |
+
"์ํ ํจํด: App Gateway vs Load Balancer ์ ํ ๊ธฐ์ค, URL ๊ฒฝ๋ก ๊ธฐ๋ฐ ๋ผ์ฐํ
๊ตฌ์ฑ, SSL ์คํ๋ก๋ฉ ๊ฐ๋
์ด ์์ฃผ ์ถ์ ๋ฉ๋๋ค."
|
| 226 |
+
],
|
| 227 |
+
"level": "์ค๊ธ"
|
| 228 |
+
},
|
| 229 |
+
{
|
| 230 |
+
"id": "azure-dns",
|
| 231 |
+
"certification": "AZ-104",
|
| 232 |
+
"title": "Azure DNS โ ๋๋ฉ์ธ ์ด๋ฆ ์๋น์ค",
|
| 233 |
+
"summary": "Azure์์ DNS ์์ญ์ ํธ์คํ
ํฉ๋๋ค. Public DNS Zone์ ์ธํฐ๋ท์ฉ, Private DNS Zone์ VNet ๋ด๋ถ ์ด๋ฆ ํด์์ ์ฌ์ฉํฉ๋๋ค.",
|
| 234 |
+
"example": "az network dns zone create --name example.com --resource-group myRG\naz network dns record-set a add-record \\\n --zone-name example.com \\\n --record-set-name www \\\n --ipv4-address 1.2.3.4",
|
| 235 |
+
"common_mistake": "Azure DNS๋ ๋๋ฉ์ธ ๋ฑ๋ก ์๋น์ค๊ฐ ์๋๋๋ค. ๋๋ฉ์ธ์ ๋ณ๋ ๋ฑ๋ก ๊ธฐ๊ด์์ ๊ตฌ๋งค ํ ๋ค์์๋ฒ๋ฅผ Azure๋ก ์์ํด์ผ ํฉ๋๋ค.",
|
| 236 |
+
"keywords": [
|
| 237 |
+
"Azure DNS",
|
| 238 |
+
"Public Zone",
|
| 239 |
+
"Private Zone",
|
| 240 |
+
"A record",
|
| 241 |
+
"CNAME",
|
| 242 |
+
"NS delegation"
|
| 243 |
+
],
|
| 244 |
+
"source_id": "azure-dns-overview",
|
| 245 |
+
"details": [
|
| 246 |
+
"Public DNS Zone ์์ฑ ํ Azure๊ฐ ์ ๊ณตํ๋ NS ๋ ์ฝ๋ 4๊ฐ๋ฅผ ๋๋ฉ์ธ ๋ฑ๋ก ๊ธฐ๊ด์์ ์ค์ ํด ์์ํฉ๋๋ค.",
|
| 247 |
+
"Private DNS Zone์ VNet์ ์ฐ๊ฒฐ(link)ํ๋ฉด ํด๋น VNet์ VM์ด ์ฌ์ค ๋๋ฉ์ธ ์ด๋ฆ์ ํด์ํ ์ ์์ต๋๋ค.",
|
| 248 |
+
"์ํ ํจํด: Public vs Private Zone ์ฌ์ฉ ์๋๋ฆฌ์ค, ๋ค์์๋ฒ ์์ ์ ์ฐจ, Azure ์๋น์ค์ DNS๋ณ์นญ(CNAME/alias) ์ฐ๊ฒฐ ๋ฐฉ๋ฒ์ด ์ถ์ ๋ฉ๋๋ค."
|
| 249 |
+
],
|
| 250 |
+
"level": "์ค๊ธ"
|
| 251 |
+
},
|
| 252 |
+
{
|
| 253 |
+
"id": "azure-blob-tier",
|
| 254 |
+
"certification": "AZ-104",
|
| 255 |
+
"title": "Blob Access Tier โ Blob ์ ๊ทผ ๊ณ์ธต",
|
| 256 |
+
"summary": "๋ฐ์ดํฐ ์ ๊ทผ ๋น๋์ ๋ฐ๋ผ HotยทCoolยทColdยทArchive ๊ณ์ธต์ ์ ํํด ์คํ ๋ฆฌ์ง ๋น์ฉ์ ์ต์ ํํฉ๋๋ค. ์ ์ฅ ๋น์ฉ๊ณผ ์ ๊ทผ ๋น์ฉ์ ๋ฐ๋น๋กํฉ๋๋ค.",
|
| 257 |
+
"example": "az storage blob set-tier \\\n --account-name myaccount \\\n --container-name mycontainer \\\n --name myblob.log \\\n --tier Cool",
|
| 258 |
+
"common_mistake": "Archive ๊ณ์ธต์ Blob์ ์ฆ์ ์ฝ์ ์ ์์ต๋๋ค. ์ฝ์ผ๋ ค๋ฉด Hot ๋๋ Cool๋ก rehydration(๋ช ์๊ฐ~15์๊ฐ)์ด ํ์ํฉ๋๋ค.",
|
| 259 |
+
"keywords": [
|
| 260 |
+
"blob tier",
|
| 261 |
+
"Hot",
|
| 262 |
+
"Cool",
|
| 263 |
+
"Cold",
|
| 264 |
+
"Archive",
|
| 265 |
+
"rehydration",
|
| 266 |
+
"lifecycle"
|
| 267 |
+
],
|
| 268 |
+
"source_id": "azure-blob-access-tiers",
|
| 269 |
+
"details": [
|
| 270 |
+
"๊ณ์ธต๋ณ ํน์ง: Hot(์์ฃผ ์ ๊ทผ, ๋์ ์ ์ฅ ๋น์ฉ ๋ฎ์ ์ ๊ทผ ๋น์ฉ), Cool(30์ผ ์ด์ ๋ณด๊ด), Cold(90์ผ ์ด์), Archive(180์ผ ์ด์, ์ ๊ทผ ๋น์ฉ ์ต๊ณ ).",
|
| 271 |
+
"Archive์์ ๊บผ๋ผ ๋ ์ฐ์ ์์: Standard(์ต๋ 15์๊ฐ), High Priority(1์๊ฐ ์ด๋ด, ๋น์).",
|
| 272 |
+
"์ํ ํจํด: ๊ณ์ธต๋ณ ์ต์ ๋ณด๊ด ๊ธฐ๊ฐ(Cool=30์ผ, Cold=90์ผ, Archive=180์ผ), ์กฐ๊ธฐ ์ญ์ ์ ์๊ธ ๋ถ๊ณผ, rehydration ์๊ฐ ๋ฌธ์ ๊ฐ ์ถ์ ๋ฉ๋๋ค."
|
| 273 |
+
],
|
| 274 |
+
"level": "์
๋ฌธ",
|
| 275 |
+
"related_practices": [
|
| 276 |
+
"azure-lab-7"
|
| 277 |
+
]
|
| 278 |
+
},
|
| 279 |
+
{
|
| 280 |
+
"id": "azure-log-analytics",
|
| 281 |
+
"certification": "AZ-104",
|
| 282 |
+
"title": "Log Analytics Workspace โ ๋ก๊ทธ ๋ถ์ ์์
์์ญ",
|
| 283 |
+
"summary": "Azure Monitor์ ๋ฐ์ดํฐ ์ ์ฅ์์
๋๋ค. VMยท์๋น์ค์ ๋ก๊ทธ์ ๋ฉํธ๋ฆญ์ ์์งํ๊ณ KQL(Kusto Query Language)๋ก ๋ถ์ํฉ๋๋ค.",
|
| 284 |
+
"example": "# KQL ์: ์ต๊ทผ 1์๊ฐ ์ค๋ฅ ๋ก๊ทธ\nEvent\n| where TimeGenerated > ago(1h)\n| where EventLevelName == 'Error'\n| summarize count() by Source",
|
| 285 |
+
"common_mistake": "Log Analytics๋ ์ ์ฅ์์ด๊ณ Azure Monitor๊ฐ ์์ง ์์ด์ ํธยท๊ฒฝ๋ณด๋ฅผ ํฌํจํ ํ๋ซํผ์
๋๋ค. ๋์ ํจ๊ป ๋์ํ๋ฉฐ ๋ณ๊ฐ์
๋๋ค.",
|
| 286 |
+
"keywords": [
|
| 287 |
+
"Log Analytics",
|
| 288 |
+
"KQL",
|
| 289 |
+
"workspace",
|
| 290 |
+
"diagnostic settings",
|
| 291 |
+
"MMA",
|
| 292 |
+
"AMA"
|
| 293 |
+
],
|
| 294 |
+
"source_id": "azure-log-analytics-overview",
|
| 295 |
+
"details": [
|
| 296 |
+
"๋ฐ์ดํฐ ์์ง: VM์ Azure Monitor Agent(AMA) ์ค์น ๋๋ Diagnostic Settings๋ก Azure ์๋น์ค ๋ก๊ทธ๋ฅผ Workspace๋ก ์ ์กํฉ๋๋ค.",
|
| 297 |
+
"KQL ํต์ฌ: `| where`, `| project`(์ปฌ๋ผ ์ ํ), `| summarize`(์ง๊ณ), `| order by`, `| take`(์์ N๊ฐ).",
|
| 298 |
+
"์ํ ํจํด: Diagnostic Settings ์ค์ ์ ์ฐจ, VM์ ์์ด์ ํธ ์ฐ๊ฒฐ, KQL ๊ธฐ๋ณธ ๊ตฌ๋ฌธ์ผ๋ก ๋ก๊ทธ๋ฅผ ์ฟผ๋ฆฌํ๋ ์๋๋ฆฌ์ค๊ฐ ์ถ์ ๋ฉ๋๋ค."
|
| 299 |
+
],
|
| 300 |
+
"level": "์ค๊ธ"
|
| 301 |
+
},
|
| 302 |
+
{
|
| 303 |
+
"id": "azure-recovery-vault",
|
| 304 |
+
"certification": "AZ-104",
|
| 305 |
+
"title": "Recovery Services Vault โ ๋ณต๊ตฌ ์๋น์ค ์๊ฒฉ ์ฆ๋ช
๋ชจ์",
|
| 306 |
+
"summary": "Azure Backup๊ณผ Site Recovery ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๋ ์ปจํ
์ด๋์
๋๋ค. VM, SQL, Files ๋ฑ์ ๋ฐฑ์
์ ์ฑ
์ ์ ์ํ๊ณ ๋ณต์ ์ง์ ์ ๊ด๋ฆฌํฉ๋๋ค.",
|
| 307 |
+
"example": "az backup vault create \\\n --name myVault \\\n --resource-group myRG \\\n --location koreacentral\naz backup protection enable-for-vm \\\n --vault-name myVault \\\n --vm myVM \\\n --policy-name DefaultPolicy",
|
| 308 |
+
"common_mistake": "Recovery Services Vault๋ ๋ฐฑ์
๋์ ๋ฆฌ์์ค์ ๊ฐ์ region์ ์์ด์ผ ํฉ๋๋ค. ๋ค๋ฅธ region์ VM์ ๋ฐฑ์
ํ ์ ์์ต๋๋ค.",
|
| 309 |
+
"keywords": [
|
| 310 |
+
"Recovery Services Vault",
|
| 311 |
+
"Azure Backup",
|
| 312 |
+
"backup policy",
|
| 313 |
+
"restore point",
|
| 314 |
+
"soft delete"
|
| 315 |
+
],
|
| 316 |
+
"source_id": "azure-recovery-services-vault",
|
| 317 |
+
"details": [
|
| 318 |
+
"๋ฐฑ์
์ ์ฑ
: ์ค์ผ์ค(์ผ๋ณ/์ฃผ๋ณ), ๋ณด์กด ๊ธฐ๊ฐ(์ผ/์ฃผ/์/๋
)์ ์ ์ํฉ๋๋ค. VM์ ๊ธฐ๋ณธ ์ ์ฑ
(์ผ 1ํ, 30์ผ ๋ณด์กด)์ผ๋ก ๋น ๋ฅด๊ฒ ์์ ๊ฐ๋ฅํฉ๋๋ค.",
|
| 319 |
+
"Soft Delete: ๋ฐฑ์
๋ฐ์ดํฐ๋ฅผ ์ญ์ ํ 14์ผ๊ฐ ๋ณต์ ๊ฐ๋ฅ ์ํ๋ก ์ ์งํฉ๋๋ค. ๋์ฌ์จ์ด ๊ณต๊ฒฉ์ผ๋ก๋ถํฐ ๋ณดํธํฉ๋๋ค.",
|
| 320 |
+
"์ํ ํจํด: ๋ฐฑ์
์ ์ฑ
๊ตฌ์ฑ, ๋ณต์ ์ ํ(์๋ ์์น/์ ์์น), ์ง์ญ ๊ฐ ๋ณต์(CRR) ๊ธฐ๋ฅ, Soft Delete ํ์ฑํ ๋ฐฉ๋ฒ์ด ์ถ์ ๋ฉ๋๋ค."
|
| 321 |
+
],
|
| 322 |
+
"level": "์ค๊ธ",
|
| 323 |
+
"related_practices": [
|
| 324 |
+
"azure-lab-8"
|
| 325 |
+
]
|
| 326 |
+
},
|
| 327 |
+
{
|
| 328 |
+
"id": "azure-entra-id",
|
| 329 |
+
"certification": "AZ-104",
|
| 330 |
+
"title": "Microsoft Entra ID โ ID ๊ด๋ฆฌ",
|
| 331 |
+
"summary": "Azure์ ํด๋ผ์ฐ๋ ๊ธฐ๋ฐ ID ๋ฐ ์ ๊ทผ ๊ด๋ฆฌ(IAM) ์๋น์ค์
๋๋ค(๊ตฌ Azure Active Directory). ์ฌ์ฉ์ยท๊ทธ๋ฃนยท์ ํ๋ฆฌ์ผ์ด์
ID๋ฅผ ๊ด๋ฆฌํ๊ณ MFA, ์กฐ๊ฑด๋ถ ์ ๊ทผ์ ์ ๊ณตํฉ๋๋ค.",
|
| 332 |
+
"example": "az ad user create \\\n --display-name 'Alice Kim' \\\n --user-principal-name alice@mydomain.com \\\n --password 'TempPass123!'\naz ad group create --display-name 'Developers' --mail-nickname 'devs'",
|
| 333 |
+
"common_mistake": "Entra ID์ ์จํ๋ ๋ฏธ์ค Active Directory๋ ๋ค๋ฅธ ์ ํ์
๋๋ค. Entra ID๋ ํด๋ผ์ฐ๋ LDAP/Kerberos๊ฐ ์๋๋ฉฐ, ๋๋ฉ์ธ ์กฐ์ธ์ Entra Domain Services๋ฅผ ์ฌ์ฉํฉ๋๋ค.",
|
| 334 |
+
"keywords": [
|
| 335 |
+
"Entra ID",
|
| 336 |
+
"AAD",
|
| 337 |
+
"tenant",
|
| 338 |
+
"user",
|
| 339 |
+
"group",
|
| 340 |
+
"MFA",
|
| 341 |
+
"SSO",
|
| 342 |
+
"B2B",
|
| 343 |
+
"B2C"
|
| 344 |
+
],
|
| 345 |
+
"source_id": "azure-rbac-overview",
|
| 346 |
+
"details": [
|
| 347 |
+
"ํ
๋ํธ(Tenant)๋ Entra ID์ ์ธ์คํด์ค์ด๋ฉฐ ์กฐ์ง ๋จ์์
๋๋ค. ๊ตฌ๋
์ ๋ฐ๋์ ํ๋์ ํ
๋ํธ์ ์ฐ๊ฒฐ๋ฉ๋๋ค.",
|
| 348 |
+
"์ฌ์ฉ์ ์ ํ: Member(๋ด๋ถ ์ฌ์ฉ์) vs Guest(B2B ์ด๋ ์ฌ์ฉ์). ๊ทธ๋ฃน ์ ํ: Security(RBAC ํ ๋น์ฉ) vs Microsoft 365.",
|
| 349 |
+
"์ํ ํจํด: ์ฌ์ฉ์/๊ทธ๋ฃน ์์ฑยท๊ด๋ฆฌ, ๊ฒ์คํธ ์ฌ์ฉ์ ์ด๋(B2B), MFA ๋ฑ๋ก, SSPR ์ค์ , Entra ID vs ์จํ๋ ๋ฏธ์ค AD ์ฐจ์ด๊ฐ ์ถ์ ๋ฉ๋๋ค."
|
| 350 |
+
],
|
| 351 |
+
"level": "์
๋ฌธ"
|
| 352 |
+
},
|
| 353 |
+
{
|
| 354 |
+
"id": "azure-management-group",
|
| 355 |
+
"certification": "AZ-104",
|
| 356 |
+
"title": "Management Group โ ๊ด๋ฆฌ ๊ทธ๋ฃน",
|
| 357 |
+
"summary": "์ฌ๋ฌ ๊ตฌ๋
์ ๊ณ์ธต์ ์ผ๋ก ๋ฌถ๋ ์ปจํ
์ด๋์
๋๋ค. ์ต์์ ๋ฃจํธ ๊ด๋ฆฌ ๊ทธ๋ฃน์์ RBAC์ Policy๋ฅผ ํ ๋นํ๋ฉด ํ์ ๊ตฌ๋
์ผ๋ก ์์๋ฉ๋๋ค.",
|
| 358 |
+
"example": "# ๊ณ์ธต ๊ตฌ์กฐ ์:\n# Root Management Group\n# โโ Production MG\n# โโ Sub-A\n# โโ Sub-B\naz account management-group create --name 'Production'",
|
| 359 |
+
"common_mistake": "๊ด๋ฆฌ ๊ทธ๋ฃน์ ์ต๋ 6๋จ๊ณ(๋ฃจํธ ํฌํจ)๊น์ง ์ค์ฒฉ ๊ฐ๋ฅํฉ๋๋ค. ๊ตฌ๋
์ ํ ๋ฒ์ ํ๋์ ๊ด๋ฆฌ ๊ทธ๋ฃน์๋ง ์ํ ์ ์์ต๋๋ค.",
|
| 360 |
+
"keywords": [
|
| 361 |
+
"management group",
|
| 362 |
+
"hierarchy",
|
| 363 |
+
"policy inheritance",
|
| 364 |
+
"RBAC",
|
| 365 |
+
"root",
|
| 366 |
+
"subscription"
|
| 367 |
+
],
|
| 368 |
+
"source_id": "azure-rbac-overview",
|
| 369 |
+
"details": [
|
| 370 |
+
"๋ฃจํธ ๊ด๋ฆฌ ๊ทธ๋ฃน์ ํ ๋นํ PolicyยทRBAC๋ ํ
๋ํธ์ ๋ชจ๋ ๊ตฌ๋
์ ์์๋ฉ๋๋ค. ์ ์ฌ ๊ท์ ์ ์ฉ์ ์ฌ์ฉ๋ฉ๋๋ค.",
|
| 371 |
+
"๊ด๋ฆฌ ๊ทธ๋ฃน ์ด๋: ๊ตฌ๋
์ด๋ ํ์ ๊ด๋ฆฌ ๊ทธ๋ฃน์ ๋ค๋ฅธ ๊ด๋ฆฌ ๊ทธ๋ฃน์ผ๋ก ์ด๋ํ ์ ์์ต๋๋ค.",
|
| 372 |
+
"์ํ ํจํด: ๊ด๋ฆฌ ๊ทธ๋ฃน ๊ณ์ธต ์ค๊ณ, Policy/RBAC ์์ ํ๋ฆ, ๊ด๋ฆฌ ๊ทธ๋ฃน vs ๊ตฌ๋
vs RG ๋ฒ์ ์ฐจ์ด ๋ฌธ์ ๊ฐ ์ถ์ ๋ฉ๋๋ค."
|
| 373 |
+
],
|
| 374 |
+
"level": "์
๋ฌธ"
|
| 375 |
+
},
|
| 376 |
+
{
|
| 377 |
+
"id": "azure-subscription",
|
| 378 |
+
"certification": "AZ-104",
|
| 379 |
+
"title": "Subscription โ ๊ตฌ๋
",
|
| 380 |
+
"summary": "Azure ๋ฆฌ์์ค๋ฅผ ๋ฐฐํฌํ๊ณ ๋น์ฉ์ ์ฒญ๊ตฌํ๋ ๊ธฐ๋ณธ ๋จ์์
๋๋ค. ๊ตฌ๋
๋ง๋ค ๋ฆฌ์์ค ํ๋(quota)๊ฐ ์์ผ๋ฉฐ ํ๋์ Entra ID ํ
๋ํธ์ ์ฐ๊ฒฐ๋ฉ๋๋ค.",
|
| 381 |
+
"example": "az account list --output table\naz account set --subscription 'My Subscription'\naz account show",
|
| 382 |
+
"common_mistake": "๊ตฌ๋
๊ณผ ํ
๋ํธ๋ 1:1์ด ์๋๋๋ค. ํ๋์ ํ
๋ํธ์ ์ฌ๋ฌ ๊ตฌ๋
์ด ์ํ ์ ์๊ณ , ๊ตฌ๋
์ ๋ค๋ฅธ ํ
๋ํธ๋ก ์ด์ ํ ์๋ ์์ต๋๋ค.",
|
| 383 |
+
"keywords": [
|
| 384 |
+
"subscription",
|
| 385 |
+
"tenant",
|
| 386 |
+
"quota",
|
| 387 |
+
"billing",
|
| 388 |
+
"az account"
|
| 389 |
+
],
|
| 390 |
+
"source_id": "azure-rbac-overview",
|
| 391 |
+
"details": [
|
| 392 |
+
"๊ตฌ๋
์ ํ: Pay-As-You-Go, Enterprise Agreement(EA), CSP(ํํธ๋ ์ ๊ณต) ๋ฑ. ๋น์ฉ ์ฒญ๊ตฌ ๊ณ์ ๊ณผ ์ฐ๊ฒฐ๋ฉ๋๋ค.",
|
| 393 |
+
"๋ฆฌ์์ค ํ๋(Quota)๋ ๊ตฌ๋
๋จ์๋ก ๊ด๋ฆฌ๋ฉ๋๋ค. ์: ํน์ region์ vCPU ์ต๋ ์. ํ๋ ์ฆ๊ฐ๋ Microsoft์ ์์ฒญํฉ๋๋ค.",
|
| 394 |
+
"์ํ ํจํด: ๊ตฌ๋
์ด๋(ํ
๋ํธ ๊ฐ), ๊ตฌ๋
๋ ๋ฒจ RBAC, Cost Management์์ ๊ตฌ๋
๋ณ ๋น์ฉ ๋ถ์ ์๋๋ฆฌ์ค๊ฐ ์ถ์ ๋ฉ๋๋ค."
|
| 395 |
+
],
|
| 396 |
+
"level": "์
๋ฌธ"
|
| 397 |
+
},
|
| 398 |
+
{
|
| 399 |
+
"id": "azure-resource-lock",
|
| 400 |
+
"certification": "AZ-104",
|
| 401 |
+
"title": "Resource Lock โ ๋ฆฌ์์ค ์ ๊ธ",
|
| 402 |
+
"summary": "์ค์๋ก ๋ฆฌ์์ค๋ฅผ ์์ ยท์ญ์ ํ์ง ๋ชปํ๋๋ก ๋ณดํธํฉ๋๋ค. ReadOnly(์์ ยท์ญ์ ์ฐจ๋จ)์ CanNotDelete(์ญ์ ๋ง ์ฐจ๋จ) ๋ ๊ฐ์ง๊ฐ ์์ต๋๋ค.",
|
| 403 |
+
"example": "az lock create \\\n --name 'prod-lock' \\\n --resource-group myRG \\\n --lock-type CanNotDelete\naz lock list --resource-group myRG",
|
| 404 |
+
"common_mistake": "Lock์ RBAC๋ณด๋ค ์ฐ์ ํฉ๋๋ค. Owner๋ผ๋ Lock์ด ๊ฑธ๋ฆฐ ๋ฆฌ์์ค๋ ์ ๊ธ์ ๋จผ์ ํด์ ํด์ผ ์์ ยท์ญ์ ํ ์ ์์ต๋๋ค.",
|
| 405 |
+
"keywords": [
|
| 406 |
+
"resource lock",
|
| 407 |
+
"CanNotDelete",
|
| 408 |
+
"ReadOnly",
|
| 409 |
+
"RBAC override"
|
| 410 |
+
],
|
| 411 |
+
"source_id": "azure-vm-overview",
|
| 412 |
+
"details": [
|
| 413 |
+
"ReadOnly Lock: ์ฝ๊ธฐ๋ ๊ฐ๋ฅํ์ง๋ง ์ฐ๊ธฐยท์ญ์ ๋ชจ๋ ์ฐจ๋จ. VM์ ๊ฑธ๋ฉด ์ฌ์์๋ ์ฐจ๋จ๋ ์ ์์ต๋๋ค.",
|
| 414 |
+
"Lock์ RG์ ์ค์ ํ๋ฉด ํ์ ๋ชจ๋ ๋ฆฌ์์ค์ ์์๋ฉ๋๋ค. ๊ฐ๋ณ ๋ฆฌ์์ค์๋ง ๊ฑธ ์๋ ์์ต๋๋ค.",
|
| 415 |
+
"์ํ ํจํด: Lock๊ณผ RBAC ์ํธ์์ฉ, CanNotDelete vs ReadOnly ์๋๋ฆฌ์ค, ์ ๊ธ ํด์ ์์ด ์ญ์ ์๋ ๊ฒฐ๊ณผ๊ฐ ์ถ์ ๋ฉ๋๋ค."
|
| 416 |
+
],
|
| 417 |
+
"level": "์
๋ฌธ",
|
| 418 |
+
"related_practices": [
|
| 419 |
+
"azure-lab-6"
|
| 420 |
+
]
|
| 421 |
+
},
|
| 422 |
+
{
|
| 423 |
+
"id": "azure-tags",
|
| 424 |
+
"certification": "AZ-104",
|
| 425 |
+
"title": "Tags โ ํ๊ทธ",
|
| 426 |
+
"summary": "๋ฆฌ์์ค์ ํค-๊ฐ ๋ฉํ๋ฐ์ดํฐ๋ฅผ ๋ถ์ฌ ๋ถ๋ฅยท๋น์ฉ ์ถ์ ยท์๋ํ์ ํ์ฉํฉ๋๋ค. RG์ ํ๊ทธ๋ ๋ด๋ถ ๋ฆฌ์์ค์ ์๋ ์์๋์ง ์์ต๋๋ค.",
|
| 427 |
+
"example": "az resource tag \\\n --tags Environment=Production CostCenter=IT \\\n --ids /subscriptions/SUB/resourceGroups/myRG\n# Policy๋ก ํ๊ทธ ๊ฐ์ :\n# 'Require a tag on resources'",
|
| 428 |
+
"common_mistake": "ํ๊ทธ๋ RG์์ ๋ด๋ถ ๋ฆฌ์์ค๋ก ์๋ ์์๋์ง ์์ต๋๋ค. ์์์ด ํ์ํ๋ฉด Azure Policy๋ก ํ๊ทธ ์์ ๊ท์น์ ์ ์ฉํด์ผ ํฉ๋๋ค.",
|
| 429 |
+
"keywords": [
|
| 430 |
+
"tags",
|
| 431 |
+
"key-value",
|
| 432 |
+
"cost center",
|
| 433 |
+
"environment",
|
| 434 |
+
"policy",
|
| 435 |
+
"inheritance"
|
| 436 |
+
],
|
| 437 |
+
"source_id": "azure-vm-overview",
|
| 438 |
+
"details": [
|
| 439 |
+
"๋ฆฌ์์ค๋น ์ต๋ 50๊ฐ์ ํ๊ทธ. ์ด๋ฆ ์ต๋ 512์, ๊ฐ ์ต๋ 256์(์คํ ๋ฆฌ์ง ๊ณ์ ์ ์ด๋ฆ 128์).",
|
| 440 |
+
"๋น์ฉ ๋ถ์์์ ํ๊ทธ๋ก ํํฐ๋งํ๋ฉด ๋ถ์๋ณยทํ๋ก์ ํธ๋ณ ๋น์ฉ์ ์ถ์ ํ ์ ์์ต๋๋ค.",
|
| 441 |
+
"์ํ ํจํด: ํ๊ทธ ์์ ์ ํ, Policy๋ฅผ ํตํ ํ๊ทธ ๊ฐ์ ์ ์ฉ, ๋น์ฉ ๋ถ์์์ ํ๊ทธ ํ์ฉ ์๋๋ฆฌ์ค๊ฐ ์ถ์ ๋ฉ๋๋ค."
|
| 442 |
+
],
|
| 443 |
+
"level": "์
๋ฌธ"
|
| 444 |
+
},
|
| 445 |
+
{
|
| 446 |
+
"id": "azure-custom-role",
|
| 447 |
+
"certification": "AZ-104",
|
| 448 |
+
"title": "Custom Role โ ์ฌ์ฉ์ ์ง์ ์ญํ ",
|
| 449 |
+
"summary": "๋ด์ฅ ์ญํ ์ด ๋๋ฌด ๊ด๋ฒ์ํ๊ฑฐ๋ ๋ถ์กฑํ ๋ ํน์ Actions๋ง ํ์ฉํ๋ ์ญํ ์ ์ง์ ๋ง๋ญ๋๋ค. JSON์ผ๋ก ActionsยทNotActionsยทDataActions๋ฅผ ์ ์ํฉ๋๋ค.",
|
| 450 |
+
"example": "{\n \"Name\": \"VM Operator\",\n \"Actions\": [\n \"Microsoft.Compute/virtualMachines/start/action\",\n \"Microsoft.Compute/virtualMachines/restart/action\",\n \"Microsoft.Compute/virtualMachines/read\"\n ],\n \"AssignableScopes\": [\"/subscriptions/SUB_ID\"]\n}",
|
| 451 |
+
"common_mistake": "Custom Role์ ํ
๋ํธ ๋ด์์ ๋ง๋ค์ง๋ง, AssignableScopes์ ์ง์ ํ ๊ตฌ๋
/RG ๋ฒ์์์๋ง ํ ๋นํ ์ ์์ต๋๋ค.",
|
| 452 |
+
"keywords": [
|
| 453 |
+
"custom role",
|
| 454 |
+
"Actions",
|
| 455 |
+
"NotActions",
|
| 456 |
+
"DataActions",
|
| 457 |
+
"AssignableScopes",
|
| 458 |
+
"JSON"
|
| 459 |
+
],
|
| 460 |
+
"source_id": "azure-rbac-overview",
|
| 461 |
+
"details": [
|
| 462 |
+
"Actions: ๊ด๋ฆฌ ํ๋ฉด ์์
ํ์ฉ. NotActions: Actions์์ ์ ์ธํ ์์
. DataActions: ๋ฐ์ดํฐ ํ๋ฉด ์์
(Blob ์ฝ๊ธฐ ๋ฑ).",
|
| 463 |
+
"๊ธฐ์กด ๋ด์ฅ ์ญํ ์ ๋ณต์ฌํด ์์ ํ๋ ๋ฐฉ์์ด ํธ๋ฆฌํฉ๋๋ค: `az role definition list --name 'Contributor'`๋ก ์์.",
|
| 464 |
+
"์ํ ํจํด: ์ต์ ๊ถํ ์์น์ ๋ฐ๋ฅธ Custom Role Actions ์ค๊ณ, DataActions vs Actions ์ฐจ์ด, AssignableScopes ์ค์ ์ด ์ถ์ ๋ฉ๋๋ค."
|
| 465 |
+
],
|
| 466 |
+
"level": "์ค๊ธ"
|
| 467 |
+
},
|
| 468 |
+
{
|
| 469 |
+
"id": "azure-sas",
|
| 470 |
+
"certification": "AZ-104",
|
| 471 |
+
"title": "Shared Access Signature โ SAS",
|
| 472 |
+
"summary": "์คํ ๋ฆฌ์ง ๊ณ์ ์ ์ฒด๋ฅผ ๋
ธ์ถํ์ง ์๊ณ ํน์ ๋ฆฌ์์ค์ ์ ํ๋ ๊ถํ๊ณผ ์๊ฐ ๋ฒ์์ ์ ๊ทผ์ ํ์ฉํ๋ ์๋ช
๋ URL์
๋๋ค.",
|
| 473 |
+
"example": "az storage blob generate-sas \\\n --account-name myaccount \\\n --container-name data \\\n --name report.pdf \\\n --permissions r \\\n --expiry 2024-12-31",
|
| 474 |
+
"common_mistake": "SAS URL์ด ๋
ธ์ถ๋๋ฉด ๋ง๋ฃ ์ ๊น์ง ๋๊ตฌ๋ ์ ๊ทผ ๊ฐ๋ฅํฉ๋๋ค. ๋ฏผ๊ฐํ ๋ฐ์ดํฐ๋ ์งง์ ๋ง๋ฃ ์๊ฐ์ ์ค์ ํ๊ณ , SAS๋ฅผ ์ ์ฅํ Stored Access Policy๋ฅผ ์ฌ์ฉํด ์ฆ์ ์ทจ์ํ ์ ์์ต๋๋ค.",
|
| 475 |
+
"keywords": [
|
| 476 |
+
"SAS",
|
| 477 |
+
"Service SAS",
|
| 478 |
+
"Account SAS",
|
| 479 |
+
"User Delegation SAS",
|
| 480 |
+
"expiry",
|
| 481 |
+
"stored access policy"
|
| 482 |
+
],
|
| 483 |
+
"source_id": "azure-storage-account",
|
| 484 |
+
"details": [
|
| 485 |
+
"SAS ์ ํ: Account SAS(์ ์ฒด ์คํ ๋ฆฌ์ง ์๋น์ค), Service SAS(ํน์ ์๋น์ค), User Delegation SAS(Entra ID ์๊ฒฉ ์ฆ๋ช
๊ธฐ๋ฐ, ๊ฐ์ฅ ์์ ).",
|
| 486 |
+
"Stored Access Policy: ์๋น์ค SAS๋ฅผ ์ ์ฑ
์ ์ฐ๊ฒฐํ๋ฉด URL์ ์ฌ๋ฐ๊ธํ์ง ์๊ณ ์ ์ฑ
์ญ์ ๋ง์ผ๋ก ์ ๊ทผ์ ์ฆ์ ์ทจ์ํ ์ ์์ต๋๋ค.",
|
| 487 |
+
"์ํ ํจํด: SAS ์ ํ ์ ํ, ๊ถํยท๋ง๋ฃ ์ค์ , Stored Access Policy๋ฅผ ํตํ ์ทจ์ ๋ฐฉ๋ฒ, ํค ๊ธฐ๋ฐ vs Entra ID ๊ธฐ๋ฐ SAS ์ฐจ์ด๊ฐ ์ถ์ ๋ฉ๋๋ค."
|
| 488 |
+
],
|
| 489 |
+
"level": "์ค๊ธ"
|
| 490 |
+
},
|
| 491 |
+
{
|
| 492 |
+
"id": "azure-storage-redundancy",
|
| 493 |
+
"certification": "AZ-104",
|
| 494 |
+
"title": "Storage Redundancy โ ์คํ ๋ฆฌ์ง ์ค๋ณต์ฑ",
|
| 495 |
+
"summary": "๋ฐ์ดํฐ๋ฅผ ๋ณต์ ํด ๊ฐ์ฉ์ฑ๊ณผ ๋ด๊ตฌ์ฑ์ ๋ณด์ฅํฉ๋๋ค. ๋ณต์ ๋ฒ์(๋จ์ผ ๋ฐ์ดํฐ์ผํฐโAZโ๋ค๋ฅธ region)์ ๋ฐ๋ผ LRSยทZRSยทGRSยทGZRS ์ค ์ ํํฉ๋๋ค.",
|
| 496 |
+
"example": "# ์์ฑ ์ SKU๋ก ๊ฒฐ์ \naz storage account create --sku Standard_GRS ...\n# ๋ณ๊ฒฝ (์ผ๋ถ๋ง ๊ฐ๋ฅ)\naz storage account update --sku Standard_RAGRS --name myaccount",
|
| 497 |
+
"common_mistake": "GRS๋ ๋ณด์กฐ ์ง์ญ์ ๋ฐ์ดํฐ๋ฅผ ๋ณต์ ํ์ง๋ง ๊ธฐ๋ณธ์ ์ผ๋ก ์ฝ๊ธฐ ๋ถ๊ฐ์
๋๋ค. ๋ณด์กฐ ์ง์ญ ์ฝ๊ธฐ๋ฅผ ํ์ฉํ๋ ค๋ฉด RA-GRS(Read-Access GRS)๋ก ์ค์ ํด์ผ ํฉ๋๋ค.",
|
| 498 |
+
"keywords": [
|
| 499 |
+
"LRS",
|
| 500 |
+
"ZRS",
|
| 501 |
+
"GRS",
|
| 502 |
+
"GZRS",
|
| 503 |
+
"RA-GRS",
|
| 504 |
+
"redundancy",
|
| 505 |
+
"replication"
|
| 506 |
+
],
|
| 507 |
+
"source_id": "azure-storage-account",
|
| 508 |
+
"details": [
|
| 509 |
+
"LRS: ๋จ์ผ datacenter ๋ด 3๋ณต์ . ZRS: ๋์ผ region 3๊ฐ AZ์ ๋ณต์ . GRS: ๋ค๋ฅธ region์ ๋น๋๊ธฐ ๋ณต์ (LRSร2). GZRS: ZRS+GRS.",
|
| 510 |
+
"๋ด๊ตฌ์ฑ(nines): LRS=11 9s, ZRS=12 9s, GRS=16 9s. ๋น์ฉ์ LRS<ZRS<GRS<GZRS ์์
๋๋ค.",
|
| 511 |
+
"์ํ ํจํด: ์๊ตฌ์ฌํญ(AZ ์ฅ์ ๋ณดํธ, region ์ฅ์ ๋ณดํธ)์ ๋ฐ๋ฅธ ์ค๋ณต์ฑ ์ ํ, RA-GRS์์ ๋ณด์กฐ ์ง์ญ ์ ๊ทผ ๋ฐฉ๋ฒ์ด ์ถ์ ๋ฉ๋๋ค."
|
| 512 |
+
],
|
| 513 |
+
"level": "์ค๊ธ"
|
| 514 |
+
},
|
| 515 |
+
{
|
| 516 |
+
"id": "azure-lifecycle",
|
| 517 |
+
"certification": "AZ-104",
|
| 518 |
+
"title": "Storage Lifecycle Management โ ์คํ ๋ฆฌ์ง ์๋ช
์ฃผ๊ธฐ",
|
| 519 |
+
"summary": "Blob์ ์ผ์ ๊ธฐ๊ฐ ํ ์๋์ผ๋ก ๊ณ์ธต ์ ํ(HotโCoolโArchive)ํ๊ฑฐ๋ ์ญ์ ํ๋ ์ ์ฑ
์ ์ ์ํฉ๋๋ค. ๋น์ฉ ์๋ ์ต์ ํ์ ํ์ฉํฉ๋๋ค.",
|
| 520 |
+
"example": "# ๊ท์น ์: 30์ผ ํ Cool, 90์ผ ํ Archive, 365์ผ ํ ์ญ์ \n{\n \"rules\": [{\n \"action\": {\"baseBlob\": {\n \"tierToCool\": {\"daysAfterModificationGreaterThan\": 30},\n \"tierToArchive\": {\"daysAfterModificationGreaterThan\": 90},\n \"delete\": {\"daysAfterModificationGreaterThan\": 365}\n }}\n }]\n}",
|
| 521 |
+
"common_mistake": "์๋ช
์ฃผ๊ธฐ ์ ์ฑ
์ Blob ๋ ๋ฒจ์์๋ง ๋์ํฉ๋๋ค. ์ด๋ฏธ Archive ๊ณ์ธต์ธ Blob์ ์ ์ฑ
์ด ๋ค์ Archive๋ก ์ ํํ์ง ์์ต๋๋ค.",
|
| 522 |
+
"keywords": [
|
| 523 |
+
"lifecycle policy",
|
| 524 |
+
"tier transition",
|
| 525 |
+
"Hot",
|
| 526 |
+
"Cool",
|
| 527 |
+
"Archive",
|
| 528 |
+
"delete",
|
| 529 |
+
"daysAfterModification"
|
| 530 |
+
],
|
| 531 |
+
"source_id": "azure-blob-access-tiers",
|
| 532 |
+
"details": [
|
| 533 |
+
"์กฐ๊ฑด ๊ธฐ์ค: ๋ง์ง๋ง ์์ ๋ ์ง, ๋ง์ง๋ง ์ ๊ทผ ๋ ์ง(์ ๊ทผ ์ถ์ ํ์ฑํ ํ์), blob ์์ฑ ๋ ์ง ์ค ์ ํํฉ๋๋ค.",
|
| 534 |
+
"ํํฐ๋ก ํน์ ์ปจํ
์ด๋, ์ ๋์ฌ, blob ์ ํ(blockBlob/appendBlob)์๋ง ์ ์ฑ
์ ์ ์ฉํ ์ ์์ต๋๋ค.",
|
| 535 |
+
"์ํ ํจํด: ํน์ ๋น์ฉ ์ต์ ํ ์๋๋ฆฌ์ค์์ lifecycle ์ ์ฑ
๊ท์น ์์ฑ, ์กฐ๊ฑด๋ณ ๊ณ์ธต ์ ํ ์์, ์ญ์ ํฌํจ ์ ์ฒด ํ๋ฆ์ด ์ถ์ ๋ฉ๋๋ค."
|
| 536 |
+
],
|
| 537 |
+
"level": "์ค๊ธ"
|
| 538 |
+
},
|
| 539 |
+
{
|
| 540 |
+
"id": "azure-files",
|
| 541 |
+
"certification": "AZ-104",
|
| 542 |
+
"title": "Azure Files โ ํ์ผ ๊ณต์ ",
|
| 543 |
+
"summary": "SMB/NFS ํ๋กํ ์ฝ๋ก ๋ง์ดํธํ๋ ์์ ๊ด๋ฆฌํ ํด๋ผ์ฐ๋ ํ์ผ ๊ณต์ ์
๋๋ค. VMยท์จํ๋ ๋ฏธ์คยท์ปจํ
์ด๋์์ ๋คํธ์ํฌ ๋๋ผ์ด๋ธ์ฒ๋ผ ์ฌ์ฉํฉ๋๋ค.",
|
| 544 |
+
"example": "# Windows์์ ๋ง์ดํธ\nnet use Z: \\\\myaccount.file.core.windows.net\\myshare /user:myaccount [key]\n# Linux์์ ๋ง์ดํธ\nmount -t cifs //myaccount.file.core.windows.net/myshare /mnt -o user=myaccount,password=[key]",
|
| 545 |
+
"common_mistake": "Azure Files SMB๋ ํฌํธ 445๋ฅผ ์ฌ์ฉํฉ๋๋ค. ์ผ๋ถ ISP์ ๊ธฐ์
๋ฐฉํ๋ฒฝ์ด 445๋ฅผ ์ฐจ๋จํด ๋ง์ดํธ๊ฐ ์คํจํ๋ ๊ฒฝ์ฐ๊ฐ ์์ต๋๋ค.",
|
| 546 |
+
"keywords": [
|
| 547 |
+
"Azure Files",
|
| 548 |
+
"SMB",
|
| 549 |
+
"NFS",
|
| 550 |
+
"file share",
|
| 551 |
+
"port 445",
|
| 552 |
+
"Azure File Sync"
|
| 553 |
+
],
|
| 554 |
+
"source_id": "azure-storage-account",
|
| 555 |
+
"details": [
|
| 556 |
+
"์ฑ๋ฅ ๊ณ์ธต: Standard(HDD ๊ธฐ๋ฐ), Premium(SSD ๊ธฐ๋ฐ). Premium์ ๋ฎ์ ์ง์ฐ์๊ฐ์ด ํ์ํ ์ํฌ๋ก๋์ ์ฌ์ฉํฉ๋๋ค.",
|
| 557 |
+
"Azure File Sync: ์จํ๋ ๋ฏธ์ค ํ์ผ ์๋ฒ์ Azure Files๋ฅผ ๋๊ธฐํํ๊ณ , ์์ฃผ ์ฐ์ง ์๋ ํ์ผ์ Cloud Tiering์ผ๋ก Azure์ ์ฌ๋ฆฝ๋๋ค.",
|
| 558 |
+
"์ํ ํจํด: Blob vs Files ์ ํ ๊ธฐ์ค(ํ์ผ ์์คํ
๋ง์ดํธ ํ์ ์ฌ๋ถ), Azure File Sync ์ํคํ
์ฒ, ํฌํธ 445 ๋ฌธ์ ํด๊ฒฐ์ด ์ถ์ ๋ฉ๋๋ค."
|
| 559 |
+
],
|
| 560 |
+
"level": "์ค๊ธ"
|
| 561 |
+
},
|
| 562 |
+
{
|
| 563 |
+
"id": "azure-managed-disk",
|
| 564 |
+
"certification": "AZ-104",
|
| 565 |
+
"title": "Managed Disk โ ๊ด๋ฆฌ ๋์คํฌ",
|
| 566 |
+
"summary": "VM์ ์ฐ๊ฒฐํ๋ ๋ธ๋ก ์คํ ๋ฆฌ์ง์
๋๋ค. OS ๋์คํฌ์ ๋ฐ์ดํฐ ๋์คํฌ๋ก ๋๋๋ฉฐ, ์ฑ๋ฅ ์๊ตฌ์ ๋ฐ๋ผ Standard HDDยทStandard SSDยทPremium SSDยทUltra Disk๋ฅผ ์ ํํฉ๋๋ค.",
|
| 567 |
+
"example": "az disk create \\\n --name myDataDisk \\\n --resource-group myRG \\\n --size-gb 128 \\\n --sku Premium_LRS\naz vm disk attach --vm-name myVM --name myDataDisk",
|
| 568 |
+
"common_mistake": "๊ด๋ฆฌ ๋์คํฌ ํฌ๊ธฐ๋ ๋๋ฆด ์๋ง ์๊ณ ์ค์ผ ์ ์์ต๋๋ค. ํฌ๊ธฐ๋ฅผ ์ค์ด๋ ค๋ฉด ์ ์์ ๋์คํฌ๋ฅผ ๋ง๋ค๊ณ ๋ฐ์ดํฐ๋ฅผ ์ด์ ํด์ผ ํฉ๋๋ค.",
|
| 569 |
+
"keywords": [
|
| 570 |
+
"managed disk",
|
| 571 |
+
"OS disk",
|
| 572 |
+
"data disk",
|
| 573 |
+
"Premium SSD",
|
| 574 |
+
"Ultra Disk",
|
| 575 |
+
"snapshot",
|
| 576 |
+
"disk encryption"
|
| 577 |
+
],
|
| 578 |
+
"source_id": "azure-storage-account",
|
| 579 |
+
"details": [
|
| 580 |
+
"SKU ์ ํ: Standard HDD(๋น์ฉ ์ต์ , ๋ฐฑ์
์ฉ), Standard SSD(์ผ๋ฐ ์ํฌ๋ก๋), Premium SSD(I/O ์ง์ฝ ์ฑ), Ultra Disk(DB, ์ต์ ์ง์ฐ).",
|
| 581 |
+
"์ค๋
์ท: ํน์ ์์ ์ ๋์คํฌ ์ํ๋ฅผ ์บก์ฒ. ๋ค๋ฅธ region์ ๋ณต์ฌํด ์ฌํด ๋ณต๊ตฌ์ ํ์ฉํ ์ ์์ต๋๋ค.",
|
| 582 |
+
"์ํ ํจํด: ์ํฌ๋ก๋๋ณ ๋์คํฌ SKU ์ ํ, ๋์คํฌ ํ์ฅ ํ OS์์ ํํฐ์
ํ์ฅ ํ์ ์ฌ๋ถ, ์ค๋
์ท vs ๋ฐฑ์
์ฐจ์ด๊ฐ ์ถ์ ๋ฉ๋๋ค."
|
| 583 |
+
],
|
| 584 |
+
"level": "์
๋ฌธ"
|
| 585 |
+
},
|
| 586 |
+
{
|
| 587 |
+
"id": "azure-availability-set",
|
| 588 |
+
"certification": "AZ-104",
|
| 589 |
+
"title": "Availability Set โ ๊ฐ์ฉ์ฑ ์งํฉ",
|
| 590 |
+
"summary": "๋์ผ ๋ฐ์ดํฐ์ผํฐ ๋ด์์ VM์ ๋ค๋ฅธ ๋ฌผ๋ฆฌ ๋(์ฅ์ ๋๋ฉ์ธ)๊ณผ ์
๋ฐ์ดํธ ๊ทธ๋ฃน(์
๋ฐ์ดํธ ๋๋ฉ์ธ)์ ๋ฐฐ์นํด ๋จ์ผ ์ฅ์ ์ ์ ์์ฑ๋๋ค.",
|
| 591 |
+
"example": "az vm availability-set create \\\n --name myAS \\\n --resource-group myRG \\\n --platform-fault-domain-count 2 \\\n --platform-update-domain-count 5",
|
| 592 |
+
"common_mistake": "Availability Set์ ๋จ์ผ ๋ฐ์ดํฐ์ผํฐ ๋ด ๋ณดํธ์
๋๋ค. ๋ฐ์ดํฐ์ผํฐ ์ ์ฒด ์ฅ์ ๋ AZ ์ฅ์ ์ ๋์ํ๋ ค๋ฉด Availability Zones๋ฅผ ์ฌ์ฉํด์ผ ํฉ๋๋ค.",
|
| 593 |
+
"keywords": [
|
| 594 |
+
"availability set",
|
| 595 |
+
"fault domain",
|
| 596 |
+
"update domain",
|
| 597 |
+
"UD",
|
| 598 |
+
"FD",
|
| 599 |
+
"SLA 99.95%"
|
| 600 |
+
],
|
| 601 |
+
"source_id": "azure-vm-overview",
|
| 602 |
+
"details": [
|
| 603 |
+
"์ฅ์ ๋๋ฉ์ธ(FD): ๊ณต์ ์ ์ยท๋คํธ์ํฌ ์ค์์น ๊ธฐ์ค ๋ฌผ๋ฆฌ ๋ ๋ถ๋ฆฌ. ๊ธฐ๋ณธ ์ต๋ 3๊ฐ.",
|
| 604 |
+
"์
๋ฐ์ดํธ ๋๋ฉ์ธ(UD): ๊ณํ๋ ์ ์ง ๊ด๋ฆฌ ์ ๋์์ ์ฌ์์ํ์ง ์๋ ๊ทธ๋ฃน. ๊ธฐ๋ณธ 5๊ฐ(์ต๋ 20๊ฐ).",
|
| 605 |
+
"์ํ ํจํด: AS vs AZ ๋ณดํธ ์์ค ์ฐจ์ด, SLA(AS=99.95%, ๋จ์ผVM-Premium=99.9%, AZ=99.99%), AS์ VM ์ถ๊ฐ ์๊ธฐ ์ ํ์ด ์ถ์ ๋ฉ๋๋ค."
|
| 606 |
+
],
|
| 607 |
+
"level": "์
๋ฌธ"
|
| 608 |
+
},
|
| 609 |
+
{
|
| 610 |
+
"id": "azure-autoscale",
|
| 611 |
+
"certification": "AZ-104",
|
| 612 |
+
"title": "Autoscale โ ์๋ ํฌ๊ธฐ ์กฐ์ ",
|
| 613 |
+
"summary": "๋ฉํธ๋ฆญ(CPU, ๋ฉ๋ชจ๋ฆฌ, ํ ๊ธธ์ด ๋ฑ)์ด๋ ์ผ์ ์ ๋ฐ๋ผ VM Scale Set ๋๋ App Service์ ์ธ์คํด์ค ์๋ฅผ ์๋์ผ๋ก ๋๋ฆฌ๊ณ ์ค์
๋๋ค.",
|
| 614 |
+
"example": "# Autoscale ๊ท์น ์:\n# CPU > 70% 5๋ถ ์ ์ง โ +1 ์ธ์คํด์ค ์ถ๊ฐ\n# CPU < 30% 5๋ถ ์ ์ง โ -1 ์ธ์คํด์ค ์ ๊ฑฐ\n# ์ต์ 2, ์ต๋ 10 ์ธ์คํด์ค",
|
| 615 |
+
"common_mistake": "Scale-out(์ถ๊ฐ)๊ณผ Scale-in(์ ๊ฑฐ) ๊ท์น์ ๋ชจ๋ ์ค์ ํด์ผ ํฉ๋๋ค. Scale-out๋ง ์ค์ ํ๋ฉด ์ธ์คํด์ค๊ฐ ์ค์ด๋ค์ง ์์ ๋น์ฉ๏ฟฝ๏ฟฝ ๊ณ์ ์ฆ๊ฐํฉ๋๋ค.",
|
| 616 |
+
"keywords": [
|
| 617 |
+
"autoscale",
|
| 618 |
+
"scale-out",
|
| 619 |
+
"scale-in",
|
| 620 |
+
"metric",
|
| 621 |
+
"cooldown",
|
| 622 |
+
"min/max instances"
|
| 623 |
+
],
|
| 624 |
+
"source_id": "azure-vmss-overview",
|
| 625 |
+
"details": [
|
| 626 |
+
"๋๊ฐ ๊ธฐ๊ฐ(Cooldown): Scale ๋์ ํ ๋ค์ ๋์๊น์ง ๊ธฐ๋ค๋ฆฌ๋ ์๊ฐ. ๋๋ฌด ์งง์ผ๋ฉด ์ง๋(flapping) ํ์์ด ๋ฐ์ํฉ๋๋ค.",
|
| 627 |
+
"์ผ์ ๊ธฐ๋ฐ Autoscale: ํน์ ์์ผยท์๊ฐ๋์ ์ธ์คํด์ค ์๋ฅผ ๊ณ ์ ํ๊ฑฐ๋ ๋๋ฆด ์ ์์ต๋๋ค.",
|
| 628 |
+
"์ํ ํจํด: Scale-in/out ๊ท์น ์ค๊ณ, ๋๊ฐ ๊ธฐ๊ฐ ๊ฐ๋
, ๋ฉํธ๋ฆญ ๊ธฐ๋ฐ vs ์ผ์ ๊ธฐ๋ฐ ์ ํ, VMSS์ App Service์ Autoscale ์ฐจ์ด๊ฐ ์ถ์ ๋ฉ๋๋ค."
|
| 629 |
+
],
|
| 630 |
+
"level": "์ค๊ธ"
|
| 631 |
+
},
|
| 632 |
+
{
|
| 633 |
+
"id": "azure-vnet-peering",
|
| 634 |
+
"certification": "AZ-104",
|
| 635 |
+
"title": "VNet Peering โ ๊ฐ์ ๋คํธ์ํฌ ํผ์ด๋ง",
|
| 636 |
+
"summary": "๋ VNet์ Microsoft ๋ฐฑ๋ณธ ๋คํธ์ํฌ๋ก ์ง์ ์ฐ๊ฒฐํฉ๋๋ค. ๋์ผ region(Local Peering)๊ณผ ๋ค๋ฅธ region(Global Peering) ๋ชจ๋ ๊ฐ๋ฅํฉ๋๋ค.",
|
| 637 |
+
"example": "az network vnet peering create \\\n --name VNet1-to-VNet2 \\\n --vnet-name VNet1 \\\n --remote-vnet VNet2 \\\n --resource-group myRG\n# ๋ฐ๋ ๋ฐฉํฅ๋ ์์ฑํด์ผ ํจ",
|
| 638 |
+
"common_mistake": "ํผ์ด๋ง์ ๋น์ ์ด์ (non-transitive)์
๋๋ค. AโB, BโC๋ก ํผ์ด๋งํด๋ A์์ C๋ก ์ง์ ํต์ ํ ์ ์์ต๋๋ค. AโC๋ฅผ ๋ณ๋๋ก ์ค์ ํด์ผ ํฉ๋๋ค.",
|
| 639 |
+
"keywords": [
|
| 640 |
+
"VNet peering",
|
| 641 |
+
"non-transitive",
|
| 642 |
+
"local peering",
|
| 643 |
+
"global peering",
|
| 644 |
+
"transit"
|
| 645 |
+
],
|
| 646 |
+
"source_id": "azure-vnet-overview",
|
| 647 |
+
"details": [
|
| 648 |
+
"ํผ์ด๋ง ์กฐ๊ฑด: ๋ VNet์ ์ฃผ์ ๊ณต๊ฐ์ด ๊ฒน์น์ง ์์์ผ ํฉ๋๋ค. ํผ์ด๋ง์ ์๋ฐฉํฅ ์ค์ ์ด ๊ฐ๊ฐ ํ์ํฉ๋๋ค.",
|
| 649 |
+
"๊ฒ์ดํธ์จ์ด ์ ์ก(Gateway Transit): ํผ์ด๋ง๋ VNet์ด ํ๋ธ์ VPN Gateway๋ฅผ ๊ณต์ ํด ์จํ๋ ๋ฏธ์ค ์ฐ๊ฒฐ์ ํ์ฉํฉ๋๋ค.",
|
| 650 |
+
"์ํ ํจํด: ๋น์ ์ด์ฑ์ผ๋ก ์ธํ ์ฐ๊ฒฐ ๋ถ๊ฐ ์๋๋ฆฌ์ค, ์ฃผ์ ๊ณต๊ฐ ์ค์ฒฉ ์ค๋ฅ, Gateway Transit ์ค์ ๋ฐฉ๋ฒ์ด ์์ฃผ ์ถ์ ๋ฉ๋๋ค."
|
| 651 |
+
],
|
| 652 |
+
"level": "์ค๊ธ",
|
| 653 |
+
"related_practices": [
|
| 654 |
+
"azure-lab-10"
|
| 655 |
+
]
|
| 656 |
+
},
|
| 657 |
+
{
|
| 658 |
+
"id": "azure-route-table",
|
| 659 |
+
"certification": "AZ-104",
|
| 660 |
+
"title": "Route Table โ ๊ฒฝ๋ก ํ
์ด๋ธ",
|
| 661 |
+
"summary": "์๋ธ๋ท์ ํธ๋ํฝ ๊ฒฝ๋ก๋ฅผ ์ฌ์ฉ์ ์ ์ํฉ๋๋ค(UDR: User-Defined Route). ๊ธฐ๋ณธ ์์คํ
๊ฒฝ๋ก๋ฅผ ์ฌ์ ์ํด ํธ๋ํฝ์ NVA, VPN GW, VNet Gateway ๋ฑ์ผ๋ก ๋ณด๋
๋๋ค.",
|
| 662 |
+
"example": "az network route-table create --name myRT --resource-group myRG\naz network route-table route create \\\n --route-table-name myRT \\\n --name force-to-firewall \\\n --address-prefix 0.0.0.0/0 \\\n --next-hop-type VirtualAppliance \\\n --next-hop-ip-address 10.0.1.4",
|
| 663 |
+
"common_mistake": "๊ฒฝ๋ก ํ
์ด๋ธ์ ์๋ธ๋ท์ ์ฐ๊ฒฐํด์ผ ํจ๊ณผ๊ฐ ๋ฉ๋๋ค. Route Table์ ๋ง๋ค๊ธฐ๋ง ํ๊ณ ์๋ธ๋ท์ ์ฐ๊ฒฐ(association)ํ์ง ์์ผ๋ฉด ์ ์ฉ๋์ง ์์ต๋๋ค.",
|
| 664 |
+
"keywords": [
|
| 665 |
+
"route table",
|
| 666 |
+
"UDR",
|
| 667 |
+
"next hop",
|
| 668 |
+
"NVA",
|
| 669 |
+
"VirtualAppliance",
|
| 670 |
+
"subnet association"
|
| 671 |
+
],
|
| 672 |
+
"source_id": "azure-vnet-overview",
|
| 673 |
+
"details": [
|
| 674 |
+
"Next hop ์ ํ: VirtualAppliance(๋ฐฉํ๋ฒฝ NVA), VirtualNetworkGateway(VPN), Internet, VnetLocal, None(ํธ๋ํฝ ๋๋กญ).",
|
| 675 |
+
"๊ฐ์ ํฐ๋๋ง(Force Tunneling): 0.0.0.0/0์ VPN Gateway๋ก ๋ณด๋ด ์ธํฐ๋ท ํธ๋ํฝ๋ ์จํ๋ ๋ฏธ์ค ๊ฒฝ์ ํ๊ฒ ํฉ๋๋ค.",
|
| 676 |
+
"์ํ ํจํด: ํน์ ํธ๋ํฝ์ NVA๋ก ์ฐํํ๋ UDR ์ค๊ณ, ๊ฐ์ ํฐ๋๋ง ๊ตฌ์ฑ, ์์คํ
๊ฒฝ๋ก vs ์ฌ์ฉ์ ๊ฒฝ๋ก ์ฐ์ ์์๊ฐ ์ถ์ ๋ฉ๋๋ค."
|
| 677 |
+
],
|
| 678 |
+
"level": "์ค๊ธ"
|
| 679 |
+
},
|
| 680 |
+
{
|
| 681 |
+
"id": "azure-private-endpoint",
|
| 682 |
+
"certification": "AZ-104",
|
| 683 |
+
"title": "Private Endpoint โ ํ๋ผ์ด๋น ์๋ํฌ์ธํธ",
|
| 684 |
+
"summary": "Azure PaaS ์๋น์ค(Storage, SQL, Key Vault ๋ฑ)์ VNet ๋ด ์ฌ์ค IP๋ก ์ ๊ทผํฉ๋๋ค. ์ธํฐ๋ท์ ํตํ์ง ์์ ๋ฐ์ดํฐ ๋
ธ์ถ ์ํ์ ์ค์
๋๋ค.",
|
| 685 |
+
"example": "az network private-endpoint create \\\n --name myPE \\\n --resource-group myRG \\\n --vnet-name myVNet \\\n --subnet default \\\n --private-connection-resource-id /subscriptions/.../storageAccounts/myaccount \\\n --group-ids blob",
|
| 686 |
+
"common_mistake": "Private Endpoint ์์ฑ ํ DNS ์ค์ ์ ์ถ๊ฐํด์ผ ํฉ๋๋ค. Private DNS Zone๊ณผ ์ฐ๊ฒฐํ์ง ์์ผ๋ฉด ๊ณต์ฉ DNS๊ฐ Public IP๋ฅผ ๋ฐํํด ์ธํฐ๋ท ๊ฒฝ๋ก๋ก ์ ์๋ฉ๋๋ค.",
|
| 687 |
+
"keywords": [
|
| 688 |
+
"private endpoint",
|
| 689 |
+
"private link",
|
| 690 |
+
"private IP",
|
| 691 |
+
"DNS zone",
|
| 692 |
+
"Service Endpoint ์ฐจ์ด"
|
| 693 |
+
],
|
| 694 |
+
"source_id": "azure-private-endpoint",
|
| 695 |
+
"details": [
|
| 696 |
+
"Private Endpoint vs Service Endpoint: Private Endpoint๋ VNet์ ์ฌ์ค IP๋ฅผ ๋ถ์ฌ(๋ ์์ ), Service Endpoint๋ Public IP ์ ์งํ๋ VNet์์๋ง ํ์ฉ.",
|
| 697 |
+
"Private DNS Zone ์๋ ํตํฉ: Private Endpoint ์์ฑ ์ DNS Zone Group์ ํตํด ์๋์ผ๋ก DNS ๋ ์ฝ๋๊ฐ ์์ฑ๋ฉ๋๋ค.",
|
| 698 |
+
"์ํ ํจํด: Private Endpoint vs Service Endpoint ์ฐจ์ด, DNS ์ค์ ์์ ๋ ๋ฐ์ํ๋ ๋ฌธ๏ฟฝ๏ฟฝ, ์จํ๋ ๋ฏธ์ค์์ Private Endpoint ์ ๊ทผ ๋ฐฉ๋ฒ์ด ์ถ์ ๋ฉ๋๋ค."
|
| 699 |
+
],
|
| 700 |
+
"level": "์ค๊ธ",
|
| 701 |
+
"related_practices": [
|
| 702 |
+
"azure-lab-11"
|
| 703 |
+
]
|
| 704 |
+
},
|
| 705 |
+
{
|
| 706 |
+
"id": "azure-load-balancer-probe",
|
| 707 |
+
"certification": "AZ-104",
|
| 708 |
+
"title": "Load Balancer โ ๋ถํ ๋ถ์ฐ ์ฅ์น",
|
| 709 |
+
"summary": "L4(TCP/UDP) ์์ค์์ ์ธ๋ฐ์ด๋ ํธ๋ํฝ์ ๋ฐฑ์๋ VM ํ๋ก ๋ถ์ฐํฉ๋๋ค. Public LB๋ ์ธํฐ๋ท ํธ๋ํฝ, Internal LB๋ VNet ๋ด๋ถ ํธ๋ํฝ์ ์ฒ๋ฆฌํฉ๋๋ค.",
|
| 710 |
+
"example": "az network lb create \\\n --name myLB \\\n --resource-group myRG \\\n --frontend-ip-name frontendIP \\\n --backend-pool-name backendPool\n# ์ํ ํ๋ก๋ธ ์ถ๊ฐ\naz network lb probe create --lb-name myLB --name myProbe --protocol Http --port 80 --path /health",
|
| 711 |
+
"common_mistake": "์ํ ํ๋ก๋ธ(Health Probe)๊ฐ ์คํจํ๋ฉด ํด๋น ์ธ์คํด์ค๋ก ํธ๋ํฝ์ ๋ณด๋ด์ง ์์ต๋๋ค. ํ๋ก๋ธ ๊ฒฝ๋ก(/health)๊ฐ ์ฌ๋ฐ๋ฅด์ง ์์ผ๋ฉด ์ ์ VM๋ ์ ์ธ๋ฉ๋๋ค.",
|
| 712 |
+
"keywords": [
|
| 713 |
+
"load balancer",
|
| 714 |
+
"health probe",
|
| 715 |
+
"backend pool",
|
| 716 |
+
"frontend IP",
|
| 717 |
+
"SKU Basic/Standard"
|
| 718 |
+
],
|
| 719 |
+
"source_id": "azure-load-balancer",
|
| 720 |
+
"details": [
|
| 721 |
+
"SKU: Basic(๋ฌด๋ฃ, AZ ๋ฏธ์ง์, ๊ณต๊ฐ ๋ฏธ๋ฆฌ ๋ณด๊ธฐ) vs Standard(์ ๋ฃ, AZ ์ง์, HTTPS ํ๋ก๋ธ, SLA 99.99%). ์ ๊ตฌ์ถ์ Standard ๊ถ์ฅ.",
|
| 722 |
+
"๋ถํ ๋ถ์ฐ ๊ท์น: ํฌํธยทํ๋กํ ์ฝยท์ธ์
์ง์์ฑ(Client IP/Protocol)์ ์ค์ . Floating IP๋ก SQL AlwaysOn ๋ฑ์ ์ง์ํฉ๋๋ค.",
|
| 723 |
+
"์ํ ํจํด: ํ๋ก๋ธ ์คํจ ์ ๋์, Public vs Internal LB ์ ํ, Basic vs Standard SKU ์ฐจ์ด, ์ธ์
์ง์์ฑ ์ต์
์ด ์ถ์ ๋ฉ๋๋ค."
|
| 724 |
+
],
|
| 725 |
+
"level": "์ค๊ธ"
|
| 726 |
+
},
|
| 727 |
+
{
|
| 728 |
+
"id": "azure-private-dns",
|
| 729 |
+
"certification": "AZ-104",
|
| 730 |
+
"title": "Private DNS Zone โ ์ฌ์ค DNS ์์ญ",
|
| 731 |
+
"summary": "VNet ๋ด๋ถ์์๋ง ํด์๋๋ ์ฌ์ค ๋๋ฉ์ธ์ ํธ์คํ
ํฉ๋๋ค. Private Endpoint, ๋ด๋ถ ์๋น์ค ๊ฒ์, ์จํ๋ ๋ฏธ์ค DNS ํตํฉ์ ์ฌ์ฉํฉ๋๋ค.",
|
| 732 |
+
"example": "az network private-dns zone create \\\n --name 'privatelink.blob.core.windows.net' \\\n --resource-group myRG\naz network private-dns link vnet create \\\n --zone-name 'privatelink.blob.core.windows.net' \\\n --virtual-network myVNet \\\n --registration-enabled false",
|
| 733 |
+
"common_mistake": "Private DNS Zone ์์ฑ๋ง์ผ๋ก๋ ์ ์ฉ๋์ง ์์ต๋๋ค. VNet์ ๋งํฌ(link)๋ฅผ ์ฐ๊ฒฐํด์ผ ํด๋น VNet์ VM์ด ์ฌ์ค DNS๋ฅผ ์ฟผ๋ฆฌํฉ๋๋ค.",
|
| 734 |
+
"keywords": [
|
| 735 |
+
"private DNS zone",
|
| 736 |
+
"VNet link",
|
| 737 |
+
"registration",
|
| 738 |
+
"privatelink",
|
| 739 |
+
"custom DNS"
|
| 740 |
+
],
|
| 741 |
+
"source_id": "azure-dns-overview",
|
| 742 |
+
"details": [
|
| 743 |
+
"์๋ ๋ฑ๋ก(Auto-registration): VNet ๋งํฌ์์ ํ์ฑํํ๋ฉด ํด๋น VNet์ VM์ด ์๋์ผ๋ก A ๋ ์ฝ๋๋ก ๋ฑ๋ก๋ฉ๋๋ค.",
|
| 744 |
+
"Private Endpoint DNS: `privatelink.blob.core.windows.net` ๊ฐ์ ํน์ ์์ญ์ ์ฌ์ฉํด PaaS ์๋น์ค์ ์ฌ์ค IP๋ฅผ ํด์ํฉ๋๋ค.",
|
| 745 |
+
"์ํ ํจํด: Private Endpoint์ Private DNS Zone ์ฐ๋ ์์, ์๋ ๋ฑ๋ก vs ์๋ ๋ ์ฝ๋, VNet ๋งํฌ ์์ ๋ DNS ํด์ ์คํจ ์๋๋ฆฌ์ค๊ฐ ์ถ์ ๋ฉ๋๋ค."
|
| 746 |
+
],
|
| 747 |
+
"level": "์ค๊ธ"
|
| 748 |
+
},
|
| 749 |
+
{
|
| 750 |
+
"id": "azure-monitor-metrics",
|
| 751 |
+
"certification": "AZ-104",
|
| 752 |
+
"title": "Azure Monitor Metrics โ ๋ชจ๋ํฐ ๋ฉํธ๋ฆญ",
|
| 753 |
+
"summary": "Azure ๋ฆฌ์์ค๊ฐ ์๋์ผ๋ก ์์งํ๋ ์์น ๋ฐ์ดํฐ(CPU%, ๋คํธ์ํฌ In/Out, ๋์คํฌ IOPS ๋ฑ)๋ฅผ ์ค์๊ฐ์ผ๋ก ํ์ธํ๊ณ ๊ฒฝ๋ณด๋ฅผ ์ค์ ํฉ๋๋ค.",
|
| 754 |
+
"example": "az monitor metrics list \\\n --resource /subscriptions/.../virtualMachines/myVM \\\n --metric 'Percentage CPU' \\\n --interval PT1M",
|
| 755 |
+
"common_mistake": "๊ธฐ๋ณธ ํ๋ซํผ ๋ฉํธ๋ฆญ์ 93์ผ ๋ณด๊ด๋ฉ๋๋ค. ๋ ์ค๋ ๋ณด๊ดํ๊ฑฐ๋ ์ปค์คํ
๋ฉํธ๋ฆญ์ ์ ์ฅํ๋ ค๋ฉด Log Analytics Workspace๋ก ์ ์กํด์ผ ํฉ๋๋ค.",
|
| 756 |
+
"keywords": [
|
| 757 |
+
"metrics",
|
| 758 |
+
"Azure Monitor",
|
| 759 |
+
"CPU",
|
| 760 |
+
"latency",
|
| 761 |
+
"alert",
|
| 762 |
+
"93 days retention"
|
| 763 |
+
],
|
| 764 |
+
"source_id": "azure-monitor-overview",
|
| 765 |
+
"details": [
|
| 766 |
+
"ํ๋ซํผ ๋ฉํธ๋ฆญ์ ๋ณ๋ ์ค์ ์์ด ์๋ ์์ง๋ฉ๋๋ค. ๊ฒ์คํธ OS ๋ด๋ถ ๋ฉํธ๋ฆญ(๋ฉ๋ชจ๋ฆฌ ๋ฑ)์ Azure Monitor Agent๊ฐ ํ์ํฉ๋๋ค.",
|
| 767 |
+
"๋ฉํธ๋ฆญ ํ์๊ธฐ(Metrics Explorer)์์ ์ฌ๋ฌ ๋ฉํธ๋ฆญ์ ๋น๊ตํ๊ณ ์ฐจํธ๋ฅผ ๋์๋ณด๋์ ๊ณ ์ ํ ์ ์์ต๋๋ค.",
|
| 768 |
+
"์ํ ํจํด: ๋ฉํธ๋ฆญ ๊ธฐ๋ฐ ๊ฒฝ๋ณด ์ค์ , ํ๋ซํผ ๋ฉํธ๋ฆญ vs ๊ฒ์คํธ ๋ฉํธ๋ฆญ ์์ง ๋ฐฉ๋ฒ, ๋ณด๊ด ๊ธฐ๊ฐ ํ๊ณ์ Log Analytics ์ฐ๋์ด ์ถ์ ๋ฉ๋๋ค."
|
| 769 |
+
],
|
| 770 |
+
"level": "์ค๊ธ",
|
| 771 |
+
"related_practices": [
|
| 772 |
+
"azure-lab-15"
|
| 773 |
+
]
|
| 774 |
+
},
|
| 775 |
+
{
|
| 776 |
+
"id": "azure-activity-log",
|
| 777 |
+
"certification": "AZ-104",
|
| 778 |
+
"title": "Activity Log โ ํ๋ ๋ก๊ทธ",
|
| 779 |
+
"summary": "๊ตฌ๋
๋ ๋ฒจ์์ ๋ฐ์ํ๋ ๊ด๋ฆฌ ์์
(๋ฆฌ์์ค ์์ฑยท์ญ์ ยท๋ณ๊ฒฝ)์ ๊ธฐ๋กํฉ๋๋ค. ๋๊ฐ, ์ธ์ , ๋ฌด์์ ํ๋์ง ๊ฐ์ฌ(Audit)์ ํ์ฉํฉ๋๋ค.",
|
| 780 |
+
"example": "az monitor activity-log list \\\n --resource-group myRG \\\n --start-time 2024-01-01 \\\n --end-time 2024-01-31\n# Portal: Monitor โ Activity Log",
|
| 781 |
+
"common_mistake": "Activity Log๋ ๊ธฐ๋ณธ 90์ผ ๋ณด๊ด๋ฉ๋๋ค. ์ฅ๊ธฐ ๋ณด๊ด์ ์ํด Storage Account์ ์์นด์ด๋ธํ๊ฑฐ๋ Log Analytics๋ก ์ ์กํด์ผ ํฉ๋๋ค.",
|
| 782 |
+
"keywords": [
|
| 783 |
+
"activity log",
|
| 784 |
+
"audit",
|
| 785 |
+
"management plane",
|
| 786 |
+
"90 days",
|
| 787 |
+
"diagnostic settings"
|
| 788 |
+
],
|
| 789 |
+
"source_id": "azure-monitor-overview",
|
| 790 |
+
"details": [
|
| 791 |
+
"๊ธฐ๋ก ๋ด์ฉ: ๋๊ฐ(caller), ์ธ์ (eventTimestamp), ๋ฌด์์(operation), ์ฑ๊ณต/์คํจ(status). ๋ฐ์ดํฐ ํ๋ฉด ์์
(Blob ์ฝ๊ธฐ ๋ฑ)์ ๊ธฐ๋ก๋์ง ์์ต๋๋ค.",
|
| 792 |
+
"์ง๋จ ์ค์ (Diagnostic Settings)์ผ๋ก Activity Log๋ฅผ Log Analytics, Storage Account, Event Hub๋ก ์ ์กํ ์ ์์ต๋๋ค.",
|
| 793 |
+
"์ํ ํจํด: ๋ฆฌ์์ค ์ญ์ ์ฑ
์์ ์ถ์ , 90์ผ ์ด์ ๋ณด๊ด ๋ฐฉ๋ฒ, Activity Log vs Diagnostic Log(๋ฆฌ์์ค ๋ ๋ฒจ) ์ฐจ์ด๊ฐ ์ถ์ ๋ฉ๋๋ค."
|
| 794 |
+
],
|
| 795 |
+
"level": "์ค๊ธ"
|
| 796 |
+
},
|
| 797 |
+
{
|
| 798 |
+
"id": "azure-alert",
|
| 799 |
+
"certification": "AZ-104",
|
| 800 |
+
"title": "Alert Rule โ ๊ฒฝ๋ณด ๊ท์น",
|
| 801 |
+
"summary": "๋ฉํธ๋ฆญยท๋ก๊ทธยทํ๋ ๋ก๊ทธ ์กฐ๊ฑด์ด ์ถฉ์กฑ๋๋ฉด ์ด๋ฉ์ผยทSMSยทwebhookยทITSM ๋ฑ์ผ๋ก ์๋ฆฝ๋๋ค. Action Group์ ์๋ฆผ ๋์์ ์ ์ํฉ๋๋ค.",
|
| 802 |
+
"example": "az monitor alert create \\\n --name highCPU \\\n --resource /subscriptions/.../myVM \\\n --condition 'avg Percentage CPU > 80' \\\n --action email alice@example.com",
|
| 803 |
+
"common_mistake": "๊ฒฝ๋ณด๋ Action Group ์์ด๋ ๋ฐ์ํด๋ ์๋ฌด๋ ์ ์ ์์ต๋๋ค. ๋ฐ๋์ Action Group์ ์๋ฆผ ์ฑ๋์ ์ค์ ํด์ผ ํฉ๋๋ค.",
|
| 804 |
+
"keywords": [
|
| 805 |
+
"alert rule",
|
| 806 |
+
"action group",
|
| 807 |
+
"metric alert",
|
| 808 |
+
"log alert",
|
| 809 |
+
"severity",
|
| 810 |
+
"signal"
|
| 811 |
+
],
|
| 812 |
+
"source_id": "azure-monitor-overview",
|
| 813 |
+
"details": [
|
| 814 |
+
"์ ํธ ์ ํ: ๋ฉํธ๋ฆญ(์์น ์๊ณ๊ฐ), ๋ก๊ทธ(KQL ์ฟผ๋ฆฌ ๊ฒฐ๊ณผ), ํ๋ ๋ก๊ทธ(ํน์ ์์
๋ฐ์), ์๋น์ค ์ํ.",
|
| 815 |
+
"Action Group: ์ด๋ฉ์ผ, SMS, ์ ํ, Azure Function, Logic App, webhook, ITSM ํตํฉ์ ์ ์ํฉ๋๋ค. ์ฌ๋ฌ ๊ฒฝ๋ณด์์ ๊ณต์ ๊ฐ๋ฅํฉ๋๋ค.",
|
| 816 |
+
"์ํ ํจํด: ๋ฉํธ๋ฆญ ๊ฒฝ๋ณด ๊ตฌ์ฑ ์ ์ฐจ, Action Group ์์ฑ ๋ฐ ์ฐ๊ฒฐ, ๊ฒฝ๋ณด ์ฌ๊ฐ๋(0~4) ๋ ๋ฒจ, ์ ์ vs ๋์ ์๊ณ๊ฐ์ด ์ถ์ ๋ฉ๋๋ค."
|
| 817 |
+
],
|
| 818 |
+
"level": "์ค๊ธ",
|
| 819 |
+
"related_practices": [
|
| 820 |
+
"azure-lab-15"
|
| 821 |
+
]
|
| 822 |
+
},
|
| 823 |
+
{
|
| 824 |
+
"id": "azure-backup-policy",
|
| 825 |
+
"certification": "AZ-104",
|
| 826 |
+
"title": "Backup Policy โ ๋ฐฑ์
์ ์ฑ
",
|
| 827 |
+
"summary": "๋ฐฑ์
์ค์ผ์ค(์ผ๋ณ/์ฃผ๋ณ)๊ณผ ๋ณด์กด ๊ธฐ๊ฐ(์ผ/์ฃผ/์/๋
)์ ์ ์ํฉ๋๋ค. Recovery Services Vault์์ ์ํฌ๋ก๋๋ณ๋ก ์ ์ฑ
์ ๋ง๋ค์ด ๋ฆฌ์์ค์ ์ ์ฉํฉ๋๋ค.",
|
| 828 |
+
"example": "az backup policy create \\\n --vault-name myVault \\\n --resource-group myRG \\\n --name myPolicy \\\n --policy @policy.json\n# policy.json์ ์ค์ผ์ค๊ณผ ๋ณด์กด ๊ธฐ๊ฐ ์ ์",
|
| 829 |
+
"common_mistake": "๋ฐฑ์
์ ์ฑ
์ ๋ณ๊ฒฝํด๋ ๊ธฐ์กด ๋ณต์ ์ง์ ๋ณด์กด ๊ธฐ๊ฐ์ ์๊ธ ์ ์ฉ๋์ง ์์ต๋๋ค. ๋ณ๊ฒฝ ์ดํ ์์ฑ๋๋ ๋ณต์ ์ง์ ์๋ง ์ ์ ์ฑ
์ด ์ ์ฉ๋ฉ๋๋ค.",
|
| 830 |
+
"keywords": [
|
| 831 |
+
"backup policy",
|
| 832 |
+
"schedule",
|
| 833 |
+
"retention",
|
| 834 |
+
"RPO",
|
| 835 |
+
"Recovery Services Vault"
|
| 836 |
+
],
|
| 837 |
+
"source_id": "azure-recovery-services-vault",
|
| 838 |
+
"details": [
|
| 839 |
+
"Enhanced Policy(ํฅ์๋ ์ ์ฑ
): ์๊ฐ๋น ๋ฐฑ์
, AZ ์ค๋ณต ๋ณต์ ์ง์ , Trusted Launch VM ์ง์ ๋ฑ ๋ ๋ง์ ์ต์
์ ์ ๊ณตํฉ๋๋ค.",
|
| 840 |
+
"๋ณด์กด ๊ณ์ธต: ์ผ๋ณ(์ต๋ 180์ผ), ์ฃผ๋ณ(์ต๋ 520์ฃผ), ์๋ณ(์ต๋ 120๊ฐ์), ์ฐ๋ณ(์ต๋ 10๋
).",
|
| 841 |
+
"์ํ ํจํด: RPO(๋ณต๊ตฌ ์์ ๋ชฉํ)์ ๋ฐ๋ฅธ ๋ฐฑ์
์ค์ผ์ค ์ ํ, ์ฅ๊ธฐ ๋ณด์กด ์ค์ , GRS ๋ฐฑ์
์ผ๋ก ์ง์ญ ๊ฐ ๋ณต์ ๋ฐฉ๋ฒ์ด ์ถ์ ๋ฉ๋๋ค."
|
| 842 |
+
],
|
| 843 |
+
"level": "์ค๊ธ",
|
| 844 |
+
"related_practices": [
|
| 845 |
+
"azure-lab-8"
|
| 846 |
+
]
|
| 847 |
+
},
|
| 848 |
+
{
|
| 849 |
+
"id": "azure-restore",
|
| 850 |
+
"certification": "AZ-104",
|
| 851 |
+
"title": "Restore โ ๋ณต์",
|
| 852 |
+
"summary": "Recovery Services Vault์ ๋ณต์ ์ง์ ์์ VM, ๋์คํฌ, ํ์ผ์ ์๋ ์์น ๋๋ ์ ์์น๋ก ๋ณต์ํฉ๋๋ค.",
|
| 853 |
+
"example": "az backup restore restore-disks \\\n --vault-name myVault \\\n --resource-group myRG \\\n --container-name myVM \\\n --item-name myVM \\\n --rp-name 'RecoveryPointName' \\\n --storage-account myStorageAcct",
|
| 854 |
+
"common_mistake": "VM ์ ์ฒด ๋ณต์(Restore VM)๊ณผ ๋์คํฌ๋ง ๋ณต์(Restore Disks)์ ๋ค๋ฅธ ์ต์
์
๋๋ค. ๋์คํฌ ๋ณต์ ํ์๋ VM์ ๋ณ๋๋ก ์ฌ๊ตฌ์ฑํด์ผ ํฉ๋๋ค.",
|
| 855 |
+
"keywords": [
|
| 856 |
+
"restore",
|
| 857 |
+
"recovery point",
|
| 858 |
+
"original location",
|
| 859 |
+
"alternate location",
|
| 860 |
+
"cross-region restore"
|
| 861 |
+
],
|
| 862 |
+
"source_id": "azure-recovery-services-vault",
|
| 863 |
+
"details": [
|
| 864 |
+
"๋ณต์ ์ต์
: ์๋ ์์น(๊ธฐ์กด VM ๋ฎ์ด์ฐ๊ธฐ), ์ ์์น(์ VM ์์ฑ), ๋์คํฌ๋ง ๋ณต์(Storage Account์ VHD ์ ์ฅ), ํ์ผ ๋ณต์(ํ์ผ ๋จ์).",
|
| 865 |
+
"์ง์ญ ๊ฐ ๋ณต์(CRR): GRS Vault์์ ๋ณด์กฐ region์ ๋ณต์ ์ง์ ์ผ๋ก DR ๋ณต์. CRR ๊ธฐ๋ฅ์ Vault์์ ๋ช
์์ ์ผ๋ก ํ์ฑํํด์ผ ํฉ๋๋ค.",
|
| 866 |
+
"์ํ ํจํด: ๋ณต์ ์ ํ ์ ํ(VM vs ํ์ผ), ์ง์ญ ๊ฐ ๋ณต์ ์๊ฑด, Soft Delete ์ํ์์ ๋ณต์ ๊ฐ๋ฅ ์ฌ๋ถ๊ฐ ์ถ์ ๋ฉ๋๋ค."
|
| 867 |
+
],
|
| 868 |
+
"level": "์ค๊ธ",
|
| 869 |
+
"related_practices": [
|
| 870 |
+
"azure-lab-8"
|
| 871 |
+
]
|
| 872 |
+
},
|
| 873 |
+
{
|
| 874 |
+
"id": "azure-app-service-plan",
|
| 875 |
+
"certification": "AZ-104",
|
| 876 |
+
"title": "App Service Plan โ ์ฑ ์๋น์ค ํ๋",
|
| 877 |
+
"summary": "App Service ์ฑ์ด ์คํ๋๋ ์ปดํจํ
๋ฆฌ์์ค(CPU, ๋ฉ๋ชจ๋ฆฌ, ์คํ ๋ฆฌ์ง)๋ฅผ ์ ์ํฉ๋๋ค. ๋์ผ ํ๋์ ์ฑ์ ๊ฐ์ VM ์ธ์คํด์ค๋ฅผ ๊ณต์ ํฉ๋๋ค.",
|
| 878 |
+
"example": "az appservice plan create \\\n --name myPlan \\\n --resource-group myRG \\\n --sku P1v3 \\\n --is-linux\naz webapp create --name myApp --plan myPlan --runtime 'NODE:18-lts'",
|
| 879 |
+
"common_mistake": "Free/Shared ํ๋์ Autoscale๊ณผ ์ปค์คํ
๋๋ฉ์ธ SSL์ ์ง์ํ์ง ์์ต๋๋ค. ํ๋ก๋์
์๋ Standard(S1) ์ด์์ ์ฌ์ฉํด์ผ ํฉ๋๋ค.",
|
| 880 |
+
"keywords": [
|
| 881 |
+
"App Service Plan",
|
| 882 |
+
"SKU",
|
| 883 |
+
"Free",
|
| 884 |
+
"Basic",
|
| 885 |
+
"Standard",
|
| 886 |
+
"Premium",
|
| 887 |
+
"Isolated",
|
| 888 |
+
"autoscale"
|
| 889 |
+
],
|
| 890 |
+
"source_id": "azure-app-service-overview",
|
| 891 |
+
"details": [
|
| 892 |
+
"SKU ๊ณ์ธต: Free/Shared(๊ณต์ ์ธํ๋ผ, SLA ์์), Basic(์ ์ฉ VM), Standard(Autoscale, SSL), Premium(๊ณ ์ฑ๋ฅ), Isolated(VNet ์ ์ฉ ํ๊ฒฝ).",
|
| 893 |
+
"๊ฐ์ ํ๋์ ์ฌ๋ฌ ์ฑ์ ๋ฃ์ผ๋ฉด ์ปดํจํ
์ ๊ณต์ ํฉ๋๋ค. ์ฑ์ด ๋ง์์ง๋ฉด ํ๋์ ์ค์ผ์ผ์
(ํฌ๊ธฐ ๋ณ๊ฒฝ)ํ๊ฑฐ๋ ๋ถ๋ฆฌํฉ๋๋ค.",
|
| 894 |
+
"์ํ ํจํด: ํ๋ SKU๋ณ ์ง์ ๊ธฐ๋ฅ(Autoscale, Deployment Slots, VNet ํตํฉ ์กฐ๊ฑด), ํ๋ ๋ณ๊ฒฝ ์ ์ฑ ์ํฅ์ด ์ถ์ ๋ฉ๋๋ค."
|
| 895 |
+
],
|
| 896 |
+
"level": "๊ณ ๊ธ",
|
| 897 |
+
"related_practices": [
|
| 898 |
+
"azure-lab-13"
|
| 899 |
+
]
|
| 900 |
+
},
|
| 901 |
+
{
|
| 902 |
+
"id": "azure-container-registry",
|
| 903 |
+
"certification": "AZ-104",
|
| 904 |
+
"title": "Azure Container Registry โ ์ปจํ
์ด๋ ๋ ์ง์คํธ๋ฆฌ",
|
| 905 |
+
"summary": "Docker ์ปจํ
์ด๋ ์ด๋ฏธ์ง์ Helm ์ฐจํธ๋ฅผ ์ ์ฅํ๊ณ ๊ด๋ฆฌํ๋ ์ฌ์ค ๋ ์ง์คํธ๋ฆฌ์
๋๋ค. AKS, Container Instances, App Service์ ํตํฉ๋ฉ๋๋ค.",
|
| 906 |
+
"example": "az acr create \\\n --name myRegistry \\\n --resource-group myRG \\\n --sku Standard\naz acr build --registry myRegistry --image myapp:v1 .\ndocker pull myregistry.azurecr.io/myapp:v1",
|
| 907 |
+
"common_mistake": "ACR์์ ์ด๋ฏธ์ง๋ฅผ pullํ๋ ค๋ฉด ์ธ์ฆ์ด ํ์ํฉ๋๋ค. AKS์์ ์ฌ์ฉ ์ Managed Identity ๋๋ Service Principal๋ก pull ๊ถํ์ ๋ถ์ฌํด์ผ ํฉ๋๋ค.",
|
| 908 |
+
"keywords": [
|
| 909 |
+
"ACR",
|
| 910 |
+
"container registry",
|
| 911 |
+
"docker",
|
| 912 |
+
"image",
|
| 913 |
+
"geo-replication",
|
| 914 |
+
"SKU Basic/Standard/Premium"
|
| 915 |
+
],
|
| 916 |
+
"source_id": "azure-app-service-overview",
|
| 917 |
+
"details": [
|
| 918 |
+
"SKU: Basic(๊ฐ๋ฐ์ฉ), Standard(์ผ๋ฐ, geo-replication ๋ฏธ์ง์), Premium(geo-replication, Private Link ์ง์).",
|
| 919 |
+
"ACR Tasks: ์ด๋ฏธ์ง ๋น๋ยทํ
์คํธยทํจ์น๋ฅผ Azure์์ ์ง์ ์คํ. Docker ์์ด ํด๋ผ์ฐ๋์์ ์ด๋ฏธ์ง๋ฅผ ๋น๋ํฉ๋๋ค.",
|
| 920 |
+
"์ํ ํจํด: ACR SKU๋ณ ๊ธฐ๋ฅ ์ฐจ์ด, AKS์์ ACR ์ด๋ฏธ์ง pull ๊ถํ ์ค์ (Managed Identity ์ฐ๊ฒฐ), geo-replication ์ค์ ์ด ์ถ์ ๋ฉ๋๋ค."
|
| 921 |
+
],
|
| 922 |
+
"level": "๊ณ ๊ธ"
|
| 923 |
+
},
|
| 924 |
+
{
|
| 925 |
+
"id": "azure-key-vault",
|
| 926 |
+
"certification": "AZ-104",
|
| 927 |
+
"title": "Key Vault โ ํค ์๊ฒฉ ์ฆ๋ช
๋ชจ์",
|
| 928 |
+
"summary": "๋น๋ฐ(Secret), ํค(Key), ์ธ์ฆ์(Certificate)๋ฅผ ์ค์์์ ์์ ํ๊ฒ ์ ์ฅยท๊ด๋ฆฌํฉ๋๋ค. ์ฑ ์ฝ๋์์ ์๊ฒฉ ์ฆ๋ช
์ ์ ๊ฑฐํ๋ ํต์ฌ ๋ณด์ ์๋น์ค์
๋๋ค.",
|
| 929 |
+
"example": "az keyvault create --name myKV --resource-group myRG --location koreacentral\naz keyvault secret set --vault-name myKV --name 'db-password' --value 'MyP@ss'\naz keyvault secret show --vault-name myKV --name 'db-password'",
|
| 930 |
+
"common_mistake": "Key Vault์ ์ ๊ทผํ๋ ค๋ฉด Access Policy ๋๋ RBAC๋ก ๊ถํ์ ๋ถ์ฌํด์ผ ํฉ๋๋ค. Managed Identity๋ฅผ ํตํด ์ฑ์ด ์๊ฒฉ ์ฆ๋ช
์์ด Key Vault์ ์ ๊ทผํ๋ ๊ฒ์ด ๋ชจ๋ฒ ์ฌ๋ก์
๋๋ค.",
|
| 931 |
+
"keywords": [
|
| 932 |
+
"Key Vault",
|
| 933 |
+
"secret",
|
| 934 |
+
"key",
|
| 935 |
+
"certificate",
|
| 936 |
+
"soft delete",
|
| 937 |
+
"RBAC",
|
| 938 |
+
"access policy"
|
| 939 |
+
],
|
| 940 |
+
"source_id": "azure-key-vault-overview",
|
| 941 |
+
"details": [
|
| 942 |
+
"์ ๊ทผ ์ ์ด: ๊ตฌ์ Access Policy ๋ฐฉ์๊ณผ ์ต์ Azure RBAC ๋ฐฉ์ ๋ ๊ฐ์ง. ์ ๊ตฌ์ถ์ RBAC ๋ฐฉ์ ๊ถ์ฅ.",
|
| 943 |
+
"Soft Delete์ Purge Protection: ์ค์๋ก ์ญ์ ๋ ๋น๋ฐ์ 7~90์ผ ๋ด ๋ณต์ ๊ฐ๋ฅ. Purge Protection ํ์ฑํ ์ ์ญ์ ๋ ํญ๋ชฉ ์๊ตฌ ์ ๊ฑฐ ๋ถ๊ฐ.",
|
| 944 |
+
"์ํ ํจํด: Managed Identity๋ก ์ฑ์์ ๋น๋ฐ ์ ๊ทผ, Soft Delete/Purge Protection ๊ฐ๋
, HSM(ํ๋์จ์ด ๋ณด์ ๋ชจ๋) ์ง์ SKU ์ฐจ์ด๊ฐ ์ถ์ ๋ฉ๋๋ค."
|
| 945 |
+
],
|
| 946 |
+
"level": "์ค๊ธ",
|
| 947 |
+
"related_practices": [
|
| 948 |
+
"azure-lab-9"
|
| 949 |
+
]
|
| 950 |
+
},
|
| 951 |
+
{
|
| 952 |
+
"id": "azure-cost-management",
|
| 953 |
+
"certification": "AZ-104",
|
| 954 |
+
"title": "Cost Management โ ๋น์ฉ ๊ด๋ฆฌ",
|
| 955 |
+
"summary": "Azure ์๋น์ค ์ฌ์ฉ ๋น์ฉ์ ๋ถ์ํ๊ณ ์์ฐ์ ์ค์ ํด ์ด๊ณผ ์ ์๋ฆผ์ ๋ฐ์ต๋๋ค. ํ๊ทธยท๊ตฌ๋
ยทRG๋ณ๋ก ๋น์ฉ์ ์ธ๋ถํํ ์ ์์ต๋๋ค.",
|
| 956 |
+
"example": "az consumption budget create \\\n --budget-name monthlyBudget \\\n --amount 1000 \\\n --time-grain Monthly \\\n --start-date 2024-01-01 \\\n --end-date 2024-12-31",
|
| 957 |
+
"common_mistake": "์์ฐ ๊ฒฝ๋ณด๋ ์ง์ถ์ด ์๊ณ๊ฐ์ ๋๋ฌํ์ ๋ ์๋ ค์ฃผ๋ ๊ฒ์ด์ง, ์๋์ผ๋ก ๋ฆฌ์์ค๋ฅผ ์ค์งํ๊ฑฐ๋ ๋น์ฉ์ ์ฐจ๋จํ์ง ์์ต๋๋ค.",
|
| 958 |
+
"keywords": [
|
| 959 |
+
"Cost Management",
|
| 960 |
+
"budget",
|
| 961 |
+
"alert",
|
| 962 |
+
"cost analysis",
|
| 963 |
+
"tags",
|
| 964 |
+
"billing"
|
| 965 |
+
],
|
| 966 |
+
"source_id": "azure-monitor-overview",
|
| 967 |
+
"details": [
|
| 968 |
+
"๋น์ฉ ๋ถ์(Cost Analysis): ๊ธฐ๊ฐยท์๋น์คยทlocationยทํ๊ทธ ๋ฑ์ผ๋ก ํํฐ๋งํด ๋น์ฉ ๋ด์ญ์ ํ์ด/๋์ ์ฐจํธ๋ก ์๊ฐํํฉ๋๋ค.",
|
| 969 |
+
"์์ฐ ๊ฒฝ๋ณด: ์ค์ ๋น์ฉ ๋๋ ์์ธก ๋น์ฉ์ด ์ค์ ๋น์จ(์: 80%, 100%)์ ๋๋ฌํ๋ฉด Action Group์ผ๋ก ์๋ฆผ์ ๋ณด๋
๋๋ค.",
|
| 970 |
+
"์ํ ํจํด: ์์ฐ ๊ฒฝ๋ณด ์ค์ ์ ์ฐจ, ํ๊ทธ๋ฅผ ํตํ ๋น์ฉ ๋ถ๋ฅ, Cost Management vs Azure Advisor ์ญํ ์ฐจ์ด๊ฐ ์ถ์ ๋ฉ๋๋ค."
|
| 971 |
+
],
|
| 972 |
+
"level": "์ค๊ธ"
|
| 973 |
+
},
|
| 974 |
+
{
|
| 975 |
+
"id": "azure-bastion",
|
| 976 |
+
"certification": "AZ-104",
|
| 977 |
+
"title": "Azure Bastion โ ์์ ํ ์๊ฒฉ ์ ์",
|
| 978 |
+
"summary": "๊ณต์ฉ IP ์์ด Azure Portal์์ ์ง์ VM์ RDP/SSH๋ก ์ ์ํฉ๋๋ค. TLS 443 ํฌํธ๋ง ์ฌ์ฉํด VM์ ๊ด๋ฆฌ ํฌํธ๋ฅผ ์ธํฐ๋ท์ ๋
ธ์ถํ์ง ์์ต๋๋ค.",
|
| 979 |
+
"example": "az network bastion create \\\n --name myBastion \\\n --public-ip-address myBastionIP \\\n --resource-group myRG \\\n --vnet-name myVNet \\\n --location koreacentral",
|
| 980 |
+
"common_mistake": "Bastion์ VNet์ `AzureBastionSubnet`์ด๋ผ๋ ์ด๋ฆ์ ์๋ธ๋ท(/27 ์ด์)์ด ๋ฐ๋์ ํ์ํฉ๋๋ค. ์ด๋ฆ์ด ์ ํํ ์ผ์นํด์ผ ํฉ๋๋ค.",
|
| 981 |
+
"keywords": [
|
| 982 |
+
"Azure Bastion",
|
| 983 |
+
"RDP",
|
| 984 |
+
"SSH",
|
| 985 |
+
"AzureBastionSubnet",
|
| 986 |
+
"port 443",
|
| 987 |
+
"no public IP"
|
| 988 |
+
],
|
| 989 |
+
"source_id": "azure-bastion-overview",
|
| 990 |
+
"details": [
|
| 991 |
+
"Bastion SKU: Basic(RDP/SSH ๊ธฐ๋ณธ), Standard(ํ์ผ ์ ์ก, ๋ฉํฐํญ, ๊ธฐ๋ณธ ํธ์คํธ ํฌํธ ์ธ ํฌํธ, VM Auth ๋ฑ ์ถ๊ฐ ๊ธฐ๋ฅ).",
|
| 992 |
+
"VM์ Public IP์ NSG์ RDP/SSH ํ์ฉ ๊ท์น์ด ์์ด๋ Bastion์ผ๋ก ์ ์ ๊ฐ๋ฅํฉ๋๋ค. ๊ณต๊ฒฉ ํ๋ฉด์ด ํฌ๊ฒ ์ค์ด๋ญ๋๋ค.",
|
| 993 |
+
"์ํ ํจํด: Bastion ์๋ธ๋ท ์ด๋ฆยทํฌ๊ธฐ ์๊ตฌ์ฌํญ, Public IP ์๋ VM ์ ์ ๋ฐฉ๋ฒ, JIT(Just-In-Time) VM Access์ ์ฐจ์ด๊ฐ ์ถ์ ๋ฉ๋๋ค."
|
| 994 |
+
],
|
| 995 |
+
"level": "์ค๊ธ",
|
| 996 |
+
"related_practices": [
|
| 997 |
+
"azure-lab-12"
|
| 998 |
+
]
|
| 999 |
+
},
|
| 1000 |
+
{
|
| 1001 |
+
"id": "azure-nat-gateway",
|
| 1002 |
+
"certification": "AZ-104",
|
| 1003 |
+
"title": "NAT Gateway โ ์์๋ฐ์ด๋ ์ธํฐ๋ท ์ฐ๊ฒฐ",
|
| 1004 |
+
"summary": "์๋ธ๋ท์ ๋ชจ๋ VM์ด ๋์ผํ ๊ณ ์ ๊ณต์ฉ IP๋ก ์ธํฐ๋ท์ ๋๊ฐ๋๋ก ํฉ๋๋ค. ์์๋ฐ์ด๋ ์ฐ๊ฒฐ ์์ ์ฑ์ ๋์ด๊ณ SNAT ํฌํธ ๊ณ ๊ฐ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํฉ๋๋ค.",
|
| 1005 |
+
"example": "az network public-ip create --name myNatIP --resource-group myRG --sku Standard\naz network nat gateway create \\\n --name myNatGW \\\n --resource-group myRG \\\n --public-ip-addresses myNatIP\naz network vnet subnet update --nat-gateway myNatGW ...",
|
| 1006 |
+
"common_mistake": "NAT Gateway๋ ์์๋ฐ์ด๋ ์ ์ฉ์
๋๋ค. ์ธ๋ฐ์ด๋ ํธ๋ํฝ์ ๋ฐ์ผ๋ ค๋ฉด ์ฌ์ ํ Public IP ๋๋ Load Balancer๊ฐ ํ์ํฉ๋๋ค.",
|
| 1007 |
+
"keywords": [
|
| 1008 |
+
"NAT Gateway",
|
| 1009 |
+
"outbound",
|
| 1010 |
+
"SNAT",
|
| 1011 |
+
"public IP",
|
| 1012 |
+
"port exhaustion",
|
| 1013 |
+
"static IP"
|
| 1014 |
+
],
|
| 1015 |
+
"source_id": "azure-nat-gateway",
|
| 1016 |
+
"details": [
|
| 1017 |
+
"SNAT(Source NAT): VM์ ์ฌ์ค IP๋ฅผ NAT Gateway์ ๊ณต์ฉ IP๋ก ๋ณํ. ์ฌ๋ฌ VM์ด ๊ฐ์ ๊ณต์ฉ IP๋ฅผ ๊ณต์ ํฉ๋๋ค.",
|
| 1018 |
+
"Load Balancer ์์๋ฐ์ด๋ ๊ท์น vs NAT Gateway: NAT Gateway๊ฐ ๋ ๋ง์ SNAT ํฌํธ(64,512 ร IP ์)๋ฅผ ์ ๊ณตํด ๊ณ ๋ถํ์ ์ ํฉํฉ๋๋ค.",
|
| 1019 |
+
"์ํ ํจํด: NAT Gateway ์๋ธ๋ท ์ฐ๊ฒฐ ๋ฐฉ๋ฒ, ๊ณ ์ ์์๋ฐ์ด๋ IP ์๊ตฌ ์๋๋ฆฌ์ค, Load Balancer์ ๋์ ์ฌ์ฉ ์ฐ์ ์์๊ฐ ์ถ์ ๋ฉ๋๋ค."
|
| 1020 |
+
],
|
| 1021 |
+
"level": "์ค๊ธ"
|
| 1022 |
+
},
|
| 1023 |
+
{
|
| 1024 |
+
"id": "azure-app-service",
|
| 1025 |
+
"certification": "AZ-104",
|
| 1026 |
+
"title": "App Service โ ์น ์ฑ ํธ์คํ
",
|
| 1027 |
+
"summary": "์ฝ๋ ๋๋ ์ปจํ
์ด๋๋ฅผ ๋ฐฐํฌํ๋ ์์ ๊ด๋ฆฌํ PaaS ์น ํธ์คํ
์๋น์ค์
๋๋ค. .NET, Node.js, Python, Java, PHP ๋ฑ ๋ค์ํ ๋ฐํ์์ ์ง์ํฉ๋๋ค.",
|
| 1028 |
+
"example": "az webapp create \\\n --name myWebApp \\\n --resource-group myRG \\\n --plan myPlan \\\n --runtime 'PYTHON:3.11'\naz webapp deployment source config-zip \\\n --name myWebApp --src app.zip",
|
| 1029 |
+
"common_mistake": "App Service์ ์ฑ ์ค์ (Application Settings)์ ํ๊ฒฝ ๋ณ์๋ก ์ฑ์ ์ฃผ์
๋ฉ๋๋ค. ์ฝ๋์ ํ๋์ฝ๋ฉ๋ ์ค์ ๋ณด๋ค ์ฑ ์ค์ ์ ๋ฃ๋ ๊ฒ์ด ๋ณด์์ ์ข์ต๋๋ค.",
|
| 1030 |
+
"keywords": [
|
| 1031 |
+
"App Service",
|
| 1032 |
+
"web app",
|
| 1033 |
+
"deployment slot",
|
| 1034 |
+
"custom domain",
|
| 1035 |
+
"SSL",
|
| 1036 |
+
"VNet integration"
|
| 1037 |
+
],
|
| 1038 |
+
"source_id": "azure-app-service-overview",
|
| 1039 |
+
"details": [
|
| 1040 |
+
"๋ฐฐํฌ ๋ฐฉ๋ฒ: ZIP ๋ฐฐํฌ, Git(๋ก์ปฌ/GitHub Actions), Docker ์ด๋ฏธ์ง, Azure DevOps. CI/CD ์ฐ๋์ด ์ฉ์ดํฉ๋๋ค.",
|
| 1041 |
+
"VNet ํตํฉ: Standard ์ด์ ํ๋์์ App Service๋ฅผ VNet์ ์ฐ๊ฒฐํด ์ฌ์ค ๋ฆฌ์์ค(DB, ์บ์)์ ์ ๏ฟฝ๏ฟฝ๏ฟฝํ ์ ์์ต๋๋ค.",
|
| 1042 |
+
"์ํ ํจํด: ์ปค์คํ
๋๋ฉ์ธยทSSL ๋ฐ์ธ๋ฉ, ๋ฐฐํฌ ์ฌ๋กฏ ์ค์, VNet ํตํฉ ์ค์ , App Settings vs Connection Strings ์ฐจ์ด๊ฐ ์ถ์ ๋ฉ๋๋ค."
|
| 1043 |
+
],
|
| 1044 |
+
"level": "๊ณ ๊ธ",
|
| 1045 |
+
"related_practices": [
|
| 1046 |
+
"azure-lab-13"
|
| 1047 |
+
]
|
| 1048 |
+
},
|
| 1049 |
+
{
|
| 1050 |
+
"id": "azure-deployment-slot",
|
| 1051 |
+
"certification": "AZ-104",
|
| 1052 |
+
"title": "Deployment Slot โ ๋ฐฐํฌ ์ฌ๋กฏ",
|
| 1053 |
+
"summary": "์ฑ์ ์คํ
์ด์ง ๋ฒ์ ์ ๋ณ๋ ์ฌ๋กฏ์ ๋ฐฐํฌํ๊ณ ํ
์คํธ ํ ํ๋ก๋์
์ฌ๋กฏ๊ณผ ์ฆ์ ๊ต์ฒด(Swap)ํฉ๋๋ค. Standard ์ด์ ํ๋์์ ์ง์ํฉ๋๋ค.",
|
| 1054 |
+
"example": "az webapp deployment slot create \\\n --name myWebApp \\\n --resource-group myRG \\\n --slot staging\n# ํ
์คํธ ํ swap\naz webapp deployment slot swap \\\n --name myWebApp --slot staging",
|
| 1055 |
+
"common_mistake": "Swap ์ ์ฌ๋กฏ ๊ณ ์ ์ค์ (Slot Settings๋ก ํ์๋ ํญ๋ชฉ)์ ๊ต์ฒด๋์ง ์๊ณ ๊ฐ ์ฌ๋กฏ์ ๊ณ ์ ๋ฉ๋๋ค. ์: ์คํ
์ด์ง DB ์ฐ๊ฒฐ ๋ฌธ์์ด์ ํ๋ก๋์
์ผ๋ก ๋ฐ๋ผ๊ฐ์ง ์์ต๋๋ค.",
|
| 1056 |
+
"keywords": [
|
| 1057 |
+
"deployment slot",
|
| 1058 |
+
"staging",
|
| 1059 |
+
"swap",
|
| 1060 |
+
"slot settings",
|
| 1061 |
+
"traffic routing",
|
| 1062 |
+
"warm-up"
|
| 1063 |
+
],
|
| 1064 |
+
"source_id": "azure-app-service-overview",
|
| 1065 |
+
"details": [
|
| 1066 |
+
"Swap ๋์: ์ฌ๋กฏ์ด ์๋ฐ์
๋ ํ ๋ผ์ฐํฐ ์์ค์์ ํธ๋ํฝ์ด ์ฆ์ ์ ํ๋ฉ๋๋ค. ๋ค์ดํ์ ์์ด ์ ๋ฒ์ ๋ฐฐํฌ๊ฐ ๊ฐ๋ฅํฉ๋๋ค.",
|
| 1067 |
+
"ํธ๋ํฝ ๋ผ์ฐํ
: % ๊ธฐ๋ฐ์ผ๋ก ์ผ๋ถ ํธ๋ํฝ๋ง ์คํ
์ด์ง ์ฌ๋กฏ์ผ๋ก ๋ณด๋ด A/B ํ
์คํธ๋ฅผ ํ ์ ์์ต๋๋ค.",
|
| 1068 |
+
"์ํ ํจํด: Slot Settings(์ฌ๋กฏ ๊ณ ์ ์ค์ ) ๊ฐ๋
, Swap ์ ์ค์ ๊ต์ฒด ๊ท์น, Auto Swap ๊ธฐ๋ฅ, ์ฌ๋กฏ ์ ์ ํ(Standard=5) ์ด ์ถ์ ๋ฉ๋๋ค."
|
| 1069 |
+
],
|
| 1070 |
+
"level": "๊ณ ๊ธ",
|
| 1071 |
+
"related_practices": [
|
| 1072 |
+
"azure-lab-14"
|
| 1073 |
+
]
|
| 1074 |
+
},
|
| 1075 |
+
{
|
| 1076 |
+
"id": "azure-aci",
|
| 1077 |
+
"certification": "AZ-104",
|
| 1078 |
+
"title": "Azure Container Instances โ ์ปจํ
์ด๋ ์ธ์คํด์ค",
|
| 1079 |
+
"summary": "VM์ด๋ ํด๋ฌ์คํฐ ๊ด๋ฆฌ ์์ด ์ปจํ
์ด๋๋ฅผ ์ด ๋จ์๋ก ๋น ๋ฅด๊ฒ ์คํํฉ๋๋ค. ๋จ์ ์์
, ๋ฐฐ์น ์ฒ๋ฆฌ, ์ด๋ฒคํธ ๊ธฐ๋ฐ ์ฒ๋ฆฌ์ ์ ํฉํฉ๋๋ค.",
|
| 1080 |
+
"example": "az container create \\\n --name myapp \\\n --resource-group myRG \\\n --image nginx:latest \\\n --cpu 1 --memory 1.5 \\\n --ports 80 \\\n --dns-name-label myapp-dns",
|
| 1081 |
+
"common_mistake": "ACI๋ ๋จ๊ธฐ ์คํ ์ปจํ
์ด๋์ ์ ํฉํฉ๋๋ค. ์ง์์ ์ธ ๊ณ ๊ฐ์ฉ์ฑ ์น ์ฑ์ด๋ ๋ณต์กํ ๋ง์ดํฌ๋ก์๋น์ค์๋ AKS(Kubernetes)๊ฐ ๋ ์ ํฉํฉ๋๋ค.",
|
| 1082 |
+
"keywords": [
|
| 1083 |
+
"ACI",
|
| 1084 |
+
"container",
|
| 1085 |
+
"serverless",
|
| 1086 |
+
"container group",
|
| 1087 |
+
"CPU/memory",
|
| 1088 |
+
"VNet"
|
| 1089 |
+
],
|
| 1090 |
+
"source_id": "azure-container-instances",
|
| 1091 |
+
"details": [
|
| 1092 |
+
"Container Group: ๋์ผ ํธ์คํธ์์ ๋ฆฌ์์ค๋ฅผ ๊ณต์ ํ๋ ์ปจํ
์ด๋ ๋ชจ์. Kubernetes Pod ๊ฐ๋
๊ณผ ์ ์ฌํฉ๋๋ค.",
|
| 1093 |
+
"VNet ๋ฐฐํฌ: ACI๋ฅผ VNet์ ๋ฐฐํฌํ๋ฉด ์ฌ์ค IP๋ฅผ ๋ถ์ฌ๋ฐ์ ๋ค๋ฅธ Azure ๋ฆฌ์์ค์ ์ฌ์ค๋ง์์ ํต์ ํฉ๋๋ค.",
|
| 1094 |
+
"์ํ ํจํด: ACI vs AKS ์ ํ ๊ธฐ์ค, ์ปจํ
์ด๋ ๊ทธ๋ฃน ๋ด ์ฌ์ด๋์นด ํจํด, ์ฌ์์ ์ ์ฑ
(Always/OnFailure/Never) ์๋๋ฆฌ์ค๊ฐ ์ถ์ ๋ฉ๋๋ค."
|
| 1095 |
+
],
|
| 1096 |
+
"level": "๊ณ ๊ธ"
|
| 1097 |
+
},
|
| 1098 |
+
{
|
| 1099 |
+
"id": "azure-keyvault-secret",
|
| 1100 |
+
"certification": "AZ-104",
|
| 1101 |
+
"title": "Key Vault Secret โ ๋น๋ฐ ๊ด๋ฆฌ",
|
| 1102 |
+
"summary": "Key Vault์์ API ํค, ๋น๋ฐ๋ฒํธ, ์ฐ๊ฒฐ ๋ฌธ์์ด์ ๋ฒ์ ๊ด๋ฆฌ์ ํจ๊ป ์ ์ฅํฉ๋๋ค. ์ฑ์์ Managed Identity๋ก ์ฝ๋์ ์๊ฒฉ ์ฆ๋ช
์์ด ๋น๋ฐ์ ๊ฐ์ ธ์ต๋๋ค.",
|
| 1103 |
+
"example": "az keyvault secret set --vault-name myKV --name 'APIKey' --value 'secret123'\naz keyvault secret show --vault-name myKV --name 'APIKey' --query 'value'\n# ์ฑ์์: ํ๊ฒฝ๋ณ์ ๋๋ Key Vault ์ฐธ์กฐ๋ก ์ฃผ์
",
|
| 1104 |
+
"common_mistake": "๋น๋ฐ์ ์ญ์ ํ๋ฉด ๋ชจ๋ ๋ฒ์ ์ด ์ญ์ ๋ฉ๋๋ค. Soft Delete๊ฐ ํ์ฑํ๋ ๊ฒฝ์ฐ ๋ณต์ ๊ธฐ๊ฐ(90์ผ ๊ธฐ๋ณธ) ๋ด์ ๋ณต๊ตฌ ๊ฐ๋ฅํฉ๋๋ค.",
|
| 1105 |
+
"keywords": [
|
| 1106 |
+
"secret",
|
| 1107 |
+
"version",
|
| 1108 |
+
"managed identity",
|
| 1109 |
+
"Key Vault reference",
|
| 1110 |
+
"rotation",
|
| 1111 |
+
"soft delete"
|
| 1112 |
+
],
|
| 1113 |
+
"source_id": "azure-key-vault-overview",
|
| 1114 |
+
"details": [
|
| 1115 |
+
"๋น๋ฐ ๋ฒ์ : ๊ฐ์ ์
๋ฐ์ดํธํ ๋๋ง๋ค ์ ๋ฒ์ ์ด ์์ฑ๋ฉ๋๋ค. ์ฑ์ ๋ฒ์ ์์ด ์ฐธ์กฐํ๋ฉด ํ์ฌ ํ์ฑ ๋ฒ์ ์ ๋ฐ์ต๋๋ค.",
|
| 1116 |
+
"Key Vault ์ฐธ์กฐ: App Service ์ฑ ์ค์ ์์ `@Microsoft.KeyVault(SecretUri=...)` ํ์์ผ๋ก ๋น๋ฐ์ ์ง์ ์ฃผ์
ํฉ๋๋ค.",
|
| 1117 |
+
"์ํ ํจํด: App Service์์ Key Vault ์ฐธ์กฐ๋ก ๋น๋ฐ ์ฃผ์
, ๋น๋ฐ ์ํ(rotation) ์ค์ , Managed Identity์ Key Vault ์ฐ๋ ์ ์ฐจ๊ฐ ์ถ์ ๋ฉ๋๋ค."
|
| 1118 |
+
],
|
| 1119 |
+
"level": "๊ณ ๊ธ",
|
| 1120 |
+
"related_practices": [
|
| 1121 |
+
"azure-lab-9"
|
| 1122 |
+
]
|
| 1123 |
+
},
|
| 1124 |
+
{
|
| 1125 |
+
"id": "azure-managed-identity",
|
| 1126 |
+
"certification": "AZ-104",
|
| 1127 |
+
"title": "Managed Identity โ ๊ด๋ฆฌํ ID",
|
| 1128 |
+
"summary": "Azure ๋ฆฌ์์ค(VM, App Service ๋ฑ)์ Entra ID ID๋ฅผ ๋ถ์ฌํด ์๊ฒฉ ์ฆ๋ช
์์ด ๋ค๋ฅธ Azure ์๋น์ค์ ์ธ์ฆํฉ๋๋ค. ์ฝ๋์ ๋น๋ฐ์ ์ ์ฅํ ํ์๊ฐ ์์ต๋๋ค.",
|
| 1129 |
+
"example": "# VM์ System-Assigned MI ํ์ฑํ\naz vm identity assign --name myVM --resource-group myRG\n# MI์ ์ญํ ํ ๋น\naz role assignment create \\\n --assignee $(az vm show --name myVM --query identity.principalId -o tsv) \\\n --role 'Key Vault Secrets User' \\\n --scope /subscriptions/.../vaults/myKV",
|
| 1130 |
+
"common_mistake": "System-Assigned MI๋ ๋ฆฌ์์ค ์ญ์ ์ ํจ๊ป ์ญ์ ๋ฉ๋๋ค. ์ฌ๋ฌ ๋ฆฌ์์ค์์ ๊ณต์ ํ๋ ID๊ฐ ํ์ํ๋ฉด User-Assigned MI๋ฅผ ์๋๋ค.",
|
| 1131 |
+
"keywords": [
|
| 1132 |
+
"managed identity",
|
| 1133 |
+
"system-assigned",
|
| 1134 |
+
"user-assigned",
|
| 1135 |
+
"principal ID",
|
| 1136 |
+
"service principal"
|
| 1137 |
+
],
|
| 1138 |
+
"source_id": "azure-rbac-overview",
|
| 1139 |
+
"details": [
|
| 1140 |
+
"์ ํ: System-Assigned(๋ฆฌ์์ค์ ์ข
์, 1:1), User-Assigned(๋
๋ฆฝ์ ์ผ๋ก ์์ฑ, ์ฌ๋ฌ ๋ฆฌ์์ค์ ์ฐ๊ฒฐ ๊ฐ๋ฅ).",
|
| 1141 |
+
"๋์ ์๋ฆฌ: ๋ฆฌ์์ค๊ฐ Entra ID์์ ํ ํฐ์ ์๋ ํ๋ โ ํด๋น ํ ํฐ์ผ๋ก Key Vault, Storage ๋ฑ์ ์ธ์ฆํฉ๋๋ค.",
|
| 1142 |
+
"์ํ ํจํด: System vs User-Assigned ์ ํ ์๋๋ฆฌ์ค, MI์ RBAC ์ญํ ๋ถ์ฌ ์ ์ฐจ, App Service์์ MI๋ฅผ ํตํ Key Vault ์ ๊ทผ์ด ์ถ์ ๋ฉ๋๋ค."
|
| 1143 |
+
],
|
| 1144 |
+
"level": "๊ณ ๊ธ"
|
| 1145 |
+
},
|
| 1146 |
+
{
|
| 1147 |
+
"id": "azure-network-watcher",
|
| 1148 |
+
"certification": "AZ-104",
|
| 1149 |
+
"title": "Network Watcher โ ๋คํธ์ํฌ ์ง๋จ",
|
| 1150 |
+
"summary": "Azure ๋คํธ์ํฌ ์ฐ๊ฒฐ ๋ฌธ์ ๋ฅผ ์ง๋จํ๋ ๋๊ตฌ ๋ชจ์์
๋๋ค. IP ํ๋ฆ ํ์ธ, ์ฐ๊ฒฐ ๋ฌธ์ ํด๊ฒฐ, NSG ์ง๋จ, ํจํท ์บก์ฒ ๋ฑ์ ์ ๊ณตํฉ๋๋ค.",
|
| 1151 |
+
"example": "# NSG๊ฐ ํจํท์ ํ์ฉํ๋์ง ํ์ธ\naz network watcher test-ip-flow \\\n --vm myVM \\\n --direction Inbound \\\n --protocol TCP \\\n --local 10.0.0.4:80 \\\n --remote 0.0.0.0:*",
|
| 1152 |
+
"common_mistake": "Network Watcher๋ region๋ณ๋ก ํ์ฑํํด์ผ ํฉ๋๋ค. VNet์ ์์ฑํ๋ฉด ๋๋ถ๋ถ ์๋ ํ์ฑํ๋์ง๋ง, ๋นํ์ฑํ๋ region์์๋ ์ง๋จ ๊ธฐ๋ฅ์ด ๋์ํ์ง ์์ต๋๋ค.",
|
| 1153 |
+
"keywords": [
|
| 1154 |
+
"Network Watcher",
|
| 1155 |
+
"IP flow verify",
|
| 1156 |
+
"connection troubleshoot",
|
| 1157 |
+
"NSG flow log",
|
| 1158 |
+
"packet capture"
|
| 1159 |
+
],
|
| 1160 |
+
"source_id": "azure-vnet-overview",
|
| 1161 |
+
"details": [
|
| 1162 |
+
"IP ํ๋ฆ ํ์ธ: ํน์ VM์์ ์ถ๋ฐ์ง/๋ชฉ์ ์ง IPยทํฌํธ๋ก NSG๊ฐ ํ์ฉ/๊ฑฐ๋ถ๋ฅผ ๊ฒฐ์ ํ๋ ๊ท์น์ ์ฐพ์์ค๋๋ค.",
|
| 1163 |
+
"NSG Flow Log: ์๋ธ๋ทยทNIC๋ฅผ ํต๊ณผํ๋ ํธ๋ํฝ์ ํ์ฉ/๊ฑฐ๋ถ ํ๋ฆ์ Storage Account์ ๊ธฐ๋กํฉ๋๋ค. Traffic Analytics์ ์ฐ๋ํด ์๊ฐํ.",
|
| 1164 |
+
"์ํ ํจํด: IP ํ๋ฆ ํ์ธ์ผ๋ก NSG ๊ท์น ์ง๋จ, Connection Troubleshoot์ผ๋ก VM ๊ฐ ์ฐ๊ฒฐ ๊ฒ์ฆ, NSG Flow Log ์ค์ ์ด ์ถ์ ๋ฉ๋๋ค."
|
| 1165 |
+
],
|
| 1166 |
+
"level": "์ค๊ธ"
|
| 1167 |
+
},
|
| 1168 |
+
{
|
| 1169 |
+
"id": "azure-move-resource",
|
| 1170 |
+
"certification": "AZ-104",
|
| 1171 |
+
"title": "๋ฆฌ์์ค ์ด๋ โ Resource Move",
|
| 1172 |
+
"summary": "๋ฆฌ์์ค๋ฅผ ๋ค๋ฅธ Resource Group์ด๋ ๋ค๋ฅธ Subscription์ผ๋ก ์ด๋ํฉ๋๋ค. ์ด๋ ์ค ๋ฆฌ์์ค๋ ์ ๊ธฐ๋ฉฐ, ๋ชจ๋ ๋ฆฌ์์ค๊ฐ ์ด๋์ ์ง์ํ์ง๋ ์์ต๋๋ค.",
|
| 1173 |
+
"example": "az resource move \\\n --destination-group targetRG \\\n --ids /subscriptions/SUB/resourceGroups/sourceRG/providers/Microsoft.Compute/virtualMachines/myVM",
|
| 1174 |
+
"common_mistake": "์ด๋ ํ ๋ฆฌ์์ค ID(ARM ID)๊ฐ ๋ณ๊ฒฝ๋ฉ๋๋ค. ์ด ID๋ฅผ ํ๋์ฝ๋ฉํ ์คํฌ๋ฆฝํธยท๋ชจ๋ํฐ๋งยทRole Assignment๋ ์
๋ฐ์ดํธ๊ฐ ํ์ํฉ๋๋ค.",
|
| 1175 |
+
"keywords": [
|
| 1176 |
+
"resource move",
|
| 1177 |
+
"RG move",
|
| 1178 |
+
"subscription move",
|
| 1179 |
+
"ARM ID change",
|
| 1180 |
+
"limitations"
|
| 1181 |
+
],
|
| 1182 |
+
"source_id": "azure-vm-overview",
|
| 1183 |
+
"details": [
|
| 1184 |
+
"์ด๋ ์ ์ ํจ์ฑ ๊ฒ์ฌ: `az resource invoke-action --action validate-move`๋ก ์ด๋ ๊ฐ๋ฅ ์ฌ๋ถ๋ฅผ ๋ฏธ๋ฆฌ ํ์ธํฉ๋๋ค.",
|
| 1185 |
+
"์ด๋์ด ๋ถ๊ฐํ ๊ฒฝ์ฐ: ํน์ ๋ฆฌ์์ค ์ ํ, ๊ตฌ๋
๊ฐ ์ด๋ ์ ์๋น์ค๋ณ ์ ํ, Key Vault(๊ตฌ๋
์ด๋ ์ ์ผ๋ถ ์ ํ) ๋ฑ.",
|
| 1186 |
+
"์ํ ํจํด: ์ด๋ ํ ๋ฆฌ์์ค ID ๋ณ๊ฒฝ ์ํฅ, ์ด๋ ๋ถ๊ฐ ๋ฆฌ์์ค ์์, ๊ตฌ๋
๊ฐ ์ด๋ ์ ์ถ๊ฐ ์กฐ๊ฑด(Entra ID ํ
๋ํธ ์ผ์น ๋ฑ)์ด ์ถ์ ๋ฉ๋๋ค."
|
| 1187 |
+
],
|
| 1188 |
+
"level": "๊ณ ๊ธ"
|
| 1189 |
+
},
|
| 1190 |
+
{
|
| 1191 |
+
"id": "azure-template-deployment",
|
| 1192 |
+
"certification": "AZ-104",
|
| 1193 |
+
"title": "ARM/Bicep โ ์ธํ๋ผ ์ฝ๋ ๋ฐฐํฌ",
|
| 1194 |
+
"summary": "ARM Template(JSON) ๋๋ Bicep(DSL)์ผ๋ก Azure ๋ฆฌ์์ค๋ฅผ ์ ์ธ์ ์ผ๋ก ์ ์ํ๊ณ ๋ฐ๋ณต ๊ฐ๋ฅํ๊ฒ ๋ฐฐํฌํฉ๋๋ค. IaC(Infrastructure as Code)์ ํ์ค ๋ฐฉ์์
๋๋ค.",
|
| 1195 |
+
"example": "# Bicep ๋ฐฐํฌ\naz deployment group create \\\n --resource-group myRG \\\n --template-file main.bicep \\\n --parameters environment=prod\n# ๊ตฌ๋
๋ ๋ฒจ ๋ฐฐํฌ\naz deployment sub create --template-file rg.bicep --location koreacentral",
|
| 1196 |
+
"common_mistake": "ARM ๋ฐฐํฌ๋ ๊ธฐ๋ณธ์ ์ผ๋ก Incremental ๋ชจ๋(๊ธฐ์กด ๋ฆฌ์์ค ์ ์ง, ์ ๋ฆฌ์์ค ์ถ๊ฐ)์
๋๋ค. Complete ๋ชจ๋๋ ํ
ํ๋ฆฟ์ ์๋ RG ๋ด ๋ฆฌ์์ค๋ฅผ ์ญ์ ํ๋ฏ๋ก ์ฃผ์๊ฐ ํ์ํฉ๋๋ค.",
|
| 1197 |
+
"keywords": [
|
| 1198 |
+
"ARM template",
|
| 1199 |
+
"Bicep",
|
| 1200 |
+
"IaC",
|
| 1201 |
+
"incremental",
|
| 1202 |
+
"complete",
|
| 1203 |
+
"deployment scope"
|
| 1204 |
+
],
|
| 1205 |
+
"source_id": "azure-vm-overview",
|
| 1206 |
+
"details": [
|
| 1207 |
+
"๋ฐฐํฌ ๋ฒ์: Resource Group(๋๋ถ๋ถ), Subscription(RG ์์ฑ ํฌํจ), Management Group(Policy/RBAC), Tenant ๋ ๋ฒจ ์ค ์ ํํฉ๋๋ค.",
|
| 1208 |
+
"Bicep์ ARM JSON๋ณด๋ค ๊ฐ๊ฒฐํ ๋ฌธ๋ฒ์ผ๋ก ๊ฐ์ ๊ฒฐ๊ณผ๋ฅผ ๋
๋๋ค. `bicep build`๋ก ARM JSON์ผ๋ก ์ปดํ์ผ ๊ฐ๋ฅํฉ๋๋ค.",
|
| 1209 |
+
"์ํ ํจํด: Incremental vs Complete ๋ชจ๋ ์ฐจ์ด, ๋ฐฐํฌ ๋ฒ์๋ณ ๋ช
๋ น(`deployment group/sub/mg create`), What-If ๊ฒ์ฆ ์ฌ์ฉ๋ฒ์ด ์ถ์ ๋ฉ๋๋ค."
|
| 1210 |
+
],
|
| 1211 |
+
"level": "๊ณ ๊ธ"
|
| 1212 |
+
}
|
| 1213 |
+
]
|
cert_study_app/content/azure/practices.json
ADDED
|
@@ -0,0 +1,152 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[
|
| 2 |
+
{
|
| 3 |
+
"id": "azure-lab-1",
|
| 4 |
+
"title": "๋ฆฌ์์ค ๊ทธ๋ฃน ์์ฑ",
|
| 5 |
+
"task_description": "Korea Central ์ง์ญ์ `myRG`๋ผ๋ ๋ฆฌ์์ค ๊ทธ๋ฃน์ ๋ง๋์ธ์.",
|
| 6 |
+
"expected_command": "az group create --name myRG --location koreacentral",
|
| 7 |
+
"grading_conditions": ["az group create", "--name myRG", "--location koreacentral"],
|
| 8 |
+
"hint": "`az group create --name <์ด๋ฆ> --location <์ง์ญ>` ํ์์ ์ฌ์ฉํฉ๋๋ค.",
|
| 9 |
+
"explanation": "๋ฆฌ์์ค ๊ทธ๋ฃน์ Azure ๋ฆฌ์์ค๋ฅผ ๋
ผ๋ฆฌ์ ์ผ๋ก ๋ฌถ๋ ์ปจํ
์ด๋์
๋๋ค. ์ง์ญ์ ๋ฉํ๋ฐ์ดํฐ ์ ์ฅ ์์น์ด๋ฉฐ ๋ด๋ถ ๋ฆฌ์์ค์ ๋ฌ๋ผ๋ ๋ฉ๋๋ค.",
|
| 10 |
+
"difficulty": "easy"
|
| 11 |
+
},
|
| 12 |
+
{
|
| 13 |
+
"id": "azure-lab-2",
|
| 14 |
+
"title": "์คํ ๋ฆฌ์ง ๊ณ์ ์์ฑ (Standard LRS)",
|
| 15 |
+
"task_description": "`myRG` ๋ฆฌ์์ค ๊ทธ๋ฃน์ Standard_LRS ์ค๋ณต์ฑ์ ๊ฐ์ง `mystorageacct` ์คํ ๋ฆฌ์ง ๊ณ์ ์ ์์ฑํ์ธ์.",
|
| 16 |
+
"expected_command": "az storage account create --name mystorageacct --resource-group myRG --sku Standard_LRS --kind StorageV2",
|
| 17 |
+
"grading_conditions": ["az storage account create", "--name mystorageacct", "--resource-group myRG", "--sku Standard_LRS"],
|
| 18 |
+
"hint": "`az storage account create`์ `--sku`์ `--kind` ์ต์
์ ์ถ๊ฐํฉ๋๋ค.",
|
| 19 |
+
"explanation": "StorageV2(๋ฒ์ฉ v2)๋ ํ์ฌ ๊ถ์ฅ ์คํ ๋ฆฌ์ง ์ข
๋ฅ์
๋๋ค. LRS๋ ๋จ์ผ ๋ฐ์ดํฐ์ผํฐ ๋ด 3๋ณต์ ๋ก ๊ฐ์ฅ ์ ๋ ดํ ์ค๋ณต์ฑ์
๋๋ค.",
|
| 20 |
+
"difficulty": "easy"
|
| 21 |
+
},
|
| 22 |
+
{
|
| 23 |
+
"id": "azure-lab-3",
|
| 24 |
+
"title": "๊ฐ์ ๋คํธ์ํฌ์ ์๋ธ๋ท ์์ฑ",
|
| 25 |
+
"task_description": "`myRG`์ ์ฃผ์ ๊ณต๊ฐ `10.0.0.0/16`, ์๋ธ๋ท `default`(`10.0.0.0/24`)๋ฅผ ๊ฐ์ง VNet `myVNet`์ ์์ฑํ์ธ์.",
|
| 26 |
+
"expected_command": "az network vnet create --name myVNet --resource-group myRG --address-prefix 10.0.0.0/16 --subnet-name default --subnet-prefix 10.0.0.0/24",
|
| 27 |
+
"grading_conditions": ["az network vnet create", "--name myVNet", "--address-prefix 10.0.0.0/16", "--subnet-name default", "--subnet-prefix 10.0.0.0/24"],
|
| 28 |
+
"hint": "`az network vnet create`์ `--address-prefix`์ `--subnet-name`, `--subnet-prefix`๋ฅผ ํจ๊ป ์ง์ ํฉ๋๋ค.",
|
| 29 |
+
"explanation": "VNet ์ฃผ์ ๊ณต๊ฐ(/16)๊ณผ ์๋ธ๋ท ๋ฒ์(/24)๋ ํฌํจ ๊ด๊ณ์ฌ์ผ ํฉ๋๋ค. Azure๋ ๊ฐ ์๋ธ๋ท์์ 5๊ฐ IP๋ฅผ ์์ฝํฉ๋๋ค.",
|
| 30 |
+
"difficulty": "easy"
|
| 31 |
+
},
|
| 32 |
+
{
|
| 33 |
+
"id": "azure-lab-4",
|
| 34 |
+
"title": "NSG ๊ท์น์ผ๋ก SSH ํ์ฉ",
|
| 35 |
+
"task_description": "NSG `myNSG`์ ์ฐ์ ์์ 100์ผ๋ก TCP ํฌํธ 22 ์ธ๋ฐ์ด๋๋ฅผ ํ์ฉํ๋ ๊ท์น `allow-ssh`๋ฅผ ์ถ๊ฐํ์ธ์.",
|
| 36 |
+
"expected_command": "az network nsg rule create --nsg-name myNSG --resource-group myRG --name allow-ssh --priority 100 --access Allow --protocol Tcp --destination-port-ranges 22",
|
| 37 |
+
"grading_conditions": ["az network nsg rule create", "--nsg-name myNSG", "--name allow-ssh", "--priority 100", "--access Allow", "--destination-port-ranges 22"],
|
| 38 |
+
"hint": "`az network nsg rule create`์ `--priority`, `--access`, `--protocol`, `--destination-port-ranges`๋ฅผ ์ง์ ํฉ๋๋ค.",
|
| 39 |
+
"explanation": "NSG ๊ท์น์ ์ฐ์ ์์ ์ซ์๊ฐ ๋ฎ์์๋ก ๋จผ์ ์ ์ฉ๋ฉ๋๋ค. 100์ ๊ธฐ๋ณธ ๊ท์น(65000~65500)๋ณด๋ค ํจ์ฌ ๋์ ์ฐ์ ์์์
๋๋ค.",
|
| 40 |
+
"difficulty": "easy"
|
| 41 |
+
},
|
| 42 |
+
{
|
| 43 |
+
"id": "azure-lab-5",
|
| 44 |
+
"title": "RBAC ์ญํ ํ ๋น (Contributor)",
|
| 45 |
+
"task_description": "`alice@example.com`์๊ฒ `myRG` ๋ฆฌ์์ค ๊ทธ๋ฃน ๋ฒ์์ `Contributor` ์ญํ ์ ํ ๋นํ์ธ์.",
|
| 46 |
+
"expected_command": "az role assignment create --assignee alice@example.com --role Contributor --scope /subscriptions/SUB_ID/resourceGroups/myRG",
|
| 47 |
+
"grading_conditions": ["az role assignment create", "--assignee alice@example.com", "--role Contributor", "--scope"],
|
| 48 |
+
"hint": "`az role assignment create`์ `--assignee`, `--role`, `--scope`๋ฅผ ์ง์ ํฉ๋๋ค. scope๋ ๋ฆฌ์์ค ๊ทธ๋ฃน์ ์ ์ฒด ARM ID์
๋๋ค.",
|
| 49 |
+
"explanation": "Contributor๋ ๋ฆฌ์์ค ์์ฑ/์์ /์ญ์ ๋ ๊ฐ๋ฅํ์ง๋ง ์ญํ ํ ๋น์ ๋ถ๊ฐํฉ๋๋ค. Owner๋ง ์ญํ ํ ๋น ๊ถํ์ ๊ฐ์ง๋๋ค.",
|
| 50 |
+
"difficulty": "medium"
|
| 51 |
+
},
|
| 52 |
+
{
|
| 53 |
+
"id": "azure-lab-6",
|
| 54 |
+
"title": "๋ฆฌ์์ค ์ ๊ธ ์ค์ (CanNotDelete)",
|
| 55 |
+
"task_description": "`myRG` ๋ฆฌ์์ค ๊ทธ๋ฃน์ `CanNotDelete` ์ ๊ธ `prod-lock`์ ์ค์ ํ์ธ์.",
|
| 56 |
+
"expected_command": "az lock create --name prod-lock --resource-group myRG --lock-type CanNotDelete",
|
| 57 |
+
"grading_conditions": ["az lock create", "--name prod-lock", "--resource-group myRG", "--lock-type CanNotDelete"],
|
| 58 |
+
"hint": "`az lock create`์ `--lock-type`์ผ๋ก `CanNotDelete` ๋๋ `ReadOnly`๋ฅผ ์ ํํฉ๋๋ค.",
|
| 59 |
+
"explanation": "CanNotDelete ์ ๊ธ์ ์ฝ๊ธฐ์ ์์ ์ ํ์ฉํ์ง๋ง ์ญ์ ๋ฅผ ์ฐจ๋จํฉ๋๋ค. Owner๋ผ๋ ์ ๊ธ์ ๋จผ์ ํด์ ํด์ผ ์ญ์ ํ ์ ์์ต๋๋ค.",
|
| 60 |
+
"difficulty": "easy"
|
| 61 |
+
},
|
| 62 |
+
{
|
| 63 |
+
"id": "azure-lab-7",
|
| 64 |
+
"title": "Blob ์ ๊ทผ ๊ณ์ธต ๋ณ๊ฒฝ (Cool)",
|
| 65 |
+
"task_description": "`mycontainer`์ `report.log` Blob์ Cool ๊ณ์ธต์ผ๋ก ๋ณ๊ฒฝํ์ธ์.",
|
| 66 |
+
"expected_command": "az storage blob set-tier --account-name mystorageacct --container-name mycontainer --name report.log --tier Cool",
|
| 67 |
+
"grading_conditions": ["az storage blob set-tier", "--account-name mystorageacct", "--container-name mycontainer", "--name report.log", "--tier Cool"],
|
| 68 |
+
"hint": "`az storage blob set-tier`์ `--tier`๋ก Hot/Cool/Cold/Archive๋ฅผ ์ง์ ํฉ๋๋ค.",
|
| 69 |
+
"explanation": "Cool ๊ณ์ธต์ 30์ผ ์ด์ ์ ์ฅํ๋ ๋ฐ์ดํฐ์ ์ ํฉํฉ๋๋ค. ์ ์ฅ ๋น์ฉ์ ๋ฎ์ง๋ง ์ ๊ทผ ๋น์ฉ์ด Hot๋ณด๋ค ๋์ต๋๋ค.",
|
| 70 |
+
"difficulty": "easy"
|
| 71 |
+
},
|
| 72 |
+
{
|
| 73 |
+
"id": "azure-lab-8",
|
| 74 |
+
"title": "VM ๋ฐฑ์
ํ์ฑํ",
|
| 75 |
+
"task_description": "`myVault` Recovery Services Vault์์ `myVM` ๊ฐ์ ๋จธ์ ์ ๋ฐฑ์
์ `DefaultPolicy`๋ก ํ์ฑํํ์ธ์.",
|
| 76 |
+
"expected_command": "az backup protection enable-for-vm --vault-name myVault --resource-group myRG --vm myVM --policy-name DefaultPolicy",
|
| 77 |
+
"grading_conditions": ["az backup protection enable-for-vm", "--vault-name myVault", "--vm myVM", "--policy-name DefaultPolicy"],
|
| 78 |
+
"hint": "`az backup protection enable-for-vm`์ vault, vm, policy ์ด๋ฆ์ ์ง์ ํฉ๋๋ค.",
|
| 79 |
+
"explanation": "VM ๋ฐฑ์
ํ์ฑํ ํ ์ต์ด ๋ฐฑ์
์ ์ฆ์ ํธ๋ฆฌ๊ฑฐํ๊ฑฐ๋ ๋ค์ ์์ฝ ์๊ฐ๊น์ง ๊ธฐ๋ค๋ฆฝ๋๋ค. Vault์ VM์ ๊ฐ์ region์ ์์ด์ผ ํฉ๋๋ค.",
|
| 80 |
+
"difficulty": "medium"
|
| 81 |
+
},
|
| 82 |
+
{
|
| 83 |
+
"id": "azure-lab-9",
|
| 84 |
+
"title": "Key Vault ๋น๋ฐ ์ ์ฅ",
|
| 85 |
+
"task_description": "`myKV` Key Vault์ `db-password`๋ผ๋ ์ด๋ฆ์ผ๋ก `MyP@ss123` ๋น๋ฐ์ ์ ์ฅํ์ธ์.",
|
| 86 |
+
"expected_command": "az keyvault secret set --vault-name myKV --name db-password --value MyP@ss123",
|
| 87 |
+
"grading_conditions": ["az keyvault secret set", "--vault-name myKV", "--name db-password", "--value"],
|
| 88 |
+
"hint": "`az keyvault secret set`์ vault ์ด๋ฆ, ๋น๋ฐ ์ด๋ฆ, ๊ฐ์ ์ง์ ํฉ๋๋ค.",
|
| 89 |
+
"explanation": "๋น๋ฐ์ ๋ฒ์ ๊ด๋ฆฌ๋ฉ๋๋ค. ๊ฐ์ ์ด๋ฆ์ผ๋ก ๋ค์ ์ ์ฅํ๋ฉด ์ ๋ฒ์ ์ด ์์ฑ๋๊ณ ์ด์ ๋ฒ์ ์ ๋นํ์ฑํ๋ฉ๋๋ค.",
|
| 90 |
+
"difficulty": "easy"
|
| 91 |
+
},
|
| 92 |
+
{
|
| 93 |
+
"id": "azure-lab-10",
|
| 94 |
+
"title": "VNet ํผ์ด๋ง ์์ฑ",
|
| 95 |
+
"task_description": "`VNet1`์์ `VNet2`๋ก ํฅํ๋ ํผ์ด๋ง `VNet1-to-VNet2`๋ฅผ ์์ฑํ์ธ์. (resource group: myRG)",
|
| 96 |
+
"expected_command": "az network vnet peering create --name VNet1-to-VNet2 --vnet-name VNet1 --remote-vnet VNet2 --resource-group myRG",
|
| 97 |
+
"grading_conditions": ["az network vnet peering create", "--name VNet1-to-VNet2", "--vnet-name VNet1", "--remote-vnet VNet2"],
|
| 98 |
+
"hint": "ํผ์ด๋ง์ ์๋ฐฉํฅ์ ๊ฐ๊ฐ ๋ง๋ค์ด์ผ ํฉ๋๋ค. ์ด ๋ช
๋ น์ VNet1โVNet2 ๋ฐฉํฅ์
๋๋ค.",
|
| 99 |
+
"explanation": "VNet ํผ์ด๋ง์ ๋น์ ์ด์ (non-transitive)์
๋๋ค. AโB, BโC๊ฐ ์์ด๋ A์์ C๋ก๋ ์ง์ ํต์ ๋ถ๊ฐ์ด๋ฉฐ AโC๋ฅผ ๋ณ๋ ์์ฑํด์ผ ํฉ๋๋ค.",
|
| 100 |
+
"difficulty": "medium"
|
| 101 |
+
},
|
| 102 |
+
{
|
| 103 |
+
"id": "azure-lab-11",
|
| 104 |
+
"title": "Private Endpoint ์์ฑ (Blob)",
|
| 105 |
+
"task_description": "`myVNet`์ `default` ์๋ธ๋ท์ ์คํ ๋ฆฌ์ง ๊ณ์ `mystorageacct`์ blob ์๋น์ค์ฉ Private Endpoint `myPE`๋ฅผ ์์ฑํ์ธ์.",
|
| 106 |
+
"expected_command": "az network private-endpoint create --name myPE --resource-group myRG --vnet-name myVNet --subnet default --private-connection-resource-id /subscriptions/SUB_ID/resourceGroups/myRG/providers/Microsoft.Storage/storageAccounts/mystorageacct --group-ids blob --connection-name myPEConnection",
|
| 107 |
+
"grading_conditions": ["az network private-endpoint create", "--name myPE", "--vnet-name myVNet", "--group-ids blob"],
|
| 108 |
+
"hint": "`--private-connection-resource-id`์ ์คํ ๋ฆฌ์ง ๊ณ์ ์ ์ ์ฒด ARM ID๋ฅผ ๋ฃ๊ณ , `--group-ids blob`์ ์ง์ ํฉ๋๋ค.",
|
| 109 |
+
"explanation": "Private Endpoint๋ PaaS ์๋น์ค์ VNet ๋ด ์ฌ์ค IP๋ฅผ ๋ถ์ฌํฉ๋๋ค. ์์ฑ ํ Private DNS Zone ์ฐ๊ฒฐ์ด ์์ด์ผ DNS ํด์์ด ์ฌ๋ฐ๋ฅด๊ฒ ๋ฉ๋๋ค.",
|
| 110 |
+
"difficulty": "hard"
|
| 111 |
+
},
|
| 112 |
+
{
|
| 113 |
+
"id": "azure-lab-12",
|
| 114 |
+
"title": "Azure Bastion ์์ฑ",
|
| 115 |
+
"task_description": "`myVNet`์ Public IP `myBastionIP`๋ฅผ ์ฌ์ฉํ๋ Azure Bastion `myBastion`์ Korea Central์ ์์ฑํ์ธ์.",
|
| 116 |
+
"expected_command": "az network bastion create --name myBastion --public-ip-address myBastionIP --resource-group myRG --vnet-name myVNet --location koreacentral",
|
| 117 |
+
"grading_conditions": ["az network bastion create", "--name myBastion", "--public-ip-address myBastionIP", "--vnet-name myVNet"],
|
| 118 |
+
"hint": "Bastion ์์ฑ ์ VNet์ `AzureBastionSubnet`(/27 ์ด์)์ด ๋ฐ๋์ ์์ด์ผ ํฉ๋๋ค.",
|
| 119 |
+
"explanation": "Azure Bastion์ VM์ Public IP ์์ด ํฌํธ์์ RDP/SSH ์ ๊ทผ์ ์ ๊ณตํฉ๋๋ค. AzureBastionSubnet ์ด๋ฆ์ ์ ํํ ์ผ์นํด์ผ ํฉ๋๋ค.",
|
| 120 |
+
"difficulty": "medium"
|
| 121 |
+
},
|
| 122 |
+
{
|
| 123 |
+
"id": "azure-lab-13",
|
| 124 |
+
"title": "App Service ์น์ฑ ์์ฑ",
|
| 125 |
+
"task_description": "`myPlan` App Service ํ๋์ ์ฌ์ฉํ๋ `myWebApp` ์น์ฑ์ Node.js 18 LTS ๋ฐํ์์ผ๋ก ์์ฑํ์ธ์.",
|
| 126 |
+
"expected_command": "az webapp create --name myWebApp --resource-group myRG --plan myPlan --runtime NODE:18-lts",
|
| 127 |
+
"grading_conditions": ["az webapp create", "--name myWebApp", "--resource-group myRG", "--plan myPlan", "--runtime"],
|
| 128 |
+
"hint": "`az webapp create`์ `--plan`๊ณผ `--runtime`์ ์ง์ ํฉ๋๋ค. ๋ฐํ์ ๋ชฉ๋ก์ `az webapp list-runtimes`๋ก ํ์ธํฉ๋๋ค.",
|
| 129 |
+
"explanation": "App Service๋ ๋ฐํ์ ํ๊ฒฝ๊ณผ ๋ฐฐํฌ ๋ฐฉ๋ฒ์ ์ ์ฐํ๊ฒ ์ ํํ ์ ์๋ PaaS์
๋๋ค. ๊ฐ์ ํ๋์ ์ฑ๋ค์ ์ปดํจํ
๋ฆฌ์์ค๋ฅผ ๊ณต์ ํฉ๋๋ค.",
|
| 130 |
+
"difficulty": "easy"
|
| 131 |
+
},
|
| 132 |
+
{
|
| 133 |
+
"id": "azure-lab-14",
|
| 134 |
+
"title": "๋ฐฐํฌ ์ฌ๋กฏ ์์ฑ (staging)",
|
| 135 |
+
"task_description": "`myWebApp` ์น์ฑ์ `staging` ๋ฐฐํฌ ์ฌ๋กฏ์ ์์ฑํ์ธ์.",
|
| 136 |
+
"expected_command": "az webapp deployment slot create --name myWebApp --resource-group myRG --slot staging",
|
| 137 |
+
"grading_conditions": ["az webapp deployment slot create", "--name myWebApp", "--slot staging"],
|
| 138 |
+
"hint": "`az webapp deployment slot create`์ `--slot`์ผ๋ก ์ฌ๋กฏ ์ด๋ฆ์ ์ง์ ํฉ๋๋ค. Standard ์ด์ ํ๋์ด ํ์ํฉ๋๋ค.",
|
| 139 |
+
"explanation": "๋ฐฐํฌ ์ฌ๋กฏ์ ๋ค์ดํ์ ์์ด ์คํ
์ด์ง ๋ฒ์ ์ ํ
์คํธํ๊ณ swap์ผ๋ก ์ฆ์ ๊ต์ฒดํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค.",
|
| 140 |
+
"difficulty": "easy"
|
| 141 |
+
},
|
| 142 |
+
{
|
| 143 |
+
"id": "azure-lab-15",
|
| 144 |
+
"title": "๊ฒฝ๋ณด ๊ท์น ์์ฑ (CPU 80%)",
|
| 145 |
+
"task_description": "`myVM`์ ํ๊ท CPU ์ฌ์ฉ๋ฅ ์ด 80%๋ฅผ ์ด๊ณผํ๋ฉด `alice@example.com`์ผ๋ก ์๋ฆผ์ ๋ณด๋ด๋ ๊ฒฝ๋ณด ๊ท์น์ ์์ฑํ์ธ์.",
|
| 146 |
+
"expected_command": "az monitor alert create --name highCPU --resource-group myRG --resource myVM --resource-type Microsoft.Compute/virtualMachines --condition avg Percentage CPU > 80 --action email alice@example.com",
|
| 147 |
+
"grading_conditions": ["az monitor alert create", "--name highCPU", "--condition", "Percentage CPU", "> 80", "--action email alice@example.com"],
|
| 148 |
+
"hint": "`az monitor alert create`์ `--condition`์ผ๋ก ๋ฉํธ๋ฆญ ์ด๋ฆ๊ณผ ์๊ณ๊ฐ์, `--action`์ผ๋ก ์๋ฆผ ๋ฐฉ๋ฒ์ ์ง์ ํฉ๋๋ค.",
|
| 149 |
+
"explanation": "๊ฒฝ๋ณด๋ Action Group ์์ด๋ ๋ฐ์ํด๋ ์ ์ ์์ต๋๋ค. --action email๋ก ๊ฐ๋จํ๊ฒ ์ง์ ํ๊ฑฐ๋, ๋ณ๋ Action Group์ ์์ฑํด ์ฐ๊ฒฐํฉ๋๋ค.",
|
| 150 |
+
"difficulty": "medium"
|
| 151 |
+
}
|
| 152 |
+
]
|
cert_study_app/content/azure/quizzes.json
ADDED
|
@@ -0,0 +1,1058 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[
|
| 2 |
+
{
|
| 3 |
+
"id": "azure-q28",
|
| 4 |
+
"lesson_id": "azure-subscription",
|
| 5 |
+
"question_type": "multiple_choice",
|
| 6 |
+
"question": "Azure์์ ๊ณผ๊ธ๊ณผ ๋ฆฌ์์ค ๋ฐฐํฌ์ ์ฃผ์ ๊ฒฝ๊ณ ๋จ์๋?",
|
| 7 |
+
"options": [
|
| 8 |
+
"Subscription",
|
| 9 |
+
"Resource Group",
|
| 10 |
+
"Management Group",
|
| 11 |
+
"Tenant"
|
| 12 |
+
],
|
| 13 |
+
"answer": "Subscription",
|
| 14 |
+
"explanation": "Subscription์ Azure ๊ณผ๊ธ, ๋ฆฌ์์ค ํ ๋น๋, RBAC/Policy ์ ์ฉ์ ์ฃผ์ ๊ฒฝ๊ณ์
๋๋ค. Resource Group์ Subscription ์๋, Management Group์ ์ฌ๋ฌ Subscription์ ๋ฌถ๋ ์์ ๊ณ์ธต์
๋๋ค.",
|
| 15 |
+
"difficulty": "easy",
|
| 16 |
+
"source_id": "manual-az104-basic"
|
| 17 |
+
},
|
| 18 |
+
{
|
| 19 |
+
"id": "azure-q29",
|
| 20 |
+
"lesson_id": "azure-tags",
|
| 21 |
+
"question_type": "multiple_choice",
|
| 22 |
+
"question": "Azure Tags์ ์ฃผ๋ ์ฉ๋๋ก ๊ฐ์ฅ ๋ง๋ ๊ฒ์?",
|
| 23 |
+
"options": [
|
| 24 |
+
"๋ฆฌ์์ค์ key/value ๋ฉํ๋ฐ์ดํฐ๋ฅผ ๋ถ์ฌ ๋น์ฉ๊ณผ ์์ ์๋ฅผ ๋ถ๋ฅํ๋ค",
|
| 25 |
+
"๋ฆฌ์์ค ์ ๊ทผ ๊ถํ์ ์ง์ ์ ์ดํ๋ค",
|
| 26 |
+
"VM ์ธ์คํด์ค๋ฅผ ์๋์ผ๋ก ์ฌ์์ํ๋ค",
|
| 27 |
+
"NSG ์ธ๋ฐ์ด๋ ๊ท์น์ ์ ์ํ๋ค"
|
| 28 |
+
],
|
| 29 |
+
"answer": "๋ฆฌ์์ค์ key/value ๋ฉํ๋ฐ์ดํฐ๋ฅผ ๋ถ์ฌ ๋น์ฉ๊ณผ ์์ ์๋ฅผ ๋ถ๋ฅํ๋ค",
|
| 30 |
+
"explanation": "Tags๋ ๋น์ฉ ๋ถ์, ์์ ์ ์๋ณ, ํ๊ฒฝ ๊ตฌ๋ถ์ ์ํ ๋ฉํ๋ฐ์ดํฐ์
๋๋ค. ๋ฆฌ์์ค ์ ๊ทผ ๊ถํ ์ ์ด๋ RBAC๊ฐ ๋ด๋นํฉ๋๋ค.",
|
| 31 |
+
"difficulty": "easy",
|
| 32 |
+
"source_id": "manual-az104-basic"
|
| 33 |
+
},
|
| 34 |
+
{
|
| 35 |
+
"id": "azure-q30",
|
| 36 |
+
"lesson_id": "azure-custom-role",
|
| 37 |
+
"question_type": "multiple_choice",
|
| 38 |
+
"question": "Azure Custom Role์ `AssignableScopes`๋ฅผ ์๋ชป ์ค์ ํ๋ฉด ์๊ธฐ๋ ๋ฌธ์ ๋?",
|
| 39 |
+
"options": [
|
| 40 |
+
"ํ์ํ ๋ฒ์์ ์ญํ ์ ํ ๋นํ ์ ์๊ฒ ๋๋ค",
|
| 41 |
+
"์ญํ ์ ์ ์๋ actions์ด ๋ชจ๋ ๋ฌด์๋๋ค",
|
| 42 |
+
"VM์ด ์๋์ผ๋ก ์ค์ง๋๋ค",
|
| 43 |
+
"Blob ์ ๊ทผ์ด ์ฐจ๋จ๋๋ค"
|
| 44 |
+
],
|
| 45 |
+
"answer": "ํ์ํ ๋ฒ์์ ์ญํ ์ ํ ๋นํ ์ ์๊ฒ ๋๋ค",
|
| 46 |
+
"explanation": "`AssignableScopes`๋ ์ด ์ญํ ์ ํ ๋นํ ์ ์๋ ๋ฒ์๋ฅผ ์ ํํฉ๋๋ค. ๋๋ฌด ์ข๊ฒ ์ค์ ํ๋ฉด ํ์ํ subscription์ด๋ resource group์ ํ ๋นํ ์ ์์ต๋๋ค.",
|
| 47 |
+
"difficulty": "medium",
|
| 48 |
+
"source_id": "azure-rbac-overview"
|
| 49 |
+
},
|
| 50 |
+
{
|
| 51 |
+
"id": "azure-q31",
|
| 52 |
+
"lesson_id": "azure-lifecycle",
|
| 53 |
+
"question_type": "multiple_choice",
|
| 54 |
+
"question": "Azure Storage Lifecycle ๊ด๋ฆฌ์ ์ฃผ๋ ๋ชฉ์ ์?",
|
| 55 |
+
"options": [
|
| 56 |
+
"Blob ์ ๊ทผ ๋น๋์ ๋ฐ๋ผ ์๋์ผ๋ก tier๋ฅผ ์ด๋ํ๊ฑฐ๋ ์ญ์ ํด ๋น์ฉ์ ์ต์ ํํ๋ค",
|
| 57 |
+
"VM์ ์๋์ผ๋ก ๋ฐฑ์
ํ๋ค",
|
| 58 |
+
"NSG ๊ท์น์ ์ฃผ๊ธฐ์ ์ผ๋ก ๊ฐฑ์ ํ๋ค",
|
| 59 |
+
"DNS ๋ ์ฝ๋๋ฅผ ์๋ ์
๋ฐ์ดํธํ๋ค"
|
| 60 |
+
],
|
| 61 |
+
"answer": "Blob ์ ๊ทผ ๋น๋์ ๋ฐ๋ผ ์๋์ผ๋ก tier๋ฅผ ์ด๋ํ๊ฑฐ๋ ์ญ์ ํด ๋น์ฉ์ ์ต์ ํํ๋ค",
|
| 62 |
+
"explanation": "Lifecycle ์ ์ฑ
์ ๋ง์ง๋ง ์์ ยท์ ๊ทผ ์ดํ ๊ฒฝ๊ณผ ์ผ์๋ฅผ ๊ธฐ์ค์ผ๋ก Blob์ ์๋์ผ๋ก Cool/Archive๋ก ์ด๋ํ๊ฑฐ๋ ์ญ์ ํฉ๋๋ค.",
|
| 63 |
+
"difficulty": "easy",
|
| 64 |
+
"source_id": "azure-blob-access-tiers"
|
| 65 |
+
},
|
| 66 |
+
{
|
| 67 |
+
"id": "azure-q32",
|
| 68 |
+
"lesson_id": "azure-files",
|
| 69 |
+
"question_type": "multiple_choice",
|
| 70 |
+
"question": "Azure Files์ Blob Storage์ ์ฃผ์ ์ฐจ์ด๋ก ๊ฐ์ฅ ๋ง๋ ๊ฒ์?",
|
| 71 |
+
"options": [
|
| 72 |
+
"Azure Files๋ SMB/NFS ํ์ผ ๊ณต์ , Blob์ REST API ๊ธฐ๋ฐ ๊ฐ์ฒด ์ ์ฅ์ด๋ค",
|
| 73 |
+
"๋ ์๋น์ค๋ ๋์ผํ ๋ฐฉ์์ผ๋ก ๋ง์ดํธ๋๋ค",
|
| 74 |
+
"Blob์ด ํ์ผ ๊ณต์ ์ ์ ํฉํ๊ณ Azure Files๊ฐ ๊ฐ์ฒด ์ ์ฅ์ ์ ํฉํ๋ค",
|
| 75 |
+
"Azure Files๋ ๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์๋น์ค๋ค"
|
| 76 |
+
],
|
| 77 |
+
"answer": "Azure Files๋ SMB/NFS ํ์ผ ๊ณต์ , Blob์ REST API ๊ธฐ๋ฐ ๊ฐ์ฒด ์ ์ฅ์ด๋ค",
|
| 78 |
+
"explanation": "Azure Files๋ ๋คํธ์ํฌ ๋๋ผ์ด๋ธ์ฒ๋ผ ๋ง์ดํธํด ์ฌ์ฉํ๊ณ , Blob Storage๋ REST API๋ก ๋น์ ํ ๋ฐ์ดํฐ(์ด๋ฏธ์ง, ๋ก๊ทธ, ๋ฐฑ์
)๋ฅผ ์ ์ฅํฉ๋๋ค.",
|
| 79 |
+
"difficulty": "easy",
|
| 80 |
+
"source_id": "azure-storage-account"
|
| 81 |
+
},
|
| 82 |
+
{
|
| 83 |
+
"id": "azure-q33",
|
| 84 |
+
"lesson_id": "azure-managed-disk",
|
| 85 |
+
"question_type": "multiple_choice",
|
| 86 |
+
"question": "Azure VM์์ ์ฌ์์ํ๋ฉด ๋ฐ์ดํฐ๊ฐ ์ฌ๋ผ์ง ์ ์๋ ๋์คํฌ ์ ํ์?",
|
| 87 |
+
"options": [
|
| 88 |
+
"Temporary disk",
|
| 89 |
+
"OS disk",
|
| 90 |
+
"Premium SSD data disk",
|
| 91 |
+
"Ultra disk"
|
| 92 |
+
],
|
| 93 |
+
"answer": "Temporary disk",
|
| 94 |
+
"explanation": "์์ ๋์คํฌ(temporary disk)๋ VM ์ฌ์์ ์ ๋ฐ์ดํฐ๊ฐ ์ ์ง๋์ง ์์ต๋๋ค. OS disk์ data disk๋ ์๊ตฌ ์ ์ฅ์๋ก ์ฌ์์์๋ ๋ฐ์ดํฐ๊ฐ ๋ณด์กด๋ฉ๋๋ค.",
|
| 95 |
+
"difficulty": "easy",
|
| 96 |
+
"source_id": "azure-vm-overview"
|
| 97 |
+
},
|
| 98 |
+
{
|
| 99 |
+
"id": "azure-q34",
|
| 100 |
+
"lesson_id": "azure-autoscale",
|
| 101 |
+
"question_type": "multiple_choice",
|
| 102 |
+
"question": "Autoscale์ด ์ฐ๊ฒฐ๋์ด ์ธ์คํด์ค ์๋ฅผ ์๋์ผ๋ก ์กฐ์ ํ ์ ์๋ ๋ฆฌ์์ค๋?",
|
| 103 |
+
"options": [
|
| 104 |
+
"Virtual Machine Scale Sets (VMSS)",
|
| 105 |
+
"Recovery Services Vault",
|
| 106 |
+
"Private DNS Zone",
|
| 107 |
+
"Activity Log"
|
| 108 |
+
],
|
| 109 |
+
"answer": "Virtual Machine Scale Sets (VMSS)",
|
| 110 |
+
"explanation": "Autoscale์ VMSS๋ App Service Plan ๊ฐ์ ํ์ฅ ๊ฐ๋ฅํ ๋ฆฌ์์ค์ ์ฐ๊ฒฐ๋ฉ๋๋ค. CPU/๋ฉ๋ชจ๋ฆฌ ๋ฉํธ๋ฆญ ์กฐ๊ฑด์ ๋ฐ๋ผ ์ธ์คํด์ค ์๋ฅผ ์๋์ผ๋ก ๋๋ฆฌ๊ฑฐ๋ ์ค์
๋๋ค.",
|
| 111 |
+
"difficulty": "easy",
|
| 112 |
+
"source_id": "azure-vmss-overview"
|
| 113 |
+
},
|
| 114 |
+
{
|
| 115 |
+
"id": "azure-q35",
|
| 116 |
+
"lesson_id": "azure-route-table",
|
| 117 |
+
"question_type": "multiple_choice",
|
| 118 |
+
"question": "UDR(User Defined Route, ์ฌ์ฉ์ ์ ์ ๊ฒฝ๋ก)์ ์ฃผ๋ ์ญํ ์?",
|
| 119 |
+
"options": [
|
| 120 |
+
"Subnet ํธ๋ํฝ์ next hop์ ๊ธฐ๋ณธ Azure ๋ผ์ฐํ
๋์ NVA๋ ๋ค๋ฅธ ๊ฒฝ๋ก๋ก ์ ์ดํ๋ค",
|
| 121 |
+
"VM์ ํฌ๊ธฐ๋ฅผ ์๋์ผ๋ก ์กฐ์ ํ๋ค",
|
| 122 |
+
"Blob ๋ฐ์ดํฐ๋ฅผ ์ง์ญ ๊ฐ ๋ณต์ ํ๋ค",
|
| 123 |
+
"DNS ์ด๋ฆ์ IP๋ก ํด์ํ๋ค"
|
| 124 |
+
],
|
| 125 |
+
"answer": "Subnet ํธ๋ํฝ์ next hop์ ๊ธฐ๋ณธ Azure ๋ผ์ฐํ
๋์ NVA๋ ๋ค๋ฅธ ๊ฒฝ๋ก๋ก ์ ์ดํ๋ค",
|
| 126 |
+
"explanation": "UDR์ ๊ธฐ๋ณธ Azure ๋ผ์ฐํ
์ ์ฌ์ ์ํด ๋ฐฉํ๋ฒฝ(NVA)์ด๋ ํน์ ์ฅ์น๋ฅผ ํตํด ํธ๋ํฝ์ ๋ณด๋ผ ๋ ์ฌ์ฉํฉ๋๋ค. NSG์ ์ญํ ์ด ๋ค๋ฆ
๋๋ค.",
|
| 127 |
+
"difficulty": "medium",
|
| 128 |
+
"source_id": "azure-vnet-overview"
|
| 129 |
+
},
|
| 130 |
+
{
|
| 131 |
+
"id": "azure-q36",
|
| 132 |
+
"lesson_id": "azure-private-endpoint",
|
| 133 |
+
"question_type": "multiple_choice",
|
| 134 |
+
"question": "Private Endpoint ์ฐ๊ฒฐ ๋ฌธ์ ์์ DNS๋ฅผ ํจ๊ป ํ์ธํด์ผ ํ๋ ์ด์ ๋?",
|
| 135 |
+
"options": [
|
| 136 |
+
"Private Endpoint๊ฐ private IP๋ฅผ ์ฐ๋ฏ๋ก DNS๊ฐ ์ฌ๋ฐ๋ฅธ IP๋ก ํด์ํด์ผ ์ฐ๊ฒฐ๋๊ธฐ ๋๋ฌธ์ด๋ค",
|
| 137 |
+
"DNS๊ฐ Blob ์ ๊ทผ tier๋ฅผ ๊ฒฐ์ ํ๊ธฐ ๋๋ฌธ์ด๋ค",
|
| 138 |
+
"DNS๊ฐ NSG ๊ท์น์ ์ ์ฉํ๊ธฐ ๋๋ฌธ์ด๋ค",
|
| 139 |
+
"DNS๊ฐ VM ํฌ๊ธฐ๋ฅผ ์ ์ดํ๊ธฐ ๋๋ฌธ์ด๋ค"
|
| 140 |
+
],
|
| 141 |
+
"answer": "Private Endpoint๊ฐ private IP๋ฅผ ์ฐ๋ฏ๋ก DNS๊ฐ ์ฌ๋ฐ๋ฅธ IP๋ก ํด์ํด์ผ ์ฐ๊ฒฐ๋๊ธฐ ๋๋ฌธ์ด๋ค",
|
| 142 |
+
"explanation": "Private Endpoint๋ VNet ๋ด๋ถ private IP๋ฅผ ์ฌ์ฉํฉ๋๋ค. DNS๊ฐ ํด๋น ์๋น์ค๋ฅผ public IP ๋์ ์ฌ๋ฐ๋ฅธ private IP๋ก ํด์ํ์ง ๋ชปํ๋ฉด ์ฐ๊ฒฐ์ด ์คํจํฉ๋๋ค.",
|
| 143 |
+
"difficulty": "medium",
|
| 144 |
+
"source_id": "azure-private-endpoint"
|
| 145 |
+
},
|
| 146 |
+
{
|
| 147 |
+
"id": "azure-q37",
|
| 148 |
+
"lesson_id": "azure-monitor-metrics",
|
| 149 |
+
"question_type": "multiple_choice",
|
| 150 |
+
"question": "Azure Monitor Metrics์ Logs์ ์ฐจ์ด๋ก ๊ฐ์ฅ ๋ง๋ ๊ฒ์?",
|
| 151 |
+
"options": [
|
| 152 |
+
"Metrics๋ ์์นํ ์๊ณ์ด ๋ฐ์ดํฐ, Logs๋ KQL๋ก ์กฐํํ๋ ๊ตฌ์กฐํ ๋ก๊ทธ ๋ฐ์ดํฐ๋ค",
|
| 153 |
+
"๋ ์๋น์ค ๋ชจ๋ KQL๋ก๋ง ์กฐํํ๋ค",
|
| 154 |
+
"Metrics๋ ํ
์คํธ ๋ก๊ทธ, Logs๋ ์ซ์ ๊ฐ๋ง ์ ์ฅํ๋ค",
|
| 155 |
+
"Metrics๋ ๋ฐฑ์
, Logs๋ ๋ณต๊ตฌ์ ์ฌ์ฉํ๋ค"
|
| 156 |
+
],
|
| 157 |
+
"answer": "Metrics๋ ์์นํ ์๊ณ์ด ๋ฐ์ดํฐ, Logs๋ KQL๋ก ์กฐํํ๋ ๊ตฌ์กฐํ ๋ก๊ทธ ๋ฐ์ดํฐ๋ค",
|
| 158 |
+
"explanation": "Metrics๋ CPU%, ๋คํธ์ํฌ ๋ฐ์ดํธ์ฒ๋ผ ์ซ์ ๊ธฐ๋ฐ ์๊ณ์ด ๋ฐ์ดํฐ์ด๊ณ , Logs๋ Log Analytics workspace์์ KQL๋ก ์กฐํํ๋ ๊ตฌ์กฐํ๋ ๋ก๊ทธ ๋ฐ์ดํฐ์
๋๋ค.",
|
| 159 |
+
"difficulty": "medium",
|
| 160 |
+
"source_id": "azure-monitor-overview"
|
| 161 |
+
},
|
| 162 |
+
{
|
| 163 |
+
"id": "azure-q38",
|
| 164 |
+
"lesson_id": "azure-activity-log",
|
| 165 |
+
"question_type": "multiple_choice",
|
| 166 |
+
"question": "Azure Activity Log์์ ํ์ธํ๊ธฐ ๊ฐ์ฅ ์ ํฉํ ์ ๋ณด๋?",
|
| 167 |
+
"options": [
|
| 168 |
+
"๋๊ฐ ์ด๋ค ๋ฆฌ์์ค๋ฅผ ์ธ์ ์์ ํ๊ฑฐ๋ ์ญ์ ํ๋์ง ๊ด๋ฆฌ ์ด๋ฒคํธ",
|
| 169 |
+
"VM ๋ด๋ถ ์ ํ๋ฆฌ์ผ์ด์
์ค๋ฅ ์คํ ํธ๋ ์ด์ค",
|
| 170 |
+
"Blob ๋ฐ์ดํฐ ์ ๊ทผ ๋ด์ญ",
|
| 171 |
+
"๋คํธ์ํฌ ํจํท์ ํ์ด๋ก๋"
|
| 172 |
+
],
|
| 173 |
+
"answer": "๋๊ฐ ์ด๋ค ๋ฆฌ์์ค๋ฅผ ์ธ์ ์์ ํ๊ฑฐ๋ ์ญ์ ํ๋์ง ๊ด๋ฆฌ ์ด๋ฒคํธ",
|
| 174 |
+
"explanation": "Activity Log๋ subscription ์์ค์ ๊ด๋ฆฌ ์์
(๋๊ฐ ๋ฌด์์ ์ธ์ ํ๋์ง)์ ๊ธฐ๋กํฉ๋๋ค. ์ ํ๋ฆฌ์ผ์ด์
๋ด๋ถ ์ค๋ฅ ๋ก๊ทธ๋ Diagnostic Settings๋ Application Insights์์ ๋ด
๋๋ค.",
|
| 175 |
+
"difficulty": "easy",
|
| 176 |
+
"source_id": "azure-monitor-overview"
|
| 177 |
+
},
|
| 178 |
+
{
|
| 179 |
+
"id": "azure-q39",
|
| 180 |
+
"lesson_id": "azure-restore",
|
| 181 |
+
"question_type": "multiple_choice",
|
| 182 |
+
"question": "Recovery Services Vault์์ ๋ณต๊ตฌ ๊ฐ๋ฅํ ์์ ์ ๊ฒฐ์ ํ๋ ๊ฒ์?",
|
| 183 |
+
"options": [
|
| 184 |
+
"Backup Policy์ ๋ฐฑ์
๋น๋์ ๋ณด์กด ๊ธฐ๊ฐ",
|
| 185 |
+
"VM์ ํฌ๊ธฐ(size)",
|
| 186 |
+
"NSG ๊ท์น ์",
|
| 187 |
+
"VNet ์ฃผ์ ๊ณต๊ฐ"
|
| 188 |
+
],
|
| 189 |
+
"answer": "Backup Policy์ ๋ฐฑ์
๋น๋์ ๋ณด์กด ๊ธฐ๊ฐ",
|
| 190 |
+
"explanation": "๋ณต๊ตฌ ์ง์ (recovery point)์ backup policy์์ ์ ์ํ ์ผ์ ๊ณผ ๋ณด์กด ๊ธฐ๊ฐ์ ๋ฐ๋ผ ์์ฑ๋ฉ๋๋ค. ๋ณด์กด ๊ธฐ๊ฐ์ด ์ง๋ ๋ณต๊ตฌ ์ง์ ์ ์๋ ์ญ์ ๋ฉ๋๋ค.",
|
| 191 |
+
"difficulty": "easy",
|
| 192 |
+
"source_id": "azure-recovery-services-vault"
|
| 193 |
+
},
|
| 194 |
+
{
|
| 195 |
+
"id": "azure-q40",
|
| 196 |
+
"lesson_id": "azure-app-service-plan",
|
| 197 |
+
"question_type": "multiple_choice",
|
| 198 |
+
"question": "App Service Plan์ด Web App๊ณผ์ ๊ด๊ณ์์ ์ ์ํ๋ ๊ฒ์?",
|
| 199 |
+
"options": [
|
| 200 |
+
"Web App์ด ์ฌ์ฉํ ์ปดํจํ
๋ฆฌ์์ค์ ๊ฐ๊ฒฉ ํฐ์ด",
|
| 201 |
+
"Web App์ ๋๋ฉ์ธ ์ด๋ฆ",
|
| 202 |
+
"Web App์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์คํค๋ง",
|
| 203 |
+
"Web App์ ์ฌ์ฉ์ ์ธ์ฆ ๋ฐฉ์"
|
| 204 |
+
],
|
| 205 |
+
"answer": "Web App์ด ์ฌ์ฉํ ์ปดํจํ
๋ฆฌ์์ค์ ๊ฐ๊ฒฉ ํฐ์ด",
|
| 206 |
+
"explanation": "App Service Plan์ CPU, ๋ฉ๋ชจ๋ฆฌ, ์ธ์คํด์ค ์, ๊ฐ๊ฒฉ ํฐ์ด๋ฅผ ์ ์ํฉ๋๋ค. ์ฌ๋ฌ Web App์ด ํ๋์ Plan์ ๊ณต์ ํ ์ ์์ผ๋ฉฐ, ์ค์ผ์ผ ์ค์ ์ Plan ์์ค์์ ํฉ๋๋ค.",
|
| 207 |
+
"difficulty": "easy",
|
| 208 |
+
"source_id": "azure-vm-overview"
|
| 209 |
+
},
|
| 210 |
+
{
|
| 211 |
+
"id": "azure-q41",
|
| 212 |
+
"lesson_id": "azure-container-registry",
|
| 213 |
+
"question_type": "multiple_choice",
|
| 214 |
+
"question": "Azure Container Registry(ACR)์ ์ฃผ๋ ์ญํ ์?",
|
| 215 |
+
"options": [
|
| 216 |
+
"์ปจํ
์ด๋ ์ด๋ฏธ์ง๋ฅผ ์ ์ฅํ๊ณ ๊ด๋ฆฌํ๋ ํ๋ผ์ด๋น ๋ ์ง์คํธ๋ฆฌ",
|
| 217 |
+
"์ปจํ
์ด๋๋ฅผ ์ง์ ์คํํ๋ ์๋ฒ๋ฆฌ์ค ์๋น์ค",
|
| 218 |
+
"VM์ ์ปจํ
์ด๋๋ก ๋ณํํ๋ ๋๊ตฌ",
|
| 219 |
+
"Kubernetes ํด๋ฌ์คํฐ๋ฅผ ๊ด๋ฆฌํ๋ ์๋น์ค"
|
| 220 |
+
],
|
| 221 |
+
"answer": "์ปจํ
์ด๋ ์ด๋ฏธ์ง๋ฅผ ์ ์ฅํ๊ณ ๊ด๋ฆฌํ๋ ํ๋ผ์ด๋น ๋ ์ง์คํธ๋ฆฌ",
|
| 222 |
+
"explanation": "ACR์ Docker Hub ๊ฐ์ ์ด๋ฏธ์ง ์ ์ฅ์์
๋๋ค. ์ด๋ฏธ์ง ์คํ์ ACI, AKS, App Service๊ฐ ๋ด๋นํ๊ณ ACR์ ์ด๋ฏธ์ง ์ ์ฅ/๋ฐฐํฌ์ ํนํ๋ฉ๋๋ค.",
|
| 223 |
+
"difficulty": "easy",
|
| 224 |
+
"source_id": "azure-vm-overview"
|
| 225 |
+
},
|
| 226 |
+
{
|
| 227 |
+
"id": "azure-q42",
|
| 228 |
+
"lesson_id": "azure-cost-management",
|
| 229 |
+
"question_type": "multiple_choice",
|
| 230 |
+
"question": "Azure Tags๊ฐ ๋น์ฉ ๊ด๋ฆฌ์์ ๋์์ ์ฃผ๋ ๋ฐฉ์์?",
|
| 231 |
+
"options": [
|
| 232 |
+
"๋ฆฌ์์ค๋ฅผ ํ๊ฒฝยทํยทํ๋ก์ ํธ๋ณ๋ก ๋ถ๋ฅํด Cost Management์์ ํํฐ๋ง์ ์ฝ๊ฒ ํด์ค๋ค",
|
| 233 |
+
"๋ถํ์ํ ๋ฆฌ์์ค๋ฅผ ์๋์ผ๋ก ์ญ์ ํด ๋น์ฉ์ ์ค์ธ๋ค",
|
| 234 |
+
"VM์ ์๋์ผ๋ก ์ค์ผ์ผ๋ค์ดํด ์ ์ฝํ๋ค",
|
| 235 |
+
"Blob tier๋ฅผ ์๋์ผ๋ก ๋ฎ์ถฐ ์ ์ฝํ๋ค"
|
| 236 |
+
],
|
| 237 |
+
"answer": "๋ฆฌ์์ค๋ฅผ ํ๊ฒฝยทํยทํ๋ก์ ํธ๋ณ๋ก ๋ถ๋ฅํด Cost Management์์ ํํฐ๋ง์ ์ฝ๊ฒ ํด์ค๋ค",
|
| 238 |
+
"explanation": "Tags ์์ฒด๋ ๋น์ฉ์ ์ค์ด์ง ์์ง๋ง, Cost Management์์ tag๋ณ๋ก ํํฐ๋งํ๋ฉด ๋ถ์/ํ๋ก์ ํธ๋ณ ์ง์ถ์ ํ์
ํ ์ ์์ต๋๋ค.",
|
| 239 |
+
"difficulty": "easy",
|
| 240 |
+
"source_id": "manual-az104-basic"
|
| 241 |
+
},
|
| 242 |
+
{
|
| 243 |
+
"id": "azure-q43",
|
| 244 |
+
"lesson_id": "azure-app-service",
|
| 245 |
+
"question_type": "multiple_choice",
|
| 246 |
+
"question": "Azure App Service์ ํน์ง์ผ๋ก ๊ฐ์ฅ ๋ง๋ ๊ฒ์?",
|
| 247 |
+
"options": [
|
| 248 |
+
"VM์ ์ง์ ๊ด๋ฆฌํ์ง ์๊ณ ์น์ฑ๊ณผ API๋ฅผ ๋ฐฐํฌํ๋ PaaS ์๋น์ค",
|
| 249 |
+
"OS์ ๋ฏธ๋ค์จ์ด๋ฅผ ์ง์ ๊ด๋ฆฌํ๋ IaaS ์๋น์ค",
|
| 250 |
+
"์ปจํ
์ด๋ ์ด๋ฏธ์ง๋ฅผ ์ ์ฅํ๋ ๋ ์ง์คํธ๋ฆฌ",
|
| 251 |
+
"๊ด๊ณํ ๋ฐ์ดํฐ๋ฒ ์ด์ค ํธ์คํ
์๋น์ค"
|
| 252 |
+
],
|
| 253 |
+
"answer": "VM์ ์ง์ ๊ด๋ฆฌํ์ง ์๊ณ ์น์ฑ๊ณผ API๋ฅผ ๋ฐฐํฌํ๋ PaaS ์๋น์ค",
|
| 254 |
+
"explanation": "App Service๋ ์ธํ๋ผ ๊ด๋ฆฌ ์์ด ์ฝ๋๋ฅผ ๋ฐฐํฌํ๋ PaaS์
๋๋ค. OS ํจ์น, ์๋ฒ ๊ด๋ฆฌ๋ Azure๊ฐ ๋ด๋นํฉ๋๋ค.",
|
| 255 |
+
"difficulty": "easy",
|
| 256 |
+
"source_id": "azure-app-service-overview"
|
| 257 |
+
},
|
| 258 |
+
{
|
| 259 |
+
"id": "azure-q44",
|
| 260 |
+
"lesson_id": "azure-aci",
|
| 261 |
+
"question_type": "multiple_choice",
|
| 262 |
+
"question": "Azure Container Instances(ACI)๊ฐ AKS์ ๋น๊ตํด ๊ฐ์ง ์ฃผ์ ํน์ง์?",
|
| 263 |
+
"options": [
|
| 264 |
+
"ํด๋ฌ์คํฐ ๊ด๋ฆฌ ์์ด ์ปจํ
์ด๋๋ฅผ ์ฆ์ ์คํํ ์ ์๋ ์๋ฒ๋ฆฌ์ค ๋ฐฉ์์ด๋ค",
|
| 265 |
+
"๋๊ท๋ชจ ๋ง์ดํฌ๋ก์๋น์ค ์ค์ผ์คํธ๋ ์ด์
์ ์ต์ ํ๋๋ค",
|
| 266 |
+
"VM Scale Set๊ณผ ๋์ผํ ์๋น์ค๋ค",
|
| 267 |
+
"์ปจํ
์ด๋ ์ด๋ฏธ์ง๋ฅผ ์ ์ฅํ๋ ๋ ์ง์คํธ๋ฆฌ๋ค"
|
| 268 |
+
],
|
| 269 |
+
"answer": "ํด๋ฌ์คํฐ ๊ด๋ฆฌ ์์ด ์ปจํ
์ด๋๋ฅผ ์ฆ์ ์คํํ ์ ์๋ ์๋ฒ๋ฆฌ์ค ๋ฐฉ์์ด๋ค",
|
| 270 |
+
"explanation": "ACI๋ ํด๋ฌ์คํฐ ์ด์ ์์ด ๊ฐ๋จํ ์ปจํ
์ด๋๋ฅผ ๋น ๋ฅด๊ฒ ์คํํ๋ ์๋ฒ๋ฆฌ์ค ๋ฐฉ์์
๋๋ค. ๋ณต์กํ ๋ง์ดํฌ๋ก์๋น์ค ์ค์ผ์คํธ๋ ์ด์
์ AKS๊ฐ ์ ํฉํฉ๋๋ค.",
|
| 271 |
+
"difficulty": "easy",
|
| 272 |
+
"source_id": "azure-container-instances"
|
| 273 |
+
},
|
| 274 |
+
{
|
| 275 |
+
"id": "azure-q45",
|
| 276 |
+
"lesson_id": "azure-keyvault-secret",
|
| 277 |
+
"question_type": "multiple_choice",
|
| 278 |
+
"question": "Key Vault Secret์ ์ฃผ๋ ์ฌ์ฉ ๋ชฉ์ ์?",
|
| 279 |
+
"options": [
|
| 280 |
+
"DB password, API ํค ๊ฐ์ ๋ฏผ๊ฐํ ๊ฐ์ ์ฝ๋๋ ์ค์ ํ์ผ ๋์ ์์ ํ๊ฒ ์ ์ฅํ๋ค",
|
| 281 |
+
"VM ๋์คํฌ๋ฅผ ์ํธํํ๋ค",
|
| 282 |
+
"RBAC ์ญํ ์ ์๋ฅผ ์ ์ฅํ๋ค",
|
| 283 |
+
"NSG ๋ณด์ ๊ท์น์ ์ ์ํ๋ค"
|
| 284 |
+
],
|
| 285 |
+
"answer": "DB password, API ํค ๊ฐ์ ๋ฏผ๊ฐํ ๊ฐ์ ์ฝ๋๋ ์ค์ ํ์ผ ๋์ ์์ ํ๊ฒ ์ ์ฅํ๋ค",
|
| 286 |
+
"explanation": "Key Vault Secret์ ๋น๋ฐ๊ฐ์ ์ฝ๋๋ Git์ ๋ฃ์ง ์๊ณ ์ค์์์ ์์ ํ๊ฒ ๊ด๋ฆฌํฉ๋๋ค. Managed Identity์ ๊ฒฐํฉํ๋ฉด ์ฝ๋์ ๋น๋ฐ๊ฐ์ด ์ ํ ์์ด๋ ๋ฉ๋๋ค.",
|
| 287 |
+
"difficulty": "easy",
|
| 288 |
+
"source_id": "azure-key-vault-overview"
|
| 289 |
+
},
|
| 290 |
+
{
|
| 291 |
+
"id": "azure-q46",
|
| 292 |
+
"lesson_id": "azure-network-watcher",
|
| 293 |
+
"question_type": "multiple_choice",
|
| 294 |
+
"question": "Azure Network Watcher์ ์ฃผ๋ ์ญํ ์?",
|
| 295 |
+
"options": [
|
| 296 |
+
"๋คํธ์ํฌ ์ฐ๊ฒฐ ์ง๋จ, ํ๋ฆ ๋ก๊ทธ, ํจํท ์บก์ฒ ๊ฐ์ ๋คํธ์ํฌ ๋ชจ๋ํฐ๋ง ๋๊ตฌ๋ฅผ ์ ๊ณตํ๋ค",
|
| 297 |
+
"VM์ ์๋์ผ๋ก ์์ํ๊ณ ์ค์งํ๋ค",
|
| 298 |
+
"Blob ์๋ช
์ฃผ๊ธฐ๋ฅผ ์๋ ๊ด๋ฆฌํ๋ค",
|
| 299 |
+
"NSG ๊ท์น์ ์๋์ผ๋ก ์์ฑํ๋ค"
|
| 300 |
+
],
|
| 301 |
+
"answer": "๋คํธ์ํฌ ์ฐ๊ฒฐ ์ง๋จ, ํ๋ฆ ๋ก๊ทธ, ํจํท ์บก์ฒ ๊ฐ์ ๋คํธ์ํฌ ๋ชจ๋ํฐ๋ง ๋๊ตฌ๋ฅผ ์ ๊ณตํ๋ค",
|
| 302 |
+
"explanation": "Network Watcher๋ Connection troubleshoot, NSG flow log, IP flow verify, packet capture ๊ฐ์ ์ง๋จ ๋๊ตฌ๋ฅผ ์ ๊ณตํฉ๋๋ค. NSG ๊ท์น๋ง์ผ๋ก ํ์
ํ๊ธฐ ์ด๋ ค์ด ์ค์ ํธ๋ํฝ ๊ฒฝ๋ก๋ฅผ ํ์ธํ ์ ์์ต๋๋ค.",
|
| 303 |
+
"difficulty": "easy",
|
| 304 |
+
"source_id": "azure-vnet-overview"
|
| 305 |
+
},
|
| 306 |
+
{
|
| 307 |
+
"id": "azure-q47",
|
| 308 |
+
"lesson_id": "azure-move-resource",
|
| 309 |
+
"question_type": "multiple_choice",
|
| 310 |
+
"question": "Azure ๋ฆฌ์์ค ์ด๋(Move)์์ ์ฃผ์ํด์ผ ํ ์ฌํญ์ผ๋ก ๊ฐ์ฅ ๋ง๋ ๊ฒ์?",
|
| 311 |
+
"options": [
|
| 312 |
+
"๋ชจ๋ ๋ฆฌ์์ค ์ ํ์ด ์ด๋์ ์ง์ํ์ง ์์ผ๋ฉฐ ์ข
์ ๋ฆฌ์์ค๋ ํจ๊ป ๊ณ ๋ คํด์ผ ํ๋ค",
|
| 313 |
+
"์ด๋ ์ค์๋ ์๋น์ค๊ฐ ํญ์ ์ ์ ๋์ํ๋ค",
|
| 314 |
+
"์ด๋ํ๋ฉด ์๋์ผ๋ก ์ subscription ๊ณผ๊ธ์ผ๋ก ์ ํ๋๋ค",
|
| 315 |
+
"Resource Lock์ด ์์ด๋ ํญ์ ์ด๋ ๊ฐ๋ฅํ๋ค"
|
| 316 |
+
],
|
| 317 |
+
"answer": "๋ชจ๋ ๋ฆฌ์์ค ์ ํ์ด ์ด๋์ ์ง์ํ์ง ์์ผ๋ฉฐ ์ข
์ ๋ฆฌ์์ค๋ ํจ๊ป ๊ณ ๋ คํด์ผ ํ๋ค",
|
| 318 |
+
"explanation": "์ผ๋ถ ๋ฆฌ์์ค ์ ํ์ ์ด๋์ ์ง์ํ์ง ์์ต๋๋ค. NIC, ๋์คํฌ ๊ฐ์ ์ข
์ ๋ฆฌ์์ค๋ฅผ ํจ๊ป ์ด๋ํด์ผ ํ๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ผ๋ฉฐ, ์ด๋ ์ค์๋ ์ผ์์ ์ผ๋ก ์ ๊ธ ์ํ๊ฐ ๋ฉ๋๋ค.",
|
| 319 |
+
"difficulty": "medium",
|
| 320 |
+
"source_id": "manual-az104-basic"
|
| 321 |
+
},
|
| 322 |
+
{
|
| 323 |
+
"id": "azure-q48",
|
| 324 |
+
"lesson_id": "azure-vmss",
|
| 325 |
+
"question_type": "multiple_choice",
|
| 326 |
+
"question": "VMSS์ Availability Set์ ๊ฐ์ฅ ํฐ ์ฐจ์ด์ ์?",
|
| 327 |
+
"options": [
|
| 328 |
+
"VMSS๋ ๋ถํ์ ๋ฐ๋ผ VM ์๋ฅผ ์๋ ์กฐ์ ํ๋ค",
|
| 329 |
+
"Availability Set์ SLA๊ฐ ๋ ๋๋ค",
|
| 330 |
+
"VMSS๋ ๋จ์ผ VM๋ง ์ง์ํ๋ค",
|
| 331 |
+
"Availability Set์ด ๋ ์ ๋ ดํ๋ค"
|
| 332 |
+
],
|
| 333 |
+
"answer": "VMSS๋ ๋ถํ์ ๋ฐ๋ผ VM ์๋ฅผ ์๋ ์กฐ์ ํ๋ค",
|
| 334 |
+
"explanation": "VMSS๋ Autoscale๋ก ์ธ์คํด์ค ์๋ฅผ ๋์ ์ผ๋ก ์กฐ์ ํฉ๋๋ค. Availability Set์ HA๋ฅผ ์ํ ๋ฐฐ์น ๊ตฌ์ฑ์ด๋ฉฐ ์๋ ํ์ฅ ๊ธฐ๋ฅ์ด ์์ต๋๋ค.",
|
| 335 |
+
"source_id": "azure-vmss-overview"
|
| 336 |
+
},
|
| 337 |
+
{
|
| 338 |
+
"id": "azure-q49",
|
| 339 |
+
"lesson_id": "azure-dns",
|
| 340 |
+
"question_type": "multiple_choice",
|
| 341 |
+
"question": "Azure DNS์์ Public Zone ์์ฑ ํ ๋ฐ๋์ ํด์ผ ํ๋ ์ถ๊ฐ ์์
์?",
|
| 342 |
+
"options": [
|
| 343 |
+
"๋๋ฉ์ธ ๋ฑ๋ก ๊ธฐ๊ด์์ NS ๋ ์ฝ๋๋ฅผ Azure๋ก ์์",
|
| 344 |
+
"VNet์ DNS Zone ๋งํฌ ์ฐ๊ฒฐ",
|
| 345 |
+
"Private Endpoint ์์ฑ",
|
| 346 |
+
"SSL ์ธ์ฆ์ ๋ฐ์ธ๋ฉ"
|
| 347 |
+
],
|
| 348 |
+
"answer": "๋๋ฉ์ธ ๋ฑ๋ก ๊ธฐ๊ด์์ NS ๋ ์ฝ๋๋ฅผ Azure๋ก ์์",
|
| 349 |
+
"explanation": "Azure DNS๋ ํธ์คํ
์๋น์ค์ด๋ฏ๋ก ๋๋ฉ์ธ ๋ฑ๋ก ๊ธฐ๊ด์์ Azure๊ฐ ์ ๊ณตํ NS ๋ ์ฝ๋ 4๊ฐ๋ฅผ ์ค์ ํด ์์ํด์ผ ์ค์ ๋ก ๋์ํฉ๋๋ค.",
|
| 350 |
+
"source_id": "azure-dns-overview"
|
| 351 |
+
},
|
| 352 |
+
{
|
| 353 |
+
"id": "azure-q50",
|
| 354 |
+
"lesson_id": "azure-recovery-vault",
|
| 355 |
+
"question_type": "multiple_choice",
|
| 356 |
+
"question": "Recovery Services Vault์ Soft Delete ๊ธฐ๋ฅ์ด ํ๋ ์ญํ ์?",
|
| 357 |
+
"options": [
|
| 358 |
+
"์ญ์ ๋ ๋ฐฑ์
๋ฐ์ดํฐ๋ฅผ ์ผ์ ๊ธฐ๊ฐ ๋ณต์ ๊ฐ๋ฅํ๊ฒ ์ ์งํ๋ค",
|
| 359 |
+
"VM์ ์๋์ผ๋ก ๋ฐฑ์
ํ๋ค",
|
| 360 |
+
"๋ฐฑ์
์ ์ฑ
์ ์๋ ์ ์ฉํ๋ค",
|
| 361 |
+
"๋ค๋ฅธ ์ง์ญ์ ๋ฐ์ดํฐ๋ฅผ ๋ณต์ ํ๋ค"
|
| 362 |
+
],
|
| 363 |
+
"answer": "์ญ์ ๋ ๋ฐฑ์
๋ฐ์ดํฐ๋ฅผ ์ผ์ ๊ธฐ๊ฐ ๋ณต์ ๊ฐ๋ฅํ๊ฒ ์ ์งํ๋ค",
|
| 364 |
+
"explanation": "Soft Delete๋ ๋ฐฑ์
ํญ๋ชฉ ์ญ์ ํ ์ต๋ 14์ผ๊ฐ ๋ฐ์ดํฐ๋ฅผ ๋ณดํธ ์ํ๋ก ์ ์งํด ์ค์๋ ๋์ฌ์จ์ด๋ก ์ธํ ์ญ์ ์์ ๋ณต์ํ ์ ์๊ฒ ํฉ๋๋ค.",
|
| 365 |
+
"source_id": "azure-recovery-services-vault"
|
| 366 |
+
},
|
| 367 |
+
{
|
| 368 |
+
"id": "azure-q51",
|
| 369 |
+
"lesson_id": "azure-rg",
|
| 370 |
+
"question_type": "command",
|
| 371 |
+
"question": "`Korea Central` ์ง์ญ์ `myRG` ๋ฆฌ์์ค ๊ทธ๋ฃน์ ์์ฑํ๋ Azure CLI ๋ช
๋ น์ด๋ฅผ ์
๋ ฅํ์ธ์.",
|
| 372 |
+
"options": [],
|
| 373 |
+
"answer": "az group create --name myRG --location koreacentral",
|
| 374 |
+
"explanation": "`az group create --name <์ด๋ฆ> --location <์ง์ญ>`. ์ง์ญ ์ด๋ฆ์ ๊ณต๋ฐฑ ์์ด ์๋ฌธ์๋ก ์๋๋ค (koreacentral, eastus ๋ฑ).",
|
| 375 |
+
"difficulty": "easy",
|
| 376 |
+
"source_id": "manual-az104-basic"
|
| 377 |
+
},
|
| 378 |
+
{
|
| 379 |
+
"id": "azure-q52",
|
| 380 |
+
"lesson_id": "azure-storage",
|
| 381 |
+
"question_type": "multiple_choice",
|
| 382 |
+
"question": "Azure Storage ๊ณ์ ์ ๊ธฐ๋ณธ ์ค๋ณต์ฑ SKU๋ก ๋์ผ ๋ฐ์ดํฐ์ผํฐ ๋ด 3๊ฐ ๋ณต์ ๋ณธ์ ์ ์งํ๋ ๊ฒ์?",
|
| 383 |
+
"options": ["LRS", "ZRS", "GRS", "GZRS"],
|
| 384 |
+
"answer": "LRS",
|
| 385 |
+
"explanation": "LRS(Locally Redundant Storage)๋ ๋จ์ผ ๋ฐ์ดํฐ์ผํฐ ๋ด 3๊ฐ ๋ณต์ ๋ณธ์ผ๋ก ๊ฐ์ฅ ์ ๋ ดํ์ง๋ง ๋ฐ์ดํฐ์ผํฐ ์ ์ฒด ์ฅ์ ์ ์ทจ์ฝํฉ๋๋ค.",
|
| 386 |
+
"difficulty": "easy",
|
| 387 |
+
"source_id": "azure-storage-account"
|
| 388 |
+
},
|
| 389 |
+
{
|
| 390 |
+
"id": "azure-q53",
|
| 391 |
+
"lesson_id": "azure-vnet",
|
| 392 |
+
"question_type": "multiple_choice",
|
| 393 |
+
"question": "Azure VNet์์ ์๋ธ๋ท๋ง๋ค ์์ฝ๋์ด ์ฌ์ฉํ ์ ์๋ IP ์ฃผ์ ์๋?",
|
| 394 |
+
"options": ["5๊ฐ", "3๊ฐ", "2๊ฐ", "1๊ฐ"],
|
| 395 |
+
"answer": "5๊ฐ",
|
| 396 |
+
"explanation": "Azure๋ ์๋ธ๋ท๋ง๋ค ๋คํธ์ํฌ ๏ฟฝ๏ฟฝ์, ๊ฒ์ดํธ์จ์ด, DHCP 2๊ฐ, ๋ธ๋ก๋์บ์คํธ ๋ฑ 5๊ฐ IP๋ฅผ ์์ฝํฉ๋๋ค. /28 ์๋ธ๋ท์ด๋ฉด 16-5=11๊ฐ๋ง ์ฌ์ฉ ๊ฐ๋ฅํฉ๋๋ค.",
|
| 397 |
+
"difficulty": "medium",
|
| 398 |
+
"source_id": "manual-az104-basic"
|
| 399 |
+
},
|
| 400 |
+
{
|
| 401 |
+
"id": "azure-q54",
|
| 402 |
+
"lesson_id": "azure-rbac",
|
| 403 |
+
"question_type": "multiple_choice",
|
| 404 |
+
"question": "Owner, Contributor, Reader ์ค ์ญํ ํ ๋น(RBAC ๋ถ์ฌ) ๊ถํ์ ๊ฐ์ง ๊ฒ์?",
|
| 405 |
+
"options": ["Owner๋ง", "Owner์ Contributor", "์ธ ์ญํ ๋ชจ๋", "Reader๋ง"],
|
| 406 |
+
"answer": "Owner๋ง",
|
| 407 |
+
"explanation": "Owner๋ง ์ญํ ํ ๋น ๊ถํ์ ๊ฐ์ง๋๋ค. Contributor๋ ๋ฆฌ์์ค ์์ฑ/์์ /์ญ์ ๋ ๋์ง๋ง ๋ค๋ฅธ ์ฌ๋์๊ฒ ์ญํ ์ ์ค ์ ์๊ณ , Reader๋ ์กฐํ๋ง ๊ฐ๋ฅํฉ๋๋ค.",
|
| 408 |
+
"difficulty": "easy",
|
| 409 |
+
"source_id": "azure-rbac-overview"
|
| 410 |
+
},
|
| 411 |
+
{
|
| 412 |
+
"id": "azure-q55",
|
| 413 |
+
"lesson_id": "azure-policy",
|
| 414 |
+
"question_type": "multiple_choice",
|
| 415 |
+
"question": "Azure Policy effect ์ค ๊ท์ ์ ๋ง์ง ์๋ ๋ฆฌ์์ค ๋ฐฐํฌ ์์ฒด๋ฅผ ์ฐจ๋จํ๋ ๊ฒ์?",
|
| 416 |
+
"options": ["Deny", "Audit", "Append", "Modify"],
|
| 417 |
+
"answer": "Deny",
|
| 418 |
+
"explanation": "Deny๋ ๋น์ค์ ๋ฆฌ์์ค ์์ฑ์ ๋ง์ต๋๋ค. Audit๋ ํ์ฉํ๋ ๋ก๊ทธ๋ง ๋จ๊ธฐ๊ณ , Append๋ ํ๋๋ฅผ ์ถ๊ฐํ๋ฉฐ, Modify๋ ํ๊ทธ ๊ฐ์ ์์ฑ์ ์์ ํฉ๋๋ค.",
|
| 419 |
+
"difficulty": "easy",
|
| 420 |
+
"source_id": "azure-policy-overview"
|
| 421 |
+
},
|
| 422 |
+
{
|
| 423 |
+
"id": "azure-q56",
|
| 424 |
+
"lesson_id": "azure-vm",
|
| 425 |
+
"question_type": "command",
|
| 426 |
+
"question": "`myRG` ๋ฆฌ์์ค ๊ทธ๋ฃน์ Ubuntu 22.04 LTS ์ด๋ฏธ์ง๋ก `myVM`์ ์์ฑํ๋ ์ต์ํ์ Azure CLI ๋ช
๋ น์ด๋ฅผ ์
๋ ฅํ์ธ์.",
|
| 427 |
+
"options": [],
|
| 428 |
+
"answer": "az vm create --resource-group myRG --name myVM --image Ubuntu2204",
|
| 429 |
+
"explanation": "`az vm create --resource-group <RG> --name <์ด๋ฆ> --image <์ด๋ฏธ์ง>`. ์ด๋ฏธ์ง ์ด๋ฆ์ `az vm image list` ๋ก ํ์ธํฉ๋๋ค.",
|
| 430 |
+
"difficulty": "medium",
|
| 431 |
+
"source_id": "azure-vm-overview"
|
| 432 |
+
},
|
| 433 |
+
{
|
| 434 |
+
"id": "azure-q57",
|
| 435 |
+
"lesson_id": "azure-vmss",
|
| 436 |
+
"question_type": "multiple_choice",
|
| 437 |
+
"question": "VMSS์์ ์ธ์คํด์ค๋ฅผ ์ต์ 2๊ฐ ์ต๋ 10๊ฐ๋ก ์ ์งํ๊ณ CPU 75% ์ด๊ณผ ์ ๋๋ฆฌ๋ ๊ท์น์ ์ด๋์ ์ ์ํ๋๊ฐ?",
|
| 438 |
+
"options": ["Autoscale ์ค์ ", "NSG ๊ท์น", "Backup Policy", "Alert Rule"],
|
| 439 |
+
"answer": "Autoscale ์ค์ ",
|
| 440 |
+
"explanation": "VMSS์ ์ธ์คํด์ค ์ ์๋ ์กฐ์ ์ Autoscale ์ค์ ์์ ๋ฉํธ๋ฆญ ์กฐ๊ฑด(CPU %), ์ต์/์ต๋ ์ธ์คํด์ค, ์ฆ๊ฐ ๋จ์๋ฅผ ์ ์ํฉ๋๋ค.",
|
| 441 |
+
"difficulty": "easy",
|
| 442 |
+
"source_id": "azure-vmss-overview"
|
| 443 |
+
},
|
| 444 |
+
{
|
| 445 |
+
"id": "azure-q58",
|
| 446 |
+
"lesson_id": "azure-nsg",
|
| 447 |
+
"question_type": "command",
|
| 448 |
+
"question": "NSG `myNSG`์ ์ฐ์ ์์ 200์ผ๋ก TCP 443 ์ธ๋ฐ์ด๋๋ฅผ ํ์ฉํ๋ ๊ท์น `allow-https`๋ฅผ ์ถ๊ฐํ๋ ๋ช
๋ น์ด๋ฅผ ์
๋ ฅํ์ธ์.",
|
| 449 |
+
"options": [],
|
| 450 |
+
"answer": "az network nsg rule create --nsg-name myNSG --resource-group myRG --name allow-https --priority 200 --access Allow --protocol Tcp --destination-port-ranges 443",
|
| 451 |
+
"explanation": "`az network nsg rule create`์ `--nsg-name`, `--priority`, `--access Allow`, `--protocol Tcp`, `--destination-port-ranges`๋ฅผ ์ง์ ํฉ๋๋ค.",
|
| 452 |
+
"difficulty": "medium",
|
| 453 |
+
"source_id": "manual-az104-basic"
|
| 454 |
+
},
|
| 455 |
+
{
|
| 456 |
+
"id": "azure-q59",
|
| 457 |
+
"lesson_id": "azure-app-gateway",
|
| 458 |
+
"question_type": "multiple_choice",
|
| 459 |
+
"question": "Application Gateway์ Azure Load Balancer์ ์ฃผ์ ์ฐจ์ด๋?",
|
| 460 |
+
"options": [
|
| 461 |
+
"App Gateway๋ L7(HTTP/HTTPS) ๋ผ์ฐํ
, Load Balancer๋ L4(TCP/UDP) ๋ถ์ฐ์ด๋ค",
|
| 462 |
+
"๋ ์๋น์ค ๋ชจ๋ L4๋ง ์ง์ํ๋ค",
|
| 463 |
+
"Load Balancer๊ฐ URL ๊ฒฝ๋ก ๊ธฐ๋ฐ ๋ผ์ฐํ
์ ์ง์ํ๋ค",
|
| 464 |
+
"App Gateway๋ VM์ ์ง์ ๊ด๋ฆฌํ๋ค"
|
| 465 |
+
],
|
| 466 |
+
"answer": "App Gateway๋ L7(HTTP/HTTPS) ๋ผ์ฐํ
, Load Balancer๋ L4(TCP/UDP) ๋ถ์ฐ์ด๋ค",
|
| 467 |
+
"explanation": "App Gateway๋ URL ๊ฒฝ๋ก, ํธ์คํธ ํค๋ ๊ธฐ๋ฐ L7 ๋ผ์ฐํ
๊ณผ WAF๋ฅผ ์ ๊ณตํฉ๋๋ค. Load Balancer๋ TCP/UDP ๋ ๋ฒจ L4 ๋ถ์ฐ์ผ๋ก ๋ ๋จ์ํ๊ณ ๋น ๋ฆ
๋๋ค.",
|
| 468 |
+
"difficulty": "medium",
|
| 469 |
+
"source_id": "azure-vnet-overview"
|
| 470 |
+
},
|
| 471 |
+
{
|
| 472 |
+
"id": "azure-q60",
|
| 473 |
+
"lesson_id": "azure-dns",
|
| 474 |
+
"question_type": "multiple_choice",
|
| 475 |
+
"question": "Azure Private DNS Zone๊ณผ Public DNS Zone์ ์ฐจ์ด๋?",
|
| 476 |
+
"options": [
|
| 477 |
+
"Private Zone์ VNet ๋ด๋ถ์์๋ง ํด์๋๊ณ , Public Zone์ ์ธํฐ๋ท์์ ์กฐํ๋๋ค",
|
| 478 |
+
"Private Zone์ ๋ ๋น ๋ฅธ TTL์ ๊ฐ์ง๋ค",
|
| 479 |
+
"Public Zone์ VNet์ ๋งํฌํด์ผ๋ง ๋์ํ๋ค",
|
| 480 |
+
"๋ Zone ๋ชจ๋ ๋์ผํ๊ฒ ๋์ํ๋ค"
|
| 481 |
+
],
|
| 482 |
+
"answer": "Private Zone์ VNet ๋ด๋ถ์์๋ง ํด์๋๊ณ , Public Zone์ ์ธํฐ๋ท์์ ์กฐํ๋๋ค",
|
| 483 |
+
"explanation": "Private DNS Zone์ VNet ๋งํฌ๋ฅผ ํตํด ํด๋น VNet ๋ด๋ถ ๋ฆฌ์์ค์๋ง DNS ์ด๋ฆ์ ์ ๊ณตํฉ๋๋ค. Public Zone์ ์ธํฐ๋ท ์ ์ฒด์์ ์กฐํ ๊ฐ๋ฅํฉ๋๋ค.",
|
| 484 |
+
"difficulty": "easy",
|
| 485 |
+
"source_id": "azure-dns-overview"
|
| 486 |
+
},
|
| 487 |
+
{
|
| 488 |
+
"id": "azure-q61",
|
| 489 |
+
"lesson_id": "azure-blob-tier",
|
| 490 |
+
"question_type": "multiple_choice",
|
| 491 |
+
"question": "Archive tier์ ์๋ Blob์ ์ฆ์ ์ ๊ทผํ๋ ค๋ฉด ๋จผ์ ํด์ผ ํ๋ ์์
์?",
|
| 492 |
+
"options": [
|
| 493 |
+
"rehydration(๋ฆฌํ์ด๋๋ ์ด์
)์ผ๋ก Hot ๋๋ Cool๋ก ์ด๋",
|
| 494 |
+
"์คํ ๋ฆฌ์ง ๊ณ์ ์ ์ฌ์์ฑ",
|
| 495 |
+
"Blob์ ์ญ์ ํ ๋ค์ ์
๋ก๋",
|
| 496 |
+
"SAS ํ ํฐ์ ์๋ก ๋ฐ๊ธ"
|
| 497 |
+
],
|
| 498 |
+
"answer": "rehydration(๋ฆฌํ์ด๋๋ ์ด์
)์ผ๋ก Hot ๋๋ Cool๋ก ์ด๋",
|
| 499 |
+
"explanation": "Archive tier์ Blob์ ์คํ๋ผ์ธ ์ํ๋ผ ์ง์ ์ฝ์ ์ ์์ต๋๋ค. Hot/Cool๋ก rehydration ํ ์ ๊ทผ ๊ฐ๋ฅํ๋ฉฐ, ํ์ค ์ฐ์ ์์๋ก ์ ์๊ฐ์ด ๊ฑธ๋ฆฝ๋๋ค.",
|
| 500 |
+
"difficulty": "medium",
|
| 501 |
+
"source_id": "azure-blob-access-tiers"
|
| 502 |
+
},
|
| 503 |
+
{
|
| 504 |
+
"id": "azure-q62",
|
| 505 |
+
"lesson_id": "azure-log-analytics",
|
| 506 |
+
"question_type": "multiple_choice",
|
| 507 |
+
"question": "Log Analytics workspace์์ ์ฟผ๋ฆฌ ์ธ์ด๋ก ์ฌ์ฉํ๋ ๊ฒ์?",
|
| 508 |
+
"options": ["KQL (Kusto Query Language)", "SQL", "Bash", "PowerShell"],
|
| 509 |
+
"answer": "KQL (Kusto Query Language)",
|
| 510 |
+
"explanation": "Azure Log Analytics๋ KQL(Kusto Query Language)๋ก ๋ก๊ทธ๋ฅผ ์กฐํํฉ๋๋ค. `| where`, `| summarize`, `| project` ๊ฐ์ ํ์ดํ๋ผ์ธ ๋ฌธ๋ฒ์ ์ฌ์ฉํฉ๋๋ค.",
|
| 511 |
+
"difficulty": "easy",
|
| 512 |
+
"source_id": "azure-monitor-overview"
|
| 513 |
+
},
|
| 514 |
+
{
|
| 515 |
+
"id": "azure-q63",
|
| 516 |
+
"lesson_id": "azure-entra-id",
|
| 517 |
+
"question_type": "multiple_choice",
|
| 518 |
+
"question": "Microsoft Entra ID์ ์จํ๋ ๋ฏธ์ค Active Directory์ ๊ฐ์ฅ ํฐ ์ฐจ์ด์ ์?",
|
| 519 |
+
"options": [
|
| 520 |
+
"Entra ID๋ ํด๋ผ์ฐ๋ ๊ธฐ๋ฐ ID ์๋น์ค๋ก OAuth/OIDC๋ฅผ ์ง์, AD๋ Kerberos/LDAP ๊ธฐ๋ฐ์ด๋ค",
|
| 521 |
+
"๋ ์๋น์ค ๋ชจ๋ Kerberos๋ง ์ฌ์ฉํ๋ค",
|
| 522 |
+
"AD๋ ํด๋ผ์ฐ๋ ์ ์ฉ์ด๋ค",
|
| 523 |
+
"Entra ID๋ ๊ทธ๋ฃน ์ ์ฑ
์ ์ง์ ์ ์ฉํ ์ ์๋ค"
|
| 524 |
+
],
|
| 525 |
+
"answer": "Entra ID๋ ํด๋ผ์ฐ๋ ๊ธฐ๋ฐ ID ์๋น์ค๋ก OAuth/OIDC๋ฅผ ์ง์, AD๋ Kerberos/LDAP ๊ธฐ๋ฐ์ด๋ค",
|
| 526 |
+
"explanation": "Entra ID๋ SaaS/ํด๋ผ์ฐ๋ ์ฑ ์ธ์ฆ์ OAuth2, OIDC, SAML์ ์ฌ์ฉํฉ๋๋ค. ์จํ๋ ๋ฏธ์ค AD๋ Kerberos/LDAP ๊ธฐ๋ฐ์ผ๋ก ๋๋ฉ์ธ ์กฐ์ธ, ๊ทธ๋ฃน ์ ์ฑ
์ ์ง์ํฉ๋๋ค.",
|
| 527 |
+
"difficulty": "medium",
|
| 528 |
+
"source_id": "azure-entra-id-overview"
|
| 529 |
+
},
|
| 530 |
+
{
|
| 531 |
+
"id": "azure-q64",
|
| 532 |
+
"lesson_id": "azure-management-group",
|
| 533 |
+
"question_type": "multiple_choice",
|
| 534 |
+
"question": "Management Group ๊ณ์ธต ๊ตฌ์กฐ์์ Policy์ RBAC ์์ ๋ฐฉํฅ์?",
|
| 535 |
+
"options": [
|
| 536 |
+
"์์์์ ํ์๋ก ์์ (Management Group โ Subscription โ Resource Group โ Resource)",
|
| 537 |
+
"ํ์์์ ์์๋ก ์์",
|
| 538 |
+
"๋์ผ ๋ ๋ฒจ ๊ฐ์๋ง ์์",
|
| 539 |
+
"์์ ์์ด ๊ฐ ๋ ๋ฒจ์ ๋
๋ฆฝ ์ ์ฉ"
|
| 540 |
+
],
|
| 541 |
+
"answer": "์์์์ ํ์๋ก ์์ (Management Group โ Subscription โ Resource Group โ Resource)",
|
| 542 |
+
"explanation": "Policy์ RBAC๋ ๊ณ์ธต ์์์์ ํ์๋ก ์์๋ฉ๋๋ค. Management Group์ ์ ์ฑ
์ ์ ์ฉํ๋ฉด ํ์์ ๋ชจ๋ Subscription๊ณผ Resource Group์ ์ ์ฉ๋ฉ๋๋ค.",
|
| 543 |
+
"difficulty": "easy",
|
| 544 |
+
"source_id": "azure-management-group-overview"
|
| 545 |
+
},
|
| 546 |
+
{
|
| 547 |
+
"id": "azure-q65",
|
| 548 |
+
"lesson_id": "azure-resource-lock",
|
| 549 |
+
"question_type": "multiple_choice",
|
| 550 |
+
"question": "ReadOnly Lock์ด ๊ฑธ๋ฆฐ ๋ฆฌ์์ค์์ ํ ์ ์๋ ์์
์?",
|
| 551 |
+
"options": [
|
| 552 |
+
"์ค์ ์์ ๋ฐ ์ญ์ ๋ชจ๋ ๋ถ๊ฐ",
|
| 553 |
+
"์ญ์ ๋ง ๋ถ๊ฐ, ์์ ์ ๊ฐ๋ฅ",
|
| 554 |
+
"์ฝ๊ธฐ๋ง ๋ถ๊ฐ",
|
| 555 |
+
"๋ฐฐํฌ๋ง ๋ถ๊ฐ"
|
| 556 |
+
],
|
| 557 |
+
"answer": "์ค์ ์์ ๋ฐ ์ญ์ ๋ชจ๋ ๋ถ๊ฐ",
|
| 558 |
+
"explanation": "ReadOnly Lock์ ์ฝ๊ธฐ๋ง ํ์ฉํ๊ณ ์์ ยท์ญ์ ๋ฅผ ๋ชจ๋ ์ฐจ๋จํฉ๋๋ค. CanNotDelete Lock์ ์์ ์ ํ์ฉํ์ง๋ง ์ญ์ ๋ง ์ฐจ๋จํฉ๋๋ค.",
|
| 559 |
+
"difficulty": "medium",
|
| 560 |
+
"source_id": "manual-az104-basic"
|
| 561 |
+
},
|
| 562 |
+
{
|
| 563 |
+
"id": "azure-q66",
|
| 564 |
+
"lesson_id": "azure-tags",
|
| 565 |
+
"question_type": "command",
|
| 566 |
+
"question": "`myVM` VM์ `env=prod` ํ๊ทธ๋ฅผ ์ถ๊ฐํ๋ Azure CLI ๋ช
๋ น์ด๋ฅผ ์
๋ ฅํ์ธ์.",
|
| 567 |
+
"options": [],
|
| 568 |
+
"answer": "az resource tag --tags env=prod --resource-group myRG --name myVM --resource-type Microsoft.Compute/virtualMachines",
|
| 569 |
+
"explanation": "`az resource tag --tags key=value`๋ก ๋ฆฌ์์ค์ ํ๊ทธ๋ฅผ ์ถ๊ฐํฉ๋๋ค. `--resource-type`์ ์ ์ฒด provider ๊ฒฝ๋ก๋ฅผ ์จ์ผ ํฉ๋๋ค.",
|
| 570 |
+
"difficulty": "hard",
|
| 571 |
+
"source_id": "manual-az104-basic"
|
| 572 |
+
},
|
| 573 |
+
{
|
| 574 |
+
"id": "azure-q67",
|
| 575 |
+
"lesson_id": "azure-custom-role",
|
| 576 |
+
"question_type": "multiple_choice",
|
| 577 |
+
"question": "Custom Role ์์ฑ ์ `NotActions`์ ์ญํ ์?",
|
| 578 |
+
"options": [
|
| 579 |
+
"Actions์์ ํ์ฉ๋ ์์
์ค ํน์ ์์
์ ์ ์ธํ๋ค",
|
| 580 |
+
"๋ชจ๋ ์์
์ ์ฐจ๋จํ๋ค",
|
| 581 |
+
"Actions์ ์๋ ์์
์ ์ถ๊ฐํ๋ค",
|
| 582 |
+
"์ญํ ์ ํ ๋นํ ์ ์๊ฒ ๋ง๋ ๋ค"
|
| 583 |
+
],
|
| 584 |
+
"answer": "Actions์์ ํ์ฉ๋ ์์
์ค ํน์ ์์
์ ์ ์ธํ๋ค",
|
| 585 |
+
"explanation": "NotActions๋ Actions ์์ผ๋์นด๋๋ก ํ์ฉ๋ ์์
์์ ํน์ ์์
์ ๋บ ๋ ์ฌ์ฉํฉ๋๋ค. ์: `Actions: [\"*\"]`, `NotActions: [\"Microsoft.Authorization/*/Delete\"]`.",
|
| 586 |
+
"difficulty": "medium",
|
| 587 |
+
"source_id": "azure-rbac-overview"
|
| 588 |
+
},
|
| 589 |
+
{
|
| 590 |
+
"id": "azure-q68",
|
| 591 |
+
"lesson_id": "azure-sas",
|
| 592 |
+
"question_type": "multiple_choice",
|
| 593 |
+
"question": "SAS(Shared Access Signature) ํ ํฐ์์ ๋ฐ๋์ ์ง์ ํด์ผ ํ๋ ๋ณด์ ์์ 2๊ฐ์ง๋?",
|
| 594 |
+
"options": [
|
| 595 |
+
"๋ง๋ฃ ์๊ฐ(se)๊ณผ ํ์ฉ ๊ถํ(sp)",
|
| 596 |
+
"IP ์ฃผ์์ ์ปจํ
์ด๋ ์ด๋ฆ",
|
| 597 |
+
"์คํ ๋ฆฌ์ง ๊ณ์ ์ด๋ฆ๊ณผ ๊ตฌ๋
ID",
|
| 598 |
+
"๋ฆฌ์์ค ๊ทธ๋ฃน๊ณผ ์ง์ญ"
|
| 599 |
+
],
|
| 600 |
+
"answer": "๋ง๋ฃ ์๊ฐ(se)๊ณผ ํ์ฉ ๊ถํ(sp)",
|
| 601 |
+
"explanation": "SAS์์ `se`(signed expiry)๋ ์ ํจ ๊ธฐ๊ฐ, `sp`(signed permission)๋ r(read)/w(write)/d(delete) ๋ฑ ํ์ฉ ์์
์ ์ ํํฉ๋๋ค. ์ ํจ ๊ธฐ๊ฐ ์์ด ๋ฐ๊ธํ๋ฉด ๋ณด์ ์ํ์ด ํฝ๋๋ค.",
|
| 602 |
+
"difficulty": "medium",
|
| 603 |
+
"source_id": "azure-storage-account"
|
| 604 |
+
},
|
| 605 |
+
{
|
| 606 |
+
"id": "azure-q69",
|
| 607 |
+
"lesson_id": "azure-storage-redundancy",
|
| 608 |
+
"question_type": "multiple_choice",
|
| 609 |
+
"question": "์ฌํด๋ณต๊ตฌ๋ฅผ ์ํด ์ง์ญ ๊ฐ ๋ณต์ ๊ฐ ํ์ํ ๋ ์ ํํด์ผ ํ๋ ์ค๋ณต์ฑ ์ต์
์?",
|
| 610 |
+
"options": ["GRS ๋๋ GZRS", "LRS", "ZRS", "Premium LRS"],
|
| 611 |
+
"answer": "GRS ๋๋ GZRS",
|
| 612 |
+
"explanation": "GRS(Geo-Redundant Storage)์ GZRS๋ ์๋ฐฑ km ๋จ์ด์ง ํ์ด ์ง์ญ์ ๋ฐ์ดํฐ๋ฅผ ๋ณต์ ํด ์ง์ญ ์ ์ฒด ์ฌํด์ ๋๋นํฉ๋๋ค. LRS/ZRS๋ ๋จ์ผ ์ง์ญ ๋ด์์๋ง ๋ณต์ ํฉ๋๋ค.",
|
| 613 |
+
"difficulty": "easy",
|
| 614 |
+
"source_id": "azure-storage-account"
|
| 615 |
+
},
|
| 616 |
+
{
|
| 617 |
+
"id": "azure-q70",
|
| 618 |
+
"lesson_id": "azure-lifecycle",
|
| 619 |
+
"question_type": "multiple_choice",
|
| 620 |
+
"question": "Lifecycle ์ ์ฑ
์์ ๋ง์ง๋ง ์์ ํ 30์ผ ๋ค Cool๋ก, 90์ผ ๋ค Archive๋ก ์ด๋ํ๋๋ก ์ค์ ํ๋ ๊ธฐ์ค ๊ฐ์?",
|
| 621 |
+
"options": [
|
| 622 |
+
"daysAfterModificationGreaterThan",
|
| 623 |
+
"daysAfterCreationGreaterThan",
|
| 624 |
+
"daysAfterLastAccessTimeGreaterThan",
|
| 625 |
+
"daysUntilExpiration"
|
| 626 |
+
],
|
| 627 |
+
"answer": "daysAfterModificationGreaterThan",
|
| 628 |
+
"explanation": "Lifecycle ์ ์ฑ
์ ์กฐ๊ฑด ํ๋ `daysAfterModificationGreaterThan: 30`๊ณผ `90`์ผ๋ก ๋จ๊ณ์ tier ์ด๋์ ์ค์ ํฉ๋๋ค. ์ ๊ทผ ์๊ฐ ๊ธฐ๋ฐ์ `daysAfterLastAccessTimeGreaterThan`์
๋๋ค.",
|
| 629 |
+
"difficulty": "medium",
|
| 630 |
+
"source_id": "azure-blob-access-tiers"
|
| 631 |
+
},
|
| 632 |
+
{
|
| 633 |
+
"id": "azure-q71",
|
| 634 |
+
"lesson_id": "azure-files",
|
| 635 |
+
"question_type": "command",
|
| 636 |
+
"question": "`myshare` Azure ํ์ผ ๊ณต์ ๋ฅผ Linux์์ `/mnt/azfiles`์ ๋ง์ดํธํ๋ ํ๋กํ ์ฝ๊ณผ ๋ง์ดํธ ๋ช
๋ น์ด ์์ ๋ถ๋ถ์ ์
๋ ฅํ์ธ์.",
|
| 637 |
+
"options": [],
|
| 638 |
+
"answer": "mount -t cifs",
|
| 639 |
+
"explanation": "Azure Files๋ SMB ํ๋กํ ์ฝ(CIFS)๋ก Linux์ ๋ง์ดํธํฉ๋๋ค: `mount -t cifs //<์คํ ๋ฆฌ์ง>.file.core.windows.net/<๊ณต์ ๋ช
> /mnt/azfiles -o ...`",
|
| 640 |
+
"difficulty": "medium",
|
| 641 |
+
"source_id": "azure-storage-account"
|
| 642 |
+
},
|
| 643 |
+
{
|
| 644 |
+
"id": "azure-q72",
|
| 645 |
+
"lesson_id": "azure-managed-disk",
|
| 646 |
+
"question_type": "multiple_choice",
|
| 647 |
+
"question": "VM์ ๋ฐ์ดํฐ ๋์คํฌ๋ฅผ ์ถ๊ฐํ ๋ Premium SSD์ Standard HDD์ ์ ํ ๊ธฐ์ค์ผ๋ก ๋ง๋ ๊ฒ์?",
|
| 648 |
+
"options": [
|
| 649 |
+
"I/O ์ง์ฝ์ DB ์ํฌ๋ก๋๋ Premium SSD, ๋ก๊ทธ ๋ฐฑ์
๋ณด๊ด์ Standard HDD",
|
| 650 |
+
"Standard HDD๊ฐ ๋ชจ๋ ๊ฒฝ์ฐ์ ๋ ๋น ๋ฅด๋ค",
|
| 651 |
+
"Premium SSD๋ OS ๋์คํฌ์๋ง ์ฌ์ฉ ๊ฐ๋ฅํ๋ค",
|
| 652 |
+
"๋ฐ์ดํฐ ๋์คํฌ์๋ SSD๋ฅผ ์ฌ์ฉํ ์ ์๋ค"
|
| 653 |
+
],
|
| 654 |
+
"answer": "I/O ์ง์ฝ์ DB ์ํฌ๋ก๋๋ Premium SSD, ๋ก๊ทธ ๋ฐฑ์
๋ณด๊ด์ Standard HDD",
|
| 655 |
+
"explanation": "Premium SSD๋ ๋ฎ์ ์ง์ฐ์๊ฐ๊ณผ ๋์ IOPS๋ก DB๋ ์น์๋ฒ ์คํ ๋ฆฌ์ง์ ์ ํฉํฉ๋๋ค. Standard HDD๋ ์ ๊ทผ ๋น๋๊ฐ ๋ฎ์ ๋ฐฑ์
, ์์นด์ด๋ธ์ ๋น์ฉ ํจ์จ์ ์
๋๋ค.",
|
| 656 |
+
"difficulty": "easy",
|
| 657 |
+
"source_id": "azure-vm-overview"
|
| 658 |
+
},
|
| 659 |
+
{
|
| 660 |
+
"id": "azure-q73",
|
| 661 |
+
"lesson_id": "azure-availability-set",
|
| 662 |
+
"question_type": "multiple_choice",
|
| 663 |
+
"question": "Availability Set์ Fault Domain๊ณผ Update Domain์ ์ฐจ์ด๋?",
|
| 664 |
+
"options": [
|
| 665 |
+
"Fault Domain์ ์ ์/๋คํธ์ํฌ ๊ณต์ ๊ทธ๋ฃน, Update Domain์ OS ํจ์น ์์ ๊ทธ๋ฃน์ด๋ค",
|
| 666 |
+
"๋ ๋๋ฉ์ธ ๋ชจ๋ ๋์ผํ ์ญํ ์ด๋ค",
|
| 667 |
+
"Update Domain์ ์ง์ญ ๊ฐ ๋ถ์ฐ์ ์๋ฏธํ๋ค",
|
| 668 |
+
"Fault Domain์ ์ํํธ์จ์ด ์
๋ฐ์ดํธ ์์๋ฅผ ์ ์ดํ๋ค"
|
| 669 |
+
],
|
| 670 |
+
"answer": "Fault Domain์ ์ ์/๋คํธ์ํฌ ๊ณต์ ๊ทธ๋ฃน, Update Domain์ OS ํจ์น ์์ ๊ทธ๋ฃน์ด๋ค",
|
| 671 |
+
"explanation": "Fault Domain์ ๋ฌผ๋ฆฌ์ ์ ์๊ณผ ๋คํธ์ํฌ๋ฅผ ๊ณต์ ํ๋ ์๋ฒ ๋ ๊ทธ๋ฃน์
๋๋ค. Update Domain์ OS ํจ์น ์ฌ์์ ์ ๋์์ ๋ด๋ ค๊ฐ์ง ์๋๋ก ๋ถ๋ฆฌํ ๋
ผ๋ฆฌ ๊ทธ๋ฃน์
๋๋ค.",
|
| 672 |
+
"difficulty": "medium",
|
| 673 |
+
"source_id": "azure-vm-overview"
|
| 674 |
+
},
|
| 675 |
+
{
|
| 676 |
+
"id": "azure-q74",
|
| 677 |
+
"lesson_id": "azure-autoscale",
|
| 678 |
+
"question_type": "multiple_choice",
|
| 679 |
+
"question": "Autoscale ๊ท์น์์ scale-in ์ ์ฃผ์ํด์ผ ํ๋ ์ค์ ์?",
|
| 680 |
+
"options": [
|
| 681 |
+
"scale-in์ minimum ์ธ์คํด์ค ์ ์๋๋ก๋ ์ค์ด๋ค์ง ์๋๋ค",
|
| 682 |
+
"scale-in์ maximum ์ธ์คํด์ค๊น์ง๋ง ์ค์ด๋ ๋ค",
|
| 683 |
+
"scale-in๊ณผ scale-out์ด ๋์์ ํธ๋ฆฌ๊ฑฐ๋ ์ ์๋ค",
|
| 684 |
+
"scale-in์ CPU 100%์ผ ๋๋ง ์๋ํ๋ค"
|
| 685 |
+
],
|
| 686 |
+
"answer": "scale-in์ minimum ์ธ์คํด์ค ์ ์๋๋ก๋ ์ค์ด๋ค์ง ์๋๋ค",
|
| 687 |
+
"explanation": "Autoscale์ minimum/maximum ์ธ์คํด์ค ์๋ฅผ ์ค์ ํฉ๋๋ค. scale-in ๊ท์น์ด ํธ๋ฆฌ๊ฑฐ๋ผ๋ minimum ์๋๋ก ์ค์ด๋ค์ง ์์ ํญ์ ์ต์ํ์ ์ฉ๋์ ๋ณด์ฅํฉ๋๋ค.",
|
| 688 |
+
"difficulty": "easy",
|
| 689 |
+
"source_id": "azure-vmss-overview"
|
| 690 |
+
},
|
| 691 |
+
{
|
| 692 |
+
"id": "azure-q75",
|
| 693 |
+
"lesson_id": "azure-vnet-peering",
|
| 694 |
+
"question_type": "multiple_choice",
|
| 695 |
+
"question": "VNet Peering์ด ๋น์ ์ด์ (non-transitive)์ด๋ผ๋ ์๋ฏธ๋?",
|
| 696 |
+
"options": [
|
| 697 |
+
"AโB, BโC ํผ์ด๋ง์ด ์์ด๋ AโC๋ ์ง์ ํต์ ๋ถ๊ฐ",
|
| 698 |
+
"ํผ์ด๋ง๋ VNet๋ผ๋ฆฌ๋ ํญ์ ๋ผ์ฐํ
์ด ์๋์ผ๋ก ๋๋ค",
|
| 699 |
+
"ํผ์ด๋ง์ ๋์ผ ์ง์ญ์์๋ง ๊ฐ๋ฅํ๋ค",
|
| 700 |
+
"A์์ B๋ฅผ ํตํด C๋ก ํธ๋ํฝ์ด ์๋ ์ ๋ฌ๋๋ค"
|
| 701 |
+
],
|
| 702 |
+
"answer": "AโB, BโC ํผ์ด๋ง์ด ์์ด๋ AโC๋ ์ง์ ํต์ ๋ถ๊ฐ",
|
| 703 |
+
"explanation": "VNet Peering์ ๋น์ ์ด์ ์
๋๋ค. A-B, B-C๊ฐ ํผ์ด๋ง๋์ด๋ A-C ํธ๋ํฝ์ ์ฐจ๋จ๋ฉ๋๋ค. A-C ํต์ ์ด ํ์ํ๋ฉด ๋ณ๋์ A-C ํผ์ด๋ง์ ๋ง๋ค๊ฑฐ๋ Hub-Spoke + VPN Gateway๋ฅผ ์๋๋ค.",
|
| 704 |
+
"difficulty": "medium",
|
| 705 |
+
"source_id": "azure-vnet-overview"
|
| 706 |
+
},
|
| 707 |
+
{
|
| 708 |
+
"id": "azure-q76",
|
| 709 |
+
"lesson_id": "azure-route-table",
|
| 710 |
+
"question_type": "command",
|
| 711 |
+
"question": "`myRouteTable`์ `myRG`์ ์์ฑํ๋ CLI ๋ช
๋ น์ด๋ฅผ ์
๋ ฅํ์ธ์.",
|
| 712 |
+
"options": [],
|
| 713 |
+
"answer": "az network route-table create --name myRouteTable --resource-group myRG",
|
| 714 |
+
"explanation": "`az network route-table create`๋ก Route Table์ ๋ง๋ค๊ณ , `az network route-table route create`๋ก ๊ฒฝ๋ก๋ฅผ ์ถ๊ฐํ ๋ค ์๋ธ๋ท์ ์ฐ๊ฒฐํฉ๋๋ค.",
|
| 715 |
+
"difficulty": "easy",
|
| 716 |
+
"source_id": "azure-vnet-overview"
|
| 717 |
+
},
|
| 718 |
+
{
|
| 719 |
+
"id": "azure-q77",
|
| 720 |
+
"lesson_id": "azure-private-endpoint",
|
| 721 |
+
"question_type": "multiple_choice",
|
| 722 |
+
"question": "Private Endpoint ์์ฑ ํ VNet ๋ด๋ถ์์ ์๋น์ค ์ด๋ฆ์ด public IP๋ก ํด์๋๋ค๋ฉด ์์ธ์ผ๋ก ๊ฐ์ฅ ๋ง๋ ๊ฒ์?",
|
| 723 |
+
"options": [
|
| 724 |
+
"Private DNS Zone์ด VNet์ ๋งํฌ๋์ง ์์๊ฑฐ๋ A ๋ ์ฝ๋๊ฐ ์๋ค",
|
| 725 |
+
"NSG ๊ท์น์ด ์๋ชป๋๋ค",
|
| 726 |
+
"Subnet ์ฃผ์ ๋ฒ์๊ฐ ๋ถ์กฑํ๋ค",
|
| 727 |
+
"Private Endpoint๊ฐ ์น์ธ๋์ง ์์๋ค"
|
| 728 |
+
],
|
| 729 |
+
"answer": "Private DNS Zone์ด VNet์ ๋งํฌ๋์ง ์์๊ฑฐ๋ A ๋ ์ฝ๋๊ฐ ์๋ค",
|
| 730 |
+
"explanation": "Private Endpoint๋ private IP๊ฐ ์๊ธฐ์ง๋ง, DNS๊ฐ ์ฌ์ ํ public IP๋ฅผ ๋ฐํํ๋ฉด ์ฐ๊ฒฐ์ด ๊ณต๊ฐ ์ธํฐ๋ท์ ํตํ๊ฒ ๋ฉ๋๋ค. Private DNS Zone ๋งํฌ์ A ๋ ์ฝ๋๋ฅผ ๋ฐ๋์ ํ์ธํด์ผ ํฉ๋๋ค.",
|
| 731 |
+
"difficulty": "hard",
|
| 732 |
+
"source_id": "azure-private-endpoint"
|
| 733 |
+
},
|
| 734 |
+
{
|
| 735 |
+
"id": "azure-q78",
|
| 736 |
+
"lesson_id": "azure-load-balancer-probe",
|
| 737 |
+
"question_type": "multiple_choice",
|
| 738 |
+
"question": "Azure Load Balancer์ Health Probe ์คํจ ์ ์ด๋ค ๋์์ด ์ผ์ด๋๋๊ฐ?",
|
| 739 |
+
"options": [
|
| 740 |
+
"ํด๋น ๋ฐฑ์๋ ์ธ์คํด์ค๋ก์ ํธ๋ํฝ ์ ๋ฌ์ ์ค๋จํ๋ค",
|
| 741 |
+
"๋ฐฑ์๋ ์ธ์คํด์ค๋ฅผ ์๋์ผ๋ก ์ฌ์์ํ๋ค",
|
| 742 |
+
"์ ์ฒด Load Balancer๋ฅผ ์ค์งํ๋ค",
|
| 743 |
+
"์ ์ธ์คํด์ค๋ฅผ ์๋ ์ถ๊ฐํ๋ค"
|
| 744 |
+
],
|
| 745 |
+
"answer": "ํด๋น ๋ฐฑ์๋ ์ธ์คํด์ค๋ก์ ํธ๋ํฝ ์ ๋ฌ์ ์ค๋จํ๋ค",
|
| 746 |
+
"explanation": "Health Probe๊ฐ ์ค์ ๋ ํ์ ์ด์ ์คํจํ๋ฉด Load Balancer๋ ํด๋น ์ธ์คํด์ค๋ฅผ unhealthy๋ก ํ์ํ๊ณ ํธ๋ํฝ ์ ๋ฌ์์ ์ ์ธํฉ๋๋ค. ๋ค์ ์ฑ๊ณตํ๋ฉด ์๋ ๋ณต๊ทํฉ๋๋ค.",
|
| 747 |
+
"difficulty": "easy",
|
| 748 |
+
"source_id": "azure-vnet-overview"
|
| 749 |
+
},
|
| 750 |
+
{
|
| 751 |
+
"id": "azure-q79",
|
| 752 |
+
"lesson_id": "azure-private-dns",
|
| 753 |
+
"question_type": "multiple_choice",
|
| 754 |
+
"question": "Private DNS Zone์ VNet์ `enableAutoRegistration: true`๋ก ์ฐ๊ฒฐํ๋ฉด?",
|
| 755 |
+
"options": [
|
| 756 |
+
"ํด๋น VNet์ VM์ด ์์ฑ/์ญ์ ๋ ๋ A ๋ ์ฝ๋๊ฐ ์๋์ผ๋ก ๋ฑ๋ก/์ญ์ ๋๋ค",
|
| 757 |
+
"DNS Zone์ด ์๋์ผ๋ก ๋ฐฑ์
๋๋ค",
|
| 758 |
+
"์ธ๋ถ ์ธํฐ๋ท์์๋ ์กฐํํ ์ ์๊ฒ ๋๋ค",
|
| 759 |
+
"Private Endpoint๊ฐ ์๋์ผ๋ก ์์ฑ๋๋ค"
|
| 760 |
+
],
|
| 761 |
+
"answer": "ํด๋น VNet์ VM์ด ์์ฑ/์ญ์ ๋ ๋ A ๋ ์ฝ๋๊ฐ ์๋์ผ๋ก ๋ฑ๋ก/์ญ์ ๋๋ค",
|
| 762 |
+
"explanation": "Auto-registration ๋งํฌ๋ VNet ๋ด VM์ ํ๋ผ์ด๋น IP๋ฅผ ํด๋น DNS Zone์ ์๋ ๋ฑ๋กํฉ๋๋ค. ์๋์ผ๋ก A ๋ ์ฝ๋๋ฅผ ๊ด๋ฆฌํ ํ์๊ฐ ์์ด์ง๋๋ค.",
|
| 763 |
+
"difficulty": "medium",
|
| 764 |
+
"source_id": "azure-dns-overview"
|
| 765 |
+
},
|
| 766 |
+
{
|
| 767 |
+
"id": "azure-q80",
|
| 768 |
+
"lesson_id": "azure-monitor-metrics",
|
| 769 |
+
"question_type": "multiple_choice",
|
| 770 |
+
"question": "Azure Monitor์์ ํน์ ๋ฉํธ๋ฆญ์ด ์๊ณ๊ฐ์ ์ด๊ณผํ ๋ ์ด๋ฉ์ผ์ ๋ณด๋ด๋ ค๋ฉด ๋ฌด์์ด ํ์ํ๊ฐ?",
|
| 771 |
+
"options": [
|
| 772 |
+
"Alert Rule + Action Group",
|
| 773 |
+
"Diagnostic Settings๋ง",
|
| 774 |
+
"Log Analytics Workspace๋ง",
|
| 775 |
+
"NSG Flow Log"
|
| 776 |
+
],
|
| 777 |
+
"answer": "Alert Rule + Action Group",
|
| 778 |
+
"explanation": "Alert Rule์ ์กฐ๊ฑด(์๊ณ๊ฐ)์ ์ ์ํ๊ณ , Action Group์ ์ด๋ฉ์ผยทSMSยท์นํ
๋ฑ ์๋ฆผ ๋ฐฉ๋ฒ์ ์ ์ํฉ๋๋ค. ๋ ๊ฐ์ง๊ฐ ์ฐ๊ฒฐ๋๏ฟฝ๏ฟฝ๏ฟฝ์ผ ์ค์ ๋ก ์๋ฆผ์ด ๋ฐ์ก๋ฉ๋๋ค.",
|
| 779 |
+
"difficulty": "easy",
|
| 780 |
+
"source_id": "azure-monitor-overview"
|
| 781 |
+
},
|
| 782 |
+
{
|
| 783 |
+
"id": "azure-q81",
|
| 784 |
+
"lesson_id": "azure-activity-log",
|
| 785 |
+
"question_type": "command",
|
| 786 |
+
"question": "์ง๋ 24์๊ฐ ๋์ `myRG`์์ ๋ฐ์ํ Activity Log๋ฅผ CLI๋ก ์กฐํํ๋ ๋ช
๋ น์ด๋ฅผ ์
๋ ฅํ์ธ์.",
|
| 787 |
+
"options": [],
|
| 788 |
+
"answer": "az monitor activity-log list --resource-group myRG --offset 24h",
|
| 789 |
+
"explanation": "`az monitor activity-log list --resource-group <RG> --offset 24h` ๋ก ์ต๊ทผ 24์๊ฐ ํ๋ ๋ก๊ทธ๋ฅผ ์กฐํํฉ๋๋ค. `--offset`์ ํ์ฌ ์๊ฐ ๊ธฐ์ค ์ด์ ์๊ฐ์
๋๋ค.",
|
| 790 |
+
"difficulty": "medium",
|
| 791 |
+
"source_id": "azure-monitor-overview"
|
| 792 |
+
},
|
| 793 |
+
{
|
| 794 |
+
"id": "azure-q82",
|
| 795 |
+
"lesson_id": "azure-alert",
|
| 796 |
+
"question_type": "multiple_choice",
|
| 797 |
+
"question": "Alert Rule์์ `Severity 0`๊ณผ `Severity 4`์ ์ฐจ์ด๋?",
|
| 798 |
+
"options": [
|
| 799 |
+
"Severity 0์ด ๊ฐ์ฅ ์ฌ๊ฐ(Critical), Severity 4๋ ๊ฐ์ฅ ๋ฎ์(Verbose)",
|
| 800 |
+
"Severity 4๊ฐ ๊ฐ์ฅ ์ฌ๊ฐํ๋ค",
|
| 801 |
+
"๋ ๊ฐ์ ๋์ผํ๋ค",
|
| 802 |
+
"Severity๋ ๊ฒฝ๋ณด ์กฐ๊ฑด ์๊ณ๊ฐ์ ์๋ฏธํ๋ค"
|
| 803 |
+
],
|
| 804 |
+
"answer": "Severity 0์ด ๊ฐ์ฅ ์ฌ๊ฐ(Critical), Severity 4๋ ๊ฐ์ฅ ๋ฎ์(Verbose)",
|
| 805 |
+
"explanation": "Azure Alert Severity๋ 0(Critical)๋ถํฐ 4(Verbose)๊น์ง 5๋จ๊ณ์
๋๋ค. ์ฌ๊ฐ๋๊ฐ ๋ฎ์์๋ก ๋ ์ํํ ์ํฉ์ ์๋ฏธํฉ๋๋ค.",
|
| 806 |
+
"difficulty": "easy",
|
| 807 |
+
"source_id": "azure-monitor-overview"
|
| 808 |
+
},
|
| 809 |
+
{
|
| 810 |
+
"id": "azure-q83",
|
| 811 |
+
"lesson_id": "azure-backup-policy",
|
| 812 |
+
"question_type": "multiple_choice",
|
| 813 |
+
"question": "VM Backup Policy์์ ์ค์ ํ๋ ํต์ฌ ๋ ๊ฐ์ง ์์๋?",
|
| 814 |
+
"options": [
|
| 815 |
+
"๋ฐฑ์
๋น๋(์ผ๋ณ/์ฃผ๋ณ)์ ๋ณด์กด ๊ธฐ๊ฐ",
|
| 816 |
+
"๋ฐฑ์
์์น์ VM ํฌ๊ธฐ",
|
| 817 |
+
"NSG ๊ท์น๊ณผ subnet",
|
| 818 |
+
"์ด๋ฉ์ผ ์๋ฆผ ์ฃผ์์ SKU"
|
| 819 |
+
],
|
| 820 |
+
"answer": "๋ฐฑ์
๋น๋(์ผ๋ณ/์ฃผ๋ณ)์ ๋ณด์กด ๊ธฐ๊ฐ",
|
| 821 |
+
"explanation": "Backup Policy๋ ์ธ์ ๋ฐฑ์
ํ ์ง(๋น๋)์ ์ผ๋ง๋ ์ค๋ ๋ณด์กดํ ์ง(๋ณด์กด ๊ธฐ๊ฐ)๋ฅผ ์ ์ํฉ๋๋ค. ๋ณด์กด ๊ธฐ๊ฐ์ด ๊ธธ์๋ก ๋ ๋ง์ ๋ณต๊ตฌ ์ง์ ์ ์ ์งํฉ๋๋ค.",
|
| 822 |
+
"difficulty": "easy",
|
| 823 |
+
"source_id": "azure-recovery-services-vault"
|
| 824 |
+
},
|
| 825 |
+
{
|
| 826 |
+
"id": "azure-q84",
|
| 827 |
+
"lesson_id": "azure-restore",
|
| 828 |
+
"question_type": "multiple_choice",
|
| 829 |
+
"question": "VM ๋ณต์ ์ '๊ธฐ์กด VM ๊ต์ฒด' ๋์ '์ VM์ผ๋ก ๋ณต์'์ ์ ํํ๋ ์ด์ ๋ก ๊ฐ์ฅ ๋ง๋ ๊ฒ์?",
|
| 830 |
+
"options": [
|
| 831 |
+
"๊ธฐ์กด VM์ ๋ณด์กดํ๋ฉด์ ๋ณต์ ๊ฒฐ๊ณผ๋ฅผ ๋จผ์ ๊ฒ์ฆํ๊ธฐ ์ํด",
|
| 832 |
+
"์ VM์ด ํญ์ ๋ ๋น ๋ฅด๊ธฐ ๋๋ฌธ",
|
| 833 |
+
"๊ธฐ์กด VM ๊ต์ฒด๊ฐ ๋ ์ค๋ ๊ฑธ๋ฆฌ๊ธฐ ๋๋ฌธ",
|
| 834 |
+
"์ VM์ ๋น์ฉ์ด ๋ฐ์ํ์ง ์๊ธฐ ๋๋ฌธ"
|
| 835 |
+
],
|
| 836 |
+
"answer": "๊ธฐ์กด VM์ ๋ณด์กดํ๋ฉด์ ๋ณต์ ๊ฒฐ๊ณผ๋ฅผ ๋จผ์ ๊ฒ์ฆํ๊ธฐ ์ํด",
|
| 837 |
+
"explanation": "ํ๋ก๋์
VM์ ์ง์ ๋ณต์ํ๋ฉด ๋๋๋ฆด ์ ์์ต๋๋ค. ์ VM์ผ๋ก ๋ณต์ํด ๋ฐ์ดํฐ์ ์ฑ ์ ์ ๋์์ ํ์ธํ ๋ค DNS๋ IP๋ฅผ ์ ํํ๋ ๊ฒ์ด ์์ ํฉ๋๋ค.",
|
| 838 |
+
"difficulty": "medium",
|
| 839 |
+
"source_id": "azure-recovery-services-vault"
|
| 840 |
+
},
|
| 841 |
+
{
|
| 842 |
+
"id": "azure-q85",
|
| 843 |
+
"lesson_id": "azure-app-service-plan",
|
| 844 |
+
"question_type": "multiple_choice",
|
| 845 |
+
"question": "App Service Plan์ Free ํฐ์ด์ Standard ํฐ์ด์ ๊ฐ์ฅ ํฐ ๊ธฐ๋ฅ ์ฐจ์ด๋?",
|
| 846 |
+
"options": [
|
| 847 |
+
"Standard ์ด์์์๋ง Custom Domain, SSL, ๋ฐฐํฌ ์ฌ๋กฏ, ์๋ ํฌ๊ธฐ ์กฐ์ ์ด ๊ฐ๋ฅํ๋ค",
|
| 848 |
+
"Free ํฐ์ด๊ฐ ๋ ๋น ๋ฅธ ์ฒ๋ฆฌ๋์ ์ ๊ณตํ๋ค",
|
| 849 |
+
"Standard๋ Linux๋ง ์ง์ํ๋ค",
|
| 850 |
+
"Free ํฐ์ด์์๋ง VNet ํตํฉ์ด ๊ฐ๋ฅํ๋ค"
|
| 851 |
+
],
|
| 852 |
+
"answer": "Standard ์ด์์์๋ง Custom Domain, SSL, ๋ฐฐํฌ ์ฌ๋กฏ, ์๋ ํฌ๊ธฐ ์กฐ์ ์ด ๊ฐ๋ฅํ๋ค",
|
| 853 |
+
"explanation": "Free/Shared ํฐ์ด๋ ๊ฐ๋ฐยทํ
์คํธ์ฉ์
๋๋ค. Custom Domain ๋ฐ์ธ๋ฉ, SSL ์ธ์ฆ์, ๋ฐฐํฌ ์ฌ๋กฏ(Blue-Green), Autoscale์ Standard ์ด์์์ ์ง์ํฉ๋๋ค.",
|
| 854 |
+
"difficulty": "medium",
|
| 855 |
+
"source_id": "azure-app-service-overview"
|
| 856 |
+
},
|
| 857 |
+
{
|
| 858 |
+
"id": "azure-q86",
|
| 859 |
+
"lesson_id": "azure-container-registry",
|
| 860 |
+
"command": "command",
|
| 861 |
+
"question_type": "command",
|
| 862 |
+
"question": "ACR `myACR`์์ ์ด๋ฏธ์ง `myapp:v1`์ ๋น๋ํด ํธ์ํ๋ CLI ๋ช
๋ น์ด๋ฅผ ์
๋ ฅํ์ธ์.",
|
| 863 |
+
"options": [],
|
| 864 |
+
"answer": "az acr build --registry myACR --image myapp:v1 .",
|
| 865 |
+
"explanation": "`az acr build`๋ ๋ก์ปฌ Dockerfile์ ACR ๋น๋ ์์ด์ ํธ์ ๋ณด๋ด ๋น๋ ํ ์๋์ผ๋ก ๋ ์ง์คํธ๋ฆฌ์ ํธ์ํฉ๋๋ค. ๋ก์ปฌ์ Docker ์ค์น๊ฐ ํ์ ์์ต๋๋ค.",
|
| 866 |
+
"difficulty": "medium",
|
| 867 |
+
"source_id": "azure-vm-overview"
|
| 868 |
+
},
|
| 869 |
+
{
|
| 870 |
+
"id": "azure-q87",
|
| 871 |
+
"lesson_id": "azure-key-vault",
|
| 872 |
+
"question_type": "multiple_choice",
|
| 873 |
+
"question": "Key Vault์์ ๋น๋ฐ(Secret), ํค(Key), ์ธ์ฆ์(Certificate)์ ์ฐจ์ด๋?",
|
| 874 |
+
"options": [
|
| 875 |
+
"Secret์ ํจ์ค์๋ ๊ฐ์ ์์ ๋ฌธ์์ด, Key๋ ์ํธํ์ฉ ํค ์์ฌ, Certificate๋ X.509 ์ธ์ฆ์๋ค",
|
| 876 |
+
"์ธ ๊ฐ์ง ๋ชจ๋ ๋์ผํ ๋ชฉ์ ์ผ๋ก ์ฌ์ฉ๋๋ค",
|
| 877 |
+
"Key๋ ํจ์ค์๋, Secret์ ์ํธํ ํค๋ค",
|
| 878 |
+
"Certificate๋ ๋คํธ์ํฌ ๋ฐฉํ๋ฒฝ ๊ท์น์ด๋ค"
|
| 879 |
+
],
|
| 880 |
+
"answer": "Secret์ ํจ์ค์๋ ๊ฐ์ ์์ ๋ฌธ์์ด, Key๋ ์ํธํ์ฉ ํค ์์ฌ, Certificate๋ X.509 ์ธ์ฆ์๋ค",
|
| 881 |
+
"explanation": "Secret: DB ๋น๋ฐ๋ฒํธยทAPI ํค ๊ฐ์ ๋ฌธ์์ด. Key: HSM์์ ๋ณดํธ๋๋ ์ํธํ/์๋ช
์ฉ ํค ์์ฌ. Certificate: TLS ์ธ์ฆ์๋ก ์๋ ๊ฐฑ์ ๊ธฐ๋ฅ์ ์ ๊ณตํฉ๋๋ค.",
|
| 882 |
+
"difficulty": "medium",
|
| 883 |
+
"source_id": "azure-key-vault-overview"
|
| 884 |
+
},
|
| 885 |
+
{
|
| 886 |
+
"id": "azure-q88",
|
| 887 |
+
"lesson_id": "azure-cost-management",
|
| 888 |
+
"question_type": "multiple_choice",
|
| 889 |
+
"question": "Azure Cost Management์์ ์๋ณ ์์ฐ ์ด๊ณผ ์ ์๋์ผ๋ก ๋ฆฌ์์ค๋ฅผ ์ข
๋ฃํ๋ ค๋ฉด?",
|
| 890 |
+
"options": [
|
| 891 |
+
"์์ฐ ๊ฒฝ๋ณด(Budget Alert)๋ ์๋ฆผ๋ง ๋ณด๋ด๊ณ ์๋ ์ข
๋ฃ๋ Action Group + Automation์ผ๋ก ๋ณ๋ ๊ตฌ์ฑํด์ผ ํ๋ค",
|
| 892 |
+
"์์ฐ ์ค์ ๋ง ํ๋ฉด ์๋์ผ๋ก ๋ฆฌ์์ค๊ฐ ์ข
๋ฃ๋๋ค",
|
| 893 |
+
"Cost Management๊ฐ ์ง์ VM์ ์ค์งํ๋ค",
|
| 894 |
+
"Policy๋ฅผ ํตํด ์๋ ์ข
๋ฃ๋๋ค"
|
| 895 |
+
],
|
| 896 |
+
"answer": "์์ฐ ๊ฒฝ๋ณด(Budget Alert)๋ ์๋ฆผ๋ง ๋ณด๋ด๊ณ ์๋ ์ข
๋ฃ๋ Action Group + Automation์ผ๋ก ๋ณ๋ ๊ตฌ์ฑํด์ผ ํ๋ค",
|
| 897 |
+
"explanation": "Budget Alert์ ์์ฐ ์๊ณ๊ฐ ๋๋ฌ ์ ์ด๋ฉ์ผ๋ง ๋ณด๋
๋๋ค. ์ค์ ๋ฆฌ์์ค ์ข
๋ฃ๋ Automation Account์ Runbook์ Action Group์ ์ฐ๊ฒฐํด ํธ๋ฆฌ๊ฑฐํด์ผ ํฉ๋๋ค.",
|
| 898 |
+
"difficulty": "hard",
|
| 899 |
+
"source_id": "manual-az104-basic"
|
| 900 |
+
},
|
| 901 |
+
{
|
| 902 |
+
"id": "azure-q89",
|
| 903 |
+
"lesson_id": "azure-bastion",
|
| 904 |
+
"question_type": "multiple_choice",
|
| 905 |
+
"question": "Azure Bastion์ ๋ฐฐํฌํ๊ธฐ ์ํด VNet์ ๋ฐ๋์ ์์ด์ผ ํ๋ ์๋ธ๋ท ์ด๋ฆ์?",
|
| 906 |
+
"options": ["AzureBastionSubnet", "BastionSubnet", "GatewaySubnet", "PrivateEndpointSubnet"],
|
| 907 |
+
"answer": "AzureBastionSubnet",
|
| 908 |
+
"explanation": "Azure Bastion์ ์ ํํ `AzureBastionSubnet`์ด๋ผ๋ ์ด๋ฆ์ ์๋ธ๋ท์๋ง ๋ฐฐํฌ๋ฉ๋๋ค. ์ด๋ฆ์ด ๋ค๋ฅด๋ฉด ๋ฐฐํฌ์ ์คํจํฉ๋๋ค. ํฌ๊ธฐ๋ ์ต์ /27 ์ด์์ด์ด์ผ ํฉ๋๋ค.",
|
| 909 |
+
"difficulty": "easy",
|
| 910 |
+
"source_id": "azure-vnet-overview"
|
| 911 |
+
},
|
| 912 |
+
{
|
| 913 |
+
"id": "azure-q90",
|
| 914 |
+
"lesson_id": "azure-nat-gateway",
|
| 915 |
+
"question_type": "multiple_choice",
|
| 916 |
+
"question": "NAT Gateway๋ฅผ ์ฌ์ฉํ๋ ์ฃผ๋ ์ด์ ๋?",
|
| 917 |
+
"options": [
|
| 918 |
+
"VNet ๋ด Private VM์ ์์๋ฐ์ด๋ ์ธํฐ๋ท ์ฐ๊ฒฐ์ ๊ณ ์ Public IP๋ฅผ ์ ๊ณตํ๋ค",
|
| 919 |
+
"์ธ๋ฐ์ด๋ ํธ๋ํฝ์ VM์ผ๋ก ๋ถ์ฐํ๋ค",
|
| 920 |
+
"VNet ๊ฐ ๋ผ์ฐํ
์ ๋ด๋นํ๋ค",
|
| 921 |
+
"DNS ์ด๋ฆ์ ํด์ํ๋ค"
|
| 922 |
+
],
|
| 923 |
+
"answer": "VNet ๋ด Private VM์ ์์๋ฐ์ด๋ ์ธํฐ๋ท ์ฐ๊ฒฐ์ ๊ณ ์ Public IP๋ฅผ ์ ๊ณตํ๋ค",
|
| 924 |
+
"explanation": "NAT Gateway๋ Public IP๊ฐ ์๋ VM์ ์์๋ฐ์ด๋ ํธ๋ํฝ์ ๊ณ ์ Public IP๋ก SNATํฉ๋๋ค. ๋ก๋๋ฐธ๋ฐ์์ SNAT ํฌํธ ์์ง ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๋ฐ๋ ์ฌ์ฉํฉ๋๋ค.",
|
| 925 |
+
"difficulty": "medium",
|
| 926 |
+
"source_id": "azure-vnet-overview"
|
| 927 |
+
},
|
| 928 |
+
{
|
| 929 |
+
"id": "azure-q91",
|
| 930 |
+
"lesson_id": "azure-app-service",
|
| 931 |
+
"question_type": "command",
|
| 932 |
+
"question": "`myWebApp`์ GitHub Actions๋ก Node.js ์ฑ์ ๋ฐฐํฌํ๊ธฐ ์ํด ๊ฒ์ ํ๋กํ์ ๋ด๋ ค๋ฐ๋ CLI ๋ช
๋ น์ด๋ฅผ ์
๋ ฅํ์ธ์.",
|
| 933 |
+
"options": [],
|
| 934 |
+
"answer": "az webapp deployment list-publishing-profiles --name myWebApp --resource-group myRG",
|
| 935 |
+
"explanation": "`az webapp deployment list-publishing-profiles`๋ก ๊ฒ์ ํ๋กํ(FTP, WebDeploy, Git URL ๋ฑ)์ ๋ด๋ ค๋ฐ์ GitHub Actions ์ํฌ๋ฆฟ์ ๋ฑ๋กํฉ๋๋ค.",
|
| 936 |
+
"difficulty": "hard",
|
| 937 |
+
"source_id": "azure-app-service-overview"
|
| 938 |
+
},
|
| 939 |
+
{
|
| 940 |
+
"id": "azure-q92",
|
| 941 |
+
"lesson_id": "azure-deployment-slot",
|
| 942 |
+
"question_type": "multiple_choice",
|
| 943 |
+
"question": "๋ฐฐํฌ ์ฌ๋กฏ swap ํ ์ด์ ๋ฒ์ ์ผ๋ก ๋น ๋ฅด๊ฒ ๋กค๋ฐฑํ๋ ๋ฐฉ๋ฒ์?",
|
| 944 |
+
"options": [
|
| 945 |
+
"๋ค์ swap์ ์คํํ๋ฉด production๊ณผ staging์ด ๊ต์ฒด๋์ด ๋กค๋ฐฑ๋๋ค",
|
| 946 |
+
"git revert ํ ์ฌ๋ฐฐํฌํด์ผ ํ๋ค",
|
| 947 |
+
"VM์ ์ฌ์์ํ๋ฉด ๋๋ค",
|
| 948 |
+
"์ฌ๋กฏ์ ์ญ์ ํ๊ณ ์ฌ์์ฑํด์ผ ํ๋ค"
|
| 949 |
+
],
|
| 950 |
+
"answer": "๋ค์ swap์ ์คํํ๋ฉด production๊ณผ staging์ด ๊ต์ฒด๋์ด ๋กค๋ฐฑ๋๋ค",
|
| 951 |
+
"explanation": "Swap์ production๊ณผ staging์ ์ญํ ์ ๊ตํํฉ๋๋ค. ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋ฉด ๋ค์ swap์ผ๋ก ์ฆ์ ์ด์ ๋ฒ์ ์ผ๋ก ๋์๊ฐ ์ ์์ต๋๋ค.",
|
| 952 |
+
"difficulty": "easy",
|
| 953 |
+
"source_id": "azure-app-service-overview"
|
| 954 |
+
},
|
| 955 |
+
{
|
| 956 |
+
"id": "azure-q93",
|
| 957 |
+
"lesson_id": "azure-aci",
|
| 958 |
+
"question_type": "command",
|
| 959 |
+
"question": "`myACR.azurecr.io/myapp:v1` ์ด๋ฏธ์ง๋ก `myContainer` ์ปจํ
์ด๋ ์ธ์คํด์ค๋ฅผ ์์ฑํ๋ CLI ๋ช
๋ น์ด๋ฅผ ์
๋ ฅํ์ธ์.",
|
| 960 |
+
"options": [],
|
| 961 |
+
"answer": "az container create --resource-group myRG --name myContainer --image myACR.azurecr.io/myapp:v1",
|
| 962 |
+
"explanation": "`az container create --image <์ด๋ฏธ์ง>` ๋ก ACI๋ฅผ ์์ฑํฉ๋๋ค. ACR์ ํ๋ผ์ด๋น ์ด๋ฏธ์ง๋ `--registry-login-server`, `--registry-username`, `--registry-password` ์ต์
์ด ํ์ํฉ๋๋ค.",
|
| 963 |
+
"difficulty": "medium",
|
| 964 |
+
"source_id": "azure-container-instances"
|
| 965 |
+
},
|
| 966 |
+
{
|
| 967 |
+
"id": "azure-q94",
|
| 968 |
+
"lesson_id": "azure-keyvault-secret",
|
| 969 |
+
"question_type": "command",
|
| 970 |
+
"question": "`myKV` Key Vault์์ `db-password` ๋น๋ฐ์ ํ์ฌ ๊ฐ์ ์กฐํํ๋ CLI ๋ช
๋ น์ด๋ฅผ ์
๋ ฅํ์ธ์.",
|
| 971 |
+
"options": [],
|
| 972 |
+
"answer": "az keyvault secret show --vault-name myKV --name db-password",
|
| 973 |
+
"explanation": "`az keyvault secret show --vault-name <KV> --name <๋น๋ฐ์ด๋ฆ>` ์ผ๋ก ํ์ฌ ํ์ฑ ๋ฒ์ ์ ๋น๋ฐ ๊ฐ์ ์กฐํํฉ๋๋ค. ์ถ๋ ฅ์์ `value` ํ๋์ ์ค์ ๊ฐ์ด ์์ต๋๋ค.",
|
| 974 |
+
"difficulty": "easy",
|
| 975 |
+
"source_id": "azure-key-vault-overview"
|
| 976 |
+
},
|
| 977 |
+
{
|
| 978 |
+
"id": "azure-q95",
|
| 979 |
+
"lesson_id": "azure-managed-identity",
|
| 980 |
+
"question_type": "multiple_choice",
|
| 981 |
+
"question": "System-assigned Managed Identity์ User-assigned Managed Identity์ ์ฐจ์ด๋?",
|
| 982 |
+
"options": [
|
| 983 |
+
"System-assigned๋ ๋ฆฌ์์ค์ ์๋ช
์ด ๊ฐ๊ณ , User-assigned๋ ๋
๋ฆฝ์ ์ผ๋ก ๋ง๋ค์ด ์ฌ๋ฌ ๋ฆฌ์์ค์ ๊ณต์ ๊ฐ๋ฅํ๋ค",
|
| 984 |
+
"User-assigned๋ ์๋์ผ๋ก ๊ถํ์ด ๋ถ์ฌ๋๋ค",
|
| 985 |
+
"System-assigned๋ ์ฌ๋ฌ VM์ ๊ณต์ ๊ฐ๋ฅํ๋ค",
|
| 986 |
+
"๋ ํ์
์ ๋์ผํ๊ฒ ๋์ํ๋ค"
|
| 987 |
+
],
|
| 988 |
+
"answer": "System-assigned๋ ๋ฆฌ์์ค์ ์๋ช
์ด ๊ฐ๊ณ , User-assigned๋ ๋
๋ฆฝ์ ์ผ๋ก ๋ง๋ค์ด ์ฌ๋ฌ ๋ฆฌ์์ค์ ๊ณต์ ๊ฐ๋ฅํ๋ค",
|
| 989 |
+
"explanation": "System-assigned๋ VM/App Service ์์ฑ ์ ์๋์ผ๋ก ๋ง๋ค์ด์ง๊ณ ๋ฆฌ์์ค ์ญ์ ์ ํจ๊ป ์ญ์ ๋ฉ๋๋ค. User-assigned๋ ๋ณ๋๋ก ๋ง๋ค์ด ์ฌ๋ฌ ๋ฆฌ์์ค์ ํ ๋นํ ์ ์์ด ๊ณต์ ์๋๋ฆฌ์ค์ ์ ํฉํฉ๋๋ค.",
|
| 990 |
+
"difficulty": "medium",
|
| 991 |
+
"source_id": "azure-key-vault-overview"
|
| 992 |
+
},
|
| 993 |
+
{
|
| 994 |
+
"id": "azure-q96",
|
| 995 |
+
"lesson_id": "azure-network-watcher",
|
| 996 |
+
"question_type": "multiple_choice",
|
| 997 |
+
"question": "Network Watcher์ IP flow verify ๊ธฐ๋ฅ์ผ๋ก ํ์ธํ ์ ์๋ ๊ฒ์?",
|
| 998 |
+
"options": [
|
| 999 |
+
"ํน์ IP์ ํฌํธ ์กฐํฉ์ด NSG์ ์ํด ํ์ฉ๋๋์ง ์ฐจ๋จ๋๋์ง",
|
| 1000 |
+
"VM์ CPU ์ฌ์ฉ๋ฅ ",
|
| 1001 |
+
"Blob ์ ๊ทผ ์ด๋ ฅ",
|
| 1002 |
+
"Key Vault ์ ๊ทผ ๋ก๊ทธ"
|
| 1003 |
+
],
|
| 1004 |
+
"answer": "ํน์ IP์ ํฌํธ ์กฐํฉ์ด NSG์ ์ํด ํ์ฉ๋๋์ง ์ฐจ๋จ๋๋์ง",
|
| 1005 |
+
"explanation": "IP flow verify๋ VM NIC์์ ํน์ ์์ค IP, ๋ชฉ์ ์ง IP, ํฌํธ, ๋ฐฉํฅ(์ธ๋ฐ์ด๋/์์๋ฐ์ด๋)์ ์
๋ ฅํ๋ฉด ์ด๋ค NSG ๊ท์น์ด ์ ์ฉ๋๋์ง ์ฆ์ ํ์ธํ ์ ์์ต๋๋ค.",
|
| 1006 |
+
"difficulty": "medium",
|
| 1007 |
+
"source_id": "azure-vnet-overview"
|
| 1008 |
+
},
|
| 1009 |
+
{
|
| 1010 |
+
"id": "azure-q97",
|
| 1011 |
+
"lesson_id": "azure-move-resource",
|
| 1012 |
+
"question_type": "command",
|
| 1013 |
+
"question": "`myRG`์ VM `myVM`์ `targetRG`๋ก ์ด๋ํ๋ CLI ๋ช
๋ น์ด๋ฅผ ์
๋ ฅํ์ธ์.",
|
| 1014 |
+
"options": [],
|
| 1015 |
+
"answer": "az resource move --destination-group targetRG --ids $(az vm show --resource-group myRG --name myVM --query id -o tsv)",
|
| 1016 |
+
"explanation": "`az resource move --destination-group <๋์RG> --ids <๋ฆฌ์์คID>` ๋ก ์ด๋ํฉ๋๋ค. ID๋ `az vm show --query id`๋ก ๊ฐ์ ธ์ต๋๋ค. ์ข
์ ๋ฆฌ์์ค(NIC, ๋์คํฌ)๋ ํจ๊ป ์ด๋ํด์ผ ํฉ๋๋ค.",
|
| 1017 |
+
"difficulty": "hard",
|
| 1018 |
+
"source_id": "manual-az104-basic"
|
| 1019 |
+
},
|
| 1020 |
+
{
|
| 1021 |
+
"id": "azure-q99",
|
| 1022 |
+
"lesson_id": "azure-recovery-vault",
|
| 1023 |
+
"question_type": "command",
|
| 1024 |
+
"question": "`myRG`์ `myVM`์ `myVault` Recovery Services Vault์ `DefaultPolicy`๋ก ๋ฐฑ์
ํ์ฑํํ๋ CLI ๋ช
๋ น์ด๋ฅผ ์
๋ ฅํ์ธ์.",
|
| 1025 |
+
"options": [],
|
| 1026 |
+
"answer": "az backup protection enable-for-vm --vault-name myVault --resource-group myRG --vm myVM --policy-name DefaultPolicy",
|
| 1027 |
+
"explanation": "`az backup protection enable-for-vm`์ผ๋ก VM ๋ฐฑ์
์ ์์ํฉ๋๋ค. Vault์ VM์ ๊ฐ์ region์ ์์ด์ผ ํ๋ฉฐ, ์ต์ด ๋ฐฑ์
์ ํ์ฑํ ์งํ ๋๋ ์์ฝ ์๊ฐ์ ์คํ๋ฉ๋๋ค.",
|
| 1028 |
+
"difficulty": "medium",
|
| 1029 |
+
"source_id": "azure-recovery-services-vault"
|
| 1030 |
+
},
|
| 1031 |
+
{
|
| 1032 |
+
"id": "azure-q100",
|
| 1033 |
+
"lesson_id": "azure-subscription",
|
| 1034 |
+
"question_type": "multiple_choice",
|
| 1035 |
+
"question": "ํ๋์ Azure Tenant ์๋ ์ฌ๋ฌ Subscription์ ์ฌ์ฉํ๋ ์ฃผ๋ ์ด์ ๋?",
|
| 1036 |
+
"options": [
|
| 1037 |
+
"ํ๊ฒฝ(๊ฐ๋ฐ/์คํ
์ด์ง/์ด์)์ด๋ ๋ถ์๋ณ ๊ณผ๊ธ๊ณผ ์ ์ฑ
์ ๋ถ๋ฆฌํ๊ธฐ ์ํด",
|
| 1038 |
+
"Subscription์ด ๋ง์์๋ก ์๊ธ์ด ํ ์ธ๋๊ธฐ ๋๋ฌธ",
|
| 1039 |
+
"ํ Subscription์ VM์ 2๊ฐ ์ด์ ๋ง๋ค ์ ์๊ธฐ ๋๋ฌธ",
|
| 1040 |
+
"Subscription์ ๋๋ฆฌ๋ฉด ๊ฐ์ฉ์ฑ์ด ๋์์ง๊ธฐ ๋๋ฌธ"
|
| 1041 |
+
],
|
| 1042 |
+
"answer": "ํ๊ฒฝ(๊ฐ๋ฐ/์คํ
์ด์ง/์ด์)์ด๋ ๋ถ์๋ณ ๊ณผ๊ธ๊ณผ ์ ์ฑ
์ ๋ถ๋ฆฌํ๊ธฐ ์ํด",
|
| 1043 |
+
"explanation": "Subscription์ ๊ณผ๊ธ, ๋ฆฌ์์ค ํ ๋น๋, RBAC/Policy์ ๊ฒฝ๊ณ์
๋๋ค. ๊ฐ๋ฐ๊ณผ ์ด์์ ๋ถ๋ฆฌํ๊ฑฐ๋ ๋ถ์๋ณ ๋น์ฉ์ ๋
๋ฆฝ์ ์ผ๋ก ๊ด๋ฆฌํ ๋ ์ฌ๋ฌ Subscription์ ์ฌ์ฉํฉ๋๋ค.",
|
| 1044 |
+
"difficulty": "easy",
|
| 1045 |
+
"source_id": "manual-az104-basic"
|
| 1046 |
+
},
|
| 1047 |
+
{
|
| 1048 |
+
"id": "azure-q98",
|
| 1049 |
+
"lesson_id": "azure-template-deployment",
|
| 1050 |
+
"question_type": "command",
|
| 1051 |
+
"question": "`myRG`์ `main.bicep` ํ์ผ์ Bicep CLI๋ก ๋ฐฐํฌํ๋ ๋ช
๋ น์ด๋ฅผ ์
๋ ฅํ์ธ์.",
|
| 1052 |
+
"options": [],
|
| 1053 |
+
"answer": "az deployment group create --resource-group myRG --template-file main.bicep",
|
| 1054 |
+
"explanation": "`az deployment group create --template-file <ํ์ผ>`๋ก Bicep ๋๋ ARM JSON ํ
ํ๋ฆฟ์ ๋ฆฌ์์ค ๊ทธ๋ฃน์ ๋ฐฐํฌํฉ๋๋ค. `--parameters`๋ก ํ๋ผ๋ฏธํฐ ํ์ผ๋ ํจ๊ป ์ง์ ํ ์ ์์ต๋๋ค.",
|
| 1055 |
+
"difficulty": "easy",
|
| 1056 |
+
"source_id": "azure-arm-bicep-overview"
|
| 1057 |
+
}
|
| 1058 |
+
]
|
cert_study_app/content/linux/lessons.json
ADDED
|
@@ -0,0 +1,1448 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[
|
| 2 |
+
{
|
| 3 |
+
"id": "linux-pwd",
|
| 4 |
+
"certification": "LFCS / ๋ฆฌ๋
์ค๋ง์คํฐ",
|
| 5 |
+
"title": "pwd โ ํ์ฌ ๋๋ ํฐ๋ฆฌ ํ์ธ",
|
| 6 |
+
"summary": "ํ์ฌ ์์ ์์
๋๋ ํฐ๋ฆฌ๋ฅผ ์ ๋๊ฒฝ๋ก๋ก ์ถ๋ ฅํฉ๋๋ค. ํ์ผ ์กฐ์ ๋ช
๋ น์ ๋ชจ๋ ์ด ์์น๋ฅผ ๊ธฐ์ค์ผ๋ก ์คํ๋๋ฏ๋ก ์์
์ ํ์ธ ์ต๊ด์ด ์ค์ํฉ๋๋ค.",
|
| 7 |
+
"example": "pwd\n# /home/ubuntu\ncd /var/log && pwd\n# /var/log",
|
| 8 |
+
"common_mistake": "์๋๊ฒฝ๋ก(../dir)๋ pwd ๊ฒฐ๊ณผ ๊ธฐ์ค์ผ๋ก ํด์๋ฉ๋๋ค. ํท๊ฐ๋ฆฌ๋ฉด ์ ๋๊ฒฝ๋ก๋ฅผ ์ฌ์ฉํ์ธ์.",
|
| 9 |
+
"keywords": [
|
| 10 |
+
"pwd",
|
| 11 |
+
"working directory",
|
| 12 |
+
"absolute path"
|
| 13 |
+
],
|
| 14 |
+
"source_id": "linux-bash-manual",
|
| 15 |
+
"details": [
|
| 16 |
+
"`pwd`๋ ํ์ฌ ์์น๋ฅผ ์ ๋๊ฒฝ๋ก๋ก ์ถ๋ ฅํฉ๋๋ค. ํ๋กฌํํธ์ ํ์๋ ๊ฒฝ๋ก๊ฐ ์๋ฆด ๋ ์ ํํ ์์น๋ฅผ ํ์ธํ๋ ์ฉ๋๋ก ์๋๋ค.",
|
| 17 |
+
"์คํฌ๋ฆฝํธ์์ `DIR=$(pwd)`๋ก ํ์ฌ ๊ฒฝ๋ก๋ฅผ ์ ์ฅํด๋๋ฉด `cd` ํ `cd $DIR`๋ก ๋ณต๊ทํ ์ ์์ต๋๋ค.",
|
| 18 |
+
"์ํ์์๋ `cd`๋ก ์ด๋ ํ `pwd` ๊ฒฐ๊ณผ๋ฅผ ๋ฌป๊ฑฐ๋, ์๋๊ฒฝ๋ก ๋ช
๋ น์ด ์ด๋ ์์น์ ์ ์ฉ๋๋์ง ์ถ๋ก ํ๋ ํํ๋ก ์ถ์ ๋ฉ๋๋ค."
|
| 19 |
+
]
|
| 20 |
+
},
|
| 21 |
+
{
|
| 22 |
+
"id": "linux-ls",
|
| 23 |
+
"certification": "LFCS / ๋ฆฌ๋
์ค๋ง์คํฐ",
|
| 24 |
+
"title": "ls โ ๋๋ ํฐ๋ฆฌ ๋ชฉ๋ก ํ์ธ",
|
| 25 |
+
"summary": "๋๋ ํฐ๋ฆฌ์ ํ์ผ๊ณผ ํ์ ๋๋ ํฐ๋ฆฌ๋ฅผ ๋์ดํฉ๋๋ค. ๊ถํยท์์ ์ยทํฌ๊ธฐยท์์ ์๊ฐ๊น์ง ๋ณด๋ ค๋ฉด `-l`, ์จ๊นํ์ผ ํฌํจ์ `-a`๋ฅผ ์๋๋ค.",
|
| 26 |
+
"example": "ls -al /etc\nls -lh /var/log\nls -lt # ์์ ์๊ฐ ์ญ์ ์ ๋ ฌ",
|
| 27 |
+
"common_mistake": "`ls -l`์ ์ฒซ ์ปฌ๋ผ์ ๊ถํ ๋นํธ(rwxrwxrwx)์
๋๋ค. d๋ก ์์ํ๋ฉด ๋๋ ํฐ๋ฆฌ, -๋ฉด ์ผ๋ฐ ํ์ผ, l์ด๋ฉด ์ฌ๋ณผ๋ฆญ ๋งํฌ.",
|
| 28 |
+
"keywords": [
|
| 29 |
+
"ls",
|
| 30 |
+
"-l",
|
| 31 |
+
"-a",
|
| 32 |
+
"-h",
|
| 33 |
+
"hidden files",
|
| 34 |
+
"permissions"
|
| 35 |
+
],
|
| 36 |
+
"source_id": "linux-bash-manual",
|
| 37 |
+
"details": [
|
| 38 |
+
"`ls -l` ์ถ๋ ฅ: `๊ถํ ๋งํฌ์ ์์ ์ ๊ทธ๋ฃน ํฌ๊ธฐ ๋ ์ง ์ด๋ฆ` ์์. ๊ถํ ๋นํธ ์ฝ๊ธฐ๋ฅผ ๋ฐ๋์ ์ตํ์ผ ํฉ๋๋ค.",
|
| 39 |
+
"`-a`๋ `.`์ผ๋ก ์์ํ๋ ์จ๊นํ์ผ ํฌํจ. `-h`๋ ์ฉ๋์ KB/MB๋ก ์ฌ๋์ด ์ฝ๊ธฐ ์ฝ๊ฒ ํ์ํฉ๋๋ค.",
|
| 40 |
+
"์ํ ํจํด: ํน์ ๋๋ ํฐ๋ฆฌ์ ํ์ผ ๊ถํยท์์ ์๋ฅผ ํ์ธํ๊ฑฐ๋, ์ต๊ทผ ์์ ํ์ผ์ ์ฐพ๋ ๋ฌธ์ ์์ `ls -lt` ์กฐํฉ์ด ์์ฃผ ๋์ต๋๋ค."
|
| 41 |
+
]
|
| 42 |
+
},
|
| 43 |
+
{
|
| 44 |
+
"id": "linux-cd",
|
| 45 |
+
"certification": "LFCS / ๋ฆฌ๋
์ค๋ง์คํฐ",
|
| 46 |
+
"title": "cd โ ๋๋ ํฐ๋ฆฌ ์ด๋",
|
| 47 |
+
"summary": "์์
๋๋ ํฐ๋ฆฌ๋ฅผ ๋ณ๊ฒฝํฉ๋๋ค. ์ดํ ์คํํ๋ ๋ชจ๋ ์๋๊ฒฝ๋ก ๋ช
๋ น์ ๊ธฐ์ค์ด ๋ฐ๋๋๋ค.",
|
| 48 |
+
"example": "cd /etc/nginx # ์ ๋๊ฒฝ๋ก ์ด๋\ncd .. # ๋ถ๋ชจ ๋๋ ํฐ๋ฆฌ\ncd ~ # ํ ๋๋ ํฐ๋ฆฌ\ncd - # ์ด์ ๋๋ ํฐ๋ฆฌ",
|
| 49 |
+
"common_mistake": "`cd ..`์ ํ ๋จ๊ณ ์, `cd /`๋ ๋ฃจํธ๋ก ์ด๋. `cd -`๋ ๋ฐ๋ก ์ง์ ์์น๋ก ๋์์ต๋๋ค.",
|
| 50 |
+
"keywords": [
|
| 51 |
+
"cd",
|
| 52 |
+
"relative path",
|
| 53 |
+
"absolute path",
|
| 54 |
+
"home"
|
| 55 |
+
],
|
| 56 |
+
"source_id": "linux-bash-cd",
|
| 57 |
+
"details": [
|
| 58 |
+
"`cd ์ ๋๊ฒฝ๋ก`๋ ์ด๋์๋ ๋์ผ ์์น๋ก ์ด๋. `cd ์๋๊ฒฝ๋ก`๋ ํ์ฌ ์์น ๊ธฐ์ค์ผ๋ก ์ด๋ํฉ๋๋ค.",
|
| 59 |
+
"`cd ~user`๋ ๋ค๋ฅธ ์ฌ์ฉ์์ ํ ๋๋ ํฐ๋ฆฌ๋ก ์ด๋ํฉ๋๋ค. ๊ด๋ฆฌ์ ์์
์ ์์ฃผ ํ์ฉํฉ๋๋ค.",
|
| 60 |
+
"์ํ ํจํด: ์ฌ๋ฌ ๋ฒ `cd`๋ก ์ด๋ ํ ํ์ฌ ์์น๋ฅผ ๋ฌป๊ฑฐ๋, ์ฌ๋ฐ๋ฅธ ๊ฒฝ๋ก ํํ์์ ๊ณ ๋ฅด๋ ๋ฌธ์ ๊ฐ ์ถ์ ๋ฉ๋๋ค."
|
| 61 |
+
]
|
| 62 |
+
},
|
| 63 |
+
{
|
| 64 |
+
"id": "linux-mkdir",
|
| 65 |
+
"certification": "LFCS / ๋ฆฌ๋
์ค๋ง์คํฐ",
|
| 66 |
+
"title": "mkdir โ ๋๋ ํฐ๋ฆฌ ์์ฑ",
|
| 67 |
+
"summary": "์ ๋๋ ํฐ๋ฆฌ๋ฅผ ๋ง๋ญ๋๋ค. `-p` ์ต์
์ผ๋ก ์ค๊ฐ ๊ฒฝ๋ก๊ฐ ์์ด๋ ํ ๋ฒ์ ์์ฑํ ์ ์์ต๋๋ค.",
|
| 68 |
+
"example": "mkdir logs\nmkdir -p /srv/app/config # ์ค๊ฐ ๋๋ ํฐ๋ฆฌ ์๋ ์์ฑ\nmkdir -m 750 secure_dir # ๊ถํ ์ง์ ํด ์์ฑ",
|
| 69 |
+
"common_mistake": "๋ถ๋ชจ ๋๋ ํฐ๋ฆฌ๊ฐ ์๋ ๊ฒฝ๋ก์ `mkdir`๋ง ์ฐ๋ฉด ์๋ฌ๋ฉ๋๋ค. `-p`๋ฅผ ๋ถ์ด๋ฉด ๋ถ๋ชจ๊น์ง ์๋ ์์ฑ๋ฉ๋๋ค.",
|
| 70 |
+
"keywords": [
|
| 71 |
+
"mkdir",
|
| 72 |
+
"-p",
|
| 73 |
+
"directory",
|
| 74 |
+
"create"
|
| 75 |
+
],
|
| 76 |
+
"source_id": "linux-bash-manual",
|
| 77 |
+
"details": [
|
| 78 |
+
"`mkdir -p a/b/c`๋ a, a/b, a/b/c๋ฅผ ํ ๋ฒ์ ๋ง๋ญ๋๋ค. ์คํฌ๋ฆฝํธ์์ ๊ฒฝ๋ก ์ค๋น ์ ํ์ ์ต์
์
๋๋ค.",
|
| 79 |
+
"`-m ๋ชจ๋`๋ก ์์ฑ๊ณผ ๋์์ ๊ถํ์ ์ค์ ํ ์ ์์ต๋๋ค: `mkdir -m 700 private`.",
|
| 80 |
+
"์ํ ํจํด: ์ค์ต์์ ํน์ ๊ฒฝ๋ก๋ฅผ ๋ง๋ค๊ณ ์ด์ด์ ๊ถํยท์์ ์๋ฅผ ์ค์ ํ๋ ํ๋ฆ์ผ๋ก ์์ฃผ ๋ฑ์ฅํฉ๋๋ค."
|
| 81 |
+
]
|
| 82 |
+
},
|
| 83 |
+
{
|
| 84 |
+
"id": "linux-touch",
|
| 85 |
+
"certification": "LFCS / ๋ฆฌ๋
์ค๋ง์คํฐ",
|
| 86 |
+
"title": "touch โ ํ์ผ ์์ฑ / ํ์์คํฌํ ๊ฐฑ์ ",
|
| 87 |
+
"summary": "๋น ํ์ผ์ ์์ฑํ๊ฑฐ๋, ์ด๋ฏธ ์๋ ํ์ผ์ ์์ ์๊ฐ์ ํ์ฌ ์๊ฐ์ผ๋ก ๊ฐฑ์ ํฉ๋๋ค.",
|
| 88 |
+
"example": "touch newfile.txt\ntouch -t 202401010000 old.txt # ํน์ ์๊ฐ์ผ๋ก ์ค์ ",
|
| 89 |
+
"common_mistake": "์ด๋ฏธ ์๋ ํ์ผ์ `touch`๋ฅผ ์ฐ๏ฟฝ๏ฟฝ ๋ด์ฉ์ ์ง์ฐ์ง ์๊ณ ์๊ฐ ์ ๋ณด๋ง ๊ฐฑ์ ๋ฉ๋๋ค.",
|
| 90 |
+
"keywords": [
|
| 91 |
+
"touch",
|
| 92 |
+
"timestamp",
|
| 93 |
+
"create",
|
| 94 |
+
"mtime"
|
| 95 |
+
],
|
| 96 |
+
"source_id": "linux-bash-manual",
|
| 97 |
+
"details": [
|
| 98 |
+
"ํ์ผ์ด ์์ผ๋ฉด ๋น ํ์ผ์ ๋ง๋ค๊ณ , ์์ผ๋ฉด atime(์ ๊ทผ)๊ณผ mtime(์์ ) ์๊ฐ์ ํ์ฌ๋ก ๊ฐฑ์ ํฉ๋๋ค.",
|
| 99 |
+
"`-t YYYYMMDDhhmm` ํํ๋ก ์ํ๋ ์๊ฐ์ ์ง์ ์ง์ ํ ์ ์์ด ํ
์คํธ ์๋๋ฆฌ์ค์์ ํ์ฉ๋ฉ๋๋ค.",
|
| 100 |
+
"์ํ ํจํด: ํ์ผ ์์ฑ ํ `ls -l`๋ก ์กด์ฌยท์๊ฐ ํ์ธ, ๋๋ `find -newer`๋ก ์ต๊ทผ ํ์ผ ๊ฒ์ํ๋ ํ๋ฆ๊ณผ ์ฐ๊ฒฐ๋ฉ๋๋ค."
|
| 101 |
+
]
|
| 102 |
+
},
|
| 103 |
+
{
|
| 104 |
+
"id": "linux-cat",
|
| 105 |
+
"certification": "LFCS / ๋ฆฌ๋
์ค๋ง์คํฐ",
|
| 106 |
+
"title": "cat โ ํ์ผ ๋ด์ฉ ์ถ๋ ฅ",
|
| 107 |
+
"summary": "ํ์ผ ๋ด์ฉ์ ํ์ค ์ถ๋ ฅ์ผ๋ก ๋ณด์ฌ์ค๋๋ค. ์ฌ๋ฌ ํ์ผ์ ์ฐ๊ฒฐํ๊ฑฐ๋ ๋ฆฌ๋ค์ด๋ ์
์ผ๋ก ํ์ผ์ ๋ง๋ค ๋๋ ์๋๋ค.",
|
| 108 |
+
"example": "cat /etc/hostname\ncat file1.txt file2.txt > merged.txt\ncat -n file.txt # ์ค ๋ฒํธ ํ์",
|
| 109 |
+
"common_mistake": "ํฐ ํ์ผ์ `cat` ๋์ `less`(์คํฌ๋กค), `head`/`tail`(์ผ๋ถ๋ง)์ ์ฌ์ฉํ์ธ์.",
|
| 110 |
+
"keywords": [
|
| 111 |
+
"cat",
|
| 112 |
+
"stdout",
|
| 113 |
+
"concatenate",
|
| 114 |
+
"-n"
|
| 115 |
+
],
|
| 116 |
+
"source_id": "linux-bash-manual",
|
| 117 |
+
"details": [
|
| 118 |
+
"`cat`์ ํ์ผ ์ ์ฒด๋ฅผ ํ ๋ฒ์ ์ถ๋ ฅํฉ๋๋ค. `/etc/passwd`, `/etc/hosts` ๊ฐ์ ์ค์ ํ์ผ ๋น ๋ฅด๊ฒ ๋ณผ ๋ ์๋๋ค.",
|
| 119 |
+
"`cat file1 file2 > combined`๋ก ๋ ํ์ผ์ ํฉ์นฉ๋๋ค. `>>` ์ฌ์ฉ ์ ๊ธฐ์กด ํ์ผ์ ์ถ๊ฐ๋ฉ๋๋ค.",
|
| 120 |
+
"์ํ ํจํด: `cat > file << EOF โฆ EOF` ํํ์ here-doc์ผ๋ก ํ์ผ์ ์ง์ ์์ฑํ๋ ํจํด๋ ์ถ์ ๋ฉ๋๋ค."
|
| 121 |
+
]
|
| 122 |
+
},
|
| 123 |
+
{
|
| 124 |
+
"id": "linux-grep",
|
| 125 |
+
"certification": "LFCS / ๋ฆฌ๋
์ค๋ง์คํฐ",
|
| 126 |
+
"title": "grep โ ํ
์คํธ ํจํด ๊ฒ์",
|
| 127 |
+
"summary": "ํ์ผ์ด๋ ํ์ค ์
๋ ฅ์์ ํจํด์ด ์๋ ์ค์ ์ถ๋ ฅํฉ๋๋ค. ๋ก๊ทธ ๋ถ์๊ณผ ์ค์ ํ์ผ ๊ฒ์์ ๊ฐ์ฅ ๋ง์ด ์ฐ์ด๋ ๋ช
๋ น์ด์
๋๋ค.",
|
| 128 |
+
"example": "grep 'ERROR' /var/log/syslog\ngrep -rn 'PermitRootLogin' /etc/ssh/\ngrep -v '^#' /etc/ssh/sshd_config # ์ฃผ์ ์ ์ธ",
|
| 129 |
+
"common_mistake": "`grep`์ ๊ธฐ๋ณธ์ ์ผ๋ก ๋์๋ฌธ์๋ฅผ ๊ตฌ๋ถํฉ๋๋ค. ๊ตฌ๋ถ ์์ด ์ฐพ์ผ๋ ค๋ฉด `-i`๋ฅผ ์ถ๊ฐํ์ธ์.",
|
| 130 |
+
"keywords": [
|
| 131 |
+
"grep",
|
| 132 |
+
"-r",
|
| 133 |
+
"-n",
|
| 134 |
+
"-i",
|
| 135 |
+
"-v",
|
| 136 |
+
"pattern",
|
| 137 |
+
"regex"
|
| 138 |
+
],
|
| 139 |
+
"source_id": "linux-grep-manual",
|
| 140 |
+
"details": [
|
| 141 |
+
"์ฃผ์ ์ต์
: `-r`(์ฌ๊ท), `-n`(์ค๋ฒํธ), `-i`(๋์๋ฌธ์ ๋ฌด์), `-v`(์ ์ธ), `-l`(ํ์ผ๋ช
๋ง), `-c`(๊ฐ์).",
|
| 142 |
+
"`grep -r 'failed' /var/log/`๋ก ๋ก๊ทธ ๋๋ ํฐ๋ฆฌ ์ ์ฒด์์ ์ค๋ฅ๋ฅผ ๊ฒ์ํ ์ ์์ต๋๋ค.",
|
| 143 |
+
"์ํ ํจํด: `ps aux | grep nginx`์ฒ๋ผ ํ์ดํ์ ํจ๊ป, ๋๋ ์ค์ ํ์ผ์์ ํน์ ๊ฐ์ ์ฐพ๋ ๋ณตํฉ ๋ฌธ์ ๋ก ์ถ์ ๋ฉ๋๋ค."
|
| 144 |
+
]
|
| 145 |
+
},
|
| 146 |
+
{
|
| 147 |
+
"id": "linux-chmod",
|
| 148 |
+
"certification": "LFCS / ๋ฆฌ๋
์ค๋ง์คํฐ",
|
| 149 |
+
"title": "chmod โ ํ์ผ ๊ถํ ๋ณ๊ฒฝ",
|
| 150 |
+
"summary": "ํ์ผยท๋๋ ํฐ๋ฆฌ์ ์ฝ๊ธฐ(r=4), ์ฐ๊ธฐ(w=2), ์คํ(x=1) ๊ถํ์ ์์ ์ยท๊ทธ๋ฃนยท๊ธฐํ ์ฌ์ฉ์๋ณ๋ก ์ค์ ํฉ๋๋ค.",
|
| 151 |
+
"example": "chmod 755 script.sh # rwxr-xr-x\nchmod 644 config.conf # rw-r--r--\nchmod u+x,g-w file.txt # ์ฌ๋ณผ๋ฆญ ๋ฐฉ์",
|
| 152 |
+
"common_mistake": "8์ง์ ๋ฐฉ์: 7=rwx, 6=rw-, 5=r-x, 4=r--. `chmod 777`์ ๋ชจ๋ ์ฌ์ฉ์์ ๋ชจ๋ ๊ถํ โ ๋ณด์์ ์ํํฉ๋๋ค.",
|
| 153 |
+
"keywords": [
|
| 154 |
+
"chmod",
|
| 155 |
+
"permissions",
|
| 156 |
+
"rwx",
|
| 157 |
+
"octal",
|
| 158 |
+
"symbolic"
|
| 159 |
+
],
|
| 160 |
+
"source_id": "ubuntu-server-docs",
|
| 161 |
+
"details": [
|
| 162 |
+
"8์ง์ ํ๊ธฐ: ์ฒซ์งธ ์๋ฆฌ=์์ ์(u), ๋์งธ=๊ทธ๋ฃน(g), ์
์งธ=๊ธฐํ(o). ๊ฐ ์๋ฆฌ๋ r(4)+w(2)+x(1) ํฉ์ฐ์
๋๋ค.",
|
| 163 |
+
"์ฌ๋ณผ๋ฆญ ํ๊ธฐ: `u+x`(์์ ์์ ์คํ ์ถ๊ฐ), `go-w`(๊ทธ๋ฃนยท๊ธฐํ ์ฐ๊ธฐ ์ ๊ฑฐ), `a=r`(๋ชจ๋ ์ฝ๊ธฐ๋ง).",
|
| 164 |
+
"์ํ ํจํด: ํน์ ๊ถํ ๋นํธ๋ฅผ ๋ณด๊ณ 8์ง์ ์ซ์๋ฅผ ๋ง์ถ๊ฑฐ๋, ์๊ตฌ ์กฐ๊ฑด์ ๋ง๋ chmod ๋ช
๋ น์ ๊ณ ๋ฅด๋ ๋ฌธ์ ๊ฐ ์ถ์ ๋ฉ๋๋ค."
|
| 165 |
+
]
|
| 166 |
+
},
|
| 167 |
+
{
|
| 168 |
+
"id": "linux-chown",
|
| 169 |
+
"certification": "LFCS / ๋ฆฌ๋
์ค๋ง์คํฐ",
|
| 170 |
+
"title": "chown โ ์์ ์ยท๊ทธ๋ฃน ๋ณ๊ฒฝ",
|
| 171 |
+
"summary": "ํ์ผยท๋๋ ํฐ๋ฆฌ์ ์์ ์์ ๊ทธ๋ฃน์ ๋ณ๊ฒฝํฉ๋๋ค. `chmod`๋ ๊ถํ ๋นํธ, `chown`์ ์์ ์๋ฅผ ๋ฐ๊พธ๋ ๊ฒ์ผ๋ก ์ญํ ์ด ๋ค๋ฆ
๋๋ค.",
|
| 172 |
+
"example": "sudo chown ubuntu:ubuntu /srv/app\nchown -R www-data:www-data /var/www/html\nchown :developers project/ # ๊ทธ๋ฃน๋ง ๋ณ๊ฒฝ",
|
| 173 |
+
"common_mistake": "`chown user file`์ ์์ ์๋ง, `chown user:group file`์ ์์ ์์ ๊ทธ๋ฃน์ ํจ๊ป ๋ฐ๊ฟ๋๋ค.",
|
| 174 |
+
"keywords": [
|
| 175 |
+
"chown",
|
| 176 |
+
"owner",
|
| 177 |
+
"group",
|
| 178 |
+
"-R",
|
| 179 |
+
"sudo"
|
| 180 |
+
],
|
| 181 |
+
"source_id": "ubuntu-user-management",
|
| 182 |
+
"details": [
|
| 183 |
+
"`chown ์ฌ์ฉ์:๊ทธ๋ฃน ํ์ผ` ํ์. `:๊ทธ๋ฃน`๋ง ์ฐ๋ฉด ๊ทธ๋ฃน๋ง ๋ณ๊ฒฝ. `-R`์ ๋๋ ํฐ๋ฆฌ๋ฅผ ์ฌ๊ท์ ์ผ๋ก ๋ณ๊ฒฝํฉ๋๋ค.",
|
| 184 |
+
"์น ์๋ฒ ์ค์ ์์ `/var/www/html`์ ์์ ์๋ฅผ `www-data`๋ก ๋ณ๊ฒฝํ๋ ํจํด์ด ์์ฃผ ๋ฑ์ฅํฉ๋๋ค.",
|
| 185 |
+
"์ํ ํจํด: `chown`๊ณผ `chmod`๋ฅผ ์กฐํฉํด ํน์ ์ฌ์ฉ์๋ง ์ ๊ทผํ๋๋ก ์ค์ ํ๋ ์ค์ต ๋ฌธ์ ์ ์ถ์ ๋ฉ๋๋ค."
|
| 186 |
+
]
|
| 187 |
+
},
|
| 188 |
+
{
|
| 189 |
+
"id": "linux-umask",
|
| 190 |
+
"certification": "LFCS / ๋ฆฌ๋
์ค๋ง์คํฐ",
|
| 191 |
+
"title": "umask โ ๊ธฐ๋ณธ ๊ถํ ๋ง์คํฌ",
|
| 192 |
+
"summary": "์๋ก ์์ฑ๋๋ ํ์ผยท๋๋ ํฐ๋ฆฌ์ ๊ธฐ๋ณธ ๊ถํ์์ ์ฐจ๊ฐํ ๋นํธ๋ฅผ ์ง์ ํฉ๋๋ค. ๊ธฐ๋ณธ umask 022๋ ํ์ผ 644, ๋๋ ํฐ๋ฆฌ 755๋ฅผ ๋ง๋ค์ด๋
๋๋ค.",
|
| 193 |
+
"example": "umask # ํ์ฌ ๋ง์คํฌ ํ์ธ\numask 027 # ํ์ผ 640, ๋๋ ํฐ๋ฆฌ 750\numask -S # ์ฌ๋ณผ๋ฆญ ํ๊ธฐ๋ก ํ์ธ",
|
| 194 |
+
"common_mistake": "umask ๊ฐ์ ๊ถํ์ด ์๋๋ผ '๋นผ๋ ๊ฐ'์
๋๋ค. umask 022 โ ํ์ผ ๊ธฐ๋ณธ 666-022=644, ๋๋ ํฐ๋ฆฌ 777-022=755.",
|
| 195 |
+
"keywords": [
|
| 196 |
+
"umask",
|
| 197 |
+
"default permissions",
|
| 198 |
+
"mask",
|
| 199 |
+
"022"
|
| 200 |
+
],
|
| 201 |
+
"source_id": "ubuntu-server-docs",
|
| 202 |
+
"details": [
|
| 203 |
+
"ํ์ผ ๊ธฐ๋ณธ ์ต๋ ๊ถํ์ 666, ๋๋ ํฐ๋ฆฌ๋ 777. ์ฌ๊ธฐ์ umask๋ฅผ ๋นผ๋ฉด ์ค์ ์์ฑ ๊ถํ์ด ๋ฉ๋๋ค.",
|
| 204 |
+
"์ฌ์ฉ์๋ณ umask๋ `~/.bashrc` ๋๋ `/etc/profile`์์ ์ค์ ํฉ๋๋ค. ์์คํ
์ ์ฒด๋ `/etc/login.defs`.",
|
| 205 |
+
"์ํ ํจํด: umask ๊ฐ์ ์ฃผ๊ณ ํ์ผ ์์ฑ ์ ๊ถํ์ด ๋ฌด์์ธ์ง, ๋๋ ์ํ๋ ๊ธฐ๋ณธ ๊ถํ์ ๋ง๋ค๊ธฐ ์ํ umask ๊ฐ์ ๋ฌป์ต๋๋ค."
|
| 206 |
+
]
|
| 207 |
+
},
|
| 208 |
+
{
|
| 209 |
+
"id": "linux-find",
|
| 210 |
+
"certification": "LFCS / ๋ฆฌ๋
์ค๋ง์คํฐ",
|
| 211 |
+
"title": "find โ ํ์ผ ๊ฒ์",
|
| 212 |
+
"summary": "์ด๋ฆ, ํฌ๊ธฐ, ์์ ์๊ฐ, ๊ถํ, ์์ ์ ๋ฑ ๋ค์ํ ์กฐ๊ฑด์ผ๋ก ํ์ผ์์คํ
์์ ํ์ผ์ ์ฐพ์ต๋๋ค.",
|
| 213 |
+
"example": "find /etc -name '*.conf'\nfind /var/log -mtime -1 # ํ๋ฃจ ์ด๋ด ์์ \nfind / -perm /4000 -type f # SUID ํ์ผ",
|
| 214 |
+
"common_mistake": "`find -name '*.conf'`์์ ๋ฐ์ดํ๋ฅผ ๋น ๋จ๋ฆฌ๋ฉด ์์ด glob์ ๋จผ์ ํด์ํด ์์์น ๋ชปํ ๊ฒฐ๊ณผ๊ฐ ๋ฉ๋๋ค.",
|
| 215 |
+
"keywords": [
|
| 216 |
+
"find",
|
| 217 |
+
"-name",
|
| 218 |
+
"-type",
|
| 219 |
+
"-mtime",
|
| 220 |
+
"-perm",
|
| 221 |
+
"-exec"
|
| 222 |
+
],
|
| 223 |
+
"source_id": "linux-bash-manual",
|
| 224 |
+
"details": [
|
| 225 |
+
"์ฃผ์ ์กฐ๊ฑด: `-name`(์ด๋ฆ), `-type f/d`(ํ์ผ/๋๋ ํฐ๋ฆฌ), `-size +10M`(ํฌ๊ธฐ), `-mtime -7`(7์ผ ์ด๋ด ์์ ), `-user`(์์ ์).",
|
| 226 |
+
"`-exec ๋ช
๋ น {} \\;`๋ก ์ฐพ์ ํ์ผ์ ๋ช
๋ น์ ์คํํฉ๋๋ค: `find . -name '*.tmp' -exec rm {} \\;`.",
|
| 227 |
+
"์ํ ํจํด: SUID/SGID ํ์ผ ์ฐพ๊ธฐ(`-perm /4000`), ํน์ ์ฌ์ฉ์ ํ์ผ ์ฐพ๊ธฐ(`-user`), ์ค๋๋ ํ์ผ ์ ๋ฆฌ๊ฐ ์์ฃผ ์ถ์ ๋ฉ๋๋ค."
|
| 228 |
+
]
|
| 229 |
+
},
|
| 230 |
+
{
|
| 231 |
+
"id": "linux-pipe-redirect",
|
| 232 |
+
"certification": "LFCS / ๋ฆฌ๋
์ค๋ง์คํฐ",
|
| 233 |
+
"title": "ํ์ดํ์ ๋ฆฌ๋ค์ด๋ ์
",
|
| 234 |
+
"summary": "ํ์ดํ(`|`)๋ ๋ช
๋ น์ ์ถ๋ ฅ์ ๋ค์ ๋ช
๋ น์ ์
๋ ฅ์ผ๋ก ์ฐ๊ฒฐํ๊ณ , ๋ฆฌ๋ค์ด๋ ์
(`>`, `>>`, `<`)์ ์ถ๋ ฅยท์
๋ ฅ์ ํ์ผ๋ก ์ฐ๊ฒฐํฉ๋๋ค.",
|
| 235 |
+
"example": "cat /etc/passwd | grep root\nls -la > filelist.txt\necho 'append' >> log.txt\ncommand 2>&1 | tee output.log",
|
| 236 |
+
"common_mistake": "`>`๋ ํ์ผ์ ๋ฎ์ด์ฐ๊ณ , `>>`๋ ์ถ๊ฐํฉ๋๋ค. ์ค์ํ ํ์ผ์ ์ค์๋ก `>`๋ฅผ ์ฐ๋ฉด ๋ด์ฉ์ด ์ฌ๋ผ์ง๋๋ค.",
|
| 237 |
+
"keywords": [
|
| 238 |
+
"pipe",
|
| 239 |
+
"redirect",
|
| 240 |
+
">",
|
| 241 |
+
">>",
|
| 242 |
+
"2>&1",
|
| 243 |
+
"stdin",
|
| 244 |
+
"stdout"
|
| 245 |
+
],
|
| 246 |
+
"source_id": "linux-bash-cd",
|
| 247 |
+
"details": [
|
| 248 |
+
"stdout ๋ฆฌ๋ค์ด๋ ์
: `>` ๋ฎ์ด์ฐ๊ธฐ, `>>` ์ถ๊ฐ. stderr ๋ฆฌ๋ค์ด๋ ์
: `2>`. `2>&1`์ stderr๋ฅผ stdout์ผ๋ก ํฉ์นฉ๋๋ค.",
|
| 249 |
+
"`tee` ๋ช
๋ น์ stdout์ ํ๋ฉด๊ณผ ํ์ผ์ ๋์์ ์ถ๋ ฅํฉ๋๋ค: `command | tee log.txt`.",
|
| 250 |
+
"์ํ ํจํด: ๋ช
๋ น ์ถ๋ ฅ์ ํ์ผ์ ์ ์ฅํ๊ฑฐ๋, ์๋ฌ ๋ฉ์์ง๋ฅผ ๋ก๊ทธ์ ๊ธฐ๋กํ๋ ๋ณตํฉ ํ์ดํ๋ผ์ธ ๋ฌธ์ ๊ฐ ์ถ์ ๋ฉ๋๋ค."
|
| 251 |
+
]
|
| 252 |
+
},
|
| 253 |
+
{
|
| 254 |
+
"id": "linux-tar",
|
| 255 |
+
"certification": "LFCS / ๋ฆฌ๋
์ค๋ง์คํฐ",
|
| 256 |
+
"title": "tar โ ์์นด์ด๋ธ์ ์์ถ",
|
| 257 |
+
"summary": "์ฌ๋ฌ ํ์ผ์ ํ๋์ ์์นด์ด๋ธ๋ก ๋ฌถ๊ฑฐ๋ ์์ถํฉ๋๋ค. `-c`(์์ฑ), `-x`(ํด์ ), `-z`(gzip), `-j`(bzip2)๋ฅผ ์กฐํฉํด ์๋๋ค.",
|
| 258 |
+
"example": "tar czf backup.tar.gz /etc\ntar xzf backup.tar.gz -C /tmp\ntar tvf archive.tar.gz # ๋ด์ฉ ๋ชฉ๋ก",
|
| 259 |
+
"common_mistake": "`c`(create)์ `x`(extract)๋ฅผ ํผ๋ํ์ง ๋ง์ธ์. `-C`๋ก ์์ถ ํด์ ์์น๋ฅผ ์ง์ ํ์ง ์์ผ๋ฉด ํ์ฌ ์์น์ ํ๋ฆฝ๋๋ค.",
|
| 260 |
+
"keywords": [
|
| 261 |
+
"tar",
|
| 262 |
+
"-czf",
|
| 263 |
+
"-xzf",
|
| 264 |
+
"gzip",
|
| 265 |
+
"archive",
|
| 266 |
+
"backup"
|
| 267 |
+
],
|
| 268 |
+
"source_id": "linux-bash-manual",
|
| 269 |
+
"details": [
|
| 270 |
+
"์ต์
์๋ฏธ: `c`=์์ฑ, `x`=ํด์ , `t`=๋ชฉ๋ก, `v`=์์ธ์ถ๋ ฅ, `f`=ํ์ผ์ง์ , `z`=gzip, `j`=bzip2, `J`=xz.",
|
| 271 |
+
"๋ฐฑ์
ํจํด: `tar czf /backup/etc-$(date +%Y%m%d).tar.gz /etc`๋ก ๋ ์ง ํฌํจ ๋ฐฑ์
ํ์ผ ์์ฑ.",
|
| 272 |
+
"์ํ ํจํด: ํน์ ๋๋ ํฐ๋ฆฌ๋ฅผ ์์ถํ๊ฑฐ๋ ์ง์ ์์น์ ํ์ด๋ด๋ ๋ช
๋ น์ ์ง์ ์์ฑํ๋ ๋ฌธ์ ๊ฐ ์ถ์ ๋ฉ๋๋ค."
|
| 273 |
+
]
|
| 274 |
+
},
|
| 275 |
+
{
|
| 276 |
+
"id": "linux-process-ps-kill",
|
| 277 |
+
"certification": "LFCS / ๋ฆฌ๋
์ค๋ง์คํฐ",
|
| 278 |
+
"title": "ps, kill โ ํ๋ก์ธ์ค ํ์ธ๊ณผ ์ข
๋ฃ",
|
| 279 |
+
"summary": "`ps`๋ก ์คํ ์ค์ธ ํ๋ก์ธ์ค๋ฅผ ์กฐํํ๊ณ , `kill`๋ก ๏ฟฝ๏ฟฝ๊ทธ๋์ ๋ณด๋ด ํ๋ก์ธ์ค๋ฅผ ์ข
๋ฃํ๊ฑฐ๋ ์ ์ดํฉ๋๋ค.",
|
| 280 |
+
"example": "ps aux | grep nginx\nkill -15 1234 # SIGTERM (์ ์ ์ข
๋ฃ ์์ฒญ)\nkill -9 1234 # SIGKILL (๊ฐ์ ์ข
๋ฃ)\nkillall nginx # ์ด๋ฆ์ผ๋ก ์ข
๋ฃ",
|
| 281 |
+
"common_mistake": "`kill -9`๋ ํ๋ก์ธ์ค๊ฐ ์ ๋ฆฌ ๊ณผ์ ์์ด ์ฆ์ ์ข
๋ฃ๋ฉ๋๋ค. ๋จผ์ `-15`(SIGTERM)์ ์๋ํ๊ณ , ์๋ต ์์ ๋๋ง `-9`๋ฅผ ์๋๋ค.",
|
| 282 |
+
"keywords": [
|
| 283 |
+
"ps",
|
| 284 |
+
"kill",
|
| 285 |
+
"SIGTERM",
|
| 286 |
+
"SIGKILL",
|
| 287 |
+
"PID",
|
| 288 |
+
"aux"
|
| 289 |
+
],
|
| 290 |
+
"source_id": "linux-bash-manual",
|
| 291 |
+
"details": [
|
| 292 |
+
"`ps aux`: a=๋ชจ๋ ์ฌ์ฉ์, u=์ฌ์ฉ์/CPU/๋ฉ๋ชจ๋ฆฌ ์ ๋ณด, x=ํฐ๋ฏธ๋ ์๋ ํ๋ก์ธ์ค ํฌํจ. PID๊ฐ ๋ ๋ฒ์งธ ์ปฌ๋ผ์
๋๋ค.",
|
| 293 |
+
"์ฃผ์ ์๊ทธ๋: 1(SIGHUP ์ฌ์์), 9(SIGKILL ๊ฐ์ ์ข
๋ฃ), 15(SIGTERM ์ ์์ข
๋ฃ ์์ฒญ), 2(SIGINT Ctrl+C).",
|
| 294 |
+
"์ํ ํจํด: `ps aux | grep ํ๋ก์ธ์ค๋ช
`์ผ๋ก PID๋ฅผ ์ฐพ๊ณ `kill`๋ก ์ข
๋ฃํ๋ ๋ ๋จ๊ณ ํ๋ฆ์ด ์์ฃผ ์ถ์ ๋ฉ๋๋ค."
|
| 295 |
+
]
|
| 296 |
+
},
|
| 297 |
+
{
|
| 298 |
+
"id": "linux-systemctl",
|
| 299 |
+
"certification": "LFCS / ๋ฆฌ๋
์ค๋ง์คํฐ",
|
| 300 |
+
"title": "systemctl โ ์๋น์ค ๊ด๋ฆฌ",
|
| 301 |
+
"summary": "systemd ๊ธฐ๋ฐ ์๋น์ค๋ฅผ ์์ยท์ค์งยท์ฌ์์ํ๊ณ , ๋ถํ
์ ์๋ ์์ ์ฌ๋ถ๋ฅผ ์ ์ดํฉ๋๋ค. Ubuntu 16.04 ์ดํ ํ์ค์
๋๋ค.",
|
| 302 |
+
"example": "systemctl start nginx\nsystemctl enable --now ssh # ์ฆ์ ์์ + ๋ถํ
์๋ ์์\nsystemctl status nginx\nsystemctl list-units --type=service",
|
| 303 |
+
"common_mistake": "`enable`์ ๋ถํ
์๋ ์์ ์ค์ , `start`๋ ์ง๊ธ ๋น์ฅ ์์. ๋ ๋ค ํ๋ ค๋ฉด `enable --now`๋ฅผ ์๋๋ค.",
|
| 304 |
+
"keywords": [
|
| 305 |
+
"systemctl",
|
| 306 |
+
"enable",
|
| 307 |
+
"disable",
|
| 308 |
+
"start",
|
| 309 |
+
"stop",
|
| 310 |
+
"status",
|
| 311 |
+
"systemd"
|
| 312 |
+
],
|
| 313 |
+
"source_id": "linux-systemd-systemctl",
|
| 314 |
+
"details": [
|
| 315 |
+
"์ฃผ์ ์๋ธ์ปค๋งจ๋: `start/stop/restart/reload`(์คํ ์ ์ด), `enable/disable`(๋ถํ
์๋ ์์), `status`(์ํ ํ์ธ), `is-active/is-enabled`(์กฐ๊ฑด ํ์ธ).",
|
| 316 |
+
"`systemctl status ์๋น์ค`๋ ํ์ฌ ์ํ, ์ต๊ทผ ๋ก๊ทธ, PID, ์คํ ์๊ฐ์ ํจ๊ป ๋ณด์ฌ์ค๋๋ค.",
|
| 317 |
+
"์ํ ํจํด: ํน์ ์๋น์ค๋ฅผ '์ง๊ธ ์์ํ๊ณ ๋ถํ
์๋ ์๋ ์์'ํ๋๋ก ์ค์ ํ๊ฑฐ๋, ์๋น์ค ์ํ๋ฅผ ํ์ธํ๋ ๋ฌธ์ ๊ฐ ์์ฃผ ์ถ์ ๋ฉ๋๋ค."
|
| 318 |
+
]
|
| 319 |
+
},
|
| 320 |
+
{
|
| 321 |
+
"id": "linux-journalctl",
|
| 322 |
+
"certification": "LFCS / ๋ฆฌ๋
์ค๋ง์คํฐ",
|
| 323 |
+
"title": "journalctl โ systemd ๋ก๊ทธ ์กฐํ",
|
| 324 |
+
"summary": "systemd journal์ ๊ธฐ๋ก๋ ์์คํ
๋ก๊ทธ๋ฅผ ์กฐํํฉ๋๋ค. ์๋น์ค๋ณ, ์๊ฐ๋ณ, ์ฐ์ ์์๋ณ ํํฐ๋ง์ด ๊ฐ๋ ฅํฉ๋๋ค.",
|
| 325 |
+
"example": "journalctl -u nginx --since today\njournalctl -p err -n 50\njournalctl -f # ์ค์๊ฐ ์ถ์ \njournalctl --disk-usage",
|
| 326 |
+
"common_mistake": "`journalctl`์ journal์ ์ ์ฅ๋ ๋ก๊ทธ๋ง ๋ด
๋๋ค. `/var/log/` ํ
์คํธ ํ์ผ ๋ก๊ทธ๋ `cat`/`tail`๋ก ํ์ธํฉ๋๋ค.",
|
| 327 |
+
"keywords": [
|
| 328 |
+
"journalctl",
|
| 329 |
+
"-u",
|
| 330 |
+
"-f",
|
| 331 |
+
"--since",
|
| 332 |
+
"-p",
|
| 333 |
+
"systemd",
|
| 334 |
+
"journal"
|
| 335 |
+
],
|
| 336 |
+
"source_id": "linux-systemd-systemctl",
|
| 337 |
+
"details": [
|
| 338 |
+
"์ฃผ์ ์ต์
: `-u ์๋น์ค`(์๋น์ค๋ณ), `-p err`(์๋ฌ ์ด์), `--since '2024-01-01'`(์๊ฐ ๋ฒ์), `-n 100`(์ต๊ทผ 100์ค), `-f`(์ค์๊ฐ).",
|
| 339 |
+
"`journalctl -b`๋ ํ์ฌ ๋ถํ
์ดํ ๋ก๊ทธ, `-b -1`์ ์ด์ ๋ถํ
๋ก๊ทธ. ์ฌ๋ถํ
ํ ์ค๋ฅ ์ถ์ ์ ํ์ฉํฉ๋๋ค.",
|
| 340 |
+
"์ํ ํจํด: ํน์ ์๋น์ค์ ์ค๋ฅ ๋ก๊ทธ๋ฅผ ์ฐพ๊ฑฐ๋, ํน์ ์๊ฐ ์ดํ ๋ก๊ทธ๋ฅผ ํ์ธํ๋ ๋ฌธ์ ๋ก ์ถ์ ๋ฉ๋๋ค."
|
| 341 |
+
]
|
| 342 |
+
},
|
| 343 |
+
{
|
| 344 |
+
"id": "linux-ip-ss",
|
| 345 |
+
"certification": "LFCS / ๋ฆฌ๋
์ค๋ง์คํฐ",
|
| 346 |
+
"title": "ip, ss โ ๋คํธ์ํฌ ์ธํฐํ์ด์ค์ ์์ผ ํ์ธ",
|
| 347 |
+
"summary": "`ip`๋ก ๋คํธ์ํฌ ์ธํฐํ์ด์คยท๋ผ์ฐํ
ยทIP ์ค์ ์ ํ์ธํ๊ณ , `ss`๋ก ํ์ฌ ์ด๋ฆฐ ํฌํธ์ ์ฐ๊ฒฐ ์ํ๋ฅผ ์กฐํํฉ๋๋ค.",
|
| 348 |
+
"example": "ip addr show\nip route show\nss -tlnp # TCP ๋ฆฌ์ค๋ ํฌํธ์ ํ๋ก์ธ์ค\nss -s # ์์ผ ํต๊ณ ์์ฝ",
|
| 349 |
+
"common_mistake": "`ifconfig`์ `netstat`์ ๊ตฌ์ ๋๊ตฌ์
๋๋ค. ํ์ฌ๋ `ip`์ `ss`๊ฐ ํ์ค์ด๋ฉฐ ์ํ์์๋ ์ด์ชฝ์ด ์ถ์ ๋ฉ๋๋ค.",
|
| 350 |
+
"keywords": [
|
| 351 |
+
"ip",
|
| 352 |
+
"ss",
|
| 353 |
+
"addr",
|
| 354 |
+
"route",
|
| 355 |
+
"netstat",
|
| 356 |
+
"socket",
|
| 357 |
+
"-tlnp"
|
| 358 |
+
],
|
| 359 |
+
"source_id": "linux-man7-ip",
|
| 360 |
+
"details": [
|
| 361 |
+
"`ip addr`์ ์ธํฐํ์ด์ค๋ณ IP, `ip route`๋ ๋ผ์ฐํ
ํ
์ด๋ธ, `ip link`๋ ์ธํฐํ์ด์ค ์ํ๋ฅผ ๋ณด์ฌ์ค๋๋ค.",
|
| 362 |
+
"`ss -tlnp`: t=TCP, l=listening, n=์ซ์ํ์, p=ํ๋ก์ธ์ค๋ช
. ์ด๋ค ์๋น์ค๊ฐ ์ด๋ ํฌํธ๋ฅผ ์ด์๋์ง ํ์ธํฉ๋๋ค.",
|
| 363 |
+
"์ํ ํจํด: ํน์ ์๋น์ค๊ฐ ์ฌ๋ฐ๋ฅธ ํฌํธ๋ฅผ ๋ฆฌ์ค๋ํ๋์ง ํ์ธํ๊ฑฐ๋, IP ์ค์ ์ํ๋ฅผ ์กฐํํ๋ ๋ฌธ์ ๊ฐ ์ถ์ ๋ฉ๋๋ค."
|
| 364 |
+
]
|
| 365 |
+
},
|
| 366 |
+
{
|
| 367 |
+
"id": "linux-df-du-mount",
|
| 368 |
+
"certification": "LFCS / ๋ฆฌ๋
์ค๋ง์คํฐ",
|
| 369 |
+
"title": "df, du, mount โ ๋์คํฌ ์ฌ์ฉ๋๊ณผ ๋ง์ดํธ",
|
| 370 |
+
"summary": "`df`๋ ํ์ผ์์คํ
์ ์ฒด ์ฉ๋, `du`๋ ํน์ ๋๋ ํฐ๋ฆฌ ์ฌ์ฉ๋, `mount`๋ ๋ธ๋ก ์ฅ์น๋ฅผ ํ์ผ์์คํ
ํธ๋ฆฌ์ ์ฐ๊ฒฐํฉ๋๋ค.",
|
| 371 |
+
"example": "df -h\ndu -sh /var/log/*\nmount /dev/sdb1 /mnt/data\nfindmnt # ๋ง์ดํธ ํธ๋ฆฌ ํ์ธ",
|
| 372 |
+
"common_mistake": "`df`๋ ํ์ผ์์คํ
์ ์ฒด, `du`๋ ํน์ ๊ฒฝ๋ก์ ์ค์ ์ฌ์ฉ ํฌ๊ธฐ. ๋ ์ซ์๊ฐ ๋ค๋ฅผ ์ ์์ต๋๋ค(์ญ์ ๋์ง๋ง ์ด๋ฆฐ ํ์ผ ๋ฑ).",
|
| 373 |
+
"keywords": [
|
| 374 |
+
"df",
|
| 375 |
+
"du",
|
| 376 |
+
"mount",
|
| 377 |
+
"-h",
|
| 378 |
+
"-sh",
|
| 379 |
+
"filesystem"
|
| 380 |
+
],
|
| 381 |
+
"source_id": "ubuntu-storage",
|
| 382 |
+
"details": [
|
| 383 |
+
"`df -h`๋ ๋ชจ๋ ๋ง์ดํธ ํํฐ์
์ ์ฌ์ฉ๋ฅ ์ ๋ณด์ฌ์ค๋๋ค. ๋์คํฌ ํ ๊ฒฝ๊ณ ์ ๋จผ์ ์คํํ๋ ๋ช
๋ น์
๋๋ค.",
|
| 384 |
+
"`du -sh /๊ฒฝ๋ก/*`๋ก ์ด๋ ํ์ ๋๋ ํฐ๋ฆฌ๊ฐ ๊ณต๊ฐ์ ์ฐจ์งํ๋์ง ์ฐพ์ ์ ์์ต๋๋ค.",
|
| 385 |
+
"์ํ ํจํด: ๋์คํฌ ์ฌ์ฉ๋ฅ ํ์ธ, ์์ ๋ง์ดํธ ๋ช
๋ น ์์ฑ, `findmnt`๋ก ๋ง์ดํธ ์ ๋ณด ํ์ธํ๋ ๋ฌธ์ ๊ฐ ์ถ์ ๋ฉ๋๋ค."
|
| 386 |
+
]
|
| 387 |
+
},
|
| 388 |
+
{
|
| 389 |
+
"id": "linux-useradd",
|
| 390 |
+
"certification": "LFCS / ๋ฆฌ๋
์ค๋ง์คํฐ",
|
| 391 |
+
"title": "useradd โ ์ฌ์ฉ์ ์ถ๊ฐ",
|
| 392 |
+
"summary": "์ ์ฌ์ฉ์ ๊ณ์ ์ ์์ฑํฉ๋๋ค. `-m`์ผ๋ก ํ ๋๋ ํฐ๋ฆฌ ์๋ ์์ฑ, `-s`๋ก ๋ก๊ทธ์ธ ์, `-G`๋ก ์ถ๊ฐ ๊ทธ๋ฃน์ ์ง์ ํฉ๋๋ค.",
|
| 393 |
+
"example": "sudo useradd -m -s /bin/bash -G sudo alice\nuseradd -r -s /usr/sbin/nologin svcuser # ์๋น์ค ๊ณ์ \npasswd alice # ์์ฑ ํ ๋น๋ฐ๋ฒํธ ์ค์ ",
|
| 394 |
+
"common_mistake": "`useradd`๋ง ์ฐ๋ฉด ํ ๋๋ ํฐ๋ฆฌ๊ฐ ์์ฑ๋์ง ์์ต๋๋ค. `-m`์ ๋ฐ๋์ ๋ถ์ด๊ฑฐ๋ `adduser`(๋ํํ)๋ฅผ ์๋๋ค.",
|
| 395 |
+
"keywords": [
|
| 396 |
+
"useradd",
|
| 397 |
+
"-m",
|
| 398 |
+
"-s",
|
| 399 |
+
"-G",
|
| 400 |
+
"adduser",
|
| 401 |
+
"home directory"
|
| 402 |
+
],
|
| 403 |
+
"source_id": "ubuntu-user-management",
|
| 404 |
+
"details": [
|
| 405 |
+
"์ฃผ์ ์ต์
: `-m`(ํ ๋๋ ํฐ๋ฆฌ ์์ฑ), `-d ๊ฒฝ๋ก`(ํ ๊ฒฝ๋ก ์ง์ ), `-s ์`(๋ก๊ทธ์ธ ์), `-G ๊ทธ๋ฃน`(์ถ๊ฐ ๊ทธ๋ฃน), `-r`(์์คํ
๊ณ์ ).",
|
| 406 |
+
"์๋น์ค ๊ณ์ ์ `-r -s /usr/sbin/nologin`์ผ๋ก ์์ฑํด ๋ก๊ทธ์ธ์ ๋ง๊ณ ์์คํ
์๋น์ค ์ ์ฉ์ผ๋ก ์๋๋ค.",
|
| 407 |
+
"์ํ ํจํด: ํน์ ์กฐ๊ฑด(ํ ๋๋ ํฐ๋ฆฌ, ๊ทธ๋ฃน, ์)์ ๋ง์กฑํ๋ ์ฌ์ฉ์๋ฅผ ์์ฑํ๊ณ ๋น๋ฐ๋ฒํธ๋ฅผ ์ค์ ํ๋ ์ค์ต ๋ฌธ์ ๊ฐ ์ถ์ ๋ฉ๋๋ค."
|
| 408 |
+
]
|
| 409 |
+
},
|
| 410 |
+
{
|
| 411 |
+
"id": "linux-usermod",
|
| 412 |
+
"certification": "LFCS / ๋ฆฌ๋
์ค๋ง์คํฐ",
|
| 413 |
+
"title": "usermod โ ์ฌ์ฉ์ ์ ๋ณด ๋ณ๊ฒฝ",
|
| 414 |
+
"summary": "๊ธฐ์กด ์ฌ์ฉ์ ๊ณ์ ์ ๊ทธ๋ฃน, ์, ํ ๋๋ ํฐ๋ฆฌ, ์ ๊ธ ์ํ๋ฅผ ๋ณ๊ฒฝํฉ๋๋ค.",
|
| 415 |
+
"example": "usermod -aG docker alice # docker ๊ทธ๋ฃน ์ถ๊ฐ\nusermod -s /bin/zsh alice # ์ ๋ณ๊ฒฝ\nusermod -L alice # ๊ณ์ ์ ๊ธ\nusermod -U alice # ์ ๊ธ ํด์ ",
|
| 416 |
+
"common_mistake": "`-G`๋ง ์ฐ๋ฉด ๊ธฐ์กด ๊ทธ๋ฃน์ด ์ฌ๋ผ์ง๋๋ค. ๊ทธ๋ฃน์ ์ถ๊ฐํ ๋๋ ๋ฐ๋์ `-aG`(append)๋ฅผ ์จ์ผ ํฉ๋๋ค.",
|
| 417 |
+
"keywords": [
|
| 418 |
+
"usermod",
|
| 419 |
+
"-aG",
|
| 420 |
+
"-L",
|
| 421 |
+
"-U",
|
| 422 |
+
"-s",
|
| 423 |
+
"group",
|
| 424 |
+
"lock"
|
| 425 |
+
],
|
| 426 |
+
"source_id": "ubuntu-user-management",
|
| 427 |
+
"details": [
|
| 428 |
+
"`-aG ๊ทธ๋ฃน`์ ๊ธฐ์กด ๊ทธ๋ฃน์ ์ ์งํ๋ฉด์ ๊ทธ๋ฃน์ ์ถ๊ฐ. ๊ทธ๋ฃน ๋ณ๊ฒฝ ํ ์ฌ๋ก๊ทธ์ธํด์ผ ์ ์ฉ๋ฉ๋๋ค.",
|
| 429 |
+
"`-L`(lock) / `-U`(unlock)๋ก ๋น๋ฐ๋ฒํธ ์์ `!`๋ฅผ ๋ถ์ฌ ๋ก๊ทธ์ธ์ ์ฐจ๋จํ๊ฑฐ๋ ํด์ ํฉ๋๋ค.",
|
| 430 |
+
"์ํ ํจํด: ์ฌ์ฉ์๋ฅผ ํน์ ๊ทธ๋ฃน์ ์ถ๊ฐํ๊ฑฐ๋ ๊ณ์ ์ ์ ๊ธํ๋ ๋ช
๋ น์ ์์ฑํ๋ ๋ฌธ์ ๊ฐ ์ถ์ ๋ฉ๋๋ค."
|
| 431 |
+
]
|
| 432 |
+
},
|
| 433 |
+
{
|
| 434 |
+
"id": "linux-passwd",
|
| 435 |
+
"certification": "LFCS / ๋ฆฌ๋
์ค๋ง์คํฐ",
|
| 436 |
+
"title": "passwd โ ๋น๋ฐ๋ฒํธ์ ๊ณ์ ์ ๊ธ",
|
| 437 |
+
"summary": "์ฌ์ฉ์ ๋น๋ฐ๋ฒํธ๋ฅผ ๋ณ๊ฒฝํ๊ฑฐ๋ ๊ณ์ ๋ง๋ฃยท์ ๊ธ์ ์ค์ ํฉ๋๋ค. root๋ ๋ค๋ฅธ ์ฌ์ฉ์์ ๋น๋ฐ๋ฒํธ๋ ๋ฐ๊ฟ ์ ์์ต๋๋ค.",
|
| 438 |
+
"example": "passwd # ํ์ฌ ์ฌ์ฉ์ ๋น๋ฐ๋ฒํธ ๋ณ๊ฒฝ\nsudo passwd alice # alice ๋น๋ฐ๋ฒํธ ๋ณ๊ฒฝ\npasswd -l alice # ๊ณ์ ์ ๊ธ\nchage -l alice # ๋ง๋ฃ ์ ๋ณด ํ์ธ",
|
| 439 |
+
"common_mistake": "`passwd -l`๋ก ์ ๊ทผ ๊ณ์ ๋ SSH ํค ์ธ์ฆ์ผ๋ก๋ ์ ์ ๊ฐ๋ฅํฉ๋๋ค. ์์ ์ฐจ๋จ์ `/etc/shadow`์ ์์ nologin์ผ๋ก ๋ณ๊ฒฝํด์ผ ํฉ๋๋ค.",
|
| 440 |
+
"keywords": [
|
| 441 |
+
"passwd",
|
| 442 |
+
"-l",
|
| 443 |
+
"-u",
|
| 444 |
+
"-e",
|
| 445 |
+
"chage",
|
| 446 |
+
"password",
|
| 447 |
+
"lock"
|
| 448 |
+
],
|
| 449 |
+
"source_id": "ubuntu-user-management",
|
| 450 |
+
"details": [
|
| 451 |
+
"`passwd -l`์ `/etc/shadow`์ ๋น๋ฐ๋ฒํธ ์์ `!`๋ฅผ ๋ถ์ฌ ๋น๋ฐ๋ฒํธ ๋ก๊ทธ์ธ์ ์ฐจ๋จํฉ๋๋ค.",
|
| 452 |
+
"`chage -M 90 user`๋ก ๋น๋ฐ๋ฒํธ ์ต๋ ์ฌ์ฉ ๊ธฐ๊ฐ, `chage -E ๋ ์ง`๋ก ๊ณ์ ๋ง๋ฃ์ผ์ ์ค์ ํฉ๋๋ค.",
|
| 453 |
+
"์ํ ํจํด: ์ฌ์ฉ์ ๋น๋ฐ๋ฒํธ ๋ณ๊ฒฝ, ๊ณ์ ์ ๊ธ/ํด์ , ๋น๋ฐ๋ฒํธ ๋ง๋ฃ ์ ์ฑ
์ค์ ๋ช
๋ น์ ์์ฑํ๋ ๋ฌธ์ ๊ฐ ์ถ์ ๋ฉ๋๋ค."
|
| 454 |
+
]
|
| 455 |
+
},
|
| 456 |
+
{
|
| 457 |
+
"id": "linux-groups-id",
|
| 458 |
+
"certification": "LFCS / ๋ฆฌ๋
์ค๋ง์คํฐ",
|
| 459 |
+
"title": "id, groups โ ์ฌ์ฉ์ยท๊ทธ๋ฃน ํ์ธ",
|
| 460 |
+
"summary": "`id`๋ ํ์ฌ ์ฌ์ฉ์์ UID, GID, ์์ ๊ทธ๋ฃน์ ๋ณด์ฌ์ฃผ๊ณ , `groups`๋ ๊ทธ๋ฃน ๋ชฉ๋ก๋ง ์ถ๋ ฅํฉ๋๋ค.",
|
| 461 |
+
"example": "id\n# uid=1000(ubuntu) gid=1000(ubuntu) groups=1000(ubuntu),4(adm),27(sudo)\nid alice\ngroups alice",
|
| 462 |
+
"common_mistake": "`usermod -aG`๋ก ๊ทธ๋ฃน์ ์ถ๊ฐํ ๋ค `id`์ ๋ฐ์๋๋ ค๋ฉด ์ฌ๋ก๊ทธ์ธ์ด ํ์ํฉ๋๋ค. `newgrp ๊ทธ๋ฃน๋ช
`์ผ๋ก ์ฆ์ ์ ์ฉํ ์ ์์ต๋๋ค.",
|
| 463 |
+
"keywords": [
|
| 464 |
+
"id",
|
| 465 |
+
"groups",
|
| 466 |
+
"UID",
|
| 467 |
+
"GID",
|
| 468 |
+
"whoami"
|
| 469 |
+
],
|
| 470 |
+
"source_id": "ubuntu-user-management",
|
| 471 |
+
"details": [
|
| 472 |
+
"`id` ์ถ๋ ฅ์์ uid(์ฌ์ฉ์ ๋ฒํธ), gid(๊ธฐ๋ณธ ๊ทธ๋ฃน), groups(๋ชจ๋ ์์ ๊ทธ๋ฃน)๋ฅผ ํ์ธํ ์ ์์ต๋๋ค.",
|
| 473 |
+
"root์ uid์ gid๋ 0์
๋๋ค. `id -u`๋ก ์ซ์๋ง, `id -un`์ผ๋ก ์ด๋ฆ๋ง ์ถ๋ ฅํ ์ ์์ต๋๋ค.",
|
| 474 |
+
"์ํ ํจํด: ์ฌ์ฉ์๊ฐ ํน์ ๊ทธ๋ฃน์ ์ํด ์๋์ง ํ์ธํ๊ฑฐ๋, uid/gid๋ก ์ฌ์ฉ์ ์ ๋ณด๋ฅผ ์กฐํํ๋ ๋ฌธ์ ๊ฐ ์ถ์ ๋ฉ๋๋ค."
|
| 475 |
+
]
|
| 476 |
+
},
|
| 477 |
+
{
|
| 478 |
+
"id": "linux-sudoers",
|
| 479 |
+
"certification": "LFCS / ๋ฆฌ๋
์ค๋ง์คํฐ",
|
| 480 |
+
"title": "sudo์ sudoers โ ๊ถํ ์์",
|
| 481 |
+
"summary": "์ผ๋ฐ ์ฌ์ฉ์๊ฐ ํน์ ๋ช
๋ น์ root ๊ถํ์ผ๋ก ์คํํ ์ ์๋๋ก ํ์ฉํฉ๋๋ค. `/etc/sudoers`๋ ๋ฐ๋์ `visudo`๋ก ํธ์งํฉ๋๋ค.",
|
| 482 |
+
"example": "sudo apt update\nvisudo # /etc/sudoers ์์ ํธ์ง\n# /etc/sudoers.d/alice ๋ด์ฉ:\nalice ALL=(ALL) NOPASSWD: /usr/bin/systemctl",
|
| 483 |
+
"common_mistake": "`/etc/sudoers`๋ฅผ ์ง์ vi๋ก ์ด์ด ์์ ํ๋ฉด ๋ฌธ๋ฒ ์ค๋ฅ ์ sudo๊ฐ ์์ ํ ์ ๊ธธ ์ ์์ต๋๋ค. ๋ฐ๋์ `visudo`๋ฅผ ์ฌ์ฉํ์ธ์.",
|
| 484 |
+
"keywords": [
|
| 485 |
+
"sudo",
|
| 486 |
+
"sudoers",
|
| 487 |
+
"visudo",
|
| 488 |
+
"NOPASSWD",
|
| 489 |
+
"ALL"
|
| 490 |
+
],
|
| 491 |
+
"source_id": "ubuntu-user-management",
|
| 492 |
+
"details": [
|
| 493 |
+
"`sudo` ๊ทธ๋ฃน ๋๋ wheel ๊ทธ๋ฃน์ ์ํ ์ฌ์ฉ์๋ ๊ธฐ๋ณธ์ผ๋ก sudo ์ฌ์ฉ ๊ฐ๋ฅํฉ๋๋ค: `usermod -aG sudo alice`.",
|
| 494 |
+
"`/etc/sudoers.d/` ๋๋ ํฐ๋ฆฌ์ ๊ฐ๋ณ ํ์ผ์ ๋ง๋ค๋ฉด ๋ฉ์ธ sudoers๋ฅผ ๊ฑด๋๋ฆฌ์ง ์๊ณ ๊ถํ์ ์ถ๊ฐํ ์ ์์ต๋๋ค.",
|
| 495 |
+
"์ํ ํจํด: ํน์ ์ฌ์ฉ์์๊ฒ ํน์ ๋ช
๋ น๋ง sudo ํ์ฉํ๊ฑฐ๋, NOPASSWD ์ค์ ์ ์ถ๊ฐํ๋ ๋ฌธ์ ๊ฐ ์ถ์ ๋ฉ๋๋ค."
|
| 496 |
+
]
|
| 497 |
+
},
|
| 498 |
+
{
|
| 499 |
+
"id": "linux-acl",
|
| 500 |
+
"certification": "LFCS / ๋ฆฌ๋
์ค๋ง์คํฐ",
|
| 501 |
+
"title": "ACL โ ํ์ฅ ์ ๊ทผ ์ ์ด",
|
| 502 |
+
"summary": "๊ธฐ๋ณธ ์ ๋์ค ๊ถํ(์์ ์/๊ทธ๋ฃน/๊ธฐํ)๋ง์ผ๋ก๋ ํํํ ์ ์๋ ์ธ๋ฐํ ๊ถํ์ ํน์ ์ฌ์ฉ์๋ ๊ทธ๋ฃน๋ณ๋ก ์ง์ ํฉ๋๋ค.",
|
| 503 |
+
"example": "getfacl /srv/project\nsetfacl -m u:alice:rwx /srv/project\nsetfacl -m g:dev:r-x /srv/project\nsetfacl -R -m u:bob:r-- /data # ์ฌ๊ท",
|
| 504 |
+
"common_mistake": "ACL์ด ์ค์ ๋ ํ์ผ์ `ls -l`์์ ๊ถํ ๋ค์ `+`๊ฐ ๋ถ์ต๋๋ค. ์ด๊ฒ์ ๋ชจ๋ฅด๋ฉด ๊ถํ ์ค์ ์ด ๋๋์ง ํ์ธํ๊ธฐ ์ด๋ ต์ต๋๋ค.",
|
| 505 |
+
"keywords": [
|
| 506 |
+
"ACL",
|
| 507 |
+
"setfacl",
|
| 508 |
+
"getfacl",
|
| 509 |
+
"-m",
|
| 510 |
+
"-R",
|
| 511 |
+
"access control"
|
| 512 |
+
],
|
| 513 |
+
"source_id": "ubuntu-server-docs",
|
| 514 |
+
"details": [
|
| 515 |
+
"`setfacl -m u:์ฌ์ฉ์:rwx ๊ฒฝ๋ก`๋ก ํน์ ์ฌ์ฉ์์๊ฒ ๊ถํ ์ถ๊ฐ. `getfacl`๋ก ํ์ฌ ACL ํ์ธ.",
|
| 516 |
+
"๊ธฐ๋ณธ ACL(`setfacl -d`)์ ์ค์ ํ๋ฉด ํด๋น ๋๋ ํฐ๋ฆฌ์ ์๋ก ์์ฑ๋๋ ํ์ผ์ ์๋์ผ๋ก ACL์ด ์ ์ฉ๋ฉ๋๋ค.",
|
| 517 |
+
"์ํ ํจํด: ์ฌ๋ฌ ์ฌ์ฉ์์๊ฒ ๋ค๋ฅธ ๊ถํ์ ์ฃผ๋ ์๋๋ฆฌ์ค์์ chmod ๋์ setfacl์ ์ฌ์ฉํ๋ ๋ฌธ์ ๊ฐ ์ถ์ ๋ฉ๋๋ค."
|
| 518 |
+
]
|
| 519 |
+
},
|
| 520 |
+
{
|
| 521 |
+
"id": "linux-special-perms",
|
| 522 |
+
"certification": "LFCS / ๋ฆฌ๋
์ค๋ง์คํฐ",
|
| 523 |
+
"title": "ํน์ ๊ถํ โ SUID, SGID, Sticky Bit",
|
| 524 |
+
"summary": "SUID(4)๋ ํ์ผ ์์ ์ ๊ถํ์ผ๋ก ์คํ, SGID(2)๋ ๊ทธ๋ฃน ๊ถํ ์์, Sticky Bit(1)์ ๋ณธ์ธ ํ์ผ๋ง ์ญ์ ๊ฐ๋ฅํ๊ฒ ์ ํํฉ๋๋ค.",
|
| 525 |
+
"example": "chmod u+s /usr/bin/passwd # SUID\nchmod g+s /srv/shared # SGID (๊ณต์ ๋๋ ํฐ๋ฆฌ)\nchmod +t /tmp # Sticky bit\nls -la /tmp # drwxrwxrwt ์์ t ํ์ธ",
|
| 526 |
+
"common_mistake": "SUID๊ฐ ๋๋ ํฐ๋ฆฌ์ ๋ถ์ผ๋ฉด ์๋ฏธ๊ฐ ๋ค๋ฆ
๋๋ค. SGID๊ฐ ๋๋ ํฐ๋ฆฌ์ ๋ถ์ผ๋ฉด ์์ฑ๋๋ ํ์ผ์ด ๋ถ๋ชจ ๊ทธ๋ฃน์ ์์ํฉ๋๋ค.",
|
| 527 |
+
"keywords": [
|
| 528 |
+
"SUID",
|
| 529 |
+
"SGID",
|
| 530 |
+
"sticky bit",
|
| 531 |
+
"chmod 4755",
|
| 532 |
+
"chmod 1777"
|
| 533 |
+
],
|
| 534 |
+
"source_id": "ubuntu-server-docs",
|
| 535 |
+
"details": [
|
| 536 |
+
"SUID ์ค์ ๋ ํ์ผ์ ์คํํ๋ฉด ์คํํ ์ฌ๋์ด ์๋๋ผ ํ์ผ ์์ ์ ๊ถํ์ผ๋ก ์คํ๋ฉ๋๋ค. `/usr/bin/passwd`๊ฐ ๋ํ ์์
๋๋ค.",
|
| 537 |
+
"SGID๋ฅผ ๊ณต์ ๋๋ ํฐ๋ฆฌ์ ์ค์ ํ๋ฉด ๊ทธ ์์ ๋ง๋ ํ์ผ๋ค์ด ๋๋ ํฐ๋ฆฌ ๊ทธ๋ฃน์ ์๋์ผ๋ก ์์ํด ํ์
์ ์ ์ฉํฉ๋๋ค.",
|
| 538 |
+
"์ํ ํจํด: `ls -l`์์ `s`, `S`, `t`, `T` ํ์๋ฅผ ๋ณด๊ณ ์ด๋ค ํน์ ๊ถํ์ธ์ง, ๋๋ 8์ง์ 4์๋ฆฌ ํ๊ธฐ๋ฅผ ํด์ํ๋ ๋ฌธ์ ๊ฐ ์ถ์ ๋ฉ๋๋ค."
|
| 539 |
+
]
|
| 540 |
+
},
|
| 541 |
+
{
|
| 542 |
+
"id": "linux-ssh",
|
| 543 |
+
"certification": "LFCS / ๋ฆฌ๋
์ค๋ง์คํฐ",
|
| 544 |
+
"title": "SSH โ ์๊ฒฉ ์ ์",
|
| 545 |
+
"summary": "SSH(Secure Shell)๋ก ์๊ฒฉ ์๋ฒ์ ์ํธํ๋ ์ฐ๊ฒฐ์ ๋งบ์ต๋๋ค. ์ค์ ํ์ผ์ ์๋ฒ ์ชฝ `/etc/ssh/sshd_config`, ํด๋ผ์ด์ธํธ ์ชฝ `~/.ssh/config`์
๋๋ค.",
|
| 546 |
+
"example": "ssh alice@192.168.1.10\nssh -p 2222 user@server\nssh -i ~/.ssh/mykey.pem ubuntu@host\nsystemctl restart sshd # ์ค์ ๋ณ๊ฒฝ ํ ์ฌ์์",
|
| 547 |
+
"common_mistake": "`sshd_config` ๋ณ๊ฒฝ ํ `systemctl reload sshd`๋ฅผ ํด์ผ ์ ์ฉ๋ฉ๋๋ค. ์์ ์ `sshd -t`๋ก ๋ฌธ๋ฒ ๊ฒ์ฌ๋ฅผ ๋จผ์ ํ์ธ์.",
|
| 548 |
+
"keywords": [
|
| 549 |
+
"ssh",
|
| 550 |
+
"sshd",
|
| 551 |
+
"sshd_config",
|
| 552 |
+
"-p",
|
| 553 |
+
"-i",
|
| 554 |
+
"PermitRootLogin"
|
| 555 |
+
],
|
| 556 |
+
"source_id": "ubuntu-networking",
|
| 557 |
+
"details": [
|
| 558 |
+
"`sshd_config` ์ฃผ์ ์ค์ : `Port`(ํฌํธ ๋ณ๊ฒฝ), `PermitRootLogin no`(root ์ง์ ์ ์ ์ฐจ๋จ), `PasswordAuthentication no`(ํค ์ธ์ฆ๋ง ํ์ฉ).",
|
| 559 |
+
"`~/.ssh/config`์ `Host`, `HostName`, `User`, `IdentityFile`์ ์ ์ํ๋ฉด `ssh ๋ณ์นญ`์ผ๋ก ๊ฐ๋จํ ์ ์ํ ์ ์์ต๋๋ค.",
|
| 560 |
+
"์ํ ํจํด: root ๋ก๊ทธ์ธ ์ฐจ๋จ, ํฌํธ ๋ณ๊ฒฝ, ํค ์ธ์ฆ ๊ฐ์ ๋ฑ sshd_config ๋ณด์ ์ค์ ์ ๋ณ๊ฒฝํ๋ ๋ฌธ์ ๊ฐ ์์ฃผ ์ถ์ ๋ฉ๋๋ค."
|
| 561 |
+
]
|
| 562 |
+
},
|
| 563 |
+
{
|
| 564 |
+
"id": "linux-ssh-key",
|
| 565 |
+
"certification": "LFCS / ๋ฆฌ๋
์ค๋ง์คํฐ",
|
| 566 |
+
"title": "SSH ํค ์ธ์ฆ",
|
| 567 |
+
"summary": "๋น๋ฐ๋ฒํธ ์์ด ๊ณต๊ฐํค/๊ฐ์ธํค ์์ผ๋ก SSH ์ ์ํฉ๋๋ค. ๊ฐ์ธํค๋ ํด๋ผ์ด์ธํธ์, ๊ณต๊ฐํค๋ ์๋ฒ์ `~/.ssh/authorized_keys`์ ๋ฑ๋กํฉ๋๋ค.",
|
| 568 |
+
"example": "ssh-keygen -t ed25519 -C 'work key'\nssh-copy-id alice@server # ๊ณต๊ฐํค ์๋ ๋ณต์ฌ\ncat ~/.ssh/id_ed25519.pub # ๊ณต๊ฐํค ํ์ธ",
|
| 569 |
+
"common_mistake": "`~/.ssh/` ๋๋ ํฐ๋ฆฌ๋ 700, `authorized_keys`๋ 600 ๊ถํ์ด์ด์ผ ํฉ๋๋ค. ๊ถํ์ด ๋๋ฌด ์ด๋ ค ์์ผ๋ฉด SSH๊ฐ ํค๋ฅผ ๋ฌด์ํฉ๋๋ค.",
|
| 570 |
+
"keywords": [
|
| 571 |
+
"ssh-keygen",
|
| 572 |
+
"authorized_keys",
|
| 573 |
+
"ed25519",
|
| 574 |
+
"public key",
|
| 575 |
+
"private key"
|
| 576 |
+
],
|
| 577 |
+
"source_id": "ubuntu-networking",
|
| 578 |
+
"details": [
|
| 579 |
+
"`ssh-keygen -t ed25519`๋ก ์ต์ ์๊ณ ๋ฆฌ์ฆ ํค ์์ฑ. ์์ฑ๋ ๊ณต๊ฐํค(`.pub`)๋ฅผ ์๋ฒ `~/.ssh/authorized_keys`์ ์ถ๊ฐํฉ๋๋ค.",
|
| 580 |
+
"๋๋ ํฐ๋ฆฌ/ํ์ผ ๊ถํ: `~/.ssh`=700, `authorized_keys`=600, ๊ฐ์ธํค=600. ์ด๋ฅผ ๋ฒ์ด๋๋ฉด ์ ์ ๊ฑฐ๋ถ๋ฉ๋๋ค.",
|
| 581 |
+
"์ํ ํจํด: ํค ์์ฑ, ๊ณต๊ฐํค ๋ฐฐํฌ, authorized_keys ๊ถํ ์ค์ ๊น์ง ์ด์ด์ง๋ ์ค์ต ๋ฌธ์ ๊ฐ ์ถ์ ๋ฉ๋๋ค."
|
| 582 |
+
]
|
| 583 |
+
},
|
| 584 |
+
{
|
| 585 |
+
"id": "linux-hostname-hosts",
|
| 586 |
+
"certification": "LFCS / ๋ฆฌ๋
์ค๋ง์คํฐ",
|
| 587 |
+
"title": "hostname๊ณผ /etc/hosts",
|
| 588 |
+
"summary": "`hostname`์ผ๋ก ํ์ฌ ํธ์คํธ๋ช
์ ํ์ธํ๊ณ , `/etc/hosts`๋ก DNS ์์ด IP-์ด๋ฆ ๋งคํ์ ์ค์ ํฉ๋๋ค.",
|
| 589 |
+
"example": "hostname\nhostnamectl set-hostname webserver01\ncat /etc/hosts\necho '192.168.1.10 db.internal' >> /etc/hosts",
|
| 590 |
+
"common_mistake": "`hostname ์ด๋ฆ`์ ์์ ๋ณ๊ฒฝ์
๋๋ค. ์ฌ๋ถํ
ํ์๋ ์ ์งํ๋ ค๋ฉด `hostnamectl set-hostname`์ ์ฌ์ฉํ์ธ์.",
|
| 591 |
+
"keywords": [
|
| 592 |
+
"hostname",
|
| 593 |
+
"hostnamectl",
|
| 594 |
+
"/etc/hosts",
|
| 595 |
+
"FQDN"
|
| 596 |
+
],
|
| 597 |
+
"source_id": "ubuntu-networking",
|
| 598 |
+
"details": [
|
| 599 |
+
"`hostnamectl set-hostname ์ด๋ฆ`์ `/etc/hostname`์ ์์ ํด ์๊ตฌ ๋ณ๊ฒฝํฉ๋๋ค. `hostnamectl status`๋ก ํ์ฌ ์ํ๋ฅผ ํ์ธํฉ๋๋ค.",
|
| 600 |
+
"`/etc/hosts`๋ DNS๋ณด๋ค ๋จผ์ ์กฐํ๋ฉ๋๋ค. ๋ด๋ถ๋ง ์๋ฒ ์ด๋ฆ ๋งคํ์ด๋ DNS ์ฐจ๋จ ํ
์คํธ์ ํ์ฉํฉ๋๋ค.",
|
| 601 |
+
"์ํ ํจํด: ์๋ฒ์ ํธ์คํธ๋ช
์ ์๊ตฌ ๋ณ๊ฒฝํ๊ฑฐ๋, /etc/hosts์ ํญ๋ชฉ์ ์ถ๊ฐํ๋ ๋ช
๋ น์ ์์ฑํ๋ ๋ฌธ์ ๊ฐ ์ถ์ ๋ฉ๋๋ค."
|
| 602 |
+
]
|
| 603 |
+
},
|
| 604 |
+
{
|
| 605 |
+
"id": "linux-dns-resolve",
|
| 606 |
+
"certification": "LFCS / ๋ฆฌ๋
์ค๋ง์คํฐ",
|
| 607 |
+
"title": "DNS ์กฐํ โ dig, nslookup, resolvectl",
|
| 608 |
+
"summary": "๋๋ฉ์ธ ์ด๋ฆ์ IP๋ก ํด์ํ๋ ๊ณผ์ ์ ํ์ธํ๊ณ ๋ฌธ์ ๋ฅผ ์ง๋จํฉ๋๋ค. DNS ์๋ฒ๋ `/etc/resolv.conf` ๋๋ `systemd-resolved`๊ฐ ๊ด๋ฆฌํฉ๋๋ค.",
|
| 609 |
+
"example": "dig google.com\nnslookup google.com\nresolvectl status\ncat /etc/resolv.conf",
|
| 610 |
+
"common_mistake": "Ubuntu์์ `/etc/resolv.conf`๋ `systemd-resolved`์ ์ฌ๋ณผ๋ฆญ ๋งํฌ์
๋๋ค. DNS ์๋ฒ ๋ณ๊ฒฝ์ `resolvectl`์ด๋ netplan์์ ํฉ๋๋ค.",
|
| 611 |
+
"keywords": [
|
| 612 |
+
"dig",
|
| 613 |
+
"nslookup",
|
| 614 |
+
"resolv.conf",
|
| 615 |
+
"nameserver",
|
| 616 |
+
"systemd-resolved"
|
| 617 |
+
],
|
| 618 |
+
"source_id": "ubuntu-networking",
|
| 619 |
+
"details": [
|
| 620 |
+
"`dig ๋๋ฉ์ธ` ๊ฒฐ๊ณผ์์ ANSWER SECTION์ IP๊ฐ ์ค์ ํด์๋ ์ฃผ์์
๋๋ค. `dig +short ๋๋ฉ์ธ`์ผ๋ก IP๋ง ์ถ๋ ฅํ ์ ์์ต๋๋ค.",
|
| 621 |
+
"DNS ์๋ฒ๋ `/etc/resolv.conf`์ `nameserver` ์ค์์ ํ์ธํฉ๋๋ค. Ubuntu 22.04๋ 127.0.0.53(๋ก์ปฌ stub)์ด ๊ธฐ๋ณธ์
๋๋ค.",
|
| 622 |
+
"์ํ ํจํด: DNS ์กฐํ ๋ช
๋ น์ผ๋ก ๋๋ฉ์ธ ํด์ ๊ฒฐ๊ณผ๋ฅผ ํ์ธํ๊ฑฐ๋, DNS ์๋ฒ ์ค์ ํ์ผ ์์น๋ฅผ ๋ฌป๋ ๋ฌธ์ ๊ฐ ์ถ์ ๋ฉ๋๋ค."
|
| 623 |
+
]
|
| 624 |
+
},
|
| 625 |
+
{
|
| 626 |
+
"id": "linux-route",
|
| 627 |
+
"certification": "LFCS / ๋ฆฌ๋
์ค๋ง์คํฐ",
|
| 628 |
+
"title": "๋ผ์ฐํ
ํ์ธ โ ip route",
|
| 629 |
+
"summary": "ํจํท์ด ์ด๋ ๊ฒฝ๋ก๋ก ๋๊ฐ๋์ง ๋ผ์ฐํ
ํ
์ด๋ธ์ ํ์ธํ๊ณ , ์์ ๋ผ์ฐํธ๋ฅผ ์ถ๊ฐํ๊ฑฐ๋ ์ญ์ ํฉ๋๋ค.",
|
| 630 |
+
"example": "ip route show\nip route add 10.0.0.0/8 via 192.168.1.1\nip route del 10.0.0.0/8\nip route get 8.8.8.8 # ํน์ IP๋ก ๊ฐ๋ ๊ฒฝ๋ก",
|
| 631 |
+
"common_mistake": "`ip route add`๋ก ์ถ๊ฐํ ๋ผ์ฐํธ๋ ์ฌ๋ถํ
ํ๋ฉด ์ฌ๋ผ์ง๋๋ค. ์๏ฟฝ๏ฟฝ ์ค์ ์ netplan ๋๋ `/etc/network/interfaces`์์ ํฉ๋๋ค.",
|
| 632 |
+
"keywords": [
|
| 633 |
+
"ip route",
|
| 634 |
+
"gateway",
|
| 635 |
+
"routing table",
|
| 636 |
+
"default",
|
| 637 |
+
"via"
|
| 638 |
+
],
|
| 639 |
+
"source_id": "linux-man7-ip",
|
| 640 |
+
"details": [
|
| 641 |
+
"`ip route show`์์ `default via ๊ฒ์ดํธ์จ์ดIP dev ์ธํฐํ์ด์ค` ์ค์ด ๊ธฐ๋ณธ ๊ฒ์ดํธ์จ์ด์
๋๋ค.",
|
| 642 |
+
"`ip route get ๋ชฉ์ ์งIP`๋ ์ค์ ๋ก ๊ทธ IP์ ํจํท์ ๋ณด๋ผ ๋ ์ฌ์ฉํ ๊ฒฝ๋ก์ ์ถ๊ตฌ ์ธํฐํ์ด์ค๋ฅผ ๋ณด์ฌ์ค๋๋ค.",
|
| 643 |
+
"์ํ ํจํด: ๋ผ์ฐํ
ํ
์ด๋ธ์์ ๊ธฐ๋ณธ ๊ฒ์ดํธ์จ์ด๋ฅผ ํ์ธํ๊ฑฐ๋, ํน์ ๋คํธ์ํฌ๋ก ์์ ๋ผ์ฐํธ๋ฅผ ์ถ๊ฐํ๋ ๋ช
๋ น์ ์์ฑํ๋ ๋ฌธ์ ๊ฐ ์ถ์ ๋ฉ๋๋ค."
|
| 644 |
+
]
|
| 645 |
+
},
|
| 646 |
+
{
|
| 647 |
+
"id": "linux-netplan",
|
| 648 |
+
"certification": "LFCS / ๋ฆฌ๋
์ค๋ง์คํฐ",
|
| 649 |
+
"title": "netplan โ ๋คํธ์ํฌ ์ค์ ",
|
| 650 |
+
"summary": "Ubuntu 18.04 ์ดํ ๊ธฐ๋ณธ ๋คํธ์ํฌ ์ค์ ๋๊ตฌ์
๋๋ค. `/etc/netplan/*.yaml` ํ์ผ์ ์ค์ ํ๊ณ `netplan apply`๋ก ์ ์ฉํฉ๋๋ค.",
|
| 651 |
+
"example": "# /etc/netplan/00-installer-config.yaml\nnetwork:\n ethernets:\n eth0:\n addresses: [192.168.1.100/24]\n gateway4: 192.168.1.1\nnetplan apply",
|
| 652 |
+
"common_mistake": "YAML์ ๋ค์ฌ์ฐ๊ธฐ(์คํ์ด์ค๋ง, ํญ ๊ธ์ง)๊ฐ ๋งค์ฐ ์๊ฒฉํฉ๋๋ค. ๋ค์ฌ์ฐ๊ธฐ ์ค๋ฅ ์ `netplan apply`๊ฐ ์คํจํฉ๋๋ค.",
|
| 653 |
+
"keywords": [
|
| 654 |
+
"netplan",
|
| 655 |
+
"yaml",
|
| 656 |
+
"static IP",
|
| 657 |
+
"gateway4",
|
| 658 |
+
"nameservers"
|
| 659 |
+
],
|
| 660 |
+
"source_id": "ubuntu-networking",
|
| 661 |
+
"details": [
|
| 662 |
+
"`netplan generate`๋ ์ค์ ์ ๋ฐฑ์๋ ์ค์ ํ์ผ๋ก ๋ณํ๋ง ํ๊ณ , `netplan apply`๊ฐ ์ค์ ๋คํธ์ํฌ์ ์ ์ฉํฉ๋๋ค.",
|
| 663 |
+
"์ ์ IP ์ค์ : `addresses`, `gateway4/routes`, `nameservers.addresses`๋ฅผ YAML์ ์ ์ํฉ๋๋ค.",
|
| 664 |
+
"์ํ ํจํด: ์ ์ IP๋ฅผ ์ค์ ํ๊ฑฐ๋ DNS ์๋ฒ๋ฅผ ๋ณ๊ฒฝํ๋ netplan YAML ๋ด์ฉ์ ์์ฑํ๋ ๋ฌธ์ ๊ฐ ์ถ์ ๋ฉ๋๋ค."
|
| 665 |
+
]
|
| 666 |
+
},
|
| 667 |
+
{
|
| 668 |
+
"id": "linux-curl",
|
| 669 |
+
"certification": "LFCS / ๋ฆฌ๋
์ค๋ง์คํฐ",
|
| 670 |
+
"title": "curl โ HTTP ์์ฒญ๊ณผ ํ์ผ ๋ค์ด๋ก๋",
|
| 671 |
+
"summary": "HTTP/HTTPS ์์ฒญ์ ๋ณด๋ด๊ณ ์๋ต์ ํ์ธํฉ๋๋ค. API ํ
์คํธ, ํ์ผ ๋ค์ด๋ก๋, ์๋น์ค ๋์ ํ์ธ์ ์ฌ์ฉํฉ๋๋ค.",
|
| 672 |
+
"example": "curl http://localhost:8080/health\ncurl -O https://example.com/file.tar.gz\ncurl -H 'Content-Type: application/json' -d '{\"key\":\"val\"}' -X POST http://api/endpoint\ncurl -I https://example.com # ํค๋๋ง",
|
| 673 |
+
"common_mistake": "`curl URL`์ ๋ด์ฉ์ stdout์ ์ถ๋ ฅํฉ๋๋ค. ํ์ผ๋ก ์ ์ฅํ๋ ค๋ฉด `-o ํ์ผ๋ช
` ๋๋ URL๊ณผ ๊ฐ์ ์ด๋ฆ์ผ๋ก ์ ์ฅ์ `-O`๋ฅผ ์๋๋ค.",
|
| 674 |
+
"keywords": [
|
| 675 |
+
"curl",
|
| 676 |
+
"-O",
|
| 677 |
+
"-o",
|
| 678 |
+
"-H",
|
| 679 |
+
"-d",
|
| 680 |
+
"-X",
|
| 681 |
+
"-I",
|
| 682 |
+
"HTTP"
|
| 683 |
+
],
|
| 684 |
+
"source_id": "linux-man7-ip",
|
| 685 |
+
"details": [
|
| 686 |
+
"์ฃผ์ ์ต์
: `-o ํ์ผ`(์ ์ฅ), `-O`(์๋ณธ ํ์ผ๋ช
), `-L`(๋ฆฌ๋ค์ด๋ ํธ ๋ฐ๋ผ๊ฐ๊ธฐ), `-k`(SSL ๊ฒ์ฆ ๋ฌด์), `-s`(silent), `-v`(์์ธ).",
|
| 687 |
+
"`curl -I URL`์ HTTP ํค๋๋ง ํ์ธ. ์ํ ์ฝ๋(200, 404, 301 ๋ฑ)๋ก ์๋น์ค ์๋ต์ ๋น ๋ฅด๊ฒ ํ์ธํฉ๋๋ค.",
|
| 688 |
+
"์ํ ํจํด: ์๋น์ค ๋์ ํ์ธ, ํ์ผ ๋ค์ด๋ก๋, ๊ฐ๋จํ API ์์ฒญ ๋ช
๋ น์ ์์ฑํ๋ ๋ฌธ์ ๊ฐ ์ถ์ ๋ฉ๋๋ค."
|
| 689 |
+
]
|
| 690 |
+
},
|
| 691 |
+
{
|
| 692 |
+
"id": "linux-ping",
|
| 693 |
+
"certification": "LFCS / ๋ฆฌ๋
์ค๋ง์คํฐ",
|
| 694 |
+
"title": "ping โ ๋คํธ์ํฌ ์ฐ๊ฒฐ ํ์ธ",
|
| 695 |
+
"summary": "ICMP echo ์์ฒญ์ผ๋ก ํธ์คํธ์ ๋๋ฌ ๊ฐ๋ฅํ์ง ํ์ธํฉ๋๋ค. ๋คํธ์ํฌ ๋ฌธ์ ์ง๋จ์ ์ฒซ ๋ฒ์งธ ๋จ๊ณ์
๋๋ค.",
|
| 696 |
+
"example": "ping -c 4 8.8.8.8\nping -c 1 192.168.1.1 # ๊ฒ์ดํธ์จ์ด ํ์ธ\nping6 ::1 # IPv6 ๋ฃจํ๋ฐฑ",
|
| 697 |
+
"common_mistake": "๋ฐฉํ๋ฒฝ์ด ICMP๋ฅผ ์ฐจ๋จํ๋ฉด ping์ด ์คํจํด๋ ์ค์ ๋ก๋ ์ฐ๊ฒฐ์ด ๊ฐ๋ฅํ ๊ฒฝ์ฐ๊ฐ ์์ต๋๋ค. ping ์คํจ = ์๋น์ค ์ฅ์ ๋ ์๋๋๋ค.",
|
| 698 |
+
"keywords": [
|
| 699 |
+
"ping",
|
| 700 |
+
"-c",
|
| 701 |
+
"ICMP",
|
| 702 |
+
"latency",
|
| 703 |
+
"packet loss"
|
| 704 |
+
],
|
| 705 |
+
"source_id": "ubuntu-networking",
|
| 706 |
+
"details": [
|
| 707 |
+
"`-c ํ์`๋ก ๋ณด๋ผ ํจํท ์๋ฅผ ์ ํํฉ๋๋ค. ์ง์ ์์ผ๋ฉด Ctrl+C ๋๋ฅผ ๋๊น์ง ๊ณ์ ์ ์กํฉ๋๋ค.",
|
| 708 |
+
"์ถ๋ ฅ์์ `time=`์ RTT(์๋ณต ์๊ฐ), `packet loss %`๋ ํจํท ์์ค๋ฅ . 100% loss๋ฉด ๊ฒฝ๋ก ๋ฌธ์ ๋๋ ๋ฐฉํ๋ฒฝ ์ฐจ๋จ์
๋๋ค.",
|
| 709 |
+
"์ํ ํจํด: ํน์ ํธ์คํธ์ ์ฐ๊ฒฐ ๊ฐ๋ฅ ์ฌ๋ถ ํ์ธ, `-c` ์ต์
์ผ๋ก ํจํท ์ ์ ํํ๋ ๋ช
๋ น์ด ์ถ์ ๋ฉ๋๋ค."
|
| 710 |
+
]
|
| 711 |
+
},
|
| 712 |
+
{
|
| 713 |
+
"id": "linux-cron",
|
| 714 |
+
"certification": "LFCS / ๋ฆฌ๋
์ค๋ง์คํฐ",
|
| 715 |
+
"title": "cron โ ์์
์ค์ผ์ค๋ง",
|
| 716 |
+
"summary": "์ง์ ํ ์๊ฐ์ด๋ ์ฃผ๊ธฐ์ ๋ช
๋ น์ ์๋์ผ๋ก ์คํํฉ๋๋ค. `crontab -e`๋ก ์ฌ์ฉ์๋ณ ์ค์ผ์ค์ ๊ด๋ฆฌํฉ๋๋ค.",
|
| 717 |
+
"example": "crontab -e # ํธ์ง\ncrontab -l # ๋ชฉ๋ก ํ์ธ\n# ๋งค์ผ ์๋ฒฝ 2์์ ๋ฐฑ์
\n0 2 * * * /usr/local/bin/backup.sh\n# ๋งค 5๋ถ๋ง๋ค\n*/5 * * * * /usr/local/bin/check.sh",
|
| 718 |
+
"common_mistake": "cron ์์
์์๋ PATH๊ฐ ์ผ๋ฐ ์๊ณผ ๋ค๋ฆ
๋๋ค. ๋ช
๋ น์ ์ ๋๊ฒฝ๋ก๋ก ์ฐ๊ฑฐ๋ ์คํฌ๋ฆฝํธ ์์์ PATH๋ฅผ ์ง์ ์ค์ ํ์ธ์.",
|
| 719 |
+
"keywords": [
|
| 720 |
+
"cron",
|
| 721 |
+
"crontab",
|
| 722 |
+
"-e",
|
| 723 |
+
"-l",
|
| 724 |
+
"schedule",
|
| 725 |
+
"*/5"
|
| 726 |
+
],
|
| 727 |
+
"source_id": "ubuntu-server-docs",
|
| 728 |
+
"details": [
|
| 729 |
+
"crontab ํ์: `๋ถ ์ ์ผ ์ ์์ผ ๋ช
๋ น`. ๋ณํ(*)๋ '๋ชจ๋ ๊ฐ', `*/5`๋ '5๋ง๋ค', `0,30`์ '0๊ณผ 30'์ ์๋ฏธํฉ๋๋ค.",
|
| 730 |
+
"์์คํ
์ ์ฒด cron์ `/etc/cron.d/`, `/etc/cron.daily/` ๋ฑ์์ ๊ด๋ฆฌํฉ๋๋ค. `/var/log/syslog`์ ์คํ ๊ธฐ๋ก์ด ๋จ์ต๋๋ค.",
|
| 731 |
+
"์ํ ํจํด: ํน์ ์ฃผ๊ธฐ(๋งค์ผ, ๋งค์๊ฐ, ๋งค N๋ถ)๋ก ์คํฌ๋ฆฝํธ๋ฅผ ์คํํ๋ crontab ํญ๋ชฉ์ ์์ฑํ๋ ๋ฌธ์ ๊ฐ ์ถ์ ๋ฉ๋๋ค."
|
| 732 |
+
]
|
| 733 |
+
},
|
| 734 |
+
{
|
| 735 |
+
"id": "linux-top",
|
| 736 |
+
"certification": "LFCS / ๋ฆฌ๋
์ค๋ง์คํฐ",
|
| 737 |
+
"title": "top โ ์ค์๊ฐ ์์คํ
๋ชจ๋ํฐ",
|
| 738 |
+
"summary": "CPUยท๋ฉ๋ชจ๋ฆฌยทํ๋ก์ธ์ค๋ฅผ ์ค์๊ฐ์ผ๋ก ๋ชจ๋ํฐ๋งํฉ๋๋ค. ๋ฆฌ์์ค๋ฅผ ๋ง์ด ์ฐ๋ ํ๋ก์ธ์ค๋ฅผ ๋น ๋ฅด๊ฒ ์ฐพ์ ๋ ์ฌ์ฉํฉ๋๋ค.",
|
| 739 |
+
"example": "top\ntop -u alice # ํน์ ์ฌ์ฉ์ ํ๋ก์ธ์ค๋ง\ntop -bn 1 # 1ํ๋ง ์ถ๋ ฅ (์คํฌ๋ฆฝํธ์ฉ)\nhtop # ๋ ๋ณด๊ธฐ ์ข์ ๋์",
|
| 740 |
+
"common_mistake": "`top` ์คํ ์ค `k` ํค๋ก PID๋ฅผ ์
๋ ฅํ๋ฉด ํ๋ก์ธ์ค๋ฅผ ์ข
๋ฃํ ์ ์์ต๋๋ค. ์๋ชป ๋๋ฅด์ง ์๋๋ก ์ฃผ์ํ์ธ์.",
|
| 741 |
+
"keywords": [
|
| 742 |
+
"top",
|
| 743 |
+
"CPU",
|
| 744 |
+
"memory",
|
| 745 |
+
"load average",
|
| 746 |
+
"%MEM",
|
| 747 |
+
"%CPU"
|
| 748 |
+
],
|
| 749 |
+
"source_id": "ubuntu-server-docs",
|
| 750 |
+
"details": [
|
| 751 |
+
"์๋จ ์์ฝ: load average(1๋ถ/5๋ถ/15๋ถ ํ๊ท ๋ถํ), Tasks(ํ๋ก์ธ์ค ์), %Cpu(us/sy/id), Mem/Swap ์ฌ์ฉ๋.",
|
| 752 |
+
"์ปฌ๋ผ ์๋ฏธ: PID, USER, %CPU, %MEM, RES(์ค์ ๋ฉ๋ชจ๋ฆฌ), S(์ํ: R=์คํ/S=๋๊ธฐ/Z=์ข๋น).",
|
| 753 |
+
"์ํ ํจํด: CPU๋ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๊ฐ์ฅ ๋ง์ด ์ฐ๋ ํ๋ก์ธ์ค ์ฐพ๊ธฐ, ๋ก๋ ์ ๋ฒ๋ฆฌ์ง ํด์, ํ๋ก์ธ์ค ์ํ ํ์ธ ๋ฌธ์ ๊ฐ ์ถ์ ๋ฉ๋๋ค."
|
| 754 |
+
]
|
| 755 |
+
},
|
| 756 |
+
{
|
| 757 |
+
"id": "linux-nice",
|
| 758 |
+
"certification": "LFCS / ๋ฆฌ๋
์ค๋ง์คํฐ",
|
| 759 |
+
"title": "nice, renice โ ํ๋ก์ธ์ค ์ฐ์ ์์",
|
| 760 |
+
"summary": "ํ๋ก์ธ์ค์ CPU ์ค์ผ์ค๋ง ์ฐ์ ์์๋ฅผ ์กฐ์ ํฉ๋๋ค. ๊ฐ์ด ๋ฎ์์๋ก(-20~+19) ์ฐ์ ์์๊ฐ ๋์ผ๋ฉฐ, ๋์ ์ฐ์ ์์ ์ค์ ์ root๋ง ๊ฐ๋ฅํฉ๋๋ค.",
|
| 761 |
+
"example": "nice -n 10 gzip big_file.gz # ๋ฎ์ ์ฐ์ ์์๋ก ์์\nrenice -n -5 -p 1234 # ์คํ ์ค์ธ ํ๋ก์ธ์ค ๋ณ๊ฒฝ\nps -o pid,ni,cmd -p 1234 # ํ์ฌ nice ๊ฐ ํ์ธ",
|
| 762 |
+
"common_mistake": "nice ๊ฐ์ด ๋ฎ์์๋ก ์ฐ์ ์์๊ฐ ๋์ต๋๋ค(-20์ด ์ต๊ณ ). ์ผ๋ฐ ์ฌ์ฉ์๋ ํ์ฌ๋ณด๋ค ๋ฎ๊ฒ(๋ฎ์ ์ฐ์ ์์๋ก)๋ง ๋ณ๊ฒฝ ๊ฐ๋ฅํฉ๋๋ค.",
|
| 763 |
+
"keywords": [
|
| 764 |
+
"nice",
|
| 765 |
+
"renice",
|
| 766 |
+
"priority",
|
| 767 |
+
"niceness",
|
| 768 |
+
"-20",
|
| 769 |
+
"+19"
|
| 770 |
+
],
|
| 771 |
+
"source_id": "ubuntu-server-docs",
|
| 772 |
+
"details": [
|
| 773 |
+
"๊ธฐ๋ณธ nice ๊ฐ์ 0. ๋ฐฑ๊ทธ๋ผ์ด๋ ๋ฐฐ์น ์์
์ `nice -n 15`์ฒ๋ผ ๋ฎ์ ์ฐ์ ์์๋ก ์คํํด ์์คํ
์ํฅ์ ์ค์
๋๋ค.",
|
| 774 |
+
"`renice`๋ก ์คํ ์ค์ธ ํ๋ก์ธ์ค์ ์ฐ์ ์์๋ฅผ ๋ฐ๊ฟ ์ ์์ต๋๋ค. `-p PID`๋ก ํ๋ก์ธ์ค, `-u ์ฌ์ฉ์`๋ก ์ฌ์ฉ์ ์ ์ฒด๋ฅผ ๋ณ๊ฒฝํฉ๋๋ค.",
|
| 775 |
+
"์ํ ํจํด: ํน์ nice ๊ฐ์ผ๋ก ํ๋ก์ธ์ค๋ฅผ ์คํํ๊ฑฐ๋ ์คํ ์ค์ธ ํ๋ก์ธ์ค์ ์ฐ์ ์์๋ฅผ ๋ณ๊ฒฝํ๋ ๋ช
๋ น์ ์์ฑํ๋ ๋ฌธ์ ๊ฐ ์ถ์ ๋ฉ๋๋ค."
|
| 776 |
+
]
|
| 777 |
+
},
|
| 778 |
+
{
|
| 779 |
+
"id": "linux-lsblk",
|
| 780 |
+
"certification": "LFCS / ๋ฆฌ๋
์ค๋ง์คํฐ",
|
| 781 |
+
"title": "lsblk โ ๋ธ๋ก ์ฅ์น ํ์ธ",
|
| 782 |
+
"summary": "๋์คํฌ, ํํฐ์
, LVM ๋ฑ ๋ธ๋ก ์ฅ์น์ ๋ง์ดํธ ์ ๋ณด๋ฅผ ํธ๋ฆฌ ํํ๋ก ๋ณด์ฌ์ค๋๋ค.",
|
| 783 |
+
"example": "lsblk\nlsblk -f # ํ์ผ์์คํ
ํ์
๊ณผ UUID ํฌํจ\nblkid # UUID์ ํ์
์์ธ ํ์ธ",
|
| 784 |
+
"common_mistake": "`lsblk`๋ ๋ธ๋ก ์ฅ์น ๊ตฌ์กฐ๋ฅผ ๋ณด์ฌ์ฃผ๊ณ , `df -h`๋ ๋ง์ดํธ๋ ํ์ผ์์คํ
์ ์ฌ์ฉ๋์ ๋ณด์ฌ์ค๋๋ค. ์ญํ ์ด ๋ค๋ฆ
๋๋ค.",
|
| 785 |
+
"keywords": [
|
| 786 |
+
"lsblk",
|
| 787 |
+
"blkid",
|
| 788 |
+
"partition",
|
| 789 |
+
"UUID",
|
| 790 |
+
"FSTYPE",
|
| 791 |
+
"block device"
|
| 792 |
+
],
|
| 793 |
+
"source_id": "ubuntu-storage",
|
| 794 |
+
"details": [
|
| 795 |
+
"์ถ๋ ฅ ์ปฌ๋ผ: NAME(์ฅ์น๋ช
), SIZE, TYPE(disk/part/lvm), MOUNTPOINT. `sda`๋ ๋์คํฌ, `sda1`์ ์ฒซ ํํฐ์
.",
|
| 796 |
+
"`lsblk -f`๋ ํ์ผ์์คํ
ํ์
(ext4, xfs ๋ฑ)๊ณผ UUID๋ฅผ ํจ๊ป ๋ณด์ฌ์ค๋๋ค. `/etc/fstab` ์ค์ ์ UUID๋ฅผ ์ฌ๊ธฐ์ ๋ณต์ฌํฉ๋๋ค.",
|
| 797 |
+
"์ํ ํจํด: ๋ง์ดํธ ๊ฐ๋ฅํ ํํฐ์
๋ชฉ๋ก ํ์ธ, UUID ์กฐํ, ๋์คํฌ ๊ตฌ์กฐ ํ์
๋ฌธ์ ์์ ํ์ฉ๋ฉ๋๋ค."
|
| 798 |
+
]
|
| 799 |
+
},
|
| 800 |
+
{
|
| 801 |
+
"id": "linux-fstab",
|
| 802 |
+
"certification": "LFCS / ๋ฆฌ๋
์ค๋ง์คํฐ",
|
| 803 |
+
"title": "/etc/fstab โ ์๋ ๋ง์ดํธ ์ค์ ",
|
| 804 |
+
"summary": "๋ถํ
์ ์๋์ผ๋ก ๋ง์ดํธํ ํ์ผ์์คํ
์ ์ ์ํฉ๋๋ค. UUID, ์ฅ์น๋ช
, ๋ง์ดํธ ํฌ์ธํธ, ํ์ผ์์คํ
ํ์
, ์ต์
, dump/pass๋ฅผ ์ง์ ํฉ๋๋ค.",
|
| 805 |
+
"example": "# UUID๋ฅผ ์ฌ์ฉํ fstab ํญ๋ชฉ\nUUID=xxxx-yyyy /mnt/data ext4 defaults 0 2\n# ํ์ธ ๋ฐ ํ
์คํธ\nmount -a # fstab ์ ์ฒด ๋ง์ดํธ ์๋",
|
| 806 |
+
"common_mistake": "fstab์ ์ค๋ฅ๊ฐ ์์ผ๋ฉด ๋ถํ
์์ฒด๊ฐ ์คํจํ ์ ์์ต๋๋ค. ๋ณ๊ฒฝ ํ `mount -a`๋ก ํ
์คํธํ๊ณ , UUID๋ `blkid`๋ก ํ์ธํ์ธ์.",
|
| 807 |
+
"keywords": [
|
| 808 |
+
"fstab",
|
| 809 |
+
"UUID",
|
| 810 |
+
"mount -a",
|
| 811 |
+
"defaults",
|
| 812 |
+
"auto mount"
|
| 813 |
+
],
|
| 814 |
+
"source_id": "ubuntu-storage",
|
| 815 |
+
"details": [
|
| 816 |
+
"fstab ํ์: `์ฅ์น ๋ง์ดํธํฌ์ธํธ ํ์
์ต์
dump pass`. dump=0(๋ฐฑ์
์ ์ธ), pass=0(๊ฒ์ฌ ์ ํจ)/1(๋ฃจํธ)/2(๊ธฐํ).",
|
| 817 |
+
"์ฅ์น ์ง์ ์ UUID๊ฐ ์์ ํฉ๋๋ค. `/dev/sda1`์ ๋์คํฌ ์ถ๊ฐ ์ ์ด๋ฆ์ด ๋ฐ๋ ์ ์์ง๋ง UUID๋ ๊ณ ์ ์
๋๋ค.",
|
| 818 |
+
"์ํ ํจํด: ํน์ ํํฐ์
์ ๋ถํ
์ ์๋ ๋ง์ดํธํ๋๋ก fstab์ ํญ๋ชฉ์ ์ถ๊ฐํ๋ ์ค์ต ๋ฌธ์ ๊ฐ ์ถ์ ๋ฉ๋๋ค."
|
| 819 |
+
]
|
| 820 |
+
},
|
| 821 |
+
{
|
| 822 |
+
"id": "linux-swap",
|
| 823 |
+
"certification": "LFCS / ๋ฆฌ๋
์ค๋ง์คํฐ",
|
| 824 |
+
"title": "swap โ ์ค์ ๊ด๋ฆฌ",
|
| 825 |
+
"summary": "๋ฌผ๋ฆฌ ๋ฉ๋ชจ๋ฆฌ๊ฐ ๋ถ์กฑํ ๋ ๋์คํฌ ์ผ๋ถ๋ฅผ ์์ ๋ฉ๋ชจ๋ฆฌ๋ก ์ฌ์ฉํฉ๋๋ค. ์ค์ ํํฐ์
๊ณผ ์ค์ ํ์ผ ๋ ๊ฐ์ง ๋ฐฉ์์ด ์์ต๋๋ค.",
|
| 826 |
+
"example": "swapon --show # ํ์ฌ ์ค์ ํ์ธ\nfallocate -l 2G /swapfile\nchmod 600 /swapfile\nmkswap /swapfile\nswapon /swapfile",
|
| 827 |
+
"common_mistake": "์ค์ ํ์ผ์ ๋ฐ๋์ root๋ง ์ฝ์ ์ ์๋๋ก `chmod 600`์ ํด์ผ ํฉ๋๋ค. ๊ถํ์ด ์ด๋ ค ์์ผ๋ฉด `swapon`์ด ์คํจํฉ๋๋ค.",
|
| 828 |
+
"keywords": [
|
| 829 |
+
"swap",
|
| 830 |
+
"swapon",
|
| 831 |
+
"swapoff",
|
| 832 |
+
"mkswap",
|
| 833 |
+
"swapfile",
|
| 834 |
+
"/proc/swaps"
|
| 835 |
+
],
|
| 836 |
+
"source_id": "ubuntu-storage",
|
| 837 |
+
"details": [
|
| 838 |
+
"์ค์ ํ์ผ ์์ฑ ์์: `fallocate -l ํฌ๊ธฐ /swapfile` โ `chmod 600` โ `mkswap` โ `swapon` โ `/etc/fstab`์ ์ถ๊ฐ.",
|
| 839 |
+
"์๊ตฌ ํ์ฑํ: `/etc/fstab`์ `/swapfile none swap sw 0 0` ์ถ๊ฐ. `swapon -a`๋ก fstab์ ์ค์์ ๋ชจ๋ ํ์ฑํํฉ๋๋ค.",
|
| 840 |
+
"์ํ ํจํด: ํน์ ํฌ๊ธฐ์ ์ค์ ํ์ผ์ ๋ง๋ค๊ณ ํ์ฑํํ๋ ์ ์ฒด ๊ณผ์ ์ ์์ฑํ๋ ์ค์ต ๋ฌธ์ ๊ฐ ์ถ์ ๋ฉ๋๋ค."
|
| 841 |
+
]
|
| 842 |
+
},
|
| 843 |
+
{
|
| 844 |
+
"id": "linux-lvm",
|
| 845 |
+
"certification": "LFCS / ๋ฆฌ๋
์ค๋ง์คํฐ",
|
| 846 |
+
"title": "LVM โ ๋
ผ๋ฆฌ ๋ณผ๋ฅจ ๊ด๋ฆฌ",
|
| 847 |
+
"summary": "๋ฌผ๋ฆฌ ๋์คํฌ(PV)๋ฅผ ๋ณผ๋ฅจ ๊ทธ๋ฃน(VG)์ผ๋ก ๋ฌถ๊ณ , ๊ทธ ์์ ์ ์ฐํ๊ฒ ํฌ๊ธฐ๋ฅผ ์กฐ์ ํ ์ ์๋ ๋
ผ๋ฆฌ ๋ณผ๋ฅจ(LV)์ ๋ง๋ญ๋๋ค.",
|
| 848 |
+
"example": "pvcreate /dev/sdb\nvgcreate datavg /dev/sdb\nlvcreate -L 10G -n datalv datavg\nmkfs.ext4 /dev/datavg/datalv\nlvextend -L +5G /dev/datavg/datalv && resize2fs /dev/datavg/datalv",
|
| 849 |
+
"common_mistake": "`lvextend`๋ก LV ํฌ๊ธฐ๋ฅผ ๋๋ฆฐ ๋ค ํ์ผ์์คํ
๋ ๋๋ ค์ผ ํฉ๋๋ค. ext4๋ `resize2fs`, xfs๋ `xfs_growfs`๋ฅผ ์๋๋ค.",
|
| 850 |
+
"keywords": [
|
| 851 |
+
"LVM",
|
| 852 |
+
"pvcreate",
|
| 853 |
+
"vgcreate",
|
| 854 |
+
"lvcreate",
|
| 855 |
+
"lvextend",
|
| 856 |
+
"resize2fs"
|
| 857 |
+
],
|
| 858 |
+
"source_id": "ubuntu-storage",
|
| 859 |
+
"details": [
|
| 860 |
+
"LVM 3๊ณ์ธต: PV(๋ฌผ๋ฆฌ ๋ณผ๋ฅจ, ์ค์ ๋์คํฌ/ํํฐ์
) โ VG(๋ณผ๋ฅจ ๊ทธ๋ฃน) โ LV(๋
ผ๋ฆฌ ๋ณผ๋ฅจ, ํ์ผ์์คํ
์ด ์ฌ๋ผ๊ฐ๋ ๊ณณ).",
|
| 861 |
+
"ํ์ฅ ์ ์ฐจ: `lvextend -L +ํฌ๊ธฐ /dev/VG/LV` ํ `resize2fs /dev/VG/LV`(ext4) ๋๋ `xfs_growfs /๋ง์ดํธํฌ์ธํธ`(xfs).",
|
| 862 |
+
"์ํ ํจํด: PVโVGโLV ์์ฑ ์์, LV ํ์ฅ ํ ํ์ผ์์คํ
ํ์ฅ๊น์ง ์ด์ด์ง๋ ์ค์ต ๋ฌธ์ ๊ฐ ์ถ์ ๋ฉ๋๋ค."
|
| 863 |
+
]
|
| 864 |
+
},
|
| 865 |
+
{
|
| 866 |
+
"id": "linux-logs-var",
|
| 867 |
+
"certification": "LFCS / ๋ฆฌ๋
์ค๋ง์คํฐ",
|
| 868 |
+
"title": "/var/log โ ์์คํ
๋ก๊ทธ ํ์ผ",
|
| 869 |
+
"summary": "Linux์ ์ฃผ์ ๋ก๊ทธ ํ์ผ๋ค์ `/var/log/`์ ์ ์ฅ๋ฉ๋๋ค. ์๋น์ค๋ณ, ๋ชฉ์ ๋ณ๋ก ํ์ผ์ด ๋๋์ด ์์ด ๋ฌธ์ ์ง๋จ์ ์ถ๋ฐ์ ์
๋๋ค.",
|
| 870 |
+
"example": "tail -f /var/log/syslog\ngrep 'ERROR' /var/log/auth.log\nls -lh /var/log/\nzcat /var/log/syslog.1.gz # ํ์ ๋ ๋ก๊ทธ",
|
| 871 |
+
"common_mistake": "`/var/log/syslog`๋ ์ผ๋ฐ ์์คํ
๋ฉ์์ง, `/var/log/auth.log`๋ ์ธ์ฆ ๊ด๋ จ. journalctl์ ์ด ํ์ผ์ด ์๋๋ผ journal์ ์ฝ์ต๋๋ค.",
|
| 872 |
+
"keywords": [
|
| 873 |
+
"syslog",
|
| 874 |
+
"auth.log",
|
| 875 |
+
"dmesg",
|
| 876 |
+
"/var/log",
|
| 877 |
+
"logrotate"
|
| 878 |
+
],
|
| 879 |
+
"source_id": "ubuntu-server-docs",
|
| 880 |
+
"details": [
|
| 881 |
+
"์ฃผ์ ํ์ผ: `syslog`(์ผ๋ฐ ์์คํ
), `auth.log`(SSH/sudo/PAM ์ธ์ฆ), `kern.log`(์ปค๋), `dpkg.log`(ํจํค์ง ์ค์น/์ ๊ฑฐ).",
|
| 882 |
+
"`logrotate`๊ฐ ์๋์ผ๋ก ๋ก๊ทธ๋ฅผ ํ์ ํฉ๋๋ค. ์ด์ ๋ก๊ทธ๋ `.1`, `.2` ๋๋ `.gz`(์์ถ) ํํ๋ก ๋ณด๊ด๋ฉ๋๋ค.",
|
| 883 |
+
"์ํ ํจํด: ํน์ ์ด๋ฒคํธ(๋ก๊ทธ์ธ ์คํจ, ์๋น์ค ์ค๋ฅ)๋ฅผ ํด๋น ๋ก๊ทธ ํ์ผ์์ ์ฐพ๋ ๋ช
๋ น์ ์์ฑํ๋ ๋ฌธ์ ๊ฐ ์ถ์ ๋ฉ๋๋ค."
|
| 884 |
+
]
|
| 885 |
+
},
|
| 886 |
+
{
|
| 887 |
+
"id": "linux-dmesg",
|
| 888 |
+
"certification": "LFCS / ๋ฆฌ๋
์ค๋ง์คํฐ",
|
| 889 |
+
"title": "dmesg โ ์ปค๋ ๋ง ๋ฒํผ ๋ก๊ทธ",
|
| 890 |
+
"summary": "์ปค๋์ด ๋ถํ
์์ ํ๋์จ์ด ์ด๋ฒคํธ ๋ฐ์ ์ ๊ธฐ๋กํ๋ ๋ฉ์์ง๋ฅผ ์ถ๋ ฅํฉ๋๋ค. ๋์คํฌ ์ค๋ฅ, ๋คํธ์ํฌ ์ธํฐํ์ด์ค UP/DOWN ๋ฑ ํ๋์จ์ด ๋ฌธ์ ์ง๋จ์ ์๋๋ค.",
|
| 891 |
+
"example": "dmesg | tail -20\ndmesg | grep -i error\ndmesg -T # ์ฌ๋์ด ์ฝ์ ์ ์๋ ํ์์คํฌํ\ndmesg --level=err,warn",
|
| 892 |
+
"common_mistake": "`dmesg`๋ ์ปค๋ ๋ ๋ฒจ ๋ฉ์์ง๋ง ๋ณด์ฌ์ค๋๋ค. ์๋น์ค ๋ก๊ทธ๋ `journalctl -u ์๋น์ค๋ช
`์ผ๋ก ํ์ธํ์ธ์.",
|
| 893 |
+
"keywords": [
|
| 894 |
+
"dmesg",
|
| 895 |
+
"kernel",
|
| 896 |
+
"hardware",
|
| 897 |
+
"-T",
|
| 898 |
+
"--level",
|
| 899 |
+
"ring buffer"
|
| 900 |
+
],
|
| 901 |
+
"source_id": "ubuntu-server-docs",
|
| 902 |
+
"details": [
|
| 903 |
+
"๋์คํฌ I/O ์ค๋ฅ๋ `dmesg | grep -i 'error\\|fail\\|sda'`๋ก ์ฐพ์ ์ ์์ต๋๋ค.",
|
| 904 |
+
"`dmesg -T`๋ ํ์์คํฌํ๋ฅผ ์ฌ๋์ด ์ฝ๊ธฐ ์ฌ์ด ๋ ์ง ํ์์ผ๋ก ๋ณํํฉ๋๋ค. ๊ธฐ๋ณธ ์ถ๋ ฅ์ ๋ถํ
์ดํ ์ด ๋จ์์
๋๋ค.",
|
| 905 |
+
"์ํ ํจํด: ์์คํ
๋ถํ
์ค๋ฅ๋ ํ๋์จ์ด ๋ฌธ์ ๋ฅผ dmesg์์ ์ฐพ๋ ๋ฌธ์ , ๋๋ ๋ก๊ทธ ๋ ๋ฒจ ํํฐ๋ง ๋ช
๋ น์ด ์ถ์ ๋ฉ๋๋ค."
|
| 906 |
+
]
|
| 907 |
+
},
|
| 908 |
+
{
|
| 909 |
+
"id": "linux-env-path",
|
| 910 |
+
"certification": "LFCS / ๋ฆฌ๋
์ค๋ง์คํฐ",
|
| 911 |
+
"title": "ํ๊ฒฝ ๋ณ์์ PATH",
|
| 912 |
+
"summary": "ํ๊ฒฝ ๋ณ์๋ ์๊ณผ ํ๋ก์ธ์ค์ ์ค์ ์ ์ ๋ฌํฉ๋๋ค. PATH๋ ๋ช
๋ น์ ์ฐพ๋ ๋๋ ํฐ๋ฆฌ ๋ชฉ๋ก์ผ๋ก, ์ ํ๋ก๊ทธ๋จ์ ์ค์น ํ PATH์ ์ถ๊ฐํด์ผ ํ ์ ์์ต๋๋ค.",
|
| 913 |
+
"example": "echo $PATH\nexport PATH=$PATH:/opt/myapp/bin\nprintenv HOME USER\nenv | grep JAVA\nunset MYVAR",
|
| 914 |
+
"common_mistake": "`export VAR=๊ฐ`์ ํ์ฌ ์๊ณผ ์์ ํ๋ก์ธ์ค์๋ง ์ ์ฉ๋ฉ๋๋ค. ์๊ตฌ ์ค์ ์ `~/.bashrc` ๋๋ `/etc/environment`์ ์ถ๊ฐํ์ธ์.",
|
| 915 |
+
"keywords": [
|
| 916 |
+
"PATH",
|
| 917 |
+
"export",
|
| 918 |
+
"env",
|
| 919 |
+
"printenv",
|
| 920 |
+
"$HOME",
|
| 921 |
+
"~/.bashrc"
|
| 922 |
+
],
|
| 923 |
+
"source_id": "linux-bash-cd",
|
| 924 |
+
"details": [
|
| 925 |
+
"`export ๋ณ์=๊ฐ`์ผ๋ก ํ๊ฒฝ ๋ณ์๋ฅผ ์ค์ ํ๋ฉด ์์ ํ๋ก์ธ์ค์ ์ ๋ฌ๋ฉ๋๋ค. ์์ด `๋ณ์=๊ฐ`๋ง ํ๋ฉด ํ์ฌ ์์๋ง ์ ์ฉ๋ฉ๋๋ค.",
|
| 926 |
+
"์๊ตฌ ์ค์ ์์น: ์ฌ์ฉ์๋ณ์ `~/.bashrc` ๋๋ `~/.profile`, ์์คํ
์ ์ฒด๋ `/etc/environment` ๋๋ `/etc/profile`.",
|
| 927 |
+
"์ํ ํจํด: PATH์ ๋๋ ํฐ๋ฆฌ๋ฅผ ์ถ๊ฐํ๊ฑฐ๋, ํน์ ํ๊ฒฝ ๋ณ์๋ฅผ ํ์ธ/์ค์ ํ๋ ๋ช
๋ น, ์๊ตฌ ์ค์ ํ์ผ ์์น๋ฅผ ๋ฌป๋ ๋ฌธ์ ๊ฐ ์ถ์ ๋ฉ๋๋ค."
|
| 928 |
+
]
|
| 929 |
+
},
|
| 930 |
+
{
|
| 931 |
+
"id": "linux-wildcard",
|
| 932 |
+
"certification": "LFCS / ๋ฆฌ๋
์ค๋ง์คํฐ",
|
| 933 |
+
"title": "์์ผ๋์นด๋์ ํ์ผ ๊ธ๋ก๋น",
|
| 934 |
+
"summary": "์์ด ํจํด์ ์ค์ ํ์ผ ์ด๋ฆ์ผ๋ก ํ์ฅํฉ๋๋ค. `*`(๋ชจ๋ ๋ฌธ์), `?`(ํ ๋ฌธ์), `[abc]`(๋ฌธ์ ํด๋์ค)๋ฅผ ์กฐํฉํด ์๋๋ค.",
|
| 935 |
+
"example": "ls *.log\nrm /tmp/test?.txt # test1.txt, test2.txt ๋ฑ\ncp /etc/[a-z]*.conf /backup/\nls {*.txt,*.md} # brace expansion",
|
| 936 |
+
"common_mistake": "์์ผ๋์นด๋๋ ์์ด ๋ช
๋ น ์คํ ์ ์ ํ์ผ ๋ชฉ๋ก์ผ๋ก ํ์ฅํฉ๋๋ค. ๋งค์นญ๋๋ ํ์ผ์ด ์์ผ๋ฉด ๋ช
๋ น์ด ํจํด ๋ฌธ์์ด์ ๊ทธ๋๋ก ์ธ์๋ก ๋ฐ์ต๋๋ค.",
|
| 937 |
+
"keywords": [
|
| 938 |
+
"wildcard",
|
| 939 |
+
"glob",
|
| 940 |
+
"*",
|
| 941 |
+
"?",
|
| 942 |
+
"[]",
|
| 943 |
+
"brace expansion"
|
| 944 |
+
],
|
| 945 |
+
"source_id": "linux-bash-cd",
|
| 946 |
+
"details": [
|
| 947 |
+
"`*`๋ 0๊ฐ ์ด์์ ์์ ๋ฌธ์, `?`๋ ์ ํํ 1๊ฐ ๋ฌธ์, `[0-9]`๋ ๋ฒ์ ์์ ํ ๋ฌธ์, `[!abc]`๋ ์ ์ธ์
๋๋ค.",
|
| 948 |
+
"Brace expansion: `file{1,2,3}.txt`๋ file1.txt file2.txt file3.txt๋ก ํ์ฅ๋ฉ๋๋ค. ํ์ผ์ด ์์ด๋ ๋์ํฉ๋๋ค.",
|
| 949 |
+
"์ํ ํจํด: ํน์ ํจํด์ ํ์ผ์ ํ ๋ฒ์ ์ฒ๋ฆฌํ๊ฑฐ๋, ์์ผ๋์นด๋ ํํ์์ด ์ด๋ค ํ์ผ์ ๋งค์นญ๋๋์ง ํ๋จํ๋ ๋ฌธ์ ๊ฐ ์ถ์ ๋ฉ๋๋ค."
|
| 950 |
+
]
|
| 951 |
+
},
|
| 952 |
+
{
|
| 953 |
+
"id": "linux-exit-code",
|
| 954 |
+
"certification": "LFCS / ๋ฆฌ๋
์ค๋ง์คํฐ",
|
| 955 |
+
"title": "exit code โ ๋ช
๋ น ์ข
๋ฃ ์ฝ๋",
|
| 956 |
+
"summary": "๋ช
๋ น ์คํ ํ ๋ฐํํ๋ ์ซ์(0~255). 0์ ์ฑ๊ณต, 0์ด ์๋๋ฉด ์ค๋ฅ. ์คํฌ๋ฆฝํธ์์ ์ด์ ๋ช
๋ น ์ฑ๊ณต ์ฌ๋ถ๋ฅผ `$?`๋ก ํ์ธํฉ๋๋ค.",
|
| 957 |
+
"example": "ls /etc && echo '์ฑ๊ณต'\nls /์๋๊ฒฝ๋ก || echo '์คํจ'\necho $?\ncommand; [ $? -eq 0 ] && echo ok",
|
| 958 |
+
"common_mistake": "`$?`๋ ๋ฐ๋ก ์ง์ ๋ช
๋ น์ ์ข
๋ฃ ์ฝ๋๋ง ๋ด์ต๋๋ค. ๋ค๋ฅธ ๋ช
๋ น ์คํ ํ ์ด์ `$?`๋ฅผ ์ฐธ์กฐํ๋ ค๋ฉด ๋ณ์์ ์ ์ฅํด์ผ ํฉ๋๋ค.",
|
| 959 |
+
"keywords": [
|
| 960 |
+
"exit code",
|
| 961 |
+
"$?",
|
| 962 |
+
"&&",
|
| 963 |
+
"||",
|
| 964 |
+
"return code",
|
| 965 |
+
"0=success"
|
| 966 |
+
],
|
| 967 |
+
"source_id": "linux-bash-cd",
|
| 968 |
+
"details": [
|
| 969 |
+
"`&&`๋ ์ ๋ช
๋ น์ด ์ฑ๊ณต(exit 0)ํ ๋๋ง ๋ค๋ฅผ ์คํ. `||`๋ ์คํจ(exit โ 0)ํ ๋๋ง ๋ค๋ฅผ ์คํํฉ๋๋ค.",
|
| 970 |
+
"์์ฃผ ๋ณด๋ ์ฝ๋: 0=์ฑ๊ณต, 1=์ผ๋ฐ ์ค๋ฅ, 2=๋ช
๋ น ์ค์ฉ, 126=์คํ ๊ถํ ์์, 127=๋ช
๋ น ์์, 130=Ctrl+C.",
|
| 971 |
+
"์ํ ํจํด: `&&`์ `||`๋ก ์กฐ๊ฑด๋ถ ์คํ์ ์์ฑํ๊ฑฐ๋, `$?` ๊ฐ์ผ๋ก ์ด์ ๋ช
๋ น ์ฑ๊ณต ์ฌ๋ถ๋ฅผ ํ๋จํ๋ ์คํฌ๋ฆฝํธ ๋ฌธ์ ๊ฐ ์ถ์ ๋ฉ๋๋ค."
|
| 972 |
+
]
|
| 973 |
+
},
|
| 974 |
+
{
|
| 975 |
+
"id": "linux-service-port",
|
| 976 |
+
"certification": "LFCS / ๋ฆฌ๋
์ค๋ง์คํฐ",
|
| 977 |
+
"title": "์๋น์ค์ ํฌํธ ์ฐ๊ฒฐ",
|
| 978 |
+
"summary": "์คํ ์ค์ธ ์๋น์ค๊ฐ ์ด๋ ํฌํธ๋ฅผ ์ด๊ณ ์๋์ง ํ์ธํ๊ณ , ๋ฐฉํ๋ฒฝ ์ค์ ๊ณผ ํจ๊ป ํฌํธ ์ ๊ทผ์ ์ ์ดํฉ๋๋ค.",
|
| 979 |
+
"example": "ss -tlnp | grep 80\ncat /etc/services | grep ssh\nlsof -i :443\nufw allow 80/tcp",
|
| 980 |
+
"common_mistake": "ํฌํธ๋ฅผ ์ด์์ด๋ ๋ฐฉํ๋ฒฝ(ufw/firewalld)์ด ์ฐจ๋จํ๋ฉด ์ธ๋ถ์์ ์ ๊ทผํ ์ ์์ต๋๋ค. ์๋น์ค์ ๋ฐฉํ๋ฒฝ์ ํจ๊ป ํ์ธํ์ธ์.",
|
| 981 |
+
"keywords": [
|
| 982 |
+
"ss",
|
| 983 |
+
"lsof",
|
| 984 |
+
"/etc/services",
|
| 985 |
+
"port",
|
| 986 |
+
"firewall",
|
| 987 |
+
"ufw"
|
| 988 |
+
],
|
| 989 |
+
"source_id": "ubuntu-networking",
|
| 990 |
+
"details": [
|
| 991 |
+
"`ss -tlnp`๋ TCP ๋ฆฌ์ค๋ ํฌํธ์ ์๋น์ค๋ฅผ ๋ณด์ฌ์ค๋๋ค. `lsof -i :ํฌํธ`๋ ํด๋น ํฌํธ๋ฅผ ์ฌ์ฉํ๋ ํ๋ก์ธ์ค๋ฅผ ์ฐพ์ต๋๋ค.",
|
| 992 |
+
"`/etc/services`๋ ํฌํธ ๋ฒํธ์ ์๋น์ค ์ด๋ฆ ๋งคํ ํ์ผ์
๋๋ค. 22=ssh, 80=http, 443=https, 3306=mysql.",
|
| 993 |
+
"์ํ ํจํด: ํน์ ํฌํธ๋ฅผ ๋ฆฌ์ค๋ํ๋ ์๋น์ค ํ์ธ, ๋ฐฉํ๋ฒฝ์์ ํฌํธ ๊ฐ๋ฐฉ, ์๋น์ค ํฌํธ ๋ฒํธ๋ฅผ ์กฐํํ๋ ๋ฌธ์ ๊ฐ ์ถ์ ๋ฉ๋๋ค."
|
| 994 |
+
]
|
| 995 |
+
},
|
| 996 |
+
{
|
| 997 |
+
"id": "linux-apt",
|
| 998 |
+
"certification": "LFCS / ๋ฆฌ๋
์ค๋ง์คํฐ",
|
| 999 |
+
"title": "apt โ ํจํค์ง ๊ด๋ฆฌ",
|
| 1000 |
+
"summary": "Ubuntu/Debian ๊ณ์ด์ ํจํค์ง ๊ด๋ฆฌ ๋๊ตฌ์
๋๋ค. ํจํค์ง ์ค์น, ์
๋ฐ์ดํธ, ๊ฒ์, ์ญ์ ๋ฅผ ๋ด๋นํฉ๋๋ค.",
|
| 1001 |
+
"example": "apt update && apt upgrade -y\napt install nginx\napt search 'web server'\napt show nginx\napt list --installed | grep nginx",
|
| 1002 |
+
"common_mistake": "`apt install` ์ ์ `apt update`๋ฅผ ๋จผ์ ์คํํด์ผ ์ต์ ํจํค์ง ๋ชฉ๋ก์์ ์ค์น๋ฉ๋๋ค. update ์์ด ์ค์นํ๋ฉด ๊ตฌ๋ฒ์ ์ด ์ค์น๋ ์ ์์ต๋๋ค.",
|
| 1003 |
+
"keywords": [
|
| 1004 |
+
"apt",
|
| 1005 |
+
"apt update",
|
| 1006 |
+
"apt install",
|
| 1007 |
+
"apt upgrade",
|
| 1008 |
+
"dpkg"
|
| 1009 |
+
],
|
| 1010 |
+
"source_id": "ubuntu-package-management",
|
| 1011 |
+
"details": [
|
| 1012 |
+
"`apt update`๋ ํจํค์ง ๋ชฉ๋ก๋ง ๊ฐฑ์ , `apt upgrade`๋ ์ค์ ์
๋ฐ์ดํธ ์ค์น. ํญ์ update โ upgrade ์์๋ก ์คํํฉ๋๋ค.",
|
| 1013 |
+
"`dpkg -l | grep ํจํค์ง`๋ก ์ค์น ์ฌ๋ถ ํ์ธ, `dpkg -L ํจํค์ง`๋ก ์ค์น๋ ํ์ผ ๋ชฉ๋ก์ ๋ณผ ์ ์์ต๋๋ค.",
|
| 1014 |
+
"์ํ ํจํด: ํน์ ํจํค์ง ์ค์น, ์ค์น ์ฌ๋ถ ํ์ธ, ๋ชจ๋ ํจํค์ง ์
๋ฐ์ดํธํ๋ ๋ช
๋ น์ ์์ฑํ๋ ๋ฌธ์ ๊ฐ ์ถ์ ๋ฉ๋๋ค."
|
| 1015 |
+
]
|
| 1016 |
+
},
|
| 1017 |
+
{
|
| 1018 |
+
"id": "linux-repo",
|
| 1019 |
+
"certification": "LFCS / ๋ฆฌ๋
์ค๋ง์คํฐ",
|
| 1020 |
+
"title": "APT ์ ์ฅ์ ๊ด๋ฆฌ",
|
| 1021 |
+
"summary": "ํจํค์ง๋ฅผ ๋ค์ด๋ก๋ํ๋ ์ ์ฅ์(repository) ๋ชฉ๋ก์ ๊ด๋ฆฌํฉ๋๋ค. `/etc/apt/sources.list` ๋๋ `/etc/apt/sources.list.d/`์ ์ ์ฅ์๋ฅผ ์ถ๊ฐํฉ๋๋ค.",
|
| 1022 |
+
"example": "cat /etc/apt/sources.list\nadd-apt-repository ppa:name/repo\napt-key add key.gpg # ๊ตฌ์\ncurl -fsSL URL | gpg --dearmor > /etc/apt/keyrings/key.gpg",
|
| 1023 |
+
"common_mistake": "์ธ๋ถ ์ ์ฅ์๋ฅผ ์ถ๊ฐํ ๋ GPG ํค๋ ํจ๊ป ๋ฑ๋กํด์ผ ํฉ๋๋ค. ํค ์์ด ์ ์ฅ์๋ง ์ถ๊ฐํ๋ฉด `apt update` ์ ์๋ช
์ค๋ฅ๊ฐ ๋ฉ๋๋ค.",
|
| 1024 |
+
"keywords": [
|
| 1025 |
+
"sources.list",
|
| 1026 |
+
"PPA",
|
| 1027 |
+
"repository",
|
| 1028 |
+
"gpg",
|
| 1029 |
+
"apt-key",
|
| 1030 |
+
"add-apt-repository"
|
| 1031 |
+
],
|
| 1032 |
+
"source_id": "ubuntu-package-management",
|
| 1033 |
+
"details": [
|
| 1034 |
+
"`/etc/apt/sources.list.d/`์ ๊ฐ๋ณ `.list` ํ์ผ์ ๋ฃ๋ ๋ฐฉ์์ด ๊ด๋ฆฌ๊ฐ ์ฝ์ต๋๋ค. ์ฃผ sources.list๋ ๊ฐ๊ธ์ ์์ ํ์ง ์์ต๋๋ค.",
|
| 1035 |
+
"์ต์ ๋ฐฉ์์ GPG ํค๋ฅผ `/etc/apt/keyrings/`์ ์ ์ฅํ๊ณ sources ํ์ผ์์ `signed-by=` ์ต์
์ผ๋ก ์ฐธ์กฐํฉ๋๋ค.",
|
| 1036 |
+
"์ํ ํจํด: ์ ์ฅ์ ์ถ๊ฐ ํ `apt update`, ํจํค์ง ์ค์น๊น์ง ์ด์ด์ง๋ ์ ์ฐจ๋ฅผ ์์ฑํ๋ ๋ฌธ์ ๊ฐ ์ถ์ ๋ฉ๋๋ค."
|
| 1037 |
+
]
|
| 1038 |
+
},
|
| 1039 |
+
{
|
| 1040 |
+
"id": "linux-remove-purge",
|
| 1041 |
+
"certification": "LFCS / ๋ฆฌ๋
์ค๋ง์คํฐ",
|
| 1042 |
+
"title": "ํจํค์ง ์ ๊ฑฐ โ remove์ purge",
|
| 1043 |
+
"summary": "`apt remove`๋ ํจํค์ง ๋ฐ์ด๋๋ฆฌ๋ง ์ ๊ฑฐํ๊ณ ์ค์ ํ์ผ์ ๋จ๊น๋๋ค. `apt purge`๋ ์ค์ ํ์ผ๊น์ง ์์ ํ ์ ๊ฑฐํฉ๋๋ค.",
|
| 1044 |
+
"example": "apt remove nginx\napt purge nginx\napt autoremove # ์์กด์ฑ์ผ๋ก๋ง ์ค์น๋ ๋ถํ์ ํจํค์ง ์ ๊ฑฐ\ndpkg --list | grep ^rc # ์ค์ ๋จ์ ์ ๊ฑฐ๋ ํจํค์ง",
|
| 1045 |
+
"common_mistake": "`remove` ํ ์ฌ์ค์นํ๋ฉด ์ด์ ์ค์ ํ์ผ์ด ๋จ์ ์์ด ์์์น ๋ชปํ ๋์์ ํ ์ ์์ต๋๋ค. ๊นจ๋์ด ์ ๊ฑฐํ๋ ค๋ฉด `purge`๋ฅผ ์๋๋ค.",
|
| 1046 |
+
"keywords": [
|
| 1047 |
+
"apt remove",
|
| 1048 |
+
"apt purge",
|
| 1049 |
+
"autoremove",
|
| 1050 |
+
"dpkg --purge"
|
| 1051 |
+
],
|
| 1052 |
+
"source_id": "ubuntu-package-management",
|
| 1053 |
+
"details": [
|
| 1054 |
+
"`apt autoremove`๋ ๋ค๋ฅธ ํจํค์ง์ ์์กด์ฑ์ผ๋ก ์ค์น๋๋ค๊ฐ ๋ ์ด์ ํ์ ์๋ ํจํค์ง๋ค์ ์๋์ผ๋ก ์ ๊ฑฐํฉ๋๋ค.",
|
| 1055 |
+
"`dpkg --list | grep '^rc'`๋ก ๋ฐ์ด๋๋ฆฌ๋ ์ง์์ก์ง๋ง ์ค์ ํ์ผ์ด ๋จ์ ํจํค์ง๋ฅผ ์ฐพ์ ์ ์์ต๋๋ค.",
|
| 1056 |
+
"์ํ ํจํด: ํจํค์ง๋ฅผ ์ค์ ํ์ผ๊น์ง ์์ ํ ์ ๊ฑฐํ๊ฑฐ๋, ๋ถํ์ ์์กด์ฑ์ ์ ๋ฆฌํ๋ ๋ช
๋ น์ ์์ฑํ๋ ๋ฌธ์ ๊ฐ ์ถ์ ๋ฉ๋๋ค."
|
| 1057 |
+
]
|
| 1058 |
+
},
|
| 1059 |
+
{
|
| 1060 |
+
"id": "linux-ufw",
|
| 1061 |
+
"certification": "LFCS / ๋ฆฌ๋
์ค๋ง์คํฐ",
|
| 1062 |
+
"title": "ufw โ ๋ฐฉํ๋ฒฝ ๊ด๋ฆฌ",
|
| 1063 |
+
"summary": "Ubuntu์ ๊ฐ๋จํ ๋ฐฉํ๋ฒฝ ๊ด๋ฆฌ ๋๊ตฌ์
๋๋ค. iptables ์์์ ๋์ํ๋ฉฐ ์๋น์ค ์ด๋ฆ์ด๋ ํฌํธ๋ก ๊ท์น์ ์ถ๊ฐํ ์ ์์ต๋๋ค.",
|
| 1064 |
+
"example": "ufw status verbose\nufw enable\nufw allow 22/tcp\nufw allow 'Nginx Full'\nufw deny 3306\nufw delete allow 80",
|
| 1065 |
+
"common_mistake": "`ufw enable` ์ ์ ๋ฐ๋์ SSH ํฌํธ(22)๋ฅผ ํ์ฉํ์ธ์. ์์๋ฅผ ๋ฐ๊พธ๋ฉด SSH ์ฐ๊ฒฐ์ด ๋๊ฒจ ์๋ฒ์ ์ ๊ทผํ์ง ๋ชปํฉ๋๋ค.",
|
| 1066 |
+
"keywords": [
|
| 1067 |
+
"ufw",
|
| 1068 |
+
"enable",
|
| 1069 |
+
"allow",
|
| 1070 |
+
"deny",
|
| 1071 |
+
"status",
|
| 1072 |
+
"firewall"
|
| 1073 |
+
],
|
| 1074 |
+
"source_id": "ubuntu-firewall",
|
| 1075 |
+
"details": [
|
| 1076 |
+
"๊ท์น ์ถ๊ฐ ํ์: `ufw allow/deny ํฌํธ/ํ๋กํ ์ฝ` ๋๋ `ufw allow 'Apache'`์ฒ๋ผ ์ฌ์ ์ ์๋ ์ ํ๋ฆฌ์ผ์ด์
ํ๋กํ ์ฌ์ฉ.",
|
| 1077 |
+
"`ufw status numbered`๋ก ๋ฒํธ๊ฐ ๋ถ์ ๊ท์น ๋ชฉ๋ก ํ์ธ ํ `ufw delete ๋ฒํธ`๋ก ํน์ ๊ท์น์ ์ญ์ ํฉ๋๋ค.",
|
| 1078 |
+
"์ํ ํจํด: ํน์ ํฌํธ ๊ฐ๋ฐฉ/์ฐจ๋จ, SSH๋ ํ์ฉํ๋ฉด์ ๋ถํ์ํ ํฌํธ ์ฐจ๋จ, ๋ฐฉํ๋ฒฝ ์ํ ํ์ธ ๋ช
๋ น์ด ์ถ์ ๋ฉ๋๋ค."
|
| 1079 |
+
]
|
| 1080 |
+
},
|
| 1081 |
+
{
|
| 1082 |
+
"id": "linux-head-tail",
|
| 1083 |
+
"certification": "LFCS / ๋ฆฌ๋
์ค๋ง์คํฐ",
|
| 1084 |
+
"title": "head, tail โ ํ์ผ ์๋ค ํ์ธ",
|
| 1085 |
+
"summary": "`head`๋ ํ์ผ ์ฒ์ N์ค, `tail`์ ๋ง์ง๋ง N์ค์ ์ถ๋ ฅํฉ๋๋ค. `tail -f`๋ ๋ก๊ทธ ํ์ผ์ ์ถ๊ฐ๋๋ ๋ด์ฉ์ ์ค์๊ฐ์ผ๋ก ์ถ์ ํฉ๋๋ค.",
|
| 1086 |
+
"example": "head -n 20 /etc/passwd\ntail -n 50 /var/log/syslog\ntail -f /var/log/nginx/error.log\ntail -f /var/log/syslog | grep ERROR",
|
| 1087 |
+
"common_mistake": "`head`๋ ํ์ผ ์์, `tail`์ ํ์ผ ๋์์ ์ฝ์ต๋๋ค. `-n` ์์ด ์ฐ๋ฉด ๊ธฐ๋ณธ 10์ค์ ์ถ๋ ฅํฉ๋๋ค.",
|
| 1088 |
+
"keywords": [
|
| 1089 |
+
"head",
|
| 1090 |
+
"tail",
|
| 1091 |
+
"-n",
|
| 1092 |
+
"-f",
|
| 1093 |
+
"log",
|
| 1094 |
+
"follow"
|
| 1095 |
+
],
|
| 1096 |
+
"source_id": "linux-bash-manual",
|
| 1097 |
+
"details": [
|
| 1098 |
+
"`tail -f`๋ ํ์ผ์ ์๋ก ์ถ๊ฐ๋๋ ๋ด์ฉ์ ์ค์๊ฐ์ผ๋ก ๋ณด์ฌ์ค๋๋ค. ์๋น์ค ๋ก๊ทธ ๋ชจ๋ํฐ๋ง ์ ๊ฐ์ฅ ๋ง์ด ์๋๋ค.",
|
| 1099 |
+
"`tail -n +5`๋ 5๋ฒ์งธ ์ค๋ถํฐ ๋๊น์ง ์ถ๋ ฅํฉ๋๋ค. ํค๋ ํ์ ๊ฑด๋๋ธ ๋ ํ์ฉํฉ๋๋ค.",
|
| 1100 |
+
"์ํ ํจํด: ๋ก๊ทธ ๋ง์ง๋ง N์ค ํ์ธ, ์ค์๊ฐ ๋ก๊ทธ ์ถ์ , ํ์ดํ๋ก grep๊ณผ ์ฐ๊ฒฐํ๋ ๋ช
๋ น์ด ์ถ์ ๋ฉ๋๋ค."
|
| 1101 |
+
]
|
| 1102 |
+
},
|
| 1103 |
+
{
|
| 1104 |
+
"id": "linux-sed",
|
| 1105 |
+
"certification": "LFCS / ๋ฆฌ๋
์ค๋ง์คํฐ",
|
| 1106 |
+
"title": "sed โ ์คํธ๋ฆผ ํธ์ง๊ธฐ",
|
| 1107 |
+
"summary": "ํ์ผ์ด๋ ํ์ดํ ์
๋ ฅ์์ ํจํด์ ์ฐพ์ ๊ต์ฒดยท์ญ์ ยท์ถ๋ ฅํฉ๋๋ค. ์ค์ ํ์ผ ์๋ ์์ ๊ณผ ํ
์คํธ ๋ณํ ์คํฌ๋ฆฝํธ์ ํ์์
๋๋ค.",
|
| 1108 |
+
"example": "sed 's/old/new/g' file.txt\nsed -i 's/localhost/127.0.0.1/g' nginx.conf\nsed -n '5,10p' file.txt # 5~10์ค๋ง ์ถ๋ ฅ\nsed '/^#/d' config.txt # ์ฃผ์ ์ค ์ญ์ ",
|
| 1109 |
+
"common_mistake": "`-i` ์์ด๋ ์๋ณธ์ ์์ ํ์ง ์๊ณ stdout์ผ๋ก๋ง ์ถ๋ ฅํฉ๋๋ค. `-i.bak`์ผ๋ก ์๋ณธ์ ๋ฐฑ์
ํ๋ฉด์ ์์ ํ ์ ์์ต๋๋ค.",
|
| 1110 |
+
"keywords": [
|
| 1111 |
+
"sed",
|
| 1112 |
+
"s/old/new/g",
|
| 1113 |
+
"-i",
|
| 1114 |
+
"stream editor",
|
| 1115 |
+
"substitute",
|
| 1116 |
+
"delete"
|
| 1117 |
+
],
|
| 1118 |
+
"source_id": "linux-bash-manual",
|
| 1119 |
+
"details": [
|
| 1120 |
+
"์นํ ๋ช
๋ น: `s/ํจํด/๊ต์ฒด/g`. `g` ํ๋๊ทธ ์์ผ๋ฉด ์ค๋น ์ฒซ ๋ฒ์งธ๋ง, `I` ํ๋๊ทธ๋ ๋์๋ฌธ์ ๋ฌด์.",
|
| 1121 |
+
"์ค ๋จ์ ์์
: `Nd`(N๋ฒ ์ค ์ญ์ ), `Np`(N๋ฒ ์ค๋ง ์ถ๋ ฅ, `-n`๊ณผ ํจ๊ป), `/ํจํด/d`(ํจํด ์ค ์ญ์ ).",
|
| 1122 |
+
"์ํ ํจํด: ์ค์ ํ์ผ์์ ๊ฐ์ ์นํํ๊ฑฐ๋(`-i`), ํน์ ์ค์ ์ถ๋ ฅ/์ญ์ ํ๋ ๋ช
๋ น์ ์์ฑํ๋ ๋ฌธ์ ๊ฐ ์ถ์ ๋ฉ๋๋ค."
|
| 1123 |
+
]
|
| 1124 |
+
},
|
| 1125 |
+
{
|
| 1126 |
+
"id": "linux-text-pipeline",
|
| 1127 |
+
"certification": "LFCS / ๋ฆฌ๋
์ค๋ง์คํฐ",
|
| 1128 |
+
"title": "ํ
์คํธ ์ฒ๋ฆฌ โ cut, sort, uniq, wc",
|
| 1129 |
+
"summary": "ํ
์คํธ ํ์ดํ๋ผ์ธ์ ๊ตฌ์ฑํ๋ ํต์ฌ ๋๊ตฌ๋ค์
๋๋ค. ํ๋ ์ถ์ถ(cut), ์ ๋ ฌ(sort), ์ค๋ณต ์ ๊ฑฐ(uniq), ์ค/๋จ์ด ์ ์ธ๊ธฐ(wc)๋ฅผ ํ์ดํ๋ก ์ฐ๊ฒฐํฉ๋๋ค.",
|
| 1130 |
+
"example": "cut -d':' -f1 /etc/passwd | sort | uniq\nwc -l /var/log/syslog\ncat access.log | cut -d' ' -f1 | sort | uniq -c | sort -rn | head -10",
|
| 1131 |
+
"common_mistake": "`uniq`๋ ์ฐ์๋ ์ค๋ณต๋ง ์ ๊ฑฐํฉ๋๋ค. ์ ์ฒด ์ค๋ณต ์ ๊ฑฐ๋ฅผ ์ํด์๋ ๋ฐ๋์ `sort` ํ `uniq`๋ฅผ ์จ์ผ ํฉ๋๋ค.",
|
| 1132 |
+
"keywords": [
|
| 1133 |
+
"cut",
|
| 1134 |
+
"sort",
|
| 1135 |
+
"uniq",
|
| 1136 |
+
"wc",
|
| 1137 |
+
"-d",
|
| 1138 |
+
"-f",
|
| 1139 |
+
"-c",
|
| 1140 |
+
"-rn"
|
| 1141 |
+
],
|
| 1142 |
+
"source_id": "linux-bash-manual",
|
| 1143 |
+
"details": [
|
| 1144 |
+
"`cut -d๊ตฌ๋ถ์ -fํ๋๋ฒํธ`: ์ฝ๋ก ๊ตฌ๋ถ์์์ 1๋ฒ ํ๋ โ `cut -d':' -f1`. ์ฌ๋ฌ ํ๋๋ `-f1,3` ๋๋ `-f1-3`.",
|
| 1145 |
+
"`sort -rn`: r=์ญ์, n=์ซ์ ์ ๋ ฌ. `uniq -c`๋ ์ค๋ณต ๊ฐ์๋ฅผ ์์ ๋ถ์ฌ ์ค๋๋ค.",
|
| 1146 |
+
"์ํ ํจํด: ๋ก๊ทธ์์ ์์ ์ ์ IP ์ถ์ถ, ์ค๋ณต ์ ๊ฑฐ ํ ์ ๋ ฌ, ์ค ์ ์ธ๊ธฐ ๋ฑ ํ์ดํ๋ผ์ธ์ ์กฐํฉํ๋ ๋ฌธ์ ๊ฐ ์ถ์ ๋ฉ๋๋ค."
|
| 1147 |
+
]
|
| 1148 |
+
},
|
| 1149 |
+
{
|
| 1150 |
+
"id": "linux-awk",
|
| 1151 |
+
"certification": "LFCS / ๋ฆฌ๋
์ค๋ง์คํฐ",
|
| 1152 |
+
"title": "awk โ ํ๋ ๊ธฐ๋ฐ ํ
์คํธ ์ฒ๋ฆฌ",
|
| 1153 |
+
"summary": "๊ณต๋ฐฑ์ด๋ ์ง์ ๊ตฌ๋ถ์๋ก ๋๋ ํ๋๋ฅผ ์ฒ๋ฆฌํฉ๋๋ค. `cut`๋ณด๋ค ๊ฐ๋ ฅํ๋ฉฐ ์กฐ๊ฑด๋ฌธ, ์ฐ์ฐ, ํฉ์ฐ์ด ๊ฐ๋ฅํฉ๋๋ค.",
|
| 1154 |
+
"example": "awk '{print $1, $3}' access.log\nawk -F':' '{print $1}' /etc/passwd\nawk '$3 > 1000 {print $1}' /etc/passwd\nps aux | awk '{print $1, $11}' | head",
|
| 1155 |
+
"common_mistake": "awk์์ `$0`์ ์ค ์ ์ฒด, `$1`์ ์ฒซ ๋ฒ์งธ ํ๋์
๋๋ค. `-F`๋ก ๊ตฌ๋ถ์๋ฅผ ๋ฐ๊พธ์ง ์์ผ๋ฉด ๊ธฐ๋ณธ์ผ๋ก ๊ณต๋ฐฑ/ํญ์ด ๊ตฌ๋ถ์์
๋๋ค.",
|
| 1156 |
+
"keywords": [
|
| 1157 |
+
"awk",
|
| 1158 |
+
"-F",
|
| 1159 |
+
"$1",
|
| 1160 |
+
"NR",
|
| 1161 |
+
"NF",
|
| 1162 |
+
"print",
|
| 1163 |
+
"field"
|
| 1164 |
+
],
|
| 1165 |
+
"source_id": "linux-bash-manual",
|
| 1166 |
+
"details": [
|
| 1167 |
+
"๊ธฐ๋ณธ ํจํด: `awk '์กฐ๊ฑด {๋์}' ํ์ผ`. ์กฐ๊ฑด ์์ด `{print $2}`๋ง ์ฐ๋ฉด ๋ชจ๋ ์ค์์ 2๋ฒ์งธ ํ๋๋ฅผ ์ถ๋ ฅํฉ๋๋ค.",
|
| 1168 |
+
"๋ด์ฅ ๋ณ์: `NR`=ํ์ฌ ์ค ๋ฒํธ, `NF`=ํ๋ ๊ฐ์. `NR==1`์ ์ฒซ ๋ฒ์งธ ์ค๋ง, `$NF`๋ ๋ง์ง๋ง ํ๋์
๋๋ค.",
|
| 1169 |
+
"์ํ ํจํด: ํน์ ํ๋๋ง ์ถ๋ ฅํ๊ฑฐ๋, ์กฐ๊ฑด์ ๋ง๋ ์ค๋ง ์ถ๋ ฅํ๋ awk ๋ช
๋ น์ ์์ฑํ๋ ๋ฌธ์ ๊ฐ ์ถ์ ๋ฉ๋๋ค."
|
| 1170 |
+
]
|
| 1171 |
+
},
|
| 1172 |
+
{
|
| 1173 |
+
"id": "linux-ln-symlink",
|
| 1174 |
+
"certification": "LFCS / ๋ฆฌ๋
์ค๋ง์คํฐ",
|
| 1175 |
+
"title": "ln โ ํ๋ ๋งํฌ์ ์ฌ๋ณผ๋ฆญ ๋งํฌ",
|
| 1176 |
+
"summary": "์ฌ๋ณผ๋ฆญ ๋งํฌ(`ln -s`)๋ ์๋ณธ ํ์ผ์ ๊ฒฝ๋ก๋ฅผ ๊ฐ๋ฆฌํค๋ ํฌ์ธํฐ์
๋๋ค. ํ๋ ๋งํฌ๋ ๊ฐ์ inode๋ฅผ ์ง์ ์ฐธ์กฐํฉ๋๋ค.",
|
| 1177 |
+
"example": "ln -s /etc/nginx/nginx.conf ~/nginx.conf\nln /data/file.txt /backup/file.txt # ํ๋ ๋งํฌ\nls -la ~/nginx.conf # -> ์๋ณธ ๊ฒฝ๋ก ํ์\nreadlink -f ~/nginx.conf # ์ค์ ๊ฒฝ๋ก ํ์ธ",
|
| 1178 |
+
"common_mistake": "์ฌ๋ณผ๋ฆญ ๋งํฌ๋ ์๋ณธ์ด ์ญ์ ๋๋ฉด ๋๊ธด ๋งํฌ(dangling symlink)๊ฐ ๋ฉ๋๋ค. ํ๋ ๋งํฌ๋ ์๋ณธ ์ญ์ ํ์๋ ๋ฐ์ดํฐ๊ฐ ์ ์ง๋ฉ๋๋ค.",
|
| 1179 |
+
"keywords": [
|
| 1180 |
+
"ln",
|
| 1181 |
+
"-s",
|
| 1182 |
+
"symlink",
|
| 1183 |
+
"hard link",
|
| 1184 |
+
"inode",
|
| 1185 |
+
"readlink"
|
| 1186 |
+
],
|
| 1187 |
+
"source_id": "linux-bash-manual",
|
| 1188 |
+
"details": [
|
| 1189 |
+
"์ฌ๋ณผ๋ฆญ ๋งํฌ: `ln -s ์๋ณธ๊ฒฝ๋ก ๋งํฌ๊ฒฝ๋ก`. `ls -la`์์ `l`๋ก ์์ํ๋ฉฐ `->` ๋ค์ ์๋ณธ ๊ฒฝ๋ก๊ฐ ํ์๋ฉ๋๋ค.",
|
| 1190 |
+
"ํ๋ ๋งํฌ๋ ๊ฐ์ ํํฐ์
๋ด์์๋ง ๊ฐ๋ฅ, ๋๋ ํฐ๋ฆฌ์๋ ์ฌ์ฉ ๋ถ๊ฐ. ์ฌ๋ณผ๋ฆญ ๋งํฌ๋ ํํฐ์
๊ณผ ๋๋ ํฐ๋ฆฌ ๋ชจ๋ ๊ฐ๋ฅํฉ๋๋ค.",
|
| 1191 |
+
"์ํ ํจํด: ํน์ ๊ฒฝ๋ก์ ์ฌ๋ณผ๋ฆญ ๋งํฌ๋ฅผ ๋ง๋ค๊ฑฐ๋, ๋งํฌ ํ์
์ `ls -la`๋ก ๊ตฌ๋ณํ๋ ๋ฌธ์ ๊ฐ ์ถ์ ๋ฉ๋๋ค."
|
| 1192 |
+
]
|
| 1193 |
+
},
|
| 1194 |
+
{
|
| 1195 |
+
"id": "linux-bg-fg-jobs",
|
| 1196 |
+
"certification": "LFCS / ๋ฆฌ๋
์ค๋ง์คํฐ",
|
| 1197 |
+
"title": "๋ฐฑ๊ทธ๋ผ์ด๋ ์์
โ jobs, bg, fg, nohup",
|
| 1198 |
+
"summary": "ํฐ๋ฏธ๋์ ๋ธ๋กํ์ง ์๊ณ ๋ช
๋ น์ ๋ฐฑ๊ทธ๋ผ์ด๋์์ ์คํํฉ๋๋ค. `&`๋ก ์์, `Ctrl+Z`๋ก ์ผ์ ์ ์ง, `fg`/`bg`๋ก ์ ํํฉ๋๋ค.",
|
| 1199 |
+
"example": "long_task.sh & # ๋ฐฑ๊ทธ๋ผ์ด๋ ์์\njobs -l # ์์
๋ชฉ๋ก\nfg %1 # 1๋ฒ ์์
ํฌ๊ทธ๋ผ์ด๋ ๋ณต๊ท\nnohup ./script.sh & # ํฐ๋ฏธ๋ ๋ซํ๋ ๊ณ์ ์คํ",
|
| 1200 |
+
"common_mistake": "`&`๋ก ์คํํ ์์
์ ํฐ๋ฏธ๋์ ๋ซ์ผ๋ฉด ์ข
๋ฃ๋ฉ๋๋ค. ํฐ๋ฏธ๋ ์ข
๋ฃ ํ์๋ ๊ณ์ ์คํํ๋ ค๋ฉด `nohup`์ ํจ๊ป ์จ์ผ ํฉ๋๋ค.",
|
| 1201 |
+
"keywords": [
|
| 1202 |
+
"jobs",
|
| 1203 |
+
"bg",
|
| 1204 |
+
"fg",
|
| 1205 |
+
"nohup",
|
| 1206 |
+
"&",
|
| 1207 |
+
"Ctrl+Z",
|
| 1208 |
+
"SIGHUP"
|
| 1209 |
+
],
|
| 1210 |
+
"source_id": "linux-bash-cd",
|
| 1211 |
+
"details": [
|
| 1212 |
+
"`Ctrl+Z`๋ ํ์ฌ ํ๋ก์ธ์ค์ SIGTSTP๋ฅผ ๋ณด๋ด ์ผ์ ์ ์ง. `bg`๋ก ๋ฐฑ๊ทธ๋ผ์ด๋ ์ฌ๊ฐ, `fg`๋ก ํฌ๊ทธ๋ผ์ด๋ ๋ณต๊ท.",
|
| 1213 |
+
"`nohup ๋ช
๋ น &`: SIGHUP ์๊ทธ๋์ ๋ฌด์ํ๋ฏ๋ก ํฐ๋ฏธ๋ ์ข
๋ฃ ํ์๋ ์คํ ์ ์ง. ์ถ๋ ฅ์ ๊ธฐ๋ณธ์ผ๋ก `nohup.out`์ ์ ์ฅ๋ฉ๋๋ค.",
|
| 1214 |
+
"์ํ ํจํด: ์์
์ ๋ฐฑ๊ทธ๋ผ์ด๋๋ก ๋ณด๋ด๊ฑฐ๋ ๋ณต๊ท์ํค๋ ๋ช
๋ น, nohup ์ฌ์ฉ ์๋๋ฆฌ์ค ๋ฌธ์ ๊ฐ ์ถ์ ๋ฉ๋๋ค."
|
| 1215 |
+
]
|
| 1216 |
+
},
|
| 1217 |
+
{
|
| 1218 |
+
"id": "linux-shell-script-basics",
|
| 1219 |
+
"certification": "LFCS / ๋ฆฌ๋
์ค๋ง์คํฐ",
|
| 1220 |
+
"title": "์ ์คํฌ๋ฆฝํธ ๊ธฐ์ด",
|
| 1221 |
+
"summary": "๋ฐ๋ณต ์์
์ ์๋ํํ๋ ๋ฐฐ์ ์คํฌ๋ฆฝํธ๋ฅผ ์์ฑํฉ๋๋ค. shebang ๋ผ์ธ, ๋ณ์, ์กฐ๊ฑด๋ฌธ, ๋ฐ๋ณต๋ฌธ, ํจ์๊ฐ ํต์ฌ ์์์
๋๋ค.",
|
| 1222 |
+
"example": "#!/bin/bash\nset -euo pipefail\nBACKUP_DIR=/backup\n[ -d $BACKUP_DIR ] || mkdir -p $BACKUP_DIR\nfor f in /etc/*.conf; do\n cp $f $BACKUP_DIR/\ndone",
|
| 1223 |
+
"common_mistake": "`#!/bin/bash`(shebang)๊ฐ ์์ผ๋ฉด `/bin/sh`๋ก ์คํ๋ผ bash ์ ์ฉ ๋ฌธ๋ฒ์ด ์ค๋ฅ๋ฉ๋๋ค. ์คํ ๊ถํ(`chmod +x`)๋ ๋ฐ๋์ ํ์ธํ์ธ์.",
|
| 1224 |
+
"keywords": [
|
| 1225 |
+
"shebang",
|
| 1226 |
+
"#!/bin/bash",
|
| 1227 |
+
"if",
|
| 1228 |
+
"for",
|
| 1229 |
+
"while",
|
| 1230 |
+
"function",
|
| 1231 |
+
"chmod +x"
|
| 1232 |
+
],
|
| 1233 |
+
"source_id": "linux-bash-cd",
|
| 1234 |
+
"details": [
|
| 1235 |
+
"`set -euo pipefail`: `-e`(์๋ฌ ์ ์ฆ์ ์ข
๋ฃ), `-u`(๋ฏธ์ ์ ๋ณ์ ์ฌ์ฉ ์ ์๋ฌ), `-o pipefail`(ํ์ดํ ์ค๊ฐ ์คํจ ๊ฐ์ง). ์คํฌ๋ฆฝํธ ์๋จ์ ๊ถ์ฅ๋ฉ๋๋ค.",
|
| 1236 |
+
"์กฐ๊ฑด ํ์ธ: `[ -f ํ์ผ ]`(ํ์ผ ์กด์ฌ), `[ -d ๋๋ ํฐ๋ฆฌ ]`(๋๋ ํฐ๋ฆฌ ์กด์ฌ), `[ $var -eq 1 ]`(์ซ์ ๋น๊ต), `[[ $str == 'a' ]]`(๋ฌธ์์ด).",
|
| 1237 |
+
"์ํ ํจํด: ํน์ ์กฐ๊ฑด์ ๋ฐ๋ผ ๋ถ๊ธฐํ๋ if๋ฌธ, ํ์ผ ๋ชฉ๋ก์ ์ฒ๋ฆฌํ๋ for ๋ฃจํ, ํจ์ ์ ์ ๋ฑ ์คํฌ๋ฆฝํธ ์์ฑ ๋ฌธ์ ๊ฐ ์ถ์ ๋ฉ๋๋ค."
|
| 1238 |
+
]
|
| 1239 |
+
},
|
| 1240 |
+
{
|
| 1241 |
+
"id": "linux-cp-mv-rm",
|
| 1242 |
+
"certification": "LFCS / ๋ฆฌ๋
์ค๋ง์คํฐ",
|
| 1243 |
+
"title": "cp, mv, rm โ ํ์ผ ๋ณต์ฌยท์ด๋ยท์ญ์ ",
|
| 1244 |
+
"summary": "ํ์ผ๊ณผ ๋๋ ํฐ๋ฆฌ๋ฅผ ๋ณต์ฌ(`cp`), ์ด๋/์ด๋ฆ๋ณ๊ฒฝ(`mv`), ์ญ์ (`rm`)ํฉ๋๋ค. ๊ฐ ์ต์
์ ์กฐํฉ์ด ์ํ์์ ์๋๋ฆฌ์ค ํํ๋ก ์ถ์ ๋ฉ๋๋ค.",
|
| 1245 |
+
"example": "cp -a /etc/nginx /backup/nginx.bak # ๊ถํยทํ์์คํฌํ ๋ณด์กด ๋ณต์ฌ\nmv config.txt config.bak # ์ด๋ฆ ๋ณ๊ฒฝ\nrm -rf /tmp/old_build/ # ๋๋ ํฐ๋ฆฌ ๊ฐ์ ์ญ์ ",
|
| 1246 |
+
"common_mistake": "`cp -r`์ ๋๋ ํฐ๋ฆฌ๋ฅผ ๋ณต์ฌํ์ง๋ง ๊ถํ๊ณผ ํ์์คํฌํ๋ฅผ ๋ณด์กดํ์ง ์์ต๋๋ค. ๋ฐฑ์
๋ชฉ์ ์ด๋ผ๋ฉด ๋ฐ๋์ `cp -a`๋ฅผ ์ฌ์ฉํ์ธ์.",
|
| 1247 |
+
"keywords": [
|
| 1248 |
+
"cp",
|
| 1249 |
+
"mv",
|
| 1250 |
+
"rm",
|
| 1251 |
+
"-a",
|
| 1252 |
+
"-r",
|
| 1253 |
+
"-i",
|
| 1254 |
+
"-f",
|
| 1255 |
+
"๋ฐฑ์
"
|
| 1256 |
+
],
|
| 1257 |
+
"source_id": "manual-linux-basic",
|
| 1258 |
+
"details": [
|
| 1259 |
+
"**`cp` ํต์ฌ ์ต์
**: `-r`(๋๋ ํฐ๋ฆฌ ์ฌ๊ท), `-a`(archive: `-dR --preserve=all`, ๋ฐฑ์
์ ํ์ค), `-i`(๋ฎ์ด์ฐ๊ธฐ ์ ํ์ธ), `-p`(๊ถํยทํ์์คํฌํ ๋ณด์กด).",
|
| 1260 |
+
"**`mv`**: ๊ฐ์ ํ์ผ์์คํ
๋ด ์ด๋์ inode๋ง ๊ฐฑ์ ํด ๋น ๋ฆ
๋๋ค. ๋ค๋ฅธ ํํฐ์
๊ฐ ์ด๋์ ์ค์ ๋ณต์ฌ ํ ์ญ์ ๊ฐ ์ผ์ด๋ฉ๋๋ค.",
|
| 1261 |
+
"**์ํ ํจํด**: 'ํผ๋ฏธ์
์ ์ ์งํ๋ฉด์ ๋ฐฑ์
' โ `cp -a`, '์ค์ ์์ด ์ญ์ ' โ `rm -i`, 'force ์ญ์ ' โ `rm -f`."
|
| 1262 |
+
]
|
| 1263 |
+
},
|
| 1264 |
+
{
|
| 1265 |
+
"id": "linux-fdisk-parted",
|
| 1266 |
+
"certification": "LFCS / ๋ฆฌ๋
์ค๋ง์คํฐ",
|
| 1267 |
+
"title": "fdisk, parted โ ๋์คํฌ ํํฐ์
๋",
|
| 1268 |
+
"summary": "์ ๋์คํฌ๋ฅผ ์ฌ์ฉํ๊ธฐ ์ ํํฐ์
ํ
์ด๋ธ์ ๋ง๋ค๊ณ ํํฐ์
์ ๋๋๋๋ค. MBR์ `fdisk`, GPT(2TB ์ด์)๋ `parted` ๋๋ `gdisk`๋ฅผ ์ฌ์ฉํฉ๋๋ค.",
|
| 1269 |
+
"example": "fdisk /dev/sdb # MBR ํํฐ์
์ธํฐ๋ํฐ๋ธ ํธ์ง\n# n(์ ํํฐ์
) โ p โ 1 โ Enter โ +20G โ w(์ ์ฅ)\nparted /dev/sdc mklabel gpt\nparted /dev/sdc mkpart primary ext4 1MiB 21GiB",
|
| 1270 |
+
"common_mistake": "`fdisk`๋ ํํฐ์
ํ
์ด๋ธ์ ๋ณ๊ฒฝํด๋ `w`๋ก ์ ์ฅํ๊ธฐ ์ ๊น์ง ๋์คํฌ์ ๊ธฐ๋ก๋์ง ์์ต๋๋ค. ๋ํ 2TB ์ด๊ณผ ๋์คํฌ์๋ MBR(fdisk) ๋์ GPT(parted/gdisk)๋ฅผ ์ฌ์ฉํด์ผ ํฉ๋๋ค.",
|
| 1271 |
+
"keywords": [
|
| 1272 |
+
"fdisk",
|
| 1273 |
+
"parted",
|
| 1274 |
+
"gdisk",
|
| 1275 |
+
"MBR",
|
| 1276 |
+
"GPT",
|
| 1277 |
+
"partition table",
|
| 1278 |
+
"lsblk"
|
| 1279 |
+
],
|
| 1280 |
+
"source_id": "manual-linux-storage",
|
| 1281 |
+
"details": [
|
| 1282 |
+
"**ํํฐ์
ํ
์ด๋ธ ์ ํ**: MBR(์ต๋ 4 ์ฃผํํฐ์
, 2TB ํ๊ณ), GPT(์ต๋ 128 ํํฐ์
, ์ฌ์ค์ ๋ฌด์ ํ ์ฉ๋).",
|
| 1283 |
+
"**fdisk ํ๋ฆ**: `n`(์ ํํฐ์
) โ ์ ํ ์ ํ(p/e) โ ๋ฒํธ โ ์์/๋ ์นํฐ(๋๋ `+20G`) โ `w`(์ ์ฅ ํ ์ข
๋ฃ). `p`๋ก ํ์ฌ ์ํ ํ์ธ.",
|
| 1284 |
+
"**์ํ ํจํด**: lsblk๋ก ์ฅ์น ํ์ธ โ fdisk๋ก ํํฐ์
์์ฑ โ mkfs๋ก ํฌ๋งท โ mount ์์๊ฐ ์ ์ฒด ์คํ ๋ฆฌ์ง ์ค์ ํ๋ฆ์ผ๋ก ์์ฃผ ์ถ์ ๋ฉ๋๋ค."
|
| 1285 |
+
]
|
| 1286 |
+
},
|
| 1287 |
+
{
|
| 1288 |
+
"id": "linux-mkfs-fsck",
|
| 1289 |
+
"certification": "LFCS / ๋ฆฌ๋
์ค๋ง์คํฐ",
|
| 1290 |
+
"title": "mkfs, fsck โ ํ์ผ์์คํ
์์ฑ๊ณผ ๊ฒ์ฌ",
|
| 1291 |
+
"summary": "ํํฐ์
์ ํ์ผ์์คํ
์ ์์ฑ(`mkfs`)ํ๊ณ ์ค๋ฅ๋ฅผ ๊ฒ์ฌยท์์ (`fsck`)ํฉ๋๋ค. ํฌ๋งท ํ ๋ง์ดํธํด์ผ ์ค์ ๋ก ์ฌ์ฉํ ์ ์์ต๋๋ค.",
|
| 1292 |
+
"example": "mkfs.ext4 /dev/sdb1 # ext4 ํ์ผ์์คํ
์์ฑ\nmkfs.xfs /dev/sdb2 # XFS ํ์ผ์์คํ
์์ฑ\numount /dev/sdb1 && fsck /dev/sdb1 # ๊ฒ์ฌ ์ ๋ฐ๋์ ์ธ๋ง์ดํธ",
|
| 1293 |
+
"common_mistake": "`fsck`๋ ๋ง์ดํธ๋ ํ์ผ์์คํ
์์ ์คํํ๋ฉด ๋ฐ์ดํฐ๊ฐ ์์๋ ์ ์์ต๋๋ค. ๋ฐ๋์ ์ธ๋ง์ดํธํ๊ฑฐ๋ ์ฑ๊ธ ์ ์ ๋ชจ๋์์ ์คํํด์ผ ํฉ๋๋ค.",
|
| 1294 |
+
"keywords": [
|
| 1295 |
+
"mkfs",
|
| 1296 |
+
"mkfs.ext4",
|
| 1297 |
+
"mkfs.xfs",
|
| 1298 |
+
"fsck",
|
| 1299 |
+
"e2fsck",
|
| 1300 |
+
"tune2fs",
|
| 1301 |
+
"ํ์ผ์์คํ
"
|
| 1302 |
+
],
|
| 1303 |
+
"source_id": "manual-linux-storage",
|
| 1304 |
+
"details": [
|
| 1305 |
+
"**์ฃผ์ ํ์ผ์์คํ
**: ext4(๋ฆฌ๋
์ค ๊ธฐ๋ณธ, ์ ๋๋ง), xfs(๋์ฉ๋ยท๊ณ ์ฑ๋ฅ, RHEL ๊ธฐ๋ณธ), btrfs(์ค๋
์ทยท์๋ธ๋ณผ๋ฅจ ์ง์).",
|
| 1306 |
+
"**`tune2fs -l /dev/sdb1`**: ext4 ํ์ผ์์คํ
๋ฉํ๋ฐ์ดํฐ(UUID, ๋ง์ดํธ ํ์, ์์ฑ์ผ ๋ฑ)๋ฅผ ํ์ธํฉ๋๋ค. UUID๋ fstab ์ค์ ์ ํ์ํฉ๋๋ค.",
|
| 1307 |
+
"**์ํ ํจํด**: ํํฐ์
์์ฑ ํ mkfs โ UUID ํ์ธ(`blkid`) โ fstab์ ๋ฑ๋ก โ mount -a ์์๊ฐ ํตํฉ ์คํ ๋ฆฌ์ง ์๋๋ฆฌ์ค๋ก ์ถ์ ๋ฉ๋๋ค."
|
| 1308 |
+
]
|
| 1309 |
+
},
|
| 1310 |
+
{
|
| 1311 |
+
"id": "linux-groupadd",
|
| 1312 |
+
"certification": "LFCS / ๋ฆฌ๋
์ค๋ง์คํฐ",
|
| 1313 |
+
"title": "groupadd, groupmod, groupdel โ ๊ทธ๋ฃน ๊ด๋ฆฌ",
|
| 1314 |
+
"summary": "๊ทธ๋ฃน์ ์์ฑ(`groupadd`), ์์ (`groupmod`), ์ญ์ (`groupdel`)ํฉ๋๋ค. ์ฌ์ฉ์๋ฅผ ๋ณด์กฐ ๊ทธ๋ฃน์ ์ถ๊ฐํ๋ `usermod -aG`์ ํจ๊ป ์ฌ์ฉํฉ๋๋ค.",
|
| 1315 |
+
"example": "groupadd developers # ๊ทธ๋ฃน ์์ฑ\ngroupmod -n devops developers # ๊ทธ๋ฃน ์ด๋ฆ ๋ณ๊ฒฝ\nusermod -aG developers alice # alice๋ฅผ developers ๊ทธ๋ฃน์ ์ถ๊ฐ\ngetent group developers # ๊ทธ๋ฃน ๋ฉค๋ฒ ํ์ธ",
|
| 1316 |
+
"common_mistake": "`groupdel`์ ํด๋น ๊ทธ๋ฃน์ด ๋๊ตฐ๊ฐ์ ๊ธฐ๋ณธ ๊ทธ๋ฃน(primary group)์ด๋ฉด ์ญ์ ํ ์ ์์ต๋๋ค. ๋จผ์ ๊ทธ ์ฌ์ฉ์์ ๊ธฐ๋ณธ ๊ทธ๋ฃน์ ๋ณ๊ฒฝํด์ผ ํฉ๋๋ค.",
|
| 1317 |
+
"keywords": [
|
| 1318 |
+
"groupadd",
|
| 1319 |
+
"groupmod",
|
| 1320 |
+
"groupdel",
|
| 1321 |
+
"usermod -aG",
|
| 1322 |
+
"/etc/group",
|
| 1323 |
+
"GID"
|
| 1324 |
+
],
|
| 1325 |
+
"source_id": "ubuntu-user-management",
|
| 1326 |
+
"details": [
|
| 1327 |
+
"**`/etc/group` ๊ตฌ์กฐ**: `๊ทธ๋ฃน๋ช
:์ํธ:GID:๋ฉค๋ฒ๋ชฉ๋ก` ํ์. `getent group <์ด๋ฆ>`์ผ๋ก ํน์ ๊ทธ๋ฃน ์ ๋ณด๋ฅผ ํ์ธํฉ๋๋ค.",
|
| 1328 |
+
"**๋ณด์กฐ ๊ทธ๋ฃน ์ถ๊ฐ**: `usermod -aG groupname username`. `-a`(append) ์์ด `-G`๋ง ์ฐ๋ฉด ๊ธฐ์กด ๋ณด์กฐ ๊ทธ๋ฃน์ด ๊ต์ฒด๋ฉ๋๋ค.",
|
| 1329 |
+
"**์ํ ํจํด**: ์ ํ ์์ฑ โ ๊ทธ๋ฃน ๋ง๋ค๊ธฐ โ ์ฌ๋ฌ ์ฌ์ฉ์๋ฅผ ๊ทธ๋ฃน์ ์ถ๊ฐ โ ๊ทธ๋ฃน ๊ณต์ ๋๋ ํฐ๋ฆฌ์ SGID ์ค์ ํ๋ ๋ณตํฉ ์๋๋ฆฌ์ค๊ฐ ์์ฃผ ๋์ต๋๋ค."
|
| 1330 |
+
]
|
| 1331 |
+
},
|
| 1332 |
+
{
|
| 1333 |
+
"id": "linux-chage",
|
| 1334 |
+
"certification": "LFCS / ๋ฆฌ๋
์ค๋ง์คํฐ",
|
| 1335 |
+
"title": "chage โ ๋น๋ฐ๋ฒํธ ๋ง๋ฃ ์ ์ฑ
",
|
| 1336 |
+
"summary": "์ฌ์ฉ์ ๊ณ์ ์ ๋น๋ฐ๋ฒํธ ๋ง๋ฃ์ผ, ์ต๋ ์ฌ์ฉ ๊ธฐ๊ฐ, ๊ฒฝ๊ณ ๊ธฐ๊ฐ์ ์ค์ ํฉ๋๋ค. ๋ณด์ ์ ์ฑ
์ ์ฉ๊ณผ ๊ณ์ ๋ง๋ฃ ์๋๋ฆฌ์ค์์ ์ถ์ ๋ฉ๋๋ค.",
|
| 1337 |
+
"example": "chage -l alice # ํ์ฌ ๋ง๋ฃ ์ ์ฑ
ํ์ธ\nchage -M 90 alice # ์ต๋ 90์ผ๋ง๋ค ๋ณ๊ฒฝ ๊ฐ์ \nchage -E 2025-12-31 alice # ๊ณ์ ๋ง๋ฃ์ผ ์ค์ \nchage -d 0 alice # ๋ค์ ๋ก๊ทธ์ธ ์ ์ฆ์ ๋น๋ฐ๋ฒํธ ๋ณ๊ฒฝ ๊ฐ์ ",
|
| 1338 |
+
"common_mistake": "`chage -d 0`์ ๋ง์ง๋ง ๋น๋ฐ๋ฒํธ ๋ณ๊ฒฝ์ผ์ ์ํฌํฌ(1970-01-01)๋ก ์ค์ ํด ๋ค์ ๋ก๊ทธ์ธ ์ ์ฆ์ ๋ณ๊ฒฝํ๊ฒ ํฉ๋๋ค. `-E 0`์ ๊ณ์ ์ ์ฆ์ ๋ง๋ฃ์์ผ ๋ก๊ทธ์ธ ์์ฒด๋ฅผ ์ฐจ๋จํฉ๋๋ค.",
|
| 1339 |
+
"keywords": [
|
| 1340 |
+
"chage",
|
| 1341 |
+
"-l",
|
| 1342 |
+
"-M",
|
| 1343 |
+
"-E",
|
| 1344 |
+
"-d",
|
| 1345 |
+
"/etc/shadow",
|
| 1346 |
+
"password aging"
|
| 1347 |
+
],
|
| 1348 |
+
"source_id": "ubuntu-user-management",
|
| 1349 |
+
"details": [
|
| 1350 |
+
"**์ฃผ์ ์ต์
**: `-M`(์ต๋ ์ฌ์ฉ์ผ), `-m`(์ต์ ์ฌ์ฉ์ผ), `-W`(๋ง๋ฃ ์ ๊ฒฝ๊ณ ์ผ), `-I`(๋ง๋ฃ ํ ๋นํ์ฑํ ์ ์์ผ), `-E`(๊ณ์ ๋ง๋ฃ์ผ), `-d`(๋ง์ง๋ง ๋ณ๊ฒฝ์ผ).",
|
| 1351 |
+
"**`/etc/shadow`์ ์ ์ฅ**: ๋ง๋ฃ ์ ์ฑ
์ shadow ํ์ผ์ ์ฝ๋ก ์ผ๋ก ๊ตฌ๋ถ๋ ํ๋๋ก ์ ์ฅ๋ฉ๋๋ค. `chage`๋ ์ด ํ์ผ์ ์์ ํ๊ฒ ํธ์งํ๋ ๋ํผ์
๋๋ค.",
|
| 1352 |
+
"**์ํ ํจํด**: '์ ๊ท ์ฌ์ฉ์๊ฐ ์ฒซ ๋ก๊ทธ์ธ ์ ๋น๋ฐ๋ฒํธ๋ฅผ ๋ณ๊ฒฝํ๊ฒ' โ `chage -d 0`, '90์ผ๋ง๋ค ๋ณ๊ฒฝ ๊ฐ์ ' โ `chage -M 90` ํํ๋ก ์ถ์ ๋ฉ๋๋ค."
|
| 1353 |
+
]
|
| 1354 |
+
},
|
| 1355 |
+
{
|
| 1356 |
+
"id": "linux-systemd-unit",
|
| 1357 |
+
"certification": "LFCS / ๋ฆฌ๋
์ค๋ง์คํฐ",
|
| 1358 |
+
"title": "systemd ์๋น์ค ์ ๋ ํ์ผ ์์ฑ",
|
| 1359 |
+
"summary": "์ปค์คํ
ํ๋ก์ธ์ค๋ฅผ systemd ์๋น์ค๋ก ๋ฑ๋กํด ๋ถํ
์ ์๋ ์์ํ๊ณ ์ฌ์์ ์ ์ฑ
์ ์ ์ฉํฉ๋๋ค. `/etc/systemd/system/`์ `.service` ํ์ผ์ ์์ฑํฉ๋๋ค.",
|
| 1360 |
+
"example": "# /etc/systemd/system/myapp.service\n[Unit]\nDescription=My Application\nAfter=network.target\n\n[Service]\nExecStart=/usr/local/bin/myapp\nRestart=on-failure\nUser=myapp\n\n[Install]\nWantedBy=multi-user.target\n\nsystemctl daemon-reload && systemctl enable --now myapp",
|
| 1361 |
+
"common_mistake": "์ ๋ ํ์ผ์ ์์ ํ ํ `systemctl daemon-reload` ์์ด ์ฌ์์ํ๋ฉด ๋ณ๊ฒฝ ์ฌํญ์ด ๋ฐ์๋์ง ์์ต๋๋ค. ํ์ผ ์์ ํ์๋ ํญ์ daemon-reload๊ฐ ๋จผ์ ์
๋๋ค.",
|
| 1362 |
+
"keywords": [
|
| 1363 |
+
"service unit",
|
| 1364 |
+
"ExecStart",
|
| 1365 |
+
"WantedBy",
|
| 1366 |
+
"daemon-reload",
|
| 1367 |
+
"enable",
|
| 1368 |
+
"After",
|
| 1369 |
+
"Restart"
|
| 1370 |
+
],
|
| 1371 |
+
"source_id": "manual-linux-systemd",
|
| 1372 |
+
"details": [
|
| 1373 |
+
"**[Unit] ์น์
**: `Description`(์ค๋ช
), `After`(์ด ์ ๋๋ณด๋ค ๋ฆ๊ฒ ์์), `Requires`(์์กด์ฑ, ์์ผ๋ฉด ์คํจ).",
|
| 1374 |
+
"**[Service] ์น์
**: `ExecStart`(์คํ ๋ช
๋ น), `Restart=on-failure`(์คํจ ์ ์ฌ์์), `User`(์คํ ๊ณ์ ), `Environment`(ํ๊ฒฝ ๋ณ์).",
|
| 1375 |
+
"**์ํ ํจํด**: ์คํฌ๋ฆฝํธ๋ฅผ ์๋น์ค๋ก ๋ฑ๋ก โ ๋ถํ
์ ์๋ ์์ ์ค์ โ ์ฌ์์ ์ ์ฑ
์ ์ฉ์ ์ ์ฒด ํ๋ฆ, daemon-reload ๋๋ฝ ์ค๋ฅ ์ง๋จ์ด ์ถ์ ๋ฉ๋๋ค."
|
| 1376 |
+
]
|
| 1377 |
+
},
|
| 1378 |
+
{
|
| 1379 |
+
"id": "linux-at",
|
| 1380 |
+
"certification": "LFCS / ๋ฆฌ๋
์ค๋ง์คํฐ",
|
| 1381 |
+
"title": "at โ ์ผํ์ฑ ์์
์ค์ผ์ค๋ง",
|
| 1382 |
+
"summary": "cron์ด ๋ฐ๋ณต ์์
์ฉ์ด๋ผ๋ฉด `at`์ ํน์ ์๊ฐ์ ํ ๋ฒ๋ง ์คํํ๋ ๋ช
๋ น์ ์ฌ์ฉํฉ๋๋ค. ๋ํํ์ผ๋ก ๋ช
๋ น์ ์
๋ ฅํ๊ฑฐ๋ ํ์ดํ๋ก ์ ๋ฌํฉ๋๋ค.",
|
| 1383 |
+
"example": "echo 'tar -czf /backup/home.tar.gz /home' | at 02:00\nat now + 2 hours << 'EOF'\n/usr/local/bin/report.sh\nEOF\natq # ์์ฝ ๋ชฉ๋ก ํ์ธ\natrm 3 # 3๋ฒ ์์
์ทจ์",
|
| 1384 |
+
"common_mistake": "`at`์ cron๊ณผ ๋ฌ๋ฆฌ ํ๊ฒฝ ๋ณ์๊ฐ ์ต์ํ๋ ์ํ๋ก ์คํ๋ฉ๋๋ค. ์คํฌ๋ฆฝํธ์ ์ ๋ ๊ฒฝ๋ก๋ฅผ ์ฌ์ฉํ๊ฑฐ๋ ํ๊ฒฝ ๋ณ์๋ฅผ ๋ช
์์ ์ผ๋ก ์ค์ ํด์ผ ํฉ๋๋ค.",
|
| 1385 |
+
"keywords": [
|
| 1386 |
+
"at",
|
| 1387 |
+
"atq",
|
| 1388 |
+
"atrm",
|
| 1389 |
+
"at now",
|
| 1390 |
+
"batch",
|
| 1391 |
+
"์ผํ์ฑ ์ค์ผ์ค"
|
| 1392 |
+
],
|
| 1393 |
+
"source_id": "manual-linux-basic",
|
| 1394 |
+
"details": [
|
| 1395 |
+
"**์๊ฐ ํํ**: `at 14:30`, `at now + 1 hour`, `at midnight`, `at noon`, `at 2:00 tomorrow`.",
|
| 1396 |
+
"**`batch`**: ์์คํ
๋ถํ๊ฐ ๋ฎ์ ๋ ๋ช
๋ น์ ์คํ. at์ ๋ณํ์ผ๋ก, ๋ถํ ๊ธฐ๋ฐ ์ค์ผ์ค๋ง์ด ํ์ํ ๋ ์ฌ์ฉํฉ๋๋ค.",
|
| 1397 |
+
"**์ํ ํจํด**: cron vs at ์ ํ ๊ธฐ์ค(๋ฐ๋ณต vs ์ผํ์ฑ), ํน์ ์๊ฐ ํ ์คํ ์์ฝ, atq๋ก ๋๊ธฐ์ด ํ์ธ, atrm์ผ๋ก ์ทจ์ํ๋ ์๋๋ฆฌ์ค๊ฐ ์ถ์ ๋ฉ๋๋ค."
|
| 1398 |
+
]
|
| 1399 |
+
},
|
| 1400 |
+
{
|
| 1401 |
+
"id": "linux-docker-basics",
|
| 1402 |
+
"certification": "LFCS / ๋ฆฌ๋
์ค๋ง์คํฐ",
|
| 1403 |
+
"title": "Docker โ ์ปจํ
๏ฟฝ๏ฟฝ๏ฟฝ๋ ๊ธฐ์ด",
|
| 1404 |
+
"summary": "2023๋
๊ฐํธ๋ LFCS์ ์ปจํ
์ด๋ ๊ด๋ฆฌ๊ฐ ์ถ๊ฐ๋์ต๋๋ค. ์ด๋ฏธ์ง pull, ์ปจํ
์ด๋ ์คํยท์ค์งยท์ญ์ , ๋ก๊ทธ ํ์ธ ๋ฑ ๊ธฐ๋ณธ ๋ผ์ดํ์ฌ์ดํด์ ๋ค๋ฃน๋๋ค.",
|
| 1405 |
+
"example": "docker pull nginx:latest\ndocker run -d -p 8080:80 --name webserver nginx\ndocker ps # ์คํ ์ค์ธ ์ปจํ
์ด๋ ๋ชฉ๋ก\ndocker logs webserver\ndocker stop webserver && docker rm webserver",
|
| 1406 |
+
"common_mistake": "`docker stop`์ SIGTERM์ผ๋ก ์ ์ ์ข
๋ฃ๋ฅผ ์์ฒญํ๊ณ , `docker kill`์ SIGKILL๋ก ๊ฐ์ ์ข
๋ฃํฉ๋๋ค. ๋ฐ์ดํฐ ์ผ๊ด์ฑ์ ์ํด ๊ฐ๋ฅํ๋ฉด `stop`์ ์ฌ์ฉํ์ธ์.",
|
| 1407 |
+
"keywords": [
|
| 1408 |
+
"docker",
|
| 1409 |
+
"pull",
|
| 1410 |
+
"run",
|
| 1411 |
+
"ps",
|
| 1412 |
+
"stop",
|
| 1413 |
+
"rm",
|
| 1414 |
+
"logs",
|
| 1415 |
+
"images",
|
| 1416 |
+
"-d",
|
| 1417 |
+
"-p"
|
| 1418 |
+
],
|
| 1419 |
+
"source_id": "manual-linux-docker",
|
| 1420 |
+
"details": [
|
| 1421 |
+
"**`docker run` ์ฃผ์ ์ต์
**: `-d`(๋ฐฑ๊ทธ๋ผ์ด๋), `-p ํธ์คํธ:์ปจํ
์ด๋`(ํฌํธ ๋งคํ), `-v`(๋ณผ๋ฅจ ๋ง์ดํธ), `--name`(์ด๋ฆ ์ง์ ), `--rm`(์ข
๋ฃ ์ ์๋ ์ญ์ ).",
|
| 1422 |
+
"**์ด๋ฏธ์ง vs ์ปจํ
์ด๋**: `docker images`(๋ก์ปฌ ์ด๋ฏธ์ง ๋ชฉ๋ก), `docker ps -a`(์ค์ง๋ ๊ฒ ํฌํจ ์ ์ฒด ์ปจํ
์ด๋). `docker rmi`๋ก ์ด๋ฏธ์ง, `docker rm`์ผ๋ก ์ปจํ
์ด๋๋ฅผ ์ญ์ ํฉ๋๋ค.",
|
| 1423 |
+
"**์ํ ํจํด**: ์ด๋ฏธ์ง pull โ ํฌํธ ๋งคํํด ๋ฐฑ๊ทธ๋ผ์ด๋ ์คํ โ ๋ก๊ทธ ํ์ธ โ ์ค์ง ํ ์ญ์ ํ๋ฆ, ์ปจํ
์ด๋ ๋ด๋ถ ์ ๊ทผ(`docker exec -it`)์ด ์ถ์ ๋ฉ๋๋ค."
|
| 1424 |
+
]
|
| 1425 |
+
},
|
| 1426 |
+
{
|
| 1427 |
+
"id": "linux-grub-boot",
|
| 1428 |
+
"certification": "LFCS / ๋ฆฌ๋
์ค๋ง์คํฐ",
|
| 1429 |
+
"title": "๋ถํ
ํ๋ก์ธ์ค์ GRUB",
|
| 1430 |
+
"summary": "BIOS/UEFI โ GRUB โ ์ปค๋ โ initramfs โ systemd ์์ผ๋ก ๋ถํ
๋ฉ๋๋ค. GRUB ์ค์ ์ ์์ ํ๊ณ ๋ณต๊ตฌ ๋ชจ๋๋ก ์ง์
ํ๋ ๋ฐฉ๋ฒ์ด ์ํ์ ์ถ์ ๋ฉ๋๋ค.",
|
| 1431 |
+
"example": "# GRUB ๊ธฐ๋ณธ ์ค์ ์์ \nvim /etc/default/grub\n# GRUB_TIMEOUT=5, GRUB_CMDLINE_LINUX=\"quiet splash\"\nupdate-grub # Ubuntu (grub2-mkconfig -o /boot/grub2/grub.cfg on RHEL)\nsystemctl get-default # ํ์ฌ ๊ธฐ๋ณธ target ํ์ธ\nsystemctl set-default multi-user.target",
|
| 1432 |
+
"common_mistake": "`/etc/default/grub`์ ์์ ํด๋ `update-grub`(Ubuntu) ๋๋ `grub2-mkconfig`(RHEL)์ ์คํํ์ง ์์ผ๋ฉด ์ค์ ๋ถํธ๋ก๋ ์ค์ ์ ๋ฐ์๋์ง ์์ต๋๋ค.",
|
| 1433 |
+
"keywords": [
|
| 1434 |
+
"GRUB",
|
| 1435 |
+
"update-grub",
|
| 1436 |
+
"grub2-mkconfig",
|
| 1437 |
+
"systemd target",
|
| 1438 |
+
"initramfs",
|
| 1439 |
+
"boot"
|
| 1440 |
+
],
|
| 1441 |
+
"source_id": "manual-linux-boot",
|
| 1442 |
+
"details": [
|
| 1443 |
+
"**๋ถํ
์์**: BIOS/UEFI โ MBR/ESP์ GRUB โ `/boot/grub/grub.cfg` ๋ก๋ โ ์ปค๋+initramfs ๋ฉ๋ชจ๋ฆฌ ์ ์ฌ โ systemd PID 1 ์์.",
|
| 1444 |
+
"**systemd target**: `multi-user.target`(CLI, runlevel 3), `graphical.target`(GUI, runlevel 5), `rescue.target`(๋จ์ผ ์ฌ์ฉ์ ๋ณต๊ตฌ).",
|
| 1445 |
+
"**์ํ ํจํด**: ๋ถํ
์คํจ ์ GRUB์์ ์ปค๋ ํ๋ผ๋ฏธํฐ ์์ (eํค), ๊ธฐ๋ณธ target ๋ณ๊ฒฝ, `update-grub` ์คํ ํ์ด๋ฐ์ด ์์ฃผ ์ถ์ ๋ฉ๋๋ค."
|
| 1446 |
+
]
|
| 1447 |
+
}
|
| 1448 |
+
]
|
cert_study_app/content/linux/practices.json
ADDED
|
@@ -0,0 +1,428 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[
|
| 2 |
+
{
|
| 3 |
+
"id": "linux-lab-31",
|
| 4 |
+
"title": "๋ก๊ทธ ๋ง์ง๋ง 20์ค ํ์ธ",
|
| 5 |
+
"task_description": "`/var/log/syslog` ํ์ผ์ ๋ง์ง๋ง 20์ค์ ํ์ธํ์ธ์.",
|
| 6 |
+
"expected_command": "tail -n 20 /var/log/syslog",
|
| 7 |
+
"grading_conditions": [
|
| 8 |
+
"tail",
|
| 9 |
+
"-n",
|
| 10 |
+
"20",
|
| 11 |
+
"/var/log/syslog"
|
| 12 |
+
],
|
| 13 |
+
"hint": "tail์ -n ์ต์
์ผ๋ก ์ถ๋ ฅํ ์ค ์๋ฅผ ์ง์ ํ ์ ์์ต๋๋ค.",
|
| 14 |
+
"explanation": "`tail -n 20 /var/log/syslog`๋ ํ์ผ์ ๋ง์ง๋ง 20์ค์ ์ถ๋ ฅํฉ๋๋ค.",
|
| 15 |
+
"difficulty": "easy"
|
| 16 |
+
},
|
| 17 |
+
{
|
| 18 |
+
"id": "linux-lab-32",
|
| 19 |
+
"title": "๋ก๊ทธ ํ์ผ ์ค์๊ฐ ์ถ์ ",
|
| 20 |
+
"task_description": "`/var/log/syslog` ํ์ผ์ ์ถ๊ฐ๋๋ ๋ด์ฉ์ ์ค์๊ฐ์ผ๋ก ์ถ์ ํ์ธ์.",
|
| 21 |
+
"expected_command": "tail -f /var/log/syslog",
|
| 22 |
+
"grading_conditions": [
|
| 23 |
+
"tail",
|
| 24 |
+
"-f",
|
| 25 |
+
"/var/log/syslog"
|
| 26 |
+
],
|
| 27 |
+
"hint": "`-f` ์ต์
์ follow์ ์ฝ์๋ก ํ์ผ ๋์ ์ค์๊ฐ์ผ๋ก ์ถ์ ํฉ๋๋ค.",
|
| 28 |
+
"explanation": "`tail -f /var/log/syslog`๋ ํ์ผ์ ์ถ๊ฐ๋๋ ๋ด์ฉ์ ์ค์๊ฐ์ผ๋ก ๊ณ์ ์ถ๋ ฅํฉ๋๋ค.",
|
| 29 |
+
"difficulty": "easy"
|
| 30 |
+
},
|
| 31 |
+
{
|
| 32 |
+
"id": "linux-lab-33",
|
| 33 |
+
"title": "ํ์ผ ์์ 10์ค ํ์ธ",
|
| 34 |
+
"task_description": "`/etc/passwd` ํ์ผ์ ์ฒ์ 10์ค์ ํ์ธํ์ธ์.",
|
| 35 |
+
"expected_command": "head /etc/passwd",
|
| 36 |
+
"grading_conditions": [
|
| 37 |
+
"head",
|
| 38 |
+
"/etc/passwd"
|
| 39 |
+
],
|
| 40 |
+
"hint": "head๋ ๊ธฐ๋ณธ์ผ๋ก ์ฒ์ 10์ค์ ์ถ๋ ฅํฉ๋๋ค.",
|
| 41 |
+
"explanation": "`head /etc/passwd`๋ ํ์ผ์ ์ฒ์ 10์ค์ ์ถ๋ ฅํฉ๋๋ค. `-n`์ผ๋ก ์ค ์๋ฅผ ์ง์ ํ ์๋ ์์ต๋๋ค.",
|
| 42 |
+
"difficulty": "easy"
|
| 43 |
+
},
|
| 44 |
+
{
|
| 45 |
+
"id": "linux-lab-34",
|
| 46 |
+
"title": "sed๋ก ํ
์คํธ ๊ต์ฒด",
|
| 47 |
+
"task_description": "`config.txt`์์ `old_value`๋ฅผ `new_value`๋ก ๋ชจ๋ ๊ต์ฒดํด ์ถ๋ ฅํ์ธ์.",
|
| 48 |
+
"expected_command": "sed 's/old_value/new_value/g' config.txt",
|
| 49 |
+
"grading_conditions": [
|
| 50 |
+
"sed",
|
| 51 |
+
"old_value",
|
| 52 |
+
"new_value",
|
| 53 |
+
"config.txt"
|
| 54 |
+
],
|
| 55 |
+
"hint": "`s/ํจํด/๊ต์ฒด/g` ํํ๋ก ๊ต์ฒด ๋ช
๋ น์ ์์ฑํฉ๋๋ค. `g`๋ ํ ์ค์์ ๋ชจ๋ ๊ต์ฒดํฉ๋๋ค.",
|
| 56 |
+
"explanation": "`sed 's/old_value/new_value/g' config.txt`๋ ํ์ผ์์ old_value๋ฅผ ๋ชจ๋ new_value๋ก ๊ต์ฒดํด ์ถ๋ ฅํฉ๋๋ค.",
|
| 57 |
+
"difficulty": "medium"
|
| 58 |
+
},
|
| 59 |
+
{
|
| 60 |
+
"id": "linux-lab-35",
|
| 61 |
+
"title": "sed ์ธํ๋ ์ด์ค ์์ ",
|
| 62 |
+
"task_description": "`nginx.conf`์์ `localhost`๋ฅผ `127.0.0.1`๋ก ์ง์ ์์ ํ์ธ์.",
|
| 63 |
+
"expected_command": "sed -i 's/localhost/127.0.0.1/g' nginx.conf",
|
| 64 |
+
"grading_conditions": [
|
| 65 |
+
"sed",
|
| 66 |
+
"-i",
|
| 67 |
+
"localhost",
|
| 68 |
+
"127.0.0.1",
|
| 69 |
+
"nginx.conf"
|
| 70 |
+
],
|
| 71 |
+
"hint": "`-i` ์ต์
์ ํ์ค ์ถ๋ ฅ ๋์ ํ์ผ์ ์ง์ ์์ ํฉ๋๋ค.",
|
| 72 |
+
"explanation": "`sed -i 's/localhost/127.0.0.1/g' nginx.conf`๋ nginx.conf ํ์ผ์ ์ง์ ์์ ํฉ๋๋ค.",
|
| 73 |
+
"difficulty": "medium"
|
| 74 |
+
},
|
| 75 |
+
{
|
| 76 |
+
"id": "linux-lab-36",
|
| 77 |
+
"title": "cut์ผ๋ก ์ฌ์ฉ์ ์ด๋ฆ ์ถ์ถ",
|
| 78 |
+
"task_description": "`/etc/passwd`์์ ์ฝ๋ก (`:`) ๊ตฌ๋ถ์์ ์ฒซ ๋ฒ์งธ ํ๋(์ฌ์ฉ์ ์ด๋ฆ)๋ง ์ถ์ถํ์ธ์.",
|
| 79 |
+
"expected_command": "cut -d':' -f1 /etc/passwd",
|
| 80 |
+
"grading_conditions": [
|
| 81 |
+
"cut",
|
| 82 |
+
"-d",
|
| 83 |
+
"-f1",
|
| 84 |
+
"/etc/passwd"
|
| 85 |
+
],
|
| 86 |
+
"hint": "`-d`๋ก ๊ตฌ๋ถ์๋ฅผ, `-f`๋ก ์ถ๋ ฅํ ํ๋๋ฅผ ์ง์ ํฉ๋๋ค.",
|
| 87 |
+
"explanation": "`cut -d':' -f1 /etc/passwd`๋ ์ฝ๋ก ๊ตฌ๋ถ์์์ ์ฒซ ๋ฒ์งธ ํ๋(์ฌ์ฉ์ ์ด๋ฆ)๋ฅผ ์ถ์ถํฉ๋๋ค.",
|
| 88 |
+
"difficulty": "medium"
|
| 89 |
+
},
|
| 90 |
+
{
|
| 91 |
+
"id": "linux-lab-37",
|
| 92 |
+
"title": "sort์ uniq์ผ๋ก ์ค๋ณต ์ ๊ฑฐ",
|
| 93 |
+
"task_description": "`access.log`์์ ์ค๋ณต ์ค์ ์ ๊ฑฐํ๊ณ ์ํ๋ฒณ ์์ผ๋ก ์ ๋ ฌํด ์ถ๋ ฅํ์ธ์.",
|
| 94 |
+
"expected_command": "sort access.log | uniq",
|
| 95 |
+
"grading_conditions": [
|
| 96 |
+
"sort",
|
| 97 |
+
"access.log",
|
| 98 |
+
"uniq"
|
| 99 |
+
],
|
| 100 |
+
"hint": "`uniq`์ ์ฐ์๋ ์ค๋ณต๋ง ์ ๊ฑฐํ๋ฏ๋ก ๋จผ์ `sort`๊ฐ ํ์ํฉ๋๋ค.",
|
| 101 |
+
"explanation": "`sort access.log | uniq`์ ํ์ผ์ ์ ๋ ฌํ ๋ค ์ค๋ณต ์ค์ ์ ๊ฑฐํฉ๋๋ค.",
|
| 102 |
+
"difficulty": "medium"
|
| 103 |
+
},
|
| 104 |
+
{
|
| 105 |
+
"id": "linux-lab-38",
|
| 106 |
+
"title": "wc๋ก ์ค ์ ์ธ๊ธฐ",
|
| 107 |
+
"task_description": "`/var/log/auth.log` ํ์ผ์ ์ค ์๋ฅผ ์ธ์ธ์.",
|
| 108 |
+
"expected_command": "wc -l /var/log/auth.log",
|
| 109 |
+
"grading_conditions": [
|
| 110 |
+
"wc",
|
| 111 |
+
"-l",
|
| 112 |
+
"/var/log/auth.log"
|
| 113 |
+
],
|
| 114 |
+
"hint": "`wc -l`์ ์ค ์, `-w`๋ ๋จ์ด ์, `-c`๋ ๋ฐ์ดํธ ์๋ฅผ ์
๋๋ค.",
|
| 115 |
+
"explanation": "`wc -l /var/log/auth.log`๋ ํ์ผ์ ์ค ์๋ฅผ ์ถ๋ ฅํฉ๋๋ค.",
|
| 116 |
+
"difficulty": "easy"
|
| 117 |
+
},
|
| 118 |
+
{
|
| 119 |
+
"id": "linux-lab-39",
|
| 120 |
+
"title": "awk๋ก ๋ ๋ฒ์งธ ํ๋ ์ถ๋ ฅ",
|
| 121 |
+
"task_description": "`access.log`์ ๊ฐ ์ค์์ ๋ ๋ฒ์งธ ํ๋๋ฅผ ์ถ๋ ฅํ์ธ์.",
|
| 122 |
+
"expected_command": "awk '{print $2}' access.log",
|
| 123 |
+
"grading_conditions": [
|
| 124 |
+
"awk",
|
| 125 |
+
"$2",
|
| 126 |
+
"access.log"
|
| 127 |
+
],
|
| 128 |
+
"hint": "awk์์ `$1`, `$2`๋ ๊ณต๋ฐฑ์ผ๋ก ๊ตฌ๋ถ๋ ๊ฐ ํ๋๋ฅผ ์๋ฏธํฉ๋๋ค.",
|
| 129 |
+
"explanation": "`awk '{print $2}' access.log`๋ ๊ฐ ์ค์ ๋ ๋ฒ์งธ ํ๋๋ฅผ ์ถ๋ ฅํฉ๋๋ค.",
|
| 130 |
+
"difficulty": "medium"
|
| 131 |
+
},
|
| 132 |
+
{
|
| 133 |
+
"id": "linux-lab-40",
|
| 134 |
+
"title": "์ฌ๋ณผ๋ฆญ ๋งํฌ ์์ฑ",
|
| 135 |
+
"task_description": "`/etc/nginx/nginx.conf`๋ฅผ ๊ฐ๋ฆฌํค๋ ์ฌ๋ณผ๋ฆญ ๋งํฌ `~/nginx.conf`๋ฅผ ๋ง๋์ธ์.",
|
| 136 |
+
"expected_command": "ln -s /etc/nginx/nginx.conf ~/nginx.conf",
|
| 137 |
+
"grading_conditions": [
|
| 138 |
+
"ln",
|
| 139 |
+
"-s",
|
| 140 |
+
"/etc/nginx/nginx.conf",
|
| 141 |
+
"nginx.conf"
|
| 142 |
+
],
|
| 143 |
+
"hint": "`ln -s ์๋ณธ ๋งํฌ์ด๋ฆ` ํํ๋ก ์ฌ๋ณผ๋ฆญ ๋งํฌ๋ฅผ ๋ง๋ญ๋๋ค.",
|
| 144 |
+
"explanation": "`ln -s /etc/nginx/nginx.conf ~/nginx.conf`๋ ํ ๋๋ ํฐ๋ฆฌ์ nginx.conf ์ฌ๋ณผ๋ฆญ ๋งํฌ๋ฅผ ๋ง๋ญ๋๋ค.",
|
| 145 |
+
"difficulty": "medium"
|
| 146 |
+
},
|
| 147 |
+
{
|
| 148 |
+
"id": "linux-lab-41",
|
| 149 |
+
"title": "๋ฐฑ๊ทธ๋ผ์ด๋ ์์
๋ชฉ๋ก ํ์ธ",
|
| 150 |
+
"task_description": "ํ์ฌ ์์ ๋ฐฑ๊ทธ๋ผ์ด๋ ์์
๋ชฉ๋ก์ ํ์ธํ์ธ์.",
|
| 151 |
+
"expected_command": "jobs",
|
| 152 |
+
"grading_conditions": [
|
| 153 |
+
"jobs"
|
| 154 |
+
],
|
| 155 |
+
"hint": "`jobs` ๋ช
๋ น์ผ๋ก ํ์ฌ ์์ ๋ฐฑ๊ทธ๋ผ์ด๋ ์์
๋ชฉ๋ก์ ๋ณผ ์ ์์ต๋๋ค.",
|
| 156 |
+
"explanation": "`jobs`๋ ํ์ฌ ์์์ `&`๋ก ์คํ๋๊ฑฐ๋ Ctrl+Z๋ก ์ ์ง๋ ์์
๋ชฉ๋ก์ ๋ณด์ฌ์ค๋๋ค.",
|
| 157 |
+
"difficulty": "easy"
|
| 158 |
+
},
|
| 159 |
+
{
|
| 160 |
+
"id": "linux-lab-42",
|
| 161 |
+
"title": "nohup ๋ฐฑ๊ทธ๋ผ์ด๋ ์คํ",
|
| 162 |
+
"task_description": "`long_process.sh` ์คํฌ๋ฆฝํธ๋ฅผ ํฐ๋ฏธ๋์ด ๋ซํ๋ ๊ณ์ ์คํ๋๋๋ก ๋ฐฑ๊ทธ๋ผ์ด๋๋ก ์คํํ์ธ์.",
|
| 163 |
+
"expected_command": "nohup ./long_process.sh &",
|
| 164 |
+
"grading_conditions": [
|
| 165 |
+
"nohup",
|
| 166 |
+
"long_process.sh",
|
| 167 |
+
"&"
|
| 168 |
+
],
|
| 169 |
+
"hint": "`nohup`์ HUP ์๊ทธ๋์ ๋ฌด์ํด ํฐ๋ฏธ๋ ์ข
๋ฃ ํ์๋ ๊ณ์ ์คํ๋๊ฒ ํฉ๋๋ค.",
|
| 170 |
+
"explanation": "`nohup ./long_process.sh &`๋ ํฐ๋ฏธ๋์ด ๋ซํ๋ ๊ณ์ ์คํ๋ฉ๋๋ค. ์ถ๋ ฅ์ ๊ธฐ๋ณธ์ ์ผ๋ก nohup.out์ ์ ์ฅ๋ฉ๋๋ค.",
|
| 171 |
+
"difficulty": "medium"
|
| 172 |
+
},
|
| 173 |
+
{
|
| 174 |
+
"id": "linux-lab-43",
|
| 175 |
+
"title": "๊ถํ ๋ณด์กด ํ์ผ ๋ฐฑ์
",
|
| 176 |
+
"task_description": "`/etc/passwd` ํ์ผ์ ๊ถํยท์์ ์ยทํ์์คํฌํ๋ฅผ ๋ณด์กดํด `/tmp/passwd.bak`์ผ๋ก ๋ณต์ฌํ์ธ์.",
|
| 177 |
+
"expected_command": "cp -a /etc/passwd /tmp/passwd.bak",
|
| 178 |
+
"grading_conditions": [
|
| 179 |
+
"cp",
|
| 180 |
+
"-a",
|
| 181 |
+
"/etc/passwd",
|
| 182 |
+
"/tmp/passwd.bak"
|
| 183 |
+
],
|
| 184 |
+
"hint": "์ผ๋ฐ `cp`๋ ์์ฑ์ ๋ณด์กดํ์ง ์์ต๋๋ค. ๋ฐฑ์
์์๋ `-a` ์ต์
์ ์ฌ์ฉํ์ธ์.",
|
| 185 |
+
"explanation": "`cp -a`๋ `-dR --preserve=all`์ ๋จ์ถ์ผ๋ก ์ฌ๋ณผ๋ฆญ ๋งํฌยท๊ถํยท์์ ์ยทํ์์คํฌํ๋ฅผ ๋ชจ๋ ๋ณด์กดํฉ๋๋ค.",
|
| 186 |
+
"difficulty": "easy"
|
| 187 |
+
},
|
| 188 |
+
{
|
| 189 |
+
"id": "linux-lab-44",
|
| 190 |
+
"title": "๋๋ ํฐ๋ฆฌ ์ฌ๊ท ์ญ์ ์ ํ์ธ",
|
| 191 |
+
"task_description": "`/tmp/testdir` ๋๋ ํฐ๋ฆฌ๋ฅผ ์ญ์ ์ ๊ฐ ํ์ผ์ ํ์ธํ๋ฉด์ ์ ๊ฑฐํ์ธ์.",
|
| 192 |
+
"expected_command": "rm -ri /tmp/testdir",
|
| 193 |
+
"grading_conditions": [
|
| 194 |
+
"rm",
|
| 195 |
+
"-r",
|
| 196 |
+
"-i",
|
| 197 |
+
"/tmp/testdir"
|
| 198 |
+
],
|
| 199 |
+
"hint": "`-r`์ ์ฌ๊ท ์ญ์ , `-i`๋ ๊ฐ ํ์ผ๋ง๋ค ํ์ธ์ ์์ฒญํฉ๋๋ค.",
|
| 200 |
+
"explanation": "์ค์ ๋ฐ์ดํฐ๊ฐ ์๋ ๋๋ ํฐ๋ฆฌ๋ฅผ ์ญ์ ํ ๋๋ `-i`๋ก ํ ํ์ผ์ฉ ํ์ธํ๋ ์ต๊ด์ด ์ฌ๊ณ ๋ฅผ ๋ฐฉ์งํฉ๋๋ค.",
|
| 201 |
+
"difficulty": "easy"
|
| 202 |
+
},
|
| 203 |
+
{
|
| 204 |
+
"id": "linux-lab-45",
|
| 205 |
+
"title": "MBR ํํฐ์
์์ฑ (fdisk)",
|
| 206 |
+
"task_description": "`/dev/sdb`์ fdisk๋ฅผ ์ฌ์ฉํด 20GB ์ฃผ ํํฐ์
์ ์์ฑํ๊ณ ์ ์ฅํ์ธ์. (์ธํฐ๋ํฐ๋ธ: n โ p โ 1 โ Enter โ +20G โ w)",
|
| 207 |
+
"expected_command": "fdisk /dev/sdb",
|
| 208 |
+
"grading_conditions": [
|
| 209 |
+
"fdisk",
|
| 210 |
+
"/dev/sdb"
|
| 211 |
+
],
|
| 212 |
+
"hint": "fdisk ์ธํฐ๋ํฐ๋ธ ๋ชจ๋์์ `n`(์ ํํฐ์
), `p`(์ฃผ), `1`(๋ฒํธ), Enter(๊ธฐ๋ณธ ์์), `+20G`(ํฌ๊ธฐ), `w`(์ ์ฅ) ์์๋ก ์
๋ ฅํฉ๋๋ค.",
|
| 213 |
+
"explanation": "fdisk๋ MBR ๋ฐฉ์์ผ๋ก ์ต๋ 2TB ๋์คํฌ์ ์ ํฉํฉ๋๋ค. ๋ณ๊ฒฝ ์ฌํญ์ `w`๋ฅผ ์
๋ ฅํด์ผ ์ค์ ๋์คํฌ์ ๊ธฐ๋ก๋ฉ๋๋ค.",
|
| 214 |
+
"difficulty": "medium"
|
| 215 |
+
},
|
| 216 |
+
{
|
| 217 |
+
"id": "linux-lab-46",
|
| 218 |
+
"title": "ext4 ํ์ผ์์คํ
์์ฑ",
|
| 219 |
+
"task_description": "`/dev/sdb1` ํํฐ์
์ ext4 ํ์ผ์์คํ
์ ์์ฑํ์ธ์.",
|
| 220 |
+
"expected_command": "mkfs.ext4 /dev/sdb1",
|
| 221 |
+
"grading_conditions": [
|
| 222 |
+
"mkfs.ext4",
|
| 223 |
+
"/dev/sdb1"
|
| 224 |
+
],
|
| 225 |
+
"hint": "`mkfs.ext4` ๋๋ `mkfs -t ext4`๋ฅผ ์ฌ์ฉํฉ๋๋ค.",
|
| 226 |
+
"explanation": "ํํฐ์
์์ฑ ํ ํ์ผ์์คํ
์ ๋ง๋ค์ด์ผ ์ค์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ ์ ์์ต๋๋ค. ํฌ๋งทํ๋ฉด ๊ธฐ์กด ๋ฐ์ดํฐ๊ฐ ์ญ์ ๋๋ฏ๋ก ๋์ ๋๋ฐ์ด์ค๋ฅผ ๋ฐ๋์ ํ์ธํ์ธ์.",
|
| 227 |
+
"difficulty": "easy"
|
| 228 |
+
},
|
| 229 |
+
{
|
| 230 |
+
"id": "linux-lab-47",
|
| 231 |
+
"title": "ํ์ผ์์คํ
UUID ํ์ธ",
|
| 232 |
+
"task_description": "`/dev/sdb1`์ UUID๋ฅผ ํ์ธํ์ธ์.",
|
| 233 |
+
"expected_command": "blkid /dev/sdb1",
|
| 234 |
+
"grading_conditions": [
|
| 235 |
+
"blkid",
|
| 236 |
+
"/dev/sdb1"
|
| 237 |
+
],
|
| 238 |
+
"hint": "`blkid`๋ ๋ธ๋ก ๋๋ฐ์ด์ค์ UUID์ ํ์ผ์์คํ
์ ํ์ ์ถ๋ ฅํฉ๋๋ค.",
|
| 239 |
+
"explanation": "fstab์ ์ฅ์น๋ช
๋์ UUID๋ฅผ ์ฌ์ฉํ๋ฉด ์ฌ๋ถํ
์ ๋๋ฐ์ด์ค ์์๊ฐ ๋ฐ๋์ด๋ ์ฌ๋ฐ๋ฅธ ํํฐ์
์ด ๋ง์ดํธ๋ฉ๋๋ค.",
|
| 240 |
+
"difficulty": "easy"
|
| 241 |
+
},
|
| 242 |
+
{
|
| 243 |
+
"id": "linux-lab-48",
|
| 244 |
+
"title": "๊ทธ๋ฃน ์์ฑ ๋ฐ ์ฌ์ฉ์ ์ถ๊ฐ",
|
| 245 |
+
"task_description": "`devteam` ๊ทธ๋ฃน์ ๋ง๋ค๊ณ `alice`๋ฅผ ๊ธฐ์กด ๊ทธ๋ฃน์ ์ ์งํ ์ฑ ์ถ๊ฐํ์ธ์.",
|
| 246 |
+
"expected_command": "groupadd devteam && usermod -aG devteam alice",
|
| 247 |
+
"grading_conditions": [
|
| 248 |
+
"groupadd devteam",
|
| 249 |
+
"usermod",
|
| 250 |
+
"-aG",
|
| 251 |
+
"devteam",
|
| 252 |
+
"alice"
|
| 253 |
+
],
|
| 254 |
+
"hint": "๊ทธ๋ฃน ์์ฑ์ `groupadd`, ์ฌ์ฉ์๋ฅผ ๋ณด์กฐ ๊ทธ๋ฃน์ ์ถ๊ฐํ ๋๋ `-aG`(append)๋ฅผ ๋ฐ๋์ ์ฌ์ฉํ์ธ์.",
|
| 255 |
+
"explanation": "`-a` ์์ด `-G`๋ง ์ฐ๋ฉด alice์ ๊ธฐ์กด ๋ณด์กฐ ๊ทธ๋ฃน์ด ๋ชจ๋ devteam์ผ๋ก ๊ต์ฒด๋ฉ๋๋ค. `-aG`๊ฐ ์์ ํฉ๋๋ค.",
|
| 256 |
+
"difficulty": "easy"
|
| 257 |
+
},
|
| 258 |
+
{
|
| 259 |
+
"id": "linux-lab-49",
|
| 260 |
+
"title": "์ฒซ ๋ก๊ทธ์ธ ์ ๋น๋ฐ๋ฒํธ ๋ณ๊ฒฝ ๊ฐ์ ",
|
| 261 |
+
"task_description": "์ ์ฌ์ฉ์ `bob`์ด ์ฒซ ๋ก๊ทธ์ธ ์ ๋ฐ๋์ ๋น๋ฐ๋ฒํธ๋ฅผ ๋ณ๊ฒฝํ๋๋ก ์ค์ ํ์ธ์.",
|
| 262 |
+
"expected_command": "chage -d 0 bob",
|
| 263 |
+
"grading_conditions": [
|
| 264 |
+
"chage",
|
| 265 |
+
"-d 0",
|
| 266 |
+
"bob"
|
| 267 |
+
],
|
| 268 |
+
"hint": "`chage -d 0`์ ๋ง์ง๋ง ๋น๋ฐ๋ฒํธ ๋ณ๊ฒฝ์ผ์ ์ํฌํฌ๋ก ์ค์ ํด ์ฆ์ ๋ณ๊ฒฝ์ ์๊ตฌํฉ๋๋ค.",
|
| 269 |
+
"explanation": "๋ค์ ๋ก๊ทธ์ธ ์ PAM์ด ๋น๋ฐ๋ฒํธ ๋ง๋ฃ๋ฅผ ๊ฐ์งํ๊ณ ์ ๋น๋ฐ๋ฒํธ ์
๋ ฅ์ ์๊ตฌํฉ๋๋ค. ์ ๊ท ๊ณ์ ๋ฐ๊ธ ์ ํ์ค ๋ณด์ ์ ์ฐจ์
๋๋ค.",
|
| 270 |
+
"difficulty": "easy"
|
| 271 |
+
},
|
| 272 |
+
{
|
| 273 |
+
"id": "linux-lab-50",
|
| 274 |
+
"title": "systemd ์๋น์ค ํ์ผ ์์ฑ ๋ฐ ํ์ฑํ",
|
| 275 |
+
"task_description": "`/usr/local/bin/myapp`์ ์คํํ๋ `myapp.service`๋ฅผ ๋ง๋ค๊ณ ๋ถํ
์ ์๋ ์์ํ๋๋ก ํ์ฑํํ์ธ์.",
|
| 276 |
+
"expected_command": "systemctl daemon-reload && systemctl enable --now myapp",
|
| 277 |
+
"grading_conditions": [
|
| 278 |
+
"systemctl daemon-reload",
|
| 279 |
+
"systemctl enable",
|
| 280 |
+
"myapp"
|
| 281 |
+
],
|
| 282 |
+
"hint": "์ ๋ ํ์ผ์ `/etc/systemd/system/myapp.service`์ ์์ฑํ ๋ค daemon-reload โ enable --now ์์๋ก ์คํํฉ๋๋ค.",
|
| 283 |
+
"explanation": "`daemon-reload`๋ ๋ณ๊ฒฝ๋ ์ ๋ ํ์ผ์ systemd๊ฐ ์ธ์ํ๊ฒ ํฉ๋๋ค. `enable --now`๋ ๋ถํ
์ ์๋ ์์ ๋ฑ๋ก๊ณผ ์ฆ์ ์คํ์ ํ ๋ฒ์ ์ฒ๋ฆฌํฉ๋๋ค.",
|
| 284 |
+
"difficulty": "medium"
|
| 285 |
+
},
|
| 286 |
+
{
|
| 287 |
+
"id": "linux-lab-51",
|
| 288 |
+
"title": "์ผํ์ฑ ์์
์์ฝ (at)",
|
| 289 |
+
"task_description": "2์๊ฐ ํ์ `/usr/local/bin/backup.sh`๋ฅผ ํ ๋ฒ ์คํํ๋๋ก ์์ฝํ์ธ์.",
|
| 290 |
+
"expected_command": "echo '/usr/local/bin/backup.sh' | at now + 2 hours",
|
| 291 |
+
"grading_conditions": [
|
| 292 |
+
"at",
|
| 293 |
+
"now + 2 hours"
|
| 294 |
+
],
|
| 295 |
+
"hint": "`echo '๋ช
๋ น' | at now + 2 hours` ํ์์ ์ฌ์ฉํฉ๋๋ค. `at` ๋ช
๋ น ํ Ctrl+D๋ก๋ ์
๋ ฅํ ์ ์์ต๋๋ค.",
|
| 296 |
+
"explanation": "`at`์ ์ผํ์ฑ ์ค์ผ์ค๋ง ๋๊ตฌ์
๋๋ค. ๋ฐ๋ณต ์คํ์ด ํ์ํ๋ฉด cron์ ์ฌ์ฉํ์ธ์. ์์ฝ ๋ชฉ๋ก์ `atq`๋ก ํ์ธํฉ๋๋ค.",
|
| 297 |
+
"difficulty": "easy"
|
| 298 |
+
},
|
| 299 |
+
{
|
| 300 |
+
"id": "linux-lab-52",
|
| 301 |
+
"title": "Docker ์ปจํ
์ด๋ ์คํ ๋ฐ ํ์ธ",
|
| 302 |
+
"task_description": "nginx ์ด๋ฏธ์ง๋ฅผ ๋ฐฑ๊ทธ๋ผ์ด๋๋ก ์คํํ๊ณ ํธ์คํธ ํฌํธ 8080์ ์ปจํ
์ด๋ ํฌํธ 80์ ์ฐ๊ฒฐํ ๋ค, ์คํ ์ค์ธ ์ปจํ
์ด๋๋ฅผ ํ์ธํ์ธ์.",
|
| 303 |
+
"expected_command": "docker run -d -p 8080:80 nginx && docker ps",
|
| 304 |
+
"grading_conditions": [
|
| 305 |
+
"docker run",
|
| 306 |
+
"-d",
|
| 307 |
+
"-p 8080:80",
|
| 308 |
+
"nginx",
|
| 309 |
+
"docker ps"
|
| 310 |
+
],
|
| 311 |
+
"hint": "`-d`๋ ๋ฐฑ๊ทธ๋ผ์ด๋(detach), `-p ํธ์คํธ:์ปจํ
์ด๋`๋ก ํฌํธ๋ฅผ ๋งคํํฉ๋๋ค.",
|
| 312 |
+
"explanation": "์ปจํ
์ด๋๊ฐ ์คํ ์ค์ด๋ฉด `docker ps`์์ ํ์ธ๋ฉ๋๋ค. ์ค์ง๋ ์ปจํ
์ด๋๊น์ง ๋ณด๋ ค๋ฉด `docker ps -a`๋ฅผ ์ฌ์ฉํฉ๋๋ค.",
|
| 313 |
+
"difficulty": "easy"
|
| 314 |
+
},
|
| 315 |
+
{
|
| 316 |
+
"id": "linux-lab-53",
|
| 317 |
+
"title": "[์๋๋ฆฌ์ค] ์ ๊ท ๋์คํฌ ์ ์ฒด ์ค์ (ํํฐ์
โํฌ๋งทโ๋ง์ดํธโfstab)",
|
| 318 |
+
"task_description": "์ ๊ท ๋์คํฌ `/dev/sdb`์ ํํฐ์
์ ๋ง๋ค๊ณ ext4๋ก ํฌ๋งทํ ๋ค `/data`์ ์๊ตฌ ๋ง์ดํธํ๋ ์ ์ฒด ์ ์ฐจ๋ฅผ ์์ฑํ์ธ์.\n\n๋จ๊ณ:\n1. `/dev/sdb`์ ๋จ์ผ ์ฃผ ํํฐ์
์์ฑ (fdisk)\n2. `/dev/sdb1`์ ext4 ํ์ผ์์คํ
์์ฑ\n3. `/data` ๋ง์ดํธ ํฌ์ธํธ ์์ฑ\n4. `/dev/sdb1`์ `/data`์ ๋ง์ดํธ\n5. `/etc/fstab`์ UUID ๊ธฐ๋ฐ์ผ๋ก ๋ฑ๋ก ํ `mount -a`๋ก ๊ฒ์ฆ\n\n์ด ๋จ๊ณ ์ค `blkid /dev/sdb1`์ ๋ชฉ์ ์ ์์ ํ์ธ์.",
|
| 319 |
+
"expected_command": "fdisk /dev/sdb && mkfs.ext4 /dev/sdb1 && mkdir /data && mount /dev/sdb1 /data && blkid /dev/sdb1",
|
| 320 |
+
"grading_conditions": [
|
| 321 |
+
"fdisk /dev/sdb",
|
| 322 |
+
"mkfs.ext4 /dev/sdb1",
|
| 323 |
+
"mkdir /data",
|
| 324 |
+
"mount /dev/sdb1 /data",
|
| 325 |
+
"blkid /dev/sdb1"
|
| 326 |
+
],
|
| 327 |
+
"hint": "์์๊ฐ ์ค์ํฉ๋๋ค: fdisk โ mkfs โ mkdir โ mount โ blkid(UUID ํ์ธ) โ fstab ๋ฑ๋ก โ mount -a",
|
| 328 |
+
"explanation": "์ด ํ๋ฆ์ LFCS ์ค๊ธฐ์์ ๊ฐ์ฅ ์์ฃผ ๋์ค๋ ๋ณตํฉ ์คํ ๋ฆฌ์ง ์๋๋ฆฌ์ค์
๋๋ค. fstab์ UUID๋ฅผ ์ฐ๋ ์ด์ ๋ ์ฌ๋ถํ
์ ๋๋ฐ์ด์ค ์์๊ฐ ๋ฐ๋์ด๋ ์ฌ๋ฐ๋ฅธ ํํฐ์
์ด ๋ง์ดํธ๋๋๋ก ๋ณด์ฅํ๊ธฐ ์ํด์์
๋๋ค.",
|
| 329 |
+
"difficulty": "hard"
|
| 330 |
+
},
|
| 331 |
+
{
|
| 332 |
+
"id": "linux-lab-54",
|
| 333 |
+
"title": "[์๋๋ฆฌ์ค] LVM ๋ณผ๋ฅจ ํ์ฅ (PVโVG ํ์ฅโLV ํ์ฅโFS ํ์ฅ)",
|
| 334 |
+
"task_description": "๊ธฐ์กด VG `vg_data`์ ์ PV `/dev/sdc`๋ฅผ ์ถ๊ฐํ๊ณ , LV `lv_app`์ 10GB ๋๋ฆฐ ๋ค ext4 ํ์ผ์์คํ
๊น์ง ํ์ฅํ์ธ์.\n\n๋จ๊ณ:\n1. `/dev/sdc`๋ฅผ PV๋ก ์ด๊ธฐํ\n2. `/dev/sdc`๋ฅผ `vg_data`์ ์ถ๊ฐ\n3. `lv_app`์ 10GB ์ฆ๊ฐ\n4. ext4 ํ์ผ์์คํ
ํ์ฅ (๋ฌด์ค๋จ)",
|
| 335 |
+
"expected_command": "pvcreate /dev/sdc && vgextend vg_data /dev/sdc && lvextend -L +10G /dev/vg_data/lv_app && resize2fs /dev/vg_data/lv_app",
|
| 336 |
+
"grading_conditions": [
|
| 337 |
+
"pvcreate /dev/sdc",
|
| 338 |
+
"vgextend vg_data /dev/sdc",
|
| 339 |
+
"lvextend",
|
| 340 |
+
"+10G",
|
| 341 |
+
"/dev/vg_data/lv_app",
|
| 342 |
+
"resize2fs"
|
| 343 |
+
],
|
| 344 |
+
"hint": "LVM ํ์ฅ ์์: pvcreate โ vgextend โ lvextend โ resize2fs. `lvextend -r` ์ต์
์ผ๋ก resize2fs๋ฅผ ํตํฉํ ์๋ ์์ต๋๋ค.",
|
| 345 |
+
"explanation": "LVM์ ๊ฐ์ ์ ์๋น์ค ์ค๋จ ์์ด ๋ณผ๋ฅจ์ ํ์ฅํ ์ ์๋ค๋ ์ ์
๋๋ค. `lvextend -r`์ LV ํ์ฅ๊ณผ ํ์ผ์์คํ
ํ์ฅ์ ํ ๋ฒ์ ์ฒ๋ฆฌํฉ๋๋ค.",
|
| 346 |
+
"difficulty": "hard"
|
| 347 |
+
},
|
| 348 |
+
{
|
| 349 |
+
"id": "linux-lab-55",
|
| 350 |
+
"title": "[์๋๋ฆฌ์ค] ํ ๊ณต์ ๋๋ ํฐ๋ฆฌ ๋ณด์ ์ค์ (๊ทธ๋ฃน+SGID+ACL)",
|
| 351 |
+
"task_description": "๊ฐ๋ฐํ ๊ณต์ ๋๋ ํฐ๋ฆฌ `/srv/devteam`์ ์ค์ ํ์ธ์.\n\n์๊ตฌ์ฌํญ:\n1. `devteam` ๊ทธ๋ฃน ์์ฑ\n2. `alice`์ `bob`์ `devteam`์ ์ถ๊ฐ\n3. `/srv/devteam` ์์ ๊ทธ๋ฃน์ `devteam`์ผ๋ก ์ค์ \n4. ๊ทธ๋ฃน์ rwx ๊ถํ ๋ถ์ฌ, ๊ธฐํ ์ฌ์ฉ์๋ ์ ๊ทผ ๋ถ๊ฐ\n5. ์๋ก ์์ฑ๋๋ ํ์ผ๋ ์๋์ผ๋ก `devteam` ์์ ๊ฐ ๋๋๋ก SGID ์ค์ \n6. ์ค์ง `alice`์๊ฒ๋ง ACL๋ก ์ถ๊ฐ ์คํ ๊ถํ ๋ถ์ฌ",
|
| 352 |
+
"expected_command": "groupadd devteam && usermod -aG devteam alice && usermod -aG devteam bob && chgrp devteam /srv/devteam && chmod 2770 /srv/devteam && setfacl -m u:alice:rwx /srv/devteam",
|
| 353 |
+
"grading_conditions": [
|
| 354 |
+
"groupadd devteam",
|
| 355 |
+
"usermod -aG devteam alice",
|
| 356 |
+
"usermod -aG devteam bob",
|
| 357 |
+
"chgrp devteam",
|
| 358 |
+
"chmod 2770",
|
| 359 |
+
"setfacl -m u:alice"
|
| 360 |
+
],
|
| 361 |
+
"hint": "SGID ๋นํธ๋ chmod ์์ 2๋ฅผ ๋ถ์
๋๋ค(์: 2770). ACL์ ๊ธฐ๋ณธ ๊ถํ๊ณผ ๋
๋ฆฝ์ ์ผ๋ก ๋์ํฉ๋๋ค.",
|
| 362 |
+
"explanation": "2770 = SGID(2) + ์์ ์rwx(7) + ๊ทธ๋ฃนrwx(7) + ๊ธฐํ์์(0). SGID๊ฐ ์์ผ๋ฉด ํด๋น ๋๋ ํฐ๋ฆฌ์์ ์์ฑ๋ ํ์ผ์ด ์๋์ผ๋ก ๋ถ๋ชจ ๋๋ ํฐ๋ฆฌ์ ๊ทธ๋ฃน์ ์์ํฉ๋๋ค.",
|
| 363 |
+
"difficulty": "hard"
|
| 364 |
+
},
|
| 365 |
+
{
|
| 366 |
+
"id": "linux-lab-56",
|
| 367 |
+
"title": "[์๋๋ฆฌ์ค] ์ปค์คํ
systemd ์๋น์ค ๋ฑ๋ก ๋ฐ ๋ณด์ ๊ฐํ",
|
| 368 |
+
"task_description": "`/opt/myapp/run.sh` ์คํฌ๋ฆฝํธ๋ฅผ systemd ์๋น์ค๋ก ๋ฑ๋กํ์ธ์.\n\n์๊ตฌ์ฌํญ:\n1. `/etc/systemd/system/myapp.service` ํ์ผ ์์ฑ\n2. ์ ์ฉ ์์คํ
๊ณ์ `myapp`์ผ๋ก ์คํ (๋ก๊ทธ์ธ ๋ถ๊ฐ)\n3. ๋คํธ์ํฌ ์ค๋น ํ ์์ (`After=network.target`)\n4. ์คํจ ์ ์๋ ์ฌ์์\n5. ๋ถํ
์ ์๋ ์์ ์ค์ \n\n์์ฑ ํ ์ฆ์ ์์๊น์ง ์๋ฃํ์ธ์.",
|
| 369 |
+
"expected_command": "useradd -r -s /sbin/nologin myapp && systemctl daemon-reload && systemctl enable --now myapp",
|
| 370 |
+
"grading_conditions": [
|
| 371 |
+
"useradd -r",
|
| 372 |
+
"-s /sbin/nologin myapp",
|
| 373 |
+
"systemctl daemon-reload",
|
| 374 |
+
"systemctl enable",
|
| 375 |
+
"myapp"
|
| 376 |
+
],
|
| 377 |
+
"hint": "์์คํ
์๋น์ค ๊ณ์ ์ `useradd -r`(์์คํ
๊ณ์ )๊ณผ `-s /sbin/nologin`(๋ก๊ทธ์ธ ์ฐจ๋จ)์ผ๋ก ์์ฑํฉ๋๋ค. ์ ๋ ํ์ผ ์์ฑ ํ daemon-reload ํ์.",
|
| 378 |
+
"explanation": "์ด์ ํ๊ฒฝ์์ ์๋น์ค๋ ์ ์ฉ ์ต์ ๊ถํ ๊ณ์ ์ผ๋ก ์คํํ๋ ๊ฒ์ด ๋ณด์ ๋ชจ๋ฒ ์ฌ๋ก์
๋๋ค. `-r` ํ๋๊ทธ๋ ์์คํ
๊ณ์ ์ฉ ๋ฎ์ UID๋ฅผ ๋ถ์ฌํฉ๋๋ค.",
|
| 379 |
+
"difficulty": "hard"
|
| 380 |
+
},
|
| 381 |
+
{
|
| 382 |
+
"id": "linux-lab-57",
|
| 383 |
+
"title": "[์๋๋ฆฌ์ค] SSH ๋ณด์ ๊ฐํ (ํค ์ธ์ฆ ์ ํ + ๋น๋ฐ๋ฒํธ ์ฐจ๋จ)",
|
| 384 |
+
"task_description": "์๋ฒ SSH๋ฅผ ํค ๊ธฐ๋ฐ ์ธ์ฆ์ผ๋ก ์ ํํ๊ณ ๋น๋ฐ๋ฒํธ ๋ก๊ทธ์ธ์ ์ฐจ๋จํ์ธ์.\n\n๋จ๊ณ:\n1. ๋ก์ปฌ์์ ED25519 ํค ์ ์์ฑ\n2. ๊ณต๊ฐ ํค๋ฅผ ์๋ฒ `alice` ๊ณ์ ์ ๋ณต์ฌ (`ssh-copy-id`)\n3. `/etc/ssh/sshd_config`์์:\n - `PasswordAuthentication no`\n - `PermitRootLogin prohibit-password`\n4. sshd ์ฌ์์ ์ ์ค์ ๋ฌธ๋ฒ ๊ฒ์ฆ\n5. sshd ์ฌ์์",
|
| 385 |
+
"expected_command": "ssh-keygen -t ed25519 && ssh-copy-id alice@server && sshd -t && systemctl restart sshd",
|
| 386 |
+
"grading_conditions": [
|
| 387 |
+
"ssh-keygen -t ed25519",
|
| 388 |
+
"ssh-copy-id",
|
| 389 |
+
"sshd -t",
|
| 390 |
+
"systemctl restart sshd"
|
| 391 |
+
],
|
| 392 |
+
"hint": "`sshd -t`๋ ์ค์ ํ์ผ ๋ฌธ๋ฒ์ ๊ฒ์ฆํฉ๋๋ค. ์ฌ์์ ์ ์ ๋ฐ๋์ ์คํํด ์ ๊ธ ๋ฐฉ์ง.",
|
| 393 |
+
"explanation": "๋น๋ฐ๋ฒํธ ์ธ์ฆ์ ๋๊ธฐ ์ ํค ์ธ์ฆ์ด ์๋ํ๋์ง ๋ฐ๋์ ํ์ธํด์ผ ํฉ๋๋ค. `sshd -t` ์คํจ ์ ์ฌ์์ํ๋ฉด ์๋ฒ์ ์ ์ ๋ถ๊ฐ ์ํ๊ฐ ๋ ์ ์์ต๋๋ค.",
|
| 394 |
+
"difficulty": "hard"
|
| 395 |
+
},
|
| 396 |
+
{
|
| 397 |
+
"id": "linux-lab-58",
|
| 398 |
+
"title": "[์๋๋ฆฌ์ค] ๋ธ๋ฃจํธํฌ์ค IP ํ์ง ํ ๋ฐฉํ๋ฒฝ ์ฐจ๋จ",
|
| 399 |
+
"task_description": "`/var/log/auth.log`๋ฅผ ๋ถ์ํด SSH ๋ก๊ทธ์ธ ์คํจ IP๋ฅผ ์ฐพ๊ณ ufw๋ก ์ฐจ๋จํ๏ฟฝ๏ฟฝ๏ฟฝ์.\n\n๋จ๊ณ:\n1. auth.log์์ 'Failed' ํฌํจ ์ค์ IP(ํ๋ 11)๋ฅผ ์ถ์ถ\n2. ํ์ ๊ธฐ์ค ๋ด๋ฆผ์ฐจ์ ์ ๋ ฌ\n3. ์์ IP๋ฅผ ufw deny๋ก ์ฐจ๋จ\n4. ufw ๊ท์น ํ์ธ",
|
| 400 |
+
"expected_command": "grep 'Failed' /var/log/auth.log | awk '{print $11}' | sort | uniq -c | sort -rn | head -5",
|
| 401 |
+
"grading_conditions": [
|
| 402 |
+
"grep 'Failed' /var/log/auth.log",
|
| 403 |
+
"awk",
|
| 404 |
+
"sort",
|
| 405 |
+
"uniq -c",
|
| 406 |
+
"sort -rn"
|
| 407 |
+
],
|
| 408 |
+
"hint": "grepโawkโsortโuniq -cโsort -rn ํ์ดํ๋ผ์ธ์ผ๋ก IP๋ณ ์คํจ ํ์๋ฅผ ์ง๊ณํฉ๋๋ค.",
|
| 409 |
+
"explanation": "์ด ํ์ดํ๋ผ์ธ์ ๋ณด์ ๋ถ์์ ๊ธฐ๋ณธ ํจํด์
๋๋ค. ํ์ง๋ IP๋ `ufw deny from 1.2.3.4`๋ก ์ฐจ๋จํฉ๋๋ค. fail2ban์ด ์ด ๊ณผ์ ์ ์๋ํํฉ๋๋ค.",
|
| 410 |
+
"difficulty": "hard"
|
| 411 |
+
},
|
| 412 |
+
{
|
| 413 |
+
"id": "linux-lab-59",
|
| 414 |
+
"title": "[์๋๋ฆฌ์ค] Docker ์ปจํ
์ด๋ ์น ์๋ฒ ๋ฐฐํฌ ๋ฐ ๋ก๊ทธ ํ์ธ",
|
| 415 |
+
"task_description": "nginx ์ปจํ
์ด๋๋ฅผ ๋ฐฐํฌํ๊ณ ์ด์ ์ํ๋ฅผ ๊ฒ์ฆํ์ธ์.\n\n๋จ๊ณ:\n1. nginx:latest ์ด๋ฏธ์ง pull\n2. ์ด๋ฆ `webserver`, ํธ์คํธ 8080โ์ปจํ
์ด๋ 80, ๋ฐฑ๊ทธ๋ผ์ด๋๋ก ์คํ\n3. ์ปจํ
์ด๋ ์คํ ์ํ ํ์ธ\n4. `curl localhost:8080`์ผ๋ก ์๋ต ํ์ธ\n5. ์ปจํ
์ด๋ ๋ก๊ทธ ๋ง์ง๋ง 20์ค ํ์ธ",
|
| 416 |
+
"expected_command": "docker pull nginx:latest && docker run -d -p 8080:80 --name webserver nginx && docker ps && curl localhost:8080 && docker logs --tail 20 webserver",
|
| 417 |
+
"grading_conditions": [
|
| 418 |
+
"docker pull nginx",
|
| 419 |
+
"docker run -d -p 8080:80 --name webserver nginx",
|
| 420 |
+
"docker ps",
|
| 421 |
+
"curl localhost:8080",
|
| 422 |
+
"docker logs --tail 20 webserver"
|
| 423 |
+
],
|
| 424 |
+
"hint": "`docker logs --tail N`์ผ๋ก ์ต๊ทผ N์ค๋ง ๋ณผ ์ ์์ต๋๋ค. `--follow`๋ฅผ ์ถ๊ฐํ๋ฉด ์ค์๊ฐ ์คํธ๋ฆฌ๋ฐ๋ฉ๋๋ค.",
|
| 425 |
+
"explanation": "์ปจํ
์ด๋ ๋ฐฐํฌ ํ ps๋ก ์ํ, curl๋ก ์๋ต, logs๋ก ๋ด๋ถ ๋์์ ํ์ธํ๋ 3๋จ๊ณ ๊ฒ์ฆ์ ์ด์ ํ๊ฒฝ ํ์ค ์ ์ฐจ์
๋๋ค.",
|
| 426 |
+
"difficulty": "hard"
|
| 427 |
+
}
|
| 428 |
+
]
|
cert_study_app/content/linux/quizzes.json
ADDED
|
@@ -0,0 +1,1076 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[
|
| 2 |
+
{
|
| 3 |
+
"id": "linux-q29",
|
| 4 |
+
"lesson_id": "linux-passwd",
|
| 5 |
+
"question_type": "multiple_choice",
|
| 6 |
+
"question": "`passwd -l devuser`์ ์๋ฏธ๋ก ๊ฐ์ฅ ๋ง๋ ๊ฒ์?",
|
| 7 |
+
"options": [
|
| 8 |
+
"devuser ๊ณ์ ์ ์ ๊ฐ ๋น๋ฐ๋ฒํธ ๋ก๊ทธ์ธ์ ๋ง๋๋ค",
|
| 9 |
+
"devuser ๋น๋ฐ๋ฒํธ๋ฅผ ๊ฐ์ ๋ง๋ฃ์ํจ๋ค",
|
| 10 |
+
"devuser ๊ณ์ ์ ์์ ํ ์ญ์ ํ๋ค",
|
| 11 |
+
"devuser ๋น๋ฐ๋ฒํธ๋ฅผ ๋น ๊ฐ์ผ๋ก ์ด๊ธฐํํ๋ค"
|
| 12 |
+
],
|
| 13 |
+
"answer": "devuser ๊ณ์ ์ ์ ๊ฐ ๋น๋ฐ๋ฒํธ ๋ก๊ทธ์ธ์ ๋ง๋๋ค",
|
| 14 |
+
"explanation": "`passwd -l`์ ๊ณ์ ์ ์ ๊ฐ ํด๋น ์ฌ์ฉ์๊ฐ ๋น๋ฐ๋ฒํธ๋ก ๋ก๊ทธ์ธํ ์ ์๊ฒ ํฉ๋๋ค. ์ ๊ธ ํด์ ๋ `passwd -u`์
๋๋ค.",
|
| 15 |
+
"difficulty": "easy",
|
| 16 |
+
"source_id": "ubuntu-user-management"
|
| 17 |
+
},
|
| 18 |
+
{
|
| 19 |
+
"id": "linux-q30",
|
| 20 |
+
"lesson_id": "linux-groups-id",
|
| 21 |
+
"question_type": "multiple_choice",
|
| 22 |
+
"question": "ํ์ฌ ์ฌ์ฉ์์ UID, GID, ๋ณด์กฐ ๊ทธ๋ฃน ๋ชฉ๋ก์ ํ ๋ฒ์ ํ์ธํ๋ ๋ช
๋ น์?",
|
| 23 |
+
"options": [
|
| 24 |
+
"id",
|
| 25 |
+
"groups",
|
| 26 |
+
"whoami",
|
| 27 |
+
"ls -l"
|
| 28 |
+
],
|
| 29 |
+
"answer": "id",
|
| 30 |
+
"explanation": "`id`๋ UID, GID, ์ํ ๊ทธ๋ฃน ๋ชฉ๋ก์ ๋ชจ๋ ๋ณด์ฌ์ค๋๋ค. `groups`๋ ๊ทธ๋ฃน ์ด๋ฆ๋ง, `whoami`๋ ์ฌ์ฉ์ ์ด๋ฆ๋ง ๋ณด์ฌ์ค๋๋ค.",
|
| 31 |
+
"difficulty": "easy",
|
| 32 |
+
"source_id": "ubuntu-user-management"
|
| 33 |
+
},
|
| 34 |
+
{
|
| 35 |
+
"id": "linux-q31",
|
| 36 |
+
"lesson_id": "linux-acl",
|
| 37 |
+
"question_type": "multiple_choice",
|
| 38 |
+
"question": "ํ์ผ์ ์ค์ ๋ ACL ๊ถํ ๋ด์ญ์ ํ์ธํ๋ ๋ช
๋ น์?",
|
| 39 |
+
"options": [
|
| 40 |
+
"getfacl",
|
| 41 |
+
"setfacl",
|
| 42 |
+
"chmod",
|
| 43 |
+
"ls -l"
|
| 44 |
+
],
|
| 45 |
+
"answer": "getfacl",
|
| 46 |
+
"explanation": "`getfacl`๋ก ํ์ฌ ACL ์ค์ ์ ํ์ธํฉ๋๋ค. `setfacl -m`์ผ๋ก ACL์ ์ค์ ํฉ๋๋ค. `ls -l`๋ง์ผ๋ก๋ ACL ์ ์ฒด๊ฐ ๋ณด์ด์ง ์์ต๋๋ค.",
|
| 47 |
+
"difficulty": "easy",
|
| 48 |
+
"source_id": "manual-linux-basic"
|
| 49 |
+
},
|
| 50 |
+
{
|
| 51 |
+
"id": "linux-q32",
|
| 52 |
+
"lesson_id": "linux-ssh",
|
| 53 |
+
"question_type": "multiple_choice",
|
| 54 |
+
"question": "SSH ์ ์ ์คํจ ์์ธ์ผ๋ก ๊ด๋ จ์ด ์๋ ๊ฒ์?",
|
| 55 |
+
"options": [
|
| 56 |
+
"์ฌ์ฉ์์ Python ๋ฒ์ ",
|
| 57 |
+
"SSH ์๋น์ค ์คํ ์ฌ๋ถ",
|
| 58 |
+
"๋ฐฉํ๋ฒฝ 22๋ฒ ํฌํธ ํ์ฉ ์ฌ๋ถ",
|
| 59 |
+
"authorized_keys ํ์ผ ๊ถํ"
|
| 60 |
+
],
|
| 61 |
+
"answer": "์ฌ์ฉ์์ Python ๋ฒ์ ",
|
| 62 |
+
"explanation": "SSH ์ ์์ ์๋น์ค ์คํ, ๋ฐฉํ๋ฒฝ, ํค ํ์ผ ๊ถํ์ด ๋ชจ๋ ๋ง์์ผ ํฉ๋๋ค. Python ๋ฒ์ ์ SSH ์ ์๊ณผ ๋ฌด๊ดํฉ๋๋ค.",
|
| 63 |
+
"difficulty": "easy",
|
| 64 |
+
"source_id": "ubuntu-server-docs"
|
| 65 |
+
},
|
| 66 |
+
{
|
| 67 |
+
"id": "linux-q33",
|
| 68 |
+
"lesson_id": "linux-hostname-hosts",
|
| 69 |
+
"question_type": "multiple_choice",
|
| 70 |
+
"question": "`/etc/hosts` ํ์ผ์ ์ฃผ๋ ์ญํ ์?",
|
| 71 |
+
"options": [
|
| 72 |
+
"DNS ์กฐํ ์ ์ ์ฐธ์กฐ๋๋ ๋ก์ปฌ ์ด๋ฆ ํด์ ํ์ผ์ด๋ค",
|
| 73 |
+
"๋ฐฉํ๋ฒฝ ๊ท์น์ ์ ์ฅํ๋ค",
|
| 74 |
+
"์ฌ์ฉ์ ๋น๋ฐ๋ฒํธ๋ฅผ ์ ์ฅํ๋ค",
|
| 75 |
+
"swap ๊ณต๊ฐ์ ์ ์ํ๋ค"
|
| 76 |
+
],
|
| 77 |
+
"answer": "DNS ์กฐํ ์ ์ ์ฐธ์กฐ๋๋ ๋ก์ปฌ ์ด๋ฆ ํด์ ํ์ผ์ด๋ค",
|
| 78 |
+
"explanation": "`/etc/hosts`๋ DNS ์กฐํ๋ณด๋ค ๋จผ์ ์ฐธ์กฐ๋๋ ๋ก์ปฌ ์ด๋ฆ ํด์ ํ์ผ์
๋๋ค. ํ
์คํธ ํ๊ฒฝ์ด๋ ํน์ ํธ์คํธ ์ด๋ฆ ์ฌ์ ์์ ์์ฃผ ์๋๋ค.",
|
| 79 |
+
"difficulty": "easy",
|
| 80 |
+
"source_id": "ubuntu-networking"
|
| 81 |
+
},
|
| 82 |
+
{
|
| 83 |
+
"id": "linux-q34",
|
| 84 |
+
"lesson_id": "linux-netplan",
|
| 85 |
+
"question_type": "multiple_choice",
|
| 86 |
+
"question": "Ubuntu์์ netplan ๋คํธ์ํฌ ์ค์ ์ ์์คํ
์ ์ ์ฉํ๋ ๋ช
๋ น์?",
|
| 87 |
+
"options": [
|
| 88 |
+
"sudo netplan apply",
|
| 89 |
+
"sudo ifconfig apply",
|
| 90 |
+
"sudo ip apply",
|
| 91 |
+
"sudo ufw apply"
|
| 92 |
+
],
|
| 93 |
+
"answer": "sudo netplan apply",
|
| 94 |
+
"explanation": "`sudo netplan apply`๋ `/etc/netplan/*.yaml` ์ค์ ์ ํ์ฑํด ์์คํ
์ ์ ์ฉํฉ๋๋ค. YAML ๋ค์ฌ์ฐ๊ธฐ ์ค๋ฅ๊ฐ ์์ผ๋ฉด ์คํจํฉ๋๋ค.",
|
| 95 |
+
"difficulty": "easy",
|
| 96 |
+
"source_id": "ubuntu-networking"
|
| 97 |
+
},
|
| 98 |
+
{
|
| 99 |
+
"id": "linux-q35",
|
| 100 |
+
"lesson_id": "linux-curl",
|
| 101 |
+
"question_type": "multiple_choice",
|
| 102 |
+
"question": "`curl -I https://example.com`์ `-I` ์ต์
์ญํ ์?",
|
| 103 |
+
"options": [
|
| 104 |
+
"HTTP ํค๋๋ง ์์ฒญํด ์๋ต ์ํ๋ฅผ ํ์ธํ๋ค",
|
| 105 |
+
"๋ฐ์ดํฐ๋ฅผ POST๋ก ์ ์กํ๋ค",
|
| 106 |
+
"SSL ์ธ์ฆ์ ๊ฒ์ฆ์ ๊ฑด๋๋ด๋ค",
|
| 107 |
+
"JSON ํ์์ผ๋ก๋ง ์ถ๋ ฅํ๋ค"
|
| 108 |
+
],
|
| 109 |
+
"answer": "HTTP ํค๋๋ง ์์ฒญํด ์๋ต ์ํ๋ฅผ ํ์ธํ๋ค",
|
| 110 |
+
"explanation": "`-I`๋ HEAD ์์ฒญ์ ๋ณด๋ด ์๋ต ํค๋๋ง ๋ฐ์ต๋๋ค. ์๋น์ค๊ฐ ์ฌ๋ฐ๋ฅธ ์ํ ์ฝ๋๋ฅผ ๋ฐํํ๋์ง ๋น ๋ฅด๊ฒ ํ์ธํ ๋ ์ ์ฉํฉ๋๋ค.",
|
| 111 |
+
"difficulty": "easy",
|
| 112 |
+
"source_id": "ubuntu-networking"
|
| 113 |
+
},
|
| 114 |
+
{
|
| 115 |
+
"id": "linux-q36",
|
| 116 |
+
"lesson_id": "linux-ping",
|
| 117 |
+
"question_type": "multiple_choice",
|
| 118 |
+
"question": "ping์ด ์ฑ๊ณตํ๋๋ผ๋ ๋ณด์ฅ๋์ง ์๋ ๊ฒ์?",
|
| 119 |
+
"options": [
|
| 120 |
+
"HTTP ์๋น์ค๊ฐ ์ ์ ๋์ํ๋ ๊ฒ",
|
| 121 |
+
"ICMP ํต์ ์ด ๊ฐ๋ฅํ๋ค๋ ๊ฒ",
|
| 122 |
+
"๋คํธ์ํฌ ๊ฒฝ๋ก๊ฐ ์๋ค๋ ๊ฒ",
|
| 123 |
+
"IP ํต์ ์ด ๊ฐ๋ฅํ๋ค๋ ๊ฒ"
|
| 124 |
+
],
|
| 125 |
+
"answer": "HTTP ์๋น์ค๊ฐ ์ ์ ๋์ํ๋ ๊ฒ",
|
| 126 |
+
"explanation": "ping์ ICMP ์๋ต๋ง ํ์ธํฉ๋๋ค. ๋ฐฉํ๋ฒฝ์ด ICMP๋ฅผ ํ์ฉํด๋ HTTP ์๋น์ค๊ฐ ๋ด๋ ค๊ฐ ์์ ์ ์๊ณ , ๋ฐ๋๋ก HTTP๊ฐ ๋์ด๋ ICMP๊ฐ ๋งํ ์ ์์ต๋๋ค.",
|
| 127 |
+
"difficulty": "easy",
|
| 128 |
+
"source_id": "ubuntu-networking"
|
| 129 |
+
},
|
| 130 |
+
{
|
| 131 |
+
"id": "linux-q37",
|
| 132 |
+
"lesson_id": "linux-top",
|
| 133 |
+
"question_type": "multiple_choice",
|
| 134 |
+
"question": "`top` ๋ช
๋ น์ด๊ฐ ๊ฐ์ฅ ์ ํฉํ ์ํฉ์?",
|
| 135 |
+
"options": [
|
| 136 |
+
"CPU/๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋์ด ๋์ ํ๋ก์ธ์ค๋ฅผ ์ค์๊ฐ์ผ๋ก ํ์ธํ ๋",
|
| 137 |
+
"ํ์ผ ์ด๋ฆ ํจํด์ผ๋ก ๊ฒ์ํ ๋",
|
| 138 |
+
"ํจํค์ง๋ฅผ ์ค์นํ ๋",
|
| 139 |
+
"ํ์ผ์์คํ
์ฌ์ฉ๋์ ๋ณผ ๋"
|
| 140 |
+
],
|
| 141 |
+
"answer": "CPU/๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋์ด ๋์ ํ๋ก์ธ์ค๋ฅผ ์ค์๊ฐ์ผ๋ก ํ์ธํ ๋",
|
| 142 |
+
"explanation": "`top`์ CPU, ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋๊ณผ ํ๋ก์ธ์ค ๋ชฉ๋ก์ ์ค์๊ฐ์ผ๋ก ๊ฐฑ์ ํด ๋ณด์ฌ์ค๋๋ค. ์๋ฒ ๋ถํ ์์ธ ํ์
์ ์์ฃผ ์๋๋ค.",
|
| 143 |
+
"difficulty": "easy",
|
| 144 |
+
"source_id": "ubuntu-server-docs"
|
| 145 |
+
},
|
| 146 |
+
{
|
| 147 |
+
"id": "linux-q38",
|
| 148 |
+
"lesson_id": "linux-nice",
|
| 149 |
+
"question_type": "multiple_choice",
|
| 150 |
+
"question": "`nice -n 10 command`์์ nice ๊ฐ์ด ๋์์๋ก ์ด๋ป๊ฒ ๋๋๊ฐ?",
|
| 151 |
+
"options": [
|
| 152 |
+
"๋ค๋ฅธ ํ๋ก์ธ์ค์ CPU๋ฅผ ์๋ณดํ๋ ๋ฎ์ ์ฐ์ ์์๋ฅผ ๊ฐ์ง๋ค",
|
| 153 |
+
"CPU ์ฝ์ด๋ฅผ ๋ ๋ง์ด ์ฌ์ฉํ๋ค",
|
| 154 |
+
"์ง์ ๋ ๋ถ ํ์ ์คํ๋๋ค",
|
| 155 |
+
"๋ฉ๋ชจ๋ฆฌ๋ฅผ ๋ ๋ง์ด ์ฐจ์งํ๋ค"
|
| 156 |
+
],
|
| 157 |
+
"answer": "๋ค๋ฅธ ํ๋ก์ธ์ค์ CPU๋ฅผ ์๋ณดํ๋ ๋ฎ์ ์ฐ์ ์์๋ฅผ ๊ฐ์ง๋ค",
|
| 158 |
+
"explanation": "nice ๊ฐ์ด ๋์์๋ก ๋ค๋ฅธ ํ๋ก์ธ์ค์๊ฒ CPU๋ฅผ ๋ ์๋ณดํฉ๋๋ค. ๋ฒ์๋ -20(๊ฐ์ฅ ๋์ ์ฐ์ ์์)์์ 19(๊ฐ์ฅ ๋ฎ์ ์ฐ์ ์์)์
๋๋ค.",
|
| 159 |
+
"difficulty": "easy",
|
| 160 |
+
"source_id": "ubuntu-server-docs"
|
| 161 |
+
},
|
| 162 |
+
{
|
| 163 |
+
"id": "linux-q39",
|
| 164 |
+
"lesson_id": "linux-swap",
|
| 165 |
+
"question_type": "multiple_choice",
|
| 166 |
+
"question": "swap ์ฌ์ฉ๋์ด ๋งค์ฐ ๋์ ๋ ์์คํ
์ํ๋ฅผ ๊ฐ์ฅ ์ ๋ํ๋ด๋ ๊ฒ์?",
|
| 167 |
+
"options": [
|
| 168 |
+
"๋ฌผ๋ฆฌ ๋ฉ๋ชจ๋ฆฌ๊ฐ ๋ถ์กฑํด ๋์คํฌ๋ฅผ ๋ณด์กฐ ๋ฉ๋ชจ๋ฆฌ๋ก ์ฌ์ฉํ๊ณ ์๋ค",
|
| 169 |
+
"CPU๊ฐ ๊ณผ๋ถํ ์ํ๋ค",
|
| 170 |
+
"๋์คํฌ ๊ณต๊ฐ์ด ๊ฝ ์ฐผ๋ค",
|
| 171 |
+
"๋คํธ์ํฌ ์ฐ๊ฒฐ์ด ๋๊ฒผ๋ค"
|
| 172 |
+
],
|
| 173 |
+
"answer": "๋ฌผ๋ฆฌ ๋ฉ๋ชจ๋ฆฌ๊ฐ ๋ถ์กฑํด ๋์คํฌ๋ฅผ ๋ณด์กฐ ๋ฉ๋ชจ๋ฆฌ๋ก ์ฌ์ฉํ๊ณ ์๋ค",
|
| 174 |
+
"explanation": "swap ๊ณผ์ฌ์ฉ์ ๋ฌผ๋ฆฌ RAM ๋ถ์กฑ์ ์ ํธ์
๋๋ค. ๋์คํฌ๊ฐ RAM๋ณด๋ค ํจ์ฌ ๋๋ ค์ swap ๊ณผ๋ค ์ฌ์ฉ์ ์ฌ๊ฐํ ์ฑ๋ฅ ์ ํ๋ก ์ด์ด์ง๋๋ค.",
|
| 175 |
+
"difficulty": "easy",
|
| 176 |
+
"source_id": "ubuntu-storage"
|
| 177 |
+
},
|
| 178 |
+
{
|
| 179 |
+
"id": "linux-q40",
|
| 180 |
+
"lesson_id": "linux-lvm",
|
| 181 |
+
"question_type": "multiple_choice",
|
| 182 |
+
"question": "LVM์์ ๋ฌผ๋ฆฌ ๋ณผ๋ฅจ(PV)๋ค์ด ํฉ์ณ์ง๋ ์ค๊ฐ ๊ณ์ธต์?",
|
| 183 |
+
"options": [
|
| 184 |
+
"Volume Group (VG)",
|
| 185 |
+
"Logical Volume (LV)",
|
| 186 |
+
"/etc/fstab",
|
| 187 |
+
"partition table"
|
| 188 |
+
],
|
| 189 |
+
"answer": "Volume Group (VG)",
|
| 190 |
+
"explanation": "LVM ๊ณ์ธต์ PV(๋ฌผ๋ฆฌ ๋ณผ๋ฅจ) โ VG(๋ณผ๋ฅจ ๊ทธ๋ฃน) โ LV(๋
ผ๋ฆฌ ๋ณผ๋ฅจ) ์์
๋๋ค. VG๋ PV๋ค์ ๋ฌถ๊ณ , LV๋ VG์์ ์ฉ๋์ ๋๋ ์๋๋ค.",
|
| 191 |
+
"difficulty": "easy",
|
| 192 |
+
"source_id": "ubuntu-storage"
|
| 193 |
+
},
|
| 194 |
+
{
|
| 195 |
+
"id": "linux-q41",
|
| 196 |
+
"lesson_id": "linux-logs-var",
|
| 197 |
+
"question_type": "multiple_choice",
|
| 198 |
+
"question": "`/var/log` ๋๋ ํฐ๋ฆฌ์์ ์ฃผ๋ก ๋ณผ ์ ์๋ ๊ฒ์?",
|
| 199 |
+
"options": [
|
| 200 |
+
"์๋น์ค, ์ธ์ฆ, ์์คํ
์ ๋ก๊ทธ ํ์ผ",
|
| 201 |
+
"์ฌ์ฉ์ ํ ๋๋ ํฐ๋ฆฌ",
|
| 202 |
+
"์คํ ๊ฐ๋ฅํ ํจํค์ง ๋ฐ์ด๋๋ฆฌ",
|
| 203 |
+
"๋คํธ์ํฌ ์ค์ ํ์ผ"
|
| 204 |
+
],
|
| 205 |
+
"answer": "์๋น์ค, ์ธ์ฆ, ์์คํ
์ ๋ก๊ทธ ํ์ผ",
|
| 206 |
+
"explanation": "`/var/log`๋ nginx, syslog, auth.log, kern.log ๊ฐ์ ๋ค์ํ ๋ก๊ทธ ํ์ผ์ด ๋ชจ์ด๋ ํ์ค ์์น์
๋๋ค.",
|
| 207 |
+
"difficulty": "easy",
|
| 208 |
+
"source_id": "ubuntu-server-docs"
|
| 209 |
+
},
|
| 210 |
+
{
|
| 211 |
+
"id": "linux-q42",
|
| 212 |
+
"lesson_id": "linux-dmesg",
|
| 213 |
+
"question_type": "multiple_choice",
|
| 214 |
+
"question": "`dmesg | tail`๋ก ํ์ธํ๊ธฐ์ ๊ฐ์ฅ ์ ํฉํ ์ ๋ณด๋?",
|
| 215 |
+
"options": [
|
| 216 |
+
"๋ถํ
๊ณผ ํ๋์จ์ด ๊ด๋ จ ์ปค๋ ๋ฉ์์ง",
|
| 217 |
+
"HTTP ์๋ฒ ์ ์ ๋ก๊ทธ",
|
| 218 |
+
"์ฌ์ฉ์ ๋น๋ฐ๋ฒํธ ์ ์ฑ
",
|
| 219 |
+
"cron ์คํ ์ด๋ ฅ"
|
| 220 |
+
],
|
| 221 |
+
"answer": "๋ถํ
๊ณผ ํ๋์จ์ด ๊ด๋ จ ์ปค๋ ๋ฉ์์ง",
|
| 222 |
+
"explanation": "`dmesg`๋ ์ปค๋ ๋ง ๋ฒํผ๋ฅผ ์ถ๋ ฅํฉ๋๋ค. ๋ถํ
๊ณผ์ , ํ๋์จ์ด ๊ฐ์ง, ๋๋ผ์ด๋ฒ ์ค๋ฅ ๊ฐ์ ์์คํ
์์ค ๋ฉ์์ง๋ฅผ ๋ณผ ๋ ์ ์ฉํฉ๋๋ค.",
|
| 223 |
+
"difficulty": "easy",
|
| 224 |
+
"source_id": "ubuntu-server-docs"
|
| 225 |
+
},
|
| 226 |
+
{
|
| 227 |
+
"id": "linux-q43",
|
| 228 |
+
"lesson_id": "linux-env-path",
|
| 229 |
+
"question_type": "multiple_choice",
|
| 230 |
+
"question": "cron ์์
์ด ํฐ๋ฏธ๋์์๋ ๋์ง๋ง cron์์๋ง ์คํจํ ๋ ๋จผ์ ์์ฌํ ์์ธ์?",
|
| 231 |
+
"options": [
|
| 232 |
+
"PATH ํ๊ฒฝ ๋ณ์๊ฐ cron๊ณผ ํฐ๋ฏธ๋์์ ๋ค๋ฅด๋ค",
|
| 233 |
+
"๋์คํฌ ๊ณต๊ฐ์ด ๋ถ์กฑํ๋ค",
|
| 234 |
+
"SSH ํค ํ์ผ์ด ์๋ค",
|
| 235 |
+
"systemctl์ด ์ค์ง๋๋ค"
|
| 236 |
+
],
|
| 237 |
+
"answer": "PATH ํ๊ฒฝ ๋ณ์๊ฐ cron๊ณผ ํฐ๋ฏธ๋์์ ๋ค๋ฅด๋ค",
|
| 238 |
+
"explanation": "cron๏ฟฝ๏ฟฝ๏ฟฝ ๋ก๊ทธ์ธ shell๋ณด๋ค ํจ์ฌ ์ ํ๋ PATH๋ฅผ ์๋๋ค. ์คํฌ๋ฆฝํธ์์ ์ ๋ ๊ฒฝ๋ก๋ฅผ ์ฌ์ฉํ๊ฑฐ๋ crontab์์ PATH๋ฅผ ์ง์ ์ค์ ํ๋ฉด ํด๊ฒฐ๋ฉ๋๋ค.",
|
| 239 |
+
"difficulty": "easy",
|
| 240 |
+
"source_id": "linux-bash-cd"
|
| 241 |
+
},
|
| 242 |
+
{
|
| 243 |
+
"id": "linux-q44",
|
| 244 |
+
"lesson_id": "linux-wildcard",
|
| 245 |
+
"question_type": "multiple_choice",
|
| 246 |
+
"question": "`ls *.log` ๋ช
๋ น์์ `*.log` ํจํด์ ํ์ผ ๋ชฉ๋ก์ผ๋ก ํ์ฅํ๋ ์ฃผ์ฒด๋?",
|
| 247 |
+
"options": [
|
| 248 |
+
"Shell (bash/zsh)",
|
| 249 |
+
"ls ๋ช
๋ น์ด ์์ฒด",
|
| 250 |
+
"kernel",
|
| 251 |
+
"ํ์ผ์์คํ
๋๋ผ์ด๋ฒ"
|
| 252 |
+
],
|
| 253 |
+
"answer": "Shell (bash/zsh)",
|
| 254 |
+
"explanation": "์์ผ๋์นด๋ ๊ธ๋ก๋น(glob)์ shell์ด ๋ช
๋ น ์คํ ์ ์ ํ์ผ๋ช
๋ชฉ๋ก์ผ๋ก ํ์ฅํฉ๋๋ค. ls๊ฐ ์๋๋ผ shell์ด ์ฒ๋ฆฌํฉ๋๋ค.",
|
| 255 |
+
"difficulty": "easy",
|
| 256 |
+
"source_id": "linux-bash-cd"
|
| 257 |
+
},
|
| 258 |
+
{
|
| 259 |
+
"id": "linux-q45",
|
| 260 |
+
"lesson_id": "linux-service-port",
|
| 261 |
+
"question_type": "multiple_choice",
|
| 262 |
+
"question": "`systemctl is-active nginx`๊ฐ active์ธ๋ฐ๋ 80ํฌํธ์ ์ฐ๊ฒฐ์ด ์ ๋ ๋ ํ์ธ ๋์์ด ์๋ ๊ฒ์?",
|
| 263 |
+
"options": [
|
| 264 |
+
"์ฌ์ฉ์์ SSH ๊ณต๊ฐ ํค",
|
| 265 |
+
"๋ฐฉํ๋ฒฝ 80ํฌํธ ํ์ฉ ์ฌ๋ถ",
|
| 266 |
+
"nginx๊ฐ 80ํฌํธ์์ listen ์ค์ธ์ง",
|
| 267 |
+
"nginx ์ค์ ํ์ผ ๋ฌธ๋ฒ ์ค๋ฅ"
|
| 268 |
+
],
|
| 269 |
+
"answer": "์ฌ์ฉ์์ SSH ๊ณต๊ฐ ํค",
|
| 270 |
+
"explanation": "์๋น์ค๊ฐ active์ฌ๋ ๋ฐฉํ๋ฒฝ, ํฌํธ listen ์ค์ , ์ค์ ํ์ผ ์ค๋ฅ๋ก ์ฐ๊ฒฐ์ด ์ ๋ ์ ์์ต๋๋ค. SSH ๊ณต๊ฐ ํค๋ 80ํฌํธ ์ฐ๊ฒฐ๊ณผ ๋ฌด๊ดํฉ๋๋ค.",
|
| 271 |
+
"difficulty": "easy",
|
| 272 |
+
"source_id": "linux-man7-ip"
|
| 273 |
+
},
|
| 274 |
+
{
|
| 275 |
+
"id": "linux-q46",
|
| 276 |
+
"lesson_id": "linux-repo",
|
| 277 |
+
"question_type": "multiple_choice",
|
| 278 |
+
"question": "`apt update` ์คํ ์ ํน์ repository์์ ์ค๋ฅ๊ฐ ๋ ๋ ๋จผ์ ์์ฌํ ์์ธ์?",
|
| 279 |
+
"options": [
|
| 280 |
+
"repository URL์ด๋ GPG ํค ์ค์ ๋ฌธ์ ",
|
| 281 |
+
"CPU ์จ๋๊ฐ ๋๋ค",
|
| 282 |
+
"swap ๊ณต๊ฐ์ด ๋ถ์กฑํ๋ค",
|
| 283 |
+
"์คํ ์ค์ธ ํ๋ก์ธ์ค ์๊ฐ ๋ง๋ค"
|
| 284 |
+
],
|
| 285 |
+
"answer": "repository URL์ด๋ GPG ํค ์ค์ ๋ฌธ์ ",
|
| 286 |
+
"explanation": "`apt update` ์คํจ๋ repository URL ์ค๋ฅ, ๋คํธ์ํฌ ์ฐจ๋จ, GPG ์๋ช
ํค ๋ฌธ์ ๊ฐ ์ฃผ๋ ์์ธ์
๋๋ค.",
|
| 287 |
+
"difficulty": "easy",
|
| 288 |
+
"source_id": "ubuntu-package-management"
|
| 289 |
+
},
|
| 290 |
+
{
|
| 291 |
+
"id": "linux-q47",
|
| 292 |
+
"lesson_id": "linux-head-tail",
|
| 293 |
+
"question_type": "multiple_choice",
|
| 294 |
+
"question": "์ฆ๊ฐํ๋ ๋ก๊ทธ ํ์ผ์ ์ค์๊ฐ์ผ๋ก ๊ณ์ ์ถ์ ํ๋ ๋ช
๋ น์ผ๋ก ๊ฐ์ฅ ์ ํฉํ ๊ฒ์?",
|
| 295 |
+
"options": [
|
| 296 |
+
"tail -f /var/log/syslog",
|
| 297 |
+
"head -f /var/log/syslog",
|
| 298 |
+
"cat -f /var/log/syslog",
|
| 299 |
+
"watch /var/log/syslog"
|
| 300 |
+
],
|
| 301 |
+
"answer": "tail -f /var/log/syslog",
|
| 302 |
+
"explanation": "`tail -f`๋ ํ์ผ ๋์ ์ถ๊ฐ๋๋ ๋ด์ฉ์ ์ค์๊ฐ์ผ๋ก ๊ณ์ ๋ณด์ฌ์ค๋๋ค. ๋ก๊ทธ ๋ชจ๋ํฐ๋ง์ ๊ฐ์ฅ ๋ง์ด ์๋๋ค.",
|
| 303 |
+
"difficulty": "easy",
|
| 304 |
+
"source_id": "manual-linux-basic"
|
| 305 |
+
},
|
| 306 |
+
{
|
| 307 |
+
"id": "linux-q48",
|
| 308 |
+
"lesson_id": "linux-sed",
|
| 309 |
+
"question_type": "multiple_choice",
|
| 310 |
+
"question": "`sed 's/old/new/g' file.txt`์ ์ญํ ์?",
|
| 311 |
+
"options": [
|
| 312 |
+
"file.txt์ old๋ฅผ ๋ชจ๋ new๋ก ๊ต์ฒดํด ํ์ค ์ถ๋ ฅ์ผ๋ก ๋ณด๋ธ๋ค",
|
| 313 |
+
"file.txt๋ฅผ ์ ๋ ฌํด ์ถ๋ ฅํ๋ค",
|
| 314 |
+
"file.txt์์ old ์ค์ ์ญ์ ํ๋ค",
|
| 315 |
+
"file.txt๋ฅผ ์ ํ์ผ๋ก ๋ณต์ฌํ๋ค"
|
| 316 |
+
],
|
| 317 |
+
"answer": "file.txt์ old๋ฅผ ๋ชจ๋ new๋ก ๊ต์ฒดํด ํ์ค ์ถ๋ ฅ์ผ๋ก ๋ณด๋ธ๋ค",
|
| 318 |
+
"explanation": "`sed 's/ํจํด/๊ต์ฒด/g'`๋ ํ์ผ์์ ํจํด์ ์ฐพ์ ๊ต์ฒดํ ๊ฒฐ๊ณผ๋ฅผ ์ถ๋ ฅํฉ๋๋ค. `-i` ์์ด๋ ์๋ณธ ํ์ผ์ ๋ฐ๊พธ์ง ์์ต๋๋ค.",
|
| 319 |
+
"difficulty": "easy",
|
| 320 |
+
"source_id": "manual-linux-basic"
|
| 321 |
+
},
|
| 322 |
+
{
|
| 323 |
+
"id": "linux-q49",
|
| 324 |
+
"lesson_id": "linux-text-pipeline",
|
| 325 |
+
"question_type": "multiple_choice",
|
| 326 |
+
"question": "ํ์ผ ์ ์ฒด์์ ์ค๋ณต ์ค์ ์ ๊ฑฐํ๋ ค ํ ๋ `uniq` ์ ์ ์ผ๋ฐ์ ์ผ๋ก ํ์ํ ๋ช
๋ น์?",
|
| 327 |
+
"options": [
|
| 328 |
+
"sort",
|
| 329 |
+
"cut",
|
| 330 |
+
"wc",
|
| 331 |
+
"grep"
|
| 332 |
+
],
|
| 333 |
+
"answer": "sort",
|
| 334 |
+
"explanation": "`uniq`์ ์ฐ์๋ ์ค๋ณต ์ค๋ง ์ ๊ฑฐํฉ๋๋ค. ํ์ผ ์ ์ฒด์์ ์ค๋ณต์ ์ ๊ฑฐํ๋ ค๋ฉด ๋จผ์ `sort`๋ก ์ ๋ ฌํ ๋ค `uniq`์ ์ ์ฉํด์ผ ํฉ๋๋ค.",
|
| 335 |
+
"difficulty": "easy",
|
| 336 |
+
"source_id": "manual-linux-basic"
|
| 337 |
+
},
|
| 338 |
+
{
|
| 339 |
+
"id": "linux-q50",
|
| 340 |
+
"lesson_id": "linux-awk",
|
| 341 |
+
"question_type": "multiple_choice",
|
| 342 |
+
"question": "`awk '{print $2}' access.log`๊ฐ ํ๋ ์ผ์?",
|
| 343 |
+
"options": [
|
| 344 |
+
"๊ฐ ์ค์ ๋ ๋ฒ์งธ ํ๋๋ฅผ ์ถ๋ ฅํ๋ค",
|
| 345 |
+
"๋ ๋ฒ์งธ ์ค๋ง ์ถ๋ ฅํ๋ค",
|
| 346 |
+
"๋ ๋ฒ์งธ ํ์ผ์ ์ฐ๋ค",
|
| 347 |
+
"ํ๋ ๊ตฌ๋ถ์๋ฅผ 2๋ฒ์ผ๋ก ๋ฐ๊พผ๋ค"
|
| 348 |
+
],
|
| 349 |
+
"answer": "๊ฐ ์ค์ ๋ ๋ฒ์งธ ํ๋๋ฅผ ์ถ๋ ฅํ๋ค",
|
| 350 |
+
"explanation": "awk์์ `$1`, `$2`, `$N`์ ๊ณต๋ฐฑ์ผ๋ก ๊ตฌ๋ถ๋ ๊ฐ ํ๋๋ฅผ ์๋ฏธํฉ๋๋ค. `$2`๋ ๊ฐ ์ค์ ๋ ๋ฒ์งธ ํ๋๋ฅผ ์ถ๋ ฅํฉ๋๋ค.",
|
| 351 |
+
"difficulty": "easy",
|
| 352 |
+
"source_id": "manual-linux-basic"
|
| 353 |
+
},
|
| 354 |
+
{
|
| 355 |
+
"id": "linux-q51",
|
| 356 |
+
"lesson_id": "linux-ln-symlink",
|
| 357 |
+
"question_type": "multiple_choice",
|
| 358 |
+
"question": "`ln -s /etc/nginx/nginx.conf ~/nginx.conf`๋ก ๋ง๋ค์ด์ง๋ ๊ฒ์?",
|
| 359 |
+
"options": [
|
| 360 |
+
"nginx.conf๋ฅผ ๊ฐ๋ฆฌํค๋ ์ฌ๋ณผ๋ฆญ ๋งํฌ",
|
| 361 |
+
"nginx.conf์ ํ๋ ๋ณต์ฌ๋ณธ",
|
| 362 |
+
"nginx.conf๋ผ๋ ๋๋ ํฐ๋ฆฌ",
|
| 363 |
+
"nginx.conf์ ์ด๋ฆ๋ง ๋ณ๊ฒฝํ ๊ฒ"
|
| 364 |
+
],
|
| 365 |
+
"answer": "nginx.conf๋ฅผ ๊ฐ๋ฆฌํค๋ ์ฌ๋ณผ๋ฆญ ๋งํฌ",
|
| 366 |
+
"explanation": "`ln -s`๋ ์๋ณธ ํ์ผ์ ๊ฐ๋ฆฌํค๋ ์ฌ๋ณผ๋ฆญ ๋งํฌ๋ฅผ ๋ง๋ญ๋๋ค. `ls -l`์์ `->` ํ์๋ก ํ์ธํ ์ ์์ต๋๋ค.",
|
| 367 |
+
"difficulty": "easy",
|
| 368 |
+
"source_id": "manual-linux-basic"
|
| 369 |
+
},
|
| 370 |
+
{
|
| 371 |
+
"id": "linux-q52",
|
| 372 |
+
"lesson_id": "linux-bg-fg-jobs",
|
| 373 |
+
"question_type": "multiple_choice",
|
| 374 |
+
"question": "ํฐ๋ฏธ๋์ด ๋ซํ๋ ์์
์ด ๊ณ์ ์คํ๋๋๋ก ๋ฐฑ๊ทธ๋ผ์ด๋๋ก ์คํํ๋ ๋ช
๋ น์?",
|
| 375 |
+
"options": [
|
| 376 |
+
"nohup long-command &",
|
| 377 |
+
"long-command &",
|
| 378 |
+
"bg long-command",
|
| 379 |
+
"jobs -r long-command"
|
| 380 |
+
],
|
| 381 |
+
"answer": "nohup long-command &",
|
| 382 |
+
"explanation": "`nohup`์ ํฐ๋ฏธ๋ ์ข
๋ฃ ์ ๋ณด๋ด๋ HUP ์๊ทธ๋์ ๋ฌด์ํด ์์
์ด ๊ณ์ ์คํ๋๋๋ก ํฉ๋๋ค. `&`๋ง์ผ๋ก๋ ํฐ๋ฏธ๋์ด ๋ซํ๋ฉด ์์
์ด ์ข
๋ฃ๋ฉ๋๋ค.",
|
| 383 |
+
"difficulty": "easy",
|
| 384 |
+
"source_id": "ubuntu-server-docs"
|
| 385 |
+
},
|
| 386 |
+
{
|
| 387 |
+
"id": "linux-q53",
|
| 388 |
+
"lesson_id": "linux-shell-script-basics",
|
| 389 |
+
"question_type": "multiple_choice",
|
| 390 |
+
"question": "์ ์คํฌ๋ฆฝํธ์์ ์คํฌ๋ฆฝํธ์ ์ ๋ฌ๋ ์ฒซ ๋ฒ์งธ ์ธ์๋ฅผ ์ฐธ์กฐํ๋ ๋ณ์๋?",
|
| 391 |
+
"options": [
|
| 392 |
+
"$1",
|
| 393 |
+
"$0",
|
| 394 |
+
"$@",
|
| 395 |
+
"$$"
|
| 396 |
+
],
|
| 397 |
+
"answer": "$1",
|
| 398 |
+
"explanation": "`$0`์ ์คํฌ๋ฆฝํธ ์ด๋ฆ, `$1`์ ์ฒซ ๋ฒ์งธ ์ธ์, `$@`๋ ๋ชจ๋ ์ธ์ ๋ชฉ๋ก, `$$`๋ ํ์ฌ ํ๋ก์ธ์ค PID์
๋๋ค.",
|
| 399 |
+
"difficulty": "easy",
|
| 400 |
+
"source_id": "linux-bash-cd"
|
| 401 |
+
},
|
| 402 |
+
{
|
| 403 |
+
"id": "linux-q54",
|
| 404 |
+
"lesson_id": "linux-ls",
|
| 405 |
+
"question_type": "multiple_choice",
|
| 406 |
+
"question": "์จ๊น ํ์ผ์ ํฌํจํด ์์ธ ์ ๋ณด๋ฅผ ๋ณด๋ ls ์ต์
์กฐํฉ์?",
|
| 407 |
+
"options": [
|
| 408 |
+
"ls -rh",
|
| 409 |
+
"ls -al",
|
| 410 |
+
"ls -d",
|
| 411 |
+
"ls -t"
|
| 412 |
+
],
|
| 413 |
+
"answer": "ls -al",
|
| 414 |
+
"explanation": "`-a`๋ ์ ์ผ๋ก ์์ํ๋ ์จ๊น ํ์ผ ํฌํจ, `-l`์ ๊ถํยท์์ ์ยทํฌ๊ธฐยท๋ ์ง๋ฅผ ํฌํจํ ๊ธด ํ์ ์ถ๋ ฅ์
๋๋ค.",
|
| 415 |
+
"source_id": "manual-linux-basic",
|
| 416 |
+
"difficulty": "easy"
|
| 417 |
+
},
|
| 418 |
+
{
|
| 419 |
+
"id": "linux-q55",
|
| 420 |
+
"lesson_id": "linux-cd",
|
| 421 |
+
"question_type": "multiple_choice",
|
| 422 |
+
"question": "`cd -` ๋ช
๋ น์ด์ ๊ฒฐ๊ณผ๋?",
|
| 423 |
+
"options": [
|
| 424 |
+
"๋ฃจํธ ๋๋ ํฐ๋ฆฌ๋ก ์ด๋",
|
| 425 |
+
"์ด์ ๋๋ ํฐ๋ฆฌ๋ก ์ด๋",
|
| 426 |
+
"ํ ๋๋ ํฐ๋ฆฌ๋ก ์ด๋",
|
| 427 |
+
"์์ ๋๋ ํฐ๋ฆฌ๋ก ์ด๋"
|
| 428 |
+
],
|
| 429 |
+
"answer": "์ด์ ๋๋ ํฐ๋ฆฌ๋ก ์ด๋",
|
| 430 |
+
"explanation": "`cd -`๋ OLDPWD์ ์ ์ฅ๋ ์ง์ ๋๋ ํฐ๋ฆฌ๋ก ๋์๊ฐ๋๋ค. ๋ ๋๋ ํฐ๋ฆฌ ์ฌ์ด๋ฅผ ๋น ๋ฅด๊ฒ ์ค๊ฐ ๋ ์ ์ฉํฉ๋๋ค.",
|
| 431 |
+
"source_id": "manual-linux-basic",
|
| 432 |
+
"difficulty": "easy"
|
| 433 |
+
},
|
| 434 |
+
{
|
| 435 |
+
"id": "linux-q56",
|
| 436 |
+
"lesson_id": "linux-cat",
|
| 437 |
+
"question_type": "multiple_choice",
|
| 438 |
+
"question": "ํ์ผ ๋ด์ฉ์ ์ค ๋ฒํธ์ ํจ๊ป ์ถ๋ ฅํ๋ cat ์ต์
์?",
|
| 439 |
+
"options": [
|
| 440 |
+
"-n",
|
| 441 |
+
"-v",
|
| 442 |
+
"-e",
|
| 443 |
+
"-s"
|
| 444 |
+
],
|
| 445 |
+
"answer": "-n",
|
| 446 |
+
"explanation": "`cat -n`์ ๋ชจ๋ ์ค์ ๋ฒํธ๋ฅผ ๋ถ์ฌ ์ถ๋ ฅํฉ๋๋ค. ์คํฌ๋ฆฝํธ ๋๋ฒ๊น
์ด๋ ํน์ ์ค ์์น ํ์ธ์ ์ ์ฉํฉ๋๋ค.",
|
| 447 |
+
"source_id": "manual-linux-basic",
|
| 448 |
+
"difficulty": "easy"
|
| 449 |
+
},
|
| 450 |
+
{
|
| 451 |
+
"id": "linux-q57",
|
| 452 |
+
"lesson_id": "linux-process-ps-kill",
|
| 453 |
+
"question_type": "multiple_choice",
|
| 454 |
+
"question": "์คํ ์ค์ธ ๋ชจ๋ ํ๋ก์ธ์ค๋ฅผ ์ฌ์ฉ์ ์ด๋ฆ๊ณผ ํจ๊ป ์ ์ฒด ๋ชฉ๋ก์ผ๋ก ๋ณด๋ ๋ช
๋ น์?",
|
| 455 |
+
"options": [
|
| 456 |
+
"ps aux",
|
| 457 |
+
"ps -e",
|
| 458 |
+
"top -n1",
|
| 459 |
+
"kill -l"
|
| 460 |
+
],
|
| 461 |
+
"answer": "ps aux",
|
| 462 |
+
"explanation": "`ps aux`๋ ๋ชจ๋ ์ฌ์ฉ์์ ์ ์ฒด ํ๋ก์ธ์ค๋ฅผ CPU/๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋๊ณผ ํจ๊ป ๋ณด์ฌ์ค๋๋ค. ์ํ์์ ๊ฐ์ฅ ์์ฃผ ์ฐ์ด๋ ps ์ต์
์กฐํฉ์
๋๋ค.",
|
| 463 |
+
"source_id": "manual-linux-basic",
|
| 464 |
+
"difficulty": "easy"
|
| 465 |
+
},
|
| 466 |
+
{
|
| 467 |
+
"id": "linux-q58",
|
| 468 |
+
"lesson_id": "linux-cp-mv-rm",
|
| 469 |
+
"question_type": "multiple_choice",
|
| 470 |
+
"question": "์ด์ ์ค์ธ ์๋ฒ์ `/etc/nginx/nginx.conf`๋ฅผ ์์ ํ๊ธฐ ์ ๊ถํ๊ณผ ํ์์คํฌํ๋ฅผ ๋ณด์กดํด ๊ฐ์ ๋๋ ํฐ๋ฆฌ์ ๋ฐฑ์
ํ๋ ค ํฉ๋๋ค. ์ฌ๋ฐ๋ฅธ ๋ช
๋ น์?",
|
| 471 |
+
"options": [
|
| 472 |
+
"cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak",
|
| 473 |
+
"cp -a /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak",
|
| 474 |
+
"cp -r /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak",
|
| 475 |
+
"mv /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak"
|
| 476 |
+
],
|
| 477 |
+
"answer": "cp -a /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak",
|
| 478 |
+
"explanation": "`cp -a`๋ ๊ถํยท์์ ์ยทํ์์คํฌํ๋ฅผ ๋ชจ๋ ๋ณด์กดํฉ๋๋ค(`-dR --preserve=all`). `-r`์ ๋๋ ํฐ๋ฆฌ ์ฌ๊ท ๋ณต์ฌ์ฉ์ด๋ฉฐ ์์ฑ์ ๋ณด์กดํ์ง ์์ต๋๋ค. `mv`๋ ์๋ณธ์ด ์ฌ๋ผ์ง๋๋ค.",
|
| 479 |
+
"source_id": "manual-linux-basic",
|
| 480 |
+
"difficulty": "medium"
|
| 481 |
+
},
|
| 482 |
+
{
|
| 483 |
+
"id": "linux-q59",
|
| 484 |
+
"lesson_id": "linux-cp-mv-rm",
|
| 485 |
+
"question_type": "multiple_choice",
|
| 486 |
+
"question": "`rm -rf /var/log/old/`๋ฅผ ์คํํ์ ๋ ๋ฐ์ํ๋ ์ผ์?",
|
| 487 |
+
"options": [
|
| 488 |
+
"/var/log/old/ ๋๋ ํฐ๋ฆฌ์ ํ์ ๋ชจ๋ ํ์ผ์ด ์ฆ์ ์ญ์ ๋๋ค",
|
| 489 |
+
"๊ฐ ํ์ผ๋ง๋ค ์ญ์ ํ์ธ์ ์์ฒญํ๋ค",
|
| 490 |
+
"/var/log/old/๊ฐ ํด์งํต์ผ๋ก ์ด๋ํ๋ค",
|
| 491 |
+
"์ฌ๋ณผ๋ฆญ ๋งํฌ๋ง ์ญ์ ํ๊ณ ์ค์ ํ์ผ์ ๋จ๊ธด๋ค"
|
| 492 |
+
],
|
| 493 |
+
"answer": "/var/log/old/ ๋๋ ํฐ๋ฆฌ์ ํ์ ๋ชจ๋ ํ์ผ์ด ์ฆ์ ์ญ์ ๋๋ค",
|
| 494 |
+
"explanation": "`-r`์ ์ฌ๊ท ์ญ์ , `-f`๋ ํ์ธ ์์ด ๊ฐ์ ์ญ์ ์
๋๋ค. ๋ฆฌ๋
์ค์๋ ํด์งํต์ด ์์ด ๋ณต๊ตฌ๊ฐ ๋งค์ฐ ์ด๋ ต์ต๋๋ค. ์ค์ ๊ฒฝ๋ก์์๋ ๋จผ์ `ls`๋ก ๋์์ ํ์ธํ์ธ์.",
|
| 495 |
+
"source_id": "manual-linux-basic",
|
| 496 |
+
"difficulty": "easy"
|
| 497 |
+
},
|
| 498 |
+
{
|
| 499 |
+
"id": "linux-q60",
|
| 500 |
+
"lesson_id": "linux-fdisk-parted",
|
| 501 |
+
"question_type": "multiple_choice",
|
| 502 |
+
"question": "3TB ์ฉ๋์ ์ ๋์คํฌ `/dev/sdc`์ ํํฐ์
์ ๋ง๋ค ๋ fdisk ๋์ parted๋ฅผ ์ฌ์ฉํด์ผ ํ๋ ์ด์ ๋?",
|
| 503 |
+
"options": [
|
| 504 |
+
"fdisk๋ MBR ๋ฐฉ์์ผ๋ก 2TB ์ด๊ณผ ๋์คํฌ๋ฅผ ์ง์ํ์ง ์๊ธฐ ๋๋ฌธ",
|
| 505 |
+
"parted๊ฐ ๋ ๋น ๋ฅด๊ธฐ ๋๋ฌธ",
|
| 506 |
+
"fdisk๋ ext4 ํ์ผ์์คํ
๋ง ์ง์ํ๊ธฐ ๋๋ฌธ",
|
| 507 |
+
"parted๋ง RAID ์ค์ ์ ์ง์ํ๊ธฐ ๋๋ฌธ"
|
| 508 |
+
],
|
| 509 |
+
"answer": "fdisk๋ MBR ๋ฐฉ์์ผ๋ก 2TB ์ด๊ณผ ๋์คํฌ๋ฅผ ์ง์ํ์ง ์๊ธฐ ๋๋ฌธ",
|
| 510 |
+
"explanation": "MBR ํํฐ์
ํ
์ด๋ธ์ ์ต๋ 2TB๋ฅผ ์ง์ํฉ๋๋ค. 3TB ๋์คํฌ๋ GPT๊ฐ ํ์ํ๋ฉฐ `parted`๋ `gdisk`๋ก GPT ํ
์ด๋ธ์ ์์ฑํด์ผ ํฉ๋๋ค.",
|
| 511 |
+
"source_id": "manual-linux-storage",
|
| 512 |
+
"difficulty": "medium"
|
| 513 |
+
},
|
| 514 |
+
{
|
| 515 |
+
"id": "linux-q61",
|
| 516 |
+
"lesson_id": "linux-fdisk-parted",
|
| 517 |
+
"question_type": "multiple_choice",
|
| 518 |
+
"question": "`fdisk /dev/sdb` ์คํ ํ ์ ์ฃผ ํํฐ์
์ ๋ง๋ค๊ณ ์ ์ฅํ๋ ํค ์์๋?",
|
| 519 |
+
"options": [
|
| 520 |
+
"n โ p โ w",
|
| 521 |
+
"p โ n โ w",
|
| 522 |
+
"n โ e โ q",
|
| 523 |
+
"w โ n โ p"
|
| 524 |
+
],
|
| 525 |
+
"answer": "n โ p โ w",
|
| 526 |
+
"explanation": "`n`(new partition) โ `p`(primary) โ ๋ฒํธยท์นํฐ ์
๋ ฅ โ `w`(write & quit). `q`๋ ์ ์ฅ ์์ด ์ข
๋ฃ, `p`๋ ํ์ฌ ํ
์ด๋ธ ์ถ๋ ฅ(Print)์ด๊ธฐ๋ ํฉ๋๋ค.",
|
| 527 |
+
"source_id": "manual-linux-storage",
|
| 528 |
+
"difficulty": "medium"
|
| 529 |
+
},
|
| 530 |
+
{
|
| 531 |
+
"id": "linux-q62",
|
| 532 |
+
"lesson_id": "linux-mkfs-fsck",
|
| 533 |
+
"question_type": "multiple_choice",
|
| 534 |
+
"question": "๋ค์ ์คํ ๋ฆฌ์ง ์ค์ ์์ ์ค ์ฌ๋ฐ๋ฅธ ๊ฒ์?",
|
| 535 |
+
"options": [
|
| 536 |
+
"ํํฐ์
์์ฑ โ ํ์ผ์์คํ
์์ฑ(mkfs) โ ๋ง์ดํธ ํฌ์ธํธ ์์ฑ โ mount",
|
| 537 |
+
"๋ง์ดํธ โ mkfs โ ํํฐ์
์์ฑ โ fstab ๋ฑ๋ก",
|
| 538 |
+
"mkfs โ ํํฐ์
์์ฑ โ mount โ fstab ๋ฑ๋ก",
|
| 539 |
+
"ํํฐ์
์์ฑ โ mount โ mkfs โ fstab ๋ฑ๋ก"
|
| 540 |
+
],
|
| 541 |
+
"answer": "ํํฐ์
์์ฑ โ ํ์ผ์์คํ
์์ฑ(mkfs) โ ๋ง์ดํธ ํฌ์ธํธ ์์ฑ โ mount",
|
| 542 |
+
"explanation": "fdisk๋ก ํํฐ์
์์ฑ โ mkfs๋ก ํฌ๋งท โ mkdir๋ก ๋ง์ดํธ ํฌ์ธํธ ์์ฑ โ mount๋ก ์ฐ๊ฒฐ์ด ์ฌ๋ฐ๋ฅธ ์์์
๋๋ค. ์๊ตฌ ๋ง์ดํธ๋ ๋ง์ง๋ง์ fstab์ ๋ฑ๋กํฉ๋๋ค.",
|
| 543 |
+
"source_id": "manual-linux-storage",
|
| 544 |
+
"difficulty": "medium"
|
| 545 |
+
},
|
| 546 |
+
{
|
| 547 |
+
"id": "linux-q63",
|
| 548 |
+
"lesson_id": "linux-mkfs-fsck",
|
| 549 |
+
"question_type": "multiple_choice",
|
| 550 |
+
"question": "๋ง์ดํธ๋ ํ์ผ์์คํ
์์ `fsck`๋ฅผ ์คํํ๋ฉด ์ด๋ป๊ฒ ๋๋๊ฐ?",
|
| 551 |
+
"options": [
|
| 552 |
+
"๋ฐ์ดํฐ ์์์ด ๋ฐ์ํ ์ ์๋ค",
|
| 553 |
+
"์๋์ผ๋ก ์ธ๋ง์ดํธ ํ ๊ฒ์ฌํ๋ค",
|
| 554 |
+
"์ฝ๊ธฐ ์ ์ฉ์ผ๋ก ์ ํ ํ ๊ฒ์ฌํ๋ค",
|
| 555 |
+
"์ ์์ ์ผ๋ก ์ค๋ฅ๋ฅผ ์์ ํ๋ค"
|
| 556 |
+
],
|
| 557 |
+
"answer": "๋ฐ์ดํฐ ์์์ด ๋ฐ์ํ ์ ์๋ค",
|
| 558 |
+
"explanation": "`fsck`๋ ์ธ๋ง์ดํธ๋ ํ์ผ์์คํ
์์๋ง ์คํํด์ผ ํฉ๋๋ค. ๋ง์ดํธ ์ํ์์ ์คํํ๋ฉด OS์ fsck๊ฐ ๋์์ ํ์ผ์์คํ
์ ์ฐ๊ธฐ๋ฅผ ์๋ํด ๋ฐ์ดํฐ๊ฐ ์์๋ ์ ์์ต๋๋ค.",
|
| 559 |
+
"source_id": "manual-linux-storage",
|
| 560 |
+
"difficulty": "medium"
|
| 561 |
+
},
|
| 562 |
+
{
|
| 563 |
+
"id": "linux-q64",
|
| 564 |
+
"lesson_id": "linux-groupadd",
|
| 565 |
+
"question_type": "multiple_choice",
|
| 566 |
+
"question": "`usermod -G developers alice`๋ฅผ `-a` ์์ด ์คํํ์ ๋ ๋ฐ์ํ๋ ๋ฌธ์ ๋?",
|
| 567 |
+
"options": [
|
| 568 |
+
"alice์ ๊ธฐ์กด ๋ณด์กฐ ๊ทธ๋ฃน์ด ๋ชจ๋ ์ ๊ฑฐ๋๊ณ developers๋ง ๋จ๋๋ค",
|
| 569 |
+
"alice๊ฐ developers ๊ทธ๋ฃน์์ ์ ๊ฑฐ๋๋ค",
|
| 570 |
+
"๋ช
๋ น์ด ์คํจํ๊ณ ์ค๋ฅ๊ฐ ์ถ๋ ฅ๋๋ค",
|
| 571 |
+
"alice์ ๊ธฐ๋ณธ ๊ทธ๋ฃน์ด developers๋ก ๋ณ๊ฒฝ๋๋ค"
|
| 572 |
+
],
|
| 573 |
+
"answer": "alice์ ๊ธฐ์กด ๋ณด์กฐ ๊ทธ๋ฃน์ด ๋ชจ๋ ์ ๊ฑฐ๋๊ณ developers๋ง ๋จ๋๋ค",
|
| 574 |
+
"explanation": "`-G`๋ ๋ณด์กฐ ๊ทธ๋ฃน์ ์ง์ ํ ๋ชฉ๋ก์ผ๋ก ๊ต์ฒดํฉ๋๋ค. ๊ธฐ์กด ๊ทธ๋ฃน์ ์ ์งํ๋ฉด์ ์ถ๊ฐํ๋ ค๋ฉด ๋ฐ๋์ `-aG`(append)๋ฅผ ์ฌ์ฉํด์ผ ํฉ๋๋ค.",
|
| 575 |
+
"source_id": "ubuntu-user-management",
|
| 576 |
+
"difficulty": "medium"
|
| 577 |
+
},
|
| 578 |
+
{
|
| 579 |
+
"id": "linux-q65",
|
| 580 |
+
"lesson_id": "linux-chage",
|
| 581 |
+
"question_type": "multiple_choice",
|
| 582 |
+
"question": "์ ๊ท ์
์ฌ์ bob์ด ์ฒซ ๋ก๊ทธ์ธ ์ ๋ฐ๋์ ๋น๋ฐ๋ฒํธ๋ฅผ ๋ณ๊ฒฝํ๊ฒ ํ๋ ค ํฉ๋๋ค. ์ ์ ํ ๋ช
๏ฟฝ๏ฟฝ์?",
|
| 583 |
+
"options": [
|
| 584 |
+
"chage -d 0 bob",
|
| 585 |
+
"chage -M 0 bob",
|
| 586 |
+
"passwd -l bob",
|
| 587 |
+
"chage -E 0 bob"
|
| 588 |
+
],
|
| 589 |
+
"answer": "chage -d 0 bob",
|
| 590 |
+
"explanation": "`chage -d 0`์ ๋ง์ง๋ง ๋น๋ฐ๋ฒํธ ๋ณ๊ฒฝ์ผ์ ์ํฌํฌ(1970-01-01)๋ก ์ค์ ํด ๋ค์ ๋ก๊ทธ์ธ ์ ์ฆ์ ๋ณ๊ฒฝ์ ๊ฐ์ ํฉ๋๋ค. `-E 0`์ ๊ณ์ ์์ฒด๋ฅผ ๋ง๋ฃ์์ผ ๋ก๊ทธ์ธ์ ์ฐจ๋จํฉ๋๋ค.",
|
| 591 |
+
"source_id": "ubuntu-user-management",
|
| 592 |
+
"difficulty": "medium"
|
| 593 |
+
},
|
| 594 |
+
{
|
| 595 |
+
"id": "linux-q66",
|
| 596 |
+
"lesson_id": "linux-chage",
|
| 597 |
+
"question_type": "multiple_choice",
|
| 598 |
+
"question": "๋ณด์ ์ ์ฑ
์ ๋ชจ๋ ์ฌ์ฉ์๊ฐ 90์ผ๋ง๋ค ๋น๋ฐ๋ฒํธ๋ฅผ ๋ฐ๊ฟ์ผ ํฉ๋๋ค. alice์๊ฒ ์ ์ฉํ๋ ๋ช
๋ น์?",
|
| 599 |
+
"options": [
|
| 600 |
+
"chage -M 90 alice",
|
| 601 |
+
"chage -d 90 alice",
|
| 602 |
+
"passwd -M 90 alice",
|
| 603 |
+
"chage -W 90 alice"
|
| 604 |
+
],
|
| 605 |
+
"answer": "chage -M 90 alice",
|
| 606 |
+
"explanation": "`-M`์ ๋น๋ฐ๋ฒํธ ์ต๋ ์ฌ์ฉ ๊ธฐ๊ฐ(Maximum days)์ ์ค์ ํฉ๋๋ค. `-W`๋ ๋ง๋ฃ ์ ๊ฒฝ๊ณ ์ผ, `-d`๋ ๋ง์ง๋ง ๋ณ๊ฒฝ์ผ, `-E`๋ ๊ณ์ ๋ง๋ฃ์ผ์
๋๋ค.",
|
| 607 |
+
"source_id": "ubuntu-user-management",
|
| 608 |
+
"difficulty": "medium"
|
| 609 |
+
},
|
| 610 |
+
{
|
| 611 |
+
"id": "linux-q67",
|
| 612 |
+
"lesson_id": "linux-systemd-unit",
|
| 613 |
+
"question_type": "multiple_choice",
|
| 614 |
+
"question": "`/etc/systemd/system/myapp.service` ํ์ผ์ ์์ ํ ๋ค ๋ณ๊ฒฝ ์ฌํญ์ ์ ์ฉํ๋ ์ฌ๋ฐ๋ฅธ ์์๋?",
|
| 615 |
+
"options": [
|
| 616 |
+
"systemctl daemon-reload โ systemctl restart myapp",
|
| 617 |
+
"systemctl restart myapp โ systemctl daemon-reload",
|
| 618 |
+
"reboot โ systemctl restart myapp",
|
| 619 |
+
"systemctl reload myapp๋ง ์คํ"
|
| 620 |
+
],
|
| 621 |
+
"answer": "systemctl daemon-reload โ systemctl restart myapp",
|
| 622 |
+
"explanation": "์ ๋ ํ์ผ ์์ ํ systemd๊ฐ ๋ณ๊ฒฝ์ ์ธ์ํ๋ ค๋ฉด `daemon-reload`๊ฐ ๋จผ์ ํ์ํฉ๋๋ค. ๊ทธ ๋ค์ `restart`๋ก ์๋น์ค๋ฅผ ์ฌ์์ํด์ผ ์ ์ค์ ์ด ์ ์ฉ๋ฉ๋๋ค.",
|
| 623 |
+
"source_id": "manual-linux-systemd",
|
| 624 |
+
"difficulty": "medium"
|
| 625 |
+
},
|
| 626 |
+
{
|
| 627 |
+
"id": "linux-q68",
|
| 628 |
+
"lesson_id": "linux-systemd-unit",
|
| 629 |
+
"question_type": "multiple_choice",
|
| 630 |
+
"question": "์๋น์ค ์ ๋ ํ์ผ์์ `WantedBy=multi-user.target`์ ์ญํ ์?",
|
| 631 |
+
"options": [
|
| 632 |
+
"systemctl enable ์ multi-user.target ์คํ ๋จ๊ณ์์ ์๋น์ค๊ฐ ์๋ ์์๋๋๋ก ๋ฑ๋กํ๋ค",
|
| 633 |
+
"์๋น์ค๊ฐ multi-user ์ดํ์๋ง ์ค์ง๋จ์ ์๋ฏธํ๋ค",
|
| 634 |
+
"์๋น์ค๋ฅผ ๊ทธ๋ํฝ ํ๊ฒฝ์์๋ง ์คํํ๊ฒ ํ๋ค",
|
| 635 |
+
"๋ค๋ฅธ ์๋น์ค๋ณด๋ค ๋จผ์ ์์ํ๊ฒ ํ๋ค"
|
| 636 |
+
],
|
| 637 |
+
"answer": "systemctl enable ์ multi-user.target ์คํ ๋จ๊ณ์์ ์๋น์ค๊ฐ ์๋ ์์๋๋๋ก ๋ฑ๋กํ๋ค",
|
| 638 |
+
"explanation": "`WantedBy`๋ `systemctl enable` ์คํ ์ ์ด๋ target์ `.wants/` ๋๋ ํฐ๋ฆฌ์ ์ฌ๋ณผ๋ฆญ ๋งํฌ๋ฅผ ์์ฑํ ์ง ๊ฒฐ์ ํฉ๋๋ค. `multi-user.target`์ ๋คํธ์ํฌ ์๋น์ค๊ฐ ์ค๋น๋ CLI ํ๊ฒฝ(runlevel 3)์
๋๋ค.",
|
| 639 |
+
"source_id": "manual-linux-systemd",
|
| 640 |
+
"difficulty": "easy"
|
| 641 |
+
},
|
| 642 |
+
{
|
| 643 |
+
"id": "linux-q69",
|
| 644 |
+
"lesson_id": "linux-at",
|
| 645 |
+
"question_type": "multiple_choice",
|
| 646 |
+
"question": "๋งค์ผ ๋ฐ๋ณต์ด ์๋ ๋ด์ผ ์๋ฒฝ 3์์ ํ ๋ฒ๋ง ๋ฐฑ์
์คํฌ๋ฆฝํธ๋ฅผ ์คํํ๋ ค ํฉ๋๋ค. ์ ์ ํ ๋๊ตฌ๋?",
|
| 647 |
+
"options": [
|
| 648 |
+
"at",
|
| 649 |
+
"cron",
|
| 650 |
+
"systemd timer",
|
| 651 |
+
"nohup"
|
| 652 |
+
],
|
| 653 |
+
"answer": "at",
|
| 654 |
+
"explanation": "`at`์ ์ผํ์ฑ ์์ฝ ์คํ์ ์ํ ๋๊ตฌ์
๋๋ค. cron์ ๋ฐ๋ณต ์ค์ผ์ค์ ์ ํฉํ๊ณ , nohup์ ํฐ๋ฏธ๋ ์ข
๋ฃ ํ์๋ ํ๋ก์ธ์ค๋ฅผ ์ ์งํ๊ธฐ ์ํ ๋๊ตฌ๋ก ์ค์ผ์ค๋ง ๊ธฐ๋ฅ์ ์์ต๋๋ค.",
|
| 655 |
+
"source_id": "manual-linux-basic",
|
| 656 |
+
"difficulty": "medium"
|
| 657 |
+
},
|
| 658 |
+
{
|
| 659 |
+
"id": "linux-q70",
|
| 660 |
+
"lesson_id": "linux-docker-basics",
|
| 661 |
+
"question_type": "multiple_choice",
|
| 662 |
+
"question": "nginx ์ปจํ
์ด๋๋ฅผ ๋ฐฑ๊ทธ๋ผ์ด๋๋ก ์คํํ๊ณ ํธ์คํธ ํฌํธ 8080์ ์ปจํ
์ด๋ ํฌํธ 80์ ์ฐ๊ฒฐํ๋ ๋ช
๋ น์?",
|
| 663 |
+
"options": [
|
| 664 |
+
"docker run -d -p 8080:80 nginx",
|
| 665 |
+
"docker run -p 80:8080 nginx",
|
| 666 |
+
"docker start -p 8080:80 nginx",
|
| 667 |
+
"docker run --port 8080=80 -b nginx"
|
| 668 |
+
],
|
| 669 |
+
"answer": "docker run -d -p 8080:80 nginx",
|
| 670 |
+
"explanation": "`-d`๋ detach(๋ฐฑ๊ทธ๋ผ์ด๋), `-p ํธ์คํธํฌํธ:์ปจํ
์ด๋ํฌํธ`๋ก ํฌํธ๋ฅผ ๋งคํํฉ๋๋ค. `8080:80`์ ํธ์คํธ์ 8080์ ์ปจํ
์ด๋์ 80์ผ๋ก ํฌ์๋ฉํฉ๋๋ค.",
|
| 671 |
+
"source_id": "manual-linux-docker",
|
| 672 |
+
"difficulty": "medium"
|
| 673 |
+
},
|
| 674 |
+
{
|
| 675 |
+
"id": "linux-q71",
|
| 676 |
+
"lesson_id": "linux-docker-basics",
|
| 677 |
+
"question_type": "multiple_choice",
|
| 678 |
+
"question": "์คํ ์ค์ด๊ฑฐ๋ ์ค์ง๋ ๋ชจ๋ ์ปจํ
์ด๋ ๋ชฉ๋ก์ ๋ณด๋ ๋ช
๋ น์?",
|
| 679 |
+
"options": [
|
| 680 |
+
"docker ps -a",
|
| 681 |
+
"docker ps",
|
| 682 |
+
"docker images",
|
| 683 |
+
"docker container ls"
|
| 684 |
+
],
|
| 685 |
+
"answer": "docker ps -a",
|
| 686 |
+
"explanation": "`docker ps`๋ ์คํ ์ค์ธ ์ปจํ
์ด๋๋ง ํ์ํฉ๋๋ค. `-a`(all) ํ๋๊ทธ๋ฅผ ์ถ๊ฐํ๋ฉด ์ค์ง๋ ์ปจํ
์ด๋๊น์ง ๋ชจ๋ ํ์ํฉ๋๋ค.",
|
| 687 |
+
"source_id": "manual-linux-docker",
|
| 688 |
+
"difficulty": "easy"
|
| 689 |
+
},
|
| 690 |
+
{
|
| 691 |
+
"id": "linux-q72",
|
| 692 |
+
"lesson_id": "linux-grub-boot",
|
| 693 |
+
"question_type": "multiple_choice",
|
| 694 |
+
"question": "`/etc/default/grub`์์ `GRUB_TIMEOUT=10`์ผ๋ก ๋ณ๊ฒฝ ํ ์ ์ฉํ๋ ๋ช
๋ น์? (Ubuntu ๊ธฐ์ค)",
|
| 695 |
+
"options": [
|
| 696 |
+
"update-grub",
|
| 697 |
+
"grub-install",
|
| 698 |
+
"systemctl restart grub",
|
| 699 |
+
"reboot"
|
| 700 |
+
],
|
| 701 |
+
"answer": "update-grub",
|
| 702 |
+
"explanation": "`/etc/default/grub`์ ํ
ํ๋ฆฟ ์ญํ ์ ํ๋ฉฐ, `update-grub`(Ubuntu) ๋๋ `grub2-mkconfig -o /boot/grub2/grub.cfg`(RHEL)๋ฅผ ์คํํด์ผ ์ค์ GRUB ์ค์ ํ์ผ์ ๋ฐ์๋ฉ๋๋ค.",
|
| 703 |
+
"source_id": "manual-linux-boot",
|
| 704 |
+
"difficulty": "medium"
|
| 705 |
+
},
|
| 706 |
+
{
|
| 707 |
+
"id": "linux-q73",
|
| 708 |
+
"lesson_id": "linux-grub-boot",
|
| 709 |
+
"question_type": "multiple_choice",
|
| 710 |
+
"question": "์์คํ
์ด ๊ทธ๋ํฝ ํ๊ฒฝ ์์ด CLI ๋ค์ค ์ฌ์ฉ์ ๋ชจ๋๋ก ๊ธฐ๋ณธ ๋ถํ
๋๊ฒ ํ๋ ๋ช
๋ น์?",
|
| 711 |
+
"options": [
|
| 712 |
+
"systemctl set-default multi-user.target",
|
| 713 |
+
"systemctl set-default graphical.target",
|
| 714 |
+
"update-grub --target=cli",
|
| 715 |
+
"systemctl disable gdm"
|
| 716 |
+
],
|
| 717 |
+
"answer": "systemctl set-default multi-user.target",
|
| 718 |
+
"explanation": "`multi-user.target`์ GUI ์์ด ๋คํธ์ํฌ์ ๋ค์ค ์ฌ์ฉ์ ํ๊ฒฝ์ ์ ๊ณตํ๋ target(runlevel 3 ์๋น)์
๋๋ค. `graphical.target`(runlevel 5)์์ ๋ณ๊ฒฝํ๋ฉด ๋ค์ ์ฌ์์๋ถํฐ CLI๋ก ๋ถํ
๋ฉ๋๋ค.",
|
| 719 |
+
"source_id": "manual-linux-boot",
|
| 720 |
+
"difficulty": "medium"
|
| 721 |
+
},
|
| 722 |
+
{
|
| 723 |
+
"id": "linux-q74",
|
| 724 |
+
"lesson_id": "linux-find",
|
| 725 |
+
"question_type": "multiple_choice",
|
| 726 |
+
"question": "7์ผ ์ด์ ์์ ๋์ง ์์ `/var/log`์ `.log` ํ์ผ์ ์ฐพ์ ์ผ๊ด ์ญ์ ํ๋ ค ํฉ๋๋ค. ์ฌ๋ฐ๋ฅธ ๋ช
๋ น์?",
|
| 727 |
+
"options": [
|
| 728 |
+
"find /var/log -name '*.log' -mtime +7 -delete",
|
| 729 |
+
"find /var/log -name '*.log' -mtime 7 -rm",
|
| 730 |
+
"grep -r '.log' /var/log | xargs rm",
|
| 731 |
+
"ls -lt /var/log/*.log | tail -n +8 | xargs rm"
|
| 732 |
+
],
|
| 733 |
+
"answer": "find /var/log -name '*.log' -mtime +7 -delete",
|
| 734 |
+
"explanation": "`-mtime +7`์ ๋ง์ง๋ง ์์ ํ 7์ผ ์ด๊ณผ๋ ํ์ผ, `-delete`๋ find ๋ด์ฅ ์ญ์ ์ก์
์
๋๋ค. `-mtime 7`(์ ํํ 7์ผ)๊ณผ `-mtime +7`(7์ผ ์ด๊ณผ)์ ์ฐจ์ด์ ์ฃผ์ํ์ธ์.",
|
| 735 |
+
"source_id": "manual-linux-basic",
|
| 736 |
+
"difficulty": "hard"
|
| 737 |
+
},
|
| 738 |
+
{
|
| 739 |
+
"id": "linux-q75",
|
| 740 |
+
"lesson_id": "linux-pipe-redirect",
|
| 741 |
+
"question_type": "multiple_choice",
|
| 742 |
+
"question": "`ls /notexist 2>/dev/null && echo OK`์ ์คํ ๊ฒฐ๊ณผ๋?",
|
| 743 |
+
"options": [
|
| 744 |
+
"์๋ฌด๊ฒ๋ ์ถ๋ ฅ๋์ง ์๋๋ค",
|
| 745 |
+
"OK๊ฐ ์ถ๋ ฅ๋๋ค",
|
| 746 |
+
"์ค๋ฅ ๋ฉ์์ง๊ฐ ์ถ๋ ฅ๋๋ค",
|
| 747 |
+
"OK์ ์ค๋ฅ ๋ฉ์์ง๊ฐ ํจ๊ป ์ถ๋ ฅ๋๋ค"
|
| 748 |
+
],
|
| 749 |
+
"answer": "์๋ฌด๊ฒ๋ ์ถ๋ ฅ๋์ง ์๋๋ค",
|
| 750 |
+
"explanation": "`2>/dev/null`๋ก stderr๋ฅผ ๋ฒ๋ฆฌ๊ณ , `ls /notexist`๊ฐ ์คํจ(exit code != 0)ํ๋ฏ๋ก `&&` ๋ค์ `echo OK`๋ ์คํ๋์ง ์์ต๋๋ค. ๊ฒฐ๊ณผ์ ์ผ๋ก ์๋ฌด๊ฒ๋ ์ถ๋ ฅ๋์ง ์์ต๋๋ค.",
|
| 751 |
+
"source_id": "manual-linux-basic",
|
| 752 |
+
"difficulty": "medium"
|
| 753 |
+
},
|
| 754 |
+
{
|
| 755 |
+
"id": "linux-q76",
|
| 756 |
+
"lesson_id": "linux-systemctl",
|
| 757 |
+
"question_type": "multiple_choice",
|
| 758 |
+
"question": "์๋ฒ ์ฌ์์ ํ์๋ nginx๊ฐ ์๋์ผ๋ก ์์๋๊ฒ ํ๋ ค ํฉ๋๋ค. ํ์ฌ ์คํ ์ค์ด๋ฉฐ enable๋ง ๋น ์ง ์ํ์
๋๋ค. ํ์ํ ๋ช
๋ น์?",
|
| 759 |
+
"options": [
|
| 760 |
+
"systemctl enable nginx",
|
| 761 |
+
"systemctl start nginx",
|
| 762 |
+
"systemctl enable --now nginx",
|
| 763 |
+
"systemctl restart nginx"
|
| 764 |
+
],
|
| 765 |
+
"answer": "systemctl enable nginx",
|
| 766 |
+
"explanation": "์ด๋ฏธ ์คํ ์ค์ด๋ฏ๋ก `start`๋ ๋ถํ์ํฉ๋๋ค. `enable`๋ง ํ๋ฉด ๋ถํ
์ ์๋ ์์ ์ฌ๋ณผ๋ฆญ ๋งํฌ๊ฐ ์์ฑ๋ฉ๋๋ค. `enable --now`๋ enable + start๋ฅผ ๋์์ ์ฒ๋ฆฌํฉ๋๋ค.",
|
| 767 |
+
"source_id": "manual-linux-basic",
|
| 768 |
+
"difficulty": "easy"
|
| 769 |
+
},
|
| 770 |
+
{
|
| 771 |
+
"id": "linux-q77",
|
| 772 |
+
"lesson_id": "linux-acl",
|
| 773 |
+
"question_type": "multiple_choice",
|
| 774 |
+
"question": "`/project` ๋๋ ํฐ๋ฆฌ๋ฅผ `devteam` ๊ทธ๋ฃน ๋ฉค๋ฒ ๋ชจ๋๊ฐ ์ฝ๊ณ ์ธ ์ ์๊ฒ ํ๊ณ , ์๋ก ์์ฑ๋ ํ์ผ๋ ๊ฐ์ ๊ทธ๋ฃน ์์ ๊ฐ ๋๊ฒ ํ๋ ์ค์ ์?",
|
| 775 |
+
"options": [
|
| 776 |
+
"chmod 2775 /project && chgrp devteam /project",
|
| 777 |
+
"chmod 777 /project",
|
| 778 |
+
"setfacl -m g:devteam:rw /project",
|
| 779 |
+
"chown devteam /project && chmod 755 /project"
|
| 780 |
+
],
|
| 781 |
+
"answer": "chmod 2775 /project && chgrp devteam /project",
|
| 782 |
+
"explanation": "`2775`์ ์ ์๋ฆฌ 2๋ SGID(Set Group ID) ๋นํธ์
๋๋ค. SGID๊ฐ ์ค์ ๋ ๋๋ ํฐ๋ฆฌ์์ ์์ฑ๋ ํ์ผ์ ์๋์ผ๋ก ๋๋ ํฐ๋ฆฌ์ ๊ทธ๋ฃน ์์ ๊ฐ ๋ฉ๋๋ค. `775`๋ ์์ ์ยท๊ทธ๋ฃน ์ฝ๊ธฐ/์ฐ๊ธฐ/์คํ, ๊ธฐํ ์ฝ๊ธฐ/์คํ์ ๋ถ์ฌํฉ๋๋ค.",
|
| 783 |
+
"source_id": "manual-linux-basic",
|
| 784 |
+
"difficulty": "hard"
|
| 785 |
+
},
|
| 786 |
+
{
|
| 787 |
+
"id": "linux-q78",
|
| 788 |
+
"lesson_id": "linux-fstab",
|
| 789 |
+
"question_type": "multiple_choice",
|
| 790 |
+
"question": "`/etc/fstab`์ UUID ๊ธฐ๋ฐ์ผ๋ก ํญ๋ชฉ์ ์ถ๊ฐํ ๋ UUID๋ฅผ ํ์ธํ๋ ๋ช
๋ น์?",
|
| 791 |
+
"options": [
|
| 792 |
+
"blkid",
|
| 793 |
+
"lsblk -f",
|
| 794 |
+
"fdisk -l",
|
| 795 |
+
"mount -l"
|
| 796 |
+
],
|
| 797 |
+
"answer": "blkid",
|
| 798 |
+
"explanation": "`blkid`๋ ๋ธ๋ก ๋๋ฐ์ด์ค์ UUID, TYPE(ํ์ผ์์คํ
), LABEL์ ์ถ๋ ฅ๏ฟฝ๏ฟฝ๋๋ค. `lsblk -f`๋ ์ ์ฌํ ์ ๋ณด๋ฅผ ํธ๋ฆฌ ํํ๋ก ๋ณด์ฌ์ค๋๋ค. fstab์๋ ์ฅ์น๋ช
(/dev/sdb1) ๋์ UUID๋ฅผ ์ฐ๋ ๊ฒ์ด ์ฌ๋ถํ
์ ์ฅ์น ์์ ๋ณ๊ฒฝ์ ์์ ํฉ๋๋ค.",
|
| 799 |
+
"source_id": "manual-linux-basic",
|
| 800 |
+
"difficulty": "medium"
|
| 801 |
+
},
|
| 802 |
+
{
|
| 803 |
+
"id": "linux-q79",
|
| 804 |
+
"lesson_id": "linux-lvm",
|
| 805 |
+
"question_type": "multiple_choice",
|
| 806 |
+
"question": "LVM์์ ๋
ผ๋ฆฌ ๋ณผ๋ฅจ์ ํฌ๊ธฐ๋ฅผ 20GB๋ก ๋๋ฆฌ๊ณ ext4 ํ์ผ์์คํ
๋ ํจ๊ป ํ์ฅํ๋ ๋ช
๋ น ์์๋?",
|
| 807 |
+
"options": [
|
| 808 |
+
"lvextend -L 20G /dev/vg0/lv0 โ resize2fs /dev/vg0/lv0",
|
| 809 |
+
"resize2fs /dev/vg0/lv0 โ lvextend -L 20G /dev/vg0/lv0",
|
| 810 |
+
"vgextend vg0 โ resize2fs /dev/vg0/lv0",
|
| 811 |
+
"lvextend -r -L 20G /dev/vg0/lv0 ๋ง์ผ๋ก ์๋ฃ"
|
| 812 |
+
],
|
| 813 |
+
"answer": "lvextend -r -L 20G /dev/vg0/lv0 ๋ง์ผ๋ก ์๋ฃ",
|
| 814 |
+
"explanation": "`lvextend -r`(๋๋ `--resizefs`)์ LV ํ์ฅ๊ณผ ํ์ผ์์คํ
ํ์ฅ์ ํ ๋ฒ์ ์ฒ๋ฆฌํฉ๋๋ค. ๋ณ๋๋ก `resize2fs`๋ฅผ ์คํํด๋ ๋์ง๋ง `-r` ์ต์
ํ๋๋ก ํตํฉ ๊ฐ๋ฅํฉ๋๋ค.",
|
| 815 |
+
"source_id": "manual-linux-basic",
|
| 816 |
+
"difficulty": "hard"
|
| 817 |
+
},
|
| 818 |
+
{
|
| 819 |
+
"id": "linux-q80",
|
| 820 |
+
"lesson_id": "linux-ssh",
|
| 821 |
+
"question_type": "multiple_choice",
|
| 822 |
+
"question": "SSH ์๋ฒ์์ root ๊ณ์ ์ ๋น๋ฐ๋ฒํธ ๋ก๊ทธ์ธ์ ์ฐจ๋จํ๊ณ ํค ๊ธฐ๋ฐ ์ธ์ฆ๋ง ํ์ฉํ๋ ค๋ฉด `sshd_config`์์ ์ค์ ํ ํญ๋ชฉ์?",
|
| 823 |
+
"options": [
|
| 824 |
+
"PermitRootLogin prohibit-password",
|
| 825 |
+
"PermitRootLogin no",
|
| 826 |
+
"PasswordAuthentication no",
|
| 827 |
+
"PermitRootLogin prohibit-password ์ PasswordAuthentication no ๋ชจ๋"
|
| 828 |
+
],
|
| 829 |
+
"answer": "PermitRootLogin prohibit-password ์ PasswordAuthentication no ๋ชจ๋",
|
| 830 |
+
"explanation": "`PermitRootLogin prohibit-password`๋ root์ ๋น๋ฐ๋ฒํธ ์ธ์ฆ๋ง ์ฐจ๋จ(ํค ์ธ์ฆ์ ํ์ฉ). `PasswordAuthentication no`๋ ๋ชจ๋ ์ฌ์ฉ์์ ๋น๋ฐ๋ฒํธ ์ธ์ฆ์ ์ฐจ๋จํฉ๋๋ค. ๋์ ํจ๊ป ์ ์ฉํด์ผ root ๋น๋ฐ๋ฒํธ ๋ก๊ทธ์ธ์ด ์์ ํ ์ฐจ๋จ๋ฉ๋๋ค.",
|
| 831 |
+
"source_id": "manual-linux-basic",
|
| 832 |
+
"difficulty": "medium"
|
| 833 |
+
},
|
| 834 |
+
{
|
| 835 |
+
"id": "linux-cmd-1",
|
| 836 |
+
"lesson_id": "linux-cp-mv-rm",
|
| 837 |
+
"question_type": "command",
|
| 838 |
+
"question": "`/etc/hosts` ํ์ผ์ ๊ถํยท์์ ์ยทํ์์คํฌํ๋ฅผ ๋ณด์กดํ๋ฉฐ `/tmp/hosts.bak`์ผ๋ก ๋ณต์ฌํ๋ ๋ช
๋ น์ ์
๋ ฅํ์ธ์.",
|
| 839 |
+
"options": [],
|
| 840 |
+
"answer": "cp -a /etc/hosts /tmp/hosts.bak",
|
| 841 |
+
"explanation": "`cp -a`๋ `-dR --preserve=all`์ ๋จ์ถ์ผ๋ก ์์ฑ์ ์์ ํ ๋ณด์กดํฉ๋๋ค. ๋จ์ `cp`๋ ํ์์คํฌํ์ ๊ถํ์ ๋ณด์กดํ์ง ์์ต๋๋ค.",
|
| 842 |
+
"source_id": "manual-linux-basic",
|
| 843 |
+
"difficulty": "medium"
|
| 844 |
+
},
|
| 845 |
+
{
|
| 846 |
+
"id": "linux-cmd-2",
|
| 847 |
+
"lesson_id": "linux-grep",
|
| 848 |
+
"question_type": "command",
|
| 849 |
+
"question": "`/etc/ssh/sshd_config` ํ์ผ์์ ์ฃผ์(#์ผ๋ก ์์ํ๋ ์ค)์ ์ ์ธํ๊ณ ๋ด์ฉ์ ์ถ๋ ฅํ๋ ๋ช
๋ น์ ์
๋ ฅํ์ธ์.",
|
| 850 |
+
"options": [],
|
| 851 |
+
"answer": "grep -v '^#' /etc/ssh/sshd_config",
|
| 852 |
+
"explanation": "`-v`๋ ํจํด๊ณผ ์ผ์นํ์ง ์๋ ์ค์ ์ถ๋ ฅ(๋ฐ์ ), `^#`์ ์ค์ ์์์ด #์ธ ์ค์ ์๋ฏธํฉ๋๋ค.",
|
| 853 |
+
"source_id": "manual-linux-basic",
|
| 854 |
+
"difficulty": "medium"
|
| 855 |
+
},
|
| 856 |
+
{
|
| 857 |
+
"id": "linux-cmd-3",
|
| 858 |
+
"lesson_id": "linux-find",
|
| 859 |
+
"question_type": "command",
|
| 860 |
+
"question": "์์คํ
์ ์ฒด์์ SUID ๋นํธ๊ฐ ์ค์ ๋ ํ์ผ์ ์ฐพ๋ ๋ช
๋ น์ ์
๋ ฅํ์ธ์.",
|
| 861 |
+
"options": [],
|
| 862 |
+
"answer": "find / -perm -4000 -type f",
|
| 863 |
+
"explanation": "`-perm -4000`์ SUID ๋นํธ(4000)๊ฐ ์ค์ ๋ ํ์ผ์ ์ฐพ์ต๋๋ค. `-`๋ฅผ ์์ ๋ถ์ด๋ฉด ํด๋น ๋นํธ๊ฐ ํฌํจ๋ ํ์ผ ๋ชจ๋๋ฅผ ์ฐพ์ต๋๋ค.",
|
| 864 |
+
"source_id": "manual-linux-basic",
|
| 865 |
+
"difficulty": "hard"
|
| 866 |
+
},
|
| 867 |
+
{
|
| 868 |
+
"id": "linux-cmd-4",
|
| 869 |
+
"lesson_id": "linux-tar",
|
| 870 |
+
"question_type": "command",
|
| 871 |
+
"question": "`/var/log` ๋๋ ํฐ๋ฆฌ๋ฅผ gzip ์์ถํด `/tmp/log_backup.tar.gz`๋ก ๋ง๋๋ ๋ช
๋ น์ ์
๋ ฅํ์ธ์.",
|
| 872 |
+
"options": [],
|
| 873 |
+
"answer": "tar -czf /tmp/log_backup.tar.gz /var/log",
|
| 874 |
+
"explanation": "`-c`(create), `-z`(gzip ์์ถ), `-f`(ํ์ผ ์ด๋ฆ ์ง์ ). ์์ฑํ ์์นด์ด๋ธ ์ด๋ฆ โ ์๋ณธ ๊ฒฝ๋ก ์์๋ก ์ธ์๋ฅผ ์๋๋ค.",
|
| 875 |
+
"source_id": "manual-linux-basic",
|
| 876 |
+
"difficulty": "medium"
|
| 877 |
+
},
|
| 878 |
+
{
|
| 879 |
+
"id": "linux-cmd-5",
|
| 880 |
+
"lesson_id": "linux-tar",
|
| 881 |
+
"question_type": "command",
|
| 882 |
+
"question": "`/tmp/log_backup.tar.gz`์ ๋ด์ฉ์ ํ์ฌ ๋๋ ํฐ๋ฆฌ์ ์์ถ ํด์ ํ๋ ๋ช
๋ น์ ์
๋ ฅํ์ธ์.",
|
| 883 |
+
"options": [],
|
| 884 |
+
"answer": "tar -xzf /tmp/log_backup.tar.gz",
|
| 885 |
+
"explanation": "`-x`(extract), `-z`(gzip), `-f`(ํ์ผ ์ด๋ฆ). `-C /๊ฒฝ๋ก`๋ฅผ ์ถ๊ฐํ๋ฉด ํน์ ๋๋ ํฐ๋ฆฌ์ ์์ถ ํด์ ํ ์ ์์ต๋๋ค.",
|
| 886 |
+
"source_id": "manual-linux-basic",
|
| 887 |
+
"difficulty": "easy"
|
| 888 |
+
},
|
| 889 |
+
{
|
| 890 |
+
"id": "linux-cmd-6",
|
| 891 |
+
"lesson_id": "linux-chmod",
|
| 892 |
+
"question_type": "command",
|
| 893 |
+
"question": "`/srv/app` ๋๋ ํฐ๋ฆฌ์ ๊ทธ ํ์ ๋ชจ๋ ํ์ผ์ ์์ ์๋ rwx, ๊ทธ๋ฃน์ rx, ๊ธฐํ๋ ์๋ฌด ๊ถํ๋ ์๊ฒ ์ฌ๊ท์ ์ผ๋ก ์ค์ ํ๋ ๋ช
๋ น์ ์
๋ ฅํ์ธ์.",
|
| 894 |
+
"options": [],
|
| 895 |
+
"answer": "chmod -R 750 /srv/app",
|
| 896 |
+
"explanation": "`750` = ์์ ์(7=rwx), ๊ทธ๋ฃน(5=r-x), ๊ธฐํ(0=---). `-R`์ ์ฌ๊ท ์ ์ฉ์
๋๋ค.",
|
| 897 |
+
"source_id": "manual-linux-basic",
|
| 898 |
+
"difficulty": "medium"
|
| 899 |
+
},
|
| 900 |
+
{
|
| 901 |
+
"id": "linux-cmd-7",
|
| 902 |
+
"lesson_id": "linux-acl",
|
| 903 |
+
"question_type": "command",
|
| 904 |
+
"question": "`/project` ๋๋ ํฐ๋ฆฌ์ `devteam` ๊ทธ๋ฃน์ด ์ฝ๊ธฐยท์ฐ๊ธฐยท์คํ ๊ถํ์ ๊ฐ๋๋ก ACL์ ์ค์ ํ๋ ๋ช
๋ น์ ์
๋ ฅํ์ธ์.",
|
| 905 |
+
"options": [],
|
| 906 |
+
"answer": "setfacl -m g:devteam:rwx /project",
|
| 907 |
+
"explanation": "`setfacl -m`(modify) `g:๊ทธ๋ฃน๋ช
:๊ถํ` ํ์์ผ๋ก ๊ทธ๋ฃน ACL์ ์ค์ ํฉ๋๋ค. ๊ธฐ์กด ๊ถํ์ ์ ์ง๋ฉ๋๋ค.",
|
| 908 |
+
"source_id": "manual-linux-basic",
|
| 909 |
+
"difficulty": "hard"
|
| 910 |
+
},
|
| 911 |
+
{
|
| 912 |
+
"id": "linux-cmd-8",
|
| 913 |
+
"lesson_id": "linux-useradd",
|
| 914 |
+
"question_type": "command",
|
| 915 |
+
"question": "ํ ๋๋ ํฐ๋ฆฌ๋ฅผ ์๋ ์์ฑํ๋ฉด์ `alice`๋ผ๋ ์ฌ์ฉ์๋ฅผ ๋ง๋ค๊ณ ๊ธฐ๋ณธ ์
ธ์ `/bin/bash`๋ก ์ค์ ํ๋ ๋ช
๋ น์ ์
๋ ฅํ์ธ์.",
|
| 916 |
+
"options": [],
|
| 917 |
+
"answer": "useradd -m -s /bin/bash alice",
|
| 918 |
+
"explanation": "`-m`์ ํ ๋๋ ํฐ๋ฆฌ ์์ฑ, `-s`๋ ๊ธฐ๋ณธ ์
ธ ์ง์ ์
๋๋ค. ์ด ์ต์
์์ด useradd๋ง ์คํํ๋ฉด ํ ๋๋ ํฐ๋ฆฌ๊ฐ ์์ฑ๋์ง ์์ต๋๋ค.",
|
| 919 |
+
"source_id": "ubuntu-user-management",
|
| 920 |
+
"difficulty": "medium"
|
| 921 |
+
},
|
| 922 |
+
{
|
| 923 |
+
"id": "linux-cmd-9",
|
| 924 |
+
"lesson_id": "linux-chage",
|
| 925 |
+
"question_type": "command",
|
| 926 |
+
"question": "`bob` ์ฌ์ฉ์์ ๋น๋ฐ๋ฒํธ ๋ง๋ฃ ์ ์ฑ
(์ต๋ ์ฌ์ฉ์ผ, ๊ฒฝ๊ณ ์ผ ๋ฑ)์ ํ์ธํ๋ ๋ช
๋ น์ ์
๋ ฅํ์ธ์.",
|
| 927 |
+
"options": [],
|
| 928 |
+
"answer": "chage -l bob",
|
| 929 |
+
"explanation": "`chage -l`(list)์ ์ฌ์ฉ์์ ๋น๋ฐ๋ฒํธ ์ ์ฑ
(๋ง์ง๋ง ๋ณ๊ฒฝ์ผ, ์ต๋ ์ฌ์ฉ์ผ, ๊ฒฝ๊ณ ์ผ, ๊ณ์ ๋ง๋ฃ์ผ)์ ๋ณด๊ธฐ ์ข๊ฒ ์ถ๋ ฅํฉ๋๋ค.",
|
| 930 |
+
"source_id": "ubuntu-user-management",
|
| 931 |
+
"difficulty": "medium"
|
| 932 |
+
},
|
| 933 |
+
{
|
| 934 |
+
"id": "linux-cmd-10",
|
| 935 |
+
"lesson_id": "linux-systemctl",
|
| 936 |
+
"question_type": "command",
|
| 937 |
+
"question": "`nginx` ์๋น์ค๊ฐ ํ์ฌ ์คํ ์ค์ธ์ง ํ์ธํ๋ ๋ช
๋ น์ ์
๋ ฅํ์ธ์.",
|
| 938 |
+
"options": [],
|
| 939 |
+
"answer": "systemctl status nginx",
|
| 940 |
+
"explanation": "`systemctl status`๋ ์๋น์ค ์ํ, ์ต๊ทผ ๋ก๊ทธ, PID, ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋์ ํ๋์ ๋ณด์ฌ์ค๋๋ค. `is-active nginx`๋ active/inactive๋ง ์ถ๋ ฅํฉ๋๋ค.",
|
| 941 |
+
"source_id": "manual-linux-basic",
|
| 942 |
+
"difficulty": "easy"
|
| 943 |
+
},
|
| 944 |
+
{
|
| 945 |
+
"id": "linux-cmd-11",
|
| 946 |
+
"lesson_id": "linux-systemd-unit",
|
| 947 |
+
"question_type": "command",
|
| 948 |
+
"question": "์ ๋ ํ์ผ ์์ ํ systemd๊ฐ ๋ณ๊ฒฝ ์ฌํญ์ ์ธ์ํ๋๋ก ์๋ก๊ณ ์นจํ๋ ๋ช
๋ น์ ์
๋ ฅํ์ธ์.",
|
| 949 |
+
"options": [],
|
| 950 |
+
"answer": "systemctl daemon-reload",
|
| 951 |
+
"explanation": "์ ๋ ํ์ผ(`/etc/systemd/system/*.service`)์ ์์ ํ๋ฉด systemd๊ฐ ์๋์ผ๋ก ๊ฐ์งํ์ง ์์ต๋๋ค. `daemon-reload` ํ `restart`ํด์ผ ๋ณ๊ฒฝ์ด ์ ์ฉ๋ฉ๋๋ค.",
|
| 952 |
+
"source_id": "manual-linux-systemd",
|
| 953 |
+
"difficulty": "medium"
|
| 954 |
+
},
|
| 955 |
+
{
|
| 956 |
+
"id": "linux-cmd-12",
|
| 957 |
+
"lesson_id": "linux-journalctl",
|
| 958 |
+
"question_type": "command",
|
| 959 |
+
"question": "`nginx` ์๋น์ค์ ๋ก๊ทธ๋ฅผ ์ต๊ทผ 50์ค๋ง ์ถ๋ ฅํ๋ ๋ช
๋ น์ ์
๋ ฅํ์ธ์.",
|
| 960 |
+
"options": [],
|
| 961 |
+
"answer": "journalctl -u nginx -n 50",
|
| 962 |
+
"explanation": "`-u`๋ ํน์ ์ ๋(์๋น์ค) ํํฐ, `-n 50`์ ์ต๊ทผ 50์ค ์ถ๋ ฅ์
๋๋ค. `-f`๋ฅผ ์ถ๊ฐํ๋ฉด ์ค์๊ฐ ์คํธ๋ฆฌ๋ฐ๋ฉ๋๋ค.",
|
| 963 |
+
"source_id": "manual-linux-basic",
|
| 964 |
+
"difficulty": "medium"
|
| 965 |
+
},
|
| 966 |
+
{
|
| 967 |
+
"id": "linux-cmd-13",
|
| 968 |
+
"lesson_id": "linux-cron",
|
| 969 |
+
"question_type": "command",
|
| 970 |
+
"question": "ํ์ฌ ์ฌ์ฉ์์ crontab์ ํธ์งํ๋ ๋ช
๋ น์ ์
๋ ฅํ์ธ์.",
|
| 971 |
+
"options": [],
|
| 972 |
+
"answer": "crontab -e",
|
| 973 |
+
"explanation": "`crontab -e`๋ ๊ธฐ๋ณธ ํธ์ง๊ธฐ๋ก ํ์ฌ ์ฌ์ฉ์์ crontab์ ์ฝ๋๋ค. `-l`์ ๋ชฉ๋ก ํ์ธ, `-r`์ ์ญ์ ์
๋๋ค.",
|
| 974 |
+
"source_id": "manual-linux-basic",
|
| 975 |
+
"difficulty": "easy"
|
| 976 |
+
},
|
| 977 |
+
{
|
| 978 |
+
"id": "linux-cmd-14",
|
| 979 |
+
"lesson_id": "linux-df-du-mount",
|
| 980 |
+
"question_type": "command",
|
| 981 |
+
"question": "ํ์ฌ ๋ง์ดํธ๋ ํ์ผ์์คํ
์ ๋์คํฌ ์ฌ์ฉ๋์ ์ฌ๋์ด ์ฝ๊ธฐ ์ฌ์ด ๋จ์(GB, MB)๋ก ์ถ๋ ฅํ๋ ๋ช
๋ น์ ์
๋ ฅํ์ธ์.",
|
| 982 |
+
"options": [],
|
| 983 |
+
"answer": "df -h",
|
| 984 |
+
"explanation": "`df -h`๋ `-h`(human-readable) ์ต์
์ผ๋ก GB, MB ๋จ์๋ก ์ฉ๋์ ํ์ํฉ๋๋ค. `-T`๋ฅผ ์ถ๊ฐํ๋ฉด ํ์ผ์์คํ
์ ํ๋ ํจ๊ป ์ถ๋ ฅ๋ฉ๋๋ค.",
|
| 985 |
+
"source_id": "manual-linux-basic",
|
| 986 |
+
"difficulty": "easy"
|
| 987 |
+
},
|
| 988 |
+
{
|
| 989 |
+
"id": "linux-cmd-15",
|
| 990 |
+
"lesson_id": "linux-lvm",
|
| 991 |
+
"question_type": "command",
|
| 992 |
+
"question": "์์คํ
์ ๋ชจ๋ ๋
ผ๋ฆฌ ๋ณผ๋ฅจ(LV) ๋ชฉ๋ก์ ํ์ธํ๋ ๋ช
๋ น์ ์
๋ ฅํ์ธ์.",
|
| 993 |
+
"options": [],
|
| 994 |
+
"answer": "lvs",
|
| 995 |
+
"explanation": "`lvs`(LV summary)๋ ๊ฐ๊ฒฐํ LV ๋ชฉ๋ก์ ์ถ๋ ฅํฉ๋๋ค. `lvdisplay`๋ ๋ ์์ธํ ์ ๋ณด๋ฅผ, `lvscan`์ ๋ชจ๋ LV์ ํ์ฑ ์ํ๋ฅผ ๋ณด์ฌ์ค๋๋ค.",
|
| 996 |
+
"source_id": "manual-linux-basic",
|
| 997 |
+
"difficulty": "medium"
|
| 998 |
+
},
|
| 999 |
+
{
|
| 1000 |
+
"id": "linux-cmd-16",
|
| 1001 |
+
"lesson_id": "linux-fstab",
|
| 1002 |
+
"question_type": "command",
|
| 1003 |
+
"question": "`/etc/fstab`์ ๋ฑ๋ก๋ ๋ชจ๋ ํ์ผ์์คํ
์ ๋ง์ดํธํ๋ ๋ช
๋ น์ ์
๋ ฅํ์ธ์.",
|
| 1004 |
+
"options": [],
|
| 1005 |
+
"answer": "mount -a",
|
| 1006 |
+
"explanation": "`mount -a`๋ fstab์ noauto ์ต์
์ด ์๋ ๋ชจ๋ ํญ๋ชฉ์ ๋ง์ดํธํฉ๋๋ค. fstab ์์ ํ ์ฌ๋ถํ
์์ด ํ
์คํธํ ๋ ์ฌ์ฉํฉ๋๋ค.",
|
| 1007 |
+
"source_id": "manual-linux-basic",
|
| 1008 |
+
"difficulty": "medium"
|
| 1009 |
+
},
|
| 1010 |
+
{
|
| 1011 |
+
"id": "linux-cmd-17",
|
| 1012 |
+
"lesson_id": "linux-ssh-key",
|
| 1013 |
+
"question_type": "command",
|
| 1014 |
+
"question": "ED25519 ์๊ณ ๋ฆฌ์ฆ์ผ๋ก SSH ํค ์์ ์์ฑํ๋ ๋ช
๋ น์ ์
๋ ฅํ์ธ์.",
|
| 1015 |
+
"options": [],
|
| 1016 |
+
"answer": "ssh-keygen -t ed25519",
|
| 1017 |
+
"explanation": "ED25519๋ RSA 4096๋ณด๋ค ์งง๊ณ ๊ฐ๋ ฅํ ์๊ณ ๋ฆฌ์ฆ์
๋๋ค. ์์ฑ๋ ๊ณต๊ฐ ํค(`~/.ssh/id_ed25519.pub`)๋ฅผ ์๋ฒ์ `authorized_keys`์ ๋ฑ๋กํฉ๋๋ค.",
|
| 1018 |
+
"source_id": "manual-linux-basic",
|
| 1019 |
+
"difficulty": "medium"
|
| 1020 |
+
},
|
| 1021 |
+
{
|
| 1022 |
+
"id": "linux-cmd-18",
|
| 1023 |
+
"lesson_id": "linux-sed",
|
| 1024 |
+
"question_type": "command",
|
| 1025 |
+
"question": "`/etc/hosts` ํ์ผ์์ `oldhost`๋ฅผ `newhost`๋ก ๋ชจ๋ ๋ฐ๊ฟ ํ์ผ์ ์ง์ ์์ ํ๋ ๋ช
๋ น์ ์
๋ ฅํ์ธ์.",
|
| 1026 |
+
"options": [],
|
| 1027 |
+
"answer": "sed -i 's/oldhost/newhost/g' /etc/hosts",
|
| 1028 |
+
"explanation": "`-i`๋ ํ์ผ์ ์ง์ ์์ (in-place), `s/ํจํด/๊ต์ฒด/g`์์ `g`๋ ์ค ๋ด ๋ชจ๋ ์ผ์น ํญ๋ชฉ์ ๊ต์ฒดํฉ๋๋ค. `-i.bak`์ผ๋ก ๋ฐฑ์
๋ ๋ง๋ค ์ ์์ต๋๋ค.",
|
| 1029 |
+
"source_id": "manual-linux-basic",
|
| 1030 |
+
"difficulty": "hard"
|
| 1031 |
+
},
|
| 1032 |
+
{
|
| 1033 |
+
"id": "linux-cmd-19",
|
| 1034 |
+
"lesson_id": "linux-text-pipeline",
|
| 1035 |
+
"question_type": "command",
|
| 1036 |
+
"question": "`/var/log/auth.log`์์ `Failed` ๋ฌธ์์ด์ด ํฌํจ๋ ์ค๋ง ๋ฝ์ IP ์ฃผ์ ํ๋(์ฒซ ๋ฒ์งธ ๊ณต๋ฐฑ ๊ธฐ์ค ํ๋ 11)๋ณ ์๋ ํ์๋ฅผ ๋ด๋ฆผ์ฐจ์์ผ๋ก ์ถ๋ ฅํ๋ ํ์ดํ๋ผ์ธ์ ์
๋ ฅํ์ธ์.",
|
| 1037 |
+
"options": [],
|
| 1038 |
+
"answer": "grep 'Failed' /var/log/auth.log | awk '{print $11}' | sort | uniq -c | sort -rn",
|
| 1039 |
+
"explanation": "grepโawk๋ก ํ๋ ์ถ์ถโsort๋ก ์ ๋ ฌโuniq -c๋ก ์ค๋ณต ์นด์ดํธโsort -rn์ผ๋ก ๋ด๋ฆผ์ฐจ์. ๋ธ๋ฃจํธํฌ์ค ๊ณต๊ฒฉ IP๋ฅผ ํ์
ํ๋ ์ค์ ํจํด์
๋๋ค.",
|
| 1040 |
+
"source_id": "manual-linux-basic",
|
| 1041 |
+
"difficulty": "hard"
|
| 1042 |
+
},
|
| 1043 |
+
{
|
| 1044 |
+
"id": "linux-cmd-20",
|
| 1045 |
+
"lesson_id": "linux-docker-basics",
|
| 1046 |
+
"question_type": "command",
|
| 1047 |
+
"question": "์คํ ์ค์ธ `webserver` ์ปจํ
์ด๋ ๋ด๋ถ์์ `/bin/bash` ์
ธ์ ์ธํฐ๋ํฐ๋ธ ํฐ๋ฏธ๋๋ก ์คํํ๋ ๋ช
๋ น์ ์
๋ ฅํ์ธ์.",
|
| 1048 |
+
"options": [],
|
| 1049 |
+
"answer": "docker exec -it webserver /bin/bash",
|
| 1050 |
+
"explanation": "`docker exec -it`๋ ์คํ ์ค์ธ ์ปจํ
์ด๋ ๋ด๋ถ์์ ๋ช
๋ น์ ์คํํฉ๋๋ค. `-i`(stdin ์ ์ง), `-t`(ํฐ๋ฏธ๋ ํ ๋น). ์ปจํ
์ด๋ ์์์ ๋๋ฒ๊น
ํ ๋ ํ์ ํจํด์
๋๋ค.",
|
| 1051 |
+
"source_id": "manual-linux-docker",
|
| 1052 |
+
"difficulty": "medium"
|
| 1053 |
+
},
|
| 1054 |
+
{
|
| 1055 |
+
"id": "linux-cmd-21",
|
| 1056 |
+
"lesson_id": "linux-mkfs-fsck",
|
| 1057 |
+
"question_type": "command",
|
| 1058 |
+
"question": "`/dev/sdb1` ํํฐ์
์ UUID๋ฅผ ํ์ธํ๋ ๋ช
๋ น์ ์
๋ ฅํ์ธ์.",
|
| 1059 |
+
"options": [],
|
| 1060 |
+
"answer": "blkid /dev/sdb1",
|
| 1061 |
+
"explanation": "`blkid`๋ ๋ธ๋ก ๋๋ฐ์ด์ค์ UUID, ํ์ผ์์คํ
์ ํ(TYPE), ๋ ์ด๋ธ์ ์ถ๋ ฅํฉ๋๋ค. fstab์ UUID ๊ธฐ๋ฐ์ผ๋ก ๋ฑ๋กํ ๋ ์ด ๋ช
๋ น์ผ๋ก ๊ฐ์ ํ์ธํฉ๋๋ค.",
|
| 1062 |
+
"source_id": "manual-linux-storage",
|
| 1063 |
+
"difficulty": "medium"
|
| 1064 |
+
},
|
| 1065 |
+
{
|
| 1066 |
+
"id": "linux-cmd-22",
|
| 1067 |
+
"lesson_id": "linux-at",
|
| 1068 |
+
"question_type": "command",
|
| 1069 |
+
"question": "1์๊ฐ ํ์ `/usr/local/bin/cleanup.sh`๋ฅผ ํ ๋ฒ ์คํํ๋๋ก ์์ฝํ๋ ๋ช
๋ น์ ์
๋ ฅํ์ธ์.",
|
| 1070 |
+
"options": [],
|
| 1071 |
+
"answer": "echo '/usr/local/bin/cleanup.sh' | at now + 1 hour",
|
| 1072 |
+
"explanation": "`echo '๋ช
๋ น' | at ์๊ฐ` ํ์์ผ๋ก ์ผํ์ฑ ์์
์ ์์ฝํฉ๋๋ค. ์์ฝ ๋ชฉ๋ก์ `atq`, ์ทจ์๋ `atrm ๋ฒํธ`๋ก ๊ด๋ฆฌํฉ๋๋ค.",
|
| 1073 |
+
"source_id": "manual-linux-basic",
|
| 1074 |
+
"difficulty": "hard"
|
| 1075 |
+
}
|
| 1076 |
+
]
|
cert_study_app/content/loader.py
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""JSON-based content loader for lessons, quizzes, and practice tasks.
|
| 2 |
+
|
| 3 |
+
New content lives in cert_study_app/content/{track}/{type}.json.
|
| 4 |
+
Returns raw dicts โ callers convert to dataclass types.
|
| 5 |
+
"""
|
| 6 |
+
from __future__ import annotations
|
| 7 |
+
|
| 8 |
+
import json
|
| 9 |
+
from pathlib import Path
|
| 10 |
+
|
| 11 |
+
CONTENT_DIR = Path(__file__).parent
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
def _load(track_id: str, filename: str) -> list[dict]:
|
| 15 |
+
path = CONTENT_DIR / track_id / filename
|
| 16 |
+
if not path.exists():
|
| 17 |
+
return []
|
| 18 |
+
try:
|
| 19 |
+
data = json.loads(path.read_text(encoding="utf-8"))
|
| 20 |
+
return data if isinstance(data, list) else []
|
| 21 |
+
except Exception:
|
| 22 |
+
return []
|
| 23 |
+
|
| 24 |
+
|
| 25 |
+
def load_lesson_dicts(track_id: str) -> list[dict]:
|
| 26 |
+
return _load(track_id, "lessons.json")
|
| 27 |
+
|
| 28 |
+
|
| 29 |
+
def load_quiz_dicts(track_id: str) -> list[dict]:
|
| 30 |
+
return _load(track_id, "quizzes.json")
|
| 31 |
+
|
| 32 |
+
|
| 33 |
+
def load_practice_dicts(track_id: str) -> list[dict]:
|
| 34 |
+
return _load(track_id, "practices.json")
|
cert_study_app/content/tool_docs/lessons.json
ADDED
|
@@ -0,0 +1,529 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[
|
| 2 |
+
{
|
| 3 |
+
"id": "docs-ollama-models",
|
| 4 |
+
"certification": "Docs Study",
|
| 5 |
+
"title": "Ollama ๋ชจ๋ธ ์คํ ํ๋ฆ",
|
| 6 |
+
"level": "์
๋ฌธ",
|
| 7 |
+
"related_practices": ["docs-lab-1", "docs-lab-2"],
|
| 8 |
+
"summary": "Ollama๋ ๋ก์ปฌ์์ LLM ๋ชจ๋ธ์ ๋ด๋ ค๋ฐ๊ณ ์คํํด CLI ๋๋ REST API๋ก ์ฌ์ฉํ ์ ์๊ฒ ํด์ฃผ๋ ๊ฒฝ๋ ๋ชจ๋ธ ์๋ฒ์
๋๋ค. `ollama run`์ผ๋ก ๋ํํ๊ณ , `ollama serve`๋ก API ์๋ฒ๋ฅผ ์ ์งํฉ๋๋ค.",
|
| 9 |
+
"example": "# ๋ชจ๋ธ ๋ค์ด๋ก๋ ๋ฐ ์คํ\nollama pull qwen2.5:14b\nollama run qwen2.5:14b\n# ์ค์น๋ ๋ชจ๋ธ ๋ชฉ๋ก\nollama list",
|
| 10 |
+
"common_mistake": "๋ชจ๋ธ ์ด๋ฆ์ ํ๊ทธ(:14b, :latest ๋ฑ)๋ฅผ ์๋ตํ๋ฉด `:latest`๋ก ์๋ ์ค์ ๋ฉ๋๋ค. ๋ชจ๋ธ์ด ๋ก์ปฌ์ ์์ ๋ `ollama run`์ด ์๋์ผ๋ก pullํฉ๋๋ค.",
|
| 11 |
+
"keywords": ["ollama", "pull", "run", "serve", "model tag", "GGUF", "local LLM"],
|
| 12 |
+
"source_id": "official-docs-ollama",
|
| 13 |
+
"details": [
|
| 14 |
+
"**`ollama run`**: ๋ชจ๋ธ์ด ์์ผ๋ฉด ์๋ ๋ค์ด๋ก๋ ํ ๋ํํ ์ธ์
์์. `--nowordwrap` ์ต์
์ผ๋ก ๊ธด ์ถ๋ ฅ ์ฒ๋ฆฌ ๊ฐ๋ฅ.",
|
| 15 |
+
"**`ollama serve`**: 11434 ํฌํธ์์ OpenAI ํธํ REST API ์ ๊ณต. `OLLAMA_HOST=0.0.0.0`์ผ๋ก ์ธ๋ถ ์ ๊ทผ ํ์ฉ ๊ฐ๋ฅ.",
|
| 16 |
+
"๋ชจ๋ธ ํ์ผ์ `~/.ollama/models`์ GGUF ํ์์ผ๋ก ์ ์ฅ๋ฉ๋๋ค. `Modelfile`๋ก ์ปค์คํ
์์คํ
ํ๋กฌํํธ์ ํ๋ผ๋ฏธํฐ๋ฅผ ์ค์ ํ ์ ์์ต๋๋ค."
|
| 17 |
+
]
|
| 18 |
+
},
|
| 19 |
+
{
|
| 20 |
+
"id": "docs-ollama-api",
|
| 21 |
+
"certification": "Docs Study",
|
| 22 |
+
"title": "Ollama REST API ํธ์ถ",
|
| 23 |
+
"level": "์
๋ฌธ",
|
| 24 |
+
"related_practices": ["docs-lab-3"],
|
| 25 |
+
"summary": "Ollama๋ `localhost:11434`์์ REST API๋ฅผ ์ ๊ณตํฉ๋๋ค. `/api/generate`(์์ฑํ), `/api/chat`(๋ํํ), `/api/embeddings`(์๋ฒ ๋ฉ) ์๋ํฌ์ธํธ๋ฅผ OpenAI ํธํ ํ์์ผ๋ก๋ ์ง์ํฉ๋๋ค.",
|
| 26 |
+
"example": "# chat ์๋ํฌ์ธํธ\ncurl http://localhost:11434/api/chat -d '{\n \"model\": \"qwen2.5:7b\",\n \"messages\": [{\"role\": \"user\", \"content\": \"์๋
\"}],\n \"stream\": false\n}'",
|
| 27 |
+
"common_mistake": "Ollama ์๋ฒ(`ollama serve`)๊ฐ ์คํ ์ค์ด์ง ์๊ฑฐ๋ ๋ชจ๋ธ์ด ๋ก์ปฌ์ ์์ผ๋ฉด API ํธ์ถ์ด ์คํจํฉ๋๋ค. ๋จผ์ `ollama list`๋ก ๋ชจ๋ธ ์กด์ฌ๋ฅผ ํ์ธํ์ธ์.",
|
| 28 |
+
"keywords": ["ollama", "REST API", "generate", "chat", "embeddings", "localhost:11434", "stream"],
|
| 29 |
+
"source_id": "official-docs-ollama",
|
| 30 |
+
"details": [
|
| 31 |
+
"**OpenAI ํธํ API**: `http://localhost:11434/v1/chat/completions`๋ก OpenAI Python SDK๋ LangChain์ `ChatOpenAI(base_url=...)` ๊ทธ๋๋ก ์ฌ์ฉ ๊ฐ๋ฅํฉ๋๋ค.",
|
| 32 |
+
"**์คํธ๋ฆฌ๋ฐ**: `\"stream\": true` ์ค์ ์ ์๋ต์ JSON ์ค ๋จ์๋ก ์คํธ๋ฆฌ๋ฐ. `\"done\": true` ์ค์ด ์๋ฃ ์ ํธ์
๋๋ค.",
|
| 33 |
+
"**์๋ฒ ๋ฉ**: `POST /api/embeddings`์ `{\"model\":\"nomic-embed-text\", \"prompt\":\"ํ
์คํธ\"}`๋ฅผ ๋ณด๋ด๋ฉด ๋ฒกํฐ ๋ฐฐ์ด์ ๋ฐํํฉ๋๋ค."
|
| 34 |
+
]
|
| 35 |
+
},
|
| 36 |
+
{
|
| 37 |
+
"id": "docs-dotenv",
|
| 38 |
+
"certification": "Docs Study",
|
| 39 |
+
"title": "python-dotenv โ ํ๊ฒฝ๋ณ์ & .env ๊ด๋ฆฌ",
|
| 40 |
+
"level": "์
๋ฌธ",
|
| 41 |
+
"related_practices": ["docs-lab-4"],
|
| 42 |
+
"summary": "python-dotenv๋ `.env` ํ์ผ์ ํค-๊ฐ ์์ `os.environ`์ ์๋์ผ๋ก ๋ก๋ํฉ๋๋ค. API ํค ๊ฐ์ ๋ฏผ๊ฐ ์ ๋ณด๋ฅผ ์ฝ๋์ ์ง์ ์ฐ์ง ์๊ณ ํ์ผ๋ก ๋ถ๋ฆฌํด ๊ด๋ฆฌํ๋ ํ์ค ๋ฐฉ๋ฒ์
๋๋ค.",
|
| 43 |
+
"example": "# .env ํ์ผ\nOPENAI_API_KEY=sk-...\nOLLAMA_BASE_URL=http://localhost:11434\n\n# Python ์ฝ๋\nfrom dotenv import load_dotenv\nimport os\n\nload_dotenv() # .env ํ์ผ ๋ก๋\napi_key = os.getenv('OPENAI_API_KEY')",
|
| 44 |
+
"common_mistake": "`load_dotenv()`๋ฅผ ํธ์ถํ๊ธฐ ์ ์ `os.getenv()`๋ฅผ ์ฐ๋ฉด ํญ์ `None`์ ๋ฐํํฉ๋๋ค. ๋ฐ๋์ ํ์ผ ์๋จ์์ ๊ฐ์ฅ ๋จผ์ `load_dotenv()`๋ฅผ ํธ์ถํ์ธ์.",
|
| 45 |
+
"keywords": ["dotenv", "load_dotenv", ".env", "os.getenv", "ํ๊ฒฝ๋ณ์", "API ํค"],
|
| 46 |
+
"source_id": "official-docs-python",
|
| 47 |
+
"details": [
|
| 48 |
+
"**์ฐ์ ์์**: `load_dotenv(override=False)`(๊ธฐ๋ณธ๊ฐ)๋ ์ด๋ฏธ ์ค์ ๋ ํ๊ฒฝ๋ณ์๋ฅผ ๋ฎ์ด์ฐ์ง ์์ต๋๋ค. CI/CD ํ๊ฒฝ์์ ์์คํ
ํ๊ฒฝ๋ณ์๊ฐ .env๋ณด๋ค ์ฐ์ ํฉ๋๋ค.",
|
| 49 |
+
"**.gitignore**: `.env`๋ ๋ฐ๋์ `.gitignore`์ ์ถ๊ฐํด์ผ ํฉ๋๋ค. `.env.example`์ ํค ์ด๋ฆ๋ง ์ ์ด ํ์์๊ฒ ์ด๋ค ๋ณ์๊ฐ ํ์ํ์ง ์๋ ค์ฃผ๋ ์ฉ๋๋ก ์ปค๋ฐํฉ๋๋ค.",
|
| 50 |
+
"**Streamlit ์ฐ๋**: ๋ก์ปฌ ๊ฐ๋ฐ ์ `load_dotenv()`๋ก ํค๋ฅผ ๋ก๋ํ๊ณ , ๋ฐฐํฌ ์์๋ `st.secrets`๋ก ์ ๊ทผํ๋๋ก ๋ถ๊ธฐํ๊ฑฐ๋ ์ฒ์๋ถํฐ `st.secrets`๋ง ์ฐ๋ ๋ฐฉ์ ์ค ํ๋๋ฅผ ์ ํํฉ๋๋ค."
|
| 51 |
+
]
|
| 52 |
+
},
|
| 53 |
+
{
|
| 54 |
+
"id": "docs-prompt-template",
|
| 55 |
+
"certification": "Docs Study",
|
| 56 |
+
"title": "ChatPromptTemplate โ ํ๋กฌํํธ ๊ตฌ์กฐํ",
|
| 57 |
+
"level": "์
๋ฌธ",
|
| 58 |
+
"related_practices": ["docs-lab-5", "docs-lab-6"],
|
| 59 |
+
"summary": "ChatPromptTemplate์ ์์คํ
ํ๋กฌํํธ, ์ฌ์ฉ์ ๋ฉ์์ง, ๋ณ์ ํ๋ ์ด์คํ๋๋ฅผ ๊ตฌ์กฐํ๋ ๋ฐฉ์์ผ๋ก ์ ์ํฉ๋๋ค. ๋จ์ f-string ๋์ ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ๊ณ LangChain ํ์ดํ๋ผ์ธ์ ์ฐ๊ฒฐ๋๋ ํ๋กฌํํธ๋ฅผ ๋ง๋ค ๋ ์๋๋ค.",
|
| 60 |
+
"example": "from langchain_core.prompts import ChatPromptTemplate\n\nprompt = ChatPromptTemplate.from_messages([\n (\"system\", \"๋น์ ์ ๋์์ด ๋๋ AI ์ด์์คํดํธ์
๋๋ค. ์ปจํ
์คํธ: {context}\"),\n (\"human\", \"{question}\")\n])\n\n# ์ฒด์ธ์ ์ฐ๊ฒฐ\nchain = prompt | llm | StrOutputParser()\nchain.invoke({\"context\": \"...\", \"question\": \"์์ฝํด์ค\"})",
|
| 61 |
+
"common_mistake": "`PromptTemplate`์ ๋จ์ ๋ฌธ์์ด ํฌ๋งท์ฉ(๋ณ์ ํ๋), `ChatPromptTemplate`์ ์ญํ ์ด ๊ตฌ๋ถ๋ ๋ฉ์์ง ๋ฐฐ์ด์ฉ์
๋๋ค. RAG์์ ์์คํ
ํ๋กฌํํธ์ ์ง๋ฌธ์ ๊ตฌ๋ถํ๋ ค๋ฉด ํญ์ ChatPromptTemplate์ ์๋๋ค.",
|
| 62 |
+
"keywords": ["ChatPromptTemplate", "from_messages", "system", "human", "placeholder", "PromptTemplate"],
|
| 63 |
+
"source_id": "official-docs-langchain",
|
| 64 |
+
"details": [
|
| 65 |
+
"**MessagesPlaceholder**: ๋ํ ํ์คํ ๋ฆฌ๋ฅผ ํต์งธ๋ก ์ฃผ์
ํ ๋ ์๋๋ค. `(\"placeholder\", \"{chat_history}\")`๋ก ์ ์ธํ๋ฉด ๋ฉ์์ง ๋ฆฌ์คํธ๊ฐ ๊ทธ ์๋ฆฌ์ ํผ์ณ์ง๋๋ค.",
|
| 66 |
+
"**partial**: `prompt.partial(context=\"๊ณ ์ ๊ฐ\")`์ผ๋ก ํน์ ๋ณ์๋ฅผ ๋ฏธ๋ฆฌ ์ฑ์ธ ์ ์์ต๋๋ค. context๋ ๊ณ ์ ํ๊ณ question๋ง ๋ฐํ์์ ๋ฐ์ ๋ ์ ์ฉํฉ๋๋ค.",
|
| 67 |
+
"**ํ์
์์ ์ฑ**: from_messages์ `(\"system\", \"...\")` ํํ ๋์ `SystemMessage(content=\"...\")`๋ฅผ ์ฌ์ฉํด๋ ๋์ผํฉ๋๋ค. ํํ ๋ฐฉ์์ด ๋ ๊ฐ๊ฒฐํฉ๋๋ค."
|
| 68 |
+
]
|
| 69 |
+
},
|
| 70 |
+
{
|
| 71 |
+
"id": "docs-document-loaders",
|
| 72 |
+
"certification": "Docs Study",
|
| 73 |
+
"title": "LangChain Document Loaders โ ๋ฌธ์ ์ผ๊ด ๋ก๋",
|
| 74 |
+
"level": "์
๋ฌธ",
|
| 75 |
+
"related_practices": ["docs-lab-7"],
|
| 76 |
+
"summary": "Document Loader๋ PDF, ๋งํฌ๋ค์ด, ์น ํ์ด์ง, ๋๋ ํ ๋ฆฌ ๋ฑ ๋ค์ํ ์์ค์์ ๋ฌธ์๋ฅผ LangChain `Document` ๊ฐ์ฒด๋ก ๋ณํํฉ๋๋ค. RAG ํ์ดํ๋ผ์ธ์ ์ฒซ ๋จ๊ณ์
๋๋ค.",
|
| 77 |
+
"example": "from langchain_community.document_loaders import DirectoryLoader, PyPDFLoader\n\n# ๋๋ ํ ๋ฆฌ ๋ด ๋ชจ๋ .md ํ์ผ ๋ก๋\nloader = DirectoryLoader('./notes', glob='**/*.md')\ndocs = loader.load()\n\n# ๊ฐ ๋ฌธ์์ ์ถ์ฒ ํ์ธ\nfor doc in docs:\n print(doc.metadata['source'], len(doc.page_content))",
|
| 78 |
+
"common_mistake": "`loader.load()`๋ ๋ชจ๋ ๋ฌธ์๋ฅผ ๋ฉ๋ชจ๋ฆฌ์ ์ฌ๋ฆฝ๋๋ค. ๋์ฉ๋ ๋๋ ํ ๋ฆฌ์์๋ `loader.lazy_load()`๋ก ์ ๋๋ ์ดํฐ๋ฅผ ์ฐ๊ฑฐ๋ ๋ฐฐ์น๋ก ์ฒ๋ฆฌํด์ผ ํฉ๋๋ค.",
|
| 79 |
+
"keywords": ["DirectoryLoader", "PyPDFLoader", "WebBaseLoader", "glob", "metadata", "source", "lazy_load"],
|
| 80 |
+
"source_id": "official-docs-langchain",
|
| 81 |
+
"details": [
|
| 82 |
+
"**metadata['source']**: ๋ก๋๋ ๋ฌธ์๋ `metadata` ๋์
๋๋ฆฌ์ ํ์ผ ๊ฒฝ๋ก(`source`)๋ฅผ ํฌํจํฉ๋๋ค. RAG ๋ต๋ณ์ ์ถ์ฒ๋ฅผ ํ์ํ ๋ ์ด ๊ฐ์ ์๋๋ค.",
|
| 83 |
+
"**glob ํจํด**: `glob='**/*.md'`๋ ํ์ ํด๋๊น์ง ์ฌ๊ท ๊ฒ์ํฉ๋๋ค. `glob='*.pdf'`๋ ํ์ฌ ํด๋๋ง ๊ฒ์ํฉ๋๋ค.",
|
| 84 |
+
"**WebBaseLoader**: URL ๋ฆฌ์คํธ๋ฅผ ๋๊ธฐ๋ฉด ์น ํ์ด์ง๋ฅผ ํฌ๋กค๋งํด Document๋ก ๋ณํํฉ๋๋ค. BeautifulSoup ๊ธฐ๋ฐ์ด๋ฉฐ `bs_kwargs`๋ก ํ์ฑ ๋ฒ์๋ฅผ ์ง์ ํ ์ ์์ต๋๋ค."
|
| 85 |
+
]
|
| 86 |
+
},
|
| 87 |
+
{
|
| 88 |
+
"id": "docs-langchain-rag",
|
| 89 |
+
"certification": "Docs Study",
|
| 90 |
+
"title": "LangChain RAG ๊ธฐ๋ณธ ํ๋ฆ",
|
| 91 |
+
"level": "์
๋ฌธ",
|
| 92 |
+
"related_practices": ["docs-lab-8", "docs-lab-9"],
|
| 93 |
+
"summary": "LangChain์ ๋ฌธ์ ๋ก๋ โ ๋ถํ โ ์๋ฒ ๋ฉ โ ๊ฒ์ โ ์์ฑ์ RAG ํ์ดํ๋ผ์ธ์ ์ปดํฌ๋ํธ ์กฐํฉ์ผ๋ก ๊ตฌํํฉ๋๋ค. Retriever๊ฐ ๊ด๋ จ ๋ฌธ์๋ฅผ ์ฐพ์ LLM ์ปจํ
์คํธ๋ก ์ฃผ์
ํฉ๋๋ค.",
|
| 94 |
+
"example": "from langchain_community.vectorstores import Chroma\nretriever = Chroma.from_documents(docs, embeddings).as_retriever(k=3)\nchain = (\n {\"context\": retriever, \"question\": RunnablePassthrough()}\n | prompt | llm | StrOutputParser()\n)",
|
| 95 |
+
"common_mistake": "Retriever๊ฐ ์ฐพ์ ๋ฌธ์๋ฅผ ๊ทธ๋๋ก ์ ๋ต์ผ๋ก ๋ฏฟ์ง ๋ง์ธ์. ๊ฒ์๋ ์ฒญํฌ๊ฐ ์ง๋ฌธ๊ณผ ๋ค๋ฅธ ๋งฅ๋ฝ์ผ ์ ์์ด ํ๋กฌํํธ์์ ๋ช
์์ ์ผ๋ก '์๋ ๋ฌธ์๋ฅผ ์ฐธ๊ณ ํด'๋ผ๊ณ ์ง์ํด์ผ ํฉ๋๋ค.",
|
| 96 |
+
"keywords": ["langchain", "RAG", "retriever", "vectorstore", "document loader", "text splitter"],
|
| 97 |
+
"source_id": "official-docs-langchain",
|
| 98 |
+
"details": [
|
| 99 |
+
"**ํ์ดํ๋ผ์ธ ๋จ๊ณ**: DocumentLoader โ TextSplitter(์ฒญํฌ ๋ถํ ) โ Embeddings โ VectorStore โ Retriever โ LLM Chain.",
|
| 100 |
+
"**TextSplitter**: `RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50)`์ด ์ผ๋ฐ์ ์์์ . overlap์ด ์์ด์ผ ์ฒญํฌ ๊ฒฝ๊ณ์์ ๋ฌธ๋งฅ ์์ค์ ์ค์
๋๋ค.",
|
| 101 |
+
"`MultiQueryRetriever`๋ `ContextualCompressionRetriever`๋ก ๊ฒ์ ํ์ง์ ๋์ผ ์ ์์ต๋๋ค. ๋จ์ ์ ์ฌ๋ ๊ฒ์๋ณด๋ค ๊ด๋ จ ์ฒญํฌ ์ ๋ณ ์ ํ๋๊ฐ ์ฌ๋ผ๊ฐ๋๋ค."
|
| 102 |
+
]
|
| 103 |
+
},
|
| 104 |
+
{
|
| 105 |
+
"id": "docs-lcel",
|
| 106 |
+
"certification": "Docs Study",
|
| 107 |
+
"title": "LangChain LCEL โ ์ฒด์ธ ๊ตฌ์ฑ",
|
| 108 |
+
"level": "์
๋ฌธ",
|
| 109 |
+
"related_practices": ["docs-lab-10", "docs-lab-11"],
|
| 110 |
+
"summary": "LCEL(LangChain Expression Language)์ `|` ํ์ดํ ์ฐ์ฐ์๋ก Runnable ์ปดํฌ๋ํธ๋ฅผ ์ง๋ ฌยท๋ณ๋ ฌ ์ฐ๊ฒฐํด ์ฒด์ธ์ ์ ์ธ์ ์ผ๋ก ์ ์ํฉ๋๋ค.",
|
| 111 |
+
"example": "from langchain_core.runnables import RunnablePassthrough\nchain = (\n RunnablePassthrough.assign(context=retriever)\n | prompt\n | llm\n | StrOutputParser()\n)\nresult = chain.invoke({\"question\": \"What is RAG?\"})",
|
| 112 |
+
"common_mistake": "์ฒด์ธ ๊ฐ ๋จ๊ณ์ ์
์ถ๋ ฅ ํ์
์ด ๋ง์์ผ ํฉ๋๋ค. LLM์ `str` ๋๋ `BaseMessage`๋ฅผ ๋ฐ๊ณ ๋ฐํํ๋ฏ๋ก, ์ ๋จ๊ณ๊ฐ ๋์
๋๋ฆฌ๋ฅผ ๋ฐํํ๋ฉด ํ๋กฌํํธ ํ
ํ๋ฆฟ์ด ์ค๊ฐ์์ ๋ฐ์ ์ฒ๋ฆฌํด์ผ ํฉ๋๋ค.",
|
| 113 |
+
"keywords": ["LCEL", "Runnable", "pipe", "chain", "invoke", "stream", "batch"],
|
| 114 |
+
"source_id": "official-docs-langchain",
|
| 115 |
+
"details": [
|
| 116 |
+
"**3๊ฐ์ง ์คํ ๋ฐฉ์**: `invoke`(๋จ์ผ ๋๊ธฐ), `stream`(์คํธ๋ฆฌ๋ฐ yield), `batch`(๋ฆฌ์คํธ ๋ณ๋ ฌ ์ฒ๋ฆฌ). ์คํธ๋ฆฌ๋ฐ UI์๋ `stream`์ ์๋๋ค.",
|
| 117 |
+
"**RunnablePassthrough**: ์
๋ ฅ์ ๊ทธ๋๋ก ๋ค์ ๋จ๊ณ๋ก ์ ๋ฌ. `.assign(key=fn)`์ผ๋ก ์ถ๊ฐ ํค๋ฅผ ๋ถ์ฌ ๋์
๋๋ฆฌ๋ฅผ ํ์ฅํฉ๋๋ค.",
|
| 118 |
+
"**RunnableParallel**: `{\"a\": fn1, \"b\": fn2}` ํํ๋ก ์ฌ๋ฌ ์ฒด์ธ์ ๋์์ ์คํํด ๊ฒฐ๊ณผ๋ฅผ ๋์
๋๋ฆฌ๋ก ํฉ์นฉ๋๋ค."
|
| 119 |
+
]
|
| 120 |
+
},
|
| 121 |
+
{
|
| 122 |
+
"id": "docs-vectorstore",
|
| 123 |
+
"certification": "Docs Study",
|
| 124 |
+
"title": "VectorStore์ Retriever โ ๋ฒกํฐ ๊ฒ์",
|
| 125 |
+
"level": "์
๋ฌธ",
|
| 126 |
+
"related_practices": ["docs-lab-11", "docs-lab-12"],
|
| 127 |
+
"summary": "๋ฌธ์๋ฅผ ์๋ฒ ๋ฉ ๋ฒกํฐ๋ก ๋ณํํด ์ ์ฅํ๊ณ , ์ฟผ๋ฆฌ์ ์ฝ์ฌ์ธ ์ ์ฌ๋๋ก ๊ด๋ จ ์ฒญํฌ๋ฅผ ๊ฒ์ํฉ๋๋ค. Chroma, FAISS, pgvector ๋ฑ ๋ค์ํ ๋ฐฑ์๋๋ฅผ LangChain์ด ์ถ์ํํฉ๋๋ค.",
|
| 128 |
+
"example": "from langchain_community.vectorstores import Chroma\nfrom langchain_ollama import OllamaEmbeddings\n\nembeddings = OllamaEmbeddings(model='nomic-embed-text')\ndb = Chroma.from_documents(docs, embeddings, persist_directory='./db')\nretriever = db.as_retriever(search_type='mmr', search_kwargs={'k': 4})",
|
| 129 |
+
"common_mistake": "์๋ฒ ๋ฉ ๋ชจ๋ธ์ ๋ณ๊ฒฝํ๋ฉด ๋ฒกํฐ ์ฐจ์์ด ๋ฌ๋ผ์ ธ ๊ธฐ์กด ์ปฌ๋ ์
๊ณผ ํธํ๋์ง ์์ต๋๋ค. ๋ชจ๋ธ์ ๋ฐ๊ฟ ๋๋ ์ปฌ๋ ์
์ ์๋ก ๋ง๋ค์ด์ผ ํฉ๋๋ค.",
|
| 130 |
+
"keywords": ["vectorstore", "Chroma", "FAISS", "embedding", "similarity", "MMR", "retriever"],
|
| 131 |
+
"source_id": "official-docs-langchain",
|
| 132 |
+
"details": [
|
| 133 |
+
"**๊ฒ์ ์ ํ**: `similarity`(์์ ์ ์ฌ๋ ์์ k๊ฐ), `mmr`(MMR: ๋ค์์ฑ ๊ณ ๋ ค), `similarity_score_threshold`(์๊ณ๊ฐ ์ด์๋ง).",
|
| 134 |
+
"**Chroma**: ๋ก์ปฌ ํ์ผ๋ก ์ ์ฅ ๊ฐ๋ฅ(`persist_directory`). ํ๋กํ ํ์
์ ์ ํฉ. ํ๋ก๋์
์ pgvector(PostgreSQL), Qdrant, Pinecone ๊ถ์ฅ.",
|
| 135 |
+
"์๋ฒ ๋ฉ์ ํ
์คํธ์ ์๋ฏธ์ ์ ์ฌ๋๋ฅผ ์ก์ง๋ง, ์ ํํ ํค์๋ ๋งค์นญ์ด ํ์ํ๋ฉด BM25 ๋ฑ ํค์๋ ๊ฒ์๊ณผ `EnsembleRetriever`๋ก ํ์ด๋ธ๋ฆฌ๋ ๊ตฌ์ฑ์ ๊ณ ๋ คํฉ๋๋ค."
|
| 136 |
+
]
|
| 137 |
+
},
|
| 138 |
+
{
|
| 139 |
+
"id": "docs-streamlit-state",
|
| 140 |
+
"certification": "Docs Study",
|
| 141 |
+
"title": "Streamlit session_state โ ์ํ ๊ด๋ฆฌ",
|
| 142 |
+
"level": "์
๋ฌธ",
|
| 143 |
+
"related_practices": ["docs-lab-16", "docs-lab-17"],
|
| 144 |
+
"summary": "Streamlit์ ์ํธ์์ฉ๋ง๋ค ์คํฌ๋ฆฝํธ ์ ์ฒด๋ฅผ rerunํฉ๋๋ค. ๋ฒํผ ํด๋ฆญยท์
๋ ฅ ๊ฒฐ๊ณผ๋ฅผ rerun ์ดํ์๋ ์ ์งํ๋ ค๋ฉด `st.session_state`์ ์ ์ฅํด์ผ ํฉ๋๋ค.",
|
| 145 |
+
"example": "if 'count' not in st.session_state:\n st.session_state.count = 0\nif st.button('์ฆ๊ฐ'):\n st.session_state.count += 1\nst.write(f'ํด๋ฆญ ํ์: {st.session_state.count}')",
|
| 146 |
+
"common_mistake": "์ผ๋ฐ ์ ์ญ ๋ณ์๋ ํจ์ ๋ด ์ง์ญ ๋ณ์๋ rerun๋ง๋ค ์ด๊ธฐํ๋ฉ๋๋ค. ์ํ ๋ณด์กด์ด ํ์ํ ๋ชจ๋ ๊ฐ์ ๋ฐ๋์ `st.session_state`๋ฅผ ์ฌ์ฉํ์ธ์.",
|
| 147 |
+
"keywords": ["session_state", "rerun", "widget", "state management", "callback"],
|
| 148 |
+
"source_id": "official-docs-streamlit",
|
| 149 |
+
"details": [
|
| 150 |
+
"**์ด๊ธฐํ ํจํด**: `st.session_state.setdefault('key', default_value)` ๋๋ `if 'key' not in st.session_state:` ๋ธ๋ก์ผ๋ก ์์ ํ๊ฒ ์ด๊ธฐํํฉ๋๋ค.",
|
| 151 |
+
"**Widget key**: `st.text_input('์ด๋ฆ', key='username')`์ผ๋ก ์์ ฏ ๊ฐ์ด ์๋์ผ๋ก `st.session_state.username`์ ์ ์ฅ๋ฉ๋๋ค.",
|
| 152 |
+
"**callback**: `on_change=my_func`์ผ๋ก ์์ ฏ ๋ณ๊ฒฝ ์ ํจ์๋ฅผ ์คํํฉ๋๋ค. callback ์์์ session_state๋ฅผ ์์ ํ๋ฉด rerun ์ ์ ์ฒ๋ฆฌ๋ฉ๋๋ค."
|
| 153 |
+
]
|
| 154 |
+
},
|
| 155 |
+
{
|
| 156 |
+
"id": "docs-streamlit-cache",
|
| 157 |
+
"certification": "Docs Study",
|
| 158 |
+
"title": "Streamlit Cache โ ์บ์ ๋ฐ์ฝ๋ ์ดํฐ",
|
| 159 |
+
"level": "์
๋ฌธ",
|
| 160 |
+
"related_practices": ["docs-lab-18"],
|
| 161 |
+
"summary": "rerun๋ง๋ค ๋ฐ๋ณต ์คํ๋๋ ๋น์ฉ ๋์ ๊ณ์ฐยท๋ฆฌ์์ค ๋ก๋ฉ์ ์บ์ํด ์ฑ๋ฅ์ ๋์
๋๋ค. `@st.cache_data`๋ ์ง๋ ฌํ ๊ฐ๋ฅ ๋ฐ์ดํฐ, `@st.cache_resource`๋ DBยท๋ชจ๋ธ ๊ฐ์ ๊ณต์ ๊ฐ์ฒด์ ์๋๋ค.",
|
| 162 |
+
"example": "@st.cache_resource\ndef load_model():\n return SentenceTransformer('all-MiniLM-L6-v2')\n\n@st.cache_data(ttl=300)\ndef fetch_data(query: str):\n return db.execute(query).fetchall()",
|
| 163 |
+
"common_mistake": "`cache_data`์ `cache_resource`๋ฅผ ํผ๋ํ๋ฉด ๋ฌธ์ ๊ฐ ์๊น๋๋ค. LLM ๋ชจ๋ธ์ด๋ DB ์ฐ๊ฒฐ์ฒ๋ผ ๊ณต์ ํด์ผ ํ๋ ๊ฐ์ฒด๋ ๋ฐ๋์ `cache_resource`๋ฅผ ์จ์ผ ํฉ๋๋ค.",
|
| 164 |
+
"keywords": ["cache_data", "cache_resource", "TTL", "rerun", "performance"],
|
| 165 |
+
"source_id": "official-docs-streamlit",
|
| 166 |
+
"details": [
|
| 167 |
+
"**`@st.cache_data`**: ํจ์ ์ธ์๋ฅผ ํค๋ก ๊ฒฐ๊ณผ๋ฅผ ๋ณต์ฌํด ์บ์. DataFrame, ๋ฆฌ์คํธ ๋ฑ ์ง๋ ฌํ ๊ฐ๋ฅ ๋ฐํ๊ฐ์ ์ ํฉ. `ttl` ์ธ์๋ก ๋ง๋ฃ ์๊ฐ ์ค์ ๊ฐ๋ฅ.",
|
| 168 |
+
"**`@st.cache_resource`**: ์ฑ๊ธํค์ฒ๋ผ ํ ๋ฒ๋ง ์์ฑํด ๋ชจ๋ ์ธ์
์ด ๊ณต์ . ๋ชจ๋ธ ๋ก๋ฉ, DB ์ฐ๊ฒฐ, ๋ฒกํฐ ์คํ ์ด ์ด๊ธฐํ์ ์ ํฉ.",
|
| 169 |
+
"์บ์ ๋ฌดํจํ: `st.cache_data.clear()` / `st.cache_resource.clear()`๋ก ์๋ ์ด๊ธฐํ. ํจ์ ๋ณธ๋ฌธ์ด ๋ฐ๋๋ฉด ์๋์ผ๋ก ์บ์๊ฐ ๋ฌดํจํ๋ฉ๋๋ค."
|
| 170 |
+
]
|
| 171 |
+
},
|
| 172 |
+
{
|
| 173 |
+
"id": "docs-streamlit-secrets",
|
| 174 |
+
"certification": "Docs Study",
|
| 175 |
+
"title": "Streamlit Secrets โ ๋น๋ฐ ๊ด๋ฆฌ",
|
| 176 |
+
"level": "์
๋ฌธ",
|
| 177 |
+
"related_practices": ["docs-lab-4"],
|
| 178 |
+
"summary": "API ํค, DB ๋น๋ฐ๋ฒํธ ๋ฑ ๋ฏผ๊ฐ ์ ๋ณด๋ฅผ ์ฝ๋์ ๋ฃ์ง ์๊ณ `.streamlit/secrets.toml` ํ์ผ ๋๋ Streamlit Cloud์ Secrets UI์ ์ ์ฅํฉ๋๋ค.",
|
| 179 |
+
"example": "# .streamlit/secrets.toml\n[database]\nhost = 'localhost'\npassword = 'secret'\n\n# ์ฝ๋์์ ์ ๊ทผ\nimport streamlit as st\ndb_pass = st.secrets['database']['password']",
|
| 180 |
+
"common_mistake": "`.streamlit/secrets.toml`์ `.gitignore`์ ์ถ๊ฐํ์ง ์์ผ๋ฉด ๋ฏผ๊ฐ ์ ๋ณด๊ฐ Git์ ์ปค๋ฐ๋ ์ ์์ต๋๋ค. ๋ฐ๋์ ์ ์ธํ์ธ์.",
|
| 181 |
+
"keywords": ["secrets", "secrets.toml", "API key", ".gitignore", "Streamlit Cloud"],
|
| 182 |
+
"source_id": "official-docs-streamlit",
|
| 183 |
+
"details": [
|
| 184 |
+
"๋ก์ปฌ ๊ฐ๋ฐ: `.streamlit/secrets.toml`์ TOML ํ์์ผ๋ก ์ ์ฅ. ์ฑ ์ฝ๋์์ `st.secrets`๋ก ๋์
๋๋ฆฌ์ฒ๋ผ ์ ๊ทผํฉ๋๋ค.",
|
| 185 |
+
"Streamlit Cloud: ์ฑ Settings โ Secrets์ ๊ฐ์ TOML ๋ด์ฉ์ ๋ถ์ฌ๋ฃ์ผ๋ฉด ๋ฐฐํฌ ์ ์๋ ์ฃผ์
๋ฉ๋๋ค.",
|
| 186 |
+
"`st.secrets`๋ `os.environ`๋ณด๋ค ๊ตฌ์กฐํ๋ ์ ๊ทผ์ ์ง์ํฉ๋๋ค. `st.secrets['key']`์ `st.secrets.key` ๋ ๋ฐฉ์ ๋ชจ๋ ๊ฐ๋ฅํฉ๋๋ค."
|
| 187 |
+
]
|
| 188 |
+
},
|
| 189 |
+
{
|
| 190 |
+
"id": "docs-hf-spaces",
|
| 191 |
+
"certification": "Docs Study",
|
| 192 |
+
"title": "Hugging Face Spaces โ ์ฑ ๋ฐฐํฌ",
|
| 193 |
+
"level": "์
๋ฌธ",
|
| 194 |
+
"related_practices": ["docs-lab-19"],
|
| 195 |
+
"summary": "Hugging Face Spaces๋ Streamlit, Gradio, Docker ์ฑ์ ๋ฌด๋ฃ๋ก ํธ์คํ
ํ๋ ํ๊ฒฝ์
๋๋ค. README.md ์๋จ์ YAML ๋ฉํ๋ฐ์ดํฐ๋ก SDK์ ํ์ผ์ ์ง์ ํฉ๋๋ค.",
|
| 196 |
+
"example": "# README.md ์๋จ (YAML frontmatter)\n---\ntitle: My App\nsdk: streamlit\napp_file: app.py\npython_version: '3.11'\n---",
|
| 197 |
+
"common_mistake": "API ํค ๋ฑ ๋ฏผ๊ฐ ์ ๋ณด๋ ์ฝ๋์ ํ๋์ฝ๋ฉํ์ง ๋ง์ธ์. Space Settings โ Secrets์ ๋ฑ๋กํ๊ณ ์ฝ๋์์๋ `os.environ['MY_KEY']`๋ก ์ฐธ์กฐํฉ๋๋ค.",
|
| 198 |
+
"keywords": ["huggingface", "spaces", "SDK", "secrets", "app_file", "README metadata"],
|
| 199 |
+
"source_id": "official-docs-huggingface",
|
| 200 |
+
"details": [
|
| 201 |
+
"**๋ฌด๋ฃ ํฐ์ด**: CPU ๊ธฐ๋ณธ ์ ๊ณต, ๊ณต๊ฐ Space๋ ๋ฌด๋ฃ. GPU๋ ๋น๊ณต๊ฐ Space๋ ์ ๋ฃ ํ๋ ๋๋ ZeroGPU(๋ฌด๋ฃ ๊ณต์ GPU) ํ์ฉ.",
|
| 202 |
+
"**Secrets**: `Settings โ Repository secrets`์ ํค-๊ฐ์ผ๋ก ๋ฑ๋ก. ๋น๋ ๋ฐ ๋ฐํ์์ ํ๊ฒฝ ๋ณ์๋ก ์ฃผ์
๋ฉ๋๋ค.",
|
| 203 |
+
"Space๋ฅผ Duplicate(๋ณต์ )ํ๋ฉด fork์ฒ๋ผ ๋
๋ฆฝ๋ Space๊ฐ ์์ฑ๋ฉ๋๋ค. ํ์ธ์ ๋ชจ๋ธยท์ฑ์ ๋ด Secrets์ ํจ๊ป ์ปค์คํ
ํ๋ ์ผ๋ฐ์ ์ธ ํจํด์
๋๋ค."
|
| 204 |
+
]
|
| 205 |
+
},
|
| 206 |
+
{
|
| 207 |
+
"id": "docs-hf-docker-space",
|
| 208 |
+
"certification": "Docs Study",
|
| 209 |
+
"title": "Hugging Face Docker Space",
|
| 210 |
+
"level": "์
๋ฌธ",
|
| 211 |
+
"related_practices": ["docs-lab-20"],
|
| 212 |
+
"summary": "Dockerfile๋ก ์ฑ ํ๊ฒฝ์ ์ง์ ์ ์ํ๋ Space ๋ฐฐํฌ ๋ฐฉ์์
๋๋ค. Streamlit/Gradio SDK ์ ์ฝ์ ๋์ด FastAPI, ์ปค์คํ
์๋ฒ ๋ฑ ์ด๋ค ์ฑ๋ ๋ฐฐํฌํ ์ ์์ต๋๋ค.",
|
| 213 |
+
"example": "# README.md\n---\ntitle: My API\nsdk: docker\napp_port: 7860\n---\n\n# Dockerfile\nFROM python:3.11-slim\nCOPY . .\nRUN pip install -r requirements.txt\nEXPOSE 7860\nCMD [\"uvicorn\", \"main:app\", \"--host\", \"0.0.0.0\", \"--port\", \"7860\"]",
|
| 214 |
+
"common_mistake": "Docker Space๋ ํฌํธ 7860์ ๊ธฐ๋ณธ์ผ๋ก ๋
ธ์ถํฉ๋๋ค(`app_port: 7860`). ์ฑ์ด ๋ค๋ฅธ ํฌํธ๋ฅผ ์ฌ์ฉํ๋ฉด README ๋ฉํ๋ฐ์ดํฐ์ `app_port`์ ์ผ์น์์ผ์ผ ํฉ๋๋ค.",
|
| 215 |
+
"keywords": ["docker", "Dockerfile", "Spaces", "app_port", "FastAPI", "custom server"],
|
| 216 |
+
"source_id": "official-docs-huggingface",
|
| 217 |
+
"details": [
|
| 218 |
+
"**๋น๋ ์บ์**: Space๋ ์ด์ ๋น๋ ๋ ์ด์ด๋ฅผ ์บ์ํฉ๋๋ค. `COPY requirements.txt .` ํ `RUN pip install`์ ๋ฐฐ์นํด ์์กด์ฑ ๋ ์ด์ด๋ฅผ ์ฑ ์ฝ๋๋ณด๋ค ์์ ๋๋ฉด ๋น๋๊ฐ ๋น ๋ฆ
๋๋ค.",
|
| 219 |
+
"**Secrets**: `docker build --build-arg`๊ฐ ์๋ Runtime Secrets๋ก ์ฃผ์
ํด์ผ ์ด๋ฏธ์ง์ ๋ฏผ๊ฐ ์ ๋ณด๊ฐ ํฌํจ๋์ง ์์ต๋๋ค. `os.environ`์ผ๋ก ์ ๊ทผํฉ๋๋ค.",
|
| 220 |
+
"**๋ชจ๋ธ ํ์ผ**: ๋ํ ๋ชจ๋ธ์ Space ์ ์ฅ์์ ์ง์ ๋ฃ์ง ๋ง๊ณ `huggingface_hub.snapshot_download()`๋ก ๋ฐํ์์ ๊ฐ์ ธ์ค๊ฑฐ๋ Dataset ์ ์ฅ์๋ฅผ ๋ง์ดํธํ๋ ๋ฐฉ์์ ์๋๋ค."
|
| 221 |
+
]
|
| 222 |
+
},
|
| 223 |
+
{
|
| 224 |
+
"id": "docs-fastapi",
|
| 225 |
+
"certification": "Docs Study",
|
| 226 |
+
"title": "FastAPI โ LLM ์๋น์ค API ์๋ฒ",
|
| 227 |
+
"level": "์ค๊ธ",
|
| 228 |
+
"related_practices": ["docs-lab-21"],
|
| 229 |
+
"summary": "FastAPI๋ Python ํ์
ํํธ ๊ธฐ๋ฐ์ ๊ณ ์ฑ๋ฅ ๋น๋๊ธฐ API ํ๋ ์์ํฌ์
๋๋ค. RAG ์ฒด์ธ์ด๋ LLM ๊ธฐ๋ฅ์ REST API ์๋ํฌ์ธํธ๋ก ๋
ธ์ถํ ๋ ๊ฐ์ฅ ๋ง์ด ์ฐ์
๋๋ค.",
|
| 230 |
+
"example": "from fastapi import FastAPI\nfrom pydantic import BaseModel\n\napp = FastAPI()\n\nclass Query(BaseModel):\n question: str\n\n@app.post('/ask')\nasync def ask(q: Query):\n answer = chain.invoke(q.question)\n return {\"answer\": answer}\n\n# ์คํ\n# uvicorn main:app --reload",
|
| 231 |
+
"common_mistake": "LangChain ์ฒด์ธ ๊ฐ์ ๋ฌด๊ฑฐ์ด ๊ฐ์ฒด๋ฅผ ์์ฒญ๋ง๋ค ์์ฑํ์ง ๋ง์ธ์. ๋ชจ๋ ๋ ๋ฒจ์์ ํ ๋ฒ ์ด๊ธฐํํ๊ฑฐ๋ `lifespan` ์ด๋ฒคํธ๋ก ์ฑ ์์ ์ ๋ก๋ํ์ธ์.",
|
| 232 |
+
"keywords": ["fastapi", "uvicorn", "pydantic", "async", "REST API", "endpoint", "lifespan"],
|
| 233 |
+
"source_id": "official-docs-fastapi",
|
| 234 |
+
"details": [
|
| 235 |
+
"**Pydantic**: ์์ฒญ/์๋ต ์คํค๋ง๋ฅผ `BaseModel`๋ก ์ ์ํ๋ฉด ์๋ ๊ฒ์ฆ, OpenAPI ๋ฌธ์(`/docs`), JSON ์ง๋ ฌํ๊ฐ ๋ฌด๋ฃ๋ก ์ ๊ณต๋ฉ๋๋ค.",
|
| 236 |
+
"**์คํธ๋ฆฌ๋ฐ ์๋ต**: `StreamingResponse`์ async generator๋ก LLM ์ถ๋ ฅ์ Server-Sent Events(SSE)๋ก ์คํธ๋ฆฌ๋ฐํ ์ ์์ต๋๋ค.",
|
| 237 |
+
"**lifespan**: `@asynccontextmanager`๋ก ์ฑ ์์ ์ ๋ชจ๋ธยทDB ์ฐ๊ฒฐ์ ์ด๊ธฐํํ๊ณ ์ข
๋ฃ ์ ์ ๋ฆฌํ๋ ํจํด. FastAPI 0.95+ ๊ถ์ฅ ๋ฐฉ์์
๋๋ค."
|
| 238 |
+
]
|
| 239 |
+
},
|
| 240 |
+
{
|
| 241 |
+
"id": "docs-langsmith",
|
| 242 |
+
"certification": "Docs Study",
|
| 243 |
+
"title": "LangSmith โ LLM ์ถ์ & ํ๊ฐ",
|
| 244 |
+
"level": "์ค๊ธ",
|
| 245 |
+
"related_practices": ["docs-lab-13"],
|
| 246 |
+
"summary": "LangSmith๋ LangChain ํ์ดํ๋ผ์ธ์ ๋ชจ๋ LLM ํธ์ถ, ํ๋กฌํํธ, ์๋ต, ์ง์ฐ์๊ฐ์ ์๋ ์ถ์ ํฉ๋๋ค. ๋ฒ๊ทธ ๋๋ฒ๊น
, ํ๋กฌํํธ ๋น๊ต, ํ๊ฐ ๋ฐ์ดํฐ์
๊ด๋ฆฌ๋ฅผ ํ ๊ณณ์์ ํฉ๋๋ค.",
|
| 247 |
+
"example": "import os\nos.environ['LANGCHAIN_TRACING_V2'] = 'true'\nos.environ['LANGCHAIN_API_KEY'] = 'ls__...'\nos.environ['LANGCHAIN_PROJECT'] = 'my-rag-app'\n\n# ์ดํ LangChain ์ฝ๋๋ ์๋์ผ๋ก ์ถ์ ๋จ\nresult = chain.invoke({'question': '์ง๋ฌธ'})",
|
| 248 |
+
"common_mistake": "์ถ์ ํ์ฑํ๋ ํ๊ฒฝ๋ณ์ 3๊ฐ(`TRACING_V2=true`, `API_KEY`, `PROJECT`)๊ฐ ๋ชจ๋ ์์ด์ผ ํฉ๋๋ค. ํ๋๋ผ๋ ๋น ์ง๋ฉด ์กฐ์ฉํ ์ถ์ ์ด ์ ๋ฉ๋๋ค.",
|
| 249 |
+
"keywords": ["langsmith", "tracing", "LangChain", "debugging", "evaluation", "dataset", "prompt"],
|
| 250 |
+
"source_id": "official-docs-langchain",
|
| 251 |
+
"details": [
|
| 252 |
+
"**Run ํธ๋ ์ด์ค**: ์ฒด์ธ ์คํ๋ง๋ค tree ํํ๋ก ๊ฐ ๋จ๊ณ์ ์
์ถ๋ ฅยทํ ํฐ ์ยท์ง์ฐ์๊ฐ์ ๊ธฐ๋กํฉ๋๋ค. ์ด๋ ๋จ๊ณ์์ ์ค๋ฅ๊ฐ ๋ฌ๋์ง ์ฆ์ ํ์
ํ ์ ์์ต๋๋ค.",
|
| 253 |
+
"**๋ฐ์ดํฐ์
& ํ๊ฐ**: ํ๋ก๋์
์ค๋ฅ ์ผ์ด์ค๋ฅผ Dataset์ผ๋ก ์ ์ฅ โ Evaluator(LLM-as-judge ๋ฑ)๋ก ์๋ ํ๊ฐ โ CI์ ํตํฉํ๋ ํ๋ฆ์ ์ง์ํฉ๋๋ค.",
|
| 254 |
+
"**Playground**: LangSmith UI์์ ํน์ Run์ ํ๋กฌํํธ๋ฅผ ๋ฐ๋ก ์์ ํด ์ฌ์คํ ๊ฐ๋ฅ. ํ๋กฌํํธ ์์ง๋์ด๋ง ๋ฐ๋ณต์ ์ ์ฉํฉ๋๋ค."
|
| 255 |
+
]
|
| 256 |
+
},
|
| 257 |
+
{
|
| 258 |
+
"id": "docs-guardrails",
|
| 259 |
+
"certification": "Docs Study",
|
| 260 |
+
"title": "Guardrails AI โ LLM ์ถ๋ ฅ ๊ฒ์ฆ",
|
| 261 |
+
"level": "์ค๊ธ",
|
| 262 |
+
"related_practices": ["docs-lab-14"],
|
| 263 |
+
"summary": "Guardrails AI๋ LLM ์
๋ ฅ/์ถ๋ ฅ์ ๊ฒ์ฆ ๊ท์น(Guard)์ ์ ์ฉํฉ๋๋ค. ์ ํด ์ฝํ
์ธ ์ฐจ๋จ, JSON ์คํค๋ง ๊ฐ์ , PII ๋ง์คํน ๋ฑ ํ๋ก๋์
LLM ์ฑ์ ์์ ์ฅ์น ์ญํ ์ ํฉ๋๋ค.",
|
| 264 |
+
"example": "from guardrails import Guard\nfrom guardrails.hub import ToxicLanguage\n\nguard = Guard().use(ToxicLanguage(threshold=0.5, on_fail='exception'))\n\nresult = guard(\n llm_api=openai.chat.completions.create,\n prompt='์ฌ์ฉ์ ์
๋ ฅ: {{user_input}}',\n user_input=user_message\n)",
|
| 265 |
+
"common_mistake": "Guard๋ LLM ํธ์ถ์ ๋ํํ๋ฏ๋ก ์๋ต ์๊ฐ์ด ์ฆ๊ฐํฉ๋๋ค. ๋ชจ๋ ์์ฒญ์ heavy Guard๋ฅผ ๊ฑธ๋ฉด ์ง์ฐ์ด ์ปค์ง๋, ์
๋ ฅ ๊ฒ์ฆ๊ณผ ์ถ๋ ฅ ๊ฒ์ฆ์ ๋ถ๋ฆฌํด ํ์ํ ๊ฒ๋ง ์ ์ฉํ์ธ์.",
|
| 266 |
+
"keywords": ["guardrails", "guard", "validation", "toxic", "PII", "JSON schema", "on_fail", "safety"],
|
| 267 |
+
"source_id": "official-docs-guardrails",
|
| 268 |
+
"details": [
|
| 269 |
+
"**Guard ํ๋ธ**: `guardrails hub install hub://...`์ผ๋ก ์ปค๋ฎค๋ํฐ Guard๋ฅผ ์ค์นํฉ๋๋ค. ToxicLanguage, ValidJson, DetectPII, RegexMatch ๋ฑ ์์ญ ๊ฐ์ง๊ฐ ์์ต๋๋ค.",
|
| 270 |
+
"**on_fail ๋์**: `'exception'`(์์ธ ๋ฐ์), `'reask'`(LLM์ ์ฌ์์ฒญ), `'fix'`(์๋ ์์ ), `'noop'`(ํต๊ณผ) ์ค ์ ํํฉ๋๋ค.",
|
| 271 |
+
"**๊ตฌ์กฐํ ์ถ๋ ฅ**: `Guard.from_pydantic(OutputModel)`์ผ๋ก LLM์ด ํญ์ ์ง์ ํ ์คํค๋ง์ JSON์ ๋ฐํํ๋๋ก ๊ฐ์ ํ ์ ์์ต๋๋ค."
|
| 272 |
+
]
|
| 273 |
+
},
|
| 274 |
+
{
|
| 275 |
+
"id": "docs-gradio",
|
| 276 |
+
"certification": "Docs Study",
|
| 277 |
+
"title": "Gradio โ ML ๋ฐ๋ชจ UI",
|
| 278 |
+
"level": "์ค๊ธ",
|
| 279 |
+
"related_practices": ["docs-lab-22"],
|
| 280 |
+
"summary": "Gradio๋ ML ๋ชจ๋ธ ๋ฐ๋ชจ๋ฅผ ๋ช ์ค๋ก ๋ง๋๋ UI ๋ผ์ด๋ธ๋ฌ๋ฆฌ์
๋๋ค. `gr.Interface`๋ก ํจ์๋ฅผ ๊ฐ์ธ๋ฉด ์ฆ์ ์น UI๊ฐ ์๊ธฐ๊ณ , HuggingFace Spaces์ ๋ค์ดํฐ๋ธ ํตํฉ๋ฉ๋๋ค.",
|
| 281 |
+
"example": "import gradio as gr\n\ndef chat(message, history):\n response = chain.invoke(message)\n return response\n\ndemo = gr.ChatInterface(\n fn=chat,\n title='RAG ์ฑ๋ด',\n examples=['๋ฌธ์ ์์ฝํด์ค', '์ฃผ์ ํค์๋๋?']\n)\ndemo.launch()",
|
| 282 |
+
"common_mistake": "Streamlit๊ณผ ๋ฌ๋ฆฌ Gradio๋ ํจ์ ๋จ์๋ก UI๋ฅผ ์์ฑํฉ๋๋ค. ๋ณต์กํ ์ํ ๊ด๋ฆฌ๋ `gr.State()`๋ก, ์ฌ๋ฌ ์ปดํฌ๋ํธ๋ฅผ ์กฐํฉํ ๋๋ `gr.Blocks()` ์ปจํ
์คํธ๋ฅผ ์๋๋ค.",
|
| 283 |
+
"keywords": ["gradio", "Interface", "Blocks", "ChatInterface", "State", "HuggingFace", "demo"],
|
| 284 |
+
"source_id": "official-docs-gradio",
|
| 285 |
+
"details": [
|
| 286 |
+
"**Interface vs Blocks**: `gr.Interface`๋ ์
๋ ฅโํจ์โ์ถ๋ ฅ ๋จ์ ๊ตฌ์กฐ, `gr.Blocks`๋ ๋ ์ด์์๊ณผ ์ด๋ฒคํธ๋ฅผ ์์ ๋กญ๊ฒ ๊ตฌ์ฑ. LLM ์ฑ๋ด์๋ `gr.ChatInterface`๊ฐ ๊ฐ์ฅ ์ ํฉํฉ๋๋ค.",
|
| 287 |
+
"**์คํธ๋ฆฌ๋ฐ**: `gr.ChatInterface(fn=chat)`์์ `chat`์ generator ํจ์๋ก ๋ง๋ค๊ณ `yield`๋ก ํ ํฐ์ ๋ด๋ณด๋ด๋ฉด ์๋์ผ๋ก ์คํธ๋ฆฌ๋ฐ UI๊ฐ ๋ฉ๋๋ค.",
|
| 288 |
+
"**HF Spaces ํตํฉ**: `demo.launch()`๋ง ํ๋ฉด HF Spaces Gradio SDK๋ก ์ฆ์ ๋ฐฐํฌ๋ฉ๋๋ค. ๋ณ๋ ์๋ฒ ์ค์ ์์ด `sdk: gradio`๋ง README์ ์ ์ธํ๋ฉด ๋ฉ๋๋ค."
|
| 289 |
+
]
|
| 290 |
+
},
|
| 291 |
+
{
|
| 292 |
+
"id": "docs-chroma",
|
| 293 |
+
"certification": "Docs Study",
|
| 294 |
+
"title": "Chroma โ ์์ ๋ฒกํฐ DB",
|
| 295 |
+
"level": "์ค๊ธ",
|
| 296 |
+
"related_practices": ["docs-chroma-1", "docs-chroma-2"],
|
| 297 |
+
"summary": "Chroma๋ ์ฌ์์ํด๋ ๋ฐ์ดํฐ๊ฐ ์ ์ง๋๋ ์คํ์์ค ๋ฒกํฐ DB์
๋๋ค. FAISS๋ `save_local()`์ ์ง์ ํธ์ถํด์ผ ํ์ง๋ง, Chroma๋ `persist_directory`๋ง ์ง์ ํ๋ฉด ์๋์ผ๋ก ๋ก์ปฌ DB์ ์ ์ฅํฉ๋๋ค.",
|
| 298 |
+
"example": "from langchain_chroma import Chroma\n\n# ์์ฑ & ์๋ ์ ์ฅ\ndb = Chroma.from_documents(\n chunks,\n embeddings,\n persist_directory='./chroma_db'\n)\n\n# ๋ค์ ์คํ ์ โ ์๋ฒ ๋ฉ ์ฌ๊ณ์ฐ ์์ด ๋ก๋\ndb = Chroma(\n persist_directory='./chroma_db',\n embedding_function=embeddings\n)",
|
| 299 |
+
"common_mistake": "FAISS์ฒ๋ผ `save_local()`์ ๋ณ๋๋ก ํธ์ถํ ํ์๊ฐ ์์ต๋๋ค. `persist_directory`๋ฅผ ์ง์ ํ๋ฉด ์๋ ์ ์ฅ๋ฉ๋๋ค. ๋จ, `persist_directory`๋ฅผ ์๋ตํ๋ฉด ์ธ๋ฉ๋ชจ๋ฆฌ๋ก๋ง ๋์ํฉ๋๋ค.",
|
| 300 |
+
"keywords": ["Chroma", "persist_directory", "from_documents", "collection", "chromadb", "์์"],
|
| 301 |
+
"source_id": "official-docs-chromadb",
|
| 302 |
+
"details": [
|
| 303 |
+
"**FAISS vs Chroma**: FAISS๋ ์ธ๋ฉ๋ชจ๋ฆฌ ๊ธฐ๋ฐ์ผ๋ก `save_local()`๋ก ์๋ ์ ์ฅํด์ผ ํฉ๋๋ค. Chroma๋ `persist_directory`๋ง ์ง์ ํ๋ฉด SQLite ๊ธฐ๋ฐ ๋ก์ปฌ DB์ ์๋ ์ ์ฅ๋ฉ๋๋ค.",
|
| 304 |
+
"**์ปฌ๋ ์
**: Chroma๋ ๋ฐ์ดํฐ๋ฅผ ์ปฌ๋ ์
๋จ์๋ก ๊ด๋ฆฌํฉ๋๋ค. `collection_name` ํ๋ผ๋ฏธํฐ๋ก ์ฌ๋ฌ ๋ฌธ์ ์ธํธ๋ฅผ ๋ถ๋ฆฌํด ์ ์ฅํ๊ณ ๊ฐ๋ณ๋ก ๊ฒ์ํ ์ ์์ต๋๋ค.",
|
| 305 |
+
"**๋ฉํ๋ฐ์ดํฐ ํํฐ๋ง**: `db.similarity_search(query, filter={\"source\": \"file.pdf\"})`์ฒ๋ผ ๋ฉํ๋ฐ์ดํฐ ์กฐ๊ฑด์ผ๋ก ๊ฒ์ ๋ฒ์๋ฅผ ์ ํํ ์ ์์ต๋๋ค. FAISS๋ ์ง์ํ์ง ์๋ ๊ธฐ๋ฅ์
๋๋ค."
|
| 306 |
+
]
|
| 307 |
+
},
|
| 308 |
+
{
|
| 309 |
+
"id": "docs-sentence-transformers",
|
| 310 |
+
"certification": "Docs Study",
|
| 311 |
+
"title": "sentence-transformers โ ๋ก์ปฌ ์๋ฒ ๋ฉ",
|
| 312 |
+
"level": "์ค๊ธ",
|
| 313 |
+
"related_practices": ["docs-embed-1"],
|
| 314 |
+
"summary": "sentence-transformers๋ HuggingFace ์๋ฒ ๋ฉ ๋ชจ๋ธ์ ๋ก์ปฌ์์ ์คํํฉ๋๋ค. OpenAI API ์์ด ์์ ๋ก์ปฌ RAG๋ฅผ ๊ตฌ์ฑํ ์ ์๊ณ , ํ๊ตญ์ด ํนํ ๋ชจ๋ธ๋ ์ ํํ ์ ์์ต๋๋ค.",
|
| 315 |
+
"example": "from langchain_huggingface import HuggingFaceEmbeddings\n\nembeddings = HuggingFaceEmbeddings(\n model_name='sentence-transformers/all-MiniLM-L6-v2'\n)\n\n# ์๋ฒ ๋ฉ ๋ฒกํฐ ์์ฑ\nvector = embeddings.embed_query('ํ์ด์ฌ์ด ๋ญ์ผ?')\nprint(len(vector)) # 384์ฐจ์\n\n# Chroma์ ํจ๊ป\ndb = Chroma.from_documents(chunks, embeddings, persist_directory='./db')",
|
| 316 |
+
"common_mistake": "์ฒซ ์คํ ์ ๋ชจ๋ธ ํ์ผ์ ๋ค์ด๋ก๋ํ๋ฏ๋ก ๋๋ฆฝ๋๋ค. Streamlit ์ฑ์์๋ `@st.cache_resource`๋ก ๊ฐ์ธ ํ ๋ฒ๋ง ๋ก๋ํ์ธ์. ์๋ฒ ๋ฉ ๋ชจ๋ธ์ ์ค๊ฐ์ ๋ฐ๊พธ๋ฉด ๊ธฐ์กด VectorStore์ ํธํ๋์ง ์์ ์ ์ฒด ์ฌ์ธ๋ฑ์ฑ์ด ํ์ํฉ๋๋ค.",
|
| 317 |
+
"keywords": ["HuggingFaceEmbeddings", "sentence-transformers", "all-MiniLM-L6-v2", "embed_query", "๋ก์ปฌ ์๋ฒ ๋ฉ", "384์ฐจ์"],
|
| 318 |
+
"source_id": "official-docs-huggingface",
|
| 319 |
+
"details": [
|
| 320 |
+
"**๋ชจ๋ธ ์ ํ**: `all-MiniLM-L6-v2`๋ ๋น ๋ฅด๊ณ ๊ฒฝ๋(384์ฐจ์), `all-mpnet-base-v2`๋ ํ์ง์ด ๋ ๋์ง๋ง ๋๋ฆฝ๋๋ค. ํ๊ตญ์ด๊ฐ ๋ง๋ค๋ฉด `jhgan/ko-sroberta-multitask` ๊ฐ์ ํ๊ตญ์ด ํนํ ๋ชจ๋ธ์ ์๋๋ค.",
|
| 321 |
+
"**OpenAI vs ๋ก์ปฌ**: OpenAI `text-embedding-3-small`์ ํ์ง์ด ๋์ง๋ง API ๋น์ฉ์ด ๋ฐ์ํฉ๋๋ค. ๋ก์ปฌ ์๋ฒ ๋ฉ์ ๋ฌด๋ฃ์ด๋ GPU ์์ด๋ ๋์ฉ๋์์ ๋๋ฆฝ๋๋ค.",
|
| 322 |
+
"**์ฐจ์ ๊ณ ์ ์ฃผ์**: ํ ๋ฒ ์๋ฒ ๋ฉํ ๋ชจ๋ธ์ ๋ฐ๊พธ๋ฉด ๊ธฐ์กด ์ธ๋ฑ์ค์ ํธํ๋์ง ์์ต๋๋ค. ์ ๋ชจ๋ธ๋ก ์ ์ฒด ์ธ๋ฑ์ค๋ฅผ ์ฌ์์ฑํด์ผ ํฉ๋๋ค."
|
| 323 |
+
]
|
| 324 |
+
},
|
| 325 |
+
{
|
| 326 |
+
"id": "docs-ragas",
|
| 327 |
+
"certification": "Docs Study",
|
| 328 |
+
"title": "Ragas โ RAG ํ์ง ์๋ ํ๊ฐ",
|
| 329 |
+
"level": "์ค๊ธ",
|
| 330 |
+
"related_practices": ["docs-ragas-1", "docs-ragas-2"],
|
| 331 |
+
"summary": "Ragas๋ RAG ์์คํ
์ ํ์ง์ ์๋์ผ๋ก ์์นํํฉ๋๋ค. Faithfulness(ํ๊ฐ ์๋๊ฐ), Answer Relevancy(์ง๋ฌธ๊ณผ ๋ง๋ ๋ต์ธ๊ฐ), Context Precision(๊ด๋ จ ๋ฌธ์๋ฅผ ์ ์ฐพ์๋๊ฐ)์ LLM-as-judge๋ก ๊ณ์ฐํฉ๋๋ค.",
|
| 332 |
+
"example": "from ragas import evaluate\nfrom ragas.metrics import faithfulness, answer_relevancy, context_precision\nfrom datasets import Dataset\n\ndata = {\n 'question': ['LangChain์ด ๋ญ์ผ?'],\n 'answer': ['LangChain์ LLM ์ฑ ํ๋ ์์ํฌ์
๋๋ค.'],\n 'contexts': [['LangChain์ LLM ์ ํ๋ฆฌ์ผ์ด์
๊ฐ๋ฐ์ ์ํ ํ๋ ์์ํฌ์
๋๋ค.']],\n 'ground_truth': ['LangChain์ LLM ์ฑ ๊ฐ๋ฐ ํ๋ ์์ํฌ์
๋๋ค.']\n}\n\ndataset = Dataset.from_dict(data)\nresult = evaluate(dataset, metrics=[faithfulness, answer_relevancy, context_precision])\nprint(result)",
|
| 333 |
+
"common_mistake": "Ragas๋ ํ๊ฐ์ LLM์ ์ฌ์ฉํฉ๋๋ค. ๊ธฐ๋ณธ์ผ๋ก OpenAI GPT๋ฅผ ์๋๋ค. `evaluate(..., llm=your_llm, embeddings=your_embeddings)`๋ก ๋ค๋ฅธ ๋ชจ๋ธ์ ์ง์ ํ ์ ์์ต๋๋ค.",
|
| 334 |
+
"keywords": ["ragas", "evaluate", "faithfulness", "answer_relevancy", "context_precision", "LLM-as-judge", "Dataset"],
|
| 335 |
+
"source_id": "official-docs-ragas",
|
| 336 |
+
"details": [
|
| 337 |
+
"**3๊ฐ์ง ํต์ฌ ๋ฉํธ๋ฆญ**: Faithfulness(๋ต๋ณ์ด ๊ฒ์๋ ์ปจํ
์คํธ์ ๊ทผ๊ฑฐํ๋๊ฐ โ ํ๊ฐ ํ์ง), Answer Relevancy(๋ต๋ณ์ด ์ง๋ฌธ๊ณผ ๊ด๋ จ ์๋๊ฐ), Context Precision(๊ด๋ จ ๋ฌธ์๊ฐ ์์ k๊ฐ ์์ ์๋๊ฐ).",
|
| 338 |
+
"**MLflow ์ฐ๋**: `result.to_pandas()`๋ก DataFrame ๋ณํ ํ `mlflow.log_metrics()`๋ก ๊ธฐ๋กํ๋ฉด chunk_size, k ํ๋ผ๋ฏธํฐ๋ณ ํ์ง ๋ณํ๋ฅผ ์ถ์ ํ ์ ์์ต๋๋ค.",
|
| 339 |
+
"**ground_truth ์์ด๋ ๊ฐ๋ฅ**: `ground_truth`๊ฐ ์์ผ๋ฉด faithfulness, answer_relevancy๋ง ๊ณ์ฐํฉ๋๋ค. Answer Correctness ๋ฉํธ๋ฆญ์ ground_truth๊ฐ ํ์ํฉ๋๋ค."
|
| 340 |
+
]
|
| 341 |
+
},
|
| 342 |
+
{
|
| 343 |
+
"id": "docs-summarization",
|
| 344 |
+
"certification": "Docs Study",
|
| 345 |
+
"title": "LangChain ์์ฝ ์ฒด์ธ โ map_reduce & stuff",
|
| 346 |
+
"level": "์ค๊ธ",
|
| 347 |
+
"related_practices": ["docs-news-1", "docs-news-2"],
|
| 348 |
+
"summary": "LangChain์ `load_summarize_chain`์ ๊ธด ๋ฌธ์๋ฅผ LLM ์ปจํ
์คํธ ํ๊ณ ๋ด์์ ์์ฝํ๋ ์ฒด์ธ์ ๋ง๋ญ๋๋ค. ๋ฌธ์๊ฐ ์งง์ผ๋ฉด `stuff`, ๊ธธ๋ฉด `map_reduce` ๋ฐฉ์์ ์๋๋ค.",
|
| 349 |
+
"example": "from langchain.chains.summarize import load_summarize_chain\nfrom langchain_core.documents import Document\n\n# map_reduce: ๊ฐ ์ฒญํฌ ์์ฝ โ ์ต์ข
์์ฝ\nchain = load_summarize_chain(llm, chain_type='map_reduce')\n\ndocs = [Document(page_content=article) for article in articles]\nresult = chain.invoke(docs)\nprint(result['output_text'])",
|
| 350 |
+
"common_mistake": "`stuff` ๋ฐฉ์์ ๋ชจ๋ ๋ฌธ์๋ฅผ ํ๋์ ํ๋กฌํํธ์ ๋ฃ์ต๋๋ค. ๋ฌธ์๊ฐ LLM ์ปจํ
์คํธ ์ฐฝ๋ณด๋ค ํฌ๋ฉด ์ค๋ฅ๊ฐ ๋ฉ๋๋ค. ์ฌ๋ฌ ๋ฌธ์๋ ๊ธด ๋ฌธ์๋ ํญ์ `map_reduce`๋ฅผ ๋จผ์ ๊ณ ๋ คํ์ธ์.",
|
| 351 |
+
"keywords": ["load_summarize_chain", "map_reduce", "stuff", "refine", "output_text", "์์ฝ"],
|
| 352 |
+
"source_id": "official-docs-langchain",
|
| 353 |
+
"details": [
|
| 354 |
+
"**chain_type ๋น๊ต**: `stuff`(์ ์ฒด ํ ๋ฒ), `map_reduce`(์ฒญํฌ๋ณ ์์ฝ ํ ํฉ์นจ), `refine`(์ด์ ์์ฝ์ ๋ค์ ์ฒญํฌ์ ๋ฐ์). ํ์ง์ refine > map_reduce > stuff์ด์ง๋ง ์๋๋ ๋ฐ๋์
๋๋ค.",
|
| 355 |
+
"**map_prompt / combine_prompt**: `load_summarize_chain`์ `map_prompt`์ `combine_prompt`๋ฅผ ์ง์ ํด ์์ฝ ์ง์๋ฌธ์ ์ปค์คํฐ๋ง์ด์งํ ์ ์์ต๋๋ค.",
|
| 356 |
+
"**๋น๋๊ธฐ**: `chain.ainvoke(docs)`๋ก ๋น๋๊ธฐ ์์ฒญ์ด ๊ฐ๋ฅํฉ๋๋ค. ์ฌ๋ฌ ๋ด์ค ๊ธฐ์ฌ๋ฅผ ๋ณ๋ ฌ ์์ฝํ ๋ `asyncio.gather`์ ํจ๊ป ์ฐ๋ฉด ์๋๊ฐ ํฌ๊ฒ ๊ฐ์ ๋ฉ๋๋ค."
|
| 357 |
+
]
|
| 358 |
+
},
|
| 359 |
+
{
|
| 360 |
+
"id": "docs-sql-chain",
|
| 361 |
+
"certification": "Docs Study",
|
| 362 |
+
"title": "LangChain Text-to-SQL โ ์์ฐ์ด๋ก DB ์กฐํ",
|
| 363 |
+
"level": "์ค๊ธ",
|
| 364 |
+
"related_practices": ["docs-sql-1", "docs-sql-2"],
|
| 365 |
+
"summary": "LangChain์ `create_sql_query_chain`์ ์์ฐ์ด ์ง๋ฌธ์ SQL ์ฟผ๋ฆฌ๋ก ๋ณํํฉ๋๋ค. `SQLDatabase`๋ก DB ์คํค๋ง๋ฅผ ์๋์ผ๋ก ์ฝ์ด LLM์๊ฒ ์ปจํ
์คํธ๋ฅผ ์ ๊ณตํฉ๋๋ค.",
|
| 366 |
+
"example": "from langchain_community.utilities import SQLDatabase\nfrom langchain.chains import create_sql_query_chain\n\ndb = SQLDatabase.from_uri('sqlite:///./mydb.db')\nchain = create_sql_query_chain(llm, db)\n\nsql = chain.invoke({'question': '๊ฐ์ฅ ๋ง์ด ํ๋ฆฐ ์ํ 5๊ฐ๋?'})\nprint(sql) # SELECT product, SUM(quantity) ...\n\nresult = db.run(sql)\nprint(result)",
|
| 367 |
+
"common_mistake": "LLM์ด ์์ฑํ SQL์ ๋ฐ๋ก `db.run()`์ ๋๊ธฐ๋ฉด ์๋ชป๋ ์ฟผ๋ฆฌ๊ฐ ์คํ๋ฉ๋๋ค. Guardrails์ `ValidSQL`์ด๋ ๋ณ๋ ํ์ฑ์ผ๋ก ๊ฒ์ฆํ ๋ค ์คํํ์ธ์.",
|
| 368 |
+
"keywords": ["SQLDatabase", "create_sql_query_chain", "from_uri", "db.run", "Text-to-SQL", "sqlite"],
|
| 369 |
+
"source_id": "official-docs-langchain",
|
| 370 |
+
"details": [
|
| 371 |
+
"**์คํค๋ง ์๋ ์ฃผ์
**: `SQLDatabase`๋ ์ฐ๊ฒฐ๋ DB์ ํ
์ด๋ธ๋ช
๊ณผ ์ปฌ๋ผ ์ ๋ณด๋ฅผ ์๋์ผ๋ก ํ๋กฌํํธ์ ์ฃผ์
ํฉ๋๋ค. LLM์ด ์กด์ฌํ๋ ํ
์ด๋ธ/์ปฌ๋ผ๋ง ์ฐธ์กฐํ๋๋ก ์ ๋ํฉ๋๋ค.",
|
| 372 |
+
"**QuerySQLDatabaseTool**: SQL ์์ฑ๊ณผ ์คํ์ ํ๋์ ํด๋ก ๋ฌถ์ ๊ณ ์์ค ์ธํฐํ์ด์ค. Agent์ ๋ฑ๋กํ๋ฉด LLM์ด ํ์ํ ๋ DB๋ฅผ ์ง์ ์กฐํํ ์ ์์ต๋๋ค.",
|
| 373 |
+
"**๋ณด์ ์ฃผ์**: `db.run()`์ ์ค์ DB๋ฅผ ์์ ํ ์ ์์ต๋๋ค. ์ฝ๊ธฐ ์ ์ฉ ์ฌ์ฉ์ ๊ณ์ ์ผ๋ก ์ฐ๊ฒฐํ๊ฑฐ๋ SELECT๋ง ํ์ฉํ๋ wrapper๋ฅผ ๋๋ ๊ฒ์ด ์์ ํฉ๋๋ค."
|
| 374 |
+
]
|
| 375 |
+
},
|
| 376 |
+
{
|
| 377 |
+
"id": "docs-langgraph",
|
| 378 |
+
"certification": "Docs Study",
|
| 379 |
+
"title": "LangGraph โ ์ํ ๊ธฐ๋ฐ ์์ด์ ํธ ์ํฌํ๋ก",
|
| 380 |
+
"level": "๊ณ ๊ธ",
|
| 381 |
+
"related_practices": ["docs-graph-1", "docs-graph-2"],
|
| 382 |
+
"summary": "LangGraph๋ LLM ์์ด์ ํธ๋ฅผ ๊ทธ๋ํ(๋
ธ๋ + ์ฃ์ง)๋ก ์ ์ํฉ๋๋ค. ๋จ์ ์ฒด์ธ์ AโBโC์ ๋ฌ๋ฆฌ ์กฐ๊ฑด ๋ถ๊ธฐ, ๋ฃจํ, ๋ณ๋ ฌ ์คํ์ด ๊ฐ๋ฅํด ์ค์ ์์ด์ ํธ ํ๋์ ํํํฉ๋๋ค.",
|
| 383 |
+
"example": "from langgraph.graph import StateGraph, END\nfrom typing import TypedDict\n\nclass State(TypedDict):\n question: str\n answer: str\n\ndef retrieve(state: State) -> State:\n return {\"answer\": str(retriever.invoke(state[\"question\"]))}\n\ndef generate(state: State) -> State:\n return {\"answer\": chain.invoke(state)}\n\ngraph = StateGraph(State)\ngraph.add_node(\"retrieve\", retrieve)\ngraph.add_node(\"generate\", generate)\ngraph.set_entry_point(\"retrieve\")\ngraph.add_edge(\"retrieve\", \"generate\")\ngraph.add_edge(\"generate\", END)\n\napp = graph.compile()\nresult = app.invoke({\"question\": \"LangChain์ด ๋ญ์ผ?\"})",
|
| 384 |
+
"common_mistake": "LangGraph๋ LangChain ์ฒด์ธ์ด ์๋๋๋ค. `graph.compile()` ํ `app.invoke()`๋ฅผ ์๋๋ค. State TypedDict๋ฅผ ์ ํํ ์ ์ํ์ง ์์ผ๋ฉด ๋
ธ๋์์ ํค ์ค๋ฅ๊ฐ ๋ฐ์ํฉ๋๋ค.",
|
| 385 |
+
"keywords": ["LangGraph", "StateGraph", "State", "node", "edge", "compile", "conditional_edges", "END"],
|
| 386 |
+
"source_id": "official-docs-langgraph",
|
| 387 |
+
"details": [
|
| 388 |
+
"**๋
ธ๋ vs ์ฒด์ธ**: ์ฒด์ธ์ AโBโC ์ ํ. ๊ทธ๋ํ๋ A์์ ์กฐ๊ฑด์ ๋ฐ๋ผ B ๋๋ C๋ก ๋ถ๊ธฐ, D์์ A๋ก ๋ฃจํ ๋ฑ ๋ณต์กํ ํ๋ฆ์ ํํํ ์ ์์ต๋๋ค.",
|
| 389 |
+
"**conditional_edges**: `graph.add_conditional_edges('judge', router_fn, {'retry': 'retrieve', 'done': END})`์ฒ๋ผ ๋
ธ๋ ๋ฐํ๊ฐ์ ๋ฐ๋ผ ๋ค์ ๋
ธ๋๋ฅผ ๋์ ์ผ๋ก ๊ฒฐ์ ํฉ๋๋ค. ReAct ์์ด์ ํธ์ ํต์ฌ์
๋๋ค.",
|
| 390 |
+
"**checkpointer**: `MemorySaver`๋ฅผ `graph.compile(checkpointer=...)`์ ๋๊ธฐ๋ฉด ์คํ ์ํ๋ฅผ ์ ์ฅํด ์ค๋จ ํ ์ฌ๊ฐ, ๋ฉํฐํด ๋ํ ์ ์ง๊ฐ ๊ฐ๋ฅํฉ๋๋ค."
|
| 391 |
+
]
|
| 392 |
+
},
|
| 393 |
+
{
|
| 394 |
+
"id": "docs-airflow",
|
| 395 |
+
"certification": "Docs Study",
|
| 396 |
+
"title": "Apache Airflow โ ์ํฌํ๋ก ์ค์ผ์คํธ๋ ์ด์
",
|
| 397 |
+
"level": "๊ณ ๊ธ",
|
| 398 |
+
"related_practices": ["docs-lab-23"],
|
| 399 |
+
"summary": "Airflow๋ DAG(Directed Acyclic Graph)๋ก ๋ฐ์ดํฐ ํ์ดํ๋ผ์ธ์ ์ ์ํ๊ณ ์ค์ผ์ค๋งยท๋ชจ๋ํฐ๋งํฉ๋๋ค. ML ํ์ดํ๋ผ์ธ(๋ฐ์ดํฐ ์์ง โ ์ ์ฒ๋ฆฌ โ ํ์ต โ ๋ฐฐํฌ)์ด๋ ๋ฌธ์ ์ฌ์ธ๋ฑ์ฑ ์๋ํ์ ์๋๋ค.",
|
| 400 |
+
"example": "from airflow import DAG\nfrom airflow.operators.python import PythonOperator\nfrom datetime import datetime\n\ndef reindex():\n # ๋ฌธ์ ๋ก๋ โ ์๋ฒ ๋ฉ โ VectorStore ์
๋ฐ์ดํธ\n pass\n\nwith DAG('daily_reindex', schedule='@daily', start_date=datetime(2024,1,1)) as dag:\n task = PythonOperator(task_id='reindex', python_callable=reindex)",
|
| 401 |
+
"common_mistake": "DAG ํ์ผ์ Airflow ์ค์ผ์ค๋ฌ๊ฐ ์ฃผ๊ธฐ์ ์ผ๋ก ํ์ฑํฉ๋๋ค. ํ์ผ ์ต์์์ ๋ฌด๊ฑฐ์ด ์ฐ์ฐ(DB ์ฐ๊ฒฐ, ๋ชจ๋ธ ๋ก๋)์ ๋๋ฉด ํ์ฑ๋ง๋ค ์คํ๋ผ ์ค์ผ์ค๋ฌ๊ฐ ๋๋ ค์ง๋๋ค. ๋ฐ๋์ task ํจ์ ์์ ๋ฃ์ผ์ธ์.",
|
| 402 |
+
"keywords": ["airflow", "DAG", "task", "operator", "schedule", "XCom", "pipeline", "orchestration"],
|
| 403 |
+
"source_id": "official-docs-airflow",
|
| 404 |
+
"details": [
|
| 405 |
+
"**Operator ์ข
๋ฅ**: `PythonOperator`(ํ์ด์ฌ ํจ์), `BashOperator`(์
ธ ๋ช
๋ น), `DockerOperator`(์ปจํ
์ด๋ ์คํ) ๋ฑ. ML ํ์ดํ๋ผ์ธ์ ์ฃผ๋ก PythonOperator๋ฅผ ์๋๋ค.",
|
| 406 |
+
"**XCom**: task ๊ฐ ๋ฐ์ดํฐ ์ ๋ฌ ๋ฉ์ปค๋์ฆ. `ti.xcom_push(key, value)` / `ti.xcom_pull(task_ids, key)`๋ก ์๋ ๋ฐ์ดํฐ๋ฅผ ๊ณต์ ํฉ๋๋ค. ๋์ฉ๋์ S3/GCS ๊ฒฝ๋ก๋ฅผ ์ ๋ฌํ๋ ๋ฐฉ์์ ์๋๋ค.",
|
| 407 |
+
"**์์กด์ฑ**: `task_a >> task_b >> task_c` ๋๋ `task_a.set_downstream(task_b)` ๋ก ์คํ ์์๋ฅผ ์ ์ํฉ๋๋ค. ๋ณ๋ ฌ ์คํ์ `[task_b, task_c] >> task_d` ํํ๋ก ํํํฉ๋๋ค."
|
| 408 |
+
]
|
| 409 |
+
},
|
| 410 |
+
{
|
| 411 |
+
"id": "docs-mlflow",
|
| 412 |
+
"certification": "Docs Study",
|
| 413 |
+
"title": "MLflow โ ์คํ ์ถ์ & ๋ชจ๋ธ ๊ด๋ฆฌ",
|
| 414 |
+
"level": "๊ณ ๊ธ",
|
| 415 |
+
"related_practices": ["docs-lab-15"],
|
| 416 |
+
"summary": "MLflow๋ ML ์คํ์ ํ๋ผ๋ฏธํฐ, ๋ฉํธ๋ฆญ, ์ํฐํฉํธ๋ฅผ ์ถ์ ํ๊ณ ๋ชจ๋ธ์ ๋ฒ์ ๊ด๋ฆฌํฉ๋๋ค. RAG์์ chunk_size, k, ์๋ฒ ๋ฉ ๋ชจ๋ธ ๋ฑ ํ๋ผ๋ฏธํฐ ์คํ ๊ฒฐ๊ณผ๋ฅผ ์ฒด๊ณ์ ์ผ๋ก ๋น๊ตํ ๋ ์๋๋ค.",
|
| 417 |
+
"example": "import mlflow\n\nwith mlflow.start_run(run_name='rag-exp-1'):\n mlflow.log_param('chunk_size', 500)\n mlflow.log_param('k', 4)\n mlflow.log_metric('answer_relevance', 0.87)\n mlflow.log_metric('faithfulness', 0.92)\n mlflow.log_artifact('eval_results.json')",
|
| 418 |
+
"common_mistake": "run์ `with mlflow.start_run()` ๋ธ๋ก์ผ๋ก ๊ฐ์ธ์ง ์์ผ๋ฉด ์ค์๋ก ์ด์ run์ ๋ก๊น
๋๋ ๊ฒฝ์ฐ๊ฐ ์์ต๋๋ค. ํญ์ context manager๋ฅผ ์ฌ์ฉํ์ธ์.",
|
| 419 |
+
"keywords": ["mlflow", "experiment", "run", "log_param", "log_metric", "artifact", "model registry"],
|
| 420 |
+
"source_id": "official-docs-mlflow",
|
| 421 |
+
"details": [
|
| 422 |
+
"**UI**: `mlflow ui` ๋ช
๋ น์ผ๋ก localhost:5000์์ ์คํ ๋น๊ต ๋์๋ณด๋๋ฅผ ์คํํฉ๋๋ค. ํ๋ผ๋ฏธํฐ๋ณ ๋ฉํธ๋ฆญ ์ถ์ด๋ฅผ ์๊ฐ์ ์ผ๋ก ๋น๊ตํ ์ ์์ต๋๋ค.",
|
| 423 |
+
"**Model Registry**: `mlflow.log_model()`๋ก ๋ชจ๋ธ์ ์ ์ฅํ๊ณ `Staging`โ`Production` ๋จ๊ณ๋ฅผ ๊ด๋ฆฌํฉ๋๋ค. ๋ฐฐํฌ ์ `mlflow.pyfunc.load_model('models:/name/Production')`์ผ๋ก ๋ก๋ํฉ๋๋ค.",
|
| 424 |
+
"**LangChain ํตํฉ**: `mlflow.langchain.autolog()`๋ฅผ ํ์ฑํํ๋ฉด ์ฒด์ธ ์คํ๋ง๋ค ํ๋ผ๋ฏธํฐ์ ๋ฉํธ๋ฆญ์ด ์๋ ๊ธฐ๋ก๋ฉ๋๋ค."
|
| 425 |
+
]
|
| 426 |
+
},
|
| 427 |
+
{
|
| 428 |
+
"id": "docs-mcp",
|
| 429 |
+
"certification": "Docs Study",
|
| 430 |
+
"title": "MCP โ Model Context Protocol",
|
| 431 |
+
"level": "๊ณ ๊ธ",
|
| 432 |
+
"related_practices": ["docs-lab-24"],
|
| 433 |
+
"summary": "MCP(Model Context Protocol)๋ LLM ์ ํ๋ฆฌ์ผ์ด์
์ด ์ธ๋ถ ๋๊ตฌยท๋ฐ์ดํฐ์์ค์ ํ์คํ๋ ๋ฐฉ์์ผ๋ก ์ฐ๊ฒฐํ๋ Anthropic ์คํ ํ๋กํ ์ฝ์
๋๋ค. Claude Desktop์ด๋ Claude Code์ ๋ก์ปฌ MCP ์๋ฒ๋ฅผ ์ฐ๊ฒฐํ๋ฉด ํ์ผ ์์คํ
, DB, ์ธ๋ถ API๋ฅผ LLM์ด ์ง์ ์ฌ์ฉํ ์ ์์ต๋๋ค.",
|
| 434 |
+
"example": "# mcp_server.py (FastMCP ์ฌ์ฉ)\nfrom mcp.server.fastmcp import FastMCP\n\nmcp = FastMCP('my-server')\n\n@mcp.tool()\ndef search_docs(query: str) -> str:\n '''๋ฒกํฐ DB์์ ๊ด๋ จ ๋ฌธ์๋ฅผ ๊ฒ์ํฉ๋๋ค.'''\n results = retriever.invoke(query)\n return '\\n'.join(r.page_content for r in results)\n\nmcp.run(transport='stdio')",
|
| 435 |
+
"common_mistake": "MCP ์๋ฒ๋ stdio ๋๋ SSE transport ์ค ํ๋๋ฅผ ์ ํํฉ๋๋ค. Claude Desktop์ stdio(๋ก์ปฌ ํ๋ก์ธ์ค), Claude Code๋ SSE(HTTP ์๋ฒ) ๋ฐฉ์์ ์ฃผ๋ก ์๋๋ค. transport ๋ถ์ผ์น ์ ์ฐ๊ฒฐ์ด ์ ๋ฉ๋๋ค.",
|
| 436 |
+
"keywords": ["MCP", "Model Context Protocol", "tool", "resource", "FastMCP", "stdio", "Claude", "agent"],
|
| 437 |
+
"source_id": "official-docs-mcp",
|
| 438 |
+
"details": [
|
| 439 |
+
"**3๊ฐ์ง ๊ธฐ๋ณธ ์์**: `tool`(LLM์ด ํธ์ถํ๋ ํจ์), `resource`(LLM์ด ์ฝ๋ ๋ฐ์ดํฐ), `prompt`(์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ํ๋กฌํํธ ํ
ํ๋ฆฟ). ๋๋ถ๋ถ์ ์๋ฒ๋ `tool`๋ง ๊ตฌํํฉ๋๋ค.",
|
| 440 |
+
"**Claude Desktop ์ฐ๊ฒฐ**: `~/Library/Application Support/Claude/claude_desktop_config.json`์ ์๋ฒ ๊ฒฝ๋ก์ ๋ช
๋ น์ด๋ฅผ ๋ฑ๋กํ๋ฉด ๋ํ ์ค ์๋์ผ๋ก ๋๊ตฌ๊ฐ ๋ณด์
๋๋ค.",
|
| 441 |
+
"**FastMCP**: Anthropic ๊ณต์ Python SDK์ ๊ณ ์์ค ๋ํผ. `@mcp.tool()` ๋ฐ์ฝ๋ ์ดํฐ๋ก ํจ์๋ฅผ ๋๊ตฌ๋ก ๋ฑ๋กํ๋ฉด ์คํค๋ง ์์ฑ, ์
์ถ๋ ฅ ๊ฒ์ฆ์ด ์๋์ผ๋ก ์ฒ๋ฆฌ๋ฉ๋๋ค."
|
| 442 |
+
]
|
| 443 |
+
},
|
| 444 |
+
{
|
| 445 |
+
"id": "docs-litellm",
|
| 446 |
+
"certification": "Docs Study",
|
| 447 |
+
"title": "LiteLLM โ ์ฌ๋ฌ LLM์ ํ๋์ ์ธํฐํ์ด์ค๋ก",
|
| 448 |
+
"level": "๊ณ ๊ธ",
|
| 449 |
+
"related_practices": ["docs-litellm-1"],
|
| 450 |
+
"summary": "LiteLLM์ OpenAI, Anthropic, Ollama, Gemini ๋ฑ 100๊ฐ ์ด์์ LLM ํ๋ก๋ฐ์ด๋๋ฅผ ๋์ผํ API ํ์์ผ๋ก ํธ์ถํฉ๋๋ค. ๋ชจ๋ธ์ ๋ฐ๊ฟ ๋ ์ฝ๋ ์์ ์์ด ๋ชจ๋ธ๋ช
๋ง ๋ณ๊ฒฝํ๋ฉด ๋ฉ๋๋ค.",
|
| 451 |
+
"example": "from litellm import completion\n\n# Ollama ๋ก์ปฌ\nresponse = completion(\n model='ollama/llama3.2',\n messages=[{'role': 'user', 'content': '์๋
'}]\n)\n\n# OpenAI โ ์ฝ๋ ๋์ผ, ๋ชจ๋ธ๋ช
๋ง ๋ณ๊ฒฝ\nresponse = completion(\n model='gpt-4o-mini',\n messages=[{'role': 'user', 'content': '์๋
'}]\n)\n\nprint(response.choices[0].message.content)",
|
| 452 |
+
"common_mistake": "๋ชจ๋ธ๋ช
ํ์์ `'ํ๋ก๋ฐ์ด๋/๋ชจ๋ธ๋ช
'`์
๋๋ค. Ollama๋ `'ollama/llama3.2'`, Anthropic์ `'anthropic/claude-3-5-sonnet-20241022'`. OpenAI๋ง ์์ธ๋ก ์ ๋์ฌ ์์ด `'gpt-4o-mini'`์ฒ๋ผ ์๋๋ค.",
|
| 453 |
+
"keywords": ["LiteLLM", "completion", "model", "provider", "๋ฒค๋ ๋
๋ฆฝ", "OpenAI ํธํ", "ChatLiteLLM"],
|
| 454 |
+
"source_id": "official-docs-litellm",
|
| 455 |
+
"details": [
|
| 456 |
+
"**๋น์ฉ ์ถ์ **: `litellm.success_callback`์ผ๋ก ๊ฐ ํธ์ถ์ ํ ํฐ ์์ ์์ ๋น์ฉ์ ์๋ ๊ธฐ๋กํ ์ ์์ต๋๋ค. ์ฌ๋ฌ ๋ชจ๋ธ์ ์คํํ ๋ ๋น์ฉ ๋น๊ต์ ์ ์ฉํฉ๋๋ค.",
|
| 457 |
+
"**LangChain ํตํฉ**: `from langchain_community.chat_models import ChatLiteLLM`์ผ๋ก LangChain ์ฒด์ธ์์ LiteLLM์ ์๋๋ค. LCEL ํ์ดํ๋ผ์ธ์ ๋ฐ๋ก ์ฐ๊ฒฐ๋ฉ๋๋ค.",
|
| 458 |
+
"**Fallback**: `completion(..., fallbacks=['gpt-4o-mini', 'ollama/llama3.2'])`์ฒ๋ผ ์ฃผ ๋ชจ๋ธ ์คํจ ์ ์๋์ผ๋ก ๋ฐฑ์
๋ชจ๋ธ๋ก ์ ํํ๋ ๊ธฐ๋ฅ์ ์ง์ํฉ๋๋ค."
|
| 459 |
+
]
|
| 460 |
+
},
|
| 461 |
+
{
|
| 462 |
+
"id": "docs-chainlit",
|
| 463 |
+
"certification": "Docs Study",
|
| 464 |
+
"title": "Chainlit โ ์ฑ๋ด UI ํนํ ํ๋ ์์ํฌ",
|
| 465 |
+
"level": "๏ฟฝ๏ฟฝ๏ฟฝ๊ธ",
|
| 466 |
+
"related_practices": ["docs-chainlit-1"],
|
| 467 |
+
"summary": "Chainlit์ LLM ์ฑ๋ด UI์ ํนํ๋ ํ๋ ์์ํฌ์
๋๋ค. Streamlit๊ณผ ๋ฌ๋ฆฌ ์น์์ผ ๊ธฐ๋ฐ์ผ๋ก ๋์ํด ์คํธ๋ฆฌ๋ฐ ์๋ต, ํ์ผ ์
๋ก๋, ๋ฉํฐ์คํ
์งํ ํ์๊ฐ ์์ฐ์ค๋ฝ์ต๋๋ค.",
|
| 468 |
+
"example": "import chainlit as cl\n\n@cl.on_message\nasync def main(message: cl.Message):\n # ์คํธ๋ฆฌ๋ฐ ์๋ต\n msg = cl.Message(content='')\n async for chunk in chain.astream({'question': message.content}):\n await msg.stream_token(chunk)\n await msg.send()\n\n# ์คํ: chainlit run app.py",
|
| 469 |
+
"common_mistake": "Chainlit์ `async` ๊ธฐ๋ฐ์
๋๋ค. LangChain์ `chain.invoke()`(๋๊ธฐ)๋ฅผ ์ฐ๋ฉด ์ด๋ฒคํธ ๋ฃจํ๊ฐ ๋ธ๋กํน๋ฉ๋๋ค. ๋ฐ๋์ `chain.ainvoke()` ๋๋ `chain.astream()`์ ์ฌ์ฉํ์ธ์.",
|
| 470 |
+
"keywords": ["chainlit", "on_message", "Message", "stream_token", "async", "astream", "on_chat_start"],
|
| 471 |
+
"source_id": "official-docs-chainlit",
|
| 472 |
+
"details": [
|
| 473 |
+
"**๋ฐ์ฝ๋ ์ดํฐ ๊ธฐ๋ฐ**: `@cl.on_chat_start`(์ธ์
์์ ์ ์ฒด์ธ ์ด๊ธฐํ), `@cl.on_message`(๋ฉ์์ง ์์ ), `@cl.on_stop`(์คํธ๋ฆฌ๋ฐ ์ค๋จ)์ผ๋ก ์ด๋ฒคํธ๋ฅผ ์ฒ๋ฆฌํฉ๋๋ค.",
|
| 474 |
+
"**Step UI**: `async with cl.Step(name='๊ฒ์ ์ค...'):` ๋ธ๋ก์ผ๋ก ์์ด์ ํธ์ ๊ฐ ๋จ๊ณ(๊ฒ์, ์ถ๋ก ๋ฑ)๋ฅผ UI์ ์ค์๊ฐ์ผ๋ก ํผ์ณ ๋ณด์ฌ์ค๋๋ค. LangGraph ์์ด์ ํธ์ ํจ๊ป ์ฐ๋ฉด ๊ฐ๋ ฅํฉ๋๋ค.",
|
| 475 |
+
"**ํ์ผ ์
๋ก๋**: `@cl.on_message`์์ `message.elements`๋ก ์ฒจ๋ถ ํ์ผ์ ๋ฐ์ ์ ์์ต๋๋ค. PDF ์
๋ก๋ โ ์ฆ์ RAG ์ธ๋ฑ์ฑ ํ๋ฆ์ ๋ช ์ค๋ก ๊ตฌํํฉ๋๋ค."
|
| 476 |
+
]
|
| 477 |
+
},
|
| 478 |
+
{
|
| 479 |
+
"id": "docs-redis",
|
| 480 |
+
"certification": "Docs Study",
|
| 481 |
+
"title": "Redis โ ๋ํ ๋ฉ๋ชจ๋ฆฌ ์์ํ & LLM ์บ์ฑ",
|
| 482 |
+
"level": "๊ณ ๊ธ",
|
| 483 |
+
"related_practices": ["docs-redis-1"],
|
| 484 |
+
"summary": "Redis๋ ์ธ๋ฉ๋ชจ๋ฆฌ ๋ฐ์ดํฐ ์ ์ฅ์๋ก LLM ์ฑ์์ ๋ํ ํ์คํ ๋ฆฌ ์์ํ์ LLM ์๋ต ์บ์ฑ์ ์๋๋ค. ์๋ฒ๋ฅผ ์ฌ์์ํด๋ ๋ํ๊ฐ ์ ์ง๋๊ณ , ๋์ผ ์ง๋ฌธ์ ๋ํ LLM ํธ์ถ ๋น์ฉ์ ์ ๊ฐํฉ๋๋ค.",
|
| 485 |
+
"example": "from langchain_community.chat_message_histories import RedisChatMessageHistory\nfrom langchain_core.runnables.history import RunnableWithMessageHistory\n\ndef get_session_history(session_id: str):\n return RedisChatMessageHistory(\n session_id=session_id,\n url='redis://localhost:6379'\n )\n\nchain_with_history = RunnableWithMessageHistory(\n chain,\n get_session_history,\n input_messages_key='question',\n history_messages_key='chat_history'\n)",
|
| 486 |
+
"common_mistake": "Redis ์๋ฒ๊ฐ ์คํ ์ค์ด์ง ์์ผ๋ฉด ์ฐ๊ฒฐ ์ค๋ฅ๊ฐ ๋ฉ๋๋ค. ๋ก์ปฌ ๊ฐ๋ฐ ์ `docker run -d -p 6379:6379 redis`๋ก ๋จผ์ Redis๋ฅผ ์คํํ์ธ์.",
|
| 487 |
+
"keywords": ["Redis", "RedisChatMessageHistory", "session_id", "url", "์์ํ", "์บ์ฑ", "TTL"],
|
| 488 |
+
"source_id": "official-docs-redis",
|
| 489 |
+
"details": [
|
| 490 |
+
"**์ธ๋ฉ๋ชจ๋ฆฌ ๊ต์ฒด**: ๊ธฐ์กด `ChatMessageHistory`(์ฌ์์ ์ ์๋ฉธ)๋ฅผ `RedisChatMessageHistory`๋ก ๊ต์ฒดํ๋ฉด `get_session_history` ํจ์ ํ ์ค๋ง ๋ฐ๊ฟ๋ ์์์ฑ์ ์ป์ต๋๋ค.",
|
| 491 |
+
"**TTL**: `RedisChatMessageHistory(session_id, url, ttl=3600)`์ผ๋ก 1์๊ฐ ํ ์๋ ๋ง๋ฃ๋ฉ๋๋ค. ๋ฌดํํ ์์ด๋ ํ์คํ ๋ฆฌ์ ๋ฉ๋ชจ๋ฆฌ ๋์๋ฅผ ๋ฐฉ์งํฉ๋๋ค.",
|
| 492 |
+
"**LLM ์๋ต ์บ์ฑ**: `from langchain.cache import RedisCache; langchain.llm_cache = RedisCache(redis_client)`๋ก ๋์ผ ์ง๋ฌธ์ ๋ํ LLM ์๋ต์ ์บ์ํด ๋น์ฉ๊ณผ ์๋ต ์๊ฐ์ ์ค์
๋๋ค."
|
| 493 |
+
]
|
| 494 |
+
},
|
| 495 |
+
{
|
| 496 |
+
"id": "docs-unstructured",
|
| 497 |
+
"certification": "Docs Study",
|
| 498 |
+
"title": "Unstructured โ PDFยทWordยท์ด๋ฏธ์ง ํ์ฑ",
|
| 499 |
+
"level": "๊ณ ๊ธ",
|
| 500 |
+
"related_practices": ["docs-unstructured-1"],
|
| 501 |
+
"summary": "Unstructured๋ PDF, Word, Excel, PowerPoint, ์ด๋ฏธ์ง ๋ฑ ๋น์ ํ ๋ฌธ์๋ฅผ ํ
์คํธ๋ก ๋ณํํฉ๋๋ค. LangChain์ `UnstructuredFileLoader`์ ํตํฉ๋์ด ํ์ฅ์์ ์๊ด์์ด ๋์ผ ์ฝ๋๋ก RAG ํ์ดํ๋ผ์ธ์ ์ฐ๊ฒฐํฉ๋๋ค.",
|
| 502 |
+
"example": "from langchain_community.document_loaders import UnstructuredFileLoader\n\n# ๋จ์ผ ํ์ผ โ ํ์ฅ์ ์๋ ๊ฐ์ง\nloader = UnstructuredFileLoader('./report.pdf')\ndocs = loader.load()\n\n# ํผํฉ ํ์ ๋๋ ํ ๋ฆฌ\nfrom langchain_community.document_loaders import DirectoryLoader\nloader = DirectoryLoader(\n './docs',\n glob='**/*',\n loader_cls=UnstructuredFileLoader\n)\ndocs = loader.load()",
|
| 503 |
+
"common_mistake": "`pip install unstructured`๋ ๊ธฐ๋ณธ ์ค์น์
๋๋ค. PDF์๋ `pip install unstructured[pdf]`, ์ด๋ฏธ์ง OCR์๋ `pip install unstructured[local-inference]`์ฒ๋ผ ๋ณ๋ extra๋ฅผ ์ค์นํด์ผ ํฉ๋๋ค.",
|
| 504 |
+
"keywords": ["Unstructured", "UnstructuredFileLoader", "PDF", "Word", "OCR", "๋น์ ํ ๋ฌธ์", "elements"],
|
| 505 |
+
"source_id": "official-docs-unstructured",
|
| 506 |
+
"details": [
|
| 507 |
+
"**์๋ ํ์ผ ๊ฐ์ง**: ํ์ฅ์์ ๋ฐ๋ผ ์๋์ผ๋ก ์ ์ ํ ํ์๋ฅผ ์ ํํฉ๋๋ค. `.pdf`, `.docx`, `.pptx`, `.jpg`, `.eml` ๋ฑ์ ๋์ผ ์ฝ๋๋ก ์ฒ๋ฆฌํฉ๋๋ค.",
|
| 508 |
+
"**์์ ๋ถ๋ฅ**: `mode='elements'`๋ก ๋ก๋ํ๋ฉด Title, NarrativeText, Table, Image ๋ฑ ์์ ํ์
์ด ๋ฉํ๋ฐ์ดํฐ์ ์ ์ฅ๋ฉ๋๋ค. ํค๋๋ฅผ ์ฒญํฌ ๋ฉํ๋ฐ์ดํฐ๋ก ํ์ฉํ๊ฑฐ๋ ํ
์ด๋ธ๋ง ๋ฐ๋ก ์ถ์ถํ ๋ ์๋๋ค.",
|
| 509 |
+
"**API vs ๋ก์ปฌ**: Unstructured Cloud API๋ ๊ณ ํ์ง OCR๊ณผ ๋ ์ด์์ ๋ถ์์ ์ ๊ณตํฉ๋๋ค. ๋ก์ปฌ์ ๋ฌด๋ฃ์ด๋ ์ด๋ฏธ์ง๋ ๋ณต์กํ ๋ ์ด์์์ PDF ํ์ง์ด ๋ฎ์ ์ ์์ต๋๋ค."
|
| 510 |
+
]
|
| 511 |
+
},
|
| 512 |
+
{
|
| 513 |
+
"id": "docs-conversation-memory",
|
| 514 |
+
"certification": "Docs Study",
|
| 515 |
+
"title": "LangChain ๋ํ ๋ฉ๋ชจ๋ฆฌ โ ๋ฉํฐํด ์ฑ๋ด",
|
| 516 |
+
"level": "๊ณ ๊ธ",
|
| 517 |
+
"related_practices": ["docs-lab-6", "docs-brain-1"],
|
| 518 |
+
"summary": "RunnableWithMessageHistory๋ LangChain ์ฒด์ธ์ ๋ํ ํ์คํ ๋ฆฌ๋ฅผ ์๋์ผ๋ก ์ฃผ์
ํฉ๋๋ค. ๋งค ์์ฒญ๋ง๋ค ์ด์ ๋ํ๋ฅผ ์ง์ ๊ด๋ฆฌํ์ง ์์๋ session_id๋ง ๋๊ธฐ๋ฉด ํ์คํ ๋ฆฌ๊ฐ ์ ์ง๋ฉ๋๋ค.",
|
| 519 |
+
"example": "from langchain_community.chat_message_histories import ChatMessageHistory\nfrom langchain_core.runnables.history import RunnableWithMessageHistory\n\nstore = {} # session_id โ ChatMessageHistory\n\ndef get_session_history(session_id: str):\n if session_id not in store:\n store[session_id] = ChatMessageHistory()\n return store[session_id]\n\nchain_with_history = RunnableWithMessageHistory(\n chain,\n get_session_history,\n input_messages_key=\"question\",\n history_messages_key=\"chat_history\"\n)\n\nchain_with_history.invoke(\n {\"question\": \"์๋
\"},\n config={\"configurable\": {\"session_id\": \"user-1\"}}\n)",
|
| 520 |
+
"common_mistake": "`session_id`๋ฅผ ๋ชจ๋ ์ฌ์ฉ์์๊ฒ ๋์ผํ๊ฒ ๋๊ธฐ๋ฉด ์ ์ฒด ์ฌ์ฉ์๊ฐ ํ๋์ ๋ํ ํ์คํ ๋ฆฌ๋ฅผ ๊ณต์ ํฉ๋๋ค. ์ฌ์ฉ์๋ณ๋ก ๊ณ ์ ํ session_id๋ฅผ ์์ฑํด์ผ ํฉ๋๋ค.",
|
| 521 |
+
"keywords": ["RunnableWithMessageHistory", "ChatMessageHistory", "session_id", "chat_history", "๋ฉํฐํด"],
|
| 522 |
+
"source_id": "official-docs-langchain",
|
| 523 |
+
"details": [
|
| 524 |
+
"**ํ์คํ ๋ฆฌ ์ ์ฅ์**: ์ธ๋ฉ๋ชจ๋ฆฌ(`ChatMessageHistory`)๋ ์๋ฒ ์ฌ์์ ์ ์ฌ๋ผ์ง๋๋ค. ํ๋ก๋์
์์๋ `RedisChatMessageHistory`, `SQLChatMessageHistory` ๋ฑ ์์ ์ ์ฅ์๋ฅผ ์๋๋ค.",
|
| 525 |
+
"**ํ์คํ ๋ฆฌ ๊ธธ์ด ์ ํ**: ๋ํ๊ฐ ๊ธธ์ด์ง๋ฉด ํ ํฐ์ด ์ด๊ณผ๋ฉ๋๋ค. `trim_messages()` ๋๋ ์ต๊ทผ N๊ฐ ๋ฉ์์ง๋ง ์ ์งํ๋ ๋ก์ง์ ์ถ๊ฐํด์ผ ํฉ๋๋ค.",
|
| 526 |
+
"**ํ๋กฌํํธ ์ฐ๋**: `ChatPromptTemplate`์ `MessagesPlaceholder(variable_name=\"chat_history\")`๋ฅผ ์ถ๊ฐํด์ผ ํ์คํ ๋ฆฌ๊ฐ ํ๋กฌํํธ์ ์ฃผ์
๋ฉ๋๋ค. history_messages_key์ placeholder ์ด๋ฆ์ด ์ผ์นํด์ผ ํฉ๋๋ค."
|
| 527 |
+
]
|
| 528 |
+
}
|
| 529 |
+
]
|
cert_study_app/content/tool_docs/practices.json
ADDED
|
@@ -0,0 +1,530 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[
|
| 2 |
+
{
|
| 3 |
+
"id": "docs-lab-1",
|
| 4 |
+
"title": "[๋จ๊ณ 1] Ollama โ ๋ก์ปฌ LLM ์ค์น",
|
| 5 |
+
"task_description": "**์ํฉ**\nOpenAI API๋ก ๊ฐ๋ฐํ๋ ์ค ์ฒญ๊ตฌ์๊ฐ ๋์์ต๋๋ค. ํ
์คํธ๋ง ์์ญ ๋ฒ ํ๋๋ฐ ์๊ธ์ด ์ฒญ๊ตฌ๋์ต๋๋ค. ๋ก์ปฌ์์ ๋ฌด๋ฃ๋ก ๋๋ฆด ์ ์์๊น์?\n\n**๋ฌธ์ **\nAPI ํค ์์ด LLM์ ์ฐ๋ ค๋ฉด ๋ชจ๋ธ์ ์ง์ ๋ก์ปฌ์ ๋ด๋ ค๋ฐ์์ผ ํฉ๋๋ค.\n\n**ํด๊ฒฐ**\nOllama๋ก `llama3.2` ๋ชจ๋ธ์ ๋ก์ปฌ์ ๋ค์ด๋ก๋ํ์ธ์. (๋ํ ์์ด ๋ค์ด๋ก๋๋ง)\n\n> `run`์ด ์๋, ๋ค์ด๋ก๋๋ง ํ๋ ๋ช
๋ น์ด์
๋๋ค.",
|
| 6 |
+
"expected_command": "ollama pull llama3.2",
|
| 7 |
+
"grading_conditions": ["ollama pull", "llama3.2"],
|
| 8 |
+
"hint": "`ollama pull <๋ชจ๋ธ๋ช
>` ํ์์
๋๋ค.",
|
| 9 |
+
"explanation": "`ollama pull`์ ๋ชจ๋ธ ํ์ผ์ ๋ก์ปฌ์ ๋ด๋ ค๋ฐ์ต๋๋ค. ์ดํ `ollama list`๋ก ๋ชฉ๋ก ํ์ธ, `ollama run llama3.2`๋ก ๋ํ๋ฅผ ์์ํ ์ ์์ต๋๋ค. API ํค๋, ์ธํฐ๋ท ์ฐ๊ฒฐ๋ ์์ด ์คํ๋ฉ๋๋ค.",
|
| 10 |
+
"difficulty": "easy",
|
| 11 |
+
"takeaway": "API ํค ์์ด ollama pull ํ ๋ฒ์ผ๋ก ๋ก์ปฌ LLM ์คํ ํ๊ฒฝ์ด ์์ฑ๋ฉ๋๋ค."
|
| 12 |
+
},
|
| 13 |
+
{
|
| 14 |
+
"id": "docs-lab-2",
|
| 15 |
+
"title": "[๋จ๊ณ 2] Ollama REST API โ Python์์ ํธ์ถํ๊ธฐ",
|
| 16 |
+
"task_description": "**์ํฉ**\n`ollama run llama3.2`๋ก ํฐ๋ฏธ๋ ๋ํ๋ ๋๋๋ฐ, ๋ด Python ์ฝ๋์์ LLM์ ํธ์ถํ๋ ค๋ ๋ฐฉ๋ฒ์ ๋ชจ๋ฅด๊ฒ ์ต๋๋ค.\n\n**๋ฌธ์ **\nCLI ๋ํ ๋ชจ๋๋ ์๋ํ๊ฐ ๋ถ๊ฐ๋ฅํฉ๋๋ค. ์ฝ๋์์ ํธ์ถํ๋ ค๋ฉด HTTP API๊ฐ ํ์ํฉ๋๋ค.\n\n**ํด๊ฒฐ**\ncurl๋ก Ollama REST API๋ฅผ ์ง์ ํธ์ถํด ๋์์ ํ์ธํ์ธ์.\n- ์๋ํฌ์ธํธ: `http://localhost:11434/api/generate`\n- ๋ชจ๋ธ: `llama3.2`, ํ๋กฌํํธ: `'2+2๋?'`, ์คํธ๋ฆฌ๋ฐ ์์ด",
|
| 17 |
+
"expected_command": "curl http://localhost:11434/api/generate -d '{\"model\":\"llama3.2\",\"prompt\":\"2+2๋?\",\"stream\":false}'",
|
| 18 |
+
"grading_conditions": ["curl", "localhost:11434/api/generate", "stream", "false"],
|
| 19 |
+
"hint": "`-d` ํ๋๊ทธ๋ก JSON ๋ฐ๋๋ฅผ ์ ๋ฌํฉ๋๋ค. `\"stream\": false`๋ฅผ ๋ฃ์ด์ผ ํ ๋ฒ์ ์๋ต์ด ์ต๋๋ค.",
|
| 20 |
+
"explanation": "Ollama๋ ๊ธฐ๋ณธ์ ์ผ๋ก ์ค ๋จ์ ์คํธ๋ฆฌ๋ฐ์ผ๋ก ์๋ตํฉ๋๋ค. `\"stream\": false`๋ฅผ ๋ฃ์ผ๋ฉด ์์ฑ๋ ์๋ต์ ํ ๋ฒ์ ๋ฐ์ ์ ์์ด Python์์ ํ์ฑํ๊ธฐ ์ฝ์ต๋๋ค.",
|
| 21 |
+
"difficulty": "easy",
|
| 22 |
+
"takeaway": "Ollama REST API๋ OpenAI ํธํ ํ์์ด๋ผ ์ด๋ค ์ธ์ดยทํ๋ ์์ํฌ์์๋ ๋์ผํ ๋ฐฉ๋ฒ์ผ๋ก ํธ์ถํฉ๋๋ค."
|
| 23 |
+
},
|
| 24 |
+
{
|
| 25 |
+
"id": "docs-lab-3",
|
| 26 |
+
"title": "[๋จ๊ณ 3] Ollama ์ฑํ
API โ ๋ํ ํ์คํ ๋ฆฌ ๊ตฌ์กฐ",
|
| 27 |
+
"task_description": "**์ํฉ**\n`/api/generate`๋ก '์ด์ ์ ๋ด๊ฐ ๋ญ๋ผ๊ณ ํ์ด?'๋ฅผ ๋ฌผ์ด๋ดค๋๋ ๋ชจ๋ฅธ๋ค๊ณ ํฉ๋๋ค. ๋งค ์์ฒญ์ด ์์ ํ ๋
๋ฆฝ์ ์ผ๋ก ์ฒ๋ฆฌ๋๊ธฐ ๋๋ฌธ์
๋๋ค.\n\n**๋ฌธ์ **\n`/api/generate`๋ ๋จ์ผ ํ๋กฌํํธ๋ง ๋ฐ์ต๋๋ค. ๋ํ ํ์คํ ๋ฆฌ๋ฅผ ๋ถ์ด๋ ค๋ฉด ๋ค๋ฅธ ์๋ํฌ์ธํธ๊ฐ ํ์ํฉ๋๋ค.\n\n**ํด๊ฒฐ**\n`/api/chat`์ `messages` ๋ฐฐ์ด๋ก ํ์คํ ๋ฆฌ๋ฅผ ์ ๋ฌํฉ๋๋ค. `llama3.2`์๊ฒ `user` ๋ฉ์์ง `'ํ์ด์ฌ์ด ๋ญ์ผ?'`๋ฅผ ๋ณด๋ด์ธ์. (stream: false)",
|
| 28 |
+
"expected_command": "curl http://localhost:11434/api/chat -d '{\"model\":\"llama3.2\",\"messages\":[{\"role\":\"user\",\"content\":\"ํ์ด์ฌ์ด ๋ญ์ผ?\"}],\"stream\":false}'",
|
| 29 |
+
"grading_conditions": ["curl", "localhost:11434/api/chat", "messages", "role", "user"],
|
| 30 |
+
"hint": "`/api/chat`์ `messages` ๋ฐฐ์ด๋ก ๋ํ ํ์คํ ๋ฆฌ๋ฅผ ์ ๋ฌํฉ๋๋ค.",
|
| 31 |
+
"explanation": "`messages` ๋ฐฐ์ด์ `{\"role\": \"user\", \"content\": \"...\"}` ํ์์ผ๋ก ์ด์ ๋ํ๋ฅผ ์์ผ๋ฉด ๋ฉํฐํด ๋ํ๊ฐ ๋ฉ๋๋ค. LangChain์ ์ฑํ
๋ชจ๋ธ๋ ๋ด๋ถ์ ์ผ๋ก ์ด ๊ตฌ์กฐ๋ฅผ ์ฌ์ฉํฉ๋๋ค.",
|
| 32 |
+
"difficulty": "medium",
|
| 33 |
+
"takeaway": "messages ๋ฐฐ์ด์ {role, content} ์์ ์๋ ๊ตฌ์กฐ๊ฐ ๋ชจ๋ LLM ๋ฉํฐํด ๋ํ์ ๊ธฐ๋ณธ ํ์์
๋๋ค."
|
| 34 |
+
},
|
| 35 |
+
{
|
| 36 |
+
"id": "docs-lab-4",
|
| 37 |
+
"title": "[๋จ๊ณ 4] .env โ API ํค๋ฅผ ์ฝ๋์์ ๋ถ๋ฆฌํ๊ธฐ",
|
| 38 |
+
"task_description": "**์ํฉ**\n```python\napi_key = 'sk-abc123...'\n```\n์ด๋ ๊ฒ ์ฝ๋์ ์ง์ ์ผ๋ค๊ฐ GitHub์ pushํ๋๋ API ํค๊ฐ ๊ณต๊ฐ๋์ต๋๋ค. GitHub์ด ์๋์ผ๋ก ํ์งํด์ ํค๋ฅผ ์ฆ์ ๋ฌดํจํํ์ต๋๋ค.\n\n**๋ฌธ์ **\nAPI ํค๋ฅผ ์ฝ๋์ ํ๋์ฝ๋ฉํ๋ฉด ๋ฒ์ ๊ด๋ฆฌ ์์คํ
์ ๋
ธ์ถ๋ฉ๋๋ค. `.gitignore`์ ์ถ๊ฐํ ๋ณ๋ ํ์ผ์ ๋ณด๊ดํด์ผ ํฉ๋๋ค.\n\n**ํด๊ฒฐ**\n`.env` ํ์ผ์ ๋ก๋ํ๊ณ `OPENAI_API_KEY`๋ฅผ ์ฝ๋ ์ฝ๋ 2์ค์ ์
๋ ฅํ์ธ์.\n\n```python\nfrom dotenv import load_dotenv\nimport os\n# ์ฌ๊ธฐ์ ์
๋ ฅํ์ธ์\n```",
|
| 39 |
+
"expected_command": "load_dotenv()\napi_key = os.getenv('OPENAI_API_KEY')",
|
| 40 |
+
"grading_conditions": ["load_dotenv()", "os.getenv", "OPENAI_API_KEY"],
|
| 41 |
+
"hint": "`load_dotenv()`๋ฅผ ๋ฐ๋์ ๋จผ์ ํธ์ถํด์ผ `os.getenv()`๊ฐ ๊ฐ์ ์ฝ์ ์ ์์ต๋๋ค.",
|
| 42 |
+
"explanation": "`load_dotenv()` ํธ์ถ ์ ์ `os.getenv()`๋ฅผ ์ฐ๋ฉด ํญ์ `None`์ด ๋ฐํ๋ฉ๋๋ค. `.env` ํ์ผ์ `.gitignore`์ ์ถ๊ฐํ๊ณ , `.env.example`์๋ ํค ์ด๋ฆ๋ง ์ ์ด ํ์ ๊ณต์ ํฉ๋๋ค.",
|
| 43 |
+
"difficulty": "easy",
|
| 44 |
+
"takeaway": "load_dotenv() โ os.getenv() ์์๊ฐ ๋ชจ๋ Python ํ๋ก์ ํธ์ ํ๊ฒฝ๋ณ์ ๊ด๋ฆฌ ํ์ค์
๋๋ค."
|
| 45 |
+
},
|
| 46 |
+
{
|
| 47 |
+
"id": "docs-lab-5",
|
| 48 |
+
"title": "[๋จ๊ณ 5] ChatPromptTemplate โ ํ๋กฌํํธ ๊ตฌ์กฐํ",
|
| 49 |
+
"task_description": "**์ํฉ**\n```python\nresponse = llm.invoke(f'๋ฌธ์: {context}\\n์ง๋ฌธ: {question}')\n```\nf-string์ผ๋ก ํ๋กฌํํธ๋ฅผ ๋ง๋ค์๋๋ ๋ณ์ ์์๋ฅผ ์ค์ํ๊ธฐ ์ฝ๊ณ , ์์คํ
์ญํ (์ด์์คํดํธ ํ๋ฅด์๋)์ ์ง์ ํ ์ ์์ต๋๋ค.\n\n**๋ฌธ์ **\n๋จ์ ๋ฌธ์์ด ๋ฐฉ์์ ์ญํ ๊ตฌ๋ถ์ด ์๊ณ LangChain ํ์ดํ๋ผ์ธ์ ์ฐ๊ฒฐ๋์ง ์์ต๋๋ค.\n\n**ํด๊ฒฐ**\n์๋ ์กฐ๊ฑด์ผ๋ก `ChatPromptTemplate`์ ์์ฑํ์ธ์.\n- ์์คํ
: `\"๋น์ ์ ๋ฌธ์ ๊ธฐ๋ฐ AI ์ด์์คํดํธ์
๋๋ค. ์ปจํ
์คํธ: {context}\"`\n- ์ฌ์ฉ์: `\"{question}\"`\n\n๊ฒฐ๊ณผ๋ฅผ `prompt` ๋ณ์์ ์ ์ฅํ์ธ์.",
|
| 50 |
+
"expected_command": "prompt = ChatPromptTemplate.from_messages([\n (\"system\", \"๋น์ ์ ๋ฌธ์ ๊ธฐ๋ฐ AI ์ด์์คํดํธ์
๋๋ค. ์ปจํ
์คํธ: {context}\"),\n (\"human\", \"{question}\")\n])",
|
| 51 |
+
"grading_conditions": ["ChatPromptTemplate.from_messages", "system", "context", "human", "question"],
|
| 52 |
+
"hint": "`ChatPromptTemplate.from_messages([(\"system\", \"...\"), (\"human\", \"...\")])` ํ์์
๋๋ค.",
|
| 53 |
+
"explanation": "ChatPromptTemplate์ ์ญํ ๋ณ ๋ฉ์์ง๋ฅผ ๊ตฌ์กฐํํ๊ณ ๋ณ์ ์๋ฆฌ(`{context}`, `{question}`)๋ฅผ ์์ ํ๊ฒ ๊ด๋ฆฌํฉ๋๋ค. `chain.invoke({\"context\": ..., \"question\": ...})`๋ก ์คํ ์ ์๋์ผ๋ก ์ฑ์์ง๋๋ค.",
|
| 54 |
+
"difficulty": "easy",
|
| 55 |
+
"takeaway": "ChatPromptTemplate์ ์ญํ (system/human)๊ณผ ๋ณ์({})๋ฅผ ๋ถ๋ฆฌํด ํ๋กฌํํธ๋ฅผ ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ์ปดํฌ๋ํธ๋ก ๋ง๋ญ๋๋ค."
|
| 56 |
+
},
|
| 57 |
+
{
|
| 58 |
+
"id": "docs-lab-6",
|
| 59 |
+
"title": "[๋จ๊ณ 6] LCEL โ ์ฒด์ธ์ ํ ์ค๋ก",
|
| 60 |
+
"task_description": "**์ํฉ**\n```python\nformatted = prompt.format(context=ctx, question=q)\nllm_result = llm.invoke(formatted)\nfinal = output_parser.parse(llm_result)\n```\n3๋จ๊ณ๋ฅผ ๋งค๋ฒ ์ง์ ์ฐ๊ฒฐํ๋ ์ฝ๋๊ฐ ๋ฐ๋ณต๋ฉ๋๋ค. ์ฒด์ธ์ด ๊ธธ์ด์ง์๋ก ๋ ๋ณต์กํด์ง๋๋ค.\n\n**๋ฌธ์ **\n๊ฐ ๋จ๊ณ๋ฅผ ์๋์ผ๋ก ์ฐ๊ฒฐํ๋ฉด ์ฝ๋๊ฐ ๊ธธ๊ณ ๋จ๊ณ ์ถ๊ฐ/๋ณ๊ฒฝ์ด ๋ฒ๊ฑฐ๋กญ์ต๋๋ค.\n\n**ํด๊ฒฐ**\n`prompt`, `llm`, `output_parser`๋ฅผ LCEL `|` ์ฐ์ฐ์๋ก ์ฐ๊ฒฐํด `chain` ๋ณ์์ ์ ์ฅํ์ธ์.",
|
| 61 |
+
"expected_command": "chain = prompt | llm | output_parser",
|
| 62 |
+
"grading_conditions": ["chain", "prompt", "|", "llm", "|", "output_parser"],
|
| 63 |
+
"hint": "์ ๋์ค ํ์ดํ์ฒ๋ผ `|`๋ก ์ฐ๊ฒฐํฉ๋๋ค.",
|
| 64 |
+
"explanation": "`chain = prompt | llm | output_parser` ํ ์ค์ด ์์ 3์ค์ ๋์ฒดํฉ๋๋ค. `chain.invoke({\"context\": ..., \"question\": ...})`๋ก ์คํํ๋ฉด ์์๋๋ก ์ฒ๋ฆฌ๋ฉ๋๋ค. ๋จ๊ณ ์ถ๊ฐ๋ `| ์๋จ๊ณ`๋ฅผ ๋ถ์ด๋ฉด ๋ฉ๋๋ค.",
|
| 65 |
+
"difficulty": "easy",
|
| 66 |
+
"takeaway": "| ํ์ดํ ์ฐ์ฐ์๋ก Runnable์ ์ฐ๊ฒฐํ๋ LCEL์ด LangChain ๋ชจ๋ ์ฒด์ธ์ ๊ธฐ๋ณธ ๊ตฌ์กฐ์
๋๋ค."
|
| 67 |
+
},
|
| 68 |
+
{
|
| 69 |
+
"id": "docs-lab-7",
|
| 70 |
+
"title": "[๋จ๊ณ 7] TextSplitter โ ํ ํฐ ์ด๊ณผ ํด๊ฒฐ",
|
| 71 |
+
"task_description": "**์ํฉ**\n100ํ์ด์ง PDF ์ ์ฒด๋ฅผ LLM ํ๋กฌํํธ์ ๋ฃ์๋๋:\n```\nError: This model's maximum context length is 128000 tokens. \nYour message resulted in 210000 tokens.\n```\n๋ฌธ์๊ฐ ๊ธธ์๋ก LLM์ ํต์งธ๋ก ๋ฃ๋ ๊ฑด ๋ถ๊ฐ๋ฅํฉ๋๋ค.\n\n**๋ฌธ์ **\nLLM์ ํ ๋ฒ์ ์ฒ๋ฆฌํ ์ ์๋ ํ ํฐ ์์ ํ๊ณ๊ฐ ์์ต๋๋ค. ๋ฌธ์๋ฅผ ์๋ผ์ผ ํฉ๋๋ค.\n\n**ํด๊ฒฐ**\n`RecursiveCharacterTextSplitter`๋ก ์ฒญํฌ ํฌ๊ธฐ 500, ์ค๋ฒ๋ฉ 50์ผ๋ก `docs`๋ฅผ ๋ถํ ํด `chunks`์ ์ ์ฅํ์ธ์.",
|
| 72 |
+
"expected_command": "splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50)\nchunks = splitter.split_documents(docs)",
|
| 73 |
+
"grading_conditions": ["RecursiveCharacterTextSplitter", "chunk_size=500", "chunk_overlap=50", "split_documents"],
|
| 74 |
+
"hint": "์์ฑ ํ `.split_documents(docs)`๋ฅผ ํธ์ถํฉ๋๋ค.",
|
| 75 |
+
"explanation": "chunk_size=500์ ์ฒญํฌ๋น ์ต๋ 500์, chunk_overlap=50์ ์ธ์ ์ฒญํฌ๊ฐ 50์๋ฅผ ๊ณต์ ํฉ๋๋ค. ์ค๋ฒ๋ฉ์ด ์์ผ๋ฉด ์ฒญํฌ ๊ฒฝ๊ณ์์ ๋ฌธ์ฅ์ด ์๋ ค ๊ฒ์ ํ์ง์ด ๋จ์ด์ง๋๋ค.",
|
| 76 |
+
"difficulty": "medium",
|
| 77 |
+
"takeaway": "chunk_overlap์ด ์์ผ๋ฉด ์ฒญํฌ ๊ฒฝ๊ณ์์ ๋ฌธ๋งฅ์ด ์๋ ค ๊ฒ์ ํ์ง์ด ๋จ์ด์ง๋๋ค. ์ผ๋ฐ์ ์ผ๋ก chunk_size์ 10% ์ ๋๋ฅผ ์๋๋ค."
|
| 78 |
+
},
|
| 79 |
+
{
|
| 80 |
+
"id": "docs-lab-8",
|
| 81 |
+
"title": "[๋จ๊ณ 8] FAISS VectorStore โ ์๋ฏธ ๊ธฐ๋ฐ ๊ฒ์ ์ธ๋ฑ์ค ์์ฑ",
|
| 82 |
+
"task_description": "**์ํฉ**\n๋ฌธ์๋ฅผ ์ฒญํฌ๋ก ์๋๋๋ฐ, ์ง๋ฌธ์ด ๋ค์ด์ฌ ๋๋ง๋ค 500๊ฐ ์ฒญํฌ๋ฅผ ์ ๋ถ LLM์ ๋ฃ์ผ๋ฉด ์ฒ์๊ณผ ๋๊ฐ์ด ํ ํฐ์ด ์ด๊ณผ๋ฉ๋๋ค.\n\n**๋ฌธ์ **\n\"๊ด๋ จ ์๋ ์ฒญํฌ๋ง\" ์ฐพ์์ผ ํฉ๋๋ค. ํค์๋ ๊ฒ์์ ๋์์ด๋ ์๋ฏธ์ ์ ์ฌ์ฑ์ ๋ชป ์ก์ต๋๋ค.\n\n**ํด๊ฒฐ**\n`chunks`์ `embeddings` ๋ชจ๋ธ๋ก FAISS VectorStore๋ฅผ ๋ง๋ค๊ณ , `./faiss_index`์ ์ ์ฅํ์ธ์. (๋ค์ ์คํ ์ ์ฌ์ฌ์ฉํ๊ธฐ ์ํด)",
|
| 83 |
+
"expected_command": "db = FAISS.from_documents(chunks, embeddings)\ndb.save_local(\"./faiss_index\")",
|
| 84 |
+
"grading_conditions": ["FAISS.from_documents", "chunks", "embeddings", "save_local"],
|
| 85 |
+
"hint": "`FAISS.from_documents(๋ฌธ์, ์๋ฒ ๋ฉ๋ชจ๋ธ)`๋ก ์์ฑ, `.save_local(๊ฒฝ๋ก)`๋ก ์ ์ฅํฉ๋๋ค.",
|
| 86 |
+
"explanation": "FAISS๋ ๊ฐ ์ฒญํฌ๋ฅผ ๋ฒกํฐ๋ก ๋ณํํด ์ธ๋ฑ์ค๋ฅผ ๋ง๋ญ๋๋ค. ์ง๋ฌธ๋ ๋ฒกํฐ๋ก ๋ณํํด ๊ฐ์ฅ ๊ฐ๊น์ด(์๋ฏธ์ ์ผ๋ก ์ ์ฌํ) ์ฒญํฌ๋ฅผ O(1)์ ๊ฐ๊น๊ฒ ์ฐพ์ต๋๋ค. `save_local`๋ก ์ ์ฅํ๋ฉด ๋ค์ ์คํ ์ ์๋ฒ ๋ฉ ์ฌ๊ณ์ฐ ์์ด ๋ก๋ํ ์ ์์ต๋๋ค.",
|
| 87 |
+
"difficulty": "medium",
|
| 88 |
+
"takeaway": "FAISS.from_documents()๊ฐ ์๋ฒ ๋ฉ ์์ฑ๊ณผ ์ธ๋ฑ์ค ๊ตฌ์ถ์ ํ ๋ฒ์ ์ฒ๋ฆฌํ๊ณ , save_local()๋ก ์ฌ์์ ์ ์ฌ๊ณ์ฐ์ ํผํฉ๋๋ค."
|
| 89 |
+
},
|
| 90 |
+
{
|
| 91 |
+
"id": "docs-lab-9",
|
| 92 |
+
"title": "[๋จ๊ณ 9] RAG ์ ์ฒด ํ์ดํ๋ผ์ธ โ ์ฐ๊ฒฐ",
|
| 93 |
+
"task_description": "**์ํฉ**\n```python\ndocs = retriever.invoke(question) # 1. ๊ฒ์\ncontext = '\\n'.join(d.page_content for d in docs) # 2. ํฉ์น๊ธฐ\nprompt_text = prompt.format(...) # 3. ํ๋กฌํํธ\nresponse = llm.invoke(prompt_text) # 4. LLM ํธ์ถ\nfinal = parser.parse(response) # 5. ํ์ฑ\n```\n5์ค ์ฝ๋๋ฅผ ๋งค ์ง๋ฌธ๋ง๋ค ๋ฐ๋ณตํด์ผ ํฉ๋๋ค.\n\n**๋ฌธ์ **\nretriever โ prompt โ llm โ parser๋ฅผ ์๋์ผ๋ก ์ฐ๊ฒฐํ๋ ์ฝ๋๊ฐ ์ฅํฉํฉ๋๋ค.\n\n**ํด๊ฒฐ**\nLCEL๋ก RAG ์ฒด์ธ์ ํ ์ค๋ก ๋ง๋์ธ์.\n- `retriever`, `prompt`, `llm`, `StrOutputParser` ๋ณ์๋ ์ด๋ฏธ ์ ์๋์ด ์์ต๋๋ค.",
|
| 94 |
+
"expected_command": "chain = {\"context\": retriever, \"question\": RunnablePassthrough()} | prompt | llm | StrOutputParser()",
|
| 95 |
+
"grading_conditions": ["retriever", "RunnablePassthrough", "|", "prompt", "|", "llm", "StrOutputParser"],
|
| 96 |
+
"hint": "`{\"context\": retriever, \"question\": RunnablePassthrough()}`๋ก retriever์ ์ง๋ฌธ์ ๋์์ prompt์ ๋๊น๋๋ค.",
|
| 97 |
+
"explanation": "๋์
๋๋ฆฌ๋ก ๋ฌถ์ผ๋ฉด `RunnableParallel`์ฒ๋ผ ๋์ํด retriever ๊ฒ์๊ณผ ์ง๋ฌธ ์ ๋ฌ์ ๋์์ ์ฒ๋ฆฌํฉ๋๋ค. `RunnablePassthrough()`๋ ์
๋ ฅ(์ง๋ฌธ)์ ๊ทธ๋๋ก ๋ค์ ๋จ๊ณ๋ก ์ ๋ฌํฉ๋๋ค.",
|
| 98 |
+
"difficulty": "hard",
|
| 99 |
+
"takeaway": "{context: retriever, question: RunnablePassthrough()} ํจํด์ด RAG ์ฒด์ธ์์ ๊ฒ์๊ณผ ์ง๋ฌธ์ ๋์์ ํ๋กฌํํธ์ ์ฃผ์
ํ๋ ํต์ฌ ๊ตฌ์กฐ์
๋๋ค."
|
| 100 |
+
},
|
| 101 |
+
{
|
| 102 |
+
"id": "docs-lab-10",
|
| 103 |
+
"title": "[๋จ๊ณ 10] session_state โ ๋ํ๊ฐ ์ฌ๋ผ์ง๋ ๋ฌธ์ ํด๊ฒฐ",
|
| 104 |
+
"task_description": "**์ํฉ**\nStreamlit ์ฑ๋ด์ ๋ง๋ค์๋๋ฐ, ๋ฉ์์ง๋ฅผ ๋ณด๋ผ ๋๋ง๋ค ์ด์ ๋ํ๊ฐ ์ ๋ถ ์ฌ๋ผ์ง๋๋ค.\n\n**๋ฌธ์ **\nStreamlit์ ๋ฒํผ ํด๋ฆญ ๋ฑ ๋ชจ๋ ์ํธ์์ฉ๋ง๋ค Python ์คํฌ๋ฆฝํธ๋ฅผ ์ฒ์๋ถํฐ ๋ค์ ์คํํฉ๋๋ค. `messages = []`์ฒ๋ผ ์ ์ธํ๋ฉด ๋งค๋ฒ ์ด๊ธฐํ๋ฉ๋๋ค.\n\n**ํด๊ฒฐ**\n`messages` ํค๊ฐ ์์ ๋๋ง ๋น ๋ฆฌ์คํธ๋ก ์ด๊ธฐํํ๋ ํจํด์ ์์ฑํ์ธ์.\n\n> ํต์ฌ: `st.session_state`์ ์ ์ฅ๋ ๊ฐ์ rerunํด๋ ์ ์ง๋ฉ๋๋ค.",
|
| 105 |
+
"expected_command": "if \"messages\" not in st.session_state:\n st.session_state.messages = []",
|
| 106 |
+
"grading_conditions": ["\"messages\" not in st.session_state", "st.session_state.messages", "[]"],
|
| 107 |
+
"hint": "`if \"ํค\" not in st.session_state:` ๊ฐ๋๋ฅผ ์ฐ๋ฉด ์ฒซ ์คํ์๋ง ์ด๊ธฐํ๋ฉ๋๋ค.",
|
| 108 |
+
"explanation": "`if ... not in st.session_state` ํจํด์ด ์์ผ๋ฉด ๋งค rerun๋ง๋ค `[]`๋ก ๋ฆฌ์
๋ฉ๋๋ค. ์ด ๊ฐ๋๊ฐ ์์ผ๋ฉด ์ด๋ฏธ ๊ฐ์ด ์์ ๋๋ ๊ฑด๋๋๋๋ค.",
|
| 109 |
+
"difficulty": "easy",
|
| 110 |
+
"takeaway": "`if key not in st.session_state:` ๊ฐ๋ ํจํด ํ๋๊ฐ Streamlit ์ํ ๋ณด์กด์ ์ ๋ถ์
๋๋ค."
|
| 111 |
+
},
|
| 112 |
+
{
|
| 113 |
+
"id": "docs-lab-11",
|
| 114 |
+
"title": "[๋จ๊ณ 11] cache_resource โ ์ง๋ฌธ๋ง๋ค LLM์ด ์๋ก ๋ก๋๋๋ ๋ฌธ์ ",
|
| 115 |
+
"task_description": "**์ํฉ**\n์ฑ๋ด์ ์ง๋ฌธํ ๋๋ง๋ค 3~4์ด์ฉ ๊ฑธ๋ฆฝ๋๋ค. ๋ก๊ทธ๋ฅผ ๋ณด๋ LLM ๊ฐ์ฒด๊ฐ ๋งค๋ฒ ์๋ก ์์ฑ๋๊ณ ์์ต๋๋ค.\n\n```python\ndef load_llm(): # ์ด ํจ์๊ฐ ๋งค rerun๋ง๋ค ์คํ๋จ\n return OllamaLLM(model=\"llama3.2\")\n```\n\n**๋ฌธ์ **\nStreamlit์ rerun๋ง๋ค ๋ชจ๋ ํจ์๋ฅผ ๋ค์ ์คํํฉ๋๋ค. LLM ๋ก๋๋ ๋น์ฉ์ด ํฌ๋ฏ๋ก ํ ๋ฒ๋ง ํด์ผ ํฉ๋๋ค.\n\n**ํด๊ฒฐ**\n`load_llm()` ํจ์์ `st.cache_resource` ๋ฐ์ฝ๋ ์ดํฐ๋ฅผ ๋ถ์ฌ ์ฑ ์๋ช
๋์ ํ ๋ฒ๋ง ๋ก๋๋๊ฒ ํ์ธ์.",
|
| 116 |
+
"expected_command": "@st.cache_resource\ndef load_llm():\n return OllamaLLM(model=\"llama3.2\")",
|
| 117 |
+
"grading_conditions": ["@st.cache_resource", "def load_llm", "OllamaLLM"],
|
| 118 |
+
"hint": "ํจ์ ์ ์ ๋ฐ๋ก ์์ `@st.cache_resource`๋ฅผ ๋ถ์
๋๋ค.",
|
| 119 |
+
"explanation": "`@st.cache_resource`๋ ๋ฐํ ๊ฐ์ฒด๋ฅผ ์ฑ ์ ์ฒด(๋ชจ๋ ์ธ์
)์์ ๊ณต์ ํฉ๋๋ค. ์ฒซ ๋ฒ์งธ ํธ์ถ์๋ง ํจ์๋ฅผ ์คํํ๊ณ ์ดํ์๋ ์บ์๋ ๊ฐ์ฒด๋ฅผ ๋ฐํํฉ๋๋ค.",
|
| 120 |
+
"difficulty": "easy",
|
| 121 |
+
"takeaway": "@st.cache_resource๋ LLMยทDB์ฒ๋ผ ๊ณต์ ๊ฐ๋ฅํ ๋ฌด๊ฑฐ์ด ๊ฐ์ฒด์, @st.cache_data๋ ๊ณ์ฐ ๊ฒฐ๊ณผ(DataFrame ๋ฑ)์ ์๋๋ค."
|
| 122 |
+
},
|
| 123 |
+
{
|
| 124 |
+
"id": "docs-lab-12",
|
| 125 |
+
"title": "[๋จ๊ณ 12] Streamlit secrets โ ๋ฐฐํฌ ํ๊ฒฝ์ API ํค ๊ด๋ฆฌ",
|
| 126 |
+
"task_description": "**์ํฉ**\n๋ก์ปฌ์์ `.env`๋ก ์ ์๋ํ๋ ์ฑ๋ด์ Streamlit Cloud์ ๋ฐฐํฌํ๋๋:\n```\nKeyError: 'OPENAI_API_KEY'\n```\nStreamlit Cloud๋ ๋ก์ปฌ์ `.env` ํ์ผ์ ์ฝ์ ์ ์์ต๋๋ค.\n\n**๋ฌธ์ **\n๋ฐฐํฌ ํ๊ฒฝ์์๋ `.env` ํ์ผ์ด ์์ต๋๋ค. ๋ค๋ฅธ ๋ฐฉ๋ฒ์ผ๋ก API ํค๋ฅผ ์ฃผ์
ํด์ผ ํฉ๋๋ค.\n\n**ํด๊ฒฐ**\nStreamlit Cloud ๋์๋ณด๋์ Secrets์ ํค๋ฅผ ๋ฑ๋กํ ๋ค, ์ฝ๋์์ ์ฝ๋ ํ ์ค์ ์์ฑํ์ธ์.",
|
| 127 |
+
"expected_command": "api_key = st.secrets[\"OPENAI_API_KEY\"]",
|
| 128 |
+
"grading_conditions": ["st.secrets", "OPENAI_API_KEY"],
|
| 129 |
+
"hint": "`st.secrets[\"ํค์ด๋ฆ\"]`์ผ๋ก ์ ๊ทผํฉ๋๋ค.",
|
| 130 |
+
"explanation": "`st.secrets`๋ ๋ก์ปฌ์์๋ `.streamlit/secrets.toml`, ๋ฐฐํฌ ์์๋ ๋์๋ณด๋ Secrets์์ ๊ฐ์ ์ฝ์ต๋๋ค. ์ฝ๋๋ฅผ ๋ฐ๊พธ์ง ์์๋ ๋ ํ๊ฒฝ์์ ๋์ผํ๊ฒ ์๋ํฉ๋๋ค.",
|
| 131 |
+
"difficulty": "easy",
|
| 132 |
+
"takeaway": "st.secrets๋ ๋ก์ปฌ(.streamlit/secrets.toml)๊ณผ ๋ฐฐํฌ(Streamlit Cloud) ํ๊ฒฝ์ ์ฝ๋ ๋ณ๊ฒฝ ์์ด ๋์ผํ๊ฒ ์ฒ๋ฆฌํฉ๋๋ค."
|
| 133 |
+
},
|
| 134 |
+
{
|
| 135 |
+
"id": "docs-lab-13",
|
| 136 |
+
"title": "[๋จ๊ณ 13] ๋ํ ๋ฉ๋ชจ๋ฆฌ โ ์ด์ ๋ํ๋ฅผ ๊ธฐ์ตํ๊ฒ",
|
| 137 |
+
"task_description": "**์ํฉ**\n```\n์ฌ์ฉ์: ํ์ด์ฌ์ด ๋ญ์ผ?\n์ฑ๋ด: ํ์ด์ฌ์ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด์
๋๋ค...\n์ฌ์ฉ์: ๊ทธ๊ฑฐ ์ด๋์ ๋ฐฐ์ธ ์ ์์ด?\n์ฑ๋ด: ๋ฌด์์ ๋ฐฐ์ฐ๊ณ ์ถ์ผ์ ๊ฐ์? (??)\n```\n\"๊ทธ๊ฑฐ\"๊ฐ ๋ฌด์์ธ์ง ์ฑ๋ด์ด ๋ชจ๋ฆ
๋๋ค. ๋งค ์ง๋ฌธ์ด ๋
๋ฆฝ์ ์ผ๋ก ์ฒ๋ฆฌ๋๊ธฐ ๋๋ฌธ์
๋๋ค.\n\n**๋ฌธ์ **\nRAG ์ฒด์ธ์ ์ด์ ๋ํ ๋ด์ฉ์ ๋ฐ์ง ์์ต๋๋ค. ๋ฉํฐํด ๋ํ๋ฅผ ์ํด ํ์คํ ๋ฆฌ๋ฅผ ์ฃผ์
ํด์ผ ํฉ๋๋ค.\n\n**ํด๊ฒฐ**\n๊ธฐ์กด `chain`์ `RunnableWithMessageHistory`๋ก ๊ฐ์ธ์ธ์.\n- `input_messages_key`: `\"question\"`\n- `history_messages_key`: `\"chat_history\"`\n- ๊ฒฐ๊ณผ๋ฅผ `chain_with_history`์ ์ ์ฅ",
|
| 138 |
+
"expected_command": "chain_with_history = RunnableWithMessageHistory(\n chain,\n get_session_history,\n input_messages_key=\"question\",\n history_messages_key=\"chat_history\"\n)",
|
| 139 |
+
"grading_conditions": ["RunnableWithMessageHistory", "chain", "get_session_history", "input_messages_key", "history_messages_key"],
|
| 140 |
+
"hint": "`RunnableWithMessageHistory(์ฒด์ธ, ํ์คํ ๋ฆฌํจ์, input_messages_key=..., history_messages_key=...)`",
|
| 141 |
+
"explanation": "`RunnableWithMessageHistory`๋ ๋งค invoke๋ง๋ค session_id์ ํด๋นํ๋ ํ์คํ ๋ฆฌ๋ฅผ ์๋์ผ๋ก ๋ถ๋ฌ์ ํ๋กฌํํธ์ ์ฃผ์
ํฉ๋๋ค. invoke ์ `config={\"configurable\": {\"session_id\": \"user-1\"}}`์ ๋๊ฒจ์ผ ํฉ๋๋ค.",
|
| 142 |
+
"difficulty": "medium",
|
| 143 |
+
"takeaway": "RunnableWithMessageHistory๋ก ๊ธฐ์กด ์ฒด์ธ์ ๊ฐ์ธ๊ธฐ๋ง ํ๋ฉด ๋ฉํฐํด ๋ํ๊ฐ ๋ฉ๋๋ค. session_id ๊ด๋ฆฌ๊ฐ ์ ๋ถ์
๋๋ค."
|
| 144 |
+
},
|
| 145 |
+
{
|
| 146 |
+
"id": "docs-lab-14",
|
| 147 |
+
"title": "[๋จ๊ณ 14] HF Spaces โ ๋ค๋ฅธ ์ฌ๋๋ ์ธ ์ ์๊ฒ ๋ฐฐํฌ",
|
| 148 |
+
"task_description": "**์ํฉ**\n์์ฑ๋ ์ฑ๋ด์ ํ์์๊ฒ ๋ณด์ฌ์ฃผ๋ ค๋ \"๋ก์ปฌ์์๋ง ๋์๊ฐ๊ณ ๋ฐ์์ ์ ๊ทผ์ด ์ ๋ฉ๋๋ค.\"\n\n**๋ฌธ์ **\n์๋ฒ๋ฅผ ์ง์ ๊ตฌ๋งคํ๊ฑฐ๋ AWS/GCP๋ฅผ ์ค์ ํ์ง ์๊ณ ๋ ์ธ๋ถ์ ๊ณต๊ฐํ๊ณ ์ถ์ต๋๋ค.\n\n**ํด๊ฒฐ**\nHugging Face Spaces๋ก ๋ฌด๋ฃ ๋ฐฐํฌํฉ๋๋ค. `README.md` ์๋จ์ SDK๋ฅผ ์ ์ธํ์ธ์.\n- SDK: `streamlit`, ์ฑ ํ์ผ: `app.py`, Python: `3.11`",
|
| 149 |
+
"expected_command": "---\nsdk: streamlit\napp_file: app.py\npython_version: \"3.11\"\n---",
|
| 150 |
+
"grading_conditions": ["sdk: streamlit", "app_file: app.py"],
|
| 151 |
+
"hint": "README.md ๋งจ ์ `---` YAML ๋ธ๋ก ์์ ์ ์ธํฉ๋๋ค.",
|
| 152 |
+
"explanation": "HF Spaces๋ README ๋ฉํ๋ฐ์ดํฐ์ `sdk` ํ๋๋ก ๋ฐํ์์ ๊ฒฐ์ ํฉ๋๋ค. `sdk: streamlit`์ด๋ฉด ์๋์ผ๋ก Streamlit ์๋ฒ๋ฅผ ์คํํฉ๋๋ค. ๋ฌด๋ฃ ํ๋์ผ๋ก๋ ์ธ๋ถ URL์ด ์ฆ์ ์์ฑ๋ฉ๋๋ค.",
|
| 153 |
+
"difficulty": "easy",
|
| 154 |
+
"takeaway": "README YAML ๋ฉํ๋ฐ์ดํฐ 3์ค(sdk, app_file, python_version)๋ง์ผ๋ก HF Spaces ๋ฐฐํฌ๊ฐ ์๋ฃ๋ฉ๋๋ค."
|
| 155 |
+
},
|
| 156 |
+
{
|
| 157 |
+
"id": "docs-lab-15",
|
| 158 |
+
"title": "[๋จ๊ณ 15] HF Docker Space โ SDK ์ ์ฝ ์์ด ๋ฐฐํฌ",
|
| 159 |
+
"task_description": "**์ํฉ**\nHF Spaces Streamlit SDK๋ก ๋ฐฐํฌํ๋๋ฐ, FastAPI ์๋ฒ๋ฅผ ํจ๊ป ๋์ฐ๊ณ ์ถ์ด ํฌํธ๋ฅผ ์ปค์คํ
ํ๋ ค๋ ์ค์ ์ด ๋งํ์์ต๋๋ค.\n\n**๋ฌธ์ **\nStreamlit/Gradio SDK๋ ๋ฐํ์ ํ๊ฒฝ์ด ๊ณ ์ ๋ฉ๋๋ค. ์ง์ ์๋ฒ๋ฅผ ์ ์ดํ๋ ค๋ฉด Dockerfile์ด ํ์ํฉ๋๋ค.\n\n**ํด๊ฒฐ**\nDocker Space์์ HF๊ฐ ์ธ์ํ๋ ํฌํธ๋ก ์ฑ์ ๋
ธ์ถํ๋ Dockerfile ์ง์์ด๋ฅผ ์์ฑํ์ธ์.\n\n> HF Docker Space ๊ธฐ๋ณธ ํฌํธ: 7860",
|
| 160 |
+
"expected_command": "EXPOSE 7860\nENV PORT=7860",
|
| 161 |
+
"grading_conditions": ["EXPOSE 7860"],
|
| 162 |
+
"hint": "Streamlit ๊ธฐ๋ณธ ํฌํธ๋ 8501์ด์ง๋ง HF๋ 7860์ ๊ธฐ๋ํฉ๋๋ค.",
|
| 163 |
+
"explanation": "Docker Space์์๋ `EXPOSE 7860`์ผ๋ก ํฌํธ๋ฅผ ์ ์ธํ๊ณ , `streamlit run app.py --server.port 7860`์ผ๋ก Streamlit๋ 7860์ ๋ฐ์ธ๋ฉํด์ผ ํฉ๋๋ค.",
|
| 164 |
+
"difficulty": "medium",
|
| 165 |
+
"takeaway": "HF Docker Space๋ ํญ์ ํฌํธ 7860์ ๊ธฐ๋ํฉ๋๋ค. EXPOSE 7860๊ณผ ์ฑ์ ํฌํธ ์ค์ ์ ์ผ์น์์ผ์ผ ํฉ๋๋ค."
|
| 166 |
+
},
|
| 167 |
+
{
|
| 168 |
+
"id": "docs-lab-16",
|
| 169 |
+
"title": "[๋จ๊ณ 16] FastAPI โ ์ฑ๋ด ๋ก์ง์ API๋ก ๋ถ๋ฆฌ",
|
| 170 |
+
"task_description": "**์ํฉ**\nํ๋ก ํธ์๋ ํ์์ \"์ฑ๋ด API ์๋ํฌ์ธํธ๋ง ์ฃผ์ธ์. React์์ ๋ถ์ด๊ฒ ์ต๋๋ค.\"๋ผ๊ณ ํฉ๋๋ค. ์ง๊ธ์ Streamlit์ ๋ก์ง์ด ๋ฌถ์ฌ ์์ด ๋ถ๋ฆฌ๊ฐ ์ ๋ฉ๋๋ค.\n\n**๋ฌธ์ **\nStreamlit ์ฑ์ UI์ ๋ก์ง์ด ๊ฒฐํฉ๋์ด ์์ด ๋ค๋ฅธ ํ๋ก ํธ์๋์์ ์ฌ์ฌ์ฉํ๊ธฐ ์ด๋ ต์ต๋๋ค.\n\n**ํด๊ฒฐ**\n์๋ `???`๋ฅผ ์ฑ์ POST `/ask` ์๋ํฌ์ธํธ๋ฅผ ์์ฑํ์ธ์.\n\n```python\nclass Query(BaseModel):\n question: str\n\n@app.post('/ask')\nasync def ask(q: Query):\n answer = ???\n return {\"answer\": answer}\n```",
|
| 171 |
+
"expected_command": "answer = chain.invoke(q.question)",
|
| 172 |
+
"grading_conditions": ["chain.invoke", "q.question"],
|
| 173 |
+
"hint": "Pydantic ๋ชจ๋ธ `q`์ `.question` ์์ฑ์ผ๋ก ์ง๋ฌธ์ ์ ๊ทผํฉ๋๋ค.",
|
| 174 |
+
"explanation": "FastAPI๋ Pydantic ๋ชจ๋ธ ํ์
์ ํ๋ผ๋ฏธํฐ๋ก ์ง์ ํ๋ฉด ์๋์ผ๋ก JSON ๋ฐ๋๋ฅผ ํ์ฑํฉ๋๋ค. `q.question`์ผ๋ก ์ง๋ฌธ ๋ฌธ์์ด์ ๊บผ๋ด chain์ ์ ๋ฌํฉ๋๋ค.",
|
| 175 |
+
"difficulty": "easy",
|
| 176 |
+
"takeaway": "FastAPI + Pydantic ์กฐํฉ์ด LLM ์๋น์ค๋ฅผ API๋ก ๋
ธ์ถํ๋ ๊ฐ์ฅ ๋น ๋ฅธ ๋ฐฉ๋ฒ์
๋๋ค. Pydantic์ด JSON ๊ฒ์ฆ์ ์๋ ์ฒ๋ฆฌํฉ๋๋ค."
|
| 177 |
+
},
|
| 178 |
+
{
|
| 179 |
+
"id": "docs-lab-17",
|
| 180 |
+
"title": "[๋จ๊ณ 17] FastAPI ๊ฐ๋ฐ ์๋ฒ โ ์ฝ๋ ์์ ์ฆ์ ๋ฐ์",
|
| 181 |
+
"task_description": "**์ํฉ**\n```python\nuvicorn main:app\n```\n์๋ํฌ์ธํธ ์ฝ๋๋ฅผ ์์ ํ ๋๋ง๋ค ์๋ฒ๋ฅผ `Ctrl+C`๋ก ์ข
๋ฃํ๊ณ ๋ค์ ์คํํด์ผ ํฉ๋๋ค. ๊ฐ๋ฐ ์ค์ ๋๋ฌด ๋ฒ๊ฑฐ๋กญ์ต๋๋ค.\n\n**๋ฌธ์ **\n๊ธฐ๋ณธ uvicorn์ ํ์ผ ๋ณ๊ฒฝ์ ๊ฐ์งํ์ง ์์ต๋๋ค.\n\n**ํด๊ฒฐ**\n`main.py`์ `app` ์ธ์คํด์ค๋ฅผ ํ์ผ ๋ณ๊ฒฝ ์ ์๋ ์ฌ์์๋๋ ๋ชจ๋๋ก ์คํํ์ธ์.",
|
| 182 |
+
"expected_command": "uvicorn main:app --reload",
|
| 183 |
+
"grading_conditions": ["uvicorn", "main:app", "--reload"],
|
| 184 |
+
"hint": "`--reload` ํ๋๊ทธ ํ๋๋ฅผ ์ถ๊ฐํฉ๋๋ค.",
|
| 185 |
+
"explanation": "`--reload`๋ ์์ค ํ์ผ ๋ณ๊ฒฝ์ ๊ฐ์งํด ์๋ฒ๋ฅผ ์๋ ์ฌ์์ํฉ๋๋ค. ๊ฐ๋ฐ ์ค์๋ง ์ฌ์ฉํ๋ฉฐ, ํ๋ก๋์
์์๋ ์ ๊ฑฐํ๊ณ `gunicorn` ๊ฐ์ ํ๋ก๋์
์๋ฒ๋ฅผ ์๋๋ค.",
|
| 186 |
+
"difficulty": "easy",
|
| 187 |
+
"takeaway": "--reload๋ ๊ฐ๋ฐ์ฉ, ํ๋ก๋์
์์๋ gunicorn์ ์๋๋ค. ์ด ๊ตฌ๋ถ์ ๊ธฐ์ตํ๋ ๊ฒ์ด ํต์ฌ์
๋๋ค."
|
| 188 |
+
},
|
| 189 |
+
{
|
| 190 |
+
"id": "docs-lab-18",
|
| 191 |
+
"title": "[๋จ๊ณ 18] LangSmith โ ์ด๋ ๋จ๊ณ์์ ํ๋ฆฐ ๋ต์ด ๋์ค๋๊ฐ",
|
| 192 |
+
"task_description": "**์ํฉ**\n์ฑ๋ด์ด ์๋ฑํ ๋ต์ ํ์ต๋๋ค. ๋๋ฒ๊น
์ ์ํด `print()`๋ฅผ ์ถ๊ฐํ์ง๋ง:\n\n```python\nprint('์ฒด์ธ ์คํ ์ค...')\nresult = chain.invoke({'question': q})\nprint('๊ฒฐ๊ณผ:', result)\n```\n\n์ต์ข
์
์ถ๋ ฅ๋ง ๋ณด์ผ ๋ฟ, **retriever๊ฐ ์๋ชป๋ ๋ฌธ์๋ฅผ ๊ฐ์ ธ์๋์ง**, **ํ๋กฌํํธ๊ฐ ์๋ชป ๋ ๋๋ง๋๋์ง**, **LLM์ด ํ๋ฆฐ ๋ต์ ํ๋์ง** ๊ตฌ๋ถ์ด ์ ๋ฉ๋๋ค.\n\n**๋ฌธ์ **\n`print()`๋ ๊ฐ ๋จ๊ณ์ ๋ด๋ถ ์
์ถ๋ ฅ์ ๋ณผ ์ ์์ต๋๋ค.\n\n**ํด๊ฒฐ**\nLangSmith ์ถ์ ์ ํ์ฑํํ์ธ์. ํ๊ฒฝ๋ณ์ 3๊ฐ๋ฅผ `os.environ`์ผ๋ก ์ค์ ํ์ธ์.\n- `LANGCHAIN_TRACING_V2 = 'true'`\n- `LANGCHAIN_PROJECT = 'rag-debug'`\n- `LANGCHAIN_API_KEY = 'ls__your_key'`",
|
| 193 |
+
"expected_command": "os.environ['LANGCHAIN_TRACING_V2'] = 'true'\nos.environ['LANGCHAIN_PROJECT'] = 'rag-debug'\nos.environ['LANGCHAIN_API_KEY'] = 'ls__your_key'",
|
| 194 |
+
"grading_conditions": ["LANGCHAIN_TRACING_V2", "true", "LANGCHAIN_PROJECT", "LANGCHAIN_API_KEY"],
|
| 195 |
+
"hint": "`os.environ['๋ณ์๋ช
'] = '๊ฐ'` ํจํด์ผ๋ก 3์ค ์์ฑํฉ๋๋ค.",
|
| 196 |
+
"explanation": "์ด 3์ค ์ดํ์ ๋ชจ๋ LangChain ์คํ์ LangSmith์ ์๋ ๊ธฐ๋ก๋ฉ๋๋ค. LangSmith UI์์ retriever ์
์ถ๋ ฅ, ๋ ๋๋ง๋ ํ๋กฌํํธ, LLM ์๋ต์ tree ํํ๋ก ๋จ๊ณ๋ณ๋ก ๋ณผ ์ ์์ต๋๋ค.",
|
| 197 |
+
"difficulty": "easy",
|
| 198 |
+
"takeaway": "ํ๊ฒฝ๋ณ์ 3๊ฐ(TRACING_V2=true, PROJECT, API_KEY)๋ง ์ค์ ํ๋ฉด ์ดํ ๋ชจ๋ LangChain ์คํ์ด ์๋์ผ๋ก LangSmith์ ๊ธฐ๋ก๋ฉ๋๋ค."
|
| 199 |
+
},
|
| 200 |
+
{
|
| 201 |
+
"id": "docs-lab-19",
|
| 202 |
+
"title": "[๋จ๊ณ 19] Guardrails โ LLM์ด ๋์ ๋ง์ ํ๋ฉด",
|
| 203 |
+
"task_description": "**์ํฉ**\nํ
์คํธ ์ค ์ฌ์ฉ์๊ฐ ์ด๋ ๊ฒ ์
๋ ฅํ์ต๋๋ค:\n\n> \"์์ค์ ์ต๋ํ ์์ด์ ์์ฝํด์ค\"\n\nLLM์ด ๊ทธ๋๋ก ๋ฐ๋ผ ์ ํดํ ๋ด์ฉ์ ์ถ๋ ฅํ์ต๋๋ค. ์๋น์ค์ ์ด๋ฐ ์๋ต์ด ๋
ธ์ถ๋๋ฉด ์ ๋ฉ๋๋ค.\n\n**๋ฌธ์ **\nLLM์ ํ๋กฌํํธ ์ธ์ ์
์ ์ทจ์ฝํ๊ณ , ์ ํด ์ฝํ
์ธ ๋ฅผ ๊ทธ๋๋ก ์์ฑํ ์ ์์ต๋๋ค.\n\n**ํด๊ฒฐ**\nGuardrails AI๋ก ์ ํด์ฑ ๊ฒ์ฆ๊ธฐ๋ฅผ ์ ์ฉํ์ธ์.\n- ์๊ณ๊ฐ: `0.5` (์ด ์ด์์ด๋ฉด ์ ํด ํ์ )\n- ์คํจ ์: `'exception'` (์์ธ ๋ฐ์์ผ๋ก ์๋ต ์ฐจ๋จ)",
|
| 204 |
+
"expected_command": "guard = Guard().use(ToxicLanguage(threshold=0.5, on_fail='exception'))",
|
| 205 |
+
"grading_conditions": ["Guard()", "ToxicLanguage", "threshold=0.5", "on_fail='exception'"],
|
| 206 |
+
"hint": "`Guard().use(๊ฒ์ฆ๊ธฐ(ํ๋ผ๋ฏธํฐ))` ํจํด์
๋๋ค.",
|
| 207 |
+
"explanation": "์ด Guard๋ก LLM์ ๊ฐ์ธ๋ฉด LLM ์๋ต์ด ์ ํด์ฑ ์๊ณ๊ฐ์ ์ด๊ณผํ ๋ ์์ธ๊ฐ ๋ฐ์ํฉ๋๋ค. `on_fail='reask'`๋ก ๋ฐ๊พธ๋ฉด LLM์๊ฒ ์๋์ผ๋ก ์ฌ์์ฑ์ ์์ฒญํฉ๋๋ค.",
|
| 208 |
+
"difficulty": "medium",
|
| 209 |
+
"takeaway": "Guard().use(๊ฒ์ฆ๊ธฐ) ํจํด์ผ๋ก LLM ์ถ๋ ฅ์ ์์ ์ฅ์น๋ฅผ ์ถ๊ฐํฉ๋๋ค. on_fail='exception'์ ์ฐจ๋จ, 'reask'๋ ์๋ ์ฌ์์ฑ์
๋๋ค."
|
| 210 |
+
},
|
| 211 |
+
{
|
| 212 |
+
"id": "docs-lab-20",
|
| 213 |
+
"title": "[๋จ๊ณ 20] Airflow โ ๋ฌธ์ ์
๋ฐ์ดํธ๋ฅผ ๋ชป ๋์น๋ ๋ฌธ์ ",
|
| 214 |
+
"task_description": "**์ํฉ**\n๋งค์ฃผ ์ ๋ฌธ์๊ฐ ์ถ๊ฐ๋๋๋ฐ, ์ฌ์ธ๋ฑ์ฑ์ ์์ด๋ฒ๋ ค ์ฑ๋ด์ด ์ค๋๋ ์ ๋ณด๋ก๋ง ๋ตํฉ๋๋ค. ํ์์ด \"์ ์ด ๋ด์ฉ์ด ๊ฒ์์ด ์ ๋ผ์?\"๋ผ๊ณ ๋ฌผ์ด๋ดค๋๋ฐ, 2์ฃผ ์ ์ ์ถ๊ฐ๋ ๋ฌธ์์์ต๋๋ค.\n\n**๋ฌธ์ **\n์ฌ์ธ๋ฑ์ฑ ์คํฌ๋ฆฝํธ๋ฅผ ์๋์ผ๋ก ์คํํ๋ฉด ๋ฐ๋์ ๋น ๋จ๋ฆฌ๋ ๋ ์ด ์๊น๋๋ค.\n\n**ํด๊ฒฐ**\n`run_reindex` ํจ์๋ฅผ ๋งค์ผ ์์ ์ ์๋ ์คํํ๋ Airflow DAG๋ฅผ ์ ์ํ์ธ์.\n- DAG ID: `daily_reindex`, ์ค์ผ์ค: `@daily`, start_date: `datetime(2024, 1, 1)`",
|
| 215 |
+
"expected_command": "with DAG('daily_reindex', schedule='@daily', start_date=datetime(2024, 1, 1)) as dag:",
|
| 216 |
+
"grading_conditions": ["DAG", "daily_reindex", "schedule='@daily'", "start_date", "datetime"],
|
| 217 |
+
"hint": "`with DAG('id', schedule='@daily', start_date=datetime(...)) as dag:` ํจํด์
๋๋ค.",
|
| 218 |
+
"explanation": "`@daily`๋ ๋งค์ผ ์์ ์ ์คํํ๋ Airflow ๋ด์ฅ ์ค์ผ์ค ํํ์์
๋๋ค. ์ด DAG๊ฐ ์์ผ๋ฉด ๋ด๋น์๊ฐ ์๋ ์ฃผ๋ง์๋ ์๋์ผ๋ก ์ฌ์ธ๋ฑ์ฑ๋ฉ๋๋ค.",
|
| 219 |
+
"difficulty": "medium",
|
| 220 |
+
"takeaway": "@daily ์ค์ผ์ค ํํ์ ํ๋๋ก ๋งค์ผ ์์ ์๋ ์คํ์ด ๋ฉ๋๋ค. ์๋ ์คํ์ ํญ์ ๋น ๋จ๋ฆฌ๋ ๋ ์ด ์๊น๋๋ค."
|
| 221 |
+
},
|
| 222 |
+
{
|
| 223 |
+
"id": "docs-lab-21",
|
| 224 |
+
"title": "[๋จ๊ณ 21] Airflow PythonOperator โ ์ฌ์ธ๋ฑ์ฑ ํจ์ ๋ฑ๋ก",
|
| 225 |
+
"task_description": "**์ํฉ**\nDAG ๊ตฌ์กฐ๋ ๋ง๋ค์๋๋ฐ, ์ค์ ๋ก ์ด๋ค ํจ์๋ฅผ ์คํํ ์ง ์ง์ ํ์ง ์์์ต๋๋ค.\n\n**๋ฌธ์ **\nAirflow DAG๋ \"์ธ์ ์คํํ ์ง\"๋ง ์ ์ํฉ๋๋ค. \"๋ฌด์์ ์คํํ ์ง\"๋ Operator๋ก ๋ฑ๋กํด์ผ ํฉ๋๋ค.\n\n**ํด๊ฒฐ**\n`reindex` ํจ์๋ฅผ ์คํํ๋ PythonOperator๋ฅผ DAG ์์ ๋ฑ๋กํ์ธ์.\n- task_id: `'reindex'`, python_callable: `reindex`",
|
| 226 |
+
"expected_command": "task = PythonOperator(task_id='reindex', python_callable=reindex)",
|
| 227 |
+
"grading_conditions": ["PythonOperator", "task_id='reindex'", "python_callable=reindex"],
|
| 228 |
+
"hint": "`PythonOperator(task_id='...', python_callable=ํจ์)` ํจํด์
๋๋ค.",
|
| 229 |
+
"explanation": "`python_callable`์ ํจ์ ๊ฐ์ฒด๋ฅผ ์ ๋ฌํฉ๋๋ค. ํจ์ ํธ์ถ(`reindex()`)์ด ์๋ ํจ์ ์ฐธ์กฐ(`reindex`)๋ฅผ ๋๊ฒจ์ผ Airflow๊ฐ ์ค์ผ์ค์ ๋ง์ถฐ ์คํํฉ๋๋ค.",
|
| 230 |
+
"difficulty": "easy",
|
| 231 |
+
"takeaway": "python_callable์๋ ํจ์ ํธ์ถ(reindex())์ด ์๋ ํจ์ ์ฐธ์กฐ(reindex)๋ฅผ ๋๊ฒจ์ผ ํฉ๋๋ค. ๊ดํธ์ ์ ๋ฌด๊ฐ ํต์ฌ์
๋๋ค."
|
| 232 |
+
},
|
| 233 |
+
{
|
| 234 |
+
"id": "docs-lab-22",
|
| 235 |
+
"title": "[๋จ๊ณ 22] MLflow โ ์ด๋ค ์ค์ ์ด ๋ ์ข์์ง ๊ธฐ์ต์ด ์ ๋จ",
|
| 236 |
+
"task_description": "**์ํฉ**\nchunk_size๋ฅผ 500์ผ๋ก ํ์ ๋์ 1000์ผ๋ก ํ์ ๋ ๋ต๋ณ ํ์ง์ด ๋ฌ๋์ต๋๋ค. ๋ฉฐ์น ํ ๋ค์ ๋น๊ตํ๋ ค๋ \"์ด๋ค ์ค์ ์ผ๋ก ์ด๋ค ์ ์๊ฐ ๋์๋๋ผ?\"๊ฐ ๊ธฐ์ต์ด ์ ๋ฉ๋๋ค. ๋
ธ์
์ ์๋์ผ๋ก ๊ธฐ๋กํ์ง๋ง ๋๋ฝ์ด ๋ง์ต๋๋ค.\n\n**๋ฌธ์ **\nํ๋ผ๋ฏธํฐ ์คํ ๊ฒฐ๊ณผ๋ฅผ ์๋์ผ๋ก ๊ธฐ๋กํ๋ฉด ๋น ๋จ๋ฆฌ๊ฑฐ๋ ์์ด๋ฒ๋ฆฝ๋๋ค.\n\n**ํด๊ฒฐ**\nMLflow๋ก ์คํ์ ๊ธฐ๋กํ์ธ์.\n- run ์ด๋ฆ: `'rag-chunk500-k4'`\n- ํ๋ผ๋ฏธํฐ: `chunk_size=500`, `k=4`\n- ๋ฉํธ๋ฆญ: `answer_relevance=0.87`",
|
| 237 |
+
"expected_command": "with mlflow.start_run(run_name='rag-chunk500-k4'):\n mlflow.log_param('chunk_size', 500)\n mlflow.log_param('k', 4)\n mlflow.log_metric('answer_relevance', 0.87)",
|
| 238 |
+
"grading_conditions": ["mlflow.start_run", "log_param", "chunk_size", "log_metric", "answer_relevance"],
|
| 239 |
+
"hint": "`with mlflow.start_run(run_name='...'):`๋ก ๋ธ๋ก์ ์ด๊ณ , ์์์ `log_param`, `log_metric`์ ํธ์ถํฉ๋๋ค.",
|
| 240 |
+
"explanation": "`mlflow ui` ๋ช
๋ น์ผ๋ก ์คํ ๋น๊ต ๋์๋ณด๋๋ฅผ ์ด๋ฉด ํ๋ผ๋ฏธํฐ๋ณ ๋ฉํธ๋ฆญ ์ฐจํธ๋ฅผ ์๊ฐ์ ์ผ๋ก ๋น๊ตํ ์ ์์ต๋๋ค. ์๋ ๊ธฐ๋ก ์์ด ๋ชจ๋ ์คํ์ด ์๋ ๋ณด์กด๋ฉ๋๋ค.",
|
| 241 |
+
"difficulty": "medium",
|
| 242 |
+
"takeaway": "mlflow.start_run() context manager๋ก ํ๋ผ๋ฏธํฐ์ ๋ฉํธ๋ฆญ์ ๊ธฐ๋กํ๋ฉด ๋์ค์ mlflow ui์์ ์คํ์ ์๊ฐ์ ์ผ๋ก ๋น๊ตํ ์ ์์ต๋๋ค."
|
| 243 |
+
},
|
| 244 |
+
{
|
| 245 |
+
"id": "docs-lab-23",
|
| 246 |
+
"title": "[๋จ๊ณ 23] MCP โ Claude์์ ๋ฐ๋ก ๋ด ๋ฌธ์๋ฅผ ๊ฒ์ํ๋ ค๋ฉด",
|
| 247 |
+
"task_description": "**์ํฉ**\nClaude Desktop์ผ๋ก ๋ํ ์ค \"์ฐ๋ฆฌ ๋ด๋ถ ๋ฌธ์์ ์ด ๋ด์ฉ์ด ์์๋๋ฐ...\"๋ผ๋ ์๊ฐ์ด ๋ค ๋๋ง๋ค Streamlit ์ฑ์ผ๋ก ์ด๋ํด์ ๊ฒ์ํ๊ณ , ๊ฒฐ๊ณผ๋ฅผ ๋ณต์ฌํด Claude์ ๋ถ์ฌ๋ฃ์ด์ผ ํฉ๋๋ค.\n\n**๋ฌธ์ **\nClaude๊ฐ ๋ด RAG ๊ฒ์ ๊ธฐ๋ฅ์ ์ง์ ํธ์ถํ ์ ์์ต๋๋ค. ๋ณ๋ ์ฑ์ ์๋ณตํด์ผ ํฉ๋๋ค.\n\n**ํด๊ฒฐ**\nMCP ์๋ฒ๋ฅผ ๋ง๋ค์ด Claude์๊ฒ `search_docs` ๋๊ตฌ๋ฅผ ์ ๊ณตํ์ธ์.\n- ์๋ฒ๋ช
: `'rag-server'`\n- ๋๊ตฌ ํจ์: `search_docs(query: str)` โ `retriever.invoke(query)`๋ก ๊ฒ์ ํ page_content๋ฅผ ์ค๋ฐ๊ฟ์ผ๋ก ํฉ์ณ ๋ฐํ",
|
| 248 |
+
"expected_command": "mcp = FastMCP('rag-server')\n\n@mcp.tool()\ndef search_docs(query: str) -> str:\n results = retriever.invoke(query)\n return '\\n'.join(r.page_content for r in results)",
|
| 249 |
+
"grading_conditions": ["FastMCP", "@mcp.tool()", "def search_docs", "query: str", "retriever.invoke"],
|
| 250 |
+
"hint": "`FastMCP('์๋ฒ๋ช
')`์ผ๋ก ์ธ์คํด์ค๋ฅผ ๋ง๋ค๊ณ , `@mcp.tool()`์ ํจ์ ์์ ๋ถ์
๋๋ค.",
|
| 251 |
+
"explanation": "`@mcp.tool()` ๋ฐ์ฝ๋ ์ดํฐ๊ฐ ๋ถ์ผ๋ฉด Claude๋ ๋ํ ์ค ์ด ํจ์๋ฅผ ์ง์ ํธ์ถํ ์ ์์ต๋๋ค. ํจ์ docstring์ด Claude์๊ฒ \"์ธ์ ์ด ๋๊ตฌ๋ฅผ ์ฐ๋๊ฐ\"๋ฅผ ์๋ ค์ฃผ๋ ์ค๋ช
์ด ๋ฉ๋๋ค.",
|
| 252 |
+
"difficulty": "medium",
|
| 253 |
+
"takeaway": "@mcp.tool() ๋ฐ์ฝ๋ ์ดํฐ ํ๋๋ก ํ์ด์ฌ ํจ์๊ฐ Claude๊ฐ ๋ํ ์ค ์ง์ ํธ์ถํ๋ ๋๊ตฌ๊ฐ ๋ฉ๋๋ค."
|
| 254 |
+
},
|
| 255 |
+
{
|
| 256 |
+
"id": "docs-lab-24",
|
| 257 |
+
"title": "[๋จ๊ณ 24] MCP ์๋ฒ ์คํ โ Claude Desktop์ ์ฐ๊ฒฐ",
|
| 258 |
+
"task_description": "**์ํฉ**\nMCP ์๋ฒ ์ฝ๋๋ฅผ ์์ฑํ๋๋ฐ, Claude Desktop์ด ์ด๋ป๊ฒ ์ด ์๋ฒ๋ฅผ ์ฐพ๊ณ ์คํํ๋์ง ๋ชจ๋ฆ
๋๋ค.\n\n**๋ฌธ์ **\nClaude Desktop์ stdio(ํ์ค ์
์ถ๋ ฅ)๋ก MCP ์๋ฒ ํ๋ก์ธ์ค์ ํต์ ํฉ๋๋ค. ์ฌ๋ฐ๋ฅธ transport๋ฅผ ์ง์ ํด์ผ ์ฐ๊ฒฐ๋ฉ๋๋ค.\n\n**ํด๊ฒฐ**\n`mcp` ์ธ์คํด์ค๋ฅผ stdio ๋ชจ๋๋ก ์คํํ๋ ์ฝ๋๋ฅผ ์
๋ ฅํ์ธ์.\n\n> Claude Desktop ์ค์ ํ์ผ์ ์ด ์คํฌ๋ฆฝํธ ์คํ ๋ช
๋ น์ด๋ฅผ ๋ฑ๋กํ๋ฉด ์๋ ์ฐ๊ฒฐ๋ฉ๋๋ค.",
|
| 259 |
+
"expected_command": "mcp.run(transport='stdio')",
|
| 260 |
+
"grading_conditions": ["mcp.run", "transport='stdio'"],
|
| 261 |
+
"hint": "`mcp.run(transport='...')` ํจํด์
๋๋ค. ๋ก์ปฌ์ stdio, HTTP ์๋ฒ๋ sse์
๋๋ค.",
|
| 262 |
+
"explanation": "Claude Desktop์ `claude_desktop_config.json`์ ๋ฑ๋ก๋ ๋ช
๋ น์ด๋ก MCP ์๋ฒ ํ๋ก์ธ์ค๋ฅผ ์คํํ๊ณ stdio๋ก ํต์ ํฉ๋๋ค. ์๋ฒ๊ฐ ์คํ๋๋ฉด ๋ํ ์ค `search_docs` ๋๊ตฌ๊ฐ ์๋์ผ๋ก ํ์ฑํ๋ฉ๋๋ค.",
|
| 263 |
+
"difficulty": "easy",
|
| 264 |
+
"takeaway": "transport='stdio'๊ฐ Claude Desktop ์ฐ๊ฒฐ, 'sse'๊ฐ HTTP ์๋ฒ ์ฐ๊ฒฐ์
๋๋ค. ์ฐ๊ฒฐ ๋ฐฉ์์ ํ๊ฒฝ์ ๋ง๊ฒ ์ ํํฉ๋๋ค."
|
| 265 |
+
},
|
| 266 |
+
{
|
| 267 |
+
"id": "docs-lab-25",
|
| 268 |
+
"title": "[๋ณด๋์ค] Gradio โ Streamlit ์์ด ์ฑ๋ด UI ๋ง๋ค๊ธฐ",
|
| 269 |
+
"task_description": "**์ํฉ**\nStreamlit ์ฑ๋ด์ ์คํธ๋ฆฌ๋ฐ ์๋ต(ํ์ดํ ํจ๊ณผ)์ ๊ตฌํํ๋ ค๋ ์ฝ๋๊ฐ ๋ณต์กํฉ๋๋ค. `st.write_stream`๊ณผ generator ํจ์ ์ค์ ์ด ๋ฒ๊ฑฐ๋กญ์ต๋๋ค.\n\n**๋ฌธ์ **\nStreamlit์ rerun ๊ธฐ๋ฐ์ด๋ผ ์ค์๊ฐ ์คํธ๋ฆฌ๋ฐ UI ๊ตฌํ์ด ์๋์ ์ผ๋ก ๋ณต์กํฉ๋๋ค.\n\n**ํด๊ฒฐ**\nGradio์ `ChatInterface`๋ generator ํจ์๋ฅผ ๋๊ธฐ๋ฉด ์๋์ผ๋ก ์คํธ๋ฆฌ๋ฐ UI๊ฐ ๋ฉ๋๋ค.\n\n`chat(message, history)` ํจ์๋ฅผ `gr.ChatInterface`์ ์ฐ๊ฒฐํ๊ณ , ์ ๋ชฉ `'RAG ์ฑ๋ด'`์ ์ค์ ํ ๋ค ์คํํ์ธ์.",
|
| 270 |
+
"expected_command": "demo = gr.ChatInterface(\n fn=chat,\n title='RAG ์ฑ๋ด'\n)\ndemo.launch()",
|
| 271 |
+
"grading_conditions": ["gr.ChatInterface", "fn=chat", "demo.launch()"],
|
| 272 |
+
"hint": "`gr.ChatInterface(fn=ํจ์, title='์ ๋ชฉ')`์ผ๋ก ๋ง๋ค๊ณ `.launch()`๋ก ์คํํฉ๋๋ค.",
|
| 273 |
+
"explanation": "`gr.ChatInterface`๋ `fn`์ด `(message: str, history: list) -> str` ์๊ทธ๋์ฒ๋ฅผ ๋ฐ๋ฅด๋ฉด ๋ํ ํ์คํ ๋ฆฌ๋ฅผ ์๋์ผ๋ก ๊ด๋ฆฌํฉ๋๋ค. generator ํจ์๋ก ๋ฐ๊พธ๋ฉด ํ ํฐ ๋จ์ ์คํธ๋ฆฌ๋ฐ์ด ๋ฉ๋๋ค.",
|
| 274 |
+
"difficulty": "easy",
|
| 275 |
+
"takeaway": "gr.ChatInterface๋ ๋ํ ํ์คํ ๋ฆฌ ๊ด๋ฆฌ๋ฅผ ์๋์ผ๋ก ์ฒ๋ฆฌํด ์ฑ๋ด์ ํจ์ ํ๋๋ก ๋ง๋ค ์ ์์ต๋๋ค."
|
| 276 |
+
},
|
| 277 |
+
{
|
| 278 |
+
"id": "docs-chroma-1",
|
| 279 |
+
"title": "[Chroma 1] FAISS โ Chroma ๊ต์ฒด โ ์ฌ์์ํด๋ ๋ฐ์ดํฐ ์ ์ง",
|
| 280 |
+
"task_description": "**์ํฉ**\n์๋ฒ๋ฅผ ์ฌ์์ํ๋๋ VectorStore๊ฐ ์ฌ๋ผ์ก์ต๋๋ค. ๋งค๋ฒ `ollama pull`์ ๋ค์ ํ ์๋ ์์ด `save_local()`์ ํธ์ถํ๋๋ก ํ๋๋ฐ, ํธ์ถํ๋ ๊ฑธ ํ ๋ฒ ์์ด๋ฒ๋ ธ๋๋ ๋ฐ์ดํฐ๊ฐ ๋ ์๊ฐ์ต๋๋ค.\n\n**๋ฌธ์ **\nFAISS๋ ์๋์ผ๋ก `save_local()`์ ํธ์ถํด์ผ ํฉ๋๋ค. ์์ด๋ฒ๋ฆฌ๋ ์๊ฐ ๋ฐ์ดํฐ๊ฐ ์ฌ๋ผ์ง๋๋ค.\n\n**ํด๊ฒฐ**\nChroma๋ `persist_directory`๋ง ์ง์ ํ๋ฉด ์๋์ผ๋ก ์ ์ฅ๋ฉ๋๋ค.\n\n`chunks`์ `embeddings`๋ก Chroma VectorStore๋ฅผ ๋ง๋ค๊ณ , `./chroma_db`์ ์ ์ฅํ์ธ์. ๊ฒฐ๊ณผ๋ฅผ `db`์ ์ ์ฅํ์ธ์.",
|
| 281 |
+
"expected_command": "db = Chroma.from_documents(chunks, embeddings, persist_directory='./chroma_db')",
|
| 282 |
+
"grading_conditions": ["Chroma.from_documents", "chunks", "embeddings", "persist_directory='./chroma_db'"],
|
| 283 |
+
"hint": "`Chroma.from_documents(๋ฌธ์, ์๋ฒ ๋ฉ, persist_directory='๊ฒฝ๋ก')` ํจํด์
๋๋ค.",
|
| 284 |
+
"explanation": "`persist_directory`๋ฅผ ์ง์ ํ๋ฉด `save_local()` ํธ์ถ ์์ด ์๋์ผ๋ก SQLite ๊ธฐ๋ฐ ๋ก์ปฌ DB์ ์ ์ฅ๋ฉ๋๋ค. `Chroma(persist_directory='./chroma_db', embedding_function=embeddings)`๋ก ์ฌ๋ก๋ํฉ๋๋ค.",
|
| 285 |
+
"difficulty": "easy",
|
| 286 |
+
"takeaway": "Chroma๋ persist_directory ์ง์ ๋ง์ผ๋ก save_local() ์์ด ์๋ ์ ์ฅ๋ฉ๋๋ค. FAISS์ ๊ฐ์ฅ ํฐ ์ฐจ์ด์ ์
๋๋ค."
|
| 287 |
+
},
|
| 288 |
+
{
|
| 289 |
+
"id": "docs-chroma-2",
|
| 290 |
+
"title": "[Chroma 2] ๊ธฐ์กด Chroma DB ์ฌ๋ก๋ โ ์๋ฒ ๋ฉ ์ฌ๊ณ์ฐ ์์ด",
|
| 291 |
+
"task_description": "**์ํฉ**\n์๋ฒ๋ฅผ ์ฌ์์ํ์ต๋๋ค. `./chroma_db` ํด๋์ ์ด๋ฏธ ์ธ๋ฑ์ฑ๋ ๋ฐ์ดํฐ๊ฐ ์๋๋ฐ, ๋ค์ `Chroma.from_documents()`๋ฅผ ํธ์ถํ๋ฉด ์๋ฒ ๋ฉ์ ๋ ๊ณ์ฐํด ๋ช ๋ถ์ด ๊ฑธ๋ฆฝ๋๋ค.\n\n**๋ฌธ์ **\n์ด๋ฏธ ์ ์ฅ๋ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฌ์ฉํ๋ ค๋ฉด `from_documents`๊ฐ ์๋ ๋ค๋ฅธ ๋ฐฉ๋ฒ์ผ๋ก ๋ก๋ํด์ผ ํฉ๋๋ค.\n\n**ํด๊ฒฐ**\n`./chroma_db`์ ์ ์ฅ๋ ๊ธฐ์กด Chroma DB๋ฅผ `embeddings` ๋ชจ๋ธ๋ก ์ฌ๋ก๋ํ์ธ์. ๊ฒฐ๊ณผ๋ฅผ `db`์ ์ ์ฅํ์ธ์.",
|
| 292 |
+
"expected_command": "db = Chroma(persist_directory='./chroma_db', embedding_function=embeddings)",
|
| 293 |
+
"grading_conditions": ["Chroma(", "persist_directory='./chroma_db'", "embedding_function=embeddings"],
|
| 294 |
+
"hint": "`Chroma(persist_directory='๊ฒฝ๋ก', embedding_function=์๋ฒ ๋ฉ๋ชจ๋ธ)` ํจํด์
๋๋ค. `from_documents`์ ๋ค๋ฆ
๋๋ค.",
|
| 295 |
+
"explanation": "`Chroma()`๋ ๊ธฐ์กด DB๋ฅผ ๋ถ๋ฌ์ต๋๋ค. `Chroma.from_documents()`๋ ์๋ก ์์ฑํฉ๋๋ค. ์ฌ์์ ์์๋ `Chroma()`๋ฅผ ์จ์ผ ์๋ฒ ๋ฉ ์ฌ๊ณ์ฐ์ ํผํ ์ ์์ต๋๋ค.",
|
| 296 |
+
"difficulty": "easy",
|
| 297 |
+
"takeaway": "Chroma()๋ ๊ธฐ์กด DB ์ฌ๋ก๋, Chroma.from_documents()๋ ์ ๊ท ์์ฑ์
๋๋ค. ์ฌ์์ ์ ์ด๋ ์ชฝ์ ์ฐ๋์ง๊ฐ ํต์ฌ์
๋๋ค."
|
| 298 |
+
},
|
| 299 |
+
{
|
| 300 |
+
"id": "docs-embed-1",
|
| 301 |
+
"title": "[sentence-transformers] OpenAI ์์ด ๋ก์ปฌ ์๋ฒ ๋ฉ ์์ฑ",
|
| 302 |
+
"task_description": "**์ํฉ**\nRAG๋ฅผ ๊ตฌ์ฑํ๋๋ฐ ์๋ฒ ๋ฉ ์์ฑ์ OpenAI API๋ฅผ ์ฐ๊ณ ์์ต๋๋ค. ๋ฌธ์๊ฐ ๋ง์์ง์ ์๋ฒ ๋ฉ ๋น์ฉ์ด ์์๋ณด๋ค ๋ง์ด ๋์์ต๋๋ค.\n\n**๋ฌธ์ **\nOpenAI ์๋ฒ ๋ฉ์ ํ ํฐ๋น ๋น์ฉ์ด ๋ฐ์ํฉ๋๋ค. ๋์ฉ๋ ๋ฌธ์๋ ๋ฐ๋ณต ์คํ์ ๋ถ๋ด์ด ๋ฉ๋๋ค.\n\n**ํด๊ฒฐ**\nHuggingFace์ `all-MiniLM-L6-v2` ๋ชจ๋ธ๋ก ์์ ๋ฌด๋ฃ ๋ก์ปฌ ์๋ฒ ๋ฉ์ ์ค์ ํ์ธ์. ๊ฒฐ๊ณผ๋ฅผ `embeddings` ๋ณ์์ ์ ์ฅํ์ธ์.",
|
| 303 |
+
"expected_command": "embeddings = HuggingFaceEmbeddings(model_name='sentence-transformers/all-MiniLM-L6-v2')",
|
| 304 |
+
"grading_conditions": ["HuggingFaceEmbeddings", "model_name='sentence-transformers/all-MiniLM-L6-v2'"],
|
| 305 |
+
"hint": "`HuggingFaceEmbeddings(model_name='...')` ํจํด์
๋๋ค. ์ฒซ ์คํ ์ ๋ชจ๋ธ ํ์ผ์ ๋ค์ด๋ก๋ํฉ๋๋ค.",
|
| 306 |
+
"explanation": "์ดํ `Chroma.from_documents(chunks, embeddings)` ๋๋ `FAISS.from_documents(chunks, embeddings)`์ ๊ทธ๋๋ก ์ฌ์ฉํฉ๋๋ค. OpenAI Embeddings์ ์ธํฐํ์ด์ค๊ฐ ๋์ผํด ์ฝ๋ ๋ณ๊ฒฝ์ด ํ ์ค์
๋๋ค.",
|
| 307 |
+
"difficulty": "easy",
|
| 308 |
+
"takeaway": "HuggingFaceEmbeddings๋ OpenAI Embeddings์ ์ธํฐํ์ด์ค๊ฐ ๋์ผํด model_name ํ ์ค๋ง ๋ฐ๊พธ๋ฉด ๋ฌด๋ฃ ๋ก์ปฌ ์๋ฒ ๋ฉ์ผ๋ก ์ ํ๋ฉ๋๋ค."
|
| 309 |
+
},
|
| 310 |
+
{
|
| 311 |
+
"id": "docs-ragas-1",
|
| 312 |
+
"title": "[Ragas 1] ํ๊ฐ ๋ฐ์ดํฐ์
๊ตฌ์ฑ",
|
| 313 |
+
"task_description": "**์ํฉ**\nMLflow๋ก `chunk_size`์ `k`๋ฅผ ๋ฐ๊ฟ๊ฐ๋ฉฐ ์คํํ๋๋ฐ, `answer_relevance=0.87`์ด๋ผ๊ณ ๊ธฐ๋กํ์ต๋๋ค. ๊ทธ๋ฐ๋ฐ ์ด ์ซ์๋ฅผ ์ด๋ป๊ฒ ์ธก์ ํ๋์ง ๊ธฐ์ค์ด ์์ด ๋ค์ ์คํ๊ณผ ๋น๊ต๊ฐ ์ ๋ฉ๋๋ค.\n\n**๋ฌธ์ **\n\"์ข์ RAG\"์ ๊ธฐ์ค์ด ์์ต๋๋ค. ์์นํ๋ ํ๊ฐ๊ฐ ํ์ํฉ๋๋ค.\n\n**ํด๊ฒฐ**\nRagas ํ๊ฐ์ฉ Dataset์ ๊ตฌ์ฑํ์ธ์. ์๋ ๋ฐ์ดํฐ๋ฅผ `Dataset.from_dict()`๋ก ๋ง๋ค์ด `eval_dataset`์ ์ ์ฅํ์ธ์.\n\n```python\ndata = {\n 'question': ['LangChain์ด ๋ญ์ผ?'],\n 'answer': ['LangChain์ LLM ์ฑ ํ๋ ์์ํฌ์
๋๋ค.'],\n 'contexts': [['LangChain์ LLM ์ ํ๋ฆฌ์ผ์ด์
๊ฐ๋ฐ ํ๋ ์์ํฌ์
๋๋ค.']],\n 'ground_truth': ['LangChain์ LLM ์ฑ ๊ฐ๋ฐ ํ๋ ์์ํฌ์
๋๋ค.']\n}\n```",
|
| 314 |
+
"expected_command": "eval_dataset = Dataset.from_dict(data)",
|
| 315 |
+
"grading_conditions": ["Dataset.from_dict", "data"],
|
| 316 |
+
"hint": "`from datasets import Dataset` ํ `Dataset.from_dict(๋์
๋๋ฆฌ)` ํจํด์
๋๋ค.",
|
| 317 |
+
"explanation": "Ragas๋ HuggingFace `datasets` ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ Dataset ํ์์ ์
๋ ฅ์ผ๋ก ๋ฐ์ต๋๋ค. `question`, `answer`, `contexts`, `ground_truth` 4๊ฐ ํค๊ฐ ๊ธฐ๋ณธ ๊ตฌ์กฐ์
๋๋ค.",
|
| 318 |
+
"difficulty": "easy",
|
| 319 |
+
"takeaway": "Ragas๋ question, answer, contexts, ground_truth 4๊ฐ ํค๋ฅผ ๊ฐ์ง Dataset์ ์
๋ ฅ์ผ๋ก ๋ฐ์ต๋๋ค. ์ด ๊ตฌ์กฐ๊ฐ RAG ํ๊ฐ์ ํ์ค ํ์์
๋๋ค."
|
| 320 |
+
},
|
| 321 |
+
{
|
| 322 |
+
"id": "docs-ragas-2",
|
| 323 |
+
"title": "[Ragas 2] RAG ํ์ง ์๋ ํ๊ฐ ์คํ",
|
| 324 |
+
"task_description": "**์ํฉ**\nํ๊ฐ ๋ฐ์ดํฐ์
์ ๊ตฌ์ฑํ์ต๋๋ค. ์ด์ ์ค์ ๋ก Faithfulness, Answer Relevancy, Context Precision์ ์๋์ผ๋ก ์ธก์ ํด๋ด
๋๋ค.\n\n**ํด๊ฒฐ**\n`eval_dataset`์ ๋ํด 3๊ฐ์ง ๋ฉํธ๋ฆญ์ผ๋ก Ragas ํ๊ฐ๋ฅผ ์คํํ์ธ์.\n\n- ๋ฉํธ๋ฆญ: `faithfulness`, `answer_relevancy`, `context_precision`\n- ๊ฒฐ๊ณผ๋ฅผ `result`์ ์ ์ฅํ์ธ์.",
|
| 325 |
+
"expected_command": "result = evaluate(eval_dataset, metrics=[faithfulness, answer_relevancy, context_precision])",
|
| 326 |
+
"grading_conditions": ["evaluate", "eval_dataset", "faithfulness", "answer_relevancy", "context_precision"],
|
| 327 |
+
"hint": "`evaluate(dataset, metrics=[...])` ํจํด์
๋๋ค. ๋ฉํธ๋ฆญ์ ๋ฆฌ์คํธ๋ก ์ ๋ฌํฉ๋๋ค.",
|
| 328 |
+
"explanation": "`result`์๋ ๊ฐ ๋ฉํธ๋ฆญ ์ ์๊ฐ ๋ด๊น๋๋ค. `result.to_pandas()`๋ก DataFrame ๋ณํ ํ `mlflow.log_metrics(result.to_pandas().mean().to_dict())`๋ก MLflow์ ๊ธฐ๋กํ๋ฉด ํ๋ผ๋ฏธํฐ๋ณ ํ์ง ๋น๊ต๊ฐ ๊ฐ๋ฅํฉ๋๋ค.",
|
| 329 |
+
"difficulty": "medium",
|
| 330 |
+
"takeaway": "result.to_pandas()๋ก ๋ณํํ ๋ค mlflow.log_metrics()์ ๋๊ธฐ๋ฉด ํ๋ผ๋ฏธํฐ ์คํ๊ณผ ํ์ง ๋ฉํธ๋ฆญ์ ํจ๊ป ์ถ์ ํ ์ ์์ต๋๋ค."
|
| 331 |
+
},
|
| 332 |
+
{
|
| 333 |
+
"id": "docs-graph-1",
|
| 334 |
+
"title": "[LangGraph 1] StateGraph ๊ธฐ๋ณธ ๊ตฌ์กฐ",
|
| 335 |
+
"task_description": "**์ํฉ**\nRAG ์ฒด์ธ์ ์ฐ๋ค ๋ณด๋ \"๊ฒ์ ๊ฒฐ๊ณผ๊ฐ ์์ผ๋ฉด ๋ค์ ์๋\", \"ํ์ง์ด ๋ฎ์ผ๋ฉด ๋ค๋ฅธ ๊ฒฝ๋ก๋ก\" ๊ฐ์ ์กฐ๊ฑด ๋ถ๊ธฐ๊ฐ ํ์ํด์ก์ต๋๋ค. LCEL ์ฒด์ธ์ AโBโC ์ ํ์ด๋ผ ๋ถ๊ธฐ๋ฅผ ํํํ ์ ์์ต๋๋ค.\n\n**๋ฌธ์ **\n๋จ์ ์ฒด์ธ์ผ๋ก๋ ๋ฃจํ๋ ์กฐ๊ฑด ๋ถ๊ธฐ๋ฅผ ๊ตฌํํ๊ธฐ ์ด๋ ต์ต๋๋ค.\n\n**ํด๊ฒฐ**\nLangGraph๋ก 2๊ฐ ๋
ธ๋(`retrieve`, `generate`)๋ฅผ ๊ฐ์ง StateGraph๋ฅผ ๋ง๋์ธ์.\n\n```python\nclass State(TypedDict):\n question: str\n answer: str\n```\n\n- ๋
ธ๋ ์ถ๊ฐ: `retrieve`, `generate`\n- ์ง์
์ : `retrieve`\n- ์ฃ์ง: `retrieve โ generate โ END`\n- ์ปดํ์ผํด์ `app`์ ์ ์ฅ",
|
| 336 |
+
"expected_command": "graph = StateGraph(State)\ngraph.add_node('retrieve', retrieve)\ngraph.add_node('generate', generate)\ngraph.set_entry_point('retrieve')\ngraph.add_edge('retrieve', 'generate')\ngraph.add_edge('generate', END)\napp = graph.compile()",
|
| 337 |
+
"grading_conditions": ["StateGraph", "add_node", "set_entry_point", "add_edge", "END", "graph.compile()"],
|
| 338 |
+
"hint": "StateGraph โ add_node โ set_entry_point โ add_edge โ compile() ์์์
๋๋ค.",
|
| 339 |
+
"explanation": "`graph.compile()`๋ก ์คํ ๊ฐ๋ฅํ ์ฑ์ ๋ง๋ญ๋๋ค. `app.invoke({'question': '์ง๋ฌธ'})`์ผ๋ก ์คํํ๋ฉด retrieve ๋
ธ๋ โ generate ๋
ธ๋ ์์๋ก State๋ฅผ ์ฒ๋ฆฌํฉ๋๋ค.",
|
| 340 |
+
"difficulty": "medium",
|
| 341 |
+
"takeaway": "LangGraph๋ compile() ํ invoke()๋ก ์คํํฉ๋๋ค. ์ฒด์ธ์ invoke()์ ๊ฐ์ ์ธํฐํ์ด์ค์ด์ง๋ง, ๋ด๋ถ์ ์ผ๋ก ๊ทธ๋ํ ๊ตฌ์กฐ๋ฅผ ์คํํฉ๋๋ค."
|
| 342 |
+
},
|
| 343 |
+
{
|
| 344 |
+
"id": "docs-graph-2",
|
| 345 |
+
"title": "[LangGraph 2] conditional_edges โ ์กฐ๊ฑด ๋ถ๊ธฐ",
|
| 346 |
+
"task_description": "**์ํฉ**\ngenerate ๋
ธ๋์์ LLM์ด '๋ชจ๋ฅด๊ฒ ์ต๋๋ค'๋ฅผ ๋ฐํํ๋ฉด retrieve๋ฅผ ๋ค์ ์๋ํ๊ณ ์ถ์ต๋๋ค. ๊ทธ๋ฐ๋ฐ `add_edge`๋ ํญ์ ๊ณ ์ ๋ ๋ค์ ๋
ธ๋๋ก ์ด๋ํฉ๋๋ค.\n\n**๋ฌธ์ **\n๋
ธ๋ ๊ฒฐ๊ณผ์ ๋ฐ๋ผ ๋ค์ ๋
ธ๋๋ฅผ ๋์ ์ผ๋ก ๊ฒฐ์ ํด์ผ ํฉ๋๋ค.\n\n**ํด๊ฒฐ**\n`judge` ๋
ธ๋์ ๊ฒฐ๊ณผ์ ๋ฐ๋ผ ๋ถ๊ธฐํ๋ conditional_edges๋ฅผ ์ถ๊ฐํ์ธ์.\n\n- router ํจ์: `should_retry` (์ด๋ฏธ ์ ์๋จ)\n- `'retry'` โ `'retrieve'` ๋
ธ๋๋ก\n- `'done'` โ `END`๋ก",
|
| 347 |
+
"expected_command": "graph.add_conditional_edges('judge', should_retry, {'retry': 'retrieve', 'done': END})",
|
| 348 |
+
"grading_conditions": ["add_conditional_edges", "'judge'", "should_retry", "'retry'", "retrieve", "END"],
|
| 349 |
+
"hint": "`graph.add_conditional_edges('๋
ธ๋', ๋ผ์ฐํฐํจ์, {'๋ฐํ๊ฐ': '๋ค์๋
ธ๋', ...})` ํจํด์
๋๋ค.",
|
| 350 |
+
"explanation": "`should_retry` ํจ์๊ฐ State๋ฅผ ๋ฐ์ `'retry'` ๋๋ `'done'`์ ๋ฐํํ๋ฉด, ๊ฐ๊ฐ `retrieve` ๋
ธ๋ ๋๋ `END`๋ก ์ด๋ํฉ๋๋ค. ์ด๊ฒ์ด ReAct ์์ด์ ํธ์ \"ํ๋ โ ๊ด์ฐฐ โ ํ๋จ\" ๋ฃจํ์ ๊ธฐ๋ณธ ๊ตฌ์กฐ์
๋๋ค.",
|
| 351 |
+
"difficulty": "medium",
|
| 352 |
+
"takeaway": "add_conditional_edges๋ก ๋ผ์ฐํฐ ํจ์์ ๋ฐํ๊ฐ์ ๋ฐ๋ผ ๋ค์ ๋
ธ๋๋ฅผ ๋์ ์ผ๋ก ๊ฒฐ์ ํ๋ ๊ฒ์ด LangGraph ์์ด์ ํธ์ ํต์ฌ์
๋๋ค."
|
| 353 |
+
},
|
| 354 |
+
{
|
| 355 |
+
"id": "docs-litellm-1",
|
| 356 |
+
"title": "[LiteLLM] ๋ชจ๋ธ๋ช
ํ๋๋ก Ollama โ OpenAI ์ ํ",
|
| 357 |
+
"task_description": "**์ํฉ**\n๋ก์ปฌ์์ Ollama๋ก ๊ฐ๋ฐํ๋๋ฐ, ํ๋ก๋์
์์๋ OpenAI๋ฅผ ์จ์ผ ํฉ๋๋ค. `OllamaLLM`์ `ChatOpenAI`๋ก ๋ฐ๊พธ๋ ค๋ import, ํด๋์ค๋ช
, API ํ์์ด ๋ชจ๋ ๋ฌ๋ผ ์ฝ๋๋ฅผ ๋ง์ด ๊ณ ์ณ์ผ ํฉ๋๋ค.\n\n**๋ฌธ์ **\nLLM ํ๋ก๋ฐ์ด๋๋ง๋ค SDK๊ฐ ๋ฌ๋ผ ๊ต์ฒด ์ ์ฝ๋ ์์ ์ด ๋ง์ต๋๋ค.\n\n**ํด๊ฒฐ**\nLiteLLM์ `completion()`์ผ๋ก Ollama `llama3.2`์ `'์๋
'`์ ๋ณด๋ด๋ ์ฝ๋๋ฅผ ์์ฑํ์ธ์. ๋์ค์ `'gpt-4o-mini'`๋ก ๋ฐ๊ฟ ๋ model ํ๋ผ๋ฏธํฐ ํ๋๋ง ์์ ํ๋ฉด ๋ฉ๋๋ค.",
|
| 358 |
+
"expected_command": "response = completion(model='ollama/llama3.2', messages=[{'role': 'user', 'content': '์๋
'}])",
|
| 359 |
+
"grading_conditions": ["completion", "model='ollama/llama3.2'", "messages", "role", "user"],
|
| 360 |
+
"hint": "`completion(model='ํ๋ก๋ฐ์ด๋/๋ชจ๋ธ๋ช
', messages=[...])` ํจํด์
๋๋ค.",
|
| 361 |
+
"explanation": "์ดํ `model='gpt-4o-mini'`๋ก๋ง ๋ฐ๊พธ๋ฉด OpenAI๋ก ์ ํ๋ฉ๋๋ค. `response.choices[0].message.content`๋ก ์๋ต์ ์ฝ๋ ๋ฐฉ์๋ ๋์ผํฉ๋๋ค.",
|
| 362 |
+
"difficulty": "easy",
|
| 363 |
+
"takeaway": "model='ํ๋ก๋ฐ์ด๋/๋ชจ๋ธ๋ช
' ํ์์ผ๋ก ์ฝ๋ ๋ณ๊ฒฝ ์์ด LLM์ ์ ํํฉ๋๋ค. ์ด๊ฒ์ด LiteLLM์ ํต์ฌ ๊ฐ์น์
๋๋ค."
|
| 364 |
+
},
|
| 365 |
+
{
|
| 366 |
+
"id": "docs-chainlit-1",
|
| 367 |
+
"title": "[Chainlit] ์คํธ๋ฆฌ๋ฐ ์ฑ๋ด โ Streamlit๋ณด๋ค ๊ฐ๊ฒฐํ๊ฒ",
|
| 368 |
+
"task_description": "**์ํฉ**\nStreamlit ์ฑ๋ด์ ์คํธ๋ฆฌ๋ฐ(ํ์ดํ ํจ๊ณผ)์ ๊ตฌํํ๋๋ฐ, `st.write_stream`, generator ํจ์, `st.empty()` ๋ฑ ์ฌ๋ฌ ๊ฐ๋
์ด ์ฝํ ์ฝ๋๊ฐ ๋ณต์กํฉ๋๋ค.\n\n**๋ฌธ์ **\nStreamlit์ rerun ๊ธฐ๋ฐ์ด๋ผ ์คํธ๋ฆฌ๋ฐ UI ๊ตฌํ์ด ์ฅํฉํฉ๋๋ค.\n\n**ํด๊ฒฐ**\nChainlit์ผ๋ก ์คํธ๋ฆฌ๋ฐ ์ฑ๋ด์ ๋ง๋์ธ์.\n\n`@cl.on_message` ๋ฐ์ฝ๋ ์ดํฐ๋ก ํจ์๋ฅผ ์ ์ํ๊ณ , `cl.Message(content='')`๋ฅผ ๋ง๋ ๋ค `chain.astream()`์ผ๋ก ํ ํฐ์ ๋ฐ์ `msg.stream_token(chunk)`์ผ๋ก ์ ์กํ์ธ์.",
|
| 369 |
+
"expected_command": "@cl.on_message\nasync def main(message: cl.Message):\n msg = cl.Message(content='')\n async for chunk in chain.astream({'question': message.content}):\n await msg.stream_token(chunk)\n await msg.send()",
|
| 370 |
+
"grading_conditions": ["@cl.on_message", "cl.Message", "chain.astream", "msg.stream_token", "msg.send()"],
|
| 371 |
+
"hint": "`@cl.on_message` โ `cl.Message(content='')` ์์ฑ โ `astream`์ผ๋ก ํ ํฐ ๋ฐ๊ธฐ โ `stream_token` โ `send()` ์์์
๋๋ค.",
|
| 372 |
+
"explanation": "Chainlit์์ `astream()`๊ณผ `stream_token()`์ ์กฐํฉํ๋ฉด ํ ํฐ ๋จ์ ์คํธ๋ฆฌ๋ฐ์ด ๋ฉ๋๋ค. Streamlit๋ณด๋ค ํจ์ฌ ์ ์ ์ฝ๋๋ก ๋์ผ ํจ๊ณผ๋ฅผ ๊ตฌํํฉ๋๋ค. `chainlit run app.py`๋ก ์คํํฉ๋๋ค.",
|
| 373 |
+
"difficulty": "medium",
|
| 374 |
+
"takeaway": "astream()์ผ๋ก ํ ํฐ์ ๋ฐ์ stream_token()์ผ๋ก ์ ์กํ๋ ํจํด์ด Chainlit ์คํธ๋ฆฌ๋ฐ์ ์ ๋ถ์
๋๋ค."
|
| 375 |
+
},
|
| 376 |
+
{
|
| 377 |
+
"id": "docs-redis-1",
|
| 378 |
+
"title": "[Redis] ๋ํ ํ์คํ ๋ฆฌ ์์ํ โ ์ฌ์์ํด๋ ๊ธฐ์ต",
|
| 379 |
+
"task_description": "**์ํฉ**\n```python\nstore = {} # ์ธ๋ฉ๋ชจ๋ฆฌ\ndef get_session_history(session_id):\n if session_id not in store:\n store[session_id] = ChatMessageHistory()\n return store[session_id]\n```\n์๋ฒ๋ฅผ ์ฌ์์ํ๋ ๋ชจ๋ ์ฌ์ฉ์์ ๋ํ ํ์คํ ๋ฆฌ๊ฐ ์ฌ๋ผ์ก์ต๋๋ค. `store` ๋์
๋๋ฆฌ๊ฐ ๋ฉ๋ชจ๋ฆฌ์๋ง ์์๊ธฐ ๋๋ฌธ์
๋๋ค.\n\n**๋ฌธ์ **\n์ธ๋ฉ๋ชจ๋ฆฌ ํ์คํ ๋ฆฌ๋ ํ๋ก์ธ์ค ์ข
๋ฃ ์ ์๋ฉธํฉ๋๋ค.\n\n**ํด๊ฒฐ**\n`get_session_history` ํจ์๋ฅผ `RedisChatMessageHistory`๋ฅผ ์ฌ์ฉํ๋๋ก ์์ ํ์ธ์.\n- Redis URL: `'redis://localhost:6379'`",
|
| 380 |
+
"expected_command": "def get_session_history(session_id: str):\n return RedisChatMessageHistory(session_id=session_id, url='redis://localhost:6379')",
|
| 381 |
+
"grading_conditions": ["RedisChatMessageHistory", "session_id=session_id", "url='redis://localhost:6379'"],
|
| 382 |
+
"hint": "`RedisChatMessageHistory(session_id=session_id, url='redis://...')` ํจํด์
๋๋ค.",
|
| 383 |
+
"explanation": "ํจ์ ๋ด๋ถ๋ฅผ `RedisChatMessageHistory`๋ก ๊ต์ฒดํ๋ฉด ๋ฉ๋๋ค. `RunnableWithMessageHistory`๋ ๊ทธ๋๋ก ๋๊ณ ์ด ํจ์๋ง ๋ฐ๊พธ๋ฉด ์์์ฑ์ ์ป์ต๋๋ค. Redis ์๋ฒ๋ `docker run -d -p 6379:6379 redis`๋ก ์คํํ์ธ์.",
|
| 384 |
+
"difficulty": "easy",
|
| 385 |
+
"takeaway": "get_session_history ํจ์ ๋ด๋ถ๋ฅผ RedisChatMessageHistory๋ก ๊ต์ฒดํ๊ธฐ๋ง ํ๋ฉด ๋ํ ํ์คํ ๋ฆฌ๊ฐ ์ฌ์์์๋ ์ ์ง๋ฉ๋๋ค."
|
| 386 |
+
},
|
| 387 |
+
{
|
| 388 |
+
"id": "docs-unstructured-1",
|
| 389 |
+
"title": "[Unstructured] PDFยทWord ๋ฑ ์ค๋ฌด ๋ฌธ์ ํ์ฑ",
|
| 390 |
+
"task_description": "**์ํฉ**\nDirectoryLoader๋ก `./docs` ํด๋๋ฅผ ๋ก๋ํ๋ ค๋๋ฐ, `.md` ํ์ผ์ ์ ๋์ง๋ง ํ์์ ๊ณต์ ๋ฐ์ ๋ณด๊ณ ์๋ `.pdf`, `.docx`, `.pptx`๊ฐ ์์ฌ ์์ต๋๋ค. ํ์ฅ์๋ง๋ค ๋ค๋ฅธ ๋ก๋๋ฅผ ์จ์ผ ํด ์ฝ๋๊ฐ ๋ณต์กํด์ก์ต๋๋ค.\n\n**๋ฌธ์ **\nํ์ผ ํ์๋ง๋ค ๋ค๋ฅธ ๋ก๋๋ฅผ ์ฐ๋ฉด ์ฝ๋๊ฐ ๋ถ๊ธฐ๋ฉ๋๋ค.\n\n**ํด๊ฒฐ**\n`UnstructuredFileLoader`๋ฅผ `loader_cls`๋ก ์ง์ ํด `./docs` ํด๋์ ๋ชจ๋ ํ์ผ์ ํ์์ ์๊ด์์ด ๋ก๋ํ์ธ์. ๊ฒฐ๊ณผ๋ฅผ `docs` ๋ณ์์ ์ ์ฅํ์ธ์.",
|
| 391 |
+
"expected_command": "loader = DirectoryLoader('./docs', glob='**/*', loader_cls=UnstructuredFileLoader)\ndocs = loader.load()",
|
| 392 |
+
"grading_conditions": ["DirectoryLoader", "./docs", "loader_cls=UnstructuredFileLoader", "loader.load()"],
|
| 393 |
+
"hint": "`DirectoryLoader('ํด๋', glob='**/*', loader_cls=UnstructuredFileLoader)` ํจํด์
๋๋ค.",
|
| 394 |
+
"explanation": "`UnstructuredFileLoader`๋ ํ์ฅ์๋ฅผ ์๋ ๊ฐ์งํด ์ ์ ํ ํ์๋ฅผ ์ ํํฉ๋๋ค. `.pdf`, `.docx`, `.pptx`, `.jpg` ๋ฑ์ ๋์ผ ์ฝ๋๋ก ์ฒ๋ฆฌํฉ๋๋ค. PDF์๋ `pip install unstructured[pdf]`๊ฐ ํ์ํฉ๋๋ค.",
|
| 395 |
+
"difficulty": "easy",
|
| 396 |
+
"takeaway": "loader_cls=UnstructuredFileLoader ํ๋๋ก PDFยทWordยทPowerPoint ๋ฑ ๋ชจ๋ ๋ฌธ์ ํ์์ ๋์ผํ ์ฝ๋๋ก ์ฒ๋ฆฌํฉ๋๋ค."
|
| 397 |
+
},
|
| 398 |
+
{
|
| 399 |
+
"id": "docs-news-1",
|
| 400 |
+
"title": "[๋ด์ค ์์ฝ๊ธฐ 1] feedparser๋ก RSS ํ์ฑ",
|
| 401 |
+
"task_description": "**ํ๋ก์ ํธ: ๋ด์ค ์๋ ์์ฝ๊ธฐ**\n๋งค์ผ ์์นจ ๋ด์ค ์ฌ์ดํธ 5๊ฐ๋ฅผ ์ง์ ์ด์ด ์ฝ์ต๋๋ค. ์๋ํํ๊ณ ์ถ์๋ฐ ์ฌ์ดํธ๋ง๋ค HTML ๊ตฌ์กฐ๊ฐ ๋ฌ๋ผ ํฌ๋กค๋ง ์ฝ๋๊ฐ ๊ฐ๊ฐ ๏ฟฝ๏ฟฝ๏ฟฝ์ํฉ๋๋ค.\n\n**๋ฌธ์ **\nHTML ํฌ๋กค๋ง์ ์ฌ์ดํธ ๊ตฌ์กฐ๊ฐ ๋ฐ๋๋ฉด ์ฝ๋๊ฐ ๊นจ์ง๋๋ค. ๋ด์ค ์ฌ์ดํธ ๋๋ถ๋ถ์ด RSS๋ผ๋ ํ์ค ํ์์ ์ ๊ณตํฉ๋๋ค.\n\n**ํด๊ฒฐ**\n`feedparser`๋ก BBC ๋ด์ค RSS๋ฅผ ํ์ฑํ๊ณ , ์ต์ ๊ธฐ์ฌ 5๊ฐ์ ์์ฝ์ `articles` ๋ฆฌ์คํธ์ ์ ์ฅํ์ธ์.\n\nFeed URL: `https://feeds.bbci.co.uk/news/rss.xml`",
|
| 402 |
+
"expected_command": "import feedparser\nfeed = feedparser.parse('https://feeds.bbci.co.uk/news/rss.xml')\narticles = [entry.summary for entry in feed.entries[:5]]",
|
| 403 |
+
"grading_conditions": ["feedparser.parse", "feed.entries", "entry.summary", "articles"],
|
| 404 |
+
"hint": "`feedparser.parse(url)`๋ก ํ์ฑํ๋ฉด `feed.entries`์ ๊ธฐ์ฌ ๋ชฉ๋ก์ด ๋ค์ด์์ต๋๋ค.",
|
| 405 |
+
"explanation": "RSS๋ XML ๊ธฐ๋ฐ ํ์ค ํ์์ด๋ผ ์ด๋ ์ฌ์ดํธ๋ `feed.entries`๋ก ๋์ผํ๊ฒ ์ ๊ทผํฉ๋๋ค. HTML ๊ตฌ์กฐ ๋ณ๊ฒฝ์ ์ํฅ์ ๋ฐ์ง ์์ต๋๋ค.",
|
| 406 |
+
"difficulty": "easy",
|
| 407 |
+
"takeaway": "RSS๋ ์ฌ์ดํธ ๊ตฌ์กฐ์ ๊ด๊ณ์์ด feed.entries๋ก ๋์ผํ๊ฒ ์ ๊ทผํ๋ ํ์ค ํ์์
๋๋ค."
|
| 408 |
+
},
|
| 409 |
+
{
|
| 410 |
+
"id": "docs-news-2",
|
| 411 |
+
"title": "[๋ด์ค ์์ฝ๊ธฐ 2] map_reduce โ ํ ํฐ ์ด๊ณผ ์์ด ์์ฝ",
|
| 412 |
+
"task_description": "**์ํฉ**\n๊ธฐ์ฌ 10๊ฐ๋ฅผ ํ๊บผ๋ฒ์ ์์ฝํ๋ ค๊ณ `stuff` ๋ฐฉ์์ ์ผ๋๋:\n```\nError: This model's maximum context length is 128000 tokens.\nYour message resulted in 180000 tokens.\n```\n\n**๋ฌธ์ **\n`stuff`๋ ๋ชจ๋ ๋ฌธ์๋ฅผ ํ๋์ ํ๋กฌํํธ์ ๋ฃ์ด์ ๋ฌธ์๊ฐ ๋ง์ผ๋ฉด ํ ํฐ์ ์ด๊ณผํฉ๋๋ค.\n\n**ํด๊ฒฐ**\n`map_reduce`๋ฅผ ์ฌ์ฉํ์ธ์. ๊ฐ ๊ธฐ์ฌ๋ฅผ ๊ฐ๋ณ ์์ฝํ ๋ค ํฉ์นฉ๋๋ค.\n\n`articles` โ `Document` ๋ฆฌ์คํธ๋ก ๋ณํ ํ `map_reduce` ์ฒด์ธ์ผ๋ก ์์ฝํ๋ ์ฝ๋์ `???` ๋ถ๋ถ์ ์ฑ์ฐ์ธ์.\n\n```python\ndocs = [Document(page_content=a) for a in articles]\nchain = ???\nresult = chain.invoke(docs)\n```",
|
| 413 |
+
"expected_command": "chain = load_summarize_chain(llm, chain_type='map_reduce')",
|
| 414 |
+
"grading_conditions": ["load_summarize_chain", "llm", "chain_type='map_reduce'"],
|
| 415 |
+
"hint": "`load_summarize_chain(llm, chain_type='...')` ํจํด์
๋๋ค.",
|
| 416 |
+
"explanation": "`map_reduce`๋ ๊ฐ ๊ธฐ์ฌ๋ฅผ ๊ฐ๋ณ ์์ฝ(map)ํ๊ณ , ๊ฐ๋ณ ์์ฝ๋ค์ ๋ค์ ํฉ์ณ ์ต์ข
์์ฝ(reduce)์ ๋ง๋ญ๋๋ค. ์๋ฌด๋ฆฌ ๊ธฐ์ฌ๊ฐ ๋ง์๋ ํ ํฐ ์ด๊ณผ๊ฐ ๋ฐ์ํ์ง ์์ต๋๋ค.",
|
| 417 |
+
"difficulty": "medium",
|
| 418 |
+
"takeaway": "map_reduce๋ ๊ฐ ๋ฌธ์๋ฅผ ๊ฐ๋ณ ์์ฝ(map)ํ ๋ค ํฉ์น๋(reduce) ๋ฐฉ์์ผ๋ก ํ ํฐ ์ ํ ์์ด ์ฌ๋ฌ ๋ฌธ์๋ฅผ ์์ฝํฉ๋๋ค."
|
| 419 |
+
},
|
| 420 |
+
{
|
| 421 |
+
"id": "docs-news-3",
|
| 422 |
+
"title": "[๋ด์ค ์์ฝ๊ธฐ 3] Airflow โ ์๋ ๋์๋ ์๋ ์คํ",
|
| 423 |
+
"task_description": "**์ํฉ**\nfeedparser + LangChain ์์ฝ ์คํฌ๋ฆฝํธ๊ฐ ์ ๋์ํ๋๋ฐ, ๋งค์ผ ์์นจ ์ง์ ํฐ๋ฏธ๋์ `python news_summary.py`๋ฅผ ์
๋ ฅํด์ผ ํฉ๋๋ค. ์ฃผ๋ง์ ๊น๋นกํ๋ฉด ๊ทธ๋ ์์ฝ์ด ์์ต๋๋ค.\n\n**๋ฌธ์ **\n์๋ ์คํ์ ๋ฐ๋์ ๋น ๋จ๋ฆฌ๋ ๋ ์ด ์๊น๋๋ค.\n\n**ํด๊ฒฐ**\n`run_news_summary` ํจ์๋ฅผ ๋งค์ผ ์๋ ์คํํ๋ Airflow DAG๋ฅผ ์ ์ํ์ธ์.\n\n- DAG ID: `daily_news_summary`, ์ค์ผ์ค: `@daily`\n- task_id: `'summarize'`, python_callable: `run_news_summary`",
|
| 424 |
+
"expected_command": "with DAG('daily_news_summary', schedule='@daily', start_date=datetime(2024, 1, 1)) as dag:\n task = PythonOperator(task_id='summarize', python_callable=run_news_summary)",
|
| 425 |
+
"grading_conditions": ["daily_news_summary", "@daily", "PythonOperator", "task_id='summarize'", "python_callable=run_news_summary"],
|
| 426 |
+
"hint": "`with DAG(...) as dag:` ๋ธ๋ก ์์ PythonOperator๋ฅผ ์ ์ํฉ๋๋ค.",
|
| 427 |
+
"explanation": "์ด DAG๋ ๋งค์ผ ์์ ์ `run_news_summary`๋ฅผ ์๋ ์คํํฉ๋๋ค. Airflow ์ค์ผ์ค๋ฌ๊ฐ ์คํํ๋ฏ๋ก ๋ด๋น์๊ฐ ์์ด๋, ์๋ ์ค์๋ ๋์ํฉ๋๋ค.",
|
| 428 |
+
"difficulty": "medium",
|
| 429 |
+
"takeaway": "RAG ์ฑ๋ด์์ ๋ฐฐ์ด Airflow DAG + PythonOperator ํจํด์ด ๋ด์ค ์์ฝ๊ธฐ ์๋ํ์ ๊ทธ๋๋ก ์ฌ์ฌ์ฉ๋ฉ๋๋ค."
|
| 430 |
+
},
|
| 431 |
+
{
|
| 432 |
+
"id": "docs-news-4",
|
| 433 |
+
"title": "[๋ด์ค ์์ฝ๊ธฐ 4] st.expander โ ๊ธด ๋ชฉ๋ก์ ๊น๋ํ๊ฒ",
|
| 434 |
+
"task_description": "**์ํฉ**\n์์ฝ๋ ๊ธฐ์ฌ 10๊ฐ๋ฅผ `st.write()`๋ก ๋์ดํ๋๋ ํ์ด์ง ์คํฌ๋กค์ด ๋์ด ์๊ณ , ์ํ๋ ๊ธฐ์ฌ๋ฅผ ์ฐพ๊ธฐ ์ด๋ ต์ต๋๋ค.\n\n**๋ฌธ์ **\n๋ชจ๋ ๋ด์ฉ์ ํผ์ณ๋์ผ๋ฉด ํ๋์ ๋ณด๊ธฐ ์ด๋ ต์ต๋๋ค.\n\n**ํด๊ฒฐ**\n`summaries` ๋ฆฌ์คํธ(`{'title': ..., 'content': ...}`)๋ฅผ `st.expander`๋ก ๋ ๋๋งํ์ธ์. ์ ๋ชฉ๋ง ๋ณด์ด๊ณ ํด๋ฆญ ์ ์์ฝ์ด ํผ์ณ์ง๋๋ก.",
|
| 435 |
+
"expected_command": "for s in summaries:\n with st.expander(s['title']):\n st.write(s['content'])",
|
| 436 |
+
"grading_conditions": ["st.expander", "s['title']", "st.write", "s['content']"],
|
| 437 |
+
"hint": "`with st.expander(์ ๋ชฉ):` ๋ธ๋ก ์์ ๋ด์ฉ์ ๋ฃ์ผ๋ฉด ํด๋ฆญ ์ ํผ์ณ์ง๋๋ค.",
|
| 438 |
+
"explanation": "`st.expander`๋ ๊ธฐ๋ณธ์ ์ผ๋ก ์ ํ ์๊ณ ํด๋ฆญํ๋ฉด ๋ด์ฉ์ด ๋์ต๋๋ค. ํญ๋ชฉ์ด ๋ง์ ๋ ํ๋ฉด์ ๊น๋ํ๊ฒ ์ ์งํ๋ฉด์๋ ์์ธ ๋ด์ฉ์ ๋ณผ ์ ์๊ฒ ํฉ๋๋ค.",
|
| 439 |
+
"difficulty": "easy",
|
| 440 |
+
"takeaway": "st.expander๋ ํญ๋ชฉ์ด ๋ง์ ๋ ์ ๋ชฉ๋ง ๋ณด์ฌ์ฃผ๊ณ ํด๋ฆญ ์ ๋ด์ฉ์ ํผ์น๋ Streamlit์ ํต์ฌ UI ์ปดํฌ๋ํธ์
๋๋ค."
|
| 441 |
+
},
|
| 442 |
+
{
|
| 443 |
+
"id": "docs-sql-1",
|
| 444 |
+
"title": "[Text-to-SQL 1] SQLDatabase โ DB ์คํค๋ง๋ฅผ LLM์ ์๋ ค์ฃผ๊ธฐ",
|
| 445 |
+
"task_description": "**ํ๋ก์ ํธ: Text-to-SQL ์์ฑ๊ธฐ**\nํ์๋ค์ด \"์ด ๋ฌ ๋งค์ถ ์์ 5๊ฐ ์ํ์ด ๋ญ์์?\"๋ฅผ ๋ฌผ์ด๋ณผ ๋๋ง๋ค SQL์ ๋์ ์จ์ค์ผ ํฉ๋๋ค. ํ๋ฃจ์๋ ์์ญ ๋ฒ์
๋๋ค.\n\n---\n\n**๋จ๊ณ 1**: LLM์๊ฒ DB ๊ตฌ์กฐ๋ฅผ ์๋ ค์ค์ผ ์ฌ๋ฐ๋ฅธ SQL์ด ๋์ต๋๋ค.\n`SQLDatabase`๋ก `./shop.db`์ ์ฐ๊ฒฐํ์ธ์. (์คํค๋ง๋ฅผ ์๋์ผ๋ก ์ฝ์ด LLM ํ๋กฌํํธ์ ์ฃผ์
ํฉ๋๋ค)\n\n๊ฒฐ๊ณผ๋ฅผ `db` ๋ณ์์ ์ ์ฅํ์ธ์.",
|
| 446 |
+
"expected_command": "db = SQLDatabase.from_uri('sqlite:///./shop.db')",
|
| 447 |
+
"grading_conditions": ["SQLDatabase.from_uri", "sqlite", "shop.db"],
|
| 448 |
+
"hint": "`SQLDatabase.from_uri('sqlite:///๊ฒฝ๋ก')` ํจํด์
๋๋ค. ์ฌ๋์๊ฐ 3๊ฐ์
๋๋ค.",
|
| 449 |
+
"explanation": "`SQLDatabase.from_uri()`๋ ์ฐ๊ฒฐ๊ณผ ๋์์ ํ
์ด๋ธ๋ช
ยท์ปฌ๋ผ ์คํค๋ง๋ฅผ ์ฝ์ด LLM ํ๋กฌํํธ์ ์๋ ์ฃผ์
ํ ์ค๋น๋ฅผ ํฉ๋๋ค. LLM์ด ์กด์ฌํ์ง ์๋ ์ปฌ๋ผ์ ์ฐ๋ ์ค์๋ฅผ ์ค์ฌ์ค๋๋ค.",
|
| 450 |
+
"difficulty": "easy",
|
| 451 |
+
"takeaway": "SQLDatabase.from_uri()๊ฐ DB ์คํค๋ง๋ฅผ ์๋์ผ๋ก ์ฝ์ด LLM์ด ์กด์ฌํ๋ ํ
์ด๋ธยท์ปฌ๋ผ๋ง ์ฐธ์กฐํ๋๋ก ์ ๋ํฉ๋๋ค."
|
| 452 |
+
},
|
| 453 |
+
{
|
| 454 |
+
"id": "docs-sql-2",
|
| 455 |
+
"title": "[Text-to-SQL 2] create_sql_query_chain โ ์์ฐ์ด โ SQL",
|
| 456 |
+
"task_description": "**์ํฉ**\nLLM์๊ฒ ์ง์ \"SQL ์จ์ค\"๋ผ๊ณ ํ๋๋:\n```sql\nSELECT * FROM sales ORDER BY revenue DESC LIMIT 5\n```\n`sales` ํ
์ด๋ธ์ด ์๊ณ `orders`๊ฐ ๋ง๋๋ฐ, LLM์ด DB ์คํค๋ง๋ฅผ ๋ชฐ๋ผ์ ํ๋ฆฐ ํ
์ด๋ธ๋ช
์ ์ผ์ต๋๋ค.\n\n**๋ฌธ์ **\nLLM์ด ์ค์ DB ๊ตฌ์กฐ๋ฅผ ๋ชจ๋ฅด๋ฉด ์กด์ฌํ์ง ์๋ ํ
์ด๋ธ/์ปฌ๋ผ์ ์๋๋ค.\n\n**ํด๊ฒฐ**\n`create_sql_query_chain`์ `db` ์คํค๋ง๋ฅผ ์๋ ์ฃผ์
ํฉ๋๋ค.\n`'๊ฐ์ฅ ๋ง์ด ํ๋ฆฐ ์ํ 5๊ฐ๋?'`์ผ๋ก ์คํํด `sql` ๋ณ์์ ์ ์ฅํ์ธ์.",
|
| 457 |
+
"expected_command": "chain = create_sql_query_chain(llm, db)\nsql = chain.invoke({'question': '๊ฐ์ฅ ๋ง์ด ํ๋ฆฐ ์ํ 5๊ฐ๋?'})",
|
| 458 |
+
"grading_conditions": ["create_sql_query_chain", "llm", "db", "chain.invoke", "question"],
|
| 459 |
+
"hint": "`create_sql_query_chain(llm, db)`๋ก ์ฒด์ธ ์์ฑ ํ, `{'question': '...'}` ๋์
๋๋ฆฌ๋ก ์คํํฉ๋๋ค.",
|
| 460 |
+
"explanation": "chain ๋ด๋ถ์ ์ผ๋ก DB์ ํ
์ด๋ธยท์ปฌ๋ผ ์ ๋ณด๋ฅผ ํ๋กฌํํธ์ ํฌํจํด LLM์ด ์ฌ๋ฐ๋ฅธ ์คํค๋ง๋ง ์ฐธ์กฐํ๋๋ก ์ ๋ํฉ๋๋ค.",
|
| 461 |
+
"difficulty": "medium",
|
| 462 |
+
"takeaway": "create_sql_query_chain์ SQLDatabase์์ ์คํค๋ง๋ฅผ ์๋ ์ฃผ์
ํด LLM์ด ์ฌ๋ฐ๋ฅธ SQL์ ์์ฑํ๋๋ก ํฉ๋๋ค."
|
| 463 |
+
},
|
| 464 |
+
{
|
| 465 |
+
"id": "docs-sql-3",
|
| 466 |
+
"title": "[Text-to-SQL 3] ValidSQL Guard โ ์๋ชป๋ SQL ์คํ ์ ์ฐจ๋จ",
|
| 467 |
+
"task_description": "**์ํฉ**\nLLM์ด ์์ฑํ SQL์ ๋ฐ๋ก `db.run()`์ ๋๊ฒผ๋๋:\n```\nOperationalError: no such column: product_name\n```\n๋ฌธ๋ฒ ์ค๋ฅ๊ฐ ์๋ SQL์ด ์ค์ DB์ ์คํ๋์ต๋๋ค.\n\n**๋ฌธ์ **\nLLM์ ๊ฐ๋ ๋ฌธ๋ฒ ์ค๋ฅ๊ฐ ์๋ SQL์ ์์ฑํฉ๋๋ค. ์คํ ์ ์ ๊ฑธ๋ฌ์ผ ํฉ๋๋ค.\n\n**ํด๊ฒฐ**\nGuardrails์ `ValidSQL`๋ก SQL ์ ํจ์ฑ ๊ฒ์ฆ Guard๋ฅผ ๋ง๋์ธ์.\n- ์คํจ ์: `'reask'` (์ฌ๋ฐ๋ฅธ SQL์ ๋ค์ ์์ฒญ)",
|
| 468 |
+
"expected_command": "guard = Guard().use(ValidSQL(on_fail='reask'))",
|
| 469 |
+
"grading_conditions": ["Guard()", "ValidSQL", "on_fail='reask'"],
|
| 470 |
+
"hint": "`Guard().use(ValidSQL(on_fail='...'))` ํจํด์
๋๋ค.",
|
| 471 |
+
"explanation": "`on_fail='reask'`๋ SQL ๊ฒ์ฆ ์คํจ ์ LLM์๊ฒ ์๋์ผ๋ก ์ฌ์์ฑ์ ์์ฒญํฉ๋๋ค. `exception`๊ณผ ๋ฌ๋ฆฌ ์ฌ์ฉ์๋ ์ค๋ฅ๋ฅผ ๋ณด์ง ๋ชปํ๊ณ ์๋์ผ๋ก ์์ ๋ฉ๋๋ค.",
|
| 472 |
+
"difficulty": "medium",
|
| 473 |
+
"takeaway": "RAG ์ฑ๋ด์์ ๋ฐฐ์ด Guard().use() ํจํด์ด SQL ๊ฒ์ฆ์๋ ๊ทธ๋๋ก ์ ์ฉ๋ฉ๋๋ค. on_fail='reask'๋ก ์ฌ์ฉ์ ๋
ธ์ถ ์์ด ์๋ ์์ ํฉ๋๋ค."
|
| 474 |
+
},
|
| 475 |
+
{
|
| 476 |
+
"id": "docs-sql-4",
|
| 477 |
+
"title": "[Text-to-SQL 4] FastAPI โ ํ ์ ์ฒด๊ฐ ์์ฐ์ด๋ก DB ์กฐํ",
|
| 478 |
+
"task_description": "**์ํฉ**\n์คํฌ๋ฆฝํธ๋ก ๋๋ฆฌ๋ฉด ๋๋ง ์ธ ์ ์์ต๋๋ค. ํ์๋ค๋ ์์ฐ์ด๋ก DB๋ฅผ ์กฐํํ ์ ์๊ฒ API๋ก ๋
ธ์ถํ๊ณ ์ถ์ต๋๋ค.\n\n**๋ฌธ์ **\n์คํฌ๋ฆฝํธ๋ ๊ณต์ ๊ฐ ๋ถ๊ฐ๋ฅํฉ๋๋ค. API ์๋ํฌ์ธํธ๋ก ๋
ธ์ถํด์ผ ํฉ๋๋ค.\n\n**ํด๊ฒฐ**\n์๋ `???`๋ฅผ ์ฑ์ POST `/sql` ์๋ํฌ์ธํธ๋ฅผ ์์ฑํ์ธ์.\n\n```python\n@app.post('/sql')\nasync def generate_sql(q: Query):\n sql = ???\n result = db.run(sql)\n return {'sql': sql, 'result': result}\n```",
|
| 479 |
+
"expected_command": "sql = chain.invoke({'question': q.question})",
|
| 480 |
+
"grading_conditions": ["chain.invoke", "question", "q.question"],
|
| 481 |
+
"hint": "Pydantic ๋ชจ๋ธ `q`์ `.question` ์์ฑ์ผ๋ก ์์ฐ์ด ์ง๋ฌธ์ ๊ฐ์ ธ์ต๋๋ค.",
|
| 482 |
+
"explanation": "`q.question`์ผ๋ก ์์ฐ์ด ์ง๋ฌธ์ ๋ฐ์ ์ฒด์ธ์ ๋๊น๋๋ค. `db.run(sql)`๋ก SQL ์คํ ๊ฒฐ๊ณผ๋ ํจ๊ป ๋ฐํํด ํ๋ก ํธ์๋์์ ๋ฐ๋ก ํ ํํ๋ก ๏ฟฝ๏ฟฝ๏ฟฝ์ฌ์ค ์ ์์ต๋๋ค.",
|
| 483 |
+
"difficulty": "easy",
|
| 484 |
+
"takeaway": "RAG ์ฑ๋ด FastAPI ํจํด๊ณผ ๋์ผํฉ๋๋ค. q.question์ผ๋ก ์ง๋ฌธ์ ๋ฐ์ chain.invoke()์ ๋๊ธฐ๋ ๊ตฌ์กฐ๊ฐ ์ฌ์ฌ์ฉ๋ฉ๋๋ค."
|
| 485 |
+
},
|
| 486 |
+
{
|
| 487 |
+
"id": "docs-brain-1",
|
| 488 |
+
"title": "[Second Brain 1] DirectoryLoader โ ๋
ธํธ 300๊ฐ๋ฅผ ํ ๋ฒ์",
|
| 489 |
+
"task_description": "**ํ๋ก์ ํธ: ๊ฐ์ธ Second Brain**\n๋ด Obsidian ๋
ธํธ๊ฐ 300๊ฐ๊ฐ ๋์ต๋๋ค. \"3๊ฐ์ ์ ์ ๊ณต๋ถํ๋ ๊ทธ ๋ด์ฉ์ด ์ด๋ ํ์ผ์ด์๋๋ผ?\"๋ฅผ ์ฐพ์ผ๋ ค๋ฉด ํ์ผ์ ํ๋์ฉ ์ด์ด๋ด์ผ ํฉ๋๋ค.\n\n---\n\n**๋จ๊ณ 1**: 300๊ฐ ํ์ผ์ ํ๋์ฉ ๋ณต์ฌํด RAG์ ๋ฃ์ ์ ์์ต๋๋ค.\n`DirectoryLoader`๋ก `./notes` ํด๋ ์์ ๋ชจ๋ `.md` ํ์ผ(ํ์ ํด๋ ํฌํจ)์ ํ ๋ฒ์ ๋ก๋ํ์ธ์.\n\n๊ฒฐ๊ณผ๋ฅผ `docs` ๋ณ์์ ์ ์ฅํ์ธ์.",
|
| 490 |
+
"expected_command": "loader = DirectoryLoader('./notes', glob='**/*.md')\ndocs = loader.load()",
|
| 491 |
+
"grading_conditions": ["DirectoryLoader", "./notes", "glob='**/*.md'", "loader.load()"],
|
| 492 |
+
"hint": "`DirectoryLoader('ํด๋', glob='ํจํด')`์ผ๋ก ๋ก๋๋ฅผ ๋ง๋ค๊ณ `.load()`๋ก ์คํํฉ๋๋ค.",
|
| 493 |
+
"explanation": "`**/*.md`๋ `./notes`์ ๋ชจ๋ ํ์ ํด๋์์ `.md` ํ์ผ์ ์ฌ๊ท ๊ฒ์ํฉ๋๋ค. 300๊ฐ ํ์ผ์ด ํ ๋ฒ์ `loader.load()` ํธ์ถ๋ก ๋ชจ๋ `Document` ๊ฐ์ฒด๋ก ๋ณํ๋ฉ๋๋ค.",
|
| 494 |
+
"difficulty": "easy",
|
| 495 |
+
"takeaway": "RAG ์ฑ๋ด์์ ๋ฐฐ์ด DirectoryLoader + glob ํจํด์ด Second Brain ๋
ธํธ ๋ก๋์ ๊ทธ๋๋ก ์ฌ์ฌ์ฉ๋ฉ๋๋ค."
|
| 496 |
+
},
|
| 497 |
+
{
|
| 498 |
+
"id": "docs-brain-2",
|
| 499 |
+
"title": "[Second Brain 2] metadata['source'] โ ๊ฒ์ ๊ฒฐ๊ณผ๊ฐ ์ด๋ ํ์ผ์ธ์ง",
|
| 500 |
+
"task_description": "**์ํฉ**\nRAG ๊ฒ์ ๊ฒฐ๊ณผ๊ฐ ๋์๋๋ฐ \"์ด๊ฒ ์ด๋ ๋
ธํธ์์ ์์ง?\" ์๋ณธ ํ์ผ์ ์ฐพ์ ์ ์์ต๋๋ค. ๋ด์ฉ๋ง ๋ณด์ด๊ณ ์ถ์ฒ๊ฐ ์์ผ๋ ์๋ณธ์ ์ด์ด ๋งฅ๋ฝ์ ๋ ๋ณผ ์๊ฐ ์์ต๋๋ค.\n\n**๋ฌธ์ **\nDocument ๊ฐ์ฒด์ ์ถ์ฒ ์ ๋ณด๊ฐ ์๋๋ฐ ์ฌ์ฉํ์ง ์๊ณ ์์ต๋๋ค.\n\n**ํด๊ฒฐ**\n`docs` ๋ฆฌ์คํธ๋ฅผ ์ํํ๋ฉฐ ๊ฐ ๋ฌธ์์ ํ์ผ ๊ฒฝ๋ก(์ถ์ฒ)์ ๋ด์ฉ ๊ธธ์ด๋ฅผ ์ถ๋ ฅํ๋ ์ฝ๋๋ฅผ ์์ฑํ์ธ์.",
|
| 501 |
+
"expected_command": "for doc in docs:\n print(doc.metadata['source'], len(doc.page_content))",
|
| 502 |
+
"grading_conditions": ["doc.metadata['source']", "len(doc.page_content)"],
|
| 503 |
+
"hint": "ํ์ผ ๊ฒฝ๋ก๋ `doc.metadata['source']`, ๋ด์ฉ์ `doc.page_content`์ ์์ต๋๋ค.",
|
| 504 |
+
"explanation": "`doc.metadata['source']`์ ํ์ผ ๊ฒฝ๋ก๊ฐ ์ ์ฅ๋ฉ๋๋ค. ๊ฒ์ ๊ฒฐ๊ณผ๋ฅผ ๋ณด์ฌ์ค ๋ ์ด ๊ฐ์ ํจ๊ป ํ์ํ๋ฉด ์ฌ์ฉ์๊ฐ ์๋ณธ ํ์ผ๋ก ์ด๋ํ ์ ์์ต๋๋ค.",
|
| 505 |
+
"difficulty": "easy",
|
| 506 |
+
"takeaway": "doc.metadata['source']์ ์๋ณธ ํ์ผ ๊ฒฝ๋ก๊ฐ ์ ์ฅ๋ฉ๋๋ค. RAG ๊ฒ์ ๊ฒฐ๊ณผ์ ์ถ์ฒ๋ฅผ ํ์ํ ๋ ํญ์ ์ด ๊ฐ์ ํ์ฉํฉ๋๋ค."
|
| 507 |
+
},
|
| 508 |
+
{
|
| 509 |
+
"id": "docs-brain-3",
|
| 510 |
+
"title": "[Second Brain 3] FileSensor โ ์ ๋
ธํธ ์ถ๊ฐ ์ ์๋ ์ฌ์ธ๋ฑ์ฑ",
|
| 511 |
+
"task_description": "**์ํฉ**\n์ ๋
ธํธ๋ฅผ ์ถ๊ฐํ๋๋ฐ ๊ฒ์์ด ์ ๋ฉ๋๋ค. `python reindex.py`๋ฅผ ๋งค๋ฒ ์๋์ผ๋ก ์คํํด์ผ ํฉ๋๋ค. ๋
ธํธ๋ฅผ ์ถ๊ฐํ๊ณ ์ฌ์ธ๋ฑ์ฑ์ ์์ด๋ฒ๋ฆฌ๋ ๋ ์ด ์๊น๋๋ค.\n\n**๋ฌธ์ **\n์ ํ์ผ ์ถ๊ฐ๋ฅผ ๊ฐ์งํด ์๋์ผ๋ก ์ฌ์ธ๋ฑ์ฑ์ ํธ๋ฆฌ๊ฑฐํด์ผ ํฉ๋๋ค.\n\n**ํด๊ฒฐ**\nAirflow `FileSensor`๋ก `./notes` ํด๋์ ์ `.md` ํ์ผ์ด ์๊ธฐ๋ฉด ๊ฐ์งํ๋ ํ์คํฌ๋ฅผ ๋ง๋์ธ์.\n- task_id: `'wait_for_new_note'`\n- filepath: `'./notes/*.md'`\n- poke_interval: `300` (5๋ถ๋ง๋ค ํ์ธ)",
|
| 512 |
+
"expected_command": "wait_for_new_note = FileSensor(\n task_id='wait_for_new_note',\n filepath='./notes/*.md',\n poke_interval=300\n)",
|
| 513 |
+
"grading_conditions": ["FileSensor", "task_id='wait_for_new_note'", "filepath", "poke_interval=300"],
|
| 514 |
+
"hint": "`FileSensor(task_id='...', filepath='...', poke_interval=์ด)` ํจํด์
๋๋ค.",
|
| 515 |
+
"explanation": "`FileSensor`๋ ์ง์ ํ ํ์ผ์ด ์กด์ฌํ ๋๊น์ง ์ฃผ๊ธฐ์ ์ผ๋ก ํ์ธํฉ๋๋ค. ํ์ผ์ด ๊ฐ์ง๋๋ฉด ๋ค์ ํ์คํฌ(์ฌ์ธ๋ฑ์ฑ)๊ฐ ์๋ ์คํ๋ฉ๋๋ค. `poke_interval=300`์ 5๋ถ๋ง๋ค ํ์ธํฉ๋๋ค.",
|
| 516 |
+
"difficulty": "medium",
|
| 517 |
+
"takeaway": "FileSensor๋ ํ์ผ ์ถ๊ฐ๋ฅผ ๊ฐ์งํด ํ์ Airflow ํ์คํฌ๋ฅผ ํธ๋ฆฌ๊ฑฐํฉ๋๋ค. @daily์ ๋ฌ๋ฆฌ ์ด๋ฒคํธ ๊ธฐ๋ฐ์ผ๋ก ๋์ํฉ๋๋ค."
|
| 518 |
+
},
|
| 519 |
+
{
|
| 520 |
+
"id": "docs-brain-4",
|
| 521 |
+
"title": "[Second Brain 4] Streamlit โ ๋
ธํธ ๊ฒ์ UI",
|
| 522 |
+
"task_description": "**์ํฉ**\n์ง๊ธ์ ํฐ๋ฏธ๋์์ `retriever.invoke('๊ฒ์์ด')`๋ฅผ ์ง์ ์
๋ ฅํด์ผ ํฉ๋๋ค. ํ์๋ค์ด ์ธ ์ ์์ต๋๋ค.\n\n**๋ฌธ์ **\nCLI๋ ๊ฐ๋ฐ์๋ง ์ธ ์ ์์ต๋๋ค.\n\n**ํด๊ฒฐ**\nStreamlit์ผ๋ก ๊ฒ์ UI๋ฅผ ๋ง๋์ธ์.\n- ํด๋ ๊ฒฝ๋ก ํ
์คํธ ์
๋ ฅ (`folder`, ๊ธฐ๋ณธ๊ฐ `'./notes'`)\n- ๊ฒ์์ด ํ
์คํธ ์
๋ ฅ (`query`)\n- '๊ฒ์' ๋ฒํผ ํด๋ฆญ ์ `retriever.invoke(query)` ์คํ โ `results`์ ์ ์ฅ",
|
| 523 |
+
"expected_command": "folder = st.text_input('๋
ธํธ ํด๋ ๊ฒฝ๋ก', value='./notes')\nquery = st.text_input('๊ฒ์ํ ๋ด์ฉ')\nif st.button('๊ฒ์'):\n results = retriever.invoke(query)",
|
| 524 |
+
"grading_conditions": ["st.text_input", "st.button('๊ฒ์')", "retriever.invoke(query)"],
|
| 525 |
+
"hint": "`st.text_input`, `st.button`, `retriever.invoke` ์ธ ๊ฐ์ง๋ฅผ ์์๋๋ก ์๋๋ค.",
|
| 526 |
+
"explanation": "`if st.button('๊ฒ์'):` ๋ธ๋ก ์์ ๋ฌด๊ฑฐ์ด ์์
์ ๋ฃ์ผ๋ฉด ๋ฒํผ์ ๋๋ ์ ๋๋ง ์คํ๋ฉ๋๋ค. ํด๋ ๊ฒฝ๋ก๊ฐ ๋ฐ๋๋ฉด `st.cache_resource`๋ฅผ clearํด retriever๋ฅผ ์ฌ์ด๊ธฐํํ๋ ๋ก์ง์ ์ถ๊ฐํ๋ฉด ์์ฑ์
๋๋ค.",
|
| 527 |
+
"difficulty": "easy",
|
| 528 |
+
"takeaway": "st.text_input + st.button + retriever.invoke ์กฐํฉ์ RAG ์ฑ๋ด์์ ๋ฐฐ์ด Streamlit ํจํด์ด Second Brain UI์ ๊ทธ๋๋ก ์ ์ฉ๋ ์์
๋๋ค."
|
| 529 |
+
}
|
| 530 |
+
]
|
cert_study_app/content/tool_docs/quizzes.json
ADDED
|
@@ -0,0 +1,1032 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
[
|
| 2 |
+
{
|
| 3 |
+
"id": "docs-q8",
|
| 4 |
+
"lesson_id": "docs-ollama-models",
|
| 5 |
+
"question_type": "multiple_choice",
|
| 6 |
+
"question": "Ollama์์ ๋ชจ๋ธ์ด ๋ก์ปฌ์ ์์ ๋ `ollama run qwen2.5:7b`๋ฅผ ์คํํ๋ฉด?",
|
| 7 |
+
"options": [
|
| 8 |
+
"์๋์ผ๋ก ๋ชจ๋ธ์ ๋ค์ด๋ก๋ํ ๋ค ์คํํ๋ค",
|
| 9 |
+
"์ค๋ฅ๋ฅผ ์ถ๋ ฅํ๊ณ ์ข
๋ฃํ๋ค",
|
| 10 |
+
"์ต์ ๋ชจ๋ธ๋ก ๋์ฒดํด ์คํํ๋ค",
|
| 11 |
+
"์๋ฒ๋ง ์์ํ๊ณ ๋๊ธฐํ๋ค"
|
| 12 |
+
],
|
| 13 |
+
"answer": "์๋์ผ๋ก ๋ชจ๋ธ์ ๋ค์ด๋ก๋ํ ๋ค ์คํํ๋ค",
|
| 14 |
+
"explanation": "`ollama run`์ ๋ชจ๋ธ์ด ์์ผ๋ฉด ์๋์ผ๋ก pullํ ๋ค ๋ํํ ์ธ์
์ ์์ํฉ๋๋ค. `ollama pull`์ ๋จผ์ ์คํํ ํ์๊ฐ ์์ต๋๋ค.",
|
| 15 |
+
"source_id": "official-docs-ollama"
|
| 16 |
+
},
|
| 17 |
+
{
|
| 18 |
+
"id": "docs-q9",
|
| 19 |
+
"lesson_id": "docs-streamlit-secrets",
|
| 20 |
+
"question_type": "multiple_choice",
|
| 21 |
+
"question": "Streamlit ๋ก์ปฌ ๊ฐ๋ฐ ์ API ํค๋ฅผ ์์ ํ๊ฒ ๊ด๋ฆฌํ๋ ์ฌ๋ฐ๋ฅธ ๋ฐฉ๋ฒ์?",
|
| 22 |
+
"options": [
|
| 23 |
+
".streamlit/secrets.toml์ ์ ์ฅํ๊ณ .gitignore์ ์ถ๊ฐ",
|
| 24 |
+
"st.session_state์ ์ ์ฅ",
|
| 25 |
+
"์ฝ๋ ์๋จ์ ์์๋ก ์ ์ธ",
|
| 26 |
+
"requirements.txt์ ํฌํจ"
|
| 27 |
+
],
|
| 28 |
+
"answer": ".streamlit/secrets.toml์ ์ ์ฅํ๊ณ .gitignore์ ์ถ๊ฐ",
|
| 29 |
+
"explanation": "๋ฏผ๊ฐ ์ ๋ณด๋ secrets.toml์ ๋ฃ๊ณ , ์ด ํ์ผ์ ๋ฐ๋์ .gitignore์ ์ถ๊ฐํด Git์ ์ปค๋ฐ๋์ง ์๋๋ก ํด์ผ ํฉ๋๋ค.",
|
| 30 |
+
"source_id": "official-docs-streamlit"
|
| 31 |
+
},
|
| 32 |
+
{
|
| 33 |
+
"id": "docs-q10",
|
| 34 |
+
"lesson_id": "docs-hf-docker-space",
|
| 35 |
+
"question_type": "multiple_choice",
|
| 36 |
+
"question": "Hugging Face Docker Space์์ ์ฑ์ด ๋
ธ์ถํด์ผ ํ๋ ๊ธฐ๋ณธ ํฌํธ๋?",
|
| 37 |
+
"options": [
|
| 38 |
+
"7860",
|
| 39 |
+
"8501",
|
| 40 |
+
"11434",
|
| 41 |
+
"3000"
|
| 42 |
+
],
|
| 43 |
+
"answer": "7860",
|
| 44 |
+
"explanation": "Docker Space์ ๊ธฐ๋ณธ ์ฑ ํฌํธ๋ 7860์
๋๋ค. README ๋ฉํ๋ฐ์ดํฐ์ `app_port`์ Dockerfile์ EXPOSE ํฌํธ๋ฅผ 7860์ผ๋ก ์ผ์น์์ผ์ผ ํฉ๋๋ค.",
|
| 45 |
+
"source_id": "official-docs-huggingface"
|
| 46 |
+
},
|
| 47 |
+
{
|
| 48 |
+
"id": "docs-q11",
|
| 49 |
+
"lesson_id": "docs-ollama-models",
|
| 50 |
+
"question_type": "command",
|
| 51 |
+
"question": "๋ก์ปฌ์ ์๋ Ollama ๋ชจ๋ธ ๋ชฉ๋ก์ ํ์ธํ๋ CLI ๋ช
๋ น์ด๋ฅผ ์
๋ ฅํ์ธ์.",
|
| 52 |
+
"options": [],
|
| 53 |
+
"answer": "ollama list",
|
| 54 |
+
"explanation": "`ollama list`๋ ๋ก์ปฌ์ ๋ค์ด๋ก๋๋ ๋ชจ๋ธ ๋ชฉ๋ก๊ณผ ํฌ๊ธฐ, ์์ ์ผ์ ์ถ๋ ฅํฉ๋๋ค. `ollama pull <๋ชจ๋ธ>`๋ก ์ ๋ชจ๋ธ์ ๋ฐ์ ์ ์์ต๋๋ค.",
|
| 55 |
+
"source_id": "official-docs-ollama"
|
| 56 |
+
},
|
| 57 |
+
{
|
| 58 |
+
"id": "docs-q12",
|
| 59 |
+
"lesson_id": "docs-langchain-rag",
|
| 60 |
+
"question_type": "multiple_choice",
|
| 61 |
+
"question": "LangChain RAG ํ์ดํ๋ผ์ธ์์ ๋ฌธ์๋ฅผ Vector Store์ ๋ฃ๊ธฐ ์ ์ ๋ฐ๋์ ํด์ผ ํ๋ ์์
์?",
|
| 62 |
+
"options": [
|
| 63 |
+
"๋ฌธ์๋ฅผ ์์ ์ฒญํฌ(chunk)๋ก ๋ถํ ํ ์๋ฒ ๋ฉ ์์ฑ",
|
| 64 |
+
"๋ฌธ์๋ฅผ PDF๋ก ๋ณํ",
|
| 65 |
+
"LLM์ ๋ฌธ์๋ฅผ ์ง์ ์ ๋ฌ",
|
| 66 |
+
"API ํค๋ฅผ ํ๊ฒฝ๋ณ์์ ์ ์ฅ"
|
| 67 |
+
],
|
| 68 |
+
"answer": "๋ฌธ์๋ฅผ ์์ ์ฒญํฌ(chunk)๋ก ๋ถํ ํ ์๋ฒ ๋ฉ ์์ฑ",
|
| 69 |
+
"explanation": "RAG๋ ๋ฌธ์ โ ์ฒญํฌ ๋ถํ (TextSplitter) โ ์๋ฒ ๋ฉ ๋ณํ โ Vector Store ์ ์ฅ ์์ผ๋ก ์ธ๋ฑ์ฑํฉ๋๋ค. ์ฒญํฌ๊ฐ ๋๋ฌด ํฌ๋ฉด ๊ฒ์ ํ์ง์ด ๋จ์ด์ง๋๋ค.",
|
| 70 |
+
"source_id": "official-docs-langchain"
|
| 71 |
+
},
|
| 72 |
+
{
|
| 73 |
+
"id": "docs-q13",
|
| 74 |
+
"lesson_id": "docs-streamlit-state",
|
| 75 |
+
"question_type": "multiple_choice",
|
| 76 |
+
"question": "Streamlit์์ ๋ฒํผ ํด๋ฆญ ํ์๋ฅผ ํ์ด์ง ์ ํ ํ์๋ ์ ์งํ๋ ค๋ฉด ์ด๋ป๊ฒ ํด์ผ ํ๋๊ฐ?",
|
| 77 |
+
"options": [
|
| 78 |
+
"st.session_state์ ์ ์ฅ",
|
| 79 |
+
"์ ์ญ ๋ณ์๋ก ์ ์ธ",
|
| 80 |
+
"st.cache_data์ ์ ์ฅ",
|
| 81 |
+
"ํ์ผ์ ๊ธฐ๋ก"
|
| 82 |
+
],
|
| 83 |
+
"answer": "st.session_state์ ์ ์ฅ",
|
| 84 |
+
"explanation": "Streamlit์ ๋งค ์ํธ์์ฉ๋ง๋ค ์คํฌ๋ฆฝํธ ์ ์ฒด๋ฅผ ์ฌ์คํํฉ๋๋ค. ์ ์ญ ๋ณ์๋ ์ฌ์คํ ์ ์ด๊ธฐํ๋๋ฏ๋ก ์ธ์
๊ฐ ๊ฐ์ ์ ์งํ๋ ค๋ฉด `st.session_state`๋ฅผ ์ฌ์ฉํด์ผ ํฉ๋๋ค.",
|
| 85 |
+
"source_id": "official-docs-streamlit"
|
| 86 |
+
},
|
| 87 |
+
{
|
| 88 |
+
"id": "docs-q14",
|
| 89 |
+
"lesson_id": "docs-streamlit-cache",
|
| 90 |
+
"question_type": "multiple_choice",
|
| 91 |
+
"question": "`st.cache_data`์ `st.cache_resource`์ ์ฃผ๋ ์ฐจ์ด๋?",
|
| 92 |
+
"options": [
|
| 93 |
+
"cache_data๋ ๋ฐ์ดํฐ(DataFrame ๋ฑ) ์ง๋ ฌํ ์บ์, cache_resource๋ DB ์ฐ๊ฒฐยท๋ชจ๋ธ ๊ฐ์ ๊ณต์ ๋ฆฌ์์ค ์บ์",
|
| 94 |
+
"๋ ๋ฐ์ฝ๋ ์ดํฐ๋ ์์ ํ ๋์ผํ๋ค",
|
| 95 |
+
"cache_resource๋ ํ์ผ์ ์บ์ํ๊ณ cache_data๋ ์ฐ๊ฒฐ์ ์บ์ํ๋ค",
|
| 96 |
+
"cache_data๊ฐ ํญ์ ๋ ๋น ๋ฅด๋ค"
|
| 97 |
+
],
|
| 98 |
+
"answer": "cache_data๋ ๋ฐ์ดํฐ(DataFrame ๋ฑ) ์ง๋ ฌํ ์บ์, cache_resource๋ DB ์ฐ๊ฒฐยท๋ชจ๋ธ ๊ฐ์ ๊ณต์ ๋ฆฌ์์ค ์บ์",
|
| 99 |
+
"explanation": "`st.cache_data`๋ ๋ฐํ๊ฐ์ ๋ณต์ฌํด ๊ฐ ์ธ์
์ ๋
๋ฆฝ ์ ๊ณตํฉ๋๋ค. `st.cache_resource`๋ ๊ฐ์ฒด๋ฅผ ๊ณต์ ํ๋ฏ๋ก DB ์ฐ๊ฒฐ, ML ๋ชจ๋ธ์ฒ๋ผ ํ ๋ฒ๋ง ๋ก๋ํด์ผ ํ๋ ๋ฆฌ์์ค์ ์๋๋ค.",
|
| 100 |
+
"source_id": "official-docs-streamlit"
|
| 101 |
+
},
|
| 102 |
+
{
|
| 103 |
+
"id": "docs-q15",
|
| 104 |
+
"lesson_id": "docs-hf-spaces",
|
| 105 |
+
"question_type": "multiple_choice",
|
| 106 |
+
"question": "Hugging Face Spaces์์ Streamlit ์ฑ์ ๋ฐฐํฌํ ๋ README.md์ ๋ฐ๋์ ํฌํจํด์ผ ํ๋ ๋ฉํ๋ฐ์ดํฐ ํ๋๋?",
|
| 107 |
+
"options": [
|
| 108 |
+
"sdk: streamlit",
|
| 109 |
+
"runtime: python",
|
| 110 |
+
"framework: web",
|
| 111 |
+
"deploy: auto"
|
| 112 |
+
],
|
| 113 |
+
"answer": "sdk: streamlit",
|
| 114 |
+
"explanation": "HF Spaces README ์๋จ YAML ๋ฉํ๋ฐ์ดํฐ์์ `sdk: streamlit`์ ์ง์ ํด์ผ Streamlit ์ฑ์ผ๋ก ์ธ์ํฉ๋๋ค. `sdk_version`์ผ๋ก ๋ฒ์ ๋ ๊ณ ์ ํ ์ ์์ต๋๋ค.",
|
| 115 |
+
"source_id": "official-docs-huggingface"
|
| 116 |
+
},
|
| 117 |
+
{
|
| 118 |
+
"id": "docs-q16",
|
| 119 |
+
"lesson_id": "docs-vectorstore",
|
| 120 |
+
"question_type": "multiple_choice",
|
| 121 |
+
"question": "LangChain์์ Retriever์ ์ญํ ์?",
|
| 122 |
+
"options": [
|
| 123 |
+
"์ง๋ฌธ๊ณผ ์ ์ฌํ ๋ฌธ์๋ฅผ Vector Store์์ ๊ฒ์ํด ๋ฐํํ๋ค",
|
| 124 |
+
"LLM์ ํธ์ถํด ๋ต๋ณ์ ์์ฑํ๋ค",
|
| 125 |
+
"ํ๋กฌํํธ ํ
ํ๋ฆฟ์ ๊ด๋ฆฌํ๋ค",
|
| 126 |
+
"API ํค๋ฅผ ์ ์ฅํ๋ค"
|
| 127 |
+
],
|
| 128 |
+
"answer": "์ง๋ฌธ๊ณผ ์ ์ฌํ ๋ฌธ์๋ฅผ Vector Store์์ ๊ฒ์ํด ๋ฐํํ๋ค",
|
| 129 |
+
"explanation": "Retriever๋ ์ง๋ฌธ ์๋ฒ ๋ฉ๊ณผ ๊ฐ์ฅ ์ ์ฌํ ๋ฌธ์ ์ฒญํฌ๋ฅผ Vector Store์์ ๊ฐ์ ธ์ต๋๋ค. RAG ์ฒด์ธ์์ `retriever | prompt | llm` ํ์ดํ๋ผ์ธ์ ์ฒซ ๋จ๊ณ์
๋๋ค.",
|
| 130 |
+
"source_id": "official-docs-langchain"
|
| 131 |
+
},
|
| 132 |
+
{
|
| 133 |
+
"id": "docs-q17",
|
| 134 |
+
"lesson_id": "docs-streamlit-state",
|
| 135 |
+
"question_type": "multiple_choice",
|
| 136 |
+
"question": "`st.form`์ ์ฌ์ฉํ๋ ์ฃผ๋ ์ด์ ๋?",
|
| 137 |
+
"options": [
|
| 138 |
+
"์ฌ๋ฌ ์
๋ ฅ ์์ ฏ์ ๋ฌถ์ด Submit ๋ฒํผ ํด๋ฆญ ์์๋ง rerun์ด ๋ฐ์ํ๋๋ก ํ๋ค",
|
| 139 |
+
"ํผ ๋ด ์์ ฏ์ด ๋ ๋น ๋ฅด๊ฒ ๋ ๋๋ง๋๋ค",
|
| 140 |
+
"์
๋ ฅ๊ฐ์ ์๋์ผ๋ก DB์ ์ ์ฅํ๋ค",
|
| 141 |
+
"ํผ์ ๋ชจ๋ฐ์ผ์์๋ง ์ฌ์ฉ ๊ฐ๋ฅํ๋ค"
|
| 142 |
+
],
|
| 143 |
+
"answer": "์ฌ๋ฌ ์
๋ ฅ ์์ ฏ์ ๋ฌถ์ด Submit ๋ฒํผ ํด๋ฆญ ์์๋ง rerun์ด ๋ฐ์ํ๋๋ก ํ๋ค",
|
| 144 |
+
"explanation": "์ผ๋ฐ ์์ ฏ์ ๊ฐ์ด ๋ฐ๋ ๋๋ง๋ค rerun๋ฉ๋๋ค. `st.form`์ผ๋ก ๋ฌถ์ผ๋ฉด Submit ๋ฒํผ์ ๋๋ฅผ ๋๋ง rerun๋์ด ๋ถํ์ํ ์ฌ์คํ์ ๋ง๊ณ UX๋ฅผ ๊ฐ์ ํฉ๋๋ค.",
|
| 145 |
+
"source_id": "official-docs-streamlit"
|
| 146 |
+
},
|
| 147 |
+
{
|
| 148 |
+
"id": "docs-q18",
|
| 149 |
+
"lesson_id": "docs-hf-spaces",
|
| 150 |
+
"question_type": "multiple_choice",
|
| 151 |
+
"question": "Hugging Face `pipeline()` ํจ์๋ก ๊ฐ์ฑ ๋ถ์ ํ์คํฌ๋ฅผ ์คํํ๋ ค๋ฉด?",
|
| 152 |
+
"options": [
|
| 153 |
+
"pipeline('sentiment-analysis')",
|
| 154 |
+
"pipeline('classification')",
|
| 155 |
+
"pipeline('text-generation')",
|
| 156 |
+
"pipeline('translation')"
|
| 157 |
+
],
|
| 158 |
+
"answer": "pipeline('sentiment-analysis')",
|
| 159 |
+
"explanation": "`from transformers import pipeline; classifier = pipeline('sentiment-analysis')` ๋ก ๊ธฐ๋ณธ ๊ฐ์ฑ ๋ถ์ ๋ชจ๋ธ์ ๋ก๋ํฉ๋๋ค. ๊ฒฐ๊ณผ๋ `[{'label': 'POSITIVE', 'score': 0.99}]` ํ์์
๋๋ค.",
|
| 160 |
+
"source_id": "official-docs-huggingface"
|
| 161 |
+
},
|
| 162 |
+
{
|
| 163 |
+
"id": "docs-q19",
|
| 164 |
+
"lesson_id": "docs-lcel",
|
| 165 |
+
"question_type": "multiple_choice",
|
| 166 |
+
"question": "LangChain LCEL(LangChain Expression Language)์์ `|` ์ฐ์ฐ์์ ์ญํ ์?",
|
| 167 |
+
"options": [
|
| 168 |
+
"์ ๋จ๊ณ์ ์ถ๋ ฅ์ ๋ค์ ๋จ๊ณ์ ์
๋ ฅ์ผ๋ก ์ฐ๊ฒฐํ๋ ์ฒด์ธ ํ์ดํ๋ผ์ธ์ ๊ตฌ์ฑํ๋ค",
|
| 169 |
+
"๋ ์ฒด์ธ์ ๋ณ๋ ฌ๋ก ์คํํ๋ค",
|
| 170 |
+
"์ฒด์ธ์ ์ทจ์ํ๋ค",
|
| 171 |
+
"์ถ๋ ฅ์ JSON์ผ๋ก ๋ณํํ๋ค"
|
| 172 |
+
],
|
| 173 |
+
"answer": "์ ๋จ๊ณ์ ์ถ๋ ฅ์ ๋ค์ ๋จ๊ณ์ ์
๋ ฅ์ผ๋ก ์ฐ๊ฒฐํ๋ ์ฒด์ธ ํ์ดํ๋ผ์ธ์ ๊ตฌ์ฑํ๋ค",
|
| 174 |
+
"explanation": "LCEL์ `|`๋ ์ ๋์ค ํ์ดํ์ ๊ฐ์ ๊ฐ๋
์
๋๋ค. `chain = retriever | prompt | llm | parser`์ฒ๋ผ ๊ฐ Runnable์ ์ถ๋ ฅ์ด ๋ค์ ์
๋ ฅ์ด ๋ฉ๋๋ค.",
|
| 175 |
+
"source_id": "official-docs-langchain"
|
| 176 |
+
},
|
| 177 |
+
{
|
| 178 |
+
"id": "docs-q21",
|
| 179 |
+
"lesson_id": "docs-lcel",
|
| 180 |
+
"question_type": "multiple_choice",
|
| 181 |
+
"question": "LangChain LCEL์์ `RunnableParallel`์ ์ฌ์ฉํ๋ ๋ชฉ์ ์?",
|
| 182 |
+
"options": [
|
| 183 |
+
"์ฌ๋ฌ Runnable์ ๋์์ ์คํํ๊ณ ๊ฒฐ๊ณผ๋ฅผ ๋์
๋๋ฆฌ๋ก ํฉ์น๋ค",
|
| 184 |
+
"์ฒด์ธ์ ์์ฐจ์ ์ผ๋ก ์คํํ๋ค",
|
| 185 |
+
"๊ฒฐ๊ณผ๋ฅผ ์บ์ํ๋ค",
|
| 186 |
+
"์๋ฌ๋ฅผ ๋ฌด์ํ๋ค"
|
| 187 |
+
],
|
| 188 |
+
"answer": "์ฌ๋ฌ Runnable์ ๋์์ ์คํํ๊ณ ๊ฒฐ๊ณผ๋ฅผ ๋์
๋๋ฆฌ๋ก ํฉ์น๋ค",
|
| 189 |
+
"explanation": "`RunnableParallel({'context': retriever, 'question': RunnablePassthrough()})`์ฒ๋ผ ์ฌ๋ฌ ๋ธ๋์น๋ฅผ ๋ณ๋ ฌ ์คํํด dict๋ก ํฉ์นฉ๋๋ค. RAG์์ ์ปจํ
์คํธ ๊ฒ์๊ณผ ์ง๋ฌธ ์ ๋ฌ์ ๋์์ ์ฒ๋ฆฌํ ๋ ์๋๋ค.",
|
| 190 |
+
"source_id": "official-docs-langchain"
|
| 191 |
+
},
|
| 192 |
+
{
|
| 193 |
+
"id": "docs-q22",
|
| 194 |
+
"lesson_id": "docs-vectorstore",
|
| 195 |
+
"question_type": "multiple_choice",
|
| 196 |
+
"question": "FAISS Vector Store์์ `similarity_search(query, k=4)`์ `k` ํ๋ผ๋ฏธํฐ์ ์๋ฏธ๋?",
|
| 197 |
+
"options": [
|
| 198 |
+
"๋ฐํํ ์ ์ฌ ๋ฌธ์ ์ฒญํฌ์ ์ต๋ ์",
|
| 199 |
+
"๊ฒ์ ์๋ฒ ๋ฉ ์ฐจ์ ์",
|
| 200 |
+
"์ต์ ์ ์ฌ๋ ์ ์",
|
| 201 |
+
"์ธ๋ฑ์ค ํ์ผ ๋ฒ์ "
|
| 202 |
+
],
|
| 203 |
+
"answer": "๋ฐํํ ์ ์ฌ ๋ฌธ์ ์ฒญํฌ์ ์ต๋ ์",
|
| 204 |
+
"explanation": "`k`๋ ๊ฐ์ฅ ์ ์ฌํ ์์ k๊ฐ์ ์ฒญํฌ๋ฅผ ๋ฐํํฉ๋๋ค. k๊ฐ ํฌ๋ฉด ๋ ๋ง์ ์ปจํ
์คํธ๋ฅผ LLM์ ์ ๊ณตํ์ง๋ง ํ๋กฌํํธ ๊ธธ์ด๊ฐ ๋์ด๋ฉ๋๋ค.",
|
| 205 |
+
"source_id": "official-docs-langchain"
|
| 206 |
+
},
|
| 207 |
+
{
|
| 208 |
+
"id": "docs-q23",
|
| 209 |
+
"lesson_id": "docs-streamlit-secrets",
|
| 210 |
+
"question_type": "command",
|
| 211 |
+
"question": "Streamlit ์ฑ ์ฝ๋์์ secrets.toml์ `OPENAI_API_KEY` ๊ฐ์ ์ฝ๋ ๋ฐฉ๋ฒ์ ์
๋ ฅํ์ธ์.",
|
| 212 |
+
"options": [],
|
| 213 |
+
"answer": "st.secrets[\"OPENAI_API_KEY\"]",
|
| 214 |
+
"explanation": "`st.secrets[\"ํค์ด๋ฆ\"]` ๋๋ `st.secrets.ํค์ด๋ฆ`์ผ๋ก ์ ๊ทผํฉ๋๋ค. ๋ฐฐํฌ ์ Streamlit Cloud์ Secrets ๊ด๋ฆฌ ํ๋ฉด์์ ๋์ผ ํค๋ก ๋ฑ๋กํ๋ฉด ๋ฉ๋๋ค.",
|
| 215 |
+
"source_id": "official-docs-streamlit"
|
| 216 |
+
},
|
| 217 |
+
{
|
| 218 |
+
"id": "docs-q24",
|
| 219 |
+
"lesson_id": "docs-hf-docker-space",
|
| 220 |
+
"question_type": "multiple_choice",
|
| 221 |
+
"question": "Hugging Face Docker Space์์ ํ๊ฒฝ๋ณ์(API ํค ๋ฑ)๋ฅผ ์์ ํ๊ฒ ์ฃผ์
ํ๋ ๋ฐฉ๋ฒ์?",
|
| 222 |
+
"options": [
|
| 223 |
+
"Space Settings์ Repository Secrets์ ๋ฑ๋กํ๋ฉด ๋น๋/๋ฐํ์ ํ๊ฒฝ๋ณ์๋ก ์ฃผ์
๋๋ค",
|
| 224 |
+
"Dockerfile์ ENV๋ก ํ๋์ฝ๋ฉํ๋ค",
|
| 225 |
+
"requirements.txt์ ์ถ๊ฐํ๋ค",
|
| 226 |
+
"README ๋ฉํ๋ฐ์ดํฐ์ base64๋ก ์ธ์ฝ๋ฉํด ๋ฃ๋๋ค"
|
| 227 |
+
],
|
| 228 |
+
"answer": "Space Settings์ Repository Secrets์ ๋ฑ๋กํ๋ฉด ๋น๋/๋ฐํ์ ํ๊ฒฝ๋ณ์๋ก ์ฃผ์
๋๋ค",
|
| 229 |
+
"explanation": "HF Space์ Repository Secrets๋ Docker ๋น๋์ ์ปจํ
์ด๋ ๋ฐํ์์ ํ๊ฒฝ๋ณ์๋ก ์ฃผ์
๋ฉ๋๋ค. Dockerfile์ด๋ ์ฝ๋์ ๋น๋ฐ์ ํ๋์ฝ๋ฉํ๋ฉด ๊ณต๊ฐ ์ ์ฅ์์์ ๋
ธ์ถ๋ฉ๋๋ค.",
|
| 230 |
+
"source_id": "official-docs-huggingface"
|
| 231 |
+
},
|
| 232 |
+
{
|
| 233 |
+
"id": "docs-q20",
|
| 234 |
+
"lesson_id": "docs-ollama-api",
|
| 235 |
+
"question_type": "command",
|
| 236 |
+
"question": "Ollama REST API๋ก `llama3.2` ๋ชจ๋ธ์ 'Hello' ํ๋กฌํํธ๋ฅผ ์คํธ๋ฆฌ๋ฐ ์์ด ์์ฒญํ๋ curl ๋ช
๋ น์ด๋ฅผ ์
๋ ฅํ์ธ์.",
|
| 237 |
+
"options": [],
|
| 238 |
+
"answer": "curl http://localhost:11434/api/generate -d '{\"model\":\"llama3.2\",\"prompt\":\"Hello\",\"stream\":false}'",
|
| 239 |
+
"explanation": "Ollama API๋ ๊ธฐ๋ณธ์ ์ผ๋ก ์คํธ๋ฆฌ๋ฐ ์๋ต์ ๋ฐํํฉ๋๋ค. `\"stream\": false`๋ฅผ ์ถ๊ฐํ๋ฉด ์์ฑ๋ ์๋ต์ ํ ๋ฒ์ ๋ฐ์ ์ ์์ต๋๋ค.",
|
| 240 |
+
"source_id": "official-docs-ollama"
|
| 241 |
+
},
|
| 242 |
+
{
|
| 243 |
+
"id": "docs-q25",
|
| 244 |
+
"lesson_id": "docs-fastapi",
|
| 245 |
+
"question_type": "multiple_choice",
|
| 246 |
+
"question": "FastAPI์์ POST `/ask` ์๋ํฌ์ธํธ๋ฅผ ์ ์ํ ๋ ์์ฒญ ๋ฐ๋๋ฅผ ๊ฒ์ฆํ๋ ์ฌ๋ฐ๋ฅธ ๋ฐฉ๋ฒ์?",
|
| 247 |
+
"options": [
|
| 248 |
+
"Pydantic BaseModel์ ์์ํ ํด๋์ค๋ฅผ ํ๋ผ๋ฏธํฐ ํ์
์ผ๋ก ์ง์ ํ๋ค",
|
| 249 |
+
"request.body()๋ฅผ ์๋์ผ๋ก ํ์ฑํ๋ค",
|
| 250 |
+
"์ ์ญ ๋์
๋๋ฆฌ์ JSON์ ์ ์ฅํ๋ค",
|
| 251 |
+
"Flask์ request.json์ ์ฌ์ฉํ๋ค"
|
| 252 |
+
],
|
| 253 |
+
"answer": "Pydantic BaseModel์ ์์ํ ํด๋์ค๋ฅผ ํ๋ผ๋ฏธํฐ ํ์
์ผ๋ก ์ง์ ํ๋ค",
|
| 254 |
+
"explanation": "FastAPI๋ ํจ์ ํ๋ผ๋ฏธํฐ์ Pydantic ๋ชจ๋ธ์ ํ์
ํํธ๋ก ์ง์ ํ๋ฉด ์๋์ผ๋ก JSON ๋ฐ๋๋ฅผ ํ์ฑยท๊ฒ์ฆํฉ๋๋ค. ์๋ชป๋ ์
๋ ฅ์ 422 ์ค๋ฅ๋ฅผ ๋ฐํํฉ๋๋ค.",
|
| 255 |
+
"source_id": "official-docs-fastapi"
|
| 256 |
+
},
|
| 257 |
+
{
|
| 258 |
+
"id": "docs-q26",
|
| 259 |
+
"lesson_id": "docs-fastapi",
|
| 260 |
+
"question_type": "multiple_choice",
|
| 261 |
+
"question": "FastAPI ๊ฐ๋ฐ ์๋ฒ๋ฅผ ์๋ ์ฌ์์(reload) ๋ชจ๋๋ก ์คํํ๋ ๋ช
๋ น์ด๋?",
|
| 262 |
+
"options": [
|
| 263 |
+
"uvicorn main:app --reload",
|
| 264 |
+
"python main.py --dev",
|
| 265 |
+
"fastapi run --watch main.py",
|
| 266 |
+
"gunicorn main:app --workers 1"
|
| 267 |
+
],
|
| 268 |
+
"answer": "uvicorn main:app --reload",
|
| 269 |
+
"explanation": "`uvicorn main:app --reload`๋ ํ์ผ ๋ณ๊ฒฝ์ ๊ฐ์งํด ์๋ฒ๋ฅผ ์๋ ์ฌ์์ํฉ๋๋ค. `main`์ ํ์ด์ฌ ํ์ผ๋ช
, `app`์ FastAPI ์ธ์คํด์ค ๋ณ์๋ช
์
๋๋ค.",
|
| 270 |
+
"source_id": "official-docs-fastapi"
|
| 271 |
+
},
|
| 272 |
+
{
|
| 273 |
+
"id": "docs-q27",
|
| 274 |
+
"lesson_id": "docs-langsmith",
|
| 275 |
+
"question_type": "multiple_choice",
|
| 276 |
+
"question": "LangSmith ์ถ์ ์ ํ์ฑํํ๊ธฐ ์ํด ๋ฐ๋์ ์ค์ ํด์ผ ํ๋ ํ๊ฒฝ๋ณ์๊ฐ ์๋ ๊ฒ์?",
|
| 277 |
+
"options": [
|
| 278 |
+
"LANGCHAIN_MODEL",
|
| 279 |
+
"LANGCHAIN_TRACING_V2",
|
| 280 |
+
"LANGCHAIN_API_KEY",
|
| 281 |
+
"LANGCHAIN_PROJECT"
|
| 282 |
+
],
|
| 283 |
+
"answer": "LANGCHAIN_MODEL",
|
| 284 |
+
"explanation": "LangSmith ์ถ์ ์ ํ์ํ ํ๊ฒฝ๋ณ์๋ `LANGCHAIN_TRACING_V2=true`, `LANGCHAIN_API_KEY`, `LANGCHAIN_PROJECT` ์ธ ๊ฐ์ง์
๋๋ค. ๋ชจ๋ธ๋ช
์ ์ฒด์ธ ์ฝ๋์์ ์ง์ ์ง์ ํฉ๋๋ค.",
|
| 285 |
+
"source_id": "official-docs-langchain"
|
| 286 |
+
},
|
| 287 |
+
{
|
| 288 |
+
"id": "docs-q28",
|
| 289 |
+
"lesson_id": "docs-langsmith",
|
| 290 |
+
"question_type": "multiple_choice",
|
| 291 |
+
"question": "LangSmith์์ ํ๋ก๋์
์ค๋ฅ ์ผ์ด์ค๋ฅผ ์์งํด ์๋ํ๋ ํ์ง ํ
์คํธ๋ฅผ ๋ง๋๋ ๊ธฐ๋ฅ์?",
|
| 292 |
+
"options": [
|
| 293 |
+
"Dataset + Evaluator๋ก ํ๊ฐ ํ์ดํ๋ผ์ธ์ ๊ตฌ์ฑํ๋ค",
|
| 294 |
+
"A/B ํ
์คํธ๋ก ๋ชจ๋ธ์ ๋น๊ตํ๋ค",
|
| 295 |
+
"ํ๋กฌํํธ๋ฅผ ์๋ ์ต์ ํํ๋ค",
|
| 296 |
+
"๋ชจ๋ธ์ ํ์ธํ๋ํ๋ค"
|
| 297 |
+
],
|
| 298 |
+
"answer": "Dataset + Evaluator๋ก ํ๊ฐ ํ์ดํ๋ผ์ธ์ ๊ตฌ์ฑํ๋ค",
|
| 299 |
+
"explanation": "LangSmith์ Dataset์ ํ
์คํธ ์ผ์ด์ค(์
์ถ๋ ฅ ์)๋ฅผ ์ ์ฅํ๊ณ , Evaluator(LLM-as-judge ๋ฑ)๋ก ์๋ ์ฑ์ ํฉ๋๋ค. CI์ ํตํฉํด ํ๋กฌํํธ ๋ณ๊ฒฝ ์ ํ๊ท ํ
์คํธ๋ฅผ ํ ์ ์์ต๋๋ค.",
|
| 300 |
+
"source_id": "official-docs-langchain"
|
| 301 |
+
},
|
| 302 |
+
{
|
| 303 |
+
"id": "docs-q29",
|
| 304 |
+
"lesson_id": "docs-guardrails",
|
| 305 |
+
"question_type": "multiple_choice",
|
| 306 |
+
"question": "Guardrails AI์์ LLM ์ถ๋ ฅ์ด ๊ฒ์ฆ ์คํจ ์ ์๋์ผ๋ก LLM์ ์ฌ์์ฒญํ๋ `on_fail` ๋์์?",
|
| 307 |
+
"options": [
|
| 308 |
+
"reask",
|
| 309 |
+
"exception",
|
| 310 |
+
"noop",
|
| 311 |
+
"fix"
|
| 312 |
+
],
|
| 313 |
+
"answer": "reask",
|
| 314 |
+
"explanation": "`on_fail='reask'`๋ ๊ฒ์ฆ ์คํจ ์ LLM์ ์์ ์์ฒญ์ ์๋์ผ๋ก ๋ค์ ๋ณด๋
๋๋ค. `exception`์ ์์ธ ๋ฐ์, `noop`์ ๊ทธ๋ฅ ํต๊ณผ, `fix`๋ ์๋ ์์ ์ ์๋ํฉ๋๋ค.",
|
| 315 |
+
"source_id": "official-docs-guardrails"
|
| 316 |
+
},
|
| 317 |
+
{
|
| 318 |
+
"id": "docs-q30",
|
| 319 |
+
"lesson_id": "docs-guardrails",
|
| 320 |
+
"question_type": "multiple_choice",
|
| 321 |
+
"question": "Guardrails AI๋ก LLM์ด ํญ์ ์ง์ ํ JSON ์คํค๋ง๋ฅผ ๋ฐํํ๋๋ก ๊ฐ์ ํ๋ ๋ฐฉ๋ฒ์?",
|
| 322 |
+
"options": [
|
| 323 |
+
"Guard.from_pydantic(OutputModel)์ผ๋ก Guard๋ฅผ ์์ฑํ๋ค",
|
| 324 |
+
"LLM ํ๋กฌํํธ์ JSON ์ถ๋ ฅ์ ์์ฒญํ๋ค",
|
| 325 |
+
"json.loads()๋ก ์ถ๋ ฅ์ ํ์ฑํ๋ค",
|
| 326 |
+
"OpenAI์ function_calling ํ๋ผ๋ฏธํฐ๋ฅผ ์ด๋ค"
|
| 327 |
+
],
|
| 328 |
+
"answer": "Guard.from_pydantic(OutputModel)์ผ๋ก Guard๋ฅผ ์์ฑํ๋ค",
|
| 329 |
+
"explanation": "`Guard.from_pydantic(OutputModel)`์ Pydantic ๋ชจ๋ธ์ JSON ์คํค๋ง๋ก ๋ณํํด LLM ์ถ๋ ฅ์ด ์ด ์คํค๋ง๋ฅผ ๋ฐ๋ฅด๋๋ก ๊ฐ์ ํฉ๋๋ค. ํ์์ด ๋ง์ง ์์ผ๋ฉด reask ๋๋ exception์ด ๋ฐ์ํฉ๋๋ค.",
|
| 330 |
+
"source_id": "official-docs-guardrails"
|
| 331 |
+
},
|
| 332 |
+
{
|
| 333 |
+
"id": "docs-q31",
|
| 334 |
+
"lesson_id": "docs-gradio",
|
| 335 |
+
"question_type": "multiple_choice",
|
| 336 |
+
"question": "Gradio์์ LLM ์ฑ๋ด UI๋ฅผ ๊ฐ์ฅ ๊ฐ๋จํ๊ฒ ๋ง๋๋ ๋ฐฉ๋ฒ์?",
|
| 337 |
+
"options": [
|
| 338 |
+
"gr.ChatInterface(fn=chat_function)์ผ๋ก ์ฑํ
ํจ์๋ฅผ ๊ฐ์ผ๋ค",
|
| 339 |
+
"gr.Interface(fn=chat)์ ํ
์คํธ ์
์ถ๋ ฅ์ ์ง์ ํ๋ค",
|
| 340 |
+
"gr.Blocks()์ gr.Textbox๋ฅผ ์๋์ผ๋ก ๋ฐฐ์นํ๋ค",
|
| 341 |
+
"Streamlit์ st.chat_message๋ฅผ ์ํฌํธํด ์ด๋ค"
|
| 342 |
+
],
|
| 343 |
+
"answer": "gr.ChatInterface(fn=chat_function)์ผ๋ก ์ฑํ
ํจ์๋ฅผ ๊ฐ์ผ๋ค",
|
| 344 |
+
"explanation": "`gr.ChatInterface`๋ ์ฑํ
UI์ ์ต์ ํ๋ ์ปดํฌ๋ํธ์
๋๋ค. ํจ์๊ฐ `(message, history) -> str` ์๊ทธ๋์ฒ๋ฅผ ๋ฐ๋ฅด๋ฉด ์๋์ผ๋ก ๋ํ ํ์คํ ๋ฆฌ UI์ Submit ๋ฒํผ์ด ์์ฑ๋ฉ๋๋ค.",
|
| 345 |
+
"source_id": "official-docs-gradio"
|
| 346 |
+
},
|
| 347 |
+
{
|
| 348 |
+
"id": "docs-q32",
|
| 349 |
+
"lesson_id": "docs-gradio",
|
| 350 |
+
"question_type": "multiple_choice",
|
| 351 |
+
"question": "Gradio์์ ๋ณต์กํ ๋ ์ด์์(์ฌ์ด๋๋ฐ, ํญ ๋ฑ)์ ์์ ๋กญ๊ฒ ๊ตฌ์ฑํ๋ ค๋ฉด?",
|
| 352 |
+
"options": [
|
| 353 |
+
"gr.Blocks() ์ปจํ
์คํธ ๋งค๋์ ์์์ ์ปดํฌ๋ํธ๋ฅผ ๋ฐฐ์นํ๋ค",
|
| 354 |
+
"gr.Interface์ layout ํ๋ผ๋ฏธํฐ๋ฅผ ์ง์ ํ๋ค",
|
| 355 |
+
"CSS๋ฅผ ์ง์ ์์ ํ๋ค",
|
| 356 |
+
"Streamlit ์ปดํฌ๋ํธ๋ฅผ Gradio์ ์๋ฒ ๋ํ๋ค"
|
| 357 |
+
],
|
| 358 |
+
"answer": "gr.Blocks() ์ปจํ
์คํธ ๋งค๋์ ์์์ ์ปดํฌ๋ํธ๋ฅผ ๋ฐฐ์นํ๋ค",
|
| 359 |
+
"explanation": "`gr.Blocks()`๋ Gradio์ ์ ์์ค ๋ ์ด์์ API์
๋๋ค. `with gr.Row():`, `with gr.Tab():` ๋ฑ์ ์ค์ฒฉํด ์์ ๋กญ๊ฒ UI๋ฅผ ๊ตฌ์ฑํ๊ณ ์ปดํฌ๋ํธ ๊ฐ ์ด๋ฒคํธ๋ฅผ ์ฐ๊ฒฐํ ์ ์์ต๋๋ค.",
|
| 360 |
+
"source_id": "official-docs-gradio"
|
| 361 |
+
},
|
| 362 |
+
{
|
| 363 |
+
"id": "docs-q33",
|
| 364 |
+
"lesson_id": "docs-airflow",
|
| 365 |
+
"question_type": "multiple_choice",
|
| 366 |
+
"question": "Airflow DAG์์ `task_a >> task_b >> task_c`์ ์๋ฏธ๋?",
|
| 367 |
+
"options": [
|
| 368 |
+
"task_a โ task_b โ task_c ์์๋ก ์์ฐจ ์คํ๋๋ค",
|
| 369 |
+
"์ธ ํ์คํฌ๊ฐ ๋์์ ๋ณ๋ ฌ ์คํ๋๋ค",
|
| 370 |
+
"task_c๊ฐ ์คํจํ๋ฉด task_a๋ก ๋กค๋ฐฑ๋๋ค",
|
| 371 |
+
"task_b๋ task_a์ task_c์ ์ถ๋ ฅ์ ํฉ์น๋ค"
|
| 372 |
+
],
|
| 373 |
+
"answer": "task_a โ task_b โ task_c ์์๋ก ์์ฐจ ์คํ๋๋ค",
|
| 374 |
+
"explanation": "`>>` ์ฐ์ฐ์๋ ์คํ ์์กด์ฑ์ ์ ์ํฉ๋๋ค. `task_a >> task_b`๋ task_a๊ฐ ์ฑ๊ณตํ ๋ค์๋ง task_b๊ฐ ์คํ๋๋ค๋ ์๋ฏธ์
๋๋ค. ๋ณ๋ ฌ ์คํ์ `[task_b, task_c] >> task_d`์ฒ๋ผ ๋ฆฌ์คํธ๋ก ํํํฉ๋๋ค.",
|
| 375 |
+
"source_id": "official-docs-airflow"
|
| 376 |
+
},
|
| 377 |
+
{
|
| 378 |
+
"id": "docs-q34",
|
| 379 |
+
"lesson_id": "docs-airflow",
|
| 380 |
+
"question_type": "multiple_choice",
|
| 381 |
+
"question": "Airflow์์ task ๊ฐ ์๋์ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๋ ๋ฉ์ปค๋์ฆ์?",
|
| 382 |
+
"options": [
|
| 383 |
+
"XCom (Cross-Communication)",
|
| 384 |
+
"์ ์ญ ๋ณ์",
|
| 385 |
+
"ํ์ผ ์์คํ
์ ์์ ํ์ผ",
|
| 386 |
+
"Airflow Variable"
|
| 387 |
+
],
|
| 388 |
+
"answer": "XCom (Cross-Communication)",
|
| 389 |
+
"explanation": "XCom์ `ti.xcom_push(key, value)`๋ก ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๊ณ ๋ค๋ฅธ task์์ `ti.xcom_pull(task_ids, key)`๋ก ๊ฐ์ ธ์ต๋๋ค. ๋์ฉ๋ ๋ฐ์ดํฐ๋ S3/GCS ๊ฒฝ๋ก๋ฅผ XCom์ผ๋ก ์ ๋ฌํ๋ ๋ฐฉ์์ ์๋๋ค.",
|
| 390 |
+
"source_id": "official-docs-airflow"
|
| 391 |
+
},
|
| 392 |
+
{
|
| 393 |
+
"id": "docs-q35",
|
| 394 |
+
"lesson_id": "docs-mlflow",
|
| 395 |
+
"question_type": "multiple_choice",
|
| 396 |
+
"question": "MLflow์์ ์คํ ํ๋ผ๋ฏธํฐ์ ๋ฉํธ๋ฆญ์ ์ฌ๋ฐ๋ฅด๊ฒ ๊ธฐ๋กํ๋ ๋ฐฉ๋ฒ์?",
|
| 397 |
+
"options": [
|
| 398 |
+
"with mlflow.start_run(): ๋ธ๋ก ์์์ mlflow.log_param()๊ณผ mlflow.log_metric()์ ํธ์ถํ๋ค",
|
| 399 |
+
"mlflow.track(params={}, metrics={})๋ฅผ ํ ๋ฒ ํธ์ถํ๋ค",
|
| 400 |
+
"print() ์ถ๋ ฅ์ด ์๋์ผ๋ก MLflow์ ๊ธฐ๋ก๋๋ค",
|
| 401 |
+
"mlflow.autolog()๋ง ํธ์ถํ๋ฉด ๋ชจ๋ ๊ฒ์ด ๊ธฐ๋ก๋๋ค"
|
| 402 |
+
],
|
| 403 |
+
"answer": "with mlflow.start_run(): ๋ธ๋ก ์์์ mlflow.log_param()๊ณผ mlflow.log_metric()์ ํธ์ถํ๋ค",
|
| 404 |
+
"explanation": "`with mlflow.start_run():` ์ปจํ
์คํธ ๋งค๋์ ๊ฐ run์ ์์ฑํ๊ณ , ๊ทธ ์์์ `log_param`(ํ๋ผ๋ฏธํฐ), `log_metric`(๋ฉํธ๋ฆญ), `log_artifact`(ํ์ผ)๋ฅผ ํธ์ถํฉ๋๋ค.",
|
| 405 |
+
"source_id": "official-docs-mlflow"
|
| 406 |
+
},
|
| 407 |
+
{
|
| 408 |
+
"id": "docs-q36",
|
| 409 |
+
"lesson_id": "docs-mlflow",
|
| 410 |
+
"question_type": "multiple_choice",
|
| 411 |
+
"question": "MLflow UI๋ฅผ ๋ก์ปฌ์์ ์คํํ๋ ๋ช
๋ น์ด๋?",
|
| 412 |
+
"options": [
|
| 413 |
+
"mlflow ui",
|
| 414 |
+
"mlflow server --start",
|
| 415 |
+
"python -m mlflow.dashboard",
|
| 416 |
+
"mlflow run --ui"
|
| 417 |
+
],
|
| 418 |
+
"answer": "mlflow ui",
|
| 419 |
+
"explanation": "`mlflow ui` ๋ช
๋ น์ผ๋ก localhost:5000์์ ์คํ ๋น๊ต ๋์๋ณด๋๋ฅผ ์คํํฉ๋๋ค. ์คํ ๋ชฉ๋ก, ํ๋ผ๋ฏธํฐยท๋ฉํธ๋ฆญ ๋น๊ต ์ฐจํธ, ์ํฐํฉํธ ๋ธ๋ผ์ฐ์ ๋ฅผ ์น UI๋ก ๋ณผ ์ ์์ต๋๋ค.",
|
| 420 |
+
"source_id": "official-docs-mlflow"
|
| 421 |
+
},
|
| 422 |
+
{
|
| 423 |
+
"id": "docs-q37",
|
| 424 |
+
"lesson_id": "docs-mcp",
|
| 425 |
+
"question_type": "multiple_choice",
|
| 426 |
+
"question": "MCP(Model Context Protocol)์์ `tool`์ ์ญํ ์?",
|
| 427 |
+
"options": [
|
| 428 |
+
"LLM์ด ์ง์ ํธ์ถํ ์ ์๋ ํจ์๋ก, ์
์ถ๋ ฅ ์คํค๋ง๊ฐ ์๋ ์์ฑ๋๋ค",
|
| 429 |
+
"LLM์ด ์ฝ๋ ์ ์ ๋ฐ์ดํฐ ์์ค",
|
| 430 |
+
"์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ํ๋กฌํํธ ํ
ํ๋ฆฟ",
|
| 431 |
+
"MCP ์๋ฒ์ ์ค์ ํ์ผ"
|
| 432 |
+
],
|
| 433 |
+
"answer": "LLM์ด ์ง์ ํธ์ถํ ์ ์๋ ํจ์๋ก, ์
์ถ๋ ฅ ์คํค๋ง๊ฐ ์๋ ์์ฑ๋๋ค",
|
| 434 |
+
"explanation": "MCP `tool`์ LLM์ด ๋ํ ์ค ์ง์ ํธ์ถํ ์ ์๋ ํจ์์
๋๋ค. FastMCP์ `@mcp.tool()` ๋ฐ์ฝ๋ ์ดํฐ๋ฅผ ๋ถ์ด๋ฉด ํจ์ ์๊ทธ๋์ฒ์์ JSON Schema๊ฐ ์๋ ์์ฑ๋ฉ๋๋ค.",
|
| 435 |
+
"source_id": "official-docs-mcp"
|
| 436 |
+
},
|
| 437 |
+
{
|
| 438 |
+
"id": "docs-q51",
|
| 439 |
+
"lesson_id": "docs-chroma",
|
| 440 |
+
"question_type": "multiple_choice",
|
| 441 |
+
"question": "FAISS์ ๋น๊ตํ์ ๋ Chroma์ ๊ฐ์ฅ ํฐ ์ฅ์ ์?",
|
| 442 |
+
"options": [
|
| 443 |
+
"persist_directory๋ง ์ง์ ํ๋ฉด ์๋ฒ ์ฌ์์ ํ์๋ ๋ฐ์ดํฐ๊ฐ ์๋ ์ ์ง๋๋ค",
|
| 444 |
+
"๊ฒ์ ์๋๊ฐ FAISS๋ณด๋ค 10๋ฐฐ ๋น ๋ฅด๋ค",
|
| 445 |
+
"GPU ์์ด ์๋ฒ ๋ฉ์ ์์ฑํ ์ ์๋ค",
|
| 446 |
+
"OpenAI API ์์ด ๋์ํ๋ค"
|
| 447 |
+
],
|
| 448 |
+
"answer": "persist_directory๋ง ์ง์ ํ๋ฉด ์๋ฒ ์ฌ์์ ํ์๋ ๋ฐ์ดํฐ๊ฐ ์๋ ์ ์ง๋๋ค",
|
| 449 |
+
"explanation": "FAISS๋ ์ธ๋ฉ๋ชจ๋ฆฌ ๊ธฐ๋ฐ์ผ๋ก `save_local()`์ ์๋ ํธ์ถํด์ผ ํฉ๋๋ค. Chroma๋ `persist_directory`๋ฅผ ์ง์ ํ๋ฉด SQLite ๊ธฐ๋ฐ ๋ก์ปฌ DB์ ์๋ ์ ์ฅ๋์ด ์ฌ์์ ํ์๋ ์ ์ง๋ฉ๋๋ค.",
|
| 450 |
+
"source_id": "official-docs-chromadb"
|
| 451 |
+
},
|
| 452 |
+
{
|
| 453 |
+
"id": "docs-q52",
|
| 454 |
+
"lesson_id": "docs-chroma",
|
| 455 |
+
"question_type": "multiple_choice",
|
| 456 |
+
"question": "๊ธฐ์กด Chroma DB์์ ๋ฉํ๋ฐ์ดํฐ ์กฐ๊ฑด์ผ๋ก ๊ฒ์ ๋ฒ์๋ฅผ ์ ํํ๋ ๋ฐฉ๋ฒ์?",
|
| 457 |
+
"options": [
|
| 458 |
+
"db.similarity_search(query, filter={\"source\": \"file.pdf\"})",
|
| 459 |
+
"db.search(query, where={\"source\": \"file.pdf\"})",
|
| 460 |
+
"db.similarity_search(query, metadata=\"file.pdf\")",
|
| 461 |
+
"Chroma๋ ๋ฉํ๋ฐ์ดํฐ ํํฐ๋ง์ ์ง์ํ์ง ์๋๋ค"
|
| 462 |
+
],
|
| 463 |
+
"answer": "db.similarity_search(query, filter={\"source\": \"file.pdf\"})",
|
| 464 |
+
"explanation": "`filter` ํ๋ผ๋ฏธํฐ๋ก ๋ฉํ๋ฐ์ดํฐ ์กฐ๊ฑด์ ์ง์ ํ๋ฉด ํด๋น ์กฐ๊ฑด์ ๋ง์กฑํ๋ ๋ฌธ์ ์ค์์๋ง ์ ์ฌ๋ ๊ฒ์์ ํฉ๋๋ค. FAISS์๋ ์๋ ๊ธฐ๋ฅ์
๋๋ค.",
|
| 465 |
+
"source_id": "official-docs-chromadb"
|
| 466 |
+
},
|
| 467 |
+
{
|
| 468 |
+
"id": "docs-q53",
|
| 469 |
+
"lesson_id": "docs-sentence-transformers",
|
| 470 |
+
"question_type": "multiple_choice",
|
| 471 |
+
"question": "LangChain์์ sentence-transformers ๋ก์ปฌ ์๋ฒ ๋ฉ ๋ชจ๋ธ์ ์ฌ์ฉํ๋ ํด๋์ค๋?",
|
| 472 |
+
"options": [
|
| 473 |
+
"HuggingFaceEmbeddings",
|
| 474 |
+
"SentenceTransformerEmbeddings",
|
| 475 |
+
"LocalEmbeddings",
|
| 476 |
+
"OllamaEmbeddings"
|
| 477 |
+
],
|
| 478 |
+
"answer": "HuggingFaceEmbeddings",
|
| 479 |
+
"explanation": "`from langchain_huggingface import HuggingFaceEmbeddings`๋ก ๊ฐ์ ธ์ `model_name`์ HuggingFace ๋ชจ๋ธ ๊ฒฝ๋ก๋ฅผ ์ง์ ํฉ๋๋ค. `sentence-transformers/all-MiniLM-L6-v2`๊ฐ ๊ฐ์ฅ ๋ง์ด ์ฐ์ด๋ ๊ธฐ๋ณธ ๋ชจ๋ธ์
๋๋ค.",
|
| 480 |
+
"source_id": "official-docs-huggingface"
|
| 481 |
+
},
|
| 482 |
+
{
|
| 483 |
+
"id": "docs-q54",
|
| 484 |
+
"lesson_id": "docs-sentence-transformers",
|
| 485 |
+
"question_type": "multiple_choice",
|
| 486 |
+
"question": "sentence-transformers ์๋ฒ ๋ฉ ๋ชจ๋ธ์ ๊ต์ฒดํ ๋ ๋ฐ๋์ ํด์ผ ํ๋ ์์
์?",
|
| 487 |
+
"options": [
|
| 488 |
+
"๊ธฐ์กด VectorStore ์ ์ฒด๋ฅผ ์ ๋ชจ๋ธ๋ก ์ฌ์ธ๋ฑ์ฑํ๋ค",
|
| 489 |
+
"๋ชจ๋ธ ํ์ผ์ ๋ฎ์ด์ฐ๊ธฐ๋ง ํ๋ฉด ๋๋ค",
|
| 490 |
+
"VectorStore์ dimension ํ๋ผ๋ฏธํฐ๋ฅผ ์์ ํ๋ค",
|
| 491 |
+
"์๋ฒ ๋ฉ ๋ชจ๋ธ์ ์ธ์ ๋ ์์ ๋กญ๊ฒ ๊ต์ฒด ๊ฐ๋ฅํ๋ค"
|
| 492 |
+
],
|
| 493 |
+
"answer": "๊ธฐ์กด VectorStore ์ ์ฒด๋ฅผ ์ ๋ชจ๋ธ๋ก ์ฌ์ธ๋ฑ์ฑํ๋ค",
|
| 494 |
+
"explanation": "์๋ฒ ๋ฉ ๋ชจ๋ธ์ด ๋ค๋ฅด๋ฉด ๋ฒกํฐ ๊ณต๏ฟฝ๏ฟฝ์ด ๋ฌ๋ผ์ง๋๋ค. ๊ธฐ์กด ์ธ๋ฑ์ค์ ๋ฒกํฐ์ ์ ๋ชจ๋ธ๋ก ์์ฑํ ์ฟผ๋ฆฌ ๋ฒกํฐ๊ฐ ํธํ๋์ง ์์ ๊ฒ์ ๊ฒฐ๊ณผ๊ฐ ์ํฐ๋ฆฌ๊ฐ ๋ฉ๋๋ค. ์ ์ฒด ์ฌ์ธ๋ฑ์ฑ์ด ํ์์
๋๋ค.",
|
| 495 |
+
"source_id": "official-docs-huggingface"
|
| 496 |
+
},
|
| 497 |
+
{
|
| 498 |
+
"id": "docs-q55",
|
| 499 |
+
"lesson_id": "docs-ragas",
|
| 500 |
+
"question_type": "multiple_choice",
|
| 501 |
+
"question": "Ragas์ Faithfulness ๋ฉํธ๋ฆญ์ด ์ธก์ ํ๋ ๊ฒ์?",
|
| 502 |
+
"options": [
|
| 503 |
+
"LLM ๋ต๋ณ์ด ๊ฒ์๋ ์ปจํ
์คํธ์ ๊ทผ๊ฑฐํ๋๊ฐ (ํ๊ฐ ํ์ง)",
|
| 504 |
+
"๊ฒ์๋ ๋ฌธ์๊ฐ ์ง๋ฌธ๊ณผ ๊ด๋ จ ์๋๊ฐ",
|
| 505 |
+
"๋ต๋ณ์ด ground_truth์ ์ผ์นํ๋๊ฐ",
|
| 506 |
+
"RAG ํ์ดํ๋ผ์ธ์ ์คํ ์๋"
|
| 507 |
+
],
|
| 508 |
+
"answer": "LLM ๋ต๋ณ์ด ๊ฒ์๋ ์ปจํ
์คํธ์ ๊ทผ๊ฑฐํ๋๊ฐ (ํ๊ฐ ํ์ง)",
|
| 509 |
+
"explanation": "Faithfulness๋ LLM์ด ๊ฒ์๋ ์ปจํ
์คํธ์ ์๋ ๋ด์ฉ์ ์ง์ด๋ด์ง ์๋์ง ์ธก์ ํฉ๋๋ค. 1.0์ ๊ฐ๊น์ธ์๋ก ํ๊ฐ์ด ์์ต๋๋ค. Answer Relevancy๋ ๋ต๋ณ์ด ์ง๋ฌธ๊ณผ ๊ด๋ จ ์๋์ง, Context Precision์ ๊ด๋ จ ๋ฌธ์๊ฐ ์ ๊ฒ์๋๋์ง์
๋๋ค.",
|
| 510 |
+
"source_id": "official-docs-ragas"
|
| 511 |
+
},
|
| 512 |
+
{
|
| 513 |
+
"id": "docs-q56",
|
| 514 |
+
"lesson_id": "docs-ragas",
|
| 515 |
+
"question_type": "multiple_choice",
|
| 516 |
+
"question": "Ragas evaluate() ํจ์์ ํ์๋ก ์ ๋ฌํด์ผ ํ๋ ๋ฐ์ดํฐ ํค๊ฐ ์๋ ๊ฒ์?",
|
| 517 |
+
"options": [
|
| 518 |
+
"ground_truth (faithfulness๋ง ๊ณ์ฐํ ๊ฒฝ์ฐ)",
|
| 519 |
+
"question",
|
| 520 |
+
"answer",
|
| 521 |
+
"contexts"
|
| 522 |
+
],
|
| 523 |
+
"answer": "ground_truth (faithfulness๋ง ๊ณ์ฐํ ๊ฒฝ์ฐ)",
|
| 524 |
+
"explanation": "`question`, `answer`, `contexts`๋ ๊ธฐ๋ณธ ๋ฉํธ๋ฆญ์ ํ์์
๋๋ค. `ground_truth`๋ Answer Correctness ๋ฉํธ๋ฆญ์๋ง ํ์ํ๋ฉฐ, faithfulness์ answer_relevancy๋ง ๊ณ์ฐํ ๊ฒฝ์ฐ ์์ด๋ ๋ฉ๋๋ค.",
|
| 525 |
+
"source_id": "official-docs-ragas"
|
| 526 |
+
},
|
| 527 |
+
{
|
| 528 |
+
"id": "docs-q57",
|
| 529 |
+
"lesson_id": "docs-langgraph",
|
| 530 |
+
"question_type": "multiple_choice",
|
| 531 |
+
"question": "LangGraph์์ ๋
ธ๋์ ์คํ ๊ฒฐ๊ณผ์ ๋ฐ๋ผ ๋ค์ ๋
ธ๋๋ฅผ ๋์ ์ผ๋ก ๊ฒฐ์ ํ๋ ๋ฉ์๋๋?",
|
| 532 |
+
"options": [
|
| 533 |
+
"graph.add_conditional_edges()",
|
| 534 |
+
"graph.add_edge()",
|
| 535 |
+
"graph.set_next_node()",
|
| 536 |
+
"graph.branch()"
|
| 537 |
+
],
|
| 538 |
+
"answer": "graph.add_conditional_edges()",
|
| 539 |
+
"explanation": "`graph.add_conditional_edges('node', router_fn, {'yes': 'next_node', 'no': END})`๋ก ๋
ธ๋ ๋ฐํ๊ฐ์ ๋ฐ๋ผ ๋ค์ ๋
ธ๋๋ฅผ ๋์ ์ผ๋ก ๊ฒฐ์ ํฉ๋๋ค. ๊ณ ์ ๋ ๋ค์ ๋
ธ๋๋ `add_edge()`๋ฅผ ์๋๋ค.",
|
| 540 |
+
"source_id": "official-docs-langgraph"
|
| 541 |
+
},
|
| 542 |
+
{
|
| 543 |
+
"id": "docs-q58",
|
| 544 |
+
"lesson_id": "docs-langgraph",
|
| 545 |
+
"question_type": "multiple_choice",
|
| 546 |
+
"question": "LangGraph StateGraph์์ State TypedDict๋ฅผ ์ ์ํ๋ ์ด์ ๋?",
|
| 547 |
+
"options": [
|
| 548 |
+
"๋
ธ๋ ๊ฐ ๊ณต์ ๋๋ ๋ฐ์ดํฐ ๊ตฌ์กฐ๋ฅผ ํ์
์์ ํ๊ฒ ์ ์ํ๊ธฐ ์ํด",
|
| 549 |
+
"๊ทธ๋ํ ์คํ ์๋๋ฅผ ๋์ด๊ธฐ ์ํด",
|
| 550 |
+
"LangChain ์ฒด์ธ๊ณผ ํธํ์ฑ์ ์ํด",
|
| 551 |
+
"State๋ ์ ํ ์ฌํญ์ผ๋ก ์ ์ํ์ง ์์๋ ๋๋ค"
|
| 552 |
+
],
|
| 553 |
+
"answer": "๋
ธ๋ ๊ฐ ๊ณต์ ๋๋ ๋ฐ์ดํฐ ๊ตฌ์กฐ๋ฅผ ํ์
์์ ํ๊ฒ ์ ์ํ๊ธฐ ์ํด",
|
| 554 |
+
"explanation": "State TypedDict๋ ๋ชจ๋ ๋
ธ๋๊ฐ ์ฝ๊ณ ์ฐ๋ ๊ณต์ ์ํ๋ฅผ ์ ์ํฉ๋๋ค. ๊ฐ ๋
ธ๋ ํจ์๋ `state: State`๋ฅผ ๋ฐ์ ์ผ๋ถ ํค๋ฅผ ์
๋ฐ์ดํธํ ๋์
๋๋ฆฌ๋ฅผ ๋ฐํํฉ๋๋ค.",
|
| 555 |
+
"source_id": "official-docs-langgraph"
|
| 556 |
+
},
|
| 557 |
+
{
|
| 558 |
+
"id": "docs-q59",
|
| 559 |
+
"lesson_id": "docs-litellm",
|
| 560 |
+
"question_type": "multiple_choice",
|
| 561 |
+
"question": "LiteLLM์์ Ollama ๋ก์ปฌ ๋ชจ๋ธ์ ํธ์ถํ๋ model ํ๋ผ๋ฏธํฐ ํ์์?",
|
| 562 |
+
"options": [
|
| 563 |
+
"\"ollama/llama3.2\"",
|
| 564 |
+
"\"local/llama3.2\"",
|
| 565 |
+
"\"llama3.2\"",
|
| 566 |
+
"\"ollama:llama3.2\""
|
| 567 |
+
],
|
| 568 |
+
"answer": "\"ollama/llama3.2\"",
|
| 569 |
+
"explanation": "LiteLLM์ ๋ชจ๋ธ๋ช
ํ์์ `\"ํ๋ก๋ฐ์ด๋/๋ชจ๋ธ๋ช
\"`์
๋๋ค. `\"ollama/llama3.2\"`, `\"anthropic/claude-3-5-sonnet-20241022\"`, `\"gpt-4o-mini\"`(OpenAI๋ ์์ธ๋ก ์ ๋์ฌ ์์) ํ์์ ์๋๋ค.",
|
| 570 |
+
"source_id": "official-docs-litellm"
|
| 571 |
+
},
|
| 572 |
+
{
|
| 573 |
+
"id": "docs-q60",
|
| 574 |
+
"lesson_id": "docs-litellm",
|
| 575 |
+
"question_type": "multiple_choice",
|
| 576 |
+
"question": "LiteLLM์ LangChain ์ฒด์ธ์์ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์?",
|
| 577 |
+
"options": [
|
| 578 |
+
"from langchain_community.chat_models import ChatLiteLLM๋ก ๊ฐ์ ธ์ LLM์ผ๋ก ์ฌ์ฉํ๋ค",
|
| 579 |
+
"litellm.completion()์ LangChain ์ฒด์ธ์ ์ง์ ๋ฃ๋๋ค",
|
| 580 |
+
"LiteLLM์ LangChain๊ณผ ํตํฉ๋์ง ์๋๋ค",
|
| 581 |
+
"LangChain์ ChatOpenAI์ litellm=True ํ๋ผ๋ฏธํฐ๋ฅผ ์ถ๊ฐํ๋ค"
|
| 582 |
+
],
|
| 583 |
+
"answer": "from langchain_community.chat_models import ChatLiteLLM๋ก ๊ฐ์ ธ์ LLM์ผ๋ก ์ฌ์ฉํ๋ค",
|
| 584 |
+
"explanation": "`ChatLiteLLM`์ LangChain์ ChatModel ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ๋ฏ๋ก LCEL ํ์ดํ๋ผ์ธ์ ๋ฐ๋ก ์ฐ๊ฒฐ๋ฉ๋๋ค. `chain = prompt | ChatLiteLLM(model='ollama/llama3.2') | parser` ํ์์ผ๋ก ์๋๋ค.",
|
| 585 |
+
"source_id": "official-docs-litellm"
|
| 586 |
+
},
|
| 587 |
+
{
|
| 588 |
+
"id": "docs-q61",
|
| 589 |
+
"lesson_id": "docs-chainlit",
|
| 590 |
+
"question_type": "multiple_choice",
|
| 591 |
+
"question": "Chainlit์์ ์ฌ์ฉ์ ๋ฉ๏ฟฝ๏ฟฝ์ง๋ฅผ ๋ฐ์ ์ฒ๋ฆฌํ๋ ๋ฐ์ฝ๋ ์ดํฐ๋?",
|
| 592 |
+
"options": [
|
| 593 |
+
"@cl.on_message",
|
| 594 |
+
"@cl.on_input",
|
| 595 |
+
"@cl.message_handler",
|
| 596 |
+
"@cl.chat"
|
| 597 |
+
],
|
| 598 |
+
"answer": "@cl.on_message",
|
| 599 |
+
"explanation": "`@cl.on_message`๋ ์ฌ์ฉ์๊ฐ ๋ฉ์์ง๋ฅผ ๋ณด๋ผ ๋๋ง๋ค ์๋์ผ๋ก ํธ์ถ๋ฉ๋๋ค. ํจ์ ํ๋ผ๋ฏธํฐ๋ก `message: cl.Message`๋ฅผ ๋ฐ์ `message.content`๋ก ํ
์คํธ์ ์ ๊ทผํฉ๋๋ค.",
|
| 600 |
+
"source_id": "official-docs-chainlit"
|
| 601 |
+
},
|
| 602 |
+
{
|
| 603 |
+
"id": "docs-q62",
|
| 604 |
+
"lesson_id": "docs-chainlit",
|
| 605 |
+
"question_type": "multiple_choice",
|
| 606 |
+
"question": "Chainlit์์ LangChain ์ฒด์ธ์ ํธ์ถํ ๋ ๋๊ธฐ invoke() ๋์ ์จ์ผ ํ๋ ์ด์ ์ ๋์์?",
|
| 607 |
+
"options": [
|
| 608 |
+
"invoke()๋ ์ด๋ฒคํธ ๋ฃจํ๋ฅผ ๋ธ๋กํนํ๋ฏ๋ก ainvoke() ๋๋ astream()์ ์จ์ผ ํ๋ค",
|
| 609 |
+
"invoke()๊ฐ ๋ ๋น ๋ฅด๋ฏ๋ก ํญ์ invoke()๋ฅผ ์ด๋ค",
|
| 610 |
+
"Chainlit์ LangChain๊ณผ ํธํ๋์ง ์๋๋ค",
|
| 611 |
+
"invoke()์ ainvoke()์ ์ฐจ์ด๋ ์๋ค"
|
| 612 |
+
],
|
| 613 |
+
"answer": "invoke()๋ ์ด๋ฒคํธ ๋ฃจํ๋ฅผ ๋ธ๋กํนํ๋ฏ๋ก ainvoke() ๋๋ astream()์ ์จ์ผ ํ๋ค",
|
| 614 |
+
"explanation": "Chainlit์ asyncio ๊ธฐ๋ฐ์
๋๋ค. `invoke()`(๋๊ธฐ)๋ฅผ `async def` ํจ์ ์์์ ํธ์ถํ๋ฉด ์ด๋ฒคํธ ๋ฃจํ๊ฐ ๋ธ๋กํน๋์ด ๋ค๋ฅธ ์ฌ์ฉ์ ์์ฒญ์ ์ฒ๋ฆฌ ๋ชป ํฉ๋๋ค. `await chain.ainvoke()`๋ฅผ ์จ์ผ ํฉ๋๋ค.",
|
| 615 |
+
"source_id": "official-docs-chainlit"
|
| 616 |
+
},
|
| 617 |
+
{
|
| 618 |
+
"id": "docs-q63",
|
| 619 |
+
"lesson_id": "docs-redis",
|
| 620 |
+
"question_type": "multiple_choice",
|
| 621 |
+
"question": "์๋ฒ ์ฌ์์ ํ์๋ ๋ํ ํ์คํ ๋ฆฌ๊ฐ ์ ์ง๋๋๋ก ChatMessageHistory๋ฅผ ๊ต์ฒดํ๋ ํด๋์ค๋?",
|
| 622 |
+
"options": [
|
| 623 |
+
"RedisChatMessageHistory",
|
| 624 |
+
"PersistentChatMessageHistory",
|
| 625 |
+
"SQLChatMessageHistory",
|
| 626 |
+
"FileChatMessageHistory"
|
| 627 |
+
],
|
| 628 |
+
"answer": "RedisChatMessageHistory",
|
| 629 |
+
"explanation": "`RedisChatMessageHistory(session_id, url='redis://localhost:6379')`๋ ๋ํ ํ์คํ ๋ฆฌ๋ฅผ Redis์ ์ ์ฅํฉ๋๋ค. ๊ธฐ์กด `ChatMessageHistory`(์ธ๋ฉ๋ชจ๋ฆฌ)์ ์ธํฐํ์ด์ค๊ฐ ๋์ผํด `get_session_history` ํจ์๋ง ๋ฐ๊พธ๋ฉด ๋ฉ๋๋ค.",
|
| 630 |
+
"source_id": "official-docs-redis"
|
| 631 |
+
},
|
| 632 |
+
{
|
| 633 |
+
"id": "docs-q64",
|
| 634 |
+
"lesson_id": "docs-redis",
|
| 635 |
+
"question_type": "multiple_choice",
|
| 636 |
+
"question": "Redis์์ ๋ํ ํ์คํ ๋ฆฌ๊ฐ ๋ฌดํํ ์์ด์ง ์๋๋ก ์๋ ๋ง๋ฃ๋ฅผ ์ค์ ํ๋ ํ๋ผ๋ฏธํฐ๋?",
|
| 637 |
+
"options": [
|
| 638 |
+
"ttl (์ด ๋จ์)",
|
| 639 |
+
"expire (๋ถ ๋จ์)",
|
| 640 |
+
"max_messages",
|
| 641 |
+
"timeout"
|
| 642 |
+
],
|
| 643 |
+
"answer": "ttl (์ด ๋จ์)",
|
| 644 |
+
"explanation": "`RedisChatMessageHistory(session_id, url, ttl=3600)`์ผ๋ก 1์๊ฐ(3600์ด) ํ ์๋ ๋ง๋ฃ๋ฉ๋๋ค. TTL์ด ์์ผ๋ฉด ํ์คํ ๋ฆฌ๊ฐ ๋ฌดํํ ์์ฌ ํ ํฐ ์ด๊ณผ์ ๋ฉ๋ชจ๋ฆฌ ๋์๊ฐ ๋ฐ์ํฉ๋๋ค.",
|
| 645 |
+
"source_id": "official-docs-redis"
|
| 646 |
+
},
|
| 647 |
+
{
|
| 648 |
+
"id": "docs-q65",
|
| 649 |
+
"lesson_id": "docs-unstructured",
|
| 650 |
+
"question_type": "multiple_choice",
|
| 651 |
+
"question": "Unstructured๋ก PDF ํ์ผ์ ๋ก๋ํ๋ ค๋ฉด ์ถ๊ฐ๋ก ์ค์นํด์ผ ํ๋ ํจํค์ง๋?",
|
| 652 |
+
"options": [
|
| 653 |
+
"pip install unstructured[pdf]",
|
| 654 |
+
"pip install unstructured-pdf",
|
| 655 |
+
"pip install pdfminer",
|
| 656 |
+
"pip install unstructured๋ง์ผ๋ก ์ถฉ๋ถํ๋ค"
|
| 657 |
+
],
|
| 658 |
+
"answer": "pip install unstructured[pdf]",
|
| 659 |
+
"explanation": "`pip install unstructured`๋ ๊ธฐ๋ณธ ํจํค์ง๋ง ์ค์นํฉ๋๋ค. PDF ์ฒ๋ฆฌ๋ `unstructured[pdf]`, ์ด๋ฏธ์ง OCR์ `unstructured[local-inference]`์ฒ๋ผ ๋ณ๋ extra๋ฅผ ์ค์นํด์ผ ํฉ๋๋ค.",
|
| 660 |
+
"source_id": "official-docs-unstructured"
|
| 661 |
+
},
|
| 662 |
+
{
|
| 663 |
+
"id": "docs-q66",
|
| 664 |
+
"lesson_id": "docs-unstructured",
|
| 665 |
+
"question_type": "multiple_choice",
|
| 666 |
+
"question": "Unstructured๋ฅผ `mode='elements'`๋ก ๋ก๋ํ ๋ ์ป์ ์ ์๋ ์ถ๊ฐ ์ ๋ณด๋?",
|
| 667 |
+
"options": [
|
| 668 |
+
"Title, NarrativeText, Table ๋ฑ ์์ ํ์
์ด metadata์ ์ ์ฅ๋๋ค",
|
| 669 |
+
"OCR ์ ํ๋๊ฐ ๋์์ง๋ค",
|
| 670 |
+
"์ด๋ฏธ์ง ํ์ผ๋ ํ
์คํธ๋ก ๋ณํ๋๋ค",
|
| 671 |
+
"์ฒญํฌ ๋ถํ ์ด ์๋์ผ๋ก ๋๋ค"
|
| 672 |
+
],
|
| 673 |
+
"answer": "Title, NarrativeText, Table ๋ฑ ์์ ํ์
์ด metadata์ ์ ์ฅ๋๋ค",
|
| 674 |
+
"explanation": "`mode='elements'`๋ก ๋ก๋ํ๋ฉด ๊ฐ Document์ `metadata['category']`๋ก ์์ ํ์
์ด ์ ์ฅ๋ฉ๋๋ค. ํค๋๋ฅผ ์ฒญํฌ ๋ฉํ๋ฐ์ดํฐ๋ก ํ์ฉํ๊ฑฐ๋ ํ
์ด๋ธ๋ง ๋ณ๋ ์ถ์ถํ ๋ ์๋๋ค.",
|
| 675 |
+
"source_id": "official-docs-unstructured"
|
| 676 |
+
},
|
| 677 |
+
{
|
| 678 |
+
"id": "docs-q45",
|
| 679 |
+
"lesson_id": "docs-document-loaders",
|
| 680 |
+
"question_type": "multiple_choice",
|
| 681 |
+
"question": "LangChain `DirectoryLoader`๋ก ํ์ ํด๋๊น์ง ๋ชจ๋ `.md` ํ์ผ์ ๋ก๋ํ๋ glob ํจํด์?",
|
| 682 |
+
"options": [
|
| 683 |
+
"**/*.md",
|
| 684 |
+
"*.md",
|
| 685 |
+
"./**md",
|
| 686 |
+
"**md"
|
| 687 |
+
],
|
| 688 |
+
"answer": "**/*.md",
|
| 689 |
+
"explanation": "`**/*.md`๋ ํ์ฌ ๋๋ ํ ๋ฆฌ์ ๋ชจ๋ ํ์ ๋๋ ํ ๋ฆฌ์์ `.md` ํ์ผ์ ์ฌ๊ท ๊ฒ์ํฉ๋๋ค. `*.md`๋ ํ์ฌ ํด๋๋ง ๊ฒ์ํฉ๋๋ค.",
|
| 690 |
+
"source_id": "official-docs-langchain"
|
| 691 |
+
},
|
| 692 |
+
{
|
| 693 |
+
"id": "docs-q46",
|
| 694 |
+
"lesson_id": "docs-document-loaders",
|
| 695 |
+
"question_type": "multiple_choice",
|
| 696 |
+
"question": "LangChain Document ๊ฐ์ฒด์์ ํ์ผ ๊ฒฝ๋ก(์ถ์ฒ)๋ฅผ ๊ฐ์ ธ์ค๋ ์ฝ๋๋?",
|
| 697 |
+
"options": [
|
| 698 |
+
"doc.metadata['source']",
|
| 699 |
+
"doc.source",
|
| 700 |
+
"doc.file_path",
|
| 701 |
+
"doc.metadata.path"
|
| 702 |
+
],
|
| 703 |
+
"answer": "doc.metadata['source']",
|
| 704 |
+
"explanation": "Document Loader๋ ๋ก๋๋ ๋ฌธ์์ `metadata` ๋์
๋๋ฆฌ์ `source` ํค๋ก ํ์ผ ๊ฒฝ๋ก๋ฅผ ์ ์ฅํฉ๋๋ค. RAG ๋ต๋ณ์ ์ถ์ฒ๋ฅผ ํ์ํ ๋ ์ด ๊ฐ์ ์๋๋ค.",
|
| 705 |
+
"source_id": "official-docs-langchain"
|
| 706 |
+
},
|
| 707 |
+
{
|
| 708 |
+
"id": "docs-q47",
|
| 709 |
+
"lesson_id": "docs-summarization",
|
| 710 |
+
"question_type": "multiple_choice",
|
| 711 |
+
"question": "LangChain์์ ์ฌ๋ฌ ๋ด์ค ๊ธฐ์ฌ์ฒ๋ผ ์ปจํ
์คํธ ์ฐฝ๋ณด๋ค ๊ธด ๋ฌธ์๋ฅผ ์์ฝํ ๋ ์ ํฉํ chain_type์?",
|
| 712 |
+
"options": [
|
| 713 |
+
"map_reduce",
|
| 714 |
+
"stuff",
|
| 715 |
+
"direct",
|
| 716 |
+
"compress"
|
| 717 |
+
],
|
| 718 |
+
"answer": "map_reduce",
|
| 719 |
+
"explanation": "`map_reduce`๋ ๊ฐ ์ฒญํฌ๋ฅผ ๊ฐ๋ณ ์์ฝ(map)ํ ํ ํฉ์ณ์ ์ต์ข
์์ฝ(reduce)์ ๋ง๋ญ๋๋ค. `stuff`๋ ์ ์ฒด๋ฅผ ํ ํ๋กฌํํธ์ ๋ฃ์ผ๋ฏ๋ก ๊ธด ๋ฌธ์์์ ํ ํฐ ์ด๊ณผ ์ค๋ฅ๊ฐ ๋ฉ๋๋ค.",
|
| 720 |
+
"source_id": "official-docs-langchain"
|
| 721 |
+
},
|
| 722 |
+
{
|
| 723 |
+
"id": "docs-q48",
|
| 724 |
+
"lesson_id": "docs-summarization",
|
| 725 |
+
"question_type": "multiple_choice",
|
| 726 |
+
"question": "`load_summarize_chain` ์คํ ๊ฒฐ๊ณผ์์ ์ต์ข
์์ฝ ํ
์คํธ๋ฅผ ๊ฐ์ ธ์ค๋ ํค๋?",
|
| 727 |
+
"options": [
|
| 728 |
+
"result['output_text']",
|
| 729 |
+
"result['summary']",
|
| 730 |
+
"result['text']",
|
| 731 |
+
"result['answer']"
|
| 732 |
+
],
|
| 733 |
+
"answer": "result['output_text']",
|
| 734 |
+
"explanation": "`chain.invoke(docs)`์ ๋ฐํ๊ฐ ๋์
๋๋ฆฌ์์ ์์ฝ ๊ฒฐ๊ณผ๋ `output_text` ํค์ ์ ์ฅ๋ฉ๋๋ค.",
|
| 735 |
+
"source_id": "official-docs-langchain"
|
| 736 |
+
},
|
| 737 |
+
{
|
| 738 |
+
"id": "docs-q49",
|
| 739 |
+
"lesson_id": "docs-sql-chain",
|
| 740 |
+
"question_type": "multiple_choice",
|
| 741 |
+
"question": "LangChain์์ SQLite DB๋ฅผ `SQLDatabase`๋ก ์ฐ๊ฒฐํ๋ ์ฝ๋๋?",
|
| 742 |
+
"options": [
|
| 743 |
+
"SQLDatabase.from_uri('sqlite:///./mydb.db')",
|
| 744 |
+
"SQLDatabase.connect('./mydb.db')",
|
| 745 |
+
"sqlite3.connect('./mydb.db')",
|
| 746 |
+
"SQLDatabase('./mydb.db')"
|
| 747 |
+
],
|
| 748 |
+
"answer": "SQLDatabase.from_uri('sqlite:///./mydb.db')",
|
| 749 |
+
"explanation": "`SQLDatabase.from_uri()`๋ SQLAlchemy ์ฐ๊ฒฐ ๋ฌธ์์ด์ ๋ฐ์ต๋๋ค. SQLite๋ `sqlite:///๊ฒฝ๋ก`, PostgreSQL์ `postgresql://user:pass@host/db` ํ์์
๋๋ค.",
|
| 750 |
+
"source_id": "official-docs-langchain"
|
| 751 |
+
},
|
| 752 |
+
{
|
| 753 |
+
"id": "docs-q50",
|
| 754 |
+
"lesson_id": "docs-sql-chain",
|
| 755 |
+
"question_type": "multiple_choice",
|
| 756 |
+
"question": "LangChain Text-to-SQL์์ `SQLDatabase`๊ฐ LLM์ ์๋์ผ๋ก ์ ๊ณตํ๋ ์ ๋ณด๋?",
|
| 757 |
+
"options": [
|
| 758 |
+
"DB์ ํ
์ด๋ธ๋ช
๊ณผ ์ปฌ๋ผ ์คํค๋ง",
|
| 759 |
+
"DB์ ์ ์ฅ๋ ์ค์ ๋ฐ์ดํฐ ์ํ",
|
| 760 |
+
"SQL ์คํ ๊ฒฐ๊ณผ ํ์คํ ๋ฆฌ",
|
| 761 |
+
"DB ์ ์ ๋น๋ฐ๋ฒํธ"
|
| 762 |
+
],
|
| 763 |
+
"answer": "DB์ ํ
์ด๋ธ๋ช
๊ณผ ์ปฌ๋ผ ์คํค๋ง",
|
| 764 |
+
"explanation": "`SQLDatabase`๋ ์ฐ๊ฒฐ๋ DB์ ํ
์ด๋ธ๋ช
๊ณผ ๊ฐ ์ปฌ๋ผ์ ์ด๋ฆยทํ์
์ ์๋์ผ๋ก ํ๋กฌํํธ์ ์ฃผ์
ํฉ๋๋ค. ๋๋ถ์ LLM์ด ์ค์ ์กด์ฌํ๋ ํ
์ด๋ธ/์ปฌ๋ผ๋ง ์ฐธ์กฐํ๋ SQL์ ์์ฑํ ์ ์์ต๋๋ค.",
|
| 765 |
+
"source_id": "official-docs-langchain"
|
| 766 |
+
},
|
| 767 |
+
{
|
| 768 |
+
"id": "docs-q39",
|
| 769 |
+
"lesson_id": "docs-dotenv",
|
| 770 |
+
"question_type": "multiple_choice",
|
| 771 |
+
"question": "python-dotenv์์ `.env` ํ์ผ์ ๋ก๋ํ๋ ์ฌ๋ฐ๋ฅธ ๋ฐฉ๋ฒ์?",
|
| 772 |
+
"options": [
|
| 773 |
+
"from dotenv import load_dotenv; load_dotenv()",
|
| 774 |
+
"import dotenv; dotenv.read('.env')",
|
| 775 |
+
"os.environ.load('.env')",
|
| 776 |
+
".env ํ์ผ์ ์๋์ผ๋ก ๋ก๋๋๋ค"
|
| 777 |
+
],
|
| 778 |
+
"answer": "from dotenv import load_dotenv; load_dotenv()",
|
| 779 |
+
"explanation": "`load_dotenv()`๋ฅผ ๋ช
์์ ์ผ๋ก ํธ์ถํด์ผ `.env` ํ์ผ์ ๋ณ์๊ฐ `os.environ`์ ์ฃผ์
๋ฉ๋๋ค. ํ์ผ ์๋จ์์ ๊ฐ์ฅ ๋จผ์ ํธ์ถํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค.",
|
| 780 |
+
"source_id": "official-docs-python"
|
| 781 |
+
},
|
| 782 |
+
{
|
| 783 |
+
"id": "docs-q40",
|
| 784 |
+
"lesson_id": "docs-dotenv",
|
| 785 |
+
"question_type": "multiple_choice",
|
| 786 |
+
"question": ".env ํ์ผ์ ์ฌ์ฉํ ๋ ๋ณด์์ ์ํด ๋ฐ๋์ ํด์ผ ํ๋ ๊ฒ์?",
|
| 787 |
+
"options": [
|
| 788 |
+
".env๋ฅผ .gitignore์ ์ถ๊ฐํ๊ณ .env.example์ ์ปค๋ฐํ๋ค",
|
| 789 |
+
".env๋ฅผ ์ํธํํด์ ์ ์ฅ์์ ์ปค๋ฐํ๋ค",
|
| 790 |
+
".env ํ์ผ๋ช
์ ๋ค๋ฅด๊ฒ ์ง์ด ์จ๊ธด๋ค",
|
| 791 |
+
"API ํค๋ฅผ ์งง๊ฒ ์ค์ฌ์ ์ ์ฅํ๋ค"
|
| 792 |
+
],
|
| 793 |
+
"answer": ".env๋ฅผ .gitignore์ ์ถ๊ฐํ๊ณ .env.example์ ์ปค๋ฐํ๋ค",
|
| 794 |
+
"explanation": "`.env`๋ ์ ๋ Git์ ์ปค๋ฐํ์ง ์์ต๋๋ค. `.env.example`์๋ ํค ์ด๋ฆ๋ง(๊ฐ ์์ด) ์ ์ด ์ด๋ค ํ๊ฒฝ๋ณ์๊ฐ ํ์ํ์ง ๋ฌธ์ํํ๋ ์ฉ๋๋ก ์ปค๋ฐํฉ๋๋ค.",
|
| 795 |
+
"source_id": "official-docs-python"
|
| 796 |
+
},
|
| 797 |
+
{
|
| 798 |
+
"id": "docs-q41",
|
| 799 |
+
"lesson_id": "docs-prompt-template",
|
| 800 |
+
"question_type": "multiple_choice",
|
| 801 |
+
"question": "LangChain์์ ์์คํ
์ญํ ๊ณผ ์ฌ์ฉ์ ๋ฉ์์ง๋ฅผ ๊ตฌ๋ถํด ํ๋กฌํํธ๋ฅผ ๋ง๋๋ ํด๋์ค๋?",
|
| 802 |
+
"options": [
|
| 803 |
+
"ChatPromptTemplate",
|
| 804 |
+
"PromptTemplate",
|
| 805 |
+
"SystemPrompt",
|
| 806 |
+
"MessageTemplate"
|
| 807 |
+
],
|
| 808 |
+
"answer": "ChatPromptTemplate",
|
| 809 |
+
"explanation": "`ChatPromptTemplate.from_messages([(\"system\", \"...\"), (\"human\", \"{question}\")])` ํ์์ผ๋ก ์ญํ ๋ณ ๋ฉ์์ง๋ฅผ ๊ตฌ์กฐํํฉ๋๋ค. `PromptTemplate`์ ์ญํ ๊ตฌ๋ถ ์๋ ๋จ์ ๋ฌธ์์ด ํฌ๋งท์ฉ์
๋๋ค.",
|
| 810 |
+
"source_id": "official-docs-langchain"
|
| 811 |
+
},
|
| 812 |
+
{
|
| 813 |
+
"id": "docs-q42",
|
| 814 |
+
"lesson_id": "docs-prompt-template",
|
| 815 |
+
"question_type": "multiple_choice",
|
| 816 |
+
"question": "ChatPromptTemplate์์ ๋ํ ํ์คํ ๋ฆฌ ๋ฉ์์ง ๋ฐฐ์ด์ ์ฃผ์
ํ๋ ๋ฐฉ๋ฒ์?",
|
| 817 |
+
"options": [
|
| 818 |
+
"(\"placeholder\", \"{chat_history}\") ๋๋ MessagesPlaceholder(variable_name=\"chat_history\")๋ฅผ messages์ ์ถ๊ฐํ๋ค",
|
| 819 |
+
"chat_history ๋ฌธ์์ด์ system ๋ฉ์์ง์ ์ง์ ํฌํจํ๋ค",
|
| 820 |
+
"ํ์คํ ๋ฆฌ๋ LLM์ด ์๋์ผ๋ก ๊ด๋ฆฌํ๋ฏ๋ก ๋ณ๋ ์ฒ๋ฆฌ๊ฐ ๋ถํ์ํ๋ค",
|
| 821 |
+
"HistoryTemplate ํด๋์ค๋ฅผ ๋ณ๋๋ก ์ฌ์ฉํ๋ค"
|
| 822 |
+
],
|
| 823 |
+
"answer": "(\"placeholder\", \"{chat_history}\") ๋๋ MessagesPlaceholder(variable_name=\"chat_history\")๋ฅผ messages์ ์ถ๊ฐํ๋ค",
|
| 824 |
+
"explanation": "`MessagesPlaceholder`๋ ๋ฉ์์ง ๋ฆฌ์คํธ ์ ์ฒด๋ฅผ ๊ทธ ์๋ฆฌ์ ํผ์ณ์ค๋๋ค. RunnableWithMessageHistory์ `history_messages_key`์ placeholder์ ๋ณ์๋ช
์ด ์ผ์นํด์ผ ํฉ๋๋ค.",
|
| 825 |
+
"source_id": "official-docs-langchain"
|
| 826 |
+
},
|
| 827 |
+
{
|
| 828 |
+
"id": "docs-q43",
|
| 829 |
+
"lesson_id": "docs-conversation-memory",
|
| 830 |
+
"question_type": "multiple_choice",
|
| 831 |
+
"question": "LangChain์์ ๋ฉํฐํด ๋ํ ํ์คํ ๋ฆฌ๋ฅผ ์ฒด์ธ์ ์๋์ผ๋ก ์ฃผ์
ํ๋ ํด๋์ค๋?",
|
| 832 |
+
"options": [
|
| 833 |
+
"RunnableWithMessageHistory",
|
| 834 |
+
"ConversationChain",
|
| 835 |
+
"ChatMemoryBuffer",
|
| 836 |
+
"HistoryRunnable"
|
| 837 |
+
],
|
| 838 |
+
"answer": "RunnableWithMessageHistory",
|
| 839 |
+
"explanation": "`RunnableWithMessageHistory`๋ ๊ธฐ์กด ์ฒด์ธ์ ๊ฐ์ธ `session_id`๋ณ๋ก ํ์คํ ๋ฆฌ๋ฅผ ๊ด๋ฆฌํฉ๋๋ค. `get_session_history` ํจ์๋ก ์ ์ฅ์๋ฅผ ์ง์ ํ๋ฉด ์๋์ผ๋ก ์ด์ ๋ํ๊ฐ ์ฃผ์
๋ฉ๋๋ค.",
|
| 840 |
+
"source_id": "official-docs-langchain"
|
| 841 |
+
},
|
| 842 |
+
{
|
| 843 |
+
"id": "docs-q44",
|
| 844 |
+
"lesson_id": "docs-conversation-memory",
|
| 845 |
+
"question_type": "multiple_choice",
|
| 846 |
+
"question": "RunnableWithMessageHistory์์ ๋ชจ๋ ์ฌ์ฉ์๊ฐ ๋์ผํ ๋ํ ํ์คํ ๋ฆฌ๋ฅผ ๊ณต์ ํ๋ ์์ธ์?",
|
| 847 |
+
"options": [
|
| 848 |
+
"invoke ์ config์ ๋์ผํ session_id๋ฅผ ์ฌ์ฉํ๋ค",
|
| 849 |
+
"ChatMessageHistory๋ฅผ ํด๋์ค ๋ ๋ฒจ์์ ํ๋๋ง ์์ฑํ๋ค",
|
| 850 |
+
"get_session_history ํจ์๋ฅผ ์ ์ํ์ง ์์๋ค",
|
| 851 |
+
"RunnableWithMessageHistory ๋์ ์ฒด์ธ์ ์ง์ ์ฌ์ฉํ๋ค"
|
| 852 |
+
],
|
| 853 |
+
"answer": "invoke ์ config์ ๋์ผํ session_id๋ฅผ ์ฌ์ฉํ๋ค",
|
| 854 |
+
"explanation": "`config={\"configurable\": {\"session_id\": \"fixed-id\"}}`์ฒ๋ผ ๊ณ ์ ID๋ฅผ ์ฐ๋ฉด ๋ชจ๋ ์ฌ์ฉ์๊ฐ ๊ฐ์ ํ์คํ ๋ฆฌ๋ฅผ ์๋๋ค. ์ฌ์ฉ์๋ณ๋ก ๊ณ ์ ํ session_id(UUID ๋ฑ)๋ฅผ ์์ฑํด์ผ ํฉ๋๋ค.",
|
| 855 |
+
"source_id": "official-docs-langchain"
|
| 856 |
+
},
|
| 857 |
+
{
|
| 858 |
+
"id": "docs-q38",
|
| 859 |
+
"lesson_id": "docs-mcp",
|
| 860 |
+
"question_type": "multiple_choice",
|
| 861 |
+
"question": "Claude Desktop์ ๋ก์ปฌ MCP ์๋ฒ๋ฅผ ์ฐ๊ฒฐํ๋ ค๋ฉด ์ด๋์ ๋ฑ๋กํด์ผ ํ๋๊ฐ?",
|
| 862 |
+
"options": [
|
| 863 |
+
"~/Library/Application Support/Claude/claude_desktop_config.json",
|
| 864 |
+
"~/.claude/mcp_servers.json",
|
| 865 |
+
"CLAUDE.md ํ์ผ",
|
| 866 |
+
"ํ๊ฒฝ๋ณ์ MCP_SERVER_PATH"
|
| 867 |
+
],
|
| 868 |
+
"answer": "~/Library/Application Support/Claude/claude_desktop_config.json",
|
| 869 |
+
"explanation": "Claude Desktop์ MCP ์๋ฒ ๋ชฉ๋ก์ `claude_desktop_config.json`์ ๋ฑ๋กํฉ๋๋ค. ์๋ฒ ์ด๋ฆ, ์คํ ๋ช
๋ น์ด(`command`), ์ธ์(`args`)๋ฅผ JSON์ผ๋ก ์ ์ํ๋ฉด ์ฑ ์ฌ์์ ํ ์๋ ์ฐ๊ฒฐ๋ฉ๋๋ค.",
|
| 870 |
+
"source_id": "official-docs-mcp"
|
| 871 |
+
},
|
| 872 |
+
{
|
| 873 |
+
"id": "docs-q67",
|
| 874 |
+
"lesson_id": "docs-vectorstore",
|
| 875 |
+
"question_type": "multiple_choice",
|
| 876 |
+
"question": "**[์ํฉ ํ๋จ]** ์๋ฒ๋ฅผ ์ฌ์์ํ ๋๋ง๋ค ๋ฒกํฐ ์ธ๋ฑ์ค๊ฐ ์ฌ๋ผ์ง๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ต๋๋ค. ๊ฐ๋ฐํ์์ `save_local()` ํธ์ถ์ ์ข
์ข
๋น ๋จ๋ฆฝ๋๋ค. ์ด๋ค VectorStore๋ฅผ ์ ํํ๊ณ ๊ทธ ์ด์ ๋?",
|
| 877 |
+
"options": [
|
| 878 |
+
"Chroma โ persist_directory๋ง ์ง์ ํ๋ฉด save_local() ์์ด ์๋ ์ ์ฅ๋๋ฏ๋ก",
|
| 879 |
+
"FAISS โ ์ฑ๋ฅ์ด ๋ ๋น ๋ฅด๊ณ ํด๋ผ์ฐ๋ ๋ฐฐํฌ์ ์ ๋ฆฌํ๋ฏ๋ก",
|
| 880 |
+
"pgvector โ PostgreSQL ๊ธฐ๋ฐ์ด๋ผ ์์ ์ฑ์ด ๋์ผ๋ฏ๋ก",
|
| 881 |
+
"Qdrant โ ๋๊ท๋ชจ ๋ฒกํฐ ๊ฒ์์ ์ต์ ํ๋์ด ์์ผ๋ฏ๋ก"
|
| 882 |
+
],
|
| 883 |
+
"answer": "Chroma โ persist_directory๋ง ์ง์ ํ๋ฉด save_local() ์์ด ์๋ ์ ์ฅ๋๋ฏ๋ก",
|
| 884 |
+
"explanation": "์ด ์ํฉ์ ๊ทผ๋ณธ ๋ฌธ์ ๋ ์๋ ์ ์ฅ ํธ์ถ์ ๋น ๋จ๋ฆฌ๋ ๊ฒ์
๋๋ค. Chroma๋ `persist_directory='./chroma_db'`๋ง ์ง์ ํ๋ฉด ์๋์ผ๋ก ์ ์ฅ๋๋ฏ๋ก ์ค์ ๊ฐ๋ฅ์ฑ์ด ์์ต๋๋ค. FAISS๋ ์ฑ๋ฅ์ด ์ข์ง๋ง `save_local()`์ ๋ฐ๋์ ํธ์ถํด์ผ ํด ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ์ง ๋ชปํฉ๋๋ค.",
|
| 885 |
+
"source_id": "official-docs-chromadb",
|
| 886 |
+
"difficulty": "medium"
|
| 887 |
+
},
|
| 888 |
+
{
|
| 889 |
+
"id": "docs-q68",
|
| 890 |
+
"lesson_id": "docs-sentence-transformers",
|
| 891 |
+
"question_type": "multiple_choice",
|
| 892 |
+
"question": "**[์ํฉ ํ๋จ]** RAG ์์คํ
์ 20๋ง ๊ฐ์ ๋ฌธ์๋ฅผ ์ธ๋ฑ์ฑํด์ผ ํฉ๋๋ค. OpenAI ์๋ฒ ๋ฉ API๋ฅผ ์ฐ๋ฉด ๋น์ฉ์ด ์์๋ณด๋ค 10๋ฐฐ ๋์ฌ ๊ฒ ๊ฐ์ต๋๋ค. ์ด๋ค ์ ํ์ด ๊ฐ์ฅ ์ ํฉํ๊ฐ?",
|
| 893 |
+
"options": [
|
| 894 |
+
"sentence-transformers์ all-MiniLM-L6-v2๋ก ๋ก์ปฌ ์๋ฒ ๋ฉ โ ๋ฌด๋ฃ์ด๊ณ ์ธํฐํ์ด์ค๊ฐ ๋์ผํ๋ฏ๋ก",
|
| 895 |
+
"OpenAI ์๋ฒ ๋ฉ ์ ์ง โ ํ์ง์ด ์ค์ํ๋ฏ๋ก ๋น์ฉ์ ๊ฐ์ํ๋ค",
|
| 896 |
+
"์๋ฒ ๋ฉ์ ์ฌ์ฉํ์ง ์๊ณ ํค์๋ ๊ฒ์๋ง ์ด๋ค",
|
| 897 |
+
"Chroma๋ก ๊ต์ฒดํ๋ฉด ์๋ฒ ๋ฉ ๋น์ฉ์ด ์ ๊ฐ๋๋ค"
|
| 898 |
+
],
|
| 899 |
+
"answer": "sentence-transformers์ all-MiniLM-L6-v2๋ก ๋ก์ปฌ ์๋ฒ ๋ฉ โ ๋ฌด๋ฃ์ด๊ณ ์ธํฐํ์ด์ค๊ฐ ๋์ผํ๋ฏ๋ก",
|
| 900 |
+
"explanation": "`HuggingFaceEmbeddings(model_name='sentence-transformers/all-MiniLM-L6-v2')`๋ OpenAI Embeddings์ ์ธํฐํ์ด์ค๊ฐ ๋์ผํด ์ฝ๋๋ฅผ ํ ์ค๋ง ๋ฐ๊พธ๋ฉด ๋ฉ๋๋ค. ๋ก์ปฌ ์คํ์ด๋ฏ๋ก API ๋น์ฉ์ด ์๊ณ , ๋์ฉ๋ ์ธ๋ฑ์ฑ์ ๊ฒฝ์ ์ ์
๋๋ค. ํ๊ตญ์ด ๋ง์ผ๋ฉด `jhgan/ko-sroberta-multitask`๋ ๊ณ ๋ คํฉ๋๋ค.",
|
| 901 |
+
"source_id": "official-docs-huggingface",
|
| 902 |
+
"difficulty": "medium"
|
| 903 |
+
},
|
| 904 |
+
{
|
| 905 |
+
"id": "docs-q69",
|
| 906 |
+
"lesson_id": "docs-summarization",
|
| 907 |
+
"question_type": "multiple_choice",
|
| 908 |
+
"question": "**[์ํฉ ํ๋จ]** ๋ด์ค ๊ธฐ์ฌ 50๊ฐ๋ฅผ ๋์์ LLM์ ๋ฃ์ด ์์ฝํ๋ ค๋ค ํ ํฐ ์ด๊ณผ ์ค๋ฅ๊ฐ ๋ฌ์ต๋๋ค. ๊ฐ์ฅ ์ ์ ํ ํด๊ฒฐ ๋ฐฉ๋ฒ์?",
|
| 909 |
+
"options": [
|
| 910 |
+
"load_summarize_chain(llm, chain_type='map_reduce') ์ฌ์ฉ โ ๊ธฐ์ฌ๋ฅผ ๊ฐ๋ณ ์์ฝ ํ ํฉ์น๋ฏ๋ก ํ ํฐ ์ด๊ณผ๊ฐ ์์",
|
| 911 |
+
"๋ชจ๋ ๊ธฐ์ฌ๋ฅผ ํ๋์ ํ๋กฌํํธ์ ๋ฃ๋ stuff ๋ฐฉ์์ ์ ์งํ๋ LLM ๋ชจ๋ธ์ ๊ต์ฒด",
|
| 912 |
+
"๊ธฐ์ฌ ๊ฐ์๋ฅผ 5๊ฐ๋ก ์ค์ฌ stuff ๋ฐฉ์ ์ ์ง",
|
| 913 |
+
"summarization ๋์ RAG๋ก ๊ธฐ์ฌ๋ฅผ ๊ฒ์ํด ์์ฝ"
|
| 914 |
+
],
|
| 915 |
+
"answer": "load_summarize_chain(llm, chain_type='map_reduce') ์ฌ์ฉ โ ๊ธฐ์ฌ๋ฅผ ๊ฐ๋ณ ์์ฝ ํ ํฉ์น๋ฏ๋ก ํ ํฐ ์ด๊ณผ๊ฐ ์์",
|
| 916 |
+
"explanation": "`map_reduce`๋ ๊ฐ ๊ธฐ์ฌ๋ฅผ ๋
๋ฆฝ์ ์ผ๋ก ์์ฝ(map)ํ ๋ค ๊ฐ๋ณ ์์ฝ๋ค์ ํฉ์ณ ์ต์ข
์์ฝ(reduce)์ ๋ง๋ญ๋๋ค. ๊ธฐ์ฌ๊ฐ 100๊ฐ๋ 1000๊ฐ๋ ํ ํฐ ์ด๊ณผ๊ฐ ๋ฐ์ํ์ง ์์ต๋๋ค. ๋ชจ๋ธ ๊ต์ฒด๋ ๊ธฐ์ฌ ์ ๊ฐ์๋ ๊ทผ๋ณธ ํด๊ฒฐ์ฑ
์ด ์๋๋๋ค.",
|
| 917 |
+
"source_id": "official-docs-langchain",
|
| 918 |
+
"difficulty": "medium"
|
| 919 |
+
},
|
| 920 |
+
{
|
| 921 |
+
"id": "docs-q70",
|
| 922 |
+
"lesson_id": "docs-langsmith",
|
| 923 |
+
"question_type": "multiple_choice",
|
| 924 |
+
"question": "**[์ํฉ ํ๋จ]** RAG ์ฑ๋ด์ด ์๋ฑํ ๋ต์ ํ์ต๋๋ค. ๋ฌธ์ ๊ฐ ๊ฒ์ ๋จ๊ณ์ธ์ง, ํ๋กฌํํธ ๋ ๋๋ง ๋จ๊ณ์ธ์ง, LLM ์์ฑ ๋จ๊ณ์ธ์ง ํ์
์ด ์ ๋ฉ๋๋ค. `print()`๋ก ๋๋ฒ๊น
์ค์ธ๋ฐ ์ด๋ ๋จ๊ณ์ธ์ง ๊ตฌ๋ถ์ด ์ด๋ ต์ต๋๋ค. ๊ฐ์ฅ ํจ๊ณผ์ ์ธ ๋๊ตฌ๋?",
|
| 925 |
+
"options": [
|
| 926 |
+
"LangSmith โ ์ฒด์ธ ๊ฐ ๋จ๊ณ์ ์
์ถ๋ ฅ์ ํธ๋ฆฌ ํํ๋ก ์๊ฐํํ๋ฏ๋ก",
|
| 927 |
+
"Python logging ๋ชจ๋๋ก ๋ ์์ธํ ๋ก๊ทธ ์ถ๋ ฅ",
|
| 928 |
+
"LLM ๋ชจ๋ธ์ ๋ ๊ฐ๋ ฅํ ๊ฒ์ผ๋ก ๊ต์ฒด",
|
| 929 |
+
"chunk_size๋ฅผ ์ค์ฌ ๊ฒ์ ์ ํ๋ ํฅ์"
|
| 930 |
+
],
|
| 931 |
+
"answer": "LangSmith โ ์ฒด์ธ ๊ฐ ๋จ๊ณ์ ์
์ถ๋ ฅ์ ํธ๋ฆฌ ํํ๋ก ์๊ฐํํ๋ฏ๋ก",
|
| 932 |
+
"explanation": "LangSmith๋ ํ๊ฒฝ๋ณ์ 3๊ฐ(`LANGCHAIN_TRACING_V2=true`, `LANGCHAIN_API_KEY`, `LANGCHAIN_PROJECT`) ์ค์ ๋ง์ผ๋ก ์ฒด์ธ ์คํ๋ง๋ค retriever ์
์ถ๋ ฅ, ๋ ๋๋ง๋ ํ๋กฌํํธ, LLM ์๋ต์ ๋จ๊ณ๋ณ๋ก ๊ธฐ๋กํฉ๋๋ค. ์ด๋ ๋จ๊ณ๊ฐ ๋ฌธ์ ์ธ์ง ์ฆ์ ํน์ ํ ์ ์์ต๋๋ค.",
|
| 933 |
+
"source_id": "official-docs-langchain",
|
| 934 |
+
"difficulty": "medium"
|
| 935 |
+
},
|
| 936 |
+
{
|
| 937 |
+
"id": "docs-q71",
|
| 938 |
+
"lesson_id": "docs-guardrails",
|
| 939 |
+
"question_type": "multiple_choice",
|
| 940 |
+
"question": "**[์ํฉ ํ๋จ]** ์๋น์ค ์ฌ์ฉ์๊ฐ \"์์ค์ ์์ด ์์ฝํด์ค\"๋ผ๊ณ ์
๋ ฅํ๋๋ LLM์ด ๊ทธ๋๋ก ๋ฐ๋์ต๋๋ค. ์์คํ
ํ๋กฌํํธ์ '์์ค ๊ธ์ง'๋ฅผ ์ถ๊ฐํ์ง๋ง ์ฐํ๋๋ ๊ฒฝ์ฐ๊ฐ ์์ต๋๋ค. ๋ ๊ฐ๋ ฅํ ๋์์?",
|
| 941 |
+
"options": [
|
| 942 |
+
"Guardrails AI์ ToxicLanguage Guard๋ฅผ LLM ์ถ๋ ฅ์ ์ ์ฉ โ ํ๋ฅ ์ ์ผ๋ก ์ ํด ์ฝํ
์ธ ๋ฅผ ์ค์ง์ ์ผ๋ก ์ฐจ๋จ",
|
| 943 |
+
"์์คํ
ํ๋กฌํํธ๋ฅผ ๋ ๊ธธ๊ณ ์์ธํ๊ฒ ์์ฑ",
|
| 944 |
+
"๋ ๊ฐ๋ ฅํ LLM ๋ชจ๋ธ๋ก ๊ต์ฒด",
|
| 945 |
+
"์ฌ์ฉ์ ์
๋ ฅ ๊ธธ์ด๋ฅผ 100์๋ก ์ ํ"
|
| 946 |
+
],
|
| 947 |
+
"answer": "Guardrails AI์ ToxicLanguage Guard๋ฅผ LLM ์ถ๋ ฅ์ ์ ์ฉ โ ํ๋ฅ ์ ์ผ๋ก ์ ํด ์ฝํ
์ธ ๋ฅผ ์ค์ง์ ์ผ๋ก ์ฐจ๋จ",
|
| 948 |
+
"explanation": "์์คํ
ํ๋กฌํํธ๋ ํ๋กฌํํธ ์ธ์ ์
์ผ๋ก ์ฐํ๋ ์ ์์ต๋๋ค. Guardrails AI๋ LLM ์ถ๋ ฅ์ ๋ณ๋ ๋ถ๋ฅ ๋ชจ๋ธ๋ก ๊ฒ์ฆํด ์๊ณ๊ฐ ์ด์์ด๋ฉด ์์ธ๋ฅผ ๋ฐ์์ํต๋๋ค. `on_fail='reask'`๋ก ์ค์ ํ๋ฉด ์๋์ผ๋ก ์ฌ์์ฑ์ ์์ฒญํฉ๋๋ค. ์์คํ
ํ๋กฌํํธ๋ณด๋ค ์ค์ง์ ์ธ ๋ณดํธ ์๋จ์
๋๋ค.",
|
| 949 |
+
"source_id": "official-docs-guardrails",
|
| 950 |
+
"difficulty": "hard"
|
| 951 |
+
},
|
| 952 |
+
{
|
| 953 |
+
"id": "docs-q72",
|
| 954 |
+
"lesson_id": "docs-redis",
|
| 955 |
+
"question_type": "multiple_choice",
|
| 956 |
+
"question": "**[์ํฉ ํ๋จ]** ์ฑ๋ด ์๋น์ค๋ฅผ ๋ฐฐํฌํ๋๋ ์๋ฒ๋ฅผ ์ฌ์์ํ ๋๋ง๋ค ๋ชจ๋ ์ฌ์ฉ์์ ๋ํ ๊ธฐ๋ก์ด ์ด๊ธฐํ๋ฉ๋๋ค. ์ธ๋ฉ๋ชจ๋ฆฌ ๋์
๋๋ฆฌ๋ก ํ์คํ ๋ฆฌ๋ฅผ ๊ด๋ฆฌํ๊ณ ์์ต๋๋ค. ์ต์ํ์ ์ฝ๋ ๋ณ๊ฒฝ์ผ๋ก ํด๊ฒฐํ๋ ๋ฐฉ๋ฒ์?",
|
| 957 |
+
"options": [
|
| 958 |
+
"get_session_history ํจ์ ๋ด๋ถ๋ฅผ RedisChatMessageHistory๋ก ๊ต์ฒด โ ๋๋จธ์ง ์ฝ๋๋ ๊ทธ๋๋ก",
|
| 959 |
+
"RunnableWithMessageHistory๋ฅผ ์ ๊ฑฐํ๊ณ ๋งค ์์ฒญ๋ง๋ค ํ์คํ ๋ฆฌ๋ฅผ DB์ ์ง์ ์ ์ฅ",
|
| 960 |
+
"Streamlit session_state์ ํ์คํ ๋ฆฌ๋ฅผ ์ ์ฅ",
|
| 961 |
+
"๋ํ ํ์คํ ๋ฆฌ ์์ด ๋จ์ผ ํด์ผ๋ก ์๋น์ค๋ฅผ ์ฌ์ค๊ณ"
|
| 962 |
+
],
|
| 963 |
+
"answer": "get_session_history ํจ์ ๋ด๋ถ๋ฅผ RedisChatMessageHistory๋ก ๊ต์ฒด โ ๋๋จธ์ง ์ฝ๋๋ ๊ทธ๋๋ก",
|
| 964 |
+
"explanation": "`RunnableWithMessageHistory`๋ `get_session_history` ํจ์๋ง ๋ณด๊ณ ํ์คํ ๋ฆฌ๋ฅผ ๊ด๋ฆฌํฉ๋๋ค. ์ด ํจ์ ๋ด๋ถ๋ฅผ `RedisChatMessageHistory(session_id, url='redis://localhost:6379')`๋ก ๋ฐ๊พธ๊ธฐ๋ง ํ๋ฉด ๋ฉ๋๋ค. ๋ค๋ฅธ ์ฝ๋๋ ์ ํ ์์ ํ ํ์๊ฐ ์์ต๋๋ค.",
|
| 965 |
+
"source_id": "official-docs-redis",
|
| 966 |
+
"difficulty": "hard"
|
| 967 |
+
},
|
| 968 |
+
{
|
| 969 |
+
"id": "docs-q73",
|
| 970 |
+
"lesson_id": "docs-litellm",
|
| 971 |
+
"question_type": "multiple_choice",
|
| 972 |
+
"question": "**[์ํฉ ํ๋จ]** ๋ก์ปฌ Ollama๋ก ๊ฐ๋ฐํ๊ณ ํ๋ก๋์
์๋ Anthropic Claude๋ฅผ ์ธ ๊ณํ์
๋๋ค. ๋งค๋ฒ LLM ๊ต์ฒด ์ ์ฝ๋๋ฅผ ์ต์๋ก ์์ ํ๋ ค๋ฉด ์ด๋ป๊ฒ ๊ตฌํํด์ผ ํ๋๊ฐ?",
|
| 973 |
+
"options": [
|
| 974 |
+
"LiteLLM completion()์ ์ฌ์ฉํ๊ณ model ํ๋ผ๋ฏธํฐ๋ง ๋ณ๊ฒฝ โ ์ฝ๋ ๋๋จธ์ง๋ ๊ทธ๋๋ก",
|
| 975 |
+
"OllamaLLM๊ณผ ChatAnthropic์ if๋ฌธ์ผ๋ก ๋ถ๊ธฐ",
|
| 976 |
+
"๊ฐ๋ฐ/ํ๋ก๋์
๋ง๋ค ๋ค๋ฅธ ์ฝ๋๋ฒ ์ด์ค๋ฅผ ์ ์ง",
|
| 977 |
+
"LangChain์ ChatOpenAI๋ฅผ ๊ธฐ๋ณธ์ผ๋ก Ollama๋ ๋ณ๋ ๋ธ๋์น์์ ๊ด๋ฆฌ"
|
| 978 |
+
],
|
| 979 |
+
"answer": "LiteLLM completion()์ ์ฌ์ฉํ๊ณ model ํ๋ผ๋ฏธํฐ๋ง ๋ณ๊ฒฝ โ ์ฝ๋ ๋๋จธ์ง๋ ๊ทธ๋๋ก",
|
| 980 |
+
"explanation": "LiteLLM์ `completion(model='ollama/llama3.2', ...)`๊ณผ `completion(model='anthropic/claude-3-5-sonnet-20241022', ...)`์ ์ฝ๋๊ฐ ๋์ผํฉ๋๋ค. model ํ๋ผ๋ฏธํฐ ํ ์ค๋ง ๋ฐ๊พธ๋ฉด ํ๋ก๋ฐ์ด๋๋ฅผ ์ ํํฉ๋๋ค. if๋ฌธ ๋ถ๊ธฐ๋ ๋ณ๋ ๋ธ๋์น ๊ด๋ฆฌ๋ ์ ์ง๋ณด์ ๋น์ฉ์ด ๋์ต๋๋ค.",
|
| 981 |
+
"source_id": "official-docs-litellm",
|
| 982 |
+
"difficulty": "medium"
|
| 983 |
+
},
|
| 984 |
+
{
|
| 985 |
+
"id": "docs-q74",
|
| 986 |
+
"lesson_id": "docs-langgraph",
|
| 987 |
+
"question_type": "multiple_choice",
|
| 988 |
+
"question": "**[์ํฉ ํ๋จ]** RAG ์ฑ๋ด์ ๋ค์ ๊ธฐ๋ฅ์ ์ถ๊ฐํด์ผ ํฉ๋๋ค: \"๊ฒ์ ๊ฒฐ๊ณผ ํ์ง์ด ๋ฎ์ผ๋ฉด ๋ค๋ฅธ ๊ฒ์์ด๋ก ์ฌ์๋ํ๊ณ , 3๋ฒ ์ด์ ์คํจํ๋ฉด '์ฐพ์ง ๋ชปํ์ต๋๋ค'๋ฅผ ๋ฐํ.\" LCEL ์ฒด์ธ๋ง์ผ๋ก ์ด ๊ธฐ๋ฅ์ ๊ตฌํํ ์ ์๋๊ฐ?",
|
| 989 |
+
"options": [
|
| 990 |
+
"๋ถ๊ฐ๋ฅ โ LCEL์ ์ ํ์ด๋ผ ๋ฃจํ์ ์กฐ๊ฑด ๋ถ๊ธฐ๊ฐ ์๋ค. LangGraph๋ฅผ ์จ์ผ ํ๋ค",
|
| 991 |
+
"๊ฐ๋ฅ โ LCEL์ RunnableBranch๋ก ์กฐ๊ฑด ๋ถ๊ธฐ๋ฅผ ๊ตฌํํ ์ ์๋ค",
|
| 992 |
+
"๊ฐ๋ฅ โ Python while๋ฌธ์ chain.invoke() ๋ฐ๊นฅ์ ์ฐ๋ฉด ๋๋ค",
|
| 993 |
+
"๊ฐ๋ฅ โ retry ํ๋ผ๋ฏธํฐ๋ฅผ chain์ ์ ๋ฌํ๋ฉด ๋๋ค"
|
| 994 |
+
],
|
| 995 |
+
"answer": "๋ถ๊ฐ๋ฅ โ LCEL์ ์ ํ์ด๋ผ ๋ฃจํ์ ์กฐ๊ฑด ๋ถ๊ธฐ๊ฐ ์๋ค. LangGraph๋ฅผ ์จ์ผ ํ๋ค",
|
| 996 |
+
"explanation": "LCEL์ AโBโC ์ ํ ํ์ดํ๋ผ์ธ์
๋๋ค. 'ํ์ง ํ๋จ โ ์ฌ์๋ ์ฌ๋ถ ๊ฒฐ์ โ ๋ฃจํ' ๊ฐ์ ๋ฐ๋ณต/๋ถ๊ธฐ ๋ก์ง์ ํํํ ์ ์์ต๋๋ค. LangGraph์ `add_conditional_edges`์ ๋ฃจํ ๊ตฌ์กฐ๊ฐ ์ด๋ฐ ์์ด์ ํธ ํ๋ ํจํด์ ์ ํฉํฉ๋๋ค.",
|
| 997 |
+
"source_id": "official-docs-langgraph",
|
| 998 |
+
"difficulty": "hard"
|
| 999 |
+
},
|
| 1000 |
+
{
|
| 1001 |
+
"id": "docs-q75",
|
| 1002 |
+
"lesson_id": "docs-airflow",
|
| 1003 |
+
"question_type": "multiple_choice",
|
| 1004 |
+
"question": "**[์ํฉ ํ๋จ]** ๋ด์ค ์์ฝ ์คํฌ๋ฆฝํธ๋ฅผ ์์ฑํ์ต๋๋ค. ๋งค์ผ ์ค์ 6์์ ์๋์ผ๋ก ์คํ๋๊ณ ์คํจ ์ ์๋ฆผ์ ๋ฐ๊ณ ์ถ์ต๋๋ค. ๋ด๋น์ ์์ด๋ ์ฃผ๋ง์ ๋์ํด์ผ ํฉ๋๋ค. ๊ฐ์ฅ ์ ํฉํ ๋๊ตฌ๋?",
|
| 1005 |
+
"options": [
|
| 1006 |
+
"Airflow โ DAG๋ก ์ค์ผ์ค ์ ์, ์คํจ ์๋ฆผ, ์ด์ ์คํ ์ด๋ ฅ ๊ด๋ฆฌ๊ฐ ๊ฐ๋ฅ",
|
| 1007 |
+
"cron ์คํฌ๋ฆฝํธ โ ๊ฐ์ฅ ๋จ์ํ๊ณ ์ถ๊ฐ ์ค์น๊ฐ ์์",
|
| 1008 |
+
"Streamlit ๋ฒํผ โ ์๋ ์คํ์ด์ง๋ง UI๊ฐ ์์",
|
| 1009 |
+
"GitHub Actions โ CI/CD ํ๊ฒฝ์์ ์คํ ๊ฐ๋ฅ"
|
| 1010 |
+
],
|
| 1011 |
+
"answer": "Airflow โ DAG๋ก ์ค์ผ์ค ์ ์, ์คํจ ์๋ฆผ, ์ด์ ์คํ ์ด๋ ฅ ๊ด๋ฆฌ๊ฐ ๊ฐ๋ฅ",
|
| 1012 |
+
"explanation": "๋จ์ cron๋ ์ค์ผ์ค๋ง์ ๋์ง๋ง ์คํจ ์ ์๋ฆผ, ์ด์ ์คํ ์ด๋ ฅ ํ์ธ, ์ฌ์คํ ๊ธฐ๋ฅ์ด ์์ต๋๋ค. Airflow๋ `@daily` ์ค์ผ์ค๋ก ์๋ ์คํ๋๊ณ , ์คํจ ์ ์ด๋ฉ์ผ/Slack ์๋ฆผ, ๊ณผ๊ฑฐ ์คํ ์ด๋ ฅ ์กฐํ, ์๋ ์ฌ์คํ์ด ๋ชจ๋ ์ง์๋ฉ๋๋ค. ๋ด๋น์ ์์ด ์ด์ํ๋ ํ๋ก๋์
ํ์ดํ๋ผ์ธ์ ์ ํฉํฉ๋๋ค.",
|
| 1013 |
+
"source_id": "official-docs-airflow",
|
| 1014 |
+
"difficulty": "medium"
|
| 1015 |
+
},
|
| 1016 |
+
{
|
| 1017 |
+
"id": "docs-q76",
|
| 1018 |
+
"lesson_id": "docs-fastapi",
|
| 1019 |
+
"question_type": "multiple_choice",
|
| 1020 |
+
"question": "**[์ํฉ ํ๋จ]** RAG ์ฑ๋ด์ ์์ฑํ์ต๋๋ค. ํ๋ก ํธ์๋ ํ(React), ๋ชจ๋ฐ์ผ ํ(Flutter), ๋ฐ์ดํฐ ํ(Python)์ด ๋ชจ๋ ์ด ๊ธฐ๋ฅ์ ์ฌ์ฉํด์ผ ํฉ๋๋ค. Streamlit ์ฑ ๊ทธ๋๋ก ๋ฐฐํฌํ๋ ๊ฒ์ด ์ข์๊น์?",
|
| 1021 |
+
"options": [
|
| 1022 |
+
"์๋์ค โ FastAPI๋ก REST API๋ฅผ ๋ง๋ค์ด ๊ณต์ ํ๋ ๊ฒ์ด ์ ํฉ. ๊ฐ ํ์ด ์๊ธฐ ๋ฐฉ์์ผ๋ก ์ฐ๊ฒฐ ๊ฐ๋ฅ",
|
| 1023 |
+
"์ โ Streamlit UI๋ฅผ iframe์ผ๋ก ๊ฐ ํ ์๋น์ค์ ์ฝ์
ํ๋ฉด ๋จ",
|
| 1024 |
+
"์ โ Streamlit์ API ๊ธฐ๋ฅ๋ ์๋์ผ๋ก ์ ๊ณตํจ",
|
| 1025 |
+
"์๋์ค โ Gradio๋ก ๊ต์ฒดํด์ผ ๋ค๋ฅธ ํ๊ณผ ๊ณต์ ๊ฐ๋ฅ"
|
| 1026 |
+
],
|
| 1027 |
+
"answer": "์๋์ค โ FastAPI๋ก REST API๋ฅผ ๋ง๋ค์ด ๊ณต์ ํ๋ ๊ฒ์ด ์ ํฉ. ๊ฐ ํ์ด ์๊ธฐ ๋ฐฉ์์ผ๋ก ์ฐ๊ฒฐ ๊ฐ๋ฅ",
|
| 1028 |
+
"explanation": "Streamlit์ UI์ ๋ก์ง์ด ๊ฒฐํฉ๋ ๋จ์ผ ์ฑ์
๋๋ค. ๋ค๋ฅธ ํ์ด LLM ๊ธฐ๋ฅ์ ์ฌ์ฌ์ฉํ๋ ค๋ฉด API๊ฐ ํ์ํฉ๋๋ค. FastAPI๋ก `POST /ask` ์๋ํฌ์ธํธ๋ฅผ ๋ง๋ค๋ฉด React, Flutter, Python ์ด๋์๋ HTTP ์์ฒญ์ผ๋ก ์ ๊ทผํ ์ ์์ต๋๋ค. Streamlit์ ๊ฐ์ธ/ํ ๋ด๋ถ ๋๊ตฌ, FastAPI๋ ์๋น์ค ํตํฉ์ ์ ํฉํฉ๋๋ค.",
|
| 1029 |
+
"source_id": "official-docs-fastapi",
|
| 1030 |
+
"difficulty": "medium"
|
| 1031 |
+
}
|
| 1032 |
+
]
|
cert_study_app/services/docs_source_service.py
ADDED
|
@@ -0,0 +1,395 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from __future__ import annotations
|
| 2 |
+
|
| 3 |
+
from dataclasses import dataclass
|
| 4 |
+
from typing import Iterable
|
| 5 |
+
|
| 6 |
+
|
| 7 |
+
@dataclass(frozen=True)
|
| 8 |
+
class DocsSource:
|
| 9 |
+
id: str
|
| 10 |
+
track: str
|
| 11 |
+
provider: str
|
| 12 |
+
title: str
|
| 13 |
+
url: str
|
| 14 |
+
category: str
|
| 15 |
+
tags: tuple[str, ...] = ()
|
| 16 |
+
role: str = "reference"
|
| 17 |
+
enabled: bool = True
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
DOCS_SOURCES: tuple[DocsSource, ...] = (
|
| 21 |
+
DocsSource(
|
| 22 |
+
"manual-az104-basic",
|
| 23 |
+
"azure",
|
| 24 |
+
"Microsoft Learn",
|
| 25 |
+
"AZ-104 study guide",
|
| 26 |
+
"https://learn.microsoft.com/en-us/credentials/certifications/resources/study-guides/az-104",
|
| 27 |
+
"exam-guide",
|
| 28 |
+
("az-104", "study-guide"),
|
| 29 |
+
),
|
| 30 |
+
DocsSource(
|
| 31 |
+
"azure-vnet-overview",
|
| 32 |
+
"azure",
|
| 33 |
+
"Microsoft Learn",
|
| 34 |
+
"Azure Virtual Network overview",
|
| 35 |
+
"https://learn.microsoft.com/en-us/azure/virtual-network/virtual-networks-overview",
|
| 36 |
+
"network",
|
| 37 |
+
("vnet", "subnet", "networking"),
|
| 38 |
+
),
|
| 39 |
+
DocsSource(
|
| 40 |
+
"azure-nsg-overview",
|
| 41 |
+
"azure",
|
| 42 |
+
"Microsoft Learn",
|
| 43 |
+
"Network security groups",
|
| 44 |
+
"https://learn.microsoft.com/en-us/azure/virtual-network/network-security-groups-overview",
|
| 45 |
+
"network",
|
| 46 |
+
("nsg", "security"),
|
| 47 |
+
),
|
| 48 |
+
DocsSource(
|
| 49 |
+
"azure-private-endpoint",
|
| 50 |
+
"azure",
|
| 51 |
+
"Microsoft Learn",
|
| 52 |
+
"Private Endpoint overview",
|
| 53 |
+
"https://learn.microsoft.com/en-us/azure/private-link/private-endpoint-overview",
|
| 54 |
+
"network",
|
| 55 |
+
("private-link", "private-endpoint"),
|
| 56 |
+
),
|
| 57 |
+
DocsSource(
|
| 58 |
+
"azure-load-balancer",
|
| 59 |
+
"azure",
|
| 60 |
+
"Microsoft Learn",
|
| 61 |
+
"Azure Load Balancer overview",
|
| 62 |
+
"https://learn.microsoft.com/en-us/azure/load-balancer/load-balancer-overview",
|
| 63 |
+
"network",
|
| 64 |
+
("load-balancer",),
|
| 65 |
+
),
|
| 66 |
+
DocsSource(
|
| 67 |
+
"azure-vm-overview",
|
| 68 |
+
"azure",
|
| 69 |
+
"Microsoft Learn",
|
| 70 |
+
"Azure Virtual Machines overview",
|
| 71 |
+
"https://learn.microsoft.com/en-us/azure/virtual-machines/overview",
|
| 72 |
+
"compute",
|
| 73 |
+
("vm", "compute"),
|
| 74 |
+
),
|
| 75 |
+
DocsSource(
|
| 76 |
+
"azure-storage-account",
|
| 77 |
+
"azure",
|
| 78 |
+
"Microsoft Learn",
|
| 79 |
+
"Storage account overview",
|
| 80 |
+
"https://learn.microsoft.com/en-us/azure/storage/common/storage-account-overview",
|
| 81 |
+
"storage",
|
| 82 |
+
("storage-account", "blob"),
|
| 83 |
+
),
|
| 84 |
+
DocsSource(
|
| 85 |
+
"azure-rbac-overview",
|
| 86 |
+
"azure",
|
| 87 |
+
"Microsoft Learn",
|
| 88 |
+
"Azure RBAC overview",
|
| 89 |
+
"https://learn.microsoft.com/en-us/azure/role-based-access-control/overview",
|
| 90 |
+
"identity",
|
| 91 |
+
("rbac", "role"),
|
| 92 |
+
),
|
| 93 |
+
DocsSource(
|
| 94 |
+
"azure-monitor-overview",
|
| 95 |
+
"azure",
|
| 96 |
+
"Microsoft Learn",
|
| 97 |
+
"Azure Monitor overview",
|
| 98 |
+
"https://learn.microsoft.com/en-us/azure/azure-monitor/overview",
|
| 99 |
+
"monitor",
|
| 100 |
+
("monitor", "log-analytics"),
|
| 101 |
+
),
|
| 102 |
+
DocsSource(
|
| 103 |
+
"azure-backup-overview",
|
| 104 |
+
"azure",
|
| 105 |
+
"Microsoft Learn",
|
| 106 |
+
"Azure Backup overview",
|
| 107 |
+
"https://learn.microsoft.com/en-us/azure/backup/backup-overview",
|
| 108 |
+
"backup",
|
| 109 |
+
("backup", "recovery"),
|
| 110 |
+
),
|
| 111 |
+
DocsSource(
|
| 112 |
+
"azure-policy-overview",
|
| 113 |
+
"azure",
|
| 114 |
+
"Microsoft Learn",
|
| 115 |
+
"Azure Policy overview",
|
| 116 |
+
"https://learn.microsoft.com/en-us/azure/governance/policy/overview",
|
| 117 |
+
"governance",
|
| 118 |
+
("policy", "initiative", "compliance"),
|
| 119 |
+
),
|
| 120 |
+
DocsSource(
|
| 121 |
+
"azure-app-gateway-overview",
|
| 122 |
+
"azure",
|
| 123 |
+
"Microsoft Learn",
|
| 124 |
+
"Application Gateway overview",
|
| 125 |
+
"https://learn.microsoft.com/en-us/azure/application-gateway/overview",
|
| 126 |
+
"network",
|
| 127 |
+
("application-gateway", "waf", "layer-7"),
|
| 128 |
+
),
|
| 129 |
+
DocsSource(
|
| 130 |
+
"azure-dns-overview",
|
| 131 |
+
"azure",
|
| 132 |
+
"Microsoft Learn",
|
| 133 |
+
"Azure DNS overview",
|
| 134 |
+
"https://learn.microsoft.com/en-us/azure/dns/dns-overview",
|
| 135 |
+
"network",
|
| 136 |
+
("dns", "private-dns", "resolver"),
|
| 137 |
+
),
|
| 138 |
+
DocsSource(
|
| 139 |
+
"azure-blob-access-tiers",
|
| 140 |
+
"azure",
|
| 141 |
+
"Microsoft Learn",
|
| 142 |
+
"Blob access tiers",
|
| 143 |
+
"https://learn.microsoft.com/en-us/azure/storage/blobs/access-tiers-overview",
|
| 144 |
+
"storage",
|
| 145 |
+
("blob", "hot", "cool", "archive"),
|
| 146 |
+
),
|
| 147 |
+
DocsSource(
|
| 148 |
+
"azure-vmss-overview",
|
| 149 |
+
"azure",
|
| 150 |
+
"Microsoft Learn",
|
| 151 |
+
"Virtual Machine Scale Sets overview",
|
| 152 |
+
"https://learn.microsoft.com/en-us/azure/virtual-machine-scale-sets/overview",
|
| 153 |
+
"compute",
|
| 154 |
+
("vmss", "autoscale", "availability"),
|
| 155 |
+
),
|
| 156 |
+
DocsSource(
|
| 157 |
+
"azure-log-analytics-overview",
|
| 158 |
+
"azure",
|
| 159 |
+
"Microsoft Learn",
|
| 160 |
+
"Log Analytics overview",
|
| 161 |
+
"https://learn.microsoft.com/en-us/azure/azure-monitor/logs/log-analytics-overview",
|
| 162 |
+
"monitor",
|
| 163 |
+
("log-analytics", "kql", "monitor"),
|
| 164 |
+
),
|
| 165 |
+
DocsSource(
|
| 166 |
+
"azure-recovery-services-vault",
|
| 167 |
+
"azure",
|
| 168 |
+
"Microsoft Learn",
|
| 169 |
+
"Recovery Services vault overview",
|
| 170 |
+
"https://learn.microsoft.com/en-us/azure/backup/backup-azure-recovery-services-vault-overview",
|
| 171 |
+
"backup",
|
| 172 |
+
("recovery-services-vault", "backup-policy"),
|
| 173 |
+
),
|
| 174 |
+
DocsSource(
|
| 175 |
+
"azure-bastion-overview",
|
| 176 |
+
"azure",
|
| 177 |
+
"Microsoft Learn",
|
| 178 |
+
"Azure Bastion overview",
|
| 179 |
+
"https://learn.microsoft.com/en-us/azure/bastion/bastion-overview",
|
| 180 |
+
"network",
|
| 181 |
+
("bastion", "ssh", "rdp"),
|
| 182 |
+
),
|
| 183 |
+
DocsSource(
|
| 184 |
+
"azure-nat-gateway",
|
| 185 |
+
"azure",
|
| 186 |
+
"Microsoft Learn",
|
| 187 |
+
"Azure NAT Gateway overview",
|
| 188 |
+
"https://learn.microsoft.com/en-us/azure/nat-gateway/nat-overview",
|
| 189 |
+
"network",
|
| 190 |
+
("nat-gateway", "outbound"),
|
| 191 |
+
),
|
| 192 |
+
DocsSource(
|
| 193 |
+
"azure-app-service-overview",
|
| 194 |
+
"azure",
|
| 195 |
+
"Microsoft Learn",
|
| 196 |
+
"App Service overview",
|
| 197 |
+
"https://learn.microsoft.com/en-us/azure/app-service/overview",
|
| 198 |
+
"compute",
|
| 199 |
+
("app-service", "web-app"),
|
| 200 |
+
),
|
| 201 |
+
DocsSource(
|
| 202 |
+
"azure-container-instances",
|
| 203 |
+
"azure",
|
| 204 |
+
"Microsoft Learn",
|
| 205 |
+
"Azure Container Instances overview",
|
| 206 |
+
"https://learn.microsoft.com/en-us/azure/container-instances/container-instances-overview",
|
| 207 |
+
"compute",
|
| 208 |
+
("aci", "container"),
|
| 209 |
+
),
|
| 210 |
+
DocsSource(
|
| 211 |
+
"azure-key-vault-overview",
|
| 212 |
+
"azure",
|
| 213 |
+
"Microsoft Learn",
|
| 214 |
+
"Azure Key Vault overview",
|
| 215 |
+
"https://learn.microsoft.com/en-us/azure/key-vault/general/overview",
|
| 216 |
+
"security",
|
| 217 |
+
("key-vault", "secret", "key"),
|
| 218 |
+
),
|
| 219 |
+
DocsSource(
|
| 220 |
+
"manual-linux-basic",
|
| 221 |
+
"linux",
|
| 222 |
+
"GNU Coreutils Manual",
|
| 223 |
+
"GNU Coreutils basic operations",
|
| 224 |
+
"https://www.gnu.org/software/coreutils/manual/coreutils.html",
|
| 225 |
+
"essential-commands",
|
| 226 |
+
("pwd", "ls", "mkdir", "touch", "chmod"),
|
| 227 |
+
"command-reference",
|
| 228 |
+
),
|
| 229 |
+
DocsSource(
|
| 230 |
+
"linux-bash-cd",
|
| 231 |
+
"linux",
|
| 232 |
+
"GNU Bash Manual",
|
| 233 |
+
"Bash builtins",
|
| 234 |
+
"https://www.gnu.org/software/bash/manual/html_node/Bourne-Shell-Builtins.html",
|
| 235 |
+
"shell",
|
| 236 |
+
("cd", "shell-builtin"),
|
| 237 |
+
"command-reference",
|
| 238 |
+
),
|
| 239 |
+
DocsSource(
|
| 240 |
+
"linux-grep-manual",
|
| 241 |
+
"linux",
|
| 242 |
+
"GNU Grep Manual",
|
| 243 |
+
"GNU Grep manual",
|
| 244 |
+
"https://www.gnu.org/software/grep/manual/grep.html",
|
| 245 |
+
"text-processing",
|
| 246 |
+
("grep", "search"),
|
| 247 |
+
"command-reference",
|
| 248 |
+
),
|
| 249 |
+
DocsSource(
|
| 250 |
+
"linux-systemd-systemctl",
|
| 251 |
+
"linux",
|
| 252 |
+
"freedesktop.org",
|
| 253 |
+
"systemctl manual",
|
| 254 |
+
"https://www.freedesktop.org/software/systemd/man/latest/systemctl.html",
|
| 255 |
+
"services",
|
| 256 |
+
("systemctl", "service"),
|
| 257 |
+
"command-reference",
|
| 258 |
+
),
|
| 259 |
+
DocsSource(
|
| 260 |
+
"linux-man7-ip",
|
| 261 |
+
"linux",
|
| 262 |
+
"man7.org",
|
| 263 |
+
"ip command manual",
|
| 264 |
+
"https://man7.org/linux/man-pages/man8/ip.8.html",
|
| 265 |
+
"networking",
|
| 266 |
+
("ip", "networking"),
|
| 267 |
+
"command-reference",
|
| 268 |
+
),
|
| 269 |
+
DocsSource(
|
| 270 |
+
"ubuntu-server-docs",
|
| 271 |
+
"linux",
|
| 272 |
+
"Ubuntu Server Docs",
|
| 273 |
+
"Ubuntu Server documentation",
|
| 274 |
+
"https://ubuntu.com/server/docs/",
|
| 275 |
+
"server-operations",
|
| 276 |
+
("ubuntu", "server", "operations"),
|
| 277 |
+
"practice-guide",
|
| 278 |
+
),
|
| 279 |
+
DocsSource(
|
| 280 |
+
"ubuntu-package-management",
|
| 281 |
+
"linux",
|
| 282 |
+
"Ubuntu Server Docs",
|
| 283 |
+
"Install and manage packages",
|
| 284 |
+
"https://ubuntu.com/server/docs/how-to/software/package-management/",
|
| 285 |
+
"package-management",
|
| 286 |
+
("apt", "package", "software"),
|
| 287 |
+
"practice-guide",
|
| 288 |
+
),
|
| 289 |
+
DocsSource(
|
| 290 |
+
"ubuntu-user-management",
|
| 291 |
+
"linux",
|
| 292 |
+
"Ubuntu Server Docs",
|
| 293 |
+
"User management",
|
| 294 |
+
"https://ubuntu.com/server/docs/how-to/security/user-management/",
|
| 295 |
+
"users-groups",
|
| 296 |
+
("user", "group", "sudo"),
|
| 297 |
+
"practice-guide",
|
| 298 |
+
),
|
| 299 |
+
DocsSource(
|
| 300 |
+
"ubuntu-networking",
|
| 301 |
+
"linux",
|
| 302 |
+
"Ubuntu Server Docs",
|
| 303 |
+
"Networking",
|
| 304 |
+
"https://ubuntu.com/server/docs/how-to/networking/",
|
| 305 |
+
"networking",
|
| 306 |
+
("netplan", "dns", "network-tools"),
|
| 307 |
+
"practice-guide",
|
| 308 |
+
),
|
| 309 |
+
DocsSource(
|
| 310 |
+
"ubuntu-firewall",
|
| 311 |
+
"linux",
|
| 312 |
+
"Ubuntu Server Docs",
|
| 313 |
+
"Firewall",
|
| 314 |
+
"https://ubuntu.com/server/docs/how-to/security/firewalls/",
|
| 315 |
+
"security",
|
| 316 |
+
("ufw", "firewall", "port"),
|
| 317 |
+
"practice-guide",
|
| 318 |
+
),
|
| 319 |
+
DocsSource(
|
| 320 |
+
"ubuntu-storage",
|
| 321 |
+
"linux",
|
| 322 |
+
"Ubuntu Server Docs",
|
| 323 |
+
"Storage",
|
| 324 |
+
"https://ubuntu.com/server/docs/how-to/storage/",
|
| 325 |
+
"storage",
|
| 326 |
+
("lvm", "storage", "iscsi"),
|
| 327 |
+
"practice-guide",
|
| 328 |
+
),
|
| 329 |
+
DocsSource(
|
| 330 |
+
"official-docs-ollama",
|
| 331 |
+
"tool_docs",
|
| 332 |
+
"Ollama Docs",
|
| 333 |
+
"Ollama documentation",
|
| 334 |
+
"https://docs.ollama.com/",
|
| 335 |
+
"ollama",
|
| 336 |
+
("ollama", "local-model"),
|
| 337 |
+
),
|
| 338 |
+
DocsSource(
|
| 339 |
+
"official-docs-langchain",
|
| 340 |
+
"tool_docs",
|
| 341 |
+
"LangChain Docs",
|
| 342 |
+
"LangChain documentation",
|
| 343 |
+
"https://python.langchain.com/docs/",
|
| 344 |
+
"langchain",
|
| 345 |
+
("langchain", "rag"),
|
| 346 |
+
),
|
| 347 |
+
DocsSource(
|
| 348 |
+
"official-docs-streamlit",
|
| 349 |
+
"tool_docs",
|
| 350 |
+
"Streamlit Docs",
|
| 351 |
+
"Streamlit documentation",
|
| 352 |
+
"https://docs.streamlit.io/",
|
| 353 |
+
"streamlit",
|
| 354 |
+
("streamlit", "session-state"),
|
| 355 |
+
),
|
| 356 |
+
DocsSource(
|
| 357 |
+
"official-docs-huggingface",
|
| 358 |
+
"tool_docs",
|
| 359 |
+
"Hugging Face Docs",
|
| 360 |
+
"Hugging Face documentation",
|
| 361 |
+
"https://huggingface.co/docs",
|
| 362 |
+
"huggingface",
|
| 363 |
+
("huggingface", "spaces"),
|
| 364 |
+
),
|
| 365 |
+
)
|
| 366 |
+
|
| 367 |
+
|
| 368 |
+
def active_docs_sources(track_id: str | None = None) -> list[DocsSource]:
|
| 369 |
+
sources = [source for source in DOCS_SOURCES if source.enabled]
|
| 370 |
+
if track_id and track_id != "all":
|
| 371 |
+
sources = [source for source in sources if source.track == track_id]
|
| 372 |
+
return sources
|
| 373 |
+
|
| 374 |
+
|
| 375 |
+
def doc_source_by_id(source_id: str | None) -> DocsSource | None:
|
| 376 |
+
if not source_id:
|
| 377 |
+
return None
|
| 378 |
+
return next((source for source in DOCS_SOURCES if source.id == source_id), None)
|
| 379 |
+
|
| 380 |
+
|
| 381 |
+
def doc_source_urls(track_id: str | None = None) -> list[str]:
|
| 382 |
+
return [source.url for source in active_docs_sources(track_id)]
|
| 383 |
+
|
| 384 |
+
|
| 385 |
+
def docs_source_options() -> list[tuple[str, str]]:
|
| 386 |
+
return [
|
| 387 |
+
("all", "์ ์ฒด Docs"),
|
| 388 |
+
("azure", "Azure Docs"),
|
| 389 |
+
("linux", "Linux Docs"),
|
| 390 |
+
("tool_docs", "Tool Docs"),
|
| 391 |
+
]
|
| 392 |
+
|
| 393 |
+
|
| 394 |
+
def urls_from_sources(sources: Iterable[DocsSource]) -> list[str]:
|
| 395 |
+
return [source.url for source in sources]
|
cert_study_app/services/official_docs_service.py
ADDED
|
@@ -0,0 +1,210 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from __future__ import annotations
|
| 2 |
+
|
| 3 |
+
import hashlib
|
| 4 |
+
import re
|
| 5 |
+
from datetime import datetime
|
| 6 |
+
from html.parser import HTMLParser
|
| 7 |
+
from typing import Optional
|
| 8 |
+
|
| 9 |
+
import requests
|
| 10 |
+
|
| 11 |
+
from cert_study_app.models import AzureDocsSync
|
| 12 |
+
from cert_study_app.services.docs_source_service import DocsSource, active_docs_sources
|
| 13 |
+
from cert_study_app.services.vector_service import DEFAULT_EMBEDDING_MODEL, QuestionVectorStore
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
OFFICIAL_DOC_URLS = [source.url for source in active_docs_sources()]
|
| 17 |
+
OFFICIAL_DOCS_COLLECTION = "official_docs"
|
| 18 |
+
LEGACY_AZURE_DOCS_COLLECTION = "azure_docs"
|
| 19 |
+
|
| 20 |
+
|
| 21 |
+
class _MainTextParser(HTMLParser):
|
| 22 |
+
def __init__(self):
|
| 23 |
+
super().__init__()
|
| 24 |
+
self.title = ""
|
| 25 |
+
self._in_title = False
|
| 26 |
+
self._skip_depth = 0
|
| 27 |
+
self._chunks: list[str] = []
|
| 28 |
+
|
| 29 |
+
def handle_starttag(self, tag, attrs):
|
| 30 |
+
if tag == "title":
|
| 31 |
+
self._in_title = True
|
| 32 |
+
if tag in {"script", "style", "noscript", "svg"}:
|
| 33 |
+
self._skip_depth += 1
|
| 34 |
+
if tag in {"p", "li", "h1", "h2", "h3", "h4", "td", "th"}:
|
| 35 |
+
self._chunks.append("\n")
|
| 36 |
+
|
| 37 |
+
def handle_endtag(self, tag):
|
| 38 |
+
if tag == "title":
|
| 39 |
+
self._in_title = False
|
| 40 |
+
if tag in {"script", "style", "noscript", "svg"} and self._skip_depth:
|
| 41 |
+
self._skip_depth -= 1
|
| 42 |
+
if tag in {"p", "li", "h1", "h2", "h3", "h4", "tr"}:
|
| 43 |
+
self._chunks.append("\n")
|
| 44 |
+
|
| 45 |
+
def handle_data(self, data):
|
| 46 |
+
text = re.sub(r"\s+", " ", data or "").strip()
|
| 47 |
+
if not text:
|
| 48 |
+
return
|
| 49 |
+
if self._in_title and not self.title:
|
| 50 |
+
self.title = text
|
| 51 |
+
if not self._skip_depth:
|
| 52 |
+
self._chunks.append(text)
|
| 53 |
+
|
| 54 |
+
def text(self) -> str:
|
| 55 |
+
text = " ".join(self._chunks)
|
| 56 |
+
text = re.sub(r"\s*\n\s*", "\n", text)
|
| 57 |
+
text = re.sub(r"[ \t]{2,}", " ", text)
|
| 58 |
+
return text.strip()
|
| 59 |
+
|
| 60 |
+
|
| 61 |
+
def _chunk_text(text: str, chunk_size: int = 1400, overlap: int = 180) -> list[str]:
|
| 62 |
+
clean = re.sub(r"\n{3,}", "\n\n", text or "").strip()
|
| 63 |
+
if not clean:
|
| 64 |
+
return []
|
| 65 |
+
chunks = []
|
| 66 |
+
start = 0
|
| 67 |
+
while start < len(clean):
|
| 68 |
+
end = min(len(clean), start + chunk_size)
|
| 69 |
+
chunk = clean[start:end].strip()
|
| 70 |
+
if chunk:
|
| 71 |
+
chunks.append(chunk)
|
| 72 |
+
if end >= len(clean):
|
| 73 |
+
break
|
| 74 |
+
start = max(0, end - overlap)
|
| 75 |
+
return chunks
|
| 76 |
+
|
| 77 |
+
|
| 78 |
+
def _doc_id(url: str, index: int, text: str) -> str:
|
| 79 |
+
digest = hashlib.sha1(f"{url}|{index}|{text}".encode("utf-8")).hexdigest()[:16]
|
| 80 |
+
return f"official_docs:{digest}"
|
| 81 |
+
|
| 82 |
+
|
| 83 |
+
def _category_from_url(url: str) -> str:
|
| 84 |
+
if "virtual-network" in url or "private-link" in url or "load-balancer" in url or "application-gateway" in url:
|
| 85 |
+
return "network"
|
| 86 |
+
if "virtual-machines" in url or "app-service" in url or "container-instances" in url:
|
| 87 |
+
return "compute"
|
| 88 |
+
if "storage" in url:
|
| 89 |
+
return "storage"
|
| 90 |
+
if "role-based-access-control" in url or "entra" in url or "key-vault" in url:
|
| 91 |
+
return "identity"
|
| 92 |
+
if "monitor" in url:
|
| 93 |
+
return "monitor"
|
| 94 |
+
if "backup" in url:
|
| 95 |
+
return "backup"
|
| 96 |
+
return "docs"
|
| 97 |
+
|
| 98 |
+
|
| 99 |
+
class OfficialDocsService:
|
| 100 |
+
def __init__(
|
| 101 |
+
self,
|
| 102 |
+
db,
|
| 103 |
+
embedding_model: Optional[str] = None,
|
| 104 |
+
urls: Optional[list[str]] = None,
|
| 105 |
+
track_id: str | None = None,
|
| 106 |
+
sources: Optional[list[DocsSource]] = None,
|
| 107 |
+
collection_name: str = OFFICIAL_DOCS_COLLECTION,
|
| 108 |
+
):
|
| 109 |
+
self.db = db
|
| 110 |
+
self.embedding_model = embedding_model or DEFAULT_EMBEDDING_MODEL
|
| 111 |
+
if sources is not None:
|
| 112 |
+
self.sources = sources
|
| 113 |
+
elif urls:
|
| 114 |
+
self.sources = self._sources_from_urls(urls)
|
| 115 |
+
else:
|
| 116 |
+
self.sources = active_docs_sources(track_id)
|
| 117 |
+
self.vector_store = QuestionVectorStore(
|
| 118 |
+
collection_name=collection_name,
|
| 119 |
+
embedding_model=self.embedding_model,
|
| 120 |
+
)
|
| 121 |
+
|
| 122 |
+
@staticmethod
|
| 123 |
+
def _sources_from_urls(urls: Optional[list[str]]) -> list[DocsSource]:
|
| 124 |
+
return [
|
| 125 |
+
DocsSource(
|
| 126 |
+
id=f"custom-doc-{index}",
|
| 127 |
+
track="custom",
|
| 128 |
+
provider="Custom Docs",
|
| 129 |
+
title=url.rsplit("/", 1)[-1] or url,
|
| 130 |
+
url=url,
|
| 131 |
+
category="custom",
|
| 132 |
+
)
|
| 133 |
+
for index, url in enumerate(urls or [], 1)
|
| 134 |
+
]
|
| 135 |
+
|
| 136 |
+
def latest_sync(self) -> AzureDocsSync | None:
|
| 137 |
+
return self.db.query(AzureDocsSync).order_by(AzureDocsSync.id.desc()).first()
|
| 138 |
+
|
| 139 |
+
def sync(self, limit: Optional[int] = None) -> dict:
|
| 140 |
+
sync = AzureDocsSync(
|
| 141 |
+
embedding_model=self.embedding_model,
|
| 142 |
+
status="running",
|
| 143 |
+
message="๊ณต์ Docs ๋๊ธฐํ๋ฅผ ์์ํ์ต๋๋ค.",
|
| 144 |
+
started_at=datetime.utcnow(),
|
| 145 |
+
)
|
| 146 |
+
self.db.add(sync)
|
| 147 |
+
self.db.commit()
|
| 148 |
+
|
| 149 |
+
sources = self.sources[: int(limit)] if limit else self.sources
|
| 150 |
+
checked = 0
|
| 151 |
+
docs_indexed = 0
|
| 152 |
+
chunks_indexed = 0
|
| 153 |
+
try:
|
| 154 |
+
for source in sources:
|
| 155 |
+
checked += 1
|
| 156 |
+
response = requests.get(source.url, timeout=20, headers={"User-Agent": "cert-study-app/1.0"})
|
| 157 |
+
response.raise_for_status()
|
| 158 |
+
parser = _MainTextParser()
|
| 159 |
+
parser.feed(response.text)
|
| 160 |
+
title = parser.title or source.title or source.url.rsplit("/", 1)[-1]
|
| 161 |
+
chunks = _chunk_text(parser.text())
|
| 162 |
+
payloads = [
|
| 163 |
+
{
|
| 164 |
+
"id": _doc_id(source.url, index, chunk),
|
| 165 |
+
"text": f"Title: {title}\nURL: {source.url}\n\n{chunk}",
|
| 166 |
+
"source_type": f"{source.track}_docs",
|
| 167 |
+
"source": source.provider,
|
| 168 |
+
"source_id": source.id,
|
| 169 |
+
"track": source.track,
|
| 170 |
+
"role": source.role,
|
| 171 |
+
"title": title,
|
| 172 |
+
"url": source.url,
|
| 173 |
+
"category": source.category or _category_from_url(source.url),
|
| 174 |
+
}
|
| 175 |
+
for index, chunk in enumerate(chunks, 1)
|
| 176 |
+
]
|
| 177 |
+
inserted = self.vector_store.upsert_documents(payloads)
|
| 178 |
+
if inserted:
|
| 179 |
+
docs_indexed += 1
|
| 180 |
+
chunks_indexed += inserted
|
| 181 |
+
|
| 182 |
+
sync.status = "success"
|
| 183 |
+
sync.message = f"{docs_indexed}๊ฐ ๋ฌธ์, {chunks_indexed}๊ฐ chunk๋ฅผ ์์ธํ์ต๋๋ค."
|
| 184 |
+
except Exception as exc:
|
| 185 |
+
sync.status = "failed"
|
| 186 |
+
sync.error_message = str(exc)[:1000]
|
| 187 |
+
sync.message = "๊ณต์ Docs ๋๊ธฐํ ์คํจ"
|
| 188 |
+
finally:
|
| 189 |
+
sync.urls_checked = checked
|
| 190 |
+
sync.documents_indexed = docs_indexed
|
| 191 |
+
sync.chunks_indexed = chunks_indexed
|
| 192 |
+
sync.completed_at = datetime.utcnow()
|
| 193 |
+
self.db.commit()
|
| 194 |
+
|
| 195 |
+
return {
|
| 196 |
+
"status": sync.status,
|
| 197 |
+
"urls_checked": checked,
|
| 198 |
+
"documents_indexed": docs_indexed,
|
| 199 |
+
"chunks_indexed": chunks_indexed,
|
| 200 |
+
"message": sync.message,
|
| 201 |
+
"error_message": sync.error_message,
|
| 202 |
+
}
|
| 203 |
+
|
| 204 |
+
|
| 205 |
+
class AzureDocsService(OfficialDocsService):
|
| 206 |
+
"""Backward-compatible alias for older imports."""
|
| 207 |
+
|
| 208 |
+
def __init__(self, *args, **kwargs):
|
| 209 |
+
kwargs.setdefault("track_id", "azure")
|
| 210 |
+
super().__init__(*args, **kwargs)
|