# Операционная система: ядро, процессы, файлы и права доступа<no value>

## В этом уроке

Урок состоит из нескольких коротких глав — в том же порядке, что и в презентации:

1. **Глава 1** — что такое операционная система и что такое ядро
2. **Глава 2** — программа и процесс, управление памятью
3. **Глава 3** — файловая система, пользователи и права доступа

## Глава 1: Что такое операционная система и что такое ядро

### Что мы изучим?

В предыдущем уроке мы видели, что операционная система «находит файл, создаёт процесс и загружает в него программу». Теперь познакомимся с ней как следует:

- Что такое **операционная система** (сокращённо **ОС**, англ. **OS**).
- Чем она управляет и зачем.
- Что такое **ядро** (kernel) — сердцевина операционной системы.
- Как наш код «просит» её о чём-то — через **системный вызов** (system call).

### Зачем это нужно?

Каждый `print`, каждый открытый файл, каждое интернет-соединение и, в темах бэкенда и баз данных, каждый сервер — **всё проходит через операционную систему**. Когда вы получаете ошибку вроде `PermissionError` или `Address already in use`, она приходит от операционной системы. Чтобы понять ошибку, нужно понимать, кто её отправил и почему.

Кроме того, большинство серверов в мире работают на **Linux**. Даже если вы работаете в Windows, на работе вы встретитесь с Linux, поэтому важно понимать идеи, общие для всех операционных систем.

### Объяснение с основ

#### Что такое операционная система?

**Операционная система** — первая программа, которая запускается при включении компьютера, и последняя, которая завершается. Её задача: **управлять ресурсами компьютера и позволять другим программам пользоваться ими безопасно и справедливо.**

Примеры: **Windows**, **macOS**, **Linux** (Ubuntu, Debian...), **Android**, **iOS**.

{{< box "analogy" "Аналогия: управляющий зданием" >}}
Представьте офисное здание со множеством компаний (программ). Есть электричество, лифты, переговорные и склад (ресурсы: CPU, RAM, диск, сеть). Если бы каждая компания шла прямо к электрощиту и брала сколько хочет — был бы хаос. **Управляющий зданием** (операционная система) распределяет ресурсы, следит, чтобы ни одна компания не заходила в офис другой, и хранит ключи от всех дверей.
{{< /box >}}

#### Пять главных задач

| Задача | Что это значит | Пример из нашего кода |
|---|---|---|
| **Управление процессами** | Создаёт процессы, распределяет между ними время CPU, завершает их. | Каждый `python file.py` создаёт новый процесс. |
| **Управление памятью** | Даёт каждому процессу свою область RAM и не позволяет одному процессу трогать память другого. | Наши переменные живут в области, которую выделила операционная система. |
| **Управление файлами** (файловая система) | Организует диск в папки и файлы, читает и пишет за нас. | Открыть файл, сохранить, удалить. |
| **Пользователи и права** | Кто вошёл в систему и что ему разрешено. | `PermissionError` при попытке записи в системную папку. |
| **Управление устройствами** | Общается с клавиатурой, экраном, сетевой картой и диском через **драйверы**. | `print` доходит до экрана, а HTTP-запрос уходит через сетевую карту. |

#### Что такое ядро?

**Ядро** (kernel) — **центральная и наиболее защищённая часть** операционной системы. Оно загружается в RAM первым и остаётся там всё время. Именно оно на самом деле выполняет пять задач, перечисленных выше.

Всё остальное — рабочий стол, проводник, терминал и браузер — это **обычные программы**, которые работают «поверх» ядра.

#### Режим ядра и пользовательский режим

Процессор может работать в двух режимах:

- **Режим ядра** (kernel mode) — полный доступ ко всему оборудованию и всей памяти. Так работает только ядро.
- **Пользовательский режим** (user mode) — ограниченный доступ. Так работают все наши программы, включая Python.

**Зачем?** Если бы каждая программа могла обращаться к оборудованию напрямую, одна ошибка в одной программе могла бы обрушить весь компьютер, а вирус мог бы прочитать память вашего банковского приложения. Разделение защищает систему.

#### Системный вызов — просьба к ядру

