Câu hỏi phỏng vấn Scala phần 3

scala

Scala là gì ? Nó là một Language hay Platform ? Nó hỗ trợ OOP hoặc FP không ? Ai là cha đẻ của Scala ?

Scala là tiểu chuẩn cho Scalable Language. Martin Odersky là cha đẻ của Scala.

Scala là một Multi-Paradigm Programming Language, hỗ trợ cả OOP và Functional Programming. Nó được thiết kế và phát triển bởi Martin Odersky

Scala là Type-Safe Object-Functional Programming JVM language. Scala chạy trên JVM (Java Virtual Machine).

Scala là một Hybird Functional (Object Oriented và Functional). Scala là một String và Statically Type System. Trong Scala, tất cả các Type được kiểm tra trong compile Time

Scala là Statically-typed language ? Statically-typed language là gì ? Dynamically-typed language là gì ? Hãy so sánh khác nhau giữa chúng

Scala là Statically-typed language.

Statically-typed language nghĩa là Type được kiểm tra khi complier time bởi compiler, mà không phải trong lúc run-time.

Lợi ích chính của các loại ngôn ngữ này là: Như một Developer, chúng ta nên đảm bảo trong việc viết code chính xác để tránh tất cả các lỗi trong lúc compile. Nên khi Compiler kiểm tra tất cả các lỗi trong khi compile,  thì chúng ta sẽ không gặp nhiều vấn đề hay các bug khi run-time

Ví dụ: Java, Scala, C,C++, Haskell

Dynamically-typed Language nghĩa là type sẽ được kiểm tra khi run-time, không phải trong lúc compile bởi compiler. Nên compiler sẽ không kiểm tra type khi compile. Do đó chúng ta có thể gặp các vấn đề hơn hoặc các bug khi run-time.

Ví dụ: Groovy, Javascript, Ruby, Python, Smalltalk

Scala là một Pure OOP language không ? Java là một Pure OOP language không ?

Pure Object-Oriented Programming Language nghĩa là tất cả nên là một object.

Java không phải là Pure OOP language vì nó hỗ trợ hai khái niệm non-OOP sau:

  • Java hỗ trợ các kiểu dữ liệu cũ. Chúng không phải là objects
  • Java hỗ trợ Static members. Chúng không liên quan đến các object

Scala là Pure OOP language vì trong Scala, tất cả đều là một Object và tất cả đều là một giá trị. Các hàm là các giá trị và các giá trị là các object

Scala không có các kiểu dữ liệu cũ và cũng không có static members (trong class)

Scala hỗ trợ toàn bộ khái niệm Functional Programming không ? Java 8 hỗ trợ toàn bộ khái niệm Functional Programming không ?

Scala hỗ trợ toàn bộ khái niệm FP, còn Java 8 chỉ giới thiệu một vài cấu trúc của Fuctional Programming mà không hỗ trợ toàn bộ khải niệm FP

Ví dụ Java 8 không hỗ trợ Pattern matching, Function Currying, implicits..

Những ưu điểm chính của ngôn ngữ Scala là gì ? Nhược điểm của nó là gì ?

Nếu chúng ta dùng Scala để phát triển các ứng dụng, chúng ta có thể có được các lợi ich, ưu điểm và nhược điểm sau

Những ưu điểm của ngôn ngữ Scala là:

  • Code đơn giản và ngắn gọn
  • Code rất dễ diễn đạt
  • Khả năng đọc Code dễ hơn
  • 100% là type-safe ngôn ngữ
  • immutability và No Side-Effects
  • Sử dụng lại code tốt hơn
  • Dễ modular hơn
  • làm nhiều việc hơn với code ít hơn ( có thể làm một logic phức tạp bằng đoạn code đơn giản)
  • Cú pháp rất linh hoạt
  • Hỗ trợ tất cả các đặc tính OOP
  • Hỗ trợ toàn bộ đặc tính FP. Highly Functional
  • Code ít khi bị lỗi hơn
  • Lập trình chạy song song và đồng thời tốt hơn
  • Code có tính mở rộng và khả năng maintainable rất cao
  • Hiệu suất cao
  • Distributed Applications
  • Khả năng tương tác đầy đủ với Java
  • Powerful Scala DSLs available
  • REPL to learn Scala Basics

Nhược điểm của Scala là:

  • Khả năng đọc Code khó hơn
  • Hơi khó khăn để hiểu code khi mới học
  • Cú pháp khó hiểu khi học
  • Ít khả năng tương thích ngược

