티스토리 뷰

예상 질문 정리

✔️ 기본질문

  • 자기소개
  • 장/단점
  • 앞으로 어떤 개발자가 되고 싶은지

✔️ 기술질문

자료구조

  • 왜 배열을 안 쓰고 리스트 사용하는지?
    : 배열과 제네릭 타입은 2가지 차이를 가진다. 배열은 계층구조가 있다면, 상위 타입이 변하면 같이 변한다. 하지만 제네릭(리스트)타입은 계층구조가 아니기 때문에 관련이 없다. 배열은 실수를 런타임에 알지만, 리스트는 컴파일타임에 알 수 있다. 배열을 런타임에도 자신이 담기로 한 원소의 타입을 인지하지만 제네릭은 타입정보가 런타임에는 소거된다. -이펙티브자바_아이템28
  • LinkedList 자료구조는? 어떤 특징?
    : 연속적으로 저장되는 타입이 아니라 각 노드들의 연결관계를 가지고 있는 자료구조이다. 리스트의 삽입, 삭제는 O(n)이고, 검색은 O(1)이지만, 링크드리스트는 삽입과 삭제가 O(1)이고 조회가 O(n)이다.
  • 방어적 복사와 unmodifiableList() 반환의 차이는?
    : 방어적복사는 객체 외부와 내부의 관계를 새로운 객체를 만들어 사용하여 연결고리를 끊어준다. 리스트를 사용할 경우, new ArrayList();를 사용하여 연결고리를 끊는다. 외부의 변화와 상관 없이 객체 내부의 고유한 값을 유지할 수 있다. 주소값 자체가 다르다. unmodifiableList()로 반환하는 경우는 불변객체를 리턴하는 경우에 사용된다. add 등의 수정작업이 이뤄질때, 예외를 던진다. 주소값은 동일하기 때문에 방어적 복사는 아니다.

상속

  • 상속을 사용하는 이유?
    : 상속의 가장 큰 특징은 계층구조이다. 계층구조를 통해 객체를 관리하기 위해 사용한다. 코드의 중복을 줄일 수 있으며, 계층의 속성을 확대하여 사용할 수 있다.
  • 상속과 조합의 차이
    : 상속은 계층구조를 물려받아 해당 특성을 이용하게 된다. 하지만, 조합은 해당 특성을 가진 객체를 속성으로 갖는다. 상속과 조합이 같은 기능을 한다고 하더라도 가장 큰 차이는 계층 구조를 만들어내는가 아닌가라고 생각한다.  
  • 인터페이스와 추상클래스의 차이 (Interface VS abstract class)? 언제 어떤 것을 사용하는지?
    : 인터페이스는 속성을 가지 않으며 할 수 있는 기능에 초점이 맞춰져 있다. 추상클래스는 속성을 가질 수 있으며, 메소드의 구체화도 가능하다. 추상메소드 1개만 있다면 추상클래스가 된다. 이 두가지의 특성 중 가장 큰 것도 계층 구조를 이루는지 아닌지라고 생각한다. 인터페이스는 계층구조를 가지지 않고, 역할에만 집중하기 때문에 좀 더 유연한 특성을 가진다.
  • 상속과 캡슐화는 어떤 관계를 가지는지?
    : 상속은 캡슐화를 깨뜨린다. 캡슐화는 실제 구현내용을 내부로 감추는 것을 의미한다. 하지만, 상속을 사용할 경우, 자식 클래스가 자신의 내부 구현을 잘 알고 있어야 사이드이펙트를 줄일 수 있다. 부모 클래스의 구현 변경에 따라 자식 클래스도 영향을 받는다. 이런 점에서 상속은 캡슐화를 깨뜨린다.

