9회 유니톤 참가 후기

김유정·2022년 10월 16일
1
post-thumbnail

유니톤 공식 페이지에서는 유니톤을 다음과 같이 설명하고 있다.

유니톤은 IT 커뮤니티 구성원들의 즐거운 성장과 교류를 목표로 하는 해커톤입니다.

9회 유니톤은 9월 2일부터 4일까지 2박 3일간 진행됐다. 오늘은 그 후기를 적어보려 한다.

지원 과정


짧은 시간안에 서비스를 만드는 해커톤을 꼭 해보고 싶다는 생각을 했다.
그 이유는 다음과 같다.

1) 디자이너와 개발자들과의 교류
2) 시간 안에 서비스를 완성해보고 싶다는 도전 욕구

비전공 개발자이다보니 항상 전공자가 부러웠던 건 친한 개발자가 많다는 것이었다. 고민을 나누고, 기술적으로 서로 조언할 수 있는 개발자가 있었으면 좋겠다고 생각했다. 그래서 이런 기회가 너무 간절했다.

원래는 동아리 연합 해커톤이라 동아리 소속되어 있는 사람들을 우선적으로 뽑는다고 해서 IT 동아리에 소속되어 본 적이 없는 나는 걱정을 많이 했다.

그래도 정성들여 지원서를 썼는데, 다행히 참가자로 선발되었다는 문자를 받았다! 정말 해보고 싶었던 해커톤을 하게 되었다.

9회 유니톤



위의 사진은 오프닝 때이다. 9회는 오프라인으로 진행됐는데, 준비를 많이 하신 게 느껴졌다. 행사 하면서 간간히 이벤트도 진행됐고, 먹을 것도 넘쳤다.

작년에는 팀 단위로 지원했던 것 같은데, 올해는 개인 지원이여서 유니톤 측에서 팀빌딩을 해주셨다. 총 12팀이었던 걸로 기억한다. 무작위로 짜여진 팀이라 준비를 해올 수 없기 때문에, 주제는 자유롭게 선택하는 걸로 정해졌다고 한다.

기획


시간이 짧아서 기획이 빠르게 이뤄져야할 것이라 판단했다. 그래서 유니톤 시작하기 전까지 만들어보고 싶은 서비스를 열심히 생각해갔다. 3개정도 생각했는데, 그 중에 익명의 누군가와 랜덤으로 편지를 주고받는 "익명의 편지" 아이템이 가장 괜찮다고 생각해서 와이어프레임도 간단히 제작해갔다. 기획단계에서 의견을 제안해봤는데, 다들 좋다고하셨다.

하지만 안타깝게도 비슷한 서비스가 많았다. "코다"와 "밤편지"라는 앱이 가장 비슷했는데, 차별점을 생각하다가 "위치"라는 키워드가 나왔다.

타임캡슐처럼 특정 위치에 쪽지처럼 글을 남겨두면, 익명의 누군가가 볼 수 있는 서비스를 생각해냈다. 이걸 "헨젤과 그레텔"이라는 동화와 연결지어 스토리텔링을 시도했다. 그래서 메모를 쿠키로 표현했다. 쿠키를 흘리고 가는 헨젤과 그레텔처럼!


우리팀의 실력 좋은 소중한 디자이너 현우님이 만들어주신 팜플렛이다.

소중한 감정과 순간을 놓치지 않기 위해 쿠키를 남기고,
누군가 남긴 쿠키를 하나씩 주우면서 일상에서 소소한 행복을 얻기를 바라는 마음으로 제작했다.

개발



첫째 날 밤은 새벽에 집에 가서 잤고, 둘째 날 밤에는 정말 밤을 새서 개발을 했다. 1시간에서 2시간정도 눈을 붙이긴 한 것 같다. 어떻게 개발했는지 기록을 남겨보자.

기능

  1. 특정 위치에 메모 남기기
  2. 지도에서 다른 사람이 나긴 메모 확인하기
  3. 메모 상세보기
  4. 메모 조회하기

