2013-11-20 2 views
1

Я написал образец Java-класса и использовал рекурсию для определенной цели в методе. Я показал код ниже конкретного метода рекурсии (учтите, что я упомянул здесь только необходимую часть метода).Влияние использования рекурсий в Java

private String checkForDuplicateCVs(final Integer userId) throws SQLException { 

     // 
     // Codes to obtain the cvSerialId comes here... 
     // 

     final Integer cvCount = (Integer) getSqlMapClient().queryForObject("user.getCvCountBySerialId", cvSerialId); 

     if (cvCount != 0) { 
      checkForDuplicateCVs(userId); 
     } 

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

+1

Рекурсия как таковая не плохая, но вы, кажется, используете ее по методу, который делает вызов БД, и это действительно не дает хороших вибраций, ИМХО. – SudoRahul

+0

Обычно это зависит от глубины рекурсии. Внедрите итеративный алгоритм и сравните время выполнения. – sp00m

+0

@ RJ - Как рекурсия вызова вызова БД ??. Насколько я знаю, стек не следует переоценивать. Вызов DB является дорогостоящим с точки зрения времени, и в рекурсии мы не получаем ошибок из-за ограничения по времени, мы получаем ошибки из-за ограничения пространства. Поправьте меня, если я ошибаюсь. thanks – TheLostMind

ответ

3

Рекурсия не плохая сама по себе, и на самом деле это часто лучший способ разработки алгоритма.

Это, в вашем случае, я бы сказал, что это плохой дизайн. У вас есть цикл while, который вы реализовали с рекурсией.

Есть несколько возможных проблем с этим:

  • читаемость и обслуживание кода. Это петля, зачем запутывать ее?
  • Восприимчивость к переполнению стека. Ваш рекурсивный вызов принимает тот же параметр, что и родительский, поэтому вполне возможно, что вы получите бесконечный цикл, если база данных не изменится. Это отлично подходит для цикла while, но в вашем случае это приведет к достижению предела стека и исключению. Это сделало бы вашу рекурсию ошибкой, которая, на мой взгляд, имеет последствия для безопасности (отказ в обслуживании).
  • Это не относится к вашему коду, но в целом вызовы функций намного дороже, чем простые циклы. Поэтому, если вы сравниваете время выполнения цикла while и рекурсивную реализацию этого цикла while, вы увидите большой разрыв в производительности. В некоторых случаях это можно оптимизировать (а именно, рекурсию хвоста), но не всегда. (Этот эффект незначителен в коде, так как запрос к базе данных гораздо гораздо дороже, чем вызов функции накладного)
-2

Единственная темная сторона рекурсии является то, что вы можете получить StackOverflowException, если ваша функция будет называть себя большой (вы можете изменить размер стека с помощью параметра JVM). Обратите внимание, что рекурсия всегда может быть заменена простым циклом while.

+0

Рекурсия всегда может быть заменена циклом, но это не всегда * простой * цикл. Это может стать очень сложным. – Holger

+0

Ха-ха, в зависимости от того, что вы подразумеваете под _simple_ и _complex_. Каждая рекурсивная функция должна иметь условие выхода, которое всегда может быть реализовано в цикле инфинитива как 'if () break;' – user2660000

+0

Рекурсивные функции могут иметь состояние в своих кадрах стека, которое используется * после * возврата рекурсии. Теперь возьмем рекурсивную функцию, которая вызывает себя несколько раз в течение одного вызова и использует результаты и пытается переписать ее на итерационное решение ... Только рекурсия конца тривиальна для перезаписи. – Holger

Смежные вопросы