반응형

 

https://www.acmicpc.net/problem/2839

 

2839번: 설탕 배달

상근이는 요즘 설탕공장에서 설탕을 배달하고 있다. 상근이는 지금 사탕가게에 설탕을 정확하게 N킬로그램을 배달해야 한다. 설탕공장에서 만드는 설탕은 봉지에 담겨져 있다. 봉지는 3킬로그

www.acmicpc.net

 

문제 설명

상근이는 요즘 설탕공장에서 설탕을 배달하고 있다. 상근이는 지금 사탕가게에 설탕을 정확하게 N킬로그램을 배달해야 한다. 설탕공장에서 만드는 설탕은 봉지에 담겨져 있다. 봉지는 3킬로그램 봉지와 5킬로그램 봉지가 있다.

상근이는 귀찮기 때문에, 최대한 적은 봉지를 들고 가려고 한다. 예를 들어, 18킬로그램 설탕을 배달해야 할 때, 3킬로그램 봉지 6개를 가져가도 되지만, 5킬로그램 3개와 3킬로그램 1개를 배달하면, 더 적은 개수의 봉지를 배달할 수 있다.

상근이가 설탕을 정확하게 N킬로그램 배달해야 할 때, 봉지 몇 개를 가져가면 되는지 그 수를 구하는 프로그램을 작성하시오.

(입력 : 첫째 줄에 N이 주어진다. (3 ≤ N ≤ 5000))

 

 

 

 

나의 풀이

N = int(input())

five = N // 5 + 1
three = N // 3 + 1
result = 0
end_point = False

for i in range(five + 1):
  if end_point == True:
    break
  for j in range(three):
    if N == (((five-i) * 5) + (j * 3)):
      result = (five - i) + j
      end_point = True
      break

if result == 0:
  result = -1
  
print(result)

five와 three는 각각 5킬로그램 봉지와 3킬로그램 봉지의 최대 개수 + 1 이다

5킬로그램 봉지 개수가 five 이하이고, 3킬로그램 봉지 개수가 three 이하일 때,

정확히 N킬로그램을 표현하는 경우 중, 5킬로그램 봉지 개수가 가장 큰 경우를 찾는 알고리즘을 작성했다.

 

그리디 문제로 인식했으나, 풀이는 그리디 알고리즘을 사용했다고 보기가 좀 그렇다.

찾아보니 아직 안 배운 동적 프로그래밍(DP)에 가까운 것 같다.

 

 

 

남의 풀이

def sugar_bag(N):
    bag_3 = 0
    bag_5 = N // 5
    r = N % 5
    while (bag_5 >= 0):
        if r % 3 == 0:
            bag_3 = r // 3
            return bag_3 + bag_5
        bag_5 -= 1
        r += 5
    return -1
    
    
N = int(input())
print(sugar_bag(N))

3킬로그램, 5킬로그램 봉지 개수를 각각 bag_3, bag_5로 정의한다.

N을 5로 나누고 나눈 나머지를 r로 정의한다.

 

r을 3으로 나눴을 때,

나누어 떨어진다면 바로 bag_3, bag_5의 합을 반환한다.

나누어 떨어지지 않는다면 나머지에 5를 더하고 bag_5을 한 개 빼준다.

 

 

확실히 그리디 알고리즘을 사용한 풀이다.

3과 5의 최소공배수인 15에 대해,

5킬로그램 봉지 3개를 사용하는 것이 무조건 이득이므로

그리디 알고리즘 사용 형태에 해당한다.

 

 

 

 

참고 자료 : https://www.acmicpc.net/source/17359883

 

반응형
반응형

 

sum(), min(), max(), eval() - 합, 최대값, 최소값, 문자열을 식으로

# sum()
result = sum([1, 2, 3, 4, 5])
print(result) # 15

# min(), max()
min_result = min(7, 3, 5, 2)
max_result = max(7, 3, 5, 2)
print(min_result, max_result) # 2 7

# eval()
result = eval("(3+5)*7")
print(result) # 56

sum()은 합, min()과 max()는 최소, 최대값을 추출한다.

eval()은 문자열로 된 식(코드)을 계산한다.

 

 

 

sorted() - 정렬된 새로운 리스트 반환

# sorted()
result = sorted([9, 1, 8, 5, 4])
reverse_result = sorted([9, 1, 8, 5, 4], reverse=True)
print(result) # [1, 4, 5, 8, 9]
print(reverse_result) # [9, 8, 5, 4, 1]

sorted()는 리스트(또는 다른 자료형)를 정렬한다.

reverse 인자는 내림차순 여부를 결정한다. (없으면 오름차순)

 

리스트의 sort() 메서드와 다른 점은, sorted() 함수는 새로운 리스트를 생성한다는 것이다.

 

 

 

 

 

itertools permutaions(), combinations() - 순열, 조합

from itertools import permutations
data = ['A', 'B', 'C']

result = list(permutations(data, 3))
print(result)
# [('A', 'B', 'C'), ('A', 'C', 'B'), ('B', 'A', 'C'), ('B', 'C', 'A'), ('C', 'A', 'B'), ('C', 'B', 'A')]

permutations(list, n)은 list에서 순서를 고려하여 n개를 추출한 경우의 수를 생성해준다.

 

from itertools import combinations
data = ['A', 'B', 'C']

result = list(combinations(data, 2))
print(result)
# [('A', 'B'), ('A', 'C'), ('B', 'C')]

combinations(list, n)은 list에서 순서를 고려하지 않고 n개를 추출한 경우의 수를 생성해준다.

 

