처음 보는 기술을 이해하는 순서¶
정의를 많이 기억하는 대신, 처음 만난 기술도 스스로 이해할 수 있는 질문 순서를 만듭니다.
새 기술을 공부할 때 가장 흔한 실패는 구성 요소 이름부터 외우는 것이다. Kafka를 토픽·파티션·오프셋의 목록으로, Netty를 채널·파이프라인·이벤트 루프의 목록으로 기억하면 각 단어는 말할 수 있지만 왜 그런 구조가 필요한지는 설명하기 어렵다.
처음에는 내부 구현을 모두 알 필요가 없다. 무엇을 위한 기술인지, 기존 방식에서 어떤 문제가 반복됐는지, 입력이 어떤 순서로 움직이는지를 먼저 잡아야 한다. 그다음 선택 비용과 실패 조건을 붙이면 정의가 실제 판단 기준으로 바뀐다.
이 저장소가 결론보다 조건을 남기는 이유¶
운영 중에는 “보통 이렇게 한다”는 결론보다 그 결론이 성립한 조건이 필요하다. MySQL이 적합했다는 기록만으로는 데이터 분포, 잠금 충돌, 팀의 복구 경험이 달라졌을 때 같은 선택을 반복해도 되는지 판단할 수 없다.
그래서 한 글은 기술 이름보다 질문에서 시작한다. MVCC란 무엇인가보다 조회와 업데이트가 동시에 일어날 때 왜 서로 오래 기다리지 않아도 되는가가 좋은 출발점이다. 질문이 정해지면 필요한 내부 구조와 불필요한 세부 사항도 구분할 수 있다.
처음에는 세 질문만 답한다¶
첫째, 무엇을 위한 것인가. 기술이 없을 때 반복되는 문제를 한 문장으로 적는다. InnoDB라면 MySQL 안에서 행·인덱스·트랜잭션과 복구를 책임지는 저장 엔진이라고 말할 수 있어야 한다.
둘째, 언제 필요한가. 모든 장점을 나열하지 말고 실제 사용 조건을 적는다. Netty는 일반적인 HTTP API를 무조건 빠르게 만드는 도구가 아니라, 오래 열린 연결이 많거나 프로토콜과 송신 속도를 세밀하게 제어할 때 가치가 커진다.
셋째, 언제 필요하지 않은가. 익숙한 한 서버와 관계형 데이터베이스 하나로 목표를 만족한다면 분산 저장소를 추가하지 않는 편이 낫다. 대안을 먼저 쓰면 기술을 사용해야 한다는 전제에서 벗어날 수 있다.
이 세 답이 생긴 뒤에만 구성 요소와 소스 코드로 내려간다.
구성 요소보다 한 요청을 따라간다¶
낯선 구조를 볼 때는 이름 사이의 관계를 추측하지 말고 입력 하나를 고른다. SQL 조회라면 요청 수신 → SQL 해석 → 실행 계획 → 버퍼의 페이지 → 행 반환을 따라간다. Netty라면 소켓 준비 사건 → 이벤트 루프 → 채널 파이프라인 → 송신 버퍼를 따라간다.
각 단계에서는 네 가지만 기록한다.
- 이 단계가 받은 입력은 무엇인가.
- 어떤 상태를 조회하거나 변경하는가.
- 다음 단계는 누가 결정하는가.
- 실패하거나 느려지면 어떤 신호가 남는가.
이 순서로 읽으면 구성 요소가 단어 목록이 아니라 원인과 결과로 연결된다. 구조도가 필요한 경우에도 제품의 모든 상자를 넣지 않고, 지금 답하려는 질문에 영향을 주는 경계만 그린다.
공식 문서에서는 보장과 예외를 찾는다¶
공식 문서는 사용 중인 버전을 먼저 고정한다. 같은 기능 이름도 버전에 따라 기본값과 실패 동작이 달라질 수 있기 때문이다. 기능 소개보다 트랜잭션 경계, 시간 제한, 순서 보장, 복구 조건과 예외를 찾는다.
지원한다는 문장을 보았으면 세 가지를 적는다. 정확히 어디까지 보장하는지, 무엇은 설정이나 애플리케이션에 맡기는지, 우리 환경에서 확인할 지표는 무엇인지다. 예제의 정상 경로를 운영 보장으로 확대해서는 안 된다.
소스 코드는 관찰 가능한 입구에서 시작한다¶
저장소의 첫 파일부터 순서대로 읽지 않는다. 실제 증상과 연결된 진입점을 고른다. SQL 실행 문제라면 프로토콜 명령을 받는 곳에서 파서·최적화기·실행기로 내려가고, Netty 문제라면 채널의 수신 사건이 어떤 처리기를 호출하는지 따라간다.
함수 호출을 모두 기록할 필요도 없다. 어느 객체가 다음 경로를 결정하는지, 상태는 어디에 남는지, 오류가 어느 경계에서 변환되는지를 찾는다. 공개 계약과 현재 구현 세부 사항도 구분해야 한다. 내부 클래스 하나를 보았다는 이유로 앞으로도 유지될 동작이라고 가정하면 안 된다.
이슈와 변경 제안에서는 사라진 이유를 읽는다¶
이슈에서는 결론보다 재현 조건을 본다. 버전, 작업 부하, 예상 결과와 실제 결과, 유지관리자가 추가로 요구한 정보가 중요하다. 같은 오류 문구라도 재현 조건이 다르면 원인이 다를 수 있다.
PR(Pull Request, 변경 제안)에서는 코드 차이만 보지 않는다. 다른 대안이 거절된 이유, 호환성을 지키기 위한 제한, 회귀를 막는 검증을 읽는다. 완성된 공식 문서에서 압축되어 사라진 설계 제약이 이 논의에 남아 있는 경우가 많다.
논문과 RFC는 가정부터 읽는다¶
논문은 초록 뒤에 바로 결론만 가져오지 않는다. 해결하려는 문제, 평가가 성립한 작업 부하와 비교 기준부터 확인한다. 모든 수식을 이해하지 못해도 어떤 조건에서 결과가 나왔고 저자가 인정한 한계가 무엇인지는 읽을 수 있다.
RFC(Request for Comments, 인터넷 기술 표준 문서)는 MUST, SHOULD, MAY 같은 규범어와 상태 전이, 오류 처리를 중심으로 본다. 표준이 선택을 허용한 부분은 실제 제품 문서에서 어떻게 구현했는지 다시 확인한다.
마지막에는 한 인과관계로 설명한다¶
기술을 이해했다는 것은 짧은 정의를 외웠다는 뜻이 아니다. 해결하려는 문제, 내부 흐름, 이득과 실패 조건을 끊김 없이 연결할 수 있어야 한다.
예를 들어 “Netty는 비동기라 빠르다”는 설명은 부족하다. 오래 대기하는 연결마다 운영체제 스레드를 배정하는 비용이 커졌고, 이벤트 루프가 준비된 연결만 짧게 처리해 그 비용을 줄인다고 설명해야 한다. 이어서 이벤트 루프에서 느린 작업을 기다리면 여러 연결이 함께 지연된다는 조건까지 말할 수 있어야 한다.
설명한 뒤에는 규모, 조회·쓰기 비율, 장애 범위가 달라져도 같은 선택이 맞는지 묻는다. 이 질문에 따라 결론이 바뀐다면 그 조건도 문서에 남긴다.