-
CS - Java & Spring 정리CS 2023. 11. 9. 02:30
🍓 Java 문법 & 특징
🍓 자바는 인터프리터 언어인가요? 컴파일 언어인가요?
자바는 2가지 방식을 모두 혼합하여 사용합니다. 자바 컴파일러가 .java 파일을 컴파일을 통해 .class파일을 만들고, JVM의 실행 엔진의 인터프리터가 각 운영체제에 맞게 이진 코드로 변환 후 실행합니다.
🍓 자바 프로그램의 수행 과정에 대해 말씀해주세요.
자바 소스 코드를 프로그래머가 작성(.java) → 자바 컴파일러가 바이트 코드로 변환 (.class) → JVM 클래스로더로 전달, 클래스 로더가 JVM의 Runtime Data Area(JVM이 OS로부터 할당받는 메모리영역)에 올린다. → 실행 엔진이 바이트 코드들을 명령어 단위로 하나씩 가져와서 실행합니다.
🍓 Java의 String 클래스에서 equals()와 == 차이가 무엇인가요?
- equals()는 참조 변수의 값이 같은지 비교하는 메소드로, 재정의 되어있지 않다면 객체의 주소값을 비교하여 동일 객체인지 비교후 boolean 값을 리턴하는 메소드입니다.
- == 연산자는 primitive type일 경우 값을, 그 외에는 주소값을 비교하는 연산자입니다.
- String 클래스에 equals를 사용할 경우에는 주소값이 아닌 데이터 값을 비교하여 동일 여부를 판정합니다.
- ==을 사용하는 경우, 같은 문자열을 가지고 있어도 객체끼리 주소가 다르기 때문에 다르다고 판정합니다.
- 만약 String a = "hello" String b = "hello" 이런식으로 문자열로 생성할 경우 a를 생성할 때 String constant pool에 먼저 hello를 저장해둬서, b를 생성할 때 기존에 있는 hello를 참조하는 방식으로 생성하므로 이 경우엔 == 연산의 결과가 true이다.
🍓 equals() 함수만 오버라이딩하고 hashCode()는 오버라이딩 하지 않으면 어떤 문제가 발생할까요?
- equals()는 객체의 주소값을 비교하여 동일 객체인지 비교후 boolean 값을 리턴하는 메소드입니다.
- hashCode()는 객체의 주소값을 이용하여 해싱 기법을 적용한 결과값을 리턴하는 메소드입니다.
- 자바의 해시 컬렉션은 동일 객체인지 판정할 때 hashCode() 값이 같은지 먼저 확인하고 같다면 equals()함수를 호출하여 같은지 총 2번의 확인 작업을 거칩니다. equals()만 오버라이딩할 경우, hashCode() 값이 달라 다른 객체로 판단되어 동일하다고 의도했던 두 객체가 모두 추가되는 등 원치 않은 방향으로 동작할 수 있습니다.
🍓 Java는 매개변수를 call by value로 전달하나요 call by reference로 전달하나요?
- Call by value는 메소드의 매개변수로 값을 넘길때 원래 값은 놔두고, 새롭게 값을 복제하여 넘기는 방식입니다.
- Call by reference는 매개변수로 넘어온 값의 참조 자체를 넘기는 방식입니다.
- 자바의 참조형때문에 call by reference라고 생각하기 쉽지만, 주소 값을 전달하는 방식입니다.
참조 자체를 넘긴다면 new로 할당을 했을 때 methodA의 원래 값도 new로 할당한 값으로 변화해야 하지만, 자바는 그렇지 않기 때문입니다. (포인터처럼 메모리에 직접 new 할당하면 해당 객체 쓰는 메소드들 다 영향 받음)
🍓 Overloading과 Overriding의 차이점이 무엇인가요?
- 오버로딩은 하나의 메소드 명에, 반환타입과 파라미터의 개수나 타입 등을 다르게 해서 함수를 중복 정의 하는 것이다.
- 오버라이딩은 부모 클래스로부터 상속받은 메소드를 자식 클래스에서 재 정의하는 것이다. 부모 클래스의 메소드를 호출해도 실제 타입이 자식 클래스이면 자식 클래스의 메소드가 호출된다.
🍓 인터페이스와 추상 클래스의 차이점이 무엇인가요?
추상 클래스는 abstract로 선언되어 있거나 추상 메소드가 하나 이상 포함된 클래스를 의미합니다.
인터페이스는 추상 메소드와 public 정적 상수들만 가지는 구조를 의미합니다.
추상클래스는 다중 상속이 불가능하고 인터페이스는 다중 상속(구현)이 가능합니다.
🍓 다수의 인터페이스를 구현하는 것은 가능한데, 여러 개의 클래스를 상속은 불가능한 이유가 무엇일까요?
- 다이아몬드 문제
- 하나의 클래스가 같은 메소드 이름을 가진 복수의 상위 클래스를 상속받는다면, 해당 클래스는 어느 메소드를 상속받은 것인지 모호해진다.
- EX) 물고기 클래스와 사람 클래스 2가지를 상속받은 인어 클래스의 swim 메소드는 물고기처럼 수영할까 사람처럼 수영할까?
- 인터페이스의 경우 구현해야할 행위 자체만을 나타낸 추상 메서드로 이루어져 있으므로, 중간에 구현체가 끼지 않아 다중 구현이 허용된다.
🍓 Java의 Thread는 어째서 사용하고, Runnable 인터페이스를 구현하는 방식과 Thread 클래스를 상속받는 방식 중, 어떤 방식으로 구현하는 것이 좋을까요?
- 프로세스 내에서 동시에 여러 작업을 수행하기 위해 스레드를 사용합니다.
- 자바 언어에서는 다중 상속이 지원되지 않으므로, 다른 클래스를 상속받을 가능성을 생각하여 Runnable 인터페이스를 구현하는 방식으로 사용하는 것이 좀 더 권장됩니다.
🍓 Arrays.asList() 함수로 생성한 리스트는 어떤 특징을 가지나요?
remove, add 메소드를 제공하지 않아 엘리먼트를 추가하거나 삭제하는 등의 작업이 불가합니다.(실행 시 unsupportedOperationException 발생)
사이즈를 변경할 수 없고 값만 꺼낼 수 있습니다.
🍓 함수형 인터페이스는 왜 필요할까요?
람다식은 익명 함수(객체)여서 함수를 부를 이름이 없으므로 람다식으로 만든 객체에 접근하기 위해 1개의 추상 메소드만를 가지고 있는 함수형 인터페이스를 사용합니다.
🍓 stream을 사용함으로서 얻는 장점이 무엇인가요?
Java 8의 stream은 함수형 프로그램의 특징들을 대입하여, 기존의 Collection을 다루는 방법보다 간결하고 가독성이 좋도록 개선되었습니다. Lambda 구문을 사용하여 for문, if문 등을 사용하지 않아 더욱 직관적인 코드 작성에 편리하다.
원본 데이터를 바꾸지는 않으며, 재사용 불가하므로 stream 연산 결과를 컬렉션으로 반환하여 사용해야 합니다.
🍓 Error와 Checked Exception, Unchecked Exception의 차이가 무엇인가요?
먼저 프로그램 외부에서 발생하여 프로그램이 멈추는 것은 Error입니다.
프로그램 내부에서 발생하고, 스레드에만 영향을 주어 프로그램 자체는 계속 실행 가능한 것은 Exception입니다.
Exception에는 checked, unchecked 2가지 종류가 있습니다.
Runtime Exception 이라고도 하는 Unchecked Exception은 컴파일 시 체크하지 않으며 예외처리를 강제하지 않는, 실행 중 발생가능한 예외를 의미합니다. ArrayIndexOutOfBounds, NullPointerException 등이 있습니다.
Checked Exception은 Exception 클래스의 하위 클래스 중 Runtime Exception을 제외한 나머지로, 컴파일러가 예외처리를 확인하여 반드시 예외처리가 되어야 하는 예외를 의미합니다. IOException 등이 있습니다.
🍓Java의 Access Modifier 에 대해서 설명해주세요.
접근 제어자는 변수, 메소드의 접근 범위를 설정해주기 위해 사용하는 예약어입니다.
public, protected(동일패키지, 외부라도 상속받았다면 ok), default(동일패키지), private(해당 클래스 내)이 있습니다.
🍓 Junit에 대해 설명해주세요.
Junit은 자바 언어의 단위 테스트 프레임워크입니다. 단위 테스트는 프로그램의 개별 코드 조각들이 의도대로 작동하는지 검증하는 테스트입니다. 단위 테스트를 작성하고 실행하기 위한 도구로 사용됩니다.
🍓 Object 클래스에 대해 설명해주세요.
자바 모든 클래스의 최상위 클래스로 모든 클래스가 상속하게 되는 기본 클래스입니다. 아무런 클래스도 상속하지 않는 클래스더라도 Java 컴파일러가 자동으로 extends Object 코드를 넣어줍니다. Object 클래스에는 equals, hashCode, toString 등 객체들이 공통적으로 가지는 메소드들이 정의되어 있습니다.
🍓 객체 지향 프로그래밍에서의 메소드 호출과 관련된 2가지 다른 바인딩 방식에 대해 설명해주세요.
정적 바인딩
컴파일 시 변수 / 참조 타입을 기반으로 어떤 메소드 호출되어 실행해야 하는지 결정. 오버로딩된 메소드들의 호출에서 주로 발생합니다.
동적 바인딩
실행 시간에 메소드 호출과 실제 실행될 메소드를 결정하는 것으로, 객체 실제 타입을 확인하고 해당 객체에 맞는 메소드를 호출합니다.
🍓 직렬화에 대해 설명해주세요.
사용하고 있는 데이터를 파일 저장 혹은 데이터 통신에서 파싱할 수 있는 유의미한 데이터를 만들기 위해 사용하는 기술로, 자바 시스템 내부에서 사용되는 객체 또는 데이터를 외부의 자바 시스템에서도 사용할 수 있도록 바이트(byte) 형태로 데이터 변환하는 기술입니다.
🍓 컬렉션 클래스에서 Generic을 사용하는 이유가 무엇인가요?
컬렉션 클래스에 저장되는 인스턴스 타입을 제한하여 런타임에 발생할 수 있는 잠재적인 모든 예외를 컴파일 타임에 잡아 낼 수 있어서 사용합니다.
🍇 JVM 관련 질문
🍇 Major GC와 Minor GC 차이점이 무엇인가요?
- Minor GC
- Young 영역에서 일어나는 Garbage Collection으로, 속도가 빠르고 Eden, Survivor영역에 속한 젊은 객체들에 대한 Garbage Collection을 의미합니다.
- Major GC
- Old 영역에서 일어나는 Garbage Collection으로, Minor GC에 비해 속도가 느리고 Old 영역에 속한 오래된 객체들에 대한 Garbage Collection을 의미합니다.
- Old 영역에서 일어나는 Garbage Collection으로, Minor GC에 비해 속도가 느리고 Old 영역에 속한 오래된 객체들에 대한 Garbage Collection을 의미합니다.
🍇 자바의 메모리 영역은 어떻게 구성되어 있나요?
- 메소드(Method) 영역 : 전역변수와 static 변수를 저장, 프로그램의 시작부터 종료까지 남아있습니다.
- 스택(Stack) 영역 : 지역변수와 매개변수 데이터 값이 저장, 메소드 호출 시 메모리에 할당되고 종료되면 메모리가 해제된다.
- 힙(Heap) 영역 : 객체, 배열 등이 저장, 가비지 컬렉터에 의해 관리되어 진다.
🍇 Reflection이란 무엇인가요?실행 시간에 JVM의 메모리 영역에 저장된 클래스 정보들을 읽어서 활용하는 기술로 라이브러리나 프레임워크에서 활용하는 기술입니다.
🥝 Spring 관련 질문
🥝 Spring과 Spring Boot의 차이점이 무엇인가요?
- Spring은 프레임워크로, 개발자가 직접 설정파일 작성을 통해 컨테이너 구성, 빈 객체 등록, 의존성 설정 등을 수동으로 해줘야 했습니다.
- Spring Boot는 Spring에서 제공하는 여러 기능들을 자동으로 설정하여 Spring을 쉽게 사용하도록 만든 도구입니다. 프로젝트의 설정, 라이브러리 의존성 관리 등 다양한 기능들을 제공하여 편리하다는 장점이 있습니다.
- Spring Boot는 내장 톰캣 서버를 사용하여 따로 톰캣을 설치할 필요가 없고, starter를 통해 dependency를 자동화하며(버전관리 자동화), jar file을 이용해 자바 옵션만으로 손쉽게 배포가 가능하다는 차이가 있습니다.
🥝 DTO를 사용하는 이유가 무엇인가요?
양방향 참조 시의 순환 참조를 예방하고, entity 내부를 캡슐화하며 계층 간 역할을 분리하기 위해서입니다.
🥝 Bean Scope 종류는 어떤 것이 있나요?
- Bean Scope란 문자 그대로 빈이 존재할 수 있는 범위를 의미하며, 스프링 빈은 기본적으로 싱글톤 스코프로 관리되어 스프링 컨테이너의 시작과 함께 생성, 컨테이너 종료될 때까지 유지됩니다.
- 싱글톤 스코프 외에 스프링 컨테이너가 빈 생성에서 의존관계 주입까지만 관여하는 프로토타입 스코프, 웹 어플리케이션 환경에서 사용하는 웹 스코프인 request, session, application 스코프가 있습니다.
🥝 Spring Bean 라이프사이클에 대해 간단히 설명해주세요.
스프링 컨테이너가 생성되고, 컨테이너에 의해 빈이 생성됩니다. 빈이 생성되면 의존관계가 주입되고, 초기화 콜백을 통해 의존관계 주입 완료를 알립니다. 그 후 빈을 사용하고, 빈 스코프에 따라 소멸 시 소멸전 콜백이 일어나고 (싱글톤이라면 스프링 컨테이너 종료 전 등) 스프링이 종료됩니다.
🥝 Spring이 Request를 처리하는 과정에 대해 설명해주세요.
- Client 요청을 Dispatcher Servlet이 받음
- Handler Mapping이 요청 정보를 통해 요청을 위임할 Controller 찾는다.
- 요청을 Controller로 위임할 Handler Adpater를 찾아 전달, 해당 Controller로 요청을 위임
- 요청에 맞게 비즈니스 로직을 처리 후 Controller 가 반환값을 반환
- Handler Adapter가 반환값을 반환
- 최종적으로 Dispatcher Servlet이 클라이언트에게 서버의 응답 반환
🥝 Spring에서 멤버 변수를 주입받는 방법 3가지에 대해 각각 설명해주세요.
생성자 주입, 필드 주입, 수정자 주입 총 3가지가 있습니다.
- 필드 주입, 수정자 주입은 빈을 모두 생성한 이후 해당하는 필드나 setter 메소드를 찾아서 주입하는 방식이고, 생성자 주입은 빈을 생성하는 시점에 주입을 같이 하는 방식입니다.
- 생성자 주입이 권장되는데, 모든 빈을 생성하지 않아도 되어 단위 테스트가 다른 방식보다 편하고, 필드에 final 키워드를 선언하여 변경불가능하게 사용할 수 있습니다.
🥝 Spring의 IOC와 DI의 정의에 대해 간단히 설명해주세요
- IOC(제어의 역전) : 프로그램의 제어 흐름을 직접 제어하는 것이 아니라 외부에서 관리하는 것
- DI(의존성 주입) : 필요한 객체를 직접 생성하는 것이 아닌 외부로부터 객체를 받아서 사용하는 것
🥝 Spring Filter와 Interceptor와 사용하는 예시를 설명해주세요.
Filter
- 요청과 응답을 정제하는 역할로, 스프링 컨테이너가 아닌 톰캣과 같은 웹 컨테이너에 의해 관리되며 스프링 범위 밖에서 처리됩니다.
- Dispatcher Servlet에 요청이 전달되기 전/후에 사용합니다.
- 보안, 인증 / 인가 작업, 요청에 대한 일괄적인 로깅 또는 검사, 이미지/데이터 압축 및 문자열 인코딩, Spring과 분리되어야 하는 기능
Interceptor
- Dispatcher Servlet이 Controller를 호출하기 전 / 후에 인터셉터가 끼어들어 요청과 응답을 참조하거나 가공할 수 있으며, Spring Context 내에서 동작합니다.
- 세부적인 보안 및 인증/인가 작업, API 호출에 대한 로깅 또는 검사, Controller 데이터 가공
🥝 Controller로 들어오는 입력값을 검증하는 방법은 어떤 것들이 있나요?
DTO 를 검사할때는 validation 패키지의 @NotNull, @NotEmpty, @Min, @Max 등을 활용할 수 있습니다.
Controller단에서는 BindingResult 객체를 활용하여 서비스 단에서 직접 클라이언트에게 예외가 발생하였음을 알리거나, @ControllerAdvice를 이용한 전역 에러 핸들링을 활용하는 방법도 존재합니다.
🥝 @Pathvariable, @RequestParam, @RequestBody, @ModelAttribute 의 차이가 무엇인가요?
- @PathVariable : 값을 하나만 받아올 수 있으며 보통 id 값을 전송할때 주로 사용
- @RequestParam : param 형식으로 간단한 데이터를 전송할때 주로 사용
- @RequestBody : Json 형식으로 데이터를 전송할때 주로 사용
- @ModelAttribute : 폼 / MultipartFile 형식에 주로 사용
🥝 Spring에서 Dependency Injection을 IoC Container가 하는 일을 중심으로 설명해주세요
IoC Container는 Inversion of Control의 약자로, 개발자가 Spring Bean의 관리를 하지 않고 Framework가 주도적으로 관리하도록 역전시킨것이다. 따라서 IoC Container가 Spring Bean의 의존성 주입을 관리하게 되고, 개발자가 @AutoWired 등의 방법으로 설계해놓은 것을 실행한다.
🥝 Spring Bean은 언제 어떻게 생성되게 될까요?
Spring Application의 메인 메소드에서 static 메소드인 run() 메소드를 찾아 실행시킨다. run 메소드는 application context를 생성하고, @ComponentScan 때문에 @Component, @Bean 등 Bean으로 만드는 어노테이션을 찾아 Spring Bean으로 생성한 뒤, IoC 에 저장한다.
🥝 한 클래스에 대해서 Bean 생성을 여러개 하고 싶으면 어떻게 하면 될까요?
@Scope 어노테이션을 통해 Bean Scope를 session, prototype등 세션이나 요청마다 생성하는 스코프로 변경해줍니다.
🥝 Spring에서 테스트 시, @Mock 과 같은 가짜 객체를 만들어서 테스트하는 이유가 무엇인가요?
테스트는 통합 테스트 외 단위 테스트를 실행할 때, Spring 컨테이너를 띄우지 않고 테스트 하고자 하는 영역 외 나머지들은 가짜 객체로 생성하여 테스트하려는 부분만 집중적으로 보기 위해서입니다.
'CS' 카테고리의 다른 글
CS - 운영체제 정리 (0) 2023.11.02 CS - 네트워크 정리 (0) 2023.10.26 CS - 데이터베이스 정리 (0) 2023.10.19 CS 스터디 운영체제 Q&A (2) (0) 2023.10.04 소프트웨어 공학 및 알고리즘 Q&A (0) 2023.09.27