Техническое несимметричное условие в цикле - PullRequest
0 голосов
/ 05 декабря 2009

Большинство из нас знает, что цикл не должен иметь условия без завершения. Например, этот цикл C # имеет условие без завершения: любое четное значение i. Это очевидная логическая ошибка.

void CountByTwosStartingAt(byte i) { // If i is even, it never exceeds 254
    for(; i < 255; i += 2) { 
        Console.WriteLine(i);
    }
}

Иногда встречаются крайние случаи, которые крайне маловероятны, но технически представляют собой несуществующие условия (помимо переполнения стека и ошибок нехватки памяти). Предположим, у вас есть функция, которая подсчитывает количество последовательных нулей в потоке:

int CountZeros(Stream s) {
    int total = 0;
    while(s.ReadByte() == 0) total++;
    return total;
}

Теперь предположим, что вы кормите его этой вещью:

class InfiniteEmptyStream:Stream
{
    // ... Other members ...

    public override int Read(byte[] buffer, int offset, int count) {      
        Array.Clear(buffer, offset, count); // Output zeros
        return count; // Never returns -1 (end of stream)
    }
}

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

Совершенно реальный пример, как в приложении, которое я пишу. Бесконечный поток нулей будет десериализован в бесконечные «пустые» объекты (пока класс коллекции или GC не сгенерируют исключение, потому что я превысил два миллиарда элементов). Но это было бы совершенно неожиданным обстоятельством (учитывая мой источник данных).

Насколько важно не иметь абсолютно никаких не прекращающих условий? Насколько это влияет на «надежность»? Имеет ли значение, если они только «теоретически» не заканчиваются (это нормально, если исключение представляет собой неявное условие завершения)? Имеет ли значение, является ли приложение коммерческим? Если это публично распространяется? Имеет ли значение, если проблемный код никоим образом не доступен через открытый интерфейс / API?

Edit: Одна из основных проблем, с которыми я сталкиваюсь, - это непредвиденные логические ошибки, которые могут создать неразрывное условие. Если, как правило, вы гарантируете отсутствие не завершающих условий, вы можете более изящно выявлять или обрабатывать эти логические ошибки, но стоит ли это того? И когда? Это проблема, ортогональная доверию.

Ответы [ 4 ]

4 голосов
/ 05 декабря 2009

Вы либо «доверяете» своему источнику данных, либо нет.

Если вы доверяете этому, то, вероятно, вы хотите приложить максимум усилий для обработки данных, независимо от того, что это такое. Если он посылает вам нули навсегда, то это ставит вас перед проблемой, слишком большой для ваших ресурсов, и вы тратите на нее все свои ресурсы и терпите неудачу. Вы говорите, что это «совершенно неожиданно», поэтому вопрос в том, можно ли просто «совершенно неожиданно» перевернуть ваше приложение, потому что ему не хватает памяти. Или это должно быть на самом деле невозможно?

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

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

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

0 голосов
/ 06 декабря 2009

Насколько важно иметь абсолютно нет не прекращающих условий?

Это совсем не важно. То есть это не самоцель. Важно то, что код правильно реализует спецификацию. Например, интерактивная оболочка может иметь ошибку, если основной цикл завершается.

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

0 голосов
/ 05 декабря 2009

Вы либо «доверяете» своему источнику данных, либо нет.

Я бы сказал, что вы либо «поддерживаете» программное обеспечение, используемое с этим источником данных, либо нет. Например, я видел программное обеспечение, которое не обрабатывает условие нехватки памяти: но недостаточно памяти не «поддерживается» для этого программного обеспечения (или, менее точно, оно не поддерживается для этой системы ); таким образом, для этой системы, если возникает состояние недостаточного объема памяти, необходимо устранить нагрузку на систему или увеличить объем памяти (а не исправить программное обеспечение). Для этой системы обработка недостаточного объема памяти не является обязательным требованием: то, что является требованием, заключается в управлении нагрузкой на систему и предоставлении достаточного объема памяти для этой заданной нагрузки.

0 голосов
/ 05 декабря 2009

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

...