들어가며

갑자기 글을 쓰고 싶어졌다.
면접을 앞두고 내가 개발자로서 성장했던 시기를 생각해보는데, 매 순간 도전을 하고 그 도전에서 좋은 사람들을 만나서 성장했던 것이 큰 것 같다.
그리고 가장 최근에 했던 활동이 Mews 프로젝트나 React 튜터링도 있지만 그래도 이전부터 하고 싶었던 활동인 NEXTERS를 합격하고
활동하면서 기억에 남는 것이 많아 작성해보려고 한다.
(사실 23기 활동 메일 날라와서 생각나서 쓴다 ㅎㅎㅎ..)

지원

사실 지원하면서도 긴가민가 했다. 지원을 한다는 것에는 확신이 있었다. 그만큼 하고 싶었던 활동이니까.
원래 지난 21기에 백엔드 파트로 지원하면서 서류 전형에서 떨어졌기 때문에 그런 점도 있었던 것 같다.
그래서 지원서에는 개발하는 과정에서 얻은 즐거움이나 열정을 담아쓰려고 노력했던 것 같다.

나는 절대 잘하는 사람은 아니였던 것 같다. 그러나 그렇기에 매 순간 학습하려고 노력했고 이러한 점을 담아 쓰려고 했다.
왜 개발을 시작했는지, 내가 개발을 어떠한 마음가짐으로 임하는지, 그리고 매 순간 학습을 한다는 것은 어떠한 생각인지를 담으려고 했다.

면접 준비

처음 서류 전형의 결과가 나왔을 때 많이 놀랬던 것 같다.
그래도 나의 진심이 닿았구나..? 하는 그런 뿌듯함도 있었던 것 같다.
면접을 준비하면서는 되게 다양한 것들을 공부하기보다는 지난 시간의 나의 활동을 되돌아보았다.

지원서에 쓰인 내용 대부분이 부스트캠프 활동이었는데, 부스트캠프 과정에서 했던 고민들과 선택의 근거 등을 다시한번 정리했다.
그리고 그 때 가장 신경을 많이 썼던, 그리고 아직까지도 신경을 쓰면서 개발하고 있는 '웹 접근성'이라는 키워드를 상기하면서 정리했다.

면접

사실 면접 경험은 굉장히 좋았다.
많은 운영진 분들이 면접자를 많이 배려해주시고 편안한 분위기에서 진행하려고 많은 노력을 해주셔서인 것 같다.
다만 내가 많이 떨었다 ㅎㅎ..

면접 질문은 평이했지만, 지원서를 기반으로 진정성이 있는지를 많이 보신 것 같다.
나는 웹 접근성에 대한 이야기를 자소서에 담아내려고 많이 노력했다. 그 이유는 가장 관심이 컸기 때문이다... 너무 당연한가...

그렇기 때문에 웹 접근성에 대한 질문을 받았다.
웹 접근성을 고려하는 개발을 하려면 구체적으로 어떠한 식으로 개발을 해야하는지에 관한 질문이었던 것 같다.
지금에야 개발을 하면서 많이 적용하려는 노력 덕에 어느정도 체화된게 있지만, 과거에는 '이론적으로 적용해야겠다..!'여서
대답을 할 때 어버버하면서 "alt 태그에는... ', '유저는 키보드로만 조작을...' 이런식으로 대답했던 기억이 난다.

그리고 네트워킹 시간이 많은데 개발자 분들을 만나며 어떠한 내용의 네트워킹을 하고 싶은지에 대한 질문을 받았었다.
거기서 나는 너무나도 대학생 그리고 개발자 준비생 같은 대답을 했다.
'저는 개발자로서 ~~한 가치를 가지고 개발하고 있다. 다만 이 질문을 다른 개발자 분들께 했을 때 어떠한 답변을 하실지가 궁금하다.'
'학생의 마인드가 아닌 현업 개발자들은 어떠한 가치를 가지고 개발하며, 어떠한 점들을 고려하는지를 묻고싶다.'
같은 뭔가 순수한..? 대답을 했던 것 같다.

그리고 마지막에 넥스터즈에서 무엇을 얻어가고 싶냐는 질문에서
'대학 생활로서의 마지막 개발, 그리고 사회인으로서의 개발 시작의 첫 페이지를 넥스터즈와 함께하고 싶다'
라는 흠... 역시 논술 대입 출신 다운 말을 했다.

그래서 면접 경험은 너무나도 좋았지만 스스로의 대답은 조금 아쉬웠고 심기일전하여 다음기수를 노려보자..!라는 야심찬 계획과 함께
사실 다른 연합동아리에 지원을 할까 고민하고 있었다...ㅎ.ㅎ..

합격

그래서 사실 떨어질 줄 알았다.
왜냐하면 나 스스로도 아쉽고, 사실 옆에 있는 분이 너무 말씀을 잘하셔서...

근데 붙었다. 그리고 붙고 나서는 내가 부족하다는 생각은 안하기로 했다.
그것이 뽑아 주신 분들에 대한 예의라고 생각했고, 모자라다면 맞춰가면 된다고 느꼈다.

하여튼 좋은 결과를 얻었고, 넥스터즈 활동하면서 1등도 하고 정말 좋은 분들 사이에서 개발자로서의 마인드와 배움을 얻었다.
더불어 정말 많은 좋은 사람을 만나서 다음 23기도 기다려진다.

이런 구체적인 이야기는 다음에 계속 ㅎㅎ..

들어가며

하단 네비게이션바를 작업하면서 페이지를 전환과 현재 페이지 상태를 불러오는 기능이 필요했습니다.

이에 대한 방안으로

  1. window.location.href를 파싱하여 문자열로 상태를 받고, 해당 문자열에 따라 state를 설정하고 이에 맞는 style을 부여한다.
  2. onClick 이벤트를 사용하여 라우팅과 색 입히는 것을 동시

이 두가지 방법이 떠올랐고, 실행에 옮기고자 하였으나 여러가지 의문이 들었습니다.

window.location.href 파싱

url문자열을 받아오고 파싱을 하는 방법은 가장 떠올리기 쉽고, 직관적인 해결방법입니다. 눈에 보이는 요소를 통해 처리를 하기 때문에 그렇게 생각했던 것 같습니다.

그러나 몇가지 의문이 드는 점 또한 존재했습니다.

  1. 이전에 query string을 사용 할 때, 문자열 파싱을 이용했는데, 찾아보니 urlSearchParams ~ 속성을 활용하여 파싱하는 것을 학습했고, 이처럼 편한 방법으로 현재 주소 상태를 가져오는 방법이 있을 것 같다.
  2. 파싱을 하게되면 ‘/’기준으로 파싱을 할 것이다. 지금이야 프로덕트의 depth가 얕아서 ‘/’가 하나지만 추후 여러가지 depth가 생길 수 있음을 고려해야된다.

와 같은 고민을 하게 되었습니다.

이에 두번째 방식인 onClick 이벤트를 사용에 대해서 고민했습니다.

Onclick 이벤트 부여

선택에 대한 근거는 다음과 같았습니다.

