본문 바로가기
ZB 백엔드 스쿨/주차별 정리

제로베이스 백엔드 부트캠프 1주차 정리

by son_i 2023. 7. 9.
728x90

또 다시 공부를 시작해야 되는게 암울했지만 매일 지날수록 적응이 되고 새로운 것들을 알아가는 것, 아는 건 다시 복습할 수 있는 시간이 좋은 것 같다. 

 

새로 알게된 거 위주로 써보려고 한다.

 

7/3 

부끄럽게도 디버깅이 뭔지 몰랐다. 학교 다닐 땐 한 번도 실행시켜본 적이 없다.

디버깅은 코드번호 옆에 누르면 빨간 점이 생기는데 Run이 아닌 Debug로 실행하면 그 코드라인 전까지 실행이 된다.

 -종류 네가지

step over : 하위구조가 있어도 그냥 넘어감

step into : 하위구조가 있으면 타고 들어감

step out : step into에서 타고 들어왔던 하위구조에서 다시 원래 위치로 돌아옴

Run to Cursor : 특정 코드에 마우스 커서 두고 누르면 해당 줄까지 실행됨.


- 변수 이름 규칙

 문자, 숫자, _, $ 사용가능

 숫자 시작 X


- 카멜 표기법 : 가장 많이 쓰임 ex) myName


- 자료형 :

2진 (0b) , 8진 (0), 16진 (0x)

float 는 뒤에 반드시 f표시를 해야함. 이걸 몰랐었다..

 

- String 메소드 : equals, indexOf, replace, substring, toUpperCase/toLowerCase

 

- StringBuffer : String에도 문자열 붙이기가 가능하나 빈번한 추가, 삭제시 사용.

  StringBuffer sb = new StringBuilder();

  sb.append(" "); 

 

7/4

- 자료형 : 

  - 리스트 : 배열과 같이 여러 데이터를 담을 수 있는 자료형. ArrayList l1 = new ArrayList();

      add,get,size,remove,clear,sort,contains

     list.sort(Comparator.naturalOrder()); //오름차순 정렬

     list.sort(Comparator.reverseOrder()); //내림차순 정렬

  - 맵 : key, value 형태로 데이터 저장. HashMap map = new HashMap(); //제네릭 적용 안 한 케이스

     (인덱스로 접근 X, 값 저장한 순서대로 저장되지 않음.)

     put,get,size,remove,containsKey

  - 제네릭스 : 자료형을 명시적으로 지정. 제한적일 수 잇으니 안정성이 높고 형 변환 가능성이 적다.

    ArrayList <String>l1 = new ArrayList<>();

    HashMap <String,String> map = new HashMap<>();

 

 * list.remove(인덱스); //인덱스 대신 Integer.valueOf(2)를 쓰면 2의 인덱스를 반환함


- for each 문

   for(int  num : nums)   int형 배열 nums에서 num이라는 변수로 요소 하나씩 접근

 

- 연습문제 별 문제가 있었음. 헷갈렸어

*

***

*****

*******


7/5

- 다차원 배열 

for each로 출력해보기

1차원                          2차원

for(int i : myArray)       for(int[] ints:myArray)  //2차원 배열에서 행 하나를 접근

sout(i);                           for(int i : ints) sout(i) //행 하나에서 열 하나씩 접근

 

-클래스와 객체 1

메소드, 클래스 나왔고

  - this. VS this()

   this.는 자기 자신의 객체를 의미.  생성자에서 많이 씀

   this()는 한 생성자 안에서 다른 생성자를 호출할 때 씀. 매개변수를 넣어주면 그것과 매칭되는 생성자 호출됨.


-클래스와 객체 2

 - 오버로딩 : 한 클래스 내에 이름이 동일한 메소드 여러개. 매개변수의 타입,갯수는 무조건 달라야함. 반환형, 접근지정자는 관계 X

 - 접근지정자 : public, protected, default, private

 - static : 변수나 메소드의 특성을 바꾸는 키워드. static 변수 / 메소드는 객체 생성 전부터 메모리에 위치.

    특징 : 메모리에 한 번만 할당. 즉 static 변수/ 메소드는 공유됨.

    static 클래스 변수 : 해당 클래스의 각 객체들이 값을 공유

    static 클래스 메소드 : 객체 생성 안 해도 클래스 이름으로 호출 가능.


- 상속

  - supper, supper()

    supper : 부모클래스와 자식클래스 멤버 이름이 같을 때 구분.

    super() : 부모클래스의 생성자 호출할 때 사용.

   ex)

