Java Day 11

YDC·2025년 6월 21일

우테코8기

목록 보기
11/23
post-thumbnail

Day 10 복습

동기란?

요청을 보내고 응답이 올때까지 대기하는 방식
코드의 흐름이 끊겨 있음

비동기란?

요청을 보내고 대기하지 않고 다른 작업을 하는 방식
코드의 흐름이 끊기지 않음

블로킹이란?

결과가 나올때까지 해당작업에서 cpu자원을 붙잡아두고 있는것

논블로킹이란?

결과가 준비되지않으면 즉시 리턴하고 다른 일을하는 것
주기적으로 상태를 확인하면서 자원을 관리함 (Poling,Callback)

Poling

끝났어? 하고 주기적으로 물어보는 방식

Callback

끝나면 이거해줘~ 등록해놈

조합설명코드 흐름CPU 활용예시 코드주요 사용 상황
동기 + 블로킹작업 끝날 때까지 기다림멈춤낮음reader.readLine(), executeQuery()단순 순차 처리, 파일/DB
동기 + 논블로킹바로 리턴하되 결과는 없음연속중간channel.read(buffer) (NIO)저수준 I/O, 일부 네트워크
비동기 + 블로킹여러 요청 → 결과 받을 때 멈춤중단됨중간future.get()병렬 처리 후 통합, 다운로드
비동기 + 논블로킹요청 후 다른 일 → 결과는 콜백으로안 멈춤높음CompletableFuture.thenAccept()고성능 서버, UI 반응성 처리

학습 목표

1.백준 3문제

  • 2480 주사위
  • 2739 구구단
  • 10950 A+B-3

2.기능 추가

  • Rebase 실습
  • Csv 내보내기 기능 추가
  • Undo 기능 (삭제 기능)추가

3.CS 공부

  • 프로세스 동기화(실패)

1.백준 3문제

1.2480 주사위

문제

1에서부터 6까지의 눈을 가진 3개의 주사위를 던져서 다음과 같은 규칙에 따라 상금을 받는 게임이 있다.
1. 같은 눈이 3개가 나오면 10,000원+(같은 눈)×1,000원의 상금을 받게 된다.
2. 같은 눈이 2개만 나오는 경우에는 1,000원+(같은 눈)×100원의 상금을 받게 된다.
3. 모두 다른 눈이 나오는 경우에는 (그 중 가장 큰 눈)×100원의 상금을 받게 된다.
예를 들어, 3개의 눈 3, 3, 6이 주어지면 상금은 1,000+3×100으로 계산되어 1,300원을 받게 된다. 또 3개의 눈이 2, 2, 2로 주어지면 10,000+2×1,000 으로 계산되어 12,000원을 받게 된다. 3개의 눈이 6, 2, 5로 주어지면 그중 가장 큰 값이 6이므로 6×100으로 계산되어 600원을 상금으로 받게 된다.
3개 주사위의 나온 눈이 주어질 때, 상금을 계산하는 프로그램을 작성 하시오.

입력

첫째 줄에 3개의 눈이 빈칸을 사이에 두고 각각 주어진다.

출력

첫째 줄에 게임의 상금을 출력 한다.

풀이

package condition;
import java.util.Scanner;

public class BOJ_2480_TripleDice {
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int a = sc.nextInt();
        int b = sc.nextInt();
        int c = sc.nextInt();

        if(a == b && b == c){
            System.out.println(10000+(a*1000));
        }else if(a == b||a == c) {
            System.out.println(1000 +(a*100));
        } else if(b == c){
            System.out.println(1000+(b*100));
        } else if(a>b&&a>c){
            System.out.println(1000+(a*100));
        } else if(b>a&&b>c){
            System.out.println(1000+(b*100));
        } else {
            System.out.println(c*100);
        }
    }
}

주사위 3개의 결과가 주어지고, 조건에 따라 상금을 계산하는 문제 if else 및 논리 연산자 사용

2.2739 구구단

