SI 개발 10년차인데 코드 좀 봐주세요

최근 한국에 머무르는 시간이 길어지면서 Popit 저자 섭외 활동과 병행하여 개발자 멘토링을 꾸준히 하고 있습니다. SI 경력 10년 정도 되는 개발자와 만나서 이야기 한 내용을 대략적으로 정리해 보았습니다[1].

어느날 페이스북 메신저로 SI 분야에서 계속 있으면서 10년 정도의 경력을 가지고 있는데 자신이 만든 코드에 대해 리뷰를 해줄 수 없냐는 요청을 받았습니다.

si_dev_code_review

코드 리뷰로 해결할 수 있는 문제가 아니다.

이 메시지를 받고 출장 중이던 북경에서 곰곰히 생각해 보았습니다. 이 분이 요청한 대로 온라인에서 코드 리뷰만 해드리면 되는 것인가? 당연히 아닐것 입니다. SI 분야에서 개발로 10년 정도 했으면 코드의 품질은 표준 이상일테고 그 이상의 무언가에 대한 답을 찾고 계신데 딱히 어떤 구체적인 도움을 요청해야 할 지 모르기 때문에 "앞으로 어떻게 하면 될까요?" 라는 질문을 "코드 리뷰" 라는 용어로 나왔다고 생각하였습니다.

그런 생각에 다시 회신을 보내 만나기로 약속하고  2시간 정도 이야기를 나누었습니다. 처음에는 대충 상황에 대한 이야기를 들었는데 정리해보면 다음과 같았습니다.

  • 요구사항을 받고 이것을 기능으로 만들어 내는 것은 매우 즐거운 일이다.
  • 다만, 연차는 계속 늘어나는데 내가 만드는 코드는 몇년 전이나 지금이나 똑같다. Spring 기반에 오라클 DB 서버 한대에 데이터를 저장하고, 조회하는 코드가 대부분이다.
  • 조금만 로직이 복잡해지면 코드에서 if 절이 난무한다.
  • 장애나 오류가 발생하면 어떻게 문제를 찾을지 모르겠다.

물론 그 분이 만든 코드도 같이 보았습니다. 일반적인 스프링 기반의 코드로 표준적인 코드 였습니다.

왜 현재 시스템에서 스프링을 선택 하셨나요?

이야기 하는 중에 본인도 SI 회사가 아닌 서비스 회사로 이직을 하면 어떨까 생각하여  면접을 보게 되었는데 통과하지 못했다고 했습니다. 저도 질문 한두가지 해 보았는데 적절한 답변을 듣지 못했습니다. 제 질문은

개발 하실때 Spring 프레임워크를 사용하고 계신데 왜 선택하신거가요?

답변은 대부분의 SI 프로젝트가 그렇듯이

고객이 선택해서, 또는 이미 결정되어서 내려온 상황이다.

였습니다.

왜 이 질문을 하게 되었냐면 SI 프로젝트의 특징 때문이라고 할 수 있습니다. 많은 SI 프로젝트는 개발자가 선택할 수 있는 것이 거의 없습니다. 물론 프로젝트의 RFP 작성, 제안서 작성 등의 단계부터 참여를 하게 되면 전체적인 그림과 각 구성요소의 선택에 있어 의사결정에 참여할 수 있지만 대부분의 개발자는 그렇지 않은 상황입니다.

이런 상황에서 각 기술의 개념, 장/단점 등에 대한 생각보다는 현재 주어진 기술로 정해진 기능, 일정, 품질 수준에 맞는 결과물을 내야 하는 일이 SI 개발자의 주요 미션이라고 볼 수 있습니다.

