jacobhan.me
CS50x 2026 · Lecture 0

0과 1에서
출발해인공지능에 닿기까지

하버드 컴퓨터과학 입문 강의 CS50의 첫 시간. 데이비드 말란(David Malan) 교수가 전구 몇 개와 전화번호부 한 권으로 풀어낸 컴퓨터의 작동 원리를, 전공자가 아니어도 따라올 수 있도록 정리했다.

출처: Harvard CS50 Lecture 0 강연: David J. Malan 2026-05-23
00 · 시작점

왜 지금, 기초인가

강의는 방 안의 코끼리, 즉 인공지능(AI, Artificial Intelligence) 이야기로 문을 연다. 말란 교수는 AI가 프로그래밍을 바꾸고 있고 앞으로 더 그럴 것이라는 점을 인정하면서도, 그것이 좋은 일이라고 말한다. 오랫동안 소프트웨어를 만드는 과정의 병목은 사람이었다. 하루는 24시간뿐이고, 팀에 사람은 한정돼 있으며, 고치고 싶은 버그와 더하고 싶은 기능은 늘 사람 수보다 많았다.

이제는 AI에게 문제를 풀어 달라고 부탁하거나, 코드 속 버그를 찾아 달라거나, 새 기능을 추가해 달라고 말할 수 있다. 병목이 풀리는 셈이다. 그런데 바로 이 지점에서 강의의 핵심 주장이 나온다. 그래도 기초는 여전히 이해해야 한다는 것이다.

CS50은 한 번도 "프로그래밍 가르치기"를 목표로 삼은 적이 없다. 프로그래밍을 배우게 되는 것은 부수 효과일 뿐, 진짜 목표는 생각하는 법, 곧 입력을 받아 올바른 출력을 만들어 내는 사고를 가르치는 것이다. 학기가 끝나면 스크래치(Scratch), C, 파이썬(Python), SQL, HTML, CSS, 자바스크립트(JavaScript) 같은 도구에 익숙해지지만, 더 중요하게는 새 언어를 스스로 배우는 능력을 갖추게 된다.

계산기가 처음 나왔을 때를 떠올려 보자. 계산기가 있어도 덧셈과 뺄셈의 원리를 아는 일은 여전히 가치가 있었다. 원리를 알아야 계산기가 내놓은 답이 말이 되는지 판단할 수 있기 때문이다.

AI와 코드의 관계도 같다. AI라는 조수에게 일을 맡기더라도, 무엇을 시켜야 하고 그 결과가 옳은지 알려면 운전석에는 사람이 앉아 있어야 한다. 비행기를 모는 조종사, 오케스트라를 이끄는 지휘자처럼.

말란 교수는 직접 약 10줄짜리 코드로 자기만의 챗봇을 만들어 보인다. 외부 회사가 제공하는 API(Application Programming Interface, 응용 프로그램 인터페이스)라는 창구를 통해, 남이 이미 만들어 둔 기능 위에 자기 프로그램을 얹는 방식이다. 핵심은 단순하다. 사용자가 던지는 질문(user prompt)과, AI에게 미리 정해 두는 행동 지침(system prompt)을 구분해 넘기면, "한 문장으로 답하라"거나 "고양이인 척하라" 같은 성격까지 부여할 수 있다는 것이다. 적은 코드로 강력한 것을 만드는 이 경험이, 다른 사람이 풀어 둔 어려운 문제 위에 올라타는 추상화의 첫 맛보기다.

01 · 정보의 표현

컴퓨터과학이란 무엇인가

강의는 챗봇이라는 화려한 결과물에서 다시 맨 처음, 0과 1로 돌아간다. 컴퓨터과학(Computer Science)은 결국 정보의 학문이다. 정보를 어떻게 표현하고, 어떻게 처리하는가의 문제다. 그리고 그 핵심에는 컴퓨팅적 사고(computational thinking), 즉 컴퓨터과학의 아이디어를 현실의 문제에 적용하는 사고가 있다.

