336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.



객체지향의 사실과 오해

저자
조영호 지음
출판사
위키북스 | 2015-06-17 출간
카테고리
컴퓨터/IT
책소개
『객체지향의 사실과 오해』는 객체지향이란 무엇인가라는 원론적면서...
가격비교



본의 아니게 난 회사에서 당구를 꽤 잘 치는 사람으로 소문 나 있다. 아마 예전 회사에서 당구 동호회를 설립했던 이력 때문일 것이다. 지금은 아니지만 한때 난 지인들 사이에서 당구를 꽤 잘 치던 사람이긴 했었다. 그때를 돌아오면 분명 잘 치긴 했지만 한 가지 문제가 있었다. 그것은 기복이 심했다는 점이다. 어떤 날은 정말 잘 쳤지만, 어떤 날은 형편없었다.


몇 년이 지나고 우연히 한 친구를 만났다. 그 친구는 내게 당구대에 있는 점을 기준으로 계산해서 치는 당구가 있다는 것을 알려주었다. 혹시나 하는 마음으로 그 친구가 알려준 대로 당구를 쳐보았다. 정말로 계산한 대로 공이 움직이는 것 아닌가? 물론 사람이 치는지라 100% 정확하지는 않았다. 그렇지만 내가 감으로 치는 것보다는 훨씬 정확했다. 나는 이런 방식으로 훈련한다면 기복이 훨씬 줄어들 것이라 생각했다.


몇 해 전 켄트벡의 구현패턴이 나왔던 때이다. 너무 뻔한 내용을 담았다는 비판이 있었지만, 난 구현패턴을 읽으며 얻은 것이 있었다. 그중 내 안에 거미줄처럼 얽혀있던 지식이 정리되어 구조가 정립되었다는 점과, 내가 어렴풋이 알고는 있었지만 항상 표현하기 어려웠던 미묘한 것들을 구체적인 어휘를 이용하여 표현할 수 있게 되었다는 것이다.


또한 구현패턴에서 언급한 대로 자문해본 적이 있다. "이 메서드는 왜 이 클래스에 있어야 하는지?", "이 필드는 왜 이 위치에 있어야 하는 것이지?" 부끄럽게도 난 내가 작성한 코드에 대해 100% 설명할 수 없었다. 나도 모르게 무의식적으로 감으로 작성한 코드가 많았던 것이다. 설명할 수 없는 것들은 근거가 없었고, 나는 개발을 하며 내가 했던 수 많은 판단이 얼마나 취약할 수 있는지에 대해 겸허히 인정할 수밖에 없었다.


최근 "객체지향의 사실과 오해"라는 책을 읽었다. 이 책은 제목 그대로 객체지향에 대해 다룬 책이다. 난 이 책을 읽으며 예전 구현패턴을 읽을 때와 비슷한 느낌을 받았다. 동료들과 해왔던 디자인 관련 토론이 기억났다. 난 "책임", "역할", "일반화 된 인터페이스" 등 여러 어휘를 사용했었다. 지금 와서 생각해보니 그 어휘들을 내가 정확히 정의하고 있었는지, 듣는 친구들은 나와 같은 생각을 했었는지 잘 모르겠다.


다행히 이 책을 읽으며 객체지향이라는 주제 혹은 소프트웨어 디자인에 대한 구조가 내 머리속에 어느 정도 정립되는 느낌을 받았다. 구현패턴을 읽을 때와 비슷한 느낌이다. 또한 앞으로 좀 더 명확히 정의해 사용할 수 있는 어휘를 갖게 되었다. "타입", "추상화" 등이다. 앞으로 생각을 할 때 이 책을 통해 배운 어휘를 좀더 체계적으로 활용할 수 있을 것 같다. 마치 당구를 감이 아닌 계산을 통해서 치는 것처럼 말이다.


솔직히 이 책은 재밌는 책은 아니다. 음식에 비유하자면 딱딱한 오징어 다리와 비슷한 느낌이다. 딱딱한 오징어 다리는 처음 씹을 때 매우 곤혹스럽다. 이가 아프기도 하고, 턱이 피곤한 느낌이 들기도 하다. 그렇지만 인내하며 씹다 보면 오징어가 가진 진한 맛과 향이 입안으로 강하게 흘러든다. 이 순간 처음 느꼈던 부담이 보상되는 느낌이 들고, 잠시 후 나도 모르게 다른 하나를 또 입에 넣고 씹게 된다.


주위에서 긴박한 사업적 요구사항에 맞추고 맞추다 개발 품질이 몹시 훼손되어 어려운 상황에 처하는 것을 종종 본다. 사업 중심 조직에서는 그러기 쉬운 것 같고, 어떤 곳은 그게 개발자의 미덕으로 취급되는 것 같다. 혹시라도 이런 환경에 있는 분들이 계시다면 이 책을 권하고 싶다. 이 책을 공부한다면 긴박한 사업적 요구사항을 맞추면서 적절한 개발 품질 또한 유지하는 데 도움이 되리라 생각하기 때문이다.


저자이신 조영호형은 대화를 자주 나누는 가까운 개발자 선배시다. 형 또래의 분들이 관리자가 되거나, 개발자로서의 경쟁력을 점차 잃어가는 것을 본다. 그러나 형은 처음 만났던 2006년부터 지금까지 한결같이 개발에 대해 진지하게 탐구하는 학자와 같은 모습을 유지하고 계신다. 또한 형에 대해 모른채 이 책만을 보면 이론만을 추구하는 분처럼 보일지 모르겠으나, 이론을 실제로 바꾸기 위해 현장에서 고군분투하는 분이기도 하다.


좋은 책을 써 주셔 감사하고, 오래전부터 원고 리뷰를 부탁받았으나 심각한 게으름 때문에 제대로 리뷰를 못해 죄송한 마음이다. 그럼에도 책이 나오자마자 웃는 얼굴로 선물해주신 형께 감사한 마음이다. 이번 책은 1편이고 본격적으로 같은 주제를 다루는 다음 책을 준비 중이신 것으로 알고 있는데, 괴롭고 험한 길로 보이지만 또 한번 힘을 내셔셔 좋은 책으로 열매 맺으면 좋겠다.


WRITTEN BY
차민창
르세상스 엔지니어가 사회를 이끌어나가는 상상을 하며!

,
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.










WRITTEN BY
차민창
르세상스 엔지니어가 사회를 이끌어나가는 상상을 하며!

,
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

처음 르네상스 엔지니어라는 말을 들었던 것은 2010년 정도로 기억해. 당시 글쓰기 교육을 받게 되었는데, 교재 내용 중 르네상스 엔지니어라는 단어가 나오는거야. 왠지 모르게 예전부터 '르네상스'라는 단어를 들으면 뭔가 멋진 느낌이 들었어. 레오나르도 다빈치 같은 천재가 연상되어서였을까? 글쓰기 교육에서 르네상스 엔지니어를 언급한 것은 글쓰기의 중요성을 강조하기 위함이었어. 엔지니어 혹은 개발자라고 해서 단지 코딩'만' 잘하려고 하면 안 된다는 주장이었어. 난 예전부터 글쓰기를 좋아했었고 글 쓰기에 대한 가치를 높게 평가했기 때문에 충분히 공감했어.


그렇게 시간이 흘러가며 르네상스 엔지니어에 대해서는 한동안 잊고 살았던 것 같아. 물론 큰 인상을 받았지만 너도 알듯이 난 워낙 관심사가 자주 바뀌어서 말이야. 오히려 새로운 화두가 마음을 사로잡았어. 최근 한 3~4년 사이에 나는 '개발자' 그 자체에 대한 고민을 시작했어. 발단은 시간이 지날수록 개발이 더 재미없어지는거야. 위기감을 느꼈어. 혹시 이러다가 개발을 못하게 되는게 아닐까라는 생각도 들었고. 하루에 8시간 이상을 회사에서 보내는데 재미가 없으면 얼마나 고통스러운 일이겠어. 물론 너는 일은 단지 일이라고 생각하니 공감 못할수도 있겠지만 말이야.


왜 재미가 없어지는지 생각해봤어. 생각나는 것이 여럿 있었지만, 뾰죽한 해결방법은 찾지 못했어. 그러던 어느날이었어. 내가 일하는 환경에서 내가 뭔가 주도적으로 일을 할 기회가 있었어. 누가 시킨 것도 아니었는데 내가 필요하다고 판단해서 진행을 한 일이있어. 일의 결과를 바로 볼 수 있는 상황이었어. 그런데 이 때 뭔가 새로운 느낌을 받았어. 내가 한 일에 대한 결과를 보려고 준비하는데 너무 즐겁고 마음이 조금은 떨리는거야. 이런 느낌은 참 색다른 느낌이라 그날 페이스북에 이 느낌을 정리하며 이유를 곰곰히 생각해봤어.


당시 내가 내린 결론은 단지 남이 시킨 일을 하지않고 내가 계획한 일을 스스로 실행했기 때문이라는 것이었어. 그래서 만약 내가 사장이라면 좀더 일을 재밌게 할 수 있겠다는 생각이 들었어. 하지만 너도 알겠지만 사장이 되는 것은 그렇게 쉬운 문제가 아니잖아. 아무튼 이런 것을 느끼고 난 후부터 사장이 되지 않고도 어떻게 하면 일을 재밌게 할 수 있을지에 대해 고민해보기 시작했어. 결국 문제는 내가 일을 주도적으로 할 수 있는 환경을 만드는 것이었어. 회사 일이라도 마치 내 일처럼 하면 즐거울 것 같아서 말이야. 현실적으로 이런 환경을 만들어보고 싶었던거야.


하지만 쉽지 않더라고. 점점 지쳐갔고 결국 회사를 관두게 된거야. 회사 그만둔 것을 전화로만 얘기해서 자세히 얘기할 기회가 없었는데, 결국은 이런 과정을 겪으며 회사를 그만둔거야. 그냥 뭐랄까, 누군가가 나한테 일을 막 시켜. 그런데 난 왜 해야하는지 공감도 잘 안 되고 왜 해야 하는지도 잘 모르겠는거야. 재미도 없고 싫지. 물론 회사를 그만두어도 딱히 대안이 있는 것은 아니었어. 일단은 그만두고 생각을 해보려고 했어. 너에게 이런 고민에 대해 편지로 전할 욕심도 있었고 말이야. 아, 그러고보니 르네상스 엔지니어 얘기를 하다가 이 얘기가 나왔었구나.


응, 결국 난 일에 재미에 대한 고민에 대한 돌파구로써 르네상스 엔지니어를 생각해보고 있어. 처음 이 단어를 만드신 분이 생각한 의미가 있어. 그 의미에 대해 설명한 글을 보면 결국 맥락은 아까 얘기했듯이 개발자가 그냥 코딩만 하면 안 된다는거야. 예를 들어 사회적인 책임감도 있어야 하고, 다른 분야에 사람들과 협력을 잘할 수 있어야 하고, 도덕적이어야 하고 이런 것이야. 결국 개발자는 더 넓은 영역에서 활동할 수 있고 그래야 마땅하다는거야.  여기에 '재미'라는 단어가 직접적으로 등장하지 않았지만 나는 사실 이런 방향이 재미랑도 큰 연관이 있다고 봐.


왜냐하면 앞서 내가 스스로 계획한 일을 했을 때 즐거웠다고 했잖아? 그렇다면 내가 좀더 넓은 영역. 그러니깐 더 많은 책임을 가지고, 내가 더 많은 것을 계획하거나 관여하면 어떨까? 아마 일이 더 즐거워지지 않을까? 예를 들어 내가 어떤 일을 하고 있어. 그런데 그 일을 그냥 누가 시켜서 하는 때랑, 내가 그 일을 해야할지 결정을 같이해서 하는거랑 차이가 많이 있다는거야. 당연히 내가 결정에 관여하거나 혹은 직접 결정했을 때 훨씬 일이 재밌다는 것이고.  그래서 결국 르네상스 엔지니어를 추구하다 보면 재미도 더 많이 있을 것 같은거야!


그런데 냉정하게 따져보면 지금에 나로써는 그렇게 일하는 게 좀 말이 안 되기도 해. 왜냐하면 뭔가 결정하거나 관여를 하려면 그에 걸맞는 능력이 필요하잖아? 예를 들어 나한테 큰 사업의 방향을 결정하자고 하면 내가 무엇을 할 수 있을까? 자신이 없어. 아마 나는 십중팔구 큰 도움이 안될거야. 그래서 나는 개발 뿐 아니라 더 많은 실력을 가져야 한다고 생각해. 사업적인 흐름을 보는 안목이든 다른 직군과의 협력할 수 있는 능력이든 말이야. 아! 무엇보다 나는 많은 사람들이 사용하는 인터넷 서비스를 만들잖아? 그러니깐 사람에 대한 깊은 이해도 많이 필요할 것 같고.