여러 서비스 회사들은 개발자 인터뷰 시에 위와 비슷한 질문을 하게 됩니다. 이 질문에서 얻고자 하는 것은 개발자가 기술을 어떻게 바라보고 있는지에 대한 태도를 보기 위함 입니다. 수동적이 아닌 적극적으로 그 기술이 내가 만들어야 하는 서비스 또는 시스템의 요구사항에 부합되는 지를 확인하고, 더 부합되는 기술을 선택할 수 있는 능력 또는 자세를 가진 개발자를 찾기 원하기 때문입니다.

기술적인 고민이 차단된 환경

구성이 다른 프로젝트도 많이 있겠지만 많은 SI 프로젝트에서 사용하는 솔루션은 한정적 입니다. 몇 개 Application Server 브랜드와 DB는 Oracle, SQLServer 등 2 ~ 3개의 브랜드가 거의 90% 이상을 차지하고 있을 겁니다. 빅데이터 프로젝트와 같이 특별한 프로젝트의 경우 다양한 오픈 소스가 활용되고 있지만 있지만 서비스 회사보다는 많지 않을 것입니다. 이렇게 구성되는 이유 중의 하나는 수주 기반의 프로젝트라는 점입니다. 수주 기반의 프로젝트는 예산을 편성하고 그 예산에 맞게 외부 개발 회사가 수주하여 개발하는 방식입니다. 이 경우 오픈 소스를 사용하거나 아키텍처 구성을 잘하고 좋은 코드를 만드는 등의 적은 비용으로 견고한 아키텍처를 만들 수 있는 여지가 거의 없게 됩니다.

deliberate_practice

"적은 비용, 견고한 시스템", 주로 이 목표를 달성하기 위해 기술이 고도화 되는 것인데 수주 기반의 프로젝트는 "적은 비용" 이 곧 악의 축이 됩니다. "적은 비용"의 의미는 개발사 입장에서는 매출 감소가 되기 때문입니다.  그리고 이렇게 만들기 위해서는 어느 정도의 불확실성이 있는데 발주사 입장에서는 이런 불확실성의 위험부담을 안고 싶지 않기 때문에 "비싸지만, 예상 가능한" 아키텍처를 선호하게 되는 것입니다.

이런 상황에서 개발자[2]는 어떻게 될까요? 연차(경험)가 쌓일수록 기술적인 고민을 하고 그 고민이 다시 실제 운영(개발)중인 시스템에 반영이 되고, 다시 문제가 발생하고 이를 해결해 나가는 과정 속에 성장을 하게 되는데 이런 성장의 사이클이 아주 쉽게 차단되어 있습니다.

가능하면 빨리 벗어나라!

이 분과 이야기 하면서 제가 드린 가장 첫번째 조언은 빨리 이런 환경을 벗어 나라는 것이었습니다. SI 업계를 떠나라고 말씀드리고 싶었지만 차마 그렇게는 말하지 않고 앞에서 언급한 개발자가 뭔가를 결정할 수 있고, 문제가 발생하면 책임을 지고, 그 책임 기반에 다시 개선할 수 있는 이런 환경이 되는 곳을 찾아 보라고 이야기 했습니다.

SI 프로젝트에서도 이런 환경을 가진 곳을 찾을 수 있겠지만 상대적으로 서비스 회사에 이런 환경이 더 많은 것은 사실입니다. 그러면 이 분이 서비스 회사로의 이직이 가능할까요? 조건이 현재보다 나쁜 곳으로 간다면 어렵지 않겠지만 그렇지 않다면 쉽지 않을 것입니다.

물론 꼭 SI 프로젝트 환경에 있다고 주도적인 활동을 할 수 없는 것은 아닙니다. 관건은 나의 현재 실력일 것입니다. 조건이 좋은 서비스 회사로 옮기던, SI 환경에서 주도적인 업무를 찾던 필요한 것은 본인의 실력입니다. 현재의 환경에서는 실력을 쌓는 것이 다른 환경에서보다 어렵기 때문에 벗어나라고 조언을 드렸던 것입니다.

