Як зменшити кількість помилок при кодуванні?


30

Ніхто не є ідеальним, і що б ми не робили, ми збираємося час від часу створювати код, який містить помилки. Які існують деякі методи / прийоми для зменшення кількості помилок, які ви створюєте, як під час написання нового програмного забезпечення, так і при зміні / підтримці існуючого коду?


Хороший метод - зробити більш випереджаючий дизайн (не надто багато, але достатньо, щоб зробити ваш код більш структурованим і легшим для розуміння).
Джорджіо

Відповіді:


58

Уникайте фантазійного кодування. Чим складніший код, тим більше шансів на помилки. Зазвичай у сучасних системах чітко написаний код буде досить швидким і малим.

Використовуйте наявні бібліотеки. Найпростіший спосіб не мати помилок при написанні програми утиліти - це не писати її.

Вивчіть кілька формальних прийомів для більш складних речей. Якщо є складні умови, прибийте їх ручкою та папером. В ідеалі знати деякі методи доказування. Якщо я можу довести код правильним, це майже завжди добре, за винятком великих, тупих, очевидних помилок, які легко виправити. Очевидно, що це йде лише так далеко, але іноді можна формально міркувати про невеликі, але складні речі.

Що стосується наявного коду, навчіться рефакторингу: як зробити невеликі зміни в коді, часто використовуючи автоматизований інструмент, який робить код більш читабельним, не змінюючи поведінку.

Не робіть нічого занадто швидко. Виділивши трохи часу наперед, щоб зробити все правильно, перевірити, що ви зробили, і подумати над тим, що ви робите, може пізніше окупитися.

Щойно ви написали код, використовуйте те, що у вас є, щоб зробити його гарним. Тести одиниці чудові. Ви можете часто писати тести достроково, що може бути чудовим зворотним зв'язком (якщо це робиться послідовно, це розробка тесту). Компілюйте з опціями попередження та зверніть увагу на попередження.

Запропонуйте комусь ще подивитися код. Офіційні огляди кодів хороші, але вони можуть бути не в зручний час. Потягніть запити чи подібні, якщо ваша scm не підтримує їх, дозволяють асинхронні огляди. Перевірка друзів може бути менш офіційним оглядом. Парне програмування забезпечує дві пари очима на все.


x2 - те, що сказав Райан.
JBRWilkinson

2
також більшість мов можуть бути більш або менш вибагливими. Ви хочете, щоб це було максимально прискіпливо.

1
"Вивчіть кілька формальних прийомів для більш складних речей." ... Наприклад?
Дан Розенстарк

1
@Yar: Я очікую щось подібне до систем, пояснених у цій книзі: amazon.com/Verification-Sequences-Concurrent-Programs-Computer/… ; хоча я мушу сказати, що конкретна книга надзвичайно суха і тьмяна, тому там, мабуть, набагато кращі (але це єдина, яку я читав).
Joeri Sebrechts

30

Тести блоку дозволяють вам зменшити кількість помилок, які з’являються вдруге. Якщо ви знайдете помилку у своєму коді, написання одиничного тесту дозволить переконатися, що він не повернеться пізніше. (Плюс до того, що думати про всі випадки та писати тисячі одиниць тестів наперед, важко зробити інколи)


3
"Роздум про всі справи наперед" призводить до чистих, повністю визначених інтерфейсів, що може бути лише хорошою справою. Тестові одиниці важко написати, якщо ви переоблаштовуєте їх на код, який не був розроблений з урахуванням тестування.
Майк Сеймур

1
Якщо можете, то і слід. На жаль, більшість місць, де я бачив одиничні тести, як щось, що коштує більше, ніж просто "виправлення помилок по-справжньому". Отже, якщо ви можете, то ви повинні писати тести наперед, але якщо це не вважається "економічно вигідним", тоді їх написання поряд із виправленнями помилок допомагає вам наростити його з часом, не витрачаючи занадто багато бюджету на просто написання одиничних тестів. .
Райан Хейс

4
"Тестування показує наявність, а не відсутність помилок." - Е. Дійкстра. При цьому автоматичні тести, безумовно, є дуже корисним способом підтримки та підвищення якості програмного забезпечення.
ліміст

9

+1 для обох коментарів до тестового блоку.

Крім того, встановіть найвищий рівень попередження, який пропонує ваш компілятор, і переконайтеся, що попередження трактуються як помилки. Клопи часто ховаються в тих "помилкових" помилках.

Аналогічно вкладайте кошти в інструменти статичного аналізу, які працюють під час компіляції (я розглядаю їх як додатковий рівень попереджень компілятора).


+1 для коментаря статичного аналізу. Безкоштовно отримати всю цю інформацію безкоштовно :)
Morten Jensen