class Animal {
    String desc;
    Animal() {
        this.desc = "동물 클래스 입니다.";
    }

    Animal(String desc) {
        this.desc = desc;
    }

    public void printInfo() {
        System.out.println(this.desc);
    }
}

class Cat extends Animal {
    String desc;
    Cat() {
        //this.desc = "고양이 입니다.";
        //super.desc = "고양이 입니다.";
        super("고양잉이이이");
    }
}

- 오버라이딩 : 상속관계에서만 ! 부모 클래스의 메소드를 자식 클래스에서 재정의.

   조건 : 메소드 선언부는 부모클래스의 메소드와 동일해야함.

             반환타입 한정으로, 부모클래스의 반환타입으로 변환할 수 있는 타입으로 변경가능.

             부모 클래스 메소드보다 더 좁은 범위의 접근제어자 불가.

             부모 클래스 메소드보다 더 큰 범위의 예외선언 불가.


- 다형성 : 한 객체가 여러가지 타입을 가질 수 있는 것.

                부모타입의 참조변수로 자식클래스 인스턴스 참조

   class Person{

 

  }

  class Student extends Person{

 

  } 이라는 코드가 있을 때

메인에서 Person p1 = new Student(); 요런식으로 업캐스팅(자식 클래스의 객체가 부모 클래스의 객체로 형변환) 해주는 것 !

실제 생성되는 건 Student타입의 객체. 부모 -> 자식 쪽으로만 참조 가능. 역은 안 됨

이때 p1은 부모타입의 객체 참조변수라 자식 쪽은 접근이 불가 (원래 Student인데 잠시 업캐스팅 되어 type만 Person)

이때는 다운캐스팅을 해줘야 한다. Student s1 = (Student) p1 ; 이렇게

이게 좀 이해하기가 어려웠다. 다형성하면 개념은 알겠는데 굳이 왜 쓰는지 ?

그 예시가

  Car car2[] = {new Car(), new Firetruck(), new Ambluance()};

  for(Car item : car2)

    item.horn();

다형성 덕분에 Car이라는 부모 클래스 객체 하나로 상속받은 자식 클래스를 모두 가리킬 수가 있게됨.

 

더 이해하기 쉽게 공부해보았다.

다형성이란 하나의 메소드나 클래스가 있을 때 이것들이 다양한 방법으로 동작하는 것

오버로딩은 가장 쉬운 다형성의 예라고 한다.

  오버로딩은 ? 이름이 같고 매개변수의 타입이나 갯수가 다른 여러 개의 메소드를 두는 것.

  어떻게 보면 하나의 이름을 가진 메소드를 다양한 방식으로 쓰는 것이라 말이 되는 거 같다.

다형성 - Java (opentutorials.org)

이 블로그 참조하여 기본적인 이해를 마쳤고 추가 사례를 더 알아보기 위해 chatGPT에 물어봤다.

1. 상속 관계에서의 다형성: 부모 클래스 타입으로 자식 클래스의 객체를 참조할 수 있습니다. 이를 통해 여러 종류의 자식 객체를 하나의 부모 타입으로 관리하고, 동일한 부모 클래스의 메서드를 호출하여 다양한 동작을 수행할 수 있습니다.

2. 인터페이스를 이용한 다형성: 인터페이스는 일종의 계약으로, 클래스가 해당 인터페이스를 구현한다는 것을 보장합니다. 인터페이스를 타입으로 사용하면 해당 인터페이스를 구현한 다양한 클래스의 객체를 동일한 타입으로 다룰 수 있습니다. 이를 통해 객체들 간에 결합도를 낮추고 유연한 코드를 작성할 수 있습니다.

3. 메서드 오버라이딩을 통한 다형성: 자식 클래스에서 부모 클래스의 메서드를 재정의하는 것을 메서드 오버라이딩이라고 합니다. 이를 활용하면 부모 클래스의 타입으로 호출하더라도 실제로는 자식 클래스의 재정의된 메서드가 호출되어 다형성을 구현할 수 있습니다.

4. 매개변수의 다형성: 메서드의 매개변수로 부모 클래스 타입을 사용하면 해당 부모 클래스 및 그를 상속한 자식 클래스의 객체를 모두 전달할 수 있습니다. 이를 통해 하나의 메서드로 다양한 객체를 처리할 수 있습니다.

