라인

107 개의 포스트

techblog.lycorp.co.jp/ko

태그로 필터

line원문

LY의 테크 컨퍼런스, 'Tech-Verse 2025' 후기 (새 탭에서 열림)

LY Corporation(이하 LY)은 기술 컨퍼런스 'Tech-Verse 2025'를 통해 합병 이후의 플랫폼 통합 전략과 AI 기업으로의 전환 비전을 제시했습니다. LY는 자체 프라이빗 클라우드 구축을 통해 압도적인 비용 절감과 보안 강화를 실현하고, 모든 서비스에 AI 에이전트를 도입하여 사용자 경험을 혁신할 계획입니다. 특히 생성형 AI를 활용한 개발 프로세스의 전면적인 진화로 엔지니어가 서비스 본질에 집중할 수 있는 환경을 구축하는 것이 핵심입니다. **CatalystOne: 고효율 통합 플랫폼 구축** * **자체 클라우드 기반의 비용 최적화**: 퍼블릭 클라우드 대비 약 4배의 비용 절감 효과를 거두고 있으며, 50만 대의 서버와 3Tbps에 달하는 대규모 트래픽을 효율적으로 관리하고 있습니다. * **플랫폼 통합(CatalystOne)**: 합병 후 중복된 인프라를 'CatalystOne'이라는 이름 아래 통합하여 기술, 엔지니어, 시설 등 핵심 자원의 운영 집중도를 높였습니다. * **보안 및 혁신 가속화**: 통합된 플랫폼을 통해 거버넌스를 강화하고, 폭발적인 데이터 성장과 생성형 AI 수요에 기민하게 대응할 수 있는 차세대 프라이빗 클라우드 'Flava'를 구축했습니다. **전 서비스의 AI 에이전트화와 개발 혁신** * **퍼스널 에이전트 구현**: 현재 44개 서비스에 생성형 AI를 도입했으며, 수천만 개의 에이전트를 연계하여 개별 사용자의 니즈를 정교하게 지원하는 것을 목표로 합니다. * **AI 기반 개발 솔루션 도입**: 2025년 7월부터 모든 엔지니어에게 AI 개발 솔루션을 전면 도입하며, RAG(검색 증강 생성) 기술로 사내 지식을 활용해 코드 품질을 높입니다. * **생산성 지표의 획기적 개선**: PoC 결과 'Code Assist'는 96%의 정답률을 기록했고, 'Auto Test' 도입으로 테스트 시간을 97% 단축하는 등 압도적인 개발 효율성 향상을 확인했습니다. **실용적인 결론** LY의 전략은 대규모 인프라를 운영하는 기업이 단순히 AI를 도입하는 것에 그치지 않고, 인프라 통합을 통한 비용 효율화와 AI를 활용한 개발 문화 혁신이 병행되어야 함을 보여줍니다. 특히 엔지니어링 환경에 AI를 적극적으로 이식하여 확보한 리소스를 사용자 가치 증대에 재투자하는 선순환 구조는 기술 기업들이 참고할 만한 모델입니다.

line원문

코드 품질 개선 기법 17편: 사상누각 (새 탭에서 열림)

무분별한 빌더 패턴의 사용은 필수 인자의 누락을 런타임 시점에야 발견하게 만들어 코드의 안정성을 해칠 수 있습니다. 견고한 소프트웨어를 구축하기 위해서는 런타임 에러 대신 컴파일 타임에 결함을 발견할 수 있는 생성자나 팩토리 함수를 우선적으로 고려해야 합니다. 특별한 제약 사항이 있는 경우가 아니라면, 프로그래밍 언어의 기능을 활용해 불완전한 객체 생성을 원천 차단하는 것이 코드 품질 개선의 핵심입니다. **빌더 패턴의 한계와 위험성** * 전통적인 빌더 패턴은 필수 인자가 누락되어도 컴파일 단계에서 이를 감지하지 못하며, `build()` 호출 시점에 `IllegalStateException` 등의 런타임 에러를 발생시킨다. * 이는 '사상누각'처럼 기초가 불안정한 코드를 양산하는 결과를 초래하므로, 컴파일러가 인자 누락을 체크할 수 있는 생성자 기반 설계를 지향해야 한다. **기본값이 있는 인자가 많은 경우의 대안** * Kotlin과 같이 기본 인수를 지원하는 언어에서는 빌더 대신 생성자에 기본값을 설정함으로써 인자 전달의 유연성을 확보하고 가독성을 높일 수 있다. * 만약 환경상 빌더 패턴을 반드시 사용해야 한다면, 필수 인자만큼은 빌더의 생성자 인수로 직접 전달받도록 설계하여 누락 가능성을 구조적으로 방지한다. **생성 중인 상태의 처리와 타입 구분** * 빌더 객체를 다른 함수에 인자로 전달해 값을 채우는 방식(출력 인수)은 가독성을 떨어뜨리므로, 값을 반환받아 생성자나 팩토리 함수에 전달하는 방식으로 개선하는 것이 바람직하다. * 객체 생성 로직이 복잡한 파이프라인 형태라면 각 단계마다 서로 다른 타입을 정의함으로써, 유효하지 않은 중간 상태의 객체가 사용되는 것을 방지할 수 있다. **빌더 패턴이 효과적인 상황: 마지막 작업 정의** * 0회 이상 임의의 순서로 적용되는 작업이 있고, 특정 '마지막 작업(terminal operation)'을 통해 최종 결과를 산출해야 하는 경우에는 빌더 패턴과 유사한 구조가 유용하다. * 예를 들어 이미지 편집 과정(crop, filter 등)에서 데코레이터 패턴을 사용할 때, 빌더 형식을 도입하면 순수 데코레이터 패턴보다 중첩 구조가 단순해져 가독성이 크게 향상된다. 객체 생성 시 발생할 수 있는 결함을 런타임이 아닌 컴파일 타임에 검출할 수 있도록, 가장 먼저 생성자나 팩토리 함수 사용을 검토하세요. 빌더 패턴은 언어적 제약이 있거나 특수한 파이프라인 설계가 필요한 경우에만 선택적으로 활용하는 것이 좋습니다.

line원문

코드 품질 개선 기법 16편: 불이 'null'인 굴뚝에 연기가 'null'이 아닐 수 없다 (새 탭에서 열림)

