Notes.
A linear view of published notes, essays, and experiments.
분산 락에서 blind unlock이 더 위험했던 이유
blind unlock이 임계 구역의 의미를 어떻게 무너뜨렸는지 해부하고, 왜 lock correctness 문제를 Redis 전체가 아니라 lock path 안에서 먼저 풀었는지, 그리고 그 뒤에도 왜 stale owner 문제는 남는지 설명합니다.
대용량 CSV 다운로드에서 손상된 ZIP이 더 위험했던 이유
왜 포맷보다 응답의 수명주기를 먼저 봐야 했는지, 그리고 timeout 증설 대신 어떤 기준으로 export 경로를 다시 나눴는지 설명합니다.
같은 인덱스인데 성능이 달라지는 이유
인덱스가 있다는 사실보다, 결국 몇 번의 추가 읽기와 몇 건의 재확인을 만드는지가 더 중요하다는 점을 설명합니다.
MySQL Lock과 격리 수준이 진짜 문제되는 순간
잠금과 격리 수준을 이름으로 외우기보다, 무엇을 어떤 경로로 잠그고 어떤 읽기를 허용하는지로 보는 방법을 설명합니다.
MVCC는 잠금 없는 읽기를 어떻게 만드는 걸까
undo log, read view, current read를 기준으로 MVCC가 왜 잠금 없는 읽기를 가능하게 하는지 설명합니다.
MySQL 엔진과 InnoDB는 어떻게 역할을 나눌까
MySQL 엔진과 InnoDB가 어디서 역할을 나누고, handler와 클러스터링 구조가 왜 실행 계획의 감각을 바꾸는지 설명합니다.
복구 가능한 푸시 알림을 다시 설계한 방법
중복 발송과 유실을 만들던 푸시 알림 전달 모델을, 복구 가능한 작업으로 다시 정의한 과정을 설명합니다.
JPA batch insert가 생각처럼 안 됐던 이유
JPA batch insert가 기대한 만큼 묶이지 않았던 원인을 따라가며, 실제로 어디에서 성능이 새는지 다룹니다.
배포에서 속도보다 연속성이 더 중요했던 이유
병렬 배포가 만들던 다운타임과 운영 복잡도를 줄이기 위해, 롤링 배포와 AWX 중심으로 배포 구조를 다시 정리한 과정을 다룹니다.
부하 테스트에서 하드웨어보다 쿼리가 먼저 보였던 이유
병목이 인프라가 아니라 쿼리라는 사실을 어떻게 확인했고, 어떤 기준으로 성능을 읽었는지 다룹니다.
복잡한 TripPlan 조회에 QueryDSL이 필요했던 이유
복잡해진 TripPlan 조회를 QueryDSL로 다시 구성하면서, 가독성과 확장성을 어떻게 회복했는지 다룹니다.
왜 팔로우 수는 어긋났을까
팔로우 수가 실제 상태와 다르게 보이던 원인을 추적하고, 정합성을 복구하기 위해 어떤 선택을 했는지 다룹니다.
우리 팀에 맞는 Git 병합 전략을 찾는 방법
merge, squash, rebase, fast-forward를 각각 언제 쓰고 버려야 하는지 팀 협업 관점에서 비교합니다.
부분 업데이트에서 merge보다 변경 감지가 더 안전한 이유
부분 업데이트에서 merge가 만드는 덮어쓰기 위험을 짚고, 변경 감지 방식이 왜 더 안전했는지 다룹니다.
자바 코드는 JVM에서 어떻게 실행될까
컴파일, 클래스 로딩, 런타임 데이터 영역, 실행 엔진, GC까지 자바 코드가 JVM 위에서 실행되는 흐름을 한 번에 훑습니다.