이글은 2022 F-UNIV CAMP 강연 내용을 기반으로 작성되었습니다.


프로젝트를 같이 하고 있는 팀원에게 연락이 왔다 !

그분도 대학생 프론트앤드 개발자이신데, 대학생 프론트앤드 개발자들을 위한 컨퍼런스를 발견하였다며 들어보라고 추천 해주셨다.

 

그게 바로 2022 F-UNIV CAMP였다.

 

12/18일 강연을 들었고, 내가 들으며 메모한 내용 중심으로 블로그 글을 써볼까 한다.
(강연 들으며 모든 내용이 아닌 중요부분만 빠르게 메모한 것이기 때문에 글이 자세하지 않은 점 양해 바란다 ..ㅎㅎ)

 

F-UNIV CAMP는 해당 홈페이지에도 나와있는 내용이지만 프론트엔드를 진심으로 좋아하는 대학생들의 인프라를 만들기 위해 기획되었다고 한다.

해당 강연은 총 6개의 Session으로 나누어져 있었는데, 정리한 내용을 적어보도록 하겠다.

 


먼저 첫번째 강연자는 수원대 정충일님이셨다.

이분이 이 컨퍼런스를 주최하셨고, 프로젝트 기획부터 배포까지라는 내용으로 강연을 해주셨다.

나는 프로젝트 진행경험이 있었어서 강연 내용이 많이 새롭진 않았지만, 프로젝트를 막 시작하려고 하는 사람들에겐 도움이 되는 내용이 아니었을까 생각한다.

 

프로젝트의 진행순서는 기획 => 개발 => 배포가 있는데, 

각각의 단계에서 어떻게 진행되는지 직접 만드신 프로젝트를 기반하여 설명해주셨다.

나는 아직 배포 이후의 단계를 겪어보지 못하여 배포 분야가 기억에 많이 남았던 거 같다.

 

배포를 하면 피드백을 얻을 수 있다고 한다. 그 피드백을 기반으로 개선이 가능하고, 배포 후 얻은 피드백은 발견하지 못했던 오류들을 많이 발견 할 수 있다고 말씀 해주셨다.
충일님께선 실제로 에브리타임에 자신이 기획한 서비스를 올려 사용자가 늘어났고, 좋은 피드백을 받았으며 이를 학교에서도 좋게 봐서 뉴스에도 나온 경험이 있다고 하셨다.

나도 추후 어떤 서비스를 만들어냈을 때 배포 이후의 과정을 겪어보는 경험이 필요하지 않을까 생각했다. (실제 서비스를 만든 사례들을 들어보면 배포 이후의 과정 또한 배울것이 많다고 들었다.😮)

충일님은 본인이 만약 서비스를 만들게 된다면 내가 이걸 사용한다면 왜 사용해야되고, 이걸 사용하라고 어떻게 설득시킬 수 있는지에 대한 점도 생각하며 만드는것이 좋다고 말씀해주셨다. 나도 추후 내가 만들고 싶은 서비스를 사용자들에게 배포하여 좋은 피드백을 얻어보고 싶다는 생각이 드는 강연이었다.

 


두번째 강의는 아주대 넥슨 김영진님이셨다.

김영진님은 부트캠프를 준비하는 분들에게라는 주제로 강연을 하셨다.

김영진님은 네이버 부스트캠프 6기를 졸업하시고 오픈소스 컨트리뷰션 아카데미 리드멘티를 하신 후 지금은 넥슨에 합격하였다고 한다.

 

영진님은 부트캠프를 하며 많은 사람들과 의견을 주고 받으며 성장했고, 질문하는 방법에 대해 배웠고, 커뮤니티를 통해 소통을 하는 방법을 배웠다고 말씀해주셨다.

부트캠프를 수료하며 아쉬웠던 점은 주어진 과제를 해결하는데만 집중한 것이었는데, 과제에 집중하기 보단 내가 왜 이 코드를 이렇게 짜야하고 어떻게 짜야 좋은 코드를 짜는것인지에 대해 집중하는것이 좋을 것 같다고 하셨다.

그리고 부트캠프에 들어갔을때 잘하는 사람들이 많은데, 다른 사람들과 비교하며 절망하지 않는것이 중요하다고 한다.

 

강연이 끝난 후 알고리즘 코테준비와 프로젝트 비중을 어떻게 두는것이 좋을 것 같냐 라는 질문이 들어왔는데,

(이때 정말 소름 돋았다. 나랑 너무 똑같은 고민을 하셨던 분이 계셔서)

 

내가 결론을 내린 것과 같이 코딩테스트 준비를 하는것이 조금 더 중요하지 않을까 라는 답변을 해주셨다. 코테를 준비하며 풀어본 문제들 중에서 구현문제를 좋아하셨고, 그런 구현 문제를 실제 개발에 적용하는 과정이 도움이 됐던 것 같다고 말씀해주셨다.

코딩테스트를 통과해야지 내 프로젝트를 보여줄 수 있는 기회가 생기는것 같다고 말씀해주셨는데 카카오에 합격한 선배가 해준말과 너무나 일치하여 소름이 돋았고.... 정말 코딩테스트 준비 열심히 해야겠구나 라는 생각이 강하게 들었던 거 같다.🔥


