자바의 동적 바인딩(Dynamic Binding)과 정적 바인딩(Static Binding)
·
Java/정리
A a = new B();Animal animal = new Dog(); "변수 타입은 Animal인데 왜 Dog의 메서드가 실행되지?" 이 질문의 답이 바로 동적 바인딩(Dynamic Binding)이다. 이번 포스트에서는 바인딩이 무엇인지부터 동적 바인딩과 정적 바인딩의 차이, 그리고 JVM 내부에서 어떤 일이 일어나는지까지 자세히 알아보자.바인딩(Binding)이란?바인딩(Binding)은 메서드 호출과 실제 실행될 메서드를 연결하는 과정을 의미한다.dog.sound();sound()를 호출했다. ▼어떤 클래스의 sound()를 실행해야 하지? ▼실제 실행할 메서드를 결정바인딩은 언제 일어날까?2가지가 존재실행(런타임) 시점실행 시점 (런타임) - 동적 바인딩컴파일 시점 -..
StringTokenizer의 사용
·
Java/정리
오라클 공식문서https://docs.oracle.com/en/java/javase/26/docs/api/java.base/java/util/StringTokenizer.htmlStringTokenizer is a legacy class that is retained for compatibility reasons although its use is discouraged in new code. It is recommended that anyone seeking this functionality use the split method of String or the java.util.regex package instead.StringTokenizer는 호환성(Compatibility)을 위해 남아있는 Legac..
Java 문자열 입력 처리 - Scanner와 BufferedReader
·
Java/정리
입력받는 방식Java에서 콘솔 입력을 받을 때 가장 많이 사용하는 클래스는 두 가지가 있다. 대부분 Scanner를 사용하지만, 코딩 테스트나 대용량 데이터를 처리할 때는 대부분 BufferedReader를 사용한다. 이번 글에서는 두 클래스가 만들어진 이유부터 내부 동작 방식, 성능 차이까지 정리해보려고 한다.ScannerScanner sc = new Scanner(System.in);String name = sc.nextLine();int age = sc.nextInt();nextInt()nextDouble()next()nextLine()굉장히 직관적이다. 입력받고 싶은 타입 그대로 메서드가 존재한다. 덕분에 초보자가 배우기 매우 쉽다. Scanner는 사용하기 편하도록 만들어진 입력 도구이다.Inp..
시간 복잡도 표기법
·
Python/코테
유형빅 오메가: 최선일 때의 연산 횟수를 나타낸 표기법빅 세타: 보통일 때의 연산 횟수를 나타낸 표기법빅 오: 최악일 때의 연산 횟수를 나타낸 표기법수 정렬하기 예시항상 최악의 경우를 생각해서 생각을 한다. 버블 정렬과 병합 정렬이 있을 경우에 시간 복잡도를 한번 생각해본다.버블 정렬: O(n^2)병합 정렬: O(nlogn)문제에서 주어진 시간 제한과 데이터 크기를 바탕으로 어떤 정렬 알고리즘을 사용해야 할 것인지를 판단해야한다.예시로 문제에 시간 제한 2초에 연산 횟수 4,000만 번 안에 원하는 답을 구해야 한다면, n = 1,000,000인 경우에 버블정렬은 1조 번의 연산 횟수가 필요하므로 적합한 알고리즘이 아니라고 판단할 수 있다.
프로그래머스 - 폰켓몬
·
Java/코테
문제 이해하기전체 폰켓몬 중에서 N/2 마리만 선택할 수 있다.이때 중요한 점은 가능한 한 서로 다른 종류의 폰켓몬을 선택하는 것이다.먼저 폰켓몬 번호 배열에서 중복을 제거해 서로 다른 폰켓몬의 종류 수를 구한다.1. 만약 중복 제거 후의 종류 수가 N/2보다 작다면, 선택 가능한 모든 종류를 가져갈 수 있으므로 그 값이 정답이다.2. 반대로 중복 제거 후의 종류 수가 N/2보다 크거나 같다면, 최대 N/2마리까지만 선택할 수 있으므로 N/2가 정답이다. 3. 결국 정답은 중복 제거된 폰켓몬 종류 수와 N/2 중 더 작은 값이다.문제 적용하기import java.util.*;class Solution { public int solution(int[] nums) { int max = nu..
실시간 채팅 서버 개발 - 03 (방 접속하기)
·
NestJS/개발
이전 프로젝트 정리이전 포스트에서는 채팅 서버에서 방을 어떻게 생성하고, Redis를 이용해 방의 상태와 생명주기를 관리하는 구조를 정리했다. 방은 단순히 생성되고 사라지는 데이터가 아니라, WAIT → PLAYING → END 로 이어지는 명확한 상태를 가지며, 각 상태에 따라 TTL을 다르게 적용해 안전하게 관리해야 한다고 생각을 가지며 마무리 하였다. 이를 통해 유령방은 자동으로 정리하면서도, 게임이 진행 중인 방이 TTL 만료로 삭제되는 문제는 방지할 수 있었다. 이제 다음으로 해결해야 할 문제는 "방에 어떻게 입장할 것인가"이다. 방 접속은 단순히 인원 수를 증가시키는 작업처럼 보이지만, 실제로는 다음과 같은 요구사항을 동시에 만족해야 한다.최대 인원 수 초과 방지동시 접속 상황에서도 정확한 인..
실시간 채팅 서버 개발 - 02 (방 생성하기)
·
NestJS/개발
이전 프로젝트 정리앞선 포스트에서는 NestJS 기반 채팅 서버에서 Redis를 도입하고, 기본적인 Redis 연결과 서비스 구조를 구성하는 과정까지 정리했다. 하지만 Redis를 붙였다고 해서 곧바로 소켓 채팅이 완성되는 것은 아니다. 실제 채팅 시스템에서는 소켓 연결 이전에 반드시 HTTP 레벨에서 관리해야 할 상태들이 존재한다. 대표적으로 방 생성, 방 입장 가능 여부 판단, 현재 인원 수 관리와 같은 로직이다. 이러한 작업을 소켓 이벤트 내부에서 처리하게 되면, 연결 시점마다 불필요한 복잡도가 증가하고 예외 처리 또한 까다로워진다. 그래서 이번 포스트에서는 Redis를 활용해 채팅방의 상태를 HTTP API로 먼저 관리하고, 검증이 끝난 이후에만 WebSocket join 이 이루어지도록 전체 흐..
실시간 채팅 서버 개발 - 01 (Redis 및 NestJS 셋팅)
·
NestJS/개발
채팅서버가 필요한 이유이번에 라이어게임을 토이프로젝트로 만들어보면서, 생각보다 가장 먼저 필요해진 기능은 게임 로직이 아니라 채팅 서버였다. 플레이어들이 같은 방에 모이고, 서로 의견을 말하고, 실시간으로 반응을 주고받는 구조상 채팅은 필수다. 처음에는 "간단한 토이프로젝트니까 웹소켓 하나 열어서 메시지만 주고받으면 되지 않을까"라고 생각했다. 하지만 실제로 구현을 시작해보니, 익명 사용자 식별, 방 관리, 메시지 흐름 등 고민해야 할 요소들이 하나둘씩 생겨났다. 이 포스트에서는 라이어게임을 만들면서 필요에 의해 구현하게 된 NestJS 기반 채팅 서버에 대해 정리를 하려고 한다.npm install npm i @nestjs/websockets @nestjs/platform-socket.io socket..
DB조회 방식에 관하여 - 오프셋(offset)방식, 커서(cursor)방식
·
Backend Design
조회 방식에 관한 생각관계형 데이터베이스에 데이터를 저장하고, 이를 "조회" 해야 하는 상황은 대부분의 백엔드 서비스에서 필연적으로 발생한다. 데이터의 양이 많지 않다면 문제는 단순하다. SELECT * FROM table 과 같은 쿼리로 데이터를 한 번에 조회하더라도 성능이나 응답 시간에 큰 영향을 주지 않는다. 데이터가 조금 더 늘어나면 보통 페이지네이션(pagination) 을 도입한다. 데이터를 일정 단위로 나누어 가져오는 방식은 초기 단계의 서비스에서는 충분히 합리적인 선택이다. 하지만 서비스가 성장하면서 데이터의 규모가 수만, 수십만, 수백만 건으로 증가하면 기존의 방식은 점점 한계를 드러낸다. 조회 속도는 느려지고, 불필요한 리소스 소모가 발생하며, 결과적으로 사용자 경험에도 영향을 미치게 ..
Redis/BullMQ 이용하여 연산 작업 따로하기
·
NestJS/개발
연산을 따로 하려고 하는 이유이번 작업을 하고 있는 토이 프로젝트의 전체적인 동작은 다음과 같다.클라이언트가 이미지를 업로드하면NestJS 백엔드 서버에서 이미지 원본과 WebP 변환 파일을 저장하고변환된 이미지의 경로를 PostgreSQL 데이터베이스에 기록한다.현재 구조에서는 파일을 하나만 올리거나 사용자가 많지 않을 경우에는 큰 문제가 발생하지 않는다. 그러나 동시에 여러 사용자가 이미지를 업로드하고 변환 작업이 이루어지면, 빨간색 네모 박스 부분을 잘 생각해야 하는데, CPU 연산이 많은 WebP 변환 과정에서 서버에 부하가 걸릴 가능성이 있다. 이 경우, NestJS 백엔드가 모든 변환 작업을 동기적으로 처리하게 되면 다음과 같은 문제가 발생할 수 있다.응답 지연: 변환이 완료될 때까지 API ..
JWT - Passport 사용하기
·
NestJS/개발
PassportPassport는 Node.js 생태계에서 가장 널리 사용되는 인증(Authentication) 라이브러리 중 하나로, 이미 수많은 실무 애플리케이션에서 검증된 안정성과 확장성을 가지고 있다. NestJS에서는 @nestjs/passport 모듈을 통해 Passport를 프레임워크에 자연스럽게 통합할 수 있으며, 이를 통해 인증 로직을 Nest의 Guard, Strategy, Provider 구조에 맞게 표준화할 수 있다. Passport의 가장 큰 장점은 다양한 인증 방식을 전략(Strategy)이라는 개념으로 분리해 제공한다는 점이다. JWT, Local, OAuth 등 여러 인증 메커니즘을 동일한 패턴으로 처리할 수 있으며, @nestjs/passport는 이러한 Passport의 동..
JWT - 역할 기반 관리하기
·
NestJS/개발
역할 기반 관리란?이전까지는 JWT 토큰만 있으면 누구나 특정 API에 접근할 수 있었다. 하지만 실제 서비스에서 가장 중요한 부분은 사용자의 역할(Role)에 따라 접근 가능한 영역이 다르다는 점이다. 예를 들어 /member/post는 일반 사용자와 관리자가 글을 작성할 수 있는 영역이지만, /admin/post는 관리자만 접근할 수 있는 영역이다. 만약 일반 사용자가 관리자 영역에 접근할 수 있다면 보안상 큰 문제가 발생한다. 이러한 역할 기반 접근 제어를 위해서는 Guard에서 JWT 인증뿐만 아니라 역할 체크까지 함께 수행해야 한다. 즉, 토큰의 유효성을 확인하고, payload에 포함된 역할 정보를 기반으로 요청자가 해당 API를 수행할 권한이 있는지 판단하는 것이 중요하다. 오늘 이부분에 관..