[python] 파이썬 알고리즘 인터뷰 - 리스트, 딕셔너리
파이썬에서 가장 빈번하게 사용되는 자료형 1. 리스트 2. 딕셔너리 이 두 가지 자료형은 모든 문제에 빠짐없이 쓰이는 자료형이므로 확실히 이해 하기! 1. 리스트 순서대로 저장하는 시퀀스(입력한 순서대로 유지된다) 숫자 외에도 다양한 자료형과 함께 저장 가능 (ex. [1, 2, 3, 5, 4, '안녕', True] ) 변경 가능한 (Mutable List) 동적 배열로 구현된 장점 스택을 사용할 지, 큐를 사용할 지 고민하지 않아도 됨. 이말은 즉, 리스트가 스택과 큐에서 사용 가능한 모든 연산을 함께 제공한다는 뜻. 리스트의 주요 연산 시간복잡도 연산 시간 복잡도 설명 len(a) O(1) 전체 요소의 개수를 리턴 a[i] O(1) 인덱스의 i 요소를 가져옴 a[i : j] O(k) i 부터 j-1 ..
2024.03.12
no image
[python] 파이썬 알고리즘 인터뷰 - 빅오, 자료형
빅오(O, big - O) 입력값이 커질 때 알고리즘의 실행 시간(시간 복잡도)과 함께 공간 요구사항(공간 복잡도)이 어떻게 증가하는 지를 분류하는 데 사용 입력값이 무한대로 향할 때 함수의 상한을 설명하는 수학적 표기 방법 점근적 실행 시간을 표기할 때 사용하는 것이 빅오이다. 점근적 실행 시간(알고리즘을 수행하는 데 걸리는 시간을 설명하는 계산복잡도) 은 달리 말하면 시간복잡도 이다. 빅오 표기법 최고차항만을 표기, 계수는 무시한다. O(1) : 입력값이 아무리 커도 실행 시간은 일정함 예시) 해시 테이블의 조회 및 삽입 O(log n) : 매우 큰 입력값에도 크게 영향을 받지 않는 편 예시 ) 이진 검색 O(n) : 입력값만큼 실행시간에 영향을 받음. 시간은 입력값에 비례 선형 시간 알고리즘이라고 ..
2024.02.28
no image
[python] 파이썬 알고리즘 인터뷰 : 2일차 - 파이썬 문법
파이썬 고급 문법에 대해 알아보자 # 인덴트 공백 4칸을 원칙으로 함. 첫번째 줄에 파라미터가 있으면 -> 파라미터가 시작되는 부분에 보기 좋게 맞춘다. 첫번째 줄에 파라미터가 없으면 -> 공백 4칸 인덴트를 한 번 더 추가하여 다른 행과 구분되도록 한다. # 첫 줄 파라미터 있을 때 foo = long_func_name(var_one, var_two, var_three, var_four) # 없을 때 def long_func_name( var_one, var_two, var_three, var_four): print(var_one) # 네이밍 컨벤션 파이썬 변수명 네이밍 컨벤션은 자바와 다르다. 스네이크 케이스를 기본으로 한다. 자바 : 카멜 케이스(단어를 대소문자로 구분하여 섞어서 작명하는 방식) 파..
2024.02.02
[python] 파이썬 알고리즘 인터뷰 : 1일차
파이썬 알고리즘 인터뷰 라는 책으로 코딩테스트 연습을 해보고자 한다. 각각의 장에서 배운 것들을 정리하고 익히도록 하겠다 ~.~ 책을 활용하면서 필요한 것들 문제 풀이 소스코드 다운 및 학습 동영상 1. 깃허브 소스코드 : https://github.com/onlybooks/python-algorithm-interview 2. 유튜브 학습 동영상 : https://www.youtube.com/watch?v=ngHIVey3J6Y 2장 프로그래밍 언어 선택 # 파이썬을 활용한 루프 구조 구현 파이썬은 한 줄로도 루프 구현 가능 그러나 지나친 사용은 가독성을 떨어뜨릴 수 있으므로 적절하게 사용하는 것이 중요. #파이썬(Python) # 예시 1 sum = 0 for i in range(1, 10 + 1): s..
2024.02.01
no image
[AWS] Amazon Cognito에 대해 알아보기
Amazon Cognito 란? 웹 및 모바일 앱을 위한 자격 증명 플랫폼이다. OAuth 2.0 액세스 토큰 및 AWS 보안 인증을 위한 사용자 디렉터리, 인증 서버, 인증 서비스를 제공한다. AWS에서 제공하는 Cognito는 다음과 같이 두 가지 구성 요소로 되어 있다. 사용자 풀 자격 증명 풀 1. 사용자 풀 사용자 풀은 앱 또는 API에 사용자를 인증하고 권한을 부여하도록 해준다. - 애플리케이션 사용자의 가입 및 로그인을 관리할 수 있다. - 사용자 이름 및 비밀번호를 비롯한 인증 정보를 저장하고 관리한다. - 소셜 로그인(Google, Apple, Facebook 등) 및 자체 인증 정보를 사용하여 사용자를 인증할 수 있다. 2. 자격 증명 풀 인증된 혹은 익명의 사용자가 AWS 리소스에 액..
2024.01.23
no image
[AWS] AWS S3, CloudFront, Lambda@Edge를 통해 이미지 Resize
1. S3 버킷 생성하기 - 이름 : sample-lambda-image-resize - 설정 : 기본값 원하는 버킷 이름을 설정하고 아래 설정은 모두 기본값으로 둔 채, 버킷을 생성한다. 2. CloudFront 생성하기 CloudFront 에서 좌측 네비게이션 바에서 원본 엑세스를 클릭한다. 제어 설정 생성을 누른 다음, 이름과 설명을 입력한 후 생성을 클릭한다. - 이름 : s3-lambda-edge-image-resize - 설정 : 기본 3. CloudFront 배포하기 좌측 탭에서 배포를 눌러서 배포 생성을 클릭한다. 원본 도메인에서 아까 만든 S3를 선택한다. 원본 엑세스 설정은 공개에서 원본 액세스 제어 설정(권장)으로 바꿔서 선택한다. 방화벽은 다음과 같이 보안 보호 비활성화로 선택한다..
2023.11.14
AWS
no image
[Kubernetes] 쿠버네티스 알아보기 - 등장 배경 및 도커와의 차이
쿠버네티스 란? 쿠버네티스는 컨테이너화된 워크로드와 서비스를 관리하기 위한 이식성이 있고, 확장가능한 오픈소스 플랫폼이다. 쿠버네티스는 선언적 구성과 자동화를 모두 용이하게 해준다. 출처 : 쿠버네티스 공식 페이지 저 말만 들으면 무슨 의미인지 잘 모르겠다. 더 풀어서 설명해 보겠다. 일단 공식 홈페이지에 나와있는 것을 참고하여 어떻게 쿠버네티스가 나타나게 됐는 지를 살펴보자 과거 물리 서버를 사용하던 시절, 전통적인 배포 시대 - 애플리케이션을 물리 서버에서 실행함. - 여러개의 애플리케이션을 한 물리서버에서 실행하고 싶지만, 여러 애플리케이션의 리소스를 할당에 대한 정의가 없었음 - 따라서 리소스를 전부 차지하는 애플리케이션이 있을 수도 있고, 결과적으로 다른 애플리케이션의 성능 저하 문제 발생 - ..
2023.11.13
no image
[AWS] AWS RDS 인스턴스 생성 및 연결하기(PostgreSQL)
이제 AWS 에서 제공해주는 관리형 서비스인 RDS(Relational Database Service)를 생성해 보겠습니다. ✅ RDS란? AWS에서 지원하는 클라우드기반 관계형 데이터베이스 하드웨어 프로비저닝, 데이터베이스 설정, 패치 및 백업과 같이 잦은 운영 작업을 자동화하여 개발자는 개발에만 집중하도록 지원하는 서비스 조정 가능한 용량을 지원하여, 예상치 못한 양의 데이터가 쌓여도 비용만 추가하면 쭉 사용 가능하다 나는 우리 프로젝트의 사용자가 많아졌으면 좋겠다는 큰 꿈을 가지고 더 고급기능을 가지고 확장성이 좋은 PostgreSQL을 선택했다. 그리고 실무에서도 많이 사용한다고 하니 한번쯤은 사용해 보고 싶었다. 프리티어 기간이 지나면, 비용을 지불하면서 RDS를 사용해야 한다. 보통 Amazo..
2023.10.30
AWS
320x100
728x90

 

 

