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-아키텍처

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

49189

날짜: 2022년 1월 31일 오후 5:51 코드 Algorithm/49189.py at main · Junroot/Algorithm 풀이 문제를 읽고 다익스트라를 사용하면 풀 수 있다고 쉽게 캐치했다. 하지만 몇몇 테스트 케이스에서 타임 아웃이 발생했는데, q에서 무시할 데이터의 조건을 잘못 썼기 때문이다. if distances[now] < distance: continue 처음에 이렇게 조건을 작성했는데, 같은 경우도 이미 최단 경로로 등록된 노드기 때문에 굳이 큐에 넣는 작업이 필요없다. if distances[now] <= distance: continue

2024-09-15 · 1 min · 63 words

43238

날짜: 2022년 1월 31일 오후 5:51 코드 Algorithm/43238.py at main · Junroot/Algorithm 풀이 기다리는 사람의 수가 최대 1000000000명 이었기 때문에 O(1) 또는 O(logn)의 형태가 될 것이라고 추측했다. O(1)의 방식은 아이디어가 떠오르지 않아 O(logn) 방식인 이분 탐색을 사용하기로 했다. 소요되는 시간의 범위는 [0, n * (가장 오래걸리는 심사원의 시간)]으로 지정했다. 최소값을 찾아야되기 때문에 해당 인원을 처리할 수 있을 때는 answer에 기억을 해두면서 범위를 점차 줄이는 방법으로 해결했다.

2024-09-15 · 1 min · 66 words

43236

날짜: 2022년 1월 31일 오후 5:51 코드 Algorithm/43236.py at main · Junroot/Algorithm 풀이 처음에 접근한 방법은 모든 경우의 수를 구하는 것이다. 하지만 이 방법은 바위가 최대 50000개이고, 제거할 바위의 수가 1개에서 바위의 수만큼이므로, ${50000}C{25000}$ 도 계산해야되기 때문에 이 방식은 불가능하다. 두 번째로 생각한 방법은 가장 짧은 거리를 우선적으로 지우면서 탐욕적으로 계산하는 방법이다. 하지만 이 방법에는 문제가 있다. 거리 합치기 선택 가장 짧은 거리를 선택해서 다른 거리와 합칠 때, 왼쪽과 오른쪽 중에 어디에 합쳐야 될 지 알 수 없다....

2024-09-15 · 2 min · 227 words

43165

날짜: 2022년 1월 31일 오후 5:51 코드 Algorithm/43165.py at main · Junroot/Algorithm 풀이 리스트의 앞부터 순서대로 덧셈과 뺼셈을 적용하면서 리스트 끝까지 적용했을 때 등호가 성립하면 1을 리턴하고 성립하지 않으면 0을 리턴하는 재귀함수를 구현했다. 이러면 현재 선택한 숫자가 덧셈인 경우와 뺄셈인 경우를 나누어 결과값을 더하면된다. (n개의 리스트의 결과값) = (첫 번째 요소가 덧셈일 때 n-1개의 결과값) + (첫 번째 요소가 뺄셈일 때 n-1개의 결과값)

2024-09-15 · 1 min · 63 words

43164

날짜: 2022년 1월 31일 오후 5:51 코드 Algorithm/43164.py at main · Junroot/Algorithm 풀이 현재 위치에서 탈 수 있는 티켓을 계속 고르면서, 모든 티켓을 사용할 수 있는 경우를 찾으면 반환하는 함수를 만들었다. dfs이기 때문에 재귀함수를 이용했고, 현재 반환한 값이 성공적으로 찾았는지 판별하기위해 (성공여부, 경로) 튜플 형태로 반환했다. 그리고 알파벳 순서가 앞서는 경로를 우선으로 해야됐기때문에 탐색 시작전에 tickets를 한 번 정렬시켰다. 다른 사람 풀이를 봤는데, python의 경우 리턴값을 따로 쓰지 않으면 None이 리턴되는 것을 이용할 수 있었다....

2024-09-15 · 1 min · 123 words

43163

날짜: 2022년 1월 31일 오후 5:51 코드 Algorithm/43163.py at main · Junroot/Algorithm 풀이 두 단어에 글자 차이 개수 구하기 차이가 1인 단어들끼리 딕셔너리로 표현하기 bfs를 이용하여 최소 변환 단계 구하기 이렇게 3가지 문제로 나뉘었다. 1, 2번은 구현 문제이므로 따로 풀이를 적지는 않는다. bfs는 너비 우선 탐색이기 때문에 출발지로부터 거리가 짧은 노드를 우선적으로 탐색한다는 것을 인지한다면 3단계를 캐치할 수 있게된다. 큐에 단어를 넣을 때 현재까지 변환한 횟수도 함께 저장하면 쉽게 최소 변환 단계를 구할 수 있다....

2024-09-15 · 1 min · 118 words