<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>Jin's log</title>
    <link>https://devjk.tistory.com/</link>
    <description>[Nothing changes if nothing changes]

개발 관련 글 위주로 포스팅 할 예정이며, 그 밖에 자기개발/일상/여행에 관한 정보도 포스팅 할 예정입니다.</description>
    <language>ko</language>
    <pubDate>Sun, 12 Apr 2026 08:46:27 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>jinnkimm7</managingEditor>
    <image>
      <title>Jin's log</title>
      <url>https://tistory1.daumcdn.net/tistory/5168565/attach/2adb883e01314929b2f99ed55283e9ed</url>
      <link>https://devjk.tistory.com</link>
    </image>
    <item>
      <title>ERC-20의 구조적 한계와 ERC-20 Permit(EIP-2612)</title>
      <link>https://devjk.tistory.com/entry/ERC-20%EC%9D%98-%EA%B5%AC%EC%A1%B0%EC%A0%81-%ED%95%9C%EA%B3%84%EC%99%80-ERC-20-PermitEIP-2612</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;ERC-20의 구조적 한계&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스마트 컨트랙트에서 ERC-20 토큰을 사용하려면 일반적으로 다음 과정을 거칩니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;사용자가 approve()를 호출하여 컨트랙트에 토큰 사용 권한을 위임&lt;/li&gt;
&lt;li&gt;컨트랙트에서 transferFrom()을 호출하여 실제 토큰을 전송&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, 한 번의 거래를 위해 최소 2개의 트랜잭션이 필요하며, 이로 인해 가스 비용이 불필요하게 증가하게 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또한, 많은 서비스에서는 편의성을 위해 사용자가 &quot;무제한 승인&quot; (approve(uint256.max))을 하는 경우가 많은데, 이 방식은 잠재적인 보안 취약점을 유발할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컨트랙트가 해킹되거나 악의적으로 변경될 경우, 승인된 한도 내에서 사용자의 지갑에서 토큰이 무제한으로 인출될 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요약하면&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ERC-20은 컨트랙트 기반 거래 시 approve &amp;rarr; transferFrom 구조로 인해 가스가 두 번 발생하고, 무제한 승인 방식에서는 보안 리스크가 존재한다는 한계가 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 개선하기 위해 ERC-20 Permit (EIP-2612) 표준이 등장했습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;ERC-20 vs ERC-20 Permit (EIP-2612)&lt;/h2&gt;
&lt;table data-ke-align=&quot;alignLeft&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;구분&lt;/th&gt;
&lt;th&gt;&lt;b&gt;ERC-20&lt;/b&gt;&lt;/th&gt;
&lt;th&gt;&lt;b&gt;ERC-20 Permit (EIP-2612)&lt;/b&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;권한 승인 방식&lt;/td&gt;
&lt;td&gt;&lt;code&gt;approve()&lt;/code&gt; 트랜잭션 필요&lt;/td&gt;
&lt;td&gt;서명(Signature) 기반 승인&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;트랜잭션 수&lt;/td&gt;
&lt;td&gt;&lt;b&gt;최소 2개&lt;/b&gt; (&lt;code&gt;approve&lt;/code&gt; &amp;rarr; &lt;code&gt;transferFrom&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;&lt;b&gt;1개 또는 0개 (가스 없이)&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;가스 비용&lt;/td&gt;
&lt;td&gt;승인 시 가스 발생&lt;/td&gt;
&lt;td&gt;승인 시 &lt;b&gt;가스 없음&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;사용자 경험&lt;/td&gt;
&lt;td&gt;불편 (직접 승인 필요)&lt;/td&gt;
&lt;td&gt;편리 (지갑에서 서명만 하면 됨)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;동작 구조&lt;/td&gt;
&lt;td&gt;Pull 방식&lt;br /&gt;컨트랙트가 토큰을 가져감&lt;/td&gt;
&lt;td&gt;Pull 방식(동일)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;보안 위험&lt;/td&gt;
&lt;td&gt;승인한 만큼 모두 인출 가능&lt;br /&gt;(무제한 승인 시 위험)&lt;/td&gt;
&lt;td&gt;서명 단위로 제한 가능&lt;br /&gt;(세션 기반 권한 설정 가능)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Nonce 사용&lt;/td&gt;
&lt;td&gt;없음&lt;/td&gt;
&lt;td&gt;&lt;b&gt;Nonce 포함 &amp;rarr; Replay Attack 방지&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;지원 지갑/플랫폼&lt;/td&gt;
&lt;td&gt;대부분 지원&lt;/td&gt;
&lt;td&gt;최신 지갑 및 DeFi 플랫폼에서 지원&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;주요 사용 사례&lt;/td&gt;
&lt;td&gt;일반적인 ERC-20 토큰 전송 및 컨트랙트 거래&lt;/td&gt;
&lt;td&gt;DEX (예: Uniswap v3), DeFi, Gasless 거래&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;대표 구현 토큰&lt;/td&gt;
&lt;td&gt;USDT, USDC(예전 버전), LINK 등&lt;/td&gt;
&lt;td&gt;UNI, DAI, USDC(최신), AAVE 등&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;OpenZeppelin 기반 permit 함수&lt;/h2&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;function permit(
    address owner,
    address spender,
    uint256 value,
    uint256 deadline,
    uint8 v,
    bytes32 r,
    bytes32 s
) public virtual override {
    require(block.timestamp &amp;lt;= deadline, &quot;ERC20Permit: expired deadline&quot;);

    bytes32 structHash = keccak256(
        abi.encode(
            _PERMIT_TYPEHASH,
            owner,
            spender,
            value,
            _useNonce(owner),
            deadline
        )
    );

    bytes32 hash = _hashTypedDataV4(structHash);
    address signer = ECDSA.recover(hash, v, r, s);
    require(signer == owner, &quot;ERC20Permit: invalid signature&quot;);

    _approve(owner, spender, value);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Permit을 사용하는 흐름&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;사용자가 지갑에서 메시지에 서명만 함 (트랜잭션 X)&lt;/li&gt;
&lt;li&gt;컨트랙트가 permit() 함수를 호출하며 서명값 전달&lt;/li&gt;
&lt;li&gt;내부적으로 approve()처럼 권한 설정됨&lt;/li&gt;
&lt;li&gt;이후 바로 transferFrom() 가능 &amp;rarr; 1번 트랜잭션으로 거래 끝&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;permit() 함수는 사용자가 트랜잭션 없이 서명만으로 토큰 사용 권한을 위임할 수 있도록 하는 EIP-2612 표준 함수입니다. 기존 approve &amp;rarr; transferFrom 흐름을 1단계로 줄이며, 가스 비용 절감 및 UX 개선에 효과적입니다.&lt;/p&gt;</description>
      <category> &amp;zwj;  Programming/ethereum</category>
      <author>jinnkimm7</author>
      <guid isPermaLink="true">https://devjk.tistory.com/92</guid>
      <comments>https://devjk.tistory.com/entry/ERC-20%EC%9D%98-%EA%B5%AC%EC%A1%B0%EC%A0%81-%ED%95%9C%EA%B3%84%EC%99%80-ERC-20-PermitEIP-2612#entry92comment</comments>
      <pubDate>Sun, 23 Nov 2025 17:28:15 +0900</pubDate>
    </item>
    <item>
      <title>[AWS-CLI] 람다 함수 실행, 실시간 로그 추적, 피지컬 리소스 ID 조회</title>
      <link>https://devjk.tistory.com/entry/AWS-CLI-%EB%9E%8C%EB%8B%A4-%ED%95%A8%EC%88%98-%EC%8B%A4%ED%96%89-%EC%8B%A4%EC%8B%9C%EA%B0%84-%EB%A1%9C%EA%B7%B8-%EC%B6%94%EC%A0%81-%ED%94%BC%EC%A7%80%EC%BB%AC-%EB%A6%AC%EC%86%8C%EC%8A%A4-ID-%EC%A1%B0%ED%9A%8C</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;AWS로 개발을 진행하면서, 콘솔을 사용하기 번거로울 때, 프로필을 등록해 CLI로 개발 및 디버깅을 하면 편리합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오늘은 개발 하면서 자주 사용했던 람다 실행, 실시간 로그 추적 cli에 대해서 정리하려고 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;람다를 실행하거나 실시간 로그를 추적하기 위해서는 우선 람다의 피지컬 리소스를 알아야합니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;피지컬 리소스 ID 조회&lt;/h2&gt;
&lt;pre class=&quot;stata&quot;&gt;&lt;code&gt;aws cloudformation describe-stack-resources --stack-name test-api-dev \
  --query &quot;StackResources[?LogicalResourceId=='TestScheduler'].PhysicalResourceId&quot; --output text --profile profile-test&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;--stack-name 뒤에, 조회할 스택을 선택하고,&lt;/li&gt;
&lt;li&gt;TestScheduler에 template.yaml에 정의한 람다의 logical 이름을 넣어주면됨.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;람다 실행&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;조회한 피지컬 리소스 ID를 활용하여 람다를 실행합니다.&lt;/p&gt;
&lt;pre class=&quot;smali&quot;&gt;&lt;code&gt;❯ aws lambda invoke \
  --function-name test-api-dev-Scheduler-D81uo743BHIW \
  --profile profile-test \
  output.json&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;--function-name 뒤에 람다 함수 피지컬 리소스를 찾아 넣어주고,&lt;/li&gt;
&lt;li&gt;--profile 뒤에 프로필을 선택하여 cli를 실행하면 결과가 output.json에 나옴&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;실시간 로그 추적&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;조회한 피지컬 리소스 ID를 활용하여 실시간으로 로그를 추적합니다.&lt;/p&gt;
&lt;pre class=&quot;jboss-cli&quot;&gt;&lt;code&gt;aws logs tail /aws/lambda/test-api-dev-Scheduler-D81uo743BHIW \
  --profile profile-test \
  --follow&lt;/code&gt;&lt;/pre&gt;</description>
      <category>⚙️ Tool/AWS</category>
      <category>AWS</category>
      <category>CLI</category>
      <author>jinnkimm7</author>
      <guid isPermaLink="true">https://devjk.tistory.com/91</guid>
      <comments>https://devjk.tistory.com/entry/AWS-CLI-%EB%9E%8C%EB%8B%A4-%ED%95%A8%EC%88%98-%EC%8B%A4%ED%96%89-%EC%8B%A4%EC%8B%9C%EA%B0%84-%EB%A1%9C%EA%B7%B8-%EC%B6%94%EC%A0%81-%ED%94%BC%EC%A7%80%EC%BB%AC-%EB%A6%AC%EC%86%8C%EC%8A%A4-ID-%EC%A1%B0%ED%9A%8C#entry91comment</comments>
      <pubDate>Wed, 19 Nov 2025 21:08:57 +0900</pubDate>
    </item>
    <item>
      <title>[Docker] Docker로 MySQL 띄우기</title>
      <link>https://devjk.tistory.com/entry/Docker-Docker%EB%A1%9C-MySQL-%EB%9D%84%EC%9A%B0%EA%B8%B0</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;Docker로 MySQL 실행하기&lt;/h2&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;docker run --name mysql-container -e MYSQL_ROOT_PASSWORD=1234 -d -p 3306:3306 mysql:latest&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;--name : 컨테이너 이름 설정&lt;/li&gt;
&lt;li&gt;-e : 환경변수를 설정&lt;/li&gt;
&lt;li&gt;-e MYSQL_ROOT_PASSWORD= : MySQL의 root 권한의 패스워드 설정&lt;/li&gt;
&lt;li&gt;-d : detach 모드로 컨테이너가 실행됩니다. 컨테이너가 백그라운드로 실행된다고 보면 됩니다.&lt;/li&gt;
&lt;li&gt;-p &amp;lt;호스트 포트&amp;gt; &amp;lt;컨테이너 포트&amp;gt; : 호스트와 컨테이너의 포트를 연결합니다.&lt;/li&gt;
&lt;li&gt;mysql:latest : 컨테이너에 사용할 이미지 버전을 설정합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Docker Compose&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트 루트에 docker-compose.yaml을 생성 후, 아래와 같이 작성&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;version: '3.8' # 파일 포맷 버전 지정

services:
  mysql:
    image: mysql:latest # MySQL 최신 버전 사용 혹은 8.0(안정적인 버전) 사용
    container_name: opensea-mysql # 컨테이너 이름 지정
    environment:
      MYSQL_ROOT_PASSWORD: 1234 # 루트 비밀번호 설정
      MYSQL_DATABASE: opensea # 기본 데이터베이스 생성
    ports:
      - '3305:3306' # 호스트의 3305 포트를 컨테이너의 3306 포트에 매핑
    volumes:
      - mysql-data:/var/lib/mysql # 데이터 영속성을 위한 볼륨 마운트

volumes:
  mysql-data: # 데이터를 스토리지에 저장하는데, 그 스토리지 공간을 제공합니다.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 작성하면 아래와 같은 연결정보가 설정됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;호스트: localhost&lt;br /&gt;포트: 3305&lt;br /&gt;데이터베이스: opensea&lt;br /&gt;사용자: root&lt;br /&gt;비밀번호: 1234&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;CLI&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실행&lt;/p&gt;
&lt;pre class=&quot;ebnf&quot;&gt;&lt;code&gt;docker-compose up -d &lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;중지&lt;/p&gt;
&lt;pre class=&quot;ebnf&quot;&gt;&lt;code&gt;docker-compose down&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터까지 완전 삭제&lt;/p&gt;
&lt;pre class=&quot;ebnf&quot;&gt;&lt;code&gt;docker-compose down -v&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;참고&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://hipopatamus.tistory.com/109&quot;&gt;Docker에 MySQL 띄우기&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://seosh817.tistory.com/387#google_vignette&quot;&gt;도커 컴포즈 - 개념 정리 및 사용법&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>⚙️ Tool/Docker</category>
      <author>jinnkimm7</author>
      <guid isPermaLink="true">https://devjk.tistory.com/90</guid>
      <comments>https://devjk.tistory.com/entry/Docker-Docker%EB%A1%9C-MySQL-%EB%9D%84%EC%9A%B0%EA%B8%B0#entry90comment</comments>
      <pubDate>Fri, 31 Oct 2025 11:37:55 +0900</pubDate>
    </item>
    <item>
      <title>[DynamoDB] DynamoDB 로컬 연결</title>
      <link>https://devjk.tistory.com/entry/DynamoDB-DynamoDB-%EB%A1%9C%EC%BB%AC-%EC%97%B0%EA%B2%B0</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. NoSQL Workbench로 로컬 연결&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;NoSQL Workbench 설치하기&lt;/p&gt;
&lt;div style=&quot;background-color: #ffffff; color: #0f141a; text-align: start;&quot;&gt;
&lt;div&gt;
&lt;div&gt;&lt;a title=&quot;Download NoSQL Workbench for DynamoDB&quot; href=&quot;https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/workbench.settingup.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Download NoSQL Workbench for DynamoDB&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;background-color: #ffffff; color: #0f141a; text-align: start;&quot;&gt;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;NoSQL Workbench 설치 후, DDB local 실행하기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screenshot 2025-07-25 at 2.40.10 PM.png&quot; data-origin-width=&quot;2770&quot; data-origin-height=&quot;1782&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SVdC0/btsPAKy1pad/4VHelZ3s6YcTnAjCIuZIVK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SVdC0/btsPAKy1pad/4VHelZ3s6YcTnAjCIuZIVK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SVdC0/btsPAKy1pad/4VHelZ3s6YcTnAjCIuZIVK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSVdC0%2FbtsPAKy1pad%2F4VHelZ3s6YcTnAjCIuZIVK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2770&quot; height=&quot;1782&quot; data-filename=&quot;Screenshot 2025-07-25 at 2.40.10 PM.png&quot; data-origin-width=&quot;2770&quot; data-origin-height=&quot;1782&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;8000포트로 DynamoDB 로컬 실행하기&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screenshot 2025-07-25 at 2.43.34 PM.png&quot; data-origin-width=&quot;2790&quot; data-origin-height=&quot;1778&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dgCDru/btsPzQmDhoI/WkSjUrEnRb3xUykK1o4T10/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dgCDru/btsPzQmDhoI/WkSjUrEnRb3xUykK1o4T10/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dgCDru/btsPzQmDhoI/WkSjUrEnRb3xUykK1o4T10/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdgCDru%2FbtsPzQmDhoI%2FWkSjUrEnRb3xUykK1o4T10%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2790&quot; height=&quot;1778&quot; data-filename=&quot;Screenshot 2025-07-25 at 2.43.34 PM.png&quot; data-origin-width=&quot;2790&quot; data-origin-height=&quot;1778&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실행 후, 로컬 다이나모디비가 실행중인지 명령어로 확인&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;lsof -i :8000
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screenshot 2025-07-25 at 2.43.58 PM.png&quot; data-origin-width=&quot;2790&quot; data-origin-height=&quot;1778&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/OC1lS/btsPAnxBs4c/NIKMfO4ZtqHfhCWJIFlrPk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/OC1lS/btsPAnxBs4c/NIKMfO4ZtqHfhCWJIFlrPk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/OC1lS/btsPAnxBs4c/NIKMfO4ZtqHfhCWJIFlrPk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FOC1lS%2FbtsPAnxBs4c%2FNIKMfO4ZtqHfhCWJIFlrPk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2790&quot; height=&quot;1778&quot; data-filename=&quot;Screenshot 2025-07-25 at 2.43.58 PM.png&quot; data-origin-width=&quot;2790&quot; data-origin-height=&quot;1778&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실행후, 테스트 테이블 만들기&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테이블 생성 후&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로컬 다이나모디비에 생성된 테이블 리스트 확인&lt;/p&gt;
&lt;pre class=&quot;dsconfig&quot;&gt;&lt;code&gt;aws dynamodb list-tables --endpoint-url &amp;lt;http://localhost:8000&amp;gt; --profile profile.id
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screenshot 2025-07-25 at 2.44.50 PM.png&quot; data-origin-width=&quot;2790&quot; data-origin-height=&quot;1780&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DYqbu/btsPAjB9a2U/2xQPBfYPyhAcygVCBvvJIK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DYqbu/btsPAjB9a2U/2xQPBfYPyhAcygVCBvvJIK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DYqbu/btsPAjB9a2U/2xQPBfYPyhAcygVCBvvJIK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDYqbu%2FbtsPAjB9a2U%2F2xQPBfYPyhAcygVCBvvJIK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2790&quot; height=&quot;1780&quot; data-filename=&quot;Screenshot 2025-07-25 at 2.44.50 PM.png&quot; data-origin-width=&quot;2790&quot; data-origin-height=&quot;1780&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screenshot 2025-07-25 at 2.45.15 PM.png&quot; data-origin-width=&quot;2778&quot; data-origin-height=&quot;1772&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/w9W4A/btsPynZ9tPO/CiR3kor8Q7aEleaUIzb1Bk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/w9W4A/btsPynZ9tPO/CiR3kor8Q7aEleaUIzb1Bk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/w9W4A/btsPynZ9tPO/CiR3kor8Q7aEleaUIzb1Bk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fw9W4A%2FbtsPynZ9tPO%2FCiR3kor8Q7aEleaUIzb1Bk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2778&quot; height=&quot;1772&quot; data-filename=&quot;Screenshot 2025-07-25 at 2.45.15 PM.png&quot; data-origin-width=&quot;2778&quot; data-origin-height=&quot;1772&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;로컬 다이나모디비에 아이템 넣기&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;aws dynamodb put-item \
  --endpoint-url http://localhost:8000 \
  --table-name TestTable \
  --item '{
    &quot;PK&quot;: {&quot;S&quot;: &quot;test#1&quot;},
    &quot;SK&quot;: {&quot;S&quot;: &quot;1&quot;},
    &quot;description&quot;: {&quot;S&quot;: &quot;test&quot;}
  }' --profile profile.id&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;Screenshot 2025-07-25 at 3.21.29 PM.png&quot; data-origin-width=&quot;2786&quot; data-origin-height=&quot;1782&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d5yUKe/btsPy2uu44s/VMfLLMj3msFlhnNgPtR9x1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d5yUKe/btsPy2uu44s/VMfLLMj3msFlhnNgPtR9x1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d5yUKe/btsPy2uu44s/VMfLLMj3msFlhnNgPtR9x1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd5yUKe%2FbtsPy2uu44s%2FVMfLLMj3msFlhnNgPtR9x1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2786&quot; height=&quot;1782&quot; data-filename=&quot;Screenshot 2025-07-25 at 3.21.29 PM.png&quot; data-origin-width=&quot;2786&quot; data-origin-height=&quot;1782&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;혹은 람다로 넣어 보고 싶다면 아래와 같이 설정하면 됩니다.&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;export const docClient = DynamoDBDocumentClient.from(new DynamoDBClient({
  region: &quot;ap-northeast-2&quot;,
  endpoint: 'http://host.docker.internal:8000',
  credentials: {
    accessKeyId: &quot;dummy&quot;,
    secretAccessKey: &quot;dummy&quot;,
  },
}),
{
  marshallOptions: {
    convertEmptyValues: false,
    removeUndefinedValues: true,
    convertClassInstanceToMap: true,
  },
});&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;왜 host.docker.internal을 쓰는가?&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;localhost &amp;rarr; Docker 컨테이너 자기 자신 (DynamoDB 없음)&lt;/li&gt;
&lt;li&gt;host.docker.internal &amp;rarr; Docker 컨테이너에서 &lt;b&gt;호스트 머신의 DynamoDB Local&lt;/b&gt;에 접근&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. Docker로 로컬 연결&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;도커로 다이나모디비 이미지 설치&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;docker pull amazon/dynamodb-local&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;혹시나 포트가 겹치는 경우, 포트를 바꿔서 띄우기&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;docker run -d -p 8001:8000 --name dynamodb amazon/dynamodb-local
&lt;/code&gt;&lt;/pre&gt;</description>
      <category>  CS/Database</category>
      <category>AWS</category>
      <category>dynamodb</category>
      <author>jinnkimm7</author>
      <guid isPermaLink="true">https://devjk.tistory.com/89</guid>
      <comments>https://devjk.tistory.com/entry/DynamoDB-DynamoDB-%EB%A1%9C%EC%BB%AC-%EC%97%B0%EA%B2%B0#entry89comment</comments>
      <pubDate>Fri, 25 Jul 2025 15:53:38 +0900</pubDate>
    </item>
    <item>
      <title>[DynamoDB] 키 디자인 패턴</title>
      <link>https://devjk.tistory.com/entry/DynamoDB-%ED%82%A4-%EB%94%94%EC%9E%90%EC%9D%B8-%ED%8C%A8%ED%84%B4</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;DynamoDB 테이블 구조&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;아이템(보통 RDBMS에서는 로우라고 부름)&lt;/li&gt;
