<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>VIVA LA VIDA</title>
    <link>https://hyeromon.tistory.com/</link>
    <description>조금씩 나아가는  </description>
    <language>ko</language>
    <pubDate>Sat, 23 May 2026 08:30:06 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>해로몬</managingEditor>
    <image>
      <title>VIVA LA VIDA</title>
      <url>https://tistory1.daumcdn.net/tistory/6753404/attach/18c153e7e12049b399d8e48ecd71c358</url>
      <link>https://hyeromon.tistory.com</link>
    </image>
    <item>
      <title>MyBatis vs JPA</title>
      <link>https://hyeromon.tistory.com/110</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;MyBatis&lt;/b&gt;&lt;/h2&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;XML이나 annotaion을 통하여 &lt;b&gt;SQL문을 작성&lt;/b&gt;하고 객체들을 연결시키는 프레임워크이다.&lt;br /&gt;&lt;b&gt;&lt;/b&gt;&lt;/blockquote&gt;
&lt;pre id=&quot;code_1750933184740&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// ✅ MyBatis 예시 (XML Mapper)
&amp;lt;select id=&quot;findUserById&quot; parameterType=&quot;int&quot; resultType=&quot;User&quot;&amp;gt;
    SELECT * FROM users WHERE id = #{id}
&amp;lt;/select&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-end=&quot;700&quot; data-start=&quot;684&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;MyBatis 특징&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;779&quot; data-start=&quot;701&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;722&quot; data-start=&quot;701&quot;&gt;SQL을 &lt;b&gt;개발자가 직접&lt;/b&gt; 작성&lt;/li&gt;
&lt;li data-end=&quot;738&quot; data-start=&quot;723&quot;&gt;복잡한 쿼리 로직에 유리&lt;/li&gt;
&lt;li data-end=&quot;759&quot; data-start=&quot;739&quot;&gt;XML 또는 어노테이션 기반 매핑&lt;/li&gt;
&lt;li data-end=&quot;779&quot; data-start=&quot;760&quot;&gt;DB에 최적화된 쿼리 튜닝 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;787&quot; data-start=&quot;781&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;장점&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;891&quot; data-start=&quot;788&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;834&quot; data-start=&quot;788&quot;&gt;복잡한 SQL, JOIN, 서브쿼리, Stored Procedure 활용에 강함&lt;/li&gt;
&lt;li data-end=&quot;866&quot; data-start=&quot;835&quot;&gt;SQL이 명시적이라 &lt;b&gt;로직 추적 및 디버깅 용이&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;891&quot; data-start=&quot;867&quot;&gt;특정 DB에 맞는 최적화 쿼리 작성 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;899&quot; data-start=&quot;893&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;단점&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;960&quot; data-start=&quot;900&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;916&quot; data-start=&quot;900&quot;&gt;SQL 작성 및 관리 부담&lt;/li&gt;
&lt;li data-end=&quot;943&quot; data-start=&quot;917&quot;&gt;코드와 SQL이 분리돼 있어 유지보수 어려움&lt;/li&gt;
&lt;li data-end=&quot;960&quot; data-start=&quot;944&quot;&gt;객체 지향적 개발에서 한계&lt;/li&gt;
&lt;/ul&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;JPA&lt;/b&gt;&lt;/h2&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;Java 진영에서 ORM(Object-Relational Mapping) 기술 표준으로 사용하는 인터페이스 모음&lt;/blockquote&gt;
&lt;pre id=&quot;code_1750933197168&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// ✅ JPA 예시
User user = userRepository.findById(1L).orElse(null);&lt;/code&gt;&lt;/pre&gt;
&lt;h4 data-end=&quot;979&quot; data-start=&quot;967&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;JPA 특징&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1077&quot; data-start=&quot;980&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1003&quot; data-start=&quot;980&quot;&gt;&lt;b&gt;객체 중심&lt;/b&gt;으로 데이터베이스 접근&lt;/li&gt;
&lt;li data-end=&quot;1021&quot; data-start=&quot;1004&quot;&gt;SQL을 자동 생성 및 실행&lt;/li&gt;
&lt;li data-end=&quot;1041&quot; data-start=&quot;1022&quot;&gt;ORM을 통한 객체-테이블 매핑&lt;/li&gt;
&lt;li data-end=&quot;1077&quot; data-start=&quot;1042&quot;&gt;트랜잭션, 캐시, 지연로딩, 더티 체킹 등 풍부한 기능 제공&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1085&quot; data-start=&quot;1079&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;장점&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1172&quot; data-start=&quot;1086&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1107&quot; data-start=&quot;1086&quot;&gt;생산성 높음 (SQL 작성 최소화)&lt;/li&gt;
&lt;li data-end=&quot;1132&quot; data-start=&quot;1108&quot;&gt;유지보수 쉬움 (도메인 중심 개발 가능)&lt;/li&gt;
&lt;li data-end=&quot;1147&quot; data-start=&quot;1133&quot;&gt;DB 벤더 독립성 확보&lt;/li&gt;
&lt;li data-end=&quot;1172&quot; data-start=&quot;1148&quot;&gt;1차 캐시, 지연로딩 등으로 성능 최적화&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1180&quot; data-start=&quot;1174&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;단점&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1259&quot; data-start=&quot;1181&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1209&quot; data-start=&quot;1181&quot;&gt;복잡한 SQL 튜닝 어렵거나 비효율적일 수 있음&lt;/li&gt;
&lt;li data-end=&quot;1227&quot; data-start=&quot;1210&quot;&gt;JPA 동작 원리 학습 필요&lt;/li&gt;
&lt;li data-end=&quot;1259&quot; data-start=&quot;1228&quot;&gt;잘못 쓰면 N+1 문제, 예상치 못한 쿼리 발생 가능&lt;/li&gt;
&lt;/ul&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;&lt;b&gt;상황에 따른 프레임워크 추천&lt;/b&gt;&lt;/h4&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;&lt;i&gt; 상황/요구사항&amp;nbsp;&lt;/i&gt;&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;&lt;i&gt; 추천 프레임워크 &lt;/i&gt;&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CRUD 중심, 생산성 우선&lt;/td&gt;
&lt;td&gt;JPA&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;도메인 모델 중심 아키텍처 필요&lt;/td&gt;
&lt;td&gt;JPA&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;복잡한 SQL, 다이나믹 쿼리&lt;/td&gt;
&lt;td&gt;MyBatis&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;특정 DB에 최적화 필요&lt;/td&gt;
&lt;td&gt;MyBatis&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;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&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;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;931&quot; data-start=&quot;908&quot;&gt;&lt;b&gt;초기 개발 속도 중요 &amp;rarr; JPA&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;960&quot; data-start=&quot;932&quot;&gt;&lt;b&gt;SQL 주도 개발 선호 &amp;rarr; MyBatis&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;989&quot; data-start=&quot;961&quot;&gt;&lt;b&gt;복잡한 쿼리 비중 높음 &amp;rarr; MyBatis&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;1022&quot; data-start=&quot;990&quot;&gt;&lt;b&gt;도메인 중심, 객체지향 아키텍처 중요 &amp;rarr; JPA&lt;/b&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;style5&quot; /&gt;
&lt;h2 data-end=&quot;108&quot; data-start=&quot;82&quot; data-ke-size=&quot;size26&quot;&gt;  MyBatis vs JPA 핵심 정리&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;298&quot; data-start=&quot;110&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;200&quot; data-start=&quot;110&quot;&gt;&lt;b&gt;MyBatis&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;200&quot; data-start=&quot;126&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;151&quot; data-start=&quot;126&quot;&gt;SQL을 직접 작성하고 세밀하게 제어 가능&lt;/li&gt;
&lt;li data-end=&quot;177&quot; data-start=&quot;154&quot;&gt;복잡한 쿼리나 DB 성능 최적화에 강점&lt;/li&gt;
&lt;li data-end=&quot;200&quot; data-start=&quot;180&quot;&gt;SQL 관리와 유지보수 부담 존재&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;298&quot; data-start=&quot;202&quot;&gt;&lt;b&gt;JPA&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;298&quot; data-start=&quot;214&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;233&quot; data-start=&quot;214&quot;&gt;객체 지향적 개발과 생산성 향상&lt;/li&gt;
&lt;li data-end=&quot;262&quot; data-start=&quot;236&quot;&gt;SQL 자동 생성, 코드와 DB 매핑 자동화&lt;/li&gt;
&lt;li data-end=&quot;298&quot; data-start=&quot;265&quot;&gt;내부 동작 원리 숙지 필요, 예상치 못한 쿼리 발생 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;413&quot; data-start=&quot;300&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;  결론적으로, 프로젝트 특성에 맞는 선택이 중요합니다.&lt;/b&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;단순한 CRUD 위주라면 JPA가 생산성을 높여주고,&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;복잡한 쿼리나 DB 최적화가 필요한 경우 MyBatis가 더 적합합니다.&lt;/span&gt;&lt;/p&gt;</description>
      <category>개발자 면접 노트</category>
      <author>해로몬</author>
      <guid isPermaLink="true">https://hyeromon.tistory.com/110</guid>
      <comments>https://hyeromon.tistory.com/110#entry110comment</comments>
      <pubDate>Thu, 26 Jun 2025 19:20:23 +0900</pubDate>
    </item>
    <item>
      <title>RDBMS에서 정규화란?</title>
      <link>https://hyeromon.tistory.com/109</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;정규화란?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;관계형 데이터베이스에서&lt;b&gt;&lt;i&gt;&lt;u&gt; 데이터 중복을 최소화&lt;/u&gt;&lt;/i&gt;&lt;/b&gt;하고, &lt;b&gt;&lt;u&gt;데이터 구조를 체계적으로 설계&lt;/u&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;[정규화의 목표]&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;삽입(Insert), 수정(Update), 삭제(Delete) 이상(Anomaly) 방지&lt;/li&gt;
