# איך מחשב עובד: רכיבים, הרצת תוכנה ושפות תכנות<no value>

## מה בשיעור

השיעור הזה בנוי מכמה פרקים קצרים, באותו סדר כמו במצגת:

1. **פרק ראשון** — רכיבי המחשב: CPU, RAM, Storage ו-Registers
2. **פרק שני** — מה קורה מהרגע שמפעילים תוכנה ועד שהיא רצה
3. **פרק שלישי** — סוגי שפות תכנות: מקוד מכונה ועד Python

## פרק ראשון: רכיבי המחשב: CPU, RAM, Storage ו-Registers

### מה נלמד?

נפתח את "מכסה המחשב" ונכיר ארבעה רכיבים שכל מתכנת צריך להבין:

| רכיב | בשורה אחת |
|---|---|
| **CPU** | המוח — מבצע את ההוראות. |
| **Registers** | תאי זיכרון זעירים ומהירים במיוחד, **בתוך** ה-CPU. |
| **RAM** | שולחן העבודה — זיכרון מהיר וזמני לתוכנות שרצות עכשיו. |
| **Storage** | הארכיון — אחסון קבוע לקבצים, גם כשהמחשב כבוי. |

### למה צריך את זה?

כל שורת קוד שתכתבו בקורס עוברת דרך הרכיבים האלה. כשתבינו אותם, תבינו גם דברים שנראים כרגע "קסם":

- למה משתנה נעלם כשהתוכנית נגמרת, אבל קובץ נשאר?
- למה תוכנית שקוראת מהדיסק איטית יותר מתוכנית שעובדת רק בזיכרון?
- למה המחשב "נתקע" כשפותחים יותר מדי תוכנות?
- בנושא Backend ומסדי נתונים, למה שומרים מידע ב-**Database** (על Storage) ולא סתם במשתנה?

בראיונות עבודה שואלים לעיתים קרובות "מה ההבדל בין RAM ל-Storage" — זו שאלה שבודקת אם מבינים את הבסיס.

### הסבר מהבסיס

#### CPU — Central Processing Unit (יחידת העיבוד המרכזית)

ה-**CPU** (נקרא גם "מעבד") הוא הרכיב **שמבצע** הוראות. הוא יודע לבצע רק פעולות פשוטות מאוד: לחבר שני מספרים, להשוות, להעתיק ערך ממקום למקום, לקפוץ להוראה אחרת. הכוח שלו הוא **מהירות**: מיליארדי הוראות בשנייה.

- **Clock Speed** (מהירות שעון), נמדדת ב-GHz: 3 GHz ≈ שלושה מיליארד "פעימות" בשנייה.
- **Core** (ליבה): מעבד מודרני מכיל כמה ליבות, וכל ליבה היא כמו מעבד קטן נפרד. 8 ליבות = 8 דברים במקביל.

**הקשר להרצת תוכנה:** כל שורת Python שכתבתם מתורגמת בסוף להרבה הוראות קטנות, וה-CPU מבצע אותן אחת אחרי השנייה.

#### Registers — האוגרים

**Registers** הם תאי זיכרון זעירים (כל אחד מחזיק מספר אחד) **בתוך ה-CPU עצמו**. זה הזיכרון המהיר ביותר שיש במחשב. כדי לחבר שני מספרים, ה-CPU קודם מביא אותם מה-RAM לתוך Registers, מחשב, ושומר את התוצאה ב-Register.

יש במעבד מעט מאוד Registers (עשרות בודדות), ולכן הם מחזיקים רק את מה שה-CPU עובד עליו **ברגע זה**. ב-Python לא ניגשים ל-Registers ישירות. ה-Interpreter ומערכת ההפעלה דואגים לזה, אבל חשוב לדעת שהם קיימים.

#### RAM — Random Access Memory (זיכרון גישה אקראית)

**RAM** הוא הזיכרון שבו נמצאות **התוכנות שרצות עכשיו והנתונים שלהן**. כשאתם כותבים `name = "Dana"`, הערך `"Dana"` נשמר ב-RAM.