&lt;li&gt;어트리뷰트(보통 RDBMS에서는 컬럼이라고 부름)&lt;/li&gt;
&lt;li&gt;파티션키(PK) : PK가 있기때문에 테이블의 크기가 아무리 크더라도 동일한 시간에 특정 아이템을 검색할 수 있음.&lt;/li&gt;
&lt;li&gt;정렬키(SK) : SK를 통해서 1:N 관계 모델링을 할 수 있음.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;데이터베이스 스케일링&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;트래픽이 증가할 때, 높은 성능이 필요한 경우 RDBMS는 스케일 업을 선택함. 하지만 NoSQL은 처음부터 대규모 트래픽을 목적으로 만들어졌기때문에 스케일 아웃 전략을 선택함.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다면 기본 전제는 수평으로 확장 가능한 데이터를 어떻게 설계할 것인가임.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 머신들을 골고루 잘 사용할 수 있도록 설계해야함.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러 개의 파티션이 골고루 사용될 수 있도록 키 디자인 하는 것이 중요함.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;제약 조건&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;RCU : 4 KB per second&lt;/li&gt;
&lt;li&gt;WCU : 1 KB per second&lt;/li&gt;
&lt;li&gt;RCU와 WCU는 독립적으로 동작&lt;/li&gt;
&lt;li&gt;테이블에 아이템을 원하는 수만큼 추가 가능함.&lt;/li&gt;
&lt;li&gt;아이템의 최대 크기는 400 KB이지만, 이 모두를 사용하는 것은 비권장&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*다이나모 디비가 잘하는 것은 무수한 아이템 중 PK, SK 조합으로 유니크한 아이템을 빠른 찾아서 리턴하는 것임.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;스케일링은 파티셔닝을 통해서 이루어짐&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;데이터 읽기&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쿼리가 아닌 REST API를 통해서 데이터를 읽어옴.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;GSI&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추가적인 검색조건이 필요한 경우 기존 테이블을 마이그레이션 하지 않고, GSI를 자유롭게 추가하거나 삭제하여 요구조건에 대응하면 됨.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;LSI&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;베이스 테이블의 동일한 PK를 사용하고, GSI와는 달리 테이블 생성시에만 생성이 가능함. 사용하는 것을 권장하지 않음.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Tenet&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;DynamoDB 데이터 모델링 Tenet&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;모든 엑세스 패턴을 식별&lt;/li&gt;
&lt;li&gt;조인과 같은 복잡한 연산이 불가능하기 때문에 데이터를 결과셋 형식으로 미리 입력해 두는 것이 필요함.&lt;/li&gt;
&lt;li&gt;관계형 디자인 패턴을 피하고, 하나의 테이블로 시작&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;싱글 테이블 디자인&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;모든 엔티티를 하나의 테이블로 설계하는 방법&lt;/li&gt;
&lt;li&gt;적은 운영 부담, 높은 테이블 최대 성능 및 쓰로틀링 경감&lt;/li&gt;
&lt;li&gt;높은 러닝 커브, 다른 액세스 패턴의 엔티티&lt;/li&gt;
&lt;li&gt;안티 패턴
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;PK를 UserID로 고정하고 시작하는 습관&lt;/li&gt;
&lt;li&gt;엔티티 별로 테이블을 만드려는 습관&lt;/li&gt;
&lt;li&gt;GSI를 많이 사용하려는 습관&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;싱글테이블 디자인 예제&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;순서&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;비지니스 유스 케이스 이해하기&lt;/li&gt;
&lt;li&gt;ER 다이어그램 그리기&lt;/li&gt;
&lt;li&gt;모든 데이터 액세스 패턴 정리하기&lt;/li&gt;
&lt;li&gt;키 디자인 시작하기&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;참고&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 키 디자인 패턴 -&amp;nbsp;&lt;a href=&quot;https://youtu.be/I7zcRxHbo98?si=M5\_Brn0eo0svBZaR&amp;amp;t=1759&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://youtu.be/I7zcRxHbo98?si=M5\_Brn0eo0svBZaR&amp;amp;t=1759&lt;/a&gt;&lt;/p&gt;</description>
      <category>  CS/Database</category>
      <category>dynamodb</category>
      <category>nosql</category>
      <author>jinnkimm7</author>
      <guid isPermaLink="true">https://devjk.tistory.com/88</guid>
      <comments>https://devjk.tistory.com/entry/DynamoDB-%ED%82%A4-%EB%94%94%EC%9E%90%EC%9D%B8-%ED%8C%A8%ED%84%B4#entry88comment</comments>
      <pubDate>Thu, 17 Jul 2025 00:18:06 +0900</pubDate>
    </item>
    <item>
      <title>[JS] 데이터타입 / 원시 값과 객체의 비교</title>
      <link>https://devjk.tistory.com/entry/JS-%EB%8D%B0%EC%9D%B4%ED%84%B0%ED%83%80%EC%9E%85-%EC%9B%90%EC%8B%9C-%EA%B0%92%EA%B3%BC-%EA%B0%9D%EC%B2%B4%EC%9D%98-%EB%B9%84%EA%B5%90</link>
      <description>&lt;h2&gt;데이터 타입 분류&lt;/h2&gt;
&lt;p&gt;자바스크립트의 데이터 타입은 크게 두 가지로 분류됩니다.&lt;/p&gt;
&lt;p&gt;Primitive Type : String, Number, boolean, null, undefined, Symbol&lt;br&gt;Reference Type : Object - Array, function RegExp, Set, Map ...&lt;/p&gt;
&lt;p&gt;참고로 자바스크립트 메모리는 스택과 힙 영역으로 구분되어 있는데, Primitive Type은 스택 영역에 Reference Type은 힙 영역에 저장됩니다.&lt;/p&gt;</description>
      <category> &amp;zwj;  Programming/JavaScript</category>
      <category>자바스크립트</category>
      <author>jinnkimm7</author>
      <guid isPermaLink="true">https://devjk.tistory.com/87</guid>
      <comments>https://devjk.tistory.com/entry/JS-%EB%8D%B0%EC%9D%B4%ED%84%B0%ED%83%80%EC%9E%85-%EC%9B%90%EC%8B%9C-%EA%B0%92%EA%B3%BC-%EA%B0%9D%EC%B2%B4%EC%9D%98-%EB%B9%84%EA%B5%90#entry87comment</comments>
      <pubDate>Wed, 16 Jul 2025 21:37:18 +0900</pubDate>
    </item>
    <item>
      <title>[AWS] SAM local 실행 중 오류 Address already in usePort 3000 is in use by another program.</title>
      <link>https://devjk.tistory.com/entry/AWS-SAM-local-%EC%8B%A4%ED%96%89-%EC%A4%91-%EC%98%A4%EB%A5%98-Address-already-in-usePort-3000-is-in-use-by-another-program</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;SAM 람다 함수를 테스트 하기 위해 로컬로 실행 시, 아래와 같은 메세지를 자주 봤습니다.&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;Address already in use
Port 3000 is in use by another program.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3000 포트를 다른 프로그램이 사용하고 있다는 말이기 때문에 3000 포트 PID를 찾아 종료해주면 됩니다.&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;❯ lsof -i :3000
COMMAND   PID USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
sam     88428  jin 2314u  IPv4 0xab2efde4a0974aa1      0t0  TCP localhost:hbci (LISTEN)

