5주차 1 - CodingInterviewStudy/CrackingTheCodingInterview GitHub Wiki

테스팅

  • 테스팅 관련 질문
    • 실행활에서 접하는 객체를 테스트하라
    • SW 하나를 테스트하라
    • 주어진 함수에 대한 테스트 코드를 작성하라.
    • 발생한 이슈에 대한 해결책을 찾아내라.
  • 사용자의 행동 = 항상 예측 가능한 것 아님

각각의 접근법에 대해 알아보자.

면접관이 평가하는 것

  • 큰 그림 이해
    • SW의 목적
    • TC 우선순위 결정
    • 아마존 사례
      • 상품이 적절한 곳에 뜨는지 < 구매대금이 지불됬는지, 배송목록에 추가됬는지
  • 퍼즐 조각 맞추는 방법
    • SW가 큰생태계 일부로 어떻게 껴맞춰지는지
    • 구글 스프레드시트 사례
      • 문서 열고, 저장, 편집 테스트 과정이 중요하지만, 더 큰생태계인 Gmail이나 플러그인 등 다른 시스템과 제대로 통합되는지 테스트해야한다.
  • 조직화
    • 문제 구조적으로 접근하는지 확인.
    • 사례 카메라 테스트의 경우 사진촬영/이미지관리/설정 으로 범주를 나누자.
  • 실용성 (적용가능성)
    • 사례
      • 어플이 특정이미지 여는 순간 다운이 된다. 근데 재설치하라고 권유한다면, 실용적인 답 X

실제 세계에서 객체 테스트하기

  • 이런 질문도 들어온다. -> "펜을 테스트하라", "클립을 테스트하라"
  • 1단계
    • 먼저 용도 찾기. 면접관과 의논 필요. e.g. 사용자는 누가? 클립 사용목적은?
  • 2단계
  • 3단계
    • 한계 적용, 온도에 따라 클립이 잘 손상될수도 있다고 가정한다면. 테스트 결과를 다르게 잡아야.
  • 4단계
    • 스트레스 조건과 장애 조건 고려 하기.
    • 세탁기 - 너무 많은 의류 잘 안빨림.
  • 5단계
    • 테스트 어떻게 하지? (=세부사항 토론)
    • 의자를 5년 사용할 수 있는지 테스트, 진짜 5년 해야되나? 자동화 도입

Software Testing

  • 2가지 핵심 측면
    • 수작업 vs 자동화 테스트
      • 포르노 콘텐츠 포함 확인 (수작업 추천)
    • 블랙박스 vs 화이트박스 테스트
      • 화이트박스 = 내부 까지 들여다 보며 테스트
      • 블랙박스 테스트는 자동화가 어렵다. 왜죠?
        • 아마... 안에 코드가 안보이기 때문에, 로직이 어떻게 될지 몰라서 일거 같습니다.

테스트에 적용가능한 접근법 ("실제 세계에서 객체 테스트하기"를 소프트웨어적으로 생각한다면)

  • 1단계
    • 블랙박스인가 화이트박스인가? (먼저 물어보기)
  • 2단계
    • 사용자누구? 사용목적?
  • 3단계
    • 어떤 유스케이스가 있는가? (뽑아내기 위해 면접관과 지속적 의사소통하기)
  • 4단계
    • 한계조건?
  • 5단계
    • 스트레스 조건과 장애조건?

실제 개발사례에 적용한다면,

  • (사용자, 사용목적)
    • 부모가 자식의 브라우저를 통제하는 소프트웨어
      • 사용자: 부모와 아이
      • 목적: 브라우저 통제.
  • (유스케이스)
    • 부모 - 설치, 차단기능 활성화or해제, 인터넷 사용,
    • 아이 - 불법 콘텐츠 접근 or 합적 콘텐츠 접근
  • (한계조건)
  • (스트레스, 장애 조건)
    • 장애발생시, 그장애는 어떤 모습이어야 되는지. 차단된 사이트에 접속이 가능해진다거나 vice versa. 이런것은 면접관과 이야기 나눠야한다.
  • (테스트 케이스는? 테스트실행은?)
    • 여긴 수작업과 자동화 테스트가 구별되는 지점이다. 블박, 화박을 실제로 하게되는 지점이기도하다. 3,4단계를 상세히 어떻게 수행할지 이야기 한다. 어떤상황테스트? 어떤단계 자동화? 사람개입부분 어디?
  • 요약, 테스트를 체계적으로 접근하라.

함수 테스트

주로 입력과 출력만 확인. 사례 질문: sort(int[] array) 테스트는 어떻게하나요?

  • 테스트케이스 정의

    • 정상적 케이스
      • 파티셔닝이 필요한 경우, 배열길이 홀수면, 정확히 반으로 분할 안되니, 테스트케이스가 이에 대해 잘 작동되는지.
    • 극단적 케이스
    • null 또는 illegal 입력
      • 예, 피보나치에 음수가 들어오면
    • 특수한 입력
      • 이미 정렬된 배열이 들어오면? 아님 역순이면?
  • 예상되는 결과를 정의하라.

    • 새로운 정렬된 배열을 만들어서 넘기는 조건이 있으면, 기존 배열이 변경되지 않았는지에 대한 확인
  • 테스트 코드를 작성하라.

    • void testAddlhreeSorted() {
          MyList list = new MyList();
          list.addThreeSorted(3, 1, 2); // 원소를 세개 추가한다.
          assertEquals(list.getElement(0), 1);
          assertEquals(list.getElement(1), 2);
          assertEquals(list.getE1ement(2), 3);
      }
      