파이썬에서 가장 빈번하게 사용되는 자료형

1. 리스트

2. 딕셔너리

이 두 가지 자료형은 모든 문제에 빠짐없이 쓰이는 자료형이므로 확실히 이해 하기! 

 

 

 

 

1. 리스트

 

  • 순서대로 저장하는 시퀀스(입력한 순서대로 유지된다)
  • 숫자 외에도 다양한 자료형과 함께 저장 가능 (ex. [1, 2, 3, 5, 4, '안녕', True] )
  • 변경 가능한 (Mutable List) 
  • 동적 배열로 구현된

 

 

 

장점

스택을 사용할 지, 큐를 사용할 지 고민하지 않아도 됨.
이말은 즉, 리스트가 스택과 큐에서 사용 가능한 모든 연산을 함께 제공한다는 뜻. 

 

 

 

 

리스트의 주요 연산 시간복잡도


연산

시간 복잡도 설명
len(a) O(1) 전체 요소의 개수를 리턴
a[i] O(1) 인덱스의 i 요소를 가져옴
a[i : j] O(k) i 부터 j-1 까지 슬라이스. 
k개의 요소가 있다고 하면 각 객체 k개에 대한 조회가 필요하므로 O(k)
elem in a O(n) elem 요소가 a 안에 있는 지 확인.
처음부터 순차탐색 하므로 n 만큼 시간 소요.
a.count(elem) O(n) elem의 요소 개수를 리턴
a.index(elem) O(1) elem 요소의 인덱스 리턴
a.append(elem) O(1) 리스트의 마지막에 elem 요소 추가
a.pop() O(1) 리스트의 마지막 요소 추출. 스택 연산 
a.pop(0) O(n) 리스트 첫번째 요소 추출. 큐 연산
전채 복사가 필요하므로 O(n) 
➡️ 이 경우 데크 사용 권장( 덱은 O(1) ) 
idel a[i] O(n) i에 따라 다르며 최악의 경우 O(n)
a.sort() O(nlogn) 정렬. 팀소트 사용. 
최선의 경우 O(n)에도 실행될 수 있음
min(a), max(a) O(n) 최솟값, 최댓값을 계산하기 위햐서는 전체 선형 탐색해야 하므로 O(n)
a.reverse O(n) 뒤집는다. 리스트 입력 순서가 유지되므로 
뒤집으면 반대로 됨. 

 

 

 

 


 

 

 

 

리스트 특징 

 

 

1) 슬라이싱 

 

특정 범위 내의 값을 매우 편리하게 가져올 수 있음. 

a[i : j] 일 때, i 부터 j-1 까지 값을 리턴함. 

 

# 리스트
[1, 2, 3, 4, 5, '안녕', True]

a[1:3]
>> [2, 3]

 

 

# 시작 인덱스 생략 가능
# 맨 처음부터 2번째 인덱스까지 반환
a[:3] 
>> [1 ,2, 3]

 

 

# 종료 인덱스도 생략 가능 
# 4부터 맨 마지막까지 반환

a[4:]
>> [4, '안녕', True]

 

 

 

# 세번째 파라미터 : 단계(step)의 의미. 

# 맨 마지막 파라미터는 스텝의 의미
# 2씩 건너 뜀
# '1'  2  '3'

a[1:4:2] 
>> [1, 3]

 

 


 

2) 삭제 

1. 인덱스를 사용하여 삭제 - del , pop

 

[1, 2, 3, 4, 5, '안녕', True]

del a[1]     # 1번 인덱스 삭제 
>> [1, 3, 4, 5, '안녕', True]

 

 

[1, 2, 3, 4, 5, '안녕', True]

a.pop(5)    # 다섯번째 인덱스 삭제 
>> [1, 2, 3, 4, 5, True]

 

 

2. 을 통한 삭제 - remove

[1, 2, 3, 4, 5, '안녕', True]

a.remove(3)    # 값이 3인 것을 삭제 
>> [1, 2, 4, 5, '안녕', True]

 

 

 

 

* 리스트의 형태 
리스트는 객체에 대한 포인터 목록으로 구현되어 있다. 

 

 

일반적 정수형 배열 : 정수로만 이루어진 값을 연속된 메모리 공간에 저장
파이썬 리스트 : 연결 리스트에 대한 포인터 목록을 관리하고 있음 

 

 

 

아래 배열을 보자. 

[1, '안녕', True]

 

 

파이썬 리스트는 포인터 목록을 관리하고 있다고 했다. 이는 각각의 객체에 대한 참조를 갖고 있다는 것으로 
만약 2번 인덱스 값에 대해 접근하려고 하면 포인터의 위치를 찾아가서 타입 코드를 확인하고 값을 일일이 살펴봐야 한다. 

 


모두 제각각인 자료형을 단일 리스트에 모두 통합하여 저장할 수는 있지만, (강력한 장점) 

값에 접근하기 위해서는 모든 포인터 위치를 보고 값을 확인해야 하기에 속도를 희생한 측면이 있는 언어이다. (성능상 무의미하긴 하지만..)

 

 

 

 

 

 

2. 딕셔너리 

 

 

  • 키, 값 구조로 이루어짐
  • (*파이썬 3.7 + 기준) 입력 순서가 유지된다.
  • 해시 테이블로 구현되어 있음. 


 

장점

 

(인덱스를 숫자로만 지정할 수 있는 리스트와 달리) 문자를 포함해 다양한 타입을 키로 사용 가능.
숫자, 문자, 집합까지 불변 객체를 모두 키로 사용 가능 ➡️ 해싱. 
입력과 조회 모두 O(1).

 

 

 

 

딕셔너리의 주요 연산 시간 복잡도

연산 시간 복잡도 설명
len(a) O(1) 요소의 개수를 리턴 
a[key] O(1) 키를 조회하여 값 리턴
a[key] = value O(1) 키/ 값 삽입
key in a O(1) 딕셔너리에 키가 존재하는 지 확인 

 

 

 

3.7 이상부터 내부적 인덱스를 이용해 입력 순서를 유지하도록 개선되었지만,
여전히 3.6 이하를 사용하는 곳이 많으므로 입력 순서가 유지될 것이라 가정하는 것은 매우 위험! (버전 잘 확인하기) 

 

 

 

유용한 collections

import collections

collections.OderedDict()        # 입력 순서 유지 
collections.defaultdict()       # 조회 시 항상 디폴트 값 생성 -> 키 오류 방지
collections.Counter()           # 요소의 값을 키로 하고 개수를 값 형태로 만들어 카운팅

 

 

 


 

 

딕셔너리 활용 방법

 

 

1) 값 추가 

 

{'key1' : 'value1', 'key2', 'value2'}

a['key3'] = 'value3'
>> {'key1' : 'value1', 'key2': 'value2', 'key3' : 'value3'}

 

 

 

2) 키 존재하는 지 확인

 

