<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>mongu_93</title>
        <link>https://velog.io/</link>
        <description>소확행을 찾는 개발자</description>
        <lastBuildDate>Sun, 20 Aug 2023 13:40:16 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>mongu_93</title>
            <url>https://velog.velcdn.com/images/mongu_93/profile/7756f1ff-c4c2-4a78-b44d-8993228fc53a/image.jpeg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. mongu_93. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/mongu_93" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[23년 8월 셋째 주 포스팅]]></title>
            <link>https://velog.io/@mongu_93/23%EB%85%84-8%EC%9B%94-%EC%85%8B%EC%A7%B8-%EC%A3%BC-%ED%8F%AC%EC%8A%A4%ED%8C%85</link>
            <guid>https://velog.io/@mongu_93/23%EB%85%84-8%EC%9B%94-%EC%85%8B%EC%A7%B8-%EC%A3%BC-%ED%8F%AC%EC%8A%A4%ED%8C%85</guid>
            <pubDate>Sun, 20 Aug 2023 13:40:16 GMT</pubDate>
            <description><![CDATA[<p>이번 주는 여름 휴가로 도쿄를 갔다왔다.
세계 3대 도시답게 굉장히 좋은 것 같다.
공부를 별로 못했다는 핑계 ㅎㅎ..</p>
<p>그래도 SQLD 자격증 시험을 위해 책 일부를 공부하고 기출문제도 몇 개 풀어보았다.</p>
<ul>
<li><strong>참고 서적</strong> : <a href="https://www.yes24.com/Product/Goods/103967164">이경오의 SQL+SQLD 비밀노트</a><br>

</li>
</ul>
<p>계획했던 JS 인프런 강의도 신청해서 2섹션 정도 들었다.</p>
<ul>
<li><strong>강의</strong> : <a href="https://www.inflearn.com/course/functional-es6">함수형 프로그래밍과 JavaScript ES6+</a><br>

</li>
</ul>
<p>구름에서 시작한 구름톤 챌린지도 2문제 풀이 완료..!
구름 챌린지는 늘 재미난 듯</p>
<ul>
<li><strong>코테 사이트</strong> : <a href="https://level.goorm.io/l/challenge/goormthon-challenge">구름톤 챌린지</a><br>

</li>
</ul>
<p>다음 주는 좀 더 집중해서 공부량을 늘려야겠다..ㅎㅎ..ㅎㅎ</p>
<h3 id="목표"><em>목표!!</em></h3>
<p>✍️ SQLD 전 챕터 개념 익히기 및 노랭이 문풀 50번까지
✍️ 구름 챌린지 매일 꾸준히!!
✍️ JS 섹션 5까지는 공부</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Spring Boot로 개발하는 쇼핑몰 - 작업중 🔨 (75% 완료)]]></title>
            <link>https://velog.io/@mongu_93/Spring-Boot%EB%A1%9C-%EA%B0%9C%EB%B0%9C%ED%95%98%EB%8A%94-%EC%87%BC%ED%95%91%EB%AA%B0-%EC%9E%91%EC%97%85%EC%A4%91-75-%EC%99%84%EB%A3%8C</link>
            <guid>https://velog.io/@mongu_93/Spring-Boot%EB%A1%9C-%EA%B0%9C%EB%B0%9C%ED%95%98%EB%8A%94-%EC%87%BC%ED%95%91%EB%AA%B0-%EC%9E%91%EC%97%85%EC%A4%91-75-%EC%99%84%EB%A3%8C</guid>
            <pubDate>Thu, 12 Jan 2023 08:54:22 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p> 🥼 <a href="https://github.com/zpka14/ShopMallProject">Shopping Mall Project</a> 👖 - in GitHub 💻</p>
</blockquote>
<p>코틀린 문법 공부 📒. 친구와 안드로이드 앱을 만들어보려고 회의 및 강의 수강 📊.
틈틈이 프로그래머스 알고리즘 문제 풀이. 회사에서 진행하는 세일즈포스 교육 등
벌려놓은 것도 많고 해야할 일도 많아서 😱😨 바쁜 와중 ,, </p>
<p>개인적으로 실력도 다질겸 만들어보고 싶었던 쇼핑몰 홈페이지가 마침 관련 서적이 있길래 참조해서 쇼핑몰 프로젝트를 약 한 달 넘게 제작 중에 있다.</p>
<p>코드나 동작 정리는 마무리가 된 후에 할 듯 하고 이번에는 중간점검 차원으로 현재까지 작동되는 기능과 홈페이지 사진만 살짝 포스팅하려한다.</p>
<p>사용 기술은 <strong>Spring Boot, Thymeleaf, JPA, QueryDsl</strong> 등이 있다.
기존에 SpringBoot 기술을 다질 수 있는 것 뿐만 아니라 예전에 배웠던 JPA의 복습도 하고
새롭게 Junit5을 사용해서 기능을 단위 테스트하는 법도 배우고 QueryDsl을 통해 쿼리 생성을 하는 법도 배울 수 있어 좋은 듯 하다. Git 사용 실력은 덤으로 늘고 🤗🤗
IDE는 이클립스, VS Code만 쓰다가 이번에 Intellij 써봤는데 좋은 것 같기도 하고 별로인 것 같기도 하고...?</p>
<p>클론 코딩으로 공부하는 방식은 예전에 해봤었는데 그때는 동작이 어떻게 되는지 아무 생각 없이 따라하다보니 실력이 전혀 늘지 않았었지만 유명한 유튜버인 노마드 코더도 추천한 방법대로 하니 확실히 효과가 있는 것 같기도 하다.
<em><strong>(하나하나 코드 동작을 이해하면서 직접 타이핑하고 관련 기술을 찾아보며 공부 및 추가로 작은 기능 몇 개씩 변경해보기)</strong></em></p>
<p>내가 제작한 홈페이지가 이쁘게 보여지고 관련 기능이 잘 동작할 때 느껴지는 재미란...ㅎㅎ 😝
최종적으로는 지마켓, 11번가 등의 오픈마켓을 참조하여.. 
1인 개발자가 잠깐잠깐 짬내서 개발할 수 있는 범위 내에 최대한 괜찮은 퀄리티를 내보고 싶다.</p>
<br>

<p><em><strong>1월 12일자. 현재까지 Master Branch 반영 내용</strong></em></p>
<h2 id="개발환경">개발환경</h2>
<ul>
<li>BackEnd : SpringBoot - 2.7.6</li>
<li>FrontEnd : HTML, Thymeleaf</li>
<li>DB : MySQL - 8.0.31</li>
<li>IDE : Intellij<br>
## 구현기능</li>
<li>회원가입 및 로그인/로그아웃</li>
<li>권한에 따른 메뉴 접근(Admin Role은 상품 등록, 상품 관리 접근 가능)</li>
<li>상품 등록/관리에서 재고와 품절, 이미지 및 정보 설정. </li>
<li>상품 상세 정보 페이지.</li>
<li>주문하기<br>
## 남은과제</li>
<li>장바구니</li>
<li>주문 이력페이지<br>

</li>
</ul>
<h2 id="추가로-구현하고-싶은-기능">추가로 구현하고 싶은 기능</h2>
<ul>
<li>상품 카테고리 추가 - <strong>(최우선)</strong> ✨🎇 </li>
<li>버튼 별로 노출되는 상품 개수 지정(3개 보기, 5개 보기, 10개 보기)</li>
<li>두 가지 UI제공. List 형식으로 상품 조회 가능</li>
<li>상품 문의 기능</li>
<li>페이지 꾸미기</li>
<li>광고 노출<br>

</li>
</ul>
<h2 id="구현사진">구현사진</h2>
<p><img src="https://velog.velcdn.com/images/mongu_93/post/805037b8-c794-4259-9212-1c022beab900/image.png" alt="">
<img src="https://velog.velcdn.com/images/mongu_93/post/20bccf62-9bae-4e09-9dd4-453b48c424a2/image.png" alt="">
<img src="https://velog.velcdn.com/images/mongu_93/post/2de375ff-4764-4cd9-a26f-804247c158e7/image.png" alt=""></p>
<blockquote>
<p><strong>참조 서적
📚 백견불여일타 스프링 부트 쇼핑몰 프로젝트 with jpa</strong></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[구름 LEVEL - 알고리즘 먼데이 챌린지 - 후기]]></title>
            <link>https://velog.io/@mongu_93/%EA%B5%AC%EB%A6%84-LEVEL-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EB%A8%BC%EB%8D%B0%EC%9D%B4-%EC%B1%8C%EB%A6%B0%EC%A7%80-%ED%9B%84%EA%B8%B0</link>
            <guid>https://velog.io/@mongu_93/%EA%B5%AC%EB%A6%84-LEVEL-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EB%A8%BC%EB%8D%B0%EC%9D%B4-%EC%B1%8C%EB%A6%B0%EC%A7%80-%ED%9B%84%EA%B8%B0</guid>
            <pubDate>Thu, 01 Dec 2022 04:30:55 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/mongu_93/post/8f5a9201-6734-4e95-b13a-7388ccb8d2aa/image.png" alt=""></p>
<h2 id="후기">후기</h2>
<p>주차별로 포스트를 올리려고 했으나 몇 문제 못 푼 주차도 있고 회사 업무랑 주말 약속이랑 겹치다 보니 제대로 포스팅을 못하였다.
그래도 짬을 내서 8주차까지 전부 문제를 풀었고 대여섯 문제 빼고는 자바로 다 복습도 해본 것 같다.</p>
<p>좋았던 점은 문제 별로 난이도가 적절한 것 같고 상품이 있으니 매 주차에 꼬박꼬박 참여할 수 있어서 알고리즘 실력 향상에 도움이 된 것 같고
아쉬웠던 점은 역시 가장 많이 쓰는 언어인 자바의 문제 풀이가 제공되지 않아 풀이 코드를 이해할 때 이해하기가 힘든 부분이 있었고 또 더 다양한 알고리즘이 있을 것 같은데 대부분 비슷한 알고리즘만 계속 반복되는 느낌이었다. 가장 출제빈도가 높은 부분을 연습시키려는 것 일수도...?</p>
<p>그래도 전반적인 실력 향상에 도움이 되고 상품까지 받으니 일석이조...!!
다음에 또 기회가 있으면 참여할 의향이 있다.
좀 더 어려운 문제도 있으면 좋을 것 같다. (백준 골드 상위, 플래티넘 하위티어, 프로그래머스 3~4레벨 정도..? 구름 난이도에 🔥이 5개까지 있는데 챌린지엔 4개까지있는 문제밖에 없는 듯..?)</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Kotlin 입문_Chap02 [코드 제어 및 함수]]]></title>
            <link>https://velog.io/@mongu_93/Kotlin-%EC%9E%85%EB%AC%B8Chap02-%EC%BD%94%EB%93%9C-%EC%A0%9C%EC%96%B4-%EB%B0%8F-%ED%95%A8%EC%88%98</link>
            <guid>https://velog.io/@mongu_93/Kotlin-%EC%9E%85%EB%AC%B8Chap02-%EC%BD%94%EB%93%9C-%EC%A0%9C%EC%96%B4-%EB%B0%8F-%ED%95%A8%EC%88%98</guid>
            <pubDate>Wed, 30 Nov 2022 04:30:41 GMT</pubDate>
            <description><![CDATA[<p><img src="https://velog.velcdn.com/images/mongu_93/post/b55ee399-8a16-4011-976a-0e5bdd017b02/image.png" alt=""></p>
<h2 id="1-제어문">1. 제어문</h2>
<h3 id="👉-1-if문">👉 1) if문</h3>
<ul>
<li>if(if-else)문은 자바와 문법이 동일. 하지만 코틀린에서는 문장이 Expression으로 취급이 되어서 return if가 가능.(자바는 단순 Statement) 그렇기에 삼항연산자도 없음.<blockquote>
<p>1) Statement : 프로그램의 문장. Expression을 포함하나 하나의 값으로 도출이 되지 않는 문장을 주로 의미
2) Expression : Statement에서 하나의 값으로 도출이 되는 문장. Kotlin에서 if-else문은 Expression이므로 바로 return이 가능하다.</p>
</blockquote>
</li>
</ul>
<br>
<b> 예시 </b>


