<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>백엔드-쵸잉</title>
    <link>https://t1-backend-choing.tistory.com/</link>
    <description>스타트업 개발자</description>
    <language>ko</language>
    <pubDate>Thu, 13 Aug 2026 22:33:22 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>@ChoIng</managingEditor>
    <image>
      <title>백엔드-쵸잉</title>
      <url>https://tistory1.daumcdn.net/tistory/7852876/attach/33c4652ad74448bdb9cfe9626a0e3987</url>
      <link>https://t1-backend-choing.tistory.com</link>
    </image>
    <item>
      <title>대우능력개발원 수강생(2025년 수료) 후기 - 수료부터 스타트업 취업까지</title>
      <link>https://t1-backend-choing.tistory.com/7</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;안녕하세요. 작년에 대우능력개발원 국비 과정을 이수하고 올해 스타트업에 취업한 개발자 이승호라고 합니다.&lt;/p&gt;
&lt;figure contenteditable=&quot;false&quot; data-ke-type=&quot;emoticon&quot; data-ke-align=&quot;alignLeft&quot; data-emoticon-type=&quot;face&quot; data-emoticon-name=&quot;071&quot; data-emoticon-isanimation=&quot;false&quot; data-emoticon-src=&quot;https://t1.daumcdn.net/axz_keditor/emoticon/face/large/071.png&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/axz_keditor/emoticon/face/large/071.png&quot; width=&quot;80&quot; /&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;nbsp;제가 대학교 졸업학년이었을 때, 수업이 끝나고 클라우드&amp;middot;보안코딩 개발자 양성 과정을 들었습니다. 원래 학원에 직접 가야 하는 과정이었지만 학교 강의실에서 수업이 진행돼 이동 없이 들을 수 있었고, 학기 중에도 비교적 편하게 병행할 수 있었습니다. 등록하기 전에는 저도 이 과정을 듣는다고 실제로 취업까지 이어질 수 있을지 고민이 많았습니다. 지금은 스타트업에서 풀스택 개발자로 일하고 있고, 처음에는 프리랜서로 시작했다가 정규직으로 전환됐습니다. 실제로 일을 해보니 당시 배웠던 내용들이 실무에서 생각보다 많이 쓰이고 있어서, 저와 비슷한 고민을 하는 분들에게 도움이 될까 싶어 후기를 남겨봅니다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　교육은 자바 기초부터 시작했습니다. 개인적으로 좋았던 점은 단순히 문법과 사용법만 배우고 넘어가는 것이 아니라 가비지 컬렉터, 스택과 힙처럼 작성한 코드가 내부에서 어떻게 동작하고 메모리가 어떻게 관리되는지까지 깊게 다뤘다는 점입니다. 백엔드도 바로 스프링부트부터 시작하지 않고 JSP부터 기존 스프링을 거쳐 스프링부트까지 순서대로 배워, 기존 방식에서 어떤 부분이 불편했고 지금의 방식으로 어떻게 개선돼 왔는지도 이해할 수 있었습니다. 프론트엔드는 HTML, CSS, 자바스크립트 기초부터 Vue.js까지 배웠고, 젠킨스와 깃허브 액션을 이용한 CI/CD 구성과 AWS 배포도 직접 해봤습니다. 보안 코딩에서는 개발 과정에서 발생할 수 있는 취약점과 이를 방지하는 방법을 배웠고, 마지막에는 지금까지 배운 내용을 활용해 팀 프로젝트를 진행했습니다. 처음에는 배우는 범위가 넓어서 이걸 실제로 다 쓸 일이 있을까 싶기도 했지만, 지금 돌아보면 개발부터 서버와 배포까지 전체적인 흐름을 한 번 경험해본 게 도움이 많이 됐습니다. 과정 중에는 현직 개발자분도 몇 주 동안 주기적으로 오셔서 실제 현업에서는 어떻게 개발하는지 알려주시고, 저희가 진행하던 프로젝트를 보면서 계속 피드백을 해주셨습니다. 평소 개발하면서 궁금했던 부분이나 실제 회사에서는 어떻게 하는지 직접 물어볼 수 있었고, 학생들이 프로젝트를 발표하면 각자의 발표 방식에 대해서도 맞춤 피드백을 해주셔서 자신이 한 작업을 어떻게 정리하고 다른 사람에게 전달해야 하는지도 배울 수 있었습니다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　수료 후에는 스타트업에서 프리랜서 개발자로 일을 시작했습니다. 당시 배포가 수동으로 진행되고 있어 팀원들과 기존 배포 프로세스에 대해 이야기를 나눴고, 개선이 필요하다는 의견이 나와 제가 전담해 깃허브 액션을 이용한 CI/CD 자동 배포 시스템을 구축했습니다. 교육과정에서 직접 CI/CD를 구성해본 경험이 실제 업무로 이어진 사례였습니다. 또한 신규 프로젝트를 맡았을 때는 팀 프로젝트 경험 덕분에 처음부터 프로젝트를 구성하고 개발하는 과정에서도 덜 헤맬 수 있었습니다. 회사의 인프라도 AWS로 구성돼 있어 EC2, RDS 등을 다룰 일이 있었는데, 교육과정에서 AWS 환경을 직접 구성하고 배포해본 경험 덕분에 회사 환경에도 쉽게 적응할 수 있었습니다. 물론 찾아보면 금방 배울 수 있는 부분이지만, 한 번이라도 직접 실습해본 것과 실무에서 처음 접하는 것은 다르다고 생각하고 실제로 많은 도움이 됐습니다. 이렇게 교육과정에서 배운 내용을 실제 업무에 활용하면서 맡는 업무의 범위도 점차 넓어졌고, 현재는 풀스택 개발자로 일하고있습니다.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;　비전공자이거나 처음 개발을 시작하는 분들도 자바 기초부터 차근차근 시작하기 때문에 충분히 따라갈 수 있는 과정이라고 생각합니다. 그렇다고 기초적인 내용만 배우고 끝나는 과정은 아니었습니다. 수업이 진행되면서 코딩에 어느 정도 익숙해진 뒤에도 메모리 구조나 프레임워크의 동작 방식, CI/CD, AWS, 보안 코딩처럼 새롭게 배울 내용이 계속 있었습니다. 저 역시 과정을 따라가며 개발에 점점 익숙해지는 동안에도 배울 점이 많았고, 그때 경험했던 내용들이 지금 실무에서도 이어지고 있습니다. 특히 스타트업처럼 한 가지 역할에만 국한되지 않고 여러 영역을 다뤄야 하는 환경을 생각하고 있다면, 전체적인 개발 과정을 한 번 경험해보는 것이 실무에서도 꽤 도움이 될 수 있습니다. 저도 등록하기 전에는 &amp;lsquo;이걸 듣는다고 정말 취업할 수 있을까?&amp;rsquo;라는 고민을 했던 만큼, 비슷한 고민을 하고 있는 분들에게 제 경험이 조금이나마 참고가 됐으면 좋겠습니다.&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;https://www.dwit.or.kr/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://www.dwit.or.kr/&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Ai</category>
      <category>개발자</category>
      <category>개발자취업</category>
      <category>국비지원</category>
      <category>국비학원</category>
      <category>대우능력개발원</category>
      <category>스타트업</category>
      <category>시큐어코딩</category>
      <category>클라우드보안</category>
      <author>@ChoIng</author>
      <guid isPermaLink="true">https://t1-backend-choing.tistory.com/7</guid>
      <comments>https://t1-backend-choing.tistory.com/7#entry7comment</comments>
      <pubDate>Tue, 11 Aug 2026 22:34:25 +0900</pubDate>
    </item>
    <item>
      <title>파이어베이스 admin 키 만들다가 탈모올뻔할 썰 푼다 &amp;quot;이 서비스 계정에서는 키를 만들 수 없습니다.&amp;quot;</title>
      <link>https://t1-backend-choing.tistory.com/6</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;쵸오오오오오오오오잉 입니다&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;80&quot; data-origin-height=&quot;80&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/obYAV/dJMcagLKMCf/rcACQLUQcyK8tFsaVKnLj1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/obYAV/dJMcagLKMCf/rcACQLUQcyK8tFsaVKnLj1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/obYAV/dJMcagLKMCf/rcACQLUQcyK8tFsaVKnLj1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FobYAV%2FdJMcagLKMCf%2FrcACQLUQcyK8tFsaVKnLj1%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;80&quot; height=&quot;80&quot; data-origin-width=&quot;80&quot; data-origin-height=&quot;80&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h1&gt;사내 계정으로 파이어베이스 비공개 키 만들어야되는데 구글이 만들어주질 않는다&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스트레스_폭발_머리_화산_폭발_편집_crop.gif&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;720&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/brwPcL/dJMb996UK73/9khVqzhtXyKIfe14Hilq3K/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/brwPcL/dJMb996UK73/9khVqzhtXyKIfe14Hilq3K/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/brwPcL/dJMb996UK73/9khVqzhtXyKIfe14Hilq3K/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/brwPcL/dJMb996UK73/9khVqzhtXyKIfe14Hilq3K/img.gif&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;1080&quot; height=&quot;720&quot; data-filename=&quot;스트레스_폭발_머리_화산_폭발_편집_crop.gif&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;720&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;탈모올뻔했다 ㄹㅇ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;  문제 상황&lt;/h2&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;이 서비스 계정에서는 키를 만들 수 없습니다. 조직 정책에 따라 서비스 계정 키 생성이 제한되는지 확인하세요.&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;961&quot; data-origin-height=&quot;674&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/triwQ/dJMcaa5Pkx4/azfoTmMOuxoAX423TMn9f1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/triwQ/dJMcaa5Pkx4/azfoTmMOuxoAX423TMn9f1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/triwQ/dJMcaa5Pkx4/azfoTmMOuxoAX423TMn9f1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FtriwQ%2FdJMcaa5Pkx4%2FazfoTmMOuxoAX423TMn9f1%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;961&quot; height=&quot;674&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;961&quot; data-origin-height=&quot;674&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아 예?!?!&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://t1.daumcdn.net/keditor/emoticon/friends1/large/046.gif&quot; alt=&quot;&quot; width=&quot;265&quot; height=&quot;265&quot; /&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개인 프로젝트만 하다 회사프로젝트로 회사 워크스페이스에서 파이어베이스를 만지다보니 한번도 보지못한 오류에 직면했다&lt;br /&gt;저걸 안하면 FCM 을 못해서 꼭 해야되는데 이것 때문에 몇시간을 삽질했다&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;험난했던 삽질 과정&lt;/h2&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;회사 조직 워크스페이스로 이루어진 시스템이다보니 뭐만 하면 권한이 막힌다 권한 승인해달라고 요청드렸더니 다음단계에서 또 권한이 막힘 그래서 좀만더 찾아보자고 함&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;IAM 권한에 문제는 없었다 애초에 부여받은 계정으로 파이어베이스 프로젝트 생성시 &quot;소유자&quot; 권한을 갖게됨&lt;/li&gt;