이중에서 내가 했던 부분은 2번이었다. 사용자가 보는 지도 화면 내의 메모 데이터를 조회하는 API를 개발했다.

위치의 특징을 살리기 위해 반경 250m내의 메모만 읽을 수 있는 걸로 기획했다.위의 캡쳐 화면에서 보면, 하얀색 쿠키가 읽을 수 있는 메모이다. 따라서 지도 내 메모 데이터를 반환하되, 어떤 메모가 반경 250m 내에 있는지에 대한 정보도 전달해야했다.

구현

클라이언트로부터 사용자의 위치 정보, 사용자가 보고 있는 화면의 좌하단과 우상단의 좌표값에 대한 정보를 받았다. 그 정보를 이용해서 반경을 구할 수 있는 방법은 두 가지가 있었다. 유니톤에서는 2번 방법을 사용하여 MySQL로 구현했다.

1) Java 언어 이용하여 구현

  1. 데이터베이스 Letter 테이블에서 모든 데이터를 돌면서, 지도 내에 있는 데이터 찾아내기
  2. 1번에서 찾은 데이터를 돌면서 거리 계산하고, 거리가 250m 이하일 경우 "withRadius" 변수를 true로 만들기

위와 같이 지도에 있는 데이터를 뽑아내고 반복문을 돌면서 "withRadius"변수를 세팅한 후에 데이터를 반환할 수 있도록 구현이 가능했다. 코드를 첨부하기에는 너무 길어서 참고했던 글의 링크를 첨부한다.
https://se-jung-h.tistory.com/m/entry/%EC%9E%90%EB%B0%94intelij-%EC%A2%8C%ED%91%9C%EC%9C%84%EB%8F%84%EA%B2%BD%EB%8F%84%EB%A1%9C-%EC%8B%A4%EC%A0%9C-%EA%B1%B0%EB%A6%AC-%EA%B5%AC%ED%95%98%EA%B8%B0

2) MySQL 이용하여 구현 - 임시 컬럼 활용

  1. 데이터베이스 Letter 테이블에서 모든 데이터를 돌면서, 지도 내에 있는 데이터 찾아내기
  2. 데이터베이스 Letter 테이블에서 모든 데이터를 돌면서, 사용자의 위치와의 거리를 계산하여 "distance"라는 임시 컬럼에 값을 담는다. 이 때 거리가 250m 이하인 데이터를 찾아낸다.

이 경우에서는 데이터베이스에서 2개의 데이터 리스트를 얻는다. 1) 사용자가 보고 있는 지도 안의 메모 리스트, 2) 반경 안의 메모 리스트

  • LetterRepository.java
@Repository
public interface LetterRepository extends JpaRepository<Letter, Long> {
    ...

    // 1번 과정을 수행한 메서드
    List<Letter> findByXBetweenAndYBetween(Double startX, Double endX, Double startY, Double endY);

    // 2번 과정을 수행한 메서드
    @Query(value = "select *, (6371*acos(cos(radians(x))*cos(radians(?1))*cos(radians(?2)-radians(y))\n" +
            "+sin(radians(x))*sin(radians(?1)))) AS distance\n" +
            "from letter\n" +
            "where x between ?3 and ?4 and y between ?5 and ?6\n" +
            "having distance <= 0.25\n" +
            "order by distance DESC;",
            nativeQuery = true)
    List<Letter> findWithinRadius(Double curMemberX, Double curMemberY, Double startX, Double endX, Double startY, Double endY);

구현하며 느낀점과 배운점

  • 좋은 로직을 짜기 위한 고민을 했지만, 아직도 잘 모르겠다...!그래도 고민했던 그 시간이 귀했다.
    맡은 기능을 구현하면서 제일 좋은 방법은 위의 로직에서 1번과 2번을 한번에 수행하는 것이라고 생각했는데, Java를 사용하든 MySQL을 사용해서 계산하든 2번에 나눠서 로직을 수행해야했다. 데이터베이스에 withRadius 컬럼을 추가한다면, 한 번에 할 수도 있었을것이다. 하지만, 반경에 대한 값은 사용자의 위치에 따라 계속 변하는 값이라 계산 편의를 위해 컬럼을 추가하는 것은 좋은 방법이 아니라고 생각했다.

