AWS 백서 : AWS 서비스 알아보기

AWS 이 글은 누군가 AWS를 다룰 때 조금이나마 덜 고생하길 바라는 마음으로 작성하며, 부정확한 정보에 대한 지적, 정정을 환영하고 자신이 아는 바가 있다면 얼마든지 추가해주길 바랍니다. 앞으로 지속적으로 추가할 예정입니다. What is AWS? 아마존 웹 서비스(AWS, Amazon Web Service)는 아마존닷컴의 클라우드 컴퓨팅 사업부이다. 아마존 웹 서비스는 다른 웹 사이트나 클라이언트측 응용 프로그램에 대해 온라인 서비스를 제공하고 있다. Region 아마존은 클라우드 컴퓨팅을 제공하기 때문에, 데이터센터를 곳곳에 보유하고 있다. 주 고객층을 생각해 물리적으로 가까운 리전을 선택한다. ...

2024년 1월 31일 · 6 분 · 배준수

print와 logging의 차이 : stdout buffer

Today I Learned 날짜 2024년 1월 31일 수요일 내용 logging과 print 문의 차이 : stdout buffer logging과 print의 차이에 대해 많이 찾아봤는데 디버깅을 위해선 logging문을 쓰는 것이 좋다는 의견이 대다수다. 사실 그냥 다 logging을 쓰라고 한다. 단순 출력이 아닌, 오류 메시지나 변수 내용, 위치 등을 다양하게 출력할 수 있으니 print가 쓰기는 편해도 전체 디버깅 작업의 속도를 높이는데는 logging이 훨씬 효과적이다. backgrountasks에서 print가 작동이 안되는 이유에 대해선 정확한 내용을 찾기 힘들었는데, stdout buffer가 원인이라는 얘기가 있다.stdout은 표준 출력 데이터를 의미한다. 반대로 stdin은 표준 입력(ex. 키보드) 데이터를 의미한다. 백준에서 알고리즘을 풀다보면 키보드 입력을 input() 이나 sys.stdin.readline() 으로 받곤 하는데 여기서 stdin이 나오는 걸 알 수있다. print 함수는 stdout을 사용하여 출력한다. print문이 콘솔창에 찍히는 것도 표준 출력으로서 나타나는 것. ...

2024년 1월 31일 · 3 분 · 배준수

2.2 웹과 HTTP(1)