문제 해결은 가장 단순한 그림으로 압축된다. 왼쪽에 풀고 싶은 문제인 입력(input)이 있고, 오른쪽에 도달하고 싶은 목표인 출력(output)이 있으며, 그 사이에 입력을 출력으로 바꿔 주는 비밀 상자, 이른바 블랙박스(black box)가 있다. 이 그림이 곧 문제 해결이고, 따라서 컴퓨터과학이다.

입력 Input 블랙박스 출력 Output

그런데 맥, PC, 휴대폰처럼 서로 다른 기기들이 정보를 주고받으려면, 입력과 출력을 표현하는 약속이 통일돼 있어야 한다. 영어로 할 것인가, 다른 무언가로 할 것인가. 답은 누구나 어렴풋이 안다. 컴퓨터의 알파벳은 오직 0과 1뿐이다.

02 · 진법

한 손으로 31까지 세기

왜 하필 0과 1일까. 그 답을 손가락으로 보여 준다. 우리가 평소 손가락을 세는 방식은 단항법(unary), 곧 손가락을 하나씩 펴서 1, 2, 3, 4, 5까지 세는 방식이다. 한 손이면 5가 한계다. 비효율적이다.

그런데 손가락 하나하나에 서로 다른 의미, 곧 서로 다른 자릿값을 부여하면 어떨까. 펴진 손가락의 개수가 아니라 패턴에 주목하는 것이다. 이것이 이진법(binary), 곧 2진법이다. 손가락 다섯 개의 펴짐과 접힘 조합만으로 0부터 31까지, 모두 32가지를 표현할 수 있다.

3비트로 0부터 7까지 — 자릿값은 4, 2, 1 4 2 1 0 = 000 1 = 001 2 = 010 3 = 011 4 = 100 5 = 101 6 = 110 7 = 111
전구가 켜지면 1, 꺼지면 0. 세 자리만으로 0~7을 표현한다. 자릿값(4·2·1)을 곱해 더하면 십진수가 나온다.

우리가 매일 쓰는 십진법(decimal)도 원리는 같다. 십진법은 0부터 9까지 열 개의 숫자를 쓰고, 123은 사실 100×1 + 10×2 + 1×3을 줄여 쓴 것이다. 일의 자리, 십의 자리, 백의 자리에 각각 10의 거듭제곱이라는 자릿값이 붙어 있는 셈이다.

이진법은 쓸 수 있는 숫자가 0과 1, 둘뿐인 것만 다르다. 자릿값은 10의 거듭제곱 대신 2의 거듭제곱, 곧 1·2·4·8·16으로 커진다. 왜 굳이 두 개로 줄였을까. 전기가 흐르거나(1) 흐르지 않거나(0)를 구분하는 것이, 열 단계의 전압 차이를 구분해 만드는 것보다 훨씬 단순하고 만들기 쉽기 때문이다.

전구를 떠올리자. 꺼져 있으면 0, 켜져 있으면 1. 전기는 단순하다. 흐르거나 멈추거나 둘 중 하나라, 얼마나 흐르는지까지 따질 필요가 없다.

실제 컴퓨터 안에는 전구 대신 트랜지스터(transistor)라는 작은 스위치가 수백만 개 들어 있다. 이 스위치가 켜지고 꺼지며 전기를 붙잡거나 흘려보내, 0과 1을 만들어 낸다.

비트, 바이트, 그리고 익숙한 숫자들

이진수의 한 자리, 곧 0이나 1 하나를 비트(bit, binary digit)라 한다. 비트 하나로는 큰 수를 다루기 어려워, 보통 여덟 개를 묶어 단위로 쓴다. 이 묶음이 바이트(byte)다. 킬로바이트, 메가바이트, 기가바이트 할 때의 바이트가 바로 이것이다.

