Операционные системы

Что такое программа?

Короткий ответ

Программа - это набор инструкций и данных, описывающих, что должен сделать компьютер. В исходном коде программа понятна разработчику, а для выполнения она должна быть интерпретирована, скомпилирована или запущена внутри runtime.

Полный ответ

Программа - это пассивное описание вычисления: исходный код, байткод, исполняемый файл, конфигурация и связанные ресурсы. Пока программа не запущена, операционная система не выделяет ей отдельное время CPU и рабочую память процесса.

Способ выполнения зависит от технологии:

  • нативный бинарный файл содержит машинный код для конкретной архитектуры;
  • JavaScript загружается и выполняется движком, который может интерпретировать и JIT-компилировать код;
  • Java или .NET обычно используют байткод и runtime;
  • TypeScript сначала преобразуется в JavaScript, который затем выполняет JS-движок.

Например, main.ts сам по себе является исходным текстом. После сборки появляется JavaScript bundle, но работающим приложением он становится только после загрузки браузером или запуска Node.js.

Важно различать программу и ее выполнение: один и тот же Chrome, Node.js script или CLI можно запустить несколько раз. Каждый запуск создаст отдельный процесс или набор процессов со своим состоянием.

Чем программа отличается от процесса?

Короткий ответ

Программа - это пассивное описание: файлы на диске, исходный код или исполняемый файл. Процесс - это уже запущенный экземпляр программы в операционной системе.

Полный ответ

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

У процесса обычно есть:

  • PID;
  • виртуальное адресное пространство;
  • код, heap и stacks потоков;
  • открытые файлы и sockets;
  • переменные окружения и аргументы запуска;
  • текущая директория;
  • пользователь, права и ограничения ресурсов;
  • состояние выполнения, которое отслеживает scheduler.

Например, если открыть два независимых процесса браузера или дважды запустить node server.js, код программы может быть одинаковым, но память, открытые соединения и текущие запросы будут разными.

Изоляция процессов повышает устойчивость: ошибка одного процесса обычно не дает ему напрямую изменить память другого. Обратная сторона - обмен между процессами требует IPC: pipes, sockets, shared memory или других механизмов ОС.

Что происходит, когда пользователь запускает программу?

Короткий ответ

Операционная система находит исполняемый файл или runtime, создает процесс, выделяет ему память, передает аргументы и переменные окружения, подключает стандартные потоки ввода/вывода и передает управление начальной точке программы.

Полный ответ

Точная последовательность зависит от ОС и формата программы, но упрощенно запуск выглядит так:

  1. Shell, файловый менеджер или другая программа просит ОС запустить файл.
  2. ОС проверяет путь, формат файла и права доступа.
  3. Создается процесс с PID и виртуальным адресным пространством.
  4. Loader отображает в память код, данные и необходимые shared libraries.
  5. Процесс получает аргументы, environment variables, working directory и стандартные потоки.
  6. Создается основной поток, его registers и stack.
  7. Scheduler допускает поток к CPU, и выполнение начинается с entry point.

В Unix-подобных системах shell часто создает дочерний процесс и вызывает семейство exec, а Windows предоставляет CreateProcess. Детали разные, но смысл одинаков: ОС превращает пассивный файл в управляемое выполнение с ресурсами.

После старта программа обращается к файлам, сети, таймерам и устройствам через runtime и системные вызовы. Даже простой console.log() в итоге приводит к записи в стандартный output, которой управляет ОС.

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

Короткий ответ

Операционная система - это слой между программами и аппаратным обеспечением. Она управляет процессами, памятью, файлами, устройствами ввода/вывода, сетью, пользователями и правами доступа.

Полный ответ

Операционная система одновременно является менеджером ресурсов и набором абстракций над аппаратным обеспечением.

Как менеджер ресурсов она решает:

  • какой поток и когда получит CPU;
  • какие страницы памяти принадлежат процессу;
  • кто может открыть файл или порт;
  • как разделить устройства между программами;
  • как изолировать пользователей и процессы.