그리고 코딩테스트를 js로 준비하는것도 필요하다고 말씀해주셨는데, 이 말을 들으며 이것도 해야되고 저것도 해야되네😥 라고 마음이 조급해졌지만

이내 마음을 다잡고 내린 결론은

일단 지금 겨울방학엔 알고리즘 유형부터 공부하고 기존에 사용하던 c++언어로 문제들에 익숙해지는 과정을 먼저 하는것이 좋지 않을까 생각했다.

그런 후 js로 알고리즘문제도 많이 풀어보며 함수 하나하나 분류하는 과정을 학습해봐야겠다고 생각했다.

 


또 추가적으로 부트캠프 이외에도 인턴 경험을 해보면 좋을 것 같다고도 말씀해주셨다.

정말 인턴 경험은부트 캠프와는 다른 경험을 할 수 있지 않을까 라는 생각이 들었다.

 

 

부트캠프에서 알려주는 내용이 기초적일지라도 내가 배우는 부분은 무조건 생기니 어느 부트캠프던 다 좋을 것 같다고 해주신 말도 인상깊게 남았던 거 같다.
최근에 부트캠프 지원에 관한 고민에 대한 해답도 여기서 어느정도 좋은 조언을 얻었다고 생각했다. 

(좋은 부트캠프를 해야지만 잘될 것이다라는 생각을 가지고 있어 어떤 부트캠프인지 보다는 유명한 부트캠프인가에 초점을 뒀던 거 같다. 내가 정말 하고 싶은 부트캠프를 찾아 하는것이 중요할 거 같다고 생각했다.)

 


다음은 폴리텍대 채널톡에서 근무하고 계신 임광열님이셨다.

임광열님은 첫번째 취업, 그리고 첫번째 이직이라는 주제로 강연을 해주셨다. 임광열님은 신입 프론트엔드 개발자의 위치에서 그동안 겪어 왔던 이야기를 해주셨다.

광열님이 취준을 할때 쯤 됐을때 프로젝트도 했고 스터디도 했는데 취업은 어떻게 준비하면 좋을까? 라는 생각이 가득하셨다고 한다. 그래서 광열님은 회사에서 나를 왜 뽑아야할까? 라고 역지사지의 자세로 고민을 하셨다.

 


회사가 신입에게 바라는것은
1. 팀에 잘 어우러지는가
2. 성장 가능성
3. 실무 투입 가능여부
이렇게 3가지를 볼 거 같은데,

 

 

먼저 1.팀에 잘 어우러지는가협업 경험 즉 팀프로젝트 경험을 볼텐데, 이를 면접 시간내에 증명해내기는 쉽지 않다고 생각하셨다고 한다. 그저 최소한의 조건이라고 생각하셨다.

 

그래서 두번째 2. 성장 가능성.

즉, 개발을 즐기는 태도를 지녔냐 !

내가 만들고 싶은 걸 직접 만들어서 작은 성과라도 내본 사람인가!

어떤 문제를 끝까지 붙잡아서 해결해내는 사람인가!

라는 의미가 아닐까 생각했는데, 본인은 일로써 개발을 좋아하는 사람이라고 결론을 내렸기에 이 또한 자신이 면접장에서 강한 경쟁력이 될 순 없다고 생각하셨다고 한다.

 

그래서 마지막 남은 3. 실무 투업 가능한가. 

즉, 그만한 기본기가 갖춰져 있는가.

기술을 탐구 하고 그를 토대로 노션을 정리하고 내것으로 만드는! 그리고 논리적인 생각을 바탕으로 말을 조리있게 잘하는것이 바로 광일님의 장점이라고 생각하셨다고 한다.

 

그래서 이러한 부분을 어필하기 위해 기술면접에 다음과 같이 대응하였다고 한다.

 

 

먼저, 기술면접의 종류를 분류해보자면
<문답식>

1. 질문에 대한 답을 말하는 방식

2. 이론 + 실무적 지식 - 어디까지 알고 있는가?

3. 프로젝트에 대한 경험 - 이력서에 작성한 항목이 사실인가?

 

이런 문답식의 기술면접은 계속해서 들어오는 질문에 분명히 모르는것이 나올 수 있는데, 모를땐 모른다고 하고 아는것을 더 강하게 어필하는 것이 중요하다고 말씀해주셨다.

 

<과제기반>

1. 사전에 제시한 과제를 바탕으로 진행.

2. 지원자가 작성한 코드나 프로젝트 설정

 

<라이브 코딩>
1. IDE / 화이트 보드를 이용하여 면접관 앞에서 진행

2. 단순 구현 문제나 디버깅 - 문제에 대한 접근, 평소의 코드 작성 방식 확인

 

이러한 기술 면접은 요점을 파악하는 순발력과 문제해결을 위한 소통능력 중요하다고 말씀해주셨다.

 

<PR 리뷰>

1. 실제 회사 내에서 올라온 PR을 바탕으로 면접관과 함께 리뷰하는 방식

2. 기획이나 기술적 논의 등의 커뮤니케이션을 어떻게 이어나가는지?

