개발 프로젝트/Zerobase 개인프로젝트 기록

제로베이스 개인프로젝트 진행록2 - 개발기획/리뷰 (2)

bsh6226 2024. 9. 18. 12:16

지난 피드백과 회신

안녕하세요 밍밍멘토님 피드백 주신부분에 대해서 답변드립니다. 아래의 답변드린 내용을 바탕으로 기획서 수정해서 재업로드 및 피드백 요청드릴수 있도록 하겠습니다.


1) 현실성 관련하여, 현재 제가 판단하기로는 기능이 너무 많고 새롭게 배우셔야할 부분도 상당수인것으로 보여집니다. 지금까지 제가 1기부터 여러명의 수강생분들과 스터디를 진행해왔는데요, 그중에서 가장 잘하신 분을 기준으로 판단하여도 기능이 너무 많고 새롭게 배우셔야할 것들이 많아요. 전체적으로 기능을 줄여주시면 좋을 것 같습니다.

 

-> 네 욕심이 조금 과했던 것 같습니다. 리뷰해주신 내용을 보고 기획서를 다시보니 기획내용이 간결하지 못한것 같네요. 부가기능을 줄이고 로직을 간결화화하겠습니다. 그리고 부가기능들을 구현을 하지는 않되 해당 기능의 확장성을 염두에두고 데이터 구조나 프로그래밍 구조를 유연화 할 수 있는 방향을 설계방향성으로 잡고 다시 고민해보도록 하겠습니다. 

 

2)또한 기술적 구현가능성에 대해서, 구획화라는 부분을 제가 잘 이해를 못했습니다. 사각형이 어떤식으로 작성이 되는걸까요?

-> 제가 해당 지식이 부족해서 두루뭉실한 용어를 쓴 부분이 있는 것 같네요. Grid로 만든다는 게 좀 더 정확하게 표현될것같습니다. 제가 생각했던 내용은 아래 링크처럼 맵을 영역으로 쪼개는 기술을 지칭하는 것이었습니다.

https://chang12.github.io/python-map-grid/


3) 외부 API 의존성은 상관없습니다. 직접 구현하실 수 있는 부분들이 아니니 이런 부분들은 외부 API를 사용하는 것이 맞습니다. 시간 복잡도도 고려하실 이유가 없으실 것 같아요.

-> 알겠습니다. 반영하겠습니다.

 

4) 개발 방법에 대해서는, 만약 먼저 프로토타입을 개발하신다면 해당 코드에 대해서는 제가 피드백을 드리기가 어렵습니다. 따라서 프로토타입을 베이스로 개발을 하신다면 프로토타입 개발때 작성하셨던 코드를 제가 알기가 어려우니 이를 베이스로 한 개발 또한 자세한 리뷰드리기가 어려울 것 같아요. 가능하면 노션의 스터디 방식을 기준으로 진행해주셨으면 하네요.

-> 알겠습니다. 반영하겠습니다.

 

 

5) 작성해주신 주제에 대해서는, 데이터 초기화에 대해서 언제 어떤식으로 진행하실것인지(매일? 초기에 한번?) 어떤 데이터를 저장할 것인지.

-> 프로그램 실행시 최초1회 예정입니다. 문서상에 보충하겟습니다. 

 

6) 외부 API중 길찾기는 어떤 API를 사용하실 것인지

-> 처음 구상에는 3가지 API를 모두 호출하고 각 API 간의 소요시간을 비교해서 최단 소요시간을 제시하는 API를 데이터로 사용해서 진행하려고 하였습니다. 최적화라는 주제를 위해서, 일부러 복잡한 상황을 만들려고 했던 의도인데 좀 난잡하고 정리가 안되는 느낌이 있는 것같네요. 해당 비교기능은 제외하고, GoogleAPI로 정해서 한가지만 사용하도록 하겠으며, 대신 다른 API까지 확장성을 고려해서 Interface로 처리해서 Service 계층으로 넘기는 방식으로 하겠습니다.  문서상에 보충하겟습니다. 


7) 문화 유산 검색은 내부에저장후 사용하실 것인지, 사용자가 검색시마다 외부 API를 호출할 것인지

-> 데이터 초기화시에 DB에 저장한 후 내부호출 예정입니다. 문서상에 보충하겟습니다. 


8) 방문 여부는 어떤식으로 방문했다는 것을 알수 있는 것인지

