GammaCyber

סדנת למידה מהירה — טכנולוגיה חדשה תחת לחץ זמן

סימולציות מיון · 5–6 שעות

// סקירה

סדנת למידה מהירה — ספרייה לא מוכרת תוך 30 דקות

אחד מהחלקים המפחידים בסדנת גאמא הוא הרגע שמקבלים ספרייה שמעולם לא ראו — ומבקשים לממש איתה משהו תוך שעה. זה לא מבחן על הספרייה — זה מבחן על יכולת הלמידה שלך.

✓נושאי השיעור
  • שיטת 5 שלבים — README→Example→API Scan→Implement→Debug, סה"כ 30 דקות
  • ניווט ב-Documentation — מה לחפש ומה לדלג, dir() ו-help() ב-Python
  • Error Messages — קרא מלמטה למעלה, כל שגיאה היא מידע
  • תרגיל: requests (Python) — GET, JSON, timeout, error handling
  • תרגיל: axios (JavaScript) — async/await, POST, error types
  • תרגיל: C Header File — קריאת API ישירות מ-.h ללא Docs
  • Mindset מקצועי — מה אומרים למלווה, מה לא, קוד עובד חלקי > קוד שלם שבור
🎯 קשר למיוני גאמא
שיעור זה מכין לשלבים: סדנה מעשית — 'קחו 45 דקות, תלמדו ספרייה X, תממשו משימה Y' · Black Box CTF — ספרייה בקוד שמעולם לא ראית, הבן API מהקוד עצמו · ראיון מקצועי — 'מעולם לא השתמשת ב-X? הסבר איך תתחיל ללמוד'
// פרק 1

שיטת 5 שלבים: ללמוד ספרייה ב-30 דקות

כל שלב מוגבל בזמן — ומיועד לתת מספיק כדי להתחיל לממש, לא להיות מומחה. זה כמו קבלת מפה לעיר חדשה — לא צריך לדעת כל רחוב, צריך לדעת לקרוא מפה ולמצוא יעד.

1
README — מה זה ולמה זה קיים?
⏱ 5 דקות
קרא את ה-Description הראשון: מה הבעיה שהספרייה פותרת? חפש: Installation, Quick Start, Basic Example. דלג על: History, Contributing, License, Architecture עמוקה.
2
Example — העתק-הרץ-שבור
⏱ 5 דקות
מצא את ה-Basic Example הקצר ביותר. העתק בדיוק → הרץ → ראה שעובד. אחר כך שבור: שנה ערך, הוסף שורה, מחק — ראה מה קורה. Error Messages הם מורים.
3
API Scan — מה הכלים שיש?
⏱ 5 דקות
מצא את ה-Class/Module הראשי. מצא 3-5 פונקציות נפוצות. לא לקרוא הכל — רק לסרוק: מה אפשרי? שאל: 'איזו פונקציה תעשה את המשימה שנדרשת ממני?'
4
Implement — מממשים! לא מחכים
⏱ 15 דקות
התחל לכתוב קוד מיד — גם אם לא בטוח. Error? → קרא, חפש, תקן. תקוע 3 דקות? Stack Overflow. תקוע 5 דקות? חזור ל-Example ובנה מעליו.
5
Debug & Polish — מה עבד? מה לא?
⏱ 5 דקות
הרץ את הפתרון שלך — האם עושה מה שנדרש? אם לא: הוסף print/log, ראה ערכים ביניים. קוד עובד חלקי > קוד יפה שלא גמרת.
הרחבה Google חכם — חיפוש ספרייה לא מוכרת ›

הסדר הנכון לחיפוש:

  • library_name getting started → ה-Tutorial הטוב ביותר
  • library_name example python → דוגמאות מוכנות
  • library_name [error message] → פתרון לשגיאה ספציפית
  • library_name vs [ספרייה שאתה מכיר] → הבנת ההבדלים
  • site:github.com library_name → קוד אמיתי של אחרים

ב-Python: import lib; print(dir(lib)) חושף את כל ה-API תוך שניות — לפעמים עדיף מ-Docs.

✏תרגול עצמי3 שאלות
שאלה 1.1 — שיטת הלמידה
קיבלת ספרייה Python לא מוכרת בסדנה. מה הצעד הראשון?
✓ תשובה: ג) — dir() הוא ה-API Scanner המובנה של Python. תוך שניות רואים רשימת כל הפונקציות והמחלקות. help() נותן documentation מהיר על כל פונקציה — Parameters, Returns, Raises. זה מהיר בהרבה מקריאת Docs חיצוניים, ועובד גם ב-Offline.
שאלה 1.2 — ניהול זמן
אתה תקוע 8 דקות על בעיה בסדנה. מה עושים?
✓ תשובה: ד) — שתיקה + ויתור = הכישלון הכי גרוע. חיפוש GitHub Issues עם הודעת השגיאה המדויקת נותן לרוב פתרון תוך דקות. חזרה ל-Basic Example ובנייה הדרגתית עליו — Strategy מוכחת. דיבור למלווה מראה יכולת תקשורת ומודעות עצמית, וקלות עוזרת.
שאלה 1.3 — Dry Run: json.loads
import json raw = '{"name": "gamma", "score": 95, "tags": ["cyber", "ctf"]}' data = json.loads(raw) print(type(data)) print(data['tags'][1]) print(data.get('level', 'unknown'))מה הפלט?
✓ תשובה: ג) — json.loads() מחזיר Python dict. type(data) = <class 'dict'>. data['tags'] = ["cyber","ctf"]. tags[1] = "ctf" (אינדקס 1). data.get('level', 'unknown'): 'level' לא קיים ב-dict → מחזיר 'unknown'. שים לב: data['level'] היה זורק KeyError!
// פרק 2

