이슈에 대처하는 개발자의 자세
두려움은 곧 두려움에 대한 두려움이 아니고 무엇이랴 - 칼릴 지브란
"오 마이 갓김치!"
갑자기 터져나온 나의 큰 소리에 회사 사무실에 있던 모든 사람들의 이목이 쏠렸다.
'얘가 지금 뭐라고 한거야! 문제가 없었던 테스트가 지금 패일(fail)되었다고 한거야?"
컴퓨터 모니터에 띄워져 있는 채팅창에 급하게 다시 영어로 질문을 타이핑했다. 담당 중국 엔지니어의 답변은 똑같았다.
"Yes, it failed"
'지금 뭐 하자는 거야! 2주동안 아무런 문제가 없다고 하다가, 테스트 종료 2시간 전에 문제가 있다고 하면 어쩌자는 거야!'
황당함에 말문이 막혔다. 원래 패스(pass)되었던 테스트 항목인데, 어째서 이런 일이 있을수 있냐고 따지자 중국 엔지니어는 간단하게 대답했다. 그때는 자기가 잘못 테스트해서 그랬던 것 같고, 지금 보니 문제가 있다고 말이다.
어쩐지 처음부터 담당 테스트 엔지니어가 어설프고 마음에 안들었다. 2주동안 프리 테스트(Pre-Test)가 끝나면 바로 다음날 본 인증 테스트(Official Certification Test)가 진행되는 일정이었다. 소프트웨어의 보안(Security)을 공인기관에서 검증하는 인증 테스트는 까다롭고 기간도 길다. 비용도 엄청 비싸다. 그래서 추가 비용이 들더라도 인증에 실패하는 것을 막기 위해 프리 테스트를 진행한다. 프리 테스트 기간에는 소프트웨어 개발 담당자가 현지 테스트 랩(LAB)에 직접 출장가서 담당 테스트 엔지니어와 붙어서 테스트 및 디버깅을 진행하는 것이 관례였다. 하지만 전세계적으로 유행하고 있는 코로나 때문에 해외출장은 불가했다. 원격으로 프리 테스트를 진행하는 것으로 인증업체와 협의가 되었다. 메신저 및 이메일을 통해 중국 상하이에 있는 인증 테스트랩 담당 엔지니어와 실시간으로 테스트를 진행했고, 2주간의 테스트가 종료되기 불과 2시간 전이었다. 프리 테스트 초반에 문제가 많이 나오지만 한주정도 지나면 대부분의 문제는 밤을 새서라도 해결하므로 2주차정도 되면 별 문제가 발생하지 않는게 보통 상황이다. 마지막 2~3일은 마무리하는 차원에서 기존에 테스트했던 것들을 한번 더 확인하는게 관례였고, 문제가 있었던 적은 한번도 없었다.
중국 엔지니어도 자기 실수탓에 벌어진 긴박한 상황을 인지해서인지, 평소와 달리 빠르게 대응해주는 것 같았지만 시간이 너무 부족했다. 남은 2시간은 소프트웨어 버그를 디버깅하기 턱없이 부족한 시간이었다. 현지 테스트랩에서 특수한 장비로 시뮬레이션하면서 테스트하는 거라 우리쪽에서는 동일 문제를 재현할수조차 없었다. 30분 가량 질문과 답변이 오고 간 끝에 파악한 결과 발생한 문제는 심각한 이슈(critical failure)였다. 경험상 현실적으로 내일부터 본인증 테스트를 정상진행하는 것은 어렵다고 판단하여 팀장 및 경영진에게 보고하고 그에 대한 조치를 요청했다. 비록 페널티 비용을 물더라도 뻔하게 통과하지 못할 인증 테스트를 진행할수는 없는 노릇이였다.
정신없이 긴급조치를 하고 나니 1시간정도의 시간이 남았다. 윗선에 보고까지 했으니, 이제 타고 있는 똥줄을 잠시 식히며 소프트웨어 코드를 다시 들여다보았다. 직접 문제를 재현할 수 없으니, 중국 엔지니어가 제공한 정보와 연관된 소프트웨어 코드를 번갈아 보며 분석을 진행했다. 10분, 20분 빠르게 시간이 지났다. 하지만 차분하게 집중하니, 점차 퍼즐이 하나하나 들어맞는게 느껴졌다. 흐릿한 윤곽이 점점 선명해지면서 불현듯 코드의 버그가 한 눈에 들어왔다. '이거다!'. 남은 시간은 이제 30분. 바로 버그를 수정한 소프트웨어를 빌드해서 메신저로 보내고 확인을 요청했다. 확신은 했지만, 장담할 수는 없었던 상황이므로 초조하게 결과를 기다렸다. 10분후 '딩동' 메신저 알람이 떴다.
"now it passed :)"
'이 자식, 사람 간 떨어지게 만들어놓고 웃기는..' 안도감에 피식 웃음이 나왔다. 폭풍과도 같은 2시간을 보냈으나 결과가 좋아 천만다행이었다. 만약 문제를 해결하지 못하고, 인증을 연기했다면 개발일정과 비용면에서 큰 손해가 있었을 것이다. 내가 살기 위해 중국 엔지니어를 악당이자 원흉으로 만들수밖에 없었을 것이다. 하지만 생각을 바꿔서 중국 엔지니어가 마지막에 그 문제를 찾지 못했더라면 어땠을까? 아무도 문제가 있다는 것은 까맣게 모른채 본 인증 테스트를 들어갔을 테고, 2주후에 "FAIL"이라고 나온 결과에 모두가 당혹할수밖에 없었을 것이다. 물론 비용 및 개발일정면에서 인증을 연기하는 것과는 비교할수없는 큰 손해를 회사에 끼쳤을테고 말이다. 그렇게 따져보니 문제를 해결하지 못했더라도 중국 엔지니어가 막판에 문제를 발견한 것은 최선의 결과였다. 비록 내가 그 얘기를 듣자마자 뒷목을 잡으며 입에 거품을 물긴 했지만 말이다.
생각해보니 아침에 출근할 때도 비슷한 일이 있었다. 지하철역을 가기 위해 집을 나와 아파트 입구 정도에 이르렀는데, 아파트 관리사무소에서 전화가 왔다. 옥상 청소때문에 꼭 필요하니 차를 다른 곳으로 주차시켜달라는 전화였다. 처음 전화를 받았을때는 '왜 하필 출근하기 바쁜데 지금 차를 빼달라는 거야' 투덜댔지만, 막상 차를 다른 곳으로 주차시킨 후 허겁지겁 전철역으로 뛰어가면서 든 생각은 달랐다.
'분명 어제 관리사무소에서 방송으로 공지를 했을텐데, 내가 늦게 퇴근해서 못 들었을거야. 출근중이지만 멀리 가지 않았을 때 전화를 받아서 참 다행이였던 것 같다. 안 그랬으면 차를 빼주지도 못하고 이래저래 문제가 더 많았을테니 말이야'
다른 직장인들도 마찬가지겠지만, 소프트웨어 개발자에게 이슈(issue)는 참으로 고약한 단어다. 프로젝트의 진행이 마비되는 쇼스탑퍼(show stopper)나 이슈의 원인이 되는 버그(bug)까지 총 망라해서 이슈라고 통칭할 수 있을 것이다. 일반적으로 이슈는 어떤 주제나 쟁점, 문제, 일의 단위를 지칭하지만, 개발자에게 '이슈'는 단순하게 말하면 공식적으로 불거진 '문제거리'다. 살면서 아무런 문제나 걱정거리가 없는 것이 불가능하듯이, 일을 하면 크든 작든 이슈는 필연적으로 발생한다. 하나의 이슈 때문에 심하게 고생을 한 나머지 개발자 생활을 지속해야 하나 고민에 빠지기도 한다. 내게 그 고민은 2006년 가을 독일에서 찾아왔다, 담당하던 소프트웨어 모듈의 심각한 버그로 제품의 공식 인증이 실패했고, 모든 비난과 화살이 이제 갓 4년차 개발자인 나에게 쏟아졌다. 입사해서 말 한번 섞어본 적 없는 고위급 임원이 직접 내게 전화를 해서 너때문에 사업이 망하게 생겼다고 소리를 질러댔다. 결국 출장을 나가서 문제를 해결했다. 사업도 망하지 않았다. 하지만 그 사건 이후 이슈라는 말만 들어도 바짝 긴장했다. 자라 보고 놀란 가슴, 솥뚜껑 보고 놀란다고 작은 이슈 하나하나에도 심장이 두근거렸다. 인증이나 신모델 출시와 같이 민감한 시기에는 스트레스로 잠을 제대로 자지 못했다. 뼈아픈 경험으로 큰 교훈을 얻었으니 회사생활을 더 잘할거라고 말하는 분들도 있었다. 맞는 말이었다. 장점도 있었다. 원천적으로 이슈를 만들지 않기 위해 엄청나게 노력했다. 그 결과 '이전에 심각한 버그로 사업을 망하게 할뻔 한 놈'이라는 오명을 벗고, 일 잘 한다는 평판을 얻게 되었다. 하지만 이슈는 사라지지 않았다. 언제나 나는 이슈에 허덕거렸다.
십수년이 넘는 세월이 흘렀다. 이후에도 수많은 이슈를 만나고 해결해왔다. 물론 해결하지 못한 이슈들도 있다. 내가 직접 해결하지 못 한 것들도 있다는 말이다. 하지만 끝나지 않는 이슈는 없었다. 어떻게든 해결이 되었다. 소프트웨어 개발을 시작한 이래로 이슈라는 녀석의 본질이 변한 적은 한번도 없었다. 다만 내 스스로가 변했음을 느낀다. 이슈는 실패(failure)인가? 아니다. 단지 과정 중에 만난 튀어나온 못 같은 것이다. 귀찮긴 하지만 집어넣거나 뽑으면 된다. 이는 건강과 질병의 관계와도 같다. 병이 나면 건강에 실패한 것인가? 아니다. 예방에는 실패했을지 몰라도, 병에 걸렸다고 다 죽지는 않는다. 때로는 가벼운 병이 건강을 더 챙기게 되는 계기가 되기도 한다. 몸에 문제가 생기면 이상 현상이 외부로 나타난다. 병이 나는 것이다. 문제가 생겼으니 고치라고 몸이 요청하는 것이다. 만약 몸 안에 문제가 생겼는데도, 몸이 외부로 아무런 증상을 나타내지 않는다면 어떻게 되겠는가? 말기나 되서 드러나는 악성 암과 같은 질병들 말이다.
이슈에 감사할 필요도 있다는 말이다. 문제가 없는 삶이란 존재하지 않듯이 이슈와 버그가 없는 소프트웨어 개발자의 삶이란 없다. 이슈가 없는 개발자가 되는 방법은 아무 일도 하지 않는 것이다. 과장해서 말하자면, 이슈란 개발자인 당신이 살아있다는 증거다. 소프트웨어를 만들고 있는 과정 속에 있다는 얘기다.
첫째, 소프트웨어 개발은 통상 수개월 이상의 시간이 걸리는 장기적인 작업이다. 이 시간동안 소프트웨어 개발자는 자신이 개발중인 소프트웨어가 보이는 어떤 징후도 간과해서는 안된다. 개발기간중에 어떤 형태로든지 한번 이상 나온 문제는 언젠가는 꼭 다시 나오게 된다. 그냥 넘어가는 것은 요행을 바라는 어리석음이다. 건강을 위협하는 많은 질병들이 예방가능하듯이, 수많은 이슈와 버그 역시 예방 가능하다. 소프트웨어 개발자가 이슈를 차단할 수 있는 유일한 시간은 개발기간뿐이다. 어려운 이슈들은 항상 개발 막바지에 나온다. 개발 막바지 몸도 지치고 마음도 지친다. 쏟아지는 이슈들에 대처하는 것은 여간 어려운 일이 아니다. 가장 무서운 이슈들은 제품 출시 후에 나오는 것들이다. 개발 부서만의 문제가 아닌 전사의 문제가 되어 버린다. 개발 막바지와 출시 이후에 이슈를 해결하는 것은 개발할 때보다 더 많은 노력과 고통을 필요로 한다. 잘못 채운 첫 단추가 많은 부분을 꼬이게 만든 다. 혹시나 이슈가 현재의 소프트웨어 설계로는 개선할 수 없는 것이라면 최악이다. 소프트웨어 개발의 가장 이른 단계에서 최대한 이슈를 해결해야 한다고 소프트웨어 공학에서 그토록 강조하는 데는 다 이유가 있다.
두번째, 그럼에도 불구하고 우리는 이슈를 막을 수 없다. 이슈 자체는 스트레스가 아닌 현상에 불과하다. 이슈를 일일이 스트레스로 받아들이면 제명에 살 수 없다. 스트레스에 무감각해지라는 얘기가 아니다. 인간의 면역체계는 스트레스에 대한 내성을 만들어내지 못한다는 뇌과학자들의 연구가 있다. 이슈를 스트레스와 동일시해서는 안된다. 이슈는 항상 발생한다. 막을수 없다. 내가 만든 버그이건, 남들이 만든 버그이건, 버그가 아닌 타부서의 문제이든 간에 말이다. 우리가 결정할 수 있는 것은 오직 태도뿐이다. 사실 개발자를 키우는 것은 팔할이 이슈와 버그다. 나를 죽이지 못하는 것이 나를 더 강하게 만든다는 니체의 말처럼, 개발자의 실력은 그동안 겪은 이슈의 난이도와 양에 비례한다. 나를 힘들게 했던 이슈 때문에, 훗날 다른 이슈의 발생 가능성은 현저히 낮아진다. 또한 새로운 이슈를 더 쉽게 해결할 수 있는 내공이 쌓이게 된다. 이슈라는 것은 언제나 함께 할수밖에 없는 것임을 인정하자. 이슈를 회피하려 하지 말고, 정면으로 부딪히자. 내가 만든 버그가 아니더라도 자신이 담당한 부분이라면 자신의 책임이라고 생각하는 것이 좋은 자세다. 주도적으로 이슈를 바라볼 수 있어야 해결도 적극적으로 하게 된다. 그렇지 않으면 이슈에 대한 피해자로 계속 질질 끌려가게 된다.
세번째, 진인사 대천명(盡人事 待天命)을 마음에 새기자. 최선을 다했으면, 결과에 일희일비하지 말자는 것이다. 여기서 하나 더, 최선이라는 단어 대신 아닌 진심이라는 단어를 품고 일하자. 그래야 결과에 의해 자신의 노력과 과정의 가치가 폄하되는 것을 막을 수 있다. 오늘 있었던 프리 테스트 막바지 2시간동안 만약 내가 문제를 해결하지 못했다면, 그게 자책해야 할 일인가? 나는 분명히 최선을 다했다. 하지만 결과가 좋지 않았더라면 나의 노력은 최선이 아닌 것이 되어버렸을 것이다. 하지만 진심을 다했다고 생각한다면, 결과가 좋지 않더라도 받아들일수 있다. 모든 이슈는 내가 해결할 수 있는 것들과 내가 해결할 수 없는 것들, 단 두가지로 나뉜다. 이슈를 대하는 첫 단계에서 필요한 것은 이 둘을 구분하는 능력이다. 경험과 기술 모두 필요하다. 거기에 내가 해결할 수 있는 일에 대해 진심을 다하는 태도, 그리고 결과를 겸허히 수용하는 마음까지 있다면 당신은 이슈에 대처하는 필살의 3종 세트를 모두 갖추고 있는 것이다.