<pre><code class="language-kotlin">fun ab (n : Int) : String {
    return if (n &gt;= 10) {
        &quot;a&quot;
    }else{
        &quot;b&quot;
    }
}</code></pre>
<ul>
<li>in과 ..을 이용하면 좀 더 편하게 기준 범위의 값인지 알 수 있다.
예 : if(a in 1..50)<br>

</li>
</ul>
<h3 id="👉-2-when문">👉 2) when문</h3>
<ul>
<li>코틀린에서는 자바의 switch문이 when으로 대체되었다. 더 강력한 기능을 갖는다고 한다.
따로 break가 필요없고 if문 처럼 값을 바로 반환 받을 수 있다.</li>
</ul>
<br>
<b>예시</b>

<pre><code class="language-kotlin">when (val) {
    &quot;a&quot; -&gt; println(&quot;a&quot;)
    &quot;b&quot; -&gt; println(&quot;b&quot;)
    else -&gt; println(&quot;null&quot;)
}</code></pre>
<br>
<br>

<h2 id="2-반복문">2. 반복문</h2>
<h3 id="👉-1-for-each문">👉 1) for each문</h3>
<ul>
<li>콜론(:)대신 in 을 사용</li>
</ul>
<h3 id="👉-2-for문">👉 2) for문</h3>
<ul>
<li>전통적인 for문은 자바와 다르게 in과 .., downTo, step 등을 사용해서 표기</li>
<li>downTo, step도 함수(중위 호출 함수). 띄어쓰기로 사용 가능</li>
<li>그 외의 for문 문법은 모두 자바와 동일</li>
</ul>
<br>
<b> 예시 </b>

<pre><code class="language-java">/* Java */
//올라가는 경우
for(int i=0; i&lt;=3; i++){
    System.out.println(i);
}
//2칸 이상 씩 올라가는 경우
for(int i=0; i&lt;=10; i+=2){
    System.out.println(i);
}
//내려가는 경우
for(int i=3; i&gt;=1; i--){
    System.out.println(i);
}</code></pre>
<pre><code class="language-kotlin">/* Kotlin */
//올라가는 경우
for(i in 0..3){
    println(i)
}
//2칸 이상 씩 올라가는 경우
for(i in 1 step 3){
    println(i)
}
//내려가는 경우
for(i in 0..10 step 2){
    println(i)
}</code></pre>
<h3 id="👉-3-while문">👉 3) while문</h3>
<ul>
<li>do while문을 포함해서 자바와 동일<br>
<br>

</li>
</ul>
<h2 id="3-예외처리">3. 예외처리</h2>
<h3 id="👉-1-try-catch문">👉 1) try-catch문</h3>
<ul>
<li>try catch finally 구문은 자바와 동일</li>
<li>차이점은 Expression으로 취급이 되어 return 가능</li>
</ul>
<h3 id="👉-2-exception">👉 2) Exception</h3>
<ul>
<li>자바와 달리 Checked Exception이 없고 모두 Unchecked Exception이어서 throws로 처리를 해주지 않아도 된다.</li>
</ul>
<h3 id="👉-3-try-with-resources">👉 3) try with resources</h3>
<ul>
<li>try에 자원 객체를 전달해주면 try구문이 끝났을 때 자동으로 닫아주는 JDK 7부터 지원되는 자바의 성질</li>
<li>코틀린에서는 이러한 try with resources 구문이 없고(코틀린 언어적 특징을 활용해 close를 호출) use라는 인라인 확장함수를 사용해야한다.<br>
<br>
## 4. 함수
### 👉 1) 함수 선언</li>
<li>접근지시어 public은 생략 가능</li>
<li>fun키워드, 함수이름, 매개변수, 반환타입(Unit 생략 가능)으로 구성</li>
<li>하나의 반환하는 값을 가진 함수면 중괄호 대신 =을 써도 된다.</li>
</ul>
<br>
<b> 예시 </b>

<pre><code class="language-kotlin">fun ab(a: Int, b: Int) =
    if(a&gt;b) {
    a
  }
    else {
    b
  }

//한줄 처리
fun ab(a: Int, b: Int) = if(a&gt;b) a else b</code></pre>
<h3 id="🌟-2-default-parameter-🌟">🌟 2) Default Parameter 🌟</h3>
<ul>
<li>함수 파라미터에 기본값을 설정해줄 수 있음</li>
<li>밖에서 파라미터를 넣어주지 않으면 기본값을 사용</li>
</ul>
<h3 id="🌟-3-named-argument-🌟">🌟 3) Named Argument 🌟</h3>
<ul>
<li>사용할 때 이름을 통해 값을 직접 지정해서 넣는게 가능하다.</li>
<li>지정하지 않은 매개변수는 기본값을 사용하게 됨</li>
</ul>
<h3 id="👉-4-가변-인자">👉 4) 가변 인자</h3>
<ul>
<li>가변인자에는 vararg 키워드 사용</li>
<li>가변인자 함수를 배열로 호출할 때는 *를 붙여주어야 함.</li>
</ul>
<br>
<b> 예시 </b>

<pre><code class="language-kotlin">/* Default Parameter, Named Argument */
//선언
fun abc(
  a: Boolean, 
  b: Int = 3,
  c: String = &quot;c&quot;
){
  if(a){
      println(b)
  } else{
      println(c)
  }
}
//사용 (b: default c: named argument)
abc(true, c=&quot;hello&quot;) // 3 출력
abc(false, c=&quot;bye&quot;) // bye 출력


/* 가변 인자 */
fun allPrint(vararg strs : String) {
    for(s in strs){
        println(s)
    }
}