다형성을 적절하게 활용하면 코드의 유연성을 높이고, 재사용성을 높여 쉽게 확장 가능한 프로그램을 작성할 수 있습니다.

라고 한다.

 

사실 이미 다 해본 거고 알고있었는데 개념을 연결짓는게 어려웠던 것 같다.

너무 어렵게 생각하지말자 ! 그냥 하나의 클래스나 메소드를 여러방면으로 쓰이게 하는 것 !


- 추상클래스 & 추상메소드

 추상메소드 : 본문이 없고 선언만 되어있는 메소드

 추상클래스 : 추상메소드를 하나라도 가진 클래스.

   추상클래스는 자체적으로 객체 생성이 불가능.

   - 상속클래스에서 구현해서 쓰기

   - Main에서 익명 클래스로 구현해서 사용

       *익명클래스란 ? 이름이 없고 선언과 동시에 객체생성. 일회용

           클래스이름 참조변수이름 = new 클래스이름() {  ...  } ;


- 인터페이스

  추상메소드와 상수만으로 이루어짐. 

  다중상속처럼 사용가능. (하나의 자식이 여러 부모를 참조하는 것)]

   ex)  class C implements A, B {}


7/6

- 내부클래스 (클래스 in 클래스)  객체 생성해서 쓰는 방법을 처음 봤다 !

  클래스 내부에서 클래스 외부 멤버 자유롭게 접근 가능. 그 반대는 불가

  종류 : 인스턴스 클래스, 정적클래스, 지역클래스, 익명클래스

   - 인스턴스 클래스 : 밖 클래스 객체를 만들어야 내부 클래스 사용 가능

      Outer.Inner i = new Outer().new Inner();

   - 정적클래스 : static 키워드가 붙어서 외부 클래스가 만들어지기 전부터 메모리에 상주. 외부 클래스 객체 생성 안 하고도 사용가능.

      Outer.InnerStaticClass is1 = new Outer.InnerStaticClass(); //정적클래스라 외부클래스 객체 안 만들어주고도 외부클래스 이름.내부클래스이름으로 접근 가능.

  - 지역클래스 : 클래스 안에 메소드 안에 위치한 클래스

  - 익명클래스 : 이름을 가지지 않음. 선언과 동시에 객체 생성, 일회용

     Person 이라는 추상클래스에 printInfo라는 추상메소드가 있을 때

    Person p1 = new Person() { 

      @Override

      public void printInfo() { System.out.println("안녕"); } ;  //Person에 있는 추상메소드 구현.

    }


- 입출력

   1. 콘솔입출력

     콘솔 입력 : System.in.read(), InputStreamReader reader = , BufferedReader br = , Scanner scanner = 

       - System.in.read() : char형태로 값 하나만! 받음 123 입력해도 1만 들어가게됨. 문자형태로 받으니까 -'0'을해서 숫자로 변환해줘야함. 데이터 입력하고 enter 누르면 enter도 저장돼서 소진해줘야함. (0이 아스키코드값 48)

     소진 : System.in.read(new byte[System.in.available()]); //이 줄 없으면 1 enter했을 때 남은 enter값이 아래 입력으로 들어감.  // 첨 보는 방식이라 낯설다.

     - InputStreamReader reader = new InputSreamReader(System.in);

       char c[] = new char[3];

       reader.read(c);  //읽고자하는 배열 갯수를 지정해서 읽기 가능.

      sout(c); 

    - BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

      한창 백준 알고리즘 풀면서 Scnner도 까먹을 정도로 많이 사용했는데 안 쓰다보니까 또 낯설어졌다 .. ㅋ

   - Scanner 너무 잘 쓰고 있으니 생ㄱ략

 

     콘솔 출력 : System.out.println/print/pritnf

 

  2. 파일입출력 // 또한 부끄럽게도 .... 파일 입출력을 자바배우고 처음 알았다.

    파일 출력 : 파일로 출력

      - FileOutputStream

      - FileWriter

FileWriter fw = new FileWriter("경로");
String memo = "헤드라인\n";
fw.write(memo);
memo = "1월 28일 소은 생일\n";
fw.writer(memo);
fw.close();

   * 파일 이어쓰기 : 객체 선언 생성 동일한데 객체 다른 이름으로 하나 만들고 경로 다음에 매개변수로 ,true를 넣어줌.    

 

  - PrintWriter : FileWriter과 다른 점은 println이 있어서 줄바꿈을 문자열에 추가해주지 않아도 된다.

