서비스 목표 :
업무, 업무 일지 및 기록, 멤버등을 수치화하여 스케쥴을 자동으로 할당하고 분석 및 예측하는 기능
- 업무 일지(work stream)를 읽고 그에 타당한 작업들(tasks)로 요약
- 작업에 최적화된 작업자들(team member)을 자동 할당
- 최단 완수 기간 예측
- 작업자들의 완수 퍼포먼스 주기적으로 축정
1. 서비스를 처음 구상하게 된 계기
사회적 분위기
한때 집단 지성과 복잡한 집단 데이터를 분류하고 컨트롤하여 여러 방벙과 솔루션등을 제시하는 컨셉이 트렌드였다. AI와 IT 산업의 발전으로 요즘은 그런 부분을 통제하고 추적하고 컨트롤할 수 있는 기능들이 계속해서 나오고 있다.
예) SaaS의 프로젝트 협업 툴, HR 도구, 소셜 네트워크 추천 기능 등등
계기
나 역시 그런 부분에 특화된 기술과 기능들에 관심이 있었다. 그런 부분을 통제하고 추적하고 컨트롤할 수 있는 기능을 만들면 얼마나 획기적일까 하고 생각하다가 이번에 인력 지원 작업 기능을 만들었다. 특히 HR이나 사람등을 분석한 경험이 있는 나에게는 탁월한 선택이었다.
2. 구상 방법**
해결의 목적 - 집단의 작업 능력을 읽고 작업자의 정보를 최대한 활용하여 최단기간에 작업을 마무리할 수 있는 작업 스케쥴 자동 배치
어떻게 해결 했는가? - 알고리즘을 구상하는데 있어서는 많은 어려움이 있었다.
- 어려움 1 특정 3개의 작업에 다수를 한번에 배치하여 최단 기간의 작업 시간을 만드는 것
- 어려움 2 작업 일지를 분석하여 특정 작업 키워드들을 추천하는 방법
- 어려움 3 작업들 간의 선후 관계 구성 예 : 프로젝트 기획 -> 시장 조사처럼 프로젝트 기획이 있어야 시장 조사가 가능하기 때문에 그 관계 구성에 위배 되지 않으면서 작업을 할당하는 부분
3가지 정도의 어려운 부분 이었다. 하지만, 응용 수학과이며 전업 데이터분석인 내 전공을 살려서 획기적인 해결법들을 세가지를 찾았다.
어려움 1의 해결법
NLP 알고리즘과 검색어 추천 알고리즘중에 참조하였다.
어려움 2의 해결법
- 첫번째로 그리디 알고리즘 이부분은 누구나 생각할 수 있는 아이디어이다. 아시겠지만 작업에 참여 가능한 인원들중 가장 작업능력이 월등한 사람들을 순서대로 배치하는 알고리즘 구조를 가지고 있다.
- 두번째로 혼합정수계획법(MILP) 이부분은 데이터 분석 경력이 있어서 활용할 수 있는 방법이었다. 특정 수치로 작업을 이행하는 다수의 작업자들을 최소한이나 최대한의 시간으로 작업을 끝내는 작업 배치법이다.
- 세번째로 헝가리안 알고리즘 이부분은 최적화된 작업자들을 찾는 알고리즘이다. 허나 수치의 차이가 없는 데이터를 비교해서 데이터를 할당하는 상황에서 약간의 결함이 발생할 수 있었다. 더하여 익숙치 않은 알고리즘 방식이라서 적용하기엔 무리가 있었다.
3. 개발 진행에서 처음 경험한 시도들?
fast api와 spring boot의 이중 호출
- 도커 활용시에 여러 특이점은 외부 네트워크 설정과 통일, 더하여 정확한 alias나 명칭활용. 여러형태의 포트 설정과 매핑등이 있었다. 여러 블로그에서 어떻게 활용하였는지 학습해보았고 더하여 GPT등을 활용하여 도커코드에 문제가 있는지 점검 하였다.
- fast api 함수와 데이터 교환 방식
WebClientConfig 설정을 이용하여 주소 설정과 Content-Type을 JSON형태로 설정하여 데이터의 송수신을 원활히 처리하였다. 주고 받을 데이터 타입의 형태등 구체적인 설정을 고려하였다. 아쉬운점이 있다면 완전 비동기처리와 에러처리를 예방하는 코드를 추가하지 못한점이었다.
코루틴 활용 및 함수형 프로그래밍 활용
- 코루틴 활용시에 특이점은 서비스 레이어를 suspend 함수로 통일하여 비동기 흐름을 유지, 병렬 적인 async await 적용의 기점을 판단하는게 헷깔렸다. 더하여 사용하면 데이터 교환 처리가 원활히 안되는 경우를 피해서 활용하는 부분이 어려웠었다.
- 함수형 프로그래밍 활용시에 특이점은 forEach(), map(), filter(), flatMap() 등의 함수를 활용으로 불변 데이터를 유지했으며 보다 가독성있게 코드를 짜냈었다. 객체나 데이터의 변형이 복잡하게 일어나는 코드에서 함수형 프로그래밍을 유지하는데 혼란스러운적도 있지만 많이 익숙해지니 완전히 적응해 나갔었다.
연속 책임 연쇄 패턴 함수의 리팩토링
- 책임 연쇄 패턴은 연쇄적으로 특정 함수가 함수의 기능에 연달아 의존하여 가독성과 오류를 수정하기가 어려운 편이다. 물론, 이형태는 보안 부분에선 뛰어날 수는 있다. 작업 때는 복잡하고 다양한 연계 형태의 함수가 많아서 오류가 걸릴시에 어디에서 오류가 걸렸는지 찾아내기가 쉽지 않았다. 따라서, 함수의 기능성에 의존하기보다 하나의 함수를 병렬적으로 같은 레벨에서 의존하는 방법(퍼사드 패턴식)으로 리팩토링하여 가독성과 오류 수정 부분에서 이점을 얻었다.
- 책임 연쇄 패턴의 해결법은 가능한 하나의 함수를 병렬적으로 같은 레벨에서 의존하는 방법(퍼사드 패턴식)이나, 특정 데이터 값을 갖는 함수로 바꾸어 연쇄를 끊는 것이 미래에 리팩토링 및 업데이트하기 훨씬 수월하다. 추가 적으로 Observer 패턴을 활용하여 이벤트 기반 구조로 리팩토링해도 독립적인 함수 관리가 되기 때문에 좋다.
4. 그 외의 어려움?
의존성 개선과 SOLID 방식
몇몇 클래스에선 의존성이 늘어나는 여러 상황들이 있었다. 그때 클래스를 더 분할해서 활용하는 방식이나 퍼사드 패턴을 적극활용하거나 객체를 파라미터에서 받는등의 기법을 활용함으로써 SOLID를 지켜나가려고 했다. 느낀점으로는 다음엔 좀더 전략적이고 방대한 JPA 인터페이스 구성과 DI 방식으로 최대한 서비스 코드의 의존성을 줄여야 겠다는 생각을 한다.
분석이나 최적화와 관련된 라이브러리 코드를 구성
분석이나 최적화와 관련된 코드를 다루면서 다소 동떨어진 결과가 나오는 것을 고치기 위해 여러 입증 시도를 하였음. 데이터 형태를 변환하는 다양한 전처리 방식들을 겪으면서 여러 상황의 변수들을 겪음.