널 객체(null object) 패턴은 `null` 대신 '비어 있음'을 나타내는 객체를 사용하여 호출부의 코드를 단순화하고 예외 처리를 줄이는 유용한 디자인 패턴입니다. 그러나 일반적인 상태와 오류 상태를 명확히 구분해야 하는 상황에서 이 패턴을 무분별하게 사용하면, 컴파일러의 정적 검증을 우회하게 되어 오히려 버그를 발견하기 어렵게 만듭니다. 따라서 오류 처리가 필수적인 로직에서는 널 객체 대신 언어 차원의 `null`이나 `Optional` 타입을 사용하여 타입 안정성을 확보하는 것이 권장됩니다. ### 널 객체 패턴의 활용과 장점 널 객체 패턴은 유효하지 않은 값이나 비어 있는 상태를 특정 객체로 정의하여 프로그램의 흐름을 끊지 않도록 돕습니다. - **코드 단순화**: 컬렉션의 경우 `null` 대신 빈 리스트(`.orEmpty()`)를 반환하면 호출 측에서 별도의 널 체크 없이 즉시 순회(iteration) 로직을 수행할 수 있습니다. - **폴백 데이터 제공**: UI 표시를 위한 데이터 모델에서 '알 수 없는 사용자'와 같은 기본 객체를 정의하면, 데이터가 없는 경우에도 화면 레이아웃을 깨뜨리지 않고 기본 정보를 안전하게 보여줄 수 있습니다. - **로직 통합**: 경계 조건이나 오류 상황을 일반적인 비즈니스 로직에 자연스럽게 통합시켜 코드의 가독성을 높입니다. ### 널 객체 패턴이 유발하는 타입 안정성 문제 오류 상태를 일반 객체처럼 취급하게 되면 개발자가 의도적으로 해당 상태를 확인해야 하는 로직을 누락했을 때 이를 잡아낼 방법이 부족해집니다. - **컴파일 타임 검증 부재**: `isInvalid`와 같은 속성으로 오류를 확인해야 하는 널 객체를 사용하면, 확인 로직을 잊더라도 컴파일러는 이를 정상적인 코드로 인식합니다. - **런타임 버그 발생**: 유효하지 않은 널 객체가 시스템 내부에서 계속 전달되다가 예상치 못한 지점에서 오작동을 일으킬 수 있으며, 이는 즉시 런타임 오류가 발생하는 것보다 원인 파악이 더 어렵습니다. - **대안으로서의 정적 타입**: Kotlin의 널 가능 타입(`?`)이나 Swift의 `Optional`을 사용하면 컴파일러가 강제로 널 처리를 요구하므로, 오류 조건과 일반 조건을 명확히 분리하여 처리할 수 있습니다. ### 널 객체 패턴 사용 시 주의할 점: 동일성과 동등성 널 객체를 정의하고 비교할 때는 객체의 비교 방식에 각별히 유의해야 합니다. - **동일성(Identity) 문제**: `UserModel.INVALID`와 같은 정적 인스턴스를 `==` 연산자로 비교할 때, 해당 클래스에 `equals`가 적절히 구현되어 있지 않으면 내용이 같더라도 다른 객체로 판별될 위험이 있습니다. - **값 기반 비교의 한계**: 단순히 기본값(ID 0, 빈 문자열 등)을 채워 넣은 새 객체를 생성해 비교할 경우, 실제 '무효한 상태'를 나타내는 싱글톤 객체와 일치하지 않아 로직 오류가 발생할 수 있습니다. ### 상황에 맞는 도구 선택 제안 널 객체 패턴은 만능 해결책이 아니며, 상황에 따라 적절한 도구를 선택하는 것이 중요합니다. - **널 객체를 권장하는 경우**: 일반적인 경우와 오류/경계 상황을 굳이 구분할 필요가 없거나, '오류'를 나타내는 후보가 너무 많아 정적 검증이 오히려 복잡해질 때 사용합니다. - **정적 타입을 권장하는 경우**: 비즈니스 로직상 오류 상태를 반드시 인지하고 별도의 처리(예: 에러 다이얼로그 표시)를 수행해야 한다면 널 객체 대신 언어에서 제공하는 `null`이나 `Optional`을 활용하여 타입 시스템의 보호를 받아야 합니다.

line원문

테크 컨퍼런스 Tech-Verse 2025를 개최합니다 (새 탭에서 열림)

LY Corporation은 오는 6월 30일부터 7월 1일까지 양일간 글로벌 테크 컨퍼런스인 'Tech-Verse 2025'를 개최합니다. 이번 행사는 AI와 보안을 메인 테마로 하여 전 세계 그룹사 엔지니어들이 경험한 127개의 기술 세션을 온라인으로 공유할 예정입니다. 누구나 무료 사전 등록을 통해 참여할 수 있으며, 한국어, 영어, 일본어 실시간 통역이 제공되어 글로벌 기술 트렌드를 깊이 있게 파악할 수 있는 기회를 제공합니다. **Tech-Verse 2025 행사 개요 및 참여 방법** * **일정 및 방식**: 2025년 6월 30일(월)부터 7월 1일(화)까지 매일 오전 10시에서 오후 6시 사이에 진행되며, 전 세션 온라인 스트리밍으로 생중계됩니다. * **참여 대상**: 공식 사이트에서 사전 등록만 하면 누구나 무료로 시청할 수 있어 접근성이 높습니다. * **글로벌 협업**: 한국의 LINE Plus를 비롯해 일본, 대만, 베트남 등 LY Corporation 그룹사 전체의 엔지니어, 디자이너, 프로덕트 매니저가 참여하여 폭넓은 기술 생태계를 다룹니다. **12개 분야의 방대한 기술 세션 구성** * **일자별 트랙 구성**: 1일 차에는 AI, 보안, 서버사이드, 프라이빗 클라우드 등 인프라 중심의 세션이 배치되며, 2일 차에는 AI 유즈 케이스, 프론트엔드, 모바일 앱, 디자인 및 제품 관리 등 사용자 접점 기술을 중점적으로 다룹니다. * **다국어 지원**: 총 127개의 세션에 대해 3개 국어(한/영/일) 실시간 통역을 지원하여 언어 장벽 없이 기술적 디테일을 학습할 수 있습니다. * **핵심 테마**: 최근 IT 업계의 화두인 생성형 AI의 실무 적용과 고도화된 보안 전략이 전체 컨퍼런스의 중심축을 이룹니다. **분야별 주목해야 할 주요 기술 사례** * **AI 및 데이터 파이프라인**: 단순한 코드 작성을 넘어 전문적인 AI 코딩 프로세스로의 진화와 생성형 AI를 활용한 데이터 파이프라인 구축 및 분석 자동화 사례가 소개됩니다. * **인프라 및 서버사이드**: 'Central Dogma Control Plane'을 활용해 수천 개의 마이크로서비스를 연결하는 대규모 인프라 관리 기법과 LINE Call의 영상 품질 개선을 위한 서버 기술이 공유됩니다. * **앱 개발 및 사용자 경험**: 배달 서비스 '데마에칸(Demae-can)'의 개발 환경을 React Native에서 Flutter로 전면 교체한 과감한 이행 전략과 데이터 기반의 LINE Talk 사용자 인사이트 도출 과정이 포함되어 있습니다. **참여 권장 및 실용 가이드** 최신 기술 트렌드와 대규모 서비스 운영 노하우를 얻고 싶은 개발자라면 Tech-Verse 2025 공식 사이트를 통해 관심 있는 세션을 미리 타임테이블에 등록해 두는 것이 좋습니다. 특히 현업에서 AI 도입을 고민하거나 대규모 트래픽 처리를 위한 인프라 구조를 연구하는 엔지니어들에게 실질적인 기술적 영감을 줄 것으로 기대됩니다.