שתי תכונות חשובות:

1. **מהיר** — הרבה יותר מ-Storage (פי אלפים).
2. **זמני (Volatile)** — כשהתוכנית נגמרת או שהמחשב נכבה, התוכן נמחק.

#### Storage — אחסון קבוע

**Storage** הוא הדיסק: **SSD** (מהיר, בלי חלקים נעים) או **HDD** (דיסק מסתובב, ישן ואיטי). כאן שמורים מערכת ההפעלה, התוכנות המותקנות וכל הקבצים שלכם, כולל `hello.py`.

1. **קבוע (Non-volatile)** — המידע נשאר גם כשהמחשב כבוי.
2. **גדול וזול** — מאות GB עד TB, לעומת 8–32 GB של RAM.
3. **איטי** יחסית ל-RAM.

{{< box "analogy" "אנלוגיית המטבח" >}}
- **Storage** = המזווה: מחזיק המון, הכול נשמר לאורך זמן, אבל צריך ללכת להביא משם.
- **RAM** = משטח העבודה במטבח: מניחים עליו רק את מה שמבשלים עכשיו. נוח ומהיר, אבל בסוף היום מפנים אותו.
- **Registers** = הידיים של הטבח: מחזיקות רק את הדבר שעובדים עליו ברגע זה.
- **CPU** = הטבח עצמו: מבצע את הפעולות (חותך, מערבב, מחשב).
{{< /box >}}

#### למה לא להסתפק ברכיב אחד?

| | Registers | RAM | Storage |
|---|---|---|---|
| מהירות | הכי מהיר | מהיר | איטי יחסית |
| גודל | זעיר (בתים) | בינוני (GB) | ענק (מאות GB–TB) |
| נשמר אחרי כיבוי? | לא | לא | **כן** |
| מחיר לכל GB | יקר מאוד | יקר | זול |

אין רכיב שהוא גם מהיר מאוד, גם ענק, גם זול וגם קבוע. לכן המחשב משלב את כולם: מה שצריך **עכשיו** מוחזק קרוב ל-CPU, ומה שצריך **לאורך זמן** — על הדיסק.

### לקרוא מפרט של מחשב

כל מה שלמדנו מופיע במפרט של כל מחשב — בחנות, באתר של היצרן, או ב-Task Manager. מפרט טיפוסי של לפטופ:

```text
CPU       8 cores, 3.2 GHz
RAM       16 GB       (temporary)
Storage   512 GB SSD  (permanent)
OS        Windows 11, 64-bit (x64)
```

| שורה | מה היא אומרת |
|---|---|
| `8 cores` | שמונה ליבות — עד שמונה דברים שה-CPU מבצע באמת במקביל. |
| `3.2 GHz` | קצב השעון — כ-3.2 מיליארד פעימות בשנייה. |
| `16 GB` RAM | כמה מקום יש לתוכנות שרצות **עכשיו** ולנתונים שלהן. |
| `512 GB SSD` | כמה קבצים ותוכנות אפשר לשמור **לאורך זמן**. |
| `64-bit (x64)` | הארכיטקטורה — "שפת ההוראות" שהמעבד מבין. |

את אותם נתונים אפשר לראות במחשב עצמו: ב-Windows ב-**Task Manager** (`Ctrl + Shift + Esc`) → **Performance**, ובמק ב-**Activity Monitor**. שם רואים גם בזמן אמת כמה RAM תפוס, ואיך הוא עולה כשפותחים עוד ועוד תוכנות.

### RAM מול Storage בפועל

| | RAM | Storage |
|---|---|---|
| מה נמצא שם | תוכנות שרצות עכשיו והנתונים שלהן | קבצים, תוכנות מותקנות, מערכת ההפעלה |
| מהירות | מהיר מאוד | איטי יותר |
| גודל טיפוסי | 8–32 GB | מאות GB עד TB |
| כשהתוכנית נגמרת או שהמחשב נכבה | **נמחק** | **נשאר** |

