항해 2주차 WIL

태량·2023년 2월 19일
0

항해99

목록 보기
5/6

2/13~ 2/19간 진행된 항해 2주차에선

드디어 자바에 대해서 진도를 나갔다. 자바의 JVM, 변수, 연산자와 같은

가장 기초적이지만 어찌 보면 가장 중요한 단원들을 지나, 반복문과 조건문

까지 나아갔다. 사실 나에겐 이미 많이 접해보고 공부 했었던 부분이라 처음에는 그냥 지나칠까도 생각했는데, 오랜만에 JVM에 대한 내용을 보면서 Visual VM을 통해 힙 영역을 덤프 분석 하는 것에 욕심이 나서, 시도를 해보았다. 스냅샷까지 잘 찍어지며 가동은 됐지만 사실 어떠한 부분을 봐야하는지를 잘 몰라, 많이 활용해서 써보진 못했다. 차후에 프로젝트에서 꼭 필요한 순간이 오겠지..! 이때 다시 활용법을 찾아보고 공부할 계획이다. (사실 인프런에 백기선님 자바 테스트 관련 강의를 참고하면 도움이 많이 될 것 같긴 한데, 고민 중이며, 지금 이 글을 쓰는 와중에 교보문고에 가서 테스트 주도 관련 책에 대해서 살펴보고 구매를 할지 고민이 되기도 한다.)

그리고 나서 수요일부터는 알고리즘 파트로 접어들었다, 항해에서 엑셀 파일로 문제 난이도 별로 분류되어 각 수강생들의 라인별로 풀었는지를 체크하는 방식이였는데, 이 방식 덕분에 다른 수강생들에게 뭔가 경쟁 의식이 생겨 동기부여가 되서 좋았다. 열심히 풀며 주어진 54문제를 제일 빨리 풀고, 알고리즘에서 부족한 DFS,BFS,그리디 알고리즘, 동적 계획법을 따로 공부했다. 동적 계획법을 제외하고는 개념도 익히고, 문제를 꽤 풀어봤지만 그리디 알고리즘은 뭔가 그리디 알고리즘스럽게 풀지 못한 것 같아 아쉬움이 남는다.(너무 개념을 빠르게 훑고 문제 위주로 해서 그런건 아닌가 싶다.) -> 나머지 기간에 추가로 일요일 같은날 동적 계획법도 추가적으로 익힐 것이며, 평일에 알고리즘 전반적으로 하루에 1문제씩이라도 꾸준하게 풀 계획이다

이번주에 제일 잘한 부분은 스터디에서 중요한 역할을 맡아 다른 사람들에게 좋은 영향력을 주려고 많이 노력한 부분을 칭찬한다. 갑작스러운 자바 스터디 모임에 참석하게 됐는데, 거기에 인원이 15명정도로 굉장히 많았다. 하지만 스터디 모임장님도 프로그래밍이 처음이라 어떻게 갈피를 잡아야 할지 몰라하시다가 다음날 나에게 개인적으로 오셔서 길잡이 역할을 부탁하셨다. 나는 흔쾌히 수락했다. 사실 스터디를 좋아하지 않는데 참석한 이유가 뭔가 스터디에서 질문에 대해서 답해주고 하면, 내 공부도 많이 될 것 같아서였다. 첫 스터디때는 코딩이 처음인 분들이 많아서 진도를 많이 나가진 않았다. 그리고 스터디를 원래 싫어했던 이유가 형식적으로 누구는 어떤 범위를 맡아서 정리를 하고, 그걸 언제 모여서 공유하고 공부한다? 이런 식의 남이 정리 해주는 것을 읽고 공부가 될까? 라는 의문이 많기 때문이다. 지금도 이 생각은 변함이 없다. 그래서 스터디 방향성에 대해서 많이 생각 해봤는데, 지식의 공유보다는 그래도 먼저 공부한 사람으로써 이 부분은 짚고 생각하고 넘어 갈 수 있도록, 질문 거리를 던져주는데에 집중하기로 했다.

