목록전체 글 (146)
개발자 블로그

Onechain 거래소에서 의존성 관리를 위한 도구로 기존의 requirements.txt 대신 pipenv를 도입하게 되었습니다. 이 글에서는 왜 이 전환을 하게 되었는지, 어떤 변화가 있었는지, 그리고 얻은 이점과 고려할 점들을 공유하려고 합니다.1. 기존의 requirements.txt 방식많은 Python 개발자들이 의존성 관리 도구로 requirements.txt를 사용합니다. 간단하고 익숙한 방식이기 때문에 널리 사용되어 왔죠. requirements.txt 파일은 프로젝트에서 필요한 패키지들을 명시하고, pip 명령어를 사용해 한 번에 설치할 수 있게 해줍니다.$ pip install -r requirements.txt그러나 이 방식은 다음과 같은 한계를 가지고 있었습니다:환경 격리 부족: ..

이번 포스팅에서는 우리 팀이 어떻게 코드 품질을 높이고 일관된 코드 스타일을 유지하기 위해 자동 포매팅 도구들을 도입했는지 이야기해 보려 합니다. 특히 협업이 많은 환경에서 코드 스타일의 일관성은 유지보수성과 가독성에 큰 영향을 미치기 때문에, 도입을 위해 동료 개발자들과의 논의도 중요했던 경험이었습니다.왜 자동 포매팅이 필요한가? 협업 환경에서는 다양한 개발자들이 각자의 스타일로 코드를 작성하게 되기 때문에, 시간이 지나면 코드베이스는 일관성을 잃고 가독성이 떨어지기 쉽습니다. 이로 인해 코드 리뷰 시 불필요한 논쟁이 발생하거나, 코드 디버깅과 유지보수에 더 많은 시간이 소요될 수 있습니다. 자동 포매팅을 통해 코드 스타일을 일관되게 유지하면 코드 리뷰가 간소화되고 품질 관리도 수월해집니다. 그래서 우..

이번 포스팅에서는 Harmony 서비스 상품 팀이 대규모 트래픽과 복잡한 데이터 처리를 효율적으로 관리하기 위해 CQRS(Command Query Responsibility Segregation)를 도입하고, 배포 시 발생했던 Deadlock 문제를 어떻게 해결했는지 소개하려 합니다.문제 상황: Materialized View Refresh로 인한 Deadlock과 데이터 정합성 이슈 초기에는 조회 성능을 개선하기 위해 Materialized View를 도입해 데이터를 조회했습니다. 하지만 배포 시, Materialized View를 Refresh하는 배치 작업과 마이그레이션 트랜잭션이 맞물리면서 Deadlock이 발생했습니다. 이러한 Deadlock은 배포를 지연시키고, Refresh 주기를 1분으로 ..
커머스 플랫폼 하모니 서비스 백오피스에서 상품 데이터를 엑셀로 다운로드할 수 있는 기능을 제공하고 있었습니다. 하지만, 데이터의 양이 10만 row를 넘어가는 경우 **메모리 초과(Out of Memory)**가 발생하여 서버가 다운되는 문제가 있었습니다. 이를 방지하기 위해 임시로 기능을 제한해 두었지만, 비즈니스 요구사항을 충족하기 위해 이 기능을 최적화하는 프로젝트를 맡게 되었습니다. 이번 포스팅에서는 대용량 데이터를 처리하면서도 안정적인 시스템을 유지하기 위한 최적화 과정과 적용한 기술들에 대해 소개하고자 합니다.1. 비동기적 처리로 기획 수정대량의 데이터를 동기적으로 처리하는 대신, 비동기적인 방식으로 다운로드 프로세스를 설계했습니다. 이를 위해 다음과 같은 절차를 따랐습니다:이벤트 결과 모델링..
파이썬의 경우 가장 빠른 퀵솔트로 sort()함수가 구현이 되어있다. 퀵 솔트란? 기준 데이터를 설정하고 그 기준 보다 작은 데이터들을 왼쪽으로 큰 데이터들은 오른쪽으로 위치를 바꾸어 주며, 바뀐 데이터들 이와 같은 방법으로 재귀적으로 실행되며 정렬되는 방식. 평균적인 시간 복잡도는 O(nlogn)이고 최악의 경우, O(n**2)이 된다. 정렬 알고리즘 중 가장 빠른 시간을 자랑하지만, 기준 데이터에 따라 최악의 시간 복잡도를 가질 수 있다. 따라서, 적절한 pivot(기준)을 정해주는 것이 중요하겠다. python 또한, 내부적으로 항상 nlogn으로 pivot을 설정하여 작동하게 끔 구현이 되어있다. def quick_sort(array: list) -> list: if len(array)