사실 예전에 여기까지 생각했을 때 뭔가 두근두근 했어. 그런데 현실적으로 그럼 어떻게 해야하나 고민해보니깐 이게 쉽지는 않더라고. 지금 내가 하는 개발만 해도 과도기적인 산업영역이라 많이 바뀌거든. 매일 매일 새로운 기술이 쏟아져 나오고. 사실 이거 따라잡는 것도 쉽지는 않아. 게다가 내가 개발을 엄청나게 잘해서 이제 개발을 그만 공부해도 되는 상황도 아니거든. 결국 고민 끝에 현실적으로 취하고 있는 것은 열린 마음 전략이랄까? 이런거야. 그러니깐 항상 새로운 분야의 지식을 배울 수 있는 기회에 대해 열린 마음으로 적극적으로 참여해보는거야.


예전에 회식을 할 때 개발 얘기가 나오면 나도 참여를 해서 열심히 듣고 때로 열심히 말하곤 했어. 내 관심 주제였으니깐. 그런데 반대로 관심이 없는 정치 얘기 등이 나오면 그냥 대수롭지 않게 듣거나, 혼자 공상을 하곤 했어. 되돌아보면 그 때 내가 좀더 관심을 가졌더라면 그런 대화를 통해서도 많은 것을 배울 수 있지 않았을까 싶어. 작년정도부터 몇 가지 실험을 해봤어. 예를 들어 기획자랑 얘기할 때 그들이 업무영역에서 고민하는 것에 대해서 관심을 가지고 들어보는거야. 그랬더니 대화도 훨씬 즐거웠고 배울 것도 많다고 느꼈어. 그러면서 안목도 넓어지는 것 같았고.


한편 무엇이든 다양하게 읽어보고 있어. 예전에는 "배운다"라는 마음으로 책을 읽을 때면 그 책은 항상 개발에 관련 된 책이었어. 그런데 요즘에는 "배운다"라는 마음으로 역사, 고전 소설, 과학, 정치 뉴스 등 예전보다는 좀더 넓게 읽어보고 있어. 물론 내가 역사를 본다고 얼마나 알겠고, 과학을 본다고 해서 얼마나 이해하겠어? 그럼에도 내가 기본적으로 당연히 잘해야 하는 개발과 더불어 이런 지식 혹은 이해를 조금씩 갖춰나갈 때, 아까 기대한 대로 내가 하는 일에 대해 결정할 수 있는 소양이  점점 늘어날것이라는 기대가 있어. 


최근 너네 회사가 어렵잖아? 그래서 고생 많이 하고 있는 데 이런 얘기를 하니 좀 미안하기도 해. 뭔가 배부른 얘기 한다고 생각할까봐 걱정되는거야.  실제로 그렇기도 한데, 그래도 이해해주기를 바라는 마음으로 써. 각자의 상황에서 각자 다른 고민이 있는 것이라 너그러히 생각해주면 어떨까 싶고. 그래도 이런 얘기를 할 수 있는 네가 있어서 얼마나 좋은지 몰라. 나중에 이런 고민을 잘 해결하고 네게 다시 즐거운 내용으로 편지 쓸 수 있는 기회가 있었으면 좋겠다. 요즘 비가 많이 오는 데 건강관리 잘하고, 요즘 준비하며 시간 많이 쏟고 있다는 실사준비도 잘 되길 바랄게.

2014/06/11 민창


WRITTEN BY
차민창
르세상스 엔지니어가 사회를 이끌어나가는 상상을 하며!

,
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

동료들과 대화를 하다보면 오버엔지니어링이라는 단어가 종종 나온다. 주로 안 좋은 문맥에서 이 단어를 사용하게 된다. 전임자가 어떤 코드부분을 오버엔지니어링 해놓아서 이해하기가 어려웠다고도 하고, 더 나아가서는 시스템 자체가 오버엔지니어링 되어 있어 유지보수에 큰 어려움을 겪는다고 얘기하기도 한다. 오버엔지니어링이 미치는 부정적인 영향아 많아 보인다. 그런데, 여러 관점에서 생각해보니 오버엔지니어링은 단순히 부정적으로 보기에는 아깝고, 여러모로 생각할만한 꺼리가 있다고 생각한다. 그래서 이번 글에서 오버엔지니어링에 대한 생각을 정리해보려고 한다. 


1. 오버엔지니어링? 엔지니어링?


오버엔지니어링에 대한 여러 얘기를 나누기 전에 오버엔지니어링에 대한 간단한 정리가 필요할 것 같다. 위키피디아 등의 정의와 더불어 개발자들이 보통 인식하는 오버엔지니어링은 다음과 같다.


현재 필요한 것 보다 더 과하게 제품을 디자인 하는 것이다. 즉, 제품을 더 견고하게 만들거나, 더 복잡하게 만드는 것이다. 핵심개념만을 담아 최대한 단순하게 만들자는 최소주의와는 대비되는 개념이다. 예를 들어 실제로는 만 명의 사용자가 쓰는 시스템이 내부적으로는 1억의 사용자에 맞춰 설계 개발되어 있고, 이로인해 100만의 사용자 규모에는 필요없는 구성요소들이 들어가 있을 때 오버엔지니어링 되어 있다고 얘기한다. 보통 오버엔지니어링 되어 있으면 이후 제품을 운영 할 때 어려움을 줄 때도 많다. 단순한 구조에서는 간단히 할 수 있는 일을 더 복잡하게 해야 하는 등이 일이 발생하기 때문이다.


추가로 앞으로의 글에서 자주 사용할 '엔지니어링'이라는 표현에 대해서도 정리를 해보고 싶다. 나는 기능구현을 위해 꼭 필요한 것은 아니지만 안정성이나 확장성을 위해 부가적으로 하는 일을 '엔지니어링 한다'고 표현한다. 예를 들어 안정성을 위해 입력값을 검사하는 코드를 넣는 것이나 향후 확장성을 위해 디자인 패턴을 적용하는 것 등이 있다. 이러한 활동이 과다해지는 것을 사람들이 대게 '오버엔지니어링 한다'라고 표현하는 것을 볼 때 뜻이 적절하다고 본다. 하지만, 다른 사람이 동일하게 표현하는 것을 한번도 못 보아서 확신은 없다. 


2. 오버엔지니어링이 시작되는 이유


오버엔지니어링의 정의만 보면 이상할 수도 있다. 왜 필요보다 과하게 만드는 걸까? 내 생각에 개발자가 오버엔지니어링을 하게 되는 계기는 이렇다. 보통 초보 개발자 시절에는 오버엔지니어링을 하지 않는다. 아니 못한다. 아무래도 개발 실력이 부족할 때는 다른 것에 신경 쓸 여력이 없기 때문이다. 따라서 일단은 단순히 잘 동작하는 제품을 만드는 데 집중하고 집중한다. 얼마 후 본인이 만든 잘 동작하는 제품을 릴리즈한다. 릴리즈 후 정신없이 고객문의가 들어온다. 다양한 고객문의를 보며 안정성, 예외처리 등 고려하지 못한 부분이 많다는 것을 깨닫는다. 이런 문제를 해결해가며 잘 동작하는 기능 말고도 중요한 게 있다는 것을 깨닫는다.


다음 제품부터는 적절히 엔지니어링을 하기 시작한다. 예전과는 달리 입력 값이 잘못 들어왔을 때를 대비한 처리를 해놓기도 하고, 소스 구조도 단순히 동작하는 것을 넘어 나중에 고치기 쉽게 만들기도 한다. 이런 과정에서 초보 시절 단순히 기능구현만을 신경썼을 때 보다 소스량이 다소 늘어나게 된다. 보통 이정도 수준까지는 오버엔지니어링이라고 부르지 않는다. 오히려 코드 리뷰 등을 할 때 이런 부분에 신경 쓴 것에 긍정적인 평가를 받을 때가 잦다. 이렇게 긍정적인 평가를 받다보면 아무래도 이런 부분을 지속적으로 신경쓰게 된다. 더 고려해야 할 것이 없는지 비판적인 시각으로 제품을 살펴본다. 


경험이 많아짐에 따라 단순히 입력 값이 잘못 들어왔을 때를 대비해 몇줄의 소스 코드를 넣던 수준에서, 시스템 구조 수준에 대비를 하기에 이른다. 예로 왠지 미래에 생길 것 같은 다양한 보안 요구사항을 고려하여 복잡하지만 유연한 보안 관련 프레임웍을 미리 도입하기도 하고, 당장은 불편하지만 차후 확장성이 좋은 방향으로 저장소 구조를 설계하기도 한다. 이렇게 하는 이유는 잘못된 입력 값을 처리하던 이유와 같다. 미래에 있을법한 일에 미리 대비하여 제품의 안정성 등을 확보하자는 것이다. 이정도 수준에 이르면 종종 주변 동료에게 오버엔지니어링이 아니냐는 도전을 받기도 한다.


3. 엔지니어링은 성공해야 하는 투자


그렇자면 오버엔지니어링이 나쁜 것인가? 예로 저장소 구조에 대한 가상사례를 가지고 생각해본다. 단순히 개발해도 약 500만명의 사용자까지는 문제 없는데, 1억명 까지 사용자가 늘어나는 상황을 고려해 구조를 설계 및 구현해놓았다. 제품을 릴리즈 하고 서비스를 한다. 그런데, 초기 사용자는 10만을 넘지 않는다. 1년이 지난다. 서비스 사용자는 여전히 100만 정도이다. 당분간 더 늘 것 같지도 않다. 이 때 저장소 구조에 대해 이미 해둔 엔지니어링을 어떻게 평가해야 할까? 나는 부정적으로 본다. 왜냐하면, 1억명의 사용자를 고려하여 설계 및 구현하는 비용을 사용했는데 실제로는 사용자가 1억명이 되지 않았기 때문이다. 이렇게 될꺼라면 굳이 엔지니어링을 하지 않아도 됐다.


정반대의 상황도 생각해본다. 제품을 릴리즈 했다. 그런데, 사용자가 폭팔적으로 늘어난다. 릴리즈 한 달 만에 사용자가 1,000만명이 넘었다. 다행히 미리 해둔 엔지니어링 덕분에 사용자의 제품 사용에 큰 문제가 없다. 만약 미리 엔지니어링을 해두지 않았다면 어땠을까? 개발자는 급하게 구조를 변경해야했을 것이고, 작업기간 동안 사용자는 접속불안이나, 응답속도저하 등의 문제를 겪었을테다. 게다가 생각해보니 초기에 2주 정도를 투자해서 준비했기 망정이지, 이미 릴리즈해서 서비스 중인 제품으로 엔지니어링 했더라면 훨씬 많은 시간이 필요했음이 분명하다. 어쩌면 4주 이상이 걸렸을 지도 모르겠다. 작업 과정에서 장애도 많이 났을테고 말이다.


이런 맥락에서 볼 때 엔지니어링은 투자라고 생각한다. 마치 유망주에 투자를 하듯이 미래에 생길 것 같은 일에 투자를 하는 것이다. 위 가상의 예에서 볼 수 있듯이 실패하면 엔지니어링에 대한 투자는 아무것도 아니게 된다. 반면 성공하면 매우 긍정적인 결과가 있다. 문제는 경험 상 이런 투자가 성공으로 이어지는 때가 적다는 것이다. 정확히 측정 해보지 않았지만, 내가 봐온 많은 투자가 실패했다. 게다가 흥미로운 점은 엔지니어링의 규모가 크면 클수록 실패할 확률이 더 높다는 것이다. 특히 저장소 확장성 설계 같은 규모가 큰 엔지니어링은 이후에 보면 사용자가 적어 필요없을 때가 잦았고, 개발 뿐 아니라 운영에도 부담을 주곤 했다.


4. 적정엔지니어링


이런 이유로 가급적 성공할만한 투자만 하자는 것은 이견이 없을 것 같다. 그리고 이를 잘 판단할 수 있는 것은 개발자이다. 그런데, 현실에서 개발자는 의외로 성공하기 어려운 투자를 자주 감행한다. 이는 여러 원인이 있다고 본다. 첫째는 책임 문제이다. 예로 사용자가 폭팔적으로 증가했을 때 기술적 준비가 안 되어 있다면 개발자는 타격을 받는다. 둘째는 개발자의 욕심이다. 개발자는 대게 기술에 대한 욕심이 있는데, 엔지니어링은 이런 욕심을 충족시키는 좋은 방법 중 하나다. 셋째는 개발자가 엔지니어링을 당연하게 생각하기 때문이다. 어떤 개발자는 엔지니어링은 투자이고 선택할 수 있는 영역이라고 판단한다. 그런데, 어떤 개발자는 엔지니어링은 무조건 해야 하는 것으로 인식한다.


위 세 가지 중 개발자 책임 문제는 까다로운 문제 같다. 개발자들끼리의 회의에서 엔지니어링을 가지고 논쟁이 벌어지다 가끔 나오는 말이 있다. "그럼 나중에 장애나면 누가 책임질껀데?" 이런 말이 나오면, 그냥 모두 맘 편하게 오버엔지니어링을 하기도 한다. 합리적으로 판단해 엔지니어링을 하지 않았는데 이후 사용자가 폭팔적으로 증가해 제품의 서비스가 멈추기라도 할 때 개발자에게 책임을 묻는 사태가 일어날까 걱정하는 것이다. 또한, 이럴 때 기술적 이해가 부족한 외부부서는 개발자를 무능하게 볼 수 있고 이는 힘을 빠지게 한다. 나중에 급히 준비하는 과정도 개발자에겐 너무 힘들다. 당장 서비스에 문제가 생기면, 퇴근하기도 힘들어지기 때문이다.


