<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>뚝딱뚝딱 코딩 기록_</title>
    <link>https://ttugttag-coding.tistory.com/</link>
    <description>  ez1n's Github  
 https://github.com/ez1n</description>
    <language>ko</language>
    <pubDate>Mon, 13 Jul 2026 15:57:50 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>ez1n</managingEditor>
    <image>
      <title>뚝딱뚝딱 코딩 기록_</title>
      <url>https://tistory1.daumcdn.net/tistory/5231499/attach/fc6922c375c64ff18fd399eb512ec780</url>
      <link>https://ttugttag-coding.tistory.com</link>
    </image>
    <item>
      <title>[Record] 2025년 회고</title>
      <link>https://ttugttag-coding.tistory.com/122</link>
      <description>&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;p data-ke-size=&quot;size16&quot;&gt;벌써 2025년이 지났다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 2025년에 어떤 목표를 이루고, 어떤 목표를 이루지 못했을까?&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;나에게 2025년은 &lt;b&gt;운동, 성장, 재테크&lt;/b&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;이루려고 노력했던 목표와 기억 저편으로 넘어갔던 목표들을 돌아보며,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;운동, 성장, 재테크 3가지로 2025년을 돌아보려고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;1. 운동&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2025년은 건강을 위해 운동을 꾸준히 하기로 결심했었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2024년부터 시작한 스쿼시에 재미를 붙여 2025년에도 꾸준시 스쿼시를 다녔던 것 같다.&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;약 1년동안 꾸준히 다녔던 스쿼시와는 다르게 긴장된 근육을 풀어주고 혈액순환을 도와주는 요가에 새로운 매력을 느꼈다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히 플라잉 요가는 일반 요가보다 활동적인 운동이어서 재미도 느낄 수 있었던 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 약 3개월동안 꾸준히 플라잉 요가를 다니면서 &lt;b&gt;2026년의 메인 운동은 플라잉 요가가 될 것 같다.&lt;/b&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;운동을 하다보니 체력이 조금씩 늘어가는 것이 느껴지고&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2026년에는 지금보다 더 여러 동작을 할 수 있게 되었으면 좋겠다.&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;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;h4 data-ke-size=&quot;size20&quot;&gt;2. 성장&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2024년 12월에 &lt;b&gt;백엔드 개발자로 포지션을 변경&lt;/b&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;프론트엔드 개발을 처음 시작했던 때가 생각나긴 했지만,&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;그만큼 배로 노력해야했다.&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;작은 업무부터 조금씩 담당하며 도메인에 대한 이해도와 사용하는 기술을 익히느라 2025년이 순식간에 지나간 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;퇴근 후에도 업무나 기술적 고민에서 벗어나지 못한 날들이 많았던 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;당연하다.. 백엔드 개발에 대해선 지식이 하나도 없고 1년차 개발자였다...&lt;/span&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;24년부터 시작했던 스터디를 꾸준히 하면서 업무 도중 생기는 모르는 부분들에 대해 공부하고,&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;그 결과 도메인에 대한 흥미와 이해도가 높아졌고 담당하는 업무의 범위가 조금씩 넓어지는 것을 느꼈다.&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;학생 인턴을 담당하면서 업무적으로 사람을 관리? 하는 일에 대해서도 아주 조금은 배울 수 있었고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히 &lt;b&gt;타 팀(비개발자)과 의사소통하는 방법&lt;/b&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;이슈를 공유하는 과정에서 설명 부족으로 커뮤니케이션에 미스가 생긴 적도 간혹 있었는데,&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2-1. 업무&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;운이 좋았던 건지 포지션을 변경하고 얼마 있지 않아 대규모 신규 개발이 필요한 기능이 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존 서비스의 version 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;생각보다 규모가 컸고 개발 기간은 약 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;기획이 제대로 나오지 않은 모호한 상황에서 검토를 해야해서 사실 조금 어려움이 있었던 것 같다.&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;&lt;b&gt;의사 소통, 새로운 기능 설계 및 구현, api 인터페이스 정의, 문서 작성 등 여러가지 경험&lt;/b&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 1년차 개발자임에도 &lt;b&gt;서버 분리 작업&lt;/b&gt;도 경험할 수 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;검토와 개발, 배포 준비까지 약 2.5달 정도 걸렸던 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서버 분리와 동시에 flask&amp;nbsp; 동기 서버 &amp;rarr; fast api 비동기 서버로 마이그레이션 하는 작업까지 진행해서 그런지&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;이 경험은 정말 많은 것들을 배울 수 있는 기회가 되었던 것 같은데, 2026년에 조금씩 기록해 보려고 한다.&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;p data-ke-size=&quot;size16&quot;&gt;업무적으로 가장 크게 성장했다고 느낀 점은 바로 &lt;b&gt;운영 문의를 처리&lt;/b&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;&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;2026년에는 팀원으로서, 개발자로서 더욱 성장하는 사람이 되어야겠다.&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;h4 data-ke-size=&quot;size20&quot;&gt;3. 재테크&lt;/h4&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;솔직히 조금 미래가 어두웠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 관심을 가지게 된 것이 바로 &lt;b&gt;경제 공부&lt;/b&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;재테크는 조금 무서웠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 뉴스를 읽기 시작하고, 경제 도서를 읽기 시작했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2025년에 벌써 두 권을 읽었다.&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 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;주식, 부동산 등 돈에 대한 직접적인 내용들도 재미있지만&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;점심시간마다 경제 뉴스를 보며 어떤 종목이 잘나가고 어떤 종목이 부진한지에 대해서도 조금씩 느끼게 되고,&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;사실 요즘은 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;&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;재테크 공부와 투자를 시작한지는 반 년 정도밖에 지나지 않았지만,&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;앞으로도 꾸준히 흥미를 잃지 않고 롱런하고싶다.&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;2025년을 마치며, 그리고 2026년을 시작하며.&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2025년은 이것 저것 배우고 습득하는라 바쁜 해였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;중간에 몸이 힘들다고 신호를 보낸적도 종종 있었는데, 2026년에는 몸의 밸런스를 조절하는 방법도 알아야 할 것 같다.&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;2026년도 마찬가지겠지만 작년보다 성장한 내가 되어 올바른 방향을 찾아 조금 더 쉬운 방법으로 성장할 수 있는 해가 될 수 있도록, 느리더라도 앞으로 나아가는 내가 되어야겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>RECORD</category>
      <author>ez1n</author>
      <guid isPermaLink="true">https://ttugttag-coding.tistory.com/122</guid>
      <comments>https://ttugttag-coding.tistory.com/122#entry122comment</comments>
      <pubDate>Tue, 6 Jan 2026 20:13:09 +0900</pubDate>
    </item>
    <item>
      <title>[SQLAlchemy] SQLAlchemy 관계 로딩 / eager loading, lazy loading, joinedload, selectinload, contains_eager</title>
      <link>https://ttugttag-coding.tistory.com/121</link>
      <description>&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size18&quot;&gt;[SQLAlchemy 관계 로딩]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;SQLAlchemy의 관계 로딩에 대해 공부해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최근 sqlalchemy 버전을 올림과 동시에 flast to fastapi 마이그레이션 작업을 하고 있는데 모르는 개념들이 많이 생기고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히 relationship(관계)에 대한 부분을 많이 공부해야할 것 같다는 생각이 들었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 오늘은 sqlalchemy의 relationship loading에 대해 정리해 보려고 한다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;p style=&quot;text-align: center;&quot; data-end=&quot;198&quot; data-start=&quot;166&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-end=&quot;198&quot; data-start=&quot;166&quot; data-ke-size=&quot;size18&quot;&gt;&amp;lt;STUDY&amp;gt;&lt;/p&gt;
&lt;p data-end=&quot;165&quot; data-start=&quot;134&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-end=&quot;495&quot; data-start=&quot;463&quot; data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;❓ 관계 로딩 전략 (&lt;span style=&quot;text-align: left;&quot;&gt;relationship loading strategy)&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;blockquote data-end=&quot;592&quot; data-start=&quot;497&quot; data-ke-style=&quot;style2&quot;&gt;연관된 객체를 언제, 어떻게 가져올지를 결정하는 방법&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;- 구분설명쿼리 실행 시점
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 77.3238%; height: 63px;&quot; border=&quot;1&quot; data-end=&quot;759&quot; data-start=&quot;594&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody data-end=&quot;759&quot; data-start=&quot;650&quot;&gt;
&lt;tr style=&quot;height: 25px;&quot; data-end=&quot;700&quot; data-start=&quot;650&quot;&gt;
&lt;td style=&quot;width: 17.2093%; height: 25px;&quot; data-col-size=&quot;sm&quot; data-end=&quot;669&quot; data-start=&quot;650&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;b&gt;Lazy Loading&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.1787%; height: 25px;&quot; data-end=&quot;691&quot; data-start=&quot;669&quot; data-col-size=&quot;sm&quot;&gt;관계 필드를 접근할 때 쿼리를 실행&lt;/td&gt;
&lt;td style=&quot;width: 29.1429%; height: 25px;&quot; data-end=&quot;700&quot; data-start=&quot;691&quot; data-col-size=&quot;sm&quot;&gt;접근 시점&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 28px;&quot; data-end=&quot;759&quot; data-start=&quot;701&quot;&gt;
&lt;td style=&quot;width: 17.2093%; height: 28px;&quot; data-col-size=&quot;sm&quot; data-end=&quot;721&quot; data-start=&quot;701&quot;&gt;&lt;span style=&quot;background-color: #ffffff;&quot;&gt;&lt;b&gt;Eager Loading&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.1787%; height: 28px;&quot; data-end=&quot;738&quot; data-start=&quot;721&quot; data-col-size=&quot;sm&quot;&gt;관계를 미리 한 번에 로드&lt;/td&gt;
&lt;td style=&quot;width: 29.1429%; height: 28px;&quot; data-end=&quot;759&quot; data-start=&quot;738&quot; data-col-size=&quot;sm&quot;&gt;즉시 (Parent 쿼리 시점)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;793&quot; data-start=&quot;766&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;793&quot; data-start=&quot;766&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;1️⃣ Lazy Loading (기본값)&lt;/b&gt;&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1761645677358&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class Parent(Base):
    __tablename__ = &quot;parent&quot;
    id = Column(Integer, primary_key=True)
    children = relationship(&quot;Child&quot;, lazy=&quot;select&quot;)
    

## 사용
parents = session.query(Parent).all()

for p in parents:
    print(p.children)  # 여기서 매번 쿼리 실행됨 (N+1 문제)&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1134&quot; data-start=&quot;1074&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1101&quot; data-start=&quot;1074&quot;&gt;관계에 접근할 때마다 쿼리 추가로 실행&lt;/li&gt;
&lt;li data-end=&quot;1134&quot; data-start=&quot;1102&quot;&gt;데이터가 많을 경우 성능 저하 (N+1 Problem)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1160&quot; data-start=&quot;1141&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1160&quot; data-start=&quot;1141&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1160&quot; data-start=&quot;1141&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;2️⃣ joinedload&lt;/b&gt;&lt;/p&gt;
&lt;blockquote data-end=&quot;1193&quot; data-start=&quot;1162&quot; data-ke-style=&quot;style2&quot;&gt;JOIN을 사용하여 한 번에 데이터를 가져오는 방식&lt;/blockquote&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1761645788626&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sqlalchemy.orm import joinedload