Chú ý: Chúng ta có thể viết Code cho Scala một cách dễ đọc hoặc khó hiểu tuỳ theo cách viết. Vì Scala có thể viết một đoạn code theo nhiều cách khác nhau

Nhược điểm chính của Scala là gì ?

Ngoài rất nhiều các lợi ích của Scala, thì nó có một nhược điểm chính là: Vấn đề tương thích ngược. Khi chúng ta cập nhập lên version mới nhất của Scala, thì chúng ta cần cẩn thận trong việc thay đổi tên của các package, các class, method và function

Ví dụ nếu chúng ta sử dụng Scala version cũ và project đang dùng BeanProperty annotation. Nó đang tồn tại trong “scala.reflect” như là “scala.reflect.BeanProperty” trong version cũ. Nếu chúng tà cập nhập lên version mới, thì chúng ta cần thay đổi package từ “scala.reflect” thành “scala.beans”

Châm ngôn chính của Scala là gì ?

Giống như châm ngôn của Java là “Write once run anywhere”, thì châm ngôn của Scala là “Do more with less” hay “Do more with less code”

“Do more with less” nghĩa là chúng ta có thể phát triển một chương trình hay logic phức tạp với lượng code ít hơn

Các ngôn ngữ JVM nào là  phổ biến hiện nay?

Java, Scala, Groovy và Closure là các ngôn ngữ JVM phổ biến hiện nay.

Scala, Groovy và Closure đều hỗ trợ các đặc tính OOP và Functional Programming

Java 8 SE hỗ trợ toàn bộ đặc tính OOP. Tuy nhiên nó chỉ hỗ trợ một vài đặc điểm Funtional Programming như là Lambda Expression, function, type Inference, higher-order function

Giống như Java có java.lang.Object class, thì trong Scala có super class của tất cả các class  không ?

Như chúng ta đã biết trong Java, super class của tất cả class là java.lang.Object. Trong Scala cũng vậy, super class của tất cả class và trait là “Any” class.

Any class được định nghĩa trong scala package “scala.Any”

Truy cập mặc đinh modifier trong Scala là gì ? Scala có hỗ trợ từ khoá “public” không ?

Trong Scala, chúng ta không được đề cập đến việc truy cập một method, function, trait, object hay class, mặc định truy cập modifier là “public”. Thậm chí các trường cũng thế, “public” là mặc định truy cập của các modifier.

Chính vì lý do này mà Scala không hỗ trợ từ khoá “public”

“type inference” trong Scala là gì ?

“Type inference” là các kiểu mà có thể được suy luận bởi Scala compiler khi compile. Các kiểu này là kiểu dữ liệu hoặc kiểu trả về. Chúng ta có thể sử dụng các Types này tại nhiều chỗ trong Scala như Variable Types, Object types, kiểu tham số của Method/Function, kiểu trả về của method/ fucntion

Các điểm giống và khác nhau giữa Scala Int và java.lang.Integer là gì ? Mối liên hệ giữa Int và RichInt trong Scala là gì ?

Các điểm giống nhau giữa Scala Int và Java Integer là:

  • Cả 2 đều là class
  • Cả 2 đều được dùng để diễn tả số Integer
  • Cả 2 đều là 32 bit integers

Điểm khác nhau giữa Scala Int và Java Interger là:

  • Scala Int class không implement Comparable Interface (so sánh object)
  • Java Integer implement Comparable Interface

Java Integer giống Scala Inter và RichInt. RichInt là final class được định nghĩa trong scala.runtime như là “scala.runtime.RichInt”

Trong Scala, mối liên hệ giữa Int và RichInt là khi chúng ta sử dụng Int trong một chương trình chạy Scala, nó sẽ tự động chuyển đổi giữa thành RichInt mục đích để sử dụng tất cả các method có sẵn trong Class. Chúng ta có thể nói RichInt là một implicit class của Int.

Nothing trong Scala là gì ? Nil trong Scala là gì ? Mối liên hệ giữa Nothing và Nil trong Scala là gì ?

Trong Scala, Nothing là một kiểu(final class). Nó là một subtype của anything trong Scala. Không có instances của Nothing

Nếu Nothing không có instances thì khi nào chúng ta sử dụng nó trong Scala:

  • Nil được định nghĩa sử dụng Nothing
  • None cũng được định nghĩa để sử dụng Nothing

object None extends Option[Nothing]

  • Chúng ta có thể sử dụng Nothing như một kiểu trả về trong method mà không bao giờ return
  • Chúng ta có thể sử dụng Nothing như một kiểu trả về trong method khi chương trình thoát đột ngột (bất thường)

