본문 바로가기

알고리즘 기초/Basic

코딩 초보에게 드리는 제언

Photo by Chris Ried on Unsplash

요즘 코딩에 대한 관심이 많이 높아졌습니다. 일반인들을 대상으로 한 프로그래밍 강좌도 많이 생겼으며, 유튜브에서는 코딩 학원 광고를 심심치 않게 볼 수 있게 되었죠. 곧 있으면 초등학교나 중학교에서 코딩을 정규 과목으로 가르친다는 소식도 들었습니다. 대학교에서도 많은 것이 바뀌었습니다. 과거에는 공대생들만 코딩 수업을 들었다면, 요즘은 전교생이 필수 교양으로 코딩을 공부해야 하는 것으로 압니다. 컴퓨터과학 전공자의 전유물이던 코딩이 이제는 사람들이 보편적으로 갖추어야 하는 기본 소양이 되어가고 있습니다.

 

저는 이러한 일련의 변화가 매우 자연스러운 흐름이라고 생각합니다. 미래에는 지금보다 컴퓨터에 대한 의존도가 훨씬 높아질 것이고, 그 속에서 개인의 경쟁력은 컴퓨터를 자신의 분야에서 얼마큼 잘 활용할 줄 아는가로 결정될 것이기 때문이죠. 좀더 발칙한 상상을 해보자면, 가까운 미래에는 대다수의 사람들이 코딩을 할 수 있고, 또 할 수 밖에 없을 것이라고 생각합니다. 모든 전공에서는 자신들의 분야에 알맞는 방식으로 프로그래밍을 배우고, 현업에서는 이를 실지로 써먹는 시대가 오는 것이죠.

 

여하튼 코딩 기술을 갖추고 있는 사람과 그렇지 않은 사람 사이에는 상당한 수준의 경쟁력 차이가 발생한다는 점은 대부분 이견의 여지가 없으리라 생각합니다. 그러니 많은 분들이 코딩에 도전하고 있는 것이겠죠. 하지만 새로운 지식을 습득하는 과정은 언제나 지난합니다. 특히 그것이 그동안 본인이 몸담고 있던 분야와 완전히 다른 경우라면 그 과정은 더욱 험난해집니다. 게다가 "코딩"이라고 하면 매우 어렵고 힘든 것이라는 선입견도 존재하는 것 같습니다. 그렇지만 저는 사람들이 전혀 겁먹을 필요가 없다고 생각합니다. 코딩만큼 배우기 쉬운 것은 또 찾기 쉽지 않기 때문이죠.

 

이 글은 코딩을 처음 접하거나, 코딩이 너무 어렵다고 생각하는 분들께 도움이 되었으면 하는 바람에서 적은 글입니다. 물론 제가 그럴 자격이 있겠냐고 하면, 잘 모르겠습니다. 현업 개발자냐고 물어보시면 일한 경험도 거의 전무하다시피 하고, 그렇다고 백준의 문제를 뚝딱뚝딱 풀어 제낄 수 있냐고 하면 그것도 아닙니다. 다만 운이 좋게도, 중학생 때 코딩을 처음 접하고 프로그래밍을 할 수 있는 부대에서 군생활을 하고 컴퓨터과학 전공으로 졸업장을 받고 현재 컴퓨터과학을 좀더 깊이 공부하고자 하는 사람의 입장에서, 미리 알았더라면 코딩을 처음 배울 적에 보다 쉽게 이해할 수 있지 않았을까 생각하는 것들이 있습니다. 이 글에서는 그 내용들을 담았습니다.

 

이 글이 얼마나 많은 이들에게 읽힐지는 모르겠습니다만, 이 글을 읽고 코딩이 어떤 것인지를 이해하는데 조금이라도 도움이 된다면 좋겠습니다.

코딩 = 글쓰기

Photo by Aaron Burden on Unsplash

저는 코딩을 글쓰기에 비유하는 것을 좋아합니다. 글쓰기란 무엇인가요? 표준국어대사전에 따르면 '생각이나 사실 따위를 글로 써서 표현하는 일'입니다. 다시 말해, 글쓰기는 두 가지의 중요한 요소로 구성되어 있습니다.

글쓰기 = 생각 + 글

생각은 여러분이 전달하고자 하는 추상적인 내용이며 글은 그것을 표현하는 한 가지 수단입니다. 이 두 개념은 코딩에 대응되는 흥미로운 성질을 몇 가지 갖고 있습니다.

하나의 생각, 다양한 표현

Photo by Hannah Wright on Unsplash