어차피 Navbar에서 클릭을 통해 페이지가 전환되야하고, 전환되는 이벤트를 줄 때 같이 style을 부여하는 이벤트만 추가하게되면 해결되는 문제 아닌가? 라는 생각과 함께 진행을 했습니다.

여기서도 추가적인 고민을 했던 것이

  1. Onclick으로 이벤트를 부여하고 색을 입히면 페이지가 전환될 때 이전에 부여됐던 컴포넌트의 색 클래스를 제거해주는 로직이 필요하지 않나? ex) A화면 : A아이콘(파란색), B아이콘(회색) → B화면: A아이콘(클래스 제거 → 회색) B아이콘(이벤트 추가 → 파란색) 이 과정이 불필요하다고 느껴졌고, 코드가 필요 이상으로 길어질 수 있겠다고 생각했습니다.
  2. 만일 현재 띄워져있는 페이지를 받는 상태를 이용해서 onclick을 사용한다면, 그래도 state를 써야하므로 이 상태 없이 가능할 수 있지 않을까?
  • 사실 코드 안에 다량의 if문과 다량의 state를 쓰기 싫었습니다.

NavLink

결국 NavigationBar의 본질은 라우팅이라고 생각했고, 라우팅에 관련된 글을 읽어보다가 NavLink에 대해서 발견했습니다.

NavLink v6.4.3

NavLink가 뭔데요?

<NavLink> is a special kind of <Link> that knows whether or not it is "active".
This is useful when building a navigation menu such as a breadcrumb or 
a set of tabs where you'd like to show which of them is currently selected. 
It also provides useful context for assistive technology like screen readers.'
  • ‘활성화’ 여부를 제공하는 Link의 종류이고, 현재 선택을 보여줘야하는 navigation menu를 만드는데 유용하다. 또한 여러가지 유용한 컨텍스트를 제공한다.

NavLink를 왜 사용했는가?

만일 onclick, link를 사용하여 작업을 하는 경우, 현재의 URL과 이동할 URL을 비교하여 클래스를 추가 혹은 삭제를 해주는 불필요한 로직이 생기게됨.

const prevPath = useLocation();

return (
	<Link
		to={path}
		className={classNames("foo", {
		isActive: path === prevPath
		})}
	>
);

But

NavLink를 사용하면 별도의 처리 로직 없이 isActive 속성을 활용하여 현재 활성화 되어있는지에 대한 여부를 받고, 이에 따른 처리만 해주면 됨.

과 같은 근거로 사용을 했습니다.

실제로 작성한 코드에서 해당 부분에 대한 처리는 다음과 같았습니다.

<NavLink to=path className={({ isActive }) => (isActive ? "foo" : "")}>

언뜻 별 차이가 없어보이고, 결국 isActive 상태 받아서 삼항연산 처리 했을 뿐, 위의 코드와 다를게 없지 않나..?라고 생각이 들기도하지만, 불필요한 prevPath 상태제거와, 직접 비교하는 연산을 제거해서 코드를 간결하게 했다는 점이 긍정적인 요소라고 생각합니다.

  • 가장 큰 장점은 한번 설정함으로써 개발자가 불필요하게 현재 경로와 Link에서 사용하는 경로에 대해서 계속해서 신경쓰지 않아도 된다는 점 같습니다.

'Project > Fitory' 카테고리의 다른 글

Fitory - Fitory 검색페이지 개발 기록 & 성능 개선기  (0) 2022.12.29

들어가며

2022년은 참으로 의미가 깊고 쉽지 않은 한 해였다.
새로운 도전과 실패, 그리고 나름대로의 성공까지 모두 겪어볼 수 있었던 신기한해였으며,
참 많은 것이 변화했고 나의 방향에 대해서 갈피를 잡을 수 있었던 한 해라고 생각한다.

문닫고 들어가는 사람.

나는 항상 나를 표현할 때 복이 많은 사람, 문을 닫고 들어가는 사람이라고 말하곤 한다.
이 말인 즉슨, 나는 항상 어느 무리의 마지막에 걸쳐서 아슬하게 속할 수 있는 사람이라고 생각한다.

 

고등학교 시절 나는 그렇게 공부를 잘하는 학생은 아니였던 것으로 기억한다.
그냥 보통의 성적과 보통의 노력을 하고 그런저런 성적에 분해하지만 또 얼마 안가서 그 성적을 웃어넘길 수 있는 보통의 사람인 것 같았다.
그럼에도 욕심은 많아서 항상 더 높은 곳을 보고 내가 눈 닿아 있는 곳보다는 조금 더 너머의 위치를 바라본 것 같다.

 

대학을 고를 때도 마찬가지였다. 예전부터 나는 서울로 대학을 다녀보고 싶다는 생각이 컸다.
그러나 '그 수준의 사람들만큼 노력을 했는가?'에 대한 대답을 하라면 어렵기만 하다.
욕심이 많은 나는 목표를 이루기 위해 많은 사람들이 말렸던, 안될거라 했던 논술전형을 쓰고 운이 좋게 서울에 있는 학교에 입학했다.
입학한 당시, 그리고 몇개월이 지난 후에도 나는 이 학교에 다니는 것이 안믿겨져서 학교 강의실 단상 앞에 있는 학교로고가 어색했던 것이 꽤나 오래 지속됐던 것으로 기억한다.

 

그 다음은 부스트캠프였던 것 같다. 부스트캠프에 지원할 당시, 나는 개발을 공부하기 시작한 1년이 조금 넘은 경영대생이었다.
또 작년 초, 1월부터는 무슨 바람이 불었는지 개발을 시작했던 '프론트엔드보단 백엔드가 더 재밌어보인다.'라는 이유로
백엔드를 공부하겠다고 스프링강의를 몽땅 끊어가며 무지성으로 강의를 들으며 코드를 따라쳤던 기억이 난다.
그렇게 시간을 보내다가 부스트캠프 지원 공고를 보았다. 그리고 지원을 하면서도 당연히 떨어질 것이라고 생각했다.
그리고 1차, 2차 테스트를 보면서도 많이 모자람을 느끼고 앞으로 공부를 어떻게 해야할지 방향을 잡고 있었고,
챌린지 때도 많이 모자람을 느꼈지만 운이 좋게 나를 좋게 봐주셔서 멤버십 과정까지 갈 수 있었다.

챌린지 때도 참 많은 것을 느꼈지만 해당글은 링크로 대체하려고 한다.

부스트캠프를 하면서 정말 뛰어난 분들도 많이 만났고, 사실 '내가 제일 모자라다'라는 생각을 많이 했던 것 같다.
그렇기에 항상 내가 문을 닫고 들어온 사람이라고 생각했던 것 같다.

 

최근에는 넥스터즈라는 활동에 프론트엔드 개발로 함께할 수 있게 되었다.
개발을 시작할 때 모집공고를 본 20기, 21기부터 정말 해보고 싶었던 활동이었는데 이번 22기 모집에 지원을 했다.
준비를 하면서는 나름 열심히 준비한다고 생각했었다. 그러나 면접을 보면서 너무 긴장했던 탓인지 횡설수설하는 경우가 많았고, 원래는 대답할 수 있었던 부분도 많이 놓쳤던 것 같다.
실제로 자신있는 부분에 대한 질문을 받았는데도 잘 표현하고 싶은 마음에 이것저것 말하다가 본래의 질문의 의도와 멀어진 대답까지 이어진 경우도 많았던 것 같다. 그럼에도 어떠한 가능성을 봐주신 덕분인지 함께 할 수 있었고, 제 생각에는 이번에도 운이 좋게 문을 닫고 들어갔다고 생각하고 있다.

