이해하지 못한 버그를 계속 '고치고' 있었다
예전에는 버그가 사라지면 환호했다. 어떤 문제가 나를 괴롭히고 있을 때, 뭔가를 바꾸면 문제가 사라지고, 나는 따뜻하게 차오르는 승리감을 느끼며 다음으로 넘어가곤 했다. 버그가 사라지는 것과 버그가 고쳐지는 것은 완전히 다른 사건이라는 사실을 깨닫기까지는 오랜 시간과 많은 고통이 필요했다. 그리고 그 둘을 혼동하는 동안, 사실 전혀 해결하지 못한 문제들이 조용히 내 시스템을 채워가고 있었다. 나는 그저 그 문제들을 내 자신으로부터 숨겨두었을 뿐이었다.
이건 그냥 말로 풀어놓으면 너무나 당연하게 들리지만, 실제로 지키며 살아가기는 지독히 어려운 교훈 중 하나다. 그 순간의 모든 것이 당신을 잘못된 방향으로 밀어붙이기 때문이다.
증상이 사라지는 것의 유혹
문제가 뭔가를 바꾸자마자 사라지면, 모든 본능이 당신이 그것을 고쳤다고 외친다. 그 안도감은 진짜이고, 즉각적이며, 화학적이다. 다음 일로 넘어가라는 압박은 엄청나다. 보기에 더 이상 문제가 아니게 된 문제를 누가 계속 들쑤시고 싶어 하겠는가?
하지만 그 안도감 밑에 숨어 있는 불편한 진실은 이것이다. 증상이 사라졌다는 사실은 오직 증상이 사라졌다는 것만을 증명할 뿐이다. 그것은 당신이 실제로 근본 원인을 다루었는지, 아니면 그저 한동안 잠잠해질 만큼 건드리기만 했는지에 대해 아무것도 — 정말 아무것도 — 말해주지 않는다. 그 두 결과는 그 순간에는 똑같아 보인다. 똑같이 느껴진다. 하지만 결코 같지 않다.
설명할 수 없었던 수정
내 경우, 그 패턴은 부끄러울 만큼 흔했다. 나는 뭔가를 바꾸곤 했다 — 몇몇 연산의 순서를 뒤섞거나, 가드를 추가하거나, 근처의 뭔가를 조정하거나 — 그러면 에러가 더 이상 나타나지 않았다. 그리고 바로 그 순간 누군가 나를 멈춰 세우고 내 변경이 왜 정확히 그 문제를 해결했는지 설명해보라고 했다면, 나는 그러지 못했을 것이다. 사실 나는 몰랐다. 그저 뭔가를 건드렸더니 그 고약함이 조용해졌다는 것만 알 뿐이었다.
나는 그것을 수정이라고 불렀다. 하지만 그건 사실 디버깅이라고 할 수도 없었다. 그건 제단에 제물을 바치고 신들이 잠시나마 누그러진 듯하다는 것을 알아차리는 일에 더 가까웠다. 나는 뭔가를 바꿨고, 우주는 나를 벌하기를 멈췄으며, 나는 그 상관관계를 이해라고 해석하기로 했다. 그건 이해가 아니었다. 커밋 메시지가 달린 미신이었다.
이해하지 못한 버그는 죽은 게 아니라 — 숨어 있는 것이다
설명할 수 없는 수정의 깊은 문제는, 당신이 실제로 무엇을 했는지 전혀 모른다는 데 있다. 버그를 제거한 것인가, 아니면 그저 지금 당장 볼 수 없는 어딘가로 옮겨놓은 것인가? 당신은 정말로 모르고, 그 불확실성은 무해하지 않다. 원인이 손대지 않은 채 여전히 거기 있다면, 그것은 돌아올 것이기 때문이다. 그것은 나중에 다른 옷을 입고, 시스템의 다른 구석에서, 아주 어쩌면 더 나쁜 모습으로 다시 떠오를 것이다 — 그리고 그렇게 될 때, 당신은 그것이 몇 달 전 물리쳤다고 생각했던 바로 그 적이라는 기억조차 없을 것이다.
이것이 내가 가장 크게 과소평가했던 부분이다. 설명되지 않은 수정은 시스템 안의 버그 수를 실제로 줄이지 않는다. 그것들은 버그를 재배치할 뿐이고, 당신이 그것들을 다시 알아볼 수 있게 해줄 지식마저 앗아간다. 당신은 싸움에서 이기고 있는 게 아니다. 그저 같은 상대를 여러 변장으로 흩뿌리고 있을 뿐이다.
당신이 서서히 짓는 유령의 집
충분한 시간이 지나면, 이런 식으로 유지된 시스템은 그 작성자를 포함해 아무도 실제로 이해하지 못하는 변경들로 가득 찬다. “이게 없으면 깨졌으니까” 추가된 가드. 순전히 두려움 말고는 아무 이유 없이 보존된 순서. 원래 목적은 완전히 잊혔지만 이제 모두가 너무 불안해서 건드리지 못하는 작은 의식들.
코드베이스는 점차 미신들의 유령의 집이 된다 — 무엇을 떠받치고 있는지 확신할 수 없어서 손대지 못하는 것들로 가득한. 그리고 가장 잔인한 부분은 이것이 무언가를 바꾸는 당신의 능력에 미치는 영향이다. 무엇이 하중을 지탱하고 무엇이 장식인지 모를 때, 당신은 아무것도 확신을 가지고 옮길 수 없다. 모든 변경이 당신이 이해하지 못하는 힘에 맞선 도박이 된다. 당신이 지었지만 더 이상 이해하지 못하는 구조물 안에서.
규율: 설명할 수 없는 수정은 믿지 마라
결국 내가 스스로에게 강제한 규칙은 말하기는 간단하지만 지키기는 정말로 어렵다. 어떤 문제는 그것이 왜 일어났는지와 내 변경이 왜 그 원인을 다루는지를 둘 다 설명할 수 있을 때까지는 고쳐진 것이 아니다. 두 절반 모두. 증상은 사라졌지만 그 완전한 이야기를 말할 수 없다면, 나는 아무것도 고치지 않은 것이다 — 나는 그저 문제를 시야에서 놓친 것뿐이고, 그것은 아직 보이는 문제보다 훨씬 더 위험한 상태다.
이건 더 느리다. 끊임없이 건너뛰고 싶은 유혹이 따르고, 그 유혹은 정확히 최악의 순간에 가장 강하다. 증상이 이미 사라졌고 모든 것이 괜찮아 보이며, 눈에 보이는 모든 신호로 봐서는 일이 끝난 것처럼 보일 때. 바로 그때가 이 규율이 가장 중요한 순간이고, 바로 그때가 이 규율이 가장 불필요하게 느껴지는 순간이다. 거저 얻은 수정을 의심하는 일은 부자연스럽다. 그것이 또한 일의 전부다.
노이즈가 많은 영역에서 이것이 더더욱 중요한 이유
이 함정이 이런 영역에서 특히 악랄한 데에는 이유가 있다. 이 환경은 극도로 노이즈가 많고, 이는 곧 끊임없이 거짓 확증을 건네준다는 뜻이다. 당신이 변경을 하면 다음 실행이 더 나아 보인다 — 그런데 그게 그 변경 때문이었나, 아니면 그냥 운이었나? 결과가 제멋대로 출렁이는 시스템에서, “내가 X를 한 뒤에 더 나아졌다”는 X가 무언가를 했다는 절망적으로 빈약한 증거다.
미신은 정확히 결과가 노이즈로 가득한 곳에서 번성한다. 노이즈가 무작위적인 의식들을 딱 진짜처럼 느껴질 만큼 자주 보상해주기 때문이다. 모든 것을 평가하기 어렵게 만드는 그 무작위성이, 동시에 아무것도 하지 않은 수정을 믿기에도 위험할 만큼 쉽게 만든다. 이따금씩 당신의 무의미한 몸짓 직후에 주사위가 당신에게 유리하게 떨어지고, 당신의 뇌는 열성적으로 원인을 기록하기 때문이다.
더 깊은 교훈: 이해만이 유일한 진짜 수정이다
내가 마침내 믿게 된 것은, 유일하게 지속되는 수정은 원인까지 끝까지 이해한 수정뿐이라는 것이다. 그 외의 모든 것은 미래를 담보로 빌리는 것이다. 이해하지 못한 채 덧칠해버린 버그는 사라지지 않는다. 그것은 조용해질 뿐이고, 빌린 돈은 나중에 이자까지 붙어서, 당신이 그것을 빌린 적이 있다는 것조차 완전히 잊어버린 시점에 갚을 때가 돌아온다.
그래서 이제는 무언가가 작동하기 시작하는데 그 이유를 모를 때, 나는 안도감을 느끼지 않도록 스스로를 훈련했다. 대신 의심을 느끼려 한다. 설명되지 않은 성공은 승리가 아니다. 그것은 우연히 승리의 옷을 걸치고 있는, 풀리지 않은 수수께끼다. 그리고 그것을 전자로 취급하는 것은 내가 아는 가장 확실한, 과거의 당신 자신에게 매복당하는 방법 중 하나다.
— 시그널도, 수익도 없습니다. 투자 자문이 아닙니다.