Как работает компьютер (минимум теории)
Процессор, память, файлы — и почему Go быстрее Python
Прежде чем написать первую программу на Go, давайте разберёмся, что вообще происходит внутри компьютера, когда вы запускаете программу. Это не «скучная теория ради теории» — это фундамент, который поможет вам понимать, почему код работает именно так, а не иначе. Мы разберём три вещи: из чего состоит компьютер, как ваш текстовый код превращается в работающую программу и почему Go считается быстрым языком.
🖥 Компьютер на пальцах: процессор, память, диск
Представьте себе кухню. Повар — это процессор. Разделочный стол перед ним — это оперативная память. А холодильник в углу — это жёсткий диск (файловая система). Эта простая аналогия объясняет почти всё, что вам нужно знать о внутреннем устройстве компьютера на этом этапе.
Давайте разберём каждый элемент подробнее.
Процессор (CPU) — повар на кухне
Процессор — это «мозг» компьютера. Он умеет делать ровно одно: выполнять команды. Очень-очень быстро — миллиарды команд в секунду. Но каждая отдельная команда предельно простая: сложить два числа, сравнить одно число с другим, переместить кусочек данных из одного места в другое. Представьте повара, который невероятно быстро режет, мешает, кладёт ингредиенты — но каждое его действие элементарно. Сложное блюдо получается не потому, что одно действие сложное, а потому что простых действий очень много и они идут в правильном порядке. Точно так же работает программа: тысячи простых инструкций, выстроенных в нужной последовательности, дают сложный результат.
Оперативная память (RAM) — разделочный стол
Оперативная память — это рабочее пространство, где процессор хранит данные, с которыми работает прямо сейчас. Почему не хранить всё на диске? Потому что оперативная память в сотни раз быстрее. Вернёмся к аналогии с кухней: повару удобнее резать овощи на столе прямо перед собой, а не бегать каждый раз к холодильнику за каждой морковкой. Стол ограничен по размеру (обычно 8-16 гигабайт в современном компьютере), но зато доступ к нему мгновенный. Когда вы выключаете компьютер, оперативная память очищается — всё, что на «столе», исчезает. Поэтому важные данные хранят на диске.
Жёсткий диск (файловая система) — холодильник
Диск — это долговременное хранилище. Здесь лежат ваши файлы: документы, фотографии, музыка, программы. Всё, что вы сохраняете, попадает сюда. Диск работает медленнее оперативной памяти, но зато он гораздо больше (сотни гигабайт или терабайты) и не теряет данные при выключении. В нашей аналогии это холодильник: еды в нём помещается много, она там хранится долго, но чтобы что-то достать, нужно встать и дойти до него. Файловая система — это способ организации данных на диске: папки, вложенные папки, файлы с именами. Как полки и контейнеры в холодильнике, которые помогают быстро найти нужный продукт.
Вот и вся архитектура, которая нам нужна. Когда вы запускаете любую программу (браузер, мессенджер, игру), происходит следующее: файл программы лежит на диске. Операционная система загружает его в оперативную память. Процессор начинает выполнять инструкции одну за другой. Программа работает, пока вы её не закроете — тогда память освобождается. Это базовый цикл, который повторяется каждый раз.
📝 Исходный код, компилятор и исполняемый файл
Теперь самый важный вопрос: откуда берутся программы? Как текст, который пишет программист, превращается в работающее приложение?
Всё начинается с исходного кода. Исходный код — это текст, написанный на языке программирования. Обычный текстовый файл, который можно открыть в блокноте. Вот, например, простейшая программа на Go:
package main
import "fmt"
func main() {
fmt.Println("Привет, мир!")
}
Это просто текст. Набор букв и символов. Компьютер не может выполнить его напрямую, потому что процессор не понимает слова func, import или Println. Процессор понимает только машинный код — последовательности нулей и единиц, которые напрямую управляют электрическими сигналами внутри чипа.
Между вашим текстовым файлом и работающей программой стоит посредник — компилятор.
Компилятор — это специальная программа, которая читает ваш исходный код и переводит его в машинный код, понятный процессору. Представьте переводчика: вы написали письмо на русском языке, а переводчик превратил его в текст на языке, который понимает получатель. Компилятор делает то же самое — переводит с языка Go (понятного вам) на машинный язык (понятный процессору).
Результат работы компилятора — исполняемый файл. Это тот самый файл, который можно запустить двойным кликом (на Windows у таких файлов расширение .exe). Внутри него — машинный код, готовый к выполнению процессором. Этот файл самодостаточен: чтобы его запустить, не нужен ни компилятор, ни исходный код, ни даже установленный Go. Вы можете скопировать его на другой компьютер и запустить.
Давайте посмотрим на весь путь от кода до работающей программы:
Шаг 1. Вы пишете исходный код в текстовом файле (например, main.go)
Шаг 2. Запускаете компилятор Go командой go build main.go
Шаг 3. Компилятор проверяет ваш код на ошибки. Если нашёл — сообщит вам, и исполняемый файл не появится
Шаг 4. Если ошибок нет — компилятор создаёт исполняемый файл (например, main или main.exe)
Шаг 5. Вы запускаете этот файл, и программа работает
💡 Важный момент: компилятор — ваш первый помощник. Он не просто переводит код, он проверяет его. Если вы допустили ошибку — написали команду с опечаткой, забыли закрыть скобку, использовали переменную, которую не создавали — компилятор сообщит об этом ещё до запуска программы. Это огромное преимущество, и мы подробнее обсудим его ниже.
Обратите внимание: компиляция происходит один раз. После того как исполняемый файл создан, вы можете запускать его сколько угодно раз — быстро, без задержек, без необходимости каждый раз «переводить» код заново. Это как перевести книгу один раз и затем давать готовый перевод любому читателю, вместо того чтобы каждый раз вызывать переводчика.
⚡ Компилируемые vs интерпретируемые языки
Теперь мы подошли к одной из ключевых тем, которая объясняет, почему Go работает быстрее, чем, скажем, Python. Дело в том, что языки программирования делятся на два больших лагеря по способу выполнения кода: компилируемые и интерпретируемые.
Мы уже знаем, как работает компилируемый язык: вы пишете код, компилятор целиком переводит его в машинный код, и получается исполняемый файл. Go — компилируемый язык. C, C++, Rust — тоже.
Интерпретируемые языки работают иначе. У них нет этапа компиляции в привычном смысле. Вместо этого есть программа-интерпретатор, которая читает ваш исходный код строчка за строчкой и тут же выполняет каждую строку. Python — интерпретируемый язык. JavaScript, Ruby, PHP — тоже (с оговорками, но для нашего уровня так).
Давайте используем аналогию, чтобы прочувствовать разницу.
Компилируемый язык — перевод книги
Представьте, что вам нужно прочитать книгу, написанную на иностранном языке. Компилируемый подход: вы отдаёте книгу профессиональному переводчику. Он сидит неделю, тщательно переводит всю книгу целиком, проверяет каждое предложение, исправляет неточности. Через неделю вы получаете готовый перевод на русском языке. Теперь вы можете читать его сколько угодно раз, моментально, без переводчика. Перевод сделан один раз и навсегда.
Интерпретируемый язык — синхронный переводчик
Другой подход: вы садитесь рядом с переводчиком, и он переводит вам книгу вслух, предложение за предложением. Вы слышите перевод сразу, без ожидания. Но есть цена: каждое предложение переводится «на лету», и если вы захотите перечитать книгу — переводчик должен будет переводить всё заново с самого начала. И скорость чтения ограничена скоростью переводчика.
Теперь становится понятно, почему компилируемые языки быстрее. Когда вы запускаете программу на Go, процессор выполняет уже готовый машинный код — никакого «перевода» в момент запуска не происходит. А когда вы запускаете программу на Python, интерпретатор должен каждый раз читать текст вашего кода, разбирать его, понимать, что вы имели в виду, и только потом выполнять. Эта дополнительная работа занимает время.
Насколько именно Go быстрее Python? В зависимости от задачи — от 10 до 100 раз. Это не абстрактные цифры: если программа на Python обрабатывает данные 10 секунд, аналогичная программа на Go может справиться за 0.1-1 секунду. Для некоторых задач это критически важно.
Но было бы нечестно сказать, что компилируемые языки лучше во всём. У каждого подхода есть свои плюсы и минусы.
Преимущества компилируемых языков (Go, C, Rust)
Скорость работы. Программа выполняется максимально быстро, потому что машинный код уже готов.
Раннее обнаружение ошибок. Компилятор проверяет код до запуска. Многие ошибки вы увидите ещё до того, как программа начнёт работать. Это экономит часы отладки.
Самодостаточность. Исполняемый файл не требует ничего для запуска — ни среды выполнения, ни установленного языка на компьютере пользователя.
Преимущества интерпретируемых языков (Python, JavaScript, Ruby)
Быстрый старт. Не нужно ждать компиляции — написал строку, сразу запустил и увидел результат. Это удобно для экспериментов и обучения.
Гибкость. Код можно менять «на лету», без перекомпиляции всего проекта.
Кроссплатформенность. Один и тот же код работает везде, где установлен интерпретатор, без необходимости компилировать отдельно под каждую систему.
💡 Интересный факт: Go компилируется невероятно быстро по меркам компилируемых языков. Пока программа на C++ компилируется минутами, Go собирает проект за секунды. Создатели Go специально сделали это одним из приоритетов — они хотели дать разработчикам скорость выполнения компилируемого языка и при этом комфорт, близкий к интерпретируемым языкам. Это одна из причин, почему Go так популярен.
🎯 Как это всё связано с Go
Давайте соединим все кусочки вместе и посмотрим, что происходит, когда вы пишете и запускаете программу на Go.
Вы открываете текстовый редактор и пишете исходный код — обычный текстовый файл с расширением .go. Этот файл лежит на диске вашего компьютера. Затем вы вызываете компилятор Go. Он загружается в оперативную память, читает ваш файл, проверяет его на ошибки и создаёт исполняемый файл — тоже на диске. Когда вы запускаете этот файл, операционная система загружает его в оперативную память, и процессор начинает выполнять машинные инструкции одну за другой.
Видите, как все три компонента (процессор, память, диск) участвуют в этом процессе? Вот для чего нужна была теория из начала урока — теперь вы понимаете полную картину.
А если бы вы писали на Python? Тогда вместо компиляции вы бы запускали интерпретатор Python, который загрузился бы в память и начал читать ваш исходный код строка за строкой. Никакого отдельного исполняемого файла не появилось бы. И при каждом запуске интерпретатор «переводил» бы код заново.
Вот краткое сравнение двух подходов на практике:
Запуск программы на Go:
go build main.go # компиляция (1-2 секунды) → создаёт файл main
./main # запуск (мгновенно)
Запуск программы на Python:
python main.py # интерпретация + выполнение (каждый раз заново)
На первый взгляд Python выглядит проще: одна команда вместо двух. И для маленьких скриптов это действительно удобно. Но когда проект растёт до тысяч строк кода и обрабатывает миллионы запросов, разница в скорости становится решающей. Именно поэтому крупные компании — Google, Uber, Twitch, Dropbox — используют Go для своих серверов и сервисов, где важна каждая миллисекунда.
💡 Подсказка: Go ещё умеет делать кросс-компиляцию — вы можете сидеть на Mac и скомпилировать программу для Windows или Linux одной командой. Исполняемый файл получится готовый к запуску на целевой системе, без установки Go на ней. Это очень удобно для распространения программ.
🔄 Путь программы: от идеи до результата
Подведём итог этого урока, проследив полный путь программы от задумки до работающего приложения. Это важная ментальная модель, которая будет сопровождать вас на протяжении всего курса.
1. Идея. У вас есть задача, которую нужно решить. Допустим, вы хотите написать программу, которая считает, сколько дней осталось до вашего дня рождения.
2. Исходный код. Вы открываете редактор кода и пишете решение на языке Go. Это обычный текстовый файл, который и вы, и другой программист можете прочитать и понять. Исходный код — это ваши инструкции компьютеру, записанные в понятной для человека форме.
3. Компиляция. Компилятор Go берёт ваш файл и превращает его в машинный код. Попутно он проверяет, нет ли ошибок. Если вы где-то опечатались или написали логически противоречивый код, компилятор остановится и покажет, где именно проблема. Это как строгий, но справедливый учитель, который проверяет вашу работу перед сдачей.
4. Исполняемый файл. Результат компиляции — файл, который можно запускать. Внутри него — команды, понятные процессору. Этот файл можно скопировать на любой совместимый компьютер и запустить.
5. Выполнение. Операционная система загружает программу с диска в оперативную память. Процессор начинает выполнять инструкции. Программа работает — считает дни, выводит результат на экран, и завершается. Память освобождается.
📋 Итоги урока
- Процессор — выполняет команды (миллиарды в секунду, но каждая простая)
- Оперативная память — быстрое временное хранилище для данных, с которыми работает процессор прямо сейчас
- Диск (файловая система) — медленное, но долговременное хранилище файлов и программ
- Исходный код — текст программы, написанный программистом на понятном человеку языке
- Компилятор — переводит исходный код в машинный код и попутно проверяет ошибки
- Исполняемый файл — готовая программа, которую можно запустить без компилятора
- Go — компилируемый язык: код компилируется один раз, потом выполняется максимально быстро
- Python — интерпретируемый язык: код «переводится» заново при каждом запуске, поэтому работает медленнее
- Go в 10-100 раз быстрее Python, при этом компилируется за считанные секунды
В следующем уроке мы перейдём от теории к практике — установим Go и редактор кода на ваш компьютер, настроим рабочее окружение и напишем свою первую программу. Вы своими руками пройдёте тот самый путь: исходный код, компиляция, исполняемый файл, запуск. До встречи в уроке 1.3!