IDE ?
IDE : 통합개발환경, 코딩을 비롯해 개발에 필요한 각종 작업을 도와주는 소프트웨어를 말함 기능으로는 다음과 같다.
- 소스 코드 편집기
- 빌드 자동화
- 디버거
소스코드 편집기 : 코드를 직접 작성하고 편집할 수 있는 기능과 문법적으로 올바른 코드인지를 검사하여 사용자에게 보여 주는 기능을 포함. 자동완성 또한 코드 작성을 도와주는 것으로 편집기 기능
빌드 : 소스코드 편집기로 작성된 코드를 컴퓨터가 실행할 수 있는 바이너리 코드 형태로 변환 하는 것읋 의미 함으로 여기서 테스트 코드를 실행하여 코드가 올바르게 수정되었는지 체크하는 기능도 포함
빌드 자동화 : 이 과정들을 자동화해 주는 것으로 버튼 하나만 클릭하면 모든 테스트 코드를 실행하며 성공하면 빌드를 해줌
디버거 : 소스코드의 어떤 부분에 문제가 발생했는지 분석하는 프로그램
JDK SDK 차이
SDK : 소프트웨어를 개발하기 위해 필요한 도구의 모음을 뜻함
JDK : 자바 애플리케이션을 개발할 수 있는 도구로 SDK의 한 종류로, JDK 말고도 소프트웨오를 개발하는데 활용하는 라이브러리 역시 SDK로 구분
- 자바 컴파일러와 JRE로 구성
- JRE : 문자 그대로 자바 애플리케이션을 실행할 수 있는 환경을 제공하는 소프트웨어
- JVM : .class 파일을 실행하는 주체
- Open JDK : 말 그대로 오픈소스 공개된 JDK
- LTS : 장기간 기술 지원을 받을 수 있는 의미
다형성 : 상속과 인터페이스
하나의 객체가 내무적으로 여러 타입을 가질 수 있고, 어떤 타입이 들어 있느냐에 따라 각기 다른 동작을 하는 성질을 의미
즉 자동차라는 인터페이스를 정의하고 그리고 이 자동차 인터페이스를 구현하는 Sonata라는 클래스도 정의했다. 또 다른 자동차 인터페이스를 구현하는 K5라는 클래스도 정의했으며 문법적으로는 다음과 같이 사용할 수 있다.
public interface Car {}
public class Sonata implements Car {}
public class K5 implements Car {}
public class Main {
public static void main(String[] args) {
Car car1 = new Sonata();
Car car2 = new K5();
}
}
인터페이스인 Car 타입의 참조 변수에 자동차 인터페이스의 구현체인 Sonata와 k5 인스턴스를 모두 대입할 수 있는데, 이것을 가능하도록 하는 특성이 바로 다형성이다. car를 부모클래스로 바꾸고, '구햔한다.'라는 표현을 '상속하다.'로 바꿔도 다형성은 동일하게 적용된다.
다형성에 대해 알았지만 장점은 무엇이 있을까? 여기서 인터페이스의 참조 변수로 구현 클래스의 인스턴스를 넣어 사용할 수 있다. 정도로만 이해하는 것이 좋다. 다형성이 있는 코드는 if문이 없더라도 경우에 따라 다른 코드가 실행되도록 만들 수 있다 즉 코드가 if문으로 복잡해지는 것을 막을 수 있다.
컬렉션 List
데이터에 집합을 의미 주요 컬렉션으로 List, set, map이 있는데 이는 모두 구현체가 아닌 인터페이스이다. 인터페이스를 구현하는 여러 클래슺우 가장 많이 사용하는 List 인터페이스의 구현체 ArrayList에 대해 알아보자. ArrayList 역시 배열처럼 여러 개의 데어터를 다룰 때 주로 사용한다.
동일성과 동등성
자바의 기본 개념을 배우다 보면 자바의 문법과 구현에만 집중한 나머지 놓치기 쉬운 포인트가 잇다 바로 동일성과 동등성이다.
public class Main {
public static void main(String[] args) {
String str1 = new String("is same?");
String str2 = new String("is same?");
System.out.println(str1 == str2); // true or false?
}
}
str1와 str2가 가리키는 존재가 서로 동일하지 않아 false를 출력한다. 즉 자바에서 동일하다고 말하는 경우는 같은 인스턴스를 참고하고 있을때를 말한다. 같은 값을 가지고 있더라도 각각 생성으로 서로 다은 린스턴스이다. 따라서 두 변수 값은 서로 동일하지 않다.
변수 str1과 str2가 가지고 있는 String 인스턴스의 값을 비교하려면 ==가 아니라 equals()메서드로 비교햐여 한다.
public class Main {
public static void main(String[] args) {
String str1 = new String("is same?");
String str2 = new String("is same?");
System.out.println(str1.equals(str2)); // true or false?
}
}
equals는 동일성이 아니라 동등성을 비교하므로 true 값을 출력한다.
이것이 동일성과 동등성의 차이이다.
함수는 함수지만 이름이 없는 함수를 말한다.
파라미터가 1개인 경우
var1 -> System.out.println(var1);
파라미터가 2개인 경우
var1 -> {
var1 = var1 + 1
System.out.println(var1);
return var1;
}
파라미터가 2개 이상, 명령문 1개
(var1, var2) -> System.out.println(var1 + var2);
파라미터가 2개 이상, 명령문 2개 이상인 겨웅
(var1 , var2)-> {
System.out.println(var1);
System.out.println(var2);
}
스트림 API
컬렉션에 추가된 메서드의 집합을 의미. 스트림은 컬렉션에 담겨 있는 데이터를 마치 물이 흐르는 것처럼 처리한다는 데서 유래한 이름이다. 자바 기본서에서 많이 보았을 파일 입출력에 사용되는 '입력 스트림'과 '출력 스트림'의 스트림과 의미는 동일하다. 물론 지금부터 다루는 스트림 API는 컬렉션에 담긴 데이터를 처리하는 존재라는 것을 명시하자!
for_each()
컬렉션 요소들을 하나씩 꺼내 반복함
import java.util.Arrays;
import java.util.List;
public class Main {
public static void main(String[] args) {
Integer[] integerArray = new Integer[]{1, 2, 3, 4, 5};
List<Integer> list = Arrays.asList(integerArray);
list.stream().forEach(value -> System.out.println(value));
}
}
filter()
메서드는 컬렉션 요소들 중 조건문에 맞는 요소만 뽑아 새로운 스트림을 만든다. collect() 메서드와 함께 사용하면 전체 리스트 요소 중 조건문을 만족하는 요소를 뽑아 새로운 리스트를 만듬
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args) {
Integer[] integerArray = new Integer[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
List<Integer> list = Arrays.asList(integerArray);
List evenList = list.stream()
.filter(value -> value % 2 == 0).collect(Collectors.toList());
evenList.stream().forEach(value -> System.out.println(value));
}
}
distince()
메서드는 컬렉션의 요소에서 중복을 제거한다. 중복을 제거한다는 행위가 이미 정해져 있기 때문에 람다 표현식을 함수의 인자로 넘겨줄 필요가 없고, 이때 중복인지 아닌지를 판단하는 것은 요소들의 equals()메서드이다.
import java.util.Arrays;
import java.util.List;
public class Main {
public static void main(String[] args) {
Integer[] integerArray = new Integer[]{1, 1, 1, 1, 2, 2, 2, 3, 3, 4};
List<Integer> list = Arrays.asList(integerArray);
List<Integer> distinctList = list.stream().distinct().toList();
distinctList.stream().forEach(value -> System.out.println(value));
}
}
map()
메서드는 컬렉션의 요소들에 특정 연산을 적용한 새로운 스트림을 만들며 이때 입력으로 들어간 컬렉션의 수와 출력으로 나오는 컬렉션 수는 동일함
import java.util.Arrays;
import java.util.List;
public class Main {
public static void main(String[] args) {
String[] lowercaseArray = new String[]{"public", "static", "void"};
List<String> lowercaseList = Arrays.asList(lowercaseArray);
List<String> uppercaseList = lowercaseList.stream()
.map(value -> value.toUpperCase()).toList();
uppercaseList.stream().forEach(value -> System.out.println(value));
}
}
Optional
널이 들어 있는 레퍼런스 변수의 멤버에 접근하려고 할 때 발생하는 예외인 NullPointerException을 우하하게 해결하기 위해 등장
기술면접 TIP
1. IDE와 소스코드 편집기는 어떤 차이가 있나요?
통합개발환경인 IDE가 더 포괄적인 개념이라고 할 수 있다. IDE가 소스코드 편집기를 포함합니다. IDE는 개발에 필요한 여러 기능, 빌드를 자동으로 진행하거나 디버깅하는 기능, 소스코드를 편집할 수 있는 기능을 포함하고 있어 개발자의 사용 편의를 높임
2. 동일성과 동등성의 차이
두 인스턴스를 비교할때 사용되는 개념이다. 동일성은 '두 인스턴스가 같은 존재'인지 판단하는 것으로, 자바에서 '==' 연산자로 두 인스턴스 레퍼런스 변수를 비교함, 비교 결과가 true이면 동일한 인스턴스입니다.
동등성은 두 인스턴스 '같은 값인지' 확인하는 것으로, String 클래스의 자바의 equals() 메서드를 통해 확인하고, 직접 선언한 클래스는 equals() 메서드를 오버라이딩해 어떤 조건에서 동등하다고 판단할지를 정해 줘야 함
3. 객체지향에 대해 설명해 보시오.
객체 지향의 핵심은 추상화와 다형성입니다. 추상화와 다형성은 곧 인터페이스로 연결되는데요, 인터페이스 없이 애플리케이션을 개발하면 클라이언트 코드가 구체적인 클래스에 의존하게 되고, 하나의 클래스가 변경되면 다른 클래스도 계속해서 변경해 줘야 하는 문제가 생김. 이런 문제를 해결하려면 클라이언트 코드가 구체적인 클래스가 아니라 인터페이스에 의존해야 한다. 결국 클라이언트 코드와 구체적인 클래스 모두 인터페이스에 의존하게 되는 것이다.
이처럼 코드 변경시 몇 가지 이점이 있다.
첫째, 클라이언트 코드는 해당 인터페이스를 구현하고 있는 구체적인 클래스의 세부 구현을 몰라도 된다.
인테페이스에 의존하고 있기 떄문에 구체적인 클래스가 바뀌더라도 인터페이스가 바뀌지 않는 경우 클라이언트 코드로 변경 내용이 전파가 되지 않음
둘째 클라이언트 코드는 해당 인터페이스를 구현하고 있는 구체적인 클래스가 구현되지 않아도 자신의 코드를 개발할 수 있음.
테스트 코드를 만들어 해당 인터페이스가 해야 하는 역활에 대해 정의만 주기만 하면 된다.
추상적인 존재는 보통 다형성도 가진다. 인터페이스는 레퍼런스 변수는 해당 인터페이스를 구현하는 여러 클래스들의 인스턴스를 다음 수 있다. 그리고 레퍼런스 변 수 안에 어떤 인스턴스가 들어 있는지 신경 쓰지 않고 메서드를 호출하면 안에 들어 있는 인스턴스의 종류에 따라 완전히 다른 동작이 실행될 수 있습니다. 만약 이런 성질 없이 인터페이스가 '필수로 구현 해야 할 메서드의 집합' 역할만 했으면, 인터페이스를 선언해도 추상화했을 때의 이점을 누릴 수 없게 될 것입니다.
4. ArrayList크기가 어떻게 변하는지 설명해보세요.
자바 버전마다 그 구현 방식이 다를 수 있지만, 기본적인 틀은 최초 ArrayList 내부에 특정 크기의 배열이 생성된 다음 용량이 가즉 찰 때 마다 일정비율로 늘려간다고 알고 있습니다. 자바 8 버전 이상으로 기준으로 했을때 크기를 지정하지 않으면 최초 10 크기의 배열이 생성되고, 용량이 가득 찰 때마다 1.5배씩 늘어나는 것으로 기억함.
5. 오버라이딩과 오버로딩 차이점
오버라이딩은 부모 클래스에 정의된 메서드를 자식 클래스에 새롭게 정의하는 것 오버로딩은 동일한 메서드의 이름으로 서로 다른 파라미터와 리턴 타입의 메서드를 여러개 정의하는 것을 의미
5.1 오버라이딩과 오버로딩의 조건을 각각 설명해 보세요.
오버라이딩은 상속과 관련된 개념으로, 부모 클래스(슈퍼 클래스)의 메서드를 자식 클래스(서브 클래스)에서 재정의하는 것을 말합니다. 이를 통해 자식 클래스에서 부모 클래스의 메서드를 변경하여 사용할 수 있습니다.
오버로딩은 같은 클래스 내에서 동일한 이름을 가진 메서드를 여러 개 정의하는 것을 말합니다. 이때 메서드의 매개변수의 타입, 개수, 순서가 달라야 합니다. 오버로딩은 컴파일 타임에 결정됩니다.
'Java' 카테고리의 다른 글
자바의 Record? 그게 뭐야? (0) | 2025.01.08 |
---|---|
Java 변수의 초기값 (1) | 2024.11.18 |
String / StringBuffer / StringBuilder 차이 (1) | 2024.11.13 |
아니 인터페이스는 뭐고.. 추상클래스는 뭐야!? (0) | 2024.11.06 |
[JAVA] Java String reverse(문자열 뒤집기) (0) | 2024.06.05 |