컴퓨터공학을 공부하다 보면 수없이 듣는 단어가 하나 있어요. 바로 알고리즘인데요. 알고리즘이라는 개념은 처음 접했을 때 코딩 테스트 문제를 풀 때나 쓰이는 용어라고만 생각했었어요. 아마 많은 분이 백준이나 프로그래머스 같은 코딩 테스트 사이트를 떠올리실 거예요.

솔직히 저도 처음엔 알고리즘이 그런 특수한 상황에서만 쓰이는 용어라고 생각했는데, 알고리즘이 단지 컴퓨터공학의 전유물이 아니라는 사실을 알고 나면 꽤 흥미로워집니다.

알고보면 일상속에 있던 알고리즘

알고리즘이라는 말을 쉽게 풀어보자면, 어떤 작업을 하기 위한 구체적인 절차나 방법을 순서대로 정리한 것을 의미합니다. 생각보다 친숙한 개념인데요. 예를 들어 볼까요? 요리를 할 때 레시피를 보고 순서대로 따라 하거나, 피아노를 칠 때 악보를 보며 곡을 연주하는 것도 알고 보면 알고리즘이에요. 레시피와 악보는 각각 음식 만들기, 음악 연주하기라는 작업의 방법을 알려주는 역할을 하니까요.

컴퓨터도 똑같습니다. 컴퓨터가 어떤 작업을 수행하는 것 역시 바로 이런 알고리즘의 원리를 따르는 거예요. 알고리즘을 컴퓨터가 이해할 수 있도록 작성된 것이 바로 프로그램이죠. 우리가 코딩을 하는 과정이 사실 알고리즘을 프로그램이라는 형태로 컴퓨터에게 전달하는 과정이라고 볼 수 있어요. 우리가 무심코 작성하는 코드가 알고 보면 꽤나 이론적인 개념을 담고 있었던 거예요.

컴퓨터보다 먼저 연구된 알고리즘

흥미로운 건, 알고리즘이란 개념이 컴퓨터보다 훨씬 오래되었다는 사실이에요. 알고리즘에 대한 연구는 원래 컴퓨터가 발명되기 한참 전부터 수학자들의 주요 관심사였어요. 특정 문제를 해결하기 위해 명확한 절차를 정의하는 일, 그것 자체가 수학적 연구였던 겁니다.

유명한 예로, 두 수의 최대공약수를 구하는 유클리드 호제법을 들 수 있는데요. 이 유클리드 호제법은 컴퓨터가 없었던 고대 그리스 시절부터 있던 알고리즘이에요. 이 오래된 수학적 알고리즘이 현대에 와서 표현 형식만 바뀐 채 프로그래밍 언어에 그대로 녹아있어요. 대표적인 예로 파이썬의 math.gcd() 함수가 있습니다. 옛날 수학자들이 알고리즘을 만들지 않았다면 우리가 편하게 사용하는 이런 함수들도 없었을 거예요.

💡
유클리드 호제법, 조금 더 쉽게 이해하기
두 자연수의 최대공약수를 찾기 위한 유클리드의 알고리즘은 다음과 같은 절차를 따릅니다.
1. 두 자연수 중 더 큰 수를 M, 작은 수를 N으로 정합니다.
2. M을 N으로 나눈 나머지를 R이라고 합니다.
3. 나머지 R이 0이 아니라면, N을 M의 자리에, R을 N의 자리에 놓고 다시 2번 과정을 반복합니다.
4. 나머지 R이 0이 되면, 그때의 작은 수 N이 바로 최대공약수가 됩니다.

파이썬의 math.gcd()도 이 알고리즘을 그대로 코드로 구현해 놓은 것이죠. 표현법만 달라졌을 뿐, 알고리즘의 핵심 원리는 같아요!

알고리즘이 가진 힘, 추상화

알고리즘을 공부하며 제일 흥미로웠던 건, 알고리즘이 추상화라는 개념과 연결된다는 점이에요. 추상화(abstraction)란 쉽게 말해 복잡한 개체의 세부적인 구성 요소를 감추고, 꼭 필요한 기능만 드러내는 것을 말해요.

일상에서 쉽게 볼 수 있는 예를 들자면, 우리가 스마트폰을 쓸 때 내부 회로나 메모리의 세부 사항은 몰라도 간단히 사용할 수 있는 이유가 바로 추상화 덕분이죠. 복잡한 내용들이 모두 감춰져 있기 때문에, 더 쉽게 이해하고 사용할 수 있는 거예요.

이런 추상화 덕분에 우리는 시스템을 설계할 때도 복잡한 부분을 간단히 나누어서 쉽게 다룰 수 있어요. 프로그래밍에서 객체 지향 프로그래밍(OOP)을 배우게 되는데, 이 역시 추상화의 좋은 사례예요. 객체 지향 프로그래밍에서는 데이터와 기능을 하나의 객체로 묶어서, 내부의 세부적인 구현 방식은 숨기고 외부에서 쉽게 사용할 수 있도록 합니다.

예를 들어 쇼핑몰 프로그램에서 결제 기능을 처리하는 객체를 만든다고 하면, 사용자는 결제를 처리하는 복잡한 로직(결제 서버 통신, 카드사 인증 등등)은 몰라도 ‘결제하기’라는 간단한 명령만으로 기능을 사용할 수 있죠. 이렇게 내부적인 세부사항을 숨기고 사용하기 쉽게 만드는 게 바로 추상화이고, 객체 지향 프로그래밍은 바로 이런 추상화를 적극 활용하고 있는 프로그래밍 방식이에요.

즉, 우리가 프로그래밍이나 시스템을 다룰 때 중요한 건 세부 요소를 모두 아는 게 아니라, 각 요소가 어떻게 상호작용하는지 아는 것이에요.

참고문헌

  • J. Glenn Brookshear•Dennis Brylow 『Computer Science An Overview, 컴퓨터 과학 총론』. 이광수•윤영기(역). 휴먼싸이언스, 2019.