Перейти к основному содержимому

Отладка и видимость состояния

Разработчику Архитектору Инженеру

Отладка и видимость состояния

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

Play ITЗагрузка интерактивного демо…


Значения переменных

Переменная — это именованная область памяти, которая хранит данные определённого типа.

Типы значений переменных:

  • примитивные — числа, строки, булевы значения
  • ссылочные — объекты, массивы, коллекции
  • сложные — структуры, классы, пользовательские типы

Примеры значений в разных языках:

Код ITЗагрузка примера кода…

Код ITЗагрузка примера кода…

Код ITЗагрузка примера кода…


Как меняются значения переменных

Значения переменных изменяются в результате:

  • присваивания новых значений
  • вызова методов, изменяющих состояние
  • побочных эффектов операций
  • работы алгоритмов

Пример изменения значений (сначала — без привязки к языку):

счётчик := 0 // счётчик = 0
счётчик := 5 // счётчик = 5
счётчик := счётчик + 3 // счётчик = 8
счётчик := счётчик + 1 // счётчик = 9

список := пустой_список
добавить в список "Яблоко" // список = ["Яблоко"]
добавить в список "Банан" // список = ["Яблоко", "Банан"]
удалить из список "Яблоко" // список = ["Банан"]

Справочно на C#

Код ITЗагрузка примера кода…

Код ITЗагрузка примера кода…

Код ITЗагрузка примера кода…


Как смотреть значения переменных

Существует несколько способов просмотра значений переменных:

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


1. Отладочная печать

Console.WriteLine($"counter = {counter}");
Console.WriteLine($"items = {string.Join(", ", items)}");
print(f"counter = {counter}")
print(f"items = {items}")
console.log(`counter = ${counter}`);
console.log(`items = ${items}`);

2. Точки останова (breakpoints)

Установка точек останова в отладчике позволяет приостановить выполнение и осмотреть состояние программы.

Дополнительно полезны условные точки останова. Они останавливают выполнение только при выполнении правила, например order.Total > 100000 или retryCount == 3. Это ускоряет анализ "редких" ошибок без ручного шага по тысячам итераций.


3. Watch-выражения

Многие отладчики поддерживают отслеживание значений переменных в реальном времени.


4. Интерактивные сессии

# Python REPL
>>> x = 10
>>> x
10
>>> x + 5
15
// C# Interactive в Visual Studio
> int x = 10;
> x
10
> x + 5
15

Логирование — отладочные выводы, трассировка

Трассировка — это запись последовательности выполнения программы для анализа потока управления.

Примеры трассировки:

Код ITЗагрузка примера кода…

Код ITЗагрузка примера кода…

Уровни детализации

Используйте разные уровни логирования:

  • TRACE для детальной трассировки вызовов
  • DEBUG для отладочной информации
  • INFO для стандартных операций В продакшене обычно отключают TRACE и DEBUG для повышения производительности.

Отладчики — брейкпоинты, watch, call stack inspection

Отладчик — это инструмент, который позволяет пошагово выполнять программу и анализировать её состояние.

Практический маршрут диагностики обычно выглядит так:

  1. Повторить проблему в контролируемом сценарии;
  2. Поставить точки останова на границе входа и в подозрительном методе;
  3. Проверить call stack и значения входных параметров;
  4. Сравнить фактическое состояние с ожидаемым контрактом;
  5. Подтвердить исправление повторным прогоном.

Основные функции отладчика:

ФункцияОписаниеПример использования
Точка остановаПриостанавливает выполнение в указанной строкеКлик по номеру строки в IDE
Пошаговое выполнениеВыполняет код по одной инструкцииF10 (Step Over), F11 (Step Into)
WatchОтслеживает значения переменныхДобавление переменной в окно Watch
Call StackПоказывает цепочку вызововОкно Call Stack в отладчике
Условные точкиОстановка при выполнении условияcounter > 100
Точки трассировкиЛогирование без остановкиЛогирование значения переменной

Пример использования отладчика в разных средах:

Visual Studio (C#):

1. Установить точку останова (F9)
2. Запустить отладку (F5)
3. Использовать:
- F10: Step Over (перешагнуть)
- F11: Step Into (войти в метод)
- Shift+F11: Step Out (выйти из метода)
- F5: Continue (продолжить)

PyCharm (Python):

1. Установить точку останова (клик слева от номера строки)
2. Запустить отладку (правая кнопка → Debug)
3. Использовать панель отладки для навигации

Chrome DevTools (JavaScript):

1. Открыть Sources панель (F12)
2. Установить точку останова (клик по номеру строки)
3. Использовать кнопки управления выполнением

Инспекция состояния в продакшене — телеметрия, метрики, логи

Телеметрия — это сбор данных о работе приложения в реальном времени.

Компоненты телеметрии:

Типы данных телеметрии:

  1. Логи — события с временной меткой

Код ITЗагрузка примера кода…

  1. Метрики — числовые показатели
http_requests_total{method="POST", endpoint="/orders", status="200"} 1234
memory_usage_bytes{service="order-service"} 524288000
cpu_usage_percent{service="order-service"} 45.2
  1. Трассировки — цепочки вызовов
TraceId: abc123
├─ Span: ProcessOrder (100ms)
│ ├─ Span: ValidateOrder (10ms)
│ ├─ Span: SaveToDatabase (50ms)
│ └─ Span: SendNotification (40ms)

Пример интеграции телеметрии:

Код ITЗагрузка примера кода…


"Не отвечает" — что это значит?

Зависание приложения — это состояние, при котором программа перестаёт реагировать на пользовательский ввод или внешние события.

Причины зависаний:


1. Бесконечные циклы

Код ITЗагрузка примера кода…

Код ITЗагрузка примера кода…


2. Блокировки и взаимоблокировки (deadlock)

Код ITЗагрузка примера кода…


3. Ожидание внешних ресурсов

Код ITЗагрузка примера кода…


4. Проблемы с памятью

Код ITЗагрузка примера кода…


Как читать ошибки?

Структура сообщения об ошибке обычно включает:

  1. Тип исключения — класс ошибки
  2. Сообщение — описание проблемы
  3. Стек вызовов — цепочка методов, приведших к ошибке
  4. Дополнительные данные — контекст ошибки

Пример чтения ошибки в C#:

System.IO.FileNotFoundException:
Could not find file 'C:\config.txt'.

at System.IO.FileStream.ValidateFileHandle(SafeFileHandle fileHandle)
at System.IO.FileStream.CreateFileOpenHandle(FileMode mode, FileShare share)
at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access)
at Program.ReadFile(String path) in C:\Program.cs:line 15
at Program.Main(String[] args) in C:\Program.cs:line 8

Анализ:

  • Тип: FileNotFoundException — файл не найден
  • Сообщение: Could not find file 'C:\config.txt' — какой файл
  • Стек вызовов: показывает путь от Main до FileStream
  • Место в коде: Program.cs:line 15 — где произошла ошибка

Пример чтения ошибки в Python:

Traceback (most recent call last):
File "app.py", line 10, in <module>
result = divide(10, 0)
File "app.py", line 6, in divide
return a / b
ZeroDivisionError: division by zero

Анализ:

  • Тип: ZeroDivisionError — деление на ноль
  • Сообщение: division by zero — описание ошибки
  • Стек вызовов: от divide в строке 6 до <module> в строке 10

Куда идти дальше


Что запомнить

  • Отладка строится вокруг фактов о состоянии, а не вокруг предположений.
  • Значения переменных, стек вызовов и точки останова дают основу диагностики.
  • Логи и телеметрия продолжают работу отладчика в продакшене.
  • Чем раньше видна некорректная переменная, тем дешевле исправление.

Типичные ошибки

  • Слишком много print без структуры и контекста.
  • Пошаговая отладка без гипотезы и критерия проверки.
  • Игнорирование call stack при анализе исключения.
  • Отсутствие таймаутов и отмены в коде, который ждёт внешние ресурсы.

Мини-практика

  1. Выберите дефект, который периодически повторяется.
  2. Сформулируйте гипотезу, какие две переменные важнее всего.
  3. Поставьте условный breakpoint по этим переменным.
  4. Подтвердите или опровергните гипотезу и зафиксируйте реальную причину.