Error Messages — המורה הטוב ביותר

שגיאות הן לא כישלון — הן מידע. מקצוענים רואים Error ומפעילים Methodology. מתחילים רואים Error ונבהלים. ההבדל הוא גישה.

טבלת Error Types

סוג שגיאהמה זה אומראיך לטפל
ModuleNotFoundErrorהספרייה לא מותקנתpip install X / npm install X
AttributeErrorקראת לפונקציה שלא קיימתdir(obj) לבדוק מה יש
TypeErrorטיפוס שגוי בפרמטרבדוק מה הפונקציה מצפה
KeyError / IndexErrorגישה לKey/Index שלא קייםבדוק שה-Key קיים קודם
ConnectionErrorבעיה ברשתבדוק URL, port, חיבור
ValueErrorערך לא תקיןבדוק פורמט הנתונים
# ─── Anatomy: קרא Traceback מלמטה למעלה! ───────────────── Traceback (most recent call last): ← התחל לקרוא מלמטה! File 'my_code.py', line 15, in main result = api.fetch_data(url, timeout) File '/lib/api_client.py', line 42, in fetch_data response = requests.get(url, timeout=timeout) requests.exceptions.ConnectionError: ← 1. סוג השגיאה Failed to establish a new connection: ← 2. תיאור [Errno 111] Connection refused ← 3. הסיבה הספציפית # ─── אבחון ───────────────────────────────────────────────── # 1. שורה תחתונה: 'Connection refused' → השרת לא מקשיב # 2. הקוד שלי: line 15 → בדוק ה-URL שאני שולח # 3. פתרון: האם ה-URL נכון? האם השרת רץ? האם ה-Port נכון? # ─── Pattern נפוץ בסדנה / CTF ───────────────────────────── # שגיאה: AttributeError: 'NoneType' has no attribute 'text' # → response מ-requests.get() החזיר None (שגיאת רשת?) # פתרון: תמיד בדוק: if response is not None and response.status_code == 200: data = response.json() else: print(f"Error: {response.status_code if response else 'No response'}")
! מלכודת — None לא זורק Exception ›

פונקציה שמחזירה None על כישלון (במקום לזרוק Exception) היא מלכודת נפוצה. הקוד ממשיך, ואחר כך קורסת בשורה אחרת עם AttributeError מבלבל.

# ─── דוגמה: None propagation ────────────────────────────── def find_user(id): # ... API call ... # מחזיר None אם לא נמצא user = find_user(999) # לא קיים → None print(user['name']) # AttributeError: 'NoneType'! # ─── תיקון: תמיד בדוק None ────────────────────────────── user = find_user(999) if user is None: print("User not found") else: print(user['name'])
כלל: בכל פעם שפונקציה יכולה להחזיר None — בדוק לפני שימוש. זה גם Error Handling וגם Defense Programming.
✏תרגול עצמי3 שאלות
שאלה 2.1 — זיהוי Error
קיבלת: TypeError: connect() missing 1 required positional argument: 'port'. מה עושים?
✓ תשובה: ד) — ה-Error מספר בדיוק מה חסר: פרמטר 'port'. help(connect) מציג את כל הפרמטרים הנדרשים ואופציונליים. TypeError = טיפוס שגוי או פרמטר חסר — תמיד קרא מה הפונקציה מצפה. ה-Error הוא ה-Doc!
שאלה 2.2 — קריאת Traceback
File 'scanner.py', line 23, in run_scan results = api.scan(target) File '/lib/api.py', line 67, in scan sock.connect((host, port)) ConnectionRefusedError: [Errno 111] Connection refusedמה הבעיה וכיצד לתקן?
✓ תשובה: א) — קוראים מלמטה למעלה: שורה תחתונה = ConnectionRefusedError: Connection refused. זה אומר שמנסים לפתוח TCP connection אבל השרת לא מקשיב. הקוד שלך ב-line 23. לבדוק: target נכון? Port פתוח? אם זה סדנה — האם השרת שלהם רץ? שאל את המלווה.
שאלה 2.3 — AttributeError על None
import requests r = requests.get('https://api.example.com/data') print(r.json()['result']) # שגיאה: AttributeError: 'NoneType' object has no attribute 'json'מה הסיבה ומה התיקון?
✓ תשובה: ג) — requests.get() יכול להחזיר None אם יש שגיאת רשת, או לזרוק Exception. ה-AttributeError "NoneType has no attribute 'json'" = r היא None. תיקון: if r and r.status_code == 200: data = r.json(). תמיד בדוק None ו-status_code לפני שימוש ב-Response.
// פרק 3

