모의면접에서 받았던 질문에 대한 답을 다시 정리해보려고 합니다.
1. 추상화 vs 캡슐화
캡슐화: 객체가 내부적으로 어떻게 구현되어있는 지 감추는 것 (숨기는 것)
추상화: 클래스 구현 세부 사항과 동작을 분리하는 것.
2. 숨기면 다 캡슐화가 되나?
지금 생각해보면 이 질문에 대한 대답은 no라고 생각된다. 그 이유는, 숨기기만 하고 외부에서 숨긴 데이터 조작이 가능하다면, 그것은 진정한 캡슐화라고 할 수 없기 때문이다. 우선, 캡슐화를 하는 목적은 객체의 내부 구현을 감추어 내부 구현의 변화가 일어나더라도 협력하는 외부 객체에 변화의 영향이 퍼져나가지 않도록 막기 위함이다. 앞서 말한 것처럼 숨기기만 하고 getter를 통해 데이터를 넘겨주고, 심지어 넘겨받은 데이터를 외부에서 조작 및 변경이 가능하다면 즉, 객체의 내부구현이 드러난다면 이는 진정한 캡슐화를 했다고 이야기할 수 없다고 생각한다.
3. 어떤걸 숨기면?
우선 캡슐화는 변화할 수 있는 어떤 것이든 다 숨기는 것을 말한다. 변화할 수 있는 어떤 것이라함은 속성, 타입, 종류 등 어떠한 변화할 수 있는 것이라도 내부 구현 변경으로 인해 외부가 영향을 받을 수 있다면 일단 숨기고보자!이다.
왜 일단 숨기고 보냐? 어떤 장점이 있길래?
객체지향 설계는 책임을 갖는 객체들의 결합으로 이루어진다. 각 객체는 자신에게 주어진 책임을 다하는 것이 목적이되, 다른 객체의 변화로 인해 그와 협력하고 있는 또 다른 객체가 영향을 받는다면 이는 좋은 설계라 할 수 없다. 따라서 변화할 수 있는 것을 숨기고, 숨긴 객체에 그 변화할 수 있는 것과 관련된 책임을 모두 맡긴다. (면접에서도 그랬지만 지금 이 글을 쓰면서도 횡설수설하는 것 같다. 어떡하지..)
4. enumMap 을 사용한 이유?
이번에 enum을 사용하고, 이 enum이 key가 되어 View에 Map으로 넘겨질 경우가 있다면 모두 enumMap을 사용했다.
그 이유는, enumMap을 사용했을 때 enum에서 나열된 순서가 보장되었기 때문이다.
나는 enum을 설계할 때 순서를 중요시하는 편이다. (특히 3개 이상인 경우) 따라서 enum을 키 값으로 넘겨줄 때 Map으로 구현 시 값이 변화할 수 있지만, enumMap을 사용하면 enum의 순서가 자동으로 보장되기 때문에 믿고 사용할 수 있어 enumMap을 사용했다. 더불어 속도도 빠르다고 하지만, 아직까지 그에 대해서 직접 체감한 적은 없다.
5. 자바의 scope에 대해 아는가?
면접 볼 때도 몰랐고, 지금도 몰라서 다시 공부해보았다.
우선 변수의 스코프란 프로그램에서 사용되는 변수들은 사용 가능한 범위를 가지는데, 이를 스코프라고 한다. 즉, 변수가 선언된 블럭이 그 변수의 사용범위이다. 지역변수 , 멤버변수 순으로 우선순위를 가진다.
참고 - tuhbm.github.io/2018/06/24/javaScope/
6. Test 코드 컨벤션?
Test 코드를 짤 때 나만의 약속으로는 given-when-then 구조를 활용하였다. given-when-then 구조를 활용한 이유는 이 구조 없이 테스트를 작성했을 때 로직이 눈에 그려지지 않았기 때문이다. given-when-then을 사용하면 주어진 값과, 현재 조건과, 그 이후에 내가 테스트하고 싶은 결과값을 순서대로 확인할 수 있어 가독성이 좋았기 때문에 사용했다.
7. tdd vs unit test
정의를 물어보는 것인지..? 솔직히 말하면 정의도 아직은 잘 모르겠다. 그래서 찾아보고 정리한다.
TDD란 테스트 주도 개발 방법론으로 개발하는 과정에서 테스트 스크립트를 작성하고, 그 코드를 돌려가며 프로덕션 코드를 완성하는 것을 말한다.
- 참고 : nesoy.github.io/articles/2017-01/TDD
Unit Test란 모듈이나 애플리케이션 안의 개별 코드 단위가 예상대로 작동하는 지 확인하는 행위이다. 프로덕션 코드를 테스트하는 코드의 형태를 취한다.
즉, 프로덕션 코드를 작성하기 전 먼저 원하는 기능을 그리고, 그 기능단위로 unit Test를 수행하는 것이 tdd라고 할 수 있다. (뇌피셜)
8. jUnit 사용 이유?
이 질문은 피카가 했었는데, 사실 의도를 물어볼 걸 조금 아쉽다. 하고 많은 테스트 프레임워크들 중 JUnit 이라는 프레임워크를 왜 사용하게 되었는지를 묻는 것인지, 아니면 테스트하기 위해 JUnit을 사용하는 이유를 묻는 것인지 애매하다.
후자에 대해 답변하자면, 우선 JUnit을 사용하는 이유는 설계하고 만든 프로덕션 코드가 내가 의도한대로 잘 동작하는지를 확인하기 위해 사용했다. 테스트를 활용하지 않으면 구문마다 System.out.println을 달아 콘솔에 찍히는 내용을 확인해야했고, 이는 매우 번거로웠으며 가끔 똑같은 말을 출력하도록 해 놓은 경우에는 알아보기가 어려웠다. 하지만 테스트 프레임워크인 JUnit을 사용하므로서 기능 단위, 메서드 단위로 쪼개어 테스트해볼 수 있었고, @Display annotation을 통해 주석과 같은 개념의 설명도 달 수 있었기 때문에 문서로서의 역할도 할 수 있었다.
9. 커스텀예외를 적절한 때에 적절히 사용한다 했는데 적절한 때가 언제?
클래스명을 통해 예외를 확인해야할 때 사용하는 것이 좋다고 생각한다. spring프로젝트를 통해 controllerAdvice 내부에서 각 Exception을 핸들링할 수 있었다. 이러한 경우 클래스명을 통해 예외 처리 경로를 라우팅할 수 있고 그에 따라 알맞은 리스폰스를 줄 수 있기에 이러한 경우가 커스텀 예외를 사용하기 적합한 경우라고 생각한다. (면접볼 땐 그지같이 대답했었는데 그나마 좀 나아진 듯)
10. 컴파일, 런타임 어느 때 오류나는 것이 좋은가?
런타임에 나는 오류는 잡기 힘들고, 컴파일 타임에 나는 오류는 찾기는 좋지만 프로그램 실행 조차 되지 않기 때문에 이 또한 불편하다. 오류는 안나는 것이 제일 좋다고 생각한다.