Top-K — heap 이 항상 답은 아니다
K번째 큰 값 문제에서 heap 은 반사적인 선택이지만, 전체 배열이 이미 메모리에 있다면 Quick Select 가 평균 더 빠르다. heap 크기 K 유지와 Quick Select 의 메커니즘, 그리고 데이터 형태에 따른 선택 기준.
K번째 큰 값 문제에서 heap 은 반사적인 선택이지만, 전체 배열이 이미 메모리에 있다면 Quick Select 가 평균 더 빠르다. heap 크기 K 유지와 Quick Select 의 메커니즘, 그리고 데이터 형태에 따른 선택 기준.
findById 로 얻은 managed entity 는 save() 없이 변경 감지(dirty checking)로 UPDATE 된다. 엔티티 3상태와 스냅샷 비교 원리, save() 가 실제로 하는 일, 그리고 이 자동 동작의 전제인 영속성 컨텍스트의 수명을 정리한다.
@Transactional 은 붙였다고 동작하지 않는다. Spring 은 bean 을 프록시로 감싸고 프록시를 거친 호출만 가로챈다. private 메소드와 self-invocation 에서 조용히 무시되는 이유, 그리고 @DataJpaTest 의 테스트 트랜잭션이 그 결함을 가리는 착시까지 정리한다.
Union-Find 는 그룹마다 root 대표를 두고 같은 그룹인지 판정한다. 최적화 없는 구현은 사슬 트리에서 find 가 O(N) 까지 늘어지지만, path compression 과 union by rank 를 더하면 사실상 상수가 된다.
위상정렬의 Kahn BFS 는 진입차수 0 인 노드를 반복해서 꺼내 처리하는 알고리즘이고, 사이클 검출은 별도 로직 없이 따라온다. Kahn BFS 의 메커니즘, Course Schedule 유형, DFS post-order 와의 선택 기준.
부분 배열 합 문제는 슬라이딩 윈도우와 누적합 두 도구로 O(N) 환원된다. 입력에 음수가 섞이거나 합이 정확히 K 인 등식 조건이 붙으면 단조성이 깨지고, 도구는 누적합 + 해시 영역으로 넘어간다.
답을 직접 찾지 못하는 문제도 결정 함수와 단조성이 보이면 답 자체를 이분탐색할 수 있다. parametric search 의 사고 패턴 — 결정 함수 정의, 단조성 방향, lo/hi 정당화.
Round Robin과 Least Connection은 오래 로드밸런서의 기본이었다. 그런데 Envoy, AWS ALB 같은 최신 로드밸런서가 핵심 옵션으로 들고 온 알고리즘은 Least Outstanding Requests이고, 그 실용 구현은 Power of Two Choices다. 분배 결정의 단위가 connection에서 request로 세분화된 진화 경로를 정리한다.
MSA 는 서비스를 어느 기준으로 가를 것인가의 결정이다. 도메인 경계, 데이터 소유권, 스케일 패턴, 장애 격리 — 어느 것을 우선하느냐가 경계를 만들고 통신과 데이터를 차례로 결정한다.
ES 와 CQRS 는 시스템의 원본 데이터와 그 표현의 분리를 다룬다. 도입 비용이 시스템 전반에 분산되므로 채택 가치를 명시할 수 있을 때 채택할 만하다고 본다.
분산 트랜잭션은 모놀리스의 단일 ACID 트랜잭션이 분산 환경에서 어떻게 분해되고, 그 조각을 어떻게 재조립하는가의 문제다. 2PC, Saga (Choreography vs Orchestration), Outbox 의 역할과 트레이드오프.
settings.json, CLAUDE.md, slash commands, subagents, hooks. Claude Code 커스터마이징 표면은 ‘언제 개입하는가’라는 기준 하나로 네 계층으로 정돈된다.
alacritty + tmux + nvim + zsh + Claude Code 다섯 도구로 구성한 터미널 중심 개발 환경. 각 도구의 선택 이유와 조합 방식을 정리한다.
JIRA의 이슈와 워크플로우를 작업 단위의 그래프로 보고, Sprint 라이프사이클·이슈 계층·Git/GitHub 연동 패턴·자동화 흐름을 정리한다.
GitHub Actions를 저장소 이벤트 기반 자동화 엔진으로 보고, workflow / job / step 3단 추상과 trigger·runner·secret 운영을 정리한다.
GitHub PR을 Git 변경 그래프에 협업 레이어를 더한 추상으로 보고, Code Review 사이클·PR 단위 설계·머지 전략을 정리한다.
Git을 명령어 모음이 아닌 변경의 그래프로 보고, commit hygiene·branch strategy·merge vs rebase 결정이 그래프 모양에 대한 선택임을 정리한다.
SLA는 사후 모니터링으로 지켜지는 것이 아니라 설계로 만들어지고 운영으로 지켜진다. 저지연 서비스에서 SLI가 가용성이 아니라 p99 지연이 되는 순간, timeout budget·캐싱·degradation·격리·load shedding 이 SLA를 만들고, p99 SLO·Error Budget 소진율·headroom·배포 게이트·회고가 그것을 지킨다.
이중 쓰기와 fallback 읽기를 조합하여 운영 중인 서비스의 데이터 형식을 무중단으로 전환하는 3단계 패턴을 정리한다.
봉투 암호화의 CMK/DEK 2중 키 구조가 키 유출 영향을 제한하고 키 회전을 단순화하는 원리를 정리한다.
MLflow의 네 조각이 ML Lifecycle의 어느 칸을 메우는지, 그리고 경량 팀이 그 중 어떤 조각을 고를 수 있는지.
Circuit Breaker 의 차단 트리거와 회복 전략은 함께 설계되어야 한다. 회복 없는 차단은 의존성을 영구히 끊고, 차단 기준 없는 회복은 무의미한 반복 전이다.
Rate Limit 알고리즘을 고르기 전에, 어느 계층에서 보호할지가 먼저 알고리즘의 선택지를 좌우한다. L4/L7/Application 계층과 Token/Leaky/Sliding/Fixed 알고리즘의 교차 관계를 정리한다.
sklearn과 ONNX는 같은 계층의 경쟁자가 아니다. 두 도구의 자리를 분리해서 보면 ‘ONNX 계층이 필요한가’라는 질문이 자연스럽게 남는다.
CTR 예측의 기준 모델로서 Logistic Regression의 구조와 특성을 정리한다. 오래된 모델이 여전히 기준 모델로 쓰이는 이유.
수동 reload, 정적 upstream, 빈약한 L7 observability — 정적 reverse proxy가 cloud-native 환경에서 마주친 한계를 Envoy의 xDS와 filter chain이 어떻게 푸는지 정리한다.
VPC 의 격리·라우팅·연결·보안 네 갈래를, 백엔드 개발자가 실제로 마주치는 결정 중심으로 한 자리에 모았다.
Java 는 강타입 + JVM 바이트코드 + JIT 의 적응형 최적화. Python 은 동적 타입 + 인터프리터 + 선언적 type hint. Go 는 정적 + structural typing + 단일 컴파일러. 타입 시스템 결정이 런타임 매커니즘을 결정한다.
세 도구는 같은 자리에 보이지만 풀어내는 문제가 다르다. 정적 컨텐츠 전달, 동적 컨텐츠 생성, 트래픽 중개를 어떻게 나눠 갖는지 정리한다.
CPython 의 GIL 은 멀티스레드 CPU bound 를 차단하고 우회법을 강제한다. Java 는 OS 스레드 1:1 의 비용을 Java 21 virtual thread 로 우회해 thread-per-request 를 살렸다. Go 는 처음부터 M:N 스케줄러로 goroutine 을 경량화했다. 세 모델이 같은 백엔드 워크로드에서 다른 결정으로 이어진다.
세 언어 모두 GC 를 쓰지만 우선순위가 다르다. Java 는 generational + region(G1/ZGC), Python 은 reference counting + cyclic detector, Go 는 concurrent tri-color mark-sweep. 각 GC 가 무엇을 포기했는지가 운영 특성을 가른다.
함수에 객체를 넘기는 동작을 ‘참조 전달’ 이라 부르지만 메모리에서는 모두 값 복사다. Java reference value 복사, Python call by sharing, Go 구조체 헤더와 escape analysis. 무엇이 복사되느냐가 다를 뿐 메커니즘은 같다.
기본 핸드셰이크 위에서 TLS를 운영하는 세 가지 실무 주제를 정리한다. 세션 재개와 0-RTT로 반복 비용을 줄이고, mTLS로 클라이언트까지 인증하고, ACME로 인증서 발급과 갱신을 자동화한다.
Container 오케스트레이션의 기본 구조와 백엔드 개발자가 알아야 할 핵심 오브젝트, 네트워크, 스케일링, 운영 방법을 정리한다.
Go의 동시성 모델은 CSP를 기반으로 Goroutine과 Channel을 핵심 도구로 제공한다. 각 도구의 동작 원리와 선택 기준을 정리한다.
TLS는 신뢰할 수 없는 네트워크 위에서 기밀성·무결성·인증을 확보해 안전한 채널을 만든다. 대칭/비대칭 하이브리드 암호화, TLS 1.2 핸드셰이크, 인증서와 PKI 신뢰 모델, 그리고 TLS 1.3의 개선을 정리한다.
같은 NoSQL 우산 아래에서 MongoDB 와 Redis 가 서로 다른 역할로 자리잡은 이유. 데이터 모델·스토리지·스키마·확장·사용 사례를 기준으로 비교 정리.
Spring MVC는 요청당 스레드를 할당한다. I/O 대기가 길어지면 스레드가 묶인다. WebFlux는 이벤트 루프 기반 논블로킹 모델로 이 문제를 해결한다. MVC와의 구조적 차이, Reactor 패턴, 선택 기준을 정리한다.
HTTP/1.1은 요청과 응답이 순차적이다. HTTP/2는 멀티플렉싱, 바이너리 프레이밍, 헤더 압축으로 이 구조를 바꿨다. 두 프로토콜의 차이와 HTTP/2 위에서 동작하는 gRPC의 특성을 정리한다.
Observer는 상태 변화를 구독자에게 통지하는 일대다 관계로 결합을 끊는다. Subject는 누가 듣는지 모른 채 통지만 한다. EventEmitter, RxJS, 이벤트 기반 아키텍처가 모두 여기서 확장된다. 브로커를 매개하는 pub/sub와는 구분된다.
Container의 개념과 VM과의 차이를 정리하고, Docker의 아키텍처, Dockerfile, Docker Compose의 기본 사용법을 설명한다.
코드를 기술 계층별로 나누는 수평 분할과, 기능/도메인별로 나누는 수직 분할의 차이를 정리한다. 각각의 장단점과 선택 기준.
Strategy는 알고리즘군을 같은 인터페이스로 캡슐화해 런타임에 교체한다. if/switch 분기 수정 대신 전략 추가로 확장한다. 일급 함수가 있는 언어에서는 별도 Strategy 클래스가 함수 하나로 흡수된다.
Nest.js는 Node.js 생태계에서 DI 컨테이너와 Module 시스템을 프레임워크 수준에서 제공한다. IoC, DI, Module, Provider 등 핵심 설계 원칙을 정리한다.
Facade는 복잡한 서브시스템에 단순한 진입점을 제공해 클라이언트와 내부 구현의 결합을 끊는다. 서비스 레이어, 라이브러리 SDK가 사실상 Facade다. Adapter는 인터페이스 변환, Mediator는 양방향 조정이라는 점에서 구분된다.
레이어드 아키텍처는 기술적 책임 기준으로 코드를 수평 계층으로 나눈다. 4계층 구조의 각 역할, 의존성 방향 규칙, DIP로 계층 간 결합을 끊는 방법을 정리한다.
Kafka의 핵심 개념(토픽, 파티션, 컨슈머 그룹, 복제)을 정리하고, ZooKeeper 의존성을 제거한 KRaft 모드의 등장 배경을 설명한다.
Hexagonal Architecture의 핵심 개념과 Go에서의 관용적 구현. 암묵적 인터페이스와 패키지 구조를 활용한 의존성 방향 제어.
Decorator는 상속의 조합 폭발을 조합으로 대체한다. 같은 인터페이스를 유지하는 래퍼를 런타임에 겹쳐 기능을 동적으로 더한다. java.io, Python 함수 데코레이터, 웹 미들웨어 체인이 모두 같은 의도의 변주다.
Builder 는 생성자의 세 가지 한계가 동시에 모일 때의 해결책이다. 매개변수 수가 많고, 일부가 선택적이고, 단계적 검증이 필요한 경우. 셋이 같이 모이지 않으면 다른 도구로 충분하다. 언어가 named/default 매개변수를 제공하면 Builder 의 필요도 자연스럽게 줄어든다.
Factory 의 공통 의도는 객체 생성과 사용의 분리다. 세 변형 (Factory Method / Abstract Factory / Static Factory Method) 은 분리 방식이 다르고 적합한 상황도 다르다. 실무에서는 Static Factory Method 가 가장 자주 쓰이고, DI 컨테이너가 등장하면 명시적 Factory 의 일부 역할이 컨테이너로 흡수된다.
Singleton 은 가장 단순한 패턴이지만 안티패턴 논란의 대표 사례다. 단일 인스턴스 보장과 전역 접근을 한 패턴에 묶은 결정이 강한 결합과 테스트 어려움의 원인. DI 가 두 의도를 분리한 일반 대안이다.
DIP(원칙), IoC(패턴), DI(기법)는 서로 다른 추상 수준에 있는 개념이다. 위계를 분명히 봐야 프레임워크 기능과 설계 원리가 섞이지 않는다.
캐시 패턴은 읽기 채움 책임과 쓰기 경로 두 축으로 정전 5종(cache-aside, read-through, write-through, write-back, refresh-ahead)으로 나뉜다. 패턴 선택은 곧 두 축의 결정 조합이다.
트랜잭션은 원자성, 락은 직렬성을 담당한다 — 서로 대체재가 아니다. 격리 수준의 기본 읽기로는 못 막는 Lost Update 를 비관적 락과 낙관적 락이 어떻게 메우는가, 그리고 선택 기준.
트랜잭션 격리 수준은 ‘어떤 이상 현상까지 허용할 것인가’ 의 정책 선택이다. ANSI 4단계가 각각 막는 anomaly, 그리고 표준과 다르게 동작하는 InnoDB 의 MVCC 와 Repeatable Read.
RDB 트랜잭션의 ACID 4개 속성이 실제로 무엇을 보장하는가. A/C/D 는 비교적 명확한 보장이지만 I 만 ‘단계’ 가 존재하는 이유 — 정확성과 동시성의 트레이드오프 도입.
백엔드 개발에서 자주 마주치는 두 전송 프로토콜, TCP와 UDP의 동작 원리를 정리한다. 연결 수립, 신뢰성 보장, 흐름/혼잡 제어 메커니즘과 선택 기준.
L2 스위치, L3 라우팅, L4/L7 로드밸런서 — 실무 용어에 붙는 계층 번호가 어디서 왔는지 정리한다. OSI 7계층과 TCP/IP 모델의 대응, 그리고 각 번호가 실제로 가리키는 것.
HTTP는 stateless다. 사용자 인증을 유지하려면 상태를 어딘가에 저장해야 한다. 서버에 저장하는 세션 방식과 토큰에 담아 클라이언트에 위임하는 JWT 방식의 구조, 트레이드오프, 저장 전략을 정리한다.
JWT를 인증 방식이라 부르고 OAuth로 로그인했다고 말하던 시절, 용어가 머릿속에서 뒤섞였다. 인증과 인가, 그리고 증명을 어디에 두는가라는 두 기준으로 Basic·Digest·API Key·Session·Token·OAuth·OIDC·SSO를 정리한다.