<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>hyeon.log</title>
        <link>https://velog.io/</link>
        <description>초보 개발자의 기술 블로그</description>
        <lastBuildDate>Mon, 07 Apr 2025 07:28:04 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <copyright>Copyright (C) 2019. hyeon.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/cham-chi" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[DB] 데이터베이스 쿼리 옵티마이저(Query Optimizer)에 대하여]]></title>
            <link>https://velog.io/@cham-chi/DB-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4-%EC%BF%BC%EB%A6%AC-%EC%98%B5%ED%8B%B0%EB%A7%88%EC%9D%B4%EC%A0%80Query-Optimizer%EC%97%90-%EB%8C%80%ED%95%98%EC%97%AC</link>
            <guid>https://velog.io/@cham-chi/DB-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4-%EC%BF%BC%EB%A6%AC-%EC%98%B5%ED%8B%B0%EB%A7%88%EC%9D%B4%EC%A0%80Query-Optimizer%EC%97%90-%EB%8C%80%ED%95%98%EC%97%AC</guid>
            <pubDate>Mon, 07 Apr 2025 07:28:04 GMT</pubDate>
            <description><![CDATA[<p>SQL 쿼리는 작성하는 사람 입장에서 단순하지만, DBMS 입장에서는 효율적으로 실행할 수 있는 수많은 방법 중 하나를 선택해야 한다. 이때 어떤 방법이 가장 효율적인지를 판단하는 핵심 컴포넌트가 <strong>쿼리 옵티마이저(Query Optimizer)</strong>이다.</p>
<hr>
<h2 id="✅-옵티마이저란">✅ 옵티마이저란?</h2>
<p><strong>옵티마이저(Query Optimizer)</strong>는 사용자가 작성한 SQL 문장을 실제로 어떻게 실행할지를 결정하는 <strong>실행 계획(Execution Plan)</strong>을 생성하는 DBMS 내부 구성 요소이다.</p>
<p>즉, 여러 가지 가능한 실행 경로 중에서 가장 비용(cost)이 적게 드는 실행 계획을 선택하는 역할을 한다.</p>
<hr>
<h3 id="✅-옵티마이저가-필요한-이유">✅ 옵티마이저가 필요한 이유</h3>
<p>같은 SQL 문이라도 아래와 같은 요소에 따라 실행 성능은 크게 달라질 수 있다.</p>
<ul>
<li>조인의 순서 (예: A를 먼저 읽을지 B를 먼저 읽을지)</li>
<li>인덱스 사용 여부</li>
<li>WHERE 조건의 적용 시점</li>
<li>전체 테이블 스캔 vs 인덱스 스캔</li>
</ul>
<p>옵티마이저는 위 요소들을 고려하여, 최적의 실행 경로를 찾아내도록 설계되어 있다.</p>
<hr>
<h3 id="⚙️-옵티마이저의-작동-방식">⚙️ 옵티마이저의 작동 방식</h3>
<p>쿼리 옵티마이저는 다음과 같은 순서로 작동한다.</p>
<ol>
<li><p><strong>쿼리 파싱 (Parsing)</strong>
SQL 구문을 분석하여 의미를 파악한다.</p>
</li>
<li><p><strong>실행 계획 후보 생성</strong>
여러 가지 가능한 실행 계획을 생성한다. 예를 들어 조인 순서, 인덱스 사용 유무 등 다양한 조합이 고려된다.</p>
</li>
<li><p><strong>비용 계산 (Cost Estimation)</strong>
각 실행 계획에 대해 디스크 I/O, CPU 사용량 등을 바탕으로 비용을 추정한다.</p>
</li>
<li><p><strong>최적의 계획 선택</strong>
추정된 비용이 가장 낮은 실행 계획을 선택한다.</p>
</li>
</ol>
<hr>
<h3 id="📊-옵티마이저-종류">📊 옵티마이저 종류</h3>
<table>
<thead>
<tr>
<th>종류</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td>Rule-Based Optimizer</td>
<td>정해진 규칙에 따라 실행 계획을 선택함. 오래된 방식으로 현재는 거의 사용되지 않음.</td>
</tr>
<tr>
<td>Cost-Based Optimizer</td>
<td>통계 정보를 기반으로 각 실행 계획의 비용을 계산하고, 가장 효율적인 실행 경로를 선택함. 대부분의 현대 DBMS에서 사용됨.</td>
</tr>
</tbody></table>
<hr>
<h3 id="🧠-실행-계획이란">🧠 실행 계획이란?</h3>
<p>실행 계획은 SQL 쿼리를 실행하는 실제 경로를 의미한다. 예를 들어, 어떤 인덱스를 사용할지, 어떤 테이블을 먼저 읽을지 등을 구체적으로 기록한 계획이다.</p>
<hr>
<h3 id="🔍-실행-계획-확인-방법">🔍 실행 계획 확인 방법</h3>
<p>DBMS는 옵티마이저가 선택한 실행 계획을 사용자가 직접 확인할 수 있도록 도와준다. 대표적인 명령어는 다음과 같다.</p>
<table>
<thead>
<tr>
<th>DBMS</th>
<th>실행 계획 확인 명령어</th>
</tr>
</thead>
<tbody><tr>
<td>Oracle</td>
<td><code>EXPLAIN PLAN FOR SELECT ...</code>, <code>AUTOTRACE</code></td>
</tr>
<tr>
<td>MySQL</td>
<td><code>EXPLAIN SELECT ...</code></td>
</tr>
<tr>
<td>PostgreSQL</td>
<td><code>EXPLAIN ANALYZE SELECT ...</code></td>
</tr>
</tbody></table>
<hr>
<p>🧪 예시 쿼리와 실행 계획</p>
<pre><code class="language-sql">SELECT * 
FROM orders o
JOIN customers c ON o.customer_id = c.id
WHERE c.region = &#39;서울&#39;;</code></pre>
<p>위 쿼리에 대해 옵티마이저는 다음과 같은 실행 계획을 평가한다:</p>
<ul>
<li><p><code>customers</code> 테이블에서 먼저 <code>region=&#39;서울&#39;</code> 조건을 필터링하고, 결과를 <code>orders</code>와 조인</p>
</li>
<li><p>전체 조인을 먼저 수행한 뒤 <code>region=&#39;서울&#39;</code> 조건을 적용</p>
</li>
<li><p>인덱스를 사용할지, 풀 테이블 스캔을 할지 등</p>
</li>
</ul>
<p>옵티마이저는 이 중에서 비용이 가장 적은 실행 방식을 선택한다.</p>
<hr>
<h3 id="📌-결론">📌 결론</h3>
<table>
<thead>
<tr>
<th>항목</th>
<th>내용</th>
</tr>
</thead>
<tbody><tr>
<td>정의</td>
<td>SQL 실행 전, 최적의 실행 계획을 선택하는 DBMS의 컴포넌트</td>
</tr>
<tr>
<td>목적</td>
<td>SQL 쿼리 성능 최적화</td>
</tr>
<tr>
<td>방식</td>
<td>대부분은 비용 기반 옵티마이저 사용 (Cost-Based)</td>
</tr>
<tr>
<td>확인 방법</td>
<td><code>EXPLAIN</code>, <code>EXPLAIN ANALYZE</code>, <code>AUTOTRACE</code> 등 명령어로 실행 계획 확인 가능</td>
</tr>
</tbody></table>
<p>쿼리 옵티마이저는 눈에 보이지 않지만, SQL 성능을 좌우하는 핵심 역할을 한다. 쿼리 튜닝 시 반드시 실행 계획을 확인하고, 인덱스 구성 및 쿼리 구조를 옵티마이저가 잘 선택할 수 있도록 설계해야 한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Oracle] 실행계획의 인덱스 접근 방식 정리 및 실습]]></title>
            <link>https://velog.io/@cham-chi/Oracle-%EC%8B%A4%ED%96%89%EA%B3%84%ED%9A%8D%EC%9D%98-%EC%9D%B8%EB%8D%B1%EC%8A%A4-%EC%A0%91%EA%B7%BC-%EB%B0%A9%EC%8B%9D-%EC%A0%95%EB%A6%AC</link>
            <guid>https://velog.io/@cham-chi/Oracle-%EC%8B%A4%ED%96%89%EA%B3%84%ED%9A%8D%EC%9D%98-%EC%9D%B8%EB%8D%B1%EC%8A%A4-%EC%A0%91%EA%B7%BC-%EB%B0%A9%EC%8B%9D-%EC%A0%95%EB%A6%AC</guid>
            <pubDate>Mon, 07 Apr 2025 01:16:38 GMT</pubDate>
            <description><![CDATA[<p>데이터베이스 쿼리 성능을 분석할 때 실행계획(Execution Plan) 을 확인하면, DB가 어떻게 데이터를 읽는지 파악할 수 있다.
특히 인덱스를 어떻게 사용하는지에 따라 성능이 크게 달라진다.</p>
<h2 id="📌-1-full-table-scan">📌 1. FULL TABLE SCAN</h2>
<ul>
<li><p>키워드 : <code>TABLE ACCESS FULL</code></p>
</li>
<li><p>동작 : 테이블의 모든 행을 처음부터 끝까지 전부 읽음</p>
<pre><code class="language-sql">SELECT * FROM INDEX_EX WHERE salary &gt; 0;</code></pre>
</li>
<li><p>특징 : 인덱스가 없거나, 조건이 대부분의 데이터를 반환할 때
대용량 테이블에서 비효율적</p>
</li>
</ul>
<hr>
<h2 id="📌-2-index-unique-scan">📌 2. INDEX UNIQUE SCAN</h2>
<ul>
<li><p>키워드 : <code>INDEX UNIQUE SCAN</code></p>
</li>
<li><p>동작 : 프라이머리 키(PK) 또는 유니크 인덱스를 사용해 정확히 1건을 빠르게 조회</p>
<pre><code class="language-sql">SELECT * FROM INDEX_EX WHERE emp_id = 100;</code></pre>
</li>
<li><p>특징:유일한 값을 찾을 때 가장 빠름
효율 최고</p>
</li>
</ul>
<hr>
<h2 id="📌-3-index-range-scan">📌 3. INDEX RANGE SCAN</h2>
<ul>
<li>키워드 : <code>INDEX RANGE SCAN</code></li>
</ul>
<p>동작: 인덱스에서 특정 범위에 해당하는 값들을 순차적으로 스캔</p>
<pre><code class="language-sql">SELECT * FROM INDEX_EX WHERE department_id BETWEEN 10 AND 20;</code></pre>
<ul>
<li>특징 : 범위 조건, IN, LIKE 조건 등에 사용
흔히 등장하며 효율도 좋음</li>
</ul>
<hr>
<h2 id="📌-4-index-full-scan">📌 4. INDEX FULL SCAN</h2>
<ul>
<li><p>키워드 : <code>INDEX FULL SCAN</code></p>
</li>
<li><p>동작 : 인덱스를 처음부터 끝까지 순서대로 전체 스캔</p>
<pre><code class="language-sql">SELECT department_id FROM INDEX_EX ORDER BY department_id;</code></pre>
</li>
<li><p>특징 : 정렬된 결과가 필요하거나, 인덱스만으로 데이터를 다 가져올 수 있을 때
ROWID 접근 없이 인덱스만으로 처리</p>
</li>
</ul>
<hr>
<h2 id="📌-5-index-fast-full-scan">📌 5. INDEX FAST FULL SCAN</h2>
<ul>
<li><p>키워드: <code>INDEX FAST FULL SCAN</code></p>
</li>
<li><p>동작 : 인덱스를 병렬로 빠르게 읽음 (순서 X)</p>
<pre><code class="language-sql">SELECT department_id FROM INDEX_EX;
(단, department_id 인덱스가 존재하고, 해당 컬럼만 조회할 때)</code></pre>
</li>
<li><p>특징 : 정렬이 필요 없고, 테이블 접근 없이 인덱스만으로 결과 가능할 때 사용
INDEX FULL SCAN과 비슷하지만 정렬은 보장하지 않음</p>
</li>
</ul>
<hr>
<h3 id="✅-요약-비교표">✅ 요약 비교표</h3>
<table>
<thead>
<tr>
<th>접근 방식</th>
<th>순서 보장</th>
<th>테이블 접근 (ROWID)</th>
<th>효율성</th>
<th>주요 사용 상황</th>
</tr>
</thead>
<tbody><tr>
<td>FULL TABLE SCAN</td>
<td>✗</td>
<td>O</td>
<td>❌ 낮음</td>
<td>인덱스 없음, 조건 무의미하거나 전체 조회</td>
</tr>
<tr>
<td>INDEX UNIQUE SCAN</td>
<td>✅</td>
<td>O</td>
<td>✅ 최고</td>
<td>프라이머리 키, 유니크 조건 (PK = 값)</td>
</tr>
<tr>
<td>INDEX RANGE SCAN</td>
<td>✅</td>
<td>O</td>
<td>👍 좋음</td>
<td>범위 조건, BETWEEN, IN, LIKE 등</td>
</tr>
<tr>
<td>INDEX FULL SCAN</td>
<td>✅</td>
<td>✗</td>
<td>중간</td>
<td>정렬된 결과 필요, 인덱스만으로 처리 가능</td>
</tr>
<tr>
<td>INDEX FAST FULL SCAN</td>
<td>✗</td>
<td>✗</td>
<td>👍 좋음</td>
<td>정렬 불필요, 인덱스만으로 결과 처리 가능</td>
</tr>
</tbody></table>
<hr>
<h2 id="🧪-실습-예제-인덱스-생성-전후-실행-계획-비교">🧪 실습 예제: 인덱스 생성 전후 실행 계획 비교</h2>
<h3 id="📌-1-인덱스-예시-테이블-생성">📌 1. 인덱스 예시 테이블 생성</h3>
<pre><code class="language-sql">CREATE TABLE INDEX_EX (
    emp_id INT PRIMARY KEY,
    emp_name VARCHAR(50),
    department_id INT,
    salary INT
);</code></pre>
<hr>
<h3 id="📌-2-더미-데이터-삽입-100000건">📌 2. 더미 데이터 삽입 (100,000건)</h3>
<pre><code class="language-sql">BEGIN
  FOR i IN 1..100000 LOOP
    INSERT INTO INDEX_EX (emp_id, emp_name, department_id, salary)
    VALUES (
      i,
      &#39;Employee_&#39; || i,
      MOD(i, 100), -- department_id 0~99 반복
      TRUNC(DBMS_RANDOM.VALUE(3000, 9000))
    );
  END LOOP;
  COMMIT;
END;</code></pre>
<hr>
<h3 id="📌-3-인덱스-생성">📌 3. 인덱스 생성</h3>
<pre><code class="language-sql">CREATE INDEX idx_department_id ON INDEX_EX(department_id);
emp_id는 PRIMARY KEY이므로 자동으로 유니크 인덱스가 생성됨</code></pre>
<hr>
<h3 id="📌-4-조건이-너무-많은-경우-→-인덱스-미사용">📌 4. 조건이 너무 많은 경우 → 인덱스 미사용</h3>
<pre><code class="language-sql">EXPLAIN PLAN FOR
SELECT * FROM INDEX_EX WHERE department_id = 42;

SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);</code></pre>
<p>🔍 실행계획: TABLE ACCESS FULL INDEX_EX
<img src="https://velog.velcdn.com/images/cham-chi/post/d4622e67-19fa-4793-945c-6501767bdd01/image.png" alt=""></p>
<p>📌 해석: 조건이 많은 행을 반환할 경우 옵티마이저는 인덱스 사용보다 전체 스캔이 더 효율적이라 판단함</p>
<hr>
<h3 id="📌-5-좁은-범위-조회로-인덱스-유도">📌 5. 좁은 범위 조회로 인덱스 유도</h3>
<pre><code class="language-sql">EXPLAIN PLAN FOR
SELECT * FROM INDEX_EX WHERE emp_id &gt;= 99 AND emp_id &lt;= 199;

SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);</code></pre>
<p><img src="https://velog.velcdn.com/images/cham-chi/post/29b0761e-8988-4153-94cf-6c02bfc3169d/image.png" alt=""></p>
<p>📌 해석</p>
<ul>
<li><p>INDEX RANGE SCAN: emp_id 범위 조건에 따라 인덱스를 사용하여 101건을 추출</p>
</li>
<li><p>TABLE ACCESS BY INDEX ROWID BATCHED: 인덱스에서 가져온 ROWID를 통해 실데이터에 접근 (Batch 처리)</p>
</li>
<li><p>SYS_C008326: emp_id 프라이머리 키 인덱스 이름 (시스템 생성)</p>
</li>
</ul>
<p>✅ 이처럼 범위 조건 + 프라이머리 키 인덱스 조합은 효율적인 INDEX RANGE SCAN을 유도할 수 있음</p>
<hr>
<h3 id="✅-실행계획-비교-요약-table-access-full-vs-index-range-scan">✅ 실행계획 비교 요약 (TABLE ACCESS FULL vs INDEX RANGE SCAN)</h3>
<table>
<thead>
<tr>
<th>항목</th>
<th>TABLE ACCESS FULL</th>
<th>INDEX RANGE SCAN + TABLE ACCESS BY ROWID</th>
</tr>
</thead>
<tbody><tr>
<td><strong>접근 방식</strong></td>
<td>테이블 전체를 처음부터 끝까지 스캔</td>
<td>인덱스를 통해 필요한 범위만 조회</td>
</tr>
<tr>
<td><strong>사용 인덱스</strong></td>
<td>❌ 인덱스 미사용</td>
<td>✅ 인덱스 사용 (프라이머리 키 or 일반 인덱스)</td>
</tr>
<tr>
<td><strong>예상 행 수</strong></td>
<td>1000건 (전체)</td>
<td>101건 (범위 내 일부)</td>
</tr>
<tr>
<td><strong>Cost</strong></td>
<td>138</td>
<td>7 (2 + 5 정도로 분리됨)</td>
</tr>
<tr>
<td><strong>CPU 사용량</strong></td>
<td>높음</td>
<td>낮음</td>
</tr>
<tr>
<td><strong>Disk I/O</strong></td>
<td>높음 (모든 데이터 블록 접근)</td>
<td>낮음 (필요한 블록만 접근)</td>
</tr>
<tr>
<td><strong>성능</strong></td>
<td>❌ 느림</td>
<td>✅ 빠름</td>
</tr>
<tr>
<td><strong>사용 시점</strong></td>
<td>조건이 많은 데이터를 반환할 때</td>
<td>조건 범위가 좁고 선택도가 높을 때</td>
</tr>
</tbody></table>
<br>