val arr = arrayOf(&quot;a&quot;,&quot;b&quot;,&quot;c&quot;)
allPrint(*arr)</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[Kotlin 입문_Chap01 [변수, 타입, 연산자]]]></title>
            <link>https://velog.io/@mongu_93/Kotlin-%EC%9E%85%EB%AC%B8Chap01-%EB%B3%80%EC%88%98-%ED%83%80%EC%9E%85-%EC%97%B0%EC%82%B0%EC%9E%90</link>
            <guid>https://velog.io/@mongu_93/Kotlin-%EC%9E%85%EB%AC%B8Chap01-%EB%B3%80%EC%88%98-%ED%83%80%EC%9E%85-%EC%97%B0%EC%82%B0%EC%9E%90</guid>
            <pubDate>Wed, 16 Nov 2022 05:49:35 GMT</pubDate>
            <description><![CDATA[<h2 id="코틀린">코틀린</h2>
<p>IntelliJ IDEA의 개발사 JetBrains에서 2011년에 공개한 오픈 소스 프로그래밍 언어. JVM 기반의 언어.</p>
<blockquote>
<ul>
<li>Java와 유사하지만 더 간결한 문법과 다양한 기능을 추가</li>
</ul>
</blockquote>
<ul>
<li>Java와의 상호 운용이 100% 지원</li>
<li>구글이 안드로이드의 공식 언어로 Kotlin을 추가</li>
<li>자바를 사용했을 때 보다 코드량이 비약적으로 감소하고 생산성이 대폭 향상</li>
</ul>
<p>이러한 특징 때문에 많은 곳에서 자바가 코틀린으로 대체되고 있고 최신 언어인 코틀린을 다룰 줄 아는 것은 굉장한 장점이 될 것 같아 코틀린 문법 공부를 시작하고 있는 중이다.
<br></p>
<h3 id="1-변수">1. 변수</h3>
<pre><code class="language-kotlin">-- 변수 작성법 --
var number : Long? = 10L</code></pre>
<ul>
<li>모든 변수에 var/val을 붙임
var : 변경가능
val : 변경불가</li>
<li>타입 명시적 작성 X -&gt; 타입 추론 자동</li>
<li>기본(원시)타입과 참조타입 구분을 안해줘도 됨</li>
<li>Null이 들어갈 수 있는 변수는 타입 뒤에 ? 작성 (다른 타입으로 간주됨)</li>
<li>객체 인스턴스화 new 작성 X<br>

</li>
</ul>
<h3 id="2-null-처리">2. NULL 처리</h3>
<ul>
<li>코틀린은 Null이 들어갈 수 있는 타입은 다르게 간주 (한 번 Null 검사 시 non-null임을 컴파일러가 알 수 있음)</li>
<li>Null이 아닌 경우에만 호출되는 Safe Call(?.)이 있음.</li>
<li>Null인 경우에만 호출되는 Elvis 연산자(?:)가 있음.</li>
<li>Null이 절대 아닐 때 사용할 수 있는 not null 단언(!!)이 있음.<pre><code class="language-kotlin">//str이 Null이 아니면 startsWith 작동. Null이면 Null 반환
return str?.startsWith(&quot;A&quot;)
//str이 Null이 아니면 startsWith 작동. Null이면 false 반환
return str?.startsWith(&quot;A&quot;) ? : false
//str이 Null이 아니면 startsWith 작동. Null이면 NPE 에러
return str!!.startsWith(&quot;A&quot;)</code></pre>
</li>
<li>Kotlin에서 Null이 들어갈 수 있는 자바 코드를 사용할 때는 플랫폼 타입에 유의해야 함.</li>
</ul>
<h3 id="3-타입">3. 타입</h3>
<ul>
<li>기본 타입들 간의 변환은 명시적으로 이루어짐</li>
<li>is, as를 사용해 타입을 체크하고 형변환을 한다.</li>
<li>Any 키워드는 코틀린에서 모든 자료형의 슈퍼 클래스이다. (Java의 Object)</li>
<li>Unit 키워드는 함수의 반환이 없다는 것의 표시 (Java의 Void)</li>
<li>Nothing 타입은 항상 예외를 발생시킴 (의미 있는 데이터가 없다는 것을 명시적으로 표현 - 잘 쓰이지는 않음)</li>
<li>문자열을 가공할 때 ${변수}를 사용해서 데이터를 받아온다.</li>
<li>문자열에서 특정 문자를 가져올 때 배열 인덱스처럼 [ ] 를 사용한다.<pre><code class="language-kotlin">val a : Any = &quot;abc&quot; //any 사용
</code></pre>
</li>
</ul>
<p>//a 타입 확인
if(a is String) {
    val b : String? = a
    println(&quot;${a[0]}&quot;) //a의 첫번째 글자
    println(&quot;b는 $b&quot;) //b 출력
}else{
    val b : Int? = a as? Int //a Int 형 변환
    println(&quot;b는 $b&quot;)
}</p>
<pre><code>
### 4. 연산자
- 단항, 산술, 대입 연산자 Java와 동일
- 비교 연산자 Java와 동일하나 객체끼리도 자동으로 compareTo를 사용해주어 비교 가능하다.
- Java의 ==, equals가 코틀린에서는 ===, == 이다.
- in/!in (포함 연산자) ..([a..b] -&gt;a부터 b까지의 범위 객체 생성) 같은 연산자가 있다.
- 객체마다 연산자를 직접 정의 가능하다.</code></pre>]]></description>
        </item>
        <item>
            <title><![CDATA[구름 LEVEL - 알고리즘 먼데이 챌린지 3주차(JAVA)]]></title>
            <link>https://velog.io/@mongu_93/%EA%B5%AC%EB%A6%84-LEVEL-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EB%A8%BC%EB%8D%B0%EC%9D%B4-%EC%B1%8C%EB%A6%B0%EC%A7%80-3%EC%A3%BC%EC%B0%A8JAVA</link>
            <guid>https://velog.io/@mongu_93/%EA%B5%AC%EB%A6%84-LEVEL-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EB%A8%BC%EB%8D%B0%EC%9D%B4-%EC%B1%8C%EB%A6%B0%EC%A7%80-3%EC%A3%BC%EC%B0%A8JAVA</guid>
            <pubDate>Wed, 26 Oct 2022 14:52:04 GMT</pubDate>
            <description><![CDATA[<h2 id="3주차-문제-후기">3주차 문제 후기</h2>
<p>밥을 안먹고 풀다가 배고파서 중간에 1시간 걸린다는 배달 시켰는데 배달이 20분만에 와서.. 하다가 제대로 못했다
3번 풀다가 시간초과가 뜨길래 코드를 고치려고 했는데 배달이 와서 그냥 제출하고 넘겼다.
4번은 밥 먹으면서 조금 문제를 읽고 끄적여봤는데 어떻게 풀어야할지 감이 안왔다.
2주차에서 3주차로 넘어오면서 확 어려워진게 느껴졌다. 당황..
그래도 어려우니 복습하면서 배울 점이 많을 것 같다 느껴졌다.</p>
<ul>
<li>링크 주소 : <a href="https://level.goorm.io/level/challenge">구름 - 알고리즘 먼데이 챌린지</a>
<img src="https://velog.velcdn.com/images/mongu_93/post/f44644ae-5754-4a66-ad1f-93d84c047a0b/image.png" alt=""></li>
</ul>
<p><br><br></p>
<h2 id="3주차-문제-해설-자바">3주차 문제 해설 (자바)</h2>
<p><strong>1번</strong> : 현재 주어진 값이 음수면 그 값의 양수가 양수면 그 값의 음수가 있는지 없는지 판단하면 되는 문제.
간단하게 Set에다가 입력 값을 넣고 하나씩 꺼내보면 될 것 같았다.</p>
<pre><code class="language-java">import java.io.*;
import java.util.*;

public class Main {
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int N = Integer.parseInt(br.readLine());
        StringTokenizer st = new StringTokenizer(br.readLine());
        HashSet&lt;Integer&gt; set = new HashSet&lt;&gt;();

        for(int i=0; i&lt;N; i++){
            int num = Integer.parseInt(st.nextToken());
            set.add(num);
        }

        int sum = 0;
        for(int i : set){
            if(!set.contains(-i)) sum += i;
        }

        System.out.println(sum);
    }
}</code></pre>
<br>

<p><strong>2번</strong> : 핸드폰 숫자 자판을 몇 번 입력하는가에 따라 값이 바뀌고 그 값들을 이어붙여서 출력하면 되는 문제.
푸는건 안 어려운데 너무 노가다였다. 모든 케이스를 다 적어줘야하니. 
이거 아니면 밥 오기 전에 3번 고치고 4번 문제도 제대로 읽어는 봤을 수도.. </p>
<p>버튼 1, 7, 9만 5로 나머지는 4로 몇 번 입력했는지에 따라 나머지를 구해서 문자를 붙여주면 되고
알파벳 같은 경우는 일일이 if조건 없이 아스키코드를 통해 간편하게 구할 수 있다.</p>
<pre><code class="language-java">import java.io.*;
import java.util.*;

public class Main {
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int N = Integer.parseInt(br.readLine());
        String s = br.readLine();
        StringBuilder answer = new StringBuilder();

        int cnt = 0;
        for(int i=0; i&lt;N; i++){
            if(i+1 &lt; N) {
                if (s.charAt(i) == s.charAt(i + 1)) {
                    cnt++;
                    continue;
                }
            }
            switch(s.charAt(i)){
                case &#39;1&#39; :
                    if(cnt % 5 == 0){
                        answer.append(&quot;1&quot;);
                    }else if(cnt % 5 == 1){
                        answer.append(&quot;.&quot;);
                    }else if(cnt % 5 == 2){
                        answer.append(&quot;,&quot;);
                    }else if(cnt % 5 == 3){
                        answer.append(&quot;?&quot;);
                    }else if(cnt % 5 == 4){
                        answer.append(&quot;!&quot;);
                    }
                    break;
                case &#39;2&#39; :
                    if(cnt % 4 == 0){
                        answer.append(&quot;2&quot;);
                    }else{
                        answer.append((char)(&#39;A&#39;+ cnt % 4 -1));
                    }
                    break;
                case &#39;3&#39; :
                    if(cnt % 4 == 0){
                        answer.append(&quot;3&quot;);
                    }else{
                        answer.append((char)(&#39;D&#39;+ (cnt % 4) -1));
                    }
                    break;
                case &#39;4&#39; :
                    if(cnt % 4 == 0){
                        answer.append(&quot;4&quot;);
                    }else{
                        answer.append((char)(&#39;G&#39;+ (cnt % 4) -1));
                    }
                    break;
                case &#39;5&#39; :
                    if(cnt % 4 == 0){
                        answer.append(&quot;5&quot;);
                    }else{
                        answer.append((char)(&#39;J&#39;+ cnt % 4 -1));
                    }
                    break;
                case &#39;6&#39; :
                    if(cnt % 4 == 0){
                        answer.append(&quot;6&quot;);
                    }else{
                        answer.append((char)(&#39;M&#39;+ cnt % 4 -1));
                    }
                    break;
                case &#39;7&#39; :
                    if(cnt % 5 == 0){
                        answer.append(&quot;7&quot;);
                    }else{
                        answer.append((char)(&#39;P&#39;+ cnt % 5 -1));
                    }
                    break;
                case &#39;8&#39; :
                    if(cnt % 4 == 0){
                        answer.append(&quot;8&quot;);
                    }else{
                        answer.append((char)(&#39;T&#39;+ cnt % 4 -1));
                    }
                    break;
                case &#39;9&#39; :
                    if(cnt % 5 == 0){
                        answer.append(&quot;9&quot;);
                    }else{
                        answer.append((char)(&#39;W&#39;+ cnt % 5 -1));
                    }break;
            }
            cnt = 0;
        }

        System.out.println(answer);
    }
}</code></pre>
<br>

<p><strong>3번</strong> : 난이도가 조금 올라간다. 이번 주차까지는 난이도 2로만 출제될 줄 알았는데 난이도 3이 두 개 있었다.
가중치가 없는 그래프의 정점을 구하는 BFS의 기본 문제.
늘 하던 식으로 인접 행렬로 처음에 풀었는데 시간초과가 났다. 
정점들이 간선이 없는 경우들도 있을 텐데 고려하지 않았다.
이런 경우에는 실제로 간선을 가지고 있는 정점만을 가지고 있는 인접 리스트를 사용해야 한다.
인접 행렬, 인접 리스트는 각각 장단점이 있는데 아래 블로그에 잘 설명되어 있는 것 같다.</p>
<p><a href="https://born2bedeveloper.tistory.com/42">[JAVA] 그래프 구현하기 (인접 행렬, 인접 리스트)</a>
<br>
먼저 인접 리스트를 만들어서 입력 값을 양방향으로 연결해주고 BFS 방식(Queue 사용)을 통해 따라가면 된다.
이때 최소 거리로 가야하므로 방문한 노드이면 지나친다.</p>
<pre><code class="language-java">import java.io.*;
import java.util.*;

public class Main {

    static ArrayList&lt;ArrayList&lt;Integer&gt;&gt; graph;
    static int N;
    static boolean[] visited;
    static int answer = Integer.MAX_VALUE;
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        N = Integer.parseInt(st.nextToken());
        int M = Integer.parseInt(st.nextToken());
        int K = Integer.parseInt(st.nextToken());
        visited = new boolean[N+1];
        graph = new ArrayList&lt;&gt;();

        for (int i = 0; i &lt;= N; i++) {
            graph.add(new ArrayList&lt;&gt;());
        }

        for(int i=0; i&lt;M; i++){
            st = new StringTokenizer(br.readLine());
            int start = Integer.parseInt(st.nextToken());
            int end = Integer.parseInt(st.nextToken());
            graph.get(start).add(end);
            graph.get(end).add(start);
        }

        bfs(1);
        if(answer &lt;= K) System.out.println(&quot;YES&quot;);
        else System.out.println(&quot;NO&quot;);
    }

    public static void bfs(int start){
        Queue&lt;GO&gt; q = new LinkedList&lt;&gt;();
        q.add(new GO(start,0));
        visited[1] = true;

        while(!q.isEmpty()){
            int now = q.peek().now;
            int cnt = q.poll().cnt;

            if(now == N) {
                answer = Math.min(answer, cnt);
                return;
            }

            Iterator&lt;Integer&gt; iter = graph.get(now).listIterator();
            while(iter.hasNext()) {
                int i = iter.next();
                if(!visited[i]) {
                    visited[i] = true;
                    q.add(new GO(i,cnt+1));
                }
            }
        }
    }
}

class GO {
    int now, cnt;

    public GO(int now, int cnt){
        this.now = now;
        this.cnt = cnt;
    }
}</code></pre>
<br>

<p><strong>4번</strong> : 계속 런타임 에러가 뜨는데 아마 재귀하면서 자바언어에서 메모리 초과가 나서 그런것 같다.
구름 공식 풀이코드에 있는 C++, Python은 정답이고 그 풀이 그대로 옮겼으나 되지 않는다.
다른 사람들도 안된다고 하는거보면 언어별로 아직은 문제가 있는 듯..??
구름에서 제공하는 풀이가 생각보다 친절해서 따로 설명은 안해도 될 것 같고... 대신 언어 호환만 잘 해줬음 좋겠다.</p>
<pre><code class="language-java">import java.io.*;
import java.util.*;

class Main {
    static ArrayList&lt;ArrayList&lt;Integer&gt;&gt; graph;
    static boolean[] visited;
    static ArrayList&lt;Integer&gt; cycle;
    static int find = -1;

    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        int N = Integer.parseInt(st.nextToken());
        graph = new ArrayList&lt;&gt;();
        visited = new boolean[N+1];
        cycle = new ArrayList&lt;&gt;();

        for (int i = 0; i &lt;= N; i++) {
            graph.add(new ArrayList&lt;&gt;());
        }

        for(int i=0; i&lt;N; i++){
            st = new StringTokenizer(br.readLine());
            int start = Integer.parseInt(st.nextToken());
            int end = Integer.parseInt(st.nextToken());
            graph.get(start).add(end);
            graph.get(end).add(start);
        }

        findCycle(1, 1);

        System.out.println(cycle.size());
        Collections.sort(cycle);
        for(int i : cycle){
            System.out.print(i + &quot; &quot;);
        }

    }

    public static void findCycle(int u, int p){
        if(visited[u]){
            find = u;
            cycle.add(u);
            return;
        }

        visited[u] = true;

        for(int i : graph.get(u)){
            if(i == p) continue;
            findCycle(i, u);

            if(find == -2) return;

            if(find == u){
                find = -2;
                return;
            }

            if(find&gt;=0){
                cycle.add(u);
                return;
            }
        }
    }
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[구름 LEVEL - 알고리즘 먼데이 챌린지 2주차(JAVA)]]></title>
            <link>https://velog.io/@mongu_93/%EA%B5%AC%EB%A6%84-LEVEL-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EB%A8%BC%EB%8D%B0%EC%9D%B4-%EC%B1%8C%EB%A6%B0%EC%A7%80-2%EC%A3%BC%EC%B0%A8</link>
            <guid>https://velog.io/@mongu_93/%EA%B5%AC%EB%A6%84-LEVEL-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EB%A8%BC%EB%8D%B0%EC%9D%B4-%EC%B1%8C%EB%A6%B0%EC%A7%80-2%EC%A3%BC%EC%B0%A8</guid>
            <pubDate>Tue, 11 Oct 2022 08:18:55 GMT</pubDate>
            <description><![CDATA[<h2 id="2주차-문제-후기">2주차 문제 후기</h2>
<p>4/4솔, 걸린시간 1시간 내외
졸려서 다음 날 풀어보려했는데 잘못 눌렀더니 시작되버려서 부랴부랴 풀었다.
전 주차보다 어렵다기보다는 귀찮은 문제들이 많았다.
2주차라서 문제에 난이도가 🔥x2 였는데 어렵진 않았고
좌표값 문제인데 좌표값으로 풀려다가 꼼수 부려서 5분만에 끝냈다.
오히려 3번 문제가 헷갈려서 오래걸렸다.</p>
<p>아 그리고 챌린지 해설을 보니 언어가 파이썬이 주된 듯 하다.(C++도 있기는 하지만) 
난이도도 파이썬에 맞춰진 느낌 + 자바로 푸는 나로써는 정답 제공이 없어서 아쉬움...
그리고 내가 풀었었던 코드는 못보는 것 같다.</p>
<ul>
<li>링크 주소 : <a href="https://level.goorm.io/level/challenge">구름 - 알고리즘 먼데이 챌린지</a>
<img src="https://velog.velcdn.com/images/mongu_93/post/f44644ae-5754-4a66-ad1f-93d84c047a0b/image.png" alt=""></li>
</ul>
<p><br><br></p>
<h2 id="2주차-문제-해설-자바">2주차 문제 해설 (자바)</h2>
<p>코드를 올리고 싶은데 전에 풀었던 코드를 다시 못보는 것 같아 다시 풀기는 귀찮고...(다시 풀었다 결국)</p>
<p><strong>1번</strong> : 시험 개수만큼 반복문 돌려서 인원, 점수를 입력 받고 평균을 구한 다음 문제에 맞게 출력. 형 변환과 출력만 신경쓰면 되는 쉬운 문제.</p>
<p><strong>2번</strong> : 분리된 집합을 구하는 문제인데.. 앞에 글자랑 뒤에 글자랑 달라질 때 카운트를 1 증가시키면 된다.</p>
<p><strong>3번</strong> : 난이도가 1 치고는 어려운 문제. 2는 됐어야 할 듯
4번보다 어렵고 귀찮다. 
다중 조건 정렬이라 자바에서 Compare를 Override 해줘서 비교해줘야 한다. 더 쉬운 방법이 있는지는 모르겠다. 
소수점 둘째자리까지 보여야하므로 포매팅도 해줘야한다.</p>
<pre><code class="language-java">import java.io.*;
import java.util.*;

class Main {
    public static void main(String[] args) throws Exception {
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(bf.readLine());
        int N = Integer.parseInt(st.nextToken());
        int k = Integer.parseInt(st.nextToken());
        List&lt;People&gt; list = new ArrayList&lt;&gt;();

        for(int i=0; i&lt;N; i++){
            st = new StringTokenizer(bf.readLine());
            list.add(new People(st.nextToken(),Double.parseDouble(st.nextToken())));
        }

        Collections.sort(list, (p1, p2) -&gt; {
            if(p1.name.equals(p2.name)) {
                if(p1.height &gt; p2.height){
                    return 1;
                }else{
                    return -1;
                }
            }else {
                return p1.name.compareTo(p2.name);
            }
        });

        System.out.println(list.get(k-1).answer());
    }
}

class People {
    String name;
    double height;

    public People(String name, double height) {
        this.name = name;
        this.height = height;
    }

    public String answer() {
        return name + &quot; &quot; + String.format(&quot;%.2f&quot;, height);
    }
}</code></pre>
<p><strong>4번</strong> : 2차원 배열을 선언하고 좌표값 자기자신이랑 상하좌우 값을 더해 주는 것 같은데 복잡하게 하기 싫어서 상하좌우 벽만 없으면 각 방향당 1씩 카운트를 더해주면 되니 
좌표값이 1이거나 n일 때 조건만 걸고 카운트를 더해주었다.</p>
<pre><code class="language-java">/* MondayChallenge_week2_Q4 */
import java.io.*;
import java.util.*;

class Main {
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        int n = Integer.parseInt(st.nextToken());
        int k = Integer.parseInt(st.nextToken());
        int cnt = 0;

        // n이 1이면 한 칸이라 방향이 없으니 폭탄 터지는 수 만큼 반환
        if(n==1) {
            System.out.println(k);
            return;
        }

        //n이 1이 아닐 때
        for(int i=0; i&lt;k; i++){
            st = new StringTokenizer(br.readLine());
            int x = Integer.parseInt(st.nextToken());
            int y = Integer.parseInt(st.nextToken());

            if(x==1 || x==n) cnt += 2; //좌우 벽이 막혔을 때
            else cnt +=3; //자기 자신과 좌우 카운트 증가

            if(y==1 || y==n) cnt += 1; //상하 벽이 막혔을 때
            else cnt +=2; //상하 카운트 증가
        }

        System.out.println(cnt);
    }
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[Salesforce Certified Administrator 취득 후기]]></title>
            <link>https://velog.io/@mongu_93/Salesforce-Certified-Administrator-%EC%B7%A8%EB%93%9D-%ED%9B%84%EA%B8%B0</link>
            <guid>https://velog.io/@mongu_93/Salesforce-Certified-Administrator-%EC%B7%A8%EB%93%9D-%ED%9B%84%EA%B8%B0</guid>
            <pubDate>Tue, 04 Oct 2022 06:30:40 GMT</pubDate>
            <description><![CDATA[<p>요새 이래저래 바빠서 벨로그에 글을 너무 못 썼는데 그간 한 일들을 정리해보려고 한다.</p>
<p>우선 세일즈포스 관련 자격증 하나를 취득했다.
회사에서 아직은 세일즈포스를 쓰지는 않고 있는데 향후에 쓰게 될거고 자격증이 있으면 좋다고 해서 등록해서 쳐보았다.
자격증 응시 비용은 <strong>200$</strong> !!.. 환율이 고공행진을 하고 있어서 지금으로 치면 20만원대 후반으로 거의 30만원 가까이에 육박하는 금액,,</p>
<p>공부는 덤프를 주구장창 외우고 Salesforce Quiz 사이트에서 Quiz Set 여러 개 있는 것을 계속 풀어보았다. 덤프나 퀴즈에 틀리게 적힌 것 같은 답은 또 관련 내용을 찾아봐서 제대로 정답체크를 해보았다.
근데 이것도 은근 세일즈포스 사용법을 익히는데 나름 도움이 되는 듯 하다. 문제를 보다보면 어느게 어느 기능인지 예상되는 경우가 있다.</p>
<p>2주간 틈틈이 보고 시험 치는 전 일주일 전 부터는 퇴근 후와 주말 반납을 한 결과 다행히 한 번에 붙었다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[구름 LEVEL - 알고리즘 먼데이 챌린지 1주차 (JAVA)]]></title>
            <link>https://velog.io/@mongu_93/%EA%B5%AC%EB%A6%84-LEVEL-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EB%A8%BC%EB%8D%B0%EC%9D%B4-%EC%B1%8C%EB%A6%B0%EC%A7%80-1%EC%A3%BC%EC%B0%A8</link>
            <guid>https://velog.io/@mongu_93/%EA%B5%AC%EB%A6%84-LEVEL-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EB%A8%BC%EB%8D%B0%EC%9D%B4-%EC%B1%8C%EB%A6%B0%EC%A7%80-1%EC%A3%BC%EC%B0%A8</guid>
            <pubDate>Tue, 04 Oct 2022 06:00:02 GMT</pubDate>
            <description><![CDATA[<h2 id="알고리즘-먼데이-챌린지">알고리즘 먼데이 챌린지</h2>
<p>구름은 COS PRO 모의고사를 풀기 위해서 가입해서 종종 문제를 풀던 곳인데 
이번에 구름 LEVEL에서 8주동안 매주 진행하는 알고리즘 문제 챌린지를 오픈했다.
코테 공부도 할겸 상품도 주고 재미있어 보여서 참여 신청을 하였다.
한 주 한 주 더 어려워지는 것 같은데 나중에 7주차, 8주차를 풀 수 있을지 모르겠다.. 
그전에 연습을 해둬야지,,
테스트 방식은 백준하고 유사하고 IDE 환경은 프로그래머스와 유사하다고 보면 될 것이다.</p>
<ul>
<li>링크 주소 : <a href="https://level.goorm.io/level/challenge">구름 - 알고리즘 먼데이 챌린지</a>
<img src="https://velog.velcdn.com/images/mongu_93/post/f44644ae-5754-4a66-ad1f-93d84c047a0b/image.png" alt=""></li>
</ul>
<p><br><br></p>
<h2 id="1주차-문제-후기">1주차 문제 후기</h2>
<p>4/4솔, 걸린시간 50분 내외
10월 3일 문제 출제가 된 날 궁금해서 바로 풀어보았다.
문제는 총 4문제, 시간제한은 2시간이었다.
다른 주차도 동일한지는 아직 모르겠다.</p>
<p>나름 최하 난이도니 빨리 푼다고 풀었는데 문제를 잘못 이해해서 50분 걸렸다.
챌린지 해설이 나오기 전에 문제 공유가 불가능하다고 하니 문제에 대해서 언급은 하지 못할 것 같고 난이도는 1주차답게 낮다고 보면 된다. 주어진 문제만 잘 이해한다면 2시간 이내에 입문자들도 충분히 풀 수 있을 정도..
근데 다음주차들도 문제가 이렇게 나오면 이해를 잘못해서 오래걸리거나 못 풀수도 있을 것 같다.
프로그래머스나 기업 입사시험들 처럼 주어진 테스트케이스에 대해서는 설명을 좀 더 자세히 해줬으면 하는 바램이다.
그래도 확실히 챌린지라 하니 게임하는 것 같고 재미는 있다.</p>
<br>

<h2 id="1주차-문제-해설-자바">1주차 문제 해설 (자바)</h2>
<p>코드를 올리고 싶은데 전에 풀었던 코드를 다시 못보는 것 같아 다시 풀기는 귀찮고...</p>
<p><strong>1번</strong> : 간단하게 Input 값들의 단순 곱인데 자료형을 Long을 써줘야 테스트 케이스 통과할 것이다. 
BigInteger까지 필요할 수도?</p>
<p><strong>2번</strong> : 포함되는 문자열 찾는 문제. substring을 쓰려다 그냥 contains를 썼다.</p>
<p><strong>3번</strong> : 문제에서 공식을 제공해준다. 그대로 쓰면 된다. 절대값은 Math.Abs()</p>
<p><strong>4번</strong> : 소수 찾는 문제. 처음에는 문제를 잘못 읽어서 주어진 값이 소수인지 판별했는데 답이 이상하게 나왔다. 
1부터 n까지 인덱스가 소수인 걸 찾고 그 인덱스에 해당하는 값을 더하는 문제.
에라토스테네스의 체를 쓰면 된다.</p>
<ul>
<li><em>에라토스테네스 체</em>
간단하게 말해서 해당하는 숫자가 소수이면 그 배수들은 전부 소수가 아니므로 배열에 소수가 아니라고 체크하고 넘어가면 된다. 그러면 많은 수를 판별할 때 훨씬 시간이 짧아진다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[프로그래머스 - 코딩테스트 실전 대비 모의고사 2차 문제집, 1 ~ 3번 풀이 코드[JAVA]]]></title>
            <link>https://velog.io/@mongu_93/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%BD%94%EB%94%A9%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%8B%A4%EC%A0%84-%EB%8C%80%EB%B9%84-%EB%AA%A8%EC%9D%98%EA%B3%A0%EC%82%AC-2%EC%B0%A8-%EB%AC%B8%EC%A0%9C%EC%A7%91-%ED%92%80%EC%9D%B4-%EC%BD%94%EB%93%9CJAVA</link>
            <guid>https://velog.io/@mongu_93/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EC%BD%94%EB%94%A9%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%8B%A4%EC%A0%84-%EB%8C%80%EB%B9%84-%EB%AA%A8%EC%9D%98%EA%B3%A0%EC%82%AC-2%EC%B0%A8-%EB%AC%B8%EC%A0%9C%EC%A7%91-%ED%92%80%EC%9D%B4-%EC%BD%94%EB%93%9CJAVA</guid>
            <pubDate>Fri, 05 Aug 2022 08:58:11 GMT</pubDate>
            <description><![CDATA[<ul>
<li><p>문제 풀이는 블로그 등에 작성이 가능하다는 답변보고 글을 작성하였습니다.
정책이 변경되는 경우 알려주시면 해당 글 비공개 처리하도록 하겠습니다.</p>
</li>
<li><p>확인한 글의 출처 : <a href="https://career.programmers.co.kr/questions/34688">https://career.programmers.co.kr/questions/34688</a></p>
</li>
</ul>
<h2 id="1번">1번</h2>
<pre><code class="language-java">import java.util.Arrays;

class Solution {
    public int solution(int[] number) {
        int answer = 0;
        Arrays.sort(number);

        for(int i=0; i&lt;number.length-2; i++){
            if(number[i] &gt; 0) break;
            for(int j=i+1; j&lt;number.length-1; j++){
                if(number[i] + number[j] &gt; 0) break;
                for(int k=j+1; k&lt;number.length; k++){
                    if(number[i] + number[j] + number[k] == 0) answer++;
                }
            }
        }

        return answer;
    }
}</code></pre>
<p><img src="https://velog.velcdn.com/images/mongu_93/post/314b2eb2-66b8-4d75-bd0a-1bc2d70ad2aa/image.png" alt=""></p>
<h2 id="2번">2번</h2>
<pre><code class="language-java">class Solution {
    public int solution(int[] topping) {
        int answer = 0;

        boolean[] toppingType1 = new boolean[10001];
        int[] toppingType2 = new int[10001];

        int cnt1 = 0;
        int cnt2 = 0;

        for(int i=topping.length-1; i&gt;=0; i--){
            if(toppingType2[topping[i]] == 0) {
                cnt2++;
            }
            toppingType2[topping[i]]++;
        }

        for(int i=0; i&lt;topping.length-1; i++){
            if(!toppingType1[topping[i]]) {
                toppingType1[topping[i]] = true;
                cnt1++;
            }
            toppingType2[topping[i]] --;

            if(toppingType2[topping[i]] == 0){
                cnt2--;
            }

            if(cnt1 == cnt2) answer++;
        }

        return answer;
    }
}</code></pre>
<p><img src="https://velog.velcdn.com/images/mongu_93/post/d7d92c8f-3800-4367-9563-fc8b51035d37/image.png" alt=""></p>
<h2 id="3번">3번</h2>
<ul>
<li>BFS 활용, 주어진 연결을 노드로 그리기 중요 !!</li>
<li>System.out.print의 경우 루트 노드에서 연결된 노드 레벨 확인 용</li>
</ul>
<pre><code class="language-java">import java.util.*;

class Solution {
    static boolean[] visited;

    public int[] solution(int n, int[][] roads, int[] sources, int destination) {
        int[] answer = new int[sources.length];
        List&lt;List&lt;Integer&gt;&gt; nodeList = setList(n, roads);
        //System.out.println(nodeList);

        for(int i=0; i&lt;sources.length; i++){
            if(sources[i] == destination){
                answer[i] = 0;
                continue;
            }
            if(nodeList.get(sources[i]).isEmpty()) {
                answer[i] = -1;
                continue;
            }

            visited = new boolean[n+1];
            // System.out.println(&quot;&quot;);
            // System.out.println(&quot;@@@@ next @@@@&quot;);
            // System.out.println(&quot;&quot;);
            answer[i] = bfs(sources[i], destination, nodeList);
        }

        return answer;
    }

    //노드 그리기
    public static List&lt;List&lt;Integer&gt;&gt; setList (int n, int[][] roads) {
        List&lt;List&lt;Integer&gt;&gt; nodeList = new ArrayList&lt;&gt;();
        List&lt;Integer&gt; temp;

        for(int index = 0; index &lt;= n; index++) {
            nodeList.add(new ArrayList&lt;&gt;());
        }

        for(int index = 0; index &lt; roads.length; index++) {
            int start = roads[index][0];
            int end = roads[index][1];

            temp = nodeList.get(start);

            if(!temp.contains(end)) {
                temp.add(end);
            }

            temp = nodeList.get(end);

            if(!temp.contains(start)) {
                temp.add(start);
            }
        }
        return nodeList;
    }

    public static int bfs(int start, int end, List&lt;List&lt;Integer&gt;&gt; node){
        List&lt;Integer&gt; list;
        Queue&lt;Integer&gt; q = new LinkedList&lt;&gt;();
        int cnt = 1;

        q.offer(start);
        visited[start] = true;
        //System.out.println(&quot;---- level 0 -----&quot;);
        //System.out.println(start);

        while(!q.isEmpty()){

            int qSize = q.size();
            // System.out.println(&quot;&quot;);
            // System.out.println(&quot;---- level &quot; + cnt + &quot; -----&quot;);

            for(int qIndex=1; qIndex&lt;=qSize; qIndex++){
                list = node.get(q.poll());

                for(int i=0; i&lt;list.size(); i++){
                    int link = list.get(i);

                    if(!visited[link]) {
                        //System.out.println(link);
                        if(link == end) return cnt;
                        q.offer(link);
                        visited[link] = true;
                    }
                }
            }
            cnt++;
        }

        return -1;
    }
}</code></pre>
<p><img src="https://velog.velcdn.com/images/mongu_93/post/4f6b954d-4399-4af8-b562-737e6e439388/image.png" alt=""></p>
<br>

<p><em><strong>자세한 풀이는 차후에 자세히 쓰겠습니다. 궁금한 점은 댓글로 달아 주세요~</strong></em></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[DFS(깊이 우선 탐색), BFS(너비 우선 탐색)]]></title>
            <link>https://velog.io/@mongu_93/DFS%EA%B9%8A%EC%9D%B4-%EC%9A%B0%EC%84%A0-%ED%83%90%EC%83%89-BFS%EB%84%88%EB%B9%84-%EC%9A%B0%EC%84%A0-%ED%83%90%EC%83%89</link>
            <guid>https://velog.io/@mongu_93/DFS%EA%B9%8A%EC%9D%B4-%EC%9A%B0%EC%84%A0-%ED%83%90%EC%83%89-BFS%EB%84%88%EB%B9%84-%EC%9A%B0%EC%84%A0-%ED%83%90%EC%83%89</guid>
            <pubDate>Thu, 28 Jul 2022 01:21:42 GMT</pubDate>
            <description><![CDATA[<ul>
<li>** DFS와 BFS는 그래프를 탐색하는 방법**들로 코딩테스트에서 굉장히 자주나오고 유용하게 쓰이는 알고리즘이다. 
하지만 이해를 했다 싶어도 문제마다 적절히 응용하려니 늘 어려워서 검색 도움 없이 제대로 푼적이 별로 없다. 😥 
미로나 연결된 경로들을 보면 어느정도 느낌이 와서 조금 풀어볼만한데 응용해서 나오면 감이 오질 않는다 ...
프로그래머스 뿐만 아니라 백준의 문제까지 많이 풀어보면서 꼭 내껄로 만들 필요가 있을 것 같다.<br>

</li>
</ul>
<p><em>*<em>📢 아래에서 DFS와 BFS에 대해 자세히 알아보자 (정말 정말 중요 !! 💥)  📢 *</em></em>
<br></p>
<h2 id="dfs깊이-우선-탐색란-😲">DFS(깊이 우선 탐색)란? 😲</h2>
<p><img src="https://upload.wikimedia.org/wikipedia/commons/7/7f/Depth-First-Search.gif" alt=""></p>
<blockquote>
<p>출처: <a href="https://developer-mac.tistory.com/64">https://developer-mac.tistory.com/64</a></p>
</blockquote>
<br>
루트 노드(혹은 다른 임의의 노드)에서 시작해서 다음 분기(branch)로 넘어가기 전에 해당 분기를 완벽하게 탐색하는 방법으로 이러한 한 노드에서 제일 마지막 자식까지 탐색하고 돌아오는 과정을 백트래킹이라고 한다.

<ul>
<li>구현 방법 : 스택이나 재귀함수(인접행렬)로 구현</li>
</ul>
<h2 id="bfs너비-우선-탐색란-😵">BFS(너비 우선 탐색)란? 😵</h2>
<p><img src="https://upload.wikimedia.org/wikipedia/commons/5/5d/Breadth-First-Search-Algorithm.gif" alt=""></p>
<blockquote>
<p>출처: <a href="https://developer-mac.tistory.com/64">https://developer-mac.tistory.com/64</a></p>
</blockquote>
<br>]]></description>
        </item>
        <item>
            <title><![CDATA[[React] 훅(Hooks)]]></title>
            <link>https://velog.io/@mongu_93/React-%ED%9B%85Hooks</link>
            <guid>https://velog.io/@mongu_93/React-%ED%9B%85Hooks</guid>
            <pubDate>Thu, 14 Jul 2022 01:21:08 GMT</pubDate>
            <description><![CDATA[<h3 id="리액트-훅react-hooks🤔🤔">리액트 훅(React Hooks)🤔🤔</h3>
<ul>
<li>리액트 16.8 버전부터 추가된 기능, 클래스 컴포넌트와 생명주기 메서드를 이용하여 작업을 하던 기존 방식에서 벗어나 함수형 컴포넌트에서도 더 직관적인 함수를 이용하여 작업할 수 있게 만든 기능</li>
</ul>
<p>현재 듣는 리액트 강의에서 이러한 훅을 사용해서 개발을 하고 있었다.
들으면서 잘 이해가 가지 않는 부분도 있었고 정리가 필요하다고 느껴 훅에 대해서 간단하게 알아보려고 한다.</p>
<h3 id="장점">장점</h3>
<ul>
<li>기존 방식의 개발은 상태관련 로직이 한 곳에 묶여있기에 상태 로직의 재사용이 불가능하고 테스트가 어려웠지만 훅은 상태관련 로직을 추상화하여 재사용과 테스트가 가능</li>
<li>직관성을 가짐</li>
<li>더 빠른 성능과 코드의 양이 짧아짐<br>
### 규칙</li>
<li>최상위 레벨에서만 호출 가능. 반복문, 조건문, 중첩된 함수 내부에서 호출 불가</li>
<li>오직 리액트 함수 컴포넌트 내에서만 호출 가능<br>
### ❕ 리액트 내장 훅 API ❗</li>
</ul>
<ol>
<li>useState()</li>
<li>useEffect()</li>
<li>useContext()</li>
<li>useRef()</li>
<li>useReducer()</li>
<li>useMemo()</li>
<li>useCallback()</li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[도대체 React 는 무엇일까?]]></title>
            <link>https://velog.io/@mongu_93/%EB%8F%84%EB%8C%80%EC%B2%B4-React-%EB%8A%94-%EB%AC%B4%EC%97%87%EC%9D%BC%EA%B9%8C</link>
            <guid>https://velog.io/@mongu_93/%EB%8F%84%EB%8C%80%EC%B2%B4-React-%EB%8A%94-%EB%AC%B4%EC%97%87%EC%9D%BC%EA%B9%8C</guid>
            <pubDate>Tue, 12 Jul 2022 00:56:50 GMT</pubDate>
            <description><![CDATA[<h2 id="react">React</h2>
<ul>
<li><strong>React</strong>는 웹 프레임워크로, 자바스크립트 라이브러리의 하나로서 사용자 인터페이스를 만들기 위해 사용된다.</li>
<li>페이스북에서 개발하고 관리하는 UI 라이브러리</li>
</ul>
<p><strong>가상돔</strong></p>
<ul>
<li>리액트는 가상 돔을 통해서 UI를 빠르게 업데이트한다.</li>
<li>가상 돔은 이전 UI 상태를 메모리에 유지해서 변경된 부분만 실제 돔에 반영 해주는 기술이다.</li>
<li>불필요한 업데이트를 줄여서 성능이 좋아진다.</li>
</ul>
<p><strong>사용이유</strong></p>
<ul>
<li>UI를 자동으로 업데이트 해주기 때문</li>
<li>원래는 Dom을 직접 수정해야 하는데 쉽지 않으므로 프레임워크의 도움을 받음</li>
</ul>
<blockquote>
<p>리액트는 UI 기능만 제공한다. 
따라서 전역 상태 관리나 라우팅, 빌드 시스템을 각 개발자가 직접 구축해야 한다. 
리액트에서 create-react-app 이라는 툴을 제공하여 직접 구축해야 하는 번거로움을 줄여주고 있다.</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[Node.js는 무엇인가?]]></title>
            <link>https://velog.io/@mongu_93/Node.js%EB%8A%94-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80</link>
            <guid>https://velog.io/@mongu_93/Node.js%EB%8A%94-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80</guid>
            <pubDate>Wed, 06 Jul 2022 09:09:01 GMT</pubDate>
            <description><![CDATA[<h2 id="nodejs-✍️">Node.js ✍️</h2>
<blockquote>
<ul>
<li>JavaScript를 서버에서도 사용할 수 있도록 만든 프로그램</li>
</ul>
</blockquote>
<ul>
<li>V8이라는 JavaScript 엔진 위에서 동작하는 자바스크립트 런타임(환경)이다.
(V8 : 자바스크립트를 기계어로 컴파일 해주는 엔진)</li>
<li>서버사이트 스크립트 언어가 아니다. 프로그램(환경)이다.</li>
<li>웹서버와 같이 확장성 있는 네트워크 프로그램을 제작하기 위해 만들어졌다.</li>
</ul>
<br>

<h3 id="장점-😁">장점 😁</h3>
<ul>
<li>✨ 자바스크립트를 동일하게 사용해서 서버단 로직을 처리할 수 있다. ✨</li>
<li>새로운 언어를 습득하지 않고도 자바스크립트를 활용해 서버기술을 빠르게 개발하고 응용 가능.
즉 개발이 쉽다는 말이 된다. 서버 설치부터 화면 띄우는 것까지 빠르게 처리</li>
<li>Non-blocking I/O와 단일 스레드 이벤트 루프를 통한 높은 처리 성능</li>
<li>이벤트 기반 비동기방식 서버 무리가 적음<br>

</li>
</ul>
<p><strong>💡 한줄요약 : 
자바스크립트를 브라우저가 아닌 곳에서도 실행을 시켜보자!! 그러기 위한 자바스크립트의 실행환경!</strong></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스] 힙(Heap) - 이중우선순위큐 (JAVA)]]></title>
            <link>https://velog.io/@mongu_93/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%ED%9E%99Heap-%EC%9D%B4%EC%A4%91%EC%9A%B0%EC%84%A0%EC%88%9C%EC%9C%84%ED%81%90-JAVA</link>
            <guid>https://velog.io/@mongu_93/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%ED%9E%99Heap-%EC%9D%B4%EC%A4%91%EC%9A%B0%EC%84%A0%EC%88%9C%EC%9C%84%ED%81%90-JAVA</guid>
            <pubDate>Thu, 30 Jun 2022 00:47:39 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><a href="https://programmers.co.kr/learn/courses/30/lessons/42628">프로그래머스 - 이중우선순위 큐</a></p>
</blockquote>
<h3 id="문제-설명">문제 설명</h3>
<p>이중 우선순위 큐는 다음 연산을 할 수 있는 자료구조를 말합니다.</p>
<blockquote>
<p><strong>명령어</strong>
I 숫자 : 큐에 주어진 숫자를 삽입합니다.
D 1: 큐에서 최댓값을 삭제합니다.
D -1: 큐에서 최솟값을 삭제합니다.</p>
</blockquote>
<h3 id="제한사항">제한사항</h3>
<ul>
<li>operations는 길이가 1 이상 1,000,000 이하인 문자열 배열입니다.</li>
<li>operations의 원소는 큐가 수행할 연산을 나타냅니다.</li>
<li>원소는 “명령어 데이터” 형식으로 주어집니다.- 최댓값/최솟값을 삭제하는 연산에서 최댓값/최솟값이 둘 이상인 경우, 하나만 삭제합니다.</li>
<li>빈 큐에 데이터를 삭제하라는 연산이 주어질 경우, 해당 연산은 무시합니다.<br>
### 풀이방향
문제 이름에 풀이방향이 주어진 케이스이다.
최댓값/최솟값을 보면 우선순위큐를 사용해야겠다는게 감이와야 한다.
그리고 제목에서 우선순위큐를 두 개 이용해서 풀라고 힌트를 준다.

</li>
</ul>
<p>간단하게 최대 힙(Max Heap), 최소 힙(Min Heap)을 이용하면 된다.
각각의 큐를 두 개 만들고 명령어 문자열을 잘라서 명령어에 따라 큐에 삽입/삭제 연산을 하면 된다.
삽입 연산 시 2개의 큐에 값을 삽입하고 삭제 연산 시 최댓값이면 최대 힙에서 첫번째 값 반환 후 삭제, 최소 힙에서 최댓값 반환 받은 값 삭제, 최솟값일 시에는 반대로 삭제 연산을 수행하면 된다.</p>
<pre><code class="language-java">import java.util.*;

class Solution {
    public int[] solution(String[] operations) {
        int[] answer = new int[2];
        PriorityQueue&lt;Integer&gt; pq1 = new PriorityQueue&lt;&gt;();
        PriorityQueue&lt;Integer&gt; pq2 = new PriorityQueue&lt;&gt;(Collections.reverseOrder());

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

            if(operations[i].substring(0,1).equals(&quot;I&quot;)){
                pq1.offer(Integer.parseInt(operations[i].substring(2)));
                pq2.offer(Integer.parseInt(operations[i].substring(2)));
                continue;
            }

            if(pq1.isEmpty()) continue;

            switch(operations[i].substring(2)){
                case &quot;1&quot;:
                    int max = pq2.poll();
                    pq1.remove(max);
                    break;
                case &quot;-1&quot;:
                    int min = pq1.poll();
                    pq2.remove(min);
                    break;
            }

        }

        if(pq1.size() &gt; 0 ) {
            answer[0] = pq2.peek();
            answer[1] = pq1.peek();
        }

        return answer;
    }
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스] 힙(Heap) - 디스크 컨트롤러 (JAVA)]]></title>
            <link>https://velog.io/@mongu_93/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%ED%9E%99Heap-%EB%94%94%EC%8A%A4%ED%81%AC-%EC%BB%A8%ED%8A%B8%EB%A1%A4%EB%9F%AC-JAVA</link>
            <guid>https://velog.io/@mongu_93/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%ED%9E%99Heap-%EB%94%94%EC%8A%A4%ED%81%AC-%EC%BB%A8%ED%8A%B8%EB%A1%A4%EB%9F%AC-JAVA</guid>
            <pubDate>Wed, 29 Jun 2022 14:36:36 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p><a href="https://programmers.co.kr/learn/courses/30/lessons/42627">프로그래머스 - 디스크 컨트롤러</a></p>
</blockquote>
<h3 id="문제-설명">문제 설명</h3>
<p>하드디스크는 한 번에 하나의 작업만 수행할 수 있습니다. 디스크 컨트롤러를 구현하는 방법은 여러 가지가 있습니다. 가장 일반적인 방법은 요청이 들어온 순서대로 처리하는 것입니다.</p>
<p>예를들어</p>
<blockquote>
<ul>
<li>0ms 시점에 3ms가 소요되는 A작업 요청</li>
</ul>
</blockquote>
<ul>
<li>1ms 시점에 9ms가 소요되는 B작업 요청</li>
<li>2ms 시점에 6ms가 소요되는 C작업 요청</li>
</ul>
<p>와 같은 요청이 들어왔습니다. 이를 그림으로 표현하면 아래와 같습니다.</p>
<p><img src="https://velog.velcdn.com/images/mongu_93/post/a9929fb2-9beb-41d1-8797-b94b91aa88a1/image.png" alt=""></p>
<p>한 번에 하나의 요청만을 수행할 수 있기 때문에 각각의 작업을 요청받은 순서대로 처리하면 다음과 같이 처리 됩니다.</p>
<p><img src="https://velog.velcdn.com/images/mongu_93/post/a2624bbb-fa1a-4c14-9671-0f6ecbf310c3/image.png" alt=""></p>
<blockquote>
<ul>
<li>A: 3ms 시점에 작업 완료 (요청에서 종료까지 : 3ms)</li>
</ul>
</blockquote>
<ul>
<li>B: 1ms부터 대기하다가, 3ms 시점에 작업을 시작해서 12ms 시점에 작업 완료(요청에서 종료까지 : 11ms)</li>
<li>C: 2ms부터 대기하다가, 12ms 시점에 작업을 시작해서 18ms 시점에 작업 완료(요청에서 종료까지 : 16ms)</li>
</ul>
<p>이 때 각 작업의 요청부터 종료까지 걸린 시간의 평균은 10ms(= (3 + 11 + 16) / 3)가 됩니다.</p>
<p>하지만 A → C → B 순서대로 처리하면
<img src="https://velog.velcdn.com/images/mongu_93/post/474e814d-d7d6-41ef-9d61-0a15f68843d5/image.png" alt=""></p>
<blockquote>
<ul>
<li>A: 3ms 시점에 작업 완료(요청에서 종료까지 : 3ms)</li>
</ul>
</blockquote>
<ul>
<li>C: 2ms부터 대기하다가, 3ms 시점에 작업을 시작해서 9ms 시점에 작업 완료(요청에서 종료까지 : 7ms)</li>
<li>B: 1ms부터 대기하다가, 9ms 시점에 작업을 시작해서 18ms 시점에 작업 완료(요청에서 종료까지 : 17ms)</li>
</ul>
<p>이렇게 A → C → B의 순서로 처리하면 각 작업의 요청부터 종료까지 걸린 시간의 평균은 9ms(= (3 + 7 + 17) / 3)가 됩니다.</p>
<p>각 작업에 대해 [작업이 요청되는 시점, 작업의 소요시간]을 담은 2차원 배열 jobs가 매개변수로 주어질 때, 작업의 요청부터 종료까지 걸린 시간의 평균을 가장 줄이는 방법으로 처리하면 평균이 얼마가 되는지 return 하도록 solution 함수를 작성해주세요. (단, 소수점 이하의 수는 버립니다)
<br></p>
<h3 id="제한-사항">제한 사항</h3>
<ul>
<li>jobs의 길이는 1 이상 500 이하입니다.</li>
<li>jobs의 각 행은 하나의 작업에 대한 [작업이 요청되는 시점, 작업의 소요시간] 입니다.</li>
<li>각 작업에 대해 작업이 요청되는 시간은 0 이상 1,000 이하입니다.</li>
<li>각 작업에 대해 작업의 소요시간은 1 이상 1,000 이하입니다.</li>
<li>하드디스크가 작업을 수행하고 있지 않을 때에는 먼저 요청이 들어온 작업부터 처리합니다.<br>

</li>
</ul>
<h3 id="풀이-방향">풀이 방향</h3>
<p>작업이 요청되는 시점이 빠를수록 그리고 작업이 수행 되고 있을 때 다른 대기 중인 작업들의 요청 시간이 겹치면 
대기 작업의 소요시간이 짧을수록 먼저 수행되게 코드를 짜면 될 것이라 생각했다.</p>
<p>먼저 주어진 jobs안의 작업 요청이 무작위로 섞여 있을 수 있기 때문에 가장 먼저 jobs 배열을 요청 시간으로 오름차순 정렬을 한다.</p>
<p>그 다음 요청에 작업의 소요시간이 적은 게 제일 먼저 오도록 우선순위 큐를 만들어준다. (큐에 요청이 들어올 때 작업시간이 제일 적은 것이 우선순위가 높아지면서 오름차순 정렬)</p>
<p>하나의 작업이 완료가 되는 시점까지 들어온 요청을 큐에 넣고 큐가 비고 작업할게 남아있지 않으면 
모든 작업의 개별 작업 시간 (작업 완료 시간 - 작업 요청 시간)을 더해서 평균을 구해준다.</p>
<pre><code class="language-java">import java.util.*;

class Solution {
    public int solution(int[][] jobs) {
        int answer = 0;

        //요청 시간 정렬
        Arrays.sort(jobs, (o1, o2) -&gt; o1[0] - o2[0]);
        //우선순위 큐로 작업 시간 정렬
        PriorityQueue&lt;int[]&gt; pq = new PriorityQueue&lt;&gt;((o1, o2) -&gt; o1[1] - o2[1]);

        int i = 0;
        int time = jobs[0][0];

        while(i &lt; jobs.length || !pq.isEmpty()){ // 큐가 비어있고 작업할게 없으면 종료

            //큐에 삽입 (하나의 작업이 완료되는 시점까지 들어온 모든 요청을 큐에 넣음)
            while(i&lt; jobs.length &amp;&amp; !(jobs[i][0] &gt; time)){
                pq.offer(jobs[i++]);
            }

            //큐가 비어져있으면(중간에 비는 경우) 시간 초기화(i번째 작업이 요청되는 시점으로)
            if(pq.isEmpty()) {
                time = jobs[i][0];
                pq.offer(jobs[i++]);
            }

            //작업
            int[] work = pq.poll();
            time += work[1];
            //작업 완료 시간 - 작업 요청 시간
            answer += time-work[0];
        }

        //평균
        return answer/jobs.length;
    }
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[프로그래머스] 힙(Heap) - 더 맵게 (JAVA)]]></title>
            <link>https://velog.io/@mongu_93/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%ED%9E%99Heap-%EB%8D%94-%EB%A7%B5%EA%B2%8C-JAVA</link>
            <guid>https://velog.io/@mongu_93/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%ED%9E%99Heap-%EB%8D%94-%EB%A7%B5%EA%B2%8C-JAVA</guid>
            <pubDate>Wed, 29 Jun 2022 13:48:37 GMT</pubDate>
            <description><![CDATA[<blockquote>
<ul>
<li><a href="https://programmers.co.kr/learn/courses/30/lessons/42626">프로그래머스 - 더 맵게</a></li>
</ul>
</blockquote>
<h3 id="🔍-문제-설명">🔍 문제 설명</h3>
<p>매운 것을 좋아하는 Leo는 모든 음식의 스코빌 지수를 K 이상으로 만들고 싶습니다. 
모든 음식의 스코빌 지수를 K 이상으로 만들기 위해 Leo는 스코빌 지수가 가장 낮은 두 개의 음식을 
아래와 같이 특별한 방법으로 섞어 새로운 음식을 만듭니다.</p>
<p>섞은 음식의 스코빌 지수 = 가장 맵지 않은 음식의 스코빌 지수 + (두 번째로 맵지 않은 음식의 스코빌 지수 * 2)
Leo는 모든 음식의 스코빌 지수가 K 이상이 될 때까지 반복하여 섞습니다.</p>
<p>Leo가 가진 음식의 스코빌 지수를 담은 배열 scoville과 원하는 스코빌 지수 K가 주어질 때, 
모든 음식의 스코빌 지수를 K 이상으로 만들기 위해 섞어야 하는 최소 횟수를 return 하도록 solution 함수를 작성해주세요.</p>
<blockquote>
<ul>
<li>배열중 스코빌 지수가 가장 낮은 두개의 음식을 조건(x + y*2)을 통해서 계산해 
모든 배열의 값이 k 이상이 되게 만들어 섞은 횟수를 return 하는 문제 </li>
</ul>
</blockquote>
<h3 id="📢-제한-사항">📢 제한 사항</h3>
<ul>
<li>scoville의 길이는 2 이상 1,000,000 이하입니다.</li>
<li>K는 0 이상 1,000,000,000 이하입니다.</li>
<li>scoville의 원소는 각각 0 이상 1,000,000 이하입니다.</li>
<li>모든 음식의 스코빌 지수를 K 이상으로 만들 수 없는 경우에는 -1을 return 합니다.<br>

</li>
</ul>
<h3 id="📝-풀이">📝 풀이</h3>
<ul>
<li>힙(우선순위 큐)은 자동으로 정렬이 된다는 것을 이용해 제일 작은 값과 그 다음 작은 값을 꺼내 연산 후 비교<br>


</li>
</ul>
<p>처음에는 힙에 대한 개념 없이 그냥 ArrayList로도 쉽게 풀 수 있겠다 싶어 최솟값을 반환하고 그 다음 최솟값을 반환해서 푸니 정확성 테스트는 통과했으나 효율성 테스트를 통과하지 못했다.</p>
<p>힙에 대한 내용을 확실하게 공부를 하고 보니 최솟값 찾는 속도가 훨씬 빠를 것이라 생각이 들어 우선순위 큐를 이용해 풀었다.</p>
<pre><code class="language-java">import java.util.*;

class Solution {
    public int solution(int[] scoville, int K) {
        int answer = 0;


        //우선순위 큐 선언
        PriorityQueue&lt;Integer&gt; pq = new PriorityQueue&lt;&gt;();

        //우선순위 큐에 스코빌 배열 요소 삽입
        for(int i : scoville){
            pq.offer(i);
        }

        //최솟값이 조건 K보다 작을 때 반복
        while(pq.peek() &lt; K){
            pq.offer(pq.poll() + pq.poll()*2); // 최솟값 반환, 다음 최솟값 반환 * 2
            answer++;

            //마지막 남은 음식도 K보다 작으면 -1 반환
            if (pq.peek() &lt; K &amp;&amp; pq.size() == 1) {
                answer = -1;
                break;
            }
        }

        return answer;

        /* 효율성 테스트 시간초과 
        ArrayList&lt;Integer&gt; array = new ArrayList&lt;&gt;();

        for(int s : scoville) {
            array.add(s);
        }

        int min = Collections.min(array);

        while(min &lt; K){
            array.remove(Integer.valueOf(min));
            if(array.size()==0) {
                answer = -1;
                break;
            }

            int temp = Collections.min(array);
            array.remove(Integer.valueOf(temp));

            int newFood = min + temp*2;
            array.add(newFood);
            answer ++;

            min = Collections.min(array);
        } 
        */
    }
}</code></pre>
<ul>
<li>peek() : 첫 번째 값 반환</li>
<li>poll() : 첫 번째 값 반환 후 제거</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[자바스크립트 비동기 처리 3 - Async & Await]]></title>
            <link>https://velog.io/@mongu_93/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EB%B9%84%EB%8F%99%EA%B8%B0-%EC%B2%98%EB%A6%AC-3-Async-Await</link>
            <guid>https://velog.io/@mongu_93/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EB%B9%84%EB%8F%99%EA%B8%B0-%EC%B2%98%EB%A6%AC-3-Async-Await</guid>
            <pubDate>Tue, 28 Jun 2022 01:11:28 GMT</pubDate>
            <description><![CDATA[<p><strong>Async &amp; Await</strong>는 기존의 비동기 처리 방식인 콜백 함수와 프로미스의 단점을 보완하고 개발자가 읽기 좋은 코드를 작성할 수 있게 도와주는 비동기 처리 패턴 문법
<br></p>
<h2 id="async--await-기본-문법">async &amp; await 기본 문법</h2>
<pre><code class="language-javascript">async function 함수명() {
  await 비동기_처리_메서드_명();
}</code></pre>
<p>함수의 앞에 <strong>async</strong> 라는 예약어를 붙이고 함수의 내부 로직 중 HTTP 통신을 하는 비동기 처리 코드 앞에 <strong>await</strong>를 붙인다. </p>
<p><strong>*** 비동기 처리 메서드가 꼭 프로미스 객체를 반환해야 **await</strong>가 의도한 대로 동작</p>
<br>

<p><strong>예제</strong></p>
<pre><code class="language-javascript">function fetchItems() {
  return new Promise(function(resolve, reject) {
    var items = [1,2,3];
    resolve(items) // 이행
  });
}

async function logItems() {
  var resultItems = await fetchItems();
  console.log(resultItems); // [1,2,3], fetchItems()의 items 반환
}</code></pre>
<p>fetchItems() 함수는 프로미스 객체를 반환하는 함수, fetchItems() 함수를 실행하면 프로미스가 이행(Resolved)되며 결과 값은 items 배열</p>
<p>logItems() 함수를 실행하면 fetchItems() 함수의 결과 값인 items 배열이 resultItems 변수에 담긴다. </p>
<p>따라서, 콘솔에는 [1,2,3]이 출력
<br></p>
<h3 id="async--await-예외-처리">async &amp; await 예외 처리</h3>
<p>async &amp; await에서 예외를 처리하는 방법은 try catch.
프로미스에서 에러 처리를 위해 .catch()를 사용했던 것처럼 async에서는 catch {} 를 사용</p>
<p><strong>예시</strong></p>
<pre><code class="language-javascript">async function logTodoTitle() {
  try {
    var user = await fetchUser();
    if (user.id === 1) {
      var todo = await fetchTodo();
      console.log(todo.title); 
    }
  } catch (error) {
    console.log(error);
  }
}</code></pre>
<p>발견된 에러는 error 객체에 담기기 때문에 에러의 유형에 맞게 에러 코드를 처리</p>
<br>

<blockquote>
<p>출처 : <a href="https://joshua1988.github.io/web-development/javascript/js-async-await">https://joshua1988.github.io/web-development/javascript/js-async-await</a> - (Captain Pangyo)</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[최소 신장 트리 - (크루스칼 알고리즘)]]></title>
            <link>https://velog.io/@mongu_93/%EC%B5%9C%EC%86%8C-%EC%8B%A0%EC%9E%A5-%ED%8A%B8%EB%A6%AC</link>
            <guid>https://velog.io/@mongu_93/%EC%B5%9C%EC%86%8C-%EC%8B%A0%EC%9E%A5-%ED%8A%B8%EB%A6%AC</guid>
            <pubDate>Thu, 23 Jun 2022 07:48:02 GMT</pubDate>
            <description><![CDATA[<p><strong>신장 트리</strong> :  모든 임의의 정점이 연결된 그래프인 연결 그래프의 부분 그래프, 모든 정점이 간선으로 연결되어 있지만 사이클이 존재하지 않는 그래프
<br></p>
<h3 id="최소-신장-트리">최소 신장 트리</h3>
<p>신장 트리를 구성하는 간선들의 가중치 합이 가장 작은 신장 트리, 최소 신장 트리를 구현하는 알고리즘은 주로 2가지(크루스칼, 프림)가 있다.
<br></p>
<h3 id="👀-크루스칼-알고리즘">👀 크루스칼 알고리즘</h3>
<p>최소 신장 트리 구현에 사용되는 알고리즘으로 가중치 그래프의 모든 간선들을 대상으로 </p>
<blockquote>
<p>1)  최소 비용의 간선으로 구성
2)  &quot;사이클을 형성하지 않음&quot;</p>
</blockquote>
<p>위 조건을 지켜가며 각 단계마다 사이클을 이루지 않는 최소 비용 간선을 선택하여 최소 신장 트리를 완성하는 알고리즘</p>
<p><img src="https://velog.velcdn.com/images/mongu_93/post/2468b263-d9a2-493c-9058-b590e8577060/image.png" alt="">
위 순서대로(간선의 비용이 적은 순서대로) 선택하여 모든 노드가 연결되면 종료한다.</p>
<p>매 단계마다 최선의 해를 선택하기에 그리디 알고리즘에 바탕을 두고있으며
서로소 집합(Disjoint Set), 유니온 파인드(Union-Find)을 알아야 알고리즘을 올바르게 구현할 수 있다.
<br>
<strong>🧐 서로소 집합이란?</strong></p>
<p>공통 원소가 없는 두 집합을 의미
서로소 집합은 트리 자료구조를 통해 집합을 표현하고, 연산을 수행
하나의 트리를 하나의 집합으로 볼 때, find연산은 트리의 루트노드를 찾고, 그 루트노드를 통해 특정 집합을 표현
그리고 union 연산의 경우 두 원소에 대해 find 연산을 수행하여 각각의 루트노드를 찾고, 
한 쪽의 루트노드를 다른 쪽에 연결함으로써 하나의 트리로 만드는 합집합 연산을 수행
<br></p>
<h3 id="👀-유니온-파인드">👀 유니온 파인드</h3>
<p>상호 배타적 집합(Disjoint-set)</p>
<p>▷ 여러 노드가 존재할 때, 두 개의 노드를 선택해서, 현재 두 노드가 서로 같은 그래프에 속하는지 판별하는 알고리즘</p>
<p>▷ 2가지 연산으로 이루어져 있음.</p>
<ul>
<li><p>Find : x가 어떤 집합에 포함되어 있는지 찾는 연산</p>
</li>
<li><p>Union : x와 y가 포함되어 있는 집합을 합치는 연산</p>
</li>
</ul>
<p><strong>코드 예시</strong></p>
<pre><code class="language-java">class Solution {
    static int[] parent;

    /* A가 속한 집합, B가 속한 집합을 합침.
    1) A와 B의 루트 노드 A&#39;,B&#39;를 각각 찾는다
     2) A&#39;를 B&#39;의 부모 노드로 설정한다 */
    public static void union(int a, int b) {
        a = find(a);
        b = find(b);
        if(a != b) parent[b] = a;
    }

    // x가 속한 루트 노드 값을 반환, 즉 x가 어느 집합에 속해있는지 확인
    public static int find(int x) {
        if (x == parent[x])
            return x;
        else
            return parent[x] = find(parent[x]);
    }

}</code></pre>
<br>

<h3 id="💻-코딩테스트-연습-문제">💻 코딩테스트 연습 문제</h3>
<p>&amp;nbsp&amp;nbsp&amp;nbsp<strong>(크루스칼 알고리즘 사용 예 - 프로그래머스 [섬 연결하기])</strong></p>
<p><em><strong>문제</strong></em></p>
<pre><code>n개의 섬 사이에 다리를 건설하는 비용(costs)이 주어질 때, 
최소의 비용으로 모든 섬이 서로 통행 가능하도록 만들 때 필요한 최소 비용을 return 하도록 solution을 완성하세요.

다리를 여러 번 건너더라도, 도달할 수만 있으면 통행 가능하다고 봅니다. 
예를 들어 A 섬과 B 섬 사이에 다리가 있고, 
B 섬과 C 섬 사이에 다리가 있으면 A 섬과 C 섬은 서로 통행 가능합니다.


**제한사항**

섬의 개수 n은 1 이상 100 이하입니다. costs의 길이는 ((n-1) * n) / 2이하입니다.
임의의 i에 대해, costs[i][0] 와 costs[i] [1]에는 다리가 연결되는 두 섬의 번호가 들어있고, 
costs[i] [2]에는 이 두 섬을 연결하는 다리를 건설할 때 드는 비용입니다.

같은 연결은 두 번 주어지지 않습니다. 또한 순서가 바뀌더라도 같은 연결로 봅니다. 
즉 0과 1 사이를 연결하는 비용이 주어졌을 때, 1과 0의 비용이 주어지지 않습니다.

모든 섬 사이의 다리 건설 비용이 주어지지 않습니다. 
이 경우, 두 섬 사이의 건설이 불가능한 것으로 봅니다.

연결할 수 없는 섬은 주어지지 않습니다.</code></pre><br>

<p><em><strong>코드 풀이</strong></em></p>
<pre><code class="language-java">import java.util.Arrays;

class Solution {
    static int[] parent; //부모 노드 담을 배열

    public int solution(int n, int[][] costs) {
        int answer = 0;
        parent = new int[n];

        //다리 연결 비용 내림차순 정렬
        Arrays.sort(costs, (o1, o2) -&gt; Integer.compare(o1[2], o2[2])); 

        //부모노드 초기화
        for(int i=0; i&lt;n; i++){
            parent[i] = i;
        }

        //A섬, B섬이 연결되어있는지 찾아서 비용 반환
        for(int[] cost : costs){
            if(find(cost[0]) != find(cost[1])) {
                answer += cost[2];
                union(cost[0], cost[1]);
            }
        }
        return answer;
    }

    //유니온 (a를 b의 부모 노드로 설정)
    public static void union(int a, int b) {
        a = find(a);
        b = find(b);
        if(a != b) parent[b] = a;
    }

    //x가 속한 루트 노드 값을 반환
    public static int find(int x) {
        if (x == parent[x])
            return x;
        else
            return parent[x] = find(parent[x]);
    }

}
</code></pre>
<blockquote>
<p>프로그래머스 - 섬 연결하기 (탐욕법)
<a href="https://programmers.co.kr/learn/courses/30/lessons/42861">https://programmers.co.kr/learn/courses/30/lessons/42861</a></p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[자바스크립트 비동기 처리 2 - Promise]]></title>
            <link>https://velog.io/@mongu_93/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EB%B9%84%EB%8F%99%EA%B8%B0-%EC%B2%98%EB%A6%AC-2-Promise</link>
            <guid>https://velog.io/@mongu_93/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EB%B9%84%EB%8F%99%EA%B8%B0-%EC%B2%98%EB%A6%AC-2-Promise</guid>
            <pubDate>Tue, 21 Jun 2022 06:07:01 GMT</pubDate>
            <description><![CDATA[<h2 id="프로미스란">프로미스란?</h2>
<h4 id="자바스크립트-비동기-처리에-사용되는-객체">자바스크립트 비동기 처리에 사용되는 객체</h4>
<br>

<p><strong>기존 콜백 함수 코드</strong></p>
<pre><code class="language-javascript">function getData(callbackFunc) {
  $.get(&#39;url 주소/products/1&#39;, function(response) {
    callbackFunc(response); // 서버에서 받은 데이터 response를 callbackFunc() 함수에 넘겨줌
  });
}

getData(function(tableData) {
  console.log(tableData); // $.get()의 response 값이 tableData에 전달됨
});</code></pre>
<p>위의 코드를 프로미스를 사용해서 작성하면 아래와 같이 된다. 
<br></p>
<p><strong>프로미스를 사용한 코드</strong></p>
<pre><code class="language-javascript">function getData(callback) {
  // new Promise() 추가
  return new Promise(function(resolve, reject) {
    $.get(&#39;url 주소/products/1&#39;, function(response) {
      // 데이터를 받으면 resolve() 호출
      resolve(response);
    });
  });
}

// getData()의 실행이 끝나면 호출되는 then()
getData().then(function(tableData) {
  // resolve()의 결과 값이 여기로 전달됨
  console.log(tableData); // $.get()의 reponse 값이 tableData에 전달됨
});</code></pre>
<p>못 보던 new Promise(), resolve(), then()이 추가되었다.
이를 이해하기 위해서는 프로미스의 3가지 상태를 알아야 한다.</p>
<p>프로미스는 new Promise()로 생성하고 종료될 때까지 3가지의 상태를 갖는다.</p>
<blockquote>
<ul>
<li><strong>Pending(대기)</strong> : 비동기 처리 로직이 아직 완료되지 않은 상태</li>
</ul>
</blockquote>
<ul>
<li><strong>Fulfilled(이행)</strong> : 비동기 처리가 완료되어 프로미스가 결과 값을 반환해준 상태</li>
<li><strong>Rejected(실패)</strong> : 비동기 처리가 실패하거나 오류가 발생한 상태</li>
</ul>
<br>

<h3 id="pending대기">Pending(대기)</h3>
<p>new Promise() 메서드를 호출하면 대기(Pending) 상태가 된다.
new Promise() 메서드를 호출할 때 콜백 함수를 선언할 수 있고, 콜백 함수의 인자는 resolve, reject이다.</p>
<pre><code class="language-javascript">new Promise(function(resolve, reject) {
  // ...
});</code></pre>
<br>

<h3 id="fulfilled이행">Fulfilled(이행)</h3>
<p>콜백 함수의 인자 resolve를 아래와 같이 실행하면 이행(Fulfilled) 상태
이행 상태가 되면 then()을 이용하여 처리 결과 값을 받을 수 있다.</p>
<pre><code class="language-javascript">function getData() {
  return new Promise(function(resolve, reject) {
    var data = 100;
    resolve(data); //이행 상태
  });
}

// resolve()의 결과 값 data를 resolvedData로 받음
getData().then(function(resolvedData) {
  console.log(resolvedData); // 100
});</code></pre>
<br>

<h3 id="rejected실패">Rejected(실패)</h3>
<p>new Promise()로 프로미스 객체를 생성하면 콜백 함수 인자로 reject를 사용할 수 있다. reject를 아래와 같이 호출하면 실패(Rejected) 상태가 된다.</p>
<pre><code class="language-javascript">function getData() {
  return new Promise(function(resolve, reject) {
    reject(new Error(&quot;Request is failed&quot;));
  });
}

// reject()의 결과 값 Error를 err에 받음
getData().then().catch(function(err) {
  console.log(err); // Error: Request is failed
});</code></pre>
<p><img src="https://velog.velcdn.com/images/mongu_93/post/4fe2dec1-f006-4612-ab38-81271af030a8/image.png" alt=""></p>
<h6 id="nbspnbsp_프로미스-처리-흐름---출처--mdn_">&amp;nbsp&amp;nbsp_프로미스 처리 흐름 - 출처 : MDN_</h6>
<p>프로미스의 또 다른 특징은 여러 개의 프로미스를 연결하여 사용할 수 있다는 점
then() 메서드를 호출하고 나면 새로운 프로미스 객체가 반환.
즉, then() 으로 여러 개의 프로미스를 연결할 수 있음.</p>
<h3 id="프로미스-에러-처리">프로미스 에러 처리</h3>
<p>then()에 catch()를 붙여 에러 처리에 사용</p>
<pre><code class="language-javascript">function getData() {
  return new Promise(function(resolve, reject) {
    reject(&#39;failed&#39;);
  });
}

//catch()로 에러를 처리하는 코드
getData().then().catch(function(err) {
  console.log(err);
});</code></pre>
<blockquote>
<p>출처 : <a href="https://joshua1988.github.io/web-development/javascript/promise-for-beginners/">https://joshua1988.github.io/web-development/javascript/promise-for-beginners/</a> - (Captain Pangyo)</p>
</blockquote>
]]></description>
        </item>
    </channel>
</rss>