<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>hyunah_parc.log</title>
        <link>https://velog.io/</link>
        <description></description>
        <lastBuildDate>Tue, 03 Mar 2026 10:14:02 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>hyunah_parc.log</title>
            <url>https://velog.velcdn.com/images/hyunah_parc/profile/9718f012-8de5-41e5-9dcd-b1ba30c99644/image.jpeg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. hyunah_parc.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/hyunah_parc" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[SUPINFO][Linux] Bash Scripting]]></title>
            <link>https://velog.io/@hyunah_parc/Linux-Bash-Scripting</link>
            <guid>https://velog.io/@hyunah_parc/Linux-Bash-Scripting</guid>
            <pubDate>Tue, 03 Mar 2026 10:14:02 GMT</pubDate>
            <description><![CDATA[<h2 id="1---archive">1 - Archive</h2>
<blockquote>
</blockquote>
<p>Write a script that creates a tarball of a given user home directory. The script can take the username as argument; otherwise, the script will prompt for it. The archive will be stored in /tmp with the date in the file name. </p>
<p>요구사항 정리:</p>
<ul>
<li>사용자 이름을 인자로 받기</li>
<li>인자가 없으면 프롬프트로 입력받기</li>
<li>해당 사용자의 홈 디렉토리를 tar로 압축</li>
<li>/tmp 에 저장</li>
<li>파일 이름에 날짜 포함</li>
</ul>
<h3 id="1-archivesh-파일-생성">1) archive.sh 파일 생성</h3>
<pre><code class="language-bash">$ nano archive.sh</code></pre>
<pre><code class="language-bash">#!/bin/bash

# 1. 사용자 이름이 인자로 들어왔는지 확인
if [ -n &quot;$1&quot; ]; then
    USERNAME=&quot;$1&quot;
else
    read -p &quot;Enter username: &quot; USERNAME
fi

# 2. 홈 디렉토리 경로 설정
HOME_DIR=&quot;/home/$USERNAME&quot;

# 3. 사용자가 존재하는지 확인
if [ ! -d &quot;$HOME_DIR&quot; ]; then
    echo &quot;Error: User home directory does not exist.&quot;
    exit 1
fi

# 4. 날짜 생성 (YYYYMMDD 형식)
DATE=$(date +%Y%m%d)

# 5. 아카이브 파일 이름 설정
ARCHIVE_NAME=&quot;/tmp/${USERNAME}_home_${DATE}.tar.gz&quot;

# 6. tarball 생성
tar -czf &quot;$ARCHIVE_NAME&quot; &quot;$HOME_DIR&quot;

# 7. 완료 메시지
echo &quot;Archive created: $ARCHIVE_NAME&quot;</code></pre>
<h3 id="2-실행-권한-주기">2) 실행 권한 주기</h3>
<pre><code class="language-bash">$ chmod +x archive.sh</code></pre>
<h3 id="3-인자없이-실행">3) 인자없이 실행</h3>
<pre><code class="language-bash">$ ./archive.sh</code></pre>
<p>이름 입력</p>
<h3 id="4-결과">4) 결과</h3>
<pre><code class="language-bash">hyunah@hyunah-VMware-Virtual-Platform:~$ ./archive.sh
Enter username: hyunah
tar: Removing leading `/&#39; from member names
tar: /home/hyunah/.cache/ibus/dbus-WE4vOIwr: socket ignored
tar: /home/hyunah/.cache/ibus/dbus-YBwpaXcG: socket ignored
tar: /home/hyunah/.cache/ibus/dbus-0DB5uqCN: socket ignored
tar: /home/hyunah/.cache/ibus/dbus-rMCaQ34F: socket ignored
Archive created: /tmp/hyunah_home_20260303.tar.gz</code></pre>
<h2 id="2---tbbt">2 - TBBT</h2>
<blockquote>
<p>You have just ripped off a DVD of the first season of one of your favorite TV shows. The files are named as &quot;Chapter XX.avi&quot;. You want to get all these files renamed as &quot;XX - Episode name.avi&quot;. Write a script that reads episode names from a eplist.txt file (one episode per line, sorted chronologically):
Pilot
The Big Bran Hypothesis
The Fuzzy Boots Corollary
The Luminous Fish Effect
The Hamburger Postulate
The Middle-Earth Paradigm
The Dumpling Paradox
The Grasshopper Experiment
The Cooper-Hofstadter Polarization
The Loobenfeld Decay
The Pancake Batter Anomaly
The Jerusalem Duality
The Bat Jar Conjecture
The Nerdvana Annihilation
The Pork Chop Indeterminacy
The Peanut Reaction
The Tangerine Factor
This file does not contain episode numbers, only titles. The script should compute new names for each file, show a renaming proposition and ask user for confirmation before actually renaming.</p>
</blockquote>
<p>요구사항 정리:</p>
<ul>
<li>현재 파일명: Chapter XX.avi</li>
<li>변경할 파일명: XX - Episode name.avi</li>
<li>에피소드 제목은 eplist.txt에서 한 줄씩 읽음</li>
<li>실제 변경 전에 미리 보여주고 사용자 확인 받기</li>
</ul>
<h3 id="1-eplisttxt-생성">1) eplist.txt 생성</h3>
<pre><code class="language-bash">nano eplist.txt</code></pre>
<pre><code>Pilot
The Big Bran Hypothesis
The Fuzzy Boots Corollary
The Luminous Fish Effect
The Hamburger Postulate
The Middle-Earth Paradigm
The Dumpling Paradox
The Grasshopper Experiment
The Cooper-Hofstadter Polarization
The Loobenfeld Decay
The Pancake Batter Anomaly
The Jerusalem Duality
The Bat Jar Conjecture
The Nerdvana Annihilation
The Pork Chop Indeterminacy
The Peanut Reaction
The Tangerine Factor</code></pre><p>2) rename.sh 생성</p>
<pre><code class="language-bash">nano rename.sh</code></pre>
<pre><code class="language-bash">#!/bin/bash

# TBBT Episode Rename Script
# 기존 파일이 없어도 제안 출력 가능

EPFILE=&quot;eplist.txt&quot;

# 1. eplist.txt 존재 확인
if [ ! -f &quot;$EPFILE&quot; ]; then
    echo &quot;Error: $EPFILE not found.&quot;
    exit 1
fi

# 2. eplist.txt 라인 수
EP_COUNT=$(wc -l &lt; &quot;$EPFILE&quot;)

echo &quot;Proposed renaming:&quot;
echo &quot;-------------------&quot;

i=1
declare -a OLD_NAMES
declare -a NEW_NAMES

# 3. 제안 계산 및 출력 (파일 없어도)
while IFS= read -r TITLE; do
    OLD_NAME=$(printf &quot;Chapter %02d.avi&quot; &quot;$i&quot;)
    NEW_NAME=$(printf &quot;%02d - %s.avi&quot; &quot;$i&quot; &quot;$TITLE&quot;)

    echo &quot;$OLD_NAME  -&gt;  $NEW_NAME&quot;

    # 실제 rename를 위해 배열에 저장
    OLD_NAMES+=(&quot;$OLD_NAME&quot;)
    NEW_NAMES+=(&quot;$NEW_NAME&quot;)

    ((i++))
done &lt; &quot;$EPFILE&quot;

echo
read -p &quot;Proceed with renaming if files exist? (y/n): &quot; ANSWER

if [[ &quot;$ANSWER&quot; =~ ^[Yy]$ ]]; then
    # 실제 파일이 있을 경우만 rename
    for idx in &quot;${!OLD_NAMES[@]}&quot;; do
        if [ -f &quot;${OLD_NAMES[$idx]}&quot; ]; then
            mv &quot;${OLD_NAMES[$idx]}&quot; &quot;${NEW_NAMES[$idx]}&quot;
        fi
    done
    echo &quot;Renaming completed for existing files.&quot;
else
    echo &quot;Operation cancelled.&quot;
fi</code></pre>
<h3 id="3-실행-권한-주기">3) 실행 권한 주기</h3>
<pre><code class="language-bash">$ chmod +x rename.sh</code></pre>
<h3 id="4-실행">4) 실행</h3>
<pre><code class="language-bash">$ ./rename.sh</code></pre>
<h3 id="5-결과">5) 결과</h3>
<pre><code class="language-bash">hyunah@hyunah-VMware-Virtual-Platform:~$ ./rename.sh
Proposed renaming:
-------------------
Chapter 01.avi  -&gt;  01 - Pilot.avi
Chapter 02.avi  -&gt;  02 - The Big Bran Hypothesis.avi
Chapter 03.avi  -&gt;  03 - The Fuzzy Boots Corollary.avi
Chapter 04.avi  -&gt;  04 - The Luminous Fish Effect.avi
Chapter 05.avi  -&gt;  05 - The Hamburger Postulate.avi
Chapter 06.avi  -&gt;  06 - The Middle-Earth Paradigm.avi
Chapter 07.avi  -&gt;  07 - The Dumpling Paradox.avi
Chapter 08.avi  -&gt;  08 - The Grasshopper Experiment.avi
Chapter 09.avi  -&gt;  09 - The Cooper-Hofstadter Polarization.avi
Chapter 10.avi  -&gt;  10 - The Loobenfeld Decay.avi
Chapter 11.avi  -&gt;  11 - The Pancake Batter Anomaly.avi
Chapter 12.avi  -&gt;  12 - The Jerusalem Duality.avi
Chapter 13.avi  -&gt;  13 - The Bat Jar Conjecture.avi
Chapter 14.avi  -&gt;  14 - The Nerdvana Annihilation.avi
Chapter 15.avi  -&gt;  15 - The Pork Chop Indeterminacy.avi
Chapter 16.avi  -&gt;  16 - The Peanut Reaction.avi
Chapter 17.avi  -&gt;  17 - The Tangerine Factor.avi

Proceed with renaming if files exist? (y/n): y
Renaming completed for existing files.</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Supinfo][Docker] Labs 3.2 - 도커로 Spring Boot 애플리케이션 컨테이너화 하기]]></title>
            <link>https://velog.io/@hyunah_parc/SupinfoDocker-Spring-Boot-%EC%95%A0%ED%94%8C%EB%A6%AC%EC%BC%80%EC%9D%B4%EC%85%98-%EB%8F%84%EC%BB%A4-%EC%BB%A8%ED%85%8C%EC%9D%B4%EB%84%88%EB%A1%9C-%EB%B0%B0%ED%8F%AC%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@hyunah_parc/SupinfoDocker-Spring-Boot-%EC%95%A0%ED%94%8C%EB%A6%AC%EC%BC%80%EC%9D%B4%EC%85%98-%EB%8F%84%EC%BB%A4-%EC%BB%A8%ED%85%8C%EC%9D%B4%EB%84%88%EB%A1%9C-%EB%B0%B0%ED%8F%AC%ED%95%98%EA%B8%B0</guid>
            <pubDate>Wed, 17 Dec 2025 23:59:34 GMT</pubDate>
            <description><![CDATA[<h1 id="spring-boot-앱-도커-컨테이너로-배포하기-conteneuriser-une-application-spring-boot">Spring Boot 앱 도커 컨테이너로 배포하기 (Conteneuriser une application Spring Boot)</h1>
<h2 id="1-스프링-부트-프로젝트-configuration">1. 스프링 부트 프로젝트 configuration</h2>
<p>Se rendre sur <a href="https://start.spring.io">https://start.spring.io</a> et configurer le projet à générer de la manière suivante :
<a href="https://start.spring.io%EC%97%90">https://start.spring.io에</a> 들어가서 프로젝트 설정을 해준다</p>
<pre><code>- Project : Gradle - Groovy
- Language : Java
- Spring Boot : dernière version 3.x.x stable
- Packaging : jar
- Java : au plus la version du JDK installé sur votre machine
- Dépendances : &quot;Spring Web&quot;</code></pre><ul>
<li>java는 본인 버전 선택해주기</li>
<li>Generate, 다운로드 후 압축 풀기</li>
</ul>
<h2 id="2-스프링-부트-앱-만들기">2. 스프링 부트 앱 만들기</h2>
<h3 id="1-lab32-springboot-폴더-생성">1) lab3.2-springboot 폴더 생성</h3>
<h3 id="2-1에서-만든-demo-폴더-붙여넣기">2) 1.에서 만든 demo 폴더 붙여넣기</h3>
<h3 id="3-applicationjava-있는-곳에-hellocontrollerjava-파일-만들기">3) Application.java 있는 곳에 HelloController.java 파일 만들기</h3>
<pre><code class="language-java">package com.example.demo;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {

    @GetMapping(&quot;/&quot;)
    public String hello() {
        return &quot;Hello from Spring Boot 1 !&quot;;
    }
}</code></pre>
<h2 id="3-터미널-열어서-빌드하기">3. 터미널 열어서 빌드하기</h2>
<pre><code>.\gradlew.bat clean bootJar        </code></pre><p><img src="https://velog.velcdn.com/images/hyunah_parc/post/ac46bc1c-fef9-4d36-aca0-2aaf972e7133/image.png" alt=""></p>
<ul>
<li>빌드가 성공적으로 됐으면 build/libs에 .jar 파일이 생긴다</li>
</ul>
<h2 id="4-dockerfile-만들기">4. Dockerfile 만들기</h2>
<pre><code class="language-dockerfile">FROM amazoncorretto:21
WORKDIR /app
COPY build/libs/demo-0.0.1-SNAPSHOT.jar app.jar
EXPOSE 8080
ENTRYPOINT [&quot;java&quot;, &quot;-jar&quot;, &quot;app.jar&quot;]</code></pre>
<h2 id="5-도커-이미지-만들기">5. 도커 이미지 만들기</h2>
<pre><code>docker build -t lab3.2-springboot .</code></pre><p><img src="https://velog.velcdn.com/images/hyunah_parc/post/46ec4aaf-6678-4056-b6c0-33fd230c2edb/image.png" alt=""></p>
<h2 id="6-도커-컨테이너-실행하기">6. 도커 컨테이너 실행하기</h2>
<pre><code>docker run -p 8080:8080 --name lab3.2-springboot lab3.2-springboot</code></pre><p><img src="https://velog.velcdn.com/images/hyunah_parc/post/465788dc-2b6e-4e54-bcc3-abd7f041ba0b/image.png" alt=""></p>
<ul>
<li>docker desktop에서 돌아가는 거 확인
<img src="https://velog.velcdn.com/images/hyunah_parc/post/cefebc73-e4b9-448c-a2ae-688d2cac0d87/image.png" alt=""></li>
</ul>
<h2 id="7-localhost8080-확인">7. localhost:8080 확인</h2>
<p>Hello from Spring Boot 1 ! 뜨면 정상 작동되는 것작동되는 것
<img src="https://velog.velcdn.com/images/hyunah_parc/post/1c84d194-17be-43e0-a6d9-dfa5ae221f03/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Supinfo][Docker] Labs 3.1 - 도커로 Express 애플리케이션 컨테이너화하기]]></title>
            <link>https://velog.io/@hyunah_parc/SupinfoDocker-Labs-3.1-Express-%EC%95%A0%ED%94%8C%EB%A6%AC%EC%BC%80%EC%9D%B4%EC%85%98-%EC%BB%A8%ED%85%8C%EC%9D%B4%EB%84%88%ED%99%94%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@hyunah_parc/SupinfoDocker-Labs-3.1-Express-%EC%95%A0%ED%94%8C%EB%A6%AC%EC%BC%80%EC%9D%B4%EC%85%98-%EC%BB%A8%ED%85%8C%EC%9D%B4%EB%84%88%ED%99%94%ED%95%98%EA%B8%B0</guid>
            <pubDate>Wed, 17 Dec 2025 20:30:18 GMT</pubDate>
            <description><![CDATA[<h1 id="express-애플리케이션-컨테이너화하기-conteneuriser-une-application-express">Express 애플리케이션 컨테이너화하기 (Conteneuriser une application Express)</h1>
<p><img src="https://velog.velcdn.com/images/hyunah_parc/post/9d472a38-a6be-4740-bb22-239eee084fa7/image.png" alt=""></p>
<h2 id="1-express-앱-만들기">1. Express 앱 만들기</h2>
<h3 id="1-lab31-express-폴더-생성-vs-code-사용">1) lab3.1-express 폴더 생성 (VS Code 사용)</h3>
<h3 id="2-터미널에서-express-ulid-설치">2) 터미널에서 express, ulid 설치</h3>
<pre><code>npm install express ulid</code></pre><p><img src="https://velog.velcdn.com/images/hyunah_parc/post/c9fb2128-61e6-4b9e-adcf-3a95c5b69e16/image.png" alt=""></p>
<h3 id="3-serverjs-파일-생성">3) server.js 파일 생성</h3>
<pre><code class="language-javascript">const express = require(&#39;express&#39;);
const { ulid } = require(&#39;ulid&#39;);

const app = express();

// JSON 파싱을 위해 필요
app.use(express.json());

// 기본 라우트
app.get(&#39;/&#39;, (req, res) =&gt; {
  res.send(&#39;Hello, Express!&#39;);
});

// JSON 반환 라우트
app.get(&#39;/api/data&#39;, (req, res) =&gt; {
  res.json({
    message: &#39;JSON data&#39;,
    id: ulid()
  });
});

// JSON 받는 라우트
app.post(&#39;/api/echo&#39;, (req, res) =&gt; {
  const receivedData = req.body;
  res.json({
    message: &#39;Received Data&#39;,
    data: receivedData
  });
});

app.listen(3000, () =&gt; {
  console.log(&#39;Server on http://localhost:3000&#39;);
});</code></pre>
<h2 id="2-로컬에서-express-앱-작동-확인">2. 로컬에서 express 앱 작동 확인</h2>
<h3 id="1-터미널에서-node-serverjs로-실행">1) 터미널에서 node server.js로 실행</h3>
<p><img src="https://velog.velcdn.com/images/hyunah_parc/post/04b4512b-761d-47f5-ab1d-331cb7544fc0/image.png" alt=""></p>
<h3 id="2-get-localhost3000-get-localhost3000apidata-확인">2) (GET) localhost:3000, (GET) localhost:3000/api/data 확인</h3>
<p><img src="https://velog.velcdn.com/images/hyunah_parc/post/ba17ff23-96fd-4eb5-bd30-db10cb3e9aac/image.png" alt="">
<img src="https://velog.velcdn.com/images/hyunah_parc/post/e0792216-d100-448d-af7c-c5d04d0a545a/image.png" alt=""></p>
<h3 id="3-post-localhost3000apiecho-확인-postman-사용">3) (POST) localhost:3000/api/echo 확인 (Postman 사용)</h3>
<p><img src="https://velog.velcdn.com/images/hyunah_parc/post/e49fdb17-78f2-4253-916c-5870a4990aef/image.png" alt=""></p>
<h2 id="3-dockerfile-작성">3. Dockerfile 작성</h2>
<p>(컨테이너로 만들기 위한 문서)</p>
<pre><code class="language-dockerfile">FROM node:20-alpine
WORKDIR /app
COPY . .
# os에 있는 기본 shell 사용함
# RUN npm install
RUN [&quot;npm&quot;, &quot;install&quot;]
EXPOSE 3000
CMD [&quot;node&quot;, &quot;server.js&quot;]</code></pre>
<h2 id="4-docker-이미지-빌드">4. Docker 이미지 빌드</h2>
<pre><code>docker build -t lab3.1-express .</code></pre><p><img src="https://velog.velcdn.com/images/hyunah_parc/post/9882713a-680e-48df-a2ad-ca25f57ca165/image.png" alt=""></p>
<h2 id="5-컨테이너-실행">5. 컨테이너 실행</h2>
<pre><code>docker run --name lab3.1-express -p 3000:3000 lab3.1-express</code></pre><p><img src="https://velog.velcdn.com/images/hyunah_parc/post/ee2c2934-27e9-477c-9376-9c8e347af037/image.png" alt=""></p>
<h2 id="6-컨테이너에서-테스트">6. 컨테이너에서 테스트</h2>
<p>&quot;2. 로컬에서 express 앱 작동 확인&quot;과 똑같이 확인해주면 된다
로컬에서 작동하는 건지, 컨테이너에서 작동하는 건지 확인해보고 싶다면 컨테이너를 멈추고 테스트해보면 된다! </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Supinfo][Docker] Labs 2.3 - 도커로 Redis 컨테이너 설치하고 Node.js로 연동하기
]]></title>
            <link>https://velog.io/@hyunah_parc/docker-redis</link>
            <guid>https://velog.io/@hyunah_parc/docker-redis</guid>
            <pubDate>Mon, 15 Dec 2025 15:25:04 GMT</pubDate>
            <description><![CDATA[<h2 id="1-docker-hub에서-redis-공식-이미지-pull-하기">1. Docker Hub에서 Redis 공식 이미지 pull 하기</h2>
<p>(Se rendre sur le Docker Hub et rechercher l&#39;image officielle Redis)
<img src="https://velog.velcdn.com/images/hyunah_parc/post/429352ee-d125-442f-8876-1135b9572d0b/image.png" alt=""></p>
<h2 id="2-받은-redis-이미지-run해서-redis-컨테이너-실행하기">2. 받은 Redis 이미지 Run해서 Redis 컨테이너 실행하기</h2>
<p>(Lancer un conteneur Redis nommé redis-db et qui publie le port 6379. Se renseigner sur les options de configuration disponibles via les variables d’environnement)</p>
<ul>
<li>컨테이너 이름 : redis-db</li>
<li>포트 : 6379</li>
</ul>
<pre><code>docker run -d --name redis-db -p 6379:6379 redis:latest</code></pre><p>간단한 비밀번호 추가 방법 👇</p>
<ul>
<li>Redis 공식 이미지는 환경변수로 비밀번호 설정을 지원하지 않음
대신 redis-server 실행 옵션으로 설정
개발/실습 환경에서 간단하게 보안 추가할 때 자주 사용<pre><code>docker run -d --name redis-db -p 6379:6379 redis:latest redis-server --requirepass 5763</code></pre><img src="https://velog.velcdn.com/images/hyunah_parc/post/f4d403fa-d247-4a81-81e8-bde465e0ad35/image.png" alt=""></li>
</ul>
<h2 id="3-javascriptnodejs로-redis-연결하기">3. JavaScript(Node.js)로 Redis 연결하기</h2>
<h3 id="1-lab23-node-app-redis-폴더-생성-vs-code-사용">1) lab2.3-node-app-redis 폴더 생성 (VS Code 사용)</h3>
<h3 id="2-nodejs-redis-라이브러리-설치">2) Node.js Redis 라이브러리 설치</h3>
<pre><code>npm init -y
npm install redis</code></pre><p><img src="https://velog.velcdn.com/images/hyunah_parc/post/b74b46b8-93a1-4644-99d8-76eef4549a91/image.png" alt="">
<img src="https://velog.velcdn.com/images/hyunah_parc/post/04c47c6e-21fd-4833-b0a6-ddd428cd64e5/image.png" alt=""></p>
<h3 id="3-indexjs-파일-추가">3) index.js 파일 추가</h3>
<pre><code class="language-javascript">const redis = require(&#39;redis&#39;);

async function main() {
    const client = redis.createClient({
        url: &#39;redis://localhost:6379&#39; // 비밀번호가 있다면: redis://:mypassword@redis-db:6379
    });

    client.on(&#39;error&#39;, (err) =&gt; {
        console.error(&#39;Redis Client Error&#39;, err);
    });

    try {
        await client.connect();

        await client.set(&#39;foo&#39;, &#39;bar&#39;);
        const value = await client.get(&#39;foo&#39;);
        console.log(&quot;The value of &#39;foo&#39; is :&quot;, value);

    } catch (err) {
        console.error(&quot;Error:&quot;, err);
    } finally {
        await client.quit();
    }
}

main();</code></pre>
<h3 id="4-vs-code에서-indexjs-실행">4) VS Code에서 index.js 실행</h3>
<pre><code>node index.js</code></pre><p><img src="https://velog.velcdn.com/images/hyunah_parc/post/aa3411c0-c338-447a-8305-7b4d1003cce4/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Supinfo][GCP] Google Cloud ]]></title>
            <link>https://velog.io/@hyunah_parc/SupinfoGCP-Google-Cloud</link>
            <guid>https://velog.io/@hyunah_parc/SupinfoGCP-Google-Cloud</guid>
            <pubDate>Tue, 09 Dec 2025 03:21:25 GMT</pubDate>
            <description><![CDATA[<h2 id="1-vpc-networks">1. VPC Networks</h2>
<p>Google Cloud Virtual Private Cloud</p>
<ul>
<li>전세계 단위로 동작하는 가상 네트워크</li>
<li>전역(Global) 단위 : 특정 region에 종속되지 않음</li>
<li>Subnets은 지역(Region) 단위</li>
<li>VPC는 기본적으로 서로 통신하지 X : Peering, VPN, Interconnect, Shared VPC로 연결 필요</li>
<li>같은 Subnet = 같은 Region : 같은 Region 안의 여러 Zone이 같은 서브넷을 공유</li>
<li>같은 VPC 안에 있으면 다른 Region이어도 서로 통신이 가능하지만, 같은 Region이어도 다른 VPC 면 인터넷을 통해서 통신해야된다</li>
</ul>
<h3 id="1-subnet-creation-mode">1) Subnet Creation Mode</h3>
<ul>
<li>Custom Subnet Mode<ul>
<li>운영 환경에서 추천</li>
<li>관리자가 Subnet을 직접 생성</li>
<li>IP 범위 겹침 방지</li>
<li>Firewall rules 없음</li>
</ul>
</li>
<li>Auto Subnet Mode<ul>
<li>테스트 환경에서 추천</li>
<li>프로젝트 생성 시 생성되는 기본 VPC</li>
<li>모든 Region에 /20 Subnet 자동 생성</li>
<li>Region 추가될 때마다 자동으로 Subnet 추가됨</li>
<li>기본 Firewall rules 포함(TCP 22 등)</li>
</ul>
</li>
</ul>
<h3 id="2-shared-vpc">2) Shared VPC</h3>
<p>한 조직 안에서 여러 프로젝트가 <strong>하나의 &#39;중앙 VPC&#39;를 공유하는 구조</strong></p>
<ul>
<li>Host Project
실제 VPC가 있는 프로젝트
서브넷 생성 담당</li>
<li>Service Projects
애플리케이션이 배치되는 프로젝트
네트워크 리소스는 중앙 팀에서 관리
서브넷을 사용만 가능</li>
<li>목적
회사 여러 팀이 동일 네트워크 정책을 써야 할 때
기업 네트워크 구조 중앙화
CIDR 충돌 방지
보안 및 감사 중앙 집중
대규모 기업, 팀 구조에 최적화</li>
<li>특징
조직 내부에서만 작동
네트워크 관리자는 Host Project만 관리
Service Project는 VPC 수정 불가
VM은 Service Project에 만들지만 Subnet은 Host Project에만 존재</li>
<li>보안 및 라우팅
같은 VPC 내부이므로 전부 자동 라우팅
firewall, routes 모두 한 네트워크이므로 관리 용이</li>
<li>시험 포인트
서브넷 생성은 Host Project에서만 가능
Service Project는 Subnet을 &quot;사용&quot;만 가능
Shared VPC는 조직(Organization) 내부에서만 사용 가능
Cross-organization 불가</li>
</ul>
<h3 id="3-vpc-network-peering">3) VPC Network Peering</h3>
<p><strong>두 VPC 간 private IP 기반 통신 연결</strong>을 제공</p>
<ul>
<li>목적
빠르게 두 VPC를 private으로 연결
네트워크를 합치지 않고도 통신 가능
서로 다른 조직, 프로젝트 간 통신 가능</li>
<li>특징
같은 Region일 필요 없음
네트워크 간 격리된 상태에서 private 연결 -&gt; 회계, 보안 분리를 유지하면서 통신 필요할 때 적합
트랜짓(transit) 불가 : a-b, b-c 여도 a-c 통신 불가능</li>
<li>언제 사용?
서로 다른 프로젝트 간 private 연결이 필요할 때
SaaS 제공 업체와 private 연결이 필요할 때
통합 네트워크는 필요 없지만 private 통신만 필요한 경우</li>
<li>시험 포인트
peering은 양방향 설정 필요
Firewall Rule 필요
peering은 네트워크를 완전히 합치는 것이 X</li>
</ul>
<h3 id="4-cloud-vpn">4) Cloud VPN</h3>
<p>VPN(IPsec)을 사용해 온프레미스 또는 외부 네트워크 ↔ GCP VPC를 안전하게 연결하는 서비스</p>
<ul>
<li>목적
온프레미스 &lt;-&gt; GCP 간 사설 통신
외부 클라우드 &lt;-&gt; GCP 통신
빠른 하이브리드 클라우드 구성</li>
<li>종류
Classic VPN
HA VPN(99.99% SLA)</li>
<li>특징
Public internet 위에서 암호화된 터널</li>
</ul>
<p>1.5~3Gbps per tunnel
여러 터널로 확장 가능 (ECMP)</p>
<ul>
<li>언제 사용?
온프레미스와 GCP를 빠르게 연결할 때
기업 내부망과 GCP를 사설 통신으로 묶을 때
Dedicated Interconnect 하기에는 비용/시간이 부족할 때</li>
<li>시험 포인트
Cloud VPN은 인터넷을 사용 : public internet 위에서 IPsec 사용
Cloud VPN은 사설 IP 연결 가능
Classic VPN은 SLA 없음
HA VPN은 SLA 99.99%
VPN은 cross-organization도 가능</li>
</ul>
<p>Q. In GCP, subnets are used mostly for IP addressing purposes.
GCP Subnet은 주로 VM에 내부 IP를 할당하기 위한 Pool(IP Range)을 제공하는 목적이 가장 크다.
GCP의 Subnet = 특정 Region에서 사용할 IP 주소 덩어리(CIDR Block)</p>
<p>cf) 온프레미스(On-premises)란?
조직 내부 건물(데이터센터, 서버실)에 하드웨어를 두고 직접 인프라를 관리·운영하는 방식</p>
<h2 id="2-dns">2. DNS</h2>
<p><strong>Domain Name System</strong>
도메인 이름을 IP 주소로 바꿔주는 시스템
예) <a href="http://www.google.com">www.google.com</a>  →  142.250.72.238
api.mycompany.com → 10.20.1.15
사람은 도메인이 기억하기 쉽고, 컴퓨터는 IP가 필요하므로 DNS가 둘 사이를 변환해주는 전화번호부 역할을 한다</p>
<p>GCP 내부에서 VM이 DNS 조회를 할 때 VM이 직접 DNS 서버를 설정하지 않는다
대신, 169.254.169.254 (Metadata Server) 이 주소가 자동으로 DNS Resolver 역할을 한다</p>
<ul>
<li>왜 Metadata Server가 DNS Resolver?
GCP가 VM에 내부 DNS 정보를 통제하기 쉽기 때문
Internal DNS / Cloud DNS Private Zone 모두 여기로 라우팅됨
VM에 공통된 DNS 구조 제공</li>
<li><em>VM은 반드시 Metadata Server를 통해 DNS 요청을 한다*</em></li>
</ul>
<p>VM이 부팅되면 DHCP로 IP 주소와 함께 DNS 서버 주소(= Metadata Server)가 자동 제공된다
즉,따로 DNS 설정을 하지 않아도
GCP가 VM 네트워크 설정을 자동 구성
Internal DNS 및 Private Zone 조회 가능</p>
<h3 id="1-internal-dns">1) Internal DNS</h3>
<p>GCP가 VPC 내부에서 기본으로 제공하는 DNS 서비스
VM을 만들면 GCP가 자동으로 내부 DNS 이름을 만든다</p>
<ul>
<li>특징
같은 프로젝트, 같은 VPC 내부에서만 조회 가능 -&gt; 다른 프로젝트나 다른 VPC에서는 Internal DNS 이름을 알 수 없음, 다른 VPC에서도 조회하려면 DNS Peering 필요
Google이 자동 생성
VM primary internal IP 기반</li>
<li>쓰는 이유
VM끼리 IP가 아니라 이름으로 통신 가능
VM IP가 바뀌어도 이름은 유지 (재생성 전까지)</li>
</ul>
<h3 id="2-cloud-dns">2) Cloud DNS</h3>
<p>Google Cloud가 제공하는 공식 DNS 서비스로 성능과 안정성이 매우 뛰어나다.</p>
<ul>
<li>Public DNS Zone
인터넷 공개용 도메인
예) <a href="http://www.mycompany.com">www.mycompany.com</a></li>
<li>Private DNS Zone
GCP 내부 VPC에서만 보이는 도메인
VPC 내부에서만 보이는 DNS 영역
예) erp-back-end1.eu.local 10.10.0.100
erp-back-end2.eu.local 10.10.0.101
내부 전용 Application Load Balancer에도 사용
GCP VPC는 Global이기 때문에 Private DNS Zone도 Global하게 적용된다
  : VPC 전체(여러 Region 포함)에서 동일하게 사용 가능
  : subnet이 어디 있든 같은 private zone 조회 가능
같은 프로젝트, 같은 VPC에 속해있어야 조회 가능 -&gt; 다른 VPC에서 조회하려면 DNS Peering 필요</li>
<li>특징
완전 관리형
고성능 (Google 글로벌 DNS 인프라)
Anycast 기반
100% SLA</li>
</ul>
<h2 id="3-cloud-cdn">3. Cloud CDN</h2>
<p>CDN(Content Delivery Network)은 전 세계 여러 위치에 분산된 서버 네트워크를 이용해, 사용자에게 웹사이트, 이미지, 동영상 등 콘텐츠를 더 빠르고 안정적으로 전달하는 기술
반드시 Cloud Load Balancer 필요</p>
<ul>
<li><p>기본 구성 요소</p>
<ul>
<li>Origin Server (오리진 서버)
원래 콘텐츠가 저장된 서버
예: 웹사이트의 이미지, HTML, 동영상 등</li>
<li>Cache Server (캐시 서버)
콘텐츠를 복제해서 저장하는 서버
사용자가 요청하면 오리진 서버가 아니라 캐시 서버에서 콘텐츠를 전달</li>
</ul>
</li>
<li><p>CDN의 장점
사용자 가까이에서 콘텐츠 제공 → 지연 시간(latency) 감소 → 빠른 웹/앱
대역폭 절약 → 트래픽이 많은 사이트에 유리
오리진 서버 부담 감소 → 서버 안정성 향상
서버 네트워크가 분산되고 중복되어 가용성 증가</p>
</li>
<li><p>작동 방식</p>
<ul>
<li>사용자가 요청 → 가장 가까운 엣지 서버(Edge Server) 확인</li>
<li>캐시 히트(Cache Hit)
콘텐츠가 이미 캐시에 있음 → 바로 사용자에게 제공 → 빠름</li>
<li>캐시 미스(Cache Miss)
콘텐츠가 캐시에 없음 → 오리진 서버에서 가져와 캐시에 저장 후 제공</li>
</ul>
</li>
</ul>
<h2 id="4-connectivity">4. Connectivity</h2>
<p>Hybrid Connectivity
온프레미스(On-prem 데이터센터), 다른 클라우드, GCP VPC 를 하나의 네트워크처럼 연결하는 전체 통신 구조
42 Regions, 127 Zones</p>
<p>POP이란? 
Point of Presence
구글 네트워크 장비가 실제의 물리적 네트워크 시설에 설치된 위치</p>
<h3 id="1-public-internet-vpn-ipsec-vpn-tunnel">1) Public Internet VPN (IPsec VPN tunnel)</h3>
<p>Encrypted tunnel to VPC networks through the public internet
인터넷 위에서 IPSEC VPN 터널로 사설 네트워크 연결
cloud에, cloud 끼리 연결하는 가장 빠른 방법
속도 1.5 ~ 3 Gbps per tunnel
static/dynamic (BGP) based VPN
비용 제일 저렴</p>
<h3 id="2-cloud-interconnect-전용-회선">2) Cloud Interconnect (전용 회선)</h3>
<ul>
<li>Dedicated
Dedicated, direct connection to VPC networks
Higher bandwidth needs (10 Gbps or 100 Gbps per link)</li>
<li>Partner
Dedicated bandwidth, connection to VPC network through a service provider
50 Mbps –10 Gbps per connection</li>
</ul>
<h3 id="3-peering">3) Peering</h3>
<h2 id="5-load-balancing">5. Load Balancing</h2>
<p>사용자 트래픽을 여러 백엔드 서버에 자동 분산하여 가용성·확장성·성능을 확보하는 서비스</p>
<ul>
<li>Layer 7 (Application LB)</li>
</ul>
<ul>
<li>Layer 4 (Network LB)</li>
</ul>
<h2 id="6-firewalls">6. Firewalls</h2>
<p>VPC 네트워크 단위로 적용되는 상태 기반(Stateful) 분산 방화벽</p>
<ul>
<li><p>Ingress and Egress firewall (allow / deny rules)</p>
</li>
<li><p>Stateful with Connection tracking</p>
</li>
<li><p>Distributed: enforced on host =&gt; no choke points</p>
</li>
<li><p>Flexible grouping mechanism for applications: tags,
service accounts</p>
</li>
<li><p>No support for dest IP match on ingress FW. no
support for source IP match on egress FW</p>
</li>
<li><p>Ingress
외부 -&gt; VM 들어오는 트래픽</p>
</li>
<li><p>Egress
VM -&gt; 외부 나가는 트래픽</p>
</li>
<li><p>요소
Direction : INGRESS / EGRESS
Priority : 숫자 낮을수록 우선
Target : 적용 대상 VM (Tag, SA)
Source/Destination : IP 또는 subnet
Allow/Deny : permit / 차단</p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Supinfo][Docker] Labs 2.2 - 도커로 PostgreSQL 컨테이너 설치하고 Node.js로 연동하기]]></title>
            <link>https://velog.io/@hyunah_parc/docker-postgres</link>
            <guid>https://velog.io/@hyunah_parc/docker-postgres</guid>
            <pubDate>Fri, 28 Nov 2025 15:05:27 GMT</pubDate>
            <description><![CDATA[<h2 id="1-docker-hub에서-postgresql-공식-이미지-pull-하기">1. Docker Hub에서 PostgreSQL 공식 이미지 pull 하기</h2>
<p><img src="https://velog.velcdn.com/images/hyunah_parc/post/8a83a32d-d3f2-4a75-b18b-43b668ffaf8d/image.png" alt="">
&quot;postgres&quot; 라고 검색해야 나온다</p>
<h2 id="2-받은-postgres-이미지-run해서-postgres-컨테이너-실행하기">2. 받은 postgres 이미지 Run해서 postgres 컨테이너 실행하기</h2>
<ul>
<li>컨테이너 이름 : postgresql-db</li>
<li>포트 : 5432</li>
<li>비밀번호 지정<pre><code class="language-bash">docker run --name postgresql-db -e POSTGRES_USER=hyunahpark -e POSTGRES_PASSWORD=pw57
63 -e POSTGRES_DB=my-postgres-db -p 5432:5432 -d postgres:latest</code></pre>
</li>
<li>--name postgresql-db : 컨테이너 이름</li>
<li>-e POSTGRES_PASSWORD=비밀번호넣기 : postgres 사용자 비밀번호 설정</li>
<li>-p 5432:5432 : 호스트 ↔ 컨테이너 포트 매핑</li>
<li>-d : 백그라운드 실행</li>
</ul>
<p><img src="https://velog.velcdn.com/images/hyunah_parc/post/42567718-8f01-4a6a-9587-4775420836bc/image.png" alt=""></p>
<h2 id="3-javascriptnodejs로-postgresql-연결하기">3. JavaScript(Node.js)로 PostgreSQL 연결하기</h2>
<h3 id="1-프로젝트-폴더-만들기-vs-code-사용">1) 프로젝트 폴더 만들기 (VS Code 사용)</h3>
<p>lab2.2-postgres</p>
<h3 id="2-pg-패키지-설치">2) pg 패키지 설치</h3>
<pre><code class="language-bash">npm install pg</code></pre>
<p><img src="https://velog.velcdn.com/images/hyunah_parc/post/a7047e08-bffd-4ad6-91ed-4e8fd230dd51/image.png" alt=""></p>
<h3 id="3-indexjs-파일-생성-작성하기">3) index.js 파일 생성, 작성하기</h3>
<p>테이블 생성, 데이터 삽입, 데이터 조회 기능</p>
<pre><code class="language-javascript">// container : postgresql-db

const { Client } = require(&#39;pg&#39;);

// 주의할 점 : 2번에서 docker run할 때 설정했던 정보대로 넣어줘야 접속이 된다 (user, password, db)
const client = new Client({
  user: &#39;hyunahpark&#39;,
  host: &#39;127.0.0.1&#39;,  // 여기서 로컬 PC의 Docker 포트로 연결
  database: &#39;my-postgres-db&#39;,
  password: &#39;pw5763&#39;,
  port: 5432
});

async function main() {
  try {
    await client.connect();
    console.log(&#39;PostgreSQL 연결 성공&#39;);

     // 1️⃣ 테이블 생성
    await client.query(`
      CREATE TABLE IF NOT EXISTS users (
        id SERIAL PRIMARY KEY,
        name VARCHAR(50) UNIQUE,
        age INT
      );
    `);
    console.log(&#39;테이블 생성 완료&#39;);

    // 2️⃣ 데이터 삽입
    await client.query(`
      INSERT INTO users (name, age) VALUES
      (&#39;Alice&#39;, 25),
      (&#39;Bob&#39;, 30)
      ON CONFLICT DO NOTHING;
    `);

    console.log(&#39;데이터 삽입 완료&#39;);

    // 3️⃣ 데이터 조회
    const res = await client.query(&#39;SELECT * FROM users;&#39;);
    console.log(&#39;조회 결과:&#39;, res.rows);

  } catch (err) {
    console.error(&#39;연결 오류:&#39;, err);
  } finally {
    await client.end();
  }
}

main();</code></pre>
<h3 id="4-vs-code에서-indexjs-실행">4) VS Code에서 index.js 실행</h3>
<pre><code class="language-bash">node index.js</code></pre>
<h3 id="5-결과">5) 결과</h3>
<p><img src="https://velog.velcdn.com/images/hyunah_parc/post/264d5b3d-b8f6-4650-a2c8-227f443c8174/image.png" alt=""></p>
<pre><code class="language-bash">PostgreSQL 연결 성공
테이블 생성 완료
데이터 삽입 완료
조회 결과: [ { id: 1, name: &#39;Alice&#39;, age: 25 }, { id: 2, name: &#39;Bob&#39;, age: 30 } ]</code></pre>
<h3 id="-터미널에서-데이터베이스-직접-접속하는-방법">+ 터미널에서 데이터베이스 직접 접속하는 방법</h3>
<pre><code class="language-bash">docker exec -it postgresql-db psql -U hyunahpark -d my-postgres-db</code></pre>
<ul>
<li>docker &quot;postgresql-db&quot; 컨테이너 안에서</li>
<li>psql 실행</li>
<li>&quot;hyunahpark&quot; 사용자로</li>
<li>&quot;my-postgres-db&quot; DB에 접속</li>
</ul>
<p><img src="https://velog.velcdn.com/images/hyunah_parc/post/606d1f7d-4324-4cc5-8b83-cc934c8b2d6a/image.png" alt=""></p>
<pre><code class="language-bash">C:\Users\hyuna\3DOKR\lab2.2-postgres&gt;docker exec -it postgresql-db psql -U hyunahpark -d my-postgres-db
psql (18.1 (Debian 18.1-1.pgdg13+2))
Type &quot;help&quot; for help.

my-postgres-db=# select * from users
my-postgres-db-# ;
 id | name  | age 
----+-------+-----
  1 | Alice |  25
  2 | Bob   |  30
(2 rows)</code></pre>
<h3 id="-vs-code에서-데이터베이스-테이블-보기">+ VS Code에서 데이터베이스 테이블 보기</h3>
<p>1) SQL Tools PostgreSQL 이라는 extension 다운로드 하기
<img src="https://velog.velcdn.com/images/hyunah_parc/post/6f93b834-3839-4cd3-9b67-8590d484e092/image.png" alt=""></p>
<p>2) Add connections
눌러서 db 이름, 사용자 이름, 포트 등 설정해주고 비밀번호 입력해주면 된다</p>
<p>3) 결과
<img src="https://velog.velcdn.com/images/hyunah_parc/post/f83d368a-c442-4c93-bc9f-6b8dc0cb2183/image.png" alt="">
이렇게 왼쪽 메뉴에 SQL Tools 메뉴가 생기는데 여기서 Table을 표로 볼 수 있다</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Redis 레디스란]]></title>
            <link>https://velog.io/@hyunah_parc/Redis-%EB%A0%88%EB%94%94%EC%8A%A4%EB%9E%80</link>
            <guid>https://velog.io/@hyunah_parc/Redis-%EB%A0%88%EB%94%94%EC%8A%A4%EB%9E%80</guid>
            <pubDate>Tue, 25 Nov 2025 13:53:08 GMT</pubDate>
            <description><![CDATA[<h2 id="1️⃣-redis-기본-개념">1️⃣ Redis 기본 개념</h2>
<p>Redis는 인메모리 데이터베이스입니다.
→ 즉, 데이터를 RAM(메모리)에 저장해서 엄청 빠르게 읽고 쓸 수 있어요.</p>
<p>주로 캐시(cache), 세션 저장, 실시간 카운트, 메시지 큐 등에 사용됩니다.</p>
<h2 id="2️⃣-특징">2️⃣ 특징</h2>
<ul>
<li>속도
메모리에 저장되므로 읽기/쓰기 속도가 매우 빠름</li>
<li>데이터 구조
문자열(String), 리스트(List), 셋(Set), 해시(Hash) 등 다양한 구조 지원</li>
<li>영속성
기본은 메모리 저장이지만, 필요하면 디스크에 저장 가능
간단한 키-값 저장소 : GET key, SET key value처럼 간단하게 사용 가능</li>
</ul>
<h2 id="3️⃣-redis가-현업에서-인기-있는-이유">3️⃣ Redis가 현업에서 인기 있는 이유</h2>
<p>Redis는 현업에서 특히 웹 서비스, 게임, 금융, 이커머스 등 다양한 분야에서 광범위하게 활용된다.</p>
<ul>
<li>초고속 성능
메모리에 데이터를 저장하므로 읽기/쓰기 속도가 매우 빠름
예: 페이지 조회수, 실시간 랭킹, 채팅 메시지</li>
<li>다양한 데이터 구조 지원
문자열, 리스트, 셋, 해시, 정렬된 셋 등
단순 키-값뿐 아니라 복잡한 데이터 구조도 효율적으로 처리 가능</li>
<li>세션 관리
웹 서비스에서 사용자 로그인 세션을 저장할 때 많이 사용
여러 서버에서 세션을 공유할 수 있어 확장성 좋음</li>
<li>캐시(Cache) 용도로 최적
데이터베이스 조회 결과를 Redis에 캐싱해서 DB 부하 감소
예: 인기 게시글, 상품 정보, API 결과</li>
<li>메시지 브로커 / 큐
Pub/Sub(발행/구독) 기능으로 실시간 알림, 채팅 구현 가능
작업 큐(Task Queue)로도 활용 가능</li>
</ul>
<h2 id="4️⃣-현업-사용-예시">4️⃣ 현업 사용 예시</h2>
<ul>
<li>이커머스<br>상품 조회수 카운트, 장바구니 임시 저장, 추천 캐시</li>
<li>소셜미디어<br>실시간 좋아요/댓글 카운트, 팔로워 알림</li>
<li>게임<br>랭킹 순위, 실시간 점수, 매칭 큐</li>
<li>금융/핀테크<br>트랜잭션 임시 저장, 캐싱, 실시간 통계</li>
<li>웹 서비스<br>로그인 세션, API 응답 캐시, 페이지 캐싱</li>
</ul>
<p>즉, Redis는 <strong>“속도가 중요한 곳”과 “실시간 데이터가 필요한 곳”</strong>에서 거의 필수적으로 사용되는 기술이다.</p>
<h2 id="💡">💡</h2>
<p>현업에서는 DB + Redis 조합이 일반적이다.
DB는 안정적인 저장소, Redis는 빠른 접근과 캐싱 역할</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Supinfo][Docker] Docker Desktop 설치]]></title>
            <link>https://velog.io/@hyunah_parc/docker-Docker-Desktop-%EC%84%A4%EC%B9%98</link>
            <guid>https://velog.io/@hyunah_parc/docker-Docker-Desktop-%EC%84%A4%EC%B9%98</guid>
            <pubDate>Mon, 24 Nov 2025 12:46:41 GMT</pubDate>
            <description><![CDATA[<p>여기서 다운로드
<a href="https://www.docker.com/">https://www.docker.com/</a></p>
<p><img src="https://velog.velcdn.com/images/hyunah_parc/post/0b9670ba-43d1-49a6-849d-1f3542c947a2/image.png" alt="">
Download Docker Desktop &gt; Download for Windows - AMD64
윈도우 재시작 후 까만 창이 뜨고 리눅스 설치한다고 뜨면 아무 버튼이나 눌러서 설치</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[GitHub] Git 깃 다운로드 후 VS Code로 GitHub 연결 후 코드 업로드 하기]]></title>
            <link>https://velog.io/@hyunah_parc/Git-%EA%B9%83-%EB%8B%A4%EC%9A%B4%EB%A1%9C%EB%93%9C-%ED%9B%84-VS-Code%EB%A1%9C-GitHub-%EC%97%B0%EA%B2%B0-%ED%9B%84-%EC%BD%94%EB%93%9C-%EC%97%85%EB%A1%9C%EB%93%9C-%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@hyunah_parc/Git-%EA%B9%83-%EB%8B%A4%EC%9A%B4%EB%A1%9C%EB%93%9C-%ED%9B%84-VS-Code%EB%A1%9C-GitHub-%EC%97%B0%EA%B2%B0-%ED%9B%84-%EC%BD%94%EB%93%9C-%EC%97%85%EB%A1%9C%EB%93%9C-%ED%95%98%EA%B8%B0</guid>
            <pubDate>Fri, 17 Oct 2025 13:26:02 GMT</pubDate>
            <description><![CDATA[<h2 id="1-git-다운로드">1. Git 다운로드</h2>
<ul>
<li><a href="https://git-scm.com/downloads/win">https://git-scm.com/downloads/win</a> 에서 latest 다운로드</li>
<li>exe 파일 실행해서 설치해주기</li>
</ul>
<h2 id="2-git-설치-완료-확인">2. Git 설치 완료 확인</h2>
<ul>
<li>설치가 끝났다면 VS Code 터미널 또는 명령 프롬프트(cmd) 열고 입력:<pre><code>git --version</code></pre></li>
</ul>
<p>👉 정상이라면 이런 식으로 버전이 표시된다</p>
<pre><code>git version 2.51.0.windows.1
</code></pre><h2 id="3-사용자-정보-등록-처음-한-번만">3. 사용자 정보 등록 (처음 한 번만)</h2>
<p>👉 “내가 만든 커밋이 누구 것인지” 표시해주는 설정</p>
<pre><code>git config --global user.name &quot;내이름&quot;
git config --global user.email &quot;내이메일@example.com&quot;</code></pre><p>(이메일은 GitHub 계정에 등록된 이메일을 사용하는 걸 추천)</p>
<h2 id="4-vs-code에서-github에-올리기">4. VS Code에서 GitHub에 올리기</h2>
<h3 id="1-vs-code에서-프로젝트-폴더의-터미널-열기">1) VS Code에서 프로젝트 폴더의 터미널 열기</h3>
<p>혹은 아무 터미널에서 </p>
<pre><code>cd 프로젝트폴더경로</code></pre><h3 id="2-git-초기화">2) Git 초기화</h3>
<pre><code>git init</code></pre><p>👉 이 명령은 현재 폴더를 Git 저장소로 초기화한다.
(폴더 안에 .git이라는 숨김 폴더가 생긴다.)</p>
<h3 id="3-변경-파일-추가--커밋">3) 변경 파일 추가 &amp; 커밋</h3>
<pre><code>git add .
git commit -m &quot;Initial commit&quot;</code></pre><p>👉 git add . : 모든 파일을 Git에 추적하도록 추가
👉 git commit -m &quot;Initial commit&quot; : 첫 커밋 메시지 작성</p>
<h3 id="4-github에-새-저장소repository-만들기">4) GitHub에 새 저장소(repository) 만들기</h3>
<p>“Initialize this repository with a README”는 체크 X
(이미 로컬에 Git 초기화가 되어 있기 때문)</p>
<p>👉 .gitignore는 코드 업로드 전 로컬 저장소에서 만드는 것 추천!! 
(갓 프로젝트 파일을 만든 거면 상관 없지만 node_modules가 생긴 상태면 .gitignore을 안 만들고 깃허브에 업로드 하면 쓸 데 없는 파일까지 다 업로드 되어버린다)</p>
<h3 id="5-로컬-프로젝트와-github-연결--업로드">5) 로컬 프로젝트와 GitHub 연결 &amp; 업로드</h3>
<pre><code>git remote add origin https://github.com/사용자이름/my-project.git
git branch -M main
git push -u origin main</code></pre><p>👉 GitHub에서 새 저장소를 만들면
위처럼 안내 문구가 나온다. (복사해서 터미널에 붙여넣기!!)
👉 https:// 다음은 본인 깃허브 리퍼지토리 주소로 바꿔주기</p>
<h3 id="6-github-로그인--personal-access-tokenpat-입력">6) GitHub 로그인 / Personal Access Token(PAT) 입력</h3>
<p>VS Code 내 세 번째 메뉴 &quot;Source Control&quot;에서 &quot;Publish to GitHub&quot; 눌러서 깃허브 로그인 해주기</p>
<h3 id="7-업로드-완료">7) 업로드 완료!</h3>
<p>명령이 끝나면 GitHub에 들어가서 새로고침하면 프로젝트 파일이 올라간 것을 볼 수 있다!</p>
<p>👉 나는 6번 로그인을 안 하고 publish를 안 눌러줬더니 안 올라갔었다. 깃허브 처음 연결하는 거라면 잊지 말기!</p>
<p><img src="https://velog.velcdn.com/images/hyunah_parc/post/1b13e038-27ac-4253-9e67-f41ea138291d/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Node.js] 블로킹 vs 논블로킹]]></title>
            <link>https://velog.io/@hyunah_parc/Node.js-%EB%B8%94%EB%A1%9C%ED%82%B9-vs-%EB%85%BC%EB%B8%94%EB%A1%9C%ED%82%B9</link>
            <guid>https://velog.io/@hyunah_parc/Node.js-%EB%B8%94%EB%A1%9C%ED%82%B9-vs-%EB%85%BC%EB%B8%94%EB%A1%9C%ED%82%B9</guid>
            <pubDate>Sun, 05 Oct 2025 23:21:32 GMT</pubDate>
            <description><![CDATA[<h1 id="1️⃣-블로킹blocking-vs-논블로킹non-blocking">1️⃣ 블로킹(Blocking) vs 논블로킹(Non-blocking)</h1>
<h2 id="블로킹blocking">블로킹(Blocking)</h2>
<ul>
<li>어떤 작업이 끝날 때까지 다음 코드가 실행되지 않는 것을 의미</li>
<li>쉽게 말해, 작업 중에는 아무것도 못하고 기다리는 상태</li>
<li>Node.js에서 대표적인 예 : 동기식 파일 읽기(readFileSync)</li>
</ul>
<pre><code class="language-javascript">const fs = require(&quot;fs&quot;);

console.log(&quot;시작&quot;);
const data = fs.readFileSync(&quot;file.txt&quot;, &quot;utf8&quot;); // 여기서 파일 읽는 동안 멈춤
console.log(data);
console.log(&quot;끝&quot;);</code></pre>
<p>실행 순서:
시작
(파일 읽는 동안 잠시 멈춤)
파일 내용 출력
끝</p>
<p>즉, 파일 읽기가 끝날 때까지 다른 작업이 진행되지 않음 → 서버라면 요청 처리도 멈춰버림</p>
<h2 id="논블로킹non-blocking">논블로킹(Non-blocking)</h2>
<ul>
<li>작업을 시작하고, 끝나길 기다리지 않고 바로 다음 코드 실행</li>
<li>Node.js에서 주로 콜백(callback), Promise, async/await 방식으로 사용</li>
<li>예시 : 비동기 파일 읽기(readFile)</li>
</ul>
<pre><code class="language-javascript">const fs = require(&quot;fs&quot;);

console.log(&quot;시작&quot;);
fs.readFile(&quot;file.txt&quot;, &quot;utf8&quot;, (err, data) =&gt; {
    console.log(data); // 파일 읽기 끝나면 실행
});
console.log(&quot;끝&quot;);</code></pre>
<p>실행 순서:
시작
끝
(나중에 파일 내용 출력)</p>
<p>서버에서는 다른 요청 처리를 중간에 멈추지 않고 계속 진행할 수 있음</p>
<h1 id="2️⃣-핵심-포인트">2️⃣ 핵심 포인트</h1>
<ol>
<li>블로킹 → 작업 완료까지 기다림 → 다른 코드 정지</li>
<li>논블로킹 → 작업 시작 후 바로 다음 코드 실행 → 완료되면 콜백/Promise로 처리</li>
<li>Node.js 서버에서는 블로킹 코드를 많이 쓰면 전체 서버 성능 저하</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Supinfo][Node.js] Products CRUD API 만들기]]></title>
            <link>https://velog.io/@hyunah_parc/SupinfoJavaScript-Products-CRUD-API-%EB%A7%8C%EB%93%A4%EA%B8%B0</link>
            <guid>https://velog.io/@hyunah_parc/SupinfoJavaScript-Products-CRUD-API-%EB%A7%8C%EB%93%A4%EA%B8%B0</guid>
            <pubDate>Sun, 05 Oct 2025 23:06:49 GMT</pubDate>
            <description><![CDATA[<p>자바스크립트 오랜만에 하니까 어렵다
학교에서 한 실습 중 유용한 한 개 기록</p>
<h1 id="👩💻-문제">👩‍💻 문제</h1>
<p><img src="https://velog.velcdn.com/images/hyunah_parc/post/4ab13b8c-996b-4334-997a-6fadda8590e5/image.png" alt=""></p>
<h1 id="🙋♀️-답변">🙋‍♀️ 답변</h1>
<pre><code class="language-javascript">let products = [
    {id: 1, name: &quot;Laptop&quot;, price: 1200},
    {id: 2, name: &quot;Headphones&quot;, price: 150},
    {id: 3, name: &quot;Keyboard&quot;, price: 70},
    {id: 4, name: &quot;Mouse&quot;, price: 40},
    {id: 5, name: &quot;Monitor&quot;, price: 300}
];

// Import the express library
const express = require(&quot;express&quot;);

// Initializing the app
const app = express();

app.use(express.json());
// app.use() : 요청 바디(request body)를 JSON으로 파싱하는 내장 미들웨어
// express.json()
// : 요청 바디(request body)를 JSON으로 파싱하는 내장 미들웨어
// 클라이언트가 보낸 JSON 데이터를 request.body로 바로 사용할 수 있게 만들어줌

// CREATE
app.post(&quot;/products&quot;, (request, response)=&gt; {
    const newProduct = request.body; // OBJECT JS
    console.log(newProduct); 
    products.push(newProduct);
    response.status(201).send(products);
    // response.json(products);
});

// READ ALL (+ 필터 기능)
// 쿼리 파라미터 - request.query
app.get(&quot;/products&quot;, (request, response)=&gt; {

    const query = request.query; // 쿼리 파라미터 전체 가져오기
    console.log(query);

    // let name = query.name;
    // let minPrice = query.minPrice;
    // let maxPrice = query.maxPrice;

    // 객체 구조 분해 할당 (Object destructuring assignment)
    let { name, minPrice, maxPrice } = query;

    // 문자열 -&gt; 숫자 변환
    minPrice = minPrice ? Number(minPrice) : undefined;
    maxPrice = maxPrice ? Number(maxPrice) : undefined;

    // 새로운 배열로 필터링
    let filtered = products;

    // 이름 검색 (부분 일치도)
    if(name) {
        filtered = filtered.filter(p =&gt; {
            return p.name.toLowerCase().includes(name.toLowerCase());
        });
    }

    // 최소 가격
    if(minPrice !== undefined) {
        filtered = filtered.filter(p =&gt; {
            return p.price &gt;= minPrice
        });
    }

    // 최대 가격
    if(maxPrice) {
        filtered = filtered.filter(p =&gt; {
            return p.price &lt;= maxPrice
        });
    }

    response.status(200).json(filtered);
});

// READ ONE
// (경로) 파라미터 - request.params
app.get(&quot;/products/:id&quot;, (request, response)=&gt; {
    const id = parseInt(request.params.id); // 모든 params 중에 id를 가져온다 (String 형식)
    console.log(&quot;Product id : &quot; + id);
    const product = products.find(p=&gt; p.id===id);
    console.log(product);

    if (!product) {
        return response.status(404).send({ message: &quot;Product not found&quot; });
    }

    response.status(200).send(product);
})

// UPDATE
app.put(&quot;/products/:id&quot;, (request, response)=&gt; {
    const id = parseInt(request.params.id); // 모든 params 중에 id를 가져온다 (String 형식)
    console.log(&quot;Product id : &quot; + id);
    const product = products.find(p=&gt; p.id===id);
    console.log(product);

    if (!product) {
        return response.status(404).send({ message: &quot;Product not found&quot; });
    }

    const { name, price } = request.body;

    if(name) product.name = name;
    if(price !== undefined) product.price = price;

    response.status(200).send(product);
});

// DELETE
app.delete(&quot;/products/:id&quot;, (request, response)=&gt; {
    const id = parseInt(request.params.id); // 모든 params 중에 id를 가져온다 (String 형식)
    console.log(&quot;Product id : &quot; + id);
    const product = products.find(p=&gt; p.id===id);

    if (!product) {
        return response.status(404).send({ message: &quot;Product not found&quot; });
    }

    products = products.filter(p=&gt; p.id !== id);

    response.status(200).send(products);
});



app.listen(8080, (err)=&gt; {
    console.log(&quot;Server running on http://localhost:8080&quot;);
});</code></pre>
<h1 id="🤔">🤔</h1>
<ul>
<li>request.params.id 나 request.body.minPrice 결과가 String이니까 int로 변경해주기</li>
<li>int로 변경해줬을 때 NaN 뜨지 않게 undefined 처리해주기</li>
<li>객체 구조 분해 할당 사용해서 간결하게 하기</li>
<li>없는 제품 검색했을 때 404 리턴해주는 게 좋은가? (더 RESTful 하다고 한다) : 어떤 경우에 404 리턴해주고 어떤 경우에 null 리턴해주는 게 좋은지?</li>
<li>response.send()와 response.json() 사용의 차이</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[python vs java] 가변 인자 함수 (*args, int...  args)]]></title>
            <link>https://velog.io/@hyunah_parc/python-vs-java-%EA%B0%80%EB%B3%80-%EC%9D%B8%EC%9E%90-%ED%95%A8%EC%88%98</link>
            <guid>https://velog.io/@hyunah_parc/python-vs-java-%EA%B0%80%EB%B3%80-%EC%9D%B8%EC%9E%90-%ED%95%A8%EC%88%98</guid>
            <pubDate>Tue, 20 May 2025 11:24:48 GMT</pubDate>
            <description><![CDATA[<h3 id="🐍-python">🐍 Python</h3>
<pre><code class="language-python">def add_many(*args):
    return sum(args)

print(add_many(1, 2, 3, 4))  # 10</code></pre>
<p>파이썬에서 *args는 가변 위치 인자 variable-length positional arguments 라고 부른다.</p>
<h3 id="☕️-java">☕️ Java</h3>
<pre><code class="language-java">public class Example {
    public static int addMany(int... args) {
        int sum = 0;
        for (int num : args) {
            sum += num;
        }
        return sum;
    }

    public static void main(String[] args) {
        System.out.println(addMany(1, 2, 3, 4));  // 출력: 10
    }
}</code></pre>
<p>자바에서 int... args는 Varargs (variable arguments) 라고 부른다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[python] 리스트 컴프리헨션]]></title>
            <link>https://velog.io/@hyunah_parc/python-%EB%A6%AC%EC%8A%A4%ED%8A%B8-%EC%BB%B4%ED%94%84%EB%A6%AC%ED%97%A8%EC%85%98</link>
            <guid>https://velog.io/@hyunah_parc/python-%EB%A6%AC%EC%8A%A4%ED%8A%B8-%EC%BB%B4%ED%94%84%EB%A6%AC%ED%97%A8%EC%85%98</guid>
            <pubDate>Tue, 20 May 2025 10:46:42 GMT</pubDate>
            <description><![CDATA[<p>리스트 컴프리헨션 신박하다......</p>
<pre><code class="language-python">a = [1,2,3,4]
result = [num*3 for num in a if num%2 !=0]
print(result)

result = [i*j for i in range(1,10) for j in range(1,10)]
print(result)</code></pre>
<p>결과</p>
<pre><code class="language-python">[3, 9]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 2, 4, 6, 8, 10, 12, 14, 16, 18, 3, 6, 9, 12, 15, 18, 21, 24, 27, 4, 8, 12, 16, 20, 24, 28, 32, 36, 5, 10, 15, 20, 25, 30, 35, 40, 45, 6, 12, 18, 24, 30, 36, 42, 48, 54, 7, 14, 21, 28, 35, 42, 49, 56, 63, 8, 16, 24, 32, 40, 48, 56, 64, 72, 9, 18, 27, 36, 45, 54, 63, 72, 81]</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[python vs Java] Python의 range()와 Java의 IntStream.range()]]></title>
            <link>https://velog.io/@hyunah_parc/python-vs-Java-Python%EC%9D%98-range%EC%99%80-Java%EC%9D%98-IntStream.range</link>
            <guid>https://velog.io/@hyunah_parc/python-vs-Java-Python%EC%9D%98-range%EC%99%80-Java%EC%9D%98-IntStream.range</guid>
            <pubDate>Tue, 20 May 2025 10:04:46 GMT</pubDate>
            <description><![CDATA[<h3 id="python-🐍">Python 🐍</h3>
<pre><code class="language-python">for i in range(1, 11):
    print(i)</code></pre>
<h3 id="java-☕️">Java ☕️</h3>
<pre><code class="language-java">for (int i = 1; i &lt; 11; i++) {
    System.out.println(i);
}</code></pre>
<p>항상 기본 for문만 사용했었는데 Stream으로 간단하게 한 줄로 가능하다는 것을 알았다...!</p>
<pre><code class="language-java">import java.util.stream.IntStream;

public class StreamExample {

    public static void main(String[] args) {

        IntStream.range(1, 11).forEach(System.out::println); // 메서드 레퍼런스 방식
        IntStream.range(1, 11).forEach(x-&gt;System.out.println(x)); // 람다식
    }

}</code></pre>
<p>람다식도 익숙하지 않아서 아직 잘 못 쓰는데 메서드 레퍼런스 방식은 진짜 모르겠다,,,,😀 간결한 건 좋은데 직관적이지 않아서 더 어렵게 느껴지는 것 같다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[python vs Java] 리스트 같은 곳 참조하기 (참조 복사)]]></title>
            <link>https://velog.io/@hyunah_parc/python-%EB%A6%AC%EC%8A%A4%ED%8A%B8-%EA%B0%99%EC%9D%80-%EA%B3%B3-%EC%B0%B8%EC%A1%B0%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@hyunah_parc/python-%EB%A6%AC%EC%8A%A4%ED%8A%B8-%EA%B0%99%EC%9D%80-%EA%B3%B3-%EC%B0%B8%EC%A1%B0%ED%95%98%EA%B8%B0</guid>
            <pubDate>Tue, 20 May 2025 08:53:09 GMT</pubDate>
            <description><![CDATA[<h3 id="python-🐍">Python 🐍</h3>
<pre><code class="language-python">a = [1, 2, 3]
b = a

b.append(4)

print(a)  # 👉 [1, 2, 3, 4]
print(b)  # 👉 [1, 2, 3, 4]
print(a is b)  # 👉 True</code></pre>
<h3 id="java-☕️">Java ☕️</h3>
<pre><code>List&lt;Integer&gt; a = new ArrayList&lt;&gt;(List.of(1, 2, 3));
List&lt;Integer&gt; b = a;

b.add(4);

System.out.println(a); // 👉 [1, 2, 3, 4]
System.out.println(b); // 👉 [1, 2, 3, 4]</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[python vs Java] 집합 자료형 set에서 교집합, 합집합, 차집합 구하기]]></title>
            <link>https://velog.io/@hyunah_parc/python-%EC%A7%91%ED%95%A9-%EC%9E%90%EB%A3%8C%ED%98%95-set%EC%97%90%EC%84%9C-%EA%B5%90%EC%A7%91%ED%95%A9-%ED%95%A9%EC%A7%91%ED%95%A9-%EC%B0%A8%EC%A7%91%ED%95%A9-%EA%B5%AC%ED%95%98%EA%B8%B0-vs-Java</link>
            <guid>https://velog.io/@hyunah_parc/python-%EC%A7%91%ED%95%A9-%EC%9E%90%EB%A3%8C%ED%98%95-set%EC%97%90%EC%84%9C-%EA%B5%90%EC%A7%91%ED%95%A9-%ED%95%A9%EC%A7%91%ED%95%A9-%EC%B0%A8%EC%A7%91%ED%95%A9-%EA%B5%AC%ED%95%98%EA%B8%B0-vs-Java</guid>
            <pubDate>Mon, 19 May 2025 19:42:40 GMT</pubDate>
            <description><![CDATA[<p>집합 자료형인 set의 특징은</p>
<ul>
<li>중복을 허용하지 않는다</li>
<li>순서가 없다</li>
</ul>
<h2 id="✔️-파이썬-자바로-교집합-합집합-차집합-구하기">✔️ 파이썬, 자바로 교집합, 합집합, 차집합 구하기</h2>
<h3 id="python-🐍">Python 🐍</h3>
<pre><code class="language-python">a = {1, 2, 3}
b = {2, 3, 4}

print(a &amp; b) 
print(a.intersection(b))  # 교집합: {2, 3}
print(a | b) 
print(a.union(b))         # 합집합: {1, 2, 3, 4}
print(a - b) 
print(a.difference(b))    # 차집합: {1}</code></pre>
<h3 id="java-☕️">Java ☕️</h3>
<pre><code class="language-java">import java.util.*;

public class Main {
    public static void main(String[] args) {
        Set&lt;Integer&gt; a = new HashSet&lt;&gt;(Arrays.asList(1, 2, 3));
        Set&lt;Integer&gt; b = new HashSet&lt;&gt;(Arrays.asList(2, 3, 4));

        // 교집합
        Set&lt;Integer&gt; intersection = new HashSet&lt;&gt;(a);
        intersection.retainAll(b);
        System.out.println(&quot;교집합: &quot; + intersection);  // [2, 3]

        // 합집합
        Set&lt;Integer&gt; union = new HashSet&lt;&gt;(a);
        union.addAll(b);
        System.out.println(&quot;합집합: &quot; + union);         // [1, 2, 3, 4]

        // 차집합
        Set&lt;Integer&gt; difference = new HashSet&lt;&gt;(a);
        difference.removeAll(b);
        System.out.println(&quot;차집합: &quot; + difference);    // [1]
    }
}</code></pre>
<p>이렇게 비교해보니 코드 길이 차이가... 😱 파이썬이 훨씬 간단하고 쉽긴 하다 !!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[python vs Java] Python의 .keys 와 Java의 .keySet()]]></title>
            <link>https://velog.io/@hyunah_parc/python-python%EC%9D%98-.keys-%EC%99%80-java%EC%9D%98-.keySet</link>
            <guid>https://velog.io/@hyunah_parc/python-python%EC%9D%98-.keys-%EC%99%80-java%EC%9D%98-.keySet</guid>
            <pubDate>Mon, 19 May 2025 18:50:28 GMT</pubDate>
            <description><![CDATA[<p>자바를 먼저 공부하고 파이썬을 공부하다보니 자꾸 파이썬의 이 기능은 자바에서 뭐였더라? 생각하게 된다... 그래서 진도가 잘 안 나가 !! 😀 그래도 정리해놓기</p>
<h3 id="python">Python</h3>
<pre><code class="language-python">a = {&#39;name&#39;: &#39;Alice&#39;, &#39;age&#39;: 30, &#39;city&#39;: &#39;Seoul&#39;}

keys = a.keys()
print(keys)           # dict_keys([&#39;name&#39;, &#39;age&#39;, &#39;city&#39;])
print(list(keys))     # [&#39;name&#39;, &#39;age&#39;, &#39;city&#39;]</code></pre>
<h3 id="java">Java</h3>
<pre><code class="language-java">import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class Main {
    public static void main(String[] args) {
        Map&lt;String, Integer&gt; map = new HashMap&lt;&gt;();
        map.put(&quot;name&quot;, 1);
        map.put(&quot;age&quot;, 2);
        map.put(&quot;city&quot;, 3);

        Set&lt;String&gt; keys = map.keySet();

        System.out.println(keys);  // [name, age, city]
    }
}</code></pre>
<p>map 선언 안 해도 되고 그냥 냅다 써버리는 거 적응 안 된다,,, 파이썬의 첫인상은 유도리가 너무 넘쳐서 당황스러운 느낌... 그래서 오히려 헷갈리는 느낌...😀</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Java] Stack vs Heap 메모리]]></title>
            <link>https://velog.io/@hyunah_parc/Java-Stack-vs-Heap</link>
            <guid>https://velog.io/@hyunah_parc/Java-Stack-vs-Heap</guid>
            <pubDate>Sat, 17 May 2025 19:41:11 GMT</pubDate>
            <description><![CDATA[<h2 id="🧠-java에서-stack과-heap의-차이">🧠 Java에서 Stack과 Heap의 차이</h2>
<h3 id="📌-stack-영역">📌 Stack 영역</h3>
<ul>
<li>메서드 호출 시 생성되는 프레임과 지역 변수가 저장되는 공간입니다.</li>
<li>후입선출 (LIFO, Last In First Out) 구조로 동작합니다.</li>
<li>메서드가 호출되면 메모리가 자동으로 할당되고, 메서드가 끝나면 자동으로 해제됩니다.</li>
<li>속도가 빠르며, 각 스레드마다 독립적인 스택을 가집니다 → 스레드 안전(Thread-safe)<pre><code class="language-java">void example() {
  int x = 10; // x는 Stack에 저장됨
}</code></pre>
</li>
</ul>
<h3 id="📌-heap-영역">📌 Heap 영역</h3>
<ul>
<li>new 키워드를 통해 생성된 객체가 저장되는 공간입니다.</li>
<li>메모리는 동적으로 할당되며, <strong>가비지 컬렉터(Garbage Collector)</strong>가 관리합니다.</li>
<li>Stack보다 속도가 느리지만, 객체는 프로그램 전반에서 공유될 수 있습니다.</li>
<li>여러 스레드가 접근 가능하기 때문에 <strong>동기화(synchronization)</strong>가 필요할 수 있습니다.<pre><code class="language-java">Person p = new Person(); // p는 Stack에, 실제 Person 객체는 Heap에 저장됨</code></pre>
<h3 id="🔍-요약-표">🔍 요약 표:</h3>
<img src="https://velog.velcdn.com/images/hyunah_parc/post/579bb051-20a9-4478-b656-f31440f08b73/image.png" alt=""></li>
</ul>
<h2 id="🧠-stack-vs-heap-in-java">🧠 Stack vs Heap in Java</h2>
<h3 id="📌-stack">📌 Stack</h3>
<ul>
<li>The stack is a region of memory that stores method call frames and local variables.</li>
<li>It follows the Last In, First Out (LIFO) principle.</li>
<li>Memory is automatically allocated and deallocated when methods are called and return.</li>
<li>It is faster than the heap.</li>
<li>Each thread has its own stack, so it&#39;s thread-safe.</li>
<li>Example:
When you declare a local variable like int x = 10; inside a method, it&#39;s stored in the stack.</li>
</ul>
<h3 id="📌-heap">📌 Heap</h3>
<ul>
<li>The heap is a region of memory used for dynamic memory allocation.</li>
<li>Objects created using new are stored in the heap.</li>
<li>Memory in the heap is managed by the Garbage Collector.</li>
<li>It is slower compared to the stack.</li>
<li>The heap is shared among all threads, so you need to handle synchronization for thread safety.</li>
<li>Example:
When you write Person p = new Person();, the Person object is created in the heap, while the reference p is stored in the stack.<h3 id="🔍-summary-table">🔍 Summary Table:</h3>
<img src="https://velog.velcdn.com/images/hyunah_parc/post/96de03cc-ef40-4b28-a2d9-9a9b280764a9/image.png" alt=""></li>
</ul>
<h2 id="🧠-pile-stack-vs-tas-heap-en-java">🧠 Pile (Stack) vs Tas (Heap) en Java</h2>
<h3 id="📌-pile-stack">📌 Pile (Stack)</h3>
<ul>
<li>La pile est une zone mémoire qui stocke les frames d’appel de méthode et les variables locales.</li>
<li>Elle suit le principe dernier entré, premier sorti (LIFO).</li>
<li>La mémoire y est allouée et libérée automatiquement à chaque appel et retour de méthode.</li>
<li>Elle est plus rapide que le tas.</li>
<li>Chaque thread dispose de sa propre pile, ce qui la rend thread-safe.</li>
<li>Exemple :
Lorsque vous déclarez une variable locale comme int x = 10; dans une méthode, x est stockée dans la pile.</li>
</ul>
<h3 id="📌-tas-heap">📌 Tas (Heap)</h3>
<ul>
<li>Le tas est une zone mémoire utilisée pour l’allocation dynamique.</li>
<li>Les objets créés avec new sont stockés dans le tas.</li>
<li>La gestion de la mémoire est assurée par le ramasse-miettes (Garbage Collector).</li>
<li>Il est plus lent que la pile.</li>
<li>Le tas est partagé entre tous les threads, donc synchronisation nécessaire pour la sécurité des accès concurrents.</li>
<li>Exemple :
Avec Person p = new Person();, l’objet Person est créé dans le tas, tandis que la référence p est stockée dans la pile.</li>
</ul>
<h3 id="🔍-tableau-récapitulatif">🔍 Tableau récapitulatif</h3>
<p><img src="https://velog.velcdn.com/images/hyunah_parc/post/68890f48-4045-4907-a48b-58007803c5e1/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JavaScript] 버튼 눌러서 배경 색상 랜덤으로 바꾸기]]></title>
            <link>https://velog.io/@hyunah_parc/JavaScript-%EB%B2%84%ED%8A%BC-%EB%88%8C%EB%9F%AC%EC%84%9C-%EB%B0%B0%EA%B2%BD-%EC%83%89%EC%83%81-%EB%9E%9C%EB%8D%A4%EC%9C%BC%EB%A1%9C-%EB%B0%94%EA%BE%B8%EA%B8%B0</link>
            <guid>https://velog.io/@hyunah_parc/JavaScript-%EB%B2%84%ED%8A%BC-%EB%88%8C%EB%9F%AC%EC%84%9C-%EB%B0%B0%EA%B2%BD-%EC%83%89%EC%83%81-%EB%9E%9C%EB%8D%A4%EC%9C%BC%EB%A1%9C-%EB%B0%94%EA%BE%B8%EA%B8%B0</guid>
            <pubDate>Fri, 02 May 2025 19:04:22 GMT</pubDate>
            <description><![CDATA[<pre><code class="language-javascript">&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
&lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot;&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
    &lt;title&gt;Document&lt;/title&gt;
    &lt;script&gt;
        function changeColor() {
            let arrColor = [&quot;red&quot;, &quot;orange&quot;, &quot;yellow&quot;, &quot;green&quot;, &quot;blue&quot;];
            let arrNum = Math.floor(Math.random()*arrColor.length); // 0~5
            // console.log(arrNum);
            let tag = document.getElementById(&quot;theBody&quot;);
            tag.style.backgroundColor = arrColor[arrNum];
        }
    &lt;/script&gt;
&lt;/head&gt;
&lt;body id=&quot;theBody&quot;&gt;
    &lt;button onclick=&quot;changeColor()&quot;&gt;배경 색상 바꾸기&lt;/button&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre>
<p><img src="https://velog.velcdn.com/images/hyunah_parc/post/63aedd67-2903-4304-94fe-89f42123fec8/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JavaScript] 객체 생성자]]></title>
            <link>https://velog.io/@hyunah_parc/JavaScript-%EA%B0%9D%EC%B2%B4-%EC%83%9D%EC%84%B1%EC%9E%90</link>
            <guid>https://velog.io/@hyunah_parc/JavaScript-%EA%B0%9D%EC%B2%B4-%EC%83%9D%EC%84%B1%EC%9E%90</guid>
            <pubDate>Fri, 02 May 2025 18:24:00 GMT</pubDate>
            <description><![CDATA[<p>자바스크립트에서 객체를 만들 때 객체 생성자를 사용할 수 있는 방법은 두 가지가 있다.</p>
<ul>
<li>클래스를 사용하여 객체 생성자 정의</li>
<li>함수 방식으로 객체 생성자 사용</li>
</ul>
<h3 id="1-클래스를-사용한-객체-생성자-es6">1. 클래스를 사용한 객체 생성자 (ES6)</h3>
<p>ES6부터는 클래스를 사용하여 객체 생성자를 정의할 수 있다. 클래스는 생성자 함수의 새로운 문법적 표현이다.</p>
<pre><code class="language-javascript"> &lt;script&gt;
        class Person {
          // 생성자 함수
            constructor(name, age) {
                this.name = name;
                this.age = age;
            }

          // 메서드 정의
            sayHello() {
                console.log(`안녕하세요 ${this.name}`);
            }
        }

        // 객체 생성
        let person1 = new Person(&quot;홍길동&quot;, 20);

        // 메서드 호출
        person1.sayHello();
    &lt;/script&gt;</code></pre>
<h3 id="2-1-함수-방식으로-객체-생성자-사용-전통적-방식">2-1. 함수 방식으로 객체 생성자 사용 (전통적 방식)</h3>
<p>전통적인 객체 생성자 방식은 함수 선언을 사용하여 객체를 생성하는 방법이다. 이 방식에서 new 키워드를 사용하여 객체를 생성한다.</p>
<pre><code class="language-javascript">     &lt;script&gt;
          // 객체 생성자 함수 정의
        function Person(name, age) {
            this.name = name;
            this.age = age;
            this.sayHello = function() {
                console.log(`안녕하세요 ${this.name}`);
            };
        }

        // 객체 생성
        let person1 = new Person(&quot;홍길동&quot;, 30);

        // 메서드 호출
        person1.sayHello();
    &lt;/script&gt;</code></pre>
<h3 id="2-2-프로토타입-사용">2-2. 프로토타입 사용</h3>
<p>객체 생성자 함수에 프로토타입을 사용하여 함수를 등록하면 메모리 낭비를 줄일 수 있다.</p>
<pre><code class="language-javascript">    &lt;script&gt;
        function Person(name, age) {
            this.name = name;
            this.age = age;
            // this.sayHello = function() {
            //     console.log(`안녕하세요 ${this.name}`);
            // };     
        }

        Person.prototype.sayHello = function() {
            console.log(`안녕하세요 ${this.name}`);
        }

        let person1 = new Person(&quot;박현아&quot;, 29);
        person1.sayHello();
    &lt;/script&gt;</code></pre>
]]></description>
        </item>
    </channel>
</rss>