기술 면접(자바 2)

유요한·2024년 2월 22일
0

기술면접

목록 보기
2/27
post-thumbnail

내부 클래스

클래스 내부에 클래스를 선언하여 외부 클래스의 필드에 쉽게 접근하기 위해 사용한다. 내부 클래스의 필드를 사용하기 위해서는 외부 클래스 객체에서 객체화해야 사용할 수 있다. 장점은 내부 클래스에서 외부 클래스 멤버들을 쉽게 접근할 수 있고 코드의 복잡성을 줄일 수 있다. 내부 클래스를 사용하는 이유는 상속 처럼 사용하고 캡슐화하여 다른 클래스에서는 내부에 쉽게 접근하지 못하도록 숨기기 위해서 사용한다.

💡Inner Class(내부 클래스)의 장점에 대해 설명해주세요.

  • 내부 클래스에서 외부 클래스의 멤버에 손쉽게 접근할 수 있다.

  • 서로 관련 있는 클래스를 논리적으로 묶어서 표현함으로써, 코드의 캡슐화를 증가시킨다.

  • 외부에서는 내부 클래스에 접근할 수 없으므로, 코드의 복잡성을 줄일 수 있다.


리플렉션(Reflection)이란 무엇인지 설명해주세요.

  • 리플렉션이란 구체적인 클래스 타입을 알지 못해도 그 클래스의 메소드, 타입, 변수들에 접근할 수 있도록 해주는 자바 API입니다.

  • 런타임 상황에서 메모리에 올라간 클래스나 메서드 등의 정의를 동적으로 찾아서 조작할 수 있는 기술

  • 컴파일 시간이 아닌 실행 시간에 동적으로 특정 클래스의 정보를 객체화를 통해 분석 및 추출해낼 수 있는 프로그래밍 기법

장점

런타임 시점에 사용할 인스턴스를 선택하고 동작시킬 수 있는 유연한 기능을 제공한다.

단점

  • 컴파일 시점이 아니라 런타임 시점에서 오류를 잡기 때문에 컴파일 시점에 확인할 수 없다.

  • 접근 제어자로 캡슐화된 필드, 메서드에 접근 가능해지므로 기존 동작을 무시하고 캐뜨리는 행위가 가능해진다.

사용처

  • 런타임 시점에 다른 클래스를 동적으로 로딩하여 접근할 때 사용

  • 클래스와 멤버 필드, 메서드 등에 관한 정보를 얻어야 할 때 사용


Error와 Exception의 차이를 설명해주세요.

  • Error는 실행 중 일어날 수 있는 치명적 오류를 말합니다. 컴파일 시점에 체크할 수 없고, 오류가 발생하면 프로그램은 비정상 종료되며 예측 불가능한 UncheckedException에 속합니다.

  • 반면, Exception은 Error보다 비교적 경미한 오류이며, try-catch를 이용해 프로그램의 비정상 종료를 막을 수 있습니다.


접근제어자

private

private 접근 제어자를 사용하여 선언된 클래스 멤버는 외부에 공개되지 않으며, 외부에서는 직접 접근할 수 없다. 즉, 자바 프로그램은 private 멤버에 직접 접근할 수 없으며, 해당 객체의 public 메소드를 통해서만 접근할 수 있다. 따라서 private 멤버는 public 인터페이스를 직접 구성하지 않고, 클래스 내부의 세부적인 동작을 구현하는 데 사용된다.

public

public 접근 제어자를 사용하여 선언된 클래스 멤버는 외부로 공개되며, 해당 객체를 사용하는 프로그램 어디에서나 직접 접근할 수 있다. 자바 프로그램은 public 메소드를 통해서만 해당 객체의 private 멤버에 접근할 수 있다. 따라서 public 메소드는 private 멤버와 프로그램 사이의 인터페이스(interface) 역할을 수행한다고 할 수 있다.

자바에서 public 멤버는 프로그램 어디에서 누구나 접근할 수 있다.

default

자바에서는 클래스 및 클래스 멤버의 접근 제어의 기본값으로 default 접근 제어를 별도로 명시하고 있다. 이러한 default를 위한 접근 제어자는 따로 존재하지 않으며, 접근 제어자가 지정되지 않으면 자동적으로 default 접근 제어를 가지게 된다. default 접근 제어를 가지는 멤버는 같은 클래스의 멤버와 같은 패키지에 속하는 멤버에서만 접근할 수 있다.

