프론트엔드 개발자가

알고리즘을 공부하는 이유 (w/ 코드트리)

이 포스팅은 코드트리 x 글또 블로그 챌린지 2기를 통해 코드트리 체험권을 받아 작성한 후기입니다.

코딩 테스트 이후의 알고리즘

알고리즘을 공부하는 것은 정상적인 개발자로 작동하는 데 있어 꽤나 필수적이다. 바로 코딩 테스트 때문이다. 최소한의 개발 능력을 갖고 있음을 증명하는 코딩테스트는 '과제 테스트'가 새롭게 떠오르는 요즘에도 여전히 수많은 회사의 채용 프로세스를 책임지고 있다. 그러나 프론트엔드 개발자라면 알고리즘을 공부(정확히는 코딩테스트를 준비)하면서 이러한 의문을 한 번쯤은 가져보았을 것이다.

'코딩테스트를 마치고 나서도 이 지식은 의미가 있는가?'

동일한 이유에서 나도 그동안 알고리즘 공부를 오래 미뤄왔었다. 운 좋게 코딩 테스트 없이 실무를 시작하고 나서부터는 더욱 그랬다. 그러다 코드트리라는 서비스를 알게 되고, 감사하게도 이 서비스를 체험할 기회를 얻어, 본격적인 알고리즘 공부를 처음 제대로 시작해보았다.

그리고 첫 한 달이 지났다. 아직 공부할 것이 많이 남아있지만 위의 질문에 대해 현재의 내가 내린 결론은 매우 그렇다 이다. 나는 알고리즘 공부는 프론트엔드 개발자의 실무에 확실한 도움이 될 수 있다고 꽤나 확신한다. 이러한 믿음을 갖게 된 두 가지 이유를, 코드트리라는 아주 반가운 서비스의 소개와 함께 짚어보고자 한다.

자바스크립트라는 무기를 정비하기

자바스크립트는 코딩 테스트에서 그리 선호되는 언어가 아니다. 문제 풀이의 속도도 그리 빠르지 않고, 최적화도 까다로우며, 특유의 느슨하고 포용적인 문법들은 문제풀이를 위한 간단한 밑작업도 때때로 모호하게 만든다. 뿐만 아니라 웹 프론트엔드 개발자들마저도 자바스크립트를 꺼리게 되는 중요한 이유 중 하나는 바로 브라우저라는 제약이 많은 런타임 때문이다. 물론 Node.js와 같은 독립적인 런타임 환경도 존재하지만, 웹 프론트엔드 개발의 대부분은 크롬과 같은 브라우저 환경에서 html 문서에 임베드된 자바스크립트 파일을 다루는 작업이다. 그렇기에 단순히 process.stdin으로 입력을 받는 일조차도, 웹페이지 위주로 자바스크립트를 접한 개발자들에게는 어색하게 느껴질 수 있다.

기존의 많은 서비스들은 그런 이유에서인지 자바스크립트에 친화적이지 않았다. 나를 포함하여 주변의 많은 프론트엔드 개발자들은 파이썬이나 자바, C++를 이용해 코딩 테스트를 준비했다. 이런 이유에서 프론트엔드 개발자의 알고리즘 공부는 실무로부터 더욱 멀어지고 말았나 싶기도 하다.

이번에 사용해본 코드트리의 가장 큰 차별점은 자바스크립트에 관한 자료가 충분히 제공된다는 것이다. 단순히 다양한 문제와 풀이를 제공하는 데 치중된 서비스들과 달리, 코드트리는 문제 풀이 개념에 대한 상세한 해설과 더불어, 문법에 관한 정보와 구현 예제를 언어별로 제공한다. 이 덕분에 나 역시 친숙한 자바스크립트로 자료를 읽고 연습 문제를 풀어볼 수 있었다.