stmt = select(Parent).options(joinedload(Parent.children))
parents = session.execute(stmt).scalars().all()&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1464&quot; data-start=&quot;1356&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1402&quot; data-start=&quot;1356&quot;&gt;SQL: SELECT ... FROM parent JOIN child ...&lt;/li&gt;
&lt;li data-end=&quot;1427&quot; data-start=&quot;1403&quot;&gt;장점: 쿼리 한 번으로 모든 데이터 로드&lt;/li&gt;
&lt;li data-end=&quot;1464&quot; data-start=&quot;1428&quot;&gt;단점: JOIN이 많아지면 결과가 중복되고 비효율적일 수 있음&lt;/li&gt;
&lt;/ul&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;p data-end=&quot;1491&quot; data-start=&quot;1471&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;3️⃣ selectinload&lt;/b&gt;&lt;/p&gt;
&lt;blockquote data-end=&quot;1530&quot; data-start=&quot;1493&quot; data-ke-style=&quot;style2&quot;&gt;JOIN 대신 IN 쿼리를 사용하여 한 번에 데이터를 가졍호는 방식&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1761645919910&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sqlalchemy.orm import selectinload

stmt = select(Parent).options(selectinload(Parent.children))
parents = session.execute(stmt).scalars().all()&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1822&quot; data-start=&quot;1697&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1776&quot; data-start=&quot;1697&quot;&gt;SQL
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;1776&quot; data-start=&quot;1706&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;1729&quot; data-start=&quot;1706&quot;&gt;첫 번째 쿼리: 부모 리스트 조회&lt;/li&gt;
&lt;li data-end=&quot;1776&quot; data-start=&quot;1732&quot;&gt;두 번째 쿼리: WHERE child.parent_id IN (...)&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li data-end=&quot;1802&quot; data-start=&quot;1777&quot;&gt;장점: JOIN보다 깔끔하고 중복 감소&lt;/li&gt;
&lt;li data-end=&quot;1822&quot; data-start=&quot;1803&quot;&gt;단점: 쿼리가 최소 2회 실행&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1852&quot; data-start=&quot;1829&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1852&quot; data-start=&quot;1829&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1852&quot; data-start=&quot;1829&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;4️⃣ contains_eager&lt;/b&gt;&lt;/p&gt;
&lt;blockquote data-end=&quot;1910&quot; data-start=&quot;1854&quot; data-ke-style=&quot;style2&quot;&gt;직접 작성한 JOIN 결과를 ORM 관계로 매핑할 때 사용&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1761645931957&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sqlalchemy.orm import contains_eager

stmt = (
    select(Parent)
    .join(Parent.children)
    .options(contains_eager(Parent.children))
)
parents = session.execute(stmt).scalars().unique().all()&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;p data-end=&quot;2138&quot; data-start=&quot;2130&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;  특징&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2253&quot; data-start=&quot;2139&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2178&quot; data-start=&quot;2139&quot;&gt;ORM에게 &amp;ldquo;이 JOIN 결과는 이미 관계 데이터야&amp;rdquo;라고 알려줌&lt;/li&gt;
&lt;li data-end=&quot;2215&quot; data-start=&quot;2179&quot;&gt;JOIN 구문을 직접 제어할 수 있어, 복잡한 쿼리에 유용&lt;/li&gt;
&lt;li data-end=&quot;2253&quot; data-start=&quot;2216&quot;&gt;필터링된 관계 로딩, alias / 서브쿼리 조합에서 특히 중요&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;2274&quot; data-start=&quot;2260&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;2274&quot; data-start=&quot;2260&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-end=&quot;2274&quot; data-start=&quot;2260&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;✅ 비교&lt;/b&gt;&lt;/h4&gt;
&lt;div&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;2617&quot; data-start=&quot;2276&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody data-end=&quot;2617&quot; data-start=&quot;2369&quot;&gt;
&lt;tr data-end=&quot;2420&quot; data-start=&quot;2369&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2380&quot; data-start=&quot;2369&quot;&gt;&lt;b&gt;lazy&lt;/b&gt;&lt;/td&gt;
&lt;td data-end=&quot;2394&quot; data-start=&quot;2380&quot; data-col-size=&quot;sm&quot;&gt;접근 시 SELECT&lt;/td&gt;
&lt;td data-end=&quot;2402&quot; data-start=&quot;2394&quot; data-col-size=&quot;sm&quot;&gt;접근 시점&lt;/td&gt;
&lt;td data-end=&quot;2411&quot; data-start=&quot;2402&quot; data-col-size=&quot;sm&quot;&gt;단순, 느림&lt;/td&gt;
&lt;td data-end=&quot;2420&quot; data-start=&quot;2411&quot; data-col-size=&quot;sm&quot;&gt;기본 관계&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;2480&quot; data-start=&quot;2421&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2438&quot; data-start=&quot;2421&quot;&gt;&lt;b&gt;joinedload&lt;/b&gt;&lt;/td&gt;
&lt;td data-end=&quot;2450&quot; data-start=&quot;2438&quot; data-col-size=&quot;sm&quot;&gt;JOIN으로 로딩&lt;/td&gt;
&lt;td data-end=&quot;2455&quot; data-start=&quot;2450&quot; data-col-size=&quot;sm&quot;&gt;즉시&lt;/td&gt;
&lt;td data-end=&quot;2470&quot; data-start=&quot;2455&quot; data-col-size=&quot;sm&quot;&gt;쿼리 1회, 중복 가능&lt;/td&gt;
&lt;td data-end=&quot;2480&quot; data-start=&quot;2470&quot; data-col-size=&quot;sm&quot;&gt;간단한 관계&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;2542&quot; data-start=&quot;2481&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2500&quot; data-start=&quot;2481&quot;&gt;&lt;b&gt;selectinload&lt;/b&gt;&lt;/td&gt;
&lt;td data-end=&quot;2511&quot; data-start=&quot;2500&quot; data-col-size=&quot;sm&quot;&gt;IN 쿼리 2회&lt;/td&gt;
&lt;td data-end=&quot;2516&quot; data-start=&quot;2511&quot; data-col-size=&quot;sm&quot;&gt;즉시&lt;/td&gt;
&lt;td data-end=&quot;2529&quot; data-start=&quot;2516&quot; data-col-size=&quot;sm&quot;&gt;효율적, 중복 적음&lt;/td&gt;
&lt;td data-end=&quot;2542&quot; data-start=&quot;2529&quot; data-col-size=&quot;sm&quot;&gt;다대일 / 일대다&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;2617&quot; data-start=&quot;2543&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;2564&quot; data-start=&quot;2543&quot;&gt;&lt;b&gt;contains_eager&lt;/b&gt;&lt;/td&gt;
&lt;td data-end=&quot;2577&quot; data-start=&quot;2564&quot; data-col-size=&quot;sm&quot;&gt;수동 JOIN 매핑&lt;/td&gt;
&lt;td data-end=&quot;2582&quot; data-start=&quot;2577&quot; data-col-size=&quot;sm&quot;&gt;즉시&lt;/td&gt;
&lt;td data-end=&quot;2596&quot; data-start=&quot;2582&quot; data-col-size=&quot;sm&quot;&gt;커스텀 JOIN 가능&lt;/td&gt;
&lt;td data-end=&quot;2617&quot; data-start=&quot;2596&quot; data-col-size=&quot;sm&quot;&gt;필터링된 관계, alias 사용&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;h4 data-end=&quot;2659&quot; data-start=&quot;2624&quot; data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&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;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;b&gt;  contains_eager + alias&amp;nbsp;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;JOIN 대상이 단순한 테이블이 아니라 별칭(alias) 혹은 서브쿼리인 경우 SQLAlchemy가 관계를 자동으로 인식하지 못하기 때문에 alias 인자를 명시적으로 넘겨줌&lt;/blockquote&gt;
&lt;p data-end=&quot;2834&quot; data-start=&quot;2661&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;2834&quot; data-start=&quot;2661&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-end=&quot;2869&quot; data-start=&quot;2841&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;  필터링된 관계 eager load&lt;/b&gt;&lt;/h4&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1761646340776&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;from sqlalchemy.orm import aliased, contains_eager

ChildAlias = aliased(Child)

stmt = (
    select(Parent)
    .join(ChildAlias, Parent.id == ChildAlias.parent_id)
    .where(ChildAlias.age &amp;gt; 10)
    .options(contains_eager(Parent.children, alias=ChildAlias))
)

parents = session.execute(stmt).scalars().unique().all()&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;3351&quot; data-start=&quot;3208&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;3253&quot; data-start=&quot;3208&quot;&gt;ChildAlias는 Child의 별칭 &amp;rarr; ORM 자동 인식 불가&lt;/li&gt;
&lt;li data-end=&quot;3308&quot; data-start=&quot;3254&quot;&gt;contains_eager(..., alias=ChildAlias)로 관계 직접 지정&lt;/li&gt;
&lt;li data-end=&quot;3351&quot; data-start=&quot;3309&quot;&gt;필터링된 alias 데이터를 Parent.children에 매핑 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;3381&quot; data-start=&quot;3358&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-end=&quot;3381&quot; data-start=&quot;3358&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;b&gt;  &lt;/b&gt;서브쿼리 alias&lt;/b&gt;&lt;/h4&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1761646354177&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;child_subq = (
    select(Child)
    .where(Child.age &amp;gt;= 10)
    .subquery()
)

FilteredChild = aliased(Child, child_subq)

stmt = (
    select(Parent)
    .join(FilteredChild, Parent.id == FilteredChild.parent_id)
    .options(contains_eager(Parent.children, alias=FilteredChild))
)

parents = session.execute(stmt).scalars().unique().all()&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;3840&quot; data-start=&quot;3740&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;3788&quot; data-start=&quot;3740&quot;&gt;서브쿼리 기반 alias를 JOIN하면 ORM이 이를 기본 관계로 인식하지 않음&lt;/li&gt;
&lt;li data-end=&quot;3840&quot; data-start=&quot;3789&quot;&gt;alias 옵션을 지정해야 관계 필드(Parent.children)로 자동 매핑 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;3884&quot; data-start=&quot;3847&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-end=&quot;3884&quot; data-start=&quot;3847&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;b&gt;&lt;b&gt;&lt;b&gt;&lt;b&gt; &lt;/b&gt;&lt;/b&gt;&amp;nbsp;&lt;/b&gt;&lt;/b&gt;여러 alias 관계를 동시에 eager load&lt;/b&gt;&lt;/h4&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1761646371293&quot; class=&quot;python&quot; data-ke-language=&quot;python&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;AddressAlias = aliased(Address)
OrderAlias = aliased(Order)