9

Окрім сказаного:

  • Не ігноруйте коди помилок - наприклад, не вважайте, що ви отримали дійсний результат, що файл був успішно створений і т. Д. ... Тому що одного дня щось трапиться.
  • Не припускайте, що ваш код ніколи не вводить якусь умову, і тому "безпечно ігнорувати цю умову".
  • Перевірте свій код, а потім перевірить його хтось інший. Я вважаю, що я найгірша людина, яка перевіряє власний код.
  • Зробіть перерву, потім перечитайте свій код і подивіться, чи "ви пропустили очевидне". Часто трапляється зі мною.

Дуже багато речей, які я зараз забуваю, але інші, напевно, подумають про них. :)


7
І якщо ви настільки впевнені, що умова X ніколи не відбудеться ... скористайтеся утвердженням, щоб переконатися, що коли станеться умова X, ви дізнаєтесь про це (через виняток, або вхід у систему, чи що завгодно).
Френк Ширар

@MetalMikester: Одиничні тести хороші. Але, використовуючи мови високого рівня та хороші бібліотеки, більшість жорстких помилок потребують інтеграції та регресійного тестування.
Вектор

9

Я розробив досить функціональний стиль програмування, незважаючи на те, що мої основні мови були C ++ та Python. Я виявив, що якщо я передаю весь контекст функції (або методу), що цій функції потрібно виконати свою роботу, і повернути значущі дані, які я шукаю, мій код стане набагато надійнішим.

Неявна держава - ворог, і на мій досвід - це джерело помилок №1. Цей стан може бути глобальними змінними або змінними членів, але якщо результати залежать від того, що не передається функції, про яку ви задаєте проблеми. Очевидно, що усунути стан неможливо, але його мінімізація має величезні позитивні наслідки для надійності програми.

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

Подивіться, все це також позитивно впливає на продуктивність. Виграй!


З мого досвіду, це може швидко стати нудним обходити всі штати за кожен дзвінок, якщо методи такі маленькі, як і повинні бути. Цю проблему можна вирішити, використовуючи безліч малих незмінних класів із короткими строками життя об'єкта. Таким чином, ви можете зберігати тимчасовий стан як поля та відкидати об'єкт, коли він більше не потрібен. :-)
Jørgen Fogh

Ще одне врахування того, що цей випадок стає стомлюючим, це те, що, можливо, ви намагаєтеся пройти навколо занадто багато стану. :)
dash-tom-bang

У багатьох випадках це правда, але часто це не так. У деяких доменах вам потрібен доступ до багатьох держав, навіть якщо у вас немає великої кількості змінних . Зараз я працюю над генератором коду, де мені потрібен доступ до кількох таблиць символів. Я не хочу передавати їх кожному методу.
Jørgen Fogh

8
  • Пишіть менше коду, який робить більше.
  • Подумайте про наслідки низького рівня та наслідки високого рівня
  • Поміркуйте абстракцію, яку ви створюєте у своєму коді.
  • Напишіть лише можливі складності, якщо це можливо.

Я збирався написати великий пост, який підсумовує як "пишіть менше, що робить більше" (IOW знаю і використовую доступні вам інструменти). Я просто замість цього +1.
Kaz Dragon

1
Але будьте обережні, щоб не отримати фантазійного коду, намагаючись досягти меншого коду.
габлін

1
@gablin: фантазія в очах глядачів багато в чому. Я можу сьогодні написати та прочитати код, який був би задушений у 4 роки тому. Сьогодні Haskell мені подобається. :)
Пол Натан

8

Трохи менш технічна відповідь: не програмуйте, коли ви втомилися (9 годин на день достатньо), п’яні або «запечені». Коли я втомився, мені не вистачає терпіння писати чистий код.


2
Як правило, більшості програмістів потрібно кілька років, щоб зрозуміти це. Це важливий момент.
Джефф Девіс


5

Тут є кілька чудових відповідей щодо тестування одиниць та інструментів. Єдине, що я можу додати до них:

Залучайте тестерів якомога раніше

Якщо у вас є тестова команда, не потрапляйте у пастку, коли ви ставитесь до них як до службовців якості якості вашого коду та не зафіксуєте ваші вади. Натомість працюйте з ними та залучайте їх якомога раніше (для спритних проектів це буде від початку проекту, але ми завжди можемо знайти способи залучити їх раніше, якщо ми дійсно намагатимемося).

  • Дізнайтеся, який їх план тестування. Перегляньте з ними їхні тестові випадки - чи покриваєте ви їх усім своїм кодом?
  • Попросіть їх зрозуміти вимоги. Це те саме, що і ваше?
  • Дайте їм ранні робочі конструкції для проведення дослідницьких випробувань - ви будете вражені вдосконаленнями, які вони запропонують.

