<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>dev-jhyun</title>
        <link>https://velog.io/</link>
        <description>Better than Yesterday, Further than Before</description>
        <lastBuildDate>Fri, 15 Nov 2024 06:42:53 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>dev-jhyun</title>
            <url>https://velog.velcdn.com/images/jh_yun505/profile/97ad7c63-abfa-4017-82c7-d08d05d856dd/image.jpeg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. dev-jhyun. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/jh_yun505" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[Docker를 활용한 배포 - Docker Compose와 Docker Network]]></title>
            <link>https://velog.io/@jh_yun505/Docker%EB%A5%BC-%ED%99%9C%EC%9A%A9%ED%95%9C-%EB%B0%B0%ED%8F%AC-Docker-Compose%EC%99%80-Docker-Network</link>
            <guid>https://velog.io/@jh_yun505/Docker%EB%A5%BC-%ED%99%9C%EC%9A%A9%ED%95%9C-%EB%B0%B0%ED%8F%AC-Docker-Compose%EC%99%80-Docker-Network</guid>
            <pubDate>Fri, 15 Nov 2024 06:42:53 GMT</pubDate>
            <description><![CDATA[<h1 id="1-docker-composeyml을-활용한-배포">1. docker-compose.yml을 활용한 배포</h1>
<h2 id="docker-composeyml-작성">docker-compose.yml 작성</h2>
<p>Docker를 활용해 MySQL 이미지를 가져와 실행하고, 이를 spring 이미지에서 이용하도록 docker-compose.yml 파일을 작성했다.</p>
<pre><code class="language-yaml">services:
  mysql:
    image: mysql:latest
    container_name: mysql-example
    environment:
      MYSQL_ROOT_PASSWORD: ${db_root_password}
      MYSQL_DATABASE: ${db_name}
      MYSQL_USER: ${db_username}
      MYSQL_PASSWORD: ${db_password}
    ports:
      - &quot;3306:3306&quot;

  spring-boot-app:
    image: ${생성한_Docker_image_이름}
    container_name: spring-boot-container
    ports:
      - &quot;8080:8080&quot;
    depends_on:
      - mysql
    environment:
      DB_URL: jdbc:mysql://mysql:3306/${db_name}
      DB_USERNAME: ${db_username}
      DB_PASSWORD: ${db_password}
      SPRING_PROFILES_ACTIVE: prod</code></pre>
<h2 id="오류-발생">오류 발생</h2>
<p> <img src="https://velog.velcdn.com/images/jh_yun505/post/6726dfe4-9c6e-466f-9c1b-e5b62eb57c74/image.png" alt="">
MySQL 컨테이너는 계속해서 실행되지만 spring 이미지가 계속해서 종료 되는 문제가 발생했다.
<img src="https://velog.velcdn.com/images/jh_yun505/post/a94726fe-23a3-4376-bf6d-2971d9365443/image.png" alt="">
로그를 살펴보니 MySQL이 제대로 시작되기 전에 Spring 컨테이너가 실행이 되면서 DB 연결을 시도해서 자꾸 멈추는 것을 확인했다.</p>
<p>찾아보니 <code>depends_on</code>의 경우는 Docker compose에서 <em>&#39;단순히 서비스의 시작 순서를 설정하는 것이지 서비스의 준비상태까지 보장하는 것은 아니&#39;</em> 라고 한다.</p>
<p>따라서 정상적으로 실행시키기 위해서는 mysql이 실제로 <strong>통신가능한 상태</strong>인지 확인하는 과정이 필요하다.</p>
<h2 id="해결-방법">해결 방법</h2>
<h3 id="1-wait-for-it-사용">1) wait-for-it 사용</h3>
<blockquote>
<p><code>wait-for-it</code>은 docker에서 여러 Docker Container들을 동시에 실행해야 할 때 각각의 실행 순서를 정해준다.
<a href="https://github.com/vishnubob/wait-for-it">https://github.com/vishnubob/wait-for-it</a></p>
</blockquote>
<h4 id="github에서-wait-for-itsh-다운로드">github에서 <code>wait-for-it.sh</code> 다운로드</h4>
<pre><code class="language-bash">curl -o wait-for-it.sh https://raw.githubusercontent.com/vishnubob/wait-for-it/master/wait-for-it.sh
chmod +x wait-for-it.sh</code></pre>
<h4 id="docker-composeyml-또는-dockerfile-수정"><code>docker-compose.yml</code> 또는 <code>Dockerfile</code> 수정</h4>
<h5 id="dockerfileyml">Dockerfile.yml</h5>
<pre><code class="language-yml">spring-boot-app:
  image: elice_aws_docker_practice
  container_name: spring-boot-container
  ports:
    - &quot;8080:8080&quot;
  depends_on:
    - mysql
  environment:
    DB_URL: jdbc:mysql://mysql:3306/elice
    DB_USERNAME: elice
    DB_PASSWORD: elice1234
    SPRING_PROFILES_ACTIVE: prod
  entrypoint: [&quot;wait-for-it.sh&quot;, &quot;mysql:3306&quot;, &quot;--&quot;, &quot;java&quot;, &quot;-jar&quot;, &quot;app.jar&quot;]</code></pre>
<h5 id="dockerfile">Dockerfile</h5>
<pre><code class="language-Dockerfile">FROM openjdk:17-jdk-slim

# wait-for-it.sh 복사
COPY wait-for-it.sh /usr/local/bin/wait-for-it.sh
RUN chmod +x /usr/local/bin/wait-for-it.sh

# 앱 실행 명령어를 wait-for-it.sh로 래핑
CMD [&quot;wait-for-it.sh&quot;, &quot;mysql:3306&quot;, &quot;--&quot;, &quot;java&quot;, &quot;-jar&quot;, &quot;app.jar&quot;]</code></pre>
<ul>
<li>MySQL 컨테이너가 완전히 실행되고 난 뒤에 jar 파일을 실행한다.</li>
</ul>
<h3 id="2-healthcheck를-사용한-컨테이너-상태-확인">2) HealthCheck를 사용한 컨테이너 상태 확인</h3>
<pre><code class="language-yaml">services:
  mysql:
    image: mysql:latest
    container_name: mysql-example
    environment:
      MYSQL_ROOT_PASSWORD: ${db_root_password}
      MYSQL_DATABASE: ${db_name}
      MYSQL_USER: ${db_username}
      MYSQL_PASSWORD: ${db_password}
    ports:
      - &quot;3306:3306&quot;
    healthcheck:
      test: [&quot;CMD&quot;, &quot;mysqladmin&quot;, &quot;ping&quot;, &quot;-h&quot;, &quot;localhost&quot;]
      interval: 10s
      timeout: 5s
      retries: 3

  spring-boot-app:
    image: ${생성한_Docker_image_이름}
    container_name: spring-boot-container
    ports:
      - &quot;8080:8080&quot;
    depends_on:
      mysql:
        condition: service_healthy
    environment:
      DB_URL: jdbc:mysql://mysql:3306/${db_name}
      DB_USERNAME: ${db_username}
      DB_PASSWORD: ${db_password}
      SPRING_PROFILES_ACTIVE: prod</code></pre>
