Фибоначчи с использованием рекурсивного метода дает мне переполнение стека

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

add_header X-Forwarded-For $proxy_add_x_forwarded_for;
add_header X-Real-Ip       $remote_addr;

Когда вы выполните:

curl -H 'X-Forwarded-For: 8.8.8.8, 192.168.1.2' http://192.168.1.3/

Ваш nginx в myhost.com отправит вперед:

X-Forwarded-For: 8.8.8.8, 192.168.1.2, 192.168.1.3

X-Real-IP будет IP-адресом первого предыдущего прокси-сервера, если вы будете следовать инструкциям вслепую.

В случае, если доверять тому, кто является вашим пользователем, вы можете попробовать что-то например django-xff: https://pypi.python.org/pypi/django-xff/

-3
задан buræquete 1 March 2019 в 01:02
поделиться

2 ответа

Одним из решений этой проблемы рекурсии является прерывание рекурсии с помощью динамического программирования. Например, запоминание может быть применено и позволит вам реализовать его как

private static Map<Integer, Integer> memo = new HashMap<>();
static {
    memo.put(0, 0);
    memo.put(1, 1);
}

public static int rFib(int n) {
    if (memo.containsKey(n)) {
        return memo.get(n);
    }
    int r = rFib(n - 2) + rFib(n - 1);
    memo.put(n, r);
    return r;
}
0
ответ дан Elliott Frisch 1 March 2019 в 01:02
поделиться

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

Очень просто понять рекурсию из Фибоначчи, потому что это действительно тривиальный рекурсивный алгоритм для вас, чтобы объяснить кому-то и понять ... Что означает, что это здорово для программирования рекурсии, верно? К сожалению, нет.

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

В программировании есть вещь, называемая стеком. Это буквально называется это, потому что это как стопка бумаг. Когда вы вызываете функцию, она помещает в стек всю информацию, необходимую для вызова функции, передачи аргументов и знания, как вернуться из функции (и некоторых других административных вещей). Когда эта функция рекурсивно вызывает себя, она помещает другой лист поверх стека . Затем эта функция помещает еще один лист. Эти листы не удаляются до тех пор, пока функция не завершится ... Но поскольку одна функция не может завершиться до завершения другой, она просто растет, растет и растет.

И стек только такой большой. Преднамеренно. Чтобы избежать этой проблемы.

Обычно рекурсия не используется для таких глубоких проблем. (Хвост-рекурсивные люди: игнорируйте это; если вы не знаете, что такое хвост-вызов-рекуссия: также игнорируйте это.)

Чтобы исправить это, не сделай это. Общепризнанно, что почти в каждом произвольно-рекурсивном приложении функции цикл for будет работать лучше (и быстрее).

0
ответ дан iAdjunct 1 March 2019 в 01:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: