[CS50] CS50x 2026 - Lecture 0 - Scratch

Posted by Euisuk's Dev Log on January 9, 2026

https://youtu.be/7ZJ4oo4h8vI

참고 자료

본 영상의 이미지 출처는 위에 첨부한 유튜브 영상입니다.

서론

“AI가 코딩을 다 해주는데 왜 프로그래밍을 배워야 하나요?”

이 질문은 ChatGPT, Claude 같은 대규모 언어 모델(LLM)이 등장한 이후 가장 많이 받는 질문 중 하나입니다. 하버드 대학교의 CS50 강의를 이끄는 David Malan 교수는 이 질문에 대해 명쾌한 답변을 제시합니다. AI의 확산은 두려워할 현상이 아니라 오히려 흥미진진한 기회이며, 그럼에도 불구하고 컴퓨터 과학의 기본기는 여전히 필수적이라는 것입니다.

이 글에서는 CS50 강의의 핵심 내용을 바탕으로 왜 AI 시대에도 컴퓨터 과학 교육이 중요한지, 그리고 컴퓨터가 세상을 어떻게 표현하고 문제를 해결하는지 살펴보겠습니다.

AI 시대의 프로그래밍: 병목에서 협업으로

인간이라는 병목 현상

소프트웨어 개발 업계에서는 수십 년 동안 인간이 직접 제품을 만들고 문제를 해결해 왔습니다. 그러나 여기에는 근본적인 한계가 있었습니다. 하루 동안 일할 수 있는 시간은 제한적이고, 팀원 수도 한정되어 있습니다. 반면 해결해야 할 버그와 구현하고 싶은 기능은 항상 넘쳐났습니다. 인간 자체가 병목(bottleneck)이었던 것입니다.

AI의 등장은 이 병목 현상을 근본적으로 변화시키고 있습니다. 이제 개발자는 AI를 활용하여 코드의 버그를 찾아내거나, 새로운 기능을 추가하는 작업을 훨씬 효율적으로 수행할 수 있게 되었습니다.

핸들은 여전히 인간이 잡아야 한다

그렇다면 AI가 모든 것을 해결해 줄 수 있을까요? Malan 교수는 단호하게 “아니다”라고 답합니다. CS50이 “Computer Science”라는 이름을 가진 이유가 바로 여기에 있습니다. 이 수업은 단 한 번도 단순한 코딩 기술을 가르치는 수업이 아니었습니다. 코딩 능력은 컴퓨터 과학을 배우는 과정에서 자연스럽게 따라오는 부산물일 뿐입니다.

CS50의 진정한 목표는 사고하는 방법을 가르치는 것입니다. 입력을 받아서 올바른 출력을 만들어내는 법, 그리고 이를 위한 도구들을 마스터하는 법을 배우는 것이 핵심입니다. 여러분은 시스템에 끌려다니는 승객이 아니라, 이 시스템을 완전히 장악한 설계자가 되어야 합니다.

계산기의 교훈

이런 상황은 과거에도 있었습니다. 계산기가 처음 등장했을 때 많은 사람들이 더 이상 암산을 배울 필요가 없다고 생각했습니다. 그러나 수십 년이 지난 지금도 덧셈과 뺄셈의 원리를 이해하는 것은 여전히 가치 있는 일입니다. 마찬가지로, AI가 코드를 작성해 주더라도 그 코드가 무엇을 하는지, 어떤 문제를 해결할 수 있는지 이해하는 것은 인간의 몫입니다.

핵심 원리를 마스터한 후에는 AI라는 조수에게 기대어 문제를 해결하면 됩니다. 하지만 그 전에 기본기를 갖추는 것이 필수적입니다.

데이터의 표현: 컴퓨터는 세상을 어떻게 이해하는가

이진법의 원리

컴퓨터는 영어도, 한국어도, 우리가 일상에서 사용하는 10진법 숫자도 직접적으로 이해하지 못합니다. 컴퓨터가 이해하는 것은 오직 두 가지 상태뿐입니다. 스위치가 켜진 상태(1)와 꺼진 상태(0)입니다. 이 하나하나의 단위를 비트(bit)라고 부르며, 이는 Binary Digit의 줄임말입니다.