PrintWriter pr = new PrintWriter("경로");
String memo = "헤드라인";
pr.println(memo);
pr.close();

 * 파일 이어쓰기 : 객체 생성시 매개변수 안에 FileWriter를 만들어서 넣어줘야함. 상당히 귀찮네

  PrintWriter pr2 = new PrintWriter(new FileWriter("경로",true));

 

  파일 입력 : 파일에서 읽어들이는 입력

     - FileInputStream

     - BufferedReader

BufferedReader br = new BufferedReader(new FileReader("경로"));
while(true){
	String line = br.readLine();
    if(line == null) break;
    else System.out.print(line);
    //println안 해준 이유는 이미 파일 저장할 때 println으로 저장해서 줄바꿈이 되어있음.
}

- 예외 : 정상적이지 않은 케이스 ex) 0으로 나누기, 배열인덱스 초과, 없는 파일 열기 etc...

   - 예외처리 : 정상적이지 않은 case에 대한 적절한 처리 방법

try{
	//오류발생가능코드
}catch(){
	//어떻게 해결할 건지 !
}finally{
	//오류발생여부 상관없이 무조건 실행되는 코드
}

  * throw : 예외발생

    ... 함수명() { throw new Exception(); } 

  * throws : 예외를 호출한 쪽으로 전가시킴.

    ...함수명()  throws xxxException {   } 함수내부에서 예외 발생했을 경우 함수를 호출한 쪽으로 예외를 전가시킴.

//throw 예제
class NotTenException extends RunTimeException{ } 
//사용자가 예외를 직접 만들어줌. 여기서 중요한 건 RunTimeException을 무조건 상속받아야함 !

public class Main{
	public void ten(int num){
    	try{
        	if(num != 10){ //10이 아닐 때 예외를 발생시킴 이부분을 try로 감싸줌
       	 		throw new NotTenException();
            }
        } catch(NotTenException e){ 
        //catch에 매개변수로 들어가는 예외는 발생한 예외랑 동일하게 써줘야함 !
        	System.out.println(e);
           }
    	
    }
    
	public static void main(String args[]){
    	Test t = new Test();
        t.ten(8); //예외가 발생할 거임
    }
}

//throws 예제
public class Main{
	public void ten(int num) throws NotTenException{
    	if(num != 10){ //10이 아닐 때 예외를 발생시킴
       		throw new NotTenException();
        }
    }
    
	public static void main(String args[]){
    	Test t = new Test();
        try{
        	t.ten(8); //예외가 발생할 거임. 이부분을 try로 감싸줌
        }catch(NotTenException e){
         	System.out.println(e);
        }
    }
}