&lt;li&gt;즉 계정에 부여받은 권한으로 파이어베이스에서 일반적으로 대부분의 기능을 만드는데는 문제가없음&lt;/li&gt;
&lt;li&gt;마스터 워크스페이스계정으로 비공개 키를 만들면 되지않을까? 해서 요청 드렸으나 똑같은 문제 발생 이땐 정말 OTL 그자체였다&lt;/li&gt;
&lt;li&gt;급기야 그냥 개인계정에 프로젝트 만들고 회사계정에 소유권 이전까지 생각하게되는데...&lt;/li&gt;
&lt;/ol&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;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;必死則生 必生則死 (필사즉생 필생즉사)&lt;br /&gt;죽고자 하면 살것이고 살고자 하면 죽을 것이다&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p style=&quot;text-align: center;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;죽었다 생각하니 해답이 보였따!!&lt;/b&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;원인 : 그렇다면 뭐가 문제였냐?&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;897&quot; data-origin-height=&quot;241&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xOMEG/dJMcag52RSe/LpKnR9EotrEOAlHWaVHlck/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xOMEG/dJMcag52RSe/LpKnR9EotrEOAlHWaVHlck/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xOMEG/dJMcag52RSe/LpKnR9EotrEOAlHWaVHlck/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxOMEG%2FdJMcag52RSe%2FLpKnR9EotrEOAlHWaVHlck%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;897&quot; height=&quot;241&quot; data-origin-width=&quot;897&quot; data-origin-height=&quot;241&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최근에 만든 계정이다보니 다음과 같이 키 생성 제약이 디폴트옵션으로 활성화되어 있어서 그런것이다&lt;br /&gt;처음에 단순히 cmd+f 로 조직계정에서 &quot;disableServiceAccountKeyCreation&quot; 항목을 검색했다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;근데 어라라? 문서에선 비활성화 처리하라고 돼있는데 이미 비활성화되어있었다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2차멘붕&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 이 문제는 생각보다 간단했다 해당 옵션이 더 뒤에 다음페이지에 숨겨져서 안보였던것!!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1215&quot; data-origin-height=&quot;155&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/UcbH6/dJMcacbuUXc/J6D9LGEJK6kuIQtcKtV5U1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/UcbH6/dJMcacbuUXc/J6D9LGEJK6kuIQtcKtV5U1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/UcbH6/dJMcacbuUXc/J6D9LGEJK6kuIQtcKtV5U1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FUcbH6%2FdJMcacbuUXc%2FJ6D9LGEJK6kuIQtcKtV5U1%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;1215&quot; height=&quot;155&quot; data-origin-width=&quot;1215&quot; data-origin-height=&quot;155&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;IAM 관리자-&amp;gt;조직정책&lt;/b&gt; 에서 필터옆에 disableServiceAccountKeyCreation 검색하면 2개가 나오는데 아래에있는 활성을 비활성화로 만들어야된다&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;457&quot; data-origin-height=&quot;146&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cEODBa/dJMcaf67exm/TFfCmPqnyhrNt1khJ9HNuk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cEODBa/dJMcaf67exm/TFfCmPqnyhrNt1khJ9HNuk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cEODBa/dJMcaf67exm/TFfCmPqnyhrNt1khJ9HNuk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcEODBa%2FdJMcaf67exm%2FTFfCmPqnyhrNt1khJ9HNuk%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;457&quot; height=&quot;146&quot; data-origin-width=&quot;457&quot; data-origin-height=&quot;146&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 수정하려보니 비활성화되어있다 해당권한은 문서에서 분명히 &lt;b&gt;&quot;조직 정책 관리자&quot;&lt;/b&gt; 를 부여해야 바꿀수있다는데 이상한애들만 보인다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;405&quot; data-origin-height=&quot;360&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cHkqYr/dJMcaa5PlC6/WaxCfLFlJVCKXS0HaoB6N1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cHkqYr/dJMcaa5PlC6/WaxCfLFlJVCKXS0HaoB6N1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cHkqYr/dJMcaa5PlC6/WaxCfLFlJVCKXS0HaoB6N1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcHkqYr%2FdJMcaa5PlC6%2FWaxCfLFlJVCKXS0HaoB6N1%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;405&quot; height=&quot;360&quot; data-origin-width=&quot;405&quot; data-origin-height=&quot;360&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내가 찾는건 이게 아니라구요 ㅠㅠ&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt; 해결과정&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다시한번 절망 &lt;b&gt;대 공 황&lt;/b&gt; 상태가 되었는데 나와 비슷한 문제를 겪은 선배님들의 답변&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;735&quot; data-origin-height=&quot;165&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cFnEx0/dJMcah4XmiT/3bdlWA1EfMY1GheHj0xTL0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cFnEx0/dJMcah4XmiT/3bdlWA1EfMY1GheHj0xTL0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cFnEx0/dJMcah4XmiT/3bdlWA1EfMY1GheHj0xTL0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcFnEx0%2FdJMcah4XmiT%2F3bdlWA1EfMY1GheHj0xTL0%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;735&quot; height=&quot;165&quot; data-origin-width=&quot;735&quot; data-origin-height=&quot;165&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&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;b&gt;자라미또(Zalamito)&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;size18&quot;&gt;&lt;b&gt;1. 조직 계정 진입&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;250&quot; data-origin-height=&quot;213&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c4NRK4/dJMcafe1Uvw/DlWHi2OaFFzFdLF8KivHBk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c4NRK4/dJMcafe1Uvw/DlWHi2OaFFzFdLF8KivHBk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c4NRK4/dJMcafe1Uvw/DlWHi2OaFFzFdLF8KivHBk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc4NRK4%2FdJMcafe1Uvw%2FDlWHi2OaFFzFdLF8KivHBk%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;250&quot; height=&quot;213&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;250&quot; data-origin-height=&quot;213&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;&lt;b&gt;&amp;nbsp; IAM 관리자 -&amp;gt; IAM&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;size18&quot;&gt;&lt;b&gt;2. 조직관리자 부여&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;534&quot; data-origin-height=&quot;40&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cr1SJi/dJMcabwSnWQ/B40OkEY9x1gy07yKlhjNxk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cr1SJi/dJMcabwSnWQ/B40OkEY9x1gy07yKlhjNxk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cr1SJi/dJMcabwSnWQ/B40OkEY9x1gy07yKlhjNxk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcr1SJi%2FdJMcabwSnWQ%2FB40OkEY9x1gy07yKlhjNxk%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;534&quot; height=&quot;40&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;534&quot; data-origin-height=&quot;40&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&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;1. 조직 정책 관리자를 부여해달라고 요청하거나&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. iam 수정권한을 링크로 보낼수있는데&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;본좌는 후자를 택했다&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;418&quot; data-origin-height=&quot;366&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/A2oXc/dJMcadalwwm/s2RnDqfwakcJVglK4PGjv1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/A2oXc/dJMcadalwwm/s2RnDqfwakcJVglK4PGjv1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/A2oXc/dJMcadalwwm/s2RnDqfwakcJVglK4PGjv1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FA2oXc%2FdJMcadalwwm%2Fs2RnDqfwakcJVglK4PGjv1%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;418&quot; height=&quot;366&quot; data-origin-width=&quot;418&quot; data-origin-height=&quot;366&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;짜잔!!!! 조직정책관리자가 떴다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;3.disableServiceAccountKeyCreation 옵션 비활성화&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1354&quot; data-origin-height=&quot;167&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bvMRb1/dJMcagdUE34/K6kJTVJw1PZIWlqi2IUZ71/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bvMRb1/dJMcagdUE34/K6kJTVJw1PZIWlqi2IUZ71/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bvMRb1/dJMcagdUE34/K6kJTVJw1PZIWlqi2IUZ71/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbvMRb1%2FdJMcagdUE34%2FK6kJTVJw1PZIWlqi2IUZ71%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;1354&quot; height=&quot;167&quot; data-origin-width=&quot;1354&quot; data-origin-height=&quot;167&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아까는 비활성화 되어있던 정책수정이 활성화되었따!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;614&quot; data-origin-height=&quot;551&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/6UB6k/dJMcacWQ0FQ/CKPTyuyVPbobyqYqEk7TAk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/6UB6k/dJMcacWQ0FQ/CKPTyuyVPbobyqYqEk7TAk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/6UB6k/dJMcacWQ0FQ/CKPTyuyVPbobyqYqEk7TAk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6UB6k%2FdJMcacWQ0FQ%2FCKPTyuyVPbobyqYqEk7TAk%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;429&quot; height=&quot;385&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;614&quot; data-origin-height=&quot;551&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;미적용하고 설정하면&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1186&quot; data-origin-height=&quot;147&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/GQXxX/dJMcagya62R/M1SaPNsABVqRBlMBklsu7k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/GQXxX/dJMcagya62R/M1SaPNsABVqRBlMBklsu7k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/GQXxX/dJMcagya62R/M1SaPNsABVqRBlMBklsu7k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FGQXxX%2FdJMcagya62R%2FM1SaPNsABVqRBlMBklsu7k%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;1186&quot; height=&quot;147&quot; data-origin-width=&quot;1186&quot; data-origin-height=&quot;147&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;상위 규칙도 비활성화되면서 드디어 키를 만들수 있게된다!!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;417&quot; data-origin-height=&quot;248&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/uE1RX/dJMcahjBPwh/00BpKOD0i4LwCfjtna5C60/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/uE1RX/dJMcahjBPwh/00BpKOD0i4LwCfjtna5C60/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/uE1RX/dJMcahjBPwh/00BpKOD0i4LwCfjtna5C60/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FuE1RX%2FdJMcahjBPwh%2F00BpKOD0i4LwCfjtna5C60%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;417&quot; height=&quot;248&quot; data-filename=&quot;blob&quot; data-origin-width=&quot;417&quot; data-origin-height=&quot;248&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;딸깍하면 나오던 json 파일이 이렇게 험난할줄이야ㅠㅠ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아무튼 해결이요&lt;/p&gt;
&lt;figure contenteditable=&quot;false&quot; data-ke-type=&quot;emoticon&quot; data-ke-align=&quot;alignLeft&quot; data-emoticon-type=&quot;friends1&quot; data-emoticon-name=&quot;032&quot; data-emoticon-isanimation=&quot;false&quot; data-emoticon-src=&quot;https://t1.daumcdn.net/keditor/emoticon/friends1/large/032.gif&quot;&gt;&lt;img src=&quot;https://t1.daumcdn.net/keditor/emoticon/friends1/large/032.gif&quot; width=&quot;150&quot; /&gt;&lt;/figure&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;참고&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.cloud.google.com/iam/docs/troubleshoot-org-policies?hl=ko&quot;&gt;https://docs.cloud.google.com/iam/docs/troubleshoot-org-policies?hl=ko&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.reddit.com/r/googleworkspace/comments/1biw03d/service_account_key_creation_is_disabled/?tl=ko&quot;&gt;https://www.reddit.com/r/googleworkspace/comments/1biw03d/service_account_key_creation_is_disabled/?tl=ko&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.cloud.google.com/organization-policy/restrict-service-accounts?hl=ko#disable_service_account_creation&quot;&gt;https://docs.cloud.google.com/organization-policy/restrict-service-accounts?hl=ko#disable_service_account_creation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>클라우드&amp;amp;인프라/Firebase</category>
      <category>FCM</category>
      <category>Firebase</category>
      <category>gcp</category>
      <category>IAM</category>
      <category>iam.disableServiceAccountKeyCreation</category>
      <category>비공개키</category>
      <category>서비스계정</category>
      <category>조직정책</category>
      <category>조직정책관리자</category>
      <category>파이어베이스</category>
      <author>@ChoIng</author>
      <guid isPermaLink="true">https://t1-backend-choing.tistory.com/6</guid>
      <comments>https://t1-backend-choing.tistory.com/6#entry6comment</comments>
      <pubDate>Mon, 30 Mar 2026 22:34:39 +0900</pubDate>
    </item>
    <item>
      <title>[ 스프링부트 ] Could not autowire. Multi bean found 원인과 해결</title>
      <link>https://t1-backend-choing.tistory.com/5</link>
      <description>&lt;p&gt;쵸오오오오오오오오잉 입니다&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://t1.daumcdn.net/keditor/emoticon/face/small/071.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h1&gt;  문제 상황&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;스프링에서 인터페이스를 &lt;code&gt;@Autowired&lt;/code&gt; 를 통해 의존성 주입할 때 이걸 구현할 클래스가 2개 이상일 때 어떤 클래스를 주입해야 될지 몰라서 스프링에서는 예외를 발생시킴&lt;ul&gt;
