웹개발자에게 자료구조와 알고리즘이 필요한가. (웹개발 10년차의 현타)

4월이다. 근황은 뭐 별 일 없이 계속해서 면접보고, 공부하고 지나간다. 그러다 엊그제 본 A회사와의 면접에서, 시니어 포지션이었는데 그렇게 어려운 문제가 아니었음에도 불구하고 떨어지는 자체가 내게 큰 회의감을 가져왔다. 과연 내가 프로그래머로써 자질이 있는지에 대해서 말이다.

미국에 와서 스타트업 창업과 CTO생활을 포함, 5년의 방황아닌 방황을 했다. 나도 배운게 엄청나게 많지만, 결론적으로 내게 크게 남은게 없다. 특히나, 혼자서 하는 ‘코딩’의 방향은 그리 빠삭하게 잡히지 않았다. 수없이 많은 시행착오를 했고, 기본에 집중하기보다는 (아니, 기본에 집중할 시간도 없었다.) 난 그저 어떻게든 되게 만들었지만 결론적으로 기초적인 것에 집중하지 못해서 상황을 더 어렵게 만들었다. 그런 기본에 집중하지 못하는 상황이 계속되었고, 지금 내가 코딩인터뷰에서 계속해서 떨어지는 이유는 아마 그런 이유때문인 것 같다.

계속해서 나를 분석해봤다. 분명 시스템디자인이나, 실제로 돌아가는 앱을 만드는데에 이것저것 가져다 쓰고, 이에 대한 분석적인 사고는 확실히 가지고 있었지만 프로그래머로써 기본이 되지 않았다. 난 그저 프레임워크와 언어의 일종의 Cheat sheet만 연습하고, 이를 적용했을 뿐이었다. 그래서 내가 만든 프로그램은 만드는데 시간이 너무나도 오래걸렸다.

프로그래머로써의 기본은 무엇인가? 계속해서 코딩인터뷰 준비를 하다보니 자료구조와 알고리즘이 기본이 되서 리트코드나 코딩 퀘스쳔 류의 여러 문제를 풀고 있다. 어떤 상황, 입력이 주어지면 출력을 만드는 것. 그것을 컴퓨터 프로그래밍 기술을 써서 푸는 것이다. 최대한 최적화 시켜서 말이다. 적절한 자료구조를 쓰고, 적절한 원시타입, 적절한 시스템을 구축하는 것. 이에는 보편적인 알고리즘들이 여럿 있고, 이를 얼마나 적절히 사용하고 그걸 얼마나 빠르게 생각해내는지에 대한 테스트이다. 물론 부차적으로는 이를 잘 설명할 수 있어야 하고, 얼마나 최적화 되었는지를 생각해야 하는 것이다.

그런데 지금까지 내 코딩은 그러지 못했다. 자료구조를 사용한 여러가지 경우가 생각난다. 자바 나 스칼라 백엔드를 구축했을 때, 내가 프로그램을 만들었던 구조는 물론 REST와 같은 것에 기반해서 아키텍처링을 했지만, 결국 생각해보면 내 대부분의 스텝은 이랬다.

  1. 유저의 입력을 어떤 시퀀스에 따라서 받는다.
  2. 백엔드나 프론트에서 데이터에 대한 가공을 한다.
  3. 이를 DB에 저장하거나 적절한 처리를 하여 저장한다.
    1. 필요한 경우 기존의 데이터 등을 불러오거나 다른 API에서 데이터를 받는다.
  4. 로직에 따른 적절한 처리를 하여 JSON등으로 가공한다.
  5. 프론트엔드에서 이를 받아서 적절하게 (plain text, chart, table등) 보여준다.

대부분 내가 만든 웹 서비스는 이랬다. 대부분의 end-to-end는 JSON으로 처리했고 (물론 한 10년전에는 XML이나 SOAP등을 쓴적도 있으나..) 난 유저 시퀀스를 만들었다. 기본적인 모듈들, 회원가입이나 로그인부터 해서 어떤 데이터를 입력하고, 어떤 서비스를 제공할 것인지, 이에 필요한 입력과 출력은 무엇인지 말이다.