두 번째 개발자의 욕심 또한 생각해볼만한 문제다. 경험상 실력이 좋은 개발자일수록 엔지니어링에 욕심이 있는 것 같다. 기술적 지식이 많다보니 제품을 설계할 때 많은 고민을 한다. 고민을 통해 인지하게 된 제품의 기술적 약점을 보완하고 싶은 마음이 자연스레 생긴다. 약점이 뻔히 보이는 데 아무것도 안 하고 넘어가는 것은 개발자에게는 힘든 문제일수도 있다. 한편 신기술을 극단적으로 선호하는 개발자도 있다. 이런 개발자는 나름의 근거를 가지고 새로나온 프레임웍 등의 신기술을 도입한다. 하지만, 가만히 살펴보면 도입근거가 미약할 때가 많고, 외부 시선으로 보기에는 오버엔지니어링으로 판단하게 될 때도 있다.


그래서 나는 개발자가 현재 비즈니스 상황에 따라 적절한 엔지니어링 수준을 결정하는 능력이 중요하다고 생각한다. 이를 위해서는 세 가지 정도 꼭 필요한 능력이 있다고 생각하는데 첫째가 용기다. 용기가 필요한 이유는 엔지니어링 결정으로 인해 최악의 경우 다소 억울한 비난을 받을수도 있기 때문이다. 이런 부분을 감안하고도 옳은 판단을 내릴 수 있어야 한다고 본다. 둘째는 비지니스에 대한 이해이다. 예로 확장성에 대한 엔지니어링 결정을 하려면, 어떤 데이터가 많이 증가할지 예측이 가능해야 한다. 이런 부분은 기술력보다는 비즈니스 이해가 판단에 더 많은 영향을 미친다고 생각한다. 마지막으로 당연히 기술력이 필요하다.


그런데, 초반 제품을 개발할 때 위에서 얘기한 적정엔지니어링 관점으로 준비를 했다고 가정하면, 이후 제품 운영이 더 어려울 수도 있다. 왜냐하면, 경험상 미리 준비하는 것보다 운영 중에 준비하는 것이 훨씬 어렵기 때문이다. 따라서, 적정엔지니어링을 적용해 제품을 개발했다면 비즈니스 상황 및 시스템 모니터링을 통해 필요한 엔지니어링을 지속적으로 확보해가는 능력이 필요하다고 본다. 또한, 이 때도 적정엔지니어링을 유지하는 것이 좋다고 본다. 운영 중 확장성 문제가 생겼을 때 한번에 투자하기 보다는, 조금씩 투자하며 현재 상황에 맞게 전진할 수 있다고 보기 때문이다. 아래는 이런 노력을 하며 실제 있었던 경험담이다. 다만, 많은 것이 생략 된 대략적인 내용이다.


최초 상황


- MySQL Master 1대 /Slave 1대

- Master는 Insert/Update/Delete 쓰기 요청을 받음, Slave는 Select 요청을 받음

- Master의 데이터는 Slave로 실시간 복제 됨

- 릴리즈 한지 약 2년 정도 된 제품


첫 번째 엔지니어링


- Slave에 복잡한 쿼리가 많아 Slow Query가 늘어나며 부담이 생김

- 추가 Slave를 투입하여 Slave를 2대로 만듬

- Round Robin 방식으로 Slave#1, Slave#2가 번갈아 가며 요청을 처리하게 함

- 결과로 Slow Query가 줄고 부담이 경감 됨

- 위 작업에 2일 정도 소모


두 번째 엔지니어링(준비했었으나 실제 제휴가 진행되지 않아 계획만 세움)


- 제휴로 인해 약 10배 사용자가 예상 됨, 곧바로 샤딩을 할수도 있지만 비용을 고려하여 다시 한번 조금만 엔지니어링 하기로 함

- Master는 N개로 늘릴 수 없기 때문에 Scale-Up(하드웨어 업그레이드) 방식으로 확장

- Slave는 필요한 만큼 확장하고 마찬가지로 Round Robin 방식으로 서비스, 단 복제지연을 고려해야 함

- 이후 모니터링 중 복제지연이 생기면 필요한 튜닝을 진행

- 만약 사용자가 10배 그 이상이 될 소지가 보이면 비즈니스/기술 부서에서 최소한 1달 전에 인지하여 준비


설명


위 경험담을 보면 보통 사용하는 샤딩이 안 되어 있는 상황이다. 아마 초기에 이로 인한 여러 이득이 있었을 것으로 판단한다. 그 후 성능 문제가 발생했지만, 아무래도 큰 작업인 샤딩을 진행하지는 않는다. 다만, 가까운 미래에 필요할 정도로만 엔지니어링을 한다. 이후 10배 사용자가 필요한 상황이 되었지만, 이때도 어떻게든 구조를 많이 변경하지 않고 엔지니어링을 해본다. 10배 이상이 되면 구조적인 한계가 있기 때문에 샤딩을 진행한다. 다만, 샤딩은 시간이 필요하기 때문에 모니터링 및 판단을 잘 해서 최소한 1달 전에 알 수 있도록 준비한다.


5. 적정엔지니어링이 개발자에게 미치는 영향

적정엔지니어링은 비즈니스 관점에서 긍정적으로 볼 수 있을 것 같다. 미리 기술에 투자하지 않고 필요할 때마다 조금씩 점진적으로 해나가기 때문에 빠르게 제품을 릴리즈 하는데 도움이 되기 때문이다. 특히 스타트업처럼 시간적 여유가 부족하다면 더욱 빛을 발할 것 같다. 게다가, 데이터베이스 샤딩을 하지 않는 사례를 보면 제품 개발 시점 뿐 아니라 운영 시점에 긍정적 영향을 주기도 한다. 그런데, 개발자에게는 어떨까? 부정적인 점이 있다고 본다. 적정엔지니어링의 필요성을 느낀 후 반년 넘게 실천을 해보았다. 처음에는 내가 성숙한 개발자가 된 것 같아 기분이 좋았다. 그런데, 시간이 갈수록 뭔가 문제가 있다는 생각이 들었다.


자연스레 예전 모습을 기억해보았다. 예전에는 프로젝트 중 10~20%정도는 기술적으로 도전하곤 했었다. 도전이라는 것은 어떤 면에서는 적정엔지니어링을 하지 않았다는 뜻이다. 투자 관점의 합리적인 엔지니어링보다는 단순히 기술적 도전을 위한 엔지니어링을 시도했다. 이런 도전을 통해 재미를 느꼈고 새로운 것을 배웠다. 그런데, 적정엔지니어링에 몰입하고 난 후에는 항상 비즈니스를 고려한 최적의 결정만을 하려 노력했다. 자연스레 예전 습관이었던 10~20% 기술적 도전은 사라졌다. 이로인해 단기간에 내가 할 수 있는 최선의 결과를 냈는지는 모르겠지만, 장기적으로는 재미를 잃어가고 한편으로 지쳐갔다.


나는 적정엔지니어링은 성숙한 개발자라면 꼭 해야한다고 생각해 실천했었고, 지금도 이 생각은 변함없다. 그럼에도 한편에서 개발자는 항상 도전하는 게 반드시 필요하다고 생각한다. 특히 개인적 시간에 따로 도전하는 것도 좋지만, 업무 영역에서 많이 도전해야 한다고 생각한다. 경험상 업무적 도전이 훨씬 현실적이고 배우는 게 많기 때문이다. 따라서 적정엔지니어링과 오버엔지니어링 모두 조화롭게 추구하는 게 좋다고 생각한다. 적정엔지니어링을 너무 심하게 하는 것도, 오버엔지니어링을 너무 심하게 하는 것도 금물이라 본다. 프로젝트 위험도나 본인의 상황에 따라 틀리겠지만 적절한 비율은 8:2 혹은 9:1 정도가 아닐까 싶다. 물론 많은 편이 적정엔지니어링이다.[1]


6. 요약


사람들은 누군가 불필요한 엔지니어링을 한다고 판단할 때 오버엔지니어링이라 부르며 부정적으로 생각한다. 엔지니어링은 어떤 면에서 미래를 위한 투자로 볼 수 있다. 이런 투자가 과열될 때 오버엔지니어링이 되기 쉬운 것 같다. 그래서 개발자는 오버엔지니어링을 하기보다는 적절한 수준의 엔지니어링을 뜻하는 적정엔지니어링을 추구할 필요가 있다고 본다. 하지만, 적정엔지니어링만 추구하다보면 개발의 재미가 없어지고 발전도 더뎌지는 것 같다. 따라서 장기적인 관점에서 개발자는 어느정도의 오버엔지니어링을 통해 본인의 재미와 발전을 추구하는 것이 좋다고 생각한다.


[1] 단순히 프로젝트를 하는 것만으로도 많이 배우는 상황에 있는 개발자에게는 해당하지 않는 내용이다.


* 이어지는 글 '최소엔지니어링에 대한 생각' : http://wave.ivorypen.com/minslovey/5



WRITTEN BY
차민창
르세상스 엔지니어가 사회를 이끌어나가는 상상을 하며!

,
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

최근 메일, 전화, 소셜 네트워크를 통해 동료 개발자의 퇴사소식이 들린다. 마음이 무척 심란하고, 특히 몇년동안 사내에서 얼굴을 봐온 동료의 퇴사 소식에는 진한 아쉬움이 느껴진다. 이런 와중 누군가 내게 묻는다. 너는 힘들다고 하며 왜 여기에 계속 있냐고 말이다. 또 누군가는 내게 조언한다. 너는 타성에 젖어 한 자리에 머물러 있음으로 인해 개발자로써 경쟁력을 잃어가고 있다고 말이다. 그 외에도 많은 얘기가 있다. 그런데, 이런 얘기는 모두 개발자로써 하는 고민과 맞닿아 있다는 생각이 든다. 그래서 나는 최근 경험한 대화를 기초로 해 개발자로 자주 고민하고 되는 주제인 이직과 경쟁력에 대해 가지고 있는 생각을 정리해보고자 한다. 


1. 이직 혹은 이동에 대한 생각


내가 생각하는 이상적인 이직은 내가 하고 싶은 일이 있는데 현재의 환경에서는 할 수 없어 부득불 이직을 하는 것이다. 반대로 가급적 피하고자 하는 이직은 현재의 일이 너무 싫어서 이를 피해 새로운 환경으로 이직하는 것이다. 그동안의 개발자 경력 중 이직을 많이 해보진 않았지만 비슷한 점이 많은 팀 이동은 많이 해보았다. 지금 생각나는 것만 해도 약 3~4 차례 팀 이동이 있었다. 나는 그때마다 파랑새를 꿈꾸었다. '여기는 정말 아닌 것 같다. 봐봐. 저쪽팀은 사람이 너무 좋아보여. 정평이 난 인품 봐봐. 환경도 굉장히 자유롭네? 그래, 결심했다. 여기서 구질구질질하게 스트레스 받으며 내 인생을 허비하지 말고 가보자.


결과는 어땠을까? 안타깝게도 파랑새를 찾은 경험은 없다. 막상 이동을 해보면 외부에서 보이던 장점이 허구였던 적도 있고, 실제로 장점이 있더라도 그 장점을 덮을만한 단점이 더 많은 때도 있었다. 그럴때면 내 잘못된 선택에 괴로웠고, 다시 다음 파랑새를 찾아보곤 했다. 그런데 파랑새를 찾는 경험이 반복되며 이상한 느낌이 들기 시작했다. 침착하게 상황을 되돌아보며 자연스레 "혹시 내가 잘못된 게 아닐까?" 라는 생각을 하게 되었다. 왜냐하면 아무리 좋아보이는 곳을 가도 나는 만족하지 못했으며, 계속해서 어려움이 있었기 때문이다. 따라서 환경이 아닌 내게 초점을 맞춰 생각을 해보기 시작했다.


예전에는 어떤 어려움이 생기면 대게 외부 환경 중 하나를 비난했다. 예를 들어 내 자신과 관리자와의 업무 관계에서 어려움이 생기면 관리자를 비난했던 것이다. 대게 나는 관리자가 잘못했다고 믿었고 관리자가 변화하길 바랬다. 그러나, 이제는 관리자를 지금 그대로 인정해보았다. '관리자는 저럴만한 사정이 있다. 그런데, 난 어려움이 있다. 어려움을 해결하기 위해 '내가 할 수 있는 일'은 무엇인가?' 이런 생각의 전환 후 많은 것이 달라졌다. 문제가 있을 때 내가 할 수 있는 것을 고민하기 시작했던 것이다. 물론 쉬운 일은 아니었다. 하지만, 최소한 어려움이 생겼을 때 비난 하는 것보다는 훨씬 낫다는 생각이 들었다.