&lt;li&gt;Service라는 클래스에서 Dao라는 인터페이스를 DI로 주입받고 있는 상황&lt;/li&gt;
&lt;li&gt;Dao라는 인터페이스는 2개의 클래스가 구현하고 있음(AAADao, BDDDao)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;제목 없는 다이어그램.drawio.png&quot; data-origin-width=&quot;621&quot; data-origin-height=&quot;171&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bEw2up/btsOQIqnjCh/mfA4g7MmV4oxP8D8xrXlo1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bEw2up/btsOQIqnjCh/mfA4g7MmV4oxP8D8xrXlo1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bEw2up/btsOQIqnjCh/mfA4g7MmV4oxP8D8xrXlo1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbEw2up%2FbtsOQIqnjCh%2FmfA4g7MmV4oxP8D8xrXlo1%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;621&quot; height=&quot;171&quot; data-filename=&quot;제목 없는 다이어그램.drawio.png&quot; data-origin-width=&quot;621&quot; data-origin-height=&quot;171&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;| 잉..? 그냥 구현 클래스를 주입받은면 되는 거 아닌가?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;안될 건 없음 오히려 하면 위와 같은 문제는 해결됨&lt;/li&gt;
&lt;li&gt;단, 객체 지향 설계 원칙 SOLID에서 &lt;strong&gt;의존 역전 원칙(Dependency Inversion Principle)&lt;/strong&gt; &lt;em&gt;&amp;quot;구현체에 의존하면 안 되고 추상화에 의존해야 된다&amp;quot;라는&lt;/em&gt; 원칙에 어긋남&lt;/li&gt;
&lt;li&gt;또한 추상화에 의존하면 유연하게 변경이 가능하여 확장성에 좋음(유지보수 용이)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;참고 코드&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;// 인터페이스 
public interface FileUploader {
    String fileUpload(File file);
}

