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

scala

Version hiện tại của Scala ? Scala 2.12 có gì mới ?

Version hiên tại của Scala là 2.11.7 (stable). Nó hỗ trợ Java SE 7.

Scala v2.12 hỗ trợ Java SE8 hoặc version mới nhất.

2. Option trong Scala là gì ? Some và None có ý nghĩa gì ? Option/Some/None là design pattern nào trong Scala ?

Trong Scala, Option thường được miêu tả giá trị có tồn tại hoặc không

Option là một abstract class. Option thường có 2 subclass: Some và None. Tất cả (Option, Some, None) đều được định nghĩa trong Scala package như là “scala.Option”

Option là một bounded collection trong Scala. nó chứa một phần tử hoặc không. Nếu Option không chứa phần tử nào thì gọi là None. Nếu nó chứa một phần tử thì gọi là Some

Ví dụ:

def get(val index: Int): Option[String]

Giả sử  hàm trên từ một List. Hàm này sẽ trả vể kiểu là Option[String]. Nếu List này chứa các phần tử thì hàm get sẽ trả về một phần tử là “Some[String]” mà thoả mãn giá trị index đầu vào. Ngoài ra nó sẽ trả về None nếu không có phần tử nào.

Some là một case class, còn None là một Object. Và vì cả 2 đều là case class / object nên chúng ta có thể dùng chúng trong pattern matching

Sự kết hợp của tất cả 3 định nghĩa trên được gọi là Option/Some/None Design Pattern trong Scala

Either là gì trong Scala ? Left và Right là gì ? Hãy giải thích Left, Right và Either design pattern trong Scala ?

Trong Scala, Either là một abstract class. Nó được dùng để biểu diễn giá trị của 2 kiểu khác nhau (có thể). Nó nhận được 2 kiểu tham số khác nhau: Either[A, B]

Nó chính xác có 2 kiểu lớp con (subtypes): Left và Right. Nếu Either[A,B] diễn tả một instance A thì có nghĩa nó là Left. Nếu nó diễn tả một instance B thì có nghĩa nó là Right

Cái này được gọi là Either/Left/Right design pattern trong Scala

Scala Option là tương đương với gì trong Java SE 8 ? Sử dung Option như thế nào trong Scala ?

Scala Option là tương tự Java SE 8 Optional. Java SE 8 đã giới thiệu một class Optional hữu ích mới để diễn tả các giá trị tồn tại hoặc không. Optional có sẵn trong “java.util” package.

Cả Scala Option và Java SE Optional đều đại diện cho các giá trị không bắt buộc. Cả 2 đều được dùng để tránh việc kiểm tra null không mong muốn và NullPointerException.

Ưu điểm của Function Programming hoặc Pure Function là gì ?

Dưới đây là những ưu điểm của Function Progamming hoăc Pure Function:

  • Moduler hơn
  • Dễ hiểu hơn
  • Dễ kiểm tra hơn
  • Ít bị Bug hơn
  • Dễ sử dụng lại hơn
  • Easier to Parallelism and generalize

Framework nào là phổ biến trong Scala để phát triển RESTful webservice hoặc REST API ?

Có rất nhiều Framework trong Scala để phát triển RESTful webservice. Phổ biến nhất là:

  • Play framework: Trong Play chúng ta gọi các REST API URL giống Routes. Các URL được đặt tất cả trong route của Play Framework. Nó là một web framework giúp tạo Rest Api dễ dàng
  • Scalatra Framework:  Nó là một web framework giúp tạo Rest Api một cách đơn giản và dễ dàng.
  • Spray Framework: Nó rất ngắn gọn và được xây dựng dựa trên Akka framework, nên cách tốt nhất là dùng Actor Modal để tạo một Rest Api
  • Lift Framework: Nó cho routing bằng cách sử dụng pattern matching

Framework nào tốt nhất giúp tạo tài liệu Rest Api cho Scala ?