Enum

  • Enum이란? 왜사용? 어떤 특징?
    : 열거형이라고 하며 서로 연관된 상수들의 집합이다. 각각이 하나의 클래스의 인스턴스이다. Enum은 싱글톤 객체를 만들 수 있는 가장 안전한 방법이라고 한다.
  • EnumMap의 특징?
    : Map에서 Key 값으로 가지고 있기 위해서는 해싱작업이 이루어지는데 EnumMap은 이미 알고 있는 키이기 때문에 빠른 해싱이 가능하여 성능적으로 좋다. orderedMap으로 Enum에 명시된 순서를 유지한다.

Test

  • TDD의 장단점, 왜 하는지?
    : TDD는 TestDrivenDevelopment로 실패하는 테스트를 구현한 뒤, 통과하는 테스트를 만들기 위한 프로덕션 코드를 작성하는 방식으로 개발하는 방법론이다. TDD를 하면 작성하는 모든 프로덕션코드에 대한 테스트코드를 작성하게 되기 때문에 촘촘한 테스트를 작성코드를 작성하게 된다는 장점이 있다. 또한, 테스트 하기 쉬운 코드는 좋은 코드인 경우가 많으므로 더 유연한 코드를 작성하게 될 가능성이 높다. 하지만, 대체로 시간이 더 오래걸리는 단점이 생긴다.
  • 테스트코드 왜 짜는지?
    : 테스트를 작성하는 것은 빠른 피드백을 위함이다. 개발자들은 머릿속으로 시뮬레이션을 통해 코드 개발을 진행하게 될 것이다. 어떤 상황에서 이 부분은 이렇게 동작할 것이다라고 생각하고 구현한다. 이것이 제대로 동작하는지를 확인시켜주는 것이 테스트코드이다. 자동화된 테스트코드를 통해 해당 동작에 대한 신뢰를 가지고 개발을 진행하게 된다.
  • 점진적 리팩토링 경험?
    : 체스게임을 리팩토링하면서 각 말이 Position 속성을 가지고 있다가 제거하게 된 경우가 있었다. 이렇게 하면서 각 피스에 대한 정보는 물론 점수계산 로직도 수정이 일어났다. 중복코드를 생성하며 점진적 리팩토링을 진행해나갔다. 한군데 수정으로 몇십군데의 컴파일 에러가 날 수 있음을 경험하고나서는 점진적 리팩토링의 중요성에 대해 느끼게 되었다. 또한, 그만큼 객체간의 강한 결합을 가지고 있었다는 점도 알 수 있었다. 점진적 리팩토링을 하면 어느 부분까지 에러없이 동작하는지 알 수 있고, 돌아가는 서비스를 유지한 채 리팩토링을 진행하게 되어 안정감을 준다.

객체지향

  • 원시값을 포장하는 이유?
    : 객체를 더 객체답게 활용하기 위함이다. 원시값을 포장하면 유의미한 객체가 된다. 객체로써 자신을 나타내며, 유효성 검증, 역할 등을 자신이 책임지게 된다. 서비스가 커질수록 각 객체가 맡은바 역할과 책임을 다하는 것이 중요하다고 생각한다. 유의미한 값에 그런 역할과 책임을 주는 것이 원시값을 포장하는 이유라고 생각한다.
  • 불변객체를 사용하는 이유?
    : 동시성문제 때문에 불변객체를 사용한다. 동시에 객체에 접근할 경우 기대와 다른 결과가 나올 수 있는데, 이런 문제를 불변객체를 통해서 해소할 수 있다.  
  • 객체지향 SOLID
    : S(단일책임원칙 - 클래스는 단 하나의 책임을 가져야 한다.)
      O(개방폐쇄원칙 - 확장에는 열려 있어야 하고, 변경에는 닫혀 있어야 한다.)
      L(리스코프치환원칙 - 상위타입의 객체를 하위 타입의 객체로 치환해도 정상작동해야 한다.)
      I(인터페이스분리원칙 - 인터페이스는 클라이언트 기준으로 분리되어야 한다.)
     D(의존역전원칙 - 고수준 모듈은 저수준 모듈 구현에 의존해서는 안된다.)
  • 일급컬렉션의 사용이유? 일급컬렉션은 무엇인가?
    : 자료구조형을 객체로 감싸 관리하는 것을 일급컬렉션이라고 생각한다. 이것은 원시값을 포장하는 이유와 같다. 객체가 가질 수 있는 자료를 직접 관리하면서 책임과 역할을 하기 위함이다. 자료의 갯수나 추가조건, 삭제여부 등에 제약조건을 부여할 수 있으며 객체의 조건의 맞게 자료구조를 사용할 수 있다. 
  • 방어적 복사를 사용하는 이유?
    : 외부와 객체 내부와의 관계를 끊어 객체 내부의 값을 더 고유하게 유지하기 위함이라고 생각한다. 