  • MySQL로는 생각보다 많은 것을 할 수 있다.
    그 때 멘토로 오신 당근마켓 백엔드 개발자 분에게 구현에 대해 조언을 얻었을 때, MySQL로 하는 방법을 추천해주셨다. MySQL로 계산하면 대부분 조금 더 빠르게 수행된다고 하셨던 것 같다. MySQL은 지원하는 기능이 많으니 개발을 할 때, 많이 찾아보라고 하셨다. 그 전까지는 기능을 구현한다고 하면 데이터베이스에서는 간단한 수정, 삭제, 검색 정도만 했는데 이렇게 복잡한 계산까지 가능한 줄 몰랐다. Java로 모든 백엔드 로직을 구현하려고 하기보다 데이터를 가져오는 단계에서부터 데이터 처리를 최대한 해두면 빠르고 편리하게 구현이 가능한 듯하다. 잘 이해한지는 모르겠다. 사실 그 당시에는 Java로 구현을 안해봐서 이후에 개발을 하고 MySQL을 사용한 방법과 시간 비교를 해봤는데 거의 비슷했다. 데이터가 많지 않아서 큰 차이가 없었던 것 같다.

  • Spring에서 Body를 통해 정보를 전달받고 싶다면, PostMapping을 사용하자...!
    iOS에서 내가 만든 api를 사용하여 통신을 하려고 했는데, 계속 400 Bad Request 에러가 났다. 정말 많은 시간을 날린 부분이다. 400 에러라 서버에 에러 로그가 찍히지도 않으니 뭐 때문에 문제인지 알기 어려웠다. 수많은 시행착오 끝에 GetMapping이라 Body로 정보가 전달이 되지 않는다는 것을 깨달았다. Spring에서 정보를 받을 때 무시하는 것인지, iOS에서 요청을 보낼 때 보내지 않는 것인지는 모르겠으나 PostMapping으로 바꾸니 해결됐다.

  • 검증에 대한 중요성을 깨달았다.
    위의 에러를 해결하긴 했는데, 반경 내의 데이터가 잘 반환되지 않았다. 분명 계산식에는 문제가 없고, 백엔드 로직에도 문제가 없는 것 같았다. 결론적으로는 클라이언트에서 위도와 경도를 바꿔서 보내서 적절하지 않은 데이터가 갔던 것이다. 만약 위도와 경도 범위를 설정하여 검증했다면, 조금 더 문제를 빨리 알아챘을 것이다.

발표 & 시상


팀마다 짧게 발표를 했다. 질의응답 시간은 따로 없었고, 이후 시연 부스를 통해 추가 설명할 기회가 있었다. 시연 후에 잠시 졸면서 결과를 기다렸는데....

특별상을 받았다!!

12팀 중 1팀 대상, 2팀 우수상, 3팀 특별상이었다. 특별상이지만 그래도 좋다. 얼른 출시됐으면 하는 팀에게 주는 상이라고 했기 때문에, 그 의미가 담긴 상이라서 더 좋았던 것 같다.

유니톤 그 후


유니톤 후에도 우리의 디스코드 채널은 나름 활발하다. 다들 뜻이 맞아서 앱 출시를 위해 노력하고 있다. 하지만, 아무래도 다들 본업이 있다보니 유니톤때처럼 진도가 잘 나가지는 않는다.

출시와 별개로 유니톤에 참여하길 정말 잘했다는 생각이 든다. 올해 가장 잘한 일이 아닐까..? 9월 초에 있던 일인데, 쓸 얘기가 많다보니 회고가 늦어졌다.

참고


0개의 댓글