-
Notifications
You must be signed in to change notification settings - Fork 0
Coroutine ‐ CoroutineDispatcher
woojin.jang edited this page May 22, 2026
·
1 revision
- 사용자의 요청 :
launch나async와 같은 빌더를 통해 코루틴이 새로 생성된다. - 작업 대기열(Queue) 적재 : 디스패처는 넘겨받은 코루틴을 관리 하에 있는 동기화된 작업 대기열에 적재한다.
- 쓰레드 풀 상태 : Thread-1이 코루틴 1을, Thread-2가 코루틴 2를 할당받아 하부 CPU 코어 위에서 활발히 동기 연산을 수행 중인 상태이다.
- 쓰레드 가용 상태 전환 : Thread-1이 실행 중이던 코루틴 1 연산을 완료하면 해당 쓰레드는 디스패처에게 다음 작업을 요청한다.
- Deque 및 Dispatch : 디스패처는 작업 대기열의 코루틴 3을 꺼내어 비어있는 Thread-1에 바인딩한다.
- 실행 : Thread-1은 코루틴 3 내부에 정의된 코드 블록을 실행하기 시작한다.
- 단일 쓰레드 디스패처란, 생성된 코루틴들을 오직 단 하나의 쓰레드에만 할당해 순차적으로 실행하도록 강제하는 코루틴 디스패처이다.
- 다중 쓰레드 풀을 사용하는 다른 것과 달리 작업 대기열에 쌓인 코루틴들이 아무리 많아도 단 1개의 지정된 쓰레드가 컨텍스트 스위칭을 하며 작업을 처리한다.
- 멀티 쓰레드 디스패처란, 생성된 코루틴들을 여러 개의 쓰레드로 구성된 쓰레드 풀에 분배해 병렬 및 동시 실행을 제어하는 코루틴 디스패처이다. 1. 내부 아키텍처 및 구동 메커니즘
- 공유 작업 대기열 및 로컬 대기열 : 생성된 코루틴들은 일차적으로 디스패처가 관리하는 공유 작업 대기열에 적재되거나 각 워커 쓰레드가 소유한 독립적인 로컬 큐에 할당된다.
- 라운드 로빈 및 작업 할당 : 풀 내부의 가용 상태인 워커 쓰레드들이 큐에서 코루틴 객체를 하나씩 꺼내어 자신에게 할당된 CPU 코어 위에서 실행한다.
- 작업 훔치기 알고리즘 : 특정 쓰레드가 자신에게 할당된 로컬 큐 작업을 모두 끝내면 여전히 작업이 많이 남아있는 다른 쓰레드의 로컬 큐에서 코루틴을 훔쳐와 대신 실행함으로써 쓰레드 풀 전체의 부하 분산을 극대화한다.
- 논블로킹 인터리빙 : 실행 중인 코루틴이
suspend()를 만나면 해당 쓰레드는 해당 코루틴을 힙 메모리에 보존 처리한 뒤 큐로 돌아가 즉시 다음 대기 중인 코루틴을 실행한다.
This is a delicate API. The result of this method is a closeable resource with the associated native resources (threads or native workers).
- 컴퓨터 자원은 크게 두 종류로 나뉘는데 JVM이 관리하는 힙 메모리, OS가 관리하는 자원들(쓰레드, 네이티브 메모리, 파일 핸들, 소켓 등)이 있다.
- JVM의 경우 GC에 의해 수거가 되지만 OS가 관리하는 자원들은 GC의 관리 범위 밖이다.
new를 호출하는 순간 OS 레벨에서 쓰레드가 생성되고 네이티브 메모리가 점유된다. 이 시점부터 해당 자원은 명시적으로 반환되기 전까지 계속 점유된 상태를 유지하는데 이렇게 되면 두 가지 문제가 생긴다.- 하나는 GC에 맡기면 힙의 객체만 제거될 뿐, OS에 할당된 쓰레드와 메모리는 반환되지 않는다. 이것이 자원 누수이다.
- 다른 하나는
new를 반복 호출할 때마다 OS 자원 할당이 반복되는데, 이 작업 자체가 비용이 크다. 누적되면 메모리 고갈이나 시스템 성능 저하로 이어진다.- 그래서 이 객체는 한 번 생성해서 재사용하고, 더 이상 필요하지 않은 시점에 반드시
close()를 명시적으로 호출해서 OS 자원을 반환해야 한다.
-
Dispatchers.IO는 파일 입출력, 네트워크 요청, 데이터베이스 쿼리 실행 등과 같은 물리적 대기 시간을 수반하는 블로킹 I/O 작업을 처리하도록 설계된 멀티 쓰레드 기반의 코루틴 디스패처이다. - 초기상태(idle) : 애플리케이션 구동 초기에는 불필요하게 쓰레드를 많이 생성하지 않고 최소한의 워커 쓰레드만 유지한다.
- 수요 기반 생성 : 대량의 블로킹 I/O 작업을 가지는 코루틴들이
Dispatchers.IO로 들어오면 기존 쓰레드들이 모두 블로킹 상태에 빠져 큐의 작업을 처리할 수 없게 된다. 이 때, 디스패처는 최대 임계치에 도달하기 전까지 실시간으로 새로운 쓰레드를 풀에 추가 생성해 적재된 코루틴들을 할당한다. - 자원 회수 및 셧다운 : I/O 트래픽 스파이크가 지나가고 작업 대기열이 비워지면, 새로 생성되었던 쓰레드들이 가용(idle) 상태로 전환된다. 지정된 타임아웃(Keep-Alive Time)동안 추가 작업이 들어오지 않는 쓰레드들은 JVM 자원 반환을 위해 런타임에 의해 자동으로 파괴되어 메모리 점유율을 스스로 낮춘다.
- 기본적으로 사용할 수 있는 쓰레드의 수는 64와 JVM에서 사용할 수 있는 프로세서의 수 중 큰 값이다.
-
Dispatchers.Default는 CPU 바운드 작업(대규모 데이터 정렬, 복잡한 알고리즘 연산, JSON/XML 파싱, 이미지 및 동영상 인코딩, 암호화 가동)을 위한 디스패처이다. - 코루틴 빌더를 사용할 때 별도의 디스패처를 명시하지 않으면 이 디스패처가 기본값으로 자동 지정된다.
- 논리적 태그 제어 : 동일한 워커 쓰레드 풀 내부에서 현재 실행되는 코루틴이
Default규칙으로 들어왔는지,IO규칙으로 들어왔는지 논리적으로 카운팅하며 쓰레드 제한 수만 동적으로 변환한다. - 스위칭 최적화 : 비즈니스 로직 도중 대용량 가공 연산을 하다가 파일 저장으로 넘어가기 위해
withContext(Dispatchers.IO)를 호출하더라도 쓰레드가 바뀌는 하드웨어 스위칭 없이 동일한 쓰레드 내에서 객체의 컨텍스트만 바뀌어 실행되므로 내부 연산 효율이 극대화된다.
1. CoroutineScheduler
- Kotlin Coroutine 라이브러리는 JVM 환경에서 구동될 때, 내장 디스패처들을 위해 자체 설계한 고성능 쓰레드 풀인
CoroutineScheduler를 단 하나만 개설해 관리한다. - 공유 쓰레드 풀이 바로
CoroutineScheduler인스턴스를 말한다.Dispatchers.Default와Dispatchres.IO는 별개의 쓰레드 풀을 각각 생성하는 것이 아니라 단 하나의 스케줄러에서 쓰레드를 나누어 쓰는 구조인 것이다.
2. limitedParallelism
-
limitedParallelism은 기존에 존재하는 디스패처를 기반으로 동시 실행 가능한 코루틴의 최대 개수를 지정된 상한선으로 제한하는 역할을 수행한다. - 새로운 쓰레드 풀을 개설하는 비용을 지불하지 않는다. 원래 디스패처의 쓰레드 자원을 그대로 재사용하되, 제출된 코루틴들에 대해서만 논리적인 동시성 상한선을 적용한다.
- 메인 쓰레드에서의 작업을 위한 디스패처로 기본 코루틴 라이브러리에는 구현체가 없다.
- 해당 디스패처를 사용하려면 안드로이드 코루틴 라이브러리 추가가 필요하다.
-
Dispatchers.Main은 여러 쓰레드에서 코루틴을 실행하는 요청하든 코루틴을 작업 대기열에 먼저 적재한 후 Main Thread가 비었을 때, 코루틴을 보낸다.
-
Dispatchers.Main.immediate는 코루틴을 실행하는 코드가 메인 쓰레드에서 실행되고 있다면 작업 대기열에 적재될 필요없이 메인 쓰레드에서 그대로 실행될 수 있게 한다. - 만약 백그라운드 쓰레드에서 코루틴을 실행 요청하면 작업 대기열에 적재 후 메인 쓰레드로 보낸다.(=Dispatchers.Main과 같은 메커니즘)
- 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⭐
- 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 - 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]
- Reactive Programming - Reactive System & Reactive Programming
- Reactive Programming - Fundamentals of WebFlux and Reactor
- Reactive Programming - Core Operators in WebFlux Reactor
- Reactive Programming - Practical Patterns in WebFlux
- Reactive Programming - WebFlux Patterns with Spring Boot
- 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
- MySQL ‐ Solving Concurrency Problems using Database-Level Locking
- MySQL - Checking DB Metrics with SQL Queries
- MySQL - Data Modeling for Practical Service Development
- MySQL - Basic CRUD in MySQL
- MySQL - MySQL Horizontal Scaling
- 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
- MySQL - Multi Column Index
- MySQL - Covering Index
- MySQL - ORDER BY
- MySQL - INSERT
- MySQL - AUTO_INCREMENT_LOCK
- MySQL - MySQL LockType
- MySQL - DeadLock Case
- MySQL - NoOffset For Query Tuning
- 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 pub/sub & streams
- 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 - DeComposition Patterns
- MicroService Architecture - Service Communications Patterns
- 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 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
- 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
- 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 - Advanced Concept]
- [Nginx - Advanced Reverse Proxy]
- [Monitoring - Log Concept]
- [Monitoring - Log Level & Filter]
- [Monitoring - Logback]
- [Monitoring - Log Collection with ELK Stack]
- [Monitoring - Log Monitoring with Kibana]
- [Monitoring - Building a Monitoring System with Spring Boot Actuator]
- [Monitoring - Server Monitoring with Prometheus and Grafana with Discord Alerts]
- Test - Load Testing Fundamentals
- [Test - Diagnosing Bottlenecks via Load Testing]
- [Test - Performance Tuning: Resolving Bottlenecks]
- Test - JUnit5
- Test - Mockito
- Test - TestContainers
- Test - JMeter
- Test - Chaos Monkey
- [Test - ArchUnit]
- [Test - Unit Testing Essentials]
- [Test - TDD]
- [Test - Testing with Spring & JPA]
- Test - A Guide to Effective Mocking
- Test - Appendix: Tips for Better Testing
- (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]
- (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 - 클래스⭐