->  방문여부는 사용자가 유물을 방문처리 request를 하도록 하는 기능을 추가할 것이며, 방문자 위치가 100m이내인지 검증하는 로직을 추가할 예정입니다. 문서상에 보충하겟습니다. 


9) 전체적인 서비스 사용 flow가 자세히 기재되지 않은 것 같아요. 

-> 문서상에 보충하겠습니다.


10 ) 또한 회원이 방문한 문화유산이 없는 지역은 Black으로 가린다고 하셨는데 view도 개발하실 계획이신가요?필요하신 부분은 추가적인 답변 및 보충하셔서 다시한번 기재해주시면 좋을 것 같습니다.
-> view는 개발하지 않고, 각 회원별로 DB상에 방문한 1. Grid 정보를 저장하거나 2. DB상에 방문한 유적을 저장하고 이를 Grid데이터로 변환하거나 하려고 의도하였습니다. 해당 기능을 제외할지 유지할지 조금 고민해보고 문서상에 보충하겠습니다.

 

리뷰를 배울점

1. 프로그램의 핵심로직은 명료하고 단순해야한다.

2. 향후 확장성(편의성과 디테일) 고려하고 싶다면 이를 반영하여 최처 설계시 확장에 유연한 구조로 녹여낼 필요가 있다.

3. 계획은 항상 현실적이고 최소한의 기준으로 진행해야 실현가능성이 있다. 실현불가능한 계획은 의미가 없다.

4. 기획단계에서 logic흐름을 구체화하여야 정확한 설계가 가능하다

 

 

구현기술고려점(1) : Grid를 어떻게 관리할 것인가?  DB에 저장  혹은 동적으로 생성?

- Grid는 Map이라고 부를 수 있는 가장 큰 Grid를 상하좌우 좌표를 특정 길이로 잘게 자른 것이라고 할 수 있다.

- 나의 프로그램에서 Grid가 어떻게 쓰이는지가 설계의 핵심인데, Grid는 사용자가 Map을 조회할때 특정 Grid를 방문한적이 있는지 없는지에 따라서 Black으로 처리하느냐 마느냐 (True/False)로 표현하기 위함이다.

- DB에 Grid정보를 저장하고 이를 조회하여 Front측으로 정보를 넘긴다고 했을때, 사용자의 Map 조회는 어떤 곳이든 조회할 수 있으므로 DB의 Full Scan으로 u*n time-complexity가 필요할 것으로 보인다. (spatial index를 사용하면 Log n이 필요하다고 한다) Logn이라고해도 nlogn으로 적은 비용이 아니고 DB접근은 최소화 해야된다고 생각한다. 

- 메모리 내에서 map 데이터 request의 상하좌우 좌표가 넘어오면 이를 미리 정해진 기준으로 grid를 나누면 n번의 계산으로 n개의 grid를 생성할 수 있다. 그리고 이를 black으로 표시할지 결정하기 위해서 1. user의 방문한 유적지 m개의 좌표가 각 상하좌우 범위 안에 들어가는지 2. 들어간다면 grid로 만들었을 때 몇번째 grid로 속하는지 확인하여 해당 grid의 black표시여부를 true로 표시하면 n+m의 시간복잡도이다. 이정도는 In-memory연산이 충분히 가능하다고 생각함

 

따라서 visited point만 DB에 저장하고 grid는 동적으로 계산하는 것으로. 

 

 

 
구현기술고려점(2) : 경로탐색을 어떻게 구현할 것인가?

 

다양한 알고리즘에 대해서 확인해보았으나 출발점에서 다시 한점으부터 특수한 점의 최단거리를 찾는 다익스트라, 벨만포드 알고리즘은 적합하지 않은 것으로 확인하였다. 내가 제시한 문제는 Traveling Salesman Problem인데 Bruteforce의 경우 O(n!)이고 Dp를 사용해도 O(n^2 * 2^n)인 것으로 확인되어 부분최적이 전체최적임을 가정하고서 계산을 진행하는 Greedy방식으로 푸는 수 밖에 없어보인다. 이것이 현실적인 방안으로 보임.

 

기획수정안

[프로젝트 아이디어 제출본 rev2]

1. 주제 : 국가문화유산 지도앱

- 국가문화유산 API 데이터를 기반으로  문화유산의 '지도상위치', '사용자답사경로추천', '사용자방문이력'을 관리하는 지도앱을 만들고자 합니다.

 

2. 주제선택배경