Swagger là tool tốt nhất cho mục đích này. Nó rất đơn giản và là open source tool để tạo tài liệu Rest Api cùng với Json trong Scala

  • Nếu chúng ta sử dung Play Framework bằng Scala để tạo Rest Api, thì có thể sử dụng play-swagger module để tạo tài liệu Rest Api
  • Nếu chúng ta sử dụng Spray để tạo Rest Api, thì sử dụng spray-swagger module để tạo tài liệu Rest Api

Giống như Hibernate trong Java, ORM Framework nào là phổ biến trong Play/Scala ?

Giống như JPA, Hibernate và Toplink là những ORM Framework trong Java. Trong Scala, cũng có rất nhiều ORM Framework  được sử dụng trong Play/Scala.

Những ORM framework phổ biến nhất cho Play/Scala là:

  • Slick
  • Anorm
  • SORM ( Scala ORM)
  • Squeryl

Tool tốt nhất giúp Scala Aplication truy cập dữ liệu trong MongoDB NoSql là gì ?

ReactiveMongo là Scala Driver tốt nhất để tạo một Scala Aplication truy cập dữ liệu trong MongoDB NoSql. Nó hỗ trợ đầy đủ các hoạt động I/O non-blocking và  bất đồng bộ

Khách hàng phổ biến nào đang sử dụng play và Scala để phát triển ứng dụng ?

Có hàng nghìn khách hàng đang sử dụng Play và Scala trong sản phẩm. Danh sách bên dưới đây là những khách hàng phổ biến đang sử dụng Play và Scala:

  • LinkedIn
  • The Guardian
  • Ocado
  • LuchidChart
  • GOV.UK

Ngôn ngữ nào là tốt nhất để sử dụng với Play Framework: Scala hay Java ?

Play 2 đã được viết hoàn toàn trong Scala. Nếu chúng ta sử dụng Play bằng Java, chúng ta cần đối mặt với nhiều vấn đề bởi vì Java không hỗ trợ đầy đủ các tính năng của FP.

Scala là lựa chọn tốt nhất để sử dụng Play Framework phát triển các ứng dụng có tính mở rộng cao, hiệu năng tốt hơn với Concurrency/Parallelism và các ứng dụng độ trễ thấp bởi vì:

  • Play 2 được viết hoàn toàn trong Scala
  • Nó hỗ trợ đầy đủ các đặc điểm của FP
  • Nó là Expression Language ( ngôn ngữ biểu hiện) hơn Java ( tức là code ngắn hơn, dễ sử dụng hơn)
  • Nó hỗ trợ Akka Actor Model rất dễ dàng
  • Template xây dựng Play được phát triển trong Scala

Scala hỗ trợ các ứng dụng tính mở rộng cao và hiệu năng cao như thế nào ?

Scala hỗ trợ Multi-Paradigm Programming ( Cả OOP và FP) và sử dụng Actor Concurrency Model, chúng có thể phát triển các ứng dụng tính mở rộng cao và hiệu năng cao rất dễ dàng

Những Build tool nào được dùng để phát triển các ứng dụng Play / Scala cơ bản?

Có 3 build tool phổ biến nhất để phát triển các ứng dụng Play / Scala cơ bản:

  • SBT
  • Maven
  • Gradle

SBT là gì ? Build Tool nào là tốt nhất để phát triển các ứng dụng Play và Scala ?

SBT viết tắt của Scala Build Tool. Nó là một Build tool đơn giản để phát triển các ứng dụng Scala cơ bản

Hầu hết mọi người đều dùng SBT như là một build tool để phát triển các ứng dụng Play và Scala. Ví dụ, Scala Plugin trong IntelliJ IDEA sử dụng SBT như một Build tool mặc định

Có những Unit Test, Functional Testing hay nhưng BDD Framework nào được sử dụng cho Play và Scala ?

  • Spec2
  • ScalaTest
  • ScalaCheck
  • Mokito

Code-coverage tool nào hiện nay là tốt cho Play và Scala ?