Nil là một object thường được dùng để diễn tả một list trống. Nó được định nghĩa trong “scala.collection.immuable” package như sau:

object Nil extends List[Nothing]

Ví dụ:

scala> Nil
 res5: scala.collection.immutable.Nil.type = List()
 scala> Nil.length
 res6: Int = 0

Null trong Scala là gì ? null trong Scala là gì ? So sánh khác nhau giữa Null và null trong Scala ?

Null là một kiểu (final class) trong Scala. Null tồn tại trong package “scala.null”. Nó có một và chỉ một instance là null

Trong Scala, null là instance của scala.Null

Ví dụ:

scala> val myNullRef : Null = null
 myNullRef: Null = null

Chúng ta không thể gán các giá trị khác (ngoài null) thành Null type. Nó chỉ chấp nhận giá trị null

Null là subtype của tất cả các Reference types. Nó  không phải là subtype của value types., chúng ta không thể gán “null” cho bất kỳ biến nào của value type

Ví dụ:

scala> val myInt : Int = null
 :10: error: an expression of type Null is ineligible for implicit conversion
 val myInt : Int = null

Unit là gì ? So sánh khác nhau giữa Java void và Scala Unit ?

Trong Scala, Unit dùng để biểu diễn là “không có giá trị” hoặc “Giá trị không hữu ích”. Unit là final class trong Scala package “scala.Unit”

Unit của Scala là giống với void của Java. Nhưng chúng có vài điểm khác nhau:

  • Java void không có giá trị nào. Nó không có gì
  • Scala unit có một giá trị là ()
  • () là giá trị của type Unit trong Scala. Tuy nhiên Java void thì không có giá trị
  • Java void là từ khoá (định nghĩa hàm). Scala unit là final class

Cả 2 đều dùng để diễn tả method/function không trả về giá trị

So sánh khác nhau giữa val và var ?

Trong Scala, val và var được dùng để định nghĩa các biến. Tuy nhiên chúng có ý nghĩa khác nhau:

  • var là viết tắt của variable
  • val là viết tắt của value
  • Như chúng ta đã biết rằng, variable có nghĩa là có thể thay đổi được còn value có nghĩa là không thể thay đổi (hằng số)
  • var được dùng để định nghĩa mutable biến nên chúng ta có thể gán lại cho biến một giá trị mới
  • val được dùng để định nghĩa immuable biến nên chúng ta không thể thay đổi giá trị của nó
  • Trong thuật ngữ của Java, var nghĩa là “variable” và val nghĩa là “final variable”

REPL trong Scala là gì ? Làm thế nào để truy cập REPL trong CMD prompt ?

REPL viết tắt của Read-Evaluate-Print Loop. REPL được biết như là biên dịch để chạy code Scala trên command prompt. Nó là lý do tại sao mà RELP còn được biết như là Scala CLI(Command Line Interface) hay Scala command-line shell

Mục đích chính của REPL là dùng để phát triển hoặc kiểm tra một đoạn code nhỏ của scala với mục đích để thực hành. Nó rất là hữu ích cho Scala Beginner để thực hành các chương trình cơ bản.

Chúng ta có thể truy cập REPL bằng cách dùng câu lệnh “scala”. Khi chúng ta gõ câu lệnh “scala” trên CMD prompt, chúng ta sẽ truy cập REPL shell để chạy scala code

D:\> scala
 scala>

Các tính năng của Scala ?

Ngôn ngữ Scala hỗ trợ các tính năng sau:

  • Hỗ trợ OOP-style và Functional-style
  • Pure OOP language
  • Hỗ trợ đầy đủ đặc điểm của Functional
  • REPL biên dịch
  • Strong Type System
  • Statically-Typed ngôn ngữ
  • Type inference (Suy ra type)
  • Hỗ trợ Pattern Matching
  • Hỗ trợ Closures
  • Hỗ trợ cấu trúc dữ liệu Persistent
  • Sử dụng Actor Modal để phát triển các ứng dụng truy cập đồng thời
  • Khả năng tương thích với Java
  • Sẵn có trên tất cả các tool phát triển: IDE, build tool, web framework, TDD, BDD framework

Làm thế nào để chúng ta implement vòng lặp ? So sánh khác nhau của vòng lặp trong OOP và FP ?

Chúng ta có thể hiểu  làm thế nào để implement một vòng lặp trong Object-Oriented: Đó là sử dụng một biến tạm mutable, cập  nhập giá trị của biến và sử dụng cấu trúc vòng lặp. Nó rất là tẻ nhạt và cách tiếp cận không an toàn. Nó không phải là thread-safe.

