<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>악깡버 &amp;zwj; </title>
    <link>https://k-ang.tistory.com/</link>
    <description>될 때까지</description>
    <language>ko</language>
    <pubDate>Sun, 9 Aug 2026 17:47:32 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>suuunnnn</managingEditor>
    <image>
      <title>악깡버 &amp;zwj; </title>
      <url>https://tistory1.daumcdn.net/tistory/4723208/attach/ca7cac4b3b374997adbb7062d0657dd8</url>
      <link>https://k-ang.tistory.com</link>
    </image>
    <item>
      <title>[BOJ] 게리맨더링 Java</title>
      <link>https://k-ang.tistory.com/181</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;부분집합 + BFS&lt;/p&gt;
&lt;pre id=&quot;code_1748175374956&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.io.*;
import java.util.*;

public class BOJ_게리맨더링_v2 {

	static int N, ans, cntA, cntB;
	static int[] people;
	static int[][] matrix;	// 연결된 노드들
	static boolean[] isSelected, visited;
	static Queue&amp;lt;Integer&amp;gt; queue = new ArrayDeque&amp;lt;&amp;gt; ();
	
	public static void main(String[] args) throws Exception {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		N = Integer.parseInt(br.readLine());
		
		people = new int[N+1];
		matrix = new int[N+1][N+1];
		isSelected = new boolean[N+1];
		
		StringTokenizer st = new StringTokenizer(br.readLine());
		for (int i=1; i&amp;lt;=N; i++) {
			people[i] = Integer.parseInt(st.nextToken());
		}
		for (int i=1; i&amp;lt;=N; i++) {
			st = new StringTokenizer(br.readLine());
			int cnt = Integer.parseInt(st.nextToken());
			for (int j=1; j&amp;lt;=cnt; j++) {
				int num = Integer.parseInt(st.nextToken());
				matrix[i][num] = 1;	// 연결된 노드들
			}
		} //입력끝
		
		ans = Integer.MAX_VALUE;
		subset(1);
		System.out.println(ans==Integer.MAX_VALUE? -1:ans);
	}

	/**
	 * 부분집합
	 */
	static void subset(int idx) {
		if (idx == N+1) {
			check();	// 두 부분집합에 대해서 bfs
			return;
		}
		isSelected[idx] = true;
		subset(idx+1);
		isSelected[idx] = false;
		subset(idx+1);
	}
	
	static void check() {
		List&amp;lt;Integer&amp;gt; A = new ArrayList&amp;lt;&amp;gt; ();
		List&amp;lt;Integer&amp;gt; B = new ArrayList&amp;lt;&amp;gt; ();
		for (int i=1; i&amp;lt;=N; i++) {
			if (isSelected[i]) {
				A.add(i);
				continue;
			}
			B.add(i);
		}
		if (A.size() &amp;lt; 1 || B.size() &amp;lt; 1) return; // 구역 당 선거구가 1개라도 있어야 함

		visited = new boolean[N+1];
		cntA = bfs(A, true);
		cntB = bfs(B, false);
		
		// 끊긴게 있는지 확인
		for (int i=1; i&amp;lt;=N; i++) {
			if (!visited[i]) return;
		}
		ans = Math.min(ans,  Math.abs(cntA-cntB));
	}
	
