우리는 왜 알고리즘을 공부해야 하는가?
컴퓨터의 하드웨어 연산능력은 급속히 향상되는 데다 가격은 저렴해지고 있고, 클라우드 서비스를 이용하면 이러한 자원을 필요할 때 원하는 만큼만 사용할 수 있기에 하드웨어는 더더욱 저렴하게 사용할 수 있을 것처럼 보이는데, 소프트웨어 프로그래밍은 인터넷에서 손쉽게 검색해서 사용할 수 있는 수많은 오픈소스 라이브러리가 있는 것을 사용하거나 클라우드 회사에서 제공하는 서비스를 그냥 써서 구현하면 될 것 같은데, 왜 굳이 힘들게 따분하고 현실과 동떨어진 것처럼 보이는 알고리즘을 공부할 필요가 있을까?
이 책을 펼치기 전에는 누구나 이런 의문을 가질 수 있겠지만, 책을 끝까지 읽어본 뒤에는 그 의문이 너무도 부질없는 것이었으며, 알고리즘을 모르는 것 자체가 얼마나 현실과 동떨어져 있는 것인지를 뼈저리게 느끼게 될 것이다. 우리가 ‘1+1=2’같은 프로그래밍만 취미로 만들며 살아간다면 모르겠지만, 요즘 같이 빠르게 디지털화가 되고 있는 시대에는 수천만 또는 그 이상의 동시접속자들의 까다로운 취향을 맞추기 위해 엄청난 데이터를 다차원으로 실시간으로 분석하면서, 시시각각 변화하는 그들의 요구에 끊김 없이 즉시 응답하는 온라인 서비스를 만들어야만 하고, 그것을 가능하게 하는 근간에는 효과적인 알고리즘이 있기 때문이다.
이 책에는 저자는 자신도 학창시절에는 알고리즘에 대해 어려움을 겪었다는 것을 고백하고 있다. 하지만, 회사에서 경험을 쌓은 뒤 이직을 결심하게 되면서 여러 코딩면접을 준비하게 되고, 당시 대부분의 책은 C언어 기반의 알고리즘만 다루고 있어, 저자가 직접 파이썬 기반의 알고리즘을 구현한 책을 집필까지 하게 된 것이 이 책의 탄생 배경이다.
“이 책은 알고리즘이라는 높은 산을 오르려는 독자들과 함께, 준비운동을 하고 기초체력을 기르는 것을 목표로 하고 있습니다.” (p.29)
저자는 알고리즘을 제대로 습득하기 위해서는 편법이나 요령이 아닌 정공법이 필요함을 강조한다. 그렇기에 직접 코드를 만들어 가는 실습을 중심으로 설명해주고 있다. 또한 알고리즘의 일반적 지식을 전달하는 다른 책과는 달리, 자신의 경험을 토대로 왜 알고리즘이 필요한지를 설명하면서 알고리즘을 단계별로 구현하고 따라할 수 있도록 해준다. 저자와 같이 단계별로 발생하는 에러 메세지를 의도적으로 접하게 하면서 그 원인과 해결 방법을 설명해주는 책은 지금까지 본 적이 없는 것 같다. 뿐만 아니라 각 단계별로 겪을 수 있는 여러 시행착오에 대한 자세한 설명과 격려를 통해 낙오자 없이 끝까지 완주할 수 있도록 성취감과 자신감을 갖게 해준다. 저자의 고뇌와 독자에 대한 많은 배려가 느껴지는 부분이다.
알고리즘에 대한 설명을 할 때 이해하기 쉽도록 우리에게 친근한 예제를 곁들여주고 있다. 예를 들면 스택을 하나씩 뽑아 쓰는 티슈나 통 안에 들어있는 감자칩에 비유한 것은 매우 기발하다는 생각이 들었다.
“알고리즘 문제를 풀 때는 처음에 무언가 한 줄이라도 코딩을 해봐야 시작할 수 있다. 계속 생각만 한다면 아무것도 못하고 결국 면접관에게 모른다고 해야 할 수 있습니다. 그렇게 된다면, 내가 원하는 회사에 갈 수 있는 확률이 그만큼 줄어듭니다.” (p.276)
긴장되서 아무것도 기억이 안나는 코딩테스트에서 땀을 뻘뻘 흘리며 고생하는 모습을 상상해보면, 이 한마디가 얼마나 절실히 와닿고 힘이 되는지 이해할 수 있을 것이다. 알고리즘 코딩테스트는 알고리즘을 알고 있어야만 대응할 수 있는데, 소위 말하는 기출문제뿐만 아니라 유형과 출제 빈도 등에 대해 책 전반에 걸쳐 접할 수 있다.
“실제 프로젝트에서는 코드 가독성이 중요하기 때문에 변수를 한두 번 더 사용하는 게 좋을 때도 있지만, 알고리즘 문제를 풀 때는 메모리를 적게 사용하는 것이 좋기 때문에, 공간 복잡도를 낮추기 위해서 변수는 최소한으로 사용해야 합니다.” (p.272)
이 책에서 가장 인상적인 부분은 단순히 알고리즘을 해결하는 것에서 그치지 않고, 실제 대용량의 데이터에 적용할 경우 어떠한 문제가 발생할 수 있고, 이에 대해 어떻게 대처할 수 있는지에 다양한 해법을 제시해주고 있다. 예를 들어 timestamp를 사용하여 대용량 데이터를 처리하는데 필요한 시간을 check 하고, 알고리즘의 업그레이드를 통해 어떻게 performance 개선이 이뤄지는지 다양한 관점에서 실증하는 사례를 제시해 실무에 매우 유용해 보인다. 보통 split()과 같은 스택 연산을 정규식(regular expression)을 사용하면 더 쉽고 빠르게 구현할 수 있을 것이라 생각되지만, 실제로는 그렇지 않을 수 있다는 것을 예제로 보여준다.
“해시는 앞서 말씀드린 것처럼 보안 분야에서 암호화 용도로 많이 활용됩니다. SHA-256과 같은 알고리즘이, 암호화를 위한 대표적인 해시 함수입니다.” (p.179)
“기본적으로 데이터를 전체에 골고루 뿌려줄 수 있는 좋은 해시 함수를 선택하는 것이 중요하며, 일반적으로 오픈 어드레싱(open addressing)을 활용할 경우 저장할 데이터의 두 배 정도의 공간을 미리 확보하여 충돌을 발생하는 상황에 대비하는 것이 좋습니다.” (p.197)
이러한 조언은 실무에 바탕을 둔 저자와 같은 경험에서만 나올 수 있는 것이어서 더더욱 소중하게 느껴진다.
개인적으로 이 책의 저자를 처음 접하게 된 것은 2018년 출간된 「한입에 웹 크롤링’」을 통해서이다. 웹 크롤링에 대한 국내 저자의 책이 거의 없었던 당시에 저자의 책을 읽고 매우 유용하게 잘 활용했던 기억이 있었는데, 이번에 새로운 책을 통해서 저자를 다시 만날 수 있어서 감회가 새로웠다.
코딩테스트 응시자들과 효율적 알고리즘을 구현하는 많은 개발자들에게 더할 나위 없이 좋은 책이 될 것으로 확신한다.