자바스크립트로 알고리즘 공부를 얼마간 진행해본 소감은, 글쎄, 여전히 내 풀이의 수행시간은 남들의 배로 찍히긴 한다. 그렇지만 순위보다 더욱 중요한 깨달음을 얻기도 했다. 바로 '나는 여전히 자바스크립트를 공부해야 한다'는 사실이다. 결국 프론트엔드 개발자가 실무에 들고 뛰어드는 무기는 자바스크립트(물론 타입스크립트도 포함해서)다. 그럼에도 단순한 UI 구현 작업을, 특히 리액트와 같은 라이브러리들에 의해 통제된 환경에서 수행하다 보면 손에 익은 몇 가지 연산자나 자료형, 네이티브 메서드만을 사용하곤 한다. 이처럼 타성에 젖은 내 자바스크립트 실력은 진짜 복잡한 문제를 만났을 때 내 골치를 아프게 했다.

그러나 코드트리에서 마주한, 자바스크립트로 구현된 온갖 알고리즘들은 문제 풀이의 도구이기 이전에 신선한 영감으로 다가왔다. 우습게도 파이썬으로는 구현해보았지만 자바스크립트로는 시도해본 적 없었던 이진 탐색 트리를 구현하고, 기술 면접의 답변 이상으로는 접하지 않았던 과 스택, 를 직접 다루다 보니 실무에서도 내가 자바스크립트를 충분히 다루지 못해 제대로 풀지 못했던 문제가 많았다는 생각이 들었다. 생소한 내장 객체들의 쓰임새와 동작 원리를 알았다면 훨씬 간결하게 표현할 수 있는 로직이 많았고, 이를 기반으로 간단한 알고리즘을 구현하여 성능을 최적화할 수 있는 구문도 많았다.

좋은 프론트엔드 개발자는 자바스크립트라는 본인의 무기를 단순히 파지할 뿐만 아니라 제대로 갈고 닦을 줄 알아야한다. 자바스크립트의 능력과 한계를 명확히 알고, 그것이 애플리케이션의 동작을 어떻게 묘사하는 게 가장 적절한 지를 스스로 판단할 수 있어야 한다. 이를 점검하는 데 있어, 자바스크립트를 이용한 알고리즘 공부는 좋은 숫돌이 될 수 있다. 손에 익은 몇 가지 표현법만으로는 쉽게 정복할 수 없는 난관을 마주해야지, 우리는 비로소 우리가 가진 무기의 잠재력을 알 수 있기 때문이다.

거인과 대화하는 법을 배우기

자바스크립트 실력을 키우는 것도 이 공부의 좋은 효과겠지만, 여기서 설명을 마무리하기에는 큰 아쉬움이 남는다. 누군가 좋은 집중력으로 ECMAScript 명세를 꼼꼼히 읽는게 더 확실하지 않겠냐고 물으면 딱히 반론할 거리가 없기 때문이다. 내가 알고리즘을 공부하면서

프론트엔드의 개발 환경은 정말 많은 오픈 소스 라이브러리들에 의존하고 있다. 이미 업계의 표준으로 자리잡은 리액트는 물론이고 이제는 프로덕션 레벨에서도 활발히 사용되는 Next. 상태 관리라는 클라이언트 개발의 까다로운 문제를 다루는 Redux나 xstate. 나아가 코드의 일관성을 중시하는 수많은 개발자들의 수명을 연장시켜주는 eslint나 prettier까지도. 현업에서 사용되는 대부분의 기술, 다시 말해 우리 프론트엔드 개발자들이 발을 딛고 있는 거인들은 대부분 오픈 소스 프로젝트이다.

이 도구들은 정말 마법처럼 편리하고, 신선하게 관리되며, 누구나 능력 이상의 서비스를 개발할 수 있게 해준다. 그러나 오픈 소스이기 때문에, 즉 내가 소유하고 있는 코드가 아니라 다가오는 모두를 위해 존재하는 코드기 때문에 생기는 문제도 존재한다. 오픈 소스가 나의 서비스를 위해 맞춤 제작된 도구일 수는 없다. 이 사실이 서비스의 구현에 치명적으로 다가온다면, 우리는 도구의 일부분을 수정하는 수 밖에 없다.