// 인터페이스 구현체
@Component
public class AwsS3Uploader implements FileUploader{
    @Override
    public String fileUpload(File file) {
        // 구현코드 
    }
}
// 인터페이스 구현체
@Component
public class LocalFileUploader implements FileUploader{
    @Override
    public String fileUpload(File file) {
        // 구현 코드
    }
}
@Service
public class FileService {
    private FileUploader fileUploader;
    // FileUploader 라는 인터페이스로 주입시 오류 발생 !
    public FileService(FileUploader fileUploader) {
        this.fileUploader = fileUploader;
    }
}&lt;/code&gt;&lt;/pre&gt;&lt;h1&gt;  해결방법&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1262&quot; data-origin-height=&quot;50&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cy8F8b/btsOSme0hZx/WNqTGTn7kRhdT5BLAoJJW1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cy8F8b/btsOSme0hZx/WNqTGTn7kRhdT5BLAoJJW1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cy8F8b/btsOSme0hZx/WNqTGTn7kRhdT5BLAoJJW1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcy8F8b%2FbtsOSme0hZx%2FWNqTGTn7kRhdT5BLAoJJW1%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;1262&quot; height=&quot;50&quot; data-origin-width=&quot;1262&quot; data-origin-height=&quot;50&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;p&gt;&lt;em&gt;Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed&lt;/em&gt;&lt;/p&gt;
&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;h3&gt;1. &lt;code&gt;@Primary&lt;/code&gt; 를 통해 주입받는 우선순위를 부여&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;@Primary
@Component
public class AwsS3Uploader implements FileUploader {
    @Override
    public String fileUpload(File file) {
        return &amp;quot;&amp;quot;;
    }
}&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;컴포넌트 스캔 대상인 어노테이션 (Component, Service, Controller 등..) 혹은 &lt;code&gt;@Bean&lt;/code&gt; 에서 @Primary를 통해 우선순위를 부여 가능&lt;/li&gt;
&lt;li&gt;구현체가 여러 개인 인터페이스를 주입받는 클래스의 경우 @Primary 로 우선순위 부여받은 클래스가 주입됨&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2. &lt;code&gt;@Qualifier&lt;/code&gt; 를 통해 주입할 클래스를 선택&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;@Service
public class FileService {
    private FileUploader fileUploader;

    public FileService(@Qualifier(&amp;quot;awsS3Uploader&amp;quot;) FileUploader fileUploader) {
        this.fileUploader = fileUploader;
    }
}&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;생성자 주입의 경우 &lt;code&gt;@Qualifier&lt;/code&gt; 어노테이션에서 네이밍을 통해 주입할 클래스를 선택할 수 있음 이 &lt;strong&gt;&amp;#39;네이밍&amp;#39;&lt;/strong&gt; 은 기본적으로 클래스명에서 첫 글자만 소문자로 한 값이 기본값&lt;/li&gt;
&lt;li&gt;&lt;code&gt;@Component&lt;/code&gt; 어노테이션에 이름을 따로 지정하면 그 이름으로 Qualifier를 지정할 수 있음&lt;/li&gt;
&lt;li&gt;&lt;code&gt;@Component(&amp;quot;aws&amp;quot;)&lt;/code&gt; 로 지정할 경우 생성자 주입에서 아래와 같이 사용이 가능&lt;/li&gt;
&lt;li&gt;&lt;code&gt;public FileService(@Qualifier(&amp;quot;aws&amp;quot;) FileUploader fileUploader) { this.fileUploader = awsS3Uploader; } }&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;@Primary&lt;/code&gt; 로 우선순위가 부여되더라도 &lt;code&gt;@Qualifier&lt;/code&gt; 가 우선적으로 주입된다 즉 @Qualifer 의 우선순위가 더 높다&lt;/p&gt;
&lt;h3&gt;3. &lt;code&gt;@AutoWired&lt;/code&gt; 필드명으로 하위 클래스 선택&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;@Service
public class FileService {
    private FileUploader awsS3Uploader;