위와 같이 태도를 바꾼 후 내 자신이 긍정적 방향으로 바뀌고 있음을 강하게 느꼈다. 예전이라면 불평불만 할 상황에서 오히려 더욱 고민하며 전진할 수 있게 된 것이다. 점점 더 단련되고 성숙해지는 느낌을 받았다. 하지만, 안타깝게도 내 개인적 경험에서 이런 시도는 좋은 결실을 맺지 못했다. 열심히 해보았지만 언제부터인가 결과는 안 보이고 내 자신만 너무 지쳐갔다. 내 노력만으로는 한계가 느껴졌던 것이다. 이렇게 되자 다시 생각을 하게 되었다. 환경을 탓하며 파랑새를 꿈꾸던 시절이 극단이었다면, 환경을 제외하고 내 자신에만 초점을 맞추는 것도 또 다른 극단이라는 생각이 든다.


예로 박지성 선수가 있다. 이 선수는 환경에 대해 불만을 터트리지 않는다. 오히려 감독, 팀 상황 등을 그대로 인정하고 이런 환경에서 본인이 어떻게 해야할지 고민한다. 예로 감독이 선발출전을 시키지 않을 때 어떤 선수는 감독에게 불만을 터트린다. 하지만, 이 선수는 언젠가 올 기회를 준비하며 더욱 몸상태를 끌어올리는 데 집중한다. 그런데, 이 선수가 일년 전 팀을 옮긴 후 본인은 특별한 변화가 없음에도 부진한 상태이다. 아마 팀에 영향을 받았을 것이다. 한편 부진하던 선수가 팀을 바꾼 후 모두가 놀랄만한 결과를 보여주는 때도 잦다. 이런 사례들를 볼 때 환경과 개인의 조화가 정말 중요하다는 생각이 든다.


앞서 하고 싶은 일을 찾아 떠나는 이상적인 이직에 대해 언급했다. 그러나, 실제 현실에서는 어려움을 겪기 때문에 이직을 생각하는 때가 잦은 것 같다. 실제로 많은 동료들이 후자에 가까운 방식으로 떠나갔다. 몇 개월 뒤 동료들을 만나 대화를 나눠보면 내간 느낀 것처럼 역시 파랑새는 없었다. 새로운 곳에서 새로운 어려움이 생기고 그에 따라 새로운 국면에서 씨름하게 될 뿐이다. 따라서 이직이라는 것은 파랑새를 찾는 방법으로 보지 않는 게 좋을 것 같다. 그것보다는 본인이 현재 환경에서 최선을 다해 어려움을 헤쳐나가 보았음에도 도무지 만족스럽지 않을 때 나에게 좀더 잘 어울리는 환경을 찾는 방법으로 보면 어떨까 싶다. 좋고, 나쁜 환경이 아닌 본인에게 어울리는 환경 말이다.


2. 개발자 경쟁력에 대한 생각


난 개발자는 계속해서 발전해야 한다고 생각한다. 계속 발전해야 개발이 계속 즐거울 것이기 때문이다. 지난 몇년간 개발을 하며 느낀 점이 있다. 바로 처음에는 경이롭고 신선한 개발적 경험이 시간이 지나 숙련도가 높아질수록 단순 노동처럼 느껴진다는 것이다. 발전을 할수록 여러 가지 즐거움이 많아진다. 적절한 곳에 새로운 기술을 도입하며 즐거움이 생길 수도 있고, 오랫동안 사용해온 기술이라도 전혀 다른 시각으로 접근해 사용해보다 즐거움이 생길 수도 있다. TDD를 통해 색다른 즐거움이 생길수도 있고, 가독성 높은 코드를 위한 노력을 하며 일상의 업무에 예기치 않은 기쁨과 보람이 생길 수도 있다.


하지만, 위에서 이직에 대해 얘기한 것처럼 환경으로 인한 영향력은 피하기 어려운 편이라고 생각한다. 예로 내 상황을 생각해본다. 나는 지난 몇년 간 일상적인 업무가 일상적인 업무가 되지 않도록 노력해왔다. 그럼에도 돌아보면 나는 내가 일하는 주요 환경이라 할 수 있는 '포털 서비스 개발'이라는 환경을 뛰어넘지 못했던 것 같다. 예를 들어 난 게임에서 필요한 그래픽 프로그래밍에도 관심이 있지만, 지난 몇년 간 이런쪽의 자료를 거의 보지 못했다. 왜냐하면 내 고민의 대부분은 '포털 서비스 개발'에 속해있었고, 이곳에서 생기는 주제만 가지고 고민하고 또 고민해봐도 해결되지 않는 문제가 많았기 때문이다.


이런 상황을 보며 누군가가 해준 조언인 '타성으로 인한 경쟁력 저하'에 대해 다시 고민해본다. 정말 나는 한곳에 오래 있음으로 인해 타성이 생기고 경쟁력이 저하되고 있는걸까?  벤처 회사에 가서 게임 개발을 하게 되면 문제가 해결될까? 나로써는 아직 경험해보지 못한 미지의 영역이라 뭐라 말하기가 어렵다. 한번 상상해본다. 난 3D 클라이언트를 맡아 생전 처음으로 그래픽 프로그래밍을 하게 된다. 아는 것이 없어 너무 어렵다. 열심히 공부하고 또 공부하며 코드를 조금씩 작성해 나간다. 어려움이 많지만 즐거움도 많다. 그래픽 분야에 대해 많이 알아가며 발전을 하고 있는게 강하게 느껴진다.


그런데, 그동안 내가 쭉 고민해왔던 포털 서비스 개발은 어떻게 되는 것일까? 이 쪽도 발전이 있을까? 어쩌면 그래픽 프로그래밍이라는 완전히 새로운 환경이 기존에 고민했단 포털 서비스 개발에 대해 영감을 주어 모든 분야에 걸쳐 더욱더 발전하는 계기가 될 수도 있을 것 같다. 하지만, 이는 이상적인 상황이고 현실적으로는 포털 서비스 개발에 대한 고민을 잃어버린 채 그래픽 분야에 대한 발전만 있을 확률이 높을 것 같다. 이렇게 된다고 가정하면 난 개발자로써 더 발전한 것일까? 만약 그냥 포털 서비스 개발에 대해 계속 고민하며 그쪽 분야에서 더 많은 경험과 지식을 갖게 되면 그것도 발전한 거 아닌가? 잘 모르겠고 확신할 수 없다. 너무 많은 상황이 있을 것 같다.


사실 내가 겪는 확실한 문제는 점점 개발의 즐거움이 적어진다는 점이다. 즐거움이 적어짐과 동시에 발전도 더뎌지고 있다. 즉, 경쟁력이 저하되고 있는 것이다. 이는 발전을 원하는 개발자로에겐 매우 치명적인 문제라고 생각한다. 원인이 무엇일까? 누군가 조언한 것처럼 타성 때문일까? 예전에는 분명히 내 개인의 노력을 통해 어느정도 개발의 재미가 생기곤 했었다. 그런데, 지금에 이르러선 이런 재미가 많이 없어졌다. 개발에 대한 열의가 떨어져서 일까? 그렇다면 열의는 왜 떨어질까? 나이가 듦에 따라 자연스레 떨어지는 것이라면 어쩔 수가 없다. 하지만, 어떤 요인으로 인해 떨어지는 것이라면 그 원인을 찾아서 개선해 볼 수 있을 것 같다. 


결국 분명한 것이 있고 분명하지 않은 것이 있다. 분명한 것은 내가 개발자로써 해결해야 할 문제가 있다는 것이다. 분명하지 않은 것은 이런 문제가 발생하는 원인이다. 확신할 수 없기에 무엇인가 결론을 내리기가 어렵다. 하지만, 문제가 있다는 것은 분명하기에 뭐라도 시도하는 편이 좋을 것 같다. 이 문제를 좀더 탐색하기 위해 탁상공론 하기 보다는 내 자신을 과감히 새로운 환경에 던져 보는 것도 좋을 것 같다. 그후 불안한 마음과 낯섬을 느끼며 새롭게 시작하는 내 자신을 관찰해 본다면 이에 대한 답에 가까워 질 수 있을 것 같다. 이 문제는 꽤 오래된 문제이기 때문에 어떤 시도든 적극적으로 해보는 게 좋겠다는 생각이 든다.


3. 정리


글을 쓰다보니 각 주제는 참 복잡하다고 느껴진다. 예전 페이스북에 너무 많은 통찰은 결정을 방해한다는 글을 쓴적이 있다. 그런데, 나 역시 같은 상황을 겪고 있는 것 같다. 어렸을 때 자바를 공부하게 된 계기가 있다. 당시 C++과 자바 사이에서 어떤 것에 시간을 더 투자해 공부할지 고민했었다. 나는 지식도 경험도 없었다. 그래서 그냥 '더 마음이 내켰던' 자바를 공부하기로 결정했다. 지금 생각해보면 인생에 있어 굉장히 중요한 문제였음에도 빠르게 결정 했었다. 이 결정은 지금까지 아무 문제가 없었고, 오히려 매우 잘한 결정이라 생각하고 있다. 어쩌면 위 문제도 직관을 믿고 과감히 행동함으로써 해결해야하는 종류의 문제일지도 모르겠다.


WRITTEN BY
차민창
르세상스 엔지니어가 사회를 이끌어나가는 상상을 하며!

,
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.
예전에 겪었던 일이다. 동료 개발자와 여러 얘기를 하다보면 '안다'라는 표현이 자주 나왔다. 예로 어떤 동료와 테스트에 대한 얘기를 나눈적이 있다. 얘기하다보니 지식이 풍부한 것 같았다. 그런데, 그 개발자는 실제 업무에서 테스트를 활용하지 않았다. 개발하는 모습을 유심히 보니 테스트의 장점을 누릴 수 있는 상황에서도 테스트를 활용하지 않았다. 기회가 보아 테스트를 통해 누릴 수 있는 장점에 대해 다시 얘기해보았다. 그 개발자는 듣더니 본인도 다 알고 있는 내용이라고 한다. 의문이 든다. 이 개발자는 테스트에 대한 지식은 분명히 있는 것 같은데 정말 테스트에 대해 아는 사람이라고 해야하나?

기독교의 교리를 배울 때 인상 깊었던 점은 '하나님을 아는 것에 대한 정의'이다. 하나님을 안다는 것은 하나님을 믿는 진짜 자녀라는 뜻과 동일하게 취급한다. 예를 들어보자. 어떤 사람이 하나님에 대한 지식이 생겼다. 하나님의 성품에 대해 물어보면 대답도 잘한다. 아마 교리시험을 보면 높은 점수를 받을 것 같다. 그렇지만 기독교에서는 이 상태만으로 하나님을 '아는'사람이라 칭하지 않는다. 어느날 이 사람이 배운 지식을 가지고 심각하게 고민하더니 하나님에 대한 깊은 이해와 더불어 사랑이 생겼다. 결국 본인이 사랑하게 된 하나님에 뜻에 따라 살기로 결심하고 실천에 옮긴다. 기독교에서는 비로써 이 사람을 하나님을 '아는'사람이라 칭한다. 

위 기독교 사례를 모든 것에 적용하기엔 무리가 있겠지만, 무엇인가를 아는 것은 단순히 지식만을 의미하는 게 아닐 것 같다. 하지만, 요즘에는 많은 지식을 알고 얘기하는 것이 무언가를 아는 것으로 비춰지는 때가 잦은 것 같다. 때로 지식만을 가지고 전문가로 행세하는 사람도 있는 것 같다. 하지만, 아는 것에 '깊이'가 있다면 지식은 단지 시작일 뿐이라고 본다. 그 후 마음이 움직이고, 의지를 통해 지식을 실천 했을 때야 깊이를 갖추고 비로서 '안다고' 얘기할 수 있는게 아닐까 싶다.



WRITTEN BY
차민창
르세상스 엔지니어가 사회를 이끌어나가는 상상을 하며!

,
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

약 한달 전 새로운 팀으로 옮겼다. 동료들이 반갑게 맞아주며 약 2주 간은 천천히 소스코드도 읽어보고 기존 업무를 파악하라고 한다. 사실 기존 조직에서 여러모로 지쳐있는 상태에서 왔기 때문에 좋은 기회라고 생각했다. 천천히 소스코드도 읽고 그동안 했던 생각도 정리해보며 하루 하루를 나름 알차게 보냈다. 그런데, 얼마 지나지 않은 금요일에 갑작스레 일을 맡게 되었다.


1. 첫 번째 시도


우리 서비스는 RabbitMQ를 사용하고 있다. 대부분의 서비스는 장비 중 한 대에 문제가 생길 때도 정상적인 서비스를 하기 위해 최소한 장비 2대 이상을 클러스터링 해서 사용하는데, 우리 서비스도 L4 스위치와 RabbitMQ 2.3.1 자체의 클러스터링 기능을 이용해 이런 부분을 염두에 두고 있었다. L4 스위치는 클라이언트(Queue 구조에서 Publisher)에서 도메인명으로 MQ 서버에 접근했을 때 연결(Connection)을 분산시키는 역할을 하고 있었고, RabbitMQ 자체의 클러스터링은 두 독립적인 노드가 마치 하나의 MQ 인스턴스처럼 동작하게 하는 역할을 하고 있었다. 그런데, 어느날 시스템 팀에서 메모리 불량으로 MQ 1번 장비가 언제 문제가 생길지 모르니 가급적 신속히 교체 작업을 진행하자고 했다. 옆 자리 과장님은 RabbitMQ가 클러스터링 되어 있음을 알았기 때문에 바로 장비 1대를 중단했다. 별 문제가 없을 것이라 생각했지만 혹시나 해서 MQ를 사용하는 클라이언트의 로그를 보았다. 그런데, 놀랍게도 MQ 관련 오류 메세지가 수도 없이 올라오고 있었다. 과장님은 놀라 바로 중단했던 장비를 즉시 재기동 시켰다. 좀 살펴보던 과장님은 머리가 아팠는지 옆 자리에 있던 내게 도움을 부탁했다. 나도 사실 RabbitMQ를 한번도 써보지 못햇다. 하지만, 어쨌든 함께 문제를 살펴보기 시작했다.