손가락으로 숫자를 세는 방식을 생각해 봅시다. 일반적으로 손가락 다섯 개로 1부터 5까지만 셀 수 있습니다. 하지만 손가락의 패턴을 활용하면 어떨까요? 각 손가락에 의미를 부여하여 엄지는 1, 검지는 2, 중지는 4와 같이 설정하면, 한 손으로 0부터 31까지 총 32가지 숫자를 표현할 수 있습니다.

컴퓨터도 동일한 원리를 사용합니다. 전구 세 개가 있다면, 각각 1의 자리, 2의 자리, 4의 자리를 나타냅니다. 모두 꺼져 있으면 0, 맨 오른쪽만 켜지면 1, 가운데만 켜지면 2, 둘 다 켜지면 3입니다. 이런 식으로 전구 세 개만으로 0부터 7까지 8가지 숫자를 표현할 수 있습니다.

바이트와 비트의 확장

비트를 8개 모으면 1바이트(byte)가 됩니다.

1바이트로는 0부터 255까지 총 256가지 값을 표현할 수 있습니다. 옛날 컴퓨터가 256가지 색상만 표시할 수 있었던 이유, GIF 이미지가 256색으로 제한되는 이유가 바로 여기에 있습니다.

💡 TIPS
GIF 이미지가 256색(8비트)으로 제한되는 이유는 1987년 기술 개발 당시의 저장 공간 절약 및 전송 속도 향상(효율성)이 주 목적이었기 때문입니다.

32비트와 64비트의 차이는 단순히 두 배가 아닙니다.

32비트로 표현할 수 있는 숫자는 약 40억(2322^{32}232)이며, 이는 약 4GB에 해당합니다. 과거 컴퓨터가 RAM을 4GB 이상 인식하지 못했던 이유입니다.

반면 64비트는 2642^{64}264, 즉 약 18경(18,446,744,073,709,551,616)이라는 천문학적 숫자를 표현할 수 있습니다.

비트 수를 두 배로 늘렸을 뿐인데, 표현 가능한 범위는 기하급수적으로 증가한 것입니다.

문자의 표현: ASCII와 Unicode

숫자만으로는 이메일, 문서, 메시지를 표현할 수 없습니다. 그래서 컴퓨터 과학자들은 약속을 만들었습니다. 특정 숫자를 특정 문자에 대응시키기로 한 것입니다. 이 약속이 바로 ASCII(American Standard Code for Information Interchange)입니다.

ASCII에서 65는 대문자 A, 66은 B, 67은 C를 나타냅니다. “Hi!”라는 단어는 컴퓨터 내부에서 72(H), 105(i), 33(!)이라는 숫자의 나열로 저장됩니다. 여러분이 보내는 텍스트 메시지, 이메일, 문서는 결국 수많은 0과 1이 만들어낸 숫자 덩어리일 뿐이며, 우리 눈에만 글자로 보이도록 약속되어 있는 것입니다.

ASCII는 미국에서 만들어져 영어 알파벳만 표현할 수 있다는 한계가 있었습니다. 이를 해결하기 위해 Unicode가 등장했습니다. Unicode는 8비트보다 훨씬 많은 비트를 사용하여 전 세계 모든 언어와 이모지까지 표현할 수 있습니다.

2015년 옥스포드 사전이 “기쁨의 눈물을 흘리는 얼굴” 이모지(😂)를 올해의 단어로 선정한 것은 문화적으로 이모지가 이미 문자로 인정받았음을 보여줍니다. 하지만 컴퓨터 과학의 관점에서 이모지는 그림이 아니라 약속된 번호에 불과합니다.

이미지와 영상의 표현

사진은 어떻게 표현될까요? 이미지를 극단적으로 확대하면 수많은 점들이 보입니다. 이 점 하나하나를 픽셀(pixel, Picture Element)이라고 부릅니다. 각 픽셀은 색상 정보를 가지고 있으며, 컴퓨터는 이를 RGB(Red, Green, Blue) 세 가지 숫자로 표현합니다.

