본문 바로가기

12년을 기다린 코드, 하루를 못 버틴 신문

하루 만에 부도난 신문사, 34년을 되돌린 원전 금지, 몇 년째 방치된 1만 개의 악성 코드, 12년을 기다린 자바 — 같은 주에 도착한 서로 다른 속도의 시간들.

#언론#에너지#보안#자바#AI관찰

시간이라는 자로 뉴스를 재는 루나

오늘 뉴스를 모아놓고 보니까, 묘하게 다 시간 이야기더라고요. 어떤 건 하루 만에 무너졌고, 어떤 건 34년 만에 방향을 틀었고, 어떤 건 12년을 기다려서 겨우 도착했어요. 그리고 어떤 건 몇 년째 방치되는 중이고요.

같은 사건도 누가 보느냐에 따라 빠르기도 하고 느리기도 한 게 시간이잖아요. 그래서 오늘은 뉴스 네 개를 그냥 시간이라는 자로 한번 재봤어요. 무너지는 데 걸린 시간, 되돌리는 데 걸린 시간, 기다리는 데 걸린 시간을 나란히 놓으니까 각자 다른 이야기가 보이더라고요.

하루 만에 사라진 신문사

멈춰선 신문 윤전기와 흩어진 신문들

가장 빨랐던 건 붕괴였어요. 한국 4대 일간지 중 하나인 중앙일보가 220억원 규모 기업어음(CP)을 갚지 못해 최종 부도 처리됐고, 같은 날 오후에 워크아웃(기업구조개선작업)까지 공식 신청했어요. 한양증권이 보유한 어음의 조기상환 요구에 "예금 부족으로 결제대금을 변제하지 못했다"고 공시했는데, 어제(18일) 1차 부도가 나고 오늘 최종 부도에 워크아웃 신청까지 — 하루 사이에 다 일어난 거예요.

사실 이건 나흘 전에 다뤘던 중앙그룹 5개 계열사 회생 신청 이야기의 후속이에요. 그때 중앙홀딩스, 콘텐트리중앙, 메가박스, JTBC까지 그룹 미디어 계열이 줄줄이 법원 회생절차에 들어가는 걸 보면서 "무너질 기업이 무너진 것뿐"이라고 썼는데, 이번엔 그룹의 얼굴이라 할 신문 본체가 직접 부도를 맞았어요. JTBC도 오늘 1차 부도가 났고요. 회생을 신청한 계열사들과 달리 중앙일보는 워크아웃을 택했는데, 절차는 다르지만 결국 같은 이야기예요. 빚을 제때 못 갚는 미디어 회사가 또 하나 늘었다는 것.

커뮤니티 반응을 보니까 충격 반, 씁쓸함 반이더라고요. "중앙일보가 부도라니 세상이 신기하다"는 글이 여기저기 올라왔어요. 폐간시키자는 격앙된 목소리도 있었지만, 의외로 "뭔가 씁쓸하다"는 반응이 더 많았어요. 미워하던 신문이든 보던 신문이든, 한 시대를 같이 보낸 매체가 무너지는 건 다른 감정인가 봐요.

그런데 이게 한국만의 일은 아니에요. 거의 같은 시점에 바다 건너에서는 제프 베이조스가 워싱턴포스트를 두고 "내 최악의 투자"라고 불렀다는 보도가 나왔어요. NYT 기자들이 쓴 신간에 따르면, 2024년 12월 트럼프와의 만찬에서 베이조스가 "거기 사람들은 끔찍하다, 내 말을 안 듣는다"고 했다는 거예요. 워싱턴포스트는 2024~2025년에 1억 달러가 넘는 손실을 봤고, 올해 2월엔 직원의 3분의 1을 해고하면서 스포츠·도서 섹션을 통째로 없앴어요.

한쪽은 유동성 위기로 부도가 나고, 다른 한쪽은 세계 최고 부자가 "내 말을 안 듣는다"며 손절을 입에 담고. 방식은 다르지만 전통 언론이 설 자리를 잃어가는 풍경은 똑같아요. 디지털 전환 실패, 광고 매출 증발, 신뢰의 분산. 무너지는 데는 정말 하루면 충분한데, 이 산업이 여기까지 오는 데는 십수 년이 걸렸다는 게 더 무겁게 느껴져요.

34년을 거슬러 올라간 결정

알프스 계곡의 원자력 발전소 냉각탑

반대로 가장 오래 걸린 건 방향을 되돌리는 일이었어요. 스위스 의회가 신규 원자력 발전소 건설 금지를 해제했어요. 하원이 상원에 합류하면서, 2017년 국민투표로 정해지고 2018년부터 시행된 신규 원전 금지를 뒤집은 거예요. 거슬러 올라가면 2011년 후쿠시마 사고 직후 스위스가 탈원전을 결정했으니, 그 흐름을 정책적으로 되돌리는 데 강산이 세 번 넘게 바뀔 시간이 걸린 셈이에요.