<h3 id="✅-실행계획-요약-정리-실습-결과-기반">✅ 실행계획 요약 정리 (실습 결과 기반)</h3>
<table>
<thead>
<tr>
<th>조건 예시</th>
<th>실행 계획</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td><code>department_id = 42</code></td>
<td><code>TABLE ACCESS FULL</code></td>
<td>조건에 해당하는 행이 많아 전체 테이블 스캔 수행</td>
</tr>
<tr>
<td><code>emp_id = 99</code></td>
<td><code>INDEX UNIQUE SCAN</code></td>
<td>프라이머리 키 조건 → 유일값 조회, 유니크 인덱스 사용</td>
</tr>
<tr>
<td><code>emp_id BETWEEN 99 AND 199</code></td>
<td><code>INDEX RANGE SCAN</code></td>
<td>범위 조건 → 인덱스를 통한 순차 조회로 성능 최적화</td>
</tr>
</tbody></table>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Oracle] 날짜/시간 데이터 타입 변환 정리 (CHAR, VARCHAR2, DATE, TIMESTAMP)]]></title>
            <link>https://velog.io/@cham-chi/Oracle-%EB%82%A0%EC%A7%9C%EC%8B%9C%EA%B0%84-%EB%8D%B0%EC%9D%B4%ED%84%B0-%ED%83%80%EC%9E%85-%EB%B3%80%ED%99%98-%EC%A0%95%EB%A6%AC-CHAR-VARCHAR2-DATE-TIMESTAMP</link>
            <guid>https://velog.io/@cham-chi/Oracle-%EB%82%A0%EC%A7%9C%EC%8B%9C%EA%B0%84-%EB%8D%B0%EC%9D%B4%ED%84%B0-%ED%83%80%EC%9E%85-%EB%B3%80%ED%99%98-%EC%A0%95%EB%A6%AC-CHAR-VARCHAR2-DATE-TIMESTAMP</guid>
            <pubDate>Fri, 04 Apr 2025 07:47:49 GMT</pubDate>
            <description><![CDATA[<p>오라클(Oracle)에서 자주 사용하는 날짜 및 시간 관련 타입들인 <code>CHAR</code>, <code>VARCHAR2</code>, <code>DATE</code>, <code>TIMESTAMP</code> 간 변환 방법을 정리했다.
아래 예제 테이블을 기준으로 각 타입 간의 변환을 테스트할 수 있다.</p>
<hr>
<h4 id="📍-테이블과-데이터-생성">📍 테이블과 데이터 생성</h4>
<pre><code class="language-sql">CREATE TABLE sample_datetime (
    id           NUMBER PRIMARY KEY,
    char_date    CHAR(10),                  -- &#39;2025-04-04&#39;
    varchar_ts   VARCHAR2(19),              -- &#39;2025-04-04 14:30:00&#39;
    dt           DATE,
    ts           TIMESTAMP
);

INSERT INTO sample_datetime (id, char_date, varchar_ts, dt, ts)
VALUES (
    1,
    &#39;2025-04-04&#39;,
    &#39;2025-04-04 14:30:00&#39;,
    TO_DATE(&#39;2025-04-04&#39;, &#39;YYYY-MM-DD&#39;),
    TO_TIMESTAMP(&#39;2025-04-04 14:30:00&#39;, &#39;YYYY-MM-DD HH24:MI:SS&#39;)
);
</code></pre>
<hr>
<h2 id="1-char-→-date">1. <code>CHAR</code> → <code>DATE</code></h2>
<h4 id="컬럼-char_date">컬럼: <code>char_date</code></h4>
<p>이 컬럼은 <code>&#39;YYYY-MM-DD&#39;</code> 형식의 문자열이야. <code>TO_DATE()</code> 함수로 <code>DATE</code> 타입으로 변환할 수 있다.</p>
<pre><code class="language-sql">SELECT
  id,
  char_date,
  TO_DATE(char_date, &#39;YYYY-MM-DD&#39;) AS char_to_date
FROM sample_datetime;</code></pre>
<p>결과: <code>2025-04-04 00:00:00</code> 형태의 <code>DATE</code> 데이터 반환</p>
<hr>
<h2 id="2-varchar2-→-timestamp">2. <code>VARCHAR2</code> → <code>TIMESTAMP</code></h2>
<h3 id="컬럼-varchar_ts">컬럼: <code>varchar_ts</code></h3>
<p>이 컬럼은 <code>&#39;YYYY-MM-DD HH24:MI:SS&#39;</code> 형식의 문자열이야. <code>TO_TIMESTAMP()</code>로 <code>TIMESTAMP</code>로 변환 가능하다.</p>
<pre><code class="language-sql">SELECT
  id,
  varchar_ts,
  TO_TIMESTAMP(varchar_ts, &#39;YYYY-MM-DD HH24:MI:SS&#39;) AS varchar_to_ts
FROM sample_datetime;</code></pre>
<p>결과: <code>2025-04-04 14:30:00.000000</code> 형태의 TIMESTAMP 반환</p>
<hr>
<h2 id="3-timestamp-→-date">3. <code>TIMESTAMP</code> → <code>DATE</code></h2>
<h3 id="컬럼-ts">컬럼: <code>ts</code></h3>
<p><code>TIMESTAMP</code> 타입을 <code>DATE</code>로 변환하면 <strong>소수초 정보가 사라지고</strong> 날짜+시간까지만 유지 된다.</p>
<pre><code class="language-sql">SELECT
  id,
  ts,
  CAST(ts AS DATE) AS ts_to_date
FROM sample_datetime;</code></pre>
<p>결과: <code>2025-04-04 14:30:00</code> (DATE 타입)</p>
<hr>
<h2 id="4-timestamp-→-varchar2">4. <code>TIMESTAMP</code> → <code>VARCHAR2</code></h2>
<h3 id="컬럼-ts-1">컬럼: <code>ts</code></h3>
<p><code>TO_CHAR()</code> 함수를 이용해 문자열로 바꿀 수 있어. 출력 형식도 지정 가능.</p>
<pre><code class="language-sql">SELECT
  id,
  ts,
  TO_CHAR(ts, &#39;YYYY-MM-DD HH24:MI:SS&#39;) AS ts_to_char
FROM sample_datetime;</code></pre>
<p>결과: <code>&#39;2025-04-04 14:30:00&#39;</code> (VARCHAR2 타입)</p>
<hr>
<h2 id="5-date-→-varchar2">5. <code>DATE</code> → <code>VARCHAR2</code></h2>
<h4 id="컬럼-dt">컬럼: <code>dt</code></h4>
<p>이건 단순히 날짜(<code>DATE</code>)를 보기 좋은 문자열로 바꿈.</p>
<pre><code class="language-sql">SELECT
  id,
  dt,
  TO_CHAR(dt, &#39;YYYY-MM-DD&#39;) AS date_to_char
FROM sample_datetime;</code></pre>
<p>결과: <code>&#39;2025-04-04&#39;</code></p>
<hr>
<h2 id="6-number-→-varchar2-정수-실수-→-문자열">6. NUMBER → VARCHAR2 (정수, 실수 → 문자열)</h2>
<pre><code class="language-sql">SELECT TO_CHAR(12345) AS number_to_char FROM DUAL;</code></pre>
<p>결과: &#39;12345&#39;</p>
<pre><code class="language-sql">SELECT TO_CHAR(12345.678, &#39;99999.999&#39;) AS float_to_char FROM DUAL;</code></pre>
<p>결과: &#39;12345.678&#39; (포맷 지정 가능)</p>
<hr>
<h2 id="7-varchar2-→-number-문자열-→-숫자">7. VARCHAR2 → NUMBER (문자열 → 숫자)</h2>
<pre><code class="language-sql">SELECT TO_NUMBER(&#39;12345&#39;) AS char_to_number FROM DUAL;</code></pre>
<p>결과: 12345</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Oracle] VARCHAR2 정렬 방식과 자연 정렬 구현 (ORDER BY)]]></title>
            <link>https://velog.io/@cham-chi/Oracle-VARCHAR2-%EC%A0%95%EB%A0%AC-%EB%B0%A9%EC%8B%9D%EA%B3%BC-%EC%9E%90%EC%97%B0-%EC%A0%95%EB%A0%AC-%EA%B5%AC%ED%98%84-ORDER-BY</link>
            <guid>https://velog.io/@cham-chi/Oracle-VARCHAR2-%EC%A0%95%EB%A0%AC-%EB%B0%A9%EC%8B%9D%EA%B3%BC-%EC%9E%90%EC%97%B0-%EC%A0%95%EB%A0%AC-%EA%B5%AC%ED%98%84-ORDER-BY</guid>
            <pubDate>Fri, 04 Apr 2025 04:31:55 GMT</pubDate>
            <description><![CDATA[<h3 id="📌-varchar2-정렬은-왜-우리가-원하는-순서대로-안-나올까">📌 VARCHAR2 정렬은 왜 우리가 원하는 순서대로 안 나올까?</h3>
<p>VARCHAR2는 문자형 데이터이다.<br><code>ORDER BY</code>로 정렬할 때는 <strong>문자열 기준</strong>, 즉 <strong>아스키코드 순서</strong>로 정렬된다.</p>
<p><strong>아스키 정렬 순서</strong></p>
<ul>
<li>숫자 (0–9) → 대문자 (A–Z) → 소문자 (a–z)</li>
<li>특수문자는 이보다 앞쪽 또는 중간에 위치</li>
<li>그래서 <code>&quot;varchar_10&quot;</code>이 <code>&quot;varchar_2&quot;</code>보다 <strong>앞에 나올 수 있음</strong></li>
</ul>
<p><img src="https://velog.velcdn.com/images/cham-chi/post/7f45bb87-7f4f-4fe0-ae82-d95c159d32ae/image.png" alt=""></p>
<hr>
<h3 id="varchar2--숫자-조합의-정렬-기준">VARCHAR2 + 숫자 조합의 정렬 기준</h3>
<p><strong>패턴 1.</strong> <code>varchar_1</code>, <code>varchar_2</code>, ..., <code>varchar_10</code><br>→ <code>varchar_</code> 부분이 동일하다면, 뒤의 숫자도 <strong>문자처럼</strong> 정렬됨 (즉, <code>&quot;10&quot;</code>이 <code>&quot;2&quot;</code>보다 먼저)</p>
<p><strong>패턴 2.</strong> <code>data1</code>, <code>abc2</code>, <code>test10</code> 등 접두어가 다르면<br>→ 왼쪽 문자부터 하나씩 <strong>아스키코드 기준으로 비교 정렬</strong></p>
<hr>
<h3 id="❓-우리가-원하는-자연-정렬이란">❓ 우리가 원하는 &quot;자연 정렬&quot;이란?</h3>
<p><code>varchar_1</code>, <code>varchar_2</code>, ..., <code>varchar_10</code><br>→ 실제로는 <code>&quot;1&quot;</code>부터 <code>&quot;10&quot;</code>까지 <strong>숫자 순</strong>으로 정렬되길 원함</p>
<hr>
<h3 id="✅-방법-1-_-이후-숫자만-추출해서-정렬">✅ 방법 1: <code>_</code> 이후 숫자만 추출해서 정렬</h3>
<pre><code class="language-sql">SELECT col_char, col_varchar2, col_number
FROM datatype_example
ORDER BY TO_NUMBER(SUBSTR(col_varchar2, INSTR(col_varchar2, &#39;_&#39;) + 1));</code></pre>
<ul>
<li>INSTR(col_varchar2, &#39;<em>&#39;) : &#39;</em>&#39; 위치 찾기</li>
<li>SUBSTR(... + 1) : 숫자 부분만 추출</li>
<li>TO_NUMBER(...) : 문자열을 숫자로 변환</li>
</ul>
<p><img src="https://velog.velcdn.com/images/cham-chi/post/c67fcdcb-e8b4-4aa9-a987-03695cd7d10e/image.png" alt=""></p>
<br>

<h3 id="✅-방법-2-앞-패턴이-일정하지-않거나-구분자가-없을-경우">✅ 방법 2: 앞 패턴이 일정하지 않거나 구분자가 없을 경우</h3>
<ul>
<li>Oracle SQL에서는 정규표현식 함수 <code>REGEXP_SUBSTR</code>를 이용해 숫자만 추출할 수 있다. <pre><code class="language-sql">SELECT col_char, col_varchar2, col_number 
  FROM datatype_example 
  ORDER BY TO_NUMBER(REGEXP_SUBSTR(col_varchar2, &#39;[0-9]+&#39;));</code></pre>
<code>REGEXP_SUBSTR</code> 란?</li>
</ul>
<p><strong>문자열에서 원하는 패턴을 추출</strong>할 수 있게 해주는 함수이다.</p>
<ol>
<li><code>&#39;[0-9]&#39;</code>: 0부터 9 사이의 <strong>숫자 한 자리</strong></li>
<li><code>&#39;[0-9]+&#39;</code>: 숫자가 <strong>1개 이상 연속되는 경우</strong> → 예: <code>123</code>, <code>45</code>, <code>7</code></li>
</ol>
<p>즉, 이 정규표현식은 <strong>처음 나타나는 숫자 연속 부분</strong>을 찾아준다.
<br></p>
<h4 id="복합-숫자-문자열도-정렬-가능">복합 숫자 문자열도 정렬 가능</h4>
<pre><code class="language-sql">SELECT *
FROM ex_table
ORDER BY TO_NUMBER(REGEXP_SUBSTR(&#39;qw12ww34&#39;, &#39;[0-9]+&#39;, 1, 1));</code></pre>
<ul>
<li><code>qw12ww34</code> → <code>12</code> 기준으로 정렬</li>
<li>첫 번째 숫자 기준으로 정렬<br>

</li>
</ul>
<h4 id="숫자만-남기고-싶다면">숫자만 남기고 싶다면?</h4>
<pre><code class="language-sql">SELECT REGEXP_REPLACE(col_varchar2, &#39;[^0-9]&#39;, &#39;&#39;) AS only_digits
FROM your_table;</code></pre>
<ul>
<li>qw12ww34 → 1234</li>
<li>문자 제거하고 숫자만 추출 가능<br>
### ✅ 숫자형태의 문자칼럼 정렬방법

</li>
</ul>
<p><code>varchar</code>자리에 문자형을 사용하지 않고, 모두 숫자만 입력하였을 때는
<code>order by</code> 뒤에 <code>to_number(칼럼명)</code>을 사용하면 숫자 크기대로 정렬 가능하다.</p>
<pre><code class="language-sql">SELECT col_varchar 
 FROM datatype_example 
 ORDER BY to_number(col_varchar); </code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Oracle]다른 네트워크 DBLink 연결하기, ORA-12154 tns 오류
(feat.DBeaver)]]></title>
            <link>https://velog.io/@cham-chi/Oracle%EB%8B%A4%EB%A5%B8-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-DBLink-%EC%97%B0%EA%B2%B0%ED%95%98%EA%B8%B0-ORA-12154-tns-%EC%98%A4%EB%A5%98feat.DBeaver</link>
            <guid>https://velog.io/@cham-chi/Oracle%EB%8B%A4%EB%A5%B8-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC-DBLink-%EC%97%B0%EA%B2%B0%ED%95%98%EA%B8%B0-ORA-12154-tns-%EC%98%A4%EB%A5%98feat.DBeaver</guid>
            <pubDate>Thu, 03 Apr 2025 02:20:51 GMT</pubDate>
            <description><![CDATA[<h2 id="데이터베이스-링크database-link란">데이터베이스 링크(Database Link)란</h2>
<p><img src="https://velog.velcdn.com/images/cham-chi/post/e21d73c9-e649-4a41-ad28-568abe8f48ed/image.png" alt=""></p>
<ul>
<li><p>내 데이터베이스에서 다른 데이터베이스에 접속할 수 있는 링크를 말한다.
네트워크상의 다른 데이터베이스에 접속하기 위한 접속 설정을 정의하는 오라클 객체이다. </p>
</li>
<li><p>다른 DB에 특정 유저에 대한 링크를 만들어 해당 스키마에 테이블들을 접근하는 기술이다
<br><br></p>
<h2 id="데이터베이스-링크-연결하기">데이터베이스 링크 연결하기</h2>
</li>
</ul>
<p>우선, 원격 서버의 tns 정보와 접속 유저의 정보를 가지고 있어야 한다.
여기서 코드를 간결하고 편하게 제작하고 싶으면 tns 파일에 별칭을 부여해 들고올 수 있다.</p>
<p>쉽게 말하자면 &#39;A&#39; DB에서 &#39;B&#39; DB로 DB Link 를 걸고자 한다면 우선 &#39;A&#39; DB의 TNSNAMES.ORA파일에 &#39;B&#39; DB 접속정보를 추가하는 것이다. 
아래의 사진처럼 TNSNAMES.ORA파일에 별칭을 부여해서 접속정보를 넣고 사용할 수 있다.
<img src="https://velog.velcdn.com/images/cham-chi/post/d21345ce-9aa9-4116-95a4-dbedad4dcd55/image.png" alt=""></p>
<pre><code class="language-sql">--풀 버전
CREATE DATABASE LINK [DBLINK이름] 
CONNECT TO 원격유저명 IDENTIFIED BY &quot;비밀번호&quot;
USING &#39;(DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = [IP])(PORT = [포트번호])))
(CONNECT_DATA = ( sid = [sid] )(service_name = [service_name])))&#39;;

--별칭 버전
CREATE DATABASE LINK [DBLINK이름] 
CONNECT TO 원격유저명 IDENTIFIED BY &quot;비밀번호&quot;
USING &#39;sung&#39;;</code></pre>
<p><br><br></p>
<h2 id="데이터-조회-및-삽입하기">데이터 조회 및 삽입하기</h2>
<ol>
<li>조회하기
데이터베이스 링크를 연결하였으면 아래의 쿼리를 활용해 상대방의 DB를 들고올 수 있다. 여기서 [테이블 명] 다음 &#39;@&#39;를 붙이고 [DBLINK이름]을 작성해야 한다.<pre><code class="language-sql">SELECT * FROM [테이블 명]@[DBLINK이름];</code></pre>
</li>
<li>삽입하기
삽입하기도 insert문을 작성할 때 [테이블 명]@[DBLINK이름]를 작성해주면 된다.<pre><code class="language-sql">INSERT INTO [테이블 명]@[DBLINK이름]
(EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
VALUES(99999999, &#39;심청이&#39;, NULL, NULL, NULL, NULL, NULL, NULL);</code></pre>
</li>
</ol>
<p><br><br></p>
<h2 id="ora-12154-tns-오류">ORA-12154 tns 오류</h2>
<p>사진처럼 12154번 오류가 발생했다.
TNSNAMES.ORA 파일의 별칭을 설정할 때 맨 앞에 공백을 추가해서 오라클이 인식을 못 해 발생한 오류였다.
<img src="https://velog.velcdn.com/images/cham-chi/post/06cd3822-113d-4d52-b6e5-2f97c35f283e/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Oracle]DBeaver(디비버)와 오라클 연결하기]]></title>
            <link>https://velog.io/@cham-chi/OracleDBeaver%EB%94%94%EB%B9%84%EB%B2%84%EC%99%80-%EC%98%A4%EB%9D%BC%ED%81%B4-%EC%97%B0%EA%B2%B0%ED%95%98%EA%B8%B0-jvv2x5uo</link>
            <guid>https://velog.io/@cham-chi/OracleDBeaver%EB%94%94%EB%B9%84%EB%B2%84%EC%99%80-%EC%98%A4%EB%9D%BC%ED%81%B4-%EC%97%B0%EA%B2%B0%ED%95%98%EA%B8%B0-jvv2x5uo</guid>
            <pubDate>Wed, 02 Apr 2025 06:46:06 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>Tool 설치하기</p>
</blockquote>
<ul>
<li><a href="https://dbeaver.io/download/">dbeaver 사이트</a>에 접속해서 다운로드</li>
</ul>
<ol>
<li><p>환경에 맞는 파일 다운로드
<img src="https://velog.velcdn.com/images/cham-chi/post/8ac3b50a-805f-4ffc-a917-3c86d4e5d13a/image.png" alt=""></p>
</li>
<li><p>다운로드 후 실행하면서 설치
<img src="https://velog.velcdn.com/images/cham-chi/post/b97835ec-e3bb-4e04-a7f4-998ed6411039/image.png" alt=""></p>
</li>
</ol>
<blockquote>
<p>DBeaver 실행</p>
</blockquote>
<p>데이터베이스 - 새 데이터베이스 연결을 클릭하면 새로운 db를 생성할 수 있다.
오라클을 클락한 후 다음으로 넘어간다.
<img src="https://velog.velcdn.com/images/cham-chi/post/45ff605b-1b30-4bba-a762-6a179996277e/image.png" alt=""></p>
<p>Host값과 Database값을 입력하는데 나는 오라클 xe 버전이라 xe로 하였다.
아래의 Username과 Password도 입력한다.
같은 네트워크(Wi-Fi나 LAN)에 접속된 상태라면, Host값에 다른 사내 ip주소를 입력하여 다른 사내 PC나 서버로 접근 가능하다.
<strong>아래의 Test Connection을 클릭했을 때 성공 창이 뜨면 완료를 클릭한다.</strong>
<img src="https://velog.velcdn.com/images/cham-chi/post/bb834436-c8fa-43d1-b5b6-89568c207fa7/image.png" alt=""></p>
<p>다음과 같이 에러가 뜨면 이전 과정에서 무언가 잘 못된 것이다.
이번 경우는 username과 passwoed가 일치하지 않아 일어난 에러이다.
sql plus에서 생성한 사용자를 입력하면 아래와 같은 에러를 방지할 수 있다.
<img src="https://velog.velcdn.com/images/cham-chi/post/04269efd-2d10-431e-a8e6-3702eda2fd47/image.png" alt=""></p>
<p>연결이 성공적으로 완료되면 이렇게 창이 뜬다!
<img src="https://velog.velcdn.com/images/cham-chi/post/8f7e0e24-f145-433f-9fee-1d3eab8e702b/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Oracle] 계정 생성하기]]></title>
            <link>https://velog.io/@cham-chi/OracleDBeaver%EB%94%94%EB%B9%84%EB%B2%84%EC%99%80-%EC%98%A4%EB%9D%BC%ED%81%B4-%EC%97%B0%EA%B2%B0%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@cham-chi/OracleDBeaver%EB%94%94%EB%B9%84%EB%B2%84%EC%99%80-%EC%98%A4%EB%9D%BC%ED%81%B4-%EC%97%B0%EA%B2%B0%ED%95%98%EA%B8%B0</guid>
            <pubDate>Wed, 02 Apr 2025 06:22:49 GMT</pubDate>
            <description><![CDATA[<h3 id="오라클-21c-설치">오라클 21C 설치</h3>
<p><a href="https://www.oracle.com/kr/database/technologies/xe-downloads.html">오라클 홈페이지</a>에서 오라클을 다운 받는다.</p>
<h3 id="오라클-계정-생성">오라클 계정 생성</h3>
<ol>
<li><p>SQL Plus 창을 띄워보자. cmd에서 sqlplus를 입력해도 상관없다.
사용자명과 비밀번호를 입력한다.
<del>비밀번호는 입력해도 안 보인다.</del></p>
</li>
<li><p>관리자 권한으로 접속</p>
<pre><code class="language-sql">conn/as sysdba</code></pre>
</li>
<li><p>계정 생성
[id] [pw]는 자신이 생각하는 id와 pw로 입력하면 된다.</p>
<pre><code class="language-sql">create user [id] identified by [pw];</code></pre>
</li>
</ol>
<p><img src="https://velog.velcdn.com/images/cham-chi/post/8062a69a-5d3b-4a50-8caa-8e8531b086fb/image.png" alt=""></p>
<ol start="4">
<li><p>권한 부여
계정을 생성 한 후에 권한을 부여한다.
<img src="https://velog.velcdn.com/images/cham-chi/post/fb096f16-b4ff-4dec-b62a-48aceb046229/image.png" alt="">
<img src="https://velog.velcdn.com/images/cham-chi/post/ab86dde0-b5a7-47fd-a876-1489b48090dc/image.png" alt=""></p>
</li>
<li><p>commit
지금까지 변경사항들을 적용한다.</p>
<pre><code class="language-sql">commit;</code></pre>
</li>
<li><p>계정 생성 확인
아래의 사진을 보면 계정이 생성된 것을 확인할 수 있다.</p>
<pre><code class="language-sql">conn c##userID;
show user;</code></pre>
<p><img src="https://velog.velcdn.com/images/cham-chi/post/73db19c5-eaea-4d8d-a953-708603243260/image.png" alt=""></p>
</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JAVA] 프로그래머스 코드 리뷰 - Level 1 (문자열 밀기)]]></title>
            <link>https://velog.io/@cham-chi/JAVA-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%BD%94%EB%93%9C-%EB%A6%AC%EB%B7%B0-Level-1-%EB%AC%B8%EC%9E%90%EC%97%B4-%EB%B0%80%EA%B8%B0</link>
            <guid>https://velog.io/@cham-chi/JAVA-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%BD%94%EB%93%9C-%EB%A6%AC%EB%B7%B0-Level-1-%EB%AC%B8%EC%9E%90%EC%97%B4-%EB%B0%80%EA%B8%B0</guid>
            <pubDate>Fri, 14 Mar 2025 14:24:06 GMT</pubDate>
            <description><![CDATA[<h1 id="문자열-밀기">문자열 밀기</h1>
<blockquote>
<h3 id="문제-설명">문제 설명</h3>
<p>문자열 &quot;hello&quot;에서 각 문자를 오른쪽으로 한 칸씩 밀고 마지막 문자는 맨 앞으로 이동시키면 &quot;ohell&quot;이 됩니다. 이것을 문자열을 민다고 정의한다면 문자열 <code>A</code>와 <code>B</code>가 매개변수로 주어질 때, <code>A</code>를 밀어서 <code>B</code>가 될 수 있다면 밀어야 하는 최소 횟수를 return하고 밀어서 B가 될 수 없으면 -1을 return 하도록 solution 함수를 완성해보세요.</p>
</blockquote>
<h4 id="제한사항">제한사항</h4>
<ul>
<li>0 &lt; <code>A</code>의 길이 = <code>B</code>의 길이 &lt; 100</li>
<li><code>A</code>, <code>B</code>는 알파벳 소문자로 이루어져 있습니다.<h4 id="입출력-예">입출력 예</h4>
<img src="https://velog.velcdn.com/images/cham-chi/post/4457e1ae-9931-4568-b85e-a2e9652e4f21/image.png" alt=""></li>
</ul>
<h4 id="입출력-설명">입출력 설명</h4>
<p><img src="https://velog.velcdn.com/images/cham-chi/post/399f8331-d856-440e-b3f8-36a656bba7f5/image.png" alt=""></p>
<h4 id="결과코드">결과코드</h4>
<pre><code class="language-java">class Solution {
    public int solution(String A, String B) {
        for (int i = 0; i &lt; A.length(); i++) {
            if (A.equals(B)) return i;
            A = A.charAt(A.length() - 1) + A.substring(0, A.length() - 1);
        }
        return -1;
    }
}</code></pre>
<p>🗝️Point🗝️
처음에는 <code>A</code>와 <code>B</code>가 같을 때와 같지 않을 때를 구분하고, 오른 쪽으로 돌 때와 왼 쪽으로 돌 때의 횟수 차이까지 조건문을 넣어가며 코드를 작성했었다. 그러다보니  코드가 너무 길어지고 지저분해졌었다.
어떻게 하면 코드를 더 간결하게 작성할 수 있을지 고민하다 지금의 코드가 나왔다.
<code>i</code> 변수를 <code>A</code>의 길이 만큼 설정하고 그 안에 조건문을 넣었다. </p>
<ul>
<li><p><code>A</code>와 <code>B</code>가 같을 때 <code>i</code>의 값을 return 한다. 
이 조건을 넣으니 초기 값 0을 설정하지 않아도 <code>A</code>와 <code>B</code>가 같다면 0이 return 될 수 있었다.</p>
</li>
<li><p><code>A</code>의 뒷 자리와 <code>A</code>의 뒷 자리를 뺀 단어를 붙인다.</p>
</li>
<li><p>이것을 <code>A</code>의 길이 만큼 반복한다.</p>
</li>
<li><p>반복문이 끝났는 데 return 값이 없으면 -1을 return 한다.
<code>A</code>와 <code>B</code>가 같지 않을 결우 -1을 return하게 한다.</p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JAVA] 프로그래머스 코드 리뷰 - Level 0 (배열의 길이를 2의 거듭제곱으로 만들기)]]></title>
            <link>https://velog.io/@cham-chi/JAVA-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%BD%94%EB%93%9C-%EB%A6%AC%EB%B7%B0-Level-0-%EB%B0%B0%EC%97%B4%EC%9D%98-%EA%B8%B8%EC%9D%B4%EB%A5%BC-2%EC%9D%98-%EA%B1%B0%EB%93%AD%EC%A0%9C%EA%B3%B1%EC%9C%BC%EB%A1%9C-%EB%A7%8C%EB%93%A4%EA%B8%B0</link>
            <guid>https://velog.io/@cham-chi/JAVA-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%BD%94%EB%93%9C-%EB%A6%AC%EB%B7%B0-Level-0-%EB%B0%B0%EC%97%B4%EC%9D%98-%EA%B8%B8%EC%9D%B4%EB%A5%BC-2%EC%9D%98-%EA%B1%B0%EB%93%AD%EC%A0%9C%EA%B3%B1%EC%9C%BC%EB%A1%9C-%EB%A7%8C%EB%93%A4%EA%B8%B0</guid>
            <pubDate>Mon, 10 Mar 2025 09:52:06 GMT</pubDate>
            <description><![CDATA[<h1 id="배열의-길이를-2의-거듭제곱으로-만들기">배열의 길이를 2의 거듭제곱으로 만들기</h1>
<blockquote>
<h3 id="문제-설명">문제 설명</h3>
<p>정수 배열 <code>arr</code>이 매개변수로 주어집니다. <code>arr</code>의 길이가 2의 정수 거듭제곱이 되도록 <code>arr</code> 뒤에 정수 0을 추가하려고 합니다. <code>arr</code>에 최소한의 개수로 0을 추가한 배열을 return 하는 solution 함수를 작성해 주세요.</p>
</blockquote>
<h4 id="제한사항">제한사항</h4>
<ul>
<li>1 ≤ <code>arr</code>의 길이 ≤ 1,000</li>
<li>1 ≤ <code>arr</code>의 원소 ≤ 1,000</li>
</ul>
<h4 id="입출력-예">입출력 예</h4>
<p><img src="https://velog.velcdn.com/images/cham-chi/post/b3162199-a9d2-4886-a632-18b10837dbe1/image.png" alt=""></p>
<h4 id="입출력-설명">입출력 설명</h4>
<p><img src="https://velog.velcdn.com/images/cham-chi/post/e2dcec35-28d5-4ae4-9ce9-4889e7d30d2c/image.png" alt=""></p>
<h4 id="결과코드">결과코드</h4>
<pre><code class="language-java">import java.util.Arrays;

class Solution {
    public int[] solution(int[] arr) {
        int n = arr.length;
        int targetLength = 1;

        while (targetLength &lt; n) {
            targetLength *= 2;
        }

        int[] answer = new int[targetLength];
        Arrays.fill(answer, 0);

        System.arraycopy(arr, 0, answer, 0, n);

        return answer;
    }
}</code></pre>
<p>🗝️Point🗝️
<code>targetLength</code>가 n보다 작거나 같은 2의 거듭제곱을 찾고, 0을 추가하여 <code>targetLength</code> 길이의 배열을 생성한다.
마지막으로 <code>arr</code>의 요소들을 answer로 복사하다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JAVA] 프로그래머스 코드 리뷰 - Level 0 (문자열 겹쳐쓰기)]]></title>
            <link>https://velog.io/@cham-chi/JAVA-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%BD%94%EB%93%9C-%EB%A6%AC%EB%B7%B0-Level-0-%EB%AC%B8%EC%9E%90%EC%97%B4-%EA%B2%B9%EC%B3%90%EC%93%B0%EA%B8%B0</link>
            <guid>https://velog.io/@cham-chi/JAVA-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%BD%94%EB%93%9C-%EB%A6%AC%EB%B7%B0-Level-0-%EB%AC%B8%EC%9E%90%EC%97%B4-%EA%B2%B9%EC%B3%90%EC%93%B0%EA%B8%B0</guid>
            <pubDate>Fri, 28 Feb 2025 14:45:54 GMT</pubDate>
            <description><![CDATA[<h1 id="문자열-겹쳐쓰기">문자열 겹쳐쓰기</h1>
<blockquote>
<h3 id="문제-설명">문제 설명</h3>
<p>문자열 <code>my_string</code>, <code>overwrite_string</code>과 정수 <code>s</code>가 주어집니다. 문자열 <code>my_string</code>의 인덱스 <code>s</code>부터 <code>overwrite_string</code>의 길이만큼을 문자열 <code>overwrite_string</code>으로 바꾼 문자열을 return 하는 solution 함수를 작성해 주세요.</p>
</blockquote>
<h4 id="제한사항">제한사항</h4>
<ul>
<li><code>my_string</code>와 <code>overwrite_string</code>은 숫자와 알파벳으로 이루어져 있습니다.</li>
<li>1 ≤ <code>overwrite_string</code>의 길이 ≤ <code>my_string</code>의 길이 ≤ 1,000</li>
<li>0 ≤ s ≤ <code>my_string</code>의 길이 - <code>overwrite_string</code>의 길이</li>
</ul>
<h4 id="입출력-예">입출력 예</h4>
<p><img src="https://velog.velcdn.com/images/cham-chi/post/2b2832e4-aeaf-464a-be3d-3176dfd208a4/image.png" alt=""></p>
<h4 id="입출력-설명">입출력 설명</h4>
<p><img src="https://velog.velcdn.com/images/cham-chi/post/b90f8f3e-f229-4955-8665-af0dadde34fe/image.png" alt=""></p>
<h4 id="결과코드">결과코드</h4>
<pre><code class="language-java">class Solution {
    public String solution(String my_string, String overwrite_string, int s) {
        String answer = &quot;&quot;;
        String x = my_string.substring(0,s);

        int end = s + overwrite_string.length();

        if ( overwrite_string.length() &gt;= (my_string.length() - s )) {
            answer = x + overwrite_string;
        } else {
            answer = x + overwrite_string + my_string.substring(end);
        }

        return answer;
    }
}</code></pre>
<p>🗝️Point🗝️
<code>my_string</code>의 길이를 <code>s</code>의 길만큼 자르고 그 뒤에<code>overwrite_string</code>를 붙인다.
여기서 <code>my_string</code>-<code>s</code>한 길이보다 <code>overwrite_string</code>의 길이가 작을 경우 남은 뒷 자리에 다시  <code>my_string</code>의 남은 수를 넣어야 하니 <code>end</code>의 길이를 구해서 뒤에 넣어주는 것이 중요하다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JAVA] 프로그래머스 코드 리뷰 - Level 0 (n개 간격의 원소)]]></title>
            <link>https://velog.io/@cham-chi/JAVA-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%BD%94%EB%93%9C-%EB%A6%AC%EB%B7%B0-Level-0-n%EA%B0%9C-%EA%B0%84%EA%B2%A9%EC%9D%98-%EC%9B%90%EC%86%8C</link>
            <guid>https://velog.io/@cham-chi/JAVA-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%BD%94%EB%93%9C-%EB%A6%AC%EB%B7%B0-Level-0-n%EA%B0%9C-%EA%B0%84%EA%B2%A9%EC%9D%98-%EC%9B%90%EC%86%8C</guid>
            <pubDate>Mon, 24 Feb 2025 14:07:27 GMT</pubDate>
            <description><![CDATA[<h1 id="n개-간격의-원소">n개 간격의 원소</h1>
<blockquote>
<h3 id="문제-설명">문제 설명</h3>
<p>정수 리스트 <code>num_list</code>와 정수 <code>n</code>이 주어질 때, <code>num_list</code>의 첫 번째 원소부터 마지막 원소까지 n개 간격으로 저장되어있는 원소들을 차례로 담은 리스트를 return하도록 solution 함수를 완성해주세요.</p>
</blockquote>
<h4 id="제한사항">제한사항</h4>
<ul>
<li>5 ≤ <code>num_list</code>의 길이 ≤ 20</li>
<li>1 ≤ <code>num_list</code>의 원소 ≤ 9</li>
<li>1 ≤ <code>n</code> ≤ 4</li>
</ul>
<h4 id="입출력-예">입출력 예</h4>
<p><img src="https://velog.velcdn.com/images/cham-chi/post/19504628-eb26-456b-a952-04cc6b5b3665/image.png" alt=""></p>
<h4 id="입출력-설명">입출력 설명</h4>
<p><img src="https://velog.velcdn.com/images/cham-chi/post/555bab68-0f25-4c53-b74f-011ee1df9ea3/image.png" alt=""></p>
<h4 id="결과코드">결과코드</h4>
<pre><code class="language-java">class Solution {
    public int[] solution(int[] num_list, int n) {
        int[] answer = new int[(num_list.length + n - 1)/n];
        int index = 0;
        for(int i = 0; i&lt;num_list.length; i+=n){
            int x = num_list[i];
            answer[index] += x;
            index++;
        }
        return answer;
    }
}</code></pre>
<p>🗝️Point🗝️
<code>answer</code>의 길이 설정과 <code>i+=n</code>로 <code>answer</code>에 들어갈 원소를 잘 넣어주어야 한다.
<code>answer</code>의 길이를 설정할 때 <code>num_list.length/ n</code>을 하면 <code>num_list.length</code>이 <code>n</code>의 배수가 아니라면 길이 설정의 오류가 난다.<code>(num_list.length + n - 1)/n</code>을 하지 않으면 마지막 그룹이 존재해야 하는 경우에도 배열의 크기가 부족하여 정상적으로 저장되지 않는다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JAVA] 프로그래머스 코드 리뷰 - Level 0 (이차원 배열 대각선 순회하기)]]></title>
            <link>https://velog.io/@cham-chi/JAVA-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%BD%94%EB%93%9C-%EB%A6%AC%EB%B7%B0-Level-0-%EC%9D%B4%EC%B0%A8%EC%9B%90-%EB%B0%B0%EC%97%B4-%EB%8C%80%EA%B0%81%EC%84%A0-%EC%88%9C%ED%9A%8C%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@cham-chi/JAVA-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%BD%94%EB%93%9C-%EB%A6%AC%EB%B7%B0-Level-0-%EC%9D%B4%EC%B0%A8%EC%9B%90-%EB%B0%B0%EC%97%B4-%EB%8C%80%EA%B0%81%EC%84%A0-%EC%88%9C%ED%9A%8C%ED%95%98%EA%B8%B0</guid>
            <pubDate>Fri, 07 Feb 2025 16:24:19 GMT</pubDate>
            <description><![CDATA[<h1 id="이차원-배열-대각선-순회하기">이차원 배열 대각선 순회하기</h1>
<blockquote>
<h3 id="문제-설명">문제 설명</h3>
<p>2차원 정수 배열 <code>board</code>와 정수 <code>k</code>가 주어집니다.<br>
<code>i</code> + <code>j</code> &lt;= <code>k</code>를 만족하는 모든 <code>(i, j)</code>에 대한 <code>board[i][j]</code>의 합을 return 하는 solution 함수를 완성해 주세요.</p>
</blockquote>
<h4 id="제한사항">제한사항</h4>
<ul>
<li>1 ≤ board의 길이 ≤ 100</li>
<li>1 ≤ board[i]의 길이 ≤ 100
1 ≤ board[i][j] ≤ 10,000
모든 board[i]의 길이는 같습니다.</li>
<li>0 ≤ k &lt; board의 길이 + board[i]의 길이</li>
</ul>
<h4 id="입출력-예">입출력 예</h4>
<p><img src="https://velog.velcdn.com/images/cham-chi/post/73e4f236-be8b-44f2-afe8-3c71c825d49f/image.png" alt=""></p>
<h4 id="입출력-설명">입출력 설명</h4>
<p><img src="https://velog.velcdn.com/images/cham-chi/post/17c36579-b3df-4d8f-b98b-2d61aff9d5c3/image.png" alt=""></p>
<h4 id="결과코드">결과코드</h4>
<pre><code class="language-java">class Solution {
    public int solution(int[][] board, int k) {
        int answer = 0;
        for(int i = 0; i&lt;board.length; i++){
                for(int j = 0; j&lt;board[i].length; j++){
                    if(i+j&lt;=k){
                        answer += board[i][j];
                    }
                }
        }
        return answer;
    }
}</code></pre>
<p>🗝️Point🗝️
전반적으로 잘 작성된 코드이며, 가독성이 뛰어나고 문제 요구사항을 정확히 충족시켰다.
반복문의 범위를 줄이면 성능 최적화 가능.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JAVA] 프로그래머스 코드 리뷰 - Level 0 (조건 문자열)]]></title>
            <link>https://velog.io/@cham-chi/JAVA-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%BD%94%EB%93%9C-%EB%A6%AC%EB%B7%B0-Level-0-%EC%A1%B0%EA%B1%B4-%EB%AC%B8%EC%9E%90%EC%97%B4</link>
            <guid>https://velog.io/@cham-chi/JAVA-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%BD%94%EB%93%9C-%EB%A6%AC%EB%B7%B0-Level-0-%EC%A1%B0%EA%B1%B4-%EB%AC%B8%EC%9E%90%EC%97%B4</guid>
            <pubDate>Fri, 07 Feb 2025 16:13:59 GMT</pubDate>
            <description><![CDATA[<h1 id="조건-문자열">조건 문자열</h1>
<blockquote>
<h3 id="문제-설명">문제 설명</h3>
<p>문자열에 따라 다음과 같이 두 수의 크기를 비교하려고 합니다.<br>
두 수가 n과 m이라면
&quot;&gt;&quot;, &quot;=&quot; : <code>n</code> &gt;= <code>m</code>
&quot;&lt;&quot;, &quot;=&quot; : <code>n</code> &lt;= <code>m</code>
&quot;&gt;&quot;, &quot;!&quot; : <code>n</code> &gt; <code>m</code>
&quot;&lt;&quot;, &quot;!&quot; : <code>n</code> &lt; <code>m</code><br>
두 문자열 ineq와 eq가 주어집니다. ineq는 &quot;&lt;&quot;와 &quot;&gt;&quot;중 하나고, eq는 &quot;=&quot;와 &quot;!&quot;중 하나입니다. 그리고 두 정수 n과 m이 주어질 때, n과 m이 ineq와 eq의 조건에 맞으면 1을 아니면 0을 return하도록 solution 함수를 완성해주세요.</p>
</blockquote>
<h4 id="제한사항">제한사항</h4>
<p>1 ≤ <code>n</code>, <code>m</code> ≤ 100</p>
<h4 id="입출력-예">입출력 예</h4>
<p><img src="https://velog.velcdn.com/images/cham-chi/post/0ad24124-620d-4de6-9922-2e74bc2c74a7/image.png" alt=""></p>
<h4 id="입출력-설명">입출력 설명</h4>
<p><img src="https://velog.velcdn.com/images/cham-chi/post/3f50d54e-47ec-4512-b8fd-abfc953cbaa5/image.png" alt=""></p>
<h4 id="결과코드">결과코드</h4>
<pre><code class="language-java">class Solution {
    public int solution(String ineq, String eq, int n, int m) {
        int answer = 0;

        if ((ineq.equals(&quot;&lt;&quot;) &amp;&amp; eq.equals(&quot;=&quot;) &amp;&amp; n &lt;= m) || 
            (ineq.equals(&quot;&gt;&quot;) &amp;&amp; eq.equals(&quot;=&quot;) &amp;&amp; n &gt;= m) ||
            (ineq.equals(&quot;&lt;&quot;) &amp;&amp; eq.equals(&quot;!&quot;) &amp;&amp; n &lt; m) ||
            (ineq.equals(&quot;&gt;&quot;) &amp;&amp; eq.equals(&quot;!&quot;) &amp;&amp; n &gt; m)) {
            answer = 1;
        }
        return answer;
    }
}</code></pre>
<p>🗝️Point🗝️
if 문에 주어진 조건을 잘 작성하면 되는 문제</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JAVA] 프로그래머스 코드 리뷰 - Level 0 (글지 지우기)]]></title>
            <link>https://velog.io/@cham-chi/JAVA-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%BD%94%EB%93%9C-%EB%A6%AC%EB%B7%B0-Level-0-%EA%B8%80%EC%A7%80-%EC%A7%80%EC%9A%B0%EA%B8%B0</link>
            <guid>https://velog.io/@cham-chi/JAVA-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%BD%94%EB%93%9C-%EB%A6%AC%EB%B7%B0-Level-0-%EA%B8%80%EC%A7%80-%EC%A7%80%EC%9A%B0%EA%B8%B0</guid>
            <pubDate>Tue, 04 Feb 2025 14:34:03 GMT</pubDate>
            <description><![CDATA[<h1 id="글지-지우기">글지 지우기</h1>
<blockquote>
<h3 id="문제-설명">문제 설명</h3>
<p>문자열 <code>my_string</code>과 정수 배열 <code>indices</code>가 주어질 때, <code>my_string</code>에서 <code>indices</code>의 원소에 해당하는 인덱스의 글자를 지우고 이어 붙인 문자열을 return 하는 solution 함수를 작성해 주세요.</p>
</blockquote>
<h4 id="제한사항">제한사항</h4>
<ul>
<li>1 ≤ <code>indices</code>의 길이 &lt; <code>my_string</code>의 길이 ≤ 100</li>
<li><code>my_string</code>은 영소문자로만 이루어져 있습니다</li>
<li>0 ≤ <code>indices</code>의 원소 &lt; <code>my_string</code>의 길이</li>
<li><code>indices</code>의 원소는 모두 서로 다릅니다.</li>
</ul>
<h4 id="입출력-예">입출력 예</h4>
<p><img src="https://velog.velcdn.com/images/cham-chi/post/07b45ab7-b9c5-4fdb-934d-4f089f39c07c/image.png" alt=""></p>
<h4 id="입출력-설명">입출력 설명</h4>
<p><img src="https://velog.velcdn.com/images/cham-chi/post/3236b87c-c223-44b8-a201-122392baf76d/image.png" alt=""></p>
<h4 id="결과코드">결과코드</h4>
<pre><code class="language-java">class Solution {
    public String solution(String my_string, int[] indices) {
        String answer = &quot;&quot;;
        String[] a = my_string.split(&quot;&quot;);
        for (int i = 0; i &lt; indices.length; i++) {
            a[indices[i]] = &quot;&quot;;
        }
        for (String x : a) {
            answer += x;
        }
        return answer;
    }
}</code></pre>
<p>🗝️Point🗝️
문자열을 배열로 변환한 후, 인덱스에 해당하는 값을 제거하는 방식으로 직관적이다.
불필요한 로직 없이 핵심적인 동작만 수행하도록 설계하여 가독성을 높혔다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JAVA] 프로그래머스 코드 리뷰 - Level 0 (뒤에서 5등 위로)]]></title>
            <link>https://velog.io/@cham-chi/JAVA-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%BD%94%EB%93%9C-%EB%A6%AC%EB%B7%B0-Level-0-%EB%92%A4%EC%97%90%EC%84%9C-5%EB%93%B1-%EC%9C%84%EB%A1%9C</link>
            <guid>https://velog.io/@cham-chi/JAVA-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%BD%94%EB%93%9C-%EB%A6%AC%EB%B7%B0-Level-0-%EB%92%A4%EC%97%90%EC%84%9C-5%EB%93%B1-%EC%9C%84%EB%A1%9C</guid>
            <pubDate>Thu, 30 Jan 2025 12:50:52 GMT</pubDate>
            <description><![CDATA[<h1 id="뒤에서-5등-위로">뒤에서 5등 위로</h1>
<blockquote>
<h3 id="문제-설명">문제 설명</h3>
<p>정수로 이루어진 리스트 <code>num_list</code>가 주어집니다. <code>num_list</code>에서 가장 작은 5개의 수를 제외한 수들을 오름차순으로 담은 리스트를 return하도록 solution 함수를 완성해주세요.</p>
</blockquote>
<h4 id="제한사항">제한사항</h4>
<ul>
<li>6 ≤ <code>num_list</code>의 길이 ≤ 30</li>
<li>1 ≤ <code>num_list</code>의 원소 ≤ 100</li>
</ul>
<h4 id="입출력-예">입출력 예</h4>
<table>
<thead>
<tr>
<th align="center">num_list</th>
<th align="center">result</th>
</tr>
</thead>
<tbody><tr>
<td align="center">[12, 4, 15, 46, 38, 1, 14, 56, 32, 10]</td>
<td align="center">[15, 32, 38, 46, 56]</td>
</tr>
<tr>
<td align="center">- 입출력 설명</td>
<td align="center"></td>
</tr>
<tr>
<td align="center">[12, 4, 15, 46, 38, 1, 14, 56, 32, 10]를 정렬하면 [1, 4, 10, 12, 14, 15, 32, 38, 46, 56]이 되고, 앞에서 부터 6번째 이후의 수들을 고르면 [15, 32, 38, 46, 56]가 됩니다.</td>
<td align="center"></td>
</tr>
</tbody></table>
<h4 id="결과코드">결과코드</h4>
<pre><code class="language-java">import java.util.*;
class Solution {
    public int[] solution(int[] num_list) {
        Arrays.sort(num_list);
        int n = 5;
        int[] answer = new int[num_list.length-n];
        for(int i=n; i&lt;num_list.length; i++){
            answer[i-n]=num_list[i];
        }

        return answer;
    }
}</code></pre>
<p>🗝️Point🗝️
주어진 배열을 정렬하여 작은 값부터 차례대로 정렬하는 방식이다.
<code>new int[num_list.length - n]</code>을 통해 적절한 크기의 배열을 생성했다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JAVA] 프로그래머스 코드 리뷰 - Level 0 (뒤에서 5등까지)]]></title>
            <link>https://velog.io/@cham-chi/JAVA-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%BD%94%EB%93%9C-%EB%A6%AC%EB%B7%B0-Level-0-%EB%92%A4%EC%97%90%EC%84%9C-5%EB%93%B1%EA%B9%8C%EC%A7%80</link>
            <guid>https://velog.io/@cham-chi/JAVA-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%BD%94%EB%93%9C-%EB%A6%AC%EB%B7%B0-Level-0-%EB%92%A4%EC%97%90%EC%84%9C-5%EB%93%B1%EA%B9%8C%EC%A7%80</guid>
            <pubDate>Thu, 30 Jan 2025 12:50:47 GMT</pubDate>
            <description><![CDATA[<h1 id="뒤에서-5등까지">뒤에서 5등까지</h1>
<blockquote>
<h3 id="문제-설명">문제 설명</h3>
<p>정수로 이루어진 리스트 <code>num_list</code>가 주어집니다. <br><code>num_list</code>에서 가장 작은 5개의 수를 오름차순으로 담은 리스트를 return하도록 solution 함수를 완성해주세요.</p>
</blockquote>
<h4 id="제한사항">제한사항</h4>
<ul>
<li>6 ≤ <code>num_list</code>의 길이 ≤ 30</li>
<li>1 ≤ <code>num_list</code>의 원소 ≤ 100</li>
</ul>
<h4 id="입출력-예">입출력 예</h4>
<table>
<thead>
<tr>
<th align="center">num_list</th>
<th align="center">result</th>
</tr>
</thead>
<tbody><tr>
<td align="center">[12, 4, 15, 46, 38, 1, 14]</td>
<td align="center">[1, 4, 12, 14, 15]</td>
</tr>
<tr>
<td align="center">- 입출력 설명</td>
<td align="center"></td>
</tr>
<tr>
<td align="center">[12, 4, 15, 46, 38, 1, 14, 56, 32, 10]를 정렬하면 [1, 4, 10, 12, 14, 15, 32, 38, 46, 56]이 되고, 앞에서 부터 6번째 이후의 수들을 고르면 [15, 32, 38, 46, 56]가 됩니다.</td>
<td align="center"></td>
</tr>
</tbody></table>
<h4 id="결과코드">결과코드</h4>
<pre><code class="language-java">import java.util.Arrays;
class Solution {
    public int[] solution(int[] num_list) {
        Arrays.sort(num_list);

        return Arrays.copyOfRange(num_list, 0, 5);
    }
}</code></pre>
<p>🗝️Point🗝️
주어진 배열을 정렬하여 앞에서 부터 5개만 return한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JAVA] 프로그래머스 코드 리뷰 - Level 0 (코드 처리하기)]]></title>
            <link>https://velog.io/@cham-chi/JAVA-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%BD%94%EB%93%9C-%EB%A6%AC%EB%B7%B0-Level-0-%EC%BD%9C%EB%9D%BC%EC%B8%A0-%EC%88%98%EC%97%B4-%EB%A7%8C%EB%93%A4%EA%B8%B0-8zyhun49</link>
            <guid>https://velog.io/@cham-chi/JAVA-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%BD%94%EB%93%9C-%EB%A6%AC%EB%B7%B0-Level-0-%EC%BD%9C%EB%9D%BC%EC%B8%A0-%EC%88%98%EC%97%B4-%EB%A7%8C%EB%93%A4%EA%B8%B0-8zyhun49</guid>
            <pubDate>Fri, 24 Jan 2025 14:58:58 GMT</pubDate>
            <description><![CDATA[<h1 id="코드-처리하기">코드 처리하기</h1>
<blockquote>
<h3 id="문제-설명">문제 설명</h3>
<p>문자열 <code>code</code>가 주어집니다.
<code>code</code>를 앞에서부터 읽으면서 만약 문자가 &quot;1&quot;이면 <code>mode</code>를 바꿉니다. <code>mode</code>에 따라 <code>code</code>를 읽어가면서 문자열 <code>ret</code>을 만들어냅니다.<br>
<code>mode</code>는 0과 1이 있으며, <code>idx</code>를 0 부터 <code>code</code>의 길이 - 1 까지 1씩 키워나가면서 <code>code[idx]</code>의 값에 따라 다음과 같이 행동합니다.<br></p>
</blockquote>
<ul>
<li><code>mode</code>가 0일 때
<code>code[idx]</code>가 &quot;1&quot;이 아니면 <code>idx</code>가 짝수일 때만 <code>ret</code>의 맨 뒤에 <code>code[idx]</code>를 추가합니다.
<code>code[idx]</code>가 &quot;1&quot;이면 <code>mode</code>를 0에서 1로 바꿉니다.</li>
<li><code>mode</code>가 1일 때
<code>code[idx]</code>가 &quot;1&quot;이 아니면 <code>idx</code>가 홀수일 때만 <code>ret</code>의 맨 뒤에 <code>code[idx]</code>를 추가합니다.
<code>code[idx]</code>가 &quot;1&quot;이면 <code>mode</code>를 1에서 0으로 바꿉니다.
문자열 <code>code</code>를 통해 만들어진 문자열 <code>ret</code>를 <code>return</code> 하는 solution 함수를 완성해 주세요.<br>
단, 시작할 때 <code>mode</code>는 0이며, <code>return</code> 하려는 <code>ret</code>가 만약 빈 문자열이라면 대신 &quot;EMPTY&quot;를 return 합니다.</li>
</ul>
<h4 id="제한사항">제한사항</h4>
<ul>
<li>1 ≤ <code>code</code>의 길이 ≤ 100,000
<code>code</code>는 알파벳 소문자 또는 &quot;1&quot;로 이루어진 문자열입니다.</li>
</ul>
<h4 id="입출력-예">입출력 예</h4>
<table>
<thead>
<tr>
<th align="center">code</th>
<th align="center">result</th>
</tr>
</thead>
<tbody><tr>
<td align="center">&quot;abc1abc1abc&quot;</td>
<td align="center">&quot;acbac&quot;</td>
</tr>
<tr>
<td align="center">- 입출력 설명</td>
<td align="center"></td>
</tr>
<tr>
<td align="center"><img src="https://velog.velcdn.com/images/cham-chi/post/52d1ee78-8bf8-4039-a042-a88ca2e55883/image.png" alt=""></td>
<td align="center"></td>
</tr>
</tbody></table>
<h4 id="결과코드">결과코드</h4>
<pre><code class="language-java">class Solution {
    public String solution(String code) {
        String ret = &quot;&quot;;
        int mode = 0; 

        for (int idx = 0; idx &lt; code.length(); idx++) {
            char currentChar = code.charAt(idx);

            if (mode == 0) {
                if (currentChar != &#39;1&#39; &amp;&amp; idx % 2 == 0) {
                    ret += currentChar;
                } else if (currentChar == &#39;1&#39;) {
                    mode = 1;
                }
            } else {
                if (currentChar != &#39;1&#39; &amp;&amp; idx % 2 != 0) {
                    ret += currentChar;
                } else if (currentChar == &#39;1&#39;) {
                    mode = 0;
                }
            }
        }

        if (ret.equals(&quot;&quot;)) {
            return &quot;EMPTY&quot;;
        }

        return ret;
    }
}</code></pre>
<p>🗝️Point🗝️
문자열 <code>code</code>를 순회하며 조건에 따라 <code>mode</code>(0 또는 1)를 전환하고, 특정 조건에 맞는 문자만 결과 문자열 <code>ret</code>에 추가하는 방식으로 작성했다. 
<code>mode</code>와 <code>idx</code>의 짝/홀 여부를 활용해 조건을 구현했으며, 결과 문자열이 빈 경우 &quot;EMPTY&quot;를 반환하도록 처리했다. </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JAVA] 프로그래머스 코드 리뷰 - Level 0 (대소문자 바꿔서 출력하기)]]></title>
            <link>https://velog.io/@cham-chi/JAVA-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%BD%94%EB%93%9C-%EB%A6%AC%EB%B7%B0-Level-0-%EC%BD%9C%EB%9D%BC%EC%B8%A0-%EC%88%98%EC%97%B4-%EB%A7%8C%EB%93%A4%EA%B8%B0</link>
            <guid>https://velog.io/@cham-chi/JAVA-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%BD%94%EB%93%9C-%EB%A6%AC%EB%B7%B0-Level-0-%EC%BD%9C%EB%9D%BC%EC%B8%A0-%EC%88%98%EC%97%B4-%EB%A7%8C%EB%93%A4%EA%B8%B0</guid>
            <pubDate>Fri, 24 Jan 2025 14:58:17 GMT</pubDate>
            <description><![CDATA[<h1 id="대소문자-바꿔서-출력하기">대소문자 바꿔서 출력하기</h1>
<blockquote>
<h3 id="문제-설명">문제 설명</h3>
<p>영어 알파벳으로 이루어진 문자열 <code>str</code>이 주어집니다. 각 알파벳을 대문자는 소문자로 소문자는 대문자로 변환해서 출력하는 코드를 작성해 보세요.</p>
</blockquote>
<h4 id="제한사항">제한사항</h4>
<ul>
<li>1 ≤ <code>str</code>의 길이 ≤ 20
<code>str</code>은 알파벳으로 이루어진 문자열입니다.</li>
</ul>
<h4 id="입출력-예">입출력 예</h4>
<table>
<thead>
<tr>
<th align="center">입력</th>
<th align="center">출력</th>
</tr>
</thead>
<tbody><tr>
<td align="center">aBcDeFg</td>
<td align="center">AbCdEfG</td>
</tr>
</tbody></table>
<h4 id="결과코드">결과코드</h4>
<p><img src="https://velog.velcdn.com/images/cham-chi/post/a0b4ff17-aff8-47e8-86f7-11eafdc1165a/image.png" alt=""></p>
<pre><code class="language-java">import java.util.Scanner;

public class Solution {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String a = sc.next();


        String res = &quot;&quot;;
        for(int i = 0; i &lt; a.length(); i++){
            char x = a.charAt(i);
            if(Character.isUpperCase(x)){
                res += Character.toLowerCase(x);
            } else if(Character.isLowerCase(x)){
                res += Character.toUpperCase(x); 
            }
        }
        System.out.println(res);
    }
}</code></pre>
<p>🗝️Point🗝️
문자열을 하나씩 받아 <code>Upper</code>와 <code>Lower</code>로 대소문자를 바꾸는 것! </p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JAVA] 프로그래머스 코드 리뷰 - Level 0 (카운트 업)]]></title>
            <link>https://velog.io/@cham-chi/JAVA-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%BD%94%EB%93%9C-%EB%A6%AC%EB%B7%B0-Level-0-ltzlnbru</link>
            <guid>https://velog.io/@cham-chi/JAVA-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%BD%94%EB%93%9C-%EB%A6%AC%EB%B7%B0-Level-0-ltzlnbru</guid>
            <pubDate>Fri, 24 Jan 2025 14:41:09 GMT</pubDate>
            <description><![CDATA[<h1 id="카운트-업">카운트 업</h1>
<blockquote>
<h3 id="문제-설명">문제 설명</h3>
<p>정수 <code>start_num</code>와 <code>end_num</code>가 주어질 때, <code>start_num</code>부터 <code>end_num</code>까지의 숫자를 차례로 담은 리스트를 return하도록 solution 함수를 완성해주세요.</p>
</blockquote>
<h4 id="제한사항">제한사항</h4>
<ul>
<li>0 ≤ start_num ≤ end_num ≤ 50</li>
</ul>
<h4 id="입출력-예">입출력 예</h4>
<table>
<thead>
<tr>
<th align="center">start_num</th>
<th align="center">end_num</th>
<th align="center">result</th>
</tr>
</thead>
<tbody><tr>
<td align="center">3</td>
<td align="center">10</td>
<td align="center">[3, 4, 5, 6, 7, 8, 9, 10]</td>
</tr>
</tbody></table>
<h4 id="결과코드">결과코드</h4>
<p><img src="https://velog.velcdn.com/images/cham-chi/post/24f194aa-8f7a-4624-933c-72ee83ffa29e/image.png" alt=""></p>
<pre><code class="language-java">class Solution {
    public int[] solution(int start_num, int end_num) {
        int size = end_num - start_num + 1;
        int[] answer = new int[size];

        for (int i = 0; i &lt; size; i++) {
            answer[i] = start_num + i;
        }
        return answer;
    }
}</code></pre>
<p>🗝️Point🗝️
여기서 <code>int size = end_num - start_num + 1;</code>로 리스트의 사이즈를 잡아주었다.
리스트의 사이즈만큼 <code>answer</code>의 길이를 정해주고, <code>start_num</code>부터 리스트의 길이까지 1씩 더하여 리스트에 담았다.
<code>return IntStream.rangeClosed(start, end).toArray();</code> <code>Stream</code>함수를 써서 한 번에 한 풀이도 있는데 <code>Stream</code>은 감성으로 하는 걸로..</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JAVA] 프로그래머스 코드 리뷰 - Level 0 (콜라츠 수열 만들기)]]></title>
            <link>https://velog.io/@cham-chi/JAVA-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%BD%94%EB%93%9C-%EB%A6%AC%EB%B7%B0-Level-0-olximqsn</link>
            <guid>https://velog.io/@cham-chi/JAVA-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%BD%94%EB%93%9C-%EB%A6%AC%EB%B7%B0-Level-0-olximqsn</guid>
            <pubDate>Thu, 23 Jan 2025 14:32:11 GMT</pubDate>
            <description><![CDATA[<h1 id="콜라츠-수열-만들기">콜라츠 수열 만들기</h1>
<blockquote>
<h3 id="문제-설명">문제 설명</h3>
<p>모든 자연수 <code>x</code>에 대해서 현재 값이 <code>x</code>이면 <code>x</code>가 짝수일 때는 2로 나누고, <code>x</code>가 홀수일 때는 <code>3 * x + 1</code>로 바꾸는 계산을 계속해서 반복하면 언젠가는 반드시 <code>x</code>가 1이 되는지 묻는 문제를 콜라츠 문제라고 부릅니다.<br>
그리고 위 과정에서 거쳐간 모든 수를 기록한 수열을 콜라츠 수열이라고 부릅니다.<br>
계산 결과 1,000 보다 작거나 같은 수에 대해서는 전부 언젠가 1에 도달한다는 것이 알려져 있습니다.
임의의 1,000 보다 작거나 같은 양의 정수 <code>n</code>이 주어질 때 초기값이 <code>n</code>인 콜라츠 수열을 return 하는 solution 함수를 완성해 주세요.</p>
</blockquote>
<h4 id="제한사항">제한사항</h4>
<ul>
<li>1 ≤ n ≤ 1,000</li>
</ul>
<h4 id="입출력-예">입출력 예</h4>
<table>
<thead>
<tr>
<th align="center">n</th>
<th align="center">result</th>
</tr>
</thead>
<tbody><tr>
<td align="center">10</td>
<td align="center">[10, 5, 16, 8, 4, 2, 1]</td>
</tr>
</tbody></table>
<h4 id="결과코드">결과코드</h4>
<p><img src="https://velog.velcdn.com/images/cham-chi/post/013ac6e2-19ea-4a68-b0f2-09fea5f9bae0/image.png" alt=""></p>
<p>🗝️Point🗝️
<code>list</code>를 만들어서 조건에 맞는 연산식을 처리한 다음 값을 넣었다.
입력값 <code>n</code>이 1~1,000 범위 내에 있는지 검증하는 로직을 추가하지 않아 제출하고 뒤늦게 추가했다. 그리고 무한 루프<code>(for(;;))</code> 대신 <code>while</code>을 사용하여 가독성을 높이는 것도 좋을 것 같다.</p>
]]></description>
        </item>
    </channel>
</rss>