SCoverage là Code-coverage tool cho Play và Scala

Scoverage là viết tắt của Scala Code-coverage tool. Nó có 3 plugins để hỗ trợ build tools:

  • SBT
  • Maven
  • Gradle

Tool nào là tốt nhất hiện nay để kiểm tra Scala Style cho Play và Scala ?

Giống  như Checkstyle cho các ứng dụng Java. Scalastyle là tool tốt nhất hiện nay cho Play và Scala.

Scalastyle theo dõi source code Scala của chúng ta và chỉ ra các vấn đề tiềm tàng trong source code. Nó có 3 plugin hỗ trợ các build tool:

  • SBT
  • Maven
  • Gradle

Nó có 2 plugin để hỗ trợ 2 IDEs:

  • IntelliJ IDEA
  • Eclipse IDE

Những IDE nào hỗ trợ Play và Scala và  như thế nào ?

Có 2 IDE phổ biến hỗ trợ Play và Scala:

  • IntelliJ IDEA
  • Eclipse

Chúng hỗ trợ bằng cách sử dụng Scala Plugin, ví dụ Esclipe có một Scala IDE để hỗ trợ các ứng dụng Play và Scala

IntelliJ IDEA có một plugin là “Scala Plugin for IntelliJ IDEA” để hỗ trợ “Scala, SBT và Play 2 Famework”

Mặc định Unit và Functional Testing Framework cho Play là gì ? Build tool mặc định cho play là gì ? Mặc định Template Engine cho Play là gì ? Webserver nào được tích hợp trong Play Framework ?

Mặc định Unit và Functional Testing của Play là Spec2. Nó rất dễ để test các ứng dụng Play/Scala sử dụng Specs2 Framework

Play  tích hợp các “Twirl” Template. Nó được phát triển trong Scala. Bằng việc sử dụng những template này, chúng ta có thể phát triển các ứng dụng Play/Scala một cách dễ dàng.

Mặc định webserver được tích hợp trong Play Framework là Netty Server

Tại sao Scala lại tốt hơn Java ? Nhưng ưu điểm của Scala so với Java 8 ? So sánh với Java thì những ưu điểm chính hoặc những lợi ích của Scala là gì ?

Bởi vì Scala hỗ trợ rất nhiều những đặc điểm sau đây, nên nó tốt hơn Java 8:

  • đầy đủ các đặc tính FP
  • Express Language hơn (ngắn hơn và dễ sử dụng hơn)
  • Pattern matching
  • Hỗ trợ tốt hơn cho Akka Actor Model
  • Tự dộng giả quyết vấn đề Diamond kề thừa với Trait
  • Asynchronous và  Non-blocking IO programming sử dụng Akka Framework
  • Fully Reactive Streaming API (xử lý dữ liệu bất đồng bộ)

Anonymous Function trong Scala là gì ? Literal function trong Scala là gì? hãy miêu tả những ưu điểm của chúng ?

Anonymous Function là một Function nhưng nó không có tên hàm. Nó cũng được biết như là một Funtion Literal

Những ưu điểm của Anonymous Function/Function Literal trong Scala:

  • Chúng ta có thể gán một Function Literal vào một biến
  • Chúng ta có thể truyền một Function Literal vào một funtion/method khác
  • Chúng ta có thể trả về một Function Literal như giá trị trả về hoặc kết quả của function/method khác

Ví dụ:

var inc = (x:int) => x + 1

Higher-Order Fucntion (HOF) là gì ?

Higher-Order Function(HOF) cùng là một function nhưng thực hiên một, hai hoặc cả hai điều sau:

  • Coi các function khác như các tham số đầu vào
  • Trả về các hàm như giá trị của nó ( return functions)

Sự khác nhau giữa case class và normal class là gì ?

