본문 바로가기
Study/JSCODE - 자바

1주차 스터디 노트

by Dev Lighthouse 2024. 8. 16.
320x100
320x100

아래의 질문들에 대해 학생/취준생/이직 준비자 등등 다 답해보자

자바 기본

자바 객체지향

 

 


난 실천 없는 지식은 크게 의미 없다고 생각해서.. 직접 Empty 프로젝트를 만들고 각각 버전을 가진 모듈을 추가했다

그리고 LTS버전으로만 추가했다. 8, 11, 17, 21

내 블로그로 혹시나 자바 개념을 잡아볼 학생이라면, 텍스트만으로 자바8~21까지 버전을 배우기보다는 직접 코드로 쳐보고, 기록을 남겨가면서 배워줬으면 좋겠다

또한 LTS버전이 아닌 9, 10, 12, 13, 14, 15.. 이런 버전은 굳이 공부할 필요가 있나..?싶기도하다

기업 또한 언젠가 지원이 끊길 minior 버전을 사용하는 곳은 거의 없을거라고 생각한다

굳이 면접에 들어가서 "자바13에서 switch구문에 람다 표현식 기능이 Preview로 추가됐어요!!"라고 말해봤자 큰 이득은 없을 것 같다..

추가로 Preview기능또한 LTS에서 추가되기 전에 미리 학습할 필요가 없다고 생각한다

단순히 면접 통과용으로 <Java버전별 차이>를 검색해서 달달 외우기보다 직접 눈으로, 손으로, 깃허브로 공부기록이라도 남겨가면서 체화해보길 권장하는 바이다

그리고 제발 남의 블로그 글을 단순히 복붙하는 블로거가 되지 않길 바란다. 출처도 밝히고, 그 코드를 내가 직접 실행해서 눈으로 보자!

LTS 버전 - 8, 11, 17, 21

각 모듈마다 다른 버전으로 실행되는지 테스트 + 실행할때마다 Main, Main(1), Main(2)이렇게 뜨는게 거슬려서 실행환경도 고정해줬다

Run Configuration에서 변경
java8 - corretto1.8(아마존꺼)
java11 - corretto11(아마존꺼)

마지막으로 java8버전과의 비교를 위해서 JDK1.7 버전 또한 Oracle에서 직접 다운로드 받아서 추가해줬다

자바 기본

Java의 특징에 대해서 알려주세요

더보기
  • Platform Independent - 플랫폼 독립적
    • Windows, Linux, Mac에 상관없이 JVM이 플랫폼 위에 맞는 bytecode로 변환하기 때문
  • Object-Oriented Programming - 객체 지향 프로그래밍
    • 객체지향의 4가지 특징인 캡상추다 < 제가 외울때 쓰는 말입니다ㅋ
    • Encapsulation - 캡슐화
    • Inheritance - 상속
    • Abstraction - 추상화
    • Polymorphism - 다형성
  • Simplicity - 단순함
    • C++에 기초한 언어
    • 명시적 포인터, 연산자 오버로딩 등 혼란을 주는 기능이나 자주 사용하지 않는 것들 제거
  • Robustness - 견고성
    • GC에 의해서 자동으로 관리되는 메모리
    • 즉, 믿을 수 있고, 쉽게 에러가 발생하지 않는 어플리케이션 개발 가능
  • Security - 보안
    • 포인터가 없으므로 범위를 벗어난 배열에 엑세스 불가
    • 스택 손상, 버퍼 오버플로와 같은 여러 보안 결함을 자바에서 악용하는 것 방지
    • JVM Sandbox 내에서 프로그램 실행
    • Classloder: 네트워크 소스로부터 가져온 것들에서 로컬 파일 시스템 클래스의 패키지로 분리시켜 보안 강화
    • Bytecode verifier: 객체로 정당한 접근을 침해할 수 있는 불법적인 코드조각을 확인하여 보안 강화
    • Security manager: 클래스가 로컬 디스크의 읽기와 쓰기 등에 접속할 수 있는 리소스를 결정해 보안 강화
  • Distributed - 분산
    • RMI(Remote Method Invocation) - 원격 메서드 호출
    • EJB(Enterprise Java Beans) - 엔터프라이즈 자바 빈
    • 분산된 어플리케이션을 만들기 위해서 사용. 인터넷 연결을 통해 서로 연결된 하나 이상의 시스템에 쉽게 분산 가능
  • Multithreading - 멀티스레딩
    • 자바는 멀티스레딩을 지원해서 프로그램의 여러 부분을 동시에 실행 가능
    • 고성능이 필요한 애플리케이션에 유용
  • Portability - 이식성
    • Java bytecode를 모든 플랫폼에게 옮길 수 있고, 실행 가능
    • WORA(Write Once Run Anywhere)
  • High Performance - 고성능
    • 런타임 중의 오버헤드를 줄이는 방식으로 정의되어 있음
    • JIT 컴파일러를 통해 필요에 의해 호출되는 메서드만 컴파일하여 애플리케이션의 실행 속도 향상
    • 컴파일이 된 상태라면 전통적인 인터프리트 언어보다 빠름
  • Architecture neutral - 중립적인 아키텍처
    • 특성에 의존하는 구현이 없음
    • primitive type의 크기가 고정되어 있음
    • C는 int는 32bit 아키텍처의 경우 2바이트, 64bit 아키텍처의 경우 4바이트의 메모리를 차지
    • Java는 32/64bit 아키텍처 모두 4바이트의 메모리 차지
  • Interpreted - 소스코드 to 기계어
  • Dynamic - 동적
    • 클래스의 동적 로딩 지원
    • 네이티브 언어인 C, C++ 함수 지원

 

