코딩은 마라톤

[대외활동] 큐시즘(KUSITMS) 30기 밋업 프로젝트 회고 본문

대외활동/KUSITMS

[대외활동] 큐시즘(KUSITMS) 30기 밋업 프로젝트 회고

anxi 2024. 12. 26. 08:09

서론

한 달 여만에 블로그를 작성하네요...

큐시즘에서 진행한 밋업이 성공적으로 마무리되고, 큐시즘 30기 수료까지 끝이 났습니다.

 

지금이야말로 회고 적기 최적의 순간

 

기업 프로젝트가 끝나고 회고를 작성했으니, 밋업도 쓰는 게 인지상정 (기업 프로젝트 회고 : https://developer-anxi.tistory.com/60)

30기 밋업 프로젝트 회고 지금 시작합니다! 


프로젝트 소개

우리 팀이 만든 서비스는 "조각조각"입니다.

‘조각조각’은 일상 속에서 발생하는 자투리 시간을 의미 있게 활용할 수 있도록 돕는 개인 맞춤형 활동 추천 서비스입니다.

 

자투리 시간?

개인 맞춤형 활동 추천 서비스?

 

글을 읽고 무슨 서비스인지 이해하기 어려울 수 있어요.

그런 분들은 우리 서비스를 한 번 사용해 보시면 좋을 거 같습니다! (제발 사용해 달라는 뜻.)

 

 

제발..

배포 링크 : https://cnergy.kro.kr/

 

나의 시간조각을 모아, 조각조각

 

cnergy.kro.kr

 

조각조각은 

  • 사용자의 자투리 시간의 정도와 다양한 정보(온라인, 오프라인)를 입력받고
  • 사용자가 원하는 활동 키워드를 입력받아
  • 사용자에게 AI 기반 개인 맞춤형 활동을 추천합니다.
  • 사용자의 활동을 아카이빙 할 수 있고
  • 월별 조회를 통해 사용자가 의미 있게 활용한 활동과 자투리 시간을 확인한다.

그다음은..

 

여기에 담는 것보다 아래 링크를 들어가면 매우 잘 정리된 자료가 있다고!?!

 

기획 의도와 기능 등의 자세한 정보가 궁금하다면, https://github.com/KUSITMS-30th-TEAM-C

 

KUSITMS-30th-TEAM-C

큐시즘 30기 밋업 프로젝트 C팀. KUSITMS-30th-TEAM-C has 3 repositories available. Follow their code on GitHub.

github.com

 

여기서 자세하게 읽어보실 수 있습니다!


개발

역할

 

저는 백엔드를 담당했고, 개발팀 리드를 맡았습니다.


구현 과정 및 성능 개선

1. OAuth를 활용한 회원가입 및 로그인

구글, 네이버, 카카오..?

 

OAuth를 활용한 소셜 로그인 구현을 해본 적이 없었습니다.

프로젝트 초기 설정 후, 구현할 첫 기능이었는데

구글, 네이버, 카카오를 모두 해볼 수 있어 몹시 설렜습니다 ㅎㅎㅎ

 

OAuth 인터페이스 사용
인터페이스를 구현하는 구글 구현체
인터페이스를 구현하는 네이버 구현체
인터페이스를 구현하는 카카오 구현체

 

위와 같이 DIP(의존 역전 원칙)를 적용하여 인터페이스를 각 써드파티에서 구현할 수 있게 만들었습니다.

OAuthRestClient를 생성자 주입 및 Factory 패턴을 활용하여 런타임 시점에 구현체를 동적으로 선택할 수 있게 구현하였습니다.


2. 메인 홈 조회 / 3. 빠른 시작 조회, 등록, 수정 / 4. 아카이빙 활동 캘린더 조회

 

저희 서비스에서는 활동 조회 기능이 중요한 요소였기 때문에, 이를 개선하는 데 중점을 두었습니다.

기존 개발 방식의 경우, JPA를 통해 활동 엔티티를 가져와서 이를 DTO로 변경 후 반환하였습니다.

 

기존

// 엔티티 전부를 가져오는 쿼리
@Query("""
    select a
    from ActivityJpaEntity a
    where a.memberId = :memberId
    and a.createdAt between :startDateTime and :endDateTime
    and a.finished = true
    order by a.createdAt ASC
""")
List<ActivityJpaEntity> findByMemberIdAndCreatedAtBetweenAndFinishedTrue(
        UUID memberId, LocalDateTime startDateTime, LocalDateTime endDateTime
);

// 엔티티 조회 후 변환하는 로직
List<ActivityJpaEntity> entityResults = activityJpaDao.findByMemberIdAndCreatedAtBetweenAndFinishedTrue(
        memberId, startDateTime, endDateTime
);
List<HomeActivityInfoResponse> response = entityResults.stream()
        .map(entity -> new HomeActivityInfoResponse(
                entity.getId(),
                entity.getKeyword(),
                entity.getTitle(),
                entity.getSavedTime()
        )).toList();

 

위와 같이 구현했었지만, 아래와 같은 생각이 들었습니다.

반환하는 DTO의 필드는 id, keyword, title, savedTime 4개의 필드인데 
과연 불필요한 컬럼을 가져와서 스트림으로 변환하는 로직을 짜는 게 맞을까? 
JPA에서 무조건 엔티티만 반환해야 하나?

 

이 생각을 하게 되었고, 찾다 보니 DTO 프로젝션 방식을 통해 필요한 컬럼만 가져오는 방법을 찾게 되었습니다.

 

DTO 프로젝션 적용

// DTO Projection
@Query("""
    select new spring.backend.activity.dto.response.HomeActivityInfoResponse(
        a.id,
        a.keyword,
        a.title,
        a.savedTime
    )
    from ActivityJpaEntity a
    where a.memberId = :memberId
    and a.createdAt between :startDateTime and :endDateTime
    and a.finished = true
    order by a.createdAt ASC
""")
List<HomeActivityInfoResponse> findTodayActivities(UUID memberId, LocalDateTime startDateTime, LocalDateTime endDateTime);

// 변환 로직 불필요
List<HomeActivityInfoResponse> response = activityJpaDao.findTodayActivities(memberId, startDateTime, endDateTime);

 

JPQL을 사용해서 DTO 프로젝션을 통해 원하는 필드만 가져오게 되었습니다.

그렇다면, 과연 성능 상의 차이(이점)가 있을지 테스트했습니다.

 

성능 테스트

 

전제 조건 : 데이터 100,000건 기준

 

프로젝션 없이 전체 필드를 조회한 결과   |   DTO 프로젝션 해서 특정 필드만 조회한 결과

 

불필요한 전체 필드를 조회한 후 DTO로 변환하는 경우에는 1127ms가 소요된 반면,
DTO 프로젝션을 통해 필요한 특정 필드만 조회한 경우에는 337ms로,
약 3배 이상의 성능 개선을 확인할 수 있었습니다.

 

그렇다면, 전부 DTO 프로젝션을 하면 성능 개선이 되는 거 아닌가요?!

 

라고 생각하실 수 있지만, 꼭 그렇지는 않습니다.

이 부분에 경우, 이동욱(향로)님께서 우아콘 QueryDSL 성능 개선 발표에서 언제 프로젝션 하면 좋은지 설명해 주셔서 보시는 것을 꼭 강추드립니다!

https://www.youtube.com/watch?v=zMAX7g6rO_Y&t=477s

보시면 절대 후회 안합니다..! 넘 도움되는 강연 감사합니다 ㅎㅎ

 

그래서 홈 조회뿐만 아니라 빠른 시작 및 활동 캘린더 조회에서도 JPQL + DTO 프로젝션을 통해 성능 개선을 하였습니다!


5. 온라인 추천 - OpenAI / Youtube API

OpenAI를 연동하는 방법은 https://developer-anxi.tistory.com/64  참고해 주시면 됩니다:)

 

[SpringBoot + OpenAI(ChatGPT)] SpringBoot에서 OpenAI API를 이용해 연동하기

진행 중인 프로젝트에서 최근 ChatGPT를 연동해서 응답을 받아와야할 상황이 생겼습니다.OpenAI Java SpringBoot 라이브러리도 있기는 하지만 (https://github.com/TheoKanning/openai-java?tab=readme-ov-file)라이브러리

developer-anxi.tistory.com

 

원래는 클로바 AI를 활용하여 온라인, 오프라인의 추천 기능을 활용하려고 하였지만, AI 추천 정확도가 오프라인에서 좋았어서

온라인은 OpenAI를 사용하였습니다.

 

또한 추천을 받을 때, 플랫폼이 유튜브이면 유튜브 API를 사용해서 유튜브 링크를 제공하는 기능도 있었습니다.

OpenAI와 Youtube API를 연동할 때도 OAuth 소셜 로그인과 동일하게 DIP를 적용하였습니다.

 

 

추천 AI 인터페이스 사용
인터페이스를 구현하는 Clova 구현체

 

인터페이스를 구현하는 OpenAI 구현체

 

DIP를 적용할 때, 요청 DTO는 Clova와 OpenAI 모두 동일했지만

응답 DTO의 경우, 필드가 서로 다르기 때문에 제네릭을 사용해서 DIP를 적용했습니다.


6. 활동 종료 (수동, 자동)

활동 종료 기능을 구현하는 것이 가장 재밌었습니다 ㅋㅋㅋ!

사실 활동 종료를 수동으로 사용자가 종료하는 것은 API를 만들어서 상태를 변경하면 되는 것이라 간단하다는 생각이 들었는데,

문제는 자동 종료였습니다.

 

자동 종료는 사용자가 활동 추천을 받을 때 입력한 자투리 시간이 지나면 자동으로 종료가 되는 기능입니다.

자동 종료도 수동 종료와 같이 "비슷하겠지~"라는 생각을 했지만, 상황에 닥치니 어떻게 해야 할지 고민이 많아졌습니다.

띠용

 

고민했던 방식은 다음 두 가지입니다:

  1. 스케줄러 사용
    짧은 주기로 상태를 계속 확인하는 방식입니다.
  2. RabbitMQ 사용
    메시지의 TTL(Time-To-Live)을 설정해 일정 시간이 지나면 자동으로 처리되는 방식입니다.

각 방식의 장단점을 비교해 보았습니다.

 

1. 스케줄러 사용

  • 장점:
    • 구현이 간단하고 추가적인 외부 시스템에 의존하지 않는다.
  • 단점:
    • 어느 정도 주기로 실행해야 효율적인지 결정하기 매우 어렵다.
    • 짧은 주기로 스케줄러를 실행하면 계속 스레드를 사용하게 되어 성능 문제가 발생할 수 있다...

2. RabbitMQ 사용

  • 장점:
    • TTL을 설정하면 메시지의 만료 시간이 정확히 관리된다.
    • 비동기로 처리되므로 애플리케이션 내에서의 부하가 적다.
  • 단점:
    • RabbitMQ에서 TTL을 사용해 본 적이 없고, 러닝 커브가 있다.
    • TTL이 지난 메시지가 큐에서 제거되지 않고 Dead Letter Queue (DLQ)로 이동하게 되는데, 이 과정에서 해당 메시지를 다시 사용할 수 없다..

계속해서 찾아본 결과, RabbitMQ Delayed Message Plugin 을 알게 되었고

이 플러그인을 사용하면, 간단한 설정을 통해 메시지를 지연시킬 수 있고 지연시킨 메시지를 다시 사용할 수 있게 됩니다.

따라서 플러그인을 사용해 기능을 구현하였습니다!

 

휴우.. 시원

 

 

https://www.rabbitmq.com/blog/2015/04/16/scheduling-messages-with-rabbitmq

 

Scheduling Messages with RabbitMQ | RabbitMQ

For a while people have looked for ways of implementing delayed

www.rabbitmq.com

 

플러그인을 사용한 메시지 지연 처리 방법은 조만간 블로그에 작성하겠습니다.

 


7. Scheduler를 통해 빠른 시작 이메일 알림

빠른 시작을 미리 등록해 두면, 사용자에게 이메일 알림을 통해 사용을 유도하였습니다.

 

이메일 알림은 15분 주기로 수행되며, 이메일 알림을 구현할 때도 고민 지점이 꽤 있었습니다.

 

스케쥴러 VS 스프링 배치

 

원래는 이메일 전송을 구현하기 위해 스프링 배치를 사용했습니다.

스프링 배치를 선택한 이유는, 이메일을 전송할 사용자를 청크 단위로 읽어 들여 처리하면 효율적일 것이라고 판단했습니다.


ItemReader에서 메일을 보낼 사용자를 조회하고, ItemWriter에서 메일을 전송하는 방식으로 설계하려 했지만,

벌크 전송 방식이 아닌 비동기로 개별 사용자에게 메일을 보내는 방식을 선택하면서 스프링 배치를 사용하지 않기로 결정했습니다.

Spring Batch의 특성

 

추가로, 스프링 배치는 트랜잭션 관리, 재시도 및 로깅, 대용량 데이터 처리에서 강점을 가지지만, 

위 강점을 주기적으로 메일 전송하는 데 사용될까?라는 생각이 들었고
결국, 이 경우 스프링 배치를 사용하는 것은 오버 엔지니어링에 해당한다고 생각해, 스케줄러를 사용하는 방식으로 전환했습니다.

 

이메일 벌크로 전송 VS 비동기로 개별 사용자에게 전송

 

이메일을 처음에 동기식으로 개별 사용자에게 반복문을 사용해서 보내려고 하였습니다.

 

3명 기준

개별 + 동기 방식

 

벌크 전송

 

  • 개별 + 동기 방식
    • SMTP 연결이 매번 사용자마다 열리고 닫히는 과정이 반복되어 시간이 오래 걸립니다.
  • 벌크 방식
    • 한 번의 SMTP 연결로 여러 사용자에게 메일을 전송할 수 있어 효율적입니다.

이러한 이유로 처음에는 벌크 방식으로 구현했습니다.
하지만...

받는 사람이 모두 표시되는 문제 발생...

 

따라서, 비동기 방식으로 개별 사용자에게 메일을 전송하기로 결정했습니다.

 

비동기로 구현함으로써, 이전의 동기 방식에서 발생했던 SMTP 연결과 해제 과정의 반복적인 시간 소모를 줄이고,
여러 쓰레드를 활용해 동시에 여러 사용자에게 개별적으로 메일을 보낼 수 있는 구조를 설계했습니다.


도메인 주도 설계 (DDD)

이번 프로젝트에서는 기능 구현보다 "설계"에 더욱 중점을 두고 진행했습니다.

설계 기법으로 도메인 주도 설계(DDD)를 채택하여, 시스템의 핵심 도메인과 그에 관련된 비즈니스 로직을 중심으로 설계하였습니다.

 

프로젝트 구조 - 활동 도메인

├── BackendApplication.java
├── activity
│   ├── application
│   │   ├── QuickStartActivitySelectService.java
│   │   ├── ...
│   ├── domain
│   │   ├── entity
│   │   │   └── Activity.java
│   │   ├── repository
│   │   │   └── ActivityRepository.java
│   │   ├── service
│   │   │   ├── FinishActivityService.java
│   │   │   └── ...
│   │   └── value
│   │       ├── Keyword.java
│   │       └── ...
│   ├── exception
│   │   └── ActivityErrorCode.java
│   ├── infrastructure
│   │   ├── mapper
│   │   │   └── ActivityMapper.java
│   │   ├── persistence
│   │   │   └── jpa
│   │   │       ├── adapter
│   │   │       │   └── ActivityRepositoryImpl.java
│   │   │       ├── dao
│   │   │       │   └── ActivityJpaDao.java
│   │   │       ├── entity
│   │   │       │   └── ActivityJpaEntity.java
│   │   │       ├── repository
│   │   │       │   └── ActivityJpaRepository.java
│   │   │       └── value
│   │   │           └── KeywordJpaValue.java
│   │   └── queue
│   │       ├── FinishActivityMessage.java
│   │       ├── FinishActivityMessageConsumer.java
│   │       └── FinishActivityMessageProducer.java
│   ├── presentation
│   │   ├── FinishActivityController.java
│   │   ├── ...
│   │   ├── dto
│   │   │   ├── request
│   │   │   │   ├── ActivitiesByMemberAndKeywordInMonthRequest.java
│   │   │   │   ├── ...
│   │   │   └── response
│   │   │       ├── ActivitiesByMemberAndKeywordInMonthResponse.java
│   │   │       ├── ...
│   │   └── swagger
│   │       ├── FinishActivitySwagger.java
│   │       ├── ...
│   └── query
│       └── dao
│           └── ActivityDao.java

 

아키텍처

  • 각 기능을 명확히 분리하여 응용 계층(application), 도메인 계층(domain), 인프라스트럭처 계층(infrastructure), 표현 계층(presentation)으로 나누어 관리하였습니다.
  • 표현 계층: API 요청과 응답을 처리하며, Swagger를 통해 API 문서를 관리
  • 응용 계층: 비즈니스 로직을 수행하는 서비스들이 위치 / 표현 영역과 도메인 영역을 연결하는 매개체 역할
  • 도메인 계층: 핵심 엔티티와 도메인 영역에 위치한 도메인 로직을 표현하는 도메인 서비스가 존재
  • 인프라스트럭처 계층: 구현 기술에 대한 것을 다룸(DB연동, 메시징 큐에 메시지 전송, 수신 등 실제 구현)
  • query(dao): 조회 전용 기능 담당

이외에도 DIP를 사용해서 저수준 모듈이 고수준 모듈에 의존하게 해서 계층 구조를 지키려고 노력하였습니다.

 

도메인 주도 설계 공부는 이 책으로 했었는데 추천드립니다!! (제가 정리해 둔 블로그 글도 있으니 많관부~!)

https://product.kyobobook.co.kr/detail/S000001810495

 

도메인 주도 개발 시작하기: DDD 핵심 개념 정리부터 구현까지 | 최범균 - 교보문고

도메인 주도 개발 시작하기: DDD 핵심 개념 정리부터 구현까지 | 가장 쉽게 배우는 도메인 주도 설계 입문서!이 책은 도메인 주도 설계(DDD)를 처음 배우는 개발자를 위한 책이다. 실제 업무에 DDD를

product.kyobobook.co.kr


찐 회고

위에서는 개발 구현 과정과 성능 개선 사항, 그리고 고민했던 지점들에 대해 작성했습니다..

개발자가 아니시더라도 지금까지 읽어주셨다면, 진심으로 감사의 말씀을 전합니다!!!

 

Keep

코드리뷰에 진심 人

 

이번 프로젝트를 진행하면서 코드 리뷰를 가장 열심히 했던 것 같습니다.

 

백엔드 같은 팀에서 함께한 호영이 형은 이전에 자바/스프링이 아닌 Node로 개발을 했었습니다. 처음에는 부족한 제가 형에게 코드 리뷰를 하면서 변경을 요구할 수 있을지 고민이 많이 들었지만, 호영이 형이 코드 리뷰를 해주는 것이 너무 좋고, 고맙다고 말하며 자신에게 도움이 많이 된다고 말해주어서, 진심을 담아 코드 리뷰를 하게 되었습니다.

 

코드 리뷰를 할 때, 저만의 규칙이 있었습니다.

  1. 리뷰는 최대한 객관적인 근거를 가지고 한다.
    주관적으로 "이 코드보단 이게 나을 것 같은데?" 보다는, 책이나 블로그 등을 참고하여 근거를 들어 리뷰를 하려고 했습니다.
  2. 형이 작성한 코드를 전부 이해하고 리뷰한다.
    당연히 코드 리뷰를 하려면 코드를 전부 봐야 하지만, 때때로 코드 이해를 제대로 하지 않고 리뷰할 수 있다는 생각이 들었습니다. 코드를 정확히 이해하지 않으면 형이 어떤 생각을 가지고 코드를 작성했는지 알 수 없었습니다. 전부 이해한 후에는 제가 구현하지 않았음에도 제가 구현한 것처럼 학습한 느낌을 받았습니다.

이펙티브 자바에서 떠오른 기억을 기반으로 리뷰!

 

자세하게 설명해주고 있는 호영이 햄

 

코드 리뷰를 진행하면서 서로 많은 대화를 나누고, 많은 것을 배운 과정이 된 것 같습니다!

이 자리를 빌려, 부족한 리뷰를 받아주고 열심히 리뷰해 준 호영이 형에게 감사의 마음을 전합니다 🥰


구현보다 소통에 진심 

 

저는 기능 구현보다 기획 의도를 명확히 이해하는 것이 중요하다고 생각했습니다.

기획 의도를 제대로 파악하지 않고 기능을 빠르게 구현하면, 남은 기능들을 빠르게 처리할 수는 있겠지만, 기획 측과의 소통 부재로 인해 추후에 추가적인 개발이 필요할 수 있다고 생각했습니다. 그래서 저는 슬랙과 피그마를 활용하여 기획 의도를 명확히 이해하고, 필요한 부분에 대해서는 제안을 하는 등 기능 구현보다는 기획 단계에서의 충분한 소통에 집중했습니다.

기능 <<<<<<<< 소통


DDD에 진심 

 

밋업 프로젝트 이전부터 기능 구현도 중요하지만 설계의 중요성을 깨닫고 있었습니다. 그래서 도메인 주도 설계(DDD)에 관심을 갖고, 책을 읽으며 DDD를 학습하고 있었고, 이를 밋업 프로젝트에 최대한 적용해보고 싶었습니다.

 

책을 통해 DDD를 왜 사용하는지 잘 체감되지 않았지만, 직접 프로젝트에 적용해 보니 그 필요성과 장점이 확실히 느껴졌습니다.

예를 들어, 각 도메인 객체가 명확한 책임을 가지게 되어 코드의 응집도가 높아 유지보수가 용이하고, 테스트 코드 작성 시에도 도메인 객체들을 독립적으로 모킹(Mock)할 수 있어 단위 테스트가 쉽다고 생각했습니다.


Problem

완벽에 집착 人

 

밋업 프로젝트는 2개월이라는 짧은 기간 동안 기획부터 개발까지 모두 마쳐야 했습니다. 저는 이 기간 동안 팀의 역량을 최대한 발휘하여 가능한 한 완성도 높은 프로덕트를 만들고 싶었습니다.

특히 백엔드 개발을 맡으면서 DDD 설계를 최대한 적용하고, 기능 구현 전 기능 분담을 어떻게 할지에 대해 필수적으로 고민했습니다. 또한, 코드 리뷰는 최대한 꼼꼼히 진행하며, 심지어 공백 하나하나까지 확인하면서 리뷰를 했습니다. 이런 자세는 제 성격상 완벽을 추구하는 부분도 있었지만, 팀원인 호영이 형에게 과도한 부담을 주지 않았을까 하는 아쉬움이 깊게 남습니다.

호영이 형 미아내


부족한 개발리드 人

 

초등학생, 중학생 때 매번 학급 반장, 부반장을 했었습니다..

하지만 고등학생 때부터 밋업 프로젝트 전까지 리드 역할을 맡은 적이 없었고, 리더를 해보면 어떨까 해서 이번 밋업 시작할 때 제가 하게 되었습니다!

 

개발 리드의 역할은 다음과 같습니다:

  • 매주 개발팀 회의를 진행
  • 개발팀의 개발 현황을 확인하고, 다른 파트와 소통
  • 해야 할 일과 공지 사항을 팀원들에게 전달
  • 등 있습니다.

사실 위 역할은 잘했다고 생각합니다 ㅎ (자화자찬)

 

하지만 제가 부족하다고 느끼는 점은 다음과 같습니다:

  • 개발 팀과의 친목 도모 부족 (자주 만나고 밥도 먹고 모각코도 하는 등, 여러 기회를 만들었어야 했는데...)
  • 팀원들의 능력을 믿고, 더 효율적으로 업무를 위임하지 못한 점

물론 우리 개발 팀원들은 알잘딱깔센 하게 업무를 잘해주었지만, 막판에 급했던 상황도 있었던 만큼, 가끔이라도 제가 좀 더 관심을 기울였더라면 개발이 좀 더 수월해졌을까 하는 아쉬움이 남습니다...ㅜㅜ

예영 누나, 동준이 미아내


Try (내가 나에게 하는 조언)

  • 완벽함도 좋지만, 지금의 미완이 결국은 완성이 되고, 완성이 다듬어져 완벽이 될 수 있기에 미완을 즐길 줄도 알았으면 좋겠어.
  • 팀원들의 능력을 믿되, 개인 프로젝트가 아닌 팀 프로젝트이기 때문에 이성적으로 프로젝트의 진척도와 현재 상황을 잘 판단하면 더 좋은 개발리드가 될 수 있을 거야.

느낀 점

참 재밌는 두 달이었다.

매일 새벽까지 개발하고, 떠들기도 하고, 고민도 털어놓고...

 

예전에 기획 파트인 나영, 가연, 예진 누나랑 백엔드 파트인 호영이 형이랑 새벽에 얘기하면서, 진지한 대화(진담)를 한 적이 있다.

물론 나는 진담을 별로 좋아하진 않지만 ㅋㅋ, 팀원들의 고민을 듣고 싶었다.

 

근데 팀원들의 고민이 없었다 😂

팀프로젝트하면 다들 쌓인 게 있을 수도 있을 텐데... 진짜 고민이 없는 목소리였다. 오히려 지어내는 느낌이랄까..

그만큼 우리 팀은 프로젝트 진행하면서 큰 갈등이나 불만 없이 잘 흘러간 것 같다.

 

밋업을 시작하고 매주 토요일이 오기를 기대했다. (토요일이 언제 오나.. 자고 일어나면 토요일이면 좋겠다.. 비나이다 비나이다 🙏)

세션 장소에 가는 게 즐거웠고, 세션 끝나고 팀원들과 밥 먹고, 작업하고, 술도 먹고, 밤도 새우고, 

사실 뭘 하든 상관없었다. 그냥 같이 있는 매 순간에 내가 있을 수 있어 행복했다.

 

한 씨의 자랑, 한 씨의 최고 PM인 나영아 ☀️

지금에서야 말하지만, 내가 C팀을 1순위로 지망한 건 너란 이유가 9할 이상이야 🤣

동아리 운영하면서 많이 힘들었을 텐데, 힘든 내색 전혀 없이 항상 입이 귀에 걸려있는 너를 보면서 괜히 너를 닮고 싶더라.

나이스 == 한나영이랄까? 😁

우리 팀 분위기가 매우 좋았지만, 그걸 지탱하는 사람은 너였던 거 같아.

나랑 나이도 같은데 많이 배운다 나영아. 같은 팀 해서 진심으로 영광굴비였다. (아 미안 이건 좀 ㅋㅋ, 나만 재밌으면 됐지~)

 

사람을 편하게 해주는 예진누나 ☘️

첫 만남인 만다라트 쓸 때도 내가 극 I라서 어색 어색한데 말도 잘 걸어주고 분위기를 너무 행복하게 만들어줘서 고마워!

누나랑 있을 때는 왠지 모르게 평안해 마음이 🤝

아마 그건 누나가 말도 잘 들어주고 사람을 편하게 해 줘서 그러는 거 같아.

배려심 == 신예진이랄까? 😁

인턴 하느라 바쁠 텐데 항상 파이팅 하고.. 완두콩즈 크아 일정도 얼른 잡자 🎈

 

깔깔깔, 대전의 유잼걸 가연아 🎸

밋업 초반에 너랑 동갑이라고 거짓말 쳤던 그때가 엊그제 같은데.. 벌써 두 달 됐어 😱

처음에 사실 친해지기 가장 오래 걸릴 거 같다고 생각했어 ㅋㅋㅋㅋㅋ 약간 시크해 보였달까..

어린 나이에 엄청 열심히 사는 거 같아. 대외활동도 많이 하고, 늦은 새벽에 슬랙 들어가면 너만 활동 중이고..

책임감 == 홍가연이랄까? 😁

방학 때도 할 게 많을지 잘 모르지만,, 쉴 때는 좀 쉬고,, 완두콩즈 물풍선 터뜨리러 가자 💣

 

혼자 해도 100인분 이상 하는 은정아 🖌️

너랑은 큐시즘 오티 때부터 많이 마주쳤었는데 (동밀리)

그때는 내가 어색함이 너무 커서 모두랑 못 친해지고 있어서 아쉬웠는데 🤯

이번 밋업 때 다시 만나서 친해질 수 있게 돼서 좋았어!

일당백 == 최은정이랄까? 😁

뉴켓에서 받은 1등 상품 잘 쓰고 있어! 쉴 때 잘 쉬고 항상 파이팅 🥇

 

가천대에서 먼저 만나지 못해 아쉬운 예영누나 😿

가천대에서 한 번쯤은 마주칠 법한데 어떻게 못 마주쳤을까..

예영누나는 웃을 때 진심이 느껴져서 나까지 기분 좋아지더라~

예영누나랑은 좀 더 친해질 필요가 있어. 난 아직 만족 못해 ㅋㅋㅋㅋ

성실함 == 공예영이랄까? 😁

회사 다니면서 퇴근하고 짬 내서 개발하는 게 진짜 힘들 텐데... 밋업 하느라 고생 많았어 👍

 

너~무나 착한 동생 동준아 🥁

밋업 전부터 눈길에 있던 동준이..

항상 사람들한테 잘하고 매너 좋아서 친해질 기회가 있을까? 했는데 밋업에서 만나게 돼서 너무 좋다 ☺️

동준이랑도 좀 더 친해질 필요가 있어. 맛있는 거 먹으러 가자!

스윗함 == 황동준이랄까? 😁

산업체 지원 중인 걸로 알고 있는데 산업체 꼭 붙기를 바랄게 🙏

 

웬만한 자바, 스프링 개발자보다 잘하는 호영이 햄 🤘

형이 없었다면 백엔드 개발이 잘 마무리되었을까?라는 생각을 종종 하곤 해.

그만큼 개발하는 데 있어 형의 영향력이 엄청 컸어.

코드 리뷰가 많기도 하고, 내가 바라는 게 많아서 형한테 부담이 갔다면 미안해 😥

형은 착해서 정말 괜찮다고 하겠지만 힘들 때도 있었을 텐데 너무 잘해줘서 고마워 🤩

많이 부족한 나한테서 조금이라도 형한테 도움이 됐다면 나한테 더 이상 여한은 없다~!

오티 때 첫 만남부터 MT에서 개발 얘기도 하고 ㅋㅋㅋ 밋업까지 같이 할 수 있어 영광이었어~

취업 준비 파이팅이고, 느좋 공간도 같이 가고 가끔은 운동도 같이 하자 헬스보이 💪