**הקשר לתכנות:** כל **משתנה** שתכתבו בתוכנית חי ב-**RAM**. בכל הרצה התוכנית מקבלת זיכרון חדש וריק, וכשהיא מסתיימת — הזיכרון משתחרר והערכים נעלמים. לכן מונה שסופר בתוך תוכנית "מתחיל מאפס" בכל הרצה מחדש.

מה שצריך **להישאר** — רשימת סטודנטים, הזמנות, ציונים — חייב להיכתב ל-**Storage**: לקובץ, או למסד נתונים. נלמד את שתי הדרכים בהמשך הקורס.

### טעות נפוצה

**הטעות — "הוספתי RAM והמחשב ישמור יותר קבצים"**, או ההפך: "יש לי 1TB דיסק אז לא חסר לי זיכרון".

אלה שני משאבים שונים:

- **מעט RAM** ‏←‏ המחשב איטי כשהרבה תוכנות פתוחות. מערכת ההפעלה מתחילה להעביר חלקים מה-RAM לדיסק (נקרא **Swap** / Page File), והדיסק איטי.
- **מעט Storage** ‏←‏ אין מקום לשמור קבצים ולהתקין תוכנות.

**טעות שנייה — "שמרתי", אבל רק ב-RAM.** תוכנה מציגה הודעה "נשמר!", אבל בפועל המידע נמצא רק במשתנה, כלומר ב-RAM. כל עוד התוכנית רצה — הכול נראה תקין. כשהיא נסגרת או שהמחשב נכבה — הנתונים נעלמים. שמירה אמיתית היא תמיד **כתיבה ל-Storage**.

### סיכום

- **CPU** מבצע הוראות. **Cores** מאפשרות ביצוע במקביל, ו-**GHz** מודדים את קצב הפעימות.
- **Registers** הם הזיכרון הזעיר והמהיר ביותר, **בתוך** ה-CPU, ומחזיקים את מה שמחושב ברגע זה.
- **RAM** מהיר וזמני: משתנים חיים בו ונעלמים בסוף התוכנית.
- **Storage** (SSD/HDD) איטי יותר אבל קבוע: קבצים נשארים גם אחרי כיבוי.
- כדי ששמירה תשרוד, צריך לכתוב ל-**Storage** (קובץ / Database).

<!-- docs:start — generated by scripts/intro6/site_docs.py; edit the links there -->

### דוקומנטציה רשמית

