분류 전체보기
![[SnowTaxi] WebSocket + STOMP로 실시간 채팅 구현](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdna%2FbXJKQQ%2FbtsMkx4G38I%2FAAAAAAAAAAAAAAAAAAAAALJnCSxBApEH3KJPvPyFa4pagcdQ31vv2gRUv2lADsfe%2Fimg.png%3Fcredential%3DyqXZFxpELC7KVnFOS48ylbz2pIh7yKj8%26expires%3D1753973999%26allow_ip%3D%26allow_referer%3D%26signature%3Du%252BD9iX43rM%252Bxj2WmuEa7U%252BGKqtQ%253D)
[SnowTaxi] WebSocket + STOMP로 실시간 채팅 구현
HTTP vs WebSocket?HTTP는 클라이언트가 서버로 Request를 보내고, 서버가 Response를 주는 요청-응답 구조이다.반면 WebSocket은 클라이언트-서버 간의 실시간 양방향 통신이 가능한 통신 프로토콜이다.즉, 클라이언트의 Request 없이도 서버가 클라이언트로 정보를 실시간으로 보내줄 수 있다.서버는 클라이언트와의 연결 정보를 알아야만 Response(또는 메시지)를 보낼 수 있다. 웹소켓에서는 클라이언트와 서버가 최초 한 번만 연결을 맺으면, 서버가 그 클라이언트에 대한 연결 정보를 메모리 상에 유지한다. 그래서 매번 클라이언트의 Request 없이도, 그 연결(세션)을 이용해 메시지를 역방향으로 보낼 수 있는 것이다.HTTP와 WebSocket 모두 OSI 7계층에 위치하..
![[SnowTaxi] 이메일 인증 로직과 비동기 처리](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdna%2Fbrm4J3%2FbtsMlpkzCNg%2FAAAAAAAAAAAAAAAAAAAAAO2CDLaAOpER4PkbSYAJ_0ns5id3hnu9COzkpvrOU666%2Fimg.png%3Fcredential%3DyqXZFxpELC7KVnFOS48ylbz2pIh7yKj8%26expires%3D1753973999%26allow_ip%3D%26allow_referer%3D%26signature%3DbTeNED8YKjOohY2BGzqwJoPDV%252F4%253D)
[SnowTaxi] 이메일 인증 로직과 비동기 처리
학교 프로젝트에서 학우 전용 인증/인가 시스템을 개발하던 중이었습니다. 회원가입 플로우를 구현하고 테스트를 진행하는데, 한 가지 큰 문제점을 발견했습니다."이메일 인증 버튼 누르고 5초나 기다려야 하네?"이메일 전송에 5초나 걸리는 동안 사용자는 아무것도 하지 못한 채 기다려야 했습니다. 개발자인 저도 테스트하면서 답답함을 느꼈는데, 실제 사용자라면 더 큰 불편을 겪을 것이 분명했습니다. 코드를 살펴보니 원인을 찾을 수 있었습니다. 회원가입 로직이 하나의 스레드에서 순차적으로 처리되고 있었습니다.@Servicepublic class UserService { public void registerUser(UserDto userDto) { // 1. 회원 정보 저장 User us..
페이징과 세그멘테이션
페이징(Paging): 페이징은 메모리를 일정한 크기의 페이지(Page)로 나누는 기술입니다. 이 페이지들은 물리적인 메모리에 할당될 때 연속적으로 배치되지 않습니다.프로세스는 페이지 단위로 분할되며, 각 페이지는 일정한 크기를 가집니다(예: 4KB).논리적 주소 공간은 페이지 번호와 오프셋(offset)으로 구성됩니다. 페이지 번호는 페이지의 위치를 가리키고, 오프셋은 페이지 내에서의 위치를 가리킵니다.페이징은 외부 단편화(External Fragmentation) 문제를 해결합니다. 페이지들은 고정된 크기이므로, 프로세스가 메모리에 할당될 때 크기에 따라 페이지 수가 결정됩니다.내부 단편화(Internal Fragmentation) 문제는 발생할 수 있습니다. 각 페이지는 고정된 크기를 가지기 때문에..
DML, DCL, 윈도함수, 그룹함수
데이터 조작어(DML)데이터 조작어는 DB에 저장된 자료들을 SELECT, INSERT, UPDATE, DELTE하는 언어이다. SELECT: 데이터 조회SELECT [ALL|DISTINCT] column_name(s)FROM table_name[WHERE condition][GROUP BY column_name(s)][HAVING group_condition][ORDER BY column_name(s)[ASC|DESC]];ALL(default): 모든 튜플을 검색 / DISTINCT: 중복된 칼럼값이 조회되면 하나만 검색GROUP BY: 칼럼값을 기준으로 그룹으로 분류HAVING: GROUP BY에 의해 생성된 결과 중 원하는 조건에 부합하는 데이터만 확인ORDER BY: 칼럼값을 정렬, ASC/DES..
트랜잭션
트랜잭션 데이터베이스 시스템에서 하나의 논리적 기능을 정상적으로 수행하기 위한 작업의 기본 단위 인가받지 않은 사용자로부터 데이터를 보장하기 위해 DBMS가 가져야 하는 특성이다. 트랜잭션 특징으로 원자성, 일관성, 격리성(고립성), 영속성이 있다. 원자성 (Atomicity) 트랜잭션의 연산 전체가 모두 정상 실행 or 모두 취소가 되어야 하는 성질 Commit과 Rollback에 의해 원자성을 보장받는다. 일관성 (Consistency) 시스템의 고정요소는 트랜잭션 수행 전과 수행 완료 후의 상태가 같아야 하는 성질 병행 제어(concurrency control): 다수 사용자 환경에서 여러 트랜잭션을 수행할 때, 데이터베이스 일관성 유지를 위해 상호작용을 제어하는 기법 미보장 시 문제점: 갱신 손실..

Entity Manager
Entity Manager CRUD 동작 중 UPDATE는 JPA에 존재하지 않는데도 JPA는 업데이트를 수행한다. 이는 JPA가 데이터의 변경을 감지하여 자동으로 update 쿼리를 실행하기 때문이다. JPA는 EntityManger와 영속성 컨텍스트(Persistence Context)를 통해 이를 수행한다. @Entity로 만들어진 엔티티는, EntityManager의 persist 메서드를 통해 영속 상태가 될 수 있다. → em.persist(entity) 엔티티를 영속성 컨텍스트에 저장하면 id를 통해 영속 상태의 엔티티를 다룬다. → em.find(key) 영속성 컨텍스트를 쓰는 이유 1차 캐시: 데이터를 조회할 때, DB에서 바로 조회하는 것이 아니라 영속성 컨텍스트에서 먼저 조회함 영속성..

웹 애플리케이션 이해
웹 서버 HTTP 기반 동작 정적 리소스 제공, 기타 기능 정적 HTML, CSS, JS, 이미지, 영상 ex) NGINX, APACHE 웹 애플리케이션 서버 (WAS) HTTP 기반 동작 웹서버 기능 포함 프로그램 코드를 실행해서 애플리케이션 로직 수행 동적 HTML, HTTP API(JSON) 서블릿, JSP, 스프링 MVC ex) 톰캣 웹 시스템 구성 WAS는 정적 리소스, 애플리케이션 로직 모두 제공 가능하기 때문에 WAS, DB만으로 시스템 구성이 가능하다. 그러나 WAS가 너무 많은 역할을 담당하면 서버 과부하가 우려되고, 가장 비싼 애플리케이션 로직이 정적 리소스의 문제 때문에 수행이 어려울 수 있다. 또한, WAS 장애시 오류 화면(정적 파일)도 노출이 불가능할 것이다. 정적 리소스는 웹서..