중복 순열과 중복 조합을 나타내는 product(list, n)과 combinations_with_replacement(list, n) 함수도 존재한다.

 

 

 

Counter - 성분의 개수를 세어주는 클래스

from collections import Counter

counter = Counter(['red', 'blue', 'red', 'green', 'blue', 'blue'])

print(counter['blue']) # 3
print(counter['green']) # 1
print(dict(counter)) # 딕셔너리로 반환
# {'red': 2, 'blue': 3, 'green': 1}

Counter는 리스트에서 성분의 개수를 세어주는 클래스이다.

딕셔너리 형태로 각 성분의 개수를 반환할 수도 있다.

 

 

gcd() - 최대공약수

import math

# 최소공배수(LCM)을 구하는 함수
def lcm(a, b):
	return a * b // math.gcd(a, b)
    
a = 21
b = 14

print(math.gcd(21, 14)) # 7 (최대공약수)
print(lcm(21, 14) # 42 (최소공배수)

gcd(a, b)는 a와 b의 최대공약수를 구하는 메서드이다.

최소공배수는 = (두 수의 곱) / (최대공약수) 공식에 따라 위와 같이 구할 수 있다.

(공식을 간단히 증명하자면,

A와 B의 최대공약수를 GCD라 하고, A = a x GCD, B = b x GCD 라 하자.

AB = a x b x (GCD)^2 이다.

이때, a, b, GCD는 모두 서로소 이므로, 위의 식에서 양변을 GCD로 나누면

AB/GCD = a x b x GCD 이고, 이 값은 최소공배수가 된다.)

 

 

 

 

반응형
반응형

리스트 컴프리헨션(List Comprehension)이란?

대괄호 안에 조건문과 반복문을 적용하여 리스트를 초기화하는 방법이다.

-> 코딩테스트 문제를 풀 때 유용한 문법이라고 한다.

 

 

 

 

 

사용 예시

반복문만 사용

array = [i for i in range(10)]
print(array) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

간단한 반복문으로 위와 같은 배열을 생성할 수 있다.

 

 

 

 

반복문과 조건문 사용

array = [i for i in range(10) if i % 2 == 1]
print(array) # [1, 3, 5, 7, 9]

조건문을 추가할 수 있다.

 

 

 

 

삽입 인자 변경

array = [i * i for i in range(10)]
print(array) # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

리스트에 삽입할 인자를 변경할 수 있다.

 

 

 

 

2차원 배열 생성

# 모든 성분이 0인 3 x 4 크기의 2차원 배열
array = [[0] * 3 for _ in range(4)]
# [0] * 3 => [0, 0, 0]

print(array)
# [[0,0,0], [0,0,0], [0,0,0], [0,0,0]]

# 잘못된 사용
array = [[0] * 3] * 4

2차원 배열을 생성할 때 매우 유용하게 사용할 수 있다.

('_'는 0, 1, ...,  n의 값을 가질테지만, 사용하지 않는 값이라는 뜻으로 '_'로 표시한다.)

 

잘못된 사용은 [0, 0, 0]라는 배열 하나를 생성하고, 같은 위치를 참조하는 4개의 배열을 생성한다.

즉, 동일한 배열([0, 0, 0]) 하나를 세 번 참조하는 것이므로 의도와 다르다.

 

 

 

일반적 코드와의 비교

## 리스트 컴프리헨션
# 0 ~ 19까지의 홀수
array = [i for i in range(20) if i % 2 == 1]
print(array)

## 일반적인 코드
# 0 ~ 19까지의 홀수
array = []
for i in range(20) :
	if i % 2 == 1 :
    	array.append(i)
print(array)

리스트 컴프리헨션이 얼마나 간결한 기능인지 알 수 있다.

 

 

 

 

반응형
반응형
 

[무료] 따라하며 배우는 NestJS - 인프런 | 강의

이 강의를 통해 NestJS에 대해서 배울 수 있습니다., - 강의 소개 | 인프런...

www.inflearn.com

 

 

 

개요

인프런에서 제공하는 Nest.js 무료 강의.
다른 인프런 무료강의들처럼 유튜브로 배포된 영상을 강의형태로 모았다.

쉽고 재밌습니다.

 

 

 

 

 

 

강의 후기

 

 

🔎 학습 내용

- Nest.js 기본 요소 설명(MVC 패턴에 대한 간략한 설명도)
- 간단한 CRUD 구현 (DB 연결 X)
- Pipe 이용(유효성 체크 등을 위한 미들웨어)
- DB 연동 후 CRUD 수정(Postgresql & TypeORM)
- JWT를 활용한 인증 로직 구현
- 게시물 접근 권한 로직 구현
- 그 외 (Log, Configuration)

 

 

 

 

 

 

🔎 학습 시간

- 강의시간 : 약 10시간
- 공부시간 : 약 20시간

 

 

🔎 수강 조건

- 웹 프레임워크(Express면 더 좋고)에 대한 기본적인 이해

이해가 없어도 들을 수 있는 난이도이기는 하지만, 기초적인 것을 다 설명해주시지는 않기 때문에 기본적인 이해는 필요할 것 같다.

 

 

 

🔎 수강 대상

- Nest.js 기초를 빠르게 잡고 싶은 사람
- Express 개발자 (Nest 함 써보세요 편합니다 ^^)

 

 

 

 


주관적 평가

 

 

👍 좋았던 점

1) 적당한 난이도
어렵지는 않지만 직접 프로젝트를 만들 수 있을 정도의 예제로 구성되어 있어 좋았다! 강의 수강 후 바로 개발 시작하면 될듯.

 

2) 깔끔한 구성