2.2 웹과 HTTP(1) 2.2.1 HTTP 개요 웹의 애플리케이션 계층 프로토콜인 **HTTP(HyperText Transfer Protocol)**는 웹의 중심이다. **웹 페이지(Web page, 문서)**는 객체(object)들로 구성된다. **객체(object)**는 단순히 단일 URL로 지정할 수 있는 하나의 파일(HTML 파일, JPEG 이미지, 자바스크립트, CCS 스타일 시트 파일, 비디오 클립 등)이다. 대부분의 웹 페이지는 기본 HTML 파일과 여러 참조 객체로 구성된다. 각 URL은 2개의 요소를 갖고 있다. 객체를 갖고 있는 서버의 호스트 이름 객체의 경로 이름 **웹 브라우저(Web browser)**는 HTTP의 클라이언트 측을 구현하기 떄문에 웹의 관점에서 클라이언트와 브라우저는 혼용된다. HTTP는 TCP를 전송 프로토콜로 사용한다. 과정 HTTP 클라이언트가 먼저 서버에 TCP 연결을 시작 브라우저와 서버 프로세스는 각자의 소켓 인터페이스를 통해 TCP로 접속. 소켓 인터페이스는 각 프로세스와 TCP 연결 사이에서의 출입구다. 서버와 클라이언트는 메시지를 소켓 인터페이스에게 보낸다. 이후 부터는 TCP의 몫이다. HTTP는 **비상태 프로토콜(stateless protocol)**이다. 클라이언트에 대한 정보를 유지하지 않기 떄문이다. 2.2.2 비지속 연결과 지속 연결 클라이언트-서버 상호작용이 TCP상에서 발생할 때, 각 요구/응답 쌍이 분리된 TCP 연결을 통해 보내지면 비지속 연결(non-persistent connection) 모든 요구와 해당하는 응답들이 같은 TCP 연결상으로 보내지면 지속 연결(persistent connection) HTTP/1.0가 디폴트 모드로 지속 연결을 사용하지만 HTTP 클라이언트와 서버는 비지속연결을 사용하도록 설정될 수 있다. 비지속 연결 HTTP 클라이언트가 서버에게 URL을 통해 html 파일을 요청한다고 가정해보자. HTML 파일은 여러 개의 참조 객체 이미지를 가진다. HTTP 클라이언트는 HTTP 기본 포트 번호 80을 통해 서버로 TCP 연결을 시도한다. 그 결과 클라이언트와 서버는 각각 소켓을 가진다. 클라이언트가 자신의 소켓을 통해 HTTP 요청 메시지를 보낸다. 이 요청에는 필요한 html의 경로 이름을 포함한다. 서버는 소켓으로 요청 메시지를 받고 필요한 html 객체를 추출한다. 응답 메시지에 객체를 캡슐화하고 소켓을 통해 클라이언트로 보낸다. HTTP 서버는 TCP에게 TCP 연결을 끊으라고 한다(하지만 실제로는 클라이언트가 응답을 올바로 받을 때까지 끊지 않는다). 클라이언트가 응답 메시지를 받으면 TCP 연결이 중단된다. 필요한 참조 객체(이미지) 10개를 가져오기 위해 각각의 객체에 대한 TCP 연결이 시작된다(1~4 반복). 비지속 연결에선 총 11개의 TCP 연결이 발생한다. 순차적으로 하지 않고 동시 연결(동시에 11개의 연결을 구성하여 각각 처리)로 응답 시간을 줄일 수 있다. 세 방향 핸드셰이크(three-way handshake) SYN(Synchronize) : 클라이언트가 서버에 연결을 요청하는 메시지를 보냄 SYN-ACK(Synchronize-Acknowledment) : 서버가 클라이언트의 연결 요청을 수락하고, 클라이언테에게 확인 응답을 보냄 ACK(Acknowledgment) : 클라이언트가 서버의 확인 응답을 받고, 다시 서버에 확인 메시지를 보내 연결을 완료한다. RTT(round-trip time) : 패킷이 클라이언트로부터 서버까지 가고, 다시 클라이언트로 돌아오는 데 걸리는 시간 세 방향 핸드셰이크 중 2단계가 완료될때 까지의 시간이 RTT다. ACK는 2단계가 완료된 후 요청 메시지를 보낼 때 같이 보낸다. 서버에 요청을 보낼 떄는 (TCP 연결 + 요청)이 필요하다. 따라서 서버의 응답시간은 (2RTT + 파일 전송 시간)이다. 지속 연결 HTTP 비지속 연결의 단점 각 요청 객체에 대한 새로운 연결이 설정되고 유지되어야 함. 이를 위해 필요한 TCP 버퍼는 서버에게 부담이 될 수 있음. 응답시간 (2 RTT) 지속 연결은 하나의 지속 TCP 연결로 여러 웹페이지와 관련 객체를 통신할 수 있다. 파이프라이닝(pipelining) : 각 객체에 대한 요구는 진행 중인 요구에 대한 응답을 기다리지 않고 연속해서 만들어질 수 있음. HTTP 서버는 타임아웃 기간동안 사용되지 않으면 연결을 닫기 떄문에, HTTP 디폴트 모드는 파이프라이닝을 이용해 지속 연결한다.

2024년 1월 30일 · 3 분 · 배준수

QA, 구글 API 비용 예측

Today I Learned 날짜 2024년 1월 30일 화요일 내용 계속 QA를 진행하고 있다. 키워드 추출 실패 갑자기 특정 경우에 키워드를 추출해내는데 실패하고 있다. 키워드는 nltk 관련 문제라 AI가 고장난 건 아니였다. 안되는 상품의 URL을 들어가보니 리뷰들이 모두 한글로 작성되어있었다. 그동안 리뷰가 당연히 영어로 가져와질 것이라고 생각했는데, 원어(작성 언어)와 접속시 설정한 언어 중 하나로 선택할 수 있었다. 문장을 단어 단위로 쪼개는 tokenize는 punkt 데이터를 사용하는데 어제 말했듯 정말 다양한 언어 데이터가 존재하지만, 긍정 부정을 판별하는 opinion_lexicon은 영어밖에 없었다. 리뷰를 항상 영어 번역하여 가져오도록 했더니 해결되었다. ...

2024년 1월 30일 · 4 분 · 배준수

파이썬 알고리즘 : 뉴스 클러스터링