그러면 SI 프로젝트에 있으면 무조건 기술을 쌓기가 어려울까요? 저는 SI 프로젝트를 하면서도 충분히 깊이 있는 기술을 쌓을 수 있다고 생각합니다. 단지 조금 힘들 뿐 입니다. 저도 SI 프로젝트에 있으면서 나름대로 개인의 기술을 발전시켜 왔습니다. 그래서 그분에세 제가 사용했던 방법을 알려 드렸습니다.

의도적인 학습이 필요하다.

단순히 프로젝트에 참여해서 개발을 한다고 나의 기술이 좋아지는 것은 없습니다. 처음 개발에 발을 들이고 몇년 동안은 계속 발전을 한다는 느낌을 가질 것이지만 어느 연차가 되면 정체되어 있는 것을 느끼게 됩니다.

물론 다른 분야의 경력 또는 기술은 계속 증가할 수 있는데 해당 분야의 업무에 대한 이해도, 고객 관계 또는 프로젝트의 관리 등의 분야에 대한 경험을 계속 쌓일 것입니다. 이런 분야에 대한 경험을 더 즐기는 분들이라면 이런 환경이 더 좋을 수도 있겠지만 현장 개발자로 계속 성장으로 원하는 개발자라면 답답함을 느끼게 됩니다. 이런 느낌은 서비스 회사라고 없는 것은 아니기 때문에 연차가 쌓이는 것에 비해 실력이 늘지 않는 개발자에게 필자가 사용했던 방법을 공유해 볼까 합니다.

deliberate_practice2

필자가 제시하는 방법은 프로젝트 수행을 하면서 사용하는 기술, 발생하는 문제들을 접합때 의도적으로 더 깊게, 원론을 찾으려는 노력을 하는 것입니다. 즉, 학습의 의도를 가지고 프로젝트를 바라보라는 것입니다. 예를 들어 이번에 만난 개발자의 코드를 보면서 @Singleton이 눈에 띄어 왜 이렇게 했냐고 하니 상태 관리를 하지 않는 Bean의 경우 굳이 매번 객체를 만들 필요가 없기 때문이라고는 답변을 들었습니다. 물론 맞는 답변입니다. 거기서 더 나아가 다시 질문을 했습니다. 왜 그런가요?

이 질문에 더 깊은 답으로 들어가면 톰캣과 같은 WAS가 하나의 사용자 요청을 받아서 어떻게 쓰레드가 만들어지고 하는 등의 부분에 닿을 것이고, 이러면 다시 멀티 쓰레드의 Concurrency에 대한 학습으로 이어질 수 있습니다.   다시 더 깊게 들어가면 소켓 프로그램은 어떻게 만들어지고 소켓 프로그램에서 여러 클라이언트로 부터의 접속을 처리하는 방법이 나올 것입니다.

또 다른 질문을 해 보았습니다. 스프링을 사용하면 데이터베이스 Connection 객체를 거의 사용하지 않는데 이것은 도대체 어떻게 관리되고 있는 것 일까요? 하나의 요청(Request Thread)에는 하나의 Connection을 계속 유지시켜야 트렌젝션 제어를 할 수 있는데 어떻게 각 도메인 객체 또는 서비스 객체에 각각의 메소드 처리 시 전달이 될까요? 최초의 Connection은 누가 만들까요? 등등 수없이 많은 질문을 해 볼 수 있습니다.

아니면 이런 상상도 해볼 수 있겠죠. 지금 개발 중인 코드에 if 절이 너무 난무하고 로직이 복잡하면 코드도 같이 복잡해지는데 어떻게 하면 해결할 수 있을까? DB 서버 한대로는 동시에 몇만명 사용자 정도만 처리할 수 있는데 추석에 이벤트를 하면 동시에 수십만명이 접속할텐데 어떻게 해야 처리할 수 있을까? 등등 의도적으로 자신을 훈련할 수 있는 사이클을 만들어야 합니다.

