본문 바로가기

전체 글

iOS In-App Purchase 서버 검증 구현하기 (JWS 방식) 운영 중인 사이드 프로젝트에서 결제 기능을 개발하게 되었습니다. 2024년 이후 Apple의 영수증 검증 방식이 변경되었는데, 관련 한글 자료가 많지 않아 정리해봅니다. Apple 영수증 검증 방식의 변화 Apple은 2024년부터 기존 verifyReceipt API를 Deprecated 처리하고, JWS(JSON Web Signature) 기반 영수증 검증으로 전환했습니다. 기존 방식 (Deprecated) 클라이언트 → 서버 → Apple verifyReceipt API → 응답 Base64 인코딩된 영수증을 Apple 서버로 전송하고, Apple이 검증 후 JSON 응답을 반환하는 방식이었습니다. 문.. 더보기
[ 백트래킹 ] N과 M Backtracking 이란?백트래킹은 모든 가능한 경우를 탐색하되 조건을 만족하지 않는 경로를 미리 차단(가지치기)하는 알고리즘이다. 쉽게 말해가능한 선택지를 따라가며 시도한다.조건에 어긋나면 되돌아온다. -> 백트래킹조건을 만족하면 결과를 기록한다.DFS(깊이 우선 탐색)을 기반으로 구현한다. 우선 문제를 분석해보자.[백준 15649]https://www.acmicpc.net/problem/15649"1부터 N까지 자연수 중에서 중복 없이 M개를 고른 모든 수열을 출력하라"N개의 수 중에서 M개를 뽑되 순서가 중요하고, 중복은 허용되지 않는다. 해당 문제는 겉으로 보기엔 단순한 모든 경우 탐색 문제처럼 보이지만 실제로는 Combinatorial Explosion 다루는 예제처럼 보인다. 모든 경우를 .. 더보기
InnoDB 스토리지 엔진 아키텍처 MySQL 스토리지 엔진 중에 가장 많이 사용되는 InnoDB는 거의 유일하게 레코드 기반의 잠금을 제공하며, 그 때문에 높은 동시성 처리가 가능하고 안정적이며 성능이 뛰어나다. 이번 글에서는 InnoDB 스토리지 엔진의 핵심 아키텍처를 자세히 살펴보고자 한다.프라이머리 키에 의한 클러스터링InnoDB의 모든 테이블은 기본적으로 프라이머리 키를 기준으로 클러스터링되어 저장된다. 이는 프라이머리 키 값의 순서대로 디스크에 저장된다는 의미이고, 세컨더리 인덱스는 레코드의 주소 대신 프라이머리 키의 값을 논리적 주소로 사용한다.클러스터링과 넌클러스터링의 차이클러스터링 인덱스는 데이터가 인덱스 키 순서대로 물리적으로 정렬되어 저장되는 구조다. 반면 넌클러스터링 인덱스는 데이터의 실제 저장 순서와 무관하게 별도의.. 더보기
MySQL 엔진 아키텍처 이해하기 항상 MySQL을 사용하면서 전반적인 구조가 궁금했다. 두루뭉실하게 알았던 내용을 Real MySQL을 토대로 정리하고자 한다. MySQL 서버는 사람의 머리 역할을 담당하는 MySQL 엔진과 손발 역할을 담당하는 스토리지 엔진으로 구분된다.MySQL 엔진클라이언트로부터 접속 및 쿼리 요청을 처리하는 커넥션 핸들러와 SQL 파서 및 전처리기, 쿼리의 최적화된 실행을 위한 옵티마이저가 중심을 이룬다.스토리지 엔진MySQL 엔진은 요청된 SQL 문장을 분석하거나 최적화하는 등 DBMS의 두뇌에 해당하는 처리를 수행하고, 실제 데이터를 디스크 스토리지에 저장하거나 디스크 스토리지로부터 데이터를 읽어오는 부분은 스토리지 엔진이 담당한다.스레딩 구조MySQL 서버는 프로세스 기반이 아니라 스레드 기반으로 동작한다.. 더보기
Ubuntu 한정된 자원 상태에 서버 튜닝하기 최근에 사내 서버 자원량 감축을 위해 개발 서버의 컴퓨팅 자원을 낮추기로 결정했는데요. 낮은 자원에서 많은 컨테이너를 띄우다보니 Thread Starvation 현상이 나타났어요. 한정된 자원에서 최선의 효율을 뽑기위해 아래와 같은 작업을 진행했습니다.Thread Starvation 쓰레드 기아 상태위키피디아에 따르면 기아 상태는 프로세스가 끊임없이 필요한 컴퓨팅 자원을 가져오지 못하는 상황으로, 이러한 자원 없이는 처리를 끝낼 수 없는 병행 컴퓨터에서 마주치는 문제에요. 기아 상태는 스케줄링이나 상호 배제 알고리즘의 오류에 기인하지만 자원 누수에 의해 일어날 수도 있으며 포크 폭탄과 서비스 거부 공격을 통해 고의적으로 발생할 수도 있어요. ec2.small 2코어 2G 렘을 사용하면서 여러 서버들과 맞.. 더보기
MySQL, PostgreSQL의 날짜와 시간 타입이 만든 혼란 최근 저는 라이선스 관리 시스템을 개발하면서 MySQL에서 PostgreSQL로 마이그레이션을 진행했는데요. 다른 팀과 협업 및 Postgres 기능적 이점(Extension, REST API 구현,Master-slave 등)을 고려해 선택하게 되었는데요. 마이그레이션을 진행하면서 날짜와 시간에 대한 차이점으로 인해 어려움을 겪었어요. Postgres를 토입하면서 저는 해외 사용을 고려해 타임존을 UTC로 고정하고 시간도 UTC 기준으로 저장하고 파싱되길 원했는데요. 이를 위해 OffsetDateTIme 타입을 JPA 엔티티에서 사용했고, 개발 초기에 ddl-auth: create 설정을 통해 자동 테이블을 생성해 개발을 이어갔어요. 여러 테스트를 진행하면서 미묘한 차이가 나타나 각 DB의 날짜/시간을 .. 더보기
[ 백준 / Java ] 2805 나무자르기 첫번 째 접근 방법(브루트 포스) public class B_2805 { public static void main(String[] args) { long startTime = System.currentTimeMillis(); Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int m = sc.nextInt(); List list = new ArrayList() { { for (int i = 0; i < n; i++) { add(sc.nextInt()); } } }; int max = list.stream().mapToInt(Integer::intValue).max().orElse(0); while(true) { int tree = 0; max--.. 더보기
[Java / Javascript] HashSet, HashMap HashSet 🤔 set 인터페이스를 구현하는 Java 컬렉션 프레임워크의 일부로 중복된 요소 없이 값을 저장하는 데이터 구조다. 그리고 비선형 구조이기 때문에 순서의 개념과 인덱스가 존재하지 않는다. 때문에 값을 추가/삭제 하는 경우 Set 내부에 해당 값을 검색하여 해당 기능을 수행해야 한다. 이로 인해 처리속도가 List에 비해 느리다는 것이 단점이다. HashSet은 내부적으로 HashMap을 사용하여 요소를 저장한다. 특징 요소의 순서를 보장하지 않는다. 하나의 null 값을 포함할 수 있다. 주로 데이터의 중복을 허용하지 않는 상황에서 사용한다. import java.util.HashSet; public class HashSetExample { public static void main(Str.. 더보기