전체 글 334

GPT와 함께한 3년

2023년 1월, 플피에서 1년을 채우고 코파일럿이 한창 유행일 때에 ChatGPT를 처음 사용했다.그 때부터 지금까지 3년이 넘는 시간동안 gpt 무료버전을 아주 알뜰하게 잘 사용했다. 최소 정보로 어떻게 답을 얻을 수 있을까개인/회사의 정보를 노출하지 않고 얼마나 정확한 답을 얻을 수 있을까항상 고민했던 항목이다.그러다보니 대화의 깊이가 깊어지면 더 깊어지고, 얕으면 더욱 얕아질 수 밖에 없었다.최근 면접에서 GPT 사례로 인한 면접자의 성향을 알아본다는 글을 봤던 기억이 있다.그래서 재미로 나도 해봤다. Q. 지금까지 나의 질문성향으로 봤을때 내 성격을 얘기해봐 A. 지금까지의 질문 패턴만 기준으로 추정하면 다음과 같은 성향이 보입니다.1. 실용주의 성향이 강함질문 대부분이 이론 자체보다 실제 서비..

생각정리 2026.06.22

대용량 쿼리 벌크 업데이트

그동안 잘못 알고 있었던 사실.DB에 최소한으로 접근하는 것이 항상 좋다.-> DB에 연결된 트랜잭션의 시간이 길어진다면, 전체적인 데이터베이스의 접근하는 속도가 저하된다. 사실 위 의미대로라면 분할로 업데이트하는 청크는 설명될 수 없다.NestJS, MySQL, Typeorm의 예를 들어보겠다. 1. 업데이트에 필요한 행만큼 쿼리문 실행async bulkMap(dto: BulkDto): Promise { let updatedCount: number = 0; await this.entityManager.transaction(async (em) => { for(const item of dto.items){ const result = await em..createQueryB..

Server/성능개선 2026.02.19

2025년 회고

조금은 늦었지만 2025년 회고를 작성해본다. 25년도에 맞이한 가장 큰 변화는 이직이다.그동안 30인 이하의 스타트업에서만 근무를 했었고, 25년 7월에 총 사원수 300명에 육박하는 기업에 입사했다.내가 속한 팀의 팀원은 20명 정도였고, 개발파트 인원은 나 포함 3명이다.작은 기업에서도 항상 개발팀의 인원은 많았고, 입지가 두터웠다면 현재의 회사에서는 그와 정반대의 느낌이다. 이직 하위의 가장 큰 변화는 세 가지가 존재한다. 1. 내가 만든 제품을 사용하는 사용자가 존재한다.여러 회사를 거치면서 많은 프로젝트를 진행했지만 항상 사용자는 거의 존재하지 않았다.어떤 문제점이 있을까, 어떻게 해결해야될까는 늘 추상적이고 글로만 접했으며 개인프로젝트에서만 해결했었던 사건들이었다.지금은 라이브 로그를 가만히..

생각정리 2026.01.09

Next 14 & React 18) 빌드에러

오랜만에 넥스트를 돌렸는데 이상한 에러가 발생해서 해결하는데 이틀이나 소요됐다.Error: should not be imported outside of pages/_document.TypeError: Cannot read properties of null (reading 'useState')Error occurred prerendering page "/_not-found".Export encountered an error on /_not-found/page: /_not-found, exiting the build. 이외에 여러 에러도 만나봤지만, 해결했던 결론만 먼저 이야기하고 시작하겠다. 나의 경우 아래를 확인하니 해결됐다.echo $NODE_ENV# development 진행중인 백엔드 프로젝트에서..

Client/Next.js 2025.12.31

JS & TS) Map으로 시간복잡도 줄이기

C++에서는 map, set을 엄청 자주 사용했는데,JS에서는 이상하게 사용을 안하게 된다.그러다 반복문에서 include, find 등 람다식을 사용해 이중포문을 만들게 되었고. 5만건의 유저 업데이트 중, O(n2)이라는 무시무시한 경험을 해버렸다.그래서 부랴부랴 C++에서 사용했던 맵을 다시 사용했다. const users: User[] = await this.userRepo.find();// new Mapconst userMap: Map = new Map(users.map((u) => [u.id, u]));// hasif(userMap.has(1)) console.log('id 1인 유저 포함');// getconst user1 = userMap.get(1);// setuserMap.set(2,{..

Server/성능개선 2025.12.10

평균 15s API 응답속도 2s로 줄이기

문제상황모든 구매목록을 가져오는 API가 있다.총 구매목록은 2만여건이지만, 조인된 테이블들의 데이터 가짓수를 합치면 60만여건이 넘었다.DTO를 활용하여 모든 테이블을 조인하고 테이블별 검색조건을 where절로 한 번에 검색할 수 있는 편리함이 있었지만, 검색을 하지 않아도 되는 상태에서도 모든 테이블을 조인하는 문제가 있었다.그래서 해당 페이지에 진입하면 모든 구매목록을 가져오기 때문에 15초라는 긴 시간이 소요됐다. 해결방법리스트 페이지는 디테일 정보를 표기할 필요가 없으므로, 필요없는 테이블은 조인에서 제외한다.DTO에 따라 검색조건이 들어오면, 필요한 테이블만 조인한다.인덱스를 탈 수 없는 LIKE 검색은 최소화한다.검색조건으로 사용되는 컬럼들은 인덱싱을 설정한다. 사이드 이펙트해당 API에서 ..

Server/성능개선 2025.10.17

MySQL, TypeORM) Lock으로 동시성 문제 해결

전제조건product 테이블에는 stock이라는 재고가 있다.재고는 0이 되면 구매할 수 없다.a, b 유저가 동시에 동일한 상품을 구매한다. 로직 a, b유저는 재고가 존재하는 상품의 정보를 불러온다.SELECT * FROM product WHERE id = 1 AND stock > 0; 문제 상황a가 먼저 상품을 구매하고 재고를 차감하여 재고가 0이 되면, b는 불러왔던 상품을 구매할 수 없다.트랜잭션을 사용했지만 두 유저가 동시에 테이블에 접근하는건 막을 수 없었다. 해결 방법상품을 읽을 때 부터 Lock을 걸어 해당 행을 다른 유저가 가져올 수 없게 만든다.Lock을 건 상황에서 에러가 발생했다면, 빠르게 락을 해제해야한다. 무한히 기다리는 데드락이 발생할 수 있기 때문.SELECT * FROM ..

Server/성능개선 2025.10.17

NestJS) AWS-S3 효율적인 업로드 방법

