Scala Question Answers
Scala Question Answers
What is Scala
Object-oriented and functional programming are both possible with Scala, and Scala is a
language that can run on the Java Virtual Machine (JVM). This makes Scala a great choice
for developing websites. It has grown to be one of the most beloved programming languages
of developers because of its vast array of libraries. Using Scala, Spark developers can write
better, more performant code through powerful features like macros, tuples, and
functions. Although Scala is difficult to master to some extent, the effort and money put into
learning the language are well worth it.
object ScalaProgram{
def main(args:Array[String])
{
println("Welcome to InterviewBit")
}
}
Output:
Welcome to InterviewBit
A functional approach can also be used to write code in Scala, as shown below:
def scalaProgram
{
println("Welcome to InterviewBit")
}
scalaProgram
Output:
Welcome to InterviewBit
Crack your next tech interview with confidence!
Take a free mock interview, get instant⚡️ feedback and recommendation💡
Take Free Mock Interview
Some languages bring unique benefits to a particular kind of project, making them the best
choice. The interoperability of Scala and its functional programming paradigm propelled
Scala's rapid growth. In order to address Java's critics, Scala is designed to be concise. The
following are some of Scala's unique features that set it apart from other programming
languages:
Type Inference: Scala doesn't require you to mention the data type or return type of
functions explicitly. It will infer the type of data by itself and the return type of
function depends on the type of last expression present in the function.
Immutability: The default behavior of Scala variables is immutability, which means
that they can't be altered. Thus, concurrency control can be managed easier. In
addition, mutable variables can also be used.
Lazy Evaluation: In lazy evaluation or call-by-need, expressions are not evaluated
until their first use, or until their demand. Computations are lazy in Scala by default.
To declare a lazy variable, use the lazy keyword.
Case classes and Pattern matching: Case classes in Scala are immutable classes that
can be decomposed via pattern matching. Case classes include public and immutable
parameters by default. These classes support pattern matching, which makes it easier
to write logical code.
String Interpolation: Scala 2.10.0 introduces String Interpolation, a new method for
generating strings from your data. Users can embed variable references directly in
processed string literals with string interpolation. String interpolation in Scala can be
achieved using the s, f, and raw interpolation methods.
Singleton object: Neither static variables nor static methods exist in Scala, so its
singleton object (a class with only one object in the source code) is used as an entry
point to your program execution. a class. When declaring a singleton object, the
keyword "object" is used instead of the class keyword.
Additionally, it offers:
Scala's compatibility and interoperability with Java allow developers to keep their
Java libraries and use the JVM.
By supporting multi-paradigm programming, Scala enables more elegant, compact,
and type-safe programming.
Scala integrates seamlessly with big data ecosystems, which are largely based on
Java. It works flawlessly with Java libraries, IDEs (like Eclipse and IntelliJ), and
frameworks (such as Spring and Hibernate).
It is easier to learn because it is more concise, readable, and error-free, especially for
people with a background in Java or a similar language.
Scala offers complex features such as macros, tuples, etc., making coding easier and
more performance-enhancing.
Scala offers a number of advances, including functions, macros, and tuples.
By using an expressive typing system, it ensures security and consistency in statistical
abstraction.
With Scala, you can build fault-tolerant, highly concurrent systems.
Apache Spark Ecosystem has good support for Scala, it's perfect for data analytics.
Scala provides support for concurrency, allowing parallel processing.
Download PDF
Scala case classes are like regular classes except for the fact that they are good for modeling
immutable data and serve as useful in pattern matching. Case classes include public and
immutable parameters by default. These classes support pattern matching, which makes it
easier to write logical code. The following are some of the characteristics of a Scala case
class:
Syntax:
Example:
Output:
Streams, a Scala feature, are essentially lazy lists in which elements are only evaluated as
needed. In this way, Scala allows for faster processing. Streams are similar to lists in terms of
performance.
Syntax:
Scala lets you construct Lists by using the :: operator, while you can build Streams by using
the #:: operator with Stream.empty at the end of the expression. A stream's head in the above
syntax is 1, while its tail is 2 and 3.
Example:
object MainObject
{
def main(args:Array[String]){
val stream = 20 #:: 30 #:: 45 #:: Stream.empty
println(stream)
}
}
Output:
Stream(20, ?)
Observe the output and you will see a question mark instead of the second element. Scala
only evaluates lists if they are needed.
A tuple is a heterogeneous data structure, consisting of a fixed number of elements, each with
a different data type. A tuple, however, can contain objects of different types, as well as being
immutable. They are particularly useful when returning multiple values from methods.
A tuple's type is determined by how many elements it contains as well as the type of those
elements. Scala uses Tuple2, Tuple3, etc., up to Tuple22, to represent types of tuples. Scala
currently limits the number of elements in a tuple to 22, and if the number of elements in the
tuple exceeds 22, an error will be generated.
The inferred type of ingredient is (Integer, String), which is shorthand for Tuple2[Int,
String].
Note: Tuples can be used to overcome this limit. It is possible for a tuple to contain other
tuples.
It is well known that variables are merely reserved memory locations for storing values. In
Scala, variables are mainly of two types:
Mutable Variables: These are variables whose value is capable of changing and the
var keyword is used to declare these variables.
Syntax:
Example:
Immutable Variables: These are variables whose value is not capable of changing
and the val keyword is used to declare these variables.
Syntax:
Example:
The Scala Option[T] is referred to as a carrier of one element or none for a specified type. As
the name suggests, this container holds either a Some or a None object, which represents a
missing value. It holds Some[T] if a value is stored, otherwise none. In simple words, Scala
options are wrappers for missing values.
Example:
object option
{
def main(args: Array[String])
{
val employee: Map("InterviewBit" -> "Aarav", "Scaler" -> "Ankesh")
val a= employee.get("InterviewBit")
val b= employee.get("Informatica")
println(a);
println(b);
}
}
Output:
Some(Aarav)
None
Here, the key of the value InterviewBit is found, therefore, Some is returned, however, the
key of the value Informatica is not found, therefore, None is returned.
Literals, or constants, are any constant value that can be assigned to a variable. A literal is a
set of symbols used to describe a constant value in the code. They are classified into the
following types:
Integer literals
Floating point literals
Boolean literals
Symbol literals
Character literals
String literals
Multi-Line strings
A helper class, named App, is provided by Scala that provides the main method and its
members together. App trait allows Objects to be turned into executable programs quickly.
The App class in Scala can be extended instead of writing your own main method. This way
you can produce concise and scalable applications.
Example:
object InterviewBit extends App
{
println("Hello Scala")
}
In Scala, an extractor defines a method unapply(), as well as an optional method, apply(). For
mapping and unmapping data between form and model data, both apply and unapply methods
are used.
Apply() method: Assembling an object from its components is done with this
method. For example, by using the two components firstName and lastName, we can
create the Employee object with the apply method.
Unapply() method: This method follows the reverse order of apply order and
decomposes an object into components. For example, you can break or decompose
that employee object down into its components i.e., firstName and lastName.
A set is a collection of unique items that cannot be repeated. In Scala, non-negative integer
sets are called Bitsets, and they are represented as variable-size arrays of bits packed into 64-
bit words. The largest number in a bitset represents its memory footprint.
Syntax:
Example:
import scala.collection.immutable.BitSet
object InterviewBit
{
def main(args:Array[String])
{
println("Initialize a BitSet")
val numbers: BitSet = BitSet(5, 6, 7, 8)
println(s"Elements of BitSet are = $bitSet")
println(s"Element 6 = ${bitSet(6)}")
println(s"Element 3 = ${bitSet(3)}")
println(s"Element 7 = ${bitSet(7)}")
}
Output:
Initialize a BitSet
Elements of BitSet are = BitSet(5,6,7,8)
Element 6 = true
Element 3 = false
Element 7 = true
Scala provides us with a function called ofDim that declares multidimensional arrays using
the matrix format. Array.ofDim can be used to declare multidimensional arrays. There's no
limit to the number of dimensional arrays you can create.
Syntax:
or
Example:
object MultiArrayExample
{
def main(args: Array[String])
{ val multiArr= Array.ofDim[Int](2, 2)
multiArr(0)(0) = 5
multiArr(0)(1) = 10
multiArr(1)(0) = 15
multiArr(1)(1) = 20
for(i <- 0 to 1; j <- 0 to 1)
{
println("Element "+ i + j + " = " + multiArr(i)(j))
}
}
}
Output:
Element 00 = 5
Element 01 = 10
Element 10 = 15
Element 11 = 20
According to their declarations, Scala variables are categorized into three scopes as given
below:
Fields: Variables of this type can be accessed from any method within a Web object,
or from outside the object, depending on access modifiers used. Depending on the var
and val keywords, they can be mutable or immutable.
Method Parameters: When a method is invoked, these variables are used to pass
values to the method. All method parameters use the val keyword and are strictly
immutable. Normally, these are accessed within a method, but a Reference allows
accessing them outside the method.
Local Variables: These are the variables (mutable or immutable) declared inside a
method and accessible only within that method. By returning them from the method,
they can be accessed outside of the method.
Map() and its close cousin flatMap() are often used when we deal with data structures in
Scala and both are higher-order functions.
Higher-order functions are functions in Scala that either take or return another function as an
argument or parameter. Another way to say it is a function that works with a function. You
can create higher-order functions, lambda functions, or anonymous functions using a higher-
order function.
Example: In this case, the apply function contains another function a that is applied to b.
object InterviewBit
{
def main(args: Array[String])
{
println(apply(format, 45))
}
def apply(a: Double => String, b: Double) = a(b)
def format[S](x: S) = "{" + x.toString() + "}"
}
Output:
{45.0}
Scala closures are functions whose return value is dependent on one or more free variables
declared outside the closure function. Neither of these free variables is defined in the function
nor is it used as a parameter, nor is it bound to a function with valid values. Based on the
values of the most recent free variables, the closing function is evaluated.
Syntax:
var x = 20
def function_name(y:Int)
{
println(x+y)
}
Example:
object InterviewBit
{
def main(args: Array[String])
{
println( "Sum(2) value = " + sum(2))
println( "Sum(3) value = " + sum(3))
println( "Sum(4) value = " + sum(4))
}
var x = 20
val sum = (y:Int) => y + x
}
Output:
Sum(2) value = 22
Sum(3) value = 23
Sum(4) value = 24
In the above program, the sum is a closure function. var x = 20 is an impure closure. As can
be seen, x is the same, and y is different.
The concept of traits is similar to an interface in Java, but they are even more powerful since
they let you implement members. It is composed of both abstract and non-abstract methods,
and it features a wide range of fields as its members. Traits can either contain all abstract
methods or a mixture of abstract and non-abstract methods. In computing, a trait is defined as
a unit that encapsulates the method and its variables or fields. Furthermore, Scala allows
partial implementation of traits, but no constructor parameters may be included in traits. To
create traits, use the trait keyword.
Syntax:
trait Trait_Name
{
// Fields...
// Methods...
}
Example:
trait MyCompany
{
def company
def position
}
class MyClass extends MyCompany
{
def company()
{
println("Company: InterviewBit")
}
def position()
{
println("Position: SoftwareDeveloper")
}
def employee() //Implementation of class method
{
println("Employee: Aarav")
}
}
object Main
{
def main(args: Array[String])
{
val obj = new MyClass();
obj.company();
obj.position();
Obj.employee();
}
}
Output:
Company: InterviewBit
Position: SoftwareDeveloper
Employee: Aarav
Scala and Java are two of the world's most popular programming languages. Comparing
Scala to Java, Scala is still a relatively new language. So, let us compare some of the
differences between both of them.
Java Scala
It was originally designed to be an Originally intended to be both an object-oriented
object-oriented language, but it began and functional language, Scala supports
supporting functional programming concurrency and immutability, as well as many
features in recent years. other features of functional programming.
It takes a short time to convert source It takes a long time to compile the source code into
code to byte code. byte code.
Scala is designed to be concise. One line of Scala
In Java, even the most mundane and code can easily replace twenty lines of “simple”
simple tasks require long-form code. Java code, even though it is a slightly more
complex language.
Lazy evaluation and operator Lazy evaluation and operator overloading are
overloading are not supported. supported.
Due to Java's backward compatibility,
The language does not provide backward
code written in the new version will run
compatibility.
without error in an older version.
Grails, spring, and many other
Scala supports frameworks such as Play and Lift.
frameworks are supported.
In Scala, any method or function can be treated as a
Objects are treated as functions in Java.
variable.
Java variables are mutable by default. Scala variables are immutable by default.
When compared to Scala, Java is easier Unlike Java, Scala includes nested coding, making
to read. it less readable.
Static keywords are used in Java. There are no static keywords in Scala.
Multiple inheritances are not supported The language supports multiple inheritances
by classes, but by interfaces. through classes, but not through abstract classes.
Despite being a simple topic, the monad belongs in the advanced section of the Scala
language. It is important to understand that a monad is not a class or a trait; it is a concept.
Thus, a monad represents an object that wraps another object in Scala. Each step in Monads
has an output that serves as input for subsequent steps. Although Scala's maximum
collections are Monads, yet not all Monads are collections. Some Monads, for example, can
be used as containers like Options. To put it succinctly, the data types that implement map
and flatMap() (such as options, lists) in Scala are called monads.
Standard functions generally include a name, a list of parameters, a return type, and a body.
An anonymous function is one for which a name is not given. In Scala, anonymous functions
are defined by a lightweight syntax. In the source, anonymous functions are referred to as
function literals, and at run time, these function literals become objects called function
values. We can use it to create inline functions.
Syntax:
(z:Int, y:Int)=> z*y
Or
(_:Int)*(_Int)
Scala takes the opposite approach; with functions, the arguments are val - i.e., immutable by
default. This eliminates the need to type extra arguments. Scala is known for its use of
immutability in design and in many cases, this is the default behavior. Immutability's benefits
include addressing equality issues and concurrency.
Identification is done with the help of identifiers in programming languages. The identifiers
in Scala are case-sensitive and can be class, method, variable, or object name.
Example:
class InterviewBit
{
var x: Int = 45
}
object Scaler
{
def main(args: Array[String])
{
var y = new InterviewBit();
}
}
As you can see from the above example, we have six identifiers:
Types of Identifiers
In Scala, currying refers to the technique of transforming a function. There are multiple
arguments passed into this function, which then forms a chain of functions that take one
argument each. This type of function is widely used in multiple functional languages.
Syntax:
Example:
object Currying
{
def add(a: Int, b: Int) = a + b;
def main(args: Array[String])
{
println(add(10, 5));
}
}
Output:
15
In this case, we've defined an add function that takes two arguments (a and b), and it gives us
the result of adding a and b, by calling it in the main function.
Scala supports tail recursion, which sets it apart from other languages. Recursion involves
breaking a problem down into smaller sub-problems and calling itself to resolve each of
them. Simply put, recursion can be thought of as a function calling itself. Tail recursion refers
to executing the last statement recursively. As a result, these functions are more performant
since they utilize tail call optimization. They do not add another stack frame to memory, but
rather keep calling functions. If you are experiencing a stack overflow with your recursive
functions, a tail-recursive function is your remedy. In addition, tail recursion makes your
code faster and memory-constant.
Syntax:
Example:
import scala.annotation.tailrec
object InterviewBit
{
def SCALER(a: Int, b: Int): Int =
{
@tailrec def scaler(x:Int, y:Int): Int=
{
if (y == 0) x
else scaler(y, x % y)
}
scaler(a, b)
}
def main(args:Array[String])
{
println(SCALER(11, 7))
}
}
Output:
The constructors are responsible for initializing the state of the object. In the same way as
methods, constructors also consist of statements/instructions that are executed when an object
is created. Constructors are used in Scala to create instances of classes. Scala has two types of
constructors:
Primary Constructor: Scala programs often contain only one constructor, known as
the primary constructor. It is not necessary to create a constructor explicitly since the
primary constructor and the class shares the same body.
Syntax:
class class_name(Parameter_list)
{
// Statements...
}
Syntax:
def this(......)
27. Explain the difference between the terms Nil, Null, None and Nothing.
Null, null, Nil, Nothing, None, and Unit are all used to represent empty values in Scala.
Null refers to the absence of data, and its type is Null with a capital N.
Null is considered to be a list that contains zero items. Essentially, it indicates the end
of the list.
Nothing is also a trait without instances.
None represents a sensible return value.
Unit is the return type for functions that return no value.
Scala uses the yield keyword in conjunction with the for loop. Following the completion of
loop iterations, the yield keyword returns the result. For loops internally store the iterated
result in a buffer, and upon finishing all iterations, it yields the final result from that buffer.
Maps, FlatMaps, Filters, and Nomads are all supported by Yield.
Syntax:
The implicit parameter, as opposed to the regular parameter, can be passed silently to a
method without going through the regular parameter list. The implicit keyword indicates
these parameters and any parameters following the implicit keyword are implicit. Essentially,
when we don't pass anything to methods or functions, the compiler will look for an implicit
value and use that as a parameter. Whenever implicit keywords appear in a function's
parameter scope, this marks all parameters as implicit. Each method can simply have a single
implicit keyword.
Syntax:
Example:
object InterviewBit
{
def main(args: Array[String])
{
val value = 20
implicit val addition = 5
def add(implicit to: Int) = value + to
val result = add
println(result)
}
}
Output:
25
31. Explain the different access modifiers that are available in Scala.
Using access modifiers, you can limit the scope to particular regions of code. Scala has three
access modifiers: public, private, and protected. If you wish to use an access modifier, you
must include its keywords private/protected/public in the definition of a member of the
package, class, or object. By default, the access modifier is public if neither of these
keywords is used.
Private: A private member can only be accessed within a class that defines it or
through one of its objects.
Protected: Protected members are accessible from sub-classes of the class in which
they are defined. This also applies to methods and variables.
Public member: By default, the access modifier is public. In the absence of the
private or protected keyword, the compiler will treat the members as public, and it is
not necessary to specify "public".
Functions are first-class values in Scala and can be created using the def keyword. When
defining a function, the return type of the parameter must be specified. A function's return
type is optional. The default return type of a function is Unit if it is not specified. Function
declarations in Scala have the following form: −
When you don't use the equals sign and the method body, methods are implicitly declared
abstract.
Example:
object InterviewBit
{
def main(args: Array[String])
{
println("Sum:" + addFunction(10,5));
}
def addFunction(x:Int, y:Int) : Int =
{
var sum:Int = 0
sum = x + y
return sum
}
}
Output:
Sum: 15
The Scala team has not decided to use a "static" keyword as part of their design. This
decision was taken primarily to make Scala a Pure Object-Oriented Language. Using the
"static" keyword, we can even access class members without creating or using an object. This
is totally against the OOP principles. For instance, Java does not qualify as a pure OO
language since it supports the "static" keyword.
There are various types of inheritance supported by Scala, including single, multilevel,
multiple, and hybrid. Single, multilevel, and hierarchy can all be applied to your class. Due to
the fact that Scala doesn't allow multiple inheritances, Scala's trait comes into play to deal
with the problem. Traits are defined in a similar manner to classes, except that they use the
keyword trait rather than the class as shown below:
trait TraitName
{
//Methods
//Fields
}
Scala does not support the expression "j++" and should either be replaced with “j+=1” or
“j=j+1”.
A Scala list is a collection of data stored as a linked list. In Scala, a list is immutable,
meaning it cannot be changed. To remedy this, Scala offers List-Buffer. There are multiple
ways to update a list and add new elements such as using the ":+" method: It adds new
elements at the end of a list.
Syntax:
list_Name :+ element_Name
Example:
object Colours
{
def main(args: Array[String])
{
val myList = List ("Red" , "White")
println("List’s Content : " + myList)
println(" Appending/adding elements at the end of list!")
val updatedList = myList :+ "Blue"
println("Updated List’s Content: " + updatedList)
}
}
Output:
Example:
object InterviewBit
{ def main(args: Array[String])
{
println("Hello Scaler!!!")
}
}
Hello Scaler!!!