stmt = (
    select(User)
    .join(AddressAlias, User.id == AddressAlias.user_id)
    .join(OrderAlias, User.id == OrderAlias.user_id)
    .options(
        contains_eager(User.addresses, alias=AddressAlias),
        contains_eager(User.orders, alias=OrderAlias),
    )
)&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-end=&quot;4269&quot; data-start=&quot;4235&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-end=&quot;4269&quot; data-start=&quot;4235&quot; data-ke-style=&quot;style3&quot;&gt;  각 관계마다 별도의 alias를 지정하여 매핑 가능하다.&lt;/blockquote&gt;
&lt;p data-end=&quot;4284&quot; data-start=&quot;4276&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;4284&quot; data-start=&quot;4276&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;4284&quot; data-start=&quot;4276&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;✅ 정리&lt;/b&gt;&lt;/p&gt;
&lt;div&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-end=&quot;4719&quot; data-start=&quot;4286&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody data-end=&quot;4719&quot; data-start=&quot;4324&quot;&gt;
&lt;tr data-end=&quot;4412&quot; data-start=&quot;4324&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;4343&quot; data-start=&quot;4324&quot;&gt;&lt;b&gt;기본 관계 eager load&lt;/b&gt;&lt;/td&gt;
&lt;td data-end=&quot;4412&quot; data-start=&quot;4343&quot; data-col-size=&quot;md&quot;&gt;.join(Parent.children).options(contains_eager(Parent.children))&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;4520&quot; data-start=&quot;4413&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;4434&quot; data-start=&quot;4413&quot;&gt;&lt;b&gt;필터링된 관계 eager load&lt;/b&gt;&lt;/td&gt;
&lt;td data-end=&quot;4520&quot; data-start=&quot;4434&quot; data-col-size=&quot;md&quot;&gt;.join(ChildAlias)... .options(contains_eager(Parent.children, alias=ChildAlias))&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;4640&quot; data-start=&quot;4521&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;4548&quot; data-start=&quot;4521&quot;&gt;&lt;b&gt;서브쿼리 기반 alias eager load&lt;/b&gt;&lt;/td&gt;
&lt;td data-end=&quot;4640&quot; data-start=&quot;4548&quot; data-col-size=&quot;md&quot;&gt;.join(FilteredChild)... .options(contains_eager(Parent.children, alias=FilteredChild))&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;4719&quot; data-start=&quot;4641&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;4665&quot; data-start=&quot;4641&quot;&gt;&lt;b&gt;여러 관계를 동시에 eager load&lt;/b&gt;&lt;/td&gt;
&lt;td data-end=&quot;4719&quot; data-start=&quot;4665&quot; data-col-size=&quot;md&quot;&gt;.options(contains_eager(..., alias=...)) 여러 개 지정&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;5134&quot; data-start=&quot;5122&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;5134&quot; data-start=&quot;5122&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-end=&quot;5134&quot; data-start=&quot;5122&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;b&gt;✅&lt;/b&gt;&amp;nbsp;마무리 요약&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 105px;&quot; border=&quot;1&quot; data-end=&quot;5392&quot; data-start=&quot;5136&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody data-end=&quot;5392&quot; data-start=&quot;5178&quot;&gt;
&lt;tr style=&quot;height: 19px;&quot; data-end=&quot;5208&quot; data-start=&quot;5178&quot;&gt;
&lt;td style=&quot;height: 19px;&quot; data-col-size=&quot;sm&quot; data-end=&quot;5189&quot; data-start=&quot;5178&quot;&gt;&lt;b&gt;lazy&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot; data-end=&quot;5208&quot; data-start=&quot;5189&quot; data-col-size=&quot;sm&quot;&gt;관계 접근 시점에 쿼리 실행&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot; data-end=&quot;5242&quot; data-start=&quot;5209&quot;&gt;
&lt;td style=&quot;height: 19px;&quot; data-col-size=&quot;sm&quot; data-end=&quot;5226&quot; data-start=&quot;5209&quot;&gt;&lt;b&gt;joinedload&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot; data-end=&quot;5242&quot; data-start=&quot;5226&quot; data-col-size=&quot;sm&quot;&gt;JOIN으로 즉시 로딩&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot; data-end=&quot;5278&quot; data-start=&quot;5243&quot;&gt;
&lt;td style=&quot;height: 19px;&quot; data-col-size=&quot;sm&quot; data-end=&quot;5262&quot; data-start=&quot;5243&quot;&gt;&lt;b&gt;selectinload&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot; data-end=&quot;5278&quot; data-start=&quot;5262&quot; data-col-size=&quot;sm&quot;&gt;IN 쿼리로 즉시 로딩&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot; data-end=&quot;5326&quot; data-start=&quot;5279&quot;&gt;
&lt;td style=&quot;height: 19px;&quot; data-col-size=&quot;sm&quot; data-end=&quot;5300&quot; data-start=&quot;5279&quot;&gt;&lt;b&gt;contains_eager&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot; data-end=&quot;5326&quot; data-start=&quot;5300&quot; data-col-size=&quot;sm&quot;&gt;직접 JOIN 결과를 ORM 관계로 매핑&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot; data-end=&quot;5392&quot; data-start=&quot;5327&quot;&gt;
&lt;td style=&quot;height: 19px;&quot; data-col-size=&quot;sm&quot; data-end=&quot;5356&quot; data-start=&quot;5327&quot;&gt;&lt;b&gt;alias + contains_eager&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot; data-end=&quot;5392&quot; data-start=&quot;5356&quot; data-col-size=&quot;sm&quot;&gt;필터링된 / 서브쿼리 기반 관계를 깔끔하게 매핑할 때 필수&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;p data-end=&quot;5514&quot; data-start=&quot;5399&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;5514&quot; data-start=&quot;5399&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;5514&quot; data-start=&quot;5399&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;p data-end=&quot;5514&quot; data-start=&quot;5399&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;5514&quot; data-start=&quot;5399&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;5514&quot; data-start=&quot;5399&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;5514&quot; data-start=&quot;5399&quot; data-ke-size=&quot;size16&quot;&gt;  자세한 내용은 공식 문서를 참고해주세요.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot; data-start=&quot;4742&quot; data-end=&quot;5115&quot;&gt;
&lt;li data-start=&quot;4742&quot; data-end=&quot;4882&quot;&gt;&lt;a style=&quot;color: #0070d1;&quot; data-start=&quot;4744&quot; data-end=&quot;4880&quot;&gt;contains_eager() &amp;mdash; SQLAlchemy 2.0 Docs&lt;/a&gt;&lt;/li&gt;
&lt;li data-start=&quot;4883&quot; data-end=&quot;5010&quot;&gt;&lt;a style=&quot;color: #0070d1;&quot; data-start=&quot;4885&quot; data-end=&quot;5008&quot;&gt;Aliased ORM entities&lt;/a&gt;&lt;/li&gt;
&lt;li data-start=&quot;5011&quot; data-end=&quot;5115&quot;&gt;&lt;a style=&quot;color: #0070d1;&quot; data-start=&quot;5013&quot; data-end=&quot;5115&quot;&gt;Relationship Loading Techniques&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&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;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a style=&quot;color: #006dd7; text-align: center;&quot; href=&quot;https://github.com/ez1n&quot;&gt; ez1n github 구경하기 &amp;nbsp;&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1761647233401&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;profile&quot; data-og-title=&quot;ez1n - Overview&quot; data-og-description=&quot;Front-End Developer. ez1n has 18 repositories available. Follow their code on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/ez1n&quot; data-og-url=&quot;https://github.com/ez1n&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/ce2cHB/hyZMM7wq4J/IZFJkBELFKPE9jczZg29Rk/img.jpg?width=460&amp;amp;height=460&amp;amp;face=223_257_250_286,https://scrap.kakaocdn.net/dn/cElahy/hyZMlwWcmV/2cydS8fj4OJPkJ2EJ7qPZk/img.jpg?width=460&amp;amp;height=460&amp;amp;face=223_257_250_286&quot;&gt;&lt;a href=&quot;https://github.com/ez1n&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/ez1n&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/ce2cHB/hyZMM7wq4J/IZFJkBELFKPE9jczZg29Rk/img.jpg?width=460&amp;amp;height=460&amp;amp;face=223_257_250_286,https://scrap.kakaocdn.net/dn/cElahy/hyZMlwWcmV/2cydS8fj4OJPkJ2EJ7qPZk/img.jpg?width=460&amp;amp;height=460&amp;amp;face=223_257_250_286');&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;ez1n - Overview&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Front-End Developer. ez1n has 18 repositories available. Follow their code on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>BACKEND/Framework &amp;amp; Library</category>
      <author>ez1n</author>
      <guid isPermaLink="true">https://ttugttag-coding.tistory.com/121</guid>
      <comments>https://ttugttag-coding.tistory.com/121#entry121comment</comments>
      <pubDate>Tue, 28 Oct 2025 19:28:17 +0900</pubDate>
    </item>
    <item>
      <title>[Record] 2024년 하반기 &amp;amp; 2025년 상반기 회고</title>
      <link>https://ttugttag-coding.tistory.com/120</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2024년 하반기 회고를 연말에 쓰려고 했으나 많은 일들이 일어나 실패했다..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1년이 지난 지금에서야 지난 1년간의 회고를 써보려고한다.&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&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;2024년 하반기&lt;/b&gt;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;- 갑작스러운 권고 사직, 백엔드로의 전향&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2024년 11월에 2023년 11월 이후 다시 없을줄 알았던 권고 사직의 위기가 찾아왔다.&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;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;&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;생각할 시간은 주말포함 단 3일.. 큰 고민이 시작되었다.&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;br /&gt;길게 보았을 때 결국 백엔드 개발을 하고싶은 의향이 있었지만 프론트엔드를 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;고민 끝에 내린 결정은 포지션 변경.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞으로의 미래를 보았을 때 5년, 10년 이후에 백엔드 개발자로 전향하는 것보다&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;서비스의 도메인을 이해하고 데이터를 설계하여 비즈니스 로직을 통해 서비스의 품질을 높이고 성능을 개선하는 일도 해보고 싶었기 때문에 결정에 후회는 없다.&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;p data-ke-size=&quot;size16&quot;&gt;하지만 또다시 동료들과 헤어지게 되었다. 팀을 옮기기 전 같은 소속이었던 팀원들 총 5명이 퇴사하게 되었다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; 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;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2025년 상반기&lt;/b&gt;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;- 백엔드 개발자로의 첫 걸음&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2024년 12월, 백엔드 개발을 위해 공부를 시작했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2주 동안 네트워크 기초 지식과 fast api, python, sqlalchemy 등 내가 개발할 프로젝트에서 사용 중인 기술을 익혀야했다.&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;강의와 공식문서를 오가며, 그리고 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;&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;퇴근 후 집에서 공부를 하며 작업을 마무리하기도 했고, 사수에게 이런 저런 지식들을 전달받으며 최대한 익숙해지려고 노력했다.&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;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;- 신규 개발&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;회사에서 운영중인 서비스의 2.0 버전을&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;개발 기간은 2달이었고 4월 1일에 출시 예정이었기 때문에 서둘러야 하는 상황이었다.&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;그래도 테이블을 설계할 때 고려해야하는 부분, rest api, 프론트와의 협업, 사이드 이펙트에 대한 고민 등 정말 많은 경험을 했고, 많은 것을 배울 수 있는 기회였다.&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;&amp;nbsp;&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;너무 뿌듯했고, 이 시점부터 백엔드 개발에 재미를 붙이기 시작했던 것 같다.&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;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;- 인턴, 그리고 첫 매니징&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;7월 말, 학생 인턴 두 명이 들어왔다.&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;그 중 백엔드 파트 담당을 내가 맡게 되었다.&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;사실 처음에는 정말 막막했다.&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;일단 어느 정도의 지식을 가지고 있는지 체크한 후 간단한 CRUD 기능을 만들어 보면서&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;6주간 함께하면서 백엔드 개발 시작 이후 처음으로 코드리뷰도 했는데 생각보다 많은 시간이 소요되어서 깜짝 놀랐다.&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;특히 사수가 내 코드에 리뷰를 다는 과정이 이렇겠구나.. 하는 생각이 가장 많이 들었다. ㅎㅎ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;s&gt;(사람을 관리하면서 내 일까지 하는 것이 쉬운 일이 아니더라..)&lt;/s&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;이런 저런 일이 많았지만 이번 매니징 경험은 정말 많은 것을 배울 수 있는 경험이었다.&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&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;지금까지는 프론트엔드 개발에만 관심을 가지고 공부하면 된다고 생각했다.&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;24년 하반기부터 25년 상반기까지는 힘든 일도 많았지만 그만큼 성장할 수 있는 시기였다고 생각한다.&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;지금도 성장하기 위해 노력하고 있지만 더 열심히 해야겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2025년 하반기는 더욱 성장해있기를 바라며.&lt;/p&gt;</description>
      <category>RECORD</category>
      <author>ez1n</author>
      <guid isPermaLink="true">https://ttugttag-coding.tistory.com/120</guid>
      <comments>https://ttugttag-coding.tistory.com/120#entry120comment</comments>
      <pubDate>Wed, 17 Sep 2025 21:25:08 +0900</pubDate>
    </item>
    <item>
      <title>[인프라] 컨테이너 인프라 환경을 지원하는 도구</title>
      <link>https://ttugttag-coding.tistory.com/119</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size18&quot;&gt;[Tools]&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&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: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;lt;STUDY&amp;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;&amp;nbsp;&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;&lt;b&gt;컨테이너 인프라 환경&lt;/b&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;컨테이너를 중심으로 구성된 인프라 환경&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;마이크로서비스 아키텍처로 구현하기에 적합&lt;/li&gt;