배경회원가입시 이미지를 s3에 업로드한다.방법 1프론트에서 이미지를 인풋태그에 삽입하면, 블롭으로 이미지를 만들어 미리보기를 만든다.서버에 formData로 바로 전송해 하나의 API에서 검증 및 S3업로드, 다른 로직을 수행한다. 장점하나의 API에서 작업하니 편리하다 단점바디를 formData로 받아야한다.스웨거 작성 등 직접 나열해야 하는 이유로 불편하다.방법 2프론트에서 이미지를 인풋태그에 삽입 시, API를 한 번 호출한다.API에서는 getSignedUrlPromise 함수로 만료시간이 존재하는 임시 이미지를 버킷에 생성한다.해당 url과 파일 정보를 받아 프론트에서 이미지 태그로 미리보기를 만든다.서버에 json 바디로 파일정보를 가입할 회원의 정보와 함께 송신한다.서버에서는 회원 검증을 마..

Server/성능개선 2025.08.07

NestJS) 의존성주입에서 객체 초기화 문제

먼저 백그라운드를 정해본다. 1. AppModule에 임포트 순서대로 모듈의 초기화가 진행된다.import { Module } from '@nestjs/common';import { TypeOrmModule } from '@nestjs/typeorm';import { AppController } from './app.controller';import { AppService } from './app.service';import { EnvConfigModule, TypeOrmConfigService,} from './config';import { AuthModule } from './modules/auth/auth.module';import { AdminModule } from './modules/adm..