if 'key4' in a:
	print('존재하는 키')
else :
	print('존재하지 않는 키')

 

 

 

3) 키, 값 조회 

 

for k,v in a.items():
	print(k, v)

 

 

 

4) 키 삭제 

{'key1' : 'value1', 'key2', 'value2', 'key3' : 'value3'}

del a['key1']
>> {'key2', 'value2', 'key3' : 'value3'}

 

 

 


 

 

딕셔너리 모듈

 

 

1) defaultdict 객체

 

# 존재하지 않는 키를 조회할 경우,
# 에러 메시지를 출력하는 대신 디폴트 값을 기준으로 해당 키에 대한 딕셔너리 아이템 생성.

a = collections.defaultdic(int)
a['A'] = 5
a['B'] = 4
a 
>> defaultdict(<class 'int'>, {'A':5 , 'B' : 4}) 


a['C'] += 1
a
>> defaultdict(<class 'int'>, {'A':5 , 'B' : 4, 'C' : 1})

 

 

'C' 는 없는 키 값이지만,
디폴트인 0을 기준으로 자동으로 생성 후 여기 1을 더해 최종적으로 1인 값과 그의 키인 'C' 를 딕셔너리에 추가한다. 

 

 

 


 

2) Counter 객체

 

# 아이템에 대한 개수를 계산해 딕셔너리로 리턴한다. 

a = [1,2,3,4,5,5,5,6,6]

b = collections.Counter(a)
b
>> Counter({5:3, 6:2, 1:1, 2:1, 3:1, 4:1})

 

키에는 아이템의 값이, 값에는 해당 아이템의 개수가 들어간 딕셔너리 생성. 

 

 

 

가장 빈도 수 높은 요소 추출

b.most_common(2)

>> [(5, 3), (6, 2)]

 

 

 


 

 

3) OrderedDict 객체 (파이썬 3.7 미만 버전

 

 

# 대부분 언어에서 해시 테이블을 이용한 자료형은 입력 순서 유지 X
# 입력 값을 부여할 경우 OrderedDict는 입력 그대로 순서가 유지됨.

collections.OrderedDict({'banana' : 3, 'apple' : 4, 'orange' : 2})

 

 

 

 

 

 

728x90
반응형
320x100
728x90

 

 

 

빅오(O, big - O)

입력값이 커질 때 알고리즘의 실행 시간(시간 복잡도)과 함께 공간 요구사항(공간 복잡도)이 어떻게 증가하는 지를 분류하는 데 사용 

입력값이 무한대로 향할 때 함수의 상한을 설명하는 수학적 표기 방법

 

 

 

점근적 실행 시간을 표기할 때 사용하는 것이 빅오이다. 
점근적 실행 시간(알고리즘을 수행하는 데 걸리는 시간을 설명하는 계산복잡도) 은 달리 말하면 시간복잡도 이다. 

 

 

 

빅오 표기법
최고차항만을 표기, 계수는 무시한다.

 

 

  •  O(1) : 입력값이 아무리 커도 실행 시간은 일정함 
    예시) 해시 테이블의 조회 및 삽입

  • O(log n) : 매우 큰 입력값에도 크게 영향을 받지 않는 편 
    예시 ) 이진 검색 

  • O(n) : 입력값만큼 실행시간에 영향을 받음. 시간은 입력값에 비례 
    선형 시간 알고리즘이라고 함. 
    예시 ) 정렬되지 않은 리스트에서 최댓값 혹은 최솟값 찾기 

  • O(nlogn) : 병합 정렬을 비롯한 대부분의 효율 좋은 정렬 알고리즘이 대부분 해당 
    적어도 모든 수에 대해 한 번 이상은 비교해야 하는 비교 기반 알고리즘은 O(nlogn) 보다 빠를 순 없음 

  • O(n^2) : 버블 정렬 같은 비효율적인 정렬 알고리즘 

  • O(2^n) : 피보나치 수를 재귀로 계산하는 알고리즘 

  • O(n!) : 각 도시를 방문하고 돌아오는 가장 짧은 경로를 찾는 외판원 문제를 브루투 포스로 풀이할 때 해당 

 

 

시간과 공간 관계 : 트레이드 오프 
실행 시간이 빠른 알고리즘은 공간을 많이 사용하고, 공간을 적게 차지하는 알고리즘은 실행 시간이 느리다. 

 

 

 

 

상한과 하한

 

  • 빅오 : 상한을 의미 (가장 늦게 실행될 때)
  • 빅오메가 : 하한을 의미 (가장 빨리 실행될 때)
  • 빅세타 : 평균을 의미 

 

 

 


 

 

 

 

파이썬 자료형

 

 

1. 숫자 


파이썬에서는 숫자 정수형으로 int 만을 제공.

고정 정밀도 정수형은 지원하지 않게됨. 

 

bool 또한 int의 서브 클래스 

 

object > int > bool

 

 

 


 

 

2. 매핑

 


매핑이란 키와 자료형으로 구성된 복합 자료형 

파이썬에서 내장된 유일한 매핑 자료형은 딕셔너리 

 

 


 

 

3. 집합

 

 

중복된 값을 갖지 않는 자료형 
set 이 해당 

set은 입력 순서가 유지되지 않는다. 

 

 

# set 
a = {'a', 'b', 'c'}

# dictionary
a = {'a':'A', 'b':'B', 'c':'C'}

 

 

 


 

 

 

4. 시퀀스 

 

 

어떤 특정 대상의 순서 있는 나열. 수열 이라고도 함 

 

  • str : 문자의 순서 있는 나열로 문자열을 이루는 자료형 
  • list : 다양한 값들을 배열 형태의 순서 있는 나열로 구성하는 자료형. 자유롭게 값을 추가, 삭제 할 수 있는 동적 배열 

 

불변 시퀀스 : str, tuple, bytes

가변 시퀀스 : list 

 

 

# str의 참조 

a = 'abc'

a = 'def'

 

a가 'abc' 였다가 'def' 가 되었다고 해서 값 자체가 변경된 것이 아니라 
a가 참조하는 주소가 달라진 것이다. 

 

 

 


 

5. 객체 

파이썬은 모든 것이 객체.

 

언어 지원 타입 형태
C 원시 타입
자바 원시 타입, 객체
파이썬 객체 

 

 

C나 자바는 성능에 대한 우선순위가 높은 언어이며 매우 빠른 연산이 가능. 하지만 공간을 많이 차지 한다. 
하지만 파이썬은 편리한 기능 제공에 우선순위를 둔 언어. 

 

 

 

파이썬은 불변 객체가변 객체로 구분

 

 

 

불변 객체

클래스 설명
bool 부울
int  정수
float 실수
tuple 리스트와 튜플 차이는 불변 여부
str 문자

 

 

 

가변 객체 

클래스 설명
list 리스트
set 중복된 값을 갖지 않는 집합
dict 딕셔너리

 

 

 


 

6. 불변 객체 

 

 

파이썬은 모든 것이 객체이기 때문에 원시 타입처럼 각각의 값들이 각 메모리의 다른 영역에 위치하는 게 아니라 
모두 같은 위치에 존재한다. 

 

10
a = 10
b = a

print(id(10), id(a), id(b))

 

 

 

 

 

 

 

 

그렇다면 만약 a 값을 11로 바꾸면 b 도 11로 바뀌어야 하는 게 아닌가?!

-> 그렇지 않다. 

 

 

 

 

파이썬의 숫자와 문자는 모두 불변이기 때문

 

 

 

 

값을 담고 있는 변수는 참조일 뿐이고, 실제로 값을 갖고 있는 int 와 str은 모두 불변. 
int, str, tuple 은 불변 객체이르모 dict 의 키나 set 의 값으로 사용 가능하다. 

 

 

 


 

