Последние недели я размышляю о низкоуровневом программировании. Читаю, изучаю, анализирую. Это видео стало крайней точкой, и я решил написать эту статью.
Описание проблемы
Я получил профильное техническое образование. В моей стране это бакалавриат компьютерной инженерии. Формально, я должен знать как низкий, так и высокий уровень. Но в связи с личной наклонностью к высокому уровню, со СДВГ (можете прочесть здесь), низкий уровень вводит меня в уныние.
Сегодня, на закате 2025 года, до сих пор можно встретить тех, которые советуют начинающим изучать программирование с C/C++, когда даже те желают заниматься беком. Есть те, которые получают профильное образование, разбираются с внутренностями компьютера, изучают алгоритмы и структуры данных. А есть те, которые программируют. Без универа, без технических знаний, и создают величайшее искусство, даже понятия не имея, что такое бинарный поиск.
Эволюция
Я долго пытался решить для себя, кто же прав. Пытался нащупать центр проблемы. И мне кажется, что я нашел, а центром является эволюция. Программирование эволюционирует. И это касается не лишь языков или парадигм, но и вообще взгляда на него. 30 лет. Много или мало? Еще 30 лет назад, чтобы считаться хорошим программистом, вам обязательно было чуть ли не иметь машинный код своим родным языком, болтая с процессором на кухне за чашкой чая.
И наследие неизбежно. Есть программисты, которые начали свою деятельность достаточно давно. А еще, преподаватели. Те самые, которые застали все то время, и сегодня говорят: Hello World в одну строку? Не, дорогой, что-то тебя не в ту степь понесло. Ты сначала разберись с регистрами, а потом будешь на текст в консольке облизываться.
Да, я утрирую. Но ведь доля истины в этом есть?
Есть книжка небезызвестного в нашем кругу Страуструпа - "Программирование: принципы и практика использования C++". В этой книге автор резко негативно высказывается о желающих просто заниматься логикой, без погружения в технические детали (ВАЖНО! Это моя оценка его отношения).
Языкам программирования на развитие требуется некоторое время. 15 лет назад Python был эдаким языком энтузиастов. 10 лет назад он зашевелился, а сегодня Google имеет принцип: "Python там, где это возможно, C++ там, где вынуждены." Пока Python/Java/C# развивались, C++ себе был и использовался даже для небольших прикладных программ.
Как стать инженером?
Я делю тех, которые занимаются программированием, на 2 типа по виду деятельности, мышлению, знаниям и опыту: программисты (инженеры) и разработчики. Инженеры занимаются разработкой системного ПО: ОС, драйверы, инструменты, которые применяются разработчиками (библиотеки, API, движки).
Разработчики берут инструменты, созданные инженерами, и творят с их помощью.
Как писали в комментариях к видео, ссылка на которое было в начале, суть которых сводится к тому, что если рассматривать изучение программирования как таковое, которое начинать необходимо с низкого уровня, то "если ты хочешь открыть обувной магазин, ты должен сначала вырастить корову. Затем научиться выделывать кожу, а потом шить обувь. Создание своего велосипеда нужно начинать со сталелитейной компании. Ведь понимание того как создаются материалы поможет сделать материалы более высокого качества".
Я не говорю, что понимание низкого уровня плохо. Нет. Но начиная с низкого уровня, до решения реальных задач нужно потратить... А сколько же времени нужно потратить?
Бинарный поиск в книжках объясняется на логарифмах. Изучить и понять логарифмы несложно. Но:
Для хеш-функций и криптографии требуется теоретико-числовая арифметика и абстрактная алгебра;
Для эллиптической криптографии требуются конечные поля и теория групп;
Для оптимизации запросов в БД требуются теория графов, статистика и линейное программирование;
Для обучения моделей ML требуются математический анализ, линейная алгебра и теория оптимизации;
Для компьютерного зрения требуются проективная геометрия и вариационные методы;
Для компиляторов требуются формальные языки, автоматы и теория графов...
Одни хорошо учились в школе и могут осилить более сложную математику. Но и есть иные, которые дрожат от деления (особенно с дробями), которые не знают или вернее забыли математику даже на уровне начальной школы, которые не могут двигаться вперед без конкретных ответов. Не верите, что такие бывают? Я перед вами. И что нам делать? Потратить лет пять на изучение базы и тогда приступать к низкому уровню?
А для чего, когда есть библиотеки, разработанные гениями инженерной мысли? Когда есть открытый код, который постоянно оптимизируется? Когда есть языки с управляемым кодом, от которых не ожидаешь неопределенного поведения?
Знаю, что могут быть те, которые скажут: ваши пайтоны и сишарпы непроизводительны, и говорить не о чем. О C# я даже говорить не стану, Roslyn отвечает за меня. О Python, да, есть проблемы, не позволяющие создавать свои движки из-за несовместимости glue code и игровых циклов. Да и то я не уверен, если это нельзя решить, поскольку есть векторизация с помощью NumPy.
Итоги
Каждый должен заниматься своим делом. Мне нравится заниматься логикой приложения, не отвлекаясь на несущественное. Почему несущественное? Потому что я своими руками могу навредить больше, чем эффективно, что обеспечит управляемый код. Это существенно.
Меня такой подход пока устраивает. При том что вопреки некоторым мнениям крупные компании вполне охотно нанимают таких разработчиков, взять тех же Blizzard (как же как же, глядел я их вакансии, миленько). Сегодня рынку важен time to market, то есть, рынку все равно, если вы 10 лет будете писать свой низкоуровневый фундамент, результат нужен здесь и сейчас.
Правда откровенно говоря, иногда от незнания неуправляемых яп страдаю. Недавно столкнулся с ситуацией, когда на C/C++ были обертки, решающие определенные задачи в пару строк кода, когда на Python лишь низкоуровневые реализации. Но совместить это так и не смог, но это совсем иная история...
Поделитесь в комментариях вашим отношением к теме, затронутой в данной статье. Я с уважением отношусь к инакомыслию и признаю, что могу ошибаться.