Хороші робочі стосунки з вашими тестерами означає, що ви зможете зловити припущення та дефекти дуже рано, перш ніж вони зможуть завдати шкоди. Це також означає, що тестувальники відчувають повноваження допомагати в розробці продукту та вирішувати питання юзабіліті, коли є час їх виправити.


4

Інструменти статичного аналізу

Плагіни та додатки, такі як FindBugs, сканують ваш код і знаходять місця, де є потенційні помилки. Місця, де змінні не ініціалізуються та не використовуються або просто божевільні речі, які 9 разів із 10, полегшують виникнення помилок. Такі інструменти допомагають мені запобігти моєму костелі рухатися по дорозі, навіть якщо це ще не помилка.

PS: Не забудьте завжди досліджувати, чому інструмент говорить вам про щось погано. Ніколи не боляче вчитися (і не все правильно у всіх ситуаціях).


3

Перевірка коду або інші форми експертної оцінки, такі як парне програмування.

Структуровані кодові огляди, такі як перевірка Фагана, можуть бути принаймні настільки ж ефективними та ефективними, як тестування одиниць, а в деяких випадках навіть виявились кращими за тестування одиниць. Інспекції також можна використовувати раніше в життєвому циклі програмного забезпечення та з артефактами, крім коду.

Огляди експертів із програмного забезпечення Карла Вігерса - це чудова книга з цього приводу.


2

Окрім усіх інших пропозицій тут, увімкніть усі можливі попередження до найвищого рівня чутливості та розглядайте їх як помилки. Також використовуйте будь-які інструменти для підв’язки, якими володіє мова.

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


2

Тут багато хороших відповідей, але кілька речей я хотів додати. Переконайтесь, що ви насправді розумієте вимогу. Я бачив багато помилок, коли користувач думав, що ця вимога означає X, а програміст подумав, що це означає Y. Відштовхуйтесь, щоб з’ясувати погані або неоднозначні вимоги. Я знаю, що всі ми любимо заскочувати і кодувати, але чим більше часу, витраченого на фронт, забезпечуючи розуміння, тим менше буде переробляти і виправляти помилки.

Ознайомтеся з бізнесом, який ви підтримуєте, ви часто побачите речі, які відсутні у вимогах, які тоді відсутні або потребують подальшого пояснення. Знайте, що якщо ви виконаєте завдання Y, як зазначено, це порушить існуючу функцію Z.

Розуміння структури вашої бази даних. Багато багатьох помилок є результатом запиту, який є синтаксично правильним, але повертає неправильні результати. Дізнайтеся, як розпізнати, коли результати виглядають смішно. Якщо я пишу складний запит щодо звітування, я завжди залучаю технічного фахівця для перегляду моїх результатів, перш ніж я відзначу його як готовий до роботи, вони неминуче побачать щось у даних, які я пропустив. Потім зробіть собі записки про те, що вони схопили, що ви цього не зробили, і пам’ятайте, що наступного разу ви зробите щось подібне.


1

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

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


1

Я дотримуюся практики Test-Code-Test замість Code-test-code-test. Це допомагає мені думати про випадки використання та відповідним чином формувати логіку


1

Використовуйте інструменти перевірки коду, такі як ReSharper або IDE, такі як IntelliJ IDEA, які попереджають про багато помилок копіювання та вставки та інші, наприклад, вказуючи змінні, "які записані, але ніколи не прочитані". Врятувало мені багато часу.


1

Дивно, але ще не було згадано наступні три дуже важливі моменти:

  • Використовуйте твердження вільно. Питання, яке ви завжди повинні задавати собі, це не "чи варто це стверджувати?" але "чи я щось забув стверджувати?"

  • Вибирають незмінність. (Використовуйте остаточне / читання лише вільно.) Чим менше у вас стан змін, тим менше речей може піти не так.

  • Не оптимізуйте передчасно. Багато програмістів відстежують проблеми, пов'язані з ефективністю, змушуючи їх непотрібно перекручувати код і базікати, не заздалегідь усвідомлюючи, чи не буде продуктивність. По-перше, побудуйте свій програмний продукт академічним шляхом, не зважаючи на ефективність; потім подивіться, чи погано працює; (Мабуть, не буде.) Якщо виникають якісь проблеми з продуктивністю, знайдіть одне або два місця, де ви зможете запропонувати приємні та формальні алгоритмічні оптимізації, які дозволять вашому продукту відповідати його вимогам щодо продуктивності, а не налаштовувати та не зламати всю базу коду. стискайте цикли годин та тут.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.