Share your 3 key kotlin interview question


#1

Hi Kotliner,
Was looking for some similar post, but couldn’t find one, so created this.

I know 3 is very less number, feel free to add 5, 10 or more.

Lets stick to kotlin jvm for this post and avoid android specific questions.

Feel free to ask trick questions, code snippet or ideomatic design related questions but also share your answer in some link or attachments for such questions.

In the next post i would share my 3 favorite key questions, which i would like to ask any kotlin developer.


#2

Will add more tomorrow, but this is one I read wrong often and every time I find it annoying…

What is wrong about the statement “val means immutable”?

val does not mean immutable, val means read-only.
Example:

class Test{
    private val _rand = Random()
    val rand get() = _rand.nextInt()
}

Immutable hopefully will be added soon…

What does cross-inline mean and when do you use it?

answer
inline fun foo(crossinline lamb: () -> Unit){
    lamb()
}

When you add crossinline, you can only return from the lambda (local return).
When you don’t add crossinline, you can return out of the place that calls the lambda as well (non-local return):

why:

https://kotlinlang.org/docs/reference/inline-functions.html#non-local-returns

in my own words
inline fun foo(lamb: ()->Unit) = lamb()
fun bar() {
    println(1)
    foo{ return }
    println(2)
}

is replaced with:

fun bar() {
    println(1)
    return
}

So you return not only out of foo, but out of bar as well. this is called non-local return.

When the lambda can be inlined, but is called inside another lambda/object, the context changes.
This means that you can’t return out of the original context anymore.
In other words, the return should not be allowed anymore.

a clear example:

inline fun createReturner(crossinline lamb: () -> Int) = object: Returner{
override fun returning() = lamb()
}

fun test() : Int{
    Main.returner = createReturner{
        return 4.
    }
}

This is obviously not allowed: calling returner.returning() in Main, will not make test return 4.
And it would be a complete maddness when you take in account that returner.returning can be called twice :stuck_out_tongue_winking_eye: .


#3

The term ‘read-only’ doesn’t help me much. (After all, if an object was really read-only, then it’d be immutable!)

Instead, I think of val as meaning that the reference is immutable — not the object it points to.

(Probably harking back to my days of coding in C, where const is part of the type and can apply to pointers or to the values they point to…)


One of the puzzlers that’s ensnared me before is illustrated by:

fun displayNumber(i: Int) = {
    println(i)
}

That compiles, but does it do what’s expected?

No! It’s intended to take a number and print it; but what it actually does is take a number and return a function which prints it.
The mistake is the extraneous equals sign.
This sort of problem can be very hard to spot. A good way is to specify the function’s return type: if you give Unit but the compiler finds () -> Unit, it’ll complain.


#4

Nop. I understand what you mean, but a property is not pointing to an object. A property is just a combination of a getter and optionally also a setter and backing variable. There is nothing immutable about a property.

This idea leads to a lot of problems. For example some people think of List to be immutable because it just has val-properties, it is read-only though.


#5

This confusion about val, List, and immutability vs. read-only comes up so much. I wonder if it would be worth adding a section to the docs that tries to explain this with diagrams or something. Maybe this is all already there somewhere but it would be nice to have once spot we could point people to when they get it wrong.

Trying to summarize what could be explained in that section:

A val variable’s value is usually a reference to an object. The value of the variable cannot be changed to refer to a different object. However, the object to which the val variable refers can modified unless the object itself is immutable.

A variable of type List is a read-only view to a mutable object whether the variable is declared with var or val. It is possible to modify the object referenced by that variable by using another variable of type MutableList referencing the same object.

fun main(args: Array<String>) {
    val c = mutableListOf("a", "b")
    val d: List<*> = c as List<*>
    println("d = $d")
    c.removeAt(0)
    println("d = $d")
}

#6

True most of the time. But a variable of type List can also point to a immutable list. Most of the time this is just not the case, eg listOf returns an ArrayList which is mutable.

Not that I know of (at least not in the official docs, I’m sure there are many posts about this). I was thinking about writing an addition to the docs but never did it, maybe I should.


#7

Yes, I was oversimplifying when I wrote: “A variable of type List is a read-only view to a mutable object…” An immutable List is possible, at least, in theory.

Although, I’m having a hard time thinking of an immutable collection implementation on the JVM. Are there any?


#8

#9

Collections.emptyList is an immutable empty list. Collections.singletonList is immutable as well. The List.of(...) overloads as of Java 9 return immutable Lists as well. And the Lists returned by Arrays.asList(...) aren’t immutable, but have a fixed size at least. So immutable Lists aren’t nearly as rare as one might think.