Python, Go, Rust, Java или другие? Какой язык программирования следует изучать именно сейчас: рекомендуют айтишники
Какой язык программирования лучше учить, чтобы стать востребованным специалистом? Множество стеков и технологий усложняют выбор будущих айтишников. Поэтому мы решили спросить у опытных программистов о том, какой язык программирования сейчас самый перспективный. Мы собрали около 100 ответов, однако аргументировали свой выбор только часть респондентов. Упомянули множество технологий — Go, Ruby, Java, PHP, C#, Python и другие. Поскольку аргументированными были не все ответы, публикуем интересные аргументы айтишников из нашего опроса. Напомним, мы спросили айтишников, какой язык программирования они считают самым перспективным и попросили обосновать свой ответ.
Программистам понравился любимый язык хакеров. Rust пошел в гору, популярность Python и Java под угрозой
Язык программирования Rust все больше нравится разработчикам ПО. Количество тех, кто пишет на нем, растет, как и его общемировая популярность, на что указывают различные рейтинги и опросы. Но путь к первой пятерке у Rust будет очень тернистым – многие программисты считают его слишком сложным в освоении, особенно в сравнении с Python, который почти два года лидирует в большинстве рейтингов самых востребованных языков программирования.
Rust в любимчиках
Язык программирования Rust, созданный в 2006 г., стал довольно быстро набирать очки популярности, пишет портал TechSpot. Об этом свидетельствуют результаты опроса сообщества Rust Foundation, развивающего Rust, который проходил в конце 2022 г. и затронул почти 9500 человек.
Более 90% участников опроса Rust Foundation назвали себя «пользователями Rust». Из этой группы людей почти половина (47%) заявили, что пишут на Rust ежедневно, и это на 4 процентных пункта больше, чем годом ранее.
Значительная часть использующих Rust разработчиков (30%) на данный момент умеет писать лишь простой код. Около 42% респондентов назвали высоким свой уровень владения этим языком.
В исследовании Rust Foundation приняли участие руководители проектов и программисты, и на все пункты опроса ответили 82% участников. Это намного больше результатов 2021 г., когда проводился такой же опрос – его тогда завершили лишь 76% респондентов.
Единственное, что удерживает мировое сообщество программистов от массового перехода на Rust — это повышенная сложность его освоения
Сам опрос был доступен на 11 языках, включая английский и упрощенный китайский. Сделано это было для максимального охвата аудитории, потому что не все программисты в мире владеют английским языком. В России, как сообщал CNews, к концу лета 2023 г. потребность в таких разработчиках пошла на убыль.
Rust повсюду
За 17 лет своего существования Rust успел проникнуть во многие крупные программные проекты. Созданный Грейдоном Хоаром (Graydon Hoare), сотрудником Mozilla Research, он нашел свое применение, в том числе, в ядре Linux, браузере Chromium и в ОС Windows, пишет TechSpot. Какие именно компоненты этой ОС созданы на Rust, Microsoft не раскрывает.
Также Rust очень любят использовать авторы вредоносного ПО, но не потому, что в этом языке есть что-то особенное. Они ценят его ничуть не меньше, чем Golang за авторством Google, Dlang или Nim просто потому, что эти языки хоть и на слуху, но все еще являются весьма экзотичными, что усложняет работу экспертам по информационной безопасности. Выявлять опасный софт, написанный на этих языках, сложнее в сравнении с базовым С и С++, в результате чего хакеры не только пишут на них новое ПО, но и переносят на их синтаксис ранее выпущенные программы. Для примера, весь мир в конце 2020 г. будоражило стремительное распространение трояна Buer, написанного на С, но антивирусные решения довольно быстро научились вылавливать и обезвреживать его. Летом 2021 г. появилась его новая версия RustyBuer, которая, как видно из названия, написана на Rust.
До топ-5 еще далеко
О росте популярности Rust среди разработчиков ПО свидетельствует и рейтинг языков программирования компании Tiobe, обновляемый ежемесячно. В июле 2023 г. он расположился на 17 месте, хотя еще годом ранее не входил и в первую 20-ку. Это самый лучший результат за все годы его существования, а наихудшим было 211 место в декабре 2012 г.
Стоит отметить, что Rust дорос до версии 1.0 сравнительно недавно – лишь в 2015 г. Предыдущие девять лет своего существования он был в статусе беты.
В августе 2023 г. Rust опустился в рейтинге Tiobe на 18 строчку. Откат на фоне предыдущего месяца незначительный, особенно в сравнении с августом 2022 г., когда этот язык занимал 22 место. Сейчас впереди него не только постоянные «жители» топ-5 в лице Python, Java, C, C++ и C#, но и очень древние языки программирования, пик популярности которых пришелся едва ли не на середину XX века – COBOL и Fortran. Первый появился в 1959 г., а второй – двумя годами ранее.
Негативные факторы
Добраться до первого места, например, в рейтинге Tiobe, языку Rust, с высокой долей вероятности, будет непросто. С октября 2021 г. в этом списке лидирует Python, основное конкурентное преимущество которого – невероятно низкий порог входа. Разобраться в нем и начать писать простые программы сможет даже закоренелый гуманитарий, о чем свидетельствует популярность и многочисленность экспресс-курсов по изучению этого языка.
Как осуществлять техподдержку после ухода западных вендоров? Опыт «Мобиус Технологии»