곰곰이 따져보면, 대개 우리가 글로 전하고자 하는 바는 하나로 고정된 경우가 많습니다. 누군가를 사랑한다고 생각한다면 전 세계 어느 나라, 어느 문화권의 사람이든 <나는 너를 사랑해>에 대응하는 생각을 가질 겁니다. 하지만 이를 글로 표현하는 방식은 제각기 다릅니다. 한국어를 사용하는 사람이라면 "나는 너를 사랑해."라고 적을 테지만, 영어를 사용하는 사람이라면 "I love you."라고 적을 테니 말이죠.

 

만약 서로의 언어를 모르는 상황이라면 전혀 소통이 되지 않을 것입니다. 만약 여러분이 한국어를 접한 적도 없는 이에게 "나는 너를 사랑해"라고 편지를 보내봐야 그 사람은 아무런 감동도 받지 않을 것입니다. 번역기에 돌려 보는 수고를 한 후에야 여러분의 마음을 이해할 수 있겠죠. 하지만 아무리 번역기의 품질이 좋아졌다고 하더라도 그것이 여러분의 생각을 100% 번역해 주지는 못할 터입니다. 그러니 다른 언어를 사용하는 누군가와 제대로 소통하기 위해서는 최소한 한 쪽이 다른 한 쪽이 사용하는 언어를 배울 필요가 있습니다.

대상에 따라 달라지는 생각