PR리뷰 방식의 기술면접은 나의 협업 능력을 잘 보여줄 수 있을 뿐만 아니라, 회사의 진행방식도 알 수 있어서 좋은 기술면접이라고 생각한다고 하셨다.


 

위와 같은 기술 면접들이 있는데, 광일님이 면접 준비할때에도 이 모든것을 다 대비하긴 어려웠기에 다음과 같은 부분들을 준비했다고 말씀하셨다.

 

[목표의 구체화]
1. 원하는 회사의 사이트

2. 채용 플랫폼

3. 채용공고의 필수조건 / 우대조건


면접은 모든 내용을 다 준비할 순 없지만 내가 희망하는 회사에서 요구하는 필수조건만이라도 무조건 공부해 가는것이 중요하다고 하셨다. 해당 사이트에 들어가면 정보들이 다 나와져 있고, 이런 최소한의 역량은 달성해야한다고 하셨다.

 

그래서 광일님은 셀프체크를 위해 노션을 정리하여 아는것과 모르는것을 구분하였다고 한다.

노션 속에는 중요 프론트엔드 관련 개념들이 폴더로 나열되어 있었고, 몇회독을 했는지도 이모지로 표현하여 셀프 체크를 하고 있었다.

광일님의 정리 방법을 보며 정말 내 스타일이라고 느꼈다.(아니 광일님 말고 정리방법이요.정리방법. 저 그런 사람아니에요.)


중요한 필수적인 개념들을 빠트리는거 없이 모두 적어두고 한눈에 볼 수 있도록 정리해 놨고, 그 노션 속 내용들만 보면서 공부하면 완벽하게 준비 할 수 있겠구나라는 생각이 들었기 때문이다. 그런 정리된 느낌이 좋았다. 나도 그런 방식으로 빠트리는거 없이 계획적으로 공부해야겠다라는 생각이 많이 들었다.

 

 

광일님이 정리하며 집중했던 것들은
1. TIL식 말고, 개념 단위로 정리하기.(이게 내가 생각하기에 좋은 방법인 거 같다.)

2. 개념안의 연관관계를 시작적으로 구분하기 위해 마크다운 문서 적극 활용하기

3. 누군가에게 설명한다고 생각하고 흐름이 끊기는 부분을 보충하기. 그러면 지식이 구조화 됨.

이라고 말씀해주셨다.

 

 

 

딱 강연을 마쳤을때 '체계적이다' 라는 생각이 강하게 들었고, 나도 이렇게 준비해야지 맘이 놓이겠구나 싶었다.

취준을 하면서 내가 왜 이 회사에 붙었지..? 라는 느낌이 들기보다 내가 이렇게 준비했으니 붙었지. 라는 생각이 들었으면 좋겠다고 생각했다.

최근 취준생들을 많이 봐서 그런지 취업 관련 이야기인 광일님의 강연이 인상깊었던 거 같다.

 

 


광일님께서는 실력있는 개발자활발한 대외활동을 하고, 유명 오픈소스 기여 하고, 프론트 백 모두 다 개발가능 한 사람이 아닌

1. 비즈니스에 근거한 우선순위를 고려하는 사람.
2. 부족한 기획이라도 더 나은 결과물을 만드는 사람.
3. 일정 관리와 공유를 꼼꼼히 챙기는 사람.
4. 문제를 문제라고 인지하고 해결 방법을 찾는 사람.
인거 같다고 말씀해주셨다.
나도 최근들어 이부분에 굉장히 동의하고 있고, 활발한 대외활동을 해야지 실력있는 개발자가 되는것이 아니라는 것을 인지하는 것에 도움이 되는 말이었다고 생각한다.

 


광일님은 이직을 하셨는데, 회사의 목표와 개인의 목표의 괴리가 생겨 이직을 하셨다고 한다.

개발을 하면서 만족감을 느낀건 본인이 성장할때 만족을 느꼈기 때문에 자신과 비슷한 위치의 프론트엔드 개발자가 어느정도 있고, 그 개발자들과 이야기를 나눌 수 있는 환경이 필요하다고 느꼈다고 한다.

이직을 할때 회사 선택의 기준은
1. 업무 환경 (팀 구성, 기술 스택)
2. 회사 (개발 문화, 현재 단계와 앞으로의 목표)
3. 보상 (남들과 비교하지 않을 정도의 최소 기준)
정도였고, 스스로 자격요건에 충족하는 사람인지 검토가 먼저라고도 말씀해주셨다.

이렇게 이직과 관련된 이야기도 해주시고 강연이 마무리가 되었다.

 


다음은 아주대 카카오 차재명님께서 발표해주셨다.

현재 카카오 다음 포탈에 제직중이시고 강의 주제는 Svelte, 들어보셨나요? 였다.

나는 Svelte를 이번강의에서 처음 들어봤다. (React만 했으니..)

 

React를 사용하는 이유는
1. 라이브러리의 다양성 보장

2. hook을 통해 다양한 기능 사용

3. vDOM을 통한 이벤트 기반 반응

등등 많은 이유가 있는데,

React를 사용하다가 새로운게 필요하다고 생각되어 Svelte를 알게 되셨다고 한다.

