이 게시물을 읽기 전에, “Scala 기본 인터뷰 질문과 답변”에서 이전 게시물을 읽어 Scala 언어에 대한 기본 지식을 습득하십시오. 이 게시물에서는 경험있는 Scala 개발자에게 유용한 몇 가지 더 많은 Scala 인터뷰 질문에 대해 논의할 것입니다. 참고로, 이 목록은 이미 매우 크게 되었으므로, 남은 질문과 답변을 포함한 다른 게시물을 전달할 예정입니다. 해당 게시물은 다음 위치에서 참조하십시오: “Scala 중급 및 고급 인터뷰 질문과 답변”
Scala 인터뷰 질문
이 섹션에서는 모든 Scala 중급 인터뷰 질문을 나열하고 다음 섹션에서는 해당 질문에 대해 자세히 논의할 것입니다.
- 기본 생성자란 무엇인가요? Scala에서 보조 생성자 또는 보조 생성자는 무엇인가요?
- Scala에서 보조 생성자의 사용 목적은 무엇인가요? Scala에서 보조 생성자를 정의할 때 따라야 할 규칙을 설명해주세요.
- Scala에서 Array와 ArrayBuffer의 차이점은 무엇인가요?
- case class는 무엇인가요? case object는 무엇인가요? case class의 장점은 무엇인가요?
- Case Object와 Object(일반 객체)의 차이점은 무엇인가요?
- 일반 클래스와 비교했을 때 Case 클래스의 주요 장점이나 이점은 무엇입니까?
- Scala에서 isInstanceOf 및 asInstanceOf 메서드의 사용은 무엇입니까? Java에서 유사한 개념이 있습니까?
- 기본적으로 Case Object가 Serializable이고 일반 Object가 아닌 것을 어떻게 증명합니까?
- Scala의 Array와 List의 차이점은 무엇입니까?
- Scala에서 “val”과 “lazy val”의 차이는 무엇입니까? Eager Evaluation과 Lazy Evaluation은 무엇입니까?
- Scala에서 equals 메서드와 ==의 관계는 무엇입니까? Scala의 ==와 Java의 == 연산자의 차이는 무엇입니까?
- Scala의 내부 클래스와 Java의 내부 클래스의 차이점은 무엇입니까?
- 다이아몬드 문제(Diamond Problem)는 무엇입니까? Scala는 다이아몬드 문제를 어떻게 해결합니까?
- Scala에 “static” 키워드가 없는 이유는 무엇입니까? 이 결정의 주요 이유는 무엇입니까?
- Scala에서 “object” 키워드의 사용은 무엇입니까? Scala에서 싱글톤 객체를 어떻게 생성합니까?
- Scala에서 object 키워드를 사용하여 팩토리 메서드를 어떻게 정의합니까? object에서 팩토리 메서드를 정의하는 데 사용하는 것은 무엇입니까?
- Scala에서 apply 메서드는 무엇입니까? Scala에서 unapply 메서드는 무엇입니까? Scala에서 apply와 unapply 메서드의 차이점은 무엇입니까?
- Scala에서 ‘new’ 키워드를 사용하지 않고 클래스의 인스턴스를 생성할 때 어떻게 작동합니까? 이 접근 방식은 언제 사용합니까?
- Scala에서 비공개 주요 생성자를 어떻게 선언합니까? Scala에서 비공개 주요 생성자를 호출하는 방법은 무엇입니까?
- 동반 객체는 Scala의 동반 클래스의 비공개 멤버에 접근할 수 있습니까?
- Scala에서 class 및 object라는 두 개의 별도 키워드에 대한 주요 설계 결정은 무엇입니까? Scala에서 인스턴스 멤버와 정적 멤버를 어떻게 정의합니까?
- Scala에서 object는 무엇입니까? 클래스의 싱글톤 객체이거나 클래스의 인스턴스입니까?
- Scala에서 동반 객체(Companion Object)란 무엇입니까? Scala에서 동반 클래스(Companion Class)란 무엇입니까? Scala에서 동반 객체의 사용은 무엇입니까?
- Scala에서 인터페이스를 구현하는 방법은 무엇입니까?
- Scala에서 Range는 무엇입니까? Scala에서 Range를 어떻게 생성합니까?
- Scala에서 Nothing 유형의 값은 몇 개입니까?
- Scala에서 Unit 유형의 값은 몇 개입니까?
- Scala에서 Range는 무엇입니까? Scala에서 Range를 어떻게 생성합니까?
- FP에서 함수와 프로시저 사이의 차이점은 무엇입니까?
- Scala의 보조 생성자와 Java의 생성자의 주요 차이점은 무엇입니까?
- Scala의 for-comprehension 구조에서 ‘yield’ 키워드의 사용은 무엇입니까?
- Scala의 for-comprehension 구조에서 guard는 무엇입니까?
- Scala는 Java 8보다 상속 다이아몬드 문제를 어떻게 자동 및 쉽게 해결합니까?
- Scala에서 패턴 매칭은 어떤 디자인 패턴을 따릅니까? Java에서 ‘isinstanceof’ 연산자는 어떤 디자인 패턴을 따릅니까?
스칼라 인터뷰 질문과 답변
이 섹션에서는 위 목록에서 각 질문을 가져와 필요한 경우 적절한 예제와 함께 상세히 논의할 것입니다. 이러한 개념을 예제와 함께 심층적으로 이해하려면 스칼라 자습서 섹션의 이전 게시물을 참조하십시오.
주 생성자란 무엇인가요? 스칼라에서 보조 생성자 또는 보조 생성자란 무엇인가요? 스칼라에서 보조 생성자의 목적은 무엇인가요? 스칼라에서 생성자를 오버로드하는 것이 가능한가요?
스칼라에는 두 종류의 생성자가 있습니다:
- 주 생성자
- 보조 생성자
주 생성자 스칼라에서 주 생성자는 클래스 정의 자체와 함께 정의된 생성자입니다. 각 클래스는 하나의 주 생성자를 가져야 합니다: 매개변수 생성자 또는 매개변수 없는 생성자. 예시:-
class Person
위의 Person 클래스에는 이 클래스의 인스턴스를 생성하는 데 사용되는 제로 매개변수 또는 매개변수 없는 주 생성자가 있습니다.
class Person (firstName: String, lastName: String)
위의 Person 클래스에는 이 클래스의 인스턴스를 생성하는 데 사용되는 두 개의 매개변수가 있는 주 생성자가 있습니다. 보조 생성자 보조 생성자는 보조 생성자로도 알려져 있습니다. 아래와 같이 ‘def’ 및 ‘this’ 키워드를 사용하여 보조 생성자를 선언할 수 있습니다:
class Person (firstName: String, middleName:String, lastName: String){
def this(firstName: String, lastName: String){
this(firstName, "", lastName)
}
}
스칼라에서 보조 생성자의 사용 목적은 무엇입니까? 스칼라에서 보조 생성자를 정의하는 데 따르는 규칙을 설명해주세요.
스칼라에서 보조 생성자의 주된 목적은 생성자를 오버로드하는 것입니다. 자바와 마찬가지로 여러 종류의 생성자를 제공하여 사용자가 요구에 따라 적절한 것을 선택할 수 있습니다. 보조 생성자 규칙:
- 이들은 메서드와 마찬가지로입니다. 메서드처럼 ‘def’ 키워드를 사용하여 정의해야 합니다.
- 모든 보조 생성자에 대해 동일한 이름 ‘this’를 사용해야 합니다.
- 각 보조 생성자는 이전에 정의된 다른 보조 생성자나 주 생성자에 대한 호출로 시작해야 합니다. 그렇지 않으면 컴파일 시간 오류가 발생합니다.
- 각 보조 생성자는 매개변수 목록이 다르게 설정되어야 합니다: 숫자나 유형에 따라 달라질 수 있습니다.
- 보조 생성자는 슈퍼 클래스 생성자를 호출할 수 없습니다. 그들은 주 생성자를 통해서만 호출해야 합니다.
- 모든 보조 생성자는 주 생성자를 직접 또는 다른 보조 생성자를 통해 간접적으로 호출해야 합니다.
참고:- Scala의 생성자에 대해 자세히 알고 싶다면 제 Scala 게시물을 참조하세요: Primary Constructor 및 Auxiliary Constructor.
Scala에서 Array와 ArrayBuffer의 차이점은 무엇인가요?
Scala에서 Array와 ArrayBuffer의 차이점:
- Array는 크기가 고정된 배열입니다. 한 번 생성되면 크기를 변경할 수 없습니다.
- ArrayBuffer는 크기가 가변적인 배열입니다. 크기를 동적으로 늘리거나 줄일 수 있습니다.
- Array는 Java의 기본 배열과 유사합니다.
- ArrayBuffer는 Java의 ArrayList와 유사합니다.
케이스 클래스란 무엇인가요? 케이스 오브젝트란 무엇인가요? 케이스 클래스의 장점은 무엇인가요?
케이스 클래스는 “case class” 키워드로 정의된 클래스입니다. 케이스 오브젝트는 “case object” 키워드로 정의된 객체입니다. 이 “case” 키워드 때문에 우리는 보일러플레이트 코드를 피하기 위한 몇 가지 이점을 얻을 수 있습니다. 우리는 “new” 키워드를 사용하지 않고도 케이스 클래스 객체를 생성할 수 있습니다. 기본적으로 스칼라 컴파일러는 모든 생성자 매개변수에 대해 “val”을 접두사로 붙입니다. 이것은 일반 클래스에는 불가능한 것이기 때문에 val 또는 var를 사용하지 않고도 케이스 클래스의 생성자 매개변수가 클래스 멤버가 됩니다. 케이스 클래스의 장점:
- 기본적으로 스칼라 컴파일러는 toString, hashCode 및 equals 메서드를 추가합니다. 이러한 보일러플레이트 코드 작성을 피할 수 있습니다.
- 기본적으로 스칼라 컴파일러는 apply 및 unapply 메서드가 있는 동반 객체를 추가합니다. 따라서 케이스 클래스의 인스턴스를 생성하는 데 new 키워드가 필요하지 않습니다.
- 기본적으로 스칼라 컴파일러는 copy 메서드도 추가합니다.
- 패턴 매칭에서 케이스 클래스를 사용할 수 있습니다.
- 기본적으로 케이스 클래스 및 케이스 오브젝트는 직렬화됩니다.
Case Object와 Object(일반 객체)의 차이점은 무엇인가요?
- 일반 객체는 “object” 키워드를 사용하여 생성됩니다. 기본적으로 싱글톤 객체입니다.
object MyNormalObject
- Case Object는 “case object” 키워드를 사용하여 생성됩니다. 기본적으로 싱글톤 객체입니다.
case object MyCaseObject
- 기본적으로 Case Object는 toString 및 hashCode 메서드를 가져옵니다. 그러나 일반 객체는 그렇지 않습니다.
- 기본적으로 Case Object는 Serializable입니다. 그러나 일반 객체는 그렇지 않습니다.
일반 클래스와 비교했을 때 Case 클래스의 주요 장점이나 이점은 무엇인가요?
다음은 Case 클래스가 일반 클래스보다 가지는 주요 장점이나 이점입니다:
- 유용한 메서드를 자동으로 추가하여 보일러플레이트 코드를 피합니다.
- 기본적으로 ‘val’인 파라미터를 사용하여 불변성을 지원합니다.
- 패턴 매칭에서 쉽게 사용할 수 있습니다.
- Case 클래스의 인스턴스를 생성할 때 ‘new’ 키워드를 사용할 필요가 없습니다.
- 기본적으로 직렬화 및 역직렬화를 지원합니다.
Scala에서 isInstanceOf 및 asInstanceOf 메서드의 사용법은 무엇입니까? Java에 비슷한 개념이 있습니까?
isInstanceOf 및 asInstanceOf 메서드는 Any 클래스에 정의되어 있으므로 이러한 메서드를 어떤 클래스나 객체로 가져오려면 가져올 필요가 없습니다. “isInstanceOf” 메서드는 객체가 주어진 유형인지 여부를 테스트하는 데 사용됩니다. 그렇다면 true를 반환합니다. 그렇지 않으면 false를 반환합니다.
scala> val str = "Hello"
scala>str.isInstanceOf[String]
res0: Boolean = false
“asInstanceOf” 메서드는 객체를 지정된 유형으로 캐스트하는 데 사용됩니다. 주어진 객체와 유형이 동일한 유형이라면 주어진 유형으로 캐스트됩니다. 그렇지 않으면 java.lang.ClassCastException을 throw합니다.
scala> val str = "Hello".asInstanceOf[String]
str: String = Hello
Java에서 ‘instanceof’ 키워드는 Scala의 ‘isInstanceOf’ 메서드와 유사합니다. Java에서는 다음과 같은 수동 형 변환은 Scala의 ‘asInstanceOf’ 메서드와 유사합니다.
AccountService service = (AccountService)
context.getBean("accountService");
기본적으로 Case Object가 Serializable이고 Normal Object가 그렇지 않음을 어떻게 증명합니까?
기본적으로 Case Object는 Serializable입니다. 그러나 일반 객체는 그렇지 않습니다. 다음과 같이 isInstanceOf 메서드를 사용하여이를 증명 할 수 있습니다:
scala> object MyNormalObject
defined object MyNormalObject
scala> MyNormalObject.isInstanceOf[Serializable]
res0: Boolean = false
scala> case object MyCaseObject
defined object MyCaseObject
scala> MyCaseObject.isInstanceOf[Serializable]
res1: Boolean = true
Scala에서 Array와 List의 차이점은 무엇입니까?
- 배열은 항상 변경 가능하지만 목록은 항상 변경 불가능합니다.
- 일단 생성되면 배열 값을 변경할 수 있지만 목록 개체를 변경할 수는 없습니다.
- 배열은 고정 크기 데이터 구조이고 목록은 가변 크기 데이터 구조입니다. 목록의 크기는 수행 한 작업에 따라 자동으로 증가 또는 감소합니다.
- 배열은 불변 인 반면 목록은 공변입니다.
참고 : – 불변 및 공변에 대해 확신이 없으면 Scala 인터뷰 질문에 대한 다음 게시물을 읽어보세요.
Scala에서 “val”과 “lazy val”의 차이는 무엇입니까? Eager Evaluation과 Lazy Evaluation은 무엇입니까?
기본적으로 “val”은 변경할 수 없는 변수를 정의하는 데 사용되는 값 또는 상수를 의미합니다. 프로그램 평가에는 두 가지 종류가 있습니다:
- Eager Evaluation
- Lazy Evaluation
Eager Evaluation은 프로그램을 컴파일 시간이나 프로그램 배포 시간에 평가하는 것을 의미하며 클라이언트가 해당 프로그램을 사용하든 사용하지 않든 관계없이입니다. Lazy Evaluation은 프로그램을 실행 시간에 필요할 때에만 평가하는 것을 의미하며 즉, 클라이언트가 프로그램에 액세스할 때에만 평가됩니다. “val”과 “lazy val”의 차이점은 “val”이 즉시 평가되는 변수를 정의하는 데 사용되고 “lazy val”도 변수를 정의하지만 게으르게 평가됩니다.
Scala에서 equals 메서드와 ==의 관계는 무엇인가요? Scala의 ==와 Java의 == 연산자를 어떻게 구별하나요?
Scala에서는 두 인스턴스 또는 객체를 비교할 때 equals() 메서드를 호출할 필요가 없습니다. ==로 두 인스턴스를 비교할 때 Scala는 해당 객체의 equals() 메서드를 자동으로 호출합니다. Java의 == 연산자는 참조 동등성을 확인하는 데 사용됩니다. 즉, 두 참조가 동일한 객체를 가리키는지 여부를 확인합니다. Scala의 ==는 인스턴스 동등성을 확인하는 데 사용됩니다. 즉, 두 인스턴스가 동일한지 여부를 확인합니다.
Scala의 내부 클래스와 Java의 내부 클래스의 차이점은 무엇인가요?
Java에서 내부 클래스는 외부 클래스와 관련이 있으며 내부 클래스는 외부 클래스의 멤버입니다. 그러나 Scala는 외부 클래스와 내부 클래스 간의 관계를 다르게 처리합니다. Scala의 내부 클래스는 외부 클래스 객체와 관련이 있습니다.
Diamond Problem이란 무엇인가요? Scala가 Diamond Problem을 어떻게 해결하는지요?
A Diamond Problem is a Multiple Inheritance problem. Some people calls this problem as Deadly Diamond Problem. In Scala, it occurs when a Class extends more than one Traits which have same method definition as shown below. Unlike Java 8, Scala solves this diamond problem automatically by following some rules defined in Language. Those rules are called “Class Linearization”. Example:-
trait A{
def display(){ println("From A.display") }
}
trait B extends A{
override def display() { println("From B.display") }
}
trait C extends A{
override def display() { println("From C.display") }
}
class D extends B with C{ }
object ScalaDiamonProblemTest extends App {
val d = new D
d display
}
여기서의 출력은 “trait C에서의 C.display”입니다. Scala 컴파일러는 오른쪽에서 왼쪽으로 “B와 C로 확장”을 읽고, 가장 왼쪽의 trait인 C에서 “display” 메서드 정의를 가져옵니다. 참고: 명확한 설명과 함께 이를 이해하려면 “Scala Traits in Depth”에서 제 포스트를 확인하세요.
왜 Scala에는 “static” 키워드가 없을까요? 이 결정의 주된 이유는 무엇인가요?
우리가 아는 대로, 스칼라에는 “static” 키워드가 전혀 없습니다. 이것은 스칼라 팀에 의한 설계 결정입니다. 이 결정을 내린 주된 이유는 스칼라를 순수 객체 지향 언어로 만들기 위함입니다. “static” 키워드는 해당 클래스 멤버를 객체를 생성하거나 객체를 사용하지 않고도 접근할 수 있다는 것을 의미합니다. 이는 완전히 객체 지향 원칙에 반하는 것입니다. 언어가 “static” 키워드를 지원한다면, 해당 언어는 순수 객체 지향 언어가 아닙니다. 예를 들어, 자바는 “static” 키워드를 지원하기 때문에 순수 객체 지향 언어가 아닙니다. 하지만 스칼라는 순수 객체 지향 언어입니다.
스칼라에서 “object” 키워드의 용도는 무엇인가요? 스칼라에서 싱글톤 객체를 어떻게 생성하나요?
스칼라에서 “object” 키워드는 다음과 같은 목적으로 사용됩니다:
- 스칼라에서 싱글톤 객체를 생성하는 데 사용됩니다.
object MySingletonObject
여기서 MySingletonObject는 자동으로 싱글톤 객체가 됩니다.- “object” 키워드는 실행 가능한 스칼라 프로그램인 스칼라 애플리케이션을 정의하는 데 사용됩니다.
object MyScalaExecutableProgram{
def main(args: Array[String]){
println("Hello World")
}
}
위에서 보여진 것처럼 object에 main 메소드를 정의하면 (이는 Java의 main() 메소드와 동일합니다), 자동으로 실행 가능한 스칼라 프로그램이 됩니다.- ‘static’ 키워드를 사용하지 않고도 정적 멤버인 정적 변수와 정적 메소드를 정의하는 데 사용됩니다.
object MyScalaStaticMembers{
val PI: Double = 3.1414
def add(a: Int, b: Int) = a + b
}
변수 PI를 정의하고 add 메소드를 정적 멤버로 만들면 MyScalaStaticMembers.add(10, 20)과 같이 별도의 객체를 생성하지 않고 호출할 수 있게 됩니다. 이는 팩토리 메소드를 정의하는 데 사용되며 다음 질문을 확인하세요.
Scala에서 object 키워드를 사용하여 팩토리 메소드를 어떻게 정의하며, 팩토리 메소드를 정의하는 데 어떤 용도가 있나요?
Scala에서는 ‘object’ 키워드를 사용하여 팩토리 메소드를 정의합니다. Scala에서 이러한 팩토리 메소드의 주요 목적은 ‘new’ 키워드를 사용하지 않고 객체를 생성하는 데 있습니다. 팩토리 메소드를 정의하려면: Scala에서는 팩토리 메소드를 정의하기 위해 apply 메소드를 사용할 수 있습니다. 주요 생성자와 여러 보조 생성자가 있는 경우 아래와 같이 여러 apply 메소드를 정의해야 합니다.
class Person(val firstName: String, val middleName: String, val lastName: String){
def this(firstName: String, lastName: String){
this(firstName,"",lastName)
}
}
object Person{
def apply(val firstName: String, val middleName: String, val lastName: String)
= new Person(firstName,middleName,lastName)
def apply(val firstName: String, val lastName: String)
= new Person(firstName, lastName)
}
이제 ‘new’ 키워드를 사용하지 않고 또는 원하는대로 ‘new’ 키워드를 사용하여 Person 객체를 생성할 수 있습니다.
val p1 = new Person("Scala","Java")
or
val p1 = Person("Scala","Java")
Scala에서 apply 메서드는 무엇인가요? Scala에서 unapply 메서드는 무엇인가요? Scala에서 apply 및 unapply 메서드의 차이점은 무엇인가요?
Scala에서 apply 및 unapply 메서드는 매우 중요한 역할을 합니다. 또한 Play Framework에서 Form 데이터와 모델 데이터 간의 데이터 매핑 및 언매핑에 매우 유용합니다. 간단히 말해서,
- apply 메서드: 객체를 해당 구성 요소에서 구성하거나 조립하는 데 사용됩니다.
- unapply 메서드: 객체를 해당 구성 요소로 분해하거나 해체하는 데 사용됩니다.
Scala의 apply 메서드: 이 메서드는 해당 구성 요소를 사용하여 객체를 구성하는 데 사용됩니다. 예를 들어 Person 객체를 생성하려면 firstName 및 lastName 두 구성 요소를 사용하여 Person 객체를 다음과 같이 구성할 수 있습니다.
class Person(val firstName: String, val lastName: String)
object Person{
def apply(firstName: String, lastName: String)
= new Person(firstName, lastName)
}
Scala의 unapply 메서드: 이 메서드는 객체를 해당 구성 요소로 분해하는 데 사용됩니다. apply 메서드의 역과정을 따릅니다. 예를 들어 Person 객체가 있다면 해당 객체를 firstName 및 lastName 두 구성 요소로 분해할 수 있습니다. 아래에 표시된 것처럼요.
class Person(val firstName: String, val lastName: String)
object Person{
def apply(firstName: String, lastName: String)
= new Person(firstName, lastName)
def unapply(p: Person): (String,String)
= (p.firstName, p.lastName)
}
‘new’ 키워드를 사용하지 않고 Scala에서 Class의 인스턴스를 생성할 때 내부 작동 방식은 어떻게 되나요? 이 접근 방식을 언제 사용하나요? Scala에서 private 생성자를 선언하는 방법은 무엇인가요?
Scala에서 ‘new’ 키워드를 사용하지 않고 Class의 인스턴스를 생성할 때, 내부적으로 Companion 객체에서 해당 apply 메서드를 호출합니다. 여기서 적절한 apply 메서드란 매개변수와 일치하는 것입니다. 이 옵션을 선택하는 경우: private 생성자를 제공하고 ‘new’ 키워드를 사용하지 않아야 할 때, 동일한 매개변수 세트를 사용하여 apply 메서드만 구현하고 클래스 사용자가 new 키워드 없이 인스턴스를 생성할 수 있도록 할 수 있습니다.
스칼라에서 개인 주 생성자를 선언하는 방법은 무엇입니까? 스칼라에서 개인 주 생성자를 호출하는 방법은 무엇입니까?
스칼라에서는 개인 주 생성자를 매우 쉽게 선언할 수 있습니다. 클래스 이름 바로 뒤에 ‘private’를 추가하고 매개변수 목록 앞에 클래스와 동일하게 주 생성자를 정의하면 됩니다. 아래에 표시된 것처럼:
class Person private (name: String)
object Person{
def apply(name: String) = new Person(name)
}
개인 생성자이기 때문에 외부에서 호출할 수 없습니다. 위와 같이 팩토리 메서드(즉, apply 메서드)를 제공하고 그 생성자를 간접적으로 사용해야 합니다.
스칼라에서 동반 객체는 동반 클래스의 개인 멤버에 액세스합니까?
일반적으로 개인 멤버는 해당 클래스 내에서만 액세스할 수 있습니다. 그러나 스칼라의 동반 클래스와 동반 객체는 다른 기능을 제공합니다. 스칼라에서 동반 객체는 동반 클래스의 개인 멤버에 액세스할 수 있으며, 동반 클래스는 동반 객체의 개인 멤버에 액세스할 수 있습니다.
스칼라에서 두 개의 별도 키워드에 대한 주요 디자인 결정은 무엇인가요: 클래스와 객체? 스칼라에서 인스턴스 멤버와 정적 멤버를 어떻게 정의하나요?
스칼라에서는 인스턴스 멤버를 정의하기 위해 class 키워드를 사용하고 정적 멤버를 정의하기 위해 object 키워드를 사용합니다. 스칼라에는 static 키워드가 없지만 여전히 object 키워드를 사용하여 정의할 수 있습니다. 이에 대한 주요 디자인 결정은 인스턴스 및 정적 멤버 간의 명확한 분리입니다. 그리고 느슨한 결합을 유지하는 것입니다. 그리고 다른 주요 이유는 static 키워드를 피함으로써 스칼라가 순수한 객체 지향 언어가 되도록하는 것입니다.
스칼라에서 object란 무엇인가요? 싱글톤 객체인가요, 아니면 클래스의 인스턴스인가요?
자바와는 달리 스칼라에는 ‘object’에 대해 두 가지 의미가 있습니다. 이에 대해 혼란스러워하지 마세요. 명확하게 설명해 드리겠습니다. 자바에서는 ‘object’에 대해 “클래스의 인스턴스”라는 하나의 의미만 있습니다.
- 자바와 마찬가지로 object의 첫 번째 의미는 “클래스의 인스턴스”입니다.
val p1 = new Person("Scala","Java")
or
val p1 = Person("Scala","Java")
- 두 번째 의미는 객체가 스칼라에서의 키워드임을 뜻합니다. 이는 스칼라 실행 가능한 프로그램, 동반 객체(Companion Objects), 싱글톤 객체 등을 정의하는 데 사용됩니다.
스칼라에서 동반 객체(Companion Object)란 무엇인가요? 스칼라에서 동반 클래스(Companion Class)란 무엇인가요? 동반 객체의 사용 목적은 무엇인가요?
간단히 말하면, 스칼라 클래스와 객체가 동일한 이름을 가지고 동일한 소스 파일에 정의되어 있다면, 해당 클래스는 “동반 클래스”이고 해당 객체는 “동반 객체”로 알려져 있습니다. Scala “class” 키워드를 사용하여 클래스를 생성하고 Scala “object” 키워드를 사용하여 동일한 이름으로 동일한 소스 파일 내에 객체를 생성하는 경우, 해당 클래스는 “동반 클래스”이고 해당 객체는 “동반 객체”로 알려져 있습니다. 예시: – Employee.scala
class Employee{ }
object Employee{ }
스칼라에서 동반 객체의 주요 목적은 apply 메서드를 정의하고 해당 동반 클래스 객체의 인스턴스 생성 시 new 키워드를 사용하지 않도록하는 것입니다.
스칼라에서 인터페이스를 구현하는 방법은 무엇인가요?
Java 배경을 통해 알고 있는 대로, 우리는 인터페이스를 사용하여 연락처를 정의합니다. 그러나 스칼라에는 인터페이스 개념이 없습니다. 심지어 스칼라에는 인터페이스 키워드도 없습니다. 스칼라에는 이를 위한 더 강력하고 유연한 개념인 트레이트가 있습니다.
스칼라에서의 Range란 무엇인가요? 스칼라에서 Range를 어떻게 생성하나요?
Range는 스칼라에서의 게으른 컬렉션입니다. Range는 ‘scala.Range’과 같이 ‘scala’ 패키지에 있는 클래스입니다. 정수 값의 시퀀스를 나타내는 데 사용됩니다. 정수의 정렬된 시퀀스입니다. 예시:-
scala> 1 to 10
res0: scala.collection.immutable.Range.Inclusive = Range(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
scala> 1 until 10
res1: scala.collection.immutable.Range = Range(1, 2, 3, 4, 5, 6, 7, 8, 9)
스칼라에서 Nothing 타입의 값은 몇 개 있나요?
스칼라에서, Nothing 타입은 값이 없으므로 0개입니다. 어떠한 값도 가지고 있지 않습니다. 모든 값 클래스와 참조 클래스의 서브타입입니다.
스칼라에서 Unit 타입의 값은 몇 개 있나요?
Scala에서 Unit은 Java의 void 키워드와 유사합니다. “값이 없음”을 나타내는 데 사용됩니다. 유일한 값은 ()입니다.
순수 함수(pure function)란 무엇인가요?
A pure function is a function without any observable side-effects. That means it returns always same results irrespective how many times we call it with same inputs. A pure function always gives same output for the same inputs. For Example:-
scala> 10 + 20
res0: Int = 30
scala>
scala> 10 + 20
res0: Int = 30
여기에는 Int 클래스에 있는 ” + “라는 순수 함수가 있습니다. 이 함수는 같은 입력 10과 30에 대해 몇 번을 호출하더라도 항상 같은 결과 30을 반환합니다.
FP에서 함수와 프로시저의 차이점은 무엇인가요?
둘 다 계산을 수행하는 데 사용되지만, 함수는 부작용이 없는 계산 단위이고, 프로시저는 부작용이 있는 계산 단위입니다.
Scala의 보조 생성자와 Java의 생성자의 주요 차이점은 무엇인가요?
스칼라의 보조 생성자는 거의 Java의 생성자와 유사하지만 몇 가지 차이점이 있습니다. Java의 생성자와 비교하여 보조 생성자에는 다음과 같은 몇 가지 차이가 있습니다:
- 보조 생성자는 “this” 키워드를 사용하여 호출됩니다.
- 모든 보조 생성자는 “this”라는 동일한 이름으로 정의됩니다. Java에서는 생성자를 정의할 때 클래스 이름을 사용합니다.
- 각 보조 생성자는 이전에 정의된 보조 생성자 또는 기본 생성자를 호출해야 합니다.
- ‘def’ 키워드를 사용하여 메서드/함수 정의처럼 보조 생성자를 정의합니다. Java에서는 생성자 정의와 메서드 정의가 다릅니다.
스칼라의 for-컴프리헨션 구조에서 ‘yield’ 키워드의 사용은 무엇인가요?
스칼라의 for-컴프리헨션 구조에서 ‘yield’ 키워드를 사용할 수 있습니다. ‘for/yield’는 요소 컬렉션을 반복하고 동일한 유형의 새 컬렉션을 생성하는 데 사용됩니다. 원본 컬렉션을 변경하지 않습니다. 이는 원본 컬렉션 유형과 동일한 새 컬렉션을 생성합니다. 예를 들어 List를 반복하려면 ‘for/yield’ 구조를 사용하면 새 List만 생성됩니다.
scala> val list = List(1,2,3,4,5)
list: List[Int] = List(1, 2, 3, 4, 5)
scala> for(l <- list) yield l*2
res0: List[Int] = List(2, 4, 6, 8, 10)
Scala의 for-comprehension 구조에서 가드란 무엇인가요?
Scala에서 for-comprehension 구조에는 조건을 작성하여 일부 요소를 필터링하고 새 컬렉션을 생성하는 if 절이 있습니다. 이 if 절은 “가드”로도 알려져 있습니다. 그 가드가 true이면 해당 요소를 새 컬렉션에 추가합니다. 그렇지 않으면 해당 요소를 원래 컬렉션에 추가하지 않습니다. 예시:- 새 컬렉션에 짝수만 생성하기 위한 for-comprehension 가드.
scala> val list = List(1,2,3,4,5,6,7,8,9,10)
list: List[Int] = List(1, 2, 3, 4, 5 , 6 , 7 , 8 , 9 , 10)
scala> for(l <- list if l % 2 =0 ) yield l
res0: List[Int] = List(2, 4, 6, 8, 10)
Scala가 자바 8보다 상속 다이아몬드 문제를 자동으로 쉽게 해결하는 방법은 무엇인가요?
Java 8의 인터페이스와 기본 메서드를 사용하면 상속 다이아몬드 문제가 발생합니다. 개발자는 Java 8에서 이를 수동으로 해결해야 합니다. 이 문제에 대한 기본 또는 자동 해결 방법을 제공하지 않습니다. Scala에서는 특징을 사용하여 동일한 문제가 발생하지만 Scala는 매우 똑똑하여 클래스 선형화 개념을 사용하여 상속 다이아몬드 문제를 자동으로 해결합니다.
Scala에서 패턴 매칭은 어떤 디자인 패턴을 따릅니까? Java에서 ‘isinstanceof’ 연산자는 어떤 디자인 패턴을 따릅니까?
Scala에서 패턴 매칭은 Visitor 디자인 패턴을 따릅니다. 마찬가지로, Java의 ‘isinstanceof’ 연산자도 Visitor 디자인 패턴을 따릅니다. 이것이 “Scala 중급 인터뷰 질문과 답변”에 관한 전부입니다. 저는 앞으로 오는 포스트에서 일부 고급 Scala 인터뷰 질문과 답변을 논의할 것입니다. 제 포스트를 좋아하시거나 문제/제안이 있으시면 댓글을 남겨주세요.
Source:
https://www.digitalocean.com/community/tutorials/scala-interview-questions