-
Notifications
You must be signed in to change notification settings - Fork 0
ElasticSearch ‐ Managing Document (2)
woojin edited this page Aug 1, 2026
·
2 revisions
POST /my_index/_doc/100
{
"title": "Elasticsearch Advanced",
"author": "Anthony K",
"publish_date": "2024-05-20",
"tags": ["search", "analytics"]
}- 경로는
/{인덱스}/_doc/{문서 ID}형태다. - 본문은 JSON 문서 전체를 그대로 보낸다.
GET /my_index/_doc/100- 경로 마지막의
100이 Document Id다. - ID를 알면 해당 문서 하나를 바로 가져온다.
기존 필드 수정
POST /my_index/_update/100
{
"doc": {
"author": "Anthony K2"
}
}새 필드 추가
POST /my_index/_update/100
{
"doc": {
"price": 100
}
}-
_doc이 아니라_update엔드포인트를 쓴다. - 바꿀 내용을
doc안에 담는다. 기존 필드 수정과 새 필드 추가가 같은 문법이다.
- 수정 요청이 들어와도 문서를 제자리에서 고치지 않는다. Elasticsearch 내부에서는 아래 순서로 처리한다.
- 기존 문서 조회(Fetch) — 인덱스에서 현재 버전의 문서를 가져온다.
- 변경 적용(Apply Changes) — 가져온 문서에 요청한 변경을 반영한다.
- 새 문서로 색인(Index) — 수정된 문서를 새 버전으로 색인한다.
- 기존 문서 삭제 표시(Mark as Deleted) — 이전 버전은 논리적 삭제(logical deletion) 처리한다. 인덱스에 남아 있되 삭제 플래그가 붙고 검색 대상에서 제외된다.
- 세그먼트 병합(Segment Merging) — 백그라운드 작업이 삭제 표시된 문서를 물리적으로 제거하고 공간을 회수한다.
- 일관성(Consistency) — 제자리 수정을 하지 않으므로 분산 환경에서 race condition과 데이터 손상을 피할 수 있다.
- 버전 관리(Versioning) — 수정할 때마다 새 버전이 생기므로 동시 수정 관리가 쉽고, optimistic concurrency control 같은 기능을 제공할 수 있다.
- 성능(Performance) — Elasticsearch는 append-only 워크로드에 최적화되어 있어 색인과 검색 성능에 유리하다.
# delete a document
DELETE /my_index/_doc/100
# flush a document
POST /my_index/_flush-
DELETE도 즉시 물리 삭제가 아니라 삭제 표시다. 실제 제거는 세그먼트 병합 시점에 일어난다. -
_flush는 메모리의 변경분을 디스크에 반영한다.
- 스크립트는 문서 색인, 수정, 검색 과정에서 더 복잡한 연산과 계산을 수행할 수 있게 해준다.
- Inline Scripts — 요청 안에 직접 작성하는 스크립트다.
- Stored Scripts — 서버에 저장해두고 고유 ID로 참조하는 스크립트다.
-
File Scripts — 각 노드의
config/scripts디렉터리에 저장하는 방식이다. 보안상의 이유로 잘 쓰이지 않고 권장되지도 않는다.
- Elasticsearch는 여러 스크립트 언어를 지원하지만, Painless가 가장 권장되며 안전하다.
- Groovy, JavaScript, Python도 사용할 수 있으나 성능과 보안 측면에서 Painless가 우선된다.
문서 수정 예시
POST /my_index/_update/100
{
"script": {
"source": "ctx._source.price += 10"
}
}-
ctx._source로 현재 문서에 접근해 값을 직접 계산한다.
커스텀 스코어링 예시
POST /my_index/_search
{
"query": {
"function_score": {
"query": {
"match_all": {}
},
"script_score": {
"script": {
"source": "doc['price'].value * _score"
}
}
}
}
}- Painless를 사용한다 — 보안과 성능 모두에서 유리하다.
- 스크립팅 권한을 신뢰할 수 있는 사용자로 제한한다.
- 필요하지 않다면 운영 환경에서 동적 스크립팅을 비활성화한다.
- 공통적이고 재사용되는 스크립트는 stored script로 만들어 공격 표면을 줄인다.
- Elasticsearch의 upsert는 update와 insert를 결합한 연산이다.
- 지정한 ID의 문서가 있으면 수정(update) 한다.
- 없으면 제공한 내용으로 새 문서를 생성(insert) 한다.
POST /my_index/_update/5
{
"doc": {
"author": "John Doe"
},
"upsert": {
"title": "Elasticsearch Basics",
"author": "Jane Doe",
"publish_date": "2024-05-09",
"tags": ["search", "analytics"]
}
}-
doc— 문서가 이미 있을 때 적용할 변경 내용이다. 여기서는author만 바뀐다. -
upsert— 문서가 없을 때 새로 생성할 문서 전체다. - 즉 문서 존재 여부에 따라 둘 중 하나만 사용된다.
POST /my_index/_update/7
{
"script": {
"source": "ctx._source.price++"
},
"upsert": {
"title": "Elasticsearch Basics",
"author": "Jane Doe",
"publish_date": "2024-05-09",
"price": 100,
"tags": ["search", "analytics"]
}
}-
script— 문서가 있을 때 실행할 로직이다. 기존 값을 읽어 계산한다(price++). -
upsert— 문서가 없을 때 생성할 초기 문서다. 초기값price: 100을 함께 넣어둔다. - 카운터처럼 기존 값을 증가시키되 첫 요청에서는 초기값을 세워야 하는 경우에 쓰는 형태다.
PUT /my_index/_doc/20
{
"title": "Elasticsearch Basics",
"author": "John Doe",
"publish_date": "2024-05-09",
"tags": ["search", "analytics"]
}- 같은 ID에 다시
PUT을 보내면 문서 전체가 교체된다. -
PUT /{index}/_doc/{id}는 부분 수정이 아니라 전체 덮어쓰기다. - 요청 본문에 없는 필드는 사라진다.
PUT /my_index/_doc/20
{
"title": "Updated Elasticsearch Basics",
"author": "Jane Doe",
"publish_date": "2024-06-01",
"tags": ["search", "analytics", "updated"]
}- Routing은 인덱스 안에서 문서가 shard들에 어떻게 분산되는지를 결정하는 메커니즘이다.
- 제대로 활용하면 Elasticsearch 작업의 성능과 효율을 크게 개선할 수 있다. 특히 대용량 데이터셋이나 특정한 쿼리 패턴에서 효과가 크다.
- Default Routing — 문서 ID를 해싱해 shard를 정한다.
- Custom Routing — shard를 결정할 커스텀 값(routing key) 을 직접 지정한다. 더 효율적인 쿼리가 가능해진다.
-
쿼리 성능 향상(Improved Query Performance)
- 연관된 문서들이 같은 shard에 저장되도록 보장하면, Elasticsearch가 질의해야 할 shard 수를 줄일 수 있어 응답이 빨라진다.
-
데이터 지역성(Data Locality)
- 연관 데이터를 함께 저장하므로, 멀티테넌시나 데이터 분할 시나리오를 가진 애플리케이션에 특히 유용하다.
색인할 때 routing key 지정
POST /my_index/_doc/1?routing=user123
{
"title": "Elasticsearch Basics",
"author": "John Doe",
"publish_date": "2024-05-09",
"tags": ["search", "analytics"]
}검색할 때 같은 routing key 지정
GET /my_index/_search?routing=user123
{
"query": {
"match": {
"author": "John Doe"
}
}
}- 쿼리 파라미터
?routing=으로 값을 넘긴다. - 색인과 검색에 같은 키를 쓰면, 검색이 모든 shard가 아니라 해당 shard만 조회한다.
-
shard 불균형(Shard Imbalance)
- custom routing을 조심해서 쓰지 않으면 데이터가 고르지 않게 분포할 수 있다. routing key가 shard 전체에 고르게 퍼지는 값인지 확인해야 한다.
-
routing key 변경(Routing Key Changes)
- 문서를 routing key와 함께 색인하고 나면, 문서를 재색인하지 않고는 routing key를 바꿀 수 없다.
- Client Request — 클라이언트가 Elasticsearch 노드(coordinating node)로 요청을 보낸다. 검색 쿼리, ID로 문서 조회, 집계 등이 모두 해당한다.
- Coordinating Node — 요청 처리를 담당한다. 요청을 파싱해 어떤 인덱스와 shard를 조회해야 하는지 판단한다.
- Routing — 쿼리에 관련된 각 shard에 대해, coordinating node가 적절한 shard 복사본으로 요청을 전달한다. 각 인덱스는 shard로 나뉘고 각 shard는 primary 하나와 0개 이상의 replica를 가지므로, 어느 복사본을 조회할지 결정해야 한다.
- Shard Level Execution — 요청이 primary shard 또는 replica shard 중 하나로 전달된다(연산 종류와 부하 분산 설정에 따라 달라진다). 해당 shard가 로컬에서 쿼리나 조회를 수행한다.
- Aggregation and Reduction — 검색 쿼리의 경우 각 shard가 쿼리를 실행하고 결과를 coordinating node로 돌려준다. coordinating node는 이 결과들을 취합해(검색 결과 병합, 최종 집계 수행) 완전한 응답을 만든다.
- Response to Client — coordinating node가 최종 취합된 응답을 클라이언트에 보낸다.
- 읽기 요청을 처리할 최적의 shard 복사본(primary 또는 replica)을 동적으로 선택해 읽기 성능과 효율을 개선하도록 설계된 기능이다.
- 이 선택은 노드의 현재 성능과 부하 지표를 근거로 이루어진다.
동작 방식
- 지표 수집(Metrics Collection) — Elasticsearch는 각 shard 복사본(primary와 replica 모두)에 대해 응답 시간, 부하, 큐 크기 같은 지표를 수집한다.
- 동적 선택(Dynamic Selection) — 읽기 요청이 오면 특정 복사본으로 정적으로 라우팅하지 않고, coordinating node가 이 지표들을 이용해 가장 빠른 응답이 기대되는 복사본을 동적으로 선택한다.
효과
- 부하 분산(Load Balancing) — 가장 덜 바쁘거나 가장 빠르게 응답하는 shard를 고르므로, 노드 간 부하가 더 효과적으로 분산되고 전체 시스템 성능이 최적화된다.
- 지연 개선(Improved Latency) — 읽기 요청을 가장 응답성이 좋은 복사본으로 보내므로, 지연이 줄고 클러스터의 응답성이 향상된다.
- Client Request — 클라이언트가 문서를 쓰기 위해 Elasticsearch 노드(coordinating node)로 색인 요청을 보낸다. 요청에는 문서 내용과 저장할 인덱스가 담긴다.
- Document Routing — coordinating node가 어느 shard가 이 문서를 담아야 하는지 결정한다. 기본적으로 문서 ID의 해시로 shard를 정하며, custom routing을 설정할 수도 있다.
-
Primary Shard Processing — 요청이 해당 문서를 담당하는 primary shard로 전달된다. 인덱스가 샤딩되어 있으면 각 문서는 routing에 따라 하나의 primary shard에 배정된다.
- primary shard가 쓰기를 처리하고 sequence number를 부여한다.
- 현재 primary shard의 primary term이 함께 포함된다.
- primary shard는 연산을 영속화한 뒤 local checkpoint를 갱신한다.
- Replication — primary shard가 쓰기를 처리하고 나면, sequence number와 primary term을 포함해 모든 replica shard로 연산을 전달한다. 각 replica가 쓰기를 처리하고 자신의 local checkpoint를 갱신한다. primary와 모든 replica가 쓰기를 확인해야만 쓰기 연산이 성공으로 간주된다.
- Global Checkpoint Update — primary shard가 모든 replica의 local checkpoint를 추적한다. in-sync 상태인 replica 전부가 쓰기를 확인하면, primary shard가 global checkpoint를 모든 replica가 확인한 가장 높은 sequence number로 갱신한다.
- Acknowledgment — coordinating node가 primary와 모든 replica의 확인 응답을 기다린다. 전부 확인되면 클라이언트에 성공 응답을 보낸다.
| 개념 | 의미 |
|---|---|
| Translog | write-ahead log 역할을 한다 |
| Checkpoint | translog에서 커밋 성공 지점을 표시하는 marker |
| ├ Global Checkpoint | shard의 in-sync 복사본 전체가 도달한 지점 |
| └ Local Checkpoint | 개별 shard 하나가 도달한 지점 |
| Primary Term | primary shard가 재할당될 때마다 증가하는 카운터 |
| Sequence Number | 연산을 순서대로 처리하기 위한 카운터 |
1단계 — 첫 쓰기
Global checkpoint: 99
Primary: 99 → 100
Replica1: 99 → 100
Replica2: 99 → 99 (in progress)
2단계 — 두 번째 쓰기
Global checkpoint: 99
Primary: 99 → 100 → 101
Replica1: 99 → 100 → 101
Replica2: 99 → 99 (in progress)
3단계 — 뒤처진 replica가 따라잡음
Global checkpoint: 99 → 101
Primary: 99 → 100 → 101
Replica1: 99 → 100 → 101
Replica2: 99 → 99 → 100 → 101
- primary와 replica1이 101까지 앞서가도, replica2가 99에 머물러 있는 동안 global checkpoint는 99에서 움직이지 않는다.
- replica2가 101까지 따라잡은 뒤에야 global checkpoint가 101로 올라간다.
- 즉 global checkpoint는 가장 뒤처진 in-sync 복사본이 결정한다. 이 지점까지는 모든 복사본이 동일함이 보장되므로, 장애 복구 시 어디부터 재전송해야 하는지의 기준이 된다.
- Elasticsearch에서 동시성 문제를 다루는 것은 데이터 일관성과 정확성을 보장하기 위해 반드시 필요하다. 특히 처리량이 많은 환경에서 중요하다.
- 두 클라이언트가 같은 문서를 동시에 다룰 때 일어나는 일이다.
- 각자 자기가 읽은 값(10)을 기준으로 계산했기 때문에, 나중 쓰기가 앞선 쓰기를 덮어쓴다.
- OCC는 Elasticsearch가 여러 클라이언트의 동시 읽기는 허용하되, 특정 시점에 쓸 수 있는 클라이언트는 하나뿐임을 보장하는 방식이다.
-
if_primary_term과if_seq_no로 구현한다.
POST /store/_update/1?if_primary_term=1&if_seq_no=3-
성공 — 문서가 여전히
_seq_no: 3,_primary_term: 1이면 갱신된다. -
실패 — 그 사이 다른 클라이언트가 문서를 바꿔
_seq_no가 달라졌다면 거부되고version_conflict_engine_exception오류가 발생한다. - 즉 "내가 읽은 그 버전이 아직 그대로일 때만 써라"는 조건부 쓰기다.
- 쿼리를 기준으로 문서들을 수정하려면
_update_by_queryAPI를 사용한다.
전체 문서 수정 — 쿼리 없이
POST /store/_update_by_query
{
"script": {
"source": "ctx._source.stock -= 1"
}
}-
query를 생략하면 인덱스의 모든 문서에 스크립트가 적용된다.
조건에 맞는 문서만 수정 — 쿼리 지정
POST /store/_update_by_query
{
"script": {
"source": "ctx._source.stock -= 1"
},
"query": {
"term": {
"product": "peach"
}
}
}-
query를 함께 주면 매칭된 문서에만 스크립트가 적용된다. - 여기서는
product가peach인 문서들의stock만 1씩 줄어든다.
- 쿼리를 기준으로 문서들을 삭제하려면
_delete_by_queryAPI를 사용한다.
POST /store/_delete_by_query
{
"query": {
"term": {
"product": "apple"
}
}
}
-
product가apple인 문서들이 삭제된다.
- Elasticsearch의 bulk action은 여러 건의 index, update, delete, create 연산을 하나의 API 호출로 수행하는 방법이다.
- 개별 요청을 여러 번 보내는 오버헤드를 줄여 효율적이다. 대용량 데이터 색인, 다건 문서 수정, 문서 일괄 삭제에 특히 유용하다.
| Action | 동작 | 문서가 이미 있으면 |
|---|---|---|
| Index | 문서를 추가하거나 갱신한다 | 교체(replace) 된다 |
| Update | 문서를 부분 수정한다 | — (없으면 upsert로 생성 가능) |
| Delete | ID로 문서를 삭제한다 | — |
| Create | 새 문서를 추가한다 | 실패한다 |
- Index — 있으면 덮어쓰고 없으면 만든다. 존재 여부를 신경 쓰지 않을 때 쓴다.
- Update — 지정한 필드만 바꾼다. 문서가 없을 때를 대비하려면 upsert를 함께 쓴다.
- Delete — 문서 ID를 지정해 삭제한다.
- Create — 새로 만드는 경우에만 성공한다. 중복 생성을 막고 싶을 때 쓴다.
- 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 - 트랜잭션과 잠금]
- 객체지향의 사실과 오해(역할, 책임, 협력 관점에서 본 객체지향) - 협력하는 객체들의 공동체
- 객체지향의 사실과 오해(역할, 책임, 협력 관점에서 본 객체지향) - 이상한 나라의 객체
- [객체지향의 사실과 오해(역할, 책임, 협력 관점에서 본 객체지향) - 타입과 추상화]
- [객체지향의 사실과 오해(역할, 책임, 협력 관점에서 본 객체지향) - 역할, 책임, 협력]
- [객체지향의 사실과 오해(역할, 책임, 협력 관점에서 본 객체지향) - 책임과 메시지]
- [객체지향의 사실과 오해(역할, 책임, 협력 관점에서 본 객체지향) - 객체 지도]