5개월간 iOS앱을 리팩터링하며 알게된점(SOPT회고)(1)

Youth·2023년 12월 18일
2

회고

목록 보기
1/10

날씨가 아주 많이 추워졌네요
저는 울산에 살고있어서 눈을 볼일이 별로없지만 서울은 눈이 아주 많이 왔다고 하더라고요

이번 포스팅은 조금 주저리주저리 회고를 하는 글 정도로 적어보려고 합니다
연말이되면 올해를 보내는 회고를 쓸까했지만 지금 제 감정을 쓰는게 더 의미가 있을것 같더라고요 ㅎㅎ

길고길었던 리팩터링 과정에 대한 포스팅으로 시작하려했는데 적으려하다보니 SOPT에 대한 회고가 선행되어야할거같아서 이번 포스팅은 SOPT회고 위주로 작성될것같습니다. 만약에 SOPT는 모르겠고! 5개월동안 리팩터링한 과정이 궁금해!하시면 다음글인 5개월간 iOS앱을 리팩터링하며 알게된점(더 나은 MVC로의 여정)(2)부터 5개월간 iOS앱을 리팩터링하며 알게된점(MVVM으로의 여정)(3)(추후 추가)을 보시면 될것같습니다!

반년이 지난 이제야 SOPT 회고글을 작성하는 이유

저는 32기 SOPT iOS파트로 활동을 했고 아마도 제 기억으로는 한참 더웠던 7월 말쯤 공식적인 활동이 마무리되었던것같습니다 근데 지금은 12월 중순이고 어영부영 5개월이라는 시간이 지났습니다

7월에 종무식이 끝나고 당시에 같이 활동했던 사람들이 SOPT 32기 회고글을 많이 올렸던거같은데 저는 당시에 회고글 비슷한글도 올리지 않았습니다, 그리고 5개월이 지난 지금에서야 회고를 쓰게 되었습니다

왜 5개월이나 지났는데 회고글을 쓰나요?

라고 물어보실수도 있을거같아 답변을 하자면 제 기준으로 SOPT 32기 활동을 마침표찍었다는 생각이 최근에 들어서야 들었거든요. 5개월에 걸친 라이언하트 리팩터링이 끝나니까 앱잼도, SOPT도 끝나는 느낌이 들었던것같아 회고글을 본격적으로 쓰게 된거같습니다

Apple Developer Academy@POSTECH의 끝

저는 2022년에 Apple Developer Academy@POSTECH에서 iOS개발자로의 커리어를 시작했습니다
이것만 보시면 오 꽤 그래도 할줄을 알았나보네요?하시는 분들도 많을것같지만 애플아카데미에 합격했을때 저는 변수상수도 모르고 삼항연산자를 사망연산자라고 3개월동안 알고있던사람이었습니다

아카데미 특성상 내가 아무리 못해도 프로젝트 자체를 개인프로젝트까지합해서 6개를 하기때문에 결과물만 보면 나 그래도 이제좀 iOS개발좀해~라고 착각을 불러일으킬수있다는 단점아닌 단점이 존재합니다

뭐...사실 제가 딱 그랬습니다
iOS개발을 할줄도 모르면서 앱출시를 2개나 했다는 뽕(?)에 차올라서 무슨 대단한 개발자라도 된듯한 자만심을 가지고있었습니다. 사실은 저보다 훨씬 잘하는 친구들이 만들어준 앱에 UI정도만 짰는데 말이죠..ㅎㅎ

부끄럽지만 저는 당시에 네트워크통신이 제일 무서웠습니다 정말 주구장창 url을 넣어서 get통신만 할 수 있었습니다 post같은건 못했습니다 그렇다고 UI는 좀 잘짜냐하면 다시 제가 짯던 코드를 보면 그냥 엉망진창인 수준이었습니다

그러다보니 아카데미가 끝날때 쯤엔 팀에서 개발자만으로 1인분을 한다기보다는 기획+개발+팀매니징 까지 해야 1인분을 할 수있는 사람이 되어있었습니다

당연히 iOS 개발자로서의 실력은 정체상태였고 옆친구의 성장, 실력을 보면서 부러워하는 상태로 아카데미를 마무리했습니다