문제

N을 입력받은 뒤, 구구단 N단을 출력하는 프로그램을 작성하시오. 출력 형식에 맞춰서 출력하면 된다.

입력

첫째 줄에 N이 주어진다. N은 1보다 크거나 같고, 9보다 작거나 같다.

출력

출력형식과 같게 N1부터 N9까지 출력한다.

예제 입력 1 

2

예제 출력 1 

2 1 = 2
2
2 = 4
2 3 = 6
2
4 = 8
2 5 = 10
2
6 = 12
2 7 = 14
2
8 = 16
2 * 9 = 18

풀이

package loop;
import java.util.Scanner;

public class BOJ_2739_Gugudan {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        for (int i =1;i<=9; i++){
            System.out.println(n+" * "+i+" = "+(n*i));
        }
    }
}

For 문을 사용하여 반복하면 기본적인 반복문

3.10950 A+B-3

문제

두 정수 A와 B를 입력받은 다음, A+B를 출력하는 프로그램을 작성하시오.

입력

첫째 줄에 테스트 케이스의 개수 T가 주어진다.
각 테스트 케이스는 한 줄로 이루어져 있으며, 각 줄에 A와 B가 주어진다. (0 < A, B < 10)

출력

각 테스트 케이스마다 A+B를 출력한다.

예제 입력 1

5
1 1
2 3
3 4
9 8
5 2

예제 출력 1

2
5
7
17
7

풀이

package loop;
import java.util.Scanner;

public class BOJ_10950_Ab3 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        while(n-->0){
            int a = sc.nextInt();
            int b = sc.nextInt();
            System.out.println(a+b);
        }
    }
}

간단한 테스트 케이스 반복 처리 능력 테스트

2.기능 추가

1.Rebase 실습

Feat/category GitHub //원격으로 연결 및 삭제
git checkout main //메인으로 이동
git merge feat/category //메인에 머지
git push origin main  //github에 반영
git branch -d feat/category //브랜치 삭제
git push origin —delete feat/category //github에도 삭제

git checkout feat/csvExprot //brach 이동
git rebase main //main을 기준으로 리베이스
git push origin feat/csvExport //github에 반영
git log —online —graph —all //커밋 확인으로 rebase확인

2.csv 내보내기 기능 추가

TodoManager 코드 추가

toString을 사용해서 간결하게 표출
public static void exportCsv(List<Todo>todos, String filename) {
    try(FileWriter writer = new FileWriter(filename)){
        writer.append("ID,isDone,Task(Category),DueDate\n");
        for (int i=0;i<todos.size();i++) {
            Todo todo = todos.get(i);
            writer.append(String.valueOf(i+1)).append(",");
            writer.append(todo.toString()).append("\n");
        }
        System.out.println("todos.csv 파일");
        } catch (IOException e) {
        System.out.println("CSV 저장  오류 발생 "+e.getMessage());
    }
}

Main 코드 추가

case 7:
    TodoManager.exportCsv(todos, "todos.csv");
    break;

TodoManagerTset 코드 추가

테스트 코드 추가
개념설명
try-with-resourcesclose()를 자동으로 호출해주는 문법
→ 자원 누수 방지
FileReader파일을 문자 단위로 읽는 스트림 클래스
BufferedReader라인 단위로 읽기 위해 FileReader를 감싸는 클래스
readLine()파일에서 한 줄씩 읽어 문자열로 반환
\n은 포함되지 않음

FileReader란? 파일을 문자단위로 읽는 스트림

BufferedReader란? 라인 단위로 읽기 위해 감싸는 클래스

ReadLine()이란 ? 한줄씩 읽어서 문자열로 반환

즉 test_todos.csv라는 파일을 문자단위 -> 라인단위->로 바꾼후 한줄씩 문자열로 읽음