Опрос Rust Foundation показал, что овладеть базовыми знаниями Rust, в отличие от Python, за пару недель не получится. 30% респондентов указали трудность освоения в качестве основной причины отказа от дальнейшего использования Rust и перехода на другой язык.
Согласно результатам исследования, некоторые разработчики программного обеспечения по-прежнему считают Rust слишком сложным для создания крупных проектов и дальнейшего их развития. Больше четверти респондентов (26%) также выразили обеспокоенность по поводу будущей поддержки своих проектов на Rust.
Считаете, что Python лучше всех? Просто вы не имели дело с Rust
“Технологии прошлого спасут будущее от себя самого”, — так Грэйдон Хор, создатель Rust, пояснял, чего хотел достичь.
Одна их ключевых черт Rust — использование технологий, хорошо знакомых академической среде, но редко применяемых в современных языках программирования. Старые, надёжные и иногда забытые технологии, но, прежде всего, крайне хорошо работающие.
Эти технологии используются в основном для одной цели: безопасность.
Звучит скучно? Нет, если вы спросите у сообщества. Согласно опросу StackOverflow, с 2016 года впечатляющие 86,1% разработчиков на Rust предпочитают этот язык остальным, что делает его самым любимым языком уже пятый год подряд.
Бытует мнение, что разработчики программного обеспечения — одни из самых прогрессивных людей на этой планете. Однако Rust является полной противоположностью мантре “действуй быстро и всё ломай”. Тем не менее, любой разработчик почти наверняка изучит концепции, о которых никогда не слышал ранее.
От новизны системного программирования для некоторых разработчиков над алгебраическими типами данных до собственного подхода Rust к безопасности памяти — каждый может найти что-то новое и крайне полезное для изучения. Столько причин полюбить Rust!
Более безопасный доступ к памяти без сборки мусора
Безопасное и эффективное управление памятью компьютера является одной из самых сложных задач для любого языка программирования. В Python, например, есть сборщик мусора, который постоянно ищет неиспользуемую память и очищает её в процессе работы программы.
В других языках, таких как C и C++, программисты должны явно выделять и освобождать память в процессе работы. Поскольку проблемы, связанные с памятью, устраняются до запуска программы, этот подход лучше с точки зрения оптимизации производительности.
С другой стороны, память — это ещё одна вещь, о которой разработчикам приходится думать постоянно. Это одна из причин, по которым написание программы на C занимает больше времени, чем на Python, даже если результат в итоге одинаков.
Rust идёт альтернативным путём: память распределяется через систему владения на этапе компиляции. Это отличный способ добиться очистки неиспользуемых данных без необходимости постоянно помнить о выделении и освобождении памяти.
По сути, владение — это совокупность трёх правил:
- У каждого значения в Rust есть переменная, называемая владельцем.
- Единовременно может быть только один владелец.
- Когда владелец выходит за пределы области видимости, значение теряется, а память освобождается.
Простой пример присвоения вектора в Rust:
fn main() <
let a = vec![1, 2, 3];
let b = a;
println!("a: ", b);
>
На второй строчке создаётся вектор [1, 2, 3] с владельцем a , затем владение переходит к b . Поскольку верный владелец вызывается в операторе печати, при выполнении программа компилирует и возвращает ожидаемый результат:
a: [1, 2, 3]
С другой стороны, можно попробовать вызвать вектор с предыдущим владельцем, a :
fn main() let a = vec![1, 2, 3];
let b = a;
println!("a: ", b, a);
>
В этом случае компилятор выбросит ошибку, потому что a был отброшен в третьей строчке. Здесь намного больше тонкостей, но основная идея такова.
Python же будет работать во втором случае. Его сборщик мусора отбросит a только после последнего вызова, что удобно для разработчика, но невыгодно с точки зрения объёма памяти.
В C всё будет несколько сложнее: вам нужно выделить место в памяти для a , затем поставить указатель на вектор, потом выделить больше места в памяти для b , перенаправить b на a , и, наконец, освободить пространство, занимаемое a и b , когда вы закончите.
С этой точки зрения подход Rust к работе с памятью — это компромисс между скоростью разработки и производительностью. Хотя писать на нём не так легко, как на Python, Rust не настолько неуклюж, как C, если вы хорошо понимаете концепцию владения.
С другой стороны, его эффективность поразительна: команде разработчиков Tilde, например, удалось сократить использование памяти на 90 процентов после того, как они переписали часть JavaHTTP на Rust.
Приятная статическая типизация
Между сторонниками динамической и статической типизаций существует длительная вражда. Хотя создавать программное обеспечение проще на языках с динамической типизацией, код довольно быстро становится трудно поддерживать. И это одна из причин, почему код на Python может быть довольно сложным в обслуживании, в сравнении с тем же C.
С другой стороны, необходимость объявлять тип каждой переменной в C раздражает. Если вы когда-либо пытались использовать double в функции, которая возвращает тип float в C, вы поймёте, о чем речь.
Rust выбирает срединный путь: это система статического типа, но от разработчика требуется определять типы только аргументов высшего уровня, таких как аргументы функции и константы. Внутри тел функций допускается вывод типов в стиле Python.
Одна особо полезная фича Rust — наличие типа None . Она позволяет обрабатывать исключения на этапе компиляции, следовательно, программа гарантированно работает без сбоев для конечного пользователя. Взгляните на этот пример, где мы можем получить полное имя человека независимо от того, есть ли у него второе имя:
fn get_full_name(fname: &str, mname: Option, lname: &str) -> String <
match mname Some(n) => format!("<> <> <>", fname, n, lname),
None => format!("<> <>", fname, lname),
>
>fn main() println!("<>", get_full_name("Ronald", None, "McDonald"));
println!("<>", get_full_name("Dwight", Some("P."), "Eisenhower"));
>
Хотя версии обходного решения None существуют и в других языках, оно демонстрирует амбиции Rust: не усложнять процесс написания кода, сохраняя при этом его надёжность и удобство в поддержке.
Изящный подход к системному программированию
В то время как Python — язык программирования общего назначения, Rust, как и C, определённо предназначен для системного программирования. И хотя Rust не идеальный язык для создания приложений для конечных пользователей, он прекрасно подходит для разработки частей ПО, предоставляющих сервисы другим программам.
Таким образом, эффективность заложена в основу Rust. Лучшей демонстрацией этого являются абстракции с нулевой стоимостью, интерпретирующие код при минимальном использовании памяти. Как сказал Бьёрн Страуструп, создатель C++: “Вы не платите за то, что не используете. Вы используете то, что уже написано в коде”.
Например, рассмотрим добавление всех целых чисел до 1000 в Python:
sum(range(1000))
Этот код выполняет 1000 итераций и дополнений при каждом запуске — это значительно замедляет его выполнение. Сравним с Rust:
(0..1000).sum()
Этот код компилируется до постоянной 499500 . Использование памяти сокращается в 1000 раз.
Хотя эти абстракции существуют и в C, Rust также активно их использует, а одна из его целей — добавить в язык как можно больше абстракций с нулевой стоимостью. С этой точки зрения, Rust — это C следующего уровня.
C существует более 40 лет, и Rust стремится к тому же, уделяя особое внимание обратной совместимости. Даже сейчас всё ещё можно запустить код, написанный на Rust 1.0. И точно так же написанный сегодня код можно будет запустить двадцать лет спустя. Rust не ржавеет!
Небольшое, но восхитительное сообщество
Учитывая особое внимание Rust к безопасности и самодостаточности, неудивительно, что Dropbox переписал большую часть основной структуры на Rust. Разработчики из Mozilla, первого большого спонсора этого языка, написали на нём жизненно важные части Firefox. Microsoft признал C и C++ не безопасными для критически важного ПО и всё больше инвестирует в Rust.
Так происходит не только в крупных корпорациях — любовь к Rust свойственна и отдельным разработчикам. Несмотря на то, что его используют только 5% разработчиков, они относятся к языку с огромным энтузиазмом.
И тому есть причины. Хорошо продуманы не только спецификация языка и компилятор. У Rust есть rustup для установки и управления пакетами инструментальных средств. Есть Cargo, инструмент командной строки, поставляемый с каждой установкой Rust и помогающий управлять зависимостями, запускать тесты и создавать документацию.
Существует crates.io, где пользователи могут делиться библиотеками, и docs.rs , где они документируются. Есть проверки компилятора от Clippy и автоматическое форматирование от rustfmt.
Помимо этого, существуют официальные и неофициальные чаты, субреддиты, пользовательские форумы, вопросы на StackOverflow и конференции по всему миру. Чего ещё желать в сообществе, которое ставит во главу угла дружелюбие?
Минусы: необходимость бежать, прежде чем вы научитесь ходить
Одна из демотивирующих вещей в Rust — высокий порог входа. В то время как для начала продуктивной работы с большинством языков требуется 1–2 дня, для Rust скорее всего потребуется одна или две недели.
Это связано с необходимостью осваивать множество новых концепций, не используемых другими языками, а также с тем фактом, что во время компиляции возникает множество ошибок. Все исключения потребуется обрабатывать сразу, вы не сможете просто написать работающий код и добавить их позже, как в том же Python.
Вдобавок, поскольку Rust всё ещё довольно нов, в нём есть не все библиотеки, которые могут понадобиться. Помимо официальной документации и различных вопросов на StackOverflow, существует не так много руководств.
Хорошая новость заключается в том, что как только вы изучите концепции и скомпилируете программу, всё пойдёт как по маслу. Кроме того, благодаря обратной совместимости, программы будут работать и через двадцать лет.
Учитывая устойчивость кода и тот факт, что Rust поддерживается рядом крупных корпораций, стоит потратить на его изучение одну-две недели, не взирая на недостатки.
Итоги: осваивайте без страха
Rust более чем безопасен: многие из его основных концепций направлены на то, чтобы устранять утечки памяти и другие проблемы безопасности. В эпоху, когда всё решает программное обеспечение, безопасность обязательна.
Для каждого развивающегося языка, вероятно, найдётся место: Go всё больше и больше заполняет пространство Python и Java, Julia наступает на пятки Python в науке о данных, а Rust растёт в области Python и C++. Что делает Rust особенным, так это впечатляющее сообщество, инновационные функции и тот факт, что он рассчитан на многолетнюю работу.
Конечно, многое ещё предстоит сделать, и только часть работы может быть выполнена на Rust. У современных языков есть все шансы закрепиться на некоторое время, даже если в ближайшие годы появятся другие новинки. Но если бы пришлось делать ставки на один язык, то Rust был бы беспроигрышным вариантом.
- Замыкания в Rust
- Диагностика кода на Rust
- Импорт в Python
Предыстория
Поскольку я буду выражать собственное мнение о том, “почему не Python”, немного расскажу о себе. 4 месяца назад я уволился с последнего места работы и сейчас являюсь соучредителем компании MotivEdge. Наиболее часто используемым мной языком программирования был Python, так как я в основном разрабатывал бэкенд Django и скрипты ROS на Python. Я начал изучать этот язык около 10 лет назад и сразу же полюбил его, поскольку, в отличие от C ++ или Java, он давал мне ощущение “свободы”.
Кроме того, я использовал довольно много пакетов, связанных с машинным обучением/анализом: PyTorch , numpy , pandas , scikit-learn , jupyter и другие. Эти пакеты впечатляли своим удобством и простотой в использовании.
Но теперь я переключаюсь на Rust, так как Python стал доставлять мне слишком много проблем при разработке больших проектов. Теперь обо всем по порядку.
Истоки проблем с Python
1. Обезьяний патч
Monkey patch (обезьяний патч) — это способ расширить или изменить код среды выполнения динамических языков без изменения оригинального исходного кода.
Эта функция дает разработчику большую свободу, позволяя править код, чтобы заставить его работать. Самым показательным примером использования обезьяньего патча является написание тестов, с которыми мы не можем справиться “корректно” во время выполнения.
Но эта функция слишком динамична и может привести к непредсказуемым ошибкам, если программист не будет достаточно внимателен. Например, иногда переменной с одинаковым именем могут быть присвоены два разных типа. Подобные “отклонения” в поведении кода происходят, когда проект растет и никто не может запомнить всех имен использованных переменных. Члену команды, не посвященному в курс дела, будет трудно понять, “почему код присваивает новый тип”.
2. Типы параметров функций
Эта проблема, как и обезьяний патч, вызвана динамикой языка. Например, у нас есть функция для сложения двух чисел:
def add(num1: int, num2: int) -> int:
return num1 + num2
Но при ее использовании компилятор Python не контролирует тип параметра. Подсказки по проверке типов больше похожи на медвежьи услуги. Можно вызвать функцию, как показано ниже:
add(“123”, 3)
Конечно, это вызовет ошибку. Чтобы добиться выполнения необходимых действий — сложения двух чисел, придется ввести дополнительный код перед возвратом:
def add(num1: int, num2: int) -> int: if type(num1) != int or type(num2) != int: # Обработка ошибок или выявление конкретной ошибки!
raise IntNumberError()return num1 + num2
Теперь код выглядит лучше, так как в нем обработан неправильный тип ввода. Но это чревато дополнительной работой — обновлением тестового кода для обработки ветви if . Добавляются, по крайней мере, еще две функции тестирования: num1 не int и num2 не int .
3. Область видимости
Допустим, у нас есть код:
for i in range(3):
passprint(i)
После выполнения мы видим, что выведено число 2 . Но i должно использоваться только в области видимости цикла for ! Такой неправильный параметр области видимости делает код сложным для сопровождения и отладки.
Для меня это самая запутанная конструкция в Python. Я видел много примеров кода, в котором программист определяет переменную только в области видимости if , но использует эту переменную после выражений if-else .
4. Скорость исполнения
Очевидно, что Python работает медленно. Если программа объемная и сложная, ее выполнение займет больше времени, чем в других языках программирования. Приходится использовать PyPy или другие компиляторы, чтобы немного увеличить скорость.
5. Контролируемость
При передаче в функцию списка list и строки string оба параметра будут работать по-разному. Например, у нас есть код:
def change(lst, st):
lst.append(4)
st = “new string”x = [1, 2, 3]
s = “old string”print(x, s)change(x, s)
print(x, s)
Вывод будет следующим:
[1, 2, 3] old string[1, 2, 3, 4] old string
Как видим, list дополнился новым элементом в конце, но параметр string не изменился. Причина в том, что Python передал в функцию ссылку на list и значение string . Оба параметра работают совершенно по-разному.
Такая особенность иногда сбивает с толку: трудно отследить, где изменилось значение переменной. Это увеличивает время отладки при разработке.
Запуск Rust
Проект Rust стартовал еще в 2010 году. Rust — это мультипарадигмальный высокоуровневый язык программирования общего назначения, разработанный для обеспечения производительности и безопасности, в том числе безопасного параллелизма. Rust не похож на C и C++, которые могут выдавать нулевой указатель. Компилятор помогает автоматически проверять срок службы и владельца переменной. В большинстве случаев, если код скомпилирован на Rust, то это на 80-90% успешный код.
Вот как Rust решил вышеуказанные проблемы Python.
1. Обезьяний патч
Rust — это статический язык программирования. Он не допускает динамических исправлений по методу обезьяньего патча. Во-первых, в нем нельзя назначать разные типы данных для одной переменной. Во-вторых, определенная переменная по умолчанию неизменяема. Если нужно создать изменяемую переменную, необходимо определить ее с помощью явно указанного ключевого слова mut .
2. Типы параметров функций
Как было упомянуто выше, Rust статичен и требует определения типа при передаче параметров функции. Передача некорректных типов вызовет возражение компилятора. В этом языке компилятор помогает устранять потенциальные ошибки, избавляя от применения бесполезного предложения if для проверки типа и сокращая время модульного тестирования. Это значит, что вы можете сосредоточиться на логике и алгоритмах тестового кода.
3. Область видимости
У Rust нет GC (автоматического управления памятью). Он удаляет переменную, когда заканчивается ее срок службы. Тем самым переменная выводится за пределы области видимости. И хотя это не на 100% верно, так как срок службы не то же самое, что область видимости, но для простого кода можно считать, что они совпадают.
Таким образом, компилятор выдаст ошибку, если в коде будет указанная выше переменная i вне цикла:
for i in 0..3 println!(“<>”, i);
>println!(“<>”, i); // Здесь возникает ошибка
4. Скорость исполнения
Совершенно очевидно, что Rust обладает почти такой же скоростью, как C/C++. Один универсальный совет: не забывайте —release при сборке кода. Избегайте этой довольно распространенной “ошибки”.
5. Контролируемость
В Rust много “магии”, но она не сбивает с толку, как в Python. “Магия” здесь заключается в rust-анализаторе и компиляторе. В Rust компилятор является партнером разработчика, помогая устранять потенциальные ошибки при программировании.
“Магия”, наблюдаемая в приведенном выше коде Python, никогда не произойдет в Rust. И на это есть несколько причин.
- При определении функции в Rust необходимо определить тип параметра. Если нужно передать в функцию указатель/ссылку, перед параметром добавляется & .
- Если нужно изменить что-то в параметре при передаче его в функцию, требуется явно определить mut .
- Если ссылка в функцию не передается, то право собственности на параметр переходит к функции. Это означает, что переменная будет “удалена” после вызова этой функции.
Итак, в Rust нет “магии” Python. Мы знаем, как данные передаются и применяются в основном коде и функциях. То, как мы используем переменные или параметры, полностью контролируется нами.
Заключение
Rust моложе, чем Python. Большинство крейтов находятся в стадии разработки. Но сообщество растет и активно действует. Создается много отличных крейтов, многие компании расширяют свою команду Rust.
Я какое-то время программировал на Rust, и мне не просто понравилось — я наслаждался этим процессом. Правда, иногда я чувствовал, что компилятор “убьет” меня из-за слишком большого количества ошибок.
Конечно, мы все еще можем использовать Python и другие языки, поскольку их библиотеки помогают выполнять многие задачи. У Rust может не быть соответствующего крейта. Но почему бы нам не создать его? Давайте внесем свой вклад в Rust!
- Rust: взгляд старого программиста
- Введение в программирование на Rust
- Rust или Си: кто Усэйн Болт в мире программирования?