아카데미에있을때 SOPT출신의 개발자를 몇봐왔습니다 제가 본 SOPT출신의 아카데미 러너는 잘한다라는 생각을 하게 만들어줬습니다 다른걸 떠나서 실력적으로는 인정할수밖에 없는 사람들이었던 덕에 SOPT를 한번 해보고싶다라는 생각을 아카데미 끝나기 반년전부터 해왔습니다

아카데미가 끝나고 저는 약 두달간의 여행과 휴식시간을 가졌습니다
당시 제 상황은 UIkit은 시작한지 4달정도였고 그마저도 2달간 쉰다고 다까먹은 상태였습니다
어떻게든 강의를 들으면서 다시 감을 잡으려는 시간을 보냈고 프로젝트는 하지는 못했지만 그래도 다시 UI짜는 감정도는 되찾은 채로 SOPT에 지원했고 합격했습니다

SOPT 32기 iOS파트

SOPT에 들어왔을때는 YB라는 명찰과 애플아카데미출신이라는 명찰이 함께 붙었습니다
사실 저와함께 SOPT에 합격한 아카데미출신이 둘 있었는데 저와는 다르게 외향적인 사람들이었습니다
(지금 생각해보면 잘 아는 사람들이랑 같이 붙어서 다행이었다고 생각합니다) 그리고 제가 생각했을때는 저보다 잘하는 사람들이었습니다

그래서 그런가 YB라고 하기엔 애플아카데미출신이라서 좀 더 잘하는거같고 OB라고 하기엔 내가 그 사람들정도의 실력이 전혀아니라는 생각이 들었습니다, 그 중간의 어중간한 상태의 포지션이라는걸 1주차 세미나때 알게되었습니다

지금생각해보면 당시 기수에서 많이 즐기지 못했던 이유가 스스로 정의한 포지션 때문이 아닐까라는 생각이 들었습니다 처음 iOS를 접하는 YB분들을 조금이라도 도와줄수는 있지만 그렇다고 OB분들처럼 실력이 되지 않는다는 마음에 내가 전달하는 지식이 틀리면 어떡하지라는 생각이 부담이었습니다. 그래서 그 중간의 포지션의 역할을 다하기 위해서 더 열심히 과제를 했고 공부를 했습니다

처음 세미나때 제가 옆 조원에게 받았던 질문이 delgate pattern이 뭔가요였습니다 단순한 질문이지만 오히려 근본을 알아야 답할수있는 질문이기도 했습니다. 오히려 이런 기본적인 질문에 대한 답을 하기 위해서는 기초를 잘 공부해야하는구나 애매하게알고있으면 답을 잘 할수없구나라는 생각이 그때 들었습니다

오히려 이거 UI어떻게 짜요?, tableview어떻게 만들어요?같은 질문을 받을줄알았는데 좀더 fundamental한 질문들을 받기 시작하면서 그 질문들에 최대한 정확하고 올바른 답을 해주기위해 많은 시간을 쏟아부었던것같습니다

지금 생각해보면 그놈의 아카데미출신이라는 타이틀에 누가되지 않으려고 노력했던것같네요...아니면 별거없는 실력이 들통나는게 무서워였을수도 있고요

SOPT에서는 제가 아카데미에서 아쉬웠던 부분을 나름 해결하려고 노력을 했던것같습니다. 저는 코드리뷰가 무서운사람이었습니다 고칠거 투성이인 코드인걸 알지만 실제로 지적이 날라오는걸 보는건 생각보다 고통스럽긴합니다. 그래서 오히려 아카데미 중반이후에 그냥 오류없으면 리뷰없이 머지하는 상황이 편하다고 느껴지기도 했습니다

근데 그러다보니 내가 짠 코드가 발전이 없다는 느낌이 들기시작했습니다, 물론 바빠서 모든 pr에 리뷰를 달수 없긴했지만 저정도의 수준에서는 다른사람의 다양한 코드를 보는것만으로 공부가 되니까 그부분에서 느꼈던 아쉬움을 SOPT에서 코드리뷰로 풀려고 노력했습니다

그러려면 우선 코드리뷰를 달기전에 내가 잘알아야했습니다
당시 SOPT는 매주 기본과제+심화과제가 주어졌는데 심화과제는 선택이었습니다 근데 심화과제까지는 하고싶었고 꽤나 시간이나 품이드는 과제들이 몇개있었기에 과제구현 + 모르는 부분 공부가 다른 조원들의 과제마무리전에 끝나야 여유있게 코드리뷰를 달고 소통을 할 수있겠다는 생각이들었습니다

