DEV Community

Hannah Usmedynska
Hannah Usmedynska

Posted on • Originally published at jobswithscala.com on

100 Scala Coding Interview Questions and Answers

Preparing for a Scala coding interview requires more than reading documentation. Candidates need to practice explaining concepts clearly under pressure, and hiring teams need reliable questions that separate real understanding from memorized definitions. The Scala coding questions and answers below cover five levels of difficulty across 100 scenarios.

Preparing for the Scala Coding Interview

A strong Scala coding interview process benefits both sides of the table. Recruiters get a repeatable framework for comparing candidates, and engineers get a clear picture of the skills they need to demonstrate. The two sections below explain how standardized questions improve outcomes for each group.

How Sample Coding Interview Questions Help Recruiters

Standardized Scala interview coding questions give recruiters a consistent way to compare candidates across rounds. When every interviewer works from the same question bank, evaluation becomes less subjective and more defensible. Structured approaches to interviewing also reduce bias, as confirmed by SHRM research on talent selection. A shared set of interview coding questions for Scala developers ensures that technical screens measure depth rather than interviewer preference.

How Sample Coding Interview Questions Help Technical Specialists

For engineers, practicing with realistic Scala code interview questions reveals gaps before the actual conversation. Working through bad and good answer pairs builds the habit of structuring responses around reasoning, not just syntax. Reviewing Scala questions across difficulty levels also helps specialists calibrate whether they are preparing at the right depth for the role they are targeting.

List of 100 Scala Coding Interview Questions and Answers

The questions are organized into five sections by experience level and question style. Each section starts with five detailed questions that include both a bad and a good answer so you can see common mistakes alongside strong responses. The remaining questions provide a correct answer only for faster review.

Junior Scala Developer Coding Interview Questions

These questions test foundational Scala knowledge: immutability, basic types, pattern matching, and collections. They work well as opening questions for candidates at the entry level. For a broader set of conceptual questions at this level, see our guide on Scala interview questions for freshers.

1: What is the difference between val and var in Scala?

Bad answer: They are interchangeable. val is just a naming convention for constants.

Good answer: val creates an immutable binding that cannot be reassigned. var allows reassignment. Prefer val to reduce side effects and make code easier to reason about.

2: What is a case class in Scala?

Bad answer: A shorter way to write a regular class, nothing more.

Good answer: A case class auto-generates equals, hashCode, toString, copy, and a companion object with apply and unapply. It is designed for immutable data modeling and pattern matching.

3: How does Option work in Scala?

Bad answer: It is like a nullable type. You call .get to retrieve the value.

Good answer: Option wraps a value as Some(x) or None. Use map, flatMap, or getOrElse to handle it safely. Calling .get on None throws an exception and should be avoided.

4: What is pattern matching in Scala?

Bad answer: It is the same as a switch statement in Java.

Good answer: Pattern matching supports type checks, case class destructuring, guard conditions, and nested patterns. With sealed traits the compiler ensures all cases are covered.

5: What are traits in Scala?

Bad answer: Traits are just like Java interfaces.

Good answer: Traits can include abstract and concrete members, hold state, and support mixin composition through linearization. A class can extend multiple traits, enabling a form of multiple inheritance.

6: What is a companion object?

Answer: An object sharing the same name and file as a class. It can access private members and typically holds factory methods.

7: What is the difference between == and eq?

Answer: == calls equals for structural comparison. eq checks reference identity and only works on AnyRef.

8: What is string interpolation?

Answer: Embedding expressions in strings using s”Hello, $name” or f”$price%1.2f” prefixes.

9: What is a sealed trait?

Answer: A trait that can only be extended in the same source file, allowing the compiler to check pattern match exhaustiveness.

10: What does yield do in a for comprehension?

Answer: It collects the results of each iteration into a new collection instead of performing side effects.

11: What is the difference between List and Vector?

Answer: List is optimized for head access and prepend. Vector provides efficient random access and append.

12: What is Unit in Scala?

Answer: The type with only one value, (). It indicates a function returns no meaningful result, similar to void in Java.

13: What is the apply method?

Answer: A method that lets you call an object like a function. obj(x) is rewritten to obj.apply(x) by the compiler.

14: What is the difference between Nil and None?

Answer: Nil is an empty List. None is the empty case of Option.

15: What is a higher-order function?

Answer: A function that takes other functions as parameters or returns a function as its result.

16: What does flatMap do on a collection?

Answer: It applies a function returning a collection to each element, then flattens the results into a single collection.

