반응형

전체 글 391

Q. 파이썬 팩키지 pika로 래빗엠큐RabbitMQ로 접속할 때 나타나는 에러는?

A. 연결 설정 오류로 StreamLostError: ('Transport indicated EOF',) 등 에러가 발생한다. 래빗엠큐 AMQP 기본 port는 5672다. 그런데 엉뚱한 port를 입력한다면? import pika connection = pika.BlockingConnection( pika.ConnectionParameters(host='localhost', port=3306)) channel = connection.channel() channel.queue_declare(queue='hello') channel.basic_publish(exchange='', routing_key='hello', body='Hello World!') print(" [x] Sent 'Hello World..

Q. 래빗엠큐RabbitMQ에서 ack의 의미는?

A. acknowledgment 확인, 인지란 뜻이다. 아래 출처를 보면 ack(nowledgement)란 표현을 볼 수 있다. 발음은 애크라고 읽는 것 같다. In order to make sure a message is never lost, RabbitMQ supports message acknowledgments. An ack(nowledgement) is sent back by the consumer to tell RabbitMQ that a particular message had been received, processed and that RabbitMQ is free to delete it. 출처: Message acknowledgment 파이썬 pika 팩키지를 활용할 경우 auto_ack..

Q. 파이썬으로 래빗엠큐RabbitMQ 메시지를 보내고 받고 싶다면?

A. pika 팩키지를 활용하면 된다. RabbitMQ 공식 홈페이지에 pika 튜토리얼이 있다. 튜토리얼 그대로 따라하면 쉽게 테스트를 해볼 수 있다. 도커로 RabbitMQ 실행하기 /Users/taptorestart 부분은 여러분의 경로로 수정하면 된다. 참고: rabbitmq dockerhub docker run --name rabbitmq \ -p 5672:5672 \ -p 15672:15672 \ -v /Users/taptorestart/rabbitmq:/var/lib/rabbitmq \ -d rabbitmq:3.11.10-management 이 때 중요한 것은 -p 5672:5672도 적어줘야 한다는 점이다. 실행했으면 접속하자. http://localhost:15672/ 로 접속하고 id,..

무료 플랫폼은 뭘로 돈을 벌까?

광고와 거래다. 광고를 해주고 수수료를 받고, 시장을 만들어서 거래를 주선하고 수수료를 받거나 물건을 직접 판다. 사람이 많이 모이는 곳 사람이 많이 모이는 곳은 정보를 널리 알리기에, 곧 광고를 하기에 좋다. 사람이 많이 모이니 당연히 물건을 사고 팔기에도 좋다. 그런 곳을 소유하고 있다면 광고를 하고 싶은 사람들과 물건을 팔고 싶은 사람들이 연락을 해온다. 그 사람들에게 광고를 할 수 있는 공간이나 물건을 사고 팔 수 있는 공간을 내주고 돈을 받을 수 있다. 출퇴근 때 이용하게 되는 지하철을 생각해보자. 지하철에는 광고가 붙어 있고, 역 안에는 가게들이 있다. 불꽃축제, 벚꽃축제 등 많은 사람들이 모일 것으로 예상되는 날이 되면 어김없이 물건을 팔려는 노점상들이 축제 장소 근처에 몰려드는 것도 마찬가..

Q. 래빗엠큐RabbitMQ를 종료하고 재시작하면 큐에 쌓여 있던 메시지가 사라질까?

A. Durability 설정이 durable이고, Delivery mode가 persistent 라면 메시지가 남아 있다. RabbitMQ 실행 우선 RabbitMQ를 실행하자. 도커를 사용한다면 아래 명령어로 쉽게 RabbitMQ를 실행할 수 있다. /Users/taptorestart 부분은 여러분의 경로로 수정하면 된다. 참고: rabbitmq dockerhub docker run --name rabbitmq \ -p 5672:5672 \ -p 15672:15672 \ -v /Users/taptorestart/rabbitmq:/var/lib/rabbitmq \ -d rabbitmq:3.11.10-management 실행했으면 접속하자. http://localhost:15672/ 로 접속하고 id, ..

"측정할 수 없다면 관리할 수 없다."라고 피터 드러커는 말한 적이 없다고?

드러커가 했다고 하는 그 말KPI(핵심성과지표)와 평가에 관한 HR 담당자의 설명을 듣다가 눈에 띄는 문장이 있었다. "측정할 수 없다면 관리할 수 없다." - 피터 드러커 피터 드러커. 경영학의 아버지라고 불리기도 하는 그 분이다. 실제 검색해보면 비슷한 문장을 인용한 칼럼들을 쉽게 찾을 수 있었다. 서평 / 성과지표의 배신, 김태완, 물류신문, 2022. 6. 15. [ET단상]'Plan-Do-See'의 오류, 류승범, 전자신문, 2022. 8. 23. 등 모두 피터 드러커가 말했다고 피터 드러커를 인용하고 있다. 예를 들면 피터 드러커는 “측정할 수 없다면 관리할 수 없고, 관리할 수 없으면 개선할 수도 없다”라고 말했다. ... 출처: [ET단상]'Plan-Do-See'의 오류, 류승범, 전자신문..

Q. 깃허브 풀리퀘스PullRequest 때 테스트를 자동화하는 방법은?

A. 깃허브GitHub 워크플로우workflows를 활용하면 쉽게 테스트를 자동화할 수 있다. pytest를 실행하는 예 깃허브 저장소에 .github 폴더를 만들고 그 아래 workflows를 만든다. 그리고 아래 내용을 담은 yml 파일을 만든다. 이름은 아무 거나 가능하다. tests.yml로 만들자. name: Test on: pull_request: branches: - main jobs: build: runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v3 - uses: actions/setup-python@v4 with: python-version: '3.6' - run: | python -m pip install --upgrade pip pyth..

Q. JetBrains의 제품(IntelliJ, WebStorm 등) 개인 라이선스나, 커뮤니티 에디션으로 회사에서 상업용 제품을 개발해도 될까?

A. 가능하다. 문제 없다. 공식 사이트에 답변을 보자. 개인용 라이선스를 회사와 집에서 사용할 수 있나요? 네, 개인용 라이선스는 회사에서도, 집에서도 사용할 수 있습니다. 회사 프로젝트뿐만 아니라 개인 프로젝트에서도 사용할 수 있습니다. JetBrains EULA에서는 이를 제한하지 않습니다. 개인용 라이선스를 상업적 개발 작업에 사용할 수 있나요? 네, 개인용 라이선스를 모든 종류의 개발 작업에서 사용할 수 있습니다. 단, 본인의 개인용 라이선스를 사용해야 하며 다른 이들과 공유하면 안 됩니다. 또한 회사에서 개인용 라이선스를 대신 결제하거나 상환하거나 어떤 방식으로든 자금을 지원하면 안됩니다. 개인용 라이선스를 회사에서 쓰는 것은 괜찮으나, 회사가 개인용 라이선스 자금을 지원하면 안 된다. 이 문..

개발 Dev 2023.02.19

테스트 주도 개발이 기능부터 개발하는 것보다 더 빠르고 안정적이다

테스트 주도 개발Test Driven Development(TDD)란? 켄트 벡이 창시한 개발 방법론으로 테스트부터 작성하는 개발 방법론이다. 먼저 통과하지 못할 테스트를 작성하고 테스트를 통과하도록 코드를 작성한다. 그 뒤 코드를 개선, 리팩터링하고 테스트하는 과정을 반복하는 식이다. 리팩터링 책으로 유명한 마틴 파울러가 추천하는 개발방식이다. TDD의 가장 큰 특징은? 테스트 주도란 명칭처럼 테스트부터 작성한다! 기능부터 작성 → 테스트가 아니라, 테스트 → 기능 코드 작성이다. 파이썬을 예를 들면 테스트부터 작성한다. def test_sum() assert sum(1, 2) == 3 당연히 sum 함수 구현이 안 되어 있으니 테스트는 실패한다. 위 테스트가 성공할 때까지 sum함수를 구현하는 식이다..

테스트Test 기반 없는 코드 리뷰Code Review의 비효율성과 위험성

코드 리뷰 코드 리뷰를 하는 리뷰어는 보통 눈으로 변경된 코드를 읽고 자신의 의견을 말한다. 코드 전체가 아니라 바뀐 부분만 주로 본다. 따라서 코드 변경에 따른 의도하지 않은 부작용까지는 생각하기 어렵다. 리뷰어는 의견을 낼 뿐 책임지지 않는다. 책임은 코드 작성자 몫이다. 테스트 기반 없는 코드 리뷰의 비효율성 리뷰어가 제시한 사소한 변경이라도 만에 하나 있을 부작용 확인을 위해 작성자는 매번 테스트를 해야 한다. 테스트가 없는 상태라면 일일이 리뷰어의 의견을 반영할 때마다 관련 코드 전반을 테스트 해야 한다. 리뷰어들이 같은 시간 한꺼번에 리뷰해주면 좋겠지만 A 리뷰어, B리뷰어가 리뷰하는 시간은 다른 경우가 대부분이다. 따라서 리뷰를 받을 때마다 테스트하게 된다. 테스트 기반 없는 코드 리뷰의 위..

Q. 장고Django에서 같은 이름으로 인덱스index를 추가할 수 있을까?

A. 장고 2.2.x 버전에서는 추가할 수 있고, 장고 3.2.x 버전에서는 추가할 수 없다. 장고 버전 3.2.x에서 인덱스 name을 같은 이름으로 하면 유일한 이름이 아니라고 makemigrations에서 에러가 발생한다. 사례 예제 코드 DRF - CRUD를 활용해서 테스트 해보자. 테스트를 위해서 모델에 아래처럼 인덱스를 추가하자. class Category(models.Model): name = models.CharField(max_length=200) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) class Meta: db_table = "category" ..