비트 여덟 개를 모두 켜면 십진수로 255가 된다. 0부터 세면 모두 256가지다. 그래서 256은 컴퓨터과학에서 거듭 등장하는 숫자다. 옛날 컴퓨터가 화면에 256색만 표시할 수 있었던 것도, 8비트로 표현할 수 있는 경우의 수가 256가지였기 때문이다.

비트 수표현 가능한 가짓수셀 수 있는 최댓값
1비트20 ~ 1
8비트 (1바이트)2560 ~ 255
32비트약 43억0 ~ 약 43억
64비트약 1.8×10¹⁹천문학적 범위

요즘 맥과 PC, 휴대폰은 한 번에 64비트를 다루는 것이 흔하다. 컴퓨터가 기하급수적으로 빨라지고 메모리가 커진 데다, 인터넷에 학습할 데이터가 넘쳐 나게 된 흐름이 맞물려, 앞서 만든 챗봇 같은 도구가 가능해졌다는 것이 말란 교수의 설명이다.

03 · 문자

0과 1로 알파벳을 쓰는 법

숫자는 이해됐다. 그렇다면 영어 대문자 A는 어떻게 저장할까. 컴퓨터가 가진 것이라곤 전기와 켜고 끄는 스위치뿐인데. 답은 똑같다. 정수에 신분을 부여하는 것이다. 어떤 0과 1의 패턴, 곧 어떤 숫자를 A로 쓸지 약속만 하면 된다.

오래전 한 무리의 사람들(당시 미국인들)이 모여 그 약속을 정했다. 이것이 아스키(ASCII, American Standard Code for Information Interchange, 미국 정보 교환 표준 부호)다. 종이에 알파벳과 숫자를 짝지어 적어 둔 대응표일 뿐이다. 대문자 A는 65, B는 66, C는 67로 이어진다.

그래서 누군가 72 73 33이라는 세 바이트를 보냈다면, 대응표를 펴 보면 72는 H, 73은 I, 33은 느낌표다. 곧 "HI!"라는 메시지다. 받는 쪽 휴대폰도 같은 아스키 약속을 알고 있기에, 숫자가 아니라 글자로 보여 준다.

세 바이트가 도착하면 — "HI!" 01001000 72 H 01001001 73 I 00100001 33 ! 8비트 패턴 → 십진수 → 약속된 글자
같은 0과 1의 패턴도, 문자 메시지 앱에서는 글자로, 계산기에서는 숫자로, 포토샵에서는 색으로 해석된다. 해석 방법을 정하는 것은 프로그래머다.

이 대응표에는 재미있는 규칙이 숨어 있다. 소문자는 대문자보다 정확히 32만큼 크다. 대문자 A는 65, 소문자 a는 97이고, 그 차이는 32다. B와 b, C와 c 모두 마찬가지다. 그래서 컴퓨터가 글자를 대문자에서 소문자로 바꾸는 일은, 8비트 패턴에서 32 자리(64·32·16…에서 32의 자리)에 해당하는 비트 하나만 켜면 끝나는 단순한 산수가 된다.

04 · 더 많은 문자

아스키를 넘어 유니코드와 이모지로

아스키는 8비트, 곧 256가지만 표현한다. 영어 알파벳과 숫자, 문장 부호를 담기엔 충분하지만, 한국어를 비롯한 수많은 언어의 문자와 기호를 담기엔 턱없이 부족하다. 그래서 세상은 아스키를 포함하는 더 큰 약속, 유니코드(Unicode)로 옮겨 갔다.

유니코드는 8비트가 아니라 16비트, 24비트, 때로는 32비트를 한 문자에 쓴다. 32비트면 약 43억 가지를 표현할 수 있으니, 인류의 모든 언어를 담고도 자리가 남는다. 우리가 매일 보내는 이모지(emoji)가 폭발적으로 늘어난 이유 중 하나가 이것이다. 이모지는 사실 이미지가 아니라 문자다. 다만 그 문자를 표시하는 글꼴이 매우 화려하고 그림 같을 뿐이다.

