pile·
최신
  1. 백엔드·네이버페이네이버페이·

    Composite PK에서 시작된 Spring Boot 4 / Spring Batch 6 업그레이드 기록

    문제Spring Data JDBC 의 Composite ID 적용을 위해 Spring Boot 3.5 → 4.0.1 업그레이드 시 Spring Batch, Kotlin, Jackson 등 전체 스택 메이저 전환 필요.

    접근Spring Boot 4 / Spring Batch 6 / Spring Framework 7 / Kotlin 2.3 / Jackson 3 / Kotest 6 / Gradle 9 / ojdbc11 순차 업그레이드. Composite ID 는 Persistable 인터페이스로 구현, JdbcDefaultBatchConfiguration 상속으로 메타데이터 저장.

    결과기술 부채 해결 + 장기 유지보수성 개선. 운영 DB 접근 정책 충돌을 사전 식별해 안정적 배포 달성.

    #spring#kotlin#spring-boot+3
  2. 백엔드·네이버 D2네이버 D2·

    C++ 객체 수명과 암묵적 객체 생성

    문제C++ 에서 memcpy / cast 같은 저수준 작업이 undefined behavior 가 되지 않으려면 객체 수명 규칙을 제대로 이해해야 한다.

    접근C++ 표준의 "객체 수명(object lifetime)" 정의 + C++20 도입의 암묵적 객체 생성(implicit object creation) 규칙을 정리. 어떻게 쓰면 안전한지 코드 예시로 설명.

    결과std 표준이 보장하는 안전한 패턴과 위험 패턴을 명확히 구분. C++ 개발자가 무심코 쓰는 패턴의 위험도 파악.

    #cpp#object-lifetime#memory-model+2
  3. 백엔드·네이버 D2네이버 D2·

    C++ std::bit_cast와 reinterpret_cast — 언제 어떤 것을 써야 하는가

    문제std::bit_cast 와 reinterpret_cast 모두 비트 패턴을 재해석한다. 언제 어떤 것을 써야 하나.

    접근C++20 에 도입된 bit_cast 와 기존 reinterpret_cast 의 안전성 차이, type punning 시 undefined behavior 가 되는 조건을 코드 예시로 비교.

    결과bit_cast 는 trivially copyable 타입 사이 안전한 변환, reinterpret_cast 는 더 강력하지만 undefined behavior 위험. 상황별 선택 가이드 제공.

    #cpp#bit-cast#reinterpret-cast+2
  4. 백엔드·LINE EngineeringLINE Engineering·

    기획서 없이 내재화하기: 검증 로직으로 동일함을 증명하다

    문제큰 시스템 마이그레이션에서 기획서/spec 없이도 "새 구현이 기존과 같다" 는 것을 어떻게 보장하나.

    접근LINE 이 shadow validation / dual run 패턴 적용. 새 시스템과 기존을 병렬로 실행해 출력값을 자동 비교, 차이가 임계 이하면 동일성 인정.

    결과기획서 없이도 동작 동일성을 정량적으로 증명. 마이그레이션 안전성 + 속도 양립.

    #migration#engineering-practice#shadow-validation+2
  5. 백엔드·LINE EngineeringLINE Engineering·

    LINE 앱의 다자간 대화 기능 통합

    문제LINE 앱에 1:1, 그룹, 멀티디바이스 대화가 따로 있어 일관성 문제가 잦았다.

    접근다자간 대화 기능을 한 채팅 코어로 통합. 멀티 디바이스 sync, 메시지 순서 보장, 읽음 표시 일관성 같은 분산 시스템 문제를 풀어냄.

    결과대화 종류와 무관하게 동일한 UX 와 신뢰성. 새 기능 추가 시 한 곳만 고치면 모든 대화 종류에 반영.

    #messaging#multi-device-sync#consistency+2
  6. 백엔드·카카오페이카카오페이·

    배포 직후 발생하는 응답 지연을 해결하기 위한 여정 (feat. JVM 웜업)

    문제JVM 기반 서비스를 배포 직후 트래픽 받으면 JIT 컴파일이 완료되기 전이라 응답 지연이 튄다.

    접근카카오페이가 예열 트래픽 주입, AOT 컴파일 활용, 트래픽 점진 증가(canary 비율 조절) 를 조합한 웜업 전략 설계.

    결과배포 직후 latency 스파이크 제거. 사용자 체감 영향 없이 안전한 배포 가능.

    #jvm#warmup#jit+2
  7. 백엔드·LINE EngineeringLINE Engineering·

    코드 품질 개선 기법 30편: (투명한) 운명의 붉은 실

    문제코드에 보이지 않는 invisible coupling 이 누적되면 작은 변경도 큰 영향을 준다.

    접근LINE 코드 품질 30편 — "(투명한) 운명의 붉은 실" 비유. 변수 / 함수가 코드 전반에 미치는 숨은 의존을 찾고 줄이는 리팩터링 패턴.

    결과변경 영향 범위 축소 + 코드 유지보수성 개선. 시리즈물의 마무리편.

    #refactoring#engineering-practice#code-quality+1
  8. 백엔드·쏘카쏘카·

    Node.js 컨테이너, 왜 깔끔하게 안 죽을까? (feat. Graceful shutdown)

    문제Node.js 컨테이너가 SIGTERM 을 받았을 때 in-flight 요청을 끝내지 않고 죽으면 사용자에게 5xx 가 보인다.

    접근쏘카가 graceful shutdown 을 제대로 구현 — SIGTERM 핸들러로 새 요청 거부 + 진행 중 요청 완료 대기 + DB 연결 정리. K8s preStop hook 과 readiness probe 를 연동.

    결과배포 / 스케일 다운 시 사용자 영향 없이 안전한 종료. Node.js / K8s 운영의 기본기 정리.

    #kubernetes#nodejs#graceful-shutdown+2
  9. 백엔드·뱅크샐러드뱅크샐러드·

    뱅크샐러드가 게임을 만들 때 데이터 정합성을 유지하는 법 (feat. 낙관적 락)

    문제게임형 앱테크 서비스의 character_state(잔액·레벨)는 유저 액션·운영 백오피스·배치 등 여러 경로로 동시에 갱신된다. 동시성 제어가 없으면 Lost Update 가 발생해 현금성 자산 정합성이 깨진다.

    접근재시도 로직 없는 낙관적 락을 채택. version 컬럼을 두고 UPDATE 시 WHERE version = ? 조건으로 CAS 한다. 충돌 시 즉시 실패시켜 호출자가 처리하도록 위임한다.

    결과잠금 대기 없이 정합성을 보장하고 코드 복잡도를 낮췄다. 현금성 재화가 오가는 도메인에서도 트랜잭션 단순화와 동시성 안전성을 동시에 확보했다.

    #optimistic-lock#concurrency-control#data-consistency+1
  10. 백엔드·LINE EngineeringLINE Engineering·

    코드 품질 개선 기법 29편: 고르디우스 변수

    문제로컬·원격 데이터 동기화 클래스에서 ID 집합 비교 결과를 `localEntryIds`, `remoteEntryIds` 변수에 담아 추가·업데이트·삭제 분기를 만들면, 변수 하나로 여러 의미가 묶여 "고르디우스 변수" 가 된다.

    접근의도별로 변수를 잘라낸다. `idsToAdd`, `idsToUpdate`, `idsToDelete` 처럼 결과 집합을 미리 계산한 뒤 각 처리에 그대로 전달한다. 비교식 `id !in localEntryIds && id in remoteEntryIds` 같은 표현을 변수명으로 흡수.

    결과분기 조건이 변수명으로 자기 설명적이 되고, 분기마다 의미가 명확해진다. 코드 리뷰 시 변수 한 개에 여러 책임이 묶인 패턴을 식별하는 안티패턴으로 정착시킨다.

    #code-review#refactoring#kotlin+1
  11. 백엔드·LINE EngineeringLINE Engineering·

    코드 품질 개선 기법 28편: 제약 조건에도 상속세가 발생한다

    문제Kotlin 에서 `IntArray` 의 박싱 회피 이점을 살리려 `List<Int>` 를 구현한 `ImmutableIntList` 같은 래퍼를 만들면, 상위 인터페이스의 기본 메서드가 그대로 따라와 의도치 않은 가변 동작·성능 저하가 발생한다.

    접근"상위 타입을 상속/구현하면 제약과 책임이 함께 따라온다" 는 관점으로 설계를 재검토. 꼭 필요한 일부 메서드만 노출하거나, 인터페이스 구현 대신 별도 타입으로 한다.

    결과박싱 최적화와 불변성을 동시에 얻으려고 인터페이스를 무리하게 구현하는 패턴의 비용을 명시한다. 작은 래퍼 클래스 설계 시 상속의 "상속세" 를 계산하라는 가이드를 제공.

    #code-review#kotlin#performance+1
  12. 백엔드·LINE EngineeringLINE Engineering·

    코드 품질 개선 기법 27편: 티끌이 모여 태산이 되듯 의존성도 쌓이면

    문제`LatestNewsSnippetUseCase` 같이 작은 유스케이스도 리포지터리·포매터·팩토리 등 의존성을 하나씩 추가하다 보면 6~7개가 쌓여 테스트·재사용·이해 비용이 누적된다.

    접근의존성을 누적하기 전에 "이 클래스의 책임 단위에 정말 필요한가" 를 물어 분리하거나 합친다. 포매터·팩토리 같은 보조 의존성은 호출자로 끌어올리고 유스케이스는 도메인 변환만 담당하도록.

    결과작은 클래스가 점점 무거워지는 경향을 "의존성도 쌓이면 태산" 으로 표현. 코드 리뷰에서 의존성 개수를 의도적으로 점검하도록 유도한다.

    #code-review#design-pattern#dependency-injection+1
  13. 백엔드·LINE EngineeringLINE Engineering·

    코드 품질 개선 기법 26편: 설명의 핵심은 첫 문장에 있다

    문제문서화 주석이 함수의 동작을 절차적으로 길게 나열하면 독자는 끝까지 읽어야 의도를 파악한다. 결과적으로 주석이 길어도 이해 비용이 줄지 않는다.

    접근"설명의 핵심은 첫 문장" 원칙을 적용. 첫 문장에 함수의 목적·반환 의미를 압축해 적고, 절차 묘사는 필요한 만큼만 뒤에 붙인다. 코드를 보면 알 수 있는 내용은 주석에서 뺀다.

    결과짧고 의도 중심의 주석이 더 잘 읽힌다. 코드 리뷰에서 "첫 문장만 보면 무엇을 하는지 알 수 있는가" 를 점검 기준으로 삼는다.

    #code-review#naming#documentation+1
  14. 백엔드·LINE EngineeringLINE Engineering·

    동적 사용자 분할을 활용한 새로운 A/B 테스트 시스템을 소개합니다

    문제기존 A/B 테스트는 사용자 그룹을 정적으로 분할해 실험 변경·교차 실험·세그먼트 조합에 한계가 있다. 그룹 정의가 코드와 결합되면 운영 비용이 커진다.

    접근동적 사용자 분할을 도입. 실험 정의 시점에 사용자 속성·해시·시드로 그룹을 즉시 계산해 분기한다. 여러 실험을 동시에 운영하고 그룹 간 직교성을 검증하는 시스템을 구축.

    결과새로운 실험 도입·중단이 코드 배포 없이 가능해진다. CTR 같은 지표 비교가 데이터 기반 의사결정에 곧바로 연결된다.

    #ab-test#experimentation#user-segmentation+1
  15. 백엔드·LINE EngineeringLINE Engineering·

    코드 품질 개선 기법 25편: 요컨대... 무슨 말이죠?

    문제Kotlin data class 의 일부 필드가 자주 변하는 상태라는 이유로 `var` 로 선언되면, 동일 객체를 공유한 여러 곳에서 의도하지 않은 변경이 발생해 버그가 새어 나간다.

    접근모든 필드를 `val` 로 두고 상태 변경 시 `copy()` 로 새 인스턴스를 만들도록 강제. 리뷰 코멘트도 "그래서 결론은 val 로 하라" 는 한 문장으로 핵심을 먼저 전달한다.

    결과불변 데이터 모델이 동시성·디버깅 측면의 안전성을 높인다. 리뷰 코멘트 작성 시 결론을 첫 문장에 두는 스타일 가이드도 함께 정착.

    #code-review#kotlin#immutability+1