도전과 치열함

내가 위에서 '문을 닫고 들어가는 사람'이라고 말하긴 했지만, 사실 너무 운에 치부하기에는 저는 다 선발된 입장이고, 뽑아 주신 분들이 봐주신 것이 있기에 뽑아주신 분들에 대한 예의도 아닌 것 같아 제가 생각하기에 올해 살았던 스탠스와 내가 할 수 있었던 것에 대해서 회고를 남겨보자한다.

 

나의 올해는 도전과 치열함의 연속이었던 것 같다.

나는 항상 도전을 하는 사람이었다. 이건 올해 뿐만이 아닌, 매 순간이었던 것 같다. 기회는 도전을 해야 시작되는 것이고, 도전에 실패할 때마다 앞으로 내가 나아갈 방향이 명확해진다고 생각하기 때문이다. 올해도 역시 크게 부스트캠프와 넥스터즈에 도전을 했고, 좋은 기회를 받을 수 있었다.

 

그리고 그 과정에서 항상 치열했던 것 같다. 도전을 많이 한다고 그 기회가 소중하지 않은 것은 아니였다. 특히 부스트캠프의 챌린지 기간은 내 인생에서 가장 치열한 기간을 꼽으라면 이 시기가 꼽힐 정도였던 것 같다. 이 역시 링크로 대체하겠다.. 진짜 치열했다.. ㅎㅎㅎ..

그렇게 치열했기 때문에 나는 닿기 힘든 부분에 있어서는 놓쳤을지 모르더라도, 닿을 듯 말듯한 기회는 잡아낼 수 있었던 것 같다.

 

그리고 또한 '문을 닫고 들어간다.'라고 생각하는 것이 마냥 부정적으로 생각하는 것은 아니였다. 나는 항상 저렇게 생각했기에 더욱 노력했어야 됐고, 더 치열해야했다. 같이 하는 사람들이 너무 대단하고 좋은 사람들이었기에, 이들과 계속해서 함께가려면, 그리고 긍정적인 효과를 내기 위해서 더 치열하고 열정적으로 활동에 임했고, 그 결과 많이 성장할 수 있었던 것 같다.

포기

올해는 도전을 하고 성공도 했던 만큼 어느정도 포기도 했다. 이전에는 기획자의 꿈을 가지고 기획 공부도 병행했고, 상반기에는 개발자로 아직 준비가 되지 않았다고 생각하여 기획과 경영 직무로 많은 곳을 지원했고 IT 서비스 기업 중 원하던 기업의 최종면접까지 갈 수 있었다.

 

그러나 최종에서 약간은 아쉬운 결과를 받았고, 그 이후 도전했던 부스트캠프를 합격하면서, 조금 더 기획에 대한 꿈을 확신할 수 있었다. 그리고 그와 동시에 기획의 길을 포기하게 되었다.

정리하며

올해는 참 많은 것을 얻고, 포기하고, 배웠다. 길지 않은 인생을 살았지만, 그래도 가장 인상 깊었던, 농도가 진했던 시기를 꼽으라면 나는 단연코 2022년을 꼽을 것 같다.

 

기획과 프론트, 백엔드 사이에서 고민하던 1분기를 지나, 기획의 꿈을 향해 걸어가고 포기했던 2분기, 가장 치열하고 새로운 꿈을 향해 달렸던 3분기, 그리고 앞으로의 나를 준비해나가는 4분기까지.

 

매 순간 태우고 빛났던 이 시기를 기억하며, 언젠가 길을 잃을 때 과거의 가장 밝게 타는 2022년의 불을 보고 다시 돌아와 다시끔 이겨내고 앞으로 달릴 수 있을 것 같다.

들어가며

사실 수료를 한지 약 이주의 시간이 되었고, 후기가 굉장히 늦게 쓰는편이라 감정이 온전하진 않지만,
한자 한자 기억을 살리면서 적어보려고 한다.

돌이켜보면 아무것도 모르는 상태로 들어가 그래도 이제는 무엇을 해결할 수 있는 개발자가 된 것 같아
지난 시간이 행복했던 시간이라고 생각된다.

학습 방법에 대한 이해

결과적으로 8주를 마치고 나니 스스로 효율적으로 학습하는 방법에 대해서 학습하게 되었다.

부스트 캠프에서는 바텀업 방식으로 기본적인 원리를 이해하고 이해를 바탕으로 더 효율적인 라이브러리가 있다!
그러니까 이런 원리로 작동하는데, 이걸 편하게 쓰려면 이걸 사용하자!
정도의 흐름으로 바텀업 방식의 학습을 했던 것 같은데, 이 방식이 솔직히 잘 맞는지는 않았던 것 같다.

기본에 대해서 학습할 때, 이것이 무엇을 위한건지에 대해서 이해하기 어려웠던 것 같고,
세세한 부분들을 모두 구현해야하다보니 되려 이해하기 더 어려웠던 것 같다.

후에 스프린트를 다 마치고 나니 나는 탑다운 방식의 학습 방법이 맞다는 결론에 이르었다.

8주동안 가장 깊게 학습했던 웹 프론트엔드 분야에서 리액트를 학습할 때는 래퍼런스도 많고, 공식문서도 잘 나와 있기 때문에
리액트 자체를 학습하는데는 어렵지 않았다.

그리고 오히려 학습 스프린트를 마치고 다시 첫주차, 두번째 주차의 코드를 봤을 때 비로소 보이는 것들이 많았다.
기본이 부족했기 때문에, 웹에서 프론트엔드는 어떠한 역할을하고, 어떻게 작동을 하고 이를 세세하게, 바닐라 자바스크립트로
작성하기 위해서는 어떻게 해야하는지.

이 순서로 학습하는 탑 다운 방식의 방법이 나에게 효율적이라는 것을 깨달았다.

8주간, 솔직히 비약적으로 많이 늘었다. 라고는 말하기 힘들었지만 학습 방식을 알았고, 이를 바탕으로
후에 이어질 그룹프로젝트에서의 효율적인 학습을 할 수 있었기에 학습 방법을 알아간 점만으로도 충분하다고 생각한다.

코드리뷰

먼저 코드 리뷰가 도움이 많이 됐고 많이 늘었던 것 같다.

이는 부스트캠프의 챌린지부터 성장되었던 역량인 것 같다.

항상 내가 생각하는 것은 코드를 작성하는 것은 한편의 글을 작성하는 것과 같다고 생각하며
각자의 코드마다 글쓰기 습관처럼 각자의 성향이 뭍어나온다고 생각을한다.

책을 읽을 때도 독특한 방식으로 책을 쓰거나, 어려운 문체가 사용되면 읽기 어려운 경우도 많다.
예를 들어 내가 처음 베르나르 베르베르의 책을 접할 때, '신'이라는 책으로 처음 접했는데,
이때 책의 전개 방식과 자주 변경되는 시점으로 인해 읽기 어려워했던 기억이 난다.