&lt;li&gt;컨테이너를 서비스 단위로 포장하여 배포, 확장이 용이함&lt;/li&gt;
&lt;li&gt;컨테이너, 컨테이너 관리, 개발 환경 구성 및 배포 자동화, 모니터링&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;❓ 컨테이너&lt;br /&gt;운영체제 커널에서 다른 프로세스에 영향을 받지 않고 독립적으로 실행되는 프로세스 상태&lt;/blockquote&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;&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;size18&quot;&gt;&lt;b&gt;컨테이너 인프라 환경을 지원하는 도구&lt;/b&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;&lt;b&gt;1️⃣ 도커&lt;/b&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;컨테이너 환경에서 독립적으로 애플리케이션을 실행할 수 있도록 컨테이너를 만들고 관리하는 것을 도와주는 컨테이너 도구&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;운영 체제 환경에 관계없이 독립적인 환경에서 일관된 결과 보장&lt;/li&gt;
&lt;li&gt;컨테이너디(Containerd), 크라이오(CRI-O), 파드맨(Podman) 등&lt;/li&gt;
&lt;/ul&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;p data-ke-size=&quot;size16&quot;&gt;2️⃣ &lt;b&gt;쿠버네티스&lt;/b&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;다수의 컨테이너를 관리하는데 사용&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;컨테이너의 자동 배포, 배포된 컨테이너에 대한 동작 보증, 부하에 따른 동적 확장 등의 기능 제공&lt;/li&gt;
&lt;li&gt;컨테이너 인프라에 필요한 기능을 통합하고 관리하는 솔루션&lt;/li&gt;
&lt;li&gt;도커 스웜(Docker Swarm), 메소스(Mesos), 노마드(Nomad) 등&lt;/li&gt;
&lt;/ul&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;p data-ke-size=&quot;size16&quot;&gt;3️⃣ &lt;b&gt;젠킨스&lt;/b&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;지속적 통합, 지속적 배포 지원하는 도구&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;개발한 프로그램의 빌드, 테스트, 패키지화, 배포 단계 자동화하여 개발 단계 표준화 (개발 생산성 향상)&lt;/li&gt;
&lt;li&gt;뱀부(Bamboo), 깃헙 액션(Github Action), 팀시티(Teamcity) 등&lt;/li&gt;
&lt;/ul&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;p data-ke-size=&quot;size16&quot;&gt;4️⃣ &lt;b&gt;프로메테우스 &amp;amp; 그라파나&lt;/b&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;모니터링을 위한 도구&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;프로메테우스로 수집한 데이터를 그라파나에서 시각화&lt;/li&gt;
&lt;li&gt;중앙 모니터링이 필요한 컨테이너 인프라 환경에서 효율적으로 모니터링 가능&lt;/li&gt;
&lt;li&gt;프로메테우스 &amp;amp; 그라파나 컨테이너로 패키징되어 동작&lt;/li&gt;
&lt;li&gt;최소한의 자원으로 쿠버네티스의 클러스터 상태를 시각적으로 표현&lt;/li&gt;
&lt;li&gt;모니터링 데이터 수집 도구: 데이터독(DataDog), 인플럭스DB(InfluxDB), 뉴렐릭(New Relic) 등&lt;/li&gt;
&lt;li&gt;데이터 시각화 도구: 키바나(Kibana), 크로노그래프(Chronograf) 등&lt;/li&gt;
&lt;/ul&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&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;p data-ke-size=&quot;size16&quot;&gt;회사에서 도커와 쿠버네티스를 사용하기는 하는데 제대로 알지 못하고 있는 것 같아 그동안 미뤄뒀던 공부를 시작했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 백엔드 개발을 시작한지 1년이 채 되지 않아 적응하기에도 바쁘다는 핑계로 소홀했던 것 같다.&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;다음 글부터는 도커와 쿠버네티스에 대해 본격적으로 기록해보려고 한다.&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;a href=&quot;https://www.yes24.com/product/goods/102099414&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;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;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a style=&quot;color: #3d62ce; text-align: center;&quot; href=&quot;https://github.com/ez1n&quot;&gt; ez1n github 구경하기 &amp;nbsp;&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1758109148780&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;profile&quot; data-og-title=&quot;ez1n - Overview&quot; data-og-description=&quot;Front-End Developer. ez1n has 19 repositories available. Follow their code on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/ez1n&quot; data-og-url=&quot;https://github.com/ez1n&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cV88Ii/hyZJs2Y1vp/j5kPNZFt9Tbupqzk2tTsn1/img.jpg?width=460&amp;amp;height=460&amp;amp;face=223_257_250_286,https://scrap.kakaocdn.net/dn/77yS9/hyZJoTM461/kWqmOHSZO9PuLcdOKPO1H1/img.jpg?width=460&amp;amp;height=460&amp;amp;face=223_257_250_286&quot;&gt;&lt;a href=&quot;https://github.com/ez1n&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/ez1n&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cV88Ii/hyZJs2Y1vp/j5kPNZFt9Tbupqzk2tTsn1/img.jpg?width=460&amp;amp;height=460&amp;amp;face=223_257_250_286,https://scrap.kakaocdn.net/dn/77yS9/hyZJoTM461/kWqmOHSZO9PuLcdOKPO1H1/img.jpg?width=460&amp;amp;height=460&amp;amp;face=223_257_250_286');&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;ez1n - Overview&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Front-End Developer. ez1n has 19 repositories available. Follow their code on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>BACKEND/Infra</category>
      <author>ez1n</author>
      <guid isPermaLink="true">https://ttugttag-coding.tistory.com/119</guid>
      <comments>https://ttugttag-coding.tistory.com/119#entry119comment</comments>
      <pubDate>Wed, 17 Sep 2025 20:40:16 +0900</pubDate>
    </item>
    <item>
      <title>[Record] 2024년 상반기 회고</title>
      <link>https://ttugttag-coding.tistory.com/118</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2024년의 상반기가 지나가고, 하반기가 시작되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;많은 일이 있었던 2024년의 상반기를 회고를 통해 되돌아보려 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;1. 재취업 준비&lt;/b&gt;&lt;br /&gt;2023년 회고와 2024년 신년 계획을 기록하며 언급한 적 있지만 예기치 않은 퇴사로 인해 다시 취업준비를 해야하는 상황이었다.&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;그런 상황에서 덩그러니 퇴사를 하게 되었고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;누가봐도 애매한 6개월이라는 경력으로 취업 준비를 다시 시작하게 되었다.&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;많은 회사에서 서류가 탈락되면서 이력서를 수정하고 또 수정했고 멘탈을 다잡으며 다시 도전하기를 반복했다.&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 style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그 과정에서 면접은 회사가 나를 평가하는 동시에 나도 회사를 평가할 수 있는 기회라는걸 또다시 깨달았다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; 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;그리고 그동안 시간을 허투루 보낸 것은 아니구나 라고 생각하게 된 계기가 있었는데,&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;첫 회사에 재직하면서, 그리고 재취업 준비를 하면서 보낸 시간들이 헛되지 않았고 제대로된 방향으로 나아가고 있구나.&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;어떻게 보면 2024년은 나의 성장을 깨달을 수 있게 해준 좋은 경험으로 시작할 수 있어서 좋았던 것 같다.&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;&lt;b&gt;2. 여러가지 시도&lt;/b&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;항상 회사를 선택할 때 관심이 가는 분야인지와 그 회사가 하는 일의 성장 가능성이 있는지에 대해 생각한다.&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;여튼 그렇게 선택한 회사에 와보니 역시나 생각했던 이상과는 다른 부분이 많았고, 꽤나 많은 고민을 하게 만들었다.&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;다행이도 같이 일하는 프론트엔드 개발자 동료분이 나와 비슷한 관심사를 가지고 있는 분이어서&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;파트장 자리가 공석이 되면서 기존에 재직중이신 동료분이 그 역할을 혼자 도맡게 된 일이 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;약 2-3달 동안 이 상황이 지속되었고, 혹여나 버거울까 하는 생각에&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;또, 기존 서비스를 좀 더 효율적으로 운영하고, 사용자 경험을 향상시킬 수 있을지에 대해 의논하며&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;이 모든 것들은 결국 팀원들이 같은 생각을 가지고 같은 목표를 위해 노력했기 때문에 할 수 있었던 일이라고 생각한다.&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;size18&quot;&gt;&lt;b&gt;3. 팀 이동과 고민..&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;7월, 회사가 합병되면서 팀을 옮기게 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프론트엔드 팀이 3명에서 8명으로 늘어나게 되었고, 다양한 연차의 개발자분들과 일할 수 있다는 생각에 설레기도 했다.&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;이 부분에 대한 이야기는 2024년 하반기 회고에서 할 수 있지 않을까?&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;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;[문서 작업]&lt;/b&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;생각해보면 당연히 해야할 일인데 그동안 겪은 팀, 회사에서는 이 부분에 대한 중요성을 간과하고 있었던 것 같다.&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;물론 개발자가 개발을 안하고 문서화만 한다는 것이 크게 재미있는 일은 아니지만&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;&lt;b&gt;[코드 리뷰]&lt;/b&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;내가 PR을 올려서 리뷰를 받은 것은 아니지만! ㅋㅋㅋ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다른 분의 PR에 적극적으로 리뷰를 달아주는 팀원분들이 너무 좋았고, 리뷰를 읽어보며 나도 다시 한 번 생각하게 될 수 있어서 더 좋은 경험이 되는 것 같다.&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;추가로, 나도 누군가에게 도움이 되는 리뷰를 남길 수 있는 사람이 되고싶다 :)&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;b&gt;[성장]&lt;/b&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;이건 나 스스로가 노력해야 하는 것이기 때문에 더 깊은 고민을 하게 되는 것 같다.&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;나 스스로 노력하면서 떨쳐내야 하는 부분이라고 생각한다.&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;고민만 하지 말고 시도해보자 :)&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;2024년 하반기에도 화이팅!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;성장하는 개발자가 되기를.&lt;/p&gt;</description>
      <category>RECORD</category>
      <author>ez1n</author>
      <guid isPermaLink="true">https://ttugttag-coding.tistory.com/118</guid>
      <comments>https://ttugttag-coding.tistory.com/118#entry118comment</comments>
      <pubDate>Sun, 4 Aug 2024 17:18:42 +0900</pubDate>
    </item>
    <item>
      <title>[Github] Github 패키지 배포하기 / typescript, npm, Github Packages</title>
      <link>https://ttugttag-coding.tistory.com/117</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size18&quot;&gt;[Github Packages 배포하기]&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&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;서로 다른 repository를 사용하기 때문에 같은 기능의 함수를 복사해서 가져와 사용하는 일이 많아졌고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;수정사항이 생기면 모든 repository에서 변경해야하는 상황도 종종 생겼다.&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;github packages에 대해 알게 되었다.&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;그래서 github packages와 npm의 차이점과&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;typescript, github packages로 패키지, 모듈을 배포하는 과정에 대해 공부해보려고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;lt;STUDY&amp;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;❓ &lt;b&gt;Github Packages&lt;/b&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;소프트웨어 패키지를  private 또는 public으로 호스트하고 프로젝트의 종속성으로 사용할 수 있는 소프트웨어 패키지 호스팅 서비스&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;공식문서에 쓰여있는 내용인데, npm처럼 패키지를 배포하여 사용할 수 있는 서비스이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;public으로 배포하는 경우 해당 organization 뿐만아니라 다른 곳에서도 사용 가능하다고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;b&gt;  npm과의 차이&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;private repository의 경우 npm은 유료 github packages는 무료로 배포할 수 있다.&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;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;사내 프로젝트는 보통 비공개이기 때문에 github packages를 이용하는 것도 괜찮은 방법인 것 같다. ㅎㅎ&lt;/span&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;❓&lt;b&gt;&lt;span style=&quot;color: #333333;&quot;&gt; 디렉토리 구조&lt;/span&gt;&lt;/b&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 alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;606&quot; data-origin-height=&quot;610&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bNHybe/btsGEroUbag/IuRj5WdKTI3BPlHszbciC1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bNHybe/btsGEroUbag/IuRj5WdKTI3BPlHszbciC1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bNHybe/btsGEroUbag/IuRj5WdKTI3BPlHszbciC1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbNHybe%2FbtsGEroUbag%2FIuRj5WdKTI3BPlHszbciC1%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;200&quot; height=&quot;201&quot; data-origin-width=&quot;606&quot; data-origin-height=&quot;610&quot;/&gt;&lt;/span&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;size16&quot;&gt;&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;b&gt;❓ 배포 방법&lt;/b&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;&lt;b&gt;0. github access token 발급&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이후 패키지를 배포하고 설치하여 사용하는 경우 필요하다.&lt;/li&gt;
