포트폴리오.
Android Developer
12 - 2024. 04
홈 화면
급식 화면
외출/외박 화면
전체 화면
기상송 화면
아키텍처 설계.
공통 도메인 모듈화.
학생용과 선생님용 두 가지로 구성된 도담도담 서비스를 개발하면서, 두 서비스 간 공통된 도메인(급식 조회, 로그인, 회원가입 등)을 모듈화하여 개발 효율성을 극대화했습니다. 이 모듈화 작업은 개발 시간 단축과 유지보수의 용이성을 크게 개선했습니다. 이 모듈화 전략을 통해 재사용 가능한 코드 기반을 확립하여 생산성을 극대화했습니다.
또한, 선생님용 iOS 버전 부재와 개발 인원 부족 문제를 해결하기 위해, Kotlin Multiplatform(KMP)을 염두에 두고 모듈을 세분화하였습니다. 이를 통해 순수 Kotlin으로 이루어진 모듈을 구축하여 향후 확장 가능성을 높였습니다.
트러블 슈팅.
모듈을 세분화하면서 모듈의 개수가 50개 가까이 증가함에 따라, Github Action에서 설정한 CI 빌드의 평균 소요시간이 11분 이상으로 늘어났습니다. 이를 해결하기 위해, 앱 모듈만 빌드하고 build —parallel
명령어를 사용해 병렬 빌드를 실행한 결과, 빌드 시간이 평균 7분으로 약 40% 감소했습니다.
40% 감소
디자인 시스템 개발.
개발 효율 상승.
UI 개발 과정에서 버튼이나 프로그래스바와 같은 UI 컴포넌트들이 중복 사용되면서, 코드 중복이 많이 발생했습니다. 이로 인해 디자인이 수정될 때마다 모든 코드를 일일이 수정해야 하는 번거로움이 있었습니다. 이 문제를 해결하기 위해, Compose의 장점을 활용하여 디자인 시스템을 개발했습니다. 중복되고 자주 사용되는 컴포넌트들을 개별 디자인 시스템 모듈로 구성함으로써, 유지보수가 용이해지고 UI 개발 소요 시간도 단축되었습니다.
트러블 슈팅.
디자인 시스템의 컴포넌트가 UI 모듈과 다른 모듈에 위치해 있어, 컴포넌트에서 사용하는 파라미터의 데이터 클래스가 Stable 여부를 컴파일러가 추론하지 못해 Unstable로 분류되면서 불필요한 Recomposition이 발생했습니다. 이를 해결하기 위해, 해당 데이터 클래스에 @Immutable 어노테이션을 추가한 결과, 외부 모듈에서 참조하더라도 Compose 컴파일러가 이를 Stable로 인식하게 되어 불필요한 Recomposition이 발생하지 않게 되었습니다.
사용자 만족도 개선.
UI/UX 변경.
안드로이드 앱 사용자들을 대상으로 만족도 조사를 실시한 결과, 약 72%의 사용자들이 UI/UX에 불편함을 느꼈습니다. 이 문제를 해결하기 위해 도담도담의 디자인을 새롭게 개선했습니다. 수치화된 정보를 시각화하고, 복잡한 UI를 단순하게 변경하는 등 사용자 피드백을 바탕으로 문제를 해결하였습니다. 그 결과 , 약 90% 이상의 사용자들이 도담도담의 UI/UX 대해 만족하는 결과를 얻었습니다.
홈 화면 (Before)
홈 화면 (After)
전체 화면 (Before)
전체 화면 (After)
애니메이션 추가.
Compose의 Animation API를 활용하여 UI에 시각적인 흥미를 더해 사용자가 더욱 만족도 있는 경험을 할 수 있도록 만들었습니다. animateContentSize()를 사용해서 유동적으로 변경되는 높이를 자연스럽게 보이도록 만들었고 animateFloatAsState()를 사용해서 차트가 차오르는 애니메이션을 넣는 등 Compose를 사용해 쉽게 애니메이션을 구현했습니다.
자동 로그인 구현.
로그인 세션이 너무 빨리 만료된다는 피드백을 받고 이를 해결하기 위해 Data Store에 사용자의 로그인 정보를 저장하여 자동 로그인을 구현했습니다. 하지만, 로그인 정보를 그대로 저장하면 보안에 취약할 수 있기 때문에 KeyStore를 사용하여 비밀번호를 암호화해 저장했습니다. 또한, 암호화된 Key는 KeyStore에 안전하게 보관되도록 구현하여 보안성을 강화했습니다.
트러블 슈팅.
KeyStore를 사용하는 과정에서 암호화(Encryption)는 정상적으로 작동했지만, 복호화(Decryption)가 작동하지 않는 문제가 발생했습니다. 문제의 원인은 Cipher를 사용할 때 생성된 IV(초기화 벡터)를 저장하지 않았기 때문입니다. 암호화 후 복호화할 때 필요한 IV가 없어서 복호화가 제대로 이루어지지 않았습니다. 이 문제를 해결하며 IV의 중요성을 알게 되었고, 문자열에 구분자를 추가해 IV를 함께 저장하는 방식을 적용하여 문제를 해결했습니다.
홈 화면
연재 웹툰
단편 웹툰
웹툰 열람
아키텍처 설계.
객체 지향 프로그래밍.
기능 단위로 모듈을 분리하여 필요한 기능만 참조할 수 있도록 했습니다. 또한, 접근 제한자와 인터페이스를 사용해 정보의 은닉화 및 추상화를 구현했습니다. 이를 통해 추후 기능 추가 시 발생하는 오류를 줄이는 데 기여했습니다.
private 키워드로 Retrofit API interface의 외부 접근 제한
interface로 Network 클래스를 추상화
internal 키워드로 외부 모듈에서 클래스로의 직접적인 접근을 제한
MVI 아키텍처.
MVI 아키텍처를 채택하여 State를 직관적이고 안전하게 관리함으로써, Recomposition 시 발생할 수 있는 다양한 State 관련 이슈를 사전에 예방했습니다. 이로 인해 UI가 안정적으로 유지되고, 불필요한 재구성이나 버그 발생을 최소화할 수 있었습니다.
성능 최적화.
이미지 로딩 속도 개선.
Glide를 사용해 연재 웹툰의 썸네일 이미지를 표시하는 데 10초 이상 소요되는 문제가 발생했습니다. 이를 해결하기 위해 Glide와 Coil의 로딩 속도를 비교한 결과, Compose에서 Coil이 더 빠르다는 것을 확인했습니다. 이후 이미지 처리 라이브러리를 Coil로 변경하고 다운사이징을 적용한 결과, 이미지 로딩 속도가 1초 이내로 줄어들었습니다.
Pagination 적용.
웹툰 서비스에서는 이미지 전송이 빈번하게 이루어지기 때문에 데이터 양이 많아지면 응답 시간이 길어질 수 있습니다. 이를 해결하기 위해 Pagination을 적용하여 데이터를 효율적으로 로드하고, 사용자에게 빠른 응답 속도를 제공할 수 있도록 했습니다. Pagination 구현에는 Jetpack Paging3 라이브러리를 사용하여 간편하게 대용량 데이터를 처리하고, 스크롤 시점에 필요한 데이터만 로드함으로써 성능을 최적화했습니다.
트러블 슈팅.
스크롤 시점에 이미 표시된 데이터가 다시 로딩되는 문제가 발생했습니다. 원인은 ViewModel에서 PagingData를 StateFlow로 래핑하면서 Paging Flow의 Cache가 끊어진 것이었습니다. 이를 해결하기 위해 ViewModel에서 .cachedIn(viewModelScope)
를 사용하여 Paging Flow의 Cache를 유지하고, PagingData를 모든 다운스트림까지 공유하도록 수정했습니다.
Backend Developer
2024. 03 - 2024. 05
마스킹 서버 개발.
안면 인식률 개선.
OpenCV의 기본 haar cascade 검출기를 사용해 382장의 프레임에서 얼굴을 인식한 결과, 151장의 얼굴을 인식하여 약 40%의 인식률을 기록했습니다. 인식률을 높이기 위해 MTCNN을 적용한 결과, 382장의 프레임 중 381장에서 얼굴을 인식하여 99% 이상의 인식률을 달성했습니다.
트러블 슈팅.
MTCNN을 사용해 인식률을 높였지만, 처리 시간이 길어지는 문제가 발생했습니다. 60fps의 6초 길이의 얼굴 영상을 OpenCV로 처리하면 5분이 소요되던 것이 MTCNN에서는 15분이 걸렸습니다. 이를 해결하기 위해, 이미지 리스트의 얼굴 인식을 순차적으로 처리하던 방식을 `ThreadPoolExecutor()`를 사용해 병렬 처리로 개선한 결과, MTCNN을 사용했을 때의 처리 시간이 5분 15초로 단축되었습니다.