2.1 기술적고려 : Optimization이란 주제에 관심이 있어서 단순히 캐싱/스레드처럼 컴퓨팅 Resource Optimization 외에도 로직 차원에서 Optimization에 관한 프로그래밍(다익스트라,TSP 등)을 경험해보고 싶었습니다. 

2.2 주제적고려 : 평소 역사와 여행을 좋아하여 탐험적 요소가 있는 지도앱을 만들어 보면 어떨까 하여 선택하였습니다.

 

3. 서비스흐름도

추후 제작해서 추가 업로드 하겠습니다.

                         

4. 기능

[데이터 초기화]

- 프로그램 동작시 최초 1회, 국가문화유산 API로부터 데이터 호출 후 내부 데이터 모델에 따라 가공하여 DB에 저장

https://www.khs.go.kr/cha/SearchKindOpenapiDt.do?ccbaKdcd=11&ccbaAsno=00030000&ccbaCtcd=11

-  {외부API : 구글, 카카오, 네이버 길찾기} 외부의 API를 통해 국내지도정보를 불러온다.

=> 국내지도정보API는 화면 형태로 제공되는 것이지 raw 데이터로는 제공되지 않아 불필요한 기능으로 확인되었습니다.

 

[회원정보]

- 기본 회원정보, 권한부여 (input : 아이디, 비밀번호, 이름, 권한; admin,user)

- 회원별로 방문한 문화재ID 리스트를 저장 관리한다.

 

[문화유산검색 : 1순위]

- 사용자 위치를 기반으로 Nkm 주변에 존재하는 문화유산을 조회한다. // (Input : 사용자위치, 거리 Nkm, Output : 문화재ID리스트)

 

[문화재방문처리 : 2순위]

-  회원은 특정 문화유산을 선택하여 문화재 방문처리한다. 단, 회원의 위치와 선택된 문화유산의 거리를 비교하여 500m이내임을 확인하고 아닐시 예외처리한다.  ( input : 사용자위치, 문화재ID, 사용자ID)

 

[지역지도조회 : 3순위] : 유저가 특정지역의 지도를 요청한다. 특정지역의 지도는 Grid로 나누어지며 방문한 문화재가 없는 Grid는 검은색으로 있는지역은 지도로 표시된다.

 

- 회원이 상하좌우 사각형 끝점이 x,y좌표로 정의되는 지역을 지도로 표시하는 것을 요청한다. request 받은 요청지역 내부 정의된 규칙에 따라 Grid로 분할하여 List<Grid>에 담는다. 이때, Grid 객체는 기본적으로 화면에 검은색으로 보이도록 boolean값이 false인 필드를 갖는다. (Input : 상하좌우 좌표, output : Grid 객체리스트) 

- 로그인한 회원의 방문문화유산 List의 x,y좌표를 Select하여 요청지역 좌표 범위 안에 포함되는지 확인하여 요청지역과 관련없은 문화유산은 1차적으로 제외한다.

- 요청지역의 좌표범위 안에 위치함으로 확인된다면 유적이 Grid 객체리스트의 몇번째 Grid에 포함되는지 검사한다. 그리고 해당되는 Grid의 맵표시 boolean값을 false에서 true로 변환한다. 모든 유적에 대해서 탐색이 끝나면 Grid 객체리스트를 FE로 반환한다. (input : Grid 객체리스트, 상하좌우좌표 output : boolean값이 변화된 Grid 객체리스트)

 

-국내지도를 사각형 Grid로 나누어 Grid별로 존재하는 문화유산을 분류하여 데이터베이스에 관리한다.

-> 국내지도 '전체'를 Grid로 나누어 DB에 저장하고 [방문지역조회]시행 시마다 특정지역에 해당하는 Grid를 select하는 것은 비효율적인 것으로 생각되었고 회원이 지도로 요청하는 특정지역이 정의되면 동적으로 Grid를 생성하는 방식으로 변경하였습니다.

 

- 문화유산이 방문으로 처리될때, [방문지역조회]를 재시행하여 표시되는 지도를 refresh한다. 

 

[답사경로탐색 : 4순위] : 유저 주변에 있는 문화유산을 방문하고 돌아오는 최적경로를 탐색하여 추천해준다. 

- [문화유산검색] 기능으로 1차적으로 문화유산위치들을 필터링한다.

- 필터링한 문화유산들을 '목적지Nodes'로 설정하고, 사용자위치를 '출발지Node'로 설정한다. 단, 이때 유저가 이미 방문한적 있는 문화유산은 '목적지Nodes'에서 제외한다.