17: How do you declare a function literal in Scala?

Answer: Using the syntax (x: Int) => x * 2, or the shorthand _ * 2 when the type is known from context.

18: What is lazy val?

Answer: A value computed only on first access and cached for all subsequent reads.

19: What is the difference between throw and Try?

Answer: throw raises an exception that must be caught. Try wraps a computation as Success or Failure for functional error handling.

20: What is an implicit parameter?

Answer: A parameter marked implicit that the compiler supplies automatically from the enclosing scope if not passed explicitly.

21: What is a partial function in Scala?

Answer: A function defined only for a subset of inputs using case blocks inside braces, e.g. { case x if x > 0 => x }.

22: What does the underscore _ mean in Scala?

Answer: It serves many roles: wildcard in imports and pattern matching, placeholder in lambdas, and default initialization.

23: What is Nothing in Scala?

Answer: The bottom type, a subtype of every other type. It has no instances and is the return type of expressions that never complete normally.

24: What are varargs in Scala?

Answer: Declared with a star (def f(args: Int*)), they accept a variable number of arguments passed as a Seq internally.

25: What is the difference between abstract class and trait?

Answer: A class can extend only one abstract class but multiple traits. Abstract classes can have constructor parameters; traits cannot (until Scala 3).

Middle Scala Developer Coding Interview Questions

These Scala coding interview questions target developers with two to five years of experience. They cover implicits, type system features, concurrency, and functional patterns. For additional conceptual depth at this level, explore our collection of middle level Scala interview questions.

1: What are implicits in Scala and how are they resolved?

Bad answer: Implicits are global variables the compiler picks up randomly.

Good answer: Implicit values are resolved through a defined search scope: local scope first, then imports, then companion objects. They power type classes, extension methods, and dependency injection patterns.

2: Explain variance in Scala: covariance, contravariance, and invariance.

Bad answer: Variance is about version compatibility between libraries.

Good answer: Covariance (+T) means Container[Sub] is a subtype of Container[Super]. Contravariance (-T) reverses the relationship. Invariance (T) allows neither. Variance annotations ensure type safety with generics.

3: What is the type class pattern in Scala?

Bad answer: A type class is a class that stores types.

Good answer: A type class defines behavior via a trait that can be implemented for any type through implicit instances, without modifying the original type. This enables ad-hoc polymorphism while keeping concerns separate.

4: How do Futures work in Scala?

Bad answer: A Future blocks the thread until the result is ready.

Good answer: A Future represents an asynchronous computation running on an ExecutionContext. It supports non-blocking composition via map, flatMap, and for comprehensions, and completes with Success or Failure.

5: What is tail recursion and how does Scala support it?

Bad answer: All recursive functions in Scala are automatically optimized.

Good answer: Tail recursion occurs when the recursive call is the last operation. The @tailrec annotation instructs the compiler to verify this and optimize the call into a loop, preventing stack overflow.

6: What is currying in Scala?

Answer: Transforming a function with multiple parameters into a chain of single-parameter functions: def add(a: Int)(b: Int) = a + b.

7: What are self types?

Answer: A self-type annotation (self: Dependency =>) declares that a trait requires another trait to be mixed in, without extending it.

8: What is the Cake Pattern?

Answer: A dependency injection approach using self types and layered traits to wire dependencies at compile time without a framework.

9: What is the difference between def, val, and lazy val in a trait?

Answer: def is evaluated on each call. val is evaluated once at initialization. lazy val is evaluated once on first access.

10: What are path-dependent types?

Answer: Types whose identity depends on the enclosing instance. Two different instances produce incompatible inner types.

11: What is structural typing in Scala?

Answer: Defining a type by its structure (methods and fields) rather than by name, using reflective calls at runtime.

12: How does for comprehension desugar in Scala?

Answer: It translates into calls to map, flatMap, and withFilter. A yield clause uses map; without yield, foreach is called.

13: What is an extractor in Scala?

Answer: An object with an unapply method that enables custom pattern matching beyond case classes.

14: What is the difference between Seq, List, and Array?

Answer: Seq is the general interface. List is an immutable linked list. Array is a mutable, JVM-backed fixed-size structure with O(1) random access.

15: What does the @specialized annotation do?

Answer: It generates separate versions of a generic class for primitive types, avoiding autoboxing overhead.

16: What are type bounds in Scala?

Answer: Upper bounds (T <: A) restrict T to subtypes of A. Lower bounds (T >: A) restrict T to supertypes of A.

