Я продолжал «чинить» баги, которых не понимал

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

Это один из тех уроков, которые звучат очевидно, если сформулировать их прямо, и которым дьявольски трудно следовать на деле, потому что всё в самом этом моменте подталкивает тебя не туда.

Соблазн исчезнувшего симптома

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

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

Исправления, которые я не мог объяснить

В моём случае паттерн был до неловкого распространённым. Я вносил изменение — менял порядок каких-то операций, добавлял проверку, подправлял что-то рядом, — и ошибка переставала появляться. И если бы ты остановил меня прямо тогда и попросил объяснить в точности, почему моё изменение устранило проблему, я бы не смог этого сделать. Я на самом деле не знал. Я просто знал, что я к чему-то прикоснулся, и зло умолкло.

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

Баг, которого ты не понимаешь, не мёртв — он прячется

Глубинная проблема исправления, которое ты не можешь объяснить, в том, что ты понятия не имеешь, что именно ты сделал. Ты убрал баг или просто переместил его туда, где сейчас его не видно? Ты искренне не знаешь, и эта неопределённость небезобидна. Потому что если причина по-прежнему на месте, нетронутая, она вернётся. Она всплывёт позже, в другом костюме, в каком-то другом углу системы, очень возможно, в худшем, — и когда это случится, у тебя не останется и памяти о том, что это тот же самый враг, которого ты, как тебе казалось, победил несколько месяцев назад.

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

Дом с привидениями, который ты медленно строишь

За достаточный срок система, которую обслуживают таким образом, наполняется изменениями, которых никто, включая их автора, на самом деле не понимает. Проверка, добавленная «потому что без неё ломалось». Порядок, сохранённый из чистого страха. Маленькие ритуалы, чьё изначальное назначение полностью забыто, но которые теперь все слишком боятся убрать.

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

Дисциплина: не доверяй исправлению, которое не можешь объяснить

Правило, которое я в конце концов навязал себе, просто сформулировать и по-настоящему трудно соблюдать: проблема не исправлена, пока я не могу объяснить и почему она возникла, и почему моё изменение устраняет эту причину. Обе половины. Если симптом исчез, но я не могу рассказать эту историю целиком, значит, я ничего не исправил — я лишь потерял проблему из виду, а это куда более опасное состояние, чем проблема, которую я всё ещё вижу.

Это медленнее. Соблазн пропустить этот шаг постоянен, и он сильнее всего ровно в худший момент: когда симптом уже исчез, всё выглядит благополучно, и работа, по всем видимым признакам, кажется сделанной. Именно тогда дисциплина важнее всего и именно тогда она кажется наиболее излишней. Дарёному исправлению в зубы не смотрят — это противоестественно. И это же и есть вся работа.

Почему это важно ещё сильнее в шумной области

Есть причина, по которой эта ловушка особенно коварна в такой области, как эта. Среда крайне шумная, а значит, она постоянно подсовывает тебе ложные подтверждения. Ты вносишь изменение, следующий прогон выглядит лучше — но это было изменение или просто везение? В системе, где исходы качаются сами по себе, «стало лучше после того, как я сделал X» — отчаянно слабое свидетельство того, что X вообще что-то сделал.

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

Более глубокий урок: понимание — единственное настоящее исправление

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

Поэтому теперь, когда что-то начинает работать, а я не знаю почему, я приучил себя не чувствовать облегчения. Вместо этого я стараюсь чувствовать подозрение. Необъяснённый успех — не победа; это нерешённая загадка, которая просто переоделась в одежду победы, и принимать её за первое — один из самых надёжных известных мне способов попасть в засаду, устроенную твоим же прошлым «я».

— Никаких сигналов, никакой доходности, не инвестиционный совет.