유튜브에 배포된 강의가 맞나 싶을 정도로 강의 구성이 깔끔했다.

 

3) 왜케 재밌지?

너무 재밌어가지고 밥 먹을 때도 자꾸 다음 강의 생각나고 그래서 하루 만에 다 들었다.

 

 

 

 

 

👎 나빴던 점

버전 문제가 좀 있는데요, 강사님 깃에서 package.json, package.lock.json 그대로 복사해오면 해결되더라구요..

 

 

 


프로젝트 기술 스택을 Express에서 Nest.js로 옮기기 위해 급하게 들었던 강의.
아티클이랑 깃허브 리파지토리 뒤져서 그냥 시작할까하다가, 강의 한 번 들어보고 싶어서 들었는데
너무 잘한 선택이었다!

 

후기 끝.

 

 

 

 

 

 

 

반응형
반응형

나는 빠르게 공부하고 프레임워크 공부로 넘어가야했기 때문에

가장 인기 있는 교재인 '자바의 정석'은 길이가 너무 길어 패스했다. (나중에 필요하면 보는 걸로~)

 

Java의 기초를 다지기 위해

생활코딩의 '생활코딩 JAVA 입문 수업',

위키독스의 '점프 투 자바'

두 가지 자료를 모두 정독했다.

 

각각의 특징과 추천 대상에 대해 얘기해보고자 한다.

 

 

 

 

생활코딩 - JAVA 입문 수업

 

생활코딩 JAVA 입문 수업 - 생활코딩

본 수업은 2019년에 제작된 자바 수업으로 2013년에 제작된 생활코딩 JAVA 수업의 리뉴얼된 수업입니다.  수업소개 이 수업은 가장 인기있는 컴퓨터 언어인 Java의 기본을 알려드리는 수업입니다.

opentutorials.org

유튜브 동영상 강좌로 진행된다.

 

이 수업은 정확히 Java 강의라기보다는,

Java의 기초를 알려주고 그것을 활용해 프로그래밍 전반에 입문시키는 강의라고 하는 게 정확하겠다.

 

프로그래밍을 아예 처음 시작했다고 가정하고,

프로그래밍이란 무엇인지, 우리가 이것을 왜 공부하고 어떻게 적용하며 발전시켜 나갈 것인지,

초심자가 방향을 잃지 않고 발전할 수 있도록 태도, 공부법 등에 대해서 함께 일러준다.

심금을 울리는(?) 문장들을 자주 들을 수 있다.

 

프로그래밍이 처음이라면 아주 도움이 되겠으나,

이미 프로그래밍을 공부한 상태에서 Java를 공부하고 싶은 것이라면 난이도가 낮고 부연설명이 길다고 느낄 수 있겠다.

그래서 나는 웬만한 내용은 스킵하면서 아주 빠르게 완강했다.

 

 

 

 

위키독스 - 점프 투 자바

 

점프 투 자바

**초보 프로그래머를 위한 자바 입문서** 이 책은 문법위주의 지식보다는 이해중심의 지식을 전달하는 것을 주 목적으로 한다. 예를 들어 자바에서 잘 파악하기 힘든 개념 ...

wikidocs.net

위키독스를 만드신 '박응용'님께서 만드신 자료.

동영상 강의는 아니고, 인터넷에 배포된 자료(책)을 따라가는 구조다.

 

언어 전반에 대한 내용은 다루면서, 깊이가 너무 얕지도 깊지도 않다고 느꼈다.

다른 언어를 공부한 경험이 있다면, 90~100%를 어렵지 않게 소화할 수 있을 것이다.

 

다만 프로그래밍이 처음이라면, 조금 어려움을 겪을 수 있겠으나

천천히 이해하면서 진행한다면 크게 무리는 없을 것이다!

 

설명과 비유, 그리고 내용이 너무 좋았다!

문제 난이도도 적당해서 재밌게 풀면서 넘어갔다.

 

개발을 어느정도 경험하고 다시 보니, 점프 투 자바는 진짜 개발에 필요한 내용 위주로 간결하게 다룬 것이라는 것을 깨달았다.

 

 

 

 

 

총평

- 프로그래밍이 처음이다 -> 생활코딩

- 다른 언어를 공부해본 경험이 있다 -> 위키독스(점프 투 자바)

 

자바를 오래 쓸 거라면 '자바의 정석' 같은 자세한 기본서를 보는 것이 참 좋겠지만!

빠르게 공부 후 개발을 진행해야 한다면 '점프 투 자바'를 진짜 강추한다.

 

프로그래밍 초심자가 Java를 통해서 프로그래밍에 입문하고자 한다면, 생활코딩의 강의를 추천한다.

강사님의 말씀 하나하나가 좋은 개발자로 성장하는 데에 방향키가 되어줄 것이라고 생각한다.

다만 그 깊이를 더하고 싶다면, 완강 후 '점프 투 자바'를.. 공부해보시길..

 

 

 

 

 

반응형
반응형

 

" Shout Our Passion Together "

 

 

 

 

The SOPT 활동이 끝나간다.

서버 파트원으로서 세미나, 스터디, 그리고 대망의 앱잼까지 다양한 경험을 통해 많은 것을 느끼고 배울 수 있었다.

개발 경력 2달짜리 JB였던 나에게 과분할 만큼 많은 지식과 경험이 쏟아지는 시간이었다.

 

자부할 만큼 많은 것을 배운 경험도, 더 열정을 쏟지 못해 아쉬웠던 경험도 떠오른다.

그중에서도 기술적으로 성장한 부분과 아쉬웠던 부분을 기록해보고자 한다.

 

