Bohrbug — це програмна помилка, яка поводиться детерміновано: за однакових вхідних даних вона відтворюється щоразу без винятку. Назва походить від атомної моделі Нільса Бора, де електрон рухається по строго визначеній орбіті — так само передбачувано, як і цей баг. За даними Вікіпедії (2026), Bohrbug належить до класу найпростіших для діагностики дефектів, оскільки не потребує спеціальних умов для повторення.
Головне
Bohrbug — це тип програмної помилки, яка проявляється детерміновано: за одних і тих самих вхідних даних вона завжди призводить до однакового збою. Термін введено в науковий обіг дослідниками Джимом Греєм та Андреасом Райтером у книзі «Transaction Processing: Concepts and Techniques» (1993).
На відміну від Mandelbug, який хаотично змінює свою поведінку, Bohrbug стабільний: розробник може відтворити його із закритими очима, подавши системі ті самі параметри. Це робить його ідеальним кандидатом для покрокового налагодження в IDE.
Bohrbug зустрічається на всіх етапах життєвого циклу ПЗ — від розробки до експлуатації. Часто він виявляється на етапі тестування, оскільки QA-інженери виконують повторювані сценарії, які гарантовано призводять до збою.
Згідно з класифікацією Грея та Райтера, Bohrbug — це дефект, який задовольняє трьом умовам: фіксований набір вхідних даних, однаковий стан системи та однаковий результат збою. Якщо хоча б одна з умов порушується, баг перестає бути «борівським».
Автори підкреслюють, що Bohrbug — це не обов'язково проста помилка. Він може бути як завгодно складним за логікою, але його детермінізм відрізняє його від усіх інших типів збоїв у класифікації.
Назва Bohrbug походить від імені датського фізика Нільса Бора, творця планетарної моделі атома. Аналогія проста: як електрон у моделі Бора рухається по строго фіксованій орбіті, так і цей баг повторює ту саму поведінку при кожному запуску.
Грей та Райтер обрали цю назву, щоб протиставити детерміновані помилки хаотичним, які вони назвали Mandelbug — на честь математика Бенуа Мандельброта, основоположника теорії фракталів та хаосу.
Цікаво, що в англомовній літературі термін Bohrbug часто використовується як синонім «детермінованої помилки», хоча в україномовному середовищі він менш поширений. Більшість розробників називають такі баги просто «відтворюваними помилками».
Bohrbug має набір відмінних властивостей, які дозволяють ідентифікувати його серед інших типів програмних дефектів. Розглянемо кожну характеристику докладно.
Головна риса Bohrbug — повна передбачуваність. Якщо застосунок впав за певних вхідних даних на машині розробника, він впаде точно так само на машині тестувальника та в продакшені. Жодних випадкових факторів.
Bohrbug відтворюється у 100% спроб. Це означає, що для його налагодження не потрібні спеціальні інструменти — достатньо звичайної IDE та налагоджувача. Розробник ставить точку зупинки, запускає застосунок, подає вхідні дані та покроково проходить код.
Якщо Bohrbug не виправити, він буде відтворюватися в будь-якій версії програми до моменту виправлення. Часові фактори — завантаження CPU, фаза місяця, час доби — не впливають на його прояв.
Причини виникнення Bohrbug можна розділити на кілька категорій. Розуміння цих категорій допомагає швидше знаходити корінь проблеми.
Неправильно побудована умова — найчастіша причина Bohrbug. Наприклад, розробник використав оператор `||` замість `&&`, що призвело до некоректного виконання гілки коду при кожному виклику функції з певними аргументами.
Використання оператора `<=` замість `<` або зворотна ситуація — класичне джерело Bohrbug. Якщо цикл має виконатися 10 разів, а виконується 11 через невірну умову, це детермінована помилка, яка проявиться при кожному запуску.
Жорстко закодовані константи, які не відповідають бізнес-логіці, створюють стабільні збої. Наприклад, таймаут підключення до сервера встановлено в 100 мілісекунд замість 5000 — з'єднання буде обриватися при кожному запиті.
Виявлення Bohrbug — найпростіше завдання для розробника порівняно з іншими типами багів. Детермінований характер дозволяє застосовувати стандартні методи налагодження.
public class DiscountCalculator {
public double calculate(double amount, boolean isPremium) {
// Помилка: преміум-користувачі отримують знижку 5% замість 10%
if (isPremium) {
return amount * 0.95;
}
return amount * 0.90;
}
}
У цьому прикладі Bohrbug очевидний: при виклику `calculate(1000, true)` метод завжди повертає 950 замість 900. Найпростіший unit-тест з фіксованими вхідними даними миттєво виявить проблему.
Для виявлення Bohrbug unit-тести — найефективніший засіб. Достатньо покрити функцію набором тестів з різними граничними значеннями, і детермінована помилка проявиться при першому ж прогоні.
Коли Bohrbug виявлено, покрокове налагодження в IDE — найкращий спосіб знайти корінь. Розробник ставить точку зупинки на вході у функцію та проходить кожен рядок, спостерігаючи за значеннями змінних.
Bohrbug відрізняється від інших типів програмних помилок за ключовою ознакою — детермінованістю. Розглянемо порівняння в таблиці.
| Тип багу | Відтворюваність | Причина | Складність налагодження |
|---|---|---|---|
| Bohrbug | 100% за тих самих вхідних | Логічна помилка | Низька |
| Mandelbug | Залежить від стану | Гонка потоків, таймінги | Висока |
| Schrödinbug | До читання коду — 0% | Усвідомлення помилки | Психологічна |
| Hindenbug | Одноразово | Каскад відмов | Екстремальна |
| Heisenbug | Змінюється при налагодженні | Оптимізація компілятора | Середня |
Bohrbug — єдиний тип помилки, який можна гарантовано відтворити в контрольованих умовах. Це робить його найбезпечнішим з точки зору діагностики, але не менш небезпечним для користувача.
Heisenbug — баг, який зникає при спробі його налагодити. На відміну від Bohrbug, Heisenbug може не відтворюватися в налагоджувачі через зміну таймінгів виконання коду. Початківці-розробники часто плутають ці два типи.
Розглянемо реальний приклад Bohrbug у застосунку для інтернет-магазину. Функція розраховує підсумкову вартість замовлення з урахуванням податку.
public double calculateTotal(double subtotal, double taxRate) {
// Помилка: розробник встановив taxRate як відсоток
// але забув поділити на 100
return subtotal + (subtotal * taxRate);
}
При виклику `calculateTotal(1000, 20)` функція поверне 21000 замість очікуваних 1200. Це класичний Bohrbug: одні й ті самі вхідні дані завжди призводять до одного й того самого невірного результату. Виправлення тривіальне — додати ділення на 100.
Після виправлення функція коректно обробляє податкову ставку:
public double calculateTotal(double subtotal, double taxRatePercent) {
return subtotal + (subtotal * taxRatePercent / 100.0);
}
Цей приклад наочно показує, що Bohrbug може бути викликаний найпростішою математичною помилкою. Саме тому код-рев'ю та unit-тести — головні інструменти профілактики таких дефектів.
Часті запитання
Bohrbug — це різновид звичайного багу, який відрізняється суворою детермінованістю. Будь-який Bohrbug є багом, але не кожен баг — Bohrbug. Звичайний баг може відтворюватися нестабільно або залежати від зовнішніх факторів.
Стабільним Bohrbug називають через його здатність відтворюватися при кожному запуску з однаковими вхідними даними. Ця властивість робить його передбачуваним і зручним для налагодження — на відміну від Mandelbug або Heisenbug.
Термін Bohrbug ввели Джим Грей та Андреас Райтер у 1993 році в книзі «Transaction Processing: Concepts and Techniques». Вони класифікували програмні помилки за ступенем детермінованості, використовуючи аналогії з фізики та математики.
Для швидкого виправлення Bohrbug необхідно: відтворити баг у тестовому середовищі, пройти код покроково в налагоджувачі, знайти рядок з невірною логікою та написати unit-тест, який перевіряє коректну поведінку.
Так, Bohrbug може бути як завгодно складним за своєю логікою. Детермінованість не означає простоту. Баг може включати безліч умов і вкладених викликів, але якщо він стабільно відтворюється — це Bohrbug.
Підсумки
Ми розробимо мобільний застосунок під ключ
IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.
Читайте також