Как слой абстракций ОС дает программам более удобные сущности:

  • процесс вместо ручного управления CPU;
  • файл вместо работы с блоками накопителя;
  • socket вместо прямого формирования сетевых сигналов;
  • virtual memory вместо физических адресов RAM;
  • window, input events и device APIs поверх конкретного железа.

ОС включает не только kernel. В систему также входят drivers, системные службы, библиотеки, shell и пользовательские утилиты. Например, Linux технически является ядром, а привычная Linux-система дополнена user-space инструментами и дистрибутивом.

Для frontend-разработчика ОС проявляется через файловые watchers, лимиты открытых файлов, процессы dev server, переменные окружения, сертификаты, DNS, sockets и поведение браузера.

Что такое ядро операционной системы?

Короткий ответ

Ядро - центральная часть операционной системы, которая управляет самыми низкоуровневыми ресурсами: CPU, памятью, процессами, драйверами, файловой системой и сетевым вводом/выводом.

Полный ответ

Kernel работает с повышенными привилегиями и контролирует ресурсы, которым нельзя безопасно доверить обычным приложениям.

К основным задачам ядра относятся:

  • планирование потоков на CPU;
  • создание и завершение процессов;
  • virtual memory и защита адресных пространств;
  • обработка interrupts;
  • работа с device drivers;
  • файловые системы;
  • network stack;
  • проверка прав доступа и системных ограничений.

Пользовательская программа не читает диск и не управляет сетевой картой напрямую. Она вызывает API runtime или системной библиотеки, а те переходят к system call, например open, read, write, mmap или socket. Kernel проверяет запрос, выполняет привилегированную операцию и возвращает результат.

Ошибка в kernel или driver опаснее ошибки обычного приложения, потому что kernel имеет доступ ко всей системе. Поэтому минимизация кода с высокими привилегиями и четкая граница user/kernel space важны для безопасности и устойчивости.

Чем kernel space отличается от user space?

Короткий ответ

Kernel space - область, где работает ядро ОС и код с максимальными правами. User space - область, где работают обычные пользовательские программы.

Полный ответ

Kernel space и user space разделены уровнями привилегий CPU и механизмами virtual memory.

Код в kernel space может управлять page tables, drivers, interrupts и памятью разных процессов. Код в user space обычно видит только собственное виртуальное адресное пространство и не может выполнить привилегированную инструкцию напрямую.

Когда приложению нужен защищенный ресурс, оно делает system call:

  1. CPU переключается в привилегированный режим.
  2. Kernel проверяет параметры и права.
  3. Операция выполняется или отклоняется.
  4. Управление возвращается в user space.

Это разделение ограничивает последствия ошибок. Если вкладка браузера падает, обычно завершается ее процесс, а не вся ОС. Если же критическая ошибка происходит в kernel driver, возможен crash всей системы.

Переход между режимами не бесплатен, но обычно проблема производительности не в одном system call, а в огромном числе мелких операций. Поэтому I/O часто буферизуют и объединяют в batches.

Что такое поток выполнения?

Короткий ответ

Поток выполнения - это последовательность инструкций внутри процесса, которую планировщик ОС может выполнять на CPU. Процесс может иметь один или несколько потоков.

Полный ответ

Thread - минимальная единица выполнения, которую обычно планирует ОС. Каждый поток имеет собственные:

  • instruction pointer;
  • registers;
  • stack;
  • состояние scheduler.

При этом потоки одного процесса обычно разделяют code, heap, открытые файлы и sockets. Благодаря общей памяти обмен данными дешевле, чем между процессами, но требуется синхронизация.

Например, browser process может использовать отдельные потоки для UI, I/O и служебной работы, а renderer process - main thread и дополнительные worker threads. JavaScript-код страницы обычно выполняется на main thread, но Web Worker дает отдельный execution context, который может работать параллельно на другом ядре.