Svelte에 많은 기능을 설명해주셨는데, 공식문서를 참고하면 더 자세하게 나와 있을거라고도 알려주셨고, 나는 Svelte의 다양한 기능들 중 store라는 기능이 인상깊게 남았던 거 같다.

 

프론트 프로젝트를 진행하며 컴포넌트가 많아지고 상속받는 props들이 늘어나며 우리는 상태관리 라이브러리(redux/recoil)와 context api 등을 활용하여 props들을 정리하곤 했다.

 

코드를 정리하여도 많은 props들을 관리하는건 어렵구나 라고 생각하곤 했는데,
Svelte에 있는 store 기능을 사용하면, store에 추가하여 store를 임포트 해서 쓸 수 있다고 했다.

그럼 많은 props들을 store에 넣을 수 있는거고, import코드만 작성해주면 좀 더 깔끔해지지 않을까 라는 생각에 굉장히 좋은 프레임워크구만! 이라고 생각했다.

 

 

현재 Svelte를 사용중인 곳이 바로 daum 웹페이지라고 한다. 그래서 많은 관심 바란다고 말씀해주셨다 ㅎㅎ

Svelte를 처음 알게 되어 흥미로웠고, 추후 좀 더 알아본 후 나에게 더 매력적으로 다가오게 된다면 사용해보는것도 좋은 경험이 될 것 같다고 생각했다.

 

 

추가로 강연이 끝나고 질문도 받아주셨는데, 재명님도 네이버 부스트캠프를 하셨고, 그를 통해 경험을 좀 쌓으면서 인턴준비를 했고하계 인턴쉽을 6월에 하시고 전환 면접에 합격하여 본사에 들어가신 케이스라고 말씀해주셨다.

 


그 다음은 국민대 우테코4기 황정민님이셨다.

황정민님께서는 비전공자 FE 입문 이야기 라는 주제로 강연해주셨다.

1. 처음 FE를 공부하는 법

2. 앞으로 프론트앤드로써 나아가야 할 점

3. 비전공자로써 궁금한점

의 순으로 강연해주셨는데,

 

먼저 처음 FE를 공부하는법에선

리액트로 프론트를 시작하시는 분이 많은데 (뜨끔) 리액트 속 코드들은 js, html, css 이니 이를 먼저 공부해보는게 좋다고 해주셨다. 

 

공부를 할땐 공식문서를 가장 추천하지만 어려우니

블로그 => 인터넷 강의 => 책 => 공식문서 

순으로 보는게 좋을 거 같다고 하셨다.

 

그리고 공부를 한 뒤 기술 체화를 위해 Todolist를 만들어보는것도 좋은 방법인 거 같다고 하셨다. 실제로 프로젝트 같이 하는 팀원분도 todolist만들며 프로젝트에 적용해본 내용 복습해보는것도 좋은 거 같다고 말해줬었기 때문에 오오~! 하며 들었던거 같다.😮😮😮

 

그리고 자기가 만들어보고 싶은 서비스를 만들어 보는게 도움이 많이 된다고 한다.

정민님은 예전에 FE공부를 시작하실때 FE 공부 로드맵을 보며 도장깨기 방식으로 하나하나 공부해 나갔다고 한다. 하지만 그렇게 공부하니 내가 왜 이걸 사용해야하고 어떻게 해야하는지 잘 모르게 되는 의미 없는 공부가 되었다고 한다.

 

그래서 로드맵 보고 공부하기 보단, 그냥 필요에 의한 공부를 하는게 더 좋은거 같다고 말씀해주셨다.

어떤 장점을 가졌는지 / 내가 이걸 왜 사용하는지 등을 알고 도입하여 개발해보라고 말씀해주셨다.

 

그렇게 공부하다보면 깊이 있는 공부가 가능하고, 그런 깊이 있는 공부는 면접 상황에서 꼬리질문을 잘 답할 수 있는 좋은 영향력이 된다고 하셨다.

 

또한 회고와 기록하며 내가 하고 있는것에 대해 기록을 해두면 좋다고 하셨는데, 실제 회고는 한달 간격으로 기록하셨고,  간단한 공부내용을 노션에 그리고 인상깊은 기억이나 트러블 슈팅을 기술블로그에 기록해두셨다고 한다.

 

 

앞으로 FE로 나아가야 할점은

1. 사용자 경험 개선 -> 성능 최적화 / 웹 접근성

2. 개발자 경험 개선 -> 리펙토링 / 테스트(단위,e2e, 컴포넌트) / 빌드,배포 속도 최적화 / 타입스크립트

등이 있지 않을까 라고 말씀해주셨다.

 

 

비전공자와 관련된 내용은 많이 메모하지 않았지만, 국민대 전자공학과를 나오셨는데 비전공자라고 해서 손해를 보거나 더 불리한 경우는 없었다고 말씀해주셨던 거 같다.

실제 나도 비전공자분들이 훨씬 더 잘하는 경우를 봤기 때문에, 비전공자와 전공자를 나누는건 큰 의미가 없지 않을까 생각했다. 그저 학교에서 전공 수업을 듣는다 정도?

 


마지막으로는 충남대 토스 박은식님이었다.

박은식님은 UX에 관해 발표해주셨다.

은식님은 3학년때 SIA에서 인턴을 하셨고, 4학년 1학기때 당근마켓에서 인턴을 하다가 4학년 2학기에 토스에 합격하여 일하게 되었다고 한다.

 