Object-Oriented style sử dụng cấu trúc sau đây để implement vòng lặp:

  • Cấu trúc vòng lặp
  • Mutability (giá trị biến thay đổi)
  • Side Effects ( có tác động từ bên ngoài làm ảnh hưởng đến tính toán)

Chúng ta có thể implement vòng lặp bằng cách khác trong Functional. Nó là Thread-Safe. Chúng ta có thể sử dụng 2 kỹ thuật để implement vòng lặp trong functional style:

  • Recursion ( đệ quy)
  • Tail-Recursion
  • Immuability
  • No Side-Effects

“Application” trong Scala là gì ? Scala Application là gì ? “app” trong Scala là gì ? “app” được dùng để làm gì?

Scala Application:

Trong Scala, App là một trait được định nghĩa trong scala package như “scala.App”. Nó định nghĩa main method. Nếu một Object hoặc class extends từ trait này, thì chúng sẽ trở thành một chương trình Scala có thể được gọi chạy một cách tự động bởi vì chúng sẽ kế thừa main method từ Application

Ưu điểm chính của việc sử dụng App là chúng ta sẽ không cần viết main method.

Nhược điểm của việc sử dụng App là chúng ta phải sử dụng  tên “args” để tham chiếu đến tham số của command line bởi vì scala.App sử dụng tên này cho main() method

Ví dụ:

Nếu không sử dụng Scala App:

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

Nếu sử dụng Scala App:

object MyApp extends App{
  println("Hello World!")
}

Nếu chúng ta quan sát 2 ví dụ ở trên, trong ví dụ thứ 2 chúng ta không định nghĩa main() method bởi vì chúng được kế thừa từ Scala App(Application)

Trước Scala 2.9, chúng ta có scala.Application trait. Nhưng nó đã chuyển thành scala.app sau version 2.9

Scala hỗ trợ Operator Overloading không ? Java có hỗ trợ Operator Overloading không ?

Java không hỗ trợ operator overloading. Scala thì hỗ trợ  Operator Overloading

Lý do là Java không muốn hỗ trợ tên method mà dễ gây hiểu nhầm như “+*/”. Scala thích sự mềm dẻo để Developer có thể quyết định tên method/function nên dùng

Khi chúng ta gọi 2 + 3 thì  “+” không phải là một operator, nó là một method trong Int class ( hoặc nó là implicit type). Khi chúng ta gọi như thế nó sẽ convert thành “2.+(3)”.

Expression là gì ? Statement là gì ? So sánh khác nhau giữa Expression và Statement ?

Expression:

Expression là một giá trị, nghĩa rằng nó sẽ được tính toán thành một giá trị. Giống như một Expression trả về một giá trị, chúng ta có thể gán nó vào một biến

Ví dụ:  if của Scala

Statement:

Statement định nghĩa một hoặc nhiều actions, operations, nghĩa là một Statement thực hiện các actions. Nhưng nó không trả về một giá trị, chúng không thể gán vào một biến

Ví dụ: If của Java

So sánh khác nhau giữa “if…Else” của Java và Scala ?

“If…else” của Java:

Trong java, “if…else” là một statement, không phải là một expression. Nó không trả về một giá trị và không thể gán vào một biến

Ví dụ:

 int year;
 if( count == 0)
 year = 2014;
 else
 year = 2015;

“If…else” của Scala:

Trong Scala, “if…else” là một Expression. Nó giúp tính toán một giá trị và chúng ta có thể gán nó vào một biến

Ví dụ:

val year = if( count == 0) 2014 else 2015

Chú ý rằng “if..else” của scala hoạt động như Java Ternary Operator.

val year = 0
if( count == 0)
 year = 2014
else
 year = 2015

Scala là ngôn ngữ dựa trên Expression-Based hay Statement-Based ? Java là ngôn ngữ dựa trên Expression-Based hay Statement-Based ?

Trong Scala, tất cả đều là một giá trị. Tất cả Expression hay Statement đều tính toàn thành một giá trị. Chúng ta có thể gán Expression, Function, Closure, Object..etc vào một biến. Do đó Scala là một Expression-oriented ngôn ngữ.

Trong Java, Statement không phải là một Expression hay giá trị. Chúng ta không thể gán nó vào một biến, do đó Java không phải là Expression-oriented ngôn ngữ, nó là một Statement-Based ngôn ngữ.