line원문

일 평균 30억 건을 처리하는 결제 시스템의 DB를 Vitess로 교체하기 - 1. 솔루션 선정기 (새 탭에서 열림)

LINE 결제 플랫폼 팀은 라이선스 비용 절감과 시스템 확장성 확보를 위해 기존 Nbase-T 시스템을 오픈소스 데이터베이스 클러스터링 솔루션인 Vitess로 마이그레이션하기로 결정했습니다. Apache ShardingSphere, TiDB 등 다양한 분산 DB 솔루션을 대상으로 성능과 운영 편의성을 비교 분석한 결과, 대규모 트래픽 환경에서 검증된 안정성과 고가용성을 제공하는 Vitess가 최종 후보로 선정되었습니다. 이번 과정은 결제 시스템이라는 특수성에 맞춰 서비스 중단 없는 전환과 물리 서버 환경에서의 최적화 가능성을 검증하는 데 주력했습니다. ### 후보 솔루션별 특징 및 제외 사유 * **Apache ShardingSphere**: 프락시(Proxy)와 JDBC 레이어 방식을 모두 지원하여 유연한 아키텍처 구성이 가능하지만, 데이터가 각 샤드에 고르게 분배되지 않을 경우 리샤딩(리밸런싱) 기능을 직접 구현해야 한다는 치명적인 단점이 있어 후보에서 제외되었습니다. * **TiDB**: MySQL 호환 분산 SQL DB로, SQL 계층(TiDB), 메타데이터 관리(PD), 행/열 기반 저장소(TiKV/TiFlash)로 분리된 구조를 가집니다. 샤딩키 설정 없이도 데이터를 자동 리밸런싱하여 운영 비용을 낮출 수 있다는 장점이 있어 유력한 후보로 PoC를 진행했습니다. * **Vitess**: YouTube에서 개발된 CNCF 프로젝트로, 샤딩 기술을 통해 수평 확장을 지원하며 베어 메탈 환경 설치가 가능해 결제 시스템에 필요한 높은 수준의 안정성을 확보할 수 있습니다. ### Vitess의 구조적 장점과 컴포넌트 역할 * **VTGate**: 클라이언트의 쿼리를 적절한 샤드로 라우팅하고 분산 트랜잭션을 처리하며, 애플리케이션에는 단일 DB처럼 보이도록 추상화 레이어를 제공합니다. * **VTTablet 및 VTorc**: 각 MySQL 인스턴스 앞에 위치하여 쿼리 실행과 복제를 관리하며, VTorc를 통해 장애 발생 시 자동으로 장애 조치(Failover)를 수행하여 고가용성을 유지합니다. * **토폴로지 서버**: ZooKeeper나 etcd를 활용해 클러스터의 구성 정보와 노드 상태를 중앙에서 관리함으로써 분산 환경의 일관성을 보장합니다. ### PoC를 통한 성능 및 운영 환경 검증 * **환경 일치화**: 실제 결제 시스템과 동일한 사양의 장비와 테이블 구조를 설정하여 Nbase-T, Vitess, TiDB 간의 성능 비교를 수행했습니다. * **성능 테스트 결과**: 순수 성능(TPS 및 CPU 효율) 관점에서는 기존 Nbase-T가 가장 우수했으나, Vitess 역시 대규모 요청 상황에서 안정적인 리소스 처리 능력을 보여주었습니다. * **유연한 설정**: Vitess는 필요에 따라 조회와 입력을 프라이머리와 레플리카로 분리하는 기능을 지원하며, 모든 DB 노드에 일괄적인 DDL 수행이 가능하여 관리 효율성이 높음을 확인했습니다. 결제와 같이 높은 신뢰성이 요구되는 시스템을 마이그레이션할 때는 단순한 쿼리 처리 성능뿐만 아니라 자동 장애 복구(Failover) 능력과 데이터 리샤딩의 용이성을 우선적으로 고려해야 합니다. Vitess는 글로벌 대형 서비스들에서 이미 안정성이 검증되었고, 베어 메탈 환경에서도 유연한 최적화가 가능하므로 대규모 MySQL 클러스터 운영이 필요한 조직에 강력히 추천되는 솔루션입니다.

line원문

AI와 글쟁이의 동행: 코드 주면 API 레퍼런스 써드려요 (새 탭에서 열림)

기술 문서 부족 문제를 해결하기 위해 엔지니어링 관점에서 접근한 이 글은, 생성형 AI를 활용해 사내 기술 컨텍스트와 스타일 가이드가 반영된 API 레퍼런스를 자동 생성하는 프로젝트 과정을 소개합니다. 일반적인 코딩 어시스턴트의 한계를 극복하기 위해 프롬프트 워크플로를 최적화하고, 특정 IDE에 종속되지 않도록 MCP(Model Context Protocol)를 도입하여 범용성을 확보했습니다. 최종적으로 AI가 생성한 결과물은 높은 품질을 보였으나, 기술 문서의 특성상 정확성을 담보하기 위한 인간의 검토 단계가 필수적임을 강조하며 결론을 맺습니다. ## 기존 AI 도구의 한계와 도큐먼트 엔지니어링의 목표 * 기술 문서는 항상 부족하며, 개발자 교육만으로는 시간과 관심의 부재라는 근본적인 원인을 해결하기 어렵다는 판단하에 자동화 프로세스를 구축했습니다. * GitHub Copilot과 같은 기존 도구는 코드 파악 능력은 뛰어나지만, 사내 전용 기술 용어나 특수한 스타일 가이드, 프로젝트별 컨텍스트를 반영하지 못하는 단점이 있습니다. * '사내 정보를 참고해 스타일 가이드에 맞는 API 주석을 작성하고, 이를 한곳에서 배포하기'를 목표로 테크니컬 라이터의 노하우를 자동화 공정에 이식했습니다. ## 프롬프트 최적화와 단계별 워크플로 구성 * 초기에는 방대한 지시 사항이 담긴 긴 프롬프트를 사용했으나, LLM이 복잡한 지시를 놓치는 문제가 발생하여 실행 단계를 세분화했습니다. * 처리 속도와 정확도 사이의 타협점을 찾기 위해 '프로그래밍 언어 인식', 'API 파악 및 예제 작성', '설명 및 파라미터/응답 값 작성'의 3단계 워크플로로 압축했습니다. * LINE의 고유 식별자인 'MID'를 단순한 약어(Member ID 등)로 오해하지 않고 사내 정의에 맞게 설명하도록 컨텍스트를 주입하여 일반 AI 도구와 차별화된 품질을 구현했습니다. ## 범용성 확보를 위한 MCP(Model Context Protocol) 도입 * 초기 프로토타입은 VS Code 익스텐션으로 제작했으나, IntelliJ 등 다양한 IDE를 사용하는 개발자들의 요구를 수용하기 위해 MCP 기반으로 전환했습니다. * MCP 서버는 클라이언트와의 통신에만 집중하므로, UI 구현에 드는 비용을 줄이고 언어 판별이나 코드 블록 선택 같은 부가 기능을 MCP 호스트(IDE 등)에 위임할 수 있습니다. * 사용자가 AI와 대화하며 파라미터를 입력하는 방식은 현대적인 AI 사용 경험에 부합하며, 특정 도구에 종속되지 않는 범용적인 문서화 솔루션을 제공합니다. ## AI 문서화의 성과와 실질적인 한계 * 자체 평가 결과, 생성된 주석의 88%가 기준을 만족했으며 78%의 사례에서 GitHub Copilot보다 우수한 품질의 설명을 생성하는 성과를 거두었습니다. * 그러나 AI는 확률 기반으로 작동하므로 100%의 정확성을 보장하지 못하며, 단 한 줄의 오류가 문서 전체의 신뢰도를 떨어뜨리는 API 레퍼런스의 특성상 위험 요소가 존재합니다. * 따라서 AI를 '완벽하지 않은 동반자'로 정의하고, AI가 초안을 대량으로 빠르게 생산하되 마지막 단계에서는 반드시 담당 개발자가 내용을 검토하는 '사람 중심의 검증' 프로세스를 권장합니다.

