CyStack logo
  • Sản phẩm & Dịch vụ
  • Giải pháp
  • Bảng giá
  • Công ty
  • Tài liệu
Vi

vi

Trang chủHướng dẫnTop các câu hỏi phỏng vấn Scala phổ biến

Top các câu hỏi phỏng vấn Scala phổ biến

CyStack blog 17 phút để đọc
CyStack blog20/09/2025
Locker Avatar

Chris Pham

Technical Writer

Locker logo social
Reading Time: 17 minutes

câu hỏi phỏng vấn Scala

Trong bài viết này, chúng ta sẽ cùng thảo luận thêm về một số câu hỏi phỏng vấn Scala hữu ích dành cho những Scala Developers đã có kinh nghiệm.

Lưu ý: Vì danh sách câu hỏi đã khá dài, tôi sẽ viết thêm một bài khác để trình bày những câu hỏi và câu trả lời còn lại.

Scala Interview Questions

Trong phần này, chúng ta sẽ liệt kê tất cả các Scala Intermediate Interview Questions, và ở phần tiếp theo sẽ thảo luận chi tiết từng câu.

  1. Primary Constructor là gì? Secondary hay Auxiliary Constructor trong Scala là gì?
  2. Mục đích của Auxiliary Constructors trong Scala là gì? Hãy giải thích các quy tắc cần tuân theo khi định nghĩa Auxiliary Constructors trong Scala?
  3. Sự khác nhau giữa Array và ArrayBuffer trong Scala là gì?
  4. Case class là gì? case object là gì? Ưu điểm của case class là gì?
  5. Sự khác biệt giữa Case Object và Object (Normal Object) là gì?
  6. So với Normal Class, Case-class có những lợi ích hoặc ưu điểm chính nào?
  7. Cách sử dụng các method isInstanceOf và asInstanceOf trong Scala? Trong Java có khái niệm tương tự không?
  8. Làm thế nào để chứng minh rằng mặc định Case Object là Serializable, còn Normal Object thì không?
  9. Sự khác biệt giữa Array và List trong Scala là gì?
  10. Sự khác biệt giữa “val” và “lazy” val trong Scala là gì? Eager Evaluation là gì? Lazy Evaluation là gì?
  11. Mối quan hệ giữa method equals và toán tử == trong Scala là gì? Phân biệt == trong Scala và toán tử == trong Java?
  12. Sự khác biệt giữa Inner class trong Scala và Inner class trong Java là gì?
  13. Diamond Problem là gì? Scala giải quyết Diamond Problem như thế nào?
  14. Vì sao Scala KHÔNG có từ khóa “static”? Lý do chính cho quyết định này là gì?
  15. Từ khóa “object” trong Scala được dùng để làm gì? Làm thế nào để tạo Singleton objects trong Scala?
  16. Làm sao định nghĩa Factory methods bằng từ khóa object trong Scala? Việc định nghĩa Factory methods trong object có tác dụng gì?
  17. Apply method trong Scala là gì? Unapply method trong Scala là gì? Sự khác nhau giữa apply và unapply methods là gì?
  18. Bên trong hoạt động thế nào khi chúng ta tạo một instance của Class mà không dùng từ khóa “new” trong Scala? Khi nào nên dùng cách tiếp cận này?
  19. Làm thế nào để khai báo một private Primary Constructor trong Scala? Làm sao gọi đến private Primary Constructor đó?
  20. Companion object có truy cập được các private members của Companion class trong Scala không?
  21. Quyết định thiết kế chính về việc tách riêng hai từ khóa: class và object trong Scala là gì? Làm thế nào để định nghĩa Instance members và Static members trong Scala?
  22. Object trong Scala là gì? Nó là singleton object hay là một instance của class?
  23. Companion Object trong Scala là gì? Companion Class là gì? Companion Object được dùng để làm gì?
  24. Làm thế nào để implement interfaces trong Scala?
  25. Range trong Scala là gì? Làm thế nào để tạo một Range trong Scala?
  26. Scala có bao nhiêu giá trị thuộc kiểu Nothing?
  27. Scala có bao nhiêu giá trị thuộc kiểu Unit?
  28. Range trong Scala là gì? Làm thế nào để tạo một Range trong Scala?
  29. Trong Functional Programming (FP), sự khác nhau giữa function và procedure là gì?
  30. Những khác biệt chính giữa Auxiliary constructors của Scala và constructors trong Java là gì?
  31. Tác dụng của từ khóa “yield” trong for-comprehension construct của Scala là gì?
  32. Guard trong for-comprehension construct của Scala là gì?
  33. Scala tự động và dễ dàng giải quyết vấn đề Inheritance Diamond Problem hơn Java 8 như thế nào?
  34. Trong Scala, Pattern Matching tuân theo Design Pattern nào? Trong Java, toán tử “instanceof” tuân theo Design Pattern nào?