디자인패턴

  • 상태패턴의 사용이유?
    : 기능이 상태에 따라 다르게 동작해야할 때 사용하는 패턴이다. 상태별로 처리코드를 분리하기 때문에 코드가 간결해지고 새로운 상태의 추가에 따른 변화가 적다. 상태에 따라 동작을 관리하기 편리하다.
  • 전략패턴은 무엇이고 어떤 특징을 가지는가?
    : 동일 계열의 알고리즘군을 정의하고(인터페이스), 각 알고리즘을 캡슐화하여(구체 클래스) 상호교환이 가능하게 만든 패턴이다. 개방폐쇄 원칙을 따르게 되며 구체화된 알고리즘의 교체가 편리하다. 의존성 주입과 함께 많이 사용된다.

java8 - Stream, Functional Interface

  • Stream은 무엇이고 어떤 특징이 있는지?
    : 스트림은 선언형으로 데이터를 처리가능하게 한다. for문 등으로 외부반복으로 데이터를 처리하면 어떻게(how) 처리할 것인지에 대해 관심을 가지게 되나, 스트림으로 처리하면 내부반복을 통해 무엇을(what) 결과값으로 받을 것인지에 집중할 수 있다. 메서드 체이닝으로 가독성이 좋아진다. 내부반복으로 인해 게으른 처리가 가능하며 원하는 결과 값만 처리하며, 병렬 처리를 보다 쉽게 가능하게 한다.
  • Map, flatMap의 차이점?
    : map은 각 배열을 스트림으로 매핑한다. flatMap은 스트림의 각각의 값을 다른 스트림으로 만든 다음 모든 스트림을 하나의 스트림으로 연결하는 기능을 한다. 스트림의 컨텐츠로 매핑한다.
  • Functional Interface에 대해 설명?
    : 함수형 인터페이스는 자바에서 함수를 값처럼 사용하기 위해(일급시민처럼) 사용된다. 동작 파라미터화를 가능하게 하며 동작(함수)를 인자로 받아서 실행가능하게 한다.

생성자 관련

  • Builder 패턴은 무엇인가? 언제 사용하는가?
    : 생성자에서 받는 인자의 수가 많을 때 사용할 수 있다. 꼭 필요한 값은 Builder를 만들 때 초기화해주고, 추가적인 값들은 체이닝을 통해 선택가능하다. 인자가 많으나 final로 지정되지 않은 선택적 속성이 많을 때 사용하면 좋다. (계층적으로 설계된 클래스에서 함께 사용하기 좋다고 한다.)
  • 생성자 관련하여 다양한 생성자를 사용하는 이유는?
    : 생성자가 다양하면 그 객체를 사용할 수 있는 방법을 늘려 활용도를 높여준다고 생각한다. 마치 지원하는 형태의 API가 많은 것과 같다.
  • 정적팩토리 메소드의 특징과 언제 사용하는지?
    : 일반적으로 생성자를 통해서 인스턴스를 생성하지만, 그 클래스의 인스턴스를 반환하는 메소드를 정적 팩토리 메소드라고 한다. 생성자역할을 하는 메소드에 이름을 지을 수 있으며, 인스턴스의 관리가 가능하다. 불필요한 인스턴스의 생성을 하지 않는 캐싱이 가능하다.