Những đặc điểm mà hỗ trợ bởi Java nhưng không có trong Scala và ngược lại ?

  • Java không hỗ trợ Operator Overloading, nhưng Scala hỗ trợ nó
  • Java hỗ trợ ++ và — operators, nhưng scala không hỗ trợ nó
  • Java có checked (kiểm tra exception khi compile) và unchecked (kiểm tra exception khi runtime) Exception, nhưng Scala không có checked Exceptions
  • Scala không hỗ trợ break và continue statement, nhưng java sử dụng chúng
  • Scala không có explicit type casting, nhưng java hỗ trợ nó
  • Scala hỗ trợ pattern matching nhưng java thì không
  • Java sử dụng Primitive Data type nhưng Scala thì không
  • Java hỗ trợ static member nhưng Java thì không có khái niệm này
  • Scala hỗ trợ implicit và trait, nhưng Java thì không

Chú ý: Còn nhiều tính năng nữa nhưng ở trên là những tính năng cơ bản dễ nhớ về sự khác nhau giữa Java và Scala

Sự khác nhau giữa Function và Method trong Scala ?

Scala hỗ trợ cả function và method. Chúng sử dụng cú pháp giống nhau để định nghĩa các function và method, không có sự khác nhau về cú pháp

Tuy nhiên chúng có một điểm nhỏ khác nhau:

  • Chúng ta có thể định nghĩa một method trong Scala như một class hoặc trait. Method được liên kết đến một object(instance của class). Chúng ta có thể gọi một method bằng cách sử dụng một class instance. Chúng ta không thể sử dụng một method ngoài việc tạo một object
  • Function không liên quan đến class hoặc trait. Nó được định nghĩa trong scala package. Chúng ta có thể truy cập các function mà không cần sử dụng object, giống như static trong Java

Có bao nhiêu public class có thể định nghĩa trong Scala source ?

Trong Java chúng ta chỉ có thể định nghĩa duy nhất một class/interface trong file Source. Không giống như Java, Scala có thể hỗ trợ nhiều public class trong một source files.

Chúng ta có thể định  nghĩa nhiều số public class/trait trong một scala source.

Giống như Java, Scala mặc định import package nào ?

Chúng ta biết rằng, java.lang là package mặc định được import trong chương trình Java bởi JVM một cách tự động.

Cũng vậy, trong Scala cũng mặc định import:

  • java.lang package
  • scala package
  • scala.PreDef

Có bao nhiêu operator trong Scala và tại sao ?

Không giống như Java và giống C++, Scala hỗ trợ Operator Overloading. Scala chỉ có duy nhất một operator là “=”. Còn lại đều là method

Ví dụ 2+3 thì “+” không phải là operator trong Scala. “+” là method trong Int class. Scala compiler sẽ coi 2 và 3 là một Integers và thử tìm “+” method trong Int class. Nên Scala compiler chuyển đổi “2+3” thành “2.+3” và gọi “+” method trong Int object “2” và truyền  integer object “3” như một tham số của method “+”

Cả “2+3” và “2.+3” cho kết quả như nhau

Các từ khoá được dùng trong Java nhưng không yêu cầu trong Scala ? Tại sao Scala không yêu cầu chúng ?

Java sử dụng những từ khoá sau:

  • Từ khoá “public” – định nghĩa class, interfaces và các biến vv..v
  • Từ khoá “static” – định nghĩa static members.

Scala không yêu cầu sử dụng những từ khoá trên. Scala không có từ khoá “public” và “static”

  • Trong Scala, mặc định truy cập các modifer là “public” trong class, trait, method/function, fields vv… Nó là lý do tại sao từ khoá “public” không yêu cầu
  • Để hỗ trợ hoàn toàn OOP, scala team đã tránh sử dụng “static”. Nó là lý do vì sao Scala là một Pure-OOP ngôn ngữ. Nó rất khó phân chia static members trong các ứng dụng chạy bất đồng bộ

PreDef là gì ? Mục đích chính của PreDef trong Scala là gì ?

Trong Scala, PreDef là một Object được định nghĩa trong Package “scala.PreDef”. Nó là một utility object.

Nó định nghĩa các utility method sau:

  • Console IO (print, println ..)
  • Collection utility methods
  • String utility methods
  • Implicit conversion methods
  • Asertion utility methods

Ví dụ: print, println, readLine, readInt, require method được định nghĩa trong PreDef Object

Trong Scala, PreDef là có sẵn để sử dụng các method mà không cần import trong chương trình Scala bởi vì Scala compiler import object này trong tất cả các biên dịch giống như Class, Object, Triat ..một cách tự động

You May Also Like

About the Author: Nguyen Dinh Thuc

Leave a Reply

Your email address will not be published.