2. 두 번째 시도


RabbitMQ에 대한 지식이 별로 없었음에도 신속히 교체를 해야했기 때문에 내부 동작을 파악하기 위한 충분한 시간이 부족하다 생각했다. 따라서 내부 이해에 근거한 접근보다는 블랙박스 식의 접근으로 문제를 해결하려 시도했다. 다시 말해 RabbitMQ 테스트 장비에서 여러 동작을 해보며 드러나는 결과를 관찰한 것이다. 목적은 문제 없이 장비 한대를 중단하는 것이기 때문에 어떻게 하면 서비스에 지장없이 장비를 중단할 수 있을지 여러 가지 방식으로 테스트 해보았다. 테스트를 하며 알아낸 사실은 MQ 1번 장비(마스터)를 중단하면 선언 된 Queue 등이 사라지며 문제가 생기지만, MQ 2번 장비(슬래이브)를 중단하면 아무 문제도 생기지 않는다는 점이었다. 이 결과를 확인하고 몇몇 문서를 참고한 후 '마스터가 Queue 등에 대한 메타 정보를 갖고 있기 때문에 마스터만 중단되지 않으면 서비스가 된다'라는 전제를 갖게 되었다. 일반적인 마스터-슬래이브 구조에서 마스터는 메타 정보를 관리하고 이에 따라 SPOF(Single Point Of Failure)가 되기 때문에 이 전제는 보편성이 있다고 생각했다. 이 전제에 따라 아래와 같은 교체 계획을 세웠다.


1) MQ2(슬래이브)를 중단하고 L4에서 제거한다.

이때 MQ2에 연결되어 있는 클라이언트는 연결이 끊긴 후 재연결을 시도할 것이고, 이 때 L4에서는 MQ2가 중단된 것을 인지하고 자연스레 MQ1로 연결을 해줄 것이다. MQ1로 연결이 완료되면 MQ1이 혼자 서비스한다.


2) MQ1과 MQ2의 클러스터 관계를 해제한다. 

이로인해 더이상 MQ1과 MQ2는 관계가 없게 된다.


3) MQ2의 클러스터링 설정을 초기화하고 MQ2를 마스터로 변경한다. 또한 Queue 선언 등을 MQ1과 동일하게 해 마스터로써 서비스 할 수 있게 준비시킨다. 즉, 새로운 마스터를 만드는 것이다.


4) MQ2를 다시 L4에 투입한다.


5) MQ1을 L4에서 제거하고 MQ1의 RabbitMQ를 중단한다.

이 때 1번과 같은 이유(재연결, L4)로 자연스레 MQ2로 재연결이 된다.


6) 메모리 교체가 끝나면 MQ1을 다시 MQ2의 슬래이브로 편입시킨다.


위 시나리오를 기반으로 베타환경에서 테스트를 시작했다. 혹시나 해서 여러 번 테스트를 했는데 테스트가 매우 잘 되었다. 어느정도 확신이 생겼고 리얼환경에 적용하기로 했다. 그런데 리얼환경에서 위 시나리오 중 1번 부분을 적용하는 순간 선언 된 Queue을 찾을 수 없다는 오류가 무수히 발생하며 다시 롤백을 해야했다. 


왜 그런것일까? 다시 원인을 살펴보았다. 이런저런 부분을 상세히 살피다보니 원인은 Queue가 선언되는 노드의 위치에 있었다. RabbitMQ에는 Queue를 선언 할 때 해당 Queue가 선언 될 노드를 지정할 수 있다. 리얼환경을 상세히 살펴보니 Queue선언 중 일부는 MQ1에 선언되있었고, 나머지는 MQ2에 선언되어 있었다. 이로인해 MQ2를 중단하자 MQ2에 선언 되있던 Queue선언을 찾을 수 없다는 오류가 발생한 것이다. 그렇다면 베타에서는 왜 문제가 없었지? 살펴보니 베타환경에는 모든 Queue가 MQ1번에 선언되어 있었다. 결국 현상만 보고 판단해 세운 "마스터가 중단되지 않으면 서비스가 가능하다"라는 전제는 완전히 잘못되었던 것이다.



# 그림1. 클러스터가 중단되면 Queue도 없어지는 현상


또 한번의 교체 실패로 머리가 아파왔다. 마음이 급했지만 이 상황을 어떻게 해결할지 침착하게 생각해보았다. 조금 방법을 찾아보면 현재 상황에서 어떻게든 교체를 할 수 있을 것 같았다. 하지만, 간단히 보였던 일이 커진 이유를 생각하자 생각이 바뀌었다. 즉, 근본적인 문제는 클러스터링이 제대로 동작하지 않는다는 점이었다. 이번에는 어떻게든 상황을 넘어갈 수 있지만, 이후 또 비슷한 일이 생겼을 때 지금처럼 일이 어려워 질 것이라 생각했다. 그래서 차라리 이번 기회에 클러스터링을 제대로 구성해보자 마음먹었다.


3. 세 번째 시도


결국 시스템팀에 상황을 얘기하고 잠시 교체를 미루기로 했다. 이번에는 클러스터 노드 중 하나가 중단되도 잘 동작하는 진짜 클러스터링 환경을 구성하기로 마음먹었다. 찾아보니 RabbitMQ 2.6부터 HA(High Availability)가 강화되었음을 확인했다. 


The RabbitMQ team is pleased to announce the release of RabbitMQ 2.6.0. The highlight of this release is the introduction of active-active HA, with queues getting replicated across nodes in a cluster. (생략)

http://www.rabbitmq.com/news.html


HA 관련 문서를 상세히 읽다보니 두 번째 시도에서 겪었던 문제도 이미 언급이 되어 있었다. 기존에도 읽었던 부분이지만 급하게 읽다보니 미처 인지하지 못했던 부분이었다.


You could use a cluster of RabbitMQ nodes to construct your RabbitMQ broker. This will be resilient to the loss of individual nodes in terms of the overall availability of service, but some important caveats apply: whilst exchanges and bindings survive the loss of individual nodes, queues and their messages do not.


To solve these various problems, we have developed active/active high availability for queues. This works by allowing queues to be mirrored on other nodes within a RabbitMQ cluster. The result is that should one node of a cluster fail, the queue can automatically switch to one of the mirrors and continue to operate, with no unavailability of service.

http://www.rabbitmq.com/ha.html


RabbitMQ에서는 위에서 언급 된 HA가 고려 된 Queue를 Mirrored Queue라고 부르는데 단어 그대로 Queue를 여러 노드에 걸쳐 Mirroring 해주는 기능이다. 따라서 한 노드가 중단 되어도 Queue 선언과 Queue에 담긴 메세지가 다른 노드에 이미 복사되어있기 때문에 문제 없이 서비스가 가능하다. 혹시 모르니 테스트 클러스터 환경을 구성해 RabbitMQ 2.6 이상의 최신버전을 설치하고 다양한 방법으로 노드를 중단해보며 여러 테스트를 해보았다. 마스터 노드든 슬래이드 노드든 중단되도 Queue 선언이나 Queue 안에 들어있는 메세지가 잘 보존되고 잘 처리됨을 확인했다. 이 결과에 따라 아래와 같은 교체 계획을 다시 세웠다.


1) 새로운 MQ 장비 2대를 준비하고 해당 장비에 대한 새로운 도메인(L4 바인딩 포함)도 준비한다.

2) MQ 장비에 Mirrored Queue를 제공하는 RabbitMQ 최신버전을 설치하고 클러스터링 한다.

3) 베타환경에서 신규 MQ 도메인으로 연결해 테스트를 진행한다.

4) MQ를 참조하는 모든 프로젝트에서 기존 MQ 도메인을 신규 MQ 도메인으로 바꾸어 배포한다.

5) 기존 MQ 클러스터는 제거한다.


결국 위 계획은 성공했다. 처음 예상했던 것보다 훨씬 많은 시간을 소모했지만 서비스를 중단하지 않고 MQ 클러스터를 교체한 것이다. 현재 위와 같은 구성으로 바뀐지 약 한달이 넘었지만 큰 문제 없이 잘 동작하고 있다. 앞으로는 위와 같이 급하게 장비를 교체 할 일이 생겨도 쉽게 할 수 있을 것이라 기대하고 있다.

# 그림2. 클러스터가 중단되었음에도 Mirrored Queue 때문에 Queue가 유지 됨


4. 관련 설정 및 몇 가지 이야기

 

고가용성을 보장하려면 RabbitMQ의 2.6 이상의 버전을 사용하는 게 좋고, Queue는 선언 시 반드시 HA 설정(Mirrored Queue)을 해줘야 한다. 


4-1) Spring-AMQP(Spring-Rabbit)


아래와 같이 Queue를 선언할 때 x-ha-policy를 all로 주면 된다. 


<rabbit:queue name="hello.string">

<rabbit:queue-arguments>

        <entry key="x-ha-policy" value="all" />

</rabbit:queue-arguments>

</rabbit:queue>


<rabbit:queue name="hello.object">

<rabbit:queue-arguments>

<entry key="x-ha-policy" value="all" />

</rabbit:queue-arguments>

</rabbit:queue>


혹은 코드에서 Queue를 선언한다면 아래와 같이 Parameter를 추가해주면 된다.


Map<String, Object> args = new HashMap<String, Object>();

args.put("x-ha-policy", "all");

channel.queueDeclare("myqueue", false, false, false, args);


4-2) RabbitMQ Management Web UI


Queue를 선언할 때 Mirror 필드의 값을 "Across All Nodes"로 선택해주면 된다.


4-3) Mirrored Queue는 Replication이 아님


문서에 HA가 등장하고 요즘에는 Replication을 기본적으로 지원하는 NoSQL류를 많이 살펴보다보니 Mirrored Queue가 Replication 처럼 동작한다고 착각했었다. 내가 이해한 Mirrored Queue와 Replication의 차이점은 이렇다. 


노드 A가 있고 아직 처리되지 않은 메세지가 10개 있다고 가정해보자. 이때 노드 B가 새롭게 클러스터에 참여한다. 잠시 후 노드 A가 예기치 않게 중단된다. 그럼 이 때 노드 B에 메세지가 있을까? 만약 Replication 이고 노드 B가 참여한 후 노드간에 Replication이 이뤄질 시간이 있었다면 노드 B에는 10개의 메세지가 보존되어 있을 것이다. 하지만, Mirrored Queue는 메세지가 없을 것이다. 왜냐하면 Mirrored Queue는 메세지가 들어올 때 전 노드에 복사(Mirroring) 하는 방식이기 때문이다. 위 10개 메세지가 들어올 당시 노드 B는 클러스터에 없었기 때문에 메세지는 존재하지 않는다.


4-4) 무손실 배포


이번에 새로운 클러스터를 도입하며 고민해본 부분은 어떻게 하면 무정지/무손실로 배포를 할지였다. 우리쪽에 MQ를 이용하는 곳을 생각해 보면 일반적인 MQ 모델처럼 Publisher와 Consumer가 있다. 만약 Publisher와 Consumer를 신규 도메인을 보도록 변경해 그냥 동시 배포한다면, 기존 MQ 클러스터에 쌓여있는 메세지는 더 이상 처리가 안 될 수 있다. 이런 이유로 배포 시 아래와 같은 단계로 배포를 진행했다.


1. Publisher 배포

앞으로 새롭게 유입되는 메세지는 신규 MQ 클러스터에 쌓인다.


2. 기존 MQ 클러스터의 메세지가 모두 처리되었음을 확인

이 시점에서 신규 MQ 클러스터에는 메세지가 쌓이고 있을 것이다.


3. Consumer 배포

Consumer를 배포하고 신규 MQ 클러스터에 쌓인 메세지를 처리하게 한다.


배포 중 새롭게 유입 된 메세지는 약간의 처리 지연 시간이 생기겠지만 메세지 손실 없이 배포가 가능하다.



WRITTEN BY
차민창
르세상스 엔지니어가 사회를 이끌어나가는 상상을 하며!

,
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

예전에 회사의 이사님 중 한 분이 "좋은(Good) 개발자를 넘어 탁월한(Great) 개발자가 되려면 무엇이 필요한가?"라는 주제로 에세이를 제출하라고 한적이 있었다. 당시 나도 해당 주제에 대해 고민한적이 많아 6가지 정도 주제로 간단히 에세이를 제출했는데, 당시 짧게 써 내긴 했지만 그때 미처 담지 못했던 생각이 더 있어 블로그에 정리해볼까 한다. 아래는 당시에 이사님께 제출한 글 중 일부이며, 이 글의 요약본이기도 하다.

