Kotlin is a general-purpose, high-level, open-source programming language that supports both object-oriented and functional programming styles. Its first stable release was in 2016. Though it mainly targets Java virtual machines, its code can also be compiled into JavaScript or native code. In 2019, it was announced as the preferred language for Android developers by Google. It’s a cross-platform and statically typed language with more concise and expressive syntax compared to Java. It’s also used for server-side development, web development (with frameworks like Ktor), desktop applications, and more.
In this blog, we’ll discuss the ten most commonly asked interview questions in Kotlin.
This blog will be helpful to anyone who wants to learn Kotlin and start their career as Android developer, Java developer, cross-platform developer, web developer, and anyone interested in modern, concise, and safe programming language. With the passage of time Kotlin’s popularity is growing especially in the Android ecosystem which makes it a valuable skill for developers looking to stay relevant in the industry.
A data class is a special type of class that is primarily used to hold data. They are concise and facilitate the creation of equals()
, hashCode()
, toString()
, and copy()
, based on the properties defined within the class. A sample data class is provided below for reference.
fun main() {data class Student(val name: String, val age: Int)val obj = Student("John", 20)println(obj.name)}
Line 2: The keyword data
is used to create a data class. The name of the data class is Student
, while name
and age
are the properties of the class. It should be noted that the primary constructor needs to have at least one parameter and the data class cannot be abstract, open, sealed, or inner.
Line 3: We create the object of the Student
class.
Line 4: We print the name of the student object we created.
Kotlin has built-in object types of Number
(to store integer or floating point values), Character
(to store a unicode character), String
(to store a sequence of characters), Boolean
(to store true of false value), and Array
(to store a fixed-size collection of elements of the same type). Let’s discuss these types in more detail below.
This data type can be used to store integer values or floating point values. It is further divided into the following types.
Signed integers: These include Byte
(8-bit), Short
(16-bit), Int
(32-bit), and Long
(64-bit).
Floating-point numbers: These include Float
(32-bit) and Double
(64-bit).
Let’s have a look at a working example of the above-mentioned data types.
fun main() {val b: Byte = 127 // Range: -128 to 127val s: Short = 32767 // Range: -32768 to 32767val a: Int = 10000 //Range: -2,147,483,648 to 2,147,483,647val l: Long = 1000000004 //Range: -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807val f: Float = 100.00f //Range: Approximately ±1.4 x 10^-45 to ±3.4 x 10^38val d: Double = 100.00 //Range: Approximately ±4.9 x 10^-324 to ±1.8 x 10^308println("Byte Value is " + b)println("Short Value is " + s)println("Int Value is " + a)println("Long Value is " + l )println("Float Value is " + f)println("Double Value is " + d)}
Note: We have assigned the maximum values to
Byte
andShort
data types. Try increasing the value by 1 to see if you get an error.
Lines 2–7: We declare variables of type Byte
, Short
, Int
, Long
, Float
, and Double
respectively.
Lines 10–15: We print the values of the variables.
It can store a single 16-bit Unicode character. Let’s have a look at a working example of the Char
data type below.
fun main() {val letter: Charletter = 'A'println("$letter")}
Line 2: We declare a character variable named letter
.
Line 3: We assign the value A
to our variable letter
.
Line 4: We print the character.
It can store a sequence of characters. Note that the strings in Kotlin are immutable, meaning their values cannot be changed after they are created. There are two kinds of strings available in Kotlin:
Escaped string: It is declared within double quotes (" "
) and may contain any escape characters. They are used for regular string literals where we need to escape special characters or include expressions using string interpolation.
Raw string: It is declared within triple quotes (""" """
) and may contain multiple lines of text without any escape characters. They are used when we want to have multiline strings without the need for escape characters. For long strings that span multiple lines, such as multi-line comments or large blocks of text.
Let’s have a look at a working example of both strings.
fun main() {val myString1 : String = "I work in \n Educative\n"var myString2 :String = """I love workingin Educative as it provides methe opportunites for professional growth.""";print(myString1)print(myString2)}
Note: Try adding an escape sequence of
\n
in the raw string and see the result.
Line 2: We declare an escaped string with an escaped character `\n`.
Line 3: We declare a raw string with multi-line text.
Lines 7–8: We print both the strings.
It can store either true or false. Let’s have a look at a working example of the Boolean
data type below. The most common use of boolean types is in control structures like if
, when
, and loops (while, do-while, for
) to make decisions based on whether a condition is true or false. Additionally, functions can return boolean values to indicate success, failure, or the result of a condition.
fun main() {val myBool: Boolean = trueprintln("Value of myBool is "+ myBool)}
Line 2: We declare a boolean variable named myBool
.
Line 3: We print the value of the boolean variable.
It is a fixed-size collection of elements of the same type. In Kotlin they are mutable, and their size cannot be changed after creation. Let’s have a look at a working example of the Array
data type below. The array is used when the number of elements is known and won’t change frequently. We also use them to pass data between different parts of a program or represent grids, tables, or any structure with rows and columns.
fun main() {val myIntArray: IntArray = intArrayOf(10,20,30,40,50)val myStringArray = arrayOf("this", "is", "so much", "fun")println("Value at second index of integer array is " + myIntArray[1])println("Value at third index of string array is " + myStringArray[2])}
Line 2: We declare an integer array named myIntArray
with five elements.
Line 3: We declare a string array named myStringArray
with four elements.
Lines 4–5: We print the elements at the first index for the integer array and the second index for the string array.
In Kotlin, var
and val
are used to declare variables, but they have different characteristics:
Using var
we can declare a mutable variable whose value can be changed after it is initialized. We can reassign values to variables declared with var
. It is useful for variables whose values are determined based on runtime conditions.
Using val
we can declare an immutable variable, meaning its value cannot be changed after it is initialized. Once initialized, we cannot reassign values to variables declared with it. Kindly note that because it can be initialized with the value of a variable, an immutable variable is not a constant. We should use it for constants, such as mathematical constants (PI, E) or configuration values. Its usage also helps to prevent accidental reassignments, making code safer and easier to reason about. It also improves thread safety in concurrent programming because once initialized, val
cannot change, reducing potential race conditions.
The difference between val
and const
is that val
is evaluated at runtime, whereas, const
values are fixed at compile time. So using val
is suitable for values that are not compile-time constants but whose value should not change once assigned.
Let’s have a look at a working example of both variable types.
fun main() {var a = 10a = 20val b = 5//b = 10println("Value of mutable variable is " + a)println("Value of immutable variable is " + b)}
Note: Try uncommenting the code on line 5 and see what will be the output.
Line 2: We declare a mutable variable named a
and assign it a value of 10.
Line 3: We reassign the value to our mutable variable.
Line 4: We declare an immutable variable named b
and assign it a value of 5.
Lines 7–8: We print the values of both the variables.
Creating a singleton class in Kotlin is very simple. We just need to use the object
keyword and we are done. The object
class can have functions, properties, and the init
method. However, we cannot have a constructor method in a singleton class. We can use the init
method if some initialization is required. The object gets instantiated when it is used for the first time. It provides us with thread-safe lazy initialization without having to rely on a locking algorithm.
object Singleton{init {println("Initialization of Singleton class.")}var myVariable = "Test variable in Singleton"fun printVariable(){println(myVariable)}}fun main() {Singleton.printVariable()Singleton.myVariable = "New Name"}
Line 1: We use the object
keyword to create a class named Singleton
.
Lines 2–4: We print the message “Initialization of Singleton class.”
in its initialization method.
Line 5: We declare a variable myVariable
.
Lines 6–8: We add a method named printVariable
that just prints the variable myVariable
.
Line 11: We directly access the singleton class and call its printVariable
method.
Line 12: We assign a new value to the variable myVariable
.
In Kotlin, both fold
and reduce
are
It is used to accumulate a single value by applying a given binary operation to each element and accumulating the result with an initial value. Therefore, we must provide an initial value for the accumulation.
fun main() {val numbers = listOf(1, 2, 3, 4, 5)val sum = numbers.fold(100) { acc, num -> acc + num }println("Sum of collection is " + sum)}
In this example, fold starts with an initial value of 1 and adds each element of the numbers list to the accumulator.
It is quite similar to fold, but it does not require an initial value. It starts with the first element of the collection as the initial accumulator.
fun main() {val numbers = listOf(100, 1, 2, 3, 4)val sum = numbers.reduce { acc, num -> acc + num }println("Sum of collection is " + sum)}
In this example, reduce starts with the first element 1 as the initial accumulator and adds each subsequent element to it.
In Kotlin, we have a prominent feature of null safety that eliminates the NullPointerExceptions
(NPEs) common in many other programming languages. Basically, every variable has a default non-null type, meaning it cannot hold a null
value unless explicitly specified. If a variable can hold a null
value, its type must be declared explicitly by appending ?
to the type. Let’s have a look at the usage of ?
below.
Variables of these types cannot hold null
values. The type is declared without the ?
symbol.
fun main() {var name: String = "John"//name = nullprintln("Testing null safety. Name is " + name)}
Note: Try uncommenting line 4 and see what error you get.
Line 3: We declare a non-nullable variable named name
of type string.
Line 5: We print a message along with the value of the name
variable.
Variables of these types can hold null
values. The type is declared with the ?
symbol.
fun main() {var name: String? = "John"name = nullprintln("Testing null safety. Name is " + name)}
Line 3: We declare a nullable variable named name
of type string.
Line 5: We print a message along with the value of the name
variable.
In Kotlin, coroutines are a powerful feature that allows for asynchronous programming, enabling us to write non-blocking, asynchronous code in a sequential manner. Coroutines provide a way to perform long-running tasks efficiently and conveniently without blocking the main thread, similar to other async/await patterns found in other languages.
Let’s have a look at an example below.
import kotlinx.coroutines.*fun main() {println("Main thread starts")GlobalScope.launch {delay(1000)println("Coroutine: Task completed")}println("Main thread continues")Thread.sleep(2000)println("Main thread ends")}
Line 1: We import the required package for creating coroutines.
Line 6: We use the launch
method to launch a coroutine. Inside the coroutine.
Line 7: We use delay(1000)
method to suspend the coroutine for 1 second. Note that the main thread will continue to execute immediately after launching the coroutine.
Line 12: We use Thread.sleep(2000)
to ensure the coroutine has enough time to complete before the program exits.
In Kotlin, we do not have the “static” keyword, so, if we want to achieve the functionality of static member functions, we use the companion objects. It is a special type of object that is tied to the class it belongs to rather than to instances of that class. It allows us to define methods and properties that are similar to static members in other programming languages. Let’s have a look at a sample companion object below.
class Test {companion object Test {var companionVariable: Int = 0fun companionMethod() = println("Companion method called.")}}fun main() {println(Test.companionVariable)Test.companionMethod()}
Line 2: We declare a companion object by using the companion
keyword.
Line 3: We declare a variable named companionVariable
inside the companion object.
Line 4: We create a method named companionMethod
inside the companion object.
In Kotlin, a sealed class is a special type of class that can have a fixed set of subclasses, defined within the sealed class itself. This means that all subclasses must be defined inside the sealed class declaration, and no other subclasses can be created outside of it. It is used when all the possible subclasses are known upfront. They are useful for representing restricted class hierarchies. It is to be noted that sealed classes can have constructors, but the constructors cannot be declared as private. They can be protected, internal, or public.
sealed class Shape {class Circle(val radius: Double) : Shape()class Rectangle(val width: Double, val height: Double) : Shape()class Square(val length: Double) : Shape()}fun calculateArea(shape: Shape): Double {return when (shape) {is Shape.Circle -> Math.PI * shape.radius * shape.radiusis Shape.Rectangle -> shape.width * shape.heightis Shape.Square -> shape.length * shape.length}}fun main() {val circle = Shape.Circle(10.0)val rectangle = Shape.Rectangle(5.0, 10.0)val square = Shape.Square(5.0)println("Circle area is [${calculateArea(circle)}]")println("Rectangle area is [${calculateArea(rectangle)}]")println("Square area is [${calculateArea(square)}]")}
Line 1: We create a sealed class named Shape
.
Lines 2–4: It has three subclasses named Circle
, Rectangle
, and Square
, respectively.
Line 7: We define a function that will compute the area of all three shapes using the when
operator.
Lines 16–18: We create objects of the shapes circle, rectangle, and square.
Lines 20–22: We print the area of these shapes.
Object expressions provide a way to create anonymous objects, similar to anonymous inner classes in Java. It allows us to create an instance of a class or interface without explicitly declaring a named subclass. It’s particularly useful for creating objects that are only needed once and don’t need to be reused elsewhere. There are some limitations to it though. We cannot have constructors in object expressions and they cannot be reused elsewhere in the code.
interface Shape {fun draw(): String}fun drawShapes(shapes: List<Shape>) {shapes.forEach {println(it.draw())}}fun main() {val shapes = listOf(object : Shape {override fun draw(): String {return "It is a Circle."}},object : Shape {override fun draw(): String {return "It is a Square."}})drawShapes(shapes)}
Line 1: We create an interface Shape
with a draw()
function.
Line 5: We create a drawShapes
method that will iterate over the list of Shape
objects and call its draw method.
Lines 13–18, we create two anonymous objects using object expressions, each implementing the Shape
interface with its own draw()
implementation.
Line 25: We call the drawShapes
method passing the two anonymous objects.
This wraps up our blog about the top ten interview questions in Kotlin. We started by first stating the question and then explaining the answer in detail. We then provided a code-based example for better comprehension. It is to be noted that there are many other concepts in Kotlin that will be covered in the next series of this blog.
To deepen your understanding of the Kotlin programming languages, we strongly recommend you look through the following selection of specialized courses on the Educative platform:
Kotlin Crash Course for Programmers
Kotlin is quickly joining the ranks of the most popular programming languages. Now that Google supports Kotlin for Android app development as the primary choice over Java, we’ll only see more developers making the switch. So if you’re looking to get started with Android app development, then you’ve come to the right place. This course will be your guide on getting started with Kotlin. We’ll go over all the language basics including variable declarations, data types and the type system to conditions, loops, and functions. After this course, you’ll be able to write simple Kotlin scripts and applications. With this solid understanding of the language basics, you’ll be able to more easily follow more advanced material covering functional and object-oriented programming.
The Ultimate Guide to Kotlin Programming
Kotlin has been growing in popularity among developers for some time. It was given even more recognition when Google announced in 2019 that Kotlin was now their preferred language for Android development. In this comprehensive course, you’ll start by learning the fundamentals, such as: how Java and Kotlin differ, how to work with functions, and how to utilize collections, something you’ll work with extensively in Kotlin. In the latter half of the course, you’ll be introduced to more advanced concepts like lambdas, fluency in Kotlin, and asynchronous programming. In the last section of the course, you’ll take what you’ve learned and build out an Android application that talks to a backend service. By the time you’re done with this course, you’ll have a thorough mastery of this modern JVM language. This course is based on the PragProg book, Programming Kotlin, written by the extraordinary, experienced programming-language enthusiast: Venkat Subramaniam.
Mastering Kotlin Coroutines
Ever since Google announced Kotlin as the language of choice for Android development, it's become increasingly popular. Current trends suggest that coroutines are the direction in which our industry is clearly headed. This course is for anyone interested in getting experience with Kotlin coroutines. In this course, you’ll take a hands-on, task-based approach to using coroutines in Android applications. You'll work with the most common tools that Android back-end developers use every day for Kotlin. The course explains what Kotlin coroutines are and how they work. Then, it introduces essential concepts from the kotlinx.coroutines library, such as builders, context, and scope. Kotlin best practices, exception handling, and testing of coroutines are also covered. Finally, the last part of the course will focus on hot and cold data sources, channels, and flows. By the end of this course, you’ll have tangible experience using Kotlin coroutines and will be ready to build even more coroutines of your choice.
Don’t pass up this chance to increase your knowledge and expertise in Kotlin. Take the first step toward becoming an expert developer in Kotlin by immediately enrolling in Educative courses!
Free Resources