17: How do you achieve dependency injection in Scala without a framework?

Answer: Using constructor parameters, the Reader monad, the Cake Pattern, or implicits to pass dependencies at compile time.

18: What is an algebraic data type (ADT) in Scala?

Answer: A composite type defined by a sealed trait (sum type) and case classes (product types). The compiler can verify exhaustive pattern matching on ADTs.

19: What is the difference between map and flatMap on Future?

Answer: map transforms the result inside the Future. flatMap chains another Future-returning operation, flattening nested Future[Future[T]] into Future[T].

20: What is the collect method on collections?

Answer: It applies a partial function, keeping only elements for which the function is defined. It combines filter and map in one step.

21: What is a monad in practical Scala terms?

Answer: A type with flatMap and unit (apply) that supports sequential composition. Option, Future, List, and Try are common examples.

22: What are context bounds?

Answer: A shorthand for implicit parameters: def fT: Ordering expands to def fT(implicit ev: Ordering[T]).

23: What is the difference between foldLeft and foldRight?

Answer: foldLeft processes elements left to right and is tail-recursive on List. foldRight processes right to left and may overflow on large lists.

24: What is a value class in Scala?

Answer: A class extending AnyVal that wraps a single value. The compiler removes the wrapper at runtime, avoiding heap allocation.

25: What is the difference between a class and an object in Scala?

Answer: A class is a blueprint for instances. An object is a singleton, instantiated once and accessible globally within its scope.

Senior Scala Developer Coding Interview Questions

These Scala coding interview questions for experienced engineers cover effect systems, type-level programming, and architecture decisions. They are designed for candidates with five or more years of production Scala work. For broader preparation at this level, see our list of Scala interview questions for experienced.

1: How would you design a type-safe builder pattern in Scala?

Bad answer: Use a mutable builder class with setters like in Java.

Good answer: Use phantom types or tagged type parameters to track which fields have been set at compile time. The build method becomes available only when all required fields carry a Set type tag, preventing incomplete construction.

2: Explain the differences between Cats Effect and ZIO.

Bad answer: They do the same thing, just with different syntax.

Good answer: Cats Effect provides a lightweight IO monad with tagless final style. ZIO bundles environment, error, and result into ZIO[R, E, A], offering built-in dependency injection, typed errors, and fiber-based concurrency without tagless final.

3: How does Scala 3 handle implicits differently from Scala 2?

Bad answer: Scala 3 removed implicits entirely.

Good answer: Scala 3 replaces implicit with given and using for clearer intent, introduces extension methods as a first-class construct, and adds context functions. The resolution rules remain similar, but the syntax reduces ambiguity.

4: What are opaque types in Scala 3 and when would you use them?

Bad answer: They are just type aliases with a different name.

Good answer: Opaque types create a distinct type at compile time that erases to the underlying type at runtime. They provide zero-cost abstraction for newtypes, preventing accidental misuse without boxing overhead.

5: How do you handle error management in a large Scala application?

Bad answer: Catch all exceptions at the top level and log them.

Good answer: Model errors as an ADT within a sealed trait hierarchy and propagate them through Either or a typed effect like ZIO[R, AppError, A]. Reserve exceptions for truly unrecoverable failures and keep business errors explicit in function signatures.

6: What is tagless final encoding?

Answer: A pattern abstracting over the effect type using type constructors and type class constraints, allowing swapping implementations without changing business logic.

7: What are higher-kinded types?

Answer: Types parameterized by type constructors (F[_]) rather than concrete types, enabling abstractions like Functor, Monad, and Applicative.

8: What is the free monad pattern?

Answer: It separates program description from interpretation by building an AST of operations that can be run against different interpreters.

9: How does type erasure affect Scala on the JVM?

Answer: Generic type arguments are removed at runtime. Use ClassTag or TypeTag to preserve type information when needed.

10: What is the Aux pattern?

Answer: A technique using a type member and a type alias in the companion object to expose dependent types, commonly used with Shapeless.

11: What are phantom types?

Answer: Type parameters never instantiated at runtime. They carry compile-time information to enforce constraints without runtime overhead.

12: How does Scala implement tail call optimization?

Answer: The compiler converts tail-recursive methods into loops in bytecode. It only works for self-recursive methods, not mutual recursion.

13: What is typeclass derivation in Scala 3?

Answer: A mechanism that automatically generates typeclass instances for ADTs using the derives keyword and the Mirror type.

14: How would you implement a GADT in Scala?