Если два потока изменяют общие данные без координации, появляется data race. Для защиты используют mutexes, atomics, message passing или проектируют систему так, чтобы mutable state не разделялся.

Чем процесс отличается от потока?

Короткий ответ

Процесс - изолированный экземпляр программы со своей памятью и ресурсами. Поток - линия выполнения внутри процесса.

Полный ответ

Главное различие - изоляция ресурсов.

Процесс обычно имеет отдельное виртуальное адресное пространство. Чтобы два процесса обменялись данными, нужен IPC. Потоки одного процесса видят общий heap и многие общие ресурсы, но имеют собственные stacks и registers.

Практические trade-offs:

СвойствоПроцессыПотоки
ИзоляцияВышеНиже
Обмен даннымиЧерез IPCЧерез общую память
Стоимость создания и переключенияОбычно вышеОбычно ниже
Последствие crashЧаще локализованоМожет повредить весь процесс
Риск data racesНиже между процессамиВыше при shared state

Браузеры используют multi-process архитектуру, чтобы изолировать вкладки, сайты и привилегированные компоненты. Внутри каждого процесса при этом могут работать несколько потоков.

Выбор зависит не только от скорости. Для недоверенного кода или сильной изоляции процесс может быть правильнее, даже если он тяжелее. Для тесно связанной вычислительной работы могут подойти threads или workers.

Что такое параллельность и конкурентность?

Короткий ответ

Конкурентность означает, что несколько задач продвигаются во времени независимо: одна ждет сеть, другая обрабатывает ввод, третья готовится к выполнению. Параллельность означает, что несколько задач действительно выполняются одновременно на разных ядрах CPU.

Полный ответ

Concurrency описывает организацию нескольких незавершенных задач. Система переключается между ними или продолжает одну, пока другая ждет I/O.

Parallelism означает физическое одновременное выполнение как минимум двух операций, например на разных CPU cores.

Однопоточный JavaScript может быть конкурентным:

  1. код начинает fetch;
  2. запрос обрабатывается сетевой подсистемой;
  3. main thread продолжает другую работу;
  4. после ответа callback или Promise continuation попадает в очередь.

Но JavaScript callbacks в одном event loop не выполняются параллельно друг другу. Для CPU-параллелизма в браузере нужны Web Workers, а в Node.js - worker threads или процессы.

Важно не говорить, что async/await автоматически создает новый поток. Он упрощает управление асинхронным ожиданием, но CPU-bound цикл по-прежнему блокирует текущий поток.

Что такое CPU-bound и I/O-bound задачи?

Короткий ответ

CPU-bound задача упирается в вычисления процессора: парсинг большого объема данных, сжатие, криптография, сложная агрегация. I/O-bound задача больше ждет внешний ресурс: диск, сеть, базу данных или файловую систему.

Полный ответ

У CPU-bound и I/O-bound задач разные bottlenecks, поэтому им нужны разные оптимизации.

CPU-bound:

  • CPU долго занят вычислением;
  • ускоряется улучшением алгоритма, уменьшением данных, SIMD или параллелизмом;
  • асинхронная обертка сама по себе не сокращает вычисления.

Frontend-примеры: тяжелая сортировка, декодирование данных, image processing, сложный synchronous parser.

I/O-bound:

  • большая часть времени уходит на ожидание сети, диска или базы данных;
  • помогает concurrency, caching, batching, streaming и сокращение round trips;
  • дополнительные CPU cores могут почти не изменить latency одного запроса.

Например, десять HTTP-запросов можно выполнять конкурентно, если backend допускает это. Но запуск десяти тяжелых вычислений на одном main thread не сделает их параллельными и может ухудшить responsiveness.

Сначала нужно измерить, где тратится время. Медленный пользовательский сценарий часто смешивает оба типа: сеть доставляет большой JSON, после чего main thread долго его парсит и рендерит.

Что такое терминал?

Короткий ответ

Терминал - это интерфейс для ввода команд и просмотра текстового вывода программ. В современных системах чаще всего это приложение-эмулятор терминала: Terminal, iTerm, Windows Terminal или встроенный терминал IDE.