빈 생명주기 콜백 / 빈 스코프 / 웹 스코프
커넥션 풀 (Connection Pool) 애플리케이션에 요청이 들어올 때마다 데이터베이스 연결을 수립하고, 해제하는 일은 굉장히 비효율적이다. 이 문제를 해결하기 위해 미리 여러개의 데이터베이스 커넥션을 생성해놓고, 필요할 때마다 꺼내쓰는 것이 커넥션 풀이다. IoC 컨테이너 Inversion of Control의 약자로, 컨테이너가 대신 객체의 생성부터 소멸까지의 인스턴스 생명주기의 관리를 해주는 것을 말한다. 객체 관리 주체가 프레임워크가 되기 때문에 개발자는 비즈니스 로직에 집중할 수 있다. 스프링 컨테이너가 관리하는 객체를 Bean이라고 하고, 이 빈들을 관리한다는 의미로 컨테이너를 BeanFactory라고 부른다. Bean LifeCycle 빈의 생명주기란 해당 객체가 언제,어떻게 생성되고..

컴포넌트 스캔과 의존관계 자동 주입
지금까지는 자바코드의 @Bean을 통해서 구성 정보에 직접 등록할 스프링 빈을 나열했다. 이렇게 등록해야 할 스프링 빈이 수백개가 되면 일일이 등록하기도 귀찮아지고, 구성 정보도 커지게 된다. 그래서 스프링은 구성 정보가 없어도 자동으로 스프링 빈을 등록하는 컴포넌트 스캔 기능을 제공한다. 또한, 의존관계도 자동으로 주입하는 @Autowired 기능도 제공한다. @Configuration @ComponentScan(excludeFilters = @Filter(type = FilterType.ANNOTATION, classes = Configuration.class)) public class AutoAppConfig { } 이제 @Bean 대상이었던 클래스들이 컴포넌트 스캔의 대상이 되도록 @Compone..

힙 / 이진 탐색 트리
힙 최소/최대값을 빠르게 찾기 위해 고안된 완전 이진 트리 형태의 자료구조 완전 이진 트리: 노드를 삽입할 때 최하단 왼쪽 노드부터 차례로 삽입하는 트리 힙의 구조: Max Heap / Min Heap Max Heap: 최대값이 루트노드이고, 각 부모노드는 자식노드보다 크거나 같은 값을 가짐 Min Heap: 최소값이 루트노드이고, 각 부모노드는 자식노드보다 작거나 같은 값을 가짐 우선순위 큐의 구현을 위해 사용된다. 큐는 선입선출 방식이지만, 우선순위 큐는 들어간 순서와 상관없이 높은 우선순위를 가진 원소가 가장 먼저 나오는 방식이다. 작은 숫자부터 나오는 큐를 Min Heap, 큰 숫자부터 나오는 큐를 Max Heap이라고 한다. 이진 탐색 트리와는 달리 중복된 값이 허용되고, 자식노드의 좌우는 크기..