2024년 1월 30일 알고리즘 문제풀이 문제 뉴스 클러스터링 난이도 Lv.2 코드 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 42 def solution(str1, str2): def check(x): if x[0].islower() and x[1].islower(): return True else: return False str1 = list(str1) str2 = list(str2) arr1 = [] arr2 = [] for i in range(len(str1) - 1): if str1[i].isupper(): str1[i] = str1[i].lower() if str1[i + 1].isupper(): str1[i + 1] = str1[i + 1].lower() if check(str1[i] + str1[i + 1]): arr1.append(str1[i] + str1[i + 1]) for i in range(len(str2) - 1): if str2[i].isupper(): str2[i] = str2[i].lower() if str2[i + 1].isupper(): str2[i + 1] = str2[i + 1].lower() if check(str2[i] + str2[i + 1]): arr2.append(str2[i] + str2[i + 1]) arr_all = arr1 + arr2 arr_set = set(arr_all) n_max = 0 n_min = 0 for i in arr_set: n_max += max(arr1.count(i), arr2.count(i)) if i in arr1 and i in arr2: n_min += min(arr1.count(i), arr2.count(i)) if str1 == str2: answer = 65536 elif not n_max and not n_min: answer = -1 else: answer = int((n_min / n_max) * 65536) return answer 우선 문자열을 배열로 만들었다. 이후 각 원소가 대문자라면 소문자로 만들어주었다. 대문자, 소문자 구별이 없기 때문에 비교를 수월하게 하기 위함이다. 리스트의 두 원소를 붙여서 check 함수를 통해 둘다 소문자로 이루어진 알파벳인지 확인한다. 앞서서 대문자를 모두 소문자로 바꿔서 대문자일 가능성은 없다. 굳이 두개를 나눠야 하는 이유는, “%a” 에게 islower() 메서드를 사용하면 a가 소문자라 True를 반환하기 떄문이다. 앞에 %는 무관하다. 물론 “%” 처럼 알파벳이 없다면 False를 반환하다. 따라서 둘 다 알파벳으로 이루어졌는지 확인하기 위해 check() 함수에서는 둘을 나눴다. 이후 합집합의 갯수와 교집합의 갯수를 확인하기 위해 알파벳 2개가 원소인 리스트를 합쳐 set로 만들었다. 중복된 원소를 제거하여 교집합과 합집합 계산에 경우의 수를 낮추기 위해서다. 둘 다 공집합이면 -1을 반환해야하는데, 합집합 교집합이 0일 떄로 확인했다. 다만 예시 3번처럼, “%a!” 와 “%A!” 는 실제로 2개씩 잘랐을 때 모두 알파벳 2개로 이루어지지 않아(%a, a!) 집합이 없게 표시되지만 자카드 유사도는 1이다. 알파벳의 대문자 소문자 여부를 따지지 않기 때문에 완전히 동일한 두 문자열이기 떄문이다. 이럴 때를 확인하기위해 소문자로 바꾸고 리스트화 한 이후 둘이 같다면 자카드 유사도가 1이라 66536을 곱하여 나눈 정수부분을 그대로 출력하도록 했다. ...

2024년 1월 30일 · 2 분 · 배준수

NLTK 데이터 파일 저장하기

Today I Learned 날짜 2024년 1월 29일 월요일 내용 기능 개발이 끝나고 QA를 시작했다. nltk 지난주에 nltk 패키지에서 필요한 데이터들을 templates 폴더에 추가하여 추가적인 다운로드 없이 사용하도록 코드를 작성했었다. 테스트 서버에서 오류가 발생했는데, 범인은 금요일이 연차여서 존경하는 선배님께서 원상복구 해주셨다. 문제 해결을 위해, 고민의 원점에 서서 차근차근 생각하며 다양한 방법을 생각했다. 현재 해결하고자 하는 것은 무엇인가? nltk 패키지에서 사용할 데이터 다운로드 횟수를 최소한으로 만들자. 그 목적은 무엇인가? 불필요하게 반복되는 데이터 다운로드는 리소스 낭비기 때문이다. 해결하기 위한 방법들은 무엇들이 있는가? templates 디렉토리 내에 데이터를 저장한다(현재). S3, Git Large File Storage 등의 스토리지 서비스를 이용한다. dockerFile에 이미지 빌드 시 필요한 데이터를 다운로드 하도록 한다. 방법 (a)의 동작을 정상화 시킨다고 하더라도, 간과한 문제가 있었다. nltk에서 다운로드 하는 데이터는 3가지다. ...