line원문

코드 품질 개선 기법 15편: 문법은 이름을 나타낸다 (새 탭에서 열림)

개발 시 식별자의 이름을 지을 때는 선언부의 시각적 통일성보다 호출부에서 문법적으로 자연스럽게 읽히는지를 우선해야 합니다. 수식어를 뒤에 붙이는 방식은 목록화했을 때 보기 좋을 수 있으나, 실제 코드에서 사용될 때는 문법적 오해를 불러일으켜 가독성을 저해할 위험이 크기 때문입니다. 따라서 명명법의 기준을 ‘작성자의 편의’가 아닌 ‘사용자의 이해도’에 두는 것이 코드 품질 개선의 핵심입니다. **수식어 위치에 따른 가독성 차이** - 클래스를 분할할 때 `SettingRepositorySecurity`와 같이 수식어를 뒤에 붙이면(Postfix), 정의부에서는 일관성이 있어 보이지만 호출부에서는 문법적 오해를 낳을 수 있습니다. - 예를 들어 해당 클래스를 사용하는 측에서는 이를 'SettingRepository의 보안 모듈'로 잘못 해석할 수 있으며, 이는 코드를 읽는 속도를 늦추는 원인이 됩니다. - 반면 `SecuritySettingRepository`와 같이 수식어를 앞에 붙이는 방식(Prefix)은 영문법에 부합하여 클래스의 정체성을 훨씬 명확하게 전달합니다. **복합 수식어가 필요한 경우의 처리** - 수식어가 여러 개여서 단순히 앞에 나열할 경우 의미가 왜곡될 때는 전치사(of, for, at 등)를 활용하여 의미를 명확히 해야 합니다. - '세로 모드에서의 전송 버튼 높이'를 명명할 때 `portraitSendButtonHeight`는 '세로 이미지를 보내는 버튼'으로 오해받을 수 있으므로, `sendButtonHeightForPortrait`와 같이 표현하는 것이 바람직합니다. - 다만, 클래스나 구조체 같은 타입 이름에는 전치사 사용을 피하는 것이 좋은데, 이는 인스턴스 생성 시 타입 이름의 마지막 단어를 주로 사용하게 되는 관례 때문입니다. **언어 및 플랫폼 관습의 존중** - 문법적 정확성만큼이나 해당 언어 공동체의 관습을 따르는 것도 중요합니다. - Java나 Kotlin의 `currentTimeMillis`처럼 전치사가 생략되어도 충분히 의미가 전달되는 표준 API 사례가 있다면, 이를 참고하여 해당 플랫폼의 스타일과 일관성을 유지해야 합니다. 명확한 이름을 짓기 위해서는 항상 "이 이름을 처음 본 개발자가 문법적으로 오해할 여지가 없는가?"를 자문해 보아야 합니다. 선언부의 정렬된 모습보다는 코드가 실제로 쓰이는 맥락에서의 직관성을 최우선으로 고려할 것을 권장합니다.

line원문

LINE 앱 영상 통화를 가장 많이 사용하는 나라, 태국에서 LINE 앱의 영상 통화 품질을 점검했습니다 (새 탭에서 열림)

LINE은 태국 현지 점검을 통해 자사 영상 통화 서비스가 경쟁사 대비 높은 화질과 비트레이트를 제공하며 우수한 통화 품질을 유지하고 있음을 확인했습니다. 초기 연결 단계부터 고품질 미디어를 전송하는 전략을 통해 사용자 체감 품질(QoE)을 극대화하고 있으나, 이는 네트워크 환경에 따른 프리징 발생 가능성이라는 기술적 트레이드오프를 동반합니다. 결과적으로 LINE은 지역별 네트워크 특성에 최적화된 비트레이트 균형점을 찾는 정교한 튜닝을 통해 글로벌 시장에서의 기술적 경쟁력을 확보하고 있습니다. **태국 시장의 영상 통화 특수성과 점검 배경** * 태국은 1:1 통화 중 영상 통화가 차지하는 비중이 30.43%로, 일본이나 대만 등 타 국가 대비 2배 이상 높은 영상 통화 핵심 시장입니다. * 2022년 이후 2년 만에 진행된 이번 점검은 현지 네트워크(True, AIS)의 변화를 반영하고, 점유율이 상승 중인 경쟁사 메신저와의 기술적 격차를 분석하기 위해 수행되었습니다. * 엔지니어가 직접 방콕 시내 쇼핑몰과 외곽 시장 등 사람이 붐비는 환경에서 4G 및 5G 네트워크를 통해 실시간 품질을 정성·정량적으로 평가했습니다. **현지 네트워크 기반의 실질적 품질 측정 방식** * 제한된 출장 일정과 장비의 한계를 극복하기 위해 엔지니어의 정성적 체감 품질 평가와 사후 패킷 분석을 병행했습니다. * 서비스 품질(QoS) 지표인 패킷 손실률, 지연 시간 편차 등을 수집하여 실제 사용자 체감 품질(QoE)을 추정하는 방식을 채택했습니다. * 측정 결과 LINE은 VGA 해상도, 20 FPS 이상의 프레임 레이트, 평균 150ms 수준의 낮은 지연 시간을 기록하며 전반적으로 우수한 성능을 입증했습니다. **비트레이트 전략과 화질 우위 확보** * 화질 비교 결과, LINE은 4G와 5G 모든 환경에서 경쟁사 대비 선명한 영상을 제공하며 높은 사용자 만족도를 보였습니다. * 비트레이트 설정값에서 LINE은 5G 1Mbps, 4G 600kbps의 최대치를 적극적으로 활용하는 반면, 경쟁사는 낮은 비트레이트에서 보수적으로 수치를 올리는 전략을 사용합니다. * LINE은 통화 시작 단계에서 전송 가능한 최대 비트레이트를 예측하여 즉시 고화질로 연결하는 기술을 적용해 초기 미디어 품질을 확보했습니다. **네트워크 상태와 비트레이트의 기술적 트레이드오프** * 비트레이트가 높을수록 화질은 좋아지지만, 네트워크가 불안정한 환경(이동 중이거나 혼잡한 지역)에서는 패킷 지연과 유실로 인해 화면이 멈추는 '프리징' 현상이 발생할 가능성이 커집니다. * 경쟁사는 화질을 다소 희생하더라도 네트워크 악조건에서 일관된 안정성을 유지하는 방향을 택한 것으로 분석됩니다. * LINE은 200ms 이상의 프레임 노출을 프리징으로 정의하고 관리하며, 고화질 제공과 안정성 사이의 최적의 균형점을 찾기 위해 비트레이트 제어 알고리즘을 지속적으로 고도화하고 있습니다. 네트워크 환경이 시시각각 변하는 모바일 환경에서는 절대적인 설정값보다 실시간 네트워크 예측 기술이 핵심입니다. 사용자에게 초기부터 고화질 경험을 제공하되, 환경 악화 시 유연하게 대응할 수 있는 적응형 비트레이트 제어(Adaptive Bitrate Control) 최적화가 글로벌 통화 품질 경쟁력을 결정짓는 요소가 될 것입니다.