그래서 토요일에 세미나가 끝나면 뒤풀이를 안가고 그냥 집가서 과제를 했습니다 삽질을 하면서 화요일정도에 과제를 마무리하고 개선시킬 방법이있는지 여러 레포를 뒤져가며 수정했습니다 그러다보면 어영부영 수요일 목요일이었고 그즈음엔 슬슬 다른 팀원들이 과제 pr을 올립니다. 그러면 최대한 꼼꼼히 코드리뷰를 달아주면서 한주차의 과제를 마무리했습니다

거의 매주 4~5명에게 위의 사진처럼 코드리뷰를 5~6개씩 길게 달아주기 위해서 노력했습니다
사진을 자세히 보시면 아시겠지만 대단한 코드가 아닌 이렇게 짤수도있고 그렇게 짠이유에 대한 설명정도의 리뷰였습니다

단순히 여기 스펠링 틀렸어요~final붙여주세요보다는 이런 코드리뷰가 더 도움이 되지 않을까라는 생각이 들어서 저렇게 코드리뷰를 달기 위해 노력했던것같습니다

매주 있었던 회식에는 불참했던 덕에 다른 사람들이 서로 친해지는 과정에 저는 없었지만 한주한주 지날수록 코드리뷰를 열심히 달아주는사람 정도로는 기억에 남을 수 있었던것같습니다

그 덕이었다고 해야할지 모르겠지만 3~4주차부터는 조금씩 친해지는 사람들이 생겼고 오히려 비슷한 결을 가진사람들을 만날 수 있었습니다, 다행히 친해지고 싶다고 말해주는 고마운 사람들과 다가와주는 사람들 덕분에 한주한주 부족했던 부분들을 메꿔가면서 8주간의 세미나를 마무리할 수 있었습니다

SOPT의 꽃, 앱잼

SOPT를 하는 사람들이 공통적으로 바라보는 활동이 있습니다 2주간의 합숙을 통해 하나의 앱을 만들어가는 앱잼입니다

저는 당시에 라이언하트라는팀에 들어가고 싶었고 가장 경쟁이 치열했던 팀이었습니다 당시에 시드제라는 방식때문에 가고싶다고 갈수있는 상황이 아니었기도했고 선택받지 못하면 떨어지는 방식이라 한 1주일전부터 정말 많이스트레스를 받았던걸로 기억합니다

결론적으로는 1차에서 떨어지고 2차 3차에서 선택받지 못한 덕(?)에 라이언하트라는 팀에 극적으로 합류할 수 있었습니다, 제가 라이언에 갈 수 있게 도와주시고 응원해주신분들 다시한번 감사드립니다 ㅎㅎ...

어쨋든 그렇게 우여곡절끝에 합류한 팀에서 활동을 하기전에 마지막 8주차 세미나가 남았었는데 아마 이때 처음으로 SOPT iOS파트내에서 주도적으로 뭔가를 했던 순간이었던것같습니다

당시에 미미나라는(미니세미나)라는걸 파트장이 신청받았었는데 처음으로 해보겠다고 하고 세미나를 준비했었습니다, 발표를 준비하면서 정말 많이 걱정했습니다 두달 내내 회식한번, 번개모임한번, 자잘한 모임한번 안나간 조용히 할거하는 사람이 갑자기 세미나를 하게되면 콧방귀를 뀔까봐 조금 무섭기도 했습니다

그래서 그나마 코드리뷰를 자주 달아준 덕분에 제 github닉네임인 킴스캐슬은 다들 아신다고 해서 킴스캐슬이라고 자기소개를 하고 시작하면 괜찮겠다 싶었습니다. 발표를 준비하면서 규보형이 카톡으로 이정도면 사이버팀원이라고 제발 사람들하고 회식좀하고 친해지라고 신랄하게 까는 카톡을 넣을수있게 허락해준덕에 다들 그걸 보면서 웃으면서 발표를 시작할 수 있었고 감사하게도 다들 잘 들어주셨던것 같습니다

