<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>im_tanukichoi.log</title>
        <link>https://velog.io/</link>
        <description>일단 해보자 뭐든 되겠지 😄</description>
        <lastBuildDate>Wed, 31 May 2023 09:25:39 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>im_tanukichoi.log</title>
            <url>https://velog.velcdn.com/images/tanuki_choi/profile/73ef20d7-c1ec-4474-aeb2-638bf9da131b/image.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. im_tanukichoi.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/tanuki_choi" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[프로그래머스 Lv.3] 입국심사]]></title>
            <link>https://velog.io/@tanuki_choi/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-Lv.3-%EC%9E%85%EA%B5%AD%EC%8B%AC%EC%82%AC</link>
            <guid>https://velog.io/@tanuki_choi/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-Lv.3-%EC%9E%85%EA%B5%AD%EC%8B%AC%EC%82%AC</guid>
            <pubDate>Wed, 31 May 2023 09:25:39 GMT</pubDate>
            <description><![CDATA[<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/43238">코딩테스트 연습 - 입국심사</a></p>
<h2 id="문제-설명">문제 설명</h2>
<p>n명이 입국심사를 위해 줄을 서서 기다리고 있습니다. 각 입국심사대에 있는 심사관마다 심사하는데 걸리는 시간은 다릅니다.</p>
<pre><code>처음에 모든 심사대는 비어있습니다. 
한 심사대에서는 동시에 한 명만 심사를 할 수 있습니다. 
가장 앞에 서 있는 사람은 비어 있는 심사대로 가서 심사를 받을 수 있습니다. 
하지만 더 빨리 끝나는 심사대가 있으면 기다렸다가 그곳으로 가서 심사를 받을 수도 있습니다.</code></pre><p>모든 사람이 심사를 받는데 걸리는 시간을 최소로 하고 싶습니다.</p>
<blockquote>
<p>입국심사를 기다리는 사람 수 n, 각 심사관이 한 명을 심사하는데 걸리는 시간이 담긴 배열 times가 매개변수로 주어질 때, 모든 사람이 심사를 받는데 걸리는 시간의 최솟값을 return 하도록 solution 함수를 작성해주세요.</p>
</blockquote>
<h3 id="제한사항">제한사항</h3>
<blockquote>
<ul>
<li>입국심사를 기다리는 사람은 1명 이상 1,000,000,000명 이하입니다.</li>
<li>각 심사관이 한 명을 심사하는데 걸리는 시간은 1분 이상 1,000,000,000분 이하입니다.</li>
<li>심사관은 1명 이상 100,000명 이하입니다.</li>
</ul>
</blockquote>
<h2 id="풀이">풀이</h2>
<ol>
<li><p>이분탐색. 변수 신경쓰기.</p>
<h3 id="결과">결과</h3>
<pre><code class="language-java">import java.util.*;
class Solution {
 static long answer = Long.MAX_VALUE;
 public long solution(int n, int[] times) {
     // 한 심사대에서는 동시에 한 명만 심사를 할 수 있습니다.
     // 가장 앞에 서 있는 사람은 비어 있는 심사대로 가서 심사를 받을 수 있습니다.
     // 하지만!!
     // 더 빨리 끝나는 심사대가 있으면, 기다렸다가 그곳으로 가서 심사를 받을 수도 있습니다.

     // 모든 사람이 심사를 받는데 걸리는 시간을 최소로 하고 싶습니다.

     // 파라메트릭 서치 - 매개변수 탐색

     Arrays.sort(times);

     long start = 0L;
     long end = (long) n * times[times.length-1];
     long mid = (start+end)/2;

     while(start &lt;= end){
         mid = (start+end)/2L;

         long check = 0L;
         for(int time: times){
             check += mid / time;
             if(check &gt;= n) break;
         }

         if(check &gt;= n){
             answer = Math.min(answer, mid);
             end = mid - 1L;
         }else{
             start = mid + 1L;
         }
     }

     return answer;
 }
}</code></pre>
</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스 Lv.3] 여행경로]]></title>
            <link>https://velog.io/@tanuki_choi/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-Lv.3-%EC%97%AC%ED%96%89%EA%B2%BD%EB%A1%9C</link>
            <guid>https://velog.io/@tanuki_choi/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-Lv.3-%EC%97%AC%ED%96%89%EA%B2%BD%EB%A1%9C</guid>
            <pubDate>Tue, 30 May 2023 19:34:59 GMT</pubDate>
            <description><![CDATA[<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/43164">코딩테스트 연습 - 여행경로</a></p>
<h2 id="문제-설명">문제 설명</h2>
<p>주어진 항공권을 모두 이용하여 여행경로를 짜려고 합니다. 
항상 &quot;ICN&quot; 공항에서 출발합니다.</p>
<blockquote>
<p>항공권 정보가 담긴 2차원 배열 tickets가 매개변수로 주어질 때, 방문하는 공항 경로를 배열에 담아 return 하도록 solution 함수를 작성해주세요.</p>
</blockquote>
<h3 id="제한사항">제한사항</h3>
<blockquote>
<ul>
<li>모든 공항은 알파벳 대문자 3글자로 이루어집니다.</li>
<li>주어진 공항 수는 3개 이상 10,000개 이하입니다.</li>
<li>tickets의 각 행 [a, b]는 a 공항에서 b 공항으로 가는 항공권이 있다는 의미입니다.</li>
<li>주어진 항공권은 모두 사용해야 합니다.</li>
<li>만일 가능한 경로가 2개 이상일 경우 알파벳 순서가 앞서는 경로를 return 합니다.</li>
<li>모든 도시를 방문할 수 없는 경우는 주어지지 않습니다.</li>
</ul>
</blockquote>
<h2 id="풀이">풀이</h2>
<ol>
<li>dfs를 이용해서 순열로 풀기.<h3 id="결과">결과</h3>
<pre><code class="language-java">import java.util.*;
</code></pre>
</li>
</ol>
<p>class Solution {
    static int[][] route;
    static List<String> list = new ArrayList&lt;&gt;();</p>
<pre><code>static int N;
static List&lt;String&gt; result = new ArrayList&lt;&gt;();

static List&lt;List&lt;String&gt;&gt; perm = new ArrayList&lt;&gt;();
static String[] answer = {};

public String[] solution(String[][] tickets) {

    // 출발지 고정 : ICN(0)

    // 방향 그래프, 완전 탐색
    // bfs, dfs 둘다 상관없을 듯?

    // 공항 갯수 구하기
    list.add(&quot;ICN&quot;); // ICN은 무조건 0번에서 시작.
    for(String[] ticket : tickets){
        if(!list.contains(ticket[0])) list.add(ticket[0]);
        if(!list.contains(ticket[1])) list.add(ticket[1]);
    }
    Collections.sort(list);      

    // 공항 경로 저장.
    N = list.size();
    route = new int[N][N];
    for(int i = 0; i &lt; tickets.length; i++){
        String start = tickets[i][0];
        String end = tickets[i][1];

        int x = list.indexOf(start);
        int y = list.indexOf(end);

        route[x][y] += 1;
    }

    for(int i = 0; i &lt; route.length; i++){
        int[] r = route[i];
    }

    int now = list.indexOf(&quot;ICN&quot;);
    result.add(&quot;ICN&quot;);
    dfs(0, now, tickets);

    answer = perm.get(0).toArray(new String[perm.get(0).size()]);

    return answer;
}

private void dfs(int depth, int now, String[][] tickets){
    if(depth == tickets.length){
        List&lt;String&gt; li = new ArrayList&lt;&gt;();
        for(String str: result){
            li.add(str);
        }
        perm.add(li);
        return;
    }
    for(int i = 0; i &lt; N; i++){
        if(route[now][i] &gt; 0){
            route[now][i] -= 1;
            result.add(list.get(i));
            dfs(depth+1, i, tickets);
            route[now][i] += 1;
            result.remove(result.size()-1);
        }
    }        
}</code></pre><p>}</p>
<pre><code></code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스 Lv.3] 단어 변환]]></title>
            <link>https://velog.io/@tanuki_choi/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-Lv.3-%EB%8B%A8%EC%96%B4-%EB%B3%80%ED%99%98</link>
            <guid>https://velog.io/@tanuki_choi/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-Lv.3-%EB%8B%A8%EC%96%B4-%EB%B3%80%ED%99%98</guid>
            <pubDate>Tue, 30 May 2023 17:21:56 GMT</pubDate>
            <description><![CDATA[<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/43163">코딩테스트 연습 - 단어 변환</a></p>
<h2 id="문제-설명">문제 설명</h2>
<p>두 개의 단어 begin, target과 단어의 집합 words가 있습니다. 아래와 같은 규칙을 이용하여 begin에서 target으로 변환하는 가장 짧은 변환 과정을 찾으려고 합니다.</p>
<ol>
<li>한 번에 한 개의 알파벳만 바꿀 수 있습니다.</li>
<li>words에 있는 단어로만 변환할 수 있습니다.</li>
</ol>
<pre><code>예를 들어 
begin이 &quot;hit&quot;, target가 &quot;cog&quot;, words가 
[&quot;hot&quot;,&quot;dot&quot;,&quot;dog&quot;,&quot;lot&quot;,&quot;log&quot;,&quot;cog&quot;]라면 
&quot;hit&quot; -&gt; &quot;hot&quot; -&gt; &quot;dot&quot; -&gt; &quot;dog&quot; -&gt; &quot;cog&quot;와 같이 4단계를 거쳐 변환할 수 있습니다.</code></pre><blockquote>
<p>두 개의 단어 begin, target과 단어의 집합 words가 매개변수로 주어질 때, 최소 몇 단계의 과정을 거쳐 begin을 target으로 변환할 수 있는지 return 하도록 solution 함수를 작성해주세요.</p>
</blockquote>
<h3 id="제한사항">제한사항</h3>
<blockquote>
<ul>
<li>각 단어는 알파벳 소문자로만 이루어져 있습니다.</li>
<li>각 단어의 길이는 3 이상 10 이하이며 모든 단어의 길이는 같습니다.</li>
<li>words에는 3개 이상 50개 이하의 단어가 있으며 중복되는 단어는 없습니다.</li>
<li>begin과 target은 같지 않습니다.</li>
<li>변환할 수 없는 경우에는 0를 return 합니다.</li>
</ul>
</blockquote>
<h2 id="풀이">풀이</h2>
<ol>
<li><p>bfs로 풀었으며, queue 이용, 최소값 구하는 문제</p>
<h3 id="결과">결과</h3>
<pre><code class="language-java">import java.util.*;
class Alpha{
 String word;
 int d;

 Alpha(String word, int d){
     this.word = word;
     this.d = d;
 }
}
class Solution {
 static int answer = 0;
 static boolean[] checked;
 public int solution(String begin, String target, String[] words) {

     // 한 번에 한 개의 알파벳만 바꿀 수 있습니다.

     // 최소 몇 단계의 과정을 거쳐 begin을 target으로 변환할 수 있는지
     // 최단 거리 같기도 하고? 일단 bfs로 풀어봄.

     // words에 있는 단어로만 변환할 수 있습니다.
     if(!Arrays.asList(words).contains(target)) return answer;

     checked = new boolean[words.length];
     for(int i = 0; i &lt; words.length; i++){
         if(begin.equals(words[i])) checked[i] = true;
     }

     bfs(begin, target, words);

</code></pre>
</li>
</ol>
<pre><code>    return answer;
}

private void bfs(String begin, String target, String[] words){
    Queue&lt;Alpha&gt; que = new LinkedList&lt;&gt;();
    que.offer(new Alpha(begin, 0));

    while(!que.isEmpty()){
        Alpha ap = que.poll();

        if(ap.word.equals(target)){
            answer = ap.d;
            return;
        }

        for(int i = 0; i &lt; words.length; i++){
            String wd = words[i];

            char[] wdrr = wd.toCharArray();
            char[] aprr = ap.word.toCharArray();
            int cnt = 0;
            for(int j = 0; j &lt; wd.length(); j++){
                if(wdrr[j] == aprr[j]) cnt++;
            }

            if(cnt == wd.length()-1 &amp;&amp; !checked[i]){
                checked[i] = true;
                que.offer(new Alpha(wd, ap.d+1));
            }
        }
    }  
}</code></pre><p>}
```</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스 Lv.3] 네트워크]]></title>
            <link>https://velog.io/@tanuki_choi/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-Lv.3-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC</link>
            <guid>https://velog.io/@tanuki_choi/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-Lv.3-%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC</guid>
            <pubDate>Tue, 30 May 2023 15:56:37 GMT</pubDate>
            <description><![CDATA[<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/43162">코딩테스트 연습 - 네트워크</a></p>
<h2 id="문제-설명">문제 설명</h2>
<p>네트워크란 컴퓨터 상호 간에 정보를 교환할 수 있도록 연결된 형태를 의미합니다. </p>
<pre><code>예를 들어, 

컴퓨터 A와 컴퓨터 B가 직접적으로 연결되어있고, 
컴퓨터 B와 컴퓨터 C가 직접적으로 연결되어 있을 때 
컴퓨터 A와 컴퓨터 C도 간접적으로 연결되어 정보를 교환할 수 있습니다. 

따라서 컴퓨터 A, B, C는 모두 같은 네트워크 상에 있다고 할 수 있습니다.</code></pre><blockquote>
<p>컴퓨터의 개수 n, 연결에 대한 정보가 담긴 2차원 배열 computers가 매개변수로 주어질 때, 네트워크의 개수를 return 하도록 solution 함수를 작성하시오.</p>
</blockquote>
<h3 id="제한사항">제한사항</h3>
<blockquote>
<ul>
<li>컴퓨터의 개수 n은 1 이상 200 이하인 자연수입니다.</li>
<li>각 컴퓨터는 0부터 n-1인 정수로 표현합니다.</li>
<li>i번 컴퓨터와 j번 컴퓨터가 연결되어 있으면 computers[i][j]를 1로 표현합니다.</li>
<li>computer[i][i]는 항상 1입니다.</li>
</ul>
</blockquote>
<h2 id="풀이">풀이</h2>
<ol>
<li>dfs로 풀이하였으며, 연결요소의 갯수를 구하는 문제<h3 id="결과">결과</h3>
<pre><code class="language-java">import java.util.*;
</code></pre>
</li>
</ol>
<p>class Solution {
    static int[][] network;
    static boolean[] checked;
    static int answer = 0;</p>
<pre><code>public int solution(int n, int[][] computers) {
    // 컴퓨터 개수 n
    // 연결에 대한 정보 배열 computers
    // 네트워크의 개수(연결요소의 갯수) answer
    // 양방향 통신
    // i번과 j번 컴퓨터가 연결 되어 있으면 1, 아니면 0
    network = new int[n][n];

    for(int i = 0; i &lt; n; i++){
        for(int j = 0; j &lt; n; j++){
            if(computers[i][j] == 1 &amp;&amp; i!=j) network[i][j] = 1;
        }
    }

    checked = new boolean[n]; 
    for(int i = 0; i &lt; n; i++){
        if(!checked[i]){
            answer++;
            checked[i] = true;
            dfs(n,i);
        }
    }        
    return answer;
}

static void dfs(int n, int now){
    for(int j = 0; j &lt; n; j++){
        if(network[now][j] == 1 &amp;&amp; !checked[j]){
            checked[j] = true;
            dfs(n, j);
        }
    }
}</code></pre><p>}
```</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스 Lv.2] 연속된 부분 수열의 합]]></title>
            <link>https://velog.io/@tanuki_choi/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-Lv.2-%EC%97%B0%EC%86%8D%EB%90%9C-%EB%B6%80%EB%B6%84-%EC%88%98%EC%97%B4%EC%9D%98-%ED%95%A9</link>
            <guid>https://velog.io/@tanuki_choi/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-Lv.2-%EC%97%B0%EC%86%8D%EB%90%9C-%EB%B6%80%EB%B6%84-%EC%88%98%EC%97%B4%EC%9D%98-%ED%95%A9</guid>
            <pubDate>Tue, 23 May 2023 04:08:24 GMT</pubDate>
            <description><![CDATA[<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/178870">코딩테스트 연습 - 연속된 부분 수열의 합</a></p>
<h2 id="문제-설명">문제 설명</h2>
<p>비내림차순(<code>올림차순</code>)으로 정렬된 수열이 주어질 때, 다음 조건을 만족하는 부분 수열을 찾으려고 합니다.</p>
<ul>
<li>기존 수열에서 임의의 두 인덱스의 원소와 그 사이의 원소를 모두 포함하는 부분 수열이어야 합니다.</li>
<li>부분 수열의 합은 k입니다.</li>
<li>합이 k인 부분 수열이 여러 개인 경우 길이가 짧은 수열을 찾습니다.</li>
<li>길이가 짧은 수열이 여러 개인 경우 앞쪽(시작 인덱스가 작은)에 나오는 수열을 찾습니다.</li>
</ul>
<blockquote>
<p>수열을 나타내는 정수 배열 sequence와 부분 수열의 합을 나타내는 정수 k가 매개변수로 주어질 때, 위 조건을 만족하는 부분 수열의 시작 인덱스와 마지막 인덱스를 배열에 담아 return 하는 solution 함수를 완성해주세요. 이때 수열의 인덱스는 0부터 시작합니다.</p>
</blockquote>
<h3 id="제한사항">제한사항</h3>
<blockquote>
<ul>
<li>5 ≤ sequence의 길이 ≤ 1,000,000<ul>
<li>1 ≤ sequence의 원소 ≤ 1,000</li>
<li>sequence는 비내림차순으로 정렬되어 있습니다.</li>
</ul>
</li>
<li>5 ≤ k ≤ 1,000,000,000<ul>
<li>k는 항상 sequence의 부분 수열로 만들 수 있는 값입니다.</li>
</ul>
</li>
</ul>
</blockquote>
<h2 id="풀이">풀이</h2>
<h3 id="결과">결과</h3>
<pre><code class="language-java">import java.util.*;
class Indexes implements Comparable&lt;Indexes&gt;{
    int left;
    int right;
    int size;

    public Indexes(int left, int right){
        this.left = left;
        this.right = right;
        this.size = right-left;
    }

    @Override
    public int compareTo(Indexes o) {
        if(this.size == o.size){
            return this.left - o.left;
        }
        return this.size - o.size;
    }
}
class Solution {
    public int[] solution(int[] sequence, int k) {
        int[] answer = new int[2];
        List&lt;Indexes&gt; list = new ArrayList&lt;&gt;();

        int left = 0;
        int right = 0;
        int sum = sequence[0];
        int n = sequence.length;

        while(true){
            if(sum == k){
                list.add(new Indexes(left, right));
            }
            if(left == n &amp;&amp; right == n) break;

            if(sum &lt;= k &amp;&amp; right &lt; n){
                right++;
                if(right &lt; n) sum += sequence[right];
            }else {
                if(left &lt; n) sum -= sequence[left];
                left++;
            }      
        }

        Collections.sort(list, (x,y)-&gt;x.compareTo(y));

        answer[0] = list.get(0).left;
        answer[1] = list.get(0).right;


        return answer;
    }
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스 Lv.2] 택배상자]]></title>
            <link>https://velog.io/@tanuki_choi/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-Lv.2-%ED%83%9D%EB%B0%B0%EC%83%81%EC%9E%90</link>
            <guid>https://velog.io/@tanuki_choi/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-Lv.2-%ED%83%9D%EB%B0%B0%EC%83%81%EC%9E%90</guid>
            <pubDate>Tue, 23 May 2023 02:17:13 GMT</pubDate>
            <description><![CDATA[<p><a href="">코딩테스트 연습 - </a></p>
<h2 id="문제-설명">문제 설명</h2>
<p>영재는 택배상자를 트럭에 싣는 일을 합니다. 
영재가 실어야 하는 택배상자는 크기가 모두 같으며 <code>1번 상자부터 n번 상자까지 번호가 증가하는 순서대로 컨테이너 벨트에 일렬</code>로 놓여 영재에게 전달됩니다. </p>
<p>컨테이너 벨트는 한 방향으로만 진행이 가능해서 벨트에 놓인 순서대로(1번 상자부터) 상자를 내릴 수 있습니다. 하지만 컨테이너 벨트에 놓인 순서대로 택배상자를 내려 바로 트럭에 싣게 되면 택배 기사님이 배달하는 순서와 택배상자가 실려 있는 순서가 맞지 않아 배달에 차질이 생깁니다. 
<code>따라서 택배 기사님이 미리 알려준 순서에 맞게 영재가 택배상자를 실어야 합니다.</code></p>
<p>만약 컨테이너 벨트의 맨 앞에 놓인 상자가 현재 트럭에 실어야 하는 순서가 아니라면 그 상자를 트럭에 실을 순서가 될 때까지 잠시 다른 곳에 보관해야 합니다. 
하지만 고객의 물건을 함부로 땅에 둘 수 없어 보조 컨테이너 벨트를 추가로 설치하였습니다. 
보조 컨테이너 벨트는 앞 뒤로 이동이 가능하지만 입구 외에 다른 면이 막혀 있어서 맨 앞의 상자만 뺄 수 있습니다(<code>즉, 가장 마지막에 보조 컨테이너 벨트에 보관한 상자부터 꺼내게 됩니다</code>).
보조 컨테이너 벨트를 이용해도 기사님이 원하는 순서대로 상자를 싣지 못 한다면, 더 이상 상자를 싣지 않습니다.</p>
<pre><code>예를 들어, 
영재가 5개의 상자를 실어야 하며, 택배 기사님이 알려준 순서가 
기존의 컨테이너 벨트에 네 번째, 세 번째, 첫 번째, 두 번째, 다섯 번째 놓인 택배상자 순서인 경우, 

영재는 우선 첫 번째, 두 번째, 세 번째 상자를 보조 컨테이너 벨트에 보관합니다. 
그 후 네 번째 상자를 트럭에 싣고 보조 컨테이너 벨트에서 세 번째 상자 빼서 트럭에싣습니다. 
다음으로 첫 번째 상자를 실어야 하지만 보조 컨테이너 벨트에서는 두 번째 상자를, 
기존의 컨테이너 벨트에는 다섯 번째 상자를 꺼낼 수 있기 때문에 더이상의 상자는 실을 수 없습니다. 

따라서 트럭에는 2개의 상자만 실리게 됩니다.</code></pre><blockquote>
<p>택배 기사님이 원하는 상자 순서를 나타내는 정수 배열 order가 주어졌을 때, 영재가 몇 개의 상자를 실을 수 있는지 return 하는 solution 함수를 완성하세요.</p>
</blockquote>
<h3 id="제한사항">제한사항</h3>
<blockquote>
<ul>
<li>1 ≤ order의 길이 ≤ 1,000,000</li>
<li>order는 1이상 order의 길이 이하의 모든 정수가 한번씩 등장합니다.</li>
<li>order[i]는 기존의 컨테이너 벨트에 order[i]번째 상자를 i+1번째로 트럭에 실어야 함을 의미합니다.</li>
</ul>
</blockquote>
<h2 id="풀이">풀이</h2>
<h3 id="결과">결과</h3>
<pre><code class="language-java">import java.util.*;
class Solution {
    public int solution(int[] order) {
        int answer = 0;
        Stack&lt;Integer&gt; subBalt = new Stack&lt;&gt;();

        int idx = 0;
        for(int i = 1; i &lt;= order.length; i++){
            boolean flag = false;
            // 순서와 상자가 일치하는 경우
            if(order[idx] == i){
                answer++;
                idx++;
                flag = true;
            }
            // 보조 컨테이너 벨트가 비어있지 않고,
            // 마지막 상자가 순서에 일치하는 경우
            while(!subBalt.isEmpty() &amp;&amp; subBalt.peek() == order[idx]){
                subBalt.pop();
                idx++;
                answer++;
                flag = true;
            }

            //보조 컨테이너 벨트에 적재
            if(!flag){
                subBalt.add(i);
            }
        }

        while(!subBalt.isEmpty() &amp;&amp; subBalt.peek() == order[idx]){
            subBalt.pop();
            idx++;
            answer++;
        }
        return answer;
    }
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[기술면접 (Spring)]]></title>
            <link>https://velog.io/@tanuki_choi/%EA%B8%B0%EC%88%A0%EB%A9%B4%EC%A0%91-Spring</link>
            <guid>https://velog.io/@tanuki_choi/%EA%B8%B0%EC%88%A0%EB%A9%B4%EC%A0%91-Spring</guid>
            <pubDate>Wed, 10 May 2023 19:45:18 GMT</pubDate>
            <description><![CDATA[<h3 id="💡wasweb-application-server와-wsweb-server의-차이를-설명해주세요">💡WAS(Web Application Server)와 WS(Web Server)의 차이를 설명해주세요.</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
웹서버는 정적인 데이터를 처리하는 서버입니다. 이미지나 단순 html 같은 정적인 리소스들을 전달하며 WAS만을 이용할 경우보다 빠르고 안정적으로 기능을 수행합니다.
WAS는 동적인 데이터를 위주로 처리하는 서버입니다. DB와 연결되어 사용자와 데이터를 주고받고 조작이 필요한 경우 WAS를 활용합니다.
</span>

<h3 id="💡spring-framework에-대해-설명해주세요">💡Spring Framework에 대해 설명해주세요.</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
스프링 프레임원크는 자바 개발을 편리하게 해주는 오픈소스 프레임워크 입니다.
1.경량 컨테이너로서 자바 객체를 직접관리하며, 2.제어의 역전(IoC)이라는 기술을 통해 어플리케션의 느슨한 결합을 도모합니다. 또한, 3.의존성주입(DI)을 지원하고, 4.관점 지향 프로그래밍(AOP)을 지원합니다.
</span>

<pre><code>1. 각각의 객체 생성, 소멸과 같은 라이프 사이클을 관리하며 스프링으로부터 필요한 객체를 얻어올 수 있다.
2. 컨트롤의 제어권이 사용자가 아닌 프레임워크에 있어서 필요에 다라 스프링에서 사용자의 코드를 호출한다.
3. 각각의 계층이나 서비스들 간에 의존성이 존재할 경우 프레임워크가 서로 연결시켜준다.
4. 트랜잭션이나 로깅, 보안과 같이 여러 모듈에서 공통적으로 사용하는 기능의 경우 해당 기능을 분리하여 관리할 수 있다.</code></pre><h3 id="💡⭐spring-filter와-interceptor에-대해-설명하고-사용-예시를-설명해주세요">💡⭐Spring Filter와 Interceptor에 대해 설명하고, 사용 예시를 설명해주세요.</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
필터는 톰캣과 같은 웹컨테이너에 의해 관리가 되며, Dispatcher Servlet에 요청이 전달되기 전/후에 url 패턴에 맞는 모든 요청에 대해 부가작업을 처리 할 수 있는 기능을 제공합니다.
인터셉터는 스프링 컨텍스트에서 동작하며, Dispatcher Servlet이 controller를 호출하기 전/후에 인터셉터가 끼어들어 요청과 응답을 참조하거나 가공할 수 있는 기능을 제공
</span>

<pre><code>필터는 요청과 응답을 거른 뒤 정제하는 역할을 합니다.
필터 사용 사례 :
* 보안 및 인증/인가 관련 작업
* 모든 요청에 대한 로깅 또는 검사
* 이미지/데이터 압축 및 문자열 인코딩
* Spring과 분리되어야 하는 기능
인터셉터를 요청에 대한 작업 전/후로 가로채 요청과 응답을 참조하거나 가공하는 역할을 합니다.
인터셉터 사용 사례 :
* 세부적인 보안 및 인증/인가 공통 작업
* API 호출에 대한 로깅 또는 검사
* Controller로 넘겨주는 정보(데이터)의 가공</code></pre><h3 id="💡⭐spring-webflux에-대해-설명해주세요">💡⭐Spring WebFlux에 대해 설명해주세요.</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
리액티브 프로그래밍을 통해 비동기 데이터 스트림으로 Non-Blocking 애플리케이션을 개발하기 위한 Spring WebFlux 프레임워크
</span>

<h3 id="💡⭐관점지향-프로그래밍aop-aspect-oriented-programming는-무엇이고-언제-사용할-수-있을까요">💡⭐관점지향 프로그래밍(AOP, Aspect Oriented Programming)는 무엇이고, 언제 사용할 수 있을까요?</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
AOP는 핵심 비즈니스 로직에 있는 공통 관심사를 분리하여 각각 모듈화하는 것을 의미하며, 인증,로깅, 트랜잭션 처리에 용이합니다. 
가장 큰 특징은 중복 코드 제거, 재활용성의 극대화, 변화수용의 용이성이 좋다는 점입니다.
</span>

<h3 id="💡⭐의존성-주입di-dependency-injection에-대해-설명해주세요">💡⭐의존성 주입(DI, Dependency Injection)에 대해 설명해주세요.</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
의존성 주입은 필요한 객체를 직접 생성하는 것이 아닌 외부로부터 객체를 받아서 사용하는 것입니다.
생성자주입, 필드주입, 세터주입의 3가지 방법이 있으며, Spring에서 권장하는 방법은 생성자를 통한 주입이며, 그 이유는 순환참조 방지, 불변성을 가짐, 테스트에 용이하기 때문입니다. 
</span>

<h3 id="💡requestbody-requestparam-modelattribute의-차이를-설명해주세요">💡@RequestBody, @RequestParam, @ModelAttribute의 차이를 설명해주세요.</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
@RequestBody 는 클라이언트가 전송하는 JSON 형태의 HTTP Body 내용을 MessageConverter를 통해 Java Object로 변환시켜주는 역할을 하고, 값을 주입하지 않고 값을 변환 시키므로(Reflection을 사용해 할당), 변수들의 생성자, Getter,Setter가 없어도 정상적으로 할당된다.
@RequestParam 은 1개의 HTTP 요청 파라미터를 받기 위해 사용합니다. @RequestParam은 필수 여부가 true이기 때문에, 기본적으로 반드시 해당 파라미터가 전송되어야 합니다. 전송되지 않으면 400Error를 유발할 수 있으며, 반드시 필요한 변수가 아니라면 required의 값을 false로 설정해줘야 합니다.
@ModelAttribute 는 HTTP Body 내용과 HTTP 파라미터의 값들을 생성자,Getter,Setter를 통해 주입하기 위해 사용합니다. 값 변환이 아닌 값을 주입시키므로 변수들의 생성자나 Getter,Setter가 없으면 변수들이 저장되지 않는다.
</span>

<h3 id="💡spring-boot와-spring-framework의-차이점을-설명해주세요">💡Spring Boot와 Spring Framework의 차이점을 설명해주세요.</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
가장 큰 차이점은 Auto Configuration의 차이인 것 같습니다. Spring은 프로젝트 초기에 다양한 환경설정을 해야 하지만, Spring Boot는 설정의 많은 부분을 자동화하여 사용자가 편하게 스프링을 활용할 수 있도록 돕습니다. spring boot starter dependency만 추가해 주면 설정은 끝나고, 내장된 톰캣을 제공해 서버를 바로 실행할 수 있습니다.
</span>

<h3 id="💡spring-mvc에-대해-설명해주세요">💡Spring MVC에 대해 설명해주세요.</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
Model, View, Controller의 약자이며, 레이어간 기능을 구분하는데 중점을 둔 디자인패턴입니다.<br>
Model은 데이터 관리 및 비즈니스 로직을 처리하는 부분이며, View는 비즈니스 로직의 처리 결과를 통해 유저 인터페이스가 표현되는 구간입니다. Controller는 사용자의 요청을 처리하고 모델과 뷰를 중개하는 역할을 합니다.
</span>

<pre><code>Model: DAO, DTO, Service 등
View: html, jsp, tymeleaf, mustache 등 화면을 구성하기도 하고, Rest API로 서버가 구현된다면 json 응답으로 구성되기도 한다.
Controller: Model과 View는 서로 연결되어 있지 않기 때문에 Controller가 사이에서 통신 매체가 되어줍니다.</code></pre><h3 id="💡mvc는-어떠한-흐름으로-요청을-처리하는지-설명해주세요">💡MVC는 어떠한 흐름으로 요청을 처리하는지 설명해주세요.</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
먼저, 1.클라이언트는 url을 통해 요청을 전송하고, 2.디스패처 서블릿은 핸들러 매핑을 통해 해당 요청이 어느 컨트롤러에게 온 요청인지 찾고, 핸들러 어댑터에게 요청의 전달을 맡깁니다. 4.핸들러 어댑터는 해당 컨트롤러에 요청을 전달합니다. 5.컨트롤러는 비즈니스 로직을 처리한 후에 반환할 뷰의 이름을 반환하며, 디스패처 서블릿은 6.뷰 리졸버를 통해 반환할 뷰를 찾고, 7.컨트롤러에서 뷰에게 전달한 데이터를 추가합니다. 마지막으로, 8.데이터가 추가된 뷰를 반환합니다.
</span>

<h3 id="💡dispatcherservlet-handlermapping-handleradapter-viewresolver에-대해-설명해주세요">💡DispatcherServlet, HandlerMapping, HandlerAdapter, ViewResolver에 대해 설명해주세요.</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
DispatcherServlet는 클라이언트에게 요청을 받아 응답까지의 MVC 처리과정을 통제하는 것이며, HandlerMapping은 클라이언트의 요청 URL을 어떤 Controller가 처리할지 결정하는 것이다.
HandlerAdapter는 HandlerMapping에서 결정된 핸들러 정보로 해당 메소드를 직접 호출해주는 역할을 하며, ViewResolver는 Controller의 처리 결과(데이터)를 생성할 view를 결정합니다.

</span>

<h3 id="💡제어의-역전ioc-inversion-of-control에-대해-아는대로-설명해주세요">💡제어의 역전(IoC, Inversion of Control)에 대해 아는대로 설명해주세요.</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
제어의 역전은 모든 객체에 대한 제어권을 개발자가 아닌 IoC 컨테이너에게 넘긴 것을 말합니다.
스프링에서는 IoC 컨테이너에 객체들을 생성하면 의존성을 주입하는 역할을 하고 컨테이너에 등록한 객체들을 빈 이라고 합니다.
</span>

<pre><code>DI-Dependency Injection, IoC-Inversion of Control</code></pre><h3 id="💡ioc-컨테이너에-대해-설명해주세요">💡IoC 컨테이너에 대해 설명해주세요.</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
인스턴스 생성부터 소멸까지의 인스턴스 생명주기 관리를 개발자가 아닌 컨테이너가 대신 해줍니다.
객체관리 주체가 프레임워크(Container)가 되기 때문에 개발자는 로직에 집중할 수 있는 장점이 있습니다.
</span>

<pre><code>* POJO(Plain Old Java Object)란? 
주로 특정 자바 모델이나 기능, 프레임워크를 따르지 않는 Java Object를 지칭한다.
Java Bean 객체가 대표적이다.
간단하게 getter / setter를 생각하면 될 것 같다.</code></pre><h3 id="💡스프링에서-빈bean을-등록하는-방법에-대해-말해보세요">💡스프링에서 빈(Bean)을 등록하는 방법에 대해 말해보세요.</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
빈을 등록하는 방법은 두가지가 있는데 하나는
1. 컴포넌트 스캔과 자동 의존관계 설정하는 것이고, @Component 어노테이션을 사용하는 것입니다. 이는 @Controller, @Service, @Repository는 모두 @Component를 포함하고 있습니다.
2. 자바 코드로 직접 스프링 빈 등록하는 것이고, 설정 클래스를 따로 만들어 @Configuration 어노테이션을 붙이고, 해당 클래스 안에서 빈으로 등록할 메소드를 만들어 @Bean 어노테이션을 붙여주면 자동으로 해당 타입의 빈 객체가 생성됩니다.
</span>

<h3 id="💡스프링-빈의-라이프사이클은-어떻게-관리되는지-설명해주세요">💡스프링 빈의 라이프사이클은 어떻게 관리되는지 설명해주세요.</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
먼저 스프링 Bean의 LifeCycle은 스프링 IoC 컨테이너 생성하고, 스프링 빈 생성, 의존관계 주입합니다. 초기화 콜백 메소드 호출하여 사용하고 소멸전에 콜백 메소드를 호출하며 종료합니다.
<br>
3가지 방법으로 빈 생명주기 콜백을 관리합니다.
먼저, 1.인터페이스, 2.설정정보에 초기화 메소드, 종료 메소드 지정, 3.@PostConstruct, @PreDestroy 어노테이션 지원
</span>

<h3 id="💡lombok-라이브러리에-대해-알고-있나요-알고-있다면-롬복이-만드는-메소드들이-생성되는-시점은-언제인가요">💡Lombok 라이브러리에 대해 알고 있나요? 알고 있다면 롬복이 만드는 메소드들이 생성되는 시점은 언제인가요?</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
롬복은 메소드를 컴파일하는 과정에 개입해서 추가적인 코드를 만들어냅니다.
어노테이션 프로세싱은 자바 컴파일러가 컴파일단계에서 어노테이션을 분석하고 처리하는 기법을 말합니다.
</span>

<pre><code>Lombok 라이브러리를 추가할 때 CompileOnly, AnnotationProcessor를 추가하는 이유도 된다.</code></pre><h3 id="💡-서블릿servlet에-대해-설명해주세요">💡 서블릿(Servlet)에 대해 설명해주세요.</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
클라이언트의 요청을 처리하고, 그 결과를 반환하는 Servlet 클래스의 구현 규칙을 지킨 자바 웹 프로그래밍 기술 입니다. 스프링 mvc에서 컨트롤러로 이용되며, 사용자의 요청을 받아 처리한 후에 결과를 반환합니다.
</span>

<h3 id="💡서블릿의-동작-방식에-대해-설명해주세요">💡서블릿의 동작 방식에 대해 설명해주세요.</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
1.사용자가 url을 입력하면 http Request가 서블릿 컨테이너로 전송됩니다.<br>
2.요청 받은 서블릿 컨테이너는 HttpServletRequest, HttpServletResponse 객체를 생성합니다.<br>
3.web.xml을 기반으로 사용자가 요청한 url이 어느 서블릿에 대한 요청인지 찾습니다.<br>
4.해당 서블릿에서 service메소드를 호출한 후 get,post여부에 따라 doGet() 또는 doPost()를 호출합니다.<br>
5.응답이 끝나면 HttpServletRequest, HttpServletResponse 객체를 소멸시킵니다.
</span>

<h3 id="💡vo와-bo-dao-dto에-대해-설명해주세요">💡VO와 BO, DAO, DTO에 대해 설명해주세요.</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
DAO는 DB의 데이터에 접근을 위한 객체를 말하고, Repository 또는 Mapper에 해당됩니다.<br>
BO는 여러 DAO를 활용해 비즈니스 로직을 처리하는 객체를 말하고, Service에 해당됩니다.<br>
DTO는 각 계층간의 데이터 교환을 위한 객체를 말합니다. (여기서 말하는 계층은 Controller, View, Business Layer, Persistent Layer)<br>
VO는 실제 데이터만을 저장하는 객체를 말합니다.
</span>

<pre><code>DAO-Data Access Object, BO-Business Object, 
DTO-Data Transfer Object, DTO-Data Transfer Object,
VO-Value Object</code></pre><h3 id="💡-대용량-트래픽에서-장애가-발생하면-어떻게-대응할-것인가요">💡 대용량 트래픽에서 장애가 발생하면 어떻게 대응할 것인가요?</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
스케일 업을 통해 하드웨어 스펙을 향상거나 스케일 아웃을 통해 서버를 여러대 추가해 시스템을 증가합니다.
</span>

<h3 id="💡spring의-싱글톤-패턴에-대해-설명해주세요">💡Spring의 싱글톤 패턴에 대해 설명해주세요.</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
스프링에서 bean 생성시 별다른 설정이 없으면 default로 싱글톤이 적용됩니다.
<br>스프링은 컨테이너를 통해 직접 싱글톤 객체를 생성하고 관리하는데,
요청이 들어올 때마다 매번 객체를 생성하지 않고, 이미 만들어진 객체를 공유하기 때문에 효율적인 사용이 가능합니다.
<br>
이를 통해 static 메소드나 private 생성자 등을 사용하지 않아 객체지향적 개발을 할 수 있으며,테스트하기 편리하다.
</span>

<h3 id="💡-spring의-스코프-프로토-타입-빈에-대해-설명해주세요">💡 Spring의 스코프 프로토 타입 빈에 대해 설명해주세요.</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
프로토타입 빈은 싱글톤(default bean) 빈과는 달리 컨테이너에게 빈을 요청할 때마다 매번 새로운 객체를 생성하여 반환해줍니다.
</span>

<h3 id="💡transactional의-동작-원리에-대해-설명해주세요">💡@Transactional의 동작 원리에 대해 설명해주세요.</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
@Transactional을 메소드 또는 클래스에 명시하면, AOP를 통해 Target이 상속하고 있는 인터페이스 또는 Target 객체를 상속한 Proxy 객체가 생성되며, Proxy 객체의 메소드를 호출하면 Target 메소드 전 후로 트랜잭션 처리를 수행합니다.
</span>

<h3 id="💡transactional를-스프링-bean의-메소드-a에-적용하였고-해당-bean의-메소드-b가-호출되었을-때-b-메소드-내부에서-a-메소드를-호출하면-어떤-요청-흐름이-발생하는지-설명해주세요">💡@Transactional를 스프링 Bean의 메소드 A에 적용하였고, 해당 Bean의 메소드 B가 호출되었을 때, B 메소드 내부에서 A 메소드를 호출하면 어떤 요청 흐름이 발생하는지 설명해주세요.</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
프록시는 클라이언트가 타겟 객체를 호출하는 과정에만 동작하며, 타겟 객체의 메소드가 자기 자신의 다른 메소드를 호출할 때는 프록시가 동작하지 않습니다.
</span>

<pre><code>A 메소드는 프록시로 감싸진 메소드가 아니므로 트랜잭션이 적용되지 않은 일반 코드가 수행됩니다.</code></pre><h3 id="💡a-라는-service-객체의-메소드가-존재하고-그-메소드-내부에서-로컬-트랜잭션-3개다른-service-객체의-트랜잭션-메소드를-호출했다는-의미가-존재한다고-할-때-transactional을-a-메소드에-적용하면-어떤-요청-흐름이-발생하는지-설명해주세요">💡A 라는 Service 객체의 메소드가 존재하고, 그 메소드 내부에서 로컬 트랜잭션 3개(다른 Service 객체의 트랜잭션 메소드를 호출했다는 의미)가 존재한다고 할 때, @Transactional을 A 메소드에 적용하면 어떤 요청 흐름이 발생하는지 설명해주세요.</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
트랜잭션 전파 수준에 따라 달라지는데, 만약 기본 옵션인 Required를 가져간다면 로컬 트랜잭션 3개가 모두 부모 트랜잭션인 A에 합류하여 수행됩니다.
<br>그래서 부모 트랜잭션이나 로컬 트랜잭션 3개나 모두 같은 트랜잭션이므로 어느 하나의 로직에서 문제가 발생하면 전부 롤백이 됩니다.
</span>

<h3 id="💡transactional에-readonly-속성을-사용하는-이유에-대해서-설명해주세요">💡@Transactional에 readOnly 속성을 사용하는 이유에 대해서 설명해주세요.</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
트랜잭션 안에서 수정/삭제 작업이 아닌 ReadOnly 목적인 경우에 주로 사용하며,
영속성 컨텍스트에서 엔티티를 관리 할 필요가 없기 때문에 readOnly를 추가하는 것으로 메모리 성능을 높일 수 있고,
데이터 변경 불가능 로직임을 코드로 표시할 수 있어 가독성이 높아진다는 장점이 있습니다.
</span>

<h3 id="💡⭐jpa-n--1-문제와-발생하는-이유-그리고-해결하는-방법을-설명해주세요">💡⭐JPA N + 1 문제와 발생하는 이유 그리고 해결하는 방법을 설명해주세요.</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
N+1이란 1번의 쿼리를 날렸을 때 의도하지 않은 N번의 쿼리가 추가적으로 실행되는 것을 의미합니다. 
<br>해결 방법에는 여러 방법이 있지만 가장 많이 사용되는 방법은 Fetch Join을 사용해 해결하는 방법입니다.
<br>N+1 문제가 발생하는 이유는 연관관계를 가진 엔티티를 조회할 때 한 쪽 테이블만 조회하고 연결된 다른 테이블은 따로 조회하기 때문인데,
Fetch Join을 사용하면 미리 두 테이블을 Join하여 한 번에 모든 데이터를 가져오기 때문에 N+1문제를 애초에 막을 수 있습니다.
</span>

<h3 id="💡jpa와-같은-orm을-사용하면서-쿼리가-복잡해지는-경우에는-어떻게-해결하는게-좋을까요">💡JPA와 같은 ORM을 사용하면서 쿼리가 복잡해지는 경우에는 어떻게 해결하는게 좋을까요?</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
일단 JPA 자체는 정적인 상황에서 사용하는걸 권장하기 때문에 복잡한 쿼리와 동적인 쿼리에 대한 문제가 발생하게 되는데, 그럴때는 JPQL과 Querydsl을 사용할 것을 권장하고 있습니다.
</span>

<h3 id="💡spring에서-cors-에러를-해결하기-위한-방법을-설명해주세요">💡Spring에서 CORS 에러를 해결하기 위한 방법을 설명해주세요.</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
Servlet Filter를 사용하여 커스텀한 CORS 설정을 합니다.
<br>WebMvcConfiguer를 구현한 Configuration 클래스를 만들어서 addCorsMappings()를 재정의합니다.
<br>Spring Security에서 CorsConfigurationSource를 Bean으로 등록하고 config에 추가합니다.</span>]]></description>
        </item>
        <item>
            <title><![CDATA[기술면접 (JAVA)]]></title>
            <link>https://velog.io/@tanuki_choi/%EA%B8%B0%EC%88%A0%EB%A9%B4%EC%A0%91-JAVA</link>
            <guid>https://velog.io/@tanuki_choi/%EA%B8%B0%EC%88%A0%EB%A9%B4%EC%A0%91-JAVA</guid>
            <pubDate>Mon, 08 May 2023 15:43:47 GMT</pubDate>
            <description><![CDATA[<h3 id="💡java의-특징을-설명해주새요">💡Java의 특징을 설명해주새요</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
기본자료형을 제외한 모든 요소들이 객체로 표현되고, 객체지향개념의 특징인 캡슐화, 상속, 다형성이 잘 적용된 언어입니다.
또한 운영체제에 독립적이며 가비지컬랙션을 통한 자동적인 메모리 관리가 가능합니다.
</span>

<h3 id="💡jvm의-역할에-대해-설명해주세요">💡JVM의 역할에 대해 설명해주세요.</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
스택기반으로 동작하며, 자바 바이트 코드를 운영체제에 맞게 해석해 주는 역할을 하고 가비지컬랙션을 통해 자동적인 메모리 관리를 합니다.
</span>

<h3 id="💡java의-컴파일-과정에-대해-설명해주세요">💡Java의 컴파일 과정에 대해 설명해주세요.</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
개발자가 자바파일을 생성하면 빌드를 통해 바이트코드를 생성합니다.
클래스로더를 통해 jvm메모리 내로 로드하고 실행엔진을 통해 컴퓨터가 읽을 수 있는 기계어로 해석 됩니다. 
</span>

<h3 id="💡java에서-제공하는-원시-타입들에-무엇이-있고-각각-몇-바이트를-차지하나요">💡Java에서 제공하는 원시 타입들에 무엇이 있고, 각각 몇 바이트를 차지하나요?</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
정수형으로는 바이트, 숏, 인트, 롱이 있고, 실수형으로는 프루트, 더블이 있으며, 문자형 차와 논리형 불린이 있습니다.
바이트는 1, 숏은 2, 인트는 4, 롱은 8을 차지하며, 프루트는 4, 더블은 8을 차지합니다.
문자형은 2를 차지하고 논리형은 1 바이트를 차지합니다.
</span>

<h3 id="💡오버라이딩overriding과-오버로딩overloading에-대해-설명해주세요">💡오버라이딩(Overriding)과 오버로딩(Overloading)에 대해 설명해주세요.</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
오버라이딩은 상위 클래스에 있는 메소드를 하위클래스에서 재정의 하는 것을 말하고,
오버로딩은 매개변수의 갯수나 타입을 다르게 하여 같은 이름의 메소드를 여러개 정의하는 것을 말합니다.
</span>

<h3 id="💡객체지향-프로그래밍oop에-대해-설명해주세요">💡객체지향 프로그래밍(OOP)에 대해 설명해주세요.</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
프로그램 구현에 필요한 객체를 파악하고 상태와 행위를 가진 객체를 만들고 각각의 객체들의 역할이 무엇인지 정의하여 객체들간의 상호작용을 통해 프로그램을 만드는 것을 말합니다.
특징으로는 캡슐와, 상속, 다형성, 추상화 등이 있고 모듈 재사용으로 확장 및 유지보수가 용이합니다.
</span>

<h3 id="💡try-with-resources에-대해-설명해주세요">💡try-with-resources에 대해 설명해주세요.</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
try안에 자원객체를 전달하면, try블록이 끝나고 자동으로 자원을 해제해주는 기능을 말합니다.
따로 finally 구문이나 모든 catch 구문에 종료 처리를 하지 않아도 됩니다.
</span>

<h3 id="💡불변-객체가-무엇인지-설명하고-대표적인-java의-예시를-설명해주세요">💡불변 객체가 무엇인지 설명하고 대표적인 Java의 예시를 설명해주세요.</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
불변 객체는 객체 생성 이후 내부의 상태가 변하지 않는 객체를 말합니다.
final 을 사용하여 불변 객체를 만들 수 있습니다.
참조 타입인 경우에는 copy해서 저장하거나 새로운 값을 만들어 복사하도록 합니다.
</span>

<h3 id="💡불변-객체나-final을-굳이-사용해야-하는-이유가-있을까요">💡불변 객체나 final을 굳이 사용해야 하는 이유가 있을까요?</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
쓰레드-세이프 하여 병렬 프로그래밍에 유용하며, 동기화를 고려하지 않아도 됩니다.
또한 부수효과를 피해 오류를 최소화 할 수 있으며, 가비지 컬랙션 성능을 높일 수 있습니다.
</span>

<h3 id="💡추상-클래스와-인터페이스를-설명해주시고-차이에-대해-설명해주세요">💡추상 클래스와 인터페이스를 설명해주시고, 차이에 대해 설명해주세요.</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
추상클래스는 클래스 내의 추상 메소드가 하나 이상 포함되거나 abstract(애브스트랙트)로 정의 된 경우를 말하고, 인터페이스는 모든 메소드가 추상 메소드로만 이루어져 있는 것을 말합니다.
공통점은 사용하기 위해서는 하위클래스에서 확장 및 구형을 해야합니다.
차이점으로는 인터페이스의 경우 구현하는 모든 클래스에 대해 특정한 메소트가 반드시 존재하도록 강제성이 있고, 추상클래스의 경우 상속받는 클래스의 공통적인 로직을 추상화 시키고, 기능 확장을 위해 사용합니다.
</span>

<h3 id="💡싱글톤-패턴에-대해-설명해주세요">💡싱글톤 패턴에 대해 설명해주세요.</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
싱글톤 패턴은 생성자의 호출이 반복적으로 이루어져도 실제로 생성되는 객체는 최초 생성된 객체를 반환 해주는 것입니다.
이는 메모리 낭비를 방지해주며, 다른 클래스 간의 데이터 공유가 쉽습니다.
하지만, 자원을 공유하기 때문에 테스트시 매번 인스턴스의 상태를 초기화 시켜줘야 합니다.

</span>

<h3 id="💡싱글톤-패턴의-대표적인-예시를-간단하게-설명해주세요">💡싱글톤 패턴의 대표적인 예시를 간단하게 설명해주세요.</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
싱글톤 패턴의 대표적인 예시는 Spring Bean 입니다.
스프링의 빈 등록 방식은 기본적으로 싱글톤 스코프이고, 스프링 컨테이너는 모든 빈들을 싱글톤으로 관리합니다.
</span>

<h3 id="💡가비지-컬렉션garbage-collection에-대해-설명해주세요">💡가비지 컬렉션(Garbage Collection)에 대해 설명해주세요.</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
가비지 컬렉션은 jvm의 메모리 기법중 하나이며, 시스템에서 동적으로 할당됐던 메모리 영역 중에서 필요없어진 메모리 영역을 회수하여 메모리를 관리해주는 기법입니다.
</span>

<h3 id="💡가비지-컬렉션-과정에-대해-설명해주세요">💡가비지 컬렉션 과정에 대해 설명해주세요.</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
작업을 수행하기 위해 jvm이 어플리케이션의 실행을 멈추고, 가비지컬렉션을 실행하는 쓰레드를 제외한 모든 쓰레드의 작업을 중단 후 사용하지 않는 메모리를 제거하고 작업이 재개 됩니다. 
</span>

<h3 id="💡객체지향프로그래밍oop에-대해-설명하세요">💡객체지향프로그래밍(OOP)에 대해 설명하세요</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
프로그래밍에서 필요한 데이터를 추상화시켜 행위(Method)와 상태(Attribute)를 가진 객체(Object)를 만들고, 그 객체들 간의 유기적인 상호 작용을 통해 로직을 구성하는 프로그래밍 기법입니다.
</span>

<h3 id="💡oop의-4가지-특징에-대해-설명하세요">💡OOP의 4가지 특징에 대해 설명하세요</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
먼저, 캡슐화는 독립적으로 역할 수행하기 위해 필요한 데이터와 기능을 하나로 묶은 것이며,
상속은 상위 개념의 특징을 하위 개념이 물려받는 것이고,
추상화는 객체들의 공통적인 특징을 모아 하나의 클래스로 다루는 것이고,
다형성은 하나의 타입으로 여러가지 참조변수를 사용할 수 있는 것이다.
</span>

<h3 id="💡객체지향의-설계원칙solid에-대해-설명해주세요">💡객체지향의 설계원칙(SOLID)에 대해 설명해주세요.</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
1.SRP(단일책임원칙): 모든 클래스는 각각 하나의 책임만 가져야한다.
2.OCP(개방폐쇄원칙): 기존 코드를 변경하지 않으면서 기능을 추가할 수 있도록 설계가 되는 원칙
3.LSP(리스코프치환원칙): 부모클래스가 들어갈 자리에 자식클래스를 넣어도 역할 하는데 문제가 없어야한다.
4.ISP(인터페이스분리원칙): 최소한의 기능만 제공하면서, 하나의 역할에 집중하는 것이다.
5.DIP(의존관계역전원칙): 구체적인 클래스 보다 상위클래스, 인터페이스, 추상클래스와 같이 변하지 않을 가능성이 높은 클래스와 관계를 맺으라는 것이다.
</span>

<h3 id="💡자바의-메모리-영역에-대해-설명해주세요">💡자바의 메모리 영역에 대해 설명해주세요.</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
method, stack, heap으로 구분되며, 
method는 전역변수와 스태택변수를 저장하며, method영역은 프로그램 시작부터 종료까지 남아있습니다.
stack은 지역변수와 매개변수 데이터 값이 저장되는 공간이며, 메소드가 메모리에 할당되고 종료되면 메모리가 해제됩니다.
heap은 new 키워드로 생성되는 객체, 배열 등이 저장되면, 가비지 컬랙션에 의해 메모리가 관리됩니다.
</span>

<h3 id="💡각-메모리-영역이-할당되는-시점은-언제인가요">💡각 메모리 영역이 할당되는 시점은 언제인가요?</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
Method 영역 : JVM이 동작해서 클래스가 로딩될 때 생성
Stack 영역 : 컴파일 타임 시 할당
Heap 영역 : 런타임시 할당
</span>

<h3 id="💡클래스와-객체에-대해-설명해주세요">💡클래스와 객체에 대해 설명해주세요.</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
클래스는 객체를 생성하는데 사용하고, 객체는 클래스 기반으로 생성 됩니다. 
</span>

<h3 id="💡생성자constructor에-대해-설명해주세요">💡생성자(Constructor)에 대해 설명해주세요.</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
생성자는 클래스와 같은 이름의 메소트로 객체가 생성될 때 호출되는 메소드입니다.
</span>

<h3 id="💡-wrapper-class란-무엇이며-boxing과-unboxing은-무엇인지-설명해주세요">💡 Wrapper Class란 무엇이며, Boxing과 UnBoxing은 무엇인지 설명해주세요.</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
기본 자료형(Primitive data type)에 대한 객체 표현을 Wrapper class라고 합니다.
기본 자료형 → Wrapper class로 변환하는 것을 Boxing이라 하며,
Wrapper class → 기본 자료형으로 변환하는 것을 UnBoxing이라 합니다.
</span>

<h3 id="💡synchronized에-대해-아는-대로-말해주세요">💡Synchronized에 대해 아는 대로 말해주세요.</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
여러 개의 쓰레드가 한개의 자원을 사용하고자 할 때, 현재 데이터를 사용하고 있는 쓰레드를 제외하고 나머지 쓰레드들은 데이터에 접근할 수 없게 막는 개념입니다.
멀티쓰레드 환경에서 쓰레드간 동기화를 시켜 데이터의 thread-safe를 보장합니다.
그러나 자주 사용하면 오히려 프로그램의 성능저하를 일으킬 수 있습니다.
</span>

<h3 id="💡new-string과-리터럴의-차이에-대해-설명해주세요">💡new String()과 리터럴(&quot;&quot;)의 차이에 대해 설명해주세요.</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
new String()은 new 키워드로 새로운 객체를 생성하기 때문에 Heap 메모리 영역에 저장되고,
리터럴("")는 Heap 안에 있는 String Constant Pool 영역에 저장됩니다.
</span>

<h3 id="💡string-stringbuffer-stringbuilder의-차이를-설명해주세요">💡String, StringBuffer, StringBuilder의 차이를 설명해주세요.</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
String은 불변의 속성을 가지며, StringBuffer와 StringBuilder는 가변의 속성을 가집니다.
StringBuffer는 동기화를 지원하여 멀티 쓰레드 환경에서 주로 사용하며,
StringBuilder는 동기화를 지원하지 않아 싱글 쓰레드 환경에서 주로 사용합니다.
</span>

<h3 id="💡string-객체가-불변인-이유에-대해-아는대로-설명해주세요">💡String 객체가 불변인 이유에 대해 아는대로 설명해주세요.</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
1. 특정 문자열 값을 재사용하는 빈도가 높을 수록 상당한 성능 향상을 기대할 수 있습니다.
2. 여러 쓰레드에서 동시에 특정 String 객체를 참조하더라도 안전합니다.
3. 해당 참조에 대한 문자열 값을 바꾸는 것이 불가능하기 때문에 보안에 유리하다.
</span>

<h3 id="💡-접근-제한자access-modifier에-대해-설명해주세요">💡 접근 제한자(Access Modifier)에 대해 설명해주세요.</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
변수 또는 메소드의 접근 범위를 설정해주기 위해서 사용하는 Java의 예약어를 의미하며,
public, protected, (default), private 가 존재합니다.
</span>

<pre><code>public - 접근 제한이 없다. (같은 프로젝트 내 어디서든 사용 가능)
protected - 해당 패키지 내, 다른 패키지에서 상속받아 자손 클래스에서 접근 가능하다.
(default) - 해당 패키지 내에서만 접근 가능
private - 해당 클래스에서만 접근 가능</code></pre><h3 id="💡클래스-멤버-변수-초기화-순서에-대해-설명해주세요">💡클래스 멤버 변수 초기화 순서에 대해 설명해주세요.</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
먼저 static 변수 선언부는 클래스가 로드 될 때 제일 먼저 초기화 되고, 필드 변수 선언부는 객체가 생성될 때 생성자 block보다 앞서 초기화 됩니다.
마지막으로 생성자 블록은 객체가 생성될 때 jvm이 내부정으로 locking 합니다.
</span>

<h3 id="💡-static에-대해-설명해주세요">💡 static에 대해 설명해주세요.</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
static 키워드를 사용한 변수나 메소드는 클래스가 메모리에 올라갈 때 자동으로 생성되며 클래스 로딩이 끝나면 바로 사용할 수 있습니다. 즉, 인스턴스(객체) 생성 없이 바로 사용 가능합니다.
모든 객체가 메모리를 공유한다는 특징이 있고, GC 관리 영역 밖에 있기 때문에 프로그램이 종료될 때까지 메모리에 값이 유지된 채로 존재하게 됩니다.
</span>

<h3 id="💡static을-사용하는-이유에-대해-설명해주세요">💡static을 사용하는 이유에 대해 설명해주세요.</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
자주 변하지 않는 값이나 공용자원에 대한 접근에 있어서 매번 로딩하거나 값을 읽어들이는 것보다 전역변수와 같은 개념을 통해 접근하는 것이 비용도 줄이고 효율을 높일수 있기 때문입니다.
</span>

<h3 id="💡inner-class내부-클래스의-장점에-대해-설명해주세요">💡Inner Class(내부 클래스)의 장점에 대해 설명해주세요</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
1.내부 클래스에서 외부 클래스의 멤버에 손쉽게 접근할 수 있다.
2.서로 관련 있는 클래스를 논리적으로 묶어서 표현함으로써, 캡슐화를 증가시키고, 코드의 복잡성을 낮출 수 있다.
3. 외부에서는 내부 클래스에 접근할 수 없으므로, 코드의 보안성을 높일 수 있다.
</span>

<h3 id="💡⭐리플렉션reflection이란-무엇인지-설명해주세요">💡⭐리플렉션(Reflection)이란 무엇인지 설명해주세요.</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
구체적인 클래스 타입을 알지 못해도 그 클래스의 메소드, 타입, 변수들에 접근할 수 있도록 해주는 자바 API입니다. 코드 작성할 시점에는 어떤 타입의 클래스를 사용할지 모르지만, 런타임 시점에 지금 실행되고 있는 클래스를 가져와서 실행해야하는 경우 사용됩니다.
</span>

<pre><code>intelliJ의 자동완성 기능, 스프링의 어노테이션이 리플렉션을 이용한 기능</code></pre><h3 id="💡⭐error와-exception의-차이를-설명해주세요">💡⭐Error와 Exception의 차이를 설명해주세요.</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
Error는 실행 중 일어날 수 있는 치명적 오류를 말합니다. 
컴파일 시점에 체크할 수 없고, 오류가 발생하면 프로그램은 비정상 종료되지만,
Exception은 Error보다 비교적 경미한 오류이며, try-catch를 이용해 프로그램의 비정상 종료를 막을 수 있습니다.
</span>

<h3 id="💡checkedexception과-uncheckedexception의-차이를-설명해주세요">💡CheckedException과 UnCheckedException의 차이를 설명해주세요.</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
CheckedException은 실행하기 전에 예측 가능한 예외를 말하고, 반드시 예외 처리를 해야 합니다. 대표적으로 IOException이 있습니다. 
UncheckedException은 실행하고 난 후에 알 수 있는 예외를 말하고, 따로 예외처리를 하지 않아도 됩니다. 대표적으로 NullPointerException이 있습니다.
</span>

<h3 id="💡optional-api에-대해-설명해주세요">💡Optional API에 대해 설명해주세요.</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
NullPointerException을 피하려면 null여부 검사를 반드시 하게 되는데 java8부터는 Optional api 를 이용하여  null로 인한 예외가 발생하지 않도록하고 optional 클래스의 메소드를 통해 null을 컨트롤 할 수 있습니다.
</span>

<h3 id="💡⭐collection-framework에-대해-설명해주세요">💡⭐Collection Framework에 대해 설명해주세요.</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
다수의 데이터를 쉽고 효과적으로 관리할 수 있는 표준화된 방법을 제공하는 클래스의 집합을 의미합니다. 자바 컬렉션에는 list, set, map, stack, quere가 존재 합니다.
</span>

<h3 id="💡⭐list-set-map-stack-queue의-특징에-대해-설명해주세요">💡⭐List, Set, Map, Stack, Queue의 특징에 대해 설명해주세요.</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
1.list는 순서가 있는 데이터의 집합이며, 데이터의 중복을 허용합니다.
2.set은 순서가 없는 데이터의 집합이며, 데이터의 중복을 허용하지 않습니다.
  만약 순서를 보장하고 싶다면, linkedhashset을 사용합니다.
3.map은 키와 값이 한쌍을 이뤄져 있고, 키를 기준으로 중복을 허용하지 않으며, 순서가 없습니다.
  만약 순서를 보장하고 싶다면, linkedhashmap를 사용합니다.
  또한 key를 기준으로 정렬을 하고 싶다면, treemap를 사용합니다.
4.stack은 선형 자료 구조이며, FILO, LIFO이다.
5.queue는 선형 자료 구조이며, FIFO이다.
</span>

<h3 id="💡array와-arraylist의-차이점에-대해-설명하세요">💡Array와 ArrayList의 차이점에 대해 설명하세요.</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
Array는 인덱스(Index)로 접근하고, ArrayList는 메서드를 통해 접근한다.
Array는 Object 뿐만 아니라 원시 타입(int, long, double 등)도 담을 수 있지만, ArrayList는 Object만 담을 수 있다. 
그래서 정수를 ArrayList에 넣을 경우 Integer형은 가능하지만 int 형은 불가능하다. 
</span>

<h3 id="💡⭐hashmap와-hashtable의-차이점에-대해-설명하세요">💡⭐HashMap와 Hashtable의 차이점에 대해 설명하세요.</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
가장 큰 차이점은 동기화의 지원 여부입니다.
HashMap은 동기화를 지원하지 않으며, 단일 쓰레드 환경에서 사용하기 좋은 자료구조이고,
HashTable은 동기화를 지원하며, 멀티 쓰레드 환경에서 사용하기 좋은 자료구조이다.
HashMap은 null을 허용하지만 HashTable은 null을 허용하지 않는다.
속도는 멀티 쓰레드 환경이 아니라면 HashTable이 HashMap보다 느리다.
</span>

<pre><code>다른 스레드가 block되고 unblock되는 대기 시간을 기다리기 때문</code></pre><h3 id="💡java는-멀티-스레드multi-thread-환경인데-멀티-스레드에-대해-설명하세요">💡Java는 멀티 스레드(Multi Thread) 환경인데 멀티 스레드에 대해 설명하세요.</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
하나의 프로세스 내에서 둘 이상의 스레드가 동시에 작업을 수행하는 것을 의미합니다.
</span>

<h3 id="💡멀티-스레드를-사용하는-이유가-무엇인가요">💡멀티 스레드를 사용하는 이유가 무엇인가요?</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
각 쓰레드가 자신이 속한 프로세스의 메모리를 공유하므로, 시스템 자원의 낭비가 적습니다.
또한 하나의 쓰레드가 작업을 할 때 다른 쓰레드가 별도의 작업을 할 수 있어 사용자와의 응답성도 좋아집니다.
</span>

<h3 id="💡⭐set과-map의-타입이-wrapper-class가-아닌-object를-받을-때-중복-검사는-어떻게-할건지-설명해주세요">💡⭐Set과 Map의 타입이 Wrapper Class가 아닌 Object를 받을 때 중복 검사는 어떻게 할건지 설명해주세요.</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
hashCode()메소드를 오버라이팅하여 리턴된 해시코드값이 같은지 보고 해시코드 값이 다르다면 다른 객체로 판단하며, 값이 같으면 equals()메소드를 오버라이딩하여 다시 비교한다. 이 두 개 값이 모두 맞다면 중복 객체입니다.
</span>

<h3 id="💡vector와-list의-차이를-설명해주세요">💡Vector와 List의 차이를 설명해주세요.</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
벡터는 데이터 삽입시 원소를 밀어내지만 리스트는 노드를 연결만 하기 때문에, 삽입 삭제 부분에서 리스트가 시간복잡도의 우위를 가집니다.
벡터는 랜덤부분접근이 가능하지만 리스트는 더블링크드리스트(노드가 양쪽으로 연결)로 되어있기 때문에 랜덤 접근이 되지 않습니다. 검색적인 측면에서는 벡터가 우위에 있습니다.
</span>

<h3 id="💡⭐제네릭에-대해-설명해주시고-왜-쓰는지-알려주세요">💡⭐제네릭에 대해 설명해주시고, 왜 쓰는지 알려주세요.</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
제네릭은 데이터 타입을 하나로 지정하지 않고 사용할때마다 범용적이고 포괄적으로 지정한다는 의미입니다. 이를 사용함으로써 잘못된 타입이 사용될 수 있는 문제를 컴파일 과정에서 제거할 수 있어 에러를 사전에 방지할 수 있습니다.
</span>

<h3 id="💡final--finally--finalize-의-차이를-설명해주세요">💡final / finally / finalize 의 차이를 설명해주세요.</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
1.final은 클래스, 메소드, 변수, 인자를 선언할 때 사용할 수 있으며, 한 번만 할당하고 싶을 때 사용합니다.
2.finally는 try-catch와 함께 사용되며, try-catch가 종료될 때 finally block이 항상 수행되기 때문에 마무리 해줘야 하는 작업이 존재하는 경우에 해당하는 코드를 작성해주는 코드 블록입니다.
3.finalize는 Object클래스에 정의되어 있는 메소드이며, GC에 의해 호출되는 메소드로 절대 호출해서는 안되는 메소드입니다.
</span>

<h3 id="💡직렬화serialize와-역직렬화에-대해-설명해주세요">💡직렬화(Serialize)와 역직렬화에 대해 설명해주세요.</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
직렬화는 시스템 내부에서 사용되는 객체 또는 데이터를 외부의 시스템에서도 사용할 수 있도록 바이트형태로 데이터 변환하는 기술입니다.
역직렬화는 직렬화된 바이트(Byte) 형태의 데이터를 다시 객체로 변환하는 과정입니다.
</span>

<pre><code>직렬화: JVM의 메모리에 상주(힙 or 스택)되어 있는 객체 데이터를 바이트 형태로 변환하는 기술</code></pre><h3 id="💡serialversionuid를-선언해야-하는-이유에-대해-설명해주세요">💡SerialVersionUID를 선언해야 하는 이유에 대해 설명해주세요.</h3>
<span style="background-color: #0a4ca8; color: #0a4ca8;">
JVM은 직렬화와 역직렬화를 하는 시점의 클래스에 대한 버전 번호를 부여하는데, 만약 그 시점에 클래스의 정의가 바뀌어 있다면 새로운 버전 번호를 할당하게 됩니다. 
그래서 직렬화할 때의 버전 번호와 역직렬화를 할 때의 버전 번호가 다르면 역직렬화가 불가능하게 될 수 있기 때문에 이런 문제를 해결하기 위해 SerialVersionUID를 사용합니다.
</span>

<p><a href="https://dev-coco.tistory.com/153">참고 자료 1) 신입 개발자 기술면접 질문 정리 - 자바</a>
<a href="https://backendcode.tistory.com/236">참고 자료 2) 신입 백엔드 개발자 기술 면접 핵심 정리 - Java</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[기술면접 질문 정리 - Java(2)]]></title>
            <link>https://velog.io/@tanuki_choi/%EA%B8%B0%EC%88%A0%EB%A9%B4%EC%A0%91-%EC%A7%88%EB%AC%B8-%EC%A0%95%EB%A6%AC-Java2</link>
            <guid>https://velog.io/@tanuki_choi/%EA%B8%B0%EC%88%A0%EB%A9%B4%EC%A0%91-%EC%A7%88%EB%AC%B8-%EC%A0%95%EB%A6%AC-Java2</guid>
            <pubDate>Wed, 03 May 2023 08:16:53 GMT</pubDate>
            <description><![CDATA[<h1 id="java">JAVA</h1>
<hr>
<hr>
<h2 id="👩🎓-collection">👩‍🎓 Collection</h2>
<h4 id="1-list-map-set-stack-queue-인터페이스를-기준으로-여러-구현체가-존재">1. List, Map, Set, Stack, Queue 인터페이스를 기준으로 여러 구현체가 존재.</h4>
<h4 id="2-왜-collection을-사용">2. 왜 collection을 사용?</h4>
<ul>
<li>다수의 데이터를 다루는데 표준화된 클래스들을 제공해주기 때문에 DataStructure를 직접 구현하지 않고 편하게 사용할 수 있기 때문이다.</li>
<li>배열과 다르게 객체를 보관하기 위한 공간을 미리 정하지 않아도 되므로, 상황에 따라 객체의 수를 동적으로 정할 수 있다.</li>
<li>프로그램의 공간적인 효율성을 높여준다.</li>
</ul>
<h4 id="3list">3.List</h4>
<ul>
<li>직접 @Override를 통해 사용자가 정의하여 사용할 수도 있다.</li>
<li>대표적인 구현체<ul>
<li>ArrayList(Vector개선), LinkedList<h4 id="4map">4.Map</h4>
</li>
</ul>
</li>
<li>key-value 구조로 이루어져 있다.</li>
<li>key를 기준으로 중복된 값을 저장하지 않으여, 순서를 보장하지 않는다.</li>
<li>대표적인 구현체<ul>
<li>HashMap, TreeMap(key값으로 정렬), LinkedHashMap(순서를 보장) <h4 id="5set">5.Set</h4>
</li>
</ul>
</li>
<li>value에 대해 중복된 값을 저장하지 않으며, 순서를 보장하지 않는다.</li>
<li>대표적인 구현체<ul>
<li>HashSet, LinkedHashSet(순서를 보장)<h4 id="6stack">6.Stack</h4>
</li>
</ul>
</li>
<li>선형 자료구조.</li>
<li>나중에 들어온 원소가 가장 먼저 나온다.(LIFO)</li>
<li>먼저 들어간 원소가 나중에 나온다.(FILO)<h4 id="7queue">7.Queue</h4>
</li>
<li>선형 자료 구조.</li>
<li>먼저 들어온 원소가 가장 먼저 나온다.(FIFO)<ul>
<li>Priority Queue(트리구조)</li>
</ul>
</li>
</ul>
<hr>
<h2 id="👩🎓-annotation">👩‍🎓 Annotation</h2>
<h4 id="1-본래-주석이란-뜻으로-인터페이스를-기반으로-한-문법">1. 본래 주석이란 뜻으로, 인터페이스를 기반으로 한 문법.</h4>
<h4 id="2-주석처럼-코드에-달아-클래스에-특별한-의미를-부여하거나-기능을-주입할-수-있다">2. 주석처럼 코드에 달아 클래스에 특별한 의미를 부여하거나 기능을 주입할 수 있다.</h4>
<h4 id="3-해석되는-시점을-정할-수-도-있다">3. 해석되는 시점을 정할 수 도 있다.</h4>
<h4 id="4-종류">4. 종류</h4>
<ul>
<li><p>Built-in annotation</p>
<ul>
<li><p>자바에 내장되어 있는 어노테이션.</p>
</li>
<li><p>주로 컴파일러를 위한 것으로 컴파일러에게 유용한 정보 제공.</p>
</li>
<li><p>대표적인 예</p>
<p>  @Override(현재메서드가 수퍼클래스의 메소드를 오버라이드한 메소드임을 명시)</p>
<pre><code>    @Deprecated(더이상 사용하지 말아야 할 메소드 명시)
    @SupressWarning(프로그래머의 의도를 컴파일러에게 전달하여 경고를 제거)
    @FunctionalInterface(컴파일러에게 다음 인터페이스는 함수형 인터페이스 임을 알린다.)</code></pre></li>
</ul>
</li>
<li><p>Meta annotation</p>
<ul>
<li><p>어노테이션에대한 정보를 나타내기위한 어노테이션</p>
</li>
<li><p>어노테이션의 동작을 결정</p>
</li>
<li><p>새로운 어노테이션 정의할 때 사용</p>
</li>
<li><p>대표적인 예</p>
<pre><code>@Target(적용가능한 대상을 지정하는데 사용)
@Retention(유지되는 기간을 정하는데 사용)
     RetentionPolicy (SOURCE, CLASS, RUNTIME)
@Documented(jvavadoc으로 작성한 문서에 포함되도록 할 때 사용)
@Inherited(자손클래스에도 상속되도록 함)
@Native(네이티브 메서드에 의해 참조되는 상수 필드에 붙임)</code></pre></li>
</ul>
</li>
<li><p>Custom annotation</p>
<ul>
<li><p>개발자가 직접 만들어내는 어노테이션</p>
<p>  public @Interface Annotation {}</p>
<h4 id="reference-httpsasfirstalwaystistorycom309">[reference] (<a href="https://asfirstalways.tistory.com/309">https://asfirstalways.tistory.com/309</a>)</h4>
</li>
</ul>
</li>
</ul>
<hr>
<h2 id="👩🎓-generic">👩‍🎓 Generic</h2>
<h4 id="1-자바에서-안정성을-맡고-있다">1. 자바에서 안정성을 맡고 있다.</h4>
<h4 id="2-다양한-타입의-객체들을-다루는-메서드나-컬렉션-클래스에서-사용하는-것으로-컴파일과정에서-타입체크를-해주는-기능이다">2. 다양한 타입의 객체들을 다루는 메서드나 컬렉션 클래스에서 사용하는 것으로 컴파일과정에서 타입체크를 해주는 기능이다.</h4>
<h4 id="3-객체의-타입-안정성을-높이고-형변황의-번거로움을-줄여준다">3. 객체의 타입 안정성을 높이고 형변황의 번거로움을 줄여준다.</h4>
<h4 id="4-코드도-간결해진다">4. 코드도 간결해진다.</h4>
<pre><code>예를 들면, Collection 에 특정 객체만 추가될 수 있도록, 
또는 특정한 클래스의 특징을 갖고 있는 경우에만 추가될 수 있도록 하는 것</code></pre><h4 id="5-collection-내부에서-들어온-값이-내가-원하는-값인지-별도의-로직처리를-구현할-필요가-없어진다">5. collection 내부에서 들어온 값이 내가 원하는 값인지 별도의 로직처리를 구현할 필요가 없어진다.</h4>
<h4 id="6-api-를-설계하는데-있어서-보다-명확한-의사전달이-가능해진다">6. api 를 설계하는데 있어서 보다 명확한 의사전달이 가능해진다.</h4>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스 Lv.2] 순위 검색]]></title>
            <link>https://velog.io/@tanuki_choi/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-Lv.2-%EC%88%9C%EC%9C%84-%EA%B2%80%EC%83%89</link>
            <guid>https://velog.io/@tanuki_choi/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-Lv.2-%EC%88%9C%EC%9C%84-%EA%B2%80%EC%83%89</guid>
            <pubDate>Wed, 03 May 2023 06:05:25 GMT</pubDate>
            <description><![CDATA[<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/72412">코딩테스트 연습 - 순위 검색</a></p>
<h2 id="문제-설명">문제 설명</h2>
<blockquote>
<p>지원자가 지원서에 입력한 4가지의 정보와 획득한 코딩테스트 점수를 하나의 문자열로 구성한 값의 배열 info, 개발팀이 궁금해하는 문의조건이 문자열 형태로 담긴 배열 query가 매개변수로 주어질 때,
각 문의조건에 해당하는 사람들의 숫자를 순서대로 배열에 담아 return 하도록 solution 함수를 완성해 주세요.</p>
</blockquote>
<h3 id="제한사항">제한사항</h3>
<blockquote>
<ul>
<li>info 배열의 크기는 1 이상 50,000 이하입니다.</li>
<li>info 배열 각 원소의 값은 지원자가 지원서에 입력한 4가지 값과 코딩테스트 점수를 합친 &quot;개발언어 직군 경력 소울푸드 점수&quot; 형식입니다.<ul>
<li>개발언어는 cpp, java, python 중 하나입니다.</li>
<li>직군은 backend, frontend 중 하나입니다.</li>
<li>경력은 junior, senior 중 하나입니다.</li>
<li>소울푸드는 chicken, pizza 중 하나입니다.</li>
<li>점수는 코딩테스트 점수를 의미하며, 1 이상 100,000 이하인 자연수입니다.</li>
<li>각 단어는 공백문자(스페이스 바) 하나로 구분되어 있습니다.</li>
</ul>
</li>
<li>query 배열의 크기는 1 이상 100,000 이하입니다.</li>
<li>query의 각 문자열은 &quot;[조건] X&quot; 형식입니다.<ul>
<li>[조건]은 &quot;개발언어 and 직군 and 경력 and 소울푸드&quot; 형식의 문자열입니다.</li>
<li>언어는 cpp, java, python, - 중 하나입니다.</li>
<li>직군은 backend, frontend, - 중 하나입니다.</li>
<li>경력은 junior, senior, - 중 하나입니다.</li>
<li>소울푸드는 chicken, pizza, - 중 하나입니다.</li>
<li>&#39;-&#39; 표시는 해당 조건을 고려하지 않겠다는 의미입니다.</li>
<li>X는 코딩테스트 점수를 의미하며 조건을 만족하는 사람 중 X점 이상 받은 사람은 모두 몇 명인 지를 의미합니다.</li>
<li>각 단어는 공백문자(스페이스 바) 하나로 구분되어 있습니다.</li>
<li>예를 들면, &quot;cpp and - and senior and pizza 500&quot;은 &quot;cpp로 코딩테스트를 봤으며, 경력은 senior 이면서 소울푸드로 pizza를 선택한 지원자 중 코딩테스트 점수를 500점 이상 받은 사람은 모두 몇 명인가?&quot;를 의미합니다.</li>
</ul>
</li>
</ul>
</blockquote>
<h2 id="풀이">풀이</h2>
<h3 id="to-do-리스트">To-Do 리스트</h3>
<ol>
<li>지원자 리스트와 채용 리스트를 생성.</li>
<li>채용리스트에 지원자가 충족되면 1씩 더함.</li>
</ol>
<h3 id="결과">결과</h3>
<pre><code class="language-java">import java.util.*;

class Developer {
    String language;
    String subject;
    String career;
    String soulFood;
    int score;

    public Developer(String language, String subject, String career, String soulFood, int score){
        this.language = language;
        this.subject = subject;
        this.career = career;
        this.soulFood = soulFood;
        this.score = score;
    }

    @Override
    public String toString(){
        return &quot;[&quot;+this.language+&quot;, &quot;+this.subject+&quot;, &quot;+this.career+&quot;, &quot;+this.soulFood+&quot;, &quot;+this.score+&quot;]&quot;;
    }
}

class Solution {
    public int[] solution(String[] info, String[] query) {
        int[] answer = new int[query.length];
        int k = 0;

        List&lt;Developer&gt; list = new ArrayList&lt;&gt;();
        List&lt;Developer&gt; quelist = new ArrayList&lt;&gt;();

        for(String p: info){
            String[] srr = p.split(&quot; &quot;);
            Developer dp = new Developer(srr[0],srr[1],srr[2],srr[3],Integer.parseInt(srr[4]));
            list.add(dp);
        }

        for(String q : query){
            String[] srr = q.replaceAll(&quot;and &quot;,&quot;&quot;).split(&quot; &quot;);
            Developer dp = new Developer(srr[0],srr[1],srr[2],srr[3],Integer.parseInt(srr[4]));
            quelist.add(dp);
        }

        for(Developer h: quelist){
            //System.out.println(h.toString());
            for(Developer v: list){
                if((h.language.equals(v.language) || h.language.equals(&quot;-&quot;))
                  &amp;&amp; (h.subject.equals(v.subject) || h.subject.equals(&quot;-&quot;))
                  &amp;&amp; (h.career.equals(v.career) || h.career.equals(&quot;-&quot;))
                  &amp;&amp; (h.soulFood.equals(v.soulFood) || h.soulFood.equals(&quot;-&quot;))
                  &amp;&amp; h.score &lt;= v.score){
                    answer[k]++;
                    //System.out.println(&quot;&gt;&quot;+v.toString());
                }
            }
            k++;
        }

        return answer;
    }
}</code></pre>
<h3 id="알게-된-점">알게 된 점</h3>
<blockquote>
<p>💥 효율성 테스트 0점.
💥 지원자를 기준으로 만들 수 있는 경우의 수를 map형태로 저장.
💥 map정렬시에 일일히 정렬하는 것보다 한번에 정리하면 시간단축이 가능.
💥 이분법으로 스코어보다 높은 사람의 수를 구함.</p>
</blockquote>
<pre><code class="language-java">import java.util.*;

class Solution {
    static Map&lt;String, List&lt;Integer&gt;&gt; map = new HashMap&lt;&gt;();
    public void numberofcase(String[] srr, String str, int cnt){
        if(cnt == 4){
            if(!map.containsKey(str)){
                map.put(str, new ArrayList&lt;&gt;());
            }
            map.get(str).add(Integer.parseInt(srr[4]));
            return;
        }

        numberofcase(srr, str+&quot;-&quot;, cnt+1);
        numberofcase(srr, str+srr[cnt], cnt+1);
    }

    public int[] solution(String[] info, String[] query) {
        int[] answer = new int[query.length];

        for(int i = 0; i &lt; info.length; i++){
            String srr[] = info[i].split(&quot; &quot;);
            numberofcase(srr,&quot;&quot;,0);
        }

        for(String key: map.keySet()){
            Collections.sort(map.get(key));
        }

        for(int i = 0; i &lt; query.length; i++){
            String[] t = query[i].replaceAll(&quot; and &quot;,&quot;&quot;).split(&quot; &quot;);
            if(map.get(t[0]) != null){
                List&lt;Integer&gt; list = map.get(t[0]);
                int s = 0;
                int e = list.size()-1;
                while(s &lt;= e){
                    int m = (s+e)/2;
                    if(list.get(m) &lt; Integer.parseInt(t[1])){
                        s = m + 1;
                    }else {
                        e = m - 1;
                    }
                }
                answer[i] = list.size()-s;
            }
        }

        return answer;
    }
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스 Lv.2] 호텔 대실]]></title>
            <link>https://velog.io/@tanuki_choi/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-Lv.2-%ED%98%B8%ED%85%94-%EB%8C%80%EC%8B%A4</link>
            <guid>https://velog.io/@tanuki_choi/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-Lv.2-%ED%98%B8%ED%85%94-%EB%8C%80%EC%8B%A4</guid>
            <pubDate>Mon, 01 May 2023 14:49:43 GMT</pubDate>
            <description><![CDATA[<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/155651">코딩테스트 연습 - 호텔 대실</a></p>
<h2 id="문제-설명">문제 설명</h2>
<p>호텔을 운영 중인 코니는 최소한의 객실만을 사용하여 예약 손님들을 받으려고 합니다. 
한 번 사용한 객실은 <code>퇴실 시간을 기준으로 10분간 청소</code>를 하고 다음 손님들이 사용할 수 있습니다.</p>
<blockquote>
<p>예약 시각이 문자열 형태로 담긴 2차원 배열 book_time이 매개변수로 주어질 때, 코니에게 필요한 최소 객실의 수를 return 하는 solution 함수를 완성해주세요.</p>
</blockquote>
<h3 id="제한사항">제한사항</h3>
<blockquote>
<ul>
<li>1 ≤ book_time의 길이 ≤ 1,000<ul>
<li>book_time[i]는 [&quot;HH:MM&quot;, &quot;HH:MM&quot;]의 형태로 이루어진 배열입니다<ul>
<li>[대실 시작 시각, 대실 종료 시각] 형태입니다.</li>
<li>시각은 HH:MM 형태로 24시간 표기법을 따르며, &quot;00:00&quot; 부터 &quot;23:59&quot; 까지로 주어집니다.<ul>
<li>예약 시각이 자정을 넘어가는 경우는 없습니다.</li>
<li>시작 시각은 항상 종료 시각보다 빠릅니다.</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</blockquote>
<h2 id="풀이">풀이</h2>
<h3 id="to-do-리스트">To-Do 리스트</h3>
<ol>
<li>퇴실시간은 10분 더해서 저장.</li>
<li>비교해서 작으면 역순으로 정렬 후, 리스트에서 제거.</li>
<li>최소 퇴실시간 재지정.<h3 id="결과">결과</h3>
<pre><code class="language-java">import java.util.*;
</code></pre>
</li>
</ol>
<p>class Room{
    String checkIn;
    String checkOut;</p>
<pre><code>public Room(String checkIn, String checkOut){
    this.checkIn = checkIn;
    this.checkOut = checkOut;
}</code></pre><p>}</p>
<p>class Solution {
    public int solution(String[][] book_time) {
        int answer = 1;</p>
<pre><code>    Arrays.sort(book_time, (x,y)-&gt;x[0].compareTo(y[0]));

    List&lt;Room&gt; list = new ArrayList&lt;&gt;();

    String min = &quot;&quot;;

    for(String[] rooms : book_time ){
        String[] end = rooms[1].split(&quot;:&quot;);
        int ehour = Integer.parseInt(end[0]);
        int emin = Integer.parseInt(end[1])+10;
        if(emin &gt;= 60){
            ehour += 1;
            emin -= 60;
        }
        String co = String.format(&quot;%02d&quot;, ehour)+&quot;:&quot;+String.format(&quot;%02d&quot;, emin);
        Room rm = new Room(rooms[0], co);

        if(!list.isEmpty()){
            //System.out.println(min+&quot;, &quot;+rm.checkIn+&quot;= &quot;+min.compareTo(rm.checkIn));
            if(min.compareTo(rm.checkIn) &lt;= 0 ){
                Collections.sort(list, (x,y)-&gt;x.checkOut.compareTo(y.checkOut));
                list.remove(0);
                if(!list.isEmpty()){
                    min = list.get(0).checkOut;
                }else {
                    min = &quot;&quot;;
                }
            }else {
                answer++;
            }
            if(min.compareTo(rm.checkOut) &gt; 0){
                min = rm.checkOut;
            }
        }else{
            min = rm.checkOut;
        }

        list.add(rm);
    }

    // for(Room r : list){
    //     System.out.printf(&quot;(%s, %s)\n&quot;,r.checkIn, r.checkOut);
    // }

    return answer;
}</code></pre><p>}</p>
<pre><code></code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스 Lv.2] 점 찍기]]></title>
            <link>https://velog.io/@tanuki_choi/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-Lv.2-%EC%A0%90-%EC%B0%8D%EA%B8%B0</link>
            <guid>https://velog.io/@tanuki_choi/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-Lv.2-%EC%A0%90-%EC%B0%8D%EA%B8%B0</guid>
            <pubDate>Mon, 01 May 2023 08:05:20 GMT</pubDate>
            <description><![CDATA[<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/140107">코딩테스트 연습 - 점 찍기</a></p>
<h2 id="문제-설명">문제 설명</h2>
<p>좌표평면을 좋아하는 진수는 x축과 y축이 직교하는 2차원 좌표평면에 점을 찍으면서 놀고 있습니다. 
진수는 두 양의 정수 k, d가 주어질 때 다음과 같이 점을 찍으려 합니다.</p>
<ul>
<li>원점(0, 0)으로부터 x축 방향으로 <code>a*k(a = 0, 1, 2, 3 ...)</code>, y축 방향으로 <code>b*k(b = 0, 1, 2, 3 ...)</code>만큼 떨어진 위치에 점을 찍습니다.</li>
<li>원점과 거리가 d를 넘는 위치에는 점을 찍지 않습니다.</li>
</ul>
<pre><code>예를 들어, 
k가 2, d가 4인 경우에는 (0, 0), (0, 2), (0, 4), (2, 0), (2, 2), (4, 0) 위치에
점을 찍어 총 6개의 점을 찍습니다.</code></pre><blockquote>
<p>정수 k와 원점과의 거리를 나타내는 정수 d가 주어졌을 때, 점이 총 몇 개 찍히는지 return 하는 solution 함수를 완성하세요.</p>
</blockquote>
<h3 id="제한사항">제한사항</h3>
<blockquote>
<ul>
<li>1 ≤ k ≤ 1,000,000</li>
<li>1 ≤ d ≤ 1,000,000</li>
</ul>
</blockquote>
<h2 id="풀이">풀이</h2>
<h3 id="to-do-리스트">To-Do 리스트</h3>
<h3 id="결과">결과</h3>
<pre><code class="language-java">
import java.util.*;

class Node {
    int x;
    int y;

    public Node(int x, int y){
        this.x = x;
        this.y = y;
    }
}

class Solution {
    public long solution(int k, int d) {
        long answer = 0;
        //2차원 좌표평면 -&gt; (+,+)
        //원점으로 부터 1~k까지, 1~k까지
        //단, 원점과의 거리가 d를 넘는 위치에는 점을 찍지 않는다.
        Node node = new Node(0,0);

        while(node.x &lt;= d){
            //System.out.printf(&quot;(%d, %d)\n&quot;,node.x,node.y);
            double x2 = Math.ceil(Math.pow(node.x,2));
            double y2 = Math.ceil(Math.pow(node.y,2));

            double dis = Math.sqrt(x2 + y2);
            if(dis &lt;= (double) d) {
                answer += 1;
                //System.out.printf(&quot;(%d, %d)\n&quot;,node.x,node.y);
            }
            node.y += k;
            if(node.y &gt; d) {
                node.y = 0;
                node.x += k;
            }   
        }

        return answer;
    }
}</code></pre>
<h3 id="알게-된-점">알게 된 점</h3>
<blockquote>
<p>💥 8,11,13,14 시간 초과.</p>
</blockquote>
<pre><code class="language-java">import java.util.*;

class Solution {
    public long solution(int k, int d) {
        long answer = 0;
        //2차원 좌표평면 -&gt; (+,+)
        //원점으로 부터 1~k까지, 1~k까지
        //단, 원점과의 거리가 d를 넘는 위치에는 점을 찍지 않는다.

        for(int i = 0; i &lt;= d; i+=k){
            double x2 = Math.pow(i,2);
            double d2 = Math.pow(d,2);

            double dis = Math.sqrt(d2-x2);

            answer += (long)(dis/(long)k)+1;
        }

        return answer;
    }
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스 Lv.2] 큰 수 만들기]]></title>
            <link>https://velog.io/@tanuki_choi/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-Lv.2-%ED%81%B0-%EC%88%98-%EB%A7%8C%EB%93%A4%EA%B8%B0</link>
            <guid>https://velog.io/@tanuki_choi/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-Lv.2-%ED%81%B0-%EC%88%98-%EB%A7%8C%EB%93%A4%EA%B8%B0</guid>
            <pubDate>Thu, 27 Apr 2023 06:35:16 GMT</pubDate>
            <description><![CDATA[<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/42883">코딩테스트 연습 - 큰 수 만들기</a></p>
<h2 id="문제-설명">문제 설명</h2>
<p>어떤 숫자에서 k개의 수를 제거했을 때 얻을 수 있는 가장 큰 숫자를 구하려 합니다.</p>
<p>예를 들어, 숫자 1924에서 수 두 개를 제거하면 [19, 12, 14, 92, 94, 24] 를 만들 수 있습니다. 이 중 가장 큰 숫자는 94 입니다.</p>
<blockquote>
<p>문자열 형식으로 숫자 number와 제거할 수의 개수 k가 solution 함수의 매개변수로 주어집니다. number에서 k 개의 수를 제거했을 때 만들 수 있는 수 중 가장 큰 숫자를 문자열 형태로 return 하도록 solution 함수를 완성하세요.</p>
</blockquote>
<h3 id="제한사항">제한사항</h3>
<blockquote>
<ul>
<li>number는 2자리 이상, 1,000,000자리 이하인 숫자입니다.</li>
<li>k는 1 이상 number의 자릿수 미만인 자연수입니다.</li>
</ul>
</blockquote>
<h2 id="풀이">풀이</h2>
<h3 id="to-do-리스트">To-Do 리스트</h3>
<ol>
<li><p>stack이 비어있는 경우, 수를 넣어준다.</p>
</li>
<li><p>stack의 마지막 값보다 넣으려는 수가 크고, 제거하려는 수 k 가 0보다 큰 경우에 아래를 반복한다.
2-1. 기존 stack값을 제거한다. 이때 제거하려는 수 k도 1을 감소한다.
2-2. 만약 그전에 stack이 비어버리거나 k가 0보다 작거나 같아지는 경우 반복을 멈춘다.</p>
</li>
<li><p>넣으려는 수를 stack에 저장한다.</p>
</li>
<li><p>stack의 크기와 최종적으로 구할 수 있는 수의 길이가 같다면 반복을 멈춘다.</p>
<h3 id="결과">결과</h3>
<pre><code class="language-java">import java.util.*;
class Solution {
 public String solution(String number, int k) {
     String answer = &quot;&quot;;
     Stack&lt;Integer&gt; stack = new Stack&lt;&gt;();
     char[] crr = number.toCharArray();
     for(int i = 0; i &lt; crr.length; i++){
         char c = crr[i];
         int num = Integer.parseInt(String.valueOf(c));
         if(stack.isEmpty()){
             stack.add(num);
             continue;
         }

         while(stack.peek() &lt; num &amp;&amp; k &gt; 0){
             stack.pop();
             k--;
             if(stack.isEmpty() || k &lt;= 0) break;
         }
         stack.add(num);
         if(stack.size() == number.length()-k) break;
     }

     for(int i : stack){
         answer += i;
     }
     return answer;
 }
}</code></pre>
</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스 Lv.2] 롤케이크 자르기]]></title>
            <link>https://velog.io/@tanuki_choi/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-Lv.2-%EB%A1%A4%EC%BC%80%EC%9D%B4%ED%81%AC-%EC%9E%90%EB%A5%B4%EA%B8%B0</link>
            <guid>https://velog.io/@tanuki_choi/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-Lv.2-%EB%A1%A4%EC%BC%80%EC%9D%B4%ED%81%AC-%EC%9E%90%EB%A5%B4%EA%B8%B0</guid>
            <pubDate>Thu, 27 Apr 2023 06:29:39 GMT</pubDate>
            <description><![CDATA[<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/132265">코딩테스트 연습 - 롤케이크 자르기</a></p>
<h2 id="문제-설명">문제 설명</h2>
<p>철수는 롤케이크를 두 조각으로 잘라서 동생과 한 조각씩 나눠 먹으려고 합니다. 
이 롤케이크에는 여러가지 토핑들이 일렬로 올려져 있습니다. 
철수와 동생은 롤케이크를 공평하게 나눠먹으려 하는데, 그들은 롤케이크의 크기보다 롤케이크 위에 올려진 토핑들의 종류에 더 관심이 많습니다. 
그래서 <code>잘린 조각들의 크기와 올려진 토핑의 개수에 상관없이 각 조각에 동일한 가짓수의 토핑이 올라가면 공평하게 롤케이크가 나누어진 것</code>으로 생각합니다.</p>
<blockquote>
<p>롤케이크에 올려진 토핑들의 번호를 저장한 정수 배열 topping이 매개변수로 주어질 때, 롤케이크를 공평하게 자르는 방법의 수를 return 하도록 solution 함수를 완성해주세요.</p>
</blockquote>
<h3 id="제한사항">제한사항</h3>
<blockquote>
<ul>
<li>1 ≤ topping의 길이 ≤ 1,000,000<ul>
<li>1 ≤ topping의 원소 ≤ 10,000</li>
</ul>
</li>
</ul>
</blockquote>
<h2 id="풀이">풀이</h2>
<h3 id="to-do-리스트">To-Do 리스트</h3>
<ol>
<li>p1에 토핑과 토핑의 수를 저장.</li>
<li>p2에 토핑을 나누면서 p1의 토핑의 수를 감소. 이때 토핑이 0개가 되면 제거.</li>
<li>p1의 갯수와 p2의 갯수가 같아지면 방법의 수를 1씩 증가.<h3 id="결과">결과</h3>
<pre><code class="language-java">import java.util.*;
</code></pre>
</li>
</ol>
<p>class Solution {
    public int solution(int[] topping) {
        int answer = 0;
        // 롤케이크를 두 조각으로 잘라서 동생과 나눠먹을 예정
        // 롤케이크를 공평하게 나눠먹으려 함.
        // 롤케이크의 크기보다 롤케이크 위에 올려진 토핑들의 종류에 더 관심이 많음.
        // ** 잘린 조각들의 크기와 올려진 토핑의 개수에 상관없이 
        //    각 조각에 동일한 가짓수의 토핑이 올라가면 공평하게 롤케이크가 나누어진 것
        Map&lt;Integer,Integer&gt; p1 = new HashMap&lt;&gt;();
        Set<Integer> p2 = new HashSet&lt;&gt;();</p>
<pre><code>    for(int t : topping){
        p1.put(t, p1.getOrDefault(t,0)+1);
    }

    for(int i = 0; i &lt; topping.length; i++){
        int t = topping[i];
        p2.add(t);
        p1.put(t, p1.get(t)-1);
        if(p1.get(t) == 0) p1.remove(t);

        if(p1.size() == p2.size()) answer++;
    }
    return answer;
}</code></pre><p>}</p>
<pre><code></code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스 Lv.2] 숫자 변환하기]]></title>
            <link>https://velog.io/@tanuki_choi/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-Lv.2-%EC%88%AB%EC%9E%90-%EB%B3%80%ED%99%98%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@tanuki_choi/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-Lv.2-%EC%88%AB%EC%9E%90-%EB%B3%80%ED%99%98%ED%95%98%EA%B8%B0</guid>
            <pubDate>Thu, 27 Apr 2023 06:25:55 GMT</pubDate>
            <description><![CDATA[<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/154538">코딩테스트 연습 - 숫자 변환하기</a></p>
<h2 id="문제-설명">문제 설명</h2>
<p>자연수 x를 y로 변환하려고 합니다. 사용할 수 있는 연산은 다음과 같습니다.</p>
<ul>
<li>x에 n을 더합니다</li>
<li>x에 2를 곱합니다.</li>
<li>x에 3을 곱합니다.</li>
</ul>
<blockquote>
<p>자연수 x, y, n이 매개변수로 주어질 때, x를 y로 변환하기 위해 필요한 최소 연산 횟수를 return하도록 solution 함수를 완성해주세요. 이때 x를 y로 만들 수 없다면 -1을 return 해주세요.</p>
</blockquote>
<h3 id="제한사항">제한사항</h3>
<blockquote>
<ul>
<li>1 ≤ x ≤ y ≤ 1,000,000</li>
<li>1 ≤ n &lt; y</li>
</ul>
</blockquote>
<h2 id="풀이">풀이</h2>
<h3 id="to-do-리스트">To-Do 리스트</h3>
<ol>
<li><p>처음 값을 넣고 구하려는 값보다 작거나 같은 수인 경우의 수의 값을 넣음.</p>
</li>
<li><p>작거나 같은 수가 하나도 없는 경우 -1 리턴</p>
</li>
<li><p>같은 수가 있다면 반복한 횟수 출력.</p>
<h3 id="결과">결과</h3>
<pre><code class="language-java">import java.util.*;
class Solution {
 public int solution(int x, int y, int n) {
     int answer = 0;
     // 경우의 수 : 3
     // x+n | x*2 | x*3
     // 최소 연산 횟수 구하기 (단, 만들수 없다면 -1)
     Set&lt;Integer&gt; list = new HashSet&lt;&gt;();
     Set&lt;Integer&gt; tmp = null;
     list.add(x);

     while(!list.isEmpty()){
         tmp = new HashSet&lt;&gt;();
         if(list.contains(y)) break;

         for(int i : list){
             if(i+n &lt;= y) tmp.add(i+n);
             if(i*2 &lt;= y) tmp.add(i*2);
             if(i*3 &lt;= y) tmp.add(i*3);
         }
         list = tmp;
         answer++;
     }
     if(list.isEmpty()) answer = -1;

     return answer;
 }
}</code></pre>
</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스 Lv.2] 2개 이하로 다른 비트]]></title>
            <link>https://velog.io/@tanuki_choi/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-Lv.2-2%EA%B0%9C-%EC%9D%B4%ED%95%98%EB%A1%9C-%EB%8B%A4%EB%A5%B8-%EB%B9%84%ED%8A%B8</link>
            <guid>https://velog.io/@tanuki_choi/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-Lv.2-2%EA%B0%9C-%EC%9D%B4%ED%95%98%EB%A1%9C-%EB%8B%A4%EB%A5%B8-%EB%B9%84%ED%8A%B8</guid>
            <pubDate>Wed, 26 Apr 2023 07:32:54 GMT</pubDate>
            <description><![CDATA[<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/77885">코딩테스트 연습 - 2개 이하로 다른 비트</a></p>
<h2 id="문제-설명">문제 설명</h2>
<p>양의 정수 x에 대한 함수 f(x)를 다음과 같이 정의합니다.
<code>x보다 크고 x와 비트가 1~2개 다른 수들 중에서 제일 작은 수</code></p>
<p>예를 들어,</p>
<p><code>f(2) = 3</code> 입니다.
2보다 큰 수들 중에서 비트가 다른 지점이 2개 이하이면서 제일 작은 수가 3이기 때문입니다.</p>
<table>
<thead>
<tr>
<th align="left">수</th>
<th align="left">비트</th>
<th align="left">다른 비트의 개수</th>
</tr>
</thead>
<tbody><tr>
<td align="left">2</td>
<td align="left">000...0010</td>
<td align="left"></td>
</tr>
<tr>
<td align="left">3</td>
<td align="left">000...0011</td>
<td align="left">1</td>
</tr>
</tbody></table>
<p><code>f(7) = 11</code> 입니다. 
7보다 큰 수들 중에서 비트가 다른 지점이 2개 이하이면서 제일 작은 수가 11이기 때문입니다.</p>
<table>
<thead>
<tr>
<th align="left">수</th>
<th align="left">비트</th>
<th align="left">다른 비트의 개수</th>
</tr>
</thead>
<tbody><tr>
<td align="left">7</td>
<td align="left">000...0111</td>
<td align="left"></td>
</tr>
<tr>
<td align="left">8</td>
<td align="left">000...1000</td>
<td align="left">4</td>
</tr>
<tr>
<td align="left">9</td>
<td align="left">000...1001</td>
<td align="left">3</td>
</tr>
<tr>
<td align="left">10</td>
<td align="left">000...1010</td>
<td align="left">3</td>
</tr>
<tr>
<td align="left">11</td>
<td align="left">000...1011</td>
<td align="left">2</td>
</tr>
</tbody></table>
<blockquote>
<p>정수들이 담긴 배열 numbers가 매개변수로 주어집니다. numbers의 모든 수들에 대하여 각 수의 f 값을 배열에 차례대로 담아 return 하도록 solution 함수를 완성해주세요.</p>
</blockquote>
<h3 id="제한사항">제한사항</h3>
<blockquote>
<ul>
<li>1 ≤ numbers의 길이 ≤ 100,000</li>
<li>0 ≤ numbers의 모든 수 ≤ 10¹⁵</li>
</ul>
</blockquote>
<h2 id="풀이">풀이</h2>
<h3 id="to-do-리스트">To-Do 리스트</h3>
<ol>
<li>기존 수에 1씩 더함.</li>
<li>기존 수와 1를 더한 수를 xor연산, 그 수를 이진법으로 표현</li>
<li>1의 갯수를 세서 2보다 커지면 break.</li>
<li>반복완료 후 2보다 작거나 같은 수인 경우 break.</li>
<li>해당 되지 않는 경우 1를 더함.</li>
<li>반복하여 나온 값을 저장.<h3 id="결과">결과</h3>
<pre><code class="language-java">import java.util.*;
</code></pre>
</li>
</ol>
<p>class Solution {
    public long[] solution(long[] numbers) {
        long[] answer = new long[numbers.length];
        // x보다 크고 x와 비트가 1~2개 다른 수들 중에서 제일 작은 수</p>
<pre><code>    int k = 0;
    for(long num : numbers){
        long ins = num+1L;

        while(true){
            int cnt = 0;
            String str = Long.toBinaryString(num ^ ins);
            char[] crr = str.toCharArray();
            for(char c : crr){
                if(c == &#39;1&#39;) cnt++;
                if(cnt &gt; 2) break;
            }
            if(cnt &lt;= 2) break;
            ins += 1L;
        }
        answer[k++] = ins;
    }
    return answer;
}</code></pre><p>}</p>
<pre><code>
### 알게 된 점
&gt; 💥 테스트 10, 11번 시간초과
&gt; 💥 규칙을 찾아서 실행.

```java
import java.util.*;

class Solution {
    public long[] solution(long[] numbers) {
        long[] answer = new long[numbers.length];
        // x보다 크고 x와 비트가 1~2개 다른 수들 중에서 제일 작은 수

        int k = 0;
        for(long num : numbers){
            String str = Long.toBinaryString(num);
            char[] crr = str.toCharArray();

            int cnt = 0;           
            for(int i = crr.length-1; i &gt;= 0; i--){
                char c = crr[i];
                if(c == &#39;0&#39;) {
                    break;
                }
                cnt++;
            }
            answer[k++] = num+Math.round(Math.pow(2,cnt-1));

        }
        return answer;
    }
}</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스 Lv.2] 가장 큰 수]]></title>
            <link>https://velog.io/@tanuki_choi/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-Lv.2-%EA%B0%80%EC%9E%A5-%ED%81%B0-%EC%88%98</link>
            <guid>https://velog.io/@tanuki_choi/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-Lv.2-%EA%B0%80%EC%9E%A5-%ED%81%B0-%EC%88%98</guid>
            <pubDate>Wed, 26 Apr 2023 05:27:01 GMT</pubDate>
            <description><![CDATA[<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/42746">코딩테스트 연습 - 가장 큰 수</a></p>
<h2 id="문제-설명">문제 설명</h2>
<p>0 또는 양의 정수가 주어졌을 때, 정수를 이어 붙여 만들 수 있는 가장 큰 수를 알아내 주세요.</p>
<p>예를 들어, 주어진 정수가 [6, 10, 2]라면 [6102, 6210, 1062, 1026, 2610, 2106]를 만들 수 있고, 이중 가장 큰 수는 6210입니다.</p>
<blockquote>
<p>0 또는 양의 정수가 담긴 배열 numbers가 매개변수로 주어질 때, 순서를 재배치하여 만들 수 있는 가장 큰 수를 문자열로 바꾸어 return 하도록 solution 함수를 작성해주세요.</p>
</blockquote>
<h3 id="제한사항">제한사항</h3>
<blockquote>
<ul>
<li>numbers의 길이는 1 이상 100,000 이하입니다.</li>
<li>numbers의 원소는 0 이상 1,000 이하입니다.</li>
<li>정답이 너무 클 수 있으니 문자열로 바꾸어 return 합니다.</li>
</ul>
</blockquote>
<h2 id="풀이">풀이</h2>
<h3 id="to-do-리스트">To-Do 리스트</h3>
<ol>
<li><p>숫자를 사전 순으로 정렬.</p>
</li>
<li><p>Comparator를 이용하여 현재 숫자와 이후 숫자를 비교.</p>
</li>
<li><p>단, 0만 나오는 경우 는 수를 연결하지 않음.</p>
<h3 id="결과">결과</h3>
<pre><code class="language-java">import java.util.*;
class Solution {
 public String solution(int[] numbers) {
     String answer = &quot;&quot;;
     List&lt;String&gt; list = new ArrayList&lt;&gt;();
     for(int num : numbers){
         list.add(String.valueOf(num));
     }
     Collections.sort(list, new Comparator&lt;String&gt;(){
         public int compare(String s1, String s2) {
             return (s2+s1).compareTo(s1+s2);
         }
     });

     for(String s: list){
         if(answer.equals(&quot;0&quot;) &amp;&amp; s.equals(&quot;0&quot;)) continue;
         answer += s;
     }
     return answer;
 }
}</code></pre>
</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스 Lv.2] 뒤에 있는 큰 수 찾기]]></title>
            <link>https://velog.io/@tanuki_choi/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-Lv.2-%EB%92%A4%EC%97%90-%EC%9E%88%EB%8A%94-%ED%81%B0-%EC%88%98-%EC%B0%BE%EA%B8%B0</link>
            <guid>https://velog.io/@tanuki_choi/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-Lv.2-%EB%92%A4%EC%97%90-%EC%9E%88%EB%8A%94-%ED%81%B0-%EC%88%98-%EC%B0%BE%EA%B8%B0</guid>
            <pubDate>Thu, 20 Apr 2023 19:09:49 GMT</pubDate>
            <description><![CDATA[<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/154539">코딩테스트 연습 - 뒤에 있는 큰 수 찾기</a></p>
<h2 id="문제-설명">문제 설명</h2>
<p>정수로 이루어진 배열 numbers가 있습니다. 
배열 의 각 원소들에 대해 자신보다 뒤에 있는 숫자 중에서 자신보다 크면서 가장 가까이 있는 수를 뒷 큰수라고 합니다.</p>
<blockquote>
<p>정수 배열 numbers가 매개변수로 주어질 때, 모든 원소에 대한 뒷 큰수들을 차례로 담은 배열을 return 하도록 solution 함수를 완성해주세요. 
단, 뒷 큰수가 존재하지 않는 원소는 -1을 담습니다.</p>
</blockquote>
<h3 id="제한사항">제한사항</h3>
<blockquote>
<ul>
<li>4 ≤ numbers의 길이 ≤ 1,000,000<ul>
<li>1 ≤ numbers[i] ≤ 1,000,000</li>
</ul>
</li>
</ul>
</blockquote>
<h2 id="풀이">풀이</h2>
<h3 id="결과">결과</h3>
<pre><code class="language-java">import java.util.*;

class Solution {
    public int[] solution(int[] numbers) {
        int[] answer = new int[numbers.length];
        int k = 0;
        // 자신보다 1. 뒤에 있는 숫자 중에서 
        // 2. 자신보다 크면서 3. 가장 가까이 있는 수를 뒷 큰수
        // 모든 원소에 대한 뒷 큰수들을 차례로 담은 배열을 return 하도록 solution 함수를 완성
        // 단, 뒷 큰수가 존재하지 않는 원소는 -1
        Arrays.fill(answer, -1);

        for(int i = 0; i &lt; numbers.length-1; i++ ){
            int num = numbers[i];
            int min = Integer.MAX_VALUE;
            for(int j = i+1; j &lt; numbers.length; j++ ){
               int nNum = numbers[j];
               if(num &lt; nNum) {
                   min = nNum;
                   break;
               }
            }
            answer[k++] = min==Integer.MAX_VALUE? -1 : min;
        }
        return answer;
    }
}</code></pre>
<h3 id="알게-된-점">알게 된 점</h3>
<blockquote>
<p>💥 테스트 20 ~ 23 : 시간초과.</p>
</blockquote>
<pre><code class="language-java">import java.util.*;

class Solution {
    public int[] solution(int[] numbers) {
        int[] answer = new int[numbers.length];
        // 자신보다 1. 뒤에 있는 숫자 중에서 
        // 2. 자신보다 크면서 3. 가장 가까이 있는 수를 뒷 큰수
        // 모든 원소에 대한 뒷 큰수들을 차례로 담은 배열을 return 하도록 solution 함수를 완성
        // 단, 뒷 큰수가 존재하지 않는 원소는 -1
        Arrays.fill(answer, -1);

        Stack&lt;Integer&gt; st = new Stack&lt;&gt;();
        for(int i = 0; i &lt; numbers.length; i++){
            int num = numbers[i];
            while(!st.isEmpty() &amp;&amp; numbers[st.peek()] &lt; num){
                answer[st.pop()] = num;  
            }
            st.push(i);
        }
        return answer;
    }
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스 Lv.2] 2 x n 타일링]]></title>
            <link>https://velog.io/@tanuki_choi/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-Lv.2-2-x-n-%ED%83%80%EC%9D%BC%EB%A7%81</link>
            <guid>https://velog.io/@tanuki_choi/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-Lv.2-2-x-n-%ED%83%80%EC%9D%BC%EB%A7%81</guid>
            <pubDate>Tue, 18 Apr 2023 19:07:45 GMT</pubDate>
            <description><![CDATA[<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/12900">코딩테스트 연습 - 2 x n 타일링</a></p>
<h2 id="문제-설명">문제 설명</h2>
<p>가로 길이가 2이고 세로의 길이가 1인 직사각형모양의 타일이 있습니다. 
이 직사각형 타일을 이용하여 세로의 길이가 2이고 가로의 길이가 n인 바닥을 가득 채우려고 합니다. 
타일을 채울 때는 다음과 같이 2가지 방법이 있습니다.</p>
<pre><code>타일을 가로로 배치 하는 경우
타일을 세로로 배치 하는 경우</code></pre><p>예를들어서 n이 7인 직사각형은 다음과 같이 채울 수 있습니다.</p>
<p><img src="https://velog.velcdn.com/images/tanuki_choi/post/25580073-7f2b-40cf-90da-ac32386864d5/image.png" alt=""></p>
<blockquote>
<p>직사각형의 가로의 길이 n이 매개변수로 주어질 때, 이 직사각형을 채우는 방법의 수를 return 하는 solution 함수를 완성해주세요.</p>
</blockquote>
<h3 id="제한사항">제한사항</h3>
<blockquote>
<ul>
<li>가로의 길이 n은 60,000이하의 자연수 입니다.</li>
<li>경우의 수가 많아 질 수 있으므로, 경우의 수를 1,000,000,007으로 나눈 나머지를 return해주세요.</li>
</ul>
</blockquote>
<h2 id="풀이">풀이</h2>
<h3 id="결과">결과</h3>
<pre><code class="language-java">class Solution {
  public static int[] tile;

  public int solution(int n) {
    int answer = 0; 
    tile = new int[60000];
    tile[1] = 1;
    tile[2] = 2;

    for(int i = 3; i &lt;= n; i++) {
      tile[i] = (tile[i-1]+ tile[i-2])%1000000007;
    }

    return tile[n];
  }
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스 Lv.2] [1차] 프렌즈4블록]]></title>
            <link>https://velog.io/@tanuki_choi/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-Lv.2-1%EC%B0%A8-%ED%94%84%EB%A0%8C%EC%A6%884%EB%B8%94%EB%A1%9D</link>
            <guid>https://velog.io/@tanuki_choi/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-Lv.2-1%EC%B0%A8-%ED%94%84%EB%A0%8C%EC%A6%884%EB%B8%94%EB%A1%9D</guid>
            <pubDate>Tue, 18 Apr 2023 18:40:31 GMT</pubDate>
            <description><![CDATA[<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/17679">코딩테스트 연습 - [1차] 프렌즈4블록</a></p>
<h2 id="문제-설명">문제 설명</h2>
<p>블라인드 공채를 통과한 신입 사원 라이언은 신규 게임 개발 업무를 맡게 되었다.
이번에 출시할 게임 제목은 <code>프렌즈4블록 (같은 모양의 카카오프렌즈 블록이 2×2 형태로 4개가 붙어있을 경우 사라지면서 점수를 얻는 게임)</code>이다.</p>
<p><img src="https://velog.velcdn.com/images/tanuki_choi/post/ee7feaa6-84b2-47f9-bbd1-061cab9cdf6b/image.png" alt=""></p>
<pre><code>만약 판이 위와 같이 주어질 경우, 라이언이 2×2로 배치된 7개 블록과 콘이 2×2로 배치된 4개 블록이 지워진다. 
같은 블록은 여러 2×2에 포함될 수 있으며, 지워지는 조건에 만족하는 2×2 모양이 여러 개 있다면 한꺼번에 지워진다.</code></pre><p><img src="https://velog.velcdn.com/images/tanuki_choi/post/01197b93-1f60-48d2-8e39-70f751b30838/image.png" alt=""></p>
<pre><code>블록이 지워진 후에 위에 있는 블록이 아래로 떨어져 빈 공간을 채우게 된다.</code></pre><p><img src="https://velog.velcdn.com/images/tanuki_choi/post/6768d48f-6ed8-4051-b34f-3f65f9fc8055/image.png" alt=""></p>
<pre><code>만약 빈 공간을 채운 후에 다시 2×2 형태로 같은 모양의 블록이 모이면 다시 지워지고 떨어지고를 반복하게 된다.</code></pre><blockquote>
<p>입력으로 블록의 첫 배치가 주어졌을 때, 지워지는 블록은 모두 몇 개인지 판단하는 프로그램을 제작하라.</p>
</blockquote>
<h3 id="입력-형식">입력 형식</h3>
<blockquote>
<ul>
<li>입력으로 판의 높이 m, 폭 n과 판의 배치 정보 board가 들어온다.</li>
<li>2 ≦ n, m ≦ 30</li>
<li>board는 길이 n인 문자열 m개의 배열로 주어진다. 
블록을 나타내는 문자는 대문자 A에서 Z가 사용된다.</li>
</ul>
</blockquote>
<h3 id="출력-형식">출력 형식</h3>
<blockquote>
<ul>
<li>입력으로 주어진 판 정보를 가지고 몇 개의 블록이 지워질지 출력하라.</li>
</ul>
</blockquote>
<h2 id="풀이">풀이</h2>
<h3 id="결과">결과</h3>
<pre><code class="language-java">import java.util.*;

class Solution {
  static boolean[][] visited;

  public int solution(int m, int n, String[] board) {
    int answer = 0;
    char game[][] = new char [m][n];

    // game판에 정보저장.
    for (int i = 0; i &lt; board.length; i++) {
      String b = board[i];
      char[] brr = b.toCharArray();
      for (int j = 0; j &lt; brr.length; j++) {
        char c = brr[j];
        game[i][j] = c;
      }
    }   

    boolean flag = true;
    while(flag) {
      flag = false;
      visited = new boolean[m][n];
      for (int i = 0; i &lt; m - 1; i++) {
        for (int j = 0; j &lt; n - 1; j++) {
          if(game[i][j] == &#39;#&#39;) continue;
          if (check(i,j,game)) {
            visited[i][j] = true;
            visited[i + 1][j] = true;
            visited[i][j + 1] = true;
            visited[i + 1][j + 1] = true;
            flag = true;
          }
        }
      }
      answer = remove(m,n,game);
      visited = new boolean[m][n];
    }

    return answer;
  }

  private static boolean check(int x, int y, char[][] game) {
    char ch = game[x][y];
    if(ch == game[x][y+1] &amp;&amp; ch== game[x+1][y] &amp;&amp; ch == game[x+1][y+1]){
        return true;
    }
    return false;
  }

  private static int remove(int m, int n, char[][] game) {
    int cnt = 0;
    for(int i=0; i&lt;m; i++){
        for(int j=0; j&lt;n; j++){
            if(visited[i][j]) game[i][j] = &#39;#&#39;;
        }
    }

    for(int i=0; i&lt;n; i++) {
      Queue&lt;Character&gt; que = new LinkedList&lt;&gt;();
      for(int j=m-1; j&gt;=0; j--) {
        if(game[j][i] == &#39;#&#39;) cnt++;
        else que.add(game[j][i]);
      }
      int idx = m-1;
      while(!que.isEmpty()) {
        game[idx--][i] = que.poll();
      }
      for(int j = idx; j &gt;= 0; j--) {
        game[j][i] = &#39;#&#39;;
      }
    }
    return cnt;
  }
}</code></pre>
<h3 id="알게-된-점">알게 된 점</h3>
<blockquote>
<p>💥 객체지향적사고방식으로 풀어보자.</p>
</blockquote>
]]></description>
        </item>
    </channel>
</rss>