line원문

코드 품질 개선 기법 14편: 책임을 부여하는 오직 하나의 책임 (새 탭에서 열림)

단일 책임 원칙(SRP)을 기계적으로 적용하여 클래스를 과도하게 분리하면, 오히려 시스템 전체의 복잡도가 증가하고 사양의 제약 조건을 파악하기 어려워질 수 있습니다. 코드 품질을 높이기 위해서는 개별 클래스의 응집도뿐만 아니라, 분리된 클래스들이 맺는 의존 관계와 호출자가 짊어져야 할 관리 부담을 종합적으로 고려해야 합니다. 결국 핵심적인 제약 조건을 한곳에서 관리할 수 있다면, 약간의 책임이 섞여 있더라도 초기 구현의 단순함을 유지하는 것이 더 나은 선택일 수 있습니다. **과도한 책임 분리가 초래하는 문제** * 동적으로 실행 로직이 변하는 '론치 버튼'을 구현할 때, 버튼 바인딩 책임과 로직 선택 책임을 별도 클래스로 분리하면 각 클래스는 단순해지지만 시스템 구조는 복잡해집니다. * 로직별로 별도의 바인더 인스턴스를 생성하고 `isEnabled` 상태를 통해 실행 여부를 제어하게 되면, 버튼 하나에 여러 개의 리스너가 등록되는 등 내부 동작을 추적하기 어려워집니다. * 결과적으로 "단 하나의 로직만 실행되어야 한다"는 비즈니스 제약 조건을 확인하기 위해 여러 클래스와 루프 문을 모두 훑어야 하는 비용이 발생합니다. **제약 조건의 분산과 상태 중복** * 책임을 분리하면 특정 사양이 코드 전체로 흩어지는 '책임 떠넘기기' 현상이 발생할 수 있습니다. * 예를 들어 어떤 로직이 활성화되었는지 나타내는 상태를 상위 클래스(Selector)에 추가하면, 하위 클래스(Binder)의 `isEnabled` 속성과 데이터가 중복되어 상태 불일치 문제가 생길 위험이 있습니다. * 이러한 중복은 코드의 신뢰성을 떨어뜨리며, 사양 변경 시 수정해야 할 포인트가 늘어나는 결과를 초래합니다. **의존성 비대화와 라비올리 코드(Ravioli Code)** * 세부 사항을 은닉하기 위해 의존 관계를 더 잘게 쪼개면, 이를 조합해야 하는 호출자(Caller)의 코드가 비대해지는 '갓 클래스(God Class)' 현상이 나타날 수 있습니다. * 너무 작은 단위로 쪼개진 클래스들이 서로 얽히면 전체 흐름을 파악하기 위해 수많은 파일을 오가야 하는 '라비올리 코드'가 되어 유지보수성이 저하됩니다. * 객체 지향의 핵심은 캡슐화인데, 제약 조건을 보장하는 로직을 분리해버리면 오히려 캡슐화가 깨지고 외부 의존성만 강해지는 부작용이 생깁니다. **실용적인 설계를 위한 제언** 클래스를 분할할 때는 응집도라는 단일 지표에만 매몰되지 말고, 분할 후의 의존성 그래프와 호출자의 편의성을 반드시 확인해야 합니다. 만약 특정 클래스가 내부에서 핵심 제약 조건을 깔끔하게 관리하고 있다면, 억지로 책임을 나누기보다 그 응집된 구조를 유지하는 것이 시스템 전체의 결합도를 낮추고 코드의 가독성을 높이는 길입니다.

line원문

복잡한 회원 인증 프로세스, 기본 원칙만 알면 쉽습니다 (새 탭에서 열림)