requests (Python) ו-axios (JS) — תרגול מעשי

שתי ספריות HTTP נפוצות שמופיעות בסדנה. requests לפייתון, axios לג'אווסקריפט. הלוגיקה זהה — HTTP request, קבל response, טפל ב-errors.

# ─── requests (Python) — API מרכזי ─────────────────────── import requests # GET בסיסי: r = requests.get('https://httpbin.org/get', timeout=10) print(r.status_code) # 200 print(r.json()) # dict — הJSON המפוענח print(r.text) # str — גוף כטקסט גולמי print(r.headers) # dict — Response headers # GET עם params: r = requests.get('https://api.github.com/users/torvalds', headers={'Accept': 'application/vnd.github.v3+json'}, timeout=10) if r.status_code == 200: data = r.json() print(f"Name: {data['name']}, Repos: {data['public_repos']}") # POST עם JSON: r = requests.post('https://httpbin.org/post', json={'key': 'value'}, timeout=10) # Error Handling: try: r = requests.get('https://httpbin.org/delay/10', timeout=2) except requests.exceptions.Timeout: print("Timeout!") except requests.exceptions.ConnectionError: print("No connection!") # ─── axios (JavaScript) — API מרכזי ───────────────────── const axios = require('axios'); // GET בסיסי: const response = await axios.get('https://api.example.com/data'); console.log(response.data); // ← הJSON (לא response.json()!) console.log(response.status); // 200 // POST עם Error Handling: try { const res = await axios.post('/api/items', { name: 'test' }); console.log('Created:', res.data); } catch (error) { if (error.response) { // שרת החזיר 4xx/5xx console.error('Server error:', error.response.status); } else if (error.request) { // לא קיבלנו תגובה כלל console.error('Network error'); } else { // שגיאה בהגדרת הRequest console.error('Setup error:', error.message); } }
תכונהrequests (Python)axios (JavaScript)
JSON Responser.json()response.data
Status Coder.status_coderesponse.status
AsyncSynchronous (blocking)Promise / async-await
Error 4xx/5xxאין Exception — בדוק status_codeזורק Exception עם error.response
Timeouttimeout=10 (שניות){ timeout: 10000 } (ms)
✏תרגול עצמי3 שאלות
שאלה 3.1 — requests vs axios
ב-requests (Python) קיבלת Response עם status_code=404. האם נזרקה Exception?
✓ תשובה: ב) — ההבדל המרכזי בין requests לaxios: axios זורק Exception על 4xx/5xx (ל-catch ב-try-catch). requests לא — הוא מחזיר Response עם status_code=404 ומצפה שתבדוק. אפשר להפעיל r.raise_for_status() כדי שrequests יזרוק Exception על שגיאות HTTP.
שאלה 3.2 — axios error types
ב-axios קיבלת Exception בtry-catch. error.response הוא undefined. מה זה אומר?
✓ תשובה: ד) — axios מסווג שגיאות ל-3: (1) error.response מוגדר = שרת ענה עם 4xx/5xx. (2) error.request מוגדר, error.response = undefined = Request יצא אבל ללא תגובה (Timeout/Connection Refused). (3) שניהם undefined = שגיאה בהגדרת ה-Request עצמו.
שאלה 3.3 — Dry Run: requests
import requests r = requests.get('https://api.github.com/users/torvalds', timeout=10) data = r.json() print(data.get('public_repos', 0)) print(type(data['login']))מה יודפס (בהנחה שהAPI עובד)?
✓ תשובה: ג) — r.json() מחזיר dict. data.get('public_repos', 0) = מחזיר את הערך (מספר repos) או 0 אם לא קיים. data['login'] = שם המשתמש כ-string. type(str) = <class 'str'>. שים לב: ב-JSON, numbers → Python int, strings → Python str.
// פרק 4

קריאת C Header + Mindset מקצועי בסדנה

בסדנה אפשר לקבל ספרייה ב-C עם Header File בלבד — אין Docs, אין README. הכישרון לקרוא .h ולהסיק API הוא מיומנות RE בסיסית.

// ─── mysterylib.h — ספרייה לא מוכרת ──────────────────── typedef struct { int id; char name[64]; float score; } Record; // Initialize the library. Call before any other function. // Returns: 0 on success, -1 on error int mystery_init(const char *config_path); // Create a new record. name: max 63 chars. score: 0.0-100.0 // Returns: pointer to Record, or NULL on failure Record* mystery_create(const char *name, float score); // Fetch record by ID. Returns NULL if not found. Record* mystery_get(int id); // Save all records to disk. // Returns: number of records saved, or -1 on error int mystery_save(const char *filepath); // Free all resources. Call at end. void mystery_cleanup(void); // ─── ניתוח ה-Header: מה מסיקים? ────────────────────────── // 1. struct Record: id (auto), name (max 63!), score (0-100) // 2. Flow חובה: init() → create()/get() → save() → cleanup() // 3. Error: return -1 / NULL על כישלון — תמיד בדוק! // 4. init() קודם לכל — בלי זה כולם ייכשלו // 5. mystery_create: לא malloc עצמנו — הספרייה מנהלת זיכרון // ─── שימוש נכון ─────────────────────────────────────────── if (mystery_init(NULL) != 0) { return 1; } // תמיד בדוק! Record *r = mystery_create("Alice", 95.5f); if (!r) { mystery_cleanup(); return 1; } // NULL check! printf("id=%d name=%s score=%.1f\n", r->id, r->name, r->score); int saved = mystery_save("output.dat"); mystery_cleanup(); // תמיד בסוף!