이와 마찬가지로, 코드를 작성할 때도 개인의 성향이 많이 묻어 나온다.
추상화를 하는 기준도 다르고, 컴포넌트를 분리할 때도 최대한 작게 혹은 역할과 관심사에 따른 분리, 또는 상태에 따른 분리 등
다양한 방법으로 설계하고 작성한다.

차이점은 책은 상대적으로 타인의 문체를 접하기가 쉽지만 코드는 상대적으로 어렵다는 점에 있다.
그리고 더욱이 상대방이 코드를 썼던 논리와 이유를 듣는 기회는 흔치 않다.

하지만 부스트캠프에서 하는 코드리뷰에서는 이러한 기회가 많이 생겼다.
매주 3명의 동료들을 계속해서 바꿔가며 만나면서 다양한 코드를 접했고,
리뷰하면서 좋은 점을 배우고 모르는 점을 질문을 할 수 있었다.

해당 기회를 통해 많은 좋은 점을 배웠고, 이전에는 백지 상태였던 나였기에
지금의 코드에는 내가 배우고자했던, 철학이 확실했고 공감했던 분들의 코드가
나의 방식으로 재해석되어 작성되어 있는 것 같다.

더불어 타인의 코드를 보면서 이해하기 위해 모르는 부분을 더 섬세하게 공부하고,
이해하려고 했던 노력으로 인해 얻었던 성장은 정말 큰 도움이 되었던 것 같다.

공식문서

학습을 하면서 정말 많은 래퍼런스를 보았다.
특히 블로그를 많이 본 것 같은데, Nest를 학습할 때는 블로그를 많이 찾아봐도
내가 원하는 내용이 없을 때도 있었고 버전이 자주바뀌는 라이브러리의 경우는 나의 버전과 달라서 적용이 되지 않는 경우도 있었다.

그렇기 때문에 공식문서를 찾아보기 시작했고, 실제로 도움이 많이 된 것 같다.

부스트캠프를 하면서 처음에 공식문서를 보는 것이 도움이 된다는 말을 많이 들었다.
공식문서에서 해당 라이브러리, 프레임워크의 철학과 가장 정확한 사용 방법을 알 수 있다는 내용이었다.

처음에는 읽기 힘든 공식문서보다는 간단하게, 그리고 읽기 좋게 쓰인 블로그를 선호했다.

사용된 예시도 많았고, 솔직히 코드를 가져다 쓰면 되는 경우도 많았기 때문이다.

하지만 이번 계기를 통해 공식문서를 보는 습관을 가지게 되었고,
공식문서를 보면서 기초를 학습하고, 이를 활용하는 방법에 대해 고민하면서 더 깊은 학습을 할 수 있게 되었다.

솔직히 아직까지 프레임워크에 대한 철학을 알아가는 기쁨은 발견하지 못했지만,
이러한 학습 방식을 계속하여 나아가다보면 나도 그런 기쁨을 알지 않을까.. 하면서 학습을 계속해서 해보고자 한다.

마치며

참 많은 것들을 배웠지만 작성하고 나니 짧은 글이라 아쉬움이 남는 것 같다.
회고를 조금 미리미리 써볼 걸 그랬다..

하여튼 이번 기회는 내가 개발자라는 길에 대한 확신을 가지게 된 계기였으며,
가장 밀도 높은 5개월이었다고 생각한다.

비록 부스트캠프는 끝났지만, 여기서 배웠던 많은 분들의 태도와 자세,
그리고 학습 방식은 앞으로의 개발을 함에 있어서도 계속될 것이다.

그리고 '지속 가능한 개발자'라는 키워드를 끊임 없이 고민하며
계속하여 나아가고 있지 않을까 싶다.

들어가며

안녕하세요 🙂

저는 이번 프로젝트 기간 동안 진행했던 다양한 기능 중 검색페이지에 대한 경험을 작성해보고자 합니다.

이 글은 검색페이지를 구현하면서 진행했던 고민의 흐름과 개선의 흔적을 담았습니다.

검색페이지 기능

  • 키워드를 입력하면 유저 리스트에 있는 정보를 기반으로 자동완성이 된다.
  • 검색 결과로 나타난 프로필을 누르면 해당 유저의 프로필로 이동한다.

searchGif

검색 키워트 이벤트 개선기

초기 기획

Keyword 자동완성, 유저리스트

구현 과정에서 관점

모든 유저 리스트를 한번에 받아와서 받아온 후 그 유저 리스트를 기반으로 검색해서 띄워주자

  • 실 사용 유저가 많지 않을 것이라고 예상되니까 한번에 받아오는데 오랜 시간이 걸리지 않는다.
  • 자동완성을 통해 검색어가 바뀔 때마다 API 호출이 일어나게 되면 너무 빈번하게 일어난다.
  • API 호출도 결국 비용인데, 너무 빈번하게 일어나는거 아닌가.
  • 검색 자동완성은 빈번하게 일어나는 이벤트인데, 이벤트 발생시마다 api 호출을 하면

    응답 대기 시간이 발생하고, 그 대기 시간이 너무 빈번하게 발생한다.

그래서 결국 초기에는 모든 유저 리스트를 한번에 받아와서 그 리스트를 필터링하기로 하였습니다.

검색 자동완성 ver 1

console.log('너무 오래전에 작성한 코드라 코드가 남아있지 않습니다 😅')

Keyword.

Throttling : 이벤트를 일정한 주기마다 발생시키기.

쓰로틀링으로 구현을 한 이유는 단순했습니다.

“일정 기간마다 이벤트를 발생시키면 일정 기간마다 자동 완성이 되므로
유저가 더 편하게 사용할 수 있겠지?”

이에 대한 근거는 다음과 같았습니다.

siun을 칠 때 한 글자에 500ms가 걸린다고 가정, 쓰로틀링 간격 또한 500ms이라고 가정하겠습니다.

→ s에서 한번, i에서 한번, u에서 한번, n에서 한번,

즉, 타이핑마다 글자마다 자동완성을 해주면 유저가 원하는 키워드를 더 편하게 찾을수 있을 것이라고 생각했습니다.

BUT.

팀원들과 의견을 공유한 결과 나온 의견은 다음과 같습니다.

“불필요한 요청이 너무 많이 발생한다.”

“검색에 모르는 사람을 찾으려고 글자를 하나하나 치는 사람보다는 키워드를 정해놓고 치는 사람이 많을 것이다.”

이에 대한 의견을 바탕으로 개선을 시작했습니다.

검색 자동완성 ver2

// 모든 유저의 리스트를 가져옴.
const { allUserList } = useAllUserList();

// 검색 결과로 나온 유저가 담긴 배열.
const [searchValue, setSearchValue] = useState<string>("");
const [searchedUser, setSearchedUser] = useState<SearchedUserInfo[]>([]);

// searchValue가 바뀔 때 마다 검색을 시작.
useEffect(() => {
    return SearchUtils.searchUser(searchValue, allUserList, setSearchedUser);
 }, [searchValue]);

