2017. 8. 18 - honux

2017.8.17 honux 강의

Junit Test - 유닛테스트, 단위테스트

“method” - 논리적으로 한가지 기능만 가지는 것을 테스트한다.
논리적인 하나의 의미를 가지거나 재활용이 가능한 경우, 반복되는 경우에 분리를 한다.
분리를 하지 않으면 코드의 중복이 발생한다.(가독성이 떨어진다.)
코드의 중복은 수정이 일어났을때 모든 코드를 고쳐야해서 실수의 발생이 높아진다.
단위 테스트는 코드 작성 후 테스트를 하는 것.
TDD는 테스트를 먼저 작성하고 코드를 작성하는 것. - 시간이 많이 걸린다, 코드의 생산성이 많이 떨어진다. TDD는 실제로는 찬반양론이 많기때문에 상황에 맞게 적용.
하지만 유닛테스트를 필수이다. 둘의 차이점은 테스트를 먼저 작성하느냐, 나중에 하느냐의 차이.

컴퓨터 과학

CPU의 단위 - word - 4byte. 프로그램 명령어가 저장되는 곳 - code
모든 프로그램은 하드디스크에 들어있다.
프로그램이 실행될려면 메모리에 올라가야한다.
메모리에 올라간 프로그램을 프로세스라고 부른다.
자바 컴파일 파일(.class)은 바이트 파일이라는 파일이 생성된다. (기계어가 적다.) 자파 클래스 파일은 JVM에 의해서 실행된다. 제임스 고슬링은 자바를 냉장고 같은 가전기기에 사용할려고 만들었으나. 브라우저 인터넷에 애플릿덕분에 유행했다.

clock pc 메모리 레지스터 캐시

가상메모리

메모리 코드 데이터 힙 스택

포인터와 참조 스택에 지역변수를 저장하는 이유는 쉽게쓰고 버릴려고.

Student s = new Student()

Student s 는 지역변수 - 스택 new Student 는 인스턴스 - 힙 스택은 힙의 주소값을 가진다.

네이버 블로그 헬로우 월드 - 가비지 컬렉터

알고리즘

복잡도(Complexity) - 분석

  • 성능 분석을 위해 사용됨
    응답시간 - 얼마나 빨리 응답이 오는가? , 수행시간 - 얼마나 프로그래밍이 빠르게 완료되는가?

공간복잡도 - 얼마나 적은 메모리와 디스크를 사용하는가?
시간복잡도 - 얼마나 프로그램이 빨리 완료되는가?

점근 표기법 (Asymptotic notation)

  • 알고리즘 복잡도를 단순히 표현하기 위해 사용됨.
  • Big-O 표기법이 가장 유명 빅오에서 g(x)는 최악의 경우 (성능 상한선 )

프로그램 성능에서 중요한건 가끔 느려질때 왜 느려졌는지를 알아내야한다.

JFC(Java Collection Framework)

  • Collection 객체를 묶어서 표현하는 객체

Class : state + behavior

class -> Instance : 객체

상속은 클래스를 확장하기 위해서 쓰고 싶은 것.

처음부터 확장을 못하는 이유

  1. 남이 먼저 만들어 놓은 클래스
  2. 2가지의 클래스를 유사하게 만들고 싶어서(공통된 요소도 있지만 다른 요소도 있을 때 사용)

Abstract class : 객체를 못만드는 클래스
그 자체로는 쓸모가 없다. 하지만 상속을 사용해서 사용한다.
코딩을 할때 스펙(코딩스타일을 강제하기위해)을 위해 필요하다.
고양이를 만들라면 만들 수 있지만 포유류같은 상위 개념을 표현하기 위해 가상 메소드가 필요하다.
기능을 제한하기 위해 Abstract를 만들 수 있는데 이 개념의 끝에 위치한게 Interface라고 할 수 있다.

객체지향 프로그래밍은 클래스와 클래스간의 메시지를 주고받는것이 중요하다.
인터페이스를 이용하면 이것을 잘 정의 할 수 있다.

집합 : 원소의 중복이 없다.

Abstract클래스는 어떤 것은 구현이 되어있다. interface는 구현이 안되어있다. 배열에서 O의 복잡도를 찾는건 O(1)이다.

ArrayList는 Size가 내부적으로 고정되어있다. 사이즈가 찰때마다 사이즈를 자동으로 늘이므로 느려진다. 탐색이 빠르다. LinkedList는 삽입 삭제는 빠르다. 탐색은 느리다. - 삽입과 삭제가 빈번할때 사용하면 좋다.

