6-키-값 저장소 설계

키-값 저장소: 비 관계형 데이터베이스로 저장소에 저장되는 값은 고유 식별자를 키로 가진다. 키는 일반 텍스트일 수도 있고 해시 값일 수도 있다. 키는 성능상의 이유로 짧을수록 좋다. 문제 이해 및 설계 범위 확정 다음 특성을 갖는 키-값 저장소를 설계해 볼 것이다. 키-값 쌍의 크기는 10KB 이하이다. 큰 데이터를 저장할 수 있어야 한다. 높은 가용성을 제공해야 한다. 따라서 시스템은 설사 장애가 있더라도 빨리 응답해야 한다. 높은 규모 확장성을 제공해야 한다. 따라서 트래픽 양에 따라 자동적으로 서버 증설/삭제가 이루어져야 한다....

2024-09-15 · 7 min · 1287 words

6-클래스 설계

상속보다는 컴포지션을 사용하라 간단한 행위 재사용 재사용을 위해 상속을 사용했을 때 단점 상속은 하나의 클래스만을 대상으로 할 수 있다. 상속을 사용해서 행위를 추출하다 보면, 많은 함수를 갖는 거대한 BaseXXX 클래스를 만들게 되고, 굉장히 깊고 복잡한 계층 구조가 만들어진다. 상속은 클래스의 모든 것을 가져오게 된다. 따라서 불필요한 함수를 갖는 클래스가 만들어질 수 있다. 인터페이스 분리 원칙 위반 상속은 이해하기 어렵다. 작동 방식을 이해하기 위해 슈퍼클래스를 여러 번 확인해야 한다. 재사용을 위해 컴포지션을 사용했을 때 장점 코드의 실행을 더 명확하게 예측할 수 있다....

2024-09-15 · 7 min · 1407 words

6-코틀린 타입 시스템

널 가능성 널 가능성(nullability): NPE를 피할 수 있게 돕기 위한 코틀린 타입 시스템의 특성 코틀린을 비롯한 최신 언어에서 null에 대한 접근 방법은 가능한 한 이 문제를 실행 시점에서 컴파일 시점으로 옮기는 것이다. 널이 될 수 있는 타입[] 모든 타입은 기본적으로 널이 될 수 없는 타입이다. 널을 받을 수 있게 하려면 타입 이름 뒤에 물음표(?)를 명시해야 한다. 널이 될 수 있는 타입의 변수가 있다면 그에 대해 수행할 수 있는 연산이 제한된다. 메소드를 직접 호출할 수 없다....

2024-09-15 · 10 min · 2024 words

6-전송 계층 신뢰할 수 있는 데이터 전송

전송 계층의 역할 전송 계층은 목적지에 신뢰할 수 있는 데이터를 전달하는 역할과 전송된 데이터의 목적지가 어떤 애플리케이션인지 식별하는 역할을 한다. 전송 계층의 특징을 설명하면 신뢰성/정확성과 효율성으로 구분할 수 있다. 신뢰성/정확성: 데이터를 목적지에 문제없이 전달하는 것. 연결형 통신이라고 한다. 연결형 통신은 상대편과 확인해 가면서 통신하는 방식이다. TCP 효율성: 데이터를 빠르고 효율적으로 전달하는 것. 비연결형 통신이라고 한다. 비연결 통신은 상대편을 확인하지 않고 일방적으로 데이터를 전송하는 방식이다. 동영상처럼 효율적인 데이터 전송이 필요한 애플리케이션에서 사용한다....

2024-09-15 · 3 min · 441 words

6-손쉬운 기능명세 작성법 2강 명세가 뭡니까

기능 명세 vs 기술 명세 5장에서 이야기 했던 명세는 기능 명세에 해당한다. 기능 명세(functional specification) 사용자 관점에서 젶무이 어떻게 동작할지를 기술 구현은 신경 쓰지 않는다. 화면, 메뉴, 대화 상자 등 기술 명세(technical specification) 프로그램 내부 구현을 기술한다. 자료 구조와 관계 형 데이터베이스 모델과 프로그래밍 언어, 도구, 알고리즘 선택과 같은 항목을 다룬다. 명세서에 넣는 단골 항목 면책 조항: 현재 명세가 완벽하지 않다는 것을 알리는 방어적 내용. 저자: 명세에서 무엇인가 잘못된다면, 이를 수정할 책임있는 명세서 소유자를 지정해야 하며, 이 사람 이름이 명세서에 찍혀 있어야 한다....