- 컬렉션 프레임워크 : 여러 데이터를 편리하게 다룰 수 있게 만들어 놓은 것 ( 자료구조 및 알고리즘을 구조화)

    대표 인터페이스 : List, Set, Map

    * List 인터페이스 : 순서가 있는 데이터의 집합, 데이터 중복 허용

         대표 구현 클래스 : LinkedList(removeFirst(),removeLast()), ArrayList, Vetcor

   * Set 인터페이스 : 순서가 없는 데이터의 집합, 데이터 중복 X

         대표 구현 클래스 : HashSet(add(값),remove(값)//인덱스가 아니라 원하는 값 바로 지우기 가능 !), TreeSet(이진탐색에 특화된 자료구조래) first() 처음값, Last() 마지막 값, lower(값) 매개변수보다 바로 전 작은 값 하나, higher(값) 매개변수보다 바로 다음 큰 값 하나.

   *Map 인터페이스 : key와 value쌍인 데이터 집합, 순서 유지하지 않음.

         대표 구현 클래스 : HashMap, TreeMap(put으로 자료넣기, firstKey(),firstEntry()//처음 데이터 쌍, LastKey(), LastEntry(), lowerEntry(값),higherEntry(값))

 

*HashSet으로 중복을 피해서 로또 번호 만들기 실습해봄 ! 오름차순으로 정렬할 때 LinkedList list = new LinkedList(set);해서 잠시 List로 바꾸고 Collections.sort(list) 했다.


- 람다식 : 람다식도 혼자공부할 때 어렵게 느껴졌었는데 별 거 아니었구나

   람다 표현식 : 메소드 대신 하나의 식으로 표현하는 것

      익명함수 :

                  반환타입 메소드이름(매개변수 , ...) {     }

                  ex) public int sum(int x,int y) { return x+y }; 를 익명함수로 바꾸면

                       (int x,int y) -> {  return x+y; }// 완전 간단해졌다

  *람다식 장점 : 코드간결, 가독성 높음, 생산성 높음

  *람다식 단점 : 재사용불가능(익명), 디버깅 어려움, 재귀함수로는 맞지않음(이름이 없으니까 !)

 


- 스트림 : 이날 하고 다음날 강의 다시보며 실습하면서 익혔다. 참 편리한 기능이었구나 !!!

  알고리즘 풀 때 스트림 관련 지식을 찾아본 적이 있었는데 그때는 너무 어렵고 복잡해서 포기했었다.

그치만 이제는 포기할 수가 없다. 모르는 건 무조건 알고 넘어가야한다...!

  정의 : 배열, 컬렉션 등의 데이터를 하나씩 참조하여 처리 가능한 기능.

            for문의 사용을 줄여서 코드를 간결하게 함.

            스트림은 크게 3가지로 구성 : Stream 생성, 중개연산, 최종연산

 

1. Stream 생성

//배열 스트림 생성
String str[] = new String{"a","b","c"};
Stream stream = Arrays.stream(str); // 배열이 스트림으로 바뀜
strea.forEach(System.out::println); //forEach는 최종연산

//컬렉션 스트림
ArrayList list = new ArrayList(Arrays.asList(1,2,3,4,5));
Stream stream = list.stream();

//스트림 builder
Stream stream = Stream.builder().add(1).add(2).add(3).build();

//스트림 generate
Stream streamGenerate = Stream.generate( () -> "abc" ).limit(3);
()안에 람다식과 유사하게 어떤 데이터를 만들지 작성. "abc"데이터를 limit만큼 반복생성

//스트림 iterate
Stream streamIterate = Stream.iterate( 10, n -> n*2 ).limit(3);
10은 초기값이고 그 초기값이 어떻게 변할지를 두 번째 매개변수로 써줌. limit는 저 동작을 몇 번 할 지
  출력 값 : 10,20,30

//기본타입 스트림
IntStream intStream = IntStrean.range(1,5); // 1~4까지의 데이터 생성.
rangeClosed이용하면 넣은 끝값까지 데이터 추출가능.

2. 중개연산

//Filtering
IntStream intStream = IntStream.range(1,10).filter( n -> n%2 ==0 );
  filter안의 값이 참이 되는 데이터만 남김
  
//Mapping
IntStream intStream = IntStream.range(1,10).map(n -> n*2);
  모든 요소에 연산을 적용
  
//Sorting
IntStream intStream = IntStream.builder().add(5).add(2).add(3).build();
IntStream intStreamSorting = intStream.sorted(); //정렬됨.

3. 최종연산

//최종연산 forEach,sum,average,min,max,reduce등

//sum, average
int sum = IntStream.range(1,6).sum();

double avd = IntStream.range(1,6).average().getAsDouble();
//마지막 getAsDouble안 하면 이상한 값 나온다

//min,max
int min = IntStream.range(1,10).min().getAsInt();
int max = IntStream.range(1,10).max().getAsInt();

//reduce 좀 어렵다
Stream <Integer> stream = new ArrayList<Integer>(Arrays.asList(1,2,3,4,5)).stream();
System.out.println(stream.reduce((x,y) -> x+y).get());
  연쇄적인 연산으로 데이터 뽑아내기 가능

 

   *Practice 문제로 1~10까지 짝수들의 합을 출력. for문 쓰면 몇 줄 많이 생기는데 stream을 이용하면 한 줄에도 가능했다.

System.out.println(IntStream.range(1,11).filter(n -> n%2 == 0).sum());

 


복습 포스팅만해도 두시간이 넘게 걸린 것 같다.

온라인 강의라 불안함도 조금있고 자바 기초는 아는 내용이다보니 집중도 잘 되지 않았는데 그래도 꿋꿋이 들었다.

위에 쓴 것처럼 알았다해도 완벽하게 알지 못 한 것들, 헷갈리는데 그냥 넘어간 것들, 알았어도 다른 곳에 이용된 사례들을 알게된게 쏠쏠하다. 배운 것들을 알고리즘 문제에도 잘 적용할 수 있게 계속 복기하면서 연습해야 할 것같다.

많은 양을 공부했다고 생각하진 않지만 하루도 빠지지않고 꾸준히 해왔음에 의의를 두고 다음 주는 더 열심히 해보자 

다음 주부턴 테스트도 있을테니 더욱 바빠지겠지만 시간관리 잘해서 화이팅 해보자 !!!