<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>justcallmelight_</title>
        <link>https://velog.io/</link>
        <description>안녕하세요, 미림마이스터고등학교 뉴미디어소프트웨어과 1학년에서 풀스택 개발자로 성장중인 권율입니다. Github에서 저의 개발 흔적들을 볼수있습니다.</description>
        <lastBuildDate>Sat, 24 Oct 2026 17:33:24 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>justcallmelight_</title>
            <url>https://velog.velcdn.com/images/justcallmelight_/profile/518b93b7-46db-434c-8449-c541a8d7e5cc/image.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. justcallmelight_. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/justcallmelight_" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[미톤 2026 | 개인 프로젝트만 하던 내가 팀장이 되어 iOS 앱을 제대로 만든 해커톤]]></title>
            <link>https://velog.io/@justcallmelight_/%EB%AF%B8%ED%86%A4-2026</link>
            <guid>https://velog.io/@justcallmelight_/%EB%AF%B8%ED%86%A4-2026</guid>
            <pubDate>Sat, 24 Oct 2026 17:33:24 GMT</pubDate>
            <description><![CDATA[<h2 id="들어가며">들어가며</h2>
<p>미톤(MITHON)은 미림마이스터고등학교에서 하는 해커톤이에요. 미림 해커톤을 줄인 말이죠. 입시를 준비하다 알게 됐고, 합격하면 꼭 해보고 싶은 것 중 하나였어요. 그래서 이번에는 수상보다 <strong>경험 자체</strong>에 더 의미를 뒀어요.</p>
<p>이번 미톤은 저에게 두 가지가 처음이었어요.</p>
<ol>
<li>iOS 앱을 &quot;제대로&quot; 만들어 본 것</li>
<li>몇 안 되는 협업 프로젝트였다는 것 (저는 보통 혼자 만들거든요)</li>
</ol>
<h3 id="행사-소개">행사 소개</h3>
<ul>
<li><strong>일시</strong>: 10월 23일 저녁 7시부터 24일 오전까지, 밤샘 개발 후 오전 9시 반부터 발표</li>
<li><strong>장소</strong>: 성수역 2번 출구 도보 1~2분, 알파코 성수 2캠퍼스</li>
<li><strong>주관</strong>: 알파코</li>
<li><strong>분위기</strong>: 경쟁보다 협력이 훨신 컸어요. 다른 팀과 대화도 잘 통해서 다른 팀원이 힘들어하는 바이브코딩이나 GitHub의 PR, Branch, Merge 같은 걸 제가 알려주기도 했어요. 
옆에서 보던 EcoCheck 팀 Design 담당은 저를 보고 말을 못 알아 듣겠다고도 했어요.</li>
</ul>
<h2 id="우리-팀과-ecocheck-서비스">우리 팀과 EcoCheck 서비스</h2>
<p>저희 팀은 &quot;찍으면 알려주고, 버리면 쌓이는 분리배출&quot; 앱 <strong>EcoCheck</strong>를 만들었어요. 쓰레기를 카메라로 찍으면 AI가 재질을 판별하고, 그에 맞는 분리배출 방법을 단계별로 알려줘요. 올바르게 버리면 포인트가 쌓이는 구조도 설계했어요.</p>
<table>
<thead>
<tr>
<th>역할</th>
<th>담당</th>
</tr>
</thead>
<tbody><tr>
<td>팀장 · Full-Stack (뉴미디어소프트웨어과)</td>
<td>기획 · Full-Stack · 디자인 동작 구현 및 위계구조, UX 디테일 피드백</td>
</tr>
<tr>
<td>Backend (뉴미디어소프트웨어과)</td>
<td>Back-end 총괄 (Java, SQL)</td>
</tr>
<tr>
<td>Design (뉴미디어디자인과)</td>
<td>UI 디자인 총괄 (Figma Design)</td>
</tr>
</tbody></table>
<p>저는 팀장 · Full-Stack 이라고 써져있는 사람이에요. 메인 백엔드 담당도 있지만, 백엔드도 했어요.
팀 전원 모두 미림마이스터고등학교 친구들이에요. 멘토 등 외부 인원이 아닌 이상 저희 학교의 학생만 미톤에 참여할수 있어요.</p>
<h2 id="문제-정의-및-해결">문제 정의 및 해결</h2>
<p>분리배출이 막히는 이유는 세 가지로 봤어요.</p>
<ul>
<li><strong>헷갈려요</strong>: 물건마다 기준이 달라서 매번 검색해야 해요</li>
<li><strong>귀찮아요</strong>: 찾아보는 데 시간이 걸려서 대충 버리게 돼요</li>
<li><strong>티가 안 나요</strong>: 잘 버려도 변화가 없어서 습관이 되지 않아요</li>
</ul>
<p>그래서 &quot;찍고, 알고, 쌓는다&quot;로 풀었어요.</p>
<p>솔직히 아이디어를 정하는 과정이 쉽지 않았어요. 처음엔 아이디어가 없었고, 막상 나온 아이디어는 제 기준에선 너무 뻔해서 최종 결정 전까지 고민을 엄청 했어요. 다음 해커톤은 지금 만들고 있는 프로젝트만큼 좋은 아이디어로 나가고 싶어요.</p>
<h2 id="웹에서-ios-앱으로-기획을-갈아엎었어요">웹에서 iOS 앱으로: 기획을 갈아엎었어요</h2>
<p>원래 기획서는 모바일 웹(HTML, CSS, JavaScript)에 AI는 Google Teachable Machine으로 직접 학습하는 계획이었어요. 그런데 개발 단계에서 <strong>SwiftUI 기반 iOS 앱 + Java 서버 + MySQL</strong> 구조로 바꿨어요. 모바일에 완벽 대응하는 웹으로 만들면 구현 단계를 빠르게 줄일 수 있다는 걸 알았지만, 이번엔 더 열심히 해 보고 싶어서 iOS 앱을 선택했어요. 사실 Flutter도 쓰고싶었지만, 그 생각이 났을때는 이미 iOS 앱 개발이 진행중이였고, 그거에 비해 필요성이 낮아서 현재는 Flutter를 쓰고있지 않아요.</p>
<p>참고로 AI를 직접 학습시킨 건 아니에요. 기존 Gemini 모델에 분류 기준을 전달하는 방식이고, 구분하는 재질은 투명 페트병, 알루미늄 캔, 철 캔, 유리병, 골판지, 종이류, 플라스틱 용기 총 7종이에요. 사진 자체는 서버나 DB에 저장하지 않고, 분석할 때 Gemini로만 보내요. AI가 실패하면 사용자가 재질을 직접 골라서 안내를 볼 수 있어요.</p>
<h2 id="처음-제대로-만든-ios-앱">처음 제대로 만든 iOS 앱</h2>
<p>Swift로 뭔가 만져 본 적은 있었지만, 이렇게 제대로 만든 건 처음이에요. 가장 인상 깊었던 건 두 가지였어요.</p>
<ul>
<li><strong>Xcode Canvas(미리보기)</strong>: 코드를 고치면 화면이 바로 바뀌는 게 좋았어요</li>
<li><strong>내 폰에 직접 설치됐을 때</strong>: 빌드가 계속 실패해서 버그를 잡던 중에 성공했는데, &quot;드디어..&quot; 하는 마음과 함께 내 폰에서 진짜 앱이 돌아가는 게 신기했어요</li>
</ul>
<p>실기기에서 앱을 켜고 제일 먼저 확인한 건 기능이 아니라 <strong>디자인과 누락된 페이지</strong>였어요. 이 이야기는 아래 삽질 기록에서 이어져요.</p>
<blockquote>
<p><img src="https://velog.velcdn.com/images/justcallmelight_/post/40d67796-50f9-413f-a7b4-604997049142/image.png" alt="">
Xcode를 둘러보는 중. 오른쪽 위 컴퓨터 시간이 현장감을 준다.</p>
</blockquote>
<h2 id="협업에서-겪은-일들">협업에서 겪은 일들</h2>
<h3 id="대부분-프로젝트를-혼자만-하다가-2명-이상-github로-협업하기">대부분 프로젝트를 혼자만 하다가 2명 이상 GitHub로 협업하기</h3>
<p>저는 해커톤 시작 전에 Notion, GitHub, Figma를 만들어서 팀원을 초대하고, 서로의 진행 상황을 공유했어요, 가장 어려웠던 건 <strong>백엔드 팀원의 서버를 제 프론트에 붙이는 일</strong>이었어요. 처음할땐 좀 어려웠지만 한번 해보니 쉬웠어요.</p>
<h3 id="로그인을-필수로-할-것인가">로그인을 필수로 할 것인가</h3>
<p>팀에서 유일하게 의견이 갈렸던 부분이에요. 저는 EcoCheck의 핵심인 분리배출 안내는 <strong>로그인 없이 바로</strong> 쓸 수 있어야 한다고 생각했어요. 구글 계정이 없거나 가입을 원치 않는 사람도 스캔하고 배출 방법을 확인할 수 있어야 하고, 로그인은 기록 동기화나 포인트처럼 계정이 필요한 기능에서만 선택적으로 요청하자는 입장이었어요. 로그인하지 않은 사용자의 기록은 우선 기기에만 저장하거나, 저장 없이 안내만 제공하는 방안을 같이 정하자고 제안했어요.</p>
<p>반대쪽 의견은 처음부터 로그인하게 하자는 거였어요. 왜 로그인해야 하냐고 물으면 포인트를 얻기 위해서라고 설명하면 된다는 거죠. 구글 로그인은 Supabase로 하기로 했고, 기록을 계정과 어떻게 연결할지는 백엔드 팀원과 함께 정하는 중이에요. 카카오 로그인과 네이버 로그인은 판단상 MVP 단계에서 제외시켰습니다</p>
<h3 id="노트북을-닫으면-서버도-닫혀요">노트북을 닫으면 서버도 닫혀요</h3>
<p>개발 중 가장 당황했던 순간이에요. 갑자기 서버가 인식되지 않았는데, 원인은 로컬 서버를 돌리던 백엔드 팀원이 노트북을 닫아놨던거였어요.</p>
<p>로컬 서버를 백엔드 팀원의 노트북에 두었는데, 본인도 모르게 노트북을 닫아놨고, 그 상태로 인식을 시키니 앱 서브타이틀 부분에 길게 오류 메시지가 영어로 나타났고, 그걸 해석해보고 백엔드 팀원의 노트북을 보기 닫혀있었습니다.</p>
<p>노트북을 열고 다시 HTTP 로컬 서버를 켜주었고, 다행히도 정상적으로 작동했습니다.
당시 처음 테스트 할 당시라서 다른 문제인줄 알고 앱 담당인 저는 심장이 떨렸던 기억이 납니다.</p>
<h2 id="삽질-기록">삽질 기록</h2>
<h3 id="1-디자인을-swiftui로-옮기기">1. 디자인을 SwiftUI로 옮기기</h3>
<p>한 분야에서 가장 오래 걸린 작업은 단연코 이거에요. 디자인 팀원은 UI만 만들었기 때문에 인터랙션이나 애니메이션, 사용 플로우 등은 제가 프론트를 짜면서 동시에 직접 설계해야 했고, 디테일이 자꾸 누락되거나 화면이 의도한 대로 나오지 않았어요. Figma 외 툴로는 로고를 어도비 일러스트레이터로 직접 작업했어요.</p>
<p>UI 디자인을 할때 Safe Zone을 고려하라는 지침을 팀 리더인 제가 주지 못했습니다. 이로 인해 Safe Zone이 고려되지 않았던 문제가 있어 Figma로 직접 수정했고, 프론트에 가져오는 동안 간격이 틀어지거나 디자인이 미세하게 다르게 가져와지거나 하는 문제가 있었지만, 계속해서 문제 해결을 하다보니 아침 5시였지만, 당시 정신없고 졸린 몸으로도 결국 문제점을 모두 없앴어요.</p>
<blockquote>
<p><img src="https://velog.velcdn.com/images/justcallmelight_/post/a020a02e-1fac-4340-8679-f21db361b63b/image.png" alt="">
Safe Zone이 고려되지 않은 상태의 화면과 네비 등에 아이콘이 나오지 않는 문제가 발생중인 EcoCheck 홈 화면.</p>
</blockquote>
<h3 id="2-gemini-응답-타임-아웃-백엔드">2. Gemini 응답 타임 아웃 (백엔드)</h3>
<p>백엔드에서 가장 힘들었던 문제예요. API 키를 정상적으로 설정했는데도 응답 시간 초과가 계속 발생했어요. 사진이 문제인지 코드가 문제인지 알 수 없어서, 요청을 <strong>모델 조회, 텍스트 생성, 사진 분석</strong>으로 쪼개 따로 테스트하고, 모델별 응답을 비교해서 정상적으로 분석되는 설정을 찾아냈어요.</p>
<p>여기서 배운 건 하나예요. <strong>문제가 막막할 때는 단계를 나눠서 확인한다.</strong> API를 연결하는 것만큼 입력 검증과 오류 처리가 중요하다는 것도 알게 됐어요.</p>
<h3 id="3-지도">3. 지도</h3>
<p>제가 구현하기 가장 어려웠던 기능이에요. 네이버 지도 API는 키 발급과 호출 확인까지 해 봤지만, 지도 API를 앱에 가져오는 게 힘들었어요. 카카오는 아예 비즈니스가 필요한것으로 확인됬고요. MVP로 OpenStreetMap을 넣어 뒀어요. 서울열린데이터광장의 쓰레기통 데이터 6,849건을 DB에 저장하고 주변 조회 API까지 만들었는데, 지도에 표시할 좌표는 아직 샘플 2건뿐이에요. 위도 경도 데이터가 있어야 위치를 정확히 찍을 수 있어서, 위도 경도 데이터와 전체 좌표가 포함된 주소기반산업지원서비스의 위치정보요약DB를 신청해 둔 상태이고, 받기까지 최대 수주일이 걸려요. DB를 받는 대로 EcoCheck에 구현할 예정이에요.</p>
<blockquote>
<p><img src="https://velog.velcdn.com/images/justcallmelight_/post/a83a19b3-0e81-42b1-854f-9002401981a7/image.PNG" alt="">
구현되어있는 앱 내 OpenStreetMap 연동 모습. 구현 단계라 디자인적으로 이슈가 보이는 모습이다.</p>
</blockquote>
<h3 id="번외---원동력">번외 - 원동력</h3>
<p>수많은 다과와 몬스터 에너지 드링크, 햄버거 그리고 야식 라면까지 선생님들이 챙겨 주셨어요. 개발하다 당이 떨어질 때마다 다과로 채우는 느낌이 정말 좋았고, 멘토 선생님들도 계셔서 든든했어요.</p>
<p>저는 다과 조금과 몬스터 에너지 드링크 2캔을 마셨어요. 흰색의 울트라 맛으로 골랐답니다. 저녁의 햄버거는 싸이버거와 화이트갈릭 싸이가 있던것 같은데, 저는 후자를 골랐어요.</p>
<p><img src="https://velog.velcdn.com/images/justcallmelight_/post/8ec2eb90-955c-4882-80be-ee39f47848b5/image.jpg" alt=""></p>
<h2 id="새벽의-기록">새벽의 기록</h2>
<ul>
<li>잠은 한숨도 못 잤어요. 돌아오는 2호선에서 많이 잤어요.</li>
<li>팀원들이 힘들어 할땐 제가 10분에서 20분정도 파워 냅을 재우기도 했어요.</li>
<li>너무 힘들때 새벽 1시에 백엔드 팀원과 로비에서 라면을 먹었어요. 나눈 대화는 &quot;힘들다&quot;, &quot;화이팅&quot;, &quot;맛있다&quot;, &quot;몸이 풀린다&quot; 정도였고, 라면 먹고 다시 개발에 들어갔어요</li>
<li>한창 해커톤이 진행되고 있던 새벽 4시 쯤, 주변을 둘러보니 다른 팀들은 몇명 잠시 자고 있거나 멘토링을 받고 있었어요</li>
<li>새벽 5시에 작은 창을 열어 해가 뜨는 중 바람을 쐬었어요. 당충전 사례처럼 몸이 회복되는 기분이 정말 좋았어요.</li>
<li>마감 직전에는 프레젠테이션, 발표 대본, 시연 영상을 준비했어요</li>
<li>가장 힘들 때 든 생각은 &quot;할 수 있다&quot;였고, 끝까지 간 원동력은 그 생각과 작품을 보여주고 싶은 마음이었어요</li>
</ul>
<h2 id="발표와-결과">발표와 결과</h2>
<p>수상 여부는 아직 결과가 없고, 이 프로젝트는 <strong>12월까지 이어져요.</strong></p>
<ul>
<li>발표에서 소프트웨어 파트는 제가 전부 설명했어요</li>
<li>처음 계획한 기능 중 80% 이상은 구현했다고 생각해요. 막판에 시간이 살짝 부족했어요</li>
<li>심사 피드백 중 기억에 남는 건 1학년의 나이에도 SQL 같은 여러 고도의 기술을 활용한 점을 좋게 봐 주셨다는 거예요. 감사하고 뿌듯했어요</li>
</ul>
<p>발표가 끝나고 가장 먼저 든 생각은 &quot;내가 미톤을 했구나&quot;였어요.</p>
<h2 id="앞으로-할-일">앞으로 할 일</h2>
<ul>
<li>지원 품목을 7종에서 전자기기 등으로 확대하고, 다양한 사진으로 정확도 검증</li>
<li>위치정보요약DB가 오면 쓰레기통 좌표를 채워서 지도 표시 완성, 이후 네이버 지도 적용</li>
<li>구글 로그인(Supabase), 포인트 지급·교환 기준, 랭킹 시스템, 리포트 구현</li>
<li>서버 배포와 기록 동기화 (지금은 앱의 기록이 기기 내부에 저장돼요)</li>
</ul>
<h2 id="마치며">마치며</h2>
<ul>
<li>혼자 했다면 못 했겠다 싶은 순간은 &quot;개발 속도&quot;였어요. 여러명에서 하니 작업이 병렬로 처리되어 더 빠르게 만들어 졌어요, 예를 들어 누군가는 프론트와 백엔드를 차례대로 계속 구현할 시간에 우리는 한명은 디자인, 한명은 백엔드, 한명은 프론트를 계속 구현하고 있으니 작업 속도가 빨랐어요.</li>
</ul>
<p>이번 미톤을 한 문장으로 정리하면 &quot;좋은 경험이었다&quot;예요. 평소 혼자 만들던 제가 팀으로 하나의 앱을 끝까지 만들어 보면서 자신감이 높아졌어요. 다음에도 무조건 참가할 거고, 앞으로도 iOS 앱 개발은 꼭 계속하고 싶어요.</p>
<p>몇 년 뒤 이 글을 다시 읽으면 아마 추억이겠다는 생각이 들어요.</p>
<hr>
<p>Project Information</p>
<p>Project: EcoCheck
Event: MITHON 2026 (미림마이스터고등학교, 알파코)
Date: 2026.10.23 – 2026.10.24
Location: 알파코 성수 2캠퍼스 (서울특별시 성동구 아차산로 111 (성수동2가) 2층)</p>
<p>Team</p>
<ul>
<li>권율 — Team Leader / Full-Stack / Frontend</li>
<li>백엔드 팀원 — Backend</li>
<li>디자이너 — Design</li>
</ul>
<p>Tech Stack</p>
<ul>
<li>iOS: Swift, SwiftUI, Xcode</li>
<li>Backend: Java, MySQL</li>
<li>AI: Google Gemini API</li>
<li>Map: OpenStreetMap</li>
<li>Collaboration: GitHub, Notion, Figma</li>
</ul>
<p>Github Repository: justcallmelightt/EcoCheck</p>
<p>2026년 10월 25일 작성.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[새로고침 없는 웹은 어떻게 만들까? React를 "제대로" 배워보기로 한 이유]]></title>
            <link>https://velog.io/@justcallmelight_/%EC%83%88%EB%A1%9C%EA%B3%A0%EC%B9%A8-%EC%97%86%EB%8A%94-%EC%9B%B9%EC%9D%80-%EC%96%B4%EB%96%BB%EA%B2%8C-%EB%A7%8C%EB%93%A4%EA%B9%8C-React%EB%A5%BC-%EC%A0%9C%EB%8C%80%EB%A1%9C-%EB%B0%B0%EC%9B%8C%EB%B3%B4%EA%B8%B0%EB%A1%9C-%ED%95%9C-%EC%9D%B4%EC%9C%A0</link>
            <guid>https://velog.io/@justcallmelight_/%EC%83%88%EB%A1%9C%EA%B3%A0%EC%B9%A8-%EC%97%86%EB%8A%94-%EC%9B%B9%EC%9D%80-%EC%96%B4%EB%96%BB%EA%B2%8C-%EB%A7%8C%EB%93%A4%EA%B9%8C-React%EB%A5%BC-%EC%A0%9C%EB%8C%80%EB%A1%9C-%EB%B0%B0%EC%9B%8C%EB%B3%B4%EA%B8%B0%EB%A1%9C-%ED%95%9C-%EC%9D%B4%EC%9C%A0</guid>
            <pubDate>Sat, 24 Oct 2026 16:25:41 GMT</pubDate>
            <description><![CDATA[<p>React는 메타(Meta)와 오픈소스 커뮤니티가 개발한 사용자 인터페이스(UI)를 만들기 위한 자바스크립트 라이브러리에요.</p>
<p>저는 React를 AI에게 도움받아 써봤지만, 전부 다 설명은 못 하겠더라고요</p>
<p>React를 AI의 도움을 받아 실제 프로젝트 여러 개에 구현해본 적이 있어서, 이미 여러 번 써봤어요. 그런데 설명을 못 하는 부분이 아직 있더라고요.</p>
<p>그래서 문득 이런 생각이 들었어요.</p>
<p>&quot;나, React를 쓰긴 쓰는데... 내가 쓴 게 맞나?&quot;</p>
<p>결과물은 돌아가는데, 왜 이렇게 짜는지는 설명을 못 하는 부분이 있었어요. 어떤 기술인지는 잘 알지만, 직접 코드를 한 줄씩 손코딩해서 짜본 경험은 잘 없었고요. 그래서 궁금증 반, &quot;제대로 배우면 더 잘 쓸 수 있겠다&quot;는 마음 반으로 React 강의를 듣기 시작했어요. 이 글은 강의 첫 부분을 듣고, 제가 이해한 “React를 왜 쓰는지”를 정리한 기록이에요.</p>
<p>SPA, 앱처럼 동작하는 웹사이트</p>
<p>인스타그램이나 쇼핑몰을 쓰다 보면, 메뉴를 눌러 다른 페이지로 이동해도 화면이 깜빡이지 않고 필요한 부분만 스르륵 바뀌는 걸 볼 수 있어요. 쇼핑몰에서 카테고리를 바꿔도 새로고침 없이 상품 목록만 바뀌죠.</p>
<p>이런 방식으로 만든 사이트를 SPA(Single Page Application) 라고 불러요. 이름 그대로 페이지가 하나뿐이고, 이동할 때마다 새 페이지를 통째로 받아오는 대신 필요한 내용만 바꿔 끼우는 방식이에요.</p>
<p>기존 웹사이트: 클릭 → 서버에서 새 페이지를 통째로 받아옴 → 화면이 깜빡이며 전환
SPA: 클릭 → 바뀌어야 할 부분만 교체 → 앱처럼 부드럽게 전환</p>
<p>인스타그램, 트위터, 페이스북이 대표적인 예고, 사용성이 실제 앱과 비슷해서 &quot;웹앱&quot;이라고도 부른다고 해요.</p>
<p>그걸 만들어주는 도구가 React</p>
<p>이런 웹앱을 만들 때 많이 쓰는 도구가 React, Angular, Vue 같은 라이브러리(프레임워크)예요. 강의에서는 그중 사용자가 가장 많은 React를 배운다고 했고, 제가 React를 선택한 이유도 비슷해요.</p>
<ol>
<li><p>사용자가 가장 많아요
사용자가 많다는 건 자료와 질문·답변이 많다는 뜻이고, 막혔을 때 해결책을 찾기 쉽다는 뜻이기도 해요. 입문자에게는 큰 장점이에요.</p>
</li>
<li><p>취업과 실무에서 자주 요구해요
규모와 관계없이 많은 회사가 웹사이트를 만들 때 이런 기술을 도입하고 있고, 프론트엔드 채용에서도 React 경험을 자주 볼 수 있어요. 거의 필수 소양처럼 여겨진다고 해요.</p>
</li>
<li><p>앱으로 확장하기 쉬워요
웹앱으로 만들어두면 PWA나 하이브리드 방식을 통해 실제 앱으로 발행하는 것도 상대적으로 수월해요.</p>
</li>
<li><p>사용자 경험이 좋아져요
화면이 빠르고 부드럽게 반응하면 사용자는 &quot;빠르다&quot;고 느끼고, 쇼핑몰 같은 서비스에서는 구매 전환율에도 긍정적인 영향이 있다고 알려져 있어요. (강의에서 들은 내용이라 정확한 수치나 사례는 따로 찾아볼 예정이에요.)</p>
</li>
</ol>
<p>참고로 새로고침 없는 방식 자체는 React만의 특징이 아니에요. Angular나 Vue도 같은 방식으로 동작해요. 그래서 &quot;왜 하필 React?&quot;의 답은 기술적 우월함보다는 사용자 수, 생태계, 채용 시장 쪽에 가깝다고 이해했어요.</p>
<p>솔직히, 쉽다고는 안 하더라고요</p>
<p>강의에서도 React 문법은 처음엔 낯설고, 기존 방식으로 자바스크립트를 써온 사람에게는 약간 충격일 수 있다고 해요. 요즘은 문법이 많이 쉬워졌지만 그래도 입문자에게는 어렵다고요.</p>
<p>저는 이미 AI로 결과물을 만들어본 상태라, &quot;아는 것 같은 착각&quot;이 가장 큰 함정일 것 같아요. 돌아가는 코드와 내가 이해한 코드는 다르니까요.</p>
<p>저는 이 정도 상태에서 시작해요.</p>
<p>설명할 수 있는 것: React가 왜 효율적이고 무엇인지, SPA가 뭔지, 컴포넌트가 대략 뭔지</p>
<p>나중에 이 글을 다시 열었을 때, 이 줄이 얼마나 바뀌었는지가 제 성장 기록이 될 것 같아요.</p>
<p>앞으로의 계획</p>
<p>지금은 강의를 절반 정도 들었고, 첫 부분은 OT 성격이라 아직 직접 따라 해본 건 없어요. 그래서 계획은 이렇게 잡았어요.</p>
<p>강의를 끝까지 듣되, 코드는 반드시 직접 쳐보기. AI와 채팅으로 문제 해결을 같이 하는 건 인정
AI에게 코드를 짜주게 하지 말고, 먼저 내가 짜본 뒤에 비교해보기
이전에 AI의 도움을 통해 만들었던 프로젝트 중 하나를 골라, 내 손으로 다시 만들어보거나 설명할 수준까지 도달하기
배우면서 헷갈렸던 부분은 이 블로그에 계속 정리하기</p>
<p>AI로 만드는 것과 직접 이해하고 만드는 것의 차이가 얼마나 큰지, 배우면서 느끼는 대로 솔직하게 기록해볼게요.</p>
<p>다음 글 예고: 컴포넌트와 props를 직접 손으로 짜보며 이해한 내용을 정리해볼 예정이에요.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[클래스 필드와 테이블 컬럼이 안 맞으면 생기는 일 (Java + SQLite)]]></title>
            <link>https://velog.io/@justcallmelight_/%ED%81%B4%EB%9E%98%EC%8A%A4-%ED%95%84%EB%93%9C%EC%99%80-%ED%85%8C%EC%9D%B4%EB%B8%94-%EC%BB%AC%EB%9F%BC%EC%9D%B4-%EC%95%88-%EB%A7%9E%EC%9C%BC%EB%A9%B4-%EC%83%9D%EA%B8%B0%EB%8A%94-%EC%9D%BC-Java-SQLite</link>
            <guid>https://velog.io/@justcallmelight_/%ED%81%B4%EB%9E%98%EC%8A%A4-%ED%95%84%EB%93%9C%EC%99%80-%ED%85%8C%EC%9D%B4%EB%B8%94-%EC%BB%AC%EB%9F%BC%EC%9D%B4-%EC%95%88-%EB%A7%9E%EC%9C%BC%EB%A9%B4-%EC%83%9D%EA%B8%B0%EB%8A%94-%EC%9D%BC-Java-SQLite</guid>
            <pubDate>Thu, 22 Oct 2026 06:10:39 GMT</pubDate>
            <description><![CDATA[<h2 id="들어가며">들어가며</h2>
<p>Java로 게임 점수를 SQLite에 저장하는 코드를 만들다가, 코드 리뷰를 받고 나서야 제 코드에 문제가 있다는 걸 알게 됐습니다.
<strong>실행은 잘 되는데, 나중에 터질 문제</strong>였어요. 이 글에서는 그 문제가 뭔지, 왜 바로 안 드러나는지, 어떻게 고쳤는지 정리합니다.</p>
<h2 id="1-문제의-코드-before">1. 문제의 코드 (Before)</h2>
<p>자바 클래스는 이렇게 만들었어요.</p>
<pre><code class="language-java">class GameScore {
    private Integer id;
    private String gameName;
    private String playerName;
    private Double score;
    private String data; // 필드 끝
    ...
}</code></pre>
<p>테이블은 이렇게 만들었고요.</p>
<pre><code class="language-sql">CREATE TABLE IF NOT EXISTS game_scores (
id INTEGER PRIMARY KEY AUTOINCREMENT,
game_name TEXT NOT NULL,
player_name TEXT NOT NULL,
score REAL NOT NULL,
date TEXT NOT NULL,
name TEXT NOT NULL,
grade INTEGER NOT NULL
)</code></pre>
<p>이 상태로 실행하면 <code>DB 연결 성공</code>이 정상적으로 출력됩니다. 그래서 문제를 눈치채지 못했어요.</p>
<h2 id="2-뭐가-안-맞았나">2. 뭐가 안 맞았나</h2>
<table>
<thead>
<tr>
<th>자바 클래스</th>
<th>SQL 테이블</th>
<th>문제</th>
</tr>
</thead>
<tbody><tr>
<td><code>data</code></td>
<td><code>date</code></td>
<td>오타. 같은 데이터인데 이름이 다름</td>
</tr>
<tr>
<td>없음</td>
<td><code>name</code></td>
<td>클래스에 없는 컬럼 (<code>playerName</code>과 의미도 중복)</td>
</tr>
<tr>
<td>없음</td>
<td><code>grade</code></td>
<td>클래스에 없는 컬럼</td>
</tr>
</tbody></table>
<h2 id="3-왜-바로-안-터질까">3. 왜 바로 안 터질까?</h2>
<p><code>CREATE TABLE</code>은 <strong>테이블 모양만 정의</strong>할 뿐, 자바 클래스와 비교하지 않습니다.
자바와 SQLite는 서로의 존재를 모르고, 둘을 연결하는 건 내가 직접 쓰는 <code>INSERT</code>/<code>SELECT</code> 문자열뿐이에요.
그래서 불일치는 <strong>데이터를 넣고 꺼내는 코드를 쓰는 순간</strong> 드러납니다.</p>
<h3 id="예상되는-에러-1-없는-컬럼을-조회할-때">예상되는 에러 1: 없는 컬럼을 조회할 때</h3>
<pre><code class="language-java">// 클래스 필드 이름(data)을 그대로 SQL에 쓴 경우
&quot;SELECT game_name, data FROM game_scores&quot;</code></pre>
<p>→ <code>no such column: data</code> 계열의 에러</p>
<h3 id="예상되는-에러-2-not-null-컬럼에-값을-안-넣을-때">예상되는 에러 2: NOT NULL 컬럼에 값을 안 넣을 때</h3>
<pre><code class="language-java">// 클래스에는 name, grade가 없으니 INSERT에도 넣을 값이 없음
&quot;INSERT INTO game_scores (game_name, player_name, score, date) VALUES (?, ?, ?, ?)&quot;</code></pre>
<p>→ <code>name</code>, <code>grade</code>가 <code>NOT NULL</code>이라 <code>NOT NULL constraint failed</code> 계열의 에러</p>
<blockquote>
<p>(직접 실행해서 나온 실제 에러 메시지로 교체하세요)</p>
</blockquote>
<h2 id="4-고치기-after">4. 고치기 (After)</h2>
<p>기준은 <strong>자바 클래스와 테이블이 1:1로 대응</strong>되는 것입니다.</p>
<pre><code class="language-java">class GameScore {
    private Integer id;
    private String gameName;
    private String playerName;
    private Double score;
    private String date; // data -&gt; date
    ...
}</code></pre>
<pre><code class="language-sql">CREATE TABLE IF NOT EXISTS game_scores (
id INTEGER PRIMARY KEY AUTOINCREMENT,
game_name TEXT NOT NULL,
player_name TEXT NOT NULL,
score REAL NOT NULL,
date TEXT NOT NULL
)</code></pre>
<table>
<thead>
<tr>
<th>자바 필드</th>
<th>SQL 컬럼</th>
</tr>
</thead>
<tbody><tr>
<td><code>id</code></td>
<td><code>id</code></td>
</tr>
<tr>
<td><code>gameName</code></td>
<td><code>game_name</code></td>
</tr>
<tr>
<td><code>playerName</code></td>
<td><code>player_name</code></td>
</tr>
<tr>
<td><code>score</code></td>
<td><code>score</code></td>
</tr>
<tr>
<td><code>date</code></td>
<td><code>date</code></td>
</tr>
</tbody></table>
<p>자바는 <code>camelCase</code>, SQL은 <code>snake_case</code>가 관례라서 이름 형태는 달라도 <strong>의미는 1:1</strong>이어야 합니다.</p>
<h2 id="5-배운-점">5. 배운 점</h2>
<ul>
<li>자바 클래스와 DB 테이블은 서로 자동으로 검증되지 않는다.</li>
<li>불일치는 <code>CREATE TABLE</code>이 아니라 <code>INSERT</code>/<code>SELECT</code>에서 드러난다.</li>
<li>테이블을 만들기 전에 <strong>필드 ↔ 컬럼 대응표</strong>부터 그려보면 이런 실수를 줄일 수 있다.</li>
<li>오타(<code>data</code>/<code>date</code>)는 컴파일러가 잡아주지 않는다.</li>
</ul>
<h2 id="마치며">마치며</h2>
<p>다음 글에서는 <code>PreparedStatement</code>로 INSERT/SELECT를 구현해 보겠습니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[개발자를 위한 기초 Velog 튜토리얼]]></title>
            <link>https://velog.io/@justcallmelight_/%EA%B0%9C%EB%B0%9C%EC%9E%90%EB%A5%BC-%EC%9C%84%ED%95%9C-%EA%B8%B0%EC%B4%88-Velog-%ED%8A%9C%ED%86%A0%EB%A6%AC%EC%96%BC</link>
            <guid>https://velog.io/@justcallmelight_/%EA%B0%9C%EB%B0%9C%EC%9E%90%EB%A5%BC-%EC%9C%84%ED%95%9C-%EA%B8%B0%EC%B4%88-Velog-%ED%8A%9C%ED%86%A0%EB%A6%AC%EC%96%BC</guid>
            <pubDate>Thu, 18 Jun 2026 05:34:44 GMT</pubDate>
            <description><![CDATA[<h2 id="markdown-튜토리얼">Markdown 튜토리얼</h2>
<p>Velog를 처음 켜고 글을 쓰면서 느낀 점은 <strong>&quot;웹을 구성하는 HTML 태그들과 구조적으로 굉장히 비슷하다&quot;</strong>는 것이다. 알고 보니 벨로그는 개발자들이 가장 애용하는 <strong>마크다운(Markdown) 기반</strong> 플랫폼이였다. </p>
<hr>
<h3 id="1-제목-태그-heading--html의-h1--h3">1. 제목 태그 (Heading) = HTML의 <code>&lt;h1&gt;</code> ~ <code>&lt;h3&gt;</code></h3>
<p>텍스트 앞에 샵(<code>#</code>)의 개수를 조절하여 제목 크기를 지정합니다. HTML의 제목 태그와 완전히 매칭되며, 벨로그 우측에 목차를 자동으로 생성해 준다.</p>
<h1 id="가장-큰-제목-h1">가장 큰 제목 (H1)</h1>
<h2 id="중간-제목-h2---주로-대주제를-나눌-때-사용">중간 제목 (H2) - 주로 대주제를 나눌 때 사용</h2>
<h3 id="소제목-h3---세부-항목을-나눌-때-사용">소제목 (H3) - 세부 항목을 나눌 때 사용</h3>
<hr>
<h3 id="2-코드-블록-code-block--html의-precode">2. 코드 블록 (Code Block) = HTML의 <code>&lt;pre&gt;&lt;code&gt;</code></h3>
<p>개발 블로그에서 코드를 예쁘게 서식화해 주는 기능이다. 백틱(```) 3개 뒤에 해당 언어(html, css, javascript 등)를 적어주면 알아서 하이라이팅이 적용된다.</p>
<pre><code class="language-javascript">// 자바스크립트 코드 테스트
const frontend = &quot;HTML, CSS, JS&quot;;
console.log(`${frontend} 마스터하기!`);</code></pre>
]]></description>
        </item>
    </channel>
</rss>