- [Windows — Memory Management](https://learn.microsoft.com/en-us/windows/win32/memory/memory-management) — RAM, זיכרון וירטואלי ואיך תוכנות מקבלות זיכרון
- [Windows — About Memory Management](https://learn.microsoft.com/en-us/windows/win32/memory/about-memory-management) — איך מערכת ההפעלה מנהלת את הזיכרון

<!-- docs:end -->

## פרק שני: מה קורה מהרגע שמפעילים תוכנה ועד שהיא רצה

### מה נלמד?

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

### למה צריך את זה?

- כשתוכנית "לא עולה", תדעו לשאול **באיזה שלב** היא נכשלה: הקובץ לא נמצא? אין הרשאה? חסר זיכרון?
- כשמדברים בנושא Python על **Runtime Error** (שגיאה בזמן ריצה) לעומת **Syntax Error** (שגיאת תחביר), ההבדל נובע בדיוק מהשלבים שנלמד כאן.
- בנושא Backend ומסדי נתונים נריץ **שרת**, תוכנה שלא נגמרת אלא ממשיכה לרוץ ולחכות לבקשות. כדי להבין את זה צריך להבין קודם מהי תוכנה רצה.

### הסבר מהבסיס

#### תוכנה שמורה לעומת תוכנה רצה

**תוכנה** (Program) שלא רצה היא סתם **קובץ על הדיסק** — רצף של בתים ב-Storage. כדי שהיא "תעשה" משהו, צריך לטעון אותה ל-RAM ולתת ל-CPU לבצע את ההוראות שבה. תוכנה בזמן ריצה נקראת **Process** (תהליך). ההבחנה הזו חשובה מאוד, ונעמיק בה מחר.

#### המסלול הכללי — 6 שלבים

1. **בקשה** — המשתמש לוחץ פעמיים על אייקון, או כותב פקודה ב-Terminal.
2. **איתור** — **מערכת ההפעלה** (Operating System) מחפשת את קובץ התוכנה על ה-Storage.
3. **בדיקת הרשאות** — מערכת ההפעלה בודקת שמותר למשתמש הזה להריץ את הקובץ.
4. **יצירת Process** — מערכת ההפעלה רושמת תהליך חדש, נותנת לו מספר מזהה (**PID** — Process ID) ומקצה לו אזור זיכרון משלו ב-RAM.
5. **טעינה ל-RAM** — מערכת ההפעלה מעתיקה את הוראות התוכנה מהדיסק לאזור הזיכרון של התהליך, ומכניסה אותו לתור של ה-CPU.
6. **ביצוע** — ה-CPU מתחיל לבצע את ההוראות, אחת אחרי השנייה, במחזור שנקרא **Fetch → Decode → Execute**.

#### מחזור Fetch → Decode → Execute

זה ה"דופק" של כל מחשב. ה-CPU חוזר עליו מיליארדי פעמים בשנייה:

| שלב | מה קורה | איזה רכיב |
|---|---|---|
| **Fetch** (הבאה) | ה-CPU מביא מה-RAM את ההוראה הבאה. Register מיוחד (Program Counter) זוכר איפה הוא עומד. | RAM → Registers |
| **Decode** (פענוח) | ה-CPU מבין איזו הוראה זו: חיבור? השוואה? העתקה? | CPU |
| **Execute** (ביצוע) | ה-CPU מבצע אותה. התוצאה נשמרת ב-Register, ואם צריך — חוזרת ל-RAM. | CPU, Registers, RAM |

{{< box "analogy" "אנלוגיה" >}}
טבח עם מתכון: **Fetch** — קורא את השורה הבאה במתכון. **Decode** — מבין שכתוב "לקצוץ בצל". **Execute** — קוצץ. ואז עובר לשורה הבאה. המתכון (התוכנה) מונח על משטח העבודה (RAM), והטבח (CPU) מחזיק בידיים (Registers) רק את מה שהוא עובד עליו עכשיו.
{{< /box >}}

#### ומה קורה עם Python?

ה-CPU לא מבין Python. הוא מבין רק **שפת מכונה** (Machine Code) של הארכיטקטורה שלו. אז מה קורה כשכותבים `python hello.py`?

1. מערכת ההפעלה מוצאת את התוכנה `python` (קובץ `python.exe` ב-Windows), יוצרת **Process** וטוענת אליו את התוכנה. מה שרץ על ה-CPU הוא **ה-Interpreter**, שהוא בעצמו תוכנה בשפת מכונה.
2. ה-Interpreter קורא את `hello.py` מהדיסק.
3. הוא **בודק תחביר** ו**מתרגם** (Compile) את כל הקובץ לשפת ביניים פשוטה שנקראת **Bytecode**. אם יש שגיאת תחביר, התהליך נעצר כאן, **לפני ששורה אחת רצה**.
4. ה-**PVM** (Python Virtual Machine), החלק ב-Interpreter שמבצע Bytecode, עובר על ההוראות אחת אחרי השנייה ומבצע אותן. אם שורה מסוימת נכשלת (למשל חלוקה באפס), נוצרת שגיאה **בזמן ריצה**, ושורות שכבר רצו — רצו.
5. כשהקוד נגמר, ה-Process מסתיים ומערכת ההפעלה משחררת את ה-RAM שלו.

```text
hello.py (Storage)
   │  python reads the file
   ▼
Syntax check + compile  ──►  Bytecode  (in RAM)
   │
   ▼
PVM executes bytecode instruction by instruction
   │  each instruction = many machine instructions
   ▼
CPU: Fetch → Decode → Execute (billions per second)
```

### כל הרצה היא תהליך חדש

כשמריצים את אותו קובץ שלוש פעמים, מערכת ההפעלה יוצרת **שלושה תהליכים שונים** — כל אחד עם **PID** (מזהה תהליך) משלו ועם אזור זיכרון חדש:

```text
python hello.py   ->  new Process, PID 14872
python hello.py   ->  new Process, PID 9316
python hello.py   ->  new Process, PID 20480
```

ה-**Program** (הקובץ `hello.py`) לא השתנה. כל **Process** הוא הרצה נפרדת שלו, שנולדת, רצה ונעלמת. אפשר לראות את זה בעיניים ב-Task Manager: תהליך בשם `python` מופיע בזמן שהתוכנית רצה, ונעלם כשהיא מסתיימת.

### טעות נפוצה

**הטעות: לחשוב שכל השגיאות קורות באותו רגע.** יש שני רגעים שונים לגמרי:

```text
print("Line 1 runs?")
print("Line 3"
→ SyntaxError: '(' was never closed
  (nothing runs at all)

print("Line 1 runs")
print(10 / 0)
→ Line 1 runs
→ ZeroDivisionError: division by zero
```

- **SyntaxError** נתפסת בשלב **בדיקת התחביר**, לפני שנוצר Bytecode — ולכן **אף שורה לא רצה**, גם לא הראשונה.
- **ZeroDivisionError** היא שגיאת **זמן ריצה** — ה-PVM כבר ביצע את השורות שלפניה, ונעצר רק כשהגיע לשורה הבעייתית.

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

### סיכום

- תוכנה על הדיסק היא סתם קובץ. כשהיא רצה, היא **Process** עם **PID** משלה ואזור ב-RAM.
- מערכת ההפעלה מוצאת את הקובץ, בודקת הרשאות, יוצרת Process וטוענת את התוכנה לזיכרון שלו ב-RAM.
- ה-CPU מבצע הוראות במחזור **Fetch → Decode → Execute**, בעזרת Registers.
- ב-Python: הקוד נבדק ומתורגם ל-**Bytecode**, ואז ה-**PVM** מבצע אותו.
- **Syntax Error** עוצרת לפני שורה ראשונה. **Runtime Error** עוצרת באמצע, אחרי ששורות קודמות כבר רצו.

<!-- docs:start — generated by scripts/intro6/site_docs.py; edit the links there -->

### דוקומנטציה רשמית

- [Windows — About Processes and Threads](https://learn.microsoft.com/en-us/windows/win32/procthread/about-processes-and-threads) — מתוכנית לתהליך שרץ
- [Python Glossary — bytecode](https://docs.python.org/3/glossary.html#term-bytecode) — מה Python עושה עם הקובץ לפני שהיא מריצה אותו

<!-- docs:end -->

## פרק שלישי: סוגי שפות תכנות: מקוד מכונה ועד Python

### מה נלמד?

בפרק הקודם ראינו שה-CPU מבצע הוראות במחזור Fetch → Decode → Execute. היום נשאל: **מאיפה מגיעות ההוראות האלה?** נלמד:

- מה זה **קוד מכונה** (Machine Code) ולמה אף אחד לא כותב בו.
- מה ההבדל בין שפות **Low-level** לשפות **High-level**.
- שתי הדרכים לתרגם קוד להוראות: **Compiler** ו-**Interpreter**.
- איפה **Python** נמצאת, ולמה בחרנו בה לקורס.

### למה צריך את זה?

כשמתחילים לתכנת, שומעים כל הזמן משפטים כמו "C מהירה", "Python איטית", "JavaScript רצה בדפדפן" או "צריך לקמפל את זה". בלי להבין **איך** קוד הופך להוראות שה-CPU מבצע, המשפטים האלה נשמעים כמו קסם.

ההבנה הזו עוזרת גם בפועל:

- להבין **למה** Python מוצאת שגיאת תחביר עוד לפני שהקוד רץ, אבל שגיאות אחרות רק באמצע הריצה.
- לבחור את הכלי הנכון למשימה — ולהבין למה חברות משתמשות בכמה שפות במקביל.
- לענות על שאלה קלאסית בראיונות עבודה: "מה ההבדל בין Compiled ל-Interpreted?"

### הסבר מהבסיס

#### מה ה-CPU באמת מבין

המעבד מבין רק **הוראות בינאריות** — רצפים של אפסים ואחדים. כל הוראה היא פעולה קטנה מאוד: "העתק מספר לתא הזה", "חבר שני מספרים", "קפוץ לכתובת אחרת". זה נקרא **קוד מכונה** (Machine Code).

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

**שפת תכנות** היא גשר: אנחנו כותבים בשפה שנוחה לנו, ותוכנה מיוחדת מתרגמת אותה להוראות שה-CPU מבין.

#### Low-level מול High-level

אותה פעולה — לשמור את האות `a` — בכמה רמות:

```text
Machine Code   10110000 01100001
Assembly       MOV AL, 61h
C              char c = 'a';
Python         c = "a"
```

- **Low-level** (שפה ברמה נמוכה) — קרובה למכונה. שולטים בכל פרט: בזיכרון, ברגיסטרים, בכל הוראה. מהיר מאוד, אבל קשה לכתוב וקל לטעות. דוגמאות: Assembly, ובמידה רבה גם C.
- **High-level** (שפה ברמה גבוהה) — קרובה לשפה של בני אדם. השפה דואגת לפרטים בשבילנו: ניהול זיכרון, סוגי נתונים, רשימות ומילונים מוכנים. קל לכתוב ולקרוא, ובדרך כלל איטי יותר בזמן ריצה. דוגמאות: Python, JavaScript, Java.

#### Compiled — מתרגמים הכול מראש

ב**שפה מקומפלת** תוכנה בשם **Compiler** (מהדר) קוראת את כל הקוד **לפני** ההרצה, בודקת אותו, ומתרגמת אותו לקובץ הרצה בקוד מכונה. אחר כך מריצים את הקובץ הזה — כמה פעמים שרוצים, בלי לתרגם שוב.

```text
Compiled (C, Go, Rust):
  source code -> compiler -> program.exe -> run
  translate once, run many times
```

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

#### Interpreted — מתרגמים בזמן ההרצה

ב**שפה מפורשת** תוכנה בשם **Interpreter** (מפרש) קוראת את הקוד **בזמן ההרצה**, ומבצעת אותו תוך כדי תרגום.

```text
Interpreted (Python, JavaScript):
  source code -> interpreter -> run, line by line
  translate every time you run
```

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

{{< box "analogy" "אנלוגיה: ספר מתורגם מול מתורגמן" >}}
**Compiler** הוא כמו מתרגם שמתרגם ספר שלם לעברית לפני שהוא יוצא לחנויות. לוקח זמן, אבל אחר כך כל קורא פשוט קורא — מהר.

**Interpreter** הוא כמו מתורגמן סימולטני בהרצאה: מתרגם משפט אחרי משפט, בזמן אמת. אין המתנה מראש, אבל כל הרצאה דורשת מתורגמן מחדש.
{{< /box >}}

#### שפות מוכרות ומה עושים איתן

| שפה | רמה | בעיקר משמשת ל... |
|---|---|---|
| **Python** | High-level, מפורשת | נתונים, בינה מלאכותית, שרתים, אוטומציה |
| **JavaScript** | High-level, מפורשת | אתרים — בדפדפן ובשרת |
| **Java / C#** | High-level, מקומפלת לשלב ביניים | מערכות גדולות בארגונים, אפליקציות |
| **C / C++** | Low-level יחסית, מקומפלת | מערכות הפעלה, משחקים, חומרה |

#### ואיפה Python נמצאת?

Python היא שפה **High-level** ו**מפורשת**. אבל מאחורי הקלעים יש שלב ביניים, כמו שראינו בפרק הקודם:

1. Python קוראת את כל הקובץ ובודקת תחביר — לכן **SyntaxError** עוצר הכול לפני שורה ראשונה.
2. היא מתרגמת את הקוד ל-**Bytecode** — הוראות ביניים פשוטות.
3. ה-**PVM** (Python Virtual Machine) מריץ את ה-Bytecode הוראה אחרי הוראה — ושגיאות כמו **ZeroDivisionError** מתגלות רק כשמגיעים לשורה.

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

### טעות נפוצה

**"איזו שפה הכי טובה?"** — זו שאלה בלי תשובה.

- **אין שפה הכי טובה — יש שפה שמתאימה למשימה.** משחק תלת-ממד צריך מהירות של C++; ניתוח נתונים צריך את הספריות של Python; אתר צריך JavaScript.
- שפה שמהירה בזמן ריצה בדרך כלל איטית יותר לכתיבה, ולהפך.
- **הרעיונות עוברים בין שפות:** משתנים, תנאים, לולאות, פונקציות ואובייקטים קיימים כמעט בכל שפה. מי שלמד שפה אחת היטב — לומד את הבאה הרבה יותר מהר.

טעות נוספת: לחשוב ש"מפורשת" אומר "לא בודקת כלום מראש". Python כן בודקת את התחביר של כל הקובץ לפני הריצה — היא פשוט לא מייצרת קובץ הרצה נפרד.

### סיכום

- ה-CPU מבין רק **קוד מכונה** — אפסים ואחדים. שפת תכנות היא גשר בינינו לבינו.
- **Low-level** — קרובה למכונה, מהירה וקשה. **High-level** — קרובה לאדם, קריאה ונוחה.
- **Compiler** מתרגם הכול מראש לקובץ הרצה — ריצה מהירה. **Interpreter** מתרגם בזמן ההרצה — פיתוח נוח.
- **Python** היא High-level, מפורשת ודינמית, עם שלב **Bytecode** שה-**PVM** מריץ.
- אין שפה הכי טובה — יש שפה שמתאימה למשימה, והרעיונות עוברים בין שפות.

<!-- docs:start — generated by scripts/intro6/site_docs.py; edit the links there -->

### דוקומנטציה רשמית

- [Python FAQ — What is Python?](https://docs.python.org/3/faq/general.html#what-is-python) — איפה Python נמצאת בין השפות
- [Python Glossary — interpreted](https://docs.python.org/3/glossary.html#term-interpreted) — שפה מפורשת מול שפה מקומפלת

<!-- docs:end -->

<!-- exercises:start — generated by scripts/intro6/sync_site_exercises.py; edit scripts/intro6/exercises/ -->
## תרגול

שאלות הבנה על החומר של השיעור — בלי קוד.

### תרגיל 1: איזה רכיב?

לכל תיאור — איזה רכיב מתאים: CPU, Registers, RAM או Storage?

1. נמחק כשהמחשב נכבה, ובו נמצאים המשתנים של תוכנית שרצה.
2. מבצע מיליארדי הוראות בשנייה.
3. שומר את הקבצים גם כשאין חשמל.
4. תאי זיכרון זעירים ומהירים ביותר, בתוך המעבד.

{{< solution >}}
1. **RAM** — זיכרון זמני ומהיר (Volatile).
2. **CPU** — המעבד, שמבצע את ההוראות.
3. **Storage** (SSD/HDD) — אחסון קבוע (Non-volatile).
4. **Registers** — מחזיקים את מה שה-CPU עובד עליו ברגע זה.
{{< /solution >}}

### תרגיל 2: לקרוא מפרט

זה המפרט של לפטופ:

```text
CPU       8 cores, 3.2 GHz
RAM       16 GB
Storage   512 GB SSD
```

1. מה המשמעות של `8 cores`?
2. דני אומר: "יש לי 512 GB, אז אני יכול לפתוח כמה תוכנות שאני רוצה בלי שהמחשב יאט". מה הטעות?

{{< solution >}}
1. **שמונה ליבות** — עד שמונה דברים שה-CPU מבצע באמת במקביל.
2. ה-512 GB הם **Storage** — מקום לשמור קבצים. התוכנות שרצות עכשיו נמצאות ב-**RAM**, ובו יש רק 16 GB. כשה-RAM מתמלא, מערכת ההפעלה מעבירה חלקים לדיסק (Swap), והמחשב מאט.
{{< /solution >}}

### תרגיל 3: המסלול מקובץ לתהליך

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

- (א) מערכת ההפעלה יוצרת תהליך (Process) חדש, עם PID ואזור זיכרון משלו
- (ב) מערכת ההפעלה מוצאת את קובץ התוכנה על הדיסק (Storage)
- (ג) ה-CPU מבצע את ההוראות של התוכנה, אחת אחרי השנייה (Fetch, Decode, Execute)
- (ד) מערכת ההפעלה טוענת את הוראות התוכנה מהדיסק לאזור הזיכרון של התהליך ב-RAM

{{< solution >}}
הסדר: **(ב), (א), (ד), (ג)**

1. **(ב)** מערכת ההפעלה מוצאת את קובץ התוכנה על ה-Storage.
2. **(א)** היא יוצרת תהליך חדש — נותנת לו PID ומקצה לו אזור זיכרון משלו ב-RAM.
3. **(ד)** היא מעתיקה את הוראות התוכנה מהדיסק לאזור הזיכרון של התהליך.
4. **(ג)** ה-CPU מבצע את ההוראות אחת אחרי השנייה — מביא (Fetch), מפענח (Decode) ומבצע (Execute).

למה (א) לפני (ד)? קודם צריך "בית" בזיכרון — התהליך עם אזור הזיכרון שלו — ורק אז אפשר להעתיק לתוכו את ההוראות.
{{< /solution >}}

### תרגיל 4: שגיאה — באיזה שלב?

בכל אחד מהמקרים הבאים: האם זו שגיאת תחביר (SyntaxError) או שגיאת זמן ריצה? והאם השורה הראשונה הודפסה?

```text
# Program A
print("Start")
print("End"

# Program B
print("Start")
print(10 / 0)
```

{{< solution >}}
- **Program A — SyntaxError** (סוגריים לא נסגרו). Python בודקת את התחביר של כל הקובץ **לפני** שהיא מריצה שורה כלשהי, ולכן **שום דבר לא הודפס**, גם לא `Start`.
- **Program B — שגיאת זמן ריצה** (`ZeroDivisionError`). התחביר תקין, ולכן התוכנית התחילה לרוץ: `Start` **הודפס**, והשגיאה קרתה רק כשהגיעה לשורה השנייה.
{{< /solution >}}

### תרגיל 5: Compiled מול Interpreted

1. מה ההבדל בין Compiler ל-Interpreter?
2. תנו יתרון אחד לכל דרך.
3. איפה Python נמצאת בתמונה, ומה התפקיד של Bytecode ושל PVM?

{{< solution >}}
1. **Compiler** מתרגם את כל הקוד **מראש** לקובץ הרצה בקוד מכונה. **Interpreter** מתרגם ומבצע את הקוד **בזמן ההרצה**.
2. יתרונות:
   - **Compiled** — ריצה מהירה, כי התרגום כבר נעשה.
   - **Interpreted** — נוח לפיתוח: משנים שורה ומריצים מיד, ואותו קוד רץ על כל מחשב שיש בו Interpreter.
3. **Python היא שפה High-level מפורשת.** מאחורי הקלעים היא בודקת תחביר ומתרגמת את הקוד ל-**Bytecode** (הוראות ביניים), ואז ה-**PVM** (Python Virtual Machine) מריץ את ה-Bytecode הוראה אחרי הוראה.
{{< /solution >}}

<!-- exercises:end -->