Câu hỏi và trả lời phỏng vấn Scala

Trong phần này, chúng ta sẽ lần lượt lấy từng câu hỏi trong danh sách trên để thảo luận chi tiết, kèm theo ví dụ (nếu cần). Nếu bạn muốn hiểu rõ hơn với ví dụ cụ thể, hãy tham khảo các bài viết trước trong mục Scala Tutorials.

What is Primary Constructor? What is Secondary or Auxiliary Constructor in Scala? What is the purpose of Auxiliary Constructor in Scala? Is it possible to overload constructors in Scala?

Trong Scala có hai loại constructor:

  1. Primary Constructor
  2. Auxiliary Constructor

Primary Constructor

Trong Scala, Primary Constructor được định nghĩa ngay trong phần khai báo class. Mỗi class bắt buộc phải có một Primary Constructor: có thể là constructor có tham số hoặc không có tham số. Ví dụ:

class Person

Class Person ở trên có một Primary Constructor không tham số (Zero-parameter / No-Parameter / Parameterless) để tạo ra các instance của class này.

class Person (firstName: String, lastName: String)

Class Person ở trên có một Primary Constructor với hai tham số để tạo ra các instance của class này. Auxiliary Constructor Auxiliary Constructor còn được gọi là Secondary Constructor. Chúng ta có thể khai báo một Secondary Constructor bằng cách sử dụng các từ khóa “def” và “this” như trong ví dụ dưới đây:

class Person (firstName: String, middleName:String, lastName: String){
  def this(firstName: String, lastName: String){
      this(firstName, "", lastName)
  }
}

Tác dụng của Auxiliary Constructors trong Scala? Các quy tắc khi định nghĩa Auxiliary Constructors trong Scala?

Trong Scala, mục đích chính của Auxiliary Constructors là để overload constructors. Tương tự như trong Java, chúng ta có thể cung cấp nhiều loại constructors khác nhau để người dùng chọn tuỳ theo nhu cầu.

Quy tắc của Auxiliary Constructor:

  • Chúng hoạt động giống như các method. Do đó, cần dùng từ khóa “def” để định nghĩa chúng.
  • Tất cả Auxiliary Constructors đều phải sử dụng cùng một tên là “this”.
  • Mỗi Auxiliary Constructor phải bắt đầu bằng một lời gọi đến một Auxiliary Constructor đã được định nghĩa trước đó hoặc Primary Constructor. Nếu không, sẽ bị lỗi compile-time.
  • Mỗi Auxiliary Constructor phải khác nhau ở danh sách tham số: có thể khác về số lượng hoặc kiểu dữ liệu.
  • Auxiliary Constructors không thể trực tiếp gọi super class constructor. Chúng chỉ có thể gọi thông qua Primary Constructor.
  • Tất cả Auxiliary Constructors đều phải gọi về Primary Constructor, trực tiếp hoặc gián tiếp thông qua các Auxiliary Constructors khác.

Sự khác biệt giữa ArrayArrayBuffer trong Scala?

Case class là một class được định nghĩa với từ khóa “case class”. Case object là một object được định nghĩa với từ khóa “case object”. Nhờ có từ khóa “case”, chúng ta sẽ nhận được một số lợi ích để tránh phải viết boilerplate code. Chúng ta có thể tạo object của case class mà không cần dùng từ khóa “new”. Mặc định, Scala compiler sẽ thêm tiền tố “val” cho tất cả constructor parameters. Vì vậy, ngay cả khi không khai báo val hoặc var, các tham số constructor của case class vẫn trở thành class members, điều này không thể thực hiện được với normal classes. Advantages of case class:

  • Mặc định, Scala Compiler sẽ thêm các method toString, hashCode và equals, giúp chúng ta tránh phải viết lại phần boilerplate code này.
  • Mặc định, Scala Compiler sẽ thêm companion object với các method apply và unapply, vì vậy chúng ta không cần dùng từ khóa new để tạo instance của case class.
  • Mặc định, Scala Compiler cũng thêm method copy.
  • Chúng ta có thể sử dụng case classes trong Pattern Matching.
  • Mặc định, Case class và Case Object đều là Serializable.

