Explore topic-wise InterviewSolutions in .

This section includes InterviewSolutions, each offering curated multiple-choice questions to sharpen your knowledge and support exam preparation. Choose a topic below to get started.

1.

What are some of the disadvantages of Kotlin?

Answer»

Following are some of the disadvantages of Kotlin:

  • In Kotlin, there are a few keywords that have non-obvious meanings: internal, crossinline, expect, reified, sealed, inner, open. Java has none of these.
  • Checked exceptions are likewise absent in Kotlin. Although checked exceptions have become less prominent, many programmers believe them to be an effective technique to ensure that their code is stable.
  • A lot of what happens in Kotlin is hidden. You can ALMOST always trace the logic of a program in Java. When it comes to bug hunting, this can be really useful. If you define a data class in Kotlin, getters, setters, equality testing, tostring, and hashcode are automatically added for you.
  • Learning resources are limited. The number of developers who are moving to Kotlin is GROWING, yet there is a small developer community accessible to help them understand the language or address problems during development.
  • Kotlin has variable compilation speed. In some SITUATIONS, Kotlin outperforms Java, particularly when EXECUTING incremental builds. However, we must remember that when it comes to clean builds, Java is the clear WINNER.
2.

Differentiate between launch / join and async / await in Kotlin.

Answer»

launch / join:-

The launch COMMAND is used to start and stop a coroutine. It's as though a new THREAD has been started. If the code inside the launch throws an exception, it's considered as an uncaught exception in a thread, which is typically written to stderr in backend JVM programs and crashes ANDROID applications. Join is used to WAIT for the launched coroutine to complete before propagating its exception. A crashed child coroutine, on the other hand, cancels its PARENT with the matching exception.

async / await:-

The async keyword is used to initiate a coroutine that computes a result. You must use await on the result, which is represented by an instance of Deferred. Uncaught exceptions in async code are held in the resultant Deferred and are not transmitted anywhere else. They are not executed until processed.

3.

What do you understand about the backing field in Kotlin?

Answer»

A backing FIELD is an auto-generated field for any property that may only be USED inside ACCESSORS (getter or setter) and will only be present if it utilizes the default IMPLEMENTATION of at least one of the accessors, or if a custom accessor refers to it through the field identifier. This backing field is used to avoid an accessor's recursive call, which WOULD result in a StackOverflowError.

Fields are not allowed in Kotlin classes. When employing custom accessors, however, it is occasionally required to have a backing field. Kotlin includes an automatic backing field for these purposes, which may be accessed by the field identifier.

For example,

var marks: Int = someValue get() = field set(value) { field = value }

Explanation:-  Here the field identifier acts as a reference to the property “marks” value in the get() and set() method. So, whenever we call the get(), we get the field’s value returned. Similarly, whenever we call the set(), we set the “marks” property value to “value”.

4.

What do you understand about sealed classes in Kotlin?

Answer»

Kotlin introduces a crucial new form of class that isn't seen in Java. These are referred to as "sealed classes." Sealed classes, as the NAME implies, adhere to constrained or bounded class hierarchies. A sealed class is one that has a SET of subclasses. When it is known ahead of time that a type will conform to one of the subclass types, it is employed. Type safety (that is, the compiler will VALIDATE types during compilation and throw an exception if a wrong type has been assigned to a variable) is ensured through sealed classes, which limit the types that can be matched at compile time rather than runtime.

The SYNTAX is as follows:-

sealed class className

Another distinguishing aspect of sealed classes is that their constructors are by default private. Due to the fact that a sealed class is automatically abstract, it cannot be instantiated.

For example,

// KOTLINsealed class Sample { class A : Sample() { fun print() { println("This is the subclass A of sealed class Sample") } } class B : Sample() { fun print() { println("This is the subclass B of sealed class Sample") } }}fun main(){ val obj1 = Sample.B() obj1.print() val obj2 = Sample.A() obj2.print()}

Output:-

This is the subclass B of sealed class SampleThis is the subclass A of sealed class Sample

Explanation:- In the above code, we have created a sealed class named “Sample” and we have created TWO sub classes within it named “A” and “B”. In the main function, we create an instance of both the sub classes and call their “print” method.

5.

Explain suspend function in the context of Kotlin.

Answer»

