Kotlin is immensely practical. It addresses the problems that developers have, and not some guys in the academia. So, it has type inference, it has amazing type safety, good collection library, and concurrency library to top it. And it's now official - a lot of organisations are migrating their backend applications to Kotlin, and this trend is not likely to end soon. Follow along to check the most complete and comprehensive collection of the most common and advanced Kotlin Interview Questions every Android developer should know in 2020.
In Java an array can be initialized such as:
int numbers[] = new int[] {10, 20, 30, 40, 50}How does Kotlin's array initialization look like?
val numbers: IntArray = intArrayOf(10, 20, 30, 40, 50)Just use object.
object SomeSingletonThe above Kotlin object will be compiled to the following equivalent Java code:
public final class SomeSingleton {
public static final SomeSingleton INSTANCE;
private SomeSingleton() {
INSTANCE = (SomeSingleton)this;
System.out.println("init complete");
}
static {
new SomeSingleton();
}
}This is the preferred way to implement singletons on a JVM because it enables thread-safe lazy initialization without having to rely on a locking algorithm like the complex double-checked locking.
We frequently create classes whose main purpose is to hold data. In Kotlin, this is called a data class and is marked as data:
data class User(val name: String, val age: Int)To ensure consistency and meaningful behavior of the generated code, data classes have to fulfill the following requirements:
fold and reduce in Kotlin? When to use which?fold takes an initial value, and the first invocation of the lambda you pass to it will receive that initial value and the first element of the collection as parameters.
listOf(1, 2, 3).fold(0) { sum, element -> sum + element }The first call to the lambda will be with parameters 0 and 1.
Having the ability to pass in an initial value is useful if you have to provide some sort of default value or parameter for your operation.
reduce doesn't take an initial value, but instead starts with the first element of the collection as the accumulator (called sum in the following example)
listOf(1, 2, 3).reduce { sum, element -> sum + element }The first call to the lambda here will be with parameters 1 and 2.
var and val in Kotlin?var is like general variable and it's known as a mutable variable in kotlin and can be assigned multiple times.
val is like Final variable and it's known as immutable in Kotlin and can be initialized only single time.
+----------------+-----------------------------+---------------------------+
| | val | var |
+----------------+-----------------------------+---------------------------+
| Reference type | Immutable(once initialized | Mutable(can able to change|
| | can't be reassigned) | value) |
+----------------+-----------------------------+---------------------------+
| Example | val n = 20 | var n = 20 |
+----------------+-----------------------------+---------------------------+
| In Java | final int n = 20; | int n = 20; |
+----------------+-----------------------------+---------------------------+var and where val?Use var where value is changing frequently. For example while getting location of android device:
var integerVariable : Int? = nullUse val where there is no change in value in whole class. For example you want set textview or button's text programmatically.
val stringVariables : String = "Button's Constant or final Text"when vs switch in KotlinIn Java we use switch but in Kotlin, that switch gets converted to when. When has a better design. It is more concise and powerful than a traditional switch. when can be used either as an expression or as a statement.
Some examples of when usage:
when(number) {
1 -> println("One")
2, 3 -> println("Two or Three")
4 -> println("Four")
else -> println("Number is not between 1 and 4")
}when {
number < 1 -> print("Number is less than 1")
number > 1 -> print("Number is greater than 1")
}fun describe(obj: Any): String =
when (obj) {
1 -> "One"
"Hello" -> "Greeting"
is Long -> "Long"
!is String -> "Not a string"
else -> "Unknown"
}when (x) {
is Int -> print("X is integer")
is String -> print("X is string")
}when(number) {
1 -> println("One") //statement 1
2 -> println("Two") //statement 2
3 -> println("Three") //statement 3
in 4..8 -> println("Number between 4 and 8") //statement 4
!in 9..12 -> println("Number not in between 9 and 12") //statement 5
else -> println("Number is not between 1 and 8") //statement 6
}Kotlin's type system is aimed at eliminating the danger of null references from code, also known as the The Billion Dollar Mistake.
One of the most common pitfalls in many programming languages, including Java, is that accessing a member of a null reference will result in a null reference exception. In Java this would be the equivalent of a NullPointerException or NPE for short.
In Kotlin, the type system distinguishes between references that can hold null (nullable references) and those that can not (non-null references). For example, a regular variable of type String can not hold null:
var a: String = "abc"
a = null // compilation errorTo allow nulls, we can declare a variable as nullable string, written String?:
var b: String? = "abc"
b = null // ok
print(b)Why is this code wrong?
class Student (var name: String) {
init() {
println("Student has got a name as $name")
}
constructor(sectionName: String, var id: Int) this(sectionName) {
}
}The property of the class can’t be declared inside the secondary constructor.. This will give an error because here we are declaring a property id of the class in the secondary constructor, which is not allowed.
If you want to use some property inside the secondary constructor, then declare the property inside the class and use it in the secondary constructor:
class Student (var name: String) {
var id: Int = -1
init() {
println("Student has got a name as $name")
}
constructor(secname: String, id: Int) this(secname) {
this.id = id
}
}In Kotlin, if you want to create the local constants which are supposed to be used with in the class then you can create it like below:
val MY_CONSTANT_1 = "Constants1"
// or
const val MY_CONSTANT_2 = "Constants2"Like val, variables defined with the const keyword are immutable. The difference here is that const is used for variables that are known at compile-time.
Also avoid using companion objects. Behind the hood, getter and setter instance methods are created for the fields to be accessible. Calling instance methods is technically more expensive than calling static methods. Instead define the constants in object:
object DbConstants {
const val TABLE_USER_ATTRIBUTE_EMPID = "_id"
const val TABLE_USER_ATTRIBUTE_DATA = "data"
}apply?Consider:
class Message(message: String, signature: String) {
val body = MessageBody()
init {
body.text = message + "\n" + signature
}
}Do you see any refactoring that could be done?
You can write:
class Message(message: String, signature: String) {
val body = MessageBody().apply {
text = message + "\n" + signature
}
}IntArray and an Array<Int> is in Kotlin interchangeably?Array<Int> is an Integer[] under the hood, while IntArray is an int[].
This means that when you put an Int in an Array<Int>, it will always be boxed (specifically, with an Integer.valueOf() call). In the case of IntArray, no boxing will occur, because it translates to a Java primitive array.
So no, we can't use them interchangeably.
Can you rewrite this Java code in Kotlin?
public class Singleton {
private static Singleton instance = null;
private Singleton(){
}
private synchronized static void createInstance() {
if (instance == null) {
instance = new Singleton();
}
}
public static Singleton getInstance() {
if (instance == null) createInstance();
return instance;
}Using Kotlin:
object SingletonUnlike many other languages with similar capabilities, async and await are not keywords in Kotlin and are not even part of its standard library.
kotlinx.coroutines is a rich library for coroutines developed by JetBrains. It contains a number of high-level coroutine-enabled primitives, including launch, async and others. Kotlin Coroutines give you an API to write your asynchronous code sequentially.
The documentation says Kotlin Coroutines are like lightweight threads. They are lightweight because creating coroutines doesn’t allocate new threads. Instead, they use predefined thread pools, and smart scheduling. Scheduling is the process of determining which piece of work you will execute next.
Additionally, coroutines can be suspended and resumed mid-execution. This means you can have a long-running task, which you can execute little-by-little. You can pause it any number of times, and resume it when you’re ready again.
Some think that Kotlin is a mess of extra syntax and keywords. Here are a few keywords which have non-obvious meanings: internal, crossinline, expect, reified, sealed, inner, open. Java has none of these. Kotlin is also amusingly inconsistent in its keywords: a function is is declared with ‘fun’, but an interface is declared with ‘interface’ (not ‘inter’?). Kotlin also doesn’t have checked exceptions. Checked exceptions have become unfashionable, yet many (including me) find them a powerful way to ensure that your code is robust. Finally, Kotlin hides a lot of what goes on. In Java, you can trace through almost every step of program logic. This can be vital for hunting down bugs. In Kotlin, if you define a data class, then getters, setters, equality testing, to string, and hash code are added for you invisibly. This can be a bad idea.
Also according docs, what Java has that Kotlin does not:
Basically for me less thinking required to write kotlin equivalent to most java code:
data class
java: you have to write getters and setters for each thing, you have to write hashCode properly (or let IDE auto generate, which you have to do again every time you change the class), toString (same problem as hashcode) and equals (same problem as hashCode). or you could use lombok, but that comes with some quirky problems of its own. record types are hopefully on the way. *kotlin: data class does it all for you.
getter and setter patterns
java: rewrite the getter and setter for each variable you use it for
kotlin: don't have to write getter and setter, and custom getter and setter take a lot less typing in kotlin if you do want to. also delegates exist for identical getters\setters
abstract vs open classes
java: you have to make an abstract class implementation
kotlin: open class lets you make an inheritable class while also being usable itself. nice mix of interface and regular class imo
extension functions
java: doesnt exist
kotlin: does exist, makes functions more clear in usage and feels more natural.
null
java: Anything but primitives can be null at any time.
kotlin: you get to decide what can and cant be null. allows for nice things like inline class
singleton
java: Memorize singleton pattern
kotlin: object instead of class
generics
java: Theyre alright, nothing fancy
kotlin: Reified generics (you can access the actual type), in and out for covariance
named parameters
java: does not exist, easy to break api back-compatibility if you arent careful.
kotlin: does exist, easy to preserve api back-compatiblity.
primary constructor
java: does not have per-se, you still have to define everything inside the class
kotlin: very nice to be able to quickly write a constructor without any constructor function or extra needless declarations
lateinit in Kotlin and when would you use it?lateinit means late initialization. If you do not want to initialize a variable in the constructor instead you want to initialize it later on and if you can guarantee the initialization before using it, then declare that variable with lateinit keyword. It will not allocate memory until initialized. You cannot use lateinit for primitive type properties like Int, Long etc.
lateinit var test: String
fun doSomething() {
test = "Some value"
println("Length of string is "+test.length)
test = "change value"
}There are a handful of use cases where this is extremely helpful, for example:
@Before - annotated method;@Autowired).Unlike Java or C#, Kotlin doesn’t have static members or member functions. If you need to write a function that can be called without having a class instance but needs access to the internals of a class, you can write it as a member of a companion object declaration inside that class.
class EventManager {
companion object FirebaseManager {
}
}
val firebaseManager = EventManager.FirebaseManagerThe companion object is a singleton. The companion object is a proper object on its own, and can have its own supertypes - and you can assign it to a variable and pass it around. If you're integrating with Java code and need a true static member, you can annotate a member inside a companion object with @JvmStatic.
!! operator?The not-null assertion operator !! converts any value to a non-null type and throws a KotlinNullPointerException exception if the value is null.
Consider:
fun main(args: Array<String>) {
var email: String?
email = null
println(email!!)
}This operator should be used in cases where the developer is guaranteeing – it allows you to be 100% sure that its value is not null.
A blocking call to a function means that a call to any other function, from the same thread, will halt the parent’s execution. Following up, this means that if you make a blocking call on the main thread’s execution, you effectively freeze the UI. Until that blocking calls finishes, the user will see a static screen, which is not a good thing.
Suspending doesn’t necessarily block your parent function’s execution. If you call a suspending function in some thread, you can easily push that function to a different thread. In case it is a heavy operation, it won’t block the main thread. If the suspending function has to suspend, it will simply pause its execution. This way you free up its thread for other work. Once it’s done suspending, it will get the next free thread from the pool, to finish its work.
List and Array types?The major difference from usage side is that Arrays have a fixed size while (Mutable)Listcan adjust their size dynamically. Moreover Array is mutable whereas List is not.
Furthermore kotlin.collections.List is an interface implemented among others by java.util.ArrayList. It's also extended by kotlin.collections.MutableListto be used when a collections that allows for item modification is needed.
On the jvm level Array is represented by arrays. List on the other hand is represented by java.util.List since there are no immutable collections equivalents available in Java.
const and val?consts are compile time constants. Meaning that their value has to be assigned during compile time, unlike vals, where it can be done at runtime.
This means, that consts can never be assigned to a function or any class constructor, but only to a String or primitive.
For example:
const val foo = complexFunctionCall() //Not okay
val fooVal = complexFunctionCall() //Okay
const val bar = "Hello world" //Also okayopen and public in Kotlin?final: it allows others to inherit from this class.static methods in Kotlin?Place the function in the companion object.
class Foo {
public static int a() { return 1; }
}will become:
class Foo {
companion object {
fun a() : Int = 1
}
}
// to run
Foo.a();Another way is to solve most of the needs for static functions with package-level functions. They are simply declared outside a class in a source code file. The package of a file can be specified at the beginning of a file with the package keyword. Under the hood these "top-level" or "package" functions are actually compiled into their own class. In the above example, the compiler would create a class FooPackage with all of the top-level properties and functions, and route all of your references to them appropriately.
Consider:
package foo
fun bar() = {}usage:
import foo.barUnit-returning in functions? Why is VALUE there? What is this VALUE?Explain what is the purpose of Unit-returning in functions? Why is VALUE there? What is this VALUE?
fun printHello(name : String?) : Unit {
if (name != null)
print("Hello, $name!")
else
print("Hi there!")
// We don't need to write 'return Unit.VALUE' or 'return', although we could
}The purpose is the same as C's or Java's void. Only Unit is a proper type, so it can be passed as a generic argument etc.
Why we don't call it "Void": because the word "void" means "nothing", and there's another type, Nothing, that means just "no value at all", i.e. the computation did not complete normally (looped forever or threw an exception). We could not afford the clash of meanings.
Why Unit has a value (i.e. is not the same as Nothing): because generic code can work smoothly then. If you pass Unit for a generic parameter T, the code written for any T will expect an object, and there must be an object, the sole value of Unit.
How to access that value of Unit: since it's a singleton object, just say Unit
UNIT actually contains valuable information, it basically just means "DONE". It just returns the information to the caller, that the method has been finished.
What will be the output?
val aVar by lazy {
println("I am computing this value")
"Hola"
}
fun main(args: Array<String>) {
println(aVar)
println(aVar)
}For lazy the first time you access the Lazy property, the initialisation (lazy() function invocation) takes place. The second time, this value is remembered and returned:
I am computing this value
Hola
Holalateinit over lazy initialization in Kotlin?There are some simple rules to determined if you should use one or the other for properties initialisation:
Also compare:
| lateinit var | by lazy |
|---|---|
| Can be initialized from anywhere the object seen from. | Can only be initialized from the initializer lambda. |
| Multiple initialization possible. | Only initialize single time. |
| Non-thread safe. It’s up to user to initialize correctly in a multi-threaded environment. | Thread-safety by default and guarntees that the initializer is invoked by once. |
| Can only be used for var. | Can only be used for val. |
| Not eligible for nonnull properties. | Not eligible for nonnull properties. |
| An isInitialized method added to check whether the value has been initialized before. | Property never able to un-initialized. |
| Not allowed on properties of primitive types. | Allowed on properties of primitive types. |
Elvis operator in Kotlin?The Elvis operator is part of many programming languages, e.g. Kotlin but also Groovy or C#. The Elvis operator is the ternary operator with its second operand omitted.
x ?: y // yields `x` if `x` is not null, `y` otherwise.If x isn't null, then it will be returned. If it is null, then the y will be returned.
inline class in Kotlin and when do we need one? Provide an example.Builder pattern in Kotlin?* and Any in Kotlin generics?launch/join and async/await in Kotlin coroutines?Rust has been Stack Overflow’s most loved language for four years in a row and emerged as a compelling language choice for both backend and system developers, offering a unique combination of memory safety, performance, concurrency without Data races...
Clean Architecture provides a clear and modular structure for building software systems, separating business rules from implementation details. It promotes maintainability by allowing for easier updates and changes to specific components without affe...
Azure Service Bus is a crucial component for Azure cloud developers as it provides reliable and scalable messaging capabilities. It enables decoupled communication between different components of a distributed system, promoting flexibility and resili...