먼저 강연을 시작하기 앞서 UI/UX를 잘 모르시는 분들은 침착맨의 "UI/UX 레벨테스트 영상"을 보면 이게 뭔지 정도는 알 수 있을 것이라고 말씀해주셨다. ㅎㅎ 강연을 듣고 있는 와중이라 안 봤는데 나도 나중에 한번 봐야겠다ㅎㅎㅎ

 

토스에 계신 분이어서 그런지... 정말 프론트 UI/UX에 분야에 관련된 엄청난 지식들을 이야기 해주셨다. 내용을 듣는데 어려워서 이해하느라 메모를 많이 못했지만 그래도 한번 정리해보겠다.

 

 

먼저 다크모드더큰텍스트 그리고 웹접근성에 대해서 설명해주셨다.

 

다크모드에 대해서 나는 예전에 한번 이야기를 들어본 거 같다. 다크모드로의 전환 개발이 마냥 쉬워보이지만 간단하지 않고, 다크모드를 많이 사용하는 추세인 요즘에 꼭 필요한 기술이라고 들었던 거 같다. 나도 나중에 내가 만든 서비스를 리펙토링하며 다크모드를 적용해보면 어떨까 하는 큰꿈을(..ㅎㅎ) 꾸었다.😆

 

그리고 더 큰 텍스트는 말그대로 텍스트를 키워 더 잘보이게 해주는 기능이다.

 

그리고 웹 접근성에서

시각에 도움을 주는 요소들은

웹페이지엔 스크린리더가 있는데, 이미지 태그에 있는 src값을 읽어준다고 한다. 하지만 alt값이 있으면 그걸 읽어준다!

 

내가 프로젝트를 진행하며 태그를 작성할때 alt값을 안 적어주고 작성한 적이 있었는데, 프로젝트를 함께 진행한 팀원이 alt값에 대해서 설명해준 적이 있었다. 이렇게 스크린리더가 alt값을 읽어 어떤 코드인지 알려주는 기능을 하기 때문에, 다음부턴 alt값도 함께 적어주며 코드를 작성하곤 했던 거 같다.

 

또한 aria label이란 것도 있는데, aria-label을 넣어주면 스크린리더가 이를 읽어서 접근성이 더 높아진다고 한다.

공식문서

 

그래서

1. 의미있는 html태그 사용

2. 적절한 aria사용

등등 시각적으로 도움을 줄 수도 있다.

 

이와같이 시각적 외에도 운동성이 부족한 사람에게 키보드 접근성을 제공해주는 부분도 있다고 한다.

 

 

 

사용자 경험을 도와주는 도구들은

1. 제이콥의 법칙

=> 사용자는 이전의 경험들을 바탕으로 사이트가 동작하는 것을 기대한다.

2. 도허티 임계

=> 컴퓨터와 사용자가 서로를 기다리지 않아도 되는 속도로 인터렉션을 하면 생산성이 높아진다.

3. 폰 레스토프 효과

=> 평범한 것보다 독특하거나 특이한 것을 기억할 확률이 더 높다.

4. 피츠의 법칙

=> 대상에 도달하는 시간은 대상까지의 거리의 대상의 크기의 함수 관계에 있다.

 

와 같은 것들이 있는데 이 4가지 중에서 4번 피츠에 법칙에 대해 더 설명해주셨다.

피츠의 법칙 설명을 위해 강의자료로 제공해주신 사진

위 사진에서 사각형을 위에서부터 좌우로 왔다갔다 하며 순서대로 클릭을 하고 총 몇번을 클릭할 수 있었는지 시간을 제고 세어보라고 하셨다. 나는 사진 속 사각형을 따라가며 클릭해보았고, 사각형의 면적이 클수록! 그리고 거리가 가까울 수록! 더 많이 클릭 할 수 있다 라는것을 깨달았다.

 

이와 같은 활동을 해보니 피츠의 법칙이 이해가 잘 되었고, 우리가 UI/UX구성을 할때에도

1. 터치 대상의 크기는 사용자가 정확하게 선택할 수 있을 정도로 충분히 커야하고

2. 터치 대상 사이에 충분한 거리를 확보해야한다

는 점을 알 수 있었다.

 

 

지금 프론트 프로젝트를 진행하며 UI/UX단계에 있는데, 은식님의 강연 내용또한 너무 인상깊게 남았던 거 같다. UI/UX에서 중요시 여겨야할 부분에 대해 깨달았고, 좀 더 공부해보고 정리 해본 뒤 프로젝트에도 적용해봐야겠다고 생각했다.

 


이렇게 강연이 끝이 났다.

 

정말 멋지신 분들의 강연 내용을 들어서 배울 수 있는게 많았고, 강연에서 깨달은 내용과 배우게 된 내용을 토대로 개발 공부를 지속해 나가야겠다고 생각했다.

https://www.acmicpc.net/problem/17499

 

17499번: 수열과 시프트 쿼리

첫 번째 줄에 Q개의 연산을 차례대로 수행한 후 a1, a2, …, aN 을 공백을 사이에 두고 출력합니다.

www.acmicpc.net