2024년 1월 29일 · 3 분 · 배준수

파이썬 알고리즘 : N개의 최소 공배수

2024년 1월 25일 알고리즘 문제풀이 문제 N개의 최소 공배수 난이도 Lv.2 코드 1 2 3 4 5 6 7 8 9 10 11 12 def solution(arr): num = max(arr) i = 1 while True: answer = num*i for x in arr: if answer%x: i += 1 break else: return answer 어떤 수들의 최소공배수는 모든 수의 배수라는 의미이다. 따라서 수 들중 가장 큰 수의 배수를 모두 탐색하여 어떤 수로도 나누어 떨어질 때가 최소공배수이다. 가장 큰 수로 하는 이유는, 그나마 횟수를 조금이라도 낮추기 위해서이다. ...

2024년 1월 29일 · 1 분 · 배준수

파이썬 알고리즘 : 문자열 나누기

2024년 1월 26일 알고리즘 문제풀이 문제 문자열 나누기 난이도 Lv.1 코드 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 def solution(s): answer = 0 while s: x = s[0] num_x = 0 not_x = 0 for i in range(len(s)): if s[i] == x: num_x += 1 else: not_x += 1 if num_x == not_x: answer += 1 s = s[i+1:] break else: return answer+1 return answer

2024년 1월 26일 · 1 분 · 배준수

누구나 이해할 수 있는 코드 짜기

Today I Learned 날짜 2024년 1월 25일 목요일 내용 낫 놓고 기억자도 모름 알리익스프레스에서 크롤링을 제한해두었다. 어제 겪은 문제의 원인이다. 상품 정보를 가져오지 못하는 이유를 온갖 곳에서 찾았을 때 분명 보았던 글이고, 생각도 해봤지만 특정하지 못했다. 개발 실력을 키우는 수준에서 가능한 것과 그렇지 않은 것을 구별해내는 능력은 아직 먼 일일지도 모르겠지만, 좀 갖고싶다. 코드개선 오늘은 전체적으로 내가 작성한 코드의 퀄리티를 높이는 작업을 했다. 타입 힌팅 : 함수들의 반환 타입을 지정해주었다. 재사용성할 필요성은 느끼지 못해서 스키마에 추가하진 않았다. 키워드인자 : 함수를 정의할 때 parameter도 정의한다. 함수를 호출할 때 정의한 순서대로 값을 넣을 수도 있고(위치인자), 정의한 parameter 이름으로 넣을 수도 있다(키워드인자). 키워드 인자는 어떤 값이 어떤 인자로 쓰여있는지 확실히 알 수 있기 때문에, 여러 사람이 보는 코드에서 불필요한 혼동을 줄여준다. nltk 데이터 : 받은 리뷰들을 각 단어의 원형으로 토큰화하고, 긍부정을 판별하기 위해서 데이터가 필요하다. 데이터가 자주 업데이트 되지 않다보니 한번만 다운로드 하도록 변경했다. 기존에는 분석함수 호출할 떄마다 다운로드했는데, 큰 것은 용량이 122MB다 보니 너무 비효율적이다. S3 버킷에 넣을까 고민했는데, 매번 가져와서 조회하는 것도 효율적이지 않다고 생각했다. 그럼 docker-compose에 빌드할 때 다운로드하도록 추가할 것도 고민해봤다. 하지만 애초에 데이터를 저장해두는 이유는, 이 데이터가 업데이트가 잘 되지 않기 떄문이다. 최근 업데이트가 2016년이였으니까.. 그냥 위젯이나 이메일 템플릿 저장하듯이 디렉토리에 추가해주었다. 괜히 어렵게 생각했네. 회고 평탄할 줄 알았지만 힘든 한주였다. ...

2024년 1월 25일 · 1 분 · 배준수

파이썬 알고리즘 : 정수 제곱근 판별

2024년 1월 25일 알고리즘 문제풀이 문제 정수 제곱근 판별 난이도 Lv.1 코드 1 2 3 4 5 6 7 def solution(n): tmp = int(n**(0.5)) if tmp**2 == n: answer = (tmp+1)**2 else: answer = -1 return answer 제곱근은 0.5제곱과 같음.

2024년 1월 25일 · 1 분 · 배준수