출처

https://www.javatpoint.com/features-of-java

 

Features of Java - Javatpoint

features of java, advantages, programming, main, java, language, important, explain, secured, robust, simple , object oriented, portable, platform independent, dynamic, distributed, interpreted, multi threaded, interpreted

www.javatpoint.com

 

https://www.geeksforgeeks.org/introduction-to-java/

 

Introduction to Java - GeeksforGeeks

Java is a versatile, beginner-friendly programming language known for its 'write once, run anywhere' capability. Explore how Java's simple, object-oriented approach has made it essential for mobile apps, web development, and more.

www.geeksforgeeks.org

https://tworab.tistory.com/10

 

자바(JAVA)의 특징

자바의 특징 자바에는 많은 기능이 주어집니다. 이 기능들은 자바 전문용어로 잘 알려져 있습니다. 자바 기능들은 단순하고 이해하기 쉽도록 아래와 같이 나열하였습니다. 1. Simple( 단순함 )2. Obj

tworab.tistory.com

 

 

Java의 단점에 대해서 설명해주세요.

더보기
  • 성능
    • JVM(자바 가상 머신) 위에서 동작하기 때문에 C++ 등 다른 프로그래밍 언어에 비해 느릴 수 있음
  • 메모리 관리
    • GC가 메모리를 관리하기 때문에 성능이 저하되고, 메모리 사용량이 늘어날 수 있음
  • 구문이 장황함
    • 같은 기능이더라도 Python이나 Kotlin언어보다 더 많은 코드줄이 필요
  • 저수준 액세스
    • 보안과 이식성을 높이기 위해 의도적으로 시스템 리소스에 대한 저수준 엑세스를 제한
    • 하드웨어 조작이 필요한 수준의 애플리케이션으로는 적합하지 않음
  • 다중 상속 미지원
    • 하나의 슈퍼클래스에서만 상속 가능
    • 프로그래머가 일반적인 문제를 해결하기 위해 활용할 수 있는 디자인 패턴을 제한할 수도 있음
    • 이 다중 상속 미지원은 장점이 될수도 있고 단점이 될 수도 있으나 장점이 더 크게 작용하긴 함
  • 레거시 코드와의 호환성
    • Java는 많은 업데이트가 이루어졌고, 이전 버전과의 호환을 지원하기 위해 많은 노력을 함
    • 이때문에 개발자는 이전 버전의 java로 빌드된 과거 소프트웨어를 업그레이드하는 것이 어려울 수 있음
  • 학습 곡선
    • 프로그래밍을 처음 접하는 경우 Python, Kotlin언어보다 배우기 어려움(하지만 C보다는 쉬움)

 

출처

https://www.developer.com/java/advantages-and-disadvantages-of-java/#disadvantages

 

 

Java 실행 과정에 대해서 설명해주세요.

더보기

2022년 8월에 작성한 내 글이 있긴 하다ㅋㅋ

https://code-boki.tistory.com/80

 

Compile, Link, Build, Run (feat. C vs JAVA)

프로그램을 작성하다보면 컴파일 타임, 런타임이란 용어들을 접하고... 컴파일, 런타임을 검색하다보면 링크, 빌드, 바인드 이런 용어들도 접하게 된다 그럼 이제부터 과연 이게 무엇인지에 대

code-boki.tistory.com

 

  1. 소스파일 작성 - java 코드 작성(.java)
  2. 컴파일 - javac라는 자바 컴파일러에 의해 .class 확장자를 가진 바이트코드가 생성
  3. 클래스 로딩 - JVM의 class Loader(클래스로더)에서 .class파일을 lazy loading함
  4. 유효성 검증 - Bytecode verifier(바이트코드 검증기)가 .class파일이 Java언어, JVM 명세에 맞게 작성되어있나 검사함
  5. 링크 - 유효성 검증 이후에 메모리를 기본값으로 초기화하고 클래스변수를 할당. 클래스의 constant pool내의 심볼릭 참조를 직접 참조로 변경
  6. 초기화 - static 변수들이 정의된 값으로 초기화됨(bootstrap/extension/system loader/application loader)
  7. 실행 - Runtime Engine(실행 엔진)에서 .class파일을 인터프리터 or JIT 두가지 방식 중 한가지 방법으로 기계어인 binary code로 변환해서 실행

출처

https://code-boki.tistory.com/80

 

Compile, Link, Build, Run (feat. C vs JAVA)

프로그램을 작성하다보면 컴파일 타임, 런타임이란 용어들을 접하고... 컴파일, 런타임을 검색하다보면 링크, 빌드, 바인드 이런 용어들도 접하게 된다 그럼 이제부터 과연 이게 무엇인지에 대

code-boki.tistory.com

 

https://junhyunny.github.io/information/java/jvm-execution-engine/

 

JVM 실행 엔진(Execution Engine)

<br /><br />

junhyunny.github.io

 