<ul>
<li>HealthCheck를 사용하는경우 MySQL이 정상 작동 상태를 반환하기 전까지 spring-boot-app을 시작하지 않는다</li>
</ul>
<h2 id="결과">결과</h2>
<p>나는 HealthCheck를 활용하는 방법을 선택했다.
<img src="https://velog.velcdn.com/images/jh_yun505/post/603e4f7d-d064-4ff9-a7fb-fdd257f37c3b/image.png" alt=""></p>
<p>위의 사진을 살펴보면 처음 실행했을 때는 <code>mysql-example</code>과 <code>spring-boot-container</code>의 로그가 번갈아 가며 찍히다가 종료되었는데, 이번에는 mysql이 전부 실행된 뒤에 spring이 실행되는 모습을 볼 수 있다.
<img src="https://velog.velcdn.com/images/jh_yun505/post/9e131ad5-ab18-4f90-bf4d-f9f6cb0b4a14/image.png" alt="">
localhost를 통해서 접근도 잘 되는 것을 확인할 수 있다.</p>
<hr>
<h1 id="2-docker-network를-활용한-배포">2. Docker Network를 활용한 배포</h1>
<blockquote>
<p>이 방법은 이미 MySQL이나 다른 서비스가 Docker를 이용해 배포되고 있을 때 사용하면 좋을 것 같다. docker-compose를 통해서 docker 컨테이너를 생성 및 실행하는 경우 docker network가 새로 생성되기 때문!</p>
</blockquote>
<h2 id="docker-network-생성">Docker Network 생성</h2>
<p><img src="https://velog.velcdn.com/images/jh_yun505/post/3f004fa9-3b1b-49c4-a1fe-e5fabda974f4/image.png" alt=""></p>
<pre><code class="language-bash">docker network create ${network_name}
docker network ls</code></pre>
<h2 id="mysql-컨테이너-생성">MySQL 컨테이너 생성</h2>
<p><img src="https://velog.velcdn.com/images/jh_yun505/post/f950dcc1-5894-4b34-8816-987561f44688/image.png" alt=""></p>
<pre><code class="language-bash">docker pull mysql
docker run -d --name mysql-container --network ${위에서_설정한_네트워크명} -e MYSQL_ROOT_PASSWORD=${password} mysql:latest
docker ps
docker network inspect ${네트워크명}</code></pre>
<h2 id="mysql-컨테이너에-접속해-db-생성">MySQL 컨테이너에 접속해 DB 생성</h2>
<pre><code class="language-bash">docker exec -it &lt;mysql-container-이름&gt; bash # bash 터미널 실행
mysql -u root -p</code></pre>
<p>위의 명령어를 사용하면 MySQL 컨테이너의 터미널에 접근이 가능하다.
이후 터미널에서 mysql을 실행하고, DB를 생성해준다.</p>
<pre><code class="language-mysql">CREATE DATABASE &lt;DB명&gt;</code></pre>
<h2 id="docker-composeyml-파일-수정">docker-compose.yml 파일 수정</h2>
<h3 id="1-이미-생성된-docker-image를-사용하는-경우">1) 이미 생성된 Docker image를 사용하는 경우</h3>
<pre><code class="language-yaml">services:
  spring-app:
    image: your-existing-image:latest  # 사용하려는 Docker 이미지 이름과 태그
    container_name: spring-app-container
    ports:
      - &quot;8080:8080&quot;
    nvironment:
      SPRING_DATASOURCE_URL: jdbc:mysql://${mysql_container_이름}:3306/${db_이름}
      SPRING_DATASOURCE_USERNAME: ${db_username}
      SPRING_DATASOURCE_PASSWORD: ${db_password}
    networks:
      - docker-net-prac

networks:
  docker-net-prac:
    external: true</code></pre>
<h3 id="2-docker-image를-생성하는-경우">2) Docker image를 생성하는 경우</h3>
<pre><code class="language-yaml">services:
  spring-app:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: spring-app-container
    environment:
      SPRING_DATASOURCE_URL: jdbc:mysql://${mysql_container_이름}:3306/${db_이름}
      SPRING_DATASOURCE_USERNAME: ${db_username}
      SPRING_DATASOURCE_PASSWORD: ${db_password}
    ports:
      - &quot;8080:8080&quot;
    networks:
      - docker-net-prac

networks:
  docker-net-prac:
    external: true</code></pre>
