Interview Questions Flashcards
What is lateinit ?
lateinit is a keyword in Kotlin that allows you to declare a non-nullable variable without initializing it immediately. It is primarily used with mutable (var) properties and only with non-primitive types.
How to check initialising for lateinit
Use ::variableName.isInitialized to check if a lateinit variable has been initialized.
What is by lazy
Expensive Computations: Properties that require significant resources or time to initialize.
Deferred Initialization: When the property might not be needed immediately or at all.
Read-Only Properties: Ideal for properties declared with val.
what is keypoints of lazy
Immutable Properties Only: Can only be used with val.
Thread Safety: By default, by lazy is thread-safe (LazyThreadSafetyMode.SYNCHRONIZED), but you can configure it.
Single Initialization: The initializer is invoked only once, and the same value is returned on subsequent accesses.
Cannot Be Reassigned: Once initialized, the property cannot be changed.
when to use by lazy or lateinit
When to Use Which:
Use lateinit:
When you need to initialize a mutable property after object creation.
Common in scenarios like dependency injection or Android view binding.
Use by lazy:
When you have an immutable property that is expensive to create and should only be initialized when needed.
Suitable for properties that benefit from lazy initialization to improve performance.
Extension Functions
Extension functions allow you to add new functions to existing classes without inheriting from them or using design patterns like Decorator. They enable you to extend the functionality of a class without modifying its source code.
fun ClassName.newFunctionName(params): ReturnType {
// Function body
}
Extension Properties
Extension properties allow you to add new properties to existing classes. However, unlike extension functions, extension properties cannot have backing fields, meaning they cannot store state. They must be computed based on existing data.
val ClassName.propertyName: PropertyType
get() = // Computation or logic
Scope Functions
Scope functions are functions that allow you to execute a block of code within the context of an object. They help in making the code more concise and readable by reducing boilerplate. (let, run, with, apply, also)
let
Usage:
To execute a lambda expression on the object and return the lambda result.
Often used for null-checks and chaining calls.
run
To execute a lambda expression on the object and return the lambda result.
Useful when you want to perform operations on an object and return a result.
with
To perform multiple operations on an object without creating a temporary variable.
Returns the lambda result.
with(object) {
// ‘this’ refers to the object
}
apply
To configure or initialize an object and return the object itself.
Commonly used in object initialization and builder patterns.
also
To perform additional operations on an object without altering it.
Useful for logging, debugging, or performing side-effects.
Common Pitfalls Scope Fun
Excessive use can make the code harder to read and understand.
Overlapping variable names (this vs it) can lead to confusion.
Not understanding what each scope function returns can lead to bugs.
Functions Types and lamba expressions
Function Types: These describe the types of functions, including their parameters and return types. For example, a function type that takes two Int parameters and returns an Int is written as (Int, Int) -> Int.
Lambda Expressions: These are concise, anonymous functions that can be treated as values. They are useful for passing behavior (functions) as arguments to other functions.