Dto, VO

  • Dto란? 사용시 장점은?
    : Dto는 Data Transfer Object로 데이터 전달용 객체이다. 각 다른 계층 간의 데이터를 전달하기 위해 사용된다. getter, setter 이외의 로직을 갖지 않으며, 전달하는 값의 특성을 나타낼 수 있는 장점이 있다.
  • Dto와 VO의 차이는?
    : VO는 Value Object로 값 객체이다. 원시값을 포장한 객체도 VO가 된다. Dto는 값을 형태에 맞게 전달하기 위해서 사용되나 VO는 값 그 자체 객체이다.

기타

  • 캐싱을 하는 이유는? 캐시하면 될 것과 안 될 것들은?
    : 캐싱을 하면 불필요한 객체의 생성을 관리할 수 있다. 같은 객체라면 굳이 여러번 생성할 필요가 없이 생성된 객체를 가져다 쓸 수 있기 때문에 자원을 절약할 수 있다. 캐싱은 불변객체나 상태가 없는 객체를 사용해야 한다. 상태가 변하는 객체를 캐싱하면 원하지 않는 결과를 초래할 수 있다. 
  • MSA란?
    : MSA란 MicroService Architecture로 모놀리식과 대비되는 개념이다. 작은 단위의 요소들을 조립하여 서비스를 만드는 것을 의미한다. 작은 컴포넌트들의 각각의 역할을 책임지고 있기 때문에 개별적인 수정이 가능하다. 각 컴포넌트간의 응집도를 높이고 결합도는 낮춰 MSA를 구현할 수 있다.
  • BigDecimal VS BigInteger
    : BigDecimal은 소수점 단위도 표현되지만, BigInteger는 소수점 단위 표현은 되지 않는다. 돈과 관련된 값은 BigDecimal로 표현하는 것이 좋다. BigInteger은 큰 정수 값을 표현하기 위해 사용된다. 둘다 불변객체이며 문자열의 형태로 저장된다. 사칙연산이 되지 않으므로 구현되어 있는 메소드를 통해 객체를 반환한다.
  • 객체를 비교하는 방법?
    : equals, hashcode를 오버라이드하여 같은 속성을 가진 객체는 같은 객체로 비교할 수 있다. 객체의 대소비교를 위해서는 Comparable, Comparator를 구현하여 비교할 수 있다. Comparable은 인터페이스이며 CompareTo()를 구현하여 비교가 가능하다. 자기자신이 객체 비교 관계를 가지고 있다. Comparator도 인터페이스이며 compare()을 구현하여 비교한다. compare(객체1, 객체2)로 객체들을 받아서 외부에서 객체 비교를 해준다.

패키지구조

  • 각 패키지 구조는 어떤 특징을 지니는지?(Service Layer의 역할)
    : domain - 순수한 메인 비지니스 로직이 들어있다.
    : dto - 레이어 간의 값을 전달하기 위한 객체들이 들어있다.
    : dao - DB에 접근하는 로직이 들어있다.
    : service - DB에 접근해서 가져온 값들과 컨트롤러 사이에서 비즈니스 로직을 처리해준다.
    : controller - 다른 패키지들(도메인과 뷰 등)을 연결해주는 역할을 하는 로직이 있다.
  • MVC 패턴이란?
    : Model, View, Controller로 나누어 각각의 역할을 구분한 패턴이다. View에는 뷰와 관련된 로직, Model에는 도메인과 관련된 비즈니스 로직이 존재하며 Controller는 그 둘을 연결하고 관리하는 역할을 해준다. View와 Model를 독립적으로 존재하게 하여 뷰의 변경이 도메인 로직에 영향을 미치지 않게 구분해준다.

✔️ 기타 추가 공부할 부분

  • JCF
  • clone()
  • Collections.unmodifiableList, Arrays.asList()
  • null, Optional
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/07   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
글 보관함