7. 가변 객체 

 

 

list 는 다른 변수가 참조하고 있을 때 값을 변경하면 그 변수의 값이 변경될 수 있다. 

 

 

a = [1,2,3,4,5]
b = a
print(b)   # 변경 전 

a[2] = 4
print(a)   # 변경 후 
print(b)

 

 

 

 

 

 

 

 

 

리스트 a의 요소를 변경했더니 b 또한 같이 바뀌는 것을 볼 수 있다. 

 

 

 

 

 

 

출처 : 파이썬 알고리즘 인터뷰 | 박상길

728x90
반응형
320x100
728x90

 

 

 

파이썬 고급 문법에 대해 알아보자 

 

 

 

# 인덴트

 

공백 4칸을 원칙으로 함.

 

  • 첫번째 줄에 파라미터가 있으면 -> 파라미터가 시작되는 부분에 보기 좋게 맞춘다. 
  • 첫번째 줄에 파라미터가 없으면 -> 공백 4칸 인덴트를 한 번 더 추가하여 다른 행과 구분되도록 한다. 

 

# 첫 줄 파라미터 있을 때
foo = long_func_name(var_one, var_two,
                    var_three, var_four)


# 없을 때
def long_func_name(
        var_one, var_two, var_three,
        var_four):
    print(var_one)

 

 

 


 

 

# 네이밍 컨벤션

 

 

파이썬 변수명 네이밍 컨벤션은 자바와 다르다. 스네이크 케이스를 기본으로 한다. 

 

  • 자바 : 카멜 케이스(단어를 대소문자로 구분하여 섞어서 작명하는 방식)
  • 파이썬 : 스네이크 케이스(각 단어를 언더스코어(_)로 구분함)

 

따라서 파이썬 변수명이나 함수명에는 언더바를 사용해 표기하도록 하자! 

 

# 카멜 케이스
camelCase: int = 1

# 스네이크 케이스
snake_case: int = 1

 

 

 


 

 

 

# 타입 힌트 

 

 

타입 힌트 : 파이썬은 동적 타이핑 언어임에도 불구하고, 타입을 지정할 수 있게 해주는 것

 

 

# 타입 지정 안한 경우 -> 어떤 숫자를 넘겨야 하는 지 알 수 없음 
def fn(a):
    
 
# 타입 힌트로 지정한 경우 
def fn(a: int) -> bool:

 

 

 

주의할 점)

 

파이썬은 동적 할당이므로 아래와 같이 문자열에 정수를 할당하여도 

문자열이 아닌 정수 타입을 반환한다. 

 

 

a: str = 1
type(a)

<class 'int'>

 

 

 


 

 

# 리스트 컴프리헨션

 

  • 리스트 컴프리헨션 : 기존 리스트를 기반으로 새로운 리스트를 만들어 내는 구문 

 

파이썬은 map, filter와 같은 함수형 기능을 지원하며 람다 표현식 또한 지원한다.

지나친 리스트 컴프리헨션 사용은 가독성을 떨어뜨리므로 표현식이 2개를 넘지 않게 하는 것이 좋다. 

 

 

a = list(map(lambda x :x+10, [1,2,3]))
print(a)

# 결과 [11,12,13]

 

 

 

a = [n  * 2 for n in range(1, 10 + 1) if n % 2 == 1]
print(a)


# 결과 [2, 6, 10, 14, 18]

 

 

  • 딕셔너리의 경우 

    기존

 

# 기존 
a = {}
for key, value in dic.items():
    a[key] = value

 

 

 

     리스트 컴프리헨션 사용 시, 

 

a = {key: value for key, value in dic.items()}

 

 

 


 

 

# 제너레이터 

 

  • 제너레이터 : 루프의 반복 동작을 제어할 수 있는 루틴 형태 
  • yield 구문을 사용한다. 

 

기존의 return 구문은 값을 리턴 하고 모든 함수의 동작을 종료한다. 

하지만 yield 는 제너레이터가 여기까지 실행 중이던 값을 내보낸다는 뜻으로 중간값을 리턴한 다음, 함수는 종료되지 않고

계속해서 맨 끝에 도달할 때까지 실행된다. 

 

def get_natural_number():
    n = 0
    while True:
        n += 1
        yield n 
        
        
 # 종료 구문이 없으므로 값을 계속해서 내보냄

 

 

 

만약 값을 내보내고 싶다면 next()를 통해 추출한다. 

 

 

 

g = get_natural_number()
for _ in range(100):
    print(next(g))

 

 

 

아래와 같이 100까지 출력되는 것을 볼 수 있다. 

 

 

 

 

 

여러 타입의 값을 하나의 함수에서 생성하는 것도 가능하다. 

 

 

def generator():
    yield 1
    yield 'string'
    yield True


g = generator()
print(next(g))
print(next(g))
print(next(g))

 

 

 

 

 

 

 

 


 

 

 

# range 

 

  • range() : 제너레이터의 방식을 활용하는 대표적인 함수

a와 b의 길이를 비교해 보면 둘 다 동일한 100만개가 출력된다. 

 

a = [n for n in range(1000000)]
b = range(1000000)

print(len(a))
print(len(b))

 

 

 

그러나 차이점은 a는 이미 생성된 값이 담겨 있고, b 는 생성해야 한다는 조건이 있다. 

 

이제 둘의 메모리를 비교해 보면 확연히 차이가 난다. 

 

 

print(sys.getsizeof(a))
print(sys.getsizeof(b))

 

 

 

 

b가 메모리 점유율이 훨씬 더 적은 것을 알 수 있다. b는 미리 생성하지 않은 값이므로 메모리 점유율이 더 작다.

그렇다고 인덱스에 접근이 안되는 것은 아니다. 

 

 

print(b[999])

 

 

 

 

 

 


 

 

# enumerate 

 

  • enumerate() : 열거하다 라는 뜻의 함수. 인덱스와 값을 함께 리턴해줌

 

a = [1,2,3,2,45,2,5]
b = list(enumerate(a))
print(b)


# 결과 [(0, 1), (1, 2), (2, 3), (3, 2), (4, 45), (5, 2), (6, 5)]

 

 

 

인덱스와 값을 함께 출력하고 싶을 때 사용하면 유용하다. 

 

for i, v in enumerate(a):
	print(i, v)

 

 

 


 

 

# 나눗셈 연산자

 

  • // : 정수형을 나눗셈할 때 동일한 정수형을 결과로 리턴함(내림 연산자 역할)
  • 즉, 몫을 구하는 연산자이다.

 

5 // 3

# 결과: 1

 

 

  • % : 나머지를 구하는 연산자 

 

5 % 3

# 결과 : 2

 

 

 

몫과 나머지를 동시에 구하려면 divmod() 함수를 사용하면 된다.

 

 

divmod(5, 3)

# 결과 : (1, 2)

 

 

 


 

 

# print

 

각각의  출력 방법에 대해 알아보겠다. 

 

 

1. 기본 띄어쓰기 출력 

 

print('A1', 'B1')

A1 B2

 

 

 

2. 구분자 지정 출력 -> sep 사용

 

print('A1', 'B1', sep=',')

A1, B2

 

 

 

3. 줄바꿈 없이 출력 -> end 사용

 

print() 함수는 항상 줄바꿈을 하기 때문에

end 파라미터를 공백으로 처리하여 줄바꿈을 하지 않도록 제한 가능하다. 

 

 

print('aa', end=' ')
print('bb')

aa bb

 

 

 

4. 리스트 출력하기 (한 줄로)

 

 

a = ['A', 'B']
print(' '.join(a))


A B

 

 

 