&lt;li&gt;데이터 구조의 일관성 확보&lt;/li&gt;
&lt;/ul&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;&lt;b&gt;제1정규형 (1NF)&lt;/b&gt;&lt;/h4&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: #f6e199;&quot;&gt;모든 속성이 &lt;b&gt;원자값&lt;/b&gt;을 가져야 한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;중첩 데이터, 반복 그룹 제거&lt;/li&gt;
&lt;/ul&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 38px;&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;height: 17px;&quot;&gt;학생 ID&lt;/td&gt;
&lt;td style=&quot;height: 17px;&quot;&gt;이름&lt;/td&gt;
&lt;td style=&quot;height: 17px;&quot;&gt;연락처&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot; data-end=&quot;464&quot; data-start=&quot;425&quot;&gt;
&lt;td style=&quot;height: 21px;&quot; data-col-size=&quot;sm&quot; data-end=&quot;434&quot; data-start=&quot;425&quot;&gt;1&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot; data-end=&quot;440&quot; data-start=&quot;434&quot; data-col-size=&quot;sm&quot;&gt;홍길동&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot; data-end=&quot;464&quot; data-start=&quot;440&quot; data-col-size=&quot;sm&quot;&gt;010-1234, 010-5678&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;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;&lt;b&gt;&amp;rarr; 1NF 적용 후 &lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;학생ID&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;이름&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;연락처&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;홍길동&lt;/td&gt;
&lt;td&gt;010-1234&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;홍길동&lt;/td&gt;
&lt;td&gt;010-5678&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;제2정규형 (2NF)&lt;/b&gt;&lt;/h4&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: #f6e199;&quot;&gt;&lt;b&gt;부분 함수 종속 제거&lt;/b&gt;&lt;/span&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;| 학번 | 과목코드 | 교수명|성적 |&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;rarr;성적&lt;/li&gt;
&lt;li&gt;과목코드 &amp;rarr;교수명(부분 종속)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;905&quot; data-start=&quot;849&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;&lt;b&gt;&amp;rarr; 2NF 적용 후 분리&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;b&gt;학생-성적 테이블&lt;/b&gt;&lt;br /&gt;| 학번 | 과목코드 | 성적 |&lt;/p&gt;
&lt;p data-end=&quot;936&quot; data-start=&quot;907&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;과목 테이블&lt;/b&gt;&lt;br /&gt;| 과목코드 | 교수명 |&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style8&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;제3정규형 (3NF)&lt;/b&gt;&lt;/h4&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: #f6e199;&quot;&gt;이행적 함수 종속 제거&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;기본키가 아닌 다른 속성에 종속되는 속성을 분리한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1089&quot; data-start=&quot;1057&quot; data-ke-size=&quot;size16&quot;&gt;| 직원ID | 부서ID | 부서명 |&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1134&quot; data-start=&quot;1091&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1106&quot; data-start=&quot;1091&quot;&gt;직원ID &amp;rarr; 부서ID&lt;/li&gt;
&lt;li data-end=&quot;1134&quot; data-start=&quot;1107&quot;&gt;부서ID &amp;rarr; 부서명 (&lt;b&gt;이행적 종속&lt;/b&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1186&quot; data-start=&quot;1136&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;rarr; 3NF 적용 후 분리&lt;/b&gt;&lt;br /&gt;&lt;b&gt;직원 테이블&lt;/b&gt;&lt;br /&gt;| 직원ID | 부서ID |&lt;/p&gt;
&lt;p data-end=&quot;1217&quot; data-start=&quot;1188&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;부서 테이블&lt;/b&gt;&lt;br /&gt;| 부서ID | 부서명 |&lt;/p&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;BCNF&lt;/b&gt;&lt;/h4&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: #f6e199;&quot;&gt;모든 결정자가 후보키&lt;/span&gt;일 것&lt;/li&gt;
&lt;li&gt;(예시) 복합키가 여러 개 존재하거나 후보키가 여러 개인 경우 추가 분해 필요하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 73px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt; &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;학번(StudentID)&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt; &lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt; &lt;span style=&quot;color: #333333; text-align: start;&quot;&gt;강의실(Room)&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt; &lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt; 교수(Professor) &lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;1001&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;101호&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;김교수&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;1002&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;102호&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;이교수&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;1003&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;101호&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;김교수&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;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&amp;rarr; BCNF 적용 후 분리&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt; 학번(StudentID) &lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt; &amp;nbsp;강의실(Room) &lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1001&lt;/td&gt;
&lt;td&gt;101호&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1002&lt;/td&gt;
&lt;td&gt;102호&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1003&lt;/td&gt;
&lt;td&gt;101호&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;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt; 강의실(Room) &lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt; 교수(Professor) &lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;101호&lt;/td&gt;
&lt;td&gt;김교수&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;102호&lt;/td&gt;
&lt;td&gt;이교수&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;제4정규형&amp;nbsp;&lt;/b&gt;&lt;b&gt;(4NF)&lt;/b&gt;&lt;/h4&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style7&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;제5정규형 (5NF)&lt;/b&gt;&lt;/h4&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;정규화의 장점과 단점&lt;/b&gt;&lt;/h3&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;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;753&quot; data-start=&quot;740&quot;&gt;데이터 중복 감소&lt;/li&gt;
&lt;li data-end=&quot;768&quot; data-start=&quot;754&quot;&gt;데이터 무결성 향상&lt;/li&gt;
&lt;li data-end=&quot;787&quot; data-start=&quot;769&quot;&gt;테이블 구조의 논리적 설계&lt;/li&gt;
&lt;/ul&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;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;837&quot; data-start=&quot;801&quot;&gt;테이블 수 증가 &amp;rarr; JOIN 연산 많아져 성능 저하 가능성&lt;/li&gt;
&lt;li data-end=&quot;892&quot; data-start=&quot;838&quot;&gt;시스템 규모나 상황에 따라 &lt;b&gt;반정규화(Denormalization)&lt;/b&gt; 를 고려하기도 함&lt;/li&gt;
&lt;/ul&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;size18&quot;&gt;따라서 &lt;span style=&quot;font-size: 1.12em; letter-spacing: 0px;&quot;&gt;&lt;b&gt;정규화&lt;/b&gt;는 &lt;u&gt;안정적이고 일관성 있는 데이터베이스를 구축&lt;/u&gt;하고, &lt;u&gt;시스템의 확장성과 유지보수를 용이&lt;/u&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;</description>
      <category>개발자 면접 노트</category>
      <author>해로몬</author>
      <guid isPermaLink="true">https://hyeromon.tistory.com/109</guid>
      <comments>https://hyeromon.tistory.com/109#entry109comment</comments>
      <pubDate>Thu, 26 Jun 2025 19:03:22 +0900</pubDate>
    </item>
    <item>
      <title>RESTful API 설계의 핵심 원칙</title>
      <link>https://hyeromon.tistory.com/108</link>
      <description>&lt;h3 data-end=&quot;165&quot; data-start=&quot;146&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;RESTful API란 무엇인가&lt;/b&gt;&lt;/h3&gt;
&lt;p data-end=&quot;318&quot; data-start=&quot;167&quot; data-ke-size=&quot;size16&quot;&gt;RESTful API는 **Representational State Transfer(표현 상태 전달)**라는 아키텍처 스타일을 따르는 웹 API 설계 방식이다.&lt;br /&gt;주로 HTTP 프로토콜을 기반으로 하며, **자원(Resource)**을 중심으로 데이터를 주고받는다.&lt;/p&gt;
&lt;p data-end=&quot;362&quot; data-start=&quot;320&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;h4 data-end=&quot;390&quot; data-start=&quot;369&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;RESTful API의 핵심 개념&lt;/b&gt;&lt;/h4&gt;
&lt;p data-end=&quot;409&quot; data-start=&quot;392&quot; data-ke-size=&quot;size16&quot;&gt;REST의 철학은 다음과 같다:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;573&quot; data-start=&quot;411&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;479&quot; data-start=&quot;411&quot;&gt;&lt;b&gt;자원의 표현(Representation)을 전송(Transfer)&lt;/b&gt; 하여, 클라이언트와 서버가 상태를 주고받는다.&lt;/li&gt;
&lt;li data-end=&quot;520&quot; data-start=&quot;480&quot;&gt;서버는 &lt;b&gt;상태를 저장하지 않는 Stateless 구조&lt;/b&gt;를 따른다.&lt;/li&gt;
&lt;li data-end=&quot;573&quot; data-start=&quot;521&quot;&gt;&lt;b&gt;HTTP URI로 자원을 식별&lt;/b&gt;하고, &lt;b&gt;HTTP 메서드&lt;/b&gt;를 통해 행위를 정의한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;614&quot; data-start=&quot;575&quot; data-ke-size=&quot;size16&quot;&gt;이러한 원칙을 따르는 API를 &lt;b&gt;RESTful API&lt;/b&gt;라고 부른다.&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-end=&quot;646&quot; data-start=&quot;621&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;RESTful API의 6가지 핵심 원칙&lt;/b&gt;&lt;/h4&gt;
&lt;p data-end=&quot;665&quot; data-start=&quot;648&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;1. 자원 지향 아키텍처&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;767&quot; data-start=&quot;667&quot; data-ke-size=&quot;size16&quot;&gt;REST API는 &lt;b&gt;모든 것을 자원(Resource) 중심&lt;/b&gt;으로 설계한다. 각 자원은 고유한 &lt;b&gt;URI(Uniform Resource Identifier)&lt;/b&gt; 로 식별되며, URL을 통해 자원의 위치를 명확히 표현해야 한다.&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 data-end=&quot;749&quot; data-start=&quot;676&quot;&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;749&quot; data-start=&quot;695&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;749&quot; data-start=&quot;726&quot;&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;URL 설계 규칙&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;989&quot; data-start=&quot;331&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;467&quot; data-start=&quot;331&quot;&gt;&lt;b&gt;명사 사용 및 복수형 표현&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;467&quot; data-start=&quot;354&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;383&quot; data-start=&quot;354&quot;&gt;자원 이름은 명사로 표현하고, 복수형을 사용한다.&lt;/li&gt;
&lt;li data-end=&quot;467&quot; data-start=&quot;386&quot;&gt;예시:&lt;br /&gt;/users &amp;rarr; 사용자 목록&lt;br /&gt;/products &amp;rarr; 상품 목록&lt;br /&gt;/orders &amp;rarr; 주문 목록&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;668&quot; data-start=&quot;469&quot;&gt;&lt;b&gt;HTTP 메서드로 행위 구분 (CRUD 매핑)&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;668&quot; data-start=&quot;503&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;531&quot; data-start=&quot;503&quot;&gt;GET /users &amp;rarr; 사용자 목록 조회&lt;/li&gt;
&lt;li data-end=&quot;560&quot; data-start=&quot;534&quot;&gt;POST /users &amp;rarr; 사용자 생성&lt;/li&gt;
&lt;li data-end=&quot;596&quot; data-start=&quot;563&quot;&gt;GET /users/{id} &amp;rarr; 특정 사용자 조회&lt;/li&gt;
&lt;li data-end=&quot;632&quot; data-start=&quot;599&quot;&gt;PUT /users/{id} &amp;rarr; 사용자 정보 수정&lt;/li&gt;
&lt;li data-end=&quot;668&quot; data-start=&quot;635&quot;&gt;DELETE /users/{id} &amp;rarr; 사용자 삭제&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;803&quot; data-start=&quot;670&quot;&gt;&lt;b&gt;경로 변수 최소화 및 계층 구조 표현&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;803&quot; data-start=&quot;699&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;721&quot; data-start=&quot;699&quot;&gt;필요한 최소한의 경로 변수만 사용&lt;/li&gt;
&lt;li data-end=&quot;743&quot; data-start=&quot;724&quot;&gt;계층적 관계는 URL로 표현&lt;/li&gt;
&lt;li data-end=&quot;803&quot; data-start=&quot;746&quot;&gt;예시:&lt;br /&gt;/users/{userId}/orders &amp;rarr; 특정 사용자의 주문 목록 조회&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;910&quot; data-start=&quot;805&quot;&gt;&lt;b&gt;쿼리 매개변수로 필터링, 정렬, 페이징 지원&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;910&quot; data-start=&quot;838&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;910&quot; data-start=&quot;838&quot;&gt;예시:&lt;br /&gt;/products?category=electronics&amp;amp;sort=price&amp;amp;page=2&amp;amp;size=10&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;989&quot; data-start=&quot;912&quot;&gt;&lt;b&gt;버전 관리 필수&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;989&quot; data-start=&quot;929&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;957&quot; data-start=&quot;929&quot;&gt;API의 안정성을 위해 버전을 URI에 명시&lt;/li&gt;
&lt;li data-end=&quot;989&quot; data-start=&quot;960&quot;&gt;예시:&lt;br /&gt;/api/v1/users&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;933&quot; data-start=&quot;910&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;2. 무상태성 (Stateless)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;1012&quot; data-start=&quot;935&quot; data-ke-size=&quot;size16&quot;&gt;서버는 클라이언트의 상태 정보를 저장하지 않는다.&lt;br /&gt;각 요청은 완전 독립적으로 동작하며, 필요한 모든 정보는 요청에 포함되어야 한다.&lt;/p&gt;
&lt;p data-end=&quot;1021&quot; data-start=&quot;1014&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;1060&quot; data-start=&quot;1022&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1033&quot; data-start=&quot;1022&quot;&gt;서버 확장성 향상&lt;/li&gt;
&lt;li data-end=&quot;1047&quot; data-start=&quot;1034&quot;&gt;요청 간 간섭 최소화&lt;/li&gt;
&lt;li data-end=&quot;1060&quot; data-start=&quot;1048&quot;&gt;시스템 복잡도 감소&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1091&quot; data-start=&quot;1067&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;3. 캐시 가능 (Cacheable)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;1210&quot; data-start=&quot;1157&quot; data-ke-size=&quot;size16&quot;&gt;캐시 사용은 네트워크 지연을 줄이고, 서버의 부하를 경감시키며, 전반적인 성능을 향상시킨다. 따라서 API 응답에는 캐싱 정책을 명시해야 하고, 클라이언트가 응답을 적절히 캐시할 수 있도록 해야한다.&lt;/p&gt;
&lt;p data-end=&quot;1240&quot; data-start=&quot;1217&quot; data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1240&quot; data-start=&quot;1217&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;4. 클라이언트 - 서버 구조 분리&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;1348&quot; data-start=&quot;1321&quot; data-ke-size=&quot;size16&quot;&gt;REST는 클라이언트와 서버가 독립적으로 동작할 수 있도록 분리된 구조를 강조한다.&lt;/p&gt;
&lt;p data-end=&quot;1348&quot; data-start=&quot;1321&quot; data-ke-size=&quot;size16&quot;&gt;각 부분의 독립적인 진화를 가능하게 하여, 서버의 기능 개선이 클라이언트의 업데이트 없이 이루어질 수 있도록 지원한다.&lt;/p&gt;
&lt;p data-end=&quot;1348&quot; data-start=&quot;1321&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1386&quot; data-start=&quot;1355&quot; data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;5. 계층화 시스템 (Layered System)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-end=&quot;1488&quot; data-start=&quot;1388&quot; data-ke-size=&quot;size16&quot;&gt;클라이언트는 요청이 직접 서버에 도달하는지, 중간에 프록시나 게이트웨이가 있는지 알 수 없다.&lt;br /&gt;이 계층 구조 덕분에 &lt;u&gt;로드 밸런싱, 보안, 암호화 등을 투명하게 적용&lt;/u&gt;할 수 있다.&lt;/p&gt;
&lt;p data-end=&quot;1488&quot; data-start=&quot;1388&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;1518&quot; data-start=&quot;1495&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;6. 코드 온 디맨드 (선택 사항)&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;1614&quot; data-start=&quot;1520&quot; data-ke-size=&quot;size16&quot;&gt;서버가 실행 가능한 코드를 클라이언트에 전송하여 클라이언트의 기능을 일시적으로 확장할 수 있음을 의미한다. 이 원칙은 클라이언트의 유연성을 높이지만, 필수는 아니다.&lt;/p&gt;
&lt;p data-end=&quot;667&quot; data-start=&quot;622&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;</description>
      <category>개발자 면접 노트</category>
      <author>해로몬</author>
      <guid isPermaLink="true">https://hyeromon.tistory.com/108</guid>
      <comments>https://hyeromon.tistory.com/108#entry108comment</comments>
      <pubDate>Thu, 26 Jun 2025 18:38:12 +0900</pubDate>
    </item>
    <item>
      <title>HTTP 상태코드</title>
      <link>https://hyeromon.tistory.com/107</link>
      <description>&lt;h3 data-end=&quot;420&quot; data-start=&quot;406&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;HTTP 상태 코드란?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-end=&quot;533&quot; data-start=&quot;422&quot; data-ke-size=&quot;size16&quot;&gt;HTTP 상태 코드는 &lt;b&gt;클라이언트의 요청에 대한 서버의 응답 상태&lt;/b&gt;를 나타내는 숫자 코드이다.&lt;br /&gt;총 5가지 범주(1xx~5xx)로 나뉘며, 각 코드의 앞자리 숫자가 의미하는 범주는 다음과 같다.&lt;/p&gt;
&lt;hr data-end=&quot;538&quot; data-start=&quot;535&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h4 data-end=&quot;554&quot; data-start=&quot;540&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;810&quot; data-start=&quot;556&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;범위&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;이름&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;설명&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;651&quot; data-start=&quot;612&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;619&quot; data-start=&quot;612&quot;&gt;&lt;b&gt;1xx&lt;/b&gt;&lt;/td&gt;
&lt;td data-end=&quot;631&quot; data-start=&quot;619&quot; data-col-size=&quot;sm&quot;&gt;정보 응답&lt;/td&gt;
&lt;td data-end=&quot;651&quot; data-start=&quot;631&quot; data-col-size=&quot;sm&quot;&gt;요청을 받았으며 처리를 계속함&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;688&quot; data-start=&quot;652&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;659&quot; data-start=&quot;652&quot;&gt;&lt;b&gt;2xx&lt;/b&gt;&lt;/td&gt;
&lt;td data-end=&quot;671&quot; data-start=&quot;659&quot; data-col-size=&quot;sm&quot;&gt;성공 응답&lt;/td&gt;
&lt;td data-end=&quot;688&quot; data-start=&quot;671&quot; data-col-size=&quot;sm&quot;&gt;요청이 정상적으로 처리됨&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;735&quot; data-start=&quot;689&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;696&quot; data-start=&quot;689&quot;&gt;&lt;b&gt;3xx&lt;/b&gt;&lt;/td&gt;
&lt;td data-end=&quot;707&quot; data-start=&quot;696&quot; data-col-size=&quot;sm&quot;&gt;리다이렉션&lt;/td&gt;
&lt;td data-end=&quot;735&quot; data-start=&quot;707&quot; data-col-size=&quot;sm&quot;&gt;추가 조치가 필요함 (다른 위치로 이동 등)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;771&quot; data-start=&quot;736&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;743&quot; data-start=&quot;736&quot;&gt;&lt;b&gt;4xx&lt;/b&gt;&lt;/td&gt;
&lt;td data-end=&quot;754&quot; data-start=&quot;743&quot; data-col-size=&quot;sm&quot;&gt;클라이언트 오류&lt;/td&gt;
&lt;td data-end=&quot;771&quot; data-start=&quot;754&quot; data-col-size=&quot;sm&quot;&gt;클라이언트의 잘못된 요청&lt;/td&gt;
&lt;/tr&gt;
&lt;tr data-end=&quot;810&quot; data-start=&quot;772&quot;&gt;
&lt;td data-col-size=&quot;sm&quot; data-end=&quot;779&quot; data-start=&quot;772&quot;&gt;&lt;b&gt;5xx&lt;/b&gt;&lt;/td&gt;
&lt;td data-end=&quot;791&quot; data-start=&quot;779&quot; data-col-size=&quot;sm&quot;&gt;서버 오류&lt;/td&gt;
&lt;td data-end=&quot;810&quot; data-start=&quot;791&quot; data-col-size=&quot;sm&quot;&gt;서버 내부 문제로 요청 실패&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;div&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr data-end=&quot;815&quot; data-start=&quot;812&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;836&quot; data-start=&quot;817&quot; data-ke-size=&quot;size23&quot;&gt;✅&lt;b&gt; 대표 상태 코드 상세 설명&lt;/b&gt;&lt;/h3&gt;
&lt;h4 data-end=&quot;853&quot; data-start=&quot;838&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;  1xx - 정보&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;906&quot; data-start=&quot;854&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;906&quot; data-start=&quot;854&quot;&gt;&lt;b&gt;100 Continue&lt;/b&gt;&lt;br /&gt;요청의 일부가 전송되었으며 나머지를 계속 보내도 됨.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;911&quot; data-start=&quot;908&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h4 data-end=&quot;928&quot; data-start=&quot;913&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;  2xx - 성공&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1112&quot; data-start=&quot;929&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;991&quot; data-start=&quot;929&quot;&gt;&lt;b&gt;200 OK&lt;/b&gt;&lt;br /&gt;가장 일반적인 성공 응답. GET, POST, PUT 등 다양한 요청에 사용된다.&lt;/li&gt;
&lt;li data-end=&quot;1046&quot; data-start=&quot;992&quot;&gt;&lt;b&gt;201 Created&lt;/b&gt;&lt;br /&gt;리소스가 성공적으로 생성됨. 주로 POST 요청 시 사용.&lt;/li&gt;
&lt;li data-end=&quot;1112&quot; data-start=&quot;1047&quot;&gt;&lt;b&gt;204 No Content&lt;/b&gt;&lt;br /&gt;요청은 성공했지만 응답 본문은 없음. DELETE 요청 후 자주 사용됨.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1160&quot; data-start=&quot;1114&quot; data-ke-size=&quot;size16&quot;&gt;&amp;rarr;   &lt;b&gt;&quot;성공 응답&quot;이라고 할 때, 가장 대표적인 코드는 200 OK이다.&lt;/b&gt;&lt;/p&gt;
&lt;hr data-end=&quot;1165&quot; data-start=&quot;1162&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h4 data-end=&quot;1185&quot; data-start=&quot;1167&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;  3xx - 리다이렉션&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1324&quot; data-start=&quot;1186&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1237&quot; data-start=&quot;1186&quot;&gt;&lt;b&gt;301 Moved Permanently&lt;/b&gt;&lt;br /&gt;요청한 리소스가 영구적으로 이동함.&lt;/li&gt;
&lt;li data-end=&quot;1276&quot; data-start=&quot;1238&quot;&gt;&lt;b&gt;302 Found&lt;/b&gt;&lt;br /&gt;일시적으로 다른 위치에서 응답함.&lt;/li&gt;
&lt;li data-end=&quot;1324&quot; data-start=&quot;1277&quot;&gt;&lt;b&gt;304 Not Modified&lt;/b&gt;&lt;br /&gt;캐시된 리소스가 그대로 사용 가능함.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;1329&quot; data-start=&quot;1326&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h4 data-end=&quot;1352&quot; data-start=&quot;1331&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;  4xx - 클라이언트 오류&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1580&quot; data-start=&quot;1353&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1408&quot; data-start=&quot;1353&quot;&gt;&lt;b&gt;400 Bad Request&lt;/b&gt;&lt;br /&gt;잘못된 문법으로 인해 서버가 요청을 이해할 수 없음.&lt;/li&gt;
&lt;li data-end=&quot;1467&quot; data-start=&quot;1409&quot;&gt;&lt;b&gt;401 Unauthorized&lt;/b&gt;&lt;br /&gt;인증이 필요함. (예: 로그인하지 않은 상태로 접근 시)&lt;/li&gt;
&lt;li data-end=&quot;1517&quot; data-start=&quot;1468&quot;&gt;&lt;b&gt;403 Forbidden&lt;/b&gt;&lt;br /&gt;서버가 요청을 이해했지만 거부함. 권한 부족.&lt;/li&gt;
&lt;li data-end=&quot;1580&quot; data-start=&quot;1518&quot;&gt;&lt;b&gt;404 Not Found&lt;/b&gt;&lt;br /&gt;요청한 리소스를 찾을 수 없음. (가장 자주 마주치는 오류 중 하나)&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;1585&quot; data-start=&quot;1582&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h4 data-end=&quot;1605&quot; data-start=&quot;1587&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;  5xx - 서버 오류&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1794&quot; data-start=&quot;1606&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1668&quot; data-start=&quot;1606&quot;&gt;&lt;b&gt;500 Internal Server Error&lt;/b&gt;&lt;br /&gt;서버 내부에서 처리 중 알 수 없는 에러 발생.&lt;/li&gt;
&lt;li data-end=&quot;1723&quot; data-start=&quot;1669&quot;&gt;&lt;b&gt;502 Bad Gateway&lt;/b&gt;&lt;br /&gt;게이트웨이 또는 프록시 서버가 잘못된 응답을 받음.&lt;/li&gt;
&lt;li data-end=&quot;1794&quot; data-start=&quot;1724&quot;&gt;&lt;b&gt;503 Service Unavailable&lt;/b&gt;&lt;br /&gt;서버가 일시적으로 요청을 처리할 수 없음. (예: 서버 점검 중)&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;1799&quot; data-start=&quot;1796&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;p data-end=&quot;1821&quot; data-start=&quot;1801&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;  자주 묻는 질문 (FAQ)&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;1849&quot; data-start=&quot;1823&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Q. 200 OK는 언제 사용하나요?&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;1901&quot; data-start=&quot;1850&quot; data-ke-size=&quot;size16&quot;&gt;&amp;rarr; &lt;b&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;요청이 성공적으로 처리된 경우 대부분의 HTTP 메서드에서 사용&lt;/span&gt;된다.&lt;/b&gt;&lt;br /&gt;예:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1992&quot; data-start=&quot;1902&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1922&quot; data-start=&quot;1902&quot;&gt;GET 요청에 대한 정상 응답&lt;/li&gt;
&lt;li data-end=&quot;1949&quot; data-start=&quot;1923&quot;&gt;PUT 요청으로 데이터 업데이트 완료 시&lt;/li&gt;
&lt;li data-end=&quot;1992&quot; data-start=&quot;1950&quot;&gt;POST 요청이지만, 새로 생성된 리소스 정보가 응답에 포함되지 않을 때&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;2027&quot; data-start=&quot;1994&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Q. POST 요청 시 꼭 201을 써야 하나요?&lt;/b&gt;&lt;/p&gt;
&lt;p data-end=&quot;2147&quot; data-start=&quot;2028&quot; data-ke-size=&quot;size16&quot;&gt;&amp;rarr; &lt;b&gt;반드시 그런 것은 아니다.&lt;/b&gt;&lt;br /&gt;201은 리소스가 생성된 경우에 사용하는 것이 명확하지만, &lt;i&gt;일부 API에서는 200으로 응답하기도 한다&lt;/i&gt;.&lt;/p&gt;
&lt;p data-end=&quot;2147&quot; data-start=&quot;2028&quot; data-ke-size=&quot;size16&quot;&gt;RESTful API 설계 지침에서는 보통 201 사용을 권장한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>개발자 면접 노트</category>
      <author>해로몬</author>
      <guid isPermaLink="true">https://hyeromon.tistory.com/107</guid>
      <comments>https://hyeromon.tistory.com/107#entry107comment</comments>
      <pubDate>Wed, 25 Jun 2025 22:49:55 +0900</pubDate>
    </item>
    <item>
      <title>MVC 패턴</title>
      <link>https://hyeromon.tistory.com/106</link>
      <description>&lt;h3 data-end=&quot;133&quot; data-start=&quot;122&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;MVC 패턴이란?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-end=&quot;283&quot; data-start=&quot;135&quot; data-ke-size=&quot;size16&quot;&gt;MVC는 &lt;b&gt;Model-View-Controller&lt;/b&gt;의 약자로, 애플리케이션을 &lt;b&gt;세 가지 주요 구성 요소로 분리&lt;/b&gt;하는 소프트웨어 설계 패턴이다.&lt;br /&gt;주로 웹 애플리케이션에서 사용되며, 코드의 &lt;b&gt;역할을 명확히 나누고 유지보수와 확장성&lt;/b&gt;을 높이는 데 유리하다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;668&quot; data-start=&quot;285&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;387&quot; data-start=&quot;285&quot;&gt;&lt;b&gt;Model(모델)&lt;/b&gt;:&lt;br /&gt;애플리케이션의 &lt;b&gt;핵심 데이터와 비즈니스 로직&lt;/b&gt;을 담당한다. 예를 들어 게시판이라면, 게시글 데이터를 조회&amp;middot;저장&amp;middot;수정하는 로직이 모델에 속한다.&lt;/li&gt;
&lt;li data-end=&quot;500&quot; data-start=&quot;389&quot;&gt;&lt;b&gt;View(뷰)&lt;/b&gt;:&lt;br /&gt;사용자에게 보이는 &lt;b&gt;UI 화면&lt;/b&gt;을 담당한다. HTML, JSP, Thymeleaf 같은 템플릿 엔진이 여기에 해당하며, 데이터를 시각적으로 보여주는 역할을 한다.&lt;/li&gt;
&lt;li data-end=&quot;668&quot; data-start=&quot;502&quot;&gt;&lt;b&gt;Controller(컨트롤러)&lt;/b&gt;:&lt;br /&gt;사용자의 요청을 받아 Model에게 전달하고, 처리 결과를 View로 연결해주는 &lt;b&gt;중간 조율자 역할&lt;/b&gt;을 한다. 예를 들어 로그인 요청을 받으면, Controller는 Model에게 인증을 요청하고 결과에 따라 알맞은 화면(View)을 반환한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;673&quot; data-start=&quot;670&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h4 data-end=&quot;688&quot; data-start=&quot;675&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;MVC 패턴의 흐름&lt;/b&gt;&lt;/h4&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1750858314159&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[User] 
   &amp;darr;
[Controller] &amp;rarr; [Model] &amp;rarr; DB
   &amp;darr;
[View] &amp;rarr; 사용자에게 결과 표시&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;942&quot; data-start=&quot;766&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;803&quot; data-start=&quot;766&quot;&gt;사용자가 브라우저에서 요청을 보낸다. (예: /login)&lt;/li&gt;
&lt;li data-end=&quot;847&quot; data-start=&quot;804&quot;&gt;Controller가 요청을 받아 적절한 Model에게 작업을 요청한다.&lt;/li&gt;
&lt;li data-end=&quot;889&quot; data-start=&quot;848&quot;&gt;Model은 로직을 수행하고 결과를 Controller에게 반환한다.&lt;/li&gt;
&lt;li data-end=&quot;942&quot; data-start=&quot;890&quot;&gt;Controller는 결과를 View에 전달하고, View는 사용자에게 화면을 출력한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr data-end=&quot;947&quot; data-start=&quot;944&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h4 data-end=&quot;962&quot; data-start=&quot;949&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;MVC 패턴의 장점&lt;/b&gt;&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;1398&quot; data-start=&quot;964&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;1098&quot; data-start=&quot;964&quot;&gt;&lt;b&gt;역할의 명확한 분리&lt;/b&gt;&lt;br /&gt;구성 요소의 책임이 명확하게 구분되어 있어 &lt;b&gt;코드의 가독성&lt;/b&gt;이 높고, 유지보수가 쉬워진다.&lt;br /&gt;화면(View)을 수정해도 핵심 로직(Model)은 영향을 받지 않고, 그 반대도 마찬가지이다.&lt;/li&gt;
&lt;li data-end=&quot;1207&quot; data-start=&quot;1100&quot;&gt;&lt;b&gt;낮은 결합도와 높은 응집도&lt;/b&gt;&lt;br /&gt;각 구성 요소는 &lt;b&gt;서로 강하게 의존하지 않기 때문에&lt;/b&gt;, 독립적으로 개발&amp;middot;수정&amp;middot;테스트가 가능하다.&lt;br /&gt;코드 재사용성과 유연성이 높아진다.&lt;/li&gt;
&lt;li data-end=&quot;1300&quot; data-start=&quot;1209&quot;&gt;&lt;b&gt;모델 재사용 가능&lt;/b&gt;&lt;br /&gt;하나의 Model을 여러 View에서 사용할 수 있어, &lt;b&gt;웹, 모바일, 관리자 페이지 등 다양한 환경에 적용 가능&lt;/b&gt;하다.&lt;/li&gt;
&lt;li data-end=&quot;1398&quot; data-start=&quot;1302&quot;&gt;&lt;b&gt;협업에 유리함&lt;/b&gt;&lt;br /&gt;프론트엔드는 View 중심으로, 백엔드는 Controller와 Model 중심으로 개발할 수 있어 &lt;b&gt;업무 분담과 협업이 효율적&lt;/b&gt;이다.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr data-end=&quot;1403&quot; data-start=&quot;1400&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h4 data-end=&quot;1418&quot; data-start=&quot;1405&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;MVC 패턴의 한계점&lt;/b&gt;&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;1961&quot; data-start=&quot;1420&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;855&quot; data-start=&quot;735&quot;&gt;&lt;b&gt;간단한 프로젝트에선 과한 구조가 될 수 있다&lt;/b&gt;&lt;br /&gt;작은 규모의 기능이라도 Model, View, Controller로 나누어야 하므로&lt;br /&gt;오히려 코드가 복잡해지고 초기 개발 속도를 떨어뜨릴 수 있다.&lt;/li&gt;
&lt;li data-end=&quot;1004&quot; data-start=&quot;857&quot;&gt;&lt;b&gt;Controller 비대화 현상 (Massive Controller)&lt;/b&gt;&lt;br /&gt;설계가 잘못되면 Controller에 여러 책임이 몰려서, 로직이 복잡해지고 유지보수가 어려워질 수 있다.&lt;br /&gt;&amp;rarr; 일반적으로 Service 계층을 도입해 책임을 분산시킨다.&lt;/li&gt;
&lt;li data-end=&quot;1117&quot; data-start=&quot;1006&quot;&gt;&lt;b&gt;완전한 역할 분리가 어려운 경우가 있다&lt;/b&gt;&lt;br /&gt;현실적인 코드에서는 View에 일부 로직이 들어가거나,&lt;br /&gt;Controller가 Model에 과하게 의존하는 등 구조가 흐트러질 수 있다.&lt;/li&gt;
&lt;li data-end=&quot;1230&quot; data-start=&quot;1119&quot;&gt;&lt;b&gt;테스트 코드 작성의 어려움&lt;/b&gt;&lt;br /&gt;Controller가 여러 책임을 가지면 단위 테스트가 어려워지고,&lt;br /&gt;의존성 주입이나 계층 분리가 되어 있지 않으면 테스트 코드 작성이 번거로워진다.&lt;/li&gt;
&lt;li data-end=&quot;1359&quot; data-start=&quot;1232&quot;&gt;&lt;b&gt;Model과 View의 의존성을 완전히 분리하기 어렵다&lt;/b&gt;&lt;br /&gt;실무에서는 View에서 Model 객체를 직접 참조하는 일이 많으며,&lt;br /&gt;이로 인해 설계 원칙에서 말하는 '완전한 분리'가 잘 지켜지지 않을 수 있다.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr data-end=&quot;1966&quot; data-start=&quot;1963&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h4 data-end=&quot;1984&quot; data-start=&quot;1968&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;MVC 패턴의 설계 원칙&lt;/b&gt;&lt;/h4&gt;
&lt;p data-end=&quot;2031&quot; data-start=&quot;1986&quot; data-ke-size=&quot;size16&quot;&gt;MVC 패턴을 올바르게 사용하기 위해서는 다음과 같은 구조적 원칙을 지켜야 한다:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2574&quot; data-start=&quot;2033&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2137&quot; data-start=&quot;2033&quot;&gt;&lt;b&gt;Model은 Controller와 View에 의존하지 않아야 한다.&lt;/b&gt;&lt;br /&gt;Model은 순수하게 데이터와 로직만 처리하는 계층이어야 하며, 다른 구성 요소에 의존하면 안 된다.&lt;/li&gt;
&lt;li data-end=&quot;2262&quot; data-start=&quot;2139&quot;&gt;&lt;b&gt;View는 Controller에 의존하면 안 되고, Model만 참조해야 한다.&lt;/b&gt;&lt;br /&gt;View는 Model에서 데이터를 받아 표현하는 데 집중해야 하며, 로직은 Controller나 Model에 맡겨야 한다.&lt;/li&gt;
&lt;li data-end=&quot;2377&quot; data-start=&quot;2264&quot;&gt;&lt;b&gt;Controller는 Model과 View에 의존할 수 있다.&lt;/b&gt;&lt;br /&gt;사용자의 입력을 처리하고, 로직을 호출하고, 그 결과를 View에 전달하는 책임을 가지므로, 양쪽에 접근이 가능해야 한다.&lt;/li&gt;
&lt;li data-end=&quot;2574&quot; data-start=&quot;2379&quot;&gt;&lt;b&gt;View가 데이터를 필요로 할 때는 Controller를 통해 Model에서 받아야 한다.&lt;/b&gt;&lt;br /&gt;View는 직접 Model을 호출하지 않고, Controller가 필요한 데이터를 준비해 전달해야 한다. (&amp;rarr; 실무에서는 View가 Model을 직접 참조하는 경우도 있지만, 이상적인 구조는 Controller가 중간 다리 역할을 하는 것)&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>개발자 면접 노트</category>
      <author>해로몬</author>
      <guid isPermaLink="true">https://hyeromon.tistory.com/106</guid>
      <comments>https://hyeromon.tistory.com/106#entry106comment</comments>
      <pubDate>Wed, 25 Jun 2025 22:40:44 +0900</pubDate>
    </item>
    <item>
      <title>Kotlin과 같은 등급은 Java인가 Spring인가?</title>
      <link>https://hyeromon.tistory.com/105</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Kotlin과&amp;nbsp;같은&amp;nbsp;등급은&amp;nbsp;Java인가&amp;nbsp;Spring인가?&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Kotlin과 같은 프로그래밍 언어는 Java 입니다.&lt;br /&gt;Spring은 프레임워크로 웹 애플리케이션을 개발하기 쉽게 도와주는 도구입니다.&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;항목&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;성격/역할&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;예&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;Java&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;프로그래밍 언어&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;C++, Python 같은 언어&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;Kotlin&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;프로그래밍 언어&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;Java의 대안 또는 JVM 기반 언어&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;Spring&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;프레임워크&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;언어(Java 또는 Kotlin) 위에 올라가는 웹 개발 도구&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;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Java와 Kotlin의 공통점&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 data-end=&quot;206&quot; data-start=&quot;83&quot;&gt;&lt;b&gt;JVM 기반 언어&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;396&quot; data-start=&quot;208&quot;&gt;&lt;b&gt;강력한 도구와 라이브러리 공유&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;396&quot; data-start=&quot;235&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;304&quot; data-start=&quot;235&quot;&gt;&lt;b&gt;같은 개발 도구(IDE)&lt;/b&gt; 사용 가능
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;304&quot; data-start=&quot;268&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;304&quot; data-start=&quot;268&quot;&gt;예: IntelliJ IDEA, Android Studio 등&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;396&quot; data-start=&quot;308&quot;&gt;&lt;b&gt;동일한 Java 라이브러리 사용 가능&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;396&quot; data-start=&quot;342&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;396&quot; data-start=&quot;342&quot;&gt;Kotlin에서도 Java의 라이브러리나 프레임워크(Spring 등)를 그대로 사용할 수 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;519&quot; data-start=&quot;398&quot;&gt;&lt;b&gt;상호운용성 (Interoperability)&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;519&quot; data-start=&quot;433&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;472&quot; data-start=&quot;433&quot;&gt;Kotlin과 Java 코드를 &lt;b&gt;서로 호출하고 혼용할 수 있음&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;519&quot; data-start=&quot;476&quot;&gt;예: Kotlin 클래스에서 Java 클래스를 불러오거나, 그 반대도 가능&lt;/li&gt;
&lt;/ul&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;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Java와 Kotlin의 차이점&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;항목 Java Kotlin&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 178px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;&lt;b&gt;문법&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;길고 반복적인 코드가 많음&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;간결하고 현대적인 문법&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;&lt;b&gt;Null 처리&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;NullPointerException(NPE)에 취약&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;컴파일 타임에서 null 안전성 보장 (?, !! 등)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;&lt;b&gt;함수형 프로그래밍&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;제한적 지원&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;고차 함수, 람다 등 함수형 완전 지원&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;&lt;b&gt;데이터 클래스&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;직접 모든 메서드 구현해야 함&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;data class 한 줄로 자동 생성&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;&lt;b&gt;코루틴(비동기)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;기본 지원 없음 (Thread 위주)&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;**코루틴(Coroutines)**으로 간단하고 가벼운 비동기 처리 가능&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 21px;&quot;&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;&lt;b&gt;확장 함수&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;없음&lt;/td&gt;
&lt;td style=&quot;height: 21px;&quot;&gt;fun 클래스명.함수명()으로 확장 가능&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;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;Java와 Kotlin의 장단점&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;&amp;nbsp;&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;Java&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;&lt;b&gt;Kotlin&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;장점&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;오랜 역사와 안정성&lt;br /&gt;방대한 커뮤니티와 문서&lt;br /&gt;라이브러리/프레임워크 다양함&lt;br /&gt;기업용 시스템에 적합&lt;/td&gt;
&lt;td&gt;문법이 간결해 생산성 &amp;uarr;&lt;br /&gt;Null 안정성으로 오류 &amp;darr;&lt;br /&gt;함수형/확장 함수 지원&lt;br /&gt;코루틴으로 간단한 비동기 처리&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;단점&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;코드가 장황하고 반복적&lt;br /&gt;NullPointerException 위험&lt;br /&gt;최신 기능 도입이 느림&lt;/td&gt;
&lt;td&gt;러닝 커브(Java 대비)&lt;br /&gt;일부 빌드/컴파일 속도 느릴 수 있음&lt;br /&gt;레거시 Java 프로젝트와 100% 호환은 아님(경우에 따라)&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;</description>
      <category>개발자 면접 노트</category>
      <author>해로몬</author>
      <guid isPermaLink="true">https://hyeromon.tistory.com/105</guid>
      <comments>https://hyeromon.tistory.com/105#entry105comment</comments>
      <pubDate>Wed, 25 Jun 2025 20:14:48 +0900</pubDate>
    </item>
    <item>
      <title>Spring - 의존성 주입(DI)의 종류</title>
      <link>https://hyeromon.tistory.com/104</link>
      <description>&lt;p style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;의존성 주입(Dependency Injection, DI)&lt;/b&gt;&lt;/p&gt;
&lt;blockquote style=&quot;color: #666666; text-align: left;&quot; data-ke-style=&quot;style2&quot;&gt;스프링 컨테이너에서 객체 Bean을 먼저 생성해두고 생성한 객체를 지정한 객체에 주입하는 방식&lt;/blockquote&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: #000000;&quot;&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; background-color: #f6e199;&quot;&gt;생성자 주입&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000; background-color: #f6e199;&quot;&gt;필드주입&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;color: #000000; background-color: #f6e199;&quot;&gt;세터 주입 &lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;3가지 방법이 있다.&lt;/b&gt;&lt;/span&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;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;1.생성자 주입(Constructor Injection)&lt;/b&gt;&lt;/h3&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;*단일 생성자에 한해 @Autowired를 생략 가능&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-end=&quot;561&quot; data-start=&quot;552&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;✅ 장점&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;715&quot; data-start=&quot;562&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;590&quot; data-start=&quot;562&quot;&gt;&lt;b&gt;불변성 보장&lt;/b&gt; &amp;rarr; final 사용 가능&lt;/li&gt;
&lt;li data-end=&quot;632&quot; data-start=&quot;591&quot;&gt;&lt;b&gt;필수 의존성 보장&lt;/b&gt; &amp;rarr; 의존 객체 없으면 객체 생성 자체가 안 됨&lt;/li&gt;
&lt;li data-end=&quot;677&quot; data-start=&quot;633&quot;&gt;&lt;b&gt;순환 의존을 조기에 발견 가능&lt;/b&gt; &amp;rarr; 애플리케이션 시작 시점에 오류 발생&lt;/li&gt;
&lt;li data-end=&quot;715&quot; data-start=&quot;678&quot;&gt;&lt;b&gt;테스트 코드 작성 용이&lt;/b&gt; &amp;rarr; 생성자 인자로 직접 주입 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;726&quot; data-start=&quot;717&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;❌ 단점&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;762&quot; data-start=&quot;727&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;762&quot; data-start=&quot;727&quot;&gt;의존성이 많아지면 생성자가 길어질 수 있음 &amp;rarr; 리팩터링 필요&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1750848273765&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Component
public class OrderService {
    private final PaymentService paymentService;

    @Autowired
    public OrderService(PaymentService paymentService) {
        this.paymentService = paymentService;
    }
}&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;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;2.필드 주입(Field Injection)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;필드에 직접 @Autowired를 붙여서 주입받는 방식&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-end=&quot;1081&quot; data-start=&quot;1072&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;✅ 장점&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1119&quot; data-start=&quot;1082&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1098&quot; data-start=&quot;1082&quot;&gt;구현이 가장 간단하고 빠름&lt;/li&gt;
&lt;li data-end=&quot;1119&quot; data-start=&quot;1099&quot;&gt;&lt;u&gt;테스트용/프로토타입용 코드에 유용&lt;/u&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-end=&quot;1130&quot; data-start=&quot;1121&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;❌ 단점&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1230&quot; data-start=&quot;1131&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1173&quot; data-start=&quot;1131&quot;&gt;&lt;b&gt;테스트 어려움&lt;/b&gt; &amp;rarr; 필드에 직접 접근 불가 (리플렉션 사용해야 함)&lt;/li&gt;
&lt;li data-end=&quot;1199&quot; data-start=&quot;1174&quot;&gt;&lt;b&gt;불변성 깨짐&lt;/b&gt; &amp;rarr; final 불가&lt;/li&gt;
&lt;li data-end=&quot;1230&quot; data-start=&quot;1200&quot;&gt;&lt;b&gt;Spring이 관리하는 환경에서만 동작 가능&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1750848281228&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Component
public class AlertService {

    @Autowired
    private SmsSender smsSender;
}&lt;/code&gt;&lt;/pre&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;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;3.세터 주입(Setter Injection)&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;setter 메서드를 통해 의존객체를 주입받는 방식&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-end=&quot;1455&quot; data-start=&quot;1446&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;✅ 장점&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1500&quot; data-start=&quot;1456&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1481&quot; data-start=&quot;1456&quot;&gt;의존성을 &lt;b&gt;나중에 바꾸거나 설정 가능&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;1500&quot; data-start=&quot;1482&quot;&gt;필요할 때만 의존성 주입 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-end=&quot;1511&quot; data-start=&quot;1502&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;❌ 단점&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1555&quot; data-start=&quot;1512&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1542&quot; data-start=&quot;1512&quot;&gt;객체 생성 시점에 완전한 초기화가 안 될 수도 있음&lt;/li&gt;
&lt;li data-end=&quot;1555&quot; data-start=&quot;1543&quot;&gt;불변성 보장 안 됨&lt;/li&gt;
&lt;/ul&gt;
&lt;pre id=&quot;code_1750848288128&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;@Component
public class NotificationService {
    private MessageSender sender;

    @Autowired
    public void setSender(MessageSender sender) {
        this.sender = sender;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;@Autowired로 주입할 대상이 없는 경우에는 오류가 발생한다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&lt;span style=&quot;color: #666666;&quot;&gt;주입할 대상이 없어도 동작하도록 하려면 @Autowired(required = false)를 통해 설정할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&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;size18&quot;&gt;&lt;b&gt;[정리]&lt;/b&gt;&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;&lt;b&gt;생성자 주입&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;&lt;b&gt;필드 주입&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;&lt;b&gt;세터 주입&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;가독성이 좋고,&lt;br /&gt;테스트코드 작성에 용이하며,&lt;br /&gt;런타임 시점에 유연성이 높다.&lt;br /&gt;&lt;br /&gt;*권장하는 방법&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;가독성이 가장 떨어지기 때문에 유지보수가 어려우며, 의존성 변경이 어려워 유연성이 떨어진다.&lt;br /&gt;&lt;br /&gt;*최대한 안쓰는 것이 좋다&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%;&quot;&gt;생성자 주입에 비해 코드 가독성이 떨어지기 때문에 코드의 양이 많을 때 사용한다.&lt;br /&gt;생성자를 통해 객체를 생성하고, Setter 메서드를 통해 의존성을 주입하는 것이 좋다.&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;</description>
      <category>개발자 면접 노트</category>
      <author>해로몬</author>
      <guid isPermaLink="true">https://hyeromon.tistory.com/104</guid>
      <comments>https://hyeromon.tistory.com/104#entry104comment</comments>
      <pubDate>Wed, 25 Jun 2025 19:54:20 +0900</pubDate>
    </item>
    <item>
      <title>Spring - 의존성 주입(DI)</title>
      <link>https://hyeromon.tistory.com/103</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;의존성 주입(Dependency Injection, DI)&lt;/b&gt;&lt;/h4&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;스프링 컨테이너에서 객체 Bean을 먼저 생성해두고 생성한 객체를 지정한 객체에 주입하는 방식&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;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인터페이스를 사이에 둿 클래스 레벨에서는 의존관계가 고정되지 않도록 런타임 시에 관계를 동적으로 주입하여 &lt;i&gt;&lt;u&gt;유연성을 확보&lt;/u&gt;&lt;/i&gt;하고 &lt;u&gt;&lt;i&gt;결합도를 낮출&lt;/i&gt;&lt;/u&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;두 객체 간의 관계라는 관심사의 분리&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;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;의존성 주입을 왜 사용하는가?&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1750844349976&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;public class Store{
	private Coke coke;
    
    public Store(){
    	this.coke = new Coke();
    }
}&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;size18&quot;&gt;&lt;b&gt;&amp;lt;문제점&amp;gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 두 클래스가 강하게 결합되어 있다&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;만약 Store에서 Coke가 아닌 Milk로 변경하고자 한다면 Store 클래스의 생성자에 변경이 필요 -&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;2. 객체들 간의 관계가 아니라 클래스 간의 관계가 맺어진다. -&amp;gt; &lt;span style=&quot;background-color: #dddddd;&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;객체들 간의 관계가 맺어졌다면 다른 객체의 구체 클래스(coke or milk)를 전혀 알지 못하더라도, 인터페이스의 타입(Drinks)으로 사용할 수 있다.&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;[의존성 주입으로 해결되는 점]&lt;/b&gt;&lt;/h4&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;문제점&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;적용 후 해결 방식&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;강한 결합&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Store는 더 이상 Coke, Milk 같은 구체 클래스에 의존하지 않고 Drinks 인터페이스에만 의존함. 따라서 다른 음료로 교체 시 Store를 수정할 필요가 없음&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;클래스 간의 관계&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;이제 클래스 간 관계가 아닌 &lt;b&gt;객체 간의 관계&lt;/b&gt;로 구성됨. 외부에서 어떤 객체를 넣느냐에 따라 동작이 바뀌므로 유연성이 생김&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;관심사 분리&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Store는 어떤 음료를 파는지에 대한 책임이 없음 &amp;rarr; 책임이 분리되고 관심사가 명확해짐&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;확장성&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;새로운 음료 (Juice, Water 등) 추가 시 Store 수정 없이 사용 가능&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;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #dddddd;&quot;&gt;&lt;i&gt;&lt;u&gt;요약&lt;/u&gt;&lt;/i&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;의존성 주입은 객체 간의 결합을 낮추고, 추상화된 타입을 통해 더 유연하고 테스트 가능한 구조를 만들어준다.&lt;/b&gt;&lt;br /&gt;&lt;b&gt;이로 인해 객체 지향 설계 원칙을 잘 따르게 되고, 유지보수와 확장이 쉬워진다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>개발자 면접 노트</category>
      <author>해로몬</author>
      <guid isPermaLink="true">https://hyeromon.tistory.com/103</guid>
      <comments>https://hyeromon.tistory.com/103#entry103comment</comments>
      <pubDate>Wed, 25 Jun 2025 19:04:34 +0900</pubDate>
    </item>
    <item>
      <title>AJAX를 사용하는 이유</title>
      <link>https://hyeromon.tistory.com/102</link>
      <description>&lt;h2 data-end=&quot;176&quot; data-start=&quot;164&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Ajax란?&lt;/b&gt;&lt;/h2&gt;
&lt;p data-end=&quot;293&quot; data-start=&quot;178&quot; data-ke-size=&quot;size16&quot;&gt;Ajax는 &lt;b&gt;Asynchronous JavaScript and XML&lt;/b&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;h4 data-end=&quot;315&quot; data-start=&quot;300&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;어떻게 동작할까?&lt;/b&gt;&lt;/h4&gt;
&lt;p data-end=&quot;413&quot; data-start=&quot;317&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;사용자가 동작 실행&lt;/b&gt;&lt;br /&gt;➡️ &lt;b&gt;JavaScript가 서버에 요청&lt;/b&gt;&lt;br /&gt;➡️ &lt;b&gt;서버가 응답 반환&lt;/b&gt;&lt;br /&gt;➡️ &lt;b&gt;받은 데이터를 이용해 웹페이지 일부만 업데이트&lt;/b&gt;&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;&lt;b&gt;Ajax의 주요 구성요소&lt;/b&gt;&lt;/h4&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;HTML / CSS&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;웹 페이지의 구조와 스타일을 구성한다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;DOM (Document Object Model)&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;자바스크립트가 HTML 요소를 동적으로 조작할 수 있도록 도와준다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;JavaScript&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;Ajax의 중심. 서버 요청을 보내고, 받은 데이터를 처리한다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;XMLHttpRequest&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;브라우저에서 서버와 데이터를 주고받는 API이다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;JSON / XML / 텍스트 등&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;서버와 주고받는 데이터 형식. 요즘은 대부분 JSON 사용한다.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;b&gt;이벤트 (Event)&lt;/b&gt;&lt;/td&gt;
&lt;td&gt;버튼 클릭, 스크롤 등 사용자 동작을 트리거로 Ajax 요청을 보낸다.&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;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;AJAX를 사용하는 이유&lt;/b&gt;&lt;/h4&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 114px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;&lt;b&gt;장점&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;&lt;b&gt;설명&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;&lt;b&gt;전체 페이지 새로고침 없이 일부만 업데이트&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;필요한 부분만 바꿔서 빠르고 부드러운 사용자 경험 제공&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;&lt;b&gt;페이지 로드 후에도 서버와 통신 가능&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;동적으로 데이터를 가져오고, 업데이트 가능&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;&lt;b&gt;백그라운드 통신 가능&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;사용자가 인식하지 못하는 사이에 서버 요청 처리&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;&lt;b&gt;비동기 처리로 속도 향상&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;응답을 기다리지 않고 다음 작업 수행 가능&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;&lt;b&gt;서버 자원과 트래픽 절약&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;전체 페이지가 아니라 필요한 데이터만 요청&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;h4 data-end=&quot;1241&quot; data-start=&quot;1227&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;⚠️ Ajax의 한계&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1375&quot; data-start=&quot;1243&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1375&quot; data-start=&quot;1342&quot;&gt;히스토리 관리가 되지 않고, 페이지간 이동 없는 통신 방법으로 보안 상의 문제가 생길 수 있음.&lt;/li&gt;
&lt;li data-end=&quot;1375&quot; data-start=&quot;1342&quot;&gt;연속으로 데이터 요청 -&amp;gt; 서버 부하 증가&lt;/li&gt;
&lt;li data-end=&quot;1375&quot; data-start=&quot;1342&quot;&gt;디버깅 어려움&lt;/li&gt;
&lt;li data-end=&quot;1375&quot; data-start=&quot;1342&quot;&gt;서버 푸시가 불가 =&amp;gt; 클라이언트가 요청해야 함.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;b&gt;클라이언트 풀링 방식&lt;/b&gt;: 사용자가 직접 원하는 정보를 서버에게 요청하여 얻는 방식&lt;br /&gt;&lt;b&gt;서버 푸시 방식&lt;/b&gt; : 사용자가 요청하지 않아도 서버가 알아서 특정 정보를 제공하는 것을 의미.&lt;br /&gt;대표적으로 앱에서 자동으로 보내는 푸시 알림이 있음.&lt;/blockquote&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-end=&quot;923&quot; data-start=&quot;912&quot; data-ke-size=&quot;size20&quot;&gt;요약&lt;/h4&gt;
&lt;blockquote data-end=&quot;1030&quot; data-start=&quot;925&quot; data-ke-style=&quot;style2&quot;&gt;
&lt;p data-end=&quot;1030&quot; data-start=&quot;927&quot; data-ke-size=&quot;size16&quot;&gt;AJAX는 &lt;b&gt;HTML, DOM, JavaScript, 서버 통신 API(XMLHttpRequest 등)를 함께 활용해&lt;u&gt; 새로고침 없이 동적으로 웹 페이지를 갱신하는 기술 방식&lt;/u&gt;&lt;/b&gt;&lt;u&gt;입니다.&lt;/u&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description>
      <category>개발자 면접 노트</category>
      <author>해로몬</author>
      <guid isPermaLink="true">https://hyeromon.tistory.com/102</guid>
      <comments>https://hyeromon.tistory.com/102#entry102comment</comments>
      <pubDate>Tue, 24 Jun 2025 23:26:51 +0900</pubDate>
    </item>
    <item>
      <title>동기(Synchronous)와 비동기(Asynchronous)의 차이점</title>
      <link>https://hyeromon.tistory.com/101</link>
      <description>&lt;h3 data-end=&quot;404&quot; data-start=&quot;382&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;✅ 동기(Synchronous)란?&lt;/b&gt;&lt;/h3&gt;
&lt;p data-end=&quot;461&quot; data-start=&quot;406&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;작업이 순차적으로 진행되며&lt;/b&gt;, 하나의 작업이 완료되기 전에는 다음 작업으로 넘어가지 않습니다.&lt;/p&gt;
&lt;h4 data-end=&quot;471&quot; data-start=&quot;463&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;예시&lt;/b&gt;&lt;/h4&gt;
&lt;blockquote data-end=&quot;506&quot; data-start=&quot;472&quot; data-ke-style=&quot;style2&quot;&gt;
&lt;p data-end=&quot;506&quot; data-start=&quot;474&quot; data-ke-size=&quot;size16&quot;&gt;A 작업이 끝나야만 B 작업을 시작할 수 있는 구조입니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 data-end=&quot;517&quot; data-start=&quot;508&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;주요 특징&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;644&quot; data-start=&quot;519&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;558&quot; data-start=&quot;519&quot;&gt;&lt;b&gt;순차적 실행&lt;/b&gt;: 하나의 작업이 끝나야 다음 작업으로 진행됨&lt;/li&gt;
&lt;li data-end=&quot;595&quot; data-start=&quot;559&quot;&gt;&lt;b&gt;직관적인 흐름&lt;/b&gt;: 코드 흐름이 간단하고 이해하기 쉬움&lt;/li&gt;
&lt;li data-end=&quot;644&quot; data-start=&quot;596&quot;&gt;&lt;b&gt;성능 저하 가능성&lt;/b&gt;: 시간이 오래 걸리는 작업이 전체 흐름을 지연시킬 수 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-end=&quot;662&quot; data-start=&quot;646&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;언제 사용하면 좋을까?&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;746&quot; data-start=&quot;664&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;684&quot; data-start=&quot;664&quot;&gt;작업의 &lt;b&gt;순서가 중요한 경우&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;717&quot; data-start=&quot;685&quot;&gt;&lt;b&gt;이전 작업의 결과&lt;/b&gt;가 바로 다음 작업에 필요할 때&lt;/li&gt;
&lt;li data-end=&quot;746&quot; data-start=&quot;718&quot;&gt;&lt;b&gt;간단한 스크립트나 소규모 프로그램&lt;/b&gt;에 적합&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;751&quot; data-start=&quot;748&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-end=&quot;777&quot; data-start=&quot;753&quot; data-ke-size=&quot;size23&quot;&gt;✅ 비동기(Asynchronous)란?&lt;/h3&gt;
&lt;p data-end=&quot;845&quot; data-start=&quot;779&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;작업이 서로 독립적으로 실행&lt;/b&gt;되며, 하나의 작업이 끝나기를 기다리지 않고 다음 작업을 수행할 수 있는 방식입니다.&lt;/p&gt;
&lt;h4 data-end=&quot;855&quot; data-start=&quot;847&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;예시&lt;/b&gt;&lt;/h4&gt;
&lt;blockquote data-end=&quot;893&quot; data-start=&quot;856&quot; data-ke-style=&quot;style2&quot;&gt;
&lt;p data-end=&quot;893&quot; data-start=&quot;858&quot; data-ke-size=&quot;size16&quot;&gt;A 작업이 완료되기를 기다리는 동안 B 작업도 같이 수행됩니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 data-end=&quot;904&quot; data-start=&quot;895&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;주요 특징&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1014&quot; data-start=&quot;906&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;927&quot; data-start=&quot;906&quot;&gt;&lt;b&gt;병렬적인 작업 처리&lt;/b&gt; 가능&lt;/li&gt;
&lt;li data-end=&quot;966&quot; data-start=&quot;928&quot;&gt;&lt;b&gt;대기 시간 최소화&lt;/b&gt;: 사용자가 느끼는 응답 속도가 빨라짐&lt;/li&gt;
&lt;li data-end=&quot;1014&quot; data-start=&quot;967&quot;&gt;&lt;b&gt;복잡한 구조&lt;/b&gt;: 콜백, 프로미스, 예외 처리 등으로 코드가 복잡해질 수 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 data-end=&quot;1032&quot; data-start=&quot;1016&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;언제 사용하면 좋을까?&lt;/b&gt;&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1152&quot; data-start=&quot;1034&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1073&quot; data-start=&quot;1034&quot;&gt;네트워크 요청, 파일 읽기/쓰기 등 &lt;b&gt;시간이 오래 걸리는 작업&lt;/b&gt;&lt;/li&gt;
&lt;li data-end=&quot;1099&quot; data-start=&quot;1074&quot;&gt;&lt;b&gt;여러 작업을 동시에 처리&lt;/b&gt;해야 할 때&lt;/li&gt;
&lt;li data-end=&quot;1122&quot; data-start=&quot;1100&quot;&gt;&lt;b&gt;UI 응답성&lt;/b&gt;을 유지해야 할 때&lt;/li&gt;
&lt;li data-end=&quot;1152&quot; data-start=&quot;1123&quot;&gt;&lt;b&gt;대규모 트래픽을 처리하는 서버 애플리케이션&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;1157&quot; data-start=&quot;1154&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h4 data-end=&quot;1180&quot; data-start=&quot;1159&quot; data-ke-size=&quot;size20&quot;&gt;  주요 비동기 프로그래밍 패턴&lt;/h4&gt;
&lt;h4 data-end=&quot;1201&quot; data-start=&quot;1182&quot; data-ke-size=&quot;size20&quot;&gt;1. &lt;b&gt;Callback&lt;/b&gt;&lt;/h4&gt;
&lt;blockquote data-end=&quot;1226&quot; data-start=&quot;1202&quot; data-ke-style=&quot;style2&quot;&gt;
&lt;p data-end=&quot;1226&quot; data-start=&quot;1204&quot; data-ke-size=&quot;size16&quot;&gt;작업 완료 시 특정 함수를 호출하는 방식&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1273&quot; data-start=&quot;1228&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1240&quot; data-start=&quot;1228&quot;&gt;장점: 간단한 구조&lt;/li&gt;
&lt;li data-end=&quot;1273&quot; data-start=&quot;1241&quot;&gt;단점: 콜백 지옥(Callback Hell) 발생 가능&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1750768086662&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function getData(callback) {
  setTimeout(() =&amp;gt; {
    const data = &quot;데이터&quot;;
    console.log(&quot;1. 데이터를 가져왔습니다.&quot;);
    callback(data);
  }, 1000);
}

function processData(data, callback) {
  setTimeout(() =&amp;gt; {
    const processed = data + &quot; &amp;rarr; 처리됨&quot;;
    console.log(&quot;2. 데이터를 처리했습니다.&quot;);
    callback(processed);
  }, 1000);
}

function displayResult(result) {
  console.log(&quot;3. 결과:&quot;, result);
}

// 실행
getData(function(data) {
  processData(data, function(result) {
    displayResult(result);
  });
});

--------------------------------
(1초 후) 1. 데이터를 가져왔습니다.  
(1초 후) 2. 데이터를 처리했습니다.  
        3. 결과: 데이터 &amp;rarr; 처리됨&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h4 data-end=&quot;1013&quot; data-start=&quot;1004&quot; data-ke-size=&quot;size20&quot;&gt;  설명&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;1113&quot; data-start=&quot;1015&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;1047&quot; data-start=&quot;1015&quot;&gt;getData() &amp;rarr; 1초 후 &quot;데이터&quot; 반환&lt;/li&gt;
&lt;li data-end=&quot;1079&quot; data-start=&quot;1048&quot;&gt;반환된 데이터를 processData()로 넘김&lt;/li&gt;
&lt;li data-end=&quot;1113&quot; data-start=&quot;1080&quot;&gt;처리된 결과를 displayResult()에서 출력&lt;/li&gt;
&lt;/ol&gt;
&lt;hr data-end=&quot;1406&quot; data-start=&quot;1403&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h4 data-end=&quot;1435&quot; data-start=&quot;1408&quot; data-ke-size=&quot;size20&quot;&gt;2. &lt;b&gt;Promise / Future&lt;/b&gt;&lt;/h4&gt;
&lt;blockquote data-end=&quot;1476&quot; data-start=&quot;1437&quot; data-ke-style=&quot;style2&quot;&gt;
&lt;p data-end=&quot;1476&quot; data-start=&quot;1439&quot; data-ke-size=&quot;size16&quot;&gt;작업의 성공/실패 결과를 약속하는 객체를 사용하여 흐름 제어&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1533&quot; data-start=&quot;1478&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1511&quot; data-start=&quot;1478&quot;&gt;장점: &lt;b&gt;체이닝(Chaining)&lt;/b&gt; 으로 가독성 향상&lt;/li&gt;
&lt;li data-end=&quot;1533&quot; data-start=&quot;1512&quot;&gt;단점: 예외 처리가 복잡할 수 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1750768524180&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function getData() {
    return new Promise((resolve, reject) =&amp;gt; {
        setTimeout(() =&amp;gt; {
            resolve(&quot;데이터&quot;);
        }, 1000);
    });
}

getData()
    .then(data =&amp;gt; console.log(data))
    .catch(error =&amp;gt; console.error(error));&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h4 data-end=&quot;810&quot; data-start=&quot;801&quot; data-ke-size=&quot;size20&quot;&gt;  설명&lt;/h4&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;957&quot; data-start=&quot;812&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;856&quot; data-start=&quot;812&quot;&gt;getData()는 1초 후 &quot;데이터&quot;를 반환하는 비동기 함수&lt;/li&gt;
&lt;li data-end=&quot;908&quot; data-start=&quot;857&quot;&gt;.then() 안의 콜백은 &lt;b&gt;작업이 성공(resolve)&lt;/b&gt; 되었을 때 실행됩니다.&lt;/li&gt;
&lt;li data-end=&quot;957&quot; data-start=&quot;909&quot;&gt;.catch()는 &lt;b&gt;작업이 실패(reject)&lt;/b&gt; 했을 때 에러를 처리합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-end=&quot;1634&quot; data-start=&quot;1631&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h4 data-end=&quot;1660&quot; data-start=&quot;1636&quot; data-ke-size=&quot;size20&quot;&gt;3. &lt;b&gt;Async / Await&lt;/b&gt;&lt;/h4&gt;
&lt;blockquote data-end=&quot;1699&quot; data-start=&quot;1662&quot; data-ke-style=&quot;style2&quot;&gt;
&lt;p data-end=&quot;1699&quot; data-start=&quot;1664&quot; data-ke-size=&quot;size16&quot;&gt;비동기 코드를 동기 코드처럼 작성할 수 있게 해주는 문법&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;1753&quot; data-start=&quot;1701&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;1717&quot; data-start=&quot;1701&quot;&gt;장점: 가독성 좋고 직관적&lt;/li&gt;
&lt;li data-end=&quot;1753&quot; data-start=&quot;1718&quot;&gt;단점: 구형 환경이나 일부 언어에서는 지원하지 않을 수 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre id=&quot;code_1750768985821&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;async function main() {
  try {
    const data = await getData();
    const processed = await processData(data);
    displayResult(processed);
  } catch (error) {
    console.error(&quot;에러 발생:&quot;, error);
  }
}

main();&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;hr data-end=&quot;1964&quot; data-start=&quot;1961&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h4 data-end=&quot;1989&quot; data-start=&quot;1966&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;⚠️ 비동기 프로그래밍 시 주의할 점&lt;/b&gt;&lt;/h4&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-end=&quot;2247&quot; data-start=&quot;1991&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li data-end=&quot;2061&quot; data-start=&quot;1991&quot;&gt;&lt;b&gt;동시성 문제(Concurrency)&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2061&quot; data-start=&quot;2023&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2061&quot; data-start=&quot;2023&quot;&gt;여러 작업이 동시에 실행되면서 예상치 못한 결과가 발생할 수 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;2110&quot; data-start=&quot;2063&quot;&gt;&lt;b&gt;복잡한 흐름 제어&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2110&quot; data-start=&quot;2085&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2110&quot; data-start=&quot;2085&quot;&gt;예외 처리, 상태 관리가 까다로울 수 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;2190&quot; data-start=&quot;2112&quot;&gt;&lt;b&gt;과도한 사용은 오히려 성능 저하&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2190&quot; data-start=&quot;2142&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2190&quot; data-start=&quot;2142&quot;&gt;필요하지 않은 곳에 비동기를 사용하면 오히려 디버깅이 어려워지고 CPU 리소스 낭비&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li data-end=&quot;2247&quot; data-start=&quot;2192&quot;&gt;&lt;b&gt;블로킹 코드 주의&lt;/b&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-end=&quot;2247&quot; data-start=&quot;2214&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li data-end=&quot;2247&quot; data-start=&quot;2214&quot;&gt;비동기 흐름 중 동기 함수가 전체 흐름을 막는 경우 있음&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&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: 100%; height: 95px;&quot; border=&quot;1&quot; data-end=&quot;2820&quot; data-start=&quot;2570&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 19px;&quot;&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;&lt;b&gt;항목&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;&lt;b&gt;동기(Synchronous)&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot;&gt;&lt;b&gt;비동기(Asynchronous)&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot; data-end=&quot;2691&quot; data-start=&quot;2668&quot;&gt;
&lt;td style=&quot;height: 19px;&quot; data-col-size=&quot;sm&quot; data-end=&quot;2676&quot; data-start=&quot;2668&quot;&gt;&lt;b&gt;실행 방식&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot; data-col-size=&quot;sm&quot; data-end=&quot;2682&quot; data-start=&quot;2676&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;순차적&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot; data-col-size=&quot;sm&quot; data-end=&quot;2691&quot; data-start=&quot;2682&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;병렬 가능&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot; data-end=&quot;2722&quot; data-start=&quot;2692&quot;&gt;
&lt;td style=&quot;height: 19px;&quot; data-col-size=&quot;sm&quot; data-end=&quot;2700&quot; data-start=&quot;2692&quot;&gt;&lt;b&gt;코드 흐름&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot; data-col-size=&quot;sm&quot; data-end=&quot;2710&quot; data-start=&quot;2700&quot;&gt;단순, 직관적&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot; data-col-size=&quot;sm&quot; data-end=&quot;2722&quot; data-start=&quot;2710&quot;&gt;복잡하지만 유연&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot; data-end=&quot;2763&quot; data-start=&quot;2723&quot;&gt;
&lt;td style=&quot;height: 19px;&quot; data-col-size=&quot;sm&quot; data-end=&quot;2728&quot; data-start=&quot;2723&quot;&gt;&lt;b&gt;성능&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot; data-col-size=&quot;sm&quot; data-end=&quot;2744&quot; data-start=&quot;2728&quot;&gt;작업 지연 시 전체 지연&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot; data-col-size=&quot;sm&quot; data-end=&quot;2763&quot; data-start=&quot;2744&quot;&gt;작업 병렬 처리로 성능 향상&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 19px;&quot; data-end=&quot;2820&quot; data-start=&quot;2764&quot;&gt;
&lt;td style=&quot;height: 19px;&quot; data-col-size=&quot;sm&quot; data-end=&quot;2773&quot; data-start=&quot;2764&quot;&gt;&lt;b&gt;적합한 상황&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot; data-col-size=&quot;sm&quot; data-end=&quot;2792&quot; data-start=&quot;2773&quot;&gt;작업 순서 중요, 단순한 로직&lt;/td&gt;
&lt;td style=&quot;height: 19px;&quot; data-col-size=&quot;sm&quot; data-end=&quot;2820&quot; data-start=&quot;2792&quot;&gt;I/O, 대기 많은 작업, 대규모 처리 필요&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;</description>
      <category>개발자 면접 노트</category>
      <author>해로몬</author>
      <guid isPermaLink="true">https://hyeromon.tistory.com/101</guid>
      <comments>https://hyeromon.tistory.com/101#entry101comment</comments>
      <pubDate>Tue, 24 Jun 2025 21:49:03 +0900</pubDate>
    </item>
  </channel>
</rss>