Java - Java Etc Study
내용을 더 심도있게 공부하면 깊은 내용들이 많겠지만, 간략하게만 짚고 넘어가도 되는 내용들 위주로 정리하였다.
1. public static main(String[] args) 메서드란?
- Java 프로그램의 진입점(entry point) 역할을 하는 특별한 메서드이다.
- 이 메서드는 Java 프로그램이 실행될 때 JVM에 의해 자동으로 호출되며, 프로그램의 시작점으로 동작한다.
2. 반복문을 사용할 때 주의할 점
- 반복문 밖에서 해도 무관한 코드를 반복문 안에서 사용하는 경우를 주의해야한다. 특히 객체 생성을 주의해야한다.
- 예를 들어 Test라는 클래스에 대한 객체를 선언할 때, 불필요하게 반복문 안에서 선언한다면 Heap 메모리 공간을 순간적으로 많이 차지하게 되어 문제가 발생할 수도 있다.
3. 배열에 대한 명확한 정의
- 같은 자료형 타입을 연속적으로 그룹화하여 가지고 다니는 것을 말하며, 메모리에 이미 특정 공간만큼을 미리 차지하며 선언하는 것이기 때문에 늘리거나 줄일 수 없다.
- 또한 인덱스 범위 밖을 건들지 않게 조심하여야 하며, 만들어 놓고 사용하지 않는 공간이 있다면 그만큼 메모리 낭비이기 때문에.. 크기를 늘리거나 줄이고 싶을 경우 ArrayList를 사용하는 것이 좋다.
4. Batch 란? ( +Spring )
- 스프링의 @Scheduled 어노테이션이나, Spring Batch 처럼 일정 시간마다 동작할 수 있게끔 해주는걸 Batch라고 한다. ( 주기적으로 )
5. 상속은 왜 사용하는 것인가?
- 클래스간의 논리적 관계를 맺어주기 위해 사용하고, 공통적으로 사용하는 변수나 메서드가 많을 경우, 중복해서 작성하지 않기 위해 상속을 이용한다.
6. 상속의 단점은?
- 부모 클래스에 추상메서드를 추가하였다.
- 그런데 그 부모 클래스를 상속하고 있는 자식 클래스가 100개이고, 그 중 50개는 해당 메서드를 굳이 오버라이딩할 필요가 없다.
- 그럼에도 불구하고 추상메서드기 때문에 100개의 자식 클래스에서 오버라이딩은 다 해줘야하니 굉장히 힘들 수 있음.
- 또한 너무 상속을 많이 할 경우 결합도의 문제가 있을 수 있음. ( 결합도는 약하게 응집도는 강하게 )
- 항상 단점을 생각할 때는, 많은 경우를 생각해야 한다. 상속을 한 클래스만 받고있다고 한다면 이런 생각을 못하게 되는데, 상속을 100개 받는다고 하니 문제점이 보인다. 이처럼 트래픽도 그렇고 서버도 항상 많은 경우를 생각해야 단점이 보인다.
7. 캡슐화가 깨지는 예시를 들어주시오.
- private를 걸었지만 setter나 getter 등으로 접근을 하여 캡슐화가 깨지는 경우가 종종있다.
- 이런걸 방지하기 위해 setter에 특정 if문을 걸거나, 생성자를 통해 해결하기도 한다.
class Time { private int hour = 0; Time(int hour) throws Exception { if ( hour < 0 || hour > 23 ) throw new Exception("hour 는 0부터 23까지만 가능합니다."); this.hour = hour; } public int getHour() { return hour; } public void setHour(int hour) throws Exception { if ( hour < 0 || hour > 23 ) throw new Exception("hour 는 0부터 23까지만 가능합니다."); this.hour = hour; } } public class Test2 { public static void main(String[] args) throws Exception { Time time = new Time(23); time.setHour(25); // Exception } }
- 좀 극단적인 예시 코드이긴하다 ㅎㅎㅎ…
8. API란 무엇인가?
- 클라이언트들와 서비스를 주고 받는 방법(코드)
- 클라이언트가 ?webtoon=123&no=30 이라는 코드를 해당 “웹툰을 불러와주는 API”에게 보내면, 123아이디를 가진 웹툰의 30화를 가져와줌.
- 이 때 웹툰을 불러와주는 저 서비스의 대한 코드를 우리는 API라고 하고, 그걸 설명해놓은 문서를 API문서라고 한다.
9. SDK 란?
- 안드로이드 스튜디오나, JDK 처럼 개발자가 개발을 하기에 필요한 도구 모음을 SDK라고 한다.
10. enum 을 사용하는 이유
- 가독성, 유지보수성이 좋다
- 타입 강제로 인해 안전한 타입 지정 가능하다.
- 스위치 문 사용에 효과적이다.
- 열거형이므로 하나의 논리적 집합 안에 명시적으로 잘 표현
11. 자바에서 말하는 스레드와 프로세스의 차이는?
- 프로세스는 실행되는 프로그램 단위를 말하지만, 스레드는 해당 프로그램 안에서 실행되는 단위이며 프로세스 내에서 할당된 자원을 공유하여 사용한다.
- 그래서 하나의 스레드만 사용하는 프로세스의 경우 단일 스레드 프로세스라 하고, 여러 스레드를 사용할 경우 멀티 스레드 프로세스라 한다.
12. 개발을 할 때 System.exit( ); 이나 System.gc( ); 를 사용하면 안되는 이유는?
- System.exit 는 현재 실행중인 프로그램을 강제적으로 종료하는 코드이므로, 파일을 닫거나 리소스를 정리하는 등의 작업을 수행할 기회조차 주어지지 않는다. 또한 테스트가 어려움으로 사용을 권장하지 않는다.
- System.gc는 GC를 강제로 실행시켜 정리하는 메서드이다. 가비지를 탐색하고 정리하는 작업이 꽤 무거운 작업이기 때문에 강제적으로 실행하기 보다, 자연스럽게 GC가 동작하도록 하는것이 좋다. 또한 자바의 특성상 개발자가 직접 메모리에 관여하는 행위는 좋지 않다.
13. 개발을 할 때 System.out.println( ); 을 사용하면 안되는 이유는?
- System.out.println( );은 문자열을 출력할 때 사용한다.
- 그러나 여기에는 심각한 단점이 있는데, System.out.println( ); 은 Blocking과 Synchronized 둘 다 적용되기 때문에 성능이 매우 저하된다는 것이다.
- System.out.println( ); 이 I/O 작업인데, I/O 작업은 블로킹 되는 특성이 있기 때문이고 이에 따라서 해당 스레드는 다른 작업을 수행하지 못하고 기다려야 한다.
- 그리고 Synchronized 도 있기 때문에, 여러 스레드가 접근하면 순차적으로 작업을 진행하므로 다른 스레드들은 기다려야 하는데, 이러한 문제로 성능에 크게 문제가 생긴다.
- 그렇기 때문에 현업에서는 log 를 남기는 방법을 사용한다.
14. 객체 출력시 toString 보다는 valueOf를 쓰는게 좋은 이유
- 객체를 문자열로 출력하려 할 때, 객체가 Null이면 toString( ) 사용 시 오류가 발생함.
- 하지만 valueOf를 사용하면 StringBuilder로 바꿔주기 때문에 안전하게 null로 print 할 수 있음.
15. Date나 Calander 대신 LocalDateTime을 사용하는 이유는 ??
- LocalDateTime 은 Java 8 부터 추가된 날짜 관련 클래스이다.
- Date나 Calander는 가변 클래스라 값 변경도 가능하고, Thread-safe 하지도 않다.
- 그러나, LocalDateTime은 불변이고, Thread-safe 하다.
- 같은 이유로 ZonedDateTime을 쓰기도 하며,
- YEAR 이나 MONTH 등의 송석을 사용 하는 것도 Calendar 대신 ChronoField 를 사용한다.
16. Java 에서 goto 는 사용 불가능하다.
- 코드의 흐름을 임의로 이동시키는 명령문이다.
- 초기 프로그래밍 언어에서는 일반적으로 제공 되었지만, 가독성과 유지보수성 중 부정적인 영향을 미치기 때문에
- 사용을 지양하고 있으며, Java 에서는 아예 사용 할 수 없게 예약어로 막아두었다.
17. static 블럭
- static 블럭은 클래스가 클래스 로더에 의해 로딩될 때, 즉 해당 클래스에 대한 인스턴스가 최초로 만들어졌을 때 한 번 실행된다.
- 생성자보다 빨리 실행된다.
- 실질적으로는 잘 사용안한다.
- Bean 으로 등록된 클래스의 경우, Spring 컨테이너에서 초기화 하므로 static 블럭이 의미가 없다.
18. 전역변수를 많이 사용하면 생기는 문제
- 격리가 안되서 단위 테스트의 어려움을 겪음 ( 테스트에도 전역 변수가 있을 수 있음 )
- 전역 변수를 선언한 의도는 코드 어디서든 참고 및 할당할 수 있는 변수를 사용하겠다는 것인데, 그러면 수의 유효 범위가 클수록 코드의 가독성은 나빠지고, 의도치 않게 상태가 변경될 수 있는 위험성도 높아진다.
- 긴 생명주기로 인한 Stack 메모리를 많이 사용하는 문제
- 전역변수와 같은 변수명은 지역변수에서 사용할 수 없으므로 네이밍 문제도 있을 수 있다.