이러한 수정 과정은, 많은 경우 라이브러리가 제공하는 인터페이스를 바탕으로 플러그인을 만드는 데 그칠 수도 있다. 그러나 어떤 경우에는 라이브러리를 포크해와서 내부 코드를 수정해야할 수도 있고, 심지어는 라이브러리의 코드 일부를 가져와 새로운 도구를 만들어야 할 수도 있다. 다행히도 오픈 소스는 여러분들이 가장 핵심적인 코드에 접근하는 것조차 전혀 막지 않는다. 그러나 문제가 되는 것은 우리의 코드 독해 능력이다.

여기서 우리가 가진 알고리즘 지식은 좋은 길잡이가 될 수 있다. 대표적인 예시는 바로 트리에 관한 지식이다. 이미 트리 형태로 구현된 DOM을 다루는 많은 라이브러리들은 트리를 특정 방식으로 순회하는 로직을 내부에 지니고 있다. 리액트만 봐도 그렇다. 리액트의 재조정자(reconciler)는 변경사항이 생길 때마다 리액트 엘리먼트로 구성된 트리를 비교하면서 수행되어야 할 명령의 종류와 우선순위를 파악하는데, 이를 위해 특수한 깊이 우선 탐색 로직을 내부에 탑재하고 있다. 우리가 `react-reconciler` 패키지의 코드를 마주하게 된다면, 일단은 그 복잡도와 난해함 때문에 한숨부터 나올 것이다. 그러나 눈에 익은 깊이 우선 탐색 로직이 눈에 띈다면, 우리는 이 구문을 시작점으로 해서 '어떤 트리를 순회하고 있지?', '어떤 정보를 계산하거나 수정하지?', 또는 '왜 BFS가 아닌 DFS지?'와 같은 물음을 던져가며 코드들의 의미를 차근차근히 파악할 수 있다.

비록 서비스를 구현할 때에는 알고리즘 지식을 활용할 일이 거의 없다고 할 지라도, 구현을 가능케 하는 도구의 내부에는 수많은 알고리즘이 동작하며 겉보기에 마법과도 같은 결과물을 실제로 구현하고 있다. 그리고 우리 스스로가 프론트엔드 개발자로서의 역량에 일찍 한계선을 그을 생각이 아니라면, 알고리즘으로 돌아가는 이 거인들을 언젠가는 마주하게 될 것이다. 알고리즘을 공부하는 것은, 우리에게 오래 전부터 어께를 내어주었던 거인들과 대화하는 방법을 공부하는 것이다.

갈 길은 언제나 멀다...

알고리즘은 개발자가 갖춰야 할 기본적인 역량이기도 하지만, 동시에 아무리 공부해도 끝이 없고 까다롭게 느껴지는 분야다. 이 글의 내용처럼 내가 알고리즘을 공부해야 하는 이유에 대해서는 큰 확신을 가졌지만, 내가 이를 얼마나 이해했고, 얼마나 더 공부해야 할 지는 잘 감이 오지 않는다. 지금 와서 그렇게 중요하지는 않아졌지만, '그래서 코딩 테스트를 보면 성적이 얼마나 나올까?'라는 일반적인 질문에 대해서도 명확히 답을 할 수는 없을 것 같다.

그렇지만 나는 앞으로도 계속 알고리즘을 공부할 것이다. 위의 두 가지 이유를 토대로 스스로 되물었을 때 충분히 공부한 것 같다는 확신이 들 때 까지 말이다(어쩌면 평생일 지도 모르겠다.) 그리고 이 과정에서 (아직 내가 다 마치지 못한 코드트리의 기본 커리큘럼 외에도) 서비스가 제공하는 다양한 테스트와 결과 분석 툴을 사용해보고자 하니, 다음 후기는 좀 더 풍부하고 유용한 글이 되었으면 한다.