Полный ответ

Исторически terminal был физическим устройством с клавиатурой и экраном, подключенным к вычислительной машине. Сегодня terminal emulator - приложение, которое воспроизводит текстовый интерфейс терминала.

Он отвечает за:

  • отображение символов, colors и cursor;
  • передачу нажатий клавиш;
  • размер текстовой области;
  • обработку control sequences;
  • связь с shell или другой консольной программой через pseudo-terminal.

Сам terminal обычно не решает, что означает cd, npm или pipe. Он передает ввод запущенной программе и отображает ее output. Обычно этой программой является shell, но в terminal можно запустить REPL, editor или другую TUI-программу.

Поэтому закрытие окна terminal может завершить связанные процессы, но это зависит от того, привязаны ли они к terminal, запущены ли через background manager, nohup, tmux, system service или IDE.

Чем terminal отличается от shell?

Короткий ответ

Terminal отвечает за окно, ввод, вывод и отображение текста. Shell - это программа, которая читает команду, разбирает аргументы, ищет исполняемые файлы, запускает процессы и связывает их ввод/вывод.

Полный ответ

Terminal предоставляет канал взаимодействия, а shell предоставляет язык команд и управление процессами.

Shell:

  • разбирает quoting, variables и wildcard expansion;
  • выполняет built-in команды вроде cd;
  • ищет программы по PATH;
  • создает pipelines;
  • настраивает redirections;
  • запускает foreground и background jobs;
  • возвращает exit code.

Например, при команде:

Кодпример
cat app.log | grep ERROR > errors.log

terminal передает строку shell. Shell создает процессы cat и grep, соединяет stdout первого со stdin второго и перенаправляет результат в файл. Terminal только отображает ввод и то, что не было перенаправлено.

Примеры shell: bash, zsh, fish, PowerShell. Их syntax и built-ins отличаются, поэтому команда для Bash не обязана работать в PowerShell, даже если используется то же приложение terminal.

Что такое stdin, stdout и stderr?

Короткий ответ

stdin - стандартный ввод процесса, stdout - обычный результат, stderr - ошибки и диагностика. Shell может соединять и перенаправлять эти потоки.

Полный ответ

При запуске консольный процесс обычно получает три стандартных потока:

  • stdin с file descriptor 0;
  • stdout с file descriptor 1;
  • stderr с file descriptor 2.

По умолчанию они могут быть связаны с terminal, но shell умеет заменить источник или назначение:

Кодпример
node build.mjs < input.json
node build.mjs > result.txt
node build.mjs 2> errors.txt
node build.mjs > all.txt 2>&1
cat app.log | grep ERROR

Разделение stdout и stderr важно для автоматизации. CLI может писать machine-readable результат в stdout, а progress и диагностику - в stderr, не повреждая данные pipeline.

Stream не обязательно является файлом на диске. Он может быть terminal, pipe, socket или специальное устройство. Запись может буферизоваться, поэтому момент вызова logging API и момент появления текста не всегда совпадают.

Что такое переменные окружения?

Короткий ответ

Переменные окружения - это пары ключ-значение, которые ОС или shell передают процессу при запуске. Они часто используются для конфигурации: режим окружения, адрес API, токены, порты и feature flags.

Полный ответ

Environment variables являются частью окружения процесса. Обычно дочерний процесс получает копию набора переменных родителя при запуске.

Пример:

Кодпример
API_URL=https://api.example.com NODE_ENV=production node server.mjs

Процесс читает значения через API runtime, например process.env в Node.js. Если после запуска изменить переменную в другом окне shell, работающий процесс обычно не получит обновление автоматически.

Важные ограничения:

  • значения передаются как strings;
  • наличие переменной нужно валидировать при старте;
  • environment не является безопасным secret storage сам по себе;
  • переменные frontend build часто подставляются в bundle во время сборки и становятся видны пользователю;
  • runtime-конфигурация браузерного приложения требует отдельного механизма, например config endpoint или файла.