A FUNCTION that may be started, halted, then resumed is known as a suspend function. ONE of the most important things to remember about the suspend functions is that they can only be invoked from another suspend function or from a coroutine. Suspending functions are MERELY standard Kotlin functions with the suspend modifier ADDED, indicating that they can suspend coroutine execution without blocking the current thread. This means that the code you're looking at may pause execution when it calls a suspending function and restart execution at a later time. However, it makes no mention of what will happen to the present thread in the meantime.

Suspending functions can call any other ordinary functions, but another suspending function is required to suspend the execution. Because a suspending function cannot be called from a REGULAR function, numerous coroutine builders are supplied, allowing you to call a suspending function from a non-suspending scope like launch, async, or runBlocking.

delay() function is an example of suspend function.

6.

Explain scope functions in the context of Kotlin. What are the different types of Scope functions available in Kotlin?

Answer»

The Kotlin standard library includes numerous FUNCTIONS that aid in the execution of a block of code within the context of an object. When you use a lambda expression to call these functions on an object, temporary scope is created. These functions are referred to as Scope functions. The object of these functions can be accessed WITHOUT knowing its NAME. Scope functions make code more clear, LEGIBLE, and succinct, which are key qualities of the Kotlin programming language.

Following are the different types of Scope functions available in Kotlin:-

  • let:- 
    Context object:   it 
    Return value:   lambda result
    The let function is frequently used for null safety calls. For null safety, use the safe call operator(?.) with ‘let'. It only runs the block with a non-null value.
  • apply:-
    Context object:  this
    Return value:   context object
    “Apply these to the object,” as the name suggests. It can be used to operate on receiver object members, primarily to initialise them.
  • with:-
    Context object:  this
    Return value:   lambda result
    When calling functions on context objects without supplying the lambda result, ‘with' is recommended.
  • run:-
    Context object:  this 
    Return value:   lambda result
    The ‘run' function is a combination of the ‘let' and ‘with' functions. When the object lambda involves both INITIALIZATION and computation of the return value, this is the method to use. We can use run to make null safety calls as well as other calculations.
  • also:-
    Context object:  it
    Return value:   context object
    It's used when we need to do additional operations after the object members have been initialised.
7.

What do you understand about coroutines in the context of Kotlin?

Answer»

Unlike many other languages with equivalent capabilities, async and await are neither keywords nor part of Kotlin's standard library. JetBrains' kotlinx.coroutines library is a comprehensive library for coroutines. It includes a number of high-level coroutine-enabled primitives, such as launch and async. Kotlin Coroutines provide an API for writing ASYNCHRONOUS code in a sequential manner.

Coroutines are similar to thin threads. Coroutines are lightweight since they don't allocate new threads when they're created. Instead, they employ pre-defined thread pools as well as intelligent SCHEDULING. The process of deciding which piece of work you will do next is known as scheduling. Coroutines can also be paused and resumed in the middle of their execution. This means you can have a long-term project that you can work on incrementally. You can PAUSE it as many times as you WANT and continue it WHENEVER you're ready.

8.

Differentiate between lateinit and lazy initialisation. Explain the cases when you should use lateinit and when you should use lazy initialisation.

Answer»

Following are the differences between lateinit and lazy initialisation:-

lateinitlazy initialisation
The main PURPOSE is to delay the initialisation to a later point in time.The main purpose is to initialise an object only when it is used at a later point in time. Also, a single COPY of the object is maintained throughout the program. 
It's possible to initialise the object from anywhere in the program.Only the initializer lambda can be used to initialise it.
Multiple initializations are possible in this case.Only a single initialisation is possible in this case.
It's not thread-safe. In a multi-threaded system, it is up to the user to correctly initialise.Thread-safety is enabled by default, ensuring that the initializer is only called once.
It works only with var.It works only with val.
The isInitialized method is added to verify if the value has previously been initialised.It is impossible to uninitialize a property.
Properties of PRIMITIVE TYPES are not allowedAllowable on primitive type properties.

There are a few easy principles to follow when deciding whether to use lateinit or lazy initialisation for property initialization:

  • Use lateInit if properties are mutable (i.e., they may change later).
  • Use lateinit if properties are set externally (for example, if you need to pass in an external VARIABLE to set it). There is still a way to use lazy, but it isn't as obvious.
  • If they're only meant to be initialised once and shared by everybody, and they're more internally set (depending on a class variable), then lazy is the way to go. We could still use lateinit in a tactical sense, but utilising lazy initialisation would better encapsulate our initialization code.