Case class cũng là một class, tuy nhiên khi chúng ta so sánh nó với một normal class, thì nó mang đến nhiều ưu điểm và  lợi ích sau:

  • Mặc định, các tham số constructor của case class là ‘val’. Chúng ta không cần phải khai báo các tham số với ‘val’
  • Mặc định các tham số constructor trở thành các class fields
  • Những method sau sẽ được tạo tự động: toString, equals, hashCode, copy, apply và unapply
  • Nó sẽ tự động là companion objects
  • Không cần dùng “new” để tạo instace của case class
  • dễ sử dụng trong pattern matching

Tất cả những đặc điểm trên sẽ được thêm vào bởi Scala compiler trong thời gian compile. Nó là không thể với Normal class

Những ưu điểm của Play/Scala stack để phát triển một ứng dụng web ?

  • Open Source: Play Framework là một open Source miễn phí để phát triển các ứng dụng Web
  • Hiệu suất tốt hơn: Play framework tự động cập nhập những thay đổi giúp nâng cáo hiệu suất developer. Không cần build, deploy và kiểm tra những thay đổi. Chỉ cập nhập các thay đổi và refresh trang web để xem các cập nhâp mới
  • Stateless (cấu trúc server side, các request khác nhau được response một cách độc lập, không liên quan request trước) và dễ để tạo một REST API: Play là HTTP dựa trên stateless model để điều khiển các request web, nên nó giúp phát triển REST API (hoặc Restful web services) rất dễ dàng
  • Error handling dễ hơn: Nếu chúng ta phát triển các ứng dụng web bằng Play Framework, nó sẽ thông báo tất cả các lỗi trong trình duyệt ở định dạng rất hữu ích. Nó sẽ đưa ra các error message, vị trí file, line bao nhiêu xảy ra lỗi, làm nổi bật đoạn code để hiểu lỗi một cách dễ dàng
  • High performance và tính mở rộng tốt hơn với Reactive ( xử lỹ dữ liệu bất đồng bộ): Play framework được phát triển theo Reactive design pattern và nó được xây dựng đựa trên Netty Server để sử dụng các đặc tính Non-blocking IO. Do đó chúng ta có thể phát triển các ứng dụng với tính mở rộng và performance cao rất dễ dàng
  • Dễ dàng mở rộng: Play là frame work rất linh động và hỗ trợ phát triển các plugin rất dễ dàng giúp mở rộng các tính năng của nó.
  • Đồng thời và song song tốt hơn: Cả Scala và Play đều hỗ trợ Function Programming, nhờ đó nó dễ dàng phát triển các ứng dụng  chạy đồng thời hoặc song song bởi FP là immutability, Pure OOP, pattern matching, Actor Model
  • Dễ reuseability hơn, dễ test và modular hơn: Cả Scala và Play đều hỗ trợ FP, nên chúng ta có thể phát triển các ứng dụng dễ dàng: reuseability và modular hơn. Do khả năng Modular hơn nên nó cũng dễ test hơn

Cấu trúc OOP nào trong Java mà không có trong Scala ? Ngược lại cấu trúc OOP nào trong Scala không có trong Java ?

Cấu trúc Java OOP mà không được hỗ trợ trong Scala:

  • Không có khái niệm interface trong Scala
  • Không có khái niệm Enum trong Scala

Cấu trục Scala OOP mà không được hỗ trợ trong Java:

  • Scala trait
  • Giải quyết vấn đề Diamond kế thừa một cách tự động

call-by-name là gì ? Scala và Java hỗ trợ call-by-name không? So sánh sự khác nhau giữa tham số hàm call-by-name và call-by-value ?

call-by-name nghĩa là chỉ tính toán các tham số của method/function khi cần thiết hoặc khi truy cập chúng. Nếu chúng ta không cần sử dụng chúng thì nó sẽ không được tính

Scala hỗ trợ cả 2 function call-by-name và call-by-value. Nhưng Java thì chỉ hỗ trợ call-by-value mà không hỗ trợ call-by-name