Sự khác biệt giữa Case Object và Object (Normal Object) là gì?

• Normal object được tạo bằng từ khóa object. Mặc định, nó là một singleton object.

object MyNormalObject

• Case Object được tạo bằng từ khóa “case object”. Mặc định, nó cũng là một singleton object.

case object MyCaseObject

• Mặc định, Case Object có các method toString và hashCode, còn normal object thì không.

• Mặc định, Case Object là Serializable, còn normal object thì không.

Khi so sánh với Normal Class, những ưu điểm hoặc lợi ích lớn nhất của Case Class là gì?

Dưới đây là những ưu điểm chính của Case Class so với Normal Class:

  • Tránh được nhiều boiler-plate code nhờ việc Scala tự động thêm một số method hữu ích.
  • Mặc định hỗ trợ Immutability vì các parameter của nó là “val”.
  • Dễ sử dụng trong Pattern Matching.
  • Không cần dùng từ khóa “new” để tạo instance của Case Class.
  • Mặc định hỗ trợ Serialization và Deserialization.

Việc sử dụng các method isInstanceOf và asInstanceOf trong Scala là gì? Có khái niệm tương tự nào trong Java không?

Cả hai phương thức isInstanceOf và asInstanceOf đều được định nghĩa trong class Any. Vì vậy không cần import để sử dụng trong bất kỳ class hay object nào.

Phương thức “isInstanceOf” được dùng để kiểm tra xem object có thuộc kiểu dữ liệu được chỉ định hay không. Nếu có thì trả về true, ngược lại trả về false.

 scala> val str = "Hello"
   
 scala>str.isInstanceOf[String]
 res0: Boolean = false

Phương thức “asInstanceOf” được dùng để ép kiểu object sang kiểu dữ liệu được chỉ định. Nếu object và kiểu dữ liệu chỉ định là cùng kiểu, thì nó sẽ ép sang kiểu đó. Ngược lại, nó sẽ ném ra java.lang.ClassCastException.

 scala> val str = "Hello".asInstanceOf[String]
 str: String = Hello

Trong Java, từ khóa “instanceof” tương tự với phương thức “isInstanceOf” trong Scala. Trong Java, việc ép kiểu thủ công giống với phương thức “asInstanceOf” trong Scala.

AccountService service = (AccountService)
 context.getBean("accountService");

Làm sao để chứng minh rằng mặc định Case Object là Serializable còn Normal Object thì không?

Vâng, mặc định Case Object là Serializable, còn Normal Object thì không. Chúng ta có thể chứng minh điều này bằng cách sử dụng phương thức isInstanceOf như được minh họa dưới đây:

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

Sự khác biệt giữa Array và List trong Scala

  • Array luôn Mutable, trong khi List luôn Immutable.
  • Khi đã tạo, chúng ta có thể thay đổi giá trị trong Array, nhưng không thể thay đổi đối tượng List.
  • Array là cấu trúc dữ liệu có kích thước cố định, trong khi List là cấu trúc dữ liệu có kích thước thay đổi. Kích thước của List sẽ tự động tăng hoặc giảm dựa trên các thao tác mà ta thực hiện trên nó.
  • Array là Invariant, trong khi List là Covariant.

Lưu ý: Nếu bạn chưa chắc chắn về khái niệm Invariant và Covariant, vui lòng đọc bài viết tiếp theo của tôi về các câu hỏi phỏng vấn Scala.

Sự khác biệt giữa “val” và “lazy val” trong Scala? Eager Evaluation là gì? Lazy Evaluation là gì?

Như đã thảo luận trong Basic Scala Interview Questions, “val” có nghĩa là giá trị hoặc hằng số, được dùng để định nghĩa các biến Immutable.