Answer: Using a sealed trait with type parameters and case classes that fix those parameters, enabling the compiler to narrow types in pattern match branches.

15: What is the Reader monad used for?

Answer: Passing shared read-only configuration or dependencies through a computation without explicit parameter threading.

16: What are union and intersection types in Scala 3?

Answer: Union (A | B) means a value is one of the listed types. Intersection (A & B) means it has all members of both types.

17: What is the difference between cats.effect.IO and Scala.concurrent.Future?

Answer: IO is lazy and referentially transparent, doing nothing until explicitly run. Future is eager, starts immediately upon creation, and caches the result.

18: How do you ensure thread safety in Scala?

Answer: Use immutable data structures, actors (Akka/Pekko), Ref from Cats Effect or ZIO, or STM for composable transactions.

19: What is a fiber in Scala effect systems?

Answer: A lightweight virtual thread managed by the effect runtime. Fibers enable structured concurrency with millions of concurrent tasks on a small thread pool.

20: How does match type work in Scala 3?

Answer: A type-level pattern match that computes a result type based on the input type, enabling type-level programming without macros.

21: What is inline in Scala 3?

Answer: A modifier guaranteeing the compiler inlines the definition at each call site, enabling compile-time evaluation and metaprogramming.

22: What is the difference between a type alias and an opaque type?

Answer: A type alias is fully transparent; the compiler treats it as its underlying type everywhere. An opaque type is distinct at compile time, preventing unintended substitution.

23: How do you manage resource lifecycle in Scala?

Answer: Use Resource from Cats Effect or Scope from ZIO, which guarantee acquisition and release even on error or cancellation.

24: What is the difference between IO and Task?

Answer: IO (Cats Effect) tracks side effects in a pure value. Task (Monix/ZIO) adds features like cancelation and scheduling. Both defer execution until explicitly run.

25: What is the difference between structural and nominal typing?

Answer: Nominal typing identifies types by name (default in Scala). Structural typing identifies them by shape, using reflection at runtime.

Explore Available Opportunities from Top Companies

Browse All Jobs

Practice-Based Scala Developer Coding Questions

These Scala coding practice questions move beyond theory and ask candidates to write or describe implementations. They test whether the candidate can translate concepts into working code.

1: Write a function that reverses a list without using the built-in reverse method.

Bad answer: Use a var and a while loop to swap elements in place.

Good answer: Use tail recursion with an accumulator: match on the list, prepend each head to the accumulator, and recurse on the tail. This is stack-safe and purely functional.

2: Implement a function that checks whether a string is a palindrome.

Bad answer: Convert to a char array, loop with indices, compare from both ends using mutable state.

Good answer: Compare the string to its reverse using s == s.reverse. For a custom approach, recurse: a single-char or empty string is a palindrome; otherwise check first and last characters, then recurse on the inner substring.

3: Write a function to flatten a nested list structure.

Bad answer: Use casting and mutable buffers to iterate through levels manually.

Good answer: Use pattern matching and recursion: match each element as either a List (recurse) or a value (wrap in List), then concatenate with flatMap. This handles arbitrary nesting depth.

4: Implement a simple memoization wrapper for a function.

Bad answer: Use a global mutable HashMap and synchronize access everywhere.

Good answer: Return a new function wrapping a private mutable.Map. On each call, check the map first; if absent, compute the result, store it, and return it. For thread safety, use a concurrent map.

5: Write a function that groups consecutive duplicate elements of a list.

Bad answer: Use index-based loops and mutable accumulators.

Good answer: Use span: match on the list, split off elements equal to the head, collect them as a group, and recurse on the remainder. This is concise and avoids mutation.

6: Implement a stack using an immutable List.

Answer: Use a case class wrapping a List. Push prepends an element. Pop returns the head and a new stack with the tail.

7: Write a tail-recursive function for the nth Fibonacci number.

Answer: Use two accumulators: @tailrec def fib(n: Int, a: BigInt = 0, b: BigInt = 1): BigInt = if (n <= 0) a else fib(n – 1, b, a + b).

8: Implement a basic binary search on a sorted Vector.

Answer: Compare the target to the middle element, recurse on the left or right half, and return the index wrapped in Option.

9: Write a function that transposes a matrix represented as a List of Lists.

Answer: Use List.transpose, or implement it by mapping the head of each row and recursing on the tails.

10: Implement FizzBuzz using pattern matching.