Mindset מקצועי בסדנה

מצבתגובה שגויה ❌תגובה נכונה ✅
לא יודע את הספרייה'אני לא יכול לעשות את זה''אני מתחיל ב-README / dir()'
שגיאה לא מובנתפאניקה, מחיקת כל הקודקרא Error בקפידה, חפש GitHub Issues
תקוע 5 דקותשתיקה, ויתורחזור ל-Example, שנה גישה, דבר למלווה
הזמן עומד לפוגמנסה לגמור הכל ושובר80% עובד מוצג > 100% שבור
💬 המשפטים שמרשימים בוחן
"אני לא מכיר את הספרייה הזו — אבל הנה הflow שאני מניח, אנסה"
"קיבלתי Error, זה אומר שהParameter מצפה לtype אחר"
"הגעתי עד לנקודה X, החלק Y לא הספקתי — הנה הפתרון החלקי"
"שאלתי Stack Overflow על השגיאה הזו ומצאתי ש..."

המשפטים שמכשילים: 'לא יודע', 'לא מבין', 'אי אפשר' — בלי הסבר!
✏תרגול עצמי3 שאלות
שאלה 4.1 — קריאת C Header
ב-Header רואים: int db_connect(const char *host, int port, int timeout_ms);. מה אפשר להסיק על Error Handling?
✓ תשובה: א) — C Convention סטנדרטי: int return value שלילי (-1) = כישלון, 0 = הצלחה (או ID חיובי). const char *host = input בלבד (const). timeout_ms = timeout במילישניות. תמיד בדוק return value ב-C — אין Exception mechanism אוטומטי. זה נלמד מקריאת Header בלבד!
שאלה 4.2 — Mindset
אתה בסדנה, נתנו לך ספרייה ב-C. כתבת קוד שעובד 80% — חלק אחד נשבר. נותרות 3 דקות. מה עושים?
✓ תשובה: א) — 80% עובד + הסבר ברור > 100% שבור. הבוחן מעריך: (1) מה הצלחת לממש. (2) האם אתה מבין מה חסר. (3) האם יש לך תכנית לפתרון. מחיקה ב-3 דקות האחרונות = אסון. שתיקה = לא מראה מה ידעת. דיבור על מה עבד ומה לא = Professional.
שאלה 4.3 — גאמא סגנון: Flow מלא
בסדנה קיבלת Header: void* net_open(const char *url); int net_read(void *conn, char *buf, int size); void net_close(void *conn);. מה ה-Flow הנכון לשימוש?
✓ תשובה: ב) — מה-Header מסיקים: net_open מחזיר void* (handle) → יכול להיות NULL על כישלון → חייב לבדוק. net_read מקבל conn → צריך אחרי open. net_close = cleanup שחייב תמיד לקרות. Pattern קלאסי: init → use → cleanup. אם net_read מחזיר int (bytes read) → לולאה עד 0/-1.
// סימולציית מיון

אתגר מעשי — סדנה תחת לחץ — Security ו-Debug

פורמט מיון אמיתי: מתוזמן, רב-קטגורי, תחת לחץ. בונוס-זמן על פתרון מהיר. ההגשה נבדקת אוטומטית מול מקרי-קצה נסתרים.

T5 · שיא800 נק'~15 דק'algorithmic⏱ בונוס-זמן
Security — ניתוח לוג התחברויות
תחת לחץ זמן: נתחו לוג התחברויות. logs היא רשימת שורות 'IP STATUS' (STATUS = FAIL/OK). החזירו את כתובת ה-IP עם הכי הרבה כשלונות (FAIL). שובר-שוויון: הכתובת הקטנה לקסיקוגרפית. אם אין כשלונות — None.
דוגמאות
top_failed_ip(['1.1.1.1 FAIL','1.1.1.1 FAIL','2.2.2.2 FAIL']) → '1.1.1.1'
הפתרון נשמר מקומית ומשותף עם עמוד „כתיבת קוד”.
פתרון-ייחוס Security — ניתוח לוג התחברויות ›
from collections import Counter def top_failed_ip(logs: list) -> str: c = Counter() for ln in logs: ip, status = ln.split() if status == 'FAIL': c[ip] += 1 if not c: return None mx = max(c.values()) return min(ip for ip, v in c.items() if v == mx) # שובר-שוויון: קטן לקסיקוגרפית
T4 · מתקדם550 נק'~10 דק'debug⏱ בונוס-זמן
Debug מהיר — חיפוש בינארי שבור
חיפוש בינארי זה נכנס ללולאה אינסופית על חלק מהקלטים. מצא ותקן את הבאג במהירות (רמז: עדכון הגבול התחתון). מחזיר אינדקס היעד, או -1 אם לא נמצא.
// הקוד השבור לתיקון
def bsearch(a, t): lo, hi = 0, len(a) - 1 while lo <= hi: mid = (lo + hi) // 2 if a[mid] == t: return mid elif a[mid] < t: lo = mid # באג כאן else: hi = mid - 1 return -1
דוגמאות
bsearch([1,3,5,7,9], 7) → 3
bsearch([1,3,5,7,9], 4) → -1
הפתרון נשמר מקומית ומשותף עם עמוד „כתיבת קוד”.
פתרון-ייחוס Debug מהיר — חיפוש בינארי שבור ›
def bsearch(a: list, t: int) -> int: lo, hi = 0, len(a) - 1 while lo <= hi: mid = (lo + hi) // 2 if a[mid] == t: return mid elif a[mid] < t: lo = mid + 1 # התיקון: mid+1 (היה mid -> לולאה אינסופית) else: hi = mid - 1 return -1
// פרק 5