마음 한켠에 남아있었던 다른 분들과도 친해지고 싶은 아쉬움이 그렇게 해소되었던것같습니다. 세미나가 끝나고 정말 마지막 회식에는 참여해서 2차까지가는 기염(?)을 토했는데 당시에 2차로갔던 술집에 들어가자마자 다들 실환가 하는 표정으로 저사람이 회식에? 하며 저를 쳐다보는 그 장면이 잊혀지지 않네요

마지막 회식에서 이런저런 사람들과 이런저런 이야기를 하면서 마음한켠에 아쉬웠던 마음까지 훌훌 털어버리면서 SOPT 32기 iOS 세미나를 마무리 할 수 있었고 앱잼을 시작할 수 있었습니다

당시 SOPT는 32기수나 진행된 동아리였고 그러다보니 SOPT스럽다라는 말을 꽤나 자주들었다는걸 알게되었습니다. 개발자인 저로서는 그렇게 달갑지 않은 말이었는데 기존 기수에 사용되었던 코드가 그대로 사용되다보니

  1. 모두가 비슷비슷한 네트워크 구조(대부분 싱글톤)
  2. 모두가 비슷비슷한 라이브러리 채택(대부분 moya, alamofire을 moya처럼 쓰기)
  3. 앱잼특성상 2주만에 앱을 만들어야해서 전부다 똑같은 아키텍쳐구조(mvc)

위의 세가지 구조가 거의 동일했고 그러다보니 각자 앱잼팀의 UI랑 기획정도만 다르고 코드의 메커니즘이 거의 동일했습니다

사실 3번같은 경우는 그럴수있다고 생각은 합니다 MVC도 잘쓰면 충분히 좋은 아키텍처라고 생각하고 2주동안 앱을 완성해야하는데 모든 팀원이 MVVM을 새로배워서 적용하면서 트러블슈팅까지한다...? 이건 솔직히 불가능하다라는 의견에는 동의를 하지만 시간이없기에 MVC는 아무리 생각해도 아니었습니다

그래서 관성에 의한 SOPT스러운 프로젝트를 하지 않기 위해서 팀원들과 정말 많은 회의 내부 미니 세미나를 준비했습니다

1번같은 경우는 팀내 사정을 고려해야하기에 어쩔수없이 싱글톤으로 사용했지만(8주간의 세미나에서 싱글톤으로 구현했기에 팀원들이 해당 방식이 그나마 익숙함, 새로배우기엔 앰잼까지의 시간이 촉박) 앱잼전 회의때 추후에 DIP를 활용한 3단계의 네트워크 레이어의 설계를 마쳤었습니다

2번같은 경우는 urlsession과 async/await을 이용해보기로 했습니다, alamofire나 moya모두 기본base는 urlsession이기에 해당방식을 통해 기초를 쌓자는 의도였고 모두가 동의해줘서 그렇게 결정을 하게 되었습니다, GCD와 async/await의 경우엔 기존 GCD의 단점들에 대한 공감대가 형성이 되었고 성능적으로도 우위에있는 async/await을 쓰지 않을이유가 없다고 생각했습니다(그나마 GCD는 광범위한 iOS버전을 사용할수잇지만 저희팀의 앱타겟은 iOS 16이었기에 문제가 없었습니다)

3번같은 경우는 MVC를 사용하는 이유가 data binding이 없는 앱이었기때문이라는 확실한 이유와함께 massive한 viewcontroller를 만들지 않기 위한 명확한 관심사 분리와 디자인시스템 구축이라느 목표를 맞추고 앱잼을 시작하게 되었습니다

하루 10분 좋은 아빠가 되는 방법, 라이언하트

7월 초부터 2주간의 합숙이 시작되었습니다
당시 저희팀의 인원이 모든 앱잼팀중에 제일 많았던걸로 기억하는데 그만큼 숙소가 좋았고 다같이 작업할수있는 거실에 넓은 책상까지 있었습니다, 작업속도는 예상한만큼 진행되었고 iOS팀은 일주일에 세번정도는 따로 모여서 트러블 슈팅을 진행하고 pr에 최대한 자세히 기록한다는 최소한의 룰을 지키면서 앱잼을 진행했습니다

잠자리를 가리는 편이 아닌데 너무나 확바뀐 환경과 같이 침대를 써야하는 상황 그리고 열몇명이 모두 생활패턴이 다른 부분에서 오는 불편함 때문이었는지 저는 그렇게 깊게 잠을 이루지는 못했습니다