Java Bytecode에 대해서 설명해주세요.

더보기

여기에서 내가 위에서 만든 프로젝트에서 Java8에서 Main클래스에 있는 main 함수를 실행해봤다

이후 out디렉토리 경로에 보면 .class파일이 생성된 것을 볼 수 있다

이게 바로 bytecode이다

.java(source) -> .class(bytecode)

컴파일
바이트 코드를 IntelliJ 내에서 확인해 본 모습

이번에는 cat 명령어로 내부를 확인해본다

cat 명령어로 본 class파일

이번에는 hex코드를 볼 수 있는 plugin을 설치해서 확인해본다

hex/binary file viewer
binary editor
class 파일 내부

사실 내부를 까보면 이런 형태이다. 이 바이트코드를 JVM에서 읽는 것이다

그럼 이제는 이 .class 파일을 javap 명령어를 통해 디컴파일링(역 어셈블)해보자

javap -v -p -s Main

-v는 verbose로 보통 다른 명령어에서도 cli를 통해 더 디테일하게 설명을 볼때 사용하는 옵션이다

-p는 private로 모든 private한 클래스와 멤버들을 보겠다는 옵션이다

-s는 signature로 메서드와 필드의 시그니처를 보겠다는 옵션이다

 

인텔리제이의 내부 콘솔로는 부족해서 터미널을 따로 열어서 실행해봤다

bytecode 역어셈
Classfile /Users/boki/IdeaProjects/java-versions/out/production/java8/Main.class
  Last modified 2024. 8. 16.; size 510 bytes
  SHA-256 checksum deac67cd0898f8a33cfde7135e67fbcdb3c647dbf597bec87d82926dd8b723ba
  Compiled from "Main.java"
public class Main
  minor version: 0
  major version: 52
  flags: (0x0021) ACC_PUBLIC, ACC_SUPER
  this_class: #5                          // Main
  super_class: #6                         // java/lang/Object
  interfaces: 0, fields: 0, methods: 2, attributes: 1
