JPA 영속성 컨텍스트와 Dirty Checking
findById 로 얻은 managed entity 는 save() 없이 변경 감지(dirty checking)로 UPDATE 된다. 엔티티 3상태와 스냅샷 비교 원리, save() 가 실제로 하는 일, 그리고 이 자동 동작의 전제인 영속성 컨텍스트의 수명을 정리한다.
findById 로 얻은 managed entity 는 save() 없이 변경 감지(dirty checking)로 UPDATE 된다. 엔티티 3상태와 스냅샷 비교 원리, save() 가 실제로 하는 일, 그리고 이 자동 동작의 전제인 영속성 컨텍스트의 수명을 정리한다.
@Transactional 은 붙였다고 동작하지 않는다. Spring 은 bean 을 프록시로 감싸고 프록시를 거친 호출만 가로챈다. private 메소드와 self-invocation 에서 조용히 무시되는 이유, 그리고 @DataJpaTest 의 테스트 트랜잭션이 그 결함을 가리는 착시까지 정리한다.
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. 무엇이 복사되느냐가 다를 뿐 메커니즘은 같다.
Go의 동시성 모델은 CSP를 기반으로 Goroutine과 Channel을 핵심 도구로 제공한다. 각 도구의 동작 원리와 선택 기준을 정리한다.
Spring MVC는 요청당 스레드를 할당한다. I/O 대기가 길어지면 스레드가 묶인다. WebFlux는 이벤트 루프 기반 논블로킹 모델로 이 문제를 해결한다. MVC와의 구조적 차이, Reactor 패턴, 선택 기준을 정리한다.
Nest.js는 Node.js 생태계에서 DI 컨테이너와 Module 시스템을 프레임워크 수준에서 제공한다. IoC, DI, Module, Provider 등 핵심 설계 원칙을 정리한다.