5. format 사용하기 

 

 

idx = 1
fruit = "Apple"

print('{0}: {1}'.format(idx + 1, fruit))

# 인덱스 생략도 가능
print('{}: {}'.format(idx + 1, fruit))

# 결과 
2: Apple

 

 

 

6. f- string 사용 ( 3.6 + 에서만 사용 가능) 

 

print(f'{idx + 1} : {fruit}')

2: Apple

 

 


 

 

# pass

 

pass는 널 연산으로 아무것도 하지 않는 기능.

인덴트 오류나 불필요한 오류를 방지할 수 있다. 코드를 인터페이스부터 구현한 다음에 추후 구현을 진행 가능함. 

 

class MyClass(object):
    def method_a(self):
        pass
    def method_b(self):
        print("Method B")


c = MyClass()

 

 

 

 


 

 

# locals

 

  • locals() : 로컬에 선언된 모든 변수를 조회할 수 있는 명령.

 

디버깅할 때 많은 도움이 된다. 

 

import pprint

pprint.pprint(locals())

 

 

클래스 내부 로컬 변수를 출력해 준다

 

 

 


 

 

# 구글 파이썬 스타일 가이드 

 

 

YES

 

if not users:
    print('no users')

if foo == 0:
    self.handle_zero()

if i % 10 == 0:
    self.handle_multiple_of_ten()

 

 

 

 

NO

 

if len(users) == 0:
    print('no users')

if foo is not None and not foo:
    self.handle_zero()

if i % 10:
    self.handle_multiple_of_ten()

 

 

 

길이가 없다는 말은 값이 없다는 뜻으로 not users 로도 충분하다. 

값을 비교할 때는 비교 대상이 되는 값을 직접 비교하는 것이 좋다. 

 

 

 

 

 

출처 : 파이썬 알고리즘 인터뷰 | 박상길

728x90
반응형
320x100
728x90

 

 

파이썬 알고리즘 인터뷰 라는 책으로 코딩테스트 연습을 해보고자 한다. 

각각의 장에서 배운 것들을 정리하고 익히도록 하겠다 ~.~

 

 

 

 

책을 활용하면서 필요한 것들 

문제 풀이 소스코드 다운 및 학습 동영상

1. 깃허브 소스코드 : https://github.com/onlybooks/python-algorithm-interview

2. 유튜브 학습 동영상 : https://www.youtube.com/watch?v=ngHIVey3J6Y

 

 

 

 

2장 프로그래밍 언어 선택

 


# 파이썬을 활용한 루프 구조 구현 

 

 

파이썬은 한 줄로도 루프 구현 가능

그러나 지나친 사용은 가독성을 떨어뜨릴 수 있으므로 적절하게 사용하는 것이 중요.

 

#파이썬(Python)

# 예시 1
sum = 0
for i in range(1, 10 + 1):
	sum += i
    
    
# 예시 2 
sum = sum(i for i in range(1, 10 + 1))


# 예시 3
sum = sum(range(1, 10 + 1))

 

 

 

 

# 제네릭 프로그래밍

 

파이썬은 동적 파이핑 언어로 *제네릭이 필요 없다 

(* 제네릭 : 파라미터의 타입이 나중에 지정되게 하여 재활용성을 높일 수 있는 프로그래밍 스타일)

 

def are_equal(a, b):
	return a == b
    
are_equal(10, 10.0)

 

 

 

하지만 이는 장단점이 확실하다. 사용하기에는 매우 편하지만, 코드의 복잡성이 높아질 수 있다. 

그래서 다음과 같이 타입을 명시하는 방법도 있다. 

 

 

 

<타입 힌트를 통해 제네릭을 사용하는 방법> 

 

from typing import TypeVar

T = TypeVar('T')
U = TypeVar('U')

def are_equal(a: T, b: U) -> bool:
	return a == b


are_equal(10, 10.0)

 

 

파이썬은 동적 파이핑 언어이지만, 

이렇게 타입을 명시하면 가독성이 좋아지며 버그 발생 확률을 줄일 수 있다. 

 

 

 

 

# 배열 반복

 

파이썬은 다른 언어에 비해 문자열 자료형이라는 선언 조자 필요가 없다.

 

#Python
foo = ['A', 'B', 'C']
for f in foo:
	print(f)

 

 

#Java
String[] foo = new String[]{"A", "B", "C"};
for (String f : foo) {
	System.out.println(f);
}

 

 

 

 

# 구조체

 

배열 : 순차적으로 메모리를 할당함.

구조체 : 메모리의 어느 영역에나 어떤 크기로든 할당할 수 있는 복합 자료형.

 

 

 

파이썬에는 구조체가 없을 뿐더러, 클래스 또한 데이터 타입을 지정할 수 없다. 

구조체와 같은 형태를 정의하려면 네임드 튜플을 사용해야 한다. 

 

 

from collections import namedtuple

MyStruct = namedtuple("MyStruct", "field1 field2 field3")
m = MyStruct("foo", "bar", "baz")

 

 

 

파이썬 3.7 부터는 dataclass 를 지원한다. @dataclass 데코레이션(자바에서는 어노테이션) 으로 

다음과 같이 class를 이용해 구조체 형태로 정의 가능하다. 

 

 

from dataclasses import dataclass

@dataclass
class Product:
    weight: int = None
    price: float = None

apple = Product()
apple.price = 10

 

 

 

 

# 클래스 

 

파이썬에서의 클래스는 위에 언급한 dataclass 데코레이션을 이용해 클래스를 선언한다. 

 

from dataclasses import dataclass

@dataclass
class Rectangle:
    width: int
    height: int
    
    def area(self):
        return self.width * self.height

rect = Rectangle(3, 4)
print(rect.area)

 

 

 

 

 

 

출처 : 파이썬 알고리즘 인터뷰 | 박상길

728x90
반응형
320x100
728x90

 

 

Amazon Cognito 란?

웹 및 모바일 앱을 위한 자격 증명 플랫폼이다. OAuth 2.0 액세스 토큰 및 AWS 보안 인증을 위한
사용자 디렉터리, 인증 서버, 인증 서비스를 제공한다. 

 

 

AWS에서 제공하는 Cognito는 다음과 같이 두 가지 구성 요소로 되어 있다. 

  • 사용자 풀
  • 자격 증명 풀 

 

1. 사용자 풀  

 

사용자 풀은 앱 또는 API에 사용자인증하고 권한을 부여하도록 해준다. 

 

- 애플리케이션 사용자의 가입 및 로그인을 관리할 수 있다.

- 사용자 이름 및 비밀번호를 비롯한 인증 정보를 저장하고 관리한다. 

- 소셜 로그인(Google, Apple, Facebook 등) 및 자체 인증 정보를 사용하여 사용자를 인증할 수 있다. 

 

 

 

2. 자격 증명 풀

인증된 혹은 익명의 사용자가 AWS 리소스에 액세스 할 수 있도록 권한을 부여한다. 

 

- 자격 증명 풀은 사용자에게 리소스를 제공할 수 있도록 AWS 보안 인증을 발급한다. 

 

 


 

Amazon Cognito 사용자 풀 생성하기

 

 

 

소셜 로그인을 위해 연동 자격 증명 공급자를 선택해준다. 
사용자 풀 로그인 옵션으로는 일단 이메일만 선택. 

 

 

 

 

MFA 설정은 없음으로 두었다. 

 

Cognito 자동 메시지 전송 또한 체크 해제. 별도 청구 금액이 발생할 수 있다. 

 

cognito 이메일 전송 선택. 

 

소셜 로그인 설정은 지금은 건너뛰기. 

 

사용자 풀 이름과 관련 도메인을 설정해준다. 

 

 

 