유니코드 협회는 "기쁨의 눈물을 흘리는 얼굴"이라는 이모지가 존재한다고 약속만 정한다. 그 약속에 어떤 그림을 입힐지는 애플, 구글, 마이크로소프트가 각자 자유롭게 정한다.

그래서 같은 0과 1의 패턴인데도, 아이폰에서 본 이모지와 안드로이드에서 본 이모지가 조금씩 다르게 보인다. 글자는 같고 글꼴만 다른, 활자체의 차이인 셈이다.

05 · 색과 이미지

숫자 세 개로 색을 만들다

색도 같은 방식이다. 빨강, 초록, 파랑을 각각 얼마나 섞을지 정하면 무지개의 거의 모든 색을 만들 수 있다. 이것이 RGB(Red Green Blue, 빨강·초록·파랑) 방식이다. 세 색은 각각 1바이트, 곧 0부터 255까지의 값을 가진다. 0은 그 색이 전혀 없음, 255는 최대다.

흥미로운 점이 있다. 앞서 "HI"를 만든 72 73 33이라는 세 숫자를, 포토샵 같은 프로그램이 열면 글자가 아니라 색 하나로 해석한다. 빨강 72, 초록 73, 파랑 33을 섞은, 어두운 노란빛 색이다. 같은 0과 1이 맥락에 따라 전혀 다른 것이 된다는 사실을 다시 보여 준다.

세 빛을 겹쳐 색을 만든다 — RGB R G B 0, 0, 0 = 검정 255, 255, 255 = 흰색 72, 73, 33 = "HI"와 같은 값
빛을 모두 끄면(0,0,0) 검정, 모두 최대로 켜면(255,255,255) 흰색. 옛 영사기의 빨강·초록·파랑 렌즈를 한 점에 모으던 원리 그대로다.

화면 속 이미지를 확대하면 작은 점들이 보인다. 이 점 하나하나가 픽셀(pixel)이고, 픽셀마다 RGB 세 바이트, 곧 24비트로 색을 기록한다. 그래서 큰 사진은 점이 수천 개에 달하고, 각 점이 3바이트씩 차지하니 파일 크기가 금세 메가바이트(수백만 바이트) 단위가 된다.

한 단계 더 올라가면 영상이 된다. 영상은 1초에 30장 안팎의 이미지가 화면을 빠르게 지나가며 우리 뇌를 속여 움직임처럼 보이게 하는 것이다. 옛날 책장을 빠르게 넘기던 플립북과 똑같은 원리다. 소리 역시 음의 높이(주파수), 길이(지속 시간), 크기(진폭)를 숫자로 표현해 저장한다.

정보 표현의 핵심

  • 모든 것의 바탕은 0과 1뿐이다. 숫자든 글자든 색이든, 답은 언제나 0과 1의 패턴으로 귀결된다.
  • 같은 패턴도 맥락에 따라 다르게 해석된다. 그 해석 방법을 컴퓨터에 알려 주는 것이 프로그래머의 일이다.
  • 낮은 단계의 표현(비트) 위에 높은 단계의 표현(글자 → 이미지 → 영상)을 차곡차곡 쌓아 올린다.
06 · 문제 해결

전화번호부에서 사람 찾기

이제 정보를 표현하는 법은 갖췄다. 그렇다면 블랙박스 안, 곧 입력을 출력으로 바꾸는 과정은 어떻게 만들까. 그 비밀 소스가 알고리즘(algorithm), 곧 문제를 푸는 단계별 지시 사항이다.

전화번호부에서 "John Harvard"를 찾는다고 하자. 알파벳순으로 정렬된 1000쪽짜리 책이다. 방법은 여러 가지다.

방법 1 — 한 장씩 넘기기

맨 앞부터 한 장씩 넘긴다. 집중만 하면 언젠가 찾는다. 옳은 알고리즘이다. 하지만 끔찍하게 느리다. 운이 나쁘면 1000번을 넘겨야 한다.