protected

자바 클래스는 private 멤버로 정보를 은닉하고, public 멤버로 사용자나 프로그램과의 인터페이스를 구축한다. 여기에 부모 클래스(parent class)와 관련된 접근 제어자가 하나 더 존재한다. protected 멤버는 부모 클래스에 대해서는 public 멤버처럼 취급되며, 외부에서는 private 멤버처럼 취급된다.

클래스의 protected 멤버에 접근할 수 있는 영역은 다음과 같다.

  1. 이 멤버를 선언한 클래스의 멤버
  2. 이 멤버를 선언한 클래스가 속한 패키지의 멤버
  3. 이 멤버를 선언한 클래스를 상속받은 자식 클래스의 멤버

접근제한자(접근지정자)란?

private는 클래스 자신만 접근을 허용한다. default는 다른 패키지에 소속된 클래스를 차단하고 protected는 일반적으로 자식 클래스에서만 허용하고 같은 패키지에서는 default와 같지만 다른 패키지에서는 자식 클래스에서만 허용된다. public은 모든 곳에서 접근 허용한다.


캡슐화, 은닉화

캡슐화

객체가 은닉화 된 상태에서 메소드나 생성자의 일의 내용을 알 필요 없이, 그 형태(메서드 이름/파라미터/리턴 타입)만 알면 호출해서 사용할 수 있는 특성

은닉화

외부 객체로부터 속성 값(데이터, 멤버 변수값)을 감추는 특성


extends와 implements

extends

  • 부모에서 선언/정의를 모두하며 자식은 메소드/변수를 그대로 사용할 수 있음

  • 부모의 메소드를 그대로 사용할 수 있으며 오버라이딩 할 필요 없이 부모에 구현되있는 것을 직접 사용 가능하다.

  • 자바는 다중상속을 지원하지 않는데, 대신 implements(인터페이스)가 등장했다.

implements

  • 부모 객체는 선언만 하며 정의(내용)은 자식에서 오버라이딩 (재정의) 해서 사용해야함

  • implements의 가장 큰 특징은 부모의 메소드를 반드시 오버라이딩(재정의)해야 한다.


Getter & Setter 메소드

객체지향 프로그래밍에서 객체의 데이터는 외부에서 직접적으로 접근하는 것을 막는다. 객체 데이터를 외부에서 읽고 변경시 무결성이 깨질 수 있기 때문이다. 그렇기 때문에 객체지향 프로그래밍에서는 메소드를 통해서 데이터를 변경하는 방법을 선호한다. 메소드는 매개값을 검증해서 유효한 값만 데이터로 저장할 수 있기 때문이다. 이런 역할을 하는것이 setter이다. getter은 외부에서 객체의 데이터를 읽을 때도 메소드를 사용하는 것이 좋은데 이럴 때 사용한다.

실제 프로젝트에서는 setter을 사용하지 않고 닫아두고 Builder을 사용한다. 이유는 setter을 사용하면 아무곳에서나 변경할 수 있는데 그런 상황을 제어하고자 builder을 사용하는 것입니다.


메소드란?

어떤 기능을 하는 코드들을 재사용하기 위해 한곳에 모아 처리하는 것이다. 매개변수라는 입력 값을 받아 무언가 처리하고 출력 값을 리턴한다. 장점은 불필요한 중복코드를 줄이고 코드의 가독성을 높여준다.


형변환

다른 형식으로 형태를 변환시키는 것인데 클래스에서 상속관계에 있는 클래스만 형변환이 가능하다.

  1. 업 캐스팅
    부모 타입의 객체에 자식 클래스의 필드를 담아주는 것이고 자식 객체를 넣어준다. 그리고 자식 생성자를 호출해주는 것이다. 자식 타입의 객체를 부모 타입의 객체로 변환시켜 준다. 업 캐스팅을 해주면 자식 메소드는 사용할 수 없다.

  2. 다운 캐스팅
    부모 타입의 객체를 자식 타입의 객체로 변환시키고 업 캐스팅 된 객체를 다시 자식 객체에 담는 기법이다. 업 캐스팅 시 잘려나갔던 자식 클래스의 메소드를 다시 사용할 수 있게 해준다.


instanceof란?