보안 키를 생성해준다. 

 

 

콜백 URL은 일단 아래와 같이 로컬 호스트로 설정 후, 개발 이후 실제 URL로 대체한다. 

 

 

 

 

 

 

728x90
반응형
320x100
728x90

1. S3 버킷 생성하기  

 

- 이름 : sample-lambda-image-resize

- 설정 : 기본값 

 

 

 

 

원하는 버킷 이름을 설정하고 아래 설정은 모두 기본값으로 둔 채, 버킷을 생성한다. 

 

 

 

2. CloudFront 생성하기

 

CloudFront 에서 좌측 네비게이션 바에서 원본 엑세스를 클릭한다. 

 

 

 

 

제어 설정 생성을 누른 다음, 이름과 설명을 입력한 후 생성을 클릭한다.

 

 

- 이름 : s3-lambda-edge-image-resize

- 설정 : 기본

 

 

 

 

 

3. CloudFront 배포하기 

 

좌측 탭에서 배포를 눌러서 배포 생성을 클릭한다.

 

 

 

원본 도메인에서 아까 만든 S3를 선택한다.

 

 

 

 

 

 

원본 엑세스 설정은 공개에서 원본 액세스 제어 설정(권장)으로 바꿔서 선택한다. 

 

 

 

 

 

 

방화벽은 다음과 같이 보안 보호 비활성화로 선택한다. 

 

 

 

 

 

 

4. S3 버킷 정책 수정하기 

 

 

위에서 배포를 하고 나면 상단에 다음과 같이 경고가 뜬다. 

 

 

 

S3 버킷 정책을 본격적으로 수정해보자

 

그전에, cloudfront 배포에서 원본을 선택한 다음, 내 원본을 클릭 후 편집을 누른다.

 

 

 

 

아래로 내려가서 정책 복사를 눌러준다. 

 

 

 

 

 

이제 다시 S3 버킷 권한으로 이동해보자.

 

위에서 s3 버킷 권한으로 이동을 클릭하면 다음과 같은 화면이 보인다. 

 

 

 

 

 

편집을 눌러서 아까 복사한 정책을 붙여넣기로 넣어준다.

 

 

 

 

 

변경 사항 저장 클릭.

 

 

5. S3에 이미지 업로드하기 

 

 

이제 S3에 이미지를 업로드 해 준다.

업로드 하면 다음과 같이 나타난다. 

 

 

 

사진을 눌러서 

 

 

 

 

객체 url 에 들어가보면 다음과 같이 AccessDenied 가 뜨면 성공이다. 

 

 

 

 

 

 

6.  CloudFront 도메인에서 이미지 잘 뜨는 지 확인하기

 

 

 

 

이제 다시 CloudFront 가서 배포 도메인을 복사한 뒤, 내 이미지 사진을 확인해본다. 

 

 

 

이미지가 잘 뜬다. 성공!

 

 

7. CloudFront 캐시 정책 생성하기 

 

 

cloudfront에서 정책을 눌러서 사용자 정의 정책을 생성해준다. 

 

 

 

 

이름과 설명을 넣어준다. 

 

 

 

 

 

캐시 키 설정에서 쿼리 문자열은 모두로 바꾸어 준다. 
이렇게 하면, 나중에 q w h t 이렇게 따로 키 설정을 안해주어도 된다.

 

 

 

 

 

그리고 생성 클릭.

 

 

 

8.  CloudFront 원본 요청 정책 생성 

 

 

아까는 캐시 정책을 생성했다면, 바로 옆 탭을 눌러서 원본 요청 정책을 생성한다. 

 

 

 

 

이름과 설명을 넣은 뒤, 아까와 동일하게 쿼리 문자열을 모두로 설정한다. 

 

 

 

 

 

 

9.  CloudFront 동작 편집 

 

 

배포에서 동작을 클릭한 뒤, 편집을 눌러준다. 

 

 

 

 

 

아까 설정한 캐시 및 원본 정책을 선택해 준다.  (사용자 정의에 있는 것 선택) 

 

 

 

 

 

 

아래 처럼 알맞게 선택 되었는 지 확인 

 

 

 

 

 

10. IAM 권한 설정하기 

 

 

IAM 에서 역할을 눌러 역할 만들기를 클릭한다. 

 

 

 

 

신뢰할 수 있는 엔터티 유형은 AWS 서비스로,

사용 사례는 Lambda를 클릭한다. 

 

 

 

 

 

 

검색창에 AWSLambdaExecute를 검색한 뒤, 선택한다. 

 

 

 

 

 

 

 

 

권한이 잘 들어갔는 지 확인 한 다음,

 

 

 

 

역할 생성을 눌러준다.

 

 

 

11.  IAM 역할 신뢰 정책 편집하기 

 

 

 

엣지를 수행하기 위해서는 "edgelambda.amazonaws.com" 역할도 있어야 한다. 

신뢰 정책 편집을 눌러 추가해준다. 

 

 

{
   "Version": "2012-10-17",
   "Statement": [
      {
         "Effect": "Allow",
         "Principal": {
            "Service": [
               "lambda.amazonaws.com",
               "edgelambda.amazonaws.com"
            ]
         },
         "Action": "sts:AssumeRole"
      }
   ]
}

 

 

 

12. 람다 함수 만들기

 

 

 

중요한 것은 버지니아 북부 지역에서 생성한다는 것이다.  람다 엣지는 버지니아 북부에서 배포해야지만 작동한다. 

그리고 node 로 설정한다. 

 

 

 

 

 

13. 이미지 resize 코드 작성 및 람다에 올리기 

 

 

 

AWS 에서 제공하는 Cloud9을 IDE 를 사용할 수도 있지만,

나는 기존에 사용하던 Visual Studio Code 를 열어서 코드를 작성했다. 

 

 

 

그리고 해당 프로젝트에서 node를 설치에 주었다. 

 

아래는 내가 사용한 이미지 resize 코드이다. 

 

const sharp = require('sharp');
const aws = require('aws-sdk');

const s3 = new aws.S3({
  region: 'ap-northeast-2'
});
const BUCKET = 'S3_버킷_이름_대체';

exports.handler = async (event, _, callback) => {
  const { request, response } = event.Records[0].cf;

  /** 쿼리 설명
   * w : width
   * h : height
   * f : format
   * q : quality
   * t : type (contain, cover, fill, inside, outside)
   */
  const querystring = request.querystring;
  const searchParams = new URLSearchParams(querystring);

  if (!searchParams.get('w') && !searchParams.get('h')) {
    return callback(null, response);
  }

  const { uri } = request;
  const [, imageName, extension] = uri.match(/\/?(.*)\.(.*)/);

  const width = parseInt(searchParams.get('w'), 10);
  const height = parseInt(searchParams.get('h'), 10);
  const quality = parseInt(searchParams.get('q'), 10) || DEFAULT_QUALITY;
  const type = searchParams.get('t') || DEFAULT_TYPE;
  const f = searchParams.get('f');
  const format = (f === 'jpg' ? 'jpeg' : f) || extension;

  try {
    const s3Object = await getS3Object(s3, BUCKET, imageName, extension);
    const resizedImage = await resizeImage(s3Object, width, height, format, type, quality);

    response.status = 200;
    response.body = resizedImage.toString('base64');
    response.bodyEncoding = 'base64';
    response.headers['content-type'] = [
      {
        key: 'Content-Type',
        value: `image/${format}`
      }
    ];
    response.headers['cache-control'] = [{ key: 'cache-control', value: 'max-age=31536000' }];
    return callback(null, response);

  } catch (error) {
    return callback(error);
  }
};

const DEFAULT_QUALITY = 80;
const DEFAULT_TYPE = 'contain';