	/**
	 * BFS
	 */
	static int bfs(List&amp;lt;Integer&amp;gt; list, boolean flag) {
		int cnt = 0;
		int start = list.get(0);
		queue.offer(start);
		visited[start] = true;
		
		while (!queue.isEmpty()) {
			int now = queue.poll();
			cnt += people[now];
			for (int i=1; i&amp;lt;=N; i++) {
				if (matrix[now][i] == 1 &amp;amp;&amp;amp; !visited[i] &amp;amp;&amp;amp; isSelected[i] == flag) {
					queue.offer(i);
					visited[i] = true;
				}
			}
		}
		return cnt;
	}
	
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;사담&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이전 제출 참고해서 다시 풀어봤다. 취업하고 적응한다고 문제를 많이 못(안)풀었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아무리 생각해도 게리맨더링이 제일 재밌는 것 같다..&lt;/p&gt;</description>
      <author>suuunnnn</author>
      <guid isPermaLink="true">https://k-ang.tistory.com/181</guid>
      <comments>https://k-ang.tistory.com/181#entry181comment</comments>
      <pubDate>Sun, 25 May 2025 21:16:22 +0900</pubDate>
    </item>
    <item>
      <title>[Algorithm] 프로그래머스 - 베스트 앨범.java</title>
      <link>https://k-ang.tistory.com/179</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 문제&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/42579&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/42579&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1718549998335&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;프로그래머스&quot; data-og-description=&quot;코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.&quot; data-og-host=&quot;programmers.co.kr&quot; data-og-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/42579&quot; data-og-url=&quot;https://programmers.co.kr/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dh0KTI/hyWoNPyyje/arMwlJ9rYlC9ZTw2Wgrpwk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/GFbUy/hyWle2npyw/kmhpOVZH3fcuBR7Txi4Lq0/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/42579&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/42579&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dh0KTI/hyWoNPyyje/arMwlJ9rYlC9ZTw2Wgrpwk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/GFbUy/hyWle2npyw/kmhpOVZH3fcuBR7Txi4Lq0/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;프로그래머스&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;programmers.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 풀이&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 장르 재생횟수 많은 순서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 노래 재생횟수 많은 순서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 고유번호 작은 순서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;map 2개를 두고&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 노래 정보 map (해시맵의 해시맵)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 재생횟수 map&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;장르의 key값만 뽑은 리스트를 정렬할 때, 정렬 조건에 장르 재생횟수가 많은 순 조건 추가&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;노래의 key값만 뽑은 리스트를 정렬할 때, 정렬 조건에 노래 재생횟수가 많은 순 조건 추가&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;answer 리스트에 개수 되는대로 add (단, 2개까지)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;유의할 점은&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;List&amp;lt;Integer&amp;gt;를 int[] 로 맵핑하는 방법인데,&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;stream과 mapToInt를 사용하였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. mapToInt 원리&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 해시맵에서 value가 map 형태면 put했을 때 이미 key가 있어도 value 업데이트가 아니라 중복되는 key에 새로운 value가 추가되는건가? value 안의 key도 체크하는건가?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1718549984580&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.util.*;
import java.io.*;

class Solution {
    public int[] solution(String[] genres, int[] plays) {
        List&amp;lt;Integer&amp;gt; answer = new ArrayList&amp;lt;&amp;gt; ();
		Map&amp;lt;String, Integer&amp;gt; countMap = new HashMap&amp;lt;&amp;gt; ();
		Map&amp;lt;String, Map&amp;lt;Integer, Integer&amp;gt;&amp;gt; musicMap = new HashMap &amp;lt;&amp;gt; ();
		
		for (int i=0; i&amp;lt;genres.length; i++) {
			if (countMap.containsKey(genres[i])) {
				countMap.put(genres[i], countMap.get(genres[i]) + plays[i]);
				musicMap.get(genres[i]).put(i, plays[i]);
			}
			else {
				Map&amp;lt;Integer, Integer&amp;gt; map = new HashMap&amp;lt;&amp;gt; ();
				map.put(i, plays[i]);
				countMap.put(genres[i], plays[i]);
				musicMap.put(genres[i], map);
			}
		}
		List&amp;lt;String&amp;gt; genreList = new ArrayList&amp;lt;&amp;gt; (countMap.keySet());
		Collections.sort(genreList, (s1, s2) -&amp;gt; countMap.get(s2) - countMap.get(s1));
		for (String genre : genreList) {
			Map&amp;lt;Integer, Integer&amp;gt; music = (HashMap&amp;lt;Integer, Integer&amp;gt;) musicMap.get(genre);
			List&amp;lt;Integer&amp;gt; musicList = new ArrayList&amp;lt;&amp;gt; (music.keySet());
			Collections.sort(musicList, (s1, s2) -&amp;gt; music.get(s2) - music.get(s1));
			
			answer.add(musicList.get(0));
			if (musicList.size() &amp;gt; 1) {
				answer.add(musicList.get(1));
			}
		}
		
		return answer.stream()
				.mapToInt(i-&amp;gt;i)
				.toArray();
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4. 사담&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Algorithm</category>
      <author>suuunnnn</author>
      <guid isPermaLink="true">https://k-ang.tistory.com/179</guid>
      <comments>https://k-ang.tistory.com/179#entry179comment</comments>
      <pubDate>Mon, 17 Jun 2024 00:07:03 +0900</pubDate>
    </item>
    <item>
      <title>[집피지기] 2. JPA 설정하기</title>
      <link>https://k-ang.tistory.com/174</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. JPA 설정&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JPA를 설정하기 위한 필수 절차는 아래와 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. build.gradle에 dependency를 추가한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;533&quot; data-origin-height=&quot;45&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cFGnNL/btsCCxNSaPu/AM6cuzg2oDxZ6M4NTbCbwK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cFGnNL/btsCCxNSaPu/AM6cuzg2oDxZ6M4NTbCbwK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cFGnNL/btsCCxNSaPu/AM6cuzg2oDxZ6M4NTbCbwK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcFGnNL%2FbtsCCxNSaPu%2FAM6cuzg2oDxZ6M4NTbCbwK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;533&quot; height=&quot;45&quot; data-origin-width=&quot;533&quot; data-origin-height=&quot;45&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. application.yml에서 설정을 해준다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;161&quot; data-origin-height=&quot;102&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ulS3Z/btsCBLrSWpm/iJKX13MNStBVMzGSDzetH1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ulS3Z/btsCBLrSWpm/iJKX13MNStBVMzGSDzetH1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ulS3Z/btsCBLrSWpm/iJKX13MNStBVMzGSDzetH1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FulS3Z%2FbtsCBLrSWpm%2FiJKX13MNStBVMzGSDzetH1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;161&quot; height=&quot;102&quot; data-origin-width=&quot;161&quot; data-origin-height=&quot;102&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- ddl-auto는 상용에서는 절대 create로 하면 안됨. none으로 설정 후 사용하자.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;spring-boot-starter-data-jpa에는 jakarta.persistence가 포함되어 있다.&lt;br /&gt;(이전에는 javax.persistence였으나, 회사명이 바뀌면서 jakarta.persistence가 되었다.)&lt;br /&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;510&quot; data-origin-height=&quot;225&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cSEzHn/btsCBMqKzDb/Ob1pCf0QvikBkRDGmQGN00/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cSEzHn/btsCBMqKzDb/Ob1pCf0QvikBkRDGmQGN00/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cSEzHn/btsCBMqKzDb/Ob1pCf0QvikBkRDGmQGN00/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcSEzHn%2FbtsCBMqKzDb%2FOb1pCf0QvikBkRDGmQGN00%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;451&quot; height=&quot;199&quot; data-origin-width=&quot;510&quot; data-origin-height=&quot;225&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/blockquote&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;</description>
      <category>프로젝트/집피지기</category>
      <author>suuunnnn</author>
      <guid isPermaLink="true">https://k-ang.tistory.com/174</guid>
      <comments>https://k-ang.tistory.com/174#entry174comment</comments>
      <pubDate>Wed, 27 Dec 2023 06:41:58 +0900</pubDate>
    </item>
    <item>
      <title>[집피지기] 1. GitHub 레포지토리 생성</title>
      <link>https://k-ang.tistory.com/173</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;공부만이 살 길이다 ..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해야한다&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;규연언니... 혜지언니... 예인...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가보자고...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/Zippizigi/zippizigi&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://github.com/Zippizigi/zippizigi&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1703622667232&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - Zippizigi/zippizigi:  &amp;zwj;  우리집 지키는 똑똑한 지피지기&quot; data-og-description=&quot; &amp;zwj;  우리집 지키는 똑똑한 지피지기. Contribute to Zippizigi/zippizigi development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/Zippizigi/zippizigi&quot; data-og-url=&quot;https://github.com/Zippizigi/zippizigi&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bYxB7M/hyUTJuYs14/mPGItuMD7rBYKFg1z0z6i0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/Zippizigi/zippizigi&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/Zippizigi/zippizigi&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bYxB7M/hyUTJuYs14/mPGItuMD7rBYKFg1z0z6i0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - Zippizigi/zippizigi:  &amp;zwj;  우리집 지키는 똑똑한 지피지기&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt; &amp;zwj;  우리집 지키는 똑똑한 지피지기. Contribute to Zippizigi/zippizigi development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>프로젝트/집피지기</category>
      <author>suuunnnn</author>
      <guid isPermaLink="true">https://k-ang.tistory.com/173</guid>
      <comments>https://k-ang.tistory.com/173#entry173comment</comments>
      <pubDate>Wed, 27 Dec 2023 05:33:53 +0900</pubDate>
    </item>
    <item>
      <title>[Javascript] 비동기 API 호출 (async/await, fetch)</title>
      <link>https://k-ang.tistory.com/172</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;예시 코드&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. index.html&lt;/p&gt;
&lt;pre id=&quot;code_1702820154785&quot; class=&quot;html xml&quot; data-ke-language=&quot;html&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;meta charset=&quot;utf-8&quot; /&amp;gt;
    &amp;lt;script src=&quot;./main.js&quot; type=&quot;text/javascript&quot;&amp;gt;&amp;lt;/script&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;div class=&quot;container&quot;&amp;gt;
      &amp;lt;h4 class=&quot;text-center&quot;&amp;gt;게시판 - Main&amp;lt;/h4&amp;gt;

      &amp;lt;div class=&quot;input-group mb-3&quot;&amp;gt;

      &amp;lt;table class=&quot;table table-hover&quot;&amp;gt;
        &amp;lt;thead&amp;gt;
          &amp;lt;tr&amp;gt;
            &amp;lt;th&amp;gt;#&amp;lt;/th&amp;gt;
            &amp;lt;th&amp;gt;제목&amp;lt;/th&amp;gt;
            &amp;lt;th&amp;gt;작성자&amp;lt;/th&amp;gt;
            &amp;lt;th&amp;gt;작성일시&amp;lt;/th&amp;gt;
            &amp;lt;th&amp;gt;조회수&amp;lt;/th&amp;gt;
          &amp;lt;/tr&amp;gt;
        &amp;lt;/thead&amp;gt;
        &amp;lt;tbody&amp;gt;
          &amp;lt;tr&amp;gt;
            &amp;lt;td&amp;gt;{{ board.boardId }}&amp;lt;/td&amp;gt;
            &amp;lt;td&amp;gt;{{ board.title }}&amp;lt;/td&amp;gt;
            &amp;lt;td&amp;gt;{{ board.userName }}&amp;lt;/td&amp;gt;
            &amp;lt;td&amp;gt;{{ board.regDt.date | makeDateStr(&quot;.&quot;) }}&amp;lt;/td&amp;gt;
            &amp;lt;td&amp;gt;{{ board.readCount }}&amp;lt;/td&amp;gt;
          &amp;lt;/tr&amp;gt;
        &amp;lt;/tbody&amp;gt;
      &amp;lt;/table&amp;gt;
      &amp;lt;div style=&quot;color: red;&quot; class=&quot;btn btn-sm btn-primary&quot;&amp;gt;
        &amp;lt;a href='javascript:void(0);' onclick=&quot;test();&quot;&amp;gt;test&amp;lt;/a&amp;gt;
        &amp;lt;a href=&quot;javascript:getHello();&quot;&amp;gt;글쓰기&amp;lt;/a&amp;gt;
        &amp;lt;a href=&quot;javascript:getHello2();&quot;&amp;gt;HelloPOST&amp;lt;/a&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. main.js&lt;/p&gt;
&lt;pre id=&quot;code_1702820166553&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function init() {
  console.log(&quot;===init===&quot;);
}
init();

async function test() {
  console.log(&quot;===test===&quot;);
}

function getData(url) {
  return fetch(url).then(function (data) {
    return data.json();
  });
}

async function getHello() {
  const url = &quot;http://localhost:8080/hello&quot;;
  const result = await getData(url);
  console.log(result);
  document.write(result.name);
  console.log(result.name);
  return result;
}

// JSON.stringify() : JSON객체로 직렬화 (js객체 =&amp;gt; JSON)
// JSON.parse() : Javascript 객체로 역직렬화 (JSON =&amp;gt; js객체)
async function getHello2() {
  param = {
    test: &quot;[test param]&quot;,
  };
  const url = &quot;http://localhost:8080/hello2&quot;;
  fetch(url, {
    method: &quot;POST&quot;,
    headers: {
      &quot;Content-Type&quot;: &quot;application/json&quot;,
    },
    // body: JSON.stringify({
    //   test: &quot;[test param]&quot;,
    // }),
    body: JSON.stringify(param),
  })
    // 첫 번째 then: 아직 body도착 전, promise 객체
    // 비동기로 처리된 fetch 함수의 결과 값이 들어오면 then 메소드의 액션을 실행한다.
    // fetch함수는 서버에서 전달받은 Promise 객체를 리턴, 리턴된 객체를 then메소드에서 인자로 받는다. =&amp;gt; 헤더는 도착, 바디는 도착 전
    // .json()은 Promise 객체를 리턴한다.
    // Promise 작동방식: fetch 후 날아오는 response객체는 일단 header먼저 도착함. 모든 header 도착하자마자 return됨
    // 아직 body가 안 온 상태인 Promise객체를 바로 반환하는 것임.
    // 중간에 기다렸다가 body까지 다 온 Promise객체를 리턴하고 싶지만 그건 불가능함.
    // 때문에 .then으로 chaining(체이닝)해서 실행해야 한다.
    .then((result) =&amp;gt; {
      return result.json();
    })
    .then((result) =&amp;gt; {
      console.log(result);
      document.write(result.name);
      console.log(result.name);
    })
    .catch((error) =&amp;gt; {
      console.log(error);
      alert(&quot;error가 발생하였습니다.&quot;);
    });
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;HTTP 메소드에 따른 API 호출&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;- GET&lt;/b&gt;&lt;/h4&gt;
&lt;pre id=&quot;code_1702820216542&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;async function getHello() {
  const url = &quot;http://localhost:8080/hello&quot;;
  const result = await getData(url);
  console.log(result.name);
  return result;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;- POST&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Promise 객체 체이닝X&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1702820960529&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;/**
 * Promise 체이닝X
 */
async function getHello3() {
  param = {
    test: &quot;[test param]&quot;,
  };
  const url = &quot;http://localhost:8080/hello2&quot;;
  const res = await fetch(url, {
    method: &quot;POST&quot;,
    headers: {
      &quot;Content-Type&quot;: &quot;application/json&quot;,
    },
    body: JSON.stringify(param),
  });

  const result = await res.json();

  console.log(result.name);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Promise 객체 체이닝O&lt;/b&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1702820257232&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;async function getHello2() {
  param = {
    test: &quot;[test param]&quot;,
  };
  
  const url = &quot;http://localhost:8080/hello2&quot;;
  fetch(url, {
    method: &quot;POST&quot;,
    headers: {
      &quot;Content-Type&quot;: &quot;application/json&quot;,
    },
    body: JSON.stringify(param),
  })
    .then((result) =&amp;gt; {
      return result.json(); //여기서 Promise 객체가 나옴
    })
    .then((result) =&amp;gt; {
      console.log(result.name);
    })
    .catch((error) =&amp;gt; {
      console.log(error);
      alert(&quot;error가 발생하였습니다.&quot;);
    });
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. then을 2번 쓰는 이유&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;Promise의 작동 방식&lt;/b&gt;&lt;/span&gt; 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- .json을 해도 json객체가 아닌 Promise객체가 리턴된다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* 비동기로 처리된 fetch()는 결과 값을 받으면 then메소드의 액션을 실행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;* fetch()를 하면 서버로부터 전달받은 response 객체를 리턴한다. 리턴된 객체는 then메소드의 인자로 받는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 서버로부터 response 객체를 받을 때, 모든 header가 도착하면 바로 return한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp; &amp;nbsp;=&amp;gt; &lt;b&gt;아직 body가 오지 않은 상태, body를 기다리고 있는 상태&lt;/b&gt;인&lt;b&gt; Promise 객체&lt;/b&gt;를 리턴하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 중간에 기다려서 body까지 도착한 Promise 객체를 리턴하는 것은 불가능하다. 애초에 header가 도착하자마자 바로 리턴해버리기 때문에, &lt;b&gt;.then으로 chaining(체이닝)&lt;/b&gt; 하여 body값을 받아야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;Promise 객체란?&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #666666; text-align: left;&quot;&gt;- 비동기 함수 호출이 완료됐을 때 처리하기 위한 함수를 설정하는 모듈&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #666666; text-align: left;&quot;&gt;- 비동기 연산의 결과를 나타내는 객체&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #666666; text-align: left;&quot;&gt;- 사용이유 : 기존의 콜백함수 사용 시 콜백지옥 발생, 가독성 떨어지고 유지보수성 낮았음.&lt;/span&gt; &lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;Promise Chaining (여러 Promise 연결)이란?&lt;/b&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #666666; text-align: left;&quot;&gt;- .then을 나열하여 제어하는 방식.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #666666; text-align: left;&quot;&gt;- then에서 return해주고 다음 then에서 이를 받아 사용하는 방식.&lt;/span&gt; &lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. Javascript 객체와 JSON 객체&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- JSON.stringify() : Javascript =&amp;gt; JSON 객체로 직렬화&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- JSON.parse() : JSON =&amp;gt; Javascipt 객체로 직렬화&lt;/p&gt;</description>
      <category>Web/Javascript</category>
      <author>suuunnnn</author>
      <guid isPermaLink="true">https://k-ang.tistory.com/172</guid>
      <comments>https://k-ang.tistory.com/172#entry172comment</comments>
      <pubDate>Sun, 17 Dec 2023 23:00:22 +0900</pubDate>
    </item>
    <item>
      <title>[Javascript] 변수, 연산자, 조건문, 반복문, 함수, 배열</title>
      <link>https://k-ang.tistory.com/171</link>
      <description>&lt;pre id=&quot;code_1702819981367&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&quot;en&quot;&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;meta charset=&quot;UTF-8&quot; /&amp;gt;
    &amp;lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot; /&amp;gt;
    &amp;lt;title&amp;gt;Document&amp;lt;/title&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;script&amp;gt;
      // 1
      // var로 선언한 변수는 정수든, 문자든 다 자유자재로 바꿀 수 있다.
      var a = 1;
      a = &quot;test&quot;;
      console.log(a + 1);

      //2
      // ==: 동등연산자, ===: 일치연산자
      // ==: 값(의미) 비교, ===: 값(의미) &amp;amp; 데이터타입 비교
      console.log(1 == 1); //true
      console.log(1 == &quot;1&quot;); //true
      console.log(1 === &quot;1&quot;); //false

      console.log(undefined == null); //true
      console.log(undefined === null); //false

      console.log(1 == true); //true
      console.log(1 === true); //false

      //3
      // ==: 의미 비교, ===: 의미, 타입 비교
      console.log(1 != &quot;1&quot;); //false
      console.log(1 !== &quot;1&quot;); //true

      //4
      // 조건문
      if (true) {
        console.log(&quot;result is true&quot;);
      }
      if (false) {
        var age = prompt(&quot;나이를 입력해주세요.&quot;);
        if (age === &quot;25&quot;) {
          alert(&quot;25 good bye!&quot;);
        }

        var id = prompt(&quot;id를 입력해주세요.&quot;);
        if (id == &quot;sunakang&quot;) {
          var pw = prompt(&quot;pw를 입력해주세요.&quot;);
          if (pw == &quot;sunakang&quot;) {
            alert(&quot;Hello, &quot; + id);
          } else {
            alert(&quot;비밀번호를 다시 입력해주세요.&quot;);
          }
        } else {
          alert(&quot;누구세요?&quot;);
        }
      }

      //5
      // 반복문
      while (false) {
        console.log(&quot;hi&quot;);
      }

      //6
      // 함수
      /**
       * 1. 재사용성
       * 2. 유지보수 용이
       * 3. 가독성
       **/
      function numbering() {
        var i = 0;
        while (i &amp;lt; 5) {
          document.write(i + &quot;&amp;lt;br/&amp;gt;&quot;);
          i++;
        }
      }
      //numbering();

      // 출력 - return
      function get_member() {
        return &quot;suna&quot;; //출력되고 끝
        return &quot;sun&quot;;
        return &quot;sunakang&quot;;
      }
      console.log(get_member());

      // 입력
      // - 전달하는 값 = 인자(argument)
      // - 전달받는 변수 = 매개변수, 파라미터(parameter)
      // value: 매개변수(parameter)
      function get_argument(value) {
        return value * 2;
      }
      // 100: 인자(argument)
      console.log(get_argument(100));

      // 함수 형태2
      var write_function = function write_function() {
        return &quot;fuction&amp;lt;br/&amp;gt;&quot;;
      };
      console.log(write_function);

      // 함수 형태3 - 익명함수, 정의와 호출을 동시에 함
      (function () {
        console.log(&quot;suna&quot;);
      })();

      //7
      // 배열
      var member = [&quot;kang&quot;, 1, &quot;suna&quot;];
      console.log(member[0] + &quot; &amp;amp; &quot; + member[1]);

      function get_member2() {
        return [&quot;1&quot;, 2, 3.3];
      }
      var member2 = get_member2();
      console.log(member2[0] + &quot; &amp;amp; &quot; + member2[1] + &quot; &amp;amp; &quot; + member2[2]);

      var member3 = [&quot;kang&quot;, &quot;suna&quot;, &quot;test&quot;];
      for (var i = 0; i &amp;lt; member3.length - 1; i++) {
        console.log(member3[i].toUpperCase() + &quot;&amp;lt;br/&amp;gt;&quot;);
      }

      var list = [1, 2, 3];
      // push: 꼬리에 추가
      list.push(4);
      console.log(list);
      // unshift: 머리에 추가
      list.unshift(0);
      console.log(list);
      // concat: 인자로 전달하여 꼬리에 추가
      list = list.concat(5);
      console.log(list);
      // splice: 0부터 2까지를 -1로 변경
      list.splice(0, 3, -1);
      console.log(list);
    &amp;lt;/script&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Web/Javascript</category>
      <author>suuunnnn</author>
      <guid isPermaLink="true">https://k-ang.tistory.com/171</guid>
      <comments>https://k-ang.tistory.com/171#entry171comment</comments>
      <pubDate>Sun, 17 Dec 2023 22:33:07 +0900</pubDate>
    </item>
    <item>
      <title>[SpringBoot] devtools란?</title>
      <link>https://k-ang.tistory.com/170</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;SpringBoot DevTools&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- SpringBoot에서 제공하는 개발 편의를 위한 모듈이다. spring-boot-devtools 의존성을 추가하여 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 브라우저로 전송되는 내용들에 대한 코드가 변경되면, 자동으로 애플리케이션을 재시작하여 브라우저에도 업데이트를 해주는 역할을 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 개발을 하다보면, &lt;b&gt;브라우저에 보여주는 내용(문구 등)도 수정하면 애플리케이션을 재시작해야한다.&lt;/b&gt; 때문에 devtools를 사용하면 &lt;b&gt;브라우저에 보여주는 내용&lt;/b&gt;은 &lt;u&gt;&lt;b&gt;수정 시 자동으로 재시작해주어 브라우저에 업데이트&lt;/b&gt; &lt;/u&gt;해주는 역할을 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;제공하는 기능&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;SpringBoot DevTools가 제공하는 기능은 크게 5가지이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- Property Defaults&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- Automatic Restart&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;- Live Reload&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Global Settings&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Remote Applications&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;5가지 중 상위 3가지 기능이 주로 쓰인다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. Property Defaults&lt;/b&gt; (개발 시점/배포 시점에 기본적으로 개발 단계에 맞춰 설정해준다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- Spring에서 제공하는 thymeleaf는 기본적으로 캐싱 기능을 제공한다. 때문에 타임리프 파일을 수정하여도 반영되지 않는다. &lt;b&gt;타임리프의 캐싱 기능을 해제&lt;/b&gt;하기 위해서는 application.yml에서 spring.tymeleaf.cache 를 false로 수정해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 devtools를 사용하면 이러한 작업을 제공한다. 즉, 템플릿 엔진의 캐싱 기능을 자동으로 꺼주는 역할을 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. Automatic Restart&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 파일 수정 후 저장을 하면, Classpath에 존재하는 해당 &lt;b&gt;파일의 변경을 감지하고 자동으로 서버를 restart&lt;/b&gt; 해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 클래스경로에서 파일 변경이 일어날 때마다 애플리케이션을 다시 시작하게 되어 main스레드가 아니라 restartedMain 스레드로 기동된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;devtools 반영 전 쓰레드 : main쓰레드&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;641&quot; data-origin-height=&quot;112&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/6K4xz/btsB3a0IW1I/spDRpmsma9ooES4SdzU7Ik/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/6K4xz/btsB3a0IW1I/spDRpmsma9ooES4SdzU7Ik/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/6K4xz/btsB3a0IW1I/spDRpmsma9ooES4SdzU7Ik/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F6K4xz%2FbtsB3a0IW1I%2FspDRpmsma9ooES4SdzU7Ik%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;446&quot; height=&quot;78&quot; data-origin-width=&quot;641&quot; data-origin-height=&quot;112&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;devtools 반영 후 쓰레드 : restart main 쓰레드&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;763&quot; data-origin-height=&quot;99&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/8QIPM/btsB5zex2e8/wcs44tEkL8kBQ3S3P1vYZ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/8QIPM/btsB5zex2e8/wcs44tEkL8kBQ3S3P1vYZ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/8QIPM/btsB5zex2e8/wcs44tEkL8kBQ3S3P1vYZ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F8QIPM%2FbtsB5zex2e8%2Fwcs44tEkL8kBQ3S3P1vYZ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;509&quot; height=&quot;66&quot; data-origin-width=&quot;763&quot; data-origin-height=&quot;99&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;3. Live Reload&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 별도의 확장 프로그램 설치 없이, VSCode의 live reload 처럼 수정하면 &lt;b&gt;브라우저에서 자동으로 업데이트&lt;/b&gt; 되는 모습을 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;설정 방법&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. Gradle에 의존성을 추가한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;489&quot; data-origin-height=&quot;24&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cs3trh/btsB8VU1Ybi/JVmTKo0zSM6FYWhqhxnx31/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cs3trh/btsB8VU1Ybi/JVmTKo0zSM6FYWhqhxnx31/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cs3trh/btsB8VU1Ybi/JVmTKo0zSM6FYWhqhxnx31/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcs3trh%2FbtsB8VU1Ybi%2FJVmTKo0zSM6FYWhqhxnx31%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;489&quot; height=&quot;24&quot; data-origin-width=&quot;489&quot; data-origin-height=&quot;24&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;div style=&quot;background-color: #282c34; color: #abb2bf;&quot;&gt;
&lt;pre class=&quot;nginx&quot;&gt;&lt;code&gt;developmentOnly 'org.springframework.boot:spring-boot-devtools'&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 소스코드 변경 시 자동으로 반영되기 위한 설정&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2-1. Settings &amp;gt; Advanced Settings &amp;gt; Allow autho-make to start~ 체크&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;909&quot; data-origin-height=&quot;709&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dgx250/btsB6hEG7oa/mNE8NTVKUD8Y8Mth6Mv501/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dgx250/btsB6hEG7oa/mNE8NTVKUD8Y8Mth6Mv501/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dgx250/btsB6hEG7oa/mNE8NTVKUD8Y8Mth6Mv501/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdgx250%2FbtsB6hEG7oa%2FmNE8NTVKUD8Y8Mth6Mv501%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;611&quot; height=&quot;477&quot; data-origin-width=&quot;909&quot; data-origin-height=&quot;709&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2-2. Settings &amp;gt; Compiler &amp;gt; Build project automatically 체크&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;912&quot; data-origin-height=&quot;711&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/0CT0l/btsB7lNrdJo/1RKsu5qlpMXPtA8tIwe3dK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/0CT0l/btsB7lNrdJo/1RKsu5qlpMXPtA8tIwe3dK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/0CT0l/btsB7lNrdJo/1RKsu5qlpMXPtA8tIwe3dK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F0CT0l%2FbtsB7lNrdJo%2F1RKsu5qlpMXPtA8tIwe3dK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;614&quot; height=&quot;479&quot; data-origin-width=&quot;912&quot; data-origin-height=&quot;711&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;결론&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한 마디로 &quot;소스코드 자동 반영&quot;을 위해 DevTools를 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. 타임리프 캐싱 기능을 개발 시점에서 해제해주고 live reload 기능으로 &lt;b&gt;코드를 수정하면 자동으로 반영됨.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 파일 수정하면 이를 감지하고 &lt;b&gt;서버를 자동으로 restart하여 반영함.&lt;/b&gt;&lt;/p&gt;</description>
      <category>Web/SpringBoot</category>
      <author>suuunnnn</author>
      <guid isPermaLink="true">https://k-ang.tistory.com/170</guid>
      <comments>https://k-ang.tistory.com/170#entry170comment</comments>
      <pubDate>Sun, 17 Dec 2023 17:57:35 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스] 요격시스템 - Java</title>
      <link>https://k-ang.tistory.com/169</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181188&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://school.programmers.co.kr/learn/courses/30/lessons/181188&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1701728695937&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;프로그래머스&quot; data-og-description=&quot;코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.&quot; data-og-host=&quot;programmers.co.kr&quot; data-og-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181188&quot; data-og-url=&quot;https://programmers.co.kr/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/ezO77/hyUIszLwGb/K8xUFU1nRsPBVpKTA61cqk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/gc9oL/hyUIrnkgzS/TrBMWBffYqLn2W4YWTp071/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181188&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/181188&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/ezO77/hyUIszLwGb/K8xUFU1nRsPBVpKTA61cqk/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630,https://scrap.kakaocdn.net/dn/gc9oL/hyUIrnkgzS/TrBMWBffYqLn2W4YWTp071/img.png?width=1200&amp;amp;height=630&amp;amp;face=0_0_1200_630');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;프로그래머스&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;programmers.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. 문제&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;폭격 미사일 정수 쌍(s, e) 가 배열로 주어진다. 이에 맞서 요격 미사일을 발사하려고 할 때, 필요한 요격 미사일 개수의 최솟값을 구하는 문제이다. 여기서 s, e는 시작 x좌표 s, 끝 x좌표 e를 의미한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;766&quot; data-origin-height=&quot;354&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bbEoeG/btsBo6Dy4Am/DL94ql9rmN9xAatoEGhk0k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bbEoeG/btsBo6Dy4Am/DL94ql9rmN9xAatoEGhk0k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bbEoeG/btsBo6Dy4Am/DL94ql9rmN9xAatoEGhk0k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbbEoeG%2FbtsBo6Dy4Am%2FDL94ql9rmN9xAatoEGhk0k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;424&quot; height=&quot;354&quot; data-origin-width=&quot;766&quot; data-origin-height=&quot;354&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. 풀이&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리디 문제이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;모든 target을 e 기준 오름차순으로 정렬한 후 그리디로 처리한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;target을 하나하나 보면서&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. targets를 e를 기준으로 오름차순 정렬&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 1부터 차례대로 볼 때, 시작점보다 작거나 같을 경우 ans++해주고 해당 폭격 미사일의 끝점으로 이동한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;571&quot; data-origin-height=&quot;146&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bf0wDD/btsBrfmfd6j/s49ea0nBUzqOZdgKQgcPmk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bf0wDD/btsBrfmfd6j/s49ea0nBUzqOZdgKQgcPmk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bf0wDD/btsBrfmfd6j/s49ea0nBUzqOZdgKQgcPmk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbf0wDD%2FbtsBrfmfd6j%2Fs49ea0nBUzqOZdgKQgcPmk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;391&quot; height=&quot;100&quot; data-origin-width=&quot;571&quot; data-origin-height=&quot;146&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시간복잡도는 Arrays.sort()를 사용하여 최악의 경우 N(50만 log 50만) + for문 O(50만)이 될 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. 코드&lt;/h3&gt;
&lt;pre id=&quot;code_1701728733587&quot; class=&quot;java&quot; data-ke-language=&quot;java&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;import java.util.*;
import java.io.*;

class Solution {
    public int solution(int[][] targets) {
        // e 오름차순 정렬
        Arrays.sort(targets, (o1, o2) -&amp;gt; o1[1] - o2[1]);
        
        int ans = 0;
        int x = 0;
        for (int[] target : targets) {
            if (x &amp;lt;= target[0]) {
                x = target[1];
                ans++;
            }
        }
        
        return ans;
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4. 사담&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;재밌었다. 잘못된게 있다면 언제든 피드백 부탁드립니다.&lt;/p&gt;</description>
      <category>Algorithm/Programmers</category>
      <author>suuunnnn</author>
      <guid isPermaLink="true">https://k-ang.tistory.com/169</guid>
      <comments>https://k-ang.tistory.com/169#entry169comment</comments>
      <pubDate>Tue, 5 Dec 2023 07:35:14 +0900</pubDate>
    </item>
    <item>
      <title>[Spring Batch] 2. 스프링 배치로 Hello,World 실행하기 예제 (tasklet 사용)</title>
      <link>https://k-ang.tistory.com/167</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;스프링 배치는 설명만 읽고서는 이해하기 어려웠다. 코드로 직접 만들어보는 것이 이해하기 쉬울 것 같아 한 번 만들어보았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1. build.gradle에 MySQL dependency 추가&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2. 데이터베이스 생성을 위한 docker-compose.yml 파일 생성&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 프로젝트의 최상단 위치에 생성&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3. 설정을 위한 application.yml 파일 작성&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4. docker 명령어를 통해 데이터베이스 구동&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;docker-compose up -d&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1️⃣차 시도&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1857&quot; data-origin-height=&quot;63&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oauk0/btsATYlxlvA/duhAWM08kJE0ufYMBcqdYK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oauk0/btsATYlxlvA/duhAWM08kJE0ufYMBcqdYK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oauk0/btsATYlxlvA/duhAWM08kJE0ufYMBcqdYK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Foauk0%2FbtsATYlxlvA%2FduhAWM08kJE0ufYMBcqdYK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1857&quot; height=&quot;63&quot; data-origin-width=&quot;1857&quot; data-origin-height=&quot;63&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;했더니 위와 같은 에러 발생.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3306 포트가 충돌한 것, 아마 workbench를 켜두고 있어서 발생한 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;netstat -aon&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;으로 확인해보니 3306 포트가 사용 중이었다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;663&quot; data-origin-height=&quot;212&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cDdMNa/btsAVsNhXru/7D9rcKOdcfwL8A0Pr43YcK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cDdMNa/btsAVsNhXru/7D9rcKOdcfwL8A0Pr43YcK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cDdMNa/btsAVsNhXru/7D9rcKOdcfwL8A0Pr43YcK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcDdMNa%2FbtsAVsNhXru%2F7D9rcKOdcfwL8A0Pr43YcK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;663&quot; height=&quot;212&quot; data-origin-width=&quot;663&quot; data-origin-height=&quot;212&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;taskkill /f /pid 5952 &lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;했더니 엑세스가 거부되었다며 프로세스 종료가 되지 않았다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;387&quot; data-origin-height=&quot;58&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kW5Lc/btsATjwNLua/m0XPUaoYwI563TOLTxAFEK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kW5Lc/btsATjwNLua/m0XPUaoYwI563TOLTxAFEK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kW5Lc/btsATjwNLua/m0XPUaoYwI563TOLTxAFEK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkW5Lc%2FbtsATjwNLua%2Fm0XPUaoYwI563TOLTxAFEK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;387&quot; height=&quot;58&quot; data-origin-width=&quot;387&quot; data-origin-height=&quot;58&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해결 방법은 cmd를 관리자 권한으로 열어 똑같이 taskkill 해주는 것이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;359&quot; data-origin-height=&quot;46&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5Ho5N/btsASoyK2cv/xH75pDs04wE9I3QHrx1im0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5Ho5N/btsASoyK2cv/xH75pDs04wE9I3QHrx1im0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5Ho5N/btsASoyK2cv/xH75pDs04wE9I3QHrx1im0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5Ho5N%2FbtsASoyK2cv%2FxH75pDs04wE9I3QHrx1im0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;359&quot; height=&quot;46&quot; data-origin-width=&quot;359&quot; data-origin-height=&quot;46&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다시 도커로 DB를 구동해보니 컨테이너가 올라갔다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;632&quot; data-origin-height=&quot;90&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bByqxc/btsAYEzONLq/UgIqdpKwe8GGlxKNmFud30/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bByqxc/btsAYEzONLq/UgIqdpKwe8GGlxKNmFud30/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bByqxc/btsAYEzONLq/UgIqdpKwe8GGlxKNmFud30/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbByqxc%2FbtsAYEzONLq%2FUgIqdpKwe8GGlxKNmFud30%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;632&quot; height=&quot;90&quot; data-origin-width=&quot;632&quot; data-origin-height=&quot;90&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2️⃣차 시도&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 새로운 에러가 발생 ..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light'; color: #666666; text-align: start;&quot;&gt;com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Light'; color: #666666; text-align: start;&quot;&gt;해결방법은 아래와 같다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;503&quot; data-origin-height=&quot;190&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dU3uZs/btsAUJ2KMIG/8pdkpapijwksefA6JyF8e1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dU3uZs/btsAUJ2KMIG/8pdkpapijwksefA6JyF8e1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dU3uZs/btsAUJ2KMIG/8pdkpapijwksefA6JyF8e1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdU3uZs%2FbtsAUJ2KMIG%2F8pdkpapijwksefA6JyF8e1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;315&quot; height=&quot;119&quot; data-origin-width=&quot;503&quot; data-origin-height=&quot;190&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;에서 MYSQL 80 을 시작해주면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3️⃣차 시도&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또 새로운 에러 발생..&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;894&quot; data-origin-height=&quot;59&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/clzkZi/btsAYFFwBQZ/aUbEmlMA5S0EvfLkWuKHxk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/clzkZi/btsAYFFwBQZ/aUbEmlMA5S0EvfLkWuKHxk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/clzkZi/btsAYFFwBQZ/aUbEmlMA5S0EvfLkWuKHxk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FclzkZi%2FbtsAYFFwBQZ%2FaUbEmlMA5S0EvfLkWuKHxk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;558&quot; height=&quot;37&quot; data-origin-width=&quot;894&quot; data-origin-height=&quot;59&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 에러의 원인은 useSSL=false로 지정해놓고 allowPublicKeyRetrieval을 지정해주지 않아 발생한 에러다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;useSSL=false를 과감하게 지워줬더니 모든 에러가 사라지고 말끔하게 시작이 잘 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4️⃣차 시도&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;되는가 했지만 알고보니 DB가 올라와있지 않았다. 해당 에러는 이미 존재하는 계정이라 create 할 수 없다고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;root계정말고 test 계정으로 설정해주었다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1120&quot; data-origin-height=&quot;192&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/VJrg3/btsAYE7GluG/wZAi6sga3724RxRbbRrFa1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/VJrg3/btsAYE7GluG/wZAi6sga3724RxRbbRrFa1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/VJrg3/btsAYE7GluG/wZAi6sga3724RxRbbRrFa1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FVJrg3%2FbtsAYE7GluG%2FwZAi6sga3724RxRbbRrFa1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1120&quot; height=&quot;192&quot; data-origin-width=&quot;1120&quot; data-origin-height=&quot;192&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;확인해보니 잘 올라갔다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1122&quot; data-origin-height=&quot;100&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Mde6B/btsATCptQmR/VizraHM6SUi9dRXXMZmG0k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Mde6B/btsATCptQmR/VizraHM6SUi9dRXXMZmG0k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Mde6B/btsATCptQmR/VizraHM6SUi9dRXXMZmG0k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMde6B%2FbtsATCptQmR%2FVizraHM6SUi9dRXXMZmG0k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1122&quot; height=&quot;100&quot; data-origin-width=&quot;1122&quot; data-origin-height=&quot;100&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Web/SpringBoot</category>
      <author>suuunnnn</author>
      <guid isPermaLink="true">https://k-ang.tistory.com/167</guid>
      <comments>https://k-ang.tistory.com/167#entry167comment</comments>
      <pubDate>Sun, 26 Nov 2023 20:21:00 +0900</pubDate>
    </item>
    <item>
      <title>[Spring Batch] 1. 스프링 배치(Spring Batch)란?</title>
      <link>https://k-ang.tistory.com/166</link>
      <description>&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;배치 (Batch)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 대용량 데이터 처리 작업을 자동화하는 것&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;스프링 배치 (Spring Batch)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 대용량 데이터 처리를 위한 경량화된 프레임워크&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 반복적인 작업을 수행하는 일괄처리(batch processing) 작업을 효율적으로 처리할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;사용 목적&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 대용량의 데이터 일괄 처리 작업&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;- 특정한 시점에 스케쥴러를 통한 자동화된 작업 (ex. 푸시알림)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;아키텍쳐 구조&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignLeft&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;694&quot; data-origin-height=&quot;405&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/leyJt/btsAScZsHuH/CSAoxtcH30I4MFNvgzkrfk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/leyJt/btsAScZsHuH/CSAoxtcH30I4MFNvgzkrfk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/leyJt/btsAScZsHuH/CSAoxtcH30I4MFNvgzkrfk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FleyJt%2FbtsAScZsHuH%2FCSAoxtcH30I4MFNvgzkrfk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;644&quot; height=&quot;376&quot; data-origin-width=&quot;694&quot; data-origin-height=&quot;405&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Web/SpringBoot</category>
      <author>suuunnnn</author>
      <guid isPermaLink="true">https://k-ang.tistory.com/166</guid>
      <comments>https://k-ang.tistory.com/166#entry166comment</comments>
      <pubDate>Sun, 26 Nov 2023 17:24:28 +0900</pubDate>
    </item>
  </channel>
</rss>