프로그래밍을 이루는 세 가지 축에 대한 개인적 이해
들어가며
- 이 글은 지금, 스스로 프로그래밍을 바라보는 관점을 정리하기 위해 작성한 글이다. 학술적 타당성이나 새로움보다는 관점의 정립에 목적이 있다.
- 최종 수정일: 25/12/06
회사에서 RAG를 다루기도 하고, 개인적으로도 Feather라는 검색 엔진 및 경량 데이터베이스를 구축하는 과정에서 ‘프로그래밍이란 무엇일까’라는 질문을 다시 생각하게 되었다. 기술을 익히고 프로젝트를 진행하는 과정은 결국 근본적인 질문과 맞닿아 있기 때문이다.또한, 지금 내가 바라보는 프로그래밍의 기반이 무엇인지에 대한 고민도 중요할 것이다.
컴퓨터 과학을 공부하다보면, 운영체제나 데이터베이스와 같이 개별 과목이 가지는 경계 안에서 사고하는 경우가 잦다. 학문적 분류는 분명히 운영체제, 데이터베이스, 네트워크 등과 같이 잘게 나뉘어 있다. 하지만 실제 프로그래밍은 그 경계의 교차점에서 발생하는 문제를 다루는 활동이 아닐까?
이러한 이해를 위해서는 학문적 구분이 아닌, 프로그래밍을 구성하는 더 근본적인 축을 찾는 시도가 필요하다. 따라서 나는 그 축을 ‘정보’라는 관점에서 바라보려고 한다. 컴퓨터 과학의 분과에서 한 발 물러나 생각해보자.
프로그래밍을 ‘정보 흐름을 설계하고 최적화하는 활동’으로 이해하면 어떨까? 정보 시스템(Information System)에서의 도구로서 프로그래밍이 갖는 역할이라기보다는, 프로그래밍 자체에 초점을 두는 관점으로 말이다. 그렇다면 이 ‘정보 흐름’을 이루는 것이 바로 프로그래밍을 구성하는 축이 될 것이다.
본론으로 들어가기 전에, 이러한 축은 앞으로의 학습을 진행하기 위한 개인적인 관점 정립임을 다시 한 번 명시한다.
프로그래밍을 이루는 세 가지 축
프로그래밍을 이루는 세 가지 축을 통신, 저장, 검색이라고 생각해보자. 간단한 웹 어플리케이션을 예시로 삼아도 좋겠다.
우리는 흔히 웹 어플리케이션에 대해서 프론트엔드, 백엔드, 데이터베이스라는 식으로 시스템을 나누어 설명하고는 한다. 이런 구분은 구현 단계에서의 책임 분리이지, 프로그래밍을 구성하는 근본 원리는 아니다. 프론트엔드는 사용자와 상호작용하며 서버로부터 정보를 받아오고, 백엔드는 필요한 연산을 처리해 다시 정보를 돌려주며, 데이터베이스는 그 정보를 적절히 저장하고 검색할 수 있게 한다. 이렇게 바라보면 서로 다른 역할처럼 보였던 요소들이 사실은 하나의 정보 흐름 속에 통합된다.
그런데 이와 같은 흐름은 데이터베이스 내부에서도 마찬가지로 존재한다. 데이터베이스는 단순히 저장 기능에만 국한된 데이터를 보관하는 저장소가 아니다. 내부적으로도 페이지를 읽어오고(통신), 디스크에 기록하며(저장), 필요한 데이터를 찾아내는(검색) 정보 흐름을 가지고 있다.
운영체제도 마찬가지다. 운영체제는 메모리나 파일 시스템을 통해 정보를 저장하고, 프로세스 간 통신(IPC)이나 시스템 콜을 통해 정보를 전달하며, 페이지 테이블이나 파일 디렉토리를 탐색하는 방식으로 필요한 정보를 찾아낸다.
즉, 프로그래밍을 특정 기술 스택이나 계층에 종속된 활동이 아니라, 정보를 저장하고, 옮기고, 찾아내는 일의 반복과 최적화로 바라 볼 수 있다. 물론, 규모가 커짐에 따라 증가하는 복잡성을 처리하는 것은 별개의 이야기다. 연산은 통신, 저장, 검색을 다룬 후에 이야기하겠다.
통신, 저장, 검색
통신 (Communication)
통신은 정보가 한 지점에서 다른 지점으로 이동하는 과정이다.
흔히 통신이라고 하면 HTTP 요청이나 메시지 큐 같은 네트워크 인프라를 떠올린다. 하지만 사실 프로그래밍 언어의 함수 호출부터 운영체제의 프로세스 간 통신, 서버 간 RPC, 이벤트 스트림까지 모두 “정보를 전달한다”는 동일한 패턴을 공유한다.
저장 (Storage)
저장은 정보가 보존되는 과정이다.
저장이라고 하면 보통 디스크나 데이터베이스처럼 영속적인 저장매체를 떠올리지만, 저장은 훨씬 넓은 개념이라고 생각한다. 프로그램은 실행되는 동안 끊임없이 상태(state)를 유지해야 하고, 그 상태는 형태만 다를 뿐 모두 저장된 정보이다.
검색 (Retrieval)
검색은 필요한 정보를 선택하고 꺼내는 과정이다.
배열을 선형적으로 탐색하는 것부터 RDBMS의 인덱스, 그래프 탐색, 심지어 캐시 히트 여부 판단까지 모두 정보를 찾는 행위다. 규모와 맥락이 다를 뿐, 결국 프로그램은 필요한 정보가 어디에 있는지 검색하며 동작한다.
예시: 주소 결정 프로토콜(ARP)
위 세 축에 대한 예시로 ARP를 들어보고자 한다. ARP는 흔히 네트워크라는 과목 속에서 다뤄지지만, 통신-저장-검색이라는 구조를 잘 나타내는 사례다.
먼저, 운영체제는 패킷을 특정 IP 주소로 보내기 위해 해당 IP에 대응하는 MAC 주소를 검색한다. 이때 가장 먼저 ARP 테이블을 확인한다.
ARP 테이블은 IP와 MAC 주소를 매핑시키는 일종의 캐시 테이블이다. 테이블에 원하는 항목이 이미 저장되어 있으면, 운영체제는 저장된 정보를 그대로 꺼내어 사용한다.
하지만 테이블에 기록이 없다면, 운영체제는 외부에서 정보를 얻어와야 한다. 이때 이루어지는 것이 ARP 요청과 응답이라는 통신 과정이다. 네트워크에 IP 주소에 대한 MAC 주소 요청을 브로드캐스트하면, 그 장치가 자신의 MAC 주소를 유니캐스트 응답으로 알려준다. 운영체제는 이 정보를 다시 ARP 테이블에 저장하고 이용한다.
이 흐름을 따라가 보면 ARP는 주소 변환 기능을 넘어선다. 정보가 찾아지고, 전달되고, 보존되는 과정이 작은 규모에서 어떻게 반복되는지가 잘 드러나는 까닭이다. 이런 의미에서 ARP 예시는 정보 흐름을 이해하는 하나의 작은 프랙탈처럼 볼 수 있다.
세 축의 개인적 의미
이러한 관점은 내가 프로그래밍을 이해하고 학습하는 데 도움이 될 것이라고 믿는다. 왜냐하면 기술마다 새로운 개념과 구조가 등장하는 것처럼 보이지만, 그 기반에는 따라가다 보면 늘 정보를 어떻게 전달하고(통신), 보존하며(저장), 다시 찾아 사용할 것인가(검색)라는 동일한 문제로 귀결되기 때문이다.
그래서 이러한 구조를 틀로 삼아 앞으로의 프로그래밍을 이해하고자 한다. 그렇다면 새로운 기술을 배울 때도 통신, 저장, 검색을 중심으로 나누어 빠르게 맥락을 잡을 수 있다. 또한, 복잡해 보이는 시스템도 결국 이 세 가지 과정의 조합으로 추상화해 이해할 수 있다. 실제 문제를 해결하는 과정에서도 세 축에서 시작해 문제를 파악할 수 있다.
축 간의 관계
특히 흥미로운 점은 하나의 시스템이나 프로그램이 특정 축에 더 강하게 특화되거나, 혹은 하나의 축을 최적화하기 위해 다른 축과의 관계를 재설계한다는 점이다. 시스템을 이러한 시각에서 보면 기술의 목적을 더 명확히 파악할 수 있다.
예를 들어, 데이터베이스 시스템은 겉으로는 저장을 중심에 둔 기술처럼 보인다. 하지만 데이터베이스는 검색을 위해 저장 구조를 적극적으로 재배치한다. 인덱스 구조나 정렬된 페이지 레이아웃은 모두 검색을 위한 저장 방식이다. 즉, 저장이라는 축이 검색이라는 축을 위해 최적화되는 셈이다.
반대로 Kafka나 RabbitMQ 같은 메시징 시스템은 통신을 주목적으로 하지만, 높은 신뢰성을 위해 내부적으로는 로그를 지속적으로 저장한다. 이들은 통신을 강화하기 위해 저장 축을 재활용하는 구조다. 통신을 안정적으로 만들기 위해 저장을 도입하는 셈이므로, 두 축이 서로 얽혀 목적을 보완한다.
또 다른 예로, 검색 엔진은 이름만 보면 검색 중심의 시스템으로 여겨진다. 하지만 대규모 사전 구조, 역색인, 벡터 스토어 등 다양한 저장 구조 위에서 작동한다. 검색을 효율적으로 하기 위해 저장에 몸을 맡기고 있다.
이처럼 시스템마다 어느 축에 더 많은 힘을 실을지, 혹은 어떤 축을 희생해 다른 축을 강화할지가 다르다. 이 관계는 기술적 선택이나 설계상의 트레이드오프를 이해하는 데 중요한 기준점이 된다.
개인 프로젝트 Feather 경험
이러한 관점은 내가 Feather를 개발하는 과정에서도 자연스럽게 드러났다. 경량 데이터베이스로서 정보를 저장하고 다시 찾아 쓰기 위한 구조를 바닥부터 설계했던 프로젝트다. (현재 진행중이다.) 처음에는 Lucene을 더욱 가볍게 구현해보자는 학습 목적이었지만, 구현을 진행할수록 Feather 내부에서 이루어지는 대부분의 일이 결국 통신–저장–검색이라는 세 축을 중심으로 조직되어 있다고 느꼈다.
예를 들어, 문서를 인덱싱하는 과정은 겉으로 보기에는 단순히 텍스트를 처리하는 작업처럼 보인다. 하지만 실제로는 검색을 효율적으로 만들기 위해 텍스트를 토큰 단위로 분해하고, 그 토큰들을 사전 구조에 저장하며, 역색인을 구축하는 일련의 데이터 변환 과정이다. 이 과정 전부가 검색을 위해 저장을 재구성하는 것이다.
또한, 바이너리 파일 포맷(.dic, .post, .doc, .meta 등)을 설계하면서는 저장이 어떻게 검색과 연관되는지 알 수 있었다. 사전을 어떻게 구성할 것인가, 문서 ID를 어떤 방식으로 저장할 것인가, 포스팅 리스트를 어떤 구조로 정렬하고 압축할 것인가 같은 결정들은 모두 저장 방식을 통한 검색 최적화를 고민하는 과정이었다. 즉, 저장이라는 축이 보관 수단을 넘어 검색이라는 축을 위해 적극적으로 최적화되는 것이다.
재밌게도, Feather를 만들며 바닥부터 한 층씩 쌓아 올리는 경험을 통해 검색 엔진 그 이상을 배웠다. 시스템이 정보를 어떻게 전달하고, 보존하고, 찾아내는지를 살펴볼수록, 세 축이 실제 구현에서 가지는 역할을 체감할 수 있었다.
연산은 어디로?
그런데 컴퓨터라는 이름에서 드러나듯이, 연산의 중요성도 빼놓을 수 없다. 실제 프로그래밍에서는 어떤 형태로든 계산이 이루어진다. 더하기 연산, 조건 판단, 문자열 조작, 데이터 정렬 및 압축 등 모든 활동이 연산이다.
나는 연산을 독립된 축이나 더욱 근본적인 기반으로 두기보다는 정보의 흐름을 조직하고 최적화하기 위해 수행되는 변환 과정이라고 이해하고자 한다. 즉, 연산은 통신, 저장, 검색을 가능하게 하거나 더 효율적으로 만들기 위해 정보의 형태를 바꾸는 역할을 한다.
예를 들어 정렬 연산을 보자. 정렬은 그 자체로 목적이 있는 것이 아니라, 이후의 검색을 빠르게 하기 위해 데이터를 재배치하는 과정이다. 해시 함수 계산은 저장이나 검색을 일정한 시간 안에 수행하기 위해 정보를 압축하고 재구성하는 활동이다. 암호화는 정보를 안전하게 통신하기 위해 필요한 형태로 변환하는 것이다.
이렇게 보면 연산은 정보와 분리된 실체가 아니라, 정보를 다음 단계의 처리에 적합한 형태로 만드는 변환이다. 연산은 새로운 정보를 창출하기도 하고, 노이즈를 제거하거나 구조를 재배열하기도 하며, 목적에 맞게 정보를 압축하거나 확장하기도 한다. 하지만 이러한 모든 활동은 어디까지나 더 큰 흐름의 일부로서 수행된다.
그래서 나는 연산을 프로그래밍의 중심 원리나 축으로 보기보다는, 세 축 사이에서 작동하는 정보 조작의 메커니즘으로 이해하고 있다. 정보가 흐르기 위해서는 적절히 다듬어져야 한다. 따라서 연산은 구조라기보다는 정보를 발생시키는 작동 방식이라고 생각한다. 통신을 위해서는 한 지점에서 다른 지점에 맞게 변환되어야 하고, 저장을 위해서도 저장소가 원하는 틀에 맞게 재구성되어야 한다. 검색을 위해서도 정보는 식별될 수 있도록 구분되어 가공된 채로 있어야 한다.
나가며
앞으로 새로운 기술을 접하고, 시스템을 설계하거나 문제를 분석하는 경우가 잦을 것이다. 기술이 정보를 어떻게 주고받고, 어떤 방식으로 저장하고, 어떤 기준으로 다시 검색하는가라는 질문에서 시작하고자 한다. 이는 학습의 틀이기도 하지만, 프로그래밍과 시스템을 이해하고 설계하기 위한 사고 모델이기도 하다.
네트워크나 운영체제 같은 전통적인 CS 과목뿐 아니라, 분산 시스템, 보안, 머신러닝, 심지어 소프트웨어 개발 프로세스와 아키텍처 설계까지도 이 세 축의 관점으로 다시 볼 수 있다. 도메인이 무엇이든 결국 시스템은 정보를 흘려보내고, 어딘가에 보존하며, 다시 찾아 쓰도록 만들어져 있기 때문이다.
기술은 빠르게 바뀌지만, 정보가 흐르는 방식은 크게 변하지 않는다. 그래서 이러한 사고 모델은 이해의 기준점이 되어줄 것이라고 생각한다.
부록: 컴퓨터 과학을 바라보기
LLM을 이용해 위 세 축에 대해서 컴퓨터 과학 분과에 대한 시각을 정리해보았다.
각각의 역할에 대해서 반론도 충분히 가능할 것이고, 반론함으로써 오히려 컴퓨터과학 학습에 도움이 될 것이라고도 생각함에 남겨둔다.
- 네트워크
| 역할 | 설명 |
|---|---|
| 주요 축: 통신 | 정보가 한 지점에서 다른 지점으로 이동하는 방식을 규정한다. |
| 저장과의 관계 | 패킷 재전송, 버퍼링, TCP 상태 관리 등은 정확한 통신을 위해 필요한 임시 저장 구조이다. |
| 검색과의 관계 | 라우팅 테이블·ARP·DNS 등은 “다음 목적지”를 찾는 검색 과정이다. |
| 연산의 역할 | 패킷 분할, 체크섬 계산 등 통신을 위한 정보 변환 수행. |
- 운영체제
| 역할 | 설명 |
|---|---|
| 주요 축: 저장 | 메모리 관리, 파일 시스템, 프로세스 상태 등 시스템의 모든 정보 보존 담당. 관리도 이에서 시작. |
| 통신과의 관계 | 시스템 콜, IPC, 문맥 교환 등은 커널 수준의 통신 메커니즘. |
| 검색과의 관계 | 페이지 테이블 조회, inode 탐색 등 저장된 정보를 빠르게 찾기 위한 구조 포함. |
| 연산의 역할 | 스케줄링, 메모리 압축 등 저장·검색의 효율을 위한 변환 과정. |
- 자료구조
| 역할 | 설명 |
|---|---|
| 주요 축: 저장 → 검색 최적화 | 자료구조는 “검색을 빠르게 하기 위한 저장 방식의 설계”라고 해도 무방하다. |
| 통신과의 관계 | 거의 없음. 단, 분산 자료구조에서는 네트워크 통신과 결합됨. |
| 검색과의 관계 | 해시, 트리, 그래프 등은 검색 비용을 줄이기 위한 구조적 선택. |
| 연산의 역할 | 삽입·삭제·정렬 등 데이터 형태를 원하는 구조로 재배치하는 변환. |
- 알고리즘
| 역할 | 설명 |
|---|---|
| 주요 축: 연산 변환 | 정보를 더 적은 시간·공간으로 처리하기 위한 변환 과정 자체를 연구한다. |
| 저장과의 관계 | 메모리 사용량을 줄이거나 캐시 친화성을 높이는 등 저장 효율을 최적화한다. |
| 검색과의 관계 | 탐색·정렬·경로탐색 알고리즘은 검색 비용 자체를 감소시키는 기법. |
| 통신과의 관계 | 분산 알고리즘·동기화 알고리즘은 통신 비용을 직접 다룬다. |
- 프로그래밍 언어론
| 역할 | 설명 |
|---|---|
| 주요 축: 표현과 모델링(메타 구조) | 세 축이 “코드” 형태로 어떻게 표현될 수 있는지를 정의한다. |
| 통신과의 관계 | async/await, coroutine, channel 같은 통신 메커니즘의 추상화. |
| 저장과의 관계 | 상태(state), 클로저, 힙/스택 모델 등 저장 구조의 표현. |
| 검색과의 관계 | 패턴 매칭, 이름 해석(name resolution) 등 구조적 검색의 언어적 모델. |
| 연산의 역할 | 타입 시스템, 평가 전략, 최적화 등 정보 변환을 규정하는 규칙 세트. |
- 데이터베이스
| 역할 | 설명 |
|---|---|
| 주요 축: 저장 ↔ 검색의 극단적 균형 | 어떤 형태로 저장해야 검색이 빠른지를 고민하는 학문. |
| 통신과의 관계 | 분산 DB에서는 네트워크가 일급 요소가 된다. |
| 연산의 관계 | 정렬/조인/압축 등 검색을 위한 대규모 정보 변환. |
- 분산 시스템
| 역할 | 설명 |
|---|---|
| 주요 축: 통신 + 저장 일관성 | 여러 노드가 동일한 정보를 보존하고 전달하기 위해 어떤 프로토콜이 필요한지 다룬다. |
| 검색과의 관계 | 분산 해시 테이블, 샤딩된 인덱스 등. |
| 연산의 역할 | 합의(consensus), 재시도, 보정 등 정보 일관성을 유지하기 위한 복잡한 변환. |
- 컴퓨터 구조
| 역할 | 설명 |
|---|---|
| 주요 축: 저장과 검색의 실제 하드웨어 구현 | 레지스터, 캐시 계층 구조, 메모리 접근, 버스 프로토콜 등. |
| 통신과의 관계 | CPU–메모리 간 통신, 캐시 일관성 프로토콜. |
| 연산의 역할 | ALU, 파이프라인 등 정보 변환의 최저 레벨 구현. |
- 소프트웨어 공학
| 역할 | 설명 |
|---|---|
| 주요 축: 정보 흐름의 조직과 관리 | 요구사항 → 설계 → 구현 → 테스트는 정보 흐름을 단계별로 구조화하는 일. |
| 저장과의 관계 | 버전 관리, 문서화, 시스템 아키텍처 기록. |
| 통신과의 관계 | API 설계, 도메인 경계 정리. |
- 머신러닝 / 인공지능
| 역할 | 설명 |
|---|---|
| 주요 축: 검색 최적화 + 정보 변환 | 모델은 고차원 공간에서 “비슷한 것을 찾기 위한 구조”이다. |
| 저장과의 관계 | 파라미터 저장, 벡터 스토어, 학습 데이터셋. |
| 통신과의 관계 | 분산 학습, 파라미터 서버. |
| 연산의 역할 | 학습·추론 모두 거대한 정보 변환 과정. |