많은 개발자들이 이를 위해 업무 시간이 아닌 퇴근 이후에 공부를 하는 형태로 접근을 많이 하는데 저는 업무와 관련되지 않는 분야에 대해 별도의 시간을 투자하여 공부하는 것은 효율적인 측면이나 깊이있는 기술을 익히는데는 한계가 있다고 보기 때문에 권장하지 않습니다. 가장 큰 이유는 공부해서 얻은 지식과 실무에서 얻은 지식의 차이는 그야말로 어마아마 하기 때문입니다.

현재 하고 있는 개발 환경, 운영 환경에 집중해서 더 깊게 더 견고하게 만들려고 했을 때의 문제를 스스로에게 던지는 것입니다. 물론 답은 혼자 찾을 필요는 없습니다. 주변에 개발자에게 물어 보거나 커뮤니티에 나오거나 등등 다양한 방법으로 해결할 수 있습니다. 현재 popit에 가장 많은 글을 쓰고 계신 tony 님도 일상에서 학습을 하는 대표적인 사례라고 할 수 있습니다.

정시 퇴근?

이렇게 깊게 파고 들기 시작하면 하나의 기능을 만드는데 시간이 많이 소요됩니다. 프로젝트 관련 기능을 개발하면서 앞에서 말한 깊게 파보라는 것을 하게 되면 개발 시간이 오래 걸리게 됩니다. 이 부족한 시간은 원래 개인적으로 별도로 학습을 하려고 했던 시간을 이용하여 어느 정도 보충할 수 있습니다. 예를 들어 퇴근 후 별도로 학습하는데 2시간 정도를 사용했다면 이 2시간을 회사 프로젝트 개발에 사용하는 것입니다.

이렇게 되면 어디까지 회사일이고 어디까지 학습인지 경계가 애매하게 됩니다. 근무시간에만 회사 개발을 하고 퇴근 후 시간에 공부를 하겠다는 전략으로 보면 절대 할 수 없는 방법입니다.

즉, 어디까지가 회사일이고, 어디까지가 나를 위한 학습인지 경계가 모호해 집니다.

이런 상황에서 퇴근이라는 말이 의미가 있을까요? 저녁에 사무실을 나온다는 의미의 퇴근이 아니라 하루 중 회사일을 하지 않고 본인의 개인적인 일을 하는 시간부터를 퇴근으로 정의한다면 필자가 제시하는 프로젝트 내에서 공부를 하라는 것은 사무실을 떠난 후에도 계속해서 학습과 회사일을 같이하게 되는 것입니다. 이런 생활속에서 굳이 늦게 까지 사무실에서 개발을 할 필요는 없을 것입니다. 집에서도 프로젝트 관련 기능 개발을 할 수 있을 것이고. 개발 중 의문점이 있는 부분을 찾아서 학습할 수도 있을 것입니다.

필자는 이런 방법을 통해 학습 시간을 확보하고, 학습의 효과를 증가 시켰습니다. 이런 경험으로 자바를 익히고, 아키텍처를 익히고, Hadoop을 통해 분산 컴퓨팅의 전반적인 개념을 이해했으며, 다양한 오픈 소스 활동도 하게 되었습니다.

고달픈 삶!

이런 학습 방법의 삶은 초반에는 무척 힘이 듭니다. 업무에 더 많은 시간이 투자되기 때문이죠.

learning_curve

이 고통의 시간이 지나면 기본적인 요구사항에 대한 기능 구현은 빠르게 할 수 있고, 더 많은 시간을 학습에 투자할 수 있게 됩니다. 그러면 우리가 많은 보는 그래프와 같이 선형적으로 증가하는 것이 아니라 그 이상으로 증가하게 될 것입니다. 이 고통의 시간을 넘는 것이 문제라는 것이죠? 이 고통의 시간을 지날 수 있는 본인만의 방법을 찾는 것이 가장 중요할 것입니다.

주변에 도와줄 사람은 많다.