회원 인증 체계는 서비스의 신뢰도와 직결되는 핵심 요소로, 설계 단계부터 서비스 특성에 맞는 인증 방식을 전략적으로 선택하는 것이 중요합니다. 일본 배달 서비스 '데마에칸'은 인증 기술의 전환과 사용자 흐름 개선을 통해 부정 사용자를 획기적으로 차단하고 가입 이탈률을 대략 30%나 낮추는 성과를 거두었습니다. 이 글은 복잡한 인증 절차를 목적별로 그룹화하고 비용 효율적인 기술을 도입하여 보안과 편의성을 동시에 확보한 실무 사례를 상세히 다룹니다. **부실한 인증 설계가 초래하는 운영 리스크** * **유령 회원 및 데이터 오염:** 실제 존재하지 않는 정보를 입력한 회원을 식별하지 못할 경우, 추후 마케팅이나 운영 과정에서 연락이 불가능한 '엣지 케이스'가 누적됩니다. * **신규 가입 방해:** 타인의 정보를 도용하여 가입된 계정이 있을 경우, 해당 정보의 실제 소유자가 신규 가입을 시도할 때 본인 증명 과정이 복잡해져 이탈을 유발합니다. * **어뷰징 방어 불가:** 쿠폰 이벤트 등 마케팅 비용이 투입될 때 식별 장치가 없다면, 중복 가입이나 부정 사용자를 걸러낼 수 없어 직접적인 금전적 손실이 발생합니다. **국내와 해외 인증 체계의 기술적 차이** * **국내의 본인 인증 체계:** 전자 정부 시스템을 기반으로 이름, 주민등록번호, 연락처를 결합한 강력한 '본인 인증(Identity Authentication)'이 가능하며 PASS 앱이나 1원 인증 등이 대표적입니다. * **해외의 점유 인증 방식:** 일본을 포함한 많은 국가에서는 한국과 같은 통합 본인 확인 시스템이 없으므로, 해당 정보를 실제로 소유하고 있는지만 확인하는 '점유 인증(Possession Authentication)'에 주로 의존합니다. * **인증 정보의 관리:** 높은 보안 수준이 필요한 서비스일수록 인증 정보의 유효 기간을 설정하고, 탈퇴 후 재가입 방지를 위한 데이터 보관 기간을 신중하게 설계해야 합니다. **비용 효율을 고려한 부정 사용자 차단 전략** * **SMS에서 발신 인증(IVR)으로 전환:** 일본 내에서 SMS 수신 가능 번호를 구매하는 비용보다 전화 수신 가능 번호를 구매하는 비용이 훨씬 비싸다는 점에 착안했습니다. * **어뷰징 대응 성과:** 기존 SMS 인증 시 20%를 상회하던 부정 사용자 비율이 전화 발신 인증 도입 후 1.5%로 대폭 감소하여 마케팅 예산 낭비를 방지했습니다. **사용자 경험(UX) 최적화를 통한 가입 흐름 개선** * **목적별 단계 그룹화:** 파편화되어 있던 주소 입력과 인증 절차를 개선하여, 1단계에서 발신/이메일 인증을 완료하고 2단계에서 개인 정보를 입력하도록 흐름을 정돈했습니다. * **입력 간소화 및 SNS 연동:** 소셜 로그인 버튼을 이메일 입력 단계로 전진 배치하여, SNS에서 받아온 정보를 통해 이후 입력 항목을 자동 완성하고 심리적 허들을 낮췄습니다. * **이탈 방지 장치 마련:** 이메일 오기입 시 가입 과정을 처음부터 다시 시작하지 않도록 '뒤로 가기' 버튼을 제공하고, 화면 이탈 시 경고 메시지를 띄워 가입 완료를 유도했습니다. * **데이터 기반 개선:** 위와 같은 설계를 통해 기존 46%에 달하던 가입 이탈률을 17%까지 낮추는 수치적 성과를 달성했습니다. 성공적인 인증 시스템 구축을 위해서는 서비스가 직면한 부정 사용의 형태를 정확히 파악하고, 무조건 복잡한 단계를 추가하기보다 인증 수단의 비용 대비 효과를 면밀히 따져봐야 합니다. 또한, 강화된 보안 절차가 사용자의 이탈로 이어지지 않도록 목적별로 단계를 그룹화하고 로그 설계를 통해 병목 지점을 지속적으로 모니터링하는 것이 권장됩니다.

line원문

코드 품질 개선 기법 13편: 클론 가족 (새 탭에서 열림)

두 개의 상속 트리가 서로 암묵적으로 대응하며 발생하는 '클론 가족' 문제는 코드의 타입 안정성을 해치고 유지보수를 어렵게 만듭니다. 이 글은 코드 공통화를 위한 부적절한 상속 사용을 경계하고, 대신 컴포지션이나 제네릭을 활용하여 데이터 모델 간의 관계를 명확히 정의함으로써 런타임 오류 가능성을 줄이는 방법을 제시합니다. ### 클론 가족 현상과 타입 안정성 문제 데이터를 공급하는 클래스 계층과 데이터 모델 계층이 서로 일대일로 대응하지만, 이 관계가 코드상에서 명시되지 않을 때 문제가 발생합니다. * **다운캐스팅의 필요성**: 부모 공급자 클래스가 공통 데이터 모델 인터페이스를 반환할 경우, 실제 사용 시점에서는 구체적인 타입으로 변환하는 다운캐스팅(`as`)이 강제됩니다. * **암묵적 제약 조건**: '특정 공급자는 특정 모델만 반환한다'는 규칙이 컴파일러가 아닌 개발자의 머릿속에만 존재하게 되어, 코드 변경 시 실수로 인한 오류가 발생하기 쉽습니다. * **유연성 부족**: 하나의 공급자가 여러 모델을 반환하거나 구조가 복잡해질 때, 타입 검사만으로는 시스템의 안전성을 보장하기 어렵습니다. ### 상속 대신 애그리게이션과 컴포지션 활용 단순히 로직의 공통화가 목적이라면 상속보다는 기능을 분리하여 포함하는 방식이 더 효과적입니다. * **로직 추출**: 공통으로 사용하는 데이터 획득 로직을 별도의 클래스(예: `OriginalDataProvider`)로 분리합니다. * **의존성 주입**: 각 공급자 클래스가 분리된 로직 클래스를 속성으로 가지도록 설계하면, 부모 클래스 없이도 코드 중복을 피할 수 있습니다. * **타입 명확성**: 각 공급자가 처음부터 구체적인 데이터 타입을 반환하므로 다운캐스팅이 아예 필요 없어집니다. ### 제네릭을 이용한 매개변수적 다형성 적용 여러 공급자를 하나의 컬렉션으로 관리해야 하는 등 상속 구조가 반드시 필요한 경우에는 제네릭을 통해 타입을 명시해야 합니다. * **타입 파라미터 지정**: 부모 클래스에 타입 파라미터 `T`를 도입하여, 자식 클래스가 어떤 타입의 데이터를 반환하는지 컴파일 시점에 명시하도록 합니다. * **상한 제한(Upper Bound)**: 필요한 경우 `T : CommonDataModel`과 같이 제약 조건을 추가하여 최소한의 공통 인터페이스를 보장할 수 있습니다. * **업캐스팅 지원**: 제네릭을 사용하면 부모 타입으로 관리하면서도 각 인스턴스가 반환하는 타입의 안전성을 유지할 수 있어 활용도가 높습니다. 상속은 강력한 도구이지만 단순히 코드를 재사용하기 위한 목적으로 사용하면 의도치 않은 타입 문제를 야기할 수 있습니다. 클래스 간의 관계가 암묵적인 제약에 의존하고 있다면, 이를 컴포지션으로 분리하거나 제네릭을 통해 명시적인 관계로 전환하는 것이 견고한 코드를 만드는 핵심입니다.

line원문

문의 대응을 효율화하기 위한 RAG 기반 봇 도입하기 (새 탭에서 열림)