@Test
public void testExportCsvCreateValidFile() {
    List<Todo> todos = new ArrayList<>();
    todos.add(new Todo("JUnit 복습", false,"기타", LocalDate.now()));
    String filename = "test_todos.csv";

    TodoManager.exportCsv(todos, filename);

    File file = new File(filename);
    assertTrue(file.exists());

    try(BufferedReader reader = new BufferedReader(new FileReader(filename))){
        String header = reader.readLine();
        String data = reader.readLine();

        assertEquals("ID,isDone,Task(Category),DueDate", header);
        assertTrue(data.contains("JUnit 복습"));
        assertTrue(data.contains("기타"));
        assertTrue(data.contains("[]"));
    }catch(Exception e){
        fail("파일 읽기 실패" + e.getMessage());
    }

}

3.Undo 기능 (삭제기능) 추가

Stack이란?

나중에 넣는게 제일 먼저 나오는 LIFO(Last In First Out) 구조

예시

Stack<String> stack = new Stack<>();

stack.push("공부하기");    //Stack[공부하기,]
stack.push("운동하기"); // Stack[공부하기,운동하기]
stack.push("게임하기"); //Stack: [공부하기,운동하기,게임하기]

String latest = stack.pop();   // 꺼내기
System.out.println(latest);    // "게임하기"
System.out.println(lastest); // “운동하기”
System.out.println(lastest); // “게임하기”
System.out.println(lastest); //오류발생 스택에 남아 있는게 없음
메서드설명예시
push()데이터를 스택에 넣는다 (추가)stack.push("운동")
pop()스택에서 가장 최근 항목을 꺼낸다 (제거)stack.pop()"운동"
isEmpty()스택이 비어 있는지 확인stack.isEmpty()true/false

TodoService 코드 추가

Stack 지역 변수 추가 삭제시 스택 푸쉬코드 추가, 운도 기능 메소드 추가
public class TodoService {
    private List<Todo> todos;
    private Stack<Todo> deleteTodos = new Stack<>();
    public TodoService(List<Todo> todos) {
        this.todos = todos;
    }
// 할일 삭제
public void remove(int displayIndex) {
    int realIndex = displayIndex - 1;
    if (isValidIndex(realIndex)) {
        for (int i = 0; i < todos.size(); i++) {
            System.out.println((i + 1) + "." + todos.get(i));
        }
        deleteTodos.push(todos.get(realIndex));
        todos.remove(realIndex);
        System.out.println("✅ 삭제되었습니다.");
    } else {
        System.out.println("❌ 잘못된 번호입니다.");
    }
}
   //되돌리기 기능
    public void undoDelete(List<Todo>todos) {
            if(!deleteTodos.isEmpty()){
                Todo restored = deleteTodos.pop();
                todos.add(restored);
                System.out.println("복구완료”+”\n”+ restored);
            }

}

TodoServiceTest 코드 추가

BeforeEach에 스택 지역 변수 추가, 되돌리기 테스트 메소드 추가
@BeforeEach
public void setUp() {
    ArrayList<Todo> todos = new ArrayList<>();
    Stack<Todo> deleteTodos = new Stack<>();
    service = new TodoService(todos);
}


@Test
public void testUndoDelete() {
    service.add("휴식","기타","2025-12-14");
    service.remove(1);
    assertEquals(0, service.getTodos().size());

    service.undoDelete(service.getTodos());
    assertEquals(1, service.getTodos().size());
    assertEquals("휴식", service.getTodos().get(0).getTask());
}

리뷰

오늘은 백준 문제를 너무 나도 쉽게 전부 타파 후 무려 기능도 2개나 추가하고 테스트 코드마저 추가해버린
누가 이녀석을 뉴비로 보겠는가 !! ( ;;) 미친 천재성을 자랑하며 완벽하게 수행해 냈다
이제 그 무엇도 두렵지 않다! API오너라 SpringBoot 오너라 하하하하하하하
물론 시간을 많이써서 목표로 했던 cs공부를 못했지만
그건 내일의 나에게 … 오늘도 고생했다 멋있다 나 !

profile
초심자

0개의 댓글