개발을 하다 보면 멀티모듈이라는 말을 들어보았었다. 단순히 모듈을 여러 개 사용하는 거라고 생각했다. 하지만 사용할 때마다 빌드가 되지 않는 상황이 발생하였다. 결과적으로는 "되긴 되게" 만들어 놓고 넘어갔다. 즉, 해결은 했지만 이해하지는 못한 상태였다. 멀티모듈을 사용하게 되면 중복제거를 하면 좋다는 정도만 알았고, 반대로 멀티 모듈을 도입하면서 발생하는 빌드 복잡도 증가, 의존성 관리 비용, 실행 구조의 제약과 같은 손해(트레이드오프)에 대해서는 전혀 고려하지 않았던거 같다. 지금 돌이켜보면, 문제의 원인은 멀티 모듈 자체가 아니라구조를 이해하지 않은 상태에서 구조를 도입하려 했다는 점에 있었다.멀티모듈을 왜 사용하는가?멀티모듈을 왜 사용할까요? 사용하지 않으면 다음과 같이 처리 할 수 있습니다. ..
머지 방법에는 크게 세 가지가 존재합니다. 스퀴시 머지(Squash Merge), 머지 커밋(Merge Commit), 그리고 리베이스 앤 머지(Rebase and Merge)입니다.Git을 사용하는 대부분의 팀은 이 세 가지 중 하나, 혹은 조합된 전략을 선택해 사용하고 있습니다.흥미로운 점은, 어느 전략이 "정답"이라고 합의된 경우는 거의 없다는 것입니다.같은 Git을 사용하고, 같은 기능을 개발하더라도 회사나 팀에 따라 머지 전략은 확연히 달라집니다.그렇다면 왜 이런 차이가 발생하는 걸까요?이는 단순히 Git 사용 취향의 문제가 아니라,팀의 협업 방식, 배포 주기, 장애 대응 전략, 그리고 변경 이력을 바라보는 관점이 다르기 때문입니다.이 글에서는 세 가지 머지 방식이 각각 어떤 특징을 가지는지 살..
카드에는 크게 두 가지 결제 방식이 있습니다. 체크 카드와 신용 카드입니다. 결제 과정은 서로 다르지만, 사용자가 기대하는 결과는 같습니다. 같은 10,000원짜리 상품을 구매했다면, 체크 카드로 결제했든 신용 카드로 결제했든 결제가 '성공했다'는 최종 상태는 동일해야 합니다.결제 방식이 다르다는 사실은 사용자에게 중요한 정보가 아닙니다. 중요한 것은 성공 여부와 그 결과가 일관되게 유지되는가입니다. 이처럼 서로 다른 처리 과정을 거치더라도 하나의 동일한 결과로 수렴해야 하는 문제를 시스템에서는 정합성(consistency) 이라고 부릅니다. 이 정합성 문제를 다루는 가장 단순한 접근은 클라이언트가 서버에 상태를 반복적으로 요청하는 HTTP 요청 기반의 폴링 방식입니다. 현재 상태를 계속 확인함으로써 결..
Lombok을 활용하면 빌더 패턴을 보일러플레이트 코드 없이 간단하게 구현할 수 있습니다.그러다 보니 문득 이런 생각이 들었습니다."이 패턴은 왜 사용하는 걸까?"파라미터를 유연하게 조절할 수 있다는 점은 알고 있었지만,빌더 패턴의 본질이 단순히 편의성에만 있는 것은 아닐 것 같았습니다.과연 이렇게 이해하는 것만으로 충분한 걸까요?왜 탄생하게 되었을까?빌더 패턴은 왜 탄생했을까요? 초창기 객체는 파라미터가 간단했다고 합니다. 필드 몇개 생성자 하나...class A { int a; int b; public A(int a, int b) { this.a = a; this.b = b; }}하지만 필드는 증가하고 필수 값과 선택 값들이 혼재되기 시작했습니다. 어떨때는 생성 조건이 도메인마다..
HTTPS로 서비스를 띄우기 위해서는 웹 서버가 필요하다. 내가 사용하고 있는 개발 도구는 Spring Boot이고, 내장 웹 서버로 Tomcat을 사용하고 있다. Tomcat과 Spring Boot는 자체적으로 HTTPS를 지원하지만, 실무 환경에서는 애플리케이션이 직접 HTTPS를 처리하는 방식보다는 프록시 웹 서버를 앞단에 두는 구조가 더 일반적으로 사용된다고 한다. 이는 Spring Boot가 HTTPS를 지원하지 못해서가 아니라, TLS(암호화) 처리를 애플리케이션에서 분리하여 인증서 관리, 성능 부담, 운영 복잡도를 줄이기 위함이다. 그렇다면 프록시 웹 서버는 어떻게 HTTPS 요청을 받아서 내부의 Spring Boot 애플리케이션과 통신하게 될까? 이 글에서는 프록시 웹 서버가 HTTPS 연..
종종 이런 생각을 합니다.디자인 패턴은 왜 학습해야 할까? 그리고 왜 학습했음에도 프로젝트에 바로 적용하지 못할까?디자인 패턴은 문제를 단순화하여 해결을 돕는 도구처럼 보이지만, 본질적으로는 새로운 해결책을 만들어내기 위한 수단이 아닙니다. 디자인 패턴은 소프트웨어 개발 과정에서 반복적으로 발생했던 설계 문제를, 검증된 구조로 다시 풀기 위한 가이드라인에 가깝습니다. 그렇기 때문에 패턴을 학습했음에도 실제 프로젝트에서 곧바로 적용하지 못하는 상황은 자연스럽습니다. 이는 패턴이 아직 필요할 만큼 구조적 문제가 명확하게 드러나지 않았기 때문이며, 비정상적인 현상이 아닙니다. 디자인 패턴의 목적은 코드를 단순하게 만드는 데 있지 않습니다. 오히려 결합도를 낮추고 책임을 분리함으로써, 변경과 확장이 발생하더라도..
분산 환경에서 요청은 한 번만 도착한다는 보장은 없습니다.네트워크 지연, 타임아웃, 클라이언트 재시도 등으로 동일한 요청은 언제든지 여러 번 전달될 수 있습니다. 이때 자주 등장하는 개념이 바로 멱등성입니다. 멱등성은 흔히 "여러 번 동작해도 같은 결과를 반환하는 성질"이라고 설명됩니다. 하지만 이 정의만으로는 멱등성과 재시도의 차이를 제대로 이해하기 어렵습니다. 재시도 역시 요청을 여러 번 수행한다는 점에서는 멱등성과 매우 유사해 보이기 때문입니다. 그럼에도 불구하고 두 개념은 결과와 책임의 관점에서 명확히 다릅니다. 재시도는 실패 가능성을 전제로 다시 요청을 보내는 행위인 반면, 멱등성은 중복 요청이 발생하더라도 시스템의 상태를 안전하게 유지하는 설계적 성질에 가깝습니다. 이 차이를 구분하지 못하면,..
디자인 패턴에는 수많은 패턴들이 존재합니다. 그중에서도 팩토리 패턴은 "객체 생성"이라는 가장 흔하지만, 동시에 가장 위험한 지점을 다룹니다.팩토리라고 하면 보통 공장의 이미지를 떠올릴 겁니다. 공장은 제품을 만들되, 제품이 어떻게 만들어지는지(공정)는 외부에 노출하지 않죠. 그런데 소프트웨어에서도 비슷한 문제가 생깁니다. 처음엔 new로 객체를 만들면 끝이지만, 시간이 지나면 생성 로직은 복잡해지고, 조건이 늘고, 테스트가 어려워지고, 결국 생성 코드가 여기저기 퍼지면서 변경 비용이 폭발합니다. 팩토리 패턴은 단순히 "객체를 대신 만들어주는 패턴"이 아닙니다. 생성 책임을 분리해서, 변경이 전파되는 범위를 통제하는 설계 전략입니다.이번 시간에는 "공장처럼 찍어낸다"는 비유를 넘어서, 왜 new가 위험해..
Git Flow라는 개념은 오래전부터 들어왔지만, 실제로 구조를 이해하고 사용해본 경험은 거의 없었다. 그동안은 Git의 기본적인 사용법(commit, push, branch)만 알고 있으면 충분하다고 생각했다. 필요하면 그때그때 찾아보면 된다고 판단했고, 개인 개발 환경에서는 그 선택이 크게 틀리지도 않았다.하지만 협업 환경에서는 이야기가 달라진다. 브랜치의 목적이 불분명해지고, 배포 코드와 개발 코드의 경계가 흐려지는 순간Git은 협업을 돕는 도구가 아니라 혼란을 증폭시키는 요소가 된다.특히 이직을 준비하며 여러 팀의 개발 문화를 살펴보면서, Git Flow는 단순한 브랜치 전략이 아니라배포 안정성과 협업 비용을 관리하기 위한 규칙이라는 점을 뒤늦게 체감하게 되었다.이 글에서는 Git Flow를 "외..
크게 DB에는 2가지 종류가 존재합니다. SQL을 사용하는 RDB와 SQL도 사용하는 NoSql(NoSql이 왜 Nosql인지에 대해 sql을 안써서 noSql이다 아니다 Not only sql의 약자라 그렇다라는 말들이 존재합니다. 안 중요하다고 생각합니다.)그렇다면, 어떻게 다를까요? 성능을 올리는 방식에는 크게 두가지가 있습니다. 수평적으로 늘리는 방식과 수직적으로 늘리는 방식이 있습니다. 간단히 설명하자면 수평적으로 성능을 올리는 방법은 갯수나 방법등을 늘리는 방법이고, 수직적으로 늘리는 방법은 성능을 올리는 방법입니다. 이에 해당하는 기술들은 Replication, 파티셔닝, 샤딩등이 존재한다고 합니다. 자세하게 설명하면 다른 방법들이긴하지만 말이죠. 그리고 개발을 하게 되면 SQL을 사용하여 ..
오래 기억에 남으려고 이해가 가지 않는것들은 이해가 갈때까지 공부하는 방식을 선택하였고, 계속 복습을 반복하는 형식으로 진행하였습니다. 하지만 여기에는 아주 치명적인 문제가 있었습니다. 그것은 생각보다 시간이 오래걸렸습니다. 보통 토요일 부터 시작해서 월요일까지 정리를 마치는데 나오는 결과물이 생각보다 좋지는 않았던거 같습니다. 그래서 방법을 다시한번더 바꾸려고 합니다. 그렇다고 해서 GPT에 돌린결과를 그대로 쓸 생각은 없습니다. 그렇게 해버리면 공부하는 의미가 없기 때문이죠. 조금더 고민해보고 진행해보겠습니다.일단 학습을 하려고 하는 범위 부터 말씀드리고 깊게 학습하는 방식으로 변경하는게 좋다고 생각합니다.학습할 내용은 다음과 같습니다.Index, SQL Injection, Statement vs P..
이전 장에서 프로세스의 상태에 대해 자세하게 알아봤습니다. 그리고 프로세스는 독립된 메모리 공간이라고 설명했었습니다. 간단하게 저번에 학습한 내용을 복습해보면 프로세스의 상태는 생성 -> 준비 -> 대기 -> 실행 -> 종료 -> 좀비 -> 해제 순으로 진행이 되어지며, 스케쥴러를 통해 프로세스의 실행 순서를 결정하게 되어집니다. 실행 순서를 나타내는 방식으로는 FSFC 먼저 들어온 친구부터 처리하는 기법, 우선순위 우선순위가 높은거 부터 처리하는 기법, RR 순차적으로 돌면서 처리하는 기법(순차적은 원형입니다.) SFJ 짧은 시간이 걸릴거 같은거 부터 처리하는 기법, CFS CPU가 가장 적게 쓴거 부터 처리하는 기법등이 존재합니다. 핵심은 모든 스케쥴러는 최초 1회는 FSFC으로 동작을 하게 되고, ..