3. 의사소통을 잘하지 못하는 개발자를 배려해주시면 좋겠습니다.


기술적인 열정을 가지고 있으며 기술력이 좋은 개발자는 이상하게 의사소통 능력이 떨어지는 경우가 많습니다. 따라서 회사에 필요한 가치를 많이 만들고 있으면서도 그런 것을 잘 드러내지 못합니다. 반면 의사소통에 보다 신경을 쓰는 개발자는 상대적으로 덜한 가치를 만들면서도 그것을 매우 잘 드러내고 그에 따른 보상을 받습니다. 이때 의사소통 능력이 부족한 개발자는 상대적 박탈감을 느끼게 됩니다. 왜냐하면, 본인이 더 많은 가치를 만들었다고 생각하기 때문입니다.


의사소통 능력이 부족하다는 것이 자랑할 바는 아니지만, 회사에서 이런 개발자들이 상대적 박탈감을 가지지 않도록 특별히 배려해준다면 좋을 것 같습니다. 어떤 면에서 순수하다고 볼 수 있는 이런 사람들이 탄탄히 기술적 기반을 가지고 의사소통 능력도 향상시키며 성장하면 회사에 매우 큰 도움이 될 것이라 생각합니다.


1. 개발자의 의사소통 능력이란?


가끔 개발자의 의사소통 능력이 무엇일까에 대해 생각해보곤 한다. 개발자에게 있어 의사소통 능력이란 무엇일까? 엄밀한 정의는 어려울테고, 단순히 내가 일하면서 느낀 것 위주로 생각해보면 세 가지 정도 예시를 들 수 있을 것 같다. 첫째는 개발자 간에 특정 주제를 논의하거나 공유하는 것이다. 이런 종류의 의사소통은 본인과 동료가 함께 잘하고 함께 발전할 수 있게 한다는 점에서 유익하다고 생각한다. 둘째는 기획자 등 협력하는 부서의 동료와 원활하게 일하는 것이다. 예로 기획자의 말을 잘 이해하는 것, 기획서를 잘 읽는 것, 기술적인 이슈를 기획자에게 이해시키는 것 등이 있을 것 같다. 이러한 능력은 함께 좋은 제품을 만들어가는 데 무척 중요하다고 본다. 셋째는 회사의 방향을 고려하는 능력이다. 이를 의사소통 능력이라고 얘기해야 하는지 약간 의문이 들지만, 회사의 핵심 목표를 이해하고 그에 걸맞게 사고하고 판단하며 일한다는 관점에서 보면 기획자가 쓴 기획서를 잘 읽는 것과 큰 차이가 없을 것 같다. 


내가 그동안 만나 함께 일해왔던 동료들을 머리속에 떠올려 본다. 의사소통 능력과 개발 실력이 모두 뛰어난 개발자가 많았으면 좋았겠지만 이런 유형의 개발자는 무척 드물었다. 반면 개발 능력에 강점을 보이는 개발자(의사소통 능력은 떨어지는)와, 의사소통 능력에 강점을 보이는 개발자(개발 능력은 떨어지는)는 종종 볼 수 있었다. 이 두 유형의 개발자는 현실에서 자주 비교가 되었고 이로인한 여러 사건이 있었다.


2. 내가 보고 느낀 현실


그동안 내가 봐왔던 대부분의 조직에서는 의사소통 능력이 뛰어난 개발자가 더 인정받고 더 빨리 승진했다고 생각한다. 반면 개발 능력이 뛰어난 개발자는 비교적 인정받지 못했으며 저평가를 받을 때도 잦았다. 흥미로운 점은 대게 관리자는 의사소통 능력이 뛰어난 개발자를 높히 평가했지만, 동료들은 개발 능력이 뛰어난 개발자를 더 높히 평가했다는 점이다. 또한, 의사소통이 뛰어난 개발자는 자의가 아님에도 종종 다른 개발자의 노력을 빼앗는 듯한 상황을 연출하기도 했다. 적극적으로 업무에 관한 의사소통을 하다보니 본인이 하지 않거나 관여만 했던 일임에도 불구하고 본인이 주도해서 이뤄낸 것으로 다른 사람이 오해하게 만들었기 때문이었다. 이 때 개발만 묵묵히 해왔던 개발자는 어느순간 본인이 재주넘는 곰과 같은 신세인 것 같다는 몹시 쓰라린 느낌을 받곤 했다. 이는 큰 문제였다. 왜냐하면, 이런 느낌을 받은 개발자가 급격히 의욕이 꺽이기도 했기 때문이다.


이런 현실을 보며 스스로 많은 고민을 해보았다. 왜 의사소통을 잘하는 개발자가 개발을 잘하는 개발자보다 대게 더 인정받을까? 내가 일하는 곳은 서비스를 운영하는 곳이었기 때문에 철저히 서비스 관점에서 생각해보았다. 두 개발자 유형 중 서비스에 누가 더 기여하고 있는가? 하지만, 냉정하고 정직하게 생각해볼 때 대답하기는 무척 어려웠다. 왜냐하면 제품을 만드는 데는 적절한 의사소통과 개발 모두 중요했기 때문이다. 


3. 의사소통 능력이 부족한 개발자에 대한 배려


의사소통 능력이 좋은 개발자는 어쨌든 본인이 손해보지 않게 어떤 상황이든 잘 헤쳐나갈 수 있는 능력이 있다고 생각한다. 문제는 의사소통 능력이 부족한 개발자이다. 묵묵히 일하며 많은 가치를 만들면서도 그런 것들을 잘 알리지 못하고 결국 화려한 개발자 뒤에 가려지고 손해 볼 때가 있기 때문이다. 손해를 보아도 그런 것들을 얘기해서 해결하는 데 익숙하지 않기 때문에 또 다시 손해를 보기도 하는 것 같다. 나는 그래서 이런 개발자에겐 특별한 배려가 필요하다고 생각한다. 아래는 이런 종류의 배려가 있으면 어떨까라는 부분을 정리해본 것이다.


* 본인이 잘 드러내지 못해도 관리자나 동료가 그가 팀에서 하는 역할과 기여하는 바를 구체적으로 알아주면 좋겠다.

대게 의사소통 능력이 떨어지는 개발자는 본인이 하는 일을 잘 드러내지 못하는 것 같다. 따라서 많은 가치를 만듬에도 불구하고 주위(특히 관리자)에서는 그 사람이 무슨 가치를 만드는지 잘 모를 때가 있다. 가까운 곳에서 일하는 동료는 이런 개발자를 높이 평가하지만, 현실적으로 여러모로 손해를 볼 때가 잦은 것 같다. 만약 주위에서 이런 개발자의 가치를 제대로 알아준다면, 얼마나 좋을까?


* 본인이 개발 역량 중심으로 발전해나가도 팀에 충분히 기여할 수 있다는 믿음을 주면 좋겠다.

다른 사람들은 개발도 어느정도 하고 의사소통도 잘하는 것 같은데, 난 맨날 기술적인 내용만 공부를 하고 있어도 될까? 사회인으로써 직장인으로써 필요한 다른 것도 많이 배워야 하지 않을까? 라는 의문이 들 수 있을 것 같다. 만약 본인이 개발 역량을 쌓는 것이 명확하게 팀에 도움이 된다는 것을 알게되고 실제로도 그렇다면 좋을 것 같다. 


물론 기술적인 내용 외 하는 고민이 나쁘다는 것은 아니다. 다만, 이런 것을 고민하다 오히려 개발 역량보다는 다른 것에 집중하게 될 수 있는 것이 문제라고 생각한다.


* 일을 할 때 기술적인 책임과 권한을 주면 좋겠다.

개발 능력이 뛰어난 개발자가 본인의 일에 대한 기술적인 책임과 권한을 갖는 것은 굉장한 기쁨일 것 같다. 어쩌면 이것 하나만으로도 충분히 만족스러워 할 수도 있을 것 같다.


* 본인이 공정하게 대우 받고 있다고 느끼게 해주면 좋겠다.

위에서 나온 예처럼 본인이 재주넘는 곰처럼 누군가에게 이용당하고 있다고 느끼면 의욕이 많이 떨어질 것 같다. 주위에 의사소통 능력이 뛰어난 개발자가 있어도 의사소통을 통해 만드는 가치만큼 본인이 개발을 통해 많은 가치를 만든다면 공정하게 대우 받을 수 있다는 믿음이 있으면 좋을 것 같다.


* 의사소통을 비롯해 떨어지는 능력을 향상시킬 수 있게 도와주면 좋겠다.

때때로 개발에만 너무 집중하다보니 본인이 어떤 능력이 부족한지 잘 모를수도 있을 것 같다. 따라서 본인이 개선해야 할 점을 정확하게 알려주면 좋을 것 같다. 다만 기본적으로 가지고 있는 강점은 계속해서 발전시키는 것을 전제로 하면 좋겠다. 위에서 얘기했듯이 다른 것에 더 많은 신경을 쓰다 오히려 본인의 강점을 잃어버릴 수도 있다고 생각하기 때문이다.


4. 맺음말


의사소통 능력은 떨어지지만 개발에 특별한 강점이 있는 개발자에게 이상적인 회사란 어떤 모습일까 상상해본다. 말투가 어눌한 개발자가 있다. 그런데 그 사람이 몇몇 기술적 회의에서는 날카로운 모습을 보여준다. 다른 사람은 그가 하는 기술적인 견해에 귀를 귀울이며, 혹 뭔가 정리가 안 되어 말을 제대로 못해도 더 많은 것을 차분히 얘기할 수 있도록 배려해주고 도와준다. 이렇게 개발적 강점을 살리고 인정해주는 문화와 환경을 갖춘 회사가 있다면 이런 개발자에게는 이상적인 회사가 아닐까 생각해본다.


나는 기술적 강점이 있는 개발자가 의사소통 등 약점을 보완하려 애쓰기 보다는 본인의 강점을 더욱 강화시키는 것이 좋지 않을까 생각한다. 어떻게 보면 개발에 재능이 있는 것인데, 본인의 재능을 더욱 강화시키는 게 약점을 강화시키는 것보다 훨씬 성취가 빠를테고 결국 처음 부분 이사님이 말씀하셨던 탁월한(Great) 개발자가 되는데도 더 도움이 될 것 같기 때문이다. 물론 약점을 아예 보완하지 말자는 얘기는 아니다. 다만 개발 능력이 중심이 되어야 한다는 뜻이다. 예를 들어 기술적으로 계속해서 성장했으면 세계적인 개발자가 될만한 소양을 갖춘 사람이 있었다고 가정해보자. 그런데, 이 사람이 어느날 무슨 생각을 했는지 개발보다는 의사소통 능력에 중점적으로 힘쓰기 시작했다. 결국 사회적으로 출세했지만, 개발 능력은 크게 발전하지 않았다. 만약 이런 일이 실제로 있다면 어떨까? 개발자의 시각에서는 너무 아쉬운 일 아닐까?


WRITTEN BY
차민창
르세상스 엔지니어가 사회를 이끌어나가는 상상을 하며!

,
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

몇달 전 개발 방법론과 관련한 모임이 있었다. 모임 중 여러 주제로 의견을 나눴는데, 그 중 프로세스에 대한 격렬한 논쟁이 있었다. 어떤 문제를 개선하기 위해 프로세스를 도입하자는 측과 도입하지 말자는 측의 의견대립이 있었던 것이다. 이런 모임에서 여러 의견을 듣다보면 프로세스에 대한 고민이 참 재밌게 느껴진다. 그래서 프로세스에 대한 경험이 많지 않음에도 개발자로 생활하며 자연스레 갖게 된 프로세스에 대한 여러 생각을 나눠볼까한다. 

1. 어떤 프로세스가 생기는 과정

어느 날 회사가 왜 프로세스를 만드는지에 대해 생각해봤다. 다양한 생각을 하다보니 내 나름의 결론에 이르게 되었다. 예를 들어 '쿼리 검수'라는 프로세스가 있다고 가정해보자. 왜 생겼을까? 내가 속한 회사의 사례를 들면 좋을 것 같다. 내가 처음 입사했을 당시 회사에는 프로세스가 많지 않았다. 많은 팀이 각자가 선호하는 방법을 활용하여 서비스를 운영했다. 때로 장애가 발생하기도 했다. 고객이 피해를 입었고, 일을 잘하는 팀은 장애 대책을 스스로 고안하여 대응하곤 했다. 장애 중 자주 발생했던 것 중 하나는 느린 쿼리 문제였다. 예로 개발자가 실수해 인덱스를 사용하지 않는 쿼리가 배포 되면 예외 없이 문제가 발생했었다.

여기부터는 나의 상상이 약간 들어간다. 어느 날 전사적 관점에서 문제를 바라보는 고위 관리자가 등장한다. 고위 관리자는 장애 기록을 보다 재밌는 사실을 알게된다. 그동안 쿼리 때문에 장애가 많이 발생했다는 점이다. 중간 관리자를 불러 물어본다.

고위 관리자 : '왜 이렇게 쿼리 관련 장애가 많죠?'
중간 관리자 : '가끔 개발자가 쿼리를 잘못 작성해서 그렇습니다.',
고위 관리자 : '이에 대한 대책을 마련해 주세요.'

(대책 마련 후)