Constant pool:
   #1 = Methodref          #6.#20         // java/lang/Object."<init>":()V
   #2 = Fieldref           #21.#22        // java/lang/System.out:Ljava/io/PrintStream;
   #3 = String             #23            // java 8
   #4 = Methodref          #24.#25        // java/io/PrintStream.println:(Ljava/lang/String;)V
   #5 = Class              #26            // Main
   #6 = Class              #27            // java/lang/Object
   #7 = Utf8               <init>
   #8 = Utf8               ()V
   #9 = Utf8               Code
  #10 = Utf8               LineNumberTable
  #11 = Utf8               LocalVariableTable
  #12 = Utf8               this
  #13 = Utf8               LMain;
  #14 = Utf8               main
  #15 = Utf8               ([Ljava/lang/String;)V
  #16 = Utf8               args
  #17 = Utf8               [Ljava/lang/String;
  #18 = Utf8               SourceFile
  #19 = Utf8               Main.java
  #20 = NameAndType        #7:#8          // "<init>":()V
  #21 = Class              #28            // java/lang/System
  #22 = NameAndType        #29:#30        // out:Ljava/io/PrintStream;
  #23 = Utf8               java 8
  #24 = Class              #31            // java/io/PrintStream
  #25 = NameAndType        #32:#33        // println:(Ljava/lang/String;)V
  #26 = Utf8               Main
  #27 = Utf8               java/lang/Object
  #28 = Utf8               java/lang/System
  #29 = Utf8               out
  #30 = Utf8               Ljava/io/PrintStream;
  #31 = Utf8               java/io/PrintStream
  #32 = Utf8               println
  #33 = Utf8               (Ljava/lang/String;)V
{
  public Main();
    descriptor: ()V
    flags: (0x0001) ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                  // Method java/lang/Object."<init>":()V
         4: return
      LineNumberTable:
        line 2: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       5     0  this   LMain;

  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=1, args_size=1
         0: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
         3: ldc           #3                  // String java 8
         5: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
         8: return
      LineNumberTable:
        line 4: 0
        line 5: 8
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       9     0  args   [Ljava/lang/String;
}
SourceFile: "Main.java"

 

자바 클래스 파일의 10개 섹션이라고 한다

 

 

출처

https://en.wikipedia.org/wiki/Java_class_file

 

Java class file - Wikipedia

From Wikipedia, the free encyclopedia Executable Java file format Java class fileInternet media typeapplication/java-vm, application/x-httpd-java, application/x-java, application/java, application/java-byte-code, application/x-java-class, application/x-ja

en.wikipedia.org

 

https://tlo-developer.tistory.com/262

 

[JAVA 실습 #8] javap 정리

자바(JAVA) 실습 - javap 명령어 정리 > OpenJDK 1.8 (openjdk version 1.8.0_292) > javap 명령어는 하나 이상의 class를 역어셈블한다. javap의 결과값은 사용한 옵션에 따라 달라진다. javap 옵션 없이 실행하는 경우

tlo-developer.tistory.com

 

https://wonit.tistory.com/589

 

[조금 더 깊은 Java] Java Bytecode 를 알아보자 (자바를 컴파일하면 어떤 일이 일어날까?)

우리는 많은 시간 Java를 이용해서 다양한 소프트웨어를 개발하면서 들었던 소리가 있다. Java는 JVM 이 있기 때문에 플랫폼에 종속적이지 않고 이식성이 뛰어나다. 그 이유에 대해서 생각해본 경

wonit.tistory.com

 

Java의 인터프리터(interpreter) 방식과 JIT 컴파일(compile) 방식에 대해서 설명해주세요.

더보기
  • 인터프리터 방식
    • 컴파일 과정 없이 바이트코드를 즉시 실행
    • 바이트코드를 한 줄씩 해석하고 실행하므로 성능이 낮을 수 있음
    • 반복적인 코드가 있을 경우 매번 해석해야 하므로 실행 속도가 느림

 

  • JIT 컴파일 방식
    • 실행 중인 바이트코드의 일부를 네이티브 기계어로 변환하여 실행하는 방법
    • 프로그램이 실행되는 동안 "필요한 시점"에 바이트코드를 컴파일하여 네이티브 코드로 변환
    • 프로그램이 처음 실행될 때는 인터프리터가 바이트코드를 해석하여 실행
    • JVM은 자주 실행되는 코드(핫스팟)를 탐지, 이러한 부분을 JIT 컴파일러에 전달하여 네이티브 코드로 컴파일
    • 네이티브 코드로 변환된 부분은 인터프리터 방식보다 훨씬 빠르게 실행
    • 동적 최적화 - 실행 중에 최적화를 수행할 수 있으며, 런타임 정보에 기반한 최적화를 통해 성능을 높일 수 있음
    • 초기 오버헤드 - 처음 JIT 컴파일이 이루어질 때는 컴파일 시간으로 인해 약간의 지연이 발생할 수 있음
    • 메모리 사용량 증가: 네이티브 코드를 메모리에 유지해야 하므로 메모리 사용량이 증가할 수 있음

 

사용해본 Java 버전과 특징 그리고 왜 그 버전을 사용했는지 설명해주세요.

더보기

2022년도에는 Java 11버전을 주로 사용했었다

2023년부터는 Java 21버전을 주로 사용했었다

2024년 현재도 Java 21버전으로 프로젝트를 만들고 있다

 

이유는 LTS(Long Term Support) 버전들이고, Kotlin으로 마이그레이션 할 수 있는 최소버전이 17이고, 2023년 11월에 발표된 Spring boot6에서는 Java17을 based version으로 지정하고 있기 때문에 사용했다

 

Java 8, 11, 17 버전에 대해 아는대로 설명해주세요.

더보기

- Java 8

1.8버전에 추가된 Stream api
java7버전에서는 사용 못하는 람다 표현식. 우측은 java8의 람다 표현식

 

  • 람다 expression 추가
  • Stream API 추가
  • Optional Class 도입
  • 날짜 및 시간 API 추가

 

- Java 11

java8에서는 살펴볼 수 없는 strip() 메서드
java11에서 추가된 of 메서드
  • String 관련 메서드 추가 - strip(), isBlank(), repeat()
  • Files 관련 메서드 추가 - readString(), writeString()
  • Collection 관련 메서드 추가 - toArray(), of()
  • Predicate 관련 메서드 추가 - not()
  • Java10에 도입된 var키워드를 람다 파라미터로 전달 가능 - .map((var x) -> x.to...)
  • javac로 컴파일하지 않고 java 명령어로 바로 실행 가능

 

- Java 17

  • Text Blok - """ """로 문자열을 감싸서 가독성 있는 multi line 문자열을 입력할 수 있다
  • Switch lambda, multi condition, skip default
  • Instance of 패턴 매칭 확장
  • Record
  • Sealed class
  • toList(), not Collections.toList()

 

참고

https://blogs.oracle.com/javakr/post/java8-16

 

https://blogs.oracle.com/javakr/post/java8-16

 

blogs.oracle.com

https://techblog.gccompany.co.kr/우리팀이-jdk-17을-도입한-이유-ced2b754cd7

 

우리팀이 JDK 17을 도입한 이유

안녕하세요, T플랫폼개발실 개발3팀 제이든입니다. 이번 포스팅에서는 저희팀에서 Java 17 버전을 도입하게 된 이유와 개발자 입장에서 주요하다 생각되는 업데이트 내용 및 사용사례를 소개드리

techblog.gccompany.co.kr

 

JDK와 JRE에 대해서 설명해주세요.

더보기
  • JDK: Java Development Kit. 내부에 JRE가 포함되어 있음
    • javac : 자바 컴파일러로 자바 소스를 바이트 코드로 컴파일
    • java : 자바 인터프리터. 컴파일러가 생성한 바이트 코드를 해석하고 실행
    • javadoc : 자바 소스로부터 HTML 형식의 API 도큐먼트 생성
    • jar : 자바 클래스 파일을 압축한 자바 아카이브 파일(.jar) 생성, 관리하는 압축 프로그램 (like zip)
    • jmod : 자바의 모듈 파일(.jmd)을 만들거나 모듈 파일의 내용 출력
    • jlink : 응용프로그램에 맞춘 맞춤형 JRE 생성
    • jdb : 자바 응용프로그램의 실행 중 오류를 찾는 데 사용하는 디버거
    • javap : 역어셈블러. 컴파일된 클래스 파일을 원래의 소스로 변환
  • JRE: Java Runtime Environment
    • JVM: 자바 바이트코드를 실행하는 가상머신
    • 라이브러리: 자바 표준 라이브러리 클래스와 필수 런타임 라이브러리

 

추가로...  도커에서 실행되는 이미지를 만들때는 굳이 FROM을 JDK이미지를 쓸 필요가 없다

https://bcho.tistory.com/1356

 

효율적인 도커 이미지 만들기 #1 - 작은 도커 이미지

효율적인 도커 이미지 만들기#1 작은 도커 이미지 만들기조대협 (http://bcho.tistory.com) 일반적으로 도커를 이용해서 자바 애플리케이션 컨테이너를 빌드하면 보통 사이즈가 500~700M 로 배우 큰 이미

bcho.tistory.com

 

출처

https://inpa.tistory.com/entry/JAVA-%E2%98%95-JDK-JRE-JVM-%EA%B0%9C%EB%85%90-%EA%B5%AC%EC%84%B1-%EC%9B%90%EB%A6%AC-%F0%9F%92%AF-%EC%99%84%EB%B2%BD-%EC%B4%9D%EC%A0%95%EB%A6%AC

 

☕ JDK / JRE / JVM 개념 & 구성 원리 💯 총정리

자바를 처음 설치하면 C:\Program Files\Java 폴더에 아래와 같이 JDK와 JRE 가 각각 설치되는 것을 볼 수 있다. 그렇다면 이 JDK와 JRE의 역할은 무엇인지 그리고 자바 프로그램(JVM)은 어떤식으로 돌아가

inpa.tistory.com

 

 

동일성과 동등성에 대해 설명해 주세요.

더보기
  • 동일성
    • Identity 
    • 두 객체가 같은 메모리 위치를 참조하고 있는지를 의미
  • 동등성
    • Equality
    • 두 객체가 같은 값을 가지고 있는지를 의미

 

equals()와 ==의 차이점은 무엇일까요?

더보기
  • equals()
    • 동등성을 비교하기 위한 연산자
  • ==
    • 동일성을 비교하기 위한 연산자
     

아래 스크린샷에서 fruit1과 fruit2는 각각 다른 주소값(해시로 치환됨. 접근 불가. 확인만 가능)을 갖고 있는 것을 볼 수 있다

 

HashCode를 설명하고, equals() 와 hashCode() 의 차이점에 대해 설명해 주세요.

더보기
  • HashCode
    • 객체를 식별하는 정수값을 반환하는 메서드
  • equals() vs hashCode()
    • equlas()는 두 객체가 동일한 내용을 갖고 있는지 확인
    • hashCode()는 객체의 고유한 해시코드를 반환

 

 

왜 equals() 외에 hashCode() 도 재정의해야 하나요?

더보기
  • 해시 기반 컬렉션(HashMap, HashSet)에서 객체를 정확하게 저장/검색하려면 equals()와 hashCode()가 일관되게 동작해야 함
  • JPA에서도 엔티티의 동일성을 보장하기 위해 보통 재정의하는 메서드임!

 

toString()에 대해서 설명해주세요.

더보기
  • toString() 메서드는 객체의 문자열 표현을 반환
  • 기본적으로 클래스 이름과 해시코드를 포함한 문자열을 반환
  • 개발할때는 보통 재정의하여 사용하는 편!
  • JPA에서 toSring()메서드를 재정의하여 Eager 엔티티의 호출을 막는게 기본이자 중요한 팁~!

 

자바에서 메인 메서드는 왜 static으로 되어 있을까요?

더보기
  • main 메서드는 자바 애플리케이션의 시작점
  • 프로그램이 시작될 때 자바 가상 머신(JVM)은 main 메서드를 호출하여 프로그램을 실행
  • main 메서드가 static으로 되어 있는 이유는, JVM이 애플리케이션을 시작할 때 객체를 생성하지 않고도 main 메서드를 호출할 수 있어야 하기 때문
  • 객체를 생성하지 않고 클래스 레벨에서 바로 실행할 수 있도록 하기 위해 static으로 선언됨
  • Kotlin에서도 main메서드를 실행할때도 @JvmStatic 어노테이션을 붙이거나, 코틀린 파일로 만들어서 main 메서드를 만듦!

 

상수(Constant)와 리터럴(Literal)에 대해서 설명해주세요.

더보기
  • 상수(Constant): 프로그램에서 변경되지 않는 값. final 키워드를 사용
  • 리터럴(Literal): 프로그램에서 코드 내에 직접 명시된 고정된 값. 

 

Primitive Type과 Reference Type에 대해서 설명해주세요.

더보기
  • Primitive Type
    • 기본 데이터 유형
    • 자바에서 미리 정의된 단순 데이터 타입
    • null 값을 가질 수 없음
    • int, char, float, boolean 등
  • Reference Type
    • 객체나 배열 같은 복잡한 데이터 유형
    • 실제 데이터는 메모리의 다른 위치에 저장
    • null 값을 가질 수 있음
    • 변수는 그 위치를 참조
    • 객체, 클래스, 배열
    • Integer, Character, String, Float, Boolean

 

Java는 Call by Value 일까요? 아님 Call by Reference 일까요?

더보기

Java는 Call By Value를 사용한다

사실 이 질문이 조금 옳지 않다고 생각하는데.. 추후 다른 글로 덧붙일 예정이다!

 

일단 다른 블로그들은 너무 추상적이거나 어렵게만 설명한 것 같아보인다

용어 하나하나부터 짜르고 들어가보자

 

Call? 이란 무엇일까?

내가 vba다음으로 배운 언어인.. C언어를 예로 들어본다

C언어를 배울때 나오는 것은 함수의 선언/호출/정의부 용어가 나온다

영어로는 Declaration/Call/Definition라고 한다

함수 선언/호출/정의부

그럼 이제 알았다! Call은 함수를 불러다 쓰는 부분이라는 것이다

 

그럼 by Value와 by Reference를 해석해보자

by Value: 값에 의해 / by Ref(생략): 참조에 의해

 

앞에서 찾은 Call을 붙여서 다시 해석해보자 Call By Value: 값에 의한 호출 / Call by Ref: 참조에 의한 호출

흠 드디어 개념 설명이 끝났다..휴

그래서 그게 뭔데?

일단 Function또는 Method에서 signature는 argument를 의미한다. 그리고 body는 { } 내부를 말한다

 

자바에서는 메서드 호출 시마다 Stack Frame이라는 공간이 생기고, { } 해당 메서드 내부에서 선언된 지역 변수들을 저장하는 공간이다

지역 변수들을 저장하는 공간 < 여기가 중요한 키워드이다

변수는 어디에 저장될까? 메모리이다

객체도 메모리이다

다만 자바에서는 스택, 메서드(Static, metaspace[자바8이후]) / 힙 영역 / 기타(PC레지스터, Nativce[JNI]) 영역 등이 있다

 

스택 영역: 지역변수

메서드 영역: 클래스/상수/필드 정보/메서드 정보

힙 영역: 동적으로 생성된 객체나 배열

 

사실 Call By Value / Call By Ref를 사전적 직독직해 말고 안에 돌아가는 걸 찾아보면

- Call By Value: 메서드가 호출될 때 인자로 전달된 변수의 "값"이 복사되어 전달

- Call By Ref: 객체의 참조(주소)가 전달될 때도 "값에 의한 호출"로 처리. 참조(객체의 메모리 주소)를 복사해서 전달하기 때문

 

그러면 메서드 body의 시작인 { 를 만나면 Stack Frame이라는 공간이 생기고 그 안에서(Stack Frame 내부에서) 

1. 기본 데이터 타입(인자 포함)을 사용하면?

- 메서드가 호출되면 새로운 Stack Frame이 생성

- Stack Frame 내에서 지역 변수와 메서드 인자가 저장됨

- primitive 데이터 타입의 경우, 값이 복사되어 전달되므로, 호출부와 정의부에서 서로 다른 메모리 주소에 저장된 2개의 독립적인 값을 갖게 됨

=> 메서드 내에서 이 값을 변경해도, 원본 변수에는 영향을 미치지 않음

요약: 값 복사가 일어나면서 (호출부/정의부) 서로 다른 메모리 주소를 갖는 2개의 데이터를 사용

 

2. 참조 타입(인자 포함)을 사용하면?

- 객체 타입의 경우, 메서드 호출 시 객체의 참조(주소)가 복사됨

- Stack Frame 내에서 사용되며, 원본 객체와 동일한 메모리 주소를 가리킴

=> 이 때문에 메서드 내에서 이 참조된 객체의 속성을 변경하면 실제 객체의 값이 변경됨

but!!) 메서드 내에서 참조 변수를 새로운 객체로 변경(재할당)하면, 복사된 참조 변수만이 새로운 객체를 가리키게 되고, 원본 참조 변수에는 영향을 미치지 않음

요약: 참조 복사가 일어나면서 (호출부/정의) 서로 같은 메모리 주소를 사용하기때문에 1개의 주소참조를 사용 + 메서드 내에서 이 참조된 객체의 속성을 변경하면 실제로 값 변경이 일어나지만, 새로운 객체로 변경(재할당)하면, 복사된 참조 변수만이 새로운 객체를 가리키게 됨

 

-------------------------

 

가장 중요한 Why파트이다

Q. 왜 Java는 Call By Value를 선택했을까?

A. 메서드 내부의 변경이 외부로 영향을 미치는 side effect를 전달할 가능성을 줄임

- 1. 단순성과 예측 가능성: 메서드 호출의 동작을 쉽게 이해하고 예측할 수 있게 함

- 2. 안정성: 외부 변수의 상태가 예기치 않게 변경되는 것을 방지

- 3. 객체지향 프로그래밍 조화: 객체의 상태를 제어하면서도 참조 자체의 변경이 외부에 영향을 미치지 않도록 함

- 4. 언어의 일관성: 단순하고 안전한 언어 설계를 유지

- 5. 메모리 관리의 효율성: 객체 참조를 복사하여 메모리 사용을 최소화

- 6. 컴파일러 최적화와 성능: 성능 최적화를 더 효율적으로 수행할 수 있음

 

Java 직렬화(Serialization)에 대해서 설명해주세요.

더보기

자바 Serialization은 객체의 상태를 바이트 스트림으로 변환하여 파일, 네트워크를 통해 전송하거나 저장하는 기술입니다. 이 과정은 객체의 지속성을 확보하고, 분산 환경에서 객체를 쉽게 공유할 수 있게 해줍니다. 객체를 직렬화하기 위해서는 해당 객체의 클래스가 java.io.Serializable 인터페이스를 구현해야 하며, 직렬화 과정은 ObjectOutputStream을 사용하여 수행됩니다.

 

역직렬화는 ObjectInputStream을 통해 이루어지며, 직렬화 과정에서 transient 키워드로 선언된 필드는 무시됩니다. 직렬화는 객체의 데이터를 안전하게 전송하고 저장하는 데 필수적이지만, 보안 측면에서 주의를 요합니다.

 

주의할점: serialVersionUID를 구현해야지 직/역질직렬화시 버전검증을 할 수 있음

 

출처

https://inpa.tistory.com/entry/JAVA-%E2%98%95-%EC%A7%81%EB%A0%AC%ED%99%94Serializable-%EC%99%84%EB%B2%BD-%EB%A7%88%EC%8A%A4%ED%84%B0%ED%95%98%EA%B8%B0

 

☕ 자바 직렬화(Serializable) - 완벽 마스터하기

자바의 직렬화 & 역직렬화 직렬화(serialize)란 자바 언어에서 사용되는 Object 또는 Data를 다른 컴퓨터의 자바 시스템에서도 사용 할수 있도록 바이트 스트림(stream of bytes) 형태로 연속전인(serial) 데

inpa.tistory.com

 

https://devloo.tistory.com/entry/%EC%9E%90%EB%B0%94-%EC%A7%81%EB%A0%AC%ED%99%94-%EC%82%AC%EC%9A%A9%EC%9D%84-%ED%94%BC%ED%95%B4%EC%95%BC-%ED%95%98%EB%8A%94-%EC%9D%B4%EC%9C%A0

 

자바 직렬화 사용을 피해야 하는 이유

오늘날 대부분의 백엔드 서비스는 마이크로서비스 아키텍처를 기반으로 구현됩니다. 서비스는 비즈니스 기능에 따라 분리되어 디커플링을 실현하지만, 이로 인해 새로운 과제가 생깁니다. 서

devloo.tistory.com

 

 

자바 객체지향

오버로딩과 오버라이딩의 차이는 뭔가요?

더보기

오버로딩(Overloading)

  • overloading: 과적하다. 많이 싣는다는 뜻
  • 오버로딩은 같은 이름을 가진 메서드를 여러 개 정의하는 것을 의미
  • 이름은 같지만 매개변수나 개수가 다른, 실실적으로 시그니쳐가 다른 메서드들을 정의
class Example {
    void print(int a) {
        System.out.println("Integer: " + a);
    }

    void print(double a) {
        System.out.println("Double: " + a);
    }

    void print(int a, int b) {
        System.out.println("Sum: " + (a + b));
    }
}

 

 

오버라이딩(Overriding)

  • overriding: 최우선의, 재 정의
  • 부모 클래스의 메서드를 자식 클래스에서 재정의하는 기법
사전적 해석
class Parent {
    void show() {
        System.out.println("Parent's show method");
    }
}

class Child extends Parent {
    @Override
    void show() {
        System.out.println("Child's show method");
    }
}

 

다형성이 무엇이고, 왜 필요할까요?

더보기

다형성은 하나의 객체에 여러 가지 타입을 대입할 수 있다는 것을 의미합니다. 다형성을 구현하는 방법으로는 오버로딩, 오버라이딩, 함수형 인터페이스를 사용하는 것이 있습니다. 다형성을 사용하면 코드 재사용성이 증가하고, 새로운 클래스가 추가되더라도 기존 코드를 수정할 필요가 없으므로 코드의 유연성이 높아집니다.

 

일단 다형성이란 말도 있지만, 영어 원문 책에서는 Polymorphism(폴리모피즘)이라고 불린다는 것을 알아두자

위에서 말한 오버로딩은 컴파일 타임 바인딩이 일어나게 하고(컴파일 시점에 바인딩이 됨), 컴파일 타임 다형성을 나타내는 형태이다

그리고 오버라이딩은 런 타임 바인딩이 일어나게 되고(실행 시점에 바인딩이 됨), 런 타임 다형성을 나타내는 형태이다

 

자바에서는 ArrayList, LinkedList -> List로 치환되는 등 이런 다형성을 적극 사용하고 있다~!

부모-자식 상속간에도 다형성이 적용된다

 

상속은 무엇인가요?

더보기

상속(Inheritance)은 객체 지향 프로그래밍에서 클래스 간의 관계를 정의하는 중요한 개념입니다.

상속을 통해 하위 클래스(자식 클래스)는 상위 클래스(부모 클래스)의 속성과 메서드를 물려받을 수 있습니다.

이를 통해 다형성을 구현할 수도 있고, 상위 클래스의 메소드나 필드를 하위 클래스가 재사용할 수 있고, 기존의 기능을 확장하거나 수정할 수 있습니다.

class Animal {
    void sound() {
        System.out.println("Some sound");
    }
}

class Dog extends Animal {
    @Override
    void sound() {
        System.out.println("Bark");
    }
}

class Cat extends Animal {
    @Override
    void sound() {
        System.out.println("Meow");
    }
}

public class Main {
    public static void main(String[] args) {
        Animal myDog = new Dog();  // Dog 타입의 객체를 Animal 타입으로 참조
        Animal myCat = new Cat();  // Cat 타입의 객체를 Animal 타입으로 참조

        myDog.sound();  // "Bark" 출력
        myCat.sound();  // "Meow" 출력
    }
}

 

상속의 단점은 무엇이 있을까요?

더보기

하위 클래스는 상위 클래스의 메소드나 필드를 사용할 수 있으므로 하위 클래스는 수동적인 객체가 될 수 있습니다. 또한, 기능 확장을 위해 잘 정의된 상위 클래스의 메소드를 오버라이딩하면 캡슐화를 깨뜨립니다.

 

상속과 조합의 차이에 대해 설명해 주세요.

더보기

상속은 객체들 간의 관계를 구축하여 다형성을 구현합니다. 이와 더불어 상위 클래스의 메소드나 필드를 하위 클래스가 재사용하거나 수정할 수 있습니다. 반면, 컴포지션(조합)은 A라는 객체가 B라는 객체를 의존하고 B 객체의 메소드를 사용할 뿐 다형성과는 관계가 없습니다.

 

상속(Inheritance)

  • 객체들 간의 관계를 구축하여 다형성을 구현. 상위 클래스의 메소드나 필드를 하위 클래스가 재사용하거나 수정할 수 있음
  • 간결하지만 강결합을 초래함(강결합 원인: 상위 클래스에 의존, 상속 구조[단일 상속]의 제한, 상속된 모든 기능을 가져야 함)
  • is-a 관계(Dog is a Animal. 강아지는 동물의 한 종류이다)
class Animal {
	...
}

class Dog extends Animal {
	...
}

 

조합(Composition)

  • A라는 객체가 B라는 객체를 의존하는 경우
  • 하나의 클래스가 다른 클래스의 인스턴스를 속성으로 가지는 경우
  • has-a 관계(Car has a Engine. 자동차는 엔진을 갖는다)
class Engine {
    //
}

class Car {
    private final Engine engine;

    Car(Engine engine) {
        this.engine = engine;
    }

    void drive() {
        System.out.println("Car is driving");
    }
}

 

그럼 논외로 조합은 강결합이 아닐까?

=> 그렇다고 볼 수 있다. 객체간 독립적인 관계를 유지하면서 서로 협력할 수 있게 하여, 클래스 간 결합을 느슨하게 할 수 있다
상속보다는 덜 강결합

 

instanceof 키워드란 무엇인가요?

더보기

특정 객체가 특정 클래스 또는 인터페이스의 인스턴스인지 여부를 확인할 때 사용하는 키워드이다

이 키워드는 런타임에 객체의 실제 타입을 검사하여, 객체가 지정된 클래스나 인터페이스의 인스턴스인지 여부를 boolean 값으로 반환한다

public static void main(String[] args) {
    System.out.println("java 11");

    Animal myDog = new Dog();

    if (myDog instanceof Dog) {
        System.out.println("myDog is an instance of Dog");
    }

    if (myDog instanceof Animal) {
        System.out.println("myDog is an instance of Animal");
    }

    if (myDog instanceof Object) {
        System.out.println("myDog is an instance of Object");
    }
}
instanceof

 

instanceof 키워드를 사용할 때 문제점으로 무엇이 있을까요?

더보기

- 로직상 구체적인 객체가 드러나므로, 캡슐화가 저해됨

- 로직이 바뀔 때마다 instanceof 분기 로직을 수정해야하므로 유지보수성이 떨어짐

- 런타임에 객체의 타입을 확인하므로 성능이 좋지 않음

 

interface란 무엇일까요?

더보기

특정 클래스에서 구현해야 하는 명세를 의미

 

interface와 abstract class는 어떤 차이가 있나요?

더보기
  • 상태(인스턴스 변수)
    • interface - 가질 수 없음. 대신 상수(literal)로 정의 하면 public static final로 변환되어, 하위 클래스에서 가져와서 사용 가능
    • abstract class - 가질 수 있음
interface에서 존재할 수 없는 인스턴스 변수
  • 다중상속
    • interface - 가능
    • abstract class - 불가능
다중상속
  • 접근제어자
    • interface - 모든 메서드가 public, 하지만 내부적으로 static, private은 가질 수 있음(둘 다 body를 정의해야됨)
    • abstract class - 접근 제한자를 자유롭게 사용 가능(private abstract은 제외)
인터페이스의 접근제어자
상속의 접근제어자

 

언제 interface 사용하고, 언제 abstract class 사용 하나요?

더보기

abstract class는 클래스 상속이므로 가능한 interface + default 메서드 기반으로 정의하는 편입니다.

만일 상태를 유의미하게 이용해야 하는 경우 abstract class를 사용합니다.

 

final 키워드에 대해 설명해 주세요.

더보기

- 변수에 붙일 경우, 1번만 초기화를 보장합니다.

- 메서드에 붙일 경우, 오버라이딩이 불가합니다.

- 클래스에 붙일 경우, 상속이 불가합니다.

 

'Study > JSCODE - 자바' 카테고리의 다른 글

3주차 스터디 노트  (2) 2024.08.29
2주차 스터디 노트  (0) 2024.08.22
JSCODE 스터디 신청  (0) 2024.08.16

댓글