방법 2 — 두 장씩 넘기기

두 장씩 넘기면 두 배 빠르다. 그런데 찾는 사람이 두 장 사이에 끼어 그냥 지나칠 위험이 있다. 이건 알고리즘의 버그(bug), 곧 오류다. 지나쳤다 싶으면 한 장 되돌아가 확인하도록 고치면 된다. 빨라지긴 했지만 본질은 방법 1과 같다.

방법 3 — 절반씩 찢어 버리기

책의 한가운데를 펼친다. M 페이지가 나왔는데 찾는 사람이 J라면, 그는 왼쪽에 있다. 그러면 오른쪽 절반을 통째로 버린다. 1000쪽이 500쪽이 된다. 남은 절반의 한가운데를 다시 펼치고, 또 절반을 버린다. 500 → 250 → 125 … 이렇게 반복하면 단 한 쪽만 남는다.

문제 크기가 커질수록 — 세 알고리즘의 소요 시간 문제 크기 (전화번호부 쪽 수) → 소요 시간 → 방법 1 n 번 방법 2 n/2 번 방법 3 log₂ n 번 0
방법 1은 쪽 수에 비례(n)해 시간이 늘어나는 직선, 방법 2는 그 절반(n/2)인 완만한 직선이다. 방법 3은 로그(log₂ n) 곡선으로, 책이 두 배 두꺼워져도 단 한 번만 더 찢으면 된다.

세 알고리즘 모두 옳다. 일은 끝낸다. 그러나 효율은 근본적으로 다르다. 두 동네가 전화번호부를 합쳐 1000쪽이 2000쪽이 됐다고 하자. 방법 1과 2는 시간이 그대로 두 배가 된다. 하지만 방법 3은 어떤가. 2000쪽을 1000쪽으로 줄이는 데 단 한 번 더 찢으면 그만이다.

좋은 코드를 짜는 일은 단지 정답을 내는 데서 끝나지 않는다. 그 일을 잘, 그리고 빠르게, 최소한의 자원으로 해내는 것이다. — 강의의 핵심 메시지

이것이 CS50이 강조하는 지점이다. 코드는 정확성(correctness)만이 아니라 설계(design)와 스타일(style)로도 평가된다. 같은 문제를 더 적은 시간, 더 적은 메모리, 더 적은 비용으로 푸는 것이 잘 설계된 코드다.

07 · 의사코드

알고리즘을 글로 풀어 쓰면

방법 3을 사람이나 로봇에게 시키려면 단계별 지시로 옮겨야 한다. 이렇게 영어나 한국어 같은 자연어로 또박또박 적은 단계별 지시를 의사코드(pseudocode, 슈도코드)라 한다. 정해진 형식은 없고, 사람마다 자기 방식으로 쓴다.

전화번호부 찾기를 의사코드로 옮기면 대략 이렇다. 책을 펴고, 한가운데를 펼치고, 페이지를 본다. 찾는 사람이 거기 있으면 전화한다. 더 앞쪽에 있으면 왼쪽 절반의 한가운데로 가서 "페이지를 본다" 단계로 돌아간다. 더 뒤쪽이면 오른쪽 절반으로 가서 역시 돌아간다.

여기서 두 가지가 드러난다. 첫째, 같은 단계로 자꾸 돌아가도 무한 반복이 아니다. 매번 문제가 절반으로 줄어들어 결국 한 쪽만 남기 때문이다. 둘째, 빠뜨리기 쉬운 경우가 하나 있다. 찾는 사람이 아예 책에 없을 때다. 이 경우를 처리하지 않으면 컴퓨터는 무한정 헤매다 멈추거나 다시 시작한다.

맥이나 PC가 갑자기 멈추고 무지개 빛 원이 빙빙 돌 때, 그건 대개 당신 잘못이 아니다. 구글이나 애플의 어느 개발자가 "이런 드문 경우도 일어날 수 있다"는 상황을 미처 처리하지 못해, 컴퓨터가 무엇을 해야 할지 모른 채 얼어붙은 것이다.

