-
๋ชจ์ ํ ์คํธ
๋๊ฐ ๋ฝ์์ ๋ํ๊ธฐ
public static int[] solution_03(int[] numbers) { TreeSet<Integer> result = new TreeSet<>(); for (int i = 0; i < numbers.length - 1; i++) { for (int j = i + 1; j < numbers.length; j++) { result.add(numbers[i] + numbers[j]); } } return result.stream().sorted().mapToInt(Integer::intValue).toArray(); }- stream ์ฌ์ฉ๋ฒ
๋ชจ์๊ณ ์ฌ (์ํฌ์)
public static int[] solution_04(int[] answers) { int[] pattern1 = {1, 2, 3, 4, 5}; int[] pattern2 = {2, 1, 2, 3, 2, 4, 2, 5}; int[] pattern3 = {3, 3, 1, 1, 2, 2, 4, 4, 5, 5}; int[] scores = new int[3]; for (int i = 0; i < answers.length; i++) { scores[0] += answers[i] == pattern1[i % pattern1.length % pattern1.length] ? 1 : 0; scores[1] += answers[i] == pattern2[i % pattern2.length % pattern2.length] ? 1 : 0; scores[2] += answers[i] == pattern3[i % pattern3.length % pattern3.length] ? 1 : 0; } int maxScore = Arrays.stream(scores).max().getAsInt(); ArrayList<Integer> answer = new ArrayList<>(); for (int i = 0; i < scores.length; i++) { if (scores[i] == maxScore) { answer.add(i + 1); } } return answer.stream().mapToInt(Integer::intValue).toArray(); }- ํจํด ํ์ , maxScore ๊ตฌํ๋ ๋ฐฉ๋ฒ .max().getAsInt()
ํ๋ ฌ์ ๊ณฑ์
public static int[][] solution_05(int[][] arr1, int[][] arr2) { int[][] answer = new int[arr1.length][arr2[0].length]; for (int i = 0; i < arr1.length; i++) { for (int j = 0; j < arr2[0].length; j++) { for (int k = 0; k < arr1[0].length; k++) { answer[i][j] += arr1[i][k] * arr2[k][j]; } } } return answer; }- O(N^3) ์ index ์ ์
์คํจ์จ
public static int[] solution_06(int N, int[] stages) { int[] challenger = new int[N+2]; Arrays.stream(stages).forEach(stage -> challenger[stage]++); HashMap<Integer, Double> fails = new HashMap<>(); double totalPlayer = stages.length; for( int i = 1; i <= N; i++) { if(challenger[i] == 0) { fails.put(i, 0.0); }else { fails.put(i, (double)challenger[i]/totalPlayer); totalPlayer -= challenger[i]; } } return fails.entrySet().stream() .sorted((o1, o2) -> Double.compare(o2.getValue(), o1.getValue())) .mapToInt(HashMap.Entry::getKey).toArray(); }- challenger ์ [N+2] ๊ฐ๋ก ์ก๋ ์ด์
- for๋ฌธ์์ totalPlayer -= challenger[i];
- HashMap์ entrySet ์ฌ์ฉ ์๋ น ๊ธฐ์ตํ๊ธฐ
๋ฐฉ๋ฌธ ๊ธธ์ด
import java.util.HashMap; import java.util.HashSet; class Solution { private static HashMap<Character, int[]> location = new HashMap<>(); private static void initLocation() { location.put('U', new int[]{0, 1}); location.put('D', new int[]{0, -1}); location.put('L', new int[]{-1, 0}); location.put('R', new int[]{1, 0}); } public int solution(String dirs) { initLocation(); int x = 5, y = 5; HashSet<String> answer = new HashSet<>(); for (int i = 0; i < dirs.length(); i++) { int[] move = location.get(dirs.charAt(i)); int nx = x + move[0]; int ny = y + move[1]; if (!isValidMove(nx, ny)) { continue; } answer.add(x + " " + y + " " + nx + " " + ny); answer.add(nx + " " + ny + " " + x + " " + y); x = nx; y = ny; } return answer.size() / 2; } private static boolean isValidMove(int nx, int ny) { return nx < 11 && nx >= 0 && ny < 11 && ny >= 0; } }- A->B, B->A ๋ ํ๋์ ์ด๋๊ฒฝ๋ก๋ก ํ์ ๋๋ ์ ์ ์ answer.size() / 2 (๋ฌธ์ ์๋ ์์ธ ์ค๋ช ์ด ์์)
CreatedThu, 24 Apr 2025 20:48:45 +0900 -
Virtual Thread๋ Java 19๋ถํฐ ๋์ ๋๊ณ Java 21์์ ์ ์์ผ๋ก ์์ ํ๋ Project Loom์ ํต์ฌ ๊ธฐ๋ฅ ์ค ํ๋๋ก, ๊ธฐ์กด์ Java ํ๋ซํผ์์ ์ฌ์ฉ๋๋ platform thread(๋๋ OS thread)์๋ ๋ค๋ฅธ ๊ฐ๋ ์ ๋๋ค. Virtual thread๋ **๊ฒฝ๋ ์ค๋ ๋(lightweight thread)**๋ก์, ์์ญ๋ง ๊ฐ์ ์ค๋ ๋๋ฅผ ๋์์ ์คํํ ์ ์๋๋ก ์ค๊ณ๋์์ต๋๋ค.
1. Virtual Thread์ ํต์ฌ ๊ฐ๋
๊ธฐ์กด Platform Thread vs Virtual Thread
ํญ๋ชฉ Platform Thread Virtual Thread ๊ตฌํ OS ๋ ๋ฒจ์์ ๊ด๋ฆฌ JVM์์ ์ง์ ๊ด๋ฆฌ ์์ฑ ๋น์ฉ ๋ฌด๊ฒ๊ณ ๋ฆฌ์์ค ๋ง์ด ์ฌ์ฉ ๊ฐ๋ณ๊ณ ๊ฑฐ์ ๋ฌด์ ํ ์์ฑ ๊ฐ๋ฅ ์ปจํ ์คํธ ์ค์์นญ OS ์ค์ผ์ค๋ฌ์ ์์กด JVM ์ค์ผ์ค๋ฌ ์ฌ์ฉ (๋น ๋ฆ) ๋์์ฑ ์ฒ๋ฆฌ ์ ํ์ ์ธ ๋์์ฑ ๊ณ ๋ฐ๋ ๋์์ฑ ์ฒ๋ฆฌ ๊ฐ๋ฅ
2. ์ฃผ์ ํน์ง
๊ฒฝ๋ ์ค๋ ๋
- Virtual thread๋ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋์ด ํจ์ฌ ์ ๊ณ ์์ฑ ์๋๋ ๋น ๋ฆ ๋๋ค.
- 1:1 ๋งคํ์ด ์๋ M:N ๊ตฌ์กฐ๋ก, ์ฌ๋ฌ virtual thread๊ฐ ํ๋์ OS thread๋ฅผ ๊ณต์ ํฉ๋๋ค.
์ฐจ๋จ I/O์์ ํตํฉ
- ๊ธฐ์กด์๋
Thread.sleep()์ด๋InputStream.read()๊ฐ์ blocking I/O ํธ์ถ์ด OS thread๋ฅผ ์ ์ ํ์ฌ ๋นํจ์จ์ ์ด์์. - Virtual thread์์๋ ์ด๋ฌํ ํธ์ถ์ด ๋ฐ์ํ๋ฉด JVM์ด ํด๋น virtual thread๋ฅผ parkingํ๊ณ , ๋ค๋ฅธ ์์ ์ ์คํ์์ผ ๋ณ๋ชฉ์ ํผํจ.
์ฝ๋ ์คํ์ผ ์ ์ง
- ๊ธฐ์กด์
CompletableFuture,ReactiveAPI ์์ด๋ ์ ํต์ ์ธ ๋๊ธฐ ์ฝ๋ ์คํ์ผ์ ์ ์งํ๋ฉด์๋ ๊ณ ์ฑ๋ฅ ๋น๋๊ธฐ ์ฒ๋ฆฌ๊ฐ ๊ฐ๋ฅ.
3. ์ฌ์ฉ ์์
Runnable task = () -> { System.out.println("Hello from " + Thread.currentThread()); }; Thread thread = Thread.ofVirtual().start(task);ํน์
Executors๋ฅผ ํตํด ์๋ง์ ์ค๋ ๋ ์ฒ๋ฆฌ๋ ๊ฐ๋ฅ:CreatedThu, 24 Apr 2025 11:26:42 +0900 -
๋์ฉ๋ ์ฒ๋ฆฌ๋ฅผ ์ํ **๋น๋๊ธฐ Event Driven Architecture (EDA)**๋ ์์คํ ์ด ์ด๋ฒคํธ(event)๋ฅผ ์ค์ฌ์ผ๋ก ์๋ํ๋ฉฐ, ํ์ฅ์ฑ, ์ ์ฐ์ฑ, ์ฑ๋ฅ์ ํ๋ณดํ๋ ๋ฐ์ ํจ๊ณผ์ ์ธ ์ํคํ ์ฒ์ ๋๋ค. ์๋์ ๊ฐ๋ ๊ณผ ๊ตฌ์ฑ ์์, ์ฅ์ ๋ฐ ์ ์ฉ ์ฌ๋ก์ ๋ํด ์์ธํ ์ค๋ช ๋๋ฆด๊ฒ์.
โ 1. ๊ธฐ๋ณธ ๊ฐ๋
**Event Driven Architecture (EDA)**๋ ์์คํ ๋ด์์ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ฉด, ์ด๋ฅผ ๊ฐ์งํ๊ณ ์ฒ๋ฆฌํ๋ ๊ตฌ์กฐ๋ก ๊ตฌ์ฑ๋ฉ๋๋ค. ์ด๋ฒคํธ๋ ์ด๋ค ์ํ์ ๋ณํ๋ฅผ ์๋ฏธํ๊ณ , ์ด๋ฅผ **ํ๋ก๋์(์์ฐ์)**๊ฐ ๋ฐ์์ํค๊ณ , **์ปจ์๋จธ(์๋น์)**๊ฐ ์ด๋ฅผ ์ฒ๋ฆฌํฉ๋๋ค.
๋น๋๊ธฐ ๋ฐฉ์์์๋ ์ด ์ด๋ฒคํธ๊ฐ ์ฆ์ ์ฒ๋ฆฌ๋์ง ์๊ณ , ํ๋ ๋ฒํผ๋ฅผ ํตํด ์ผ์ ์ ์ฅ๋๋ฉฐ, ์ปจ์๋จธ๊ฐ ๊ฐ๋ฅํ ์์ ์ ์ด๋ฒคํธ๋ฅผ ์ฒ๋ฆฌํฉ๋๋ค. ์ด ๊ตฌ์กฐ๋ ์์คํ ์ด ์ฒ๋ฆฌํด์ผ ํ ๋ฐ์ดํฐ๋ ์์ฒญ์ด ๋ง์ ๋ ๋ถํ๋ฅผ ์ํํ๊ณ ํ์ฅ์ฑ์ ์ ๊ณตํฉ๋๋ค.
CreatedThu, 24 Apr 2025 11:22:53 +0900 -
JPA์์ N+1 ๋ฌธ์ ๋ ์ฑ๋ฅ ์ ํ๋ฅผ ์ ๋ฐํ ์ ์๋ ๋ํ์ ์ธ ORM ์ฌ์ฉ ์์ ์ด์ ์ค ํ๋์ ๋๋ค. ์๋์ ์์ธํ ์ค๋ช ๋๋ฆด๊ฒ์.
N+1 ๋ฌธ์ ๋?
N+1 ๋ฌธ์ ๋ JPA์์ ์ฐ๊ด๋ ์ํฐํฐ๋ฅผ ์ง์ฐ ๋ก๋ฉ(LAZY loading) ๋ฐฉ์์ผ๋ก ์กฐํํ ๋ ๋ฐ์ํฉ๋๋ค.
์๋ฅผ ๋ค์ด, ๋ค์๊ณผ ๊ฐ์ ์ํฉ์ ๊ฐ์ ํด ๋ด ์๋ค:
- ๊ฒ์๊ธ(Post)๊ณผ ์์ฑ์(Member)๋ ๋ค๋์ผ(N:1) ๊ด๊ณ์ด๋ค.
- ๊ฒ์๊ธ 1๊ฐ๋ ์์ฑ์ 1๋ช ์ ๊ฐ์ง๋ค.
@Entity public class Post { @ManyToOne(fetch = FetchType.LAZY) private Member author; }๊ฒ์๊ธ ๋ฆฌ์คํธ๋ฅผ ์กฐํํ๋ ์ฟผ๋ฆฌ๋ฅผ ๋ ๋ฆฌ๋ฉด:
List<Post> posts = postRepository.findAll();์ด๋ JPA๋ ๋ค์๊ณผ ๊ฐ์ ๋ฐฉ์์ผ๋ก ์๋ํฉ๋๋ค:
CreatedWed, 23 Apr 2025 20:48:45 +0900 -
stream().mapToInt()๋ Java Stream API์์ ์ฌ์ฉ๋๋ ๋ฉ์๋ ์ค ํ๋๋ก, Stream์ ์์๋ฅผintํ ์ ์๋ก ๋ณํํ์ฌIntStream์ ์์ฑํ๋ ์ญํ ์ ํฉ๋๋ค.๐ก ์ฌ์ฉ ๋ชฉ์
mapToInt()๋ ์ฃผ๋ก ๊ฐ์ฒด ์คํธ๋ฆผ์์ ์ ์๊ฐ์ ์ถ์ถํ๊ณ ์ ํ ๋ ์ฌ์ฉ๋ฉ๋๋ค. ์๋ฅผ ๋ค์ด, ์ด๋ค ๊ฐ์ฒด ๋ฆฌ์คํธ์์ ํน์ ํ๋(์: ๋์ด, ์ ์ ๋ฑ)๋ฅผ ์ ์๋ก ๋ฝ์๋ผ ๋ ์ ์ฉํฉ๋๋ค.
๐ ๊ธฐ๋ณธ ๊ตฌ์กฐ
Stream<T> stream = ...; IntStream intStream = stream.mapToInt(element -> ๋ณํํ int ๊ฐ);
โ ์์
List<String> list = List.of("1", "2", "3"); int sum = list.stream() .mapToInt(Integer::parseInt) // String โ int .sum(); // IntStream ์ฐ์ฐ ์ฌ์ฉ System.out.println(sum); // ์ถ๋ ฅ: 6์ ์ฝ๋์์:
CreatedWed, 23 Apr 2025 13:48:45 +0900 -
๋ฐฐ์ด
์ ์ธ
int[] arr = {0,0,0,0,0,0}; int[] arr = new int[6];- ArrayList - ์ ์ฅํ ๋ฐ์ดํฐ ๊ฐ์๋ฅผ ์ ํํ ์ ์ ์๋ค๋ฉด…
์ฐจ์
- 2์ฐจ์
int[][] arr = { {1,2,3}, {4,5,6}};ArrayList
- ์ถ๊ฐ
ArrayList<Integer> list = new ArrayList<>(); list.add(1);- ์ด๊ธฐํ
ArrayList<Integer> list = new ArrayList<>(); ArrayList<Integer> list2 = new ArrayList<>(list);- ์ ๊ทผ - get(index)
- ์ญ์ - remove()
- length ๋ณ์
- Arrays.sort()
- toString()
- size()
- isEmpty()
- Collections.sort
ArrayList<Integer> list = new ArrayList<>(Arrays.asList(1,2,3,4,5)); Collections.sort(list); // array๋ Arrays.sort()- sort() ์ฌ์ฉ์ from ์ธ๋ฑ์ค, to ์ธ๋ฑ์ค๋ก ํน์ ๋ฒ์๋ง ์ ๋ ฌ ๊ฐ๋ฅ
ArrayList ํจ์จ์ฑ
- ์๊ฐ ๋ณต์ก๋
- ์ ๊ทผ O(1)
- ๋งจ ๋ค ์ฝ์ O(1)
- ๋งจ ์์ด๋ ์ค๊ฐ. O(N)
- ๊ณ ๋ คํ ์
- ํ ๋นํ ์ ์๋ ๋ฉ๋ชจ๋ฆฌ - ์ ์ํ 1์ฐจ์ 1000๋ง๊ฐ, 2์ฐจ์์ 3000*3000 ์ ๋
- ์ค๊ฐ์ ๋ฐ์ดํฐ ์ฝ์ ์ด ๋น๋ฒํ ๊ฒฝ์ฐ ์๊ฐ ์ด๊ณผํ ์ ์์.
๋ชธํ๊ธฐ ๋ฌธ์
์ ๋ ฌ
- Arrays.sort() -> Dual-Pivot QuickSort ํน์ Tim-Sort : ์ฑ๋ฅ์ข์ผ๋๊น ๊ทธ๋ฅ ์ฐ์
// bubble sort ์ private static int[] bubbleSort(int[] org) { int[] arr = org.clone(); int n = arr.length; for(int i=0; i< n; i++) { for(int j=0; j<n-i-1; j++) { if(arr[j] > arr[j+1]) { int temp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = temp; } } } }- ์๋ณธ์ ๊ทธ๋๋ก ๋๊ณ ์ถ์ผ๋ฉด
int[] clone = arr.clone();๋ฐฐ์ด ์ ์ดํ๊ธฐ
- ์ค๋ณต ์ ๊ฑฐ
Integer[] result = Arrays.stream(arr).boxed().distinct().toArray(Integer[]::new); Arrays.sort(result, Collections.reverseOrder()); Arrays.stream(result).mapToInt(Integer::intValue).toArray(); // int[]๋ก- ๊ฐ๊ธ์ ํ์ค API๋ฅผ ์ฌ์ฉํด์ ์๊ฐ์ด๊ณผ ๋ฐ์ํ์ง ์๋๋ก
TreeSet<Integer> set = new TreeSet<>(Collections.reverseOrder()); int[] result = new int[set.size()]; for(int i = 0; i < result.length; i++) { result[i] = set.pollFirst(); } // ์ค๋ณต์ ๊ฑฐ O(N), ์ ๋ ฌ O(NlogN) => O(NlogN)CreatedTue, 22 Apr 2025 20:48:45 +0900