Хорошая практика - преобразовать сырые variables в типизированный config один раз при старте и завершить процесс с понятной ошибкой, если обязательное значение отсутствует.

Что такое exit code?

Короткий ответ

Exit code - числовой код завершения процесса. Обычно 0 означает успех, а ненулевое значение - ошибку или другое неуспешное состояние.

Полный ответ

Когда процесс завершается, ОС сохраняет его status, который может прочитать родительский процесс или shell. По соглашению 0 означает успешное выполнение, а ненулевые значения обозначают разные причины неуспеха.

Shell использует status для управления командами:

Кодпример
npm test && npm run build
npm test || echo "Tests failed"

В первом случае build запускается только после 0, во втором правая команда выполняется после ошибки. CI/CD работает по тому же принципу: job считается failed, если команда вернула ненулевой status.

CLI полезно выбирать стабильные codes и писать объяснение в stderr. При завершении из-за signal отображаемое значение может кодироваться особым образом и отличаться между shell и ОС, поэтому не стоит считать любое конкретное ненулевое число универсальным без документации инструмента.

В Node.js можно задать process.exitCode, чтобы event loop завершился естественно и buffered output успел записаться, вместо немедленного process.exit().

Что такое порт?

Короткий ответ

Порт - числовой идентификатор transport endpoint внутри хоста. IP-адрес помогает найти сетевой интерфейс, а порт - программу или службу, которой предназначены данные.

Полный ответ

TCP и UDP используют номера портов от 0 до 65535, чтобы несколько сетевых программ могли работать на одном IP-адресе. TCP port и UDP port являются разными пространствами: процесс может использовать один номер для TCP, а другой - для UDP.

Server обычно bind-ится к известному порту, например 443. Client при исходящем соединении получает временный ephemeral port. TCP-соединение различается набором:

protocol + source IP + source port + destination IP + destination port

Поэтому тысячи clients могут одновременно обращаться к одному server port: у соединений различаются source endpoints.

В URL порт указывают после двоеточия: http://localhost:3000. Если порт не указан, схема задает default, например 80 для HTTP и 443 для HTTPS.

Порт не является физическим разъемом и не гарантирует конкретный protocol приложения. На 3000 может работать HTTP server, но это определяется программой, а не самим числом.

Что значит "программа слушает порт"?

Короткий ответ

Это значит, что программа привязала socket к адресу и порту и готова принимать входящие соединения или datagrams.

Полный ответ

Для TCP server последовательность обычно включает:

  1. создать socket;
  2. выполнить bind к local address и port;
  3. перевести socket в состояние listen;
  4. принимать соединения через accept;
  5. читать и писать данные через socket каждого соединения.

Для UDP постоянного соединения может не быть: программа bind-ится к порту и получает отдельные datagrams.

Адрес binding важен:

  • 127.0.0.1:3000 доступен только через loopback;
  • 0.0.0.0:3000 означает все подходящие IPv4 interfaces;
  • конкретный LAN IP ограничивает один interface.

Например, dev server, слушающий только localhost, откроется на ноутбуке разработчика, но обычно не будет доступен с телефона в той же сети. Чтобы открыть доступ, нужно изменить binding и учесть firewall.

Почему порт может быть занят?

Короткий ответ

Другой socket уже может быть привязан к несовместимому сочетанию protocol, address и port. Тогда новый server получает ошибку вроде EADDRINUSE.

Полный ответ

ОС не позволяет двум listening sockets без специальных условий одновременно владеть одним и тем же endpoint. Например, если процесс слушает 0.0.0.0:3000, он занимает порт на всех IPv4 interfaces и может конфликтовать с binding к 127.0.0.1:3000.

Причины:

  • старый dev server продолжает работать;
  • IDE или terminal оставили background process;
  • другой инструмент использует тот же default port;
  • предыдущие соединения еще находятся в переходном TCP state;
  • настройки контейнера публикуют host port.

