В программировании есть понятие, которое одновременно пугает новичков и восхищает опытных разработчиков. Это — рекурсия. Её часто описывают как «функцию, вызывающую саму себя», но за этой фразой скрывается целая философия построения алгоритмов.
Что такое рекурсия простыми словами
В самом широком смысле это — повторение действия внутри самого себя. Представьте два зеркала, стоящих друг напротив друга: в каждом отражении — новое, чуть меньшее, и так до бесконечности. Примерно так работает рекурсивный процесс: функция видит задачу, решает её частично и передаёт оставшуюся часть… самой себе. В программировании рекурсия — это метод решения задач через повторные вызовы одной и той же функции, но с изменёнными аргументами. Каждый вызов приближает программу к «точке останова» — моменту, когда повторения прекращаются.
Интуитивное объяснение
Представьте, что вы стоите между двумя зеркалами, направленными друг на друга. Вы видите цепочку бесконечных отражений, уходящую вдаль. То же самое происходит при рекурсии: функция вызывает саму себя снова и снова — пока не достигнет определённого условия, после чего начинает «возвращаться» обратно.
Ключевые термины
Чтобы понять механику, нужно знать три основных понятия:
-
Рекурсивная функция — функция, которая вызывает сама себя.
-
База рекурсии — условие, при котором процесс прекращается. Без базы программа зациклится.
-
Шаг рекурсии — часть, в которой функция вызывает себя для решения меньшей задачи.
Пример:
Если мы хотим посчитать количество файлов в папке, мы можем пройти по каждому элементу, а если встречаем вложенную папку — снова вызвать ту же функцию. Так программа обходит всю структуру до конца, пока не останется ни одного непроверенного каталога.
Как работает рекурсия в программировании
Это не магия, а строгий механизм. Он строится на стеке вызовов — области памяти, где хранятся активные функции.
Механизм работы
- Функция вызывает сама себя, передавая изменённые аргументы.
- Каждый новый вызов помещается в стек — как карточка поверх другой.
- Когда достигается база рекурсии, функция перестаёт вызывать себя и начинает возвращать результаты «вверх».
База и условие выхода
Главное правило — в каждой рекурсии должна быть точка остановки. Если её нет, программа будет вызывать себя бесконечно, пока не переполнит стек и не завершится с ошибкой (RecursionError в Python).
Прямой и обратный ход
-
Прямой ход — функция вызывает саму себя, углубляясь в задачу.
-
Обратный ход — выполнение идёт назад, собирая результаты из стека вызовов.
Пример псевдокода:
При вызове recurse(3) произойдёт следующее:
- 3 → вызывает recurse(2)
- 2 → вызывает recurse(1)
- 1 → вызывает recurse(0)
- 0 — база рекурсии, возврат 1
- Далее значения перемножаются обратно: 1 * 2 * 3 = 6
Разновидности рекурсии
Понятие классифицируется в зависимости от того, как и где функция вызывает саму себя.
1. Прямая
Функция вызывает саму себя напрямую.
2. Косвенная
Функция А вызывает функцию B, а та снова вызывает функцию А.
3. Линейная и каскадная
-
Линейная — один рекурсивный вызов в теле функции.
-
Каскадная (многоступенчатая) — функция вызывает себя несколько раз.
Пример: вычисление чисел Фибоначчи, где fib(n) = fib(n-1) + fib(n-2).
4. Хвостовая рекурсия (tail recursion)
Особый вид, при котором результат вычислений не зависит от последующих вызовов. Такая форма может быть оптимизирована компилятором — стек не растёт, и программа работает как цикл.
Пример:
Здесь на каждом шаге результат передаётся как параметр (acc), поэтому новые вызовы не накапливаются в стеке.
Отличия от цикла
Преимущества и недостатки
Рекурсия — инструмент мощный, но требующий осторожности. Её плюсы и минусы лучше всего видны при сравнении с итерацией.
Преимущества
-
Краткость и читаемость. Рекурсивные функции лаконичны, особенно в алгоритмах с ветвлениями.
-
Наглядность. Код часто ближе к математической логике и проще для понимания принципа.
-
Естественное решение. Для деревьев, графов или вложенных структур рекурсия логичнее, чем цикл.
Недостатки
-
Переполнение стека. При слишком глубокой рекурсии память заканчивается.
-
Сложность отладки. Ошибка в базе может привести к бесконечным вызовам.
-
Скорость. Рекурсия часто медленнее, чем эквивалентный цикл.
Примеры в программировании
1. Расчёт факториала
Факториал числа n! = 1 × 2 × … × n. Через рекурсию это выглядит максимально просто:
Каждый вызов умножает текущее число на результат следующего, пока не достигнет нуля.
2. Числа Фибоначчи
Каждое число — сумма двух предыдущих: F(n) = F(n-1) + F(n-2).
Вызов fib(5) даст последовательность вызовов:
Результат — 5. Однако это пример неэффективной рекурсии, потому что многие значения вычисляются по нескольку раз. Для ускорения применяют мемоизацию (кэширование результатов).
3. Обход дерева
Рекурсия незаменима при работе с древовидными структурами — файлами, XML, JSON, каталогами.
Каждый узел вызывает ту же функцию для своих потомков, пока дерево не обойдётся целиком.
4. Поиск пути в лабиринте
В играх и алгоритмах навигации рекурсия позволяет искать выход, перебирая соседние клетки:
Каждый шаг вызывает функцию для соседней клетки, пока не найдёт путь.
Баланс между красотой и эффективностью
Опытные разработчики стараются находить компромисс: если задача может быть решена итеративно без потери понятности — выбирают цикл. Если же структура данных сама по себе рекурсивна (например, JSON или дерево DOM), то рекурсивный подход оказывается естественнее и надёжнее.
За пределами программирования
Хотя чаще всего рекурсия упоминается в контексте кода, этот принцип встречается повсюду — от математики до биологии и искусства.
В математике
Рекурсивные формулы описывают последовательности, где каждый элемент зависит от предыдущих: числа Фибоначчи, факториалы, фракталы, степенные ряды. Рекурсивное мышление помогает строить доказательства по индукции — шаг за шагом, от простого к сложному.
В биологии
Природа любит повторения. Форма листа повторяет очертания ветви, а ветвь — всего дерева.
Фрактальная структура лёгких, кровеносных сосудов или береговой линии — это естественные проявления рекурсии.
В гуманитарных дисциплинах
В грамматике: предложение может содержать другое предложение. Например: «Я знаю, что ты знаешь, что он сказал». В литературе — «вложенные истории»: рассказ внутри рассказа. В живописи — отражения, зеркала, повторяющиеся мотивы. В философии — это способ мыслить структурно, когда результат на каждом уровне строится на предыдущем.
Как отлаживать и тестировать рекурсивные функции
Чтобы избежать сбоев, важно понимать, где и почему возникает ошибка.
1. Проверяйте базу рекурсии
Больше половины проблем — из-за отсутствия или неправильной базы. Функция должна всегда иметь условие выхода, которое гарантирует завершение.
2. Тестируйте на простых примерах
Начинайте с минимальных данных (n=0, n=1). Если функция корректно работает для них, можно проверять большие значения.
3. Используйте отладчик IDE
Большинство IDE (PyCharm, VS Code, IntelliJ) позволяют пройти рекурсивный процесс пошагово. Вы увидите, как аргументы меняются при каждом вызове и где цикл заходит в тупик.
4. Контролируйте глубину стека
В Python есть ограничение по умолчанию — около 1000 вызовов. Если рекурсия может быть глубже, нужно: import syssys.setrecursionlimit(3000). Но лучше оптимизировать алгоритм или перейти на итерацию.
5. Используйте вывод логов
Добавьте печать входящих аргументов — иногда простая строка print(n) показывает, где именно «застрял» вызов.
Сценарии выбора
Хорошее правило: если алгоритм можно описать фразой «вызови себя для подзадачи» — рекурсия естественна. А если речь идёт о «повтори то же действие несколько раз» — цикл проще и надёжнее.
Типичные ошибки начинающих программистов
-
Отсутствие условия выхода. Функция уходит в бесконечный вызов и вызывает переполнение стека.
-
Неправильное изменение аргумента. Например, n не уменьшается на каждом шаге.
-
Лишние вычисления. Повторные вызовы с одними и теми же аргументами замедляют работу.
Решение — мемоизация (lru_cache в Python).
-
Потеря возвращаемого значения. Забыто return, из-за чего результат не возвращается обратно.
-
Попытка решить всё рекурсией. Иногда проще и быстрее использовать цикл — это не «менее красиво», а просто практичнее.
С чего начать изучение
Быстро освоить процесс можно, если двигаться от простого к сложному — рекурсивно, в буквальном смысле.
1. Начните с визуальных аналогий
Представьте матрёшку, зеркала или русло реки, где каждый уровень повторяет предыдущий.
Такой образ помогает понять идею самоподобия.
2. Решайте базовые задачи
- Факториал числа.
- Подсчёт суммы элементов списка.
- Разворот строки.
- Поиск элемента в дереве.
Сначала пишите рекурсивно, потом попробуйте переписать в цикле — чтобы увидеть разницу.
3. Используйте курсы и книги
-
Hexlet: курсы по алгоритмам и Python включают раздел с наглядными примерами.
-
Coursera / edX: курсы по компьютерным наукам (CS50, Algorithms I).
-
Книги:
- «Грокаем алгоритмы» Адитьи Бхаргавы;
- «Structure and Interpretation of Computer Programs» (SICP).
4. Практикуйтесь в визуализации
Сервисы вроде Python Tutor или Visualgo.net позволяют пошагово проследить, как функция вызывает саму себя.
Заключение
Рекурсия — не просто техника программирования, а способ мышления, позволяющий видеть задачи как цепочки взаимосвязанных шагов. Она учит структурировать решения, выделять базу, мыслить от общего к частному. Для программиста это — фундаментальная идея, лежащая в основе множества алгоритмов: от сортировок и обхода графов до работы компиляторов и нейросетей. Освоив рекурсивные тонкости, вы начинаете понимать логику программирования на глубоком уровне — где каждая задача сводится к меньшей версии самой себя. И что сам процесс её изучения — тоже рекурсивен.
<!DOCTYPE html>
<html class="h-100" data-bs-theme="light" data-mantine-color-scheme="light" lang="ru" prefix="og: https://ogp.me/ns#">
<head>
<meta content="width=device-width, initial-scale=1.0" name="viewport">
<meta content="IE=Edge" http-equiv="X-UA-Compatible">
<link crossorigin="true" href="https://cdn.hexlet.io" rel="preconnect">
<link href="https://mc.yandex.ru" rel="preconnect">
<meta content="aa2vrdtq64dub8knuf83lwywit311w" name="facebook-domain-verification">
<link href="/favicon.ico" rel="icon" sizes="any">
<link href="/favicon.svg" rel="icon" type="image/svg+xml">
<link href="/apple-touch-icon.png" rel="apple-touch-icon">
<link href="/manifest.webmanifest" rel="manifest">
<script>
//<![CDATA[
window.gon={};gon.ym_counter="25559621";gon.is_bot=true;gon.applications={};gon.current_user={"id":null,"last_viewed_notification_id":null,"email":null,"state":null,"first_name":"","last_name":"","created_at":"2026-02-26 17:00:43 UTC","current_program":null,"current_team":null,"full_name":"","guest":true,"can_use_paid_features":false,"is_hexlet_employee":false,"sanitized_phone_number":"","can_subscribe":true,"can_renew_education":false};gon.token="4oq64TTgfQcY9EaWpP5evEfHtTHhy0QmX_sitJ-RkHINW3HWxp7QZ663Yg6o8a7Lh86Ym-n8uoTiG7jgzZZ3HA";gon.locale="ru";gon.language="ru";gon.theme="light";gon.rails_env="production";gon.mobile=false;gon.google={"analytics_key":"UA-1360700-51","optimize_key":"GTM-5QDVFPF"};gon.captcha={"google_v3_site_key":"6LenGbgZAAAAAM7HbrDbn5JlizCSzPcS767c9vaY","yandex_site_key":"ysc1_Vyob5ZPPUdPBsu0ykt8bVFdzsfpoVjQChLGl2b4g19647a89","verification_failed":null};gon.social_signin=false;gon.typoreporter_google_form_id="1FAIpQLSeibfGq-KvWQ2Fyru-zkFFRVTLBuzXAHAoEyN1p49FtDmNoNA";
//]]>
</script>
<meta charset="utf-8">
<title>Что такое Рекурсия? — Q&A Хекслет</title>
<meta name="description" content="2 ответа на вопрос, что такое Рекурсия простыми словами? Глоссарий Хекслета.">
<link rel="canonical" href="https://ru.hexlet.io/qna/glossary/questions/chto-takoe-rekursiya">
<meta property="og:description" content="2 ответа
на вопрос, что такое Рекурсия простыми словами? Глоссарий Хекслета.">
<meta property="og:title" content="Что такое Рекурсия? — Q&A Хекслет">
<meta property="og:url" content="https://ru.hexlet.io/qna/glossary/questions/chto-takoe-rekursiya">
<meta name="csrf-param" content="authenticity_token" />
<meta name="csrf-token" content="FYSuAa0vF_uiJkgKg-b8rTu5DZIyHuWcptr3zn6ZVTD6VWU2X1G6mxRlbJKP6Qza-7AgODopGz4bOm2aLJ6yXg" />
<script src="/vite/assets/inertia-INZxX8jp.js" crossorigin="anonymous" type="module"></script><link rel="modulepreload" href="/vite/assets/chunk-DsPFFUou.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/preload-helper-BJ4cLWpC.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/init-nkZBEvfU.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/ahoy-DrlRQ-1D.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/analytics-6pOtQ3OW.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/ErrorFallbackBlock-naDSYSy9.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/Surface-DL2bpZA-.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/gon-D3e4yh1x.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/mantine-CGMYrt2Y.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/utils-DRqSHbQE.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/routes-CCH8ilKF.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/extends-C-EagtpE.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/inheritsLoose-BBd-DCVI.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/objectWithoutPropertiesLoose-DRHXDhjp.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/index.esm-DAqKOkZ0.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/Button-CGPUux8l.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/CloseButton-D1euiPao.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/Group-BX48WcuU.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/Loader-BQEY8g6v.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/Modal-Cy3HByv7.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/OptionalPortal-1Hza5P2w.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/Stack-CtjJzfw4.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/Textarea-Ck64llAy.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/Box-B5-OOzBf.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/DirectionProvider-Dc9zdUke.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/events-DJQOhap0.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/use-reduced-motion-D2owz4wa.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/use-disclosure-zKtK5W1r.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/use-hotkeys-Cnc_Rwkb.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/random-id-DOQyszCZ.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/notifications.store-C-3AFSMn.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/exports-C_MrNx_T.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/axios-BEvgo0ym.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/dayjs.min-BkKovM-s.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/i18next-BlSq9s7B.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/client-U9M77rxp.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/react-dom-DaLxUz_h.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/useTranslation-Bx1Cdrkz.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/compiler-runtime-6XxiPFnt.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/jsx-runtime-CwjcCKJi.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/react-CkL4ZRHB.js" as="script" crossorigin="anonymous">
<link rel="stylesheet" href="/vite/assets/application-BqhCP46M.js" />
<script src="/vite/assets/application-Df9RExpe.js" crossorigin="anonymous" type="module"></script><link rel="modulepreload" href="/vite/assets/chunk-DsPFFUou.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/autocomplete-VMNbxKGl.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/routes-CCH8ilKF.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/createPopper-C3aM9r1M.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/js.cookie-D1-O8zkX.js" as="script" crossorigin="anonymous"><link rel="stylesheet" href="/vite/assets/application-C8HjmMaq.css" media="screen" />
<script>
window.ym = function(){(ym.a=ym.a||[]).push(arguments)};
window.addEventListener('load', function() {
setTimeout(function() {
ym.l = 1*new Date();
ym(window.gon.ym_counter, "init", {
clickmap: true,
trackLinks: true,
accurateTrackBounce: true,
webvisor: true
});
// Загружаем скрипт
var k = document.createElement('script');
k.async = 1;
k.src = 'https://mc.yandex.ru/metrika/tag.js';
document.head.appendChild(k);
ym(window.gon.ym_counter, 'getClientID', function(clientID) {
window.ymClientId = clientID;
});
}, 1500);
});
</script>
<!-- Google Tag Manager - deferred -->
<script>
// dataLayer stub сразу — пуши работают до загрузки скрипта
window.dataLayer = window.dataLayer || [];
// Сам скрипт — отложенно после load
window.addEventListener('load', function() {
setTimeout(function() {
dataLayer.push({'gtm.start': new Date().getTime(), event: 'gtm.js'});
var j = document.createElement('script');
j.async = true;
j.src = 'https://www.googletagmanager.com/gtm.js?id=GTM-WK88TH';
document.head.appendChild(j);
}, 1500);
});
</script>
<!-- End Google Tag Manager -->
</head>
<body>
<noscript>
<div>
<img alt="" src="https://mc.yandex.ru/watch/25559621" style="position:absolute; left:-9999px;">
</div>
</noscript>
<header class="sticky-top bg-body">
<nav class="navbar navbar-expand-lg">
<div class="container-xxl">
<a class="navbar-brand" href="/"><img alt="Логотип Хекслета" height="24" src="https://ru.hexlet.io/vite/assets/logo_ru_light-BpiEA1LT.svg" width="96">
</a><button aria-controls="collapsable" aria-expanded="false" aria-label="Меню" class="navbar-toggler border-0 mb-0 mt-1" data-bs-target="#collapsable" data-bs-toggle="collapse">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="collapsable">
<ul class="navbar-nav mb-lg-0 mt-lg-1">
<li class="nav-item dropdown">
<button aria-haspopup class="btn nav-link" data-bs-toggle="dropdown" type="button">
Все курсы
<span class="bi bi-chevron-down align-middle ms-1"></span>
</button>
<ul class="dropdown-menu">
<li>
<a class="dropdown-item d-flex py-2" href="/courses"><div class="fw-bold me-auto">Все что есть</div>
<div class="text-muted">117</div>
</a></li>
<li>
<hr class="dropdown-divider">
</li>
<li class="dropdown-item">
<b>Популярные категории</b>
</li>
<li>
<a class="dropdown-item py-2" href="/courses_devops">Курсы по DevOps
</a></li>
<li>
<a class="dropdown-item py-2" href="/courses_data_analytics">Курсы по аналитике данных
</a></li>
<li>
<a class="dropdown-item py-2" href="/courses_programming">Курсы по программированию
</a></li>
<li>
<a class="dropdown-item py-2" href="/courses_testing">Курсы по тестированию
</a></li>
<li>
<hr class="dropdown-divider">
</li>
<li class="dropdown-item">
<b>Популярные курсы</b>
</li>
<li>
<a class="dropdown-item py-2" href="/programs/devops-engineer-from-scratch">DevOps-инженер с нуля
</a></li>
<li>
<a class="dropdown-item py-2" href="/programs/go">Go-разработчик
</a></li>
<li>
<a class="dropdown-item py-2" href="/programs/java">Java-разработчик
</a></li>
<li>
<a class="dropdown-item py-2" href="/programs/python">Python-разработчик
</a></li>
<li>
<a class="dropdown-item py-2" href="/programs/qa-auto-engineer-java">Автоматизатор тестирования на Java
</a></li>
<li>
<a class="dropdown-item py-2" href="/programs/data-analytics">Аналитик данных
</a></li>
<li>
<a class="dropdown-item py-2" href="/programs/frontend">Фронтенд-разработчик
</a></li>
</ul>
</li>
<li class="nav-item dropdown">
<button aria-haspopup class="btn nav-link" data-bs-toggle="dropdown" type="button">
О Хекслете
<span class="bi bi-chevron-down align-middle"></span>
</button>
<ul class="dropdown-menu bg-body">
<li>
<a class="dropdown-item py-2" href="/pages/about">О нас
</a></li>
<li>
<a class="dropdown-item py-2" href="/blog">Блог
</a></li>
<li>
<span class="dropdown-item py-2 external-link" data-href="https://special.hexlet.io/hse-research" role="button">Результаты (Исследование)
</span></li>
<li>
<span class="dropdown-item py-2 external-link" data-href="https://career.hexlet.io" role="button">Хекслет Карьера
</span></li>
<li>
<a class="dropdown-item py-2" href="/testimonials">Отзывы студентов
</a></li>
<li>
<span class="dropdown-item py-2 external-link" data-href="https://t.me/hexlet_help_bot" role="button">Поддержка (В ТГ)
</span></li>
<li>
<span class="dropdown-item py-2 external-link" data-href="https://special.hexlet.io/referal-program/?promo_creative=priglasite-druzei&promo_name=referal-program&promo_position=promo_position&promo_start=010724&promo_type=link" role="button">Реферальная программа
</span></li>
<li>
<span class="dropdown-item py-2 external-link" data-href="https://special.hexlet.io/certificate" role="button">Подарочные сертификаты
</span></li>
<li>
<span class="dropdown-item py-2 external-link" data-href="https://hh.ru/employer/4307094" role="button">Вакансии
</span></li>
<li>
<span class="dropdown-item d-flex external-link" rel="noopener noreferrer nofollow" data-href="https://b2b.hexlet.io" data-target="_blank" role="button">Компаниям
</span></li>
<li>
<span class="dropdown-item d-flex external-link" rel="noopener noreferrer nofollow" data-href="https://hexly.ru/" data-target="_blank" role="button">Колледж
</span></li>
<li>
<span class="dropdown-item d-flex external-link" rel="noopener noreferrer nofollow" data-href="https://hexlyschool.ru/" data-target="_blank" role="button">Частная школа
</span></li>
</ul>
</li>
<li><a class="nav-link" href="/subscription/new">Подписка</a></li>
</ul>
<ul class="navbar-nav flex-lg-row align-items-lg-center gap-2 ms-auto">
<li>
<a class="nav-link" aria-label="Переключить тему" href="/theme/switch?new_theme=dark"><span aria-hidden="true" class="bi bi-moon"></span>
</a></li>
<li>
<span data-target="_self" class="nav-link external-link" data-href="/u/new" role="button"><span>Регистрация</span>
</span></li>
<li>
<span data-target="_self" class="nav-link external-link" data-href="https://ru.hexlet.io/session/new" role="button"><span>Вход</span>
</span></li>
</ul>
</div>
</div>
</nav>
</header>
<div class="x-container-xxxl">
</div>
<main class="mb-6 min-vh-100 h-100">
<link rel="preload" as="image" href="https://hexlet.io/rails/active_storage/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6NDAyOCwicHVyIjoiYmxvYl9pZCJ9fQ==--ae9eed98663dd1201759d042a5ba7ca790866156/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJ3ZWJwIiwicmVzaXplX3RvX2xpbWl0IjpbNDAwLDQwMF0sInNhdmVyIjp7InF1YWxpdHkiOjg1fX0sInB1ciI6InZhcmlhdGlvbiJ9fQ==--5b6f46dacd1af664f27558553a58076185091823/Programming-bro.png"/><link rel="preload" as="image" href="https://hexlet.io/rails/active_storage/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6Mzc2MCwicHVyIjoiYmxvYl9pZCJ9fQ==--9348098e4053d798b6f34bee4ef66947540261e4/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJ3ZWJwIiwicmVzaXplX3RvX2xpbWl0IjpbNDAwLDQwMF0sInNhdmVyIjp7InF1YWxpdHkiOjg1fX0sInB1ciI6InZhcmlhdGlvbiJ9fQ==--5b6f46dacd1af664f27558553a58076185091823/Low%20code%20development-rafiki.png"/><link rel="preload" as="image" href="https://hexlet.io/rails/active_storage/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6Mzc1OCwicHVyIjoiYmxvYl9pZCJ9fQ==--023ea18f500b1c4c91617fa96bbc52df8395da39/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJ3ZWJwIiwicmVzaXplX3RvX2xpbWl0IjpbNDAwLDQwMF0sInNhdmVyIjp7InF1YWxpdHkiOjg1fX0sInB1ciI6InZhcmlhdGlvbiJ9fQ==--5b6f46dacd1af664f27558553a58076185091823/Software%20engineer-bro.png"/><link rel="preload" as="image" href="https://hexlet.io/rails/active_storage/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6NDAxNiwicHVyIjoiYmxvYl9pZCJ9fQ==--eb66b9b5e26fafa32844ce0f4522c3ed84544040/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJ3ZWJwIiwicmVzaXplX3RvX2xpbWl0IjpbNDAwLDQwMF0sInNhdmVyIjp7InF1YWxpdHkiOjg1fX0sInB1ciI6InZhcmlhdGlvbiJ9fQ==--5b6f46dacd1af664f27558553a58076185091823/Hand%20coding-rafiki.png"/><link rel="preload" as="image" href="https://hexlet.io/rails/active_storage/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6Mzc1NywicHVyIjoiYmxvYl9pZCJ9fQ==--bd2826bc88b4074fdf555368020c1fc0ac0705c1/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJ3ZWJwIiwicmVzaXplX3RvX2xpbWl0IjpbNDAwLDQwMF0sInNhdmVyIjp7InF1YWxpdHkiOjg1fX0sInB1ciI6InZhcmlhdGlvbiJ9fQ==--5b6f46dacd1af664f27558553a58076185091823/Low%20code%20development-rafiki.png"/><link rel="preload" as="image" href="/vite/assets/development-BVihs_d5.png"/><div id="app" data-page="{"component":"web/qna/questions/show","props":{"errors":{},"locale":"ru","language":"ru","httpsHost":"https://ru.hexlet.io","host":"ru.hexlet.io","colorScheme":"light","auth":{"user":{"id":null,"last_viewed_notification_id":null,"email":null,"state":null,"first_name":"","last_name":"","created_at":"2026-02-26T17:00:42.802Z","current_program":null,"current_team":null,"full_name":"","guest":true,"can_use_paid_features":false,"is_hexlet_employee":false,"sanitized_phone_number":"","can_subscribe":true,"can_renew_education":false}},"cloudflareTurnstileSiteKey":"0x4AAAAAAA15KmeFXzd2H0Xo","vkIdClientId":"51586979","yandexIdClientId":"88d071f1d3384eb4bd1deb37910235c7","formAuthToken":"Bz8aRDeViZ90_PZjF3QlxuisQos9dpIUVY1tZWG4af_o7tFzxesk_8K_0vsbe9WxKKVvITVBbLbobfcxM7-OkQ","category":{"id":15,"title":"Глоссарий","slug":"glossary","questions_count":382,"locale":"ru"},"mainStackCategory":{"id":2,"name":"Курсы по веб-разработке","slug":"web_development","short_name":"Веб-разработка","order":190,"state":"published","category_slug":"courses_web_development"},"answerDto":{"id":null,"body":"","meta":{"model":"question_answer","relations":{}}},"question":{"creator":{"id":104929,"email":"feycot@gmail.com","first_name":"Nikolai","last_name":"Gagarinov","telegram":"","full_name":"Nikolai Gagarinov","removed":false},"category":{"id":15,"title":"Глоссарий","slug":"glossary","questions_count":382,"locale":"ru"},"tags":[],"id":3861,"answers_count":2,"slug":"chto-takoe-rekursiya","state":"published","title":"Рекурсия","created_at":"2023-06-05T10:02:27.408Z","details":null,"best_answer_id":5225,"related_stacks_count":5},"answers":[{"user":{"id":104929,"email":"feycot@gmail.com","first_name":"Nikolai","last_name":"Gagarinov","telegram":"","full_name":"Nikolai Gagarinov","removed":false},"question":{"creator":{"id":104929,"email":"feycot@gmail.com","first_name":"Nikolai","last_name":"Gagarinov","telegram":"","full_name":"Nikolai Gagarinov","removed":false},"category":{"id":15,"title":"Глоссарий","slug":"glossary","questions_count":382,"locale":"ru"},"tags":[],"id":3861,"answers_count":2,"slug":"chto-takoe-rekursiya","state":"published","title":"Рекурсия","created_at":"2023-06-05T10:02:27.408Z","details":null,"best_answer_id":5225,"related_stacks_count":5},"id":5225,"state":"active","body":"\nВ программировании есть понятие, которое одновременно пугает новичков и восхищает опытных разработчиков. Это — рекурсия. Её часто описывают как «функцию, вызывающую саму себя», но за этой фразой скрывается целая философия построения алгоритмов.\n\n\n\n## Что такое рекурсия простыми словами\n\nВ самом широком смысле это — повторение действия внутри самого себя. Представьте два зеркала, стоящих друг напротив друга: в каждом отражении — новое, чуть меньшее, и так до бесконечности. Примерно так работает рекурсивный процесс: функция видит задачу, решает её частично и передаёт оставшуюся часть… самой себе. В программировании рекурсия — это метод решения задач через повторные вызовы одной и той же функции, но с изменёнными аргументами. Каждый вызов приближает программу к «точке останова» — моменту, когда повторения прекращаются.\n\n### Интуитивное объяснение\n\nПредставьте, что вы стоите между двумя зеркалами, направленными друг на друга. Вы видите цепочку бесконечных отражений, уходящую вдаль. То же самое происходит при рекурсии: функция вызывает саму себя снова и снова — пока не достигнет определённого условия, после чего начинает «возвращаться» обратно.\n\n### Ключевые термины\n\nЧтобы понять механику, нужно знать три основных понятия:\n\n* **Рекурсивная функция** — функция, которая вызывает сама себя.\n* **База рекурсии** — условие, при котором процесс прекращается. Без базы программа зациклится.\n* **Шаг рекурсии** — часть, в которой функция вызывает себя для решения меньшей задачи.\n\n**Пример:**\nЕсли мы хотим посчитать количество файлов в папке, мы можем пройти по каждому элементу, а если встречаем вложенную папку — снова вызвать ту же функцию. Так программа обходит всю структуру до конца, пока не останется ни одного непроверенного каталога.\n\n## Как работает рекурсия в программировании\n\nЭто не магия, а строгий механизм. Он строится на стеке вызовов — области памяти, где хранятся активные функции.\n\n### Механизм работы\n\n1. Функция вызывает сама себя, передавая изменённые аргументы.\n2. Каждый новый вызов помещается в стек — как карточка поверх другой.\n3. Когда достигается база рекурсии, функция перестаёт вызывать себя и начинает возвращать результаты «вверх».\n\n### База и условие выхода\n\nГлавное правило — в каждой рекурсии должна быть точка остановки. Если её нет, программа будет вызывать себя бесконечно, пока не переполнит стек и не завершится с ошибкой (RecursionError в Python).\n\n### Прямой и обратный ход\n\n* **Прямой ход** — функция вызывает саму себя, углубляясь в задачу.\n* **Обратный ход** — выполнение идёт назад, собирая результаты из стека вызовов.\n\nПример псевдокода:\n\n```python\ndef recurse(n):\n if n == 0: # база рекурсии\n return 1\n else:\n return n * recurse(n - 1)\n```\n\nПри вызове recurse(3) произойдёт следующее:\n\n1. 3 → вызывает recurse(2)\n2. 2 → вызывает recurse(1)\n3. 1 → вызывает recurse(0)\n4. 0 — база рекурсии, возврат 1\n5. Далее значения перемножаются обратно: `1 * 2 * 3 = 6`\n\n## Разновидности рекурсии\n\nПонятие классифицируется в зависимости от того, как и где функция вызывает саму себя.\n\n### 1. Прямая\n\nФункция вызывает саму себя напрямую.\n\n```python\ndef countdown(n):\n if n > 0:\n print(n)\n countdown(n - 1)\n```\n\n### 2. Косвенная\n\nФункция А вызывает функцию B, а та снова вызывает функцию А.\n\n```python\ndef funcA(x):\n if x > 0:\n funcB(x - 1)\n\ndef funcB(x):\n if x > 0:\n funcA(x - 1)\n```\n\n### 3. Линейная и каскадная\n\n* **Линейная** — один рекурсивный вызов в теле функции.\n* **Каскадная (многоступенчатая)** — функция вызывает себя несколько раз.\n Пример: вычисление чисел Фибоначчи, где fib(n) = fib(n-1) + fib(n-2).\n\n### 4. Хвостовая рекурсия (tail recursion)\n\nОсобый вид, при котором результат вычислений не зависит от последующих вызовов. Такая форма может быть оптимизирована компилятором — стек не растёт, и программа работает как цикл.\n\n**Пример:**\n\n```python\ndef factorial(n, acc=1):\n if n == 0:\n return acc\n return factorial(n - 1, acc * n)\n```\n\nЗдесь на каждом шаге результат передаётся как параметр (acc), поэтому новые вызовы не накапливаются в стеке.\n\n## Отличия от цикла\n\n| Параметр | Рекурсия | Цикл |\n|:-----------------------------|:-----------------------------------------|:----------------------------------------|\n| **Принцип работы** | Функция вызывает саму себя | Команда повторяется внутри одного блока |\n| | | |\n| **Механизм хранения данных** | Стек вызовов | Переменные в текущей области памяти |\n| **Понятность кода** | Часто проще и короче | Иногда громоздко, но очевидно |\n| **Производительность** | Медленнее из-за накладных расходов стека | Быстрее, оптимизирован процессором |\n| **Риск ошибок** | Переполнение стека, бесконечный вызов | Бесконечный цикл при ошибке в условии |\n| **Применение** | Деревья, графы, рекурсивные формулы | Повторяющиеся линейные операции |\n\n## Преимущества и недостатки\n\nРекурсия — инструмент мощный, но требующий осторожности. Её плюсы и минусы лучше всего видны при сравнении с итерацией.\n\n### Преимущества\n\n* **Краткость и читаемость.** Рекурсивные функции лаконичны, особенно в алгоритмах с ветвлениями.\n* **Наглядность.** Код часто ближе к математической логике и проще для понимания принципа.\n* **Естественное решение.** Для деревьев, графов или вложенных структур рекурсия логичнее, чем цикл.\n\n### Недостатки\n\n* **Переполнение стека.** При слишком глубокой рекурсии память заканчивается.\n* **Сложность отладки.** Ошибка в базе может привести к бесконечным вызовам.\n* **Скорость.** Рекурсия часто медленнее, чем эквивалентный цикл.\n\n## Примеры в программировании\n\n### 1. Расчёт факториала\n\nФакториал числа n! = 1 × 2 × … × n. Через рекурсию это выглядит максимально просто:\n\n```python\ndef factorial(n):\n if n == 0:\n return 1 # база return n * factorial(n - 1) # шаг print(factorial(5)) # 120\n```\n\nКаждый вызов умножает текущее число на результат следующего, пока не достигнет нуля.\n\n### 2. Числа Фибоначчи\n\nКаждое число — сумма двух предыдущих: `F(n) = F(n-1) + F(n-2)`.\n\n```python\ndef fib(n):\n if n <= 1:\n return n\n return fib(n-1) + fib(n-2)\n```\n\nВызов fib(5) даст последовательность вызовов:\n\n```text\nfib(5) → fib(4) + fib(3)fib(4) → fib(3) + fib(2)...\n```\nРезультат — 5. Однако это пример неэффективной рекурсии, потому что многие значения вычисляются по нескольку раз. Для ускорения применяют мемоизацию (кэширование результатов).\n\n### 3. Обход дерева\n\nРекурсия незаменима при работе с древовидными структурами — файлами, XML, JSON, каталогами.\n\n```python\ndef traverse(node):\n print(node.value)\n for child in node.children:\n traverse(child)\n```\nКаждый узел вызывает ту же функцию для своих потомков, пока дерево не обойдётся целиком.\n\n### 4. Поиск пути в лабиринте\n\nВ играх и алгоритмах навигации рекурсия позволяет искать выход, перебирая соседние клетки:\n\n```python\ndef find_exit(maze, x, y):\n if maze[x][y] == 'exit':\n return True mark_as_visited(x, y)\n for next in neighbours(x, y):\n if find_exit(maze, next.x, next.y):\n return True\n return False\n```\n\nКаждый шаг вызывает функцию для соседней клетки, пока не найдёт путь.\n\n## Баланс между красотой и эффективностью\n\nОпытные разработчики стараются находить компромисс: если задача может быть решена итеративно без потери понятности — выбирают цикл. Если же структура данных сама по себе рекурсивна (например, JSON или дерево DOM), то рекурсивный подход оказывается естественнее и надёжнее.\n\n\n\n## За пределами программирования\n\nХотя чаще всего рекурсия упоминается в контексте кода, этот принцип встречается повсюду — от математики до биологии и искусства.\n\n### В математике\n\nРекурсивные формулы описывают последовательности, где каждый элемент зависит от предыдущих: числа Фибоначчи, факториалы, фракталы, степенные ряды. Рекурсивное мышление помогает строить доказательства по индукции — шаг за шагом, от простого к сложному.\n\n### В биологии\n\nПрирода любит повторения. Форма листа повторяет очертания ветви, а ветвь — всего дерева.\n Фрактальная структура лёгких, кровеносных сосудов или береговой линии — это естественные проявления рекурсии.\n\n### В гуманитарных дисциплинах\n\nВ грамматике: предложение может содержать другое предложение. Например: «Я знаю, что ты знаешь, что он сказал». В литературе — «вложенные истории»: рассказ внутри рассказа. В живописи — отражения, зеркала, повторяющиеся мотивы. В философии — это способ мыслить структурно, когда результат на каждом уровне строится на предыдущем.\n\n## \n\n## Как отлаживать и тестировать рекурсивные функции\n\nЧтобы избежать сбоев, важно понимать, где и почему возникает ошибка.\n\n### 1. Проверяйте базу рекурсии\n\nБольше половины проблем — из-за отсутствия или неправильной базы. Функция должна всегда иметь условие выхода, которое гарантирует завершение.\n\n### 2. Тестируйте на простых примерах\n\nНачинайте с минимальных данных (n=0, n=1). Если функция корректно работает для них, можно проверять большие значения.\n\n### 3. Используйте отладчик IDE\n\nБольшинство IDE (PyCharm, VS Code, IntelliJ) позволяют пройти рекурсивный процесс пошагово. Вы увидите, как аргументы меняются при каждом вызове и где цикл заходит в тупик.\n\n### 4. Контролируйте глубину стека\n\nВ Python есть ограничение по умолчанию — около 1000 вызовов. Если рекурсия может быть глубже, нужно: import syssys.setrecursionlimit(3000). Но лучше оптимизировать алгоритм или перейти на итерацию.\n\n### 5. Используйте вывод логов\n\nДобавьте печать входящих аргументов — иногда простая строка print(n) показывает, где именно «застрял» вызов.\n\n## Сценарии выбора\n\n| Сценарий | Рекурсия | Циклы |\n|:--------------------------------------------:|:------------------:|:----------------------:|\n| Обход дерева, графа, каталогов | Лучше использовать | |\n| Вычисление факториала или Фибоначчи | Для обучения | Для практических задач |\n| Обработка массивов, фильтрация | | Предпочтительно |\n| Простые повторения | | Оптимально |\n| Алгоритмы поиска (DFS, QuickSort, MergeSort) | Эффективно | |\n\nХорошее правило: если алгоритм можно описать фразой «вызови себя для подзадачи» — рекурсия естественна. А если речь идёт о «повтори то же действие несколько раз» — цикл проще и надёжнее.\n\n## Типичные ошибки начинающих программистов\n\n1. **Отсутствие условия выхода.** Функция уходит в бесконечный вызов и вызывает переполнение стека.\n2. **Неправильное изменение аргумента.** Например, n не уменьшается на каждом шаге.\n3. **Лишние вычисления.** Повторные вызовы с одними и теми же аргументами замедляют работу.\n Решение — мемоизация (lru_cache в Python).\n4. **Потеря возвращаемого значения.** Забыто return, из-за чего результат не возвращается обратно.\n5. **Попытка решить всё рекурсией.** Иногда проще и быстрее использовать цикл — это не «менее красиво», а просто практичнее.\n\n## С чего начать изучение\n\nБыстро освоить процесс можно, если двигаться от простого к сложному — рекурсивно, в буквальном смысле.\n\n### 1. Начните с визуальных аналогий\n\nПредставьте матрёшку, зеркала или русло реки, где каждый уровень повторяет предыдущий.\n Такой образ помогает понять идею самоподобия.\n\n### 2. Решайте базовые задачи\n\n* Факториал числа.\n* Подсчёт суммы элементов списка.\n* Разворот строки.\n* Поиск элемента в дереве.\n\nСначала пишите рекурсивно, потом попробуйте переписать в цикле — чтобы увидеть разницу.\n\n### 3. Используйте курсы и книги\n\n* **Hexlet:** курсы по алгоритмам и Python включают раздел с наглядными примерами.\n* **Coursera / edX:** курсы по компьютерным наукам (CS50, Algorithms I).\n* Книги:\n\n * «Грокаем алгоритмы» Адитьи Бхаргавы;\n * «Structure and Interpretation of Computer Programs» (SICP).\n\n### 4. Практикуйтесь в визуализации\n\nСервисы вроде Python Tutor или Visualgo.net позволяют пошагово проследить, как функция вызывает саму себя.\n\n## Заключение\n\nРекурсия — не просто техника программирования, а способ мышления, позволяющий видеть задачи как цепочки взаимосвязанных шагов. Она учит структурировать решения, выделять базу, мыслить от общего к частному. Для программиста это — фундаментальная идея, лежащая в основе множества алгоритмов: от сортировок и обхода графов до работы компиляторов и нейросетей. Освоив рекурсивные тонкости, вы начинаете понимать логику программирования на глубоком уровне — где каждая задача сводится к меньшей версии самой себя. И что сам процесс её изучения — тоже рекурсивен.\n","votes_up_count":1,"votes_down_count":0,"created_at":"2025-11-24T19:28:30.984Z","user_id":104929,"category_slug":"glossary"},{"user":{"id":647057,"email":"redkinaelena10.02.89@yandex.ru","first_name":"Елена","last_name":"Редькина","telegram":"89670235676","full_name":"Елена Редькина","removed":false},"question":{"creator":{"id":104929,"email":"feycot@gmail.com","first_name":"Nikolai","last_name":"Gagarinov","telegram":"","full_name":"Nikolai Gagarinov","removed":false},"category":{"id":15,"title":"Глоссарий","slug":"glossary","questions_count":382,"locale":"ru"},"tags":[],"id":3861,"answers_count":2,"slug":"chto-takoe-rekursiya","state":"published","title":"Рекурсия","created_at":"2023-06-05T10:02:27.408Z","details":null,"best_answer_id":5225,"related_stacks_count":5},"id":3035,"state":"active","body":"Рекурсия - это процесс повторения определенной операции или действия. В программировании рекурсия используется для описания алгоритмов, которые содержат внутри себя вызовы самих себя. Это позволяет создавать более компактные и понятные алгоритмы, а также увеличивает эффективность их работы.","votes_up_count":0,"votes_down_count":0,"created_at":"2023-11-16T12:09:14.950Z","user_id":647057,"category_slug":"glossary"}],"relatedQuestions":[{"creator":{"id":583099,"email":"shade.mailbox@gmail.com","first_name":"Arthur","last_name":"Cheremisin","telegram":"","full_name":"Arthur Cheremisin","removed":false},"category":{"id":15,"title":"Глоссарий","slug":"glossary","questions_count":382,"locale":"ru"},"tags":[{"id":1095,"slug":"data-analitika","name":"data-аналитика"},{"id":1096,"slug":"analitika","name":"Аналитика"}],"id":2709,"answers_count":2,"slug":"chto-takoe-pandas","state":"published","title":"Pandas","created_at":"2023-03-29T12:39:32.428Z","details":"","best_answer_id":5306,"related_stacks_count":5},{"creator":{"id":104929,"email":"feycot@gmail.com","first_name":"Nikolai","last_name":"Gagarinov","telegram":"","full_name":"Nikolai Gagarinov","removed":false},"category":{"id":15,"title":"Глоссарий","slug":"glossary","questions_count":382,"locale":"ru"},"tags":[],"id":3577,"answers_count":1,"slug":"chto-takoe-1c-buhgalteriya","state":"published","title":"1C:Бухгалтерия","created_at":"2023-06-05T10:02:18.923Z","details":null,"best_answer_id":3315,"related_stacks_count":0},{"creator":{"id":104929,"email":"feycot@gmail.com","first_name":"Nikolai","last_name":"Gagarinov","telegram":"","full_name":"Nikolai Gagarinov","removed":false},"category":{"id":15,"title":"Глоссарий","slug":"glossary","questions_count":382,"locale":"ru"},"tags":[],"id":3578,"answers_count":1,"slug":"chto-takoe-1c-predpriyatie","state":"published","title":"1C:Предприятие","created_at":"2023-06-05T10:02:18.960Z","details":null,"best_answer_id":3314,"related_stacks_count":5},{"creator":{"id":104929,"email":"feycot@gmail.com","first_name":"Nikolai","last_name":"Gagarinov","telegram":"","full_name":"Nikolai Gagarinov","removed":false},"category":{"id":15,"title":"Глоссарий","slug":"glossary","questions_count":382,"locale":"ru"},"tags":[],"id":3579,"answers_count":1,"slug":"chto-takoe-a-b-testirovanie","state":"published","title":"A/B-тестирование","created_at":"2023-06-05T10:02:18.988Z","details":null,"best_answer_id":3313,"related_stacks_count":5},{"creator":{"id":104929,"email":"feycot@gmail.com","first_name":"Nikolai","last_name":"Gagarinov","telegram":"","full_name":"Nikolai Gagarinov","removed":false},"category":{"id":15,"title":"Глоссарий","slug":"glossary","questions_count":382,"locale":"ru"},"tags":[],"id":3580,"answers_count":1,"slug":"chto-takoe-agile","state":"published","title":"Agile","created_at":"2023-06-05T10:02:19.016Z","details":null,"best_answer_id":3312,"related_stacks_count":5}],"relatedLandings":[{"stack":{"id":34,"slug":"algorithms","title":"Алгоритмы и структуры данных","audience":"for_programmers","start_type":"anytime","pricing_model":"subscription","priority":"medium","kind":"track","state":"published","stack_state":"finished","order":4000,"duration_in_months":2},"id":56,"slug":"algorithms","title":"Алгоритмы и структуры данных","subtitle":"Навык, который увеличит ваши шансы пройти алгоритмическое интервью в международные компании на 80%","subtitle_for_lists":"Алгоритмы для собеседований","locale":"ru","current":true,"duration_in_months_text":"2 месяца","stack_slug":"algorithms","price_text":"от 3 900 ₽","duration_text":"2 месяца","cover_list_variant":"https://hexlet.io/rails/active_storage/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6NDAyOCwicHVyIjoiYmxvYl9pZCJ9fQ==--ae9eed98663dd1201759d042a5ba7ca790866156/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJ3ZWJwIiwicmVzaXplX3RvX2xpbWl0IjpbNDAwLDQwMF0sInNhdmVyIjp7InF1YWxpdHkiOjg1fX0sInB1ciI6InZhcmlhdGlvbiJ9fQ==--5b6f46dacd1af664f27558553a58076185091823/Programming-bro.png"},{"stack":{"id":20,"slug":"js-sicp","title":"СИКП на JS","audience":"for_programmers","start_type":"anytime","pricing_model":"subscription","priority":"medium","kind":"track","state":"published","stack_state":"finished","order":4050,"duration_in_months":1},"id":28,"slug":"js-sicp","title":"СИКП на JS","subtitle":"Навык понимать программы на фундаментальном уровне, уверенно проходить собеседования и решать сложные задачи","subtitle_for_lists":"Навык фундаментального программирования","locale":"ru","current":true,"duration_in_months_text":"1 месяц","stack_slug":"js-sicp","price_text":"от 3 900 ₽","duration_text":"1 месяц","cover_list_variant":"https://hexlet.io/rails/active_storage/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6Mzc2MCwicHVyIjoiYmxvYl9pZCJ9fQ==--9348098e4053d798b6f34bee4ef66947540261e4/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJ3ZWJwIiwicmVzaXplX3RvX2xpbWl0IjpbNDAwLDQwMF0sInNhdmVyIjp7InF1YWxpdHkiOjg1fX0sInB1ciI6InZhcmlhdGlvbiJ9fQ==--5b6f46dacd1af664f27558553a58076185091823/Low%20code%20development-rafiki.png"},{"stack":{"id":37,"slug":"python-sicp","title":"СИКП на Python","audience":"for_programmers","start_type":"anytime","pricing_model":"subscription","priority":"medium","kind":"track","state":"published","stack_state":"finished","order":4150,"duration_in_months":1},"id":62,"slug":"python-sicp","title":"СИКП на Python","subtitle":"Навык понимать код на фундаментальном уровне, уверенно проходить собеседования и решать сложные задачи","subtitle_for_lists":"Изучите Python на глубоком уровне для решения сложных задач","locale":"ru","current":true,"duration_in_months_text":"1 месяц","stack_slug":"python-sicp","price_text":"от 3 900 ₽","duration_text":"1 месяц","cover_list_variant":"https://hexlet.io/rails/active_storage/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6Mzc1OCwicHVyIjoiYmxvYl9pZCJ9fQ==--023ea18f500b1c4c91617fa96bbc52df8395da39/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJ3ZWJwIiwicmVzaXplX3RvX2xpbWl0IjpbNDAwLDQwMF0sInNhdmVyIjp7InF1YWxpdHkiOjg1fX0sInB1ciI6InZhcmlhdGlvbiJ9fQ==--5b6f46dacd1af664f27558553a58076185091823/Software%20engineer-bro.png"},{"stack":{"id":36,"slug":"java-sicp","title":"СИКП на Java","audience":"for_programmers","start_type":"anytime","pricing_model":"subscription","priority":"medium","kind":"track","state":"published","stack_state":"finished","order":4100,"duration_in_months":1},"id":60,"slug":"java-sicp","title":"СИКП на Java","subtitle":"Навык понимать программы на фундаментальном уровне, уверенно проходить собеседования и решать сложные задачи","subtitle_for_lists":"Изучите фундаментальные принципы программирования на Java","locale":"ru","current":true,"duration_in_months_text":"1 месяц","stack_slug":"java-sicp","price_text":"от 3 900 ₽","duration_text":"1 месяц","cover_list_variant":"https://hexlet.io/rails/active_storage/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6NDAxNiwicHVyIjoiYmxvYl9pZCJ9fQ==--eb66b9b5e26fafa32844ce0f4522c3ed84544040/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJ3ZWJwIiwicmVzaXplX3RvX2xpbWl0IjpbNDAwLDQwMF0sInNhdmVyIjp7InF1YWxpdHkiOjg1fX0sInB1ciI6InZhcmlhdGlvbiJ9fQ==--5b6f46dacd1af664f27558553a58076185091823/Hand%20coding-rafiki.png"},{"stack":{"id":35,"slug":"ruby-sicp","title":"СИКП на Ruby","audience":"for_programmers","start_type":"anytime","pricing_model":"subscription","priority":"medium","kind":"track","state":"published","stack_state":"finished","order":null,"duration_in_months":1},"id":58,"slug":"ruby-sicp","title":"СИКП на Ruby","subtitle":"Навык понимания программ на фундаментальном уровне, помогающий уверенно проходить собеседования и увеличивать доход","subtitle_for_lists":"Изучите фундаментальные принципы программирования на Ruby ","locale":"ru","current":true,"duration_in_months_text":"1 месяц","stack_slug":"ruby-sicp","price_text":"от 3 900 ₽","duration_text":"1 месяц","cover_list_variant":"https://hexlet.io/rails/active_storage/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6Mzc1NywicHVyIjoiYmxvYl9pZCJ9fQ==--bd2826bc88b4074fdf555368020c1fc0ac0705c1/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJ3ZWJwIiwicmVzaXplX3RvX2xpbWl0IjpbNDAwLDQwMF0sInNhdmVyIjp7InF1YWxpdHkiOjg1fX0sInB1ciI6InZhcmlhdGlvbiJ9fQ==--5b6f46dacd1af664f27558553a58076185091823/Low%20code%20development-rafiki.png"}]},"url":"/qna/glossary/questions/chto-takoe-rekursiya","version":"0b0c6d4ebbd40fd58630a0dd89cc25544ccdf24e","encryptHistory":false,"clearHistory":false}"><style data-mantine-styles="true">:root, :host{--mantine-font-family: Arial, sans-serif;--mantine-font-family-headings: Arial, sans-serif;--mantine-heading-font-weight: normal;--mantine-radius-default: 0rem;--mantine-primary-color-filled: var(--mantine-color-indigo-filled);--mantine-primary-color-filled-hover: var(--mantine-color-indigo-filled-hover);--mantine-primary-color-light: var(--mantine-color-indigo-light);--mantine-primary-color-light-hover: var(--mantine-color-indigo-light-hover);--mantine-primary-color-light-color: var(--mantine-color-indigo-light-color);--mantine-spacing-xxl: calc(4rem * var(--mantine-scale));--mantine-font-size-xs: 12px;--mantine-font-size-sm: 14px;--mantine-font-size-md: 16px;--mantine-font-size-lg: clamp(16.0000px, calc(15.2727px + 0.2273vw), 18.0000px);--mantine-font-size-xl: clamp(16.0000px, calc(14.5455px + 0.4545vw), 20.0000px);--mantine-font-size-display-3: clamp(32.0000px, calc(26.1818px + 1.8182vw), 48.0000px);--mantine-font-size-display-2: clamp(36.0000px, calc(25.8182px + 3.1818vw), 64.0000px);--mantine-font-size-display-1: clamp(40.0000px, calc(25.4545px + 4.5455vw), 80.0000px);--mantine-font-size-h1: clamp(28.0000px, calc(23.6364px + 1.3636vw), 40.0000px);--mantine-font-size-h2: clamp(24.0000px, calc(21.0909px + 0.9091vw), 32.0000px);--mantine-font-size-h3: clamp(20.0000px, calc(17.0909px + 0.9091vw), 28.0000px);--mantine-font-size-h4: clamp(16.0000px, calc(13.0909px + 0.9091vw), 24.0000px);--mantine-font-size-h5: clamp(16.0000px, calc(14.5455px + 0.4545vw), 20.0000px);--mantine-font-size-h6: 1rem;--mantine-primary-color-0: var(--mantine-color-indigo-0);--mantine-primary-color-1: var(--mantine-color-indigo-1);--mantine-primary-color-2: var(--mantine-color-indigo-2);--mantine-primary-color-3: var(--mantine-color-indigo-3);--mantine-primary-color-4: var(--mantine-color-indigo-4);--mantine-primary-color-5: var(--mantine-color-indigo-5);--mantine-primary-color-6: var(--mantine-color-indigo-6);--mantine-primary-color-7: var(--mantine-color-indigo-7);--mantine-primary-color-8: var(--mantine-color-indigo-8);--mantine-primary-color-9: var(--mantine-color-indigo-9);--mantine-color-red-0: #ffeaea;--mantine-color-red-1: #fed4d4;--mantine-color-red-2: #f4a7a8;--mantine-color-red-3: #ec7878;--mantine-color-red-4: #e55050;--mantine-color-red-5: #e03131;--mantine-color-red-6: #e02829;--mantine-color-red-7: #c71a1c;--mantine-color-red-8: #b21218;--mantine-color-red-9: #9c0411;--mantine-color-violet-0: #fce9ff;--mantine-color-violet-1: #f1cfff;--mantine-color-violet-2: #e09bff;--mantine-color-violet-3: #d16fff;--mantine-color-violet-4: #be37fe;--mantine-color-violet-5: #b51afe;--mantine-color-violet-6: #b009ff;--mantine-color-violet-7: #9b00e4;--mantine-color-violet-8: #8a00cc;--mantine-color-violet-9: #7800b3;--mantine-color-indigo-0: #edecff;--mantine-color-indigo-1: #d6d5fe;--mantine-color-indigo-2: #aaa9f4;--mantine-color-indigo-3: #7b79eb;--mantine-color-indigo-4: #5451e4;--mantine-color-indigo-5: #3b37e0;--mantine-color-indigo-6: #2d2adf;--mantine-color-indigo-7: #1f1ec7;--mantine-color-indigo-8: #1819b2;--mantine-color-indigo-9: #0c149e;--mantine-color-cyan-0: #dffdff;--mantine-color-cyan-1: #caf5ff;--mantine-color-cyan-2: #99e8ff;--mantine-color-cyan-3: #64daff;--mantine-color-cyan-4: #3ccffe;--mantine-color-cyan-5: #24c8fe;--mantine-color-cyan-6: #00c2ff;--mantine-color-cyan-7: #00ade4;--mantine-color-cyan-8: #009acd;--mantine-color-cyan-9: #0085b5;--mantine-color-green-0: #e9fdec;--mantine-color-green-1: #d7f6dc;--mantine-color-green-2: #b0eab9;--mantine-color-green-3: #86df94;--mantine-color-green-4: #62d574;--mantine-color-green-5: #4ccf5f;--mantine-color-green-6: #3fcc54;--mantine-color-green-7: #2fb344;--mantine-color-green-8: #25a03b;--mantine-color-green-9: #138a2e;--mantine-color-yellow-0: #fff7e2;--mantine-color-yellow-1: #ffeecd;--mantine-color-yellow-2: #ffdc9c;--mantine-color-yellow-3: #ffc966;--mantine-color-yellow-4: #feb93a;--mantine-color-yellow-5: #feae1e;--mantine-color-yellow-6: #ffa90f;--mantine-color-yellow-8: #ca8200;--mantine-color-yellow-9: #af7000;--mantine-h1-font-size: clamp(28.0000px, calc(23.6364px + 1.3636vw), 40.0000px);--mantine-h1-font-weight: normal;--mantine-h2-font-size: clamp(24.0000px, calc(21.0909px + 0.9091vw), 32.0000px);--mantine-h2-font-weight: normal;--mantine-h3-font-size: clamp(20.0000px, calc(17.0909px + 0.9091vw), 28.0000px);--mantine-h3-font-weight: normal;--mantine-h4-font-size: clamp(16.0000px, calc(13.0909px + 0.9091vw), 24.0000px);--mantine-h4-font-weight: normal;--mantine-h5-font-size: clamp(16.0000px, calc(14.5455px + 0.4545vw), 20.0000px);--mantine-h5-font-weight: normal;--mantine-h6-font-size: 1rem;--mantine-h6-font-weight: normal;}
:root[data-mantine-color-scheme="dark"], :host([data-mantine-color-scheme="dark"]){--mantine-color-anchor: var(--mantine-color-text);--mantine-color-dimmed: #495057;--mantine-color-dark-filled: var(--mantine-color-dark-5);--mantine-color-dark-filled-hover: var(--mantine-color-dark-6);--mantine-color-dark-light: rgba(105, 105, 105, 0.15);--mantine-color-dark-light-hover: rgba(105, 105, 105, 0.2);--mantine-color-dark-light-color: var(--mantine-color-dark-0);--mantine-color-dark-outline: var(--mantine-color-dark-1);--mantine-color-dark-outline-hover: rgba(184, 184, 184, 0.05);--mantine-color-gray-filled: var(--mantine-color-gray-5);--mantine-color-gray-filled-hover: var(--mantine-color-gray-6);--mantine-color-gray-light: rgba(222, 226, 230, 0.15);--mantine-color-gray-light-hover: rgba(222, 226, 230, 0.2);--mantine-color-gray-light-color: var(--mantine-color-gray-0);--mantine-color-gray-outline: var(--mantine-color-gray-1);--mantine-color-gray-outline-hover: rgba(241, 243, 245, 0.05);--mantine-color-red-filled: var(--mantine-color-red-5);--mantine-color-red-filled-hover: var(--mantine-color-red-6);--mantine-color-red-light: rgba(236, 120, 120, 0.15);--mantine-color-red-light-hover: rgba(236, 120, 120, 0.2);--mantine-color-red-light-color: var(--mantine-color-red-0);--mantine-color-red-outline: var(--mantine-color-red-1);--mantine-color-red-outline-hover: rgba(254, 212, 212, 0.05);--mantine-color-pink-filled: var(--mantine-color-pink-5);--mantine-color-pink-filled-hover: var(--mantine-color-pink-6);--mantine-color-pink-light: rgba(250, 162, 193, 0.15);--mantine-color-pink-light-hover: rgba(250, 162, 193, 0.2);--mantine-color-pink-light-color: var(--mantine-color-pink-0);--mantine-color-pink-outline: var(--mantine-color-pink-1);--mantine-color-pink-outline-hover: rgba(255, 222, 235, 0.05);--mantine-color-grape-filled: var(--mantine-color-grape-5);--mantine-color-grape-filled-hover: var(--mantine-color-grape-6);--mantine-color-grape-light: rgba(229, 153, 247, 0.15);--mantine-color-grape-light-hover: rgba(229, 153, 247, 0.2);--mantine-color-grape-light-color: var(--mantine-color-grape-0);--mantine-color-grape-outline: var(--mantine-color-grape-1);--mantine-color-grape-outline-hover: rgba(243, 217, 250, 0.05);--mantine-color-violet-filled: var(--mantine-color-violet-5);--mantine-color-violet-filled-hover: var(--mantine-color-violet-6);--mantine-color-violet-light: rgba(209, 111, 255, 0.15);--mantine-color-violet-light-hover: rgba(209, 111, 255, 0.2);--mantine-color-violet-light-color: var(--mantine-color-violet-0);--mantine-color-violet-outline: var(--mantine-color-violet-1);--mantine-color-violet-outline-hover: rgba(241, 207, 255, 0.05);--mantine-color-indigo-filled: var(--mantine-color-indigo-5);--mantine-color-indigo-filled-hover: var(--mantine-color-indigo-6);--mantine-color-indigo-light: rgba(123, 121, 235, 0.15);--mantine-color-indigo-light-hover: rgba(123, 121, 235, 0.2);--mantine-color-indigo-light-color: var(--mantine-color-indigo-0);--mantine-color-indigo-outline: var(--mantine-color-indigo-1);--mantine-color-indigo-outline-hover: rgba(214, 213, 254, 0.05);--mantine-color-blue-filled: var(--mantine-color-blue-5);--mantine-color-blue-filled-hover: var(--mantine-color-blue-6);--mantine-color-blue-light: rgba(116, 192, 252, 0.15);--mantine-color-blue-light-hover: rgba(116, 192, 252, 0.2);--mantine-color-blue-light-color: var(--mantine-color-blue-0);--mantine-color-blue-outline: var(--mantine-color-blue-1);--mantine-color-blue-outline-hover: rgba(208, 235, 255, 0.05);--mantine-color-cyan-filled: var(--mantine-color-cyan-5);--mantine-color-cyan-filled-hover: var(--mantine-color-cyan-6);--mantine-color-cyan-light: rgba(100, 218, 255, 0.15);--mantine-color-cyan-light-hover: rgba(100, 218, 255, 0.2);--mantine-color-cyan-light-color: var(--mantine-color-cyan-0);--mantine-color-cyan-outline: var(--mantine-color-cyan-1);--mantine-color-cyan-outline-hover: rgba(202, 245, 255, 0.05);--mantine-color-teal-filled: var(--mantine-color-teal-5);--mantine-color-teal-filled-hover: var(--mantine-color-teal-6);--mantine-color-teal-light: rgba(99, 230, 190, 0.15);--mantine-color-teal-light-hover: rgba(99, 230, 190, 0.2);--mantine-color-teal-light-color: var(--mantine-color-teal-0);--mantine-color-teal-outline: var(--mantine-color-teal-1);--mantine-color-teal-outline-hover: rgba(195, 250, 232, 0.05);--mantine-color-green-filled: var(--mantine-color-green-5);--mantine-color-green-filled-hover: var(--mantine-color-green-6);--mantine-color-green-light: rgba(134, 223, 148, 0.15);--mantine-color-green-light-hover: rgba(134, 223, 148, 0.2);--mantine-color-green-light-color: var(--mantine-color-green-0);--mantine-color-green-outline: var(--mantine-color-green-1);--mantine-color-green-outline-hover: rgba(215, 246, 220, 0.05);--mantine-color-lime-filled: var(--mantine-color-lime-5);--mantine-color-lime-filled-hover: var(--mantine-color-lime-6);--mantine-color-lime-light: rgba(192, 235, 117, 0.15);--mantine-color-lime-light-hover: rgba(192, 235, 117, 0.2);--mantine-color-lime-light-color: var(--mantine-color-lime-0);--mantine-color-lime-outline: var(--mantine-color-lime-1);--mantine-color-lime-outline-hover: rgba(233, 250, 200, 0.05);--mantine-color-yellow-filled: var(--mantine-color-yellow-5);--mantine-color-yellow-filled-hover: var(--mantine-color-yellow-6);--mantine-color-yellow-light: rgba(255, 201, 102, 0.15);--mantine-color-yellow-light-hover: rgba(255, 201, 102, 0.2);--mantine-color-yellow-light-color: var(--mantine-color-yellow-0);--mantine-color-yellow-outline: var(--mantine-color-yellow-1);--mantine-color-yellow-outline-hover: rgba(255, 238, 205, 0.05);--mantine-color-orange-filled: var(--mantine-color-orange-5);--mantine-color-orange-filled-hover: var(--mantine-color-orange-6);--mantine-color-orange-light: rgba(255, 192, 120, 0.15);--mantine-color-orange-light-hover: rgba(255, 192, 120, 0.2);--mantine-color-orange-light-color: var(--mantine-color-orange-0);--mantine-color-orange-outline: var(--mantine-color-orange-1);--mantine-color-orange-outline-hover: rgba(255, 232, 204, 0.05);--app-cta-gradient: linear-gradient(90deg, var(--mantine-color-blue-9) 0%, var(--mantine-color-cyan-7) 100%);--app-color-surface: #2e2e2e;}
:root[data-mantine-color-scheme="light"], :host([data-mantine-color-scheme="light"]){--mantine-color-anchor: var(--mantine-color-text);--mantine-color-dimmed: #495057;--mantine-color-red-light: rgba(224, 40, 41, 0.1);--mantine-color-red-light-hover: rgba(224, 40, 41, 0.12);--mantine-color-red-outline-hover: rgba(224, 40, 41, 0.05);--mantine-color-violet-light: rgba(176, 9, 255, 0.1);--mantine-color-violet-light-hover: rgba(176, 9, 255, 0.12);--mantine-color-violet-outline-hover: rgba(176, 9, 255, 0.05);--mantine-color-indigo-light: rgba(45, 42, 223, 0.1);--mantine-color-indigo-light-hover: rgba(45, 42, 223, 0.12);--mantine-color-indigo-outline-hover: rgba(45, 42, 223, 0.05);--mantine-color-cyan-light: rgba(0, 194, 255, 0.1);--mantine-color-cyan-light-hover: rgba(0, 194, 255, 0.12);--mantine-color-cyan-outline-hover: rgba(0, 194, 255, 0.05);--mantine-color-green-light: rgba(63, 204, 84, 0.1);--mantine-color-green-light-hover: rgba(63, 204, 84, 0.12);--mantine-color-green-outline-hover: rgba(63, 204, 84, 0.05);--mantine-color-yellow-light: rgba(255, 169, 15, 0.1);--mantine-color-yellow-light-hover: rgba(255, 169, 15, 0.12);--mantine-color-yellow-outline-hover: rgba(255, 169, 15, 0.05);--app-color-surface: #f1f3f5;--app-cta-gradient: linear-gradient(90deg, var(--mantine-color-blue-filled) 0%, var(--mantine-color-cyan-5) 100%);}</style><style data-mantine-styles="classes">@media (max-width: 35.99375em) {.mantine-visible-from-xs {display: none !important;}}@media (min-width: 36em) {.mantine-hidden-from-xs {display: none !important;}}@media (max-width: 47.99375em) {.mantine-visible-from-sm {display: none !important;}}@media (min-width: 48em) {.mantine-hidden-from-sm {display: none !important;}}@media (max-width: 61.99375em) {.mantine-visible-from-md {display: none !important;}}@media (min-width: 62em) {.mantine-hidden-from-md {display: none !important;}}@media (max-width: 74.99375em) {.mantine-visible-from-lg {display: none !important;}}@media (min-width: 75em) {.mantine-hidden-from-lg {display: none !important;}}@media (max-width: 87.99375em) {.mantine-visible-from-xl {display: none !important;}}@media (min-width: 88em) {.mantine-hidden-from-xl {display: none !important;}}</style><script type="application/ld+json">{"@context":"https://schema.org","@type":"QAPage","mainEntity":{"@type":"Question","name":"Рекурсия","answerCount":2,"datePublished":"2023-06-05T10:02:27.408Z","author":{"@type":"Person","name":"Nikolai Gagarinov"},"acceptedAnswer":{"@type":"Answer","text":"\nВ программировании есть понятие, которое одновременно пугает новичков и восхищает опытных разработчиков. Это — рекурсия. Её часто описывают как «функцию, вызывающую саму себя», но за этой фразой скрывается целая философия построения алгоритмов.\n\n\n\n## Что такое рекурсия простыми словами\n\nВ самом широком смысле это — повторение действия внутри самого себя. Представьте два зеркала, стоящих друг напротив друга: в каждом отражении — новое, чуть меньшее, и так до бесконечности. Примерно так работает рекурсивный процесс: функция видит задачу, решает её частично и передаёт оставшуюся часть… самой себе. В программировании рекурсия — это метод решения задач через повторные вызовы одной и той же функции, но с изменёнными аргументами. Каждый вызов приближает программу к «точке останова» — моменту, когда повторения прекращаются.\n\n### Интуитивное объяснение\n\nПредставьте, что вы стоите между двумя зеркалами, направленными друг на друга. Вы видите цепочку бесконечных отражений, уходящую вдаль. То же самое происходит при рекурсии: функция вызывает саму себя снова и снова — пока не достигнет определённого условия, после чего начинает «возвращаться» обратно.\n\n### Ключевые термины\n\nЧтобы понять механику, нужно знать три основных понятия:\n\n* **Рекурсивная функция** — функция, которая вызывает сама себя.\n* **База рекурсии** — условие, при котором процесс прекращается. Без базы программа зациклится.\n* **Шаг рекурсии** — часть, в которой функция вызывает себя для решения меньшей задачи.\n\n**Пример:**\nЕсли мы хотим посчитать количество файлов в папке, мы можем пройти по каждому элементу, а если встречаем вложенную папку — снова вызвать ту же функцию. Так программа обходит всю структуру до конца, пока не останется ни одного непроверенного каталога.\n\n## Как работает рекурсия в программировании\n\nЭто не магия, а строгий механизм. Он строится на стеке вызовов — области памяти, где хранятся активные функции.\n\n### Механизм работы\n\n1. Функция вызывает сама себя, передавая изменённые аргументы.\n2. Каждый новый вызов помещается в стек — как карточка поверх другой.\n3. Когда достигается база рекурсии, функция перестаёт вызывать себя и начинает возвращать результаты «вверх».\n\n### База и условие выхода\n\nГлавное правило — в каждой рекурсии должна быть точка остановки. Если её нет, программа будет вызывать себя бесконечно, пока не переполнит стек и не завершится с ошибкой (RecursionError в Python).\n\n### Прямой и обратный ход\n\n* **Прямой ход** — функция вызывает саму себя, углубляясь в задачу.\n* **Обратный ход** — выполнение идёт назад, собирая результаты из стека вызовов.\n\nПример псевдокода:\n\n```python\ndef recurse(n):\n if n == 0: # база рекурсии\n return 1\n else:\n return n * recurse(n - 1)\n```\n\nПри вызове recurse(3) произойдёт следующее:\n\n1. 3 → вызывает recurse(2)\n2. 2 → вызывает recurse(1)\n3. 1 → вызывает recurse(0)\n4. 0 — база рекурсии, возврат 1\n5. Далее значения перемножаются обратно: `1 * 2 * 3 = 6`\n\n## Разновидности рекурсии\n\nПонятие классифицируется в зависимости от того, как и где функция вызывает саму себя.\n\n### 1. Прямая\n\nФункция вызывает саму себя напрямую.\n\n```python\ndef countdown(n):\n if n > 0:\n print(n)\n countdown(n - 1)\n```\n\n### 2. Косвенная\n\nФункция А вызывает функцию B, а та снова вызывает функцию А.\n\n```python\ndef funcA(x):\n if x > 0:\n funcB(x - 1)\n\ndef funcB(x):\n if x > 0:\n funcA(x - 1)\n```\n\n### 3. Линейная и каскадная\n\n* **Линейная** — один рекурсивный вызов в теле функции.\n* **Каскадная (многоступенчатая)** — функция вызывает себя несколько раз.\n Пример: вычисление чисел Фибоначчи, где fib(n) = fib(n-1) + fib(n-2).\n\n### 4. Хвостовая рекурсия (tail recursion)\n\nОсобый вид, при котором результат вычислений не зависит от последующих вызовов. Такая форма может быть оптимизирована компилятором — стек не растёт, и программа работает как цикл.\n\n**Пример:**\n\n```python\ndef factorial(n, acc=1):\n if n == 0:\n return acc\n return factorial(n - 1, acc * n)\n```\n\nЗдесь на каждом шаге результат передаётся как параметр (acc), поэтому новые вызовы не накапливаются в стеке.\n\n## Отличия от цикла\n\n| Параметр | Рекурсия | Цикл |\n|:-----------------------------|:-----------------------------------------|:----------------------------------------|\n| **Принцип работы** | Функция вызывает саму себя | Команда повторяется внутри одного блока |\n| | | |\n| **Механизм хранения данных** | Стек вызовов | Переменные в текущей области памяти |\n| **Понятность кода** | Часто проще и короче | Иногда громоздко, но очевидно |\n| **Производительность** | Медленнее из-за накладных расходов стека | Быстрее, оптимизирован процессором |\n| **Риск ошибок** | Переполнение стека, бесконечный вызов | Бесконечный цикл при ошибке в условии |\n| **Применение** | Деревья, графы, рекурсивные формулы | Повторяющиеся линейные операции |\n\n## Преимущества и недостатки\n\nРекурсия — инструмент мощный, но требующий осторожности. Её плюсы и минусы лучше всего видны при сравнении с итерацией.\n\n### Преимущества\n\n* **Краткость и читаемость.** Рекурсивные функции лаконичны, особенно в алгоритмах с ветвлениями.\n* **Наглядность.** Код часто ближе к математической логике и проще для понимания принципа.\n* **Естественное решение.** Для деревьев, графов или вложенных структур рекурсия логичнее, чем цикл.\n\n### Недостатки\n\n* **Переполнение стека.** При слишком глубокой рекурсии память заканчивается.\n* **Сложность отладки.** Ошибка в базе может привести к бесконечным вызовам.\n* **Скорость.** Рекурсия часто медленнее, чем эквивалентный цикл.\n\n## Примеры в программировании\n\n### 1. Расчёт факториала\n\nФакториал числа n! = 1 × 2 × … × n. Через рекурсию это выглядит максимально просто:\n\n```python\ndef factorial(n):\n if n == 0:\n return 1 # база return n * factorial(n - 1) # шаг print(factorial(5)) # 120\n```\n\nКаждый вызов умножает текущее число на результат следующего, пока не достигнет нуля.\n\n### 2. Числа Фибоначчи\n\nКаждое число — сумма двух предыдущих: `F(n) = F(n-1) + F(n-2)`.\n\n```python\ndef fib(n):\n if n <= 1:\n return n\n return fib(n-1) + fib(n-2)\n```\n\nВызов fib(5) даст последовательность вызовов:\n\n```text\nfib(5) → fib(4) + fib(3)fib(4) → fib(3) + fib(2)...\n```\nРезультат — 5. Однако это пример неэффективной рекурсии, потому что многие значения вычисляются по нескольку раз. Для ускорения применяют мемоизацию (кэширование результатов).\n\n### 3. Обход дерева\n\nРекурсия незаменима при работе с древовидными структурами — файлами, XML, JSON, каталогами.\n\n```python\ndef traverse(node):\n print(node.value)\n for child in node.children:\n traverse(child)\n```\nКаждый узел вызывает ту же функцию для своих потомков, пока дерево не обойдётся целиком.\n\n### 4. Поиск пути в лабиринте\n\nВ играх и алгоритмах навигации рекурсия позволяет искать выход, перебирая соседние клетки:\n\n```python\ndef find_exit(maze, x, y):\n if maze[x][y] == 'exit':\n return True mark_as_visited(x, y)\n for next in neighbours(x, y):\n if find_exit(maze, next.x, next.y):\n return True\n return False\n```\n\nКаждый шаг вызывает функцию для соседней клетки, пока не найдёт путь.\n\n## Баланс между красотой и эффективностью\n\nОпытные разработчики стараются находить компромисс: если задача может быть решена итеративно без потери понятности — выбирают цикл. Если же структура данных сама по себе рекурсивна (например, JSON или дерево DOM), то рекурсивный подход оказывается естественнее и надёжнее.\n\n\n\n## За пределами программирования\n\nХотя чаще всего рекурсия упоминается в контексте кода, этот принцип встречается повсюду — от математики до биологии и искусства.\n\n### В математике\n\nРекурсивные формулы описывают последовательности, где каждый элемент зависит от предыдущих: числа Фибоначчи, факториалы, фракталы, степенные ряды. Рекурсивное мышление помогает строить доказательства по индукции — шаг за шагом, от простого к сложному.\n\n### В биологии\n\nПрирода любит повторения. Форма листа повторяет очертания ветви, а ветвь — всего дерева.\n Фрактальная структура лёгких, кровеносных сосудов или береговой линии — это естественные проявления рекурсии.\n\n### В гуманитарных дисциплинах\n\nВ грамматике: предложение может содержать другое предложение. Например: «Я знаю, что ты знаешь, что он сказал». В литературе — «вложенные истории»: рассказ внутри рассказа. В живописи — отражения, зеркала, повторяющиеся мотивы. В философии — это способ мыслить структурно, когда результат на каждом уровне строится на предыдущем.\n\n## \n\n## Как отлаживать и тестировать рекурсивные функции\n\nЧтобы избежать сбоев, важно понимать, где и почему возникает ошибка.\n\n### 1. Проверяйте базу рекурсии\n\nБольше половины проблем — из-за отсутствия или неправильной базы. Функция должна всегда иметь условие выхода, которое гарантирует завершение.\n\n### 2. Тестируйте на простых примерах\n\nНачинайте с минимальных данных (n=0, n=1). Если функция корректно работает для них, можно проверять большие значения.\n\n### 3. Используйте отладчик IDE\n\nБольшинство IDE (PyCharm, VS Code, IntelliJ) позволяют пройти рекурсивный процесс пошагово. Вы увидите, как аргументы меняются при каждом вызове и где цикл заходит в тупик.\n\n### 4. Контролируйте глубину стека\n\nВ Python есть ограничение по умолчанию — около 1000 вызовов. Если рекурсия может быть глубже, нужно: import syssys.setrecursionlimit(3000). Но лучше оптимизировать алгоритм или перейти на итерацию.\n\n### 5. Используйте вывод логов\n\nДобавьте печать входящих аргументов — иногда простая строка print(n) показывает, где именно «застрял» вызов.\n\n## Сценарии выбора\n\n| Сценарий | Рекурсия | Циклы |\n|:--------------------------------------------:|:------------------:|:----------------------:|\n| Обход дерева, графа, каталогов | Лучше использовать | |\n| Вычисление факториала или Фибоначчи | Для обучения | Для практических задач |\n| Обработка массивов, фильтрация | | Предпочтительно |\n| Простые повторения | | Оптимально |\n| Алгоритмы поиска (DFS, QuickSort, MergeSort) | Эффективно | |\n\nХорошее правило: если алгоритм можно описать фразой «вызови себя для подзадачи» — рекурсия естественна. А если речь идёт о «повтори то же действие несколько раз» — цикл проще и надёжнее.\n\n## Типичные ошибки начинающих программистов\n\n1. **Отсутствие условия выхода.** Функция уходит в бесконечный вызов и вызывает переполнение стека.\n2. **Неправильное изменение аргумента.** Например, n не уменьшается на каждом шаге.\n3. **Лишние вычисления.** Повторные вызовы с одними и теми же аргументами замедляют работу.\n Решение — мемоизация (lru_cache в Python).\n4. **Потеря возвращаемого значения.** Забыто return, из-за чего результат не возвращается обратно.\n5. **Попытка решить всё рекурсией.** Иногда проще и быстрее использовать цикл — это не «менее красиво», а просто практичнее.\n\n## С чего начать изучение\n\nБыстро освоить процесс можно, если двигаться от простого к сложному — рекурсивно, в буквальном смысле.\n\n### 1. Начните с визуальных аналогий\n\nПредставьте матрёшку, зеркала или русло реки, где каждый уровень повторяет предыдущий.\n Такой образ помогает понять идею самоподобия.\n\n### 2. Решайте базовые задачи\n\n* Факториал числа.\n* Подсчёт суммы элементов списка.\n* Разворот строки.\n* Поиск элемента в дереве.\n\nСначала пишите рекурсивно, потом попробуйте переписать в цикле — чтобы увидеть разницу.\n\n### 3. Используйте курсы и книги\n\n* **Hexlet:** курсы по алгоритмам и Python включают раздел с наглядными примерами.\n* **Coursera / edX:** курсы по компьютерным наукам (CS50, Algorithms I).\n* Книги:\n\n * «Грокаем алгоритмы» Адитьи Бхаргавы;\n * «Structure and Interpretation of Computer Programs» (SICP).\n\n### 4. Практикуйтесь в визуализации\n\nСервисы вроде Python Tutor или Visualgo.net позволяют пошагово проследить, как функция вызывает саму себя.\n\n## Заключение\n\nРекурсия — не просто техника программирования, а способ мышления, позволяющий видеть задачи как цепочки взаимосвязанных шагов. Она учит структурировать решения, выделять базу, мыслить от общего к частному. Для программиста это — фундаментальная идея, лежащая в основе множества алгоритмов: от сортировок и обхода графов до работы компиляторов и нейросетей. Освоив рекурсивные тонкости, вы начинаете понимать логику программирования на глубоком уровне — где каждая задача сводится к меньшей версии самой себя. И что сам процесс её изучения — тоже рекурсивен.\n","datePublished":"2025-11-24T19:28:30.984Z","upvoteCount":1,"author":{"@type":"Person","name":"Nikolai Gagarinov"},"url":"https://ru.hexlet.io/qna/glossary/questions/chto-takoe-rekursiya#answer-5225"},"suggestedAnswer":[{"@type":"Answer","text":"Рекурсия - это процесс повторения определенной операции или действия. В программировании рекурсия используется для описания алгоритмов, которые содержат внутри себя вызовы самих себя. Это позволяет создавать более компактные и понятные алгоритмы, а также увеличивает эффективность их работы.","datePublished":"2023-11-16T12:09:14.950Z","upvoteCount":0,"author":{"@type":"Person","name":"Елена Редькина"},"url":"https://ru.hexlet.io/qna/glossary/questions/chto-takoe-rekursiya#answer-3035"}]}}</script><div style="--container-size:var(--container-size-lg);margin-top:var(--mantine-spacing-xl);height:100%" class="m_7485cace mantine-Container-root" data-size="lg" data-strategy="block"><script type="application/ld+json">{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"position":1,"@type":"ListItem","item":{"@id":"/qna","name":"Вопросы и ответы"}},{"position":2,"@type":"ListItem","item":{"@id":"/qna/glossary/questions","name":"Глоссарий"}},{"position":3,"@type":"ListItem","item":{"@id":"/qna/glossary/questions/chto-takoe-rekursiya","name":"Рекурсия"}}]}</script><div style="margin-bottom:var(--mantine-spacing-xs)" class="m_8b3717df mantine-Breadcrumbs-root"><a style="--text-fz:var(--mantine-font-size-sm);--text-lh:var(--mantine-line-height-sm);white-space:normal;color:inherit" class="mantine-focus-auto m_849cf0da m_f678d540 mantine-Breadcrumbs-breadcrumb m_b6d8b162 mantine-Text-root mantine-Anchor-root" data-size="sm" data-underline="hover" href="/"><div style="color:inherit" class="m_4451eb3a mantine-Center-root"><svg xmlns="http://www.w3.org/2000/svg" width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-home-link "><path d="M20.085 11.085l-8.085 -8.085l-9 9h2v7a2 2 0 0 0 2 2h4.5"></path><path d="M9 21v-6a2 2 0 0 1 2 -2h2a2 2 0 0 1 1.807 1.143"></path><path d="M20 21a1 1 0 1 0 2 0a1 1 0 1 0 -2 0"></path><path d="M20 16a1 1 0 1 0 2 0a1 1 0 1 0 -2 0"></path><path d="M15 19a1 1 0 1 0 2 0a1 1 0 1 0 -2 0"></path><path d="M21 16l-5 3l5 2"></path></svg></div></a><div class="m_3b8f2208 mantine-Breadcrumbs-separator">/</div><a style="--text-fz:var(--mantine-font-size-sm);--text-lh:var(--mantine-line-height-sm);white-space:normal;color:inherit" class="mantine-focus-auto m_849cf0da m_f678d540 mantine-Breadcrumbs-breadcrumb m_b6d8b162 mantine-Text-root mantine-Anchor-root" data-size="sm" data-underline="hover" href="/qna">Вопросы и ответы</a><div class="m_3b8f2208 mantine-Breadcrumbs-separator">/</div><a style="--text-fz:var(--mantine-font-size-sm);--text-lh:var(--mantine-line-height-sm);white-space:normal;color:inherit" class="mantine-focus-auto m_849cf0da m_f678d540 mantine-Breadcrumbs-breadcrumb m_b6d8b162 mantine-Text-root mantine-Anchor-root" data-size="sm" data-underline="hover" href="/qna/glossary/questions">Глоссарий</a><div class="m_3b8f2208 mantine-Breadcrumbs-separator">/</div><p style="--text-fz:var(--mantine-font-size-sm);--text-lh:var(--mantine-line-height-sm);white-space:normal;color:var(--mantine-color-dimmed)" class="mantine-focus-auto m_f678d540 mantine-Breadcrumbs-breadcrumb m_b6d8b162 mantine-Text-root" data-size="sm">Рекурсия</p></div><style data-mantine-styles="inline">.__m__-_R_eub_{margin-bottom:var(--mantine-spacing-xs);}@media(min-width: 36em){.__m__-_R_eub_{margin-bottom:var(--mantine-spacing-xs);}}</style><div style="--group-gap:var(--mantine-spacing-md);--group-align:center;--group-justify:space-between;--group-wrap:wrap" class="m_4081bf90 mantine-Group-root __m__-_R_eub_"><style data-mantine-styles="inline">.__m__-_R_deub_{width:100%;}@media(min-width: 36em){.__m__-_R_deub_{width:70%;}}@media(min-width: 75em){.__m__-_R_deub_{width:75%;}}</style><div class="__m__-_R_deub_"><div style="--group-gap:var(--mantine-spacing-md);--group-align:center;--group-justify:start;--group-wrap:nowrap" class="m_4081bf90 mantine-Group-root"><h1 style="--title-fw:var(--mantine-h1-font-weight);--title-lh:var(--mantine-h1-line-height);--title-fz:var(--mantine-h1-font-size)" class="m_8a5d1357 mantine-Title-root" data-order="1">Рекурсия</h1></div></div></div><style data-mantine-styles="inline">.__m__-_R_iub_{--grid-gutter:var(--mantine-spacing-md);}</style><div class="m_410352e9 mantine-Grid-root __m__-_R_iub_"><div class="m_dee7bd2f mantine-Grid-inner"><style data-mantine-styles="inline">.__m__-_R_3diub_{--col-flex-grow:auto;--col-flex-basis:100%;--col-max-width:100%;}@media(min-width: 48em){.__m__-_R_3diub_{--col-flex-grow:auto;--col-flex-basis:83.33333333333334%;--col-max-width:83.33333333333334%;}}@media(min-width: 62em){.__m__-_R_3diub_{--col-flex-grow:auto;--col-flex-basis:66.66666666666667%;--col-max-width:66.66666666666667%;}}</style><div class="m_96bdd299 mantine-Grid-col __m__-_R_3diub_"><div style="--group-gap:var(--mantine-spacing-md);--group-align:center;--group-justify:flex-start;--group-wrap:wrap;margin-bottom:var(--mantine-spacing-lg)" class="m_4081bf90 mantine-Group-root"></div><div style="--group-gap:var(--mantine-spacing-md);--group-align:center;--group-justify:flex-start;--group-wrap:wrap;margin-bottom:var(--mantine-spacing-xl);font-size:var(--mantine-font-size-sm)" class="m_4081bf90 mantine-Group-root"><div style="--group-gap:calc(0.25rem * var(--mantine-scale));--group-align:center;--group-justify:flex-start;--group-wrap:wrap;margin-inline-start:auto" class="m_4081bf90 mantine-Group-root"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-calendar "><path d="M4 7a2 2 0 0 1 2 -2h12a2 2 0 0 1 2 2v12a2 2 0 0 1 -2 2h-12a2 2 0 0 1 -2 -2v-12"></path><path d="M16 3v4"></path><path d="M8 3v4"></path><path d="M4 11h16"></path><path d="M11 15h1"></path><path d="M12 15v3"></path></svg><p class="mantine-focus-auto m_b6d8b162 mantine-Text-root" data-inherit="true">3 года назад</p></div><div style="--group-gap:calc(0.25rem * var(--mantine-scale));--group-align:center;--group-justify:flex-start;--group-wrap:wrap" class="m_4081bf90 mantine-Group-root"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-user "><path d="M8 7a4 4 0 1 0 8 0a4 4 0 0 0 -8 0"></path><path d="M6 21v-2a4 4 0 0 1 4 -4h4a4 4 0 0 1 4 4v2"></path></svg><p class="mantine-focus-auto m_b6d8b162 mantine-Text-root" data-inherit="true">Nikolai Gagarinov</p></div></div><div role="link" tabindex="0" style="cursor:pointer"><button style="display:block;width:100%" class="mantine-focus-auto m_87cf2631 mantine-UnstyledButton-root" type="button" aria-label="Присоединяйтесь к нашему Telegram-сообществу"><div style="background-color:light-dark(var(--mantine-color-gray-1), var(--mantine-color-dark-6));margin-block:var(--mantine-spacing-xs)" class="m_e615b15f mantine-Card-root m_1b7284a3 mantine-Paper-root"><div style="--group-gap:var(--mantine-spacing-md);--group-align:center;--group-justify:flex-start;--group-wrap:wrap" class="m_4081bf90 mantine-Group-root"><div style="--ti-bg:transparent;--ti-color:var(--mantine-color-indigo-light-color);--ti-bd:calc(0.0625rem * var(--mantine-scale)) solid transparent;margin-inline-end:auto;color:inherit" class="m_7341320d mantine-ThemeIcon-root" data-variant="transparent"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-brand-telegram "><path d="M15 10l-4 4l6 6l4 -16l-18 7l4 2l2 6l3 -4"></path></svg></div>Присоединяйтесь к нашему Telegram-сообществу</div></div></button></div><h2 style="--title-fw:var(--mantine-h2-font-weight);--title-lh:var(--mantine-h2-line-height);--title-fz:var(--mantine-h2-font-size);margin-block:var(--mantine-spacing-xl)" class="m_8a5d1357 mantine-Title-root" data-order="2">Ответы</h2><div style="margin-bottom:var(--mantine-spacing-xl);padding:var(--mantine-spacing-lg)" class="m_e615b15f mantine-Card-root m_1b7284a3 mantine-Paper-root" data-with-border="true" id="answer-5225"><div style="--group-gap:calc(1.125rem * var(--mantine-scale));--group-align:stretch;--group-justify:flex-start;--group-wrap:nowrap" class="m_4081bf90 mantine-Group-root"><div style="--stack-gap:var(--mantine-spacing-md);--stack-align:stretch;--stack-justify:flex-start;font-size:var(--mantine-font-size-h1);font-weight:lighter;text-align:center" class="m_6d731127 mantine-Stack-root">1<a style="color:inherit" class="mantine-focus-auto m_849cf0da m_b6d8b162 mantine-Text-root mantine-Anchor-root" data-underline="hover" href="/qna/glossary/questions/chto-takoe-rekursiya/answers/5225/vote"><div style="--ti-bg:transparent;--ti-color:var(--mantine-color-indigo-light-color);--ti-bd:calc(0.0625rem * var(--mantine-scale)) solid transparent;color:inherit" class="m_7341320d mantine-ThemeIcon-root" data-variant="transparent"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-thumb-up "><path d="M7 11v8a1 1 0 0 1 -1 1h-2a1 1 0 0 1 -1 -1v-7a1 1 0 0 1 1 -1h3a4 4 0 0 0 4 -4v-1a2 2 0 0 1 4 0v5h3a2 2 0 0 1 2 2l-1 5a2 3 0 0 1 -2 2h-7a3 3 0 0 1 -3 -3"></path></svg></div></a><div style="--ti-bg:transparent;--ti-color:var(--mantine-color-indigo-light-color);--ti-bd:calc(0.0625rem * var(--mantine-scale)) solid transparent;color:inherit" class="m_7341320d mantine-ThemeIcon-root" data-variant="transparent"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-check "><path d="M5 12l5 5l10 -10"></path></svg></div></div><div style="--stack-gap:var(--mantine-spacing-md);--stack-align:stretch;--stack-justify:flex-start;width:100%;min-width:0rem" class="m_6d731127 mantine-Stack-root"><div style="margin-bottom:auto" class="m_d08caa0 mantine-Typography-root"><p>В программировании есть понятие, которое одновременно пугает новичков и восхищает опытных разработчиков. Это — рекурсия. Её часто описывают как «функцию, вызывающую саму себя», но за этой фразой скрывается целая философия построения алгоритмов.</p>
<p><img style="--image-object-fit:contain;width:auto" class="m_9e117634 mantine-Image-root" src="https://cdn6.hexlet.io/kXL2HlnthwaI.png" alt="KXL2HlnthwaI image" loading="lazy"/></p>
<h2 id="heading-2-1">Что такое рекурсия простыми словами</h2>
<p>В самом широком смысле это — повторение действия внутри самого себя. Представьте два зеркала, стоящих друг напротив друга: в каждом отражении — новое, чуть меньшее, и так до бесконечности. Примерно так работает рекурсивный процесс: функция видит задачу, решает её частично и передаёт оставшуюся часть… самой себе. В программировании рекурсия — это метод решения задач через повторные вызовы одной и той же функции, но с изменёнными аргументами. Каждый вызов приближает программу к «точке останова» — моменту, когда повторения прекращаются.</p>
<h3 id="heading-3-2">Интуитивное объяснение</h3>
<p>Представьте, что вы стоите между двумя зеркалами, направленными друг на друга. Вы видите цепочку бесконечных отражений, уходящую вдаль. То же самое происходит при рекурсии: функция вызывает саму себя снова и снова — пока не достигнет определённого условия, после чего начинает «возвращаться» обратно.</p>
<h3 id="heading-3-3">Ключевые термины</h3>
<p>Чтобы понять механику, нужно знать три основных понятия:</p>
<ul>
<li><strong>Рекурсивная функция</strong> — функция, которая вызывает сама себя.</li>
<li><strong>База рекурсии</strong> — условие, при котором процесс прекращается. Без базы программа зациклится.</li>
<li><strong>Шаг рекурсии</strong> — часть, в которой функция вызывает себя для решения меньшей задачи.</li>
</ul>
<p><strong>Пример:</strong>
Если мы хотим посчитать количество файлов в папке, мы можем пройти по каждому элементу, а если встречаем вложенную папку — снова вызвать ту же функцию. Так программа обходит всю структуру до конца, пока не останется ни одного непроверенного каталога.</p>
<h2 id="heading-2-4">Как работает рекурсия в программировании</h2>
<p>Это не магия, а строгий механизм. Он строится на стеке вызовов — области памяти, где хранятся активные функции.</p>
<h3 id="heading-3-5">Механизм работы</h3>
<ol>
<li>Функция вызывает сама себя, передавая изменённые аргументы.</li>
<li>Каждый новый вызов помещается в стек — как карточка поверх другой.</li>
<li>Когда достигается база рекурсии, функция перестаёт вызывать себя и начинает возвращать результаты «вверх».</li>
</ol>
<h3 id="heading-3-6">База и условие выхода</h3>
<p>Главное правило — в каждой рекурсии должна быть точка остановки. Если её нет, программа будет вызывать себя бесконечно, пока не переполнит стек и не завершится с ошибкой (RecursionError в Python).</p>
<h3 id="heading-3-7">Прямой и обратный ход</h3>
<ul>
<li><strong>Прямой ход</strong> — функция вызывает саму себя, углубляясь в задачу.</li>
<li><strong>Обратный ход</strong> — выполнение идёт назад, собирая результаты из стека вызовов.</li>
</ul>
<p>Пример псевдокода:</p>
<div style="margin-bottom:var(--mantine-spacing-lg)" class="m_e597c321 mantine-CodeHighlight-codeHighlight" dir="ltr"><div class="m_be7e9c9c mantine-CodeHighlight-controls"><button style="--ai-bg:transparent;--ai-hover:transparent;--ai-color:inherit;--ai-bd:none" class="mantine-focus-auto mantine-active m_d498bab7 mantine-CodeHighlight-control m_8d3f4000 mantine-ActionIcon-root m_87cf2631 mantine-UnstyledButton-root" data-variant="none" type="button" aria-label="Copy code"><span class="m_8d3afb97 mantine-ActionIcon-icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M8 8m0 2a2 2 0 0 1 2 -2h8a2 2 0 0 1 2 2v8a2 2 0 0 1 -2 2h-8a2 2 0 0 1 -2 -2z"></path><path d="M16 8v-2a2 2 0 0 0 -2 -2h-8a2 2 0 0 0 -2 2v8a2 2 0 0 0 2 2h2"></path></svg></span></button></div><div style="--scrollarea-scrollbar-size:calc(0.25rem * var(--mantine-scale));--sa-corner-width:0px;--sa-corner-height:0px" class="m_f744fd40 mantine-CodeHighlight-scrollarea m_d57069b5 mantine-ScrollArea-root" dir="ltr"><div style="overflow-x:hidden;overflow-y:hidden;overscroll-behavior-inline:none" class="m_c0783ff9 mantine-ScrollArea-viewport" data-scrollbars="xy"><div class="m_b1336c6 mantine-ScrollArea-content"><pre class="m_2c47c4fd mantine-CodeHighlight-pre" style="padding:0"><code class="m_5caae6d3 mantine-CodeHighlight-code">def recurse(n):
if n == 0: # база рекурсии
return 1
else:
return n * recurse(n - 1)</code></pre></div></div></div><button class="mantine-focus-auto m_c9378bc2 mantine-CodeHighlight-showCodeButton m_87cf2631 mantine-UnstyledButton-root" data-hidden="true" type="button">Expand code</button></div>
<p>При вызове recurse(3) произойдёт следующее:</p>
<ol>
<li>3 → вызывает recurse(2)</li>
<li>2 → вызывает recurse(1)</li>
<li>1 → вызывает recurse(0)</li>
<li>0 — база рекурсии, возврат 1</li>
<li>Далее значения перемножаются обратно: <code style="margin-bottom:var(--mantine-spacing-lg)" class="m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight m_e597c321 mantine-CodeHighlight-codeHighlight m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight">1 * 2 * 3 = 6</code></li>
</ol>
<h2 id="heading-2-8">Разновидности рекурсии</h2>
<p>Понятие классифицируется в зависимости от того, как и где функция вызывает саму себя.</p>
<h3 id="heading-3-9">1. Прямая</h3>
<p>Функция вызывает саму себя напрямую.</p>
<div style="margin-bottom:var(--mantine-spacing-lg)" class="m_e597c321 mantine-CodeHighlight-codeHighlight" dir="ltr"><div class="m_be7e9c9c mantine-CodeHighlight-controls"><button style="--ai-bg:transparent;--ai-hover:transparent;--ai-color:inherit;--ai-bd:none" class="mantine-focus-auto mantine-active m_d498bab7 mantine-CodeHighlight-control m_8d3f4000 mantine-ActionIcon-root m_87cf2631 mantine-UnstyledButton-root" data-variant="none" type="button" aria-label="Copy code"><span class="m_8d3afb97 mantine-ActionIcon-icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M8 8m0 2a2 2 0 0 1 2 -2h8a2 2 0 0 1 2 2v8a2 2 0 0 1 -2 2h-8a2 2 0 0 1 -2 -2z"></path><path d="M16 8v-2a2 2 0 0 0 -2 -2h-8a2 2 0 0 0 -2 2v8a2 2 0 0 0 2 2h2"></path></svg></span></button></div><div style="--scrollarea-scrollbar-size:calc(0.25rem * var(--mantine-scale));--sa-corner-width:0px;--sa-corner-height:0px" class="m_f744fd40 mantine-CodeHighlight-scrollarea m_d57069b5 mantine-ScrollArea-root" dir="ltr"><div style="overflow-x:hidden;overflow-y:hidden;overscroll-behavior-inline:none" class="m_c0783ff9 mantine-ScrollArea-viewport" data-scrollbars="xy"><div class="m_b1336c6 mantine-ScrollArea-content"><pre class="m_2c47c4fd mantine-CodeHighlight-pre" style="padding:0"><code class="m_5caae6d3 mantine-CodeHighlight-code">def countdown(n):
if n > 0:
print(n)
countdown(n - 1)</code></pre></div></div></div><button class="mantine-focus-auto m_c9378bc2 mantine-CodeHighlight-showCodeButton m_87cf2631 mantine-UnstyledButton-root" data-hidden="true" type="button">Expand code</button></div>
<h3 id="heading-3-10">2. Косвенная</h3>
<p>Функция А вызывает функцию B, а та снова вызывает функцию А.</p>
<div style="margin-bottom:var(--mantine-spacing-lg)" class="m_e597c321 mantine-CodeHighlight-codeHighlight" dir="ltr"><div class="m_be7e9c9c mantine-CodeHighlight-controls"><button style="--ai-bg:transparent;--ai-hover:transparent;--ai-color:inherit;--ai-bd:none" class="mantine-focus-auto mantine-active m_d498bab7 mantine-CodeHighlight-control m_8d3f4000 mantine-ActionIcon-root m_87cf2631 mantine-UnstyledButton-root" data-variant="none" type="button" aria-label="Copy code"><span class="m_8d3afb97 mantine-ActionIcon-icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M8 8m0 2a2 2 0 0 1 2 -2h8a2 2 0 0 1 2 2v8a2 2 0 0 1 -2 2h-8a2 2 0 0 1 -2 -2z"></path><path d="M16 8v-2a2 2 0 0 0 -2 -2h-8a2 2 0 0 0 -2 2v8a2 2 0 0 0 2 2h2"></path></svg></span></button></div><div style="--scrollarea-scrollbar-size:calc(0.25rem * var(--mantine-scale));--sa-corner-width:0px;--sa-corner-height:0px" class="m_f744fd40 mantine-CodeHighlight-scrollarea m_d57069b5 mantine-ScrollArea-root" dir="ltr"><div style="overflow-x:hidden;overflow-y:hidden;overscroll-behavior-inline:none" class="m_c0783ff9 mantine-ScrollArea-viewport" data-scrollbars="xy"><div class="m_b1336c6 mantine-ScrollArea-content"><pre class="m_2c47c4fd mantine-CodeHighlight-pre" style="padding:0"><code class="m_5caae6d3 mantine-CodeHighlight-code">def funcA(x):
if x > 0:
funcB(x - 1)
def funcB(x):
if x > 0:
funcA(x - 1)</code></pre></div></div></div><button class="mantine-focus-auto m_c9378bc2 mantine-CodeHighlight-showCodeButton m_87cf2631 mantine-UnstyledButton-root" data-hidden="true" type="button">Expand code</button></div>
<h3 id="heading-3-11">3. Линейная и каскадная</h3>
<ul>
<li><strong>Линейная</strong> — один рекурсивный вызов в теле функции.</li>
<li><strong>Каскадная (многоступенчатая)</strong> — функция вызывает себя несколько раз.
Пример: вычисление чисел Фибоначчи, где fib(n) = fib(n-1) + fib(n-2).</li>
</ul>
<h3 id="heading-3-12">4. Хвостовая рекурсия (tail recursion)</h3>
<p>Особый вид, при котором результат вычислений не зависит от последующих вызовов. Такая форма может быть оптимизирована компилятором — стек не растёт, и программа работает как цикл.</p>
<p><strong>Пример:</strong></p>
<div style="margin-bottom:var(--mantine-spacing-lg)" class="m_e597c321 mantine-CodeHighlight-codeHighlight" dir="ltr"><div class="m_be7e9c9c mantine-CodeHighlight-controls"><button style="--ai-bg:transparent;--ai-hover:transparent;--ai-color:inherit;--ai-bd:none" class="mantine-focus-auto mantine-active m_d498bab7 mantine-CodeHighlight-control m_8d3f4000 mantine-ActionIcon-root m_87cf2631 mantine-UnstyledButton-root" data-variant="none" type="button" aria-label="Copy code"><span class="m_8d3afb97 mantine-ActionIcon-icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M8 8m0 2a2 2 0 0 1 2 -2h8a2 2 0 0 1 2 2v8a2 2 0 0 1 -2 2h-8a2 2 0 0 1 -2 -2z"></path><path d="M16 8v-2a2 2 0 0 0 -2 -2h-8a2 2 0 0 0 -2 2v8a2 2 0 0 0 2 2h2"></path></svg></span></button></div><div style="--scrollarea-scrollbar-size:calc(0.25rem * var(--mantine-scale));--sa-corner-width:0px;--sa-corner-height:0px" class="m_f744fd40 mantine-CodeHighlight-scrollarea m_d57069b5 mantine-ScrollArea-root" dir="ltr"><div style="overflow-x:hidden;overflow-y:hidden;overscroll-behavior-inline:none" class="m_c0783ff9 mantine-ScrollArea-viewport" data-scrollbars="xy"><div class="m_b1336c6 mantine-ScrollArea-content"><pre class="m_2c47c4fd mantine-CodeHighlight-pre" style="padding:0"><code class="m_5caae6d3 mantine-CodeHighlight-code">def factorial(n, acc=1):
if n == 0:
return acc
return factorial(n - 1, acc * n)</code></pre></div></div></div><button class="mantine-focus-auto m_c9378bc2 mantine-CodeHighlight-showCodeButton m_87cf2631 mantine-UnstyledButton-root" data-hidden="true" type="button">Expand code</button></div>
<p>Здесь на каждом шаге результат передаётся как параметр (acc), поэтому новые вызовы не накапливаются в стеке.</p>
<h2 id="heading-2-13">Отличия от цикла</h2>
<div style="--table-min-width:calc(50rem * var(--mantine-scale));--sa-corner-width:0px;--sa-corner-height:0px" class="m_a100c15 mantine-TableScrollContainer-scrollContainer m_d57069b5 mantine-ScrollArea-root"><div style="overflow-x:hidden;overflow-y:hidden" class="m_c0783ff9 mantine-ScrollArea-viewport" data-offset-scrollbars="x" data-scrollbars="xy"><div class="m_b1336c6 mantine-ScrollArea-content"><div class="m_62259741 mantine-TableScrollContainer-scrollContainerInner"><table><thead><tr><th style="text-align:left">Параметр</th><th style="text-align:left">Рекурсия</th><th style="text-align:left">Цикл</th></tr></thead><tbody><tr><td style="text-align:left"><strong>Принцип работы</strong></td><td style="text-align:left">Функция вызывает саму себя</td><td style="text-align:left">Команда повторяется внутри одного блока</td></tr><tr><td style="text-align:left"></td><td style="text-align:left"></td><td style="text-align:left"></td></tr><tr><td style="text-align:left"><strong>Механизм хранения данных</strong></td><td style="text-align:left">Стек вызовов</td><td style="text-align:left">Переменные в текущей области памяти</td></tr><tr><td style="text-align:left"><strong>Понятность кода</strong></td><td style="text-align:left">Часто проще и короче</td><td style="text-align:left">Иногда громоздко, но очевидно</td></tr><tr><td style="text-align:left"><strong>Производительность</strong></td><td style="text-align:left">Медленнее из-за накладных расходов стека</td><td style="text-align:left">Быстрее, оптимизирован процессором</td></tr><tr><td style="text-align:left"><strong>Риск ошибок</strong></td><td style="text-align:left">Переполнение стека, бесконечный вызов</td><td style="text-align:left">Бесконечный цикл при ошибке в условии</td></tr><tr><td style="text-align:left"><strong>Применение</strong></td><td style="text-align:left">Деревья, графы, рекурсивные формулы</td><td style="text-align:left">Повторяющиеся линейные операции</td></tr></tbody></table></div></div></div></div>
<h2 id="heading-2-14">Преимущества и недостатки</h2>
<p>Рекурсия — инструмент мощный, но требующий осторожности. Её плюсы и минусы лучше всего видны при сравнении с итерацией.</p>
<h3 id="heading-3-15">Преимущества</h3>
<ul>
<li><strong>Краткость и читаемость.</strong> Рекурсивные функции лаконичны, особенно в алгоритмах с ветвлениями.</li>
<li><strong>Наглядность.</strong> Код часто ближе к математической логике и проще для понимания принципа.</li>
<li><strong>Естественное решение.</strong> Для деревьев, графов или вложенных структур рекурсия логичнее, чем цикл.</li>
</ul>
<h3 id="heading-3-16">Недостатки</h3>
<ul>
<li><strong>Переполнение стека.</strong> При слишком глубокой рекурсии память заканчивается.</li>
<li><strong>Сложность отладки.</strong> Ошибка в базе может привести к бесконечным вызовам.</li>
<li><strong>Скорость.</strong> Рекурсия часто медленнее, чем эквивалентный цикл.</li>
</ul>
<h2 id="heading-2-17">Примеры в программировании</h2>
<h3 id="heading-3-18">1. Расчёт факториала</h3>
<p>Факториал числа n! = 1 × 2 × … × n. Через рекурсию это выглядит максимально просто:</p>
<div style="margin-bottom:var(--mantine-spacing-lg)" class="m_e597c321 mantine-CodeHighlight-codeHighlight" dir="ltr"><div class="m_be7e9c9c mantine-CodeHighlight-controls"><button style="--ai-bg:transparent;--ai-hover:transparent;--ai-color:inherit;--ai-bd:none" class="mantine-focus-auto mantine-active m_d498bab7 mantine-CodeHighlight-control m_8d3f4000 mantine-ActionIcon-root m_87cf2631 mantine-UnstyledButton-root" data-variant="none" type="button" aria-label="Copy code"><span class="m_8d3afb97 mantine-ActionIcon-icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M8 8m0 2a2 2 0 0 1 2 -2h8a2 2 0 0 1 2 2v8a2 2 0 0 1 -2 2h-8a2 2 0 0 1 -2 -2z"></path><path d="M16 8v-2a2 2 0 0 0 -2 -2h-8a2 2 0 0 0 -2 2v8a2 2 0 0 0 2 2h2"></path></svg></span></button></div><div style="--scrollarea-scrollbar-size:calc(0.25rem * var(--mantine-scale));--sa-corner-width:0px;--sa-corner-height:0px" class="m_f744fd40 mantine-CodeHighlight-scrollarea m_d57069b5 mantine-ScrollArea-root" dir="ltr"><div style="overflow-x:hidden;overflow-y:hidden;overscroll-behavior-inline:none" class="m_c0783ff9 mantine-ScrollArea-viewport" data-scrollbars="xy"><div class="m_b1336c6 mantine-ScrollArea-content"><pre class="m_2c47c4fd mantine-CodeHighlight-pre" style="padding:0"><code class="m_5caae6d3 mantine-CodeHighlight-code">def factorial(n):
if n == 0:
return 1 # база return n * factorial(n - 1) # шаг print(factorial(5)) # 120</code></pre></div></div></div><button class="mantine-focus-auto m_c9378bc2 mantine-CodeHighlight-showCodeButton m_87cf2631 mantine-UnstyledButton-root" data-hidden="true" type="button">Expand code</button></div>
<p>Каждый вызов умножает текущее число на результат следующего, пока не достигнет нуля.</p>
<h3 id="heading-3-19">2. Числа Фибоначчи</h3>
<p>Каждое число — сумма двух предыдущих: <code style="margin-bottom:var(--mantine-spacing-lg)" class="m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight m_e597c321 mantine-CodeHighlight-codeHighlight m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight">F(n) = F(n-1) + F(n-2)</code>.</p>
<div style="margin-bottom:var(--mantine-spacing-lg)" class="m_e597c321 mantine-CodeHighlight-codeHighlight" dir="ltr"><div class="m_be7e9c9c mantine-CodeHighlight-controls"><button style="--ai-bg:transparent;--ai-hover:transparent;--ai-color:inherit;--ai-bd:none" class="mantine-focus-auto mantine-active m_d498bab7 mantine-CodeHighlight-control m_8d3f4000 mantine-ActionIcon-root m_87cf2631 mantine-UnstyledButton-root" data-variant="none" type="button" aria-label="Copy code"><span class="m_8d3afb97 mantine-ActionIcon-icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M8 8m0 2a2 2 0 0 1 2 -2h8a2 2 0 0 1 2 2v8a2 2 0 0 1 -2 2h-8a2 2 0 0 1 -2 -2z"></path><path d="M16 8v-2a2 2 0 0 0 -2 -2h-8a2 2 0 0 0 -2 2v8a2 2 0 0 0 2 2h2"></path></svg></span></button></div><div style="--scrollarea-scrollbar-size:calc(0.25rem * var(--mantine-scale));--sa-corner-width:0px;--sa-corner-height:0px" class="m_f744fd40 mantine-CodeHighlight-scrollarea m_d57069b5 mantine-ScrollArea-root" dir="ltr"><div style="overflow-x:hidden;overflow-y:hidden;overscroll-behavior-inline:none" class="m_c0783ff9 mantine-ScrollArea-viewport" data-scrollbars="xy"><div class="m_b1336c6 mantine-ScrollArea-content"><pre class="m_2c47c4fd mantine-CodeHighlight-pre" style="padding:0"><code class="m_5caae6d3 mantine-CodeHighlight-code">def fib(n):
if n <= 1:
return n
return fib(n-1) + fib(n-2)</code></pre></div></div></div><button class="mantine-focus-auto m_c9378bc2 mantine-CodeHighlight-showCodeButton m_87cf2631 mantine-UnstyledButton-root" data-hidden="true" type="button">Expand code</button></div>
<p>Вызов fib(5) даст последовательность вызовов:</p>
<div style="margin-bottom:var(--mantine-spacing-lg)" class="m_e597c321 mantine-CodeHighlight-codeHighlight" dir="ltr"><div class="m_be7e9c9c mantine-CodeHighlight-controls"><button style="--ai-bg:transparent;--ai-hover:transparent;--ai-color:inherit;--ai-bd:none" class="mantine-focus-auto mantine-active m_d498bab7 mantine-CodeHighlight-control m_8d3f4000 mantine-ActionIcon-root m_87cf2631 mantine-UnstyledButton-root" data-variant="none" type="button" aria-label="Copy code"><span class="m_8d3afb97 mantine-ActionIcon-icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M8 8m0 2a2 2 0 0 1 2 -2h8a2 2 0 0 1 2 2v8a2 2 0 0 1 -2 2h-8a2 2 0 0 1 -2 -2z"></path><path d="M16 8v-2a2 2 0 0 0 -2 -2h-8a2 2 0 0 0 -2 2v8a2 2 0 0 0 2 2h2"></path></svg></span></button></div><div style="--scrollarea-scrollbar-size:calc(0.25rem * var(--mantine-scale));--sa-corner-width:0px;--sa-corner-height:0px" class="m_f744fd40 mantine-CodeHighlight-scrollarea m_d57069b5 mantine-ScrollArea-root" dir="ltr"><div style="overflow-x:hidden;overflow-y:hidden;overscroll-behavior-inline:none" class="m_c0783ff9 mantine-ScrollArea-viewport" data-scrollbars="xy"><div class="m_b1336c6 mantine-ScrollArea-content"><pre class="m_2c47c4fd mantine-CodeHighlight-pre" style="padding:0"><code class="m_5caae6d3 mantine-CodeHighlight-code">fib(5) → fib(4) + fib(3)fib(4) → fib(3) + fib(2)...</code></pre></div></div></div><button class="mantine-focus-auto m_c9378bc2 mantine-CodeHighlight-showCodeButton m_87cf2631 mantine-UnstyledButton-root" data-hidden="true" type="button">Expand code</button></div>
<p>Результат — 5. Однако это пример неэффективной рекурсии, потому что многие значения вычисляются по нескольку раз. Для ускорения применяют мемоизацию (кэширование результатов).</p>
<h3 id="heading-3-20">3. Обход дерева</h3>
<p>Рекурсия незаменима при работе с древовидными структурами — файлами, XML, JSON, каталогами.</p>
<div style="margin-bottom:var(--mantine-spacing-lg)" class="m_e597c321 mantine-CodeHighlight-codeHighlight" dir="ltr"><div class="m_be7e9c9c mantine-CodeHighlight-controls"><button style="--ai-bg:transparent;--ai-hover:transparent;--ai-color:inherit;--ai-bd:none" class="mantine-focus-auto mantine-active m_d498bab7 mantine-CodeHighlight-control m_8d3f4000 mantine-ActionIcon-root m_87cf2631 mantine-UnstyledButton-root" data-variant="none" type="button" aria-label="Copy code"><span class="m_8d3afb97 mantine-ActionIcon-icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M8 8m0 2a2 2 0 0 1 2 -2h8a2 2 0 0 1 2 2v8a2 2 0 0 1 -2 2h-8a2 2 0 0 1 -2 -2z"></path><path d="M16 8v-2a2 2 0 0 0 -2 -2h-8a2 2 0 0 0 -2 2v8a2 2 0 0 0 2 2h2"></path></svg></span></button></div><div style="--scrollarea-scrollbar-size:calc(0.25rem * var(--mantine-scale));--sa-corner-width:0px;--sa-corner-height:0px" class="m_f744fd40 mantine-CodeHighlight-scrollarea m_d57069b5 mantine-ScrollArea-root" dir="ltr"><div style="overflow-x:hidden;overflow-y:hidden;overscroll-behavior-inline:none" class="m_c0783ff9 mantine-ScrollArea-viewport" data-scrollbars="xy"><div class="m_b1336c6 mantine-ScrollArea-content"><pre class="m_2c47c4fd mantine-CodeHighlight-pre" style="padding:0"><code class="m_5caae6d3 mantine-CodeHighlight-code">def traverse(node):
print(node.value)
for child in node.children:
traverse(child)</code></pre></div></div></div><button class="mantine-focus-auto m_c9378bc2 mantine-CodeHighlight-showCodeButton m_87cf2631 mantine-UnstyledButton-root" data-hidden="true" type="button">Expand code</button></div>
<p>Каждый узел вызывает ту же функцию для своих потомков, пока дерево не обойдётся целиком.</p>
<h3 id="heading-3-21">4. Поиск пути в лабиринте</h3>
<p>В играх и алгоритмах навигации рекурсия позволяет искать выход, перебирая соседние клетки:</p>
<div style="margin-bottom:var(--mantine-spacing-lg)" class="m_e597c321 mantine-CodeHighlight-codeHighlight" dir="ltr"><div class="m_be7e9c9c mantine-CodeHighlight-controls"><button style="--ai-bg:transparent;--ai-hover:transparent;--ai-color:inherit;--ai-bd:none" class="mantine-focus-auto mantine-active m_d498bab7 mantine-CodeHighlight-control m_8d3f4000 mantine-ActionIcon-root m_87cf2631 mantine-UnstyledButton-root" data-variant="none" type="button" aria-label="Copy code"><span class="m_8d3afb97 mantine-ActionIcon-icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M8 8m0 2a2 2 0 0 1 2 -2h8a2 2 0 0 1 2 2v8a2 2 0 0 1 -2 2h-8a2 2 0 0 1 -2 -2z"></path><path d="M16 8v-2a2 2 0 0 0 -2 -2h-8a2 2 0 0 0 -2 2v8a2 2 0 0 0 2 2h2"></path></svg></span></button></div><div style="--scrollarea-scrollbar-size:calc(0.25rem * var(--mantine-scale));--sa-corner-width:0px;--sa-corner-height:0px" class="m_f744fd40 mantine-CodeHighlight-scrollarea m_d57069b5 mantine-ScrollArea-root" dir="ltr"><div style="overflow-x:hidden;overflow-y:hidden;overscroll-behavior-inline:none" class="m_c0783ff9 mantine-ScrollArea-viewport" data-scrollbars="xy"><div class="m_b1336c6 mantine-ScrollArea-content"><pre class="m_2c47c4fd mantine-CodeHighlight-pre" style="padding:0"><code class="m_5caae6d3 mantine-CodeHighlight-code">def find_exit(maze, x, y):
if maze[x][y] == 'exit':
return True mark_as_visited(x, y)
for next in neighbours(x, y):
if find_exit(maze, next.x, next.y):
return True
return False</code></pre></div></div></div><button class="mantine-focus-auto m_c9378bc2 mantine-CodeHighlight-showCodeButton m_87cf2631 mantine-UnstyledButton-root" data-hidden="true" type="button">Expand code</button></div>
<p>Каждый шаг вызывает функцию для соседней клетки, пока не найдёт путь.</p>
<h2 id="heading-2-22">Баланс между красотой и эффективностью</h2>
<p>Опытные разработчики стараются находить компромисс: если задача может быть решена итеративно без потери понятности — выбирают цикл. Если же структура данных сама по себе рекурсивна (например, JSON или дерево DOM), то рекурсивный подход оказывается естественнее и надёжнее.</p>
<p><img style="--image-object-fit:contain;width:auto" class="m_9e117634 mantine-Image-root" src="https://cdn6.hexlet.io/0lWXMGGP5cJC.png" alt="0lWXMGGP5cJC image" loading="lazy"/></p>
<h2 id="heading-2-23">За пределами программирования</h2>
<p>Хотя чаще всего рекурсия упоминается в контексте кода, этот принцип встречается повсюду — от математики до биологии и искусства.</p>
<h3 id="heading-3-24">В математике</h3>
<p>Рекурсивные формулы описывают последовательности, где каждый элемент зависит от предыдущих: числа Фибоначчи, факториалы, фракталы, степенные ряды. Рекурсивное мышление помогает строить доказательства по индукции — шаг за шагом, от простого к сложному.</p>
<h3 id="heading-3-25">В биологии</h3>
<p>Природа любит повторения. Форма листа повторяет очертания ветви, а ветвь — всего дерева.
Фрактальная структура лёгких, кровеносных сосудов или береговой линии — это естественные проявления рекурсии.</p>
<h3 id="heading-3-26">В гуманитарных дисциплинах</h3>
<p>В грамматике: предложение может содержать другое предложение. Например: «Я знаю, что ты знаешь, что он сказал». В литературе — «вложенные истории»: рассказ внутри рассказа. В живописи — отражения, зеркала, повторяющиеся мотивы. В философии — это способ мыслить структурно, когда результат на каждом уровне строится на предыдущем.</p>
<h2 id="heading-2-27"><img style="--image-object-fit:contain;width:auto" class="m_9e117634 mantine-Image-root" src="https://cdn6.hexlet.io/4rDkSOlnmv62.png" alt="image" loading="lazy"/></h2>
<h2 id="heading-2-28">Как отлаживать и тестировать рекурсивные функции</h2>
<p>Чтобы избежать сбоев, важно понимать, где и почему возникает ошибка.</p>
<h3 id="heading-3-29">1. Проверяйте базу рекурсии</h3>
<p>Больше половины проблем — из-за отсутствия или неправильной базы. Функция должна всегда иметь условие выхода, которое гарантирует завершение.</p>
<h3 id="heading-3-30">2. Тестируйте на простых примерах</h3>
<p>Начинайте с минимальных данных (n=0, n=1). Если функция корректно работает для них, можно проверять большие значения.</p>
<h3 id="heading-3-31">3. Используйте отладчик IDE</h3>
<p>Большинство IDE (PyCharm, VS Code, IntelliJ) позволяют пройти рекурсивный процесс пошагово. Вы увидите, как аргументы меняются при каждом вызове и где цикл заходит в тупик.</p>
<h3 id="heading-3-32">4. Контролируйте глубину стека</h3>
<p>В Python есть ограничение по умолчанию — около 1000 вызовов. Если рекурсия может быть глубже, нужно: import syssys.setrecursionlimit(3000). Но лучше оптимизировать алгоритм или перейти на итерацию.</p>
<h3 id="heading-3-33">5. Используйте вывод логов</h3>
<p>Добавьте печать входящих аргументов — иногда простая строка print(n) показывает, где именно «застрял» вызов.</p>
<h2 id="heading-2-34">Сценарии выбора</h2>
<div style="--table-min-width:calc(50rem * var(--mantine-scale));--sa-corner-width:0px;--sa-corner-height:0px" class="m_a100c15 mantine-TableScrollContainer-scrollContainer m_d57069b5 mantine-ScrollArea-root"><div style="overflow-x:hidden;overflow-y:hidden" class="m_c0783ff9 mantine-ScrollArea-viewport" data-offset-scrollbars="x" data-scrollbars="xy"><div class="m_b1336c6 mantine-ScrollArea-content"><div class="m_62259741 mantine-TableScrollContainer-scrollContainerInner"><table><thead><tr><th style="text-align:center">Сценарий</th><th style="text-align:center">Рекурсия</th><th style="text-align:center">Циклы</th></tr></thead><tbody><tr><td style="text-align:center">Обход дерева, графа, каталогов</td><td style="text-align:center">Лучше использовать</td><td style="text-align:center"></td></tr><tr><td style="text-align:center">Вычисление факториала или Фибоначчи</td><td style="text-align:center">Для обучения</td><td style="text-align:center">Для практических задач</td></tr><tr><td style="text-align:center">Обработка массивов, фильтрация</td><td style="text-align:center"></td><td style="text-align:center">Предпочтительно</td></tr><tr><td style="text-align:center">Простые повторения</td><td style="text-align:center"></td><td style="text-align:center">Оптимально</td></tr><tr><td style="text-align:center">Алгоритмы поиска (DFS, QuickSort, MergeSort)</td><td style="text-align:center">Эффективно</td><td style="text-align:center"></td></tr></tbody></table></div></div></div></div>
<p>Хорошее правило: если алгоритм можно описать фразой «вызови себя для подзадачи» — рекурсия естественна. А если речь идёт о «повтори то же действие несколько раз» — цикл проще и надёжнее.</p>
<h2 id="heading-2-35">Типичные ошибки начинающих программистов</h2>
<ol>
<li><strong>Отсутствие условия выхода.</strong> Функция уходит в бесконечный вызов и вызывает переполнение стека.</li>
<li><strong>Неправильное изменение аргумента.</strong> Например, n не уменьшается на каждом шаге.</li>
<li><strong>Лишние вычисления.</strong> Повторные вызовы с одними и теми же аргументами замедляют работу.
Решение — мемоизация (lru_cache в Python).</li>
<li><strong>Потеря возвращаемого значения.</strong> Забыто return, из-за чего результат не возвращается обратно.</li>
<li><strong>Попытка решить всё рекурсией.</strong> Иногда проще и быстрее использовать цикл — это не «менее красиво», а просто практичнее.</li>
</ol>
<h2 id="heading-2-36">С чего начать изучение</h2>
<p>Быстро освоить процесс можно, если двигаться от простого к сложному — рекурсивно, в буквальном смысле.</p>
<h3 id="heading-3-37">1. Начните с визуальных аналогий</h3>
<p>Представьте матрёшку, зеркала или русло реки, где каждый уровень повторяет предыдущий.
Такой образ помогает понять идею самоподобия.</p>
<h3 id="heading-3-38">2. Решайте базовые задачи</h3>
<ul>
<li>Факториал числа.</li>
<li>Подсчёт суммы элементов списка.</li>
<li>Разворот строки.</li>
<li>Поиск элемента в дереве.</li>
</ul>
<p>Сначала пишите рекурсивно, потом попробуйте переписать в цикле — чтобы увидеть разницу.</p>
<h3 id="heading-3-39">3. Используйте курсы и книги</h3>
<ul>
<li>
<p><strong>Hexlet:</strong> курсы по алгоритмам и Python включают раздел с наглядными примерами.</p>
</li>
<li>
<p><strong>Coursera / edX:</strong> курсы по компьютерным наукам (CS50, Algorithms I).</p>
</li>
<li>
<p>Книги:</p>
<ul>
<li>«Грокаем алгоритмы» Адитьи Бхаргавы;</li>
<li>«Structure and Interpretation of Computer Programs» (SICP).</li>
</ul>
</li>
</ul>
<h3 id="heading-3-40">4. Практикуйтесь в визуализации</h3>
<p>Сервисы вроде Python Tutor или Visualgo.net позволяют пошагово проследить, как функция вызывает саму себя.</p>
<h2 id="heading-2-41">Заключение</h2>
<p>Рекурсия — не просто техника программирования, а способ мышления, позволяющий видеть задачи как цепочки взаимосвязанных шагов. Она учит структурировать решения, выделять базу, мыслить от общего к частному. Для программиста это — фундаментальная идея, лежащая в основе множества алгоритмов: от сортировок и обхода графов до работы компиляторов и нейросетей. Освоив рекурсивные тонкости, вы начинаете понимать логику программирования на глубоком уровне — где каждая задача сводится к меньшей версии самой себя. И что сам процесс её изучения — тоже рекурсивен.</p></div><div class="m_3eebeb36 mantine-Divider-root" data-orientation="horizontal" role="separator"></div><div style="--group-gap:var(--mantine-spacing-md);--group-align:center;--group-justify:flex-start;--group-wrap:wrap;font-size:var(--mantine-font-size-sm)" class="m_4081bf90 mantine-Group-root"><div style="--group-gap:var(--mantine-spacing-xs);--group-align:center;--group-justify:flex-start;--group-wrap:wrap;margin-inline-start:auto" class="m_4081bf90 mantine-Group-root"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-calendar "><path d="M4 7a2 2 0 0 1 2 -2h12a2 2 0 0 1 2 2v12a2 2 0 0 1 -2 2h-12a2 2 0 0 1 -2 -2v-12"></path><path d="M16 3v4"></path><path d="M8 3v4"></path><path d="M4 11h16"></path><path d="M11 15h1"></path><path d="M12 15v3"></path></svg><p class="mantine-focus-auto m_b6d8b162 mantine-Text-root" data-inherit="true">3 месяца назад</p></div><div style="--group-gap:var(--mantine-spacing-xs);--group-align:center;--group-justify:flex-start;--group-wrap:wrap" class="m_4081bf90 mantine-Group-root"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-user "><path d="M8 7a4 4 0 1 0 8 0a4 4 0 0 0 -8 0"></path><path d="M6 21v-2a4 4 0 0 1 4 -4h4a4 4 0 0 1 4 4v2"></path></svg><p class="mantine-focus-auto m_b6d8b162 mantine-Text-root" data-inherit="true">Nikolai Gagarinov</p></div></div></div></div></div><div style="margin-bottom:var(--mantine-spacing-xl);padding:var(--mantine-spacing-lg)" class="m_e615b15f mantine-Card-root m_1b7284a3 mantine-Paper-root" data-with-border="true" id="answer-3035"><div style="--group-gap:calc(1.125rem * var(--mantine-scale));--group-align:stretch;--group-justify:flex-start;--group-wrap:nowrap" class="m_4081bf90 mantine-Group-root"><div style="--stack-gap:var(--mantine-spacing-md);--stack-align:stretch;--stack-justify:flex-start;font-size:var(--mantine-font-size-h1);font-weight:lighter;text-align:center" class="m_6d731127 mantine-Stack-root">0<a style="color:inherit" class="mantine-focus-auto m_849cf0da m_b6d8b162 mantine-Text-root mantine-Anchor-root" data-underline="hover" href="/qna/glossary/questions/chto-takoe-rekursiya/answers/3035/vote"><div style="--ti-bg:transparent;--ti-color:var(--mantine-color-indigo-light-color);--ti-bd:calc(0.0625rem * var(--mantine-scale)) solid transparent;color:inherit" class="m_7341320d mantine-ThemeIcon-root" data-variant="transparent"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-thumb-up "><path d="M7 11v8a1 1 0 0 1 -1 1h-2a1 1 0 0 1 -1 -1v-7a1 1 0 0 1 1 -1h3a4 4 0 0 0 4 -4v-1a2 2 0 0 1 4 0v5h3a2 2 0 0 1 2 2l-1 5a2 3 0 0 1 -2 2h-7a3 3 0 0 1 -3 -3"></path></svg></div></a></div><div style="--stack-gap:var(--mantine-spacing-md);--stack-align:stretch;--stack-justify:flex-start;width:100%;min-width:0rem" class="m_6d731127 mantine-Stack-root"><div style="margin-bottom:auto" class="m_d08caa0 mantine-Typography-root"><p>Рекурсия - это процесс повторения определенной операции или действия. В программировании рекурсия используется для описания алгоритмов, которые содержат внутри себя вызовы самих себя. Это позволяет создавать более компактные и понятные алгоритмы, а также увеличивает эффективность их работы.</p></div><div class="m_3eebeb36 mantine-Divider-root" data-orientation="horizontal" role="separator"></div><div style="--group-gap:var(--mantine-spacing-md);--group-align:center;--group-justify:flex-start;--group-wrap:wrap;font-size:var(--mantine-font-size-sm)" class="m_4081bf90 mantine-Group-root"><div style="--group-gap:var(--mantine-spacing-xs);--group-align:center;--group-justify:flex-start;--group-wrap:wrap;margin-inline-start:auto" class="m_4081bf90 mantine-Group-root"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-calendar "><path d="M4 7a2 2 0 0 1 2 -2h12a2 2 0 0 1 2 2v12a2 2 0 0 1 -2 2h-12a2 2 0 0 1 -2 -2v-12"></path><path d="M16 3v4"></path><path d="M8 3v4"></path><path d="M4 11h16"></path><path d="M11 15h1"></path><path d="M12 15v3"></path></svg><p class="mantine-focus-auto m_b6d8b162 mantine-Text-root" data-inherit="true">2 года назад</p></div><div style="--group-gap:var(--mantine-spacing-xs);--group-align:center;--group-justify:flex-start;--group-wrap:wrap" class="m_4081bf90 mantine-Group-root"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-user "><path d="M8 7a4 4 0 1 0 8 0a4 4 0 0 0 -8 0"></path><path d="M6 21v-2a4 4 0 0 1 4 -4h4a4 4 0 0 1 4 4v2"></path></svg><p class="mantine-focus-auto m_b6d8b162 mantine-Text-root" data-inherit="true">Елена Редькина</p></div></div></div></div></div><style data-mantine-styles="inline">.__m__-_R_4bbdiub_{--carousel-slide-gap:var(--mantine-spacing-xs);--carousel-slide-size:70%;}@media(min-width: 36em){.__m__-_R_4bbdiub_{--carousel-slide-gap:var(--mantine-spacing-xl);--carousel-slide-size:50%;}}</style><div style="--carousel-control-size:calc(2.5rem * var(--mantine-scale));--carousel-controls-offset:var(--mantine-spacing-sm);margin-top:var(--mantine-spacing-xl);margin-bottom:var(--mantine-spacing-lg);padding-block:var(--mantine-spacing-sm);background:var(--app-color-surface)" class="m_17884d0f mantine-Carousel-root responsiveClassName" data-orientation="horizontal" data-include-gap-in-size="true"><div class="m_39bc3463 mantine-Carousel-controls" data-orientation="horizontal"><button class="mantine-focus-auto m_64f58e10 mantine-Carousel-control m_87cf2631 mantine-UnstyledButton-root" type="button" data-inactive="true" data-type="previous" tabindex="-1"><svg viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg" style="transform:rotate(90deg);width:calc(1rem * var(--mantine-scale));height:calc(1rem * var(--mantine-scale));display:block"><path d="M3.13523 6.15803C3.3241 5.95657 3.64052 5.94637 3.84197 6.13523L7.5 9.56464L11.158 6.13523C11.3595 5.94637 11.6759 5.95657 11.8648 6.15803C12.0536 6.35949 12.0434 6.67591 11.842 6.86477L7.84197 10.6148C7.64964 10.7951 7.35036 10.7951 7.15803 10.6148L3.15803 6.86477C2.95657 6.67591 2.94637 6.35949 3.13523 6.15803Z" fill="currentColor" fill-rule="evenodd" clip-rule="evenodd"></path></svg></button><button class="mantine-focus-auto m_64f58e10 mantine-Carousel-control m_87cf2631 mantine-UnstyledButton-root" type="button" data-inactive="true" data-type="next" tabindex="-1"><svg viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg" style="transform:rotate(-90deg);width:calc(1rem * var(--mantine-scale));height:calc(1rem * var(--mantine-scale));display:block"><path d="M3.13523 6.15803C3.3241 5.95657 3.64052 5.94637 3.84197 6.13523L7.5 9.56464L11.158 6.13523C11.3595 5.94637 11.6759 5.95657 11.8648 6.15803C12.0536 6.35949 12.0434 6.67591 11.842 6.86477L7.84197 10.6148C7.64964 10.7951 7.35036 10.7951 7.15803 10.6148L3.15803 6.86477C2.95657 6.67591 2.94637 6.35949 3.13523 6.15803Z" fill="currentColor" fill-rule="evenodd" clip-rule="evenodd"></path></svg></button></div><div class="m_a2dae653 mantine-Carousel-viewport" data-type="media"><div class="m_fcd81474 mantine-Carousel-container __m__-_R_4bbdiub_" data-orientation="horizontal"><div class="m_d98df724 mantine-Carousel-slide" data-orientation="horizontal"><div tabindex="0" style="cursor:pointer;height:100%"><a style="text-decoration:none" class="mantine-focus-auto m_849cf0da m_b6d8b162 mantine-Text-root mantine-Anchor-root" data-underline="hover" href="/programs/algorithms?promo_name=programs_list&promo_position=qna_question&promo_creative=catalog_card&promo_type=card" target="_blank"><div style="height:100%" class="m_e615b15f mantine-Card-root m_1b7284a3 mantine-Paper-root" data-with-border="true"><div style="--group-gap:calc(0.25rem * var(--mantine-scale));--group-align:center;--group-justify:flex-start;--group-wrap:nowrap" class="m_4081bf90 mantine-Group-root"><span style="font-size:var(--mantine-font-size-sm)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">2 месяца</span><span class="mantine-focus-auto m_b6d8b162 mantine-Text-root">·</span><span style="font-size:var(--mantine-font-size-sm)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Для продвинутых</span></div><p style="margin-bottom:var(--mantine-spacing-sm);font-size:var(--mantine-font-size-h5);font-weight:bold" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Алгоритмы и структуры данных</p><p class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Алгоритмы для собеседований</p><div style="margin-top:auto" class=""><div class="m_4451eb3a mantine-Center-root"><img style="opacity:0.8;width:70%" class="m_9e117634 mantine-Image-root mantine-visible-from-xs" src="https://hexlet.io/rails/active_storage/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6NDAyOCwicHVyIjoiYmxvYl9pZCJ9fQ==--ae9eed98663dd1201759d042a5ba7ca790866156/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJ3ZWJwIiwicmVzaXplX3RvX2xpbWl0IjpbNDAwLDQwMF0sInNhdmVyIjp7InF1YWxpdHkiOjg1fX0sInB1ciI6InZhcmlhdGlvbiJ9fQ==--5b6f46dacd1af664f27558553a58076185091823/Programming-bro.png" alt="Алгоритмы и структуры данных" loading="eager"/></div><div style="--group-gap:var(--mantine-spacing-md);--group-align:end;--group-justify:space-between;--group-wrap:wrap;margin-top:var(--mantine-spacing-xs)" class="m_4081bf90 mantine-Group-root"><p style="font-size:var(--mantine-font-size-xl)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">от 3 900 ₽</p><p style="font-size:var(--mantine-font-size-sm)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Посмотреть →</p></div></div></div></a></div></div><div class="m_d98df724 mantine-Carousel-slide" data-orientation="horizontal"><div tabindex="0" style="cursor:pointer;height:100%"><a style="text-decoration:none" class="mantine-focus-auto m_849cf0da m_b6d8b162 mantine-Text-root mantine-Anchor-root" data-underline="hover" href="/programs/js-sicp?promo_name=programs_list&promo_position=qna_question&promo_creative=catalog_card&promo_type=card" target="_blank"><div style="height:100%" class="m_e615b15f mantine-Card-root m_1b7284a3 mantine-Paper-root" data-with-border="true"><div style="--group-gap:calc(0.25rem * var(--mantine-scale));--group-align:center;--group-justify:flex-start;--group-wrap:nowrap" class="m_4081bf90 mantine-Group-root"><span style="font-size:var(--mantine-font-size-sm)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">1 месяц</span><span class="mantine-focus-auto m_b6d8b162 mantine-Text-root">·</span><span style="font-size:var(--mantine-font-size-sm)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Для продвинутых</span></div><p style="margin-bottom:var(--mantine-spacing-sm);font-size:var(--mantine-font-size-h5);font-weight:bold" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">СИКП на JS</p><p class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Навык фундаментального программирования</p><div style="margin-top:auto" class=""><div class="m_4451eb3a mantine-Center-root"><img style="opacity:0.8;width:70%" class="m_9e117634 mantine-Image-root mantine-visible-from-xs" src="https://hexlet.io/rails/active_storage/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6Mzc2MCwicHVyIjoiYmxvYl9pZCJ9fQ==--9348098e4053d798b6f34bee4ef66947540261e4/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJ3ZWJwIiwicmVzaXplX3RvX2xpbWl0IjpbNDAwLDQwMF0sInNhdmVyIjp7InF1YWxpdHkiOjg1fX0sInB1ciI6InZhcmlhdGlvbiJ9fQ==--5b6f46dacd1af664f27558553a58076185091823/Low%20code%20development-rafiki.png" alt="СИКП на JS" loading="eager"/></div><div style="--group-gap:var(--mantine-spacing-md);--group-align:end;--group-justify:space-between;--group-wrap:wrap;margin-top:var(--mantine-spacing-xs)" class="m_4081bf90 mantine-Group-root"><p style="font-size:var(--mantine-font-size-xl)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">от 3 900 ₽</p><p style="font-size:var(--mantine-font-size-sm)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Посмотреть →</p></div></div></div></a></div></div><div class="m_d98df724 mantine-Carousel-slide" data-orientation="horizontal"><div tabindex="0" style="cursor:pointer;height:100%"><a style="text-decoration:none" class="mantine-focus-auto m_849cf0da m_b6d8b162 mantine-Text-root mantine-Anchor-root" data-underline="hover" href="/programs/python-sicp?promo_name=programs_list&promo_position=qna_question&promo_creative=catalog_card&promo_type=card" target="_blank"><div style="height:100%" class="m_e615b15f mantine-Card-root m_1b7284a3 mantine-Paper-root" data-with-border="true"><div style="--group-gap:calc(0.25rem * var(--mantine-scale));--group-align:center;--group-justify:flex-start;--group-wrap:nowrap" class="m_4081bf90 mantine-Group-root"><span style="font-size:var(--mantine-font-size-sm)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">1 месяц</span><span class="mantine-focus-auto m_b6d8b162 mantine-Text-root">·</span><span style="font-size:var(--mantine-font-size-sm)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Для продвинутых</span></div><p style="margin-bottom:var(--mantine-spacing-sm);font-size:var(--mantine-font-size-h5);font-weight:bold" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">СИКП на Python</p><p class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Изучите Python на глубоком уровне для решения сложных задач</p><div style="margin-top:auto" class=""><div class="m_4451eb3a mantine-Center-root"><img style="opacity:0.8;width:70%" class="m_9e117634 mantine-Image-root mantine-visible-from-xs" src="https://hexlet.io/rails/active_storage/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6Mzc1OCwicHVyIjoiYmxvYl9pZCJ9fQ==--023ea18f500b1c4c91617fa96bbc52df8395da39/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJ3ZWJwIiwicmVzaXplX3RvX2xpbWl0IjpbNDAwLDQwMF0sInNhdmVyIjp7InF1YWxpdHkiOjg1fX0sInB1ciI6InZhcmlhdGlvbiJ9fQ==--5b6f46dacd1af664f27558553a58076185091823/Software%20engineer-bro.png" alt="СИКП на Python" loading="eager"/></div><div style="--group-gap:var(--mantine-spacing-md);--group-align:end;--group-justify:space-between;--group-wrap:wrap;margin-top:var(--mantine-spacing-xs)" class="m_4081bf90 mantine-Group-root"><p style="font-size:var(--mantine-font-size-xl)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">от 3 900 ₽</p><p style="font-size:var(--mantine-font-size-sm)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Посмотреть →</p></div></div></div></a></div></div><div class="m_d98df724 mantine-Carousel-slide" data-orientation="horizontal"><div tabindex="0" style="cursor:pointer;height:100%"><a style="text-decoration:none" class="mantine-focus-auto m_849cf0da m_b6d8b162 mantine-Text-root mantine-Anchor-root" data-underline="hover" href="/programs/java-sicp?promo_name=programs_list&promo_position=qna_question&promo_creative=catalog_card&promo_type=card" target="_blank"><div style="height:100%" class="m_e615b15f mantine-Card-root m_1b7284a3 mantine-Paper-root" data-with-border="true"><div style="--group-gap:calc(0.25rem * var(--mantine-scale));--group-align:center;--group-justify:flex-start;--group-wrap:nowrap" class="m_4081bf90 mantine-Group-root"><span style="font-size:var(--mantine-font-size-sm)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">1 месяц</span><span class="mantine-focus-auto m_b6d8b162 mantine-Text-root">·</span><span style="font-size:var(--mantine-font-size-sm)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Для продвинутых</span></div><p style="margin-bottom:var(--mantine-spacing-sm);font-size:var(--mantine-font-size-h5);font-weight:bold" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">СИКП на Java</p><p class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Изучите фундаментальные принципы программирования на Java</p><div style="margin-top:auto" class=""><div class="m_4451eb3a mantine-Center-root"><img style="opacity:0.8;width:70%" class="m_9e117634 mantine-Image-root mantine-visible-from-xs" src="https://hexlet.io/rails/active_storage/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6NDAxNiwicHVyIjoiYmxvYl9pZCJ9fQ==--eb66b9b5e26fafa32844ce0f4522c3ed84544040/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJ3ZWJwIiwicmVzaXplX3RvX2xpbWl0IjpbNDAwLDQwMF0sInNhdmVyIjp7InF1YWxpdHkiOjg1fX0sInB1ciI6InZhcmlhdGlvbiJ9fQ==--5b6f46dacd1af664f27558553a58076185091823/Hand%20coding-rafiki.png" alt="СИКП на Java" loading="eager"/></div><div style="--group-gap:var(--mantine-spacing-md);--group-align:end;--group-justify:space-between;--group-wrap:wrap;margin-top:var(--mantine-spacing-xs)" class="m_4081bf90 mantine-Group-root"><p style="font-size:var(--mantine-font-size-xl)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">от 3 900 ₽</p><p style="font-size:var(--mantine-font-size-sm)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Посмотреть →</p></div></div></div></a></div></div><div class="m_d98df724 mantine-Carousel-slide" data-orientation="horizontal"><div tabindex="0" style="cursor:pointer;height:100%"><a style="text-decoration:none" class="mantine-focus-auto m_849cf0da m_b6d8b162 mantine-Text-root mantine-Anchor-root" data-underline="hover" href="/programs/ruby-sicp?promo_name=programs_list&promo_position=qna_question&promo_creative=catalog_card&promo_type=card" target="_blank"><div style="height:100%" class="m_e615b15f mantine-Card-root m_1b7284a3 mantine-Paper-root" data-with-border="true"><div style="--group-gap:calc(0.25rem * var(--mantine-scale));--group-align:center;--group-justify:flex-start;--group-wrap:nowrap" class="m_4081bf90 mantine-Group-root"><span style="font-size:var(--mantine-font-size-sm)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">1 месяц</span><span class="mantine-focus-auto m_b6d8b162 mantine-Text-root">·</span><span style="font-size:var(--mantine-font-size-sm)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Для продвинутых</span></div><p style="margin-bottom:var(--mantine-spacing-sm);font-size:var(--mantine-font-size-h5);font-weight:bold" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">СИКП на Ruby</p><p class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Изучите фундаментальные принципы программирования на Ruby </p><div style="margin-top:auto" class=""><div class="m_4451eb3a mantine-Center-root"><img style="opacity:0.8;width:70%" class="m_9e117634 mantine-Image-root mantine-visible-from-xs" src="https://hexlet.io/rails/active_storage/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6Mzc1NywicHVyIjoiYmxvYl9pZCJ9fQ==--bd2826bc88b4074fdf555368020c1fc0ac0705c1/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJ3ZWJwIiwicmVzaXplX3RvX2xpbWl0IjpbNDAwLDQwMF0sInNhdmVyIjp7InF1YWxpdHkiOjg1fX0sInB1ciI6InZhcmlhdGlvbiJ9fQ==--5b6f46dacd1af664f27558553a58076185091823/Low%20code%20development-rafiki.png" alt="СИКП на Ruby" loading="eager"/></div><div style="--group-gap:var(--mantine-spacing-md);--group-align:end;--group-justify:space-between;--group-wrap:wrap;margin-top:var(--mantine-spacing-xs)" class="m_4081bf90 mantine-Group-root"><p style="font-size:var(--mantine-font-size-xl)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">от 3 900 ₽</p><p style="font-size:var(--mantine-font-size-sm)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Посмотреть →</p></div></div></div></a></div></div><div class="m_d98df724 mantine-Carousel-slide" data-orientation="horizontal"><div tabindex="0" style="cursor:pointer;height:100%"><a style="text-decoration:none" class="mantine-focus-auto m_849cf0da m_b6d8b162 mantine-Text-root mantine-Anchor-root" data-underline="hover" href="/courses?promo_name=programs_list&promo_position=qna_question&promo_creative=catalog_card&promo_type=card"><div style="height:100%" class="m_e615b15f mantine-Card-root m_1b7284a3 mantine-Paper-root" data-with-border="true"><h2 style="--title-fw:var(--mantine-h2-font-weight);--title-lh:var(--mantine-h2-line-height);--title-fz:var(--mantine-h2-font-size);margin-bottom:var(--mantine-spacing-md);font-size:var(--mantine-font-size-h3)" class="m_8a5d1357 mantine-Title-root" data-order="2" data-responsive="true">Каталог</h2><p style="margin-bottom:auto" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Полный список доступных курсов по разным направлениям</p><div style="margin-top:auto" class=""><div class="m_4451eb3a mantine-Center-root"><img style="opacity:0.8;width:70%" class="m_9e117634 mantine-Image-root mantine-visible-from-xs" src="/vite/assets/development-BVihs_d5.png" alt="Orientation"/></div></div></div></a></div></div></div></div></div></div><style data-mantine-styles="inline">.__m__-_R_5diub_{--col-flex-grow:auto;--col-flex-basis:100%;--col-max-width:100%;}@media(min-width: 48em){.__m__-_R_5diub_{--col-flex-grow:auto;--col-flex-basis:16.666666666666668%;--col-max-width:16.666666666666668%;}}@media(min-width: 62em){.__m__-_R_5diub_{--col-flex-grow:auto;--col-flex-basis:33.333333333333336%;--col-max-width:33.333333333333336%;}}</style><div class="m_96bdd299 mantine-Grid-col __m__-_R_5diub_ mantine-visible-from-md"><div style="margin-bottom:var(--mantine-spacing-xl);padding:var(--mantine-spacing-xl);background:var(--mantine-color-blue-0);width:100%" class="m_e615b15f mantine-Card-root m_1b7284a3 mantine-Paper-root"><p style="margin-bottom:var(--mantine-spacing-sm);font-size:var(--mantine-font-size-h4)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Похожие вопросы</p><ul class="m_abbac491 mantine-List-root"><li style="margin-bottom:var(--mantine-spacing-xs)" class="m_abb6bec2 mantine-List-item" data-with-icon="true"><div class="m_75cd9f71 mantine-List-itemWrapper"><span class="m_60f83e5b mantine-List-itemIcon"><div class="m_4451eb3a mantine-Center-root"><div style="--ti-size:var(--ti-size-xs);--ti-bg:transparent;--ti-color:var(--mantine-color-indigo-light-color);--ti-bd:calc(0.0625rem * var(--mantine-scale)) solid transparent;color:inherit" class="m_7341320d mantine-ThemeIcon-root" data-variant="transparent" data-size="xs"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-chevron-compact-right "><path d="M11 4l3 8l-3 8"></path></svg></div></div></span><span class="mantine-List-itemLabel"><a class="mantine-focus-auto m_849cf0da m_b6d8b162 mantine-Text-root mantine-Anchor-root" data-underline="hover" href="/qna/glossary/questions/chto-takoe-pandas">Pandas</a></span></div></li><li style="margin-bottom:var(--mantine-spacing-xs)" class="m_abb6bec2 mantine-List-item" data-with-icon="true"><div class="m_75cd9f71 mantine-List-itemWrapper"><span class="m_60f83e5b mantine-List-itemIcon"><div class="m_4451eb3a mantine-Center-root"><div style="--ti-size:var(--ti-size-xs);--ti-bg:transparent;--ti-color:var(--mantine-color-indigo-light-color);--ti-bd:calc(0.0625rem * var(--mantine-scale)) solid transparent;color:inherit" class="m_7341320d mantine-ThemeIcon-root" data-variant="transparent" data-size="xs"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-chevron-compact-right "><path d="M11 4l3 8l-3 8"></path></svg></div></div></span><span class="mantine-List-itemLabel"><a class="mantine-focus-auto m_849cf0da m_b6d8b162 mantine-Text-root mantine-Anchor-root" data-underline="hover" href="/qna/glossary/questions/chto-takoe-1c-buhgalteriya">1C:Бухгалтерия</a></span></div></li><li style="margin-bottom:var(--mantine-spacing-xs)" class="m_abb6bec2 mantine-List-item" data-with-icon="true"><div class="m_75cd9f71 mantine-List-itemWrapper"><span class="m_60f83e5b mantine-List-itemIcon"><div class="m_4451eb3a mantine-Center-root"><div style="--ti-size:var(--ti-size-xs);--ti-bg:transparent;--ti-color:var(--mantine-color-indigo-light-color);--ti-bd:calc(0.0625rem * var(--mantine-scale)) solid transparent;color:inherit" class="m_7341320d mantine-ThemeIcon-root" data-variant="transparent" data-size="xs"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-chevron-compact-right "><path d="M11 4l3 8l-3 8"></path></svg></div></div></span><span class="mantine-List-itemLabel"><a class="mantine-focus-auto m_849cf0da m_b6d8b162 mantine-Text-root mantine-Anchor-root" data-underline="hover" href="/qna/glossary/questions/chto-takoe-1c-predpriyatie">1C:Предприятие</a></span></div></li><li style="margin-bottom:var(--mantine-spacing-xs)" class="m_abb6bec2 mantine-List-item" data-with-icon="true"><div class="m_75cd9f71 mantine-List-itemWrapper"><span class="m_60f83e5b mantine-List-itemIcon"><div class="m_4451eb3a mantine-Center-root"><div style="--ti-size:var(--ti-size-xs);--ti-bg:transparent;--ti-color:var(--mantine-color-indigo-light-color);--ti-bd:calc(0.0625rem * var(--mantine-scale)) solid transparent;color:inherit" class="m_7341320d mantine-ThemeIcon-root" data-variant="transparent" data-size="xs"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-chevron-compact-right "><path d="M11 4l3 8l-3 8"></path></svg></div></div></span><span class="mantine-List-itemLabel"><a class="mantine-focus-auto m_849cf0da m_b6d8b162 mantine-Text-root mantine-Anchor-root" data-underline="hover" href="/qna/glossary/questions/chto-takoe-a-b-testirovanie">A/B-тестирование</a></span></div></li><li style="margin-bottom:var(--mantine-spacing-xs)" class="m_abb6bec2 mantine-List-item" data-with-icon="true"><div class="m_75cd9f71 mantine-List-itemWrapper"><span class="m_60f83e5b mantine-List-itemIcon"><div class="m_4451eb3a mantine-Center-root"><div style="--ti-size:var(--ti-size-xs);--ti-bg:transparent;--ti-color:var(--mantine-color-indigo-light-color);--ti-bd:calc(0.0625rem * var(--mantine-scale)) solid transparent;color:inherit" class="m_7341320d mantine-ThemeIcon-root" data-variant="transparent" data-size="xs"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-chevron-compact-right "><path d="M11 4l3 8l-3 8"></path></svg></div></div></span><span class="mantine-List-itemLabel"><a class="mantine-focus-auto m_849cf0da m_b6d8b162 mantine-Text-root mantine-Anchor-root" data-underline="hover" href="/qna/glossary/questions/chto-takoe-agile">Agile</a></span></div></li></ul></div><div style="justify-content:end;margin-top:0rem;position:sticky;top:calc(5rem * var(--mantine-scale))" class="m_8bffd616 mantine-Flex-root __m__-_R_1bddiub_"><div tabindex="0" style="cursor:pointer"><a style="text-decoration:none" class="mantine-focus-auto m_849cf0da m_b6d8b162 mantine-Text-root mantine-Anchor-root" data-underline="hover" href="/courses_web_development?promo_name=program_category&promo_position=qna_question&promo_creative=card&promo_type=card"><div style="background-color:var(--mantine-color-default);border:calc(0.0625rem * var(--mantine-scale)) solid var(--mantine-color-default-border);padding-inline:var(--mantine-spacing-xl);padding-top:var(--mantine-spacing-xl);padding-bottom:var(--mantine-spacing-xs);width:100%" class="m_e615b15f mantine-Card-root m_1b7284a3 mantine-Paper-root"><div class="m_4451eb3a mantine-Center-root" data-inline="true"><p style="font-size:var(--mantine-font-size-h4)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Курсы по веб-разработке</p></div><img class="m_9e117634 mantine-Image-root" src="/vite/assets/development-BVihs_d5.png"/><p style="margin-bottom:var(--mantine-spacing-xs);text-align:right" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Посмотреть →</p></div></a></div></div></div></div></div></div></div>
</main>
<footer class="bg-dark fw-light text-light px-3 py-5">
<div class="row small">
<div class="col-12 col-sm-6 col-md-3">
<div class="h5 mb-3">Хекслет</div>
<ul class="list-unstyled">
<li>
<a class="nav-link link-light py-1 ps-0" href="/pages/about">О нас</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/testimonials">Отзывы</a>
</li>
<li>
<span class="nav-link link-light py-1 ps-0 external-link" data-href="https://b2b.hexlet.io" role="button">Корпоративное обучение</span>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/blog">Блог</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/qna">Вопросы и ответы</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/glossary">Глоссарий</a>
</li>
<li>
<span class="nav-link link-light py-1 ps-0 external-link" data-href="https://help.hexlet.io" data-target="_blank" role="button">Справка</span>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" target="_blank" rel="noopener noreferrer" href="/map">Карта сайта</a>
</li>
</ul>
</div>
<div class="col-12 col-sm-6 col-md-3">
<div class="h5 fw-normal mb-3">Направления</div>
<ul class="list-unstyled">
<li>
<a class="nav-link link-light py-1 ps-0" href="/courses_devops">DevOps
</a></li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/courses_data_analytics">Аналитика
</a></li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/courses_backend_development">Бэкенд
</a></li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/courses_programming">Программирование
</a></li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/courses_testing">Тестирование
</a></li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/courses_front_end_dev">Фронтенд
</a></li>
</ul>
</div>
<div class="col-12 col-sm-6 col-md-3">
<div class="h5">Профессии</div>
<ul class="list-unstyled">
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/devops-engineer-from-scratch">DevOps-инженер с нуля</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/go">Go-разработчик</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/java">Java-разработчик</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/python">Python-разработчик </a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/data-analytics">Аналитик данных</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/qa-engineer">Инженер по ручному тестированию</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/php">РНР-разработчик</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/frontend">Фронтенд-разработчик</a>
</li>
</ul>
</div>
<div class="col-12 col-sm-6 col-md-3">
<div class="h5">Навыки</div>
<ul class="list-unstyled">
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/python-django-developer">Django</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/docker">Docker</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/php-laravel-developer">Laravel</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/postman">Postman</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/js-react-developer">React</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/js-rest-api">REST API в Node.js</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/spring-boot">Spring Boot</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/typescript">Typescript</a>
</li>
</ul>
</div>
</div>
<hr>
<div class="row">
<div class="col-12 col-sm-4 col-md-2">
<div class="fs-4">
<ul class="list-unstyled d-flex">
<li class="me-3">
<a aria-label="Telegram" target="_blank" class="link-light" rel="noopener noreferrer nofollow" href="https://t.me/hexlet_ru"><span class="bi bi-telegram"></span>
</a></li>
<li>
<a aria-label="Youtube" target="_blank" class="link-light" rel="noopener noreferrer nofollow" href="https://www.youtube.com/user/HexletUniversity"><span class="bi bi-youtube"></span>
</a></li>
</ul>
</div>
<div class="mb-2 d-flex flex-column">
<a class="link-light text-decoration-none" rel="nofollow" href="mailto:support@hexlet.io">support@hexlet.io</a>
<a class="link-light text-decoration-none py-2" target="_blank" href="https://t.me/hexlet_help_bot">t.me/hexlet_help_bot</a>
</div>
<ul class="list-unstyled d-flex">
<li class="me-3">
<span class="link-light text-decoration-none opacity-50 x-font-size-18 external-link" rel="nofollow" data-href="https://hexlet.io/locale/switch?new_locale=en" data-target="_self" role="button"><span class="my-auto">EN</span>
</span></li>
<li class="me-3">
<span class="link-light text-decoration-none opacity-50 x-font-size-18 opacity-100 external-link" rel="nofollow" data-href="https://ru.hexlet.io/locale/switch?new_locale=ru" data-target="_self" role="button"><span class="my-auto">RU</span>
</span></li>
<li class="me-3">
<span class="link-light text-decoration-none opacity-50 x-font-size-18 external-link" rel="nofollow" data-href="https://kz.hexlet.io/locale/switch?new_locale=kz" data-target="_self" role="button"><span class="my-auto">KZ</span>
</span></li>
</ul>
</div>
<div class="col-12 col-sm-4 col-md-3">
<ul class="list-unstyled fs-4">
<li class="mb-3">
<a class="link-light text-decoration-none" href="tel:8%20800%20100%2022%2047">8 800 100 22 47</a>
<span class="d-block opacity-50 small">бесплатно по РФ</span>
</li>
<li>
<a class="link-light text-decoration-none" href="tel:%2B7%20495%20085%2021%2062">+7 495 085 21 62</a>
<span class="d-block opacity-50 small">бесплатно по Москве</span>
</li>
</ul>
</div>
<div class="col-12 col-sm-4 col-md-3">
<div class="small mb-3">Образовательные услуги оказываются на основании Л035-01298-77/01989008 от 14.03.2025</div>
<ul class="list-unstyled small">
<li>
<a class="nav-link link-light py-1 ps-0" href="/pages/legal">Правовая информация</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/pages/offer">Оферта</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/pages/license">Лицензия</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/pages/contacts">Контакты</a>
</li>
</ul>
</div>
<div class="col-12 col-sm-12 col-md-4 small">
<div class="mb-2">
<div>ООО «<a href="/" class="text-decoration-none link-light">Хекслет Рус</a>»</div>
<div>108813 г. Москва, вн.тер.г. поселение Московский,</div>
<div>г. Московский, ул. Солнечная, д. 3А, стр. 1, помещ. 20Б/3</div>
<div>ОГРН 1217300010476</div>
<div>ИНН 7325174845</div>
</div>
<hr>
<div>АНО ДПО «<a href="/" class="text-decoration-none link-light">Учебный центр «Хекслет</a>»</div>
<div>119331 г. Москва, вн. тер. г. муниципальный округ</div>
<div>Ломоносовский, пр-кт Вернадского, д. 29</div>
<div>ОГРН 1247700712390</div>
<div>ИНН 7736364948</div>
</div>
</div>
</footer>
<div id="root-assistant-offcanvas"></div>
<script src="/vite/assets/assistant-CdBlNCiQ.js" crossorigin="anonymous" type="module"></script><link rel="modulepreload" href="/vite/assets/chunk-DsPFFUou.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/init-nkZBEvfU.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/ErrorFallbackBlock-naDSYSy9.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/MarkdownBlock-DbyKWoR_.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/gon-D3e4yh1x.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/mantine-CGMYrt2Y.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/shiki-V011pkdv.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/utils-DRqSHbQE.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/routes-CCH8ilKF.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/lib-XR8Qr8kR.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/dist-GCHh59xr.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/Box-B5-OOzBf.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/notifications.store-C-3AFSMn.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/useIsomorphicEffect-HJ6VK0D3.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/lib-KSp6QbZ0.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/axios-BEvgo0ym.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/classnames-l6ipYlLR.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/dayjs.min-BkKovM-s.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/debounce-jMQ_Cf4f.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/i18next-BlSq9s7B.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/client-U9M77rxp.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/react-dom-DaLxUz_h.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/useTranslation-Bx1Cdrkz.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/compiler-runtime-6XxiPFnt.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/jsx-runtime-CwjcCKJi.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/react-CkL4ZRHB.js" as="script" crossorigin="anonymous">
<script defer src="https://static.cloudflareinsights.com/beacon.min.js/v67327c56f0bb4ef8b305cae61679db8f1769101564043" integrity="sha512-rdcWY47ByXd76cbCFzznIcEaCN71jqkWBBqlwhF1SY7KubdLKZiEGeP7AyieKZlGP9hbY/MhGrwXzJC/HulNyg==" data-cf-beacon='{"version":"2024.11.0","token":"d11015b65d11429ea6b4a2ef37dd7e0b","server_timing":{"name":{"cfCacheStatus":true,"cfEdge":true,"cfExtPri":true,"cfL4":true,"cfOrigin":true,"cfSpeedBrain":true},"location_startswith":null}}' crossorigin="anonymous"></script>
</body>
</html>