-
Spring Boot์์ ํ์ผ์ ์คํธ๋ฆฌ๋ฐ(Stream) ๋ฐฉ์์ผ๋ก writeํ ๋, ๋ฉ๋ชจ๋ฆฌ์ ์ฌ๋ฆด์ง ์ฌ๋ถ๋ ์ฌ์ฉ ๋ฐฉ์์ ๋ฐ๋ผ ๋ฌ๋ผ์ง๋๋ค. ํ์ง๋ง ์ผ๋ฐ์ ์ธ ๊ฒฝ์ฐ ์คํธ๋ฆฌ๋ฐ์ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ์ ์ต์ํํ๊ธฐ ์ํ ๊ธฐ๋ฒ์ผ๋ก, ์ ์ฒด ๋ฐ์ดํฐ๋ฅผ ๋ฉ๋ชจ๋ฆฌ์ ์ฌ๋ฆฌ์ง ์๊ณ ์ผ์ ํฌ๊ธฐ์ ๋ฒํผ๋ฅผ ํตํด ์ ์ง์ ์ผ๋ก ์ฒ๋ฆฌํฉ๋๋ค.
โ ๋ฉ๋ชจ๋ฆฌ์ ์ฌ๋ฆฌ์ง ์๋ ๊ฒฝ์ฐ (Streaming ๋ฐฉ์)
Java์์
InputStreamโOutputStreamํํ๋ก ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ ๋ ๋ณดํต ๋ค์์ฒ๋ผ ์ฌ์ฉํฉ๋๋ค:try (InputStream in = ...; OutputStream out = new FileOutputStream("output.txt")) { byte[] buffer = new byte[8192]; // 8KB ๋ฒํผ int bytesRead; while ((bytesRead = in.read(buffer)) != -1) { out.write(buffer, bytesRead, 0); } }์ด ๋ฐฉ์์:
CreatedWed, 30 Apr 2025 13:25:18 +0900 -
Servlet์ด๋?
Servlet์ Java๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์์ฑ๋ ์๋ฒ ์ธก ํ๋ก๊ทธ๋จ์ผ๋ก, ํด๋ผ์ด์ธํธ(์ฃผ๋ก ์น ๋ธ๋ผ์ฐ์ )์ ์์ฒญ์ ์ฒ๋ฆฌํ๊ณ , ์๋ต์ ์์ฑํ๋ ์ญํ ์ ํฉ๋๋ค. ์ฃผ๋ก HTTP ์์ฒญ๊ณผ ์๋ต์ ์ฒ๋ฆฌํ๊ธฐ ์ํด ์ฌ์ฉ๋๋ฉฐ, Java EE (์ดํ Jakarta EE๋ก ์ด๋ฆ ๋ณ๊ฒฝ) ์คํ์ ์ผ๋ถ์ ๋๋ค.
Servlet์ ๊ธฐ๋ณธ์ ์ผ๋ก ์น ์ ํ๋ฆฌ์ผ์ด์ ์๋ฒ(Tomcat, Jetty ๋ฑ) ์์์ ๋์ํ๋ฉฐ, ์น ์๋ฒ์ ํด๋ผ์ด์ธํธ ๊ฐ์ ์ค๊ฐ ์ฒ๋ฆฌ์๋ก ๊ธฐ๋ฅํฉ๋๋ค.
Servlet์ ์ฃผ์ ํน์ง
- Java ์ธ์ด ๊ธฐ๋ฐ: ํ๋ซํผ ๋ ๋ฆฝ์ ์ด๋ฉฐ ๊ฐ์ฒด ์งํฅ ํ๋ก๊ทธ๋๋ฐ์ ์ฅ์ ์ ๊ฐ์ง๋๋ค.
- ์์ฒญ-์๋ต ์ฒ๋ฆฌ: HTTP ์์ฒญ(
GET,POST,PUT,DELETE๋ฑ)์ ๋ฐ์์ ํ์ํ ๋น์ฆ๋์ค ๋ก์ง์ ์ํํ๊ณ , ๊ฒฐ๊ณผ๋ฅผ ๋ค์ ํด๋ผ์ด์ธํธ์ ์ ์กํฉ๋๋ค. - ํ์ฅ์ฑ: ์ถ๊ฐ ์ค์ ๊ณผ ๋ผ์ดํ์ฌ์ดํด ๊ด๋ฆฌ๊ฐ ๊ฐ๋ฅํด ๋ณต์กํ ์น ์ ํ๋ฆฌ์ผ์ด์ ๊ฐ๋ฐ์ด ๊ฐ๋ฅํฉ๋๋ค.
- ์ค๋ ๋ ๊ธฐ๋ฐ: ํ๋์ Servlet ์ธ์คํด์ค๊ฐ ๋ค์์ ์์ฒญ์ ์ฒ๋ฆฌํ๊ธฐ ์ํด ์ฌ๋ฌ ์ค๋ ๋์ ํจ๊ป ๋์ํฉ๋๋ค.
- ๋ผ์ดํ์ฌ์ดํด ๊ด๋ฆฌ:
init(),service(),destroy()๋ฉ์๋๋ฅผ ํตํด ์๋ช ์ฃผ๊ธฐ๋ฅผ ๊ด๋ฆฌํฉ๋๋ค.
Servlet์ ๋์ ๋ฐฉ์
- ํด๋ผ์ด์ธํธ ์์ฒญ: ์ฌ์ฉ์๊ฐ ๋ธ๋ผ์ฐ์ ๋ฅผ ํตํด ์๋ฒ๋ก ์์ฒญ์ ๋ณด๋ ๋๋ค.
- ์น ์๋ฒ ์ ๋ฌ: ์์ฒญ์ ์น ์๋ฒ(Tomcat ๋ฑ)์ ์ํด ํด๋น Servlet์ ์ ๋ฌ๋ฉ๋๋ค.
- Servlet ์์ฒญ ์ฒ๋ฆฌ:
service()๋ฉ์๋๊ฐ ํธ์ถ๋์ด ์์ฒญ์ ์ฒ๋ฆฌํฉ๋๋ค.- ์์ฒญ ๋ฐฉ์์ ๋ฐ๋ผ
doGet(),doPost()๋ฑ์ ๋ฉ์๋๊ฐ ์คํ๋ฉ๋๋ค.
- ์๋ต ์์ฑ: ์ฒ๋ฆฌ ๊ฒฐ๊ณผ๋ฅผ
HttpServletResponse๊ฐ์ฒด๋ฅผ ํตํด ํด๋ผ์ด์ธํธ๋ก ๋ฐํํฉ๋๋ค. - ๋ผ์ดํ์ฌ์ดํด ์ข
๋ฃ: ์๋ฒ๊ฐ ๋ด๋ ค๊ฐ๊ฑฐ๋ ํน์ ์ํฉ์์
destroy()๊ฐ ํธ์ถ๋์ด ์ ๋ฆฌ ์์ ์ ํฉ๋๋ค.
Servlet์ ๊ธฐ๋ณธ ๊ตฌ์กฐ (์์ )
import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet("/hello") public class HelloServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setContentType("text/html"); resp.getWriter().write("<h1>Hello, Servlet!</h1>"); } }์ด ์ฝ๋๋
/hello๊ฒฝ๋ก๋ก ์์ฒญ์ด ์ค๋ฉด “Hello, Servlet!” ์ด๋ผ๋ HTML์ ํด๋ผ์ด์ธํธ์ ๋ฐํํฉ๋๋ค.CreatedTue, 29 Apr 2025 20:19:45 +0900 -
Java์์
abstract class์interface๋ ๋ ๋ค **์ถ์ํ(abstraction)**๋ฅผ ์ํ ์๋จ์ด์ง๋ง, ์ค๊ณ ๋ชฉ์ ๊ณผ ์ฌ์ฉ ๋ฐฉ์์ ์ค์ํ ์ฐจ์ด๊ฐ ์์ต๋๋ค. ์๋์ ๊ทธ ์ฐจ์ด์ ์ ์ ๋ฆฌํด ๋๋ฆด๊ฒ์.
โ ๊ณตํต์
- ๋ ๋ค ์ธ์คํด์คํํ ์ ์์
- ๋ ๋ค ๋ฉ์๋ ์๊ทธ๋์ฒ๋ง ์ ์ธํ๊ณ , ๊ตฌํ์ ํ์ ํด๋์ค(๋๋ ๊ตฌํ ํด๋์ค)์์ ๋ด๋น
- ๋ ๋ค **๋คํ์ฑ(polymorphism)**์ ์ํ ์๋จ
๐ ์ฃผ์ ์ฐจ์ด์
ํญ๋ชฉ abstract classinterfaceํค์๋ abstract class ClassNameinterface InterfaceName๋ค์ค ์์ ๋ถ๊ฐ (๋จ์ผ ์์๋ง ๊ฐ๋ฅ) ๊ฐ๋ฅ (์ฌ๋ฌ ์ธํฐํ์ด์ค ๊ตฌํ ๊ฐ๋ฅ) ์์ฑ์ ์์ฑ์ ์ ์ ๊ฐ๋ฅ ์์ฑ์ ์์ ํ๋ ์ธ์คํด์ค ๋ณ์, ์ ์ ๋ณ์ ๊ฐ๋ฅ public static final์์๋ง ์ ์ธ ๊ฐ๋ฅ (Java 8 ์ด์ ๊ธฐ์ค)๋ฉ์๋ ๊ตฌํ ์ผ๋ถ ๋ฉ์๋ ๊ตฌํ ๊ฐ๋ฅ Java 8๋ถํฐ๋ default,static๋ฉ์๋ ๊ตฌํ ๊ฐ๋ฅ์ ๊ทผ ์ ์ด์ ๋ค์ํ ์ ๊ทผ ์ ์ด์( private,protected,public) ์ฌ์ฉ ๊ฐ๋ฅ๋ชจ๋ ๋ฉ์๋๋ ๊ธฐ๋ณธ์ ์ผ๋ก public abstract(Java 9 ์ดํprivate๋ฉ์๋๋ ๊ฐ๋ฅ)๋ชฉ์ “IS-A” ๊ด๊ณ (์์ ๊ธฐ๋ฐ์ ๊ณ์ธตํ) ๊ธฐ๋ฅ ์ ์์ฉ, ๊ณ์ฝ ๊ธฐ๋ฐ ๊ตฌ์กฐ (๋คํ์ฑ, ํ๋ฌ๊ทธ์ธ)
โจ Java 8+ ์ดํ ๋ฌ๋ผ์ง ์
- Java 8๋ถํฐ ์ธํฐํ์ด์ค์
default๋ฉ์๋์static๋ฉ์๋ ์ถ๊ฐ ๊ฐ๋ฅinterface Vehicle { default void start() { System.out.println("Starting..."); } } - Java 9๋ถํฐ๋
private๋ฉ์๋๋ ์ธํฐํ์ด์ค ๋ด๋ถ์์ ์ ์ธ ๊ฐ๋ฅ
โ ์ธ์ ์ด๋ค ๊ฑธ ์จ์ผ ํ ๊น?
-
abstract class๊ฐ ์ ํฉํ ๊ฒฝ์ฐ:
CreatedThu, 24 Apr 2025 21:48:45 +0900 -
๋ชจ์ ํ ์คํธ
๋๊ฐ ๋ฝ์์ ๋ํ๊ธฐ
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