סיכום + Dry Run גאמא

הנה סיכום השיטות הקריטיות ושאלות מסכמות בסגנון מיון גאמא.

✓מה למדנו בשיעור 48
  • שיטת 5 שלבים: README(5) → Example(5) → API Scan(5) → Implement(15) → Debug(5) = 30 דק׳
  • dir(lib) + help(func) ב-Python = Docs מובנים, עובד גם Offline
  • Traceback: קרא מלמטה למעלה. שורה תחתונה = סוג השגיאה ← זה מה שלתקן
  • requests: r.json(), r.status_code, timeout=10. לא זורק על 4xx/5xx — בדוק ידנית
  • axios: response.data, response.status. זורק Exception על 4xx/5xx. error.response vs error.request
  • C Header: struct = נתונים, Comments = Docs, return -1/NULL = error, init→use→cleanup
  • Mindset: קוד עובד חלקי > קוד שלם שבור. "תקוע כאן, הנה מה שניסיתי" > שתיקה
  • תקוע? → dir(), help(), GitHub Issues, חזור לExample, דבר למלווה
🎯 השיעור הבא
שיעור 49 — סדנת פרזנטציה: סימולציית ראיון מקצועי
✏תרגול סיום — גאמא סגנון3 שאלות
גאמא סגנון א׳ — שיטה בפעולה
בסדנה קיבלת ספרייה Python לא מוכרת ושאלה: 'שלח HTTP GET ל-API וקבל שדה "result"'. אין README. מה 3 הצעדים הראשונים?
✓ תשובה: ד) — ה-3 צעדים: dir() → help() → כתוב. זה ה-API Scan השלב מהשיטה, אבל כשאין README מתחילים ישר בו. תוך 5 דקות יודעים: מה הפונקציות, מה הפרמטרים, מה ה-Return Value. אחר כך ממשים ב-15 דקות.
גאמא סגנון ב׳ — Error Diagnosis
קוד Python מריץ result = api.search("gamma")['hits'][0]['title'] וקורס עם KeyError: 'hits'. מה הבעיה?
✓ תשובה: א) — KeyError: 'hits' = ה-dict שמוחזר לא מכיל את המפתח 'hits'. אולי ה-API משתמש ב-'results' / 'data' / 'items'. תמיד: print(api.search("gamma")) ולראות את מבנה ה-dict האמיתי. לא להניח על שמות מפתחות.
גאמא סגנון ג׳ — C Header: Error Pattern
ב-Header: Record* mystery_create(const char *name, float score);. כתבת: Record *r = mystery_create("Alice", 95.5); ומשתמש ב-r->name. מה החסר הקריטי?
✓ תשובה: א) — Header אומר: "Returns: pointer to Record, or NULL on failure". גישה ל-r->name כשr=NULL = Segmentation Fault ← קריסה מיידית. כלל: כל פונקציה C שמחזירה pointer → תמיד בדוק NULL לפני גישה. (ג) גם נכון אבל לא הסיבה לקריסה כאן.)
שאלות תרגול ותשובות (15)

שאלה 1.1 — שיטת הלמידה · קיבלת ספרייה Python לא מוכרת בסדנה. מה הצעד הראשון?

  • א. לקרוא את כל ה-Documentation הרשמי של הספרייה מההתחלה ועד הסוף
  • ב. לפנות למלווה בסדנה ולבקש ממנו שיסביר בדיוק מה הספרייה עושה
  • ג. import the_lib; print(dir(the_lib)) כדי לחשוף מיד את כל ה-API הזמין
  • ד. להתחיל לכתוב קוד שמנחש את שמות הפונקציות וה-API של הספרייה
תשובה: ג

✓ תשובה: ג) — dir() הוא ה-API Scanner המובנה של Python. תוך שניות רואים רשימת כל הפונקציות והמחלקות. help() נותן documentation מהיר על כל פונקציה — Parameters, Returns, Raises. זה מהיר בהרבה מקריאת Docs חיצוניים, ועובד גם ב-Offline.