예를 들어, 빨강 72, 초록 200, 파랑 0이라는 세 숫자의 조합은 특정한 노란색을 만들어냅니다. 빛의 세계에서는 빨강과 초록을 섞으면 노란색이 되고, 세 가지를 모두 최대로 섞으면 흰색이 됩니다. 이 원리를 이용하면 세 개의 숫자만으로 세상의 모든 색상을 표현할 수 있습니다.

동영상은 이 원리의 확장입니다. 정지 이미지(숫자 덩어리)를 1초에 30번 또는 60번씩 빠르게 바꿔치기하면 움직이는 것처럼 보이는 착시가 발생합니다. 결국 화면에 보이는 모든 것(얼굴, 배경, 자막)은 수백만 개의 픽셀로 구성되고, 각 픽셀은 RGB 숫자로 이루어지며, 그 숫자들은 가장 밑바닥에서 수많은 전기 신호가 켜지고 꺼지는 이진법의 춤에 불과합니다.

알고리즘: 문제 해결의 핵심

알고리즘이란 무엇인가

알고리즘(Algorithm)이라는 단어는 거창하게 들리지만, 본질적으로는 문제를 해결하는 단계별 지침입니다. 입력(input)을 받아서 원하는 출력(output)을 만들어내는 레시피와 같습니다.

전화번호부에서 특정 인물을 찾는 문제를 예로 들어 봅시다. 입력은 전화번호부이고, 원하는 출력은 “Mike Smith의 전화번호” 또는 “이 책에 Mike Smith는 없다”라는 결과입니다.

첫 번째 알고리즘: 순차 탐색

가장 단순한 방법은 첫 페이지부터 한 장씩 넘기는 것입니다. A로 시작하는 페이지, B로 시작하는 페이지… 이렇게 끈기 있게 넘기면 Mike Smith가 책에 있는 한 반드시 찾아낼 수 있습니다.

이 알고리즘은 정확(correct)합니다. 하지만 효율적(efficient)일까요?

전혀 아닙니다.

1,000페이지 책이라면 최악의 경우 1,000번을 넘겨야 합니다. 책의 크기에 비례하여 시간이 선형으로 증가하는 O(n)O(n)O(n) 알고리즘입니다.

두 장씩 넘기면 어떨까요? 속도는 두 배 빨라지지만, 찾는 이름이 건너뛴 페이지에 있을 수 있다는 치명적인 버그가 있습니다. 건너뛴 페이지를 다시 확인하는 로직을 추가해도 여전히 O(n)O(n)O(n)의 시간 복잡도를 벗어나지 못합니다.

두 번째 알고리즘: 이진 탐색

우리는 본능적으로 더 똑똑한 방법을 알고 있습니다. 전화번호부의 중간을 펴서 현재 위치가 찾는 이름보다 앞인지 뒤인지 확인하고, 필요 없는 절반을 버리는 것입니다.

중간을 펴서 T로 시작하는 페이지가 나왔다면, Mike Smith(M으로 시작)는 왼쪽에 있습니다. 오른쪽 절반은 완전히 버릴 수 있습니다. 이제 남은 절반에서 같은 과정을 반복합니다. 중간을 펴서 J가 나왔다면 M은 오른쪽에 있으므로 왼쪽 절반을 버립니다.

이 과정을 반복하면 결국 단 한 장의 종이만 남게 되고, 거기에 Mike Smith가 있습니다.

알고리즘의 구성 요소

이 전화번호부 탐색 알고리즘은 네 가지 핵심 요소로 구성됩니다.

첫째, 함수(Function)입니다.

  • “집어들어라”, “펼쳐라”와 같은 동작을 나타냅니다.

둘째, 조건문(Conditional)입니다.

  • “만약 Smith가 페이지에 있다면 전화해라”, “Smith가 왼쪽에 있다면…“과 같은 분기 로직입니다.

셋째, 불리언(Boolean)입니다.

  • “Smith가 여기 있는가?”라는 질문에 예(True) 또는 아니오(False)로 답하는 참/거짓 값입니다.

넷째, 루프(Loop)입니다.

  • “3번째 줄로 돌아가라”처럼 사람을 찾을 때까지 계속해서 반복하는 구조입니다.

시간 복잡도의 극적인 차이