Có hai loại evaluation trong chương trình:

  1. Eager Evaluation
  2. Lazy Evaluation

Eager Evaluation là việc chương trình được đánh giá ngay tại thời điểm biên dịch hoặc triển khai, bất kể người dùng có thực sự sử dụng hay không, trong khi Lazy Evaluation là việc chương trình chỉ được đánh giá tại thời điểm chạy khi có nhu cầu, nghĩa là chỉ khi người dùng truy cập thì nó mới thực sự được thực thi. Do đó, sự khác biệt giữa “val” và “lazy val” nằm ở cách đánh giá: “val” được đánh giá ngay lập tức, còn “lazy val” thì chỉ được đánh giá trì hoãn khi cần thiết.

Quan hệ giữa equals method và == trong Scala là gì? Phân biệt == trong Scala và == trong Java?

Trong Scala, ta không cần trực tiếp gọi phương thức equals() để so sánh hai instance hay object. Khi ta so sánh hai instance bằng toán tử ==, Scala sẽ tự động gọi phương thức equals() của object đó. Trong Java, toán tử == được dùng để kiểm tra Reference Equality, tức là kiểm tra xem hai reference có trỏ tới cùng một object trong bộ nhớ hay không. Ngược lại, trong Scala, toán tử == được dùng để kiểm tra Instance Equality, tức là kiểm tra xem hai instance có bằng nhau về giá trị hay không.

Sự khác biệt giữa Inner class trong Scala và Java là gì?

Trong Java, Inner class gắn liền với Outer class, tức là nó được xem như một thành viên của Outer class. Ngược lại, trong Scala, mối quan hệ này được xử lý khác: Inner class trong Scala gắn liền với Outer class object, chứ không chỉ với Outer class nói chung.

Diamond Problem là gì? Scala giải quyết Diamond Problem như thế nào?

Diamond Problem là một vấn đề trong Multiple Inheritance. Một số người còn gọi nó là Deadly Diamond Problem. Trong Scala, vấn đề này xảy ra khi một Class kế thừa từ nhiều Traits khác nhau nhưng các Traits đó lại có cùng một định nghĩa phương thức, như trong ví dụ dưới đây.

diamond problem 1

Không giống như Java 8, Scala giải quyết diamond problem một cách tự động bằng cách tuân theo một số quy tắc đã được định nghĩa trong ngôn ngữ. Những quy tắc này được gọi là “Class Linearization”. Ví dụ: –

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
}

Kết quả ở đây là “From C.display” từ trait C. Scala Compiler sẽ đọc phần “extends B with C” từ phải sang trái và lấy định nghĩa phương thức “display” từ trait ngoài cùng bên trái, tức là C.

Tại sao Scala không có keyword “static”? Nguyên nhân chính của quyết định này là gì?

Như chúng ta biết, Scala không hề có keyword “static”. Đây là một quyết định thiết kế có chủ đích từ Scala Team. Nguyên nhân chính là để biến Scala thành một Pure Object-Oriented Language. Keyword “static” có nghĩa là ta có thể truy cập vào các thành viên của class mà không cần tạo object hay không cần thông qua object. Điều này hoàn toàn đi ngược lại với nguyên tắc của OOP. Nếu một ngôn ngữ hỗ trợ “static”, thì ngôn ngữ đó không thể được coi là thuần hướng đối tượng. Ví dụ: Java có hỗ trợ “static” keyword, do đó Java không phải là một Pure Object-Oriented Language. Ngược lại, Scala là một Pure Object-Oriented Language.

Công dụng của keyword “object” trong Scala? Cách tạo Singleton object trong Scala?

Trong Scala, keyword object được dùng cho các mục đích sau:

  • Được sử dụng để tạo singleton object trong Scala.
object MySingletonObject

Ở đây, MySingletonObject tự động trở thành một singleton object. Keyword object được dùng để định nghĩa Scala Applications, tức là các chương trình Scala có thể thực thi.

object MyScalaExecutableProgram{   
   def main(args: Array[String]){
       println("Hello World")
   }
}

Khi ta định nghĩa main method trong một object như ví dụ trên (tương tự như main() method trong Java), chương trình đó sẽ tự động trở thành một executable Scala program. Keyword object cũng được dùng để định nghĩa các static members như static variables và static methods, nhưng không cần dùng đến keyword “static”.

