<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>y_bin.log</title>
        <link>https://velog.io/</link>
        <description>컴퓨터가 이해하는 코드는 바보도 작성할 수 있다. 사람이 이해하도록 작성하는 프로그래머가 진정한 실력자다. -마틴 파울러</description>
        <lastBuildDate>Mon, 06 Jan 2025 07:39:11 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>y_bin.log</title>
            <url>https://velog.velcdn.com/images/y_bin/profile/84989f06-2c90-434f-a692-4e0778751e22/image.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. y_bin.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/y_bin" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[카카오 로그인]]></title>
            <link>https://velog.io/@y_bin/%EC%B9%B4%EC%B9%B4%EC%98%A4-%EB%A1%9C%EA%B7%B8%EC%9D%B8</link>
            <guid>https://velog.io/@y_bin/%EC%B9%B4%EC%B9%B4%EC%98%A4-%EB%A1%9C%EA%B7%B8%EC%9D%B8</guid>
            <pubDate>Mon, 06 Jan 2025 07:39:11 GMT</pubDate>
            <description><![CDATA[<h3 id="kakao-login-api">Kakao Login API</h3>
<ul>
<li>카카오 계정을 통해 사용자가 애플리케이션에 로그인할 수 있도록 도와주는 인증 서비스</li>
<li>사용자는 카카오 계정으로 인증받고, 애플리케이션은 카카오를 통해 사용자 정보를 안전하게 받을 수 있음</li>
</ul>
<h3 id="jwt">JWT</h3>
<ul>
<li>클라이언트와 서버 간 정보를 안전하게 전달하기 위한 토큰</li>
<li>사용자 인증 후 서버에서 생성</li>
<li>API 요청 시 Authorization 헤더에 포함하여 서버에 전송</li>
<li>서버는 JWT 검증을 통해 사용자의 인증 상태 확인</li>
</ul>
<h3 id="oauth">OAuth</h3>
<ul>
<li>클라이언트가 리소스 소유자의 데이터를 안전하게 접근할 수 있도록 허가하는 프로토콜</li>
<li>제 3자 클라이언트가 사용자의 접근 권한을 위임받을 수 있는 표준 프로토콜</li>
</ul>
<h3 id="spring-security">Spring Security</h3>
<ul>
<li>요청 중간에 필터가 생기는 것</li>
</ul>
<h3 id="순서">순서</h3>
<ol>
<li>클라이언트가 카카오 로그인 요청</li>
<li>서버가 카카오 인증 서버로 OAuth 인가 코드 요청</li>
<li>사용자에게 인증 요청 및 로그인</li>
<li>카카오 인증 서버에서 인가 코드 발급</li>
<li>서버가 인가 코드를 사용하여 카카오 인증 서버에 접근 토큰 요청</li>
<li>카카오에서 받은 접근 토큰으로 사용자 정보를 요청하고 이 정보를 기반으로 애플리케이션 서버에서 JWT 생성</li>
<li>Spring Security를 통한 JWT 저장(로컬 저장소 / 쿠키) 및 관리</li>
<li>클라이언트가 API 요청 시 Authorization 헤더에 JWT를 포함하여 서버에 요청</li>
<li>Spring Security에서 요청을 가로채고 JWT의 유효성을 검증</li>
<li>Spring Security가 JWT검증을 통과하면 서버에서 접근 권한 허용 및 응답</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[Referer 헤더]]></title>
            <link>https://velog.io/@y_bin/Referer-%ED%97%A4%EB%8D%94</link>
            <guid>https://velog.io/@y_bin/Referer-%ED%97%A4%EB%8D%94</guid>
            <pubDate>Sun, 15 Dec 2024 07:00:26 GMT</pubDate>
            <description><![CDATA[<h2 id="referer-헤더">Referer 헤더</h2>
<ul>
<li>HTTP 요청의 일부</li>
<li>사용자가 현재 요청을 보내기 전에 방문했던 웹 페이지의 URL을 포함</li>
<li>웹 서버가 사용자의 이전 페이지를 알 수 있도록 도와줌</li>
<li>CORS 정책에 따라 다른 출처의 리소스에 대한 요청에서 Referer 헤더가 제한될 수 있음</li>
</ul>
<h3 id="용도">용도</h3>
<ol>
<li>트래픽 분석 : 사용자가 어떤 페이지에서 현재 페이지로 유입되었는지를 분석하여 트래픽 소스를 파악할 수 있음</li>
<li>보안 : 요청의 출처를 확인하고, 특정 페이지에서만 접근할 수 있도록 제한하는 등 보안 조치를 취할 수 있음</li>
<li>사용자 경험 개선 : 사용자가 이전에 방문한 페이지에 따라 맞춤형 콘텐츠를 제공하거나, 사용자가 어떤 경로로 사이트를 탐색했는지를 이해하는 데 도움을 줄 수 있음</li>
</ol>
<h3 id="형식">형식</h3>
<pre><code>Referer: https://example.com/previous-page</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[CSRF 공격]]></title>
            <link>https://velog.io/@y_bin/CSRF-%EA%B3%B5%EA%B2%A9</link>
            <guid>https://velog.io/@y_bin/CSRF-%EA%B3%B5%EA%B2%A9</guid>
            <pubDate>Sun, 15 Dec 2024 06:57:00 GMT</pubDate>
            <description><![CDATA[<h2 id="csrf-공격이란">CSRF 공격이란?</h2>
<ul>
<li>로그인한 사용자의 권한을 이용하여 웹사이트에 악성 요청을 보내는 것(사용자가 이미 로그인 한 상태에서 공격자가 사용자의 권한으로 요청을 보내는 것)</li>
<li>서버에서 발생 함</li>
<li>권한을 도용당한 클라이언트가 가짜 요청을 서버에게 전송하는 것</li>
</ul>
<h3 id="순서">순서</h3>
<ol>
<li>사용자가 A 사이트에 로그인</li>
<li>A사이트가 세션 쿠키를 브라우저에 저장</li>
<li>사용자가 악성 사이트 B를 방문</li>
<li>B사이트에서 악성 코드 실행(사용자의 세션 쿠키를 포함하여 A사이트로 전송)</li>
<li>A사이트는 이 요청을 정상적인 사용자로부터 온 요청으로 인식하고 처리</li>
</ol>
<h3 id="방어법">방어법</h3>
<ul>
<li>각 요청에 대해 고유한 CSRF 토큰을 생성하고 검증하여 요청의 유효성을 확인</li>
<li>CSRF 토큰을 HTML 폼에 숨겨진 필드로 추가하여 서버로 요청을 전송한 후 서버에서 세션에 저장된 토큰과 비교</li>
<li>쿠키에 SameSite 속성을 설정하여 외부 사이트에서의 요청에 대해 쿠키가 전송되지 않도록 함</li>
<li>요청의 Referer 헤더를 확인하여 요청이 신뢰할 수 있는 출처에서 온 것인지 검증</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JAVA] 프로그래머스 : 가장 큰 수]]></title>
            <link>https://velog.io/@y_bin/JAVA-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EA%B0%80%EC%9E%A5-%ED%81%B0-%EC%88%98-682jaeug</link>
            <guid>https://velog.io/@y_bin/JAVA-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EA%B0%80%EC%9E%A5-%ED%81%B0-%EC%88%98-682jaeug</guid>
            <pubDate>Tue, 08 Oct 2024 06:03:11 GMT</pubDate>
            <description><![CDATA[<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/42746">https://school.programmers.co.kr/learn/courses/30/lessons/42746</a></p>
<pre><code>import java.util.*;

class Solution {
    public String solution(int[] numbers) {
        String answer = &quot;&quot;;
        String[] arr = new String[numbers.length];
        boolean isZero = true;
        for(int i=0; i&lt;numbers.length; i++){
            arr[i] = numbers[i] + &quot;&quot;;
            if(!arr[i].equals(&quot;0&quot;)){
                isZero = false;
            }
        }
        //문자열 두 개를 이어 붙인 수를 내림차순 정렬
        // Arrays.sort(arr, new Comparator&lt;String&gt;(){
        //    @Override
        //     public int compare(String o1, String o2){ 
        //         return Integer.parseInt(o2+o1) - Integer.parseInt(o1+o2);
        //     }
        // });
        Arrays.sort(arr,(o1,o2)-&gt;Integer.parseInt(o2+o1) - Integer.parseInt(o1+o2));
        for(int i=0; i&lt;numbers.length; i++){
            answer += arr[i];
            if(isZero){
                answer = &quot;0&quot;;
            }
        }
        return answer;
    }
}</code></pre><p><img src="https://velog.velcdn.com/images/y_bin/post/1be3ce18-1e5e-42dd-a477-115f7e30dcc4/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Map.Entry]]></title>
            <link>https://velog.io/@y_bin/Map.Entry</link>
            <guid>https://velog.io/@y_bin/Map.Entry</guid>
            <pubDate>Wed, 02 Oct 2024 17:07:49 GMT</pubDate>
            <description><![CDATA[<h3 id="mapentry">Map.Entry</h3>
<ul>
<li>Java의 Map 인터페이스에서 제공하는 중첩 인터페이스</li>
<li>맵의 Key, Value 쌍을 쉽게 다루기 위해 사용</li>
<li>주로 Map의 entrySet() 메소드와 함께 사용하여 맵의 모든 엔트리를 반복할 때 유용</li>
</ul>
<h3 id="기본-문법">기본 문법</h3>
<pre><code>Map&lt;K, V&gt; map = new HashMap&lt;&gt;(); //map에 key-value 쌍 추가

for(Map.Entry&lt;K, V&gt; entry : map.entrySet()){
    K key = entry.getKey(); //키 가져오기
    V value = entry.getValue(); //값 가져오기
}</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[JAVA] 프로그래머스 : 신고 결과 받기]]></title>
            <link>https://velog.io/@y_bin/JAVA-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%8B%A0%EA%B3%A0-%EA%B2%B0%EA%B3%BC-%EB%B0%9B%EA%B8%B0</link>
            <guid>https://velog.io/@y_bin/JAVA-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%8B%A0%EA%B3%A0-%EA%B2%B0%EA%B3%BC-%EB%B0%9B%EA%B8%B0</guid>
            <pubDate>Wed, 02 Oct 2024 16:53:54 GMT</pubDate>
            <description><![CDATA[<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/92334">https://school.programmers.co.kr/learn/courses/30/lessons/92334</a></p>
<pre><code>import java.util.*;

class Solution {
    public int[] solution(String[] id_list, String[] report, int k) {
        //신고당한 user를 key로, 신고 user를 map으로 -&gt; 신고당한 user의 중복 알아서 제거
        //report : 신고자id 신고한id
        HashMap&lt;String, HashSet&lt;String&gt;&gt; map = new HashMap&lt;&gt;();
        HashSet&lt;String&gt; set;
        HashMap&lt;String, Integer&gt; cnt = new HashMap&lt;&gt;(); //처리 결과를 받은 유저

        for(int i=0; i&lt;report.length; i++){
            String[] input = report[i].split(&quot; &quot;);
            if(!map.containsKey(input[1])){ //신고당한 기록이 없는 경우
                set = new HashSet&lt;&gt;(); //새로운 해시셋 만들기
            }else{
                set = map.get(input[1]); //input[1]의 map 가져오기
            }
            set.add(input[0]); //set에 신고한 유저 추가
            map.put(input[1], set); //신고당한 유저에 set 추가
        }

        //이제 map에서의 value값인 set 탐색
        for(Map.Entry&lt;String, HashSet&lt;String&gt;&gt; entry : map.entrySet()){
            if(entry.getValue().size() &gt;= k){ //신고 횟수가 k 이상인 경우
                for(String s : entry.getValue()){  //값들을 하나씩 순회
                    cnt.put(s, cnt.getOrDefault(s,0)+1);
                }
            }
        }

        int[] answer = new int[id_list.length];
        for(int i=0; i&lt;id_list.length; i++){
            if(cnt.containsKey(id_list[i])){
                answer[i] = cnt.get(id_list[i]);
            }else{
                answer[i] = 0;
            }
        }
        return answer;
    }
}</code></pre><p><img src="https://velog.velcdn.com/images/y_bin/post/3046711a-8dbf-466c-bdae-c9622cedc90e/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JAVA] 프로그래머스 : 베스트앨범]]></title>
            <link>https://velog.io/@y_bin/JAVA-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EB%B2%A0%EC%8A%A4%ED%8A%B8%EC%95%A8%EB%B2%94</link>
            <guid>https://velog.io/@y_bin/JAVA-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EB%B2%A0%EC%8A%A4%ED%8A%B8%EC%95%A8%EB%B2%94</guid>
            <pubDate>Tue, 01 Oct 2024 09:17:49 GMT</pubDate>
            <description><![CDATA[<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/42579">https://school.programmers.co.kr/learn/courses/30/lessons/42579</a></p>
<p>HashMap 안에 ArrayList를 만드는 것 까지는 괜찮았지만, HashMap을 value값을 기준으로 정렬 하는 것이 어려웠다.</p>
<p>우선, Key에 해당하는 값을 가져와서 ArrayList에 담아야 한다. index에 key값을 저장하고, 각 방에 해당하는 값에 value를 저장하는 것이다.</p>
<pre><code>import java.util.*;

class Solution {
    public ArrayList solution(String[] genres, int[] plays) {
        //속한 노래가 많이 재생된 장르 -&gt; 장르 내에서 재생된 노래 -&gt; 재생 횟수가 같으면 고유 번호가 낮은 노래
        int len = genres.length;
        HashMap&lt;String, Integer&gt; cntMap = new HashMap&lt;&gt;(); //전체 재생 횟수를 구하기 위함
        HashMap&lt;String, ArrayList&lt;int[]&gt;&gt; map = new HashMap&lt;&gt;(); //장르, &lt;재생횟수, 고유번호&gt; 
        ArrayList&lt;Integer&gt; answer = new ArrayList&lt;&gt;();

        for(int i=0; i&lt;len; i++){ 
            if(cntMap.containsKey(genres[i])){
                cntMap.put(genres[i], cntMap.get(genres[i])+plays[i]);
            }else{
                cntMap.put(genres[i], plays[i]);
            }
        }

        for (int i=0; i&lt;len; i++) {
            if (!map.containsKey(genres[i])) { //키가 없으면
                map.put(genres[i], new ArrayList&lt;int[]&gt;()); //빈 배열 생성 -&gt; 이 과정을 안해주면 NullPointerException 발생
            }
            map.get(genres[i]).add(new int[]{plays[i], i}); //재생 횟수, 고유 번호 저장
        }

        //cntMap을 value값을 기준으로 정렬
        ArrayList&lt;String&gt; list = new ArrayList&lt;&gt;(cntMap.keySet());
        Collections.sort(list, new Comparator&lt;String&gt;(){
            @Override
            public int compare(String o1, String o2){
                return cntMap.get(o2) - cntMap.get(o1); //내림차순 정렬
            }
        });

        for(int i=0; i&lt;list.size(); i++){
            ArrayList&lt;int[]&gt; songs = map.get(list.get(i));
            Collections.sort(songs, new Comparator&lt;int[]&gt;(){
                @Override
                public int compare(int[] o1, int[] o2){
                    if(o1[0] == o2[0]){
                        return o1[1] - o2[1];
                    }
                    return o2[0] - o1[0];
                }
            });
            for(int j=0; j&lt;songs.size(); j++){
                if(j &gt;= 2){
                    break;
                }
                answer.add(songs.get(j)[1]);
            }
        }

        return answer;
    }
}</code></pre><p><img src="https://velog.velcdn.com/images/y_bin/post/ed39b6ca-7311-4ca0-a328-9d84b7f957a6/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JAVA] 프로그래머스 : 다항식 더하기]]></title>
            <link>https://velog.io/@y_bin/JAVA-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EB%8B%A4%ED%95%AD%EC%8B%9D-%EB%8D%94%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@y_bin/JAVA-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EB%8B%A4%ED%95%AD%EC%8B%9D-%EB%8D%94%ED%95%98%EA%B8%B0</guid>
            <pubDate>Sat, 21 Sep 2024 10:39:53 GMT</pubDate>
            <description><![CDATA[<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/120863#">https://school.programmers.co.kr/learn/courses/30/lessons/120863#</a></p>
<p>문자열에 x가 들어간다면 그 문자열은 x항인 것이다. 만약, 문자열이랑 x와 같다면 계수가 1인 것이다. 또한, 문자가 isDigit이면, 상수항인 것이다.</p>
<p>isDigit은 String으로 판단할 수 없기 때문에 charAt을 이용하여 그 한 자리 수를 Character로 변경하고 isDigit 메소드를 사용해 주엇다.</p>
<p>마지막으로, numCnt가 1인 경우에는 계수를 생략시켜서 문자열로 출력시켜 주어야 한다.</p>
<pre><code>class Solution {
    public String solution(String polynomial) {
        String[] input = polynomial.split(&quot; &quot;);
        int xCnt = 0; //계수
        int numCnt = 0; //상수항
        String answer = &quot;&quot;;
        for(int i=0; i&lt;input.length; i++){
            if(input[i].contains(&quot;x&quot;)){ //x항일 경우
                if(input[i].equals(&quot;x&quot;)){ //계수가 1일 경우
                    xCnt = xCnt + 1;
                }else{ //계수가 붙은 경우 -&gt; 계수가 두개인 경우도 생각해야함
                    input[i] = input[i].replace(&quot;x&quot;, &quot;&quot;);
                    xCnt += Integer.parseInt(input[i]);
                }
            }else if(Character.isDigit(input[i].charAt(0))){
                numCnt += Integer.parseInt(input[i]);
            }
        }

        if (numCnt &gt; 0 &amp;&amp; xCnt &gt; 0) {
            if(xCnt == 1){
                answer = &quot;x&quot; + &quot; + &quot; + numCnt;
            }else{
                answer = xCnt + &quot;x&quot; + &quot; + &quot; + numCnt;
            }
        } else if (numCnt &lt;= 0 &amp;&amp; xCnt &gt; 0) {
            if(xCnt == 1){
                answer = &quot;x&quot;;
            }else{
                answer = xCnt + &quot;x&quot;;
            }
        } else if (numCnt &gt; 0 &amp;&amp; xCnt &lt;= 0) {
            answer = numCnt + &quot;&quot;;
        } 
        return answer;
    }
}</code></pre><p><img src="https://velog.velcdn.com/images/y_bin/post/767d4a51-e521-4b8c-bdf0-030f11f4d85f/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JAVA] 프로그래머스 : 특이한 정렬]]></title>
            <link>https://velog.io/@y_bin/JAVA-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%ED%8A%B9%EC%9D%B4%ED%95%9C-%EC%A0%95%EB%A0%AC</link>
            <guid>https://velog.io/@y_bin/JAVA-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%ED%8A%B9%EC%9D%B4%ED%95%9C-%EC%A0%95%EB%A0%AC</guid>
            <pubDate>Sat, 21 Sep 2024 09:42:00 GMT</pubDate>
            <description><![CDATA[<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/120880">https://school.programmers.co.kr/learn/courses/30/lessons/120880</a></p>
<p>Comparator를 사용하면 쉽게 문제가 풀린다. compare메소드 안에 diffA와 diffB를 선언해준 후 문제를 풀면 된다. 이 문제를 풀고 나니 Comparator에 대한 감이 잡힌 것 같다.</p>
<pre><code>import java.util.*;

class Solution {
    public ArrayList solution(int[] numlist, int n) {
        int[] answer = {};
        ArrayList&lt;Integer&gt; list = new ArrayList&lt;&gt;();
        for(int i=0; i&lt;numlist.length; i++){
            list.add(numlist[i]);
        }
        Collections.sort(list, new Comparator&lt;Integer&gt;(){
           @Override
            public int compare(Integer a, Integer b){
                int diffA = Math.abs(a-n);
                int diffB = Math.abs(b-n);

                if(diffA == diffB){
                    //같으면 숫자가 큰 게 우선
                    return b-a;
                }
                return diffA - diffB;
            }
        });
        return list;
    }
}</code></pre><p><img src="https://velog.velcdn.com/images/y_bin/post/6c1e513d-45a9-4807-8633-18d2168725b0/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[반 정규화 기법]]></title>
            <link>https://velog.io/@y_bin/%EB%B0%98-%EC%A0%95%EA%B7%9C%ED%99%94-%EA%B8%B0%EB%B2%95</link>
            <guid>https://velog.io/@y_bin/%EB%B0%98-%EC%A0%95%EA%B7%9C%ED%99%94-%EA%B8%B0%EB%B2%95</guid>
            <pubDate>Fri, 20 Sep 2024 08:30:08 GMT</pubDate>
            <description><![CDATA[<h3 id="반-정규화">반 정규화</h3>
<ul>
<li>정규화된 엔티티, 속성, 관계에 대해 성능 향상과 개발 운영의 단순화를 위해 중복, 통합, 분리 등을 수행하는 데이터 모델링의 기법</li>
<li>데이터의 일관성과 무결성을 우선으로 할지, 데이터베이스의 성능과 단순화에 우선순위를 둘 것인지를 비교</li>
</ul>
<h4 id="장점">장점</h4>
<ul>
<li>성능 향상과 관리의 효율성 증가</li>
</ul>
<h4 id="단점">단점</h4>
<ul>
<li>데이터의 일관성 및 정합성 저하</li>
<li>유지를 위한 비용 발생 -&gt; 성능에 나쁜 영향을 미칠 수 있음</li>
</ul>
<h3 id="기법">기법</h3>
<table>
<thead>
<tr>
<th>구분</th>
<th>수행 방법</th>
<th>설명</th>
</tr>
</thead>
<tbody><tr>
<td>테이블</td>
<td>테이블 병합</td>
<td>1:1 관계, 1:M 관계를 통합하여 조인 횟수를 줄여 성능을 향상</td>
</tr>
<tr>
<td></td>
<td>테이블 분할</td>
<td>테이블을 수직 혹은 수평으로 분할</td>
</tr>
<tr>
<td></td>
<td>중복 테이블 추가</td>
<td>대량의 데이터들에 대한 집계함수를 사용하여 실시간 통계정보를 계산하는 경우 -&gt; 별도의 통계 테이블을 두거나 중복 테이블을 추가</td>
</tr>
<tr>
<td>컬럼</td>
<td>컬럼 중복화</td>
<td>조인 성능 향상을 위한 중복 허용</td>
</tr>
<tr>
<td>관계</td>
<td>중복관계 추가</td>
<td>성능 저하를 예방하기 위해 추가적 관계를 맺는 방법</td>
</tr>
</tbody></table>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JAVA] 프로그래머스 : 제곱수 판별하기]]></title>
            <link>https://velog.io/@y_bin/JAVA-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%A0%9C%EA%B3%B1%EC%88%98-%ED%8C%90%EB%B3%84%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@y_bin/JAVA-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%A0%9C%EA%B3%B1%EC%88%98-%ED%8C%90%EB%B3%84%ED%95%98%EA%B8%B0</guid>
            <pubDate>Fri, 20 Sep 2024 06:25:55 GMT</pubDate>
            <description><![CDATA[<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/120909">https://school.programmers.co.kr/learn/courses/30/lessons/120909</a></p>
<p>Math.sqrt()는 return type이 double이다. 이것을 몰라서 테스트 케이스 7,8번 통과를 못했었다. 제곱근의 값을 정수로 강제형변환 한 후 제출하니 모든 테스트 케이스를 통과하였다.</p>
<pre><code>import java.util.*;

class Solution {
    public int solution(int n) {
        int answer = 2;
        //n이 제곱수면 1, 아니면 2
        if(n == (int)Math.sqrt(n) * (int)Math.sqrt(n)){
            answer = 1;
        }
        return answer;
    }
}</code></pre><p><img src="https://velog.velcdn.com/images/y_bin/post/707fe20a-750c-4658-bd6e-f8ee6b53543b/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[코딩 기초 트레이닝 캘린더 완성]]></title>
            <link>https://velog.io/@y_bin/%EC%BD%94%EB%94%A9-%EA%B8%B0%EC%B4%88-%ED%8A%B8%EB%A0%88%EC%9D%B4%EB%8B%9D-%EC%BA%98%EB%A6%B0%EB%8D%94-%EC%99%84%EC%84%B1</link>
            <guid>https://velog.io/@y_bin/%EC%BD%94%EB%94%A9-%EA%B8%B0%EC%B4%88-%ED%8A%B8%EB%A0%88%EC%9D%B4%EB%8B%9D-%EC%BA%98%EB%A6%B0%EB%8D%94-%EC%99%84%EC%84%B1</guid>
            <pubDate>Fri, 20 Sep 2024 06:17:29 GMT</pubDate>
            <description><![CDATA[<p>약 한 달 정도가 소요되었다. 솔직히 말하면 더 열심히 할 수 있었는데, 미루고 미루다가 생각보다 늦어진 것 같다. 입문 문제도 빨리 완료한 후, 어려운 문제도 많이 풀어봐야겠다.</p>
<p><img src="https://velog.velcdn.com/images/y_bin/post/a04f4566-7125-46cb-8db2-603e97d54a20/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JAVA] 프로그래머스 : 그림 확대]]></title>
            <link>https://velog.io/@y_bin/JAVA-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EA%B7%B8%EB%A6%BC-%ED%99%95%EB%8C%80</link>
            <guid>https://velog.io/@y_bin/JAVA-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EA%B7%B8%EB%A6%BC-%ED%99%95%EB%8C%80</guid>
            <pubDate>Fri, 20 Sep 2024 06:16:17 GMT</pubDate>
            <description><![CDATA[<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/181836">https://school.programmers.co.kr/learn/courses/30/lessons/181836</a></p>
<p>각 문자를 k번 반복해 새로운 문자열을 만들고, 그 새로운 문자열을 k번 반복해 ArrayList에 넣어 주면 된다.</p>
<pre><code>import java.util.*;

class Solution {
    public ArrayList solution(String[] picture, int k) {
        int len = picture.length;
        ArrayList&lt;String&gt; list = new ArrayList&lt;&gt;();
        for(int i=0; i&lt;len; i++){
            String newStr = &quot;&quot;;
            String[] str = picture[i].split(&quot;&quot;);
            for(int j=0; j&lt;str.length; j++){
                for(int a=0; a&lt;k; a++){
                    newStr += str[j];
                }
            }
            for(int j=0; j&lt;k; j++){
                list.add(newStr);
            }
        }
        return list;
    }
}</code></pre><p><img src="https://velog.velcdn.com/images/y_bin/post/81a00c55-1714-44bf-aa0b-a62759f82c98/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JAVA] 백준 1913번 : 달팽이]]></title>
            <link>https://velog.io/@y_bin/JAVA-%EB%B0%B1%EC%A4%80-1913%EB%B2%88-%EB%8B%AC%ED%8C%BD%EC%9D%B4</link>
            <guid>https://velog.io/@y_bin/JAVA-%EB%B0%B1%EC%A4%80-1913%EB%B2%88-%EB%8B%AC%ED%8C%BD%EC%9D%B4</guid>
            <pubDate>Thu, 19 Sep 2024 19:12:49 GMT</pubDate>
            <description><![CDATA[<p><a href="https://www.acmicpc.net/problem/1913">https://www.acmicpc.net/problem/1913</a></p>
<h3 id="반례">반례</h3>
<h4 id="입력">입력</h4>
<p>3
1</p>
<h4 id="정답">정답</h4>
<p>9 2 3 
8 1 4 
7 6 5 
2 2</p>
<p>위의 반례를 찾지 못해서 시간이 많이 소요되었다. 위의 반례의 경우에는 while문이 돌기 전의 조건(arr[rowStart][colStart] = num++;의 조건)이므로 내가 따로 지정을 해 주어야 한다.</p>
<pre><code>package silver3;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class num1913 {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int N = Integer.parseInt(br.readLine());
        int inputNum = Integer.parseInt(br.readLine());
        int num = 1; // 시작 수
        int[][] arr = new int[N][N];
        int x = 0;
        int y = 0;

        int rowStart = N / 2;
        int colStart = N / 2;

        arr[rowStart][colStart] = num++;
        if (arr[rowStart][colStart] == inputNum) {
            x = N / 2;
            y = N / 2;
        }
        int steps = 1; // 나선의 초기 크기

        while (num &lt;= N * N) {
            for (int i = 0; i &lt; steps; i++) {
                if (num &gt; N * N) {
                    break;
                }
                rowStart--; //위로
                arr[rowStart][colStart] = num++;
                if (arr[rowStart][colStart] == inputNum) {
                    x = rowStart;
                    y = colStart;
                }
            }

            for (int i = 0; i &lt; steps; i++) {
                if (num &gt; N * N) {
                    break;
                }
                colStart++; //오른쪽으로
                arr[rowStart][colStart] = num++;
                if (arr[rowStart][colStart] == inputNum) {
                    x = rowStart;
                    y = colStart;
                }
            }
            steps++;

            for (int i = 0; i &lt; steps; i++) {
                if (num &gt; N * N) {
                    break;
                }
                rowStart++; //아래로
                arr[rowStart][colStart] = num++;
                if (arr[rowStart][colStart] == inputNum) {
                    x = rowStart;
                    y = colStart;
                }
            }

            for (int i = 0; i &lt; steps; i++) {
                if (num &gt; N * N) {
                    break;
                }
                colStart--; //왼쪽으로
                arr[rowStart][colStart] = num++;
                if (arr[rowStart][colStart] == inputNum) {
                    x = rowStart;
                    y = colStart;
                }
            }
            steps++;
        }

        for (int i = 0; i &lt; N; i++) {
            for (int j = 0; j &lt; N; j++) {
                System.out.print(arr[i][j] + &quot; &quot;);
            }
            System.out.println();
        }
        System.out.println((x + 1) + &quot; &quot; + (y + 1));
    }
}
</code></pre><p><img src="https://velog.velcdn.com/images/y_bin/post/ac065728-d0a6-46d9-a75b-9e49f8271793/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JAVA] 프로그래머스 : 정수를 나선형으로 배치하기]]></title>
            <link>https://velog.io/@y_bin/JAVA-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%A0%95%EC%88%98%EB%A5%BC-%EB%82%98%EC%84%A0%ED%98%95%EC%9C%BC%EB%A1%9C-%EB%B0%B0%EC%B9%98%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@y_bin/JAVA-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%A0%95%EC%88%98%EB%A5%BC-%EB%82%98%EC%84%A0%ED%98%95%EC%9C%BC%EB%A1%9C-%EB%B0%B0%EC%B9%98%ED%95%98%EA%B8%B0</guid>
            <pubDate>Thu, 19 Sep 2024 09:24:42 GMT</pubDate>
            <description><![CDATA[<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/181832">https://school.programmers.co.kr/learn/courses/30/lessons/181832</a></p>
<p>우선, n이 4일때를 기준으로 문제를 이해해 보자.</p>
<p>첫 번째 for문을 보면 같은 행에서 시작을 한다. 즉, 0번째 줄에서 시작하는 것이다. 0번째 줄에서 시작해서 열(세로줄)을 하나씩 채우는 것이다. 그러면 배열의 첫 번째 줄에 1,2,3,4가 들어간다. 그 다음, rowStart를 1 증가시켜 시작 행을 1 증가시켜준다.</p>
<p>그 다음, 두 번째 for문을 보면 맨 마지막 열에서 그 아래로 내려가는 로직이다. 그럼 맨 마지막 줄의 세로줄이 4,5,6,7이 채워진다. 그 다음 맨 마지막 열을 채웠으므로 colEnd를 1 줄여주어 끝 열을 하나 단축시켜준다.</p>
<p>그 다음에는 for문을 이용하여 1씩 감소시켜 반복시켜 주면 된다.</p>
<h3 id="정답-코드-1">정답 코드 1</h3>
<pre><code>class Solution {
    public int[][] solution(int n) {
        int[][] answer = new int[n][n];
        int num = 1; //배치할 숫자
        int rowStart = 0; //행(가로)
        int rowEnd = n-1;
        int colStart = 0; //열(세로)
        int colEnd = n-1;
        //처음에는 오른쪽 끝까지 이동
        while(rowStart &lt;= rowEnd &amp;&amp; colStart &lt;= colEnd){ //아직 채우지 않은 행과 열이 있는지 판단
            for(int i=colStart; i&lt;=colEnd; i++){ //세로꺼를 하나하나 채워야 함
                answer[rowStart][i] = num++; //0번째 행
            }
            rowStart++; //행 증가

            for(int i=rowStart; i&lt;=rowEnd; i++){
                answer[i][colEnd] = num++; //맨 마지막 가로줄 하나씩 채우기
            }
            colEnd --; //한 칸 왼쪽으로

            if(rowStart &lt;= rowEnd){
                for(int i=colEnd; i&gt;=colStart; i--){
                    answer[rowEnd][i] = num++; //세로 채우기
                }
                rowEnd --; //한 칸 오른쪽으로
            }

            if(colStart &lt;= colEnd){
                for(int i=rowEnd; i&gt;=rowStart; i--){
                    answer[i][colStart] = num++; //가로 채우기
                }
                colStart ++;
            }
        }
        return answer;
    }
}</code></pre><p><img src="https://velog.velcdn.com/images/y_bin/post/27a0d20a-a189-43df-9b20-d5475a3b19cc/image.png" alt=""></p>
<h3 id="정답-코드-2">정답 코드 2</h3>
<p>이 코드는 dx, dy를 사용하는 코드이다. 이 코드를 이해하는데 더 어려웠지만, 코드를 이해하고 나니 더 쉬웠다.</p>
<p>way는 방향을 나타내는 변수이다. 즉, dx와 dy를 합쳐 보면 {오른쪽, 아래, 왼쪽, 위}의 순서로 탐색을 진행한다. dx는 x좌표를, dy는 y좌표에 관여한다고 생각하면 이해하기가 쉽다.</p>
<p>좌표를 보면 헷갈리기 때문에 코드로 살펴봐야 한다. 
0,0부터 시작이기 때문에 answer[0][0] = 1, visited[0][0] = true가 된다. 이 때 if문의 조건에 부합하지 않기 때문에 if문을 건너뛴다. 그러면 그 다음 while문의 반복에서 마지막 조건인 visited[0][0]==true에서 걸리기 때문에 way를 1 증가시켜준다. 그러면 x=0, y=1이 되고, answer[0][1] = 2, visited[0][1] = true가 되는 것이다.</p>
<p>즉, (0,0) -&gt; (0,1)의 순서로 좌표가 채워지는 것이다.</p>
<p>만약, 나선의 방향을 변경하고 싶다면 dx,dy의 순서를 변경하면 된다.</p>
<pre><code>import java.util.*;

class Solution {
    public int[][] solution(int n) {
        int[] dx = {1,0,-1,0};
        int[] dy = {0,1,0,-1};

        boolean[][] visited = new boolean[n][n];
        int x = 0;
        int y = 0;
        int num = 1;
        int way = 0;
        int[][] answer = new int[n][n];
        while(num &lt;= Math.pow(n,2)){
            answer[x][y] = num;
            visited[x][y] = true;
            if(x + dx[way] &lt; 0 || x + dx[way] &gt;= n || y + dy[way] &lt; 0 || y + dy[way] &gt;= n || visited[x+dx[way]][y+dy[way]]==true){
                way++;
                way %= 4;
            }
            //위의 조건을 모두 통과하는 경우에만 이동
            x = x + dx[way];
            y = y + dy[way];
            num++;
        }
        return answer;
    }
}</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[[JAVA] 프로그래머스 : 정사각형으로 만들기]]></title>
            <link>https://velog.io/@y_bin/JAVA-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%A0%95%EC%82%AC%EA%B0%81%ED%98%95%EC%9C%BC%EB%A1%9C-%EB%A7%8C%EB%93%A4%EA%B8%B0</link>
            <guid>https://velog.io/@y_bin/JAVA-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%A0%95%EC%82%AC%EA%B0%81%ED%98%95%EC%9C%BC%EB%A1%9C-%EB%A7%8C%EB%93%A4%EA%B8%B0</guid>
            <pubDate>Tue, 17 Sep 2024 19:14:37 GMT</pubDate>
            <description><![CDATA[<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/181830">https://school.programmers.co.kr/learn/courses/30/lessons/181830</a></p>
<pre><code>import java.util.*;

class Solution {
    public int[][] solution(int[][] arr) {
        int rows = arr.length; //행 -&gt; 가로줄
        int coll = arr[0].length; //열 -&gt; 안의 각각 요소
        int size = Math.max(rows, coll); //둘 중 더 큰 사이즈 찾기
        int[][] answer = new int[size][size];
        for(int i=0; i&lt;size; i++){
            //각 요소를 복사해서 넣기
            if(i &lt; rows){
                answer[i] = Arrays.copyOf(arr[i], size);
            }else{
                Arrays.fill(answer[i], 0);
            }
        }
        return answer;
    }
}</code></pre><p><img src="https://velog.velcdn.com/images/y_bin/post/c4bac8dd-acb8-4aad-8e9d-0c63305ed778/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[회고 : 최우수상 🥇]]></title>
            <link>https://velog.io/@y_bin/%ED%9A%8C%EA%B3%A0-%EC%B5%9C%EC%9A%B0%EC%88%98%EC%83%81</link>
            <guid>https://velog.io/@y_bin/%ED%9A%8C%EA%B3%A0-%EC%B5%9C%EC%9A%B0%EC%88%98%EC%83%81</guid>
            <pubDate>Sun, 15 Sep 2024 07:17:45 GMT</pubDate>
            <description><![CDATA[<p>9월 11일에 드디어!!! 발표를 했다!! </p>
<p>전 날 여태까지 했던 프로젝트인 오목, 축하해요, 그리고 이번 쏠거지까지 전시를 하고 스티커도 제작했었다.</p>
<p>발표장에는 무려 신한 ds 본부장님도 오시고, 그 외에도 정말 많은 높으신 분들이 와 주셨다. 대략 10분정도 되는 것 같았다 ㅎㅎ </p>
<p>심지어 아침에 커피차도 와 있었다. 인당 커피 한 잔에 츄러스까지 주셨다 ㅠㅠ 저 때 먹은 츄러스는 지금도 먹고싶을 정도로 맛있었다..🤤</p>
<p><img src="https://velog.velcdn.com/images/y_bin/post/24897b29-43dd-46c9-863b-a4725893b703/image.png" alt=""></p>
<p>발표는 옆반까지 총 합쳐서 8팀이서 했는데, 5회차(우리반), 6회차 순서대로 한 팀씩 번갈아가면서 진행하였다. 앞 4팀이 1부, 뒷 4팀이 2부였는데, 우리팀은 2부 두 번째 순서였다.</p>
<p>팀장 언니가 발표를 하고, 팀원 전체가 나가서 질의응답을 받았다. 애초에 발표도 잘했었던지라 분위기가 좋았는데, 질의응답에서 웃음이 많이 터졌다. 이 때 속으로 솔직히 상을 기대했던 것 같다 ㅎㅎ</p>
<p>한 분이 우리 발표에 대한 피드백 및 앞으로 추가하면 좋을 것 같은 기능을 말씀해 주셨는데, 내가 &quot;신한 쏠에 저희 프로젝트 끼워주시면 추진해 보겠습니다!!&quot; 라고 답했다. 이 말에 다들 웃음을 터뜨려 주셔서 너무 감사했다ㅠㅠ</p>
<p>발표 전, 쉬는시간에 우리 팀이 만든 스티커를 나눠드리며 &quot;부자되세요~&quot;라고 외치고 다녔었고, 발표 때도 팀원 모두가 옷에 스티커를 하나씩 붙이고 나갔었다.</p>
<p><img src="https://velog.velcdn.com/images/y_bin/post/68fd6d5b-4014-4226-903c-facecb67a019/image.png" alt=""></p>
<p><img src="https://velog.velcdn.com/images/y_bin/post/daae0482-b867-4308-9ecc-107200d4c393/image.png" alt=""></p>
<p>전반적으로 우리 팀의 좋았던 분위기가 발표에서도 잘 드러난 것 같아서 너무 뿌듯했다. 이를 좋게 봐주신 덕분인지, 우리 팀은 최우수상을 수상하였다 !!!!</p>
<p>정말 너무 기분이 좋아서 웃음이 감춰지지 않았다ㅠㅠ 우리 팀은 팀원의 평균 나이도 가장 어렸고, 인원수도 가장 적었던 팀이었기에 솔직히 최우수상까지는 기대하지 않았었는데, 놀랍게도 최우수상이었기 때문이다!!ㅠㅠ</p>
<p><img src="https://velog.velcdn.com/images/y_bin/post/e5e8b1d2-1669-4169-ad7d-eb6ca567d3ee/image.png" alt=""></p>
<p>이후 시상식이 끝나고, 강점 멘토링을 해 주셨던 분께서 소감을 말씀해 주셨는데, 그 분도 스티커를 옷에 붙이고 나와주셨다. 상당히 기억에 남는 팀이었다면서 스티커를 붙여 주셨는데, 진짜 너무 감동받았고 좋게 봐 주셔서 너무너무 감사드렸다.</p>
<p><img src="https://velog.velcdn.com/images/y_bin/post/2d4286a6-7e4e-4940-b837-88f6ba72771b/image.png" alt=""></p>
<p>그동안 노력했던 것이 헛되지 않았음이 증명되었고, 모두에게 인정받는 기분이었다. 무엇보다 이력서에 추가할 수상 경력이 한 줄 생겨서 너무 행복했고, 학원 수료식이 끝난 지금 시점까지도 너무너무 행복하다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JAVA] 프로그래머스 : 날짜 비교하기]]></title>
            <link>https://velog.io/@y_bin/JAVA-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EB%82%A0%EC%A7%9C-%EB%B9%84%EA%B5%90%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@y_bin/JAVA-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EB%82%A0%EC%A7%9C-%EB%B9%84%EA%B5%90%ED%95%98%EA%B8%B0</guid>
            <pubDate>Sun, 15 Sep 2024 06:44:58 GMT</pubDate>
            <description><![CDATA[<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/181838#">https://school.programmers.co.kr/learn/courses/30/lessons/181838#</a></p>
<p>반례를 찾는 것에서 살짝 시간 소요가 되었다.
<img src="https://velog.velcdn.com/images/y_bin/post/e350d06e-6ba5-4261-b505-05479b647f49/image.png" alt=""></p>
<pre><code>class Solution {
    public int solution(int[] date1, int[] date2) {
        int answer = 1;
        if(date1[0] &gt; date2[0]){ //앞에꺼의 연도가 더 크면
            answer = 0;
        }else if(date1[0] == date2[0]){ //연도가 같으면
            if(date1[1] &gt; date2[1]){
                answer = 0;
            }else if(date1[1] == date2[1]){
                if(date1[2] &gt;= date2[2]){
                    answer = 0;
                }
            }
        }
        return answer;
    }
}</code></pre><p><img src="https://velog.velcdn.com/images/y_bin/post/4b7de3f9-0637-432c-9274-5d3fbf222967/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JAVA] 백준 1743번 : 음식물 피하기]]></title>
            <link>https://velog.io/@y_bin/JAVA-%EB%B0%B1%EC%A4%80-1743%EB%B2%88-%EC%9D%8C%EC%8B%9D%EB%AC%BC-%ED%94%BC%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@y_bin/JAVA-%EB%B0%B1%EC%A4%80-1743%EB%B2%88-%EC%9D%8C%EC%8B%9D%EB%AC%BC-%ED%94%BC%ED%95%98%EA%B8%B0</guid>
            <pubDate>Sun, 15 Sep 2024 04:56:11 GMT</pubDate>
            <description><![CDATA[<p><a href="https://www.acmicpc.net/problem/1743">https://www.acmicpc.net/problem/1743</a></p>
<p>이 문제는 dfs를 이용하여 푸는 문제이다. 음식물 쓰레기가 있다고 가정한 후, 상하좌우를 비교하여 연속된 곳에 있으면 그 곳을 찾으면 된다. 
즉, 주어진 2차원 배열에서 음식물 쓰레기가 있는 위치를 기준으로 dfs를 수행하며, 인접한 음식물 쓰레기의 개수를 세는 방식인 것이다. 배열을 순회하며 음식물 쓰레기가 있으면 dfs를 호출하고, 상하좌우의 인접한 위치를 탐색하면서 아직 방문하지 않은 음식물 쓰레기가 있는 경우 dfs를 또 호출하여 깊이를 탐색하는 것이다.</p>
<pre><code>import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;

public class Main {
    public static boolean[][] visited;
    public static int[][] arr;
    public static int N, M, K, answer, max;
    public static int[] dx = {-1, 1, 0, 0};
    public static int[] dy = {0, 0, -1, 1};

    public static void main(String[] args) throws IOException {
        //방문한 적이 없고 쓰레기라면 dfs 탐색
        //가장 큰 음식물 쓰레기의 개수를 구하는 거니까 인접한 경우(위, 아래가 붙은 경우) 1씩 더해주면 됨
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String[] input1 = br.readLine().split(&quot; &quot;);
        N = Integer.parseInt(input1[0]); //통로의 세로 길이
        M = Integer.parseInt(input1[1]); //통로의 가로 길이
        K = Integer.parseInt(input1[2]); //떨어진 음식물 쓰레기의 개수
        arr = new int[N][M]; //세로 가로
        visited = new boolean[N][M];
        for (int i = 0; i &lt; K; i++) { //음식물 쓰레기가 있는 곳을 입력
            String[] input = br.readLine().split(&quot; &quot;);
            int r = Integer.parseInt(input[0]); //위에서부터(세로)
            int c = Integer.parseInt(input[1]); //왼쪽에서부터(가로)
            arr[r - 1][c - 1] = 1;
        }
        max = 0;
        for (int i = 0; i &lt; N; i++) {
            for (int j = 0; j &lt; M; j++) {
                if (arr[i][j] == 1 &amp;&amp; !visited[i][j]) { //쓰레기이고 방문하지 않은 경우에만 탐색
                    answer = 0;
                    dfs(i, j);
                    if (answer &gt; max) {
                        max = answer;
                    }
                }
            }
        }
        System.out.println(max);
        br.close();
    }

    public static void dfs(int x, int y) {
        visited[x][y] = true;
        answer++;

        for (int i = 0; i &lt; 4; i++) {
            int nowX = x + dx[i];
            int nowY = y + dy[i];

            if (nowX &gt;= 0 &amp;&amp; nowY &gt;= 0 &amp;&amp; nowX &lt; N &amp;&amp; nowY &lt; M) {
                if (!visited[nowX][nowY] &amp;&amp; arr[nowX][nowY] == 1) {
                    dfs(nowX, nowY);
                }
            }
        }
    }
}
</code></pre><p><img src="https://velog.velcdn.com/images/y_bin/post/b7dee875-198d-4fb5-acd7-9cc6f62f5508/image.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JAVA] 프로그래머스 : 0 떼기]]></title>
            <link>https://velog.io/@y_bin/JAVA-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-0-%EB%96%BC%EA%B8%B0</link>
            <guid>https://velog.io/@y_bin/JAVA-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-0-%EB%96%BC%EA%B8%B0</guid>
            <pubDate>Sun, 15 Sep 2024 03:23:43 GMT</pubDate>
            <description><![CDATA[<p><a href="https://school.programmers.co.kr/learn/courses/30/lessons/181847">https://school.programmers.co.kr/learn/courses/30/lessons/181847</a></p>
<p>이 숫자는 앞에 있는 0을 제거하는 문제이다. 처음에는 문자열의 replace, substring을 사용해서 문제를 풀었었는데, 그냥 string값을 int로 변환해 주면 되는 문제였다!!</p>
<pre><code>class Solution {
    public String solution(String n_str) {
        //String을 정수로 변환하면 됨
        int num = Integer.parseInt(n_str);
        return num+&quot;&quot;;
    }
}</code></pre><p><img src="https://velog.velcdn.com/images/y_bin/post/910b105e-b316-4e4c-b390-42a8a240f106/image.png" alt=""></p>
]]></description>
        </item>
    </channel>
</rss>