&lt;li&gt;토큰을 통해 해당 사용자가 organization에 write / read 권한이 있는지를 판단하는 것 같다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;  github Settings &amp;gt; Developer Settings &amp;gt; Personal access tokens &amp;gt; Tokens (classic) &amp;gt; Generate new token (classic)&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2912&quot; data-origin-height=&quot;1638&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dnFfO8/btsGFjDWCRM/DPpaY2TwGX3f2xDLTsKLmk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dnFfO8/btsGFjDWCRM/DPpaY2TwGX3f2xDLTsKLmk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dnFfO8/btsGFjDWCRM/DPpaY2TwGX3f2xDLTsKLmk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdnFfO8%2FbtsGFjDWCRM%2FDPpaY2TwGX3f2xDLTsKLmk%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;709&quot; height=&quot;399&quot; data-origin-width=&quot;2912&quot; data-origin-height=&quot;1638&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;토큰 이름 입력, 만료일 설정 및 write:packages 선택 후 토큰 생성&lt;/li&gt;
&lt;li&gt;토큰의 이름은 원하는대로 설정 가능하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1674&quot; data-origin-height=&quot;1432&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/IfYA6/btsGB9W6lU1/OkpJ9yY6q8ZwDRXZ0lOmn0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/IfYA6/btsGB9W6lU1/OkpJ9yY6q8ZwDRXZ0lOmn0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/IfYA6/btsGB9W6lU1/OkpJ9yY6q8ZwDRXZ0lOmn0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIfYA6%2FbtsGB9W6lU1%2FOkpJ9yY6q8ZwDRXZ0lOmn0%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;577&quot; height=&quot;494&quot; data-origin-width=&quot;1674&quot; data-origin-height=&quot;1432&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;  write:packages를 설정해야 패키지 배포가 가능하다.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. package.json 생성&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- init을 통해 package.json 파일을 생성한다.&lt;/p&gt;
&lt;pre id=&quot;code_1713179443917&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;npm init&lt;/code&gt;&lt;/pre&gt;
&lt;pre id=&quot;code_1713179561143&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# package.json

{
  &quot;name&quot;: &quot;@scope/package_name&quot;,
  &quot;version&quot;: &quot;1.0.0&quot;,
  &quot;private&quot;: false,
  &quot;main&quot;: &quot;index.js&quot;,
  &quot;description&quot;: &quot;&quot;,
  &quot;license&quot;: &quot;ISC&quot;,
  &quot;repository&quot;: {
    &quot;type&quot;: &quot;git&quot;,
    &quot;url&quot;: &quot;repository_url&quot;
  },
  &quot;publishConfig&quot;: {
    &quot;@scope:registry&quot;: &quot;https://npm.pkg.github.com&quot;
  },
}&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;name&lt;/b&gt;: @organization or @userId/패키지명&lt;/li&gt;
&lt;li&gt;&lt;b&gt;private&lt;/b&gt;: 패키지를 공개로 배포할지, 비공개로 배포할지 설정 (단, private organization의 경우 제외)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;publishConfig&lt;/b&gt;: 패키지를 배포할 저장소 (registry에 배포하겠다는 의미)&lt;/li&gt;
&lt;/ul&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;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. typescript 설치&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1713180550772&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;npm install -D typescript&lt;/code&gt;&lt;/pre&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;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. tsconfig.json 생성&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1713180645924&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{
  &quot;compilerOptions&quot;: {
    &quot;paths&quot;: {
      &quot;@scope/package_name&quot;: [
        &quot;./src&quot;
      ]
    },
    &quot;target&quot;: &quot;es5&quot;,
    &quot;outDir&quot;: &quot;dist&quot;,
    &quot;declaration&quot;: true,
    &quot;sourceMap&quot;: true,
    &quot;declarationMap&quot;: true
  },
  &quot;include&quot;: [
    &quot;src/**/*&quot;
  ]
}&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;declaration, sourceMap, declarationMap 옵선을 true로 설정해주어야한다!!&lt;/li&gt;
&lt;/ul&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;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;4. package.json 파일 수정&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1713180681055&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{
  // ...
  &quot;source&quot;: &quot;src/index.ts&quot;,
  &quot;main&quot;: &quot;dist/index.js&quot;,
  &quot;module&quot;: &quot;dist/index.module.js&quot;,
  &quot;types&quot;: &quot;dist/index.d.ts&quot;,
  &quot;files&quot;: [
    &quot;dist&quot;
  ],
  &quot;scripts&quot;: {
    &quot;build&quot;: &quot;tsc --build&quot;
  },
  &quot;author&quot;: &quot;&quot;,
  &quot;license&quot;: &quot;ISC&quot;,
  &quot;devDependencies&quot;: {
    &quot;typescript&quot;: &quot;^5.4.5&quot;
  }
}&lt;/code&gt;&lt;/pre&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;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;5. .npmrc 파일 생성&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1713181321592&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// .npmrc

@scope:registry=https://npm.pkg.github.com/&lt;/code&gt;&lt;/pre&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;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;6. 배포할 util 함수 생성&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 배포할 간단한 util 함수를 생성한다.&lt;/p&gt;
&lt;pre id=&quot;code_1713181372226&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// src/index.ts

export function printName(name: string) {
  return name;
}&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;package.json에서 &quot;source&quot;를 src/index.ts로 설정해 주었기 때문에 index.ts 파일에 함수를 작성했다.&lt;/li&gt;
&lt;li&gt;파일/폴더를 나누고 싶은 경우 원하는 구조로 작성한 뒤 src/index.ts 파일에서 import 및 export 해주면 된다.&lt;/li&gt;
&lt;li&gt;이후 package.json 버전을 변경한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;  root directory에 있는 package.json의 version을 이전에 배포한 적 없는 버전으로 변경해야 배포할 수 있다.&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;&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;b&gt;7. 배포할 소스 빌드&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1713181507329&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;npm build&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;루트 디렉토리에 dist 파일 생성&lt;/li&gt;
&lt;/ul&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;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;8. &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;개인 액세스 토큰 인증&lt;/span&gt;&lt;/b&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;&lt;b&gt;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;npm login&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1713181697623&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;npm login --scope=@NAMESPACE --auth-type=legacy --registry=https://npm.pkg.github.com

&amp;gt; Username: USERNAME
&amp;gt; Password: GITHUB_ACCESS_TOKEN&lt;/code&gt;&lt;/pre&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;b&gt;~/.npmrc&lt;span&gt;&amp;nbsp;&lt;/span&gt;파일&lt;span&gt;&amp;nbsp;&lt;/span&gt;에 개인 액세스 토큰(클래식) 추가&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1713181817220&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;open ~/.npmrc

# 아래 내용 등록
//npm.pkg.github.com/:_authToken=GITHUB_ACCESS_TOKEN