שאלה 1.2 — ניהול זמן · אתה תקוע 8 דקות על בעיה בסדנה. מה עושים?

  • א. המשך לנסות עוד ועוד, מפני שקרוב לוודאי שהפתרון כבר ממש קרוב
  • ב. מחק את כל הקוד שכתבת עד כה והתחל את המשימה כולה מחדש מאפס
  • ג. דלג על הסעיף הזה באופן מלא ועבור ישר לסעיף הבא של המשימה
  • ד. שנה גישה: חפש את השגיאה ב-GitHub Issues וחזור לבנות מ-Example בסיסי
תשובה: ד

✓ תשובה: ד) — שתיקה + ויתור = הכישלון הכי גרוע. חיפוש GitHub Issues עם הודעת השגיאה המדויקת נותן לרוב פתרון תוך דקות. חזרה ל-Basic Example ובנייה הדרגתית עליו — Strategy מוכחת. דיבור למלווה מראה יכולת תקשורת ומודעות עצמית, וקלות עוזרת.

שאלה 1.3 — Dry Run: json.loads · import json raw = '{"name": "gamma", "score": 95, "tags": ["cyber", "ctf"]}' data = json.loads(raw) print(type(data)) print(data['tags'][1]) print(data.get('level', 'unknown'))מה הפלט?

import json
raw = '{"name": "gamma", "score": 95, "tags": ["cyber", "ctf"]}'
data = json.loads(raw)
print(type(data))
print(data['tags'][1])
print(data.get('level', 'unknown'))
  • א. dict / cyber / unknown — tags[1] הוא הערך השני ברשימת ה-tags
  • ב. dict / ctf / None — get() מחזיר None כאשר אין ברירת-מחדל מוגדרת
  • ג. <class 'dict'> / ctf / unknown — get() מחזיר ברירת-מחדל למפתח חסר
  • ד. str / ctf / None — json.loads מחזיר מחרוזת גולמית ולא מילון נתונים
תשובה: ג

✓ תשובה: ג) — json.loads() מחזיר Python dict. type(data) = <class 'dict'>. data['tags'] = ["cyber","ctf"]. tags[1] = "ctf" (אינדקס 1). data.get('level', 'unknown'): 'level' לא קיים ב-dict → מחזיר 'unknown'. שים לב: data['level'] היה זורק KeyError!

שאלה 2.1 — זיהוי Error · קיבלת: TypeError: connect() missing 1 required positional argument: 'port'. מה עושים?

TypeError: connect() missing 1 required positional argument: 'port'
  • א. חפש את הטקסט 'TypeError Python' במנוע החיפוש וקווה לפתרון מהיר
  • ב. הסר לחלוטין את השורה שקוראת ל-connect() כדי להיפטר מן השגיאה
  • ג. הסר והתקן מחדש את הספרייה, שכן ייתכן שההתקנה הנוכחית פגומה
  • ד. קרא help(connect) כדי לראות את הפרמטרים הנדרשים ואז תקן את הקריאה
תשובה: ד

✓ תשובה: ד) — ה-Error מספר בדיוק מה חסר: פרמטר 'port'. help(connect) מציג את כל הפרמטרים הנדרשים ואופציונליים. TypeError = טיפוס שגוי או פרמטר חסר — תמיד קרא מה הפונקציה מצפה. ה-Error הוא ה-Doc!

שאלה 2.2 — קריאת Traceback · File 'scanner.py', line 23, in run_scan results = api.scan(target) File '/lib/api.py', line 67, in scan sock.connect((host, port)) ConnectionRefusedError: [Errno 111] Connection refusedמה הבעיה וכיצד לתקן?

File 'scanner.py', line 23, in run_scan
  results = api.scan(target)
File '/lib/api.py', line 67, in scan
  sock.connect((host, port))
ConnectionRefusedError: [Errno 111] Connection refused
  • א. השירות שאליו מנסים להתחבר אינו פועל, או שה-host/port שגויים — בדוק
  • ב. מדובר בשגיאת תחביר (Syntax) בשורה 23 של הקובץ scanner.py שכתבת
  • ג. הספרייה api כלל אינה מותקנת במערכת, ולכן יש להריץ pip install api
  • ד. חסר קובץ המקור lib/api.py שהספרייה מנסה לטעון בזמן הריצה שלה
תשובה: א

✓ תשובה: א) — קוראים מלמטה למעלה: שורה תחתונה = ConnectionRefusedError: Connection refused. זה אומר שמנסים לפתוח TCP connection אבל השרת לא מקשיב. הקוד שלך ב-line 23. לבדוק: target נכון? Port פתוח? אם זה סדנה — האם השרת שלהם רץ? שאל את המלווה.

שאלה 2.3 — AttributeError על None · import requests r = requests.get('https://api.example.com/data') print(r.json()['result']) # שגיאה: AttributeError: 'NoneType' object has no attribute 'json'מה הסיבה ומה התיקון?

import requests
r = requests.get('https://api.example.com/data')
print(r.json()['result'])
# שגיאה: AttributeError: 'NoneType' object has no attribute 'json'
  • א. הספרייה requests אינה מותקנת כלל, ולכן יש להריץ pip install requests
  • ב. ל-Response אין מתודת json(), ולכן צריך להשתמש במקום זאת ב-.text
  • ג. r הוא None (שגיאת רשת או URL שגוי) — בדוק זאת לפני הגישה ל-.json()
  • ד. ה-API החזיר את הקוד 404, ולכן יש לוודא ש-status_code שווה ל-200