Как же программа в пользовательском режиме пишет в файл или отправляет данные в сеть? Она **просит** ядро. Такая просьба называется **системным вызовом** (system call).

```text
Your Python code:       print("Hi")
        │
Python interpreter:     "I need to write 'Hi' to the screen"
        │   System Call (write)
        ▼
Kernel (Kernel Mode):   checks permissions → talks to the screen driver
        │
        ▼
Hardware:               the text appears
```

{{< box "term" "Словарь" >}}
- **Operating System (OS)** — программное обеспечение, которое управляет ресурсами компьютера.
- **Kernel (ядро)** — защищённая сердцевина ОС. Работает всегда и выполняет само управление.
- **Driver (драйвер)** — небольшая программа, которая учит ядро общаться с определённым компонентом оборудования.
- **System Call (системный вызов)** — просьба программы к ядру выполнить защищённое действие.
- **User Mode / Kernel Mode** — ограниченный режим для обычных программ / полный режим для ядра.
{{< /box >}}

### Распространённые операционные системы

| Операционная система | Где встречается | Оболочка терминала |
|---|---|---|
| **Windows** | Большинство персональных компьютеров | PowerShell |
| **macOS** | Компьютеры Apple | zsh |
| **Linux** | Большинство облачных серверов и компьютеры разработчиков | Bash |
| **Android / iOS** | Телефоны и планшеты | — |