async function getS3Object(s3, bucket, imageName, extension) {
  try {
    const s3Object = await s3.getObject({
      Bucket: bucket,
      Key: decodeURI(imageName + '.' + extension)
    }).promise();

    return s3Object;
  } catch (error) {
    console.log('s3.getObject error: ', error);
    throw new Error(error);
  }
}

async function resizeImage(s3Object, width, height, format, type, quality) {
  try {
    const resizedImage = await sharp(s3Object.Body)
      .resize(width, height, { fit: type })
      .toFormat(format, {
        quality
      })
      .toBuffer();

    return resizedImage;
  } catch (error) {
    console.log('resizeImage error: ', error);
    throw new Error(error);
  }
}

 

 

이제 프로젝트를 압축해서 람다에 올리면 된다. 

 

 

 

 

 

14. CloudFront 트리거 추가하기 

 

 

이제 해당 람다 함수에 CloudFront 트리거를 추가한다. 

 

 

 

그리고 Deploy to Lambda@Edge 를 클릭한다. 

 

 

 

 

 

- distribution : 기존에 Cloudfront 에 배포한 것을 선택 

- Cache behavior : 본인이 설정한 S3 이미지 경로

- CloudFront event : Origin response 로 설정 

 

 

 

이렇게 설정한 뒤 배포를 눌러준다. 

 

 

 

배포를 하면 이렇게 버전이 생긴다. 나는 4번의 수정, 배포를 거쳐서 네 개의 버젼이 있다. 

 

 

 

 

15. 배포된 이미지 확인하기 

 


이제 본인의 CloudFront 배포 도메인을 통해서 확인해보자 

 

 

 

https://배포_도메인_이름t/images/105.png?w=29&h=60&t=outside

https://배포_도메인_이름t/images/105.png?w=118&h=244&t=outside

 

 

원하는 사이즈와 타입을 넣으면 그에 맞게 사진이 잘 변하는 것을 확인할 수 있다..! 

 

 

 

 

 

 

 

 

이렇게 CloudFront 를 활용하면 S3에 가진 원본 이미지 하나로도 각 요청에 맞는 사이즈 이미지를 전달 가능하다 

 

 

 

728x90
반응형
320x100
728x90

 

 

 

쿠버네티스 란? 

쿠버네티스는 컨테이너화된 워크로드와 서비스를 관리하기 위한 이식성이 있고, 확장가능한 오픈소스 플랫폼이다. 쿠버네티스는 선언적 구성과 자동화를 모두 용이하게 해준다. 

출처 : 쿠버네티스 공식 페이지

 

 

 

 

 

저 말만 들으면 무슨 의미인지 잘 모르겠다. 

더 풀어서 설명해 보겠다. 

 

 

 

 

일단 공식 홈페이지에 나와있는 것을 참고하여 어떻게 쿠버네티스가 나타나게 됐는 지를 살펴보자 

 

 

출처 : 쿠버네티스 공식 홈페이지

 

 

 

  • 과거 물리 서버를 사용하던 시절, 전통적인 배포 시대

    - 애플리케이션을 물리 서버에서 실행함.

    - 여러개의 애플리케이션을 한 물리서버에서 실행하고 싶지만,
                                   여러 애플리케이션의 리소스를 할당에 대한 정의가 없었음

    - 따라서 리소스를 전부 차지하는 애플리케이션이 있을 수도 있고,
                                       결과적으로 다른 애플리케이션의 성능 저하 문제 발생

    -  여러 물리 서버를 두는 해결책   ➡️   리소스가 충분히 활용되지 않는다는 점에서 확장 가능하지 않음
                                                      ➡️    조직이 많은 물리 서버를 유지하는 데에 높은 비용이 듦






  • VM(Virtual Machine의 도입) 배포 시대 

    VM 이란? 가상화된 하드웨어 상에서 자체 운영체제를 포함한 모든 구성 요소를 실행하는 하나의 완전한 머신

    -
    단일 물리 서버의 CPU에서 여러 가상 시스템 (VM)을 실행하는 방식.

    - 가상화를 사용하면 VM간에 애플리케이션을 격리함 
                 ➡️   애플리케이션의 정보를 다른 애플리케이션에서 자유롭게 액세스 
                                                                                        할 수 없으므로, 일정 수준의 보안성을 제공

    - 물리 서버에서 리소스를 보다 효율적으로 활용 가능

    - 쉬운 업데이트와 추가,  하드웨어 비용을 절감할 수 있어 더 나은 확장성을 제공 가능  





    • 컨테이너 개발 시대 

      - VM의 격리 속성을 완화하여 애플리케이션 간에 운영체제(OS)를 공유
                         ➡️ VM처럼 각각의 컨테이너가 완전한 운영체제를  가지지 않아도 됨. 

      - 클라우드나 OS 배포본에 모두 이식 가능

      - 지속적인 개발, 통합 및 배포 : 안정적이고 주기적으로 컨테이너 이미지를 빌드해서
                                                                                                    배포 가능하고 효율적으로 롤백 가능

      -
      배포 시점이 아닌 빌드/릴리스 시점에 애플리케이션 컨테이너 이미지를 만듦,                         
                                                                                                                                ➡️  애플리케이션이 인프라스트럭처에서 분리

      - VM은 각각이 독립된 운영체제를 실행하므로, 일부 중복된 자원 사용이 발생함
                                                                   ➡️ 컨테이너는 호스트 OS의 리소스를 효율적으로 공유하며,
                                                                                      여러 컨테이너를 더 적은 자원으로 실행 가능함.



      즉, VM 보다 더 가벼우면서도 확장성이 뛰어나고 이식성이 높은 가상화 기술을 제공한다. 


 



이런 배경으로 컨테이너가 등장하였다. 

우리가 알고 있는 컨테이너 중에 가장 유명한 것이 바로 '도커' 이다. 
도커는 즉, 컨테이너화 플랫폼 혹은 런타임인 것이다. 




도커 란?

Docker는 개발자가 컨테이너를 빌드, 배포 및 실행하도록 지원하는 상용 컨테이너화 플랫폼 및 런타임. 단일 API를 통한 간단한 명령과 자동화를 갖춘 클라이언트-서버 아키텍처를 사용한다.

 



그렇다면 도커쿠버네티스차이는 무엇일까?

 

 

 

위에서 말한 Docker는 컨테이너화된 애플리케이션을 패키징하고 배포하는 효율적인 방법을 제공하지만, Docker만으로는 대규모로 컨테이너를 실행하고 관리하기는 어렵다. 왜냐면 한 도커는 하나의 애플리케이션 스택 혹은 서비스를 정의하기 때문이다. 

 

여러개의 애플리케이션을 각각의 컨테이너를 통해 배포할 수 있지만, 이 여러 애플리케이션이 배포된 각각의 컨테이너를 총 관리하는 역할을 도커가 하기엔 어렵기 때문이다. 

 

이렇게 수많은 서버에 분산된 컨테이너를 유지하기 위해 여러 컨테이너를 조정하고 예약하는 방법, 컨테이너 간 통신을 가능하게 하는 방법 및 컨테이너 인스턴스를 확장하는 것을 해결해 주기 위해 Kubernetes가 탄생한 것이다. 

 

 

쿠버네티스는 컨테이너를 오케스트레이션하는 솔루션. 


 

 

쿠버네티스 클러스터  란?

쿠버네티스는 여러개의 컨테이너를 실행하고 관리할 수 있는 환경을 제공한다고 했다. 이 여러개의 컨테이너를 담고 있는 곳을 노드(Node) 라고 한다. 클러스터는 이러한 여러 노드를 구성하고 있는 집합이다. 

 


쿠버네티스 클러스터의 구성 요소 