- '출발지Node'가 복수의 '목적지Nodes'을 탐색하고 '출발지Node'로 돌아오는 경로를 구성한다. 해당 경로 중 최적화점수 순서대로 5개의 루트를 유저에게 반환한다.  최적화 점수기준은 경로 내 문화유산의 중요도점수(국보급, 보물급 등에 따른 차등점수)*문화재개수/총소요시간(유적별관람시간(1시간) + 총경로이동시간)으로 한다. // (Input : 사용자위치, 사용가능시간 output: 최적화된 순서로 정렬된 5가지 경로)

 

 

5. 확장고려기능 : 구현은 안하되 확장가능성 고려하여 설계

 

[답사경로탐색] 

- 'Node' 간의 경로 확인시 외부 API를 통해 API별 소요시간을 확인하며  최단시간을 제시하는 API의 데이터를 사용하여 계산한다. {외부API : 구글, 카카오, 네이버 길찾기} 

=> 어떤 API든 호환가능하도록 API Adapter를 Interface로 처리 예정

 

[문화유산검색]

-  한국어 검색하여 문화재 이름을 자동완성하고 단순조회 // (Input : 검색어)

-  한국어 검색하여 검색어와 '문화재이름'과 '문화재설명'의 관련성 순서대로 정렬 // (Input : 검색어)

 

[도슨트 기능] 

- 간단한 GPT  프롬프트 엔지니어링으로 튜닝하여 주제별 도슨트 출력준비

A. 공통프롬프트 : 유적지 도슨트처럼 설명, B.세부프롬프트 1. 예술적관점으로 설명 2. 역사적관점으로 설명 

- 방문한 문화유산에 대해서 도슨트 내용을 OpenAI API를 통해 생성, 호출하며 이때, 1. 예술적관점설명 2. 역사적관점설명으로 컨텐츠 생성관점을 선택할 수 있다.

 

6. 한계 및 우려사항  

A. 경험/지식 부재로 인한 우려 핵심기능만 구현하는 방향으로 다시 잡았는데 현실성 재검토 한번 더 부탁드리겠습니다.

B. 배우면서 할필요가 있는 내용들

- [위치표시기능] : 문화재유산의 위치정보를 Geolocation으로 데이터 처리하는 방법,  DB에는 Spatial Index로 탐색하는 방법.

- [답사경로탐색기능] : 다익스트라,TSP 등 다양한 알고리즘을 학습하고 어떤 최적화 알고리즘을 사용할지 학습필요.

 

프로젝트 리뷰 및 배운점


멘토리뷰

 

나의 회신

안녕하세요 밍밍멘토님 상세한 피드백 감사드립니다. 피드백 주신부분에 대해서 답변드립니다. 

 

• 우선 일차적으로는 주제의 현실성에 대해서 제가 피드백을 드리긴 했습니다. 다만 제가 상화님의 실력이나 해당 스터디에 투자할 수 있는 시간등을 정확히 알지 못하기 때문에 이전에 드린 피드백 이외에 더 나아가서 피드백을 드리긴 어려울 것 같습니다. 제가 처음에 드린 피드백을 바탕으로 고민해보신 뒤 현재와 같이 범위를 설정하신 것이라면 문제 없을 것이라고 생각됩니다.

 

-> 네, 1~4순위 우선순위대로 구현 진행해보도록 하겠습니다.


• 다만 추가적으로 드릴 수 있는 피드백으로는, 현재 알고리즘 학습을 한뒤 학습하신 알고리즘을 서버개발에 녹여내고자 하신것 같은데요, 저는 해당 부분이 서버개발자로서 크게 메리트가 있는 경험이라고는 판단하지 않습니다. 실무에서는 더 복잡한 알고리즘을 사용하기 때문이에요. 그리고 서버 개발자가 알고 있어야할 기본적인 알고리즘에 대한 이해도는 코딩테스트를 통해서 테스트합니다. 따라서 알고리즘을 서버 개발 기능에 이용하는 것을 서비스의 메리트로 삼기에는 조금 돌아가는 느낌이 드네요. 그보다는 쿼리 최적화나 캐싱전략등에 집중하는것이 좀더 좋다고 개인적으로는 생각하긴합니다. 다만, 해당 기능을 한번 구현해보고 싶으시다면 해당 측면에서 기능을 넣는 것은 좋다고 생각합니다.

 