source ~/.npmrc&lt;/code&gt;&lt;/pre&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;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;9. 배포&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1713181528222&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;npm publish&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;배포가 완료되면 repository 오른쪽 하단 또는 organization의 packages에 패키지가 뜬다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1978&quot; data-origin-height=&quot;810&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vaYey/btsGDz1SCvk/HX9e4XWv07Ru8VKVmKdX7K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vaYey/btsGDz1SCvk/HX9e4XWv07Ru8VKVmKdX7K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vaYey/btsGDz1SCvk/HX9e4XWv07Ru8VKVmKdX7K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvaYey%2FbtsGDz1SCvk%2FHX9e4XWv07Ru8VKVmKdX7K%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;810&quot; data-origin-width=&quot;1978&quot; data-origin-height=&quot;810&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2884&quot; data-origin-height=&quot;1604&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Is48b/btsGCu0XU0H/CPPyFsc91KiajMTkILhdH1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Is48b/btsGCu0XU0H/CPPyFsc91KiajMTkILhdH1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Is48b/btsGCu0XU0H/CPPyFsc91KiajMTkILhdH1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIs48b%2FbtsGCu0XU0H%2FCPPyFsc91KiajMTkILhdH1%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;552&quot; height=&quot;1604&quot; data-origin-width=&quot;2884&quot; data-origin-height=&quot;1604&quot;/&gt;&lt;/span&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;size16&quot;&gt;&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;b&gt;사용 방법&lt;/b&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;배포된 패키지를 클릭하여 들어가면 command line이 나오는데 해당 스크립트를 복사하여 사용하고자하는 프로젝트에서 설치하여 사용할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1713182714459&quot; class=&quot;shell&quot; data-ke-language=&quot;shell&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;npm install @scope/package_name@version&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;간혹 unauthorized 에러가 발생하는 경우가 있는데 그것은 사용 권한 확인이 되지 않았기 때문!&lt;/li&gt;
&lt;li&gt;이런 경우 npm login을 한 다음 다시 설치하면 된다.&lt;/li&gt;
&lt;li&gt;설치 완료된 이후 프로젝트에서 자동 import가 되는지까지 확인한다면 성공적이다  &lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&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;p data-ke-size=&quot;size16&quot;&gt;솔직히 typescript를 도입하면서 삽질을 조금 오래(?) 했는데,,,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;결국 typescript를 javascript로 변환하고 index.d.ts (타입 선언 파일)을 이용하여 type을 지정해주지 않아 발생하는 에러 때문에 고생했던 거시여따...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;tsc --build를 통해 빌드 파일을 만들어 해당 파일들을 배포하니 간단하게(...?) 해결되고 말았다.&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;이상으로 간단한 util 함수를 npm 패키지처럼 배포하여 사용하는 과정에 대해 공부해 보았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 장기적으로는 util 함수를 넘어서 공통으로 자주 사용되는 component까지 개인 패키지로 배포하여 재사용성을 높이는 것이 목표이다.&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;때문에 다음에는 pnpm과 typescript를 이용하여 모노레포를 통해 패키지를 배포하는 방법에 대해 공부해 보려고 한다.&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;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&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;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;&lt;a style=&quot;color: #006dd7; text-align: center;&quot; href=&quot;https://github.com/ez1n&quot;&gt; ez1n github 구경하기 &amp;nbsp;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1713183140365&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;profile&quot; data-og-title=&quot;ez1n - Overview&quot; data-og-description=&quot;Front-End Developer. ez1n has 17 repositories available. Follow their code on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/ez1n&quot; data-og-url=&quot;https://github.com/ez1n&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cd8qzb/hyVPVhhdEA/9wIzpvkopsqKmbRl6zHWBK/img.jpg?width=460&amp;amp;height=460&amp;amp;face=223_257_250_286&quot;&gt;&lt;a href=&quot;https://github.com/ez1n&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/ez1n&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cd8qzb/hyVPVhhdEA/9wIzpvkopsqKmbRl6zHWBK/img.jpg?width=460&amp;amp;height=460&amp;amp;face=223_257_250_286');&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;ez1n - Overview&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Front-End Developer. ez1n has 17 repositories available. Follow their code on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>RECORD</category>
      <category>GitHub</category>
      <category>github packages</category>
      <category>npm</category>
      <category>package</category>
      <category>typescript</category>
      <category>패키지 배포</category>
      <author>ez1n</author>
      <guid isPermaLink="true">https://ttugttag-coding.tistory.com/117</guid>
      <comments>https://ttugttag-coding.tistory.com/117#entry117comment</comments>
      <pubDate>Mon, 15 Apr 2024 21:16:02 +0900</pubDate>
    </item>
    <item>
      <title>[리액트] useEffect vs useLayoutEffect</title>
      <link>https://ttugttag-coding.tistory.com/116</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;[React_ useLayoutEffect]&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;useEffect와 useLayoutEffect의 차이를 알아보자.&lt;/span&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;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&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;span style=&quot;color: #000000;&quot;&gt;이전 회사에 재직하면서 useLayoutEffect라는 React Hook을 처음 접하게 되었다.&lt;/span&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;&lt;span style=&quot;color: #000000;&quot;&gt;사실 잊고 살다가 얼마 전 면접에서 useEffect와 useLayoutEffect의 차이와 useLayoutEffect를 사용해 본 적 있냐는 질문에 다시 떠올랐다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;사용해 본 적도 없고 개념도 잘 몰라서 솔직하게 모른다고 대답하긴 했지만,&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;이번 기회에 공부해보는 것도 좋을 것 같아서 정리해 보려고 한다.&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;lt;STUDY&amp;gt;&lt;/span&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;&lt;span style=&quot;color: #000000;&quot;&gt;❓ &lt;b&gt;useEffect, useLayoutEffect&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;React Component의 Side Effect를 관리하는데 사용되는 Hooks&lt;/span&gt;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1️⃣ &lt;b&gt;useEffect&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;(setup, dependencies)&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;모든 컴포넌트가 render &amp;amp; paint된 이후 비동기적으로 실행된다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;실행 함수에 DOM에 영향을 주는 코드가 있을 경우 화면 깜빡임을 경험할 수 있다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;dependencies에 컴포넌트 내부에 정의된 객체 or 함수가 있는 경우 필요 이상으로 재실행 될 수 있다.(무한 호출)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&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;span style=&quot;color: #000000;&quot;&gt;1. setup 함수&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; &amp;nbsp;- Effect 로직이 포함된 함수&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; &amp;nbsp;- clean up 함수 사용 가능&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;text-align: left;&quot;&gt;&amp;nbsp; &amp;nbsp;- 컴포넌트가 DOM에 추가될 때 실행됨&lt;/span&gt;&lt;span style=&quot;text-align: left;&quot;&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;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;  &lt;b&gt;clean up 함수&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 의존성 배열이 변하면서 모든 리렌더링이 끝나고 처음으로 실행된 이후&amp;nbsp;setup 함수 실행&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;- 컴포넌트가 DOM에서 사라질 때 실행&lt;/span&gt;&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2. dependencies (optional)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; &amp;nbsp;- setup 함수 안에서 참조되는 반응값(reactive values)의 배열&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; &amp;nbsp;- 반응값: 컴포넌트 안에서 선언된 props, state, variables, functions 등&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; &amp;nbsp;- 생략시 리렌더링이 발생할 때마다 다시 실행&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1710768259680&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;useEffect(() =&amp;gt; {
  // functions ...
  
  return () =&amp;gt; {
    // clean up function ...
  }
}, [dependency1, dependency2, ...])&lt;/code&gt;&lt;/pre&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;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2️⃣ &lt;b&gt;useLayoutEffect&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;text-align: start;&quot;&gt;(setup, dependencies)&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;브라우저가 화면을 다시 그리기 전 (paint) 실행되는 useEffect 버전&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;모든 컴포넌트가 render된 이후 동기적으로 실행되고 컴포넌트를 그리기(paint) 때문에 화면 깜빡임이 없다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;로직이 복잡할 경우 사용자가 화면을 보기까지 오래걸린다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000;&quot;&gt;과도하게 사용하는 경우 속도가 저하될 수 있다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&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;span style=&quot;color: #000000;&quot;&gt;1. setup 함수&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; &amp;nbsp;- Effect 로직이 포함된 함수&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; &amp;nbsp;- clean up 함수 사용 가능&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: left;&quot;&gt;&amp;nbsp; &amp;nbsp;- 컴포넌트가 DOM에 추가되기 전(paint 이전) 실행됨&lt;/span&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;&lt;span style=&quot;color: #000000;&quot;&gt;2. dependencies (optional)&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp; &amp;nbsp;- useEffect와 동일&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1710768289659&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;useLayoutEffect(() =&amp;gt; {
  // functions ...
  
  return () =&amp;gt; {
    // clean up function ...
  }
}, [dependency1, dependency2, ...])&lt;/code&gt;&lt;/pre&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start;&quot;&gt;❓&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;b&gt;useEffect vs useLayoutEffect&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 84.7674%; height: 153px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 9.31312%; height: 17px;&quot;&gt;&amp;nbsp;&lt;/td&gt;
&lt;td style=&quot;width: 41.6575%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;useEffect&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 43.779%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;useLayoutEffect&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 64px;&quot;&gt;
&lt;td style=&quot;width: 9.31312%; height: 64px; text-align: center;&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;공통점&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 85.4365%; height: 64px;&quot; colspan=&quot;2&quot;&gt;1. &lt;span&gt;컴포넌트 최상단 or 자체 hooks (커스텀 훅)에서 호출 가능&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;2. 클라이언트 단에서만 실행 (서버 렌더링 동안 실행 X)&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 36px;&quot;&gt;
&lt;td style=&quot;width: 9.31312%; height: 72px; text-align: center;&quot; rowspan=&quot;2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;차이점&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 41.6575%; height: 36px;&quot;&gt;컴포넌트 render &amp;amp; paint 이후 비동기적으로 실행&lt;/td&gt;
&lt;td style=&quot;width: 43.779%; height: 36px;&quot;&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;컴포넌트 render 이후 동기적으로 실행 &amp;amp; paint 실행&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 36px;&quot;&gt;
&lt;td style=&quot;width: 41.6575%; height: 36px;&quot;&gt;깜빡임현상&lt;/td&gt;
&lt;td style=&quot;width: 43.779%; height: 36px;&quot;&gt;깜빡임 현상 X&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&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;p data-ke-size=&quot;size16&quot;&gt;공식문서에서는 성능이 저하될 수 있기 때문에 useLayoutEffect보다는 가급적 useEffect를 사용하라고 권장하고 있다.&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;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;lt;자세한 내용은 &lt;a href=&quot;https://react.dev/reference/react/useEffect&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;React 공식문서&lt;/a&gt;에서 확인 가능합니다&amp;gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1710767822213&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;useEffect &amp;ndash; React&quot; data-og-description=&quot;The library for web and native user interfaces&quot; data-og-host=&quot;react.dev&quot; data-og-source-url=&quot;https://react.dev/reference/react/useEffect&quot; data-og-url=&quot;https://react.dev/reference/react/useEffect&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/lEZr8/hyVAH40lJs/GY91MGrsmXsr6s78i4KwWk/img.png?width=1080&amp;amp;height=567&amp;amp;face=0_0_1080_567,https://scrap.kakaocdn.net/dn/IUYVP/hyVAJV5Jhc/tLtcD5NT2n4YUCj9cASjJk/img.png?width=1080&amp;amp;height=567&amp;amp;face=0_0_1080_567&quot;&gt;&lt;a href=&quot;https://react.dev/reference/react/useEffect&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://react.dev/reference/react/useEffect&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/lEZr8/hyVAH40lJs/GY91MGrsmXsr6s78i4KwWk/img.png?width=1080&amp;amp;height=567&amp;amp;face=0_0_1080_567,https://scrap.kakaocdn.net/dn/IUYVP/hyVAJV5Jhc/tLtcD5NT2n4YUCj9cASjJk/img.png?width=1080&amp;amp;height=567&amp;amp;face=0_0_1080_567');&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;useEffect &amp;ndash; React&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;The library for web and native user interfaces&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;react.dev&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;span style=&quot;text-align: center;&quot;&gt; 내가 보려고 정리하는 React&lt;/span&gt;&lt;span style=&quot;text-align: center;&quot;&gt; &lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;a style=&quot;color: #000000; text-align: center;&quot; href=&quot;https://github.com/ez1n&quot;&gt; ez1n github 구경하기 &amp;nbsp;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1710249912861&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;profile&quot; data-og-title=&quot;ez1n - Overview&quot; data-og-description=&quot;Front-End Developer. ez1n has 14 repositories available. Follow their code on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/ez1n&quot; data-og-url=&quot;https://github.com/ez1n&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/T61Cq/hyVAOVTYW0/kE6Qkt15ZbAjmqkxNufl10/img.jpg?width=460&amp;amp;height=460&amp;amp;face=223_257_250_286&quot;&gt;&lt;a href=&quot;https://github.com/ez1n&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/ez1n&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/T61Cq/hyVAOVTYW0/kE6Qkt15ZbAjmqkxNufl10/img.jpg?width=460&amp;amp;height=460&amp;amp;face=223_257_250_286');&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;ez1n - Overview&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Front-End Developer. ez1n has 14 repositories available. Follow their code on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>FRONTEND/React &amp;amp; React Native</category>
      <category>LifeCycle</category>
      <category>react</category>
      <category>useEffect</category>
      <category>useLayoutEffect</category>
      <category>리액트</category>
      <category>생명주기</category>
      <author>ez1n</author>
      <guid isPermaLink="true">https://ttugttag-coding.tistory.com/116</guid>
      <comments>https://ttugttag-coding.tistory.com/116#entry116comment</comments>
      <pubDate>Mon, 18 Mar 2024 22:39:54 +0900</pubDate>
    </item>
    <item>
      <title>[플러터] FutureBuilder / StatelessWidget에서 데이터 패칭하기</title>
      <link>https://ttugttag-coding.tistory.com/115</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size18&quot;&gt;[Flutter_ FutureBuilder]&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;StatefulWidget을 사용하지 않고 api를 호출하여 데이터 패칭하는 방법을 알아보자.&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&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;b&gt;StatefulWidget으로 state를 정의하고 initState에서 데이터를 불러왔다&lt;/b&gt;..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(리액트의 useEffect와 유사하게 사용하고 있었다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 &lt;b&gt;플러터에서는 state를 잘 사용하지 않는다&lt;/b&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;확실히 initState를 이용하는 경우 해당 데이터의 state를 모두 생성해 주어야하고,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터 패칭 함수를 호출한 뒤 state를 변경해야하기 때문에 상당히 번거롭다는 생각이 들긴했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;((추가로 함수만 다르고 동일한 패턴의 코드가 screen마다 계속 발생하는 부분이 마음에 안들기도 했다(?)ㅋㅋ))&lt;/span&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;그런데 &lt;b&gt;FutureBuilder&lt;/b&gt;라는 위젯을 사용하면&lt;b&gt; StatelessWidget에서 데이터 패칭, 로딩 상태 표현이 가능&lt;/b&gt;하다고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;state를 생성하지 않고 비동기 함수를 호출해서 데이터를 받아올 수 있다..!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 FutureBuilder에 대해 정리해 보려고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;lt;STUDY&amp;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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;❓&lt;b&gt; FutureBuilder&lt;/b&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;비동기 데이터의 상태(로딩, 에러, 완료)에 따라 위젯을 보여줄 때 사용하는 위젯&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;future&lt;/b&gt;: 기다려야하는 데이터의 값 (비동기 데이터 전달)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;builder&lt;/b&gt;: UI를 그려주는 함수&lt;/li&gt;