<h3 id="docker-composeyml-파일-설명">docker-compose.yml 파일 설명</h3>
<h4 id="context의-역할">context의 역할</h4>
<ol>
<li>Docker 빌드 컨텍스트 경로 지정<ul>
<li>Docker 데몬이 해당 디렉토리를 기준으로 Dockerfile과 빌드에 필요한 파일을 찾음</li>
</ul>
</li>
<li>COPY 명령어에서 사용<ul>
<li>Dockerfile 내에서 COPY나 ADD 명령어를 사용할 때, context로 지정된 디렉토리 기준으로 파일 경로를 참조</li>
</ul>
</li>
<li>빌드 파일 전송<ul>
<li>Docker는 context에서 지정한 경로에 있는 모든 파일을 Docker 데몬에게 전송</li>
<li>.dockerignore 파일을 사용하면 불필요한 파일들을 제거 가능</li>
</ul>
</li>
</ol>
<h4 id="external-option">external option</h4>
<ul>
<li>이미 존재하는 네트워크를 사용하는 경우 <code>true</code>로 설정함</li>
<li>Docker compose는 기본적으로 고유한 네트워크를 생성하기 때문에 <code>external: true</code>를 통해 이 동작을 막는다.</li>
<li>동일한 네트워크를 생성하려고 하면 충돌 에러가 발생할 수 있기 때문에 Compose가 네트워크를 새로 생성하지 않도록 한다.</li>
</ul>
<hr>
<p><strong>[참고자료]</strong></p>
<ul>
<li><a href="https://tytydev.tistory.com/45">Docker spring boot mysql 연동 자세히 설명</a></li>
<li><a href="https://velog.io/@ppinkypeach/NestJs%EC%97%90%EC%84%9C-Wait-for-it-%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EC%A0%81%EC%9A%A9%ED%95%98%EA%B8%B0">NestJs에서 Wait-for-it 스크립트 적용하기</a></li>
<li><a href="https://velog.io/@cabbage/%EB%AC%B8%EC%A0%9C%ED%95%B4%EA%B2%B0-%EB%8F%84%EC%BB%A4-%EC%BB%B4%ED%8F%AC%EC%A6%88%EC%97%90%EC%84%9C-DB-%EC%97%B0%EA%B2%B0-%EC%A7%80%EC%97%B0-%EC%9D%B4%EC%8A%88">[문제해결] 도커 컴포즈에서 DB 연결 지연 이슈</a></li>
<li><a href="https://velog.io/@lijahong/0%EB%B6%80%ED%84%B0-%EC%8B%9C%EC%9E%91%ED%95%98%EB%8A%94-Docker-%EA%B3%B5%EB%B6%80-Docker-Compose-Network-Volume-%EC%A0%95%EC%9D%98%ED%95%98%EA%B8%B0">0부터 시작하는 Docker 공부 - Docker Compose - Network &amp; Volume 정의하기</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[이론] 네트워크 모델(Network Models)]]></title>
            <link>https://velog.io/@jh_yun505/Network-Models</link>
            <guid>https://velog.io/@jh_yun505/Network-Models</guid>
            <pubDate>Wed, 10 Apr 2024 03:14:48 GMT</pubDate>
            <description><![CDATA[<h2 id="1-layered-tasks">1. Layered Tasks</h2>
<h3 id="layered-architecture">Layered Architecture</h3>
<ul>
<li>A single machine, each layer calls upon the services of the layer just below it.</li>
</ul>
<h3 id="peer-to-peer">Peer-to-Peer</h3>
<p>두 컴퓨터끼리의 통신 → 다른 컴퓨터가 어떻게 통신하는지는 알 필요 없다.</p>
<h2 id="2-the-osi-model">2. The OSI Model</h2>
<h3 id="osi-7-layers">OSI 7 Layers</h3>
<blockquote>
<p>💡 계층을 나누는 이유 → 독립적으로 작동하게 하여 편리하게 할 수 있다. 하나의 레이어가 달라지더라도 인터페이스만 동일하다면 다른 레이어들 고칠 필요 없다.</p>
</blockquote>
<ul>
<li>왜 Internet 모델로 다시 돌아왔는가?<ul>
<li>빨라지려면 단순해야 한다.</li>
<li>OSI 7계층은 ? 복잡하다.</li>
</ul>
</li>
</ul>
<h2 id="4-tcpip-protocol-suite">4. TCP/IP Protocol Suite</h2>
<blockquote>
<p>💡 TCP(Transmission Control Protocol) / IP(Internetworking Protocol)</p>
</blockquote>
<h2 id="5-addressing">5. Addressing</h2>
<h3 id="physical-address">Physical Address</h3>
<ul>
<li>Physical Address : 보드에 적힌 Ethernet 주소<ul>
<li>LAN이나 WAN 에 의해 정해지는 주소</li>
<li>Data Link Layer에서 사용 되는 Frame 안에 포함된다.</li>
<li>가장 낮은 레벨의 주소</li>
<li>모든 사람이 받아보지만 자기 주소랑 안맞으면 프레임 버린다.</li>
</ul>
</li>
</ul>
<h3 id="logical-addressip-주소">Logical Address(IP 주소)</h3>
<ul>
<li>문자로 표기 된 것은 논리 주소</li>
<li>컴퓨터 물리 주소 알 수는 있지만 실제로 통신 할 때에는 논리 주소인 IP주소를 사용한다</li>
</ul>
<p><img src="https://velog.velcdn.com/images/jh_yun505/post/ef2d4dee-c4b4-4465-82b3-d77a6e119c8c/image.png" alt=""></p>
<h3 id="port-address">Port Address</h3>
<p><img src="https://velog.velcdn.com/images/jh_yun505/post/e35e641f-5142-42c9-922e-bb88e4e58790/image.png" alt=""></p>
<h2 id="6-basic-of-internet-routing">6. Basic of Internet Routing</h2>
<h3 id="routong-table-hierarchy">Routong Table Hierarchy</h3>
<p><img src="https://velog.velcdn.com/images/jh_yun505/post/4a2c2e50-952d-458e-9a26-cac26859ff0b/image.png" alt=""></p>
<h3 id="class-of-internet-address">Class of Internet Address</h3>
<ol>
<li>Class A (<strong>1.0.0.0</strong> - 127. 255. 255.255) : 7bits(netid- 부여받은 주소) + 24bits(hostId- 정한 주소)</li>
<li>Class B (<strong>128.0.0</strong> - 191. 255.255.255) : 14bits(netid- 부여받은 주소) + 16bits(hostId- 정한 주소)</li>
<li>Class C (<strong>192.0.0.0</strong> - 223.255.255.255) : 21bits(netid- 부여받은 주소) + 8bits(hostId- 정한 주소)</li>
</ol>
<h3 id="step-for-basic-routing">Step for Basic Routing</h3>
<ol>
<li>packet을 받으면 dst addr 추출</li>
<li>Network Address = Dst addr &amp; SubNet Mask in Entry</li>
<li>network address == dst network address?<ol>
<li>matching → send</li>
<li>else → repeat until right match</li>
</ol>
</li>
<li>No match ⇒ select default</li>
</ol>
<p><img src="https://velog.velcdn.com/images/jh_yun505/post/11f99542-dc35-428d-ac32-872bf0cd620e/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/jh_yun505/post/a4203708-3159-43ec-b510-7b6d2c3cca4d/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/jh_yun505/post/1d67d28c-439e-4081-adea-1ae7292e0a5f/image.png" alt=""></p>
<ul>
<li>000.000.000.000/<strong>26</strong><ul>
<li>뒤에 붙는 숫자 ⇒ 앞에서부터 1의 갯수 → 32 - 26 = 6 ⇒ 64개씩 그룹</li>
</ul>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/jh_yun505/post/22791f36-142f-471d-8e1c-4109bb209dc4/image.png" alt=""></p>
<ul>
<li>네트워크 계층이 있다 == Routing Table이 있다.</li>
<li>connected ⇒ 직접 연결되어 있다 : ARP 날려서 논리 주소 얻는다</li>
<li>else ⇒ Gateway로 가면 된다</li>
</ul>
<p><img src="https://velog.velcdn.com/images/jh_yun505/post/15445e84-aa38-42fb-a073-7eed50a2aa95/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[취업준비] 상반기 1차 점검]]></title>
            <link>https://velog.io/@jh_yun505/%EC%B7%A8%EC%97%85%EC%A4%80%EB%B9%84-%EC%83%81%EB%B0%98%EA%B8%B0-1%EC%B0%A8-%EC%A0%90%EA%B2%80</link>
            <guid>https://velog.io/@jh_yun505/%EC%B7%A8%EC%97%85%EC%A4%80%EB%B9%84-%EC%83%81%EB%B0%98%EA%B8%B0-1%EC%B0%A8-%EC%A0%90%EA%B2%80</guid>
            <pubDate>Fri, 05 Apr 2024 09:47:56 GMT</pubDate>
            <description><![CDATA[<p>미국에서 인턴을 하다가 돌아오고 나니...
갑자기 공채 시즌이 되었다.
한 달 정도는 준비할 시간이 있겠거니 했던 내가 너무 어이없다.</p>
<p>상반기에 합격을 바라는 것은 어려울 거라는 것은 이미 알고 있었지만
그래도 도전해보지 않고 포기할 수는 없으니(코딩 테스트를 봐 본 적이 없어서 경험이 필요하기도 했다)
전부터 가고 싶어했던 기업들 몇 개만 지원서를 넣었다.</p>
<h2 id="토스---python-개발자-챌린지">토스 - Python 개발자 챌린지</h2>
<ul>
<li>3/8 지원 완료</li>
<li>3/10 과제 테스트</li>
</ul>
<p>토스에서 파이썬을 쓸 줄 아는 사람이라면 누구나 도전할 수 있고, 코딩 테스트가 아니라 과제 테스트로 진행하길래 지원해봤다.
하지만 Django를 한 번도 안 써본 나에게는 너무 어려운 도전이었고...
시험 당일에 급하게 다녀와야 하는 곳이 있어서 2시간 정도 밖에 살펴 볼 시간이 없었다.
과제 테스트를 한 번도 해본 적이 없어서 어쨌든 어떻게 나오는 지 알 수 있어서 좋은 경험이었다.
<img src="https://velog.velcdn.com/images/jh_yun505/post/e56bbaac-ad7a-4c88-96d8-537754dc0344/image.jpeg" alt=""></p>
<h2 id="네이버---infra-직무">네이버 - Infra 직무</h2>
<ul>
<li>모집 기간: 2024.03.05 ~ 2024.03.18</li>
<li>3/17 지원 완료</li>
<li>3/21 온라인 코딩테스트 및 기업 문화 적합도 검사 대상자 안내
<img src="https://velog.velcdn.com/images/jh_yun505/post/f814ca92-b32f-40e9-b375-67546ab335dc/image.png" alt=""></li>
<li>3/23 코딩 테스트</li>
<li>4/4 결과 발표 연기 안내 메세지
  <img src="https://velog.velcdn.com/images/jh_yun505/post/9d86b54d-1334-4dfe-b747-9b5fb4308969/image.png" alt=""></li>
</ul>
<p>컴퓨터 공학 전공자라면 누구나 가고 싶어하는 기업이 네이버 아닐까?
서류 탈락은 거의 없다고 하는데 혹시나 서류에서 떨어질까봐 자소서 문항과 제출한 서류들을 세번씩은 본 것 같다.
제출 이후에도 수정할 수 있다는 것이 매우 편리했다.
코딩 테스트에서 아주...아주 망했기 때문에 마음을 비우고 있는 상태였는데
결과 발표가 연기 되었다고 메세지를 보내주셔서 감사했다.
지원자를 배려해주는 기업 같다.</p>
<hr>
<p> 2024/04/09 추가
 탈락 메일이 왔다.
 탈락 메일은 왜 두 개씩 오는 건가요ㅜㅜ
 내년에 다시 한 번 도전해봐야지
 <img src="https://velog.velcdn.com/images/jh_yun505/post/47bae0c1-2d03-4ee5-9e5b-ca8fb719649a/image.jpeg" alt=""></p>
<hr>
<h2 id="삼성전자-dx---da-사업부">삼성전자 DX - DA 사업부</h2>
<ul>
<li>모집 기간: 2024.03.11 ~ 2024.03.18</li>
<li>3/18 지원 완료</li>
<li>4/5 직무적합성평가 결과 안내 메일
오늘 나올 줄 모르고 있었는데 갑자기 메일이 와서 정말 핸드폰을 던질 뻔 했다.
합격 불합격이 메일에 적혀 있는 것은 아니고 삼성 채용 사이트에 들어가서 확인하면 된다.
<img src="https://velog.velcdn.com/images/jh_yun505/post/b55d7f1c-77e1-4a4a-b678-cbd69d21829f/image.png" alt="">
삼성이 서류가 빡세다는 얘기를 들어서 걱정했는데(SW 말고 다른 직군은 그럴지도)
다행히 코딩테스트를 볼 수 있는 기회를 얻었다.
얼마 안 남았는데 준비하는 게 깝깝하다.</li>
</ul>
<h2 id="aws---data-center-operation-trainee">AWS - Data Center Operation Trainee</h2>
<ul>
<li>모집 기간: 2024.02 ~ 모집 완료 시</li>
<li>4/4 지원 완료</li>
</ul>
<p>정말 고민을 많이 했다.
커리어 페어도 참여해서 듣고 질문도 하고 그랬다..
AWS는 워낙에 채용 과정이 길어서... 잊고 있다 보면 합/불을 알려주려나 하고 있다.
자유형식 영어 이력서라 이력서 작성에 시간을 좀 들였다.</p>
<h2 id="우아한-형제들---우아한-테크캠프-7기">우아한 형제들 - 우아한 테크캠프 7기</h2>
<ul>
<li>모집 기간: 2024.04.04 ~ 2024.04.10</li>
<li>4/4 지원 완료</li>
<li>코딩테스트: 4/13 예정</li>
</ul>
<p>우아한 테크캠프가 여지껏 지원한 모든 과정 중에 가장 간단하게 접수할 수 있었다.
그만큼 코딩 테스트 결과가 중요하다는 뜻일텐데 아주 걱정이 많다...</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Infra 기초] 1. 서버란 무엇인가]]></title>
            <link>https://velog.io/@jh_yun505/Infra-Basic-1-Server</link>
            <guid>https://velog.io/@jh_yun505/Infra-Basic-1-Server</guid>
            <pubDate>Tue, 26 Mar 2024 01:57:13 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>본 글은 Inflearn의 <a href="https://www.inflearn.com/course/%EB%88%84%EA%B5%AC%EB%82%98-%EC%89%BD%EA%B2%8C-%EC%9D%B4%ED%95%B4%ED%95%98%EB%8A%94-it-%EC%9D%B8%ED%94%84%EB%9D%BC-%EA%B8%B0%EC%B4%88/dashboard">롱런하는 슈퍼 개발자가 되기 위한 필수 지식, IT 인프라 기초 총정리</a> 을 수강하며 정리한 내용입니다.</p>
</blockquote>
<h1 id="서버와-클라이언트">서버와 클라이언트</h1>
<p><img src="https://velog.velcdn.com/images/jh_yun505/post/939e90f5-9250-43aa-8cef-6e59a92259f6/image.png" alt="서버와 클라이언트 동작 원리"></p>
<ul>
<li>서버: 클라이언트에게 네트워크를 통해 정보나 서비스를 제공하는 장치(요청 시 저장되어 있던 응용 프로그램을 전송)</li>
<li>클라이언트: 네트워크를 통하여 서버에 접속해 정보를 확인하거나 서비스를 이용하는 장치(응용 프로그램을 요청한 뒤 실행)</li>
</ul>
<blockquote>
<p>서버는 클라이언트의 <strong>요청</strong>을 처리하므로 클라이언트로부터 요청을 받아야 제 역할을 다 할 수 있다.</p>
</blockquote>
<h1 id="서버의-역할-및-종류">서버의 역할 및 종류</h1>
<h2 id="웹-애플리케이션-구성-서버">웹 애플리케이션 구성 서버</h2>
<ul>
<li><p>웹 서비스를 제공하기 위해서는 다양한 서버가 필요하다.(규모가 작은 경우 하나의 서버로 통합할 수 있지만 리소스 부족 가능성이 있다.)</p>
</li>
<li><p>클라이언트가 브라우저를 통해 콘텐츠(소스코드, 텍스트, 이미지, 동영상 등)을 요청하면 서버가 이에 대한 응답을 전송하는 방식</p>
<h3 id="구성-서버의-종류">구성 서버의 종류</h3>
</li>
<li><p>웹 서버: 클라이언트와 가장 가까이 존재하며, 정적 콘텐츠를 클라이언트에게 전달.</p>
<blockquote>
<p>서버는 응답을 보낸 후 요청 내용과 응답 내용을 기록하게 되는데 이를 <strong>Log</strong> 라고 한다.</p>
</blockquote>
</li>
<li><p>애플리케이션 서버: 동적 콘텐츠를 클라이언트에 전달. 웹 서버로부터 요청을 받아 콘텐츠를 전달한다.</p>
</li>
<li><p>데이터베이스(DB) 서버: 애플리케이션의 정보를 저장해서 운영, 관리할 수 있는 데이터베이스를 구동하는 서버</p>
</li>
<li><p>프록시 서버: 클라이언트가 자신을 통해서 다른 네트워크 서비스에 간접적으로 접속할 수 있게 해주는 컴퓨터 시스템. 서버와 서버 사이의 중계기 역할
  <img src="https://velog.velcdn.com/images/jh_yun505/post/16e3f00e-16de-47a4-a613-35f4e1941c8b/image.png" alt=""> 출처: <a href="https://securityboulevard.com/2023/04/what-is-reverse-proxy-how-does-it-works-and-what-are-its-benefits/">https://securityboulevard.com/2023/04/what-is-reverse-proxy-how-does-it-works-and-what-are-its-benefits/</a></p>
<ul>
<li>리버스 프록시 서버: <ul>
<li>웹앱서버 / WAS 앞에 놓여져 있으며(인터넷 뒷단에 존재) 서버쪽으로 데이터 요청을 밀어준다. <ul>
<li>흔히 사용하는 [Apache, Nginx] &lt;-&gt; [Tomcat] 분리 형태를 Reverse 프록시라고 볼 수 있다.</li>
</ul>
</li>
<li>사용 시 로드 밸런싱, 본래 서버의 IP 노출 방지, 캐싱, 암호화의 이점이 있다.</li>
</ul>
</li>
<li>포워드 프록시 서버: <ul>
<li>클라이언트 바로 뒤에 놓여 있음. <ul>
<li>인터넷을 통해 외부 서버에서 데이터를 가져와 클라이언트에게 응답한다. </li>
<li>사용 시 캐싱을 통한 빠른 응답, 서버에 클라이언트의 IP 주소를 알리지 않음, 암호화의 이점이 있다.</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<h1 id="서버-하드웨어와-소프트웨어">서버 하드웨어와 소프트웨어</h1>
<h2 id="서버-하드웨어-분류-by-폼팩터">서버 하드웨어 분류 by 폼팩터</h2>
<h3 id="랙rack-마운트-서버">랙(Rack) 마운트 서버</h3>
<ul>
<li>랙에 밀어넣는 형태의 서버</li>
<li>한 칸을 1U(Unit)이라 하고 크기에 따라 1U 서버 ~ nU 서버라고 부른다.<h3 id="블레이드blade형-서버">블레이드(Blade)형 서버</h3>
</li>
<li>랙 마운트형 서버를 더 얇게 만들고 케이스가 없는 형태의 서버<h3 id="타워형-서버">타워형 서버</h3>
</li>
<li>일반 데스크탑 PC와 유사한 형태의 서버</li>
<li>워크스테이션이라고도 부른다<h2 id="서버-하드웨어-분류-by-종류">서버 하드웨어 분류 by 종류</h2>
<h3 id="main-frame">Main Frame</h3>
</li>
<li>IBM이 1964년 출시한 통계, 금융 분야에 사용되는 대형 서버</li>
<li>경량화하여 UNIX가 나왔으며 마찬가지로 금융권 및 대기업에서 많이 사용하는 형태의 서버이다.<h3 id="x86">x86</h3>
</li>
<li>가장 많이 사용하는 서버 유형</li>
<li>랙서버의 경우 대부분 x86</li>
</ul>
<p>대표적인 서버 하드웨어 제조사는 HPE, Dell Technologies, Inspur, Lenovo, IBM, Asus등이 있다.</p>
<h2 id="서버-소프트웨어">서버 소프트웨어</h2>
<h3 id="서버-osoperating-system">서버 OS(Operating System)</h3>
<ul>
<li>z/OS : Main Frame에서 사용되는 IBM에서 만든 서버용 OS</li>
<li>AIX, hp UX, Oracle Solaris: UNIX에서 사용되는 서버용 OS</li>
<li>Debian, Ubuntu, CentOS: x86에서 주로 사용되는 Customized 된 리눅스 배포판</li>
<li>RedHat, SUSE: OS 자체는 무료지만 기술지원이 유료인 Linux 기반 상용 소프트웨어</li>
<li>Microsoft Windows Server: 마이크로소프트에서 만든 유료 서버용 OS</li>
</ul>
<h3 id="서버-소프트웨어-서버-os-위에-설치">서버 소프트웨어: 서버 OS 위에 설치</h3>
<ul>
<li>Apache, Nginx, Microsoft IIS: 서버가 웹서버의 역할을 하게끔 해주는 소프트웨어</li>
<li>FileZilla: FTP(File Transfer Protocol) 서버</li>
<li>Exchange: 메일 송수신을 위한 서버. SMTP(Simple Mail Transfer Protocol)을 사용</li>
</ul>
<hr>
<h1 id="참고자료">참고자료</h1>
<p><a href="https://inpa.tistory.com/entry/NETWORK-%F0%9F%93%A1-Reverse-Proxy-Forward-Proxy-%EC%A0%95%EC%9D%98-%EC%B0%A8%EC%9D%B4-%EC%A0%95%EB%A6%AC">🌐 Reverse Proxy / Forward Proxy 정의 &amp; 차이 정리</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[LLM] Prompt Engineering]]></title>
            <link>https://velog.io/@jh_yun505/LLM-Prompt-Engineering</link>
            <guid>https://velog.io/@jh_yun505/LLM-Prompt-Engineering</guid>
            <pubDate>Sat, 03 Feb 2024 19:39:33 GMT</pubDate>
            <description><![CDATA[<p>요즘 Chat GPT의 출시로 인해 LLM에 대한 관심이 커져가면서 LLM과 연관된 Prompt Engineering에 대한 관심도 높아지고 있다.
나는 주로 Coursera나 Udemy에서 Tech 관련된 강의를 듣는데
Prompt Engineering에 관한 강의들이 많아지고 있다.
물론 LLM 자체를 개발하는 것도 중요하지만 다양한 분야에 앞으로 LLM이 적용되면서 LLM을 어떻게 <strong>잘</strong> 활용할 것인가?가 중요한 화두가 된 것 같다.</p>
<p>이 글에서는 LLM과 Prompt Engineering에 대해 정리해보고자 한다.</p>
<h1 id="llmlarge-language-models">LLM(Large Language Models)</h1>
<h2 id="llm이란-무엇인가">LLM이란 무엇인가</h2>
<p>LLM(Large Language Model)은 방대한 양의 텍스트 데이터로 훈련을 해서 자연어 이해 및 생성을 하는 모델로 다양한 언어 관련 작업을 진행할 수 있다. GPT-3, BERT, Transformer 와 같은 대규모 언어 모델의 등장 및 발전을 통해 자연어 처리 분야에서 혁신이 일어나고 있다.
현재 GPT-4 모델이 출시되었고 많은 사람들이 사용하는 Chat GPT는 해당 모델을 활용한 AI 기반 대화 시스템이다.</p>
<h2 id="llm의-동작-원리">LLM의 동작 원리</h2>
<h3 id="데이터-학습">데이터 학습</h3>
<p>LLM의 데이터 학습 방식을 이해하기 위해서는 모델이 어떻게 텍스트 데이터를 처리하고 학습하는 지가 중요하다.</p>
<ol>
<li><p>데이터 수집: 일반적으로 인터넷에서 수집되며, 해당 데이터를 통해 모델이 다양한 언어 패턴, 문맥, 어휘를 학습하는 데에 도움이 된다.</p>
</li>
<li><p>데이터 전처리: 수집된 데이터를 토큰화(Tokenization) 과정을 통해 긴 텍스트를 더 작은 단위(토큰)으로 분할하고 모델이 텍스트를 처리할 수 있도록 만든다.</p>
</li>
<li><p>모델 훈련: 토큰화된 데이터는 신경망 훈련에 사용된다. 모델은 다양한 언어적 패턴(텍스트의 문맥, 구문, 의미 등)을 학습한다.</p>
</li>
<li><p>파인 튜닝(fine-tuning): 모델이 특정 작업이나 도메인에 적합하도록 추가적으로 학습하는 과정을 의미한다.</p>
</li>
<li><p>지속적인 학습: 지속적으로 새로운 데이터를 학습하여 최신 정보를 반영하고 성능을 향상한다.</p>
<h3 id="자연어-처리-기술">자연어 처리 기술</h3>
<p>LLM이 언어를 이해하고 생성하기 위해서는 다양한 기술이 필요하다.</p>
</li>
<li><p>Tokenization (토큰화)
<img src="https://velog.velcdn.com/images/jh_yun505/post/cb839c92-9ffb-4857-a428-c9ce0b065010/image.webp" alt="">
출처: <a href="https://teetracker.medium.com/llm-fine-tuning-step-tokenizing-caebb280cfc2">https://teetracker.medium.com/llm-fine-tuning-step-tokenizing-caebb280cfc2</a></p>
<ul>
<li>정의: 토큰화는 긴 텍스트 문자열을 더 작은 단위, 즉 토큰으로 분할하는 과정. 토큰은 단어, 문자, 문장 부호 등이 될 수 있다.</li>
<li>목적: 텍스트를 모델이 처리할 수 있는 형태로 변환하는 것. 토큰화를 통해 복잡한 자연어 데이터가 구조화되고, 모델이 학습할 수 있는 형태로 만들어진다.</li>
</ul>
</li>
<li><p>Embedding (임베딩)</p>
<ul>
<li>정의: 임베딩은 토큰(단어, 문자 등)을 벡터 공간에 매핑하는 과정. 각 토큰은 고차원의 벡터로 변환된다.</li>
<li>목적: 자연어의 의미적, 문맥적 정보를 수치적 형태로 표현하는 것. 단어의 의미, 문맥, 관계 등을 학습한다.</li>
</ul>
</li>
<li><p>Neural Networks (신경망)</p>
<ul>
<li><p>정의: 신경망은 인간의 뇌를 모방한 인공지능의 핵심 구조로, 다수의 노드(뉴런)가 서로 연결되어 복잡한 계산을 수행한다.</p>
</li>
<li><p>종류: LLM에서 주로 사용되는 신경망은 &#39;Transformer&#39; 아키텍처로 Attention 메커니즘을 사용하여 입력 시퀀스의 중요한 부분에 초점을 맞춘다.
<img src="https://velog.velcdn.com/images/jh_yun505/post/100fa8e4-1632-4f87-8747-66466a8487a7/image.png" alt="">
출처: <a href="https://pub.aimind.so/summary-of-transformer-achitecture-c2cef6dcaca6">https://pub.aimind.so/summary-of-transformer-achitecture-c2cef6dcaca6</a></p>
</li>
<li><p>목적: 신경망은 텍스트 데이터에서 패턴을 학습하고, 이를 바탕으로 문장 생성, 질문에 대한 답변, 텍스트 요약 등의 작업을 수행한다.</p>
</li>
</ul>
</li>
</ol>
<h1 id="prompt-engineering">Prompt Engineering</h1>
<h2 id="prompt-engineering이란">Prompt Engineering이란?</h2>
<p>LLM에게 특정한 출력을 유도하기 위해 입력(Prompt)를 설계하는 일이다.
LLM의 성능은 입력되는 프롬프트에 의해 크게 좌우된다.
같은 내용을 질의하더라도 얼마나 상세하게, 어떤 형식으로 질문하냐에 따라 답변의 질이 달라지게 된다.
이러한 중요성이 강조되면서 Prompt Engineering이라는 분야가 주목받게 되었다.</p>
<h2 id="llm과-prompt-engineering">LLM과 Prompt Engineering</h2>
<h3 id="llm과-prompt의-상호작용">LLM과 Prompt의 상호작용</h3>
<p>LLM은 입력된 프롬프트에 따라 출력값이 다르다.
효과적은 Prompt Engineering을 통해 LLM이 보다 정확한 결과를 제공하도록 할 수 있다.</p>
<h3 id="llm의-활용성-높이기">LLM의 활용성 높이기</h3>
<p>Prompt Engineering을 통해 LLM의 성능 최적화 및 다양한 산업에 맞춤형 LLM 모델로 만들 수 있다.</p>
<h2 id="prompt-engineering-관련-강의">Prompt Engineering 관련 강의</h2>
<p><a href="https://www.coursera.org/specializations/prompt-engineering">https://www.coursera.org/specializations/prompt-engineering</a>
<a href="https://www.udemy.com/course/chatgpt-ai-masterclass/">https://www.udemy.com/course/chatgpt-ai-masterclass/</a></p>
<p>추후에 관련 강의를 수강하면서
AI 시대에 어떻게 LLM을 활용할 것인지 공부해보고자 한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Rust] Hot하다고 말만 들었지..]]></title>
            <link>https://velog.io/@jh_yun505/Rust-Hot%ED%95%98%EB%8B%A4%EA%B3%A0-%EB%A7%90%EB%A7%8C-%EB%93%A4%EC%97%88%EC%A7%80</link>
            <guid>https://velog.io/@jh_yun505/Rust-Hot%ED%95%98%EB%8B%A4%EA%B3%A0-%EB%A7%90%EB%A7%8C-%EB%93%A4%EC%97%88%EC%A7%80</guid>
            <pubDate>Sat, 03 Feb 2024 18:52:34 GMT</pubDate>
            <description><![CDATA[<p>우리 학과에서는 학과는 커리큘럼 상 주언어로 Java, Python, C를 사용한다.
다른 언어들(C++, Ocaml, Java script,...)들을 배우긴 하지만 한 학기정도만 사용하게 되고 프로젝트는 돌고 돌아 친숙한 Java나 Python을 사용하게 된다.
그럼에도 불구하고 일명 <strong>HOT</strong>한 언어들은 계속해서 나오고 있는데,
Type Script라든가 Go, Kotlin 등등 여러 언어가 있지만 그 중 하나가 <strong>Rust</strong>였다.</p>
<p>Rust는 안전성, 속도, 병렬 처리를 중심으로 설계된 언어로, 다음과 같은 특징들이 있다.</p>
<ul>
<li>메모리 안전성: 컴파일 시점에서 메모리 안전성을 검사해서 메모리 누수 및 메모리 관련 오류를 방지한다.</li>
<li>소유권 시스템: 각 변수의 데이터에 대한 소유권을 관리하여 데이터 경합과 같은 문제를 효율적으로 관리한다.</li>
<li>병렬 및 동시성 처리: 데이터 경합이 없으므로 안전하게 병렬 처리를 수행할 수 있다.</li>
<li>성능: 저수준 언어의 성능을 유지하면서도 고수준 언어의 추상화를 제공한다.</li>
</ul>
<p>작년에 졸업 프로젝트를 진행하면서 지도교수님이 상담을 해주셨는데 그 중 C/C++언어를 주 언어로 사용하는 팀원에게 교수님이 &quot;자네는 Rust 공부해 볼 생각 없나?&quot;라고 말씀하셨다.</p>
<p>이렇게 Rust를 들어보긴 했지만  실제로 사용해 볼 일도 별로 없고 
같은 프로그램이더라도 Language에 따라 속도가 확연히 차이가 날 수 있다고는 하지만 실감해 본 적이 없었는데 이번에 인턴을 진행하면서 뜻밖의 부분에서 Rust를 마주치게 되었다.</p>
<p>내가 현재 인턴을 진행하는 회사는 Proteomics 관련 회사로,
단백질 분석을 위해 다양한 프로그램들을 사용한다.</p>
<p><img src="https://velog.velcdn.com/images/jh_yun505/post/2fd9a57d-20b4-4d1e-9d48-9d2ecae950a0/image.png" alt="Proteomics 과정"> 출처: <a href="https://www.leibniz-fli.de/research/core-facilities-services/cf-proteomics">https://www.leibniz-fli.de/research/core-facilities-services/cf-proteomics</a></p>
<p>단백질 분석 과정(위의 사진에서 4번 과정)에서는
FASTA file을 읽고, 효소 소화 과정 시뮬레이션을 통해 단백질 서열을 펩타이드로 분해하고, 질량 분석을 위해 B/Y이온을 만드는 과정이 필요하다.
Proteomics Database Search Engine에서 이러한 단백질 서열 분석을 하고 특정한 단백질이나 펩타이드의 존재를 확인하기 위해 해당 기능을 포함하게 된다.</p>
<p>내가 맡은 업무는 아니지만 함께 인턴을 하던 친구가 Fragment Indexing에 Rust를 도입하는 업무를 맡게 되었다.
동일한 Indexing 프로그램을 하나는 C#으로, 다른 하나는 Rust로 작성하였는데
놀랍게도 <strong>C#은 소요 시간 5분, Rust는 50초</strong>가 나왔다.
물론 여러 경우를 생각해봐야겠지만 단순히 생각하면 언어를 바꿔서 소요시간이 1/6이 되었다.
Proteomics도 모르고 Rust를 처음 써본 그 친구가 Fragment Indexing 부분에서 속도를 6배로 높였는데,
만약에 Protemics Database Search Engine이 Rust로 작성되어 있다면?</p>
<p>우리의 멘토링을 담당하시던 박사님이 오픈소스 프로그램 중에서 Rust로 개발된 SAGE를 발견하셨다.</p>
<p><img src="https://velog.velcdn.com/images/jh_yun505/post/77226f12-847c-444c-ad69-fddee745fff6/image.png" alt=""></p>
<p>출처: <a href="https://github.com/lazear/sage">https://github.com/lazear/sage</a></p>
<p>Github 페이지의 Sage 소개글은 다음과 같이 적혀있다.</p>
<blockquote>
<p>Sage: proteomics searching so fast it seems like magic</p>
</blockquote>
<p>정말 마법처럼 보일정도로 빠르다.
박사님은 회의 시작 전에 Search를 돌려놓고 회의 중에 결과가 다 나와버렸다며 아주 기뻐하셨다.
우리 회사는 빠르게 SAGE를 도입하기로 결정했고,
나는 SAGE를 클라우드에서, 그리고 우리의 Web Platform에서 실행하도록 Migration하는 역할을 맡았다.</p>
<p>내가 Proteomics에 대한 지식이 풍부했거나 이 분야에서 오랜 기간 일했다면
이 과정을 통해 배우는 것이 더 많았겠지만
내가 이런 Hot한 언어가 현업에서 사용되는 것을 보면서 느낀 것은</p>
<ul>
<li>프로그램 Language를 변경함으로써 생산성을 말도 안되게 높일 수 있다<ul>
<li>적절한 Language를 선택하는 것도 중요하다</li>
<li>각 언어의 장/단점을 이해하고 있는 것도 도움이 많이 되겠다.</li>
</ul>
</li>
<li>필요한 기능에 대해서 open source 프로그램을 이용하는 것도 좋은 방법이다.</li>
<li>편하다고 안주하지말고 신기술, 새로운 언어를 배우는 것을 멈추지 말자.</li>
</ul>
<p>였다.</p>
<p>잘 모르는 분야에서 일을 하는 것이 물론 힘이 들 때도 있지만<del>(SAGE의 Configuration file을 이해하기 위해서 구글과 ChatGPT와 한참을 싸웠다)</del>
새로운 것을 배운다는 것, 일을 하면서 얻어가는 것이 있다는 것은 정말 즐거운 일이다.</p>
<p>Rust가 Hot한 언어라고 말만 들었을 때의 나와,
실제로 그 Hot한 언어가 어떤 변화를 이끌어내는지 두 눈으로 보고 경험한 나는 분명히 다를 것이다.</p>
]]></description>
        </item>
    </channel>
</rss>