Goricon에서 다른 문제들도 있었지만, 이 문제 유형은 알아두고 방법을 익히면 다른 같은 유형의 문제들도 쉽게 해결 할 수 있을거라는 판단이 들어 이 문제에 대한 풀이를 적어보고 완벽히 익혀보고자 한다.


문제 해석


 

어떤 한 수열을 입력받은 후, 1번을 입력받았을 땐 한 수에 x 만큼 값을 추가, 2번을 입력받았을땐 오른쪽으로 이동, 3번은 왼쪽으로 이동하여 최종적으로 변화된 수열을 출력하는 문제이다. 


코드


#include<iostream>
#include<algorithm>
#include<vector>
#include<cstring>
#include <tuple>
#include <string>
using namespace std;
long long a[200000];
int N, Q;
int x;
int start_point = 0;
int k, add_item;



int main() {
	ios::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
	
	cin >> N >> Q;
	for (int i = 0; i < N; i++) {
		cin >> a[i];
	}
	for (int i = 0; i < Q; i++) {
		cin >> x;
		if (x == 1) {
			cin >> k >> add_item;
			k -= 1;
			a[(start_point + k) % N] += add_item;
		}
		else if (x == 2) {
			cin >> k;
			start_point = (start_point + N - k) % N;
		}
		else if (x == 3) {
			cin >> k;
			start_point = (start_point + k) % N;
		}
	}

	for (int i = 0; i < N; i++) {
		cout << a[(start_point + i) % N] << ' ';
	}




	return 0;
}

문제풀이


위 문제에서 중요한 부분은 바로

start_point = (start_point + N - k) % N;

이 문장과,

start_point = (start_point + k) % N;

이 문장이다.

나는 이 문제에서 1번을 입력받았을때 해당 숫자를 x 만큼 늘리는 과정은 어렵지 않다고 생각했다. 입력 받은 수 + x 를 해주고 다시 그 입력받은 수에 넣어주면 되기 때문이다.
하지만, 중요하다고 본게 2번 3번이다. 

나는 일단 전체적으로 수열이 이동하는 것이기때문에, start_point를 잡아주는것이 중요하다고 보았고, 배열의 start_point를 0으로 잡고, 계산했다.
먼저 오른쪽으로 이동하는 2번 같은 경우는 첫번째 코드와 같이 작성해보았는데, star_point에서 배열의 길이인 N만큼 더해주고, 입력받은 얼만큼 이동할 것인가?에 대한 k를 빼줬다.(늘어난 길이에서 k를 더해주는것이 아닌 빼주는것은 N만큼 더해줬으니 반대로 생각해주면 된다.) 그 후 N으로 나머지연산을 해주면 원래 배열의 길이로 돌아와 k만큼 이동한 배열을 얻을 수 있다.

다음으로 3번같은경우는 start_point에서 k만큼 더해준 후, (2번의 경우와 반대 ! N을 더해주지 않았으니.) 배열의 길이인 N으로 나머지 연산을 해주면 왼쪽으로 이동한 수열을 도출 해 낼 수 있다.

이 문제를 위 식을 생각하지 않고 배열안에 모든 수를 일일이 옮기려 하면, 시간과 코드가 길어지게 된다.
앞으로 위와 같은 문제 유형을 맞닥트렸을 때 위 식을 잘 생각해 내어 빠른 시간안에 문제를 해결해야겠다고 생각했다.

https://www.acmicpc.net/problem/21868

 

21868번: 미적분학 입문하기

첫 번째 줄에는 양수 $\epsilon$을 분수로 표현했을 때의 분자와 분모가 공백으로 구분되어 주어진다. 각 분자와 분모는 $1$ 이상 $10\,000$ 이하의 자연수다. 두 번째 줄에는 일차 이하의 다항함수 $f

www.acmicpc.net


문제해석


단순하게 문제 속 수학식을 살펴보고 입력받은 값으로 계산하여 출력하여 주면 되는 문제이다.
알고리즘 기술과 관련된 지식이 필요하다기 보다는 정말 수학문제를 풀줄 알면 사람이면 누구나 이 문제를 해결할 수 있다.


코드


#include<iostream>
#include<algorithm>
#include<vector>
#include<cstring>
#include <tuple>
#include <string>
#include <queue>
using namespace std;
int eh, el;
int a, b;
int x0;



int main() {
	ios::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);

	cin >> eh >> el;
	cin >> a >> b;
	cin >> x0;
	cout << a * x0 + b <<'\n';
	int hh = eh, ll = el * a;
	if (!hh || !ll) {
		cout << "0 0" << '\n';
	}
	cout << abs(hh) <<' ' << abs(ll) << '\n';
    
    return 0;
}

문제풀이


먼저 극한값을 구하는건 간단하게 해결할 수 있다. x가 x0에 가까워질때의 극한값이므로 a*x0+b를 해주면 쉽게 구할 수 있다.
그 후 델타값을 구하는건 수학적 지식이 필요한데, 델타는 입실론을 a로 나눈 값이다. 따라서 분자인 hh는 그대로 유지해주고 분모인 ll는 a를 곱해줘야한다. (그래야지 a로 나누는게 됨.)
그런 후 c++ 절댓값 라이브러리 abs() 함수를 사용하여 출력만 해주면 문제를 해결 할 수 있다.
정말 수학 문제 그자체. 아무래도 신입생들을 위한 알고리즘 문제이다보니 이런 수학 유형을 많이 내지 않았을까 싶다.

 

 