동아리 활동에서 얻은 엄청난(?) 감상들은 네이버 블로그에 정리해보았다.

 

27년 만에 알게 된 나 - 솝트 30기 회고(The SOPT 30th server)

개발자가 되고자 들어간 솝트에서 27년 동안 몰랐던 나에 대해 알게 되었다. 사실 이건 너무 당연한 말이다...

blog.naver.com

 

 

 


 서버 파트 세미나 

1주차 세미나 때 충격을 아직도 잊지 못한다. 파트장님의 세미나 강의는 내가 들었던 어떤 강의보다 명료했다.

하지만, 아무런 CS 지식이 없는 나는 쓰레드가 어쩌고 큐가 어쩌고 하는 내용들을 거진 알아들을 수 없었다.

더군다나 매주 4시간의 세미나 내용은 시중 프로그래밍 강의 만큼이나 내용이 꽉차서 복습하는 데 거진 두세배의 시간이 걸렸다.

 

아무튼 나는, 이해가 안 되는 내용은 될 때까지 복습하고 정리하면서 최대한 모든 내용을 따라가려고 노력했다.

 

Javascript, Typescript

Python만 조금 다뤄본 나는 새로 배운 Javascript가 너무 어색했다. 사실 처음에는 문법이 간결한 Python이 그리워 JS에 정 자체가 붙지 않았다. 그런데 TS까지 이해하려니 코드를 칠 때마다 혀에서 피맛이 나는듯 거부감이 들었다.

 

그래도 어렵게 들어온 동아리, 최선을 다해보자며 세미나 복습, 유튜브 강의, 각종 아티클로 어찌저찌 따라갔다. 지금은 TS 사용이 전혀 어색하지 않고, Python 만큼이나 생각하는 것을 코드로 표현할 수 있게 된 것 같다.

 

특히 기억에 남는 내용은 Promise에 관한 것.

사실 아무리 복습하고, 아티클을 수십 개(구라 아님) 읽어봐도 도무지 이해가 되지 않던 내용이 Promise와 Async, Await이었다.

너무 열 받아서 이틀을 내리 Promise에 꼴았다. 이해가 될 때까지 강의와 아티클을 찾아봤고, 결국 나름의 방식대로 이해해서 정리했다.

 

[Javascript] 동기/비동기 정리(3) - JS 초짜가 async/await 완벽하게 이해하기(+Typescript로 변환까지)

헷갈리는 동기, 비동기 개념을 정리하는 포스팅 (3) 1) callback에 대한 이해🔗 : https://woojin.tistory.com/27 2) JS 초짜가 Promise 완벽하게 이해하기🔗 : https://woojin.tistory.com/28 이번 포스팅은, asy..

woojin.tistory.com

 

 

 

Node.js, Express, MongoDB

세미나에서 다룬 기술 스택 3개.

처음 접할 때는 모든 게 어색했다. 간신히 익혔던 Django의 MTV 패턴과도 비슷한 듯 달랐고, 디렉토리 구조도 너무 달랐다. 어느 파일이 어디서 어떤 역할을 하는지 하나도 감이 오지 않았다.

 

하지만 파트장님의 선물인 보일러 플레이트를 반복해서 사용하면서 처음 다뤄보는 MVC 패턴과 컨트롤러 서비스 로직 분리, 각종 모듈과 타입 명시 파일의 분리된 구조를 완전히 이해할 수 있었다. 요청이 들어와 미들웨어와 라우터를 거쳐 서버 내부의 각 단에 전달되고, 가공되고, Response되기 까지의 과정을 나름대로 잘 이해할 수 있었다. 심지어는 구조가 너무 달라 혼동되던 Django의 구조도 더 명확하게 이해할 수 있었다. 이래서 '프레임워크는 도구일 뿐'이라고 말하는 듯싶었다.

 

MongoDB는 사실 세미나 때 사용하고 앱잼 때 사용해보지 못해서 조금 아쉽지만, 그래도 나름대로 열심히 이해하고 사용해보았다.

꼴랑 2달 공부한 JB였지만, SQLD도 따고 프로젝트 DB도 직접 설계해본 헛짬바로 관계형 DB가 너무 익숙했다. 비관계형 데이터베이스에서 어떻게 연관관계를 표현할 것이며, 어떻게 효율적인 스키마 구조를 설계할 수 있을지 도무지 감이 오지 않았다. 아직도 의문이 완전히 풀리지는 않았지만, 관계형과는 다른 특성을 조금은 이해하고 참조가 아닌 직접 조회를 효율적으로 수행하기 위한 스키마를 설계해야 함이 조금은 와닿게 느껴진다.

 

 

 

 스터디 

The SOPT(솝트 30기)에서 내가 활동한 스터디는 금잔디조, AWS 스터디(이하 파트 스터디), 코테 스터디, 회고 스터디(이하 전체 스터디) 총 4개였다.



금잔디조

금잔디조는 서버 파트 YB, OB가 섞여서 필수로 지정되는 세미나 코드 리뷰 그룹이다. 사실 스터디라고 보기엔 애매하지만, 금잔디로부터 너무 많은 것을 배웠기에 적고 넘어가고 싶다. 

우선 세미나에 열정을 다했기에 나올 수 있었던 많은 질문들이 오갔다는 것이 좋았다. 그리고 최선을 다해 답변해주던 친구들에게 너무 고맙다. 처음에는 사람이 이렇게 착할 수가 있나 싶어 의구심도 들었지만, 개발 생태계에서 지식 공유에 기여하는 것이 본인의 발전과 명성에도 보탬이 되는 일이라는 것을 알고 나니 이해가 되었고, 더욱 멋져 보였다.