2024-09-15 · 1 min · 194 words

6-세부사항

데이터베이스는 세부사항이다 애플리케이션 내부 데이터의 구조는 시스템 아키텍처에서 대단히 중요하다. 하지만 데이터베이스는 데이터 보델이 아닌 소프트웨어일 뿐이다. 아키텍처 관점에서 이러한 유틸리티닌 저수준의 세부사항일 뿐이라서 아키텍처와는 관련이 없다. 데이터베이스 시스템이 우위를 차지할 수 있었던 이유는 디스크 떄문이다. 느린 디스크를 개선하기 위해 색인, 캐시, 쿼리 계획 최적화가 필요했다. 이를 위해ㅅ 데이터 접근 및 관리 시스템이 필요했다. 파일 시스템: 문서 기반. 문서의 이름을 기준으로 조회할 떄는 잘 동작하지만, 내용을 기준으로 검색할 떄는 크게 도움되지 않는다....

2024-09-15 · 4 min · 816 words

6-단위 테스트 스타일

단위 테스트의 세 가지 스타일 단위 테스트의 세 가지 스타일 출력 기반 테스트 상태 기반 테스트 통신 기반 테스트 테스트 품질: 출력 기반 > 상태 기반 > 통신 기반 출력 기반 테스트 정의 SUT에 입력을 넣고 생성되는 출력을 점검하는 방식 출력 기반 테스트 스타일은 사이드 이펙트가 없는 순수 함수 방식으로 작성된 코드에만 적용된다. 상태 기반 스타일 정의 작업이 완료된 후 시스템 상태를 확인 상태는 SUT나 협력자 중 하나, 또는 데이터베이스나 파일 시스템 등과 같은 프로세스 외부 의존성의 상태 등을 의미할 수 있다....

2024-09-15 · 4 min · 759 words

6-교착 상태

교착 상태의 개요 교착 상태의 정의 교착 상태: 2개 이상의 프로세스가 다른 프로세스의 작업이 끝나기만 기다리며 작업을 더 이상 진행하지 못하는 상태. 교착 상태 vs 아사 상태: 아사 상태는 운영체제가 잘못된 정책을 사용하여 특정 프로세스 작업이 지연되는 문제고, 교착 상태는 여러 프로세스가 작업을 진행하다 자연적으로 발생하는 문제다. 교착 상태는 시스템 자원, 공유 변수(또는 파일), 응용 프로그램 등을 사용할 떄 발생할 수 있다. 자원 할당 그래프 자원 할당 그래프: 프로세스가 어떤 자원을 사용 중이고 어떤 자원을 기다리고 있는지 방향성이 있는 그래프로 표현한 것이다....

2024-09-15 · 7 min · 1367 words

6-REST 서비스 생성하기

REST 컨트롤러 작성하기 서버에서 데이터 가져오기 @CrossOrigin(origins = ["*"]) @RequestMapping(path = ["/design"], produces = ["application/json"]) @RestController class DesignTacoController( private val tacoRepository: TacoRepository ) { @GetMapping("/recent") fun recentTacos(): Iterable<Taco> { val pageRequest = PageRequest.of(0, 12, Sort.by("createdAt").descending()) return tacoRepository.findAll(pageRequest).content } } @RestController: @Controller와 @ResponseBody를 지원하는 애노테이션 @ResponseBody: 리턴 값을 HTTP 응답 바디에 직접 쓰는 값으로 사용한다. 응답 바디를 직접 작성하는 방법으로는 이외에도, ResopnsEntity 객체를 반환하는 방법이 있다. @RequestMapping produces: HTTP의 Accept 헤더에 사용되고 HTTP의 Content Negotiation에 사용된다....

2024-09-15 · 5 min · 886 words

5-프로세스 동기화

프로세스 간 통신 프로세스 간 통신의 개념 프로세스 내부 데이터 통신: 하나의 프로세스 내에 2개 이상의 스레드가 존재하는 경우의 통신. 프로세스 내부의 스레드는 전역 변수나 파일을 이용하여 데이터를 주고 받는다. 프로세스 간 데이터 통신: 같은 컴퓨터에 있는 여러 프로세스끼리의 통신. 공용 파일 또는 운영체제가 제공하는 파이프를 사용하여 통신한다. 네트워크를 이용한 데이터 통신: 여러 컴퓨터가 네트워크로 연결되어 있을 때의 통신. 프로세스가 소켓을 이용하여 데이터를 주고받는다. 💡 같은 컴퓨터에 있는 프로세스끼리도 소켓을 이용하여 통신할 수 있다....