//유저를 검색.
const SearchUtils = {
    // 검색 키워드를 기반으로 유저를 필터링
    searchEvent: (
       word: string,
       userList: SearchedUserInfo[],
       setSearchedUser: (searchResult: SearchedUserInfo[]) => void,
    ) => {
    if (word.length === 0) {
      return [];
    }
    const searchResult: SearchedUserInfo[] = userList.filter((user: SearchedUserInfo) => {
      return user.name.includes(word);
    });
    setSearchedUser(searchResult);
    return searchResult;
  },

    searchUser: (
       searchValue: string,
       userList: SearchedUserInfo[],
       setSearchedUser: React.Dispatch<React.SetStateAction<SearchedUserInfo[]>>,
          ) => {
    const timer = setTimeout(() => {
       setSearchedUser(SearchUtils.searchEvent(searchValue, userList, setSearchedUser));
    }, 500);
    return () => clearTimeout(timer);
  },
}

Keyword.

Debouncing : 마지막에 호출된 함수만 실행하기.

“검색에 모르는 사람을 찾으려고 글자를 하나하나 치는 사람보다는 키워드를 정해놓고 치는 사람이 많을 것이다.”

해당 가정에 시작해서 유저가 모든 키워드를 입력하고 난 후, 검색을 실행하기로 결정했습니다.

개선 과정

  • 기존의 키보드 입력을 통한 값의 변화마다 이벤트가 호출 되던 것을 입력을 마친 후 500ms 동안 추가 입력이 발생하지 않을 경우 이벤트를 호출.
  • 입력이 계속 되면 clearTimeout이 실행되어 검색을 하는 함수가 들어있는 timer를 지우게 되어 검색이 일어나지 않음.
  • 검색을 멈추면 clearTimeout이 작동하지 않고, timer가 500ms를 기다린 후에 내부에 있는 setSearchedUser를 실행함.

개선 결과

  • 기존 ‘핏토리’라는 검색어 입력시, 7번의 이벤트 호출이 발생하던 것을 1회 호출로 최적화.
  • 불필요한 이벤트 호출 방지.

API 호출 방식 개선기

새로운 문제의 발생

테스트를 진행하면서 저희팀은 Mock data로 5000명의 유저를 넣었습니다.

그러다보니 이전에는 발생하지 않았던 모든 유저 리스트를 받아오는 것에서 문제가 발생했습니다.

생각보다 검색 페이지를 로딩하는데 불필요한 지연시간이 발생했습니다.

Problem1. list를 불러오는데 240ms라는 시간이 걸림. → 유저 볼륨이 커지면 더 오래걸릴 것

ㅇ

 

123123


834ms 중 유저 리스트를 받아오는 것이 240ms가 소요됨.

  • 하단 list의 경우 추천친구 데이터 → 디폴트로 필요한 값임.

Problem2. 불필요한 상황에서 API 호출이 일어남.

111

개선 사항

  • 유저 검색을 처음에 한번에 불러오지 말고 필요에 따라 불러오자.

    → 유저는 검색이 아닌 추천 친구를 보러만 들어올 수도 있는데, 초기 속도가 느리면 불편하다.

검색 자동완성 ver3

// 검색 결과로 나온 유저가 담긴 배열.
const [searchedUser, setSearchedUser] = useState<SearchedUserInfo[]>([]);

// searchValue가 바뀔 때 마다 검색을 시작.
useEffect(() => {
    return SearchUtils.searchUserByKeyword(searchValue, setSearchedUser);
  }, [searchValue]);

const SearchUtils = {
    searchUserByKeyword: (
       searchValue: string,
       setSearchedUser: React.Dispatch<React.SetStateAction<SearchedUserInfo[]>>,
     ) => {
    const timer = setTimeout(async () => {
       //값이 없을 경우 api 요청을 하지 않음.
       if (!searchValue) return setSearchedUser([]);
       const userList = await UserAPI.searchUserByKeyword(searchValue);
       // 반환할 결과가 없을 때, 빈 배열로 반환
       if (!userList) return setSearchedUser([]);
       return setSearchedUser(userList);
     }, 500);
     return () => clearTimeout(timer);
   },
}

Keyword

UX - 사용성 개선, 불필요한 요청 방지

개선 과정

  • 기존에 한번에 불러오던 유저 리스트를 검색어 입력시 해당 키워드에 맞는 유저를 가져오는 방식으로 변경.
  • 처음에 유저 리스트를 가져오지 않으므로 초기 렌더링 속도 상승
  • 검색하는 키워드가 없으면 API 요청을 날리지 않음
    const timer = setTimeout(async () => {
        //값이 없을 경우 api 요청을 하지 않음.
        if (!searchValue) return setSearchedUser([]);
        const userList = await UserAPI.searchUserByKeyword(searchValue);
        // 반환할 결과가 없을 때, 빈 배열로 반환
        if (!userList) return setSearchedUser([]);
        return setSearchedUser(userList);
      }, 500);
    개선 결과

123123124

  • 빈 값일 때 API 요청이 날아가지 않음
  • 기존의 약 800ms가 소요되던 것을 480ms로 축소 시킬 수 있었음.
  • 이를 통한 더 빠른 초기 렌더링을 통해 사용성을 개선할 수 있었음.

후기

항상 구현을 하는 단계에서 프로젝트가 끝나면 성능에 대해서 신경을 쓰지 못하는 경우가 많았습니다.

그리고 평소에 ms의 단위로 인한 지연은 크게 고려하지 않았고, 항상 확장 가능성에 대해서 고려를 안했던 것 같습니다.

그러나 이번 기회를 통해 유저가 나 혼자일 때의 환경과, 5000명, 그리고 그 이상을 불러올 때 얼마나 큰 변화를 가져오는지 알게 되었습니다.

이번 과정을 통해 성능 개선에 대해서 큰 관심이 생겼고, 추후 개발을 진행할 때 성능 개선을 하는 것에 흥미를 가지고 임할 수 있을 것 같습니다.

이번 프로젝트 뿐만 아니라 개선하는 과정에서 정말 많은 질문들을 했고, 어쩌면 당연하다고 생각되는 질문들도 확실 하기 위해 한번 더 할만큼

귀찮게 한거 같은데 항상 즐겁게 대답해주셨던 팀원들 모두 감사합니다 :)

들어가며

저는 참 복이 많은 사람입니다.

사실 오늘 결과를 받기까지 최선을 다했다고 생각하지만,

제 모든 주변인들에게 말했듯, 반 포기도 아닌 포기상태였고 겸허하게 졌잘싸 마인드로 받아들이기 위해 수십번의 마인드 컨트롤도 했습니다.

왜냐면 제가 4주를 진행하면서 만난 모든 분들은 너무나도 뛰어나셨고, 열정이 넘치셨으며, 저는 매 순간 배우는 사람이었기 때문입니다.

재미없게 미리 결론부터 말하면 좋은 기회를 받아 멤버십에 합격하게 되었고,

멤버십을 진행하면서 지치고, 조금은 열정이 사그라들 때마다 이 때의 마음가짐을 되돌아보고자 글을 작성합니다.