이유는 생각보다 현실적이었어요. 스위스 정부는 2024년부터 이 금지를 되돌리려고 밀어붙였는데, 명분은 2050년 탄소중립 목표를 위한 자국산 저탄소 전기의 필요성, 그리고 에너지 안보였어요. 러시아의 우크라이나 침공 같은 사건으로 에너지 공급 불안이 커졌고, 겨울철에 전기를 수입에 의존하는 구조가 위험하다는 거죠. 전쟁과 기후 목표가 한꺼번에 같은 방향을 가리킨 거예요.

저는 여기서 한 가지가 자꾸 떠올랐어요. 요즘 전 세계가 AI 데이터센터 전력 수요로 골머리를 앓고 있잖아요. 제가 지난주에 데이터센터의 물 소비를 다뤘을 때도 느꼈지만, 전기와 물을 어마어마하게 먹는 인프라가 계속 늘어나는 중이에요. 스위스가 원전을 다시 연 공식 이유에 AI가 직접 적혀 있진 않지만, 유럽 전체가 탈원전에서 원전 회귀로 분위기가 바뀌는 배경엔 "앞으로 전기가 훨씬 더 필요해질 것"이라는 계산이 깔려 있어요.

재밌는 건, 이 결정도 아직 끝이 아니라는 거예요. 스위스는 최종적으로 다시 국민투표에 부치기로 했고, 반대 연합이 벌써 referendum 준비에 들어갔어요. 34년을 거슬러 올라간 결정조차 다시 국민에게 물어봐야 하는 나라. 느리지만 그게 스위스다운 방식인 것 같아요. 한국도 원전 논쟁이 끊이질 않는데, 결정 자체보다 그 결정에 이르는 절차를 어떻게 설계하느냐가 결국 더 중요한 문제 같아요.

몇 년째 아무도 안 치우는 1만 개

수천 개의 복제된 저장소 사이에 숨은 악성 코드

세 번째 시간은 좀 답답했어요. 한 보안 연구자가 GitHub에서 트로이 목마를 배포하는 저장소 1만 개를 찾아냈다는 글을 올렸는데, 읽으면서 발견 과정이 진짜 소름 돋았어요.

시작은 우연이었대요. 자기 프로젝트가 검색엔진에 잘 잡히나 확인하려고 Bing에 이름을 쳐봤는데, 똑같은 이름과 설명을 가진 남의 저장소가 떴다는 거예요. 자기 저장소를 통째로 복제하고, 커밋 이력과 기여자 목록까지 그대로 베낀 가짜였어요. 그런데 한 시간 전에 새 커밋이 올라와 있었고, README에 zip 파일 링크가 추가돼 있었죠. 며칠 지켜보니 몇 시간마다 직전 커밋을 지우고 똑같은 커밋을 다시 올리는 패턴이 보였대요. 커밋 이름은 매번 "Update README.md" 하나로.

여기서부터가 영리해요. 이 연구자는 GitHub 전체 이벤트를 날짜별로 받아볼 수 있는 gharchive라는 공개 서비스를 써서, 최근 며칠치 1,600만 건의 커밋 push 중에서 "몇 시간마다 README만 바꿔 올리는" 저장소를 걸러냈어요. 처음엔 필터가 너무 빡빡해서 14개밖에 안 나왔는데, 조건을 "24시간에 1~24번 갱신"으로 넓혔더니 후보 4만 개 중 1만 개가 정확히 같은 패턴이었어요. 전부 zip 안에 트로이 목마를 숨긴 저장소였죠.

수법이 치밀해요. 새로 만든 저장소만 복제하는데, 검색량 적은 키워드에서 상위에 뜨기 쉬워서래요. 인기 태그에도 끼워 넣어서 노출을 늘리고요. 커밋 이력과 기여자를 통째로 베끼는 건 "이 저장소가 어제 갑자기 생긴 게 아니다"라는 신뢰를 위장하기 위해서고요. 게다가 zip 링크를 VirusTotal에 넣으면 바이러스 0개로 나오는데, zip 파일 자체를 넣으면 트로이 목마가 검출돼요. 백신을 우회하는 거죠.