두 알고리즘의 차이를 그래프로 그려보면 명확해집니다.

  • 순차 탐색은 데이터가 늘어나면 시간도 똑같이 늘어나는 직선(O(n)O(n)O(n))을 그립니다.
  • 반면 이진 탐색은 데이터가 아무리 늘어나도 시간은 거의 늘어나지 않는 로그 곡선(O(log⁡n)O(\log n)O(logn))을 그립니다.

이 차이를 극단적으로 보여드리겠습니다. 전화번호부에 40억 명(전 세계 인구 또는 Facebook/Google 사용자 수)의 이름이 있다고 가정합시다. 순차 탐색으로 Mike Smith를 찾으려면 최악의 경우 40억 번을 넘겨야 합니다.

반면 이진 탐색을 사용하면 40억을 반으로 줄이고, 20억, 10억, 5억… 이렇게 계속 반으로 줄여나가면 단 한 명이 남을 때까지 단 32번이면 충분합니다. log⁡2(4×109)≈32\log_2(4 \times 10^9) \approx 32log2​(4×109)≈32이기 때문입니다.

40억 번 대 32번. 이것은 단순한 속도의 차이가 아닙니다. 차원이 다른 것입니다. 아무리 빠른 슈퍼컴퓨터를 가져와도 비효율적인 알고리즘을 사용한다면, 효율적인 알고리즘을 사용하는 낡은 노트북을 절대 이길 수 없습니다.

Scratch를 통한 프로그래밍 핵심 개념 학습

Scratch의 교육적 가치

CS50에서는 본격적인 텍스트 기반 프로그래밍 언어(C, Python 등)에 들어가기 전에 MIT Media Lab에서 개발한 시각적 프로그래밍 언어인 Scratch를 먼저 다룹니다. Scratch를 사용하는 이유는 중괄호, 괄호, 세미콜론 같은 문법적 요소에 신경 쓰지 않고 프로그래밍의 핵심 개념에 집중할 수 있기 때문입니다.

Scratch에서는 퍼즐 조각처럼 생긴 블록들을 드래그 앤 드롭으로 연결하여 프로그램을 만듭니다. 이 블록들은 색상별로 기능이 구분되어 있어 직관적으로 어떤 종류의 기능인지 파악할 수 있습니다.

핵심 프로그래밍 개념의 시각화

Scratch를 통해 배우는 핵심 개념들은 모든 프로그래밍 언어에서 동일하게 적용됩니다.

함수(Function)는 특정 작업을 수행하는 동작입니다. Scratch의 “say” 블록은 화면에 말풍선을 표시하는 함수이며, 이 함수는 입력(argument)을 받아 부수 효과(side effect)를 발생시킵니다. 부수 효과란 화면에 무언가가 표시되거나 스피커에서 소리가 나는 것처럼 사용자가 인지할 수 있는 결과를 의미합니다.

변수(Variable)는 값을 저장하는 컨테이너입니다. 수학에서 xxx, yyy, zzz가 숫자를 담듯이, 프로그래밍에서 변수는 숫자뿐 아니라 텍스트, 사용자 입력 등 다양한 값을 저장할 수 있습니다. Scratch에서 “ask” 블록을 사용하면 사용자의 답변이 “answer”라는 변수에 자동으로 저장됩니다.

반환값(Return Value)은 함수가 컴퓨터에게 돌려주는 값입니다. 부수 효과와 달리 반환값은 사용자 눈에 보이지 않고 코드 내부에서만 사용됩니다. 이 값을 다른 함수의 입력으로 전달하여 더 복잡한 동작을 구성할 수 있습니다.

반복의 문제와 루프

고양이가 세 번 야옹하게 만들고 싶다면, 가장 단순한 방법은 “play sound meow” 블록을 세 번 복사하는 것입니다. 하지만 이 방식은 정확(correct)하지만 잘 설계되지 않은(poorly designed) 코드입니다.

왜 문제일까요? 만약 야옹 사이의 대기 시간을 1초에서 2초로 바꾸고 싶다면, 모든 곳에서 수정해야 합니다. 6개의 블록이 아니라 60개, 600개, 6000개라면 어딘가에서 반드시 실수가 발생합니다.