Answer: (1 to 100).map { case n if n % 15 == 0 => “FizzBuzz”; case n if n % 3 == 0 => “Fizz”; case n if n % 5 == 0 => “Buzz”; case n => n.toString }.

11: Write a function to find the second-largest element in a list.

Answer: Sort the distinct elements in descending order and take the second, or fold through the list tracking the top two values.

12: Implement run-length encoding for a list.

Answer: Group consecutive duplicates with span, then map each group to a tuple of (element, count).

13: Write a function to merge two sorted lists into one sorted list.

Answer: Pattern match both lists, compare heads, prepend the smaller one, and recurse on the remainder.

14: Implement Either-based validation that accumulates errors.

Answer: Use a custom combine function or the Validated type from Cats to collect all errors instead of short-circuiting on the first.

15: Write a generic function to group a List into a Map by a key function.

Answer: Use groupBy: def toMapA, K(f: A => K): Map[K, List[A]] = xs.groupBy(f).

Tricky Scala Developer Coding Questions

These questions expose edge cases and surprising behavior in Scala. They test whether a candidate understands what happens beneath common abstractions.

1: What is the output of List(1, 2, 3).zip(List(“a”, “b”))? Why?

Bad answer: It throws an exception because the lists have different lengths.

Good answer: It returns List((1, “a”), (2, “b”)). zip pairs elements by position and silently drops extras from the longer list. Use zipAll to include all elements with default values.

2: What happens when you define a val in a trait and override it in a subclass?

Bad answer: It works like a regular variable assignment.

Good answer: The trait’s val initializer runs during construction, before the subclass override is assigned, resulting in null or zero. This is the initialization order problem. Use lazy val or def in the trait to avoid it.

3: How many intermediate collections does (1 to 5).map(_ + 1).filter(_ % 2 == 0).sum create?

Bad answer: One collection is created and reused throughout the chain.

Good answer: Two intermediate collections are created: one from map and one from filter, before sum. Using .view before the chain or LazyList avoids these allocations by fusing the operations.

4: Why does comparing Arrays with == return false even if they have the same elements?

Bad answer: Scala does not support array comparison.

Good answer: Array is a JVM array, and == on AnyRef checks reference identity by default. Use sameElements for element-wise comparison: arr1.sameElements(arr2), or convert to Seq first.

5: What happens if two implicits of the same type are in scope?

Bad answer: The compiler picks the first one it finds.

Good answer: The compiler reports an ambiguous implicit error and refuses to compile. To resolve it, remove one implicit, make one more specific so resolution can prioritize it, or place them in different scopes.

6: What is the difference between :+ and +: on collections?

Answer: :+ appends an element to the end. +: prepends to the beginning. The colon side faces the collection.

7: Why does var x: Int = _ compile but val x: Int = _ does not?

Answer: The underscore initializer sets a var to its default value (0 for Int, null for references). It requires mutability since the value is meant to be assigned later.

8: What does Stream.from(1) return and why should you use LazyList instead?

Answer: It returns an infinite stream of integers. Stream memoizes all computed elements, risking memory leaks. LazyList (Scala 2.13+) can discard computed values.

9: Can a case class extend another case class?

Answer: No. Case-to-case inheritance is prohibited because it breaks the auto-generated equals and copy contracts. Use a sealed trait with separate case classes instead.

10: What happens when you shadow a variable name inside a nested scope?

Answer: The inner binding hides the outer one within its scope. This is legal and does not produce a compilation error by default, but it can cause subtle bugs.

Tips for Scala Coding Interview Preparation for Candidates

Working through a list of Scala coding interview questions is a strong start, but preparation goes further than memorizing answers.

• Practice explaining your reasoning out loud. Interviewers evaluate how you think, not just what you know.

• Write actual code in a REPL or IDE for every concept you review. Reading about pattern matching is not the same as writing it.

• Study the bad answers in this guide as carefully as the good ones. Recognizing common misconceptions helps you avoid them under pressure.

• Focus on the level that matches the role. Reviewing senior-level effect system questions will not help if the interview targets foundational knowledge.

• Review Scala-specific idioms like Option handling, for comprehensions, and ADTs. These come up far more often than algorithmic puzzles in Scala interviews.

Conclusion

Scala interviews reward candidates who can connect language features to real design decisions. Use these 100 questions to build that connection, practice explaining trade-offs out loud, and walk into the interview ready to show how you think, not just what you have memorized.

The post 100 Scala Coding Interview Questions and Answers first appeared on Jobs With Scala.

Top comments (0)