object MyScalaStaticMembers{ 
  val PI: Double = 3.1414  
  def add(a: Int, b: Int) = a + b
}

Khi ta định nghĩa biến PI và các phương thức add, chúng sẽ trở thành static members. Điều này có nghĩa là ta có thể gọi chúng mà không cần tạo một object riêng biệt, ví dụ: MyScalaStaticMembers.add(10, 20).

Ngoài ra, keyword object còn được dùng để định nghĩa Factory methods.

Cách định nghĩa Factory methods bằng keyword object trong Scala? Công dụng của việc định nghĩa Factory methods trong object là gì?

Trong Scala, ta sử dụng keyword object để định nghĩa Factory methods. Mục đích chính của các Factory methods này là tránh phải sử dụng keyword new khi tạo object. Nhờ đó, ta có thể tạo object mà không cần gọi trực tiếp new constructor.

Để định nghĩa Factory methods, ta có thể dùng apply method. Nếu một class có Primary Constructor và nhiều Auxiliary Constructors, ta sẽ định nghĩa nhiều apply methods tương ứng.

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)
}

Bây giờ, chúng ta có thể tạo các object Person không cần dùng keyword new, hoặc dùng new nếu muốn.

val p1 = new Person("Scala","Java")
or 
val p1 = Person("Scala","Java")

Apply method và unapply method trong Scala là gì? Sự khác biệt giữa chúng?

Trong Scala, apply và unapply methods đóng vai trò rất quan trọng. Chúng cũng rất hữu ích trong Play Framework để mapping và unmapping dữ liệu giữa Form data và Model data.

Nói đơn giản:

  • apply method: Dùng để tạo hoặc lắp ráp một object từ các thành phần của nó.
  • unapply method: Dùng để phân rã hoặc tháo rời một object thành các thành phần của nó.

Apply method trong Scala: Nó được dùng để tạo một object bằng cách sử dụng các thành phần của object đó. Ví dụ, nếu muốn tạo một object Person, ta sẽ dùng hai thành phần firstName và lastName để lắp ráp thành object Person như sau.

class Person(val firstName: String, val lastName: String)

object Person{
  def apply(firstName: String, lastName: String) 
        = new Person(firstName, lastName)
}

Unapply method trong Scala: Nó được dùng để phân rã một object thành các thành phần của nó. Đây là quá trình ngược lại với apply method. Ví dụ, nếu ta có một object Person, thì có thể phân rã object này thành hai thành phần firstName và lastName như minh họa dưới đây.

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)
}

Cách hoạt động “under-the-hood” khi tạo một instance của Class mà không dùng từ khóa new trong Scala? Khi nào nên sử dụng cách này? Cách khai báo constructor private trong Scala?

Trong Scala, khi chúng ta tạo một instance của Class mà không dùng từ khóa “new”, về cơ bản hệ thống sẽ gọi phương thức apply phù hợp có trong Companion object của class đó. Ở đây, “phương thức apply phù hợp” nghĩa là phương thức có tham số khớp với những gì chúng ta truyền vào.

Khi nào nên dùng cách này:

  • Khi chúng ta muốn cung cấp constructor private (không muốn ai ngoài class hoặc companion object trực tiếp gọi constructor).
  • Khi muốn tránh việc sử dụng từ khóa new khi tạo instance.

Cách làm là: chúng ta chỉ cần triển khai phương thức apply với cùng tập tham số như constructor private, từ đó cho phép người dùng class tạo object mà không cần dùng từ khóa new.

Làm thế nào để khai báo một Primary Constructor private trong Scala? Làm sao để gọi đến private Primary Constructor đó?

Trong Scala, việc khai báo một Primary Constructor private rất đơn giản. Chỉ cần định nghĩa Primary Constructor như bình thường và thêm từ khóa private ngay sau tên class và trước danh sách tham số như ví dụ dưới đây:

class Person private (name: String)
object Person{
 def apply(name: String) = new Person(name)
}

Vì đây là private constructor, nên chúng ta không thể gọi trực tiếp từ bên ngoài. Thay vào đó, cần cung cấp một factory method (tức là phương thức apply như đã trình bày ở trên) và sử dụng constructor đó một cách gián tiếp.