תשובה: ג

✓ תשובה: ג) — requests.get() יכול להחזיר None אם יש שגיאת רשת, או לזרוק Exception. ה-AttributeError "NoneType has no attribute 'json'" = r היא None. תיקון: if r and r.status_code == 200: data = r.json(). תמיד בדוק None ו-status_code לפני שימוש ב-Response.

שאלה 3.1 — requests vs axios · ב-requests (Python) קיבלת Response עם status_code=404. האם נזרקה Exception?

  • א. כן — הספרייה requests זורקת Exception על כל שגיאת HTTP שמתקבלת
  • ב. לא — requests אינו זורק Exception על 4xx/5xx; יש לבדוק status_code ידנית
  • ג. כן — הקוד 404 תמיד גורם לזריקת חריגה מסוג FileNotFoundError
  • ד. זה תלוי לחלוטין בגרסה הספציפית של הספרייה requests המותקנת אצלך
תשובה: ב

✓ תשובה: ב) — ההבדל המרכזי בין requests לaxios: axios זורק Exception על 4xx/5xx (ל-catch ב-try-catch). requests לא — הוא מחזיר Response עם status_code=404 ומצפה שתבדוק. אפשר להפעיל r.raise_for_status() כדי שrequests יזרוק Exception על שגיאות HTTP.

שאלה 3.2 — axios error types · ב-axios קיבלת Exception בtry-catch. error.response הוא undefined. מה זה אומר?

error.response
  • א. השרת קיבל את הבקשה והחזיר עליה שגיאת שרת פנימית מסוג 500
  • ב. הבקשה עצמה כלל לא נשלחה מהדפדפן אל השרת בשל שגיאה מוקדמת
  • ג. ה-JSON שהתקבל בגוף התגובה אינו תקין, ולכן הפענוח שלו נכשל
  • ד. הבקשה נשלחה אך לא התקבלה תגובה — זו שגיאת רשת (Timeout או DNS)
תשובה: ד

✓ תשובה: ד) — axios מסווג שגיאות ל-3: (1) error.response מוגדר = שרת ענה עם 4xx/5xx. (2) error.request מוגדר, error.response = undefined = Request יצא אבל ללא תגובה (Timeout/Connection Refused). (3) שניהם undefined = שגיאה בהגדרת ה-Request עצמו.

שאלה 3.3 — Dry Run: requests · import requests r = requests.get('https://api.github.com/users/torvalds', timeout=10) data = r.json() print(data.get('public_repos', 0)) print(type(data['login']))מה יודפס (בהנחה שהAPI עובד)?

import requests
r = requests.get('https://api.github.com/users/torvalds',
                  timeout=10)
data = r.json()
print(data.get('public_repos', 0))
print(type(data['login']))
  • א. שגיאת KeyError, מכיוון שהמפתח 'public_repos' כלל אינו קיים ב-JSON
  • ב. הערך 0 ולאחריו <class 'int'>, מכיוון ש-login מוחזר כמספר שלם
  • ג. מספר כלשהו ואז <class 'str'> — public_repos הוא int ו-login מחרוזת
  • ד. הערך None ולאחריו <class 'dict'>, מכיוון ש-data הוא מילון מקונן
תשובה: ג

✓ תשובה: ג) — r.json() מחזיר dict. data.get('public_repos', 0) = מחזיר את הערך (מספר repos) או 0 אם לא קיים. data['login'] = שם המשתמש כ-string. type(str) = <class 'str'>. שים לב: ב-JSON, numbers → Python int, strings → Python str.

שאלה 4.1 — קריאת C Header · ב-Header רואים: int db_connect(const char *host, int port, int timeout_ms);. מה אפשר להסיק על Error Handling?

int db_connect(const char *host, int port, int timeout_ms);
  • א. לפי מוסכמת C: הערך 0 מציין הצלחה ו--1 מציין כישלון — תמיד לבדוק
  • ב. הפונקציה תמיד מצליחה, וערך ה-int המוחזר הוא מזהה החיבור שנוצר
  • ג. הפונקציה זורקת Exception במקרה של כישלון בהתחברות אל השרת
  • ד. ערך ההחזרה מסוג const char* הוא מחרוזת המתארת את פרטי השגיאה
תשובה: א

✓ תשובה: א) — C Convention סטנדרטי: int return value שלילי (-1) = כישלון, 0 = הצלחה (או ID חיובי). const char *host = input בלבד (const). timeout_ms = timeout במילישניות. תמיד בדוק return value ב-C — אין Exception mechanism אוטומטי. זה נלמד מקריאת Header בלבד!