여러분이 저에게 '간선에 가중치가 있는 그래프에서 한 정점에서 다른 정점까지의 최단 경로 구하는 방법'을 글로 설명한다고 해보죠.(모르셔도 괜찮습니다.) 만약 여러분이 최단 경로를 구하는 알고리즘을 잘 알고 있다면 <그냥 다익스트라 알고리즘(Dijkstra's algorithm)이나 벨만-포드 알고리즘(Bellman-Ford algorithm)을 쓰면 되지 않나?>라고 생각하실 겁니다. 다행히 제 지식의 깊이가 두 알고리즘이 어떻게 동작하고 왜 올바른 결과를 출력하며 얼마큼의 시간 동안 수행되는지를 아는 수준은 되기에 여러분의 입장에서도 더도 말고 덜도 말고 딱 그 생각대로 적어 주셔도 충분합니다.

 

하지만 글을 읽는 사람의 앎의 폭이 그만큼 깊지는 못한 경우라면 방금 생각을 그대로 글로 적었다가는 욕 먹기 십상입니다. 그러면 이제 여러분은 머릿속으로 열심히 생각을 하게 되겠죠. <그래프는 아는가?>, <가중치는 어떻게 설명해야 하지?>, <다익스트라 알고리즘의 직관적인 설명은 어떻게 해야 하지?> 등 꼬리에 꼬리를 물고 읽는 이의 수준에 맞게 여러분의 생각을 정제해 나갈 것입니다.

코딩에의 대응

코딩도 마찬가지입니다. 코딩은 결국 '사용자가 컴퓨터를 이용해 하고자 하는 바를 컴퓨터가 이해하는 글로 표현하는 일'을 의미합니다. 여기서 컴퓨터가 이해하는 글이 바로 C/C++, Java, Python과 같은 프로그래밍 언어입니다. 따라서 첫 번째 성질에서 살펴본 것처럼 컴퓨터와 소통하기 위해서는 우리는 프로그래밍 언어를 사용해야 합니다. 안타깝게도 컴퓨터는 한국어를 배울 생각이 없어 보이더라고요.

 

다음 성질은 글을 읽는 대상에 따라 글을 적을 때의 생각이 달라져야 한다는 것이었습니다. 특히 대상의 지적 수준에 따라 얼마큼 구체적으로 생각해야하는지 달라졌습니다. 그렇다면 현재 우리의 대상인 컴퓨터는 어떨까요? 컴퓨터는 똑똑할까요? 멍청할까요? 이는 다음 절에서 알아보도록 하겠습니다.

컴퓨터는 똑똑할까?

Photo by Alex Knight on Unsplash

좋은 인연으로 고등학교에서 컴퓨터과학에 대한 강연을 할 기회가 몇 번 있었습니다. 그 때마다 저는 학생들에게 이렇게 묻곤 하였죠.

과연 사람과 컴퓨터, 둘 중에 누가 더 똑똑할까요?

학생들의 대답은 다양합니다만 대표적인 답변을 몇 개 소개해 드리겠습니다. 컴퓨터가 똑똑하다고 하는 친구들은

    "요즘 컴퓨터로 거의 모든 것을 할 수 있으니 컴퓨터가 똑똑한 것 아니냐?"

고 말합니다. 그러면 저는

    "거의 모든 일이지 모든 일이 아니며, 할 수 있는 것이지 반드시 사람보다 잘한다고 말할 수는 없지 않겠느냐? 그렇다면 왜 아직 사람들은 일을 하고 있으며, 현장에는 사람 손이 필요한 곳이 있겠는가?"

고 되물어 줍니다. 반대로 사람이 똑똑하다고 생각하는 친구들이

    "사람이 컴퓨터를 만들었으니 사람이 더 똑똑한 것 아니냐?"

고 말하면, 저는

    "여러분의 부모님이 여러분을 기르시는데, 그러면 여러분은 여러분 부모님보다는 절대 똑똑해질 수 없는 것이냐? 또, 여러분의 선생님은 여러분을 가르치고 계신데, 여러분은 절대로 선생님보다 똑똑해질 수 없는 것이냐?"

라고 답합니다.

 

네, 궤변입니다. 저는 학생들 각각이 가진 생각을 모두 존중하며, 둘 중 어느 것도 답이 될 수 있겠다고 생각합니다. 대신 코딩에서 만큼은 답이 하나로 정해져 있다고 생각합니다. 바로 사람보다 컴퓨터가 멍청하다는 것이죠. 이를 학생들에게 다음과 같이 설명하고는 합니다.

 

우리들의 영원한 친구, 철수와 영희가 있습니다. 어느 날 철수와 영희는 쪽지 시험을 보고 집으로 같이 돌아오는 길이었습니다. 세 문제 중 1번 문제와 3번 문제를 맞춘 철수는 한껏 우쭐해 있었죠. 이를 자랑하고 싶은 철수는 영희에게 물었습니다.

    "영희야, 혹시 1번 문제 맞췄니?"

이에 영희는 당연하다는 표정으로 고개를 끄덕입니다. 여기에 굴할 철수가 아니죠. 철수에게는 아직 3번 문제가 남아있으니 말이죠.

    "그럼, 3번은 맞췄어?"

이번에도 영희는 두 손을 위로 보이고 어깨를 으쓱하며 뭘 그런 것을 묻느냐는 표정을 짓습니다. 이에 철수는 낙담하며 고개를 푹 숙입니다. 그 모습을 본 영희는 철수에게 한 마디 날리죠.

    "2번 문제는 왜 안 묻니?"

 

위 상황에서 과연 철수와 영희 중 누가 똑똑할까요? 물론 쪽지 시험 한 번에 학생의 지적 능력을 평가한다는 것은 매우 위험한 처사입니다만, 최소한 쪽지 시험에 한해서는 철수가 맞은 것을 영희가 모두 맞았으며 반대로 영희가 맞은 것 중에는 철수가 틀린 것이 있으므로 영희가 철수보다 똑똑하다고 말할 수 있습니다. 다시 말하면, 철수가 맞은 문항들이 영희가 맞은 문항들의 '진부분 집합'을 이루므로 영희가 똑똑한 것이죠.

 

이를 사람이 할 수 있는 일과 컴퓨터가 할 수 있는 일에 대응해 보겠습니다. 아키텍처마다 CPU가 처리할 수 있는 명령어가 달라지기는 하겠지만, 어찌 되었든 현대 컴퓨터가 처리할 수 있는 일은 사실 사칙 연산, 대소 비교, 반복, 비트 연산, 메모리에 읽고 쓰기 정도 밖에 없습니다. 그리고 이 작업들은 여러분이라면 충분히 처리할 수 있는 것들입니다.

 

반대로 사람은 할 수 있지만 컴퓨터는 할 수 없는 것들로 저는 가치 판단, 추론, 상상력을 꼽습니다. 컴퓨터는 그 자체로 옳고 그름을 판단하는 능력이 없으며, 주어진 상황에서 숨겨진 내용을 유추해 내는 능력도 없고, 완전히 새로운 무언가를 생각해 낼 깜냥도 없습니다.(이견의 여지가 있다는 것을 인정합니다. 다만, 요는 컴퓨터 그 자체가 할 수 있는 일을 논하고자 하는 것이며, 빅 데이터 및 데이터 마이닝, 인공 지능과는 결이 다른 이야기임을 알아 주시기 바랍니다.)

코딩? 멍청한 컴퓨터에게 일을 시키는 글!

지금까지의 내용을 정리해 보죠. 앞에서 코딩을 '사용자가 컴퓨터를 이용해 하고자 하는 바를 컴퓨터가 이해하는 글로 표현하는 일'이라고 정의하였습니다. 또한, 안타깝게도 컴퓨터가 한국어를 배울 마음이 없기 때문에, 컴퓨터와 소통하기 위해서는 우리가 직접 컴퓨터가 이해하는 언어인 프로그래밍 언어를 배워야 한다고 말씀드렸습니다.

 

제가 소개한 글쓰기의 두 번째 특징은 읽는 대상의 지적 수준에 따라 생각의 추상도가 달라진다는 점이었습니다. 추상적인 내용을 곧장 이해할 수 있는 독자를 상정했다면, 글도 추상적으로 적을 수 있겠지만, 아직 그러한 내용을 이해하기에는 부족한 독자도 읽을 수 있으려면 훨씬 구체적으로 글이 적혀야 합니다. 좀더 자세히 말하자면, 추상적인 생각의 큰 덩어리를 독자가 이해할 수 있는 수준의 구체적인 생각 뭉치로 쪼개고, 그제야 그 생각 뭉치들을 글로 적어야 한다는 것입니다.

 

Photo by Louis Hansel @shotsoflouis on Unsplash

코딩의 대상 독자는 컴퓨터입니다. 그리고 저는 앞에서 컴퓨터가 멍청하다고 하였죠. 사실 그냥 멍청한 수준이 아닙니다. 이해할 수 있는 것이 그저 사칙 연산이나 대소 비교, 반복과 같은 작업 뿐입니다. 예를 들어, 컴퓨터에게 \(n\)개의 수를 쥐어주고 여기서 최댓값을 찾으라고 시키면 이대로는 못 찾습니다. 앞에서부터 차례로 수를 하나씩 찾아 보면서 지금까지 본 것들 중에서 가장 큰 값과 이번에 새로 보는 값 중 더 큰 값으로 계속 유지시키라고 이야기해 주어야 합니다.

 

따라서 코딩을 하기 위해서는 컴퓨터가 할 수 있는 일이 무엇인지 아는 것이 중요합니다. 그러고는 여러분이 컴퓨터에게 시키고자 하는 일을 컴퓨터가 처리할 수 있는 뭉치로 쪼개어 생각해야 합니다. 그러면 각각의 생각 뭉치가 자연스럽게 프로그래밍 언어에 대응하게 될 것입니다. 이때 컴퓨터가 처리할 수 있는 생각 뭉치들을 저는 알고리즘(algorithm)이라고 부릅니다. 다시 말해, 앞에서 '글쓰기 = 생각 + 글'이라는 공식을 코딩에 대응하면

코딩 = 알고리즘 + 프로그래밍 언어

가 되겠습니다.

마치며 : 코딩 초보에게 드리는 제언

아마도 코딩을 어렵다고 느끼신 분들은 십중팔구 컴퓨터가 처리할 수 있는 작업의 단위를 잘 모르실 것입니다. 이는 여러분이 멍청해서 어렵게 느껴지는 것이 아닙니다. 컴퓨터에 비해 너무 똑똑해서 그런 것입니다. 가끔 말귀가 어두운 친구에게 무언가를 설명하다가 답답함을 느끼셨을 텐데, 그것과 비슷한 상황이라고 생각합니다.

 

컴퓨터가 처리할 수 있는 작업의 단위를 알지 못하면, 프로그래밍 언어가 왜 그런 식으로 만들어졌는지 이해하는 것도 어렵습니다. 물론 언어마다 추상도(level of abstraction)의 차이가 있겠지만, 프로그래밍 언어는 컴퓨터가 할 수 있는 작업 단위를 거의 일대일로 대응시킨 것에 지나지 않기 때문입니다.

 

이를 알기 위해서는 결국 컴퓨터가 무엇인지 알아야 합니다. 여러 정의가 있겠지만, 간략히 표현하자면 현대 컴퓨터는 CPU와 메모리가 있고, 메모리에서 자료를 읽어 CPU에서 처리한 후 다시 메모리에 결과를 입력하는 동작을 반복하는 기계를 통칭합니다. 이때 CPU가 할 수 있는 일은 앞에서 설명한 대로 사칙 연산이나 대소 비교 정도 밖에 없습니다.(물론 최신 CPU 및 GPU는 훨씬 다양한 명령어를 소화할 수 있지만, 본질적으로는 앞의 기본적인 연산들을 한 번에 처리하는 것뿐입니다.) 컴퓨터 시스템에 관한 내용은 나중에 기회가 되면 정리해 보도록 하겠습니다.

 

코딩, 쉽지 않습니다. 멍청한 컴퓨터의 수준까지 추상적인 생각을 쪼개는 작업이 쉬운 일은 아니기 때문입니다. 하지만, 제가 그래도 코딩이 다른 것보다 배우기 쉽다고 생각하는 이유는 더하기 빼기 정도를 할 수 있는 사람이라면 컴퓨터가 할 수 있는 작업의 전부를 이해할 수 있기 때문입니다. 물론 완전 생 초보는 "Hello world!"를 찍어 보며 프로그래밍 언어에 익숙해지는 시간이 필요하겠지만, 어느 정도 프로그래밍 언어가 눈에 익었지만 여전히 코딩이 벅찬 분들이라면, 컴퓨터가 처리할 수 있는 일이 무엇인지에 대해서 고민하시고, 그것을 단위로 여러분의 생각을 쪼개보는 연습을 해보시는 것을 추천드립니다.

 

궁금하신 점이 있으시거나, 글에 오류가 있는 경우에는 알려주시기 바랍니다. 긴 글을 읽어주셔서 고맙습니다. :)