그래서 아래는 스터디 노션에 남긴 내용들이다.

  1. 클래스 vs 객체

    • 사람은 클래스인가? 객체인가?
    • 김연아는 클래스인가? 객체인가?
    • 뽀로로는 클래스인가? 객체인가?
    • 펭귄은 클래스인가? 객체인가?
  2. 객체 지향 4대 특성 중 [추상화]에 대하여

    • 추상화란 구체적인 것을 분해해서 관심 영역에 있는 특성만 가지고 재조합 하는 것 = 모델링

    문제) 병원의 환자라는 클래스를 설계(추상화, 모델링)하려고 한다. 아래의 Patient 클래스에서 불필요한 필드와 메소드는 무엇인가.

    문제2) 더 나아가 아래에 적힌 단어를 실제 자바 형식으로 작성하시오.

    public class Patient{
    
    	시력
    	몸무게
    	연봉
    	혈액형                          => 인스턴스 필드
    	여자친구
    	키
    	나이
    	직업
     
    
    	먹다()
    	자다()
    	일하다()
    	운전하다() 
    	입금하다()                      => 메소드
    	출금하다()
    	이체하다()
    	대출하다()
    	운동하다()
    }
  3. 추상화 좀 더 살펴보기. 쥐를 예로 들어서.

    | 성명
    나이
    꼬리수 |
    | 울다() |

    Mouse

    | + name : String
    +age : int

    • countOfTail : int |
      | + sing() : void |

쥐라는 클래스가 있고, 필드와 메소드가 있다. Mouse 클래스를 정의하고, MouseDriver라는 클래스에서 Mouse 객체를 생성하고, 객체를 사용해서 메소드를 사용하기.


public class Mouse {

    public String name;         => 참고! 98% 이상의 경우 필드는 private로 감춰야 함.

    public int age;

    public int countOfTail;

    public void sing() {
        System.out.println("나는 "+name+"이야. 찍찍");
    }

}

public class MouseDriver {

    public static void main(String[] args) {

        Mouse mickey = new Mouse();

        mickey.name = "미키";

        mickey.age = 85;

        mickey.countOfTail = 1;

        mickey.sing();

    }

}
  1. 위에 mouse 클래스처럼, Penguin이라는 클래스를 정의하고, Penguin의 인스턴스 필드에 이름, 서식지(habitat)를 반드시 포함하여, 객체를 생성 해보기.

    메소드로는 펭귄 객체의 이름과 서식지를 콘솔에 출력하는 메소드 작성.

  2. 인스턴스 멤버와 인스턴스 필드는 차이가 존재 하는가요? 존재한다면 어떻게 다른가요?

  3. 클래스, 인스턴스, 클래스 정적 멤버, 인스턴스 멤버는 각각 자바 메모리 영역에 어디에 속해 있나요.

  4. 왜 메소드는 반환을 명시 해줘야 하는가? void는 값을 반환하진 않지만, 반환에 대해 명시.

  • 자료구조와 자바 메모리 영역에 관련해서 설명하세요.

    그리고 추가로 월요일에 있을 알고리즘 테스트를 위해 항해측에서 예상 문제 3개를 제공 해준 것이 있다. 그때 어제 저번에 같이 프로젝트를 진행해서 친해진 분이 조부상을 당하셔서, 공부를 못하게 되는 상황이라, 예상 문제에 대한 핵심 아이디어도 정리해서 그분에게 전달 해드렸다.

  1. 1번 문제
package codingTest;

import java.time.LocalDate;

public class Exam1 {

    public static void main(String[] args) {

        /*
        *   문제 풀이 아이디어
        *
        *   1. 사실 int[] month_day 라는 배열에 각 월마다 최대 일수를 적어 놓고, 시작되는 날짜를 기준으로
        *       연산을 돌리면 되긴 하는데, 좀 까다로운 면이 있음. plusDays 메소드를 이용해서 간단하게 계산하기 ㅎㅎ;
        *
        *   2. LocalDate.Of 메소드는 매개변수에 (연도,월,일)이 들어감. 그리고 반환 값을 LocalDate 인스턴스를 반환함
        *       이것은 정적 메소드를 통한 생성자 팩토리. => 왜 이걸 사용하는지는 찾아보면 공부 될 듯. 중요한 개념 중에 하나임.
        *
        *   3. 근데 이 로직에서 문제가 만약에 23년 11월이 주어지면 24년으로 넘어가기에 결과값이 1이내로 오차가 생김. 이건 따로 로직 넣어줘야함.
        *
        *
        * */

        int month = 11;
        int day = 27;

        LocalDate date = LocalDate.of(2023,month,day);

        LocalDate date1 = date.plusDays(98);

        if(date1.getMonth().getValue() < month){
            date1 = date1.plusDays(1);
        } 

        System.out.println(date1);

    }

}
  1. 2번 문제
package codingTest;

public class Exam2 {