객체가 참조하고 있는 객체의 실제 클래스 타입을 확인하기 위한 연산자이다. 이항 연산자로 왼쪽에는 확인할 객체를 오른쪽에는 클래스를 피연산자로 이용한다. 일반적으로 런타임에 발생할 오류를 방지하고자 사용하는데 형변환이 가능한지 확인하고 true일 경우에 형변환하기 위해 사용된다. 즉, 오류를 방지하기 위한 목적이다.


💡인터페이스와 추상 클래스는 무엇이고 차이점은 무엇인가?

인터페이스는 추상화보다 더 높은 추상화 개념을 적용한 것입니다. 멤버 변수를 가지지 못하고 추상 메소드와 상수만을 선언해야 합니다. 밑 그림만 그려져 있는 기본 설계도라고 볼 수 있다. 인터페이스는 다른 클래스를 작성하는데 도움을 줄 목표로 작성이 됩니다.

추상클래스는 추상화한 개념을 자바에서 실제 클래스로 만드는 과정입니다. 다만, 추상 클래스는 객체화하여 사용할 수 없고 추상 클래스를 상속받은 자식 클래스에서 오버라이드하여 사용할 수 있습니다. 따라서 인터페이스와 추상클래스만을 가지고 새로운 객체를 생성할 수 없습니다.

두개의 차이점은 목적에 있습니다. 인터페이스와 추상클래스의 차이점은 인터페이스는 밑그림만 그려져 있는 기본 설계도라고 볼 수 있고 추상클래스는 미완성 설계도라고 볼 수 있습니다. 두개 전부 자식클래스에서 맞춰서 사용할 수 있지만 인터페이스는 다중 상속이 가능하면서 구현하는 모든 클래스에 특정한 메소드를 존재하도록 강제하고 추상클래스는 다중 상속이 불가능 하고 상속을 받아서 기능을 확장시키는 역할을 한다.


static 메소드란?

static이 붙은 변수, 메소드, 구역 등은 프로그램 실행시 가장 먼저 메모리에 올라간다. static이 붙은 메소드는 내부에서 객체의 필드에 올라오는 일반 전역변수와 일반 메소드는 아직 존재하지 않기 때문에 프로그램 실행시 해석이 불가능해서 사용할수 없습니다. 따라서 static이 붙은 전역변수, static 메소드, 자기 자신안에 선언된 지역변수만 사용할 수 있습니다. static이 붙은 것은 모든 객체가 공유해서 클래스 이름으로 직접 접근이 가능합니다.

JAVA의 non-static 멤버와 static 멤버의 차이

non-static 멤버

  1. 공간적 특징
  • 멤버는 객체마다 별도로 존재한다.
  • 인스턴스 멤버라고 부른다.
  1. 시간적 특성
  • 객체 생성 시에 멤버가 생성된다.
  • 객체 생성 후 멤버 사용이 가능하다.
  • 객체가 사라지면 멤버도 사라진다.
  1. 공유의 특성
  • 공유되지 않는다.
  • 멤버는 객체 내에 각각의 공간을 유지한다.

static 멤버

  1. 공간적 특성
  • 멤버는 클래스당 하나가 생성된다.
  • 멤버는 별도의 공간에 생성된다. (객체 내부❌)
  • 클래스 멤버 라고 부른다.
  1. 시간적 특성
  • 클래스 로딩 시에 멤버가 생성된다.
  • 객체가 생기기 전에 이미 생성된다.
  • 객체가 생기기 전에 사용이 가능하다.

    즉, 객체를 생성하지 않고도 사용가능

  • 객체가 사라져도 멤버는 사라지지 않는다.
  • 멤버는 프록램이 종료될 때 사라진다.
  • 공유의 특성 : 동일한 클래스의 모든 객체들에 의해 공유된다.

익명 클래스

익명 클래스는 일회용이다. 단 하나의 객체만을 위한 클래스이고 익명 클래스는 이름이 없는 클래스를 의미한다. 클래스 정의와 동시에 객체를 생성할 수 있습니다. 사용하는 이유는 프로그램 내에서 한번만 객체로 만드는데 사용되는 클래스를 굳이 정의할 필요가 없기 때문입니다. 객체를 하나만 만들건데 굳이 클래스를 만들어주면 낭비가 되니 익명 클래스를 통하여 사용합니다.


JAVA의 제네릭(Generic)

개념

모든 종류의 타입을 다룰 수 있도록 일반화 된 타입 매개 변수(generic type)로 클래스나 메서드를 선언하는 기법