자바8에서 인터페이스가 가질 수 있는 것들.

  1. 상수 필드 (public static final)
      public interface Parent{
       public static final int MAX_VALUE = 100;
       public static final int MIN_VALUE = 0;
      }
    
    • 인터페이스에서 선언된 상수는 implements된 Class에서 바로 사용 가능
       class A implements Parent {
         int max = MAX_VALUE;
         int min = MIN_VALUE;
       }
      
  2. 추상 메소드 (public abstract)
      public interface Parent {
     public abstract void run();
      }
    
  • 추상메소드는 implements 한 Class에서 무조건 Override해야함(강제)
    class A implements Parent {
        @Override
        public void run() {
          //run() 메소드를 선언하지 않을 시 에러발생
          //The type ParentTest must implement the inherited abstract method Parent.run()
        }
    }
    
  1. 디폴트 메소드 (public default)
      public interface Parent {
     public default void setState(boolean state) {
       if(state) {
         System.out.println("현재상태는 true입니다. 인터페이스에서 구현된 내용입니다.");
       } else {
         System.out.println("현재상태는 false입니다. 인터페이스에서 구현된 내용입니다.")
       }
     }
      }
    
    • 위와 같이 인터페이스안에 디폴트 메소드를 구현하면 implements한 클래스에서는 setState 메서드를 그대로 사용해도 되고 아니면 필요에 맞게 재정의(오버라이딩)해도 된다.
    • 기본적으로 디폴트 메소드는 모든 구현 객체(클래스)에서 공유하는 기본 메소드 용도로 사용할 수도 있지만, 이전에 먼저 개발한 구현 클래스를 그대로 사용하고 변경하지 않으면서, 새롭게 개발하는 클래스는 디폴트 메소드를 사용해 새로운 내용을 구현할 수 있다.
         public interface 포유류 {
       public abstract void 먹다();
      
       public default void 날다() {
         System.out.println("모든 포유류가 날 수 있지는 않지만 이 기능을 구현한 객체는 날 수 있다.");
       }
         }
      
        public class 박쥐 implements 포유류{
          @Override
          public void 먹다() {
            // 포유류를 implements한 클래스는 모두 먹다() 메소드를 구현해야합니다.
            public void 먹다() {
              System.out.println("배가 고픕니다. 밥을 먹읍시박쥐.");
            }

            public void 날다() {
              System.out.println("박쥐가 날다날다");
            }
          }
        }

        public class 다람쥐 implements 포유류{
          @Override
          public void 먹다() {
            // 포유류를 implements한 클래스는 모두 먹다() 메소드를 구현해야합니다.
            public void 먹다() {
              System.out.println("배가 고픕니다. 밥을 먹읍시다람쥐.");
            }

            //다람쥐는 날지 않으므로 날다() 메소드를 구현하지 않습니다.
          }
        }

        public class 참새 implements 포유류{
          @Override
          public void 먹다() {
            // 포유류를 implements한 클래스는 모두 먹다() 메소드를 구현해야합니다.
            public void 먹다() {
              System.out.println("배가 고픕니다. 밥을 먹읍시참새.");
            }

            //참새를 날 수 있지만 굳이 재정의를 하지 않아도 날다 메소드를 사용 할 수 있습니다.
          }
        }
  • 위 예제 처럼 디폴트 메소드는 구현해도되고 오버라이드 해도되고 아무것도 하지않아도 됩니다. 이미 개발된 코드가 있을때 새로운 기능을 추가해야한다면 기존의 클래스들에 오류를 발생 시키지 않고 인터페이스에 디폴트 메소드를 선언해서 다른 클래스에 추가 할 수 있습니다.
  1. 정적 메소드(public static) ``` public interface 생물 { public static void 숨쉬다() { System.out.print(“모든 생명체는 숨을 쉬어야합니다.”); } }
public class 인간 implements 인간 {
    void 활동() {
      생물.숨쉬다(); // 인간을 숨을 쉬어야 활동을 합니다.
    }
}
```

* 정적 메소드는 위와 같이 ```생물.숨쉬다();```와 같이 객체가 없어도 인터페이스만으로 호출 할 수 있습니다.
  1. 익명 구현 객체
    • 자바 8에서 지원하는 람다식은 인터페이스의 익명 구현 객체를 생성 할 수 있도록 추가되었습니다. 이 기능은 주로 UI프로그래밍에서 이벤트를 처리하거나, 임시 작업 스레드를 만들기 위해서 유용하게 사용되어 질 수 있다고 합니다.
       인터페이스 변수 = new 인터페이스() {
         // 인터페이스에 선언된 추상 메소드의 실제 메소드 선언
       };
    
           * 예시  ```    public class 예시 {
     public static void main(String[] args) {
    
         포유류 포오오오오유류 = new 포유류() {
           public void 먹다() {
             //실제 구현 내용
             System.out.println("먹다 먹다 먹다 먹다 마구 먹다");
           }
         };
    
     }    }  ```  * 위의 포유류 인터페이스를 예제로 사용하였다. 인터페이스의 가상 메소드인 먹다를 인터페이스의 익명 객체를 선언하여 사용할 수 있다.  * 익명 구현 객체도 예시.java 컴파일 시 예시$1.class와 같이 이름뒤에 $가 붙고 생성 번호가 붙는 class 파일이 생성된다.
    

Comments