이 의사코드에는 모든 프로그래밍 언어에서 다시 만날 핵심 개념들이 들어 있다. 무언가를 해내는 동사이자 동작인 함수(function), 갈림길에서 길을 정하는 조건문(conditional), 그 갈림길에서 던지는 예/아니오 질문인 불 표현식(Boolean expression), 그리고 같은 동작을 되풀이하게 만드는 반복문(loop)이다. 불 표현식의 이름은 수학자 조지 불(George Boole)에서 왔으며, 답이 참/거짓 또는 1/0인 질문을 가리킨다.

08 · 추상화

거인의 어깨 위에 서다

컴퓨터는 데이터만 표준화한 게 아니다. 명령어도 표준화했다. 인텔(Intel), AMD, 엔비디아(Nvidia) 같은 회사들이 어떤 0과 1의 패턴이 "두 수를 더하라", "하드디스크에서 메모리로 값을 불러오라", "화면에 출력하라"를 뜻하는지 정해 둔다. 그래서 0과 1로만 된 프로그램도 화면에 "hello world"를 찍을 수 있다.

초창기 개발자들은 실제로 0과 1을, 천공 카드의 구멍으로 직접 적었다. 곧 너무 고되다는 것을 깨달은 누군가가 시간을 들여, 사람이 읽기 쉬운 언어를 0과 1로 번역해 주는 프로그램을 만들었다. 이것이 최초의 컴파일러(compiler), 곧 한 언어를 다른 언어로 옮기는 프로그램이다.

Python C 0과 1

그 위에 또 누군가가 C로 짠 프로그램으로 파이썬을 C로 바꾸고, C는 다시 0과 1로 바뀐다. 이렇게 기초 위에 더 쉬운 도구를 얹고, 그 위에 또 얹는 것이 컴퓨팅의 추상화(abstraction) 원리다.

우리는 거인의 어깨 위에 설 수 있다. 이 구성 요소들을 어떻게 쓰고 조립하는지 알기만 한다면.

강의 첫머리의 챗봇이 다시 의미를 갖는다. 말란 교수가 챗봇 내부를 직접 만들 줄 몰라도 자기 챗봇을 만들 수 있었던 이유는, 오픈AI(OpenAI) 같은 회사가 낮은 단계의 복잡한 구현을 이미 추상화해 API라는 창구로 제공했기 때문이다. 적은 코드로 강력한 것을 만드는 경험의 정체가 바로 이 추상화였던 셈이다.

09 · 닫는 글

운전석에 앉는 사람

강의 0은 0과 1이라는 가장 작은 단위에서 출발해, 숫자와 글자와 색을 거쳐, 알고리즘과 추상화를 지나, 다시 첫머리의 인공지능으로 돌아온다. 한 바퀴를 돈 셈이다.

AI가 코드를 대신 짜 주는 시대에 왜 이 기초를 배우느냐는 질문에, 강의 전체가 하나의 답을 내놓는다. 무엇을 시켜야 할지, 그 결과가 옳은지, 더 나은 방법은 없는지를 판단하려면 기초를 알아야 한다는 것이다. 도구가 아무리 강력해져도 운전석에는 사람이 앉아야 한다.

강의 0이 남긴 것

  • 컴퓨터과학은 프로그래밍이 아니라 문제 해결, 곧 입력을 올바른 출력으로 바꾸는 사고다.
  • 모든 정보는 0과 1로 표현되며, 그 해석을 정하는 것이 사람의 몫이다.
  • 같은 문제를 푸는 알고리즘은 여럿이고, 좋은 알고리즘은 정확하면서도 효율적이다.
  • 추상화 덕분에 우리는 남이 풀어 둔 어려운 문제 위에 올라타 더 큰 것을 만든다.