처리 방법

  • 타입 제거(type erasure)라는 개념에 근거한다.

  • 소스 코드를 JVM이 인식하는 바이트 코드로 변환할 때 인자로 주어진 타입을 제거하는 기술이다.

  • 제네릭이 있다고 해서 크게 달라지는 것은 없다. 단지 코드를 좀 더 예쁘게 만들 뿐이다. 그래서 JAVA 의 제네릭(Generic)은 때로는 문법점 양념(Syntactic Sugar) 이라고 부른다.


💡Set과 Map의 타입이 Wrapper Class가 아닌 Object를 받을 때 중복 검사는 어떻게 할건지 설명해주세요.

hashCode() 메소드를 오버라이딩하여 리턴된 해시코드 값이 같은지를 보고 해시코드 값이 다르다면 다른 객체로 판단하고, 해시코드 값이 같으면 equals() 메소드를 오버라이딩하여 다시 비교합니다. 이 두 개가 모두 맞으면 중복 객체입니다.


Sync vs Async

두 가지의 차이점은 호출하는 함수가 호출되는 함수의 작업 완료 여부를 신경쓰는지 여부 에 차이가 있다.

Sync(동기)

동기는 함수 A가 B를 호출한 뒤, B의 결과값이 나오면 해당 결과값을 가지고 바로 처리하는 방식이다.

Async(비동기)

비동기는 함수 A가 B를 호출한 뒤, B의 결과값에 큰 비중을 두지 않고 결과가 나오면 처리를 할 수도 있고 안 할 수도 있다.


SerialVersionUID를 선언해야 하는 이유에 대해 설명해주세요.

  • JVM은 직렬화와 역직렬화를 하는 시점의 클래스에 대한 버전 번호를 부여하는데, 만약 그 시점에 클래스의 정의가 바뀌어 있다면 새로운 버전 번호를 할당하게 됩니다. 그래서 직렬화할 때의 버전 번호와 역직렬화를 할 때의 버전 번호가 다르면 역직렬화가 불가능하게 될 수 있습니다. 이런 문제를 해결하기 위해 SerialVersionUID를 사용합니다.

  • 만약 직렬화할 때 사용한 SerialVersionUID의 값과 역직렬화 하기 위해 사용했던 SVUID가 다르다면 InvalidClassException이 발생할 수 있다.


Stream

  • 자바 8에서 추가된 API

  • 컬렉션 타입의 데이터를 Stream 메서드로 내부 반복을 통해 정렬, 필터링 등이 가능

  • 데이터를 변경하지 않는다.
    원본 데이터로부터 데이터를 읽기만 할 뿐, 원본 데이터 자체를 변경하지 않는다.

  • 작업을 내부 반복으로 처리하므로 불필요한 코딩을 줄일 수 있다.

  • 최종 연산 후 stream이 닫히므로 일회용이다.

  • parellel 메서드 제공을 통해 병렬처리가 가능
    각 스레드가 개별 큐를 가지고 있으며 놀고 있는 스레드가 있으면 일하는 스레드의 작업을 가져와 수행

  • 중간 연산 작업은 바로 실행되는게 아니라 종결 처리의 실행이 필요할 때에서야 비로소 중간 처리가 실행된다.

구조

  • Stream 생성

  • 중간 연산

    • 데이터를 가공하는 과정에 해당
    • 필터링 : filter, distinct
    • 변환 : map, flatMap
    • 제한 : limit, skip
    • 정렬 : sorted
    • 연산결과확인 : peek
  • 최종 연산

    • Stream 안의 데이터를 모아 반환하는 역할을 한다.
    • 출력 : foreach
    • 소모 : reduce
    • 검색 : findFirst, findAny
    • 검사 : anyMatch, allMatch, noneMatch
    • 통계 : count, min, max
    • 연산 : sum, savage
    • 수집 : collect

