<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>일하는 개미의 개발 블로그</title>
    <link>https://gee05053.tistory.com/</link>
    <description>신입 개발자의 개발 블로그</description>
    <language>ko</language>
    <pubDate>Sun, 5 Apr 2026 16:01:28 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>일하는 개미</managingEditor>
    <item>
      <title>드디어 취준 끝.</title>
      <link>https://gee05053.tistory.com/33</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;개요&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;드디어 길고 길었던 취업 준비가 끝났다. 초기 스타트업에 Frontend Developer 직무로 취업을 했고, 내가 취업 준비하면서 가장 자신있게 면접을 진행하고 편안했던 분위기 때문에, 이 회사에 입사하고 싶었다. 생각보다 길어진 취업 준비로 많은 생각도 하고 그랬는데, 이 시기동안 했던 생각과 느낀점들, 경험했던 것들을 지금 정리해야 그래도 기억이나지.. 안그러면 또 까먹어버리기 때문에,,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 글에서는 전역을 하고 나서 내가 취업 준비했던 과정, 힘든 점 등등 겪었던 것들을 정리해보려고한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;전역 전&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;21년 3월에 소위로 임관을 했던 나는 어느덧 전역을 앞두고 있었다. 전역이 다가올수록 점점 취업에 대한 불안감이 생겨났지만, 야근이 많아 규칙적으로 매일 공부는 할 수 없었기 때문에, 주말에라도 코딩테스트를 준비하면서 조금씩 준비를 했다. 주변에서는 '전역하고 좀만 놀지 왜 바로 취업 준비를 하냐' 라고 많이 말을 했지만, 이미 졸업을 하고 2년이 지난 나의 머리 속에는 전공 지식들 과 언어들이 없었다. 또 한번 나태해지면 무기력해질 때까지 나태해지는 나를 잘 알기에, 조금이라도 더 빨리 준비해서 남들과의 차이를 매꿔야했다. 코딩 테스트를 준비하면서 지원할 회사들도 알아보았다. 하지만 인턴 경험도 없었기 때문에, 취업에 대한 막막함이 너무 컸고, 인턴같은 경험을 할 수 있으면 좋겠다라는 생각이 들었는데, 휴가 때 친구가 &lt;b&gt;오픈소스 컨트리뷰션 아카데미&lt;/b&gt;를 추천해줬다. 해당 프로그램에는 내가 지원할 회사로 알아봤던 래블업도 있었고 프로그램 기간이 전역하고나서 7월부터 10월까지 였기 때문에 나한테 너무 좋은 상황이었다. 얼마 안남은 참가 신청을 후딱 작성하고 결과를 기다리며 전역을 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;전역 후.. 컨트리뷰션 아카데미 시작&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;길었던 군 생활이 끝나고 전역을 했다. 얼마 후 컨트리뷰션 아카데미에서 래블업에 합격했다는 소식을 받았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;'드디어.. 전역을 하고 시작이 좋구나' 생각을 했다 ㅋㅋㅋㅋ 프로그램을 시작을 하고 나서 처음으로 여러 개발자들과 이야기를 해보며 오픈소스 기업에 기여를 하는 경험을 했다. 기여라고 해도 간단한 이슈를 찾아서 Github에 등록하고, 이슈 해결 PR을 작성하는 것이었지만 나한테는 너무나 소중한 경험이었다. 프로그램에 참가하는 동안, 본격적으로 Frontend 면접 질문들을 준비했고, 구직 사이트에도 하나 둘씩 가입하며 이력서를 작성하기 시작했다. 컨트리뷰션 아카데미가 종료될 때 쯤, 래블업에 면접을 봤다. 개발자로서 첫 면접이었는데 망했다..ㅋㅋㅋㅋ 지금 돌이켜보면 정말 많이 부족했고, 내가 너무 오만했던거 같다. React를 사용하고 있지만 이 친구를 왜 사용하는지도 몰랐고, 이 친구의 장점에 대해서도 제대로 설명도 못했으니 결과는 너무 당연했다. 지금 생각해보면 너무 아쉽기도하다. 다른 곳에 면접을 보면서 조금씩 다듬었으면 다른 결과가 나왔을까? 하는 생각도 조금은 들었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;컨트리뷰션 아카데미 종료, 그리고.. 사회의 쓴 맛&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컨트리뷰션 아카데미도 종료를 하고, 래블업에 기여한 경험을 바탕으로 이력서를 다듬으면서 여러 기업에 제출했지만, 생각보다 더 많이 어려웠다. 인턴 경험 하나 없는 이력서는 그냥 종이 쪼가리에 불과했고, 구직 사이트에 내 구직 현황에 불합격이 10개, 15개, 20개 점점 쌓여갈 수록 점점 자신감은 떨어져나갔다. 면접 질문들도 면접을 보면서 다듬을 수 있을 텐데, 이력서에서 모두 다 떨어지니.. 인턴부터라도 경험을 하고자 했지만, 점점 어려워 지는 경제에서 인턴, 신입보다는 경력직을 뽑는 분위기가 되었다. 2~5년차 뽑는 공고는 많지만 인턴, 신입을 뽑는 공고를 찾기는 어려웠다. 이 시기에 자신감이 정말 많이 떨어졌으며, 앞날이 안보였다. 오죽했으면 그토록 싫어했던 군대 재임관도 생각을 했을까... 친구들은 이제 전역하고 4개월밖에 안되었으면서 뭘 그리 조급하냐고 했다. 뭐 틀린 말도 아니다. 1년~2년 준비하는 사람들도 있는데 고작 4개월 가지고 뭘 그리 급할까. 하지만 시간이 지난다고해서 내 이력서가 달라지는 것이 아니기에 나에 대해서 더욱 더 채찍질을 했던거 같다. 그렇게 좌절을 하고 있을 때, 또 다시 나를 도와준건 컨트리뷰션 아카데미와 래블업이었다. 컨트리뷰션 아카데미와 연계로 래블업에서 2개월 가을 인턴을 신청받는다는 소식을 받았다. 정직원 면접에서는 떨어졌었지만, 2개월만이라도 더 일을 하고 싶었고, 소식을 듣자마자 바로 신청했다. 결과는 합격. 이 합격이 얼마나 감격스러웠는지.. 너무 행복했던거 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;래블업 인턴&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫 출근 전날 밤에는 잠도 안왔다. 첫 인턴 출근이라니. 너무 떨렸고 기대가 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 인턴 기간은 나에게 너무나 소중하고 고마운 기간이었다. 나에 대해서 어떤 부분이 부족하고 어떤 부분이 장점인지를 많이 느낄 수 있었던 기간이었다. 좋은 리더분들과 frontend 팀원들, 그리고 좋은 회사 사람들 덕분에 매일 웃으면서 즐겁게 출근할 수 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금도 나는 래블업 인턴 기간이 없었으면 이 글을 적는 지금도 이력서를 작성하면서 사회의 쓴 맛을 보고 있지 않았을까 하는 생각을 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원래는 가을 인턴만 진행하는 것이었지만 양해를 구해, 2달 더 연장을 해서 총 4개월을 인턴으로 진행했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;래블업 인턴 기간에 진행했던 내용은 &lt;a href=&quot;https://gee05053.tistory.com/32&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;래블업 인턴 후기 글&lt;/a&gt;에서 확인하면 좋을거 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;인턴이 끝나고..&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인턴이 끝날 때 쯤부터 다시 이력서를 수정하면서 다른 기업들에 제출을 했다. 인턴 경험이 추가되고, 조금만 자기소개서가 수정되었을 뿐인데, 이력서 합격 비율이 점점 높아졌다. 많으면 일주일에 4개의 기업에서 1차 합격 소식을 들었던거 같다. 그러면서 대면 면접, 온라인 면접, 다대다 면접, 코딩 테스트 등 다양한 면접을 경험하면서 면접 질문도 수정할 수 있었고, 여러 경험들을 할 수 있었다. 그러다가 이번에 합격한 기업에 면접을 볼 기회가 생겼고, 가장 내가 편하게 느끼고, 재미있게 일을 할 수 있을거 같아 해당 기업을 선택했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;후기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가끔 친구들이랑 이야기하면서 '너는 OOO으로 돌아가면 돌아간다 vs 돌아가지 않는다' 질문을 받은 사람이 많을 것이다. 나는 보통 돌아간다고한다. 생각해보면 그 시기에 아쉬운 것도 많기 때문에. 만약 다시 돌아간다고해도 다르게 행동한다는 보장은 없지만..ㅋㅋㅋ 그래도 돌아가고 싶다고 말한다. 하지만 그래도 항상 돌아가기 싫다는 시기가 있는데, 바로 고3 수능이었다. 내가 정말 후회없을 만큼 공부했고(하지만 수능 성적은,,,ㅎㅎ 최저는 맞췄으니 한잔해 ) 다시 돌아가도 그렇게 할 자신이 없기 때문에. 이번에 하나 더 추가되었다. 취준 기간은 돌아가고 싶지않다. ㅋㅋㅋㅋㅋㅋ 절대로.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;취업 준비 기간이 9개월이면 뭐 적당하게 걸렸다고 많이들 이야기 하지만, 나는 잘 모르겠다.. ㅋㅋㅋㅋ 처음에 원래 3개월을 잡아서 그럴 수도..?&lt;br /&gt;아직 대학교에 진학을 하고 있거나 졸업을 앞두고 취업을 준비하고 있다면 가장 먼저 하고싶은 이야기 아래와 같다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;어떻게든 경험을 쌓아라.&lt;br /&gt;고3때 수시 원서를 작성할 때도 다들 느꼈겠지만 생각보다 자기소개서에 작성할 것이 없다. 이는 이력서도 마찬가지이다. 이름, 연락처, 학교를 작성하고 나면 대외활동, 자격증, 회사 경험 밖에 작성할 것이 없다. 최대한 인턴 경험을하고, 컨트리뷰션 아카데미와 같은 대외활동을 많이 참가하라고 말하고 싶다.&lt;/li&gt;
&lt;li&gt;GitHub 관리, 포트폴리오 관리는 필수다.&lt;br /&gt;생각보다 GitHub과 포트폴리오를 많이 본다. 많은 공고에서 포트폴리오(선택) 이런 식으로 작성해두지만 있고 없고의 차이는 심하다. 또한 개발자라면 GitHub은 또다른 이력서이다. google을 잘 검색해보면 GitHub overview를 꾸미는 여러 방법들이 있으니 깔끔하고 본인을 설명하기 쉽게 꾸며놓는 것도 서류 통과에서 긍정적으로 보는 것 같았다. 또한 잔디 관리도 중요하니 작은 사이드 프로젝트라도 꾸준하게 올려보자.&lt;/li&gt;
&lt;li&gt;면접에서 기본으로 물어보는 질문들은 무조건 술술 나올 때까지 연습하고, 면접을 보고나서 바로 준비했던 질문 리스트를 업데이트하자.&lt;br /&gt;면접을 시작하면 보통 기술 질문 전에 자기소개, 지원동기, OOO직무를 선택한 이유, 프로젝트 등등 기본적인 질문으로 시작한다. 솔직히 자기소개에서 버벅거리고 자신없게 이야기한다면 좋은 인상을 받기 힘들 것이다. 첫인상이 중요한 만큼 자기소개를 가장 중요하게 생각했고 이때까지 가장 많이 수정했다. 지원동기는 면접 2일전에 회사에 대해서 검색을 해보면 여러가지 정보를 얻을 수 있을 것이다. 그런 정보들을 바탕으로 나의 장점을 이끌어 낼 수 있는 내용을 섞으면 좋은 글이 완성이 된다. 그리고 마지막으로 면접 하나하나가 중요한 경험이다. 만약 준비했던 질문 리스트에 없던 질문을 받게된다면 잘 기록해두었다가 바로 업데이트를 해두자. 면접이 끝나고 나면 생각보다 긴장이 풀려서 기억이 잘 안나는 경우가 많다.&lt;/li&gt;
&lt;li&gt;항상 지원한 기업에 궁금한 점 질문을 5가지 이상은 준비하자&lt;br /&gt;보통 면접이 끝나고나면 이제 역질문을 할 기회를 준다. '우리 회사에 궁금한 점이 있으면 편하게 물어보아라'&lt;br /&gt;이건 어떻게보면 이 사람이 우리 회사에 얼마나 관심이 있는지를 확인하는 평가라고 생각한다.&lt;br /&gt;나는 보통 '이력서에서 어떤 부분을 좋게 보셔서 이렇게 면접 기회를 주셨는지 또 어떤 부분이 아쉬웠는지 알고싶다.', '팀원은 어떻게 되는가' 등등 질문을 했다. 물론 공고에 있는 내용인지 확인은 하고 질문해야한다. 공고에 있음에도 질문을 하면 공고를 제대로 확인을 안하는 사람으로 느껴질 수도 있다.&lt;/li&gt;
&lt;li&gt;추천 구직 사이트&lt;br /&gt;나는 보통 원티드, 사람인, 커리어리를 주로 사용했다. 사람인은 매일 수십개씩 추천 기업 알림이 와서 꽤 많이 도움이되었던거 같다. 원티드는 뭔가 다른 구직 사이트에 비해서 깔끔하다는 느낌을 받았던거 같다. 커리어리는 처음에는 개발자 커뮤니티로 사용하려고 했으나, 프로젝트 쪽에 가끔 스타트업이나, 좋은 주제를 가지고 팀원을 구하는 글을 많이 보았다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제부터 신입 개발자 인생 시작이다. 아직 취업 준비중인 분들도 화이팅이고, 나처럼 이제 새롭게 시작하는 사람들도 모두 화이팅 &lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>대학 &amp;amp; 일상 일기</category>
      <category>개발자</category>
      <category>면접</category>
      <category>사람인</category>
      <category>신입</category>
      <category>원티드</category>
      <category>전역</category>
      <category>취업 준비</category>
      <category>커리어리</category>
      <author>일하는 개미</author>
      <guid isPermaLink="true">https://gee05053.tistory.com/33</guid>
      <comments>https://gee05053.tistory.com/33#entry33comment</comments>
      <pubDate>Thu, 28 Mar 2024 16:19:20 +0900</pubDate>
    </item>
    <item>
      <title>래블업 인턴 후기</title>
      <link>https://gee05053.tistory.com/32</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;개요&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;OpenUp에서 주최한 오픈소스 컨트리뷰션 아카데미(이하 컨트리뷰션 아카데미)에 지원하여 래블업 주식회사(이하 래블업)에서 11월부터 12월까지 8주간 가을 인턴을 진행했으며, 이후 1월부터 2월까지 8주를 추가 연장하여 총 16주간 근무했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;군대를&lt;span&gt; &lt;/span&gt;전역하고&lt;span&gt;, &lt;/span&gt;개발자로서&lt;span&gt; &lt;/span&gt;첫&lt;span&gt; &lt;/span&gt;회사인&lt;span&gt; &lt;/span&gt;래블업을&lt;span&gt; &lt;/span&gt;다니면서&lt;span&gt; &lt;/span&gt;경험했던&lt;span&gt; &lt;/span&gt;과정들을&lt;span&gt; &lt;/span&gt;작성했다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;지원동기&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컨트리뷰션 아카데미 전에도 래블업에 대해서 관심을 가지고 있었는데, 마침 컨트리뷰션 아카데미를 통해서 기여할 수 있는 기회가 생겼다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컨트리뷰션 아카데미 기간 동안에 Backend.AI의 webui 이슈를 해결하고 리팩토링을 진행했었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컨트리뷰션 아카데미를 참여하는 동안 Backend.AI에 대한 애정과 관심, 그리고 재미를 많이 느꼈고, 프로그램이 끝나고 계속해서 기여 하고싶다는 생각을 하게되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마침&lt;span&gt; &lt;/span&gt;컨트리뷰션&lt;span&gt; &lt;/span&gt;아카데미와&lt;span&gt; &lt;/span&gt;연계로&lt;span&gt; &lt;/span&gt;래블업에서&lt;span&gt; &lt;/span&gt;근무할&lt;span&gt; &lt;/span&gt;수&lt;span&gt; &lt;/span&gt;있는&lt;span&gt; &lt;/span&gt;기회가&lt;span&gt; &lt;/span&gt;생겼고&lt;span&gt;, &lt;/span&gt;망설임&lt;span&gt; &lt;/span&gt;없이&lt;span&gt; &lt;/span&gt;지원하게&lt;span&gt; &lt;/span&gt;되었다&lt;span&gt;.&lt;/span&gt;&lt;span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span&gt;온보딩&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인턴이 시작되고 첫 3주동안은 온보딩 과정을 진행했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RealTime Chat&lt;span&gt;을&lt;/span&gt; &lt;span&gt;구현&lt;/span&gt;, Backend.AI &lt;span&gt;환경&lt;/span&gt; &lt;span&gt;구성&lt;/span&gt;, Pebble Seminar &lt;span&gt;순서로&lt;/span&gt; &lt;span&gt;진행했다&lt;/span&gt;.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;RealTime Chat&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Backend.AI의 Core쪽 코드에 친숙해기지 위한 첫 과제였다. 실시간 채팅 앱을 Python을 이용하여 구현하였으며 aiohttp, aioredis, aysncio 라이브러리를 사용하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;채팅의 내용을 저장해야한다는 조건이 없어 InMemoryDB인 redis를 사용했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;채팅방에&lt;span&gt; &lt;/span&gt;입장하면&lt;span&gt; &lt;/span&gt;사용자는&lt;span&gt; &lt;/span&gt;채팅방에&lt;span&gt; subscribe&lt;/span&gt;가&lt;span&gt; &lt;/span&gt;되도록&lt;span&gt; &lt;/span&gt;했으며&lt;span&gt;, &lt;/span&gt;사용자가&lt;span&gt; &lt;/span&gt;메세지를&lt;span&gt; &lt;/span&gt;입력하면&lt;span&gt; subscribe&lt;/span&gt;된&lt;span&gt; &lt;/span&gt;유저&lt;span&gt; &lt;/span&gt;즉&lt;span&gt; &lt;/span&gt;같은&lt;span&gt; &lt;/span&gt;채팅방에&lt;span&gt; &lt;/span&gt;있는&lt;span&gt; &lt;/span&gt;다른&lt;span&gt; &lt;/span&gt;유저들에게&lt;span&gt; &lt;/span&gt;입력한&lt;span&gt; &lt;/span&gt;메세지를&lt;span&gt; publish&lt;/span&gt;하도록&lt;span&gt; &lt;/span&gt;구현했다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-02-28 오후 4.18.00.png&quot; data-origin-width=&quot;508&quot; data-origin-height=&quot;968&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cXMrkn/btsFqMmN9nt/CWQWRII6dHbDdcJCIYBUSk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cXMrkn/btsFqMmN9nt/CWQWRII6dHbDdcJCIYBUSk/img.png&quot; data-alt=&quot;RealTime Chat 동작 사진&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cXMrkn/btsFqMmN9nt/CWQWRII6dHbDdcJCIYBUSk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcXMrkn%2FbtsFqMmN9nt%2FCWQWRII6dHbDdcJCIYBUSk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;508&quot; height=&quot;968&quot; data-filename=&quot;스크린샷 2024-02-28 오후 4.18.00.png&quot; data-origin-width=&quot;508&quot; data-origin-height=&quot;968&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;RealTime Chat 동작 사진&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코딩테스트를 준비하면서 Python을 기본적으로 다룰 수는 있었지만, aiohttp, asyncio, aioredis 등 과 같은 라이브러리를 사용해본 경험이 없어서 개념을 익히고 이해하는데 시간이 걸렸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만&lt;span&gt; &lt;/span&gt;해당&lt;span&gt; &lt;/span&gt;과제를&lt;span&gt; &lt;/span&gt;통해서&lt;span&gt; Backend.AI&lt;/span&gt;의&lt;span&gt; Core&lt;/span&gt;쪽&lt;span&gt; &lt;/span&gt;코드들을&lt;span&gt; &lt;/span&gt;이해하는데&lt;span&gt; &lt;/span&gt;많은&lt;span&gt; &lt;/span&gt;도움이&lt;span&gt; &lt;/span&gt;되었으며&lt;span&gt;, &lt;/span&gt;새로운&lt;span&gt; &lt;/span&gt;라이브러리들을&lt;span&gt; &lt;/span&gt;공부할&lt;span&gt; &lt;/span&gt;수&lt;span&gt; &lt;/span&gt;있어서&lt;span&gt; &lt;/span&gt;좋았다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Backend.AI &lt;span&gt;환경&lt;/span&gt; &lt;span&gt;구성&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컨트리뷰션 아카데미에서 이미&lt;span&gt;&amp;nbsp; &lt;/span&gt;Backend.AI를 설치 해본 경험이 있기 때문에, 인턴 기간에 다시 환경 구성하는 과정이 어렵지는 않았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 컨트리뷰션 아카데미에서 설치를 시도하면서 나 또한 많은 에러와 실패를 겪으면서 Backend.AI 설치가 쉽지않다는 것을 알고있었고, 같이 인턴십을 진행하시는 다른 분도 설치 과정에서 어려움을 많이 겪으셨다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이미 한번 그 실패들을 경험하고, 해결법을 알고있는지라, 도움을 드릴 수 있었고, 빨리 설치하고 다른 업무를 진행할 수 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;환경을&lt;span&gt; &lt;/span&gt;구성하면서&lt;span&gt; &lt;/span&gt;가상&lt;span&gt; &lt;/span&gt;머신과&lt;span&gt; VPN&lt;/span&gt;도&lt;span&gt; &lt;/span&gt;설정했고&lt;span&gt;, &lt;/span&gt;로컬에서&lt;span&gt; &lt;/span&gt;문제가&lt;span&gt; &lt;/span&gt;생겨도&lt;span&gt; &lt;/span&gt;업무를&lt;span&gt; &lt;/span&gt;할&lt;span&gt; &lt;/span&gt;수&lt;span&gt; &lt;/span&gt;있도록&lt;span&gt; &lt;/span&gt;가상&lt;span&gt; &lt;/span&gt;머신에도&lt;span&gt; &lt;/span&gt;환경을&lt;span&gt; &lt;/span&gt;구성했다&lt;span&gt;. &lt;/span&gt;이렇게&lt;span&gt; &lt;/span&gt;가상&lt;span&gt; &lt;/span&gt;머신에&lt;span&gt; &lt;/span&gt;구성을&lt;span&gt; &lt;/span&gt;하고나서&lt;span&gt; &lt;/span&gt;이후&lt;span&gt; &lt;/span&gt;업무를&lt;span&gt; &lt;/span&gt;하는&lt;span&gt; &lt;/span&gt;동안&lt;span&gt; Local&lt;/span&gt;은&lt;span&gt; &lt;/span&gt;개발용으로&lt;span&gt; &lt;/span&gt;많이&lt;span&gt; &lt;/span&gt;사용했고&lt;span&gt;, &lt;/span&gt;가상&lt;span&gt; &lt;/span&gt;머신은&lt;span&gt; &lt;/span&gt;테스트&lt;span&gt; &lt;/span&gt;서버를&lt;span&gt; &lt;/span&gt;구성하여&lt;span&gt; &lt;/span&gt;사용했다&lt;span&gt;. &lt;/span&gt;회사에&lt;span&gt; &lt;/span&gt;가상&lt;span&gt; &lt;/span&gt;머신을&lt;span&gt; &lt;/span&gt;쉽게&lt;span&gt; &lt;/span&gt;관리하고&lt;span&gt; &lt;/span&gt;구성할&lt;span&gt; &lt;/span&gt;수&lt;span&gt; &lt;/span&gt;있는&lt;span&gt; VM Farm&lt;/span&gt;이&lt;span&gt; &lt;/span&gt;있어&lt;span&gt;, &lt;/span&gt;개발과&lt;span&gt; &lt;/span&gt;테스트&lt;span&gt; &lt;/span&gt;환경을&lt;span&gt; &lt;/span&gt;구성하기&lt;span&gt; &lt;/span&gt;너무&lt;span&gt; &lt;/span&gt;좋았다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;Pebble Seminar&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RealTime Chat과 Backend.AI 환경 구성을 마친 후, Backend.AI의 구조와 코드를 이해하고, 그 내용을 바탕으로 짧은 세미나를 준비했다. 나는 Backend.AI WebUI에서 사용돠는 GraphQL과 Relay에 대해서 발표를 하게 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;GraphQL&lt;/span&gt;은&lt;span&gt; &lt;/span&gt;사용해본&lt;span&gt; &lt;/span&gt;경험이&lt;span&gt; &lt;/span&gt;있으나&lt;span&gt; &lt;/span&gt;다른&lt;span&gt; &lt;/span&gt;사람들&lt;span&gt; &lt;/span&gt;앞에서&lt;span&gt; &lt;/span&gt;발표하기에는&lt;span&gt; &lt;/span&gt;가지고&lt;span&gt; &lt;/span&gt;있는&lt;span&gt; &lt;/span&gt;지식이&lt;span&gt; &lt;/span&gt;부족했고&lt;span&gt; Relay&lt;/span&gt;는&lt;span&gt; &lt;/span&gt;처음들어본&lt;span&gt; &lt;/span&gt;라이브러리였기&lt;span&gt; &lt;/span&gt;때문에&lt;span&gt;, Pebble Seminar&lt;/span&gt;를&lt;span&gt; &lt;/span&gt;준비하는데&lt;span&gt; &lt;/span&gt;있어&lt;span&gt; &lt;/span&gt;많이&lt;span&gt; &lt;/span&gt;걱정되고&lt;span&gt;, &lt;/span&gt;많은&lt;span&gt; &lt;/span&gt;문서들을&lt;span&gt; &lt;/span&gt;읽으면서&lt;span&gt; &lt;/span&gt;준비했다&lt;span&gt;. &lt;/span&gt;우선&lt;span&gt; GraphQL&lt;/span&gt;과&lt;span&gt; Relay &lt;/span&gt;공식&lt;span&gt; &lt;/span&gt;문서들을&lt;span&gt; &lt;/span&gt;읽으면서&lt;span&gt; &lt;/span&gt;개념을&lt;span&gt; &lt;/span&gt;익혔고&lt;span&gt;, Backend.AI &lt;/span&gt;코드들을&lt;span&gt; &lt;/span&gt;하나씩&lt;span&gt; &lt;/span&gt;분석하면서&lt;span&gt; Backend.AI&lt;/span&gt;에서는&lt;span&gt; &lt;/span&gt;어떻게&lt;span&gt; &lt;/span&gt;적용이되었고&lt;span&gt;, &lt;/span&gt;어떻게&lt;span&gt; &lt;/span&gt;동작하는지에&lt;span&gt; &lt;/span&gt;대해서&lt;span&gt; &lt;/span&gt;파악했다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pQsPT/btsFmfRiOAp/Szz7ZOZ5xP4yfKRcDFBxp1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pQsPT/btsFmfRiOAp/Szz7ZOZ5xP4yfKRcDFBxp1/img.jpg&quot; data-origin-width=&quot;2400&quot; data-origin-height=&quot;3044&quot; data-is-animation=&quot;false&quot; data-filename=&quot;KakaoTalk_Photo_2024-02-29-14-07-20 002.jpeg&quot; width=&quot;439&quot; height=&quot;557&quot; style=&quot;width: 49.7677%; margin-right: 10px;&quot; data-widthpercent=&quot;50.35&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pQsPT/btsFmfRiOAp/Szz7ZOZ5xP4yfKRcDFBxp1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpQsPT%2FbtsFmfRiOAp%2FSzz7ZOZ5xP4yfKRcDFBxp1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2400&quot; height=&quot;3044&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/srGQ0/btsFjW5UaRW/VdtoUsCjj7ZBTILbJV7HHK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/srGQ0/btsFjW5UaRW/VdtoUsCjj7ZBTILbJV7HHK/img.jpg&quot; data-origin-width=&quot;2584&quot; data-origin-height=&quot;3324&quot; data-is-animation=&quot;false&quot; data-filename=&quot;KakaoTalk_Photo_2024-02-29-14-07-19 001.jpeg&quot; width=&quot;458&quot; height=&quot;589&quot; style=&quot;width: 49.0696%;&quot; data-widthpercent=&quot;49.65&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/srGQ0/btsFjW5UaRW/VdtoUsCjj7ZBTILbJV7HHK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsrGQ0%2FbtsFjW5UaRW%2FVdtoUsCjj7ZBTILbJV7HHK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2584&quot; height=&quot;3324&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;Pebble Seminar 준비 자료&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Pebble Seminar&lt;/span&gt;를&lt;span&gt; &lt;/span&gt;준비하면서&lt;span&gt; &lt;/span&gt;코드륵&lt;span&gt; &lt;/span&gt;분석하다보니&lt;span&gt;, WebUI&lt;/span&gt;에서&lt;span&gt; &lt;/span&gt;동작하고&lt;span&gt; &lt;/span&gt;있는&lt;span&gt; &lt;/span&gt;코드들을&lt;span&gt; &lt;/span&gt;자연스럽게&lt;span&gt; &lt;/span&gt;이해하게되었고&lt;span&gt;, &lt;/span&gt;이후&lt;span&gt; &lt;/span&gt;이슈들을&lt;span&gt; &lt;/span&gt;해결하는&lt;span&gt; &lt;/span&gt;과정에서&lt;span&gt; &lt;/span&gt;조금&lt;span&gt; &lt;/span&gt;더&lt;span&gt; &lt;/span&gt;쉽게&lt;span&gt; &lt;/span&gt;문제가&lt;span&gt; &lt;/span&gt;발생하는&lt;span&gt; &lt;/span&gt;코드를&lt;span&gt; &lt;/span&gt;찾고&lt;span&gt;, &lt;/span&gt;해결하는데&lt;span&gt; &lt;/span&gt;큰&lt;span&gt; &lt;/span&gt;도움이&lt;span&gt; &lt;/span&gt;되었다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Backend.AI &lt;span&gt;이슈&lt;/span&gt; &lt;span&gt;해결&lt;/span&gt; &lt;span&gt;및&lt;/span&gt; &lt;span&gt;기능&lt;/span&gt; &lt;span&gt;구현&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;온보딩을 마치고, 드디어 프론트엔드 팀에 합류하여 Backend.AI 이슈를 해결하고 기능 구현을 시작했다. 나는 프론트엔드 리더분과 커피챗을 가지며 이번 인턴십 기간 업무 카테고리를 정했다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Table Column Setting 컴포넌트 제작&lt;/li&gt;