LY 주식회사의 SR(Service Reliability) 팀은 반복되는 AWX 플랫폼 관련 문의를 효율적으로 처리하기 위해 RAG(검색 증강 생성) 기반의 지원 봇을 도입했습니다. 이 시스템은 사용자가 방대한 가이드 문서를 읽지 않고 중복된 질문을 던질 때 발생하는 운영 리소스 소모 문제를 해결하기 위해 고안되었습니다. 사내 위키와 과거 상담 이력을 활용해 정확도 높은 답변을 생성함으로써 관리자의 개입 없이도 사용자 문제를 신속하게 해결하는 성과를 거두었습니다. **AWX 지원 봇의 기술 스택 및 구성** - **LLM 및 프레임워크:** OpenAI의 GPT 모델을 메인 엔진으로 사용하며, LangChain 프레임워크를 통해 전체적인 워크플로를 관리합니다. Slack과의 연동은 Bolt for Python을 활용했습니다. - **임베딩 모델:** 다국어 지원 및 문장 비교 성능이 뛰어난 'paraphrase-multilingual-mpnet-base-v2' 모델(SBERT)을 선택하여 글로벌 임직원의 다양한 언어 문의에 대응합니다. - **벡터 데이터베이스:** 사내에서 PaaS 형태로 제공되어 접근성이 높은 OpenSearch를 사용하며, 텍스트 데이터를 고차원 벡터로 변환하여 저장하고 검색합니다. **RAG 및 벡터 검색을 통한 답변 정확도 향상** - **LLM의 한계 극복:** 학습되지 않은 최신 정보 부재나 허위 정보 생성(Hallucination) 문제를 해결하기 위해, 질문과 관련된 신뢰할 수 있는 컨텍스트를 LLM에 함께 전달하는 RAG 기법을 적용했습니다. - **벡터 검색 원리:** 사용자의 질문을 임베딩하여 벡터화한 뒤, 벡터 DB 내에서 의미적으로 유사한 문장들을 k-NN(최근접 이웃) 방식으로 검색하여 최적의 참고 자료를 추출합니다. - **유사도 기반 추출:** 단순 키워드 매칭이 아닌 의미적 유사성을 판단하므로, 'Buy'와 'Purchase'처럼 단어는 달라도 맥락이 같은 정보를 정확히 찾아낼 수 있습니다. **봇 워크플로 및 데이터 활용 전략** - **사용자 상호작용:** 사용자가 Slack으로 문의하면 봇이 사내 위키와 과거 Slack 스레드 데이터를 검색합니다. 추출된 데이터를 바탕으로 LLM이 1차 답변을 제공하며, 해결되지 않을 경우에만 '관리자 호출' 버튼을 통해 담당자를 연결합니다. - **데이터 소스 다각화:** 공식 가이드 문서뿐만 아니라 실제 사용자들이 겪었던 문제와 해결책이 담긴 'Slack 문의 스레드 데이터'를 함께 인덱싱하여 실무적인 답변이 가능하도록 구성했습니다. - **리소스 최적화:** 봇의 자동 응답을 통해 단순 반복 문의에 대한 관리자의 수동 대응 시간을 줄이고, 개발 조직이 서비스 운영 본연의 업무에 더 집중할 수 있는 환경을 조성했습니다. RAG 기반 시스템을 구축할 때 가장 중요한 것은 신뢰할 수 있는 데이터 소스의 확보입니다. LY의 사례처럼 공식 문서와 실제 상담 이력을 병행 활용하면 LLM이 훨씬 구체적이고 실무에 유효한 답변을 생성할 수 있습니다. 운영 중인 서비스의 문의 대응 리소스가 부담된다면, 익숙한 벡터 DB와 오픈소스 임베딩 모델을 조합한 RAG 봇 도입을 적극 추천합니다.

line원문

코드 품질 개선 기법 12편: 세트 할인 (새 탭에서 열림)

여러 속성을 개별적으로 변경할 수 있게 허용하는 구조는 상태 간의 불일치를 초래하고 예기치 못한 버그를 유발할 수 있습니다. 이를 해결하기 위해 서로 연관된 상태들을 하나의 객체로 묶어 한 번에 업데이트하도록 인터페이스를 제한하면 시스템의 예측 가능성을 높일 수 있습니다. 결과적으로 코드의 의도가 명확해지고 스레드 안전성 확보와 디버깅이 훨씬 용이해집니다. **개별 속성 변경의 위험성** * **실행 순서 의존성:** 활성화 상태(`isActive`)와 세부 설정(`minImportanceToRecord` 등)이 분리되어 있으면, 설정을 변경하기 전에 활성화를 먼저 시도할 경우 의도치 않게 이전 설정값이 적용되는 문제가 발생합니다. * **상태 초기화의 불일치:** 특정 속성이 변경될 때 내부 카운터가 초기화되어야 함에도 불구하고, 어떤 속성은 초기화를 수행하고 어떤 속성은 누락하는 등의 관리 포인트가 파편화되어 로직이 복잡해집니다. * **경쟁 상태(Race Condition):** 비동기 환경에서 여러 속성을 순차적으로 변경하면, 변경 중간에 다른 로직이 개입하여 불완전한 상태의 데이터를 읽게 될 위험이 있습니다. **데이터 묶음과 인터페이스 제한을 통한 개선** * **객체 캡슐화:** 연관된 설정값들을 `SamplingPolicy`와 같은 별도의 불변(Immutable) 클래스로 묶어 관리함으로써 속성들이 항상 한 세트로 업데이트되도록 강제합니다. * **상태 표현의 최적화:** 별도의 불리언 플래그 대신 상태 객체의 `null` 여부로 활성화 상태를 표현하여, 활성 상태일 때는 반드시 유효한 설정값이 존재함을 보장합니다. * **원자적 업데이트:** `startRecording`과 같이 명시적인 메서드를 통해서만 상태를 변경하게 함으로써 내부 카운터 초기화와 설정 변경이 한 번에(Atomic) 이루어지도록 제어합니다. **실용적인 결론** 단순히 모든 필드에 세터(setter)를 열어두는 것보다, 비즈니스 로직상 함께 움직여야 하는 데이터는 하나의 '상태 객체'로 정의하는 것이 좋습니다. 특히 한 속성의 변화가 다른 속성의 의미나 동작에 영향을 주는 경우에는 인터페이스를 엄격하게 제한하여 잘못된 상태 조합이 발생하는 것을 원천적으로 차단해야 합니다.

line원문

AI로 생성한 이미지는 어떻게 평가할까요? (인페인팅 적용편) (새 탭에서 열림)