4주간 함께해주신 모든 분들에게 감사하며, 매 순간 많이 배웠고 감사했습니다.

 

나의 생활

매 순간이 최선이었고, 한 순간도 포기하진 않았다.

뭔 말같지도 않은 말을 이렇게 써놨냐 하면, 그냥 첫 문장이라 멋있게 쓰고 싶었다.

근데 이 말이 맞는 것 같다.

 

사실 삶 자체를 되게 리얼하게 표현하면, 평일에는 하루에 세시간 이상 자본 적이 없고, 목요일에는 잠을 안잤다.

그렇게 금요일에는 밀린 잠을 보충했으며, 주말에는 밀린 학습정리와 코드 리팩토링을 진행했다.

 

이게 기본이 부족한 내가 살아남는 법이 아니었나 싶다.

 

첫 주는 실제로 미션 시간의 60%를 자바스크립트를 공부하고, 문법 검색하는 것에 사용했다.

기초가 부족하다보니 부가적으로 공부할 것이 많아져서 생긴 슬픈 일이었다.

 

그리고 동료들과 학습할 때는, 내가 모르는 것을 부끄러워 하되, 같은 일로 부끄럽지 않게 하려고 노력을 했다.

풀어쓰자면, 내가 오늘 모르는 것은 당연하게 모를 수 있다. 나는 처음이니까. 너무 당당한 것은 좋지 않지만 스스로 인정하는 과정이 필요했다.

그리고 이를 되풀이 하지 않도록 노력했다. 다음날 부족한 지식으로 인해 부끄러울 순 있으나, 같은 지식으로 부끄러운 것 만큼 더 안타까운 일이 없다.

그렇기에 한번 학습한 내용은 계속해서 인지하려고 노력했던 것 같다.

 

2주차부터는 다양한 문법을 써보려고 했던 것 같다.

배열은 이전에 자바나 파이썬으로 너무나도 많이 써봐서 익숙했고, 자바스크립트가 자바와 비슷한 점도 있어서 조금 익숙했다.

그런데 어느날 보니까 내 코드가 자바스크립트 같지 않고, 너무 자바의 코드와 비슷해서 뭘 공부하고 있는 것인지 회의가 들었다.

그렇기 때문에 object 자료형도 써보고, filter도 한번 써보고... 이러면서 언어를 조금더 자바스크립트 같이 바꾸려는 노력을 조금씩 했던 것 같다. 물론 잘 된거 같지는 않지만 시도에 의의를 두고....

 

3주차부터는 개념적인 고민을 하기 시작했다.

미션이 무엇을 의도하는 것이며, 단순이 주먹구구식의 해결이 아니라 뭘 생각하게 시켰는지, 이를 해결하기 위해 내가 무엇을 공부해야 하는지를 굉장히 고민을 많이 했다.

실제로 미션을 받고 5시간 넘게 공부한 적도 있으며, 미션을 제출 할 때 체크포인트 전부를 못했다고 제출하는 경우도 많았다.

특히 어느 한 날의 경우는 밤 12시가 되었는데, 코드를 한 줄도 적지 못하는 대참사가 일어나기도 했다.

지금에 와서야 대참사라고 웃으며 이야기 하지만 그 당시에는 진짜 울뻔했다..

그 때 위로해주신 같은 조원 분들 항상 감사합니다....

그 때 참 답답했고 막막하고 회의감도 들고 온갖 부정적인 생각이 다들었으나, 그 이후에 개념 공부에 대한 위대함을 깨달은 것 같다.

1시쯤 첫 코드를 치기 시작한 이후로 내가 무엇을 해야할지를 깨닫고 결국 다음날 피어세션 전까지는 대부분을 완성해서 낼 수 있었다.

이 때부터 항상 코딩 시작에 목숨을 걸지 않기로 했다. 

근본적인 학습이 되어 있으면, 시작이 언제든 결국 해결된다는 것을 알았다.

 

4주차부터는 설계에 대한 고민을 했다.

실제로 동료 학습 때 가장 많이 했던 주제들이 설계에 대한 이야기였으며, 나는 이러한 근거를 가지고 이렇게 접근했고, 이렇게 설계를 했다. 등의 이야기를 하려고 노력을 많이 했던 것 같다. 이 때 혼자서 공부하기 시작한게 디자인 패턴이었는데, 사실 이틀하고 더 못했다.

하여튼 이만큼 설계 자체에 대한 고민을 많이했다.

그리고 4주차 와서 참 많이 뿌듯했던 것은, 더 이상 자바스크립트 문법으로 검색하는 시간은 없었고,

이전에는 검색에 소요되는 시간이 70% ~ 80%였다면 이제는 학습과 코딩의 비율이 50대 50으로 맞춰졌다는 점이었다.

참 스스로에 대해서 뿌듯하긴 했지만 수면시간은 동일하게 새벽 5시 6시였으니, 그냥 검색 시간이 줄은 것으로 마무리하겠다. 

 

수료 후기 및  느낀점

처음엔 타인과 비교를 많이 했다.

진짜 그냥 대단한사람이 너무 많았다. 나는 아직 개념 공부하고 있는데, 누구는 두번째 미션하고 있고..

질문하시는 퀄리티도 다르고.. 답변하는 내용도 나는 못알아 먹겠고... 

또한 1주차 팀원 분들이 너무 대단하셔서 나는 많이 모자라구나, 멤버십은 힘들겠다...라고 수십번 되뇌였던 것 같다.

오히려 다행인 점은 이 경험 때문에 나는 멤버십을 가겠다는 목적 보다는 '한달밖에 없는 소중한 시간 동안 크게 성장하자.'

라는 마음이 컸던 것 같다.

하지만 멤버십을 포기했다고 해서 미션을 포기하지는 않았다. 

동료와 함께하는 학습시간은 내 학습이 충분히 전제되어 있어야 하며, 내가 모자라면 타인에게 할 수 있는 말이 없고, 내가 받을 피드백도 적어진다.

그렇기 때문에 더 치열하게 했어야 했다.

 

그리고 이후에는 이전의 내 모습과 비교를 많이 했다.

실제로 주말에 가장 많이 본 자료는 과거의 내 자료였다.

과거의 나는 어떻게 짰으며, 지금의 내가 이 시각으로 보면 어떻게 개선할 수 있었을까를 생각을 했던 것 같다.

그렇게 해결할 수 있으면 개선을 했고, 실제로 마지막 주에 가서는 대부분의 체크포인트에 체크를 할 수 있었다.

 

결국 나는 성장한 것 같고, 각자의 속도로 성장해나가는 지속 가능한 개발자 중, 각자의 속도 부분에 대해서는 조금 이해를 할 수 있었다.

 

음...

이 글을 어쩌면 보실 8기 분들을 위해 그래도 글을 쓰자면

1. 경쟁해야 될 것은 어제의 나입니다.

실제로 대단한 분들이 너무 많으셨고, 타인과 비교하자면 학습 의지만 꺾이는 것 같습니다.

어제의 내가 몰랐던 내용을 오늘의 내가 안다면 그것은 크게 의미 있는 것입니다.

 