이 문제를 해결하는 것이 바로 루프(Loop)입니다. “repeat 3” 블록 안에 야옹 동작을 넣으면, 한 곳에서만 횟수나 대기 시간을 수정해도 전체에 적용됩니다. 코드를 모듈화(modularize)하여 공통 기능을 한 곳에 모으면 유지보수가 훨씬 쉬워집니다.

추상화와 사용자 정의 블록

더 나아가, “meow”라는 동작 자체를 하나의 블록으로 만들 수 있습니다. Scratch의 “Make a Block” 기능을 사용하면 MIT가 만들지 않은 새로운 퍼즐 조각을 직접 정의할 수 있습니다.

“define meow”라는 블록을 만들고 그 안에 소리 재생과 대기 동작을 넣으면, 이제 프로그램 어디서든 “meow” 블록 하나만 사용하면 됩니다. 구현 세부사항은 시야에서 사라지고, 우리는 “고양이가 야옹한다”는 높은 수준의 개념만 다루면 됩니다.

여기에 인자(argument)를 추가하면 더욱 강력해집니다. “meow n times”라는 블록을 만들면 야옹 횟수를 매개변수로 받아 원하는 만큼 반복할 수 있습니다. 이것이 바로 추상화(Abstraction)의 핵심입니다. 저수준의 구현 세부사항을 감추고, 고수준의 개념만으로 프로그래밍할 수 있게 해줍니다.

조건문과 이벤트 기반 프로그래밍

조건문(Conditional)은 프로그램이 상황에 따라 다르게 동작하도록 합니다. “if touching mouse pointer, then play sound meow”라는 로직은 마우스 커서가 고양이 위에 있을 때만 야옹 소리를 냅니다. 마치 고양이를 쓰다듬는 것과 같은 효과입니다.

하지만 이 조건문을 “forever” 블록 없이 사용하면 문제가 생깅니다. 프로그램은 너무 빨라서 초록 깃발을 클릭한 순간에만 조건을 확인하고 즉시 종료됩니다. 그 순간 마우스가 고양이 위에 없었다면 아무 일도 일어나지 않습니다.

“forever” 블록으로 감싸면 프로그램은 지속적으로 조건을 확인합니다. 사용자가 언제 고양이를 쓰다듬든 그 순간을 감지할 수 있습니다.

실제 프로젝트 구축: Oscar Time 게임

Malan 교수는 자신이 약 20년 전에 만든 “Oscar Time”이라는 게임을 예시로 보여줍니다. 하늘에서 떨어지는 쓰레기를 Oscar의 쓰레기통으로 드래그하여 점수를 얻는 게임입니다. 8~12시간이 걸린 이 프로젝트는 복잡해 보이지만, 실제로는 기본적인 구성 요소들의 조합입니다.

프로젝트 분해 과정:

  1. Oscar 0: 가장 단순한 버전. 코드 없이 스프라이트와 배경만 배치
  2. Oscar 1: Oscar에 조건문 추가. 마우스가 닿으면 뚜껑이 열리는 애니메이션
  3. Oscar 2: 쓰레기에 병렬 스크립트 추가. 드래그 가능하게 설정하고, 랜덤 위치에서 떨어지며, Oscar에 닿으면 다시 위로 텔레포트
  4. Oscar 3: 공통 코드를 “go to top”이라는 사용자 정의 블록으로 추출하여 중복 제거
  5. Oscar 4: score 변수 추가. 쓰레기가 Oscar에 닿을 때마다 점수 증가

이것이 바로 점진적 개발(Incremental Development)입니다. 거창한 목표가 있더라도 작은 문제부터 해결하고, 한 입 크기로 진전을 이루어 최종 솔루션에 도달합니다.

IVY’s Hardest Game: 고급 개념 적용

CS50 선배가 만든 “IVY’s Hardest Game”은 더 복잡한 게임 메커닉을 보여줍니다.

키보드 입력 처리: “listen for keyboard” 함수는 화살표 키 입력을 감지하고 스프라이트의 좌표를 변경합니다. 위쪽 화살표가 눌리면 Y를 1 증가시키고, 오른쪽 화살표가 눌리면 X를 1 증가시킵니다.