배경 인물 제거(BPR) 기능을 구현하기 위해서는 사진의 빈 공간을 자연스럽게 채워주는 '인페인팅(Inpainting)' 기술의 선정이 핵심적이지만, 단순히 논문의 수치만으로는 실제 서비스 성능을 가늠하기 어렵습니다. 이를 해결하기 위해 LY Corporation 개발팀은 다양한 생성형 AI 모델과 평가 지표를 비교 분석하여, 실제 사람의 시각적 평가와 가장 유사한 결과를 도출하는 최적의 평가 체계를 구축하고자 했습니다. 결과적으로 고해상도와 큰 삭제 영역 등 실무적인 제약 조건을 반영한 자체 테스트를 통해 서비스에 가장 적합한 모델 선정 기준을 마련했습니다. **배경 인물 제거(BPR)의 3단계 프로세스** * **인스턴스 분할(Instance Segmentation):** 사진 속 각 픽셀이 어떤 객체(사람, 건물, 나무 등)에 속하는지 식별하여 개별적으로 인식합니다. * **주요 객체 탐지(Salient Object Detection):** 이미지에서 시선이 집중되는 메인 피사체와 제거 대상인 배경 인물을 픽셀 단위로 구분합니다. * **인페인팅(Inpainting) 수행:** 배경 인물이 제거된 빈 영역을 주변 환경과 조화롭게 재구성하여 채워 넣는 최종 단계로, 전체 결과물 품질에 가장 큰 영향을 미칩니다. **인페인팅 모델의 기술적 접근 방식** * **디퓨전(Diffusion) 계열:** 랜덤 노이즈에서 점진적으로 이미지를 복원하며, 복잡한 세부 사항을 자연스럽게 살리는 데 유리하지만 생성 속도가 상대적으로 느립니다. * **GAN(Generative Adversarial Network) 계열:** 생성자와 판별자가 경쟁하며 학습하는 구조로, 디퓨전 모델에 비해 이미지 생성 속도가 빠르다는 장점이 있습니다. * **성능의 가변성:** 저해상도나 좁은 영역에서는 대부분의 모델이 준수한 성능을 보이나, 고해상도 이미지에서 큰 영역을 삭제할 경우 모델별로 결과물의 품질 차이가 극명하게 발생합니다. **신뢰할 수 있는 인페인팅 모델 평가의 어려움** * **벤치마크의 한계:** 논문에서 제시하는 256x256 등 고정된 저해상도 지표는 실제 서비스의 고해상도 환경을 대변하지 못합니다. * **정답의 부재:** 이미지 생성은 하나의 정답이 존재하지 않으며, 다양한 결과물이 모두 정답이 될 수 있어 수치화된 평가가 복잡합니다. * **상황별 성능 변화:** 특정 테스트셋에서 우수한 모델이 다른 인페인팅 영역이나 데이터셋에서는 실망스러운 결과를 보여주는 경우가 빈번합니다. **실험을 통한 최적의 평가 방법 탐색** * **데이터셋 구성:** 품질 편차가 큰 10개의 이미지를 모은 'BPR 평가 데이터셋'과 표준인 'Places365'를 활용해 11개의 최신 인페인팅 모델(LaMa, HINT, FLUX.1 등)을 테스트했습니다. * **사용된 지표:** 단일 이미지 품질을 측정하는 Aesthetics score, CLIP-IQA, Q-Align과 모델 간 선호도를 비교하는 PickScore, ImageReward 등을 적용했습니다. * **최종 목표:** 사람이 직접 눈으로 평가하는 비용과 시간을 줄이면서도, 인간의 주관적 평가 결과와 가장 높은 상관관계를 갖는 자동화된 평가 지표를 찾는 데 집중했습니다. **성공적인 AI 기능을 위한 실용적 제언** 논문상의 지표(Metric)에만 의존하기보다는 실제 서비스가 적용될 환경(해상도, 객체 크기 등)과 유사한 자체 데이터셋을 구축하여 테스트해야 합니다. 특히 배경 인물 제거와 같이 시각적 자연스러움이 중요한 작업에서는 정량적 수치 너머의 '심미적 점수'를 반영할 수 있는 최신 생성형 AI 평가 방법론을 병행하여 모델을 검증하는 것이 필수적입니다.

line원문

코드 품질 개선 기법 11편: 반복되는 호출에 함수도 지친다 (새 탭에서 열림)

객체의 상태를 확인하고 그 결과에 따라 상태를 변경하는 로직은 호출자가 아닌 해당 객체 내부로 캡슐화하는 것이 코드 품질을 높이는 핵심입니다. 이를 통해 외부로 드러나는 상태 전이 로직을 단순화하고, 조건 확인 누락으로 인해 발생할 수 있는 잠재적인 버그를 효과적으로 방지할 수 있습니다. 특히 상태 변경 여부에 따른 후속 작업이 필요할 때는 복잡한 콜백보다 명확한 반환값을 활용하는 것이 코드의 가독성과 유지보수 측면에서 유리합니다. **상태 확인 로직의 내재화** * `if (receiver.a()) { receiver.b() }`와 같이 외부에서 객체의 상태를 묻고 동작을 결정하는 구조는 중복 호출의 번거로움과 확인 누락의 위험을 수반합니다. * 상태를 변경하는 함수(예: `markAsFriend`) 내부에서 직접 조건을 검사(예: `isFriend`)하도록 설계하면, 호출자는 객체의 내부 상태를 일일이 신경 쓰지 않고도 안전하게 기능을 수행할 수 있습니다. * 이러한 방식은 객체 내부의 상태 전이를 단순화하며, '이미 해당 상태인 경우 아무것도 하지 않는다'는 동작을 자연스럽게 보장합니다. * 만약 조건부 동작임을 명시적으로 드러내야 한다면 `markAsFriendIfNotYet`과 같이 함수 이름을 명확하게 짓거나 주석으로 보완하는 방법이 권장됩니다. **콜백 대신 반환값으로 결과 전달** * 상태 변경 성공 여부에 따라 팝업 노출과 같은 후속 작업이 필요할 때, 고차 함수를 통한 콜백(onSucceeded) 방식은 피하는 것이 좋습니다. * 콜백 방식은 의존성 순환을 일으킬 수 있고, 해당 로직이 동기적으로 실행되는지 비동기적으로 실행되는지 호출부에서 파악하기 어렵게 만듭니다. * 대신 `Boolean` 등의 반환값을 활용하면 호출자가 결과에 따라 후속 로직을 직접 제어할 수 있어 코드의 실행 흐름이 명확해집니다. * 이때 함수 이름에서 반환값의 의미가 명확히 드러나지 않는다면 문서화를 통해 보완하고, 호출자가 반환값을 반드시 확인하도록 강제하는 기법을 함께 사용할 수 있습니다. 객체 설계 시 "묻지 말고 시키라(Tell, Don't Ask)"는 원칙을 적용해 보시기 바랍니다. 객체 외부에서 상태를 묻고 판단하기보다, 객체가 스스로 자신의 상태를 확인하고 동작하게 함으로써 더 견고하고 읽기 쉬운 코드를 작성할 수 있습니다.