Companion object có truy cập được các private member của Companion class trong Scala không?

Thông thường, các private member chỉ có thể truy cập bên trong chính class đó. Tuy nhiên, Scala cung cấp một tính năng đặc biệt cho Companion class và Companion object: trong Scala, một Companion object có thể truy cập các private member của Companion class, và ngược lại, Companion class cũng có thể truy cập các private member của Companion object.

Quyết định thiết kế chính về hai từ khóa riêng biệt class và object trong Scala là gì? Làm thế nào để định nghĩa instance members và static members trong Scala?

Trong Scala, chúng ta dùng từ khóa class để định nghĩa các instance members và từ khóa object để định nghĩa các static members. Scala không có từ khóa static, nhưng vẫn có thể định nghĩa chúng bằng cách sử dụng từ khóa object. Quyết định thiết kế chính ở đây là để tạo ra sự phân tách rõ ràng giữa instance members và static members, giảm sự phụ thuộc lẫn nhau. Một lý do quan trọng khác là tránh dùng từ khóa static để Scala trở thành một ngôn ngữ lập trình hướng đối tượng thuần túy.

Object trong Scala là gì? Nó là singleton object hay instance của class?

Khác với Java, trong Scala, từ khóa “object” có hai nghĩa. Đừng nhầm lẫn. Trong Java, object chỉ có một nghĩa duy nhất là “một instance của class”.

• Tương tự như Java, nghĩa thứ nhất của object trong Scala cũng là “một instance của class”.

val p1 = new Person("Scala","Java")
or 
val p1 = Person("Scala","Java")

• Nghĩa thứ hai là object là một từ khóa trong Scala. Nó được dùng để định nghĩa các chương trình có thể thực thi trong Scala, Companion Objects, Singleton Objects, v.v.

Companion Object trong Scala là gì? Companion Class trong Scala là gì? Công dụng của Companion Object trong Scala là gì?

Nói một cách đơn giản, nếu một class và một object trong Scala có cùng tên và được định nghĩa trong cùng một file nguồn, thì class đó được gọi là “Companion Class” và object đó được gọi là “Companion Object”.

Khi chúng ta tạo một Class bằng từ khóa “class” và một Object bằng từ khóa “object” với cùng tên và trong cùng file nguồn, thì class đó được gọi là “Companion Class” và object đó được gọi là “Companion Object”.

Ví dụ: Employee.scala

class Employee{ }
object Employee{ }

Trong Scala, mục đích chính của Companion Object là để định nghĩa các phương thức apply và tránh việc sử dụng từ khóa new khi tạo instance của Companion class đó.

Làm thế nào để implement interfaces trong Scala?

Như chúng ta biết từ Java, ta dùng interface để định nghĩa hợp đồng. Tuy nhiên, trong Scala không có khái niệm interface. Thậm chí, Scala cũng không có từ khóa interface. Thay vào đó, Scala có một khái niệm mạnh mẽ và linh hoạt hơn, đó là trait, để thực hiện mục đích này.

Range trong Scala là gì? Làm thế nào để tạo Range trong Scala?

Range là một Lazy Collection trong Scala. Range là một class có sẵn trong package “scala”, ví dụ “scala.Range”. Nó được dùng để biểu diễn một dãy các giá trị nguyên theo thứ tự.

Ví dụ:

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)

Trong Scala, kiểu Nothing có bao nhiêu giá trị?

Trong Scala, kiểu Nothing không có giá trị nào cả. Nó là subtype của tất cả các Value classes và Reference classes.

Trong Scala, kiểu Unit có bao nhiêu giá trị?

Trong Scala, Unit tương tự như từ khóa void trong Java. Nó được dùng để biểu diễn “không có giá trị”. Kiểu Unit chỉ có một giá trị duy nhất, đó là ().

Pure function là gì?

Pure function là một hàm không có bất kỳ side-effect quan sát được nào. Nghĩa là, hàm luôn trả về kết quả giống nhau bất kể chúng ta gọi nó bao nhiêu lần với cùng đầu vào. Một pure function luôn cho cùng một output với cùng một input.

Ví dụ:

scala> 10 + 20
res0: Int = 30
scala>
scala> 10 + 20
res0: Int = 30