    public FileService(FileUploader awsS3Uploader) {
        this.awsS3Uploader = awsS3Uploader;
    }
}&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;필드명&lt;/strong&gt; 또는 생성자 주입의 경우 &lt;strong&gt;파라미터 명&lt;/strong&gt;으로도 주입할 클래스를 지정할 수 있음 &lt;code&gt;@Qualifier&lt;/code&gt; 에서 했던 방식과 유사하게 주입하려는 클래스에서 앞글자만 소문자로 설정하는 것이 기본값&lt;/li&gt;
&lt;li&gt;&lt;code&gt;@Component&lt;/code&gt; 에 별도로 이름을 지정한 경우, 해당 이름과 일치하는 변수명을 생성자 파라미터로 사용해야 정상적으로 주입된다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;@Component(&amp;quot;aws&amp;quot;)&lt;/code&gt; 일경우 변수명 혹은 파라미터명으로 해도 해당 클래스가 주입됨&lt;/li&gt;
&lt;li&gt;우선순위가 가장 낮음 &lt;code&gt;@Qualifier&lt;/code&gt; &lt;code&gt;@Primary&lt;/code&gt; 둘 다 매칭되지 않으면 &lt;code&gt;@Autowired&lt;/code&gt; 필드명으로 주입&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;4. &lt;code&gt;@Configuration&lt;/code&gt; 에서 &lt;code&gt;@Bean&lt;/code&gt; 을 등록&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;@Configuration
public class AppConfiguration {
    @Bean
    public FileUploader getFileUploader(){
        return new AwsS3Uploader();
    }
}
// @Component 어노테이션 제거
public class AwsS3Uploader implements FileUploader {
// ... 생략
}
// @Component 어노테이션 제거
public class LocalFileUploader implements FileUploader{
// ... 생략
}&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;가장 원초적인 방식&lt;/li&gt;
&lt;li&gt;컴포넌트 스캔 대상인 어노테이션 (@Controller,@Service,@Component 등...) 은 제거 해야 꼬이지 않음&lt;ul&gt;
&lt;li&gt;@Qualifier 를 사용할 때 bean으로 등록한 메서드 명으로 등록가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;추상 클래스를 리턴해주는 &lt;code&gt;@Bean&lt;/code&gt; 을 설정하고 리턴값에 구현클래스를 지정&lt;/li&gt;
&lt;li&gt;&lt;code&gt;@Primary&lt;/code&gt; 와 연계하여 구현클래스를 리턴하는 &lt;code&gt;@Bean&lt;/code&gt; 을 여러 개 만든 후 우선순위 지정 가능&lt;/li&gt;
&lt;li&gt;Configuraion에서 전체의 의존성을 관리하기 때문에 앞에서 &lt;code&gt;@Qualifier&lt;/code&gt;, &lt;code&gt;@Primary&lt;/code&gt; 등과 같이 지정하는 거에 비해 관리 용이&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;5. Collection Based Injection&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;@Service
public class FileService {
    private Map&amp;lt;String,FileUploader&amp;gt; fileUploader;

    public FileService(Map&amp;lt;String, FileUploader&amp;gt; fileUploader) {
        this.fileUploader = fileUploader;
    }

    public String test(){
        return fileUploader.get(&amp;quot;localFileUploader&amp;quot;).fileUpload(null);
    }
}&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;배열 Collection 객체 등을 통해 구현클래스를 모두 주입하여 필요한 구현클래스 참조하여 사용&lt;/li&gt;
&lt;li&gt;Map의 경우 String Key 값에 구현 클래스의 앞글자만 소문자로 바꾼 값이 기본값이어도 이것도 &lt;code&gt;@Component&lt;/code&gt; 에서 이름을 지정하면 그 값이 Key 값이 됨&lt;/li&gt;
&lt;li&gt;위에서 했던 방식들과 주입될 클래스를 사전에 지정하는 방식이 아닌 유연하게 하위 클래스에 접근 가능&lt;/li&gt;
&lt;li&gt;Map 뿐만 아니라 Set, List 도 가능하나 Map 이 접근하기가 편함  &lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;  결론&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;인터페이스 기반의 의존성 주입(DI) 시, 구현 클래스가 2개 이상 존재하면 어떤 구현체를 주입할지 스프링이 판단하지 못해서 에러가 발생&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;우선순위&lt;/th&gt;
&lt;th&gt;메서드&lt;/th&gt;
&lt;th&gt;특징&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;1순위&lt;/td&gt;
&lt;td&gt;&lt;code&gt;@Qualifier&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;가장 명시적인 방식, 이름으로 특정 구현체 지정&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2순위&lt;/td&gt;
&lt;td&gt;&lt;code&gt;@Primary&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;기본(default)으로 주입할 구현체 설정&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3순위&lt;/td&gt;
&lt;td&gt;&lt;code&gt;@Autowired&lt;/code&gt; 필드명&lt;/td&gt;
&lt;td&gt;클래스명 기반 자동 매칭, 우선순위 가장 낮음&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;구현체가 많고, 유연한 전략 전환이 필요하거나 플러그인 구조처럼 동적으로 선택해야 할 경우엔 Map, List, Set 등의 컬렉션 기반 주입(Collection-based injection)을 사용하면 확장성과 유지보수가 훨씬 좋아짐&lt;/li&gt;
&lt;li&gt;추상 클래스의 구현체를 동시에 여러 개를 써야 할 상황이 올경우 &lt;strong&gt;Collection Based Injection&lt;/strong&gt; 을 사용하여 Map과 같은 Collection 객체에서 관리 가능&lt;/li&gt;
&lt;li&gt;Java Config (@Configuration)를 통해 명시적으로 Bean을 등록하고 관리하는 방식도 고려해 볼 수 있음&lt;ul&gt;
&lt;li&gt;이는 전체 의존성을 한눈에 파악하고 제어할 수 있는 장점이 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>백엔드/스프링부트</category>
      <category>autowired</category>
      <category>collectionbasedinjection</category>
      <category>Di</category>
      <category>Primary</category>
      <category>Qualifier</category>
      <category>Solid</category>
      <category>스프링</category>
      <category>의존성</category>
      <category>의존성주입</category>
      <category>자바</category>
      <author>@ChoIng</author>
      <guid isPermaLink="true">https://t1-backend-choing.tistory.com/5</guid>
      <comments>https://t1-backend-choing.tistory.com/5#entry5comment</comments>
      <pubDate>Thu, 26 Jun 2025 01:14:52 +0900</pubDate>
    </item>
    <item>
      <title>[ JAVA ] Scanner nextInt() 와 nextLine() 을 같이썻다가 억장 와르르</title>
      <link>https://t1-backend-choing.tistory.com/4</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;쵸오오오오오오오오잉 입니다&lt;/p&gt;
&lt;h1&gt;발생 배경 &amp;amp; 문제 상황&lt;/h1&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;국비 수업 중 scanner로 입력을 받을 때 nextInt()와 nextLine()을 연달아서 입력했더니 nextLine() 이 무시되고 오류가 발생&lt;/li&gt;
&lt;li&gt;줄 바꿈이 버퍼에 남아 이런 오류가 발생했고 nextLine() 하고 정수변환을 하는 것으로 결론이 났지만 왜 버퍼에 남아있을지 의문이 생겨 Scanner 내부를 분석해 봄&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;reasonml&quot;&gt;&lt;code&gt;import java.util.*;