&lt;li&gt;E2E Test 관련 조사&lt;/li&gt;
&lt;li&gt;데일리 업무&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;11월부터 12월까지 8주간 진행된 인턴십 기간에서 총 19개의 Pull Request를 작성했고, 그 중 18개가 Merge되고 1개는 리뷰가 진행중인 상태이다. 컨트리뷰션&lt;span&gt; &lt;/span&gt;아카데이를&lt;span&gt; &lt;/span&gt;활동하면서&lt;span&gt; &lt;/span&gt;이슈를&lt;span&gt; &lt;/span&gt;찾고&lt;span&gt;, &lt;/span&gt;할당하는데&lt;span&gt; &lt;/span&gt;있어서&lt;span&gt; &lt;/span&gt;어려움이&lt;span&gt; &lt;/span&gt;적었고&lt;span&gt;, &lt;/span&gt;이슈를&lt;span&gt; &lt;/span&gt;해결하는데&lt;span&gt; &lt;/span&gt;재미를&lt;span&gt; &lt;/span&gt;느껴서&lt;span&gt; &lt;/span&gt;남들보다&lt;span&gt; &lt;/span&gt;더&lt;span&gt; &lt;/span&gt;많은&lt;span&gt; &lt;/span&gt;이슈들을&lt;span&gt; &lt;/span&gt;해결할&lt;span&gt; &lt;/span&gt;수&lt;span&gt; &lt;/span&gt;있었다&lt;span&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span&gt;기능 추가 PR&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1. Table Columns Setting 구현&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/lablup/backend.ai-webui/pull/2071&quot;&gt;https://github.com/lablup/backend.ai-webui/pull/2071&lt;/a&gt;&lt;br /&gt;&lt;span&gt;인턴십&lt;/span&gt; &lt;span&gt;기간에서&lt;/span&gt; &lt;span&gt;목표로&lt;/span&gt; &lt;span&gt;했던&lt;/span&gt; &lt;span&gt;이슈&lt;/span&gt; &lt;span&gt;중&lt;/span&gt; &lt;span&gt;하나였다&lt;/span&gt;. 가을 인턴 기간에서 유일하게 기존에 있던 컴포넌트를 리팩토링이 아닌, 처음부터 구상하고 구현했다. 이 기능을 구현하기 전에는 간단한 기능이고 금방 끝낼 수 있을거라고 생각했지만 생각과 다르게 흘러갔다.&lt;br /&gt;우선 이전까지는 컴포넌트를 새롭게 만드는 것을 너무 쉽게 생각했구나를 많이 느꼈다. 이전에도 컴포넌트를 만들기 전에 디자인하고, 전달받을 props들을 생각하긴 했지만, 해당 이슈를 통해서 컴포넌트를 새롭게 만들 때, 확장성을 생각해서 조금 더 시간과 노력을 투자해야한다고 느꼈었다. 또한 다른 사이트들은 어떤 식으로 디자인되어 있는지, 적용된 기능들이 무엇이 있는지 좀 더 관심있게 봐야겠다를 느낄 수있었다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-02-29 오후 2.36.31.png&quot; data-origin-width=&quot;3104&quot; data-origin-height=&quot;1974&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uQG4U/btsFoFhoBqX/09gwBUISKRcN78xjTQXDf0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uQG4U/btsFoFhoBqX/09gwBUISKRcN78xjTQXDf0/img.png&quot; data-alt=&quot;Table Columns Setting&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uQG4U/btsFoFhoBqX/09gwBUISKRcN78xjTQXDf0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuQG4U%2FbtsFoFhoBqX%2F09gwBUISKRcN78xjTQXDf0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3104&quot; height=&quot;1974&quot; data-filename=&quot;스크린샷 2024-02-29 오후 2.36.31.png&quot; data-origin-width=&quot;3104&quot; data-origin-height=&quot;1974&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Table Columns Setting&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2. 모델 서빙 페이지 Table에 서비스 엔드포인트와 소유자 Column 추가&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/lablup/backend.ai-webui/pull/2047&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/lablup/backend.ai-webui/pull/2047&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존에는 모델 서비스를 만들고 나면 endpoint를 상세 페이지에 들어가서 확인해야하는데, 자주 사용하는 기능이다보니 Table Column에 추가되었으면 하는 요청이 있었다. 또한 admin 계정에서는 같은 그룹에 속한 유저의 서비스도 다 보여지기 때문에, 소유자가 누구인지도 나타 낼 수 있는 Column이 보여지면 좋겠다는 의견이 있었다. 해당 기능을 구현하기 위한 GraphQL field는 이미 구현되어있었기 때문에 데이터를 받아오는 query의 field를 추가하여 엔드포인트와 서비스 소유자의 데이터를 받아왔고, Table의 Column을 추가하여 데이터를 나타냈다. 소유자 Column은 Admin 권한을 가진 계정에만 나타난다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bxiDFI/btsFsbGIs3c/UjOR8kk0KkNAv08q6ZIVik/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bxiDFI/btsFsbGIs3c/UjOR8kk0KkNAv08q6ZIVik/img.png&quot; data-is-animation=&quot;false&quot; data-origin-width=&quot;3104&quot; data-origin-height=&quot;1974&quot; data-filename=&quot;스크린샷 2024-02-29 오후 3.57.07.png&quot; style=&quot;width: 49.4186%; margin-right: 10px;&quot; data-widthpercent=&quot;50&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bxiDFI/btsFsbGIs3c/UjOR8kk0KkNAv08q6ZIVik/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbxiDFI%2FbtsFsbGIs3c%2FUjOR8kk0KkNAv08q6ZIVik%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3104&quot; height=&quot;1974&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ddQ40D/btsFm6mba1q/ZCswrlzX4CF4J1151TwYRk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ddQ40D/btsFm6mba1q/ZCswrlzX4CF4J1151TwYRk/img.png&quot; data-is-animation=&quot;false&quot; data-origin-width=&quot;3104&quot; data-origin-height=&quot;1974&quot; data-filename=&quot;스크린샷 2024-02-29 오후 3.56.46.png&quot; style=&quot;width: 49.4186%;&quot; data-widthpercent=&quot;50&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ddQ40D/btsFm6mba1q/ZCswrlzX4CF4J1151TwYRk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FddQ40D%2FbtsFm6mba1q%2FZCswrlzX4CF4J1151TwYRk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3104&quot; height=&quot;1974&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;구현 모습. Admin 계정에서 나오는 화면(왼쪽) 과 User계정에서 나오는 화면(오른쪽)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;3. CANCELLED 상태인 세션의 로그 버튼 비활성화&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/lablup/backend.ai-webui/pull/2045&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/lablup/backend.ai-webui/pull/2045&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CANCELLED 상태는 컨테이너가 생성된 적이 없거나 생성에 실패한 상태이다. 기존에는 CANCELLED 상태인 세션에도 로그 버튼이 활성화 되어있어, 사용자가 로그 버튼을 누르게된다면 에이전트가 컨테이너 정보를 찾을 수 없어 500에러가 나타났다. 그래서 해당 PR에서 CANCELLED 상태인 세션은 사용자들이 로그 버튼을 누를 수 없게 비활성화 하는 작업을 진행했다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-02-29 오후 4.12.39.png&quot; data-origin-width=&quot;3104&quot; data-origin-height=&quot;1974&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bj4vB0/btsFr9oBsj9/Wa7qYKAfOgm9uZiXbIvVpk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bj4vB0/btsFr9oBsj9/Wa7qYKAfOgm9uZiXbIvVpk/img.png&quot; data-alt=&quot;TERMINATED 상태의 세션(1번 세션)과 CANCELLED 상태의 세션(2번 세션)&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bj4vB0/btsFr9oBsj9/Wa7qYKAfOgm9uZiXbIvVpk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbj4vB0%2FbtsFr9oBsj9%2FWa7qYKAfOgm9uZiXbIvVpk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3104&quot; height=&quot;1974&quot; data-filename=&quot;스크린샷 2024-02-29 오후 4.12.39.png&quot; data-origin-width=&quot;3104&quot; data-origin-height=&quot;1974&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;TERMINATED 상태의 세션(1번 세션)과 CANCELLED 상태의 세션(2번 세션)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;4. Dark mode를 위한 테스트 및 custom hook 제작&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/lablup/backend.ai-webui/pull/2120&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/lablup/backend.ai-webui/pull/2120&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Dark mode를 적용하기 전 색깔을 하드코딩한 컴포넌트를 찾고, Dark mode 적용하기 위한 useThemeMode라는 이름의 custom hook을 구현했다. Custom hook을 만들 때 ahooks의 useLocalStorageState hook을 사용해서 구현하려고 했으나, 같은 Key값을 사용하는 state에 대해서 자동으로 state 관리가 되는 줄 알았으나 예상과 다르게 독립적으로 동작하는 것을 확인했다. 그래서 같은 Key값을 사용하는 state에 대해서 값이 바뀌면 자동으로 바뀌도록 구현하기 위해 useLocalStorageGlobalState 라는 이름의 custom hook을 추가했고, 해당 hook을 사용해서 Dark mode를 설정할 수 있는 useThemeMode라는 custom hook을 만들 수 있었다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Bug fix PR&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1. 초대 토큰 값 없이 회원가입 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/lablup/backend.ai-webui/pull/2046&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/lablup/backend.ai-webui/pull/2046&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;config.toml에서 allowSignupWithoutConfirmation이라는 옵션을 true로 변경하게되면, 초대 토큰없이 회원가입이 가능한데, 사용자가 회원가입 버튼을 누르게되면, 토큰 값이 undefined되어 있다고 에러를 발생했었다. 따라서 해당 PR에서는 allowSignupWithoutConfrimation의 옵션이 true면 token 변수를 사용하지 않도록 수정했다. 또한 이전에는 회원가입 버튼을 누르고 나서 core쪽에서 데이터를 처리하는 동안 다른 입력 값들을 수정할 수 있었으며, dialog가 닫힌 뒤, 다시 열면 이전 데이터가 남아있는 이슈가 있었는데, 해당 PR에서 데이터를 처리하는 동안 다른 입력 값들을 입력할 수 없게 설정했으며, dialog가 닫히면 이전에 입력한 값들이 clear되도록 설정했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2. 사용자 관리 페이지에서 서브 탭에 맞는 화면 표시&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/lablup/backend.ai-webui/pull/2055&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/lablup/backend.ai-webui/pull/2055&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사용자 관리 페이지에는 활성화 상태인 사용자와, 비활성화 상태인 사용자들을 보여줄 수 있는 서브 탭이 존재한다. 하지만 해당 페이지에서 작업을 하다가 다른 페이지로 이동한 뒤 다시 사용자 관리 페이지로 돌아오면 서브 탭은 비활성으로 되어있지만, 실제 화면에는 활성화 상태인 사용자 리스트들이 나오는 문제가 있었다. 해당 문제는 사용자들에게 혼란을 줄 수 있는 부분이라 생각했고, 해당 PR에서 수정하게 되었다. 다른 페이지로 이동할 때, 현재 작업중인 서브 탭이 무엇인지 기억하여, 다시 해당 페이지로 돌아왔을 때 이전에 작업했던 서브 탭과 관련된 화면을 나타낼 수 있도록 수정했다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EfiKi/btsFmjNe0wU/rFH4sIPkgG8VW7CHcdLhbK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EfiKi/btsFmjNe0wU/rFH4sIPkgG8VW7CHcdLhbK/img.png&quot; data-is-animation=&quot;false&quot; data-origin-width=&quot;1143&quot; data-origin-height=&quot;498&quot; data-filename=&quot;285569733-627d7bfd-c18f-42ad-8112-e9d8c41e98e4.png&quot; style=&quot;width: 58.6534%; margin-right: 10px;&quot; data-widthpercent=&quot;59.34&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EfiKi/btsFmjNe0wU/rFH4sIPkgG8VW7CHcdLhbK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEfiKi%2FbtsFmjNe0wU%2FrFH4sIPkgG8VW7CHcdLhbK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1143&quot; height=&quot;498&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/24G2c/btsFnXwd9bw/3tx0DAboAFcelhBf8t5X51/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/24G2c/btsFnXwd9bw/3tx0DAboAFcelhBf8t5X51/img.png&quot; data-origin-width=&quot;3104&quot; data-origin-height=&quot;1974&quot; data-is-animation=&quot;false&quot; data-filename=&quot;스크린샷 2024-03-01 오후 9.12.26.png&quot; style=&quot;width: 40.1838%;&quot; data-widthpercent=&quot;40.66&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/24G2c/btsFnXwd9bw/3tx0DAboAFcelhBf8t5X51/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F24G2c%2FbtsFnXwd9bw%2F3tx0DAboAFcelhBf8t5X51%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3104&quot; height=&quot;1974&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;수정 전 사진(왼쪽)과 수정 후 사진(오른쪽)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;인턴 기간 연장&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이슈를 해결하다보니 8주라는 시간은 금방 지나갔고, 가을 인턴을 마무리해야하는 시간이 찾아왔다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;군대를 전역하고 개발자로서 첫 사회생활이라 중요한 시기였는데 래블업에서 인턴을 하면서 나의 부족한 점이 무엇인지, 어떤 부분을 더 준비해야하는지, 다른 분들은 어떻게 개발을 하는지 등등 을 많이 느낄 수 있는 기간이었다. 2달이라는 시간이 매우 짧게 느껴졌고, 2달동안 매우 즐겁게 일을 했기 때문에, 좀 더 일해보고 싶다라는 생각이 들었다. 그래서 리더분께 인턴십 기간을 연장하고 싶다는 의견을 말씀드렸고, 8주를 더 연장하여 2월까지 인턴십을 진행하기로 했다. 그리고 가을 인턴에서는 나의 부족한 부분에 대해서는 많이 생각이 났지만, 나의 장점을 찾지 못했다. 그래서 아래 3가지 개인적인 목표를 세우며 시작하기로 다짐했다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;이번 기간에는 장점을 찾자&lt;/li&gt;
&lt;li&gt;시간이 될 때마다 document를 읽자&lt;/li&gt;
&lt;li&gt;아쉬움이 없을만큼 더 열심히 일해보자&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;연장된 기간 이슈 해결 및 기능 구현&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;연장된 기간에 하는 일이 이전과 크게 다르지 않았다. 온보딩 기간과 설치과정이 없어 이슈 해결에 좀 더 집중할 수 있는 기간이었다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;기능 추가 PR&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1. ErrorLogList 리팩토링&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/lablup/backend.ai-webui/pull/2131&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/lablup/backend.ai-webui/pull/2131&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;기존 Lit element로 구현되어 있던 ErrorLog List를 React로 리팩토링을 진행했다. &lt;span style=&quot;color: #000000;&quot;&gt;해당 기능들은&lt;span&gt;&amp;nbsp;리팩토링을&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;하고나서 개인적으로도 잘 사용하고 있어 가장 만족스러운 이슈였다&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bPC2n0/btsFnXJLlWJ/eaBGFkHdYK5UWL5RSGVg6k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bPC2n0/btsFnXJLlWJ/eaBGFkHdYK5UWL5RSGVg6k/img.png&quot; data-is-animation=&quot;false&quot; data-origin-width=&quot;2434&quot; data-origin-height=&quot;824&quot; data-filename=&quot;293842684-71144f1d-df8c-481d-b3bd-36b1b780ce06.png&quot; style=&quot;width: 64.5012%; margin-right: 10px;&quot; data-widthpercent=&quot;65.26&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bPC2n0/btsFnXJLlWJ/eaBGFkHdYK5UWL5RSGVg6k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbPC2n0%2FbtsFnXJLlWJ%2FeaBGFkHdYK5UWL5RSGVg6k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2434&quot; height=&quot;824&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nYyUW/btsFs1jTzJj/OtOSvpB9zqBAqlwwmbaqik/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nYyUW/btsFs1jTzJj/OtOSvpB9zqBAqlwwmbaqik/img.png&quot; data-origin-width=&quot;3104&quot; data-origin-height=&quot;1974&quot; data-is-animation=&quot;false&quot; data-filename=&quot;스크린샷 2024-03-01 오후 9.39.55.png&quot; style=&quot;width: 34.336%;&quot; data-widthpercent=&quot;34.74&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nYyUW/btsFs1jTzJj/OtOSvpB9zqBAqlwwmbaqik/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnYyUW%2FbtsFs1jTzJj%2FOtOSvpB9zqBAqlwwmbaqik%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3104&quot; height=&quot;1974&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;리팩토링 전(왼쪽)과 리팩토링 후(오른쪽) 사진&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;리팩토링&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;을 진행하면서 기존에는 없었던 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Search &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;기능과 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Error&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;filter&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 기능이 추가되었다&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bfFlo8/btsFobHUaeF/XirLHn0IHyWAX9BEUFKJJk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bfFlo8/btsFobHUaeF/XirLHn0IHyWAX9BEUFKJJk/img.png&quot; data-origin-width=&quot;3104&quot; data-origin-height=&quot;1974&quot; data-is-animation=&quot;false&quot; data-filename=&quot;스크린샷 2024-03-01 오후 9.38.33.png&quot; style=&quot;width: 49.4186%; margin-right: 10px;&quot; data-widthpercent=&quot;50&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bfFlo8/btsFobHUaeF/XirLHn0IHyWAX9BEUFKJJk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbfFlo8%2FbtsFobHUaeF%2FXirLHn0IHyWAX9BEUFKJJk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3104&quot; height=&quot;1974&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/1I98R/btsFsnAz3Mz/flLQuiA1Tdbo8iZawJSgi0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/1I98R/btsFsnAz3Mz/flLQuiA1Tdbo8iZawJSgi0/img.png&quot; data-is-animation=&quot;false&quot; data-origin-width=&quot;3104&quot; data-origin-height=&quot;1974&quot; data-filename=&quot;스크린샷 2024-03-01 오후 9.38.51.png&quot; style=&quot;width: 49.4186%;&quot; data-widthpercent=&quot;50&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/1I98R/btsFsnAz3Mz/flLQuiA1Tdbo8iZawJSgi0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F1I98R%2FbtsFsnAz3Mz%2FflLQuiA1Tdbo8iZawJSgi0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3104&quot; height=&quot;1974&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;추가된 Search 기능(왼쪽)과 Filter 기능(오른쪽)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Search&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;로 원하는 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Error&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;와 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;log&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;를&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 찾을 수 있으며 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;error filter&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;를&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 체크하면 에러에 해당하는 로그만 볼 수 있다&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size18&quot;&gt;2. Modal 드래그 기능&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/lablup/backend.ai-webui/pull/2179&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/lablup/backend.ai-webui/pull/2179&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;React-draggable &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;라이브러리를 사용하여 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Modal&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;drag&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;될 수 있도록 기능을 추가했다&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;. &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Modal&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;에 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Draggable props&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;를&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 추가하여 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;drag&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;가 필요한 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;modal&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;에서 적용할 수 있다&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-03-01 오후 9.48.24.png&quot; data-origin-width=&quot;3104&quot; data-origin-height=&quot;1974&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bEvEGK/btsFqNNb3ZI/JKO0Rhv6kjstemh6blAtuK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bEvEGK/btsFqNNb3ZI/JKO0Rhv6kjstemh6blAtuK/img.png&quot; data-alt=&quot;드래그 가능한 Modal&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bEvEGK/btsFqNNb3ZI/JKO0Rhv6kjstemh6blAtuK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbEvEGK%2FbtsFqNNb3ZI%2FJKO0Rhv6kjstemh6blAtuK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3104&quot; height=&quot;1974&quot; data-filename=&quot;스크린샷 2024-03-01 오후 9.48.24.png&quot; data-origin-width=&quot;3104&quot; data-origin-height=&quot;1974&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;드래그 가능한 Modal&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Modal 제목 왼쪽에 있는 아이콘을 클릭하면서 마우스를 움직이면 Modal을 화면에 원하는 위치로 이동시킬 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;현재는 사용자 관리페이지&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;의 사용자 정보를 볼 수 있는 Modal&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;과 사용자 설정을 변경할 수 있는 Modal&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;에 적용되어 있어 확인할 수 있다.&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure data-ke-type=&quot;video&quot; data-ke-style=&quot;alignCenter&quot; data-video-host=&quot;kakaotv&quot; data-video-url=&quot;https://tv.kakao.com/v/444997096&quot; data-video-thumbnail=&quot;https://scrap.kakaocdn.net/dn/be2xZw/hyVuf7tumI/X0AI4IaiVlNN8Aodk6xyek/img.jpg?width=1728&amp;amp;height=1080&amp;amp;face=0_0_1728_1080,https://scrap.kakaocdn.net/dn/bpXwhb/hyVumyLIUt/kMEElXrQcFYVBkW14NMJLK/img.jpg?width=1728&amp;amp;height=1080&amp;amp;face=0_0_1728_1080&quot; data-video-width=&quot;860&quot; data-video-height=&quot;538&quot; data-video-origin-width=&quot;860&quot; data-video-origin-height=&quot;538&quot; data-ke-mobilestyle=&quot;widthContent&quot; data-video-play-service=&quot;daum_tistory&quot; data-original-url=&quot;&quot; data-video-title=&quot;&quot;&gt;&lt;iframe src=&quot;https://play-tv.kakao.com/embed/player/cliplink/444997096?service=daum_tistory&quot; width=&quot;860&quot; height=&quot;538&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;
&lt;figcaption style=&quot;display: none;&quot;&gt;&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;아직은 사용되는 곳이 많지는 않지만&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 점점 컴포넌트들이 늘어나고&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;,&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 기능들이 추가되면서 유용하게 사용될 수 있다고 생각한 &lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;PR&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이었다&lt;/span&gt;&lt;span style=&quot;color: #000000;&quot;&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;Bug fix PR&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;1. Vfolder 초대 권한 수정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/lablup/backend.ai-webui/pull/2143&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/lablup/backend.ai-webui/pull/2143&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Group vfolder 사용자 권한이 수정되지 않는 문제가 있었다. 권한을 수정하려고 하면 select에서 item들이 제대로 표시 및 선택이 되지 않는 문제가 있었다. 기존에는 option 태그를 사용해서 item들을 표시해주고 있었는데, mwc-list-item으로 변경하여 item들을 표시해주었고, overflow 옵션을 수정하여 해당 이슈를 해결했다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/boLx4t/btsFqYnFzVj/r2yMV43fy02oJD3bevtftK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/boLx4t/btsFqYnFzVj/r2yMV43fy02oJD3bevtftK/img.png&quot; data-is-animation=&quot;false&quot; data-origin-width=&quot;656&quot; data-origin-height=&quot;1131&quot; data-filename=&quot;295816278-50a4254d-2e7a-4873-b389-9f9f14a9a8df.png&quot; style=&quot;width: 26.6334%; margin-right: 10px;&quot; data-widthpercent=&quot;26.95&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/boLx4t/btsFqYnFzVj/r2yMV43fy02oJD3bevtftK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FboLx4t%2FbtsFqYnFzVj%2Fr2yMV43fy02oJD3bevtftK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;656&quot; height=&quot;1131&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dJCB08/btsFm3XTP4m/GDAK686J7oWuRH26kKACX1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dJCB08/btsFm3XTP4m/GDAK686J7oWuRH26kKACX1/img.png&quot; data-origin-width=&quot;3104&quot; data-origin-height=&quot;1974&quot; data-is-animation=&quot;false&quot; data-filename=&quot;스크린샷 2024-03-02 오후 8.51.13.png&quot; style=&quot;width: 72.2038%;&quot; data-widthpercent=&quot;73.05&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dJCB08/btsFm3XTP4m/GDAK686J7oWuRH26kKACX1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdJCB08%2FbtsFm3XTP4m%2FGDAK686J7oWuRH26kKACX1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3104&quot; height=&quot;1974&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;PR 전 사진(왼쪽)과 PR 후 사진(오른쪽)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;2. ResourceGroupSelect이 Card밖으로 나가는 문제&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/lablup/backend.ai-webui/pull/2166&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/lablup/backend.ai-webui/pull/2166&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ResourceGroupSelect의 값이 너무 크면 Card밖으로 표시가 되는 문제가 있었다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bkkBQ7/btsFqYOJKcV/SbdZMnbBWMzhv3y9bNy6j1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bkkBQ7/btsFqYOJKcV/SbdZMnbBWMzhv3y9bNy6j1/img.png&quot; data-origin-width=&quot;3664&quot; data-origin-height=&quot;3054&quot; data-is-animation=&quot;false&quot; data-filename=&quot;298866980-682808f8-77b4-40c6-aa45-7a3aa1aad4fa.png&quot; style=&quot;width: 49.4186%; margin-right: 10px;&quot; data-widthpercent=&quot;50&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bkkBQ7/btsFqYOJKcV/SbdZMnbBWMzhv3y9bNy6j1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbkkBQ7%2FbtsFqYOJKcV%2FSbdZMnbBWMzhv3y9bNy6j1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3664&quot; height=&quot;3054&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qBqC3/btsFt6S0f9W/lOOEF2CKZUKCp8NhArhxJ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qBqC3/btsFt6S0f9W/lOOEF2CKZUKCp8NhArhxJ0/img.png&quot; data-origin-width=&quot;3664&quot; data-origin-height=&quot;3054&quot; data-is-animation=&quot;false&quot; data-filename=&quot;298867028-6404d7f6-7d9e-46d4-bac6-08760debf75e.png&quot; style=&quot;width: 49.4186%;&quot; data-widthpercent=&quot;50&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qBqC3/btsFt6S0f9W/lOOEF2CKZUKCp8NhArhxJ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqBqC3%2FbtsFt6S0f9W%2FlOOEF2CKZUKCp8NhArhxJ0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3664&quot; height=&quot;3054&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;문제가 되었던 증상들&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 문제를 해결하기 위해서 Select에 max-width css를 설정하여 Card의 width를 넘지 못하도록 하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한 해당 PR에서 Select에서 Search기능을 추가했는데, 해당 기능을 추가하면서 ahooks의 useControllableValue라는 hook을 사용했다. useControllableValue는 부모나 자신이 props를 관리할 수 있게 도와주는 hook이다. 간단한 PR이었지만 useControllableValue를 처음 사용하다보니 생각보다 시간이 오래 걸린 PR이었다. 해당 이슈를 해결하면서 리더분과 다른 인턴분의 도움을 받아 해결할 수 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;3. 요약 페이지에서 키페어 생성&amp;amp;관리 버튼 눌렀을 때 키페어 리스트가 보여지지 않는 문제&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/lablup/backend.ai-webui/pull/2194&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/lablup/backend.ai-webui/pull/2194&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요약 페이지에는 &lt;b&gt;새 키페어 생성&lt;/b&gt;, &lt;b&gt;키페어 관리&lt;/b&gt; 라는 버튼이 있는데, 해당 버튼을 누르면 단순히 사용자 관리 페이지로 이동하여 키페어 리스트가 아닌 유저 리스트가 보여지는 이슈가 있었다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;299544804-c4c54d12-4432-46a2-a5a3-25124602d9ec.png&quot; data-origin-width=&quot;374&quot; data-origin-height=&quot;530&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b2uazG/btsFnYhNiZq/DRhUW0ssypuCt47Ak7pXMK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b2uazG/btsFnYhNiZq/DRhUW0ssypuCt47Ak7pXMK/img.png&quot; data-alt=&quot;요약 페이지에서 새 키페어 생성 버튼과 키페어 관리 버튼&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b2uazG/btsFnYhNiZq/DRhUW0ssypuCt47Ak7pXMK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb2uazG%2FbtsFnYhNiZq%2FDRhUW0ssypuCt47Ak7pXMK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;374&quot; height=&quot;530&quot; data-filename=&quot;299544804-c4c54d12-4432-46a2-a5a3-25124602d9ec.png&quot; data-origin-width=&quot;374&quot; data-origin-height=&quot;530&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;요약 페이지에서 새 키페어 생성 버튼과 키페어 관리 버튼&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/coalp4/btsFuK3pDKk/KvlRyKYRlxljT3PbGHrly0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/coalp4/btsFuK3pDKk/KvlRyKYRlxljT3PbGHrly0/img.png&quot; data-origin-width=&quot;3664&quot; data-origin-height=&quot;3054&quot; data-is-animation=&quot;false&quot; data-filename=&quot;299545011-3a5ac46a-4580-4d97-aa8d-287d0ef889b5.png&quot; style=&quot;width: 49.4186%; margin-right: 10px;&quot; data-widthpercent=&quot;50&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/coalp4/btsFuK3pDKk/KvlRyKYRlxljT3PbGHrly0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcoalp4%2FbtsFuK3pDKk%2FKvlRyKYRlxljT3PbGHrly0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3664&quot; height=&quot;3054&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NBuZp/btsFoJLhDX0/yE3bI2Q6pkSL9keLQAMEGK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NBuZp/btsFoJLhDX0/yE3bI2Q6pkSL9keLQAMEGK/img.png&quot; data-origin-width=&quot;3664&quot; data-origin-height=&quot;3054&quot; data-is-animation=&quot;false&quot; data-filename=&quot;299545176-132b9dfb-aceb-48f8-9a4a-c9750fa48039.png&quot; style=&quot;width: 49.4186%;&quot; data-widthpercent=&quot;50&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NBuZp/btsFoJLhDX0/yE3bI2Q6pkSL9keLQAMEGK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNBuZp%2FbtsFoJLhDX0%2FyE3bI2Q6pkSL9keLQAMEGK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3664&quot; height=&quot;3054&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;새 키페어 생성 버튼을 눌렀을 때(왼쪽) 과 키페어 관리를 눌렀을 때(오른쪽)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 이슈는 크리티컬한 이슈는 아니었지만, 내가 처음으로 Backend.AI를 사용해보면서 키페어라는 기능을 잘 이해하지 못했을 때, 많이 혼동이 있었던 경험때문에 해결했었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 이슈를 해결하고 나서는 의도한 대로 키페어 리스트들이 화면에 나타나는 것을 확인할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uX19x/btsFsZ0PWgd/6xv4ExXwGkoTguMNBDiH6K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uX19x/btsFsZ0PWgd/6xv4ExXwGkoTguMNBDiH6K/img.png&quot; data-origin-width=&quot;3104&quot; data-origin-height=&quot;1974&quot; data-is-animation=&quot;false&quot; data-filename=&quot;스크린샷 2024-03-02 오후 9.10.33.png&quot; style=&quot;width: 49.4186%; margin-right: 10px;&quot; data-widthpercent=&quot;50&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uX19x/btsFsZ0PWgd/6xv4ExXwGkoTguMNBDiH6K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuX19x%2FbtsFsZ0PWgd%2F6xv4ExXwGkoTguMNBDiH6K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3104&quot; height=&quot;1974&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qgbVt/btsFt3PxSM3/pv2HBgmZzC6TszyYKoLfB1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qgbVt/btsFt3PxSM3/pv2HBgmZzC6TszyYKoLfB1/img.png&quot; data-origin-width=&quot;3104&quot; data-origin-height=&quot;1974&quot; data-is-animation=&quot;false&quot; data-filename=&quot;스크린샷 2024-03-02 오후 9.10.43.png&quot; style=&quot;width: 49.4186%;&quot; data-widthpercent=&quot;50&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qgbVt/btsFt3PxSM3/pv2HBgmZzC6TszyYKoLfB1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqgbVt%2FbtsFt3PxSM3%2Fpv2HBgmZzC6TszyYKoLfB1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3104&quot; height=&quot;1974&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
  &lt;figcaption&gt;이슈를 해결 한 뒤 새 키페어 생성 버튼을 눌렀을 때(왼쪽) 과 키페어 관리를 눌렀을 때(오른쪽)&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;인턴십을 마치며&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전역을하고 친구의 추천을 시작하게된 컨트리뷰션 아카데미를 인연으로 래블업에서 긴 시간동안 기여를 할 수 있었다. 이전에 다른 회사의 인턴 경험, 프로젝트 경험이 없었기 때문에, 전역을 한 뒤 새롭게 시작하는 나한텐 있어서 매우 중요한 시기였는데, 래블업에서 활동할 수 있어서 나의 장단점, 부족한 기술, 오픈소스 회사의 문화 등을 경험할 수 있어서 너무 좋았다. 수평적인 구조, 자유로운 분위기, 쾌적한 근무 환경과 좋은 장비들 까지 매일 출근하고 싶게 만드는 회사가 몇이나 있을까? 4개월을 래블업에서 근무했지만, 매일 출근하고 싶고, 래블업이라면 내가 오랫동안 재미있고 원하는 일을 하면서 회사를 다닐 수 있겠다 라고 생각이 들었다. 4개월이라는 시간동안 래블업에서 서비스하고 있는 Backend.AI에도 정이 들어서, 매년 래블업에서 주최하는 컨퍼런스도 시간이 될 때마다 참가하여 발전된 모습과, 기술들을 보러 갈 예정이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;KakaoTalk_Photo_2024-03-02-21-17-43.jpeg&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cPAEtW/btsFqZUpN1V/zVrXyQkgZf5OUS8qwPA6Fk/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cPAEtW/btsFqZUpN1V/zVrXyQkgZf5OUS8qwPA6Fk/img.jpg&quot; data-alt=&quot;래블업 사무실&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cPAEtW/btsFqZUpN1V/zVrXyQkgZf5OUS8qwPA6Fk/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcPAEtW%2FbtsFqZUpN1V%2FzVrXyQkgZf5OUS8qwPA6Fk%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;4032&quot; height=&quot;3024&quot; data-filename=&quot;KakaoTalk_Photo_2024-03-02-21-17-43.jpeg&quot; data-origin-width=&quot;4032&quot; data-origin-height=&quot;3024&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;래블업 사무실&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>대학 &amp;amp; 일상 일기</category>
      <category>Backend.AI</category>
      <category>Lablup</category>
      <category>래블업</category>
      <category>오픈소스 컨트리뷰션 아카데미</category>
      <category>인턴</category>
      <category>인턴십</category>
      <author>일하는 개미</author>
      <guid isPermaLink="true">https://gee05053.tistory.com/32</guid>
      <comments>https://gee05053.tistory.com/32#entry32comment</comments>
      <pubDate>Sat, 2 Mar 2024 21:22:52 +0900</pubDate>
    </item>
    <item>
      <title>React를 왜 사용할까??</title>
      <link>https://gee05053.tistory.com/31</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;React란?&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;React는 JavaScript 라이브러리 중 하나로 UI를 만들기 위해서 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;React를 검색하면 SPA, Virtual DOM, Hook ... 등등 단어들이 따라오는데 이번 글에서 이것들을 한번에 정리하고자한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;SPA&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Single Page Aplication의 약자로 서버로 부터 완전한 새로운 페이지를 불러오지 않고 현재의 페이지를 동적으로 다시 작성함으로써 사용자와 소통하는 웹 어플리케이션이나 웹 사이트를 말한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존 전통적인 웹방식은 새로운 페이지를 요청할 때 마다 정적 리소스(CSS, 이미지, 영상...)가 다운로드 되고 전체 페이지를 다시 렌더링하는 방식이었다. 하지만 이런 방식은 규모가 커지면서 불필요한 트래픽이 증가하고 속도가 많이 느렸다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에서 React는 UI를 만들기 위해서 사용한다고 했는데 정확히는 SPA UI를 만들기 위해서 사용하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;React는 경로에 따라서 다른 뷰를 보여줄 수 있다. 하지만 여기서 Header, Footer, Navbar 과 같이 공통적으로 보여지는 부분이 있을 것이다. 경로가 바뀌어도 공통적으로 가지고 있는 컴포넌트들은 다시 요청하기 보다는 그대로 유지하고 변경되는 부분만 요청해서 불러오는 것이 좋다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Virtual DOM&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Virtual DOM은 DOM과 유사한 객체를 메모리에 올려 변경사항이 있으면 현재 DOM과 비교하여 변경된 부분만 실제 DOM에 적용시킬 수 있게 해주는 추상화 된 DOM이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 DOM을 조작하게 되면 레이아웃을 다시 계산하고 그려야하기 때문에 비용이 높은 작업이다. 하지만 Virtual DOM은 메모리 상에서만 동작하며 실제 DOM을 조작을 최소화한다. React는 Virtual DOM을 사용하여 렌더링이 조금 더 빠르게 일어날 수 있도록 해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 Virual DOM에도 단점이 있다. DOM과 동일한 구조가 메모리에 위치하기 때문에 추가적인 메모리를 사용한다. 이는 간단한 UI나 프로젝트에서는 불필요한 오버헤드일 수도 있다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Hook&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Hook은 기존 클래스 컴포넌트에서 사용가능했던 Lifecycle API, state 관리 기능을 함수형 컴포넌트에서도 사용할 수 있도록 하는 기능이다. 흔히 보면 useEffect, useState, useContext와 같은 것들이 모두 Hook이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;React 장점&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;React의 장점은 아래와 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. Virtual DOM을 사용해서 빠른 렌더링이 가능하다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. UI의 재사용성이 높으며 유지보수에 좋다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 커뮤니티가 잘 활성화 되어있다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 다른 자바스크립트 라이브러리나 패키지를 사용하기 좋다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;React 단점&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;React 단점은 아래와 같다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. IE8 이하는 지원하지 않는다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; - 이제 Internet Explorer를 사용하지 않아서 큰 단점은 아닌거 같다..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 진입 장벽이 쉽지 않다...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. View 기능만 지원하기에 routing, 상태 관리는 직접 구현해야한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>언어/React</category>
      <category>hook</category>
      <category>react</category>
      <category>React 단점</category>
      <category>React 장점</category>
      <category>spa</category>
      <category>Virtual DOM</category>
      <author>일하는 개미</author>
      <guid isPermaLink="true">https://gee05053.tistory.com/31</guid>
      <comments>https://gee05053.tistory.com/31#entry31comment</comments>
      <pubDate>Fri, 15 Sep 2023 16:07:30 +0900</pubDate>
    </item>
    <item>
      <title>자바스크립트 동작</title>
      <link>https://gee05053.tistory.com/30</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;기술면접을 준비하면서 공부했던 내용들을 정리하고자 오랜만에 블로그에 들어왔습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번 글에서는 자바스크립트 동작에 대해서 글을 적어보려고 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1.&amp;nbsp; JavaScript&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이전에 자바스크립트에서 작성한 글이 있지만 해당 글을 이해하기 위해서 간단하게 알고 넘어가야하는 개념이 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바스크립트는 싱글 스레드 언어입니다. 따라서 명령어 여러개를 동시에 처리하는 것이 아니라 한줄씩 처리할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2. JavaScript 구성&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1686&quot; data-origin-height=&quot;1260&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c6zmrR/btst6O3yivd/KhfARLLL3YrDfnKzI6Wnlk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c6zmrR/btst6O3yivd/KhfARLLL3YrDfnKzI6Wnlk/img.png&quot; data-alt=&quot;JavaScript 동작 출처: google Javascript엔진 검색&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c6zmrR/btst6O3yivd/KhfARLLL3YrDfnKzI6Wnlk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc6zmrR%2Fbtst6O3yivd%2FKhfARLLL3YrDfnKzI6Wnlk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;612&quot; height=&quot;457&quot; data-origin-width=&quot;1686&quot; data-origin-height=&quot;1260&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;JavaScript 동작 출처: google Javascript엔진 검색&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바스크립트 동작을 이해하려면 자바스크립트 엔진, Web API, queue, Event Loop으로 구성되어 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2-1. 자바스크립트 엔진&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바스크립트 엔진에는 heap과 stack이 있습니다. heap에는 원시타입, 객체타입이 선언이 되면 메모리 힙에 할당이 되고, 사용이 끝나면 자동으로 힙에서 해제됩니다. stack은 실행해야하는 코드인 실행 컨텍스트가 쌓입니다. 코드 실행시 push, 실행이 끝나면 pop이 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기에서 실행 컨텍스트란 실행가능한 코드가 실행되기 위해서 필요한 환경을 모아놓은 객체입니다. 기본적으로는 글로벌 컨텍스트가 스택 가장 아래 쌓이고 그 다음으로 함수 컨텍스트 들이 위로 차례로 쌓입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2-2. Web API&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Web API에는 Ajax 요청, SetTimeout, setInterval, 이벤트 핸들러의 등록과 같은 웹 브라우저에서 제공하는 기능들입니다. 해당 기능들은 그립과 같이 자바스크립트 엔진과는 떨어져 있는 것을 확인할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2-3. Queue&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음으로는 Queue 입니다. Queue라고 하면 선입선출, 먼저 들어온 객체가 먼저 나가는 자료구조입니다. 그림에는 Callback queue만 있는데 사실은 Callback queue를 포함해서 MicroTask queue, Animation Frame이 추가로 해서 3개의 queue가 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 Callback queue는 MacroTask queue 또는 Task queue라고도 불립니다. 해당 queue는 Ajax, setTimeOut, setInterval, setImmediate와 같은 task의 결과를 넘겨 받습니다. 우선순위는 3개의 queue중에서 가장 낮습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음으로는 MicroTask queue입니다. 해당 queue는 promise, async/await, process.nextTick 과 같은 비동기 호출을 넘겨 받습니다. 3개의 queue중에서 우선순위가 가장 높습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음으로는 AnimationFrame입니다. requestAnimationFrame과 같은 브라우저 렌더링과 관련된 task를 넘겨받습니다. 3개의 queue중에서 우선순위가 2번째로 높습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정리해보면 queue는 총 3개가 있으며 우선순위는 MicroTask queue &amp;gt; AnimationFrame &amp;gt; MacroTask queue 입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이해가 잘 안되신다면 아래 블로그 글을 참고하시면 좋을거 같습니다!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://velog.io/@titu/JavaScript-Task-Queue%EB%A7%90%EA%B3%A0-%EB%8B%A4%EB%A5%B8-%ED%81%90%EA%B0%80-%EB%8D%94-%EC%9E%88%EB%8B%A4%EA%B3%A0-MicroTask-Queue-Animation-Frames-Render-Queue&quot;&gt;https://velog.io/@titu/JavaScript-Task-Queue%EB%A7%90%EA%B3%A0-%EB%8B%A4%EB%A5%B8-%ED%81%90%EA%B0%80-%EB%8D%94-%EC%9E%88%EB%8B%A4%EA%B3%A0-MicroTask-Queue-Animation-Frames-Render-Queue&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1694682885463&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[JavaScript] Task Queue말고 다른 큐가 더 있다고? (MicroTask Queue, Animation Frames)&quot; data-og-description=&quot;자바스크립트에서 비동기 함수가 동작하는 원리에 대해서 공부했다면, Task Queue에 대해 들어보았을 것이다. Task Queue는 Web API가 수행한 비동기 함수를 넘겨받아 Event Loop가 해당 함수를 Call Stack에 &quot; data-og-host=&quot;velog.io&quot; data-og-source-url=&quot;https://velog.io/@titu/JavaScript-Task-Queue%EB%A7%90%EA%B3%A0-%EB%8B%A4%EB%A5%B8-%ED%81%90%EA%B0%80-%EB%8D%94-%EC%9E%88%EB%8B%A4%EA%B3%A0-MicroTask-Queue-Animation-Frames-Render-Queue&quot; data-og-url=&quot;https://velog.io/@titu/JavaScript-Task-Queue말고-다른-큐가-더-있다고-MicroTask-Queue-Animation-Frames-Render-Queue&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/DJaHp/hyTV4fzFIp/ujYHNxdYFvI0ZbqpHq2Kw0/img.png?width=950&amp;amp;height=500&amp;amp;face=0_0_950_500&quot;&gt;&lt;a href=&quot;https://velog.io/@titu/JavaScript-Task-Queue%EB%A7%90%EA%B3%A0-%EB%8B%A4%EB%A5%B8-%ED%81%90%EA%B0%80-%EB%8D%94-%EC%9E%88%EB%8B%A4%EA%B3%A0-MicroTask-Queue-Animation-Frames-Render-Queue&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://velog.io/@titu/JavaScript-Task-Queue%EB%A7%90%EA%B3%A0-%EB%8B%A4%EB%A5%B8-%ED%81%90%EA%B0%80-%EB%8D%94-%EC%9E%88%EB%8B%A4%EA%B3%A0-MicroTask-Queue-Animation-Frames-Render-Queue&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/DJaHp/hyTV4fzFIp/ujYHNxdYFvI0ZbqpHq2Kw0/img.png?width=950&amp;amp;height=500&amp;amp;face=0_0_950_500');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[JavaScript] Task Queue말고 다른 큐가 더 있다고? (MicroTask Queue, Animation Frames)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;자바스크립트에서 비동기 함수가 동작하는 원리에 대해서 공부했다면, Task Queue에 대해 들어보았을 것이다. Task Queue는 Web API가 수행한 비동기 함수를 넘겨받아 Event Loop가 해당 함수를 Call Stack에&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;velog.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2-4. Event Loop&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Event Loop은 Stack이 비어져 있으면 Queue에서 대기중인 작업을 Stack으로 올려줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3. 동작&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간단한 개념들을 익혔으니 이제는 동작을 알아보겠습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1694683140200&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;console.log(&quot;start&quot;)