이번 연습은 3명이서 9문제중 7문제를 풀었다. 마지막에 시간이 좀 더 있었으면 F번을 풀을 수 있었을 거 같은데 아쉬웠다. 나는 오히려 이런 수학공식을 해결하여 문제를 푸는게 좀 더 나한텐 익숙하다. 알고리즘 문제를 많이 풀었기 보단 수학 공부한 기억이 더 많이 남아서가 아닐까 생각한다. 다른 팀원들은 수학 문제에 오히려 약하다고 하니 내가 수학문제가 나오면 맞추려고 노력해야겠다.

프로젝트 진행 중,
어떤 목록들을 선택하고 그 목록들을 한 화면에서 나타내어줘야하는 상황에서,
내가 선택한 목록들이 많을 경우에 한 화면에 모든 목록들을 나열하기엔 UI적인 면에서 좋지 않다고 판단되었다.
그래서 해결 방법을 찾던 도중 팀원에게 carousel을 사용해보는건 어떠냐 라는 이야기를 들었고,
여러 자료들을 참고하여 carousel을 구현해 보았다.

먼저 캐러셸을 만들 수 있는 방법은 다양하다.
1. 라이브러리를 활용한다.

- React-Slick

- React-Material-Ui-Carousel

- React Responsive Carousel

 

2. Reat-Hook 을 사용해 직접 구현한다.

 

나는 현재 React를 공부하고 있는 사람이고, 아직 초보자이기 때문에, React 라이브러리를 활용하는것도 좋지만, 직접 로직을 이해하며 코드를 짜보는것이 좋겠다고 판단되었다.

그래서 2번 방법을 택하였고, React Hook과 프로젝트에서 활용하고 있는 css 라이브러리 styled component 를 활용하여 제작해보았다.

 

 

그럼 먼저 carousel에 구조에 대해서 살펴보도록 하겠다.

기술 선택 목록 - carousel 구조 설명

허접한 내 그림 실력에 큰 아량을 베풀어 주길 바라며..

위 사진에서 검은색으로 표시된 부분이 바로 기술을 표현할 전체 Container라고 보면 되고,
초록색 부분이 실제 기술들이 보여지는 부분,

그리고 핑크색 부분이 선택한 기술들이 담겨져 있는 Container라고 보면 된다.

 

나는 양 끝에 있는 화살표 버튼을 눌렀을 경우 뒤에 남겨져 있는 기술들이 보여지길 바랬고, 화살표에 어떠한 onClick 이벤트를 주어야겠다고 생각했다.

 // 현재 슬라이드를 나타내는 useState
  const [currentSlide, setCurrentSlide] = useState(0);
// 초록색 부분에서 보여지는 목록 개수
  const viewingSkill = 4;
  // 현재 슬라이드를 제외한 Slide 개수 (skillsImg는 임의로 만들어준 mock data(선택 항목)이다.)
  const TOTAL_SLIDES = skillsImg.length / viewingSkill - 1;
 // 첫번째 슬라이드
  const firstSlide = 0;
  const handleClickNextSlide = () => {
    if (currentSlide >= TOTAL_SLIDES) { // 더이상 이동할 슬라이드가 없다면
      setCurrentSlide(firstSlide); // 첫번째 슬라이드로 이동. ->useState 활용
    } else {
      setCurrentSlide(currentSlide + 1); // 아니라면 다음 슬라이드로 이동.->useState 활용 
    }
  };
  const handleClickPrevSlide = () => {
    if (currentSlide === firstSlide) { // 이전버튼을 눌렀는데, 첫번째 슬라이드라면
      setCurrentSlide(TOTAL_SLIDES); // 마지막 슬라이드로 이동 ->useState 활용
    } else {
      setCurrentSlide(currentSlide - 1); // 아니라면 전 슬라이드로 이동 ->useState 활용
    }
  };

그렇게 버튼 이벤트가 발생했을 시 실행시키기 위해 작성한 코드가 바로 윗 코드이다.

자세한 설명은 주석으로 작성해 주었다.

이렇게 해준 뒤, 내가 선택한 목록들을 보여주기 위해 어떠한 특정 DOM을 선택해주는 useRef또한 사용해줘야했다.

 const slideRef = useRef(null); // slideRef라는 객체 useRef를 활용하여 생성.
  
  useEffect(() => { // useEffect를 활용하여 
    slideRef.current.style.transition = 'all 0.5s ease-in-out'; // 어느 슬라이드를 보여주고 있는지 지정함.
    slideRef.current.style.transform = `translateX(-${currentSlide}00%)`; // 가로 슬라이드이기 때문에 translateX를 활용하였다.
  }, [currentSlide]);

translateX 을 활용하여 가로로 핑크색 항목들이 이동할 수 있게 했고, 위와 같이 useRef와 useEffect를 활용하여 이동하는 활동을 주었다.

그런 후 , return 부분을 보면