알찬 답변에 관련 아티클까지 찾아봐주던 조장님..
우리만 보는 금잔디조 노션 페이지에 쌓인 어마어마한 양의 아티클

 

AWS 스터디

가장 아쉬움이 많이 남는 스터디.. 하지만 사람을 얻었다(?)

Udemy에서 구매한 AWS 자격증 강의를 함께 듣는 스터디였다. 인프라 공부는 역시 너무 생소했고 어려웠다. 목표만큼 강의를 많이 듣지는 못했지만, 부분부분 공부한 내용들이 앱잼 때 서버 인프라를 구축하며 도움을 주어 신기했다. Route53 사용법, ELB의 역할, 말로만 듣던 CI/CD의 정의와 구현 방법에 대해 배울 수 있었다. Key와 IAM 계정을 통해 보안을 지키는 방법 또한 익힐 수 있었다.

 

 

코테 스터디

사실 다른 것에 바빠 우선순위가 밀렸..지만(강의를 듣는 형식의 스터디였다) 인상적인 순간이 남아 기록하고 싶다.

솝트 내외로 꽤 유명하신 분께서 스터디를 준비하고 강의해주셨는데, 내용이 알찬 것은 물론이고 그 모습이 너무 멋있었다. 솝트 활동을 하면서 나도 많은 사람을 대상으로 무언가 지식을 전하는 경험을 반드시 해야겠다고 마음을 먹게 되었다.

 

 

회고 스터디

는 감상적인 내용이 가득해 이곳에 적지 않겠지만.. 나에겐 솝트 활동의 척추뼈(?)와 같은 존재였다.

 

 

 

 

 앱잼 

3주 간의 장기 해커톤 앱잼. 딜리버블이라는 서비스를 만들게 되었고, 명실상부 쌉고수 Sigrid와 함께 서버파트를 맡게 된다.

Sigrid의 리드 하에 Express, MySQL, TypeORM을 사용한 프로젝트를 만들었다. 또한 AWS를 활용한 다양한 인프라적 경험도 했다.

짱리버블 가족들

TypeORM과 Repository 구조

세미나에서 다루지 않았던 새로운 스택을 사용하기로 했다. 사실 세미나에서 다뤘던 스택을 제대로 사용해보고 싶은 마음이 있었지만, 새로운 것을 배우는 것도 좋은 경험이 될 것 같다고 생각해 받아들였다. 다만 웹 프레임워크도 바꾸자는 제안은 완곡하게 거절했다. 배운 것을 써먹어는 보고 싶었기 때문.

 

TypeORM을 사용하면서 Repository를 따로 분리했다. 기존에는 Service 단에서 비즈니스 로직과 더불어 DB에 접근하는 로직까지 포함했다면, 이번 프로젝트에서는 DB에 접근하는 로직을 Repository로 분리했다. 책임을 분리하는 방법과 이점에 대해서 처음 고민하고 배울 수 있는 시간이었다.

 

 

디미터 법칙과 객체 지향

객체 지향이란 그저 어디서 주워들은 단어에 불과했다. 제대로 된 공부도 해보지 못한 채로 객체 지향적인 코드를 고민했다. Sigrid는 나에게 디미터 법칙을 소개하고 그것을 고민한 코드를 짜보라는 미션을 선물한다. 부랴부랴 아티클을 읽고 고민하며 코드를 작성한다. 그렇게 객체 지향적인 코드를 짜게 되었냐고 스스로 반문한다면 아니라고 대답할 것이다. 하지만 아무 고민 없이 구현만 되는 코드를 짜던 나에게 어떤 제동이 걸렸고, 그것을 공부하기 위한 허들이 매우 낮아졌다는 것만으로도 큰 의미가 있는 경험이었다.

 

 

AWS 인프라

Sigrid가 나에게 처음 제시한 미션은 VPC와 서브넷을 구축하는 것이었다. 디폴트로 생성되는 그것 말고, 새롭게 생성한 서브넷에 우리가 사용할 EC2 인스턴스와 RDS 인스턴스를 집어넣고 안전하게 관리하는 인프라를 구축하라는 것이었다.

그것도 아주 간단한 한 마디 말로 전달한 미션이었다. "VPC 한 번 구축해볼래요?" 말은 쉽지. 드릅게 어려웠다.

그렇게 개발자의 마인드를 배울 수 있었다. 하면 되는 것이다. 어렵고 쉽고는 존재하지 않았다. 해서 되는 것과 되지 않는 것만 존재할 뿐.

(The SOPT 서버파트 블로그에 아티클도 게재했다.)

 

VPC, 서브넷 설정으로 RDS에 안전하게 접근하기!

✏️ 작성자: 우진 📌 작성자의 한마디: "AWS 털리기 전에 외양간 고칩시다." ???: AWS가 털려서 900만원 낼뻔 했어. 개발자라면 누구나 들어본 AWS 괴담. 우리가 그 주인공이 되어 우리의 소를 다 털

velog.io

 

SSL 인증서를 연결하고 Load Balancer를 이용해 HTTPS로 연결하는 경험도 했다! 클라이언트 단에서 API 연결을 위해 HTTPS 주소가 필요하다고 했다. 임시 방편으로 할 수 있는 방법들이 있었지만, 그보다는 실제 인증서를 구매해 적용해보기로 한다.

Route 53, Elastic Load Balancer 등의 기술을 사용했는데, 아티클을 아무리 보면서 따라해도 과정이 이해되지는 않았다. 하지만 다양한 시행착오를 겪고 그것을 해결하면서, 각 과정이 어떤 의미를 가지고 있는지 대략적으로 이해되기 시작했다. 가령 ELB에서 HTTP 요청(80번 포트)이 HTTPS(443번 포트)로 리다이렉트되면서 SSL 인증을 받는다던가 하는..

