2편: 회사에서 원하는 개발 실력을 갖추는 방법
앞선 글에서는 최근에 개발자 구인난이 심해졌다는 내용과, 그 원인에 관해서 알아보았습니다. 그렇다면 어떻게 회사들이 원하는 실력을 갖출 수 있을까요?
참고로 여기서 말하는 회사란 높은 연봉, 좋은 복지, 훌륭한 동료와 도전적인 일을 할 수 있는 회사들을 의미합니다. (박봉에 제대로 된 개발을 하기 힘든 영세한 SI 업체는 누구나 쉽게 들어갈 수 있으니 논외로 합니다.)
단순히 많고 많은 개발자 중 one of them 이 아닌, 많은 회사들이 원하는 실력 좋은 개발자가 되기 위해서는 노력이 필요합니다. SW개발을 업으로 삼기 위해서 근본적으로 중요한 것은 SW 개발 실력이고, 밑에 언급할 내용들은 그 실력을 쌓기 위한 방법들의 예시입니다.
최소 6개월, 일반적으로는 1~2년 정도의 노력이 필요한데, 그 기간 정도만 열심히 노력한다면 시장에서 많은 오퍼를 받는 개발자가 될 수 있습니다. (프로그래밍을 좋아한다는 가정하에) 그 이유는 다양한 프로젝트를 보다 체계적으로 진행 해 보며 문제 해결력을 기르기 위한 최소 기간이 필요하기 때문입니다. (일반적으로 회사에서도 신입을 트레이닝하고, 어느정도 기여를 하고 밥값을 할 수 있을 정도가 되려면 보통 최소 1년 정도 걸립니다.)
참고로, 대부분은 학부 대학생을 기준으로 말씀드리는 것이며, 학교 수업만으로는 부족하고 별도의 노력을 해야 할 필요가 있습니다.
많은 학생들이 코딩 테스트를 준비하면서 일반적으로 알고리즘고 자료구조는 잘 아는 경우가 많습니다. 이것은 문제를 해결하기 위한 가장 기본적인 구조이기 때문에, 알고리즘을 매번 직접 구현하진 못하더라도 (일반적으로는 라이브러리를 쓰면 되서 직접 구현할 일이 그리 많지 않기 때문에) 어떤 원리인지, 어떤 상황에서 사용하는지는 잘 알아야 할 필요가 있습니다.
라이브러리를 쓰기 때문에 매번 직접 구현은 안해도 된다고 했지만, 직접 구현해보는 경험은 해 볼 필요가 잇습니다. 왜냐면 현업에서는 학교에서 배운 알고리즘이나 자료구조만 쓰는 게 아니라 새로운 것을 생각하거나 응용해야 할 경우가 많기 때문입니다. 그리고 특정 도메인마다 다양한 알고리즘들이 많은데, 자신이 지원할 분야에 관해서는 그런 특정한 알고리즘이나 자료구조에 관해서도 공부할 필요가 있습니다.
코딩 테스트가 채용에 크게 변별력은 없다는 것은 이미 많은 기업들이 알고 있지만, 아직도 기본적으로 채용에 쓰이는 방식인데 이는 필터링 용도입니다. 따라서 기본적인 내용은 알아야 하고, 자세하게 알 수록 유리합니다.
어떤 언어든 일반적으로 스타일 가이드와 같은 것이 있습니다. 그런 것들을 찬찬히 읽어보고 코딩할 때 습관을 들이는 것이 좋습니다. 특히나, 주니어 레벨의 경우 코드를 간결하고 깔끔하게 쓰는 경우가 잘 없고, 예외 처리가 잘 안되어 있는 경우를 많이 봅니다. 이런 것들은 끊임없는 연습이 필요합니다.
스타일 가이드와 같은 것은 다 이유가 있기 때문에 그렇게 사용하는 것입니다. 이런 것들에 대해 알 수록 해당 언어에 대해 깊이 알 수 있습니다. 그리고 해당 언어에 대해서 깊게 설명한 좋은 글들이 인터넷에 정말 많은데, 그런 글들을 시간 날 때마다 읽어보는 것이 좋습니다.
자신이 잘 사용하는 오픈소스 라이브러리가 있다고 할 때, 내부 코드를 한번씩 살펴보세요. 특히나 star가 많은 인기있는 라이브러리는 아주 좋은 공부 교재입니다. 오픈소스 라이브러리들 중에는 굉장히 잘 짜여진 코드들이 많습니다.
회사에 QA팀이 있다면 테스트를 그냥 QA팀에게 맡기면 될까요? 절대 아닙니다. 현업에서도 테스트는 시간 부족으로 제대로 못하는 경우가 많기는 하지만, 테스트는 개발 생산성에 매우 많은 영향을 끼칩니다.
toy project 라면 테스트를 작성할 일이 별로 없겠지만, 실제 운영하는 서비스라면 테스트를 작성하는 것은 매우 중요합니다. 특히나 주니어 레벨의 경우 테스트를 제대로 작성하는 경우가 잘 없는데, 다양한 테스트에 관해서 공부하고 이것들을 습관화 하는 것이 좋습니다.
테스트도 unit test, integration test, stress test 등 다양한 테스트들이 있고, 다양한 기법들이 있으며 해당 언어에서 사용하는 다양한 라이브러리들이 있을 것입니다. 테스트의 세계도 굉장히 넓습니다. 많은 경우 테스트를 이론적으로 배우겠지만, 프로젝트에 제대로 적용하는 경우는 드문 편입니다. 특히나, 프로젝트마다 그 특성에 맞는 테스트를 고안하는 것도 아키텍쳐를 고안하는 것 처럼 굉장히 난이도 높은 경우가 있기 때문에, 테스트를 잘 만들고 이걸로 인해 개발 생산성이 높아지는 것을 실제로 느껴보는 경험은 아주 중요합니다.
앞 선 글에서 학교를 다니든, 부트캠프를 하든 프로젝트는 하지만 toy project 수준에서 그친다는 게 문제라고 했습니다. 그냥 기술을 단순하게 써 보는것과, 기술을 이용해서 사용자가 있는 서비스를 만드는 것은 수준이 다른 문제입니다.
학교나 학원에서 하는 것을 제외하고서라도, 따로 프로젝트를 진행하는 것이 좋습니다. 이 때, 단순히 내가 어떤 기술을 써보거나 공부해 보고 싶어서 하기보다는, 실제로 사용자가 있는 프로젝트를 목표로 하는것이 좋습니다. 이 때, 위에서 말한 간결하며 다양한 예외가 처리되는 깔끔한 코드를 작성하는 경험, 테스트를 어떻게 작성할지 고민하는 경험 등을 직접 해 보는 것이 좋습니다.
물론 사용자를 실제로 많이 확보하긴 쉽지 않습니다. 경험을 쌓는 것이 목적이므로, 사용자가 많아지고 규모가 커질 때를 대비하여 아키텍쳐를 어떻게 구성할 지, 그리고 새로운 기능이 빠르게 추가되어야 하는데 서비스를 무중단으로 유지하며 어떻게 새로운 기능이 추가될 지 등을 고민하는게 좋습니다. 이런 과정을 통하여 아키텍쳐를 구성하는 방법, 테스트를 잘 작성하는 방법, 빠른 기능 추가와 배포를 위한 CI/CD 와 같은 것에 대해서 새로이 알 수 있으며 고민을 해 볼 수 있습니다.
특히나, 아키텍쳐 설계와 관련해서는 항상 더 좋은 방법은 없을지, 더 효율적으로 할 수는 없을지 다양한 기술들을 찾아보고, 연구해보고, 고민해 볼 필요가 있습니다. 물론 현업에서는 "레거시" 가 있기 때문에 아키텍쳐 구성 등이 제한되는 경우가 많습니다만, 최신 기술들을 사용해보고, 그런 기술들이 왜 나왔는지 고민해 보며 직접 적용을 해 보며 경험한 것과, 그렇지 않은 것은 굉장히 많은 차이가 납니다.
프로젝트를 진행할 때 최적화에 대한 고민도 해볼 필요가 있습니다. 일반적으로 코딩테스트를 진행할 때는 Big-O notation으로 연산의 복잡도를 어렵지 않게 계산할 수 있습니다. 하지만 실전에서는 그리 간단한 문제가 아닙니다. 입력에 대한 고려와, 내부의 복잡한 로직들에 대한 고려를 하다 보면 코딩 테스트 문제처럼 간단히 복잡도를 계산할 수 없습니다.
따라서, 최적화를 할 때는 프로파일링을 진행하는데 프로파일링을 위한 테스트를 작성하는 것과, 프로파일링 후 개선을 하여 속도를 최적화하는 등의 경험을 쌓아 볼 필요가 있습니다. 현업에서는 굉장히 중요한 것들인데 toy project를 하며 이렇게까지 하는 경우는 잘 없는 것 같습니다.
메모리 최적화 또한 마찬가지입니다. 규모가 큰 프로젝트에서는 큰 데이터량을 연산하거나 부하가 많아지게 되면 memory leak 이 발생하거나 메모리 용량이 부족해지는 경우가 자주 발생합니다. 이 때 메모리 최적화를 위해서는 사용하는 언어의 Gabage collection 동작 원리도 알아야 하고, 그 언어의 특성도 자세히 알아야 합니다. 이렇게 어떤 부분이 문제인지 찾아나가는 경험을 toy project에서 하기는 힘들겠지요.
이건 당연한 것이겠지만, 개발자는 최신 기술 공부를 게을리 하지 말아야 합니다. 개발 면접을 볼 때 이 사람이 뼛속까지 개발자인가? 를 보기 위해서 최신 기술 질문을 많이 하는데 이때 잘 대답한다면 좋은 인상을 줄 확률이 높겠죠?
예를 들어, 웹 개발을 한다고 할 때 일반적으로는 REST API 형태로 프론트엔드-백엔드 통신하는 것을 구현 할 것입니다. 그러면 REST API 에 관한 자세한 내용을 알고 있어야 할 것입니다. 근데, 최근에는 gRPC나 GraphQL 같은 기능도 많이 사용하는데 (물론 큰 기업보다는 비교적 신규 프로젝트를 하는 스타트업들이 많이 사용하지만) 이런 기술을 실제로 써 보고, 경험을 하며 기존의 기술과 비교를 해서 어떤 장단점이 있는지 몸으로 체득해 본 것과 안 한 것은 거의 하늘과 땅 차이입니다.
웹 개발 시 API를 만든다고 해도 단순히 동기적 통신이 아닌 비동기 통신, 예를 들어 서버에서 클라이언트로 푸시를 넣어주어야 하는 경우 등 현업에서는 다양한 니즈가 있기 때문에 이런 것들을 경험해 보는 게 좋습니다. 서버에서 클라이언트로 비동기 통신을 하기 위해서는 SSE 나 Websocket 같은 기술들을 사용할 텐데 이런 것들을 언제 쓰고 어떻게 사용해야 효율적이며 다른 방법과 비교하여 장단점이 뭐가 있을지 살펴볼 필요가 있습니다.
다른 예로 최근에는 Microservice Architecture가 유행인데 (이게 정말 필요로 하는가는 논외로 하고) 이런 구조에서는 보통 아키텍쳐가 어떻게 짜여지는 지 살펴보는 것도 좋을 것입니다. 마이크로서비스들 사이에서 어떻게 통신하는지, 통신할 때 주로 kafka 나 Message Queue 계열을 많이 쓸 텐데 왜 쓰는 건지, 다양한 프레임워크가 어떻게 이뤄져 있고 장단점이 뭐가 있는지 등을 경험해 보는게 좋습니다.
DB에 관해서도 마찬가지입니다. 일반적으로 배우는 RDB 뿐 아니라 NoSQL은 왜 사용하는지, In-memory DB는 왜 있고 어떨 때 쓰는지 등을 실제로 프로젝트에 접목시켜보고, 경험해 보며 장단점을 분석해 보는 것이 좋습니다.
프론트엔드를 예로 들면, 요즘 제일 수요가 많은 React 를 한다면 React가 어떻게 나오게 된 기술인지, 버전이 올라가며 많이 쓰는 React hook 은 왜 많이들 쓰는것인지, 최근 나온 lazy는 왜 쓰는건지 등 해당 프레임워크의 설계 철학이나 버전 업이 되면서 이렇게 개선이 되는 이유 등에 관해 깊이 고민해 볼 필요가 있습니다. 최신 기술들을 학교에서 다뤄보기는 힘들기 때문에 꼭 시간을 내서 해보는 것이 좋습니다.
당연하게도 다 잘할 수는 없습니다. 일단 자신이 목표하는 포지션과 전문분야를 정해 놓고, 그것과 관련된 것 부터 깊게 파고들어가야 합니다. 한 가지를 깊게 잘 하면, 이걸 하나씩 늘려가는 것은 점점 쉬워집니다.
예를 들어, 백엔드 개발자를 희망한다면 그 중에서도 한가지 기술스택을 정해서 깊게 파보는 게 좋습니다. Python/Django 를 할 것인지, Spring/Java+Kotlin을 할 것인지 등을 정한 후에 하는 것입니다. 사실 이런 것은 시장에서 수요가 높은 것을 하는게 좋겠지만, 어쨌든 한가지에 관해 깊게 알게 되면 다른 분야는 비교적 빠르게 학습할 수 있습니다.
머신러닝쪽을 예로 들자면, 많은 머신러닝 엔지니어 지원자가 그냥 수업이나 강의를 듣고 toy project 해본 정도 수준으로 머신러닝 엔지니어가 되길 희망하는 경우가 많습니다. 그리고 보통 대부분 딥러닝에 대해서만 조금 아는 수준입니다. 근데 딥러닝이 만능이 절대 아닙니다. 현업에서 딥러닝이 잘 되는 경우는 제한적입니다. 기존에 많이 쓰이던 classical한 ML 알고리즘들에 관한 지식도 필요하며, EDA 에 관한 경험도 필요하고 수학적 지식도 필요하며 해당 회사에서 만드는 서비스의 도메인에 관한 지식도 필요합니다.
현업에서는 발표된 논문의 연구내용을 가져다가 구현해 보고 개선해야 할 수도 있기 때문에 코드 복붙이 아닌 직접 다 구현하는 능력이라던가, Kaggle 에서 어느정도 랭킹이 올라가 본 경험이 중요하게 작용합니다. Kaggle 랭킹을 높이려면 단순 지식을 배워서 조금 써 본 것이 아니라 다양한 테크닉을 종합적으로 사용해 봐야 하기 때문이지요. 많은 ML엔지니어 포지션의 우대사항에 괜히 논문 발표나, Kaggle 상위랭킹이 있는게 아닙니다. 현업에서는 수업에서 배우는 것 처럼 우아하게 준비된 데이터를 쉽게 모델링 하고, 결과를 볼 수 있지 않고 카오스적인 상태에서 문제를 해결해야 하는 경우가 많기 때문입니다.
다 잘할 필요는 없지만, 최소한 한가지 만큼은 깊이 파 볼 필요가 있습니다.
워렌 버핏이 했던 지식은 복리로 쌓인다는 유명한 말이 있습니다. 시간 나는 대로 개발과 관련된 블로그나 아티클 등을 읽고 정리해 보는 것이 좋습니다. 처음에는 잘 이해가 가지 않는 것들이 많고, 글 하나 읽는 데도 오랜 시간이 걸릴 수 있습니다. 하나의 글을 이해하기 위해 여러 번의 검색을 계속 해야 할 수도 있습니다. 하지만, 꾸준히 읽다 보면 어느 순간 글을 더 이해하기 쉬워질 것이고 지식은 정말 복리로 쌓인다는 경험을 할 수가 있습니다. (꾸준함이 가장 중요합니다)
자신이 사용하는 오픈소스 라이브러리의 경우 내부 동작을 완전히 이해해보는 습관을 들이는 것이 좋습니다. 다 그렇게 하긴 힘들겠지만 최소한 유명한 라이브러리의 경우에는 내부를 공부해 보는게 좋습니다. 현업에서는 오픈소스 내부를 뜯어 보고 수정하는 경우도 많기 때문입니다. 일반적인 주니어 레벨 개발자 면접을 볼 때 보면 오픈소스를 사용만 해봤지 내부 동작 원리에 대해 고민해 본 경우가 잘 없었는데, 그런 습관을 들이고 관심있는 라이브러리에 대해 깊이 공부했다면 좋은 평가를 받을 수 있겠지요?
SW업계는 변화가 많고 항상 새로운 기술이 많이 나오기 때문에 학습을 해야 하는 것은 필연적입니다. 기본 지식이 많이 쌓이면 학습하기가 비교적 쉬워질 것입니다. 물론, 나이가 들어갈수록 새로운 것을 받아들이기 힘들 수도 있지만, 계속해서 학습하는 자세가 중요합니다.
제가 강조드리고 싶은 내용이 한가지 있습니다.
단순히 특정 기업에 들어가겠다고 여러 꼼수를 습득하는 것은, 성공할 확률이 낮습니다. 장기적으로 보고 내 실력을 키우겠다는 마음가짐으로 접근하는 것이 좋습니다. 최소 6개월 ~ 길면 2년 정도 정말 정말 열심히 노력한다면 수 많은 오퍼를 계속해서 받는 실력자가 될 수 있습니다.
꼰대같이 경쟁이나 노오력만 강조한다고 할 지도 모르겠지만, 노력이 필요하다는 것은 엄연한 사실입니다. 물론 한두번 정도 운이 좋을 수는 있겠지만, 커리어를 계속해서 발전시키고 싶고 좋은 회사에서 훌륭한 사람들과 원하는 일을 하기 위해서는 시장에서 원하는 실력을 갖추어야 합니다. 그리고 이를 위해서는 노력을 해야 합니다. 남들이 놀 때 나도 놀면 그냥 남들과 똑같은 실력을 갖게 되는 것이고, 그러면 레드오션에서 힘들게 경쟁해야 합니다. 탁월해지고 싶다면, 필연적으로 남들이 놀 때도 나는 공부하고 노력해야 합니다.
쉽게 얻을 수 있는 것은 아무것도 없습니다. 하지만, 제대로 된 방향으로 제대로 된 노력을 하게 되면 시장에서 원하는 뛰어난 인재가 될 수 있다고 확신합니다.
여기 있는 내용만으로는 제대로 된 방향을 알기 힘들 수도 있다고 생각합니다. 제가 바빠서 확답은 못드리지만 상담이 필요한 분들은 메일 주시면 최대한 답변 드리겠습니다.