&lt;li&gt;&lt;b&gt;snapshot&lt;/b&gt; : future의 상태를 알 수 있음 (loading, error, done)&lt;/li&gt;
&lt;/ul&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;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;  전체 코드&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&amp;nbsp;&lt;b&gt;StatefulWidget 사용&lt;/b&gt; (변경 전)&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1708939549961&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class HomeScreen extends StatefulWidget {
  const HomeScreen({super.key});

  @override
  State&amp;lt;HomeScreen&amp;gt; createState() =&amp;gt; _HomeScreenState();
}

class _HomeScreenState extends State&amp;lt;HomeScreen&amp;gt; {
  List&amp;lt;DataModel&amp;gt; data = [];
  bool isLoading = true;

  @override
  void initState() {
    super.initState();
    fetchData();
  }

  void fetchData() async {
    var response  = await getData(); // 데이터 불러오기
    setState(() {
      data = response;
      isLoading = false;
    });
  }

  @override
  Widget build(BuildContext context) {
    if (isLoading) {
      return const Center(
        child: CircularProgressIndicator(),
      );
    }
          
    return Container();
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 데이터를 생성, 초기화한 이후 initState에서 업데이트한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;FutureBuilder 사용&lt;/b&gt; (변경 후)&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1708939739261&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;class HomeScreen extends StatelessWidget {
  HomeScreen({super.key});

  final Future&amp;lt;List&amp;lt;DataModel&amp;gt;&amp;gt; data = getData(); 

  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
        future: data, // 비동기 데이터 전달
        builder: (context, snapshot) {
          if (snapshot.hasData) {
            return Container()
          }
          return const Center(
            child: CircularProgressIndicator(),
          );
        },
      );
  }
}&lt;/code&gt;&lt;/pre&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;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; &lt;/b&gt;&lt;b&gt;&amp;nbsp;차이점&lt;/b&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;&lt;b&gt;&lt;b&gt;&lt;b&gt;1️⃣&lt;/b&gt;&lt;/b&gt;&lt;/b&gt;&amp;nbsp;데이터 정의&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp;- state를 정의하지 않고 바로 데이터 패칭 함수로 데이터를 불러온다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp;- 데이터 타입이 Future로 감싸져있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;변경 전&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1709097024326&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//...

  List&amp;lt;DataModel&amp;gt; data = [];
  bool isLoading = true;

  @override
  void initState() {
    super.initState();
    fetchData();
  }

  void fetchData() async {
    var response  = await getData(); // 데이터 불러오기
    setState(() {
      data = response;
      isLoading = false;
    });
  }
  
//...&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;변경 후&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1709097100844&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//...

final Future&amp;lt;List&amp;lt;DataModel&amp;gt;&amp;gt; data = getData();

//...&lt;/code&gt;&lt;/pre&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;p data-ke-size=&quot;size16&quot;&gt;2️⃣&amp;nbsp;리턴할 위젯&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp;- FutureBuilder로 감싼 후 future와 builder를 구성한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp;- isLoading이라는 state 대신 snapshot의 hasData를 이용하여 로딩 유무를 판별한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp;- 오류가 발생하는 경우 snapshot의 hasError를 이용하여 에러 UI를 노출시킬 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;변경 전&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1709099164444&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//...

  @override
  Widget build(BuildContext context) {
    if (isLoading) {
      return const Center(
        child: CircularProgressIndicator(),
      );
    }
          
    return Container();
  }
  
  //...&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;변경 후&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1709099142896&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;//...

  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
        future: data, // 비동기 데이터 전달
        builder: (context, snapshot) {
          if (snapshot.hasData) {
            return Container()
          }
          return const Center(
            child: CircularProgressIndicator(),
          );
        },
      );
  }
  
  //...&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;FutureBuilder를 사용하니 확실히 코드가 더 간결해지는 것을 볼 수 있었다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;마음이 편-안해 지는 느낌☆&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;그리고 로딩 상태나 오류가 발생했을 때의 UI를 snapshot의 상태에 따라 (hasData, hasError 등) 표현할 수 있기 때문에&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;더욱 간편하게 느껴진다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&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;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;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&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;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #555555; text-align: center;&quot;&gt; 내가 보려고 정리하는 Flutter&lt;/span&gt;&lt;span style=&quot;color: #555555; text-align: center;&quot;&gt; &lt;/span&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;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;a style=&quot;color: #3d62ce; text-align: center;&quot; href=&quot;https://github.com/ez1n&quot;&gt; ez1n github 구경하기 &amp;nbsp;&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1709098364856&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;profile&quot; data-og-title=&quot;ez1n - Overview&quot; data-og-description=&quot;Front-End Developer. ez1n has 14 repositories available. Follow their code on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/ez1n&quot; data-og-url=&quot;https://github.com/ez1n&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/eCS2x/hyVqhrWzTL/ZfwaYqJR8QVhsYNe7WiDP0/img.jpg?width=460&amp;amp;height=460&amp;amp;face=223_257_250_286&quot;&gt;&lt;a href=&quot;https://github.com/ez1n&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/ez1n&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/eCS2x/hyVqhrWzTL/ZfwaYqJR8QVhsYNe7WiDP0/img.jpg?width=460&amp;amp;height=460&amp;amp;face=223_257_250_286');&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;ez1n - Overview&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Front-End Developer. ez1n has 14 repositories available. Follow their code on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>FRONTEND/Flutter</category>
      <category>DART</category>
      <category>Flutter</category>
      <category>FutureBuild</category>
      <category>statefulwidget</category>
      <category>statelesswidget</category>
      <category>다트</category>
      <category>데이터패칭</category>
      <category>플러터</category>
      <author>ez1n</author>
      <guid isPermaLink="true">https://ttugttag-coding.tistory.com/115</guid>
      <comments>https://ttugttag-coding.tistory.com/115#entry115comment</comments>
      <pubDate>Wed, 28 Feb 2024 14:50:49 +0900</pubDate>
    </item>
    <item>
      <title>[Record] 2023년 회고, 그리고 2024년 신년 계획</title>
      <link>https://ttugttag-coding.tistory.com/114</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2022년 개발 공부를 시작한 이후 벌써 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;2023년의 마지막인 12월 31일인 오늘, 23년 한 해를 돌아보려고 한다.&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;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2023년 상반기&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;- 본격적인 취업 준비 시작과 함께 찾아온 불안감, 좌절감&lt;/b&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;2022년에는 주로 공부를 하며 시간을 보냈다면,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2023년에 접어들면서 본격적으로 이력서와 자기소개서, 포트폴리오를 만들며 지원을 시작했던 것 같다.&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;가까웠던 사람들이 꿈을 이루어 원하는 일을 시작하는 모습을 보며 부러운 마음과 동시에 빨리 취업을 해야한다는 부담감이 자리잡았다.&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;자존감도 많이 떨어지고 의욕도 정말 많이 떨어졌던 시기.&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;그럴 때마다 주변 지인의 &quot;넌 잘하고 있어.&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;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;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2023년 하반기&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;- 첫 출근, 그리고 첫 퇴사&lt;/b&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;6월에 갑자기 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;회사에 대해 조사 하면서 &quot;가고 싶다.&quot;라는 생각이 들었던 곳에서 연락이 와서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아침에 눈 뜨자마자 최종 합격도 아닌데 1차 면접 합격 소식에 소리지르면서 엄마한테 뛰어갔던 생각이 난다. ㅋㅋㅋ&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차 면접을 합격해서 그런지 2차 면접따위 합격할 것 같다는 근거없는 자신감을 갖고(???&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;&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;span style=&quot;color: #9d9d9d;&quot;&gt;지금 생각하면 좀 창피한 것 같기도..&lt;/span&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;그렇게 7월 10일에 첫 출근을 했고,&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;&lt;span style=&quot;font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', 'Apple SD Gothic Neo', Arial, sans-serif; letter-spacing: 0px;&quot;&gt;문제가 생겼을 때 함께 고민해주는 사람들이 있다는 것이 좋았고, 그러면서 새로 알게되는 것들이 신기하기도 하고 재미있었다.&lt;/span&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;첫 실무 협업이라 업무 파악이 서툴렀고, 실수도 많이 했겠지만 그래도 열심히 했다..!&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;10월에는 사이드 프로젝트 기획을 시작했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다양한 분야를 접해보고 싶기도 하고, RN과 플러터가 자주 비교되는 만큼 얼마나 다른지도 알아보고 싶었기 때문에,&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;그리고 23년이 거의 끝나갈 무렵, 퇴사를 하게 되었다.&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;26년 살면서 26살에 첫 입사와 첫 퇴사를 동시에 겪다니 신기한 경험이다 ㅎㅎ&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;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2024년에는..&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;- 가장 큰 목표 상반기 취업&lt;/b&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;내년 상반기에는 꼭 관심있는 분야의 회사를 발견하기를!&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;&lt;b&gt;- 영어 공부&lt;/b&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;내년에는 꼭 영어 회화 공부! 해야지!&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;size18&quot;&gt;&lt;b&gt;- 운동하기&lt;/b&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;체력이 너무 떨어졌다. 이제는 해야한다. 건강을 위해서라도..&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;이 세 가지만 지켜도 2024년은 성공이다.&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&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;p data-ke-size=&quot;size16&quot;&gt;뭔가 다사다난했던(?) 2023년 이었던 것 같은데,&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;감사했던 분들도 정말 많고 어쩌구 저쩌구 그랬던 2023년 안녕이다.&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;2024년도 즐겁고, 의미있고, 생산적인, 행복한 일년을 만들어보자!&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;12시 되면 Lotto(EXO) 들을거다. 흥&lt;/span&gt;&lt;/p&gt;</description>
      <category>RECORD</category>
      <author>ez1n</author>
      <guid isPermaLink="true">https://ttugttag-coding.tistory.com/114</guid>
      <comments>https://ttugttag-coding.tistory.com/114#entry114comment</comments>
      <pubDate>Sun, 31 Dec 2023 23:59:04 +0900</pubDate>
    </item>
    <item>
      <title>[Firebase] RDB를 Firestore로 옮기기 / 관계형 데이터베이스 vs 비관계형 데이터베이스, NoSQL, Firebase</title>
      <link>https://ttugttag-coding.tistory.com/113</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size18&quot;&gt;[Firebase_RDB vs NoSQL]&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&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;기존 RDB의 데이터를 Firestore로 이관할 때 어떤 구조로 설계해야할까?&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;관계형 데이터베이스의 데이터를 비관계형 데이터베이스(Firestore)로 옮길 수 있는 방법에 대해 고민하게 되었다.&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;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;RDB 기반의 데이터를 NoSQL 기반의 클라우드 데이터베이스인 Firestore로 옮겼던 경험을 소개하려고 한다.&lt;/p&gt;