- 마스터 노드 (Master Node)
- 워커 노드 (Worker Node)

 

 

 

 

쿠버네티스의 자세한 개념 용어들에 대해서는 나중에 알아보도록 하겠다..

 

 

 

 

728x90
반응형
320x100
728x90

 

 

이제 AWS 에서 제공해주는 관리형 서비스인 RDS(Relational Database Service)를 생성해 보겠습니다.

 

 

 

✅ RDS란?

  • AWS에서 지원하는 클라우드기반 관계형 데이터베이스
  • 하드웨어 프로비저닝, 데이터베이스 설정, 패치 및 백업과 같이 잦은 운영 작업을 자동화하여
    개발자는 개발에만 집중하도록 지원하는 서비스
  • 조정 가능한 용량을 지원하여, 예상치 못한 양의 데이터가 쌓여도 비용만 추가하면 쭉 사용 가능하다

 

 

 

나는 우리 프로젝트의 사용자가 많아졌으면 좋겠다는 큰 꿈을 가지고

더 고급기능을 가지고 확장성이 좋은 PostgreSQL을 선택했다.

 

그리고 실무에서도 많이 사용한다고 하니 한번쯤은 사용해 보고 싶었다. 

 

 

 

 

 

프리티어 기간이 지나면, 비용을 지불하면서 RDS를 사용해야 한다. 

보통 Amazon Aurora(Mysql과 PostgreSQL 을 클라우드 기반에 맞게 재구성한 데이터 베이스) 로 많이 교체한다.

 

하지만 Aurora는 프리티어 대상이 아니고, 최저 비용이 10만원대 이기 때문에 

 

처음 시작할때는 MySQL, MariaDB, PostgreSQL 중에서 선택하는 것을 추천한다. 

 

 

 


 

이제 본격적으로 RDS 인스턴스를 생성해 보겠다. 

 

 

1. RDS 생성에 들어가서 PostgreSQL 을 선택한다.

 

밑에 나오는 데이터 베이스 엔진 버전은 기본 값으로 두었다. 

 

 


 

2. 프리티어 템플릿 선택하기 

 

 

프리티어로 사용하기 위해서는 프리티어 템플릿을 사용하자 

 

 


 

3. DB 인스턴스와 마스터 사용자 설정

 

 

 

 

 

DB 이름과 마스터 사용자 이름을 설정한다.

AWS 자습서에는 아래 예시처럼 이름을 설정해 놓았다. DB에는 하이픈, 이름에는 언더바를 사용하는 듯 하다. 

tutorial-db-instance

tutorial_user

 

Auto generate a password(암호 자동 생성) 옵션은 끈 상태로 둔다. 

 

그리고 암호 입력

 

실제 데이터 베이스에 접근하려면 여기서 설정한 사용자 정보로 접근하므로 사용자 이름과 비밀번호는 따로 적어두자

 

 

 


 

4. 인스턴스 구성 및 스토리지

 

 

 

이때는 기본값인 db.t3.micro 로 유지해 놓는다. 

 

 

 

스토리지도 20GB 기본 값으로 둔다. 

이때, 스토리지 자동 조정을 클릭하면, 활성화가 되어 있는 것을 볼 수 있다. 이를 체크 해제해주자.

안그러면 과금이 발생할지도 모른다!!!

 

 

 


 

 

5.  EC2 연결하기 

 

 

 

앞서 생성한 EC2 인스턴스를 RDS에 연결할 것이다. EC2 컴퓨팅 리소스에 연결을 선택하자 

 

그후 인스턴스를 선택하면 되는 데, 생성한 것이 있으면 자동적으로 밑에 뜰 것이다. 해당 것을 클릭하면 된다.

만약 안뜬다면, EC2와 RDS를 생성한 지역이 동일한지 살펴보자..! 

EC2는 서울에 있는데 RDS는 다른지역에서 생성했으면, 서울에서 생성한 EC2는 보이지 않는다..

 

 

 

+ 추가) 

테스트를 위해서 퍼블릭 엑세스 기능을 활성화 하고 싶다면 다음과 같이 설정하면 된다. 

 

 

이후 보안 그룹에서 지정된 IP 만 접근하도록 막을 예정이다. 

 

 

그리고 보안 그룹도 새로 생성해준다. 

 

포트 번호도 기억해두자..!

 


 

 

6.  데이터 베이스 인증 

 

 

 

위에 설정한 암호로 인증할 것이다. 기본 설정 그대로 암호 인증을 선택한다. 

 


 

7. 모니터링 

 

 

 

모니터링도 혹시나 과금이 될지도 모르니 선택을 해제했다. 

 


 

8. 추가 구성

 

 

추가 구성을 눌러서, 데이터 베이스 이름을 작성한다. 

그리고 백업 기능도 체크 해제!! 스냅샷 생성 또한 과금 발생 우려도 있으며 DB 메모리도 많이 차지하게 된다. 

 

 

그 아래는 기본 설정으로 둔 뒤, 데이터 베이스 생성을 클릭한다. 

 

 

 

 

콘솔로 다시 가면 생성된 것을 볼 수 있다. 

 


 

 

RDS 파라미터 설정하기 

 

 

1. 왼쪽 탭에서 파라미터 그룹 클릭


 

2. 파라미터 그룹 생성을 클릭하여 새로운 그룹을 만든다. 

 

 

 


 

3.  엔진 버전 설정하기 

 

 

생성한 PostgreSQL 엔진과 같은 버전을 맞춰야 한다. 

15.3 버전이므로 15를 선택한다.  

 

 

그 다음, 파라미터 이름과 설명을 설정하고 만들기를 누른다. 

 

 

 

4. 서울 시간으로 설정하기 

 

파라미터 수정에 들어가서 편집을 누르고 timezone 을 검색한다음, UTC+9 를 입력한다. 

 

 

다른 블로그 글을 보다보면, Mysql 로 설정한 경우 Character Set 을 utf8mb4 로 변경해 주는 것을 볼 수 있다. 

하지만 postgresql은 그럴 필요가 없다. 

 

utf8mb4 는 표준 인코딩 방식이 아니며 MySQL 의 UTF-8 이 3 byte만 지원하는 문제를 해결하기 위한 땜질 처방입니다.
PostgreSQL 이나 Oracle, MS-SQL 등을 사용한다면 이런 문제를 고민할 필요가 없습니다

 


 

5. 최대 연결 변경하기 

 

 

좀 더 넉넉한 값으로 최대 연결을 증가시켜준다. 

 

 


 

6. 수정한 파라미터 규칙 적용하기 

 

 

이제 새로 만든 파라미터 규칙을 내가 생성한 RDS에 적용할 것이다. 

RDS 에 들어가서 내가 만든 DB를 선택한 뒤 수정을 눌러준다. 

 

 

 

그 다음 추가 구성을 누른다. 

default 로 되어 있는 것을 내가 새롭게 만든 파라미터 그룹으로 바꿔서 설정한다. 

 

 

 

 

그 다음 즉시 적용을 눌러 DB 인스턴스를 수정한다. 

 

 

 


 

7. 내 PC에서 RDS 접속해보기 

 

 

로컬 PC에서  RDS로 접근하기 위해서 RDS의 보안 그룹에 내 PC의 IP를 추가해야한다. 

 

 

1. RDS 세부 정보 페이지에서 보안그룹 항목 클릭 및 인바운드 규칙 편집 

 

 

 

2. ec2 보안그룹 추가

 

 

이렇게 하면 EC2와 RDS 간에 접근이 가능하다. 

 

 

 

 

 

다음 글에서는 Datagrip 을 사용하여 AWS의 RDS를 접근하는 것을 해 보겠다. 

728x90
반응형