<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>seonyong-dev.log</title>
        <link>https://velog.io/</link>
        <description>최적의 해답을 찾고 무한한 과정을 즐기는 개발자</description>
        <lastBuildDate>Mon, 04 May 2026 09:05:50 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <copyright>Copyright (C) 2019. seonyong-dev.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/seonyong-dev" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[React 공부 전 알아야 할 JavaScript]_구조와 통신]]></title>
            <link>https://velog.io/@seonyong-dev/React-%EA%B3%B5%EB%B6%80-%EC%A0%84-%EC%95%8C%EC%95%84%EC%95%BC-%ED%95%A0-JavaScript%EA%B5%AC%EC%A1%B0%EC%99%80-%ED%86%B5%EC%8B%A0</link>
            <guid>https://velog.io/@seonyong-dev/React-%EA%B3%B5%EB%B6%80-%EC%A0%84-%EC%95%8C%EC%95%84%EC%95%BC-%ED%95%A0-JavaScript%EA%B5%AC%EC%A1%B0%EC%99%80-%ED%86%B5%EC%8B%A0</guid>
            <pubDate>Mon, 04 May 2026 09:05:50 GMT</pubDate>
            <description><![CDATA[<p>이번 포스트에서는 <code>ES Modules</code>, <code>Promise</code>, <code>async / await</code>에 대해 포스팅 했습니다.</p>
<blockquote>
<p>ES Modules(import/export)</p>
</blockquote>
<p>파일을 기능별로 나누어 내보거나 가져올 수 있는 기능입니다.</p>
<p>export 에는 두 가지 방법이 있습니다.</p>
<h4 id="1-named-export이름-지정-내보내기">1. Named export(이름 지정 내보내기)</h4>
<pre><code>// math.js
export const add = (a, b) =&gt; a + b;
export const multiply = (a, b) =&gt; a * b;

// App.js
import { add, multiply } from &#39;./math.js&#39;;</code></pre><p>위 코드처럼 export 할 변수 앞에 <code>export</code> 만 적어주면 되고 여러개 가능합니다. 가져올때는 {} 안에 지정한 변수명을 입력하여 가져오면 됩니다.
<span style="color:gray">(from 뒤의 <code>&#39;./math.js&#39;</code>는 같은 폴더 내의 math.js 파일에서 가져오라는 뜻입니다. 또한, 확장자는 생략가능합니다.)</span></p>
<h4 id="2-default-export-기본으로-내보내기">2. Default Export (기본으로 내보내기)</h4>
<pre><code>// Button.js
const Button = () =&gt; { ... };
export default Button;

// App.js
import MyButton from &#39;./Button.js&#39;; // &#39;Button&#39; 대신 &#39;MyButton&#39;으로 이름 지어도 됨</code></pre><p>위 코드처럼 export 할 때는 <code>export default</code>라고 적어주면 되고 named 와 달리 한 파일내에 한 개만 가능합니다. 가져올 때는 {} 없이 원하는 이름으로 가져올 수 있습니다.</p>
<br>
리액트의 기본 구조가 컴포넌트 단위로 만들어 조립하는 것이기 때문에 이 부분을 잘 이해해야 합니다.

<h5 id="컴포넌트component란--jsxhtml처럼-생긴-태그를-반환하는-재사용-가능한-함수입니다-이름을-만들때는-대문자로-시작pascalcase해야하고-사용할-때는-태그처럼-작성합니다ex-mycomponent">&#39;컴포넌트(Component)&#39;란? : JSX(HTML처럼 생긴 태그)를 반환하는 재사용 가능한 함수입니다. 이름을 만들때는 대문자로 시작(PascalCase)해야하고 사용할 때는 태그처럼 작성합니다.(ex. <code>&lt;MyComponent/&gt;</code>)</h5>
<br>

<blockquote>
<p>Promise 객체</p>
</blockquote>
<p>자바스크립트는 싱글 스레드라 한 번에 하나의 일만 할 수 있는데, 오래 걸리는 작업(네트워크 요청 등)을 기다리는 동안 화면이 멈추지 않게 하기 위해 비동기 처리가 필요하기 때문에 Promise를 사용합니다. 그래서 생기는 문제가 <strong>&#39;데이터를 가져오는 동안 화면이 멈춰버리거나&#39;</strong>, <strong>&#39;데이터 의존성&#39;</strong>입니다. 이것을 해결하기 위한 방법이 <code>Promise</code> 입니다.</p>
<h4 id="promise는-3가지-상태를-가집니다"><code>Promise</code>는 3가지 상태를 가집니다.</h4>
<ul>
<li><p>Pending (대기) : 작업 진행 중</p>
</li>
<li><p>Fulfilled (이행/성공) : 작업 성공</p>
</li>
<li><p>Rejected (거부/실패) : 작업 에러 발생</p>
<br>
#### 생성된 Promise 객체는 .then()과 .catch()를 사용해 결과를 처리합니다.

</li>
</ul>
<p>.then(): resolve가 호출되었을 때 실행됩니다. (성공 처리)</p>
<p>.catch(): reject가 호출되었을 때 실행됩니다. (실패 처리)</p>
<p>.finally(): 성공/실패 여부와 상관없이 마지막에 무조건 실행됩니다.</p>
<pre><code>// Promise 생성
function userLoad(userId) {
  return new Promise((resolve, reject) =&gt; {
    console.log(&quot;데이터를 가져오는 중...&quot;);

    setTimeout(() =&gt; {
      const success = Math.random() &gt; 0.3;

      if (success) {
        // 성공하면 resolve를 호출하고 데이터를 담아 보냅니다. (상태: fulfilled)
        resolve({ id: userId, name: &quot;홍길동&quot;, age: 20 });
      } else {
        // 실패하면 reject를 호출하고 에러를 담아 보냅니다. (상태: rejected)
        reject(&quot;서버 응답이 없습니다. 네트워크를 확인하세요.&quot;);
      }
    }, 1500);
  });
}

// Promise 실행
userLoad(101)
  .then((user) =&gt; {
    // resolve()가 실행되면 여기로 들어옵니다.
    // 인자로 넘어온 &#39;user&#39;는 resolve 안에 넣었던 객체입니다.
    console.log(&quot;성공&quot;);
    console.log(`유저 이름은 ${user.name}이고, 나이는 ${user.age}살입니다.`);
  })
  .catch((error) =&gt; {
    // reject()가 실행되면 여기로 들어옵니다.
    // 인자로 넘어온 &#39;error&#39;는 reject 안에서 쓴 문자열입니다.
    console.log(&quot;실패&quot;);
    console.log(`이유: ${error}`);
  })
  .finally(() =&gt; {
    // 성공하든 실패하든 마지막에 실행됩니다.
    console.log(&quot;모든 시도가 종료되었습니다.&quot;);
  });</code></pre><p>위 코드에서는 직접 생성자를 호출했지만 <code>fetch</code> 같은 일부 함수는 함수안에서 내부적으로 만들어줍니다.
<br></p>
<blockquote>
<p><strong><code>fetch</code> 함수와 <code>async/await</code></strong></p>
</blockquote>
<h4 id="fetch">fetch</h4>
<p>이전 프로젝트에서 비동기 통신을 위해 JQuery의 <code>AJAX</code>를 사용했었어요. <code>AJAX</code>를 사용하려면 외부 라이브러리를 참조해야하고 라이브러리를 통째로 가져오는 것이기 때문에 아무래도 무거워요.</p>
<p>이런 단점을 보완할 수 있는게 <code>fetch</code>에요. 브라우저 내장 기능이기 때문에 가볍고 가독성 측면에서도 <code>AJAX</code>보다 좋아요.</p>
<p>위 단락에서 <code>fetch</code> 함수는 <code>Promise</code>를 포함하고 있다고 했었는데 그 덕분에 비동기 통신이 가능합니다. 다만, 단점이 로직이 복잡해지면 가독성과 유지보수성이 급격하게 떨어진다는 점이에요.</p>
<pre><code>fetch(&#39;/user&#39;)
  .then(res =&gt; res.json())
  .then(user =&gt; {
    // 여기서 user 객체 사용 가능
    return fetch(`/posts?userId=${user.id}`);
  })
  .then(res =&gt; res.json())
  .then(posts =&gt; {
    // 위쪽 then 블록에서 끝났기 때문에 user 객체에 접근이 안 됨(따로 변수를 선언해둬야 함)
    console.log(`${user.name}의 글:`, posts); // ReferenceError: user is not defined
  });</code></pre><p>  위 코드에서 보이는 것처럼 Promise 체이닝(<code>.then</code>)이 생겨서 가독성과 유지보수가 힘들어지고 맨 아래 코드처럼 값의 공유가 힘들어집니다. 그래서 사용하는게 <code>async/await</code> 입니다.</p>
<h4 id="asyncawait">async/await</h4>
<p>  <code>async</code>와 <code>await</code>의 쓰임새를 먼저 알아볼게요.</p>
<ul>
<li><p>async : 일반 함수를 비동기 함수로 <strong>&#39;정의&#39;</strong>할때 사용합니다. (Promise 객체를 반환합니다.)</p>
</li>
<li><p>await : 비동기 작업(데이터를 불러오는 작업)을 기다렸다가 가져오도록 <strong>&#39;명령&#39;</strong>합니다.</p>
<p>위와 같이 쓰이기 때문에 <code>fetch</code> 앞에는 <code>await</code>가 붙습니다.</p>
</li>
</ul>
<pre><code> // 함수 앞에 async를 붙입니다.
async function fetchUserData() {
  try {
    // fetch 앞에 await를 붙입니다. 
    // 서버에서 응답이 올 때까지 여기서 잠시 멈춥니다.
    const response = await fetch(&#39;https://api.example.com/user/1&#39;);

    // &#39;서버 에러&#39;시에는 catch로 가지 않습니다. response.ok로 한번 걸러주는 작업이 필요합니다.
    if (!response.ok) {
      throw new Error(&quot;서버에 문제가 발생했습니다.&quot;);
    }

    // 응답이 왔다면, 데이터(JSON)를 꺼냅니다.
    // 이 과정도 시간이 걸리므로 await를 붙여서 기다려줍니다.
    const userData = await response.json();

    console.log(&quot;사용자 정보:&quot;, userData);

  } catch (error) {
    // 네트워크가 끊기거나 주소가 잘못되는 등 에러가 나면 이곳이 동작합니다.)
    console.error(&quot;데이터 가져오기 실패:&quot;, error);
  }
}</code></pre><p><code>Promise</code>만 사용할 때보다 가독성이 향상되고 변수에 담을 수 있어 재사용에 용이합니다. 또한, <code>try...catch</code>를 사용할 수 있어 에러 처리에도 좋습니다.</p>
<p><br><br>
<span style="color:gray">이번 포스트를 마지막으로 [React 공부 전 알아야 할 JavaScript]에 대한 포스팅이 끝났습니다. 다음에 React 공부한 내용에 대해 포스팅 하겠습니다.</span></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[React 공부 전 알아야 할 JavaScript]_조건부 렌더링]]></title>
            <link>https://velog.io/@seonyong-dev/React-%EA%B3%B5%EB%B6%80-%EC%A0%84-%EC%95%8C%EC%95%84%EC%95%BC-%ED%95%A0-JavaScript%EC%A1%B0%EA%B1%B4%EB%B6%80-%EB%A0%8C%EB%8D%94%EB%A7%81</link>
            <guid>https://velog.io/@seonyong-dev/React-%EA%B3%B5%EB%B6%80-%EC%A0%84-%EC%95%8C%EC%95%84%EC%95%BC-%ED%95%A0-JavaScript%EC%A1%B0%EA%B1%B4%EB%B6%80-%EB%A0%8C%EB%8D%94%EB%A7%81</guid>
            <pubDate>Sun, 03 May 2026 18:18:47 GMT</pubDate>
            <description><![CDATA[<p>이번 포스트에서는 <strong>&#39;삼항 연산자&#39;</strong>, <strong>&#39;단축 평가&#39;</strong>, <strong>&#39;옵셔널 체이닝&#39;</strong>에 대해서 포스팅했습니다.</p>
<blockquote>
<p><strong>삼항 연산자(Condition ? A : B)</strong></p>
</blockquote>
<p>조건(condition)이 참일 때는 &#39;A&#39;, 거짓일 때는 &#39;B&#39;를 실행하는 연산자 입니다.</p>
<pre><code>const isLogin = true;
const message = isLogin ? &quot;환영합니다!&quot; : &quot;로그인이 필요해요.&quot;;
console.log(message); // 환영합니다!</code></pre><p>React 화면을 만드는 HTML 코드(JSX)는 자바스크립트 &#39;함수 호출&#39;로 변환되는데, 함수 인자 자리에 문장이 들어갈 수 없고 &#39;값&#39;만 들어갈 수 있기 때문에 if문을 쓸 수 없습니다. 그래서 삼항 연산자를 사용합니다. 또한, 상태에 따라 UI를 바꿔야할 때 사용합니다.</p>
<blockquote>
<p><strong>단축 평가 (&amp;&amp; , ||)</strong></p>
</blockquote>
<h4 id="and-연산자">&amp;&amp; (AND 연산자)</h4>
<p>: 앞이 Truthy(참 같은 값)이면 뒤의 값을 반환하고 앞이 Falsy(0, false 등)이면 앞의 값을 그대로 반환합니다.</p>
<pre><code>message &amp;&amp; &lt;p&gt;새 메시지가 왔어요!&lt;/p&gt;
(메시지가 있을 때만 알림창을 띄우고 싶을 때 사용)


// 주의사항 : count가 0인 경우
count &amp;&amp; &lt;p&gt;내용&lt;/p&gt; // 화면에 &#39;0&#39; 출력

count &gt; 0 &amp;&amp; &lt;p&gt;내용&lt;/p&gt; // 화면에 출력되는 것 없음</code></pre><h4 id="-or-연산자">|| (OR 연산자)</h4>
<p>: 앞이 Truthy이면 앞의 값을 반환하고 앞이 Falsy이면 뒤의 값(기본값)을 반환합니다.</p>
<pre><code>userName || &quot;익명사용자&quot;
(사용자 이름이 등록 안 되어 있을 때 &#39;익명&#39;이라고 보여주고 싶을 때 사용)</code></pre><p>데이터가 없을 때 아예 안보여주거나 기본값을 주고 싶을 때 사용합니다.</p>
<p>삼항연산자와 OR 연산자를 비교해서는 조건중심인지, 데이터 유무 중심인지 비교해보면 구분하는데 도움이 될겁니다.</p>
<pre><code>// 1. OR 연산자
const result = score || &quot;미응시&quot;; 
console.log(result); // &quot;미응시&quot; (0은 자바스크립트에서 false)

// 2. 삼항 연산자
const result = (score === null) ? &quot;미응시&quot; : score;
console.log(result); // 0 (정확히 null일 때만 체크)</code></pre><p> 위의 코드는 score가 0일 때 각각의 연산자가 서로 다른 결과를 도출하는 것을 확인할 수 있습니다.</p>
<p> OR 연산자가 데이터 유무 중심이라고 했는데 모순처럼 느껴지실겁니다. &#39;0&#39;이라는 데이터가 있는데도 불구하고 기본값을 출력하는 이유는 이미 자바스크립트의 설계가 그렇게 되어 있기 때문입니다.
 <span style="color:gray; font-size: 16px">(ES11(2020)에서는 0도 값으로 인정해주는 <code>??</code>연산자도 있습니다. 리액트 환경에서는 버전 상관없이 사용 가능합니다.)</span></p>
<blockquote>
<p><strong>옵셔널 체이닝 (?.)</strong></p>
</blockquote>
<p> 데이터가 없어도 에러가 나지 않게 해주는 문법입니다.</p>
<p> 사용할때는 값을 읽을 때만 사용 가능하며, user?.name = &#39;홍길동&#39; 처럼 값을 할당할 때는 사용할 수 없습니다.</p>
<pre><code> // address가 있으면 city를 읽고, 없으면 그냥 undefined로 남겨줘 (에러 금지!)
const city = user?.address?.city;</code></pre><p>위 코드 처럼 단계마다 사용가능합니다.</p>
<p>리액트는 데이터가 비동기로 들어오는 경우가 많습니다. &quot;Uncaught TypeError: Cannot read properties of undefined&quot; 에러로 다운되는 것을 방지해줍니다.</p>
<br>
<span style="color:gray">다음 포스트는 마지막 구조와 통신 내용으로 포스팅하겠습니다.</span>
]]></description>
        </item>
        <item>
            <title><![CDATA[[React 공부 전 알아야 할 JavaScript]_리스트 렌더링]]></title>
            <link>https://velog.io/@seonyong-dev/React-%EA%B3%B5%EB%B6%80-%EC%A0%84-%EC%95%8C%EC%95%84%EC%95%BC-%ED%95%A0-JavaScript%EB%A6%AC%EC%8A%A4%ED%8A%B8-%EB%A0%8C%EB%8D%94%EB%A7%81</link>
            <guid>https://velog.io/@seonyong-dev/React-%EA%B3%B5%EB%B6%80-%EC%A0%84-%EC%95%8C%EC%95%84%EC%95%BC-%ED%95%A0-JavaScript%EB%A6%AC%EC%8A%A4%ED%8A%B8-%EB%A0%8C%EB%8D%94%EB%A7%81</guid>
            <pubDate>Sun, 03 May 2026 15:15:37 GMT</pubDate>
            <description><![CDATA[<p>이번 포스트는 <code>map()</code>, <code>filter()</code>, <code>find()</code>, <code>reduce()</code>, 4가지 함수에 대해 포스팅하겠습니다.</p>
<blockquote>
<p><strong>map()</strong></p>
</blockquote>
<p>배열의 모든 요소를 하나씩 원하는 형태로 변환해주는 함수입니다.</p>
<pre><code>// 화면 그릴 때
const posts = [{id: 1, title: &#39;첫 글&#39;}, {id: 2, title: &#39;두 번째 글&#39;}];
const list = posts.map(post =&gt; &lt;li key={post.id}&gt;{post.title}&lt;/li&gt;);

// 데이터 수정할 때(상태 업데이트)
const users = [{id : 1, name : &#39;A&#39;}, {id : 2, name : &#39;B&#39;}];
const updated = users.map(u =&gt; u.id === 1 ? {...u, name : &#39;Modified&#39;} : u);</code></pre><p>React에서 대부분의 경우 화면 그릴 때 사용합니다. 태그에 key값이 있는 이유는 나머지 기존 요소들은 그대로 둔 채 새로운 요소만 추가하기 위함입니다.
<br></p>
<blockquote>
<p><strong>filter()</strong></p>
</blockquote>
<p>배열에서 조건에 맞는 데이터만 추출해 새로운 배열을 만들 때 사용합니다.</p>
<pre><code>const products = [
  { name : &#39;사과&#39;, price : 1000 },
  { name : &#39;수박&#39;, price : 5000 }
];
const cheap = products.filter(item =&gt; item.price &lt; 2000);
console.log(cheap); // [{ name : &#39;사과&#39;, price : 1000 }]</code></pre><p>&#39;삭제 기능&#39;을 만들 때 필수입니다. 삭제 한 후 나머지 데이터를 보여줄 때 사용합니다.
<br></p>
<blockquote>
<p><strong>find()</strong></p>
</blockquote>
<p>조건에 맞는 첫 번째 데이터 하나만 추출할 때 사용합니다.</p>
<pre><code>const users = [{ id : 1, name : &#39;철수&#39; }, { id : 2, name : &#39;영희&#39; }];
const user = users.find(u =&gt; u.id === 2);
console.log(user); // { id : 2, name : &#39;영희&#39; }</code></pre><p>게시판 목록에서 특정 게시글을 클릭했을 때, 그 게시글의 상세 내용 하나만 가져와서 보여줄 때 사용합니다.</p>
<blockquote>
<p><strong>reduce()</strong></p>
</blockquote>
<p>데이터 타입에 따라 결과가 다릅니다. 숫자 배열일 때는 <strong>합계</strong>, 문자열 배열일 때는 <strong>개수(카운팅)를 세는 객체</strong>를 결과로 도출합니다. 그리고 배열을 합쳐서 2차원 배열을 1차원으로 펼칠 수도 있습니다.</p>
<pre><code>// 기본 문법 구조(주로 누적값과 현재값만 사용)
배열.reduce((누적값, 현재값, 인덱스, 원본배열) =&gt; 다음 누적값, 누적값의 초기값);

// 숫자 배열인 경우
const nums = [1, 2, 3, 4];
const sum = nums.reduce((acc, cur) =&gt; acc + cur, 0); 
console.log(sum); // 10

// 문자열 배열인 경우
const items = [&#39;apple&#39;, &#39;banana&#39;, &#39;apple&#39;, &#39;orange&#39;];
const count = items.reduce((acc, cur) =&gt; {
  acc[cur] = (acc[cur] || 0) + 1;
  return acc;
}, {}); 
console.log(count); // { apple : 2, banana : 1, orange : 1 }

// 배열 합치기(2차원 배열 -&gt; 1차원 배열)
const nested = [[1, 2], [3, 4], [5, 6]];
const flat = nested.reduce((acc, cur) =&gt; acc.concat(cur), []);
console.log(flat); // [1, 2, 3, 4, 5, 6]
</code></pre><p><span style="color:gray; font-size:16px;">유의사항 : 초기값을 설정하지 않으면 0번 인덱스를 초기값으로 사용하고 현재값은 1번 인덱스부터 시작합니다.</span></p>
<p><code>reduce()</code>는 단순 나열이 아닌 통계를 내거나 재조합 할 때 유용합니다.
<br>
<span style="color:gray">다음 포스트는 조건부 렌더링에 대한 내용으로 포스팅하겠습니다.</span></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[React 공부 전 알아야 할 JavaScript]_데이터 조작 핵심 기술]]></title>
            <link>https://velog.io/@seonyong-dev/React-%EA%B3%B5%EB%B6%80-%EC%A0%84-%EC%95%8C%EC%95%84%EC%95%BC-%ED%95%A0-JavaScript%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%A1%B0%EC%9E%91-%ED%95%B5%EC%8B%AC-%EA%B8%B0%EC%88%A0</link>
            <guid>https://velog.io/@seonyong-dev/React-%EA%B3%B5%EB%B6%80-%EC%A0%84-%EC%95%8C%EC%95%84%EC%95%BC-%ED%95%A0-JavaScript%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%A1%B0%EC%9E%91-%ED%95%B5%EC%8B%AC-%EA%B8%B0%EC%88%A0</guid>
            <pubDate>Sun, 03 May 2026 12:03:48 GMT</pubDate>
            <description><![CDATA[<p>이번 포스트에선 &#39;구조분해할당&#39;, &#39;스프레드 연산자&#39;, &#39;나머지 매개변수&#39;에 대해 포스팅 했습니다.</p>
<blockquote>
<p><strong>구조 분해 할당 (Destructuring Assignment)</strong></p>
</blockquote>
<p>객체나 배열에서 필요한 데이터만 추출해서 변수로 만드는 것을 말해요.</p>
<h4 id="배열분해--순서-중요">배열분해 : 순서 중요</h4>
<pre><code>const colors = [&#39;red&#39;, &#39;blue&#39;, &#39;green&#39;];

// 고전적인 방식
const first = colors[0];
const second = colors[1];


// 구조 분해
const [first, second] = colors; // first에는 &#39;red&#39;, second에는 &#39;blue&#39;가 들어감

// 구조 분해(,으로 순서 구분하여 원하는 데이터 추출)
const [,first, second] = colors; // first에는 &#39;blue&#39;, second에는 &#39;green&#39;이 들어감
</code></pre><br>

<h4 id="객체분해--key-중요">객체분해 : key 중요</h4>
<pre><code>const user = { name : &#39;홍길동&#39;, age : 25 };

// 고전적인 방식
const name = user.name; // 또는 const name = user[&#39;name&#39;]


// 구조 분해
const { name, age } = user; 
console.log(name); // &#39;홍길동&#39;

// 구조 분해(key와 &#39;다른 변수명&#39;으로 저장)
const { name : id, age } = user;
console.log(id) // &#39;홍길동&#39;

// 구조 분해(key값이 없거나 undefined 일 경우 &#39;기본값 설정&#39;)
const { name, age, job = &#39;dev&#39; }
console.log(job) // &#39;dev&#39;</code></pre><p>이렇게 구조분해를 사용하면 가독성이 증가할뿐만 아니라 유지보수가 용이하고 기본값을 설정할 수 있어 편리합니다.</p>
<blockquote>
<p><strong>스프레드 연산자 (Spread Operator)</strong></p>
</blockquote>
<p>스프레드 단어 뜻처럼 배열이나 객체의 요소들을 낱개로 분리하여 복사한 후 값을 추가하거나 수정하는 것을 말합니다.
사용할 때는 기존의 변수 앞에 &#39;...&#39;(점 세개)를 붙여서 사용하고 매개변수로 적을 때는 <strong>맨 앞</strong>에 적어 사용합니다.</p>
<h4 id="배열">배열</h4>
<pre><code>// 배열 값 추가
const base = [1, 2];
const newArray = [...base, 3, 4]; // [1, 2, 3, 4]

// 배열 값 수정
const updateArray = [...newArray.slice(0,2), 5, ...newArray.slice(3)]
// [1, 2, 5, 4]</code></pre><br>

<h4 id="객체">객체</h4>
<pre><code>const user = { name : &#39;홍길동&#39;, age : 25 };
const updatedUser = { ...user, age : 26, job : &#39;dev&#39;};
// name은 유지하고 age 수정, job 추가</code></pre><p>리액트에는 기존의 데이터를 직접 수정하지 않고 복사본을 사용해야하는 <strong>&#39;불변성 유지&#39;</strong>라는 규칙이 있기 때문에 스프레드 연산자가 매우 유용합니다.</p>
<blockquote>
<p><strong>나머지 매개변수 (Rest Parameter)</strong></p>
</blockquote>
<p>rest도 단어 뜻처럼 <span style="color:gray">(지정한 데이터를 제외한)</span> 나머지 값들을 모아줍니다.
사용할 때는 rest도 스프레드처럼 &#39;...&#39;(점 세개)하고 뒤에 변수명(변수명은 자신이 지정)을 붙입니다. 스프레드와는 반대로 매개변수로 적을 때는 무조건 <strong>맨 뒤</strong>에 적어 사용합니다. </p>
<h4 id="함수-파라미터">함수 파라미터</h4>
<pre><code>function exRest(first, sencond, ...others) {
  console.log(first);  // 1
  console.log(second); // 2
  console.log(others); // [3, 4, 5]
}
exRest(1, 2, 3, 4, 5);</code></pre><br>

<h4 id="객체-구조-분해와-함께-사용">객체 구조 분해와 함께 사용</h4>
<pre><code>const user = { id : 1, name : &#39;홍길동&#39;, age : 25, region : &#39;서울&#39; };
const { id, ...rest } = user;

console.log(id);   // 1
console.log(rest); // { name: &#39;홍길동&#39;, age: 25, region: &#39;서울&#39; }</code></pre><p>특정 데이터를 변수로 할당하거나 추출하고 남은, 나머지 데이터들을 모아서 (배열이나 객체 형태로) 한꺼번에 전달할 때 사용합니다.</p>
<br>
<span style="color:gray">다음 포스트에서는 리스트 렌더링에 대해 포스팅하겠습니다.</span>]]></description>
        </item>
        <item>
            <title><![CDATA[[React 공부 전 알아야 할 JavaScript]_문법]]></title>
            <link>https://velog.io/@seonyong-dev/React-%EA%B3%B5%EB%B6%80-%EC%A0%84-%EC%95%8C%EC%95%84%EC%95%BC-%ED%95%A0-JavaScript%EB%AC%B8%EB%B2%95</link>
            <guid>https://velog.io/@seonyong-dev/React-%EA%B3%B5%EB%B6%80-%EC%A0%84-%EC%95%8C%EC%95%84%EC%95%BC-%ED%95%A0-JavaScript%EB%AC%B8%EB%B2%95</guid>
            <pubDate>Sun, 03 May 2026 08:46:28 GMT</pubDate>
            <description><![CDATA[<p>React(이하 &#39;리액트&#39;)가 좋다는 말도 많이 듣고 리액트 기술 역량을 요구하는 기업들도 많아서 공부해봐야겠다 싶었어요. 아직 공부 중인데 리액트가 뭔지 알고 나니까 꼭 알야할 필수 지식으로 느껴지더라고요. <span style="color:gray; font-size:16px">(새로운 기술 배워서 편하게 개발할 생각하니까 벌써 설렙니다.😚)</span></p>
<p>리액트에 대한 포스트는 빨리 공부해서 곧 포스팅 해볼거에요!
이번 포스트는 리액트를 공부하기 위해 공부한 JavaScript(이하 &#39;자바스크립트&#39;)에 대한 내용을 기록해볼게요.</p>
<p>자바스크립트는 모든 프로젝트에서 사용했는데 당시엔 사용하기 급급해서 애매하게 알고 넘어간 부분들도 있었어요.</p>
<p>그래서 이번 포스트에서는 공부하면서 다시 정립한 애매한 부분들과 새롭게 배운 내용들에 대해 기록해 볼 생각이에요.</p>
<blockquote>
<p><strong>변수 선언 키워드</strong></p>
</blockquote>
<p>자바스크립트의 변수 선언 키워드는 <code>var</code>, <code>let</code>, <code>const</code> 3가지가 있어요.</p>
<ol>
<li><p>var(현재 거의 사용X)
- 중복 선언 가능 : 똑같은 이름으로 변수 선언 가능
- 함수 레벨 스코프 : 함수 안에서 선언된 변수만 지역 변수로 인정 -&gt; {} 안에서 선언한 변수를 밖에서 사용 가능
- 호이스팅 : 선언 전에 값을 부를 경우, undefined 출력 -&gt; 유지보수 힘듬</p>
</li>
<li><p>let(변수)
- 중복 선언 불가능
- 재할당 가능
- 블록 레벨 스코프 : {} 안에서 선언한 변수 밖에서 사용 불가능</p>
</li>
<li><p>const(상수)
- 재할당 불가능
- 초기화 필수
- 객체/배열의 경우 객체나 배열 내부의 값은 수정 가능</p>
</li>
</ol>
<blockquote>
<p><strong>this 바인딩</strong></p>
</blockquote>
<p>자바스크립트에서는 &#39;누가, 어떻게&#39; 호출했는지에 따라 가리키는 대상이 다릅니다.(동적 바인딩)</p>
<ol>
<li><p>기본 호출: 그냥 함수를 실행하면 this는 전역 객체(window 또는 global)를 가리킵니다.</p>
</li>
<li><p>객체의 메서드 호출: 객체 안에 정의된 함수를 실행하면, this는 해당 메서드를 호출한 객체를 가리킵니다.(ex. user.hello()에서 this는 user)</p>
</li>
<li><p>생성자 함수 호출: new 키워드로 객체를 만들 때, this는 새로 생성된 인스턴스를 가리킵니다.</p>
</li>
<li><p>화살표 함수 (Arrow Function): 화살표 함수는 자신만의 this를 가지지 않고 <strong>자신을 감싸고 있는 외부 환경의 this</strong>를 그대로 가져와서 씁니다.
ex) AI모델 Gemini에서 발췌해온 예시입니다.</p>
<pre><code>// 전역에서 선언한 경우
const myFunc = () =&gt; {
console.log(this); 
};
</code></pre></li>
</ol>
<p>myFunc(); // window (또는 undefined in strict mode)</p>
<hr>
<p>// 일반 함수에서 선언한 경우
const obj = {
  name: &#39;Gemini&#39;,
  printName: function() {
    // 여기서의 this는 obj입니다.
    const arrow = () =&gt; {
      console.log(this.name); 
    };
    arrow();
  }
};</p>
<p>obj.printName(); // &#39;Gemini&#39; (상위 함수인 printName의 this를 그대로 사용)</p>
<pre><code>
유의사항으로 자바스크립트의 객체에서 선언한 경우엔 전역 스코프를 가리킵니다. {}가 &#39;블록&#39;이 아니라 &#39;값&#39;을 나타내기 때문이에요.
추가로 `class`라는 문법 안에서는 화살표 함수를 만든 인스턴스를 가리킵니다.

&gt; Arrow function 
</code></pre><p>// 일반 함수
const add = function(a, b) {
    return a + b;
};</p>
<hr>
<p>// 화살표 함수
const add = (a, b) =&gt; a + b;</p>
<pre><code>
화살표 함수는 동적바인딩의 문제점을 해결하고 간결한 코드 작성이 가능해서 많이 사용합니다.

&gt; **템플릿 리터럴(Template Literals)**

따옴표(&quot;) 대신 백틱(\`)을 사용한 문법이에요. &lt;span style=&quot;color:gray; font-size:16px;&quot;&gt;(이전에 [&quot;RESTful API 구현해보기&quot;](https://velog.io/@seonyong-dev/RESTful-API-%EA%B5%AC%ED%98%84%ED%95%B4%EB%B3%B4%EA%B8%B0) 포스트에서 언급했던 내용입니다.)&lt;/span&gt;
</code></pre><p>// 기존 방식
const name = &quot;홍길동&quot;;
const age = 25;
console.log(&quot;제 이름은 &quot; + name + &quot;이고,\n나이는 &quot; + age + &quot;살입니다.&quot;);</p>
<p>// 템플릿 리터럴 방식
const name = &quot;홍길동&quot;;
const age = 25;
console.log(<code>제 이름은 ${name}이고,
나이는 ${age}살입니다.</code>);</p>
<pre><code>
템플릿 리터럴을 사용하면 문자열과 변수를 같이 사용할때 실수를 줄일 수 있고 줄바꿈도 알아서 적용되서 매우 편리한 기능입니다.

&gt; **객체 초기화 단축(Shorthand Property Names)**

객체를 만들 때 key와 value 값이 같다면 한 번만 적어도 되는 기능이에요.
</code></pre><p>// 기존 방식
const name = &quot;홍길동&quot;;
const age = 25;</p>
<p>const user = {
  name: name, 
  age: age<br>};</p>
<p>// 단축 방식
const name = &quot;홍길동&quot;;
const age = 25;</p>
<p>const user = {
  name,
  age
};</p>
<p>```</p>
<p>이 문법을 사용하면 가독성이 좋아지고 한 군데만 고치면 되니가 유지보수도 편리해요. 데이터를 꺼내고 넣을때 코드의 흐름이 자연스러워져요.
<br>
<span style="color:gray">다음 포스트에서는 데이터를 다루는 핵심 기술들을 포스팅할 예정입니다.</span></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[저사양 노트북으로 개발공부를 위한 Setting (자바)]]></title>
            <link>https://velog.io/@seonyong-dev/%EC%A0%80%EC%82%AC%EC%96%91-%EB%85%B8%ED%8A%B8%EB%B6%81%EC%9C%BC%EB%A1%9C-%EA%B0%9C%EB%B0%9C%EA%B3%B5%EB%B6%80%EB%A5%BC-%EC%9C%84%ED%95%9C-Setting-%EC%9E%90%EB%B0%94</link>
            <guid>https://velog.io/@seonyong-dev/%EC%A0%80%EC%82%AC%EC%96%91-%EB%85%B8%ED%8A%B8%EB%B6%81%EC%9C%BC%EB%A1%9C-%EA%B0%9C%EB%B0%9C%EA%B3%B5%EB%B6%80%EB%A5%BC-%EC%9C%84%ED%95%9C-Setting-%EC%9E%90%EB%B0%94</guid>
            <pubDate>Fri, 01 May 2026 09:50:29 GMT</pubDate>
            <description><![CDATA[<p>저번 포스트를 위해 자바관련 프로그램을 VS Code에 설치한 방법을 포스팅해볼게요.</p>
<blockquote>
<p>VS Code 내 확장프로그램 설치(Extension Pack for Java)</p>
</blockquote>
<p><img src="https://velog.velcdn.com/images/seonyong-dev/post/bba66021-5521-4563-a197-e1222604051b/image.jpg" alt=""></p>
<p>왼쪽 사이드에 extension 아이콘 또는 ctrl + shift + x 버튼을 눌러 위와 같이 확장프로그램을 찾아 설치해주세요! 자바용 IDE로 변환해주는 프로그램이에요.</p>
<p>그 다음 파란색 동그라미 스크롤을 내리면 빨간색 동그라미의 <code>Spring Boot Extension pack</code>을 클릭해서 설치해주면됩니다. Spring Boot는 편하게 개발할 수 있게 틀을 제공해주는 프레임워크에요.
<span style="color:gray">(사실 Spring MVC만 사용해보다가 저번 포스팅때 같이 공부해보자는 마음으로 Spring Boot를 처음 사용해봐서 어리버리 했는데 사용하고나서 공부해보니까 완전 혁신이더라고요.)</span></p>
<h3 id="spring-boot-구조를-사용하는-방법은-두-가지에요">Spring Boot 구조를 사용하는 방법은 두 가지에요.</h3>
<h4 id="웹사이트에서-만들기spring-initializr-260501-기준">웹사이트에서 만들기(<a href="https://start.spring.io/">Spring Initializr</a> 26.05.01 기준)</h4>
<p><img src="https://velog.velcdn.com/images/seonyong-dev/post/e3ae8ed1-ddc7-4e55-9d28-aba0355154cc/image.jpg" alt=""></p>
<p>제목에 있는 링크에 접속하면 위 사진과 비슷한 페이지가 나오는데요. 사진은 제가 미리 다 설정해놓은 상태입니다.</p>
<p>제가 설정한 Dependencies는요.</p>
<ul>
<li>Spring Web : Tomcat 서버와 JSON 변환 기능이 포함</li>
<li>Lombok(롬복) : 자바에서 Getter, Setter 같은 반복적인 코드를 자동으로 생성</li>
<li>Spring Boot DevTools : 코드를 수정하고 저장하면 서버를 자동으로 재시작</li>
</ul>
<p>Lombok은 사용했었다가 저번 포스트에서 갑자기 사용하면 혼란올 것 같고 설명하자니 너무 길어져서 포스트에선 제외했었어요.</p>
<p>나머지 해당하는 것 선택해서 GENEARTE 클릭하면 압축파일이 다운받아지는데요. 압축을 풀어서 VS Code에서 사용할 수 있어요.</p>
<h4 id="vs-code-내에서-프로젝트-만들기">VS Code 내에서 프로젝트 만들기</h4>
<ol>
<li><p>명령어 팔레트 열기 : Ctrl + Shift + P
명령어 입력: Spring Initializr: Create a Gradle Project (또는 Maven)</p>
</li>
<li><p>설정 선택 : 웹사이트에서 했던 것과 똑같은 과정대로 차례로 나옵니다.
- Spring Boot 버전 선택
- 언어 선택 (Java)
- Group ID, Artifct ID 입력
- Dependencies 선택 (여기서 &#39;Spring Web&#39; 등을 검색해서 추가!)</p>
</li>
<li><p>폴더 지정: 프로젝트를 저장할 폴더를 고르면, 자동으로 압축이 풀린 상태로 프로젝트가 생성되고 바로 열립니다.</p>
</li>
</ol>
<p>익숙해지면 아무래도 두 번째 방법이 편할거에요. 처음 사용해보시면 첫 번째 방법으로 공부해가면서 해보는 게 좋을 것 같아요.</p>
<blockquote>
<p>JDK 설치</p>
</blockquote>
<p>필수로 설치해야하는 자바 개발 도구 모음이에요. 자바 프로그램을 만들고 실행하는 데 필요한 모든 것이 들어있어요. (JRE + 개발 도구)</p>
<p>여러 사이트에서 다운 받을 수 있는데 전 <a href="https://adoptium.net/marketplace?version=17">Adoptium</a>(26.05.01기준)에서 다운받았어요.
<img src="https://velog.velcdn.com/images/seonyong-dev/post/da1538db-6d95-423e-b563-f60bdfa4afe5/image.jpg" alt=""></p>
<p>version은 LTS 버전(오랫동안 사후 지원을 해주는 안정된 버전)인 17로 했어요.</p>
<br>
이렇게하면 개발공부를 위한 자바 setting은 끝났어요! 파이팅해보자구요~!

<p><br><br>
<span style="color:gray">모든 설치를 마쳤는데도 VS Code에서 자바를 인식하지 못하면 VS Code를 완전히 종료한 뒤 다시 켜보거나, 컴퓨터를 재부팅해 보세요! 대부분의 경로는 자동으로 잡힙니다.</span></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[RESTful API 구현해보기]]></title>
            <link>https://velog.io/@seonyong-dev/RESTful-API-%EA%B5%AC%ED%98%84%ED%95%B4%EB%B3%B4%EA%B8%B0</link>
            <guid>https://velog.io/@seonyong-dev/RESTful-API-%EA%B5%AC%ED%98%84%ED%95%B4%EB%B3%B4%EA%B8%B0</guid>
            <pubDate>Tue, 28 Apr 2026 07:49:09 GMT</pubDate>
            <description><![CDATA[<p>저번 포스트에선 REST에 대한 공부를 하고 왔는데요. 
이번 포스트에선 직접 코드를 작성해보며 실제 사용할 수 있도록 해볼거에요.</p>
<p>이전 프로젝트에 REST의 설계 원칙을 지키지 못한채 JSON 데이터 통신을 구현한 코드가 있어요. 이 코드를 RESTful 하게 설계해볼게요.
<span style="color:gray; font-size:16px;">(위와 같은 과도기적 상태인 코드가 나오게 된 상황을 말해보자면요. 모달팝업창을 이용해서 데이터를 수정해야하는데 수정을 위해 기존 데이터를 불러와야 하는 상황이었어요. 모달팝업창으로 수정해야하기 때문에 SSR방식의 model 객체는 사용할 수 없었어요. 그래서 고민 끝에 나온 방법이 순수한 데이터만 보내는 방식이었어요.)</span></p>
<blockquote>
<p> Backend(Java/Spring MVC) </p>
</blockquote>
<pre><code>// RESTful 하지 않은 기존 코드
@Controller
@RequestMapping(&quot;/teacher&quot;)
public class TeacherController {

    @RequestMapping(value = &quot;/subject/subject_update.do&quot;, method = RequestMethod.POST, produces = &quot;application/json; charset=UTF-8&quot;)
    @ResponseBody
    public String SubjectUpdate(int uno, int sno) {
        SubjectVO vo = teacherService.SubjectSearch(uno, sno);

        return ConvertUtil.toJson(vo);
    }
 }

// RESTful 하게 변환한 코드
@RestController
@RequestMapping(&quot;/subjects&quot;)
public class TeacherController {

    @GetMapping(&quot;/{sno}&quot;)
    public SubjectVO getSubject(@PathVariable int sno, @RequestParam int uno) {
        return teacherService.SubjectSearch(uno, sno);
    }
}</code></pre><p>위의 변환한 코드들을 순서대로 하나씩 뜯어볼게요!</p>
<ol>
<li><code>@Controller</code> -&gt; <code>@RestController</code>
: <code>@RestController</code>를 사용하면 <code>@ResponsBody</code>를 사용하지 않아도 돼요!<br></li>
<li><code>@RequestMapping(&quot;/teacher&quot;)</code> -&gt; <code>@RequestMapping(&quot;/subjects&quot;)</code>
: 기존 코드에서는 뷰까지 한번에 보내줘야하는데 다른 폴더에 같은 이름의 파일이 있어서 폴더로 구분을 해줘야 했어요. 하지만 RESTful 한 코드에서 서버는 데이터를 주기만 하는 역할이기 때문에 그럴필요가 없어요. 그리고 RESTful에서 서버는 많은 데이터를 갖고 있기 때문에 복수형으로 명시해줘야해요.<br></li>
<li><code>method</code>, <code>produces</code>, <code>charset</code>의 유무
: <code>method</code>는 이제 행동을 표시하는 ajax에서 표현해줄거에요. <code>produces</code>와 <code>charset</code>은 기존에 return type이 String으로 되어있기 때문에 브라우저가 어떤 형식인지 알 수 있도록 명시해준거예요. 
하지만 RESTful 한 코드에서는 객체를 보내면 maven의 jackson 라이브러리의 도움을 받아 JSON으로 변형해서 데이터를 &emsp;전송해요.<br></li>
<li><code>GetMapping(&quot;/{sno}&quot;)</code>
: 이전 포스트에 알려드린 &#39;HTTP Method&#39;를 용도에 따라 <code>Mapping</code> 앞에 작성해서 사용하면 돼요. () 안의 데이터는 URL 파라미터이RH <code>@PathVariable</code>로 사용할 수 있어요.</li>
</ol>
<blockquote>
<p>Frontend(JavaScript/AJAX)</p>
</blockquote>
<pre><code>// RESTful 하지 않은 기존 코드
function DoUpdate(sno, uno) {
    $.ajax({
        url: &quot;subject_update.do&quot;,
        type: &quot;post&quot;,
        dataType: &quot;json&quot;,
        data: {
            uno: uno,
            sno: sno
        },
        success: function(subject) {

        },
        error: function(xhr, status, error) {

        }
    });
}    

// RESTful 하게 변환한 코드
function DoUpdate(sno, uno) {
    $.ajax({
        url: `/subjects/${sno}?uno=${uno}`,
        type: &quot;GET&quot;,
        dataType: &quot;json&quot;,
        success: function(subject) {

        },
        error: function(xhr, status, error) {

        }
    });
}    </code></pre><p>위의 코드도 비교해서 설명해볼게요.</p>
<ol>
<li>url : <code>&quot;subject_update.do&quot;</code> -&gt; <code>`/subjects/${sno}?uno=${uno}`</code>
: type이 GET으로 바뀌었으니 형식에 맞게 data{}를 삭제하고 URL 파라미터와 쿼리 스트링 형식에 맞게 작성해주면 돼요. 
type에는 행동을 나타내는 HTTP Method를 의도에 맞게 작성하면 돼요.
그리고 큰따옴표가 백틱으로 바꼈죠? 자바스크립트에서는 템플릿 리터럴이라는 기능을 사용하는데 `(백틱)과 ${}(플레이스홀더)를 사용해서 적용해서 가독성을 증가시킬 수 있어요. 
(ex. 큰따옴표 사용 시 : &quot;/subject/&quot; + sno + &quot;?uno=&quot; + uno)</li>
</ol>
<h3>정리</h3>
RESTful 하지 않은 코드를 형식에 맞게 수정해봤는데 그 차이가 눈에 확연하죠? 눈에 보이니 그 필요성도 더 두드러지고요. 보시는 바와 같이 가독성이 증가하고 유지보수가 용이해집니다.

<blockquote>
<p>실제 구현(VS Code/Spring Boot)</p>
</blockquote>
<p><span style="color=gray">실제 구현을 위해 setting 하는 방법은  내용이 길어져서 따로 포스팅하겠습니다.</span></p>
<p><code>lombok</code>, <code>fetch</code>를 설명하기엔 길고 그냥 쓰기엔 혼선이 있을 것 같아 이것 또한 따로 포스팅하겠습니다.</p>
<h4>index.html</h4>
<image width="80%" src="https://velog.velcdn.com/images/seonyong-dev/post/64600b50-903a-4579-9e67-d10bea753d6b/image.jpg">
프론트엔드에서 버튼을 누르면 DoUpdate 함수가 동작하며 controller 파일의 url주소에 해당하는 메서드를 동작합니다. fetch를 사용하여 script 없이 가볍게 동작가능합니다.

<h4>TeacherController.java</h4>
<image width="100%" src="https://velog.velcdn.com/images/seonyong-dev/post/f3c52310-d0f7-42b5-8bb8-df6e53753041/image.jpg">
브라우저에서 GET 타입을 받아 해당하는 메서드가 동작합니다.

<h4>TeacherService.java</h4>
<image width="80%" src="https://velog.velcdn.com/images/seonyong-dev/post/2addfaff-8270-4112-a153-0c3650df3692/image.jpg">
테스트 용도이기 때문에 DB를 거치지 않고 가짜 데이터를 이용하여 VO 객체에 데이터를 담습니다.

<h4>SubjectVO.java</h4>
<image width="80%" src="https://velog.velcdn.com/images/seonyong-dev/post/2cbfaae9-6d1a-44c7-9fb0-86fc3654c518/image.jpg">
데이터를 담은 VO 객체 구성입니다. Lombok을 사용하여 더 간결하게 표현할 수 있습니다.

<h4>동작결과</h4>
<image src="https://velog.velcdn.com/images/seonyong-dev/post/02a67baa-38ff-4361-8f16-596b41d0c820/image.jpg">
  위에서 작성한 로직대로 구현되는 것을 볼 수 있습니다. 빨간색 동그라미의 Content-Type의 정보로 서버에서 JSON으로 데이터를 받은 것을 확인할 수 있습니다.]]></description>
        </item>
        <item>
            <title><![CDATA[REST(REpresentational State Transfer) 꼭 알아야 하는 설계 원칙]]></title>
            <link>https://velog.io/@seonyong-dev/RESTREpresentational-State-Transfer-%EA%BC%AD-%EC%95%8C%EC%95%84%EC%95%BC-%ED%95%98%EB%8A%94-%EC%84%A4%EA%B3%84-%EC%9B%90%EC%B9%99</link>
            <guid>https://velog.io/@seonyong-dev/RESTREpresentational-State-Transfer-%EA%BC%AD-%EC%95%8C%EC%95%84%EC%95%BC-%ED%95%98%EB%8A%94-%EC%84%A4%EA%B3%84-%EC%9B%90%EC%B9%99</guid>
            <pubDate>Sun, 26 Apr 2026 14:51:09 GMT</pubDate>
            <description><![CDATA[<p><strong>* 현 포스트에서는 REST에 대한 공부 내용만 담겨있습니다. 직접적인 코드 구현은 다음 포스트에 게시할 예정입니다.</strong></p>
<p>올해 1, 2월에 약 5주간의 기간동안 자바와 Spring MVC로 프로젝트를 했었는데 그때의 경험들을 잊기 전에 오늘은 자바와 관련한 공부 내용을 기록해보려고 해요.</p>
<p>프로젝트를 진행하면서 공부할때, RESTful API라는 용어를 많이 봤었어요. </p>
<p>첫 프로젝트에 자격증 공부를 병행할때라 그랬는지 당시에는 공부해도 이해가 잘 가지 않아서 나중에 다시 공부해야지 했던 개념이었어요.</p>
<p>이번에 공부해보니 프로젝트할 때 알고 사용했으면 더 편했을 것 같아서 아쉽더라고요!</p>
<blockquote>
<p><strong>REST란?</strong></p>
</blockquote>
<p>REST는 REpresentational State Transfer의 약자로, 풀어서 말하면 <strong>&quot;웹에 존재하는 모든 자원(이미지, 동영상, 데이터)에 고유한 이름을 부여하고, 이를 주고받는 규칙&quot;</strong>을 의미하고 이 규칙을 잘 지켜서 만든 API를 RESTful API라고 한대요.</p>
<p>사실 이렇게말해도 저도 처음엔 확 와닿지 않았는데, 저처럼 처음에 너무 막연하다 싶으신 분들은 <strong>&quot;웹 자원의 상태를 주고받는 규칙&quot;</strong> 정도로 생각하고 공부해보시면 조금이나마 쉽게 이해할 수 있지 않을까 생각해요.</p>
<p>이전 프로젝트에서 대부분의 구현을 SSR(Server Side Rendering)으로 했었는데 RESTful API 방식인 줄은 모르고 두 번정도 사용했던 경험이 있어요.
(모르고 썼던거라 규칙은 지키지 못했어요. 그런데 사용했다고 말한 것은 <strong>&quot;순수한 데이터(JSON)만 보내는 방식&quot;</strong>을 사용했기 때문이에요.)</p>
<blockquote>
<p><strong>REST의 핵심규칙</strong></p>
</blockquote>
<ol>
<li><p>자원(Resource)은 &#39;명사&#39;로 표현한다.
<span style="font-size:16px">예를 들자면 저는 프로젝트할 때, <code>@RequestMapping</code> value 값을 &quot;/subject_update.do&quot; 이렇게 줬었어요. 하지만 REST 에서는 &quot;/subjects&quot; 이런식으로 사용해야 해요.</span></p>
</li>
<li><p>행위는 &#39;HTTP Method&#39;로 표현한다.
<span style="font-size:16px">GET: 자원 조회 (Read)
POST: 자원 생성 (Create)
PUT/PATCH: 자원 전체/일부 수정 (Update)
DELETE: 자원 삭제 (Delete)</p>
</span>

</li>
</ol>
<p>저는 프로젝트를 전통적인 방식인 &#39;GET&#39;과 &#39;POST&#39; 두가지만 사용해서 2번 규칙을 처음 봤을때 헷갈렸었어요. &#39;그렇게 하지 않아도 돌아가는데?&#39; 이런생각을 하면서 말이에요.</p>
<p>그렇게 생각했던건 REST를 프로토콜로 착각했기때문이에요. 그러면 REST는 무엇이냐 하면 정석적인 표현은 <strong>&#39;아키텍처 스타일(Architectural Style)&#39;</strong>이라고 해요. </p>
<p>쉽게 말하면, <strong>&#39;글의 문법&#39;</strong> 같은거에요. 띄어쓰기나 맞춤법이 조금 틀려도 의미는 대충 통하지만 글이 길어지고 복잡해지면 작은 문법적 실수가 가독성을 해치고 글을 이해하는 데 불필요한 시간을 사용하게 만들죠?</p>
<p>이런 불필요한 시간을 방지해서 어떤 개발자가 봐도 직관적이고 유지보수하기 쉽게 만든 규칙이 REST에요.</p>
<blockquote>
<p><strong>REST를 많이 사용하는 이유</strong></p>
</blockquote>
<p>개발자들이 원래 사용하던 방식보다 더 가볍고 직관적인 소통 방식을 원했기때문도 있지만, 현재에는 모바일 앱, 웹 브라우저, 워치 등 다양한 클라이언트가 등장했기 때문이에요.</p>
<p>위에서 제가 RESTful API 방식을 썼다고 한 이유가 순수한 데이터(JSON)만 보내서라고 했었죠? 만약, 제가 프로젝트에서 사용한 서버와 화면이 강하게 결합되어 있는 SSR방식을 사용했다면 유지보수도 어렵고 데이터를 전달할 때 많이 무거웠을거에요. 하지만 데이터를 가진 서버를 하나두고 프론트엔드만 각각 따로 관리한다면 정말 편하겠죠?</p>
<blockquote>
<p><strong>REST 핵심 용어</strong>(위에서 언급하지 않은)</p>
</blockquote>
<ol>
<li><p>무상태성(Stateless)
<span style="font-size:16px">서버는 클라이언트가 누구인지, 이전에 무엇을 했는지 기억하지 않는 대신 토큰을 활용하는 경우가 많아요. 그로인해 서버의 확장성이 좋아져요.
&quot;토큰을 사용하지 않고 매번 정보를 보내면 똑같이 무상태성을 유지할 수 있는 것 아닌가?&quot; 라고 생각한다면 두 가지 문제점이 있어요.
&emsp;  1) 보안 : 아이디와 비밀번호는 민감한 정보인데 매번 서버에 전송한다면 위험 노출 
&emsp;&emsp;&emsp;&emsp;&emsp;&ensp;빈도가 너무 높아져요.
&emsp;  2) 성능 : 아이디와 비밀번호를 보내면 매번 DB에서 확인해야하기 때문에 서버에 큰 
&emsp;&emsp;&emsp;&emsp;&emsp;&ensp;부담이돼요.</p>
</span>
</li>
<li><p>멱등성(Idempotency)
<span style="font-size:16px">연산을 여러 번 수행해도 결과가 달라지지 않는 성질이에요.<br>
REST에서 주요 메서드들의 멱등성은 다음과 같아요 :
• 멱등한 메서드 : GET, PUT, DELETE (여러 번 요청해도 처음 요청 응답 후 서버의 상태가 
&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;동일하게 유지됩니다.)<br>
• 멱등하지 않은 메서드 : POST (요청할 때마다 새로운 데이터를 생성하므로 결과가
&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&emsp;&nbsp;달라집니다.)<br>
• 예외 : PATCH는 &#39;부분 수정&#39;을 담당하므로, 설계에 따라 다릅니다.
&emsp;&emsp;&emsp;&ensp;(예: +1 연산은 비멱등, 고정된 값으로 변경은 멱등）</span></p>
<br>
위 용어들을 제대로 이해하고 설계 단계부터 적용한다면, 예외 상황을 효과적으로 제어하고 유지보수가 쉬운 API를 구축하는데 도움이 될 것이라 생각해요.
<br><br>

</li>
</ol>
<p><span style="color:gray">다음 포스트에선 프로젝트에서 사용했던 코드를 REST를 적용해서 비교해보는 방법으로 포스팅할 예정이에요. 
다만, 이전 포스트에서 말씀드렸듯 노트북 사양이 낮아서 VS code에서 직접 구현해보는건 가능할지는 모르겠어요. 한번 방법을 찾아볼게요!</span></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[알고쓰면 편한 With 구문]]></title>
            <link>https://velog.io/@seonyong-dev/%EC%95%8C%EA%B3%A0%EC%93%B0%EB%A9%B4-%ED%8E%B8%ED%95%9C-With-%EA%B5%AC%EB%AC%B8</link>
            <guid>https://velog.io/@seonyong-dev/%EC%95%8C%EA%B3%A0%EC%93%B0%EB%A9%B4-%ED%8E%B8%ED%95%9C-With-%EA%B5%AC%EB%AC%B8</guid>
            <pubDate>Sun, 19 Apr 2026 16:13:21 GMT</pubDate>
            <description><![CDATA[<p>처음 프로젝트할때, DBManager라는 클래스를 만들어서 pymysql 라이브러리를 통해 DB에서 데이터를 가져왔었어요.</p>
<blockquote>
</blockquote>
<p>초기 DBManager 예시 <span style="color:gray; font-size:15px;"><em>(가독성을 위해 메서드 내용은 제외했습니다.)</em></span></p>
<blockquote>
<pre><code>import pymysql
</code></pre></blockquote>
<p>class DBManager :
    def <strong>init</strong>(self) :</p>
<blockquote>
<pre><code># DB연결
def DBOpen(self) :

# DB연결 종료
def DBClose(self):</code></pre></blockquote>
<pre><code>
위 코드 처럼 메서드를 만들면 DB에서 데이터를 꺼내올때마다 DBOpen();을 적어줘야하고 메모리 누수(Memory Leak) 방지하기 위해 DBClose(); 를 적어줘야하는 불편함이 있었어요.

이 불편함을 해결하기 위한 구문이 바로 with 라는 구문이에요! with 구문을 사용하기 위해서는 먼저, _**&#39;컨텍스트 매니저(context manager)&#39;**_에 대해 알아야해요!

컨텍스트 매니저란 &quot;작업 수행 전 setup과 작업 종료 후 teardown을 &#39;자동&#39;으로 처리하기 위해, `__enter__`와 `__exit__` 메서드를 구현한 컨텍스트 매니저 객체&quot;에요.
&lt;span style=&quot;color:gray; font-size:15px;&quot;&gt;(메서드 명에서 알 수 있듯이 `__enter__`에서 setup 이 실행되고 `__exit__`에서 teardown이 실행됩니다.)&lt;/span&gt;

with 구문이 바로 컨텍스트 매니저를 실행하는 문법이에요!
&gt; 
컨텍스트 관리 프로토콜(Context Management Protocol)을 구현한 클래스 
&gt;```
import pymysql
&gt;
class DBManager :
    def __init__(self) :
&gt;    
    # setup
    def __enter__(self) :
&gt;    
    # teardown
    def __exit__(self, exc_type, exc_val, traceback):</code></pre><p>먼저 DBManager에 <code>__enter__</code>, <code>__exit__</code> 메서드를 만들어줘야 합니다. 또한, exit 메서드를 보시면 매개변수가 3개가 더 늘어난 것을 알 수 있는데,
• exc_type  : 발생한 예외의 클래스 타입
• exc_val   : 발생한 예외의 객체
• traceback : 예외가 발생한 위치 정보가 담긴 traceback 객체
exit 메서드로 위 3개의 값이 들어오기 때문에 매개변수를 3개 더 작성하지 않으면 에러가 나면서 작동하지 않아요.</p>
<blockquote>
</blockquote>
<p>with 구문을 사용하는 DAO 클래스</p>
<pre><code>from [파일이름] import DBManager
&gt;
class testDAO :
    def test() :
        with DBManager() as dbms :            </code></pre><p>DAO 클래스안의 메서드안에 위 예시코드처럼 with 구문을 사용하면 됩니다.</p>
<p>이렇게 with 구문을 사용하면 정상적으로 코드가 끝나든 <strong>에러로 구문이 끝나든 알아서 teardown을 작동</strong>해주기 때문에 누락이나 오타로 인한 메모리 누수를 방지할 수 있어요!</p>
<p><span style="color:gray; font-size:15px;">+ 사용할 객체가 컨텍스트 관리 프로토콜을 따르는 객체인지 알고싶을때는 dir() 함수를 사용해서 <code>__enter__</code>, <code>__exit__</code> 함수가 있는지 확인하여 알 수 있습니다.</span></p>
<blockquote>
<p>테스트 스크립트 <span style="font-size:15px;">(정상 작동 시)</span></p>
</blockquote>
<div>
<img width="80%" src="https://velog.velcdn.com/images/seonyong-dev/post/c4a0a062-bd97-48ba-9a4a-236132837bdf/image.jpg" >
<img width="60%" src="https://velog.velcdn.com/images/seonyong-dev/post/73462674-0e27-4411-9051-e8ac7b294a28/image.jpg">
<img width="100%" src="https://velog.velcdn.com/images/seonyong-dev/post/d7c0b5cc-0c0b-4501-bc15-54010e6f8ad2/image.jpg">
</div>

<blockquote>
<p>테스트 스크립트 <span style="font-size:15px;">(에러 발생 시)</span></p>
</blockquote>
<div>
<img width="80%" src="https://velog.velcdn.com/images/seonyong-dev/post/082112aa-2ddb-4ccd-bc43-3966db2b6298/image.jpg">
<img width="60%" src="https://velog.velcdn.com/images/seonyong-dev/post/56403c0c-75c8-4346-9213-4cb15485c3ab/image.jpg" >
<img width="100%" src="https://velog.velcdn.com/images/seonyong-dev/post/835b7ddb-e442-4166-a8a6-bf89313c6982/image.jpg">
</div>

<p><span style="color:gray"><em>traceback 같은 경우 따로 에러체크를 하지 않았습니다. traceback은 위에서 설명드렸듯이 에러가 발생한 상세경로를 알려주기 때문에 정보량이 많고 대부분의 경우 필요로 하지 않기 때문에 제 경우에서도 사용하지 않았습니다.</em></span>
<br>
<span style="color:gray"><em>이번 공부를 하면서 DB Connection pool이란 것도 알게됐는데 이 다음 단계인 것 같더라고요? 다음에 시간내서 공부해볼까 합니다. :D</em></span></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[저사양 노트북으로 개발공부를 위한 Setting (파이썬)]]></title>
            <link>https://velog.io/@seonyong-dev/%EC%A0%80%EC%82%AC%EC%96%91-%EB%85%B8%ED%8A%B8%EB%B6%81%EC%9C%BC%EB%A1%9C-%EA%B0%9C%EB%B0%9C%EA%B3%B5%EB%B6%80%EB%A5%BC-%EC%9C%84%ED%95%9C-Setting-%ED%8C%8C%EC%9D%B4%EC%8D%AC</link>
            <guid>https://velog.io/@seonyong-dev/%EC%A0%80%EC%82%AC%EC%96%91-%EB%85%B8%ED%8A%B8%EB%B6%81%EC%9C%BC%EB%A1%9C-%EA%B0%9C%EB%B0%9C%EA%B3%B5%EB%B6%80%EB%A5%BC-%EC%9C%84%ED%95%9C-Setting-%ED%8C%8C%EC%9D%B4%EC%8D%AC</guid>
            <pubDate>Sat, 11 Apr 2026 17:51:57 GMT</pubDate>
            <description><![CDATA[<p>현재 파이썬으로 프로젝트를 진행중이라 한동안은 파이썬 관련 개발로그를 작성해보려고요.</p>
<p>프로젝트는 학원에서 작업하기 때문에 개발에는 큰 문제가 없었는데 집에와서 공부를 하려니 문제가 생겼어요.</p>
<p>제 노트북은 20년식 i3 LG그램 노트북이거든요. 간호대학 다닐때 샀던거라 개발을 하기엔 턱도 없는 사양이죠.</p>
<p>그렇다고 개발공부를 안 할순 없잖아요?! _<span style="color:gray"><del>(누가 말하길 어쩔 수 없다는 건 핑계고 최악의 상황에서도 그저 최선을 다할 뿐이라고..읍읍)</del></span>_ 개발자의 소양 중엔 검색을 잘하는 것도 있대요. 그래서 AI한테 물어보고 구글링을 해가며 방법을 찾아냈죠!!😁</p>
<p>파이썬으로 개발할때는 라이브러리를 많이 사용하는데 그 사용을 편리하게 도와주는게 아나콘다에요. 편리하게 설치해주고 여러 프로젝트를 진행할 때, 라이브러리간 버전 충돌을 막아줘요!<span style="color:gray">(자바를 공부하신분들은 &#39;메이븐&#39;같은 프로그램이라고 생각하시면 돼요.)</span></p>
<p>그런데 아나콘다는 많은 라이브러리를 갖고 있어서 이름처럼 거대한 용량을 갖고 있어요. 그래서 찾은게 &#39;미니콘다&#39;라는 프로그램이에요. 이름에서 알 수 있듯이 같은 회사에서 만든 프로그램이에요.</p>
<p><strong>&lt;miniconda 설치방법&gt;</strong>
<span style="color:gray">바쁘신분들을 위한 <a href="https://www.anaconda.com/download/success?reg=skipped">미니콘다 설치페이지(26.04.11기준)</a> -&gt; 밑에도 링크가 있어요!</span></p>
<p>미니콘다라고 구글링하시면
<img src="https://velog.velcdn.com/images/seonyong-dev/post/06c290b9-fe72-48e0-9843-6ce535ecf47e/image.jpg" alt="">
이런 화면이 나오는데 위해서 말했듯이 같은 회사이기 때문에 왼쪽 상단에 아나콘다라고 쓰여있지만 왼쪽 목록에 표시해놓은 곳을 보면 미니콘다를 설치할 수 있는 것을 볼 수 있어요.</p>
<p>목록을 보면 맨 앞에 쓰여있는 것은 운영체제라는 것을 알 수 있을거에요. 그럼 뒤에 graphical과 shell도 무엇인지 아시나요? 전 궁금해서 찾아봤어요.
• graphical : 우리가 평소 사용하는 next눌러서 사용하는 설치 창이에요.
• shell : 명령어 스크립트로 설치하는 방법이에요.</p>
<p>저는 아직 명령어 스크립트가 익숙치 않아서 graphical installer를 사용했어요.
위 사진에서 동그라미 부분 링크를 클릭하면
<img src="https://velog.velcdn.com/images/seonyong-dev/post/6d787dae-bc8e-4a40-b6e7-9823269a8f8e/image.jpg" alt="">
위 캡쳐같이 페이지가 나와요. 처음엔 가입을 해야만 설치가 가능한가 했는데 동그라미 해놓은 하이퍼텍스트를 클릭하면 가입없이도 설치가 가능해요!
혹시 귀찮은 분들을 위해 링크 남겨드릴게요
<a href="https://www.anaconda.com/download/success?reg=skipped">미니콘다 설치페이지(26.04.11기준)</a></p>
<p>위의 하이퍼텍스트나 제가 올려놓은 링크로 가시면
<img src="https://velog.velcdn.com/images/seonyong-dev/post/78842bdf-c549-4e8a-95ab-f99cd10f5538/image.jpg" alt="">
위와 같은 페이지가 나오는데 노란색 동그라미안에 내 컴퓨터의 OS가 맞는지 확인하고 설치 버튼을 눌러주면 돼요. 왼쪽은 아나콘다고 오른쪽이 미니콘다니까, 오른쪽을 설치링크를 클릭해야해요.</p>
<p><img src="https://velog.velcdn.com/images/seonyong-dev/post/0d44ec43-c1a2-4059-8e7d-a0a0b3b69ebc/image.jpg
" width="50%">
링크를 클릭해서 설치파일을 받아서 실행하면 위 창이 나와요.<span style="color:gray"><em>(이게 위에서 말한 graphical installer에요! 직접 창을 보니까 왜 graphical인지 알겠죠?)</span></em>
이제 동그라미 해놓은 &#39;next&#39; 버튼 눌러주고 다음창에서 &#39;I agree&#39; 버튼 눌러주면</p>
<p><img src="https://velog.velcdn.com/images/seonyong-dev/post/896390bf-f9bc-4373-9019-ee4aaeebcb54/image.jpg
" width="50%">
이 창이 나오는데 &#39;just me&#39;하시면 돼요._<span style="color:gray">(관리자 권한과 관련된 설정이에요)</span>_</p>
<p><img src="https://velog.velcdn.com/images/seonyong-dev/post/3ca9b2d0-729b-4997-a916-b21e2da3846e/image.jpg"
 width="50%">
 다음 창인데 저장 폴더 경로는 그대로 하시는 것을 추천드려요!_<span style="color:gray">(기본 경로는 현재 로그인한 사용자가 자유롭게 읽고 쓸 수 있는 권한을 가진 폴더이면서 연동할 IDE가 알아서 잘 찾을 수 있다고 하더라고요!)</span>_ 혹시 사용자 이름이 한글이라서 경로에 한글이 있다면 변경하는 것을 추천드릴게요. 경로에 한글이나 공백이 있으면 오류를 일으킬 수 있대요.
<img src="https://velog.velcdn.com/images/seonyong-dev/post/3b8f2cc9-74cb-4a31-8115-f426841d0bea/image.jpg" width="50%">
여기선 제가 체크한대로 설치하시면돼요! 각 항목에 대한 설명도 적어놓을게요.
• Create shortcuts : 시작 메뉴에서 &#39;Anaconda Prompt&#39; 등을 찾기 쉽게 해줘요.</p>
<p>• Add installation to my PATH environment variable : 화면에도 &#39;NOT recommended&#39;라고 되어있는데요. 이걸 체크하면 cmd와 충돌이 날 수 있어요.</p>
<p>• Register Miniconda3 as my default Python 3.13 : 이 옵션을 체크하면 IDE에서 별다른 설정 없이도 설치된 파이썬을 바로 인식할 수 있어요.</p>
<p>• Clear the package cache upon completion : 설치 후 불필요한 임시 파일을 삭제해 용량을 확보해줘요.</p>
<p>▶ 미니콘다가 잘 설치 되었는지 확인하는 방법도 알려드릴게요.</p>
<p><strong>window 시작메뉴</strong>에 <strong>&#39;anaconda prompt&#39;</strong> 또는 &#39;miniconda prompt&#39;를 입력하면 된다고 하는데 저는 &#39;anaconda prompt&#39;로 설치되어 있어요.
<img src="https://velog.velcdn.com/images/seonyong-dev/post/3678ca87-dcfa-430b-b99c-c7e7c259a674/image.jpg
" width="50%">
이렇게 prompt 창에 <strong>&#39;conda --version&#39;</strong>을 입력하고 아랫줄 처럼 결과를 얻으면 잘 설치가 된거에요!</p>
<p>드디어 미니콘다 설치가 끝났어요! 다음은 IDE를 설치할거에요. 지금까지 저는 개발할때 STS3(eclipse)나 spyder를 사용했는데요. </p>
<p>현직에서는 확장성이나 빠른 실행속도 등의 장점이 있어서 VS Code를 많이 사용한다고 한대요. 그래서 익숙해질 겸 VS code를 사용할거에요.</p>
<p><strong>&lt;VS Code 설치방법&gt;</strong>
VS Code는 검색해서 들어가면 바로 다운로드 할 수 있는 버튼이 나와요.
<a href="https://code.visualstudio.com/">VS Code홈페이지(26.04.11)</a>
<img src="https://velog.velcdn.com/images/seonyong-dev/post/bbcf8ce1-4669-4ad0-b73a-573f792b2e75/image.jpg" width="50%">
다운받아서 실행파일을 열어서 약관동의하면 위의 창처럼 나오고요. 제가 체크한대로 하시면 돼요!
• Code(으)로 열기&quot; 작업을 Windows 탐색기 파일의 상황에 맞는 메뉴에 추가 : 
 &emsp;파일을 마우스 오른쪽 버튼으로 클릭해서 바로 VS Code로 열 수 있어요.</p>
<p>• &quot;Code(으)로 열기&quot; 작업을 Windows 탐색기 디렉터리의 상황에 맞는 메뉴에 추가 : 
 &emsp;폴더를 마우스 오른쪽 버튼으로 클릭해 해당 폴더 전체를 프로젝트로
 &emsp;바로 열 수 있어요.</p>
<p>• Code을(를) 지원되는 파일 형식에 대한 편집기로 등록합니다</p>
<p>• PATH에 추가 : 터미널에서 code라고 입력해서 실행할 수 있게 해줘요
<span style="color:gray">&emsp;(터미널은 cmd창 처럼 명령어를 입력하고 결과를 보는 텍스트 창을 말해요)</span></p>
<p>설치는 모두 끝났어요! 이제 미니콘다와 VS Code를 연동하는 일만 남았어요.</p>
<p><strong>&lt;미니콘다-VS Code 연동방법&gt;</strong>
<img src="https://velog.velcdn.com/images/seonyong-dev/post/aab1f2d0-94fe-42ad-bf11-49b62fab3509/image.jpg" width="80%"></p>
<p>연동하기 전에 파이썬 확장 프로그램 부터 설치해볼게요. 파란색 동그라미 친 버튼(Extension 버튼)을 클릭하거나 ctrl+shift+x 단축키를 입력하면 빨간색 창이 뜨는데요. 여기에서 &#39;python&#39;이라고만 써있는 프로그램을 설치하면 됩니다.</p>
<p>이제 진짜 연동을 해볼게요. 상단 메뉴 <strong>view</strong>에서 <strong>&#39;command pallete...&#39;</strong>를 찾거나 <strong>&#39;ctrl+shift+p&#39;</strong> 단축키를 입력해보세요.
<img src="https://velog.velcdn.com/images/seonyong-dev/post/ba98d256-d103-4127-951f-7cb7115cbf8b/image.jpg" width="80%">
그럼 위 사진 처럼 &#39;&amp;gt&#39; 이 생기면 &#39;Python:Select Interpreter&#39;를 입력해주면 됩니다. 
<img src="https://velog.velcdn.com/images/seonyong-dev/post/5893d1fc-61ac-49ff-9019-2656c7fe476c/image.jpg" width="80%">
그러면 위 사진 비슷하게 나올텐데 저는 이미 설치를 해놓아서 조금 다를 수 있어요. 노랑색 표시해놓은 것을 클릭하면 끝입니다!<span style="color:gray">(사실 뭘 클릭했는지는 잘 기억안나지만 확실한건 <strong>&#39;~\miniconda3\python.exe&#39;</strong> 이걸 보고 선택했었어요)</span></p>
<p>하지만 여기서 끝나면 안되겠죠? 잘 됐는지 확인해야 합니다!</p>
<p>▶ 연동이 잘 됐는지 확인하는 방법
<img src="https://velog.velcdn.com/images/seonyong-dev/post/14cdf2ad-5ce7-4007-8d9a-5c04e25e58dc/image.jpg" alt="">
간단한 .py 파일을 생성해서 run(초록색 원) 해보시면 <strong>아래 터미널창에 파란색원</strong> 처럼 나오거나 <strong>붉은원 보시면 &#39;(base)&#39;라고 쓰여있는 것</strong>을 보실 수 있어요. 이렇게 나오면 잘 연결됐다는 증거에요!
아니면 아래 코드를 입력해서도 확인할 수 있어요!</p>
<pre><code>import sys
print(&quot;현재 사용 중인 파이썬 경로:&quot;)
print(sys.executable)</code></pre><p>이상으로 저사양 노트북도 파이썬 개발공부를 할 수 있는 setting 법을 마무리할게요!
<br>
_<span style="color:gray">setting하는게 로직 설계하는 것보다 더 어렵게 느껴지네요🥲 
제가 헷갈리고 궁금했던 것들을 다 적다보니 글이 꽤 길어졌어요. 나중엔 아는 것이 많아져서 핵심만 쏙쏙 적을 수 있으면 좋겠어요!🤭
혹시나 글 내용이 줄어든다면 초심을 잃었다기보다 성장했구나 생각해주시면 감사하겠습니다😉</span>_</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[간호사에서 개발자로, 성취감을 찾아 떠난 여정]]></title>
            <link>https://velog.io/@seonyong-dev/%EA%B0%84%ED%98%B8%EC%82%AC%EC%97%90%EC%84%9C-%EA%B0%9C%EB%B0%9C%EC%9E%90%EB%A1%9C-%EC%84%B1%EC%B7%A8%EA%B0%90%EC%9D%84-%EC%B0%BE%EC%95%84-%EB%96%A0%EB%82%9C-%EC%97%AC%EC%A0%95</link>
            <guid>https://velog.io/@seonyong-dev/%EA%B0%84%ED%98%B8%EC%82%AC%EC%97%90%EC%84%9C-%EA%B0%9C%EB%B0%9C%EC%9E%90%EB%A1%9C-%EC%84%B1%EC%B7%A8%EA%B0%90%EC%9D%84-%EC%B0%BE%EC%95%84-%EB%96%A0%EB%82%9C-%EC%97%AC%EC%A0%95</guid>
            <pubDate>Sat, 11 Apr 2026 11:58:45 GMT</pubDate>
            <description><![CDATA[<p>개발하면서 배운 것, 공부한 것들을 이곳에 기록해보려해요.
저만의 업무노트 같은 것이랄까요? :)</p>
<p>현재 이미 끝난 프로젝트도 있고 진행중인 프로젝트도 있는데 다시 공부할 겸 기억을 더듬어 가면서 기록해보려고요! 먼저는 지금 진행중인 프로젝트 위주로 올리고 끝나면 이전 프로젝트도 올릴꺼에요.</p>
<p>지금은 하고 있는게 이것저것 많아서 당장은 한 주 한 개이상을 목표로 하고 있어요.</p>
<p>이제 저를 소개하자면 저는 원래 간호학을 전공한 간호사였어요. 간호사로 1년 넘게 근무하면서 보람도 느끼고 교대근무도 적응했지만 종종 현재의 삶에 만족하지 못했어요. </p>
<p>그래서 간호업무를 하는 수개월동안 고용24에 있는 적성검사도 해보고 나란 사람에 대해 고민하는 시간을 가졌었어요. </p>
<p>그 시간 동안 알게 된 저란 사람은요.
*<em>1. 성취감을 정말 좋아하고요.
2. 목표가 있어야 하지만 목표를 이루기 위한 과정이 정해진 건 싫어요.
3. 책임감이 강하고요. 시작한 일은 끝을 보려해요.
4. 걱정과 의심이 많아요.
*</em>
그래서 개발자란 직업이 너무 매력적이었어요. 하지만 저는 걱정이 많은 사람이라 확신을 갖기 위해 도서관에서 책을 빌리거나 영상을 찾아보면서 파이썬 공부를 했었어요. 그 시간이 확신을 갖게 해줬고 정말 친한 지인이 현직 개발자를 연결해줘서 용기를 얻었어요.</p>
<p>제게 있어 개발은요,
<strong>확실한 성취감이 저를 움직이게 하고요. 
결과에는 정답이 있지만 과정에는 정답이 없는 것이 제게 자유를 느끼게 해줬어요.</strong>
그리고 제 성향인
<strong>약간의 완벽주의 성향이 로직을 작성할 때 몰입하게 해주고요.
걱정과 의심이 많아서 유지보수를 위한 코드를 작성하게 하고 오류코드를 찾는데 도움이 됐어요.</strong> <del>(물론, 허점 투성이지만요..)</del></p>
<p>정말 하고 싶은 일인 만큼 앞으로도 계속 열심히 해볼게요! :)</p>
<p><strong>Certificates &amp; Background</strong>
Development
정보처리기사 (2025.12)| 한국산업인력공단
SQLD (SQL 개발자) (2026.03) | 한국데이터산업진흥원
ADsP (데이터분석 준전문가) (2026.03) | 한국데이터산업진흥원</p>
<p>Domain Expertise
간호사 면허 (2023.02) | 보건복지부</p>
]]></description>
        </item>
    </channel>
</rss>