Диагностика зависит от ОС, например:

Кодпример
lsof -i :3000

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

Опции вроде SO_REUSEADDR влияют на повторное использование адреса, но не означают, что любые два servers безопасно разделят один endpoint. Семантика зависит от ОС и socket options.

Что такое localhost?

Короткий ответ

localhost - имя текущего хоста, которое обычно разрешается в loopback-адрес 127.0.0.1 для IPv4 или ::1 для IPv6.

Полный ответ

Loopback interface позволяет сетевым программам на одном компьютере общаться через обычный network stack без отправки пакетов во внешнюю сеть.

Когда браузер открывает http://localhost:3000, он соединяется с process на той же network namespace, который слушает подходящий address и port.

Важно различать:

  • localhost - host name;
  • 127.0.0.1 и ::1 - loopback IP addresses;
  • 0.0.0.0 - не адрес для обращения из браузера, а специальный bind address “все IPv4 interfaces”.

В container или virtual machine localhost относится к самой изолированной среде, а не автоматически к host OS. Например, localhost внутри Docker container указывает на container. Для доступа к host или соседнему service нужен отдельный address или network name.

Также возможна разница IPv4/IPv6: server, слушающий только 127.0.0.1, не всегда примет соединение на ::1.

Что такое сервер?

Короткий ответ

Сервером называют роль, программу или машину, которая принимает запросы или соединения и предоставляет данные либо другой ресурс.

Полный ответ

Термин server используется на нескольких уровнях:

  • роль в конкретном взаимодействии;
  • server process, например Node.js HTTP server;
  • host или virtual machine, на которой работают server processes;
  • hardware, предназначенное для серверной нагрузки.

Server обычно слушает endpoint, принимает запрос, выполняет обработку и возвращает response. Он может одновременно обслуживать много clients через event loop, threads, processes или их комбинацию.

Ноутбук разработчика становится server для браузера, когда на нем работает Angular, Vite или Astro dev server. При этом тот же dev server может выступать client, когда запрашивает данные у backend.

Server не обязан быть удаленным и не обязан работать по HTTP. Файловый server, database, DNS server и WebSocket server предоставляют разные protocols и ресурсы.

Что такое клиент?

Короткий ответ

Клиент - сторона, которая инициирует взаимодействие с server. Им может быть браузер, мобильное приложение, CLI или другой service.

Полный ответ

Client знает или находит endpoint server, устанавливает необходимое соединение и отправляет request либо команду.

Для открытия HTTPS-страницы браузер упрощенно:

  1. разрешает domain через DNS;
  2. устанавливает TCP или QUIC connection;
  3. выполняет TLS handshake;
  4. отправляет HTTP request;
  5. получает response и обрабатывает данные.

Роли относительны. Browser является client для web server. Backend может быть server для browser и одновременно client для database, payment API или другого service.

Client также отвечает за собственные concerns: timeouts, retries, cancellation, validation response и обработку ошибок. Безусловные retries опасны для non-idempotent операций, поэтому поведение зависит от protocol и semantics запроса.

Что такое IP-адрес?

Короткий ответ

IP-адрес идентифицирует network interface в IP-сети и используется routing для доставки packets между узлами.

Полный ответ

IP address является логическим адресом network layer. Router анализирует destination address и выбирает, куда переслать packet дальше.

Основные версии:

  • IPv4, например 192.168.1.10;
  • IPv6, например 2001:db8::10.

Адрес может быть public или private, static или dynamic. За NAT несколько устройств private network могут выходить во внешнюю сеть через один public address.

IP не всегда однозначно идентифицирует физическое устройство или пользователя:

  • у устройства несколько interfaces и addresses;
  • address может измениться;
  • proxy, VPN и NAT скрывают исходный address;
  • один server address может вести к load balancer;
  • domain может разрешаться в несколько addresses.

IP отвечает за доставку между network endpoints, а transport port помогает выбрать приложение внутри host. Domain name является удобным именем и разрешается в address через DNS.