9.

Explain lazy initialization in the context of Kotlin.

Answer»

There are some classes whose object initialization is so time-consuming that it causes the entire class creation process to be delayed. Lazy INITIALISATION helps in such problems. When we declare an object using lazy initialisation, the object is initialised only once when the object is used. If the object is not used throughout, the object is not initialised. This makes the code more efficient and faster. 

For example, let us imagine you have a SlowClass class and you REQUIRE an object of that SlowClass in a different class called FASTCLASS:

// KOTLINclass FastClass { private val slowObject: SlowClass = SlowClass()}

We are generating a large object here, which will cause the development of the FastClass to be slow or delayed. There may be times where the SlowClass object isn't required. As a result, the lazy keyword can assist you in this situation:

class FastClass { private val slowObject: SlowClass by lazy { SlowClass() } }

For example,

// KOTLINclass FastClass { private val slowObject: SlowClass by lazy { println("Slow Object initialised") SlowClass() }  fun access() { println(slowObject) }}fun main(args: Array<String>) { val fastClass = FastClass() println("FastClass initialised") fastClass.access() fastClass.access()}

Output:-

FastClass initialised Slow Object initialised SlowClass@2b12fkk7 SlowClass@2b12fkk7

Explanation:- In the above code, we have instantiated an object of the SlowClass inside the class structure of the FastClass using lazy initialisation. The object of the SlowClass is generated only when it is ACCESSED in the above code, that is, when we call the access() method of the FastClass object and the same object is present throughout the main() method.

10.

What do you understand about lateinit in Kotlin? When would you consider using it?

Answer»

lateinit is an abbreviation for LATE INITIATION. If you don't want to initialize a variable in the constructor and instead want to do it later, and you can guarantee the initialization before using it, use the lateinit keyword to declare that variable. It won't start allocating memory until it's been initialized. Lateinit cannot be USED for primitive type attributes like Int, Long, and so on. Because the lateinit variable will be initialized later, you cannot use val. When a lateinit property is ACCESSED before it has been initialized, a special exception is thrown that explicitly identifies the property and the fact that it hasn't been initialized.

For example,

// KOTLINlateinit var test: Stringfun testFunction() { test = "Interview" println("The length of string is "+test.length) test = "Bit"}

When the testFunction is called, we get the following output:-

9

There are a few scenarios in which this is particularly useful, for example:

  • Variables that are initialized in LIFECYCLE methods in Android;
  • Using Dagger for DI: injected class variables are initialized outside of the constructor and independently;
  • Setup for unit tests: in a @Before - annotated function, test environment variables are initialized;
  • Annotations in Spring Boot (for example, @Autowired).
11.

Which one is better to use - val mutableList or var immutableList in the context of Kotlin?

Answer»

The PROGRAM's design clarity is improved by using mutable and immutable lists. This is done to have the developer think about and clarify the collection's purpose.

We use a mutable list if the collection will alter as part of the design. On the other HAND, we use an immutable list if the model is only meant to be viewed.

Val and var serve a distinct purpose than immutable and mutable lists. The val and var keywords specify how a variable's value/reference should be handled. We use var when the value or reference of a variable can be altered at any moment. On the other hand, we use val when a variable's value/reference can only be assigned once and cannot be modified later in the execution.

Immutable lists are frequently preferred for a variety of reasons:

  • They promote functional programming, in which state is passed on to the next function, which constructs a new state based on it, rather than being altered. This is evident in Kotlin collection methods like map, filter, reduce, and so forth.
  • It's OFTEN easier to understand and debug software that doesn't have any side effects (you can be sure that the value of an OBJECT will ALWAYS be the one at its definition).
  • Because no write access is required in multi-threaded systems, immutable resources cannot induce race conditions.

However, there are some disadvantages of using immutable lists as well. They are as follows :

  • Copying large collections simply to add/remove a single piece is very expensive.
  • When you need to alter single fields frequently, immutability can make the code more difficult. Data classes in Kotlin provide a built-in copy() method that allows you to clone an instance while changing only part of the fields' values.