벽 충돌 처리: “feel for walls” 함수는 스프라이트가 벽에 닿았는지 확인합니다. 오른쪽 벽에 닿으면 X를 -1만큼 변경하여 튕겨 나오게 합니다. 이미 벽 위에 살짝 올라갔기 때문에 한 픽셀 뒤로 물러나는 것입니다.

자율 이동 적: Yale 스프라이트는 왼쪽 벽이나 오른쪽 벽에 닿으면 180도 회전하고, 그렇지 않으면 계속 한 걸음씩 이동합니다. 이동 속도를 10 steps로 높이면 게임이 더 어려워집니다.

추적 AI: MIT 스프라이트는 “point towards Harvard”와 “move 1 step”을 forever 루프 안에서 실행합니다. 플레이어를 계속 추적하는 적을 구현한 것입니다. 하지만 이동 속도를 10으로 높이면 시각적 버그가 발생합니다. 너무 빨리 이동하다 보니 플레이어를 지나쳐버리고, 다시 돌아오고, 또 지나치는 것을 반복하며 덜덜 떠는 것처럼 보입니다.

추상화의 계층: 0과 1에서 AI까지

컴퓨터가 이해하는 것은 오직 0과 1뿐입니다. “Hello World”를 출력하는 프로그램조차 실제로는 특정 패턴의 0과 1로 이루어져 있습니다. Intel, AMD, NVIDIA 같은 회사들은 어떤 비트 패턴이 덧셈을 의미하고, 어떤 패턴이 화면 출력을 의미하는지 결정합니다.

초창기 프로그래머들은 펀치 카드로 이 비트 패턴을 직접 작성했습니다. 하지만 이것은 너무 지루했기 때문에 누군가가 컴파일러(Compiler)를 발명했습니다. 컴파일러는 한 언어를 다른 언어로 번역하는 프로그램입니다.

C 언어로 작성된 코드는 컴파일러에 의해 기계어(0과 1)로 변환됩니다. Python 코드는 (단순화하면) C로 변환되고, 다시 기계어로 변환됩니다. 그리고 OpenAI의 API 위에서 우리는 단 10줄의 코드로 챗봇을 만들 수 있습니다.

이것이 추상화의 힘입니다. 과거의 어려운 문제들을 누군가가 이미 해결해 놓았고, 그 위에 더 쉬운 도구를 만들었고, 우리는 그 도구들을 조합하여 더 복잡한 것을 만듭니다. Scratch의 “say” 블록이 어떻게 구현되었는지, OpenAI의 GPT가 내부적으로 어떻게 작동하는지 알 필요 없이 우리는 그것들을 사용할 수 있습니다.

결론: 컴퓨터 과학의 본질

컴퓨터 과학의 본질은 컴퓨팅 사고(Computational Thinking)입니다. 이는 컴퓨터 과학에서 얻은 통찰력을 현실 세계의 문제 해결에 적용하는 사고 방식입니다. 프로그래밍은 그 과정에서 사용하는 도구일 뿐입니다.

AI 시대에도 컴퓨터 과학 교육이 중요한 이유는 명확합니다. AI는 강력한 도구이지만, 그 도구를 효과적으로 활용하려면 기본 원리를 이해해야 합니다. 데이터가 어떻게 표현되는지, 알고리즘이 어떻게 작동하는지, 왜 어떤 방법이 다른 방법보다 효율적인지를 이해해야 AI라는 조수를 제대로 활용할 수 있습니다.

우리는 시스템에 끌려다니는 승객이 아니라, 시스템을 완전히 장악한 설계자가 되어야 합니다. 그것이 바로 코딩을 하기 전에 알고리즘을 배워야 하는 이유이자, 컴퓨터 과학의 진정한 가치입니다.

CS50 유명한 강의라는 것은 예전부터 알고 있었는데, 정말 쉽게 잘 설명해주시는거 같네요 :)

본 강의는 CS50의 Introduction Section에 속하는 내용입니다. (CS50x 2026 - Lecture 0 - Scratch) 이어지는 시리즈로 CS50 코스 전체 한번 작성해보도록 하겠습니다!

읽어주셔서 감사합니다 🐾