<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>소냐쿠의 개발괴발</title>
        <link>https://velog.io/</link>
        <description>백엔드 엔지니어 프로 지망생</description>
        <lastBuildDate>Thu, 29 Jun 2023 02:03:18 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>소냐쿠의 개발괴발</title>
            <url>https://velog.velcdn.com/images/sonyak-ku/profile/a42ae814-c2cc-449a-9be3-06aa4d52d0e0/social_profile.jpeg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. 소냐쿠의 개발괴발. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/sonyak-ku" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[톰캣 웹서버 글자 깨짐 현상]]></title>
            <link>https://velog.io/@sonyak-ku/%ED%86%B0%EC%BA%A3-%EC%9B%B9%EC%84%9C%EB%B2%84-%EA%B8%80%EC%9E%90-%EA%B9%A8%EC%A7%90-%ED%98%84%EC%83%81</link>
            <guid>https://velog.io/@sonyak-ku/%ED%86%B0%EC%BA%A3-%EC%9B%B9%EC%84%9C%EB%B2%84-%EA%B8%80%EC%9E%90-%EA%B9%A8%EC%A7%90-%ED%98%84%EC%83%81</guid>
            <pubDate>Thu, 29 Jun 2023 02:03:18 GMT</pubDate>
            <description><![CDATA[<p>톰캣 콘솔과 톰캣 웹서버 페이지에서 디비를 읽었을 때 글자가 깨져서 읽힌다.
<img src="https://velog.velcdn.com/images/sonyak-ku/post/78d15368-5a3f-45bd-becc-d1dd8d5ff753/image.png" alt=""></p>
<p>아래와 같이 읽혀야 되는데, 위에 처럼 글이 깨져서 읽히기 때문에 db 에 데이터를 넣지도 못하고 있다(저 깨진 값으로 데이터가 들어간다). </p>
<hr>
<h3 id="troubleshooting">TroubleShooting</h3>
<p><a href="https://blog.naver.com/baekmg1988/221302236018">https://blog.naver.com/baekmg1988/221302236018</a></p>
<p>위의 블로그에서 하라는 것 다 해봤다. 그런데 안된다.</p>
<blockquote>
<p>해결 방법은 jvm option 에 -Dfile.encoding=UTF-8  을 추가했다.
이클립스 기준 상단의 Run - Run Configurations - tomcat 버전 - Arguments 로 접근 가능</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[Unrecognized option: --add-opens when passed with _JAVA_OPTIONS]]></title>
            <link>https://velog.io/@sonyak-ku/Unrecognized-option-add-opens-when-passed-with-JAVAOPTIONS</link>
            <guid>https://velog.io/@sonyak-ku/Unrecognized-option-add-opens-when-passed-with-JAVAOPTIONS</guid>
            <pubDate>Wed, 21 Jun 2023 12:11:08 GMT</pubDate>
            <description><![CDATA[<p><em>이클립스로 톰캣을 구동했는데 이런 오류 메시지가 나왔다.</em></p>
<blockquote>
<p>Starting Apache Tomcat v8.5 at localhost&#39; has encountered a problem. 
Server Apache Tomcat v8.5 at localhost failed to start.</p>
</blockquote>
<p>그리고 콘솔에 찍힌 에러메시지는 제목과 같았다.</p>
<p>구글링 해본 결과 자바 8버전에서는 --add-opens 라는 옵션이 없기 때문에 에러가 나는 것.
<a href="https://www.ibm.com/support/pages/build-fails-unrecognized-option-add-opens">참고링크</a></p>
<p>따라서 jvm 에 넘겨지는 argument 값을 수정해야만 했다.</p>
<h3 id="eclipse-기준">[eclipse 기준]</h3>
<h3 id="run---run-configurations---tomcat-v---arguments---vm-arguments">run - run configurations - tomcat v.?.?~ - Arguments - VM Arguments</h3>
<h3 id="에서---add-opens-가-붙은-옵션들을-모두-제거해준다">에서 --add-opens 가 붙은 옵션들을 모두 제거해준다</h3>
<p>그러면 해결 완료!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Jakarta 9 와 tomcat 9]]></title>
            <link>https://velog.io/@sonyak-ku/Jakarta-9-%EC%99%80-tomcat-9</link>
            <guid>https://velog.io/@sonyak-ku/Jakarta-9-%EC%99%80-tomcat-9</guid>
            <pubDate>Tue, 20 Jun 2023 20:43:15 GMT</pubDate>
            <description><![CDATA[<p>_아니 제로베이스에서 내준 숙제를 하려고 처음으로 웹 어플리케이션 서버를 띄워서 작업을 해보려고 했는데, 인텔리제이 울트라 버전에서는 내 눈에는 일단 JavaEE 는 없었고, JakartaEE 만 선택가능해 보였다. _</p>
<hr>
<p>default 로 띄워진 코드들을 가볍게 구동했는데, jsp 파일은 되는데 거기에 a 태그로 연결된 servlet 은 404 에러가 뜨더라.</p>
<p>알고보니 Jakarta 9 버전에서는 </p>
<p><img src="https://velog.velcdn.com/images/sonyak-ku/post/d5a460f7-f3c7-4ce3-a88b-9765ad52c123/image.png" alt=""></p>
<p>Jakarta.servlet 5.0 버전 스펙을 사용하고, 이것은 tomcat 10 버전부터 구현이 되어있다고 한다.</p>
<p>내가 이용하고 있는 tomcat 9 버전에서는 그렇기 때문에 404 오류가 났던것이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Comparator Interface 공부]]></title>
            <link>https://velog.io/@sonyak-ku/Comparator-Interface-%EA%B3%B5%EB%B6%80</link>
            <guid>https://velog.io/@sonyak-ku/Comparator-Interface-%EA%B3%B5%EB%B6%80</guid>
            <pubDate>Sat, 17 Jun 2023 18:05:14 GMT</pubDate>
            <description><![CDATA[<p>순서를 비교하고 싶을 때가 있다. 대상이 숫자라면 단순하게 크기를 비교하면 되겠지만, 객체라면 <strong>어떻게 비교를 해야 하지?</strong> 라는 질문이 우선한다.</p>
<p>우리는 우선 객체의 <strong>어떤 것</strong> 을 기준으로 하여 비교를 할 지 정해야 한다.</p>
<p>그리고 그것을 가능하게 하는 자바 구현체가 바로 <strong>Comparator Interface</strong> 이다.</p>
<hr>
<pre><code class="language-java">@FunctionalInterface
public interface Comparator&lt;T&gt; {
     int compare(T o1, T o2);
}</code></pre>
<p><strong>FuntionalInterface Annotation ** 이 붙어 있는 것을 확인 할 수 있다.
Interface 가 하나의 abstract method  만을 가질 때 **FuntionalInterface</strong> 가 붙는다.</p>
<p>abstract 함수를 보면 제네릭한 T 타입의 인자 o1 과 o2 를 넘겨받아 int 를 리턴하는 형태를  볼 수 있다.</p>
<p>그리고 리턴된 int 로 우리는 비교 결과를 알 수 있다.</p>
<blockquote>
<p>compare 함수의 리턴값 int 로 우리는 비교 결과를 알 수 있다</p>
</blockquote>
<ul>
<li>음수면 o1 &lt; o2</li>
<li>0 일 경우 o1 = o2</li>
<li>양수면 o1 &gt; o2 </li>
</ul>
<br>

<p><strong>Comparator</strong> 를 사용할 때를 가정해서 풀어서 쓰자면, </p>
<p>오름차순으로 <strong>sort</strong> 하는 상황에서 <strong>o1 이 o2 보다 앞에 배치</strong>되야 할 때는 </p>
<p><strong>compare 함수</strong>가 o1, o2 를 인자로 받고 <strong>음수를 리턴</strong>해주어야 된다 고 파악할 수 있다</p>
<hr>
<h2 id="compartor-사용해보기">Compartor 사용해보기</h2>
<br>

<p>우선 아래와 같은 Human 클래스를 만들어 준다. 내부에 이름, 키, 나이 필드를 가지고 있다.
또한 getter 만 사용할 것이고, println 찍기 편하라고 toString 함수도 재정의 하였다.</p>
<pre><code class="language-java">public class Human {
    String name;
    int height;
    int age;

    public Human(String name, int height, int age) {
        this.name = name;
        this.height = height;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getHeight() {
        return height;
    }

    public int getAge() {
        return age;
    }

    @Override
    public String toString() {
        return &quot;Human{&quot; +
                &quot;name=&#39;&quot; + name + &#39;\&#39;&#39; +
                &quot;, height=&quot; + height +
                &quot;, age=&quot; + age +
                &#39;}&#39;;
    }
}
</code></pre>
<p>메인함수에서 Humans 객체들만을 담는 Humans 라는 리스트를 만들어서 값을 일부 담아보았다.</p>
<pre><code class="language-java">public class Main {
    public static void main(String[] args) {
        List&lt;Human&gt; humans = new ArrayList&lt;&gt;();
        humans.add(new Human(&quot;Alice&quot;, 165, 18));
        humans.add(new Human(&quot;Chalie&quot;, 180, 25));
        humans.add(new Human(&quot;Jackson&quot;, 170, 15));
        humans.add(new Human(&quot;Joy&quot;, 177, 19));
    }
}</code></pre>
<p>이제 humans 리스트에 있는 Human 객체들을 이름 순으로, 나이 순으로, 키 순으로 정렬해볼 것이다.</p>
<p>정렬할 때 사용할 함수는 Collections 가 제공하는 sort 함수이다.</p>
<p>함수를 찾아 들어가보면 요렇게 되어있다.</p>
<pre><code class="language-java">public static &lt;T&gt; void sort(List&lt;T&gt; list, Comparator&lt;? super T&gt; c) {
           list.sort(c);
}</code></pre>
<p>제네릭한 T 타입의 리스트와,
제네릭한 T 타입 또는 그 super 클래스 타입들을 인자로 받는 Comparator c 를 
파라미터로 받는다.</p>
<blockquote>
</blockquote>
<p>Params c – the Comparator used to compare list elements. A null value indicates that the elements&#39; natural ordering should be used.</p>
<p>쉽게말해, <strong>Comparator 가 알려준 방식으로 순서 비교를 하여 정렬하겠다</strong> 라는 뜻이다</p>
<p>위에 서두에서 말했듯이, 단순한 int 라면 숫자의 크기 비교를 통해서 순서비교가 가능하겠지만, 객체라면, 객체의 어떤 속성으로 어떻게 비교를 할지 우리가 따로 정해야 한다. Comparator 는 이런 상황에서 사용하는 것이다.</p>
<p>그럼 사용해보자</p>
<pre><code class="language-java">System.out.println(&quot;Before sort&quot;);
System.out.println(humans);

Comparator&lt;Human&gt; comparateAge = (Human h1, Human h2) -&gt; {
      return h1.getAge() - h2.getAge();
}; 

Collections.sort(humans, comparateAge);
System.out.println(&quot;After sort&quot;);
System.out.println(humans);</code></pre>
<p>위에서는 람다식으로 Comparator 를 구현한 익명함수를 만들어서 사용하였다. 하지만 따로 클래스를 구현하여 사용하여도 무방.</p>
<p>Compare 함수의 리턴값을 Human 객체들의 나이의 차이로 리턴한 것을 볼 수 있다.</p>
<p>만약 h1 이 나이가 더 작다면, 음수가 리턴되고, h1 은 h2 보다 앞에 위치하게 되는 방식이다.(h1 이 더 작다고 판단)</p>
<p>실행 결과는 아래처럼, 나이로 잘 정렬되어 나오는 것을 볼 수 있다.</p>
<p><img src="https://velog.velcdn.com/images/sonyak-ku/post/fce6e3c0-c0b5-4893-aaa0-aa11555bb835/image.png" alt=""></p>
<p>이름 으로 정렬하는 경우는 조금 다르다.</p>
<p>String 에서 제공하는 compareTo 메소드를 사용해야 한다.</p>
<pre><code class="language-java">public class Main {
    public static void main(String[] args) {
        List&lt;Human&gt; humans = new ArrayList&lt;&gt;();

        humans.add(new Human(&quot;Joy&quot;, 177, 19));
        humans.add(new Human(&quot;Chalie&quot;, 180, 25));
        humans.add(new Human(&quot;Jackson&quot;, 170, 15));
        humans.add(new Human(&quot;Alice&quot;, 165, 18));

        System.out.println(&quot;Before sort&quot;);
        System.out.println(humans);

        Comparator&lt;Human&gt; comparateAge = (Human h1, Human h2) -&gt; h1.getName().compareTo(h2.getName());


        Collections.sort(humans, comparateAge);
        System.out.println(&quot;After sort&quot;);
        System.out.println(humans);


    }
}
</code></pre>
<p>String 의 compareTo 메소드는 알파벳 어순을 비교해, 어순이 더 빠를 때에는 음수를 리턴해 준다.</p>
<p>결과는 역시 잘 알파벳 이름 순으로 정렬되어 나오는 것을 확인 할 수 있다.</p>
<p><img src="https://velog.velcdn.com/images/sonyak-ku/post/cdd673b2-59df-44b7-b46c-c3df65115da2/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[자주 사용할 계산식은 변수로 잡자.]]></title>
            <link>https://velog.io/@sonyak-ku/%EC%9E%90%EC%A3%BC-%EC%82%AC%EC%9A%A9%ED%95%A0-%EA%B3%84%EC%82%B0%EC%8B%9D%EC%9D%80-%EB%B3%80%EC%88%98%EB%A1%9C-%EC%9E%A1%EC%9E%90</link>
            <guid>https://velog.io/@sonyak-ku/%EC%9E%90%EC%A3%BC-%EC%82%AC%EC%9A%A9%ED%95%A0-%EA%B3%84%EC%82%B0%EC%8B%9D%EC%9D%80-%EB%B3%80%EC%88%98%EB%A1%9C-%EC%9E%A1%EC%9E%90</guid>
            <pubDate>Sat, 17 Jun 2023 12:06:12 GMT</pubDate>
            <description><![CDATA[<p>*<em>프로그래머스 문제를 풀던 중, 연산을 변수 처리 해야만 끝자락에서 테스트 케이스 시간초과를 당하지 않는 경우를 만났다.
*</em></p>
<pre><code class="language-java">class Solution {
    public int[][] solution(int[][] image, int K) {
        int[][] answer = new int[image.length][image[0].length];
        int t = K / 2;

        for (int r = 0; r &lt; image.length; r++) {
            for (int c = 0; c &lt; image[0].length; c++) {
                int sum = 0;
                for (int i = t; i &gt;= -t; i--) {
                    for (int j = t; j &gt;= -t; j--) {
                        int nr = r - i;
                        int nc = c - j;

                        if (nr &gt;= 0 &amp;&amp; nc &gt;= 0 &amp;&amp; nr &lt; image.length &amp;&amp; nc &lt; image[0].length) {
                            sum += image[nr][nc];
                        } // 조건문 접근
                    }
                }

                answer[r][c] = sum / (K * K);
            }
        }
        return answer;
    }
}</code></pre>
<p><strong>위의 코드에서 조건문에 접근하는 image.length 와 image[0].length 를 접근할 때 드는 비용도 아래처럼 변수화를 시켜야만 테스트 효율성 테스트에서 통과하는 경우를 만났다. 앞으로 이런 부분은 꼼꼼하게 체크해야 될 듯 하다.</strong></p>
<pre><code class="language-java">class Solution {
    public int[][] solution(int[][] image, int K) {
        int width = image.length; // 변수처리
        int height = image[0].length; // 변수처리

        int[][] answer = new int[width][height];
        int t = K / 2;

        for (int r = 0; r &lt; width; r++) {
            for (int c = 0; c &lt; height; c++) {
                int sum = 0;
                for (int i = t; i &gt;= -t; i--) {
                    for (int j = t; j &gt;= -t; j--) {
                        int nr = r - i;
                        int nc = c - j;

                        if (nr &gt;= 0 &amp;&amp; nc &gt;= 0 &amp;&amp; nr &lt; width &amp;&amp; nc &lt; height) {
                            sum += image[nr][nc];
                        } 
                    }
                }

                answer[r][c] = sum / (K * K);
            }
        }
        return answer;
    }
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[반복문 조건 배치의 중요성(?)]]></title>
            <link>https://velog.io/@sonyak-ku/%EB%B0%98%EB%B3%B5%EB%AC%B8-%EC%A1%B0%EA%B1%B4-%EB%B0%B0%EC%B9%98%EC%9D%98-%EC%A4%91%EC%9A%94%EC%84%B1</link>
            <guid>https://velog.io/@sonyak-ku/%EB%B0%98%EB%B3%B5%EB%AC%B8-%EC%A1%B0%EA%B1%B4-%EB%B0%B0%EC%B9%98%EC%9D%98-%EC%A4%91%EC%9A%94%EC%84%B1</guid>
            <pubDate>Thu, 15 Jun 2023 08:58:59 GMT</pubDate>
            <description><![CDATA[<p>문제를 푸는데 내가 예상하지 못했던 IndexOutOfBoundsException 이 뜨길래, 너무 답답해서 인텔리제이로 디버깅을 시도하였다.</p>
<p>그런데..</p>
<p>원래 짰던 코드가 아래와 같았다. </p>
<p>_나름 times 배열에 접근하는 cur 인덱스가 배열의 크기를 넘지 않도록 종료 조건을 주었다 생각했지만, 
디버깅을 해보니 cur = times.length 인 상태의 루프가 끝나고나서
종료조건을 체크하기 위해서 cur 이 배열이 크기를 1 넘은 상태에서 
time[cur] == 0 이라는 첫번째 조건에 접근하드라..
_</p>
<pre><code class="language-java">while (times[cur] == 0 &amp;&amp; cur &lt; times.length) {
      cur++;
      bag++;
}</code></pre>
<hr>
<p>_그래서 아래와 같이 종료 조건의 순서를 다르게 배치해서 가장 먼저 걸리는 조건을 배열의 인덱스 사이즈를 넘지 않는 조건으로 수정하지 오류가 해결되었다.</p>
<p>이제야.. 알아서 다행이다 ㅠㅠ_</p>
<pre><code class="language-java">while (cur &lt; times.length &amp;&amp; times[cur] == 0) {
      cur++;
      bag++;
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[DB 쿼리문 연습 (6)]]></title>
            <link>https://velog.io/@sonyak-ku/DB-%EC%BF%BC%EB%A6%AC%EB%AC%B8-%EC%97%B0%EC%8A%B5-6</link>
            <guid>https://velog.io/@sonyak-ku/DB-%EC%BF%BC%EB%A6%AC%EB%AC%B8-%EC%97%B0%EC%8A%B5-6</guid>
            <pubDate>Wed, 14 Jun 2023 05:19:51 GMT</pubDate>
            <description><![CDATA[<p>배운 쿼리</p>
<ul>
<li>distinct 함수</li>
<li>join</li>
<li>union</li>
<li>sub query 사용하기</li>
<li>ifnull 함수 : ifnull(체크대상, null 일 때 부여할 값)</li>
<li>페이징 처리는?</li>
<li>group_concat 함수</li>
</ul>
<hr>
<pre><code class="language-sql">/*
26. 제주도에 위치한 상영관을 좌석수가 많은 순서로 정렬하는 SQL문을 작성해 보세요.
[관련내용] order by 문
27. 한국에서 개최되는 주요 축제가 개최된 도시의 상영관 수를 각각 조회하는 SQL문을 작성해
주세요.
[관련내용] ifnull() 함수, sum() 함수, concat() 함수, left join 문, group by 문, 서브 쿼리 문
28. 새로운 축제를 등록하기 위해서 code값의 최대값에 + 1을 더한 신규 코드값을 가져오는 SQL
문을 작성해 보세요.
[관련내용] row_number(), max() 함수, group by, order by
29. 한국 배우중에서 이름과 영문이름이 존재하고, 생년월일 데이터가 정확한 배우의 전체
개수와 이름 순으로 20개 단위로 페이징 처리하기 위한 SQL문을 작성해 주세요.
[관련내용] count() 함수, trim() 함수, length() 함수, str_to_date() 함수, row_number() 함수, order
by 구문, limit 구문
30. 영화인이 속한 국가와 축제가 진행되는 국가 모두를 표시하는 SQL문을 작성해 주세요.
[관련내용] distinct, union, is not null 구문, trim() 함수
31. 한국의 감독 중에서 이름, 영문이름이 모두 있고, 생년월일이 정확하며 1990년에 출생한
감독들의 작품중에서 한국에서 개봉한 영화제목을 보여주는 SQL문을 작성해 보세요.(영화가
여러개인 경우 콤마(,)를 이용해서 한 컬럼에 표시해 주세요.)
[관련내용] group_concat() 함수, is not null 구문, trim() 함수, length() 함수, str_to_date() 함수,
year() 함수, order by 구문
32. 영화인 정보중 감독이 &#39;강우석&#39; 이면서 제작한 영화 목록을 년도순으로 조회하는 SQL문을
작성해 주세요.
[관련내용] in 구문, order by 구문
*/

# 26. 제주도에 위치한 상영관을 좌석수가 많은 순서로 정렬하는 SQL문을 작성해 보세요.
# [관련내용] order by 문

select *
from screen
where sido like &#39;%제주%&#39;
order by seat_count desc
;

# 27. 한국에서 개최되는 주요 축제가 개최된 도시의 상영관 수를 각각 조회하는 SQL문을 작성해
# 주세요.
# [관련내용] ifnull() 함수, sum() 함수, concat() 함수, left join 문, group by 문, 서브 쿼리 문


select f1.*,
       sum(f2.screen_count) as total_screen_count
from
(
    select concat(city, &#39;시&#39;) as city
    from festival
    where country = &#39;한국&#39; and
        important_flag = &#39;예&#39;
) f1
    join (
    select case
        when sido like &#39;%시&#39; then sido
        when gugun like &#39;%시&#39; then gugun
        else &#39;없는시&#39;
        end as sigu,
    screen_name,
    screen_count,
    seat_count
    from screen
    ) f2
        on f2.sigu = f1.city
group by sigu
;


select *
from screen;
# 28. 새로운 축제를 등록하기 위해서 code값의 최대값에 + 1을 더한 신규 코드값을 가져오는 SQL
# 문을 작성해 보세요.
# [관련내용] row_number(), max() 함수, group by, order by
select max(code) + 1 as max_code
from festival
;

# 29. 한국 배우중에서 이름과 영문이름이 존재하고, 생년월일 데이터가 정확한 배우의 전체
# 개수와 이름 순으로 20개 단위로 페이징 처리하기 위한 SQL문을 작성해 주세요.
# [관련내용] count() 함수, trim() 함수, length() 함수, str_to_date() 함수, row_number() 함수, order
# by 구문, limit 구문

select t2.*
from
(
    select t1.*
    from
    (
        select row_number() over (order by name) as ranking
                 , a.*
            from actor a
            where char_length(trim(name)) &lt;&gt; 0
              and char_length(trim(eng_name)) &lt;&gt; 0
              and length(birth) = 10
              and str_to_date(birth, &#39;%Y-%m-%d&#39;) is not null
              and country = &#39;한국&#39;
              and domain = &#39;배우&#39;
            limit 20, 10
    ) t1
    where t1.ranking &lt; 30
) t2
where t2.ranking &gt;= 20
;

# 30. 영화인이 속한 국가와 축제가 진행되는 국가 모두를 표시하는 SQL문을 작성해 주세요.
# [관련내용] distinct, union, is not null 구문, trim() 함수

select distinct (country)
from actor
where country is not null and
      trim(country) &lt;&gt; &#39;&#39;
union

select distinct(country)
from festival
where country is not null and
      trim(country) &lt;&gt; &#39;&#39;
;

# 31. 한국의 감독 중에서 이름, 영문이름이 모두 있고, 생년월일이 정확하며 1990년에 출생한
# 감독들의 작품중에서 한국에서 개봉한 영화제목을 보여주는 SQL문을 작성해 보세요.(영화가
# 여러개인 경우 콤마(,)를 이용해서 한 컬럼에 표시해 주세요.)
# [관련내용] group_concat() 함수, is not null 구문, trim() 함수, length() 함수, str_to_date() 함수,
# year() 함수, order by 구문



select a.*,
       (
        select group_concat(m.title)
        from movie m
        where m.director = a.name and
              m.open_flag = &#39;개봉&#39;
        )  as title
from actor a
where country = &#39;한국&#39; and
      domain = &#39;감독&#39; and
      name is not null and char_length(trim(name)) &lt;&gt; 0 and
      eng_name is not null and char_length(trim(eng_name)) &lt;&gt; 0 and
      year(str_to_date(birth, &#39;%Y-%m-%d&#39;)) = 1990
;

# 32. 영화인 정보중 감독이 &#39;강우석&#39; 이면서 제작한 영화 목록을 년도순으로 조회하는 SQL문을
# 작성해 주세요.
# [관련내용] in 구문, order by 구문


select *
from movie
where director in (&#39;강우석&#39;)
order by pub_year
;</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[DB 쿼리문 연습 (5)]]></title>
            <link>https://velog.io/@sonyak-ku/DB-%EC%BF%BC%EB%A6%AC%EB%AC%B8-%EC%97%B0%EC%8A%B5-5</link>
            <guid>https://velog.io/@sonyak-ku/DB-%EC%BF%BC%EB%A6%AC%EB%AC%B8-%EC%97%B0%EC%8A%B5-5</guid>
            <pubDate>Tue, 13 Jun 2023 16:32:08 GMT</pubDate>
            <description><![CDATA[<p><strong>배운 쿼리</strong></p>
<ul>
<li>ceil 함수, floor 함수, round 함수 - 각각 소수점 올림, 버림, 반올림</li>
</ul>
<hr>
<pre><code class="language-sql">/*
21. 한국인 이면서 &#39;원&#39;씨 성을 가진 배우를 조회하는 SQL문을 작성해 주세요.
[관련내용] like 문, 와일드카드 %
22. 대전시에 있는 상영관 중에서 좌석 수가 500 ~ 1000 사이인 극장의 이름을 조회하는
SQL문을 작성해 주세요.
[관련내용] between a and b 구문
23. 시도별 상영관의 전체 좌석 수, 최대 좌석 수, 최소 좌석 수, 평균 좌석 수 내용을 조회하는
SQL문을 작성해 주세요.(단, 좌석 수가 0인 상영관은 제외하고, 평균 좌석 수는 소수점 올림으로
처리해 주세요.)
[관련내용] sum ()함수, max() 함수, min() 함수, avg() 함수, ceil() 함수, group by 구문
24. 시도별 평균 좌석수가 900 이상인 상영관을 구하는 SQL문을 작성해 주세요.(다, 시도별 평균
좌석 수는 소수점 2자리까지 반올림해서 표현해 주세요.)
[관련내용] round() 함수, avg() 함수, group by 구문, having 구문
25. 영화인 중에서 생일을 알고 있고, 3월에 태어난 사람 중 직업이 감독인 사람의 한글이름,
영문이름을 조회하여, 출신국가는 한국이면, &#39;국내&#39;, 한국이 아니면 &#39;국외&#39;로 표시하는 SQL문을
작성해 주세요.
[관련내용] case 문, length() 함수, trim() 함수, str_to_date() 함수
*/

# 21. 한국인 이면서 &#39;원&#39;씨 성을 가진 배우를 조회하는 SQL문을 작성해 주세요.
# [관련내용] like 문, 와일드카드 %

select *
from actor
where country = &#39;한국&#39; and
      name like &#39;원%&#39;
;

# 22. 대전시에 있는 상영관 중에서 좌석 수가 500 ~ 1000 사이인 극장의 이름을 조회하는
# SQL문을 작성해 주세요.
# [관련내용] between a and b 구문

select screen_name
from screen
where sido = &#39;대전시&#39; and
      seat_count between 500 and 1000
;

# 23. 시도별 상영관의 전체 좌석 수, 최대 좌석 수, 최소 좌석 수, 평균 좌석 수 내용을 조회하는
# SQL문을 작성해 주세요.(단, 좌석 수가 0인 상영관은 제외하고, 평균 좌석 수는 소수점 올림으로
# 처리해 주세요.)

-- 반올림은 round, 올림은 어떻게? -&gt; ceil, 내림은 -&gt; floor
select sum(seat_count) as whole_seat,
       max(seat_count) as max_seat,
       min(seat_count) as min_seat,
       ceiling(avg(seat_count)) as avg_seat
from screen
where seat_count &gt; 0
group by sido
;

# 24. 시도별 평균 좌석수가 900 이상인 상영관을 구하는 SQL문을 작성해 주세요.(다, 시도별 평균
# 좌석 수는 소수점 2자리까지 반올림해서 표현해 주세요.)
# [관련내용] round() 함수, avg() 함수, group by 구문, having 구문

select sido,
       gugun,
       screen_name,
       round(avg(seat_count), 1) as avg_seat_count
from screen
group by sido
having avg_seat_count &gt;= 900
;

# 25. 영화인 중에서 생일을 알고 있고, 3월에 태어난 사람 중 직업이 감독인 사람의 한글이름,
# 영문이름을 조회하여, 출신국가는 한국이면, &#39;국내&#39;, 한국이 아니면 &#39;국외&#39;로 표시하는 SQL문을
# 작성해 주세요.
# [관련내용] case 문, length() 함수, trim() 함수, str_to_date() 함수

select name,
       eng_name,
        case
            when country = &#39;한국&#39; then &#39;국내&#39;
            else &#39;국외&#39;
        end as nation,
        birth
from actor
where birth is not null and
      str_to_date(birth, &#39;%Y-%m-%d&#39;) is not null and
      month(str_to_date(birth, &#39;%Y-%m-%d&#39;)) = 3 and
      domain = &#39;감독&#39;
;</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[DB 쿼리문 연습 (4)]]></title>
            <link>https://velog.io/@sonyak-ku/DB-%EC%BF%BC%EB%A6%AC%EB%AC%B8-%EC%97%B0%EC%8A%B5-4</link>
            <guid>https://velog.io/@sonyak-ku/DB-%EC%BF%BC%EB%A6%AC%EB%AC%B8-%EC%97%B0%EC%8A%B5-4</guid>
            <pubDate>Tue, 13 Jun 2023 15:02:19 GMT</pubDate>
            <description><![CDATA[<p><strong>배운 쿼리</strong></p>
<ul>
<li>char_length 함수 : length 함수는 BYTE 길이를 가져온다. </li>
<li>rpad 함수</li>
<li>substring 함수</li>
<li><ul>
<li>substring(str, pos) : str 의 pos 의 위치에서 모든 문자를 읽는다.</li>
</ul>
</li>
<li><ul>
<li>substring(str, pos, len) :  str  의 pos 의 위치에서 len 개의 문자를 읽는다.</li>
</ul>
</li>
<li>wildcard 로 쓰일때의 언더바</li>
<li>rpad 함수 </li>
</ul>
<hr>
<pre><code class="language-sql">/*
16. 전국의 CGV 극장의 이름과 규모를 조회하되 규모는 스크린 수가 5보다 작으면 &#39;소&#39;, 5보다
크거나 같고 10보 작으면 &#39;중&#39;, 10보다 크거나 같으면 &#39;대&#39;로 표시하는 SQL문을 작성해 주세요.
[관련내용] case 문, like
17. 출신지가 프랑스나 이탈리아 이면서 직업이 촬영이거나 편집인 영화인을 조회하는
SQL문을 작성해 주세요.
[관련내용] and 조건, or 조건, in 조건
18. 2010년 ~ 2020년 기간중 연도별로 상영된 영화의 수를 조회하는 SQL문을 작성해 주세요.
[관련내용] count() 함수, between a and b 구문
19. 한국인 중에서 직업이 배우인 사람의 이름을 조회하되, 개인정보 보호를 위해서 이름
중간에 &#39;*&#39; 처리를 통하여 이름이 전체적으로 노출되지 않도록 처리해 주세요.(단, 이름은
적어도 2개 이상의 문자이고 외자인 경우 성만 표시하며 4자인 경우는 성과 맨 마지막만
보여주며, 그 이상인 이름의 경우는 첫 성만 보여주고 나머지는 마스크(*) 처리해 주세요.)
[관련내용] length()함수, trim()함수, char_length()함수, rpad()함수, substring()함수
20. 한국인 이면서 &#39;배&#39;씨 성을 가진 사람 중에 &#39;준&#39;으로 끝나는 이름을 가진 영화인을 조회하는
SQL문을 작성해 주세요.(이름은 3자인 영확인을 구하세요.)
[관련내용] like 문, 와일드카드 _
*/

# 16. 전국의 CGV 극장의 이름과 규모를 조회하되 규모는 스크린 수가 5보다 작으면 &#39;소&#39;, 5보다
# 크거나 같고 10보 작으면 &#39;중&#39;, 10보다 크거나 같으면 &#39;대&#39;로 표시하는 SQL문을 작성해 주세요.
# [관련내용] case 문, like

select sido,
       gugun,
       screen_name,
       case when screen_count &lt; 5 then &#39;소&#39;
        when screen_count &lt; 10 then &#39;중&#39;
        else &#39;대&#39;
        end as gyumo,
    screen_count

from screen
where screen_name like &#39;%CGV%&#39;
order by screen_count
;

# 17. 출신지가 프랑스나 이탈리아 이면서 직업이 촬영이거나 편집인 영화인을 조회하는
# SQL문을 작성해 주세요.
# [관련내용] and 조건, or 조건, in 조건

select *
from actor
where country in (&#39;프랑스&#39;, &#39;이탈리아&#39;) and
      domain in (&#39;촬영&#39;, &#39;편집&#39;)
;

# 18. 2010년 ~ 2020년 기간중 연도별로 상영된 영화의 수를 조회하는 SQL문을 작성해 주세요.
# [관련내용] count() 함수, between a and b 구문

select pub_year,
       count(*)
from movie
where pub_year between 2010 and 2020
group by pub_year
;


# 19. 한국인 중에서 직업이 배우인 사람의 이름을 조회하되, 개인정보 보호를 위해서 이름
# 중간에 &#39;*&#39; 처리를 통하여 이름이 전체적으로 노출되지 않도록 처리해 주세요.(단, 이름은
# 적어도 2개 이상의 문자이고 외자인 경우 성만 표시하며 4자인 경우는 성과 맨 마지막만
# 보여주며, 그 이상인 이름의 경우는 첫 성만 보여주고 나머지는 마스크(*) 처리해 주세요.)
# [관련내용] length()함수, trim()함수, char_length()함수, rpad()함수, substring()함수

select name,
       CASE
        WHEN CHAR_LENGTH(TRIM(name)) = 2 THEN CONCAT(SUBSTRING(name, 1, 1), &#39;*&#39;)
        WHEN CHAR_LENGTH(TRIM(name)) = 3 THEN CONCAT(SUBSTRING(name, 1, 1), &#39;*&#39;, SUBSTRING(name, 3, 1))
        WHEN CHAR_LENGTH(TRIM(name)) = 4 THEN CONCAT(SUBSTRING(name, 1, 1), &#39;**&#39;, SUBSTRING(name, 4, 1))
        ELSE RPAD(SUBSTRING(name, 1, 1), CHAR_LENGTH(TRIM(name)), &#39;*&#39;)
        END AS new_name
from actor
where country = &#39;한국&#39; and
      domain = &#39;배우&#39; and
          CHAR_LENGTH(TRIM(name)) &gt; 1

;


# 20. 한국인 이면서 &#39;배&#39;씨 성을 가진 사람 중에 &#39;준&#39;으로 끝나는 이름을 가진 영화인을 조회하는
# SQL문을 작성해 주세요.(이름은 3자인 영확인을 구하세요.)
# [관련내용] like 문, 와일드카드 _

select *,
       char_length(trim(name))
from actor
where name like &#39;배%준&#39;
;



</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[DB 쿼리문 연습 (3)]]></title>
            <link>https://velog.io/@sonyak-ku/DB-%EC%BF%BC%EB%A6%AC%EB%AC%B8-%EC%97%B0%EC%8A%B5-3</link>
            <guid>https://velog.io/@sonyak-ku/DB-%EC%BF%BC%EB%A6%AC%EB%AC%B8-%EC%97%B0%EC%8A%B5-3</guid>
            <pubDate>Tue, 13 Jun 2023 13:17:39 GMT</pubDate>
            <description><![CDATA[<p><strong>배운 함수</strong></p>
<ul>
<li>round 함수, avg 함수</li>
<li>sub query</li>
<li>having</li>
<li>str_to_date 함수</li>
<li>between A and B</li>
<li>format 함수, sum 함수</li>
</ul>
<hr>
<pre><code class="language-sql">/*
11. 전국 극장의 스크린 수의 평균과 ‘서울시&#39;에 위치한 극장의 스크린 수의 평균을 구하고, 이
둘의 차이를 조회하는 SQL문을 작성해 보세요.(단, 최종 차이의 평균은 소수점 첫째 자리에서
반올림하여 구합니다.)
[관련내용] round() 함수, avg() 함수, sub query
12. 한국에서만 하는 축제 중에서 도시별로 진행하는 축제가 10개 이상인 도시를 가장 많이
진행하는 순서로 출력하는 SQL문을 작성해 보세요.(단, 도시정보가 없는 경우는 제외해 주세요.)
[관련내용]
13. 영화인 정보에서 직업이 배우가 아닌 사람 중에서 1980년 ~ 1990년 사이에 출생자를
조회하는 SQL문을 작성해 주세요.(생년월일 정보가 유효하지 않은 사람은 제외해 주세요.)
[관련내용] in, is not null, length() 함수, trim() 함수, str_to_date()함수, between a and b
14. 헝가리 출신의 영화인중 직업이 배우인 사람의 생일을 출생년도, 월, 일자를 각각 출력하는
SQL문을 작성해 보세요.(단, 생일이 입력되지 않은 사람은 제외해 주세요.)
[관련내용] str_to_date, year()함수, month()함수, day()함수, length()함수, trim()함수, is not null
15. 서울시에 위치한 극장 중에서 강남구가 아닌 극장의 좌석 수의 합을 조회하는 SQL문을
작성해 보세요.(좌석 수는 천단위로 콤마(,)로 표시해 주세요.)
[관련내용] format()함수, sum()함수, not in
*/

# 11. 전국 극장의 스크린 수의 평균과 ‘서울시&#39;에 위치한 극장의 스크린 수의 평균을 구하고, 이
# 둘의 차이를 조회하는 SQL문을 작성해 보세요.(단, 최종 차이의 평균은 소수점 첫째 자리에서
# 반올림하여 구합니다.)
# [관련내용] round() 함수, avg() 함수, sub query

select T1.*,
       round((T1.avg_all - T1.avg_seoul), 1) as diff
from
(
    select
        (select avg(screen_count) from screen where sido = &#39;서울시&#39;) as avg_seoul,
        (select avg(screen_count) from screen) as avg_all
) T1
;


# 12. 한국에서만 하는 축제 중에서 도시별로 진행하는 축제가 10개 이상인 도시를 가장 많이
# 진행하는 순서로 출력하는 SQL문을 작성해 보세요.(단, 도시정보가 없는 경우는 제외해 주세요.)

select f.city,
       count(*) as festival_number
from festival as f
where city is not null and trim(city) &lt;&gt; &#39;&#39; and country = &#39;한국&#39;
group by city
having festival_number &gt;= 10
order by festival_number desc
;


# 13. 영화인 정보에서 직업이 배우가 아닌 사람 중에서 1980년 ~ 1990년 사이에 출생자를
# 조회하는 SQL문을 작성해 주세요.(생년월일 정보가 유효하지 않은 사람은 제외해 주세요.)
# [관련내용] in, is not null, length() 함수, trim() 함수, str_to_date()함수, between a and b


select a.code,
       a.name,
       a.eng_name,
        case when length(birth) = 4 then str_to_date(birth, &#39;%Y-%m-%d&#39;)
        else birth
        end as birth,
        a.country,
        a.domain,
        a.pilmo,
        a.reg_dt
from actor as a
where domain not in (&#39;배우&#39;)
    and birth is not null
    and str_to_date(birth, &#39;%Y-%m-%d&#39;) is not null
    and year(str_to_date(birth, &#39;%Y-%m-%d&#39;)) between 1980 and 1990
;

# 14. 헝가리 출신의 영화인중 직업이 배우인 사람의 생일을 출생년도, 월, 일자를 각각 출력하는
# SQL문을 작성해 보세요.(단, 생일이 입력되지 않은 사람은 제외해 주세요.)
# [관련내용] str_to_date, year()함수, month()함수, day()함수, length()함수, trim()함수, is not null

select a.name,
    year(str_to_date(birth, &#39;%Y-%m-%d&#39;)) as year,
    month(str_to_date(birth, &#39;%Y-%m-%d&#39;)) as month,
    day(str_to_date(birth, &#39;%Y-%m-%d&#39;)) as day
from actor a
where country = &#39;헝가리&#39;
    and domain in (&#39;배우&#39;)
    and birth is not null
    and length(birth) = 10
    and str_to_date(birth, &#39;%Y-%m-%d&#39;) is not null
;

# 15. 서울시에 위치한 극장 중에서 강남구가 아닌 극장의 좌석 수의 합을 조회하는 SQL문을
# 작성해 보세요.(좌석 수는 천단위로 콤마(,)로 표시해 주세요.)
# [관련내용] format()함수, sum()함수, not in

select format(sum(seat_count), 0)
from screen
where sido in (&#39;서울시&#39;)
    and gugun not in (&#39;강남구&#39;)
;</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[DB 쿼리문 연습 (2)]]></title>
            <link>https://velog.io/@sonyak-ku/DB-%EC%BF%BC%EB%A6%AC%EB%AC%B8-%EC%97%B0%EC%8A%B5-2</link>
            <guid>https://velog.io/@sonyak-ku/DB-%EC%BF%BC%EB%A6%AC%EB%AC%B8-%EC%97%B0%EC%8A%B5-2</guid>
            <pubDate>Tue, 13 Jun 2023 11:59:15 GMT</pubDate>
            <description><![CDATA[<p><em><strong>배운 쿼리</strong></em></p>
<ul>
<li>case when then 문</li>
<li>row_number 함수, max 함수</li>
<li>group by, order by</li>
</ul>
<hr>
<pre><code class="language-sql">/*
6. 시카고에서 진행하는 축제중에서 영문 제목이 없는 경우 한글 제목으로 보여주며, 장르가 없는 경우
기타로 표시하며, 홈페이지가 없는 경우 홈페이지 없음&quot; 으로 조회하는 SQL문을 작성해 보세요.
[관련내용] CASE 문
7. 영화 상영관 회사별로 좌석수가 가장 많은 값을 구하고 이를 순서대로 조회하는 SQL문을 작성해
보세요.
[관련내용] row_number(), max() 함수, group by, order by
8. 국가별 영화 정보의 개수를 조회하는 SQL 구문을 작성해 보세요.(단, 국가가 없는 경우는 ‘국가 미상&#39;
으로 처리해 주세요.)
[관련내용] group by, order by, trim() 함수, count() 함수, case 문
9. CGV 극장 중에서 스크린 수가 가장 많은 극장의 순위를 5위까지 조회하는 SQL 문을 작성해 보세요.
[관련내용] order by, row_number, limit
10. 스크린 수가 가장 많은 극장의 이름을 조회하는 SQL문을 작성해 보세요.
*/

-- 6. 시카고에서 진행하는 축제중, 영문 제목이 없는 경우 한글 제목으로 보여주며
-- 장르가 없는 경우 기타로 표시하며, 홈페이가 없는 경우 &#39;홈페이지 없을&#39; 으로 조회하는 sql문 작성

select f.code,
       f.title,

       case when ifNULL(f.eng_title, &#39;&#39;) = &#39;&#39; then f.title
           else f.eng_title
        end as eng_title
       ,

       f.continent,
       f.country,
       f.city,

       case when ifnull(f.genre, &#39;&#39;) = &#39;&#39; then &#39;기타&#39;
           else f.genre
        end as genre
       ,
       f.important_flag,
       case when ifnull(f.homepage, &#39;&#39;) = &#39;&#39; then &#39;홈페이지 없음&#39;
           else f.homepage
        end as homepage
       ,
       f.first_open_date
from festival f

where city like &#39;%시카고%&#39;

;

# alter table festival
# rename column gerne to genre; -- 컬럼 명 변경하기

# 7. 영화 상영관 회사별로 좌석수가 가장 많은 값을 구하고 이를 순서대로 조회하는 SQL문을 작성해
# 보세요.

select biz_name,
       max(seat_count) as max_seat_count,
       row_number() over (order by max(seat_count)) as ranking
from screen
where biz_name is not null and trim(biz_name) &lt;&gt; &#39;&#39;

group by biz_name
order by max_seat_count
;

# 8. 국가별 영화 정보의 개수를 조회하는 SQL 구문을 작성해 보세요.(단, 국가가 없는 경우는 ‘국가 미상&#39;
# 으로 처리해 주세요.)
# [관련내용] group by, order by, trim() 함수, count() 함수, case 문

select
       case when ifnull(m.country, &#39;&#39;) = &#39;&#39; then &#39;국가 미상&#39;
        else m.country
        end as country,
     count(title) as movie_count

from movie as m
group by country
order by movie_count
;


# 9. CGV 극장 중에서 스크린 수가 가장 많은 극장의 순위를 5위까지 조회하는 SQL 문을 작성해 보세요.
# [관련내용] order by, row_number, limit

select screen_name,
       screen_count
from screen
where screen_name like &#39;%CGV%&#39;
order by screen_count desc
limit 5
;

# 10. 스크린 수가 가장 많은 극장의 이름을 조회하는 SQL문을 작성해 보세요.

select *
from screen
order by screen_count desc
limit 1
;

select *
from screen
where screen_count in (
    select max(screen_count)
    from screen
    )
;</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[DB 쿼리문 연습 (1)]]></title>
            <link>https://velog.io/@sonyak-ku/DB-%EC%BF%BC%EB%A6%AC%EB%AC%B8-%EC%97%B0%EC%8A%B51</link>
            <guid>https://velog.io/@sonyak-ku/DB-%EC%BF%BC%EB%A6%AC%EB%AC%B8-%EC%97%B0%EC%8A%B51</guid>
            <pubDate>Fri, 09 Jun 2023 11:58:31 GMT</pubDate>
            <description><![CDATA[<p><em><strong>배운 쿼리</strong></em></p>
<ul>
<li>NULL 함수, TRIM 함수, LEN 함수</li>
<li>LIKE 조건</li>
<li>IN 조건</li>
<li>DISTINCT 함수</li>
<li>JOIN, COLUMN ALIAS</li>
<li>ORDER BY</li>
</ul>
<hr>
<pre><code class="language-sql">
-- 쿼리 실습
/*
1. 영화 정보중 영문 제목이 없는 데이터를 조회하는 SQL문을 작성해 보세요.
[관련내용] NULL 함수, TRIM 함수, LEN 함수
2. 한국 영화중 2001년도에 개봉한 영화 중 액션 영화를 조회하는 SQL문을 작성해 보세요.
[관련내용] LIKE 조건
3. 싸이더스가 2020년도에 개봉한 영화 감독의 출생년도를 조회하는 SQL를 작성해 보세요.
[관련내용] IN 조건
4. 배우 정보에서 직업을 중복없이 조회하는 SQL문을 작성해 보세요.
[관련내용] DISTINCT 이용, NULL 체크
5. 영화 감독의 국가가 독일이고 2020년 이후에 개봉된 영화의 제목, 감독, 개봉일자, 장르를
최근 개봉일자 순으로 조회하는 SQL문을 작성해 보세요.
[관련내용] JOIN, COLUMN ALIAS, TABLE ALIAS, 순서 정렬
*/

-- 1. 영문 제목이 없는 데이터 조회
select * from movie
where eng_title is NULL
;

-- 2. 2001년도에 개봉한 액션 영화 조회하기 (한국영화)
select * from movie where country = &#39;한국&#39;;
select * from movie where country like &#39;한%&#39;;

-- 3. 싸이더스가 2020년도에 개봉한 영화 감독의 출생년도 조회
select director from movie
where
    pub_year = 2020 and
    production like &#39;%싸이더스%&#39;
;

select * from actor
where domain = &#39;감독&#39;
    and name in (
        select director from movie
where
    pub_year = 2020 and
    production like &#39;%싸이더스%&#39;

    );

-- 4.배우 정보에서 직업 중복없이 조회하기

select distinct(domain) from actor
where domain is NOT NULL
    and trim(domain) &lt;&gt; &#39;&#39;
;

-- 5. 영화 감독 국가 독일, 2020 년 이후 개봉된 영화의 제목, 감독, 개보일자, 장르를 최근 개봉일자 순 조회
select m.title, m.director, m.pub_year, m.genre
from movie m
    join actor a on (m.director = a.name)
where m.pub_year &gt;= 2020
    and a.country = &#39;독일&#39;
    and a.domain = &#39;감독&#39;
order by m.pub_year desc ;
;







</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[순열과 조합]]></title>
            <link>https://velog.io/@sonyak-ku/%EC%88%9C%EC%97%B4%EA%B3%BC-%EC%A1%B0%ED%95%A9</link>
            <guid>https://velog.io/@sonyak-ku/%EC%88%9C%EC%97%B4%EA%B3%BC-%EC%A1%B0%ED%95%A9</guid>
            <pubDate>Thu, 08 Jun 2023 10:29:42 GMT</pubDate>
            <description><![CDATA[<p><em>코딩문제에서 간간히 나오는 순열과 조합, 그 원소 뽑기 코드 작성법이다.</em></p>
<hr>
<p><a href="https://leetcode.com/problems/permutations/">46. Permutation - LeetCode</a></p>
<pre><code class="language-java">class Solution {
    public List&lt;List&lt;Integer&gt;&gt; permute(int[] nums) {
    // permutate logic
    Set&lt;List&lt;Integer&gt;&gt; ans = new HashSet&lt;&gt;();
    List&lt;Integer&gt; cur = Arrays.asList(Arrays.stream(nums).boxed().toArray(Integer[]::new));  
    permutation(ans, cur, 0);

    return new ArrayList(ans);
    }

    public void permutation(Set&lt;List&lt;Integer&gt;&gt; ans, List&lt;Integer&gt; cur, int r) {

        if (r == cur.size()) {
            return;
        }

        for (int i = 0; i &lt; cur.size(); i++) {
            Collections.swap(cur, r, i);
            // ans.add(cur);  --&gt; 문제가 많았던
            // 
            ans.add(new ArrayList(cur)); //--&gt; 부분
            //
            permutation(ans, cur, r + 1);
            Collections.swap(cur, r, i);
        }
    }


}</code></pre>
<p>아래의 조합은 강의를 통해서 배운 코드 작성법이고, 순열은 직접 짜본 코드이다. 그런데 제대로 HashSet의 사이즈가 증가하는데 막상 코드를 찍어보면 이상하게 나오길래 뭐가 문젠지 싶어서 한참을 헤멨다.</p>
<p><img src="https://velog.velcdn.com/images/sonyak-ku/post/b3919d9c-640d-40b2-809a-2656c73a8ef2/image.png" alt=""></p>
<p>해시셋을 프린트로 찍어보면 저런식으로 나와버리길래 이게 뭐지??? 싶었다.</p>
<p>그런데 해설 코드를 보다보니, 나와 코드 구성은 다르지만 Collections 에 아이템을 넣을 때 new ArrayList 로 새롭게 객체를 만들어서 넣길래 나도 위의 코드에서 보듯이 그렇게 코드를 수정했더니</p>
<p><img src="https://velog.velcdn.com/images/sonyak-ku/post/6a6b64c6-04b8-47c4-bf32-4325cf0fd0e0/image.png" alt=""></p>
<p>결과가 제대로 나오더라. 아직 공부가 부족한것 같다.</p>
<p><strong>아래는 리트코드에서 제공하는 <em>순열</em> 답안.</strong></p>
<pre><code class="language-java">class Solution {
    public List&lt;List&lt;Integer&gt;&gt; permute(int[] nums) {
        List&lt;List&lt;Integer&gt;&gt; ans = new ArrayList&lt;&gt;();
        backtrack(new ArrayList&lt;&gt;(), ans, nums);
        return ans;
    }

    public void backtrack(List&lt;Integer&gt; curr, List&lt;List&lt;Integer&gt;&gt; ans, int[] nums) {
        if (curr.size() == nums.length) {
            ans.add(new ArrayList&lt;&gt;(curr));
            return;
        }

        for (int num: nums) {
            if (!curr.contains(num)) {
                curr.add(num);
                backtrack(curr, ans, nums);
                curr.remove(curr.size() - 1);
            }
        }
    }
}</code></pre>
<hr>
<p><a href="https://leetcode.com/problems/combinations/solutions/3139162/java-backtracking-solution/">77. Combinations - LeetCode</a></p>
<pre><code class="language-java">class Solution {
    public List&lt;List&lt;Integer&gt;&gt; combine(int n, int k) {
    // combination logic
    int[] arr = IntStream.rangeClosed(1, n).toArray();
    boolean[] visited = new boolean[arr.length];
    List&lt;List&lt;Integer&gt;&gt; ans = new ArrayList&lt;&gt;();
    combination(ans, arr, visited, k, 0);

    return ans;
    }

    public void combination(List&lt;List&lt;Integer&gt;&gt; answer, int[] arr, boolean visited[], int depth, int r) {

        if (depth == 0) {
            List&lt;Integer&gt; t = new ArrayList&lt;&gt;();
            for (int i = 0; i &lt; visited.length; i++) {
                if (visited[i]) {
                    t.add(arr[i]);
                }
            }

            answer.add(t);
            return;
        }

        if (r == visited.length) {
            return;
        }

        visited[r] = true;
        combination(answer, arr, visited, depth - 1, r + 1);

        visited[r] = false;
        combination(answer, arr, visited, depth, r + 1);
    }

}</code></pre>
<p><strong>아래는 리트코드에서 제공하는 <em>조합</em> 코드 답안.</strong></p>
<pre><code class="language-java">class Solution {
    private int n;
    private int k;

    public List&lt;List&lt;Integer&gt;&gt; combine(int n, int k) {
        this.n = n;
        this.k = k;
        List&lt;List&lt;Integer&gt;&gt; ans = new ArrayList&lt;&gt;();
        backtrack(new ArrayList&lt;&gt;(), 1, ans);
        return ans;
    }

    public void backtrack(List&lt;Integer&gt; curr, int firstNum, List&lt;List&lt;Integer&gt;&gt; ans) {
        if (curr.size() == k) {
            ans.add(new ArrayList&lt;&gt;(curr));
            return;
        }

        int need = k - curr.size();
        int remain = n - firstNum + 1;
        int available = remain - need;

        for (int num = firstNum; num &lt;= firstNum + available; num++) {
            curr.add(num);
            backtrack(curr, num + 1, ans);
            curr.remove(curr.size() - 1);
        }

        return;
    }
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[Arrays 타입을 Collection 으로 변환해보기]]></title>
            <link>https://velog.io/@sonyak-ku/Arrays-%ED%83%80%EC%9E%85%EC%9D%84-Collection-%EC%9C%BC%EB%A1%9C-%EB%B3%80%ED%99%98%ED%95%B4%EB%B3%B4%EA%B8%B0</link>
            <guid>https://velog.io/@sonyak-ku/Arrays-%ED%83%80%EC%9E%85%EC%9D%84-Collection-%EC%9C%BC%EB%A1%9C-%EB%B3%80%ED%99%98%ED%95%B4%EB%B3%B4%EA%B8%B0</guid>
            <pubDate>Tue, 30 May 2023 19:14:44 GMT</pubDate>
            <description><![CDATA[<ul>
<li><p>int 형 데이터를 받는 배열을 Integer 타입의 List 로 어떻게 변환할 수 있을까?</p>
</li>
<li><p>이것을 배워두면, 배열에서 모든 Collection 타입의 자료구조로 변환하기가 쉽기 때문에 한번 공부겸 글을 작성해보려 한다.</p>
</li>
</ul>
<hr>
<p>문제를 예로 들어서 풀어보자</p>
<blockquote>
<p>int 배열 arr1 과 arr2 가 있다. 두 배열에 공통적으로 들어가는 원소를 배열로 가지는 int 배열을 출력해라! -&gt; 교집합 구하기 문제</p>
</blockquote>
<p>전략 세우기</p>
<ul>
<li>HashSet 의 retainAll 함수를 사용하고 싶다! (교집합 구하기)</li>
<li>Collection 타입의 자료구조로 Arrays 들을 바꿔서 조작한 후에, 다시 Collection 에서 Arrays 로 돌려 놓는 과정이 필요하겠다!</li>
</ul>
<hr>
<p>코드로 구현한 부분</p>
<pre><code class="language-java">import java.util.HashSet;
import java.util.Arrays;

class Solution {
    public int[] solution(int[] arr1, int[] arr2) {
        Integer[] arr1_n = Arrays.stream(arr1).boxed().toArray(Integer[]::new);
        Integer[] arr2_n = Arrays.stream(arr2).boxed().toArray(Integer[]::new);

        HashSet&lt;Integer&gt; set1 = new HashSet&lt;&gt;(Arrays.asList(arr1_n));
        HashSet&lt;Integer&gt; set2 = new HashSet&lt;&gt;(Arrays.asList(arr2_n));
        set1.retainAll(set2);

        int[] answer = Arrays.stream(set1.toArray(Integer[]::new)).mapToInt(i -&gt; i).toArray();

        return answer;
    }
}</code></pre>
<p>처음으로 Stream 을 써보았다. 매번 for 문으로 int to Integer, 반대로 하다가 stream을 쓰니깐 훨씬 편한 느낌이 들기도 한다.</p>
<p>스트림 공부를 해야겠다는 생각이 듬.</p>
<p>ps. 교집합 (retainAll), 차집합 (removeAll), 합집합 (addAll)</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[PECS (Producer Extends, Consumer Super)]]></title>
            <link>https://velog.io/@sonyak-ku/PECS-Producer-Extends-Consumer-Super</link>
            <guid>https://velog.io/@sonyak-ku/PECS-Producer-Extends-Consumer-Super</guid>
            <pubDate>Mon, 29 May 2023 21:57:07 GMT</pubDate>
            <description><![CDATA[<p>자바를 공부하다가 요런 코드를 보게 되었다.</p>
<pre><code class="language-java">Class&lt;? extends Integer&gt; aClass</code></pre>
<p>?? 제너릭에 들어가 있는 저건 뭐지?</p>
<p>찾아보다 도움 받은 스택오버플로우의 링크를 아래에 먼저 남긴다
<a href="https://stackoverflow.com/questions/4343202/difference-between-super-t-and-extends-t-in-java/4343547#4343547">스택오버플로우</a></p>
<hr>
<p>다시 위의 코드를 보자면 쉽게 말해, 클래스의 타입으로 올 수 있는 것은 Integer 클래스 자신 혹은 자식 클래스 라는 의미를 갖는다.</p>
<p>비슷한 코드로 </p>
<pre><code class="language-java">Class&lt;? super Integer&gt; aClass</code></pre>
<p>가 있으며</p>
<p>이는 클래스의 타입으로 올 수 있는 것은 Integer 클래스 자신 혹은 부모 클래스라는 제너릭 타입 제한을 말한다.</p>
<hr>
<p>그렇다면 제목의 PECS 는 무슨 의미 일까?</p>
<p>그림을 곁들인 자세한 설명은 위의 스택오버플로우 글에 들어가면 있다.</p>
<p>위의 스택오버플로우 글의 질문은 이거였다.</p>
<blockquote>
<p>I used to use List&lt;? extends T&gt;, but it does not allow me to add elements to it list.add(e), whereas the List&lt;? super T&gt; does.</p>
</blockquote>
<p>쉽게 말해, <strong>제너릭 안에 extends 가 들어간 타입 제한을 걸었을 때는 add 메소드가 동작하지 않았지만 super 키워드가 들어갔을때는 add 메소드가 동작했는데 왜 그런건가요?</strong> 라는 질문이다.</p>
<hr>
<p>언뜻보기엔 둘다 제너릭으로 T 타입과 함께 허용할 클래스를 자식클래스냐 부모클래스냐 제한하는 것이기 때문에, T 타입인 데이터 e 를 집어넣는 메소드가 한쪽에선 동작하지 않는다는 것이 이해가 가지 않는다.</p>
<p><del><em>다시 말하지만 그림을 곁들인 자세한 설명은 위의 링크를 타고 스택오버플로우로 여행을 가시길 바란다.</em></del></p>
<p><em>결론만 말하면</em></p>
<p><strong>문제는 저 와일드 카드 ? 에 있었다.</strong></p>
<p>스택오버플로우의 질문 글로 다시 돌아가보자면,</p>
<p>T 타입의 데이터 e 를 &lt;? super T&gt; 에서는 집어넣을 수 있는데 &lt;? extends T&gt; 에서는 넣을 수 없더라라는 질문의 글을 다시 보자면,</p>
<p>문제의 &lt;? extends T&gt; 의 제너릭의 경우 T 타입의 자식클래스 일 수 도 있기 때문에 add 코드가 동작하지 않았던 것이다.</p>
<pre><code class="language-java">class Human {}

class Man extends Human {}

class Woman extends Human{}
</code></pre>
<pre><code class="language-java">public static void Main(String[] args) {
    Human human = new Human();
    Man man = new Man();
    System.out.println(human instanceof Man); // false
    System.out.println(man instanceof Human); // true
}</code></pre>
<p>Human 클래스의 객체는 Man 자식 클래스 타입이 아니라고 드러난다.</p>
<p>문제의 &lt;? extends Human&gt; 의 경우에 적용해보자면</p>
<p>Human 타입의 데이터 e 를 add 할 수 없었던 이유는</p>
<p><strong>제너릭 안에 들어있는 저 와일드카드 ? 때문에,&lt;&gt; 안에 들어갈 타입이 Human 일 수 도 있지만 자식클래스 Man 일 수도 있기에 타입이 확실하지 않기 때문에 데이터를 집어넣을 수 없었던 것이다.</strong></p>
<p>반면 &lt;? super Human&gt; 의 경우는 가능했는데 그 이유는</p>
<p><strong>&lt;&gt; 안에 들어갈 타입이 Human 이거나 Human 의 부모클래스 일 수 있는데, Human 의 객체라면 모두 Human 의 부모클래스의 객체라고 볼 수 있기 때문에 타입이 안정되어서 add 메소드가 동작 가능했던 것이다.</strong></p>
<hr>
<p>위와 같은 경우를 잘 정의한 용어가 바로 이 글의 제목인 <em>PECS (Producer Extends, Consumer Super)</em> 이다.</p>
<ul>
<li><p>&quot;Producer Extends&quot; - If you need a List to produce T values (you want to read Ts from the list), you need to declare it with ? extends T, e.g. List&lt;? extends Integer&gt;. <strong>But you cannot add to this list</strong>.</p>
</li>
<li><p>&quot;Consumer Super&quot; - If you need a List to consume T values (you want to write Ts into the list), you need to declare it with ? super T, e.g. List&lt;? super Integer&gt;. <strong>But there are no guarantees what type of object you may read from this list</strong>.</p>
</li>
<li><p>If you need to both read from and write to a list, you need to declare it exactly with no wildcards, e.g. List<strong>&lt; Integer &gt;</strong>.</p>
</li>
</ul>
<hr>
<p>스택오버플로우의 질문 글로 부터 정리하자면, T 타입의 데이터를 쓰고 싶다면 super를 읽고 싶다면 extends 를, 둘다 하고 싶다면 그냥 와일드 카드 없이 List<T> 를 사용하면 될 것이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[사칙연산 구현하기(연산 법칙 지킴)]]></title>
            <link>https://velog.io/@sonyak-ku/%EC%82%AC%EC%B9%99%EC%97%B0%EC%82%B0-%EA%B5%AC%ED%98%84%ED%95%98%EA%B8%B0%EC%97%B0%EC%82%B0-%EC%88%9C%EC%84%9C-%EB%94%B0%EB%A6%84</link>
            <guid>https://velog.io/@sonyak-ku/%EC%82%AC%EC%B9%99%EC%97%B0%EC%82%B0-%EA%B5%AC%ED%98%84%ED%95%98%EA%B8%B0%EC%97%B0%EC%82%B0-%EC%88%9C%EC%84%9C-%EB%94%B0%EB%A6%84</guid>
            <pubDate>Fri, 26 May 2023 09:49:29 GMT</pubDate>
            <description><![CDATA[<p>프로그래머스 사칙연산 구현 문제 시험을 풀다가 시간이 지나버려서 내가 줄줄이 쓴 코드를 완성하지 못하고 날라가버렸기 때문에...</p>
<p>짜증나서 다시 구현할 겸 (내가 풀 수 있는 문제인지 테스트 겸) 코드를 작성하겠습니다.</p>
<blockquote>
<p>사칙연산 구현하기 ( 연산 순서대로 곱하기와 나누기를 먼저 계산하고 그 다음 더하기와 빼기를 합니다 ). 문자열 형태의 연산을 받으면 그것을 계산한 답을 문자열 형태로 리턴합니다. 단 소숫점 둘째자리까지만 표현합니다.(반올림, 올림, 내림 중 &#39;내림&#39; 사용하기) </p>
</blockquote>
<pre><code class="language-java">public class Solution { // 사칙연산 구현하기
    public static void main(String[] args) {
        String s =  &quot;2*3+5/6*3+15&quot;;
        s = divideOrMultiply(s);
        s = plusOrMinus(s);
        System.out.println(&quot;계산된 수식은..: &quot; + s);
    }

    public static String divideOrMultiply(String string){
        String s = string;

        String left = &quot;&quot;;
        String right = &quot;&quot;;
        int cur = -1;
        int leftCur = -1; 
        int rightCur = -1;
        char DM = &#39;a&#39;;


        while (true) {

            // dm(divide or multiply) 기호위치 찾기
            for (int i = 0; i &lt; s.length(); i++) {
                if (s.charAt(i) == &#39;*&#39; || s.charAt(i) == &#39;/&#39;) {
                    cur = i;
                    DM = s.charAt(i);
                    break;
                }
            }
            // 반복문 탈출조건 -&gt; 찾아야하는 기호가 없을때 : cur == -1;
            if (cur == -1) {
                break;
            }
            // left 찾기
            for (int i = cur - 1; i &gt;= 0; i--) {
                if (Character.isDigit(s.charAt(i)) || s.charAt(i) == &#39;.&#39;) {
                    left = s.charAt(i) + left;
                } else {
                    leftCur = i;
                    break;
                }
            }
            // right 찾기
            for (int i = cur + 1; i &lt; s.length(); i++) {
                if (Character.isDigit(s.charAt(i)) || s.charAt(i) == &#39;.&#39;) {
                    right = right + s.charAt(i);
                } else {
                    rightCur = i;
                    break;
                }
            }
            // 계산 하기
            String replaceAfter = &quot;&quot;;

            if (DM == &#39;*&#39;) {
                replaceAfter = String.format(&quot;%.2f&quot;, Double.parseDouble(left) * Double.parseDouble(right));
            } else if (DM == &#39;/&#39;) {
                replaceAfter = String.format(&quot;%.2f&quot;, Double.parseDouble(left) / Double.parseDouble(right));
            }
            // string 에 replace하고 cur, Dm, left, right 초기화 하기
            s = s.substring(0, leftCur + 1) + replaceAfter + s.substring(rightCur);
            cur = -1;
            DM = &#39;a&#39;;
            left = &quot;&quot;;
            right = &quot;&quot;;
            leftCur = -1;
            rightCur = -1;
        }

        return s;
    }

    public static String plusOrMinus(String string) {
        String s = string;

        String left = &quot;&quot;;
        String right = &quot;&quot;;
        int cur = -1;
        int leftCur = -1; 
        int rightCur = -1;
        char PM = &#39;a&#39;;


        while (true) {

            // pm(plus or minus) 기호위치 찾기
            for (int i = 0; i &lt; s.length(); i++) {
                if (s.charAt(i) == &#39;+&#39; || s.charAt(i) == &#39;-&#39;) {
                    cur = i;
                    PM = s.charAt(i);
                    break;
                }
            }
            // 반복문 탈출조건 -&gt; 찾아야하는 기호가 없을때 : cur == -1;
            if (cur == -1) {
                break;
            }
            // left 찾기
            for (int i = cur - 1; i &gt;= 0; i--) {
                if (Character.isDigit(s.charAt(i)) || s.charAt(i) == &#39;.&#39;) {
                    left = s.charAt(i) + left;
                } else {
                    leftCur = i;
                    break;
                }
            }
            // right 찾기
            for (int i = cur + 1; i &lt; s.length(); i++) {
                if (Character.isDigit(s.charAt(i)) || s.charAt(i) == &#39;.&#39;) {
                    right = right + s.charAt(i);
                } else {
                    rightCur = i;
                    break;
                }
            }
            if (rightCur == - 1) {    // 마지막 계산에서 rightCur 이 -1 이 되는 문제해결
                rightCur = s.length() - 1;
            }

            // 계산 하기
            String replaceAfter = &quot;&quot;;

            if (PM == &#39;+&#39;) {
                replaceAfter = String.format(&quot;%.2f&quot;, Double.parseDouble(left) + Double.parseDouble(right));
            } else if (PM == &#39;-&#39;) {
                replaceAfter = String.format(&quot;%.2f&quot;, Double.parseDouble(left) - Double.parseDouble(right));
            }
            // string 에 replace하고 cur, Dm, left, right 초기화 하기
            s = s.substring(0, leftCur + 1) + replaceAfter + s.substring(rightCur);
            cur = -1;
            PM = &#39;a&#39;;
            left = &quot;&quot;;
            right = &quot;&quot;;
            leftCur = -1;
            rightCur = -1;
        }

        return s;
    }

}
</code></pre>
<p><img src="https://velog.velcdn.com/images/sonyak-ku/post/5efc05cd-e5ba-4d1c-b8ea-f9e4e84d245b/image.png" alt=""></p>
<h2 id="기존코드의-문제점">기존코드의 문제점</h2>
<ul>
<li>반복문의 탈출 조건을 체크하지 않았다.</li>
<li>반복문 내에서 사용되는 변수들을 매 반복시에 초기화 하지 않았다.</li>
<li>String  의 replaceFirst() 라는 메소드가 내가 원하는대로 동작하지 않았다.</li>
<li><ul>
<li>replace() 를 사용하지 않은 이유는, 해당 되는 모든 문자열을 바꿔버리기 때문에 사칙연산에서 사용할 수 없기 때문</li>
</ul>
</li>
<li><ul>
<li>따라서 String 을 잘라붙이는 방법을 사용하였다.</li>
</ul>
</li>
<li>left 계산 할때 0.83 인 경우에 83 으로 읽음 (. 이라는 소수점을 파악 못하였다)      </li>
<li>찐 마지막 계산, 즉 연산기호가 하나 남은 경우의 연산에서, 연산을 진행 한 뒤에 마지막 substring() 부분에서 rightCur 이 여전히 -1 인 상태여서 생겼던 오류 발견.</li>
</ul>
<h2 id="깨달은-점">깨달은 점</h2>
<ul>
<li>프로그래머스 등 코테를 칠 때, 정말 사용하는 변수 하나하나, 바뀔 때마다 print를 찍었다면 위에서 만난 문제들을 미리 해결할 수 있었지 않았을 까 하는 생각이 든다. 그러지 않고 눈코딩으로 문제점을 파악하려다 보니 절대 파악하기 힘들었다.</li>
<li>IntelliJ 에서 코드를 수정하면서 디버깅툴의 도움이 없었다면..ㄷ</li>
</ul>
<h2 id="해야하는-것">해야하는 것</h2>
<ul>
<li>divideOrMultiply 함수와 plusOrMinus 함수는 상당히 많은 부분이 같다. 코드를 짠 입장에서 말해보면 동작 방식이 똑같고 적용되는 기호가 곱하기 나누기냐 - 더하기 빼기냐 의 차이 밖에 없다.</li>
<li>그렇다면 위처럼 코드를 짜는 것은 잘못 짜여진 드러운 코드가 아닐까라는 의문이 들면서 어떻게 저 코드들을 아름답게 리팩터링 해볼 수 있을까 라는 고민이 든다.</li>
<li>아마 내 자바공부 인생에서 - 리팩터링(?)이라고 부를 수 있다면 - 첫 리팩터링이 될 것이다. </li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[java.util.NoSuchElementException using iterator in java]]></title>
            <link>https://velog.io/@sonyak-ku/Iterator-%EC%82%AC%EC%9A%A9%EA%B8%B0</link>
            <guid>https://velog.io/@sonyak-ku/Iterator-%EC%82%AC%EC%9A%A9%EA%B8%B0</guid>
            <pubDate>Wed, 24 May 2023 14:32:56 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/sonyak-ku/post/e3e666c7-c528-4c81-bf33-53ea060aea44/image.png" alt=""></p>
<p>내가 사용하는 iter.next() 에서 던진 에러.
어디서 뜨는 지는 이미 알고 있었지만 어떻게 해결해야 될지 몰라 스택오버플로우를 참조했다.</p>
<pre><code class="language-java">        Iterator&lt;Entry&lt;Integer,Integer&gt;&gt; iter = hash.entrySet().iterator();

        while (iter.hasNext()) { // 문제가 되는 부분
            if (iter.next().getValue() == 1) {
                answer = iter.next().getKey();
                break;
            }
        }
</code></pre>
<p><a href="https://stackoverflow.com/questions/19106753/java-util-nosuchelementexception-using-iterator-in-java">스택오버플로우 참조 링크</a></p>
<p>답변은 아래와 같다.</p>
<blockquote>
<p>You are calling next() a bunch of times in one iteration forcing the Iterator to move to an element that doesn&#39;t exist.</p>
</blockquote>
<p>iter.next()는 다음 커서의 객체를 접근 하는 개념이 아니라 현재 커서를 다음 커서로 이동시키는 것이다. 
따라서 iter.next() 가 불릴때마다 iteration 의 커서가 한칸씩 앞으로 가기 때문이라고 말하는 듯 하다. (_스택오버플로우의 질문글은 조건문 괄호 하나 안에 iter.next() 가 여러개 배치되어있었다 _)</p>
<p>따라서 iter.next() 를 하나의 객체로 받은 뒤에 접근하여 코드를 수정하니 오류는 해결되었다.</p>
<pre><code class="language-java">        Iterator&lt;Entry&lt;Integer,Integer&gt;&gt; iter = hash.entrySet().iterator();

        while (iter.hasNext()) {
            Entry&lt;Integer, Integer&gt; entry = iter.next();
            if (entry.getValue() == 1) {
                answer = entry.getKey();
                break;
            }
        }
</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[1. 싱글톤 패턴]]></title>
            <link>https://velog.io/@sonyak-ku/1.-%EC%8B%B1%EA%B8%80%ED%86%A4-%ED%8C%A8%ED%84%B4</link>
            <guid>https://velog.io/@sonyak-ku/1.-%EC%8B%B1%EA%B8%80%ED%86%A4-%ED%8C%A8%ED%84%B4</guid>
            <pubDate>Sat, 20 May 2023 18:42:00 GMT</pubDate>
            <description><![CDATA[<hr>
<p>요즘 푹 빠진 게임이 있다. 
샌드박스에서 나온 알비온 온라인이라는 게임인데, 이 게임은 맥이든 아이폰이든 아이패드든, 윈도우든 리눅스든 모든 곳에서 호환이 되는 게임이라고 홍보를 한다.
나도 실제로 아이패드로 자주 하고, 가지고 있는 윈도우 노트북으로도 하고 있다.</p>
<p><strong>그런데 만약?</strong></p>
<blockquote>
<p>내가 아이패드로 할 때의 설정과 윈도우로 할 때의 설정이 다르다면 어떻게 될까?</p>
</blockquote>
<p>한마디로 매우 불편할 것이다. 
즉, 기기는 달라도 내가 윈도우에서든, 아이패드에서든 어디서든 설정창을 열게 되면 나에게 보여지는 설정창은 &#39;하나&#39;여야만 한다.
말 그대로 각자 새로운 객체가 아닌 하나 여야 된다는 것.</p>
<blockquote>
<p>이런 상황일 때 필요한 것이 싱글톤 패턴 (Singleton Pattern) 이다. </p>
</blockquote>
<hr>
<h2 id="코드-구현---singleton">코드 구현 - Singleton</h2>
<pre><code class="language-java">// 클래스를 하나 만든다고 가정해보자

public class Setting {
    private static Setting instance; // 외부에서 접근할 수 없는 하나의 인스턴스 변수를 선언해두고

    private Setting() {}; // 외부에서 Setting 클래스의 객체 생성이 불가능 하게끔 하기 위해 private 생성자

    public static Setting getInstance() {

        if (instance == null) { // 선언한 인스턴스 변수가 초기화가 되지 않았을때
            instance = new Setting(); // 초기화 하여 객체 생성!
        } // 인스턴스 변수가 이미 초기화가 된 상태라면 해당 객체를 반환하여 같은 인스턴스 객체를 반환하게 된다.

        return instance; // 해당 객체를 반환한다.
    }


}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[error: array creation with both dimension expression and initialization is illegal]]></title>
            <link>https://velog.io/@sonyak-ku/error-array-creation-with-both-dimension-expression-and-initialization-is-illegal</link>
            <guid>https://velog.io/@sonyak-ku/error-array-creation-with-both-dimension-expression-and-initialization-is-illegal</guid>
            <pubDate>Sat, 20 May 2023 18:04:39 GMT</pubDate>
            <description><![CDATA[<p>배열을 선언할 때 만난 오류.</p>
<p>내 코드는 이러했다.</p>
<pre><code class="language-java">class Solution {
    public int[] twoSum(int[] nums, int target) {
        HashMap&lt;Integer, Integer&gt; hash = new HashMap&lt;&gt;();
        int[] answer = new int[2];  // 배열의 사이즈를 정해서 선언하고..

        for (int i = 0; i &lt; nums.length; i++) {
            if (hash.containsKey(nums[i])) {
                answer = {hash.get(nums[i]), i}; // 배열에 값을 넣어줬을 뿐. 그런데 오류가?      

            } else {
                hash.put(target - nums[i], i);
            } 
        }

        return answer;
    }
}</code></pre>
<p>그런데 위와 같은 오류가 나버렸다. </p>
<p>해결책을 알고 보니 에러 메시지가 상당히 직관적인 것을 깨달았다.</p>
<blockquote>
<p>배열의 사이즈 선언과 초기화(데이터 넣기)는 동시에 이루어 질 수 없다는 것! </p>
</blockquote>
<p>내 코드를 보면 배열의 사이즈를 2로 정한뒤
아래에서 {hash.get(nums[i]), i} 를 통해 초기화를 해주었는데 이러면 안된다는 것이다.</p>
<blockquote>
<p>오류를 해결하기 위해서는 빈 브래킷을 사용해서 초기화를 하거나, 사이즈를 정한뒤 인덱스로 접근해 하나하나 값을 넣으면 된다.</p>
</blockquote>
<p>방법 1.</p>
<pre><code class="language-java">class Solution {
    public int[] twoSum(int[] nums, int target) {
        HashMap&lt;Integer, Integer&gt; hash = new HashMap&lt;&gt;();
        int[] answer = new int[];  // 배열의 사이즈를 사용하지 않은 빈 브래킷을 사용하고

        for (int i = 0; i &lt; nums.length; i++) {
            if (hash.containsKey(nums[i])) {
                answer = {hash.get(nums[i]), i}; // 초기화한다 -&gt; 오류 해결!

            } else {
                hash.put(target - nums[i], i);
            } 
        }

        return answer;
    }
}</code></pre>
<p>방법 2.</p>
<pre><code class="language-java">class Solution {
    public int[] twoSum(int[] nums, int target) {
        HashMap&lt;Integer, Integer&gt; hash = new HashMap&lt;&gt;();
        int[] answer = new int[2};  // 배열의 사이즈를 정한뒤

        for (int i = 0; i &lt; nums.length; i++) {
            if (hash.containsKey(nums[i])) {
                answer[0] = hash.get(nums[i]); // 인덱스로 접근해 값을 넣어준다!
                answer[1] = i; // 오류 해결!

            } else {
                hash.put(target - nums[i], i);
            } 
        }

        return answer;
    }
}</code></pre>
<p><a href="https://stackoverflow.com/questions/14922270/how-is-this-illegal">스택오버플로우 위 에러메시지 관련 글</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[자료구조 5/13 - Heap]]></title>
            <link>https://velog.io/@sonyak-ku/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-513-Heap</link>
            <guid>https://velog.io/@sonyak-ku/%EC%9E%90%EB%A3%8C%EA%B5%AC%EC%A1%B0-513-Heap</guid>
            <pubDate>Sat, 13 May 2023 12:16:08 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/sonyak-ku/post/fde96a87-bcb7-4dd5-a92a-741a474f88fe/image.jpg" alt=""></p>
<h2 id="최소-힙-의-구조">최소 힙 의 구조</h2>
<p><img src="https://velog.velcdn.com/images/sonyak-ku/post/97d02e7c-8843-4f09-939e-bb8634a8fbf7/image.png" alt=""></p>
<h2 id="연관문제">연관문제</h2>
<p><a href="https://www.acmicpc.net/problem/24174">알고리즘 수업 - 백준 24174번</a></p>
<pre><code class="language-java">import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;


public class Hp {
    static int count = 0;
    static int stepCut;
    static void heap_sort(int[] arr) {
        int n = arr.length - 1;
        build_min_heap(arr, n);
        for (int i = n; i &gt; 1; i--) {
            int tmp = arr[1];
            arr[1] = arr[i];
            arr[i] = tmp;
            // 교환!
            count++;
            if (count == stepCut) {
                System.out.println(Arrays.toString(arr));
                return;
            }
            heapify(arr, 1, i - 1);
        }
    }

    static void build_min_heap(int[] arr, int size) {
        for (int i = size / 2; i &gt; 0; i--) {
            heapify(arr, i , size);
        }
    }

    static void heapify(int[] arr, int target, int size) {
        int left = 2 * target;
        int right = 2 * target + 1;
        int smaller = 0;

        if (right &lt;= size) {
            if (arr[left] &lt; arr[right]) {
                smaller = left;
            } else {
                smaller = right;
            }
        } else if (left &lt;= size) {
            smaller = left;
        } else {
            return;
        }

        if (arr[smaller] &lt; arr[target]) {
            int tmp = arr[target];
            arr[target] = arr[smaller];
            arr[smaller] = tmp;
            // 교환!
            count++;
            if (count == stepCut) {
                System.out.println(Arrays.toString(arr));
                return;
            }
            heapify(arr, smaller, size);
        }
    }

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String[] input = (br.readLine()).split(&quot; &quot;); // array size, exchange opportunity
        String[] numbers = (br.readLine()).split(&quot; &quot;);
        stepCut = Integer.parseInt(input[1]);

        int[] arr = new int[Integer.parseInt(input[0]) + 1];
        Arrays.fill(arr, 0);

        for (int i = 0; i &lt; numbers.length; i++) {
            arr[i + 1] = Integer.parseInt(numbers[i]);
        }
        heap_sort(arr);

        if (count &lt; stepCut) {
            System.out.println(-1);
        }
    }
}
</code></pre>
<p>무슨 문제인지 이해를 하지 못하고 있다가, 다른 분들의 글을 보고 나서 문제에 적혀있는 의사코드를 그대로 작성해서 이용하면 된다는 힌트를 얻고 풀 수 있었다. </p>
<p>의사코드를 처음으로 실제 코드로 작성해보았다. 처음엔 반복문 반대로 작성해서 코드 오류가 났는데 덕분에 의사코드를 좀 더 잘 알게 되었다.</p>
]]></description>
        </item>
    </channel>
</rss>