함수가 호출되어 저장되어 사용되는 곳이 스택 메모리 영역이다. 재귀함수는 함수가 호출 되면서 함수 자기 자신을 또 다시 호출하는 방식으로 재귀함수 호출 시 스택 메모리에 호출 된 함수들이 계속 쌓이게 된다. 스택은 LIFO(선입선출) 구조이기 때문에 가장 마지막에 호출된 함수 factorial(1)를 먼저 완료하고, 값을 아래로 전달하여 최초로 호출된 함수 factorial(3)가 최종 값을 계산한다. 따라서, 재귀함수를 호출할 때 스택 메모리 공간이 초과되는 스택 오버플로우가 발생되는 오류를 주의하며, 과도한 스택 메모리가 사용되지 않도록 조심하며 사용해야한다.

컴퓨터에서 숫자를 기억하는 방식은 2진수 즉, 0과 1로만 모든 것을 표현한다. 이 때문에 오는 오차가 있어 사용 시 주의해야할 상황이 있는데 이는 float 타입을 사용할 때이다. 예를들어, 0.1이라는 숫자를 컴퓨터가 저장하는 방식은 이진수로 나타낸다면, 무한히 반복되는 숫자가 되버린다. 하지만 컴퓨터는 이러한 수를 근삿값으로 저장한다. 떄문에 정확한 값을 저장하지 않는다는 말! 이러한 문제를 해결하기 위해 파이썬에서는 decimal.Decimal, round() 등 여러가지 메소드를 통해 부동소수의 한계를 해결하는 방법 등이 있긴하다. 하지만, 이 또한, 완벽히 문제를 해결하는 방법이 아닐 수도 있으니, 사용할 시 주의하고 상황에 맞는 방법을 활용하도록 하자! 결론, 정확한 소수점 계산을 해야할 때..

함수를 정의하고, 파라미터의 기본값을 정의를 하는 경우가 많다. 하지만, 사용 시 주의 사항이 있다. mutable 한 객체를 함수의 디폴트 파라미터로 사용하지 말라는 것이다. 예제를 통해 살펴보자! def add_sharp(s = []): s.append('#') return s s = [1, 2, 3] print(add_sharp(s)) # [1, 2, 3, '#'] print(add_sharp()) # ['#'] print(add_sharp()) # ['#'] print(add_sharp()) # ['#'] 우리가 예상한 결과값은 주석 처리를 한 값이다. 하지만, 실제 결과값은 그렇지 않다. 파이썬에서 함수의 디폴트 인자들은 __defaults__ 또는 __kwdefaults__ 어트리뷰트의 저장된..
get methhod는 조회나 검색에 활용되는 http method이다. 따라서 클라이언트에서 서버로 데이터를 보낼 때, 다른 방식과 다르게 request body에 실어 보내지 않는다. 따라서 get method에서 데이터를 서버에 보내기 위해선 QueryString을 사용하거나 path parameter로 데이터를 보내야 합니다. QueryString: /endpoint?key1=value1&ket2=value2 path parameter: /endpoint// 두 가지 쓰임이 있기에 상황에 따라 두가지를 사용하면 되겠다. 우선 쿼리 스트링의 경우, Id와 같이 정확한 데이터의 정보가 아닌 경우에 쓰이며, 조건에 맞는 쿼리셋을 사용자에게 보여줄 때 사용된다. 반면, 경로 인자는 객체의 id값과 같은..
문제 설명 1389번: 케빈 베이컨의 6단계 법칙 첫째 줄에 유저의 수 N (2 ≤ N ≤ 100)과 친구 관계의 수 M (1 ≤ M ≤ 5,000)이 주어진다. 둘째 줄부터 M개의 줄에는 친구 관계가 주어진다. 친구 관계는 A와 B로 이루어져 있으며, A와 B가 친구라는 뜻 www.acmicpc.net 나의 풀이 from collections import deque, defaultdict # 기준이 되는 start_num을 기준으로 너비 탐색을 통해 kavin_bacon리스트의 인덱스 정보를 # 나를 기준으로 얼마나 떨어져있는지 카운트 정보를 담는다. # 현재 숫자가 tartget_num이라면, kavin_bacon의 해당 값을 반환 def bfs(graph, start_num, target_num):..