매일 새벽 두시쯤에 개발을 끝내고 자러들어갔다가 3시간정도 자고 새벽 5시에 일어나서 거실에 나와서 개발을 하며 날새고있는 사람들과 같이 작업을 한다던가 전날 일찍자고일어난 사람과 아침인사를 하며 작업하는 그런 생활을 일주일정도 보냈던것같습니다

그러다보니 사람인지라 일주일정도 후에는 잠이 부족해 체력이 방전되기도 하고 당연히 발생할수밖에없는 팀내 이런저런 이슈를 신경쓰다보니 조금은 지쳐있는 팀원과 제 자신을 보게되었습니다

다행히 시간을 많이 투자해서 개발을 한덕에 생각했던 계획을 충분히 맞출 수 있는 상황이었고 iOS팀은 하루 자유시간을 가지기로 결정을 했습니다, 지금생각해보면 그 하루가 2주간의 합숙을 잘 마무리 지을 수 있었던 원동력이 되었던것같습니다

저는 부족함 잠을 보충했고 아무것도 하지 않으면서 다시 재충전의 시간을 가지고 왔습니다 그렇게 하루가 지나고 모인 팀원들은 다시 물먹은 식물마냥 일주일전 상태로 돌아왔었습니다

분명히 시간이 충분하다고 생각했는데 앱잼 데모데이(발표회같은겁니다)가 다가올수록 앱내부적으로 크고작은 문제가 발생하기 시작했습니다. 지금생각해보면 가장 힘들었던 때는, 데모데이 4일전에 테스트플라이트를 올리고 다른 팀원들에게 다운을 받아달라고 했는데 iOS팀원들은 잘 되는데 다른 팀원들만 이상하게 카카오톡 로그인버튼이 안눌리는 문제가 발생했습니다.

처음에는 대충 두세시간정도면, 몇번 시도해보면 해결이 되겠지라고 생각했는데 그래도 앱출시경험이 있는 3명에서 이틀동안 거의 열시간씩 문제점을 해결하려고 했는데도 문제가 해결되지 않았습니다... 구글에 구글링을 해봐도 아무런 레퍼런스가 없고 각자 iOS개발을 하는 지인에게 연락해서 해결방법을 물어봤는데도 아무런 해결이 되지 않았습니다

그렇게 이틀을 해결이 될지도 모르는 문제를 잡고있으니 다들의욕이 떨어지기 시작했습니다. 다 완성을 했는데 마지막 한발자국을 갈수가없으니까 미치고 팔짝 뛸 노릇이었습니다. 그냥 우리 iOS팀원들 앱으로 시연을 하면되지라는 생각으로 팀내에서 타협점을 찾으려고 했습니다. 당시 저랑 팀원들도 지칠대로 지쳐서 데모데이 이틀을 남기고 휴식하기로 결정을 하기도 했습니다. 근데 그때 팀장이 xcode설정에서 한가지 찜찜한부분이있다고 확인을 했는데 릴리즈버전에서 누락된부분이있는걸 찾아냈고 그부분을 잘 체크하니 문제가 해결되었습니다

정말 그때 동영상을 안남겨놔서그렇지 반쯤 죽어가는 나무같던 팀원들이 다시 살아나서 xcode를 켜고 신나서 QA를 하면서 코딩재미있네~하며 모여서 코딩하던 모습이 기억에 남네요 ㅎㅎ

그렇게 데모데이를 잘 마치고 꿀같던 3일간의 휴식을 가질 수 있었습니다...지금 생각해보면 3일동안 잠만잤던거같아요ㅎㅎ

그래도 2주동안 참 열심히 했고 웃기도 많이 웃었고 힘들기도 엄청 힘들었습니다 그래도 2주동안 앱잼하면서 새벽에 맥주한캔하면서 개발얘기 사람사는얘기 같이하면서 소소하게 웃고 떠들었던 그 순간은 반년이 지난지금에도 기분이 좋아질만큼 좋았던 기억이라고 생각합니다

라이언하트의 끝과 시작

늘 그렇듯 정해진 프로젝트 기간이 끝나면 앱잼 합숙기간만큼 시간을 쏟을 수 없고 각자의 사정이 도드러지기 시작합니다. 이러한 점이 프로젝트의 정체기를 만들기도 하죠