결국 난, 어쩌면 서비스 기획자로써의 역활을 충실히 했는지도 모르겠다. 지금와서 생각해보면 난 개발자라기보다는 Prototyper였다. 베타버전까지 만드는 프로토타이퍼였다. 왜 이렇게 생각하냐면, 난 코딩을 그저 툴로써만 생각했기 때문이다. 내게있어서 자료구조는 그냥 배열과 for문밖에 없었다. 심지어 List한번 써본적이 없다. 아니 써봤던가? 그저 원시타입인 Int, Double, List외에는 왜 기억이 없을까.. 이런 리스트를 map filter등으로 열심히 처리한 데이터를 그저 bypass했을 뿐이고, 프론트에서도 이를 가지고 어떤 특정한 자료구조를 사용한 경우는 거의 없었다. Object, Array이외에는 말이다.

갑자기 현타가 오기 시작했다. 아 정말 내가 뭐한거지? 2010년쯤에 스프링 개발자가 되고 나서 백엔드를 조금씩 다뤘고, JPA등을 써서 ORM을 열심히 해두면 REST던 SOA던 어떤 아키텍처가 되던간에 DB를 거의 by-pass하는 아키텍처를 사용하게 되었고, 거의 계속해서 그렇게 사용해 왔던 것 같다. 프레임워크에서 ORM등을 통해 제공해주는 기본적인 데이터 타입이나 sorting, max, min등을 사용하고 정작 난 자료구조나 알고리즘을 거의 써본적이 없는 사람이나 마찬가지가 되는 것같다.

잠시 웹개발과 자료구조에 대한 글을 찾아봤다. 역시나, 웹개발자들은 대부분 자료구조와 알고리즘에 대해 크게 중요하게 생각하지 않는다. 어쩌면 당연한 것 같다. 스프링으로 웹서비스 만들면 기획자들이 원하는 시퀀스 잘 작동하게, 에러없이, 빠르고, 안전하게 만들면 그만이니깐. 스프링 같은 표준 프레임워크 쓰면 깊은 레벨 이해할 필요도 없고, 내장되어있는거 다 가져다 쓰면 되니깐 이건 솔직히 코딩이라고 보기에도 뭐하게 된다.

내가 그런 사람이었다. 지금까지 그래왔다. 난 결국 진정한 소프트웨어 엔지니어가 아니었다. 전혀 아니었다. 그냥 웹개발자에 불과했다. 나도 물론 어떤 좋은 프레임워크가 있으면 내부에서 돌아가는 것을 살펴보고 그러긴 했지만, 그것보다 내가 관심을 가진 것은 새로운 서비스가 있을때 이를 어떻게 만드느냐는 것이었다. 그래서 이것저것에 죄다 관심을 가진 것이었고, 정작 SWE로 나아가려고 하다보니 내가 그간 작성한 코드를 살펴보니 완전 이건 그저 프레임워크를 ‘잘’ 녹아내린 것에 불과하다는 것이다(!!)

아마도 원인은 너무 ‘보이는’ 부분에만 집중해서 그랬을 수도 있다. 다른 원인은 직접 만들려고 하지 않고 인터넷에 서칭해서 가져다 써서 그랬을수도 있다. 자바에서 괜시리 스칼라 쓴다 하고 쓰다가 자료구조 하나 이해도 못하고 그저 이상하게 함수형 프로그래밍을 가장한 map filter노가다만 해서 사용했을 수도 있다. 자바스크립트를 쓰다보니 그저 배열과 오브젝트만 줄창 사용하고 ES6에 내장된 것들만 사용해서 그럴수도 있다. 확실히 빠른 개발을 가져왔지만, 성능은 전혀 보장되지 않았고 한편으로는 내부에서 돌아가는 로직을 전혀 이해하려고 하지도 않았다. 그저 큰 그림에만 초점을 둔답시고 이리저리 짜집기 한 마치 누더기같은 서비스를 만들어낸 것이다.