setTimeout(function() {
  console.log(&quot;setTimeout&quot;)
}, 0)

promise.resolve()
.then(functuon() {
  console.log(&quot;promise&quot;)
})

console.log(&quot;end&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러분들은 이 코드의 결과가 어떻게 나올거 같으신가요? 정답은 아래와 같이 나옵니다.&lt;/p&gt;
&lt;pre id=&quot;code_1694683215589&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;start
end
promise
setTimeout&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 우선 Stack 가장 아래에는 글로벌 컨텍스트가 쌓입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. console.log(&quot;start&quot;)가 Stack에 push되고 실행이 될 것입니다. 실행이 되면 Stack에서 pop됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 그 다음 실행인 setTimeOut()이 Stack에 쌓입니다. 이제 setTimeOut이 실행이되야하는데 위에서 setTimeout은 Web API 중 하나입니다. 따라서 순서가 이전 console.log()랑 다릅니다. 우선 Stack에서 pop이 되고난 다음 Web API setTimeout에게 실행하라고 신호를 보냅니다. 그러면 Web API에서 setTimeout을 실행시킵니다. setTimeout이 자바스크립트 엔진이 아닌 Web API에서 실행이 되면서 Stack에는 promise.resolve()가 스택에 push되는 것입니다. 이렇게 비동기 처리가 싱글스레드에서 일어나는 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;setTimeout의 실행이 끝나면 결과인 console.log(&quot;setTimeout&quot;)은 MacroTask queue에 들어가게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 이 과정이 일어나면서 Stack에서는 promise.resolve()를 실행 시킵니다. Stack에서 pop이되고 결과인 then()이 MicroTask queue에 들어가게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5. 마지막으로 console.log(&quot;end&quot;)가 Stack에 push되고 실행이 된 다음 Stack에서 pop됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;6. 이제 더이상 실행할 코드가 없기 때문에 글로벌 컨텍스트가 pop되고 Stack은 비워집니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기까지보면 console 창에는 start, end 만 적혀 있습니다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;7. 이제 Event Loop가 Stack이 비워져 있는 것을 확인하고 Queue를 확인합니다. 우선 MicroTask queue에 있는 promise.resolve() 결과인 then()을 Stack에 Push시킨 뒤 코드를 실행하여 console에 promise가 추가됩니다. 그 다음 Stack에서는 pop됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;8. AnimationFrame에는 아무 것도 없고 마지막으로 MacroTask queue에 있는 setTimeout() 결과를 Stack에 Push하고 실행시킨 뒤 pop합니다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 모든 코드가 동작했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;뭔가 말로 적어서 조금 난잡하긴 한데, Queue에서 링크 걸어드린 블로그를 참고하시면 많은 도움이 되실거 같습니다.&lt;/p&gt;</description>
      <category>언어/JavaScript</category>
      <category>callback queue</category>
      <category>Event Loop</category>
      <category>JavaScript</category>
      <category>V8</category>
      <category>비동기</category>
      <category>실행 컨텍스트</category>
      <author>일하는 개미</author>
      <guid isPermaLink="true">https://gee05053.tistory.com/30</guid>
      <comments>https://gee05053.tistory.com/30#entry30comment</comments>
      <pubDate>Thu, 14 Sep 2023 18:35:14 +0900</pubDate>
    </item>
    <item>
      <title>JSX란?</title>
      <link>https://gee05053.tistory.com/29</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000; text-align: left;&quot;&gt;JSX란 무엇일까?&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;JSX는 JavaScript XML의 약자로 말그대로 JavaScript에 XML을 확장한 문법이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;JSX는 React에 사용되는 문법이며 JavaScript의 공식적인 문접은 아니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;JSX의 한 예인 React를 처음 구성했을 때 App.js코드를 보면 아래와 같다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;App.png&quot; data-origin-width=&quot;926&quot; data-origin-height=&quot;616&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BActv/btsj3VlTQIb/9tfWRQFKrNoYm9co8rOoD1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BActv/btsj3VlTQIb/9tfWRQFKrNoYm9co8rOoD1/img.png&quot; data-alt=&quot;React App.js 기본 코드&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BActv/btsj3VlTQIb/9tfWRQFKrNoYm9co8rOoD1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBActv%2Fbtsj3VlTQIb%2F9tfWRQFKrNoYm9co8rOoD1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;926&quot; height=&quot;616&quot; data-filename=&quot;App.png&quot; data-origin-width=&quot;926&quot; data-origin-height=&quot;616&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;React App.js 기본 코드&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 친구.. 뭔가 익숙하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;뭔가 JavaScript같아보이면서도 HTML 태그들이 들어있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JavaScript에서 HTML을 작성하듯이 비슷하게 작성할 수 있으며 가독성이 높다는 것이 JSX의 장점이라고 할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 자세하게 보면 JSX 문법들에 대한 규칙이 있는데, 처음 접근할 때는 조금씩 달라서 까다롭기도하다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;JSX 문법&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에서 단점으로 설명 했듯이 JSX 문법 JavaScript와 HTML과 다른 규칙들이 몇가지 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래에 순서대로 살펴보자&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;1. 컴포넌트에 여러 요소가 있으면 반드시 부모 요소 하나가 감싸는 형태여야 한다.&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오류 케이스&lt;/p&gt;
&lt;pre id=&quot;code_1686818677379&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function App() {
    return(
    	&amp;lt;div&amp;gt;test1&amp;lt;/div&amp;gt;
        &amp;lt;div&amp;gt;test2&amp;lt;/div&amp;gt;
    );
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;올바른 케이스&lt;/p&gt;
&lt;pre id=&quot;code_1686818959045&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function App() {
    return (
    	&amp;lt;div&amp;gt;
            &amp;lt;div&amp;gt;test1&amp;lt;/div&amp;gt;
            &amp;lt;div&amp;gt;test2&amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
    );
}&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;2. JSX 안에서 {}를 사용하여 JavaScript의 표현식을 넣을 수 있다&lt;/span&gt;&lt;/blockquote&gt;
&lt;pre id=&quot;code_1686819191654&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function App() {
    const value = &quot;Hello&quot;;
    return (
        &amp;lt;div&amp;gt;
            &amp;lt;div&amp;gt;test1&amp;lt;/div&amp;gt;
            &amp;lt;div&amp;gt;{value}&amp;lt;/div&amp;gt;
        &amp;lt;/div&amp;gt;
    );
}&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;3. 카멜표기법(CamelCase)을 사용한다.&lt;/span&gt;&lt;/blockquote&gt;
&lt;pre id=&quot;code_1686819396419&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function App() {
    const style = {
        backgroundColor : 'black',
        fontSize : '12px'
    }
    return (
        &amp;lt;div style={style}&amp;gt;test&amp;lt;/div&amp;gt;
    );
}&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;4. class명을 className이라고 표기해야한다.&lt;/span&gt;&lt;/blockquote&gt;
&lt;pre id=&quot;code_1686819628386&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function App() {
    return (
        &amp;lt;div className=&quot;testClassName&quot;&amp;gt;test&amp;lt;/div&amp;gt;
    );
}​&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;5. /* */ 을 이용하여 주석처리를 한다.&lt;/span&gt;&lt;/blockquote&gt;
&lt;pre id=&quot;code_1686819677358&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function App() {
    return (
        /*주석 테스트*/
        &amp;lt;div&amp;gt;test&amp;lt;/div&amp;gt;
    );
}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>언어/React</category>
      <author>일하는 개미</author>
      <guid isPermaLink="true">https://gee05053.tistory.com/29</guid>
      <comments>https://gee05053.tistory.com/29#entry29comment</comments>
      <pubDate>Thu, 15 Jun 2023 18:02:59 +0900</pubDate>
    </item>
    <item>
      <title>DOM이란?</title>
      <link>https://gee05053.tistory.com/28</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;이 글은 DOM을 간단하게 이해하는 정도로만 작성한 글이며 자세한 내용은 구글링을 통해서 개념을 가지는 것이 좋습니다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;DOM이란?&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DOM은 Document Object Model 의 줄인말로 HTML 문서를 구조화 한 것으로 프로그래밍 언어가 DOM 구조에 접근 할 수 있는 방법을 제공하여 문서 구조, 스타일, 내용 등을 변경 할 수 있도록 도와주는 인터페이스 역할을 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DOM은 HTML, XML 문서를 Tree형식으로 구조되며, Javascript와 같은 스크립트 언어를 사용하여 수정할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DOM의 Tree 구조 예시는 아래 사진과 같다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;DOM.png&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;828&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bzkric/btsj6lDsKlw/NRosApNMdc9VQLVsGwRcR0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bzkric/btsj6lDsKlw/NRosApNMdc9VQLVsGwRcR0/img.png&quot; data-alt=&quot;DOM Tree 구조 예시. 출처 : 위키트리&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bzkric/btsj6lDsKlw/NRosApNMdc9VQLVsGwRcR0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbzkric%2Fbtsj6lDsKlw%2FNRosApNMdc9VQLVsGwRcR0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;500&quot; height=&quot;518&quot; data-filename=&quot;DOM.png&quot; data-origin-width=&quot;800&quot; data-origin-height=&quot;828&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;DOM Tree 구조 예시. 출처 : 위키트리&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;DOM은 언제 사용할까?&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러면 DOM이라는 것을 언제 사용할까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;HTML로 웹페이지를 사용해보고 만들어본 경험자라면 알겠지만, 우리가 흔히 아는 웹페이지는 가만히 보여지는 이미지가 아니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;버튼을 눌러서 어떠한 동작을 하고, 다른 페이지로 이동, 다운로드, 데이터 변경 등 상호작용을 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 모든 것을 HTML 태그들을 이용해서 웹페이지를 만들 수 없다. 동적인 기능을 이용하기 위해서 우리는 JavaScript와 같은 스크립트 언어들을 사용하고 DOM 구조를 변경한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;요약&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DOM은 HTML을 위한 API이며 HTML을 탐색을 하거나 구조를 바꿀 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>CS/개념, 용어</category>
      <category>DOM</category>
      <category>HTML</category>
      <author>일하는 개미</author>
      <guid isPermaLink="true">https://gee05053.tistory.com/28</guid>
      <comments>https://gee05053.tistory.com/28#entry28comment</comments>
      <pubDate>Thu, 15 Jun 2023 15:02:33 +0900</pubDate>
    </item>
    <item>
      <title>.gitignore에 대하여</title>
      <link>https://gee05053.tistory.com/27</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트를 하다보면 프로젝트 폴더에 여러 파일을 다운받거나 수정하게된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;react 같은 경우 module 들을 하나 둘 씩 다운받다보면 새로운 파일들이 많이 생기고 &quot;git status&quot;에 항상 검색이 되서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;필요한 파일만 github repo에 push하고 싶을 때 불편함이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 경우처럼 git repo에 업로드 하지 않을 파일들을 기록하는게 .gitignore이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파일 이름 앞에 .이 붙어있는 것으로 보아 이 파일은 숨김 파일로 되어 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;작성방법은 어렵지 않다. 보통 아래 상화에서 많이 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 하나의 파일을 제외하고 싶을 때&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;[파일 이름].[파일 확장자]&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 특정 폴더내의 파일 모두를 제외하고 싶을 때&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;[폴더 이름]/&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 특정 확장자 파일 모두를 제외하고 싶을 때&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;*.[확장자]&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. 제외하고 싶은 폴더가 어디에 있던지 간에 제외하고 싶을 때&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;**/[폴더 이름]/&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 작성을 했으면 적용을 시켜야한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;새로 작성한 .gitignore를 git repo에 push한다&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;git add .gitignore&lt;br /&gt;git commit -m &quot;add .gitignore&quot;&lt;br /&gt;git push [remote 이름] [branch 이름]&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 하면 끝!! 이면 좋겠으나 repo의 캐쉬를 제거하고 다시 업로드해야하는 절차를 걸쳐야한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;git rm -r --cache .&amp;nbsp; &amp;nbsp; &amp;nbsp;(꼭 . 을 붙여야 오류가 안난다..)&lt;br /&gt;git add .&lt;br /&gt;git commit -m &quot;apply .gitignore&quot;&lt;br /&gt;git push [remote 이름] [branch 이름]&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 하면 .gitignore에 추가한 폴더나 파일이 push 되지 않은 것을 확인할 수 있다.&lt;/p&gt;</description>
      <category>CS/git</category>
      <author>일하는 개미</author>
      <guid isPermaLink="true">https://gee05053.tistory.com/27</guid>
      <comments>https://gee05053.tistory.com/27#entry27comment</comments>
      <pubDate>Sat, 1 Apr 2023 23:41:05 +0900</pubDate>
    </item>
    <item>
      <title>React 시작하기</title>
      <link>https://gee05053.tistory.com/26</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;이글에서는 React를 처음 시도해보시는 분들을 위한 글이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대학생때 React, ReactNative를 이용해서 팀플을 했지만 졸업하고 군대를 가고나서는 다 까먹어버림...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;찾아보니 버전도 많이 바껴있고 업데이트하고 조치하는데만 2일 걸렸다는 함정;;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가고싶어하는 회사에서도 React를 사용한다고 하니 나도 공부할 겸 저 처럼 처음 시도해보시는 분들을 위한 글입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;React 사용 전 시스템 버전&lt;/b&gt; &lt;b&gt;확인&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;578&quot; data-origin-height=&quot;254&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dWMMQO/btr4v9sWyMC/jLWruzdiQMwRxLlUkoa4j1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dWMMQO/btr4v9sWyMC/jLWruzdiQMwRxLlUkoa4j1/img.png&quot; data-alt=&quot;Ubuntu 버전. 20.04.6 LTS를 사용하고 있다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dWMMQO/btr4v9sWyMC/jLWruzdiQMwRxLlUkoa4j1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdWMMQO%2Fbtr4v9sWyMC%2FjLWruzdiQMwRxLlUkoa4j1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;578&quot; height=&quot;254&quot; data-origin-width=&quot;578&quot; data-origin-height=&quot;254&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Ubuntu 버전. 20.04.6 LTS를 사용하고 있다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;test.png&quot; data-origin-width=&quot;732&quot; data-origin-height=&quot;483&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c2LbUF/btr4JLqoiOL/mBFQNPpzbElnLauQyjcsqK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c2LbUF/btr4JLqoiOL/mBFQNPpzbElnLauQyjcsqK/img.png&quot; data-alt=&quot;nodejs, npm&amp;amp;amp;nbsp; 버전&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c2LbUF/btr4JLqoiOL/mBFQNPpzbElnLauQyjcsqK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc2LbUF%2Fbtr4JLqoiOL%2FmBFQNPpzbElnLauQyjcsqK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;588&quot; height=&quot;388&quot; data-filename=&quot;test.png&quot; data-origin-width=&quot;732&quot; data-origin-height=&quot;483&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;nodejs, npm&amp;amp;nbsp; 버전&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 그림에서 처럼 글쓴이는 Ubuntu 20.04.06 LTS, NodeJs 18.15.0, npm 9.5.0을 사용하고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대학생때도 그렇고 다시 시작하는 지금도 그렇고 가장 시간을 많이 쓰는 곳 중 하나가 버전 환경을 맞추는거 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음에는 ubuntu 18.04 LTS를 사용하고 npm은 5.버전, nodeJS는 12.버전을 사용하고 있었는데 React 페이지를 보니 사용해야하는 버전이 달라진거 같았다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;test.png&quot; data-origin-width=&quot;633&quot; data-origin-height=&quot;246&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/C8WW4/btr4vhY9s5I/RjnK7sjFLocimPoaTxRuP1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/C8WW4/btr4vhY9s5I/RjnK7sjFLocimPoaTxRuP1/img.png&quot; data-alt=&quot;출처 React 공식 홈페이지&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/C8WW4/btr4vhY9s5I/RjnK7sjFLocimPoaTxRuP1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FC8WW4%2Fbtr4vhY9s5I%2FRjnK7sjFLocimPoaTxRuP1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;633&quot; height=&quot;246&quot; data-filename=&quot;test.png&quot; data-origin-width=&quot;633&quot; data-origin-height=&quot;246&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 React 공식 홈페이지&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사진에서 처럼 Node 14.0.0, npm 5.6 이상을 사용하라고 나와있다. 무시하고 진행하면 당연히 오류로 진행이 안된다..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;겨우 Node 18.15.0, npm 9.5.0으로 업데이트하고나서 진행을 하려고하는데 우분투 18.04 LTS에서는 지원하지 않는다고 해서 Ubuntu 20.04 LTS로 업데이트도 하고 왔습니다.. 블럭되고 여러 실패가 있었으나 이 글을 읽으시는 분들은 미리 업데이트를 잘하시길 바래요..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;React 프로젝트 폴더 만들기&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 필요한 버전들도 설치가 되었으니 React 프로젝트 폴더를 만들어보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;터미널에서 프로젝트 폴더를 만들고 싶은 위치로 이동한 다음 아래 명령어를 입력하면 된다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;npx create-react-app [폴더 이름]&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;1.png&quot; data-origin-width=&quot;733&quot; data-origin-height=&quot;483&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NRglM/btr4RzC2XWr/hx02PXr9FYu98H9Ixzz3G0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NRglM/btr4RzC2XWr/hx02PXr9FYu98H9Ixzz3G0/img.png&quot; data-alt=&quot;React 프로젝트 폴더가 만들어지고 있는 과정&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NRglM/btr4RzC2XWr/hx02PXr9FYu98H9Ixzz3G0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNRglM%2Fbtr4RzC2XWr%2Fhx02PXr9FYu98H9Ixzz3G0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;733&quot; height=&quot;483&quot; data-filename=&quot;1.png&quot; data-origin-width=&quot;733&quot; data-origin-height=&quot;483&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;React 프로젝트 폴더가 만들어지고 있는 과정&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;11.png&quot; data-origin-width=&quot;826&quot; data-origin-height=&quot;456&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b9TazC/btr4G8eZUrJ/n0E3pczJNIIdsk0AR2bTOK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b9TazC/btr4G8eZUrJ/n0E3pczJNIIdsk0AR2bTOK/img.png&quot; data-alt=&quot;React 프로젝트 폴더가 완성된 모습&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b9TazC/btr4G8eZUrJ/n0E3pczJNIIdsk0AR2bTOK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb9TazC%2Fbtr4G8eZUrJ%2Fn0E3pczJNIIdsk0AR2bTOK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;737&quot; height=&quot;407&quot; data-filename=&quot;11.png&quot; data-origin-width=&quot;826&quot; data-origin-height=&quot;456&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;React 프로젝트 폴더가 완성된 모습&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트 폴더가 완성이되면 위 사진과 같은 화면이 나온다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;React 실행하기&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: left;&quot;&gt;프로젝트 폴더가 완성되고 난 뒤 마지막 2줄을 보면 우리가 만든 프로젝트 폴더로 이동한 다음 npm start를 입력해주면 된다고한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: left;&quot;&gt;잘 모르겠지만 우선 해보자.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;111.png&quot; data-origin-width=&quot;1841&quot; data-origin-height=&quot;1049&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/s3bkl/btr4AU2ygVH/azpHVRDmxbGAx6kIu7QfI1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/s3bkl/btr4AU2ygVH/azpHVRDmxbGAx6kIu7QfI1/img.png&quot; data-alt=&quot;npm start 실행한 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/s3bkl/btr4AU2ygVH/azpHVRDmxbGAx6kIu7QfI1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fs3bkl%2Fbtr4AU2ygVH%2FazpHVRDmxbGAx6kIu7QfI1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1841&quot; height=&quot;1049&quot; data-filename=&quot;111.png&quot; data-origin-width=&quot;1841&quot; data-origin-height=&quot;1049&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;npm start 실행한 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오... 뭔지 모르겠는데 터미널에는 &quot;Compiled successfully!&quot; 라는 문구가 나오고 화면에 React 문양이 빙글빙글 돌고 있는 것으로 보아 실행에 성공한거 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;근데 우리는 어떤 코드도 입력하지 않았는데 프로젝트 폴더가 만들어지자 마자 이런 결과물이 나왔을까??&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;1.png&quot; data-origin-width=&quot;915&quot; data-origin-height=&quot;565&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dd5E0u/btr5PbI8oS4/T6H0qwrz4NCt5g4CDfsbtk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dd5E0u/btr5PbI8oS4/T6H0qwrz4NCt5g4CDfsbtk/img.png&quot; data-alt=&quot;test-react/src/App.js 코드&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dd5E0u/btr5PbI8oS4/T6H0qwrz4NCt5g4CDfsbtk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdd5E0u%2Fbtr5PbI8oS4%2FT6H0qwrz4NCt5g4CDfsbtk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;915&quot; height=&quot;565&quot; data-filename=&quot;1.png&quot; data-origin-width=&quot;915&quot; data-origin-height=&quot;565&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;test-react/src/App.js 코드&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;test-react/src/App.js 코드를 보면 사진과 같이 나와있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아직 저 코드들이 이해가 안가도 된다. 처음하는데 이런거 어떻게 다 알아..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 HTML, CSS, JavaScript 조금만 해본 사람이면 아 App.js 파일에서 작성된 요소들이 실행된거구나 라고 알 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리는 앞으로 App.js를 수정하면서 코드를 작성하면 결과물을 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;11.png&quot; data-origin-width=&quot;760&quot; data-origin-height=&quot;424&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cc11vV/btr5OyxTRoI/s8tAzxiCKYrE1jlPbjvVQK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cc11vV/btr5OyxTRoI/s8tAzxiCKYrE1jlPbjvVQK/img.png&quot; data-alt=&quot;test-react/src/index.js 코드&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cc11vV/btr5OyxTRoI/s8tAzxiCKYrE1jlPbjvVQK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcc11vV%2Fbtr5OyxTRoI%2Fs8tAzxiCKYrE1jlPbjvVQK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;760&quot; height=&quot;424&quot; data-filename=&quot;11.png&quot; data-origin-width=&quot;760&quot; data-origin-height=&quot;424&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;test-react/src/index.js 코드&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;index.js 파일을 열어보니 위에서 본 App.js 를 import하고 render? 라는 것을 사용하고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ReactDOM은 뭐고 render은 뭐야... 많이 어렵다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;두려워하지마라. 나도 아직 기억이 가물가물해서 찾아보면서 작성하고있다. 처음부터 배워가면서 해야하고, 중도하차만 하지않으면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러분들도 React를 다룰 수 있을 것이다.&lt;/p&gt;</description>
      <category>언어/React</category>
      <author>일하는 개미</author>
      <guid isPermaLink="true">https://gee05053.tistory.com/26</guid>
      <comments>https://gee05053.tistory.com/26#entry26comment</comments>
      <pubDate>Sun, 19 Mar 2023 18:18:31 +0900</pubDate>
    </item>
    <item>
      <title>CPU와 GPU, TPU 차이</title>
      <link>https://gee05053.tistory.com/25</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;CPU&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Central Processing Unit, 중앙처리장치라고 불리는 CPU는 컴퓨터의 두뇌를 담당하고 있다. CPU는 명령어 하나로 처리할 수 있는 기능이 많고 각종 제어처리를 위한 부분이 많다. 또한 다양한 작업을 빠르게 처리하기 위해서 복잡한 &lt;a href=&quot;#ALU&quot;&gt;&lt;b&gt;ALU&lt;/b&gt;&lt;/a&gt; 구조를 가지고 있다. 따라서 CPU는 직렬처리에 최적화 된 몇개의 &lt;a href=&quot;#CORE&quot;&gt;&lt;b&gt;코어&lt;/b&gt;&lt;/a&gt;로 구성되어 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CPU는 코드 실행, 여러 디바이스(키보드, 하드디스크)들이랑 상호작용, 사용자들로 입력받은 명령어들을 해석, 연산 후 결과를 출력하는 역할을 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;GPU&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Graphics Processing Unit, 그래픽처리장치라고 불리는 GPU는 픽셀로 이루어진 영상을 처리하는 용도로 탄생했다. GPU는 특화된 연산을 병렬적으로 나누어서 처리한다. 따라서 특화된 연산을 빠른 속도처리하기 위해 단순한 ALU 구조를 가지고 있다. 따라서 GPU는 병렬 처리용으로 설계된 수천 개의 작은 효율적인 코어로 구성되어 있다. 위에서 설명한 CPU가 GPU를 제어한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;GPU는 AI 기계학습, 컴퓨터 그래픽 픽셀 연산, 3D 렌더링 등 에 사용된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;CPU로는 GPU를 대체할 수 없는걸까?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존 CPU는 1개의 코어로 1개의 작업밖에 할 수 없었다. 그래서 최근에는 MutiCore CPU라고해서 여러개의 코어를 가진 CPU가 등장하고 있다. intel core i9 extreme edition은 18개의 코어를 가지고 있으며 각 코어는 초당 30억 사이클을 실행할 수 있는 3.00GHZ의 속도를 가지고 있다. 그렇다면 더 이해를 할 수 없다... &lt;b&gt;CPU에 코어를 많이 늘리면되지 않을까?? &lt;/b&gt;라는 생각이 든다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 그 생각은 한계가 있다. CPU는 에너지 소모가 심하다. 이러한 CPU에 코어를 무작정 많이 늘린다면?? 우리의 전기세는 엄청나 질 것이다... GPU는 CPU보다 코어의 갯수가 많다고 했다. Nvidia Geforce RTX 3090을 예로 들면 해당 그래픽 카드는 10,496개의 코어를 가지고 있으며 각 코어 당 1.70GHZ의 속도를 가지고 있다. 코어의 갯수가 CPU랑 비교하면 어마무시하다. 이렇기 때문에 GPU가 인공지능 학습, 그래픽 픽셀 연산에 사용되는 이유이다. 이들은 간단한 계산들이지만 동시에 빠르게 연산되어야 할 필요가 있다. 쉽게 설명하면 여러분들이 게임을 할 때나 유튜브로 영상을 볼 때 화면이 부드럽게 넘어간다고 느끼는 것은 60fps 정도가 될 것이다. 이는 초당 60개의 프레임이 보여진다고 생각하면 된다. 초당 60개?? 별로 안되네 라고 생각하겠지만 여러분이 지금 이 글을 보고 있는 모니터를 생각해야한다. 요즘 보통 1920*1080 ~ 4096*2160 해상도를 가지고 있을 텐데 해당 숫자들이 하나의 픽셀이다. 여러분들이 부드럽게 이질감 없이 보이기 위해는 모든 픽셀들이 각 위치에 맞는 색깔들을 동시에 계산하고 화면에 보여져야한다. 만약에 여러분들의 4K(4096*2160) 모니터로 60fps 동영상을 보고있다면 초당 4096*2160*60 을 계산하면서 여러분들에게 보여주고 있는 것이다. 이런 동시에 빠르고 간단한 연산은 GPU가 최적일 수 밖에 없다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; &lt;/b&gt;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;TPU&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Tensor Process Unit, 2016년 Google에서 발표한 장치이다. 기존 GPU보다 백터/행렬 연산의 병렬처리에 특화되어 있어 선형대수 연산 성능을 가속화하여 복잡합 대형 신경망 모델을 학습시킬 때 정확성 달성 시간을 최소화 시킬 수 있다. Google에서 적힌 설명으로는 GPU에서는 몇주가 걸리는 모델 학습이 몇 시간안에 학습이 된다고 적혀있기도 한다. 아직까지 특허를 내지 않고 정확하게 공개되지는 않았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;용어정리&lt;/h3&gt;
&lt;p id=&quot;ALU&quot; data-ke-size=&quot;size16&quot;&gt;ALU : 산술 논리 장치, 산술연산(덧셈, 뺄셈 등등) 과 논리연산(논리합, 논리 곱)을 계산하는 디지털 회로&lt;/p&gt;
&lt;p id=&quot;CORE&quot; data-ke-size=&quot;size16&quot;&gt;코어 : 이진법으로 표현된 정보의 저장을 위한 자성 물질&lt;/p&gt;</description>
      <category>CS/개념, 용어</category>
      <category>CPU</category>
      <category>GPU</category>
      <category>TPU</category>
      <category>인공지능</category>
      <author>일하는 개미</author>
      <guid isPermaLink="true">https://gee05053.tistory.com/25</guid>
      <comments>https://gee05053.tistory.com/25#entry25comment</comments>
      <pubDate>Sat, 18 Mar 2023 03:27:05 +0900</pubDate>
    </item>
    <item>
      <title>docker에 대해서</title>
      <link>https://gee05053.tistory.com/24</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;이번 글에서는 docker에 대해서 알아보고자 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대학생 때 팀 프로젝트에서 docker를 사용해본적은 있지만.. 같은 팀원이 다 만들고 실행만해서 사용했어서 사실 사용했다고 하기엔 창피할 정도,,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대학교 때 docker에 대해서 공부해보려고 했지만 그때는 아무리 읽어도 왜 그렇게 이해가 안됐는지 모르겠다 ㅠㅠ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://subicura.com/2017/01/19/docker-guide-for-beginners-1.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://subicura.com/2017/01/19/docker-guide-for-beginners-1.html&lt;/a&gt; 사이트 글을 읽고 이해한 내용을 작성한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;글이 오래되서 버전이나 이런부분은 다르지만 docker에 대해서 개념을 잡을려고 한다면 이 글을 읽으면 많이 도움이 될 것으로 보인다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;docker에 대해서 알아보기 전에 docker를 하면 항상 따라오는 단어들을 먼저 이해하고 넘어가보고자 한다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;docker.png&quot; data-origin-width=&quot;279&quot; data-origin-height=&quot;131&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ZY7j8/btr3cIDznwY/XUa9oKaNOItw3gQNeJV8L1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ZY7j8/btr3cIDznwY/XUa9oKaNOItw3gQNeJV8L1/img.png&quot; data-alt=&quot;docker 이미지 출처 : Google&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ZY7j8/btr3cIDznwY/XUa9oKaNOItw3gQNeJV8L1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZY7j8%2Fbtr3cIDznwY%2FXUa9oKaNOItw3gQNeJV8L1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;279&quot; height=&quot;131&quot; data-filename=&quot;docker.png&quot; data-origin-width=&quot;279&quot; data-origin-height=&quot;131&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;docker 이미지 출처 : Google&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;컨테이너&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컨테이너는 docker의 로고에서도 표현되듯이 docker하면 가장 많이 따라오는 단어이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컨테이너란 라이브러리, 시스템 도구, 코드 등 소프트웨어 실행에 필요한 모든 것이 포함되어 있다. 컨테이너는 하나의 프로세스라고 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;이미지&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;docker에서 이미지란 컨테이너를 만들고 실행시키는데 사용되는 읽기 전용 템플릿이라고 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;linux container&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리눅스 컨테이너란 리눅스에서 프로세스를 격리하는 방식이다. docker는 리눅스 컨테이너 방식을 인용해서 만들어졌다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;docker&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 docker에 대해서 알아보자. docker는 컨테이너 환경에서 독랍적으로 애플리케이션을 실행할 수 있도록 컨테이너를 만들고 관리하는 것을 도와주는 도구, 즉 컨테이너를 관리하는 플랫폼이다. 이미지를 이용해서 컨테이너를 실행시키거나 만들고, git에서 github와 비슷한 docker에서는 dockerhub를 이용해서 다른 사용자에게 이미지를 배포할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;docker의 장점&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 하나의 서버에 여러개의 컨테이너를 실행해도 서로 영향을 미치지 않고 독립적으로 실행되어 가벼운 VM을 사용하는 느낌을 준다. 이는 실행중인 컨테이너에 접속하여 명령어를 입력할 수 있고 apt-get 이나 yum으로 패키지 설치가 가능하다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 새로운 컨테이너를 만드는데 1~2초 정도의 짧은 시간이 걸리며 이는 가상머신보다 훨씬 속도가 빠르다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;docker vs VM&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대충 설명만 보면 docker랑 VM이랑 크게 달라 보이진 않아보인다. docker가 VM보다 빠르고 가벼운 장점은 있다는 건데 어떤게 크게 다를까?&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;docker.jpg&quot; data-origin-width=&quot;640&quot; data-origin-height=&quot;313&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ce5Ybf/btr3fuElqzu/mkF46jwWG6kaJ2eeanYKJK/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ce5Ybf/btr3fuElqzu/mkF46jwWG6kaJ2eeanYKJK/img.jpg&quot; data-alt=&quot;VM 과 docker 차이&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ce5Ybf/btr3fuElqzu/mkF46jwWG6kaJ2eeanYKJK/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fce5Ybf%2Fbtr3fuElqzu%2FmkF46jwWG6kaJ2eeanYKJK%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;640&quot; height=&quot;313&quot; data-filename=&quot;docker.jpg&quot; data-origin-width=&quot;640&quot; data-origin-height=&quot;313&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;VM 과 docker 차이&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;VM은 host OS위에 하나의 물지적 머신에서 여러 가상 머신을 실행하는데 사용하는 소프트웨어인 hypervisor를 이용해서 Guest OS를 가상화하여 사용한다. 여러가지 OS를 가상화하여 사용할 수 있고 비교적 사용법이 간단하지만 무겁고 느려서 운영환경에서는 사용하는데 제한이 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 docker은 host OS위에 docker engine으로 프로세스를 단순하게 격리하기 때문에 가볍고 빠르다. 프로세스(컨테이너)가 필요한 만큼만 CPU나 메모리를 사용하기 때문에 성능적인 손실이 적다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;군대에서 체계운용장교라는 보직으로 있으면서 여러 서버를 관리하고 유지했다. 군대에서는 서버 1대당 PC가 각각 1대씩 있었다. 이렇게 되면 하나의 서버를 만들기 위해서 PC 하나를 새로 만들어야하기 때문에 시간이나 자원, 비용이 많이 들었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;'그냥 하나의 PC에서 여러개 설치하면 되잖아?' 생각할 수 있겠지만 군대인 만큼 호환이 잘 안된다.. 서버마다 사용하는 OS도 다르고 필요로 하는 프로그램 버전도 다르다. 회사에서도 마찬가지 일 것이다. 회사에서도 여러 서버를 관리할 일이 있을 것이고 서버당 필요로 하는 프로그램이나 OS 조건들이 많이 다를 것이다. VM은 위에서 설명했듯이 여러개의 Guest OS를 사용해서 관리하면 속도나 자원 문제가 발생하지만 docker를 이용해서 하나의 서버를 컨테이너로 관리하고 실행하면 프로세스로 쉽게 관리할 수 있다.&lt;/p&gt;</description>
      <category>CS/docker</category>
      <author>일하는 개미</author>
      <guid isPermaLink="true">https://gee05053.tistory.com/24</guid>
      <comments>https://gee05053.tistory.com/24#entry24comment</comments>
      <pubDate>Sun, 12 Mar 2023 20:16:07 +0900</pubDate>
    </item>
    <item>
      <title>git 명령어 정리</title>
      <link>https://gee05053.tistory.com/22</link>
      <description>&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;git status : git 폴더에서 사용 가능, 브랜치 상태, 수정된 파일 등을 확인할 수 있음&lt;/li&gt;
&lt;li&gt;git log : log 확인하는 명령어&lt;/li&gt;
&lt;li&gt;git init : 작업 폴더를 git 폴더로 만들기 위해 사용&lt;/li&gt;
&lt;li&gt;git clone [http://~~] : git 저장소 복제 및 다운로드&amp;nbsp;&lt;/li&gt;
&lt;li&gt;git add [수정한 파일] : git 저장소에 저장할 파일 추가&lt;/li&gt;
&lt;li&gt;git commit -m [&quot;작성할 커밋 메세지&quot;] : 저장소에 추가된 파일을 커밋 &amp;amp; 커밋 메세지 작성&lt;/li&gt;
&lt;li&gt;git push origin [브랜치 이름] : 커밋한 파일을 [브랜치 이름]으로 전송&lt;/li&gt;
&lt;li&gt;git pull : 변경된 내용 가져오니&lt;/li&gt;
&lt;li&gt;git branch : 현재 브랜치 확인&lt;/li&gt;
&lt;li&gt;git branch [브랜치 이름] : [브랜치 이름] 생성&lt;/li&gt;
&lt;li&gt;git branch -d [브랜치 이름] : [브랜치 이름] 삭제&lt;/li&gt;
&lt;li&gt;git checkout [브랜치 이름] : [브랜치 이름]으로 브랜치 변경&lt;/li&gt;
&lt;li&gt;git merge [다른 브랜치 이름] : 현재 브랜치에서 [다른 브랜치 이름] 변경사항 병합&lt;/li&gt;
&lt;li&gt;git stash : commit 하고 싶지 않은 파일이 있을 때 stash 저장소로 따로 빼놓음&lt;/li&gt;
&lt;li&gt;git stash apply : stash 저장소에 있는 파일을 다시 가져옴&lt;/li&gt;
&lt;li&gt;git stash drop : stash 저장소에 있는 파일을 삭제&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>CS/git</category>
      <category>git</category>
      <category>기본 명령어</category>
      <category>명령어</category>
      <author>일하는 개미</author>
      <guid isPermaLink="true">https://gee05053.tistory.com/22</guid>
      <comments>https://gee05053.tistory.com/22#entry22comment</comments>
      <pubDate>Fri, 10 Mar 2023 21:44:48 +0900</pubDate>
    </item>
    <item>
      <title>git과 github</title>
      <link>https://gee05053.tistory.com/23</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;git과 github는 같은 의미일까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보통 git을 사용하면 github도 같이 사용하지만 이 둘은 다른의미이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면 어떤 차이점이 있을까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;버전관리시스템&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;버전관리시스템이란 시간에 따라 파일의 변경사항을 추적하고 기록하여 필요에 따라 이전 버전으로 복구하거나 조회하는 기능을 말한다. 과제를 하거나 보고서를 작성할 때 보통 우리는 여러번의 수정 과정을 거친다. 분명 어떤 사람들은 하나의 파일을 계속 덮어쓰기 할 수도 있고, 누구는 다른이름저장 기능을 사용하여 &quot;보고서 완성본.hwp&quot;, &quot;보고서 찐막 완성본.hwp&quot;, &quot;보고서 찐찐찐막 완성본.hwp&quot; 이런식으로 저장하는 사람도 있을 것이다. 이렇게 저장을하면 단점이 있다. 첫번째 예시로는 계속 덮어쓰기 기능은 어느 지점으로 돌아가고 싶을 경우 돌아갈 수 없다.. 중간까지는 완벽한데,, 여기서부터 다시하고 싶은데 이미 덮어써버렸다.. 두번째 예시는 바탕화면이 많이 지저분하고 계속해서 그 파일을 저장하고 있어야한다. 지저분한거 감수할 수 있다고하더라도 우리는 언젠가 바탕화면에 많아진 파일들을 하나씩 보면서 최종 보고서 파일을 찾아야한다. 하지만 버전관리시스템은 이러한 단점들을 다 해결해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;필요하면 이전 버전으로 복구도할 수 있으며 기록만 잘 한다면 내가 어느버전에서 어떤 것을 수정했고 어디까지 진행했는지 알 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;git&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;git은 위에서 설명한 버전관리시스템 중 하나 이다. git은 &lt;b&gt;로컬 시스템&lt;/b&gt;에 설치되고 관리된다. 계속 쌓이는 프로그래밍 버전을 스스로 관리할 수 있다. 로컬 시스템에 설치되고 관리되기 때문에 인터넷이 없는 상태에서도 관리할 수 있다. 또한 branch 기능은 또 다른 독립적인 로컬 시스템을 만들어 관리할 수 있으며, 필요에 따라 삭제, 병합이 가능하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;github&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면 github은 뭐야?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;github은 git 저장소를 관리하는 &lt;b&gt;클라우드 서비스&lt;/b&gt;이다. 즉 git은 로컬 시스템에서만 설치되고 관리되는데 이것을 github에 올려 다른사람이랑도 공유가 가능하도록 만든다. 본인이 github에 업로드한 코드나 파일들은 다른사람들이 git clone 기능을 사용하여 이어서 작업하거나 다운받을 수 있다. 따라서 다른 사람들과 프로젝트를 할 때 공유가 가능하여 쉽게 수정하고 개선할 수 있다.&lt;/p&gt;</description>
      <category>CS/git</category>
      <category>git</category>
      <category>github</category>
      <category>로컬시스템</category>
      <category>버전관리시스템</category>
      <category>클라우드서비스</category>
      <author>일하는 개미</author>
      <guid isPermaLink="true">https://gee05053.tistory.com/23</guid>
      <comments>https://gee05053.tistory.com/23#entry23comment</comments>
      <pubDate>Fri, 10 Mar 2023 21:44:30 +0900</pubDate>
    </item>
    <item>
      <title>프로그래머스 level2 메뉴 리뉴얼</title>
      <link>https://gee05053.tistory.com/18</link>
      <description>&lt;p&gt;&lt;b&gt;1. 문제 파악하기&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;- orders 배열의 크기는 2 이상 20이하이다. &amp;amp; orders 배열의 각 원소의 크기는 2이상 10이하인 문자열이며 대문자로만 이루어져 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #333333;&quot;&gt;- 정답은 오름차순으로 정렬해서 return해야함.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;2. 문제 접근하기&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;- orders에 있는 원소들의 조합을 생각해야함. 이때 조합의 길이는 2이상 10이하의 자연수임 &amp;rarr; itertools 라이브러리의 combinations를 사용할 것임&lt;/p&gt;
&lt;p&gt;- 단품 메뉴 조합이 2번이상 나와야하며 가장 많이 나온 것들을 찾아야함.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;3. 주의할 점&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;- orders의 원소들은 대문자로 되어있지만 사전순으로 정렬되어 있지 않음 &amp;rarr; 먼저 정렬시킬 필요가 있음&lt;/p&gt;
&lt;p&gt;- 언급은 되었더라도 2번 이상 언급이 된 코스요리여야함.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;4. 정답 코드 및 해석&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;제가 작성한 코드는 아래와 같습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1613219511179&quot; class=&quot;php&quot; data-ke-language=&quot;php&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from itertools import combinations

def solution(orders, course):
    answer = []
    for i in course :
        combination = []
        for j in orders :
            j = ''.join(sorted(list(j)))
            result = list(combinations(j,i))
            for k in result :
                combination.append((''.join(list(k))))
        result = []
        for j in combination :
            count = combination.count(j)
            result.append((j,count))
        result = list(set(result))
        result = sorted(result, key=lambda x: x[1], reverse=True)
        max_result = list(filter(lambda x: x[1] &amp;gt; 1 and x[1] == result[0][1], result))
        for j in max_result :
            answer.append(j[0])
    answer.sort()
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;b&gt;1.&lt;/b&gt; 우선 course의 원소를 기준으로 for문을 돕니다.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;2.&lt;/b&gt; 그 안에 다른 for문을 작성하는데 이는 orders의 원소를 기준으로 돕니다. 이 for문의 용도는 orders 원소를 i길이로 combination하기 위함입니다. orders의 원소는 사전식으로 정렬되어 있지 않았습니다. 따라서 문자열을 리스트로 변형시키고 정렬한 다음 .join()을 이용해서 정렬된 문자열로 만듭니다.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;3.&amp;nbsp;&lt;/b&gt;result 변수 안에는 i길이로 조합된 원소들이 있습니다. 이때 result안에 원소들은 (&quot;A&quot;,&quot;B&quot;)와 같이 집합 형태로 되어 있으므로 join()을 이용해서 combination이라는 변수에 조합된 문자열을 넣습니다. for문을 다 돌았을 때, combination 변수 안에는 orders안에 있는 원소가 i길이로 조합된 문자열이 들어 있을 것입니다. ex) i=2, orders = [&quot;ABC&quot;, &quot;EFQ&quot;] 라면 combination의 최종 결과는 [&quot;AB&quot;, &quot;AC&quot;, &quot;BC&quot;, &quot;EF&quot;, &quot;EQ&quot;, &quot;FQ&quot;]가 들어 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;4.&amp;nbsp;&lt;/b&gt;다시 for문을 만들어서 combination의 각 원소가 몇번 나왔는지 센다음 result에 (조합된 문자열, count) 형태로 저장합니다. 하지만 이때 result에는 중복된 값이 있을 수 있습니다. 그래서 result = list(set(result))를 이용해서 중복된 값을 제거한 다음 다시 리스트로 만듭니다.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;5.&lt;/b&gt; result에 들어있는 원소들을 count를 기준으로 내림차순으로 정렬합니다. 그러면 가장 많이 count된 조합이 가장 앞에 있겠죠? count된 횟수가 같은 원소들이 있을테니 filter 함수를 이용해서 count가 2이상, 가장 많이 언급된 원소들만 골라냅니다. 골라낸 원소들은 max_result 변수에 저장됩니다.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;6.&lt;/b&gt; filter된 원소들을 answer에 넣습니다.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;7.&amp;nbsp;&lt;/b&gt;마지막 return하기전에 answer 리스트를 정렬한 다음 return합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;이렇게 코드를 작성하고 채점을 하면 다음과 같은 결과로 통과가 됩니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-origin-width=&quot;946&quot; data-origin-height=&quot;531&quot; data-filename=&quot;스크린샷, 2021-02-13 21-53-48.png&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/B5gaO/btqWWt0lTuO/AIo7a9qTBzIsWLQvneLZRk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/B5gaO/btqWWt0lTuO/AIo7a9qTBzIsWLQvneLZRk/img.png&quot; data-alt=&quot;테스트 케이스 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/B5gaO/btqWWt0lTuO/AIo7a9qTBzIsWLQvneLZRk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FB5gaO%2FbtqWWt0lTuO%2FAIo7a9qTBzIsWLQvneLZRk%2Fimg.png&quot; data-origin-width=&quot;946&quot; data-origin-height=&quot;531&quot; data-filename=&quot;스크린샷, 2021-02-13 21-53-48.png&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;테스트 케이스 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;5. 마치며&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;이번 문제는 level2치곤 쉬운 문제였습니다. 하지만 itertools의 combinations 기능을 몰랐다면 조합을 어떻게 만들지 조금 많이 고민했어야 했을거 같습니다. 이번 문제는 카카오 블라인드 채용에서 나온 문제인데 예전보다 카카오에서 나오는 문제들이 꽤 많이 까다롭고 복잡한 경우가 많은거 같습니다. 이번 문제는 코딩을 할줄 아냐 모르냐를 판별하는 정도인거 같은데 다른 문제들을 보면 꽤 어려운 문제들도 많더군요..ㅎ 더 노력해야겠습니다. 이번 문제는 조금 길어서 겁먹으신 분들도 있으실텐데 코딩테스트도 수능 문제처럼 문제가 길수록 힌트가 많은거 같습니다. 문제가 길수록 옆에 개인 노트에 잘 정리하면서 문제를 생각한다면 조금 더 수월하게 문제를 풀 수 있을거 같습니다.&lt;/p&gt;</description>
      <category>CS/Algorithm</category>
      <category>카카오 블라인드 채용</category>
      <category>코딩 테스트</category>
      <category>프로그래머스</category>
      <author>일하는 개미</author>
      <guid isPermaLink="true">https://gee05053.tistory.com/18</guid>
      <comments>https://gee05053.tistory.com/18#entry18comment</comments>
      <pubDate>Sat, 13 Feb 2021 21:57:16 +0900</pubDate>
    </item>
    <item>
      <title>프로그래머스 level2 주식 가격</title>
      <link>https://gee05053.tistory.com/17</link>
      <description>&lt;p&gt;&lt;b&gt;1. 문제 파악하기&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;- prices의 각 가격은 1~10,000 이하인 자연수 &amp;amp; prices의 길이는 2이상 100,000 이하 &amp;rarr; level 1에서보단 prices의 길이가 조금 긴편이지만 그래도 적당한 길이.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;2. 문제 접근하기&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;- 초 단위로 기록된 주식 가격이 담긴 배열 prices가 매개변수로 주어지고, 가격이 떨어지지 않은 기간은 몇초인지 retrurn해야함. &amp;rarr; 1초의 가격이 2이고 2초 가격이 1이면 return 배열에 들어가는 1초 가격이 떨어지지 않은 기간은 1초이다. 1초 가격이 2, 2초가격이 3, 3초 가격이 1이면 return 배열에 들어가는 1초 가격이 떨어지지 않은 기간은 2초이다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;3. 주의할 점&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;level 1 과 다르게 인자로 주어지는 값의 길이가 많이 커졌습니다. 이때 단순하게 level 1에서 생각한 방법으로 코드를 작성하시다간 시간초과가 일어날 가능성이 높습니다. 이번 문제에선 커트라인을 꽤 크게 주어진 듯하지만 개인적으로도 만족하지 않은 코드입니다. 다른 사람들 풀이의 댓글에보면 스택을 이용하면 O(n)로 문제를 풀 수 있다고 합니다. 저도 지금 당장은 생각이 나지도 않고 다른 사람들 풀이에도 O(n^2)으로 푼 방법 밖에 없어서 한번 생각해봐야겠습니다. ㅎㅎ&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;4. 정답 코드 및 해석&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;제가 문제를 푼 방법은 다음과 같습니다.&lt;/p&gt;
&lt;pre id=&quot;code_1613133026138&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(prices):
    answer = [0 for i in range(len(prices))]
    for i in range(len(prices)) :
        for j in range(i+1,len(prices)) :
            if prices[i] &amp;lt;= prices[j] :
                answer[i] += 1
            else :
                answer[i] += 1
                break
    return answer&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;시간 복잡도를 신경쓰지 않는다면 생각보다 간단하게 문제를 해결할 수 있습니다.&lt;/p&gt;
&lt;p&gt;저는 우선 answer이라는 배열에 prices길이만큼 0이라는 숫자들을 담았습니다.&lt;/p&gt;
&lt;p&gt;그런 다음 다들 보이시겠지만 2중 for문을 사용하여 O(n^2)으로 문제를 해결했습니다.&lt;/p&gt;
&lt;p&gt;이 코드는 원소 하나씩 차례대로 비교하면서 값을 구하는 방법이죠.&lt;/p&gt;
&lt;p&gt;이렇게 코드를 작성하면 아래와 같이 케이스를 해결할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;캡처.PNG&quot; data-origin-width=&quot;951&quot; data-origin-height=&quot;440&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mU1VM/btqWX5xwpfo/omTEiBpEr9Nil2uEYEZzfK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mU1VM/btqWX5xwpfo/omTEiBpEr9Nil2uEYEZzfK/img.png&quot; data-alt=&quot;테스트 케이스 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mU1VM/btqWX5xwpfo/omTEiBpEr9Nil2uEYEZzfK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmU1VM%2FbtqWX5xwpfo%2FomTEiBpEr9Nil2uEYEZzfK%2Fimg.png&quot; data-filename=&quot;캡처.PNG&quot; data-origin-width=&quot;951&quot; data-origin-height=&quot;440&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;테스트 케이스 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;5. 마치며&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;오늘은 level 2의 문제를 보았지만 그 중에서도 가장 짧고 간단한 코드들을 보았습니다. level 2라고해서 level 1과 크게 다를 것은 없습니다. 다만 코드의 길이가 조금 늘어나고 level 2부터는 시간 복잡도를 생각하면서 문제를 해결하기 시작해야합니다. 이번 문제에서는 O(n^2)로도 문제가 해결됐지만 일반적으로 대기업 코딩테스트에서는 조금 힘들 가능성이 높겠죠. 문제를 해결했다고 해서 만족하고 넘어가는 것이 아니라, 조금 더 나은 코드들을 생각해보시고 그 방법으로 다시 문제를 풀어보시는 것이 좋겠습니다.&lt;/p&gt;</description>
      <category>CS/Algorithm</category>
      <category>코딩 테스트</category>
      <category>프로그래머스</category>
      <author>일하는 개미</author>
      <guid isPermaLink="true">https://gee05053.tistory.com/17</guid>
      <comments>https://gee05053.tistory.com/17#entry17comment</comments>
      <pubDate>Fri, 12 Feb 2021 21:35:34 +0900</pubDate>
    </item>
    <item>
      <title>프로그래머스 level1 신규 아이디 추천</title>
      <link>https://gee05053.tistory.com/14</link>
      <description>&lt;p&gt;&lt;b&gt;1.&amp;nbsp;&lt;/b&gt;&lt;b&gt;문제 파악하기&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;- new_id는 길이가 1이상 1,000 이하인 문자열이다. &amp;rarr; 별로 길지 않은 문자열&lt;/p&gt;
&lt;p&gt;- new_id는 알파벳 대문자, 알파벳 소문자, 숫자, 특수문자로 구성되어 있음.&lt;/p&gt;
&lt;p&gt;- new_id에 나타날 수 있는 특수 문자는 &lt;span&gt;&lt;b&gt;-_.~!@#$%^&amp;amp;*()=+[{]}:?,&amp;lt;&amp;gt;/&lt;/b&gt; 로 한정. &amp;rarr; 이 중에서 앞에 - _ . 만 사용가능하고 나머지는 지워야함&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;2. 문제 접근하기&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;이번 문제는 문제에서 주어진 7가지 단계 순서대로 구현하면 쉽게 문제를 해결할 수 있습니다. 코드는 level1 문제치곤 길다고 생각드실 수도 있지만 그렇게 어려운 알고리즘을 생각할 필요는 없다고 생각이 듭니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;3. 주의할 점&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;- 입력으로 주어지는 new_id의 길이가 1이상 1,000 이하인 문자열이라서 무한루프에 빠지지만 않는다면 실행시간이 그렇게 오래걸리지 않을 것입니다. 7가지 단계 중 특수 문자 제거, 연속된 마침표를 제거 부분에서 while문을 이용해서 코드를 작성하신 분들이라면 무한루프를 조금 주의해서 코드를 작성하셨어야 할거 같습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;- 특수 문자 제거, 마침표 제거 등 문자열을 제거하다보면 빈문자열이 만들어지는 경우가 있을텐데, 이때 인덱싱 에러 문제로 조금 조심해야할 부분인거 같습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;4. 정답 코드 및 해석&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1613027345254&quot; class=&quot;php&quot; data-ke-language=&quot;php&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;def solution(new_id):
    del_str = [&quot;~&quot;, &quot;!&quot;, &quot;@&quot;, &quot;#&quot;, &quot;$&quot;, &quot;%&quot;, &quot;^&quot;, &quot;&amp;amp;&quot;, &quot;*&quot;,&quot;(&quot;, &quot;)&quot;, &quot;=&quot;,
               &quot;+&quot;, &quot;[&quot;, &quot;{&quot;, &quot;]&quot;, &quot;}&quot;, &quot;:&quot;, &quot;?&quot;, &quot;,&quot;, &quot;&amp;lt;&quot;, &quot;&amp;gt;&quot;, &quot;/&quot;]
    #1단계 소문자로 바꾸기
    new_id = new_id.lower()
    #2단계 특수 문자 제거
    index = 0
    while index &amp;lt; len(new_id) :
        if new_id[index] in del_str :
            new_id = new_id.replace(new_id[index], &quot;&quot;)
        else :
            index += 1
    #3단계 마침표 2번이상 연속을 하나로 치환
    while &quot;..&quot; in new_id :
        new_id = new_id.replace(&quot;.&quot;*2, &quot;.&quot;)
    #4단계 마침표 처음과 끝에 위치 제거
    if len(new_id) &amp;gt; 0 and new_id[0] == &quot;.&quot; :
        new_id = new_id[1:]
    elif len(new_id) &amp;gt; 0 and new_id[-1] == &quot;.&quot; :
        new_id = new_id[:-1]
    #5단계 빈 문자열이면 &quot;a&quot;를 대입
    if new_id == &quot;&quot; :
        new_id = &quot;a&quot;
    #6단계 16자리 이상이면 15까지 남기고 제거 &amp;amp; 끝자리 마침표 제거
    if len(new_id) &amp;gt; 15 :
        new_id = new_id[:15]
    if new_id[-1] == &quot;.&quot; :
        new_id = new_id[:-1]
    #7단계 2자리 이하면 아이디의 마지막 문자 반복
    while len(new_id) &amp;lt;= 2 :
        new_id += new_id[-1]
    return new_id&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;정답 코드 및 해석입니다. 7가지 단계로 나눠서 작성하다보니 코드가 조금 길어서 단계별로 나눠서 설명을 드리겠습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;우선 del_str이라는 리스트가 있습니다. 보시면 아시겠지만 지워야할 특수 문자들이 들어있습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;1단계는 대문자로 되어 있는 문자열을 소문자로 바꾸는 과정입니다. 파이썬에서는 .lower() 함수를 이용해서 대문자를 소문자로, .upper() 함수를 이용해서 소문자를 대문자로 바꿀 수 있습니다. 파이썬의 장점중 하나인 유용한 내장함수가 많은 것을 활용하여 1단계는 1줄로 코드를 작성할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;2단계는 특수 문자를 제거하는 것입니다. index라는 변수에 0을 초기화 시킵니다. 그런 다음 while문을 이용해서 new_id의 한문자씩 확인하면서 del_str에 들어 있는 특수 문자라면 replace(&quot;지울 문자&quot;, &quot;지운 문자 대신 바꿀 문자&quot;) 함수를 이용해서 제거시킵니다. 다른 라이브러리를 사용하여 해결할 수 있는 방법도 있지만 import를 사용하지 않고 그냥 내장함수만을 이용해서 코드를 작성한다면 이렇게 간단한 방법이 있을거 같습니다. 어차피 new_id의 최대 길이가 1,000 밖에 안되니 큰 문제는 될거 같지 않습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;3단계는 마침표가 2번이상 연속된 부분을 하나로 치환하는 것입니다. 저는 개인적으로 이 부분을 가장 까다롭다고 생각했는데요. '어떻게하면 간단하고 짧게 해결할 수 있을까?' 생각했던거 같습니다. 제가 생각한 방법은 while문을 사용하여 new_id에 &quot;..&quot;이 있으면 &quot;.&quot;으로 치환하는 방법입니다. &quot;...&quot;이더라도 앞의 &quot;..&quot;이 먼저 인식이 되서 &quot;..&quot;으로 바뀔 것이고 이는 한번 더 while문에 걸려서 &quot;.&quot;으로 바뀝니다.(&quot;...&quot; &amp;rarr; &quot;..&quot; &amp;rarr; &quot;.&quot;) 이렇게 하면 3단계 코드도 간단하게 완료 할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;4단계는 마침표가 처음이나 끝에 위치하면 제거하는 단계입니다. 이 부분은 인덱싱을 이용하면 쉽게 제거 할 수 있어서 다들 쉽게 하셨을거 같습니다. 저는 앞에 과정 때문에 길이가 0인 new_id일 경우 new_id[0]과 new_id[-1] 코드가 인덱싱 에러가 방생하여 앞에부분에 len(new_id) &amp;gt; 0이라는 조건을 넣어줬습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;5단계는 빈 문자열이면 &quot;a&quot;를 대입하는 단계입니다. 이 부분은 if문을 사용하시면 쉽게 하실 수 있는 부분이니 넘어가겠습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;6단계는 16자리 이상이면 15자리까지 남기고 나머지는 제거 &amp;amp; 끝자리에 마침표가 있으면 제거하는 단계입니다. 이부분도 if문을 사용하면 쉽게 구현할 수 있습니다. new_id가 15자리 초과라면 new_id를 슬라이싱하여 0~14까지 자릅니다. 그런 다음 new_id의 끝자리에 &quot;.&quot;이 있으면 제거해줍니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;마지막 7단계는 new_id가 2자리 이하라면 new_id의 마지막 문자를 반복하여 new_id의 길이를 3으로 만드는 단계입니다. 이 부분도 while, if문을 사용하면 쉽게 구현할 수 있었습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;이렇게 코드를 작성하면 다음과 같은 결과로 통과를 할 수 있었습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;스크린샷, 2021-02-11 16-22-46.png&quot; data-origin-width=&quot;938&quot; data-origin-height=&quot;657&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bPfpmC/btqWWtZsv1w/hVJKJmVgX0dvDJq0euHkh0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bPfpmC/btqWWtZsv1w/hVJKJmVgX0dvDJq0euHkh0/img.png&quot; data-alt=&quot;테스트 케이스 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bPfpmC/btqWWtZsv1w/hVJKJmVgX0dvDJq0euHkh0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbPfpmC%2FbtqWWtZsv1w%2FhVJKJmVgX0dvDJq0euHkh0%2Fimg.png&quot; data-filename=&quot;스크린샷, 2021-02-11 16-22-46.png&quot; data-origin-width=&quot;938&quot; data-origin-height=&quot;657&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;테스트 케이스 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;b&gt;5. 마치며&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;이번 문제도 크게 어려운 부분은 없었습니다. 빈문자열 처리, 무한루프에 빠지지만 않으셨다면 금방 해결하셨을거 같습니다. 저는 replace(), lower() 등을 사용하여 쉽게 구현했는데 내장 함수를 잘 모르시면 힘드셨을거 같습니다. 파이썬을 사용하신다면 파이썬의 큰 장점 중 하나인 내장 함수를 익히셔서 유용하게 사용하는 것을 추천드립니다. 내장 함수가 많은 만큼 기능은 비슷하지만 시간 복잡도, 공간 복잡도가 차이가 나는 함수들이 있습니다. 이런 것들을 잘 알고 비교해서 사용하신다면 시간초과가 나는 문제를 잘 해결하실 수도 있습니다.&lt;/p&gt;</description>
      <category>CS/Algorithm</category>
      <category>Python</category>
      <category>카카오 블라인드 채용</category>
      <category>코딩테스트</category>
      <category>파이썬</category>
      <category>프로그래머스</category>
      <author>일하는 개미</author>
      <guid isPermaLink="true">https://gee05053.tistory.com/14</guid>
      <comments>https://gee05053.tistory.com/14#entry14comment</comments>
      <pubDate>Thu, 11 Feb 2021 16:27:04 +0900</pubDate>
    </item>
    <item>
      <title>오랜만에 들립니다.</title>
      <link>https://gee05053.tistory.com/13</link>
      <description>&lt;p&gt;12월 8일 마지막 학기 종강을 알리는 글을 쓴 뒤, 종강하고 시간이 많으니 블로그에 일기 쓸겸 꾸준하게 관리 해야겠다고 생각했었는데 역시 사람이 한번 게을러지면 다시 일어나기 힘듭니다.. ㅋㅋㅋ 종강을 하고나서 훈련 준비 때문에 조금 바빴다는 핑계를 조금 대봅니다 ㅋㅋㅋㅋㅋ 12월 21일부터 1월 15일까지 학군단 마지막 훈련을 다녀왔습니다. 이번 겨울 훈련은 진짜 많이 추웠습니다.. 수족냉증이 있는 저에겐 너무 큰 고통이었어요  한달 정도의 훈련을 마치고 훈련 때 누리지 못했던 자유를 계속 누리면서 지냈습니다. 먹고, 자고 반복? 한마디로 백수죠 ㅋㅋㅋㅋ 그러다가 친구들이랑 잠깐 약속이 있으면 코시국이라 간단하게 밥만 먹고 오는 정도로.. 그러다가 저번주 2월 5일~2월 7일까지 부산에 다녀왔습니다. 항상 부산에 가고 싶다는 생각이 들었지만 코시국 때문에 계속 미뤘습니다. 하지만 이제 곧 입대고, 이번에 안가면 다음에도 기회를 잡기 힘들거 같아서, 바람이 불었을 때 바로 잡아서 3일만에 여행 계획, 예약 하고 다녀왔습니다. 가서 대학교에서 만들어진 가장 소중한 인연을 만나고 재미있게 놀다가 돌아왔습니다. 너무 재미있게 놀다와서 아직까지 여운이 많이 남아 있어요 ㅋㅋㅋㅋ 계속 '입대 전이지만 뭐라도 해야하는데' , '입대하고나서도 군대에 집중하기보단 코딩도 하면서 계속 폼을 유지해야하는데' 라고 계속 생각을 하지만 쉽게 일이 시작되지 않네요. 저 생각이 드는 동시에 '또 이런 시간을 누릴 날이 있을까?', '지금 걱정하는 시간도 아깝다.' 라는 생각도 들거든요 ㅋㅋㅋ  그래도 제가 내린 결론은 많이는 아니더라도 '하루를 헛되게 보내지 않았다.'라는 생각이 들 정도로만 하려고 합니다. 알고리즘 문제나 책을 읽으면서 조금씩 하면서 좋은 내용은 블로그에 정리하고 하려고 합니다. ㅎㅎ 3월은 새로운 시작을 알리는 달인거 같습니다. 개강, 군대, 다른 일 등등 각자의 상황에 맞게 잘 준비하셨으면 좋겠습니다.&lt;/p&gt;</description>
      <category>대학 &amp;amp; 일상 일기</category>
      <author>일하는 개미</author>
      <guid isPermaLink="true">https://gee05053.tistory.com/13</guid>
      <comments>https://gee05053.tistory.com/13#entry13comment</comments>
      <pubDate>Tue, 9 Feb 2021 16:12:17 +0900</pubDate>
    </item>
    <item>
      <title>대학교 과 선택, 컴퓨터 공학(소프트웨어학부) 준비?</title>
      <link>https://gee05053.tistory.com/12</link>
      <description>&lt;p&gt;&lt;b&gt;*주관적인 내용이 많습니다. 여러 글을 보면서 신중하게 결정하시길 바랍니다. 여러분이 노력해서 들어간 대학교 생활을 적성에 안맞아서 힘들어 하지 않았으면 좋겠어요.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;1. 배경&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;요즘 it계열의 과가 인기가 많습니다. 요즘 취업이 어려워지면서 그나마 취업이 잘되는 공대쪽 인기가 높아지고 있는데요. 제가 고등학생 때에도 &quot;문과는 답이없다. 이과가 미래다&quot; 라는 말을 자주 들었는데 요즘도 많이 듣는지 모르겠습니다. 실제로 대학에서도 전과를 선택하는 사람들이 많기도 합니다. 제가 소프트웨어학부이다보니 주변 친구 동생들, 어머니의 지인 자녀들도 이쪽으로 생각하는 분들이 많더라고요. 흔히 물어보시는게 당연히 &quot;미래는 어떻냐?&quot;, &quot;힘들진 않냐&quot;, &quot;어디 학교가 그래도 좋냐&quot; 등등의 질문이 들어옵니다. 제 블로그가 고등학생분들이 많이 들어올 블로그는 아니지만 혹시나 전과나 이쪽으로 생각이 있으신 분들, 자녀분들 때문에 검색해서 들어오시는 분들이 있을까해서 제가 그냥 4년동안 소프트웨어학부(컴퓨터 공학과)에서 보고 느낀 장단점, 학교 생활을 공유하고자 합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;2. 과를 선택하는데 있어 개인적으로 중요하게 생각하는 것&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;저는 개인적으로 적성을 가장 중요하게 생각해요. 저 같은 경우는 어릴 때부터 컴퓨터쪽에 가고싶어했고 적성도 우연히 잘 맞았습니다. 그래서 초등학생 5학년때 부터 장래희망에 컴퓨터 프로그래머가 되고 싶다고 적었습니다. 초중고등학교에서 흔히 진로시간에 직업적성검사? 같은 것도 해보았을 때 컴퓨터쪽이 자주 나오기도 했고요.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&amp;nbsp;하지만 현실은 자신이 하고싶은 것만으로는 할 수 없긴합니다. 그게 슬프다는 것은 알지만 현실이기도 하고, 제 주변에서도 성적만으로, 대학 가치가 높아서 들어간 친구들이 있습니다. 자신의 적성이나 하고싶은 것을 전혀 고려하지 않은 채로 말이죠. 예를 들면 연세대학교에 러시어학과 입학했지만 러시아어를 하나도 못하거나 관심이 없는 친구&lt;/span&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;(연세대학교에 이런 과가 있는지 확실하지 않으며 그냥 예를 든 것입니다.)&amp;nbsp;&lt;span style=&quot;color: #000000;&quot;&gt;문과쪽에 적성이 더 맞지만 취업을 고려해서 억지로 공대를 선택한 친구 등등 이렇게 선택한 친구들이 몇몇 있어요. 하지만 이런 친구들은 당연히 과에 대한 만족도도 낮으며, 중간에 전과를 하거나 졸업을 하고나서도 다른 길을 찾아보는 친구들이 많습니다. 제가 이 이야기를 왜하는지는 밑에 계속 읽어보시면 이해하실 겁니다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;3. 고등학교 성적&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&amp;nbsp;고등학생분들은 아무래도 성적을 가장 중요하게 생각하겠죠? 최대한 자신의 성적으로 높은 곳에 가고 싶다고 생각하실겁니다. 컴퓨터공학부는 공대치고는 성적이 그렇게 높은 편은 아닙니다. 어떤 대학의 공대에 입학 컷이 2.3이라면 컴공은 2.5~2.7정도? 더 후하게 잡으면 3.0까지도 차이났던거 같습니다.&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;(2017년도 기준)&amp;nbsp;&lt;/b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;저희 학교를 보니 제가 입학하고 나서 수시 교과 기준 컷이 엄청 높아졌긴 합니다만..(고3 담임선생님, 그 시기에 노력한 나한테 정말 감사합니다..) 그래도 대학들을 찾아보시면 대부분 대학들이 컴퓨터과가 있고, 컷도 공대기준에서는 음.. 그냥 적당하네? 라는 생각이 들었어요.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;4.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 적성? 어떤 사람들이 잘 적응할까요?&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;수학을 좋아하시는 분이거나 어떤 문제에 대해서 계속해서 고민하는 것을 좋아하시는 분이 컴퓨터공학에 잘 맞는거 같습니다. 또한 하나의 풀이법보다 다양한 풀이법에 도전하거나 생각을 하시는 분들도 나름 잘 맞다고 할 수 있겠네요. 이건 저의 개인적인 생각일뿐 사람마다 얼마나 잘 적응하고 행동하는지가 다르기 때문에 그냥 참고용으로만 봐주세요.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;5. 대학교 생활&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;아무래도 과제가 많습니다. 진짜 많아요.. 저는 주변에 다른 과친구들의 일상을 본적이 별로 없어서 저희 과가 과제가 많은건지 잘 몰랐습니다. 그냥 교수님이 내주시면 완성해서 제출하고, 짜증도 내고, 밤도 새고 했는데요. 3학년때 기숙사 생활을 하면서 저는 거의 매일 밤을 새는데 제 룸메이트들은 시험기간에만 공부를 조금하고 나머지 시간에는 편하게 보내는 것을 보고 차이를 많이 느꼈습니다. 그리고 대학생들 커뮤니티인 에브리타임에서도 보면 저희 과가 과제가 적은 편이 아니더군요;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;저는 장학금에도 욕심이 많이 있었고 대학원까지 생각이 있어 성적 관리에도 조금 신경을 많이 썼지만 그렇다고 하루종일 공부만해야 버틸 수 있는 과는 아닙니다. 저도 운동 동아리도 가입해서 활동을 했고, 그 동아리 회장도 해봤고.. 친구들과 술도 마시면서 평범한 대학생활을 했습니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;성비는 공대가 여성 비율이 적기로 유명하잖아요? 저희과는 신입생 때 기준으로 8:2~7:3정도? 였던거 같습니다. 많은 편은 아니지만 그렇다고 남성들만 득실거리는 정도는 아니였어요.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;6. 전과&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;대학생활을 하다보면 전과하는 사람들을 생각보다 많이 보는거 같습니다. 전과가 아니더라도 부전공으로는 자신의 전공과 다른 전공을 선택하는 사람이 많습니다. 저희 과는 새로 들어오는 사람들도 많지만 빠져나가는 사람들도 많습니다. 빠져나가는 사람들은 4.에서 말씀드린 사람들이 대부분입니다. 아무리 해보려고해도 적성이랑 안맞아서 도저히 못버티는 사람들이 많았습니다. 다시 수능을 보겠다고 나간 동기들도 많고요. 그래서 4.에서 성적이나 대학 네임을 보기보단 적성을 보고 고르라는 겁니다. 당연히 어떤 일을하더라도 쉬운 일이나 자신이 원하는 대로 실행되는 것은 별로 없습니다. 노력이 필요하고 인내가 필요합니다. 하지만 적성은 자신이 좋아하고 싫어하는게 정해져있는데 그걸 단순히 힘든거라고 생각하고 억지로 버티면 대학생활 4년동안 많이 힘들겁니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;7.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 건강&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;아무래도 장시간 한 자세를 유지하면서 앉아 있다보니 디스크 위험이 큽니다. 시력도 많이 떨어지기도 하고요. 저는 운동도하고 몸관리를 어느정도 한다고 생각했는데 작년에 좀 무리를하다보니 허리가 많이 안좋아지더라고요.. 작년에는 한시간 앉아있는 것도 힘들어서 한시간 앉아있고 한시간 쉬는시간 가지고 했을 정도였습니다. 저는 허리만 그렇지만 손목도 안좋아지는 사람도 많은거 같긴해요. 시력은 뭐 당연해지는 옵션이고.. 저는 밤낮을 많이 새면서 자주 밤낮이 바뀌고 하다보니 몸이 안좋아진 것도있는데 이건 사람들마다 관리하는 습관에서 다를거 같아요.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;8. 마무리&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt; 뭔가 컴퓨터 공학과에 대한 설명을 적을려는 글이었는데 어쩌다보니 대학 입시부터 시작해서 이야기가 조금 벗어난게 아닌가 싶습니다. 혹시 글에는 안담겨있지만 궁금하신점 있으시면 댓글에 남겨주세요. 이번 글도 읽어주셔서 감사합니다.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;</description>
      <category>대학 &amp;amp; 일상 일기</category>
      <category>소프트웨어학부</category>
      <category>컴공</category>
      <category>컴퓨터 공학과</category>
      <author>일하는 개미</author>
      <guid isPermaLink="true">https://gee05053.tistory.com/12</guid>
      <comments>https://gee05053.tistory.com/12#entry12comment</comments>
      <pubDate>Tue, 8 Dec 2020 22:31:59 +0900</pubDate>
    </item>
    <item>
      <title>마지막 학기 종강</title>
      <link>https://gee05053.tistory.com/11</link>
      <description>&lt;p&gt;&amp;nbsp;저번주 토요일에 시험을 끝으로 마지막 학기도 끝났습니다. 원래는 이번주부터 시험기간이지만 온라인 수업이기도하고 교수님도 빨리 시험보고 다른 과목 공부하는게 좋지 않겠냐면서 일찍 보시더군요.(저는 다른 과목 공부할게 없지만요 ㅎㅎ) take home exam 형식으로 봤는데 꽤 힘들었습니다. 문제를 완전 어렵게 내시는 교수님은 아니시지만 시간이 조금 딱 맞아떨어지거나 부족하게 내시는 교수님이신 것을 알고있었지만, 이번 수업에서 그렇게 어렵다고 느낀 부분도 없었고, 암기가 아닌 실습으로 진행하는 시험이라서 금방 끝내지 않을까 했는데... 역시나 교수님은 생각이 있으시더군요 ㅎㅎ..&lt;/p&gt;
&lt;p&gt;&amp;nbsp;아침 9시에 문제가 나오고 24시까지만 제출하면 되는 형식이었습니다. 절반 정도는 쉽게 진행해서 '오.. 빨리 끝내겠군' 생각하는 순간 나머지 문제들이 까다롭더라고요. 이게 바로 응급실에서 &quot;오늘은 한적하네&quot; 나 애니에서 &quot;해치웠나&quot; 하는 것처럼 플레그를 세운건가 싶더라고요... 그래도 최대한 해서 제출을 하긴했는데 중간중간 실수를 통해서 다시 작업하는게 너무 화가.. 한번 동작하는데 1시간 걸리는걸 터미널에서 ctrl+c눌러버려서.. 핳&lt;/p&gt;
&lt;p&gt;&amp;nbsp;결국 15시간 꽉 채워서 겨우 제출했습니다. 밥도 15시쯤 배가 너무 고파서 10분만에 밥 먹고 다시 컴퓨터 잡은거 말고는 쉬는 시간도 안가지고 했더라고요. 12시간이 지났을 때부터는 허리에 통증이.. (다들 허리하고 손목 조심하세요..) 제출하고 늦은 저녁을 먹었답니다. 그날 끝나고 뭔가 개운하거나 고생했다 느낌이 들줄 알았는데 15시간동안 앉아만 있었더니 멍.. 하더라고요. 피곤해서 일찍 자려고해도 허리가 너무 아파서 4시까지 못잤어요 ㅠㅠ&lt;/p&gt;
&lt;p&gt;&amp;nbsp;주말에 글을 쓰려고했는데 어제까지 아무것도 안해서 이제야 글을 쓰네요. 사람이라는게 한번 게으른 맛을 보면 다시 일어나기가 힘든거 같습니다;;ㅎㅎ 정신 좀 차리고 마지막 학기가 끝났다고 생각하니 뭔가 '이제 끝났구나' 라는 생각도 들고 지난 학교 생활들이 생각 나더라고요. 이런저런 생각하다가 의미없는 성적표도 다시 한번 보고.. ㅋㅋㅋ 이제 2달 뒤에 3500만원짜리 졸업장만 받으면 진짜 끝이라니. 하나의 과정을 끝날 때마다 드는 이 기분은 적응이 안되는거 같습니다. 다음 과정인 군대도 끝날 때 비슷한 기분이겠죠..? ㅋㅋㅋ&lt;/p&gt;
&lt;p&gt;&amp;nbsp;훈련까지 12일 정도 남았는데 크게 생각안하고 조금은 즉흥적으로 살아볼까 합니다. 코딩하고 싶을 땐 코딩하고, 드라마보고 싶으면 드라마보고, 졸리면 낮잠도 자면서.. 얼마 안남은 시간을 즐기면서 보내려고요. 다른 분들은 이제야 시험이 시작했을텐데 다들 올해 마무리 잘하시고 A+받아가시면 좋겠습니다.&lt;/p&gt;</description>
      <category>대학 &amp;amp; 일상 일기</category>
      <author>일하는 개미</author>
      <guid isPermaLink="true">https://gee05053.tistory.com/11</guid>
      <comments>https://gee05053.tistory.com/11#entry11comment</comments>
      <pubDate>Tue, 8 Dec 2020 19:30:42 +0900</pubDate>
    </item>
    <item>
      <title>MapReduce 동작</title>
      <link>https://gee05053.tistory.com/10</link>
      <description>&lt;p&gt;&lt;b&gt;*해당 글은 국민대학교 2020년 빅데이터 플랫폼 수업에서 배운 내용을 제가 이해한 내용을 바탕으로 작성했으며 pdf 내용을 그대로 사용하지 않았습니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;1. 배경&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;이전 글에서는 Hadoop과 MapReduce가 왜 연관이 되어 있는지에 대한 내용을 작성했습니다. 이번에는 Map과 Reduce의 기능을 살펴보고 MapReduce의 Map과 Reduce가 어떻게 동작하는지 알아보겠습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;2. Map&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;MapReduce의 첫번째 단계인 Map입니다. Map은 input 데이터들에 대해서 공통의 작업을 실행해서 원하는 형태로 만들어 줍니다. 예를 들자면 어떤 하나의 리스트에 담긴 정수들을 절대값 형태로 바꾸고 싶다고 가정을 합시다. 그렇다면 이때 리스트 안에 있는 원소들에 대해서는 원소를 절대값으로 바꾸는 공통의 작업을 실행합니다. 이렇게 원소들에게 어떤 작업을 통해서 공통된 형태를 만들어 줄 때 Map을 사용합니다. 스칼라 코드로 예를 들면 List(-10, 3, -4, 1).map(x=&amp;gt; Math.abs(x))라는 코드를 작성하면 예를 든 리스트의 원소를 절대값 형태로 바꿔주는 Map 함수를 작성한 것입니다.&amp;nbsp;일반적으로 MapReduce에서의 Map은 input 데이터를 (key, value)형식으로 만들어주는 역할을 합니다. 즉 다시 스칼라 코드로 예를 들면 List(-10, 3, -4, 1).map(x=&amp;gt; (x,1)) 이런식으로 작성하며 이때 map함수를 거친 리스트의 결과 값은 List((-10,1), (3,1), (-4,1) (1,1))의 형태가 나타날 것입니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;3. Reduce&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;Reduce는 입력으로 주어진 리스트 또는 집합 원소에 주어진 함수를 실행해서 하나의 값으로 모으는 작업을 진행합니다. 스칼라 코드를 예를 들면 List(-10, 3, -4, 1).reduce((x,y)=&amp;gt; x+y)를 실행하면 리스트의 전체 원소의 합인 -10이 나옵니다. Reduce에서는 주의할 점이 있습니다. 윗줄의 scala코드에서 (x,y)를 입력으로 받는 것을 볼 수 있습니다. 처음보는 사람들은 x와 y에는 순서대로 값이 들어 갈 것이라고 예상하는데 그렇지 않습니다. 즉 &lt;span style=&quot;color: #333333;&quot;&gt;List(-10, 3, -4, 1).reduce((x,y)=&amp;gt; x+y) 코드에서 -10+3+(-4)+1 순서로 계산이 될지 3+(-10)+1+(-4) 순서로 계산이 될지는 아무도 모릅니다. 즉 계산 순서의 변경으로 결과가 달라지는 함수를 정의해서는 안됩니다. 예를 들면 뺄셈, 나눗셈 등등이 있겠네요. &lt;/span&gt;MapReduce의 Reduce는 위에서 설명한 Map을 통해서 나온 (key, value)로 이루어진 리스트를 같은 키 값끼리 묶어서 계산하는 역할을 합니다. 이것이 이해가 안간다면 다음 문단에서 예시로 확인해도 되겠습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;4. MapReduce 활용&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;MapReduce의 예제로는 WordCount를 이용해서 예를 듭니다. 다른 예로는 페이지 랭크 알고리즘이나 문서(또는 책)에서의 특정 키워드가 몇페이지에 나타나는지 알려주는데에도 사용이 됩니다. 여기에서도 WordCount를 예로들어서 설명을 하겠으며 WordCount에서 이해한 내용을 바탕으로 다른 예제를 어떤식으로 구현하면 될지 생각해보시는 것도 좋을거 같습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;입력데이터는 &quot;This is a peach and that is a apple&quot;을 사용하겠으며 여기 문장에서 쓰인 단어들이 각각 몇개가 사용되었는지 알아보는 WordCount를 진행해보겠습니다. 언어는 scala를 통해서 진행하겠습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;우선 입력 데이터가 우리가 원하는 단어 형태로 split이 되어 있는 것이 아니라 문장으로 들어왔습니다. 그렇다면 Map을 실행하기 전에 단어로 split해주는 작업이 필요할거 같습니다. .split(&quot; &quot;)을 사용하면 띄어쓰기로 split이 되므로 각 단어들을 원소로하는 리스트가 반환이 될거 같습니다. 그렇다면 결과 형태는 List(&quot;This&quot;, &quot;is&quot;, &quot;a&quot;, &quot;peach&quot;, &quot;and&quot;, &quot;that&quot;, &quot;is&quot;, &quot;a&quot;, &quot;apple&quot;) 입니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;이 상태에서 Map 과정을 실행할 것입니다. 각 단어를 key로, 사용된 횟수를 value로 사용하기 위해서는 리스트의 원소들을 (key, value) 형태의 튜플로 만들어줘야겠네요. .map(x=&amp;gt; (x,1))을 사용한다면 결과는 List((&quot;This&quot;, 1), (&quot;is&quot;, 1), (&quot;a&quot;, 1), (&quot;peach&quot;, 1), (&quot;and&quot;, 1), (&quot;that&quot;, 1), (&quot;is&quot;, 1), (&quot;a&quot;, 1), (&quot;apple&quot;, 1)) 형태로 바뀔 것입니다. 각 단어들에게 value 1을 부여했습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;다음으로는 Reduce 과정을 실행해서 같은 key값들의 value를 다 더해준다면? (각 단어, 나온 총 횟수) 형태로 바뀔 것입니다. .reduceByKey((x,y)=&amp;gt; x._2 + y._2)를 작성하면 value를 더한 형태가 반환 될 것입니다. 이렇게된다면 최종결과는 List((&quot;This&quot;, 1), (&quot;is&quot;, 2), (&quot;a&quot;, 2), (&quot;peach&quot;, 1), (&quot;and&quot;, 1), (&quot;that&quot;, 1), (&quot;apple&quot;, 1))이 됩니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;5. 글을 마치며&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;이번 글에서는 Map과 Reduce가 어떤 기능을하며 MapReduce에서는 각각 어떤식으로 주로 사용되는지 알아보았습니다. Map과 Reduce 함수에 대해서는 코딩을 조금 해보신 분들은 다른 언어에서도 사용을 해보셔서 비슷하다고 느끼거나 별 내용이 없다고 느끼셨을거 같습니다. 맞습니다.. 아마도 처음보신 분들도 '별 내용없네' 라고 생각하셨을거 같지만..ㅎ 부족하지만 읽어주셔서 감사합니다.&lt;/p&gt;</description>
      <category>CS/빅데이터</category>
      <category>Map</category>
      <category>mapreduce</category>
      <category>reduce</category>
      <author>일하는 개미</author>
      <guid isPermaLink="true">https://gee05053.tistory.com/10</guid>
      <comments>https://gee05053.tistory.com/10#entry10comment</comments>
      <pubDate>Tue, 8 Dec 2020 18:16:45 +0900</pubDate>
    </item>
    <item>
      <title>MapReduce? Hadoop? 둘이 다른거야?</title>
      <link>https://gee05053.tistory.com/9</link>
      <description>&lt;p&gt;&lt;b&gt;1. 글의 배경&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;2016년 알파고와 이세돌의 대국이후에 인공지능에 대한 관심을 많이 받기 시작했습니다. 물론 전공자들은 이전부터 계속 개발을 하고있었지만, 대중들은 SF영화 속에서만 보던 인공지능의 성능을 직접 보고 느끼게 한 것은 알파고가 엄청난 역할을 한거 같습니다. 인공지능에 대해서 잘 모르셔도 인공지능에 대한 가벼운 지식을 가지고 있으신 분들은 인공지능이 알파고처럼 뛰어난 성능을 나타나게 하기위해서는 많은 데이터를 가지고 학습을 해야한다는 점을 아실 것입니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;인공지능이 떠오르면서 당연히 데이터에 대한 가치가 엄청나게 커졌고 빅데이터를 원하는 작업을 위해 변형하고 수정하는 것도 중요해졌습니다. 하지만 빅데이터를 가지고 작업을 한다는 것은 쉬운 일이 아닙니다. &lt;span style=&quot;color: #333333;&quot;&gt;혹시 100MB크기나 그 이상이 되는 txt파일을 열어본 적이 있으신가요? 좋은 성능의 컴퓨터를 가지신 분은 크게 불편한 점을 못느끼셨을 수도 있지만 저는 그렇게 좋은 성능의 컴퓨터를 가지고있지 않아서;; 저런 큰 용량의 파일을 열었을 때 컴퓨터가 버벅거리거나 멈춰버린 경험이 있었습니다. 그 파일가지고 변형하는 작업이 아니라 그저 파일을 연 작업만 했을 뿐인데 벌써부터 작업에 어려움이 발생했죠. &lt;/span&gt;빅데이터를 가지고있기 위해서 많은 디스크 용량이 필요하고, 빅데이터를 가지고 작업하기 위해서는 메모리와 CPU의 성능도 중요합니다. 기업에서는 사업을 하기위해서 좋은 성능을 가진 컴퓨터나 장비를 마련할 수 있지만, 학생이나 일반 사용자들은 그런 장비들을 마련하기는 쉬운 일이 아닙니다. 또한 장비가 있더라도 이러한 작업을 가능하게해주는 소프트웨어도 필요하겠죠.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;빅데이터에 대한 중요성이 커지면서, 빅데이터를 가지고 작업할 수 있는 기술도 중요해졌다는 것은 알겠는데, 개인적으로 Hadoop과 MapReduce에 대해서 처음 들었을 때, 이 둘이 뭐가 다른건지 많이 헷갈려했습니다. 여러 블로그를 찾아보아도 이 둘의 설명을 혼동해서 적으신 분들도 많았고요. 이번 글에서는 빅데이터를 쉽게 다룰 수 있게 만들어준 MapReduce와 Hadoop에 대해서 개인적으로 이해한 내용을 토대로 작성해보겠습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;2. MapReduce와 Hadoop이 등장하기 전&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;MapReduce와 Hadoop이 등장하기 전에 배경에 대해서 조금 알아볼 필요가 있습니다. 위에서 말했다시피 빅데이터를 다루는 것은 마냥 쉬운 일이 아닙니다. 과제가 밀렸을 때 한번 쯤은 몸이 여러개 였으면 좋겠다고 생각해보시지 않으셨나요? 그런 것처럼 큰 용량의 데이터를 변형하고 처리하기 위해서는 일을 분산하고 병렬로 작업하는 과정이 필요합니다. 그리고 큰 데이터를 처리하다보면 처리 시간도 오래걸리고 컴퓨터 성능에 따라서 컴퓨터가 멈춰버리거나 작업이 실패하는 경우도 종종 발생합니다. 실패하는 경우에는 어떻게 처리해줘야할까요? 그냥 소프트웨어가 꺼지거나 작업한 데이터가 날아가버리면 아무도 그 소프트웨어를 사용하지 않겠죠? 이렇게 실패(failure)에 대한 처리도 필요합니다. MapReduce와 Hadoop이 등장하기 전에는 분산 병렬 작업, 실패처리를 관리해주는 소프트웨어가 없었습니다. 그렇기 때문에 빅데이터를 가지고 작업하는 것은 너무 어려운 일이었죠. 그래서 MapReduce와 Hadoop이 등장했습니다. Hadoop은&lt;span style=&quot;color: #333333;&quot;&gt; 위에서 말한 분산 병렬처리 와 실패에 대한 처리 문제들 해결할 수 있도록 해주었습니다. 또한 MapReduce는 분산 병렬처리된 작업들을 받아서 데이터를 작업해주는 역할을 합니다.&lt;span style=&quot;color: #333333;&quot;&gt;(2006년의 하드웨어 가지고 이러한 소프트웨어를 만들어냈다니.. 이래서 성공한 기업이 아닌가 싶습니다.)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;3. MapReduce? Hadoop?&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;MapReduce와 Hadoop을 각각 검색해도 둘은 빠지지 않는 관계인거 같습니다. 그래서 이 둘이 같은 것인지 헷갈리는 사람들도 있고 이해를 잘못하는 경우도 있습니다. 조금 차이가 있긴 하지만 로고도 둘다 노란색 코끼리.. 머리가 아픕니다. 그렇다면 이 둘은 뭐가 다른 것일까요? 왜 이렇게 MapReduce를 설명하면 Hadoop이 따라오고 Hadoop을 설명하면 MapReduce가 따라오는 걸까요?&lt;/p&gt;
&lt;p&gt;&amp;nbsp;먼저 MapReduce는 2004년 구글에서 대용량 데이터 처리를 분산 병렬 컴퓨팅에서 처리하기 위한 목적으로 제작한 소프트웨어 프레임워크입니다. MapReduce는 이름에서 나와있듯이 Map작업과 Reduce 작업으로 나눌 수 있습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;Hadoop의 본명은 Apache Hadoop으로 대량의 자료를 처리할 수 있는 큰 컴퓨터 클러스터에서 동작하는 분산 응용 프로그램을 지원하는 자바 소프트웨어 프레임워크로서 2006년에 나왔습니다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;둘다 대량의 자료를 처리할 수 있게 만들어진거면 둘이 같은거냐? 아닙니다. 쉽게 이해하자면 Hadoop안에 MapReduce가 있다고 생각하시는게 이해하시기 편한거 같습니다. 빅데이터를 처리하기 위해서는 큰 용량과 분산, 병렬처리환경이 필요하다고 했습니다. 이렇게 빅데이터를 저장할 수 있는 큰 용량과 분산, 병렬처리 환경을 제공해주는 것이 Hadoop이고 그 안에서 분산된 데이터를 작업해주는 것이 MapReduce라고 생각하시면 될거 같습니다. Hadoop과 MapReduce의 안에서 각각 동작은 추후에 따로 작성하겠습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;4. 결론&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;빅데이터에 대한 중요성이 커지면서 이러한 빅데이터를 변형하고 다루는 작업도 같이 중요해졌습니다. 하지만 이러한 빅데이터를 가지고 작업한다는 것은 쉬운 일이 아니었습니다. 큰 용량의 데이터를 처리함으로써 발생하는 문제점들이 많았거든요. 이렇게 개발자들이 어려움을 겪을 때 이 어려움들을 잘 처리해준 것이 Hadoop과 MapReduce입니다. 이상으로 이번 글도 마치겠습니다. 읽어주셔서 감사합니다.&lt;/p&gt;</description>
      <category>CS/빅데이터</category>
      <category>hadoop</category>
      <category>mapreduce</category>
      <author>일하는 개미</author>
      <guid isPermaLink="true">https://gee05053.tistory.com/9</guid>
      <comments>https://gee05053.tistory.com/9#entry9comment</comments>
      <pubDate>Thu, 3 Dec 2020 14:13:58 +0900</pubDate>
    </item>
    <item>
      <title>내가 Python을 사용하는 이유</title>
      <link>https://gee05053.tistory.com/8</link>
      <description>&lt;p&gt;&lt;b&gt;1. 배경&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&amp;nbsp;블로그 글을 쓴지 3일정도가 되었고 Algorithm 카테고리에는 이제 2개의 글이 올라갔다. Algorithm이라고 거창하게 카테고리를 만들었지만 실제로는 그냥 내가 문제를 푼 해석을 풀이해논 페이지이다. 다양한 언어를 능숙하게 사용한다면 좋겠지만 이전 글을 쓰면서 '내가 다른 언어를 사용할 일이 있을까?'라는 생각이 들었다. 그 생각 결과 음.. 굳이? 라는 생각이 들었다. 그래서 나는 어쩌다가 Python을 선택하게 되었을까를 생각하다가 이렇게 글을 써본다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;2. Python이란?&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&amp;nbsp;Python은 1991년 프로그래머인 귀도 반 로섬이 발표한 고급 프로그래밍 언어이다. Python의 특징이라고 하면 인터프리터, 객체지향적 언어라는 것이다. 객체지향적이라는 것은 다른 언어에서도 많이 들었을테니 대충 알 것이고 인터프리터 언어라는 것은 특별한 컴파일이 없어도 바로 idle에서 실행할 수 있는 것을 말한다. Java를 사용해본 유저라면 코드를 작성하고 컴파일을 거친다음 작성한 코드가 실행된다. 하지만 Python에서는 해당 코드를 작성하고 실행을 누르면 바로 실행 시킬 수 있다. 또한 terminal에서도 python3(또는 python2)를 입력하면 바로 실행되어 코드를 작성해도 바로바로 결과를 얻을 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&amp;nbsp;Python은 처음 코딩을 시작하는 사람들에게 가장 많이 추천되는 언어이다. 그 이유는 다른 언어에 비해서 엄청 쉽다. 처음 코딩을 시작해서 Python을 만져보는 사람들은 &quot;이것도 어려워 죽겠는데 도데체 뭐가 쉽다는거지?&quot; 라는 생각이 들 수도 있지만 C++과 Java 등을 만지다가 Python을 만져본 사람들은 엄청난 신세계의 경험을 했을 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&amp;nbsp;이러한 이유로 Python의 인기는 계속해서 증가하고 있으며 2016년 알파고와 이세돌의 대국을 통해서 엄청난 관심을 받게된 인공지능을 개발하는 라이브러리인&amp;nbsp; Pytorch와 TensorFlow도 Python을 기반해서 나왔다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;3. 나는 어쩌다가 Python을?&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&amp;nbsp;그렇다면 나는 왜 Python을 선택했을까? 처음부터 나도 Python을 주언어로 선택한 것은 아니다. 대학생 1학년 2학기에 처음으로 자바를 다뤄봤다. 그 당시에는 무슨 생각이었는지 모르겠지만 자바를 만지면서 &quot;와 재미있다.&quot;, &quot;멋진 언어다.&quot; 라는 생각을 했었다. 지금 생각하면 왜 그랬는지 모르겠다. System.out.println()과 같이 긴 코드들이 멋져보인건지, 어디에 홀린건지..ㅋ 그러다가 방학을 보내고 다시 개강을 했을 때 자바를 보니 이게 무슨일? 하나도 안떠올라.. 간단한 코드를 작성하는데도 빨간 글씨 에러가 얼마나 많이 나오던지..ㅋㅋㅋ (이때부터라도 정신차리고 블로그에 기록을 했어야했네;;) 이전 학기에는 멋져보이던 언어가 너무 귀찮게 느껴졌다. class선언하는데 private, public 고려해야하고, '왜이리 코드들이 길어..' 라는 생각이 계속 들었다. 그래서 점점 java와 거리가 멀어졌고, 2학년 1학기에는 C++수업을 들었다. C++은 처음부터 나랑 안맞는다는 느낌이 들었다 ㅋㅋㅋㅋㅋ iterator도 복잡했고 뭐하나 쉬운게 없었다.. 그래도 소프트웨어과인데 내 주언어는 하나 있어야하지 않을까하다가 Python을 선택했다. 위에서 설명했던 쉽다는 장점이 크게 느껴졌고, 코드를 작성하기 편했다. 그래서 '그래 이게 나한테 맞는거 같아.' 라고 생각이 들었고 그때부터 주 언어로 선택한걸로 기억한다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;4.&lt;/span&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt; Python을 사용하면서 불편한 점은?&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&amp;nbsp;Python의 큰 장점이 쉽고 편리한 내장함수와 라이브러리가 많다는 장점이 너무 커서 크게 불편했던 적은 없다. 하지만 몇가지 떠오르긴한다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&amp;nbsp;우선 다른 언어에 비해 속도가 느린편인 것입니다. 이게 평소에는 별로 차이를 못느끼지만 코딩테스트에서 똑같은 알고리즘은데 C++로는 통과하고 Python으로는 통과하지 못하는 경우가 종종 발생합니다. 이러한 차이가 있는 이유는 파이선이 동적 타입이기 때문에 변수 이름 앞에 string이나 int와 같은 타입 지정없이 알아서 해줍니다. 우리에겐 정말 편리한 기능이지만 그 과정이 파이썬에게는 많이 부담이 되는 과정입니다. 이와 반대로 C++과 Java와 같은 언어들은 변수 앞에 int, string 등등 타입을 지정해줍니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&amp;nbsp;두번째로는 코딩테스트에서 Python을 지원하지 않는 회사가 종종 있습니다. 요즘은 대세 언어이고 인공지능에도 많이 사용하다보니 거의 없지만 대표적인 대기업으로는 삼성이 있습니다. 삼성도 테스트나 때에 따라서 다른거 같지만 삼성 SW역량 테스트에서 Java, C++, C만 지원하는 경우가 있습니다. 정확한 테스트 이름은 기억이 안나지만 올해 삼성에서 열린 코딩테스트가 있었는데 한번 테스트삼아 지원을 하려고했지만 Python이 없는거 보고 좌절... OTL. 다른 회사들도 종종 Python을 테스트 자체에서 지원하지 않는 경우가 종종 있다고 들었습니다. 그 이유는 뭐 여러가지가 있겠지만 인기있는 언어를 이렇게 제외시킨다는 것은 주언어 사용자 입장에서는 많이 슬픕니다..&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;5. Python 관련 추천 책&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;저는 Python에 대한 기본 지식은 google에서 검색하면서 공부했고 알고리즘 관련 공부는 아래 책을 사용했습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;스크린샷, 2020-11-23 17-59-23.png&quot; data-origin-width=&quot;479&quot; data-origin-height=&quot;623&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yguem/btqN8f2xolB/wIDOZmwIe4Uq5FHMR44cUK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yguem/btqN8f2xolB/wIDOZmwIe4Uq5FHMR44cUK/img.png&quot; data-alt=&quot;파이썬 알고리즘 인터뷰&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yguem/btqN8f2xolB/wIDOZmwIe4Uq5FHMR44cUK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fyguem%2FbtqN8f2xolB%2FwIDOZmwIe4Uq5FHMR44cUK%2Fimg.png&quot; data-filename=&quot;스크린샷, 2020-11-23 17-59-23.png&quot; data-origin-width=&quot;479&quot; data-origin-height=&quot;623&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;파이썬 알고리즘 인터뷰&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;저도 대학 동기한테 추천받아서 읽어보았는데 내용이 튼튼하고 잘 설명되어있었습니다. 개인적으로 책 읽는 것을 별로 안좋아하는데도 나름 재미있게 읽으면서 공부했습니다. 초보자분들도 쉽게 이해할 수 있고 여러 알고리즘에 대해서 익힐 수 있는 책이었습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;코딩테스트 연습은 저는 프로그래머스를 주로 사용하는 편입니다. 카카오 관련 문제나 여러 코딩테스트 문제들이 많이 올라오거든요. 다른 사람들은 백준 사이트도 많이 이용하시는 것 같습니다. 여러 사이트를 이용해보시고 자신에게 맞는 사이트에서 공부하시는게 조금이라도 더 즐겁고 편하겠죠?&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;6.&lt;/span&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt; 마치며&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt; 이번 글에서는 Python에 대해서 간단하게 소개하며 제가 왜 Python을 사용하게 되었는지 소개했습니다. 혹시 아직 주언어를 정하지 못하신 분들, 처음 코딩을 시도하시는 분들이라면 Python을 주언어로 해보시는 것을 추천드립니다. 정말 편리하거든요bb&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;읽어주셔서 감사합니다.&lt;/span&gt;&lt;/p&gt;</description>
      <category>CS/Algorithm</category>
      <category>Algorithm</category>
      <category>Python</category>
      <author>일하는 개미</author>
      <guid isPermaLink="true">https://gee05053.tistory.com/8</guid>
      <comments>https://gee05053.tistory.com/8#entry8comment</comments>
      <pubDate>Mon, 23 Nov 2020 18:02:43 +0900</pubDate>
    </item>
    <item>
      <title>프로그래머스 Level 1 두개 뽑아서 더하기</title>
      <link>https://gee05053.tistory.com/7</link>
      <description>&lt;p&gt;&lt;b&gt;1. 문제 파악하기&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;- 0이상 100이하인 정수가 들어있는 numbers의 길이는 2이상 100이하이다.&lt;/p&gt;
&lt;p&gt;&amp;rarr; 그렇게 길지 않은 데이터네요.&lt;/p&gt;
&lt;p&gt;- 더할 수 모든 수를 리스트에 담아서 오름차순으로 return 해야한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;2. 문제 접근하기&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;이 문제를 읽고 서로 다른 인덱스에 있는 두 개의 수를 더하라는 말을 보고 바로 이중 for문이 떠오릅니다. 이중 for문을 사용하면 시간복잡도는 n^2이라 좋은 성능의 알고리즘은 아니지만 문제 조건에서 numbers의 길이가 2이상 100이하라고 주어진 것을 보니 시간제한이 걸릴만한 길이는 아닐거 같습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;3. 주의할 점&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;얼핏보면 간단한 알고리즘인거 같지만 정답을 맞추기 위해서 몇가지 주의를 놓치면 조금 헤맬수 있습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;- return할 리스트에 중복 값이 들어가면 안된다.&lt;/p&gt;
&lt;p&gt;&amp;rarr; 입출력의 예를 보면 2+3, 1+4로 5가 여러번 나올 수 있습니다. 하지만 result에 보면 5가 한번밖에 나타나 있지 않죠. 중복 값이 나타난다면 제거를 해야한다는 뜻입니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;- return하는 리스트는 오름차순으로 정렬해야한다.&lt;/p&gt;
&lt;p&gt;&amp;rarr; 쉬운 조건이지만 놓칠 수 있는 조건입니다. 문제를 꼼꼼히 읽어야할 필요가 있습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Python을 능숙하게 사용하신 분들이라면 해당 문제를 쉽고 빠르게 해결하셨을 문제입니다. 하지만 Python을 다룬지 얼마 안되신 분들이나, Python 내장함수를 잘 모르시는 분들이라면 코드가 길어질 수 있습니다. Python의 장점은 이전 글에도 설명을 드렸지만 다른 언어보다 내장함수가 잘 되어있어 Python 내장함수만 알아도 문제를 쉽고 짧은 코드로 해결할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;4. 정답 코드 및 해석&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;따라서 정답 코드는 아래와 같다고 할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;스크린샷, 2020-11-23 16-50-49.png&quot; data-origin-width=&quot;431&quot; data-origin-height=&quot;227&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bEkCNx/btqNYv60QTW/IzSPCoHcYdz8ffkyyt4dMK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bEkCNx/btqNYv60QTW/IzSPCoHcYdz8ffkyyt4dMK/img.png&quot; data-alt=&quot;정답 코드&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bEkCNx/btqNYv60QTW/IzSPCoHcYdz8ffkyyt4dMK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbEkCNx%2FbtqNYv60QTW%2FIzSPCoHcYdz8ffkyyt4dMK%2Fimg.png&quot; data-filename=&quot;스크린샷, 2020-11-23 16-50-49.png&quot; data-origin-width=&quot;431&quot; data-origin-height=&quot;227&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;정답 코드&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;스크린샷, 2020-11-23 16-52-37.png&quot; data-origin-width=&quot;537&quot; data-origin-height=&quot;252&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dKCJ3R/btqN01dm7rZ/eUQ1l9XDSibjlTWOUbPfH0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dKCJ3R/btqN01dm7rZ/eUQ1l9XDSibjlTWOUbPfH0/img.png&quot; data-alt=&quot;정확성 테스트 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dKCJ3R/btqN01dm7rZ/eUQ1l9XDSibjlTWOUbPfH0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdKCJ3R%2FbtqN01dm7rZ%2FeUQ1l9XDSibjlTWOUbPfH0%2Fimg.png&quot; data-filename=&quot;스크린샷, 2020-11-23 16-52-37.png&quot; data-origin-width=&quot;537&quot; data-origin-height=&quot;252&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;정확성 테스트 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;앞에서 설명했다 싶이 2중 for문을 사용했습니다. 앞에 for문은 numbers의 처음부터 시작해야하며 numbers의 끝까지 가면 됩니다. 두번째 for문은 i랑 다른 인덱스에서 시작해야하므로 i+1에서 시작하면 됩니다. 그래서 answer 리스트에 두 인덱스에 해당하는 값을 더합니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;이렇게 for문을 빠져나오면 answer에는 아까 주의할 점에서 언급한 것과 같이 중복 된 값이 들어있고 정렬되어 있지 않은 상태입니다. Python에는 아주 감사하게도 set()이라는 함수와 list()라는 함수가 있습니다. set()은 우리가 흔히아는 집합입니다. set이 list와 다른 점은 중복된 값을 저장할 수 없으며 순서를 보장하지않는다는 점입니다. 따라서 우리는 중복 값을 제거하기 위해서 set(answer)를 사용합니다. 하지만 이렇게만 하면 정렬할 때 조금 귀찮아집니다. 따라서 중복을 없앤 set(answer)에 list(set(answer))를 사용하여 다시 리스트로 만들어줍니다. 리스트에는 sort()함수를 사용하여 쉽게 오름차순으로 만들 수 있습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;이렇게 해서 return을 하면 정답을 얻어 낼 수 있습니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;5. 다른 풀이방법&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;이렇게 2중 for문을 사용하지 않고 이 문제를 해결하는 방법은 없을까요? 있습니다. itertools.combinations를 사용해서 문제를 해결할 수 있습니다. itertools.combination은 특정 리스트 원소로 조합을 만들어 냅니다. itertools 라이브러리도 사용법을 안다면 많은 알고리즘 문제를 깔끔하게 해결할 수 있는 경우가 많습니다. 단점은 라이브 코딩도중 해당 라이브러리 이름이 떠오르지않는다면 난감하다는 점이겠죠..;;; 또 저같은 경우는 itertools를 거의 사용하지 않는 편인데요. 그 이유는 아래에서 다시 언급하겠습니다. itertools 라이브러리에는 combinations뿐만 아니라 다른 유용한 함수들도 많습니다. combinations와 다른 함수들을 사용하는 방법은 google에 직접 찾아보시길 바랍니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;itertools.combinations를 사용하면 아래와 같이 코드를 작성할 수 있으며 해당 코드 결과입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;스크린샷, 2020-11-23 17-05-59.png&quot; data-origin-width=&quot;474&quot; data-origin-height=&quot;224&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/OKuWQ/btqN2VRslXm/r1P3Bi5MzavLLJkOImmQW0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/OKuWQ/btqN2VRslXm/r1P3Bi5MzavLLJkOImmQW0/img.png&quot; data-alt=&quot;combinations를 활용한 정답 코드&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/OKuWQ/btqN2VRslXm/r1P3Bi5MzavLLJkOImmQW0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOKuWQ%2FbtqN2VRslXm%2Fr1P3Bi5MzavLLJkOImmQW0%2Fimg.png&quot; data-filename=&quot;스크린샷, 2020-11-23 17-05-59.png&quot; data-origin-width=&quot;474&quot; data-origin-height=&quot;224&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;combinations를 활용한 정답 코드&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;스크린샷, 2020-11-23 17-06-38.png&quot; data-origin-width=&quot;411&quot; data-origin-height=&quot;260&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0187S/btqN5f90upY/rJYyJ7PVW6pLUtbgFrBQ60/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0187S/btqN5f90upY/rJYyJ7PVW6pLUtbgFrBQ60/img.png&quot; data-alt=&quot;combinations를 활용한 정확성 테스트 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0187S/btqN5f90upY/rJYyJ7PVW6pLUtbgFrBQ60/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0187S%2FbtqN5f90upY%2FrJYyJ7PVW6pLUtbgFrBQ60%2Fimg.png&quot; data-filename=&quot;스크린샷, 2020-11-23 17-06-38.png&quot; data-origin-width=&quot;411&quot; data-origin-height=&quot;260&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;combinations를 활용한 정확성 테스트 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;보시면 2중 for문을 사용하진 않았지만 테스트에 소요되는 시간은 더 오래 걸린 것을 확인할 수 있습니다. 왜 이런 현상이 발생하는지는 combinations 함수를 실행할 때 어떤 형식으로 조합을 만들어 내는지를 분석해야겠지만 제 예상으로는 애초에 조합을 생성할 때도 2중 for문을 사용하면서 조합을 만들어 내지않나 싶습니다. 따라서 뭔가 2중 for문을 사용하지 않아서 조금 편안해진 기분은 들지만 걸린 시간을 보니 찜찜한건 남아 있습니다... 저는 오히려 itertools를 사용할 때 이렇게 시간이 더 오래 걸리는 경우가 많아서 해당 라이브러리를 잘 사용하지 않습니다. 실제로 좀 더 난이도 있는 문제에서 사용하다간 시간초과에 걸리는 경우도 종종 있었습니다. 따라서 상황에 맞게 잘 사용하는 방법 밖에 없어보입니다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;6. 마치며&lt;/b&gt;&lt;/p&gt;
&lt;p&gt; 이번 문제는 크게 어려운 문제는 아니었습니다. 프로그래밍을 처음하시는 분들도 다른 문제들이랑 비교했을 때 비교적 쉽다고 생각하셨을 문제입니다. 하지만 Python의 내장함수에 대해서 지식이 없으셨다면 코드가 길어지거나 헷갈리셨을 수도 있었을거 같습니다. Python을 주언어로 사용하실 목적이라면 Python의 내장함수와 주요 라이브러리를 잘 숙지해두시는 것이 중요하겠습니다.&lt;/p&gt;</description>
      <category>CS/Algorithm</category>
      <author>일하는 개미</author>
      <guid isPermaLink="true">https://gee05053.tistory.com/7</guid>
      <comments>https://gee05053.tistory.com/7#entry7comment</comments>
      <pubDate>Mon, 23 Nov 2020 17:13:43 +0900</pubDate>
    </item>
    <item>
      <title>knex.js 란?</title>
      <link>https://gee05053.tistory.com/6</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1. knex.js란?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;knex.js는 Node.js SQL builder 및 query 기능을 제공하는 라이브러리다. PostgreSQL, MSSQL, MySQL, MariaDB, SQLite3, Oracle, Amazon Redshift 등을 지원해준다. knex.js의 공식 사이트는 &lt;b&gt;&lt;a href=&quot;http://knexjs.org/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;knexjs.org/ &lt;/a&gt;&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2. 장점&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;직접 사용했을 때 장점은 기존 SQL문을 사용할 줄 안다면 거의 비슷하게 사용할 수 있다. 우리가 흔히 SQL문에서 아는 select, where, from, join 등등 다양한 query들이 포함되어 있다. 또한 지원해주는 기능도 많아서 나름 편리하다. transaction, async/await, migration 등등 을 지원해주며 사용하기 편하다. 또한 JavaScript와 SQL 코딩을 같이하는 느낌? 뭔가 데이터 베이스를 만지는거 같으면서도 일반적인 코딩하는 기분이 든다. 즉, 기존 프로그래머들이 적응하는데 오래걸리지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3. 단점&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공식 홈페이지에서 함수에 대한 설명이 조금 빈약하다. 어떤 코드를 실행했을 때 어떤 형식으로 리턴이 되는지, 어떻게 사용되는지를 조금 더 자세하게 작성해주면 좋겠다는 생각을 많이 받았다. 예를 들면 knex(&quot;table_name&quot;).select(*) 코드를 작성했을 때 &quot;table_name&quot;이라는 테이블에서 모든 field를 받아오는 정도는 SQL를 다뤄본 사람이라면 모두 알고 있다. 하지만 이때 return되는 값이 어떤 형태로 오는지를 설명되어있지 않았다. 실제로 나 같은경우에는 return되는 형식을 몰라서 조금 시간을 잡은 적도 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;*knex(&quot;table_name&quot;).select(*) 의 return은 [{row1_field1: &quot;row1의 field1의 값&quot;}, {row2_field2: &quot;row2의 값&quot;}]이다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;4. 설치 방법&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Node.js의 패키지이다보니 npm install 명령어를 통해서 설치할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1606043672639&quot; class=&quot;php&quot; data-ke-language=&quot;php&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;$ npm install knex --save&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후 configuration을 해야하는데 이것은 &lt;b&gt;&lt;a href=&quot;http://knexjs.org/#Installation&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;knexjs.org/#Installation &lt;/a&gt;&lt;/b&gt;에서 정확하게 확인하길 바란다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;5. 글쓴이는 왜 사용하게 되었나?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2020년 4학년 캡스톤 디자인에서 웹페이지를 개발할 때 PostgreSQL를 사용해서 데이터베이스를 구축했다. 이때 knex를 사용하게 되었는데 1학기에는 BackEnd를 만질 줄 아는 사람이 1명밖에 없었고 새로 배우기에는 시간이 너무 없어서 만질줄 아는 1명말고 나머지 4명은 FrontEnd기능만 맡아서 했다. 때문에, knex를 다뤄볼 일이 없었는데, 2학기에 캡스톤디자인2에서는 refactoring를 BackEnd 중심으로 진행하게 되었다. 다들 처음만질 때는 익숙하지 않다보니 막막했는데 계속 만지다보니 나름 재미도 느낀다. 하지만 BackEnd 설계 성격상 하나의 기능을 추가하거나 기존의 코드에서 바꾸려고하니 머리가 너무 아프다...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;6. 결론&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;knex 카테고리에는 내가 knex를 다루면서 찾기 힘들었던 부분, 헤맸던 부분 등등 을 정리하기 위해서 만든 카테고리다. 그래도 해당 카테고리의 글을 작성하기전에 knex가 어떤 것인지는 설명하는 글이 있어야할거 같은 느낌이 들어서 작성해본다.&lt;/p&gt;</description>
      <category>언어/knex.js</category>
      <category>knex</category>
      <author>일하는 개미</author>
      <guid isPermaLink="true">https://gee05053.tistory.com/6</guid>
      <comments>https://gee05053.tistory.com/6#entry6comment</comments>
      <pubDate>Sun, 22 Nov 2020 20:19:17 +0900</pubDate>
    </item>
    <item>
      <title>프로그래머스 Level 1 완주하지 못한 선수 찾아내기</title>
      <link>https://gee05053.tistory.com/5</link>
      <description>&lt;p&gt;&lt;b&gt;* 해당 문제풀이는 Python을 이용했습니다.&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;1. 문제 파악하기&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;- 마라톤에 참가한 선수들이 있는데 그 수는 1명 이상, 100,000명 이하이다.&lt;/p&gt;
&lt;p&gt;- completion의 길이는 participant의 길이보다 1 작다. &amp;rarr; 완주하지 못한 사람은 1명이다.&lt;/p&gt;
&lt;p&gt;- 참가자 이름은 알파벳 소문자로 이루어져 있으며 동명 이인이 있을 수 있다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;2. 문제 접근하기&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;우선 참가자 이름들이 들어 있는 participant와 완주자 이름들이 들어있는 completion은 리스트로 들어 있다. 가장 쉽게 해결하는 방법은 participant와 completion을 먼저 정렬한 다음 for문을 돌면서 같은 index 에 같은 원소가 아닌 참가자 이름을 찾아내면 된다. 파이썬은 리스트에 대한 다양한 함수들이 있으며 이 함수들을 이용하면 다른 언어보다 쉽고 빠르게 코드를 작성할 수 있다는 장점이 있다. 파이썬을 사용한다면 이 장점을 잘 사용하는 것이 중요하다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;3. 주의할 점&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;- for문을 돌릴 때 participant를 기준으로 돌리면 어떻게 될까&lt;/p&gt;
&lt;p&gt;&amp;rarr; 문제 파악하기의 2번째에서 확인 할 수 있듯이, completion의 길이가 participant의 길이보다 1 작기 때문에, participant를 기준으로 돌리게 된다면 participant의 마지막 원소까지 갔을 때, index에러가 발생할 수 있다. 따라서 for문은 completion을 기준으로 해야한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;- completion의 원소를 다 찾았는데도 발견을 못한 경우는?&lt;/p&gt;
&lt;p&gt;&amp;rarr; for문을 통해서 completion의 원소를 다 확인했는데도 정답을 찾지 못했다는 뜻은 무엇일까? 바로 participant의 마지막 원소가 정답이라는 뜻이다. 따라서 for문을 통과한 뒤에 answer가 빈 문자열인지 확인하는 if문이 필요하다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;4. 정답 코드&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;따라서 정답 코드는 아래와 같다고 할 수 있다.&lt;/p&gt;
&lt;p&gt;participant와 completion을 정렬한 뒤, completion을 기준으로 for문을 돌린다. 이때 participant의 i번째와 completion의 i번째 가 다르다는 것은 i번째 participant가 completion에 없다는 뜻이므로 이 사람이 완주를 하지 못한 사람이다. 정답을 찾은 뒤에는 뒤에 원소를 굳이 볼 필요가 없으므로 break문을 통해서 빠져나온다. 이렇게 찾았다면 다행이지만 completion의 마지막 원소까지 보았을 때 answer를 찾지 못한 경우(paritipant의 마지막 원소가 정답일 때)가 있으므로 if문을 통해서 확인을 해준다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;스크린샷, 2020-11-22 17-24-59.png&quot; data-origin-width=&quot;442&quot; data-origin-height=&quot;264&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/59u6V/btqNWhgDQN9/WFIKocPFNauK127XW2PHak/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/59u6V/btqNWhgDQN9/WFIKocPFNauK127XW2PHak/img.png&quot; data-alt=&quot;정답 코드&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/59u6V/btqNWhgDQN9/WFIKocPFNauK127XW2PHak/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F59u6V%2FbtqNWhgDQN9%2FWFIKocPFNauK127XW2PHak%2Fimg.png&quot; data-filename=&quot;스크린샷, 2020-11-22 17-24-59.png&quot; data-origin-width=&quot;442&quot; data-origin-height=&quot;264&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;정답 코드&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;5. 문제점&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;이 코드는 정답처리가 되긴한다. 정답처리가 되지만 과연 이 코드에 문제가 없다고 할 수 있을까? 이런 단순한 코드에는 여러 문제가 있을 수 있지만 가장 먼저 떠오르는 것은 호율성 문제이다. 이번 문제는 level 1이기 때문에 프로그래머스에서 호율성 테스트 통과 기준을 엄청 쉽게 해놨을 것이다. 만약 실제 코딩테스트에서 이런식으로 간단하게 코드를 작성했을 경우, 시간초과가 나타날 가능성이 높다.&lt;/p&gt;
&lt;p&gt;실제 이번 문제에서 제출 버튼을 눌렀을 때 실행시간을 보면, 만족스럽지 못할 것이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;스크린샷, 2020-11-22 17-30-31.png&quot; data-origin-width=&quot;413&quot; data-origin-height=&quot;163&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zUOcC/btqNZNFnsTQ/bqQNb1KcRg3yS1a5IVCkKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zUOcC/btqNZNFnsTQ/bqQNb1KcRg3yS1a5IVCkKk/img.png&quot; data-alt=&quot;정확성 테스트 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zUOcC/btqNZNFnsTQ/bqQNb1KcRg3yS1a5IVCkKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzUOcC%2FbtqNZNFnsTQ%2FbqQNb1KcRg3yS1a5IVCkKk%2Fimg.png&quot; data-filename=&quot;스크린샷, 2020-11-22 17-30-31.png&quot; data-origin-width=&quot;413&quot; data-origin-height=&quot;163&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;정확성 테스트 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;스크린샷, 2020-11-22 17-30-37.png&quot; data-origin-width=&quot;369&quot; data-origin-height=&quot;152&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cDX9Ac/btqNXGNuEpb/KFZOaxpETujBvwtoKNaFg1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cDX9Ac/btqNXGNuEpb/KFZOaxpETujBvwtoKNaFg1/img.png&quot; data-alt=&quot;효율성 테스트 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cDX9Ac/btqNXGNuEpb/KFZOaxpETujBvwtoKNaFg1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcDX9Ac%2FbtqNXGNuEpb%2FKFZOaxpETujBvwtoKNaFg1%2Fimg.png&quot; data-filename=&quot;스크린샷, 2020-11-22 17-30-37.png&quot; data-origin-width=&quot;369&quot; data-origin-height=&quot;152&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;효율성 테스트 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;코드가 간단해서 나쁠건 없다. 하지만 코드가 간단하면 실행시간이 오래걸리는 경우가 많고 너무 단순하게(1줄 코드)로 작성하면 처음 보는 사람은 '이 코드를 왜 이렇게 작성했을까?' 라는 생각이 들 수 도 있다. 이 trade off관계를 잘 조절하는 것이 중요할거 같다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;그렇다면 이 시간 문제를 어떻게하면 조금 더 줄일 수 있을까?&lt;/p&gt;
&lt;p&gt;그 힌트는 문제 옆에있는 해시에 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;스크린샷, 2020-11-22 17-38-07.png&quot; data-origin-width=&quot;471&quot; data-origin-height=&quot;103&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zorIH/btqNXdY9poL/F1RJplshknp2jQPlmDwNKK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zorIH/btqNXdY9poL/F1RJplshknp2jQPlmDwNKK/img.png&quot; data-alt=&quot;프로그래머스는 문제 옆에 어떤 알고리즘을 사용하면 좋은지 나와있다.&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zorIH/btqNXdY9poL/F1RJplshknp2jQPlmDwNKK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzorIH%2FbtqNXdY9poL%2FF1RJplshknp2jQPlmDwNKK%2Fimg.png&quot; data-filename=&quot;스크린샷, 2020-11-22 17-38-07.png&quot; data-origin-width=&quot;471&quot; data-origin-height=&quot;103&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;프로그래머스는 문제 옆에 어떤 알고리즘을 사용하면 좋은지 나와있다.&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;해시에 대해서 간단하게 설명하자면 키값마다 다른 값이 만들어진다. 파이썬에는 hash 함수가 기본으로 사용할 수 있는데 hash(&quot;a&quot;)와 hash(&quot;b&quot;)는 다른 값이 만들어진다.&lt;/p&gt;
&lt;p&gt;따라서 hash 함수를 이용해서 코드를 작성하면 다음과 같이 적을 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;스크린샷, 2020-11-22 18-00-43.png&quot; data-origin-width=&quot;435&quot; data-origin-height=&quot;284&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/berxgV/btqNWE3Jjno/D3hnpdkkpkv2jFDWbPTtZk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/berxgV/btqNWE3Jjno/D3hnpdkkpkv2jFDWbPTtZk/img.png&quot; data-alt=&quot;hash 함수를 이용한 정답&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/berxgV/btqNWE3Jjno/D3hnpdkkpkv2jFDWbPTtZk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FberxgV%2FbtqNWE3Jjno%2FD3hnpdkkpkv2jFDWbPTtZk%2Fimg.png&quot; data-filename=&quot;스크린샷, 2020-11-22 18-00-43.png&quot; data-origin-width=&quot;435&quot; data-origin-height=&quot;284&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;hash 함수를 이용한 정답&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;해당 코드로 제출 버튼을 누르면 다음과 같은 시간이 걸린다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;스크린샷, 2020-11-22 18-01-27.png&quot; data-origin-width=&quot;398&quot; data-origin-height=&quot;160&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bbl78t/btqNZMmb0Fl/aEL0Yu3w0Ymd7lK7xw3KEK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bbl78t/btqNZMmb0Fl/aEL0Yu3w0Ymd7lK7xw3KEK/img.png&quot; data-alt=&quot;정확성 테스트 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bbl78t/btqNZMmb0Fl/aEL0Yu3w0Ymd7lK7xw3KEK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbbl78t%2FbtqNZMmb0Fl%2FaEL0Yu3w0Ymd7lK7xw3KEK%2Fimg.png&quot; data-filename=&quot;스크린샷, 2020-11-22 18-01-27.png&quot; data-origin-width=&quot;398&quot; data-origin-height=&quot;160&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;정확성 테스트 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-filename=&quot;스크린샷, 2020-11-22 18-01-35.png&quot; data-origin-width=&quot;403&quot; data-origin-height=&quot;156&quot; data-ke-mobilestyle=&quot;widthContent&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/A0NzC/btqNVSVHMEY/RyRymLzHhuTYLTSpk8V8Jk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/A0NzC/btqNVSVHMEY/RyRymLzHhuTYLTSpk8V8Jk/img.png&quot; data-alt=&quot;효율설 테스트 결과&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/A0NzC/btqNVSVHMEY/RyRymLzHhuTYLTSpk8V8Jk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FA0NzC%2FbtqNVSVHMEY%2FRyRymLzHhuTYLTSpk8V8Jk%2Fimg.png&quot; data-filename=&quot;스크린샷, 2020-11-22 18-01-35.png&quot; data-origin-width=&quot;403&quot; data-origin-height=&quot;156&quot; data-ke-mobilestyle=&quot;widthContent&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;효율설 테스트 결과&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;정확성 테스트에선 그렇게 큰 차이가 없지만 효율성 테스트에선 꽤 많은 차이가 나는 것을 확인할 수 있다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;6. 마치며&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;알고리즘 문제를 풀고나면 정답을 맞춘 것도 좋지만 다른 사람은 어떻게 생각을 했고 어떤 식으로 작성했는지 확인하는 것도 도움이 많이 된다. 가끔씩은 나도 모르던 함수를 이용해서 엄청 쉽게 푼 사람들도 있으며 어떤 사람은 문제 해결 시작을 나와 다른 방향으로 진행해서 해결한 사람들도 있다.&lt;/p&gt;</description>
      <category>CS/Algorithm</category>
      <author>일하는 개미</author>
      <guid isPermaLink="true">https://gee05053.tistory.com/5</guid>
      <comments>https://gee05053.tistory.com/5#entry5comment</comments>
      <pubDate>Sun, 22 Nov 2020 18:04:37 +0900</pubDate>
    </item>
    <item>
      <title>JavaScript와 Node.js</title>
      <link>https://gee05053.tistory.com/3</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1. 배경&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;지금 캡스톤(졸업 작품)에서 아무 생각없이 JavaScript, Node.js, React, React Native를 사용하면서 갑자기 이들의 차이가 뭘까라는 생각이 들었다. '만약 면접에서 이런 질문이 들어오면 내가 뭐라고 대답할 수 있을까?' 라는 생각을 해보니 대답할 수 없을거 같더라.. 뭔가 이런 것을 생각한다는 자체가 바보같은 생각이라고 들때도 있지만 모르는게 죄는 아니잖아;; 지금부터라도 알고 써야지&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;그래서 이번 글에서는 이 세가지가 어떤 차이가 있는지에 대해서 정도만 알아보고자 한다. 한번 알아보는 김에 깊고 정확하게 이해하는 것도 중요하긴 하지만, 내가 이 언어쪽으로 직업을 가지거나, 주 언어로 사용을 하려는 생각이 없는데 자세하기 알기에는 안그래도 부족한 뇌 용량에 억지로 넣는 기분이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2. JavaScript&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;쉽게 말하면 JavaScript는 프로그래밍 언어 중 하나이다. 즉 우리가 흔히아는 C, C++, Python, Java와 같은 언어라고 할 수 있다. 조금 더 깊이 들어가면 객체 기반의 스크립트 프로그래밍 언어이다.(스크립트 언어를 설명하기엔 주제가 벗어나니 나중에 따로 글을 쓰게 된다면 링크를 걸어두도록 하겠다.) 따라서 JavaScript는 스크립트 언어이기 때문에 특정한 프로그램 안에서만 동작할 수 있다. 보통 Chrome, FireFox, Safari, Explore 등등에서 사용 가능하다. Chrome에서 F12를 누르면 개발자 도구를 활성화 할 수 있다. F12를 눌렀을 때 여러가지 탭이 있는데 console에서 JavaScript언어를 작성하면 동작하는 것을 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&amp;nbsp;흔히 우리는 JavaScript를 말하면 무엇이 떠오르는가? 나 같은 경우에는 JavaScript를 한번도 사용해보지 않았는데도 그냥 자연스럽게 CSS, 웹, 홈페이지 등등이 떠올랐었다.&lt;span&gt; 왜 프로그래밍 언어인데 웹에 관련된 단어들이 떠올랐을가? JavaScript도 웹이랑 밀접하게 관련되어 있기 때문이다. HTML이 웹 페이지의 기본 구조를 담당하고 CSS가 웹의 디자인을 담당한다면 JavaScript는 웹 페이지가 동작하는 것을 담당한다고 할 수 있다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span&gt;&amp;nbsp;JavaScript의 장점이라고 하면 확장성이 매우 뛰어난 언어이다. JavsScript만 알면 일반적인 웹 사이트 개발은 거의 할 수 있다. React.js, Vue.js, React Native 등등 다양한 라이브러리를 사용할 수 있다. 물론 그 안에서는 일반적인 JavaScript와 조금은 다른 부분들이 있지만 거의 비슷하다고 할 수 있다. 비전공자들이 이쪽 분야로 넘어왔을 때 가장 쉽게 배울 수 있는 것이 웹 관련 Front 쪽이라는 것이라고 보면 얼마나 쉽고 빠르게 배울 수 있는 언어인지 상상이 될 것이다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span&gt;3. Node.js&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span&gt;&amp;nbsp;좋아. 그럼 JavaScript는 프로그래밍 언어 중 하나인 것은 알겠는데 JavaScript를 뜻하는 js를 확장명으로 달고 있는 Node.js는 뭐가 다른걸까?&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span&gt;&amp;nbsp;Node.js를 이해하기 위해선 JavaScript를 먼저 배우긴 해야한다. 왜냐하면 Node.js는 JavaScript 기반으로 만들어졌기 때문이다.&amp;nbsp; Node.js는 Chrome V8 JavaScript 엔진으로 빌드된 JavaScript 런타임이다. JavaScript는 Chrome, FireFox 등등 웹 브라우저에서 동작할 수 있지만 이러한 웹 브라우저가 없으면 사용할 수 없는 단점이 존재했다. 우리는 이러한 웹 브라우저 뿐만 아니라 terminal(윈도우에서는 cmd) 같은 곳에서도 사용하거나 디버깅하고 싶은데 그럴 수 없었다는 뜻이다. 하지만 Node.js는 terminal와 같은 외부 환경에서도 실행이 가능하다. 또한 Node.js를 활용해 서버를 만들 수 있다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span&gt;&amp;nbsp;Node.js에는 여러 패키지들이 있는데 npm(Node.js Package Manager)로 관리가 된다. Python의 pip install로 Python 패키지를 설치하는 것처럼 비슷하다. npm install을 이용해서 Node.js에 관련된 패키지를 설치할 수 있다. Facebook에서 만든 yarn이라는 패키지 및 배포 관리자도 있는데 npm과 성능 측면에서는 큰 차이가 없다는거 같다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span&gt;4. React&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span&gt;React는 React.js, ReactJS라고도 불리며 JavaScript의 라이브러리 중 하나로 웹 및 앱을 개발 할 수 있다. Facebook 및 여러 공동체에 의해 유지보수가 되고 있다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span&gt;&amp;nbsp;React를 사용하면 React를 지원해주는 여러 컴포넌트 관련 라이브러리를 쉽게 사용할 수 있다. 예를 들면 버튼을 구현할 때 디자인을 손보고 싶으면 Css를 통해서 수정해야했다면, Ant Design 등의 라이브러리 등을 사용하여 해당 라이브러리에서 제공하는 Button이나 여러 컴포넌트들을 사용할 수 있다.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span&gt;&amp;nbsp;React는 JavaScript의 라이브러리 중 하나이지만 사용해보면 State와 Props 개념의 등장으로 조금은 다른 부분이 있다는 것을 느낄 것이다. 글쓴이도 처음 React를 만질 때 State, Props 이해하느라 머리가 아팠다는.. 이 글은 React를 설명하는 글은 아니다 보니 필요하신 분들은 따로 찾아보시길 바랍니다. 그래도 이 두가지를 이해하면 쉽게 웹 페이지를 개발할 수 있고, 익숙해지면 대충 이런식으로 하면 되겠구나를 생각할 수 있는 자신을 발견할 것이다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span&gt;&amp;nbsp;React는 document 사이트도 잘 되어 있고 요즘은 많이 사용하고 있어서 처음 접하더라도 쉽게 배우고 따라갈 수 있을 것이다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #333333;&quot;&gt;&lt;span&gt;5. React Native&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&amp;nbsp;React Native도 Facebook이 개발한 오픈 소스 모바일 애플리케이션 프레임워크이다. 안드로이드, iOS, 등의 어플리케이션을 개발하기 위해 사용되며 네이티브 플랫폼 기능과 React를 사용할 수 있게 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&amp;nbsp;React Native도 JavaScript 기반으로 작성하므로 나름(?) 쉽게 배울 수 있을거 같지만 초기에 꽤 많은 오류를 접한다. 특히 React Native 오류가 나면 앱에 빨간 배경에 오류 글씨가 가득차는데 정말 꼴보기 싫다... 뭔가 게임 속에서 스토리 진행하다가 죽었을 때 You DIE 문구가 나타나는 기분이랄까..?&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&amp;nbsp;대학교 2학년 때(2018년) 첫 팀프로젝트에서 모바일 어플리케이션을 개발할 때 처음으로 React Native를 사용해보았는데 생각보다 답답한 점이 많았다. 우선 에러가 나더라도 어느 이유에서 에러가 나왔는지 쉽게 이해할 수 없었다.. 물론 나중에 React Native에 대해서 익숙해지고 나면 '아..? 여기에서 실수했겠구나' 정도로 이해할 수 있지만 처음 개발하는 사람들에게 에러 문구를 보여주면 '음..? 이게 뭔말이여?' 라는 생각이 들게 만든다. 또한 document 사이트가 지금은 개선이 되어있는지 모르겠지만 당시에는 '이게 다야..?' 라는 말이 나왔다. stackoverflow 등에 검색해봐도 해결이 잘 안되는 경우도 많았고, 책을 사서 공부하려고해도 React Native에 관련된 책이 거의 없었다. 학교 도서관에 1권 있었는데 별 도움이 되진않았던 걸로 기억된다. 요즘은 사용하는 기업이나 시도하는 사람들이 많아서 조금은 관련 정보들이 많을 것으로 예상이 된다. 이전에 React를 만져보았다면 React Native를 다루는데 많은 도움이 될 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;6. 결론&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;오늘은 JavaScript와 관련된 라이브러리, 플랫폼을 알아보았다. 배경에서도 말했지만 JavaScript를 주 언어로 사용할 것이 아니라면 이러한 차이들을 굳이 알아야할까? 라는 생각이 들긴한다. 하지만 안다고해서 나쁠거야 없다. 예상하지 못한 상황에서 갑자기 사용하게 될 수도 있고, 누군가가 너 이런거 알아? 라고 했을 때 아는 척이라도 할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;많이 부족한 내용이지만 읽어주신 분들 감사합니다.&lt;/p&gt;</description>
      <category>언어/JavaScript</category>
      <author>일하는 개미</author>
      <guid isPermaLink="true">https://gee05053.tistory.com/3</guid>
      <comments>https://gee05053.tistory.com/3#entry3comment</comments>
      <pubDate>Sat, 21 Nov 2020 21:07:34 +0900</pubDate>
    </item>
    <item>
      <title>왜 블로그를 시작하게 되었는가</title>
      <link>https://gee05053.tistory.com/2</link>
      <description>&lt;p&gt;&lt;b&gt;1. 블로그란?&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;블로그 하면 다양한 이야기가 떠오른다.&lt;/p&gt;
&lt;p&gt;자신의 일상을 공유하는 블로그, 맛집을 찾아 다니며 공유하는 블로그, 어떤 제품 리뷰 블로그, 사진 공유 등등 대부분 공유에 중심이 되어 있다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;실제로도 블로그의 뜻은 '자신의 관심사에 따라 자유롭게 글을 올릴 수 있는 웹 사이트'라고 두산백과에서 명명했다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;2. 나의 첫 블로그&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;아주 어릴 때 만화책을 보는 것을 좋아했고 게임을 하는 것을 좋아해서 게임 및 만화책을 리뷰하는 블로그를 잠깐 했던 적이 있다. 초등학생 때여서 아무 생각없이 했고 아무 생각없이 글을 적고 거기에 오는 사람들과 대화하는게 전부였다.&lt;/p&gt;
&lt;p&gt;체계적으로 운영하던 블로그가 아니었기 때문에 점점 안쓰기 시작했고 그렇게 대학생이 되었다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;3. 다시 왜?&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;언제인지 정확하게 기억은 안나지만 1학년인가 2학년 때, 교수님이 자신이 새로 안 것을 블로그나 다른 곳에 잘 정리해놔서 나중에 사용하게 미리 만들어 두라고 조언을 해주셨다. 그당시에는 저학년이라 그런지 '컴공만 나오면 어쨌든 취직 걱정을 안하고 어떻게든 살 수 있는데 뭐하러 그렇게 까지 하냐' 하면서 대충 넘겼다. 그당시에는 딱히 대기업에 가고 싶다거나 성공하고 싶다는 욕심이 없었다. 그저 현실을 더 중요하게 생각하고 지금 일부터 잘하자라는 마인드였다. 그렇게 점점 지내다보니 점점 이전에 배운 것들을 까먹기 시작했다. 또 거기에 대해서 다시 공부하고 방학때 까먹어 버리고... 무한 반복..ㅎ&lt;/p&gt;
&lt;p&gt;내 친구들 별명은 기만자들인데 그 이유는 맨날 시험때 &quot;아 이번 시험공부는 진짜 안했다.&quot;, &quot;잘봤냐? 나 하나도 못풀었다.&quot; 이런 말로 밑밥을 뿌린다음 A+를 고스란히 챙겨갔다.ㅋㅋㅋㅋ 그렇게 서로 기만하다가 친해져서 모여있는 톡방 이름이 기만자들이다.&lt;/p&gt;
&lt;p&gt;그 기만자들 톡방에서 가장 깐깐한 형이 한명 있는데 이런저런 이야기를 하면서 교수님이 말씀하셨던거 처럼 블로그를 만들으라 했다. &quot;아 귀찮아&quot; 하면서 거부하던 나에게 팩트로 후두려 팼다..ㅎ 생각을 해보니 한 학기에 배운거 열심히 공부한 다음, 방학 때 그대로 포멧시키고 다시 다음학기 지식 넣고 다시 포멧시키고 이런 상황이 반복이 되었다. 컴퓨터도 포멧을 시키기 전에 다른 usb나 드라이브에 복사를 해놓고 포멧을 시키는데 내 기억을 딱히 복사시키지 않았다. 그래도 나름 머리가 잘 굴러가는 20대 초반의 지식을 시간을 들여가면서 쌓은건데 그대로 날리자니 아깝다는 생각이 들었다. '흠.. 시간이 되면 한번 써보긴 해야겠군..' 이라고 생각은 했지만 바쁜 일상과 이런저런 일 때문에 미루다보니 어느덧 졸업을 2달이 남았다.. 더 늦기전에 시간이 조금 생긴 이번주에 블로그를 생성하고 조금씩 글을 쓰려고 한다. 또한 조금 찾아보니 몇몇 기업에서는 이러한 블로그나 자신의 지식을 공유한 경험이 있으면 가산점도 있다고 들었다. 재대하고 나서 나중에 도움이 조금이라도 되지않을까 해서 작성해본다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;4. 어떤 글?&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;우선 내가 많이 사용하는 Python과 JavaScript를 위주로 작성하려고 한다. 중간에 새로운 언어나 백엔드 쪽도 만질 일이 있다면 그때가서 카테고리를 늘릴 예정.&lt;/p&gt;
&lt;p&gt;그리고 Algorithm에서는 프로그래머스에서 조금씩 풀었던 문제들을 어떤 식으로 해석하고 풀었는지 작성한 뒤 나중에 들어왔을 때 20대 초반에는 이런식으로 해석했구나라고 돌아볼 날이 오지않을까 ㅋㅋㅋ&lt;/p&gt;
&lt;p&gt;대학 &amp;amp; 일상 일기에는 그냥 내가 대학 생활이나 일상에서 느끼거나 경험한 것을 일기처럼 끄적여 보려고 한다. 과연 이 블로그가 얼마나 사람들이 들어오는 블로그가 될지 모르겠지만, 조금이라도 도움이 된다면 뭐 그거나름대로 나쁘지 않겠다 라는 생각도 든다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;5. 마치며&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;블로그를 만들고 처음 쓰는 글이다. 글쓰기 버튼을 찾는 것부터도 힘들었고 그냥 생각나는 대로 적다보니 글 맥락도 이상할 수 있다.(애초에 국어를 가장 못하고 별로 안좋아한다..) 나름 꾸준하게 작성해서 나뿐만 아니라 다른 사람에게도 도움이 되는 블로그가 되면 좋겠다.&lt;/p&gt;</description>
      <category>대학 &amp;amp; 일상 일기</category>
      <author>일하는 개미</author>
      <guid isPermaLink="true">https://gee05053.tistory.com/2</guid>
      <comments>https://gee05053.tistory.com/2#entry2comment</comments>
      <pubDate>Fri, 20 Nov 2020 22:21:43 +0900</pubDate>
    </item>
  </channel>
</rss>