ParallelStream

  • 개발자가 직접 스레드 혹은 스레드 풀을 생성하거나 관리할 필요 없이 parallStream, parallel()만 사용하면 알아서 내부적으로 common ForkJoinPool을 사용하여 작업들을 분할하고 병렬적으로 처리한다.

    ForkJoinPoolExecutorService의 구현체로 각 스레드별 개별 큐를 가지고 스레드에 아무런 task가 없으면 다른 스레드의 task를 가져와 처리하여 최적화 성능을 낼 수 있다는 특징이 있다.

  • 내부적으로 스레드 풀을 만들어서 작업을 병렬화시킨다.

  • 중요한 점은 parallelStram 각각 스레드 풀을 만드는게 아니라 별도의 설정이 없다면 하나의 스레드 풀을 모든 parallelStream이 공유한다.

  • parallelStram은 중간 연산에서 순서가 보장되지 않기 때문에 중간 연산에서 순서에 관계없는 연산의 경우에 사용한다.

  • parallelStram은 작업을 분할하기 위해 Spliterator의 trySplit()을 사용하게 되는데 이 분할하는 작업의 단위가 균등하게 나누어져야 하며, 나누어지는 작업에 대한 비용이 높지 않아야 순차적 방식보다 효율적으로 이뤄질 수 있다. array, arrayList와 같이 정확한 전체 사이즈를 알 수 있는 경우에는 분할 처리가 바르고 비용이 적게 들지만 LinkedList의 경우라면 별다른 효과를 찾기 어렵다.


람다식

  • 자바 8에서 등장
  • 메서드를 하나의 식으로 표현하는 익명 함수
  • 인터페이스 내에 한 개의 추상 메서드만 정의되어 있는 함수형(Function) 인터페이스에 사용 가능
  • 메서드를 변수처럼 다루는 것이 가능해짐

장점

  • 기존에 익명함수로 작성하던 코드를 줄일 수 있다.
  • 가독성 증가
  • 병렬 프로그래밍이 가능하다.

localDateTime

  • 자바 8에서 등장
  • LocalDateTime 클래스는 타임존 개념이 필요없는 날짜와 시간 정보 모두를 나태나기 위해서 사용됩니다. 즉, 간단하게 LocalDate와 LocalTime을 합쳐놨다고 보시면 됩니다.

default 메서드

  • 자바 8에서 등장
  • 인터페이스는 메서드 정의만 가능하고 구현은 불가능했는데 default 메서드 개념이 생기면서 인터페이스에 구현된 메서드도 추가가 가능해졌다.

기존 default 문제점

  • 불변 객체가 아님
  • 헷갈리는 월 지정(1월을 0으로 지정)
  • 일관성 없는 요일 상수(어디서는 일요일이 0, 어디서는 1)
  • Date와 Calendar 객체의 역할 분담
  • 상수 필드 남용

Optional

  • 자바 8에서 등장
  • T orElse(T other)
    • 반환할 값을 그대로 받는다.
    • 무조건 인스턴스화 된다.
  • T orElseGet(Supplier<? extends T> other)
    • Supplier로 랩핑된 값을 인자로 받는다.
    • 함수를 전달받아 바로 값으로 가져오지 않고 필요할 때 값을 가져온다.
    • Optional 안의 값이 null일 경우에만 함수가 실행되면서 인스턴스화 된다.

자바 8과 자바 11의 차이

  • default GC가 Paralle GC에서 G1GC로 변경

  • strip(), stripLeading(), stripTrailing(), isBlank(), repeat(n) 과 같은 String 클래스에 새로운 메서드 추가

  • writeString, readString, isSameFile과 같은 File 관련 새로운 메서드 추가

  • 컬렉션의 toArray() 메서드를 오버로딩하는 메서드가 추가되어 원하는 타입의 배열을 선택하여 반환할 수 있게 되었다.

  • Predicate 인터페이스에 부정을 나타내는 not() 메서드 추가

  • 람다에서 로컬 변수 var이 사용 가능

  • javac를 통해 컴파일하지 않고도 바로 java파일을 실행할 수 있게 되었다.


함수형 프로그래밍

함수형 프로그래밍은 거의 모든 것을 순수 함수로 나누어 문제를 해결하는 기법으로 작은 문제를 해결하기 위한 함수를 작성하여 가독성을 높이고 유지보수를 용이하게 해준다.

명령형 프로그래밍에서는 메소드를 호출하면 상황에 따라 내부 값이 바뀔 수 있다. 즉, 우리가 개발한 함수 내에서 선언된 변수의 메모리에 할당된 값이 바뀌는 등의 변화가 발생할 수 있다. 하지만 함수형 프로그래밍에서는 대입문이 없기 때문에 메모리에 한 번 할당된 값은 새로운 값으로 변할 수 없다.