2. 7시 체크포인트는 내일의 나와 비교하기 위한 기준점입니다. 
저는 7시 체크 포인트의 체크를 한 것보다 못한 것이 2배 이상 많은 사람인걸로 기억합니다. 너무 집착하지 마세요.

갑자기 글이 길어지는데, 부스트 캠프의 글을 보면 각자의 속도로 지속 가능한 성장을 할 수 있는 사람을 찾는다고 했는데,

7시에 너무 집착하지 않고 각자의 속도를 찾으면 좋겠습니다.

 

3. 건강을 챙기셨으면 좋겠습니다.

저는 챌린지 전 후로 건강이 크게 나빠지지는 않았지만 몸을 돌보지는 않았던 것 같습니다.

하루에 커피 두 잔, 카페인 음료 2개, 하루 세시간 수면...

하지만 여러분들은 몸을 돌보셨으면 좋겠습니다. 

부스트캠프 챌린지가 끝난 후, 이번 주에 이르기 전까지 저는 하루에 12시간을 넘게 자면서도 피곤했던 것 같습니다.

실제로 어머니께서는, 어디 아픈거 아니냐..라고 하실 정도로 잠을 많이 잤죠...

끝나고 나서의 건강 이슈와 별개로도

부스트 캠프는 매일 매일이 강도 높은 미션으로 매 순간의 컨디션이 중요합니다.

저는 원래 나쁘지 않은 체력과, 알람을 잘 듣는 체질 덕에 9시면 눈을 뜰 수 있었고 체크인과 동료 학습 시간에 집중할 수 있었습니다.

근데 3주차 부터는 체력이 부족해서 그런지 점심먹고 한시간 정도는 잤구요...

하여튼 부스트 캠프는 매일 매일이 성장이고 소중한 시간이기에 저처럼 미련하게는 안하셨으면 좋겠습니다.

 

4. 더 큰 성장을 하고 싶다면 주말을 활용하세요

사실 마스터님께서도 주말엔 놀아라! 라고 하셨지만.. 아닌가..?

하여튼 저는 모자란 지식과 모자란 미션 진행률 때문에 주말의 대부분을 할애했습니다.

덕분에 못해결한 미션을 많이 해결했고, 실제로도 성장했고요.

주말에도 평일처럼 해라!가 아닌 생각보다 하루는 기니까 쉴거 다 쉬고 남는 시간에 짬내서 하시면 좋을 것 같습니다.

 

5. 동료와 함께하세요

저는 채널에서 말을 많이 하는 편은 아니었습니다.

사실 지식이 짧아 질문에는 대답하기가 어려웠으며 그나마 할 수 있는 말들은 힘들어 하시는 분들을 위해 힘내세요..! 정도...

하지만 팀원들끼리 있는 방에서는 진짜 많이 떠들었습니다.

서로 격려하고, 고민하고, 이야기하면서 진짜 많은 힘이 되었습니다.

실제로 4주동안 첫째주에 만난 팀원 분들이 큰 의지가 되었습니다. 감사합니다.

 

챌린지 시작 전으로 돌아간다면

안돌아갈거다

 

마지막으로 

사실 많은 분들이 궁금해하시고 나도 궁금해 했던 것은 멤버십 기준이 뭔가요? 일 것입니다.

그리고 이에 대한 답은 나도 모른다...입니다.

 

실력 순으로 위에서부터 자른다면 저는 진작에 잘려나가 멤버십의 ㅁ도 구경을 못했을 것 같습니다.

근데 공부시간으로 위에서부터 자른다면 또 어떻게 될지 모른다.가 제 생각이긴합니다.

 

실제로 저는 모자란 지식 때문에 많은 지식을 할애했고, 매 순간순간 치열하게 하루하루를 살았다고 생각합니다.

그러니 기준은 모르지만, 매 순간 최선을 다하시면 좋은 결과가 있을 것 같습니다.

 

저도 예전에 많은 블로그에서 이런글로 넘어가려고 하길래 뭐야 이건...이라고 수도없이 생각했습니다.

아마 이 글을 보시고 멤버십에 대해 궁금하신 분들도 비슷하게 생각하시겠죠...?

그럼에도 제가 내린 결론이 이게 전부라 죄송하고 이게 제가 느낀 전부입니다...

모두 화이팅 하시고 앞으로 하시는 모든 일에 좋은 과정과 결과가 함께하기를 바랍니다. 

 

들어가며

거진 6개월만에 들어오는 블로그, 그리고 8월 24일.

챌린지 합격은 무슨 멤버십 결과가 나와도 이상하지 않은 오늘, 사실 멤버십 결과가 나와서 쓰는거지만

하여튼 갑자기 챌린지 합격을 회고 하는 이유는 사실 결과 나왔으니까...

챌린지를 하면서 얼마나 바쁜지를 알았고, 멤버십도 그만큼 바쁠 것을 아니까 더 늦기 전에, 그리고 잊기 전에 글을 써서 남겨보고자 한다.

 

1차 코딩 테스트

사실 기억도 잘 안난다.

문제를 외부 유출하면 법적 책임을 물 수도 있다고 했으니까 오히려 다행인가...

그럼에도 또렷하게 기억 나는 것은 굉장히 어려웠던 CS에 대한 이해를 물어봤던 문제들이 아닐까 싶다.

 

비전공생으로 개발을 시작하면서 항상 모자람을 느끼고 '공부해야지...' 마음 먹으면서도 하지 못했던 것을 꼽으라면

당연 CS인데.. 이를 막상 접하게 되니 크게 좌절했던 것 같고, 사실 이 때 반 이상 포기했던 것 같다. 

 

사실 본인이 회고하기 위해 쓴 글이지만, 언젠가 보실 8기 분들을 위해... 조금 쓰자면

저는 CS 공부라고는 졸업을 위해 수강했던 네트워크 과목이 전부이며, 그 마저도 학점을 뿌리는 비대면 시대에 B+를 받아간

둔재로 CS와는 굉장히 거리가 멀었다고 할 수 있습니다.

 

언젠가 부스트캠프 1차를 목표로 공부하시는 분들이 있으시다면 CS의 기본 운영체제, 네트워크, 자료구조, etc... 를 열심히 하시면 

빛을 보지 않을까 싶습니다.. 결국 도움이 안됐겠지만 결국 본질에 집중하라.....가 맞는거 같습니다.

 

 

2차 코딩 테스트

참 이해가 안됐다.

앞서 말한게 겸손이나 기만이 아닌 진심으로 반 포기 상태였고, 내 방은 너무 더우니까 평화롭게 거실에 앉아

스프링 강의를 들으며 있던 어느 날 이 문자를 받았고, 많이 놀랬다.

사실 체감도 안돼서 별 말도 안하고 넘어갔던 걸로 기억한다.

 

2차 코딩테스트는 잊으려고 해도 잊을 수 없으나, 앞서 말한 것처럼 유출 시 법적 책임을 물 수도 있으므로 자제하도록 하겠다.

도움도 안되겠지만 결국 말씀드리고 싶은 것은 '본질'이다.

 

내가 무엇을 해야하는지 명확히 알아야하고, 그것에 온전히 집중하면 될 것 같다.