❯ kill 88428&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;혹은 다른 포트를 사용하면 됩니다.&lt;/p&gt;
&lt;pre class=&quot;livecodeserver&quot;&gt;&lt;code&gt;sam local start-api --port 3001&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;포트를 종료하거나 다른 포트로 실행한다해도 아래와 같은 오류가 뜨는 경우가 있었습니다.&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;Internal Server Error (&quot;failed to set up container networking:
driver failed programming external connectivity on endpoint youthful_dirac
(e0ab6872a7a8dcf54b02795f2be1609e751434f622a0080d17652930ae814fec): Bind for
127.0.0.1:6517 failed: port is already allocated&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;chat gpt의 도움을 받아 해결했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Docker가 내부적으로 포트를 &quot;유령 상태&quot;로 기억 중일 수 있음 (네트워크 리소스 미정리)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Docker가 이전 컨테이너의 네트워크 리소스를 제대로 해제하지 못해서 &lt;b&gt;포트가 이미 할당된 것처럼 인식&lt;/b&gt;하는 경우입니다. 특히 컨테이너가 강제 종료되었거나 Docker가 재시작되는 도중 네트워크가 꼬이면 자주 발생합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;  해결 방법:&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;docker network prune&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;⚠️ 이 명령은 사용하지 않는 Docker 네트워크를 모두 삭제합니다. 실행 전 주의!&lt;/p&gt;
&lt;/blockquote&gt;</description>
      <category>⚙️ Tool/AWS</category>
      <category>AWS</category>
      <category>Sam</category>
      <author>jinnkimm7</author>
      <guid isPermaLink="true">https://devjk.tistory.com/86</guid>
      <comments>https://devjk.tistory.com/entry/AWS-SAM-local-%EC%8B%A4%ED%96%89-%EC%A4%91-%EC%98%A4%EB%A5%98-Address-already-in-usePort-3000-is-in-use-by-another-program#entry86comment</comments>
      <pubDate>Wed, 18 Jun 2025 00:15:02 +0900</pubDate>
    </item>
    <item>
      <title>[AWS] AWS CLI 프로파일 목록 확인 및 삭제</title>
      <link>https://devjk.tistory.com/entry/AWS-AWS-CLI-%ED%94%84%EB%A1%9C%ED%8C%8C%EC%9D%BC-%EB%AA%A9%EB%A1%9D-%ED%99%95%EC%9D%B8-%EB%B0%8F-%EC%82%AD%EC%A0%9C</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;계정 확인 방법&lt;/h2&gt;
&lt;pre class=&quot;dsconfig&quot;&gt;&lt;code&gt;❯ aws configure list-profiles
default
jin
jin2
jin3&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;삭제 방법&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;터미널에서 아래 명령어로 AWS 설정 파일을 엽니다.&lt;/p&gt;
&lt;pre class=&quot;arcade&quot;&gt;&lt;code&gt;nano ~/.aws/credentials&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또는&lt;/p&gt;
&lt;pre class=&quot;awk&quot;&gt;&lt;code&gt;code ~/.aws/credentials  # VS Code로 여는 경우&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;삭제하고 싶은 프로파일의 항목을 찾고 아래와 같이 제거합니다&lt;/p&gt;
&lt;pre class=&quot;ini&quot;&gt;&lt;code&gt;[jin3]
aws_access_key_id = AKIAXXXXXXXXXXXXX
aws_secret_access_key = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;같은 방식으로 ~/.aws/config 파일도 열어서 해당 프로파일 항목이 있으면 삭제합니다:&lt;/p&gt;
&lt;pre class=&quot;arcade&quot;&gt;&lt;code&gt;nano ~/.aws/config&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;ini&quot;&gt;&lt;code&gt;[profile jin3]
region = ap-northeast-2
output = json&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 전체 블록을 삭제한 후 저장(Ctrl + O)하고 종료(Ctrl + X)합니다.&lt;/p&gt;</description>
      <category>⚙️ Tool/AWS</category>
      <category>AWS</category>
      <author>jinnkimm7</author>
      <guid isPermaLink="true">https://devjk.tistory.com/85</guid>
      <comments>https://devjk.tistory.com/entry/AWS-AWS-CLI-%ED%94%84%EB%A1%9C%ED%8C%8C%EC%9D%BC-%EB%AA%A9%EB%A1%9D-%ED%99%95%EC%9D%B8-%EB%B0%8F-%EC%82%AD%EC%A0%9C#entry85comment</comments>
      <pubDate>Tue, 27 May 2025 12:21:45 +0900</pubDate>
    </item>
    <item>
      <title>[Next.js] Rendering</title>
      <link>https://devjk.tistory.com/entry/Nextjs-Rendering</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;What is Rendering?&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Rendering is the process of transforming the component code you write into UI that users can see and interact with&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;In Next.js, the tricky part to building a performant application is figuring out when and where this transformation should happen.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CSR, SSR and RSCs?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Rendering in React &amp;rarr; Rendering in Next.js&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;How rendering works in React - CSR&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1408&quot; data-origin-height=&quot;822&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MhGrY/btsMWIq4cao/TmC5BU5SHQDZeaygVD7m3k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MhGrY/btsMWIq4cao/TmC5BU5SHQDZeaygVD7m3k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MhGrY/btsMWIq4cao/TmC5BU5SHQDZeaygVD7m3k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMhGrY%2FbtsMWIq4cao%2FTmC5BU5SHQDZeaygVD7m3k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1408&quot; height=&quot;822&quot; data-origin-width=&quot;1408&quot; data-origin-height=&quot;822&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Client Side Rendering&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;This whole approach - where your browser transforms React components into what you see on screen - that is what we call client-side rendering&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Drawbacks of CSR&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;SEO
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;When search engines crawl your site, they are mainly looking at HTML content. But with CSR, your initial HTML is basically just an empty div - not great for search engines trying to figure out what your page is about&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Performance
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Your browser(the client) has to do everything: fetch data, build the UI, make everything interactive. that&amp;rsquo;s a lot of work!&lt;/li&gt;
&lt;li&gt;Users often end up staring at a blank screen or loading spinner while all this happens.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Server Side Rendering&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1518&quot; data-origin-height=&quot;812&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ITcY8/btsMXoMdwjI/dLyamMRPhWbRxsKqm2lUZ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ITcY8/btsMXoMdwjI/dLyamMRPhWbRxsKqm2lUZ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ITcY8/btsMXoMdwjI/dLyamMRPhWbRxsKqm2lUZ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FITcY8%2FbtsMXoMdwjI%2FdLyamMRPhWbRxsKqm2lUZ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1518&quot; height=&quot;812&quot; data-origin-width=&quot;1518&quot; data-origin-height=&quot;812&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Server-side solutions&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Search engines can now easily index the server-rendered content, solving our SEO problem.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Users see actual HTML content right away instead of staring at a blank screen or loading spinner.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Static Site Generation (SSG)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;SSG happens during build time when you deploy your application to the server.&lt;/li&gt;
&lt;li&gt;This results in pages that are already rendered and ready to serve. It&amp;rsquo;s perfect for content that stays relatively stable, like blog posts.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Server-Side Rendering (SSR)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;SSR renders pages on-demand when users request them. It&amp;rsquo;s ideal for personalized content like social media feeds where the HTML changes based on who&amp;rsquo;s logged in.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Hydration&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;During hydration, React takes control in the browser and reconstructs the component tree in memory, using the server-rendered HTML as a blueprint.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;This involves initializing application state, adding click and mouseover handler, and setting up all the dynamic features needed for a full interactive user experience.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Drawbacks of SSR - All or nothing&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;You have to fetch everything before you can show anything. We can&amp;rsquo;t start rendering HTML until all data is fetched on the server.&lt;/li&gt;
&lt;li&gt;You have to fetch everything before you can hydrate anything. We need to wait for all JS to load on the client before hydration can begin.&lt;/li&gt;
&lt;li&gt;You have to hydrate everything before you can interact with anything. Every component needs to be hydrated before any of them become interactive.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;This becomes really inefficient when some parts of your app are slower than others, as is often the case in real-world apps.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Suspense SSR architecture&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;use the component to unlock two major SSR features:&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;HTML streaming on the server
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;HTML streaming solves our first problem: You don&amp;rsquo;t have to fetch everything before you can show anything&lt;/li&gt;
&lt;li&gt;If a particular section is slow and could potentially delay the initial HTML, NP!&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1418&quot; data-origin-height=&quot;738&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Cicij/btsMVhOYKuj/S8JERmzH1pXM31qiB9OhJ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Cicij/btsMVhOYKuj/S8JERmzH1pXM31qiB9OhJ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Cicij/btsMVhOYKuj/S8JERmzH1pXM31qiB9OhJ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FCicij%2FbtsMVhOYKuj%2FS8JERmzH1pXM31qiB9OhJ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1418&quot; height=&quot;738&quot; data-origin-width=&quot;1418&quot; data-origin-height=&quot;738&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; start=&quot;2&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Selective hydration on the client
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;By wrapping your main section in a &lt;code&gt;&amp;lt;Suspense&amp;gt;&lt;/code&gt; component, you&amp;rsquo;re not just enablign streaming but also telling React it&amp;rsquo;s okay to hydrate other parts of the page before everything&amp;rsquo;s ready.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;The Evolution of React&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CSR &amp;rarr; SSR &amp;rarr; Suspense for SSR&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Suspense for SSR brought us closer to a seamless rendering experience.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;But, we still have challenges&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Large bundle sizes causing excessive downloads for users&lt;/li&gt;
&lt;li&gt;Unnecessary hydration delaying interactivity&lt;/li&gt;
&lt;li&gt;Heavy client-side processing leading to poorer performance&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;React Server Components (RSC)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RSC represent a new architecture designed by React team.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;This approach leverages the strengths of both server and client environments to optimize efficiency, load times, and interactivity&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;The architecture introduces a dual-component model&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;CSR&lt;/li&gt;
&lt;li&gt;SSR&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;This distinction is based not on the component&amp;rsquo;s functionality but rather on their execution environment and the specific systems they are designed to interact with.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Server Components handle data fetching and static rendering, while Client Components take care of rendering the interactive elements.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;RSC + Next.js&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Every component in a Next.js app defaults to being a server component&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Running components on the server brings several advantages: aero-bundle size, direct access to server-side resources, improved security, and better SEO.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;But, Server components can&amp;rsquo;t interact with browser APIs or handle user interactions.&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;// about/page.tsx

import { useState } from &quot;react&quot;;

export default function About() {
  const [name, setName] = useState(&quot;&quot;);
  return &amp;lt;h1&amp;gt;about page!&amp;lt;/h1&amp;gt;;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1482&quot; data-origin-height=&quot;1082&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Lrwqf/btsMWvFs56b/PSQvHJ7Ciw1zpRV4JSoTiK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Lrwqf/btsMWvFs56b/PSQvHJ7Ciw1zpRV4JSoTiK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Lrwqf/btsMWvFs56b/PSQvHJ7Ciw1zpRV4JSoTiK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLrwqf%2FbtsMWvFs56b%2FPSQvHJ7Ciw1zpRV4JSoTiK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1482&quot; height=&quot;1082&quot; data-origin-width=&quot;1482&quot; data-origin-height=&quot;1082&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;To create components, add the &amp;lsquo;use client&amp;rsquo; directive at the top of the file.&lt;/li&gt;
&lt;li&gt;Server components are rendered exclusively on the server.&lt;/li&gt;
&lt;li&gt;Client components are rendered once on the server and then on the client.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Reference&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=6-qMfLcPhOw&amp;amp;list=PLC3y8-rFHvwhIEc4I4YsRz5C7GOBnxSJY&amp;amp;index=47&quot;&gt;https://www.youtube.com/watch?v=6-qMfLcPhOw&amp;amp;list=PLC3y8-rFHvwhIEc4I4YsRz5C7GOBnxSJY&amp;amp;index=47&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category> &amp;zwj;  Programming/Next.js</category>
      <category>next.js</category>
      <author>jinnkimm7</author>
      <guid isPermaLink="true">https://devjk.tistory.com/84</guid>
      <comments>https://devjk.tistory.com/entry/Nextjs-Rendering#entry84comment</comments>
      <pubDate>Tue, 25 Mar 2025 22:44:46 +0900</pubDate>
    </item>
    <item>
      <title>[Next.js] Next.js 소개</title>
      <link>https://devjk.tistory.com/entry/Nextjs-Nextjs-%EC%86%8C%EA%B0%9C</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;Introduction&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Next.js is a React framework for building full-stack web application.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리액트만으로 애플리케이션을 구축할 때 모든 기능을 갖춘 애플리케이션을 만드는 것은 실행 불가능합니다. 리액트는 유저 인터페이스를 구축하는 라이브러이고, 라우팅, 데이터 페칭 등등 과 같은 다른 기능에 대한 결정을 해야합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Next.js는 유저 인터페이스를 위해 리액트를 사용하고, 어플리케이션을 위한 추가적인 기능을 제공합니다. 그것에는 라우팅, 최적화된 렌더링, 데이터 페칭, 번들링, 컴파일링 등이 있습니다. Next.js는 필요한 패키지를 모두 제공하기 때문에 추가적인 패키지를 설치할 필요가 없습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 이러한 특징들을 구현하기 위해 따라야할 컨벤션이 있습니다. (프레임워크의 특징)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Next.js는 웹 어플리케이션을 만드는 과정을 간소화합니다. Next.js가 제공하는 기능은 다음과 같습니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;라우팅
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;파일 기반 경로로 라우팅을 간소화합니다. 파일을 만들기만하면 경로가 자동으로 생성됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;API routes&lt;/li&gt;
&lt;li&gt;렌더링
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;서버사이드 렌더링과 클라이언트 사이드 렌더링을 모두 지원하기 때문에 성능과 SEO가 향상됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;데이터 페칭
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;좀 더 간소화된 데이터 페이칭을 지원합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;스타일링&lt;/li&gt;
&lt;li&gt;최적화&lt;/li&gt;
&lt;li&gt;개발 및 프로덕션 빌드 시스템&lt;/li&gt;
&lt;/ol&gt;</description>
      <category> &amp;zwj;  Programming/Next.js</category>
      <category>next.js</category>
      <author>jinnkimm7</author>
      <guid isPermaLink="true">https://devjk.tistory.com/83</guid>
      <comments>https://devjk.tistory.com/entry/Nextjs-Nextjs-%EC%86%8C%EA%B0%9C#entry83comment</comments>
      <pubDate>Tue, 25 Mar 2025 22:42:37 +0900</pubDate>
    </item>
    <item>
      <title>[TanStack Query] TanStack Query란</title>
      <link>https://devjk.tistory.com/entry/TanStack-Query-TanStack-Query%EB%9E%80</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;TanStack Query란&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;네트워크에서 받아온 데이터의 상태를 관리할 수 있도록 도와주는 라이브러리입니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;공식문서&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;TS/JS, React, Solid, Vue, Svelte를 위한 강력한 비동기 상태관리 라이브러리&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;세부적인 상태관리, 수동적인 refetching 그리고 끊임없는 비동기 스파게티 코드를 토스해라. 텐스택 쿼리는 선언적이고, 최신의 자동화된 쿼리 그리고 mutation을 줄 것입니다. 그 결과 개발자와 사용자 경험을 향상시킬 수 있을 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;선언적이고 자동적입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;데이터 fetching 로직을 일일이 작성할 필요가 없습니다. TanStack Query에게 어디서 데이터를 가져오면 되는지 얼마나 데이터의 신선도를 유지할 것인지 말해주세요. 그러면 나머지는 자동적일것입니다. TanStack 쿼리는 캐싱, 백그라운드 업데이트, 오래된(stale) 데이터를 별도의 설정없이 자동으로 해결해줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;심플하고 친숙합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로미스와 async/await에 대해서 알고 있다면, 당신은 이미 TanStack 쿼리의 사용법을 알고 있는 것입니다. 글로벌 상태, reducer, 복잡한 설정을 요구하지 않습니다. 단순히 함수만 전달해주면 됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;광범위합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;개발자도구, 무제한 로딩 API, 데이터를 업데이트하는 mutation tools를 제공해줍니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리액트 쿼리는 리액트를 위한 데이터 fetching 라이브러리로만 여겨지고 있는데 좀더 엄밀히 말하자면, 리액트 쿼리는 fetching, caching, synchronizing and updating server state를 해줍니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Caching... (possibly the hardest thing to do in programming)&lt;/li&gt;
&lt;li&gt;Deduping multiple requests for the same data into a single request&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;시작하기&lt;/h2&gt;
&lt;pre class=&quot;css&quot;&gt;&lt;code&gt;npm i @tanstack/react-query&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Query client 만들기
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Query client가 쿼리와 캐시를 관리합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;QueryProvider 적용하기
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;자식 컴포넌트에 캐시 및 클라이언트 구성을 제공합니다.&lt;/li&gt;
&lt;li&gt;QueryProvider는 쿼리 클라이언트를 값으로 사용합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;useQuery 호출하기
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;서버에서 데이터를 받으려면 useQuery Hook을 사용해야합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;적용하기&lt;/h2&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;import { Posts } from &quot;./Posts&quot;;
import &quot;./App.css&quot;;
import { QueryClient, QueryClientProvider } from &quot;@tanstack/react-query&quot;;

const queryClient = new QueryClient();

function App() {
  return (
    // Provider의 자식들은 캐시를 포함한 쿼리클라이언트에 접근이 가능합니다. 
    &amp;lt;QueryClientProvider client={queryClient}&amp;gt;
      &amp;lt;div className=&quot;App&quot;&amp;gt;
        &amp;lt;h1&amp;gt;Blog &amp;amp;apos;em Ipsum&amp;lt;/h1&amp;gt;
        &amp;lt;Posts /&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/QueryClientProvider&amp;gt;
  );
}

export default App;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;useQuery에서 반환되는 객체를 확인할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://tanstack.com/query/latest/docs/framework/react/reference/useQuery&quot;&gt;useQuery | TanStack Query React Docs&lt;/a&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;isFetching vs isLoading&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;isFetching
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;비동기 쿼리가 아직 해결되지 않았다는 것을 의미&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;isLoading
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;캐시된 데이터가 없음. isFetching보다 작은 개념&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Devtools&lt;/h3&gt;
&lt;pre class=&quot;css&quot;&gt;&lt;code&gt;npm i @tanstack/react-query-devtools&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://tanstack.com/query/latest/docs/framework/react/devtools&quot;&gt;Devtools | TanStack Query React Docs&lt;/a&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;stale, gcTime&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;stale&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;stale data라는 것은 만료되었거나 refetch될 준비가 된 데이터를 말합니다.&lt;/li&gt;
&lt;li&gt;여전히 캐시에 있습니다. 하지만 재검증 되야 한다는 뜻입니다.&lt;/li&gt;
&lt;li&gt;data refetch는 오직 stale data에만 트리거됩니다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;예를들어, 컴포넌트가 재마운트 된다거나, 윈도우가 refocus될 때, data refetching이 발생합니다.&lt;/li&gt;
&lt;li&gt;staleTime이라는 것은 데이터의 최대 수명으로 생각하면 됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;gcTime&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;gcTime은 데이터를 캐시에 유지할 시간을 결정합니다.&lt;/li&gt;
&lt;li&gt;데이터와 연관될 활성 useQuery 표시가 없고, 데이터가 현재 페이지에 표시되지 않으면, cold storage 상태로 들어갑니다.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category> &amp;zwj;  Programming/React</category>
      <category>reactquery</category>
      <category>tanstackQuery</category>
      <author>jinnkimm7</author>
      <guid isPermaLink="true">https://devjk.tistory.com/82</guid>
      <comments>https://devjk.tistory.com/entry/TanStack-Query-TanStack-Query%EB%9E%80#entry82comment</comments>
      <pubDate>Mon, 24 Mar 2025 10:10:40 +0900</pubDate>
    </item>
    <item>
      <title>[git] private repository clone시 remote: Repository not found</title>
      <link>https://devjk.tistory.com/entry/git-private-repository-clone%EC%8B%9C-remote-Repository-not-found</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;문제&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다른 사람의 private repository clone시 remote: Repository not found가 나와서 클론을 받을 수 없었습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;해결책 1&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;github.com의 앞에 유저이름@를 붙여줍니다.&lt;/p&gt;
&lt;pre class=&quot;crmsh&quot;&gt;&lt;code&gt;$ git clone https://유저이름@github.com/~~~~~~~.git&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;해결책 2&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후 권한을 부여받은 토큰을 발급받아 입력해줍니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;토큰 발급 받기&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로필을 클릭하고, 세팅에 들어가면 아래와 같은 화면이 나옵니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;634&quot; data-origin-height=&quot;1708&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/baNITC/btsMP8QQdlH/fNfkdldvHQOXrj32VSdiz1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/baNITC/btsMP8QQdlH/fNfkdldvHQOXrj32VSdiz1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/baNITC/btsMP8QQdlH/fNfkdldvHQOXrj32VSdiz1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbaNITC%2FbtsMP8QQdlH%2FfNfkdldvHQOXrj32VSdiz1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;238&quot; height=&quot;641&quot; data-origin-width=&quot;634&quot; data-origin-height=&quot;1708&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2336&quot; data-origin-height=&quot;608&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9SbMV/btsMPxKkAgv/oGkVrKs2idwQfn2MSzPKM0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9SbMV/btsMPxKkAgv/oGkVrKs2idwQfn2MSzPKM0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9SbMV/btsMPxKkAgv/oGkVrKs2idwQfn2MSzPKM0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9SbMV%2FbtsMPxKkAgv%2FoGkVrKs2idwQfn2MSzPKM0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2336&quot; height=&quot;608&quot; data-origin-width=&quot;2336&quot; data-origin-height=&quot;608&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2610&quot; data-origin-height=&quot;1512&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/byRncb/btsMQdqXX7U/H9xO3XvYRelkXFsHEYtGzK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/byRncb/btsMQdqXX7U/H9xO3XvYRelkXFsHEYtGzK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/byRncb/btsMQdqXX7U/H9xO3XvYRelkXFsHEYtGzK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbyRncb%2FbtsMQdqXX7U%2FH9xO3XvYRelkXFsHEYtGzK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2610&quot; height=&quot;1512&quot; data-origin-width=&quot;2610&quot; data-origin-height=&quot;1512&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>⚙️ Tool/git</category>
      <category>git</category>
      <author>jinnkimm7</author>
      <guid isPermaLink="true">https://devjk.tistory.com/81</guid>
      <comments>https://devjk.tistory.com/entry/git-private-repository-clone%EC%8B%9C-remote-Repository-not-found#entry81comment</comments>
      <pubDate>Wed, 19 Mar 2025 17:59:02 +0900</pubDate>
    </item>
    <item>
      <title>[DynamoDB] DynamoDB란</title>
      <link>https://devjk.tistory.com/entry/DynamoDB-DynamoDB%EB%9E%80</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;DynamoDB&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;AWS의 대표적인 NoSQL 기반 서버리스 데이터베이스 서비스입니다.&lt;/li&gt;
&lt;li&gt;key-value와 문서 기반 데이터 모델을 지원합니다.&lt;/li&gt;
&lt;li&gt;사용한만큼 비용을 지불하고, 버전 업그레이드, 가동 중단 등 유지관리가 필요없습니다.&lt;/li&gt;
&lt;li&gt;이외의 특징으론 이미지, 동영상 등 어떠한 형태도 저장이 가능하고, 질의 속도가 빠르고, 테이블 생성시 스키마 생성이 필요없다는 특징이 있습니다.&lt;/li&gt;
&lt;li&gt;기존 RDBMS와 다르게 데이터를 분산 방식으로 저장하므로 수평확장이 가능합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;어떻게 작동하는가&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Tables &amp;amp; Items : 로우와 컬럼 대신에, 다이나모 DB는 items(JSON과 같은 객체)을 테이블에 저장합니다.&lt;/li&gt;
&lt;li&gt;Primary Keys : 각각의 item들은 고유한 primary key를 가져야합니다. primary키는 partition key 단독이거나 partition key와 sort key의 조합이여야 합니다.&lt;/li&gt;
&lt;li&gt;Indexes : 효과적인 쿼리를 위해 Global Secondary Indexes (GSI)와 Local Secondary Indexes (LSI)를 사용할 수 있습니다.&lt;/li&gt;
&lt;li&gt;Automatic Scaling : 다이나모 DB는 요구에 기반하여 자동적으로 스케일업과 스케일 다운합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Item&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Item은 테이블에 저장된 근본적인 데이터 단위이고, 관계형 DB의 로우랑 유사하다고 생각하면 됩니다. 각 각의 아이템은 하나 혹은 그 이상의 속성으로 구성되어 있고, 테이블 내에서 독특하게 식별되기 위해 기본키를 가져야합니다. 기본키는 위에서 말했듯이 파티션키 단독이거나 파티션키와 정렬키의 조합이여야 합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Data Type&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다이나모 DB는 아이템의 속성에 대해 다양한 타입을 지원합니다. 주로 아래에 따라 분류됩니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Scalar Types : Number, String, Binary, Boolean, Null&lt;/li&gt;
&lt;li&gt;Document Types : List, Map&lt;/li&gt;
&lt;li&gt;Set Types : Number Set, String Set, Binary Set&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Partition Key (Hash)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파티션키는 독특한 식별자입니다. 그리고 파티션키는 scalability(확장성)을 위해 데이터를 파티션 전역에 분배합니다. 해시 알고리즘을 사용하여 스토리지 위치를 결정합니다. 파티션 키를 잘 선택하면 고른 데이터 분배를 보장할 수 있고, 병목현상을 막을 수 있습니다.(최대한 많이 분산시켜야합니다. Distribute parition keys as much as possible) 효율적인 쿼리를 위해 정렬키와 함께 복합 기본키를 구성할 수 있습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Sort Key (Range)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정렬키는 파티션 키와 함께 복합 기본키를 구성합니다. Range-based query를 가능하게 합니다. 정렬키는 효율적인 정렬과 파티션 내에서 데이터를 찾을 수 있도록합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Primary Key&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본키는 테이블 내에서 각각의 아이템을 식별할 수 있습니다. primary키는 partition key 단독이거나 partition key와 sort key의 조합이여야 합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Query&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쿼리하기 위해 파티션 키를 전달해주어야합니다. 그래서 적절한 파티션키를 선택하는 것이 중요합니다. 쿼리 작동은 테이블 내에 파티션키와 매치하는 아이템들을 리턴합니다. 정렬키는 필터와 아이템을 정렬하는데 유용하지만 필수적으로 선택해야하는 것은 아닙니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Scan&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;스캔 동작은 테이블의 결과를 패치하기 위해 파티션키 혹은 정렬키를 필요로 하지 않습니다. 이름이 암시하듯 스캔은 전체 테이블을 스캔하여 필터로써 전달된 속성 값에 기반한 결과들을 필터링합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Pagination&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다이나모 DB 쿼리/스캔 응답은 요청 하나당 1MB로 제한됩니다. 만약 결과가 1MB를 초과한다면, 자동적으로 페이지네이션됩니다. 그리고 다이나모 DB는 LastEvaluatedKey를 제공하고, 이것을 통해 다음 페이지를 패치할 수 있습니다. LastEvaluatedKey를 ExclusiveStartKey로서 다음 요청에 전달해 주어야합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;Sorting&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정렬키에 기반하여 오름차순으로 다이나모 DB 쿼리/스캔 결과가 정렬됩니다. 내림차순으로 결과를 찾기 위해서 ScanIndexForward를 false 처리해야합니다. 만약 정렬키가 숫자라면, 결과는 숫자적으로 정렬되고 그렇지 않다면 UTF-8 byte 순서를 따릅니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;실습&lt;/h2&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;const { DynamoDBClient, CreateTableCommand, PutItemCommand, GetItemCommand, DeleteItemCommand, UpdateItemCommand } = require('@aws-sdk/client-dynamodb');

const REGION = 'ap-southeast-2';

const ddbClient = new DynamoDBClient({region: REGION});
const TABLE_NAME = &quot;EspressoDrinks&quot;;

async function createTable() {
    const createParam = {
        TableName: TABLE_NAME,
        AttributeDefinitions: [
          {
            AttributeName: &quot;DrinkName&quot;,
            AttributeType: &quot;S&quot;,
          }
        ],
        KeySchema: [
          {
            AttributeName: &quot;DrinkName&quot;,
            KeyType: &quot;HASH&quot;,
          },
        ],
        BillingMode: &quot;PAY_PER_REQUEST&quot;,
      };

      await ddbClient.send(new CreateTableCommand(createParam));
      console.log('Table created!!');
}

// PutItemCommand
async function insertDrink(drinkName, price) {
    const params = {
        TableName: TABLE_NAME,
        Item: {
            DrinkName : { S: drinkName },
            Price : { N: price.toString()}
        }
    };

    await ddbClient.send(new PutItemCommand(params));
    console.log(`${drinkName} inserted!! `);
}

// GetItemCommand
async function getDrink(drinkName) {
    const params = {
        TableName : TABLE_NAME,
        Key: {
            DrinkName : { S: drinkName}
        }
    };

    const { Item } = await ddbClient.send(new GetItemCommand(params));
    console.log('Get Drink : ', Item);
}

// UpdateItemCommand
async function updateDrink(drinkName, price) {
    const params = {
        TableName: TABLE_NAME,
        Key: {
            DrinkName: { S : drinkName },
        },
        UpdateExpression: 'SET #Price = :Price',
        ExpressionAttributeNames: {
            '#Price': 'Price',
        },
        ExpressionAttributeValues: {
            ':Price' : { N : price.toString()}
        }
    };

    await ddbClient.send(new UpdateItemCommand(params));
    console.log(&quot;Drink's price updated!&quot;);
}

// DeleteItemCommand
async function deleteDrink(drinkName) {
    const params = {
        TableName: TABLE_NAME,
        Key: {
            DrinkName : { S: drinkName }
        },
    };

    await ddbClient.send(new DeleteItemCommand(params));
    console.log(&quot;Item Deleted&quot;);
}

async function main() {
    // await createTable();
    // await insertDrink('Coffee', 2000);
    // await insertDrink('Latte', 3000);
    // await getDrink('Coffee');
    // await updateDrink('Latte', 4000);
    // await deleteDrink('Latte');
}

main();&lt;/code&gt;&lt;/pre&gt;</description>
      <category>  CS/Database</category>
      <category>dynamodb</category>
      <author>jinnkimm7</author>
      <guid isPermaLink="true">https://devjk.tistory.com/80</guid>
      <comments>https://devjk.tistory.com/entry/DynamoDB-DynamoDB%EB%9E%80#entry80comment</comments>
      <pubDate>Tue, 18 Mar 2025 12:28:40 +0900</pubDate>
    </item>
    <item>
      <title>[VSCode] Mac OS 터미널 이미지 깨지는 현상 해결</title>
      <link>https://devjk.tistory.com/entry/VSCode-Mac-OS-%ED%84%B0%EB%AF%B8%EB%84%90-%EC%9D%B4%EB%AF%B8%EC%A7%80-%EA%B9%A8%EC%A7%80%EB%8A%94-%ED%98%84%EC%83%81-%ED%95%B4%EA%B2%B0</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1930&quot; data-origin-height=&quot;68&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Se0yW/btsMKT6IRrK/FIf7DXUUCfUjkrkpI9YRC1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Se0yW/btsMKT6IRrK/FIf7DXUUCfUjkrkpI9YRC1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Se0yW/btsMKT6IRrK/FIf7DXUUCfUjkrkpI9YRC1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSe0yW%2FbtsMKT6IRrK%2FFIf7DXUUCfUjkrkpI9YRC1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1930&quot; height=&quot;68&quot; data-origin-width=&quot;1930&quot; data-origin-height=&quot;68&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;shift + cmd + P 누르고 setting.json(Open user)에 아래 내용을 추가해줍니다.&lt;/p&gt;
&lt;pre class=&quot;1c&quot;&gt;&lt;code&gt;&quot;terminal.integrated.fontFamily&quot;: &quot;MesloLGS NF&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;폰트명을 본인의 폰트와 맞추어주어야합니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1938&quot; data-origin-height=&quot;94&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qreXH/btsMKCqB7oV/lmkKr8kWhdgkVCnE9tPkz0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qreXH/btsMKCqB7oV/lmkKr8kWhdgkVCnE9tPkz0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qreXH/btsMKCqB7oV/lmkKr8kWhdgkVCnE9tPkz0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqreXH%2FbtsMKCqB7oV%2FlmkKr8kWhdgkVCnE9tPkz0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1938&quot; height=&quot;94&quot; data-origin-width=&quot;1938&quot; data-origin-height=&quot;94&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>⚙️ Tool/VS Code</category>
      <category>vscode</category>
      <author>jinnkimm7</author>
      <guid isPermaLink="true">https://devjk.tistory.com/79</guid>
      <comments>https://devjk.tistory.com/entry/VSCode-Mac-OS-%ED%84%B0%EB%AF%B8%EB%84%90-%EC%9D%B4%EB%AF%B8%EC%A7%80-%EA%B9%A8%EC%A7%80%EB%8A%94-%ED%98%84%EC%83%81-%ED%95%B4%EA%B2%B0#entry79comment</comments>
      <pubDate>Thu, 13 Mar 2025 17:38:11 +0900</pubDate>
    </item>
    <item>
      <title>[JS] 자바스크립트 사용용도, ECMASCRIPT, 자바스크립트의 특징</title>
      <link>https://devjk.tistory.com/entry/JS-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EC%82%AC%EC%9A%A9%EC%9A%A9%EB%8F%84-ECMASCRIPT-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%EC%9D%98-%ED%8A%B9%EC%A7%95</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;자바스크립트의 사용용도&lt;/h2&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;브라우저&lt;/li&gt;
&lt;li&gt;Node.js가 등장한 이후부터 서버 사이드 어플리케이션 개발에서도 사용할 수 있습니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자바스크립트가 동작하기 위해서는 자바스크립트 엔진이 필요합니다. 자바스크립트 엔진은 코드를 한줄씩 번역해서 실행하는 인터프리터입니다.&lt;br /&gt;브라우저는 자바스크립트 엔진을 내장하고 있고, Node.js에도 자바스크립트 엔진을 내장하고 있습니다. 하지만, 브라우저는 HTML, CSS, 자바스크립트를 실행하여, 웹페이지를 렌더링 하는 것이 주목적이라면, Node.js는 브라우저 외부에서 자바스크립트 실행환경을 제공하는 것이 주목적입니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;ECMAScript&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;자바스크립트 핵심 문법을 규격화한 표준사항입니다.&lt;/li&gt;
&lt;li&gt;각 브라우저 제조사는 ECMAScript 사양을 준수하여 브라우저에 내장되는 자바스크립트 엔진을 구현해야합니다.&lt;/li&gt;
&lt;li&gt;또한, ECMAScript라는 표준사항에 맞게 자바스크립트를 작성해야합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;자바스크립트의 특징&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;lightweight, interpreted, just-in-time complied language with first-class functions&lt;/li&gt;
&lt;li&gt;웹 페이지를 위한 스크립트로 언어로 알려져 있지만, 브라우저가 아닌 환경에서도 사용되어 지고 있습니다.&lt;/li&gt;
&lt;li&gt;프로토타입 기반, 멀티패러다임, 싱글 스레드, 동적인 언어이고 객체지향적, 절차적, 함수형 프로그래밍 스타일을 지원합니다.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category> &amp;zwj;  Programming/JavaScript</category>
      <author>jinnkimm7</author>
      <guid isPermaLink="true">https://devjk.tistory.com/78</guid>
      <comments>https://devjk.tistory.com/entry/JS-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EC%82%AC%EC%9A%A9%EC%9A%A9%EB%8F%84-ECMASCRIPT-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%EC%9D%98-%ED%8A%B9%EC%A7%95#entry78comment</comments>
      <pubDate>Fri, 7 Feb 2025 13:45:22 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스 Lv0] 안전지대 | 자바</title>
      <link>https://devjk.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-Lv0-%EC%95%88%EC%A0%84%EC%A7%80%EB%8C%80-%EC%9E%90%EB%B0%94</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;문제&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/120866&quot;&gt;안전지대&lt;/a&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;풀이&lt;/h2&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;import java.util.*;

class Solution {
    public int solution(int[][] board) {
        int answer = 0;

        // 폭탄의 위치 파악 하기
        List&amp;lt;int[]&amp;gt; bomb_location = new ArrayList&amp;lt;&amp;gt;();

        for(int i = 0; i &amp;lt; board.length; i++) {
            for(int j = 0; j &amp;lt; board[i].length; j++) {
                if(board[i][j] == 1) bomb_location.add(new int[]{i, j});
            }
        }

        // 폭탄 주변에 위험 표시 하기
        for(int i = 0; i &amp;lt; bomb_location.size(); i++) {
            int cur_x = bomb_location.get(i)[0];
            int cur_y = bomb_location.get(i)[1];

            int[] dx = {0, 0, -1, 1, 1, 1, -1, -1};
            int[] dy = {1, -1, 0, 0, 1, -1, -1, 1};

            int limit = board.length;

            for(int j = 0; j &amp;lt; 8; j++) {
                int nx = cur_x + dx[j];
                int ny = cur_y + dy[j];

                if(nx &amp;gt;= 0 &amp;amp;&amp;amp; ny &amp;gt;= 0 &amp;amp;&amp;amp; nx &amp;lt; limit &amp;amp;&amp;amp; ny &amp;lt; limit &amp;amp;&amp;amp; board[nx][ny] == 0) {
                    board[nx][ny] = 2;
                }
            }
        }

        // 안전지대(0) 개수 세기
        for(int i = 0; i &amp;lt; board.length; i++) {
            for(int j = 0; j &amp;lt; board.length; j++) {
                if(board[i][j] == 0) answer++;
            }
        }

        return answer;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;if(nx &amp;gt;= 0 &amp;amp;&amp;amp; ny &amp;gt;= 0 &amp;amp;&amp;amp; nx &amp;lt; limit &amp;amp;&amp;amp; ny &amp;lt; limit &amp;amp;&amp;amp; board[nx][ny] == 0) 조건에서 board[nx][ny]를 제일 앞에 작성하여, ArrayIndexOutOfBoundsException가 발생했었습니다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;ArrayIndexOutOfBoundsException : 정해진 배열의 크기보다 크거나 음수 index에 대한 요청이 있으면 ArrayIndexOutOfBoundsException이 발생합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>  Coding Test/Programmers Lv0</category>
      <category>코딩테스트</category>
      <category>프로그래머스</category>
      <author>jinnkimm7</author>
      <guid isPermaLink="true">https://devjk.tistory.com/77</guid>
      <comments>https://devjk.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-Lv0-%EC%95%88%EC%A0%84%EC%A7%80%EB%8C%80-%EC%9E%90%EB%B0%94#entry77comment</comments>
      <pubDate>Tue, 21 Jan 2025 23:05:37 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스] 가격이 제일 비싼 식품의 정보 출력하기 | MySQL, 오라클</title>
      <link>https://devjk.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EA%B0%80%EA%B2%A9%EC%9D%B4-%EC%A0%9C%EC%9D%BC-%EB%B9%84%EC%8B%BC-%EC%8B%9D%ED%92%88%EC%9D%98-%EC%A0%95%EB%B3%B4-%EC%B6%9C%EB%A0%A5%ED%95%98%EA%B8%B0-MySQL-%EC%98%A4%EB%9D%BC%ED%81%B4</link>
      <description>&lt;h2&gt;문제&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/131115?language=mysql#&quot;&gt;가격이 제일 비싼 식품의 정보 출력하기&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;풀이 1&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;서브쿼리를 이용한 풀이입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;MySQL&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;SELECT PRODUCT_ID, PRODUCT_NAME, PRODUCT_CD, CATEGORY, PRICE
FROM FOOD_PRODUCT
WHERE PRICE = (
SELECT MAX(PRICE) PRICE
FROM FOOD_PRODUCT
);&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;오라클&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;SELECT *
FROM FOOD_PRODUCT
WHERE PRICE = (SELECT MAX(PRICE) FROM FOOD_PRODUCT);&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;풀이 2&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;가격을 내림차순으로 정렬하고, 최상위 로우를 뽑아내는 풀이입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;MySQL&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;SELECT * 
FROM FOOD_PRODUCT
ORDER BY PRICE DESC 
LIMIT 1;&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;오라클&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;SELECT * 
FROM (
 SELECT * FROM FOOD_PRODUCT ORDER BY PRICE DESC
)
WHERE ROWNUM &amp;lt;= 1;&lt;/code&gt;&lt;/pre&gt;</description>
      <category>  Coding Test/SQL</category>
      <category>MYSQL</category>
      <category>오라클</category>
      <category>프로그래머스</category>
      <author>jinnkimm7</author>
      <guid isPermaLink="true">https://devjk.tistory.com/76</guid>
      <comments>https://devjk.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EA%B0%80%EA%B2%A9%EC%9D%B4-%EC%A0%9C%EC%9D%BC-%EB%B9%84%EC%8B%BC-%EC%8B%9D%ED%92%88%EC%9D%98-%EC%A0%95%EB%B3%B4-%EC%B6%9C%EB%A0%A5%ED%95%98%EA%B8%B0-MySQL-%EC%98%A4%EB%9D%BC%ED%81%B4#entry76comment</comments>
      <pubDate>Tue, 21 Jan 2025 11:08:15 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스] 3월에 태어난 여성 회원 목록 출력하기 | MySQL</title>
      <link>https://devjk.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-3%EC%9B%94%EC%97%90-%ED%83%9C%EC%96%B4%EB%82%9C-%EC%97%AC%EC%84%B1-%ED%9A%8C%EC%9B%90-%EB%AA%A9%EB%A1%9D-%EC%B6%9C%EB%A0%A5%ED%95%98%EA%B8%B0-MySQL</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;문제&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/131120?language=mysql&quot;&gt;3월에 태어난 여성 회원 목록 출력하기&lt;/a&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;풀이&lt;/h2&gt;
&lt;pre class=&quot;sql&quot;&gt;&lt;code&gt;SELECT MEMBER_ID, MEMBER_NAME, GENDER, DATE_FORMAT(DATE_OF_BIRTH, '%Y-%m-%d') DATE_OF_BIRTH
FROM MEMBER_PROFILE
WHERE DATE_FORMAT(DATE_OF_BIRTH, '%m') = '03' AND TLNO IS NOT NULL AND GENDER = 'W'
ORDER BY MEMBER_ID ASC
;&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;3월에 태어난 여성을 구할 때, DATE_FORMAT 함수를 사용했습니다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://devjhs.tistory.com/89&quot;&gt;[mysql] DATE_FORMAT - 날짜 형식 설정&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;MONTH 함수를 사용해도 됩니다.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>  Coding Test/SQL</category>
      <category>MYSQL</category>
      <category>SQL</category>
      <category>프로그래머스</category>
      <author>jinnkimm7</author>
      <guid isPermaLink="true">https://devjk.tistory.com/75</guid>
      <comments>https://devjk.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-3%EC%9B%94%EC%97%90-%ED%83%9C%EC%96%B4%EB%82%9C-%EC%97%AC%EC%84%B1-%ED%9A%8C%EC%9B%90-%EB%AA%A9%EB%A1%9D-%EC%B6%9C%EB%A0%A5%ED%95%98%EA%B8%B0-MySQL#entry75comment</comments>
      <pubDate>Tue, 21 Jan 2025 10:40:19 +0900</pubDate>
    </item>
    <item>
      <title>[Excel] 엑셀로 쿼리 작성하기</title>
      <link>https://devjk.tistory.com/entry/Excel-%EC%97%91%EC%85%80%EB%A1%9C-%EC%BF%BC%EB%A6%AC-%EC%9E%91%EC%84%B1%ED%95%98%EA%B8%B0</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;엑셀로 쿼리 작성하기&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;제목 없는 디자인 (1).png&quot; data-origin-width=&quot;1914&quot; data-origin-height=&quot;983&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bLMYVU/btsLRMWtfo4/mEImUZlsX4jdY95vBEWxG0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bLMYVU/btsLRMWtfo4/mEImUZlsX4jdY95vBEWxG0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bLMYVU/btsLRMWtfo4/mEImUZlsX4jdY95vBEWxG0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbLMYVU%2FbtsLRMWtfo4%2FmEImUZlsX4jdY95vBEWxG0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1914&quot; height=&quot;983&quot; data-filename=&quot;제목 없는 디자인 (1).png&quot; data-origin-width=&quot;1914&quot; data-origin-height=&quot;983&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래와 같이 엑셀을 활용해서 쿼리를 작성하면, 실수를 줄이고 생산성 있게 쿼리를 작성할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;670&quot; data-origin-height=&quot;56&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cmbmFY/btsLRSI9X6O/zYuf0zNeQ6kHX4fb4kcta1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cmbmFY/btsLRSI9X6O/zYuf0zNeQ6kHX4fb4kcta1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cmbmFY/btsLRSI9X6O/zYuf0zNeQ6kHX4fb4kcta1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcmbmFY%2FbtsLRSI9X6O%2FzYuf0zNeQ6kHX4fb4kcta1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;670&quot; height=&quot;56&quot; data-origin-width=&quot;670&quot; data-origin-height=&quot;56&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>⚙️ Tool/Excel</category>
      <category>Excel</category>
      <author>jinnkimm7</author>
      <guid isPermaLink="true">https://devjk.tistory.com/74</guid>
      <comments>https://devjk.tistory.com/entry/Excel-%EC%97%91%EC%85%80%EB%A1%9C-%EC%BF%BC%EB%A6%AC-%EC%9E%91%EC%84%B1%ED%95%98%EA%B8%B0#entry74comment</comments>
      <pubDate>Mon, 20 Jan 2025 09:50:55 +0900</pubDate>
    </item>
    <item>
      <title>[git] .gitignore 커밋 후 바로 적용 안될 경우</title>
      <link>https://devjk.tistory.com/entry/git-gitignore-%EC%BB%A4%EB%B0%8B-%ED%9B%84-%EB%B0%94%EB%A1%9C-%EC%A0%81%EC%9A%A9-%EC%95%88%EB%90%A0-%EA%B2%BD%EC%9A%B0</link>
      <description>&lt;p&gt;.gitignore에 형상관리 할 필요가 없는 파일들을 적으면 더 이상 추적하지 않습니다.&lt;/p&gt;
&lt;p&gt;.gitignore 파일을 수정하고 commit &amp;amp; push 이후, 바로 적용되지 않는다면 git의 캐시가 원인입니다.&lt;/p&gt;
&lt;p&gt;git에 있는 캐시 파일을 지워주고 다시 add하면 됩니다.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git rm -r --cached .
git add .
git commit -m &amp;quot;removed cached&amp;quot;&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;추천 사이트&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://www.toptal.com/developers/gitignore&quot;&gt;자신의 프로젝트에 꼭 맞는 .gitignore 파일을 만드세요&lt;/a&gt;&lt;/p&gt;</description>
      <category>⚙️ Tool/git</category>
      <category>git</category>
      <author>jinnkimm7</author>
      <guid isPermaLink="true">https://devjk.tistory.com/73</guid>
      <comments>https://devjk.tistory.com/entry/git-gitignore-%EC%BB%A4%EB%B0%8B-%ED%9B%84-%EB%B0%94%EB%A1%9C-%EC%A0%81%EC%9A%A9-%EC%95%88%EB%90%A0-%EA%B2%BD%EC%9A%B0#entry73comment</comments>
      <pubDate>Mon, 20 Jan 2025 01:04:32 +0900</pubDate>
    </item>
    <item>
      <title>[오라클] MERGE INTO</title>
      <link>https://devjk.tistory.com/entry/%EC%98%A4%EB%9D%BC%ED%81%B4-MERGE-INTO</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;MERGE INTO&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 값이 있으면 UPDATE하고 없으면 INSERT하는 구문입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;489&quot; data-origin-height=&quot;296&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cLAbqr/btsLPvtM9fI/NHJPuDNTti6qO1s6AQe2X1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cLAbqr/btsLPvtM9fI/NHJPuDNTti6qO1s6AQe2X1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cLAbqr/btsLPvtM9fI/NHJPuDNTti6qO1s6AQe2X1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcLAbqr%2FbtsLPvtM9fI%2FNHJPuDNTti6qO1s6AQe2X1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;489&quot; height=&quot;296&quot; data-origin-width=&quot;489&quot; data-origin-height=&quot;296&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약에 테이블 하나만 가지고 작업을 할 경우, MERGE INTO 테이블 USING DUAL ~ 으로 사용하면 됩니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;예제&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;melon_chart 테이블입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;832&quot; data-origin-height=&quot;442&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/UNNWb/btsLP8kvu9F/ugkaVYeIOqyqNW2u0ObGb1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/UNNWb/btsLP8kvu9F/ugkaVYeIOqyqNW2u0ObGb1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/UNNWb/btsLP8kvu9F/ugkaVYeIOqyqNW2u0ObGb1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FUNNWb%2FbtsLP8kvu9F%2FugkaVYeIOqyqNW2u0ObGb1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;832&quot; height=&quot;442&quot; data-origin-width=&quot;832&quot; data-origin-height=&quot;442&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;melon_chart_new 테이블입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;830&quot; data-origin-height=&quot;440&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/TS8sy/btsLP8xZAlE/PJZLeEc07aH62HYFIZVgak/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/TS8sy/btsLP8xZAlE/PJZLeEc07aH62HYFIZVgak/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/TS8sy/btsLP8xZAlE/PJZLeEc07aH62HYFIZVgak/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTS8sy%2FbtsLP8xZAlE%2FPJZLeEc07aH62HYFIZVgak%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;830&quot; height=&quot;440&quot; data-origin-width=&quot;830&quot; data-origin-height=&quot;440&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;melon_chart_new에 있는 데이터와 melon_chart에 있는 데이터를 중복되지 않게 합치고, 최신화를 시켜주고 싶다면 아래와 같이 쿼리문을 작성하면 됩니다.&lt;/p&gt;
&lt;pre class=&quot;sql&quot;&gt;&lt;code&gt;merge into melon_chart m1
using melon_chart_new m2
on (m1.singer = m2.singer and m1.song = m2.song)
when matched then
 update set m1.ranking = m2.ranking, m1.remark = 'continue'
when not matched then
 insert values(m2.ranking, m2.singer, m2.song, 'new')
;

select * from melon_chart where remark is not null order by ranking;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;842&quot; data-origin-height=&quot;452&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bwmL4i/btsLQHmmXKA/dM4Aad4KO5M3jwUv1Bk161/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bwmL4i/btsLQHmmXKA/dM4Aad4KO5M3jwUv1Bk161/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bwmL4i/btsLQHmmXKA/dM4Aad4KO5M3jwUv1Bk161/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbwmL4i%2FbtsLQHmmXKA%2FdM4Aad4KO5M3jwUv1Bk161%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;842&quot; height=&quot;452&quot; data-origin-width=&quot;842&quot; data-origin-height=&quot;452&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;참고&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=YN5DI2ZXfoU&quot;&gt;UPDATE, INSERT를 한방에, 신박한 MERGE 문  &lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>  CS/Database</category>
      <category>오라클</category>
      <author>jinnkimm7</author>
      <guid isPermaLink="true">https://devjk.tistory.com/72</guid>
      <comments>https://devjk.tistory.com/entry/%EC%98%A4%EB%9D%BC%ED%81%B4-MERGE-INTO#entry72comment</comments>
      <pubDate>Thu, 16 Jan 2025 21:21:56 +0900</pubDate>
    </item>
    <item>
      <title>[오라클] WITH 구문</title>
      <link>https://devjk.tistory.com/entry/%EC%98%A4%EB%9D%BC%ED%81%B4-WITH-%EA%B5%AC%EB%AC%B8</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;WITH 구문&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;ORACLE9i R2 이후, 사용 가능한 구문으로 WITH 구문은 이름이 부여된 서브쿼리 블록으로 인라인 뷰처럼 작동합니다.&lt;/li&gt;
&lt;li&gt;서브쿼리를 별도로 빼서 이름을 지어주는 것이라고 생각하면 됩니다.&lt;/li&gt;
&lt;li&gt;동일 쿼리블록이 반복적으로 사용되는 경우, 이름을 붙여 한 곳에 정의하고 재사용할 수 있습니다.&lt;/li&gt;
&lt;li&gt;자주 실행되는 경우 한 번만 parsing되고 실행 계획이 수립되므로 성능 향상에 좋습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;예시&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래와 비슷한 테이블에서 존재하지 않은 연도도 같이 뽑아내기 위해, WITH절을 업무에 사용했던 적이 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1214&quot; data-origin-height=&quot;976&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/YfvEK/btsLOqFNHOj/7ZePSDk92izTxC5aLKvb2K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/YfvEK/btsLOqFNHOj/7ZePSDk92izTxC5aLKvb2K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/YfvEK/btsLOqFNHOj/7ZePSDk92izTxC5aLKvb2K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FYfvEK%2FbtsLOqFNHOj%2F7ZePSDk92izTxC5aLKvb2K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1214&quot; height=&quot;976&quot; data-origin-width=&quot;1214&quot; data-origin-height=&quot;976&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래처럼 WITH구문을 이용해 존재하지 않는 연도도 포함하는 쿼리를 작성할 수 있었습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;968&quot; data-origin-height=&quot;638&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/pvtOs/btsLOwTxRNC/O5sHgvyZ7uKCN7kkHpl1F0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/pvtOs/btsLOwTxRNC/O5sHgvyZ7uKCN7kkHpl1F0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/pvtOs/btsLOwTxRNC/O5sHgvyZ7uKCN7kkHpl1F0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FpvtOs%2FbtsLOwTxRNC%2FO5sHgvyZ7uKCN7kkHpl1F0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;968&quot; height=&quot;638&quot; data-origin-width=&quot;968&quot; data-origin-height=&quot;638&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;426&quot; data-origin-height=&quot;248&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vHq3r/btsLPzuX9iN/hmZoUDh6hcKCAqKGvlMjCK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vHq3r/btsLPzuX9iN/hmZoUDh6hcKCAqKGvlMjCK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vHq3r/btsLPzuX9iN/hmZoUDh6hcKCAqKGvlMjCK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvHq3r%2FbtsLPzuX9iN%2FhmZoUDh6hcKCAqKGvlMjCK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;426&quot; height=&quot;248&quot; data-origin-width=&quot;426&quot; data-origin-height=&quot;248&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;주의점&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;여러 번 참조하는 경우는 아니었지만, WITH 구문을 사용했습니다.&lt;/li&gt;
&lt;li&gt;두 번이상 사용되는 WITH절은 결과값이 TEMP 영역에 저장된다고 합니다. TEMP 영역에 저장하기 위해서는 disk I/O가 발생합니다. 서브쿼리에 쓰인 데이터양이 적고 결과값을 도출하는데 큰 비용이 들지 않는다면, 굳이 WITH절로 빼지않고, 서브쿼리를 작성하는 것이 적은 비용이 들 수도 있습니다.&lt;/li&gt;
&lt;li&gt;이런 이유 때문에 오라클 12.2 버전부터 WITH절의 결과값을 disk I/O에 저장하지 않고, PGA 영역에 한 번 올린다음, 용량이 모자를 때 disk I/O에 올리는 방식을 사용했다고 합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;참고&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=Dtp2BypLwsM&quot;&gt;(추천SQL강좌/추천SQL교육)오라클 SQL기초 강좌#4, WITH구문 이란?(오라클교육/SQL교육/오라클동영상/SQL동영상/오라클강의/SQL강의/오라클강좌/SQL강좌)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=swr9A3PScuE&quot;&gt;WITH절, 남발하면 큰일나요! ☹️&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>  CS/Database</category>
      <category>with</category>
      <category>오라클</category>
      <author>jinnkimm7</author>
      <guid isPermaLink="true">https://devjk.tistory.com/71</guid>
      <comments>https://devjk.tistory.com/entry/%EC%98%A4%EB%9D%BC%ED%81%B4-WITH-%EA%B5%AC%EB%AC%B8#entry71comment</comments>
      <pubDate>Thu, 16 Jan 2025 00:26:24 +0900</pubDate>
    </item>
    <item>
      <title>[git] error: pathspec 'main' did not match any file(s) known to git</title>
      <link>https://devjk.tistory.com/entry/git-error-pathspec-main-did-not-match-any-files-known-to-git</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;문제&lt;/h2&gt;
&lt;pre class=&quot;subunit&quot;&gt;&lt;code&gt;❯ git checkout main
error: pathspec 'main' did not match any file(s) known to git&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;해결&lt;/h2&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;❯ git remote update
Fetching origin
remote: Enumerating objects: 6, done.
remote: Counting objects: 100% (6/6), done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 6 (delta 0), reused 3 (delta 0), pack-reused 0 (from 0)
Unpacking objects: 100% (6/6), 1.10 KiB | 161.00 KiB/s, done.
From https://github.com/jinnkimm7/simple-board-with-mybatis
 * [new branch]      main       -&amp;gt; origin/main
❯ git checkout main
branch 'main' set up to track 'origin/main'.
Switched to a new branch 'main'&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;git remote update : 모든 원격 브랜치를 업데이트하여 최신 상태로 갱신합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;참고&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://devcamus.tistory.com/8&quot;&gt;[git] 새로 만든 원격 브랜치로 checkout이 안될 때. - error: pathspec did not match any file(s) known to git 해결법&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>⚙️ Tool/git</category>
      <category>git</category>
      <author>jinnkimm7</author>
      <guid isPermaLink="true">https://devjk.tistory.com/70</guid>
      <comments>https://devjk.tistory.com/entry/git-error-pathspec-main-did-not-match-any-files-known-to-git#entry70comment</comments>
      <pubDate>Wed, 15 Jan 2025 22:48:39 +0900</pubDate>
    </item>
    <item>
      <title>[linux] 리눅스 기초 | 디렉토리와 파일</title>
      <link>https://devjk.tistory.com/entry/linux-%EB%A6%AC%EB%88%85%EC%8A%A4-%EA%B8%B0%EC%B4%88-%EB%94%94%EB%A0%89%ED%86%A0%EB%A6%AC%EC%99%80-%ED%8C%8C%EC%9D%BC</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;디렉토리와 파일에 관한 리눅스 기초 명렁어&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ls : list, 현재 디렉토리의 파일, 폴더를 검색&lt;br /&gt;ls -l : 현재 디렉토리 파일, 폴더 자세히 보기&lt;br /&gt;pwd : print working directory, 현재 위치하고 있는 디렉토리&lt;br /&gt;mkdir : make directory 새로 생성할 디렉토리명&lt;br /&gt;touch : 파일 생성, touch test.txt&lt;br /&gt;cd : change directory 이동할 디렉토리명, cd .. =&amp;gt; 현재 디렉토리의 부모 디렉토리로 이동&lt;br /&gt;clear : 터미널 clear&lt;br /&gt;rm : rm 삭제할 파일명&lt;br /&gt;rm -r : rm -r 삭제할 디렉토리명&lt;br /&gt;man : man ls =&amp;gt; ls 명령어에 대한 메뉴얼, /sort라고 입력하면 sort라는 단어를 중심으로 검색합니다. n 키를 누르면 다음 검색어로 건너뜁니다. q를 누르면 메뉴얼에서 벗어납니다.&lt;br /&gt;cp : copy, cp 복사할 파일/폴더 원하는 경로/이름, cp test.txt test2.txt&lt;br /&gt;mv : move, 파일이나 폴더를 이동시키거나 이름을 변경하는 명령어, mv test.txt test, mv test.txt test_renamed.txt&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;참고&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://yozm.wishket.com/magazine/detail/746/&quot;&gt;알아두면 유용한 맥 터미널 명령어 모음&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>  CS/Operation System</category>
      <category>리눅스</category>
      <author>jinnkimm7</author>
      <guid isPermaLink="true">https://devjk.tistory.com/69</guid>
      <comments>https://devjk.tistory.com/entry/linux-%EB%A6%AC%EB%88%85%EC%8A%A4-%EA%B8%B0%EC%B4%88-%EB%94%94%EB%A0%89%ED%86%A0%EB%A6%AC%EC%99%80-%ED%8C%8C%EC%9D%BC#entry69comment</comments>
      <pubDate>Wed, 15 Jan 2025 21:58:19 +0900</pubDate>
    </item>
    <item>
      <title>[오라클] NULL과 공백</title>
      <link>https://devjk.tistory.com/entry/%EC%98%A4%EB%9D%BC%ED%81%B4-NULL%EA%B3%BC-%EA%B3%B5%EB%B0%B1</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;중소기업 DB 직무 면접 봤었는데, 오라클에서 NULL을 구분할 수 있는지와 관련된 질문이 기술면접 질문 중 하나였습니다. 정답을 맞췄지만, 다시 정리하고자 포스팅합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요약하자면, 공백이 없는 ''은 NULL 처리하고, 공백이 있다면 문자열이기에 NULL 처리 되지 않습니다. 아래는 테스트 사진은 결과입니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1220&quot; data-origin-height=&quot;1030&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/XUu9D/btsLHMP9ukj/VNTdtgBQKfPu77XxEPY9x0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/XUu9D/btsLHMP9ukj/VNTdtgBQKfPu77XxEPY9x0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/XUu9D/btsLHMP9ukj/VNTdtgBQKfPu77XxEPY9x0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FXUu9D%2FbtsLHMP9ukj%2FVNTdtgBQKfPu77XxEPY9x0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;590&quot; height=&quot;498&quot; data-origin-width=&quot;1220&quot; data-origin-height=&quot;1030&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;682&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wHJ1C/btsLJjTsZBc/AUrCP8e7IrJBEyqzGi0LF0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wHJ1C/btsLJjTsZBc/AUrCP8e7IrJBEyqzGi0LF0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wHJ1C/btsLJjTsZBc/AUrCP8e7IrJBEyqzGi0LF0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwHJ1C%2FbtsLJjTsZBc%2FAUrCP8e7IrJBEyqzGi0LF0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;589&quot; height=&quot;372&quot; data-origin-width=&quot;1080&quot; data-origin-height=&quot;682&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>  CS/Database</category>
      <category>null</category>
      <category>오라클</category>
      <author>jinnkimm7</author>
      <guid isPermaLink="true">https://devjk.tistory.com/68</guid>
      <comments>https://devjk.tistory.com/entry/%EC%98%A4%EB%9D%BC%ED%81%B4-NULL%EA%B3%BC-%EA%B3%B5%EB%B0%B1#entry68comment</comments>
      <pubDate>Fri, 10 Jan 2025 00:00:47 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스] 잡은 물고기의 평균 길이 구하기 | MySQL</title>
      <link>https://devjk.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%9E%A1%EC%9D%80-%EB%AC%BC%EA%B3%A0%EA%B8%B0%EC%9D%98-%ED%8F%89%EA%B7%A0-%EA%B8%B8%EC%9D%B4-%EA%B5%AC%ED%95%98%EA%B8%B0-MySQL</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;문제&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/293259&quot;&gt;잡은 물고기의 평균 길이 구하기&lt;/a&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;풀이&lt;/h2&gt;
&lt;pre class=&quot;n1ql&quot;&gt;&lt;code&gt;SELECT ROUND(AVG(IFNULL(LENGTH, 10)), 2) AVERAGE_LENGTH
FROM FISH_INFO
;&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;오라클에서 NVL 대신 MySQL에서는 IFNULL을 사용할 수 있습니다.&lt;/li&gt;
&lt;li&gt;ROUND 함수를 이용해 n번째자리에서 반올림 할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>  Coding Test/SQL</category>
      <category>MYSQL</category>
      <category>코딩테스트</category>
      <category>프로그래머스</category>
      <author>jinnkimm7</author>
      <guid isPermaLink="true">https://devjk.tistory.com/67</guid>
      <comments>https://devjk.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%9E%A1%EC%9D%80-%EB%AC%BC%EA%B3%A0%EA%B8%B0%EC%9D%98-%ED%8F%89%EA%B7%A0-%EA%B8%B8%EC%9D%B4-%EA%B5%AC%ED%95%98%EA%B8%B0-MySQL#entry67comment</comments>
      <pubDate>Sun, 5 Jan 2025 22:37:10 +0900</pubDate>
    </item>
    <item>
      <title>[Java] 클래스 (2)</title>
      <link>https://devjk.tistory.com/entry/Java-%ED%81%B4%EB%9E%98%EC%8A%A4-2</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;생성자 다중 정의&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;생성자도 다중 정의할 수 있습니다.&lt;/li&gt;
&lt;li&gt;생성자가 다중 정의되었다고 할지라도, 호출되는 생성자는 1개입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;arduino&quot;&gt;&lt;code&gt;class MyString {
    private byte[] string;

    public MyString() {}
    public MyString(String param) {
        this.string = param.getBytes();
    }

    public MyString(int param) {
        String tmp;
        tmp = String.format(&quot;%d&quot;, param);
        this.string = tmp.getBytes();
    }

    public String getString() {
        if (string == null || string.length == 0) return &quot;(null)&quot;;
        return new String(string);
    }
}

public class Main {
    public static void main(String[] args) {
        MyString str1 = new MyString(&quot;Hello&quot;);
        MyString str2 = new MyString(&quot;123&quot;);
        System.out.println(str1.getString());
        System.out.println(str2.getString());
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;얕은 복사&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;840&quot; data-origin-height=&quot;460&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bFRfAx/btsLDlKvOer/IfpIJtAwL7vOI5txhrwpSK/img.webp&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bFRfAx/btsLDlKvOer/IfpIJtAwL7vOI5txhrwpSK/img.webp&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bFRfAx/btsLDlKvOer/IfpIJtAwL7vOI5txhrwpSK/img.webp&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbFRfAx%2FbtsLDlKvOer%2FIfpIJtAwL7vOI5txhrwpSK%2Fimg.webp&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;840&quot; height=&quot;460&quot; data-origin-width=&quot;840&quot; data-origin-height=&quot;460&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인스턴스가 늘어나는 것이 아니라 단순히 참조자만 늘어나는 경우입니다. 오류가 일어날 가능성이 큽니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;깊은 복사&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;원본 자체도 새로 할당하고, 복사하는 방식입니다. 실제로 인스턴스를 늘리는 것입니다.&lt;br /&gt;clone()을 사용하여 복사된 인스턴스를 만드는 방법이 있으나, 규약이 모호하고, 예외처리가 복잡하다라는 단점이 있습니다.&lt;br /&gt;복사 생성자를 이용하면 이 단점을 없앨 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;참조자와 인스턴스를 구별하는게 매우 중요합니다!&lt;/b&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;예제&lt;/h3&gt;
&lt;pre class=&quot;arduino&quot;&gt;&lt;code&gt;class MyString {
    private byte[] string;
    MyString() {
        string = null;
    }

    public MyString(String param) {
        string = param.getBytes();
    }

    public MyString(MyString rhs) {
        this.deepCopy(rhs);
    }

    public void deepCopy(MyString rhs) {
        this.string = rhs.string.clone();
    }

    public String getString() {
        if(string == null || string.length &amp;lt;= 0) {
            return &quot;(null)&quot;;
        }

        return new String(string);
    }

    public void setString(String param) {
        string = param.getBytes().clone();
    }
}

public class Main {
    public static void main(String[] args) {
        MyString src = new MyString(&quot;Hello&quot;);
        MyString dst = new MyString(src);

        src.setString(&quot;World&quot;);
        System.out.println(dst.getString());
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;정적 멤버 (static)&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;인스턴스가 없어도 호출이 가능한 멤버(필드, 메서드)입니다.&lt;/li&gt;
&lt;li&gt;this는 인스턴스를 가리키는 것이고, static은 인스턴스 메모리를 같이 쓰지 않기 때문에, this로 정적 멤버에 접근할 수 없습니다.&lt;/li&gt;
&lt;li&gt;final과 함께 선언함으로써 심볼릭 상수로 사용하는 경우가 많습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;정적 메서드로 MyString 클래스 작성하기&lt;/h2&gt;
&lt;pre class=&quot;reasonml&quot;&gt;&lt;code&gt;class MyString {
    private byte[] string;
    private static int count;

    private MyString() {
        string = null;
    }

    private MyString(int param) {
        this.string = String.format(&quot;%d&quot;, param).getBytes();
    }

    private MyString(String param) {
        this.string = param.getBytes();
    }

    public String getString() {
        if(string == null || string.length &amp;lt;= 0) {
            return &quot;(null)&quot;;
        }

        return new String(string);
    }

    public static MyString newString(int param) {
        count++;
        return new MyString(param);
    }

    public static MyString newString(String param) {
        count++;

        if(param == null || param.length() == 0) {
            return new MyString(&quot;(null)&quot;);
        }

        return new MyString(param);
    }

    public static int getCount() {
        return MyString.count;
    }
}

public class Main {
    public static void main(String[] args) {
        // MyString src = new MyString(&quot;Hello&quot;);
        MyString s1 = MyString.newString(10);
        MyString s2 = MyString.newString(&quot;Test&quot;);

        System.out.println(s1.getString());
        System.out.println(s2.getString());
        System.out.println(MyString.getCount());
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;출처&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://www.inflearn.com/course/%EB%8F%85%ED%95%98%EA%B2%8C-%EC%8B%9C%EC%9E%91%ED%95%98%EB%8A%94-java-part2/dashboard&quot;&gt;기초 탄탄! 독하게 시작하는 Java - Part 2 : OOP와 JVM&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category> &amp;zwj;  Programming/Java</category>
      <category>java</category>
      <category>클래스</category>
      <author>jinnkimm7</author>
      <guid isPermaLink="true">https://devjk.tistory.com/66</guid>
      <comments>https://devjk.tistory.com/entry/Java-%ED%81%B4%EB%9E%98%EC%8A%A4-2#entry66comment</comments>
      <pubDate>Sat, 4 Jan 2025 19:39:43 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스] 물고기 종류 별 대어 찾기 | MySQL</title>
      <link>https://devjk.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EB%AC%BC%EA%B3%A0%EA%B8%B0-%EC%A2%85%EB%A5%98-%EB%B3%84-%EB%8C%80%EC%96%B4-%EC%B0%BE%EA%B8%B0-MySQL</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;문제&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/293261?language=mysql&quot;&gt;물고기 종류 별 대어 찾기&lt;/a&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;풀이&lt;/h2&gt;
&lt;pre class=&quot;n1ql&quot;&gt;&lt;code&gt;SELECT FI.ID, FN.FISH_NAME, FI.LENGTH
FROM FISH_INFO FI JOIN FISH_NAME_INFO FN ON FI.FISH_TYPE = FN.FISH_TYPE
WHERE (FI.FISH_TYPE, FI.LENGTH) IN (
 SELECT FISH_TYPE, MAX(LENGTH)
 FROM FISH_INFO
 GROUP BY FISH_TYPE
)
ORDER BY FI.ID
;&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;WHERE 조건에 FISH_TYPE까지 넣어줘야 정확하게 쿼리를 추출할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>  Coding Test/SQL</category>
      <category>MYSQL</category>
      <category>코딩테스트</category>
      <category>프로그래머스</category>
      <author>jinnkimm7</author>
      <guid isPermaLink="true">https://devjk.tistory.com/65</guid>
      <comments>https://devjk.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EB%AC%BC%EA%B3%A0%EA%B8%B0-%EC%A2%85%EB%A5%98-%EB%B3%84-%EB%8C%80%EC%96%B4-%EC%B0%BE%EA%B8%B0-MySQL#entry65comment</comments>
      <pubDate>Sat, 4 Jan 2025 19:06:03 +0900</pubDate>
    </item>
    <item>
      <title>원하는만큼의 데이터 가져오기 (오라클, MySQL)</title>
      <link>https://devjk.tistory.com/entry/%EC%9B%90%ED%95%98%EB%8A%94%EB%A7%8C%ED%81%BC%EC%9D%98-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EA%B0%80%EC%A0%B8%EC%98%A4%EA%B8%B0-%EC%98%A4%EB%9D%BC%ED%81%B4-MySQL</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;오라클&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;ROWNUM을 활용하여 원하는만큼의 데이터를 가져올 수 있습니다.&lt;/li&gt;
&lt;li&gt;특정한 기준으로 정렬한 후, 원하는만큼의 데이터를 추출하기 위해서 서브쿼리를 사용합니다.&lt;/li&gt;
&lt;li&gt;예제 - &lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/59405?language=oracle&quot;&gt;상위 n개 레코드&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;sql&quot;&gt;&lt;code&gt;SELECT NAME
FROM (
    SELECT *
    FROM ANIMAL_INS
    ORDER BY DATETIME
)
WHERE ROWNUM &amp;lt;= 1
;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;MySQL&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;LIMIT를 활용하여 원하는만큼의 데이터를 가져올 수 있습니다.&lt;/li&gt;
&lt;li&gt;예제 - &lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/298517?language=mysql&quot;&gt;가장 큰 물고기 10마리 구하기&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;sql&quot;&gt;&lt;code&gt;SELECT ID, LENGTH
FROM FISH_INFO
WHERE LENGTH &amp;gt;= 10
ORDER BY LENGTH DESC, ID
LIMIT 10
;&lt;/code&gt;&lt;/pre&gt;</description>
      <category>  Coding Test/SQL</category>
      <category>MYSQL</category>
      <category>SQL</category>
      <category>오라클</category>
      <author>jinnkimm7</author>
      <guid isPermaLink="true">https://devjk.tistory.com/64</guid>
      <comments>https://devjk.tistory.com/entry/%EC%9B%90%ED%95%98%EB%8A%94%EB%A7%8C%ED%81%BC%EC%9D%98-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EA%B0%80%EC%A0%B8%EC%98%A4%EA%B8%B0-%EC%98%A4%EB%9D%BC%ED%81%B4-MySQL#entry64comment</comments>
      <pubDate>Fri, 3 Jan 2025 21:10:23 +0900</pubDate>
    </item>
    <item>
      <title>[Excel] 엑셀 다른 시트로 이동하기, 화면 확대축소 단축키</title>
      <link>https://devjk.tistory.com/entry/Excel-%EC%97%91%EC%85%80-%EB%8B%A8%EC%B6%95%ED%82%A4</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;오늘 자주 사용했던 엑셀 단축키&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;다른 시트로 이동하기 : ctrl + page up / page down&lt;/li&gt;
&lt;li&gt;화면 확대 / 축소 : Ctrl + 마우스휠&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>⚙️ Tool/Excel</category>
      <category>엑셀</category>
      <author>jinnkimm7</author>
      <guid isPermaLink="true">https://devjk.tistory.com/63</guid>
      <comments>https://devjk.tistory.com/entry/Excel-%EC%97%91%EC%85%80-%EB%8B%A8%EC%B6%95%ED%82%A4#entry63comment</comments>
      <pubDate>Fri, 3 Jan 2025 12:38:17 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스] 대여 횟수가 많은 자동차들의 월별 대여 횟수 구하기 | 오라클</title>
      <link>https://devjk.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EB%8C%80%EC%97%AC-%ED%9A%9F%EC%88%98%EA%B0%80-%EB%A7%8E%EC%9D%80-%EC%9E%90%EB%8F%99%EC%B0%A8%EB%93%A4%EC%9D%98-%EC%9B%94%EB%B3%84-%EB%8C%80%EC%97%AC-%ED%9A%9F%EC%88%98-%EA%B5%AC%ED%95%98%EA%B8%B0-%EC%98%A4%EB%9D%BC%ED%81%B4</link>
      <description>&lt;h2&gt;문제&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/151139?language=oracle&quot;&gt;대여 횟수가 많은 자동차들의 월별 대여 횟수 구하기&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;풀이&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;SELECT 
 TO_NUMBER(TO_CHAR(START_DATE, &amp;#39;MM&amp;#39;)) MONTH, 
 CAR_ID, 
 COUNT(*) RECORDS
FROM 
 CAR_RENTAL_COMPANY_RENTAL_HISTORY
WHERE 
 CAR_ID IN (
    SELECT CAR_ID
    FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY
    WHERE TO_CHAR(START_DATE, &amp;#39;YYYYMM&amp;#39;) &amp;gt;= &amp;#39;202208&amp;#39; AND TO_CHAR(START_DATE, &amp;#39;YYYYMM&amp;#39;) &amp;lt;= &amp;#39;202210&amp;#39;
    GROUP BY CAR_ID
    HAVING COUNT(*) &amp;gt;= 5
 ) AND TO_CHAR(START_DATE, &amp;#39;YYYYMM&amp;#39;) &amp;gt;= &amp;#39;202208&amp;#39; AND TO_CHAR(START_DATE, &amp;#39;YYYYMM&amp;#39;) &amp;lt;= &amp;#39;202210&amp;#39;
GROUP BY 
 TO_CHAR(START_DATE, &amp;#39;MM&amp;#39;), CAR_ID
ORDER BY 
 MONTH, CAR_ID DESC
;&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;COUNT(*)을 하면 데이터가 없어도 1로 출력하기 때문에, COUNT(B.DATETIME)으로 작성했습니다.&lt;/li&gt;
&lt;li&gt;0부터 23을 가진 테이블을 만들어주기 위해 CONNECT BY(계층적 쿼리)를 사용하였습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;참고&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;우선 서브쿼리를 이용하여 대여 시작일을 기준으로 총 대여 횟수가 5회 이상인 CAR_ID를 찾아 내고, 풀이하였습니다.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>  Coding Test/SQL</category>
      <category>SQL</category>
      <category>오라클</category>
      <category>프로그래머스</category>
      <author>jinnkimm7</author>
      <guid isPermaLink="true">https://devjk.tistory.com/62</guid>
      <comments>https://devjk.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EB%8C%80%EC%97%AC-%ED%9A%9F%EC%88%98%EA%B0%80-%EB%A7%8E%EC%9D%80-%EC%9E%90%EB%8F%99%EC%B0%A8%EB%93%A4%EC%9D%98-%EC%9B%94%EB%B3%84-%EB%8C%80%EC%97%AC-%ED%9A%9F%EC%88%98-%EA%B5%AC%ED%95%98%EA%B8%B0-%EC%98%A4%EB%9D%BC%ED%81%B4#entry62comment</comments>
      <pubDate>Wed, 1 Jan 2025 20:05:44 +0900</pubDate>
    </item>
    <item>
      <title>[Java] 클래스 (1)</title>
      <link>https://devjk.tistory.com/entry/Java-%ED%81%B4%EB%9E%98%EC%8A%A4-1</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;Object(객체)&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;OOP에서 소스코드를 구성하는 단위요소입니다.&lt;/li&gt;
&lt;li&gt;자바에서는 클래스라는 문법으로 객체를 기술하고, 클래스는 반드시 존재 이유와 목적이 명확해야합니다.&lt;/li&gt;
&lt;li&gt;클래스에서 생성된 객체를 인스턴스라고 부릅니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*OOP(Object-Oriented Programming)&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;프로그램을 객체의 집합체로 보고 객체들은 서로 관계를 갖는다는 관점을 갖고 프로그래밍하는 것입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;클래스&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;클래스 안에 있는 변수나 함수를 멤버라고 부릅니다.&lt;/li&gt;
&lt;li&gt;더 자세히 변수는 필드, 함수는 메서드라고 부릅니다.&lt;/li&gt;
&lt;li&gt;선언과 정의가 공존하는 구조입니다.&lt;/li&gt;
&lt;li&gt;객체를 사용할 사람을 배려하여 작성하는 능력이 필수적으로 요구됩니다.&lt;/li&gt;
&lt;li&gt;클래스는 constructor, field, method로 구성됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;접근제어자&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;public : 외부 접근 허용&lt;/li&gt;
&lt;li&gt;protected : 같은 패키지 및 파생 클래스의 접근 허용&lt;/li&gt;
&lt;li&gt;default : 같은 패키지 소속 클래스만 접근 허용, 아무 접근 제어자를 사용 안했을 시 default&lt;/li&gt;
&lt;li&gt;private : 내부에서만 접근 허용&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;*기본적으로 필드들은 private 선언을 하여 캡슐화를 시키고, getter와 setter로 통제하는 것이 좋습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;this&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;인스턴스는 new 연산자를 통해서 사용자에 의해 미래 시점에 생성됩니다. 본인이 클래스를 작성하고 있는 시점을 현재라고 가정했을 때, 미래의 인스턴스가 어떤 메모리를 사용할지 알수가 없습니다.&lt;/li&gt;
&lt;li&gt;미래 시점에 메모리 어디엔가 인스턴스 주소값이 저장 될 것이고, 그 주소값을 가리키는 것이 &lt;code&gt;this&lt;/code&gt;입니다.&lt;/li&gt;
&lt;li&gt;같은 클래스에 대한 인스턴스라 할지라도 this 값을 서로 다른 값이 됩니다.&lt;/li&gt;
&lt;li&gt;정적 메서드(static 메서드)에서 this를 사용할 수 없습니다. 정적메서드는 독립적이므로 인스턴스와 관련이 없기 때문입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;예제&lt;/h2&gt;
&lt;pre class=&quot;arduino&quot;&gt;&lt;code&gt;class MyString {
    private byte[] string;

    public String getString() {
        if (string == null || string.length == 0) return &quot;(null)&quot;;
        return new String(string);
    }

    public void setString(String param) {
        this.string = param.getBytes();
    }

    public int length() {
        if (string == null) return 0;
        return this.string.length;
    }

    public int compareTo(String param) {
        if (string == null) return -1;
        return param.compareTo(new String(string));
    }
}

public class Main {
    public static void main(String[] args) {
        MyString str = new MyString();
        System.out.println(str.length()); // 0
        System.out.println(str.getString()); // (null)

        str.setString(&quot;Hello, world!&quot;);
        System.out.println(str.getString()); // Hello, world!
        System.out.println(str.length()); // 13
        System.out.println(str.compareTo(&quot;Hello, world!&quot;)); // 0
        System.out.println(str.compareTo(&quot;Hello, world&quot;)); // -1
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;출처&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://www.inflearn.com/course/%EB%8F%85%ED%95%98%EA%B2%8C-%EC%8B%9C%EC%9E%91%ED%95%98%EB%8A%94-java-part2/dashboard&quot;&gt;기초 탄탄! 독하게 시작하는 Java - Part 2 : OOP와 JVM&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category> &amp;zwj;  Programming/Java</category>
      <category>java</category>
      <category>클래스</category>
      <author>jinnkimm7</author>
      <guid isPermaLink="true">https://devjk.tistory.com/61</guid>
      <comments>https://devjk.tistory.com/entry/Java-%ED%81%B4%EB%9E%98%EC%8A%A4-1#entry61comment</comments>
      <pubDate>Tue, 31 Dec 2024 08:19:37 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스] 입양 시각 구하기(2) | 오라클</title>
      <link>https://devjk.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%9E%85%EC%96%91-%EC%8B%9C%EA%B0%81-%EA%B5%AC%ED%95%98%EA%B8%B02-%EC%98%A4%EB%9D%BC%ED%81%B4</link>
      <description>&lt;h2&gt;문제&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/59413?language=oracle&quot;&gt;입양 시각 구하기(2)&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;풀이&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;SELECT A.HOUR, COUNT(B.DATETIME) COUNT
FROM (SELECT LEVEL - 1 AS HOUR FROM DUAL CONNECT BY LEVEL &amp;lt;= 24) A LEFT JOIN
 ANIMAL_OUTS B ON A.HOUR = TO_CHAR(B.DATETIME, &amp;#39;HH24&amp;#39;)
GROUP BY A.HOUR
ORDER BY 1
;&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;COUNT(*)을 하면 데이터가 없어도 1로 출력하기 때문에, COUNT(B.DATETIME)으로 작성했습니다.&lt;/li&gt;
&lt;li&gt;0부터 23을 가진 테이블을 만들어주기 위해 CONNECT BY(계층적 쿼리)를 사용하였습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;참고&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://meyouus.tistory.com/175&quot;&gt;오라클 순번 채번 CONNECT BY LEVEL 활용하기&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://gent.tistory.com/640&quot;&gt;[Oracle] 오라클 CONNECT BY 사용법 (계층형 쿼리)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>  Coding Test/SQL</category>
      <category>SQL</category>
      <category>오라클</category>
      <category>프로그래머스</category>
      <author>jinnkimm7</author>
      <guid isPermaLink="true">https://devjk.tistory.com/60</guid>
      <comments>https://devjk.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%9E%85%EC%96%91-%EC%8B%9C%EA%B0%81-%EA%B5%AC%ED%95%98%EA%B8%B02-%EC%98%A4%EB%9D%BC%ED%81%B4#entry60comment</comments>
      <pubDate>Mon, 30 Dec 2024 08:07:18 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스] 년, 월, 성별 별 상품 구매 회원 수 구하기 | 오라클</title>
      <link>https://devjk.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EB%85%84-%EC%9B%94-%EC%84%B1%EB%B3%84-%EB%B3%84-%EC%83%81%ED%92%88-%EA%B5%AC%EB%A7%A4-%ED%9A%8C%EC%9B%90-%EC%88%98-%EA%B5%AC%ED%95%98%EA%B8%B0-%EC%98%A4%EB%9D%BC%ED%81%B4</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;문제&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/131532?language=oracle&quot;&gt;식품분류별 가장 비싼 식품의 정보 조회하기&lt;/a&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;풀이&lt;/h2&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;SELECT 
 TO_CHAR(B.SALES_DATE, 'YYYY') YEAR,
 TO_NUMBER(TO_CHAR(B.SALES_DATE, 'MM')) MONTH,
 GENDER,
 COUNT(DISTINCT A.USER_ID) USERS
FROM USER_INFO A JOIN ONLINE_SALE B
 ON A.USER_ID = B.USER_ID
WHERE GENDER IS NOT NULL
GROUP BY TO_CHAR(B.SALES_DATE, 'YYYY'),
 TO_NUMBER(TO_CHAR(B.SALES_DATE, 'MM')),
 GENDER
ORDER BY 1, 2, 3
;&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;1자리 숫자의 달의 경우 앞의 0을 제거하기 위해, TO_NUMBER를 사용했습니다.&lt;/li&gt;
&lt;li&gt;중복되는 유저가 카운트 되는것을 막기 위해 DISTINCT를 사용했습니다.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>  Coding Test/SQL</category>
      <category>SQL</category>
      <category>오라클</category>
      <category>프로그래머스</category>
      <author>jinnkimm7</author>
      <guid isPermaLink="true">https://devjk.tistory.com/59</guid>
      <comments>https://devjk.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EB%85%84-%EC%9B%94-%EC%84%B1%EB%B3%84-%EB%B3%84-%EC%83%81%ED%92%88-%EA%B5%AC%EB%A7%A4-%ED%9A%8C%EC%9B%90-%EC%88%98-%EA%B5%AC%ED%95%98%EA%B8%B0-%EC%98%A4%EB%9D%BC%ED%81%B4#entry59comment</comments>
      <pubDate>Thu, 26 Dec 2024 08:04:57 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스] 식품분류별 가장 비싼 식품의 정보 조회하기 | 오라클</title>
      <link>https://devjk.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%8B%9D%ED%92%88%EB%B6%84%EB%A5%98%EB%B3%84-%EA%B0%80%EC%9E%A5-%EB%B9%84%EC%8B%BC-%EC%8B%9D%ED%92%88%EC%9D%98-%EC%A0%95%EB%B3%B4-%EC%A1%B0%ED%9A%8C%ED%95%98%EA%B8%B0-%EC%98%A4%EB%9D%BC%ED%81%B4</link>
      <description>&lt;h2&gt;문제&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/131116?language=oracle&quot;&gt;식품분류별 가장 비싼 식품의 정보 조회하기&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;풀이&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;SELECT CATEGORY, PRICE MAX_PRICE, PRODUCT_NAME
FROM FOOD_PRODUCT
WHERE (CATEGORY, PRICE) IN (
    SELECT CATEGORY, MAX(PRICE)
    FROM FOOD_PRODUCT
    WHERE CATEGORY IN (&amp;#39;과자&amp;#39;, &amp;#39;국&amp;#39;, &amp;#39;김치&amp;#39;, &amp;#39;식용유&amp;#39;)
    GROUP BY CATEGORY
)
ORDER BY MAX_PRICE DESC
;&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;서브쿼리를 활용하여 문제를 해결했습니다.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>  Coding Test/SQL</category>
      <category>SQL</category>
      <category>오라클</category>
      <category>프로그래머스</category>
      <author>jinnkimm7</author>
      <guid isPermaLink="true">https://devjk.tistory.com/58</guid>
      <comments>https://devjk.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%8B%9D%ED%92%88%EB%B6%84%EB%A5%98%EB%B3%84-%EA%B0%80%EC%9E%A5-%EB%B9%84%EC%8B%BC-%EC%8B%9D%ED%92%88%EC%9D%98-%EC%A0%95%EB%B3%B4-%EC%A1%B0%ED%9A%8C%ED%95%98%EA%B8%B0-%EC%98%A4%EB%9D%BC%ED%81%B4#entry58comment</comments>
      <pubDate>Mon, 23 Dec 2024 20:57:58 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스] 보호소에서 중성화한 동물 | 오라클</title>
      <link>https://devjk.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EB%B3%B4%ED%98%B8%EC%86%8C%EC%97%90%EC%84%9C-%EC%A4%91%EC%84%B1%ED%99%94%ED%95%9C-%EB%8F%99%EB%AC%BC-%EC%98%A4%EB%9D%BC%ED%81%B4</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;문제&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/59045?language=oracle&quot;&gt;보호소에서 중성화한 동물&lt;/a&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;풀이&lt;/h2&gt;
&lt;pre class=&quot;pgsql&quot;&gt;&lt;code&gt;SELECT AI.ANIMAL_ID, AI.ANIMAL_TYPE, AI.NAME
FROM ANIMAL_INS AI JOIN ANIMAL_OUTS AO
ON AI.ANIMAL_ID = AO.ANIMAL_ID
WHERE (AI.SEX_UPON_INTAKE LIKE 'Intact%') AND (AO.SEX_UPON_OUTCOME LIKE 'Spayed%' OR AO.SEX_UPON_OUTCOME LIKE 'Neutered%')
ORDER BY 1
;&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;WHERE 조건을 다음과 같이 작성해도 됩니다.
&lt;pre class=&quot;pgsql&quot;&gt;&lt;code&gt;WHERE AI.SEX_UPON_INTAKE LIKE 'Intact%' AND AO.SEX_UPON_OUTCOME NOT LIKE 'Intact%'&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>  Coding Test/SQL</category>
      <category>SQL</category>
      <category>오라클</category>
      <category>코딩테스트</category>
      <author>jinnkimm7</author>
      <guid isPermaLink="true">https://devjk.tistory.com/57</guid>
      <comments>https://devjk.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EB%B3%B4%ED%98%B8%EC%86%8C%EC%97%90%EC%84%9C-%EC%A4%91%EC%84%B1%ED%99%94%ED%95%9C-%EB%8F%99%EB%AC%BC-%EC%98%A4%EB%9D%BC%ED%81%B4#entry57comment</comments>
      <pubDate>Sun, 22 Dec 2024 23:14:54 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스] 오프라인/온라인 판매 데이터 통합하기 | 오라클</title>
      <link>https://devjk.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%98%A4%ED%94%84%EB%9D%BC%EC%9D%B8%EC%98%A8%EB%9D%BC%EC%9D%B8-%ED%8C%90%EB%A7%A4-%EB%8D%B0%EC%9D%B4%ED%84%B0-%ED%86%B5%ED%95%A9%ED%95%98%EA%B8%B0-%EC%98%A4%EB%9D%BC%ED%81%B4</link>
      <description>&lt;h2&gt;문제&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/131537?language=oracle&quot;&gt;오프라인/온라인 판매 데이터 통합하기&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;풀이&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;SELECT TO_CHAR(SALES_DATE, &amp;#39;YYYY-MM-DD&amp;#39;) SALES_DATE, PRODUCT_ID, USER_ID, SALES_AMOUNT
FROM (
    SELECT SALES_DATE, PRODUCT_ID, USER_ID, SALES_AMOUNT
    FROM ONLINE_SALE
    UNION
    SELECT SALES_DATE, PRODUCT_ID, NULL, SALES_AMOUNT
    FROM OFFLINE_SALE
)
WHERE TO_CHAR(SALES_DATE, &amp;#39;YYYY-MM-DD&amp;#39;) LIKE &amp;#39;2022-03%&amp;#39;
ORDER BY 1, 2, 3
;&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;UNION을 사용하여 풀이했습니다.&lt;ul&gt;
&lt;li&gt;UNION은 중복된 데이터를 제거하고, UNION ALL은 중복된 데이터를 제거하지 않습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;NULL을 사용해서 컬럼을 만들 수 있다는 것을 배웠습니다.&lt;/li&gt;
&lt;li&gt;ORDER BY에 컬럼명을 직접 쓰는 대신에 숫자를 사용하여 간단하게 쿼리를 작성할 수 있다는 것을 배웠습니다.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>  Coding Test/SQL</category>
      <category>SQL</category>
      <category>오라클</category>
      <category>코딩테스트</category>
      <author>jinnkimm7</author>
      <guid isPermaLink="true">https://devjk.tistory.com/56</guid>
      <comments>https://devjk.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%98%A4%ED%94%84%EB%9D%BC%EC%9D%B8%EC%98%A8%EB%9D%BC%EC%9D%B8-%ED%8C%90%EB%A7%A4-%EB%8D%B0%EC%9D%B4%ED%84%B0-%ED%86%B5%ED%95%A9%ED%95%98%EA%B8%B0-%EC%98%A4%EB%9D%BC%ED%81%B4#entry56comment</comments>
      <pubDate>Thu, 19 Dec 2024 23:45:20 +0900</pubDate>
    </item>
    <item>
      <title>[Oracle] 오라클 데이터베이스 버전 확인 쿼리</title>
      <link>https://devjk.tistory.com/entry/Oracle-%EC%98%A4%EB%9D%BC%ED%81%B4-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4-%EB%B2%84%EC%A0%84-%ED%99%95%EC%9D%B8-%EC%BF%BC%EB%A6%AC</link>
      <description>&lt;h2&gt;오라클 데이터베이스 버전 확인 쿼리&lt;/h2&gt;
&lt;p&gt;오라클 데이터베이스 버전을 확인할 수 있는 쿼리입니다.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;select * from v$version;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;화면 캡처 2024-12-19 174930.png&quot; data-origin-width=&quot;447&quot; data-origin-height=&quot;179&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kEF6k/btsLo9jDc5D/39ttxFsKhiQt7T9LMAqvV1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kEF6k/btsLo9jDc5D/39ttxFsKhiQt7T9LMAqvV1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kEF6k/btsLo9jDc5D/39ttxFsKhiQt7T9LMAqvV1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkEF6k%2FbtsLo9jDc5D%2F39ttxFsKhiQt7T9LMAqvV1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;447&quot; height=&quot;179&quot; data-filename=&quot;화면 캡처 2024-12-19 174930.png&quot; data-origin-width=&quot;447&quot; data-origin-height=&quot;179&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;화면 캡처 2024-12-19 174804.png&quot; data-origin-width=&quot;532&quot; data-origin-height=&quot;147&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/blWBdX/btsLoxkGMT6/9kwi6cDskNRKK6wfJMSGmK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/blWBdX/btsLoxkGMT6/9kwi6cDskNRKK6wfJMSGmK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/blWBdX/btsLoxkGMT6/9kwi6cDskNRKK6wfJMSGmK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FblWBdX%2FbtsLoxkGMT6%2F9kwi6cDskNRKK6wfJMSGmK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;532&quot; height=&quot;147&quot; data-filename=&quot;화면 캡처 2024-12-19 174804.png&quot; data-origin-width=&quot;532&quot; data-origin-height=&quot;147&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2&gt;오라클 10g&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;10버전부터 오라클의 인터넷에서 그리드로 서비스를 업그레이드 하는 시기에 발표한 버전&lt;/li&gt;
&lt;li&gt;기업내의 중소형 서버를 연결시켜 유휴자원을 활용&lt;/li&gt;
&lt;li&gt;하나의 커다란 서버로 활용할 수 있기 때문에 무리하게 서버를 구입할 필요가 없어짐.&lt;/li&gt;
&lt;li&gt;Provisioning(프로비저닝), Load Balancing(부하관리), Automation(자동화) 지원&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;참고&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://codelabs.tistory.com/18&quot;&gt;[ORACLE] 오라클 - 2. 오라클 버전별 특징 및 차이점&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>  CS/Database</category>
      <category>오라클</category>
      <author>jinnkimm7</author>
      <guid isPermaLink="true">https://devjk.tistory.com/55</guid>
      <comments>https://devjk.tistory.com/entry/Oracle-%EC%98%A4%EB%9D%BC%ED%81%B4-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4-%EB%B2%84%EC%A0%84-%ED%99%95%EC%9D%B8-%EC%BF%BC%EB%A6%AC#entry55comment</comments>
      <pubDate>Thu, 19 Dec 2024 17:50:05 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스] 서울에 위치한 식당 목록 출력하기 | 오라클</title>
      <link>https://devjk.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%84%9C%EC%9A%B8%EC%97%90-%EC%9C%84%EC%B9%98%ED%95%9C-%EC%8B%9D%EB%8B%B9-%EB%AA%A9%EB%A1%9D-%EC%B6%9C%EB%A0%A5%ED%95%98%EA%B8%B0-%EC%98%A4%EB%9D%BC%ED%81%B4</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;문제&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/131118?language=oracle&quot;&gt;자동차 대여 기록 별 대여 금액 구하기&lt;/a&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;풀이&lt;/h2&gt;
&lt;pre class=&quot;sql&quot;&gt;&lt;code&gt;SELECT A.REST_ID, A.REST_NAME, A.FOOD_TYPE, A.FAVORITES, A.ADDRESS, B.REVIEW_SCORE
FROM REST_INFO A JOIN 
(SELECT REST_ID, ROUND(AVG(REVIEW_SCORE), 2) REVIEW_SCORE FROM REST_REVIEW GROUP BY REST_ID) B
ON A.REST_ID = B.REST_ID
WHERE A.ADDRESS LIKE '서울%'
ORDER BY REVIEW_SCORE DESC, FAVORITES DESC
;&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;REST_ID와 리뷰점수 평균 두 개의 컬럼을 갖는 인라인 뷰를 만들어 조인하여 풀이하였습니다.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>  Coding Test/SQL</category>
      <category>SQL</category>
      <category>오라클</category>
      <category>프로그래머스</category>
      <author>jinnkimm7</author>
      <guid isPermaLink="true">https://devjk.tistory.com/54</guid>
      <comments>https://devjk.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%84%9C%EC%9A%B8%EC%97%90-%EC%9C%84%EC%B9%98%ED%95%9C-%EC%8B%9D%EB%8B%B9-%EB%AA%A9%EB%A1%9D-%EC%B6%9C%EB%A0%A5%ED%95%98%EA%B8%B0-%EC%98%A4%EB%9D%BC%ED%81%B4#entry54comment</comments>
      <pubDate>Wed, 18 Dec 2024 22:31:09 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스 Lv0] 숨어있는 숫자의 덧셈 (2) | 자바</title>
      <link>https://devjk.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-Lv0-%EC%88%A8%EC%96%B4%EC%9E%88%EB%8A%94-%EC%88%AB%EC%9E%90%EC%9D%98-%EB%8D%A7%EC%85%88-2-%EC%9E%90%EB%B0%94</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;문제&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/120864&quot;&gt;숨어있는 숫자의 덧셈 (2)&lt;/a&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;풀이&lt;/h2&gt;
&lt;pre class=&quot;arduino&quot;&gt;&lt;code&gt;class Solution {
    public int solution(String my_string) {
        int answer = 0;

        String[] strArr = my_string.replaceAll(&quot;[a-zA-Z]&quot;, &quot; &quot;).split(&quot; &quot;);

        for(String str : strArr) {
            if(!str.equals(&quot;&quot;)) answer += Integer.parseInt(str);
        }

        return answer;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;모든 알파벳을 제거해야하는데 replaceAll(&quot;[a-zA-Z]&quot;, &quot; &quot;)를 사용하여 모든 알파벳을 제거할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>  Coding Test/Programmers Lv0</category>
      <category>코딩테스트</category>
      <category>프로그래머스</category>
      <author>jinnkimm7</author>
      <guid isPermaLink="true">https://devjk.tistory.com/53</guid>
      <comments>https://devjk.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-Lv0-%EC%88%A8%EC%96%B4%EC%9E%88%EB%8A%94-%EC%88%AB%EC%9E%90%EC%9D%98-%EB%8D%A7%EC%85%88-2-%EC%9E%90%EB%B0%94#entry53comment</comments>
      <pubDate>Wed, 18 Dec 2024 19:41:19 +0900</pubDate>
    </item>
    <item>
      <title>[JavaScript] var, let, const</title>
      <link>https://devjk.tistory.com/entry/JavaScript-var-let-const</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;자바스크립트에서 변수를 선언하는 방법은 var, let, const 세 가지가 있습니다. ES5까지 var가 유일한 변수 선언문이였지만, ES6 이후 var 사용을 지양하고 let, const를 사용합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그 이유는 아래와 같습니다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;var는 변수의 중복선언이 가능합니다.&lt;/li&gt;
&lt;li&gt;변수 호이스팅(hoisting)이 발생하여, 변수 선언이전에도 사용이 가능합니다.&lt;/li&gt;
&lt;li&gt;var는 함수레벨 스코프라, 함수 내부의 변수 외에는 모두 전역 변수가 되버립니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 항목들이 어떤 문제가 생기는지 하나씩 알아보겠습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;변수 중복 선언&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;var는 같은 이름으로 중복선언이 가능합니다. 중복선언을 하게 된다면, 의도치 않게 값이 변경될 수 있고, 이는 오류로 이어질 수 있습니다.&lt;/p&gt;
&lt;pre class=&quot;delphi&quot;&gt;&lt;code&gt;var name = jin;
var name = kim;

var age = 20;
var age; // 초기화문이 없다면 변수 선언문은 무시됩니다.

console.log(name); // kim
console.log(age); // 20

let name = jin;
let name = kim; // Uncaught SyntaxError: Identifier 'name' has already been declared&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;호이스팅&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;var로 선언된 변수는 변수 호이스팅에 의해 변수 선언문이 스코프의 선두로 끌어 올려진 것처럼 동작합니다.&lt;/p&gt;
&lt;pre class=&quot;abnf&quot;&gt;&lt;code&gt;console.log(hi); // undefined

var hi;
hi = 100;
console.log(hi); // 100&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫 번째 줄에 변수 hi를 호출했습니다. 참조할 변수가 없어 참조 에러가 발생해야하지만, undefined이 출력됩니다. 그 이유는 자바스크립트 엔진의 동작 과정 때문입니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;자바스크립트 엔진 동작 과정&lt;br /&gt;자바스크립트 엔진이 코드를 실행하기 전에, 먼저 실행되어 소스코드의 평가 과정을 거칩니다.&lt;br /&gt;평가 과정에서 자바스크립트 엔진은 var, let, const, function, class 등을 소스 코드에서 찾아내 먼저 실행합니다.&lt;br /&gt;평가 과정이 끝난 이후, 위에서부터 차례대로 한줄씩 코드를 실행합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;변수 선언이 어디에 존재하든 어디서든 변수를 참조할 수 있기 때문에, 변수 선언문이 코드의 선두로 끌어 올려진 것처럼 동작하는 자바스크립트의 고유의 특징을 호이스팅(hoisting)이라고 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;var가 아닌 let으로 실행하면 어떻게 될까요?&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;console.log(hi); // ReferenceError: hi is not defined

let hi; // 변수 선언문에서 초기화 단계가 실행됩니다.
console.log(hi); // undefined
hi = 100; // 변수 할당
console.log(hi); // 100&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;첫번째 코드에서 참조에러가 발생했습니다. 자바스크립트 엔진 동작과정에서 let으로 선언된 hi라는 변수는 호이스팅되었지만, 초기화는 아직되지 않았습니다. let 키워드는 변수 선언단계와 초기화단계가 분리되고, 변수 초기화 전에 변수에 접근할 수 없기 때문에 위와 같은 에러가 발생했습니다. (var는 변수선언시 초기화 단계가 바로 진행됩니다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;즉, let으로 선언한 스코프는 호이스팅이 발생하지 않는 것처럼 보입니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;스코프&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;var로 선언된 변수는 오로지 함수 블록만 지역 스코프로 인정합니다. if문, for문 등의 경우에는 어디서나 참조 가능한 전역 변수가 됩니다.&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;var a = 10;

if (true) {
  // 함수 블록이 아니기 때문에, 아래 a는 전역변수이고, 앞서 선언된 a가 있기 때문에, 중복선언이 됩니다. 
  var a = 100;
}

console.log(a); // 100&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;let으로 선언된 변수는 블록 레벨 스코프를 따릅니다.&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;let a = 10; // 전역변수

if (true) {
  let a = 100; // 지역변수
  let b = 200; // 지역변수
}

console.log(a); // 10
console.log(b); // Uncaught ReferenceError: b is not defined&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;요약&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;변수의 유효 범위가 크면 클수록 코드의 가독성은 나빠지고, 의도치 않게 상태가 변경될 수 있는 위험이 있기 때문에, 변수의 스코프는 좁을수록 좋습니다. 그렇기 때문에, var 대신 let, const(변하지 않는 값에 const를 사용하지만 우선 기본적으로 const를 사용하고, 재할당이 필요한 경우 let을 사용)를 사용하는 것이 좋습니다.&lt;/p&gt;</description>
      <category> &amp;zwj;  Programming/JavaScript</category>
      <category>JavaScript</category>
      <author>jinnkimm7</author>
      <guid isPermaLink="true">https://devjk.tistory.com/52</guid>
      <comments>https://devjk.tistory.com/entry/JavaScript-var-let-const#entry52comment</comments>
      <pubDate>Wed, 18 Dec 2024 16:40:05 +0900</pubDate>
    </item>
    <item>
      <title>반도체, 반도체 8대 공정</title>
      <link>https://devjk.tistory.com/entry/%EB%B0%98%EB%8F%84%EC%B2%B4-%EB%B0%98%EB%8F%84%EC%B2%B4-8%EB%8C%80-%EA%B3%B5%EC%A0%95</link>
      <description>&lt;h2&gt;반도체란&lt;/h2&gt;
&lt;p&gt;반도체는 조건에 따라 전기를 제어하는 성질을 이용해 만든 전자장치입니다.&lt;/p&gt;
&lt;p&gt;반도체의 주재료는 Si(규소, 실리콘)입니다. 규소가 반도체로 탄생되기까지 여러 공정을 거지게 됩니다.&lt;/p&gt;
&lt;h2&gt;반도체 8대 공정&lt;/h2&gt;
&lt;p&gt;웨이퍼 제조 -&amp;gt; 산화공정 -&amp;gt; 포토공정 -&amp;gt; 식각공정 -&amp;gt; 증착 &amp;amp; 이온주입 공정 -&amp;gt; 금속배선 공정 -&amp;gt; EDS 공정 -&amp;gt; 패키징 공정&lt;/p&gt;
&lt;h3&gt;웨이퍼 제조&lt;/h3&gt;
&lt;p&gt;빌딩을 만들 때에, 터가 필요하듯이 반도체를 만들 때도 터가 필요합니다. 이 때 반도체를 만들 수 있는 터가 바로 웨이퍼입니다.&lt;/p&gt;
&lt;p&gt;웨이퍼의 두께가 얇고, 지름이 클수록 한번에 생산할 수 있는 반도체 칩수가 증가합니다.&lt;/p&gt;
&lt;p&gt;이 웨이퍼는 부도체 상태이므로 반도체 성질을 가질 수 있도록 하는 작업이 필요합니다.&lt;/p&gt;
&lt;h3&gt;산화 공정&lt;/h3&gt;
&lt;p&gt;웨이퍼 표면에 산소나 수증기를 뿌려, 산화막을 형성합니다. 이 산화막은 웨이퍼의 표면을 보호하고 회로와 회로 사이의 누설전류가 흐르는 것을 방지합니다.&lt;/p&gt;
&lt;h3&gt;포토 공정&lt;/h3&gt;
&lt;p&gt;밑그림을 새기는 작업입니다. 이 작업은 사진을 현상하는 과정이랑 비슷하다고해서 포토 공정이라고 부릅니다. 산화막 위에 빛에 반응하는 물질인 감광액을 얇고 균일하게 도포합니다. 이 후, 설계한 회로패턴이 담긴 마스크에 빛을 통과시키면, 웨이퍼 표면에 회로도가 그대로 찍히게 됩니다. 마지막으로 현상액을 뿌려 빛을 받은 영역과 그렇지 않은 영역을 선택적으로 제거해 웨이퍼에 회로 패턴을 그려줍니다.&lt;/p&gt;
&lt;h3&gt;식각 공정&lt;/h3&gt;
&lt;p&gt;이제 웨이퍼에 그려진 반도체 패턴 외에 필요없는 부분을 제거해 주어야 합니다. 액체나 기체의 부식액을 이용하여 불필요한 부분을 제거해 반도체 회로 패턴을 만듭니다. 이 때 액체를 사용한다면 습식 식각, 기체나 플라즈마를 이용하며 건식 식각이라고 합니다.&lt;/p&gt;
&lt;h3&gt;증착 &amp;amp; 이온주입 공정&lt;/h3&gt;
&lt;p&gt;반도체 칩을 만드는 과정은 손톱보다 작은 크기 속에서 빌딩을 짓는 것으로 비유하기도 합니다. 포토 공정과 식각 공정을 통해 층층이 레이어를 쌓습니다. 이 때, 층층이 쌓인 회로와 회로를 구분하고 보호하는 절연막이 필요합니다. 이 얇은 막을 박막이라고 합니다. 웨이퍼 위에 원하는 분자 또는 원자 단위의 아주 얇은 박막을 입히는 것을 증착이라고 합니다. 이때, 반도체가 전기적인 성질을 가지게 하는 이온 주입 공정 또한 필요합니다. 순수한 규소는 전기가 통하지 않으나, 불순물을 넣어 전류를 흐르게 하는 전도성을 갖게 되는 것입니다. &lt;/p&gt;
&lt;h3&gt;금속배선 공정&lt;/h3&gt;
&lt;p&gt;회로가 동작하기 위해 전기적인 신호가 필요합니다. 이 때 신호가 잘 전달되도록 회로 패턴에 따라 전기가 통하는 길을 만들어주어야합니다. 이과정을 금속배선 공정이라고 부릅니다. 알루미늄, 티타늄 등과 같은 얇은 금속 막을 증착하여 전기가 통할 수 있도록 하는 과정입니다. &lt;/p&gt;
&lt;h3&gt;EDS&lt;/h3&gt;
&lt;p&gt;전기적 특성검사를 통해 원하는 품질 수준에 도달했는지 테스트하는 과정입니다. 이 때, 한 개의 웨이퍼에서 정상적으로 작동하는 칩의 개수를 수율이라고합니다. 수율이 높을수록 기술력 있는 반도체 회사로 인정받습니다. &lt;/p&gt;
&lt;h3&gt;패키징 공정&lt;/h3&gt;
&lt;p&gt;이후 EDS 공정을 거쳐 선별된 반도체 칩들은 패키징 과정을 통해 특정 기기에 탑재되기 적합한 형태로 만들어집니다. 앞선 공정들을 통해 만들어진 웨이퍼의 반도체 칩은 낱개로 하나하나 잘라서 전자기기에 탑재될 수 있는 형태를 갖추어야합니다. 반도체 칩이 외부와 신화를 주고 받을 수 있도록 길을 만들어주어야하고, 외부환경으로부터 보호받을 수 있는 환경을 만들어주어야합니다. &lt;/p&gt;
&lt;h2&gt;참고&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=AysV2zIzY94&quot;&gt;당신이 몰랐던 반도체의 모든 것 | &amp;#39;반도체 백과사전&amp;#39; EP.1 반도체의 기초 편&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=M2b2kpJRHmM&quot;&gt;&amp;#39;삼성전자&amp;#39;가 참 쉽게 알려주는 &amp;#39;반도체 8대공정&amp;#39; | 반도체 백과사전 EP.6 반도체 공정 편&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=C-ZO0k1NXgU&quot;&gt;&amp;#39;삼성전자&amp;#39;가 직접 알려주는 메모리 반도체 알고 가자 | 반도체 백과사전 EP.7 메모리 반도체 편&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>  Etc</category>
      <category>반도체</category>
      <category>반도체8대공정</category>
      <author>jinnkimm7</author>
      <guid isPermaLink="true">https://devjk.tistory.com/51</guid>
      <comments>https://devjk.tistory.com/entry/%EB%B0%98%EB%8F%84%EC%B2%B4-%EB%B0%98%EB%8F%84%EC%B2%B4-8%EB%8C%80-%EA%B3%B5%EC%A0%95#entry51comment</comments>
      <pubDate>Sun, 8 Dec 2024 23:09:23 +0900</pubDate>
    </item>
    <item>
      <title>[Excel] 엑셀 Excel 모든 셀에 동일한 값 더하기, 빼기를 실행하는 방법</title>
      <link>https://devjk.tistory.com/entry/Excel-%EC%97%91%EC%85%80-Excel-%EB%AA%A8%EB%93%A0-%EC%85%80%EC%97%90-%EB%8F%99%EC%9D%BC%ED%95%9C-%EA%B0%92-%EB%8D%94%ED%95%98%EA%B8%B0-%EB%B9%BC%EA%B8%B0%EB%A5%BC-%EC%8B%A4%ED%96%89%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95</link>
      <description>&lt;figure id=&quot;og_1732601546303&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;엑셀 Excel 모든 셀에 동일한 값 더하기, 빼기를 실행하는 방법&quot; data-og-description=&quot;엑셀에서는 특정 영역의 숫자를 일괄적으로 올리거나 내리는 등의 사칙연산을 할 수 있습니다. 이것은 작업 능률을 높이는 방법 중 하나입니다. 계산할 숫자가 많으면 하나씩 고치는 것이 쉽지 &quot; data-og-host=&quot;mainia.tistory.com&quot; data-og-source-url=&quot;https://mainia.tistory.com/2967&quot; data-og-url=&quot;https://mainia.tistory.com/2967&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bB2llC/hyXDfynYI1/zygvQvhunKqYFYH8Dqg4g1/img.png?width=800&amp;amp;height=515&amp;amp;face=0_0_800_515,https://scrap.kakaocdn.net/dn/Mjniy/hyXC9dRPIt/qGpQJxRKQYRPUOOhiQDsi0/img.png?width=800&amp;amp;height=515&amp;amp;face=0_0_800_515,https://scrap.kakaocdn.net/dn/bcNqKv/hyXDh30uyX/kiDM7QqqyqEfH0kGzJB72K/img.jpg?width=620&amp;amp;height=517&amp;amp;face=0_0_620_517&quot;&gt;&lt;a href=&quot;https://mainia.tistory.com/2967&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://mainia.tistory.com/2967&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bB2llC/hyXDfynYI1/zygvQvhunKqYFYH8Dqg4g1/img.png?width=800&amp;amp;height=515&amp;amp;face=0_0_800_515,https://scrap.kakaocdn.net/dn/Mjniy/hyXC9dRPIt/qGpQJxRKQYRPUOOhiQDsi0/img.png?width=800&amp;amp;height=515&amp;amp;face=0_0_800_515,https://scrap.kakaocdn.net/dn/bcNqKv/hyXDh30uyX/kiDM7QqqyqEfH0kGzJB72K/img.jpg?width=620&amp;amp;height=517&amp;amp;face=0_0_620_517');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;엑셀 Excel 모든 셀에 동일한 값 더하기, 빼기를 실행하는 방법&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;엑셀에서는 특정 영역의 숫자를 일괄적으로 올리거나 내리는 등의 사칙연산을 할 수 있습니다. 이것은 작업 능률을 높이는 방법 중 하나입니다. 계산할 숫자가 많으면 하나씩 고치는 것이 쉽지&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;mainia.tistory.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>⚙️ Tool/Excel</category>
      <author>jinnkimm7</author>
      <guid isPermaLink="true">https://devjk.tistory.com/50</guid>
      <comments>https://devjk.tistory.com/entry/Excel-%EC%97%91%EC%85%80-Excel-%EB%AA%A8%EB%93%A0-%EC%85%80%EC%97%90-%EB%8F%99%EC%9D%BC%ED%95%9C-%EA%B0%92-%EB%8D%94%ED%95%98%EA%B8%B0-%EB%B9%BC%EA%B8%B0%EB%A5%BC-%EC%8B%A4%ED%96%89%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95#entry50comment</comments>
      <pubDate>Tue, 26 Nov 2024 15:13:11 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스] 그룹별 조건에 맞는 식당 목록 출력하기 | 오라클</title>
      <link>https://devjk.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EA%B7%B8%EB%A3%B9%EB%B3%84-%EC%A1%B0%EA%B1%B4%EC%97%90-%EB%A7%9E%EB%8A%94-%EC%8B%9D%EB%8B%B9-%EB%AA%A9%EB%A1%9D-%EC%B6%9C%EB%A0%A5%ED%95%98%EA%B8%B0-%EC%98%A4%EB%9D%BC%ED%81%B4</link>
      <description>&lt;h2&gt;문제&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/131124?language=oracle&quot;&gt;그룹별 조건에 맞는 식당 목록 출력하기&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;풀이&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;SELECT A.MEMBER_NAME, B.REVIEW_TEXT, TO_CHAR(B.REVIEW_DATE, &amp;#39;YYYY-MM-DD&amp;#39;) REVIEW_DATE
FROM MEMBER_PROFILE A JOIN REST_REVIEW B
    ON A.MEMBER_ID = B.MEMBER_ID
WHERE A.MEMBER_ID = (
    SELECT MEMBER_ID
    FROM (
        SELECT MEMBER_ID, COUNT(*)
        FROM REST_REVIEW
        GROUP BY MEMBER_ID
        ORDER BY COUNT(*) DESC
    ) 
    WHERE ROWNUM = 1
)
ORDER BY REVIEW_DATE, REVIEW_TEXT
;&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;GROUP BY를 이용해서 최다 리뷰를 작성한 MEMBER_ID를 찾습니다.&lt;/li&gt;
&lt;li&gt;그 이후 MEMBER_PROFIL 테이블과 REST_REVIEW 테이블을 조인하여, 답은 찾아냅니다.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>SQL</category>
      <category>오라클</category>
      <category>오블완</category>
      <category>티스토리챌린지</category>
      <category>프로그래머스</category>
      <author>jinnkimm7</author>
      <guid isPermaLink="true">https://devjk.tistory.com/49</guid>
      <comments>https://devjk.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EA%B7%B8%EB%A3%B9%EB%B3%84-%EC%A1%B0%EA%B1%B4%EC%97%90-%EB%A7%9E%EB%8A%94-%EC%8B%9D%EB%8B%B9-%EB%AA%A9%EB%A1%9D-%EC%B6%9C%EB%A0%A5%ED%95%98%EA%B8%B0-%EC%98%A4%EB%9D%BC%ED%81%B4#entry49comment</comments>
      <pubDate>Mon, 25 Nov 2024 20:07:53 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스] 즐겨찾기가 가장 많은 식당 정보 출력하기 | 오라클</title>
      <link>https://devjk.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%A6%90%EA%B2%A8%EC%B0%BE%EA%B8%B0%EA%B0%80-%EA%B0%80%EC%9E%A5-%EB%A7%8E%EC%9D%80-%EC%8B%9D%EB%8B%B9-%EC%A0%95%EB%B3%B4-%EC%B6%9C%EB%A0%A5%ED%95%98%EA%B8%B0-%EC%98%A4%EB%9D%BC%ED%81%B4</link>
      <description>&lt;h2&gt;문제&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/131123?language=oracle&quot;&gt;즐겨찾기가 가장 많은 식당 정보 출력하기&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;풀이&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;SELECT FOOD_TYPE, REST_ID, REST_NAME, FAVORITES
FROM REST_INFO
WHERE (FOOD_TYPE, FAVORITES) IN (
    SELECT FOOD_TYPE, MAX(FAVORITES)
    FROM REST_INFO
    GROUP BY FOOD_TYPE
)
ORDER BY FOOD_TYPE DESC
;&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;GROUP BY를 이용해서 음식별 최대 즐겨찾기 수를 뽑은 서브쿼리를 이용해서 풀이합니다.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>  Coding Test/SQL</category>
      <category>SQL</category>
      <category>오라클</category>
      <category>오블완</category>
      <category>티스토리챌린지</category>
      <category>프로그래머스</category>
      <author>jinnkimm7</author>
      <guid isPermaLink="true">https://devjk.tistory.com/48</guid>
      <comments>https://devjk.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%A6%90%EA%B2%A8%EC%B0%BE%EA%B8%B0%EA%B0%80-%EA%B0%80%EC%9E%A5-%EB%A7%8E%EC%9D%80-%EC%8B%9D%EB%8B%B9-%EC%A0%95%EB%B3%B4-%EC%B6%9C%EB%A0%A5%ED%95%98%EA%B8%B0-%EC%98%A4%EB%9D%BC%ED%81%B4#entry48comment</comments>
      <pubDate>Fri, 22 Nov 2024 23:15:33 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스 Lv3] 가장 먼 노드 | 자바</title>
      <link>https://devjk.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-Lv3-%EA%B0%80%EC%9E%A5-%EB%A8%BC-%EB%85%B8%EB%93%9C-%EC%9E%90%EB%B0%94</link>
      <description>&lt;h2&gt;문제&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/49189?language=java&quot;&gt;가장 먼 노드&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;풀이&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;import java.util.*;

class Solution {
    public int solution(int n, int[][] edge) {
        int answer = 0;

        int[] visited = new int[n + 1];       
        ArrayList&amp;lt;ArrayList&amp;lt;Integer&amp;gt;&amp;gt; graph = new ArrayList&amp;lt;&amp;gt;();

        for(int i = 0; i &amp;lt;= n; i++) {
            graph.add(new ArrayList&amp;lt;Integer&amp;gt;());
        }    

        for(int i = 0; i &amp;lt; edge.length; i++) {
            int x = edge[i][0];
            int y = edge[i][1];

            graph.get(x).add(y);
            graph.get(y).add(x);
        }

        bfs(graph, visited, 1);

        int max = Integer.MIN_VALUE;

        for(int i = 0; i &amp;lt; visited.length; i++) {
            max = Math.max(visited[i], max);
        }

        for(int i = 0; i &amp;lt; visited.length; i++) {
            if(visited[i] == max) answer++;
        }

        return answer;
    }

    void bfs(ArrayList&amp;lt;ArrayList&amp;lt;Integer&amp;gt;&amp;gt; graph, int[] visited, int start) {
        Queue&amp;lt;Integer&amp;gt; q = new LinkedList&amp;lt;&amp;gt;();
        q.offer(start);
        visited[start] = 1;

        while(!q.isEmpty()) {
            int current = q.poll();

            for(int i = 0; i &amp;lt; graph.get(current).size(); i++) {
                int next = graph.get(current).get(i);

                if(visited[next] == 0) {
                    q.offer(next);
                    visited[next] = visited[current] + 1;
                }
            }
        }

    }    
}&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;최단거리 문제이기 때문에 bfs를 알고 있으면 쉽게 풀 수 있는 문제입니다.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>  Coding Test/Programmers Lv3</category>
      <category>BFS</category>
      <category>코딩테스트</category>
      <category>프로그래머스</category>
      <author>jinnkimm7</author>
      <guid isPermaLink="true">https://devjk.tistory.com/47</guid>
      <comments>https://devjk.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-Lv3-%EA%B0%80%EC%9E%A5-%EB%A8%BC-%EB%85%B8%EB%93%9C-%EC%9E%90%EB%B0%94#entry47comment</comments>
      <pubDate>Wed, 20 Nov 2024 23:13:49 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스] 주문량이 많은 아이스크림들 조회하기 | 오라클</title>
      <link>https://devjk.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%A3%BC%EB%AC%B8%EB%9F%89%EC%9D%B4-%EB%A7%8E%EC%9D%80-%EC%95%84%EC%9D%B4%EC%8A%A4%ED%81%AC%EB%A6%BC%EB%93%A4-%EC%A1%B0%ED%9A%8C%ED%95%98%EA%B8%B0-%EC%98%A4%EB%9D%BC%ED%81%B4</link>
      <description>&lt;h2&gt;문제&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/133027?language=oracle&quot;&gt;주문량이 많은 아이스크림들 조회하기&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;풀이&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;SELECT FLAVOR
FROM (
    SELECT FLAVOR, SUM(TOTAL_ORDER) SUM
    FROM (
        SELECT * FROM FIRST_HALF
            UNION ALL
        SELECT * FROM JULY
        )
    GROUP BY FLAVOR
    ORDER BY SUM DESC
) WHERE ROWNUM &amp;lt;= 3
;&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;상반기와 7월에 가장 많이 팔린 FLAVOR를 순서대로 3개 구하는 문제입니다. &lt;/li&gt;
&lt;li&gt;상반기 판매정보와 7월 판매정보 중 겹치는 데이터가 없기 때문에, UNION ALL을 사용해서 풀이했습니다. &lt;ul&gt;
&lt;li&gt;*참고 : UNION은 중복된 row를 제외하고(DISTINCT), UNION ALL은 중복된 row도 포함합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>  Coding Test/SQL</category>
      <category>SQL</category>
      <category>오라클</category>
      <category>오블완</category>
      <category>티스토리챌린지</category>
      <category>프로그래머스</category>
      <author>jinnkimm7</author>
      <guid isPermaLink="true">https://devjk.tistory.com/46</guid>
      <comments>https://devjk.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%A3%BC%EB%AC%B8%EB%9F%89%EC%9D%B4-%EB%A7%8E%EC%9D%80-%EC%95%84%EC%9D%B4%EC%8A%A4%ED%81%AC%EB%A6%BC%EB%93%A4-%EC%A1%B0%ED%9A%8C%ED%95%98%EA%B8%B0-%EC%98%A4%EB%9D%BC%ED%81%B4#entry46comment</comments>
      <pubDate>Wed, 20 Nov 2024 21:21:42 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스] 취소되지 않은 진료 예약 조회하기 | 오라클</title>
      <link>https://devjk.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%B7%A8%EC%86%8C%EB%90%98%EC%A7%80-%EC%95%8A%EC%9D%80-%EC%A7%84%EB%A3%8C-%EC%98%88%EC%95%BD-%EC%A1%B0%ED%9A%8C%ED%95%98%EA%B8%B0-%EC%98%A4%EB%9D%BC%ED%81%B4</link>
      <description>&lt;h2&gt;문제&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/132204?language=oracle&quot;&gt;취소되지 않은 진료 예약 조회하기&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;풀이&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;SELECT A.APNT_NO, P.PT_NAME, P.PT_NO, A.MCDP_CD, D.DR_NAME,    A.APNT_YMD
FROM APPOINTMENT A JOIN PATIENT P
    ON A.PT_NO = P.PT_NO
    JOIN DOCTOR D
    ON A.MCDP_CD = D.MCDP_CD AND A.MDDR_ID = D.DR_ID
WHERE TO_CHAR(A.APNT_YMD, &amp;#39;YYYYMMDD&amp;#39;) = &amp;#39;20220413&amp;#39; AND
    A.MCDP_CD = &amp;#39;CS&amp;#39; AND
    A.APNT_CNCL_YN = &amp;#39;N&amp;#39;
ORDER BY A.APNT_YMD
;&lt;/code&gt;&lt;/pre&gt;</description>
      <category>  Coding Test/SQL</category>
      <category>SQL</category>
      <category>오라클</category>
      <category>오블완</category>
      <category>코딩테스트</category>
      <category>티스토리챌린지</category>
      <category>프로그래머스</category>
      <author>jinnkimm7</author>
      <guid isPermaLink="true">https://devjk.tistory.com/45</guid>
      <comments>https://devjk.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%B7%A8%EC%86%8C%EB%90%98%EC%A7%80-%EC%95%8A%EC%9D%80-%EC%A7%84%EB%A3%8C-%EC%98%88%EC%95%BD-%EC%A1%B0%ED%9A%8C%ED%95%98%EA%B8%B0-%EC%98%A4%EB%9D%BC%ED%81%B4#entry45comment</comments>
      <pubDate>Mon, 18 Nov 2024 22:22:10 +0900</pubDate>
    </item>
    <item>
      <title>[컴퓨터구조] 컴퓨터구조 시작하기</title>
      <link>https://devjk.tistory.com/entry/%EC%BB%B4%ED%93%A8%ED%84%B0%EA%B5%AC%EC%A1%B0-%EC%BB%B4%ED%93%A8%ED%84%B0%EA%B5%AC%EC%A1%B0-%EC%8B%9C%EC%9E%91%ED%95%98%EA%B8%B0</link>
      <description>&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.inflearn.com/course/%ED%98%BC%EC%9E%90-%EA%B3%B5%EB%B6%80%ED%95%98%EB%8A%94-%EC%BB%B4%ED%93%A8%ED%84%B0%EA%B5%AC%EC%A1%B0-%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C/dashboard&quot;&gt;개발자를 위한 컴퓨터공학 1: 혼자 공부하는 컴퓨터구조 + 운영체제&lt;/a&gt;를 보고 학습한 내용을 기록한 포스팅입니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;컴퓨터구조를 배워야하는 이유&lt;/h1&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;프로그래머는 코드를 잘 짜는 것도 중요합니다. 하지만 컴퓨터구조적인 측면에서 발생하는 문제도 해결할 수 있어야합니다.&lt;/li&gt;
&lt;li&gt;컴퓨터구조를 학습하고 분석함으로써 문제 해결의 실마리를 찾을 수 있습니니다.&lt;/li&gt;
&lt;li&gt;또한, 성능, 용량, 비용을 고려하여 개발 할 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;컴퓨터 구조의 큰 그림&lt;/h1&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;컴퓨터가 이해하는 정보&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컴퓨터가 이해하는 정보는 &lt;code&gt;데이터&lt;/code&gt;, &lt;code&gt;명령어&lt;/code&gt;가 있습니다. 컴퓨터는 0과 1로 다양한 데이터를 표현하고 명령어를 통해 데이터를 처리하고 컴퓨터를 작동하게 합니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;컴퓨터의 네 가지 핵심 부품&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컴퓨터의 네 가지 핵심 부품은 &lt;code&gt;CPU&lt;/code&gt;, &lt;code&gt;메모리(RAM)&lt;/code&gt;, &lt;code&gt;보조기억장치&lt;/code&gt;, &lt;code&gt;입출력장치&lt;/code&gt;가 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock widthContent&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2154&quot; data-origin-height=&quot;1668&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cwJI56/btsKLyRWqrp/ECxA4TaPt4p3IEV9unfDb1/img.jpg&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cwJI56/btsKLyRWqrp/ECxA4TaPt4p3IEV9unfDb1/img.jpg&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cwJI56/btsKLyRWqrp/ECxA4TaPt4p3IEV9unfDb1/img.jpg&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcwJI56%2FbtsKLyRWqrp%2FECxA4TaPt4p3IEV9unfDb1%2Fimg.jpg&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2154&quot; height=&quot;1668&quot; data-origin-width=&quot;2154&quot; data-origin-height=&quot;1668&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;CPU&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메모리에 저장된 명령어를 읽고, 해석하고, 실행합니다. &lt;code&gt;ALU&lt;/code&gt;, &lt;code&gt;레지스터&lt;/code&gt;, &lt;code&gt;제어장치&lt;/code&gt;로 구성되어 있습니다. ALU는 계산기, 레지스터는 CPU 내의 작은 저장장치, 제어장치는 제어 신호를 내보내고, 명령어를 해석하는 장치로 생각하면 됩니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;메모리&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 실행되고 있는 프로그램(프로세스)의 명령어와 데이터를 저장합니다. 주소라는 개념을 통해 원하는 명령어와 데이터에 효율적으로 접근할 수 있습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;보조기억장치&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전원이 꺼져도 정보를 보관할 수 있는 장치입니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;입출력장치&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컴퓨터 외부에 연결되어 컴퓨터 내부와 정보를 교환하는 장치입니다.&lt;/p&gt;</description>
      <category>  CS/Computer Architecture</category>
      <category>컴퓨터구조</category>
      <author>jinnkimm7</author>
      <guid isPermaLink="true">https://devjk.tistory.com/44</guid>
      <comments>https://devjk.tistory.com/entry/%EC%BB%B4%ED%93%A8%ED%84%B0%EA%B5%AC%EC%A1%B0-%EC%BB%B4%ED%93%A8%ED%84%B0%EA%B5%AC%EC%A1%B0-%EC%8B%9C%EC%9E%91%ED%95%98%EA%B8%B0#entry44comment</comments>
      <pubDate>Sun, 17 Nov 2024 21:57:46 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스] 자동차 대여 기록 별 대여 금액 구하기 | 오라클</title>
      <link>https://devjk.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%9E%90%EB%8F%99%EC%B0%A8-%EB%8C%80%EC%97%AC-%EA%B8%B0%EB%A1%9D-%EB%B3%84-%EB%8C%80%EC%97%AC-%EA%B8%88%EC%95%A1-%EA%B5%AC%ED%95%98%EA%B8%B0-%EC%98%A4%EB%9D%BC%ED%81%B4</link>
      <description>&lt;h2&gt;문제&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/151141?language=oracle&quot;&gt;자동차 대여 기록 별 대여 금액 구하기&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;풀이&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;SELECT AA.HISTORY_ID, (AA.RENT_DATE * AA.DAILY_FEE) * (100 - NVL(DISCOUNT_RATE, 0)) / 100 FEE
FROM 
    (SELECT 
        HISTORY_ID,
        H.END_DATE - H.START_DATE + 1 RENT_DATE,
        CASE 
            WHEN H.END_DATE - H.START_DATE + 1 &amp;gt;= 90 THEN &amp;#39;90일 이상&amp;#39;
            WHEN H.END_DATE - H.START_DATE + 1 &amp;gt;= 30 THEN &amp;#39;30일 이상&amp;#39;
            WHEN H.END_DATE - H.START_DATE + 1 &amp;gt;=  7 THEN &amp;#39;7일 이상&amp;#39;
        END AS DURATION_TYPE,
        CAR_TYPE,
        DAILY_FEE
    FROM CAR_RENTAL_COMPANY_RENTAL_HISTORY H LEFT JOIN CAR_RENTAL_COMPANY_CAR C
    ON H.CAR_ID = C.CAR_ID) AA LEFT JOIN CAR_RENTAL_COMPANY_DISCOUNT_PLAN D
    ON AA.DURATION_TYPE = D.DURATION_TYPE AND AA.CAR_TYPE = D.CAR_TYPE
WHERE AA.CAR_TYPE = &amp;#39;트럭&amp;#39;
ORDER BY FEE DESC, HISTORY_ID DESC
;&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;CAR_RENTAL_COMPANY_RENTAL_HISTORY와 CAR_RENTAL_COMPANY_CAR를 조인하고 DURATION_TYPE이 추가된 인라인뷰를 만들고, CAR_RENTAL_COMPANY_DISCOUNT_PLAN과 조인하여 풀이했습니다.&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>  Coding Test/SQL</category>
      <category>SQL</category>
      <category>오라클</category>
      <category>프로그래머스</category>
      <author>jinnkimm7</author>
      <guid isPermaLink="true">https://devjk.tistory.com/43</guid>
      <comments>https://devjk.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%9E%90%EB%8F%99%EC%B0%A8-%EB%8C%80%EC%97%AC-%EA%B8%B0%EB%A1%9D-%EB%B3%84-%EB%8C%80%EC%97%AC-%EA%B8%88%EC%95%A1-%EA%B5%AC%ED%95%98%EA%B8%B0-%EC%98%A4%EB%9D%BC%ED%81%B4#entry43comment</comments>
      <pubDate>Sun, 17 Nov 2024 18:21:51 +0900</pubDate>
    </item>
  </channel>
</rss>