막연하기만 했던 인프라 구축에 대한 자신감을 얻을 수 있었다.

 

 

Git 협업 방식

Git 공부를 미루고 미루다 앱잼까지 Git 감자 상태였던 나는, Sigrid와의 협업을 통해 깃 브랜치 전략과 Issue, PR을 통한 협업 방식을 체득할 수 있었다. Git을 반드시 기초부터 공부하고 GUI 툴까지 사용해서 Git 마스터가 되리라.

 

 

다양한 코드 구현 방식

그 외에도 다양한 방식의 코드를 접하며 익힐 수 있었다. map, filter와 같은 Array 메서드를 적재적소에 사용해보기도 했고, DB에서 쿼리로 조회해온 데이터를 객체 내부의 메서드로 다시 정렬하거나, 생성자를 사용하는 여러가지 용례에 대해서도 배울 수 있었다.

 

 

 

 


그 밖에도 많은 사람에게 많은 배움을 얻어가는 한 학기였다.

 

솝트에는 잘하는 사람들과, 열정 넘치는 사람들이 혼재했다.

그들과 함께 호흡하며 공부할 수 있어 정말 영광이었고, 이제야 조금은 이 생태계에 일원으로서의 감정을 느껴 기분이 좋다.

 

멋지게, 그리고 아주 격하게 성장해서 나의 배움을 많은 사람들에게 공유하고 싶다는 꿈을 꾸는 지금이다.

그런 꿈을 이룬 미래의 어느 한 지점에서, SOPT 30기 활동은 나의 발전의 기폭제였다며 자랑스럽게 말할 것이다.

 

 

 

 

 

 

 

 

 

 

 

 

반응형
반응형

EC2에 띄울 프로젝트(Django)가 MySQL과 연동된 상태라

EC2 내부에 MySQL을 설치하고 연결하고자 한다.

 

AWS는 RDS라는 데이터베이스 서비스를 제공 중이고, MySQL을 지원한다.

보안, 운영 측면에서 상당히 괜찮은 서비스라 실제 운영 환경에서 많이들 사용한다는데,

우선은 테스트용 배포이기 때문에 MySQL을 직접 연결하기로 했다.

 

 

 

 

 

MySQL과 AWS EC2 연결하기

MySQL 사용할 포트(3306번) 접속 허용하기

AWS 콘솔에서 보안 그룹에 들어간다.

그리고 사용 중인 보안 그룹의 이름을 클릭한다.

(사용 중인 보안 그룹의 이름을 모른다면, 사용 중인 EC2의 요약 페이지로 들어가 하단의 '보안' 탭에서 확인할 수 있다.)

 

 

'인바운드 규칙 편집' 클릭

 

아래와 같이 규칙을 추가하고 저장한다.

 

 

 

EC2에 MySQL 설치 후 접속하기

우선 AWS EC2 인스턴스에 접속한다.

 

apt를 업데이트한다.

sudo apt update

 

mysql-server를 다운로드 한다.

sudo apt install mysql-server

중간에 'After this operation, 156 MB of additional disk space will be used.' 라고 묻는데,

Y를 입력해주자.

 

아래 명령어로 mysql 설치 여부를 확인한다.

mysql --version

 

mysql에 접속하기 위해 mysql -u root -p 명령어를 사용하면

거절당한다!

 

아래처럼 sudo를 사용해야 접속이 가능하다.

sudo mysql -u root -p

비밀번호는 설정이 되어있지 않아서, 그냥 엔터 한 번 더 치면 위와 같이 접속이 된다.

 

 

root 계정 비밀번호 설정

mysql 이라는 이름의 데이터베이스를 사용한다.

use mysql

 

root 계정의 비밀번호를 변경한다.

alter user 'root'@'localhost' identified with mysql_native_password by '비밀번호';

 

변경사항을 적용시키고 종료한다.

FLUSH PRIVILEGES;
exit

 

 

외부 접속 허용하기

외부 접속을 허용하기 위해 mysqld.cnf 파일을 수정해야 한다.

 

우선 아래 명령어로 root 권한을 부여한다.

sudo su

 

mysqld.cnf 파일이 있는 디렉토리로 이동한다.

cd /etc/mysql/mysql.conf.d

ls 명령어로 해당 디렉토리에 mysqld.cnf 파일이 있는지 확인할 수 있다.

 

vi 에디터로 mysqld.cnf 파일을 실행한다.

vi mysqld.cnf

위와 같이 파일이 열릴텐데,

하단의 bind-address0.0.0.0 으로 수정할 것이다.

 

1. i : 편집 상태로 변경 (하단에 INSERT 라고 뜨면 편집 상태)

2. 해당 부분 수정 후 esc를 눌러 다시 읽기 상태로 전환

3. :wq 커맨드 입력해서 저장하고 종료

 

이후에 mysql 서버를 재시작한다.

service mysql restart
mysql -u root -p

아까 설정한 비밀번호도 입력해주어야 한다.

 

 

root 유저를 계속 사용하는 것은 부적절하다고 한다.

test 라는 이름의 유저를 만들어 권한을 부여하자.

CREATE USER 'test'@'%' IDENTIFIED BY '비밀번호';

 

아래 명령어로 권한을 부여한다.

GRANT ALL PRIVILEGES ON *.* TO test@'%';

 

 

MySQL Workbench로 연결 테스트하기

Workbench는 MySQL GUI 툴인데,