-> 네 객관적인 피드백 감사드립니다. 이번 프로젝트는 우선적으로 제가 관심사가 높은 주제(문화재, 야외활동), 관심사가 높은 기술(탐색문제)를 프로젝트로 구현해보면 어떤 느낌일까 체험을 해보고싶어서 선정하게 되었습니다. 실무에서는 알고리즘만 전문적으로 공부하신 석학분이 설계를 하고 계시지 않을까 싶네요. 

 

-> 우려해주신 대로 알고리즘 학습에 과도하게 집중하지 않고 나름대로 쓰레드, 캐싱, 쿼리 등 균형을 잡아보도록 하겠습니다. 어떤 알고리즘을 써야하는지 이번주에 조금 고민+써치를 해보았는데, 잠정적인 결론은 Greedy 탐색방식으로 밖에는 구현이 안될것 같다는 것입니다.  제가 정의한 최적화문제가 부분최적이 전체최적을 보증하는 것이 아니라서 완전 탐색을 해야만 가장 최적화된 루트를 찾아낼 수 있는 문제더라구요. 그러면 탐색 경우의수가 (V-1)!이라 20개의 Node만해도 계산불가한 경우의 수가 되어서 서비스가 불가능하다는 생각이 들었습니다. 부분 최적으로 결정하는 Greedy 탐색방식으로 실제로도 그렇게 많이하는 것같더라구요. 이상으로 알고리즘 관련 조사/고민은 마무리하고 구현의 관점에서 집중하고 캐슁과 스레드, 쿼리에 집중하도록 하겠습니다.

 

• GPT 프롬프트 엔지니어링을 이용한 기능은 어떻게 개발하실 계획이신가요? 어떤 api를 이용하실 계획이신지 궁금합니다.

 

->  본 기능은 제가 지식도 계획도 아직 없는 상태입니다. [5. 확장고려기능 : 구현은 안하되 확장가능성 고려하여 설계] 항목이라 구현할 계획도 없고 1~4순위까지의 기능만 구현할 생각입니다. 문서에서 제거하지 않은 것은 해당 기능이 추가될 수도 있다는 가능성 고려하에  데이터 모델링에 참고하고 싶어서입니다. 나중에 취준시기에 좀 심심하면(?) 찾아보고 구현해볼 예정입니다. 혼선을 발생시킨다면 문서내용에서 삭제하겠습니다.

 

• grid의 크기는 어떻게 결정되나요? 또한 그냥 회원이 방문한 유적지의 위도경도를 내려주면 화면을 그려주는 측에서 grid를 그려도 될것 같은데 이 부분을 서버에서 구현하시기로 결정하신 배경이 있나요?

 

-> Grid크기는 동적으로 결정하지 않고 전역상수로 정의하고 Grid 분리기준도 일정하게 해서 동적으로 생성하되 일관성을 유지하려고 합니다. 좌우 2km정도면 적당하지 않을까 생각중입니다. 

 

-> 화면을 그려주는 측이면 FE를 말씀하시는 것일까요? 해당 질문은 제가 미처 고민못했던 부분이라 기획시 특별한 배경은 없었습니다. 지금 질문을 듣고 생각나는 부분은 (FE 측을 의미한다고 하시면), 1. 데이터 처리니깐 데이터 처리 관련은 가능하면 백엔드에서 처리하고 넘겨주는게 맞지 않나하는 생각이 들고 2. x,y좌표라는 외부API의 데이터(DB에 저장할것이지만, 출처는 외부니깐)를 내부적 기준에 따라서 Grid로 변환하는 과정이니 서비스 Layer에 해당하는 부분이 아닌가 하는 생각이 우선 듭니다. 제가 놓치고 있는 부분이 있으면 말씀부탁드려요.


• 사용자 위치를 기반으로 Nkm 주변에 존재하는 문화유산을 조회한다. // (Input : 사용자위치, 거리 Nkm, Output : 문화재ID리스트) 이 기능에 대해서는 Nkm 주변에 존재하는 문화유산 조회 자체를 API로 대체하나요? 아니면 내부 DB에서 query를 통해서 구하게 되나요?

 

-> 내부 DB 쿼리로 구현예정입니다.

 

리뷰를 통해 배울점

- 결국에 Backend 개발자에게 요구되는 우선적인 역량은 Computer Resource Optimization이다는 점 (쿼리, 캐슁, 스레드 등)