<S.SkillBoard> //  검은색 전체 Container부분
  <S.LeftAngle onClick={handleClickPrevSlide} />
    <S.SkillContainer> // 초록색 선택 목록이 보여지는 부분
       <S.SkillSlide ref={slideRef}> // 선택한 항목이 담겨있는 핑크색 Container
           {skillsImg.map(({ imageUrl, id }) => ( // 내가 선택한 목록들을 임시로 만들어둔 mock data
             <S.SkillImage key={id} src={imageUrl} /> // 선택 목록에 대한 이미지
           ))}
        </S.SkillSlide>
   </S.SkillContainer>
  <S.RightAngle onClick={handleClickNextSlide} />
</S.SkillBoard>

위와 같이 작성 했다.
검은색 SkillBoard로 감싸주고,
초록색 SkillContainer에서는 overflow:hidden; 이라는 css 속성을 주어 범위가 넘어갔을 시 보여지지 않게 했다.
핑크색 SkillSlide에서는 mock data인 skillsImg라는 데이터를 담을 수 있게 범위를 목록에 맞춰 설정해주었고,
.map 을 사용하여 배열에 있는 값을 가지고 올 수 있게 했다.
또한 각각 옆으로 이동하는 버튼에 대해서는 이미지로 불러온 다음, onClick시 아까 만든 함수들이 실행 될 수 있도록 했다.

styled-components 에 대해서도 살펴보자.

// * : 이동 버튼 포함 검은색Container
export const SkillBoard = styled.div`
  position: relative;
  display: flex;
  justify-content: space-between;
  align-items: center;

  height: 20%;
  width: 100%;
  padding: 5px 0px; // height, width, padding은 적절하게 조절하기 !!
`;
// 초록색 Container
export const SkillContainer = styled.div`
  position: relative;
  display: flex;
  align-items: center;

  height: 100%;
  width: 100%;
  overflow: hidden; // 넘어가는 부분은 안보이게 해주었다.
`;
// 핑크색 Container 
export const SkillSlide = styled.div`
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;

  height: 100%;
  width: 100%;
  gap: 12px; // 각 목록들 사이의 간격 조정. 이것 또한 객체화 해주는게 좋음.
`;
// 선택 항목 Img 크기 지정
export const SkillImage = styled.img`
  object-fit: cover;
  width: 52px;
  height: 52px;
  border-radius: 50%; // 위 그림에서와 같이 동그란 형태로 표현
  box-shadow: 1px 1px 1px 1px #cdcdcd; // 옅은 회색으로 그림자 효과 줌.
`;


// LeftAngle과 RightAngle에 관한 부분은 이미지를 선언 한 후 그 이미지에 대한 적절한 크기 값을 적용해주면 된다.

초록색에서는 overflow:hidden이 포인트이고, 핑크색에서는 gap이 포인트 인거 같다. 물론 gap을 활용 안해도 되지만, 초반에 array mock data를 불러왔을 때 나는 항목들의 이미지가 너무 붙어있어서 어찌 해야하나 고민을 많이 한 거 같다.

처음 css를 다뤄보다보니 모르는 부분이 많았지만, 점점 익숙해지고 재미가 있다고 느껴서 앞으로 꾸준히 학습하며 실력을 늘려봐야겠다.

 

이렇게 위와 같은 방법으로 코드를 작성하면 손쉽게 라이브러리를 사용하지 않고도 carousel을 구현 할 수 있다 !


추가로...

코드를 공부하면서 짜다 보니, 아무래도 변수명을 내 마음대로 작성한 경향이 있었다.
(다른 팀원이 알아보기 어렵고, 숫자들에 대하여 객체화 시켜 네이밍 처리를 해주지 않으니 리펙토링에도 어려웠다.)
추후 pr을 날리고 code review를 받을때 네이밍에 관한 부분에 대한 review를 받았다. 관련 내용을 읽어보고 난 후 네이밍 관련 부분을 수정하였고, 추후 네이밍에 관한 부분도 블로그에 작성해주면 좋을 거 같다고 생각했다. 코드짜는거와 별개로 네이밍도 항상 고민이 많은 거 같다. 익숙해지기 위해선 관련 자료들도 찾아보고 공부한 후 많이 해봐야할 거 같다는 생각이 들었다.

 

 

 

 

이번 프로젝트에서 css도 처음 다뤄보고 styled-components도 계속 활용 해보고 있는데, 초반에 배우는 과정 중에서 팀원에게 많이 피해를 준거 같아 너무 미안한 마음이 크게 들었다.

하지만 지금은 열심히 공부하여 익숙해진 상태이고, css 는 앞으로 계속해서 접해보면 익숙해지지 않을까 싶다.
storybook 도 이번기회에 사용해 보았는데, 이 또한 많이 익숙해진 상태이다. 익숙해졌지만 완벽하진 않으니 앞으로 많이 사용해보고 익히며 부족한 실력을 길러야 겠다. (필요하다면 styled-components와 css 그리고 storybook에 대해서도 정리해보자!)






참고 자료

peppermint100.log-[JS]React Hooks로 Carousel Slider 만들기

1004walnut - [React] useState, useEffect, useRef을 이용하여 캐러셀 슬라이더 구현하기

 

+ Recent posts