질의응답 형식으로 면접하듯이 정리해봤습니다.
아무리 잘 아는 질문이라고 해도 막상 대답하려고 하면 어려운거 같습니다.
완벽히 아는게 아니라는걸 알려주는거 같기도합니다.
스스로 질문해보고 응답해보면 기억에 잘 남는거 같습니다.
자바언어로된 소스코드는 어떻게 실행되나요?
- 개발자가 작성한 소스코드는 컴퓨터가 알아 들을 수 있는 코드로 변환해야합니다. 이러한 변환 과정을 컴파일이라고 하며 Javac 라는 명령어를 통해 컴파일을 진행하고 결과적으로 컴퓨터가 알아 들을 수 있는 class 파일로 변경됩니다. 그러면 java 라는 명령어를 통해서 JVM 이 컴퓨터 플랫폼(OS)에 맞춰서 실행 시킵니다.
- JVM 이란 Java Virtual Machine 입니다. JVM 은 운영체제에 종속적이며 즉, 윈도우와 리눅스에서 돌아가는 JVM이 다릅니다. JVM은 ByteCode( class 파일)을 실행하며 OS에 종속적입니다.
- 개발자는 소스코드를 작성하면 JVM이 플랫폼에 맞게 맞춰서 실행해주기 때문에 JVM은 플랫폼에 독립적이다라고 말하는 것입니다.
JVM과 JRE, JDK의 차이는 무엇입니까?
- JVM : java virtual machine 의 약자이며 프로그램을 구동하는 실행자 역할합니다.
- JRE : java runtime environment 의 약자이며 자바 프로그램을 실행할 수 있는 환경을 의미합니다. 즉 JRE 안에 JVM이 포함되어 있는 구조입니다. JRE는 보통 Class Roader , Bytecode Verifier , java virtual machine 이렇게 3가지를 말합니다. Class Roader란 컴파일된 클래스 파일을 메모리로 로드하는 역할을 하며 Bytecode verifier 는 실행되기 직전 코드를 검증하는 역할을 하고 JVM은 최종적으로 실행하는 역할입니다. 이렇게 3가지를 JRE라고 부릅니다.
- JDK : java Development Kit 의 약자이며 프로그램 개발을 위한 그 이상의 것을 제공합니다. 즉, 종합세트라고 보시면 됩니다. JDK 는 JRE 에 어떤 toolset 같은 것들이 추가된 것을 의미합니다. toolset 이라고 하면 예를 들어 컴파일러가 있습니다. 컴파일러는 javac 명령어로 class 파일로 컴파일 할 수 있으며 디버깅 기능도 제공합니다.
오토박싱과 언박싱은 어떤 차이가 있습니까?
- 오토박싱과 언박싱에 대해서 이해하기 전에 자바의 데이터타입 2가지를 이해해야 합니다. 자바의 데이터타입은 2가지가 있는데 Primitive 타입과 Object 타입이 있습니다. Primitive 는 스택영역에 저장되는 데이터이고 Object는 스택에 참조값을 두고 힙메모리에 저장되는 데이터입니다.
- Primitive 와 Object 는 서로 변환되는 것이 허용되지 않아 등장한 개념이 바로 오토박싱과 언박싱입니다. 그래서 Primitive 를 Object 화 시킨것을 Wrapper 라고 하였고 Wrapper 와 Primitive 사이의 변환이 가능하게 되었습니다.
- Primitive : boolean , char, byte, short , int , long , float, double
- Wrapper : Boolean , Charater, Byte , Short, Integer, Long , Float , Double
- 오토박싱은 Primitive -> Object 로 바꾸는 것을 의미합니다.
- 언박싱은 Object -> Primitive 로 바꾸는 것을 의미합니다. 평소 택배를 뜯을 때 언박싱이라고 하는데 큰 택배상자에서 작은 물건을 가져오니 Object 에서 가벼운 Primitive 로 바꾸는 것으로 이해하면 헷갈리지 않습니다.
스택과 힙은 어떻게 다른가요?
- 스택영역은 Primitive data 와 Reference 를 저장하며 힙은 Object 를 저장합니다. 참고로 힙과 스택의 참조가 끊어진 Object의 메모리를 정리하는 일을 Garbage Collection 이라고 합니다.
String 과 StringBuffer , StringBuilder 의 차이가 무엇인가요?
- String 은 Primitive 한것 처럼 사용하고 있지만 실제로는 Immutable 한 Object 입니다. 따라서 String의 "+" 연산이 되는 경우 새로운객체를 생성하여 다시 할당하므로 성능면에서 좋지 않습니다.
- StringBuffer는 기존 Object에 변경이 일어나는 경우 새롭게 String을 할당하는 것이 아니고 기존 객체에 변경이 일어나므로 메모리 관리에 효율적입니다. 즉, String과 달리 mutable 합니다.
- StringBuilder 역시 StiringBuffer와 같이 mutable 합니다. 다만, StringBuffer는 Synchronous 하고 StringBuilder는 non-synchronous 합니다. 그래서 StringBuilder가 퍼포먼스 측면에서는 좋지만 멀티스레드 환경에서 안정성을 보장할 수 없습니다. 그래서 멀티스레드 환경에서는 StringBuffer 가 안전합니다.
Overriding vs Overroading 의 차이는 무엇입니까?
- 오버라이딩은 자녀클래스에서 부모클래스의 메서드를 재정의하는 것을 의미합니다. 리턴타입은 부모메서드의 리턴타입과 같거나 자녀클래스여야합니다(다형성). 부모클래스는 abstract 일수도 있고 concrete 일 수도 있습니다. 오버라이딩을 위해서는 반드시 상속개념이 필요합니다.
- 오버로딩은 동일한 이름을 가진 메서드를 파라미터로 구분한것을 의미합니다. 보통 가독성을 위해서 사용하며 반드시 파라미터가 달라야합니다.
String 을 literal 로 생성하는 것과 new 로 생성하는 것의 차이가 무엇인가요?
- Object를 새로 생성하기 위해서는 new 를 반드시 이용해야합니다. 하지만 String 은 new 연산자 없이 생성할 수 있는 유일한 Object 입니다. 그래서 String 을 생성하는 방법이 2가지이며 literal을 통해 생성하면 String Constant Pool 이라는 영역에 생성됩니다. String Constant Pool은 Heap 의 일부입니다. 그림으로 보시면 좀 더 이해가 잘될것입니다.
== 와 equals 의 차이는 무엇인가요?
- == : 두 객체의 참조값을 비교하는 연산자입니다. 즉 두 객체가 같은 객체인지 여부입니다. 위 그림에서 s1,s2 를 == 로 비교하면 true를 반환합니다. 반면 s3,s4 는 다른 객체이므로 == 로 비교하면 false를 반환합니다.
- equals 는 객체의 내용을 비교합니다. 즉 다른 객체라도 내용이 같다면 true를 반환합니다. 예를 들어 s3,s4는 다른 객체이지만 "LOVE"라는 똑같은 내용을 포함하고 있으므로 Equals 는 true를 반환합니다.
Static 은 왜 필요한가요?
- new 로 객체를 생성하다보면 메모리를 많이 사용하게 됩니다. 그리고 생성하는 객체가 공통적으로 많이 쓰는 객체라면 더욱더 전역적으로 하나만 있다면 객체를 새로 생성하지 않더라도 가져다가 쓰기만 하면 될 것입니다. 그래서 static 이 생겨나게 되었습니다.
- static은 객체 생성 이전에 이미 메모리에 로딩되어 있습니다. 인스턴스와 상관없이 메모리에 존재합니다. 주로 변수와 메서드를 Static으로 선언하여 사용합니다. static 변수는 클래스 레벨에서 접근이 가능하고 전역변수가 필요할 때 주로 사용합니다. static 메서드도 클래스 레벨에서 호출하며 자주 사용하는 전역 메서드를 static으로 선언합니다. 예를 들어, Math.round() 가 있습니다.
추상 클래스와 인터페이스의 차이가 무엇인가요?
- 공통점 : 추상클래스와 인터페이스 모두 추상 메서드를 구현하도록 강제한다는 공통점이 있습니다.
- 추상클래스
1) 단일 상속만 가능
2) 변수나 메서드가 포함될 수 도있고 아닐 수도 있음.
3) 관련성이 높은 클래스 간에 코드를 공유하고 싶은 경우 사용
4) 수퍼클래스로서 관련성이 높은 클래스들에게 코드를 공유하는 미완성 설계도
- 인터페이스
1) 실질적인 구현이 없음.
2) abstract method , public static final 변수
3) default 메서드 존재
4) 다중 구현 가능
5) public 만 가능함.
6) 관련 없는 여러 클래스들의 공통된 기능을 정의하고자 할때 사용. 예를 들어, Comparable , Clonable
자바에서 Exception Handling 을 어떻게 하나요?
- try catch 를 통해 예외를 직접 처리하는 방법이 있습니다.
- throws 를 통해서 caller 에게 책임을 넘기는 방법이 있습니다.
Unchecked Exception 과 Checked Exception 의 차이는 무엇인가요?
- Checked Exception : IDE에서 제공하고 컴파일 타임에 체크할 수 있는 예외를 말합니다. 예를 들어, IO Exception 과 SQL Exception 이 있습니다.
- UnChecked Exception : 런타임에 체크하는 예외를 말합니다. 예를 들어, NPE, ArrayOutOfIndex , Arithmatic 등이 있습니다.
- Error : 예외로 처리할 수 없는 심각한 상황을 말합니다. OutOfMemory와 같이 제어할수 없는 경우입니다.
throw vs throws 의 차이는 무엇인가요?
- throws : 보통 메서드 이름 옆에 선언하며 Exception Handling 의 책임을 Caller에게 넘기기 위해 사용합니다. throws 다음에는 Class 이름이 와야합니다. class 이름들은 여러개 선언 가능합니다.
- throw : Exception 객체를 생성하여 예외를 발생시키는 것을 말합니다. 하나의 예외 객체만 생성가능하며 throw 다음에는 Class 이름이 아니라 객체가 와야합니다.
자바의 스트림이 무엇인가요?
- 스트림이란 데이터를 순차적으로 접근하기 위한 방법을 제공합니다. 즉, 입력이나 출력으로 표현된 순차적인 데이터 흐름입니다.
스트림은 한 방향으로만 통신할 수 있으므로 입력과 출력을 동시에 처리할 수는 없습니다.
- 스트림의 입출력 대상으로 파일,메모리,프로세스,문자열,오디오장치 등이 있습니다.
- java.io 패키지와 java.nio 패키지등에서 스트림에 connect 할 수 있도록 제공합니다.
1) 바이트 기반 스트림 : 이미지나 미디어파일을 다룰 때 사용합니다. InputStream, OutputStream 이라는 이름으로 주로 사용합니다.
2) 문자열 기반 스트림 : 유니코드,텍스트 데이터를 이용할 때 사용합니다. Reader , Writer 라는 접미사를 이용한 것들이 대부분입니다. BufferedReader 와 같은 것들로 파일이나 콘솔의 문자열들을 스트림을 이용해 데이터를 다루는 것들로 예를 들 수 있겠습니다.
Try Catch Finally 에 Try 안에서 System.exit(0) 를 한다면 Finally는 실행이 되나요?
- 안됩니다. System.exit 는 프로그램을 강제로 종료한다는 의미이고 완전히 소프트웨어를 중단하기 때문에 Finally는 실행되지 않습니다.
Iterator vs Enumeration 의 차이가 무엇인가요?
- Iterator 와 Enumration 모두 컬렉션에 접근하는 기술입니다.
- Enumeration 은 Snap-shot을 이용하여 접근하는 기술입니다. 따라서 원본 데이터에 변경이 생길 경우 Enumeration 으로 접근한 사본의 데이터와 원본이 달라질 수 있습니다. 그래서 remove 를 지원하지 않습니다. 또한 초기 Collection에만 지원한다는 단점이 있습니다.
- Iterator 는 별도의 스냅샷을 이용하지 않고 컬렉션 원본 데이터에 직접 접근합니다. 원본 데이터에 만약 변경이 있다면 ConcurrentModificationException 이 발생하기 때문에 훨신 안정적입니다. 또한 원본에 직접 접근하기 때문에 Iterator를 이용하여 remove가 가능합니다.
- Iterator가 모든 방면에서 좋으므로 Iterator를 사용하기를 적극 권장합니다.
Marker Interface가 무엇인가요?
- 상수도 없고 메서드도 없는 완전히 비어있는 인터페이스를 의미합니다. 어떤 특별한 행동을 JVM에게 알려주는 역할을 합니다. 태그 인터페이스라고도 합니다.
- 예시)
Serializable - 객체 직렬화 가능
Clonnable - 객체의 복제가 가능
SingleThreadModel - 싱글스레드로 처리함. 만약 서블릿이 이를 구현했다면 싱글스레드로 처리함.
Remote - RMI에서 사용하는 객체의 경우 원격호출로 사용 가능
JAVA RMI 가 무엇인가요?
- RMI 는 Remote Method Invocation 의 약자입니다. 분산된 객체간의 통신을 구현하는 모든 프로토콜을 의미합니다. 쉽게 이야기 하면 JVM 간의 통신입니다.
1) 원격객체를 RMI Registry 에 등록합니다.
2) Client가 객체 참조값을 얻어옵니다.
3) RMI 를 이용하여 Server의 원격객체를 사용합니다.
자바에서 스레드를 생성하는 방법은 무엇인가요?
- 스레드에 관해서 이해가 잘 안되신다면 운영체제편을 참고해주시기 바랍니다.
https://onejunu.tistory.com/159
- 자바에서 스레드를 생성하는 방법은 크게 2가지가 있습니다.
1) Thread 클래스를 상속 받고 run 메소드를 오버라이딩하면 됩니다.
2) Runnable 인터페이스를 구현하여 run 메서드를 오버라이딩합니다. 그 다음 아래와 같이 Thread 생성자의 파라미터로 넘겨 start 메소드를 호출하면 됩니다.
참고 : https://www.daleseo.com/java-thread-runnable/
main 메서드에 Static 이 생략되면 실행이 되나요?
- 안됩니다. main 이라는 이름은 JVM에서 약속된 프로그램 시작을 의미하는 메서드입니다. Static이 선언되어 있지 않다면 메모리에 올라가 있지 않은 상태이므로 JVM 은 main 메서드를 찾아서 실행 할 수 없게 됩니다.
public static void main(String[] args) 의 의미
1) public : JVM이 어디서든 접근가능하도록 함.
2) static : 메모리에 main 메서드를 올림.
3) void : main의 반환 타입
4) main : JVM의 약속된 이름
5) String[] args : command line parameter
- 그렇다면 final 을 선언하면 어떻게 될까요? 메서드에 final 이 선언된다는 의미는 더이상 오버라이딩을 할수 없다는 의미입니다. 따라서 main 메서드를 실행하는 데는 아무 영향이 없습니다.
멀티 스레드 환경에서 동시성 이슈를 해결하는 방법은 무엇인가요?
- Synchronized 블록을 사용하여 블록 안에서는 동시에 실행 될수 없도록 합니다.
- AtomicInteger 처럼 가볍게 사용하는 방법도 있습니다.
'CS' 카테고리의 다른 글
[OS] 운영체제 질문 - (프로세스,스레드,동기화 문제,교착상태,페이징,가상메모리) (1) | 2022.06.15 |
---|---|
[DB] 인덱스 (1) | 2022.06.14 |
[DB] 트랜잭션 질문 및 응답 (0) | 2022.06.08 |
[네트워크] 쿠키,세션 질문 및 응답 (0) | 2022.06.08 |
[네트워크] HTTP 질문 및 응답 (0) | 2022.06.08 |
댓글