&lt;p style=&quot;text-align: left;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&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: center;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;lt;STUDY&amp;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;h4 style=&quot;text-align: left;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;1. 관계형 데이터베이스 vs 비관계형 데이터베이스&amp;nbsp;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;1️⃣ 관계형 데이터베이스&lt;/b&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;관계형 모델을 기반으로 데이터를 행과 열로 구성된 테이블로 구조화하고, 각 테이블 사이의 관계를 표현하는 데이터베이스 구조&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;  &lt;b&gt;관계형 모델&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;데이터를 행(rows)과 열(columns)을 이루는 하나 이상의 &lt;b&gt;테이블(관계)로 정리&lt;/b&gt;하는 모델로,&lt;br /&gt;&lt;b&gt;고유키(Primary Key)&lt;/b&gt;가 각 행(row)을 식별한다.&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;&lt;b&gt;특징&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;외래키(&lt;span style=&quot;background-color: #ffffff; color: #202124; text-align: left;&quot;&gt;Foreign Key&lt;/span&gt;)를 통해 테이블 조인(JOIN)을 통해 관계를 나타내고, 의미있는 정보를 생성한다.&lt;/li&gt;
&lt;li&gt;SQL을 사용한다.&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #1a5490;&quot;&gt;RDB :&lt;/span&gt; MySQL, Oracle Database, Microsoft SQL Server 등&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #1a5490;&quot;&gt;클라우드 기반 RDB :&lt;/span&gt; Cloud SQL, Cloud Spanner, Alloy DB 등&lt;/li&gt;
&lt;/ul&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;b&gt;장점&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;전체 데이터베이스 구조에 영향을 주지 않고 테이블, 관계를 추가 및 삭제하고 데이터를 변경하는 것이 간편하다.&lt;/li&gt;
&lt;li&gt;데이터베이스 정규화를 통해 중복성을 최소화한다.&lt;/li&gt;
&lt;li&gt;SQL을 사용하여 복잡한 쿼리도 쉽게 사용 가능하다.&lt;/li&gt;
&lt;/ul&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;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;2️⃣ 비관계형 데이터베이스&lt;/b&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;특정 데이터 모델에 대해 목적에 맞춰 구축되는 데이터베이스&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;&lt;b&gt;특징&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;고정된 스키마가 존재하지 않는다. (스키마, 관계 정의 X)&lt;/li&gt;
&lt;li&gt;key-value 형식을 지원한다.&lt;/li&gt;
&lt;li&gt;데이터를 복제한다. (수평적 확장 : 모든 데이터를 일괄적으로 수정해야함)&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #1a5490;&quot;&gt;유형 :&lt;/span&gt; key-value, JSON 문서 형태, 그래프 형태 등&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #1a5490;&quot;&gt;예시 :&lt;/span&gt; MongoDB, CouchDB 등&lt;/li&gt;
&lt;/ul&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;b&gt;장점&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;개발이 용이하다.&lt;/li&gt;
&lt;li&gt;복잡한 구조 표현이 가능하다.&lt;/li&gt;
&lt;li&gt;기능성 및 확장성이 뛰어나다.&lt;/li&gt;
&lt;li&gt;쓰기 작업 속도가 빠르다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;2. Firestore로 데이터 이관하기 &amp;amp; 느낀 점&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Firebase는 개인 프로젝트를 진행하면서 많이 사용했던 서비스이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;realtime database를 주로 사용했었는데 회사에 들어오면서 firestore를 경험하게 되었다.&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;firestore가 realtime database와 달랐던 점은 데이터를 JSON 형태가 아닌 &lt;b&gt;collection-document (컬렉션-문서)&lt;/b&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;NoSQL의 특성상 정해진 스키마가 없어 데이터 구조를 자유롭게 표현할 수 있다는 점과,&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;하지만 관계형 데이터베이스처럼 JOIN을 통해 데이터들의 관계를 나타내고 재사용할 수 없다는 점은 단점으로 느껴졌다.&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;p data-ke-size=&quot;size16&quot;&gt;RDB를 Firestore로 옮기면서 가장 힘들고 어렵게 다가왔던 것은 &lt;b&gt;&quot;기존 관계들을 어떻게 정의해야 하는가&quot; &lt;/b&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;- firestore의 참조 타입을 사용하여 데이터를 재사용하거나,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 하위 컬렉션으로 저장한 뒤 특정 데이터만 불러오는 방법,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- document id를 필드값으로 넣고 필터를 걸어 사용하는 등&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;1️⃣&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;하위 컬렉션&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;컬렉션 하위에 새로운 컬렉션을 생성하는 방법&lt;/b&gt;이다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;collectionGroup을 통해 특정 문서 하위 컬렉션을 불러오거나 동일한 컬렉션 이름의 문서들을 모두 불러올 수 있다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;장점&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;카테고리 하위 제품을 바로 불러올 수 있다. (여성 카테고리 &amp;gt; 티셔츠 or 남성 카테고리 &amp;gt; 티셔츠)&lt;/li&gt;
&lt;li&gt;같은 컬렉션 이름을 가진 하위 문서를 한번에 불러올 수 있다. (collectionGroup)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;단점&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;firebase에서 데이터를 바로 찾는 것이 어렵다. (상위 문서의 id가 있어야함)&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;특정 카테고리에 소속되어 있는 데이터의 경우 하위 컬렉션을 활용하면 쉽게 구현이 가능하다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; 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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt; 2️⃣ reference type (참조 타입)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음에는 firestore에서 관계를 가장 쉽게 표현할 수 있는 방법이 바로 참조 타입이라는 생각이 들었다.&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;b&gt;이미 저장된 데이터의 path를 document의 하위 필드 값으로 저장하는 방식&lt;/b&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;&lt;b&gt;장점&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;path(참조 경로)를 통해 데이터를 바로 불러올 수 있다. (doc id를 통한 document 정의 과정 필요 X)&lt;/li&gt;
&lt;li&gt;원본 데이터가 변경되면 참조 데이터가 함께 변경된다. (모든 데이터를 전부 변경할 필요가 없음!)&lt;/li&gt;
&lt;/ul&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;b&gt;단점&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;참조 데이터가 많아질수록 요청되는 read 횟수 또한 늘어난다. (비용 증가)&lt;/li&gt;
&lt;/ul&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;p data-ke-size=&quot;size16&quot;&gt;실제로 배열 안에 들어있는 참조 값들을 전부 읽어오면서 몇 백 건의 read 요청으로 인해 성능에 문제가 발생하는 일이 있었다.&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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;3️⃣ &lt;b&gt;document id 기반의 관계 표현 (front 처리)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참조 타입의 read 요청 증가에 따른 문제점을 보완하기 위해 생각한 방법이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;소속된 (상위) 문서의 id를 저장하고 저장된 id를 기반으로 firestore에서 데이터를 읽어오는 방식&lt;/b&gt;이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 방법은 컬렉션의 모든 문서를 불러온 후 id 값에 따라 front에서 필터 처리를 한 후 보여주는 방식으로 사용할 수 있다.&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;b&gt;장점&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;read 요청을 한 번만 하면 되기 때문에 비용이 절약된다.&lt;/li&gt;
&lt;li&gt;데이터가 많지 않은 경우 front에서 처리하기 때문에 속도 및 성능 개선에 도움이 된다.&lt;/li&gt;
&lt;/ul&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;b&gt;단점&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;참조 데이터가 많은(대용량) 경우 성능에 문제가 생길 수 있다.&lt;/li&gt;
&lt;li&gt;중복되는 데이터 또는 삭제된 데이터가 존재할 수있다.&lt;/li&gt;
&lt;/ul&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;p data-ke-size=&quot;size16&quot;&gt;개인적으로 엄청난 대용량 데이터가 아니라면 이 방법이 가장 적합하다는 생각이 들었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론 front에서 필터 처리를 해야한다는 단점이 있지만,&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;&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;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&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;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;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #9d9d9d;&quot;&gt;&lt;s&gt;이런 저런 관계들이 꼬여 있어서 진짜 머리가 터질뻔 했다(?) ㅎ&lt;/s&gt;&lt;/span&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;시간이 충분하지 않아 더 깊게 고민하고 더 많은 방법을 시도해보지는 못했지만,&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;이번 경험을 기반으로 다음에 firebase를 이용할 때에는 더 나은 방법이 있는지 생각하고 데이터 구조를 정의할 수 있도록 공부해야겠다.&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>RECORD</category>
      <category>Firebase</category>
      <category>firestore</category>
      <category>NoSQL</category>
      <category>rdb</category>
      <category>SQL</category>
      <author>ez1n</author>
      <guid isPermaLink="true">https://ttugttag-coding.tistory.com/113</guid>
      <comments>https://ttugttag-coding.tistory.com/113#entry113comment</comments>
      <pubDate>Wed, 6 Dec 2023 16:47:24 +0900</pubDate>
    </item>
  </channel>
</rss>