순수 함수
같은 인자에 대해서 항상 같은 값을 반환하고 외부의 어떤 상태도 바꾸지 않는 함수

일급 객체
함수의 인자로 전달할 수 있고 함수의 반환값으로 사용할 수 있고 변수에 담을 수 있는 객체

일급 함수
함수가 일급객체면 일급 함수라고 하고 일급 함수에 이름이 없다면 람다식이라고 한다.

특징

부수 효과가 없는 순수 함수를 1급 객체로 간주하여 파라미터로 넘기거나 반환값으로 사용할 수 있으며 참조 투명성을 지킬 수 있다.

  • 사이드 이팩트가 없다.

    함수형 프로그래밍은 함수들의 조합으로 만들어지며, 각 함수들은 인자를 받고 그에 따른 결과를 내놓을 뿐 함수 내부적으로 어떠한 상태도 가지지 않는다. 따라서 함수 내부에서 벌어지는 일에 대해서는 전혀 신경쓸 필요가 없다. 단지, 함수 호출 시 입력하는 값과 그에 대한 결과 값만 중요할 뿐이다.

  • 동시성 프로그래밍

    명령형 프로그매밍에서는 교착상태가 발생하는 주된 원인은 스레드 간에 공유되는 데이터나 상태 값이 변경 가능(mutable)하기 때문이다. 하지만 함수형 프로그밍은 모든 데이터가 변경 불가능하고 함수는 부수 효과를 가지고 있지 않기 때문에 여러 스레드가 동시에 공유 데이터에 접근하더라도 해당 데이터가 변경될 수 없기 때문에 동시성 관련된 문제를 원칙적으로 봉쇄한다.

  • 함수를 값처럼 쓸 수 있기 때문에 익명 함수처럼 간결한 코드를 구성할 수 있다.

단점

  • 순수 함수를 구현하기 위해서 코드의 가독성이 좋지 않을 수 있다.
  • 수수 함수를 사용하는 것은 쉬울지라도 조합하는 것은 쉽지 않다.

블록킹 & 논 블록킹

  • 함수를 실행하고 모든 코드가 완료된 후 리턴되면 Blocking
  • 실행한 함수의 코드가 완료되지 않고 리턴되면 Non-Blocking

객체지향 프로그래밍과 절차지향 프로그래밍의 차이

절차지향 프로그래밍

  • 실행하고자 하는 절차를 정하고, 이 절차대로 프로그래밍 하는 방법이다.
  • 목적을 달성하기 위한 일의 흐름에 중점을 둔다.

객체지향 프로그래밍

  • 실세 상의 물체를 객체로 표현하고, 이들 사이의 관계, 상호 작용을 프로그램으로 나타낸다.

  • 객체를 추출하고 객체들의 관계를 결정하고 이들의 상호 작용에 필여한 함수(메서드) 와 변수(필드)를 설계 및 구현한다.

  • 사람의 사고와 가장 비슷하게 프로그래밍을 하기 위해서 생성된 기법

  • 하나의 클래스를 바탕으로 서로 다른 상태를 가진 인스턴스를 만들면 서로 다른 행동을 하게 된다. 즉, 하나의 클래스가 여러개의 인스턴스가 될 수 있다는 점이 객체 지향이 제공하는 가장 기본적인 재활용성이라고 할 수 있다.


Call by Reference와 Call by Value 의 차이

Call by Value (값에 의한 호출)

  • 함수가 호출될 때, 메모리 공간 안에서는 함수를 위한 별도의 임시 공간이 생성된다.

  • 함수 호출시 인자로 전달되는 변수의 값을 복사하여 함수의 인자로 전달한다.

  • 복사된 인자는 함수 안에서 지역적으로 사용되는 local value의 특성을 가진다.

  • 따라서 함수 안에서 인자의 값이 변경되어도, 외부의 변수의 값은 변경되지 않는다.

Call by Reference (참조에 의한 호출)

  • 함수가 호출될 때, 메모리 공간 안에서는 함수를 위한 별도의 임시 공간이 생성된다.

  • 함수 호출 시 인자로 전달되는 변수의 레퍼런스를 전달한다.

    해당 변수를 가르킨다.

  • 따라서 함수 안에서 인자의 값이 변경되면, 인자로 전달된 변수의 값도 함께 변경된다.

profile
발전하기 위한 공부

0개의 댓글