    public static void main(String[] args) {

        /*
        *   문제 풀이 아이디어
        *
        *  1. 새벽 5시가 넘어가면 21시로 데이터를 바꿔줘야 하는 조건에 주목한다. 따라서 cut라는 변수명으로 새벽 5시를 의미
        *       또한 새벽 5시가 넘으면 공부 체크인 시간이 21시로 바뀌는 조건에 주목하여 penalty라는 변수명에 21을 초기화.
        *
        *   2. 나머지는 아래 for문에서 보이는 것처럼, 새벽 5시(cut)를 넘기는지를 판별해서 계산하면 충분.
        *
        *
        * */

        int[] checkIn = {9, 7, 8, 9, 7, 9, 8};
        int[] checkOut = {23, 22, 26, 26, 29, 27, 22};

        int cut = 29;
        int penalty = 21;

        int sum = 0;

        for(int i=0; i<checkOut.length; i++){

            if(checkOut[i] >= cut){

                sum += penalty - checkIn[i];

            }else{

                sum += checkOut[i] - checkIn[i];
            }

        }

        System.out.println(sum);

    }

}
  1. 3번 문제
package codingTest;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;

public class Exam3 {

    public static void main(String[] args) {

        /*
        *    문제 풀이 아이디어
        *
        *   1. 주어지는 입력 값 s는 공백을 기준으로 나눠져 있다 => 각각을 사용하기 위해
        *      String의 split 메소드를 통해 공백을 기준으로 String[]로 나눠준다.
        *
        *   2. 소수를 판별하기 위한 아래 정적 메소드 isPrime 메소드를 만든다.
        *
        *   3. 만들어진 String[] 배열을 처음부터 끝까지 for문으로 탐색하며, 소수를 담는 리스트 Primes 와 소수가 아닌
        *      정수 nonPrimes 를 담는 리스트에 나눠서 담는다.  
							
							=> 여기선 배열의 갯수가 정해지지 않아서 List를 사용.
        *       (ArrayListe를 사용하면, 배열과 같지만, 크기제한 없이 배열을 사용 할 수 있습니다.) 
								배열을 처음 10칸으로 초기화 했어도 10개 이상의  데이터를 넣을 수 있는 논리.
        *      
        *
        *   4. 만들어진 nonPrimes와 Primes 를 가지고 최소값과 최대값을 찾는 로직을 실시한다. => 여기선 스트림을 이용해서 찾았는데,
        *       for문과 max = arr[0]을 정해두고 탐색 해나가는 로직을 통해서 최대값 최소값을 찾아도 무방.
        *
        *   5. 최소값과 최대값을 산출하면, 문제 형식에 맞게 String result = ""; 에 각각 담아서 반환한다.
        *
        * */

        String s = "97 75 88 99 95 92 73";

        String[] str = s.split(" ");

        System.out.println(Arrays.toString(str));

        List<Integer> nonPrimes = new ArrayList<>();
        List<Integer> primes = new ArrayList<>();

        for(String s1 : str){

            int num = Integer.parseInt(s1);

            if(isPrime(num)){

                primes.add(num);

            }else{

                nonPrimes.add(num);
            }

        }

        String result = "";

        String nonPrimeMin = nonPrimes.stream().min(Comparator.naturalOrder()).get()+"";
        String primeMax = primes.stream().max(Comparator.naturalOrder()).get()+"";

        // for문 통해서 최소값 찾기. 이 로직에선 nonPrimes.size() = nonPrimes.length와 같은 개념임. 리스트에선 size를 씀.

                /*int min = nonPrimes.get(0);

                for(int i=0; i<nonPrimes.size(); i++){

                    if(min > nonPrimes.get(i)){
                        min = nonPrimes.get(i);
                    }
                }*/

        result = nonPrimeMin+" "+primeMax;

        System.out.println(result);

    }

		// 소수 찾는 로직

    static boolean isPrime(int num){

        for(int i=2; i<=num/2; i++){               

// i <= num / 2 에서 보면 num/2까지만 탐색하는 이유는 22를 예로 들면, 어차피 22의 절반 11을 넘어가면 12부터는 죽었다 깨어나도 22를 나누지 못함

            if(num % i == 0){
                return false;
            }

        }

        return true;

    }

}

일요일 주말 아침 늦잠을 자고 일어나서, 샤워를 하면서 이번 한주를 돌이켜 봤을 때, 좋은 영향력을 공유한 것에 대해선 만족 했지만, 내 공부에 있어선 뭔가 발전이 적었다라는 생각이 든다. 뭔가 그동안 책을 통해서 순서 있는 공부를 하다 이번엔 좀 다른 방식이여서 그랬을까? 그래서 새로운 한주엔 초반에 공부에 도움을 줬던 객체지향 관련 책과 디자인 패턴을 다시 회독하면서 스터디 원들에게 도움이 될 만한 질문거리들을 만들 생각이다

profile
좋은 영향력과 교류를 위하여

0개의 댓글