문제 해결에 관한 문제

질문 사례: 주어진 장애 어떻게 디버깅하고 해결할지를 설명하라. 크롬 브라우저가 죽는다. 어떻게 해결?

  • 1단계: 시나리오 이해하기
    • 적절한 질문 찾기.
    • 언제부터? 브라우저 버전은, OS버전은? 발생 빈도는? 주로 언제 발생? 오류 보고서가 뜨는가?
  • 2단계: 문제 쪼개기
    • 테스트 가능한 단위로 분할하자.
    • 시작메뉴 -> 크롬 클릭 -> 브라우저 시작후 설정 읽어드린다. -> HTTP 요청/응답 -> 웹파이지 파싱 -> 화면 표시
    • 여기서 어디서 문제가 발생하는?

면접 질문

11.1 다음 코드에서 실수를 찾아라.

unsigned int i;
for (i = 100; i >= 0; --i) 
    printf("%d\n", i); 

답: unsigned int는 항상 0보다 크거나 같다. 그래서 무한루프가 돈다.

unsigned int i;
for (i = 100; i > 0; --i) // 수정된 코드 
    printf("%d\n", i);

11.2 실행 중 죽어버리는 프로그램의 소스코드가 있다. 디버거에서 10번 실행해본 결과, 같은 지점에서 죽는 일은 없었다. 이 프로그램은 단일 스레드 프로그램이고, C의 표준 라이브러리만 사용한다. 프로그램에 어떤 오류가 있으면, 이런 식으로 죽겠는가? 그 오류들을 어떻게 테스트해볼 수 있겠는가? 원인 -해결방법

  • 1 랜덤 변수
    • e.g. 사용자 입력, 프로그램에서 생성된 나수, 프로그램 실행 시각 등
  • 2 초기화하지 않은 변수
    • 어떤 프로그래밍 언어는 임의의 값을 해당 변수에 할당해 버린다. 그러다 보면 실행 할때 마다 프로그램이 살짝 다른 경로로 실행될 수 있다.
  • 3 메모리 누수
    • 메모리 부족한 경우 일 수 있다. 죽는 시점 몇개의 프로세스가 돌고 있냐 체크. 힙 오버 플로우나 데이터 손상 등도 이 에러에 포함된다.
  • 4 외부 의존성
    • 프로그램이 다른 응용프로그램, 다른 자원에 의존하고 있을 수있다. 의존성이 많다면 언제든지 죽을 수 있다.

누가 실행? 하는일은? 어떤 종류 프로그램? 죽는 시나리오가 있는가 (항상존재)? 예를들어, 파일을 로드만하면 죽는 프로그램은 파일 I/O와 같은 저수준 컴포넌트 때문일 수 있다.

해결방법으로, 제외(elimination) 기법을 사용하면 좋다. 예를들어, 비활성화 할 수 있는 부분 다하고, 다른 프로그램들 닫는다.

11.3 체스 테스트: We have the following method used in a chess game: boolean canMoveTo(int x, int y) x and y are the coordinates of the chess board and it returns whether or not the piece can move to that position. 이 메서드를 어떻게 테스트 할 수 있겠는가?

// Piece 클래스
// x,y 지점으로 이동할 수 있는지
boolean canMoveTo(int x, int y){}
  • extreme case validation
    • x나 y가 음수인 경우
    • x가 체스판 폭보다 큰 경우
    • y가 체스판 높이보다 큰경우
    • 체스판이 꽉 찬 경우
    • 거의 비어있는 체스판
    • 검은색 말보다 흰색말이 훨씬많은경우 또는 그 반대
    • false를 return 또는 예외 return? 면접관과 상의하기
  • general case testing
    • 체스는 여섯종류 말이 있는데, 한 말씩 가능한 모든 방향을 검사한다.
    • 모든 시나리오 보단 핵심적부분만 집중.

11.4 테스트 도구를 사용하지 않고, 웹페이지 부하 테스트를 실행하려면 어떻게 하면 되는가?

  • 부하테스트 함으로써,
    • 최대 감당할 수 있는 용량 알 수 있다.
    • 병목구간 알아낼수 있다.
    • 목표치 충족 지표 예시
      • response time
      • throughput
      • resource utilization
      • maximum load
    • 수천명 가상 사용자 만들어 보기 (다중 쓰레드 잘 작동되는지 확인 가능)

11.5 분산 은행 업무시스템을 구성하는 ATM을 어떻게 테스트하겠는가?

  • ATM 사용자는 누구인가? 시각장애인이 사용하려한다면?
  • 무슨용도? 인출/이체/조회
  • 테스트에 사용할 수 있는 도구는 무엇인가? 기계만 주어지나?
  • 컴포넌트로 나누기
    • 로그인
    • 인출
    • 입금
    • 조회
    • 이체
  • 수동 테스트
    • 잔액 부족, 존재하지 않는 계좌 등
  • 자동화 테스트
    • 시나리오 기반, e.g., race condition
    • 폐쇄 (closed) 시스템이 이상적이다.
    • 무엇보다 보안, 안정성을 최우선