정동우가 코드를 연습하고 판단을 기록하기 위해 남겨둔 개인 메모 공간입니다.
오늘의 연습 컨베이어
Bloom Filter는 집합의 모든 원소를 직접 저장하지 않고, bit 배열 하나와 여러 개의 hash 위치만으로 membership을 근사(approximate)하는 확률적 자료구조다. 결과가 “없다(negative)”이면 해당 원소는 집합에 확실히 없다고 판단할 수 있고, “있다(positive)”이면 실제로 존재할 수도 있고, false positive일 수도 있다. Burton Bloom의 1970년 논문은 이렇게 “허용 가능한 오류(false positive)”를 대가로 공간과 조회 시간을 크게 절약하는 구조를 제시했다.
집계는 필터링(filter), 그룹화(group), 합산(sum), 정렬(sort), 상위 N개 선택(take)의 다섯 단계로 분해해 각 단계를 드러낸다. 누적은 맵으로, 상위 선택은 정렬 뒤 자르기로 분리한다. 금액은 부동소수가 아니라 정수 minor unit 또는 decimal 계열로 다루고, 그룹 키(group key)는 정규화한 뒤 묶는다.
파일, 소켓, DB 커넥션, 락, 임시 디렉터리처럼 "열었으면 반드시 닫아야 하는 것"은 일반 값과 다르게 다뤄야 한다. 리소스를 얻은 스코프가 리소스를 반납해야 한다.
Code Card
Union-Find, 또는 Disjoint Set Union은 여러 원소가 어떤 연결 컴포넌트에 속하는지를 추적하는 자료구조다. 처음에는 각 원소가 독립된 집합이고, union(a, b)가 두 집합을 합치며, find(a)가 원소가 속한 집합의 대표 루트(root)를 찾는다.
Fenwick Tree는 배열의 한 값을 바꾸면서 prefix sum과 range sum을 반복 조회할 때 쓰는 자료구조다. 원 논문에서 Peter M. Fenwick는 이를 binary indexed tree라고 불렀다. 목적은 동적 산술 부호화에 필요한 누적 빈도표를 작고 빠르게 유지하는 것이었다
SoA(Structure of Arrays)는 객체 하나에 모든 필드를 묶는 대신, 같은 종류의 필드를 각각의 연속 배열로 분리하는 데이터 배치 방식이다. AoS(Array of Structures)가 Particle[]처럼 “입자 객체들의 배열”을 만든다면, SoA는 x[], y[], vx[], vy[]처럼 “속성별 배열 묶음”을 만든다.
비동기 프로그램은 연결, 작업 슬롯, 임시 업로드 세션처럼 사용 후 반환해야 하는 자원을 자주 다룬다. 문제는 획득과 해제를 각각 일반 함수 호출로 작성하면 return, 예외, 취소 경로 중 하나에서 해제 호출을 빠뜨리기 쉽다는 점이다. Async Scope Guard는 자원의 생명주기를 렉시컬 스코프(lexical scope)에 결합한다.
Single-Flight는 같은 key로 겹쳐 들어온 호출을 하나의 실행에 합치는 동시성 패턴이다.
Configuration Snapshot은 기본값, 설정 파일, 환경 변수, 명령행 인자처럼 여러 설정 공급원을 시작 시점에 한 번 합치고, 타입 변환과 검증을 끝낸 뒤 하나의 실행 설정으로 고정하는 패턴이다.
Composition Root를 둔 의존성 주입은 객체가 자기 의존성을 직접 만들지 않고, 애플리케이션 시작 지점에서 의존성 그래프를 조립한 뒤 필요한 객체에 전달하는 패턴이다. 서비스는 "무엇이 필요한지"를 생성자나 함수 인자로 드러내고, "무엇을 실제로 붙일지"는 바깥 조립 계층이 결정한다.