시스템 디자인
비유로 시작하기
비유로 시작하기
Tomcat 스레드 200개가 모두 외부 API 응답을 기다리며 블로킹되어 있다. 새 요청은 큐에서 대기하다 타임아웃이 난다. 이 상황에서 서버를 늘리는 것보다 더 근본적인 해법이 WebFlux다.
1. 선언적 트랜잭션 (@Transactional)
마이크로서비스 환경에서 주문 하나가 실패했다. Order Service → Payment Service → Inventory Service → Notification Service를 거치는데, 어디서 얼마나 걸렸는지 알 수가 없다. 분산 추적(Distributed Tracing)은...
JWT 토큰이 없는 요청이 /api/admin에 들어왔는데 그냥 통과됐다. 필터 순서가 잘못됐거나 필터 자체가 누락된 것이다. Spring Security 아키텍처를 모르면 어디서 막혀야 하는지조차 알 수 없다.
마이크로서비스 환경에서 외부 서비스 호출은 실패할 수 있다. 한 서비스의 장애가 연쇄적으로 전파돼 전체 시스템이 다운되는 “연쇄 장애(Cascading Failure)”가 가장 위험하다. Resilience4j는 이를 방어하는 경량 내결함성(Fault Tolerance) 라이브러리...
비유로 먼저 이해하기: MVC는 레스토랑과 같다. 손님 요청을 웨이터(Controller)가 받아 주방(Service)에 전달하고, 셰프가 요리(비즈니스 로직)를 완성하면 접시(View)에 담아 손님에게 돌려준다. 손님은 주방이 어떻게 돌아가는지 알 필요가 없다.
새벽 2시에 운영 장애가 났다. 로그를 보니 에러와 정상 로그가 뒤섞여 어느 요청에서 터진 건지 찾을 수가 없다. MDC를 몰랐다면 이 상황에서 로그 전체를 시간순으로 읽어내려가야 한다.
신입 때 이런 경험이 있을 것이다. 서비스 클래스 안에서 new RateDiscountPolicy()를 직접 써뒀는데, 기획이 바뀌어서 FixDiscountPolicy로 교체해야 하는 순간. 수십 개 파일을 열어 new를 바꿔야 했다. IoC와 DI는 이 문제를 해결하기 위해 태어...
마이크로서비스 환경에서 서비스들은 동적으로 생성·삭제·이동된다. IP와 포트를 하드코딩하면 배포할 때마다 설정을 바꿔야 한다. Spring Cloud Eureka는 이 문제를 해결하는 Service Discovery 솔루션이다. 서비스가 스스로 자신의 위치를 등록하고, 호출자는 이...
100개의 마이크로서비스에 DB 비밀번호를 바꿔야 한다면? 각 서비스마다 설정 파일을 수정하고 재배포하면 수십 분이 걸린다. Spring Cloud Config는 모든 서비스의 설정을 한 곳에서 관리하고, 재배포 없이 런타임에 반영하는 중앙 집중 설정 관리 솔루션이다.
Spring Cloud Gateway는 Spring 생태계의 API Gateway 솔루션이다. Netflix Zuul(블로킹)의 후계자로, Spring WebFlux(Reactor/Netty) 기반의 비동기 논블로킹 방식으로 동작한다. 라우팅, 필터링, 로드밸런싱, 인증, Rate...
Spring의 @Async는 메서드를 별도 스레드에서 비동기로 실행하게 만드는 애노테이션이다. 단순히 붙이면 동작하는 것처럼 보이지만, 내부 동작과 주의사항을 모르면 예외가 무시되거나 MDC 컨텍스트가 사라지는 등 운영 장애로 이어질 수 있다.
1. AOP란? (관심사 분리)
Java/Spring 생태계에는 HTTP 클라이언트 라이브러리가 매우 다양합니다. RestTemplate, WebClient, RestClient, OpenFeign, Retrofit, Java HttpClient, OkHttp까지 선택지가 많아 어떤 것을 써야 할지 혼란스러울 수...
1. Rate Limiting이란?
마이크로서비스 아키텍처에서는 단일 비즈니스 작업이 여러 서비스에 걸쳐 실행된다. 각 서비스는 독립적인 데이터베이스를 가지므로 전통적인 ACID 트랜잭션을 사용할 수 없다. 분산 트랜잭션은 이 문제를 해결하기 위한 다양한 패턴을 다룬다.
Tomcat과 Netty는 Java 생태계에서 가장 널리 사용되는 두 서버 엔진이다. 둘 다 네트워크 I/O를 처리하지만 설계 철학과 스레드 모델이 근본적으로 다르다. Spring MVC와 Spring WebFlux의 기반이 되는 두 엔진을 이해하면 성능 문제를 더 잘 진단하고 올...
동기(Synchronous), 비동기(Asynchronous), 블로킹(Blocking), 논블로킹(Non-blocking)은 I/O와 동시성 프로그래밍에서 자주 혼용되는 개념이다. 이 네 가지는 서로 독립된 두 축이며, 조합에 따라 4가지 모드가 만들어진다.
웹 서비스 앞에는 항상 관문이 필요하다. 수만 개의 동시 접속을 처리하고, 뒷단 서버들에 트래픽을 나눠주고, SSL을 종료하고, 정적 파일을 직접 서빙하는 역할이다. Nginx는 이 모든 것을 단 하나의 프로세스 모델로 처리한다.
로그인 세션이 24시간 뒤 자동 만료되지 않는다면 어떻게 될까? 사용자가 로그아웃을 깜빡하면 그 세션은 영원히 메모리에 남아있다. 수백만 명이 사용하는 서비스라면 Redis 메모리가 서서히 고갈되어 결국 장애로 이어진다. TTL은 이 문제를 코드 한 줄로 해결한다.
새벽 2시, 서비스가 갑자기 다운됐다는 알림이 온다. Redis 마스터 서버의 디스크가 고장났다. 데이터는? 서비스 재개까지 걸리는 시간은? 복제 없이 단일 Redis만 운영 중이었다면 모든 캐시 데이터가 날아가고 서비스는 멈춘다. 복제(Replication)는 바로 이런 상황에 ...
비유로 시작하기
재고 감소 로직을 생각해보자. GET으로 재고를 읽고, 0보다 크면 DECR로 줄인다. 두 명령 사이에 다른 요청이 끼어들면 재고가 -1이 되는 순간이 생긴다. 이 틈을 없애는 것이 Lua 스크립트다. 두 명령을 하나의 원자적 단위로 묶어 Redis 서버 안에서 실행한다.
쿠팡 타임세일, 1초에 10만 명이 몰린다. 재고는 딱 1개. 10만 명 중 정확히 1명만 구매에 성공해야 한다. 서버는 10대. 각 서버가 동시에 “재고 있음”을 확인하고 결제를 진행한다면 어떻게 될까?
블랙프라이데이 자정, 한정판 운동화 1켤레에 5만 명이 동시 접속한다. 서버 20대가 동시에 “재고 1개 남음”을 확인하고 저마다 결제를 진행한다면? 한 사람만 사야 할 물건이 20명에게 팔린다. 분산 락은 “지금 이 자원은 내가 쓰고 있으니 기다려라”는 신호를 20대 서버 전체에...
실시간 랭킹을 구현해야 한다면? MySQL로 매 요청마다 ORDER BY score DESC를 돌리면 수천 명이 동시 접속할 때 DB가 버티지 못한다. Redis Sorted Set 하나로 수백만 명의 점수를 실시간으로 정렬해 1ms 안에 응답할 수 있다. Redis가 단순 캐시 ...
개발 환경에서 잘 돌아가던 Redis가 프로덕션에서 새벽에 죽었다. 마스터 한 대뿐이었고, 자동 복구 수단도 없었다. 엔지니어가 잠에서 깨 수동으로 레플리카를 마스터로 승격시키기까지 20분이 걸렸다. 센티넬이 있었다면 30초 안에 자동으로 해결됐을 문제다.
OSI 7계층 모델이란?
비유로 시작하기
DNS란?
비유로 시작하기
로컬 캐시란?
캐시 교체(Eviction)란?
브로커 한 대가 갑자기 죽었다. 그 브로커에만 있던 메시지는 영영 사라지는가? Kafka는 처음부터 이 상황을 가정하고 설계됐다. 파티션을 여러 브로커에 복제해두고, 리더가 죽으면 팔로워 중 하나가 즉시 리더를 이어받는다.
kafkaTemplate.send("orders", event) 한 줄이면 메시지가 전송된다고 생각하기 쉽다. 하지만 이 한 줄 뒤에는 직렬화, 파티셔닝, 배치 누적, 압축, 재시도, ACK 확인까지 수십 가지 동작이 숨어있다. acks 설정 하나 잘못 건드리면 메시지가 유실되거나...
주문이 DB에 저장됐는데 Kafka 발행이 실패했다. 결제 서비스는 주문을 모른다. 반대로 Kafka 발행은 됐는데 DB 롤백이 됐다. 결제 서비스는 존재하지 않는 주문을 처리한다. 분산 트랜잭션 없이 이 문제를 해결하는 것이 Outbox 패턴이다.
초당 100만 건의 주문 이벤트가 쏟아지는 쇼핑몰을 상상해보자. producer.send(record)를 호출할 때마다 네트워크 요청이 한 번씩 나간다면 시스템은 버티지 못한다. Kafka Producer는 내부적으로 메시지를 배치로 모으고, 압축하고, 비동기로 전송하며 이 문제를...
서비스가 성장하면서 주문, 결제, 배달, 통계, 알림 시스템이 서로 직접 API를 호출한다. 하나가 느려지면 전체가 느려지고, 하나가 죽으면 연쇄 장애가 난다. Kafka는 이 결합을 끊는다.
들어가며
주문 이벤트 처리 속도가 발행 속도를 따라가지 못한다. 컨슈머 인스턴스를 한 대 더 띄우면 해결될까? 파티션이 3개인데 컨슈머가 이미 3개라면 4번째 컨슈머는 아무것도 하지 않고 대기만 한다. 컨슈머 그룹과 파티션 할당 원리를 모르면 장비를 늘려도 성능이 나아지지 않는다.
Kafka가 초당 수백만 메시지를 처리하면서도 디스크 기반임에도 빠른 이유는 무엇일까? 비결은 브로커 내부의 로그 세그먼트 구조, 페이지 캐시 활용, 제로카피 전송에 있다. 브로커 내부를 이해하면 성능 튜닝 방향이 보인다.
팀 목록을 조회하는 API가 개발 환경에서는 멀쩡하다가 운영에서 수백 ms가 걸린다면, 열에 아홉은 N+1 문제다. 데이터가 적을 때는 보이지 않다가 데이터가 쌓이면서 DB 쿼리가 폭발적으로 늘어나는 것이 이 문제의 특징이다.
Spring Boot로 애플리케이션을 만들다 보면 SQL 한 줄 짜지 않았는데 쿼리가 수십 번 나가거나, 분명히 값을 바꿨는데 DB에 반영이 안 되는 경험을 하게 된다. 이런 문제의 뿌리는 대부분 JPA 내부 동작을 모르는 데 있다.
Java는 기본형(primitive type)과 참조형(reference type)이라는 두 가지 타입 체계를 가집니다. 이 둘 사이의 간극을 메우는 것이 래퍼 클래스(Wrapper Class)이며, 오토박싱(Auto-boxing)은 이 변환을 자동화한 Java 5의 핵심 기능입니...
비유로 먼저 이해하기: 가상 스레드는 비행기 좌석과 같다. 비행기 엔진(OS 스레드)은 몇 개 없지만 좌석(가상 스레드)은 수백 개다. 승객(요청)이 좌석에 앉아 있는 동안 엔진이 교대로 각 좌석을 처리한다. OS 스레드 하나가 수천 개의 가상 스레드를 번갈아 실행하는 것도 ...
Java의 멀티스레드 환경에서 스레드 간 공유 없이 각 스레드마다 독립적인 변수를 유지해야 할 때 ThreadLocal을 사용합니다. 이 글에서는 ThreadLocal의 내부 구조부터 메모리 누수 방지, 실무 활용 패턴까지 깊이 있게 다룹니다.
주문 처리와 이메일 발송을 순차적으로 하면 사용자는 이메일이 발송될 때까지 기다려야 한다. 스레드를 분리하면 주문 처리 응답을 즉시 주고 이메일은 백그라운드에서 보낼 수 있다. 하지만 스레드를 잘못 다루면 데이터가 꼬인다.
Java에서 String은 가장 많이 사용되는 클래스이면서, 동시에 가장 많은 오해가 있는 클래스입니다. 불변성(Immutability), String Pool, 성능 최적화, 그리고 Java 11~17에서 추가된 메서드까지 완전히 정리합니다.
Java 8의 Stream API는 컬렉션 데이터를 선언적으로 처리하는 강력한 도구입니다. 단순히 for 루프를 대체하는 것이 아니라, 지연 연산(lazy evaluation), 병렬 처리, 함수 합성을 통해 데이터 파이프라인을 구성하는 새로운 패러다임입니다.
리플렉션은 런타임에 클래스 구조를 분석하고 동적으로 조작하는 강력한 기법입니다. Spring, JPA, Jackson, JUnit이 모두 이를 기반으로 동작합니다. 원리부터 실무 활용까지 상세히 정리합니다.
Java의 모든 클래스는 명시적으로 상속을 선언하지 않아도 java.lang.Object를 최상위 부모로 가집니다. Object 클래스가 제공하는 메서드들은 Java 객체 시스템의 근간을 이루며, 이를 올바르게 이해하고 오버라이딩하는 것은 Java 개발의 핵심입니다.
Java는 소켓부터 HTTP 클라이언트까지 풍부한 네트워크 API를 제공합니다. TCP/UDP 저수준 통신부터 NIO 기반 고성능 서버까지 전체를 상세히 정리합니다.
Java는 클래스 안에 클래스를 선언할 수 있습니다. 이를 중첩 클래스(Nested Class)라고 하며, 종류에 따라 동작 방식과 사용 목적이 크게 다릅니다. 잘못 사용하면 메모리 누수의 원인이 되기도 하므로, 각각의 특성을 정확히 이해하는 것이 중요합니다.
Java 8에서 도입된 람다(Lambda) 표현식은 Java를 함수형 프로그래밍 언어로 진화시킨 핵심 기능입니다. 단순한 문법 설탕(syntactic sugar)처럼 보이지만, 그 내부 동작 원리부터 실전 활용까지 깊이 있게 이해해야 제대로 쓸 수 있습니다.
Java의 I/O 시스템은 데이터를 읽고 쓰는 모든 작업의 근간입니다. 고전적인 java.io부터 고성능 NIO, 편리한 NIO.2까지 전체 체계를 상세히 정리합니다.
Java 제네릭(Generics)은 클래스, 인터페이스, 메서드를 정의할 때 타입을 파라미터로 사용할 수 있게 해주는 기능입니다. Java 5(2004)에 도입되어 타입 안전성과 코드 재사용성을 동시에 달성하는 핵심 언어 기능으로 자리잡았습니다.
API 응답이 평소엔 10ms인데 가끔 500ms로 튄다. GC 로그를 보면 Stop-the-World가 발생한 시점과 정확히 일치한다. GC 동작 원리를 모르면 튜닝 방향을 잡을 수 없다.
Java는 본래 순수 객체지향 언어지만, Java 8부터 람다와 Stream API를 통해 함수형 프로그래밍 패러다임을 적극 수용했습니다. 함수형 프로그래밍의 핵심 개념을 이해하고 Java에서 어떻게 적용하는지 깊이 있게 살펴봅니다.
Java의 예외 처리는 단순한 try-catch 문법을 넘어, 시스템의 견고성과 유지보수성을 결정하는 설계 영역입니다. 예외 계층 구조부터 커스텀 예외 설계, Spring의 예외 전략까지 완전히 정리합니다.
Java의 enum은 단순히 상수 집합을 표현하는 것을 넘어, 필드·메서드·추상 메서드를 가질 수 있는 완전한 클래스입니다. 상수 대신 Enum을 사용해야 하는 이유부터 EnumSet, EnumMap, 싱글톤 패턴까지 완전히 정리합니다.
Java 8에서 도입된 java.time 패키지는 기존 Date와 Calendar의 고질적인 문제를 해결하고, 불변(Immutable) 설계와 직관적인 API를 제공합니다. 현대 Java 개발에서 날짜·시간 처리의 표준입니다.
상품 정보, 재고, 가격을 각각 다른 API에서 가져와야 한다. 순차적으로 호출하면 300ms + 200ms + 150ms = 650ms가 걸린다. 병렬로 처리하면 300ms면 된다. CompletableFuture가 이 병렬 조합을 깔끔하게 표현해준다.
ArrayList를 써야 할지 LinkedList를 써야 할지, HashMap과 TreeMap의 차이는 무엇인지 — 컬렉션 선택 하나가 성능을 10배 이상 바꿀 수 있다. 내부 구조를 알아야 올바른 선택이 가능하다.
비유로 시작하기
비유로 시작하기
비유로 시작하기
비유로 시작하기
비유로 시작하기
단일 MySQL 서버가 감당할 수 있는 쓰기 TPS 한계에 도달했다. 읽기는 레플리카로 분산했지만 쓰기 병목은 해결되지 않는다. 수직 확장(더 좋은 서버)도 한계가 왔다. 다음 선택지가 샤딩이다.
파티셔닝이란?
인덱스를 분명히 걸었는데 EXPLAIN을 보니 Full Table Scan이다. 옵티마이저가 인덱스보다 풀스캔이 더 빠르다고 판단한 것이다. 왜 그런 선택을 했는지 이해하지 못하면 힌트를 줄 수도, 통계를 갱신할 수도 없다.
비유로 시작하기
비유로 시작하기
재고가 1개 남은 상품에 동시 주문이 100건 들어왔다. 락 없이 처리하면 재고가 -99가 될 수 있다. 어떤 락을 어떤 상황에 써야 하는지 모르면 장애가 나서야 알게 된다.
운영 중인 서비스에서 갑자기 특정 쿼리가 10배 느려졌다. 코드는 그대로인데 왜일까? 통계가 오래되어 옵티마이저가 잘못된 실행 계획을 선택했거나, Buffer Pool이 가득 차 디스크 I/O가 폭발한 것일 수 있다. DB 내부 동작 원리를 모르면 이런 상황에서 무엇을 봐야 할지조...
회원 테이블에 1,000만 건이 쌓였다. 특정 이메일 하나를 조회하는 쿼리가 5초 걸린다. 인덱스 하나 추가했더니 3ms로 떨어졌다. 왜 이런 차이가 나는지, 그리고 어떤 컬럼에 걸어야 하는지를 이 글에서 다룬다.
DB 커넥션을 맺는 것은 생각보다 비싸다. TCP 연결, 인증, 세션 초기화까지 수십~수백 밀리초가 걸린다. 매 요청마다 새 커넥션을 만들면 DB가 이 비용만으로 과부하에 걸린다. 커넥션 풀은 미리 만들어 놓은 커넥션을 재사용해 이 비용을 제거한다.
1. 개요
비유로 시작하기
비유로 시작하기
비유로 시작하기
캐싱이란?
처음에는 작은 쇼핑몰 하나였다. 코드 한 곳에서 회원, 주문, 결제, 배송을 모두 처리했다. 팀이 커지고 기능이 늘면서 빌드는 30분, 배포는 하루에 한 번, 한 줄 수정이 전체 서비스를 다운시킨다. MSA는 이 문제를 해결하기 위해 시스템을 독립적으로 배포 가능한 작은 서비스들로...
비유로 시작하기
비유로 시작하기
전통적인 시스템에서 서비스들은 서로를 직접 호출한다. Order Service가 Payment, Inventory, Notification을 직접 호출하면, 하나라도 다운되면 주문 자체가 실패한다. 이벤트 기반 아키텍처(EDA)는 서비스들이 이벤트를 통해 간접적으로 소통해 결합도를...
비유로 시작하기
AI 생태계는 2023년 이후 폭발적으로 성장했다. 개발자 워크플로우에 통합되는 코딩 어시스턴트부터 범용 챗봇, 이미지 생성, 인프라 레이어까지 각 영역별 주요 도구를 정리한다.
AI가 코드를 생성하는 시대가 되면서 개발자의 역할이 바뀌고 있다. AI를 단순히 사용하는 것을 넘어, AI가 올바르게 작동하도록 환경과 제약을 설계하는 하네스 엔지니어링(Harness Engineering)이 새로운 핵심 역량으로 부상했다.
제어의 역전 (Inversion Of Control)
의존관계 주입(DI)
싱글톤 레지스트리와 오브젝트 스코프
🔗 직렬화 프록시 패턴을 이용하면 Serialziable 구현의 위험을 크게 줄여줄 수 있다.
🔗 아이템 3에서 싱글턴 패턴을 설명하며 다음 예를 보여주었다.
🔗 아이템 50에서는 불변인 날짜 클래스를 만드는 데 가변인 Date 필드를 이용했다.
🔗 개발 일정에 쫓기는 상황에서는 API 설계에 노력을 집중하는 편이 나을 것이다.
🔗 Serializable을 구현하면 릴리즈 한 뒤에는 수정하기 어렵다.
🔗 자바 직렬화의 위험성
🔗 정확성이나 성능이 쓰레드 스케줄러에 따라 달라지는 프로그램이라면 다른 플랫폼에 이식하기 어렵다.
🔗 지연 초기화(Lazy Initialization)는 필드의 초기화 시점을 그 값이 처음 필요할 때까지 늦추는 기법이다.
🔗 한 메서드를 여러 스레드가 동시에 호출할 때 그 메서드가 어떻게 동작하느냐는 해당 클래스와 이를 사용하는 클라이언트 사이의 중요한 계약과 같다.
🔗 wait와 notify는 올바르게 사용하기가 아주 까다로우니 고수준 동시성 유릴리티를 사용하자.
🔗 java.util.concurrent 패키지는 실행자 프레임워크(Executor Framework)라고 하는 인터페이스 기반의 유연한 태스트 실행 기능을 담고 있다.
🔗 응답 불가와 안전 실패를 피하려면 동기화 메서드나 동기화 블록 안에서는 제어를 절대로 클라이언트에 양도하면 안 된다.
🔗 synchronized 키워드는 해당 메서드나 블록을 한번에 한 스레드씩 수행하도록 보장한다.
🔗 테트로미노 14500번 문제
🔗 리모컨 1107번 문제
🔗 일곱 난장이 2309번 문제
🔗 연속합2 13398번 문제
🔗 사탕 게임 3085번 문제
🔗 가장 긴 바이토닉 부분 수열 11054번 문제
🔗 가장 긴 감소하는 부분 수열 11722번 문제
🔗 가장 큰 증가 부분 수열 11055번 문제
🔗 정수 삼각형 1932 문제
🔗 와인시음백준 2156문제
🔗 동물원 백준 1309 문제
🔗 스티커 백준 9465문제
🔗 RGB 거리 백준 1149 문제
🔗 오르막 수 백준 11507문제
🔗 API 설계자가 메서드 선언에 예외를 명시하는 까닭은, 그 메서드를 사용할 때 적절한 조치를 취해달라는 것이다.
🔗 호출된 메서드가 실패하더라도 해당 객체는 메서드 호출 전 상태를 유지해야 한다.
🔗 1,2,3 더하기 3 백준 15988문제
🔗 예외의 toString 메서드에 실패 원인에 관한 정보를 가능한 한 많이 담아 반환하는 일은 아주 중요하다.
🔗 합분해 백준 2225문제
🔗 제곱수의 합 백준 1699 문제
🔗 연속합 백준 1912 문제
🔗 메서드가 던지는 예외는 그 메서드를 올바로 사용하는 데 아주 중요한 정보다.
🔗 상위 계층에서는 저수준 예외를 잡아 자신의 추상화 수준에 맞는 예외로 바꿔 던져야 한다.
🔗 숙련된 프로그래머는 그렇지 못한 프로그래머보다 더 많은 코드를 재사용한다
🔗 검사 예외를 제대로 활용하면 API와 프로그램의 질을 높일 수 있다.
🔗 가장 긴 증가하는 부분 수열4 백준 14002문제
🔗 가장 긴 증가하는 부분 수열 백준 11053문제
🔗 자바의 문제 상황을 알리는 타입(throwable)
🔗 예외를 사용한 반목문의 해악
🔗 이친수 백준 2193문제
🔗 쉬운 계단 수 백준 10844문제
🔗 자바의 명명 규칙은 크게 철자와 문법, 두 범주로 나뉜다.
🔗 모든 사람이 마음 깊이 새겨야 할 최적화 격언 세가지를 알아보자
🔗 네이티브 메서드는 뭐야?
🔗 리플렉션 기능 (java.lang.reflect)를 이용하면 프로그램에서 임의의 클래스에 접근할 수 있다.
🔗 적합한 인터페이스만 있다면 매개변수뿐 아니라 반환값, 변수, 필드를 전부 인터페이스 타입으로 선언하라.
🔗 문자열 연결 연산자로 문자열 n개를 잇는 시간은 n^2에 비례한다.
🔗 문자열은 다른 값 타입을 대신하기에 적합하지 않다.
🔗 자바의 데이터 타입은 크게 두 가지로 나눌 수 있다.
🔗 float와 double 타입은 특히 금융 관련 계산과는 맞지 않는다.
🔗 표준 라이브러리를 사용하면 그 코드를 작성한 전문가의 지식과 앞서 사용한 다른 프로그래머들의 경험을 활용할 수 있다.
🔗 while 문 보다는 낫지만 가장 좋은 방법이이 아닌 관용구들
🔗 지역변수의 범위를 줄이는 가장 강력한 기법은 ‘가장 처음 쓰일때 선언하기’다
🔗 1,2,3 더하기 5 백준 15990문제
🔗 API를 쓸모 있게 하려면 잘 작성된 문서도 곁들여야 한다.
🔗 자바 8 이전 메서드가 특정 조건에서 값을 반환 할 수 없을 때 취할 수 있는 선택 두 가지
🔗 null 반환은 나빠!
🔗 가변 인수는 인수 개수가 정해지지 않았을 때 아주 유용하다.
🔗 재정의한 메서드는 동적으로 선택되고, 다중정의한 메서드는 정적으로 선택된다.
🔗 메서드 이름을 신중히 짓자
🔗 클라이언트가 불변식을 깨뜨리려고 혈안이 되어있다고 가정하고 방어적으로 프로그래밍 하라
🔗 카드 구매하기2 백준 16194문제
🔗 카드 구매하기 백준 11052문제
🔗 2 x n 타일링 백준 11726문제
🔗 1로 만들기 백준 1463문제
🔗 골드바흐의 파티션 백준 17103문제
🔗 숨바꼭질6 백준 17087문제
🔗 2진수 8진수 변환 백준 1373문제
🔗 소수 구하기 백준 1929문제
🔗 소수 찾기 백준 1978문제
🔗 골드바흐의 추측 백준 1929문제
🔗 최대공약수 합 9613문제
🔗 최대공약수 최소공배수 백준 2609문제
🔗 팩토리얼의 0의 개수 백준 1676문제
🔗 단어 뒤집기2 백준 17413문제
🔗 단어 뒤집기 백준 9093문제
🔗 오큰수 백준 17298문제
🔗 수열 백준 1874 문제 [스택]
🔗 괄호 백준 9012 문제 [스택]
🔗 쇠막대기 백준 10799문제
🔗 에디터 백준 1406 문제 [스택]
🔗 오류는 가능한 한 빨리 (발생한 곳에서) 잡아야한다는 일반 원칙의 한 사례
🔗 플라이웨이트 (flyweight) 패턴이란?
🔗 프록시 (Proxy) 패턴이란?
🔗 프록시 (Proxy) 패턴이란?
🔗 Java Version Up? Concurrency Programming Still Difficult
🔗 스트림의 등장 :: 원소 시퀀스 반환 메서드의 반환타입 혼란 유래
🔗 스트림은 함수형 프로그래밍에 기초한 패러다임이다
🔗 스트림 API가 제공하는 추상 개념의 핵심 두가지
🔗 합성 (Composite) 패턴이란?
🔗 템플릿 메소드 패턴 매력의 반감 : 람다의 등장
🔗 메서드 참조
🔗 어탭터 (Adapter) 패턴이란?
🔗 익명 클래스
🔗 마커 인터페이스(Marker Interface)
🔗 보통의 프로그래머에게 가장 중요한 애너테이션 @Override 메소드
🔗 명명 패턴의 전통
🔗 열거 타입은 모든 상황에서 타입 안전 열거 패턴보다 우수하지만 단 하나의 예외가 있다.
🔗 ordinal 인덱싱
🔗 구닥다리 기법 feat 비트 필드 열거 상수
🔗 ordinal 메소드의 유혹
🔗 프로토타입 (Prototype) 패턴이란?
🔗 열거 타입이란
🔗 타입 안전 이종 컨테이너 패턴이란?
🔗 가변인수(varargs) 메소드와 제네릭은 베프가 될 수 없어!!
🔗 불공변 방식보다 유연한 무언가가 필요해 !!@@
🔗 메소드도 제네릭으로 만들 수 있어@@
🔗 제네릭 관련 용어
🔗 배열과 제네릭 타입의 차이
🔗 비검사 경고
🔗 제네릭 타입 (generic Type)
🔗 소스 파일 하나에 톱 레벨 클래스 여러 개 두기
🔗 중첩 클래스
🔗 태그 달린 클래스란?
🔗 인터페이스는 오직 이 용도로만 사용해야해 !!
🔗 디폴트 메소드 두둥 등장!!
🔗 인터페이스 (interface) , 추상 클래스 (abstract class)
🔗 상속을 고려한 설계와 문서화가 정확히 무슨 말이야?
상속은 코드를 재사용하는 강력한 수단이지만, 항상 최선은 아니다.
불변클래스란 간단히 말해 그 인스턴스의 내부 값을 수정할 수 없는 클래스다.
🔗 public 클래스에서의 public 필드를 통한 데이터 접근의 단점
어설프게 설계된 컴포넌트와 잘 설계된 컴포넌트의 가장 큰 차이는 바로 클래스 내부 데이터와 내부 구현 정보를 외부 컴포넌트로부터 얼마나 잘 숨겼느냐이다.
🔗 Comparable 인터페이스의 유일무이한 메서드 compareTo
Cloneable은 복제해도 되는 클래스임을 명시하는 용도의 믹스인 인터페이스(mixin interface)지만,
🔗 모든 하위 클래스에서 toString 메소드를 항상 재정의하라.
🔗 equals를 재정의한 클래스 모두에서 hashCode로 재정의해야 한다.
equals 메소드는 기본적으로 최상위 객체인 Object에서 제공하는 메소드로서 재정의를 염두에 두고 설계된 것이다. 때문에 재정의 시 지켜야 하는 일반 규약이 명확이 정의가 되어있다.
자바 라이브러리에는close 메소드를 호출해 직접 닫아줘야 하는 자원이 많다.
자바는 아래와 같이 두 가지 객체 소멸자를 제공한다.
자바는 메모리를 자동으로 관리해주는 가비지 컬렉터를 지원하는 언어이다.
똑같은 기능의 객체를 매번 생성하기보다는 객체 하나를 재사용하는 편이 나을때가 많다.
많은 클래스가 하나 이상의 자원에 의존한다.
객체 지향적으로 사고하지 않는 이들이 종종 남용하는 경우가 있지만, 정적 메서드와 정적필드만을 담은 클래스는 나름의 쓰임새가 있다. 아래의 예시를 보자
정적팩토리 메소드와 생성자에는 똑같은 제약이 하나 있다.
클래스는 클라이언트에 public 생성자 대신 (혹은 생성자와 함께) 그 클래스의 인스턴스를 반환하는 단순한 정적 팩토리 메서드를 제공할 수 있다.
빌더 (Builder) 패턴이란?
추상 팩토리 (Abstract Factory) 패턴이란?
팩토리 (Factory) 패턴이란?
싱글톤(Singleton) 패턴이란?
Step 1 : 다형성과 추상 타입
디자인 패턴(Design Pattern)이란?
Step 1: 객체와 테이블 매핑
Step 1: Filter
이번 블로깅에서는 JPA가 내부적으로 어떻게 동작하는지 작성할 것이다.
Step 1: JPA? - Java Persistence API
Step 1 : 객체의 핵심은 기능을 제공하는 것
Authentication Manger
Authentication Flow
이번엔 가벼운 회원 관리 프로그램을 만들어 볼 것이다.
SecurityContextPersistenceFilter
SecurityContext
Step 1: 정적 컨텐츠
필터 초기화와 다중 설정 클래스
Authentication
Step 1: Welcome Page 만들기
CSRF (사이트 간 요청 위조 Cross-site request forgery)
DelegatingFilterProxy
AuthenticationException
이클립스 기준입니다.
캐시 제어 헤더
권한 설정 및 표현식
검증헤더
SessionManagementFilter
캐시 시간 초과
캐시 기본동작
세션고정 보호
동시 세션 제어
인증
RememberMeAuthenticationFilter
AnonymousAuthenticationFilter
일반정보
Remember Me
Security Logout
HTTP Header
인증 API - FORM 인증 방식
HTTP 주요 상태코드
사용자 정의 보완 기능 구현
프로젝트 생성
API URI 설계 (Uniform Resource Identifier)
HTTP (HyperText Transfer Protocol)
URI (Uniform Resource Identifier)
[인터넷 통신]
Step 1: 스프링의 동작 과정
Step 1: pom.xml에 maria(mysql) db 관련 설정
Step 1: 프로젝트 생성
springboot와 jpa, thymeleaf를 이용한 게시판을 만들어 보겠습니다.