<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>ij_nim.log</title>
        <link>https://velog.io/</link>
        <description>백엔드 개발자를 준비하는 삐약이 대학생에서 ..  취준생🐣</description>
        <lastBuildDate>Tue, 29 Apr 2025 06:47:51 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>ij_nim.log</title>
            <url>https://velog.velcdn.com/images/ij_nim/profile/ae66c410-4008-41fd-af7a-e8153ab85372/image.jpeg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. ij_nim.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/ij_nim" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[kakao x goorm DEEP DIVE BE] 수료 후기]]></title>
            <link>https://velog.io/@ij_nim/kakao-x-goorm-DEEP-DIVE-BE-%EC%88%98%EB%A3%8C-%ED%9B%84%EA%B8%B0</link>
            <guid>https://velog.io/@ij_nim/kakao-x-goorm-DEEP-DIVE-BE-%EC%88%98%EB%A3%8C-%ED%9B%84%EA%B8%B0</guid>
            <pubDate>Tue, 29 Apr 2025 06:47:51 GMT</pubDate>
            <description><![CDATA[<p>드디어 지난 4월 2일! 딥다이브 백엔드 과정을 수료했다.
매주 활동 내용을 기록하고 싶었는데 수업과 프로젝트를 병행하면서 블로그도 병행한다는건 정말.. 어려운 일이었다. 그래서 프로젝트 회고록만 따로 기록해두었다.</p>
<p><img src="https://velog.velcdn.com/images/ij_nim/post/b9b97cb3-dddd-40e2-b5d8-272e82f6e9ba/image.png" alt=""></p>
<p>최종적으로 마지막 프로젝트에서 우수상을 받게되서 기뻤고 보상 받는 것 같아 행복했다. ㅎ</p>
<p><img src="https://velog.velcdn.com/images/ij_nim/post/93c929e8-7774-41e2-9bcc-da9d0e999c70/image.png" alt="">
수료식날 남은 시간동안 게임도 진행했는데 내가 백엔드 1등을 차지해서 스벅 깊티도 받았다 ㅎㅎ</p>
<p>요즘 내 딥다이브 글에 댓글들이 많이 달려서 지금까지 수업들은 과정들도 조금 적어보려고 한다.
교육은 2024년 8월 19일에 시작해서 원래는 2025년 3월에 끝나는 과정이었는데 합반프로젝트 때문에 일정이 미뤄져서 중간에 쉬는날이 더 생기고 4월 2일에 수료하게되었다. </p>
<p>과정은 오티만 오프라인으로 진행했고 수업과 수료식은 온라인으로 진행했다.
수료식은 오프라인으로 하는 경우도 있는데 이건 그때 상황에 따라 다른것같았다.</p>
<p>8월 19일부터 12월 초까지는 오전9시 ~ 11시 까지 강사님의 실시간 강의를 듣고 12시 ~ 1시는 점심시간 그 이후 시간은 그날그날 주어지는 과제와 각자 스터디 활동을 진행했다. 오티 날 스터디 팀원들을 정할시간을 주는데 저 긴 시간동안 혼자서 무언가 할 계획이 없다면,, 스터디 팀원들을 오티 날 꼭 정하고 오는게 좋은것 같다. 나는 운이 좋게도 좋은 팀원들을 만나서 수료 이후에도 스터디를 함께 진행하고 있을 정도로 도움이 많이 되었다. 그래서 처음 3~4개월 동안은 따로 스터디를 하지 않는다면 조금 하는게 없나..? 라고 느껴질 수도 있다. 나는 전공자라서 그럴수도 있지만 비전공자라면 수업 따라오기도 벅찼을 수 있을 것 같긴하다.</p>
<p>그리고 12월 중순 ~ 4월 2일까지 프로젝트를 4개를 진행했다. 
이때 기술적으로 많이 성장한다는 느낌을 받았고 지금까지 개인 프로젝트를 진행했을때는 성과를 내는 결말까지 보기가 힘들었는데 어쨌든 다른 팀원들과 무조건 발표날까지 마무리해서 발표를 해야했기에 더 열심히 참여했고, 팀원들에게서 배우는 것도 많았다. 그리고 카카오 멘토님들과도 중간중간 멘토링의 기회가 주어지는데 이것도 도움이 되었다. </p>
<p>프로젝트는 </p>
<ol>
<li>버깅/디버깅 프로젝트</li>
<li>고객만족요구 프로젝트</li>
<li>카카오맵 api 활용 프로젝트</li>
<li>합반 프로젝트 
이렇게 각 2주-3주-4주-한달조금넘게? 진행했던 것 같다. 프로젝트 수행 기간이 길지 않아서
여유는 없었다...ㅎㅎ </li>
</ol>
<p>내가 백엔드 과정 1회차라서 다른 수강생들의 후기 없이 그냥 나와있는 부트캠프 설명만으로 지원하고 수료까지 하게 되었는데 개인적으로 100% 만족까진 아니지만 결론적으로 이 부트캠프를 통해 많이 성장하기도 했고 지원해주는것도 좀 있었기에 고민하고 있다면 일단 해보라고 추천할 것 같다 처음에 그만두는 사람들도 꽤 많았고 중간중간 다른 부트캠프로 빠지는 사람도 있긴했다. 개인적으로 처음 3~4개월동안은 본인의 의지가 가장 중요하지 않을까 싶다.</p>
<p>중간에 나도 싸피에 지원했었고 그러면서 많은 후기들을 보았는데 모든 부트캠프가 자기 하기 나름인 것 같다.
그렇게 인기 많은 싸피도 후기를 보면 부정적인 후기가 참 많았던지라.. 해보고 본인이 결정하는 것이 나을 것 같다.</p>
<p>교육듣는동안 교육비 한달에 30정도?랑 gpt 지원, 교보문고 도서구매지원(약10만원), 인프런 강의 지원(지정 강의) 등등 혜택이 있었어서 나쁘지 않았다고 생각한다.</p>
<p>그리고 교육 끝자락부터 이후 6개월까지 컨설팅 상담도 가능하고 매달 취업콘서트와 커밋행사도 열려서 좋은 것 같다.
나도 수료 이후에 컨설팅 상담 이용하고 있는데 Mia님이 상담을 잘해주셔서 도움이 많이 되고 있다. </p>
<p>이상 수료 ... 끝!</p>
<p><img src="https://velog.velcdn.com/images/ij_nim/post/d66dc29a-18b5-45bf-9422-95e97260bd94/image.jpeg" alt="">
이건 수료이후 증정되는 웰컴키트이다. 우리 교육이 카카오랑 구름이 함께하는거라서 굿즈도 카테부 굿즈랑 동일했다. 에코백 받을 줄 알았는데 꽤 좋은 가방을 받아서 유용하게 잘쓸것같다..ㅎㅎ 
<img src="https://velog.velcdn.com/images/ij_nim/post/207c398b-d8e6-48c9-b66a-8d9c854a10b7/image.jpeg" alt="">
크록스에 다니까 꽤나 귀여웠다.. <del>(동생한테 빼앗겼지만 ..)</del></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[합반 프로젝트 프로젝트 회고록 / 대규모 핀테크 사일런트 컨퍼런스]]></title>
            <link>https://velog.io/@ij_nim/%ED%95%A9%EB%B0%98-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%ED%9A%8C%EA%B3%A0%EB%A1%9D-%EB%8C%80%EA%B7%9C%EB%AA%A8-%ED%95%80%ED%85%8C%ED%81%AC-%EC%82%AC%EC%9D%BC%EB%9F%B0%ED%8A%B8-%EC%BB%A8%ED%8D%BC%EB%9F%B0%EC%8A%A4</link>
            <guid>https://velog.io/@ij_nim/%ED%95%A9%EB%B0%98-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%ED%9A%8C%EA%B3%A0%EB%A1%9D-%EB%8C%80%EA%B7%9C%EB%AA%A8-%ED%95%80%ED%85%8C%ED%81%AC-%EC%82%AC%EC%9D%BC%EB%9F%B0%ED%8A%B8-%EC%BB%A8%ED%8D%BC%EB%9F%B0%EC%8A%A4</guid>
            <pubDate>Mon, 07 Apr 2025 06:45:49 GMT</pubDate>
            <description><![CDATA[<h1 id="대규모-핀테크-사일런트-컨퍼런스">대규모 핀테크 사일런트 컨퍼런스</h1>
<h1 id="1️⃣-개요">1️⃣ 개요</h1>
<h2 id="프로젝트-주제💡">프로젝트 주제💡</h2>
<p>: 대규모 핀테크 컨퍼런스에서 발생하는 비효율적인 운영 및 참가자의 불편을 해결하는 모바일 웹 기반 사일런트 컨퍼런스 솔루션</p>
<hr>
<h2 id="프로젝트-목표🚀">프로젝트 목표🚀</h2>
<p>참가자가 온·오프라인에서 능동적으로 참여할 수 있도록 지원하며, 컨퍼런스 운영의 효율성과 만족도를 높이는 올인원 솔루션을 제공합니다.</p>
<hr>
<h2 id="프로젝트-내용📝">프로젝트 내용📝</h2>
<h3 id="수행-방법">수행 방법</h3>
<ul>
<li><strong>1주차</strong>: 최종 기획안 작성 + 요구사항 파악 및 분석, 사용자 중심 웹 디자인과 개발 전략 수립</li>
<li><strong>2~5주차</strong>:<ul>
<li>시스템 아키텍처 설계, 데이터베이스 설계</li>
<li>애자일 방법론 기반 반복적 개발 프로세스 수행</li>
<li>성능 최적화 및 보안 검토</li>
<li>기타 편의 기능 개발</li>
</ul>
</li>
<li><strong>6주차</strong>: 최종 산출물 정리 및 발표, 프로젝트 성과 평가 및 개선안 제시</li>
<li>주차별 세부 일정과 산출물 정리는 해당 팀의 PM이 진행</li>
</ul>
<hr>
<h2 id="프로젝트-배경🖼️">프로젝트 배경🖼️</h2>
<p>혼잡한 강연장, 강연 선택의 어려움, 비효율적 질의응답, 세션 간 이동 어려움, 높은 운영 비용 등 기존 컨퍼런스의 문제점을 개선하고자 기존 스피커 시스템 대신 무선 헤드셋을 활용하여 한 공간에서 여러 개의 세션을 동시에 진행할 수 있는 혁신적이 포럼 방식의 사일런트 컨퍼런스를 선택하였습니다. 또한 시장의 성장 가능성을 고려하여 핀테크 컨퍼런스를 선정하였습니다.</p>
<hr>
<h1 id="2️⃣-일정">2️⃣ 일정</h1>
<h2 id="프로젝트의-시작일과-종료일📆">프로젝트의 시작일과 종료일📆</h2>
<p>시작일: 2025년 2월 26일
종료일: 2025년 4월 2일</p>
<hr>
<h2 id="작업-계획🗓️">작업 계획🗓️</h2>
<p><img src="https://velog.velcdn.com/images/ij_nim/post/83b857c1-e4f0-4aa3-9b6e-c987fe2cfcb3/image.png" alt=""></p>
<hr>
<h1 id="3️⃣-프로젝트-팀-구성">3️⃣ 프로젝트 팀 구성</h1>
<h3 id="팀-구성원들의-역할과-책임👑">팀 구성원들의 역할과 책임👑</h3>
<p><img src="https://velog.velcdn.com/images/ij_nim/post/f50e4e49-c93a-443a-a95e-3c230fc5913f/image.png" alt="">
김지민(본인)</p>
<ul>
<li>ERD 설계</li>
<li>채팅 기능 설계 및 개발</li>
</ul>
<hr>
<h1 id="4️⃣-기술-스택-및-사용-도구">4️⃣ 기술 스택 및 사용 도구</h1>
<h4 id="pd">PD</h4>
<ul>
<li>Figma</li>
</ul>
<h4 id="fe">FE</h4>
<ul>
<li>Core: React - js</li>
<li>UI: tailwindCss</li>
<li>State Managing: redux</li>
<li>Bundler: Vite</li>
</ul>
<h4 id="be-my-part">BE (My part)</h4>
<ul>
<li>SpringBoot</li>
<li>Spring Security</li>
<li>Docker</li>
<li>OAuth2</li>
<li>JPA</li>
<li>MySQL</li>
<li>Redis</li>
<li>Swagger</li>
<li>AWS</li>
<li>WebSocket</li>
<li>Redis Pub/Sub</li>
<li>Kurento</li>
</ul>
<hr>
<h1 id="5️⃣-아키텍처">5️⃣ 아키텍처</h1>
<p><strong>시스템 아키텍처</strong>
<img src="https://velog.velcdn.com/images/ij_nim/post/5a30be18-bba1-42c7-9899-a4b97caaa462/image.png" alt="">
<strong>플로우 차트</strong>
<img src="https://velog.velcdn.com/images/ij_nim/post/f9f5f299-34eb-47dc-bf82-1e9b0ee28364/image.png" alt=""></p>
<hr>
<h1 id="6️⃣-기능-설명">6️⃣ 기능 설명</h1>
<ol>
<li>모바일 웹 오디오 스트리밍 - 강연장 혼잡 시 온라인 스트리밍 대체 옵션 제공</li>
<li>실시간 혼잡도 제공 - 강연장 체크인 데이터를 활용한 실시간 좌석 및 인원 분석</li>
<li>실시간 Q&amp;A 및 투표 - 모바일을 통한 질문 및 투표 기반 인기 질문 상위 노출</li>
<li>강연 미리담기 시스템 - 관심 강연을 사전 등록하여 일정 최적화</li>
<li>맞춤 강연 추천 - 참가자의 관심사를 분석하여 맞춤 강연 추천</li>
</ol>
<hr>
<h1 id="7️⃣도전과제-및-해결책">7️⃣도전과제 및 해결책</h1>
<ol>
<li>채팅 화면에는 전송자 이름이 보여야하는데, 채팅은 쓰기랑 조회가 많아 mysql에 이름으로 계속 접근해도 괜찮을까 하는 우려사항 존재
➡️ Redis에는 userId만 저장하고, 조회할 때 userId → name을 매핑하는 방식으로 구현</li>
</ol>
<hr>
<ol start="2">
<li>전체 메시지가 아닌 각 세션의 채팅방 당 메시지 개수가 1000개만 유지되도록 구현해야하는데, 세션별로 처리하지 못했음<pre><code>// 기존 방식
// 메시지 1000개 유지
     if (redisTemplate.opsForList().size(CHAT_LIST_KEY) &gt; MAX_CHAT_SIZE) {</code></pre>➡️ (CHAT_LIST_KEY + sessionId)로 처리하도록 변경 피드백 받음<pre><code>private static final String CHAT_MESSAGE_KEY_PREFIX = &quot;chat-messages:&quot;;  // 메시지 저장용
private static final int MAX_CHAT_SIZE = 1000;</code></pre><pre><code>String chatKey = CHAT_MESSAGE_KEY_PREFIX + message.getSessionId();</code></pre>chatKey에 세션아이디를 포함시키고<pre><code>redisTemplate.opsForList().trim(chatKey, -MAX_CHAT_SIZE, -1);</code></pre>리스트 크기 1000개로 유지</li>
</ol>
<hr>
<ol start="3">
<li>페이징 처리 이슈<pre><code>// 기존 방식
List&lt;Object&gt; rawMessages = chatRepository.getRecentMessages(String.valueOf(sessionId));
</code></pre></li>
</ol>
<pre><code>Redis에서 전체 메시지 조회 후 QUESTION 카테고리만 필터링 하여 좋아요 수 기준으로 정렬 후, Pageable 기준으로 자바에서 페이징하는 방식으로 구현
⬇️
그러나, 페이징 처리를 통해 일정 부분씩 끊어서 조회하여 데이터로딩에 대한 부하를 줄이는 장점이 있는데, 레디스에서 전체 조회 후 자바에서 페이징처리해도 부하를 줄일 수 있을지에 대한 의문 발생
⬇️
Redis List를 사용하고 있어서 전체 조회 후 페이징 처리를 하는 방법을 선택했었는데, 메시지 개수가 많아지면 부하를 줄이기 어려울 것 같다고 생각
⬇️
찾아본 결과 List는 전체를 가져와서 잘라야 하고,
ZSet은 정렬된 상태에서 원하는 범위만 잘라서 가져올 수 있다고 함.
레디스는 읽기 속도가 빨라서 1000개정도까진 무리없어서 전체조회 후 자바에서 페이징처리해도 괜찮을 것 같다는 의견도 있지만, 실시간 좋아요 수에 따른 실시간 질문 정렬이 가능하도록 하기 위해서 ZSet으로 리팩토링 하는 방향으로 결정하여 해결했음

---------
4. 유저 아이디 관련 이슈
프론트 개발자에게서 들어온 이슈
&gt; &quot;우리가 유저 정보를 조회할 때 사용하는 두 API:
/api/v1/users/account
/api/v1/users/profile
이 API들의 응답(Response)에는 userId가 안 들어있는데,
그럼 우리가 ChatMessage를 생성할 때 필요한 userId는 어디서 가져와야 해?&quot;

지금 프론트엔드는 서버에 메시지를 보낼 때 userId를 포함해야 하는 상황인데,
현재 제공된 API 중 어디에도 userId가 포함돼 있지 않은 상황
1. DTO에 userId를 추가
2. ChatMessage에서 userId 대신 email 사용

➡️ 두가지 방법을 논의했으나, Spring Security가 로그인한 유저의 정보를 담아주는 객체 Principal을 사용하는 것으로 결정

- principal.getName() → 기본적으로 유저의 email이 들어 있음
- 굳이 프론트에서 userId나 email을 따로 보내지 않아도 됨
- 백엔드는 JWT 토큰 기반으로 유저 정보 확인하고, Principal을 채워줌

&gt; 💡 프론트는 단순하게 요청만 보내면 되고, 백엔드는 Principal로 유저 식별 가능

---------

5. 네이밍 이슈
![](https://velog.velcdn.com/images/ij_nim/post/ecc423f9-3be4-455a-b923-4b2bead1ac0e/image.png)
레디스 키 네임을 중복으로 사용하여 충돌발생
➡️ 중복되지 않게 키 네임을 역할에 따라 각각 설정해줌

-------

6. 메시지 찾을 수 없음 에러 발생
레디스 키 네임 수정 미반영으로 인한 에러를 확인하고 추가적으로</code></pre><p>String messageKey = &quot;chat-messages:&quot; + message.getMessageId();</p>
<pre><code>채팅 메시지 저장 시, 메시지 아이디를 키 값으로 저장하여 메시지를 제대로 불러올 수 있도록 하여 에러 해결


--------

7. timestamp 파싱 에러
**현재 상황**</code></pre><p>Text &#39;2025-03-29T22:16:19.342572147&#39; could not be parsed, unparsed text found at index 19</p>
<pre><code>&quot;2025-03-29T22:16:19.342572147&quot;는 나노초 단위까지 포함된 ISO-8601 포맷,
근데 기본적으로 Jackson + JavaTimeModule 조합은 나노초까지는 처리 못 함. 최대 마이크로초 (6자리)까지만 지원

즉, Jackson이 timestamp를 LocalDateTime으로 파싱할 때 &quot;.342572147&quot;에서 뒷자리까지 파싱 못 해서 실패</code></pre><p>// 💡 LocalDateTime 직렬화 시 나노초 제거 (기존 오류 해결용)
        objectMapper.configOverride(LocalDateTime.class)
            .setFormat(JsonFormat.Value.forPattern(&quot;yyyy-MM-dd&#39;T&#39;HH:mm:ss&quot;));</p>
<pre><code>➡️ 나노초를 제거하여 에러 해결

---------
# 8️⃣ 결과 및 성과
기능 구현 결과
![](https://velog.velcdn.com/images/ij_nim/post/8bae8b09-a3f3-4751-9a6b-3fcfe449b985/image.png)
![](https://velog.velcdn.com/images/ij_nim/post/5cd64823-25bc-45f7-9321-f12587572a7b/image.png)
![](https://velog.velcdn.com/images/ij_nim/post/949c624c-6895-4253-b966-718784ef198a/image.png)
![](https://velog.velcdn.com/images/ij_nim/post/e594d0c7-c702-4835-8103-4c9aaf11a507/image.png)
![](https://velog.velcdn.com/images/ij_nim/post/25cda99d-6f1e-4de0-9301-cba1b3ff0be0/image.png)


---------

# 9️⃣ 향후 계획
1. 혼잡도 분석
- IoT 센서 및 Beacon으로 출입 자동 체크
- 푸시 알림 기능
➡️ 강연장 혼잡 완화, 참가자의 이동 효율성 증가

2. 실시간 Q&amp;A
- NLP로 중복 질문 그룹화
- AI가 주요 질문 요약
➡️ 참여 만족도 향상, 상호 간 명확한 의사소통

3. 강연 미리담기
- 외부 캘린더 연동
- 맞춤 세션 일정 자동 추천
➡️ 개인 일정과 컨퍼런스 일정 통합 관리 가능

4. AI 강연 추천
- 머신 러닝 알고리즘 및 피드백 루프 추가(실제 유저 참여 데이터 반영)
➡️ 정교한 추천 경험 제공, 참여율 및 세션 집중도 향상

---------

# 🔟 후기 및 배운 점
처음으로 PM, PD, 프론트엔드 개발자와 협업하며 프로젝트를 진행했습니다. 이전에는 백엔드 개발자끼리만 팀을 이뤄 작업했기 때문에 기술적인 부분에 대해 깊이 설명하지 않아도 소통이 원활했지만, 이번에는 다른 분야의 팀원들과 함께하다 보니 PM과 PD에게 기술적인 내용을 쉽게 풀어 설명하는 데 어려움을 느꼈고, 프론트엔드 개발자와의 협업 방식도 새롭게 배울 수 있는 계기가 되었습니다.

특히 프로젝트 막바지에는 소통이 원활히 이루어지지 않아 시간 부족으로 인해 완성도가 다소 아쉬웠던 점도 있었지만, 이러한 경험을 통해 개발 일정 공유와 커뮤니케이션의 중요성을 깊이 깨닫게 되었습니다. 또한, 그동안 백엔드 입장에서만 작성하던 API 명세서를 프론트엔드 개발자에게도 도움이 될 수 있도록 구성하는 법을 고민해보며 협업 역량을 키울 수 있었습니다.

이번 프로젝트에서는 처음으로 채팅 기능을 직접 설계하고 구현해보았는데, WebSocket, STOMP, Redis Pub/Sub 등 익숙하지 않던 기술들을 다뤄보며 부족한 점이 많았음을 느꼈습니다. 특히, 혼자 개발할 때는 잘 느끼지 못했던 로그의 중요성과 에러 추적의 필요성을 프론트와의 협업 과정에서 실감할 수 있었습니다. 이번 경험을 바탕으로, 다음에는 보다 구조적이고 안정적인 채팅 시스템을 구현할 수 있을 것이라는 자신감도 생겼습니다.

---------

# 📌 마무리
이번 사일런트 컨퍼런스 프로젝트는 단순한 기능 구현을 넘어 실제 사용자 환경을 고려한 문제 해결 중심의 개발 경험이었습니다. 핀테크라는 주제를 통해 실시간 데이터 처리, 사용자 참여 유도, 시스템 아키텍처 구성 등 현업과 유사한 문제 상황을 경험해볼 수 있었고, 그 과정에서 기술적 역량뿐 아니라 팀원과의 원활한 커뮤니케이션 역량 역시 중요하다는 것을 몸소 느꼈습니다.

특히 실시간 채팅 기능을 처음부터 끝까지 직접 설계하고 구현하면서, Redis, WebSocket, STOMP, ZSet 등 새로운 기술 스택을 익히고 적용해볼 수 있었으며, 실시간성과 효율성, 확장성을 동시에 고려한 백엔드 개발이 얼마나 중요한지를 깨닫는 계기가 되었습니다.

이 프로젝트는 단발성으로 끝나는 서비스가 아닌, 실제 현장에 적용 가능하고 확장 가능한 플랫폼으로의 발전 가능성을 지니고 있습니다. 향후 IoT 기반 출입 체크, AI 기반 Q&amp;A 정리 및 추천 시스템 등과 연계된다면, 단순한 행사 보조 시스템을 넘어 미래형 스마트 컨퍼런스 플랫폼으로 성장할 수 있을 것이라 기대됩니다.

이번 경험을 통해 얻은 지식과 교훈을 바탕으로, 다음 프로젝트에서는 더욱 완성도 높은 시스템을 설계하고 구현할 수 있도록 노력하겠습니다.

---------

# 🔗 참고 자료 및 링크
[BE-GitHub](https://github.com/FiT-8-plus-1-BiT/backend.git)</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[카카오지도 API로 주소-상호명 재정리 API 팀 프로젝트 회고록 / 반려동물 산책 동반자 찾기 시스템]]></title>
            <link>https://velog.io/@ij_nim/%EC%B9%B4%EC%B9%B4%EC%98%A4%EC%A7%80%EB%8F%84-API%EB%A1%9C-%EC%A3%BC%EC%86%8C-%EC%83%81%ED%98%B8%EB%AA%85-%EC%9E%AC%EC%A0%95%EB%A6%AC-API-%ED%8C%80-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%ED%9A%8C%EA%B3%A0%EB%A1%9D-%EB%B0%98%EB%A0%A4%EB%8F%99%EB%AC%BC-%EC%82%B0%EC%B1%85-%EB%8F%99%EB%B0%98%EC%9E%90-%EC%B0%BE%EA%B8%B0-%EC%8B%9C%EC%8A%A4%ED%85%9C</link>
            <guid>https://velog.io/@ij_nim/%EC%B9%B4%EC%B9%B4%EC%98%A4%EC%A7%80%EB%8F%84-API%EB%A1%9C-%EC%A3%BC%EC%86%8C-%EC%83%81%ED%98%B8%EB%AA%85-%EC%9E%AC%EC%A0%95%EB%A6%AC-API-%ED%8C%80-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%ED%9A%8C%EA%B3%A0%EB%A1%9D-%EB%B0%98%EB%A0%A4%EB%8F%99%EB%AC%BC-%EC%82%B0%EC%B1%85-%EB%8F%99%EB%B0%98%EC%9E%90-%EC%B0%BE%EA%B8%B0-%EC%8B%9C%EC%8A%A4%ED%85%9C</guid>
            <pubDate>Fri, 04 Apr 2025 07:44:18 GMT</pubDate>
            <description><![CDATA[<h1 id="dangdangcrew">DangDangCrew</h1>
<h1 id="1️⃣-개요">1️⃣ 개요</h1>
<h2 id="프로젝트-주제💡">프로젝트 주제💡</h2>
<h4 id="대주제">대주제</h4>
<p>: 카카오지도 API로 주소-상호명 재정리 API </p>
<ul>
<li>카카오지도 API를 활용하여 주소 데이터를 기준으로 상호명을 체계적으로 정리하는 맞춤형 API를 개발합니다.</li>
<li>사용자들이 원하는 정보를 신속하게 검색할 수 있으며, 위치 기반 서비스의 신뢰성과 효율성을 높이는 것을 목표로 합니다.</li>
</ul>
<h4 id="소주제">소주제</h4>
<p>반려동물 산책 동반자 찾기 시스템</p>
<hr>
<h2 id="프로젝트-목표🚀">프로젝트 목표🚀</h2>
<ul>
<li><strong>Kakao Maps API 를 활용한 위치 기반 산책 장소 탐색</strong><ul>
<li>카카오 지도 api 를 활용하여 사용자의 현재 위치에서(혹은 검색 위치) 반려동물 출입 가능 장소(공원, 애견 동반 카페, 애견 동반 식당) 를 조회하고 지도에 표시</li>
<li>사용자가 직접 원하는 산책 장소를 선택하고 모임을 생성하여 동반자를 모집할  수 있도록 함</li>
</ul>
</li>
<li><strong>실시간 반려동물 동반자 매칭 시스템 구축</strong><ul>
<li>게시글 기반 모집 시스템을 도입하여 사용자가 원하는 시간과 장소에서  함께 산책 할 파트너를 쉽게 찾을 수 있도록 함</li>
<li>지역 커뮤니티 활성화를 위해 동반자 모집 기능 최적화</li>
</ul>
</li>
<li><strong>실시간 채팅 기능 구현(WebSocket 활용)</strong><ul>
<li>WebSocket 을 활용하여 참가자들끼리 실시간 채팅 가능</li>
<li>산책 시간/장소 조율 및 추가 정보 공유 가능</li>
<li>지도 공유 기능 → 선택한 공원/카페 위치를 채팅방 내에서 직접 확인</li>
</ul>
</li>
<li><strong>사용자 신뢰도 기반 후기 및 평가 시스템 구축</strong><ul>
<li>산책 모임 종료 후 매너 평가 시스템 도입(”약속을 잘 지켰나요?”, “강아지가 온순하고 활발한가요?” 등)</li>
<li>후기 및 신뢰도를 기반으로 매너 좋은 사용자에게 혜택 제공(우수 이용자 칭호 및 배지)</li>
</ul>
</li>
<li><strong>Redis 를 활용한 실시간 데이터 처리 최적화</strong>
• 유저의 참가 신청 트래픽 분석을 통해 인기 있는 반려동물 동반 장소(카페, 공원)를 실시간으로 감지하고 알림 제공</li>
</ul>
<hr>
<h2 id="프로젝트-내용📝">프로젝트 내용📝</h2>
<h3 id="수행-방법">수행 방법</h3>
<ol>
<li><strong>요구사항 분석</strong><ul>
<li>주요 기능 정의</li>
<li>사용자 시나리오 정리</li>
<li>API 기능 목록 작성</li>
<li>비즈니스 로직 명세화</li>
</ul>
</li>
<li><strong>데이터베이스 설계</strong><ul>
<li>ERD 설계</li>
<li>Redis 등 캐싱 시스템 고려</li>
</ul>
</li>
<li><strong>RESTful API 개발</strong><ul>
<li>API 엔드포인트 설계</li>
<li>HTTP Method와 응답 코드 설계</li>
<li>API 문서 작성</li>
<li>보안 적용</li>
<li>데이터 검증 및 예외처리 추가</li>
</ul>
</li>
<li><strong>테스트</strong><ul>
<li>유닛 및 통합테스트 진행</li>
</ul>
</li>
<li><strong>배포 및 유지보수</strong><ul>
<li>CI/CD 구축</li>
<li>모니터링 시스템 적용</li>
<li>오류 로깅</li>
</ul>
</li>
<li><strong>성능 평가 및 개선</strong><ul>
<li>API 응답 속도 측정 및 개선</li>
<li>Redis 등을 이용하여 캐싱 적용</li>
<li>DB 인덱스 최적화</li>
</ul>
</li>
<li><strong>마무리</strong><ul>
<li>성과물 정리</li>
<li>발표 준비</li>
</ul>
</li>
</ol>
<hr>
<h2 id="프로젝트-배경🖼️">프로젝트 배경🖼️</h2>
<p>반려인들끼리 교류하고 정보를 공유할 수 있는 모임을 쉽게 만들기 어렵고 반려동물 동반 가능 장소를 찾는 것에 대한 어려움을 해소하기 위해 반려동물 동반 가능 점포를 쉽게 확인할 수 있고, 모임 생성 및 참여할 수 있는 서비스를 제공</p>
<hr>
<h1 id="2️⃣-일정">2️⃣ 일정</h1>
<h2 id="프로젝트의-시작일과-종료일📆">프로젝트의 시작일과 종료일📆</h2>
<p>시작일: 2025년 2월 4일
종료일: 2025년 2월 21일</p>
<hr>
<h2 id="작업-계획🗓️">작업 계획🗓️</h2>
<h4 id="사전-기획">사전 기획</h4>
<p><img src="https://velog.velcdn.com/images/ij_nim/post/5a17b559-1463-4416-8946-b90aec2d1c10/image.png" alt=""></p>
<h4 id="실제-개발-기간">실제 개발 기간</h4>
<p><img src="https://velog.velcdn.com/images/ij_nim/post/09ca3cf9-5c9c-484e-8ae8-c1ff73c403f4/image.png" alt=""></p>
<hr>
<h1 id="3️⃣-프로젝트-팀-구성">3️⃣ 프로젝트 팀 구성</h1>
<h3 id="팀-구성원들의-역할과-책임👑">팀 구성원들의 역할과 책임👑</h3>
<h4 id="공통-작업">공통 작업</h4>
<ul>
<li>테스트 코드</li>
<li>ERD 설계</li>
<li>요구사항 정리 및 사용자 시나리오 작성</li>
</ul>
<h4 id="개별-작업">개별 작업</h4>
<p><strong>김지민(본인)</strong></p>
<ul>
<li>유저 도메인<ul>
<li>회원가입/로그인</li>
<li>보안, 인가, 인증 적용 (jwt)</li>
</ul>
</li>
<li><em>정태민*</em></li>
<li>유저 평가 도메인<ul>
<li>평점</li>
<li>평가 내용</li>
</ul>
</li>
<li><em>강형준*</em></li>
<li>장소 도메인</li>
<li>알림 도메인<ul>
<li>실시간 인기 점포 알림 시스템 적용 (SSE)</li>
</ul>
</li>
<li>배포 및 CI/CD 구축</li>
<li>모니터링 서버 구축</li>
<li><em>이지수*</em></li>
<li>모임 도메인<ul>
<li>모임 상세페이지</li>
<li>개인 모임 조회</li>
</ul>
</li>
<li>프로토타입 제작</li>
<li><em>임영광*</em></li>
<li>채팅 도메인<ul>
<li>장소 별 채팅 기능 적용 (WebSocket)</li>
</ul>
</li>
<li>프로토타입 제작</li>
</ul>
<hr>
<h1 id="4️⃣-기술-스택-및-사용-도구">4️⃣ 기술 스택 및 사용 도구</h1>
<h4 id="기술-스택">기술 스택</h4>
<ul>
<li>Java</li>
<li>Spring Boot</li>
<li>JWT</li>
<li>MongoDB</li>
<li>Websocket</li>
<li>Redis</li>
<li>MySQL</li>
<li>Prometheus</li>
<li>Grafana</li>
<li>SSE</li>
<li>AWS<h4 id="사용-도구">사용 도구</h4>
</li>
<li>IntelliJ IDEA</li>
<li>GitHub</li>
<li>Postman</li>
<li>Swagger</li>
<li>Docker</li>
</ul>
<hr>
<h1 id="5️⃣-아키텍처">5️⃣ 아키텍처</h1>
<h4 id="erd">ERD</h4>
<p><img src="https://velog.velcdn.com/images/ij_nim/post/4da9bedf-d2e8-47fe-b14c-a828ac11d969/image.png" alt=""></p>
<h4 id="유저-도메인">유저 도메인</h4>
<p><img src="https://velog.velcdn.com/images/ij_nim/post/fe6f542f-e1f4-4825-8ca8-6b88d94ba118/image.png" alt=""></p>
<h4 id="모임-도메인">모임 도메인</h4>
<p><img src="https://velog.velcdn.com/images/ij_nim/post/88720b05-f754-4b84-8fd4-4ed1a2406555/image.png" alt=""></p>
<h4 id="모임-평가-도메인">모임, 평가 도메인</h4>
<p><img src="https://velog.velcdn.com/images/ij_nim/post/658cd13c-d43f-480f-a98c-c162f9c62198/image.png" alt=""></p>
<h4 id="장소-도메인">장소 도메인</h4>
<p><img src="https://velog.velcdn.com/images/ij_nim/post/c8ca2c0b-fc68-4256-bc44-dc3d4bbc6a3c/image.png" alt=""></p>
<h4 id="채팅-도메인">채팅 도메인</h4>
<p><img src="https://velog.velcdn.com/images/ij_nim/post/bc7e66cd-cc53-4134-9b93-da9a3515466e/image.png" alt="">
<img src="https://velog.velcdn.com/images/ij_nim/post/4090ab38-91e6-487a-8d1b-0f554849e12e/image.png" alt=""></p>
<h4 id="알림-도메인">알림 도메인</h4>
<p><img src="https://velog.velcdn.com/images/ij_nim/post/1760d841-ff4a-43fa-b68c-e8cd718d5b33/image.png" alt="">
<img src="https://velog.velcdn.com/images/ij_nim/post/9d124447-eb3d-4ba9-8ab7-c565671b6fed/image.png" alt=""></p>
<h4 id="sse-도메인">SSE 도메인</h4>
<p><img src="https://velog.velcdn.com/images/ij_nim/post/6b8c4b0b-ab15-4758-9ef3-314af8e85f57/image.png" alt="">
<img src="https://velog.velcdn.com/images/ij_nim/post/2c243179-647d-4a0e-82b4-4a19ff5613ba/image.png" alt="">
<img src="https://velog.velcdn.com/images/ij_nim/post/757601fb-411e-447b-bc75-03343ea41580/image.png" alt=""></p>
<hr>
<h1 id="6️⃣-기능-설명">6️⃣ 기능 설명</h1>
<h4 id="회원가입">회원가입:</h4>
<p>회원가입 시 MySQL에 유저정보가 등록됩니다.</p>
<h4 id="로그인">로그인:</h4>
<p>사용자의 인증 정보를 검증하여 로그인합니다.</p>
<p>인증이 완료되면 Access Token과 Refresh Token이 발급됩니다.
Access Token은 클라이언트가 서버에 요청할 때 인증에 사용됩니다.
Refresh Token은 Redis에 저장되며, Access Token이 만료될 경우 새로운 Access Token을 발급받는 데 사용됩니다.</p>
<h4 id="로그아웃">로그아웃:</h4>
<p>사용자 인증을 해제하고, 세션을 종료합니다.
Redis에서 저장된 RefreshToken이 삭제되어 더 이상 액세스 토큰을 갱신할 수 없습니다.</p>
<h4 id="모임-생성">모임 생성:</h4>
<p>카카오 맵을 통해 사용자가 지정한 위치에 해당하는 애견 동반 장소를 보여줍니다.
애견 동반 장소를 클릭하여 장소 상세 정보를 확인하고 모임 생성 버튼을 통해 모임을 생성합니다.
모임 생성시에 최대 인원수, 모임 설명, 모임 날짜 등의 내용을 기입하여 모임을 생성합니다.</p>
<h4 id="모임-참가">모임 참가:</h4>
<p>사용자가 지도 혹은 즐겨찾기 알림을 통해 생성된 모임을 확인합니다.
모임 소개글에 적힌 장소, 시간등을 확인 합니다.
참가를 원할 경우 참가 신청을 누릅니다.</p>
<h4 id="실시간-채팅-기능">실시간 채팅 기능:</h4>
<p>실시간으로 여러 사람들과 채팅방에서 모임 관련 대화를 할 수 있습니다.</p>
<h4 id="참여자-평가">참여자 평가:</h4>
<p>모임이 종료되면 해댱 모임 참여차들 평가를 선택적으로 할 수 있습니다.</p>
<h4 id="즐겨찾기">즐겨찾기:</h4>
<p>모임을 희망하는 장소를 즐겨찾기 등록합니다.
즐겨찾기 등록한 장소에 모임이 생성되면 알림을 전송합니다.</p>
<h4 id="핫플-추천-알림">핫플 추천 알림:</h4>
<p>장소에 생성된 모임의 확정된 참가자들 수 기반으로 일정 수치 이상의 참가자수가 발생하면 접속 유저들에게 핫플 장소 알림(SSE)를 전송합니다.</p>
<hr>
<h1 id="7️⃣-도전과제-및-해결책">7️⃣ 도전과제 및 해결책</h1>
<p>도전과제라고 해야하는진 모르겠지만 프로젝트를 하면서 가장 기억에 남았던 작업은 토큰 기반 유저 조회 API 추가하는 것이었습니다. 해당 작업에 대한 PR을 올리고 팀원들에게 컨펌받는 과정에서 두가지 질문을 받았습니다.</p>
<ol>
<li><p>registerUser 메서드에서도 UserResponseDto를 생성하는 것 같은데, 공통 부분을 추출해서 쓰는게 가독성 측면에서 좋지 않을까 생각이 드는데 지민님 생각은 어떤지 궁금합니다.ᐟ</p>
</li>
<li><p>유저와 연관관계를 가진 도메인이 meeting, evaluations 등등 있습니다. 토큰에서 유저 정보를 추출해서 사용해야하는데, 해당 로직은 유저 도메인쪽에서 작성하실 예정이신지도 질문드립니다.</p>
</li>
</ol>
<p>1번 질문에 관해서는 코드를 작성하면서 공통적인 부분은 따로 추출해서 코드를 작성해야 했는데 간과한 부분이라서 아차 싶었던 부분이었습니다. 이때 이후로 최대한 공통적인 부분은 따로 리팩토링하는 작업을 거치고 있습니다.</p>
<p>2번 질문에 관해서는 유저 도메인만 생각해서 작업하다보니 유저와 연관관계를 가진 도메인들을 생각하지 못했었습니다. 그저 UserService.getUserInfo(token)를 호출해서 유저 정보를 가져오는 것만 구현해놨었습니다.</p>
<pre><code>public User getUserEntityByToken(String token) {
    String email = jwtTokenProvider.getEmailFromToken(token);
    return userRepository.findByEmail(email)
            .orElseThrow(() -&gt; new RuntimeException(&quot;User not found&quot;));
}</code></pre><p>그래서 이런 방법도 고려했었지만 해당 메서드를 사용하게 되면 매번 사용할 때마다 token 값을 넣어줘야하는 번거로움이 존재해서, SecurityContextHolder를 사용해서 로그인한 User 엔티티를 반환하는 방법을 사용하는 것이 좋을 것 같다는 피드백을 받아 </p>
<pre><code> public User getCurrentUser() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

        if (authentication == null || !authentication.isAuthenticated()) {
            throw new RuntimeException(&quot;User is not authenticated&quot;);
        }

        Object principal = authentication.getPrincipal();

        if (!(principal instanceof UserDetails)) {
            throw new RuntimeException(&quot;Authentication principal is not UserDetails type&quot;);
        }

        UserDetails userDetails = (UserDetails) principal;
        return userRepository.findByEmail(userDetails.getUsername())
                .orElseThrow(() -&gt; new RuntimeException(&quot;User not found&quot;));
    }</code></pre><p>이렇게 로그인한 유저의 엔티티를 반환하는 메서드를 추가하였습니다.</p>
<hr>
<h1 id="8️⃣-결과-및-성과">8️⃣ 결과 및 성과</h1>
<p><img src="https://velog.velcdn.com/images/ij_nim/post/7bd53698-363f-42c1-b798-ce799b660654/image.png" alt=""></p>
<h4 id="성능-최적화-보고서--api-문서">성능 최적화 보고서 &amp; API 문서</h4>
<p><a href="https://potent-tarantula-607.notion.site/_DangDangCrew-1cb13cc69d8980aaa7c4c5fc8d50b2bb?pvs=4">Notion 링크</a></p>
<h4 id="시연-영상">시연 영상</h4>
<p><img src="https://velog.velcdn.com/images/ij_nim/post/bf9ca442-500e-4d6b-90ad-241098cf7a37/image.gif" alt=""></p>
<hr>
<h1 id="9️⃣-향후-개선-사항">9️⃣ 향후 개선 사항</h1>
<p><img src="https://velog.velcdn.com/images/ij_nim/post/49cca14f-f10c-4790-9856-1405ed7d3181/image.png" alt=""></p>
<hr>
<h1 id="🔟-후기-및-배운-점">🔟 후기 및 배운 점</h1>
<p>회원가입과 JWT를 적용한 로그인, 토큰 관련 기능들을 구현하며 인증과 보안 로직에 대해 이해할 수 있었습니다. 이번에 개발한 부분을 리팩토링하며 향후 다른 프로젝트에서도 템플릿처럼 사용해 확장 개발할 수 있을 것이라 생각합니다.</p>
<p>이번 프로젝트를 통해 팀원들과 협업하며 실제 서비스 구축의 모든 단계를 경험했고, 실무에 가까운 개발 경험을 축적할 수 있었습니다. 기술적 성장은 물론, 사용자 중심 서비스 기획과 문제 해결력까지 함께 키울 수 있었던 소중한 시간이었습니다.</p>
<hr>
<h1 id="📌-마무리">📌 마무리</h1>
<p>DangDangCrew 프로젝트는 반려인들의 실제 생활 속 불편함을 해소하고 커뮤니티를 활성화하는 데 목적을 두고 기획되었습니다. 카카오 지도 API를 활용한 반려동물 동반 가능 장소 탐색, 실시간 모임 매칭, WebSocket 기반의 채팅, Redis와 SSE를 이용한 실시간 알림 등 다양한 기술을 실용적으로 융합해 완성도 높은 서비스를 구축할 수 있었습니다.</p>
<p>특히, 유저 인증과 보안(JWT), Redis 기반 실시간 데이터 처리, MongoDB와 MySQL의 혼합 사용 등 백엔드 구조의 깊이 있는 설계를 통해, 기능성과 확장성 모두를 갖춘 서비스를 만들었다는 점에서 의미가 큽니다.</p>
<p>이 프로젝트는 향후에도 산책 기록 공유 및 SNS 기능 도입, AI 기반 산책 추천 루트 생성, 반려동물 커뮤니티 이벤트 기능, 이용자 분석을 통한 개인화 추천 시스템 등으로 발전 가능성이 있습니다.</p>
<hr>
<h1 id="🔗-참고-자료-및-링크">🔗 참고 자료 및 링크</h1>
<p><a href="https://github.com/FindMeWithDeepDive/DangDangCrew.git">GitHub</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[고객 요구 맞춤 백엔드 협업 프로젝트 회고록 / 이슈 관리 시스템 개발 프로젝트]]></title>
            <link>https://velog.io/@ij_nim/%EA%B3%A0%EA%B0%9D-%EC%9A%94%EA%B5%AC-%EB%A7%9E%EC%B6%A4-%EB%B0%B1%EC%97%94%EB%93%9C-%ED%98%91%EC%97%85-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%ED%9A%8C%EA%B3%A0%EB%A1%9D-%EC%9D%B4%EC%8A%88-%EA%B4%80%EB%A6%AC-%EC%8B%9C%EC%8A%A4%ED%85%9C-%EA%B0%9C%EB%B0%9C-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8</link>
            <guid>https://velog.io/@ij_nim/%EA%B3%A0%EA%B0%9D-%EC%9A%94%EA%B5%AC-%EB%A7%9E%EC%B6%A4-%EB%B0%B1%EC%97%94%EB%93%9C-%ED%98%91%EC%97%85-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%ED%9A%8C%EA%B3%A0%EB%A1%9D-%EC%9D%B4%EC%8A%88-%EA%B4%80%EB%A6%AC-%EC%8B%9C%EC%8A%A4%ED%85%9C-%EA%B0%9C%EB%B0%9C-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8</guid>
            <pubDate>Sun, 30 Mar 2025 08:55:28 GMT</pubDate>
            <description><![CDATA[<h1 id="이슈-관리-시스템-issuemap">이슈 관리 시스템 IssueMap</h1>
<h1 id="1️⃣-개요">1️⃣ 개요</h1>
<h2 id="프로젝트-주제💡">프로젝트 주제💡</h2>
<p>: 개발 팀이나 조직 내 발생하는 버그, 기능 개선 요청, 일반적인 이슈를 체계적으로 관리할 수 있는 웹 애플리케이션 개발</p>
<hr>
<h2 id="프로젝트-목표🚀">프로젝트 목표🚀</h2>
<p>핵심 기능 구현 </p>
<ul>
<li>이슈 생성, 조회, 수정, 삭제, 상태 관리 등의 핵심 기능 구현</li>
</ul>
<p>백엔드 시스템 설계 역량 강화</p>
<ul>
<li>RESTful API 설계 및 데이터 모델링을 통해 견고한 서버 아키텍처 구축</li>
</ul>
<p>팀 협업 기반 프로젝트 관리 경험</p>
<ul>
<li>명확한 역할 분담과 코드 리뷰 과정을 통해 협업 프로세스 이해</li>
</ul>
<p>다른 팀과의 협업을 통한 기능 개발</p>
<ul>
<li><p>상호 피드백과 조율을 통해 품질 높은 소프트웨어 제공 및 개발 프로세스 최적화</p>
</li>
<li><p>협업 과정에서 발생하는 문제를 효과적으로 해결하며, 전체 프로젝트 진행 사항을 공유하고 조율</p>
</li>
</ul>
<p>데이터 보안 및 시스템 안정성 향상</p>
<ul>
<li>사용자와 시스템의 중요한 정보를 보호하기 위해 최신 보안 기술 적용</li>
</ul>
<p>프로젝트 문서화 및 프레젠테이션 기술 습득</p>
<ul>
<li>프로젝트 계획, 요구사항, 설계, 테스트 결과 등의 문서를 체계적으로 작성 및 관리</li>
</ul>
<hr>
<h2 id="프로젝트-내용📝">프로젝트 내용📝</h2>
<h3 id="수행-방법">수행 방법</h3>
<ul>
<li>요구 사항 정의<ul>
<li>고객의 요구 사항을 수집 및 분석하고, 기술 명세서를 작성</li>
<li>비즈니스 및 기술적 요구 사항을 기반으로 프로젝트 범위를 설정</li>
</ul>
</li>
<li>설계 및 아키텍처 구축<ul>
<li>데이터베이스 스키마 설계 및 서버 아키텍처 정의</li>
<li>RESTful API 설계 및 문서화</li>
</ul>
</li>
<li>백엔드 개발<ul>
<li>API 및 백엔드 로직 개발</li>
<li>인증 및 권한 관리 시스템 구현</li>
</ul>
</li>
<li>테스트 및 배포<ul>
<li>자동화된 테스트 스크립트 작성 및 실행</li>
<li>클라우드 환경에 배포</li>
<li>성능 모니터링 및 최적화</li>
</ul>
</li>
<li>유지 보수 및 개선<ul>
<li>사용자 피드백을 수집하여 시스템을 개선</li>
<li>신규 요구 사항에 따라 백엔드 로직을 수정 및 추가</li>
</ul>
</li>
<li>문서화 및 발표<ul>
<li>기술 문서 및 API 스펙 정의 작성</li>
<li>프로젝트 결과물 리뷰 및 고객 프레젠테이션 준비</li>
</ul>
</li>
</ul>
<hr>
<h2 id="프로젝트-배경🖼️">프로젝트 배경🖼️</h2>
<ul>
<li><p>실무 환경에서의 API 연계 및 협업 프로세스를 경험하고, 팀 간 요구 사항 분석, 구현, 테스트, 통합 과정을 학습.</p>
</li>
<li><p>이슈 트래커는 소프트웨어 개발 및 프로젝트 관리에서 널리 사용되는 도구로, 이를 구현함을써 실무에 가까운 경험을 쌓을 수 있음.</p>
</li>
</ul>
<hr>
<h1 id="2️⃣-일정">2️⃣ 일정</h1>
<h2 id="프로젝트의-시작일과-종료일📆">프로젝트의 시작일과 종료일📆</h2>
<p>시작일: 2025년 1월 13일
종료일: 2025년 1월 24일</p>
<hr>
<h2 id="작업-계획🗓️">작업 계획🗓️</h2>
<h4 id="1주차">1주차</h4>
<p>  01/13 (월) : 프로젝트 주제 선정 및  요구사항 분석
    - 프로젝트 주제 선정
    - 프로젝트 요구사항 분석
    - 요구사항 정의서 작성</p>
<p>  01/14 (화) : 요구사항을 기반으로 백엔드 시스템 설계
     - 데이터베이스 설계
     - API 설계 (엔트포인트 정의, 요청 / 응답 스펙 명세)
     - 보안 설계 (인증, 권한, 데이터 암호화 등)
     - 필요 시 고객과 추가 미팅을 통해 설계 검토</p>
<p>  01/15 (수) : 요구사항을 기반으로 백엔드 시스템 설계
     - 데이터베이스 설계
     - API 설계 (엔트포인트 정의, 요청 / 응답 스펙 명세)
     - 보안 설계 (인증, 권한, 데이터 암호화 등)
     - 필요 시 고객과 추가 미팅을 통해 설계 검토</p>
<p>  01/16 (목) : 작성한 문서를 기반으로 백엔드 시스템 개발 및 테스트
     - RESTful API 기반 백엔드 애플리케이션 개발
     - 데이터 통합 및 가공 로직 구현
     - 유닛 테스트 및 통합 테스트 진행
     - 고객의 피드백을 수집하여 수정 / 개선</p>
<p>  01/17 (금) : 작성한 문서를 기반으로 백엔드 시스템 개발 및 테스트
     - RESTful API 기반 백엔드 애플리케이션 개발
     - 데이터 통합 및 가공 로직 구현
     - 유닛 테스트 및 통합 테스트 진행
     - 고객의 피드백을 수집하여 수정 / 개선</p>
<p> 01/18 (토) : 작성한 문서를 기반으로 백엔드 시스템 개발 및 테스트
     - RESTful API 기반 백엔드 애플리케이션 개발
     - 데이터 통합 및 가공 로직 구현
     - 유닛 테스트 및 통합 테스트 진행
     - 고객의 피드백을 수집하여 수정 / 개선</p>
<p> 01/19 (일) : 작성한 문서를 기반으로 백엔드 시스템 개발 및 테스트
     - RESTful API 기반 백엔드 애플리케이션 개발
     - 데이터 통합 및 가공 로직 구현
     - 유닛 테스트 및 통합 테스트 진행
     - 고객의 피드백을 수집하여 수정 / 개선</p>
<h4 id="2주차">2주차</h4>
<p> 01/20 (월) : 작성한 문서를 기반으로 백엔드 시스템 개발 및 테스트
     - RESTful API 기반 백엔드 애플리케이션 개발
     - 데이터 통합 및 가공 로직 구현
     - 유닛 테스트 및 통합 테스트 진행
     - 고객의 피드백을 수집하여 수정 / 개선</p>
<p>01/21 (월) : 작성한 문서를 기반으로 백엔드 시스템 개발 및 테스트
     - RESTful API 기반 백엔드 애플리케이션 개발
     - 데이터 통합 및 가공 로직 구현
     - 유닛 테스트 및 통합 테스트 진행
     - 고객의 피드백을 수집하여 수정 / 개선</p>
<p>01/22 (화) : 작성한 문서를 기반으로 백엔드 시스템 개발 및 테스트
     - RESTful API 기반 백엔드 애플리케이션 개발
     - 데이터 통합 및 가공 로직 구현
     - 유닛 테스트 및 통합 테스트 진행
     - 고객의 피드백을 수집하여 수정 / 개선</p>
<p>01/23 (수) : 시스템 최적화 및 문서화
     - 성능 최적화 작업 (API 응답 속도 개선, DB 쿼리 최적화 등)
     - 코드 및 시스템 사용 가이드 작성</p>
<p>01/24 (목) : 최종 결과물 발표
     - 발표 자료 마무리 및 최종 산출물 제출</p>
<hr>
<h1 id="3️⃣-프로젝트-팀-구성">3️⃣ 프로젝트 팀 구성</h1>
<h3 id="팀-구성원들의-역할과-책임👑">팀 구성원들의 역할과 책임👑</h3>
<h4 id="공통-작업">공통 작업</h4>
<p>API 문서화</p>
<ul>
<li>개발한 모든 API에 대해 명확하고 상세한 문서를 작성합니다.</li>
</ul>
<p>기능 구현</p>
<ul>
<li><p>요구사항에 따라 각 기능을 설계하고 구현.</p>
</li>
<li><p>비즈니스 로직이 정상적으로 동작하는지 검증하는 단위 테스트 및 통합 테스트 작성.</p>
</li>
</ul>
<p>팀 커뮤니케이션 및 협업</p>
<ul>
<li>코드 리뷰 및 회고를 통해 코드 품질을 개선하고 팀원들과의 협력을 강화.</li>
</ul>
<h4 id="기능-개발">기능 개발</h4>
<ul>
<li>최민우: 회원가입, 로그인 기능 구현</li>
<li>강요한: 이슈 코멘트 기능 구현</li>
<li>박정현: 이슈 검색 기능 구현, 외주 담당</li>
<li>김지민(본인): 프로젝트 &amp; 팀 관리 기능</li>
<li>박진홍 : 이슈 관리 기능 구현</li>
</ul>
<hr>
<h1 id="4️⃣-기술-스택-및-사용-도구">4️⃣ 기술 스택 및 사용 도구</h1>
<ul>
<li><p><strong>기술 스택</strong></p>
<ul>
<li>Java 17</li>
<li>Spring boot 3.4.1</li>
<li>Mysql</li>
<li>AWS (EC2, RDS)</li>
<li>Redis</li>
<li>JWT</li>
<li>OAuth2</li>
<li>CI/CD (Jenkins, GitHub Actions)</li>
</ul>
<ul>
<li><strong>사용 도구</strong><ul>
<li>IntelliJ IDEA</li>
<li>JUnit5</li>
<li>Git &amp; GitHub</li>
<li>Postman</li>
<li>Swagger</li>
<li>Notion</li>
</ul>
</li>
</ul>
</li>
</ul>
<hr>
<h1 id="5️⃣-아키텍처">5️⃣ 아키텍처</h1>
<p>Project Structure
<img src="https://velog.velcdn.com/images/ij_nim/post/4801cb3e-0859-4fbb-9e78-84d0696c5981/image.png" alt="">
ERD
<img src="https://velog.velcdn.com/images/ij_nim/post/9939a963-2ede-4c77-8790-29fed1820c73/image.png" alt="">
Flow Chart
<img src="https://velog.velcdn.com/images/ij_nim/post/b84cee90-f7e6-471d-8f3f-264a0e021896/image.png" alt=""></p>
<hr>
<h1 id="6️⃣-기능-설명">6️⃣ 기능 설명</h1>
<ol>
<li>회원가입
사용자가 이름, 이메일, 비밀번호를 입력하여 새로운 계정을 생성할 수 있다.</li>
<li>로그인
사용자가 등록된 이메일과 비밀번호를 입력하여 계정에 접근할 수 있다.</li>
<li>계정 관리
사용자는 이름, 이메일, 비밀번호 등 계정 정보를 수정하거나 삭제할 수 이싿. </li>
<li>프로젝트 관리
사용자는 프로젝트 이름, 설명등을 입력하여 새로운 프로젝트를 생성하거나 삭제할 수 있다.</li>
<li>팀원 관리
사용자는 특정 팀원을 초대하거나, 초대된 팀원에 대해 권한을 관리할 수 있다.</li>
<li>이슈 관리
사용자는 이슈를 생성하고, 이슈의 상태를 관리할 수 있다.</li>
<li>이슈 검색
사용자는 키워드, 상태, 생성일, 마감일을 기준으로 이슈를 검색할 수 있다.</li>
<li>이슈 코멘트
사용자는 이슈에 코멘트를 추가하거나 기존 코멘트를 수정 및 삭제할 수 있다.</li>
<li>이슈 히스토리
사용자는 특정 이슈의 변경사항을 조회할 수 있다.</li>
</ol>
<hr>
<h1 id="7️⃣도전과제-및-해결책">7️⃣도전과제 및 해결책</h1>
<h3 id="트러블-슈팅">트러블 슈팅</h3>
<h4 id="case1">CASE:1</h4>
<p>프로젝트를 진행중 팀원의 Swagger가 갑자기 동작하지 않은 문제가 발생하였음.
⬇️
구글링을 통해 원인을 조사하였지만, 원인을 발견하지 못하여 문제가 발생했던 팀원의 Swagger 버전을 변경하여 이슈를 해결할 수 있었음.</p>
<h4 id="case2">CASE:2</h4>
<p>Swagger를 통해 서버에 API 요청을 전달하던 중, 특정 팀원의 요청만 서버에 정상적으로 전달되지 않는 문제가 발생하였음.
⬇️
해당 팀원은 ModHeader를 사용중이었으며, 헤더의 key 값이 사용자가 설정한 key 값과 일치하지 않아 인증이 거부되어, 요청이 서버에 도달하지 않은 문제였음. ModHeader에서 해당 key를 제거하여 이슈를 해결함.</p>
<h4 id="case3">CASE:3</h4>
<p>RestTemplate를 사용하여 외부 API로 헤더에 토큰 값을 담아 요청을 보냈지만, 토큰이 정상적으로 전달되지 않는 문제가 발생하였음.
⬇️
외부 API로 요청을 보냈다고 생각하였지만, 내부 서버에서 해당 요청을 처리하고 있었고, RestTemplate를 통해 요청을 전달할 때 헤더에 토큰을 추가하는 방식으로 이슈를 해결할 수 있었음.</p>
<h3 id="외주-협업-이슈">외주 협업 이슈</h3>
<h4 id="case1-1">CASE:1</h4>
<p>협업 관련 미팅 중 요구사항 정의서에 JWT 처리 로직에 대한 내용이 포함되지 않았다는 점이 확인되었고, 이로 인해 개발 진행 시 토큰 정보를 어떻게 처리할 것인지에 대한 이슈가 발생.
⬇️
개발사에서는 토큰을 처리하는 기능을 배제하여 개발을 진행하였고, 고객사에서 토큰을 처리하는 로직은 기능 구현이 완료된 후 추가하는 방식으로 이슈를 해결.</p>
<h4 id="case2-1">CASE:2</h4>
<p>개발사에게 요청한 기능들이 외주 개발 기간을 초과하여, 인증 정보 처리 로직을 고객사에서 개발 해야 하는 이슈가 발생.
⬇️
개발사에서 추가 인원을 투입하여 빠른 시일내에 기능을 구현.</p>
<hr>
<h1 id="8️⃣-결과-및-성과">8️⃣ 결과 및 성과</h1>
<h3 id="프로젝트-수행-결과">프로젝트 수행 결과</h3>
<h3 id="team-api">TEAM API</h3>
<h3 id="목적">목적</h3>
<p>프로젝트의 이슈를 관리하는 멤버들을 등록하기 위해 팀 생성, 조회, 수정, 삭제 기능 구현</p>
<h3 id="수행결과">수행결과</h3>
<p><img src="https://velog.velcdn.com/images/ij_nim/post/3fec6b14-14a0-48f8-a2fa-b944a30f25b7/image.gif" alt=""></p>
<h3 id="project-api">PROJECT API</h3>
<h3 id="목적-1">목적</h3>
<p>이슈를 관리할 프로젝트의 생성, 조회, 수정, 삭제 기능을 구현</p>
<h3 id="수행결과-1">수행결과</h3>
<p><img src="https://velog.velcdn.com/images/ij_nim/post/8038c0b3-7cde-486f-b727-bc0d459ae892/image.gif" alt=""></p>
<h1 id="9️⃣-향후-계획">9️⃣ 향후 계획</h1>
<h4 id="현직자-멘토링-후-고려사항">현직자 멘토링 후 고려사항</h4>
<ol>
<li>Redis 토큰 저장 관련 </li>
</ol>
<ul>
<li>해당 프로젝트에서는 Refresh Token만 Redis에 저장 해서 로그아웃을 구현했지만 상황에 따라서는 Access Token만 Redis에 저장 하는 방법도 있다고 함 (금융, 의료, 민감 데이터 서비스처럼 토큰 강제 무효화가 자주 필요한 경우)</li>
</ul>
<ol start="2">
<li>성능 관련</li>
</ol>
<ul>
<li>쿼리 시간 및 어플리케이션 성능 테스트를 위해서 mysql의 걸린 시간만 확인 하는 것이 아니라 쿼리 발생 시점부터 끝난 시점에 시간 차이에 대한 log를 기록해서 추후 세부적으로 분석하는 것을 권장</li>
</ul>
<ol start="3">
<li>메서드 및 네이밍 규칙</li>
</ol>
<ul>
<li>변수, 메서드 명 같은 경우에는 일관성을 가지면 좋음</li>
</ul>
<hr>
<h1 id="🔟-후기-및-배운-점">🔟 후기 및 배운 점</h1>
<h4 id="팀-의견">팀 의견</h4>
<p>처음부터 팀 협업을 통해 API 문서화부터  핵심 기능 구현까지 서로의 역할과 목표를 명확히 하고, 각자 맡은 부분을 수행하면서 이를 해결해 나가는 과정에서 문제 해결 능력과 기술적 역량이 크게 성장했다고 느꼈습니다.
추가로 팀원들과의 지속적인 소통과 피드백을 통해 서로의 접근 방식을 공유하며 개발 지식을 더 많이 배울 수 있었습니다.</p>
<h4 id="개인-의견">개인 의견</h4>
<p>처음 협력 팀과 서로 고객이 되어 요구사항 명세서를 작성해보며 고객의 입장과, 서비스를 제공해주는 입장에서 새로 배우게 되는 것들이 많았습니다. 이번 경험이 추후 기업에서 업무를 진행할 때도 큰 도움이 될 것 같습니다.</p>
<h4 id="협업-회고">협업 회고</h4>
<ol>
<li><p>요구사항 명세서 관련
개발 진행 중에 맞춰가는 것도 나쁘지 않으나, 처음부터 명확하고 자세하게 작성하면 불필요한 수정과 논의를 줄일 수 있음. 초기 요구 사항을 충분히 분석하고 정의하면 혼란을 최소화할 수 있고, 명확한 API 명세와 함께 유효성 검증, 에러 처리 방식, 데이터 구조 등을 구체적으로 작성하면 협업이 더 원활해질 것으로 보임. 결과적으로 개발 속도와 코드 품질 모두 향상될 가능성이 높음.</p>
</li>
<li><p>일정 관련
요구사항이 추가될 가능성이 있다면 미리 이 정보를 공유하고 대비할 수 있도록 하는 것이 중요하다고 생각됨. 개발 과정에서 변경 사항이 발생하는 건 자연스러운 일이지만, 사전에 이를 예측하고 팀원들과 공유하면 불필요한 혼란과 재작업을 줄일 수 있음. 또한, 유연한 설계와 확장성을 염두에 둔 개발 방식을 채택하면 요구사항 변경에 더 효과적으로 대응 할 수 있을 것으로 보임.</p>
</li>
</ol>
<hr>
<h1 id="📌-마무리">📌 마무리</h1>
<p>이번 이슈 관리 시스템 IssueMap 프로젝트는 실무에 가까운 개발 환경을 경험하며, 요구사항 분석부터 설계, 구현, 테스트, 배포까지 백엔드 개발 전 과정을 체계적으로 수행한 프로젝트였습니다. 각 팀원이 명확한 역할을 가지고 책임감 있게 기능을 구현했으며, API 설계 및 문서화, 보안 처리, 테스트 자동화 등 실무에서 요구되는 다양한 기술을 직접 적용해봄으로써 실력을 한층 끌어올릴 수 있는 계기가 되었습니다.</p>
<p>특히, JWT 기반 인증 처리, Redis를 활용한 토큰 저장 및 로그아웃 구현, RESTful한 API 아키텍처 설계, 외주 협업 이슈 해결 경험 등을 통해 실무에서 발생할 수 있는 다양한 상황에 유연하게 대응할 수 있는 역량도 함께 키울 수 있었습니다.</p>
<p>또한, 협력사와의 요구사항 명세서 기반 협업, 트러블슈팅 과정, 그리고 팀 내부의 지속적인 코드 리뷰와 피드백 문화는 향후 어떤 개발 환경에서도 빠르게 적응하고 협력할 수 있는 기반이 되었다고 생각합니다.</p>
<h4 id="🔭-향후-발전-방향">🔭 향후 발전 방향</h4>
<p>실시간 알림 기능: 이슈 상태 변경, 코멘트 등록 시 사용자에게 실시간 알림 기능 추가 (WebSocket, SSE 활용)</p>
<p>대시보드 시각화: 이슈 통계 및 프로젝트 진행 현황을 그래프로 시각화하여 관리 효율성 향상</p>
<p>모바일 대응: 반응형 UI 또는 모바일 앱 연동 기능 개발</p>
<p>DevOps 고도화: CI/CD 파이프라인 고도화 및 테스트 커버리지 자동 리포팅 시스템 적용</p>
<p>보안 강화: Refresh Token 재사용 방지, Access Token IP 기반 검증 등 고급 보안 정책 적용</p>
<hr>
<h1 id="🔗-참고-자료-및-링크">🔗 참고 자료 및 링크</h1>
<p>Project Repository
<a href="https://github.com/Maptrackers/IssueMap">https://github.com/Maptrackers/IssueMap</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[버깅/디버깅 프로젝트 회고록 / 배달의민족 클론코딩]]></title>
            <link>https://velog.io/@ij_nim/%EB%B2%84%EA%B9%85%EB%94%94%EB%B2%84%EA%B9%85-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%ED%9A%8C%EA%B3%A0%EB%A1%9D-%EB%B0%B0%EB%8B%AC%EC%9D%98%EB%AF%BC%EC%A1%B1-%ED%81%B4%EB%A1%A0%EC%BD%94%EB%94%A9</link>
            <guid>https://velog.io/@ij_nim/%EB%B2%84%EA%B9%85%EB%94%94%EB%B2%84%EA%B9%85-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%ED%9A%8C%EA%B3%A0%EB%A1%9D-%EB%B0%B0%EB%8B%AC%EC%9D%98%EB%AF%BC%EC%A1%B1-%ED%81%B4%EB%A1%A0%EC%BD%94%EB%94%A9</guid>
            <pubDate>Sun, 30 Mar 2025 07:26:33 GMT</pubDate>
            <description><![CDATA[<h1 id="배달의-민족-클론코딩-프로젝트-먹물의-민족🦑">배달의 민족 클론코딩 프로젝트 &quot;먹물의 민족🦑&quot;</h1>
<h1 id="1️⃣-개요">1️⃣ 개요</h1>
<h2 id="프로젝트-주제💡">프로젝트 주제💡</h2>
<p>: 배달의 민족 서비스 클론코딩 및 디버깅</p>
<hr>
<h2 id="프로젝트-목표🚀">프로젝트 목표🚀</h2>
<h3 id="주요-목표">주요 목표</h3>
<ol>
<li>백엔드 시스템에서 발생하는 에러/버그의 탐지 및 해결</li>
<li>소프트웨어 배포와 유지보수 프로세스 이해</li>
<li>팀 협업을 통한 문제 해결 능력 강화</li>
<li>개발 프로세스의 전반적인 최적화 경험<h3 id="하위-목표">하위 목표</h3>
</li>
<li>로그 분석을 통해 시스템 에러 식별</li>
<li>단위 및 통합 테스트 케이스 작성</li>
<li>성능 저하 문제를 진단하고 최적화 방안 적용</li>
<li>보안 취약점 평가 및 보안 패치 적용</li>
<li>지속적 통합/배포(CI/CD) 파이프라인 설정</li>
<li>API 문서화 관리</li>
</ol>
<hr>
<h2 id="프로젝트-내용📝">프로젝트 내용📝</h2>
<ol>
<li>실제 시장에서 사용되는 소프트웨어의 버전을 기반으로 한 클론 코딩 및 디버깅 진행</li>
<li>소프트웨어 배포 연습 및 배포 후 버그와 에러 탐지 및 해결</li>
<li>버그 발견 및 리포트 작성<h3 id="수행-방법">수행 방법</h3>
</li>
<li>에러/버그 탐지 및 보고</li>
</ol>
<ul>
<li>클론 코딩 소프트웨어 실행 및 로그 분석</li>
<li>발생한 에러/버그의 원인 분석 후 리포트 작성</li>
</ul>
<ol start="2">
<li>테스트 최적화</li>
</ol>
<ul>
<li>단위/통합 테스트 케이스 작성</li>
<li>성능 진단 및 최적화 실행</li>
<li>보안 평가와 보안 패치 적용</li>
</ul>
<ol start="3">
<li>협업 기반 문제 해결</li>
</ol>
<ul>
<li>작성된 에러/버그 리포트를 팀원과 교환</li>
<li>해결 방안 공유 및 해설지 작성</li>
</ul>
<ol start="4">
<li>결과물 제작</li>
</ol>
<ul>
<li>수행 평가표를 작성해 피드백 반영</li>
</ul>
<ol start="5">
<li>운영 방식</li>
</ol>
<ul>
<li>스프린트 기간에 나오는 모든 산출물은 노션을 통해 제출</li>
<li>정기적인 회의를 통해 진행 상황 공유 및 문제를 해결</li>
</ul>
<hr>
<h2 id="프로젝트-배경🖼️">프로젝트 배경🖼️</h2>
<ul>
<li>협업을 통한 실시간 버그 해결 프로젝트는 실제 시장에서 사용되는 소프트웨어를 클론 코딩하여 디버깅과 최적화를 수행하는 것을 목표로 합니다.</li>
<li>백엔드 시스템에서 발생하는 버그와 성능 문제를 발견하고 해결하는 방법을 학습하며, 배포 및 유지보수 과정을 포함한 소프트웨어 개발 전 과정을 경험합니다.</li>
<li>팀 협업을 기반으로 문제를 해결하며, 에러 보고서와 해설지를 작성해 서로의 작업을 평가하고 개선합니다.</li>
</ul>
<hr>
<h1 id="2️⃣-일정">2️⃣ 일정</h1>
<h2 id="프로젝트의-시작일과-종료일📆">프로젝트의 시작일과 종료일📆</h2>
<p>시작일: 2024년 12월 12일
휴뮤일: 2024년 12월 23일 ~ 2025년 1월 5일
종료일: 2025년 1월 10일
실제 프로젝트 기간: 12일</p>
<hr>
<h2 id="작업-계획🗓️">작업 계획🗓️</h2>
<p>2024/12/12</p>
<ul>
<li>클론 코딩 주제 선정</li>
</ul>
<p>2024/12/13 ~ 2024/12/16</p>
<ul>
<li>코드 분석 및 RISK 확인</li>
</ul>
<p>2024/12/17</p>
<ul>
<li>어플리케이션 마이그레이션 (Java, Spring boot, Gradle)</li>
</ul>
<p>2024/12/18 ~ 2024/12/20
2025/01/06 ~ 2025/01/07</p>
<ul>
<li>클린 코드 기반의 코드 리팩토링</li>
</ul>
<p>2025/01/08 ~ 2025/01/09</p>
<ul>
<li>Merge 작업</li>
</ul>
<p>2025/01/09 ~ 2025/01/10</p>
<ul>
<li>발표 준비 및 발표</li>
</ul>
<hr>
<h1 id="3️⃣-프로젝트-팀-구성">3️⃣ 프로젝트 팀 구성</h1>
<h3 id="팀-구성원들의-역할과-책임👑">팀 구성원들의 역할과 책임👑</h3>
<p>공통 작업 </p>
<ul>
<li>ERD 리팩토링</li>
<li>Maven ➡️ Gradle 변경</li>
</ul>
<hr>
<p>노현이(팀장) : 진행 상황 관리, 일정 준수 확인
김지민(본인): Admin
김중환: Delivery
김효민: Restaurant
노현이: Restaurant
박지은: Order
순진호: Customer</p>
<hr>
<p>이렇게 각자 도메인을 맡아 아래 역할을 진행한다. </p>
<ul>
<li>버깅/디버깅</li>
<li>클린 코드 수정</li>
<li>테스트 코드 작성 이후 다같이 코드 리뷰 후 배포 및 테스트 진행</li>
</ul>
<hr>
<h1 id="4️⃣-기술-스택-및-사용-도구">4️⃣ 기술 스택 및 사용 도구</h1>
<ul>
<li>기술 스택<ul>
<li>Server<ul>
<li>Java</li>
<li>Spring boot</li>
</ul>
</li>
<li>Database<ul>
<li>MySQL</li>
<li>JPA</li>
</ul>
</li>
<li>Infra<ul>
<li>AWS</li>
</ul>
</li>
<li>Security<ul>
<li>JWT</li>
<li>Spring Security</li>
</ul>
</li>
</ul>
</li>
<li>사용 도구<ul>
<li>IDE<ul>
<li>IntelliJ</li>
</ul>
</li>
<li>Database Management<ul>
<li>MySQL workbench</li>
</ul>
</li>
<li>Test &amp; QA(Quality Assurance)<ul>
<li>JUnit, Mockito, Postman</li>
</ul>
</li>
<li>SCM(Software Configuration Management)<ul>
<li>GitHub</li>
</ul>
</li>
</ul>
</li>
</ul>
<hr>
<h1 id="5️⃣-아키텍처">5️⃣ 아키텍처</h1>
<p><img src="https://velog.velcdn.com/images/ij_nim/post/44e53f76-7fc4-47db-9703-b81563a20f9a/image.png" alt=""></p>
<ol>
<li><strong>사용자 앱</strong>에서 음식점 검색 후, 원하는 메뉴를 선택하여 주문을 생성합니다.</li>
<li>주문은 <strong>백엔드 API</strong>를 통해 <strong>음식점 서버</strong>로 전달됩니다.</li>
<li><strong>음식점 서버</strong>는 주문을 수락하고, 메뉴와 주문 정보를 확인합니다.</li>
<li><strong>배달 기사 앱</strong>은 배달 요청을 수락하고, 주문을 배달하기 시작합니다.</li>
<li><strong>결제 시스템 &amp; 알림</strong>은 결제 처리를 진행하고, 사용자는 결제 완료 알림을 받습니다.</li>
</ol>
<hr>
<h1 id="6️⃣-기능-설명">6️⃣ 기능 설명</h1>
<h4 id="가게-관련">가게 관련</h4>
<ul>
<li>가게 메뉴 관리</li>
<li>광고 상품 결제<h4 id="배달-관련">배달 관련</h4>
</li>
<li>주문-배달원 연결<h4 id="주문-관련">주문 관련</h4>
</li>
<li>장바구니 관리</li>
<li>주문 상태 조회</li>
<li>주문 리뷰 관리<h4 id="쿠폰-관련">쿠폰 관련</h4>
</li>
<li>등급별 정기 쿠폰 관리</li>
<li>이벤트 쿠폰 관리</li>
<li>고객별 보유 쿠폰 관리<h4 id="고객-관련">고객 관련</h4>
</li>
<li>계정 관리</li>
<li>고객 주소 관리</li>
<li>고객 등급 관리<h4 id="관리자-관련">관리자 관련</h4>
</li>
<li>광고 상품 관리</li>
</ul>
<hr>
<h1 id="7️⃣-도전과제-및-해결책">7️⃣ 도전과제 및 해결책</h1>
<h3 id="발생한-문제">발생한 문제</h3>
<ol>
<li>maven 에서 gradle로 마이그레이션 후 실행되지 않는 코드 발생</li>
<li>admin 패키지의 컨트롤러, 서비스, 엔티티 코드에서 보완점 발견</li>
<li>intellij와 jdk 간의 호환성 문제가 발생하여 빌드 실패</li>
<li>테스트 코드 오류 수정 필요<h3 id="목표">목표</h3>
</li>
<li>마이그레이션 후 코드에서 발견된 오류 수정</li>
<li>논리 삭제 또는 물리 삭제를 고려하여 코드 수정 진행</li>
<li>컨트롤러, 서비스, 엔티티 코드의 보완점 수정</li>
<li>intellij와 jdk간의 호환성 문제 해결</li>
<li>테스트 코드 오류 수정<h3 id="리팩토링-수행-결과">리팩토링 수행 결과</h3>
<h4 id="admincontrollerjava">AdminController.java</h4>
<img src="https://velog.velcdn.com/images/ij_nim/post/8e09e564-69d8-4f1e-a319-c773f2fbb096/image.png" alt="">
<img src="https://velog.velcdn.com/images/ij_nim/post/6e0992a3-eb6a-44b3-bdb5-27731f22d2c2/image.png" alt=""></li>
</ol>
<p><strong>1. ResponseEntity 통일</strong></p>
<ul>
<li>기존 코드 내에 통일이 되어있지 않아 ResponseEntity를 사용하여 HTTP 상태 코드를 명시적으로 설정하기 위해 통일하였습니다.</li>
</ul>
<p><strong>2. 로그 추가</strong></p>
<ul>
<li>애플리케이션의 동작 상태를 기록하고, 문제를 진단하거나 디버깅하여, 시스템의 성능과 동작을 모니터링 하기 위해 로그를 추가하였습니다.</li>
<li>AdminService 코드에도 로그 추가하였습니다.</li>
</ul>
<h4 id="adminservicejava">AdminService.java</h4>
<p><img src="https://velog.velcdn.com/images/ij_nim/post/5b392867-dea0-4372-b802-4129bc20dd7e/image.png" alt="">
<img src="https://velog.velcdn.com/images/ij_nim/post/1b3a2723-cf94-40f8-8df1-c09d8bdbb822/image.png" alt="">
<img src="https://velog.velcdn.com/images/ij_nim/post/987ad390-e9c8-4a0a-ae5f-fe1b3e5a7e3f/image.png" alt="">
<strong>1. 입력 유효성 추가</strong>
중복된 loginId를 확인하기 위해 입력 유효성 추가</p>
<p><strong>2. 중복 코드 제거</strong></p>
<ul>
<li>중복된 코드들을 하나의 메서드로 빼서 처리</li>
</ul>
<p><strong>3. 메서드 명을 명시적으로 수정</strong>
findAdmin → getAdminInfoByLoginId
updateAdmin → updateAdminPassword
deleteAdmin → removeAdminByLoginId
findAdminEntity → getAdminByLoginId
permitRestaurant → authorizeRestaurant</p>
<h4 id="admincreaterequestjava">AdminCreateRequest.java</h4>
<p><img src="https://velog.velcdn.com/images/ij_nim/post/7906e5bc-a2b4-433b-b727-39083357293e/image.png" alt="">
<strong>1. 입력 유효성 추가</strong></p>
<ul>
<li>클라이언트에서 잘못된 형식의 데이터를 서버로 보내는 것을 방지하기 위해 AdminCreateRequest에 입력 유효성을 추가</li>
</ul>
<h4 id="adminupdaterequestjava">AdminUpdateRequest.java</h4>
<p><img src="https://velog.velcdn.com/images/ij_nim/post/da043c1b-36ef-489f-b0cc-a9ec2a0cce6c/image.png" alt=""></p>
<h4 id="baseloginentityjava">BaseLoginEntity.java</h4>
<p><img src="https://velog.velcdn.com/images/ij_nim/post/fe480643-bea4-4032-a869-c5152b5c6340/image.png" alt=""></p>
<h4 id="adminjava">Admin.java</h4>
<p><img src="https://velog.velcdn.com/images/ij_nim/post/e68e6a39-b0cb-4c51-8d8b-3332dc4f72ad/image.png" alt=""></p>
<ol>
<li>비밀번호 검증 책임을 DTO에서 BaseLoginEntity로 이동</li>
</ol>
<ul>
<li>DTO는 데이터를 전달하는 역할만 수행</li>
<li>BaseLoginEntity는 공동 로그인 엔티티이기 때문에 Admin, User, Customer 등 다양한 하위 엔티티에서도 재사용 가능</li>
<li>중복 제거, 코드 유지보수성 증가<h4 id="admincontrollerjava-1">AdminController.java</h4>
<img src="https://velog.velcdn.com/images/ij_nim/post/b44c9bee-7eef-4d82-bc8f-bf3584e893e0/image.png" alt=""></li>
</ul>
<h4 id="admincontrollertestjava">AdminControllerTest.java</h4>
<p><img src="https://velog.velcdn.com/images/ij_nim/post/8a6ad8cf-f0ad-4f15-85bf-66092046cf34/image.png" alt=""></p>
<ol>
<li>테스트 코드 에러 수정</li>
</ol>
<ul>
<li>AdminController 에서 createAdmin 메서드가 리소스 생성에 성공하면 201(Created)을 반환하고 있다. 그러나 AdminControllerTest에서는 200(OK)를 예상하고 있었기에 에러가 발생하여 </li>
</ul>
<p>.andExpect(status().isOK))
↓
.andExpect(status().isCreated))</p>
<p>해당 부분을 수정하였다.</p>
<hr>
<h1 id="8️⃣-결과-및-성과">8️⃣ 결과 및 성과</h1>
<h3 id="erd">ERD</h3>
<p><img src="https://velog.velcdn.com/images/ij_nim/post/2ff03f39-1253-4177-8680-9532cc79b8c7/image.png" alt=""></p>
<h3 id="테스트-수행-결과">테스트 수행 결과</h3>
<p><img src="https://velog.velcdn.com/images/ij_nim/post/c4e6de99-1bd4-4a2c-b5c7-69b63d0d94c0/image.png" alt="">
<img src="https://velog.velcdn.com/images/ij_nim/post/337162f4-b5dd-48e7-8a54-0b84836595f9/image.png" alt="">
<img src="https://velog.velcdn.com/images/ij_nim/post/893dd506-b29a-414b-8a0a-d2e5668f4e55/image.png" alt=""></p>
<h3 id="개선-사항">개선 사항</h3>
<ol>
<li>테스트 코드 개선</li>
</ol>
<ul>
<li>예외 처리 부족한 부분 추가 및 수정</li>
<li>deprecated 된 애너테이션 최신 애너테이션으로 변경</li>
</ul>
<ol start="2">
<li>물리 삭제 vs 논리 삭제 토의 후 데이터 보존이 필요한 엔티티에 대해 논리 삭제 적용</li>
<li>객체 지향 설계 원칙 SOLID를 목표로 코드 리팩토링</li>
</ol>
<ul>
<li>관심사 분리</li>
</ul>
<ol start="4">
<li>성능 향상을 위한 자료구조 변경</li>
</ol>
<h3 id="버그리포트">버그리포트</h3>
<h4 id="버그">버그</h4>
<p>AdminControllerTest 에러    </p>
<h4 id="버그-상세-내용">버그 상세 내용</h4>
<p>테스트 코드와 실제 코드 간의 기대값 불일치로 인한 에러    </p>
<h4 id="발생-원인">발생 원인</h4>
<p>&quot;AdminController에서 createAdmin 메서드가 리소스 생성에 
성공하면 201(Created)을 반환하고 있음. 
그러나 테스트에서는 200(OK)를 예상하고 있음.</p>
<h4 id="수정-계획">수정 계획</h4>
<p>테스트 코드에서<br>.andExpect(status().isOK))
↓
.andExpect(status().isCreated))
해당 부분 수정</p>
<h4 id="수정-코드">수정 코드</h4>
<pre><code> mockMvc.perform(
            post(&quot;/api/v1/admins&quot;)
                .contentType(MediaType.APPLICATION_JSON)
                .content(objectMapper.writeValueAsString(adminCreateRequest))
                .with(csrf().asHeader())
        )
        .andExpect(status().isCreated()) </code></pre><hr>
<h1 id="9️⃣-향후-계획">9️⃣ 향후 계획</h1>
<ul>
<li>단위 테스트로 분리하여 테스트 속도 향상</li>
<li>성능 최적화를 위한 queryDSL 적용</li>
<li>성능 최적화 이후 성능 테스트를 통한 지표 측정</li>
</ul>
<hr>
<h1 id="🔟-후기-및-배운-점">🔟 후기 및 배운 점</h1>
<p>기존에 프로젝트를 진행할 때는 postman, swagger 등을 이용하여 기능
테스트를 진행했었는데 이번에 처음으로 테스트 코드를 이용해서 테스트를
진행해보며 테스트 코드의 필요성을 느끼게 되었다. 또한 클린 코드 기반의
리팩토링을 진행하며 앞으로 어떻게 코드를 짜야하는지 방향성에 대해 다시
생각해보는 계기가 되었다.</p>
<hr>
<h1 id="📌-마무리">📌 마무리</h1>
<p>&quot;배달의 민족 서비스 클론 코딩&quot;이라는 주제로 프로젝트를 진행하며 테스트 코드의 중요성을 깨닫고, 레거시 코드를 분석하고 리팩토링 하는 과정에서 앞으로 코드를 작성할 때 어떻게 클린코딩을 해나가야되는지 방향성에 대해 생각해보는 계기가 되었다. 이번 프로젝트에는 성능 최적화 이후 성능 테스트를 통한 지표 측정까지는 하지 못했지만 향후 단위 테스트로 분리하여 테스트 속도를 향상시키고 성능 최적화를 위한 queryDSL을 적용하여 성능 최적화 이후 성능 테스트를 통해 지표를 측정해보면 좋을 것 같다.</p>
<hr>
<h1 id="🔗-참고-자료-및-링크">🔗 참고 자료 및 링크</h1>
<p>Project Repository
<a href="https://github.com/mukmul/BE-02-Woowa">https://github.com/mukmul/BE-02-Woowa</a>
forked from
<a href="https://github.com/prgrms-be-devcourse/BE-02-Woowa?tab=readme-ov-file">https://github.com/prgrms-be-devcourse/BE-02-Woowa?tab=readme-ov-file</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Caused by: java.lang.ClassNotFoundException.../Java Error]]></title>
            <link>https://velog.io/@ij_nim/Caused-by-java.lang.ClassNotFoundException...Java-Error</link>
            <guid>https://velog.io/@ij_nim/Caused-by-java.lang.ClassNotFoundException...Java-Error</guid>
            <pubDate>Sun, 02 Mar 2025 07:19:55 GMT</pubDate>
            <description><![CDATA[<p>버깅/디버깅 프로젝트를 하던 중 .. 에러를 맞닥뜨리게 되었다.
<img src="https://velog.velcdn.com/images/ij_nim/post/b4fa5842-e69b-4724-bfe3-19447c39d744/image.png" alt=""></p>
<p>에러의 내용은 이렇다.</p>
<pre><code>Could not find or load main class com.example.woowa.WoowaApplication
Caused by: java.lang.ClassNotFoundException: com.example.woowa.WoowaApplication</code></pre><p>해당 에러를 처음 보았기 때문에 검색을 해보았는데
JDK 문제 인 것 같았다. 파일명이 잘못되어 인식을 못하던가 버전이 맞지 않는다던가 하는 등의 원인이라고 했는데 나 같은 경우 파일명이 잘못되어 있지도 않았고 버전도 build.gradle에 내가 명시해놓은 버전과 깔려 있는 버전이 동일했다.
또한 명령어로 java -version을 입력해봐도 동일했기 때문에 왜 오류가 난 건지 알 수가 없어서 거의 모든 블로그를 보며 다 따라해봐도 되는게 없었다..</p>
<p>며칠동안 해당 에러와 싸우다보니 노트북을 초기화하고 싶은 생각이 들었지만..
다행히 팀원들이 말려준 덕에.. 노트북 초기화는 면할 수 있었다...^^</p>
<p>계속해서 에러메시지를 보다보니 환경변수를 설정해도 캐시를 지워도 안되는 것을 보고 뭔가 단단히 꼬인 것 같다는 느낌이 들어서 깔아뒀던 모든 JDK를 삭제하고 다시 깔았는데 깃에서도 오류가 났었다.</p>
<p>계속해서 지금 사용하는 계정이 아닌 예전에 사용했던 계정이 연결되는 것을 확인했고ㅠㅠ (그 계정 최근에 클론한적이 단 한번도 없었는데..) 맥북의 키체인 설정까지 들어가서 깃 로그인된것들도 다 삭제했다..</p>
<p>이렇게 깃 초기화, jdk 전부 삭제 후 재설치를 반복하다보니 해결됐다.</p>
<p>해당 프로젝트 만의 문제는 아니었던 것 같은게.. 중간에 데모 프로젝트도 생성해서 돌려봤는데 이것도 제대로 실행이 안되는것을 확인할 수 있었다.
<img src="https://velog.velcdn.com/images/ij_nim/post/89c34054-1e0a-4350-97a4-e8302d85c82a/image.png" alt=""></p>
<p>그냥 전반적으로 봤을때, 맥북에 깃 계정이 로그인이 2개가 되어있었고, JDK도 여러 버전이 깔려있었다보니 꼬여서 오류가 난 것이라 생각했다.</p>
<p>깃을 사용하다보면 이런 자잘한 오류들이 꽤 많이 나는데.. 나는 언제쯤 깃 마스터가 될 수 있을까?? ㅠㅠ 깃 오류인듯 JDK 오류인듯 했던 이번 에러.. 어찌저찌 해결했지만 다신 마주치지 말자...!! </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[2차 CS 스터디 _ DB]]></title>
            <link>https://velog.io/@ij_nim/2%EC%B0%A8-CS-%EC%8A%A4%ED%84%B0%EB%94%94-DB</link>
            <guid>https://velog.io/@ij_nim/2%EC%B0%A8-CS-%EC%8A%A4%ED%84%B0%EB%94%94-DB</guid>
            <pubDate>Sun, 02 Mar 2025 06:23:13 GMT</pubDate>
            <description><![CDATA[<p><strong>일시</strong>: 2024.12.27
<strong>장소</strong>: 용산 청년지음
<strong>주제</strong>: </p>
<h4 id="db">DB</h4>
<ol>
<li>트랜잭션</li>
<li>격리수준 (Isolation Level)<ul>
<li>SERIALIZABLE</li>
<li>REPEATABLE READ</li>
<li>READ COMMITTED</li>
<li>READ UNCOMMITED</li>
</ul>
</li>
<li>데이터베이스 락</li>
<li>pk id길이가 길어지면 일어나는일</li>
<li>JPA flush 시점</li>
<li>데이터베이스 자료형</li>
<li>정규화</li>
<li>데이터베이스 특징</li>
<li>조인</li>
<li>rdbms/nosql</li>
<li>튜닝</li>
<li>데이터베이스 인덱스</li>
<li>클러스터링과 리플리케이션</li>
<li>관계 / 키</li>
</ol>
<h4 id="진행방법">진행방법</h4>
<ol>
<li>6명이서 각자 해당 주제에 대해 학습한 내용을 매주 2회 온라인으로 발표한 후 질문을 준비해온다.</li>
<li>한명씩 준비해온 질문을 하나씩 번갈아가며 질문한 후 자유롭게 대답한다. </li>
<li>대답에 대한 피드백을 서로 주고 받으며 답변을 구체화 시키며 학습한 내용을 복기한다.</li>
</ol>
<h4 id="질문-및-피드백">질문 및 피드백</h4>
<ol>
<li><p><strong>인덱스와 키의 차이점은 무엇인가요</strong></p>
<ul>
<li>키는 데이터의 고유성과 참조 무결성을 보장 인덱스는 검색 속도를 높이기 위한 자료 구조이다.</li>
</ul>
</li>
<li><p>트랜잭션의 커밋과 롤백의 차이에 대해서 설명하세요 </p>
<ul>
<li><p>커밋: 트랜잭션이 끝나면 데이터베이스에 영구적으로 저장</p>
</li>
<li><p>롤백: 트랜잭션이 취소되고 데이터베이스를 트랜잭션 이전의 상태로 복구</p>
</li>
<li><p>트랜잭션 관리자</p>
<p>  트랜잭션의 생명 주기를 관리하는 컴포넌트</p>
<p>  격리 수준 관리, 커밋, 롤백 관리…</p>
</li>
</ul>
</li>
<li><p>영속성 컨텍스트와 그 기능을 말해보세요. </p>
<ul>
<li>영속성 컨텍스트는 엔티티를 영속화하는 환경입니다.
트랜잭션이 커밋되면 영속성 컨텍스트에 있는 쓰기 지연 SQL 저장소의 쿼리들이 db로 날라가고, 데이터들이 영구적으로 저장됩니다.</li>
</ul>
</li>
<li><p>정규화(Normalization)와 비정규화(Denormalization)의 장단점은 무엇인가요? </p>
<ul>
<li>정규화 : 중복을 최소화 하도록 설계, 상당수의 일시적 질의문을 처리하기 위해 많은 조인을 사용한다.</li>
<li>비정규화 : 읽는 시간을 최적화 하도록 설계, 조인 연산 비용을 줄인다, 규모 확장성을 실현하고자 자주 사용, 갱신 이나 삽입 비용이 많이 듬, 일관성, 저장공간 이슈</li>
</ul>
</li>
<li><p>JOIN에 대해서 설명해주세요.</p>
<ol>
<li><strong>JOIN</strong>은 데이터베이스에서 두 개 이상의 테이블을 결합하여 하나의 결과 집합으로 만드는 연산입니다.<ol>
<li>inner join : 교집합</li>
<li>outer join<ol>
<li>left : 왼쪽 기준</li>
<li>right : 오른쪽 기준</li>
<li>full outer → 누락된 값을 찾기 위해서 사용.</li>
</ol>
</li>
<li>cross join : 모든 조합</li>
</ol>
</li>
<li>union(중복 X) vs union all(중복 O)</li>
</ol>
</li>
<li><p>PK 길이가 길어질 때의 문제와 해결방안 </p>
</li>
</ol>
<pre><code>| **문제 유형** | **문제 상황** | **해결 방법** |
| --- | --- | --- |
| 성능 문제 | 인덱스 크기, 비교 비용 | **int, bigint PK**를 사용 |
| 저장 공간 문제 | 테이블, FK 크기 증가 | **숫자형 PK**로 교체 |
| 운영 문제 | 파티셔닝, 샤딩 문제 | **해시 키를 기반으로 샤딩** |
| 페이지 스플릿 | 페이지 스플릿 발생 | **숫자형 PK**로 교체, 클러스터 인덱스 |

클러스터형 인덱스 - PK를 기준으로 테이블을 정렬, 테이블 자체가 인덱스</code></pre><ol start="7">
<li><p>RDBMS가 수평확장(서버를 늘리는 확장) 에 불리한 이유는 무엇인가요? </p>
<p> 1.관계형 데이터 구조상 테이블의 관계를 외래 키 등으로 유지함으로 여러 서버에 나누어 저장하면 이러한 관계를 유지하기 어렵습니다.</p>
<p> 2.조인이 필요한 경우 데이터가 여러 서버에 분산되어 있으면 각 서버에서 데이터를 가져와 결합하여 하므로 성능 저하가 발생합니다.</p>
</li>
<li><p>데이터 무결성을 지키기 위한 제약 조건을 설명하세요 </p>
<ul>
<li>개체 무결성: PK는 중복 안되고 null도 안된다</li>
<li>참조 무결성: 외래키는 null 값을 못 가지고, 참조 테이블의 기본키와 동일해야 한다</li>
<li>도메인 무결성: 속성에 지정된 값만 가질 수 있다</li>
</ul>
</li>
<li><p>클러스터링의 장단점에 대해 말해주세요. </p>
<ul>
<li>(장) 서버가 두 대 이상으로 이뤄져있기 때문에, 한 서버가 다운돼도 서비스에 지장이 가지 않는다.</li>
<li>(단) 데이터 갱신을 하려면 (갱신하려는) 서버 외에 다른 서버들이 요청 수락을 해줘야 하기 때문에 병목현상이 발생할 수 있다.<ol>
<li>1개의 노드에 쓰기 트랜잭션이 수행되고, Commit 실행</li>
<li>실제 디스크에 내용을 쓰기 전에 다른 노드로 데이터의 복제를 요청</li>
<li>다른 노드에서 복제 요청을 수락했다는 신호를 보내고, 디스크에 쓰기를 시작</li>
<li>다른 노드로부터 신호를 받으면 실제 디스크에 데이터를 저장</li>
</ol>
</li>
</ul>
</li>
<li><p>DB 튜닝이란? </p>
<ol>
<li>단순한 퍼포먼스 향상이 아니라 자주 호출하는 SQL이나 프로그램에서 호출되는 SQL 경로등 운영체제, 미들웨어 영역까지 확장해서 자원을 범위로 성능을 향상 시키고 탐색하는 것</li>
</ol>
</li>
<li><p>Primary Key, Foreign Key에 대해 설명해 보세요.
Primary Key(기본 키)는 데이터베이스 테이블에서 각 행(row)을 고유하게 식별하는 열(column) 또는 열의 조합을 말합니다. 키가 소속된 테이블에서 중복되지 않아야 하며, 모든 행은 기본 키 값을 가집니다. 주로 이 키가 식별자(identifier)로 사용됩니다. 각 행을 고유하게 식별하기 때문에 검색, 수정, 삭제, 구분 등의 작업에서 유용하게 사용됩니다.</p>
<p>Foreign Key(외래 키)는 한 테이블의 열(column)이 다른 테이블의 기본 키(primary key)를 참조하는 역할을 합니다. 다른 테이블과의 관계를 형성하여 데이터간의 일관성과 무결성(Integrity)을 유지하는 것에 사용합니다.</p>
<p>외래 키 제약 조건은 데이터베이스 시스템에서 외래 키 값을 검증하고 관리하는 것에 사용합니다. 조건은 부모 테이블(참조 테이블)의 값과 일치하지 않거나 해당 값이 null 상태일 때도 똑같이 적용됩니다.</p>
</li>
<li><p>데드락에 대해 설명해주세요</p>
<ul>
<li>두 트랜잭션 모두가 블로킹 상태에 진입하여 서로의 블로킹을 해결할 수 없는 상태입니다.
트랜잭션 A, B에서 A가 B 트랜잭션에 대해 블로킹 상태로 진입한 경우에, B 트랜잭션이 종료(커밋 or 롤백)되어야 해당 블로킹이 끝나고 트랜잭션 A의 작업이 정상적으로 수행된다. 그러나 해당 상황의 B 트랜잭션에서 A에 대해 블로킹 상태로 진입한다면 마찬가지로 A 트랜잭션이 종료(커밋 or 롤백)되어야 해당 블로킹이 끝나고 트랜잭션 B의 작업이 정상적으로 수행된다. 이때 A와 B가 모두 상대 트랜잭션의 종료를 기다리고 있게 되어 서로의 블로킹을 영원히 해결할 수 없는 상태가 된다.
이러한 상황을 데드락 (Dead Lock)이라고 한다.</li>
</ul>
</li>
<li><p>char와 varchar의 차이점을 설명해주세요 </p>
</li>
</ol>
<h3 id="주요-비교"><strong>주요 비교</strong></h3>
<table>
<thead>
<tr>
<th>특성</th>
<th>CHAR</th>
<th>VARCHAR</th>
</tr>
</thead>
<tbody><tr>
<td><strong>길이</strong></td>
<td>고정 길이</td>
<td>가변 길이</td>
</tr>
<tr>
<td><strong>저장 공간</strong></td>
<td>항상 지정된 길이 사용</td>
<td>실제 데이터 길이 + 1~2바이트</td>
</tr>
<tr>
<td><strong>패딩</strong></td>
<td>남는 공간은 공백으로 채움</td>
<td>패딩 없음</td>
</tr>
<tr>
<td><strong>검색 속도</strong></td>
<td>빠름</td>
<td>느릴 수 있음</td>
</tr>
<tr>
<td><strong>공간 효율성</strong></td>
<td>낮음</td>
<td>높음</td>
</tr>
<tr>
<td><strong>적합한 사용 사례</strong></td>
<td>짧고 고정된 길이 데이터</td>
<td>길이가 가변적인 데이터</td>
</tr>
</tbody></table>
<p><strong>varchar</strong> vs <strong>text</strong></p>
<h3 id="varchar"><strong>VARCHAR</strong></h3>
<ul>
<li>최대 길이가 (상대적으로) 크지 않은 경우</li>
<li>테이블 데이터를 읽을 때 항상 해당 컬럼이 필요한 경우</li>
<li>DBMS 서버의 메모리가 (상대적으로) 충분한 경우</li>
</ul>
<h3 id="text"><strong>TEXT</strong></h3>
<ul>
<li>최대 길이가 (상대적으로) 큰 경우</li>
<li>테이블에 길이가 긴 문자열 타입 컬럼이 많이 필요한 경우</li>
<li>테이블 데이터를 읽을 때 해당 컬럼이 자주 필요치 않은 경우</li>
</ul>
<ol start="14">
<li>트랜잭션이 병렬로 실행될 때 발생하는 문제점에 대해서 아는대로 설명하세요 <ul>
<li><img src="https://velog.velcdn.com/images/ij_nim/post/2c9ce9c1-f8f6-4976-bd7e-45563dca8335/image.png" alt="">
<a href="https://tlatmsrud.tistory.com/118">[DB] 트랜잭션 격리수준 (Isolation Level) 에 쉽게 이해하기 :: 영암사는 승경이네</a></li>
<li><img src="https://velog.velcdn.com/images/ij_nim/post/42ede809-f4d2-44f0-a9d0-e42c021b1b70/image.png" alt=""></li>
</ul>
</li>
</ol>
<p>Non Repeatable Read는 <strong>레코드의 데이터가 달라지는 것</strong>을 의미한다면 </p>
<p>Phantom Read는 기존 조회했던 레코드의 데이터는 달라지지 않지만, <strong>새로운 레코드가 나왔다가 사라졌다가 하는 것</strong>이다. <strong>마치 유령처럼!! :</strong>(</p>
<ul>
<li><p>dirty read: 아직 커밋되지 않은 트랜잭션의 데이터를 읽는 경우</p>
</li>
<li><p>non-repeatable read: 같은 데이터를 조회했는데 다른 값이 나오는 경우</p>
<p>  (하나의 튜플에서 변경이 일어나거나 삭제가 될 때)</p>
</li>
<li><p>phantom read: 동일한 쿼리를 보냈을 때 조회의 결과가 다른 것</p>
<p>  (한 테이블에서 삭제나 변경이 일어날 때 ?)</p>
</li>
</ul>
<ol start="15">
<li><p>데이터베이스 Lock의 종류에 대해 말하고 각각에 대해 설명해주세요.</p>
<ul>
<li>공유 Lock<ul>
<li>데이터를 읽을 때 사용한다.</li>
<li>다른 공유 Lock 과 호환되지만, 배타적 Lock 과는 호환되지 않는다.</li>
<li>즉, 자신이 읽고 있는 리소스를 다른 사용자도 같이 읽을 수 있다는 의미이다. (하지만 변경은 불가능하다는 의미)</li>
</ul>
</li>
<li>배타적 Lock<ul>
<li>데이터를 변경할 때 사용한다.</li>
<li>해당 Lock 은 해제될 때까지 다른 트랜잭션이 해당 리소스에 접근할 수 없다. (변경 읽기 모두 불가능하다)</li>
</ul>
</li>
<li>접근하려는 리소스에 배타적 Lock 이 걸려있어 접근하지 못하고(Lock 경합 발생) 작업을 진행하지 못해 멈춰 선 상태를 블로킹(Blocking)이라고 한다.</li>
</ul>
</li>
<li><p><strong>락과 격리 수준의 차이점</strong></p>
</li>
</ol>
<table>
<thead>
<tr>
<th>항목</th>
<th>락 (Lock)</th>
<th>격리 수준 (Isolation Level)</th>
</tr>
</thead>
<tbody><tr>
<td><strong>정의</strong></td>
<td>데이터에 대한 접근을 제어하는 메커니즘</td>
<td>트랜잭션이 데이터에 접근할 때 다른 트랜잭션과의 상호작용을 제어하는 수준</td>
</tr>
<tr>
<td>17. RDBMS VS NoSQL (특징, 차이점)</td>
<td></td>
<td></td>
</tr>
</tbody></table>
<ol start="18">
<li>flush와 commit차이점</li>
</ol>
<h3 id="commit과-flush의-차이점-요약"><strong>Commit과 Flush의 차이점 요약</strong></h3>
<table>
<thead>
<tr>
<th>항목</th>
<th><strong>Commit</strong></th>
<th><strong>Flush</strong></th>
</tr>
</thead>
<tbody><tr>
<td><strong>목적</strong></td>
<td>트랜잭션을 <strong>완료</strong>하고 모든 변경을 <strong>영구적으로 반영</strong></td>
<td>영속성 컨텍스트의 변경 사항을 <strong>즉시 동기화</strong>하여 데이터베이스에 반영</td>
</tr>
<tr>
<td><strong>트랜잭션 상태</strong></td>
<td>트랜잭션을 <strong>완료</strong>시킴, 롤백할 수 없음</td>
<td>트랜잭션의 <strong>중간 상태</strong>에서 호출될 수 있음</td>
</tr>
<tr>
<td><strong>데이터베이스 반영</strong></td>
<td>모든 변경 사항을 <strong>영구적으로 저장</strong></td>
<td>변경 사항을 <strong>즉시 반영</strong>하지만 트랜잭션을 종료하지 않음</td>
</tr>
<tr>
<td><strong>영속성 컨텍스트 상태</strong></td>
<td><strong>완료된</strong> 트랜잭션으로 상태가 변경</td>
<td>영속성 컨텍스트의 <strong>현재 상태</strong>를 데이터베이스에 동기화</td>
</tr>
<tr>
<td><strong>실행 시점</strong></td>
<td>트랜잭션 끝에서 호출</td>
<td>트랜잭션 중 언제든지 호출 가능</td>
</tr>
<tr>
<td><strong>예시</strong></td>
<td><code>transaction.commit()</code></td>
<td><code>entityManager.flush()</code></td>
</tr>
</tbody></table>
<h3 id="느낀점">느낀점</h3>
<p>혼자 학습하고 정리할 때 보다 다같이 모여 학습한 내용에 대해 질문하고 답변하는 시간을 가지니, 이해가 안됐던 부분도 서로 도움을 통해 이해할 수 있고 학습 내용을 복기할 수 있는 시간을 가질 수 있어 좋았다.</p>
<p>또한 책을 통해 학습 한 내용들도 있지만, 여러 블로그를 통해 학습한 내용들도 많았는데 같이 이야기 나누다보니 좀 더 정확한 정보들을 얻어낼 수 있었다.</p>
<p>이 다음 주제는 네트워크로 세부 주제들도 다 정해놓은 상태이지만 이 스터디 이후로 KDT에서 다함께 프로젝트를 매일 진행하다보니 현재는 잠시 중단된 상태이지만 빠른시일내로 다시 시작할 예정이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[졸업작품] 마무리 ....]]></title>
            <link>https://velog.io/@ij_nim/%EC%A1%B8%EC%97%85%EC%9E%91%ED%92%88-%EB%A7%88%EB%AC%B4%EB%A6%AC-</link>
            <guid>https://velog.io/@ij_nim/%EC%A1%B8%EC%97%85%EC%9E%91%ED%92%88-%EB%A7%88%EB%AC%B4%EB%A6%AC-</guid>
            <pubDate>Sun, 02 Mar 2025 05:11:37 GMT</pubDate>
            <description><![CDATA[<h4 id="github">GitHub</h4>
<ol>
<li><a href="https://github.com/ijnim1121/Capstone_web">spring-server</a></li>
<li><a href="https://github.com/SRASONY/Capstone_flask">flask-server</a></li>
</ol>
<p>프로젝트의 자세한 설명은 리드미 참고 ~ 🙏</p>
<hr>
<p>이번 졸작 프로젝트는 스프링으로 메인 서버를 구축하고 딥러닝 처리를 위해 flask 서버를 구축하여 개발했다.</p>
<h4 id="작품-구성도">작품 구성도</h4>
<p><img src="https://velog.velcdn.com/images/ij_nim/post/26ede47e-016c-4cfc-b90d-d10175a0eb47/image.png" alt=""></p>
<p>우선 우리 프로젝트는 공모전 수상 경험이 있던 주제를 업그레이드 하여 
모바일앱 -&gt; 웹 으로 변경하고 기존 센서 기능 + 딥러닝 기술을 추가하여 디벨롭 하였다.</p>
<h4 id="ver1">&lt;VER.1&gt;</h4>
<p>모바일 앱(앱 인벤터로 제작) + firebase(DB) + 아두이노 센서</p>
<h4 id="ver2">&lt;VER.2&gt;</h4>
<p>웹 서버(스프링부트) + 딥러닝 서버(Flask) + MySQL(DB) + 아두이노 센서 + 딥러닝(YOLOv8)</p>
<ul>
<li>팀 멤버가 BE 4명으로 구성되어 있었기 때문에 프론트는 부트스트랩 사용해서 간단하게 만들었다. </li>
</ul>
<h4 id="동작-프로세스">동작 프로세스</h4>
<p><img src="https://velog.velcdn.com/images/ij_nim/post/9890329a-694a-417f-bcf3-92778f0f4470/image.png" alt=""></p>
<p>졸업 작품을 마무리 지은지도 5개월이 지났고.. 지난달엔 졸업까지 마무리 지었다.</p>
<p>졸작을 통해 이전의 프로젝트를 디벨롭 할 수 있어 좋은 경험이었고, 웹의 동작 프로세스를 정확히 이해하계 된 계기가 된 것 같다. </p>
<p>플라스크 서버는 딥러닝기술을 위해 급하게 개발하여 정확히 공부하지 못했지만 기회가 된다면 플라스크에 대해서도 제대로 배워보고 싶다.</p>
<p>이상 졸업 작품 끝!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로젝트 기획 회의 회고록] / Jira 사용하여 협업하기]]></title>
            <link>https://velog.io/@ij_nim/%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EA%B8%B0%ED%9A%8D-%ED%9A%8C%EC%9D%98-%ED%9A%8C%EA%B3%A0%EB%A1%9D-Jira-%EC%82%AC%EC%9A%A9%ED%95%98%EC%97%AC-%ED%98%91%EC%97%85%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@ij_nim/%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EA%B8%B0%ED%9A%8D-%ED%9A%8C%EC%9D%98-%ED%9A%8C%EA%B3%A0%EB%A1%9D-Jira-%EC%82%AC%EC%9A%A9%ED%95%98%EC%97%AC-%ED%98%91%EC%97%85%ED%95%98%EA%B8%B0</guid>
            <pubDate>Wed, 26 Feb 2025 14:20:07 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>4F 방법</p>
</blockquote>
<ul>
<li>사실(Fact): 일어난 일에 대한 객관적인 기록</li>
<li>느낌(Feeling): 상황에 대한 감정적인 반응</li>
<li>교훈(Finding): 경험을 통해 배울 수 있었던 것</li>
<li>향후 행동(Future action): 향후 할 수 있는 개선된 행동</li>
</ul>
<h3 id="fact">Fact</h3>
<p>다음과 같은 이유로 Jira를 사용하게 되었다.</p>
<ol>
<li><p>업무 관리 &amp; 협업 효율성 증가
할 일(Tasks) 정리: 개발할 기능, 버그 수정, 개선 사항 등을 티켓(issue)으로 만들어서 관리할 수 있다.
담당자 지정: 팀원들에게 업무를 배정하고 진행 상태를 확인할 수 있다.
우선순위 설정: 어떤 업무가 더 중요한지 정하고, 중요한 일부터 해결할 수 있도록 도와준다.</p>
</li>
<li><p>애자일 개발 프로세스 지원
스크럼(Scrum) &amp; 칸반(Kanban) 보드 제공: 팀이 스프린트(짧은 개발 주기)를 진행하거나, 칸반 보드에서 작업을 이동하며 진행 상황을 체크할 수 있다.
백로그 관리: 해야 할 일들을 미리 정리해두고, 스프린트 계획을 세울 때 쉽게 가져와서 개발할 수 있다.</p>
</li>
<li><p>이슈 추적 &amp; 버그 관리
코드 수정이 필요한 버그를 쉽게 기록하고, 개발 진행 상황을 추적할 수 있다.
특정 버그가 언제, 어떻게 해결됐는지도 확인 가능해서 유지보수가 편리하다.</p>
</li>
<li><p>CI/CD 및 기타 툴과 연동
Bitbucket, GitHub, Jenkins 같은 개발 도구들과 연동 가능해서 코드 변경 사항과 이슈를 연계할 수 있디.
자동화된 테스트 및 배포 과정과 연결하면, 특정 이슈가 완료되었을 때 자동으로 빌드하고 배포할 수도 있다.</p>
</li>
<li><p>팀 생산성 분석 &amp; 리포트
개발 속도, 완료된 작업량, 남은 작업 등을 시각적으로 보여주는 대시보드를 제공해서 팀의 성과를 분석할 수 있다.
버전 릴리즈 계획도 쉽게 관리 가능해서 프로젝트의 진행 상황을 체계적으로 관리할 수 있다.</p>
</li>
<li><p>문서화 &amp; 기록 관리
&quot;어떤 기능을 언제, 누가 개발했는지&quot; 기록이 남아서 협업이 원활하다.
프로젝트 진행 중 발생한 이슈와 해결 과정도 문서화할 수 있어서, 나중에 참고하기 좋다.</p>
</li>
</ol>
<hr>
<h3 id="feeling">Feeling</h3>
<p><img src="https://velog.velcdn.com/images/ij_nim/post/659f1e2f-8aa1-4727-8f90-bbfb4323a9e4/image.png" alt=""></p>
<p>지라를 통해 관리하다보니 해야 할 일을 한눈에 파악 할 수 있었다.</p>
<hr>
<h3 id="finding">Finding</h3>
<p>협업을 도와주는 툴을 사용하는 것이 확실히 일정관리에도 도움이 되고 기록으로도 남으니 나중에 참고할 수 있어 확실히 좋다는 것을 알게되었다.</p>
<hr>
<h3 id="future-action">Future action</h3>
<p>앞으로 진행하는 프로젝트에서는 Jira를 잘 활용해야겠다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로젝트 기획 회의 회고록] / Figma 사용하여 UI 디자인 하기]]></title>
            <link>https://velog.io/@ij_nim/%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EA%B8%B0%ED%9A%8D-%ED%9A%8C%EC%9D%98-%ED%9A%8C%EA%B3%A0%EB%A1%9D-Figma-%EC%82%AC%EC%9A%A9%ED%95%98%EC%97%AC-UI-%EB%94%94%EC%9E%90%EC%9D%B8-%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@ij_nim/%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EA%B8%B0%ED%9A%8D-%ED%9A%8C%EC%9D%98-%ED%9A%8C%EA%B3%A0%EB%A1%9D-Figma-%EC%82%AC%EC%9A%A9%ED%95%98%EC%97%AC-UI-%EB%94%94%EC%9E%90%EC%9D%B8-%ED%95%98%EA%B8%B0</guid>
            <pubDate>Wed, 26 Feb 2025 13:51:41 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>4F 방법</p>
</blockquote>
<ul>
<li>사실(Fact): 일어난 일에 대한 객관적인 기록</li>
<li>느낌(Feeling): 상황에 대한 감정적인 반응</li>
<li>교훈(Finding): 경험을 통해 배울 수 있었던 것</li>
<li>향후 행동(Future action): 향후 할 수 있는 개선된 행동</li>
</ul>
<h3 id="fact">Fact</h3>
<p>프론트엔드 개발자나 디자이너와 협업을 했다면 UI디자인은 해볼 일이 없었겠지만, 현재 프로젝트에는 백엔드 개발자로만 구성되어 있어 UI디자인이 있었으면 좋겠다는 판단하에, 또한 교육 과정 중 피그마 사용법에 대해 알게 되어 피그마를 사용하여 UI 디자인을 해보게 되었다.</p>
<hr>
<h3 id="feeling">Feeling</h3>
<p>처음 써보는 툴이라서 아직 서툴기는 하지만 이렇게 프로토타입을 제작해 볼 수 있다는 점에서 편리한 툴이라는 생각이 들었다. 피그마를 알기 전에는 직접 손그림을 대충 그려보거나 파워포인트 같은 것들로 UI의 느낌을 대강 표현해보았었는데, 확실히 피그마라는 툴을 쓰니까 편리했다.</p>
<hr>
<h3 id="finding">Finding</h3>
<p><img src="https://velog.velcdn.com/images/ij_nim/post/dabcee63-2fc3-4681-b9aa-0d64c7092c39/image.png" alt=""></p>
<p>내가 디자이너는 아니다보니 휴대폰에 깔려있는 여러 앱들을 보며 참고해가며 이런식으로 UI를 디자인했다. 생각보다 사용자의 편리성을 생각하는 측면이 어려웠다.</p>
<hr>
<h3 id="future-action">Future action</h3>
<p>실무에서 내가 직접 디자인을 하게 될 일은 없겠지만 피그마를 사용할 줄 알게되어 협업에 있어 도움이 될 것이라 생각하고 백엔드 개발을 할 때 간단한 프로토타입 정도는 만들 수 있을 것 같다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로젝트 개발 회의 회고록] / 모듈화]]></title>
            <link>https://velog.io/@ij_nim/%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EA%B0%9C%EB%B0%9C-%ED%9A%8C%EC%9D%98-%ED%9A%8C%EA%B3%A0%EB%A1%9D-%EB%AA%A8%EB%93%88%ED%99%94</link>
            <guid>https://velog.io/@ij_nim/%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EA%B0%9C%EB%B0%9C-%ED%9A%8C%EC%9D%98-%ED%9A%8C%EA%B3%A0%EB%A1%9D-%EB%AA%A8%EB%93%88%ED%99%94</guid>
            <pubDate>Wed, 11 Dec 2024 09:41:58 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>4F 방법</p>
</blockquote>
<ul>
<li>사실(Fact): 일어난 일에 대한 객관적인 기록</li>
<li>느낌(Feeling): 상황에 대한 감정적인 반응</li>
<li>교훈(Finding): 경험을 통해 배울 수 있었던 것</li>
<li>향후 행동(Future action): 향후 할 수 있는 개선된 행동</li>
</ul>
<h3 id="fact">Fact</h3>
<p>프로젝트 기획을 마치고 개발을 위해 패키지 구성을 어떻게 할지 정하는 중 
계층형과 도메인형중 어느것을 선택할지 이야기가 나왔다.</p>
<h3 id="1️⃣-계층형-패키지-구조-layered-package-structure">1️⃣ 계층형 패키지 구조 (Layered Package Structure)</h3>
<p>기능별 역할(계층)로 패키지를 구분하는 방식</p>
<h4 id="📂-구조-예시">📂 구조 예시</h4>
<pre><code>com.example.project
 ┣ 📂 controller
 ┣ 📂 service
 ┣ 📂 repository
 ┣ 📂 dto
 ┣ 📂 config
 ┗ 📂 domain (또는 entity)</code></pre><h4 id="📌-구조-설명">📌 구조 설명</h4>
<p>controller: 클라이언트 요청을 처리하는 API 엔드포인트와 관련된 클래스
service: 비즈니스 로직을 담당하는 클래스
repository: 데이터베이스와 직접 상호작용하는 클래스 (JPA의 Repository 인터페이스)
dto: 클라이언트와 데이터를 주고받기 위한 데이터 전송 객체
domain (entity): 데이터베이스와 매핑되는 엔티티 클래스 (JPA Entity)
config: 보안, CORS, OAuth2 등 설정 파일</p>
<h4 id="📚-장점">📚 장점</h4>
<p>명확한 계층 구분: 각 계층의 역할이 명확하므로, 코드를 처음 접하는 개발자도 쉽게 이해할 수 있습니다.
재사용성 향상: Controller, Service, Repository를 재사용하기 쉽습니다.
확장성: 계층별로 기능이 추가될 때 쉽게 확장할 수 있습니다.</p>
<h4 id="🔥-단점">🔥 단점</h4>
<p>파일 간 의존 관계가 복잡: 관련 도메인에 속하는 로직이 여러 패키지에 흩어져 있어 파일 이동이 빈번합니다.
도메인 간 비즈니스 로직 결합이 어려움: 여러 도메인에 걸친 복잡한 비즈니스 로직을 처리하기 어렵습니다.
변경에 취약: 특정 도메인에 변경이 필요할 경우, 여러 패키지(controller, service, repository)를 수정해야 합니다.</p>
<h3 id="2️⃣-도메인형-패키지-구조-domain-package-structure">2️⃣ 도메인형 패키지 구조 (Domain Package Structure)</h3>
<p>도메인 단위로 패키지를 구분하는 방식</p>
<h4 id="📂-구조-예시-1">📂 구조 예시</h4>
<pre><code>com.example.project
 ┣ 📂 user
 ┃   ┣ 📂 controller
 ┃   ┣ 📂 service
 ┃   ┣ 📂 repository
 ┃   ┣ 📂 dto
 ┃   ┗ 📂 entity
 ┣ 📂 product
 ┃   ┣ 📂 controller
 ┃   ┣ 📂 service
 ┃   ┣ 📂 repository
 ┃   ┣ 📂 dto
 ┃   ┗ 📂 entity
 ┗ 📂 config</code></pre><h4 id="📌-구조-설명-1">📌 구조 설명</h4>
<p>user 도메인: 사용자와 관련된 기능(로그인, 회원가입, 정보수정 등)과 관련된 모든 클래스가 모여있습니다.
product 도메인: 제품과 관련된 기능(상품 조회, 상품 등록, 상품 수정 등)과 관련된 모든 클래스가 모여있습니다.
공통 패키지 (config, global 등): 보안, CORS, 예외 처리 등 공통 설정 파일이 위치합니다.</p>
<h4 id="📚-장점-1">📚 장점</h4>
<p>높은 응집도: 도메인 단위로 모듈화되기 때문에 관련 클래스가 한 곳에 모여 있습니다.
변경에 유연: 특정 도메인의 기능 변경이 필요할 때 해당 도메인 패키지만 수정하면 됩니다.
비즈니스 로직 중심: 비즈니스 요구사항에 맞는 구조로 설계할 수 있습니다.
모듈화 용이: 하나의 도메인에 모든 요소가 모여 있으므로 독립적인 모듈로 만들기 쉽습니다.</p>
<h4 id="🔥-단점-1">🔥 단점</h4>
<p>중복 코드 발생: 여러 도메인에 공통적으로 사용되는 유틸리티, 예외처리, 공통 서비스 로직이 중복될 가능성이 있습니다.
도메인 간 관계 파악이 어려움: 도메인 간 연관 관계를 파악하기 어려울 수 있습니다.
초기 설계가 중요: 도메인 단위로 나누는 과정에서 잘못된 도메인 설계가 프로젝트에 큰 영향을 미칠 수 있습니다.</p>
<p><img src="https://velog.velcdn.com/images/ij_nim/post/0330366c-5903-4d06-88a2-b851c4e20d62/image.png" alt=""></p>
<h3 id="🔥-어떤-구조를-선택해야-할까">🔥 어떤 구조를 선택해야 할까?</h3>
<p><strong>1️⃣ 단순한 CRUD 프로젝트:</strong>
계층형 구조 추천
규모가 작은 프로젝트는 계층형 구조가 더 단순하고 직관적입니다.
<strong>2️⃣ 대규모 프로젝트, 도메인이 명확한 경우:</strong>
도메인형 구조 추천
여러 개발자가 협업할 때, 도메인 단위로 업무를 나누고 각 도메인에 맞는 코드만 작업하면 되므로 협업에 유리합니다.
<strong>3️⃣ 마이크로서비스 아키텍처 (MSA) 프로젝트:</strong>
도메인형 구조 필수
MSA는 도메인 단위로 서비스를 나누기 때문에, 도메인 중심으로 코드를 관리하는 것이 적합합니다.</p>
<hr>
<h3 id="feeling">Feeling</h3>
<p>지금까지 해왔던 프로젝트들은 전부 계층형 패키지 구조를 사용해왔어서 도메인형에 대한 정보가 많이 없었지만 최근 참여하고 있는 교육에서 강사님께서 도메인형으로 프로젝트를 진행하고 계셔서 그 구조를 참고하였다.</p>
<p>우리 프로젝트의 경우 기능이 많아서 대규모 프로젝트에 속하는 편이고, 도메인이 명확하며 6명이서 협업하기 때문에 도메인 단위로 업무를 나누고 각 도메인에 맞는 코드를 작업하는 것이 좋겠다 생각하여 도메인형 구조를 선택하게 되었다.</p>
<hr>
<h3 id="finding">Finding</h3>
<p>우리 프로젝트의 경우 기능이 많다보니, 어디까지 나눠야 하는지 기준이 명확하지 않아 어려움을 겪었었다. 기능 간의 관계를 생각해보며 여러 곳에 쓰이는 기능이라면 코드 중복을 피하기 위해서 따로 모듈로 빼는 것이 좋다고 판단하였다.
팀원들과 회의를 통해 기능 간의 관계성을 생각해볼 수 있는 시간이었다.</p>
<hr>
<h3 id="future-action">Future action</h3>
<p>앞으로 프로젝트를 시작할 때는 내가 진행하는 프로젝트가 어떤 특징을 가지고 있는지 파악한 후 어떤 구조를 사용하면 좋을 지 먼저 생각하는 습관을 가져야겠다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로젝트 기획 회의 회고록] / ERD 설계]]></title>
            <link>https://velog.io/@ij_nim/%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EA%B8%B0%ED%9A%8D-%ED%9A%8C%EC%9D%98-%ED%9A%8C%EA%B3%A0%EB%A1%9D-ERD-%EC%84%A4%EA%B3%84</link>
            <guid>https://velog.io/@ij_nim/%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EA%B8%B0%ED%9A%8D-%ED%9A%8C%EC%9D%98-%ED%9A%8C%EA%B3%A0%EB%A1%9D-ERD-%EC%84%A4%EA%B3%84</guid>
            <pubDate>Tue, 10 Dec 2024 15:24:30 GMT</pubDate>
            <description><![CDATA[<h3 id="프로젝트-기획-회고록">프로젝트 기획 회고록</h3>
<blockquote>
<p>4F 방법</p>
</blockquote>
<ul>
<li>사실(Fact): 일어난 일에 대한 객관적인 기록</li>
<li>느낌(Feeling): 상황에 대한 감정적인 반응</li>
<li>교훈(Finding): 경험을 통해 배울 수 있었던 것</li>
<li>향후 행동(Future action): 향후 할 수 있는 개선된 행동</li>
</ul>
<h3 id="fact">Fact</h3>
<p>프로젝트 기획을 하고 필요한 기능들을 정리 한 후 어떤 기술 스택을 사용할 것인지와 기술에 대한 세부사항을 적고 구현할 우선순위를 정한 후 ERD 설계를 시작했다.
<img src="https://velog.velcdn.com/images/ij_nim/post/7d03d877-040e-48d5-a316-8189a0294296/image.png" alt="">
<img src="https://velog.velcdn.com/images/ij_nim/post/530dd30e-ed72-4e68-ad34-8d8f77fc1972/image.png" alt="">
<img src="https://velog.velcdn.com/images/ij_nim/post/a19fd9ca-2b3b-420a-9663-d6ed95a829ee/image.png" alt="">
<img src="https://velog.velcdn.com/images/ij_nim/post/49501af4-981f-4223-987d-f9087d3e86e4/image.png" alt=""></p>
<p>이를 기반으로 ERD 설계를 하였다. 이렇게 제대로된 ERD를 처음 만들어보기도 하고, 생각보다 기능이 많아서 그 기능들간의 관계성 등을 생각하다보니 시간이 꽤 오래걸렸다.</p>
<p>자료형을 정하는 데에 있어서는 어느정도 통일을 하고 팀원 6명을 세팀으로 나눠 작업했다. </p>
<p><img src="https://velog.velcdn.com/images/ij_nim/post/001664e2-44b2-4aa3-a66a-ab9a3b1474d6/image.png" alt=""></p>
<p>PK를 정하는 과정에서 AUTO INCREMENT로 해야할지, UUID를 사용해야 할지 에 대한 논쟁이 발생했다.</p>
<h3 id="feeling">Feeling</h3>
<p>우선 이런 복잡한 ERD를 설계해본적이 처음이라 생각보다 고려해야할 점들이 많아서 어려웠다. 그리고 PK에 대한 문제는 어떻게 해야할지 고민이 많이 됐었다. 우리 프로젝트가 분산 환경이 아니라는 점과, 대규모 서비스로 운영할 계획이 아직 없다는 점, 조회가 어렵다는 점에서 UUID를 굳이 써야할까?하는 생각이 들었었다. 보통 UUID는 분산 환경에서 많이 쓰이기 때문이다. 그러나 Auto Increment를 쓰게 된다면 보안이 좋지 않다는 점에서 문제가 생겼다. 처음에는 우리가 분산 환경이라고 생각해서 uuid를 쓰기로 했었다. 그러나 우리는 db를 여러개 쓰는 것이지 분산환경은 아니었다. 이에 보안을 위해 uuid를 쓸 것인지, 조회 성능을 위해 auto increment를 쓸 것인지 고민했다.</p>
<hr>
<h3 id="finding">Finding</h3>
<p>결과적으로, 우리는 분산환경이 아니기 때문에 uuid는 쓰지 않고 auto increment를 쓰되, 발생할 수 있는 보안상의 문제는 secret key를 만들어 사용하기로 했다. </p>
<p>이 문제를 논의하는 과정에서 백엔드 개발자로 일하고 있는 선배에게 조언을 구했었는데 둘 중 무엇을 선택하던 정답은 없지만 어떤 것을 선택하는 이유가 명확하기만 하면 된다는 말을 들었다. 이렇게 결정하는 것도 개발자의 능력이구나 하는 생각이 들었다. 좋은 결정을 내리려면 관련 지식이 풍부해야한다는 것을 다시 한번 느끼게 되었다.</p>
<hr>
<h3 id="future-action">Future action</h3>
<p>auto increment를 사용하면서 발생하는 보안상의 문제를 방지하기 위해 secret key를 만들어 사용하기로 했기 때문에, 이에 대한 공부를 할 예정이다.</p>
<p>앞으로는 어떤 기술을 사용할 지 정할 때 그 기술들의 장단점을 명확히 알아봐야겠다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[API 명세서 작성하기]]></title>
            <link>https://velog.io/@ij_nim/API-%EB%AA%85%EC%84%B8%EC%84%9C-%EC%9E%91%EC%84%B1%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@ij_nim/API-%EB%AA%85%EC%84%B8%EC%84%9C-%EC%9E%91%EC%84%B1%ED%95%98%EA%B8%B0</guid>
            <pubDate>Tue, 10 Dec 2024 15:01:13 GMT</pubDate>
            <description><![CDATA[<p>POST: 새 리소스 생성 시 사용, 주로 body 사용
PUT: 리소스 전체 업데이트 시 사용, body 사용
PATCH: 리소스 부분 업데이트 시 사용, body 사용
DELETE: 리소스 삭제 시 사용, 주로 path parameter 사용
GET: 리소스 조회 시 사용, 주로 query parameter 사용</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[1차 CS 스터디 _ 자바]]></title>
            <link>https://velog.io/@ij_nim/1%EC%B0%A8-CS-%EC%8A%A4%ED%84%B0%EB%94%94-%EC%9E%90%EB%B0%94</link>
            <guid>https://velog.io/@ij_nim/1%EC%B0%A8-CS-%EC%8A%A4%ED%84%B0%EB%94%94-%EC%9E%90%EB%B0%94</guid>
            <pubDate>Tue, 10 Dec 2024 14:56:47 GMT</pubDate>
            <description><![CDATA[<p>현재 알고리즘 스터디와 프로젝트를 진행하고 있는 팀원들과 CS 면접 스터디를 시작했다. <del>(사실 시작한지 한달도 넘었는데..)</del></p>
<p>우선 우리는 매일 스터디를 진행하고 있기 때문에, 매주 화요일, 금요일은 개념 발표하는 시간으로 갖고 매달 말에 커밋 등으로 만나는 날 모의 면접을 하는 방식으로 진행하고 있다.</p>
<h4 id="✅-매주-화요일-금요일-개념-발표">✅ 매주 화요일, 금요일 개념 발표</h4>
<h4 id="✅-매달-1회-모의-면접">✅ 매달 1회 모의 면접</h4>
<h3 id="🧑🏫-스터디-방식-제안">🧑‍🏫 스터디 방식 제안</h3>
<ul>
<li>목적<ul>
<li>올바른 개발을 위해 CS 지식을 꾸준히 공부한다.</li>
<li>면접 때 알고 있는 지식을 요약해서 잘 전달할 수 있도록 한다.</li>
<li>각자의 장점과 단점을 알고 더 성장하자.</li>
</ul>
</li>
<li>개념 발표<ul>
<li>진행방식<ul>
<li>각자 준비한 내용 발표</li>
<li>팀원에게 자신이 공부한 파트 부분 모의 퀴즈<ul>
<li>질문받는 사람을 랜덤으로 선정하여 본인이 공부한 부분에 대해서 알고있는지 확인.</li>
<li>모를 경우에 해당 내용을 알고 있는 다른 스터디원이 추가 설명 또는 질문자가 다시 설명.</li>
</ul>
</li>
<li>서로의 정리 내용을 보고 궁금한 점 질문</li>
<li>따로 알게 된 사실 공유</li>
<li>해당 주제에서 질문할 수 있는 내용 공유</li>
</ul>
</li>
<li>스터디 주제<ul>
<li>네트워크</li>
<li>운영체제</li>
<li>데이터베이스</li>
<li>자료구조</li>
<li>자바</li>
<li>스프링</li>
</ul>
</li>
</ul>
</li>
<li>모의 면접<ul>
<li>진행<ul>
<li>주제별 2주 간의 팀별 스터디가 끝나면 모의 면접 진행</li>
<li>각자 면접 질문을 준비해온다.</li>
<li>랜덤으로 1:1로 질문한다.</li>
<li>출제자가 면접자에게 질문하며 Notion에 질문을 입력한다.</li>
<li>면접자는 notion을 보지 않는다.</li>
<li>그외 스터디원은 노션에 피드백을 입력한다.</li>
<li>면접자가 대답을 한 후 추가적인 설명을 덧붙이고 싶은 스터디원은 자유롭게 이야기한다.</li>
<li>만약 면접자가 대답을 못해 pass를 외친 경우 다른 스터디원 중 대답할 수 있는 자가 대답을 한다.</li>
<li>모두 대답하지 못한 경우에는 해당 개념에 대해 같이 이야기를 나눈다.</li>
</ul>
</li>
<li>질문 내용<ul>
<li>주제에 대한 학습이 되었는지 확인한다.</li>
<li>출제자와 다른 스터디원 중 꼬리 질문이 가능하다면 꼬리질문도 출제한다.</li>
</ul>
</li>
<li>서기<ul>
<li>출제자가 질문 후 노션에 본인 질문 작성</li>
<li>전전 출제자가 현재 면접자의 답변을 요약해서 정리</li>
</ul>
</li>
<li>피드백<ul>
<li>면접자가 의도한 방향과 답변이 무엇이었는지 설명하고, 다른 스터디원들도 추가적으로 피드백하는 방식</li>
<li>답변 후 간단하게 면접자 피드백 작성<ul>
<li>좋은 점</li>
<li>아쉬운 점</li>
<li>개선할 점</li>
</ul>
</li>
</ul>
</li>
<li>회고<ul>
<li>모의 면접이 끝난 후<ul>
<li>KPT<ul>
<li>Keep : 좋았던 부분, 앞으로 유지하고 싶은 방식</li>
<li>Problem : 잘 되지 않았던 부분, 개선이 필요한 방식</li>
<li>Try : Problem을 해결할 수 있도록 실천해보고 싶은 솔루션 제시</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="🧑🏫-스터디-순서">🧑‍🏫 스터디 순서</h3>
<p>⇒  자바 → db → 네트워크 → 운영체제 → 스프링 → 자료구조 + 디자인패턴</p>
<h1 id="1차-cs-스터디-주제--자바">1차 CS 스터디 주제 : 자바</h1>
<ol>
<li>JVM, JDK, JRE, JIT</li>
<li>동등성, 동일성 (equals, hashCode)</li>
<li>객체 지향<ul>
<li>4가지 특징<ol>
<li>추상화</li>
<li>상속</li>
<li>다형성</li>
<li>캡슐화</li>
</ol>
</li>
<li>SOLID (5가지 원칙)<ol>
<li>SRP</li>
<li>OCP</li>
<li>LSP</li>
<li>ISP</li>
<li>DIP</li>
</ol>
</li>
</ul>
</li>
<li>불변성</li>
<li>제네릭 타입</li>
<li>컬렉션(Collections)</li>
<li>람다 · 스트림</li>
<li><strong>자바 컴파일 과정</strong></li>
<li><strong>call by value, call by reference</strong></li>
<li><strong>인터페이스와 추상클래스의 차이</strong></li>
<li><strong>클래스 · 객체 · 인스턴스의 차이</strong></li>
<li>예외처리</li>
<li><strong>캡슐화와 은닉화의 차이</strong></li>
<li><strong>자바의 장단점</strong></li>
<li><strong>String, StringBuffer, StringBuilder의 차이</strong></li>
<li>비동기(async) · 동기 (Concurrency)</li>
<li>스레드 (synchronized)</li>
<li>오버로딩과 오버라이딩의 차이</li>
<li>가바지 컬렉션(Garbage Collection)</li>
<li>static, final</li>
<li>접근 지정자 public, protected, default(패키지 접근), private</li>
</ol>
<p>한달동안 이 주제들에 대해 공부한 후 대면으로 모여 각자 10개 정도의 질문을 뽑아와서 한명씩 돌아가면서 질문을 제시하고 질문에 대한 답을 아는 사람들이 대답하고 그 대답에 대해 피드백하는 방식으로 진행했다.</p>
<h4 id="느낀-점">느낀 점</h4>
<p>내가 생각보다 대답을 거의 못해서 .. 더 열심히 해야겠다고 생각했고 CS 지식들을 책에서 공부한 것도 있지만 구글 검색으로 공부한 것들도 많았는데 잘못 알고 있는 부분들도 꽤 있었어서 서로 피드백하며 고쳐나간 부분이 좋았다.</p>
<p>내가 준비해갔던 질문 리스트인데, 다른 사람들과 겹치는 부분도 있어서 그에 대한 피드백도 같이 정리해두었다.</p>
<p><img src="https://velog.velcdn.com/images/ij_nim/post/5411fa81-60b8-4368-aca4-1e4c55cf302a/image.jpg" alt=""><img src="https://velog.velcdn.com/images/ij_nim/post/1efae5c7-837c-4a60-9b97-eb8046533456/image.jpg" alt="">
<img src="https://velog.velcdn.com/images/ij_nim/post/9adee3e7-fe2d-4949-95b6-a3fff9987c99/image.jpg" alt=""><img src="https://velog.velcdn.com/images/ij_nim/post/846aa7cc-6058-452c-8d67-d6ebf021a289/image.jpg" alt=""></p>
<p><img src="https://velog.velcdn.com/images/ij_nim/post/c1d40d80-ae63-4ac0-abdb-1698139f0606/image.jpg" alt=""></p>
<p>혼자 공부하는 것보다 머리에 더 남았고, 피드백 줄 수 있던 부분이 좋았다!
앞으로 남은 CS 스터디도 화이팅 😃</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[SSAFY 13기 전공 지원 후기 / 인터뷰 준비]]></title>
            <link>https://velog.io/@ij_nim/SSAFY-13%EA%B8%B0-%EC%A0%84%EA%B3%B5-%EC%A7%80%EC%9B%90-%ED%9B%84%EA%B8%B0</link>
            <guid>https://velog.io/@ij_nim/SSAFY-13%EA%B8%B0-%EC%A0%84%EA%B3%B5-%EC%A7%80%EC%9B%90-%ED%9B%84%EA%B8%B0</guid>
            <pubDate>Mon, 09 Dec 2024 16:24:26 GMT</pubDate>
            <description><![CDATA[<p>싸피 13기 모집 일정
<img src="https://velog.velcdn.com/images/ij_nim/post/9b3d835d-caf3-4140-8843-ba96ebd49190/image.png" alt="">
나는 25년 2월 졸업예정이라서 지난 12기까지 지원을 못하고 있다가 드디어 지원하게 되었다.</p>
<p>예전부터 싸피 교육듣고 삼성계열로 취업했다는 이야기도 들었었고,,
일단 삼성주관 + 월 100만원 지원 + 싸피 전용 공고 등등 의 메리트에 지원하게 되었다.</p>
<p>지금도 KDT를 듣고 있긴 하지만,, 온라인이라 그런지 사실 집중이 잘 안되기도 하고 내가 첫 기수라서 기대에 못미치긴한다 .. 그나마 좋은 스터디 팀원들을 만나서 그 안에서 얻는 것들이 많긴하다! </p>
<p>이런 이유로 싸피에 지원을 하고 사실 에세이는 간단하게 적어서 냈다
그냥 어떤 프로젝트를 해봤는지 그리고 싸피에서 뭘 배우고 싶은지 포부 등등
애초에 500자?이내라서 길게 쓰지 못한다.</p>
<p>에세이 제출 후 코테를 봤는데 정확한 결과는 모르나 2문제 다 결과값은 제대로 나왔기 때문에 조심스럽게.. 2솔이 아닐까 생각해본다</p>
<p>코테 난이도는 실버 1~2수준...? 인 것 같다. 비슷한 문제들을 백준에서 풀었어서 엄청 어렵진 않았지만 그렇다고 엄청 쉽지도 않아서 시간 내에 아슬아슬하게 풀어서 냈다.</p>
<p><img src="https://velog.velcdn.com/images/ij_nim/post/56791ea0-ce59-490a-acae-7a968ba61872/image.png" alt="">
결과는 합격 ..ㅎㅎ 코테는 붙었겠지 생각하고 있었는데 이제 면접이 걱정이었다..</p>
<p>일단 나는 대입 면접 1회 말고는 제대로된 면접 경험이 없다 ㅜㅠ
거의 첫 면접이나 다름 없다는 소리...</p>
<p>그래도 교육 면접이기도 하고,, 나는 그냥 인성+기술 면접이라 생각하고 있었는데 어라라
pt면접이라는 것을 알게되고 잠시 멘붕이 왔었다... <del>그 미생에서만 보던거요...?</del></p>
<p>그치만 일단 코테도 합격했으니  하는데 까지 해봐야지 하는 심정으로
블로그 후기들도 정말 많이 찾아보고 유튜브로 pt면접도 엄청 찾아봤다
여기서 다들 추천해주는 영상이 있었는데
<a href="https://www.youtube.com/watch?v=DOvCIrwMPbQ">https://www.youtube.com/watch?v=DOvCIrwMPbQ</a>
바로 이거다 ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ 사실 다들 이거 보는 것 같다..
모든 블로그에서 추천해주고 있는 이 영상..
이 분께서 말을 정말 잘하신다..
+) 이 분 영상 중에 면접에서 아예 모르는 문제가 나왔을 때 대처법 영상도 있다 참고!ㅎ</p>
<hr>
<p>지금부터 내가 면접을 어떻게 준비했는지 적어보자면 ~~...</p>
<p><span style="color:indianred">(앞으로 나오는 모든 것들은 실제 면접과는 무관하며 면접관련 내용은 대외비이기 때문에 일체 하지 않을 예정 그저 참고용으로만 봐주세요..)</span></p>
<p>처음에는 IT관련 기사들을 어떻게 찾아봐야 하나 걱정했는데 사실 면접 준비 기간이 일주일도 채 안되게 짧았기 때문에 기사를 많이 보진  않았다. 사실 거의 안봤다.</p>
<p><img src="https://velog.velcdn.com/images/ij_nim/post/51e135a4-d616-4e1b-9d99-9856970c644c/image.png" alt="">
내가 뽑은 PT 주제 리스트이다. 이전 기수 지원자분들의 블로그와 싸피 홈페이지를 참고하면서 그냥 있는 주제 다 가지고 왔다..
<img src="https://velog.velcdn.com/images/ij_nim/post/65d70354-e915-422c-b339-48d059155841/image.png" alt="">
이건 나도 이틀전?에 알았는데 싸피 홈페이지에 보니까 요렇게 주제가 몇개 적혀있었어서 마지막엔 이 주제들을 더 중점적으로 봤다.</p>
<p>이제 이 주제에 대한 개념, 장점, 활용방안, 리스크, 해결방안에 대해 공부했다.
저 주제들 중에는 아예 모르는 개념도 있고, 헷갈리는 개념도 있었기 때문에 이 과정이 필요했고 실제로 이렇게 한게 도움이 많이 되었다.</p>
<p>이건 그냥 gpt에게 부탁했다. ㅎ 하나하나 찾아보기에는 시간이 없었기 때문에
주제를 던져주면서 개념, 장점, 활용방안, 리스크, 해결방안을 정리해달라고 했다.</p>
<p>이렇게 개념을 먼저 공부하고 기사도 그냥 gpt한테 해당 주제와 관련된 기사와 그에 맞는 질문을 한두개씩 뽑아달라고해서 면접 연습했다.ㅎ</p>
<p>그리고 시간이 얼마 없어서 면접 스터디를 할까말까 고민했었는데 그래도 모의 면접을 적어도 한번은 보고가면 좋을 것 같아서 급하게 스터디를 구했고 2번 정도 만난 후 면접을 봤다. </p>
<p>첫 면접 스터디 때는 3명이서 모여 서로의 자기소개 컨펌, 서로의 에세이를 보고 어떤 질문이 나올지 예측, PT 연습을 2시간 동안 진행했다. 한번 해보니 내가 어떤점이 부족한지 알 수 있어서 좋았다.</p>
<p>두번째 면접 스터디는 2명이서 진행했고, 면접 전날이라서 실제 면접 처럼 자기소개 + PT + 질문 순으로 진행하며 영상 기록을 남기며 피드백을 했다.</p>
<p>실제 처럼 진행해본게 가장 큰 도움이 되었다. </p>
<p>사실 다른분들의 후기를 보면 엄청 탄탄한 계획으로 면접 스터디를 여러번 진행하신 분들이 많았는데 나는 사실 그럴만한 시간적 여유도 없었고, 우리 모임은 전공자3명 비전공자3명으로 시간 맞추기도 어려웠어서 면접스터디를 짧게 진행했지만 그래도 면접스터디를 한번 쯤은 하는 것을 추천한다...! 나의 상황을 객관적으로 바라볼 수 있게 해주고 준비하다보면 지쳐서 그만하고 싶은 마음도 드는데 면접 스터디에 가려면 어쩔 수 없이 준비해야하기 때문에 열심히 하게 되는 것도 있었다.</p>
<p>인성면접은 그냥 흔한 질문들에 대한 답변을 싹 다 키워드 중심으로 정리한 후 말하는 연습을 해보고 갔다. 대본을 써버리면 그걸 달달외우게 되고 너무 외운 티가 날 것 같기도 했다. 사실 그 많은 질문들을 다 외울 시간조차 없었기에.. 질문들을 쭉 적고 그 질문에 대답할 키워드만 연상시킨 후 답변은 그때그때 생각나는 문장들로 구성해갔다. 항상 면접은 혼자 말하는 것이 아닌 면접관과의 대화를 하는 것이라는 말을 명심하면 좋을 것 같다.</p>
<p>이런식으로 면접 준비한것은 처음이었는데 괜찮은 방법이었다고 생각한다.
오히려 정해둔 답변 틀이 없으니 실제 면접에서 말이 막히지 않았다.</p>
<p><a href="https://www.youtube.com/watch?v=fUCUzp9FL38">https://www.youtube.com/watch?v=fUCUzp9FL38</a>
마지막 할말은.. 이 영상 참고했다 
내가 면접관이라도 이렇게 말해준다면 정말 좋을 것 같았기 때문에..</p>
<p>아무튼 이렇게 PT면접과 인성면접 준비를 하고 .. 면접을 보러갔다
<img src="https://velog.velcdn.com/images/ij_nim/post/cfe48b53-5515-45a6-a6ef-65ac7f0010dd/image.jpeg" alt="">
대학면접 때랑은 또 느낌이 다르게 뭔가.. 면접 공장 같았다 ㅋㅋㅋㅋ
옷은 그냥 셔츠 + 슬랙스 + 자켓을 입고 갔다.</p>
<p>20분정도 일찍 도착해서 앉아서 기다렸고 사실.. 이때는 그냥 빨리 끝났으면 좋겠다 라는 생각 뿐이었고</p>
<p>면접 대기실에서부턴 .. 될대로 되라는 마인드..</p>
<p>면접실 들어가기 직전엔 심장이 너무 쿵쾅쿵쾅 요동쳐서 ㅜㅠ 진정하느라
심호흡을 혼자 스무번은 심호흡 하다가 들어간 것 같다.</p>
<p>모든게 대외비라 자세히 말해주진 못하지만 나 같은 경우는 압박면접은 아니었고
너무 좋은 분위기에서 면접을 잘 마치고 나올 수 있었다.</p>
<p>지금 생각해보면 아 이렇게 대답할 껄 했던 답변들도 있지만
그래도 첫 면접 치고 대체적으로 잘 대답하고 나온 것 같아서 큰 후회는 없다</p>
<p>면까몰..이라고 사실 결과는 나와봐야 알겠지만..결과가 어떻게 나오든 이번 면접은 좋은 경험으로 남을 것 같다!</p>
<p>남은 면접이 있으신 분들도 화이팅 하시길 바라며 다함께 서울캠퍼스에서 만날 수 있기를..</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로젝트 기획 회의 회고록] / 프로젝트 방향성]]></title>
            <link>https://velog.io/@ij_nim/%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EA%B8%B0%ED%9A%8D-%ED%9A%8C%EC%9D%98-%ED%9A%8C%EA%B3%A0%EB%A1%9D-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EB%B0%A9%ED%96%A5%EC%84%B1</link>
            <guid>https://velog.io/@ij_nim/%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EA%B8%B0%ED%9A%8D-%ED%9A%8C%EC%9D%98-%ED%9A%8C%EA%B3%A0%EB%A1%9D-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EB%B0%A9%ED%96%A5%EC%84%B1</guid>
            <pubDate>Mon, 04 Nov 2024 06:01:40 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>4F 방법</p>
</blockquote>
<ul>
<li>사실(Fact): 일어난 일에 대한 객관적인 기록</li>
<li>느낌(Feeling): 상황에 대한 감정적인 반응</li>
<li>교훈(Finding): 경험을 통해 배울 수 있었던 것</li>
<li>향후 행동(Future action): 향후 할 수 있는 개선된 행동</li>
</ul>
<h3 id="fact">Fact</h3>
<h4 id="about-meeting">About Meeting</h4>
<p><strong>일시</strong>: 2024년 11월 1일 금요일
<strong>팀</strong>: 먹물
<strong>회의 주제</strong>: 프로젝트 기능 선정</p>
<h4 id="about-project">About Project</h4>
<p><strong>프로젝트 주제</strong>: 개발 프로젝트를 위한 네트워킹 서비스
<strong>주제 선정 이유</strong>: 구름톤 딥다이브 OT 당시, 네트워킹 시간에 팀 구성을 위해 서로를 소개하는 시간을 가졌음. 인원이 약 50명 정도로 굉장히 많은 인원을 단순히 노션에 자기소개를 작성해 공유하다보니, 50명이 작성하고 공유하는데 시간이 오래걸렸으며 자기소개가 지나간 후에는 이 자기소개서가 누구의 자기소개인지 알기 힘들었음(개인 사진이 미 포함되어 있었기 때문). 이에 공통적으로 불편함을 느껴 문제점을 해결하고자 이 주제를 선정했음. 해당 상황 뿐만 아니라 해커톤 등 프로젝트 진행을 위해 만나는 모든 상황에 유용하게 쓰일 것으로 예상했음.
<strong>개발 프로젝트를 위한 네트워킹 서비스란?</strong>
=&gt; 개발 교육 과정이나 해커톤 같이 개발 프로젝트를 위해 모인 자리에서 서로의 정보를 빠르게 교환할 수 있게 해주며, 다양한 부가 기능을 제공해 네트워킹의 기회를 만들어주는 서비스</p>
<p>이번 회의 이전까지의 상황: 프로젝트 주제가 결정되고, 대략적인 기능들에 대해 이야기가 끝난 상황으로, 이번 회의 시간에 프로젝트 기능을 확정시키기로 했음.</p>
<p><strong>문제점:</strong>
프로젝트의 목적은 공통으로 느낀 불편함을 해결하고자 서비스를 개발하는 것이었지만, 정작 서비스의 방향성과 정확한 주제에 대해서는 이야기 한 적이 없었고, 서로 다양한 의견을 나누던 중, 넣고 싶은 기능들이 달랐는데 그 이유에 대해 정리해 본 결과 방향성이 달랐던 것을 깨달음. </p>
<p>한쪽은 프로젝트를 선택한 이유가 기능 개발을 위한 것이었으므로 다양한 기능을 넣자는 의견이었고 다른 한쪽은 너무 많은 기능이 들어가다보니 프로젝트의 방향성을 잃어가는 것 같다는 의견이었음, 팀원들과 이야기 하다보니 양쪽 의견 다 타당한 이야기 였고 문제는 처음 프로젝트를 기획할 때 프로젝트의 방향성을 확실히 하지 않은데서 생겼다는 결론이 나왔음 </p>
<p>그리고 팀원들 모두 백엔드 파트이나 사용자의 편리함을 생각하다보니 프론트 파트에서 해결해야할 부분들이 생각보다 많았음.</p>
<hr>
<h3 id="feeling">Feeling</h3>
<p>회의 진행 도중 기능이 너무 많아진다는 생각을 했다. 물론 그 중 필요 없다고 생각되는 기능은 없었다. 회의가 끝나고 돌이켜보니, 나의 생각은 처음에 이야기 나누었던 주제에 치중되어 있었던 것 같다. 처음에는 명함을 주고 받는 것에 대한 불편함을 해소하고자 해당 서비스를 통해 전자 명함의 느낌을 가져가는 것도 큰 부분 이었는데 많은 기능들이 들어오니 우리의 서비스를 소개할 때 명확한 주제가 없진 않을까 하는 생각이 들었다. 그리고 사실 지금까지 여러 공모전을 하면서 주제에 대한 피드백을 정말 많이 받아왔던지라, 나도 모르게 실사용성과 기능들이 너무 중구난방으로 흩어지면 안된다는 생각이 강하게 자리잡혀있었던 것 같다.</p>
<hr>
<h3 id="finding">Finding</h3>
<p>이번 프로젝트는 배포가 큰 목적이기 보다는 기능을 개발해보는 것에 중점을 두기로 했었는데 나 또한 방향성을 제대로 잡지 못한채 의견을 하나로 내지 못했던 것 같다. 프로젝트 기획에 있어서 방향성을 확실히 정하는 것이 얼마나 중요한 것인지 다시 한 번 깨닫게 되었다.</p>
<hr>
<h3 id="future-action">Future action</h3>
<p>다음 회의 시간까지 각자 불편했던 점, 개선하고 싶었던 점을 다시 생각해보고 정리하는 시간을 가지기로 했다. 팀원들의 의견을 모아 프로젝트의 방향성을 확실히 하고 프로젝트 기획의 이유를 명확하게 할 것이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Silver I] 구간 합 구하기 5 - 11660]]></title>
            <link>https://velog.io/@ij_nim/Silver-I-%EA%B5%AC%EA%B0%84-%ED%95%A9-%EA%B5%AC%ED%95%98%EA%B8%B0-5-11660</link>
            <guid>https://velog.io/@ij_nim/Silver-I-%EA%B5%AC%EA%B0%84-%ED%95%A9-%EA%B5%AC%ED%95%98%EA%B8%B0-5-11660</guid>
            <pubDate>Wed, 30 Oct 2024 13:33:02 GMT</pubDate>
            <description><![CDATA[<p><a href="https://github.com/ijnim1121/baekjoon/tree/main/%EB%B0%B1%EC%A4%80/Silver/11660.%E2%80%85%EA%B5%AC%EA%B0%84%E2%80%85%ED%95%A9%E2%80%85%EA%B5%AC%ED%95%98%EA%B8%B0%E2%80%855">github</a></p>
<p>정답 코드</p>
<pre><code class="language-python">import sys
input = sys.stdin.readline

# 입력 받기
N, M = map(int, input().split())
tables = []

for _ in range(N):
    table = list(map(int, input().split()))
    tables.append(table)

# 2차원 dp 배열 생성 및 누적합 계산
dp = [[0] * (N + 1) for _ in range(N + 1)]

for i in range(1, N + 1):
    for j in range(1, N + 1):
        dp[i][j] = tables[i - 1][j - 1] + dp[i - 1][j] + dp[i][j - 1] - dp[i - 1][j - 1]

# 구간합 계산 함수
def range_sum(x1, y1, x2, y2):
    result = dp[x2][y2]
    if x1 &gt; 1:
        result -= dp[x1 - 1][y2]
    if y1 &gt; 1:
        result -= dp[x2][y1 - 1]
    if x1 &gt; 1 and y1 &gt; 1:
        result += dp[x1 - 1][y1 - 1]
        return result

sum_list = []
# 쿼리 처리 및 출력
for _ in range(M):
    x1, y1, x2, y2 = map(int, input().split())
    sum = range_sum(x1, y1, x2, y2)
    sum_list.append(sum)

for result in sum_list:
    print(result)
</code></pre>
<p>틀린 코드</p>
<pre><code class="language-python">N, M = map(int, input().split())
tables = []

for _ in range(N):
    table = list(map(int, input().split()))
    tables.append(table)

dp = [[0] * N for _ in range(N)] # 2차원 리스트
for i in range(0, N):
    for j in range(0, N):
        if i == 0 and j == 0:
            dp[i][j] = tables[i][j]
        elif j == 0:
            dp[i][j] = dp[i-1][N-1] + tables[i][j]
        else:
            dp[i][j] = dp[i][j-1] + tables[i][j]

def range_sum(x1, x2, y1, y2, dp):
    if x1 == x2 and y1 == y2:
        return tables[x1-1][y1-1]
    elif x1 == 1 and y1 ==1:
        return dp[x2-1][y2-1]
    else:
        sum = dp[x2-1][y2-1] - dp[x1-1][y1-1]
        return sum

range_sum_list=[]
for _ in range(M):
    x1, y1, x2, y2 = map(int, input().split())
    range_sum_list += [range_sum(x1, x2, y1, y2, dp)]

for sum in range_sum_list:
    print(sum)</code></pre>
<p>특정 구간 <code>[x1, y1]</code>부터 <code>[x2, y2]</code>까지의 합을 구할 때 중복된 구간을 제거해야 하는데, 현재 코드에서는 <code>dp</code> 배열에서 <strong>위쪽, 왼쪽, 그리고 좌상단</strong> 구간을 포함한 계산을 하지 않기 때문에 잘못된 결과가 나옵니다.</p>
<p>누적합 자체를 잘못 구했음</p>
<p>dp</p>
<p><img src="https://velog.velcdn.com/images/ij_nim/post/8a40371f-e43e-4489-8b66-353de00c4d05/image.jpeg" alt=""></p>
<p>range sum</p>
<p><img src="https://velog.velcdn.com/images/ij_nim/post/6ae3d745-5185-4004-8a7e-0f3acaef5511/image.jpeg" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Silver IV] 스택 2 - 28278]]></title>
            <link>https://velog.io/@ij_nim/Silver-IV-%EC%8A%A4%ED%83%9D-2-28278</link>
            <guid>https://velog.io/@ij_nim/Silver-IV-%EC%8A%A4%ED%83%9D-2-28278</guid>
            <pubDate>Fri, 13 Sep 2024 06:06:53 GMT</pubDate>
            <description><![CDATA[<p><a href="https://github.com/ijnim1121/baekjoon/tree/main/%EB%B0%B1%EC%A4%80/Silver/28278.%E2%80%85%EC%8A%A4%ED%83%9D%E2%80%852">백준  28278 Github Repo</a></p>
<pre><code>import sys

def stack_method(command, X=None): #X=None -&gt; 매개변수의 기본 값 설정
    # 스택 초기화 - 전역변수로 선언하여 모든 명령에서 접근할 수 있도록 함
    global stack
    if command == 1:
        stack.append(X)
    elif command == 2:
        if len(stack) == 0:
            print(-1)
        else:
            print(stack.pop())
    elif command == 3:
        print(len(stack))
    elif command == 4:
        if len(stack) == 0:
            print(1)
        else:
            print(0)
    elif command == 5:
        if len(stack) != 0:
            print(stack[-1])
        else:
            print(-1)

# 스택 초기화
stack = []

# 첫째 줄에 명령의 수 N을 입력받습니다.
N = int(sys.stdin.readline().strip())

# N개의 명령을 처리합니다.
for _ in range(N):
    command = list(map(int, sys.stdin.readline().strip().split()))

    if command[0] == 1:  # 삽입 명령인 경우
        stack_method(command[0], command[1])
    else:  # 나머지 명령은 하나의 인자만 필요
        stack_method(command[0])</code></pre><p>어제 문제를 풀면서 파이썬에서는 스택의 구현을 리스트로 처리한다는 것을 알고 스택 구현하는 문제를 풀게되었다.</p>
<p>스택의 push = 리스트의 append 메서드
스택의 pop = 리스트의 pop 메서드
--&gt; pop 메서드는 리스트의 마지막 요소를 삭제하고, 그 삭제된 요소를 반환하는 메서드이다. 기본적으로 리스트의 마지막 요소를 제거하지만, 인덱스를 지정하면 해당 인덱스의 요소를 삭제할 수도 있다.</p>
<hr>
<h3 id="스택-관련-메서드">스택 관련 메서드</h3>
<h4 id="appendx">append(x)</h4>
<p>설명: 스택의 맨 위에 요소 x를 추가합니다.
예시:</p>
<pre><code>stack = []
stack.append(1)
stack.append(2)
print(stack)  # 출력: [1, 2]</code></pre><h4 id="popi">pop([i])</h4>
<p>설명: 스택의 맨 위 요소를 제거하고 그 값을 반환합니다. 인덱스를 지정하지 않으면 마지막 요소를 제거합니다.
예시:</p>
<pre><code>stack = [1, 2, 3]
top_element = stack.pop()  # 3을 제거하고 반환
print(top_element)  # 출력: 3
print(stack)        # 출력: [1, 2]</code></pre><h4 id="-1-인덱싱">[-1] 인덱싱</h4>
<p>설명: 스택의 맨 위 요소를 반환합니다. 삭제하지 않습니다.
예시:</p>
<pre><code>stack = [1, 2, 3]
top_element = stack[-1]  # 3을 반환
print(top_element)  # 출력: 3</code></pre><h4 id="lenstack">len(stack)</h4>
<p>설명: 스택의 현재 요소 개수를 반환합니다.
예시:</p>
<pre><code>stack = [1, 2, 3]
print(len(stack))  # 출력: 3</code></pre><h4 id="clear">clear()</h4>
<p>설명: 스택의 모든 요소를 제거합니다.
예시:</p>
<pre><code>stack = [1, 2, 3]
stack.clear()
print(stack)  # 출력: []</code></pre><h4 id="extenditerable">extend(iterable)</h4>
<p>설명: 다른 iterable(리스트, 튜플 등)의 요소를 스택에 추가합니다.
예시:</p>
<pre><code>stack = [1]
stack.extend([2, 3])
print(stack)  # 출력: [1, 2, 3]</code></pre><h4 id="inserti-x">insert(i, x)</h4>
<p>설명: 인덱스 i 위치에 요소 x를 추가합니다. 스택의 동작과는 다소 다르지만, 원하는 위치에 삽입할 수 있습니다.
예시:</p>
<pre><code>stack = [1, 2]
stack.insert(0, 0)  # 인덱스 0에 0을 추가
print(stack)  # 출력: [0, 1, 2]</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[Silver V] 비밀번호 발음하기 - 4659]]></title>
            <link>https://velog.io/@ij_nim/Silver-V-%EB%B9%84%EB%B0%80%EB%B2%88%ED%98%B8-%EB%B0%9C%EC%9D%8C%ED%95%98%EA%B8%B0-4659</link>
            <guid>https://velog.io/@ij_nim/Silver-V-%EB%B9%84%EB%B0%80%EB%B2%88%ED%98%B8-%EB%B0%9C%EC%9D%8C%ED%95%98%EA%B8%B0-4659</guid>
            <pubDate>Thu, 12 Sep 2024 14:55:12 GMT</pubDate>
            <description><![CDATA[<p><a href="https://github.com/ijnim1121/baekjoon/tree/main/%EB%B0%B1%EC%A4%80/Silver/4659.%E2%80%85%EB%B9%84%EB%B0%80%EB%B2%88%ED%98%B8%E2%80%85%EB%B0%9C%EC%9D%8C%ED%95%98%EA%B8%B0">GitHub #4659 비밀번호 발음하기</a>
브론즈 문제들만 풀다가 알고리즘 강의들을 전부 듣고 실버문제를 도전했는데...
시간이 꽤 많이 걸렸던 문제이다 ㅠㅠ 결국에는 팀원들의 도움을 받았던..
멍청한 실수를 했다..</p>
<p>우선 처음에 문제를 보고는 아 이거 구현문제네 ! 
조건문 달면 끝나겠는데?? 생각하고는 
<img src="https://velog.velcdn.com/images/ij_nim/post/51fb6cf1-0859-49f2-8536-5cf69439778a/image.png" alt=""></p>
<p>이런식으로 처음엔 카운터 사용해서 갯수세면 되겠는데...? 하다보니
아.. 카운터로는 연속의 여부를 판단할 수가 없구나.. 하고</p>
<p>다시 생각을 하게 됐다.
<img src="https://velog.velcdn.com/images/ij_nim/post/dcfd3248-9720-4505-b4e7-d6d6174f08dd/image.png" alt="">
그 다음으로 구현한 함수인데 이렇게 해도 모든 테스트 케이스를 만족시킬 수는 없었다. 단순 조건문으로만 다 해결하려고 하니 겹치는 조건?들을 구현하기가 어려웠다. 그래서 여기서부턴 gpt의 도움을 받아서 어떤식으로 고치는게 좋을지 의견을 물었다.</p>
<p>그래서 나온 방법이 이 아래 방법처럼 변수들을 설정하는 방식이었다
모음소유여부를판단하는 변수, 이전 문자를 저장하는 변수, 연속 여부를 카운트하는 변수, 모음 자음의 갯수를 카운트 하는 변수, 조건 만족 여부를 판단하는 변수들을 설정해주는 방식이다.</p>
<pre><code>def is_valid_password(password):
    vowels = &#39;aeiou&#39;
    has_vowel = False
    prev_char = &#39;&#39;
    consecutive_count = 1
    vowel_count = 0
    consonant_count = 0
    is_acceptable = True

    for i in range(len(password)):
        if password[i] in vowels:
            has_vowel = True
            vowel_count += 1
            consonant_count = 0  # 자음 카운트 초기화
        else:
            vowel_count = 0  # 모음 카운트 초기화
            consonant_count += 1

        # 같은 글자가 연속으로 두 번 오는지 체크
        if password[i] == prev_char:
            consecutive_count += 1
            if consecutive_count &gt;= 2 and password[i] not in [&#39;e&#39;, &#39;o&#39;]:
                is_acceptable = False
        else:
            consecutive_count = 1  # 연속 문자 카운트 초기화


        # 모음이 3개 연속으로 오는지 체크
        if vowel_count &gt; 2:
            is_acceptable = False

        # 자음이 3개 연속으로 오는지 체크
        if consonant_count &gt; 2:
            is_acceptable = False

        prev_char = password[i]  # 이전 문자 업데이트

    return has_vowel and is_acceptable

while True:
    password = input()
    if password == &quot;end&quot;:
        break
    if is_valid_password(password):
        print(f&quot;&lt;{password}&gt; is acceptable.&quot;)
    else:
        print(f&quot;&lt;{password}&gt; is not acceptable.&quot;)</code></pre><p>여기서 치명적인 실수를 했었는데 테스트 케이스에서 같은 문자가 2개 이상 오는 경우를 처리하지 못하고 있었다. 문제의 원인은.. </p>
<pre><code>if consecutive_count &gt;= 2 and password[i] not in [&#39;e&#39;, &#39;o&#39;]:
                is_acceptable = False</code></pre><p>이 부분 이었다. 2개 이상이므로 &gt;=를 사용해야했는데 3개 연속 조건과 헷갈렸는지 &gt;2 를 사용하고 있었던 것..... </p>
<p>그리고 두번째로는 마지막 프린트 부분에서 </p>
<pre><code>if is_valid_password(password):
        print(f&quot;&lt;{password}&gt; is acceptable.&quot;)
    else:
        print(f&quot;&lt;{password}&gt; is not acceptable.&quot;)</code></pre><p>간과한 사실 하나..! 백준은 출력을 완벽하게 똑같이 구현해야만 하는데
내가 ... 마지막 마침표를 안썼었다... </p>
<p>이렇게 바보같은 실수를 2개나해서 계속  오류가 났던 것....!!</p>
<p>앞으로 구현 문제 풀때는 실수안하도록 더 꼼꼼히 정신차려야겠다 ...!!!!</p>
<p>그리고 오늘 문제를 풀면서 다시 리마인드 된 사실 하나는
파이썬에서 스택의 구현은 리스트로 한다는 것!</p>
<p>앞으로 코딩테스트 문제를 풀어나가면서 새롭게 알게된 점, 다시 리마인드 된 것들, 그리고 실수했던 부분들을 기록해나가려고 한다!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[kakao x goorm DEEP DIVE BE] OT ~ 2주차]]></title>
            <link>https://velog.io/@ij_nim/kakao-x-goorm-DEEP-DIVE-BE-OT-2%EC%A3%BC%EC%B0%A8</link>
            <guid>https://velog.io/@ij_nim/kakao-x-goorm-DEEP-DIVE-BE-OT-2%EC%A3%BC%EC%B0%A8</guid>
            <pubDate>Mon, 02 Sep 2024 07:40:49 GMT</pubDate>
            <description><![CDATA[<p>합격 소식을 받고 오티에 다녀온지도 벌써 2주가 흘러 3주차를 맞이하고 있다...!</p>
<p>생각보다 시간이 빨리 가는 듯...</p>
<p><img src="https://velog.velcdn.com/images/ij_nim/post/2213d750-c7b0-410f-9341-fbf35d21300a/image.jpeg" alt="">
아침부터 출근길을 뚫고 판교에 도착했는데
수인분당선 - 신분당선 루트는 너무나도 힘들었다..
사람이 너무 많아서 판교역에 내려서 버스타는데도 한번에 탈 수가 없었다.. 혹시 나중에 판교로 출근하게 된다면 지하철만은 안될 것 같다고 생각했다 ㅜㅜ ~</p>
<p><img src="https://velog.velcdn.com/images/ij_nim/post/d10340e9-42e2-46f8-8ff3-3a8dcb3daeef/image.jpeg" alt="">
혹시라도 출근길에 늦을까봐 일찍 출발했던 탓에 8시 50분 집합이었지만 20분 정도 일찍 도착했다.</p>
<p>도착해서 입실 큐알도 등록하고, 오티를 시작했다.</p>
<p>사실 이날 점심 이후에 수강신청도 있어서 엄청 빡센 하루였다...</p>
<blockquote>
<p>TIME TABLE
08:50 ~ 09:10 입실체크 및 방문일지 작성 안내
09:10 ~ 10:30 훈련과정 소개 및 유의사항 안내
10:30 ~ 11:30 커리어 매니저 소개
11:30 ~ 13:30 점심시간
13:30 ~ 14:30 훈련강사 소개 및 질의응답 (비대면)
14:30 ~ 15:00 노트북 대여
15:00 ~ 16:30 자기소개 및 아이스브레이킹
16:30 ~ 17:30 기초 지식 테스트
17:30 ~ 18:00 최종 안내 및 퇴실체크
＊일정은 변동될 수 있습니다.</p>
</blockquote>
<p>이 날 오티는 이렇게 진행되었고 몇분을 제외하고는 다들 모르는 사람들끼리 모인 자리라 정말 조용해서,,, 숨막히는 줄 알았다. ..</p>
<p>그렇게 다들 정적속에 안내사항을  듣고 점심을 먹으러 다같이 덮밥집에 갔다.</p>
<p>덮밥집에 도착해서야 함께 대화를 나누기 시작했다. 
왜냐면 오후에 스터디 팀을 구성하라고 했었기 때문에.... 빨리 친해지라고 하셨었다 ㅋㅋ쿠ㅠㅠㅠㅠ 오랜만에 이런 자리라 어색했지만 나름 즐거웠던 점심시간을 보냈던 것 같다. 같은 테이블에 앉았던 사람들과 밥먹고 들어가기전에 스벅에 들렀는데 너무 피곤하고 당떨어져서 평소에 먹지도 않던 자바칩 프라푸치노를 마셨다 ㅋㅎㅋㅎㅋ </p>
<p>그리고 훈련 강사님 소개 이후 자기소개를 했는데
오랜만에 이런 자기소개 해보기도 하고 처음 보는 사람들에게 나를 최대한 어필하고자 지금까지 했던 것들을 최대한 끌어내 썼던 것 같다 </p>
<p>그 후 간단한 기초테스트를 진행했는데 기초테스트는 그냥 정말 기본 지식 같은 문제였다. 뭐 sql구문에 대한 문제라던지 언어가 가진 특징이라던지 간단한 20문항이었다. </p>
<p>그리고 이제 정말 스터디 팀을 구성해야겠다고 생각해서 나의 옆자리 분과 이야기를 나누고 있다가 자기소개 시간에 같이 하고 싶었던 몇몇 분께 여쭤보자고 이야기가 나와서 여쭤봤지만, 다들 팀을 이미 구성하셔서.. 마음이 조금 다급해졌었다..ㅋㅋㅋㅋㅋㅋ</p>
<p>그래서 같이 점심 먹었던 분들도 함께 스터디하면 좋을 것 같아 여쭤보고 함께 아이스브레이킹 참여했던 분들도 모여서 6명의 스터디 그룹을 만들었다.</p>
<p>다들 성격도 너무 좋으시고 열정도 있으신 분들이라 지금까지도 스터디 아주 순조롭고 재밌게 진행중이다 !</p>
<p>1~2주차 동안은
9시 ~ 11시 실시간 강의
11시 ~ 12시 점심시간
(근데 사실 적응이 안되서 점심에 30분씩 잠들때가 많았다..)
12시 ~ 16시 스터디 팀원들과 공유할 알고리즘 문제 풀이, 스프링 강의, 개별 알고리즘 강의들을 듣고 매일 주어지는 exp 미션을 하며 시간을 보내고 16시에 팀원들과 디스코드에 모여 회의를 진행했다.</p>
<p>2시간동안 알고리즘 문제풀이를 진행하고, 함께 들어온 강의 내용을 공유하고, 그 외 프로젝트 준비 등등을 함께하며 18시에 교육을 마무리했다.</p>
<p>나는 이외에 원래 진행하고 있던 팀 프로젝트와 졸업작품이 있어서 사실 교육 이외 시간도 쉴수가 없어서 힘들었다... 그리고 함께 스터디를 진행하며 내 알고리즘 문제 풀이 능력이 얼마나 부족한지 절실하게 깨달았기 때문에 동기부여가 되서 더 열심히 해야겠다는 생각을했다.</p>
<p>알찬 하루들을 보내고 있는 요즘이지만 사실 프로젝트 + 졸작 + 팀프로젝트를 한번에 하다보니 셋다 잘하고자하는 부담감에 급성위염이 찾아오기도 했지만..... 앞으로 저 잘할 수 있겠죠....ㅎ</p>
<p>딥다이브 우수 수강생이 되는 그날까지...! 화이티 ㅇ ~~</p>
]]></description>
        </item>
    </channel>
</rss>