상개약수上開若水, 최고의 개발자는 물과 같다

동료들과 이야기를 나누다가 상선약수가 떠올랐다. 최고의 개발자는 혹시 물과 같지 않을까. 노자의 상선약수 “최고의 선은 물과 같다.(上善若水) 물은 선하여 만물을 이롭게 하지만 다투지 않는다.(水善利萬物而不爭) 뭇 사람들이 싫어하는 낮은 곳으로 자리를 잡는다.(處衆人之所惡) 그러므로 물은 도에 가장 가까운 존재다.(故幾於道).”( ‘8장 이성·易性’) 출처: 물을 깔보지 마라 물은 동그란 유리병에도, 사각형 용기에도 어느 형태에든 맞출 수 있다. 투명해서 어떤 색의 병에 담아도 그 병 색이 된다. 물은 다투지 않는다. 스며든다. 언제나 낮은 곳에 자리 잡는다. 개발자가 물과 같다면 누구와 함께 일해도 어떤 회사에서 일해도 맞출 수 있다. 어느 팀에든 프로젝트에든 예전부터 그곳에 있었던 것처럼 스며들어 있..

Q. 장고Django 쿼리셋Queryset에서 select_related보다 prefetch_related 사용을 권장하는 이유는?

A. 조인 분해를 통해서 성능상에서 이익을 얻는 경우가 많기 때문이다. select_related와 prefetch_related SQL 쿼리 예 Q. 장고Django ORM에서 n+1 이슈란? n+1 이슈 해결 방법은?란 글에서 다뤘듯이 select_related는 INNER JOIN을 사용한다. prefetch_related는 INNER JOIN을 사용하지 않고 조인을 분해한다. 앞의 글에서 다뤘던 예를 다시 가져오면 아래와 같다. select_related SQL 쿼리 예 SELECT `app_beverage`.id, `app_beverage`.name, `app_beverage`.category_id, `app_beverage`.price, `app_beverage`.is_available, `a..

Q. MySQL에서 count(*)과 count()의 차이는?

A. count(*)은 WHERE 조건이 있다면 조건에 해당하는 모든 행수를 얻을 수 있고, count(칼럼명)의 경우는 해당 칼럼명의 데이터를 조회해서 NULL이 아닌 데이터가 들어 있는 행수를 얻을 수 있다. InnoDB 엔진 예 간단히 coffee란 테이블을 만들어서 5개의 데이터를 넣었다. 맨 마지막 5번 데이터는 NULL을 넣었다. 이 상태에서 SELECT count(*) FROM coffee; 를 실행하면 5가 나온다. 만약 칼럼명인 name으로 SELECT count(name) FROM coffee; 하게 되면 4가 결과로 나온다. 두 경우 모두 Query Cost를 살펴보면 0.75이고 Full Table Scan이 발생한다. SELECT count(*) FROM coffee; SELECT..

Q. 장고Django ORM에서 n+1 이슈란? n+1 이슈 해결 방법은?

A. n+1 이슈란 목록을 조회할 때 주로 발생하며, 연관된 데이터까지 가져올 때 데이터 개수(n으로 표현)만큼 추가로 데이터베이스를 조회하는 이슈를 뜻한다. 해결 방법은 쿼리셋을 가져올 때 select_related 또는 prefetch_related를 사용하는 것이다. n+1 이슈 예아주 간단히 카페 메뉴 정보를 저장하는 API 서버를 만드는 경우를 생각해보자. (예제 코드: DRF - CRUD) 카테고리 테이블과 음료 테이블 두 개가 있다. 카테고리 테이블에는 커피, 티를 입력했고, 음료에는 카테고리를 커피로 선택해서 아메리카노, 카페 라떼, 에스프레소, 카푸치노를 입력했다. 카테고리 테이블과 음료 테이블 사이의 관계는 카테고리 1개에 여러 음료가 연결될 수 있으니 1 : n(일 대 다) 관계다. ..

Stack Overflow보다 ChatGPT가, 아니 검색보다 ChatGPT가 더 편한 거 같다

예를 들어 Python에서 리스트 순서를 유지하면서 중복을 제거하는 방법을 알고 싶다. 구글에서 검색하면 아래처럼 나왔다. 맨 위에 구글이 만들어 준 방법이 나오긴 하지만 부족하다. 다시 검색 결과를 눌러서 들어가서 실제 코드도 보고 테스트도 해봐야 한다. ChatGPT한테 물었다. 와. 사람이 알려주듯 1번 2번 3번 정리해서 알려주고, 코드 예시까지 제공해준다. 아직 약간 부족하긴 하다. 한국어로 질문해서 그럴 수도 있겠지만 갑자기 문체가 바뀌니 어색하게 느껴진다. 다른 질문도 해봤다. ChatGPT가 나보다 면접을 잘 볼 거 같다. ChatGPT 서비스를 계속 무료로 쓸 수 있다면 코드 궁금한 건 검색보다 ChatGPT한테 먼저 물어보게 될 거 같다. 검색 광고에 의존하는 구글은 어떻게 될까... ..

Q. 파이썬Python에서 타입 힌트Type hints를 적으면 타입이 변경될까?

A. 아니다. 변경되지 않는다. 아래처럼 text란 변수의 type을 int로 선언했다. 값은 "hello!"를 저장하고, type을 찍어보면 어떻게 될까? text: int = "hello!" print(type(text)) 입력값인 "hello!"의 타입인 str이 된다. int가 아니다. 에러도 발생하지 않는다. 너무 단순한 예라 그런 거고 다른 경우는 다를 거 같다고 생각할 수 있다. DRF(Django Rest Framework)에서 아래처럼 테스트를 해보자. request를 엉뚱하게 str이라고 선언한다. 그리고 type을 확인한다. 역시나 원래 타입인 rest_framework.request.Request로 나오는 것을 확인할 수 있다. 타입 힌트는 말 그대로 힌트다. 정적 타입 언어인 다른..

Q. 쿠키cookie에서 HttpOnly 속성의 기능은?

A. 자바스크립트로 document.cookie로 쿠키에 접근할 수 없게 된다. Set-Cookie: =; HttpOnly 위 예처럼 Cookie를 설정했다면 자바스크립트로는 접근이 안 된다. 실제 사례 아래 예(소스코드)를 보면 sessionid의 경우 HttpOnly인 상태인 것을 알 수 있다. document.cookie로 sessionid를 얻으려고 확인해보면 값이 없는 것을 확인할 수 있다. MDN 설명을 보자. A cookie with the HttpOnly attribute is inaccessible to the JavaScript Document.cookie API; it's only sent to the server. For example, cookies that persist in s..

Q. 장고Django의 View와 DRF의 APIView의 인증 관련 차이는?

A. CSRF 보호 제외 여부다. DRF(Django Rest Framework)의 APIView 자체도 from django.views.generic import View를 상속받아서 만든 것이다. View에 API에 주로 쓰도록 기능이 추가된 형태로 볼 수 있다. APIView의 as_view 메소드를 보자. @classmethod def as_view(cls, **initkwargs): """ Store the original class on the view function. This allows us to discover information about the view when we do URL reverse lookups. Used for breadcrumb generation. """ if i..

반응형