שאלה 4.2 — Mindset · אתה בסדנה, נתנו לך ספרייה ב-C. כתבת קוד שעובד 80% — חלק אחד נשבר. נותרות 3 דקות. מה עושים?

  • א. הצג את מה שעובד והסבר בבירור מה לא הספקת ומה ניסית לעשות בחלק X
  • ב. מחק את כל מה שכתבת עד כה ונסה במהירות פתרון חלופי אחר לגמרי
  • ג. שמור על שתיקה מוחלטת ואל תציג דבר עד שתסיים את כל המשימה
  • ד. בקש מהבוחן הארכת זמן כדי שתוכל להשלים גם את החלק שנשבר לך
תשובה: א

✓ תשובה: א) — 80% עובד + הסבר ברור > 100% שבור. הבוחן מעריך: (1) מה הצלחת לממש. (2) האם אתה מבין מה חסר. (3) האם יש לך תכנית לפתרון. מחיקה ב-3 דקות האחרונות = אסון. שתיקה = לא מראה מה ידעת. דיבור על מה עבד ומה לא = Professional.

שאלה 4.3 — גאמא סגנון: Flow מלא · בסדנה קיבלת Header: void* net_open(const char *url); int net_read(void *conn, char *buf, int size); void net_close(void *conn);. מה ה-Flow הנכון לשימוש?

void* net_open(const char *url); int net_read(void *conn, char *buf, int size); void net_close(void *conn);
  • א. net_read → net_open → net_close: קריאה תחילה ורק אחריה הפתיחה
  • ב. net_open → בדוק NULL → net_read בלולאה → net_close תמיד בסוף
  • ג. net_open → net_read → net_open שוב → net_close בסיום התהליך
  • ד. net_read → net_close → net_open: סגירה עוד לפני פתיחת החיבור
תשובה: ב

✓ תשובה: ב) — מה-Header מסיקים: net_open מחזיר void* (handle) → יכול להיות NULL על כישלון → חייב לבדוק. net_read מקבל conn → צריך אחרי open. net_close = cleanup שחייב תמיד לקרות. Pattern קלאסי: init → use → cleanup. אם net_read מחזיר int (bytes read) → לולאה עד 0/-1.

גאמא סגנון א׳ — שיטה בפעולה · בסדנה קיבלת ספרייה Python לא מוכרת ושאלה: 'שלח HTTP GET ל-API וקבל שדה "result"'. אין README. מה 3 הצעדים הראשונים?

  • א. לחפש במנוע החיפוש, לשאול את המלווה, ואז לחכות בסבלנות לתשובה
  • ב. לכתוב מיד requests.get() ולנחש את שם השדה ואת מבנה התגובה
  • ג. לקרוא מההתחלה ועד הסוף את כל קוד המקור של הספרייה הלא-מוכרת
  • ד. (1) print(dir(lib)) — מה קיים? (2) help(lib.get) — פרמטרים? (3) קוד
תשובה: ד

✓ תשובה: ד) — ה-3 צעדים: dir() → help() → כתוב. זה ה-API Scan השלב מהשיטה, אבל כשאין README מתחילים ישר בו. תוך 5 דקות יודעים: מה הפונקציות, מה הפרמטרים, מה ה-Return Value. אחר כך ממשים ב-15 דקות.

גאמא סגנון ב׳ — Error Diagnosis · קוד Python מריץ result = api.search("gamma")['hits'][0]['title'] וקורס עם KeyError: 'hits'. מה הבעיה?

result = api.search("gamma")['hits'][0]['title']
  • א. ה-dict שמחזירה api.search() אינו מכיל את המפתח 'hits' — בדוק את keys()
  • ב. הספרייה כלל אינה מותקנת, ולכן הקריאה ל-api.search נכשלת באופן מיידי
  • ג. מדובר ב-IndexError, מכיוון שאין איבר כלל במקום ה-0 של הרשימה
  • ד. המתודה search() מחזירה את הערך None ולא מילון של תוצאות חיפוש
תשובה: א

✓ תשובה: א) — KeyError: 'hits' = ה-dict שמוחזר לא מכיל את המפתח 'hits'. אולי ה-API משתמש ב-'results' / 'data' / 'items'. תמיד: print(api.search("gamma")) ולראות את מבנה ה-dict האמיתי. לא להניח על שמות מפתחות.

גאמא סגנון ג׳ — C Header: Error Pattern · ב-Header: Record* mystery_create(const char *name, float score);. כתבת: Record *r = mystery_create("Alice", 95.5); ומשתמש ב-r->name. מה החסר הקריטי?

Record* mystery_create(const char *name, float score);
  • א. לא בדקת ש-r אינו NULL לפני הגישה אליו — הדבר עלול לגרום ל-Crash
  • ב. הערך 95.5 חייב היה להיכתב כ-95.5f כדי להיות literal מסוג float
  • ג. היה צורך לקרוא תחילה לפונקציית mystery_init() עוד לפני היצירה
  • ד. היה צורך להקצות זיכרון עם malloc עוד לפני הקריאה ל-create
תשובה: א

✓ תשובה: א) — Header אומר: "Returns: pointer to Record, or NULL on failure". גישה ל-r->name כשr=NULL = Segmentation Fault ← קריסה מיידית. כלל: כל פונקציה C שמחזירה pointer → תמיד בדוק NULL לפני גישה. (ג) גם נכון אבל לא הסיבה לקריסה כאן.)