설치 및 사용 관련해서는 생략하겠다.

 

Workbench 홈에서 빨간색 박스 안의 (+) 버튼을 클릭한다.

 

Connection Name은 임의로 설정,

Hostname은 EC2 인스턴스의 퍼블릭 IP 주소,

Store in Keychain은 클릭해서 password에 아까 설정한 MySQL 유저 비밀번호 설정

 

그리고 하단의 Test Connection을 클릭하면 테스트 연결이..!

완료되었다!

 

 

이제 EC2에 배포한 웹서버와 MySQL을 연결하고 사용할 수 있다. 후..

 

 

 

 

 

참고 링크1 : https://velog.io/@issac/AWS-EC2%EC%97%90-MySQL-%EC%84%9C%EB%B2%84-%EA%B5%AC%EC%B6%95%ED%95%98%EA%B8%B0

참고 링크2 : https://mirae-kim.tistory.com/73

 

 

반응형
반응형

프로젝트의 프론트엔드 개발자가, 서버가 배포되지 않으면 개발하지 않겠다고 선언.

부랴부랴 EC2에 띄우고자 겪은 시행착오들을 묶어서 정리.

 

 

본 포스팅에서는,

1. AWS EC2 인스턴스를 생성하고

2. Github에 올라가 있는 Django 프로젝트를 AWS EC2에 배포하고

3. 터미널을 꺼도 24시간 서버가 돌아가도록 설정하는 내용을 다룬다.

-> 처음에는 백그라운드에서 직접 실행, 두번째는 백그라운드에서 동작하는 가상 터미널인 screen을 활용

 

- 프리 티어(무료버전) 서버를 사용한다.

- MacOS를 사용한다.

 

 

AWS EC2 인스턴스 생성

우선 계정을 만들고 로그인한다.

 

클라우드 서비스 | 클라우드 컴퓨팅 솔루션| Amazon Web Services

개발자, 데이터 사이언티스트, 솔루션스 아키텍트 또는 AWS에서 구축하는 방법을 배우는 데 관심이 있는 모든 사용자용 무료 온라인 교육 AWS 전문가가 구축한 500개 이상의 무료 디지털 교육 과정

aws.amazon.com

 

 

우측 상단에서 리전을 서울로 설정한다.

 

 

EC2 대시보드로 이동해 인스턴스를 시작한다. (상단의 서비스 탭 또는 검색을 통해 쉽게 찾을 수 있다.)

 

 

이름 설정

애플리케이션 및 OS 이미지 - Ubuntu / 18.04(프리 티어 사용 가능)

인스턴스 유형 - t2.micro(프리 티어 사용 가능)

키페어 생성 - 이름 설정 / RSA / .pem(Windows의 경우 .ppk 사용) --> 반드시 기억할 수 있는 곳에 저장해두어야 함.

네트워크 설정 - 인터넷에서 HTTPs 트래픽 허용 체크, 인터넷에서 HTTP 트래픽 허용 체크

 

위의 내용만 건드리고 '인스턴스 시작'을 누른다.

 

실행 중인 인스턴스의 이름을 클릭하면 아래와 같은 화면이 나온다.

 

우측 상단의 '연결'을 클릭해서 EC2를 실행시켜보자.

위와 같은 화면이 보일텐데, 터미널을 우선 실행한다.

그리고 인스턴스 생성 시 키를 저장한 디렉토리로 이동한다.

 

나는 djangoUnimate 안의 keys 폴더에 키를 저장해두었다.

 

그리고 위 화면의 빨간색 동그라미 부분을 클릭하여 코드 라인을 차례로 복사해 붙여넣는다.

그럼 아래와 같은 문구가 보이면서 EC2 인스턴스에 접속이 완료된다.

sudo apt update
sudo apt install python3
sudo apt install python3-pip
sudo apt install virtualenv
pip install virtualenv

ubuntu@ip- 위에 나오는 ip 주소는 EC2 인스턴스의 프라이빗 IP 주소이다.

 

또한 우리가 사용할 8000번 포트에 대한 보안 설정을 미리 해놓자.

좌측의 보안 그룹을 클릭하고,

인스턴스의 보안 그룹 ID를 클릭한다. (보안 그룹 ID가 여러 개라 헷갈린다면, 사용 중인 인스턴스 요약으로 돌아가, '보안' 탭을 클릭하면 보안 그룹 정보를 얻을 수 있다.)

 

좌측 하단의 '인바운드 규칙 편집'에 들어간다.

 

위와 같이 8000번 포트를 허용한다는 규칙을 만들고 저장한다.

 

 

 

 

 

Django 프로젝트 배포하기

우선 로컬에서, requirements.txt를 만들고 Github에 push한다.

requirements.txt는 해당 프로젝트에 사용하는 프레임워크, 라이브러리의 버전 정보를 저장하고 있는 것으로,

명령어 한 줄로 해당 버전에 맞는 프레임워크, 라이브버리를 모두 설치할 수 있게 도와준다.

관련 내용은 검색을 통해 쉽게 확인할 수 있다.

 

Github 리파지토리에 push하는 일련의 과정은 생략하겠다.

 

Github에 올라간 프로젝트를 clone해오는 과정부터 정리해보겠다.

 

우선 위에서 접속한 ubuntu 서버에서 아래와 내용을 차례로 입력한다.

sudo apt update
sudo apt install python3
sudo apt install python3-pip
sudo apt install virtualenv
pip install virtualenv

 apt는 패키지 관리 시스템이고,

python과 pip를 설치한다.

virtualenv는 가상환경을 만들기 위해 설치한다.

 

