Я говорю о 20-30+ миллионах строк кода, программного обеспечения в масштабе и сложности Autodesk Maya, например.
Если вы заморозите разработку до тех пор, пока это необходимо, сможете ли вы на самом деле исправить все ошибки до тех пор, пока просто не будет ни одной ошибки, если такая вещь может быть проверена компьютерами? Каковы аргументы за и против существования системы без ошибок?
Потому что есть мнение, что каждое исправление, которое вы делаете, создает больше ошибок, но я не думаю, что это правда.
Под ошибками я подразумевал от самых простых опечаток в пользовательском интерфейсе до более серьезных профилактических ошибок, которые не имеют обходного пути. Например, определенная скриптовая функция неправильно вычисляет нормали. Также, даже когда есть обходные пути, проблема все еще должна быть исправлена. Таким образом, вы могли бы сказать, что вы можете сделать эту конкретную вещь вручную вместо использования предоставленной функции, но эту функцию все еще необходимо исправить.
источник
Ответы:
Как отметил Майки, написание кода без ошибок не является целью. Если это то, к чему вы стремитесь, у меня есть для вас очень плохие новости.
Ключевым моментом является то, что вы значительно недооцениваете сложность программного обеспечения.
Перво-наперво - вы игнорируете общую картину того, как работает ваша программа. Он не работает изолированно на идеальной системе. Даже самые простые из программ «Hello World» работают в операционной системе, и поэтому даже самые простые программы подвержены ошибкам, которые могут существовать в операционной системе.
Наличие библиотек делает это более сложным. В то время как операционные системы имеют тенденцию быть достаточно стабильными, когда дело доходит до стабильности, библиотеки представляют собой смешанный пакет. Некоторые прекрасны. Другие ... не так много ... Если вы хотите, чтобы ваш код был на 100% свободен от ошибок, то вам также необходимо убедиться, что каждая библиотека, с которой вы работаете, полностью свободна от ошибок, и во многих случаях это просто невозможно у вас может не быть исходного кода.
Тогда есть темы для размышления. Большинство крупномасштабных программ используют потоки повсюду. Мы стараемся быть осторожными и писать потоки таким образом, чтобы не возникали условия гонки и взаимоблокировки, но просто невозможно протестировать каждую возможную комбинацию кода. Для того, чтобы проверить это эффективно, вам необходимо изучить все возможные последовательности команд, проходящих через ЦП. Я не делал математику по этому вопросу, но подозреваю, что перечислить все возможные игры в шахматы было бы проще.
Дела идут от трудного к невозможному, когда мы смотрим на саму машину. Процессоры не идеальны. Оперативная память не идеальна. Жесткие диски не идеальны. Ни один из компонентов внутри машины не разработан так, чтобы быть идеальным - он достаточно «хорош». Даже идеальная программа в конечном итоге потерпит неудачу из-за сбоя в работе машины. Вы ничего не можете сделать, чтобы остановить это.
Итог: можете ли вы написать «Ошибка свободного программного обеспечения»?
НЕТ
Любой, кто говорит тебе иначе, не имеет понятия.
Просто попробуйте написать программное обеспечение, которое легко понять и поддерживать. Как только вы это сделаете, вы можете назвать это днем.
РЕДАКТИРОВАТЬ: Некоторые люди отметили замечательный момент, который я полностью упустил из виду: компилятор.
Если вы не пишете в ассемблере, вполне возможно, что компилятор испортит ваш код (даже если вы докажете, что ваш код "идеален").
Список ошибок в GCC, одном из наиболее часто используемых компиляторов: http://gcc.gnu.org/bugzilla/buglist.cgi?product=gcc&component=c%2B%2B&resolution=---
источник
It is important to note, however, that even all of these steps provide no guarantee of absolute security. It is tempting to believe that a formally specified and proved program should be absolutely correct, but there are several reasons why a proved program may not behave exactly as expected.
- значит, нельзя доказать, что они не содержат ошибок, а, скорее всего, имеют меньше ошибок. Скорее как TDD.Математически МОЖЕТ быть возможным написать программное обеспечение «без ошибок» такой сложности, в зависимости от того, как вы определяете «ошибку». Доказательство этого МОЖЕТ также быть математически возможным, путем разработки тестовой системы, которая будет использовать каждую строку кода всеми возможными способами - каждый возможный вариант использования. Но я не уверен - если вы имеете дело с системой, которая выполняет сложные вычисления, вы можете столкнуться с «проблемой бесконечности» ...
Практически говоря, в системе того размера и объема, о которой вы говорите, это НЕВОЗМОЖНО . Для написания такой системы без ошибок и написания системы, доказывающей, что это займет экспоненциально больше времени, может потребоваться 1000 лет: вам придется придумывать все возможные варианты использования и писать систему, которая будет тестировать каждую из них. один - и я не верю, что есть способ определить, что вы действительно охватили каждый вариант использования в системе того размера и области, о которой вы говорите, во всем, что напоминает разумное количество времени.
IMO, ваш вопрос немного неверно направлен: наша цель как разработчиков - не писать «безошибочное» программное обеспечение. Наша цель - написать ПОЛЕЗНОЕ, ГИБКОЕ, ЛЕГКО ОБЕСПЕЧЕННОЕ ПО.
Пригодный для использования: система удовлетворяет основным требованиям, для которых она была разработана. Могут быть ошибки - но они будут в «крайних случаях» - выбросы или неприятности, а не ошибки, которые ставят под угрозу основы системы - надежные.
Ремонтопригодность: ошибки могут быть легко изолированы и исправлены, и НЕ создавать новых ошибок.
Гибкость: ваша система легко изменяется и расширяется без значительного перепроектирования и простоев: для большинства изменений требуется просто добавить новый класс или модуль, который будет соответствовать уже хорошо разработанным шаблонам и инфраструктуре.
Хорошие методы проектирования, хорошие методы управления, хорошая командная работа, добросовестные разработчики - вот формула ХОРОШЕГО ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ . (не идеально, но хорошо )
источник
Согласно этой статье, встроенное программное обеспечение для космического корабля «Шаттл» подошло очень близко - в последних трех версиях программы на 420 000 строк была только одна ошибка в каждой. Программное обеспечение поддерживалось группой из 260 мужчин и женщин. Большое количество этих людей были проверяющими, единственной целью которых было найти ошибки.
Обновление программного обеспечения, позволяющее шаттлу осуществлять навигацию с помощью спутников глобального позиционирования, затронуло всего 1,5% программы, или 6 366 строк кода. Спецификации для этого изменения составили 2500 страниц. Спецификации для всей программы занимали 30 томов и занимали 40000 страниц, или в среднем десять строк кода на страницу спецификации.
Бюджет не был проблемой - при 35 миллионах долларов в год они могли позволить себе делать все правильно.
источник
По сути, нет, но вы все равно должны делать все возможное. Я объясню почему (или просто перейдите к заключению, если вам не хватает терпения)
Рассмотрим задачу столь же тривиальную, как реализация бинарного поиска. В одной очень популярной реализации была ошибка, которая оставалась незамеченной около двух десятилетий. Если двадцати строкам понадобится двадцать лет, чтобы получить широкое распространение без ошибок и даже предположительно доказано, правильно, можем ли мы ожидать, что огромная программа не будет содержать ошибок?
Сколько ошибок мы можем ожидать от огромной программы? Одно число, которое я нашел, было «10 дефектов на 1000 строк» (Code Complete 2-е издание, стр. 517 - просто использовался пример, без цитирования каких-либо данных), что дает нам от 200 000 до 300 000 ошибок в вашем программном обеспечении. К счастью, у нас есть способы улучшить качество программы. Модульное тестирование, обзоры кода и обычное ручное тестирование, как известно, уменьшают количество ошибок. Тем не менее, число все еще будет высоким.
Если бы мы могли решить 95% всех ошибок, это было бы невероятно. И все же у нас все еще будет от 10 000 до 15 000 ошибок в программном обеспечении.
К счастью, поскольку программное обеспечение широко используется (и, следовательно, широко тестируется), будут найдены ошибки. Таким образом, мы будем постепенно получать меньше ошибок. Тем не менее, меньшее количество ошибок также означает, что оставшиеся из них труднее найти - поэтому не ожидайте линейной кривой при исправлении ошибок. Последние несколько ошибок будет действительно сложно найти и могут избежать обнаружения в течение нескольких лет (при условии, что они когда-либо будут обнаружены).
Вы также, похоже, ошибочно полагаете, что если программное обеспечение не изменится, новых ошибок не появится. Если программное обеспечение зависит от сторонних библиотек, новые версии могут нарушать некоторые функции, что приводит к появлению новых ошибок, даже если код приложения остается прежним. Новые операционные системы могут также сломать приложение, которое ранее работало идеально (см. Популярный пример в Windows Vista). Учитывайте также ошибки компилятора и т. Д.
Неясно, могут ли инструменты для проверки кода действительно решить проблему с ошибками программного обеспечения. Конечно, невозможно решить проблему остановки для любой программы, но можно доказать, что программа ведет себя так, как указано ... Но что тогда? Возможно, в программе проверки есть ошибка. Может быть, в самой спецификации есть ошибка.
Ясно, что мы можем значительно сократить количество ошибок, но вряд ли мы когда-нибудь доберемся до нуля.
(выделение добавлено)
Ты прав. Это утверждение неверно. Вот пример:
Теперь давайте исправим эту ошибку:
Видеть? Мы исправили ошибку и не представили новых.
Однако, безусловно, правильно, что каждый раз, когда вы исправляете ошибку, вы рискуете создать новую, хотя этот риск можно уменьшить (например, с помощью модульного тестирования).
Допустим, что на каждые 100 ошибок, которые я исправляю, я случайно ввожу новую. Поэтому, если я исправлю 10 000 ошибок, я добавлю 100 новых ошибок. И если я исправлю эти новые ошибки, я внесу одну ошибку. Ну и что? В программе теперь на 9 999 ошибок меньше, так что, вероятно, это лучше, чем было (при условии, что новая ошибка не в 10 000 раз хуже, чем предыдущие).
Кроме того, исправление ошибки может открыть новые. Но эти ошибки также могут быть исправлены. Если вы все сделаете правильно, в конечном итоге программное обеспечение будет в лучшем состоянии, чем оно было начато.
Такое поведение небрежно. Если есть ошибка, и вы можете ее исправить. Сделай это. Конечно, вы должны сделать все возможное, чтобы предотвратить добавление новых, но если я добавлю одну маленькую ошибку на каждые 10 серьезных ошибок, которые я исправлю, это не является веской причиной, чтобы прекратить исправлять ошибки. На самом деле, это хорошая причина, чтобы продолжать исправлять ошибки .
Чем меньше ошибок вы исправляете, тем больше ошибок останется в вашем программном обеспечении, раздражая ваших пользователей. Действительно, они не будут «возвращаться к вам в будущем». Они не вернутся, потому что они никогда не уходили. Понятие «вернуться» связано с регрессией. Опять же, можно снизить риск регрессий.
Некоторые ошибки не могут быть исправлены, потому что они стали настолько широко используемыми, что люди начали зависеть от них, и исправление ошибки может сломать программу для этих пользователей. Такое случается. Однако могут ли они действительно считаться ошибками в этом случае?
Менталитет « исправь ошибку, сделай ошибку» может быть связан с That Horrible Monster - кодом, который настолько нечитаем и не поддерживается, что простое прикосновение к нему порождает ошибки. Если в вашей кодовой базе есть монстр, вам может понадобиться сначала удалить его из монстра, прежде чем что-либо делать.
Наконец, если вы ужасный программист, есть риск, что все, к чему вы прикасаетесь, создает новые ошибки. Это, очевидно, заставит старших программистов нервничать. Тем не менее, говоря: «Не делай ничего. Не трогай ничего. Даже не дышите». Вероятно, это не правильный способ создать здоровую рабочую среду. Образование лучше.
Заключение:
источник
Причины не написание программ безглючности в основном экономичные.
Там являются математические методы , чтобы доказать правильность программы. В высококачественном курсе информатики они будут упомянуты. Специально для этого изобретены языки программирования. В теории, программирование без ошибок это возможно.
Да, есть несовершенное оборудование, которое иногда может немного изменить значение, потому что нейтрино, запущенное из далекой сверхновой миллионы лет назад, случайно попало в ваш процессор в нужном месте. Хорошо, каждая теория имеет свои предположения и абстракции. Но если предположить, что процессор работает так, как рекламируется, есть математические инструменты, чтобы убедиться, что программа тоже работает правильно.
Некоторые высокооплачиваемые ответы в этой теме вводят в заблуждение. Например, теорема Гёделя о неполноте и проблема остановки только подразумевают, что у вас не может быть, например, автоматизированного инструмента, который бы определял правильность или неправильность любой программы. Но мы не хотим определять правильность какой- либо программы, нам нужно только подтверждение правильности одной конкретной программы.
(Аналогично, если вы не можете написать программу для автоматического определения истинности какой- либо математической теоремы, это не означает, что вы не можете доказать одну конкретную математическую теорему.)
Проблема, напротив, заключается в следующем:
Хотя теоретически можно написать программу без ошибок, это будет очень дорого . Написание кода с доказательством его правильности сложнее, чем просто бросить что-то в стену и посмотреть, не заклеит ли она. Даже если «видеть, если он залипает» делается с помощью модульных тестов; и многие программисты даже не удосужились это сделать. Большинство программистов даже не знают, как это сделать, а это значит, что в качестве компании вам придется нанимать более дорогих.
Учитывая все затраты, типичный клиент более доволен дешевым программным обеспечением, которое работает хорошо в 99% случаев (и 99,9% времени после установки дополнительных обновлений), чем, возможно, в тысячу раз дороже программного обеспечения, которое хорошо работает в 100% случаев. время. Кроме того, клиент хочет иметь это программное обеспечение сейчас , а не через десять или двадцать лет.
Поэтому люди сознательно производят программное обеспечение, которое имеет некоторые шансы на ошибку, пытаясь найти оптимальную комбинацию, где ошибки не слишком часты и не слишком серьезны, а производство достаточно быстрое и достаточно дешевое. Комбинация, которая обеспечивает наибольшую прибыль в реальной жизни. (Иногда это даже означает выпуск программного обеспечения, полного ошибок, до того, как ваши конкуренты выпустят что-либо, и выпуск более достойной версии 2.0 только тогда, когда ваши конкуренты готовы выпустить свою первую достойную версию.)
Математически говоря, вы могли бы. С экономической точки зрения, зачем кому-то это делать? Это означало бы потратить двадцать лет и несколько миллионов долларов. Между тем, клиенты будут хотеть новые функции, а ваши замороженные приложения не смогут их предоставить. Поэтому, когда ваша идеальная версия готова, рынок уже занят вашими конкурентами.
Экономическое обоснование в порядке. Мы живем в мире, где деньги и время имеют значение. Но только потому, что мы не делаем что-то по экономическим причинам, мы не должны говорить глупости о том, как это невозможно сделать даже в теории. Кто знает ... может быть, через несколько лет мы будем иметь некоторые новые языки программирования и инструменты , которые могли бы сделать правильность доказать легко .
источник
Нет.
Дэвид Гилберт предложил свою вторую проблему математики еще в 1900 году, которая по сути попросила мир доказать, что арифметика работает так, как задумано. Позже он propsed « на проблему разрешения », который просил что - то подобное в логических терминах. « Первая теорема о неполноте » Курта-Геделя доказала в 1931 году, что никакая теория элементарной арифметики не может быть последовательной и полной. Представление Аланом Тьюрингом проблемы Entscheidungs как « проблема остановки » переместило проблему прямо в суть этого вопроса, где он доказал, что невозможно доказать, будет ли программа работать до конца или нет. Учитывая, что неразрешимостьТакже невозможно доказать, есть ли в программе какие-либо ошибки или нет.
Ничто из этого не освобождает практикующих программистов от нас от стремления к ошибкам. Это просто означает, что мы не можем добиться успеха в целом.
источник
int main() { return 0; }
останавливается и не содержит ошибок.Errare humanum est
Даже если вы пишете код на формальном языке, таком как B-метод , который вы можете использовать для математического доказательства соответствия требованиям,
Даже если вы используете формальный язык спецификации,
Всегда есть человеческий шаг, заключающийся в извлечении потребностей пользователя из одного или нескольких мозгов на компьютер.
Этот человеческий шаг подвержен ошибкам, и червь в яблоке.
источник
Достаточная доля «ошибок», с которыми я столкнулся, может быть более правильно описана как несоответствие между дизайном системы и ожиданиями клиентов.
Теперь, независимо от того, назовем мы эти ошибки или нет, это академический вопрос, но факт остается фактом: значительная часть работ по техническому обслуживанию возникает как прямой результат несовершенной коммуникации и изменения ожиданий клиентов.
Даже если система технически, доказуемо «правильна» в смысле соответствия спецификации (хотя это маловероятно, что это может быть для коммерческого коммерческого программного обеспечения), у вас все равно будет проблема согласования функций программного обеспечения с потребностями вашего клиента. переменчивые и плохо определенные ожидания.
Короче говоря:
Нет.
источник
Если у вас достаточно жесткая и ограниченная спецификация, вы можете доказать безошибочную программу, но только на основе недоказуемых предположений о правильном функционировании всего остального в системе. Это означает, что невозможно доказать, что спецификации будут считаться правильными тем, кто поставил исходную проблему, или тем, кто использовал службу.
источник
Я нашел раздел Джима Шора No Bugs очень полезным чтением на эту тему. Краткая форма: невозможно разрабатывать без ошибок, но мы можем работать таким образом, чтобы обнаруживать их как можно раньше.
Во время производства самого кода. Например, часто выполняя модульные тесты во время разработки, мы постоянно заверяем, что код выполняет то, что должен. Кроме того, полезно постоянно переписывать существующий код таким образом, чтобы он наиболее четко выражал предполагаемое поведение системы.
В вашем случае, однако, вы говорите об уже существующей базе кода с миллионами строк кода. Если вы хотите избавиться от такой системной ошибки, вы прежде всего должны знать, что является «ошибкой» для этой системы. Вы можете написать наборы специальных тестов, обеспечивающих функциональность системы (если она еще не существует). Сеть этих тестов может служить приблизительным определением правильного поведения системы. Но чем больше у вас кода, тем больше усилий требуется для таких упражнений. Поэтому большинство компаний идут на компромисс: они живут с несовершенными, работая со списками ошибок и обслуживанием, чтобы вытащить самые досадные ошибки из системы.
источник
О проверке компьютерной частью.
Есть два способа проверить программу с помощью компьютера. Один - тестирование, другой - использование системы доказательства.
Как только исчерпывающее тестирование становится невозможным, тестирование становится неспособным показать, что в программе нет ошибок, а есть некоторые. (И у вас есть проблема, чтобы показать, что ваши тесты сами не проверяют наличие ошибок).
Чтобы использовать систему проверки, вы начинаете с формальных требований (и они сами могут иметь ошибку, надеюсь, язык, используемый для требований, будет более подходящим, чтобы убедить себя, что в этом нет ошибки, чем с языком программирования), и конструировать / проверять с помощью помощь систем доказательства, что программа не содержит ошибок (и в системах доказательств есть вопрос об ошибках, но они оказались правильными). Современное состояние - это компилятор для подмножества C (и подмножество не является академическим, «CompCert поддерживает все подмножества MISRA-C 2004 C, а также многие функции, исключенные MISRA»).
источник
Нет, потому что компьютерная и программная среда, в которой работает приложение, будет продолжать меняться, даже если код заморожен. Операционная система продолжает развиваться с исправлениями и исправлениями, а также с устройствами и драйверами. Как только вы думаете, что достигли точки, в которой нет известных ошибок, AMD или nVidia выпустят обновление видеодрайвера, которое повлияет на ваше взаимодействие с видеоподсистемой. Теперь ваше приложение имеет визуальные дефекты (такие как мигание, мерцание или уменьшение частоты кадров) для клиентов, у которых есть определенная видеокарта или конфигурация (SLI? LOL).
Помимо аппаратного обеспечения и операционной системы, есть также несколько промежуточных программных продуктов под наиболее значимыми приложениями, которые также будут развиваться вне вашего контроля, и как только вы приведете свой код к нулевому дефекту, укажите уровни, под которыми вы получаете EOL.
Технология развивается, так же как и бизнес, использующий эту технологию, и идея «освобождения» кода невозможна или неосуществима. Бизнес, запрашивающий новый набор функций, не будет хорошо реагировать на то, что «у нас заблокирован код, пока мы преследуем все известные ошибки, и никто не сообщает о действительном дефекте программного обеспечения за X месяцев». Даже если бизнес купит эту линию, через X месяцев они спросят, как появляются новые функции, и ответ не может быть: «Мы решили продлить действие запрета, потому что Oracle просто выпустит патч, и нам нужно еще X месяцев чтобы подтвердить это ".
Нет, в какой-то момент бизнес будет искать более гибкую команду разработчиков, которая поддержит необходимость двигаться вперед со скоростью технологий. Это фундаментальная проблема, с которой сталкиваются современные команды разработчиков.
источник
Да, но вы никогда не узнаете наверняка. Чем сложнее ты выглядишь, тем больше найдешь. Чем тяжелее используется система и чем больше крайних случаев, тем более вероятно, что вы обнаружите еще одно несоответствие с первоначальным намерением или спецификацией. Это подразумевает, что ошибка сама по себе не является точной вещью и часто будет зависеть от интерпретации, от того, насколько плохо некоторые оценивают воспринимаемую аномалию.
Это нечеткая вещь. Мало систем указано до последнего бита. Если система работает хорошо, и у пользователей нет претензий (они ничем не подвержены ошибкам), и они полностью адаптированы к ней, вы можете также назвать ее свободной от ошибок.
источник
Возможна последовательная поставка программного обеспечения без ошибок, при условии достаточной дисциплины и общей командной культуры. (И хорошо продуманный модульный код, полный набор автоматизированных тестов, проверка дефектов и адаптация вашего процесса, и много других вещей, которые требуют усилий и смирения, но окупаются в тысячи раз)
Но, делая это, вы, как правило, не ставите себе задачу построить систему на 20 MLOC. Если написание кода без ошибок не является вашей целью, ни одна из них не должна создавать систему MLOC.
Мои собственные рассуждения таковы:
У какого-то человека есть необходимость выполнить. У какого-то человека (возможно, такого же, возможно, другого) есть бюджет для удовлетворения потребностей посредством написания программного обеспечения. Все эти люди рассчитывают получить какую-то выгоду за свои деньги.
Человек с бюджетом заплатит некоторым людям (возможно, тем же, возможно, другим), которых называют программистами , так что эти программисты превратят некоторое согласованное количество своего времени в программное обеспечение, удовлетворяющее потребность.
Поэтому эти программисты работают над превращением чужих денег в программное обеспечение, удовлетворяющее потребность. Они несут ответственность за правильное использование этих денег.
Это имеет следующие последствия в отношении вашего вопроса:
Все дело в деньгах, и это правильно.
источник
Да.
Но, как вы знаете, это требует слишком много усилий, чтобы того стоить.
Прежде чем я смогу защитить свой ответ, мы должны сначала определить, что это за ошибка:
Теперь, как вы, наверное, уже знаете, хорошие программные архитектуры являются модульными, так что каждый модуль можно тестировать модульно (или вручную, или как угодно) индивидуально. Благодаря дисциплине и тщательному тестированию можно написать отдельные модули, в которых нет ошибок.
"Но ждать!" Я слышу ваш протест: «Что если неожиданное (но, тем не менее, правильное) поведение одного модуля вызывает ошибку в другом?» Тогда ошибка находится во втором модуле. Модули без ошибок могут рассматриваться как API, а API, как вы знаете, требуют некоторого внимания для правильного использования.
Написание пуленепробиваемого кода требует обширных знаний крайних случаев и логики потока со стороны разработчика, и большинство разработчиков программного обеспечения либо недостаточно умны, чтобы учиться, либо просто не заботятся. Или чаще, они в срок.
«Но дай мне место, чтобы встать, и я переверну мир». - Архимед
источник