Все они выполняют одни и те же пять задач — процессы, память, файлы, пользователи и права, оборудование, — и у всех есть ядро. Различия в основном в интерфейсе, командах терминала и структуре папок (например, `C:\` в Windows и `/` в Mac и Linux).

**Почему это важно разработчикам?** Код, который вы пишете в Windows, часто в итоге работает на сервере Linux в облаке. Поэтому стоит знать различия — и писать код, который не зависит от одной операционной системы.

### Типичная ошибка

**Ошибка: пытаться трогать системные файлы «просто чтобы проверить».**

Программа обычного пользователя пытается, например, удалить файл, принадлежащий операционной системе (в папке `C:\Windows\System32`). Что происходит:

1. Программа работает в **пользовательском режиме**, поэтому сама к диску не обращается — она отправляет ядру **системный вызов**.
2. Ядро проверяет права и видит, что у обычного пользователя нет права записи в этот файл.
3. Запрос отклоняется, и программа получает **ошибку доступа** («Access is denied» / `PermissionError`).

И это **хорошо**: права защищают компьютер от ошибок пользователей и от вредоносных программ. Ошибка доступа исходит не от вашей программы — она исходит от операционной системы, которая отказала.

### Итоги

- **Операционная система** управляет ресурсами компьютера: процессами, памятью, файлами, пользователями и правами, оборудованием.
- **Ядро** — её защищённое сердце, работает в **режиме ядра**. Наши программы работают в **пользовательском режиме**.
- Программа просит ядро об услуге через **системный вызов**: вывод на экран, открытие файла, связь по сети.
- Ошибки доступа приходят от операционной системы — именно она проверяет и отказывает.
- **Windows**, **macOS** и **Linux** на компьютерах и серверах, **Android** и **iOS** на телефонах — у всех одни и те же базовые задачи.

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

### Официальная документация

- [User mode and kernel mode](https://learn.microsoft.com/en-us/windows-hardware/drivers/gettingstarted/user-mode-and-kernel-mode)

<!-- docs:end -->

## Глава 2: Программа и процесс, управление памятью

### Что мы изучим?

- Разницу между **программой** и **процессом**.
- Как операционная система запускает десятки процессов «одновременно» — **планирование** (scheduling).
- Как она управляет RAM — **управление памятью**.
- Как увидеть и остановить процессы из терминала.

### Зачем это нужно?

- В темах бэкенда и баз данных мы будем запускать **сервер**. Сервер — это процесс, который не завершается. Если запустить его дважды, второй упадёт, потому что первый всё ещё работает и держит свой адрес. Без понимания процессов это выглядит как магия.
- Когда программа «зависает», нужно знать, как найти процесс и остановить его.
- **Утечка памяти** (memory leak), то есть программа, память которой только растёт, — это баг, который ищут с помощью инструментов мониторинга процессов.

### Объяснение с основ

#### Программа — рецепт. Процесс — готовка.

- **Программа** = файл на накопителе, содержащий инструкции. Она статична: ничего не делает, просто лежит на диске. Примеры: `python.exe`, `chrome.exe`, `hello.py`.
- **Процесс** = **работающий экземпляр** программы. Он динамичен: у него есть память в RAM, PID и состояние (работает / ждёт / завершается).

**Важный момент:** одна программа может запускать **несколько процессов параллельно**. Открыли 3 окна VS Code? Это одна программа и 3 процесса (на практике больше, потому что современные браузеры и редакторы разделяют себя на несколько процессов).

{{< box "analogy" "Аналогия" >}}
**Программа** = рецепт торта, записанный в книге. **Процесс** = торт, который печётся в духовке прямо сейчас. По одному рецепту можно параллельно печь три торта в трёх духовках. У каждого своё состояние: один уже поднялся, другой только начал.
{{< /box >}}

#### Что есть у каждого процесса?

| Часть | Объяснение |
|---|---|
| **PID** | Уникальный идентификационный номер. |
| **Пространство памяти** | Личная область RAM: код, переменные и данные. |
| **Состояние** | Running (на CPU), Ready (ждёт своей очереди), Waiting (ждёт чего-то внешнего, например файла или сети). |
| **Владелец** | Какой пользователь его запустил — от этого зависят его права. |
| **Родитель** | Какой процесс его создал. Например: терминал — родитель `python`. |

#### Планирование — как все работают «одновременно»?

У вас может быть 8 ядер, а на компьютере работают 200 процессов. Как?

**Планировщик** (scheduler), часть ядра, даёт каждому процессу очень короткий **квант времени** (time slice) на CPU (миллисекунды), а затем переходит к следующему процессу. Это происходит так быстро, что кажется, будто все работают одновременно.

```text
Time →   | P1 | P2 | P3 | P1 | P2 | P3 | P1 | ...
          each slice ≈ a few milliseconds
```

Процесс, который **ждёт** (например, на `time.sleep` или ответа из сети), вообще не получает времени CPU, пока ожидание не закончится. Поэтому сервер, ожидающий запросов, почти не нагружает CPU.

#### Управление памятью

С памятью операционная система делает три главные вещи:

1. **Выделение** — при создании процесса и каждый раз, когда ему нужно больше памяти (например, растущий список), ОС даёт ему больше RAM.
2. **Изоляция** — каждый процесс видит только свою память. Один процесс **не может** читать или менять переменные другого процесса. Это не даёт багу в одном приложении испортить другое приложение.
3. **Освобождение** — когда процесс завершается, вся его RAM возвращается системе.

А если RAM закончилась? Операционная система переносит неиспользуемые части на диск (**swap** в Linux/Mac, **файл подкачки** — page file — в Windows). Это предотвращает сбой, но компьютер становится очень медленным, потому что диск медленный.

{{< box "tip" "А что с Python?" >}}
У Python есть и свой внутренний механизм — **сборщик мусора** (garbage collector). Когда объект больше не используется (на него не указывает ни одна переменная), Python сам освобождает его память. Поэтому в Python не нужно «освобождать память» вручную, как в языках вроде C.
{{< /box >}}

### Дерево процессов — кто кого запустил

Каждый процесс создаётся другим процессом — своим **родителем**. Когда вы запускаете программу из терминала, родитель — терминал:

```text
explorer.exe          PID 4120
└── pwsh.exe          PID 9920   (Terminal)
    └── python.exe    PID 18044  (our program)
```

У каждого процесса свой **PID**, а также **PPID** — PID родителя. Когда вы закрываете терминал, запущенные им процессы обычно тоже закрываются.

### Команды для просмотра и остановки процессов

Процессы можно увидеть в диспетчере задач, а также из терминала. Преподаватель покажет команды на экране:

**Windows (PowerShell):**

```powershell
Get-Process                    # list all processes
Get-Process python             # only processes named python
Stop-Process -Id 12345         # stop the process with PID 12345
```

**Mac / Linux (Bash / Zsh):**

```bash
ps aux                  # list all processes
ps aux | grep python    # filter lines that contain "python"
kill 12345              # stop the process with PID 12345
```

### Типичная ошибка

**Ошибка: думать, что `Ctrl + C` вызвал «ошибку».** Когда вы останавливаете работающую программу на Python через `Ctrl + C`, появляется примерно такое:

```text
^C
Traceback (most recent call last):
  ...
KeyboardInterrupt
```

- `Ctrl + C` отправляет процессу **просьбу остановиться** — это не баг.
- `KeyboardInterrupt` говорит: «вы остановили меня на середине».
- Любое значение, которое было только в RAM процесса, **потеряно**, потому что его память освобождена.

### Итоги

- **Программа** — статичный файл на диске. **Процесс** — её работающий экземпляр с PID, памятью и состоянием.
- Одна программа может запускать несколько процессов, у каждого своя **изолированная** память.
- **Планировщик** распределяет время CPU маленькими квантами, поэтому всё выглядит параллельным.
- **Управление памятью:** выделение, изоляция и освобождение. Когда RAM заканчивается, используется swap / файл подкачки, и это медленно.
- У каждого процесса есть **родитель**. Программу останавливают через `Ctrl + C`, а зависший процесс — через `Stop-Process` / `kill` по PID.

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

### Официальная документация

- [About Processes and Threads](https://learn.microsoft.com/en-us/windows/win32/procthread/about-processes-and-threads)
- [Virtual Address Space](https://learn.microsoft.com/en-us/windows/win32/memory/virtual-address-space)

<!-- docs:end -->

## Глава 3: Файловая система, пользователи и права доступа

### Что мы изучим?

- **Файловую систему** — как операционная система организует диск.
- **Пути** — абсолютные и относительные, и что такое `.` и `..`.
- **Пользователей** — кто вошёл в систему и кто «всемогущий» пользователь.
- **Права доступа** — кто что может делать с каждым файлом.

### Зачем это нужно?

- В теме Python мы будем читать и писать **файлы** из Python. Самая частая ошибка там — `FileNotFoundError`, и причина почти всегда в неправильном пути.
- В теме баз данных мы запустим сервер базы данных и подключимся к нему — и многие инструменты там настраиваются путями к файлам и папкам.
- При установке инструментов иногда появляется «Access denied» или «Permission denied». Стоит понимать, почему так происходит, а не решать каждую проблему через «запустить от имени администратора».

### Объяснение с основ

#### Файловая система

Сам диск — огромная последовательность байтов. **Файловая система** — слой операционной системы, который превращает эту последовательность в **файлы и папки** с именами и хранит для каждого файла дополнительную информацию (**метаданные**): размер, дату изменения, владельца и права.

Структура — **дерево**: есть **корень**, из него выходят папки, и в каждой папке есть ещё папки и файлы.

```text
Windows                         Mac / Linux
C:\                             /
├── Users\                      ├── home/            (Mac: /Users/)
│   └── dana\                   │   └── dana/
│       ├── Desktop\            │       ├── Desktop/
│       └── dev\                │       └── dev/
│           └── kodkod6\        │           └── kodkod6/
├── Program Files\              ├── usr/
└── Windows\                    └── etc/
```

Важные различия:

| | Windows | Mac / Linux |
|---|---|---|
| Корень | Буква диска: `C:\` (их может быть больше: `D:\`) | Один корень: `/` |
| Разделитель | `\` (обратная косая черта) | `/` (косая черта) |
| Домашняя папка | `C:\Users\dana` | `/home/dana` (Mac: `/Users/dana`) |
| Регистр букв | `File.txt` = `file.txt` | `File.txt` ≠ `file.txt` (в Linux) |

**Домашняя папка** (home directory) — личная папка пользователя. В ней и во всех её подпапках у вас полные права. Поэтому `kodkod6` кладут внутрь неё.

#### Абсолютный путь и относительный путь

- **Абсолютный путь** — начинается от корня. Работает откуда угодно.
  `C:\Users\dana\dev\kodkod6\week-1\hello.py`
- **Относительный путь** — начинается **от текущей папки**. Короткий, но зависит от того, где вы стоите.
  `week-1\hello.py` (если вы стоите в `kodkod6`)

Два специальных сокращения:

- `.` (точка) = **текущая папка**.
- `..` (две точки) = **родительская папка**, на одну папку вверх.

```text
Standing in: C:\Users\dana\dev\kodkod6\week-1

.              → C:\Users\dana\dev\kodkod6\week-1
..             → C:\Users\dana\dev\kodkod6
..\week-2      → C:\Users\dana\dev\kodkod6\week-2
..\..          → C:\Users\dana\dev
```

{{< box "analogy" "Аналогия" >}}
**Абсолютный путь** — полный адрес: «Израиль, Хайфа, улица Герцля, 10, квартира 3». Отправлено откуда угодно в мире — дойдёт. **Относительный путь** — указание направления: «две двери направо отсюда». Работает, только если известно, откуда вы начинаете.
{{< /box >}}

#### Пользователи

Операционная система поддерживает нескольких **пользователей**. У каждого есть имя, пароль, домашняя папка и права. Есть и «особые» пользователи:

- **Administrator** (Windows) / **root** (Linux/Mac) — суперпользователь с полными правами на всю систему.
- **Системные пользователи** — пользователи, которые не являются людьми. Под ними работают службы, например сервер или база данных, так что даже если их взломают, ущерб будет ограничен.

В обычной работе вы работаете как **обычный** пользователь и повышаете права только для конкретного действия: **Запуск от имени администратора** в Windows, `sudo` в Linux/Mac.

#### Права доступа

У каждого файла и папки есть права, которые определяют, **кто** может делать **что**. Три базовых действия:

| Право | Для файла | Для папки |
|---|---|---|
| **Read** (r) | Читать содержимое | Видеть, какие в ней файлы |
| **Write** (w) | Изменять / удалять | Создавать и удалять файлы внутри неё |
| **Execute** (x) | Запускать как программу | Входить в неё (`cd`) |

В Linux/Mac права показываются строкой вида `-rwxr-xr--`, разделённой на три группы: **владелец**, **группа** и **остальные**:

```text
-  rwx  r-x  r--
│   │    │    └── others: read only
│   │    └─────── group:  read + execute
│   └──────────── owner:  read + write + execute
└──────────────── type: "-" = file, "d" = directory
```

В Windows права называются **ACL** и находятся в меню правой кнопки мыши → Свойства → **Безопасность**. Принцип тот же.

**Зачем нужны права?** Чтобы один пользователь не мог читать личные файлы другого, чтобы неисправная программа или вирус не могли изменить системные файлы и чтобы взломанный сервер не мог трогать весь компьютер.

### Типичная ошибка

**Ошибка 1: «файл не найден» — но он существует.**

```text
Standing in:  C:\dev\kodkod6
Looking for:  data.txt
Searched:     C:\dev\kodkod6\data.txt
Real file:    C:\dev\kodkod6\week-1\data.txt
```

- **Относительный** путь проверяется **от текущей папки** — оттуда, где стоит терминал, — а не от папки, где лежит файл.
- Запустили из другой папки? Программа ищет в другом месте и не находит.
- **Исправление:** сначала перейти в нужную папку (`cd`) или использовать **абсолютный** путь.

**Ошибка 2: работать как администратор / root, «чтобы не было проблем».** Так вы обходите защиту, которую дают права: любая ошибка или вредоносная программа получает доступ ко всему компьютеру. Работайте как обычный пользователь и пользуйтесь правами суперпользователя только тогда, когда это действительно нужно.

**Ошибка 3: думать, что ошибка доступа — это баг в программе.** Когда операционная система возвращает «Access is denied» / `PermissionError`, она **проверила и обнаружила**, что у текущего пользователя нет права на это действие. Исправление — проверить, кому принадлежит файл и какие у него права, а не менять программу.

### Итоги

- **Файловая система** организует диск как **дерево** папок и файлов, начиная от корня (`C:\` или `/`).
- **Абсолютный путь** начинается от корня. **Относительный путь** — от текущей папки. `.` = здесь, `..` = вверх.
- Относительные пути отсчитываются **от того места, откуда запущена программа**, а не от расположения файла.
- У каждого пользователя есть домашняя папка и права. **Administrator / root** — суперпользователи, их используют только при необходимости.
- Базовые права: **чтение / запись / выполнение**. Ошибка доступа = операционная система отказала.

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

### Официальная документация

- [Naming Files, Paths, and Namespaces](https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file)
- [chmod — Linux manual page](https://man7.org/linux/man-pages/man1/chmod.1.html)

<!-- docs:end -->

<!-- exercises:start — generated by scripts/intro6/sync_site_exercises.py; edit scripts/intro6/exercises/ -->
## Практика

Вопросы на понимание материала урока — без кода.

### Упражнение 1: Пять задач

Перечислите пять главных задач операционной системы и приведите пример каждой из того, что происходит на вашем компьютере.

{{< solution >}}
| Задача | Пример |
|---|---|
| **Управление процессами** | Решает, кто и когда получает CPU, — браузер, музыкальный плеер и VS Code «работают вместе» |
| **Управление памятью** | Даёт каждой программе RAM и не позволяет одной программе читать память другой |
| **Управление файлами** | Хранит файлы в дереве папок на диске |
| **Пользователи и права** | Обычный пользователь не может удалить системные файлы |
| **Управление оборудованием** | Общается с экраном, клавиатурой и принтером через драйверы |
{{< /solution >}}

### Упражнение 2: Что происходит, когда print печатает?

Программа на Python выполняет `print("Hi")`. Опишите путь от программы до появления текста на экране. Используйте термины «пользовательский режим», «системный вызов», «ядро» и «драйвер».

{{< solution >}}
1. Наша программа работает в **пользовательском режиме** — у неё нет прямого доступа к экрану.
2. Python просит ядро вывести текст — это **системный вызов** (упорядоченная просьба).
3. **Ядро**, работающее в **режиме ядра** с полным доступом к оборудованию, проверяет права.
4. Ядро передаёт запрос **драйверу** экрана.
5. Текст появляется на экране.
{{< /solution >}}

### Упражнение 3: Программа и процесс

1. В чём разница между программой и процессом?
2. Вы открыли три окна Chrome. Сколько здесь программ и как минимум сколько процессов?
3. В компьютере 8 ядер, но работают 300 процессов. Как это возможно?

{{< solution >}}
1. **Программа** — файл на диске, рецепт. **Процесс** — её активный запуск в RAM со своим PID и памятью, готовка.
2. **Одна программа** (Chrome) и **как минимум три процесса** — на практике гораздо больше, потому что Chrome запускает отдельный процесс для каждой вкладки и каждого компонента.
3. **Планировщик** операционной системы делит время CPU на маленькие кванты по несколько миллисекунд и переключает ядра между процессами так быстро, что кажется, будто все работают параллельно.
{{< /solution >}}

### Упражнение 4: Пути

Терминал стоит в `C:\Users\dana\dev\kodkod6\week-1`. В какой абсолютный путь превращается каждый из относительных путей?

```text
.
..
..\week-2
..\..
```

{{< solution >}}
| Относительный путь | Абсолютный путь |
|---|---|
| `.` | `C:\Users\dana\dev\kodkod6\week-1` |
| `..` | `C:\Users\dana\dev\kodkod6` |
| `..\week-2` | `C:\Users\dana\dev\kodkod6\week-2` |
| `..\..` | `C:\Users\dana\dev` |

`.` = текущая папка, `..` = на одну папку вверх.
{{< /solution >}}

### Упражнение 5: Читаем права доступа

Вот строка из `ls -l` на компьютере с Linux:

```text
-rw-r-----   dana   grades.txt
```

1. Это файл или папка?
2. Что разрешено владельцу (dana), что разрешено группе и что разрешено всем остальным?
3. Другой пользователь, не входящий в группу, пытается прочитать файл. Что произойдёт и кто решает?

{{< solution >}}
1. **Файл** — первый символ `-` (папка начиналась бы с `d`).
2. Права разделены на три группы по три символа:
   - **Владелец** `rw-` — чтение и запись.
   - **Группа** `r--` — только чтение.
   - **Все остальные** `---` — никаких прав.
3. Он получит **ошибку доступа** (Permission denied). Решает **операционная система** — ядро проверяет права при каждой попытке обратиться к файлу.
{{< /solution >}}

<!-- exercises:end -->
