· MySQL
문제 상황서버가 사용자의 위치 정보를 지속적으로 추적하고 관리해야 하는 요구사항이 주어졌다. 그리고 고려해야할 조건은 아래와 같다. 1. 위치 정보는 매우 자주 바뀐다. 서비스 특성상 5~30초 주기로 위치 갱신 발생2. users 테이블은 비교적 정적이다 닉네임, 프로필 사진, 이메일 등은 변경이 거의 없음 3. 서버에서 위치 정보를 관리해야하는 서비스다. ERD를 설계하는데 문득 "사용자의 위도/경도 위치 정보를 정적인 users 테이블에 넣는 게 맞을까?" 생각이 들었다. 어차피 사용자 정보인데 한 테이블에 있는 게 편하지 않나? 하지만 조금만 고민해보면, 이 결정은 단순한 편의성 이상의 영향을 끼친다. 고려 사항 : 구조적 병목놓치기 쉬운 RDB의 저장 방식이 있다. 바로 "디스크는 row..
· MySQL
csv을 이용해 100만 개의 데이터를 DB에 넣은 상태이다. explain 명령을 통해 각 쿼리의 실행 계획이 어떻게 변화하는지를 살펴보자.  Explain과 AnalyzeExplain우선, mysql에서 explain 키워드를 붙이면 아래와 같이 실행 계획을 조회할 수 있다. explain은 쿼리를 직접 실행하지는 않는다.   여기서 나오는 각 필드의 개념을 표로 정리해보았다.항목내용id실행계획의 순서. 이 순서대로 select 문이 실행select typeSIMPLE : 단순 select문PRIMARY : 첫번째 쿼리DERIVED : select문으로 추출된 테이블 ( from 절에서의 서브쿼리 또는 inline view)SUBQUERY : sub query 중 첫번째 select문UNION : U..
· MySQL
MySQL은 내부적으로 OS의 파일 I/O를 사용한다. 그럼 어느 정도는 직접 구현해볼 수 있지 않을까?  우선 MySQL의 아키텍처를 참고해보았다.MySQL은 SQL 구문이 들어오면 Parser -> 전처리기 -> 옵티마이저 -> 엔진 실행기 -> 스토리지 엔진 순서로 동작한다.  설계여기서 옵티마이저와 엔진 실행기는 제거하고 설계했다. 옵티마이저의 실행 계획 알고리즘 CBO를 구현할 역량이 없다고 생각했다. 또 내부적으로 실행 계획에 따라 풀스캔이나 인덱스로 탐색하는 것을 구현해야하는데, 마찬가지로 구현할 역량이 없다고 판단했다.  스토리지 엔진은 InnoDB를 참고했다.  그런 이유로 아키텍처는 아래와 같이 구성했다.   이번 구현에서 초점을 둔 것은, Disk I/O를 최대한 줄이는 것을 목표로 ..
· Redis
문제 상황 실시간으로 베팅이 이루어지는 서비스이다. "만약 많은 사용자가 동시에 베팅을 진행할 경우, 동시성 문제가 일어나 데이터가 부정확해지는 것은 아닐까?" 고민을 하게 되었다. 구체적인 상황은 아래와 같다.1. 베팅을 하면 카운트가 올라간다. (베팅 참여자, 베팅한 금액)2. 카운트를 올리기 위해 데이터를 조회한다.3. 조회한 데이터에 증가 연산을 수행한다.4. 업데이트 된 데이터를 저장한다. 위 경우, 만약 두 명의 사용자가 데이터가 1인 시점에 접근해 각각 1씩 올려도 3이 아니라 2가 되는 동시성 문제가 발생하게 되는 것이다.   결론부터 이야기하면, 레디스와 레디스의 HINCRBY 명령어를 통해 원자성을 보장할 수 있었다. HINCRBY 명령어와 가상의 테스트 시나리오를 통해, 어떻게 동시성..
JVM과 자바의 메모리 영역에 대한 학습을 정리했다.  우선 전반적인 실행 과정을 간단히 살펴보고, 하나씩 깊게 살펴보자!  1. Java 프로그램의 전반적인 실행 과정 가장 먼저, 자바 컴파일러가 Source Code (.java) 파일을 기계어 파일인 Byte Code(.Class)로 변환한다.   그럼 변환된 기계어 파일을 JVM의 클래스 로더가 JVM 메모리 영역으로 가져온다. 클래스 로더는 말 그대로 Class 파일을 불러와서 메모리에 저장하는 역할을 수행한다. 이제 이렇게 JVM에 로딩된 바이트 코드들을 Execution Engine이 명령어 단위로 읽어서 실행한다.  위 실행 과정 중에서 JVM은 필요에 따라 가비지 컬렉션, 스레드 동기화 등으로 메모리와 자원을 관리하게 된다.  2. 왜 자..
· JavaScript
사용자가 카드를 추가하면, 실시간으로 사용자의 히스토리에 view를 업데이트해야하는 요구 조건이 있었다.목록 1에 카드를 추가하면, 히스토리 판넬에도 동시에 기록이 추가되어야 한다.  이를 위해 옵저버 패턴을 적용했다.  카드라는 상태를 관리할 TaskState 클래스를 정의해준다.import {fetchTasksAPI, addTaskAPI, editTaskAPI, deleteTaskAPI} from '../api/taskAPI.js';export class TaskState { constructor() { this.tasks = []; this._observers = []; } subscribe(observer) { this._observers.push(observer); } ..
· 운영체제
강의를 들으면서 정리한 강의 노트입니다. 강의 내용 외에도 이해가 잘 안가는 부분들을 쉽게 정리하려 노력했습니다. 반효경 교수님 운영체제 강의를 들으시는 분들이 이 글을 통해 도움이 되었으면 좋겠습니다!   (혹시 포스팅 중에 잘못된 내용이 있으면 댓글로 지적 부탁드립니다..!)강의 노트 목록1. 운영체제 서론 (Introduction to Operating Systems) 2. 운영체제 구조 : 컴퓨터 시스템의 구성(System Structure & Program Execution 1) 3. 운영체제 구조 : 동기식 입출력과 비동기식 입출력, 저장 장치 계층 구조, 프로그램의 실행(System Structure & Program Execution 2) 4. 프로세스 : 프로세스의 개념, 프로세스의 상태..
이번 포스팅에서는 JCF에서 LinkedList와 ArrayDeque가 어떻게 구현되어 있는지 살펴볼 것이다. 1.  ArrayDeque개념  Deque는 Double-Ended Queue의 줄임말로 큐의 양쪽에서 데이터를 삽입과 삭제를 할 수 있는 자료구조를 의미한다. 그리고 이 Deque 인터페이스를 구현하는 클래스가 ArrayDeque이다. JCF에서 어떻게 구현되어 있나?  elements와 head, tailpublic class ArrayDeque extends AbstractCollection implements Deque, Cloneable, Serializable{ transient Object[] elements; // non-priv..
· Redis
개발 중 예상치 못한 Redis 메모리 초과 문제로 서버가 다운되는 경험을 했다.  테스트용으로 임시 서버를 두고 작업을 해두었던 터라, 잠깐의 시간 동안 Redis Memory가 가득 찰 일은 없겠다는 안일한 생각을 했다. 그래서 Redis의 maxmemory와 maxmemory-policy 설정을 따로 해두지 않았었다. 그러다보니 무제한으로 데이터를 저장할 수 있는 상태가 되었다. 그리고 서버가 꽝 터졌다. 이번 기회를 통해 Redis 설정을 최적화하는 과정을 공유해보고자 한다.  문제 상황개발 중이던 프로젝트에서, Redis를 사용해 방에 참가한 사용자 닉네임을 list 자료구조에 저장했다.  테스트 중, 클라이언트에서 소켓 이벤트를 잘못 처리해 엄청난 양의 데이터가 Redis로 흘러들어왔고, 순식..
· Network
컴퓨터와 네트워크 강의를 들으며 정리한 강의 노트 모음입니다.  강의 노트라고는 했지만 강의의 커리큘럼을 참고한 것이 크고, 강의 외로 참고한 것들도 꽤 있어서 강의 흐름과 결이 다른 부분이 있을 수 있습니다. 하지만 잘 이해가 안 가는 부분들을 추가 포스팅과 그림으로 최대한 쉽게 정리하려고 노력해서 네트워크 공부에 도움이 되지 않을까 생각합니다.  컴퓨터와 네트워크 강의를 들으시는 분들이나 네트워크 개념에 대한 학습이 필요한 분들께 도움이 되었으면 좋겠습니다. 혹시 잘못된 부분이 있으면 댓글로 지적 부탁드립니다..! 1. OSI 7계층을 쉽게 이해해보자 (1) 2. OSI 7계층, TCP/IP Updated 을 쉽게 이해해보자 (2) 3. 전송 계층 : 다중화(Multiplexing)와 역다중화(Dem..
Node.js의 이벤트 루프는 libuv 라이브러리에 의해 관리된다.  libuv 를 학습하면서, 솔직히 정말 이해가 되지 않았다. 구체적으로 이벤트 루프가 무슨 동작을 하는 건지, microtask queue는 무엇인지, 이벤트 루프가 어떻게 논블로킹 I/O를 처리할 수 있는지 등 추상적으로만 이해할 뿐 어느 누구에게 제대로 설명하기가 쉽지 않았다.   그래서 node.js 공식 문서부터 여러 포스팅, git에 올라와있는 node.js, libuv 라이브러리 코드를 며칠간 파헤쳐보았다.  libuv란? Node.js의 이벤트 루프는 libuv라는 비동기 I/O 라이브러리에 의해 구현된다.   libuv는 C++로 작성된 라이브러리로, Node.js가 단일 스레드로 동작하면서도 비동기적으로 I/O 작업을..
정렬 알고리즘을 배우며 병합 정렬, 퀵 정렬 등 다양한 종류의 알고리즘에 대해 배웠다. 그렇다면 자바에서 자주 사용하는 Arrays.sort() 는 어떤 알고리즘으로 구현되어있을까?  구글링과 자바 내부코드를 보면, Arrays.sort는 듀얼 피봇 퀵소트를 사용한다라고 나와있다. Arrays.sort 메서드 내부를 들여다보면서, 듀얼 피봇 퀵소트란 무엇인지 그리고 범위에 따라 어떤 정렬 방식을 적용하는지를 알 수 있었는데, 그 부분에 대해 공유해보려 한다.   Arrays.sort() 내부 들여다보기int[] arr = {1, 3, 4, 2, 1 ,7};Arrays.sort(arr)---result: {1, 1, 2, 3, 4 ,7} 보통 자바에서 배열을 정렬할 때,  java.util.Arrays 클..
https://dcloud.tistory.com/98 [Java 파헤쳐보기] JVM을 파헤쳐보자JVM과 자바의 메모리 영역에 대한 학습을 정리했다.  우선 전반적인 실행 과정을 간단히 살펴보고, 하나씩 깊게 살펴보자!  1. Java 프로그램의 전반적인 실행 과정 가장 먼저, 자바 컴파일러가dcloud.tistory.com지난 포스팅에서 JVM에 대해 살펴보았다. JVM의 메모리 영역에는 메서드, 스택, 힙 영역 등이 있었다. 그리고 가비지 컬렉터가 그 중 힙 영역을 청소하고, Heap 영역에 있는 객체를 가리키는 레퍼런스 변수는 Stack 영역에 저장된다고도 언급했다.   이게 정확히 무슨 말일까? 이번 포스팅에서 JVM의 가비지 컬렉터(Garbage Collector)을 살펴보며 자세히 알아볼 것이다..
· Spring
https://dcloud.tistory.com/178  지난 포스팅에서 동적 웹 페이지를 위해 서블릿이 도입된 배경과 서블릿의 장점을 살펴보았다. 그리고 서블릿을 재정의해서 서블릿의 요청을 처리하는 것도 알아보았다.  이번에는 이어서, 서블릿의 핵심 개념인 서블릿 컨테이너를 다루어보고 스프링에서 어떤 점을 개선했고 현재의 스프링 형태가 되었는지 살펴보자.   서블릿은 어떻게 관리되고, 서블릿은 어떻게 호출될까? 1. 서블릿 컨테이너서블릿을 관리하기 위한 서블릿 컨테이너라는 것이 있다. 서블릿 컨테이너란 단어 그대로 서블릿을 담는 컨테이너이다.   우리가 자주 들어본 톰캣(Tomcat)이 대표적인 서블릿 컨테이너이자 WAS이다. 예를 들어, 사용자가 브라우저에서 HTTP 요청을 보내면 톰캣이 해당 요청을..
· MySQL
MySQL에서 B+ 트리 자료구조를 인덱스로 활용하는 이유가 무엇일까? B+ 트리를 DB 인덱스로 사용하는 이유는 크게 두 가지이다. 시간 복잡도 B+ 트리는 어떤 경우에도 O(log N)의 시간 복잡도를 가지기 때문에 빠른 검색이 가능하다. 이는 데이터가 크거나 데이터베이스가 복잡해져도 효율적인 조회 성능을 보장하는 중요한 장점이다.  예를 들어 이진 트리의 경우 최대 O(N)의 시간 복잡도를 가지게 된다.   하지만 B+ 트리는 균형 트리의 일종으로, 왼쪽과 오른쪽 노드의 밸런스를 항상 유지한다.  디스크 I/O의 효율성그럼 이런 의문이 들 수 있다.  AVL 트리, 이진 탐색 트리, 레드-블랙 트리 등의 자료구조도 균형 잡힌 트리인데, 왜 B+ 트리일까? 이 의문점을 해소하려면 우선 한 가지 개념을..
· Java GUI
1. Snake game 이란?Snake game은 뱀을 조종하여 먹이를 먹어 길이를 늘리는 게임입니다. 게임의 규칙은 간단합니다.  1. 먹이를 먹으면 뱀의 길이가 증가한다.  2. 뱀의 머리가 뱀의 몸이나 벽에 부딪히면 종료된다.  이를 Java GUI를 통해 구현해보았습니다. 2. Java GUI 코드코드는 아래와 같이 세 가지 파일로 구성됩니다.   1. Main.java  2. GamePanel.java    3. GameFrame.java 1. Main.javapublic class SnakeMain { public static void main(String[] args) { new GameFrame(); }}2. GameFrame.javaimport javax.swin..
동구름이
동구름