-
Notifications
You must be signed in to change notification settings - Fork 0
Database ‐ Database Performance and MySQL Architecture
woojin.jang edited this page Aug 3, 2026
·
6 revisions
| 계층 | 역할 |
|---|---|
| 커넥션 핸들러 | 클라이언트 접속 관리 |
| 파서 | SQL 문법 검사와 구조 분석 |
| 옵티마이저 | 최적의 실행 계획 수립 |
| 실행 엔진 | 실행 계획에 따라 스토리지 엔진 호출 |
| 스토리지 엔진 | 실제 데이터 저장과 조회 |
- 커넥션 핸들러는 클라이언트의 접속을 관리하는 계층이다.
- 클라이언트가 MySQL 서버에 접속하면 다음과 같은 과정이 일어난다.
1. TCP/IP 등으로 연결 요청을 받는다.
2. 사용자명, 비밀번호, 호스트를 확인한다.
3. 이 사용자가 어떤 데이터베이스에 접근할 수 있는지 권한을 확인한다.
4. 전용 쓰레드(Thread)를 할당한다.
- MySQL은 기본적으로 쓰레드 기반(thread-per-connection) 모델을 사용한다. 클라이언트 하나가 접속하면 전용 쓰레드 하나를 배정받는다. 이 쓰레드가 해당 클라이언트의 모든 쿼리를 처리한다.
❗웹 애플리케이션 서버(WAS)가 커넥션 풀(Connection Pool)을 통해 MySQL에 접속한다. 커넥션 풀 크기를
max_connections보다 크게 설정하면Too many connections에러가 발생할 수 있다.
- 실무에서는 웹 애플리케이션 서버가 1대가 아니다. 트래픽이 늘어나면 WAS를 여러 대로 수평 확장하는 경우가 일반적이고 각 WAS마다 독립적인 커넥션 풀을 가진다. 따라서 MySQL이 실제로 받는 전체 커넥션 개수는
WAS 대수 x WAS당 풀 크기로 계산해야 한다.- 예를 들어, WAS 10대가 각각 커넥션 풀 크기를 50으로 설정했다면 MySQL은 최대 500개의 커넥션을 받게 된다.
- 따라서,
max_connections는 다음과 같이 설정하는 것이 안전하다.- 산식 :
(WAS 대수 x WAS당 풀 크기) + 배치/관리자/모니터링용 여유분 + 관리자 예비 슬롯- 반대로 커넥션을 무작정 늘리는 것이 정답이 아니다. 커넥션 하나당 CPU, 메모리, 디스크 I/O, 네트워크, InnoDB 내부 락 등 여러 자원을 함께 소모하기 때문에 불필요하게 크게 잡으면 서버 전체 성능이 오히려 저하된다. 적정 커넥션 수 = 실제 동시 처리량 관점에서 설계해야 한다.
- 정확한 커넥션 수는 성능 테스트를 통해 결정해야 한다. 서비스의 실제 트래픽 패턴을 분석해서 커넥션 수를 조금씩 늘려가며, 응답 시간과 CPU, 메모리, 락 대기 지표가 악화되기 시작하는 지점을 찾는다. 그 직전 값이 해당 환경의 최대 적정 커넥션 개수이다.
- 파서는 SQL 문자열을 분석하는 계층이다.
- 구문 분석(Parsing) : SQL 문자열을 토큰으로 분해하고, 문법 규칙에 맞는지 검증한다.
- 파스 트리(Parse Tree) : 문법이 올바르면 내부 트리 구조로 변환해 옵티마이저에 전달한다.
- 옵티마이저(Optimizer)는 쿼리를 실행하는 최적의 경로를 결정하는 계층이다.
- MySQL의 옵티마이저는 비용 기반 옵티마이저이다. 이 경로로 가면 디스크를 몇 번 읽어야 하고, 비용이 얼마나 드는가를 계산해 가장 비용이 낮은 실행 계획을 선택한다.
- 어떤 인덱스를 사용할 것인가?
- 테이블을 어떤 순서로 접근할 것인가?
- 어떤 조인 알고리즘을 사용할 것인가?
❗옵티마이저는 항상 최선의 판단을 내리는 것이 아니다. 통계 정보가 부정확하면 잘못된 경로를 선택할 수 있다.
- 실행 엔진은 옵티마이저가 수립한 실행 계획을 실제로 수행하는 계층이다.
- 실행 엔진은 스토리지 엔진과 핸들러 API라는 표준화된 인터페이스를 통해 통신한다. 핸들러 API 덕분에 어떤 스토리지 엔진이든 동일한 방식으로 호출할 수 있다.
- 실행 엔진이 하는 일을 단순화시키면 다음과 같다.
1. 스토리지 엔진에서 행을 하나씩 가져온다.(반복)
2. 가져온 각 행에 서버 레벨 필터링을 적용한다.
3. 결과를 모아 필요한 정렬, 그룹핑을 수행한다.
4. 최종 결과를 클라이언트에 반환한다.
- 스토리지 엔진은 실제 데이터를 저장하고 읽어오는 계층이다.
- MySQL의 스토리지 엔진은 교체가 가능하다. MySQL은 Pluggable Storage Engine Architecture를 사용한다. 상위의 SQL 계층은 그대로 두고 하위의 스토리지 엔진만 바꿀 수 있다.
- InnoDB가 기본으로 선택된 이유는 다음과 같다.
- 트랜잭션 지원 : ACID를 보장한다.
- 행 수준 잠금 : 동시성이 좋다.
- 외래 키 지원 : 참조 무결성을 보장한다.
- 크래시 복구 : 비정상 종료 후에도 데이터를 복구할 수 있다.
- 스토리지 엔진은 실제 데이터를 보관하는 곳으로 생각하면 된다. 따라서 최종적으로 디스크에 데이터를 보관한다.
- 메모리(RAM) : 매우 빠르다. 나노초(ns) 단위로 접근한다.
- 디스크(SSD/HDD) : 메모리보다 수백 ~ 수만 배 느리다. 마이크로초(us) ~ 밀리초(ms) 단위로 접근한다.
- 디스크의 성능 문제를 보완하기 위해 InnoDB 아키텍처는 크게 다음과 같은 두 구조로 나뉜다.
- 메모리 구조
- 디스크 구조
- 모든 데이터를 메모리에 올리면 빠르겠지만, 메모리는 비싸고 용량이 제한적이다. 그래서 InnoDB는 자주 사용하는 데이터를 메모리에 캐싱하고, 전체 데이터를 디스크에 안전하게 보관한다.
- 버퍼 풀은 InnoDB에서 가장 중요한 메모리 영역이다.
- 버퍼 풀은 테이블 데이터와 인덱스 데이터를 페이지 단위로 캐싱한다. 페이지는 InnoDB가 데이터를 읽고 쓰는 최소 단위(기본 16KB)이다.
- 버퍼 풀의 핵심 원리는 단순하다.
1. 쿼리가 특정 데이터를 요청한다.
2. 해당 데이터가 버퍼 풀에 있으면 메모리에서 바로 읽는다.
3. 해당 데이터가 버퍼 풀에 없으면 디스크에서 읽어와서 버퍼 풀에 올린 다음에 읽는다.
- 버퍼 풀의 히트율이 높을수록 디스크 I/O가 줄어들고 성능이 좋아진다. 데이터베이스 전용 서버의 경우 물리 메모리의 최대 80%까지 버퍼 풀로 할당하는 것을 권장한다.
❗실제로 운영 서버에서
innodb_buffer_pool_size를 128MB 기본값으로 두는 일은 거의 없다. 전용 DB 서버라면 물리 메모리의 60 ~ 80%를 할당한다. 예를 들어 16GB 메모리 서버라면 10 ~ 12GB를 버퍼 풀로 설정하는 것을 권장한다. 나머지는 OS를 포함한 MySQL의 커넥션별 메모리 영역에서 나누어 쓰기 위해 남겨둔다. DB 세부 설정 방법은 추가로 공부해보면 좋다.
-
디스크 영역 : 리두 로그(Redo Log)
- 리두 로그는 크래시 복구용 디스크 구조이다. InnoDB는 데이터 파일을 변경하기 전에 리두 로그에 먼저 기록하는 WAL(Write-Ahead Loggin) 원칙을 따른다. 서버가 갑자기 죽어도 재시작 시 리두 로그를 재생해 커밋된 트랜잭션을 복구한다.
-
메모리 영역 : 로그 버퍼(Log Buffer)
- 로그 버퍼는 리두 로그를 디스크에 쓰기 전 임시로 모아두는 메모리 영역이다. 변경이 일어날 때마다 매번 디스크에 쓰면 너무 느리므로, 메모리에 쌓아두었다가 커밋 시점(또는 주기적으로) 한꺼번에 디스크에 내려쓴다.
-
디스크 영역 : 언두 로그(Undo Log)
- 언두 로그는 트랜잭션 롤백과 MVCC(Multi-Version Concurrency Control)에 사용되는 이전 버전 데이터이다.
-
디스크 영역 : 테이블스페이스(TableSpace)
- 테이블스페이스는 실제 테이블 데이터와 인덱스가 저장되는 파일이다. InnoDB는 기본적으로 테이블 하나당
.ibd파일 하나를 가진다.
- 테이블스페이스는 실제 테이블 데이터와 인덱스가 저장되는 파일이다. InnoDB는 기본적으로 테이블 하나당
- InnoDB의 데이터 저장은 페이지 ⭢ 익스텐트 ⭢ 세그먼트 ⭢ 테이블스페이스 순서의 계층 구조를 가진다.
- 페이지(Page)는 InnoDB의 최소 I/O 단위이다.
- MySQL 8.4의 페이지 기본 크기는 16KB이다.
- 모든 I/O는 페이지 단위이다. 하나의 행만 읽더라도 그 행이 들어있는 16KB 페이지 전체를 디스크에서 읽어야 한다는 뜻이다. 특정 바이트 하나만 콕 집어서 읽는 것이 불가능하다. 최소 읽기 단위가 있고 InnoDB는 이를 16KB 페이지로 관리한다. 한 번 읽어온 페이지 안에는 여러 행이 들어있으므로, 같은 페이지의 다른 행을 읽을 때는 디스크를 다시 읽을 필요가 없다.
- 인덱스의 B+Tree에서 노드 하나 = 페이지 하나를 말한다.
- 순차 I/O가 빠른 이유 : 연속된 페이지를 한꺼번에 읽을 수 있기 때문이다.
- 랜덤 I/O가 느린 이유 : 서로 다른 위치의 페이지를 하나씩 읽어야 하기 때문이다.
- 버퍼 풀이 페이지 단위로 캐싱하는 이유 : I/O 단위 자체가 페이지이기 때문이다.
- 작으면(4KB) : 같은 데이터를 담는 데 더 많은 페이지가 필요하다. B+Tree의 높이가 깊어져 검색 시 읽어야 할 페이지가 늘고, 큰 행은 한 페이지에 못 들어가 오버플로우가 잦아진다.
- 크면(64KB) : 행 한 줄만 필요해도 64KB 전체를 읽고 메모리에 올려야 해서 버퍼 풀이 낭비된다. 페이지 하나에 더 많은 행이 몰려 동시성 경합도 커진다.
- 균형(16KB) : 대부분의 행이 한 페이지에 들어간다. B+Tree 노드 하나에 수백 개의 키를 담을 수 있어 수십억 건 테이블도 대개 3~4단계 깊이로 끝난다. OS/SSD 기본 블록(4KB)의 정수배라 I/O 정렬도 깔끔해진다.
- 익스텐트(Extent)는 연속된 페이지의 그룹이다.
- 페이지가 I/O의 최소 단위라면 익스텐트는 공간 할당의 단위이다.
- 테이블이 작을 때(32페이지 이하) : 페이지를 하나씩 할당한다. 작은 테이블에 1MB를 통째로 잡으면 낭비이기 때문이다.
- 테이블이 커지기 시작하면 : 익스텐트 단위(1MB)로 전환한다. 1개씩 할당하던 것을 64개 연속 페이지 묶음으로 바꾼다.
- 테이블이 충분히 크면 : 한 번에 최대 4개의 익스텐트까지 할당한다. 테이블이 빠르게 성장 중이면 할당 횟수를 줄여 오버헤드를 낮추는 것이다.
- 인덱스 하나당 2개의 세그먼트가 할당된다.
- 비리프노드 세그먼트 : B+Tree의 내부 노드(검색 경로)를 저장한다.
- 리프노드 세그먼트 : 실제 데이터(또는 데이터를 가리키는 포인터)를 저장한다.
- MySQL InnoDB의 PK 인덱스는 리프 노드에 실제 데이터를 가지고 있고 PK가 아닌 인덱스는 리프 노드에 PK값을 가진다.
- 테이블스페이스는 세그먼트를 포함하는 최상위 저장 단위이다. 실제 디스크 파일
ibd에 매핑된다. - InnoDB는 기본적으로 각각의 테이블을 각각의 파일로 관리한다.
-- 테이블별 데이터 크기와 페이지 수 계산
SELECT TABLE_NAME,
TABLE_ROWS AS estimated_rows,
ROUND(DATA_LENGTH / 1024 / 1024, 1) AS data_mb,
ROUND(DATA_LENGTH / @@innodb_page_size) AS estimated_pages,
ROUND(INDEX_LENGTH / 1024 / 1024, 1) AS index_mb,
ROW_FORMAT
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'shop'
ORDER BY DATA_LENGTH DESC;- 인덱스도 생각보다 많은 용량을 차지한다. 인덱스는 조회를 빠르게 해주지만 공짜가 아니라는 점을 명확히 알고 있어야 한다.
- 디스크 공간을 차지하고 INSERT/UPDATE/DELETE 때마다 함께 갱신되어야 한다. 인덱스를 무작정 많이 만들면 안되는 이유가 바로 여기에 있다.
- Java - Class
- Java - Java Memory
- Java ‐ Solving Concurrency Issues with Synchronized
- Java - synchronized
- Java ‐ Instance Variable & Local Variable vs final
- Java ‐ Object
- Java ‐ Immutable Object
- Java ‐ String
- Java ‐ Wrapper Class
- Java ‐ ENUM
- Java ‐ Nested Class & Inner Class & Local Class & Anonymous Class
- Java ‐ Generic
- Java ‐ ArrayList
- Java ‐ LinkedList
- Java ‐ List
- Java ‐ Set
- Java ‐ Hash
- Java ‐ HashSet
- Java ‐ Map & Stack & Queue
- Java ‐ Iterate & Sort
- Java - Process & Thread
- Java - Thread Creation & Execution
- Java - Thread Control & LifeCycle
- Java - Memory Visibility
- Java - Advanced Synchronization
- Java - Producer/Consumer Problem
- Java - Synchronization & Atomic Operation
- Java - Concurrent Collection
- Java - Thread Pool & Executor Framework
- Java - Character Encoding
- Java - I/O
- Java - File & Files
- Java - Reflection
- Java - Annotation
- Java - Lambda
- Java - Functional Interface
- Java - Lambda vs Anonymous Class
- Java - Method Reference
- Java - Stream API
- Java - Optional
- Java - Default Method
- Java - Parallel Stream
- Java - Functional Programming
- Java - JVM & GC & SOLID
- Java - Data Storage and Memory Allocation: Primitive vs. Reference
- Java ‐ Static Keyword: Efficient Resource Management at the Class Level
- Java ‐ OOP
- Java ‐ Collection Framework Selection Standard
- Java ‐ Multi Threading & Concurrent Programming
- Java ‐ Exception Handling & Advanced Java
- Java ‐ Java 8+
- Java ‐ Java Application Performance Tuning
- Java - CAS
- Java - Virtual Thread
- Java - Benchmark
- Kotlin - Variables, Types, and Operators in Kotlin
- Kotlin - Control Flow in Kotlin
- Kotlin - Object-Oriented Programming in Kotlin
- Kotlin - Functional Programming in Kotlin
- Kotlin - Key Features of Kotlin
- Kotlin - Generics in Kotlin
- Kotlin - Lazy Initialization and Delegation in Kotlin
- Kotlin - Advanced Functional Programming in Kotlin
- Kotlin - Operator Overloading and Kotlin DSL
- Kotlin - Annotations and Reflection in Kotlin
- Kotlin - Miscellaneous Topics in Kotlin
- Coroutine - Limitations of Thread-Based Work & the Emergence of Coroutines
- Coroutine - runBlocking
- Coroutine - CoroutineDispatcher
- Coroutine - Controlling Coroutines with Job
- Coroutine - Receiving Results from Coroutines
- Coroutine - Coroutine Context
- Coroutine - Structured Concurrency
- Coroutine - Exception Handling
- Coroutine - Suspended Functions
- Coroutine - Understanding Coroutines
- Coroutine - Advanced Coroutines
- Coroutine - Coroutine Testing
- Spring - OOP & Spring
- Spring - Spring Container & Spring Bean
- Spring - Singleton Container
- Spring - Dependency Injection
- Spring - Bean LifeCycle Callback
- Spring - Bean Scope
- Spring ‐ Web Server, Web Application server
- Spring ‐ Servlet
- Spring ‐ Servlet & JSP & MVC
- Spring ‐ MVC Framework
- Spring ‐ Spring MVC
- Spring - Thymeleaf
- Spring - Message & Internationalization
- Spring - Validation
- Spring - Bean Validation
- Spring - Cookie & Session
- Spring - Filter & Interceptor
- Spring - API Exception Handling
- Spring - Spring Type Converter
- Spring - File Upload
- Spring - Connection Pool & DataSource
- Spring - Transaction
- Spring ‐ Spring Exception Abstraction
- Spring - Database Access
- Spring ‐ Spring Transaction
- Spring ‐ Spring Transaction Propagation
- Spring ‐ Thread Local
- Spring ‐ Template Method Pattern & Callback Pattern
- Spring ‐ Dynamic Proxy
- Spring ‐ Spring Proxy
- Spring ‐ Bean Processor
- Spring ‐ @Aspect AOP
- Spring ‐ Spring AOP
- Spring ‐ Spring AOP Application
- Spring - MyBatis
- Spring ‐ URL Encoding
- Spring - Cache Annotation
- Spring - Retry
- Spring Security - Initialization
- Spring Security - Authentication Process
- Spring Security - Authentication Architecture
- Spring Security - Authentication Status Persistence Processing Mechanism
- Spring Security - Session Management
- Spring Security - Exception Handling
- Spring Security - Mechanisms for responding to Malicious Attacks
- Spring Security - Authorization Process
- Spring Security - Authorization Architecture
- Spring Security - Multiple Security Settings
- Spring Security - Redis Redundancy Settings
- Spring Security - Event
- Spring Security - Integration
- Spring Security - OAuth 2.0
- Spring Security - OAuth 2.0 Authorization Type
- Spring Security - Open ID Connect
- Spring Security - OAuth 2.0 Client
- Spring Security - OAuth 2.0 Client Fundamentals
- Spring Security - OAuth 2.0 oauth2Login
- Spring Security - OAuth 2.0 oauth2Client
- Spring Security - OAuth 2.0 Resource Server
- Spring Security - OAuth 2.0 Resource Server API
- Spring Security - OAuth 2.0 Verification
- [🔖Spring Security - OAuth 2.0 MAC & RSA Token Verification]
- Spring Security - OAuth 2.0 Resource Server Permission Implementation
- Spring Security - OAuth 2.0 opaque()
- Spring Security - Integrating OAuth 2.0 Client and Resource Server
- Spring Security - Authorization Server
- Spring Security - Authorization Server Main Domain Class
- Spring Security - Authorization Server Endpoint Protocol
- Spring Batch - Scheduler vs Batch
- Spring Batch - Batch Concept
- Spring Batch - Batch Domain
- Spring Batch - Job
- Spring Batch - Step
- Spring Batch - Flow
- Spring Batch - Chunk Process
- Spring Batch - ItemReader
- Spring Batch - ItemWriter
- Spring Batch - ItemProcessor
- Spring Batch - Retry & Error Handling
- Spring Batch - Multi Threads Processing
- [Spring Batch - Batch Event Listener]
- [Spring Batch - Batch Test]
- [Spring Batch - File Processing]
- [Spring Batch - Read and Write Operations in Relational Databases and NoSQL]
- [Spring Batch - FaultTolerant & ItemStream]
- [Spring Batch - Partitioning]
- Spring Batch ‐ Tasklet vs Chunk
- [Spring Batch - Class 2]
- [Spring Batch - Class 3]
- [Spring Batch - Class 4]
- [Spring Batch - Class 5]
- [Spring Batch - Class 6]
- [Spring Batch - Class 7]
- Database - Database Introduction
- Database - Search & Sort
- Database - Data Processing
- Database - Aggregation & Grouping
- Database - Inner Join
- Database - Outer Join & Etc Join
- Database - Sub Query
- Database - UNION
- Database - CASE
- Database - Index
- Database - Data Integrity
- Database - Transaction
- Database - Why Database Design Matters
- Database - Concept Modeling
- Database - Logical Data Modeling
- Database - Identifying Relationship & Non-Identifying Relationship
- Database - Normalization
- Database - Physical Data Modeling
- Database - Common Code Design
- Database - Hierarchical Structure Design
- Database - Data Change History Design
- Database - SOFT DELETE
- Database - Statistics Table Design
- Database - Inheritance Relationship Design
- Database - Entity-Attribute-Value (EAV) Model
- Database - JSON Schema Design
- Database - Database Performance and MySQL Architecture
- Database - Execution Plans 1 - Mastering EXPLAIN
- Database - Execution Plans 2 - Mastering ANALYZE
- Database - Diagnosing Full Table Scans and Composite Index Basics
- Database ‐ Index Internal Structures 1 ‐ B-Tree & B+Tree
- Database - Index Internal Structures 2 - Clustered and Secondary Indexes
- Database - Diagnosing Using filesort and Early Termination
- Database - ICP, Covering, and Skip Scans
- Database - Merge, MRR, New Features, Hints, and Operations
- 🔖Database - The Optimizer and Histograms
- Database - Join Optimization
- Database - Optimizing Sort, Pagination, and Grouping
- Database - Streaming Aggregation and Pre-aggregated Tables
- MySQL ‐ Solving Concurrency Problems using Database-Level Locking
- MySQL - Multi Column Index
- MySQL - Covering Index & RDB vs ElasticSearch Diff
- MySQL - ORDER BY
- MySQL - INSERT
- MySQL - AUTO_INCREMENT_LOCK
- MySQL - Index Dive Using In Query
- MySQL - Why don't use prefix index in default
- MySQL - MySQL LockType
- MySQL - DeadLock Case
- MySQL - NoOffset For Query Tuning
- MySQL ‐ Skip Locked for Session
- MySQL - Checking DB Metrics with SQL Queries
- MySQL - Data Modeling for Practical Service Development
- MySQL - Basic CRUD in MySQL
- MySQL ‐ MySQL Internal Architecture and Storage Engines
- MySQL - MySQL Horizontal Scaling
- MySQL ‐ Operational‐Level System Design
- MySQL - MySQL Fundamentals
- MySQL - Why You Should Use MySQL: JOIN
- MySQL - Must-Know SQL Anti-Patterns
- MySQL - Learning Data Modeling Through Practical Examples
- MySQL - Foreign Key & Strategic Patterns
- MySQL - Advanced Topics in MySQL
- Redis ‐ Redis
- Redis ‐ Redis Manual
- Redis ‐ Redis Cache Strategy
- Redis ‐ Redis Master-Slave
- Redis - Redis Cluster Mode
- Redis - Redis Cluster Example
- Redis - Redis Data Structure
- Redis - Redis Server
- Redis - Reduce DB write load using Redis
- Redis - Solving Concurrency Issues (1)
- Redis ‐ Solving Concurrency Issues (2)
- Redis - Solving Concurrency Issues (3)
- Redis - Implementing Popular Searches
- Redis - API Rate Limiting
- Redis - Geospatial
- Redis - DAU Counting Application
- Redis - Session Management Application
- Redis - Redis Transaction ACID
- Redis - Redis Data Persistence
- Redis - Redis Keys Management
- Redis - Decoupling microservices with Redis Pub/Sub
- Redis - Redis Pipelining & RTT(Round Trip Time)
- Redis - Redis Streams
- Redis - Hash Slot Rebalancing
- JPA - Java Persistence API
- JPA - Entity Mapping & PK Strategy
- JPA ‐ JPA Association Mapping
- JPA - Proxy Association
- JPA - Value Type
- JPA - Dirty Checking vs. Merge: Understanding the Difference in JPA
- JPA - Cascading and Orphan Removal in JPA
- JPA - Introduction to Object-Oriented Query Languages in JPA
- JPA - Spring Data JPA
- JPA ‐ Solving Concurrency Issues with Pessimistic Locking
- JPA ‐ Solving Concurrency Issues with Optimistic Locking
- JPA - Lazy Loading and Performance Optimization in JPA
- JPA - ManyToOne Important Things
- JPA - OneToMany Important Things
- JPA - OSIV
- MicroService Architecture - Service Communications Patterns(RESTful API)
- MicroService Architecture - Service Communications Patterns(GraphQL)
- MicroService Architecture - Service Communications Patterns(gRPC)
- MicroService Architecture - API Gateway Patterns
- MicroService Architecture - Asynchronous Communications Patterns
- MicroService Architecture - Data Management Patterns
- MicroService Architecture - CQRS Patterns
- MicroService Architecture - Distributed Transactions
- [MicroService Architecture - Event-Driven Architecture]
- [MicroService Architecture - Resilience & Observability and Monitoring]
- [MicroService Architecture - Security Patterns]
- [MicroService Architecture - Testing Strategies]
- [MicroService Architecture - Scalability & Caching Patterns]
- [MicroService Architecture - Deployment Patterns]
- [MicroService Architecture - Serverless Architecture]
- [MicroService Architecture - GraphQL]
- [MicroService Architecture - Evolution of Distributed Systems and Their Drawbacks]
- [MicroService Architecture - Protocol Buffers]
- [MicroService Architecture - gRPC Communication Patterns]
- [MicroService Architecture - gRPC Optimization Strategies and Implementation]
- MicroService Architecture - 2PC
- MicroService Architecture - TCC
- MicroService Architecture - SAGA
- Apache Kafka - Kafka Introduction
- Apache Kafka - Kafka CLI
- Apache Kafka - Kafka Producer Application
- Apache Kafka - Kafka Consumer Application
- Apache Kafka - Idempotent Producer & Transactional Producer & Transactional Consumer
- Apache Kafka - Kafka Streams
- Apache Kafka - Kafka Connect
- Apache Kafka - Kafka Topic/Producer/Consumer
- Apache Kafka - Producer Mechanism
- Apache Kafka - Consumer Mechanism
- Apache Kafka - Multi Node Kafka Cluster
- Apache Kafka - Producer & Consumer Serialization/DeSerialization
- Apache Kafka - Topic Segment Management
- Apache Kafka - KSQLDB Stream
- Apache Kafka - KSQLDB Table
- Apache Kafka - KSQLDB Application
- Apache Kafka - Group by & Mview
- [Apache Kafka - Join]
- [Apache Kafka - Time & Windows]
- [Apache Kafka - Connecting KSQLDB to Kafka Connect]
- [Apache Kafka - Kafka Connect]
- [Apache Kafka - JDBC Source Connector]
- [Apache Kafka - JDBC Sink Connector]
- [Apache Kafka - Debezium MySQL CDC Source Connector]
- [Apache Kafka - Schema Registry]
- Apache Kafka - Differences Between RocksDB and In-Memory KeyValueStore in GlobalKTable
- Apache Kafka - Kafka Streams
- [Apache Kafka - Kafka Connect]
- [Apache Kafka - Idempotent Producers and Transactional Producers & Consumers]
- [Apache Kafka - CDC(Change Data Capture)]
- [Apache Flink - Apache Flink Architecture]
- [Apache Flink - Stream Processing]
- [Apache Flink - Data Stream API & Window]
- [Apache Flink - State Management]
- HTTP - Internet Network
- HTTP - URI & Browser Request Flow
- HTTP - HTTP Basic
- HTTP - HTTP Method
- HTTP - HTTP Method Application
- HTTP - HTTP Status Code
- HTTP ‐ HTTP Default Header
- HTTP - HTTP Cache & Condition Request
- AWS - AWS CDK(Cloud Development Kit)
- AWS - Signed URL
- AWS - PreSigned URL
- AWS - Cognito
- AWS - Signed URL Logic
- Docker - Docker
- Docker ‐ Docker CLI
- Docker ‐ Docker Volume
- Docker - Dockerfile Image
- Docker ‐ Docker Compose Container Management
- Docker ‐ Deploy(feat. AWS ECR)
- Docker - Cloud Native Technology
- Docker - Docker Essentials(1)
- Docker - Docker Essentials(2)
- Docker - Docker Network and Storage
- Docker - Building and Managing Containerized Application
- Docker - Container Orchestration
- Docker - Docker Security
- Docker - Logging and Monitoring
- Docker - Advanced Docker Usage
- Docker - Container-to-Container Communication
- [Docker - Docker Image Layer를 활용한 Cache 패턴과 Dangling Image]
- [Docker - Dockerfile 최적화를 위한 빌드 캐싱 및 멀티 스테이지 빌드 패턴]
- [Docker - GitHub Container Registry(GHCR)]
- [Docker - Docker Network 3가지]
- Kubernetes - Probe
- Kubernetes - ConfigMap & Secret
- Kubernetes - PV/PVC & Deployment & Service & HPA
- Kubernetes - Helm & Kustomize
- Kubernetes - Pod 1
- [Kubernetes - Pod 2]
- Kubernetes - Controller 1
- [Kubernetes - Controller 2]
- [Kubernetes - Object]
- [Kubernetes - Ingress & Nginx Application]
- [Kubernetes - Node Scheduling]
- [Kubernetes - Monitoring]
- [Kubernetes - Logging]
- Kubernetes - Deployment using Amazon EKS
- Jenkins - Jenkins Fundamentals & Environment Setup
- Jenkins - Jenkins Jobs: Freestyle & Pipeline
- Jenkins - Jenkins Pipeline Project
- Jenkins - Implementing Continuous Integration(CI) with Jenkins
- Nginx ‐ Nginx Introduction
- Nginx ‐ Nginx Supplementary Summary
- Nginx ‐ Deploying Domain with Nginx
- Nginx ‐ Implementing HTTPS with Nginx
- Nginx ‐ Backend Deployment via Nginx Reverse Proxy
- Nginx ‐ Load Balancing with Nginx
- Nginx - Core Concept
- [Nginx - Advanced Concept]
- [Nginx - Advanced Reverse Proxy]
- Monitoring - Log Level & Filter
- Monitoring - Log Collection with ELK Stack
- Monitoring - Log Monitoring with Kibana
- Monitoring - Server Monitoring with Prometheus and Grafana with Discord Alerts
- Test - Load Testing Fundamentals
- Test - Identifying Bottlenecks with Load Testing
- [Test - Resolving Bottlenecks and Improving Performance]
- Test - JUnit5
- Test - Mockito
- Test - TestContainers
- Test - JMeter
- Test - Chaos Monkey
- Test - ArchUnit
- Test - Appendix: Tips for Better Testing
- [gRPC - Writing .proto Files with Protocol Buffers]
- [gRPC - Various Communication Patterns in gRPC]
- [gRPC - gRPC Optimization Techniques and Advanced Features]
- TDD - Introduction to TDD
- TDD - Iterating with TDD
- TDD - Managing System Data
- TDD - Handling Unexpected Test Failures
- TDD - Abstraction & Reusability
- TDD - Building a Testing DSL
- TDD - Managing Test Context
- TDD - Driving Input Code with Output Tests
- TDD - Pagination Test
- [PostgreSQL - Docker만을 사용하는 경량화된 환경 구성 방법]
- [PostgreSQL - PostgreSQL에서 제공하는 데이터 타입]
- [PostgreSQL - PostgreSQI의 JSONB, 역인덱싱과 활용 방법]
- [PostgreSQL - 데이터베이스 성능을 위한 최적화 패턴 및 전략]
- [PostgreSQL - 트랜잭션과 ACID, Isolation 수준별 차이]
- [PostgreSQL - Database Lock 교착상태와 읽기/쓰기 성능을 보장하는 MVCC 모델]
- [PostgreSQL - pgvector와 벡터 저장, 유사도 검색 패턴 개념]
- [PostgreSQL - 벡터 인덱스 최적화와 벡터 검색과 전문 검색 결합 패턴]
- [PostgreSQL - PostgreSQL 플러그인]
- [PostgreSQL - PostGIS - 공간 쿼리와 GIST 인덱스, 지리 타입과 공간 쿼리를 위한 타입과 기본 함수]
- [PostgreSQL - pg_search - 검색 엔진 없이 텍스트 검색 구현과 주의사항]
- [PostgreSQL - 단일 인스턴스 한계를 극복하는 분산 패턴과 스케줄링, 분산 환경 구축 방법]
- [PostgreSQL - Citus - 분산 테이블과 분산 쿼리를 위한 Extension과 데이터 분산 처리]
- [PostgreSQL - pg_cron - PostgreSQL로 구성하는 CronJob]
- [PostgreSQL - 스케줄러 + 분산 처리를 동시에 도입하는 주기적 집계 쿼리 패턴]
- [Workflow-Driven Techniques for Large-Scale Traffic Processing - Kafka + Debezium을 활용한 CDC 패턴 설계]
- [Workflow-Driven Techniques for Large-Scale Traffic Processing - Temporal을 활용한 워크플로우 패턴]
- [Workflow-Driven Techniques for Large-Scale Traffic Processing - Docker와 경량 이미지를 활용한 환경 구축 방법]
- [Workflow-Driven Techniques for Large-Scale Traffic Processing - Kafka에서의 메시지 Delivery Guarantee]
- [Workflow-Driven Techniques for Large-Scale Traffic Processing - 실시간 동기화의 핵심 CDC]
- [Workflow-Driven Techniques for Large-Scale Traffic Processing - MySQL Binary Log 기반의 CDC]
- [Workflow-Driven Techniques for Large-Scale Traffic Processing - Binary Log 기반의 CDC 구현 플랫폼 Debezium이란?]
- [Workflow-Driven Techniques for Large-Scale Traffic Processing - Debezium Architecture]
- [Workflow-Driven Techniques for Large-Scale Traffic Processing - Debezium Architecture Best Practice와 주의사항]
- Reactive Programming - Everything About Reactive Programming & Core Concepts of Reactive Programming
- Reactive Programming - Mastering Reactor Operators in WebFlux & A Deep Dive into WebFlux Operators
- Reactive Programming - Best Practices and Optional Patterns in WebFlux & Key Practical Patterns for WebFlux Development
- Reactive Programming - Practical WebFlux Patterns with Spring Boot & Building Applications with Spring Boot and WebFlux
- ElasticSearch - Elasticsearch Core Concepts
- ElasticSearch - Basic Search Features & Architecture
- ElasticSearch - Korean Optimized Search
- ElasticSearch - Defining Data Types: Understanding Mappings
- ElasticSearch - Commonly Used Search APIs
- ElasticSearch - Managing Documents (1)
- ElasticSearch - Managing Documents (2)
- ElasticSearch - Analysis and Mapping
- ElasticSearch - All About Search
- ElasticSearch - Query Joins
- ElasticSearch - Processing Query Results
- ElasticSearch - Aggregations
- ElasticSearch - Tips for Improving Search Results
- [ElasticSearch - Elasticsearch Overview]
- [ElasticSearch - Elasticsearch Internals]
- [ElasticSearch - Monitoring]
- [ElasticSearch - Troubleshooting]
- Design Pattern - Strategy
- Design Pattern - Factory Method
- Design Pattern - Abstract Factory
- Design Pattern - Singleton
- Design Pattern - Observer
- Design Pattern - Publisher - Subscriber
- Design Pattern - Decorator
- Design Pattern - Adapter
- Design Pattern - Builder
- Design Pattern - Template Method
- Design Pattern - Facade
- Design Pattern - Proxy
- Design Pattern - Command
- Design Pattern - Chain of Responsibility
- Design Pattern - State
- Design Pattern - Composite
- [Clean Spring - Domain-Driven Development]
- [Clean Spring - Domain-Driven Development with Design Patterns]
- [Clean Spring - Developing Membership Application with Hexagonal Architecture]
- [Clean Spring - JPA and Domain Model Patterns]
- [Clean Spring - Designing a Consistent Domain Model with Aggregates]
- [Clean Spring - Web API Adapter]
- [Clean Spring - Hexagonal Architecture: Ports]
- [Clean Spring - Hexagonal Architecture: Application Components]
- [Clean Spring - Test Improvement & Architecture Validation]
- [Clean Spring - Developing Application Components]
- (Effective Java Item 1) Java ‐ 생성자 대신 정적 팩토리 메서드를 고려하라
- (Effective Java Item 2) Java - 생성자에 매개변수가 많다면 빌더를 고려하라
- (Effective Java Item 3) Java - private 생성자나 열거 타입으로 싱글턴임을 보증하라
- (Effective Java Item 4) Java - 인스턴스화를 막으려거든 private 생성자를 사용하라
- (Effective Java Item 5) Java - 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라
- (Effective Java Item 6) Java ‐ 불필요한 객체 생성을 피하라
- (Effective Java Item 7) Java - 다 쓴 객체 참조를 해제하라
- (Effective Java Item 8) Java - finalizer와 cleaner 사용을 피하라
- (Effective Java Item 9) Java - try‐finally보다는 try‐with‐resources를 사용하라
- (Effective Java Item 10) Java ‐ equals는 일반 규약을 지켜 재정의하라
- (Effective Java Item 11) Java ‐ equals를 재정의하려거든 hashCode도 재정의하라
- (Effective Java Item 12) Java - toString을 항상 재정의하라
- (Effective Java Item 13) Java ‐ clone 재정의는 주의해서 진행하라
- (Effective Java Item 14) Java ‐ Comparable을 구현할지 고려하라
- (Effective Java Item 15) Java ‐ 클래스와 멤버의 접근 권한을 최소화하라
- (Effective Java Item 16) Java ‐ public 클래스에서는 public 필드가 아닌 접근자 메서드를 사용하라
- (Effective Java Item 17) Java ‐ 변경 가능성을 최소화하라
- (Effective Java Item 18) Java ‐ 상속보다는 컴포지션을 사용하라
- (Effective Java Item 19) Java ‐ 상속을 고려해 설계하고 문서화하라. 그러지 않았다면 상속을 금지하라
- (Effective Java Item 20) Java ‐ 추상 클래스보다는 인터페이스를 우선하라
- (Effective Java Item 21) Java ‐ 인터페이스는 구현하는 쪽을 생각해 설계하라
- (Effective Java Item 22) Java ‐ 인터페이스는 타입을 정의하는 용도로만 사용하라
- (Effective Java Item 23) Java ‐ 태그 달린 클래스보다는 클래스 계층구조를 활용하라
- (Effective Java Item 24) Java ‐ 멤버 클래스는 되도록 static으로 만들라
- (Effective Java Item 25) Java ‐ 톱레벨 클래스는 한 파일에 하나만 담으라
- (Effective Java Item 26) Java ‐ 로 타입은 사용하지 말라
- (Effective Java Item 27) Java ‐ 비검사 경고를 제거하라
- (Effective Java Item 28) Java ‐ 배열보다는 리스트를 사용하라
- (Effective Java Item 29) Java ‐ 이왕이면 제네릭 타입으로 만들라
- (Effective Java Item 30) Java ‐ 이왕이면 제네릭 메서드로 만들라
- (Effective Java Item 31) Java - 한정적 와일드카드를 사용해 API 유연성을 높이라
- (Effective Java Item 32) Java - 제네릭과 가변인수를 함께 쓸 때는 신중하라
- (Effective Java Item 33) Java ‐ 타입 안전 이종 컨테이너를 고려하라
- (Effective Java Item 34) Java - int 상수 대신 열거 타입을 사용하라
- (Effective Java Item 35) Java - ordinal 메서드 대신 인스턴스 필드를 사용하라
- (Effective Java Item 36) Java ‐ 비트 필드 대신 EnumSet을 사용하라
- (Effective Java Item 37) Java ‐ ordinal 인덱싱 대신 EnumMap을 사용하라
- (Effective Java Item 38) Java ‐ 확장할 수 있는 열거 타입이 필요하면 인터페이스를 사용하라
- (Effective Java Item 39) Java ‐ 명명 패턴보다 애너테이션을 사용하라[Effective Java Item 39]
- (Effective Java Item 40) Java ‐ @Override 어노테이션을 일괄되게 사용하라
- (Effective Java Item 41) Java ‐ 정의하려는 것이 타입이라면 마커 인터페이스를 사용하라
- (Effective Java Item 42) Java ‐ 익명 클래스보다는 람다를 사용하라
- (Effective Java Item 43) Java ‐ 람다보다는 메서드 참조를 사용하라
- (Effective Java Item 44) Java - 표준 함수형 인터페이스를 사용하라
- (Effective Java Item 45) Java - 스트림은 주의해서 사용하라
- (Effective Java Item 46) Java - 스트림에서는 부작용 없는 함수를 사용하라
- (Effective Java Item 47) Java - 반환 타입으로는 스트림보다 컬렉션이 낫다
- (Effective Java Item 48) Java ‐ 스트림 병렬화는 주의해서 사용하라
- (Effective Java Item 49) Java ‐ 매개변수가 유효한지 검사하라
- (Effective Java Item 50) Java ‐ 적시에 방어적 복사본을 만들라
- (Effective Java Item 51) Java ‐ 메서드 시그니처를 신중히 설계하라
- (Effective Java Item 52) Java ‐ 다중정의는 신중히 사용하라
- (Effective Java Item 53) Java ‐ 가변인수는 신중히 사용하라
- (Effective Java Item 54) Java - null이 아닌, 빈 컬렉션이나 배열을 반환하라
- (Effective Java Item 55) Java ‐ 옵셔널 반환은 신중히 하라
- (Effective Java Item 56) Java ‐ 공개된 API 요소에는 항상 문서화 주석을 사용하라
- (Effective Java Item 57) Java ‐ 지역변수의 범위를 최소화하라
- (Effective Java Item 58) Java ‐ 전통적인 for문보다는 for‐each문을 사용하라
- (Effective Java Item 59) Java ‐ 라이브러리를 익히고 사용하라
- (Effective Java Item 60) Java ‐ 정확한 답이 필요하다면 float와 double은 피하라
- (Effective Java Item 61) Java ‐ 박싱된 기본 타입보다는 기본 타입을 사용하라
- (Effective Java Item 62) Java ‐ 다른 타입이 적절하다면 문자열 사용을 피하라
- (Effective Java Item 63) Java ‐ 문자열 연결은 느리니 주의하라
- (Effective Java Item 64) Java ‐ 객체는 인터페이스를 사용해 참조하라
- (Effective Java Item 65) Java ‐ 리플렉션보다는 인터페이스를 사용하라
- (Effective Java Item 66) Java ‐ 네이티브 메서드는 신중히 사용하라
- (Effective Java Item 67) Java ‐ 최적화는 신중히 하라
- (Effective Java Item 68) Java ‐ 일반적으로 통용되는 명명 규칙을 따르라
- (Effective Java Item 69) Java ‐ 예외는 진짜 예외 상황에만 사용하라
- (Effective Java Item 70) Java ‐ 복구할 수 있는 상황에는 검사 예외를, 프로그래밍 오류에는 런타임 예외를 사용하라
- (Effective Java Item 71) Java ‐ 필요 없는 검사 예외 사용은 피하라
- (Effective Java Item 72) Java ‐ 표준 예외를 사용하라
- (Effective Java Item 73) Java ‐ 추상화 수준에 맞는 예외를 던지라
- (Effective Java Item 74) Java ‐ 메서드가 던지는 모든 예외를 문서화하라
- (Effective Java Item 75) Java ‐ 예외의 상세 메시지에 실패 관련 정보를 담으라
- (Effective Java Item 76) Java ‐ 가능한 한 실패 원자적으로 만들라
- (Effective Java Item 77) Java ‐ 예외를 무시하지 말라
- (Effective Java Item 78) Java - 공유 중인 가변 데이터는 동기화해 사용하라
- (Effective Java Item 79) Java - 과도한 동기화는 피하라
- (Effective Java Item 80) Java - 쓰레드보다는 실행자, 태스크, 스트림을 애용하라
- (Effective Java Item 81) Java - wait와 notify는 동시성 유틸리티를 애용하라
- (Effective Java Item 82) Java - 쓰레드 안전성 수준을 문서화하라
- (Effective Java Item 83) Java - 지연 초기화는 신중히 사용하라
- (Effective Java Item 84) Java - 프로그램의 동작을 쓰레드 스케줄러에 기대지 말라
- (Effective Java Item 85) Java - 자바 직렬화의 대안을 찾으라
- (Effective Java Item 86) Java - Serializable을 구현할지는 신중히 결정하라
- (Effective Java Item 87) Java - 커스텀 직렬화 형태를 고려해보라
- (Effective Java Item 88) Java - readObject 메서드는 방어적으로 작성하라
- (Effective Java Item 89) Java - 인스턴스 수를 통제해야 한다면 readResolve보다는 열거 타입을 사용하라
- [🔖(Effective Java Item 90) Java - 직렬화된 인스턴스 대신 직렬화 프록시 사용을 검토하라]
- (Effective Kotlin Item 1) Kotlin - 가변성을 제한하라
- (Effective Kotlin Item 2) Kotlin - 임계 영역을 제거하라
- (Effective Kotlin Item 3) Kotlin - 가능한 한 빨리 플랫폼 타입을 제거하라
- (Effective Kotlin Item 4) Kotlin - 변수의 스코프를 최소화하라
- (Effective Kotlin Item 5) Kotlin - 인수와 상태에 대한 기대치를 명시하라
- (Effective Kotlin Item 6) Kotlin - 사용자 정의 오류보다 표준 오류를 선호하라
- (Effective Kotlin Item 7) Kotlin - 결과가 없을 가능성이 있는 경우 널 가능 또는 Result 반환 타입을 선호하라
- (Effective Kotlin Item 8) Kotlin - use를 사용하여 리소스를 닫아라
- (Effective Kotlin Item 9) Kotlin - 단위 테스트를 작성하라
- (Effective Kotlin Item 10) Kotlin - 가독성을 목표로 설계하라
- (Effective Kotlin Item 11) Kotlin - 연산자의 의미는 함수의 이름과 일치해야 한다
- (Effective Kotlin Item 12) Kotlin - 가독성을 높이려면 연산자를 사용하라
- (Effective Kotlin Item 13) Kotlin - 타입 명시를 고려하라
- (Effective Kotlin Item 14) Kotlin - 리시버를 명시적으로 참조하라
- (Effective Kotlin Item 15) Kotlin - 프로퍼티는 동작이 아닌 상태를 나타내야 한다
- (Effective Kotlin Item 16) Kotlin - Unit?을 반환이나 연산에 사용하지 말라
- (Effective Kotlin Item 17) Kotlin - 이름 있는 인수 사용을 고려하라
- (Effective Kotlin Item 18) Kotlin - 코딩 컨벤션을 준수하라
- (Effective Kotlin Item 19) Kotlin - knowledge를 반복하지 말라
- (Effective Kotlin Item 20) Kotlin - 일반적인 알고리즘을 반복하지 말라
- (Effective Kotlin Item 21) Kotlin - 일반적인 알고리즘을 구현할 때 제네릭을 사용하라
- (Effective Kotlin Item 22) Kotlin - 타입 매개변수의 섀도잉을 피하라
- (Effective Kotlin Item 23) Kotlin - 제네릭 타입에 변성 한정자 사용을 고려하라
- (Effective Kotlin Item 24) Kotlin - 공통 모듈을 추출해서 여러 플랫폼에서 재사용하라
- (Effective Kotlin Item 25) Kotlin - 각각의 함수는 하나의 추상화 수준으로 작성하라
- (Effective Kotlin Item 26) Kotlin - 변경으로부터 코드를 보호하려면 추상화를 사용하라
- (Effective Kotlin Item 27) Kotlin - API 안정성을 명시하라
- (Effective Kotlin Item 28) Kotlin - 외부 API를 래핑하는 것을 고려하라
- (Effective Kotlin Item 29) Kotlin - 가시성을 최소화하라
- (Effective Kotlin Item 30) Kotlin - 문서로 규약을 정의하라
- (Effective Kotlin Item 31) Kotlin - 추상화 규약을 준수하라
- (Effective Kotlin Item 32) Kotlin - 보조 생성자 대신 팩토리 함수를 고려하라
- (Effective Kotlin Item 33) Kotlin - 이름 있는 선택적 인수를 갖는 기본 생성자 사용을 고려하라
- (Effective Kotlin Item 34) Kotlin - 복잡한 객체 생성을 위해 DSL 정의를 고려하라
- (Effective Kotlin Item 35) Kotlin - 의존성 주입을 고려하라
- (Effective Kotlin Item 36) Kotlin - 상속보다 합성을 선호하라
- (Effective Kotlin Item 37) Kotlin - 데이터 묶음을 표현할 때 data 한정자를 사용하라
- (Effective Kotlin Item 38) Kotlin - 연산과 행동을 전달하려면 함수 타입이나 함수형 인터페이스를 사용하라
- (Effective Kotlin Item 39) Kotlin - 제한된 계층구조를 표현하기 위해 sealed 클래스와 sealed 인터페이스를 사용하라
- [(Effective Kotlin Item 40) Kotlin - 태그 클래스 대신 클래스 계층구조를 선호하라]
- [(Effective Kotlin Item 41) Kotlin - 열거형 클래스를 사용해서 값 목록을 나타내라]
- [(Effective Kotlin Item 42) Kotlin - equals의 규약을 준수하라]
- [(Effective Kotlin Item 43) Kotlin - hashCode의 규약을 준수하라]
- [(Effective Kotlin Item 44) Kotlin - compareTo의 규약을 준수하라]
- [(Effective Kotlin Item 45) Kotlin - API의 필수적이지 않은 부분을 확장으로 추출하는 것을 고려하라]
- [(Effective Kotlin Item 46) Kotlin - 멤버 확장 함수를 피하라]
- (Effective Kotlin Item 3) Kotlin - variable
- (Effective Kotlin Item 4) Kotlin - primitive types, literals, and operations
- (Effective Kotlin Item 5) Kotlin - control Flow: if, when, try, and while
- (Effective Kotlin Item 6) Kotlin - function
- (Effective Kotlin Item 7) Kotlin - for
- (Effective Kotlin Item 8) Kotlin - Null Safety and Nullable Types
- (Effective Kotlin Item 9) Kotlin - Class
- (Effective Kotlin Item 10) Kotlin - Extend
- (Effective Kotlin Item 11) Kotlin - Data Class
- (Effective Kotlin Item 12) Kotlin - Object
- (Effective Kotlin Item 13) Kotlin ‐ Exception
- (Effective Kotlin Item 14) Kotlin - Enum Classes
- (Effective Kotlin Item 15) Kotlin - Sealed Classes and Interfaces
- (Effective Kotlin Item 16) Kotlin - Annotation Classes
- (Effective Kotlin Item 17) Kotlin - Extensions
- (Effective Kotlin Item 18) Kotlin - Collections
- (Effective Kotlin Item 19) Kotlin - Operator Overloading
- (Effective Kotlin Item 20) Kotlin - The Beauty of the Type System
- (Effective Kotlin Item 21) Kotlin - Generic
- Reactive Programming - Reactive Streams
- Reactive Programming - Blocking I/O & Non-Blocking I/O
- Reactive Programming - Reactor Outline
- Reactive Programming - Marble Diagram
- Reactive Programming - Cold Sequence & Hot Sequence
- [Reactive Programming - Backpressure]
- [Reactive Programming - Sinks]
- [Reactive Programming - Scheduler]
- [Reactive Programming - Context]
- [Reactive Programming - Debugging]
- [Reactive Programming - Testing]
- [Reactive Programming - Operators]
- [Reactive Programming - Spring Webflux]
- [Reactive Programming - Annotation Based Controller]
- [Reactive Programming - Functional Endpoint]
- [Reactive Programming - Spring Data R2DBC]
- [Reactive Programming - Exception Handling]
- [Reactive Programming - WebClient]
- [Reactive Programming - Reactive Streaming Data Processing]
- 가상 면접 사례로 배우는 대규모 시스템 설계 기초 1 - 사용자 수에 따른 규모 확장성
- 가상 면접 사례로 배우는 대규모 시스템 설계 기초 1 - 개략적인 규모 추정
- 가상 면접 사례로 배우는 대규모 시스템 설계 기초 1 - 처리율 제한 장치의 설계
- [가상 면접 사례로 배우는 대규모 시스템 설계 기초 1 - 안정 해시 설계]
- [가상 면접 사례로 배우는 대규모 시스템 설계 기초 1 - 키-값 저장소 설계]
- [가상 면접 사례로 배우는 대규모 시스템 설계 기초 1 - 분산 시스템을 위한 유일 ID 생성기 설계]
- [가상 면접 사례로 배우는 대규모 시스템 설계 기초 1 - URL 단축기 설계]
- [가상 면접 사례로 배우는 대규모 시스템 설계 기초 1 - 웹 크롤러 설계]
- [가상 면접 사례로 배우는 대규모 시스템 설계 기초 1 - 알림 시스템 설계]
- [가상 면접 사례로 배우는 대규모 시스템 설계 기초 1 - 뉴스 피드 시스템 설계]
- [가상 면접 사례로 배우는 대규모 시스템 설계 기초 1 - 채팅 시스템 설계]
- [가상 면접 사례로 배우는 대규모 시스템 설계 기초 1 - 검색어 자동완성 시스템 설계]
- [가상 면접 사례로 배우는 대규모 시스템 설계 기초 1 - 유튜브 설계]
- [가상 면접 사례로 배우는 대규모 시스템 설계 기초 1 - 구글 드라이브 설계]
- (Clean Code 2) Clean Code - 의미 있는 이름
- (Clean Code 3) Clean Code - 함수
- (Clean Code 4) Clean Code - 주석
- (Clean Code 5) Clean Code - 형식 맞추기
- (Clean Code 6) Clean Code - 객체와 자료구조
- (Clean Code 7) Clean Code - 오류 처리
- (Clean Code 8) Clean Code - 경계
- (Clean Code 9) Clean Code - 단위 테스트
- (Clean Code 10) Clean Code - 클래스
📖 리팩토링 2판⭐
- 주니어 백엔드 개발자가 반드시 알아야 할 실무 지식 - 느려진 서비스, 어디부터 봐야 할까
- 주니어 백엔드 개발자가 반드시 알아야 할 실무 지식 - 성능을 좌우하는 DB 설계와 쿼리
- 주니어 백엔드 개발자가 반드시 알아야 할 실무 지식 ‐ 외부 연동이 문제일 때 살펴봐야 할 것들
- 주니어 백엔드 개발자가 반드시 알아야 할 실무 지식 ‐ 비동기 연동, 언제 어떻게 써야 할까
- 주니어 백엔드 개발자가 반드시 알아야 할 실무 지식 ‐ 동시성, 데이터가 꼬이기 전에 잡아야 한다
- 주니어 백엔드 개발자가 반드시 알아야 할 실무 지식 ‐ IO 병목, 어떻게 해결하지
- 주니어 백엔드 개발자가 반드시 알아야 할 실무 지식 ‐ 실무에서 꼭 필요한 보안 지식
- 주니어 백엔드 개발자가 반드시 알아야 할 실무 지식 ‐ 모르면 답답해지는 네트워크 기초
- 주니어 백엔드 개발자가 반드시 알아야 할 실무 지식 ‐ 자주 쓰는 서버 구조와 설계 패턴
- 주니어 백엔드 개발자가 반드시 알아야 할 실무 지식 ‐ 처음 해보는 성능 테스트를 위한 기본 정리
- 주니어 백엔드 개발자가 반드시 알아야 할 실무 지식 ‐ NoSQL 이해하기
- 주니어 백엔드 개발자가 반드시 알아야 할 실무 지식 ‐ DB로 분산 잠금 구현하기
- 개발자가 반드시 정복해야 할 객체 지향과 디자인 패턴 - 객체 지향
- 개발자가 반드시 정복해야 할 객체 지향과 디자인 패턴 - 다형성과 추상 타입
- 개발자가 반드시 정복해야 할 객체 지향과 디자인 패턴 - 재사용: 상속보단 조립
- 개발자가 반드시 정복해야 할 객체 지향과 디자인 패턴 - 설계 원칙: SOLID
- 개발자가 반드시 정복해야 할 객체 지향과 디자인 패턴 - DI(Dependency Injection)와 서비스 로케이터
- 개발자가 반드시 정복해야 할 객체 지향과 디자인 패턴 - 주요 디자인 패턴
- [Real MySQL 8.0 - 인덱스]
- [Real MySQL 8.0 - 실행 계획]
- [Real MySQL 8.0 - 아키텍처]
- [Real MySQL 8.0 - 트랜잭션과 잠금]
- 객체지향의 사실과 오해(역할, 책임, 협력 관점에서 본 객체지향) - 협력하는 객체들의 공동체
- 객체지향의 사실과 오해(역할, 책임, 협력 관점에서 본 객체지향) - 이상한 나라의 객체
- [객체지향의 사실과 오해(역할, 책임, 협력 관점에서 본 객체지향) - 타입과 추상화]
- [객체지향의 사실과 오해(역할, 책임, 협력 관점에서 본 객체지향) - 역할, 책임, 협력]
- [객체지향의 사실과 오해(역할, 책임, 협력 관점에서 본 객체지향) - 책임과 메시지]
- [객체지향의 사실과 오해(역할, 책임, 협력 관점에서 본 객체지향) - 객체 지도]