중간 관리자 : '앞으로 모든 쿼리 변경은 쿼리 검수라는 절차를 통해 실행될 것입니다. 이는 기존처럼 개발자의 실수로 장애가 발생 할 확률을 줄이기 위함입니다.


내가 알기로 적지 않은 프로세스를 이런 계기로 만들었다. 쿼리 검수 프로세스는 가만히 생각해보면 쿼리 작성하는 데 있어 가장 실력 없는 개발자를 염두에 두는 것 같다. 다시 말해 말도 안 되는 수준의 쿼리가 작성되는 것을 막으려는 것이다. 좋다. 분명 필요한 것 같다. 그런데, 혹시 이로인해 잃어버린 것은 없나?

2. 프로세스 도입으로 잃어버린 것

프로세스가 도입된 후 개발자의 아우성이 커진다. 쿼리 검수를 받다가 힘들다고 느낀 어떤 개발자가 용기내어 묻는다.

개발자 : '쿼리를 자주 수정하는 데 이거 맨날 검수 받아야 하나요?',  
담당자 : '예, 받아야 합니다. 프로세스를 지키지 않으면 문제가 생길 시 문책을 받을 수 있습니다.'


결국 개발자는 울며 겨자먹기로 쿼리 검수를 받는다. 본인이 쿼리를 잘 작성하던 못 작성하던 예외가 없다. 잘하는 사람이라고 예외를 적용하기 시작하면 전체적으로 시행이 안될 수 있기 때문이다. 따라서 소명할 수 있는 특별한 사유가 없는 한 모든 개발자는 쿼리 검수를 받는다. 여기 흥미로운 점이 하나 있다. 시간이 지나며 자연스레 개발자는 쿼리작성이 본인의 주요업무는 아니라고 생각하게 된다는 것이다. 왜냐하면 주도권과 책임이 본인에게 온전히 있지 않기 때문이다. 따라서 쿼리에 많은 시간을 들여 공부하기 보다는 쿼리 작성에 필요한 최소한의 지식만을 유지하며 쿼리 검수에 의존하게 된다. 그래도 문제가 없다. 왜냐하면 잘못 된 부분이 있으면 쿼리 검수를 받아 조언을 받고 그에 맡게 고치면 되기 때문이다. 또한 문제가 생겨도 이제는 쿼리 검수자의 잘못이 크다. 그렇다. 개발자는 더 이상 쿼리전문가가 아니어도 되고, 더 이상 쿼리를 전적으로 책임지지 않아도 된다.

한편 팀은 순발력을 잃어버린다. 기존에는 쿼리 수정이 매우 자유로웠다. 따라서 서비스에 필요한 즉시 쿼리를 수정할 수 있었다. 하지만 이제는 쿼리에 문제가 있으면 그게 사소한 수정이든 중요한 수정이든 프로세스에 따라 검수를 받아야 한다. 따라서 속도가 자연스레 떨어진다. 어떤 소신 있는 개발자는 생각한다. '이 정도 간단한 수정은 굳이 검수 받을 필요가 없다. 이는 낭비다. 내가 책임지는 것으로 하고 그냥 검수 없이 쿼리를 수정해야겠다.' 그런데 몇일 후 옆 팀의 누군가가 검수 없이 쿼리를 수정하다 장애를 냈다. 프로세스 미준수에 대한 심각한 메일이 도는 것을 보니 심상치 않다. 프로세스를 잘 지키는 게 필요하다는 쪽으로 생각이 바뀐다.
 

어떤 프로세스든 도입의 취지를 이해하는 개발자는 프로세스의 필요성을 어느정도는 인정한다. 반면 어떤 개발자는 도무지 이해가 안 되고 인정도 하지 않는다. 이 때 후자의 개발자는 답답함을 느낀다. 본인이 생각하기에 도움이 안 된다고 생각하는 프로세스를 맨날 준수하자니 비관적인 생각도 든다. 결국 프로세스의 배경을 이해하고 걸맞게 수행하기 보다는 그냥 일단 달리 수가 없으니 시키는 대로 하자라는 심정으로 '형식적인 수행'을 하게 된다. 그럼 어떤 일이 발생할까? 아마 프로세스를 만들 당시의 기대와는 달리 프로세스가 '동작하지 않을 것'이다.

3. 동작하지 않는 프로세스

어떤 분은 프로세스의 준수를 아이가 손 닦는 것으로 비유한다. 좋은 비유라 생각하여 얘기거리로 사용해보려 한다. 어떤 어린아이가 있다. 이 아이는 맨날 밖에서 온갖 더러운 것을 만지며 놀다 저녁에 들어온다. 부모는 아이의 위생이 염려된다. 따라서 아이에게 한 가지 규칙을 강제하기로 한다. '너는 항상 밖에 나갔다 들어오면 예외 없이 손을 닦아야 한다. 화장실에 들어갔다 나오지 않으면 방에 들어갈 수 없어.' 아이는 할 수 없이 밖에 나갔다 오면 항상 화장실에 들어간다. 하지만 아이는 손 닦는 것이 너무 싫기 때문에 화장실에 들어가 물을 틀고 손에 물을 살짝 묻힌 후 바로 밖으로 나온다.

아이는 부모가 정한 규칙을 지켰다. 하지만 이게 정말 부모가 바랬던 것일까? 의학적으로 맞는지는 모르겠지만 아이가 손에 물만 살짝 묻힘으로 손에 있는 세균이 더 번성했다고 가정해보자. 만약 그렇다면 부모가 기대했던 손닦기 효과는 오히려 역효과를 낸 셈이다. 아이에게 강제하고, 화장실에 들어가는 시간을 낭비했으며, 물을 사용했지만 위생이 오히려 더 안 좋아진 것이다. 한 발자국 물러나 세균이 들어가기 전 그대로라고 가정해보자. 그렇다면 좋은 것인가? 역시 아니다. 이는 투자대비효과가 나오지 않는 것이다. 왜냐하면 화장실에 들어간 노력과 물이라는 자원을 사용했음에도 그 결과가 없기 때문이다. 실제로 부모는 최소한 손이 조금이나마 깨끗해지기를 바랬지만 이는 전혀 달성되지 않았다.

내 생각에는 아이의 행동을 통해 볼 수 있는 모습 회사에서도 보이는 것 같다. 어느 정도의 비효율성(밖에 나갔다 오면 손이 더렵냐에 관계없이 무조건 손을 닦아야 함)을 감수하고 프로세스를 도입했지만 프로세스 준수자(아이)는 프로세스를 형식적(
손 닦는 시늉만 함)으로 수행하여 별 이득(물만 살짝 묻혀 여전히 손이 더러움)이 없게 한 것이다.

4. 프로세스의 개선

그럼 어떻게 하자는 얘기인가? 긍적적으로 생각해보면 이런 상황은 뭔가 다른 방법을 시도해볼 좋은 기회라고 본다. 여러 방법이 있을 것 같다. 아이에게 왜 손을 닦아야만 하는지 차근 차근 설명할 수도 있고, 아이가 손을 정말 잘 닦는지 엄하게 감시할 수 있다. 어쩌면 아이가 스스로 필요성을 느낄 때까지 손 닦는 문제에 관한 자율권을 줄 지도 모른다. 어떤 방법이든 장단점이 있을 것이다. 중요한 것은 아이를 관찰하고 본래의 목적을 달성하지 못한다면 변화를 주어야 한다는 것이다.

어떤 변화를 줄지 결정할 때 중요한 것은 투자대비효율에 근거한 판단이라고 생각한다. 아이에게 설명해주는 것이 유리할지, 아니면 얘기해봤자 소용없으니 아이에게 자율성을 부여하고 인내하며 물과 시간을 아낄지 등에 대해서다. 그런데 이런 부분을 판단하기 전에 반드시 아이와 진지한 대화가 필요하다고 생각한다. 아이의 현재 상황과 심정을 물어봐야 하는 것이다. 그냥 아이가 보여주는 단편적인 모습만 보고 일방적으로 무엇인가를 하면 잘못된 결정을 할 확률이 높다고 생각한다.

5. 상황(Context)에 따른 프로세스의 적용

쿼리검수의 예에서 볼 수 있듯이 프로세스는 최저의 수준을 보장하는 데 초점을 맞출 때가 많다. 이로 인해 비효율이 발생한다. 쿼리 작성 수준이 높은 개발자도 쿼리 검수를 받아야 하고 결국 순발력에 부정적 영향을 받기 때문이다. 하지만 이런 손해가 있어도 우리가 유지보수하는 서비스가 크다면 이는 합리적이라 할 수 있다. 왜냐하면 각 부분별로 촘촘히 정의 된 쿼리 검수 같은 프로세스가 서비스가 신중한 발걸음을 내딛으며 적정 품질을 유지하는 데 도움이 되기 때문이다. 하지만 만약 다양한 상황이 존재한다면 얘기가 달라진다. 예로 회사 내 다른 어떤 서비스는 시장상황에 기민하게 대응하는 것이 필요하다고 가정해보자. 이런 서비스는 어떻게 해야하는가? 이미 잘 뿌리내린 모든 프로세스를 도입해야 하는가? 

방금 전의 의문은 축구의 포매이션의 비유를 통해 얘기해보면 좋을 것 같다. 축구에는 다양한 포매이션이 있다. 4-4-2, 3-4-3 등. 아마 축구에 관심이 있다면 누구나 한번쯤은 들어보았을 것이다. 보통 4-4-2는 사람들이 매우 공격적인 전술이라 얘기한다. 공격 시 수비수 2명을 제외한 모든 선수가 공격을 할 때가 잦기 때문이다. 반면 3-4-3은 4-4-2에 비해 비교적 수비적인 전술이다. 공격 시에도 수비 3명은 항상 자리를 지킨다. 재밌는 점은 대부분 감독이 하나의 포매이션만을 고집하지 않는다는 점이다. 강팀을 만나면 수비수를 늘려 수비적인 전술로 싸우다가도, 약팀을 만나면 공격수를 늘리며 공격적인 전술로 싸운다. 약팀이라 생각해 공격적으로 나서다가도 거세게 공격당하면 수비적으로 금새 변하기도 한다.

나는 회사의 프로세스도 축구의 포매이션을 닮으면 어떨까 생각을 해본다. 즉, 서비스의 상황에 따라 프로세스를 유연하게 조정할 수 있었으면 좋겠다는 얘기다. 예를 들어 무엇보다 순발력이 절실히 필요한 서비스에는 쿼리 검수 프로세스를 제거하고 쿼리에 관한 모든 것을 개발자에게 전적으로 맡길 수 있을 것이다.

6. 유연한 프로세스 적용의 어려움

그렇지만 유연함은 갑자기 생기진 않는 것 같다. 평소에 스트레칭을 안 하던 사람이 유연하기로 마음 먹었다고 해도 관절이 말을 듣지 않는 것처럼, 회사에서도 이런 일이 생길 것이라 생각한다. 예를 들어 무거운 프로세스 하에서만  5년 이상 일한 팀이 있다고 가정해보자. 갑작스런 시장상황의 변화로 신규 서비스를 최대한 빠르게 출시하는 것이 필요하다. 회사에서는 힘을 실어주기 위해 이미 정의 된 프로세스는 신경쓰지 말고 마음껏 해보라고 한다. 이 때 해당팀이 정말 기민하게 반응할 수 있을까?

사실 난 이런 문제에 관한 충분한 실례를 알지 못한다. 하지만 축구를 보면서 이런 일을 예측해본다. 히딩크가 2002년 한국에 왔을 때 공격적인 전술인 4-4-2 포매이션을 정착시키려 했다. 하지만 우리나라 선수 대부분은 4-4-2에는 익숙하지 않았고, 4-4-2 포매이션으로 경기할 때 히딩크가 원하는 만큼의 경기력을 보이지 못했다. 월드컵 전 결국 히딩크는 4-4-2 포매이션을 완전히 포기했다. 반면 유럽의 어떤 팀들은 만나는 상대팀에 따라 포매이션을 변경한다. 그 팀은 어떤 포매이션을 사용해도 일정수준 이상의 경기력을 보인다.

그렇다면 4-4-2를 잘 소화화지 못했던 2002년의 한국팀과 다양한 포매이션을 자유롭게 변경하는 유럽팀과의 차이점이 뭘까? 난 축구 전문가는 아니지만 팀 구성원의 경험도 가장 크게 작용했으리라 생각한다. 여러 포매이션에서 성공적인 경기를 치뤄본 선수는 이후에도 해당 포매이션에 관한 경험과 이해를 바탕으로 여러 포매이션에서 본인의 능력을 십분 발휘할 수 있으리라 생각한다. 반면 여러 포매이션에 관한 경험과 이해가 부족한 선수는 새로운 포매이션에서 경기하게 되면 온전한 능력을 발휘하지 못할 것이다. 그래서 난 앞서 시장상황에 빠르게 대응하고 싶었던 그 팀 역시 무거운 프로세스에서만 5년 이상 일했던 경험으로 인해 기민함을 확보하는 데 어려움울 겪지 않을까 생각해본다.

7. 결론 및 요약