이런 고통의 시간을 조금이나마 줄일 수 있는 방법은 주변에 도움을 요청하는 것입니다. 커뮤니티에 참여할 수도 있고요. 이 글을 쓰게 만든 그분도 일면식도 없는 저에게 도움을 요청했습니다. 주변에 도움을 줄 수 있는 개발자는 많이 있습니다. 부끄러워하지 마시고, 괴롭힌다고 생각하지 마시고 메신저도 아니면 댓글로 도움을 요청해 보세요.

다른 기술을 배우고 싶으면 그곳으로 가라!

하지만 내가 속한 프로젝트의 기술과는 전혀 다른 분야의 기술을 익히고 싶은 경우도 많이 있을 겁니다. 이 분야에서 개인적으로 학습하는 것은 많은 도움이 되지 않는다고 앞에서 이야기 했습니다. 물론 이미 의도적으로 학습하는 방식이 몸에 배어 있는 개발자라면 상관없겠지만 아닌 경우라면 위에서 필자가 제시하는 방법으로 현재 프로젝트에서 사용하는 기술에 대해 어느 수준까지 올리는 것이 중요합니다.

일단 이렇게 스스로 생각하고 학습할 수 있는 개념이 몸에 습관이 되면 혼자 공부하기 보다는 그 분야를 메인 기술로 사용하고 있는 프로젝트나 회사로 이직하는 것이 좋다고 생각합니다. 앞에 소개드린 학습법도 별도의 학습이 아닌 업무에서 기술을 익히는 방식이었습니다.

문제는 그런 기술을 가지고 있지 않은데 어떻게 그 기술을 사용하는 곳으로 이직을 할 수 있냐는 것입니다. 저도 여러 개발자들을 인터뷰 해보았지만 많은 회사에서 실제 그 기술을 사용하는 개발자를 찾기는 쉽지 않습니다. 소프트웨어 개발에 대한 기본 개념이 충실하고 자기 주도적인 학습, 생각 방식을 가지고 있는 개발자를 선택하고 그들에게 해당 업무를 수행하게 하면 얼마 지나지 않아 그 기술에 익숙해지고 전문가로 성장할 수 있게 됩니다.

닭이 먼저냐 달걀이 먼저냐는 논리에서 벗어나는 방법은 기본에 충실하면 기술에 상관없이 본인이 원하는 기술을 사용하는 조직으로 갈수 있다는 것입니다. 아래 참고할 만한 글 중에서 첫번째 글에도 그런 내용이 있으니 참고하세요.

다른 참고할만한 글

마지막으로...

가장 중요한 것은 필자가 제시하는 것이거나 본인이 직접 선택한 학습 방법이거나 꾸준히 하는 것이 가장 중요하다고 생각합니다. 필자가 자주 하는 말이 있는데

꾸준히 2, 3년만 하면 무조건 상위 10%다.

각주

[1]: 매번 이런 글을 쓸때마다 심적으로 부담이 있습니다. 필자가 이 글에서 SI 프로젝트라고 하였지만 모든 SI 프로젝트가 이렇지 않을 것이고, SI 프로젝트에 계신 개발자들이 모두 이렇지 않다는 것은 잘 알고 있습니다. 반대로 서비스 회사에 있는 개발자라고 해서 또한 모두 적극적이고, 주도적으로 개발에 참여하지 않는 경우도 많이 있습니다.

[2]: 개발 프로젝트에서 개발자라는 의미는 여러 역할을 가지고 있는데 이 글에서의 개발자는 업무 역량이 높아지기를 원하는 개발자가 아닌 기술 자체의 역량이 높아지기를 원하는 개발자입니다. 물론 업무와 기술 양쪽 모두 연관이 되어 있겠지만 말입니다.


Popit은 페이스북 댓글만 사용하고 있습니다. 페이스북 로그인 후 글을 보시면 댓글이 나타납니다.