class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int a = sc.nextInt(); // 아무 숫자나 입력하고 엔터를 치는 순간 NumberFormatException 발생
        int b = Integer.parseInt(sc.nextLine());
        System.out.println(a);
        System.out.println(b);
    }
}

```bash
2
4&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 와 같은 정수 2개를 입력하려 했으나 엔터를 치는 순간 &lt;code&gt;NumberFormatException: For Input String :&quot;&quot;&lt;/code&gt; 발생&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;756&quot; data-origin-height=&quot;150&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/LyOse/btsOKTwMxnw/6cvzsL2BIbkfvhKIR040TK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/LyOse/btsOKTwMxnw/6cvzsL2BIbkfvhKIR040TK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/LyOse/btsOKTwMxnw/6cvzsL2BIbkfvhKIR040TK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLyOse%2FbtsOKTwMxnw%2F6cvzsL2BIbkfvhKIR040TK%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;756&quot; height=&quot;150&quot; data-origin-width=&quot;756&quot; data-origin-height=&quot;150&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h1&gt;원인 분석&lt;/h1&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;이런 현상이 발생하는 이유는 next()&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;nextInt()는 내부적으로 next()를 호출하고 입력받은 값에 정수로 변환해 주는 함수&lt;/li&gt;
&lt;li&gt;next() 함수는 자바 스캐너에 선언된 구분자(delimeter) 기준으로 토큰을 구분
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;delimeter의 기본값은 javaWhiteSpace인데 이는 줄 바꿈 공백 탭 등이 포함된 값임&lt;br /&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;595&quot; data-origin-height=&quot;49&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Vupvj/btsOHXuwzCp/5HtnpVGj18BSkCK6l7KmFK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Vupvj/btsOHXuwzCp/5HtnpVGj18BSkCK6l7KmFK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Vupvj/btsOHXuwzCp/5HtnpVGj18BSkCK6l7KmFK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FVupvj%2FbtsOHXuwzCp%2F5HtnpVGj18BSkCK6l7KmFK%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;595&quot; height=&quot;49&quot; data-origin-width=&quot;595&quot; data-origin-height=&quot;49&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;next()의 입력 처리 과정&lt;/h3&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;code&gt;Matcher라는&lt;/code&gt; 클래스를 통해 &lt;code&gt;Pattern&lt;/code&gt; 을 기준으로 토큰을 끊음&lt;/li&gt;
&lt;li&gt;delimeter 가 있기 전까지의 위치까지 토큰으로 처리
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;단 delimeter 자체를 소비하진 않음 버퍼에 남아있음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;delimeter 처음 나오는 delimeter는 skip 함&lt;br /&gt;위와 같은 과정을 반복&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;문제 상황 분석&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;문제가 발생한 입력을 string으로 변환해서 생각하면 &lt;code&gt;2\n4&lt;/code&gt; 임&lt;/li&gt;
&lt;li&gt;next()는 delimeter (기본값인 줄 바꿈 공백 탭) 이 오게 되면 delimeter 가 나오기 바로 전까지의 '토큰'을 반환함
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;단 deleimeter 토큰 자체를 소모하는 건 아님 버퍼에는 남아있음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;2라는 토큰을 반환하고 nextInt()를 통해 정수변환&lt;/li&gt;
&lt;li&gt;스캐너 버퍼에는 2를 처리하고 \n4를 처리해야 됨&lt;/li&gt;
&lt;li&gt;nextLine() 은 \n을 보는 순간 바로 입력 처리함 근데 \n 전에는 아무 값이 없기 때문에 &quot;&quot; 공백을 정수로 변환하지만 예외 발생&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;해결 방안&lt;/h1&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;nextLine()으로 \n 소모&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;reasonml&quot;&gt;&lt;code&gt;import java.util.*;
class Main {  
    public static void main(String[] args) {  
        Scanner sc = new Scanner(System.in);  
        int a = sc.nextInt();  
        sc.nextLine();  
        int b = Integer.parseInt(sc.nextLine());  
        System.out.println(a);  
        System.out.println(b);  
    }  
}&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;ol style=&quot;list-style-type: decimal;&quot; start=&quot;2&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;nextInt() nextLine() 혼용해서 사용하지 않기
&lt;pre class=&quot;actionscript&quot;&gt;&lt;code&gt;import java.util.*;
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;class Main {&lt;br /&gt;public static void main(String[] args) {&lt;br /&gt;Scanner sc = new Scanner(System.in);&lt;br /&gt;int a = Integer.parseInt(sc.nextLine());&lt;br /&gt;int b = Integer.parseInt(sc.nextLine());&lt;br /&gt;System.out.println(a);&lt;br /&gt;System.out.println(b);&lt;br /&gt;}&lt;br /&gt;}&lt;/p&gt;
&lt;p 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;&gt;
&lt;li&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; start=&quot;3&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;code&gt;2 3\n&lt;/code&gt; 이렇게 공백을 기준으로 입력받기 (nextLine()에서 trim() 처리해야 됨)&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;reasonml&quot;&gt;&lt;code&gt;import java.util.*;

class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int a = sc.nextInt();
        int b = Integer.parseInt(sc.nextLine().trim());
        // &quot;2 4\n&quot; 일경우 2는 a 변수에 할당되고 &quot; 4&quot; 가 nextLine() 에 들어가기때문에 공백처리
        System.out.println(a);
        System.out.println(b);
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;결론&lt;/h1&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;code&gt;Scanner&lt;/code&gt;의 next() 계열(nextInt(), nextDouble() 등)은 입력에서 delimiter 기준으로 토큰만 읽고, delimiter는 버퍼에 남긴다.&lt;/li&gt;
&lt;li&gt;그래서 &lt;code&gt;nextInt()&lt;/code&gt; 다음에 곧바로 &lt;code&gt;nextLine()&lt;/code&gt;을 쓰면, &lt;code&gt;nextInt()&lt;/code&gt; 호출 뒤에 남아 있던 줄 바꿈 문자(&lt;code&gt;\n&lt;/code&gt;)만 읽고 끝나버려서 빈 문자열을 반환한다.&lt;/li&gt;
&lt;li&gt;이때 빈 문자열을 &lt;code&gt;Integer.parseInt()&lt;/code&gt; 하면 NumberFormatException 발생!&lt;/li&gt;
&lt;li&gt;입력을 깔끔하게 다루려면 BufferedReader + StringTokenizer 로 하는 것이 버퍼 사이즈도 더 크고 빠름&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>자바</category>
      <category>InputMismatchException</category>
      <category>Java</category>
      <category>NumberFormatException</category>
      <category>Scanner</category>
      <category>입출력</category>
      <category>자바</category>
      <author>@ChoIng</author>
      <guid isPermaLink="true">https://t1-backend-choing.tistory.com/4</guid>
      <comments>https://t1-backend-choing.tistory.com/4#entry4comment</comments>
      <pubDate>Fri, 20 Jun 2025 21:48:32 +0900</pubDate>
    </item>
    <item>
      <title>[ 자료구조 ] 2. 배열 C/C++</title>
      <link>https://t1-backend-choing.tistory.com/3</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;쵸오오오오오오오오잉 입니다&lt;/p&gt;
&lt;h1&gt;배열&lt;/h1&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;대용량 자료의 처리&lt;/h2&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;h2 data-ke-size=&quot;size26&quot;&gt;배열 (Array)&lt;/h2&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;연속적으로 값을 저장하기 때문에 원하는 위치(Index)의 값을 즉각적으로 접근 가능(시간복잡도 O(1))&lt;/li&gt;
&lt;li&gt;배열에서 연속된 값을 보통 배열의 요소(Element)라고 부름&lt;/li&gt;
&lt;li&gt;배열은 위치(Index)와 요소(Elment)의 집합&lt;br /&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1536&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bhVCPR/btsOt28B0wP/16CqX05GNnJjKPx5IWxC7k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bhVCPR/btsOt28B0wP/16CqX05GNnJjKPx5IWxC7k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bhVCPR/btsOt28B0wP/16CqX05GNnJjKPx5IWxC7k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbhVCPR%2FbtsOt28B0wP%2F16CqX05GNnJjKPx5IWxC7k%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;1024&quot; height=&quot;1536&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;1536&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;배열 선언&lt;/h2&gt;
&lt;pre class=&quot;cpp&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;

using namespace std;

int main(){
    int arr[4] = {1,2,3,4};
    for(int i=0; i&amp;lt;sizeof(arr)/sizeof(int); i++){
        cout&amp;lt;&amp;lt; arr[i] &amp;lt;&amp;lt; endl;
    }
    return 0;
}&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;/li&gt;
&lt;li&gt;배열의 인덱스 번호는 0부터 시작&lt;/li&gt;
&lt;li&gt;sizeof 연산자를 통해 자료형의 크기 구함
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;변수 arr 은 int 가 4개인 배열이니까 16 크기를 가짐&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2차원 배열&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;code&gt;int [3][2]와&lt;/code&gt; 같은 형태의 2차원 배열 선언 가능&lt;/li&gt;
&lt;li&gt;열과 행으로 원하는 인덱스에 접근가능 ex) &lt;code&gt;arr [1][0]&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;형태는 2차원이지만 저장할 때 메모리 구조는 1차원 배열처럼 연속적으로 저장됨&lt;br /&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1610&quot; data-origin-height=&quot;1649&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cymx5f/btsOsxPw0rb/mYpK9DLegAxCQyK354fHp0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cymx5f/btsOsxPw0rb/mYpK9DLegAxCQyK354fHp0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cymx5f/btsOsxPw0rb/mYpK9DLegAxCQyK354fHp0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcymx5f%2FbtsOsxPw0rb%2FmYpK9DLegAxCQyK354fHp0%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;1610&quot; height=&quot;1649&quot; data-origin-width=&quot;1610&quot; data-origin-height=&quot;1649&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/li&gt;
&lt;/ul&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;C/C++ 에선 포인터 연산을 통해 다음 요소에 접근 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;cpp&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;

using namespace std;

int main(){
    int arr[4] = {1,2,3,4};
    cout &amp;lt;&amp;lt; &quot;arr size:&quot; &amp;lt;&amp;lt;  sizeof(arr) &amp;lt;&amp;lt; endl;
    cout &amp;lt;&amp;lt; &quot;&amp;amp; arr size:&quot; &amp;lt;&amp;lt;  sizeof(&amp;amp;arr) &amp;lt;&amp;lt; endl;
    cout &amp;lt;&amp;lt; &quot;&amp;amp; arr :&quot;  &amp;lt;&amp;lt; &amp;amp;arr &amp;lt;&amp;lt; endl;
    cout &amp;lt;&amp;lt; &quot;* arr :&quot; &amp;lt;&amp;lt; *arr &amp;lt;&amp;lt; endl;
    cout &amp;lt;&amp;lt; &quot;*(arr+1) : &quot; &amp;lt;&amp;lt; *(arr+1) &amp;lt;&amp;lt; endl;
    cout &amp;lt;&amp;lt; &quot;&amp;amp;(*(arr+1)) : &quot; &amp;lt;&amp;lt; &amp;amp;(*(arr+1)) &amp;lt;&amp;lt; endl;
    return 0;
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;출력 결과&lt;/h3&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;arr size:16
&amp;amp; arr size:8
&amp;amp; arr :0x16fbb6cd0
* arr :1
*(arr+1) : 2
&amp;amp;(*(arr+1)) : 0x16fbb6cd4&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;&amp;amp;arr 은 배열의 첫 번째 요소를 가르키는 주소 값
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;해당 값은 주소값 즉 포인트변수기 때문에 8바이트 (32비트 컴퓨터라면 4바이트라고 나옴)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;* 포인터를 통해 배열애서 원하는 위치의 요소에 접근 가능&lt;/li&gt;
&lt;li&gt;*arr 은 첫번째 요소, *(arr+1) 은 두 번째 요소에 값을 접근할 수 있음&lt;/li&gt;
&lt;li&gt;&amp;amp;(*(arr+1)) 을 접근할 시 두 번째 요소의 주소값을 가져오게 됨
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;실제로 첫 번째 요소의 주소값은.. 6cd0이었는데 두 번째 요소는.. 6cd4로 배열의 타입만큼 연속적으로 이루어진 메모리 구조라는 것을 알 수 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;배열에 삽입과 삭제 연산 구현해 보기&lt;/h2&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;삽입 삭제 연산 모두 시간복잡도가 O(n)으로 삽입 삭제하려는 값을 업데이트하고 그 뒤의 값들은 하나하나 이동시켜야 됨&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;배열 선언&lt;/h3&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;int arr[1000]={0,};
int length = sizeof(arr)/sizeof(arr[0]);
int cur = 0;&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;배열 초기화 및 현재 배열의 사이즈를 가리키는 cur 변수 선언&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;삽입 연산&lt;/h3&gt;
&lt;pre class=&quot;pgsql&quot;&gt;&lt;code&gt;void insert_array(int value, int index) {
    if (cur == 1000) {
        cout &amp;lt;&amp;lt; &quot;더이상 추가할 수 없습니다.&quot; &amp;lt;&amp;lt; endl;
        return;
    }
    if (index &amp;lt; 0 || index &amp;gt; cur) {
        cout &amp;lt;&amp;lt; &quot;유효하지 않은 인덱스입니다.&quot; &amp;lt;&amp;lt; endl;
        return;
    }
    for(int i = cur; i &amp;gt; index; i--) {
        arr[i] = arr[i - 1];
    }
    arr[index] = value;
    cur++;
}&lt;/code&gt;&lt;/pre&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;인덱스 유효성 검사&lt;/li&gt;
&lt;li&gt;배열의 현재 사이즈 cur에서 시작하여 삽입하려는 index 위치까지 반복문을 통해 한 칸식 뒤로 이동&lt;/li&gt;
&lt;li&gt;삽입하려는 위치 index에 value 값 대입&lt;/li&gt;
&lt;li&gt;값이 추가됐으므로 배열의 사이즈 추가 (cur++)&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;삭제 연산&lt;/h3&gt;
&lt;pre class=&quot;cpp&quot;&gt;&lt;code&gt;void delete_array(int index) {
    if (cur == 0) {
        cout &amp;lt;&amp;lt; &quot;삭제할 수 없습니다.&quot; &amp;lt;&amp;lt; endl;
        return;
    }
    if (index &amp;lt; 0 || index &amp;gt;= cur) {
        cout &amp;lt;&amp;lt; &quot;유효하지 않은 인덱스입니다.&quot; &amp;lt;&amp;lt; endl;
        return;
    }
    for(int i = index; i &amp;lt; cur - 1; i++) {
        arr[i] = arr[i + 1];
    }
    cur--;
}&lt;/code&gt;&lt;/pre&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;인덱스 유효성 검사&lt;/li&gt;
&lt;li&gt;삭제하려는 위치 index에서 시작하여 배열의 현재사이즈 cur까지 반복문을 통해 한 칸씩 앞으로 당김&lt;/li&gt;
&lt;li&gt;값이 삭제됐으므로 배열의 사이즈 감소 (cur--)&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;전체코드&lt;/h3&gt;
&lt;pre class=&quot;cpp&quot;&gt;&lt;code&gt;#include &amp;lt;iostream&amp;gt;

using namespace std;
int arr[1000]={0,};
int length = sizeof(arr)/sizeof(arr[0]);
int cur = 0;

void print_arr(){
    for(int i=0; i&amp;lt;cur; i++){
        cout &amp;lt;&amp;lt; arr[i] &amp;lt;&amp;lt; &quot;\t&quot;;
    }
    cout &amp;lt;&amp;lt; endl;
}
void insert_array(int value, int index) {
    if (cur == 1000) {
        cout &amp;lt;&amp;lt; &quot;더이상 추가할 수 없습니다.&quot; &amp;lt;&amp;lt; endl;
        return;
    }
    if (index &amp;lt; 0 || index &amp;gt; cur) {
        cout &amp;lt;&amp;lt; &quot;유효하지 않은 인덱스입니다.&quot; &amp;lt;&amp;lt; endl;
        return;
    }
    for(int i = cur; i &amp;gt; index; i--) {
        arr[i] = arr[i - 1];
    }
    arr[index] = value;
    cur++;
}

void delete_array(int index) {
    if (cur == 0) {
        cout &amp;lt;&amp;lt; &quot;삭제할 수 없습니다.&quot; &amp;lt;&amp;lt; endl;
        return;
    }
    if (index &amp;lt; 0 || index &amp;gt;= cur) {
        cout &amp;lt;&amp;lt; &quot;유효하지 않은 인덱스입니다.&quot; &amp;lt;&amp;lt; endl;
        return;
    }
    for(int i = index; i &amp;lt; cur - 1; i++) {
        arr[i] = arr[i + 1];
    }
    cur--;
}
int main(){
    insert_array(1,0);
    insert_array(2,0);
    insert_array(3,0);
    insert_array(10,2);
    insert_array(999,cur);
    delete_array(0);
    delete_array(cur);
    print_arr();
    return 0;
}&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;이러한 방식은 실제 ArrayList와 유사하게 동작함&lt;/li&gt;
&lt;li&gt;현재 배열의 크기가 꽉 찰경우 더 이상 추가를 못하지만 배열의 크기를 늘리고 기존값을 복사하는 방식으로 구현 가능&lt;/li&gt;
&lt;li&gt;삭제나 삽입 연산 시 해당 위치 이후의 모든 원소들을 이동시켜야 하므로 시간복잡도 O(n)&lt;/li&gt;
&lt;li&gt;배열은 연속적인 메모리 주소로 할당되기 때문에 원하는 위치에 바로 접근 가능해서 시간복잡도 O(1)&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>CS/자료구조</category>
      <category>2차원 배열</category>
      <category>c++</category>
      <category>C언어</category>
      <category>메모리 구조</category>
      <category>배열</category>
      <category>배열 코드 구현</category>
      <category>자료구조</category>
      <author>@ChoIng</author>
      <guid isPermaLink="true">https://t1-backend-choing.tistory.com/3</guid>
      <comments>https://t1-backend-choing.tistory.com/3#entry3comment</comments>
      <pubDate>Mon, 9 Jun 2025 02:38:46 +0900</pubDate>
    </item>
    <item>
      <title>[ 자료구조 ] 1. 자료구조와 알고리즘</title>
      <link>https://t1-backend-choing.tistory.com/2</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;쵸오오오오오잉 입니다&lt;/p&gt;
&lt;h1&gt;자료구조란?&lt;/h1&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;h1&gt;자료구조 분류&lt;/h1&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&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;/li&gt;
&lt;li&gt;선형 자료구조 : 각 자료사이의 앞뒤 관계가 1:1 인 선형적인 구조
&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;li&gt;배열&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&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;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;알고리즘이란?&lt;/h1&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;주어진 상황에따라 적절한 &lt;b&gt;자료구조&lt;/b&gt; 를 선택하여 효율적인 &lt;b&gt;알고리즘&lt;/b&gt; 을 설계하는것&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;알고리즘의 조건
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;입력 : 0개 이상의 입력 존재&lt;/li&gt;
&lt;li&gt;출력 : 1개 이상의 출력 존재&lt;/li&gt;
&lt;li&gt;명백성 : 각 명령어의 의미는 모호하지 않고 명확&lt;/li&gt;
&lt;li&gt;유한성 : 한정된 수 뒤에는 반드시 종료되야함 (무한반복x)&lt;/li&gt;
&lt;li&gt;유효성 : 실행 가능한 연산이여야함&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;알고리즘 성능 분석&lt;/h1&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;효율적인 알고리즘이란?&lt;/h3&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;h2 data-ke-size=&quot;size26&quot;&gt;공간복잡도 (Space Complexity)&lt;/h2&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;h2 data-ke-size=&quot;size26&quot;&gt;시간복잡도 (Time Complexity)&lt;/h2&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;b&gt;1초에 1억번 연산&lt;/b&gt; 을 기준으로 측정&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;빅오 표기법&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;입력 크기 n 이 커질때 가장 큰 영향을 주는 항만 남겨서 시간 복잡도를 표현하는 방법&lt;/li&gt;
&lt;li&gt;상수,낮은 차수,계수는 생략&lt;/li&gt;
&lt;li&gt;함수의 상한 즉 최악의 경우&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;$O(3n^2+16n+1) =&amp;gt; O(n^2)$&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;/li&gt;
&lt;li&gt;가장 차수가 높은 3n^2 에서 계수를 생략하여 O(n^2)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bzGiRe/btsObrn56f9/1ISC35ngdVQycAxNVQGoC0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bzGiRe/btsObrn56f9/1ISC35ngdVQycAxNVQGoC0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bzGiRe/btsObrn56f9/1ISC35ngdVQycAxNVQGoC0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbzGiRe%2FbtsObrn56f9%2F1ISC35ngdVQycAxNVQGoC0%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; data-origin-width=&quot;0&quot; data-origin-height=&quot;0&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;n^3 n^2 과 같이 차수가 크면 n 의 크기가 조금만 커져도 기하급수적으로 상승그외 표기법&lt;/li&gt;
&lt;li&gt;빅 오메가 표기법 : 함수의 하한을 표시, 최선의 경우&lt;/li&gt;
&lt;li&gt;빅 세타 표기법 : 동일 함수로 상한과 하한을 만들수 있는 경우의 수&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>CS/자료구조</category>
      <author>@ChoIng</author>
      <guid isPermaLink="true">https://t1-backend-choing.tistory.com/2</guid>
      <comments>https://t1-backend-choing.tistory.com/2#entry2comment</comments>
      <pubDate>Sat, 24 May 2025 02:18:10 +0900</pubDate>
    </item>
  </channel>
</rss>