CS · Regex
쓸 자리와 안 쓸 자리 - 정규식이 답이 아닐 때
HTML을 정규식으로 파싱하면 왜 반드시 깨지는지, 이메일 검증 패턴이 왜 길수록 나빠지는지를 본다. 정규식이 필요해 보이는 자리 중 상당수는 위층 설계가 실패한 자리다.
패턴 하나로 찾기 4편
CS · Regex
ReDoS - 정규식 한 줄이 서버를 세운다
요청은 한 건인데 CPU가 100%가 되고 응답이 끊긴다. 에러도 안 난다. 갈림길이 겹친 정규식 하나가 입력 한 글자마다 경우의 수를 두 배로 늘리고 있어서다.
패턴 하나로 찾기 3편
CS · Regex
엔진이 하는 일 - 해보고 안 되면 되돌아간다
정규식 엔진은 패턴을 한눈에 알아보지 않는다. 골목에 들어갔다 아니면 돌아 나오기를 반복할 뿐이다. 탐욕과 게으름이 왜 다른 답을 내는지도 그 절차 위에서만 설명된다.
패턴 하나로 찾기 2편
CS · Regex
정규식 - 찾을 것을 글자 대신 규칙으로 적는다
찾을 글자를 아는 날은 contains 하나로 끝난다. 문제는 무엇을 찾는지 정확히 모를 때다. 그때 이름 대신 인상착의를 적는 것이 정규식이고, 이 시리즈는 그 전단을 들고 뛰는 엔진을 따라간다.
패턴 하나로 찾기 1편
CS · Memory
GC가 있어도 샌다 - 치워지지 않는 것들
회수기는 안 쓰는 것을 치우지 않는다. 안 닿는 것을 치운다. 이 한 마디 차이에서 자동 회수 언어의 메모리 누수가 통째로 나온다. 어떤 코드가 안 쓸 것을 붙들고 있는지, 그리고 새는 것과 그냥 많이 쓰는 것을 어떻게 가르는지 본다.
메모리의 수명 6편
CS · Memory
멈춤 시간 - 치우는 동안 프로그램은 선다
자동 회수는 공짜가 아니라 시간으로 값을 치른다. 왜 치우는 동안 프로그램을 세워야 하는지, 왜 대부분의 객체가 금방 죽는다는 관찰이 회수기의 설계를 통째로 바꿨는지, 그리고 무엇과 무엇을 맞바꾸는지 본다.
메모리의 수명 5편
CS · Memory
도달 가능성 - 닿을 수 있으면 살아 있다
세는 대신 따라가 본다. 정해진 출발점에서 참조를 타고 갈 수 있으면 살아 있고, 못 가면 버린다. 세는 방식이 못 풀던 고리가 왜 이 방식에서는 저절로 풀리는지, 그리고 그 대신 무엇을 잃는지 본다.
메모리의 수명 4편
CS · Memory
참조 세기 - 아무도 안 보면 버린다
가리키는 곳이 몇 개인지를 세다가 0이 되면 그 자리를 돌려준다. 가장 단순하고 가장 즉시적인 자동 회수 방식이다. 세는 값이 어디서 나가는지, 그리고 이 방식이 절대 못 푸는 한 가지가 무엇인지 본다.
메모리의 수명 3편
CS · Memory
손으로 돌려주기 - 두 번 놓거나 한 번도 안 놓거나
반납을 사람이 적으면 실패하는 방식이 셋이다. 안 놓거나, 두 번 놓거나, 놓고 나서 또 쓰거나. 이 단순해 보이는 일을 왜 사람이 자꾸 틀리는지, 그리고 왜 그 버그가 하필 엉뚱한 데서 터지는지를 본다.
메모리의 수명 2편
CS · Memory
메모리 회수 - 빌린 자리는 돌려줘야 한다
프로그램은 실행되는 내내 메모리를 얻는다. 얻는 건 한 줄인데 돌려주는 건 왜 어려운가. 스택은 저절로 치워지고 힙만 문제로 남는 이유부터, 안 돌려준 자리가 프로그램을 어떻게 죽이는지까지 본다.
메모리의 수명 1편
CS · Compile
빌드 - 그 한 줄이 실제로 하는 일들
빌드 명령 한 줄 뒤에는 여러 단계가 줄지어 있고, 단계마다 파일이 하나씩 남는다. 그 파일들이 남는다는 사실이 증분 빌드를 가능하게 하고, 동시에 가끔 clean을 해야 하는 이유도 만든다.
돌아가기 전에 벌어지는 일 6편
CS · Compile
링크 - 흩어진 조각을 하나로 묶는 일
프로그램은 한 파일로 만들어지지 않는다. 여러 조각이 따로 옮겨지고, 조각마다 '이 이름은 다른 데 있다'는 빈칸이 남는다. 그 빈칸을 채우는 일이 링크이고, '그 라이브러리를 못 찾겠다'는 에러가 여기서 나온다.
돌아가기 전에 벌어지는 일 5편
CS · Compile
JIT - 돌려 보고 나서 다시 옮긴다
미리 옮길 때는 알 수 없던 것이 있다. 어느 코드가 실제로 자주 도는지, 어떤 값이 실제로 들어오는지는 돌려 봐야 안다. JIT는 그 앎을 얻은 뒤에 다시 옮기는 방식이고, 우리가 '워밍업'이라 부르는 것이 그 대가다.
돌아가기 전에 벌어지는 일 4편
CS · Compile
바이트코드 - 한 번 더 접으면 무엇이 쉬워지나
소스와 기계어 사이에 한 겹을 끼워 넣으면 만들어야 할 번역기의 수가 곱셈에서 덧셈으로 바뀐다. '한 번 짜서 어디서나 돌린다'가 실제로 옮긴 것이 무엇인지, 그리고 그 대가로 무엇을 내주는지를 본다.
돌아가기 전에 벌어지는 일 3편
CS · Compile
컴파일과 인터프리터 - 미리 옮기나 그때그때 읽나
옮기는 일을 실행 전에 몰아서 하느냐, 실행하는 내내 조금씩 하느냐. 이 선택 하나가 시작 속도와 실행 속도, 그리고 오류를 언제 알게 되는지를 통째로 바꾼다. 그런데 실제 언어들은 둘 중 하나에 딱 서 있지 않다.
돌아가기 전에 벌어지는 일 2편
CS · Compile
기계어 - CPU가 아는 말은 따로 있다
우리가 쓴 코드는 CPU가 읽을 수 있는 글이 아니다. CPU가 아는 것은 수의 나열뿐이고, 그 수의 뜻마저 기계마다 다르다. 왜 소스가 그대로 돌지 못하는지, 그리고 왜 실행 파일이 아무 컴퓨터에서나 열리지 않는지가 여기서 갈린다.
돌아가기 전에 벌어지는 일 1편
CS · Compression
압축을 켤 자리와 끌 자리 - 한 장의 판단표로 접는다
압축은 늘 이득이 아니라 바이트와 CPU를 맞바꾸는 거래다. 그래서 병목이 어디냐에 따라 답이 뒤집힌다. 이 시리즈에서 본 원리를 켤지 끌지 고르는 표 한 장으로 접는다.
압축의 원리와 한계 7편
CS · Compression
안 줄어드는 것들 - 무엇이든 반으로 줄이는 프로그램은 왜 없나
압축률이 좋다는 프로그램은 많은데 '무엇이든' 줄여 준다는 것은 하나도 없다. 더 좋은 알고리즘이 아직 안 나온 게 아니라 그런 것이 있을 수 없다는 게 증명되어 있다. 그 이유가 압축의 한계를 전부 설명한다.
압축의 원리와 한계 6편
CS · Compression
손실 압축 - 되돌릴 수 없게 버린다
지금까지의 압축은 한 비트도 안 잃고 되돌렸다. 되돌리기를 포기하면 훨씬 많이 줄어든다. 사진과 음악과 영상이 그 길을 갔고, 그래서 다시 저장할 때마다 나빠진다.
압축의 원리와 한계 5편
CS · Compression
DEFLATE - 두 아이디어를 겹치면 gzip이 된다
반복 가리키기와 짧은 이름 주기는 서로 못 잡는 자리가 반대였다. 그래서 둘을 순서대로 겹친 것이 세상에서 가장 널리 쓰이는 압축이 됐다. gzip과 zip과 zlib이 서로 무엇이 다른지도 여기서 갈린다.
압축의 원리와 한계 4편
CS · Compression
허프만 코드 - 자주 나오는 것에 짧은 이름을 준다
반복이 하나도 없어도 아직 줄일 여지가 남아 있다. 모든 글자에 똑같은 길이를 주는 것이 낭비이기 때문이다. 짧은 이름을 나눠 주면서도 어디서 끊을지 헷갈리지 않게 만드는 방법을 본다.
압축의 원리와 한계 3편
CS · Compression
반복을 가리킨다 - 같은 말을 두 번 적지 않는 법
압축이 줄이는 첫째 낭비는 반복이다. 붙어 있는 반복을 개수로 접는 것에서 시작해, 아까 나온 것을 뒤돌아 가리키는 것까지 가면 zip과 gzip이 실제로 쓰는 방법이 나온다.
압축의 원리와 한계 2편
CS · Compression
압축 - 어떤 파일은 반으로 줄고 어떤 파일은 꿈쩍도 안 한다
같은 파일을 압축했는데 하나는 3분의 1이 되고 하나는 그대로다. 압축이 데이터를 마법으로 줄이는 게 아니라 원래 낭비되던 자리를 걷어내는 일이라서 그렇다. 무엇이 낭비인지부터 본다.
압축의 원리와 한계 1편
CS · Time
시각이 틀어졌을 때 - 밀린 폭만 보고 어디부터 볼지 고르기
9시간이 밀렸는지 1시간이 밀렸는지 하루가 밀렸는지는 아무렇게나 정해지지 않는다. 밀린 폭 자체가 어디가 어긋났다는 신호다. 이 시리즈를 한 장의 판단표로 접는다.
시간이라는 데이터 9편
CS · Time
시계는 흔들린다 - 경과 시간을 재는 다른 시계
컴퓨터 안에는 시계가 둘이다. 하나는 지금이 몇 시인지 말해 주지만 뒤로 갈 수 있고, 다른 하나는 몇 시인지 모르지만 절대 뒤로 안 간다. 둘을 바꿔 쓰면 걸린 시간이 음수로 나온다.
시간이라는 데이터 8편
CS · Time
ISO 8601 - 시각을 글자로 적는 법
03/04/2025가 3월 4일인지 4월 3일인지는 읽는 사람의 나라가 정한다. 그 다툼을 끝내려고 정한 꼴이 ISO 8601이고, 큰 단위부터 적는다는 규칙 하나에서 나머지 성질이 전부 따라 나온다.
시간이라는 데이터 7편
CS · Time
팻말 없는 시각 - 저장할 때 무엇이 빠지나
DB 컬럼 타입을 고르는 순간 이 값이 순간인지 달력 시각인지가 정해진다. 이름이 비슷해 헷갈리는데, 한쪽은 쓰고 읽는 사이에 값이 조용히 바뀌고 다른 쪽은 안 바뀐다.
시간이라는 데이터 6편
CS · Time
서머타임 - 없는 시각과 두 번 오는 시각
1년에 두 번, 달력에서 한 시간이 사라지고 한 시간이 두 번 온다. 존재하지 않는 시각을 저장하려 들고 같은 시각이 두 번 오는 걸 모르는 코드는 그날 새벽에만 조용히 틀린다.
시간이라는 데이터 5편
CS · Time
시간대 - 팻말은 나라가 고쳐 단다
시간대는 지도에서 잘라 낸 세로줄이 아니라 정부가 정하고 수시로 바꾸는 규칙이다. 그래서 컴퓨터는 그 규칙 목록을 따로 들고 다녀야 하고, 그 목록이 낡으면 조용히 한 시간이 어긋난다.
시간이라는 데이터 4편
CS · Time
UTC와 오프셋 - 기준선 하나와 팻말에 적힌 숫자
팻말에 적힌 +09:00은 시간대가 아니다. 그 순간의 차이만 적힌 숫자다. 둘을 같은 것으로 알고 저장했다가 반년 뒤에 한 시간이 밀리는 사고가 여기서 나온다.
시간이라는 데이터 3편
CS · Time
에폭 - 1970년부터 몇 초 흘렀나
큰 시계가 세는 수의 정체는 '정해진 어느 날부터 흐른 초'다. 왜 하필 1970년인지, 왜 2038년에 한 번 무너지는지, 그리고 같은 순간이 어떤 시스템에선 1000배 큰 수로 적히는지를 본다.
시간이라는 데이터 2편
CS · Time
시간 - 컴퓨터에 '지금'은 수 하나다
화면에 뜬 '2025년 9월 30일 오후 3시'를 컴퓨터는 그렇게 들고 있지 않다. 저장된 건 수 하나뿐이고, 날짜와 시각은 그 수에 규칙을 씌워 만든 것이다. 그 규칙이 어긋날 때 무슨 일이 벌어지는지부터 본다.
시간이라는 데이터 1편
CS · Encoding
글자가 깨졌을 때 - 증상만 보고 어디부터 볼지 고르기
깨진 글자의 생김새는 아무렇게나 정해지지 않는다. 물음표 마름모, 네모 상자, 엉뚱한 한자는 각각 다른 곳이 어긋났다는 신호다. 이 시리즈를 한 장의 판단표로 접는다.
비트에 담기는 것들 9편
CS · Encoding
Base64와 퍼센트 인코딩 - 바이트를 글자로 포장하기
글자만 지나갈 수 있는 길에 바이너리를 실어 보내야 할 때가 있다. 그럴 때 쓰는 포장이 Base64와 퍼센트 인코딩이다. 왜 크기가 늘어나는지, 그리고 왜 이걸 암호로 착각하면 안 되는지를 본다.
비트에 담기는 것들 8편
CS · Encoding
글자 수 세기 - 이모지 하나가 일곱 글자로 세지는 이유
입력창에 100자 제한을 걸었는데 사용자는 40자만 쓰고도 막힌다. 사람이 세는 글자와 컴퓨터가 세는 단위가 층마다 다르기 때문이다. 눈에 같아 보이는 두 글자가 서로 다른 데이터인 경우도 여기서 나온다.
비트에 담기는 것들 7편
CS · Encoding
UTF-8 - 상자 크기를 글자마다 다르게 고른 결과
15만 개가 넘는 번호를 바이트에 담는 방법은 여럿이었는데 UTF-8이 세상을 다 먹었다. 이긴 이유는 영리한 압축이 아니라 옛 파일을 하나도 안 건드렸다는 데 있다.
비트에 담기는 것들 6편
CS · Encoding
아스키에서 유니코드로 - 번호부를 하나로 합치기까지
처음엔 글자 128개면 충분했다. 나라마다 남은 자리를 제 맘대로 쓰면서 같은 번호가 서로 다른 글자를 가리키게 됐고, 문서는 국경을 넘을 때마다 깨졌다. 유니코드는 그 혼란을 어떻게 끝냈나.
비트에 담기는 것들 5편
CS · Encoding
부동소수점 - 0.1 더하기 0.2가 0.3이 아닌 이유
거의 모든 언어에서 0.1 + 0.2는 0.3이 아니다. 버그가 아니라 소수를 담는 방식이 그렇게 생겼다. 왜 못 맞추는지, 왜 큰 수일수록 더 성겨지는지, 그리고 돈을 여기에 담으면 안 되는 이유를 본다.
비트에 담기는 것들 4편
CS · Encoding
정수와 넘침 - 21억 다음에 오는 것
정수를 담는 칸은 자리 수가 정해져 있다. 그 칸을 넘어서면 프로그램은 멈추지 않고 조용히 이상한 값을 내놓는다. 왜 최대값 다음이 최소값인지, 왜 하필 한가운데서 터지는지를 본다.
비트에 담기는 것들 3편
CS · Encoding
비트와 바이트 - 자리가 하나 늘면 세상이 두 배가 된다
컴퓨터가 담는 칸은 켜짐과 꺼짐 둘뿐이다. 그 칸이 하나 늘 때마다 담을 수 있는 것이 두 배가 되고, 여덟 개를 묶은 바이트가 모든 이야기의 기본 단위가 된다. 16진수가 왜 굳이 끼어드는지도 여기서 풀린다.
비트에 담기는 것들 2편
CS · Encoding
인코딩 - 컴퓨터는 글자를 모른다
화면 가득한 글자를 컴퓨터는 하나도 모른다. 저장된 것은 숫자뿐이고, 그 숫자를 글자로 되돌리는 건 미리 나눠 가진 약속이다. 그 약속이 어긋날 때 무슨 일이 벌어지는지부터 본다.
비트에 담기는 것들 1편
CS · Algorithm
느릴 때 무엇부터 의심하나 - 길 고르기 한 장
이 시리즈에서 낸 길들을 한 장에 놓는다. 그리고 실제로 코드가 느릴 때 무엇부터 의심해야 하는지, 그 순서가 왜 알고리즘부터가 아닌지.
알고리즘의 갈림길 9편
CS · Algorithm
그리디 - 지금 제일 좋아 보이는 것
앞뒤 안 재고 매 순간 최선을 고르는 방법. 빠르고 코드도 짧은데, 언제 맞는지는 짐작이 아니라 증명으로만 알 수 있다.
알고리즘의 갈림길 8편
CS · Algorithm
동적 계획법 - 한 번 푼 것은 다시 안 푼다
이름이 어렵지 하는 일은 하나다. 계산한 값을 적어두고 다시 묻지 않는 것. 대신 적어둘 자리를 내줘야 하고, 진짜 어려운 건 무엇을 적을지 정하는 일이다.
알고리즘의 갈림길 7편
CS · Algorithm
분할 정복 - 쪼개서 풀고 합친다
쪼개면 왜 빨라지는가. 이득의 출처는 나누기가 아니라 합치기이고, 그 사실을 알면 n log n이 어디서 나오는지도 같이 보인다.
알고리즘의 갈림길 6편
CS · Algorithm
재귀 - 자기를 부르는 함수
재귀는 어려운 기교가 아니라 '같은 모양의 더 작은 문제'를 그대로 코드로 옮긴 것이다. 필요한 건 둘뿐이고, 무너지는 자리도 정해져 있다.
알고리즘의 갈림길 5편
CS · Algorithm
이진탐색 - 반을 버릴 수 있을 때
정렬해 두면 한 번 볼 때마다 절반을 통째로 버릴 수 있다. 그 조건이 무엇인지, 그리고 왜 이 짧은 코드가 그렇게 자주 틀리는지.
알고리즘의 갈림길 4편
CS · Algorithm
정렬 - 줄을 세우는 값과 그 대가
정렬은 그 자체로 답인 경우보다 다른 일을 싸게 만들려고 하는 경우가 많다. 방식이 갈리는 지점과, 실무에서 진짜로 물어야 하는 안정성 이야기.
알고리즘의 갈림길 3편
CS · Algorithm
완전탐색 - 다 해보는 것이 기준선이다
가장 먼저 떠올려야 할 방법은 전부 해보는 것이다. 무식해서가 아니라, 후보가 몇 개인지를 세어봐야 더 나은 방법이 필요한지 알 수 있어서다.
알고리즘의 갈림길 2편
CS · Algorithm
알고리즘 - 답이 아니라 답에 이르는 길
알고리즘은 어려운 수학 이름이 아니라 답에 이르는 절차다. 목적지가 같아도 길은 여럿이고, 무엇을 골랐느냐가 걸리는 시간을 정한다.
알고리즘의 갈림길 1편
CS · Data Structure
무엇을 언제 고르나 - 그릇 고르기 한 장
이 시리즈에서 연 그릇들을 한 장에 놓는다. 고르는 순서는 셋이고, 대부분의 문제는 그중 첫 질문에서 끝난다.
자료구조의 선택 9편
CS · Data Structure
그래프 - 관계 자체가 데이터다
노선도에서 값은 역이 아니라 역 사이의 선에 있다. 방향과 가중치와 순환이 갈리는 자리, 그리고 왜 순환을 그렇게 찾아다니는지까지.
자료구조의 선택 8편
CS · Data Structure
힙과 우선순위 큐 - 제일 급한 것만 위로
전부 줄 세우지 않고 꼭대기 하나만 약속한다. 덜 약속해서 싸지는 그릇이고, 이름이 같은 메모리의 힙과는 아무 관계가 없다.
자료구조의 선택 7편
CS · Data Structure
트리와 이진탐색트리 - 반씩 접어 들어간다
스무고개가 백만 개를 스무 번에 줄이는 원리 그대로다. 다만 질문을 잘못 고르면 스무고개가 하나씩 세는 일이 된다.
자료구조의 선택 6편
CS · Data Structure
해시테이블 - 계산해서 자리를 정한다
찾지 않고 계산한다는 발상 하나로 O(1)이 나온다. 그 대신 충돌을 떠안고, 순서를 잃고, 가끔은 O(1)이 깨진다.
자료구조의 선택 5편
CS · Data Structure
스택과 큐 - 어느 쪽에서 꺼내나
같은 더미인데 꺼내는 자리 하나만 바꿨다. 그 하나가 되돌리기와 작업 큐를 가르고, 스택 오버플로가 왜 나는지도 여기서 설명된다.
자료구조의 선택 4편
CS · Data Structure
배열과 연결리스트 - 자리를 미느냐 고리를 바꾸느냐
중간에 하나 끼워 넣을 때 한쪽은 뒤를 전부 밀고 한쪽은 고리 둘만 바꾼다. 그런데도 실무가 거의 배열을 쓰는 이유까지.
자료구조의 선택 3편
CS · Data Structure
빅오 - 몇 배로 늘어나나
빅오는 어려운 수학이 아니라 늘어나는 모양에 붙인 이름이다. 사람이 두 배로 오면 무엇이 두 배가 되고 무엇이 네 배가 되는지로 읽는다.
자료구조의 선택 2편
CS · Data Structure
자료구조 - 담는 그릇이 속도를 정한다
자료구조는 빠른 것과 느린 것으로 나뉘지 않는다. 무엇을 싸게 하고 무엇을 비싸게 할지를 고르는 일이다. 그릇을 가르는 네 가지 질문부터 본다.
자료구조의 선택 1편