Sự khách nhau giữa call-by-name và call-by-value là:

  • Trong call-by-name, Các tham số của function được tính chỉ khi nào cần thiết chứ không phải khi function được gọi
  • Trong call-by-value, Các tham số hàm được tính khi function được gọi
  • Trong call-by-value, Các tham số được tính toán trước khi gọi hàm và chúng chỉ tính toán một lần bất kể chúng ta sử dụng hàm này bao nhiêu lần
  • Trong call-by-name, các tham số được tính toán khi nào chúng ta truy cập đến nó và nó sẽ được tính toàn mỗi lần khi chúng ta sử dụng chúng trong funcion
  • Cấu trúc của Scala là khác

Call-by-value:

def myFunction(a: Int, b: Int) { }

Cả a và b là các tham số trong call-by-value của myFunction

Call-by-name:

def myFunction(a: Int, b: => Int) { }

a là tham số của call-by-value còn b là tham số call-by-name trong myFunction

MVC framework nào là phổ biến cho Scala language để phát triến các ứng dụng web ?

Sau đây là những MVC framework phổ biến nhất cho Scala để phát triển các ứng dụng web:

  • Play Framework
  • Scalatra Framework
  • Spary Framework
  • Lift Framework

Sự khác nhau cơ bản giữa cấu trúc maven của Java và Scala là gì ?

Hầu hết các project Java đều sử dụng Maven như Build tool. Tuy nhiên, hầu hết mọi người sử dụng SBT như một build tool trong Scala để phát triển các ứng dụng. Nhưng có một vài team họ vẫn sử dụng Maven như một build tool để phát triển các ứng dụng Scala.

Các cấu trúc thư mục Maven cho các dự án Java và Scala gần như là giống hệt nhau chỉ một thư mục có tên khác là tên thư mục Scala và thư mục Java:

Cấu trúc thư mục Maven của Java:

src > main > java
src > main > resources
src > test > java
src > test > resources

Cấu trúc thư mục Maven của Scala:

src > main > resources
src > main > scala
src > test > resources
src > test > scala

Extractor trong Scala là gì ? Sự khác nhau giữa constructor và extractor là gì? Các sử dụng Extractor trong Scala như thế nào ?

Không chỉ trong Java và Scala, trong hầu hết các Constructor ngôn ngữ OOP thường được sử dụng để tạo một object hoặc một instance của class sử dụng tham số của nó. Extrator là hơi ngược với Constructor

Trong Scala, Extractor dùng để phân tích hoặc tách rời một object thành các tham số của chính nó (từ object → các tham số của constructor)

Trong Scala, apply method là một constructor. Trong đó, Extractor sử dụng unapply method để phân tích một object thành các tham số ( một phần tham số). Trong Scala, Extractor chủ yếu dùng trong khái niệm pattern matching

“???” trong Scala là gì ?

“???” không phải là toán tử, method trong scala. Nó được dùng để đánh dấu một method đang trong quá trình phát triển, nghĩa rằng developer nên cung cấp một implementation cho nó

Method này được định nghĩa trong scala.PreDef class như sau:

def ??? : Nothing = throw new NotImplementedError

Nếu chúng ta chạy method này mà không implementation nó, thì nó sẽ đưa ra lỗi “NotImplementedError”  như bên dưới:

scala> def add(a:Int, b:Int) : Int = ???
add: (a: Int, b: Int)Int
scala> add(10,20)
scala.NotImplementedError: an implementation is missing

Sự khác nhau cơ bản giữa List và Stream trong Scala collection api là gì ? Làm thế nào chúng ta có thể chứng minh sự khác nhau đó ? Khi nào thì chúng ta dùng Stream ?

Trong Scala, cả List và Stream đều từ Collection API và hoạt động tương đối giống nhau. Cả 2 đều là immutable collection

Tuy nhiên, Có một sự khác nhau giữa List và Stream trong Scala Collection API. Các phần tử trong List được tính toán Eagerly (tính toàn khi tạo) và các phần tử Stream được tính toán Lazily ( tính toán khi nào cần) khi chúng ta truy cập chúng:

