개발과정에서 마주한 문제 하나를 소개하려고 합니다. 저희 프로젝트의 구조는 Spring MVC를 메인 WAS로 두고 사용합니다. 핵심 비즈니스 로직과 거리가 멀거나 WAS에게 부담이 되는 기능 및 서비스의 다른 프로젝트에서 사용이 가능한 것들은 외부에 따로 서버를 두고 사용하고 있습니다. 그 중에 푸시 알람과 같은 서비스는 AWS Lambda + Gateway를 통해서 처리하고 있습니다. 게시글 추가와 맨션 요청이 같이 POST /posts로 들어오는 경우를 예시로 들어보며 흐름을 이해해보도록 하겠습니다 유저가 글 내용과 A유저에게 맨션을 하며 글을 추가한다 (POST / posts 요청) WAS는 해당 요청을 받고 글을 추가한다 마지막에 Controller 계층에서 AWS Gateway에게 A유저의 맨..
API 개발부터 리펙토링까지 어느정도 프로젝트가 완료되었습니다. 그러면서 자연스럽게 성능 이슈에 대해 관심을 가지게 되었습니다. WAS Thread Pool, Connection Pool 등등 다양하게 성능을 튜닝할 수 있지만 가장 극적인 효과를 볼 수 있는 SQL 쿼리 튜닝을 한번 해보았습니다. 어떤 쿼리에서 많은 시간이 소요되는 지 알아보기 위해서 DB에 많은 Row를 넣고 여러 API를 호출해보았습니다. 일반적으로 findById와 같이 PK기반으로 하나의 Row를 찾거나, insert/update/delete에 큰 문제는 없었습니다. 병목지점이 발생하는 부분은 많은 조인과 페이지네이션, 검색하는 부분이었습니다. 가장 크게 소요시간이 걸린 것은 커뮤니티 / 게시글을 검색하는 부분이었습니다. 커뮤니티..
2022.01 ~ 2023.03 동안 진행한 프로젝트가 드디어 끝났습니다. 중간에 코딩테스트나 면접 준비, 건강상의 문제로 중단된 것도 있었지만, 약 1년 2개월 동안 진행한 프로젝트를 마무리해서 기분이 좋습니다. 저는 학교에서 사용하는 커뮤니티 앱의 서버를 구축하는 프로젝트를 진행했습니다. 일반적인 커뮤니티와는 다르게 실명으로 진행하는 커뮤니티입니다. 코로나로 인해 선/후배 간의 인적교류가 줄어들어, 이를 해소하기 위해 실명 커뮤니티를 만들었습니다. 이 프로젝트는 기능 추가만 하고 끝나는 프로젝트가 아닌, 기능을 계속 추가하고 리팩토링하는 것을 목표로 했습니다. 일반적으로 프로젝트는 기능을 추가하고 끝나게 됩니다. 이는 일반적인 회사 업무와 다르다고 생각합니다. 기능의 구현도 많이 집중했지만, 전체적으..
기본 기능을 구현하고 그들을 동적으로 조합해서 기능의 집합을 이용할 수 있는 패턴이다. Decorator pattern을 이해하기 위해, 도로를 보여주는 클래스를 작성해보자. 선이 없는 일반적인 도로를 보여주는 기능, 차선을 보여주는 기능, 교통정체를 보여주는 기능, 교차로를 보여주는 기능이 있다. 이러한 기능은 기본적인 도로를 보여주는 클래스를 부모 클래스로 두어서 자신의 기능을 추가하면 된다. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 public class DisplayRoad { public void display(){ System.out..
OCP를 만족시키면서 부분-전체 관계를 가지는 객체들 간의 관계를 정의할 때 쓸 수있다. 전체와 부분을 동일한 인터페이스로 관리할 수 있다. composite pattern을 이해하기 위해서, 하나의 박스가 있다고 하자. 그리고 그 박스에는 컴퓨터의 부품들이 들어간다. Box클래스를 만들고 Keyboard, Monitor, Speaker 객체들을 멤버로 가진다. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 public class Box { private Keyboard keyboard; private Monitor monitor; private Speaker speaker; public int getTotalPrice(){ return keyboard.getPrice() + monit..
프로세스와 스레드의 차이에 대해서 알아보자. 두개의 차이는 운영체제 수업에서도 아주 중요하게 다루는 주제이다. 또한, 개발자 면접에서도 자주 나오는 주제이다. 해당 주제에 대해서 잘 공부해두면 좋을 것 같다. 1. Thread의 출현 배경 스레드의 출현 배경을 알면, Process의 차이를 더욱 명확하게 알 수 있다. 프로세스의 문제점 1. 프로세스 간 컨텍스트 스위치 오버헤드 CPU가 프로세스A를 실행하다가 B를 실행한다고 하자. 프로세스 A의 컨텍스트를 PCB에 저장하고 B의 컨텍스트를 레지스터에 저장해주어야 한다. 또한, 캐시와 MMU의 TLB도 flush해주어야 한다. 그리고 L1,L2캐시에는 프로세스B의 데이터로 채워준다. 상당히 Time consuming한 작업이다. 2. 프로세스 사이 통신의..
Quick sort와 Merge sort는 nlogn의 시간복잡도를 가지는 대표적인 정렬 방법이다. 일반적으로 Quick sort가 Merge sort보다 빠르다. 그 이유는 Locality와 관련이 있다. Locality의 개념을 알아보고 왜 Quick sort가 더 빠른지 알아보도록 하자. Locality 지역성(Locality)은 CPU가 짧은 시간 범위 내에 일정 구간의 메모리 영역을 반복적으로 엑세스하는 경향을 말한다. 메모리 내의 정보를 균일하게 엑세스 하는게 아닌, 짧은 시간내에 특정 부분을 집중적으로 참조하는 특성이다. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 void f() { //간단한 작업을 수행 } void g() { int arr[..
데이터의 변경이 발생하였고 변경을 실시간으로 통보해야할 때, OCP를 만족시키면서 데이터의 변경을 통보하는 framework이다. Observer 패턴을 이해하기 위해, 학생의 점수를 입력하고 최대/최소값을 보여주는 클래스를 작성해보자. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 public class ScoreRecord { private List scores = new ArrayList(); private MinMaxView minMaxView; public void setMinMaxView(MinMaxView minMaxView) { this.minMaxView = minMaxView; } public List getScores() { retur..
커맨드 패턴을 이해하기 위해, 만능 버튼을 만들어보자. 만능 버튼은 눌리면 어떠한 기능도 수행할 수 있다. 1 2 3 4 5 public class Lamp{ public void turnOn(){ System.out.println("Lamp on"); } } http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5; text-decoration:none">Colored by Color Scripter 1 2 3 4 5 6 7 8 9 10 public class Button{ private Lamp lamp; public void setLamp(Lamp lamp){ this.lamp = lamp; } public void pressed(..
각 원칙을 설명하기 위해 문제 상황을 제시하고 어떻게 해결해야하는 지에 대해서 중점적으로 이야기해보도록 합시다. SOLID에 대한 기원등은 위키백과를 참고하시기 바랍니다. SRP(단일 책임 원칙, Single Responsibility Principle) 객체가 단 하나의 책임만을 가지도록 설계해야 한다. 책임이라는 것은, 이 객체가 해야할 일을 의미한다. 즉 어느 객체보다도 가장 잘 할 수 있는 일이 1개여야만 한다. 일이 1개여야하는 것은 메소드가 1개라는 의미가 아니다. 논리적으로 하는 일을 의미한다. 우리가 설계 원칙을 배우는 이유는, 예상치 못한 변경사항이 발생하더라도, 다른 객체들이 크게 변화하지 않고 확장하기 위함이다. 그래서 SRP의 단일 책임 원칙이 중요하다. 이 객체가 SRP의 원칙에 ..