화려한 알고리즘이나 복잡한 자료구조, 그런 것들보다 앞서 말한 '본질'에 집중하면 될 것 같다.

가끔은 엄청나게 효율적인 것을 위해 돌아가는 것 보다는 우직하게 나아가는 것이 도움이 될 수 있겠다는 생각을 했다.

 

그리고 작성한 코드들에 근거가 있으면 좋겠다는 생각을 했다.

어디 영상에서 본거 같은데, 코드를 쓰는 것은 어린 애를 대려다 앉혀놓아도 작성할 수 있다고 했다.

물론 이 말에 동의하진 않는다. 나는 어려웠으니까.

하여튼 그럼 개발자는 코드를 작성할 때 생각을 해야하고, 코드 한 줄 한 줄에 근거가 있어야 한다고 생각한다.

이는 챌린지를 진행하면서 3주차부터 생각했던 내용이기도 하다.

 

이러한 점을 미리 생각하시고 코드를 짜는 습관과, 코딩테스트를 단순히 문제 풀이가 아닌, 이러한 관점에서 접근하여

문제 풀이를 위한 설계와 내 코드에 대한 근거를 가지고 작성한다면 좋을 것 같다.

 

 

결과

세상에 나는 운도 좋지

사실 운이 좋았다고 생각한다.

같은 말을 반복하는 것 같아 이상하지만 겸손, 기만이 아닌 운이 좋았다고 생각한다.

 

사실 걱정이 많이 됐던 것은 6기 코테 후기를 본 후였다. 

6기 분들은 문제를 다 풀어야 된다고 했는데, 나는 겨우 한문제 풀었는데.....

해서 결과 나오는 날도 모르고 있을만큼 포기를 한 상태였다.

 

결론부터 말하면 저는 한 문제를 풀었고, 그 한 문제를 풀기 위해 많은 고민을 했다고 생각합니다.

중간에 갑자기 존칭을 쓰니까 어색한데, 보실 분들을 위해서 쓰겠습니다.

그리고 한 문제에 대해서 극한의 예외케이스, 흔히들 말하는 엣지케이스까지 고려했고, 이를 고려한 것이 주효했다고 봅니다.

 

이제와서 돌이켜보면, 부스트캠프의 코테는 참 챌린지의 모습과 맞닿아 있다고 생각합니다.

난이도 자체는 많이 어려웠고, 처음에 풀면서는 와 이게 뭐야... 했지만 이제와서, 챌린지를 수료하면서 느낀 점은

이러한 테스트를 보고 뽑힌 사람이 챌린지를 잘 소화할 수 있겠구나..?라고 식견이 짧은 제가 감히 어림잡아 생각해봅니다.

 

마지막으로

사실 회고의 목적으로 제가 개인적으로 작성한 글이기는 하나,

내년 요맘 때 쯤의 8기 지원자 분들이 많이 보실 것이라고 생각합니다.

저도 진짜 많은 게시글들을 보았고, 사실 6기 코딩테스트 후기의 모든 글을 찾아본 것 같습니다. 

그 때는 정말 떨리고, 내가 할 수 있을까 라는 생각이 드실 것 같습니다.

그럼에도 열심히 해 나가시면 부스트 캠프에 함께 하실 수 있을 것이라고 생각합니다.

 

저는 공부한지 1년이 조금 넘은 비전공생이고, 공대, 이과대도 아닌 그냥 경영대생입니다. 

앞서 말씀드린 대로 CS는 제대로 공부한 적도 없으며, 알고리즘은 조금 열심히 한 것 같긴한데...

전공생 분들에 비하면 모자란 수준이었습니다.

 

이럼에도 겨우 1년 테스트 먼저봤다고 이런 글을 쓰는 저도 웃기지만 이런 저도 통과했듯,

이 글을 보시게 될, 시험을 앞둔 여러분들도 좋은 결과가 있을 것이라고 생각합니다.

 

매사에 포기하지 않고 끝까지 나아가시길 바라며, 

좋은 결과 있으시길 바라겠습니다. 감사합니다.

 

링크

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

 

문제

 

풀이

그냥 쓰여있는 문제를 구현하면 되는 문제.

조건에 따라 수행하는 액션에 대해 집중하고 구현하면 된다.

코드

import sys

N, M = map(int, input().split())
r, c, d = map(int, input().split())

arr = []
visit = [[0] * M for _ in range(N)]

for _ in range(N):
    arr.append(list(map(int, sys.stdin.readline().strip().split())))

#북, 동, 남, 서
moves = [[-1, 0], [0, 1], [1, 0], [0, -1]]
turn_count = 0
ans = 1

visit[r][c] = 1

while True:
    d = (d + 3) % 4
    nr = r + moves[d][0]
    nc = c + moves[d][1]

    if nr >= N or nc >= M or nr < 0 or nc < 0:
        turn_count += 1
        continue

    if arr[nr][nc] == 0 and visit[nr][nc] == 0:
        visit[nr][nc] = 1
        r = nr
        c = nc
        turn_count = 0
        ans += 1
        continue

    else:
        turn_count += 1

    if turn_count == 4:
        nr = r - moves[d][0]
        nc = c - moves[d][1]

        if nr >= N or nc >= M or nr < 0 or nc < 0:
            break

        elif arr[nr][nc] == 0:
            r = nr
            c = nc
            turn_count = 0
        else:
            break


print(ans)

 

후기

너무 코드가 지저분한 것 같아서 다른 분들의 코드를 봤는데 다른 분들의 풀이를 보니

필요 없는 코드가 많아서 수정하다보니 아래와 같은 코드가 나왔다.

import sys

N, M = map(int, input().split())
r, c, d = map(int, input().split())

arr = []
visit = [[0] * M for _ in range(N)]

for _ in range(N):
    arr.append(list(map(int, sys.stdin.readline().strip().split())))

#북, 동, 남, 서
moves = [[-1, 0], [0, 1], [1, 0], [0, -1]]
turn_count = 0
ans = 1

visit[r][c] = 1

while True:
    d = (d + 3) % 4
    nr = r + moves[d][0]
    nc = c + moves[d][1]

    if arr[nr][nc] == 0 and visit[nr][nc] == 0:
        visit[nr][nc] = 1
        r = nr
        c = nc
        turn_count = 0
        ans += 1
        continue

    else:
        turn_count += 1

    if turn_count == 4:
        nr = r - moves[d][0]
        nc = c - moves[d][1]

        if arr[nr][nc] == 0:
            r = nr
            c = nc
            turn_count = 0
        else:
            break


print(ans)

나는 index가 넘어가서 생기는 에러를 발생하기 위해서 예외처리를 해주었는데, 

위 코드는 그런거 없이 넘어갔다. 

원래대로라면 nr, nc를 더하는 과정에서 배열을 넘어가는 것을 조회하게 되지 않나..?

라고 생각해서 그냥 테스트로 print에 넘어가는 배열 조회해봤는데 (이하생략)

3 3

1 1 0

1 1 1

1 0 1

1 0 1

하면 분명 통과된 코드도 index 에러 나서 뭐지.. 싶었는데,

문제에

요걸 못봤다.

구현 문제는 문제를 꼭 잘 읽도록하자.

+ Recent posts