회원가입을 하면 원하는 문장을
저장할 수 있어요!
다음
AWS 이용 중이라면 최대 700만 원 지원받으세요
흔히 개발자는 이직이 쉽다고들 말한다. 다른 직군에 비해 채용공고가 많이 보이는 것도 사실이다. 하지만 주니어 개발자에겐 쉽지 않은 일이다. 막상 이직을 시도해보면 장벽이 꽤 높다는 것을 알 수 있다. 가장 큰 장벽은 바로 면접이다. 필자는 스타트업에서 1년을 일한 후, 좀 더 큰 규모의 프로젝트를 경험해보고 싶어 이직을 시도했지만 면접에서 어려움을 겪었다. 그래서 계속 이직을 시도하기보다는 퇴사 후 공부하는 기간을 갖기로 결심했다.
회원가입을 하면 원하는 문장을
저장할 수 있어요!
다음
회원가입을 하면
성장에 도움이 되는 콘텐츠를
스크랩할 수 있어요!
확인
흔히 개발자는 이직이 쉽다고들 말한다. 다른 직군에 비해 채용공고가 많이 보이는 것도 사실이다. 하지만 주니어 개발자에겐 쉽지 않은 일이다. 막상 이직을 시도해보면 장벽이 꽤 높다는 것을 알 수 있다. 가장 큰 장벽은 바로 면접이다. 필자는 스타트업에서 1년을 일한 후, 좀 더 큰 규모의 프로젝트를 경험해보고 싶어 이직을 시도했지만 면접에서 어려움을 겪었다. 그래서 계속 이직을 시도하기보다는 퇴사 후 공부하는 기간을 갖기로 결심했다.
주니어 개발자로서 자바스크립트 프레임워크인 리액트와 리액트 네이티브를 다룰 줄 아는 정도면 충분하다고 생각했는데, 1년 차 이상의 주니어로 이직할 때는 CS(Computer Science) 전공 지식이 꼭 필요했다. 업무 중에도 종종 네트워크 통신 이슈와 메모리 관리 이슈가 발생했고, 그때마다 검색을 통해 해결했지만, 기본 지식의 필요성을 느꼈다. 그래서 퇴사 후 최대 1년 간의 공부 계획을 세우게 되었다. 약 9개월이 지난 지금 주니어 개발자로서 어떻게 공부했는지, 무엇이 도움이 되었는지 회고해보고자 한다.
우선 필자는 비전공자 개발자이다. 공부 기간을 최대 1년으로 잡았기 때문에, 시간을 아낄 수 있는 효율적인 학습법이 필요했다. 먼저 쉬운 난이도로 전체 범위를 풀어보고, 난이도를 높여 중요 개념 문제를 풀어보는 공부 방식을 적용했다. CS(Computer Science) 지식 전체를 얕게 훑어본 후, 꼭 필요한 분야만 깊이 파고드는 방법이다.
함께 의지할 동료가 있으면 좋을 것 같아, 디벨럽이라는 스터디 플랫폼에서 ‘면접을 위한 CS 전공지식 노트’라는 책을 완독하는 스터디에 참여했다. 이 스터디를 통해 디자인 패턴과 네트워크, 운영체제, 데이터베이스에서 꼭 알아야 하는 핵심 키워드들을 숙지할 수 있었다. 그리고 스터디가 끝날 무렵, 소프트웨어 정글이라는 부트캠프에 합류해서 그동안 공부한 이론을 바탕으로 토이 프로젝트들을 진행해볼 수 있었다.
프론트엔드 개발자로 일한 지 약 1년이 다 되었지만, 네트워크에 대한 이해도는 낮은 편이었다. 당장은 큰 문제로 이어지지 않았지만, 장기적으로는 문제가 될 수 있었다. 당시 개발하던 앱이 간헐적으로 속도가 느려지는 성능 이슈가 있었는데, 이를 해결할 방법으로 서버 부하를 줄여주는 로드밸런싱이나 HTTP 메시지 용량을 줄이는 방법 등이 거론됐다. 당시에는 이 논의를 추상적으로만 이해하여, 네트워크 신호가 이동하는 움직임이 구체적으로 그려지지 않아 답답했다. 이는 퇴사 후 웹서버 만들기 프로젝트를 직접 해보고 나서야 해소되었다.
웹서버는 다음과 같이 구현했다. 먼저 AWS에서 EC2 인스턴스를 2개 할당받고, 하나를 클라이언트, 하나를 서버로 사용했다. 네트워크에 참여하는 주체를 호스트라고 부르며, 호스트는 고유한 IP를 가져야 하므로 2개의 인스턴스가 필요했다.
정적 콘텐츠와 동적 콘텐츠에 대한 일회적인 요청 및 응답을 테스트하고 싶었다. 서버와 클라이언트는 HTTP/1.0 프로토콜로 통신하도록 했다. IP마다 여러 개의 포트를 열어 둘 수 있는데, 들어오는 요청들을 하나의 포트에서 모두 처리하지 않고, 나누어 처리하도록 하는 것이 로드밸런싱을 구현하는 기본적인 방법이다. 이번에 만든 웹서버도 기본 포트 외에 1개의 예비 포트를 마련해두었다. 그리고 서버의 소스 코드가 접근할 수 있는 경로에 미리 영상과 글을 준비해두고, 클라이언트의 요청이 들어오면 알맞게 파싱하여 해당 경로에 있는 소스를 응답메시지에 담아서 보내도록 했다.
예비 포트를 마련해 로드밸런싱을 준비했지만, 실제로 실습하기에는 두 가지 어려움이 있었다. 첫째, 그만큼의 많은 트래픽이 발생하는 환경이 아니었다. 둘째, 멀티 스레드 환경이 구현되어 있지 않았다. 첫 번째 문제는 동료들과 함께 동시에 접속하는 트래픽을 만들어 실험해볼 수 있었지만, 멀티 스레드 환경이 구축되지 않는다면 서버가 동시에 여러 요청을 받을 수가 없으므로, 기존 코드를 멀티 스레드 방식으로 변경했다. 그래서 각각의 사용자와 연결을 맺을 때마다 분리된 스레드가 생성되어 해당 스레드에서 응답을 수행하고, 각각의 통신이 서로 간섭하지 않고 이루어지도록 했다.
이때 화이트보드에 그림을 많이 그려보면서 진행했다. 클라이언트와 서버 사이에서 여러 계층으로 구분되는 네트워크 통신의 면면을 이해하기 위해서는 그림이 꼭 필요했다. 동료 개발자들과 머리를 맞대고 한 계층씩 퍼즐 조각을 맞추자, 머릿속에서 지식이 완전히 정리되는 느낌이었다. 이처럼 이미지화된 지식은 기억에도 오래 남기 때문에 추천하는 방식이다.
앱 개발을 하며 늘 성능에 신경 써야 했는데, 이때 성능과 가장 밀접하게 연관되는 작업이 메모리 관리다. 앱 사용자의 메모리 사용량이 증가한다는 것은 앱의 속도와 성능, 그리고 사용자의 불만과 직결되는 민감한 문제였다. 하지만 자바스크립트 프레임워크인 리액트 네이티브로 만든 앱이었기에, 메모리 관리를 위해 할 수 있는 것이 많지 않다고 느꼈다. 자바스크립트는 자동으로 가비지 컬렉팅이 되는 언어로만 알고 있었기 때문이다. 변수의 상태와 생명주기를 제어하기 위해 스코프 관리를 해야 한다는 사실을 차츰 깨달았지만, 메모리에 대한 이해가 부족한 상태에서 메모리를 관리하기란 쉽지 않은 일이었다.
메모리에 대한 이해는 운영체제를 공부하면서 윤곽이 잡히기 시작했고, 직접 기본적인 운영체제의 동작을 구현해보면서 더욱 확실해졌다. 웹서버 실습이 끝난 후 핀토스라는 운영체제를 직접 구현해보는 실습을 진행했는데, 실습은 매우 어려웠지만 결과적으로는 물리 메모리 공간을 어떻게 가상의 주소공간으로 변환해서 각각의 프로그램이 사용할 수 있게 되는지 정확하게 알 수 있었다.
“Pintos는 컴퓨터 소프트웨어로서, X86 명령어 집합 아키텍처를 위한 단순 지시적 운영 체제 프레임워크이다. 커널 스레드, 사용자 프로그램의 로드 및 실행, 파일 시스템을 지원하지만, 이들 모두를 매우 단순한 방식으로 구현한다.” – 위키백과
먼저 핀토스 구현은 네 단계로 이루어졌다. CPU가 자원을 배분하기 위해 스레드를 생성하고 우선순위에 따라 스케줄링하는 기능을 구현했다. 그다음에는 스레드가 컴퓨터 자원을 요청하는 수단인 시스템 콜을 구현했다. 그 후 물리 메모리 공간을 추상화하여 스레드에 배분하는 메모리 관리 시스템을 구현했고, 마지막으로 파일 관리 시스템을 구현했다.
운영체제 구현은 어려운 만큼 재미도 있었다. 가장 큰 소득은 스레드의 개념을 명확히 한 것과 메모리 공간을 관리하는 능력을 갖추게 된 것이다. 그동안 자바스크립트가 싱글 스레드 언어라는 말과 웹 브라우저에 여러 스레드가 존재한다는 말을 이해하는 데 어려움이 있었다. 이번에 스레드 개념을 명확히 알게 되자, 자바스크립트 언어가 가진 특성을 보완하기 위해 브라우저들이 기울인 노력을 이해하고 공감할 수 있었다.
싱글 스레드와 달리, 멀티 스레드 환경은 태생적으로 스레드 간 경합과 동시성 이슈를 해결하기가 까다롭다는 문제가 있다. 자바스크립트는 이러한 한계에서 자유롭도록 싱글 스레드 환경에서 동작하도록 만들어졌고, 싱글 스레드가 가진 응답지연 문제는 비동기 함수로 해결했다.
운영체제 핀토스는 싱글 프로세스 멀티 스레드 방식으로 동작한다. 스레드들은 서로 우선순위를 가지고 스케줄링 되지만, 태스크에 따라서는 동시에 실행되어야 하는 경우가 있다. 두 스레드가 동일한 메모리나 파일 등의 자원에 접근하려고 할 때, 자원의 변경내역이 서로 불일치하게 되는 동시성 이슈가 발생할 수 있어 락을 걸어 동기화해준다.
또한 메모리 관리 시스템을 개발할 때는 한정된 물리 메모리 공간을 효율적으로 사용하기 위해 가상메모리라는 공간으로 추상화해서 배분했다. 물리 메모리 공간이 부족한 경우를 대비해, 별도의 스왑 공간을 두어 참조한 지 오래된 데이터 공간은 임시로 스왑 공간으로 들어가도록 하는 메모리 라이프사이클을 구현했다.
이렇게 운영체제 프로젝트를 하면서 과연 이런 것까지 알 필요가 있을까 싶다가도, 파고들수록 흥미로워 몇 시간을 내리 고민하기도 했다. 운영체제의 원리를 이해하고자 노력한 시간들은 이제 막 시작하는 개발자가 기초체력을 기를 수 있는 소중한 기회라고 생각한다. 특히 전공지식을 공부해본 적이 없는 비전공자라면 한 번쯤은 꼭 운영체제를 공부해보길 추천한다.
앞서 언급하진 않았지만, 알고리즘과 자료구조에 관한 공부도 꾸준히 했다. 알고리즘 문제는 가능하면 매일, 바쁠 때는 적어도 일주일에 1번은 꼭 풀었다. 하지만 알고리즘 공부의 중요성은 이미 알려진 것이 많아, 이번 글에서는 다루지 않았다. 그러나 자료구조를 적절히 활용하고, 다룰 수 있는 능력은 개발자에게 필수 소양이라는 것은 분명하다.
특히 비전공자로서 가장 갈증을 느낀 부분은 네트워크 이슈와 메모리 이슈가 발생했을 때, 내부적으로 어떤 일이 발생하는지 몰라서 디버깅하기가 어렵다는 점이었다. 지난 1년간 공부와 토이프로젝트 경험으로 디버깅하기 위해 세울 수 있는 가설이 많아졌고, 더 깊은 곳까지 들여다볼 수 있는 개발자에 한걸음 가까워졌다. 앞으로 새로운 언어나 프레임워크를 공부하더라도 빠르게 학습할 수 있을 것이라 믿는다.
흔히 개발자는 평생 공부하는 직업이라고 한다. 이 말에 크게 동의한다. 훌륭한 개발자들은 늘 공부한다. 덧붙여 드는 생각은 어떻게 공부해야 하는지도 중요하다는 것. 한번 공부한 내용을 빠르게 장기 기억으로 남겨야 다음으로 나아갈 수 있다. 그러기 위해선 기초가 탄탄해야 한다. 그러니 새로운 것을 공부하기 전에, 기반 지식을 활용해 토이 프로젝트를 진행해보고 내 기초가 탄탄한지 확인해보는 것도 좋은 방법이다.
마지막으로 앞으로의 계획을 말하자면 채팅 서비스를 개발해보고 싶다. 최근 몇 년 간 웹서비스의 실시간성이 증가하면서, 사용자와 사용자 간의 P2P 통신을 지원하는 WebRTC 기술이 주목받고 있다. 그만큼 채팅 서비스는 종류도 다양해지고, 성능 면에서도 고도화되고 있다. 그동안 기반 지식을 차곡차곡 쌓았으니, 다음 목표로 socket io 와 web RTC를 공부해 고도화된 채팅 기능을 구현해 볼 예정이다. 이번 글을 통해 필자가 퇴사 후 공부하고 경험했던 것들을 공유해보았다. 현재 공부 계획을 세우고 있거나, 무엇을 할지 고민하는 주니어 개발자들에게 작은 도움이 되길 바란다.
요즘IT의 모든 콘텐츠는 저작권법의 보호를 받는 바, 무단 전재와 복사, 배포 등을 금합니다.