이후 아래 코드를 입력해 가상환경을 생성한다.

virtualenv venv --python=python3

ls 명령어를 통해 venv 폴더가 생김을 확인할 수 있고,

 

아래 코드를 입력해 가상환경에 접속한다.

source venv/bin/activate

위처럼 좌측에 (venv)가 뜨면 가상환경에 접속한 상태이다.

 

이번엔 Github에서 장고 프로젝트를 가져온다.

가져올 리파지토리에 들어가서 Code의 HTTPS 주소를 복사해온 후,

터미널에서 아래 코드를 입력한다.

git clone <리파지토리 주소>

 

이번에는 깃에 올라가 있지 않은 settings.py를 가져온다.

(필자는 그 외에 my_settings.py라는 파일도 추가해주었다.)

 

터미널에서 원하는 디렉토리로 이동 후,

vi settings.py

위와 같이 입력한다.

 

그리고 로컬의 settings.py 코드를 모두 복사해서

터미널에 붙여넣는다.

 

:wq 라는 명령어로 저장 후 종료한다.

 

이제 runserver 명령어로 django 서버를 실행시킬 수 있다.

(단, DB 연결이 되어있지 않은 경우 실행이 어려울 수 있다. 필자는 MySQL이 연결되지 않아 실행이 되지 않았고, 해당 내용은 다음 포스팅에 작성한다.

 

이때, migrate 명령어를 사용하라는 문구가 발생할텐데, migrate도 한 번 해주면 된다.

 

서버를 실행할 때는 아래와 같이 입력해야 한다.

python3 manage.py runserver 0.0.0.0:8000

뒤의 주소를 적지 않으면 실행이 되지 않는다.

 

위와 같이 django 서버가 실행되면 완료!

 

 

 

 

 

 

 

터미널 꺼도(SSH 연결 끊겨도) 서버 연결하기

실행된 서버를 백그라운드로 넘기면, 터미널을 종료해서 서버가 계속 실행된다.

아래와 같이 터미널에 입력한다.

 

python manage.py runserver 0.0.0.0:8000 --> 장고 서버를 실행한다.

ctrl + z --> 해당 프로그램을 정지시키고 shell로 돌아온다.

bg --> 백그라운드로 보낸다.

disown -h --> ssh 연결이 끊어져도 백그라운으로 보낸 프로세스를 실행한다.

 

이후 터미널을 종료해도, 장고 서버에 접속할 수 있다.

 

아래 명령어는 리눅스 명령어로,

tcp 8000번 포트로 실행 중인 프로세스를 종료하는(kill) 명령어이다.

즉, 백그라운드에서 실행 중이던 장고 서버를 종료한다.

>> sudo lsof -t -i tcp:8000 | xargs kill -9

 

그런데..!

 

특정 api에서 아래와 같은 오류가 발생한다.

 

아.. 여기서 아주 크게 절망한다.

찾아보니 MySQL(DB) 연결이 되지 않는 문제일 가능성이..?

 

정확한 원인은 모르겠어서,

일단 직접 EC2에 설치한 MySQL 말고

RDS 인스턴스를 만들어서 연결한다.

 

그랬더니..!

 

또 안 된다. 그렇게 찾고 또 찾아서 발견한 방법이 바로,

리눅스 가상 터미널인 screen이다!

 

 

진짜로 터미널 꺼도(SSH 연결 끊겨도) 서버 연결하기 (screen 활용)

참고 문서 : https://dailyheumsi.tistory.com/19

 

screen은 리눅스 가상 터미널로,

터미널을 물리적으로 다중화하여, 백그라운드에서 터미널을 실행할 수 있는 프로그램이라고 한다.

screen을 사용해서, 터미널을 꺼도 runserver가 구동되게 하자!

 

우선 screen을 설치한다.

sudo apt-get install screen

 

그리고 screen을 생성한다.

screen -S test 	// test는 screen 이름

 

생성된 스크린을 조회해보자.

# 현재 생성된 screen list 조회
screen -ls

There is a screen on:
        7783.test (07/02/2022 02:10:13 AM)        (Attached)

 

7783이라는 네 자리 숫자가 스크린의 id이다.

Attached는 해당 스크린에 현재 접속해있는 상태라는 표시이다.

 

ctrl + a + d 를 누르면 해당 스크린에서 빠져나올 수 있다.

그 후 아래와 같이 다시 조회해보자.

 

# 현재 생성된 screen list 조회
screen -ls

There is a screen on:
        7783.test (07/02/2022 02:10:13 AM)        (Dettached)

AttachedDettached로 바뀐 것을 볼 수 있다.

해당 스크린을 빠져나온 것이다.

 

이번에는 스크린에 들어가서, runserver를 구동하고 도망나올 것이다.

# 7783 id를 가진 screen으로 다시 attach
screen -r 7783

# 7783.test screen 으로 들어온 상황
python3 manage.py runserver 0.0.0.0:8000

System check identified no issues (0 silenced).
September 30, 2018 - 21:50:28
Django version 2.1.1, using settings 'ypc.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

이 상태에서 ctrl + a + d 로 screen에서 빠져나온 후,

터미널을 종료해보자.

 

EC2의 주소와 8000번 포트를 사용해 서버에 접속하면

잘 구동되고 있음을 확인할 수 있다 !

 

 

(대충 감격해서 엉엉 우는 짤)

 

 

 

 


위와 같은 과정을 통해

Django 서버를 AWS EC2에 배포하고, 24시간 접속이 가능한 환경을 구축했다.

이제 프론트에 거센 채찍질을 할 차례이다.

 

 

 

 

 

 

반응형

+ Recent posts