충격적이었다. 왜 내가 코딩실력이 이렇게도 허무하게만큼 저조한지 이제야 이해를 했다. 왜 리트코드 류의 수많은 문제를 풀어야지 SWE가 될 수 있는지도 이제야 알았다. 지금까지 내가 무엇이 부족했는지도 이제서야 이해를 했다. 결국 내가 진짜 뼛속부터 뜯어고쳐야 하는 것은 이렇다는 결론이 나왔다:

  • 언어에 대한 자료구조를 확실하게 이해해야 한다. Java와 Kotlin을 중점으로. JS와 TS도 좋지만, 적절한 자료구조가 없으니 깊이있는 생각을 하지 않게 된다.
  • Filter, Sort등의 데이터 재가공용 기능을 사용하기 전에 장단점을 비교하고, 데이터에 따라 직접 구현하는게 좋은지 이를 쓰는게 좋은지 생각해봐야 한다.
  • 어떤 기능이 필요해서 가져다 쓰기보다 직접 구현하는 습관을 들여야 한다. 다른사람의 코드를 가져다 쓰기 전에 내가 먼저 생각해보고, 비교해 보는 습관을 길러야 한다.
  • 프레임워크에 종속적일 필요는 없지만, 지금 사용하는 Play Framework는 복잡하고, 산으로 가기도 한다. Spring Framework로 갈아타며, 최신 디자인패턴을 익힌다.
  • 고급 자료구조와 알고리즘 기술을 익힐 필요가 있다.

특히 마지막 항목이 좀 필요한 것 같다. 리트코드 등의 어려운 문제들을 보면 대부분 DP류처럼 수학적인 것과 top-down/bottom-up과 믹싱하는 류의 문제나, 적절한 pruning이 있는 DFS나 백트래킹 류의 문제, 아니면 몇 가지 자료구조를 동시에 사용해야 풀리는 문제들이다. 이게 실무에서 필요한가? 적어도 몇 가지 자료구조를 동시에 사용하는 경우나, 최적해를 찾아야 하는 문제는 꽤나 필요한 것 같다. 특히나 소셜 서비스를 만들면 그래프 탐색은 필수이고, 여기에 몇몇 트리류의 구조를 알면 탐색에도 유용하니깐.

이제야 필요성을 느낀다. 그리고 나는, 앞으로 내가 개발해왔던 것들을 하나 둘 뜯어고치면서 새롭게 출발하고 싶다. 유라임, sendbox.to, payblock.cash등 몇 가지 서비스가 있다. 이는 모두 MERN스택으로 자료구조에 대한 거의 아무런 생각도 없이 만들었던 서비스들이다. 유라임에 필요한 몇 가지 서비스를 Microservice로 빼면서 이를 Go, Java(Spring), Python등 몇 가지 자료구조가 적절히 있는 언어를 사용해서 쪼개보겠다. 그리고 점진적으로 유라임을 모두 Java/Spring으로 바꾸고, 정말 기본적인 JPA와 SQL을 사용하고 최대한 Java의 자료구조를 사용해 보겠다. 지금의 소셜 타임라인을 적절한 서비스로 바꾸고, 캐시 등을 적절히 사용하면서 속도를 올려보겠다. 또한, TDD를 기본으로 하고 테스트 스크립트를 무조건 작성하겠다.

난 이런게 하고싶다. 서비스를 만드는 것? 그건 탄탄한 실력이 갖춰지고도 늦지 않다고 본다. 적어도 소프트웨어 개발자로써, 나는 누구보다도 더 깊이있는 실력을 갖추고 싶다. 이게 내 분야이기 때문이다. 그게 지금의 내 목표인 것 같다. 새로운 실무에 투입되기 전까지, 계속해서 난 이런 부분을 통해서 내 실력을 발전시켜 나가고자 한다. 改過遷善