Алексей Панов
октябрь 2019.
517

Как писать код без багов, а?

Ответить
Ответить
Комментировать
0
Подписаться
0
1 ответ
Поделиться

Никак.

Эта цель неправильная. Правильная цель -- писать настолько понятно и настолько хорошо изолировать функции, покрывая их юнит-тестами, чтобы ошибки было как можно проще обнаружить. 

Ну и самое древнее средство против ошибок -- assert. Про него можно прочитать вот эту простенькую заметку: https://habr.com/ru/post/141080/

15
0

Это уже какая-то космическая философия. Писать код без багов - это неправильная цель?

Явно видно, что ответ написан сторонником test-driven development, который смотрит на разработку исключительно через призму "юнит-тесты решат все проблемы". Но, на мой взгляд, такая позиция является неудачной попыткой максимального упрощения того, что нельзя упростить настолько сильно и хорошо, как об этом хочется думать сторонникам test-driven development.

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

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

+1
Ответить
  1. Да, писать совсем без ошибок цель недостижимая, потому, imho, неправильная. Формально говоря, найти в программе все ошибки -- задача алгоритмически неразрешимая (доказательство этого утверждения не очень сложно, но требует начальных знаний математической логики). Сразу оговорюсь, что это формальное утверждение из математики, которое нельзя "в лоб" практически применить -- в реальной жизни мы имеем дело с очень небольшим количество алгоритмов и программ, а матлогика оперирует со всеми мыслимыми.

  2. "Явно видно, что ответ написан сторонником test-driven development" -- в качестве иллюстрации к предыдущему утверждению можно привести вот это ошибочное умозаключение. Да, людям свойственно ошибаться, потому кода совсем без ошибок почти не бывает.

  3. Юнит-тесты не настолько важны, насколько важно изолировать части программы, про которые можно сделать какие-то конкретные утверждения.

  4. Идея ассерта и юни-теста -- невдолбенно практическая. Ещё конкретнее:

  • если функция на вход принимает какие-то параметры, про которые что-то предполагает, надо проверить assert'ом, что предположение верно. Пример -- если реализуете логарифм, проверьте, что аргумент положительный. Если бинарный поиск -- что массив отсортирован.

  • если вызвали функцию, которая возвращает нечто с определённым свойством, проверьте снаружи, что свойство выполнено. Пример -- вызвали сортировку -- проверьте, что после неё массив отсортирован. Вызвали экспоненту -- проверьте, что значение положительно.

(эти два примера формулируются как "принцип недоверия" -- стоит проверять любое предположение)

  • Если можете придумать тривиальную проверку -- обязательно напишите. Я не зря выше упомянул про логарифм и экспоненту.

  • если пишете цикл, попробуйте сформулировать инвариант. Если получилось, попробуйте написать assert про него

0
Ответить

Да, писать совсем без ошибок цель недостижимая, потому, imho, неправильная

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

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

Но из вашего ответа складывается впечатление, что всё это не нужно, если писать изолированные функции и покрывать их юнит-тестами.

+1
Ответить
Прокомментировать
Ответить
Читайте также на Яндекс.Кью
Читайте также на Яндекс.Кью