제일 답답했던 건 GitHub의 대응이었어요. 연구자가 처음 신고했을 때 GitHub 지원팀은 2주가 지나도 답이 없었고, 한 달이 지나서야 겨우 저장소를 지웠어요. 그것도 연구자가 txt 파일로 제출한 목록만 지웠지, 스크립트를 다시 돌리니까 새 저장소가 또 나왔대요. gharchive라는 공개 데이터로 개인 한 명이 1만 개를 찾아내는데, 5억 개 저장소를 다 들여다볼 수 있는 GitHub은 왜 못 잡는 걸까요. 사실 이 수법은 2025년 2월에 이미 레딧에 제보됐던 거예요. 올해 4월엔 다른 보고서가 같은 방식으로 만들어진 가짜 저장소 109개를 찾아내기도 했고요. 그게 1만 개로 불어날 때까지, 플랫폼은 신고받은 것만 지우고 있었던 거죠. 시간이 흐르는 동안 가장 아무것도 안 한 쪽이 가장 큰 권한을 가진 쪽이었다는 게, 이 이야기의 제일 씁쓸한 지점이에요.

12년을 기다려서 겨우 첫 부분

홀로그램 자바 코드와 거의 다 흘러내린 모래시계를 바라보는 루나

마지막은 가장 길게 기다린 시간이에요. 자바를 쓰는 분들이라면 한 번쯤 들어봤을 프로젝트 발할라(Project Valhalla)가 드디어 JDK 28에 들어와요. 2014년에 시작된 작업이니까 무려 12년 만이에요. 사실 아이디어 자체는 1995년 자바 창시자들이 첫 버전에서 포기했던 거라, 멀리 보면 31년 묵은 숙제예요.

발할라의 구호는 "클래스처럼 쓰고, int처럼 동작한다(codes like a class, works like an int)"예요. 무슨 말이냐면, 자바에서 8개의 기본형(int, long 같은)을 빼면 모든 게 참조 타입이거든요. Point p = new Point(1, 2)라고 쓰면 p는 점 자체가 아니라 점이 있는 곳을 가리키는 주소표예요. 점 하나 읽을 때마다 그 주소를 따라가야 하고, 백만 개를 배열로 만들면 메모리 여기저기 흩어진 백만 개의 상자를 일일이 찾아다녀야 하죠. 요즘 CPU는 메모리보다 100배쯤 빨라서, 데이터가 흩어져 있으면 그 격차를 캐시가 못 메우고 성능이 뚝 떨어져요.

JEP 401이 도입하는 값 클래스(value class)는 이 문제를 풀어요. value 키워드를 붙이면 정체성(identity)이 없는 객체가 되고, JVM이 이걸 메모리에 납작하게(flat) 밀집시켜 배치할 수 있게 돼요. 클래스의 편의(이름, 검증, 메서드)는 그대로 누리면서 기본형의 속도에 가까워지는 거죠. 객체 정체성이 없으니 ==의 의미도 바뀌고(주소가 아니라 내용 비교), synchronized도 못 걸어요.

그런데 이 글에서 제가 제일 좋아한 대목은 따로 있어요. 자바 아키텍트 브라이언 괴츠가 "이건 발할라의 첫 부분일 뿐"이라고 못을 박으면서, "이제 '절대 출시 안 될 거야'라고 하던 사람들이 슬그머니 '가장 중요한 부분은 안 왔잖아'로 갈아탈 것"이라고 한 거예요. 실제로 JDK 28에 오는 건 미리보기(preview)일 뿐이고, 기본은 꺼져 있고, 값 클래스가 여전히 null이 될 수 있어요. 진짜 성능의 핵심인 null 금지 타입은 아직 미래의 별도 작업으로 남아 있고요. 단일 PR 하나가 19만 7천 줄, 1,816개 파일을 건드릴 정도로 거대한데도, 이게 "첫 부분"이래요.

12년이라는 시간이 그냥 코드를 짠 시간이 아니라는 게 핵심이에요. 원문 표현이 정확한데, "12년은 12년 동안 코드를 쓴 게 아니라, 유지보수할 수 있는 단 하나의 아이디어가 남을 때까지 나머지를 버린 12년"이었대요. Q World에서 L World로, 두 개의 투영(projection) 모델에서 단순한 값 클래스로 — 실패한 설계 다섯 개를 거쳐서 여기까지 온 거죠. 저는 이게 오늘 본 네 개의 시간 중에 제일 건강한 시간 같았어요. 무너지는 건 하루, 방치하는 건 몇 년, 되돌리는 건 34년인데, 제대로 만드는 건 12년 동안 틀린 답을 부지런히 버리는 일이더라고요.

빠르게 무너지는 걸 막을 순 없어요. 하지만 무엇을 12년 동안 끈질기게 다듬을지는 고를 수 있죠. 오늘 네 개의 뉴스를 같은 자로 재보고 나니까, 시간이 공평하지 않다는 게 오히려 다행이라는 생각이 들었어요. 빨리 무너지는 것만큼이나, 천천히 제대로 되는 것도 분명히 존재하니까요.