2024-09-15 · 8 min · 1625 words

5-안정 해시 설계

수평적 규모 확장성을 달성하기 위해서는 요청 또는 데이터를 서버에 균등하게 나누는 것이 중요하다. 해시 키 재배치(rehash) 문제 나머지 연산으로 해시를 배치하는 것은 데이터 분포가 균등할 떄만 잘 동작한다. 또한, 서버가 추가되거나 기존 서버가 삭제되면 대부분의 키가 재분배된다. 안정 해시 안정 해시: 해시 테이블 크기가 조정될 떄 평균적으로 k/n개의 키만 재배치하는 기술 k: 키의 개수 n: 슬롯의 개수 기본 구현법 해시 함수를 사용해서 서버 IP나 이름으로 링 위에 서버를 배치한다. 해시 키도 똑같이 배치한다....

2024-09-15 · 1 min · 141 words

5-아키텍처

아키텍처란? 아키텍처의 주목적: 시스템의 생명주기 지원 시스템을 쉽게 이해하고, 쉽게 개발하며, 쉽게 유지보수하고, 쉽게 배포하게 해준다. 팀 구조에 따라 아키텍처가 결정이 날 수도 있다. 작은 규모의 팀이라면 모노리틱 시스템으로 개발할 수도 있다. 팀 규모가 클 때, 안정된 인터페이스가 없고 잘 설계된 컴포넌트로 분리되어 있지 않다면 각 팀마다 하나씩 컴포넌트를 가질 가능성이 높다. 소프트웨어 아키텍처는 시스템을 단 한 번에 쉽게 배포할 수 있도록 만드는 데 목표를 두어야 한다. 개발 초기 단계에 MSA를 사용하자고 결정할 경우, 컴퓨넌트 경계가 뚜렷해지고 인터페이스가 안정화되므로 시스템을 매우 쉽게 개발할 수 있다고 판단할 수 도 있다....

2024-09-15 · 13 min · 2629 words

5-손쉬운 기능명세 작성법 1강 명세서 작업이 귀찮습니까

명세서 작업의 가장 중요한 결실은 바로 프로그램 설계다. 프로그램이 세부적으로 어떻게 동작하는지를 기술하다 보면, 자연스럽게 프로그램을 설계하게 된다. 의사소통 시간의 절약이다. 명세서 작업을 할 때, 프로그램을 어떻게 동작하게 할지만 알려주면 되고, 함꼐 일할 팀원은 이 명세서만 읽으면 된다. 세부 명세서 없이는 일정을 계획하기가 불가능하다. 명세서 작업은, 명세서가 없다면 묻혀버릴 모든 결정 사항을 못박아 버리는 방법이다.

2024-09-15 · 1 min · 55 words

5-목과 테스트 취약성

목과 스텁 구분 테스트 대역 유형 목: 외부로 나가는 상호 작용을 _모방_하고 _검사_한다. 이러한 상호 작용은 SUT가 상태를 변경하기 위한(사이드 이펙트가 있는) 의존성을 호출하는 것에 해당한다. 목과 스파이로 분류할 수 있다. 스파이는 수동으로 작성하는 반면, 목은 목 프레임워크의 도움을 받아 생성한다. 스텁: 내부로 들어오는 상호 작용을 _모방_한다. 이러한 상호 작용은 SUT가 입력 데이터를 얻기 위한 의존성을 호출하는 것에 해당한다. 스텁, 더미, 페이크로 분류할 수 있다. 더미: 널값이나 가짜 문자열과 같이 단순하고 하드코딩된 값이다....

2024-09-15 · 5 min · 975 words

5-람다로 프로그래밍

람다 식과 멤버 참조 람다 소개: 코드 블록을 함수 인자로 넘기기 ‘이벤트가 발생하면 이 핸들러를 실행하자’나 ‘데이터 구조의 모든 원소에 이 연산을 적용하자’와 같은 생각을 코드로 표현하기 위해서 예전에는 무명 내부 클래스를 사용했다. 하지만 이는 코드가 너무 번잡스러워졌고, 자바 8부터 람다를 사용해 간결하게 작성할 수 있었다. 자바 컬렉션에 대해 수행하는 대부분 작업은 람다나 멤버 참조를 인자로 받는 함수를 통해 더 짧고 이해하기 쉽게 만들 수 있다. 람다 식의 문법 람다 식을 변수에 저장할 수 있다....

2024-09-15 · 6 min · 1241 words