프로세스는 잘 활용하면 체계적으로 일하기 위한 좋은 도구가 될 수 있다고 생각한다. 하지만 도입배경에 대한 이해 없이 무조건 프로세스를 준수하는 상황이 보이면 신중히 원인을 조사해 해결방법을 모색해야 한다고 본다. 또한 단 하나의 프로세스 체계를 고집하기 보다는 유연한 프로세스 체계가 있으면 어떨까 생각해본다. 예를 들어 순발력이 중요할 때를 위한 프로세스와, 신중한 운영이 중요할 때를 위한 프로세스와 같이 말이다. 하지만, 이런 유연한 프로세스의 적용을 위해서는 구성원이 충분히 훈련되어 있어야 한다고 본다. 

지극히 개발자로써 개인적인 의견을 솔직히 밝히자면 난 프로세스를 별로 좋아하지 않는다. 일을 할 때 항상 프로세스가 걸리적 거리고 답답할 때가 많다. 난 예전 서버든 보안이든 DB든 개발자가 모두 책임지고 관리하던 시절이 그립다. 그 때는 내가 원하는 만큼 속도를 낼 수 있었고, 개발자로써 배우는 것도 훨씬 많았다.


* 관련 글 

자의적 프로세스와 타의적 프로세스 

 



WRITTEN BY
차민창
르세상스 엔지니어가 사회를 이끌어나가는 상상을 하며!

,
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.
예전에 데브피아라는 개발자 커뮤니티를 자주 다녔다. 한 때 데브피아의 게시물을 빠짐없이 읽었는데, 당시 Visual C++포럼에서 활동하는 개발자들이 자주 하던 얘기 중 하나는 빌드 수행하고 30분 정도 커피 마시러 간다는 것이었다. 당시 규모가 큰 환경의 빌드 환경은 경험해본적이 없었기 때문에 그냥 왠지 모르게 멋져 보였다. 당시엔 이런 환경이 괴롭다는 것은 미처 알지 못했던 것이다. 그후 몇 년이 지났다. 웹개발을 하며 나도 비슷한 경험을 하게 되었다. 소스의 어떤 부분을 고친 후 결과를 확인하는 데 최소 1분 이상 걸리는 환경에서 일하게 된 것이다. 소스를 고치면 컴파일을 해야했고, 로컬의 웹서버도 재시작 해야했다. 내가 원하는 만큼 개발이 빠르게 되지 않는다는 생각이 들었고 답답했다. 집중력도 떨어지기 시작했고, 시간이 아까웠다. 

1. 피드백 속도와 생산성

지금 생각해보면 이는 피드백 속도와 관련된 문제였다. 어떤 개발자든 수많은 시행착오를 통해 결론에 도달한다. 개발을 하는 과정을 떠올려보자. 처음엔 대게 무언가 잘못 된 코드를 작성한다. 얼마 후 코드가 잘못된 것을 인지한다. 곧 코드를 고친다. 또 잘못 된 점을 인지한다. 또 고친다. 만족할 때까지 반복한다. 이렇게 개발자는 목적을 달성하기까지 시행착오를 반복한다. 여기서 주목할 점은 코드를 작성하고 문제를 인지할 때까지 얼마만큼의 시간이 걸리냐이다. 어떤 기능을 개발하는 데 100번의 시행착오를 겪었다고 가정해보자. 이 때 내가 웹개발을 했을 때처럼 시행착오의 1분이 걸렸다면 원인을 유추해서 수정하는 시간을 빼고도 100분이 소요되었다는 것을 알 수 있다. 하지만 만약 10초가 걸렸다면? 1000초이다. 분으로 환산하면 약 17분 정도이다. 이처럼 피드백 속도가 빨리지면 빨라질수록 시행착오에 드는 시간을 줄어든다. 시행착오에 드는 시간이 줄어든다는 것은 개발 생산성이 높아진다는 것을 의미한다.

2. 트렌드에서 읽을 수 있는 빠른 피드백의 중요성

최근 스크럼, TDD, 지속적 통합 등이 많이 언급된다. 이들은 각자의 영역에서 추구하는 바가 있다. 하지만 공통적으로 '피드백'을 강조한다. 

스크럼의 주요실천방안 중 하나는 스프린트(Sprint, 반복주기와 비슷한 개념)이다. 2주 혹은 3주 정도의 간격으로 데모 가능한 형태의 목표를 정한 후 스프린트를 진행한다. 2주 혹은 3주 정도 후 스린린트가 끝났을 때 관계자를 모아 데모를 한다. 만약 무엇인가 잘못되어 가고 있다면 관계자의 피드백이 있을테고, 팀은 잘못된 방향을 시정할 수 있게된다. 만약 이런 스프린트가 없다면 어떤 일이 발생할까? 많은 개발자가 한번씩 경험했을 법한 일이 발생한다. 오픈 전에 의사결정자가 와서 방향 자체가 잘못 되었다며 뒤집는 것이다. 스크럼의 다른 실천방안 중 하나는 일일회의이다. 오전에 개발 관계자들이 잠시 모인다. 돌아가며 어제 한일, 오늘 할일, 이슈를 간단히 얘기한다. 일일회의를 하는 이유는 여러 가지가 있지만 그 중 하나는 피드백 때문이다. 예로 신입사원이 쉬운 일을 어렵게 하고 있거나, 각기 다른 개발자가 같은 기능을 각자 개발하는 등의 낭비를 미리 알고 이에 대처할 수 있게 된다. 

TDD는 어떤 면에서 FDD(Feedback Driven Development)이라고 불러도 손색이 없을만큼 피드백이 중요한 역할을 한다. TDD는 테스트를 먼저 작성하고 개발을 하는 것이다. TDD를 하면 엄청난 양의 피드백을 조기에 받을 수 있다. 우선 테스트를 통해 개발하는 대상을 미리 사용해보기 때문에 API 사용성에 대해 미리 알 수 있다. 나중에 다 만들어 놓고 나서 사용성이 떨어지는 부분을 수정해야겠다는 마음이 들 때 이미 많은 파일에서 사용하고 있어 수정이 어려운 때를 예방해 주는 것이다. 또 디자인에 대해서도 미리 고민할 수 있게 된다. 예를 들어 테스트를 하다 보니 의존성이 너무 많다는 것을 알게될지도 모른다. 의존성이 많다는 것은 추상화 수준에 문제가 있다는 신호로 볼 수 있다. 또한 코드 상에 존재하는 결함을 즉시 알게된다. 따라서 TDD로 개발을 하면 결함을 조기에 고칠 수 있게 된다. 

지속적 통합 역시 피드백이 중요한 역할을 한다. 머지 지옥이라는 말이 있다. 두 명의 개발자가 별도의 브랜치에서 약 3달 간 작업했다. 이때 3달 동안 작업한 것을 다시 Trunk로 합치려고 한다. 두 사람이 중복으로 수정한 부분이 많다. 그것을 오류없이 잘 머지하려 하려면 정말 지옥을 경험하는 것처럼 힘들다. 그래서 머지 지옥이다. 지속적 통합의 취지는 이런 일을 예방하자는 데 있다. 실천방법은 가능한 미리 통합하는 것이다. 위 두 명의 개발자가 지속적 통합을 시도했더라면 어땠을까? 아마 최소 하루에 한번씩 서로 커밋하고 업데이트를 하면서 작업했을 것이다. 'A 파일 어제 네가 수정했네, 네가 만든 코드 기반을 활용해서 내가 추가로 작업하면 될 것 같아.', '어제 우리 작업한 것 충돌난 것 같아. 함께 살펴보자.'  개발 중에는 이를 낭비라고 생각할 수도 있겠지만 시간이 지난 후 현명한 판단임을 알게될 것이다. 

3. 천공카드 시절의 개발자

그렇다면 피드백 속도는 근래에서야 중요해진 개념일까? 그렇지 않은 것 같다. 오래 전 천공카드로 개발하던 시절에도 피드백 속도와의 싸움이 있었다. 당시 개발자에게 요구되는 능력 중 첫째는 인내력이었다고 한다. 왜냐하면 천공카드에 구멍을 뚫어 무엇가를 실행했는데 만약 실패하면 다시 천공카드를 뚫어야 했기 때문이다. 지금은 코드를 고치고 테스트를 돌리면 내가 작성한 코드가 잘 동작하는지 여부를 금방 알 수 있다. 하지만 천공카드 시절에는 시행착오란 기다림을 뜻했을 것이고, 개발시간은 훨씬 더 오래걸렸을 것이다.

천공카드 시절 후 수십년이 지났다. 그럼에도 피드백 속도가 지금도 이렇게 중요한 것을 보면 이는 소프트웨어 개발에 있어 본질적 요소 중 하나인 것 같다. 시류에 밀접한 어떤 것이든 금방 사라져간다는 사실에 비추어 볼 때 더욱 그렇다는 확신이 든다. 피드백 속도를 빠르게 하자라는 전제는 예전에 썼던 나누어 해결하기 처럼 소프트웨어 개발을 뛰어넘어 일상의 문제에까지 광범위하게 적용될 수 있을 것 같다. 

4. 빠른 피드백 관점의 사고

난 생산성에 문제가 있다고 있을 때 피드백 관점으로 문제를 바라보고 사고해본다. 즉 피드백 속도를 향상시킬 수 있는 방법이 없는지를 살펴보는 것이다. 꽤 많은 상황에서 피드백 속도의 향상이 생산성 향상이라는 결과로 이어진다. 작년 특정 팀에 가서 짝 프로그래밍을 통해 재현하기 어려운 버그를 함께 수정한적이 있다. 그때 팀의 개발자는 문제재현을 하지 못하고 있었다. 개발자는 문제재현을 하기 위해 의심되는 코드 부분에 로그를 넣은 후 컴파일 하고 톰켓을 재시작한 후 웹브라우저에서 여러 상황을 만들어보고 있었다. 컴파일을 하고 톰켓을 재시작 하는 데 몇 분의 시간이 소요됐고, 개발자는 시행착오를 1회 겪는데 최소 몇 분씩 사용하고 있었다. 문제가 쉽제 재현되지 않았기 때문에 많은 시간을 소요하고 있었던 것이다. 난 이를 보고 피드백 속도에 문제가 있다고 판단했다. 즉시 JUnit을 이용하여 문제를 재현해볼 수 있는 테스트를 만들었다. 테스트를 만든 후 우리는 입력값을 빠르게 변경하며 기존보다 훨씬 더 빠른 속도로 시행착오를 겪기 시작했다. 얼마 후 우리가 만든 테스트가 실패했고, 이는 문제재현에 성공한 것이었다. 코드를 수정하여 테스트를 성공하게 만들었고 문제가 해결되었다. 내게 이 경험은 매우 인상 깊었는데 피드백을 의식적으로 인지하고 이를 제어했기 때문이다. 

5. 그렇다면 빠른 피드백이 정말 좋기만 한것인가?

지금까지 말한 부분에 근거해 내 머리에 자리잡은 강력한 전제 중 하나는 '빠른 피드백은 생산성을 높여준다.' 것이다. 과연 소프트웨어 세계의 절대적 진리가 있는지 갸우뚱 하는 가운데서도 이 전제만큼은 크게 의심하지 않았다. 여러 경험을 통해서 자주 증명됐고 확신은 커져만 갔다. 하지만 불완전함을 의미하는 인간이 개입되면 이는 옳지 않은 전제가 될 수도 있다.

어떤 개발자가 있다. 개발자에게 개발에 도움이 되는 정보를 5분마다 준다. 개발자가 과연 일을 잘할 수 있을까? 아닐 것이다. 개발자는 일에 집중할 수 없을 것이고 아무일도 하지 못할 것이다. 이는 개발자가 인간이기 때문에 생기는 일이다. 소프트웨어 역사에서 수도 없이 증명되었듯이 논리적으로 올바른 것이 인간이 개입하는 순간 더이상 올바르지 않게 된다. 난 폭포수 개발방법론의 가장 큰 실패원인은 인간의 불완전성을 신중히 고려하지 않았기 때문이라고 믿는다. 따라서 빠른 피드백이 좋다라는 전제에 따른 사고도 좋지만 항상 그 안에 있는 인간에 대한 신중한 고려가 필요하다고 생각한다. 

6. 이 전제는 20년 후에도 사랑받을 것 같다.

소프트웨어 산업은 다른 산업에 비해 변화가 극심하다. 즉, 과도기를 지나고 있는 것이다. 몇달 전 극찬과 조명을 받았던 그 무엇이 오늘 이 순간 전혀 조명받지 못하는 것이 그리 놀랄 일도 아니다. 새로운 프레임웍이 수도없이 나온다. 그 자신의 범위 내에서 지식을 쏟아낸다. 하지만 그 지식 많은 부분은 어느 순간부터 중요하지 않은 지식이 된다. 하지만 이런 지식과는 달리 빠른 피드백은 20년 후에도 여전히 개발자에게 사랑받는 전제로 남아있지 않을까라는 생각이 든다. 난 이를 소프트웨어 본질적 요소라고 생각하며, 지나가는 무엇이 아닌 이런 본질적 요소를 찾는 것은 개발자로써 큰 즐거움 중 하나인 것 같다.

WRITTEN BY
차민창
르세상스 엔지니어가 사회를 이끌어나가는 상상을 하며!

,