Top 30 Mobile Dev Interview Questions and Answers
30 multiple-choice questions on Mobile Dev, of the kind that come up in a technical interview, drawn from 30 bites in the Mobile Dev library. Answer them here or read straight down. Every question carries the correct option, why it is correct, and a link to the bite it came from.
Mobile app development across platforms
30 questions. Pick an answer, or open “Show the answer” to read it.
Answers are graded in your browser. Nothing is saved, and no XP or streak is earned here. The app keeps score.
Question 1 of 30
In Kotlin, what does declaring a variable with val guarantee about the referenced object?
Show the answer
Answer: c · The reference cannot be reassigned, though the object's contents may still mutate
val only prevents reassigning the reference itself, so a val holding a MutableList can still be modified. The most tempting distractor confuses reference immutability with deep object immutability, which val does not enforce.
Read the full bite: Explain val vs var in Kotlin and null safety risks
Question 2 of 30
What is the main advantage of Kotlin's approach to null safety with default non-nullable types?
Show the answer
Answer: d · It shifts the detection of potential NullPointerExceptions from runtime to compile time.
Kotlin's type system is explicitly designed to prevent NullPointerExceptions (NPEs) at compile time, a major benefit over languages that only catch them at runtime. Option B is a common misconception; val declares a read-only reference, not necessarily a compile-time constant.
Read the full bite: Explain val, var, and null safety in Kotlin
Question 3 of 30
Given the Kotlin declaration `val userNames = mutableListOf("Alice")`, which statement accurately describes the `userNames` variable?
Show the answer
Answer: d · The variable `userNames` cannot be reassigned, but the list it points to can be modified.
The `val` keyword creates a read-only reference, meaning the `userNames` variable cannot be reassigned. However, the `mutableListOf` object it points to is still mutable, allowing its contents to be changed. A common misconception is that `val` makes the object itself immutable.
Read the full bite: Explain val vs. var and null safety in Kotlin
Question 4 of 30
A team needs a niche third-party native SDK that has no Expo support yet wants EAS builds and OTA updates. What is the most accurate take?
Show the answer
Answer: a · They can use Expo prebuild with a config plugin to integrate the SDK while keeping EAS and OTA
Expo prebuild plus a config plugin lets you add arbitrary native code while retaining EAS Build and EAS Update. Abandoning Expo is unnecessary, and Expo Go actually cannot load custom native modules, which is the reverse of the distractor's claim.
Read the full bite: Expo managed workflow vs bare React Native
Question 5 of 30
Which statement accurately describes a key difference between final and const in Dart?
Show the answer
Answer: a · A final variable can hold a runtime value like DateTime.now(), while const requires a compile-time constant.
final allows single assignment at runtime, so DateTime.now() is valid, whereas const requires a compile-time constant and deep immutability. Option D is wrong because final only prevents reassignment of the variable, not mutation of the object's contents.
Read the full bite: What is the difference between final and const in Dart?
Question 6 of 30
What is the actual effect of declaring a class instance with let in Swift?
Show the answer
Answer: c · The reference cannot be reassigned, but the instance's properties can still be mutated
For reference types, let freezes only the pointer, so the variable cannot be reassigned but the object's properties remain mutable. Option B is a common misconception that confuses the reference with the instance itself.
Read the full bite: What is the difference between let and var in Swift?
Question 7 of 30
If user is null, what happens when evaluating user?.name ?: "Guest"?
Show the answer
Answer: b · It returns Guest without throwing an exception
The safe call operator ?. returns null when user is null, and the Elvis operator ?: then substitutes Guest as the fallback. Option C is tempting because ?. does preserve nullability, but it ignores that ?: immediately provides the default value.
Read the full bite: What do the safe call and Elvis operators do in Kotlin?
Question 8 of 30
Given a nullable `user: User?`, how do you safely get its name's length, returning 0 if either `user` or its `name` property is null?
Show the answer
Answer: d · user?.name?.length ?: 0
The safe call `?.` accesses properties only if the object is not null, and the Elvis operator `?:` provides the default value `0` if the preceding expression is null. The `if/else` block is verbose and not idiomatic Kotlin.
Read the full bite: Purpose of Kotlin's safe call (`?.`) and Elvis (`?:`) operators?
Question 9 of 30
Given `data class User(val name: String?)` and a nullable `val activeUser: User?`, which Kotlin expression correctly retrieves the user's name, providing "Guest" if `activeUser` is null or its `name` property is null?
Show the answer
Answer: d · activeUser?.name ?: "Guest"
Option D correctly uses the safe call operator (?. ) to access 'name' only if 'activeUser' is not null, and then the Elvis operator (?: ) to provide "Guest" if the result is null. Option C, while functionally correct, is considered non-idiomatic Kotlin as it uses a verbose if/else block instead of the more concise and expressive ?. and ?: operators.
Read the full bite: Purpose of safe call (`?.`) and Elvis (`?:`) operators
Question 10 of 30
Why does a 200ms synchronous data mapping on a React Native screen freeze interactive components like TouchableOpacity?
Show the answer
Answer: b · It monopolizes the JavaScript thread, so batched native updates and queued touch events cannot be processed.
The correct answer recognizes that the JavaScript thread is blocked, preventing batched native updates and touch events from being handled. Option A is tempting because it confuses the JavaScript thread with the native UI main thread, which is the exact misconception the card highlights.
Read the full bite: UI unresponsive during large data processing on main thread
Question 11 of 30
Which statement accurately describes Dart's positional and named parameter rules?
Show the answer
Answer: c · Optional positional parameters use square brackets and must appear before named ones.
The card states optional positional parameters use square brackets and must precede named ones, while named parameters use curly braces and can be required. D is the most tempting distractor because it repeats the common red-flag misconception that optional positional parameters use curly braces.
Read the full bite: Explain Dart positional vs named parameters and write one signature
Question 12 of 30
Which statement accurately describes a Swift Optional's implementation and a safe way to unwrap it?
Show the answer
Answer: b · It is a generic enum with Some and None cases, and it can be safely unwrapped using if let or the nil-coalescing operator.
Swift models Optional as a generic enum with Some and None cases, enforcing nil safety at compile time. The most tempting distractor suggests force-unwrapping is standard, but the card warns that using ! is unsafe and only acceptable when non-nil status is guaranteed.
Read the full bite: What is an optional in Swift? Demonstrate two safe unwrapping methods.
Question 13 of 30
When accessing a property on a nullable object in Dart, what is the fundamental difference between using ?. and !?
Show the answer
Answer: c · ?. evaluates to null when the receiver is null, while ! casts to non-nullable and may throw at runtime.
The null-aware operator ?. short-circuits and yields null if the receiver is null, whereas ! forcibly casts away nullability and throws a runtime exception if the value is actually null. Option D is wrong because it confuses ?. with the ?? default-value operator and incorrectly suggests ! is compile-time safe.
Read the full bite: Describe Dart's null-aware ?. and null assertion ! operators
Question 14 of 30
If a class has a member function and an extension function is defined with the same signature, which one will be invoked when called on an instance of that class?
Show the answer
Answer: b · The member function, because member functions always take precedence.
When a member function and an extension function have the same signature, the member function will always be chosen. This is because extension functions are resolved statically and do not override class members, making the member function the more specific choice.
Read the full bite: What is a Kotlin extension function? Write one for String.
Question 15 of 30
What is the primary effect of enabling inline requires in a React Native app?
Show the answer
Answer: a · It defers a module's evaluation until the first time it is actually used
Inline requires transform top-level imports so a module is evaluated lazily on first use, cutting startup work. It does not compile to machine code (that is closer to Hermes bytecode) nor perform tree shaking, which is a separate bundler concern.
Question 16 of 30
Which statement accurately describes the underlying mechanism of Kotlin extension functions?
Show the answer
Answer: c · They are compiled into static utility methods where the receiver object is passed as the first parameter.
The card explicitly states that extension functions are "syntactic sugar for static utility methods" and are "compiled down to static methods that take the receiver object as the first argument." They do not modify the original class or its bytecode, which is a common misconception.
Read the full bite: What is a Kotlin extension function? Write one for String.
Question 17 of 30
Which statement accurately describes how Kotlin resolves an extension function call on a receiver?
Show the answer
Answer: c · It uses the compile-time declared type of the receiver, compiling down to a static method call
Kotlin extension functions are resolved at compile time based on the declared receiver type and compile to static methods, not real class members. Option D is tempting because it mirrors true polymorphic dispatch, but extensions are statically dispatched and cannot be overridden.
Read the full bite: What is an extension function? Write a hasWhitespace extension for String.
Question 18 of 30
In Swift, a developer omits the default case in a switch over an Int and covers only a few values. What happens?
Show the answer
Answer: c · It fails to compile because the switch is not exhaustive
Swift requires switches to be exhaustive, so covering only some Int values without a default is a compile error. There is no implicit fallthrough and no break is needed, so the other options describe C behavior, not Swift.
Read the full bite: How does Swift's switch differ from C's switch?
Question 19 of 30
When designing a Swift data model that requires independent undo snapshots without retroactive mutation, why is a struct preferred over a class?
Show the answer
Answer: c · Because assignment creates a unique copy, preventing shared references from mutating prior snapshots.
Structs are value types, so each assignment copies the instance and prior snapshots remain independent. Option D is a common misconception because structs are not guaranteed to be stack-allocated, and option A is wrong since structs do not support inheritance.
Read the full bite: Explain the primary differences between a struct and a class in Swift
Question 20 of 30
When a native module method reads a live device value to return to JavaScript, why should it use a Promise or callback rather than a direct return?
Show the answer
Answer: d · Because crossing the native-to-JS boundary is asynchronous, so results are delivered via promise or callback
Values crossing from native into JavaScript are delivered asynchronously, so a Promise or callback is the correct pattern. Native code can return constants synchronously via getConstants, and package registration is unrelated to whether methods are async.
Question 21 of 30
When working with immutable state in Kotlin, which generated function of a data class is specifically designed to create a new object instance with modified properties without altering the original?
Show the answer
Answer: b · copy()
The copy() function is specifically designed to create a new instance of the data class, allowing certain properties to be modified while leaving the original object unchanged, which is crucial for immutable state management. The other generated functions serve different purposes like comparison, string representation, or hash generation, not for creating modified copies.
Read the full bite: What are the advantages of a Kotlin data class and its functions?
Question 22 of 30
When managing immutable state with a data class, what is the primary role of the generated `copy()` function?
Show the answer
Answer: b · To create a new, modified instance of the object, leaving the original unchanged.
The `copy()` function is central to working with immutable objects; it creates a new instance with specified changes, leaving the original untouched. Option A is a critical misunderstanding, as `copy()` never mutates the original object, which is key to predictable state management.
Read the full bite: What are the advantages of a Kotlin data class?
Question 23 of 30
When using a Kotlin data class as a key in a HashMap, which statement about its compiler-generated behavior is true?
Show the answer
Answer: b · Only properties defined in the primary constructor marked as val or var are used in generated equals and hashCode, so the key remains consistent in the map.
The compiler only incorporates primary constructor properties marked val or var into generated equals and hashCode, guaranteeing the contractual consistency required for safe use as a HashMap key. Option C is a tempting distractor because developers often assume body properties participate in structural equality, but the compiler intentionally excludes them.
Read the full bite: What are the primary advantages of using a data class?
Question 24 of 30
A class declares late final UserService repo and assigns it in initState. What happens if repo is read in build before that assignment?
Show the answer
Answer: a · A LateInitializationError is thrown at the point of access
late shifts definite-assignment checks from compile time to runtime, so accessing the field before assignment throws LateInitializationError. Distractor C is tempting because that is exactly the compile-time error you would receive if the field were not marked late.
Question 25 of 30
Why does indexing a Swift String by an integer like myString[5] not compile, unlike in many other languages?
Show the answer
Answer: c · Characters are variable-width grapheme clusters, so an integer offset cannot give O(1) or unambiguous access
Swift Characters are extended grapheme clusters of varying byte length, so an integer offset is neither constant-time nor meaningful, which is why String.Index is opaque. Immutability is unrelated, and String.Index is not an Int alias.
Read the full bite: Why can't you subscript a Swift String with an Int?
Question 26 of 30
Why can defining styles with StyleSheet.create be preferable to inline literal objects in a long list?
Show the answer
Answer: c · It reuses a stable object reference across renders instead of allocating a new object each time
StyleSheet styles are created once and referenced by key, giving stable references that avoid per-render allocations. React Native has no CSS cascade, and unit handling is not what StyleSheet.create provides.
Question 27 of 30
An Android Fragment needs a property for a complex, computationally expensive object that is only used in certain user flows. The object should be created only once. Which declaration is most appropriate?
Show the answer
Answer: b · private val myObject: MyObject by lazy { createExpensiveObject() }
`val by lazy` is ideal for expensive, immutable properties because it defers creation until first access and caches the result. `lateinit var` is incorrect because the property is immutable and is meant for when an external framework provides the value, not for deferred computation.
Question 28 of 30
Which statement accurately describes a fundamental difference between lateinit var and val by lazy in Kotlin?
Show the answer
Answer: b · val by lazy can initialize properties of any type, including primitives, unlike lateinit var.
The card states that lateinit var cannot be used for primitive types like Int or Boolean, while val by lazy has no such restriction. Option A is incorrect because it describes the behavior of val by lazy, not lateinit var, which is initialized manually.
Question 29 of 30
In an Activity, a property holds a ViewModel obtained via ViewModelProvider in onCreate. Why is lateinit var more suitable than val by lazy?
Show the answer
Answer: c · lateinit var allows imperative assignment and can be reassigned if the Activity is recreated
lateinit var is designed for mutable properties assigned imperatively in lifecycle callbacks like onCreate and can be reassigned when the Activity is recreated, whereas val by lazy is immutable and self-initializing. Option D is tempting but wrong because it describes lazy's first-access caching behavior, not lateinit's imperative assignment model.
Read the full bite: Explain lateinit var versus val by lazy in Android
Question 30 of 30
Given List<int> nums = [1, 2, 3, 4] and bool includeZero = true, which literal produces [0, 2, 4]?
Show the answer
Answer: a · [if (includeZero) 0, for (var n in nums) if (n.isEven) n]
Option A correctly uses collection-if to prepend 0 and collection-for with a nested collection-if to filter evens inside one literal. Option B is tempting because where looks declarative, but without the spread operator it inserts the Iterable object itself as a single element rather than flattening its contents.
Read the full bite: How do you use collection-if and collection-for to declaratively build a list?
Could you explain these out loud?
That is what an interview actually tests. Tezvyn gives you questions like these with what the interviewer is really checking, the answer that lands, and the mistake that ends the conversation, in the four minutes before your next meeting.
The iPhone app is on the way
We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.
Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.