Единица решает, есть ли задача вообще
Формулировка «превышение у восьми из девяти» выглядит как результат замера и потому не переспрашивается. Пересчёт в символах средствами языка, а не оболочки, показал диапазон 31–62 символа — массового превышения нет, а у сайта, названного «пустым», заголовок на 60 символов.
Механика. Подсчёт длины в оболочке и подсчёт байтов считают кириллический символ за два. Ошибка ровно двукратная, поэтому она не выглядит как сбой: числа правдоподобны, порядок величины привычный, «61 символ» и «122 байта» одинаково похожи на правду.
Настоящий долг после честного замера нашёлся в другом месте — 136 внутренних страниц, на которые никто не смотрел, потому что все смотрели на выдуманное превышение. Ложная задача дорога не только потраченным временем: она забирает внимание у настоящей.
Сумма дефекта в данных не равна искажению на экране
Исполнитель сдал дефект: выплата водителю посчитана в обеих записях зеркальной пары, 40 пар. Пересчёт по живой базе подтвердил ровно эти 40 пар и ровно ту сумму — в данных. Дефект при этом заявлен про экраны, а экраны считают по-разному.
| Где смотрим | Что делает код | Сколько задваивается |
|---|---|---|
| Данные, прямой пересчёт | ищет зеркальные пары по всей базе | все 40 пар |
| Страница водителя | отбрасывает зеркало, только если оригинал попал в набор того же водителя | 6 кросс-водительских пар |
| Разрез по периоду | идёт по записям напрямую, зеркала не пропускает вовсе | все пары периода |
Разница между крайними экранами — 8,5 раза. Спор «сколько стоит дефект» без ответа «на каком экране» неразрешим в принципе: обе стороны правы и обе меряют разное.
- Найти функцию, которая строит нужный экран.
- Выписать её фильтры — что она отбрасывает и по какому условию.
- Повторить эти фильтры в проверочном скрипте и только после этого называть величину.
- В формулировке дать адрес: «на странице водителя столько, в разрезе по периоду столько», а не одно число «дефект на N».
Приёмка фикса — «до и после» на одном снимке базы по каждому экрану отдельно. Сошлось на одном и не сошлось на другом — значит починка поставлена в одну точку из двух, а это и было исходной причиной дефекта.
Горизонт: за какой период и из какого источника
За один день три числа в задачах оказались неверными. «223 рейса» — на деле 326. «13 страниц под сегмент» — на деле 3. Самое дорогое: сумма, вынесенная в задачу как задолженность клиента, взята из архива за всю историю, тогда как в рабочей базе долг складывался из одной неоплаченной позиции.
Класс ошибки — «архивная сумма выдана за текущую». Спрашивать надо не только «какое число», но и «откуда оно и на какой момент». Разрыв между историческим объёмом и текущим состоянием реален, но означает он объём работы по восстановлению истории, а не деньги к взысканию — это разные задачи с разным приоритетом и разным исполнителем.
Пересчёт того же клиента по свежему снимку дал 92 рейса и 17 счетов. Число из задачи и число из базы разошлись не потому, что кто-то соврал, а потому, что снимок устаревает быстрее, чем закрывается задача.
Второй случай оттуда же — вывод, опровергнутый за минуту до записи в базу. Гипотеза звучала как «клиент заведён дважды»: 52 рейса с его именем и пустым идентификатором клиента. Разбор показал, что это водительская сторона учёта: у всех проставлен водитель, у 28 — ссылка на оригинал записи, у 38 — нулевая сумма, и заведены они импортом из переписки. Простановка идентификатора задвоила бы карточку клиента прямо перед выставлением счетов.
Снятая находка — тоже результат, и проверяется так же
Два заявленных отката в той же волне оказались уже починенными: одно значение выставлено в ноль по прямому решению владельца, вторая функция вернулась отдельным коммитом. Вводная про длину заголовков снялась целиком. Все три проверки шли против кода, а не против пересказа, — иначе снятие находки стоило бы ровно столько же, сколько сама находка.
Приятный результат опаснее тревожного. «Работы нет, всё уже сделано» — самый дешёвый способ закрыть задачу неправильно: проверять никто не просит, отчёт короткий, настроение хорошее. Второй проход нужен и на тревоге, и на зелёном, но на зелёном о нём забывают чаще.
Как мы теперь записываем число
- Единица в самой формулировке: символы или байты, записи или строки, рейсы или пары. Двукратные расхождения почти всегда живут здесь.
- Адрес рядом со значением: название экрана или запроса, которым величина получена. Число без адреса нельзя ни воспроизвести, ни оспорить.
- Горизонт и источник: на какой момент и откуда — живая база, архив, выгрузка, чужой отчёт.
- Пересчёт до работы, а не после. Совпало — работаем; разошлось — сначала переписываем карточку, потом работаем. Иногда после пересчёта задача меняет приоритет или исполнителя.
Три признака добавляют к строке отчёта десяток слов и снимают целый класс споров, где обе стороны правы и обе тратят день, чтобы это выяснить.