Что такое DNS?

Короткий ответ

DNS - распределенная система имен, которая сопоставляет domain names с IP-адресами и другими records.

Полный ответ

Когда приложению нужен example.com, resolver сначала проверяет доступные caches. Если ответа нет, запрос проходит через recursive DNS resolver, который при необходимости обращается к иерархии DNS-серверов.

Частые record types:

  • A - IPv4 address;
  • AAAA - IPv6 address;
  • CNAME - alias;
  • MX - mail servers;
  • TXT - текстовые данные и verification;
  • NS - authoritative name servers.

Ответ имеет TTL, поэтому изменения DNS распространяются не мгновенно: разные resolvers могут хранить старое значение до истечения cache.

DNS только помогает найти сетевой адрес и другие records. Он не устанавливает HTTP connection и не выполняет redirect страницы. После resolution client еще должен соединиться с нужным endpoint и выполнить protocol приложения.

Для frontend-разработки DNS важен при настройке domains, CDN, certificates, CORS и диагностике ситуации, когда domain уже изменен, но часть users видит старый address.

Что такое socket?

Короткий ответ

Socket - программная абстракция network endpoint. Через socket process отправляет и получает bytes или datagrams.

Полный ответ

Socket является объектом ОС, через который приложение работает с network stack. Он связан с protocol, local endpoint и, для установленного соединения, remote endpoint.

Для TCP listening socket принимает новые connections. После accept ОС создает отдельный connected socket, через который server обменивается ordered byte stream с конкретным client.

UDP socket отправляет и принимает отдельные datagrams без обязательного постоянного connection. UDP не гарантирует delivery, order или отсутствие duplicates на уровне protocol.

Socket API лежит ниже HTTP и WebSocket. WebSocket - application protocol с handshake и frames, который обычно работает поверх TCP socket. Эти понятия нельзя использовать как синонимы.

Приложение должно учитывать partial reads/writes, buffering, timeouts, closed connections и resource cleanup. То, что write принял данные в local buffer, не всегда означает, что remote application уже их обработало.

Почему `npm run dev` запускает сервер?

Короткий ответ

npm run dev выполняет script dev из package.json. Обычно этот script запускает dev server framework или build tool.

Полный ответ

npm не имеет встроенного универсального dev server. Он находит запись:

Кодпример
{
  "scripts": {
    "dev": "vite"
  }
}

и запускает указанную command в shell. На время script npm добавляет node_modules/.bin в PATH, поэтому локально установленный vite, astro или другой binary доступен без полного пути.

Dev server является обычным process. Обычно он:

  • bind-ится к port;
  • отдает HTML, JavaScript и assets;
  • наблюдает за files;
  • запускает incremental rebuild;
  • сообщает browser об изменениях через WebSocket;
  • выполняет HMR или reload;
  • иногда proxy requests к backend.

Это development tooling, а не production server по умолчанию. Production flow обычно сначала создает optimized build, а затем размещает static files на CDN/web server или запускает специально настроенный application server.

Почему закрытие вкладки браузера не всегда останавливает dev server?

Короткий ответ

Вкладка браузера и dev server - разные процессы. Вкладка является client, а server продолжает работать, пока не завершен его process.

Полный ответ

Browser tab только подключается к dev server по HTTP и, возможно, WebSocket. При закрытии вкладки ее connections закрываются, но server process остается запущенным в terminal, IDE, container или background session.

Чтобы остановить foreground process в terminal, обычно отправляют SIGINT через Ctrl+C. IDE может иметь отдельную кнопку stop. Если process был запущен через &, nohup, tmux, process manager или service manager, закрытие terminal также может его не завершить.

Это объясняет частую ошибку EADDRINUSE: старый server все еще слушает port, хотя вкладка браузера уже закрыта.

Server может заметить disconnect конкретного client и освободить связанные ресурсы, но отсутствие clients не означает, что process обязан завершиться. Он продолжает watch files и ждать новые connections.