라이언하트도 대부분의 상황처럼 프로젝트 정체기를 맞이할 확률이 높다고 생각했습니다, 사실 이건 어떤팀이나 마찬가지라고 생각했습니다. 2주동안 여기에 모든 노력과 시간을 쏟았으니 합숙이 끝난후에는 못만난 친구도 만나야하고 못했던것도 해야하고 휴식도 취해야합니다

다른곳에 사는 사람들이 매번 대면으로 만날수없고 장소에 대한 비용이나 시간합의도 매번 맞추기 어려우니 비대면이라는 차선책을 선택할 수밖에 없겠죠. 그렇게 당연히 속도가 더뎌질 수 밖에없습니다, 2주동안 너무 즐겁고 열심히 했던 팀이더라도 2주후에도 그런팀으로 여전히 남아있으리라는 보장은 없습니다. 프로젝트는 2순위 3순위로 미뤄지는건 너무나도 흔하고 당연한 일입니다.

라이언도 당연히 그랬다고 생각합니다. 다행히 iOS팀원들은 프로젝트가 끝나고 3일 후부터는 스터디를 구성해서 일주일에 세번정도 cs와 iOS공부 그리고 알고리즘을 위한 시간을 가졌습니다. 언제든지 라이언하트를 다시 진행할때가 오면 바로 프로젝트를 진행할수있게말이죠

앱잼이 끝난후에 팀내에서 재시작시점에 대한 논의가 활발히 진행되었습니다. 하지만 팀내에서 프로젝트에 쏟을 수 있는 시간과 우선순위를 맞추는데 어려움이 있었습니다. 당연히 그럴 수 밖에 없었다고 생각합니다

우리 프로젝트를 진지하게 사업으로 밀고 나가고싶은 사람과 취업을 위한 공부와 포트폴리오로 생각한사람은 프로젝트에 쏟을 수 있는 시간의 양 자체가 다르니까요. 하지만 사업의 명목으로 이 앱을 바라보지 않으면 작가분들에게 아티클을 받아야하고 유료 구독을 해야하는 기획팀입장에선은 미팅때 아티클 소싱시 명분이 부족해질 수 있습니다. 누군가는 그렇다고 이 앱에 100을 쏟자니 내가 계획했던 모든것들을 포기해야하거나 내가 그리고 있는 다음이 아닐수있습니다. 투자할수있는 시간과 열정에 대한 적절한 정도를 맞추지 못하면 불만이 생길 수 있고 당연히 문제가 생길 수 있습니다

팀 내에서는 다함께에 조금 더 의미를 두기로 결정을 했습니다. 라이언하트라는 팀이 지금 구성원으로 다같이 마무리하기 위해서는 새로운 기획을 통한 앱출시 혹은 기존 앱을 출시하지 않는선에서 각 파트별로 만족할수 있는 수준으로 발전시키는 선택지 중에 하나를 선택하는걸로 결론을 내리게 되었습니다

그리고 결론적으로는 두번째 선택지인 앱을 출시하지 않고 각파트별로 만족할수있는 수준으로 라이언하트를 발전시키는 방식을 선택하게 되었습니다. 끝을 위한 새로운 시작을 선택했다고 생각합니다.

iOS내에서는 기존 MVC방식의 라이언하트라는 어플리케이션을 리팩터링하기로 결정했습니다. 그렇게 결정한 이유는 UI는 완성이 되어있는 상태였지만 모든 로직이 viewcontroller에 모여있었고 보일러플레이트가 눈에보일정도로 너무 많았고 공통으로 뺄수있는 부분도 시간의 압박에 못이겨 개별구현되어있었던 탓에 보기어려운 코드였었습니다. 말그대로 돌아가기만하는, 언제 어디서 문제가 터질지 모르는 시한폭탄같은 스파게티 코드라는 생각에 모두가 동의를 했고 참여할수있는 저를 포함한 3명의 팀원과 함께 MVC에서부터 리팩터링을 진행하게 되었습니다


본 포스팅은 리팩터링이 마무리된 12월에 작성된 포스팅이며
https://github.com/Team-LionHeart/LionHeart-iOS
해당 링크에 리팩터링 과정이 readme에 자세히 기록되어있습니다

profile
AppleDeveloperAcademy@POSTECH 1기 수료, SOPT 32기 iOS파트 수료

0개의 댓글