5-네트워크 계층 목적지에 데이터 전달하기

네트워크 계층의 역할 네트워크 계층은 네트워크 간의 통신을 가능하게 해준다. 네트워크 계층을 통해 다른 네트워크로 데이터를 전송하려면 라우터라는 네트워크 장비가 필요하다. 라우터는 데이터의 목적지가 정해지면 해당 목적지까지 어떤 경로로 가는 것이 좋은지 알려주는 기능을 한다. 이를 라우팅이라고 한다. 라우터는 라우팅 테이블이 있어서 경로 정보를 등록하고 관리한다. 네트워크 계층에서는 목적지 주소를 IP주소로 표현한다. IP주소는 어떤 네트워크의 어떤 컴퓨터인지 구분할 수 있도록 해준다. 네트워크 계층에는 IP(Internet Protocol)라는 프로토콜이 있다. 네트워크 계층에서 캡슐화할 때 IP 헤더를 붙인다....

2024-09-15 · 3 min · 565 words

5-구성 속성 사용하기

스프링 XML 구성으로 속성 값을 설정하던 지난 10년간은 명시적으로 빈을 구성하지 않고는 속성을 설정하는 마땅한 방법이 없었다. 스프링 부트는 구성 속성(configuration property)을 사용하는 방법을 제공한다. 스프링 애플리케이션 컨텍스트에서 구성 속성은 빈의 속성이다. 자동-구성 세부 조정하기 두 가지 형태의 서로 다르면서도 관련이 있는 구성 빈 연결: 스프링 애플리케이션 컨텍스트에서 빈으로 생성되는 애플리케이션 컴포넌트 및 상호 간에 주입되는 방법을 선언하는 구성 속성 주입: 스프링 애플리케이션 컨텍스트에서 빈의 속성 값을 설정하는 구성 스프링 환경 추상화 이해하기 스프링 환경 추상화(environment abstraction)는 구성 가능한 모든 속성을 한 곳에서 관리하는 개념이다....

2024-09-15 · 4 min · 684 words

5-객체 생성

생성자 대신 팩토리 함수를 사용하라 팩토리 함수: 생성자 역할을 대신 해주는 함수 팩토리 함수의 장점 생성자와 다르게, 함수에 이름을 붙일 수 있다. 생성자와 다르게, 함수가 원하는 형태의 타입을 리턴할 수 있다. 또한 인터페이스 뒤에 실제 객체의 구현을 숨길 수 있다. 생성자와 다르게, 호출될 때마다 새 객체를 만들 필요가 없다. 싱글턴 패턴, 캐싱 메커니즘 팩토리 함수는 아직 존재하지 않는 객체를 리턴할 수도 있다. 객체 외부에 팩토리 함수를 만들면, 그 가시성을 원하는 대로 제어할 수 있다....

2024-09-15 · 5 min · 858 words

49191

날짜: 2022년 1월 31일 오후 5:51 코드 Algorithm/49191.py at main · Junroot/Algorithm 풀이 자신이 이길 수 있는 상대인지 확인하기 위해서 방향그래프 사용하니 해결할 수 있었다. a가 b를 이겼다고 했을 때, a→b로 연결하는 식으로 그래프를 만들면된다. 문제의 예시의 경우는 아래 그림과 같다. 이렇게 그래프를 만든 뒤, 자신이 도착할 수 있는 노드들은 모두 자신이 이길 수 있는 선수들이 된다. 4는 (2, 3, 5)를 이길 수 있다. 자신이 지는 선수의 경우에도 위의 방법으로 그래프를 그려서 구할 수 있다....

2024-09-15 · 1 min · 106 words

49190

날짜: 2022년 1월 31일 오후 5:51 코드 Algorithm/49190.py at main · Junroot/Algorithm 풀이 내 풀이 선을 그으면서 도형이 언제 생기는지 생각해보면 된다. 답은 기존에 그어져있던 선과 만나는 순간에 방이 하나 늘어난다. 그럼 선이 만나는 순간이 언제인지를 고려해보면 된다. 새로운 선을 그으면서, 기존에 방문한 점으로 이동하는 경우 새로운 선을 그으면서, 대각선을 그을 때 맞은 편 대각선이 이미 그어져 있는 경우 이 두 가지의 상황만 고려해서 시뮬레이션 하면 쉽게 해결이 가능하다. 다른 사람 풀이 다른 사람 풀이를 봤는데 너무 좋은 풀이법이 있어서 가져왔다....

2024-09-15 · 1 min · 172 words