<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>inhye-world.log</title>
        <link>https://velog.io/</link>
        <description>avocadoxxi</description>
        <lastBuildDate>Thu, 04 Mar 2021 06:16:56 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>inhye-world.log</title>
            <url>https://images.velog.io/images/inhye-world/profile/1f95064f-2b1b-4143-9564-1608e6458cdf/20190714_030629_001.jpg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. inhye-world.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/inhye-world" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[파일 종류]]></title>
            <link>https://velog.io/@inhye-world/%ED%8C%8C%EC%9D%BC-%EC%A2%85%EB%A5%98</link>
            <guid>https://velog.io/@inhye-world/%ED%8C%8C%EC%9D%BC-%EC%A2%85%EB%A5%98</guid>
            <pubDate>Thu, 04 Mar 2021 06:16:56 GMT</pubDate>
            <description><![CDATA[<p>✔ Jar : 하나의 어플리케이션 기능이 가능하도록 java 파일 등을 압축하고 지원한다. Path 등의 경로를 유지하므로 배포된 jar 파일을 사용하는 사용자들은 각 파일들에 대한 path로 인한 문제를 방지할 수 있다고 함</p>
<p>✔ War : jar와는 다르게 웹 어플리케이션을 지원하기 위한 압축방식이다. 웹 어플리케이션을 지원하기 위해서 war 압축 방식은 jsp, servlet, gif, html, jar등을 압축한다.
이 말인 즉슨, jar와 같은 맥락으로 servlet context 접근을 위해 관련된 모든 파일들을 패키지화한다.</p>
<p>✔ Ear : 하나의 웹어플리케이션 단위를 넘어 실제 서버에서 배포하기 위한 단위. 이를 위해서 jar와 war를 묶어서 각각의 기능을 지원해준다.
jar -&gt; 어플리케이션 레벨 (business layer) 지원
war -&gt; 웹어플리케이션 레벨 (web layer) 지원</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[telnet]]></title>
            <link>https://velog.io/@inhye-world/telnet</link>
            <guid>https://velog.io/@inhye-world/telnet</guid>
            <pubDate>Fri, 26 Feb 2021 05:41:02 GMT</pubDate>
            <description><![CDATA[<p>✔ 특정 사용자가 네트워크를 통해 다른 컴퓨터에 연결하여 해당 컴퓨터에서 제공하는 서비스를 받을 수 있도록 하는 인터넷 표준 프로토콜</p>
<blockquote>
<p>ssh (secure shell)
다른 사용자가 세션을 엿듣지 못하도록 세션을 감싸주는 텔넷 응용프로그램</p>
</blockquote>
<blockquote>
<p>그렇다면 둘의 차이는?
사용자 입장에서는 별 차이를 느끼지 못함
그러나,
사용자가 어떤 작업을 서버에 알려주기 위해 네트워크를 통해서 서버에 TCP/IP  패킷 정보를 전달하고 결과값을 다시 서버에게 전달한다.
이때, telnet은 정보를 byte 스트림 형식으로 주고받는다.
ssh는 DES, RSA 등 고급 암호화를 통해 통신한다. telnet 보다는 안전성이 좋다.</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[깊이 넓이 우선 탐색]]></title>
            <link>https://velog.io/@inhye-world/%EA%B9%8A%EC%9D%B4-%EB%84%93%EC%9D%B4-%EC%9A%B0%EC%84%A0-%ED%83%90%EC%83%89</link>
            <guid>https://velog.io/@inhye-world/%EA%B9%8A%EC%9D%B4-%EB%84%93%EC%9D%B4-%EC%9A%B0%EC%84%A0-%ED%83%90%EC%83%89</guid>
            <pubDate>Mon, 15 Feb 2021 13:30:47 GMT</pubDate>
            <description><![CDATA[<pre><code>class Solution {
    //계산한 값이 target이랑 같아지는 순간까지 재귀함수로 돌린다
    public int dfs(int prev, int idx, int[] numbers, int target) {
        if(idx &gt;= numbers.length){
            if(prev == target){
                //첫번째 숫자부터 같아져 버릴때
                return 1;
            }

            //그 어떤 수도 같은게 없을 때
            return 0;
        }

        int cur1 = prev + numbers[idx]; //더할 때
        int cur2 = prev - numbers[idx]; //뺄 때

        int ans = 0;

        ans += dfs(cur1, idx+1, numbers, target);
        ans += dfs(cur2, idx+1, numbers, target);

        return ans;
    }

    public int solution(int[] numbers, int target) {
        int answer = 0;

        int current = numbers[0];

        answer += dfs(current, 1, numbers, target);
        answer += dfs(-current, 1, numbers, target);

        return answer;
    }
}</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[아카이브 관련 개념들]]></title>
            <link>https://velog.io/@inhye-world/%EC%95%84%EC%B9%B4%EC%9D%B4%EB%B8%8C-%EA%B4%80%EB%A0%A8-%EA%B0%9C%EB%85%90%EB%93%A4</link>
            <guid>https://velog.io/@inhye-world/%EC%95%84%EC%B9%B4%EC%9D%B4%EB%B8%8C-%EA%B4%80%EB%A0%A8-%EA%B0%9C%EB%85%90%EB%93%A4</guid>
            <pubDate>Tue, 09 Feb 2021 14:09:56 GMT</pubDate>
            <description><![CDATA[<p>교육을 받다가 공부해오라는 개념이 있어서 정리하려한다.</p>
<p>😺 tiles</p>
<blockquote>
<p>그동안의 프로젝트에서는 header, footer jsp 파일을 따로 만들어서 jsp include를 통해 한 화면을 구현했지만, 이것은 일관된 레이아웃 적용에 대한 보장이 없었다.
<strong>tiles는 웹 화면의 레이아웃을 간단하게 정의할 수 있는 템플릿 프레임워크이다.</strong>
기본 구성 템플릿을 정의하고, 상속을 통해서 구조를 재사용 할 수 있는 기능 및 설정 파일을 통합 관리할 수 있는 툴이다. 확장성이 있고 일관된 페이지 구성을 보장할 수 있음.</p>
</blockquote>
<p>😺 RMI
이에 관련된 개념으로는 소켓이 있었다. 소켓은 서버와 통신할 때, 해당 서버의 특정 App에 접근하기 위해서는 특정 port와 연결되어 있어야 한다. 이 때, 바로 app에 접근하는 것이 아니라 소켓을 거친 뒤에 app에 접근하고 이용할 수 있게 되는 것이다.
(소켓 프로그래밍은 이 소켓 부분을 설계에서 어떤 방식으로 통신할 지 정해주는 것)
(ServerSocket 하나가 여러 컴퓨터의 client 접속을 인식하는 것이 아님.
client 1개당 1개의 ServerSocket이 생성되는 것임. ServerSocket이 너무 많아지는 것은 비효율 적이므로 이 문제를 해결하기 위해 나온 것이 바로 쓰레드임.)</p>
<p>소켓 프로그래밍에서는 분산된 객체간의 메시지 교환을 위해서는 프로그래머가 프로토콜을 직접 설계해야 했는데, 이게 너무 복잡하고 에러를 잘 발생시켰다. 이걸 해결하는 방법으로 RMI가 제안 되었음.
네트워크로 연결된 여러 대의 컴퓨터에 하나의 프로그램이 분산되어 실행되면서 마치 하나의 프로그램 처럼 움직이는 시스템 즉, 분산 시스템을 자바에서 지원해주는 프로그램이다.</p>
<blockquote>
<p><strong>네트워크로 연결된 다른 컴퓨터에 존재하는 메서드를 마치 내 컴퓨터에 있는 듯이 호출해서 사용하도록 만들어주는 것이 java.rmi 패키지이다.</strong></p>
</blockquote>
<p>😺 Logback</p>
<blockquote>
<p>log4j와는 다르게 서버 중지 없이, 이전 시점부터 복구를 할 수 있다.</p>
</blockquote>
<p>😺 log4j</p>
<blockquote>
<p>log4j를 재설정하기 위해서는 서버를 셧다운 한 후 재기동을 해야한다.</p>
</blockquote>
<p>😺 elastic search</p>
<blockquote>
<p>실시간으로 JSON 문서를 검색 가능한 데이터로 만든다. 속도, 확장성, 복원력 뿐만이 아니라 데이터 롤업이나 인덱스 생명주기 관리 등 데이터를 효율적으로 저장하고 검색할 수 있는 기본 기능이 탑재되어있다.</p>
</blockquote>
<p>replica와 shard를 공부하기 앞서, raid의 개념을 알아야 한다고 함.
<strong>RAID</strong>는 여러 개의 하드디스크를 용도에 맞게 구성하여 사용하는 기술이다.
저장 속도를 높이기 위해 분할 저장을 하거나, 안정성을 위해 복제본을 만들거나 하는 방법이다.</p>
<p>😺 shard</p>
<blockquote>
<p>RAID0 처럼 데이터를 나눠서 기록하는 방식 (속도 향상)
elastic search는 인덱싱할 때 node 내부에 논리적으로 데이터 저장 공간을 만든다. 이 저장 공간들에 여러 개의 데이터를 분산해서 저장할 수 있도록 만든다.</p>
</blockquote>
<p>😺 replica</p>
<blockquote>
<p>RAID1과 유사하다. 데이터가 shard에 저장되면, 이 shard에 대한 복제본을 만든다.
가용성이 증가되면서, 검색 성능도 향상된다.</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[패스워드의 암호화와 저장]]></title>
            <link>https://velog.io/@inhye-world/%ED%8C%A8%EC%8A%A4%EC%9B%8C%EB%93%9C%EC%9D%98-%EC%95%94%ED%98%B8%ED%99%94%EC%99%80-%EC%A0%80%EC%9E%A5</link>
            <guid>https://velog.io/@inhye-world/%ED%8C%A8%EC%8A%A4%EC%9B%8C%EB%93%9C%EC%9D%98-%EC%95%94%ED%98%B8%ED%99%94%EC%99%80-%EC%A0%80%EC%9E%A5</guid>
            <pubDate>Thu, 04 Feb 2021 06:53:15 GMT</pubDate>
            <description><![CDATA[<p>해시 
salt - 여러번 돌리더라도 몇 번 돌렸는지 횟수만 알면 상징성 있는 대표 문자열들을 추려서 대입해보면 공격자는 비번을 찾는 시간을 줄이게 된다. 또한, 같은 비밀번호를 사용하는 사용자들이 있다면 하나의 결과를 갖고도 다수 사용자의 비번을 알아내는 것이나 마찬가지인데 이걸 방지하기 위해 도입하는 것이 salt!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[리액트 공부]]></title>
            <link>https://velog.io/@inhye-world/%EB%A6%AC%EC%95%A1%ED%8A%B8-%EA%B3%B5%EB%B6%80</link>
            <guid>https://velog.io/@inhye-world/%EB%A6%AC%EC%95%A1%ED%8A%B8-%EA%B3%B5%EB%B6%80</guid>
            <pubDate>Sat, 16 Jan 2021 14:40:17 GMT</pubDate>
            <description><![CDATA[<p>props라는 것을 들었다.
react라는 것도 엄청 심오한 것 같다.</p>
<pre><code>import React from &#39;react&#39;;

function Food({ fav }){
  return &lt;h1&gt;I like {fav}&lt;/h1&gt;
}

function App() {
  return (
    &lt;div&gt;
      &lt;h1&gt;Hello!!!!!&lt;/h1&gt;
      &lt;Food fav=&quot;kimchi&quot;/&gt;
      &lt;Food fav=&quot;ramen&quot;/&gt;
      &lt;Food fav=&quot;hoppang&quot;/&gt;
      &lt;Food fav=&quot;hamburger&quot;/&gt;
    &lt;/div&gt;
  );
}

export default App;
</code></pre><p>App()이 부모인데 자손인 Food()에게 구현해달라고 props(여기서는 fav)를 argument로 food에게 보내준다.
동적으로 작동하는 방법 중에 하나라고 한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[백준 그리디 ATM]]></title>
            <link>https://velog.io/@inhye-world/%EB%B0%B1%EC%A4%80-%EA%B7%B8%EB%A6%AC%EB%94%94-ATM</link>
            <guid>https://velog.io/@inhye-world/%EB%B0%B1%EC%A4%80-%EA%B7%B8%EB%A6%AC%EB%94%94-ATM</guid>
            <pubDate>Thu, 14 Jan 2021 13:20:44 GMT</pubDate>
            <description><![CDATA[<p>💲 드디어 처음부터 끝까지 내 힘으로 문제를 풀었다!!!
너무 행복하다 ㅠㅠㅠㅠ</p>
<pre><code>import java.util.Scanner;
import java.util.*;

class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int N = sc.nextInt();
        int[] P = new int[N];
        int[] time = new int[N];
        int index = 1;
        int answer = 0;

        //각 사람의 돈 인출하는데 걸리는 시간
        for(int i = 0; i &lt; N; i++){
            P[i] = sc.nextInt();
        }

        Arrays.sort(P);
        time[0] = P[0];
        while(index &lt; N){
            for(int i = 1; i &lt; N; i++){
                time[index] = time[index-1] + P[index];   
                index++;
            }
        }
        for(int i = 0; i &lt; N; i++){
            answer += time[i];
        }

        System.out.println(answer);
    }
}</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[그리디 구명보트]]></title>
            <link>https://velog.io/@inhye-world/%EA%B7%B8%EB%A6%AC%EB%94%94-%EA%B5%AC%EB%AA%85%EB%B3%B4%ED%8A%B8</link>
            <guid>https://velog.io/@inhye-world/%EA%B7%B8%EB%A6%AC%EB%94%94-%EA%B5%AC%EB%AA%85%EB%B3%B4%ED%8A%B8</guid>
            <pubDate>Wed, 13 Jan 2021 09:33:24 GMT</pubDate>
            <description><![CDATA[<pre><code>import java.util.Arrays;

class Solution {
    public int solution(int[] people, int limit) {
        int answer = 0;

        Arrays.sort(people);

        int idx = 0;
        for(int i = people.length-1; i &gt;= idx ; i--){
            if(people[i] + people[idx] &gt; limit){
                answer++;
            }
            else {
                idx++;
                answer++;
            }
        }

        return answer;
    }
}</code></pre><p>idx(제일 작은 수)를 하나 지정하고 i를 idx까지만 줄인다.
두 수의 합이 limit보다 작거나 같으면 idx++해서 둘 사이의 간격을 줄여준다.
이 문제는 되게 쉬운건데도 못풀었다...
그래도 비슷한 방향으로 풀었음에 위안을 얻기로 했다.</p>
<p>어떻게 연습을 해야하는 것일까?</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[큰 수 만들기]]></title>
            <link>https://velog.io/@inhye-world/%ED%81%B0-%EC%88%98-%EB%A7%8C%EB%93%A4%EA%B8%B0</link>
            <guid>https://velog.io/@inhye-world/%ED%81%B0-%EC%88%98-%EB%A7%8C%EB%93%A4%EA%B8%B0</guid>
            <pubDate>Mon, 11 Jan 2021 09:26:18 GMT</pubDate>
            <description><![CDATA[<p>이번에는 풀이부터 먼저 봤다.(뭔가 진 느낌 ㅠㅠㅠㅠ)</p>
<pre><code>class Solution {
    public String solution(String number, int k) {
        String answer = &quot;&quot;;
        int delcnt = 0;
        int index = 0;

        StringBuilder sb = new StringBuilder(number);

        while(delcnt != k){
            if(index &gt;= 0 &amp;&amp; sb.charAt(index) &lt; sb.charAt(index+1)){
                sb.deleteCharAt(index);
                delcnt++;
                index--;
            }else if(index == sb.length()-2 &amp;&amp; sb.charAt(index) &gt;= sb.charAt(index+1)){
                sb.deleteCharAt(index+1);
                delcnt++;
                index--;
            }else{
                    index++;    
            }
        }

        answer = sb.toString();
        return answer;
    }
}</code></pre><p>다시 한번 해보니 한번에 풀렸지만, 외워서 푼 느낌이다...
외워서 풀더라도 푸는 방법을 알아야 하는 건데...</p>
<p>아무튼 delcnt가 k가 되면 루프를 멈추는 거니까 아무리 긴 숫자여도 큰 상관은 없는것
나는 그동안 k개 지우고 난 숫자의 길이 만을 생각해서 k개씩 어떻게 지울지를 고민했었다.</p>
<p>그런데 그렇게 하면 숫자의 순서와 지우는 것을 어떻게 지정할지가 문제였다.
그런데 다른 분의 풀이를 보니, 두 숫자만을 비교하도록 하는 방법이었다.</p>
<p>❗ 두 숫자만 비교해서 뒷 숫자가 더 크면 지금의 숫자를 지우고, 또 그러니까 index를 앞으로 당긴다.
❗ 마지막까지 k개를 못 지웠을 때 끝에서 두자리를 비교하는데,
뒷자리가 더 큰 경우는 이미 앞의 조건문에서 걸렀으니까 앞의 숫자가 더 큰 경우를 생각해준다.
더 작은 애인 뒷 숫자를 지우고, 인덱스 다시 앞으로 당긴다.
❗ 모든 위의 경우들을 모두 제외했을 때(맨 끝이 아니며, 앞자리가 뒷자리보다 클 때)는 i++를 하여 다음 글자로 가도록 한다.</p>
<p>이번 문제에서 알게된 것은 무조건 for문을 쓰는게 답은 아니라는거
크기 비교는 2개씩 생각하는 것을 기본으로 하는것!</p>
<p>내일 문제는 알고리즘 그림 처럼 yes or no로 생각하면서 코드를 짜봐야지</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[SOAP]]></title>
            <link>https://velog.io/@inhye-world/SOAP</link>
            <guid>https://velog.io/@inhye-world/SOAP</guid>
            <pubDate>Sat, 09 Jan 2021 07:59:17 GMT</pubDate>
            <description><![CDATA[<p>SOAP
HTTP, HTTPS, SMTP 등을 통해 XML 기반의 메시지를 컴퓨터 네트워크 상에서 교환하는 프로토콜</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[프로그래머스 그리디(조이스틱)]]></title>
            <link>https://velog.io/@inhye-world/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EA%B7%B8%EB%A6%AC%EB%94%94%EC%A1%B0%EC%9D%B4%EC%8A%A4%ED%8B%B1</link>
            <guid>https://velog.io/@inhye-world/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EA%B7%B8%EB%A6%AC%EB%94%94%EC%A1%B0%EC%9D%B4%EC%8A%A4%ED%8B%B1</guid>
            <pubDate>Thu, 07 Jan 2021 08:23:07 GMT</pubDate>
            <description><![CDATA[<p>문자열을 문자열 배열로</p>
<pre><code>String name = &#39;avocado&#39;;
String[] nameArr = name.split(&quot;&quot;);</code></pre><h3 id="1차-시도">1차 시도</h3>
<pre><code>class Solution {
    public int solution(String name) {
        char[] nameArr = name.toCharArray();
        int answer = nameArr.length-1;

        for(int i = 0; i &lt; nameArr.length; i++){

            if((int)nameArr[1] == 65){
                answer= answer-1;

                if((int)nameArr[i] &gt;= 78){
                    answer = answer + 91 - (int)nameArr[i];
                }else if((int)nameArr[i] &gt; 65 &amp;&amp; (int)nameArr[i] &lt;= 77){
                    answer = answer + (int)nameArr[i]-65;
                }
            }

            if((int)nameArr[1] != 65){
                if((int)nameArr[i] &gt;= 78){
                    answer = answer + 91 - (int)nameArr[i];
                }else if( (int)nameArr[i] &gt; 65 &amp;&amp; (int)nameArr[i] &lt;= 77){
                    answer = answer + (int)nameArr[i]-65;
                }
            }
        }
        return answer;
    }
}</code></pre><p>결과는 45.5점...ㅎ</p>
<h3 id="2차-시도">2차 시도</h3>
<pre><code>class Solution {
    public int solution(String name) {
        char[] nameArr = name.toCharArray();
        int answer = nameArr.length-1;

        for(int i = 0; i &lt; nameArr.length; i++){
            if((int)nameArr[i] &gt;= 78){
                    answer = answer + 91 - (int)nameArr[i];
            }else if((int)nameArr[i] &gt; 65 &amp;&amp; (int)nameArr[i] &lt;= 77){
                    answer = answer + (int)nameArr[i]-65;
            }else if((int)nameArr[1] == 65){
                answer= answer-1;
            }

        }
        return answer;
    }
}</code></pre><p>결과는 63.6점....
뭔가 코드가 반복된다...</p>
<h3 id="3차-시도">3차 시도</h3>
<pre><code>class Solution {
    public int solution(String name) {
        char[] nameArr = name.toCharArray();
        int answer = nameArr.length - 1;

        //가로의 경우
        for(int i = 0; i &lt; nameArr.length; i++){
            if((int)nameArr[i] == 65 &amp;&amp; i &lt; 2){
                answer--;
            }
        }

        //세로의 경우
        for(int i = 0; i &lt; nameArr.length; i++){
            if((int)nameArr[i] &gt;= 78){
                answer = answer + 91 - (int)nameArr[i];        
            }else if((int)nameArr[i] &gt; 65 &amp;&amp; (int)nameArr[i] &lt;= 77){
                answer = answer + (int)nameArr[i] - 65;
            }
        }
        return answer;
    }
}</code></pre><p>코드가 반복되는게 비효율적으로 보여서 가로의 경우와 세로 경우로 나눴다.
가로의 경우에는 A가 있냐 없냐가 관건이어서 거기에 맞춰서 다시 짜봤다.
결과는 81.8점.... 또 뭐가 문젠건지...</p>
<h3 id="4차-시도">4차 시도</h3>
<pre><code>class Solution {
    public int solution(String name) {
        int answer = 0;
        int demove = name.length() - 1;

        for(int i = 0; i &lt; name.length(); i++){
            char c = name.charAt(i);
            answer += (&#39;Z&#39; - c + 1) &gt; c - &#39;A&#39; ? c - &#39;A&#39; : (&#39;Z&#39; - c + 1);        

            if(c == &#39;A&#39;){
                int nexti = i+1;
                int cntA = 0;
                while(nexti &lt; name.length() &amp;&amp; name.charAt(nexti) == &#39;A&#39;){
                    cntA ++;
                    nexti ++;
                }

                int move = (i-1)*2 + (name.length() - i - 1 - cntA);

                if(demove &gt; move){
                    demove = move;
                }
            }
        }
        answer += demove;
        return answer;
    }
}</code></pre><p>결국엔 다른 사람의 풀이를 참고했다.
나와 달랐던 형식은 세로를 계산할 때 3항 연산자로 비교해 준 뒤에 바로 answer에 반영했다는 것.(너무 놀라웠음)</p>
<p>그리고 문제를 풀면서 가장 막혔던 부분이 A가 연속으로 나왔을 때 인건데,
이 분의 풀이에는 일단 특정 문자를 아예 &#39;A&#39;로 잡고, 그다음의 문자가 &#39;A&#39;인지 아닌지를 판별했다.
이렇게 해주면 A가 몇개나 연속하는지 계산이 가능하다는 점이다.</p>
<p>그리고 혼란을 방지하기 위해 새로운 move 변수를 하나 만들어서 기존의 디폴트값(demove)과는 상관없이 무브수를 계산해야 한다. (이 부분도 생각하지 못함)</p>
<pre><code>int move = (i-1)*2 + (name.length() - i - 1 - cntA);</code></pre><p>이 식은 내가 풀면서도 짜봤던 식이므로 이해를 할 수 있었다.
i번째에서 &#39;A&#39;가 나왔다면, 0에서 i-1번째는 오른쪽 갔다가 왼쪽으로 가니까 *2를 해준다.
그리고 i-1 이후의 구간은 오른쪽으로만 이동을 하니까 전체 길이에서 i+1까지 빼준다. (i는 &#39;A&#39;니까 상관없음)
그리고 cntA에서 연속하는 A의 개수를 이미 계산을 했으므로 cntA도 빼준다.
(i번째의 A를 제외한 A인 경우)</p>
<p>이제 디폴트 값이랑 move 값을 비교해서 둘 중 더 작은 것으로 교체한다.
이렇게 해주는 이유는 오른쪽으로 갔다가 왼쪽으로 가는게 더 적을 때도 있고, 처음부터 왼쪽으로 가는게 더 적은 경우도 있기에 비교를 해주는 것이다.(이건 정말 생각도 못했다....)</p>
<p>최종적으로 교체된 값이 answer가 되는 것이다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[그리디알고리즘 체육복(프로그래머스)]]></title>
            <link>https://velog.io/@inhye-world/%EA%B7%B8%EB%A6%AC%EB%94%94%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EC%B2%B4%EC%9C%A1%EB%B3%B5%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4</link>
            <guid>https://velog.io/@inhye-world/%EA%B7%B8%EB%A6%AC%EB%94%94%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EC%B2%B4%EC%9C%A1%EB%B3%B5%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4</guid>
            <pubDate>Mon, 04 Jan 2021 04:03:36 GMT</pubDate>
            <description><![CDATA[<h3 id="1차-시도">1차 시도</h3>
<pre><code>class Solution {
    public int solution(int n, int[] lost, int[] reserve) {
        int answer = 0;
        int cnt = 0;

        if(lost.length &lt;= reserve.length){
            for(int i = 0; i &lt; lost.length; i++){
                if(reserve[i] != lost[i] - 1 &amp;&amp; reserve[i] != lost[i] + 1 &amp;&amp; reserve[i] != lost[i]){
                    cnt++;
                }
            }
           answer = n-cnt; 
        }else if(reserve.length &lt; lost.length){
            for(int i = 0; i &lt; reserve.length; i++){
                if(reserve[i] != lost[i] - 1 &amp;&amp; reserve[i] != lost[i] + 1 &amp;&amp; reserve[i] != lost[i]){
                    cnt++;
                }
            }
            answer = n-cnt-(lost.length-reserve.length); 
        }

        return answer;
    }
}</code></pre><p>예제는 맞았지만 채점해보니 16점...ㅎ</p>
<h3 id="2차-시도">2차 시도</h3>
<p>3개씩 비교를 하는 것은 아무래도 다른 케이스들을 생각하지 못하게 만들어서 새로운 방식을 사용하기로 함</p>
<pre><code>class Solution {
    public int solution(int n, int[] lost, int[] reserve) {

        //최소 lost에 없는 애들은 수업 들을 수 있음
        int answer = n-lost.length;

        for(int i = 0; i &lt; reserve.length; i++){
            for(int j = 0; j &lt; lost.length; j++){

                if(reserve[i] == lost[j]){
                    answer++;
                }else if(reserve[i] == lost[j]-1){
                    answer++;
                    i++;
                    j++;
                }else if(reserve[i] == lost[j]+1){
                    answer++;
                    i++;
                    j++;
                }
            }
        }

        return answer;
    }
}</code></pre><p>이번에는 50점... </p>
<pre><code>class Solution {
    public int solution(int n, int[] lost, int[] reserve) {

        //최소 lost에 없는 애들은 수업 들을 수 있음
        int answer = n-lost.length;

        for(int i = 0; i &lt; reserve.length; i++){
            for(int j = 0; j &lt; lost.length; j++){

                if(reserve[i] == lost[j]){
                    answer++;
                }else if(reserve[i] == lost[j] + 1 &amp;&amp; lost[j] != n){
                    answer++;
                }else if(reserve[i] &gt; lost[j] + 1 &amp;&amp; lost[j] != n){
                    i--;
                }else if(reserve[i] == lost[j] - 1 &amp;&amp; lost[j] != 1){
                    answer++;
                }else if(reserve[i] &lt; lost[j] - 1 &amp;&amp; lost[j] != 1){
                    j--;
                }
                break;
            }
        }
        return answer;
    }
}</code></pre><h3 id="n차-시도ㅎ">n차 시도...ㅎ</h3>
<pre><code>import java.util.ArrayList;

class Solution {
    public int solution(int n, int[] lost, int[] reserve) {
        int answer = n - lost.length;

        //하나씩 지워주는 것이 정신 건강에 이로우므로 ArrayList를 사용하기로 함
        ArrayList&lt;Integer&gt; res = new ArrayList&lt;&gt;();
        ArrayList&lt;Integer&gt; los = new ArrayList&lt;&gt;();

        //하나씩 담아준다
        for(int r : reserve){
            res.add(r);
        }

        for(int l : lost){
            los.add(l);
        }

        //여분의 체육복을 가져왔으나, 도둑 맞았을 때
        for(int i = 0; i &lt; res.size(); i++){
            for(int j = 0; j &lt; los.size(); j++){
                if(res.get(i) == los.get(j)){
                    res.remove(i); //더이상 빌려줄 수 없으므로 reserve에서 하나씩 지워준다.
                    los.remove(j); //수업에 참여할 수 있게 되었으므로 지워준다
                    j--;//lost, reserve에서 모두 지워지니까 처음부터 들을 수 있는 사람처럼 되버림, 그 자리부터 다시 시작
                    answer++;

                    break;//멈춰서 다시 시작하니까
                }
            }
        }//여기서 reserve부터 지워줘야, 여분이 도둑맞지 않은 상황에서의 여분량을 재조정 가능

        for(int i = 0; i &lt; res.size(); i++){
            for(int j = 0; j &lt; los.size(); j++){
                if(res.get(i) == los.get(j) + 1 || res.get(i) == los.get(j) - 1){
                    res.remove(i); //더이상 빌려줄 수 없으니까
                    //los.remove(j); 수업에 참여할 수 있게 됐지만 answer에서 하나씩 제하니까 바뀌면 안됨
                    answer++;

                    break; //다시 반복하도록
                }
            }
        }
        return answer;
    }
}</code></pre><p>58점... 이쯤 되니 진짜 모르겠다.</p>
<h3 id="n1차-시도">n+1차 시도</h3>
<pre><code>import java.util.ArrayList;

class Solution {
    public int solution(int n, int[] lost, int[] reserve) {
        int answer = n - lost.length;

        //하나씩 지워주는 것이 정신 건강에 이로우므로 ArrayList를 사용하기로 함
        ArrayList&lt;Integer&gt; res = new ArrayList&lt;&gt;();
        ArrayList&lt;Integer&gt; los = new ArrayList&lt;&gt;();

        //하나씩 담아준다
        for(int r : reserve){
            res.add(r);
        }

        for(int l : lost){
            los.add(l);
        }

        //여분의 체육복을 가져왔으나, 도둑 맞았을 때
        for(int i = 0; i &lt; los.size(); i++){
            for(int j = 0; j &lt; res.size(); j++){
                if(res.get(j) == los.get(i)){
                    res.remove(j); 
                    los.remove(i); 
                    i--;
                    answer++;

                    break;
                }
            }
        }

        for(int i = 0; i &lt; los.size(); i++){
            for(int j = 0; j &lt; res.size(); j++){
                if(res.get(j) == los.get(i) + 1 || res.get(j) == los.get(i) - 1){
                    res.remove(j);
                    answer++;

                    break;
                }
            }
        }
        return answer;
    }
}</code></pre><p>for문에서 los와 res의 순서를 바꾸니 또 맞는다...
왜 이러는 걸까...</p>
<p>일단 los(0) 일때 res(1)<del>res(reserve)
los(1) 일때 res(1)</del>res(reserve)
...</p>
<p>이므로 여분의 옷이 도둑 맞을 경우에는 res, los 다 사라져야 하니까 i--해서 새 루프(?)를 다시 돌려줬던 것임</p>
<p>옷을 빌려주는 경우에는 lost가 1번 학생이거나 n번 학생일때, 바로 옆 번호 (2번이나 n-1번) 만이 빌려줄 수 있으므로 los를 기준으로 이중 for문을 돌려야했다.
res를 기준으로 돌리게 되면 los의 경우도 사라지게되어 answer 값에 변동이 생겨버린다.</p>
<p>하... 다른 분 글 참고해서 한건데로 어려우니.... level2는 또 얼마나 걸릴지...ㅠㅠㅠㅠ</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[최소값 구하기]]></title>
            <link>https://velog.io/@inhye-world/%EC%B5%9C%EC%86%8C%EA%B0%92-%EA%B5%AC%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@inhye-world/%EC%B5%9C%EC%86%8C%EA%B0%92-%EA%B5%AC%ED%95%98%EA%B8%B0</guid>
            <pubDate>Sun, 03 Jan 2021 04:39:34 GMT</pubDate>
            <description><![CDATA[<p>학원 다닐 때부터 어딘가 이해 덜하고 찝찝하게 넘어간거 같더니
역시 문제를 풀어보니 막혔다.</p>
<pre><code>import java.util.Scanner;

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

        int n = sc.nextInt();
        int[] call = new int[n];
        int min=0;

        for(int i = 0; i&lt;n; i++){
            int b = sc.nextInt();
            call[i] = b;
            min = call[0];
        }

        for(int j = 0; j&lt;n; j++){
            if(call[j] &lt;= min){
                min = call[j];
            }
        }
        System.out.println(min);
    }
}</code></pre><p>min을 배열에서 아무거나 잡으면 된다.(편의상 첫번째 자리로 만듦...)
for를 돌면서 배열에 모든 자리를 한번씩 훑게 되는데,
이 과정에서 먼저 아무거나 제시한 min과 비교를 하고 min 보다 작으면 현재 수를 min으로 교체한다. 한마디로 한번씩 돌면서 min보다 작은 건 다 교체를 해보게 된다.
for를 다 돌고나면, 그때까지도 남은 애가 가장 작은 수가 된다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[이상한 출석번호 호출 코드업 1093]]></title>
            <link>https://velog.io/@inhye-world/%EC%9D%B4%EC%83%81%ED%95%9C-%EC%B6%9C%EC%84%9D%EB%B2%88%ED%98%B8-%ED%98%B8%EC%B6%9C-%EC%BD%94%EB%93%9C%EC%97%85-1093</link>
            <guid>https://velog.io/@inhye-world/%EC%9D%B4%EC%83%81%ED%95%9C-%EC%B6%9C%EC%84%9D%EB%B2%88%ED%98%B8-%ED%98%B8%EC%B6%9C-%EC%BD%94%EB%93%9C%EC%97%85-1093</guid>
            <pubDate>Sun, 03 Jan 2021 03:44:48 GMT</pubDate>
            <description><![CDATA[<pre><code>import java.util.Scanner;

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

        int n = sc.nextInt();
        int[] call = new int[n];
        int[] myclass = new int[23];

        for(int i=0; i&lt;call.length; i++){
            int b = sc.nextInt();
            call[i] = b;
            for(int j = 0; j&lt;myclass.length; j++) {
                if(call[i] == j+1){
                    myclass[j] = myclass[j]+1;
                }
            }
        }

        for(int k=0; k&lt;23; k++){
            System.out.print(myclass[k] + &quot; &quot;);
        }
    }
}</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[코드업 1019]]></title>
            <link>https://velog.io/@inhye-world/%EC%BD%94%EB%93%9C%EC%97%85-1019-y8720na7</link>
            <guid>https://velog.io/@inhye-world/%EC%BD%94%EB%93%9C%EC%97%85-1019-y8720na7</guid>
            <pubDate>Sun, 03 Jan 2021 02:44:24 GMT</pubDate>
            <description><![CDATA[<pre><code>import java.util.Scanner;

public class Main {

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

        String str = sc.next();
        String date[] = str.split(&quot;[.]&quot;);

        int year = Integer.parseInt(date[0]);
        int month = Integer.parseInt(date[1]);
        int day = Integer.parseInt(date[2]);

        System.out.printf(String.format(&quot;%04d.%02d.%02d&quot;, year, month, day));
    }
}</code></pre><p>여기서 &#39;.&#39;역시 배열의 한 요소니까 [.]으로!!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[수정사항]]></title>
            <link>https://velog.io/@inhye-world/%EC%88%98%EC%A0%95%EC%82%AC%ED%95%AD</link>
            <guid>https://velog.io/@inhye-world/%EC%88%98%EC%A0%95%EC%82%AC%ED%95%AD</guid>
            <pubDate>Sun, 03 Jan 2021 02:44:06 GMT</pubDate>
            <description><![CDATA[<p>🐻전역
footer에 지도 링크
footer 글자크기 작게, 세로 크기 줄이기
메인화면 해상도에 맞춰서 크기 조정 - javascript
로딩 돌리는 속도 더 빨리 조정 or 없애기
head에 링크 걸려있는 부분 body 맨아래 쪽에 위치 or 링크 걸지 말고 로컬로 심어버리기
팝업 창 나왔을 때 뒤로가기 누르면 history 처리 - 확인/취소 버튼, 투자랭킹에서 랭커 눌렀을 때</p>
<p>월급관리 원그래프 퍼센트 나오도록</p>
<p>계산기 밑에서 눌렸을 때 스크롤 위로 올려서 띄우기</p>
<p>적정 주가 계산 페이지 넘기지 말고 팝업창 띄우기</p>
<p>투자랭킹 탭 볼드 처리 - 페이징 했을 때 안먹힘</p>
<p>게시판 댓글, 삭제 ajax 처리 + 파일 업로드 처리</p>
<p>readme 자산, 채권, 게시판 지우기</p>
<p>pom.xml properties에 선언해놓은 내용 el로 바꾸기</p>
<p>에러처리 403 추가</p>
<p>security-context.xml CustomUserDetails -&gt; InvestUserDetails로 네이밍 변경</p>
<p>LoginController
폴리몰피즘 적용
session 사용을 최대한 줄인다. 필요할 경우, session 사용하지 말고 spring security를 확장해서 사용.
JsonNode -&gt; 스프링에서는 최대한 java객체로 리턴 시켜주기, dto를 하나 더 만들어서.</p>
<p>@AllArgsConstructor 사용 시 @Autowired는 주석처리 (Spring 5.0이상 부터는 자동생성)
@PostMapping, GetMapping으로 @RequestMapping 수정
System.out.println 지우기</p>
<p>NaverLoginController
처리는 전부 Service에서.
HOW
Interface -&gt; ISocialLogin -&gt; 안에 login함수 넣기
I를 상속받아서 naver, kakao 구분해서 구현
restful로 naver, kakao 구분</p>
<p>security context에서 autentication 가져오는 것: principal 처리 -&gt; 일반 VO 사용
securityContext 자체가 session이므로 다시 session을 선언 할 필요가 없다. (84~85줄)
42줄: String secret -&gt; final static 선언하기 : 변하지 않는 값은 xml에 집어넣기
40줄 protected -&gt; private으로 바꾸기</p>
<p>서비스 + Interface 구현</p>
<p>페이스북 로그인 추가하기</p>
<p>Authorities 1:N 처리 -&gt; DTO에서 List로 처리</p>
<p>DTO에서 VO로 바꾸기 by Refactoring(Rename)</p>
<p>UserLoginFailHandler
40-41줄 dispatcher는 jsp에서 사용하는 것
포워딩 -&gt; 스프링 문법에 맞춰 바꾸기 -&gt; 컨트롤러 타게 만들기</p>
<p>RankService
Integer -&gt; int로 받기
mapper에서 null값 처리하기 not service</p>
<p>SalaryService
22줄 @Transactional -&gt; exception처리</p>
<p>@Transactional: mapper2개 이상 들어간 Service에 선언  </p>
<p>krx api
url -&gt; .json 없애고 돌려보기</p>
<p>Rank Mapper
85줄 X 네이밍</p>
<p>View
jQuery로 innerHtml 받아오기</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[n번째 수 구하기(코드업 1091)]]></title>
            <link>https://velog.io/@inhye-world/n%EB%B2%88%EC%A7%B8-%EC%88%98-%EA%B5%AC%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@inhye-world/n%EB%B2%88%EC%A7%B8-%EC%88%98-%EA%B5%AC%ED%95%98%EA%B8%B0</guid>
            <pubDate>Sun, 03 Jan 2021 02:43:18 GMT</pubDate>
            <description><![CDATA[<p>재귀함수 비숫한걸 풀었다.(그냥 반복문 이지만)</p>
<pre><code>import java.util.Scanner;

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

        int a = sc.nextInt();
        int m = sc.nextInt();
        int d = sc.nextInt();
        int n = sc.nextInt();
        long answer = a*m+d;

        if(n == 1){
            System.out.println(a);
        }else{
            for(int i = 2; i &lt; n; i++){
                answer = answer*m+d;
            }
            System.out.println(answer);
        }
    }
}</code></pre><p>처음에는 long[] result 배열을 하나 만들었는데 계속 loosy하다고 나와서 이유를 알 수 없었다.(아직까지도 모르겠다... 배열 크기를 n으로 줘서 그런건가...)</p>
<p>하단의 for문 에서는 i &lt; n으로 줬어야 했는데,
answer의 첫번째는 그냥 a인 것이고 2번째 부터가 answer = answer*m+d 이므로 n보다는 작아지는 거다. 이걸 놓쳤더니 계속 틀렸다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[20201229~30]]></title>
            <link>https://velog.io/@inhye-world/20201229</link>
            <guid>https://velog.io/@inhye-world/20201229</guid>
            <pubDate>Wed, 30 Dec 2020 15:03:27 GMT</pubDate>
            <description><![CDATA[<p>바닐라 자바 스크립트를 공부 해볼겸 해서 노마드코더 강의를 들으면서 만들었다.</p>
<p><img src="https://images.velog.io/images/inhye-world/post/408553c9-df5f-4178-8339-177916de57fd/proj1.gif" alt=""></p>
<p>팀 프로젝트를 할 때는 기한 내에 만들어야 하니까 자바스크립트를 제대로 공부를 안했어서 너무 아쉬웠다. 그래도 결과물이 나오니까 너무 재밌당~!
❌ 클릭하면 메모 내역이 사라지고 새로고침 해도 화면에 유지된다!!!</p>
<p>스프링으로 플젝할 때는 db에 저장돼야만 가능한 줄 알았었는데, 자바스크립트 잘 알았으면 더 풍부했을거 같다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[오늘의 수확]]></title>
            <link>https://velog.io/@inhye-world/%EC%98%A4%EB%8A%98%EC%9D%98-%EC%88%98%ED%99%95</link>
            <guid>https://velog.io/@inhye-world/%EC%98%A4%EB%8A%98%EC%9D%98-%EC%88%98%ED%99%95</guid>
            <pubDate>Tue, 29 Dec 2020 15:17:00 GMT</pubDate>
            <description><![CDATA[<p>자산관리 웹페이지 프로젝트를 하면서 한가지 아쉬웠던 것이 화면 로딩 시간이 길었던것...</p>
<p>오늘 노마드 코더의 바닐라 js를 듣다가 우연하게
자바스크립트의 promise라는 객체가 있다는 것을 알았다.</p>
<p>then이 뭔지 몰라서 찾던 중에 뜻밖의 수확...
역시 지속적으로 공부해야 싱크홀들을 메꿀 수 있는 것 같다...ㅠㅠㅠㅠ</p>
<h2 id="promise"><strong>Promise</strong></h2>
<p>주로 서버에서 받아온 데이터를 화면에 표시할 때 사용한다.
API를 통해 데이터를 받았는데, 그 과정에서 덜 받았는데 다짜고짜 화면을 띄우느라 빈화면이 뜨는 것을 방지하기 위한 방법</p>
<pre><code>getData().then(function(fn1)){
    console.log(&quot;확인해 보거라~~&quot;)
}</code></pre><p>이런 형태로 쓰고 getData() 실행이 끝나면 then()이 호출되는 방식인 것임</p>
<h2 id="promise-3-status"><strong>promise 3 status</strong></h2>
<p>pending(대기): 비동기 처리 로직이 아직 완료되지 않은 상태</p>
<pre><code>new Promis(function(resolve, reject){

});</code></pre><p>fulfilled(이행): 비동기 처리 완료되어 프로미스가 결과값 반환한 상태</p>
<pre><code>new Promis(function(resolve, reject){
    resolve();
});

getData().then(function(data){
    //then 사용 가능
});</code></pre><p>rejected(실패): 비동기 처리 실패</p>
<pre><code>new Promis(function(resolve, reject){
    reject();
});

getData().then(function(data){
    console.log(&quot;error 확인해~~&quot;)
});</code></pre><p>promis 에러 처리에는 handleSuccess, handleError, catch가 있는데
catch() 방법을 권장한다고 함...</p>
<p><a href="https://joshua1988.github.io/web-development/javascript/promise-for-beginners/#promise%EA%B0%80-%EB%AD%94%EA%B0%80%EC%9A%94">참조 링크</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[JSON.stringify]]></title>
            <link>https://velog.io/@inhye-world/JSON.stringify</link>
            <guid>https://velog.io/@inhye-world/JSON.stringify</guid>
            <pubDate>Tue, 29 Dec 2020 12:31:48 GMT</pubDate>
            <description><![CDATA[<p>localStorage는 자바스크립트 객체를 string으로 저장하려한다.</p>
<p>따라서 배열을 그냥 저장하려 하면 application에서는 그냥 object로 띄워버리기 때문에 JSON.stringify를 써서 string으로 변환할 수 있도록 하면된다.</p>
]]></description>
        </item>
    </channel>
</rss>