CS · Algorithm
느릴 때 무엇부터 의심하나 - 길 고르기 한 장
이 시리즈에서 낸 길들을 한 장에 놓는다. 그리고 실제로 코드가 느릴 때 무엇부터 의심해야 하는지, 그 순서가 왜 알고리즘부터가 아닌지.
문제를 어떻게 푸나 9편
CS · Algorithm
그리디 - 지금 제일 좋아 보이는 것
앞뒤 안 재고 매 순간 최선을 고르는 방법. 빠르고 코드도 짧은데, 언제 맞는지는 짐작이 아니라 증명으로만 알 수 있다.
문제를 어떻게 푸나 8편
CS · Algorithm
동적 계획법 - 한 번 푼 것은 다시 안 푼다
이름이 어렵지 하는 일은 하나다. 계산한 값을 적어두고 다시 묻지 않는 것. 대신 적어둘 자리를 내줘야 하고, 진짜 어려운 건 무엇을 적을지 정하는 일이다.
문제를 어떻게 푸나 7편
CS · Algorithm
분할 정복 - 쪼개서 풀고 합친다
쪼개면 왜 빨라지는가. 이득의 출처는 나누기가 아니라 합치기이고, 그 사실을 알면 n log n이 어디서 나오는지도 같이 보인다.
문제를 어떻게 푸나 6편
CS · Algorithm
재귀 - 자기를 부르는 함수
재귀는 어려운 기교가 아니라 '같은 모양의 더 작은 문제'를 그대로 코드로 옮긴 것이다. 필요한 건 둘뿐이고, 무너지는 자리도 정해져 있다.
문제를 어떻게 푸나 5편
CS · Algorithm
이진탐색 - 반을 버릴 수 있을 때
정렬해 두면 한 번 볼 때마다 절반을 통째로 버릴 수 있다. 그 조건이 무엇인지, 그리고 왜 이 짧은 코드가 그렇게 자주 틀리는지.
문제를 어떻게 푸나 4편
CS · Algorithm
정렬 - 줄을 세우는 값과 그 대가
정렬은 그 자체로 답인 경우보다 다른 일을 싸게 만들려고 하는 경우가 많다. 방식이 갈리는 지점과, 실무에서 진짜로 물어야 하는 안정성 이야기.
문제를 어떻게 푸나 3편
CS · Algorithm
완전탐색 - 다 해보는 것이 기준선이다
가장 먼저 떠올려야 할 방법은 전부 해보는 것이다. 무식해서가 아니라, 후보가 몇 개인지를 세어봐야 더 나은 방법이 필요한지 알 수 있어서다.
문제를 어떻게 푸나 2편
CS · Algorithm
알고리즘 - 답이 아니라 답에 이르는 길
알고리즘은 어려운 수학 이름이 아니라 답에 이르는 절차다. 목적지가 같아도 길은 여럿이고, 무엇을 골랐느냐가 걸리는 시간을 정한다.
문제를 어떻게 푸나 1편
CS · Data Structure
무엇을 언제 고르나 - 그릇 고르기 한 장
이 시리즈에서 연 그릇들을 한 장에 놓는다. 고르는 순서는 셋이고, 대부분의 문제는 그중 첫 질문에서 끝난다.
자료를 어떻게 담나 9편
CS · Data Structure
해시테이블 - 계산해서 자리를 정한다
찾지 않고 계산한다는 발상 하나로 O(1)이 나온다. 그 대신 충돌을 떠안고, 순서를 잃고, 가끔은 O(1)이 깨진다.
자료를 어떻게 담나 5편
CS · Data Structure
자료구조 - 담는 그릇이 속도를 정한다
자료구조는 빠른 것과 느린 것으로 나뉘지 않는다. 무엇을 싸게 하고 무엇을 비싸게 할지를 고르는 일이다. 그릇을 가르는 네 가지 질문부터 본다.
자료를 어떻게 담나 1편
Architecture · Consistency
나누면 정합성을 잃는다
두 서비스의 숫자가 다르다. CAP는 셋 중 둘을 고르라는 말이 아니고, 실무의 선택은 이분법이 아니라 눈금이다.
어떻게 나누나 6편
Architecture · Event-Driven
Pub/Sub과 이벤트 기반
일을 시키는 대신 일어난 일을 알린다. 듣는 쪽을 몰라도 되는 대신, 흐름이 코드에서 사라진다.
어떻게 나누나 5편
Architecture · Message Queue
메시지 큐 - 기다리지 않게 만든다
지금 안 해도 되는 일을 쌓아두고 나중에 처리한다. 대신 실패가 나중에 오고, 중복이 오고, 순서가 흔들린다.
어떻게 나누나 4편
Architecture · Microservices
서비스끼리 어떻게 부르나
동기 호출은 가장 단순한 답이지만, 한 곳의 느려짐이 전체로 번지는 통로이기도 하다. 타임아웃·재시도·차단기로 그 통로를 좁힌다.
어떻게 나누나 3편
Architecture · Microservices
나누면 무엇이 달라지나
배포·장애·확장 단위를 갈라놓는 대신 네트워크가 끼어든다. 얻는 것과 새로 지는 비용을 나란히 놓는다.
어떻게 나누나 2편
Architecture · Monolith
모놀리스가 먼저다
한 덩어리로 만드는 건 아직 못 나눈 상태가 아니라 정상적인 출발점이다. 무엇이 쉬워지고, 언제부터 아파지는가.
어떻게 나누나 1편
Load Balancer · Scaling
로드 밸런서 - 앞에서 나눠준다
서버를 여러 대 두면 누가 어디로 보낼지 정해야 한다. 분배 알고리즘보다 중요한 건 어느 층에서 보는가, 죽은 서버를 어떻게 아는가, TLS를 어디서 푸는가다.
부하를 견디는 법 5편
Scaling · Architecture
수직이냐 수평이냐
서버를 키우는 것과 늘리는 것은 난이도가 다르다. 늘리는 쪽이 어려운 이유는 서버가 아니라 서버가 들고 있는 상태에 있다.
부하를 견디는 법 4편
Performance · Scaling
무엇이 먼저 무너지나
부하가 늘면 전부가 고르게 느려지는 게 아니라 가장 좁은 한 곳이 먼저 막힌다. 도구를 고르기 전에 그 자리를 찾는 이야기.
부하를 견디는 법 1편
OAuth2 · Authorization
OAuth 2.0 - 열쇠를 주지 않고 권한만 넘긴다
구글로 로그인이 내 비밀번호를 받지 않는 이유. Authorization Code + PKCE 흐름 하나를 끝까지 따라간다.
인증과 인가 6편
Authentication · Authorization
인증과 인가는 다른 질문이다
로그인은 됐는데 403이 뜬다. 누구인가와 무엇을 할 수 있나는 서로 다른 질문이고, 실패했을 때 답도 다르다.
인증과 인가 1편
API · Versioning
버저닝과 하위 호환
v2를 냈는데 v1을 못 내리는 상황을 어떻게 피하나. 깨지 않고 바꾸는 방법이 먼저이고, 버전을 가르는 건 그다음이다.
API 설계 8편
API · gRPC
gRPC - 같은 양식을 미리 나눠 갖는다
REST도 JSON도 브라우저가 읽는다는 전제 위의 선택이었다. 그 전제가 없는 서버 사이 호출에서 gRPC가 무엇을 바꾸고 무엇을 내주는지 본다.
API 설계 7편
API · JSON
JSON - 왜 이게 표준이 됐나
타입이 여섯 개뿐인 형식이 어떻게 API의 기본이 됐나. 큰 정수·날짜·null이라는 세 함정과 스키마 없음의 대가.
API 설계 5편
API · REST
Endpoint 설계
같은 목록을 주는 URL이 여럿이 되지 않게 하는 법. 컬렉션과 단건, 중첩 기준, 필터·정렬·페이징 파라미터와 목록 응답 모양을 정한다.
API 설계 3편
API · Design
API는 약속이다
내부 코드는 언제든 고치지만 공개한 API는 남이 이미 그 모양에 맞춰 코드를 짜뒀다. API를 계약으로 보는 관점을 잡는다.
API 설계 1편
HTTP · Web
상태를 안 갖는다는 것
서버는 방금 로그인한 사람도 다음 요청에서 못 알아본다. 그 불편을 일부러 감수한 이유와, 그래서 상태를 어디에 두게 됐는지.
HTTP는 어떻게 오가나 2편
HTTP · Web
요청과 응답 - 한 번의 왕복에 무엇이 오가나
주소창에 한 줄 쳤을 때 실제로 오가는 건 글자 몇 줄이다. 그 글자가 어떻게 생겼고 어디를 지나는지 본다.
HTTP는 어떻게 오가나 1편
Connection Pooling · Database
Connection Pooling
스레드가 DB를 부르려면 연결이 필요한데, 연결은 만드는 것도 무제한도 비싸다. 미리 열어 재사용하되, 연결은 DB가 상한을 정하는 자원이다.
동시성과 자원 풀링 3편
Thread Pool · Concurrency
Thread Pool
스레드는 만드는 것도 무제한도 비싸다. 미리 만들어 재사용하고, 그 개수로 동시 실행을 제한하는 것 - Thread Pool.
동시성과 자원 풀링 2편
Concurrency · Thread
Concurrency
서버는 요청을 동시에 처리해야 한다. 그런데 여러 스레드가 같은 것을 건드리면 조용히 어긋난다 - 경쟁 상태와 그걸 막는 법.
동시성과 자원 풀링 1편
Pagination · Database
Pagination
100만 건을 한 번에 줄 순 없다. 나눠 주는 두 방법 - offset과 cursor, 그리고 왜 offset이 뒤로 갈수록 느려지고 밀리는가.
Idempotency · HTTP
Idempotency
네트워크는 못 믿는다. 같은 요청이 두 번 와도 한 번 한 것과 같게 - 멱등성과, POST를 멱등하게 만드는 Idempotency Key, 그리고 그 키를 누가 어떻게 만드는가.
JPA · ORM
Persistence Context
save()를 안 불렀는데 UPDATE가 나간다. JPA가 엔티티를 관리하는 공간, 영속성 컨텍스트로 그 수수께끼를 푼다.
ORM · JPA
ORM
자바 객체와 DB 테이블 사이를 손으로 나르지 않는다. JPA로 개념을 잡고, ORM이 만드는 SQL까지 본다.
Middleware · Spring
Middleware
핸들러마다 반복되는 공통 처리를 요청과 응답 사이 한 줄로 세운다. Spring의 Filter로 개념을 잡는다.
Active Record · Design Pattern
Active Record
객체가 자기를 저장할 줄 안다. Repository와 정반대 선택이고, 틀린 선택이 아니라 다른 선택이다.
Aggregate · Design Pattern
Aggregate
어디까지가 한 덩어리인가. 함께 지켜야 할 것을 묶고, 그 경계를 트랜잭션과 저장소가 따라간다.
도메인 모델링 3편
Value Object · Design Pattern
Entity와 Value Object
무엇으로 같음을 판단하나. 식별자로 같은 것과 값이 같으면 같은 것, 그 둘을 갈라 쓰는 이유.
도메인 모델링 2편
Domain Model · Design Pattern
로직을 어디에 둘 것인가
업무 규칙을 절차에 늘어놓을 것인가, 객체에 넣을 것인가. 트랜잭션 스크립트와 도메인 모델, 그리고 둘을 가르는 기준.
도메인 모델링 1편
Unit of Work · Design Pattern
Unit of Work
저장할 때마다 DB에 쓰면 업무의 반쪽만 남을 수 있다. 변경을 한 단위로 모았다가 한 번에 반영하는 패턴.
DTO · Design Pattern
DTO
엔티티를 그대로 내보내면 DB 구조가 곧 API 계약이 된다. 계층을 건너는 전용 그릇을 따로 두는 패턴.
Service Layer · Design Pattern
Service Layer
컨트롤러에 업무 절차가 쌓인다. 절차를 서비스 계층으로 옮겨, 입구가 여럿이어도 규칙은 한 곳에 있게 만드는 패턴.
Repository Pattern · Design Pattern
Repository Pattern
비즈니스 로직에서 DB 코드를 걷어낸다. 데이터 접근을 인터페이스 뒤로 숨겨, 구현을 갈아끼워도 로직은 그대로 두는 패턴.
GoF · Behavioral
Interpreter
작은 언어의 문법을 객체 트리로 표현하고 그 트리를 재귀로 평가하는, 드물지만 발상이 또렷한 행위 패턴.
행동 패턴 11편
GoF · Behavioral
Visitor
객체 구조는 그대로 두고, 그 위를 도는 새 연산을 바깥의 방문자로 추가하는 행위 패턴.
행동 패턴 10편
GoF · Behavioral
Memento
객체의 내부 상태를 캡슐화를 깨지 않고 스냅샷으로 저장해뒀다가 되돌리는 행위 패턴.
행동 패턴 9편
GoF · Behavioral
Mediator
객체들이 서로 직접 참조하며 얽히지 않도록, 중재자를 하나 세워 소통을 그리로 몰아주는 행위 패턴.
행동 패턴 8편
GoF · Behavioral
Iterator
컬렉션의 속을 열어 보지 않고 원소를 순서대로 훑을 때. 순회를 캡슐화해 내부 구조와 순회 코드를 떼어 놓는 행위 패턴.
행동 패턴 7편
GoF · Behavioral
Chain of Responsibility
누가 처리할지 미리 못 정할 때. 요청을 처리자들의 사슬에 흘려보내 처리 가능한 자가 맡게 하는 행위 패턴.
행동 패턴 6편
GoF · Behavioral
State
상태에 따라 행동이 갈릴 때. 상태를 객체로 만들어 거대한 조건문을 다형성으로 바꾸는 행위 패턴.
행동 패턴 5편
GoF · Behavioral
Template Method
여러 흐름이 큰 틀은 같은데 한 단계만 다를 때. 뼈대를 상위가 고정하고 달라지는 구멍만 하위가 채우는 행위 패턴.
행동 패턴 4편
GoF · Behavioral
Command
요청을 나중에 실행하거나 되돌리거나 기록하고 싶을 때. 요청 자체를 객체로 캡슐화하는 행위 패턴.
행동 패턴 3편
GoF · Behavioral
Observer
상태가 바뀔 때마다 관심 있는 것들을 일일이 불러야 할 때. 구독한 여럿에게 자동으로 통지하는 행위 패턴.
행동 패턴 2편
GoF · Behavioral
Strategy
기준이 늘 때마다 if/switch를 고쳐야 할 때. 알고리즘을 인터페이스로 빼 런타임에 갈아끼우는 행위 패턴.
행동 패턴 1편
GoF · Structural
Flyweight
같은 객체를 수백만 개 만들어 메모리가 터질 때. 공유 가능한 부분을 뽑아 하나만 만들어 나눠 쓰는 구조 패턴.
구조 패턴 7편
GoF · Structural
Bridge
두 축이 곱해지며 클래스가 폭발할 때. '무엇'과 '어떻게'를 두 계층으로 갈라 다리로 잇고, 각자 독립해 자라게 하는 구조 패턴.
구조 패턴 6편
GoF · Structural
Composite
파일과 폴더처럼 개별과 묶음이 섞인 트리를, 클라이언트가 구분 없이 똑같이 다루게 하는 구조 패턴.
구조 패턴 5편
GoF · Structural
Facade
하나 하려고 여러 개를 순서대로 불러야 할 때. 복잡한 하위 시스템 앞에 단순한 창구 하나를 세우는 구조 패턴.
구조 패턴 4편
GoF · Structural
Proxy
진짜 객체 앞에 대리인을 세워 접근을 제어한다. 지연 로딩·권한 검사·캐싱을 진짜를 건드리지 않고 끼우는 구조 패턴.
구조 패턴 3편
GoF · Structural
Decorator
상속으로 조합을 만들면 클래스가 폭발한다. 같은 인터페이스로 감싸 기능을 덧입히고, 여러 겹으로 쌓는 구조 패턴.
구조 패턴 2편
GoF · Structural
Adapter
내 코드가 기대하는 인터페이스와 남의 코드가 주는 인터페이스가 안 맞을 때. 사이에 번역기를 끼워 붙게 만드는 구조 패턴.
구조 패턴 1편
GoF · Creational
Prototype
처음부터 만들지 않고, 이미 있는 객체를 복제해 새로 만든다. 얕은 복사의 함정과 clone()의 문제까지 다루는 마지막 생성 패턴.
생성 패턴 5편
GoF · Creational
Builder
인자가 많고 대부분 선택인 객체를, 생성자 폭발 없이 단계별로 조립한다. 읽히고, 필수를 강제하고, 끝에서 불변으로 굳히는 생성 패턴.
생성 패턴 4편
GoF · Creational
Abstract Factory
따로 만들면 짝이 어긋난다. 서로 맞아야 하는 관련 객체들을 한 세트로 만들어, 섞이지 않게 보장하는 생성 패턴.
생성 패턴 3편
GoF · Creational
Factory Method
객체를 만드는 코드가 구체 타입에 박히지 않게. 무엇을 만들지 하위 클래스가 결정하도록 생성을 메서드로 빼는 생성 패턴.
생성 패턴 2편
GoF · Creational
Singleton
앱 전체에 인스턴스가 딱 하나만 있어야 할 때. 만드는 법은 간단하지만, 멀티스레드와 전역 상태라는 두 함정이 따라오는 생성 패턴.
생성 패턴 1편
SOLID · DIP
Dependency Inversion Principle
고수준 정책이 저수준 구현에 매달리지 않게. 둘 사이에 추상화를 두어 의존의 방향을 뒤집는 마지막 SOLID 원칙.
SOLID 원칙 5편
SOLID · ISP
Interface Segregation Principle
쓰지도 않는 메서드에 의존하게 만들지 마라. 뚱뚱한 인터페이스를 역할별로 쪼개는 네 번째 SOLID 원칙.
SOLID 원칙 4편
SOLID · LSP
Liskov Substitution Principle
자식은 부모 자리에 넣어도 약속을 깨면 안 된다. 상속은 구조가 아니라 계약을 물려받는 것 - 세 번째 SOLID 원칙.
SOLID 원칙 3편
SOLID · OCP
Open/Closed Principle
새 동작은 추가하되 기존 코드는 고치지 않는다. 타입이 늘 때마다 if-else를 여는 대신, 다형성으로 확장점을 두는 두 번째 SOLID 원칙.
SOLID 원칙 2편
SOLID · SRP
Single Responsibility Principle
클래스가 바뀌는 이유는 하나여야 한다. '일'이 아니라 '이유'로 나누는 첫 번째 SOLID 원칙.
SOLID 원칙 1편
Database · NoSQL
NoSQL - 조립을 언제 하느냐의 문제다
SQL을 안 쓴다는 뜻이 아니다. 사실을 쪼개 두고 읽을 때 붙일 것인가, 읽을 모양대로 미리 붙여 둘 것인가. 그 하나에서 이득도 대가도 전부 나온다.
데이터베이스 공통 개념 13편