오늘 한일

s사 온라인 코딩 테스트 (대기업 아님)

온라인 코딩 테스트는 해커랭크에서 진행되었다. 총 7문제가 출제됐고, 1문제는 SQL 문제였다. 아스키, 스택, 시간복잡도, json, 그래프, sql 등의 문제가 나왔다.

json 문제는 네트워크를 이용해 API에서 JSON 데이터를 가져와 특정 프로퍼티 목록을 출력하는 문제였는데, 라이브러리를 사용해도 되는지 몰라서 직접 파싱하다가 포기했었다.

그래프 문제는 그림으로 이해는 했는데, 단순 탐색 문제가 아니라 어떻게 코드를 작성해야 할 지 떠오르질 않아서 한 줄도 작성하지 못했다.

SQL문제는 쉬운 문제임에도 불구하고 시간이 오래 걸렸다. 마지막으로 쿼리를 작성한 이후로 2개월 정도가 지났나.... 갑자기 너무 헷갈렸다. 조인으로 해결할 수 있는 문제였는데, 다급한 마음에 서브 쿼리를 사용해버렸다.

마지막으로 시간이 조금 남아서 json 문제를 다시 살펴보니 import에 gson 라이브러리가 이미 추가되어있었다. gson은 입사 후 첫 프로젝트에서만 사용해봤고, 스프링에서 워낙 알아서 잘 파싱해주기 때문에 직접 사용할 일이 거의 없었다. 10분 정도 남은 시간동안 문서를 보면서 풀긴 했는데, 일부 테스트 케이스가 실패했다. page 파라미터와 관련된 케이스 같은데, page 파라미터가 메소드의 인자로 정의되어 있지 않았다. 아직도 뭐가 틀렸는지 궁금하다...

플러터 1/4/7/14 앱 기능 설계

1.0 버전에서는 그룹, 커스터마이징 기능을 제공하지 않는다. 그룹 기능은 2.0에서, 커스터마이징 기능은 3.0에서 제공할 계획이다.

메인 화면

  • 학습 과목 목록을 보여준다.
  • 아이콘/버튼을 클릭하여 학습 과목을 추가할 수 있다.
  • 학습 과목을 클릭하면 과목 상세 화면으로 이동한다.
  • 과목명 필터링 기능을 제공한다.
  • 과목을 길게 선택하여 순서 변경이 가능하다.

과목 상세 화면

  • 과목명을 표시한다.
  • 과목명을 변경할 수 있다.
  • 버튼/아이콘을 클릭하여 과목 삭제가 가능하다.
  • 학습 이력을 표시한다.
    • 학습일자, from 페이지, to 페이지를 입력하고 버튼을 클릭하면 학습 이력이 추가된다.
    • 학습일자는 달력 선택 기능을 제공한다.
    • from 페이지는 마지막 학습일자에 저장된 to 페이지를 읽어와 자동으로 설정한다. (마지막 일자의 to 페이지 + 1)
    • from 페이지는 마지막 학습일자에 저장된 to 페이지 값 이상의 페이지 값만 입력할 수 있다.
    • to 페이지는 현재 일자에 입력된 from 페이지 값 이상의 페이지만 입력할 수 있다.
  • 학습 이력에는 일차/from/to가 표시되며 일차별 정렬이 가능하다.
  • 학습 이력은 최초 일차별 내림차순으로 정렬하여 표시한다.

flutter unit test

void main() {

  test('asdasd', () {
    expect(() => Subjects(null), throwsAssertionError);
  });

  test('Duplicate', () {
    expect(() => Subjects([Subject(0, '', 0), Subject(0, '', 0)]), throwsArgumentError);
  });

  test('Create new Subject from empty subjects', () {
    var subjects = Subjects.empty();
    var subject = subjects.createSubject('subject1');

    expect(subject.pos, Subject.DEFAULT_POS);
  });

  test('Create new Subject from subjects have one element at 1', () {
    var firstPos = 1;
    var subjects = Subjects([Subject(0, 'subject1', firstPos)]);
    var subject = subjects.createSubject('subject2');

    expect(subject.pos, firstPos * 2);
  });
  
  test('Call move when is empty', () {
    var subjects = Subjects.empty();

    expect(() => subjects.move(0, 1), throwsAssertionError);
  });

  test('Pass not contains subject to move', () {
    var subjects = createSubjects(3);

    expect(() => subjects.findById(4), throwsStateError);
  });

  test('Pass larger than length toIndex move', () {
    const lastIndex = 2;
    var subjects = createSubjects(lastIndex + 1);

    expect(() => subjects.move(0, lastIndex + 1), throwsAssertionError);
  });

  test('Move first subject to third in subjects has three elements', () {
    var subjects = createSubjects(3);
    const id = 0;
    const to = 2;
    var second = subjects.findById(id);

    subjects.move(id, to);
    expect(subjects.elementAt(to).id, second.id);
  });
}

Subjects createSubjects(int count) {
  var result = Subjects.empty();
  addSubject(result, count);
  return result;
}

void addSubject(Subjects subjects, int count) {
  for (var i = 0; i < count; i++ ) {
    subjects.createSubject('subject$i');
  }
}

실제 앱 개발에 들어가기에 앞서 순서 변경 기능을 먼저 TDD로 구현해보려고 유닛 테스트를 학습하면서 구현해봤다. 근데 이미 github에 List Drag & Drop 위젯이 있다. 약간 쓸데없는 짓을 한 느낌이 나지만, dart 문법과 유닛테스트에 대해 공부한 셈 쳐야겠다.

오늘 느낀점

코딩 테스트를 볼 때도 전략이 중요한 것 같다. 빠르게 풀 수 있는 문제와 그렇지 않은 문제를 잘 캐치해서, 빠르게 풀 수 있는 문제를 먼저 풀고 최대한 코드를 정리하는데 시간을 많이 할애해야 할 것 같다. 만족할만한 코드가 나오면 그 때부터 오래걸리는 문제를 천천히 풀어봐야지.

역시나 코딩 테스트는 힘들다. 온라인 코딩 테스트도 이렇게 기운이 빠지는데, 오프라인은 얼마나 더 힘들까.....

내일 할일

  • 플러터 1/4/7/14 앱: 메인화면 개발
    • 학습 과목 목록
    • 학습 과목 추가
    • 학습 과목: Drag & Drop을 이용한 순서변경 (일급콜렉션을 적용해보자)
  • 부모님 가게 봐주기
  • 운영체제 복습