scala> var list1 = List(1,2,3,4)
list1: List[Int] = List(1, 2, 3, 4)

Chúng ta có thể quan sát thấy rằng tất cả các phần tử của List được tính toán tại thời điểm tạo một List Object. Tuy nhiên, nếu chúng ta làm tương tự với Stream, chúng ta không thể nhìn thấy tất cả phần tử. Chúng ta chỉ có thể nhìn thấy phần tử đầu tiên và các phần tử còn lại sẽ được tính toán lazily như bên dưới:

scala> var s1 = Stream(1,2,3,4)
s1: scala.collection.immutable.Stream[Int] = Stream(1, ?)

Khi chúng ta muốn Lazy collection tính toán các phần tử chỉ khi chúng ta truy cập chúng thì tốt nhất là sử dụng Stream.

Khác nhau giữa :: và #:: trong Scala là gì ? Khác nhau giữa ::: và #::: là gì ?

Trong Scala collection API:

  • :: và ::: là phương thức dùng trong List Class
  • #:: và #::: là phương thức dùng trong Stream Class
  • Trong List Class, :: method được đùng để thêm một phần tử xác định vào vị trí đầu tiên của List
scala> var list1 = List(1,2,3,4)
list1: List[Int] = List(1, 2, 3, 4)
scala> list1 = 0 :: list1
list1: List[Int] = List(0, 1, 2, 3, 4)
  • Trong List Class, ::: method dùng để nối các phần tử của List xác định với List trước nó
scala> var list1 = List(3,4,5)
list1: List[Int] = List(3, 4, 5)
scala> val list2 = List(1,2) ::: list1
list2: List[Int] = List(1, 2, 0, 1, 2, 3, 4)
  • Trong Stream, #:: method được dùng để thêm một phần tử xác định vào vị trí đầu tiên của Stream. Chỉ có phần tử mới thêm vào được tính toán và dựa theo tính toán các phần tử lazily của Stream
scala> var s1 = Stream(1,2,3,4)
s1: scala.collection.immutable.Stream[Int] = Stream(1, ?)
scala> s1 = 0 #:: s1
s1: scala.collection.immutable.Stream[Int] = Stream(0, ?)
  • Trong Stream Class, #::: method dùng để nối các phần tử của Stream xác định với Stream trước nó. Và nó vẫn theo tính toán Lazily của Stream, chỉ có phần tử mới đầu tiên là được tính toán.
scala> var s1 = Stream(1,2,3,4)
s1: scala.collection.immutable.Stream[Int] = Stream(1, ?)
scala> val s2 = Stream(-1,0) #::: s1
s2: scala.collection.immutable.Stream[Int] = Stream(-1, ?)
  • method :: hoạt động như một cons toán tử trong List Class, method #:: hoạt động như cons toán tử trong Stream Class. Ở đây ‘cons’ thay cho construct (dựng một List hoặc Stream mới)
  • method ::: hoạt động như toán tử nối chuối trong List Class và #::: hoạt động như toán tử nối chuỗi trong Stream Class

Nếu muốn trở thành một Fullstack Scala Developer, thì chúng ta nên học nhưng công nghệ nào ?

Nếu muốn trở thành một Fullstack Scala Developer,  chúng ta nên học những công nghệ sau:

  • Scala 2.11.7
  • Play 2.4.6 Framework
  • Akka 2.3 Framework
  • One Build Tool: SBT/Maven
  • One JS Framework: CoffeeScript/JavaScript
  • One IDE: IntelliJ IDEA 15/ Eclipse IDE 4.x
  • One TDD & BDD Framework: ScalaTest, Spec2, ScalaCheck,Mockito
  • Micro Services with Play and Scala
  • SCoverage
  • Scalastyle
  • Functional Programming Design Patterns
  • Machine Learning with Scala

You May Also Like

About the Author: Nguyen Dinh Thuc

Leave a Reply

Your email address will not be published.