Ở đây, phép “+” là một pure function có sẵn trong class Int. Nó luôn cho kết quả giống nhau là 30 khi cộng 10 và 20, bất kể chúng ta gọi nó bao nhiêu lần.

Trong FP, sự khác nhau giữa function và procedure là gì?

Cả hai đều được dùng để thực hiện tính toán, tuy nhiên trong lập trình hàm có một khác biệt chính: Function là một đơn vị tính toán không có side-effect, trong khi Procedure là một đơn vị tính toán có side-effect.

Sự khác biệt chính giữa Auxiliary constructors trong Scala và constructors trong Java là gì?

Auxiliary constructors trong Scala gần giống với constructors trong Java nhưng có một vài điểm khác:

  • Auxiliary constructors được gọi bằng từ khóa “this”.
  • Tất cả auxiliary constructors đều có cùng tên là “this”, trong khi Java dùng tên class để định nghĩa constructor.
  • Mỗi auxiliary constructor phải bắt đầu bằng một lời gọi tới một auxiliary constructor đã định nghĩa trước đó hoặc tới primary constructor.
  • Chúng ta dùng từ khóa “def” để định nghĩa auxiliary constructors, giống như định nghĩa method/function. Trong Java, định nghĩa constructor khác với định nghĩa method.

Công dụng của từ khóa “yield” trong for-comprehension của Scala là gì?

Chúng ta có thể sử dụng từ khóa “yield” trong cấu trúc for-comprehension của Scala. Cấu trúc “for/yield” được dùng để lặp qua một collection các phần tử và tạo ra một collection mới cùng kiểu với collection gốc. Nó không thay đổi collection ban đầu, mà sinh ra một collection mới cùng loại với collection gốc.

Ví dụ: nếu dùng “for/yield” để lặp qua một List, kết quả sẽ là một List mới.

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)

Guard trong cấu trúc for-comprehension của Scala là gì?

Trong Scala, cấu trúc for-comprehension có một mệnh đề if được dùng để viết điều kiện nhằm lọc một số phần tử và tạo ra collection mới. Mệnh đề if này còn được gọi là “Guard”. Nếu guard đó đúng thì phần tử sẽ được thêm vào collection mới, ngược lại thì phần tử đó sẽ không được thêm vào collection mới.

Ví dụ: For-comprehension Guard để tạo ra collection chỉ chứa các số chẵn.

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 giải quyết vấn đề Inheritance Diamond Problem như thế nào dễ dàng và tự động hơn Java 8?

Nếu dùng Interface với Default methods trong Java 8, chúng ta sẽ gặp Inheritance Diamond Problem. Lập trình viên phải tự xử lý thủ công vì Java 8 không cung cấp cách giải quyết mặc định hay tự động cho vấn đề này. Trong Scala, khi dùng Traits cũng sẽ gặp vấn đề tương tự, nhưng Scala giải quyết Inheritance Diamond Problem một cách tự động nhờ cơ chế Class Linearization.

Trong Scala, Pattern Matching tuân theo Visitor Design Pattern? Trong Java, toán tử “instanceof” cũng tuân theo Visitor Design Pattern?

Trong Scala, Pattern Matching tuân theo Visitor Design Pattern. Tương tự, trong Java, toán tử “instanceof” cũng tuân theo Visitor Design Pattern. Đó là toàn bộ phần “Scala Intermediate Interview Questions and Answers”. Trong các bài viết tiếp theo, chúng ta sẽ thảo luận về Advanced Scala Interview Questions and Answers. Vui lòng để lại bình luận nếu bạn thích bài viết hoặc có bất kỳ thắc mắc/đề xuất nào.

0 Bình luận

Đăng nhập để thảo luận

Chuyên mục Hướng dẫn

Tổng hợp các bài viết hướng dẫn, nghiên cứu và phân tích chi tiết về kỹ thuật, các xu hướng công nghệ mới nhất dành cho lập trình viên.

Đăng ký nhận bản tin của chúng tôi

Hãy trở thành người nhận được các nội dung hữu ích của CyStack sớm nhất

Xem chính sách của chúng tôi Chính sách bảo mật.

Đăng ký nhận Newsletter

Nhận các nội dung hữu ích mới nhất