InterviewPitch
Scala interview questions

Scala Interview Questions with Answers

Most Asked Scala Interview Questions for Software Engineer Roles

100+ QuestionsDetailed AnswersCode ExamplesUpdated for 2026

Introduction

Scala is a high‑performance language that seamlessly blends object‑oriented and functional programming. This page collects the most frequently asked Scala interview questions – from basic syntax and collections to advanced type system, implicits, concurrency, and integration with the JVM ecosystem – essential for any backend, big data, or functional programmer.

Why Scala?

  • Combines OOP and functional programming on the JVM
  • Powerful type system with inference and generics
  • Immutable data structures and functional transformations
  • Industry adoption in big data (Spark, Kafka, Akka)
  • Full interoperability with Java libraries and tooling
  • Expressive syntax that reduces boilerplate

Most Asked Scala Interview Questions

Beginner
1. What is Scala?

Scala is a modern multi-paradigm programming language designed to express common programming patterns in a concise, elegant, and type-safe way.

  • Functional: Functions are first-class citizens
  • Object-oriented: Every value is an object
  • Type-safe: Strong static type system
  • JVM compatible: Runs on Java Virtual Machine
  • Concurrent: Built-in support for concurrency
scala
// Hello World in Scala
object HelloWorld {
  def main(args: Array[String]): Unit = {
    println("Hello, World!")
  }
}

// Or using App trait
object HelloWorld extends App {
  println("Hello, World!")
}
Beginner
2. How to declare variables in Scala?

Variables in Scala are declared using val for immutable values and var for mutable variables.

  • Immutable: val x = 10
  • Mutable: var y = 20
  • Type inference: Types are inferred automatically
  • Type annotation: val x: Int = 10
  • Lazy: lazy val z = expensive()
scala
// Variables in Scala
// Immutable variable (val)
val x: Int = 10
val y: Double = 3.14
val name: String = "Scala"
val isActive: Boolean = true

// Mutable variable (var)
var counter: Int = 0
counter = 1

// Type inference
val a = 10          // Int
val b = 3.14        // Double
val c = "Scala"     // String
val d = true        // Boolean

println(x)
println(y)
println(name)
println(isActive)
Beginner
3. What are the data types in Scala?

Scala has a rich type system with both value types and reference types, all unified under the Any type.

  • Numeric: Int, Long, Double, Float
  • Boolean: Boolean
  • String: String
  • Char: Char
  • Unit: Unit (void)
  • Any: Top type
  • Nothing: Bottom type
  • Option: Option[T]
  • Tuple: (Int, String)
  • List: List[Int]
scala
// Data Types in Scala
// Integer types
val a: Int = 10
val b: Long = 100L
val c: Short = 127
val d: Byte = 127

// Floating point
val e: Double = 3.14
val f: Float = 2.5f

// String
val g: String = "Hello Scala"

// Boolean
val h: Boolean = true
val i: Boolean = false

// Char
val j: Char = 'A'

// Unit (void)
val k: Unit = ()

// Any (top type)
val l: Any = 42
val m: Any = "Hello"

// Nothing (bottom type)
// val n: Nothing = ???

// Null
val o: String = null

// Option
val p: Option[Int] = Some(42)
val q: Option[Int] = None

// Tuple
val r: (Int, String, Double) = (1, "hello", 3.14)

// List
val s: List[Int] = List(1, 2, 3, 4, 5)

// Map
val t: Map[String, Int] = Map("Scala" -> 3, "Java" -> 8)

println(a.getClass)
println(e.getClass)
Beginner
4. How to define functions in Scala?

Functions in Scala are defined using the def keyword, with support for default parameters, type inference, and higher-order functions.

  • Function declaration: def add(a: Int, b: Int): Int = a + b
  • Default parameters: def greet(name: String = "Guest")
  • Anonymous functions: (x: Int) => x * 2
  • Currying: def add(a: Int)(b: Int) = a + b
  • Variable arguments: def sum(numbers: Int*) = numbers.sum
scala
// Functions in Scala
// Function declaration
def add(a: Int, b: Int): Int = {
  return a + b
}

// One-line function
def subtract(a: Int, b: Int): Int = a - b

// Function with default parameters
def greet(name: String = "Guest"): String = {
  s"Hello, $name!"
}

// Anonymous function (lambda)
val square: Int => Int = (x: Int) => x * x
val double: Int => Int = _ * 2

// Higher-order function
def applyTwice(f: Int => Int, x: Int): Int = f(f(x))

// Function with multiple parameter lists (currying)
def addCurried(a: Int)(b: Int): Int = a + b

// Function with variable arguments
def sumAll(numbers: Int*): Int = numbers.sum

// Function with named arguments
def createPerson(name: String, age: Int = 0, city: String = "Unknown"): String = {
  s"$name ($age) from $city"
}

// Partial function
val partialAdd: Int => Int = addCurried(5)

// Usage
println(add(5, 3))
println(subtract(10, 4))
println(greet("Alice"))
println(square(4))
println(applyTwice(_ * 2, 5))
println(addCurried(5)(3))
println(sumAll(1, 2, 3, 4, 5))
println(createPerson("Alice", age = 25, city = "NYC"))
Beginner
5. What are lists in Scala?

Lists are immutable, homogeneous collections in Scala. They are constructed using List and :: (cons) operators.

  • Creation: List(1, 2, 3, 4, 5)
  • Cons: 0 :: List(1, 2, 3)
  • Concatenation: List(1, 2) ++ List(3, 4)
  • Functions: map, filter, reduce
  • Pattern matching: case head :: tail => ...
scala
// Lists in Scala
val arr: List[Int] = List(1, 2, 3, 4, 5)

// Map - transform each element
val doubled: List[Int] = arr.map(_ * 2)
println(doubled)

// Filter - select elements
val evens: List[Int] = arr.filter(_ % 2 == 0)
println(evens)

// Reduce - aggregate
val sum: Int = arr.reduce(_ + _)
println(sum)

// Fold - aggregate with initial value
val sumFold: Int = arr.foldLeft(0)(_ + _)

// List comprehension (for-comprehension)
val squares: List[Int] = for (x <- 1 to 10) yield x * x
println(squares)

// Push and prepend
val newList: List[Int] = 6 :: arr
println(newList)
val popped: List[Int] = arr.dropRight(1)
println(popped)

// List operations
val a: List[Int] = List(1, 2, 3)
val b: List[Int] = List(4, 5, 6)
val c: List[Int] = a ++ b  // Concatenation
println(c)
Beginner
6. What are maps in Scala?

Maps in Scala are immutable key-value pairs, similar to dictionaries. They provide efficient lookup and operations.

  • Creation: Map("name" -> "Alice", "age" -> 25)
  • Access: map("name")
  • Add/Update: map + ("country" -> "USA")
  • Keys/Values: map.keys, map.values
  • Get with default: map.getOrElse("key", "default")
scala
// Maps (Dictionaries) in Scala
// Create map
val person: Map[String, Any] = Map(
  "name" -> "Alice",
  "age" -> 25,
  "city" -> "NYC"
)

// Access values
println(person("name"))
println(person.get("age"))

// Get with default
val city: String = person.getOrElse("city", "Unknown")

// Add/update values (immutable)
val updatedPerson: Map[String, Any] = person + ("country" -> "USA")
val updatedAge: Map[String, Any] = updatedPerson + ("age" -> 26)

// Keys and values
println(person.keys)
println(person.values)

// Iterate over map
for ((key, value) <- person) {
  println(s"$key: $value")
}

// Delete key
val withoutCountry: Map[String, Any] = updatedPerson - "country"

// Check if key exists
println(person.contains("name"))

// Map comprehension
val squares: Map[Int, Int] = (1 to 5).map(i => i -> (i * i)).toMap
println(squares)
Beginner
7. What are tuples in Scala?

Tuples are immutable containers that can hold a fixed number of elements of different types.

  • Creation: (1, "hello", 3.14)
  • Access: tuple._1
  • Pattern matching: case (a, b, c) =>
  • Named tuples: Use case classes
  • Function return: Multiple values
scala
// Tuples in Scala
// Create tuple
val t: (Int, String, Double, Boolean) = (1, "hello", 3.14, true)

// Access elements
println(t._1)
println(t._2)

// Pattern matching to extract
val (a, b, c, d) = t
println(a, b, c, d)

// Named tuple (using case class)
case class Person(name: String, age: Int, city: String)
val alice: Person = Person("Alice", 25, "NYC")
println(alice.name)
println(alice.age)

// Function returning multiple values
def divide(a: Int, b: Int): (Int, Int) = (a / b, a % b)
val (quotient, remainder) = divide(10, 3)
println(s"Quotient: $quotient, Remainder: $remainder")

// Tuple concatenation
val t1: (Int, Int) = (1, 2)
val t2: (Int, Int) = (3, 4)
val t3: (Int, Int, Int, Int) = (t1._1, t1._2, t2._1, t2._2)
println(t3)
Beginner
8. What are control flow statements in Scala?

Scala provides standard control flow statements including conditionals, loops, and powerful pattern matching.

  • If-else: if (condition) ... else ...
  • For loops: for (i <- 1 to 10) { ... }
  • For comprehensions: for (x <- list) yield x * 2
  • While loops: while (condition) { ... }
  • Pattern matching: value match { case 0 => ... }
scala
// Control Flow in Scala
// If-else statement
val age: Int = 25
val status: String = if (age < 18) "Minor"
  else if (age < 65) "Adult"
  else "Senior"
println(status)

// For loop
for (i <- 1 to 5) {
  println(i)
}

// For loop with collection
val fruits: List[String] = List("apple", "banana", "orange")
for (fruit <- fruits) {
  println(fruit)
}

// For comprehension
val doubled: List[Int] = for (i <- 1 to 10) yield i * 2
println(doubled)

// While loop
var i: Int = 1
while (i <= 5) {
  println(i)
  i += 1
}

// Do-while loop
var j: Int = 1
do {
  println(j)
  j += 1
} while (j <= 5)

// Break and continue (using breakable)
import scala.util.control.Breaks._
breakable {
  for (i <- 1 to 10) {
    if (i == 6) break
    if (i % 2 == 0) {
      // continue - just don't execute rest of loop body
      // Scala doesn't have continue, use if guard instead
    }
    println(i)
  }
}

// Pattern matching (powerful control flow)
val number: Int = 2
number match {
  case 0 => println("Zero")
  case 1 => println("One")
  case 2 => println("Two")
  case _ => println("Other")
}
Beginner
9. What are comprehensions in Scala?

For-comprehensions in Scala provide a powerful way to work with collections and monads, similar to list comprehensions in other languages.

  • For-comprehension: for (x <- 1 to 10) yield x * x
  • Filtering: for (x <- 1 to 20 if x % 2 == 0) yield x
  • Nested: for (i <- 1 to 3; j <- 1 to 3) yield (i, j)
  • Map comprehension: (1 to 5).map(i => i -> i*i).toMap
  • Lazy: LazyList.from(1).map(_ * 2)
scala
// Comprehensions in Scala
// For-comprehension
val squares: List[Int] = for (x <- 1 to 10) yield x * x
println(squares)

// Filter in comprehension
val evens: List[Int] = for {
  x <- 1 to 20
  if x % 2 == 0
} yield x
println(evens)

// Nested comprehension
val pairs: List[(Int, Int)] = for {
  i <- 1 to 3
  j <- 1 to 3
} yield (i, j)
println(pairs)

// Map comprehension
val squareMap: Map[Int, Int] = (1 to 5).map(i => (i, i * i)).toMap
println(squareMap)

// Generator expression (lazy)
val lazySquares: LazyList[Int] = LazyList.from(1).map(x => x * x)
println(lazySquares.take(10).toList)

// Conditional comprehension
val results: List[String] = for (x <- 1 to 10) yield {
  if (x % 2 == 0) "even" else "odd"
}
println(results)
Beginner
10. How to work with strings in Scala?

Scala provides rich string manipulation capabilities using Java's String class and additional Scala features.

  • Concatenation: "Hello" + " World"
  • Interpolation: s"Welcome to $name"
  • f-interpolation: f"Value: 3.14%.2f"
  • Functions: length, toUpperCase, replace
  • Split/Join: split, mkString
scala
// Strings in Scala
// String creation
val str1: String = "Hello"
val str2: String = "World"
val str3: String = """Multi-line
string"""

// String concatenation
val greeting: String = str1 + " " + str2
println(greeting)

// String interpolation
val name: String = "Scala"
val version: Double = 2.13
println(s"Welcome to $name version $version")

// f-interpolation (formatting)
println(f"Value: 3.14159%.2f")

// String functions
val text: String = "Hello, World!"
println(text.length)
println(text.toUpperCase)
println(text.toLowerCase)
println(text.replace("World", "Scala"))

// Substring
println(text.substring(0, 5))

// Split and join
val words: Array[String] = "Hello World Scala".split(" ")
println(words.mkString(", "))
val joined: String = words.mkString("-")
println(joined)

// String comparison
println("hello" == "hello")
println("hello".compareTo("world") < 0)

// String formatting
println("%.2f".format(3.14159))
Beginner
11. What are packages in Scala?

Packages in Scala organize code into namespaces and provide modularity, similar to Java packages.

  • Definition: package com.example
  • Nested packages: package com.example.math
  • Import: import com.example.math.MathUtils
  • Wildcard import: import com.example.math._
  • Renaming: import com.example.math.{MathUtils => Math}
scala
// Packages and Imports in Scala
// Defining a package
package com.example {
  package math {
    object MathUtils {
      val PI: Double = 3.14159
      
      def add(a: Int, b: Int): Int = a + b
      def subtract(a: Int, b: Int): Int = a - b
    }
  }
}

// Using imported items
import com.example.math.MathUtils

println(MathUtils.PI)
println(MathUtils.add(5, 3))
println(MathUtils.subtract(10, 4))

// Importing multiple items
import com.example.math.MathUtils.{add, subtract, PI}

// Importing everything
import com.example.math.MathUtils._

// Renaming imports
import com.example.math.MathUtils.{add => addNumbers, PI => PiValue}

// Importing with alias
import com.example.math.{MathUtils => Math}

println(Math.add(5, 3))
println(Math.PI)

// Package object
package object utils {
  def log(message: String): Unit = println(s"LOG: $message")
}

// Using package object
import utils.log
log("Application started")

// Importing from Java
import java.util.{ArrayList, HashMap}
import java.io.{File, FileWriter}

// Importing from Scala standard library
import scala.collection.mutable.{ArrayBuffer, HashMap => MutableHashMap}
Beginner
12. What are classes in Scala?

Classes in Scala are blueprints for objects, supporting both functional and object-oriented programming paradigms.

  • Class definition: class Person(val name: String, var age: Int)
  • Case classes: case class Person(name: String, age: Int)
  • Singleton objects: object Person
  • Abstract classes: abstract class Animal
  • Traits: trait SoundMaker
scala
// Classes and Types in Scala
// Abstract class
abstract class Animal {
  val name: String
  val age: Int
  
  def makeSound(): String
}

// Case class (immutable)
case class Dog(name: String, age: Int) extends Animal {
  def makeSound(): String = "Woof!"
}

// Regular class
class Person(val name: String, var age: Int, val city: String = "Unknown") {
  def greet(): String = s"Hello, I'm $name"
  
  def haveBirthday(): Unit = {
    age += 1
  }
}

// Singleton object (companion)
object Person {
  def apply(name: String, age: Int): Person = new Person(name, age)
}

// Case class with additional methods
case class Cat(name: String, age: Int) extends Animal {
  def makeSound(): String = "Meow!"
}

// Usage
val dog: Dog = Dog("Rex", 3)
val cat: Cat = Cat("Whiskers", 2)
val person: Person = Person("Alice", 25)

println(dog.makeSound())
println(cat.makeSound())
println(person.greet())
person.haveBirthday()
println(s"Age: ${person.age}")
Intermediate
13. What is the type system in Scala?

Scala has a powerful, expressive type system that combines object-oriented and functional programming features.

  • Type inference: val x = 42
  • Type annotations: val x: Int = 42
  • Generic types: class Box[A]
  • Type bounds: [A <: AnyRef]
  • Type aliases: type IntList = List[Int]
scala
// Type System in Scala
// Type declarations
def describe(x: Int): String = s"Integer: $x"
def describe(x: Double): String = s"Double: $x"
def describe(x: String): String = s"String: $x"

// Generic types
class Box[A](val value: A) {
  def get: A = value
  def map[B](f: A => B): Box[B] = new Box(f(value))
}

// Type parameters
def identity[A](x: A): A = x

// Type bounds
class Container[A <: AnyRef](val value: A)

// Upper bound
def processNumbers[A <: Number](x: A): Double = x.doubleValue()

// Lower bound
def appendToList[A >: String](list: List[A], item: A): List[A] = list :+ item

// Type variance
class Covariant[+A]  // Covariant
class Contravariant[-A]  // Contravariant
class Invariant[A]  // Invariant

// Type aliases
type IntList = List[Int]
type StringMap = Map[String, String]

// Self type
trait Logger { self: AnyRef =>
  def log(msg: String): Unit = println(s"LOG: $msg")
}

// Usage
describe(42)
describe(3.14)
describe("Hello")

val box: Box[Int] = new Box(42)
val mapped: Box[String] = box.map(_.toString)

identity(5)
identity("Hello")

// Type checking
val isInt: Boolean = 42.isInstanceOf[Int]
val intValue: Int = 42.asInstanceOf[Int]
Intermediate
14. How to handle exceptions in Scala?

Scala provides both traditional try-catch blocks and functional error handling with Try, Either, and Option.

  • Try-catch: try { ... } catch { case e: Exception => ... }
  • Try: Try(expression)
  • Either: Either[String, Int]
  • Option: Some(value) or None
  • Finally: try { ... } finally { ... }
scala
// Exception Handling in Scala
// Try-catch block
import scala.util.{Try, Success, Failure}

try {
  // Code that might error
  val result = 10 / 0
  println(result)
} catch {
  case e: ArithmeticException => 
    println(s"Arithmetic error: ${e.getMessage}")
  case e: Exception => 
    println(s"Other error: ${e.getMessage}")
} finally {
  println("Cleanup performed")
}

// Specific error handling
try {
  val arr = Array(1, 2, 3)
  println(arr(10))
} catch {
  case e: ArrayIndexOutOfBoundsException =>
    println("Index out of bounds!")
  case e: Exception =>
    println(s"Other error: ${e.getMessage}")
}

// Using Try (functional error handling)
def divide(a: Int, b: Int): Try[Int] = Try(a / b)

val result1: Try[Int] = divide(10, 2)
val result2: Try[Int] = divide(10, 0)

result1 match {
  case Success(value) => println(s"Result: $value")
  case Failure(e) => println(s"Error: ${e.getMessage}")
}

result2 match {
  case Success(value) => println(s"Result: $value")
  case Failure(e) => println(s"Error: ${e.getMessage}")
}

// Using Either for error handling
def safeDivide(a: Int, b: Int): Either[String, Int] = {
  if (b == 0) Left("Cannot divide by zero")
  else Right(a / b)
}

safeDivide(10, 2) match {
  case Right(value) => println(s"Result: $value")
  case Left(error) => println(s"Error: $error")
}

// Throwing exceptions
def validateInput(x: Int): Int = {
  if (x < 0) throw new IllegalArgumentException("Input must be non-negative")
  x
}

// Custom exception
class MyException(message: String) extends Exception(message)

// Using Option for nullable values
def toInt(s: String): Option[Int] = {
  try {
    Some(s.toInt)
  } catch {
    case _: NumberFormatException => None
  }
}
Intermediate
15. How to work with files in Scala?

Scala uses Java's I/O libraries, with additional convenience methods from Scala's standard library.

  • Read: Source.fromFile("file.txt").mkString
  • Line by line: Source.fromFile("file.txt").getLines()
  • Write: new PrintWriter("file.txt").write("content")
  • Append: new PrintWriter(new FileWriter("file.txt", true))
  • CSV: Manual parsing or libraries
scala
// File I/O in Scala
import scala.io.Source
import java.io.{PrintWriter, File}

// Reading files
try {
  val source = Source.fromFile("example.txt")
  val content = source.mkString
  println(content)
  source.close()
} catch {
  case e: Exception => println(s"File not found: ${e.getMessage}")
}

// Reading line by line
try {
  val source = Source.fromFile("data.txt")
  for (line <- source.getLines()) {
    println(line)
  }
  source.close()
} catch {
  case e: Exception => println(s"Error reading file: ${e.getMessage}")
}

// Writing files
val writer = new PrintWriter(new File("output.txt"))
writer.write("Hello, World!\n")
writer.write("This is line 2\n")
writer.close()

// Appending to files
val appendWriter = new PrintWriter(new FileWriter("output.txt", true))
appendWriter.write("Appended line\n")
appendWriter.close()

// Reading CSV (using Scala's standard library)
val csvSource = Source.fromFile("data.csv")
val rows = csvSource.getLines().map(_.split(",")).toList
rows.foreach(row => println(row.mkString(", ")))
csvSource.close()

// Writing CSV
val data = List(
  List("Name", "Age", "City"),
  List("Alice", "25", "NYC"),
  List("Bob", "30", "LA")
)
val csvWriter = new PrintWriter(new File("output.csv"))
data.foreach(row => csvWriter.println(row.mkString(",")))
csvWriter.close()

// Using Scala's better-files (requires library)
// import better.files._
// val content = file"example.txt".contentAsString
// file"output.txt".write("Hello, World!")
Intermediate
16. How to use packages in Scala?

Scala uses sbt (Simple Build Tool) as the primary build tool with Maven Central for package management.

  • sbt: build.sbt file
  • Library dependencies: libraryDependencies += "org.typelevel" %% "cats-core" % "2.9.0"
  • Add packages: sbt add package-name
  • Import: import package.name
  • Ammonite: import $ivy.`org.typelevel::cats-core:2.9.0`
scala
// Packages and Build Tools in Scala
// build.sbt (Simple Build Tool)
/*
name := "my-project"
version := "1.0"
scalaVersion := "2.13.10"

libraryDependencies ++= Seq(
  "org.typelevel" %% "cats-core" % "2.9.0",
  "org.scalatest" %% "scalatest" % "3.2.15" % Test
)
*/

// Using packages in code
import cats._
import cats.implicits._

// Using Akka
// import akka.actor._

// Using Play Framework
// import play.api.libs.json._

// Using Spark
// import org.apache.spark.SparkContext

// Using Slick for database
// import slick.jdbc.PostgresProfile.api._

// Using ScalaTest for testing
/*
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers

class MySpec extends AnyFlatSpec with Matchers {
  "A calculator" should "add two numbers" in {
    assert(2 + 2 == 4)
  }
}
*/

// Using Ammonite (REPL)
// $ ammonite
// @ import $ivy.`org.typelevel::cats-core:2.9.0`

// Using sbt commands
// sbt compile
// sbt run
// sbt test
// sbt assembly (for fat JAR)

// Using Mill as alternative build tool
// build.mill
/*
import mill._, scalalib._
object myproject extends ScalaModule {
  def scalaVersion = "2.13.10"
}
*/
Intermediate
17. How to create plots in Scala?

Scala supports plotting through libraries like Plotly-Scala, JFreeChart, and Vegas.

  • Plotly-Scala: Scatter(x, y, mode = ScatterMode.Lines)
  • Vegas: Vegas("Chart").mark(Bar).show
  • JFreeChart: Java library integration
  • Wisp: Plotly for Scala.js
  • Apache Commons Math: Data generation
scala
// Plotting in Scala
// Using Plotly-Scala
// libraryDependencies += "org.plotly-scala" %% "plotly-render" % "0.8.4"

/*
import plotly._
import plotly.element._
import plotly.layout._

val x = Seq(1, 2, 3, 4, 5)
val y = Seq(1, 4, 9, 16, 25)

val trace = Scatter(x, y, mode = ScatterMode.LinesMarkers)
val layout = Layout(title = "Square Function")
Plotly.plot("plot.html", trace, layout)
*/

// Using JFreeChart
// import org.jfree.chart.ChartFactory
// import org.jfree.chart.plot.PlotOrientation
// import org.jfree.data.xy.XYSeriesCollection
// import org.jfree.data.xy.XYSeries

// Using Vegas (Vega-Lite wrapper)
// libraryDependencies += "org.vegas-viz" %% "vegas" % "0.3.11"
/*
import vegas._

val data = Seq(
  ("A", 1), ("B", 2), ("C", 3), ("D", 4), ("E", 5)
)

Vegas("Bar Chart")
  .withData(data)
  .mark(Bar)
  .encodeX("_1", nom)
  .encodeY("_2", quant)
  .show
*/

// Using Wisp (plotly for Scala.js)
// libraryDependencies += "com.quantifind" %% "wisp" % "0.0.4"

// Using Scala-Plot (simple plotting)
// libraryDependencies += "com.github.tototoshi" %% "scala-plot" % "0.2.0"

// Using Apache Commons Math for data generation
// libraryDependencies += "org.apache.commons" % "commons-math3" % "3.6.1"
Intermediate
18. What are data structures in Scala?

Scala provides both immutable and mutable data structures in its standard library.

  • Immutable: List, Vector, Set, Map
  • Mutable: ArrayBuffer, mutable.ListBuffer
  • Stack: mutable.ArrayStack
  • Queue: mutable.Queue
  • Array: Array (Java compatible)
scala
// Data Structures in Scala
// Immutable collections
val list = List(1, 2, 3, 4, 5)
val vector = Vector(1, 2, 3, 4, 5)
val set = Set(1, 2, 3, 4, 5)
val map = Map("a" -> 1, "b" -> 2, "c" -> 3)

// Mutable collections
import scala.collection.mutable
val mutableList = mutable.ListBuffer(1, 2, 3)
mutableList += 4

val mutableSet = mutable.Set(1, 2, 3)
mutableSet += 4

val mutableMap = mutable.Map("a" -> 1, "b" -> 2)
mutableMap("c") = 3

// Stack (using ListBuffer or ArrayStack)
val stack = mutable.ArrayStack[Int]()
stack.push(1)
stack.push(2)
stack.push(3)
val popped = stack.pop()

// Queue
val queue = mutable.Queue[Int]()
queue.enqueue(1)
queue.enqueue(2)
queue.enqueue(3)
val dequeued = queue.dequeue()

// Array
val array = Array(1, 2, 3, 4, 5)
array(0) = 10

// ArrayBuffer
val arrayBuffer = mutable.ArrayBuffer(1, 2, 3)
arrayBuffer += 4
arrayBuffer.append(5)

// Map operations
val updatedMap = map + ("d" -> 4)
val withoutA = map - "a"

// Set operations
val union = set ++ Set(6, 7, 8)
val intersect = set & Set(2, 3, 4)

// List operations
val concatenated = list ++ List(6, 7, 8)
val head = list.head
val tail = list.tail
val length = list.length

// Using Stream (lazy list)
val stream = LazyList.continually(1)
val firstTen = stream.take(10).toList
Intermediate
19. How to do statistics in Scala?

Scala provides statistical functions through its standard library and scientific libraries like Breeze.

  • Mean: data.sum / data.length
  • Median: sorted(data.length / 2)
  • Standard deviation: Custom calculation
  • Correlation: Manual calculation
  • Breeze: mean(vec), variance(vec)
scala
// Statistics in Scala
import scala.math.{sqrt, pow}

// Basic statistics
def mean(data: Seq[Double]): Double = {
  if (data.isEmpty) 0.0 else data.sum / data.length
}

def median(data: Seq[Double]): Double = {
  val sorted = data.sorted
  val length = sorted.length
  if (length % 2 == 1) sorted(length / 2)
  else (sorted(length / 2 - 1) + sorted(length / 2)) / 2.0
}

def variance(data: Seq[Double]): Double = {
  val m = mean(data)
  data.map(x => pow(x - m, 2)).sum / data.length
}

def stdDev(data: Seq[Double]): Double = sqrt(variance(data))

def correlation(x: Seq[Double], y: Seq[Double]): Double = {
  val n = x.length
  val meanX = mean(x)
  val meanY = mean(y)
  val sumXY = x.zip(y).map { case (xi, yi) => (xi - meanX) * (yi - meanY) }.sum
  val sumX2 = x.map(xi => pow(xi - meanX, 2)).sum
  val sumY2 = y.map(yi => pow(yi - meanY, 2)).sum
  sumXY / sqrt(sumX2 * sumY2)
}

def quantile(data: Seq[Double], q: Double): Double = {
  val sorted = data.sorted
  val n = sorted.length
  val pos = (n - 1) * q
  val base = pos.floor.toInt
  val frac = pos - base
  if (frac == 0) sorted(base)
  else sorted(base) + frac * (sorted(base + 1) - sorted(base))
}

// Usage
val data = (1 to 10).map(_.toDouble)
println(s"Mean: ${mean(data)}")
println(s"Median: ${median(data)}")
println(s"Std Dev: ${stdDev(data)}")
println(s"Variance: ${variance(data)}")

val x = (1 to 100).map(_.toDouble)
val y = x.map(xi => 2 * xi + scala.util.Random.nextDouble() * 20 - 10)
println(s"Correlation: ${correlation(x, y)}")
println(s"Q25: ${quantile(data, 0.25)}")
println(s"Q75: ${quantile(data, 0.75)}")

// Using Breeze (scientific library)
// libraryDependencies += "org.scalanlp" %% "breeze" % "2.0.0"
/*
import breeze.linalg._
import breeze.stats._

val vec = DenseVector(1.0, 2.0, 3.0, 4.0, 5.0)
println(mean(vec))
println(variance(vec))
println(stddev(vec))
*/
Intermediate
20. How to do linear algebra in Scala?

Scala provides linear algebra operations through custom implementations or the Breeze scientific library.

  • Matrix multiplication: matMul(A, B)
  • Transpose: transpose(matrix)
  • Determinant: determinant(matrix)
  • Breeze: DenseMatrix, DenseVector
  • Operations: a * b, a.t, det(a)
scala
// Linear Algebra in Scala
// Matrix operations
def matMul(A: Array[Array[Double]], B: Array[Array[Double]]): Array[Array[Double]] = {
  val rows = A.length
  val cols = B(0).length
  val inner = B.length
  val result = Array.ofDim[Double](rows, cols)
  
  for (i <- 0 until rows; j <- 0 until cols; k <- 0 until inner) {
    result(i)(j) += A(i)(k) * B(k)(j)
  }
  result
}

def transpose(matrix: Array[Array[Double]]): Array[Array[Double]] = {
  val rows = matrix.length
  val cols = matrix(0).length
  val result = Array.ofDim[Double](cols, rows)
  
  for (i <- 0 until rows; j <- 0 until cols) {
    result(j)(i) = matrix(i)(j)
  }
  result
}

def determinant(matrix: Array[Array[Double]]): Double = {
  val n = matrix.length
  if (n == 1) return matrix(0)(0)
  if (n == 2) return matrix(0)(0) * matrix(1)(1) - matrix(0)(1) * matrix(1)(0)
  
  var det = 0.0
  for (j <- 0 until n) {
    val subMatrix = Array.ofDim[Double](n - 1, n - 1)
    for (i <- 1 until n; k <- 0 until n if k != j) {
      subMatrix(i - 1)(k - (if (k > j) 1 else 0)) = matrix(i)(k)
    }
    det += (if (j % 2 == 0) 1 else -1) * matrix(0)(j) * determinant(subMatrix)
  }
  det
}

// Vector operations
def vectorAdd(a: Array[Double], b: Array[Double]): Array[Double] = {
  a.zip(b).map { case (x, y) => x + y }
}

def dotProduct(a: Array[Double], b: Array[Double]): Double = {
  a.zip(b).map { case (x, y) => x * y }.sum
}

def norm(a: Array[Double]): Double = {
  sqrt(a.map(x => x * x).sum)
}

// Using Breeze
/*
import breeze.linalg._

val A = DenseMatrix((1.0, 2.0, 3.0), (4.0, 5.0, 6.0), (7.0, 8.0, 10.0))
val B = DenseMatrix((1.0), (2.0), (3.0))

val product = A * B
val transposed = A.t
val det = det(A)
val inv = inv(A)
*/

// Usage
val A = Array(
  Array(1.0, 2.0, 3.0),
  Array(4.0, 5.0, 6.0),
  Array(7.0, 8.0, 10.0)
)
val B = Array(Array(1.0), Array(2.0), Array(3.0))

val product = matMul(A, B)
val transposed = transpose(A)
val det = determinant(A)
val v1 = Array(1.0, 2.0, 3.0)
val v2 = Array(4.0, 5.0, 6.0)

println(s"Matrix product: ${product.map(_.mkString(", ")).mkString("; ")}")
println(s"Transpose: ${transposed.map(_.mkString(", ")).mkString("; ")}")
println(s"Determinant: $det")
println(s"Dot product: ${dotProduct(v1, v2)}")
println(s"Norm: ${norm(v1)}")
Intermediate
21. How to work with dates in Scala?

Scala uses Java's time API (java.time) for comprehensive date and time handling.

  • Current: LocalDateTime.now()
  • Create: LocalDate.of(2024, 1, 1)
  • Arithmetic: date.plusDays(10)
  • Difference: Period.between(date1, date2)
  • Formatting: DateTimeFormatter
scala
// Dates and Time in Scala
import java.time.{LocalDate, LocalDateTime, LocalTime, ZoneId, Period, Duration}
import java.time.format.DateTimeFormatter

// Current date and time
val now = LocalDateTime.now()
println(now)

// Date creation
val date1 = LocalDate.of(2024, 1, 1)
val date2 = LocalDateTime.of(2024, 1, 1, 12, 0, 0)
println(date1)
println(date2)

// Date arithmetic
println(date1.plusDays(10))
println(date1.plusMonths(2))
println(date2.plusHours(3))

// Date difference
val diff = Period.between(date1, LocalDate.now())
println(s"${diff.getYears} years, ${diff.getMonths} months, ${diff.getDays} days")

// Duration
val duration = Duration.between(date2, LocalDateTime.now())
println(s"${duration.toDays} days, ${duration.toHours} hours")

// Formatting dates
val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
println(date2.format(formatter))

// Date functions
println(LocalDate.now().getYear)
println(LocalDate.now().getMonthValue)
println(LocalDate.now().getDayOfMonth)
println(LocalDate.now().getDayOfWeek)

// Date range
val start = LocalDate.of(2024, 1, 1)
val end = LocalDate.of(2024, 1, 10)
val dates = Iterator.iterate(start)(_.plusDays(1)).takeWhile(!_.isAfter(end)).toList
dates.foreach(println)

// Timezone handling
val newYork = ZoneId.of("America/New_York")
val dateInNY = LocalDateTime.now(newYork)
println(dateInNY)

// Parsing dates
val parsed = LocalDate.parse("2024-01-01")
println(parsed)

// Timestamps
val timestamp = System.currentTimeMillis()
println(timestamp)
val dateFromTimestamp = LocalDateTime.ofEpochSecond(timestamp / 1000, 0, ZoneId.systemDefault().getRules.getOffset(Instant.now))
println(dateFromTimestamp)
Intermediate
22. How to use regular expressions in Scala?

Scala provides regex support through the scala.util.matching.Regex class.

  • Create: "hello".r
  • Match: pattern.findFirstIn(text)
  • Capture groups: "(\d+)".r
  • Replace: text.replaceAll("\d+", "NUM")
  • Case insensitive: "(?i)hello".r
scala
// Regular Expressions in Scala
// Create regex
val pattern = "hello".r
val text = "hello world"

// Match
val matchResult = pattern.findFirstIn(text)
println(matchResult)

// Find all
val text2 = "hello world hello again"
val matches = pattern.findAllIn(text2).toList
println(matches.length)

// Regex with capture groups
val datePattern = "(\d{4})-(\d{2})-(\d{2})".r
val text3 = "Date: 2024-01-01"
val datePattern(year, month, day) = text3
println(s"Year: $year, Month: $month, Day: $day")

// Replace with regex
val replaced = "Hello 123 World".replaceAll("\d+", "NUM")
println(replaced)

// Case insensitive
val caseInsensitive = "(?i)hello".r
println(caseInsensitive.findFirstIn("HELLO world"))

// Split with regex
val parts = "Hello World Scala".split("[\s,]+")
parts.foreach(println)

// Pattern matching with regex
val numberPattern = "(\d+)".r
"123" match {
  case numberPattern(n) => println(s"Number: $n")
  case _ => println("Not a number")
}

// Using Regex with named groups
val namedPattern = "(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})".r
val namedMatch = namedPattern.findFirstMatchIn("2024-01-01")
namedMatch.foreach { m =>
  println(s"Year: ${m.group("year")}")
  println(s"Month: ${m.group("month")}")
  println(s"Day: ${m.group("day")}")
}

// Validating email
val emailPattern = "^[^\s@]+@[^\s@]+\.[^\s@]+$".r
val isValid = emailPattern.matches("test@example.com")
println(s"Email valid: $isValid")
Advanced
23. How to do parallel computing in Scala?

Scala supports parallel computing through Futures, parallel collections, actors (Akka), and Java's concurrency utilities.

  • Futures: Future { computation }
  • Parallel collections: list.par.map(_ * 2)
  • Akka actors: Actor-based concurrency
  • ForkJoinPool: new ForkJoinPool(4)
  • Java Executors: Executors.newFixedThreadPool(4)
scala
// Parallel Computing in Scala
import scala.concurrent.{Future, Await, ExecutionContext}
import scala.concurrent.duration._
import java.util.concurrent.Executors

// Using Futures (parallel collections)
implicit val ec: ExecutionContext = ExecutionContext.global

val futures = (1 to 10).map { i =>
  Future {
    Thread.sleep(1000)
    i * i
  }
}

val results = Await.result(Future.sequence(futures), 10.seconds)
println(results)

// Parallel collections
import scala.collection.parallel.CollectionConverters._

val numbers = (1 to 1000000).toList
val parallelResult = numbers.par.map(_ * 2).toList
println(s"Parallel result size: ${parallelResult.size}")

// Using parallel collections with filters
val evens = (1 to 1000).par.filter(_ % 2 == 0).toList
println(s"Evens: ${evens.size}")

// Using Actors (Akka)
// import akka.actor._
// import akka.routing.RoundRobinPool

// Using ForkJoinPool
import java.util.concurrent.ForkJoinPool
import scala.concurrent.{Await, Future}

val pool = new ForkJoinPool(4)
implicit val ec2: ExecutionContext = ExecutionContext.fromExecutor(pool)

val parallelTask = Future {
  (1 to 10).par.map { i =>
    Thread.sleep(500)
    i * i
  }.toList
}

val parallelResult2 = Await.result(parallelTask, 10.seconds)
pool.shutdown()

// Using Java's Executors
val executor = Executors.newFixedThreadPool(4)
implicit val ec3: ExecutionContext = ExecutionContext.fromExecutor(executor)

val tasks = (1 to 10).map { i =>
  Future {
    Thread.sleep(1000)
    i * i
  }
}

val combined = Future.sequence(tasks)
val finalResult = Await.result(combined, 10.seconds)
executor.shutdown()

// Using parallel collection operations
val list = (1 to 1000).toList
val parList = list.par

// Map
val squared = parList.map(_ * 2)

// Filter
val filtered = parList.filter(_ % 2 == 0)

// Reduce
val sum = parList.reduce(_ + _)

// Fold
val foldSum = parList.fold(0)(_ + _)

// Aggregate
val aggregateResult = parList.aggregate(0)(_ + _, _ + _)
Advanced
24. What is metaprogramming in Scala?

Scala supports metaprogramming through macros, reflection, and type classes for compile-time code generation and runtime inspection.

  • Macros: Compile-time code generation
  • Reflection: scala.reflect.runtime
  • Type classes: implicit and type class
  • Annotations: @Loggable
  • Shapeless: Generic programming library
scala
// Metaprogramming in Scala
import scala.reflect.runtime.{universe => ru}
import scala.tools.reflect.ToolBox

// Using reflection to inspect types
def getTypeInfo[A: ru.TypeTag](value: A): Unit = {
  val tpe = ru.typeOf[A]
  println(s"Type: $tpe")
  println(s"Type arguments: ${tpe.typeArgs}")
}

// Macro definition (requires macro paradise)
// import scala.reflect.macros.blackbox.Context

// def addLogImpl(c: Context)(expr: c.Expr[String]): c.Expr[Unit] = {
//   import c.universe._
//   reify {
//     println("Executing: " + expr.splice)
//   }
// }

// def addLog(expr: String): Unit = macro addLogImpl

// Using ToolBox for runtime compilation
val tb = ru.runtimeMirror(getClass.getClassLoader).mkToolBox()

// Dynamic method call with reflection
class MyClass {
  def greet(name: String): String = s"Hello, $name!"
}

val mirror = ru.runtimeMirror(getClass.getClassLoader)
val instance = new MyClass()
val instanceMirror = mirror.reflect(instance)
val methodSymbol = ru.typeOf[MyClass].decl(ru.TermName("greet")).asMethod
val methodMirror = instanceMirror.reflectMethod(methodSymbol)
val result = methodMirror("Scala").asInstanceOf[String]
println(result)

// Using type tags
def printType[T: ru.TypeTag](value: T): Unit = {
  println(ru.typeOf[T])
}

printType(42)
printType("Hello")

// Dynamic class loading
val classLoader = getClass.getClassLoader
val cls = classLoader.loadClass("java.util.ArrayList")
val constructor = cls.getConstructor()
val instance2 = constructor.newInstance()

// Using annotations for metaprogramming
import scala.annotation.StaticAnnotation

class Loggable extends StaticAnnotation

@Loggable
class Service {
  def process(): Unit = println("Processing...")
}

// Using type class derivation
trait Show[A] {
  def show(value: A): String
}

object Show {
  def apply[A](implicit show: Show[A]): Show[A] = show
  
  implicit val intShow: Show[Int] = (value: Int) => value.toString
  implicit val stringShow: Show[String] = (value: String) => value
}

// Using Shapeless for generic programming
// libraryDependencies += "com.chuusai" %% "shapeless" % "2.3.10"
Advanced
25. How to interoperate with Java in Scala?

Scala seamlessly interoperates with Java, allowing direct use of Java classes and libraries.

  • Java collections: new ArrayList[String]()
  • Convert collections: list.asScala, scalaSeq.asJava
  • Java I/O: new File("file.txt")
  • Java time: LocalDate.now()
  • Java threads: new Thread(() => ...)
scala
// Interoperability with Java
import java.util.{ArrayList, HashMap}
import java.io.{File, FileReader, BufferedReader}
import java.nio.file.{Paths, Files}
import scala.collection.JavaConverters._

// Using Java collections
val javaList = new ArrayList[String]()
javaList.add("Scala")
javaList.add("Java")

// Convert Java collection to Scala
val scalaList = javaList.asScala.toList
println(scalaList)

// Convert Scala collection to Java
val scalaSeq = Seq("Scala", "Java")
val javaList2 = scalaSeq.asJava
println(javaList2)

// Using Java I/O
val file = new File("example.txt")
val reader = new BufferedReader(new FileReader(file))
val lines = Iterator.continually(reader.readLine()).takeWhile(_ != null).toList
reader.close()
println(lines)

// Using Java NIO
import java.nio.charset.StandardCharsets
val path = Paths.get("example.txt")
val content = new String(Files.readAllBytes(path), StandardCharsets.UTF_8)
println(content)

// Using Java Date and Time
import java.time.{LocalDate, LocalDateTime}

val date = LocalDate.now()
val dateTime = LocalDateTime.now()

// Using Java Optional
import java.util.Optional

val javaOptional = Optional.of("Hello")
val value = if (javaOptional.isPresent) javaOptional.get() else "Default"
println(value)

// Using Java Streams
import java.util.stream.Collectors

val javaStream = javaList.stream()
val filtered = javaStream
  .filter(_.startsWith("S"))
  .collect(Collectors.toList())

// Using Java generic types
val javaMap = new HashMap[String, Integer]()
javaMap.put("Scala", 3)
javaMap.put("Java", 8)

val scalaMap = javaMap.asScala.mapValues(_.intValue()).toMap
println(scalaMap)

// Using Java threads
val thread = new Thread(() => {
  println("Running in Java thread")
})
thread.start()
thread.join()

// Java interop with Scala classes
// Scala class can extend Java class
class MyScalaClass extends java.util.ArrayList[String] {
  def addAll(items: Array[String]): Unit = {
    items.foreach(add)
  }
}
Advanced
26. How to optimize performance in Scala?

Scala performance can be optimized through tail recursion, lazy evaluation, specialization, and compiler flags.

  • Tail recursion: @tailrec
  • Lazy evaluation: lazy val, view
  • Specialization: @specialized
  • Inlining: @inline
  • Compiler flags: -optimise, -Xdisable-assertions
scala
// Performance Optimization in Scala
// Performance tips

// 1. Use immutable collections when possible
val immutableList = List(1, 2, 3, 4, 5)

// 2. Use tail recursion
def sumTailRec(list: List[Int], acc: Int = 0): Int = {
  list match {
    case Nil => acc
    case head :: tail => sumTailRec(tail, acc + head)
  }
}

// 3. Use lazy evaluation
lazy val expensiveComputation = {
  Thread.sleep(1000)
  42
}

// 4. Use view for lazy transformations
val numbers = (1 to 1000000).view.map(_ * 2).filter(_ % 2 == 0)

// 5. Use specialization for performance-critical code
import scala.annotation.tailrec
import scala.specialized

def fastSum[@specialized(Int, Long, Double) T](list: List[T])(implicit num: Numeric[T]): T = {
  list.foldLeft(num.zero)(num.plus)
}

// 6. Use while loop when needed
def sumWhile(arr: Array[Int]): Int = {
  var i = 0
  var sum = 0
  while (i < arr.length) {
    sum += arr(i)
    i += 1
  }
  sum
}

// 7. Use mutable collections for performance
import scala.collection.mutable.ArrayBuffer

val buffer = ArrayBuffer.empty[Int]
for (i <- 0 until 1000000) {
  buffer += i
}

// 8. Use String interpolation carefully
def buildString(name: String, age: Int): String = {
  s"Name: $name, Age: $age"
}

// 9. Use value classes to avoid allocation
class Wrapper(val value: Int) extends AnyVal

// 10. Use @inline annotation for small methods
import scala.annotation.inline

@inline def add(a: Int, b: Int): Int = a + b

// 11. Use parallel collections for CPU-bound tasks
val parallelResult = (1 to 1000000).par.map(_ * 2).toList

// 12. Profile with VisualVM or JProfiler
// Run with -XX:+PrintGCDetails -XX:+PrintGCTimeStamps

// 13. Use -optimise compiler flag
// scalac -optimise YourFile.scala

// 14. Use -Xdisable-assertions for production
// scalac -Xdisable-assertions YourFile.scala

// 15. Use -Xelide-below for debug levels
// scalac -Xelide-below 0 YourFile.scala
Advanced
27. How to do networking in Scala?

Scala provides networking through Java's HTTP client, Akka HTTP, and various third-party libraries.

  • HTTP client: HttpURLConnection
  • Akka HTTP: Http().singleRequest
  • Dispatch: Http.default(svc OK as.String)
  • TCP sockets: new Socket(host, port)
  • WebSocket: Akka streams
scala
// Networking in Scala
import java.net.{URL, HttpURLConnection, Socket}
import java.io.{BufferedReader, InputStreamReader, PrintWriter}
import scala.io.Source

// HTTP GET request
def get(url: String): String = {
  val connection = new URL(url).openConnection().asInstanceOf[HttpURLConnection]
  connection.setRequestMethod("GET")
  connection.setRequestProperty("User-Agent", "Scala")
  
  val responseCode = connection.getResponseCode
  if (responseCode == HttpURLConnection.HTTP_OK) {
    val reader = new BufferedReader(new InputStreamReader(connection.getInputStream))
    val response = Iterator.continually(reader.readLine()).takeWhile(_ != null).mkString("
")
    reader.close()
    response
  } else {
    throw new Exception(s"HTTP error: $responseCode")
  }
}

// HTTP POST request
def post(url: String, data: String): String = {
  val connection = new URL(url).openConnection().asInstanceOf[HttpURLConnection]
  connection.setRequestMethod("POST")
  connection.setRequestProperty("Content-Type", "application/json")
  connection.setDoOutput(true)
  
  val writer = new PrintWriter(connection.getOutputStream)
  writer.write(data)
  writer.flush()
  writer.close()
  
  val responseCode = connection.getResponseCode
  if (responseCode == HttpURLConnection.HTTP_OK) {
    val reader = new BufferedReader(new InputStreamReader(connection.getInputStream))
    val response = Iterator.continually(reader.readLine()).takeWhile(_ != null).mkString("
")
    reader.close()
    response
  } else {
    throw new Exception(s"HTTP error: $responseCode")
  }
}

// Using Scala's Source for simple GET
def fetchUrl(url: String): String = {
  Source.fromURL(url).mkString
}

// TCP client
def tcpClient(host: String, port: Int, message: String): String = {
  val socket = new Socket(host, port)
  val writer = new PrintWriter(socket.getOutputStream, true)
  val reader = new BufferedReader(new InputStreamReader(socket.getInputStream))
  
  writer.println(message)
  val response = reader.readLine()
  
  writer.close()
  reader.close()
  socket.close()
  response
}

// TCP server
def tcpServer(port: Int): Unit = {
  val serverSocket = new java.net.ServerSocket(port)
  println(s"Server listening on port $port")
  
  while (true) {
    val client = serverSocket.accept()
    val writer = new PrintWriter(client.getOutputStream, true)
    val reader = new BufferedReader(new InputStreamReader(client.getInputStream))
    
    val request = reader.readLine()
    writer.println(s"HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\nHello from server!")
    
    writer.close()
    reader.close()
    client.close()
  }
}

// Using Akka HTTP (requires library)
/*
import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.model._
import akka.stream.ActorMaterializer

implicit val system = ActorSystem()
implicit val materializer = ActorMaterializer()

val responseFuture = Http().singleRequest(HttpRequest(uri = "https://api.github.com"))
*/

// Using Dispatch (library)
// libraryDependencies += "net.databinder.dispatch" %% "dispatch-core" % "0.13.4"

/*
import dispatch._

val svc = url("https://api.github.com")
val response = Http.default(svc OK as.String)
*/
Advanced
28. How to work with JSON in Scala?

Scala provides JSON support through Play JSON, Circe, and other libraries for encoding/decoding JSON data.

  • Play JSON: Json.toJson(data), Json.parse(json)
  • Circe: io.circe library
  • Automatic format: Json.format[Person]
  • Pretty print: Json.prettyPrint(json)
  • File I/O: Json.parse(source.mkString)
scala
// Working with JSON in Scala
import scala.util.parsing.json.JSON
import play.api.libs.json._  // Requires library

// Using Play JSON
// libraryDependencies += "com.typesafe.play" %% "play-json" % "2.9.2"

// Define case class
case class Person(name: String, age: Int, city: String, hobbies: List[String])

// Automatic JSON formatting
implicit val personFormat: Format[Person] = Json.format[Person]

// Encode to JSON
val person = Person("Alice", 25, "NYC", List("reading", "coding"))
val json = Json.toJson(person)
val jsonString = Json.stringify(json)
println(jsonString)

// Pretty print
val prettyJson = Json.prettyPrint(json)
println(prettyJson)

// Decode from JSON
val jsonStr = """{"name":"Bob","age":30,"city":"LA","hobbies":["gaming","swimming"]}"""
val parsed = Json.parse(jsonStr)
val decoded = parsed.as[Person]
println(decoded.name)
println(decoded.age)

// Working with arrays
val jsonArray = Json.toJson(List(1, 2, 3, 4, 5))
println(Json.stringify(jsonArray))

// Nested structures
val nestedJson = Json.obj(
  "user" -> Json.obj(
    "id" -> 1,
    "profile" -> Json.obj(
      "name" -> "Alice",
      "email" -> "alice@example.com"
    )
  )
)
println(Json.prettyPrint(nestedJson))

// Read JSON from file
val fileContent = scala.io.Source.fromFile("data.json").mkString
val data = Json.parse(fileContent)

// Write JSON to file
val fileWriter = new java.io.PrintWriter("output.json")
fileWriter.write(Json.prettyPrint(json))
fileWriter.close()

// Using JSON with Option
case class User(name: String, age: Option[Int], email: Option[String])
implicit val userFormat: Format[User] = Json.format[User]

val userJson = Json.obj(
  "name" -> "Alice"
)
val user = userJson.as[User]
println(user.age.getOrElse(0))

// Custom JSON serialization
implicit val customFormat: Format[Person] = new Format[Person] {
  def reads(json: JsValue): JsResult[Person] = {
    for {
      name <- (json  "name").validate[String]
      age <- (json  "age").validate[Int]
      city <- (json  "city").validate[String]
      hobbies <- (json  "hobbies").validate[List[String]]
    } yield Person(name, age, city, hobbies)
  }
  
  def writes(person: Person): JsValue = {
    Json.obj(
      "fullname" -> person.name,
      "years" -> person.age,
      "location" -> person.city,
      "activities" -> person.hobbies
    )
  }
}
Advanced
29. How to test code in Scala?

Scala testing is done using ScalaTest, ScalaCheck, and other testing frameworks.

  • ScalaTest: AnyFlatSpec, Matchers
  • Assertions: result should be (expected)
  • Data providers: Table with forAll
  • ScalaCheck: Property-based testing
  • Futures: ScalaFutures
scala
// Testing in Scala
import org.scalatest.flatspec.AnyFlatSpec
import org.scalatest.matchers.should.Matchers
import org.scalatest.{BeforeAndAfter, BeforeAndAfterAll}
import org.scalatest.concurrent.ScalaFutures

// Basic test
class MathTest extends AnyFlatSpec with Matchers {
  "A calculator" should "add two numbers" in {
    val result = 2 + 2
    result should be (4)
  }
  
  it should "subtract two numbers" in {
    val result = 10 - 3
    result should be (7)
  }
}

// Test with floating point
class FloatTest extends AnyFlatSpec with Matchers {
  "Floating point" should "be approximately equal" in {
    val result = 0.1 + 0.2
    result should be (0.3 +- 0.001)
  }
}

// Test with exceptions
class ExceptionTest extends AnyFlatSpec with Matchers {
  "Division by zero" should "throw exception" in {
    an [ArithmeticException] should be thrownBy {
      10 / 0
    }
  }
}

// Test with collections
class ListTest extends AnyFlatSpec with Matchers {
  val list = List(1, 2, 3, 4, 5)
  
  "A list" should "have correct length" in {
    list should have length 5
  }
  
  it should "contain specific elements" in {
    list should contain (3)
  }
  
  it should "be sorted" in {
    list shouldBe sorted
  }
}

// Test with fixtures
class FixtureTest extends AnyFlatSpec with Matchers with BeforeAndAfter {
  var value: Int = 0
  
  before {
    value = 42
  }
  
  after {
    value = 0
  }
  
  "A fixture" should "be set up" in {
    value should be (42)
  }
}

// Test with data providers (tables)
class TableTest extends AnyFlatSpec with Matchers {
  val additionData = Table(
    ("a", "b", "expected"),
    (1, 2, 3),
    (0, 0, 0),
    (-1, 1, 0),
    (5, -3, 2)
  )
  
  forAll(additionData) { (a, b, expected) =>
    s"Adding $a and $b" should s"be $expected" in {
      val result = a + b
      result should be (expected)
    }
  }
}

// Test with Property-based testing (ScalaCheck)
import org.scalacheck.Properties
import org.scalacheck.Prop.forAll

object MathProps extends Properties("Math") {
  property("addition is associative") = forAll { (a: Int, b: Int, c: Int) =>
    (a + b) + c == a + (b + c)
  }
}

// Test with ScalaFutures
import scala.concurrent.{Future, Await}
import scala.concurrent.duration._

class FutureTest extends AnyFlatSpec with Matchers with ScalaFutures {
  implicit val patience: PatienceConfig = PatienceConfig(timeout = 5.seconds)
  
  "A future" should "complete successfully" in {
    val future = Future.successful(42)
    whenReady(future) { result =>
      result should be (42)
    }
  }
}

// Running tests
// sbt test
// sbt testOnly MathTest

// Using scalatest with sbt
// in build.sbt:
// libraryDependencies += "org.scalatest" %% "scalatest" % "3.2.15" % Test
Advanced
30. How to debug in Scala?

Scala debugging is done through logging, assertions, and IDEs with breakpoint support.

  • println: println("debug")
  • Logging: logger.info("message")
  • Assertions: assert(condition), require(condition)
  • Try: Try(expression)
  • IDE debugger: IntelliJ IDEA, Eclipse
scala
// Debugging in Scala
// Using println for debugging
def debugFunction(x: Int): Int = {
  println(s"Entering function with x = $x")
  val result = x * 2
  println(s"Result = $result")
  result
}
debugFunction(5)

// Using log4j for logging
// libraryDependencies += "org.apache.logging.log4j" %% "log4j-api-scala" % "12.0"
/*
import org.apache.logging.log4j.scala.Logging

class MyClass extends Logging {
  def doSomething(): Unit = {
    logger.info("Doing something")
    logger.debug("Debug information")
    logger.error("Error occurred")
  }
}
*/

// Using Scala's logging (built-in)
import scala.util.logging.Logged

object Logger extends Logged {
  def process(): Unit = {
    log("Processing started")
    log("Processing completed")
  }
}

// Using assert
def assertExample(x: Int): Unit = {
  assert(x > 0, "x must be positive")
  println(s"x is positive: $x")
}

// Using require
def requireExample(x: Int): Unit = {
  require(x > 0, "x must be positive")
  println(s"x is positive: $x")
}

// Using assume
def assumeExample(x: Int): Unit = {
  assume(x > 0, "x must be positive")
  println(s"x is positive: $x")
}

// Using StackTrace
try {
  throw new Exception("Something went wrong")
} catch {
  case e: Exception =>
    println(s"Error: ${e.getMessage}")
    e.printStackTrace()
}

// Using scala.util.Try for debugging
import scala.util.{Try, Success, Failure}

def divideWithTry(a: Int, b: Int): Try[Int] = {
  Try(a / b)
}

divideWithTry(10, 2) match {
  case Success(value) => println(s"Result: $value")
  case Failure(e) => println(s"Error: ${e.getMessage}")
}

// Using JVM debugging flags
// -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005

// Using ScalaTest's Debugger
// Run tests with -Dtest.debug=true

// Using SBT console for interactive debugging
// sbt console
// :load MyScript.scala

// Using IntelliJ IDEA debugger
// Set breakpoints and run in debug mode

// Using VisualVM for profiling
// jvisualvm

// Using JConsole for monitoring
// jconsole

// Using -Xprint:typer for compiler debugging
// scalac -Xprint:typer MyFile.scala

// Using -Ydebug for debug information
// scalac -Ydebug MyFile.scala
Advanced
31. What are abstract classes and traits in Scala?

Abstract classes and traits define contracts and reusable behavior in Scala's type system.

  • Abstract class: abstract class Animal { def makeSound(): String }
  • Concrete class: class Dog extends Animal
  • Trait: trait SoundMaker { def makeSound(): String }
  • Multiple traits: class Lion extends SoundMaker with Named
  • Self-type: trait Service { self: Logger => ... }
scala
// Abstract Classes and Traits in Scala
// Abstract class
abstract class Animal {
  val name: String
  val age: Int
  def makeSound(): String
}

// Concrete implementation
class Dog(val name: String, val age: Int) extends Animal {
  def makeSound(): String = "Woof!"
}

class Cat(val name: String, val age: Int) extends Animal {
  def makeSound(): String = "Meow!"
}

// Trait (interface with implementation)
trait SoundMaker {
  def makeSound(): String
}

trait Named {
  def name: String
}

// Class implementing multiple traits
class Lion(val name: String) extends SoundMaker with Named {
  def makeSound(): String = "Roar!"
}

// Trait with abstract methods
trait Logger {
  def log(message: String): Unit
  def info(message: String): Unit = log(s"INFO: $message")
  def error(message: String): Unit = log(s"ERROR: $message")
}

// Abstract type members
trait Container {
  type A
  def value: A
}

class IntContainer(val value: Int) extends Container {
  type A = Int
}

// Self-type annotation
trait Service {
  self: Logger =>
  def process(): Unit = {
    info("Processing started")
    // processing logic
    info("Processing completed")
  }
}

// Usage
val dog: Animal = new Dog("Rex", 3)
val cat: Animal = new Cat("Whiskers", 2)
val lion: Lion = new Lion("Simba")

println(dog.makeSound())
println(cat.makeSound())
println(lion.makeSound())

// Type checking
println(dog.isInstanceOf[Animal])
println(dog.isInstanceOf[Dog])
println(dog.isInstanceOf[Cat])
Advanced
32. What are generic types in Scala?

Generic types in Scala enable type-safe programming with parameterized types, type bounds, and variance.

  • Generic class: class Box[A](val value: A)
  • Type bounds: [A <: AnyRef], [A >: String]
  • Variance: class Covariant[+A], class Contravariant[-A]
  • Higher-kinded: trait Functor[F[_]]
  • Type aliases: type IntList = List[Int]
scala
// Generic Types in Scala
// Generic class
class Box[A](val value: A) {
  def get: A = value
  def map[B](f: A => B): Box[B] = new Box(f(value))
}

// Generic trait
trait Container[A] {
  def get: A
  def put(value: A): Container[A]
}

// Generic function
def identity[A](x: A): A = x

// Generic with multiple type parameters
class Pair[A, B](val first: A, val second: B)

// Type bounds
class UpperBound[A <: AnyRef](val value: A)
class LowerBound[A >: String](val value: A)

// Context bounds
def printLength[A: Seq](seq: A): Int = seq.length

// View bounds (deprecated in Scala 2.13)
// def printString[A <% String](value: A): String = value

// Covariant
class Covariant[+A](val value: A)

// Contravariant
class Contravariant[-A] {
  def process(value: A): Unit = println(value)
}

// Invariant
class Invariant[A](val value: A)

// Type aliases
type IntList = List[Int]
type StringMap = Map[String, String]

// Higher-kinded types
trait Functor[F[_]] {
  def map[A, B](fa: F[A])(f: A => B): F[B]
}

// Usage
val box: Box[Int] = new Box(42)
val mapped: Box[String] = box.map(_.toString)

val pair: Pair[String, Int] = new Pair("Hello", 42)

val upper: UpperBound[String] = new UpperBound("Hello")
// val lower: LowerBound[String] = new LowerBound("World")

val covariant: Covariant[String] = new Covariant("Hello")
val covariant2: Covariant[Any] = covariant

val list: IntList = List(1, 2, 3)
val map: StringMap = Map("a" -> "b", "c" -> "d")
Advanced
33. What are implicit conversions in Scala?

Implicit conversions and type classes in Scala enable extension methods, type class derivation, and compile-time polymorphism.

  • Implicit conversion: implicit def intToString(x: Int): String = x.toString
  • Implicit class: implicit class RichInt(val value: Int)
  • Type class: trait Show[A]
  • Implicit parameters: def process[A: Show](value: A)
  • Context bounds: [A: Show]
scala
// Implicit Conversions and Type Classes
// Implicit conversion (use with caution)
implicit def intToString(x: Int): String = x.toString
val str: String = 42 // Will implicitly convert

// Implicit class
implicit class RichInt(val value: Int) {
  def square: Int = value * value
  def cube: Int = value * value * value
}
println(5.square)
println(5.cube)

// Type class pattern
trait Show[A] {
  def show(value: A): String
}

object Show {
  def apply[A](implicit instance: Show[A]): Show[A] = instance
  
  implicit val intShow: Show[Int] = (value: Int) => value.toString
  implicit val stringShow: Show[String] = (value: String) => value
  implicit val booleanShow: Show[Boolean] = (value: Boolean) => value.toString
}

// Using type class
def printShow[A: Show](value: A): Unit = {
  println(implicitly[Show[A]].show(value))
}

printShow(42)
printShow("Hello")
printShow(true)

// Implicit parameter
def greet(implicit name: String): String = s"Hello, $name!"
implicit val defaultName: String = "Scala"
println(greet)

// Implicitly resolving
val showInt = implicitly[Show[Int]]
println(showInt.show(100))

// Context bound (shorthand for implicit parameter)
def process[A: Show](value: A): String = {
  val showInstance = implicitly[Show[A]]
  showInstance.show(value)
}

// Implicit conversion with DummyImplicit
def processInt(x: Int)(implicit d: DummyImplicit): Unit = {
  println(s"Processing int: $x")
}

// Using implicit evidence
sealed trait Evidence
object Evidence {
  implicit object IntEvidence extends Evidence
}

def requireEvidence[A](value: A)(implicit ev: Evidence): Unit = {
  println(s"Processing: $value")
}

requireEvidence(42) // Works with implicit Evidence

// Implicitly for type class derivation
trait Eq[A] {
  def equal(a: A, b: A): Boolean
}

object Eq {
  def apply[A](implicit instance: Eq[A]): Eq[A] = instance
}

implicit val intEq: Eq[Int] = (a: Int, b: Int) => a == b

def compare[A: Eq](a: A, b: A): Boolean = {
  Eq[A].equal(a, b)
}

println(compare(5, 5))
println(compare(5, 6))
Advanced
34. What are lazy evaluation and streams in Scala?

Scala supports lazy evaluation through lazy val, LazyList, and view for efficient computation.

  • Lazy val: lazy val x = expensive()
  • LazyList: LazyList.from(1).map(_ * 2)
  • View: (1 to 1000000).view.map(_ * 2)
  • Stream: LazyList.unfold(0)(state => if (state > 10) None else Some((state, state + 1)))
  • By-name parameters: def lazyIf(condition: => Boolean)(thenBlock: => Any)
scala
// Lazy Evaluation and Streams
// Lazy val
lazy val expensiveValue: Int = {
  println("Computing expensive value")
  Thread.sleep(1000)
  42
}

// Lazy list (Stream - deprecated in Scala 2.13)
// Use LazyList instead
val lazyList: LazyList[Int] = LazyList.from(1)

// LazyList with infinite sequence
val fibs: LazyList[Int] = {
  def fib(a: Int, b: Int): LazyList[Int] = a #:: fib(b, a + b)
  fib(0, 1)
}

println(fibs.take(10).toList)

// LazyList with map
val squares: LazyList[Int] = LazyList.from(1).map(_ * 2)
println(squares.take(10).toList)

// LazyList with filter
val evens: LazyList[Int] = LazyList.from(1).filter(_ % 2 == 0)
println(evens.take(10).toList)

// LazyList with takeWhile
val numbers: LazyList[Int] = LazyList.from(1).takeWhile(_ <= 100)
println(numbers.toList)

// Using view for lazy transformations
val viewList = (1 to 1000000).view.map(_ * 2).filter(_ % 2 == 0)
println(viewList.take(10).toList)

// Lazy evaluation with by-name parameters
def lazyIf(condition: => Boolean)(thenBlock: => Any)(elseBlock: => Any): Any = {
  if (condition) thenBlock else elseBlock
}

// Streaming using Iterator
val iterator: Iterator[Int] = Iterator.from(1)
println(iterator.take(10).toList)

// Using Stream with unfold
val stream: LazyList[Int] = LazyList.unfold(0) { state =>
  if (state > 10) None else Some((state, state + 1))
}
println(stream.toList)

// Lazy evaluation in collections
val lazyMap = Map(1 -> "one", 2 -> "two", 3 -> "three")
val lazyMapResult = lazyMap.view.mapValues(_.toUpperCase).toMap

// Using lazy val in classes
class LazyClass {
  lazy val computed: Int = {
    println("Computing")
    42
  }
}

val instance = new LazyClass
println(instance.computed) // First access triggers computation
println(instance.computed) // Returns cached value

// LazyList with recursion
def countdown(n: Int): LazyList[Int] = {
  if (n <= 0) LazyList.empty
  else n #:: countdown(n - 1)
}

println(countdown(10).toList)
Advanced
35. What are advanced collections operations in Scala?

Scala provides advanced collection operations including matrix operations, element-wise transformations, and functional programming methods.

  • Matrix ops: Array.tabulate, grouped
  • Element-wise: map, zip
  • Transpose: matrix.indices.map(i => matrix.map(_(i)))
  • Norm: math.sqrt(matrix.flatten.map(x => x*x).sum)
  • Trace: matrix.indices.map(i => matrix(i)(i)).sum
scala
// Advanced Collections Operations
// Collection initialization
val zeros = Array.fill(3, 3)(0)
val ones = Array.fill(3, 3)(1)
val identity = Array.tabulate(3, 3)((i, j) => if (i == j) 1 else 0)

// Reshaping
val arr = (1 to 9).toArray
val matrix = arr.grouped(3).toArray

// Transpose
def transpose[A](matrix: Array[Array[A]]): Array[Array[A]] = {
  val rows = matrix.length
  val cols = matrix(0).length
  Array.tabulate(cols, rows)((i, j) => matrix(j)(i))
}

// Element-wise operations
val A = Array.tabulate(3, 3)((i, j) => i * 3 + j + 1)
val B = A.map(_.map(_ + 1))
val C = A.map(_.map(_ * 2))
val D = A.map(_.map(x => x * x))

// Matrix multiplication
def matMul(A: Array[Array[Double]], B: Array[Array[Double]]): Array[Array[Double]] = {
  val rows = A.length
  val cols = B(0).length
  val inner = B.length
  Array.tabulate(rows, cols) { (i, j) =>
    (0 until inner).map(k => A(i)(k) * B(k)(j)).sum
  }
}

val X = Array.tabulate(3, 3)((_, _) => math.random())
val Y = Array.tabulate(3, 3)((_, _) => math.random())
val Z = matMul(X, Y)

// Element-wise multiplication
val W = X.zip(Y).map { case (rowX, rowY) =>
  rowX.zip(rowY).map { case (x, y) => x * y }
}

// Matrix norm (Frobenius)
def norm(matrix: Array[Array[Double]]): Double = {
  math.sqrt(matrix.flatten.map(x => x * x).sum)
}

// Trace
def trace(matrix: Array[Array[Double]]): Double = {
  matrix.indices.map(i => matrix(i)(i)).sum
}

// Diagonal
def diag(matrix: Array[Array[Double]]): Array[Double] = {
  matrix.indices.map(i => matrix(i)(i)).toArray
}

// Using Breeze for advanced operations
/*
import breeze.linalg._

val A = DenseMatrix((1.0, 2.0), (3.0, 4.0))
val B = DenseMatrix((5.0, 6.0), (7.0, 8.0))

val C = A * B
val D = A + B
val E = A.t
val F = A \ B
*/

println(s"Norm: ${norm(X)}")
println(s"Trace: ${trace(X)}")
println(s"Diagonal: ${diag(X).mkString(", ")}")
Advanced
36. How to handle missing data in Scala?

Scala handles missing data using Option, Either, and Try for safe error handling.

  • Option: Some(value) or None
  • Get with default: option.getOrElse(default)
  • Either: Left(error) or Right(value)
  • Try: Try(expression)
  • For-comprehension: for (a <- optA; b <- optB) yield a + b
scala
// Handling Missing Data (Option and Either)
// Using Option
val data: List[Option[Int]] = List(Some(1), Some(2), None, Some(4), Some(5), None, Some(7))

// Check for missing values
val hasMissing: Boolean = data.contains(None)
println(s"Has missing: $hasMissing")

// Remove missing values
val cleanData: List[Int] = data.flatten
println(cleanData)

// Replace missing values
val replaced: List[Int] = data.map(_.getOrElse(0))
println(replaced)

// Operations with missing values
val x: List[Option[Int]] = List(Some(1), Some(2), None, Some(4))
val y: List[Option[Int]] = List(Some(5), Some(6), None, Some(8))

val z: List[Option[Int]] = x.zip(y).map { case (a, b) =>
  for {
    va <- a
    vb <- b
  } yield va + vb
}
println(z)

// Ignoring missing values
val sumComplete: Int = x.flatten.sum
println(s"Sum of complete data: $sumComplete")

// Using Option in collections
val numbers = List(1, 2, 3, 4, 5)
val firstEven = numbers.find(_ % 2 == 0)
println(firstEven)

// Using Either for error handling
def safeDivide(a: Int, b: Int): Either[String, Int] = {
  if (b == 0) Left("Cannot divide by zero")
  else Right(a / b)
}

safeDivide(10, 2) match {
  case Right(value) => println(s"Result: $value")
  case Left(error) => println(s"Error: $error")
}

safeDivide(10, 0) match {
  case Right(value) => println(s"Result: $value")
  case Left(error) => println(s"Error: $error")
}

// Using Try for error handling
import scala.util.{Try, Success, Failure}

def divideTry(a: Int, b: Int): Try[Int] = Try(a / b)

divideTry(10, 2) match {
  case Success(value) => println(s"Result: $value")
  case Failure(e) => println(s"Error: ${e.getMessage}")
}

// Combining Options with for-comprehension
val optA: Option[Int] = Some(10)
val optB: Option[Int] = Some(20)
val result: Option[Int] = for {
  a <- optA
  b <- optB
} yield a + b

println(result)

// Using Option.getOrElse
val value: Int = data.headOption.getOrElse(0)

// Using Option.orElse
val default: Option[Int] = None
val finalValue: Option[Int] = Some(42).orElse(default)

// Using Option.fold
val processed: Int = Some(42).fold(0)(_ * 2)
Advanced
37. How to do sorting and searching in Scala?

Scala provides sorting and searching through sorted, sortBy, find, and binarySearch.

  • Sort: list.sorted, list.sortBy(_.age)
  • Custom comparator: list.sortWith(_ > _)
  • Search: list.find(_ > 5), list.filter(_ > 5)
  • Binary search: java.util.Arrays.binarySearch(array, target)
  • Contains: list.contains(7)
scala
// Sorting and Searching in Scala
// Basic sorting
val arr = List(5, 2, 8, 1, 9, 3)
val sorted = arr.sorted
println(sorted)

// Sorting with custom comparator
val arr2 = List((5, "apple"), (3, "banana"), (8, "cherry"))
val sorted2 = arr2.sortBy(_._1)
println(sorted2)

// Sorting descending
val arr3 = List(5, 2, 8, 1, 9, 3)
val sorted3 = arr3.sortWith(_ > _)
println(sorted3)

// Sorting with custom comparator
val sorted4 = arr3.sortWith((a, b) => a < b)
println(sorted4)

// Search functions
val arr5 = List(1, 3, 5, 7, 9, 11)
val greaterThan5 = arr5.filter(_ > 5)
println(greaterThan5)

val firstGreaterThan5 = arr5.find(_ > 5)
println(firstGreaterThan5)

val lastGreaterThan5 = arr5.reverse.find(_ > 5)
println(lastGreaterThan5)

// Contains
val hasSeven = arr5.contains(7)
val hasFour = arr5.contains(4)
println(s"Has 7: $hasSeven, Has 4: $hasFour")

// Binary search (requires sorted)
val arr6 = Array(1, 2, 3, 4, 5, 6, 7)
val index = java.util.Arrays.binarySearch(arr6, 5)
println(s"Found at index: $index")

// Custom binary search
def binarySearch[T: Ordering](arr: Array[T], target: T): Int = {
  val ord = implicitly[Ordering[T]]
  var left = 0
  var right = arr.length - 1
  
  while (left <= right) {
    val mid = left + (right - left) / 2
    val cmp = ord.compare(arr(mid), target)
    if (cmp == 0) return mid
    else if (cmp < 0) left = mid + 1
    else right = mid - 1
  }
  -1
}

val arr7 = Array(1, 2, 3, 4, 5, 6, 7)
val index2 = binarySearch(arr7, 5)
println(s"Found at index: $index2")

// Using sort with implicit ordering
implicit val reverseOrdering: Ordering[Int] = Ordering[Int].reverse
val sorted5 = List(5, 2, 8, 1, 9, 3).sorted
println(sorted5)
Advanced
38. What are mathematical operations in Scala?

Scala provides mathematical operations through scala.math and external libraries like Breeze.

  • Arithmetic: +, -, *, /, %
  • Trigonometric: math.sin, math.cos, math.tan
  • Statistics: data.sum, custom functions
  • Linear algebra: Breeze library
  • Random: math.random
scala
// Mathematical Operations in Scala
// Basic arithmetic
val x = 10
val y = 3
println(s"x + y = ${x + y}")
println(s"x - y = ${x - y}")
println(s"x * y = ${x * y}")
println(s"x / y = ${x / y}")
println(s"x % y = ${x % y}")
println(s"x ^ y = ${math.pow(x, y)}")

// Mathematical functions
val pi = math.Pi
println(s"sin(pi/4) = ${math.sin(pi / 4)}")
println(s"cos(pi/4) = ${math.cos(pi / 4)}")
println(s"tan(pi/4) = ${math.tan(pi / 4)}")
println(s"exp(1) = ${math.exp(1)}")
println(s"log(e) = ${math.log(math.exp(1))}")
println(s"log10(100) = ${math.log10(100)}")
println(s"sqrt(9) = ${math.sqrt(9)}")

// Special functions
println(s"abs(-5) = ${math.abs(-5)}")
println(s"ceil(3.14) = ${math.ceil(3.14)}")
println(s"floor(3.14) = ${math.floor(3.14)}")
println(s"round(3.14) = ${math.round(3.14)}")
println(s"max(1, 3, 5, 2, 4) = ${math.max(math.max(math.max(math.max(1, 3), 5), 2), 4)}")
println(s"min(1, 3, 5, 2, 4) = ${math.min(math.min(math.min(math.min(1, 3), 5), 2), 4)}")

// Random numbers
println(s"Random: ${math.random()}")

// Statistics (using Scala's standard library)
val data = (1 to 10).map(_.toDouble)
println(s"sum = ${data.sum}")
println(s"mean = ${data.sum / data.length}")
println(s"min = ${data.min}")
println(s"max = ${data.max}")

// Complex numbers (using spire or scala-math)
/*
import spire.math._
import spire.implicits._

val c1 = Complex(1.0, 2.0)
val c2 = Complex(3.0, 4.0)
val c3 = c1 + c2
val c4 = c1 * c2
*/

// Using Breeze for linear algebra
/*
import breeze.linalg._

val A = DenseMatrix((1.0, 2.0), (3.0, 4.0))
val B = DenseMatrix((5.0, 6.0), (7.0, 8.0))

val C = A * B
val D = A + B
val E = A.t
*/

// Using Apache Commons Math
// libraryDependencies += "org.apache.commons" % "commons-math3" % "3.6.1"

/*
import org.apache.commons.math3.stat.StatUtils
import org.apache.commons.math3.linear._

val data2 = Array(1.0, 2.0, 3.0, 4.0, 5.0)
println(StatUtils.mean(data2))
println(StatUtils.variance(data2))

val matrix = new Array2DRowRealMatrix(Array(
  Array(1.0, 2.0),
  Array(3.0, 4.0)
))
val inverse = new LUDecomposition(matrix).getSolver().getInverse()
*/
Advanced
39. How to do data serialization in Scala?

Scala provides data serialization through Java serialization, JSON, Pickling, XML, and libraries like Avro.

  • Java serialization: ObjectOutputStream
  • JSON: Play JSON, Circe
  • Pickling: scala.pickling
  • XML: scala.xml
  • YAML: SnakeYAML
scala
// Data Serialization in Scala
import java.io.{ObjectOutputStream, ObjectInputStream, FileOutputStream, FileInputStream}

// Using Java serialization
class Person(val name: String, val age: Int) extends Serializable

val person = new Person("Alice", 25)

// Serialize
val out = new ObjectOutputStream(new FileOutputStream("person.ser"))
out.writeObject(person)
out.close()

// Deserialize
val in = new ObjectInputStream(new FileInputStream("person.ser"))
val deserialized = in.readObject().asInstanceOf[Person]
in.close()

println(s"Name: ${deserialized.name}, Age: ${deserialized.age}")

// Using Pickling (requires library)
// libraryDependencies += "org.scala-lang.modules" %% "scala-pickling" % "1.0.0"

/*
import scala.pickling._
import scala.pickling.Defaults._

case class User(name: String, age: Int)

val user = User("Alice", 25)
val pickle = user.pickle
val unpickled = pickle.unpickle[User]
*/

// Using JSON (Play JSON)
import play.api.libs.json._

case class UserJson(name: String, age: Int, hobbies: List[String])
implicit val userFormat: Format[UserJson] = Json.format[UserJson]

val user = UserJson("Alice", 25, List("reading", "coding"))
val json = Json.toJson(user)
val jsonString = Json.stringify(json)
println(jsonString)

val parsed = Json.parse(jsonString).as[UserJson]
println(parsed.name)

// Using CSV
def toCSV(data: List[List[String]]): String = {
  data.map(_.mkString(",")).mkString("
")
}

val csvData = List(
  List("Name", "Age", "City"),
  List("Alice", "25", "NYC"),
  List("Bob", "30", "LA")
)

val csvString = toCSV(csvData)
println(csvString)

// Using XML
import scala.xml._

val xml = <person name="Alice" age="25">
  <hobbies>
    <hobby>reading</hobby>
    <hobby>coding</hobby>
  </hobbies>
</person>

println(xml)
val name = xml  "@name"
val age = xml  "@age"

// Using YAML (requires library)
// libraryDependencies += "org.yaml" % "snakeyaml" % "1.30"

/*
import org.yaml.snakeyaml.Yaml

val yaml = new Yaml()
val data = Map("name" -> "Alice", "age" -> 25)
val yamlString = yaml.dump(data)
println(yamlString)
*/

// Using Protocol Buffers (requires library)
// libraryDependencies += "com.google.protobuf" % "protobuf-java" % "3.21.12"

// Using Avro (requires library)
// libraryDependencies += "org.apache.avro" % "avro" % "1.11.1"
Advanced
40. How to interface with external systems in Scala?

Scala interfaces with external systems through JDBC, Slick, Redis clients, HTTP, and shell commands.

  • Database: java.sql.DriverManager, Slick
  • Redis: com.redis.RedisClient
  • HTTP: java.net.HttpURLConnection
  • Shell: scala.sys.process._
  • Environment: sys.env, sys.props
scala
// Interfacing with External Systems
import java.sql.{DriverManager, Connection, ResultSet}

// Database connection (JDBC)
def queryDatabase(): Unit = {
  val url = "jdbc:postgresql://localhost:5432/test"
  val user = "user"
  val password = "pass"
  
  try {
    val connection = DriverManager.getConnection(url, user, password)
    val statement = connection.createStatement()
    val resultSet = statement.executeQuery("SELECT * FROM users WHERE id = 1")
    
    while (resultSet.next()) {
      val name = resultSet.getString("name")
      println(s"User: $name")
    }
    
    resultSet.close()
    statement.close()
    connection.close()
  } catch {
    case e: Exception => println(s"Database error: ${e.getMessage}")
  }
}

// Using Slick (functional database library)
/*
import slick.jdbc.PostgresProfile.api._
import scala.concurrent.Await
import scala.concurrent.duration._

class Users(tag: Tag) extends Table[(Int, String)](tag, "users") {
  def id = column[Int]("id", O.PrimaryKey)
  def name = column[String]("name")
  def * = (id, name)
}

val users = TableQuery[Users]
val db = Database.forConfig("postgres")

val query = users.filter(_.id === 1).result
val result = Await.result(db.run(query), 5.seconds)
result.foreach { case (id, name) => println(s"User: $name") }
*/

// Using Redis (requires library)
// libraryDependencies += "net.debasishg" %% "redisclient" % "3.42"

/*
import com.redis._

val client = new RedisClient("localhost", 6379)
client.set("key", "value")
val value = client.get("key")
println(value)
*/

// Using HTTP client
import java.net.HttpURLConnection
import java.io.{BufferedReader, InputStreamReader}

def httpGet(url: String): String = {
  val connection = new java.net.URL(url).openConnection().asInstanceOf[HttpURLConnection]
  connection.setRequestMethod("GET")
  connection.setRequestProperty("User-Agent", "Scala")
  
  val reader = new BufferedReader(new InputStreamReader(connection.getInputStream))
  val response = Iterator.continually(reader.readLine()).takeWhile(_ != null).mkString("
")
  reader.close()
  connection.disconnect()
  response
}

val response = httpGet("https://api.github.com")
println(response.take(500))

// Using Shell commands
import scala.sys.process._

def executeCommand(cmd: String): String = {
  cmd.!!.trim
}

val output = executeCommand("ls -la")
println(output)

// Using environment variables
val envVar = sys.env.getOrElse("HOME", "Not set")
println(s"HOME: $envVar")

// Using System properties
val osName = sys.props.getOrElse("os.name", "Unknown")
println(s"OS: $osName")
Coding Round
41. Reverse a string

Reverse a string using reverse, manual iteration, or recursion.

  • Built-in: s.reverse
  • Manual: s.foldLeft("")((acc, c) => c + acc)
  • Recursive: if (s.isEmpty) "" else reverse(s.tail) + s.head
  • Performance: O(n) time
scala
// Reverse a string
def reverseString(s: String): String = s.reverse

def reverseStringManual(s: String): String = {
  s.foldLeft("")((acc, c) => c + acc)
}

def reverseStringRecursive(s: String): String = {
  if (s.length <= 1) s
  else reverseStringRecursive(s.tail) + s.head
}

val s = "hello"
println(s"Original: $s")
println(s"Reversed: ${reverseString(s)}")
println(s"Reversed (manual): ${reverseStringManual(s)}")
println(s"Reversed (recursive): ${reverseStringRecursive(s)}")
Coding Round
42. Check palindrome

Check if a string is a palindrome by comparing characters from both ends.

  • Built-in: s == s.reverse
  • Manual: Two-pointer comparison
  • Recursive: s.head == s.last && isPalindrome(s.tail.init)
  • Case insensitive: s.toLowerCase
scala
// Check palindrome
def isPalindrome(s: String): Boolean = {
  val cleaned = s.toLowerCase.replaceAll(" ", "")
  cleaned == cleaned.reverse
}

def isPalindromeManual(s: String): Boolean = {
  val cleaned = s.toLowerCase.replaceAll(" ", "")
  val chars = cleaned.toCharArray
  var i = 0
  var j = chars.length - 1
  while (i < j) {
    if (chars(i) != chars(j)) return false
    i += 1
    j -= 1
  }
  true
}

def isPalindromeRecursive(s: String): Boolean = {
  val cleaned = s.toLowerCase.replaceAll(" ", "")
  if (cleaned.length <= 1) true
  else if (cleaned.head != cleaned.last) false
  else isPalindromeRecursive(cleaned.substring(1, cleaned.length - 1))
}

val strings = List("racecar", "hello", "A man a plan a canal Panama", "race a car")
strings.foreach { s =>
  println(s""""$s" is palindrome: ${isPalindrome(s)}""")
}
Coding Round
43. Find max in array

Find the maximum value using max, iteration, or recursion.

  • Built-in: arr.max
  • Manual: var max = arr(0); for (i <- 1 until arr.length) { if (arr(i) > max) max = arr(i) }
  • Recursive: if (arr.isEmpty) null else ...
  • Reduce: arr.reduce(_ max _)
scala
// Find max in array
def findMax(arr: Array[Int]): Int = arr.max

def findMaxManual(arr: Array[Int]): Int = {
  if (arr.isEmpty) throw new IllegalArgumentException("Array is empty")
  var max = arr(0)
  for (i <- 1 until arr.length) {
    if (arr(i) > max) max = arr(i)
  }
  max
}

def findMaxRecursive(arr: Array[Int], index: Int = 0, max: Int = Int.MinValue): Int = {
  if (index >= arr.length) max
  else findMaxRecursive(arr, index + 1, if (arr(index) > max) arr(index) else max)
}

val arr = Array(1, 5, 3, 9, 2)
println(s"Array: ${arr.mkString(", ")}")
println(s"Max: ${findMax(arr)}")
println(s"Max (manual): ${findMaxManual(arr)}")
println(s"Max (recursive): ${findMaxRecursive(arr)}")
Coding Round
44. Remove duplicates

Remove duplicates using distinct, manual fold, or Set.

  • Built-in: list.distinct
  • Manual: list.foldLeft(List.empty[T])((acc, item) => if (acc.contains(item)) acc else acc :+ item)
  • Set: list.toSet.toList
  • Preserve order: Manual fold
scala
// Remove duplicates
def removeDuplicates[T](list: List[T]): List[T] = list.distinct

def removeDuplicatesManual[T](list: List[T]): List[T] = {
  list.foldLeft(List.empty[T]) { (acc, item) =>
    if (acc.contains(item)) acc else acc :+ item
  }
}

def removeDuplicatesSet[T](list: List[T]): List[T] = list.toSet.toList

val list = List("apple", "banana", "apple", "orange", "banana", "grape")
println(s"Original: ${list.mkString(", ")}")
println(s"Without duplicates: ${removeDuplicates(list).mkString(", ")}")
println(s"Without duplicates (manual): ${removeDuplicatesManual(list).mkString(", ")}")
println(s"Without duplicates (set): ${removeDuplicatesSet(list).mkString(", ")}")
Coding Round
45. Merge arrays

Merge arrays using ++, concat, or sorted merge.

  • Concatenate: arr1 ++ arr2
  • Sorted merge: mergeSorted(arr1, arr2)
  • Unique: (arr1 ++ arr2).distinct
  • Performance: O(n) time
scala
// Merge arrays
def mergeArrays[T](arr1: Array[T], arr2: Array[T]): Array[T] = arr1 ++ arr2

def mergeSorted(arr1: Array[Int], arr2: Array[Int]): Array[Int] = {
  val result = Array.newBuilder[Int]
  var i = 0
  var j = 0
  
  while (i < arr1.length && j < arr2.length) {
    if (arr1(i) <= arr2(j)) {
      result += arr1(i)
      i += 1
    } else {
      result += arr2(j)
      j += 1
    }
  }
  
  while (i < arr1.length) {
    result += arr1(i)
    i += 1
  }
  
  while (j < arr2.length) {
    result += arr2(j)
    j += 1
  }
  
  result.result()
}

def mergeUnique[T](arr1: Array[T], arr2: Array[T]): Array[T] = {
  (arr1 ++ arr2).distinct
}

val arr1 = Array(1, 2, 3)
val arr2 = Array(4, 5, 6)
println(s"Merged: ${mergeArrays(arr1, arr2).mkString(", ")}")

val sorted1 = Array(1, 3, 5, 7)
val sorted2 = Array(2, 4, 6, 8)
println(s"Merged sorted: ${mergeSorted(sorted1, sorted2).mkString(", ")}")
Coding Round
46. Convert string to number

Convert string to number using toInt, toDouble, or toFloat.

  • Int: s.toInt
  • Double: s.toDouble
  • Float: s.toFloat
  • Safe: Try(s.toInt).getOrElse(0)
scala
// Convert string to number
def stringToNumber(s: String): Double = s.toDouble

def stringToInt(s: String): Int = s.toInt

def stringToFloat(s: String): Float = s.toFloat

def stringToNumberSafe(s: String): Double = {
  try {
    s.toDouble
  } catch {
    case _: NumberFormatException => 0.0
  }
}

val strings = List("42", "3.14", "hello", "123", "45.67")
strings.foreach { s =>
  println(s""""$s" -> int: ${stringToInt(s)}, float: ${stringToFloat(s)}""")
}
Coding Round
47. Loop through dictionary

Iterate through a map using foreach or for comprehension.

  • foreach: map.foreach { case (k, v) => ... }
  • for: for ((k, v) <- map) { ... }
  • Keys: map.keys
  • Find key: map.get(key)
scala
// Loop through dictionary (Map)
def loopMap(map: Map[String, Any]): Unit = {
  map.foreach { case (key, value) =>
    println(s"$key => $value")
  }
}

def findKey[V](map: Map[String, V], key: String): Option[V] = map.get(key)

val data = Map("name" -> "Alice", "age" -> 25, "city" -> "NYC")
println("Dictionary:")
loopMap(data)
println()

val name = findKey(data, "name")
println(s"Name: ${name.getOrElse("Not found")}")
val country = findKey(data, "country")
println(s"Country: ${country.getOrElse("Not found")}")
Coding Round
48. Delay function execution

Delay execution using Thread.sleep or Future for async.

  • Blocking: Thread.sleep(seconds * 1000)
  • Async: Future { Thread.sleep(delay); callback }
  • Callback: delayWithCallback(seconds)(callback)(resultCallback)
  • Use case: Scheduling
scala
// Delay function execution
def delaySeconds(seconds: Long)(callback: => Unit): Unit = {
  Thread.sleep(seconds * 1000)
  callback
}

def delayAsync(seconds: Long)(callback: => Unit): Future[Unit] = {
  Future {
    Thread.sleep(seconds * 1000)
    callback
  }
}

def delayWithCallback(seconds: Long)(callback: => Unit)(resultCallback: => Unit): Future[Unit] = {
  Future {
    Thread.sleep(seconds * 1000)
    callback
    resultCallback
  }
}

def delayedPrint(message: String, seconds: Long): Unit = {
  println(s"Starting delay of $seconds seconds")
  delaySeconds(seconds) {
    println(message)
  }
}

println("Delayed execution examples:")
delayedPrint("After 2 seconds", 2)
println("Main script continues")
Coding Round
49. HTTP GET request

Make HTTP requests using HttpURLConnection or dispatch.

  • GET: new URL(url).openConnection().asInstanceOf[HttpURLConnection]
  • POST: connection.setRequestMethod("POST")
  • Headers: connection.setRequestProperty("User-Agent", "Scala")
  • Error handling: try { ... } catch { ... }
scala
// HTTP GET request
import java.net.HttpURLConnection
import java.io.{BufferedReader, InputStreamReader}

def fetchData(url: String): String = {
  val connection = new java.net.URL(url).openConnection().asInstanceOf[HttpURLConnection]
  connection.setRequestMethod("GET")
  connection.setRequestProperty("User-Agent", "Scala")
  
  try {
    val reader = new BufferedReader(new InputStreamReader(connection.getInputStream))
    val response = Iterator.continually(reader.readLine()).takeWhile(_ != null).mkString("
")
    reader.close()
    response
  } catch {
    case e: Exception =>
      println(s"Error: ${e.getMessage}")
      ""
  } finally {
    connection.disconnect()
  }
}

def postData(url: String, data: String): String = {
  val connection = new java.net.URL(url).openConnection().asInstanceOf[HttpURLConnection]
  connection.setRequestMethod("POST")
  connection.setRequestProperty("Content-Type", "application/json")
  connection.setDoOutput(true)
  
  val writer = new java.io.PrintWriter(connection.getOutputStream)
  writer.write(data)
  writer.flush()
  writer.close()
  
  try {
    val reader = new BufferedReader(new InputStreamReader(connection.getInputStream))
    val response = Iterator.continually(reader.readLine()).takeWhile(_ != null).mkString("
")
    reader.close()
    response
  } catch {
    case e: Exception =>
      println(s"Error: ${e.getMessage}")
      ""
  } finally {
    connection.disconnect()
  }
}

// Example
val result = fetchData("https://api.github.com")
if (result.nonEmpty) {
  println(result.take(500) + "...")
}
Coding Round
50. Create a promise-like task

Create promise-like behavior using Future and Promise.

  • Promise: Promise[String]()
  • Future: promise.future
  • Complete: promise.success(value), promise.failure(error)
  • Chain: for { r1 <- p1; r2 <- p2 } yield (r1, r2)
scala
// Create a promise-like task
import scala.concurrent.{Future, Promise}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration._

def createPromise(shouldResolve: Boolean): Future[String] = {
  val promise = Promise[String]()
  
  Future {
    Thread.sleep(1000)
    if (shouldResolve) {
      promise.success("Success!")
    } else {
      promise.failure(new Exception("Failed!"))
    }
  }
  
  promise.future
}

def chainPromises(p1: Future[String], p2: Future[String]): Future[(String, String)] = {
  for {
    result1 <- p1
    _ <- Future(println(s"First: $result1"))
    result2 <- p2
    _ <- Future(println(s"Second: $result2"))
  } yield (result1, result2)
}

// Example
val promise1 = createPromise(true)
val promise2 = createPromise(true)

chainPromises(promise1, promise2).onComplete {
  case scala.util.Success((r1, r2)) =>
    println(s"Both completed: $r1, $r2")
  case scala.util.Failure(e) =>
    println(s"Error: ${e.getMessage}")
}

// Wait for completion
Thread.sleep(3000)
Coding Round
51. Factorial

Calculate factorial using recursion or iteration.

  • Recursive: if (n <= 1) 1 else n * factorial(n - 1)
  • Iterative: for (i <- 2 to n) { result *= i }
  • Tail recursive: def fact(n: Int, acc: Int = 1): Int = if (n <= 1) acc else fact(n - 1, acc * n)
  • Edge cases: 0! = 1
scala
// Factorial
def factorial(n: Int): Int = {
  if (n <= 1) 1
  else n * factorial(n - 1)
}

def factorialIterative(n: Int): Int = {
  var result = 1
  for (i <- 2 to n) {
    result *= i
  }
  result
}

def factorialTail(n: Int, acc: Int = 1): Int = {
  if (n <= 1) acc
  else factorialTail(n - 1, acc * n)
}

val n = 5
println(s"Factorial of $n:")
println(s"Recursive: ${factorial(n)}")
println(s"Iterative: ${factorialIterative(n)}")
println(s"Tail recursive: ${factorialTail(n)}")
Coding Round
52. Fibonacci

Calculate Fibonacci numbers using recursion, iteration, or memoization.

  • Recursive: if (n <= 1) n else fib(n - 1) + fib(n - 2)
  • Iterative: var a = 0; var b = 1; for (_ <- 2 to n) { val c = a + b; a = b; b = c }
  • Memoized: val cache = mutable.Map.empty[Int, Int]
  • Time: O(n) iterative
scala
// Fibonacci
def fibonacci(n: Int): Int = {
  if (n <= 1) n
  else fibonacci(n - 1) + fibonacci(n - 2)
}

def fibonacciIterative(n: Int): Int = {
  if (n <= 1) n
  else {
    var a = 0
    var b = 1
    for (_ <- 2 to n) {
      val c = a + b
      a = b
      b = c
    }
    b
  }
}

def fibonacciMemoized(n: Int): Int = {
  import scala.collection.mutable.Map
  val cache = Map.empty[Int, Int]
  
  def fib(n: Int): Int = {
    if (n <= 1) n
    else if (cache.contains(n)) cache(n)
    else {
      val result = fib(n - 1) + fib(n - 2)
      cache(n) = result
      result
    }
  }
  fib(n)
}

val n = 10
println(s"Fibonacci of $n:")
println(s"Recursive: ${fibonacci(n)}")
println(s"Iterative: ${fibonacciIterative(n)}")
println(s"Memoized: ${fibonacciMemoized(n)}")
Coding Round
53. FizzBuzz

Print numbers with FizzBuzz logic using conditional statements or pattern matching.

  • If-else: if (i % 15 == 0) "FizzBuzz" else if ...
  • Pattern matching: (i % 3 == 0, i % 5 == 0) match { case (true, true) => ... }
  • List: (1 to n).map(...)
  • Output: println
scala
// FizzBuzz
def fizzbuzz(n: Int): Unit = {
  for (i <- 1 to n) {
    if (i % 15 == 0) println("FizzBuzz")
    else if (i % 3 == 0) println("Fizz")
    else if (i % 5 == 0) println("Buzz")
    else println(i)
  }
}

def fizzbuzzList(n: Int): List[String] = {
  (1 to n).map { i =>
    if (i % 15 == 0) "FizzBuzz"
    else if (i % 3 == 0) "Fizz"
    else if (i % 5 == 0) "Buzz"
    else i.toString
  }.toList
}

def fizzbuzzMatch(n: Int): Unit = {
  for (i <- 1 to n) {
    (i % 3 == 0, i % 5 == 0) match {
      case (true, true) => println("FizzBuzz")
      case (true, false) => println("Fizz")
      case (false, true) => println("Buzz")
      case _ => println(i)
    }
  }
}

println("FizzBuzz for 15:")
fizzbuzz(15)

println("FizzBuzz list:")
println(fizzbuzzList(15).mkString(", "))
Coding Round
54. Find missing number

Find missing number using sum formula or XOR operation.

  • Sum: n * (n + 1) / 2 - arr.sum
  • XOR: xorAll ^ xorArr
  • Time: O(n)
  • Edge cases: Empty array
scala
// Find missing number
def findMissing(arr: Array[Int]): Int = {
  val n = arr.length + 1
  val total = n * (n + 1) / 2
  val sum = arr.sum
  total - sum
}

def findMissingXOR(arr: Array[Int]): Int = {
  val n = arr.length + 1
  var xorAll = 0
  for (i <- 1 to n) {
    xorAll ^= i
  }
  var xorArr = 0
  for (value <- arr) {
    xorArr ^= value
  }
  xorAll ^ xorArr
}

val arr = Array(1, 2, 4, 5, 6)
println(s"Missing number: ${findMissing(arr)}")
println(s"Missing number (XOR): ${findMissingXOR(arr)}")
Coding Round
55. Find duplicates

Find duplicates using groupBy, foldLeft, or manual tracking.

  • groupBy: list.groupBy(identity).collect { case (k, v) if v.size > 1 => k }
  • Manual: var seen = Set.empty[T]; var duplicates = Set.empty[T]
  • Time: O(n)
  • Returns: List of duplicates
scala
// Find duplicates
def findDuplicates[T](list: List[T]): List[T] = {
  list.groupBy(identity).collect { case (k, v) if v.size > 1 => k }.toList
}

def findDuplicatesManual[T](list: List[T]): List[T] = {
  var seen = Set.empty[T]
  var duplicates = Set.empty[T]
  for (item <- list) {
    if (seen.contains(item)) {
      duplicates += item
    } else {
      seen += item
    }
  }
  duplicates.toList
}

val list = List(1, 2, 3, 2, 4, 3, 5, 6, 5)
println(s"Original: ${list.mkString(", ")}")
println(s"Duplicates: ${findDuplicates(list).mkString(", ")}")
println(s"Duplicates (manual): ${findDuplicatesManual(list).mkString(", ")}")
Coding Round
56. Sum of array

Sum array elements using sum, manual loop, or recursion.

  • Built-in: arr.sum
  • Manual: var sum = 0; for (value <- arr) { sum += value }
  • Recursive: if (index >= arr.length) 0 else arr(index) + sumRecursive(arr, index + 1)
  • Empty: Returns 0
scala
// Sum of array
def sumArray(arr: Array[Int]): Int = arr.sum

def sumArrayManual(arr: Array[Int]): Int = {
  var sum = 0
  for (value <- arr) {
    sum += value
  }
  sum
}

def sumArrayRecursive(arr: Array[Int], index: Int = 0): Int = {
  if (index >= arr.length) 0
  else arr(index) + sumArrayRecursive(arr, index + 1)
}

val arr = Array(1, 2, 3, 4, 5)
println(s"Array: ${arr.mkString(", ")}")
println(s"Sum: ${sumArray(arr)}")
println(s"Sum (manual): ${sumArrayManual(arr)}")
println(s"Sum (recursive): ${sumArrayRecursive(arr)}")
Coding Round
57. Average of array

Calculate average by dividing sum by length.

  • Method: arr.sum.toDouble / arr.length
  • Integer: arr.sum / arr.length
  • Empty: Return 0
  • Float: Returns double
scala
// Average of array
def averageArray(arr: Array[Int]): Double = {
  if (arr.isEmpty) 0.0
  else arr.sum.toDouble / arr.length
}

def averageInteger(arr: Array[Int]): Int = {
  if (arr.isEmpty) 0
  else arr.sum / arr.length
}

val intArr = Array(1, 2, 3, 4, 5)
val floatArr = Array(1.0, 2.0, 3.0, 4.0, 5.0)
println(s"Average (int array): ${averageArray(intArr)}")
println(s"Average (float array): ${floatArr.sum / floatArr.length}")
println(s"Average (integer): ${averageInteger(intArr)}")
Coding Round
58. Sort array ascending

Sort arrays using sorted or quickSort.

  • Non-mutating: arr.sorted
  • Mutating: scala.util.Sorting.quickSort(arr)
  • Custom: arr.sortWith(_ < _)
  • Time: O(n log n)
scala
// Sort array ascending
def sortAscending[T: Ordering](arr: Array[T]): Array[T] = arr.sorted

def sortAscendingInPlace[T: Ordering](arr: Array[T]): Unit = {
  scala.util.Sorting.quickSort(arr)
}

val arr = Array(5, 2, 8, 1, 9, 3)
println(s"Original: ${arr.mkString(", ")}")
val sorted = sortAscending(arr)
println(s"Sorted ascending: ${sorted.mkString(", ")}")
sortAscendingInPlace(arr)
println(s"Sorted in-place: ${arr.mkString(", ")}")
Coding Round
59. Sort array descending

Sort descending using sorted with reverse ordering.

  • Non-mutating: arr.sorted(Ordering[Int].reverse)
  • Mutating: scala.util.Sorting.quickSort(arr)(Ordering[Int].reverse)
  • Custom: arr.sortWith(_ > _)
  • Time: O(n log n)
scala
// Sort array descending
def sortDescending[T: Ordering](arr: Array[T]): Array[T] = {
  arr.sorted(Ordering[T].reverse)
}

def sortDescendingInPlace[T: Ordering](arr: Array[T]): Unit = {
  scala.util.Sorting.quickSort(arr)(Ordering[T].reverse)
}

val arr = Array(5, 2, 8, 1, 9, 3)
println(s"Original: ${arr.mkString(", ")}")
val sorted = sortDescending(arr)
println(s"Sorted descending: ${sorted.mkString(", ")}")
sortDescendingInPlace(arr)
println(s"Sorted in-place: ${arr.mkString(", ")}")
Coding Round
60. Flatten nested array

Flatten nested arrays using recursion or flatMap.

  • Recursive: def flatten(list: List[_]): List[_] = list.flatMap { case inner: List[_] => flatten(inner) case item => List(item) }
  • Iterative: Stack-based approach
  • One level: list.flatten
  • Depth: Handle arbitrary depth
scala
// Flatten nested array
def flatten[T](list: List[T]): List[T] = {
  list.flatMap {
    case inner: List[_] => flatten(inner.asInstanceOf[List[T]])
    case item => List(item)
  }
}

def flattenIterative[T](list: List[T]): List[T] = {
  var result = List.empty[T]
  var stack = list.reverse
  while (stack.nonEmpty) {
    stack.head match {
      case inner: List[_] =>
        stack = inner.asInstanceOf[List[T]] ::: stack.tail
      case item =>
        result = item :: result
        stack = stack.tail
    }
  }
  result
}

val nested = List(List(1, 2), List(3, 4, 5), List(6), List(7, 8, 9, 10))
val deeper = List(List(1, 2), List(3, List(4, 5)))

println(s"Nested: ${nested.mkString(", ")}")
println(s"Flatten: ${flatten(nested).mkString(", ")}")
println(s"Deeper: ${deeper.mkString(", ")}")
println(s"Flatten deeper: ${flatten(deeper).mkString(", ")}")
Coding Round
61. Chunk array

Split array into chunks using grouped or manual slicing.

  • Built-in: arr.grouped(size).toArray
  • Manual: while (i < arr.length) { result += arr.slice(i, math.min(i + size, arr.length)); i += size }
  • Predicate: chunkByPredicate
  • Use case: Batch processing
scala
// Chunk array
def chunkArray[T](arr: Array[T], size: Int): Array[Array[T]] = {
  arr.grouped(size).toArray
}

def chunkArrayManual[T](arr: Array[T], size: Int): Array[Array[T]] = {
  val result = scala.collection.mutable.ArrayBuffer.empty[Array[T]]
  var i = 0
  while (i < arr.length) {
    val end = math.min(i + size, arr.length)
    result += arr.slice(i, end)
    i += size
  }
  result.toArray
}

def chunkByPredicate[T](arr: Array[T], predicate: T => Boolean): Array[Array[T]] = {
  val result = scala.collection.mutable.ArrayBuffer.empty[Array[T]]
  var current = scala.collection.mutable.ArrayBuffer.empty[T]
  
  for (item <- arr) {
    if (predicate(item)) {
      if (current.nonEmpty) {
        result += current.toArray
        current.clear()
      }
      result += Array(item)
    } else {
      current += item
    }
  }
  
  if (current.nonEmpty) {
    result += current.toArray
  }
  
  result.toArray
}

val arr = (1 to 10).toArray
println(s"Original: ${arr.mkString(", ")}")
println("Chunk (size 3):")
val chunks = chunkArray(arr, 3)
chunks.foreach(chunk => println(s"[${chunk.mkString(", ")}]"))
Coding Round
63. Quick sort

Implement quick sort with partitioning and recursion.

  • Recursive: def quickSort(list: List[Int]): List[Int] = { if (list.length <= 1) list else { val pivot = list.head; val (left, right) = list.tail.partition(_ < pivot); quickSort(left) ::: pivot :: quickSort(right) } }
  • In-place: quickSortInPlace
  • Pivot: First or last element
  • Time: O(n log n) average
scala
// Quick sort
def quickSort[T: Ordering](list: List[T]): List[T] = {
  if (list.length <= 1) list
  else {
    val pivot = list.head
    val (left, right) = list.tail.partition(_ < pivot)
    quickSort(left) ::: pivot :: quickSort(right)
  }
}

def quickSortInPlace[T: Ordering](arr: Array[T], low: Int = 0, high: Int = -1): Unit = {
  val ord = implicitly[Ordering[T]]
  val h = if (high < 0) arr.length - 1 else high
  
  if (low < h) {
    val pi = partition(arr, low, h)(ord)
    quickSortInPlace(arr, low, pi - 1)
    quickSortInPlace(arr, pi + 1, h)
  }
}

def partition[T](arr: Array[T], low: Int, high: Int)(implicit ord: Ordering[T]): Int = {
  val pivot = arr(high)
  var i = low - 1
  
  for (j <- low until high) {
    if (ord.lteq(arr(j), pivot)) {
      i += 1
      val temp = arr(i)
      arr(i) = arr(j)
      arr(j) = temp
    }
  }
  
  val temp = arr(i + 1)
  arr(i + 1) = arr(high)
  arr(high) = temp
  
  i + 1
}

val list = List(5, 3, 8, 4, 2, 7, 1, 6)
val arr = Array(5, 3, 8, 4, 2, 7, 1, 6)

println(s"Original: ${list.mkString(", ")}")
println(s"Quick sort: ${quickSort(list).mkString(", ")}")
quickSortInPlace(arr)
println(s"Quick sort (in-place): ${arr.mkString(", ")}")
Coding Round
64. Merge sort

Implement merge sort with divide and conquer approach.

  • Divide: val mid = list.length / 2; val (left, right) = list.splitAt(mid)
  • Merge: def merge(left: List[Int], right: List[Int]): List[Int] = { (left, right) match { case (Nil, _) => right; case (_, Nil) => left; case (lh :: lt, rh :: rt) => if (lh < rh) lh :: merge(lt, right) else rh :: merge(left, rt) } }
  • Time: O(n log n)
scala
// Merge sort
def mergeSort[T: Ordering](list: List[T]): List[T] = {
  if (list.length <= 1) list
  else {
    val mid = list.length / 2
    val (left, right) = list.splitAt(mid)
    merge(mergeSort(left), mergeSort(right))
  }
}

def merge[T: Ordering](left: List[T], right: List[T]): List[T] = {
  val ord = implicitly[Ordering[T]]
  
  def loop(l: List[T], r: List[T], acc: List[T]): List[T] = {
    (l, r) match {
      case (Nil, _) => acc.reverse ::: r
      case (_, Nil) => acc.reverse ::: l
      case (lh :: lt, rh :: rt) =>
        if (ord.lteq(lh, rh)) loop(lt, r, lh :: acc)
        else loop(l, rt, rh :: acc)
    }
  }
  
  loop(left, right, Nil)
}

def mergeSortInPlace[T: Ordering](arr: Array[T], temp: Array[T], low: Int, high: Int): Unit = {
  if (low < high) {
    val mid = low + (high - low) / 2
    mergeSortInPlace(arr, temp, low, mid)
    mergeSortInPlace(arr, temp, mid + 1, high)
    mergeInPlace(arr, temp, low, mid, high)
  }
}

def mergeInPlace[T: Ordering](arr: Array[T], temp: Array[T], low: Int, mid: Int, high: Int): Unit = {
  val ord = implicitly[Ordering[T]]
  
  for (i <- low to high) {
    temp(i) = arr(i)
  }
  
  var i = low
  var j = mid + 1
  var k = low
  
  while (i <= mid && j <= high) {
    if (ord.lteq(temp(i), temp(j))) {
      arr(k) = temp(i)
      i += 1
    } else {
      arr(k) = temp(j)
      j += 1
    }
    k += 1
  }
  
  while (i <= mid) {
    arr(k) = temp(i)
    i += 1
    k += 1
  }
}

val list = List(5, 3, 8, 4, 2, 7, 1, 6)
println(s"Original: ${list.mkString(", ")}")
println(s"Merge sort: ${mergeSort(list).mkString(", ")}")
Coding Round
65. Bubble sort

Implement bubble sort with optimization to stop early if no swaps occur.

  • Basic: for (i <- 0 until n - 1) { for (j <- 0 until n - i - 1) { if (arr(j) > arr(j + 1)) { val temp = arr(j); arr(j) = arr(j + 1); arr(j + 1) = temp } } }
  • Optimized: var swapped = false; for (j <- 0 until n - i - 1) { if (...) { ...; swapped = true } }; if (!swapped) return result
  • Time: O(n²) worst case
scala
// Bubble sort
def bubbleSort[T: Ordering](arr: Array[T]): Array[T] = {
  val result = arr.clone()
  val n = result.length
  for (i <- 0 until n - 1) {
    for (j <- 0 until n - i - 1) {
      if (implicitly[Ordering[T]].gt(result(j), result(j + 1))) {
        val temp = result(j)
        result(j) = result(j + 1)
        result(j + 1) = temp
      }
    }
  }
  result
}

def bubbleSortOptimized[T: Ordering](arr: Array[T]): Array[T] = {
  val ord = implicitly[Ordering[T]]
  val result = arr.clone()
  val n = result.length
  for (i <- 0 until n - 1) {
    var swapped = false
    for (j <- 0 until n - i - 1) {
      if (ord.gt(result(j), result(j + 1))) {
        val temp = result(j)
        result(j) = result(j + 1)
        result(j + 1) = temp
        swapped = true
      }
    }
    if (!swapped) return result
  }
  result
}

val arr = Array(5, 3, 8, 4, 2, 7, 1, 6)
println(s"Original: ${arr.mkString(", ")}")
println(s"Bubble sort: ${bubbleSort(arr).mkString(", ")}")
println(s"Bubble sort optimized: ${bubbleSortOptimized(arr).mkString(", ")}")
Coding Round
66. Intersection of arrays

Find intersection using intersect or filter.

  • Built-in: arr1.intersect(arr2)
  • Filter: arr1.filter(arr2.contains)
  • Set: arr1.filter(arr2.toSet.contains)
  • Time: O(n*m) or O(n+m) with Set
scala
// Intersection of arrays
def intersection[T](arr1: Array[T], arr2: Array[T]): Array[T] = {
  arr1.intersect(arr2)
}

def intersectionManual[T](arr1: Array[T], arr2: Array[T]): Array[T] = {
  arr1.filter(arr2.contains).distinct
}

def intersectionSet[T](arr1: Array[T], arr2: Array[T]): Array[T] = {
  val set2 = arr2.toSet
  arr1.filter(set2.contains).distinct
}

val arr1 = Array("apple", "banana", "orange", "grape", "kiwi")
val arr2 = Array("banana", "kiwi", "mango", "grape")
println(s"Intersection: ${intersection(arr1, arr2).mkString(", ")}")
println(s"Intersection (manual): ${intersectionManual(arr1, arr2).mkString(", ")}")

val ints1 = Array(1, 2, 3, 4, 5)
val ints2 = Array(4, 5, 6, 7, 8)
println(s"Intersection (ints): ${intersection(ints1, ints2).mkString(", ")}")
Coding Round
67. Union of arrays

Union arrays using distinct or manual merge.

  • Built-in: (arr1 ++ arr2).distinct
  • Manual: val result = ArrayBuffer.empty[T]; result ++= arr1; for (item <- arr2) { if (!result.contains(item)) result += item }
  • Time: O(n+m)
scala
// Union of arrays
def union[T](arr1: Array[T], arr2: Array[T]): Array[T] = {
  (arr1 ++ arr2).distinct
}

def unionManual[T](arr1: Array[T], arr2: Array[T]): Array[T] = {
  val result = scala.collection.mutable.ArrayBuffer.empty[T]
  result ++= arr1
  for (item <- arr2) {
    if (!result.contains(item)) {
      result += item
    }
  }
  result.toArray
}

val arr1 = Array("apple", "banana", "orange")
val arr2 = Array("orange", "grape", "kiwi")
println(s"Union: ${union(arr1, arr2).mkString(", ")}")
println(s"Union (manual): ${unionManual(arr1, arr2).mkString(", ")}")

val ints1 = Array(1, 2, 3, 4)
val ints2 = Array(4, 5, 6, 7)
println(s"Union (ints): ${union(ints1, ints2).mkString(", ")}")
Coding Round
68. Difference of arrays

Find difference using filterNot or diff.

  • Difference: arr1.filterNot(arr2.contains)
  • Symmetric: val diff1 = arr1.filterNot(arr2.contains); val diff2 = arr2.filterNot(arr1.contains); diff1 ++ diff2
  • Time: O(n*m)
scala
// Difference of arrays
def difference[T](arr1: Array[T], arr2: Array[T]): Array[T] = {
  arr1.filterNot(arr2.contains)
}

def symmetricDifference[T](arr1: Array[T], arr2: Array[T]): Array[T] = {
  val diff1 = arr1.filterNot(arr2.contains)
  val diff2 = arr2.filterNot(arr1.contains)
  diff1 ++ diff2
}

val arr1 = Array("apple", "banana", "orange", "grape")
val arr2 = Array("banana", "kiwi", "grape")
println(s"Difference: ${difference(arr1, arr2).mkString(", ")}")
println(s"Symmetric difference: ${symmetricDifference(arr1, arr2).mkString(", ")}")

val ints1 = Array(1, 2, 3, 4, 5)
val ints2 = Array(4, 5, 6, 7, 8)
println(s"Difference (ints): ${difference(ints1, ints2).mkString(", ")}")
Coding Round
69. Group by property

Group objects by property using groupBy.

  • Method: list.groupBy(keyExtractor)
  • Count: list.groupBy(keyExtractor).mapValues(_.size)
  • Sum: list.groupBy(keyExtractor).mapValues(_.map(valueExtractor).sum)
  • Use case: Data aggregation
scala
// Group by property
case class Person(name: String, age: Int, city: String)

def groupBy[A, K](list: List[A], keyExtractor: A => K): Map[K, List[A]] = {
  list.groupBy(keyExtractor)
}

def groupAndCount[A, K](list: List[A], keyExtractor: A => K): Map[K, Int] = {
  list.groupBy(keyExtractor).mapValues(_.size)
}

def groupAndSum[A, K, V](list: List[A], keyExtractor: A => K, valueExtractor: A => V)(implicit num: Numeric[V]): Map[K, V] = {
  list.groupBy(keyExtractor).mapValues(_.map(valueExtractor).sum)
}

val people = List(
  Person("Alice", 25, "NYC"),
  Person("Bob", 30, "LA"),
  Person("Charlie", 25, "NYC"),
  Person("David", 35, "Chicago"),
  Person("Eve", 30, "LA")
)

println("Group by age:")
val byAge = groupBy(people, (p: Person) => p.age)
byAge.foreach { case (age, persons) =>
  println(s"Age $age: ${persons.map(_.name).mkString(", ")}")
}

println("Group by city:")
val byCity = groupBy(people, (p: Person) => p.city)
byCity.foreach { case (city, persons) =>
  println(s"City $city: ${persons.map(_.name).mkString(", ")}")
}

println("Count by age:")
println(groupAndCount(people, (p: Person) => p.age))
Coding Round
70. Deep clone object

Create deep copies using recursion to clone nested structures.

  • Method: def deepClone[T](obj: T): T = { obj match { case list: List[_] => list.map(deepClone).asInstanceOf[T]; case map: Map[_, _] => map.map { case (k, v) => (deepClone(k), deepClone(v)) }.asInstanceOf[T]; case _ => obj } }
  • Case classes: copy method
  • Limitations: Handles common types
scala
// Deep clone object
def deepClone[T](obj: T): T = {
  obj match {
    case list: List[_] =>
      list.map(deepClone).asInstanceOf[T]
    case map: Map[_, _] =>
      map.map { case (k, v) => (deepClone(k), deepClone(v)) }.asInstanceOf[T]
    case seq: Seq[_] =>
      seq.map(deepClone).asInstanceOf[T]
    case array: Array[_] =>
      array.map(deepClone).asInstanceOf[T]
    case option: Option[_] =>
      option.map(deepClone).asInstanceOf[T]
    case _ => obj
  }
}

case class Address(street: String, city: String)
case class Person(name: String, age: Int, address: Address)

val original = Person("Alice", 25, Address("123 Main St", "NYC"))
val cloned = deepClone(original)

cloned.address = original.address.copy(street = "456 Oak St")

println(s"Original: ${original.address.street}")
println(s"Cloned: ${cloned.address.street}")
Coding Round
71. Immutable update

Perform immutable updates using path-based updates.

  • Method: def updateImmutable(obj: Map[String, Any], path: String, value: Any): Map[String, Any]
  • Path: Dot notation
  • Recursive: Helper function
  • Use case: State management
scala
// Immutable update
def updateImmutable[T](obj: Map[String, Any], path: String, value: Any): Map[String, Any] = {
  val parts = path.split("\.")
  if (parts.length == 1) {
    obj + (parts.head -> value)
  } else {
    val first = parts.head
    val rest = parts.tail.mkString(".")
    val updated = obj.get(first) match {
      case Some(inner: Map[_, _]) =>
        updateImmutable(inner.asInstanceOf[Map[String, Any]], rest, value)
      case _ =>
        updateImmutable(Map.empty[String, Any], rest, value)
    }
    obj + (first -> updated)
  }
}

val state = Map("user" -> Map("name" -> "Alice", "age" -> 25))
val newState = updateImmutable(state, "user.age", 26)

println(s"Original: ${state("user")("age")}")
println(s"Updated: ${newState("user")("age")}")
Coding Round
72. Pipe function

Implement pipe for left-to-right function composition.

  • Method: def pipe[T](value: T, fns: (T => T)*): T = fns.foldLeft(value)((acc, fn) => fn(acc))
  • Compose: def compose[T](fns: (T => T)*): T => T = fns.reduceLeft((f, g) => x => g(f(x)))
  • Use case: Function chaining
scala
// Pipe function
def pipe[T](value: T, fns: (T => T)*): T = {
  fns.foldLeft(value)((acc, fn) => fn(acc))
}

def compose[T](fns: (T => T)*): T => T = {
  fns.reduceLeft((f, g) => x => g(f(x)))
}

val double: Int => Int = _ * 2
val addTen: Int => Int = _ + 10
val square: Int => Int = x => x * x

val result = pipe(5, double, addTen, square)
println(s"Pipe: $result")

val process = compose(double, addTen, square)
println(s"Compose: ${process(5)}")
Coding Round
73. Compose function

Implement compose for right-to-left function composition.

  • Method: def composeAlt[T](fns: (T => T)*): T => T = fns.reduceRight((f, g) => x => f(g(x)))
  • With logging: composeWithLogging
  • Direction: Right to left
scala
// Compose function
def composeAlt[T](fns: (T => T)*): T => T = {
  fns.reduceRight((f, g) => x => f(g(x)))
}

def composeWithLogging[T](fns: (T => T)*): T => T = {
  fns.reduceRight { (f, g) =>
    x => {
      val result = f(g(x))
      println(s"Intermediate: $result")
      result
    }
  }
}

val double: Int => Int = _ * 2
val addTen: Int => Int = _ + 10
val square: Int => Int = x => x * x

val composed = composeAlt(double, addTen, square)
println(s"Composed: ${composed(5)}")

val composedWithLogging = composeWithLogging(double, addTen, square)
println(s"Composed with logging: ${composedWithLogging(5)}")
Coding Round
74. Memoization

Implement memoization using mutable Map cache.

  • Method: def memoize[T, R](fn: T => R): T => R = { val cache = mutable.Map.empty[T, R]; (arg: T) => cache.getOrElseUpdate(arg, fn(arg)) }
  • Multiple args: memoizeMultiple
  • Use case: Expensive functions
scala
// Memoization
def memoize[T, R](fn: T => R): T => R = {
  val cache = scala.collection.mutable.Map.empty[T, R]
  (arg: T) => {
    cache.getOrElseUpdate(arg, fn(arg))
  }
}

def memoizeMultiple[T, R](fn: T => R): T => R = {
  val cache = scala.collection.mutable.Map.empty[T, R]
  (arg: T) => {
    if (cache.contains(arg)) cache(arg)
    else {
      val result = fn(arg)
      cache(arg) = result
      result
    }
  }
}

// Fibonacci with memoization
val fib: Int => Int = memoize { n =>
  if (n <= 1) n
  else fib(n - 1) + fib(n - 2)
}

val start = System.currentTimeMillis()
println(s"Fibonacci(35): ${fib(35)}")
val time1 = System.currentTimeMillis() - start
println(s"Time: ${time1}ms")

val start2 = System.currentTimeMillis()
println(s"Fibonacci(35) again: ${fib(35)}")
val time2 = System.currentTimeMillis() - start2
println(s"Time: ${time2}ms")
Coding Round
75. Once function

Implement once function that ensures a function is called only once.

  • Method: def once[T, R](fn: T => R): T => R = { var called = false; var result: Option[R] = None; (arg: T) => { if (!called) { called = true; result = Some(fn(arg)) }; result.get } }
  • With reset: onceWithReset
scala
// Once function
def once[T, R](fn: T => R): T => R = {
  var called = false
  var result: Option[R] = None
  (arg: T) => {
    if (!called) {
      called = true
      result = Some(fn(arg))
    }
    result.get
  }
}

def onceWithReset[T, R](fn: T => R): (T => R, () => Unit) = {
  var called = false
  var result: Option[R] = None
  
  val reset = () => {
    called = false
    result = None
  }
  
  val fnOnce = (arg: T) => {
    if (!called) {
      called = true
      result = Some(fn(arg))
    }
    result.get
  }
  
  (fnOnce, reset)
}

val initialize = once { (value: Int) =>
  println(s"Initialized with $value")
  value * 2
}

println(s"First call: ${initialize(10)}")
println(s"Second call: ${initialize(20)}")

val (init, reset) = onceWithReset { (value: Int) =>
  println(s"Initialized with $value")
  value * 2
}

println(s"First with reset: ${init(10)}")
reset()
println(s"After reset: ${init(20)}")
Coding Round
76. Debounce with leading edge

Implement debounce with leading edge execution.

  • Method: def debounceLeading[T](fn: T => Unit, delay: Long): T => Unit = { var lastCall = 0L; var timeout: Option[Thread] = None; (arg: T) => { val now = System.currentTimeMillis(); if (now - lastCall >= delay) { lastCall = now; fn(arg) } else { if (timeout.isEmpty) { val thread = new Thread { override def run(): Unit = { Thread.sleep(delay - (now - lastCall)); timeout = None; lastCall = System.currentTimeMillis(); fn(arg) } }; timeout = Some(thread); thread.start() } } } }
  • Use case: Search inputs
scala
// Debounce with leading edge
def debounceLeading[T](fn: T => Unit, delay: Long): T => Unit = {
  var lastCall = 0L
  var timeout: Option[Thread] = None
  
  (arg: T) => {
    val now = System.currentTimeMillis()
    if (now - lastCall >= delay) {
      lastCall = now
      fn(arg)
    } else {
      if (timeout.isEmpty) {
        val thread = new Thread {
          override def run(): Unit = {
            Thread.sleep(delay - (now - lastCall))
            timeout = None
            lastCall = System.currentTimeMillis()
            fn(arg)
          }
        }
        timeout = Some(thread)
        thread.start()
      }
    }
  }
}

def debounceSimple[T](fn: T => Unit, delay: Long): T => Unit = {
  var lastCall = 0L
  (arg: T) => {
    val now = System.currentTimeMillis()
    if (now - lastCall >= delay) {
      lastCall = now
      fn(arg)
    }
  }
}

val debounced = debounceSimple { (value: Int) =>
  println(s"Processing: $value")
} (2000)

println(debounced(1))
println(debounced(2))
Thread.sleep(3000)
println(debounced(3))
Coding Round
77. Throttle with leading edge

Implement throttle with leading edge execution.

  • Method: def throttleLeading[T](fn: T => Unit, delay: Long): T => Unit = { var lastCall = 0L; (arg: T) => { val now = System.currentTimeMillis(); if (now - lastCall >= delay) { lastCall = now; fn(arg) } } }
  • With trailing: throttleWithTrailing
  • Use case: Scroll events
scala
// Throttle with leading edge
def throttleLeading[T](fn: T => Unit, delay: Long): T => Unit = {
  var lastCall = 0L
  (arg: T) => {
    val now = System.currentTimeMillis()
    if (now - lastCall >= delay) {
      lastCall = now
      fn(arg)
    }
  }
}

def throttleWithTrailing[T](fn: T => Unit, delay: Long): T => Unit = {
  var lastCall = 0L
  var pending: Option[T] = None
  var timer: Option[Thread] = None
  
  (arg: T) => {
    val now = System.currentTimeMillis()
    if (now - lastCall >= delay) {
      lastCall = now
      fn(arg)
    } else {
      pending = Some(arg)
      if (timer.isEmpty) {
        val remaining = delay - (now - lastCall)
        val thread = new Thread {
          override def run(): Unit = {
            Thread.sleep(remaining)
            timer = None
            lastCall = System.currentTimeMillis()
            pending.foreach(fn)
            pending = None
          }
        }
        timer = Some(thread)
        thread.start()
      }
    }
  }
}

val throttled = throttleLeading { (value: Int) =>
  println(s"Processing: $value")
} (2000)

println(throttled(1))
println(throttled(2))
Thread.sleep(3000)
println(throttled(3))
Coding Round
78. Deep equal

Implement deep equality comparison for nested structures.

  • Method: def deepEqual(a: Any, b: Any): Boolean = { (a, b) match { case (a: List[_], b: List[_]) => a.length == b.length && a.zip(b).forall { case (x, y) => deepEqual(x, y) }; case (a: Map[_, _], b: Map[_, _]) => a.size == b.size && a.forall { case (k, v) => b.get(k).exists(deepEqual(v, _)) }; case (a: Product, b: Product) => a.productArity == b.productArity && a.productIterator.zip(b.productIterator).forall { case (x, y) => deepEqual(x, y) }; case _ => a == b } }
scala
// Deep equal
def deepEqual(a: Any, b: Any): Boolean = {
  (a, b) match {
    case (a: List[_], b: List[_]) =>
      a.length == b.length && a.zip(b).forall { case (x, y) => deepEqual(x, y) }
    case (a: Map[_, _], b: Map[_, _]) =>
      a.size == b.size && a.forall { case (k, v) =>
        b.get(k).exists(deepEqual(v, _))
      }
    case (a: Array[_], b: Array[_]) =>
      a.length == b.length && a.zip(b).forall { case (x, y) => deepEqual(x, y) }
    case (a: Option[_], b: Option[_]) =>
      (a, b) match {
        case (Some(x), Some(y)) => deepEqual(x, y)
        case (None, None) => true
        case _ => false
      }
    case (a: Product, b: Product) =>
      a.productArity == b.productArity &&
      a.productIterator.zip(b.productIterator).forall { case (x, y) => deepEqual(x, y) }
    case _ => a == b
  }
}

case class Person(name: String, age: Int)
case class Address(street: String, city: String)

val obj1 = Person("Alice", 25)
val obj2 = Person("Alice", 25)
val obj3 = Person("Alice", 26)

println(s"obj1 == obj2: ${deepEqual(obj1, obj2)}")
println(s"obj1 == obj3: ${deepEqual(obj1, obj3)}")
Coding Round
79. Observable pattern

Implement observable pattern with subscribers and notification.

  • Observable: class Observable[T] { private val subscribers = mutable.ListBuffer.empty[T => Unit]; def subscribe(callback: T => Unit): () => Unit = { subscribers += callback; () => subscribers -= callback }; def notify(data: T): Unit = { subscribers.foreach(_(data)) } }
  • Stateful: StatefulObservable
scala
// Observable pattern
import scala.collection.mutable

class Observable[T] {
  private val subscribers = mutable.ListBuffer.empty[T => Unit]
  
  def subscribe(callback: T => Unit): () => Unit = {
    subscribers += callback
    () => subscribers -= callback
  }
  
  def notify(data: T): Unit = {
    subscribers.foreach(_(data))
  }
}

class StatefulObservable[T](initialState: T) {
  private var state = initialState
  private val observable = new Observable[T]
  
  def subscribe(callback: T => Unit): () => Unit = observable.subscribe(callback)
  
  def setState(newState: T): Unit = {
    state = newState
    observable.notify(state)
  }
  
  def getState: T = state
}

// Usage
val observable = new Observable[String]
val id1 = observable.subscribe(data => println(s"Observer1: $data"))
val id2 = observable.subscribe(data => println(s"Observer2: $data"))

println("Notifying observers:")
observable.notify("Hello, World!")

id1()
println("After unsubscribing observer1:")
observable.notify("Hello again!")

val stateful = new StatefulObservable(0)
stateful.subscribe(state => println(s"State changed to: $state"))
println(s"Current state: ${stateful.getState}")
stateful.setState(10)
stateful.setState(20)
Coding Round
80. Singleton pattern

Implement singleton pattern using companion object or lazy val.

  • Companion object: object Singleton { private var instance: Option[Singleton] = None; def getInstance: Singleton = { instance.getOrElse { val newInstance = new Singleton(); instance = Some(newInstance); newInstance } } }
  • Lazy val: object LazySingleton { lazy val instance = new LazySingleton() }
scala
// Singleton pattern
object Singleton {
  private var instance: Option[Singleton] = None
  
  def getInstance: Singleton = {
    instance.getOrElse {
      val newInstance = new Singleton()
      instance = Some(newInstance)
      newInstance
    }
  }
  
  def reset(): Unit = {
    instance = None
  }
}

class Singleton private() {
  private val data = scala.collection.mutable.Map.empty[String, Any]
  
  def set(key: String, value: Any): Unit = {
    data(key) = value
  }
  
  def get(key: String): Option[Any] = data.get(key)
}

// Alternative singleton using lazy val
object LazySingleton {
  lazy val instance = new LazySingleton()
}

class LazySingleton private() {
  private val data = scala.collection.mutable.Map.empty[String, Any]
  
  def set(key: String, value: Any): Unit = {
    data(key) = value
  }
  
  def get(key: String): Option[Any] = data.get(key)
}

// Usage
val singleton1 = Singleton.getInstance
val singleton2 = Singleton.getInstance

println(s"singleton1 == singleton2: ${singleton1 == singleton2}")

singleton1.set("key", "value")
println(s"singleton2 get: ${singleton2.get("key")}")
Coding Round
81. Factory pattern

Implement factory pattern for creating objects without specifying concrete classes.

  • Factory: object UserFactory { def create(userType: String, name: String): User = { userType match { case "admin" => Admin(name); case "guest" => Guest(name); case _ => RegularUser(name) } } }
scala
// Factory pattern
trait User {
  def name: String
  def userType: String
}

case class Admin(name: String) extends User {
  def userType: String = "admin"
}

case class Guest(name: String) extends User {
  def userType: String = "guest"
}

case class RegularUser(name: String) extends User {
  def userType: String = "regular"
}

object UserFactory {
  def create(userType: String, name: String): User = {
    userType match {
      case "admin" => Admin(name)
      case "guest" => Guest(name)
      case _ => RegularUser(name)
    }
  }
  
  def createAdmin(name: String): Admin = Admin(name)
  def createGuest(name: String): Guest = Guest(name)
  def createRegular(name: String): RegularUser = RegularUser(name)
}

// Usage
val user1 = UserFactory.create("admin", "Alice")
val user2 = UserFactory.create("guest", "Bob")
val user3 = UserFactory.create("regular", "Charlie")

println(s"${user1.name} is ${user1.userType}")
println(s"${user2.name} is ${user2.userType}")
println(s"${user3.name} is ${user3.userType}")
Coding Round
82. Strategy pattern

Implement strategy pattern with interchangeable strategies.

  • Strategy: trait PaymentStrategy { def pay(amount: Double): Unit }
  • Context: class PaymentContext(var strategy: PaymentStrategy) { def executePayment(amount: Double): Unit = strategy.pay(amount) }
  • Decorator: DiscountDecorator
scala
// Strategy pattern
trait PaymentStrategy {
  def pay(amount: Double): Unit
}

class CreditCardStrategy extends PaymentStrategy {
  def pay(amount: Double): Unit = {
    println(s"Paid $$amount with Credit Card")
  }
}

class PayPalStrategy extends PaymentStrategy {
  def pay(amount: Double): Unit = {
    println(s"Paid $$amount with PayPal")
  }
}

class CryptoStrategy extends PaymentStrategy {
  def pay(amount: Double): Unit = {
    println(s"Paid $$amount with Crypto")
  }
}

class PaymentContext(var strategy: PaymentStrategy) {
  def setStrategy(strategy: PaymentStrategy): Unit = {
    this.strategy = strategy
  }
  
  def executePayment(amount: Double): Unit = {
    strategy.pay(amount)
  }
}

// Usage
val context = new PaymentContext(new CreditCardStrategy)
context.executePayment(100.0)
context.setStrategy(new PayPalStrategy)
context.executePayment(50.0)
context.setStrategy(new CryptoStrategy)
context.executePayment(75.0)

// With discount decorator
class DiscountDecorator(strategy: PaymentStrategy, discount: Double) extends PaymentStrategy {
  def pay(amount: Double): Unit = {
    val discounted = amount * (1 - discount)
    println(s"Applied discount of ${discount * 100}%")
    strategy.pay(discounted)
  }
}

val discounted = new DiscountDecorator(new PayPalStrategy, 0.1)
discounted.pay(100.0)
Coding Round
83. Observer pattern

Implement observer pattern with subject and observers.

  • Subject: class ConcreteSubject extends Subject { private val observers = mutable.ListBuffer.empty[Observer]; private var state: Any = _; def attach(observer: Observer): Unit = observers += observer; def setState(state: Any): Unit = { this.state = state; notifyObservers() } }
  • Observer: class ConcreteObserver(name: String) extends Observer { def update(data: Any): Unit = println(s"Observer $name received: $data") }
scala
// Observer pattern
trait Observer {
  def update(data: Any): Unit
}

trait Subject {
  def attach(observer: Observer): Unit
  def detach(observer: Observer): Unit
  def notifyObservers(): Unit
}

class ConcreteSubject extends Subject {
  private val observers = scala.collection.mutable.ListBuffer.empty[Observer]
  private var state: Any = _
  
  def attach(observer: Observer): Unit = observers += observer
  def detach(observer: Observer): Unit = observers -= observer
  
  def notifyObservers(): Unit = {
    observers.foreach(_.update(state))
  }
  
  def setState(state: Any): Unit = {
    this.state = state
    notifyObservers()
  }
  
  def getState: Any = state
}

class ConcreteObserver(name: String) extends Observer {
  def update(data: Any): Unit = {
    println(s"Observer $name received: $data")
  }
}

class DerivedObserver(name: String, transform: Any => Any) extends Observer {
  def update(data: Any): Unit = {
    val transformed = transform(data)
    println(s"Derived observer $name: $transformed")
  }
}

// Usage
val subject = new ConcreteSubject
val observer1 = new ConcreteObserver("1")
val observer2 = new ConcreteObserver("2")
val observer3 = new DerivedObserver("3", (data: Any) => data.toString.toUpperCase)

subject.attach(observer1)
subject.attach(observer2)
subject.attach(observer3)

println("Setting state:")
subject.setState("Hello, World!")
subject.setState("Another update")

subject.detach(observer1)
println("After detaching observer1:")
subject.setState("Final state")
Coding Round
84. Decorator pattern

Implement decorator pattern for adding features.

  • Component: trait Coffee { def getCost(): Double; def getDescription(): String }
  • Decorator: abstract class CoffeeDecorator(val coffee: Coffee) extends Coffee
  • Concrete: class MilkDecorator(coffee: Coffee) extends CoffeeDecorator(coffee) { override def getCost(): Double = coffee.getCost() + 2.0 }
scala
// Decorator pattern
trait Coffee {
  def getCost(): Double
  def getDescription(): String
}

class BasicCoffee extends Coffee {
  def getCost(): Double = 5.0
  def getDescription(): String = "Coffee"
}

abstract class CoffeeDecorator(val coffee: Coffee) extends Coffee {
  def getCost(): Double = coffee.getCost()
  def getDescription(): String = coffee.getDescription()
}

class MilkDecorator(coffee: Coffee) extends CoffeeDecorator(coffee) {
  override def getCost(): Double = coffee.getCost() + 2.0
  override def getDescription(): String = coffee.getDescription() + ", Milk"
}

class SugarDecorator(coffee: Coffee) extends CoffeeDecorator(coffee) {
  override def getCost(): Double = coffee.getCost() + 1.0
  override def getDescription(): String = coffee.getDescription() + ", Sugar"
}

class CaramelDecorator(coffee: Coffee) extends CoffeeDecorator(coffee) {
  override def getCost(): Double = coffee.getCost() + 2.5
  override def getDescription(): String = coffee.getDescription() + ", Caramel"
}

class WhippedCreamDecorator(coffee: Coffee) extends CoffeeDecorator(coffee) {
  override def getCost(): Double = coffee.getCost() + 1.5
  override def getDescription(): String = coffee.getDescription() + ", Whipped Cream"
}

// Usage
val coffee = new BasicCoffee
println(s"${coffee.getDescription()} ($$${coffee.getCost()})")

val withMilk = new MilkDecorator(coffee)
println(s"${withMilk.getDescription()} ($$${withMilk.getCost()})")

val withSugar = new SugarDecorator(coffee)
println(s"${withSugar.getDescription()} ($$${withSugar.getCost()})")

val withMilkSugar = new SugarDecorator(new MilkDecorator(coffee))
println(s"${withMilkSugar.getDescription()} ($$${withMilkSugar.getCost()})")

val fullyDecorated = new CaramelDecorator(
  new WhippedCreamDecorator(
    new SugarDecorator(
      new MilkDecorator(coffee)
    )
  )
)
println(s"${fullyDecorated.getDescription()} ($$${fullyDecorated.getCost()})")
Coding Round
85. Command pattern

Implement command pattern with execute, undo, and redo.

  • Command: class AddCommand(var receiver: Int, value: Int) extends Command { def execute(): Unit = { oldValue = receiver; receiver += value }; def undo(): Unit = { receiver = oldValue } }
  • History: class CommandHistory { private val history = mutable.ListBuffer.empty[Command]; private var current = 0; def execute(command: Command): Unit = { command.execute(); history.trimEnd(history.length - current); history += command; current += 1 } }
scala
// Command pattern
trait Command {
  def execute(): Unit
  def undo(): Unit
  def redo(): Unit
}

class AddCommand(var receiver: Int, value: Int) extends Command {
  private var oldValue = receiver
  
  def execute(): Unit = {
    oldValue = receiver
    receiver += value
  }
  
  def undo(): Unit = {
    receiver = oldValue
  }
  
  def redo(): Unit = {
    execute()
  }
}

class SubtractCommand(var receiver: Int, value: Int) extends Command {
  private var oldValue = receiver
  
  def execute(): Unit = {
    oldValue = receiver
    receiver -= value
  }
  
  def undo(): Unit = {
    receiver = oldValue
  }
  
  def redo(): Unit = {
    execute()
  }
}

class MacroCommand(commands: Command*) extends Command {
  def execute(): Unit = commands.foreach(_.execute())
  def undo(): Unit = commands.reverse.foreach(_.undo())
  def redo(): Unit = commands.foreach(_.redo())
}

class CommandHistory {
  private val history = scala.collection.mutable.ListBuffer.empty[Command]
  private var current = 0
  
  def execute(command: Command): Unit = {
    command.execute()
    history.trimEnd(history.length - current)
    history += command
    current += 1
  }
  
  def undo(): Boolean = {
    if (current > 0) {
      current -= 1
      history(current).undo()
      true
    } else false
  }
  
  def redo(): Boolean = {
    if (current < history.length) {
      history(current).redo()
      current += 1
      true
    } else false
  }
}

// Usage
var counter = 0
val history = new CommandHistory

val add5 = new AddCommand(counter, 5)
val sub3 = new SubtractCommand(counter, 3)

println(s"Initial: $counter")
history.execute(add5)
println(s"After add: $counter")
history.execute(sub3)
println(s"After sub: $counter")
history.undo()
println(s"After undo: $counter")
history.redo()
println(s"After redo: $counter")

val macroCmd = new MacroCommand(add5, add5, sub3)
history.execute(macroCmd)
println(s"After macro: $counter")
Coding Round
86. Memento pattern

Implement memento pattern for state capture and restoration.

  • Memento: class Memento(val state: Map[String, Any])
  • Originator: class Originator { private var state: Map[String, Any] = Map.empty; def save(): Memento = new Memento(state); def restore(memento: Memento): Unit = { state = memento.state } }
  • Caretaker: class Caretaker { private val mementos = mutable.ListBuffer.empty[Memento]; private var current = 0; def save(memento: Memento): Unit = { mementos.trimEnd(mementos.length - current); mementos += memento; current += 1 } }
scala
// Memento pattern
class Memento(val state: Map[String, Any])

class Originator {
  private var state: Map[String, Any] = Map.empty
  
  def save(): Memento = new Memento(state)
  
  def restore(memento: Memento): Unit = {
    state = memento.state
  }
  
  def setState(state: Map[String, Any]): Unit = {
    this.state = state
  }
  
  def getState: Map[String, Any] = state
}

class Caretaker {
  private val mementos = scala.collection.mutable.ListBuffer.empty[Memento]
  private var current = 0
  
  def save(memento: Memento): Unit = {
    mementos.trimEnd(mementos.length - current)
    mementos += memento
    current += 1
  }
  
  def undo(): Option[Memento] = {
    if (current > 0) {
      current -= 1
      Some(mementos(current))
    } else None
  }
  
  def redo(): Option[Memento] = {
    if (current < mementos.length) {
      val memento = mementos(current)
      current += 1
      Some(memento)
    } else None
  }
}

// Usage
val originator = new Originator
val caretaker = new Caretaker

caretaker.save(originator.save())
originator.setState(Map("value" -> 1))
caretaker.save(originator.save())
originator.setState(Map("value" -> 2))
caretaker.save(originator.save())
originator.setState(Map("value" -> 3))

println(s"Current: ${originator.getState("value")}")

caretaker.undo().foreach { memento =>
  originator.restore(memento)
  println(s"After undo: ${originator.getState("value")}")
}

caretaker.redo().foreach { memento =>
  originator.restore(memento)
  println(s"After redo: ${originator.getState("value")}")
}
Coding Round
87. Mediator pattern

Implement mediator pattern for centralized communication.

  • Mediator: class ConcreteMediator extends Mediator { private val colleagues = mutable.ListBuffer.empty[Colleague]; def register(colleague: Colleague): Unit = { colleagues += colleague; colleague.setMediator(this) }; def send(message: String, sender: Colleague): Unit = { colleagues.filter(_ != sender).foreach(_.receive(message)) } }
scala
// Mediator pattern
trait Mediator {
  def send(message: String, sender: Colleague): Unit
  def register(colleague: Colleague): Unit
}

abstract class Colleague(val name: String) {
  private var mediator: Mediator = _
  
  def setMediator(mediator: Mediator): Unit = {
    this.mediator = mediator
  }
  
  def send(message: String): Unit = {
    mediator.send(message, this)
  }
  
  def receive(message: String): Unit = {
    println(s"$name received: $message")
  }
}

class ConcreteMediator extends Mediator {
  private val colleagues = scala.collection.mutable.ListBuffer.empty[Colleague]
  
  def register(colleague: Colleague): Unit = {
    colleagues += colleague
    colleague.setMediator(this)
  }
  
  def send(message: String, sender: Colleague): Unit = {
    colleagues.filter(_ != sender).foreach(_.receive(message))
  }
}

class StatefulColleague(name: String, var state: Int) extends Colleague(name) {
  override def receive(message: String): Unit = {
    println(s"$name (state $state) received: $message")
  }
  
  def setState(state: Int): Unit = {
    this.state = state
  }
}

// Usage
val mediator = new ConcreteMediator
val alice = new Colleague("Alice")
val bob = new Colleague("Bob")
val charlie = new Colleague("Charlie")

mediator.register(alice)
mediator.register(bob)
mediator.register(charlie)

println("Sending messages:")
alice.send("Hello everyone!")
bob.send("Meeting at 3pm")

val mediator2 = new ConcreteMediator
val alice2 = new StatefulColleague("Alice", 0)
val bob2 = new StatefulColleague("Bob", 1)

mediator2.register(alice2)
mediator2.register(bob2)
alice2.send("Custom message for stateful colleagues")
Coding Round
88. Chain of Responsibility

Implement chain of responsibility with linked handlers.

  • Handler: abstract class Handler { private var nextHandler: Option[Handler] = None; def setNext(handler: Handler): Handler = { nextHandler = Some(handler); handler }; def handle(request: Map[String, Any]): Boolean = { nextHandler.exists(_.handle(request)) || true } }
scala
// Chain of Responsibility
abstract class Handler {
  private var nextHandler: Option[Handler] = None
  
  def setNext(handler: Handler): Handler = {
    nextHandler = Some(handler)
    handler
  }
  
  def handle(request: Map[String, Any]): Boolean = {
    nextHandler.exists(_.handle(request)) || true
  }
}

class AuthHandler extends Handler {
  override def handle(request: Map[String, Any]): Boolean = {
    if (request.contains("token")) {
      println("Authentication passed")
      super.handle(request)
    } else {
      println("Authentication failed")
      false
    }
  }
}

class LoggerHandler extends Handler {
  override def handle(request: Map[String, Any]): Boolean = {
    val url = request.getOrElse("url", "unknown")
    println(s"Logging request: $url")
    super.handle(request)
  }
}

class ValidationHandler extends Handler {
  override def handle(request: Map[String, Any]): Boolean = {
    if (request.contains("data")) {
      println("Validation passed")
      super.handle(request)
    } else {
      println("Validation failed")
      false
    }
  }
}

class RateLimitHandler extends Handler {
  private var lastCall = 0L
  private val limit = 5000L // 5 seconds
  
  override def handle(request: Map[String, Any]): Boolean = {
    val now = System.currentTimeMillis()
    if (now - lastCall >= limit) {
      lastCall = now
      println("Rate limit passed")
      super.handle(request)
    } else {
      println("Rate limit exceeded")
      false
    }
  }
}

// Usage
val auth = new AuthHandler
val logger = new LoggerHandler
val validator = new ValidationHandler
val rateLimiter = new RateLimitHandler

auth.setNext(logger).setNext(validator).setNext(rateLimiter)

val request = Map("token" -> "valid", "url" -> "/api", "data" -> "payload")
println("Processing valid request:")
auth.handle(request)

val request2 = Map("url" -> "/public")
println("Processing invalid request:")
auth.handle(request2)
Coding Round
89. State pattern

Implement state pattern with context and state transitions.

  • Context: class Context { private var state: State = new ReadyState; def setState(state: State): Unit = { this.state = state }; def request(): Unit = { state.handle(this) } }
  • States: class ReadyState extends State { def handle(context: Context): Unit = { println("Ready"); context.setState(new ProcessingState) } }
scala
// State pattern
trait State {
  def handle(context: Context): Unit
}

class ReadyState extends State {
  def handle(context: Context): Unit = {
    println("Ready: Waiting for input")
    context.setState(new ProcessingState)
  }
}

class ProcessingState extends State {
  def handle(context: Context): Unit = {
    println("Processing: Working on task")
    context.setState(new CompletedState)
  }
}

class CompletedState extends State {
  def handle(context: Context): Unit = {
    println("Completed: Task finished")
    context.setState(new ReadyState)
  }
}

class ErrorState extends State {
  def handle(context: Context): Unit = {
    println("Error: Something went wrong")
    context.setState(new ReadyState)
  }
}

class Context {
  private var state: State = new ReadyState
  private val data = scala.collection.mutable.Map.empty[String, Any]
  
  def setState(state: State): Unit = {
    this.state = state
  }
  
  def request(): Unit = {
    state.handle(this)
  }
  
  def setData(key: String, value: Any): Unit = {
    data(key) = value
  }
  
  def getData(key: String): Option[Any] = data.get(key)
}

class StatefulContext extends Context {
  override def request(): Unit = {
    state.handle(this)
    setData("last_state", state.getClass.getSimpleName)
  }
}

// Usage
val context = new Context
for (i <- 1 to 5) {
  println(s"Step $i:")
  context.request()
}

println("With data:")
val context2 = new StatefulContext
for (i <- 1 to 5) {
  context2.setData("step", i)
  context2.request()
  println(s"Data: ${context2.getData("last_state")}")
}
Coding Round
90. Proxy pattern

Implement proxy pattern for access control and lazy initialization.

  • Proxy: class Proxy extends Subject { private var realSubject: Option[RealSubject] = None; def request(): String = { realSubject match { case Some(subject) => subject.request(); case None => val subject = new RealSubject; realSubject = Some(subject); subject.request() } } }
scala
// Proxy pattern
trait Subject {
  def request(): String
}

class RealSubject extends Subject {
  def request(): String = "RealSubject: Handling request"
}

class Proxy extends Subject {
  private var realSubject: Option[RealSubject] = None
  
  def request(): String = {
    realSubject match {
      case Some(subject) =>
        println("Proxy: Using cached real subject")
        subject.request()
      case None =>
        println("Proxy: Creating real subject")
        val subject = new RealSubject
        realSubject = Some(subject)
        subject.request()
    }
  }
}

class LoggingProxy(subject: Subject) extends Subject {
  def request(): String = {
    println("Logging: Request started")
    val result = subject.request()
    println("Logging: Request completed")
    result
  }
}

class AuthProxy(subject: Subject, user: String) extends Subject {
  def request(): String = {
    if (authenticate()) {
      println("Auth: Access granted")
      subject.request()
    } else {
      println("Auth: Access denied")
      "Unauthorized"
    }
  }
  
  private def authenticate(): Boolean = user == "admin"
}

// Usage
val proxy = new Proxy
println(proxy.request())
println(proxy.request())

val real = new RealSubject
val loggingProxy = new LoggingProxy(real)
println(loggingProxy.request())

val authProxy = new AuthProxy(real, "admin")
println(authProxy.request())

val authProxy2 = new AuthProxy(real, "guest")
println(authProxy2.request())
Coding Round
91. Flyweight pattern

Implement flyweight pattern for sharing objects.

  • Flyweight: class Flyweight(val sharedState: String) { def operation(uniqueState: String): String = s"Shared: $sharedState, Unique: $uniqueState" }
  • Factory: class FlyweightFactory { private val flyweights = mutable.Map.empty[String, Flyweight]; def getFlyweight(sharedState: String): Flyweight = { flyweights.getOrElseUpdate(sharedState, new Flyweight(sharedState)) } }
scala
// Flyweight pattern
class Flyweight(val sharedState: String) {
  def operation(uniqueState: String): String = {
    s"Shared: $sharedState, Unique: $uniqueState"
  }
}

class FlyweightFactory {
  private val flyweights = scala.collection.mutable.Map.empty[String, Flyweight]
  
  def getFlyweight(sharedState: String): Flyweight = {
    flyweights.getOrElseUpdate(sharedState, new Flyweight(sharedState))
  }
  
  def getCount(): Int = flyweights.size
}

// Usage
val factory = new FlyweightFactory
val fw1 = factory.getFlyweight("state1")
val fw2 = factory.getFlyweight("state1")
val fw3 = factory.getFlyweight("state2")

println(s"fw1 and fw2 are same: ${fw1 == fw2}")
println(s"fw1 and fw3 are same: ${fw1 == fw3}")

println(fw1.operation("unique1"))
println(fw2.operation("unique2"))
println(fw3.operation("unique3"))

println(s"Number of flyweights: ${factory.getCount()}")
Coding Round
92. Bridge pattern

Implement bridge pattern for separating abstraction from implementation.

  • Abstraction: abstract class Abstraction(protected val implementation: Implementation) { def operation(): String = implementation.operation() }
  • Implementation: class ConcreteImplementationA extends Implementation { def operation(): String = "ConcreteImplementationA: Operation" }
scala
// Bridge pattern
trait Implementation {
  def operation(): String
}

class ConcreteImplementationA extends Implementation {
  def operation(): String = "ConcreteImplementationA: Operation"
}

class ConcreteImplementationB extends Implementation {
  def operation(): String = "ConcreteImplementationB: Operation"
}

abstract class Abstraction(protected val implementation: Implementation) {
  def operation(): String = implementation.operation()
}

class ExtendedAbstraction(implementation: Implementation) extends Abstraction(implementation) {
  override def operation(): String = {
    s"ExtendedAbstraction: ${implementation.operation()}"
  }
}

class AlternativeAbstraction(implementation: Implementation) extends Abstraction(implementation) {
  override def operation(): String = {
    s"AlternativeAbstraction: ${implementation.operation()}"
  }
}

// Usage
val implA = new ConcreteImplementationA
val implB = new ConcreteImplementationB

val abstraction1 = new ExtendedAbstraction(implA)
val abstraction2 = new ExtendedAbstraction(implB)
val abstraction3 = new AlternativeAbstraction(implA)

println(abstraction1.operation())
println(abstraction2.operation())
println(abstraction3.operation())
Coding Round
93. Adapter pattern

Implement adapter pattern for converting interfaces.

  • Adapter: class Adapter(adaptee: Adaptee) extends Target { override def request(): String = adaptee.specificRequest() }
scala
// Adapter pattern
class Target {
  def request(): String = "Target: Request"
}

class Adaptee {
  def specificRequest(): String = "Adaptee: Specific Request"
}

class Adapter(adaptee: Adaptee) extends Target {
  override def request(): String = adaptee.specificRequest()
}

class LoggingAdapter(adaptee: Adaptee) extends Adapter(adaptee) {
  override def request(): String = {
    println("Adapter: Logging request")
    super.request()
  }
}

// Usage
val target = new Target
val adaptee = new Adaptee
val adapter = new Adapter(adaptee)

println(target.request())
println(adapter.request())

val loggingAdapter = new LoggingAdapter(adaptee)
println(loggingAdapter.request())
Coding Round
94. Facade pattern

Implement facade pattern for simplifying complex subsystems.

  • Facade: class Facade { private val subsystemA = new SubsystemA; private val subsystemB = new SubsystemB; private val subsystemC = new SubsystemC; def simpleOperation(): String = subsystemA.operationA(); def complexOperation(): String = s"${subsystemA.operationA()} ${subsystemB.operationB()} ${subsystemC.operationC()}" }
scala
// Facade pattern
class SubsystemA {
  def operationA(): String = "SubsystemA: Operation"
}

class SubsystemB {
  def operationB(): String = "SubsystemB: Operation"
}

class SubsystemC {
  def operationC(): String = "SubsystemC: Operation"
}

class Facade {
  private val subsystemA = new SubsystemA
  private val subsystemB = new SubsystemB
  private val subsystemC = new SubsystemC
  
  def simpleOperation(): String = subsystemA.operationA()
  
  def complexOperation(): String = {
    s"${subsystemA.operationA()}
${subsystemB.operationB()}
${subsystemC.operationC()}"
  }
}

// Usage
val facade = new Facade
println("Simple operation:")
println(facade.simpleOperation())
println("Complex operation:")
println(facade.complexOperation())
Coding Round
95. Composite pattern

Implement composite pattern for tree structures.

  • Component: trait Component { def operation(): String; def add(component: Component): Unit; def remove(component: Component): Unit }
  • Composite: class Composite(name: String) extends Component { private val children = mutable.ListBuffer.empty[Component]; def operation(): String = { val childResults = children.map(_.operation()).mkString(" "); s"Composite $name: Operation $childResults" } }
scala
// Composite pattern
trait Component {
  def operation(): String
  def add(component: Component): Unit
  def remove(component: Component): Unit
  def getChildren(): List[Component]
}

class Leaf(name: String) extends Component {
  def operation(): String = s"Leaf $name: Operation"
  def add(component: Component): Unit = throw new UnsupportedOperationException
  def remove(component: Component): Unit = throw new UnsupportedOperationException
  def getChildren(): List[Component] = Nil
}

class Composite(name: String) extends Component {
  private val children = scala.collection.mutable.ListBuffer.empty[Component]
  
  def operation(): String = {
    val childResults = children.map(_.operation()).mkString("
")
    s"Composite $name: Operation
$childResults"
  }
  
  def add(component: Component): Unit = children += component
  def remove(component: Component): Unit = children -= component
  def getChildren(): List[Component] = children.toList
  
  def countLeaves(): Int = {
    children.map {
      case leaf: Leaf => 1
      case composite: Composite => composite.countLeaves()
    }.sum
  }
}

// Usage
val leaf1 = new Leaf("A")
val leaf2 = new Leaf("B")
val leaf3 = new Leaf("C")
val leaf4 = new Leaf("D")

val composite1 = new Composite("Comp1")
composite1.add(leaf1)
composite1.add(leaf2)

val composite2 = new Composite("Comp2")
composite2.add(leaf3)
composite2.add(composite1)

val root = new Composite("Root")
root.add(leaf4)
root.add(composite2)

println(root.operation())
println(s"Number of leaves: ${root.countLeaves()}")
Coding Round
96. Visitor pattern

Implement visitor pattern for adding operations to objects.

  • Visitor: trait Visitor { def visitA(element: ElementA): String; def visitB(element: ElementB): String }
  • Element: trait Element { def accept(visitor: Visitor): String }
scala
// Visitor pattern
trait Visitor {
  def visitA(element: ElementA): String
  def visitB(element: ElementB): String
}

trait Element {
  def accept(visitor: Visitor): String
}

class ElementA(val data: String) extends Element {
  def accept(visitor: Visitor): String = visitor.visitA(this)
}

class ElementB(val data: String) extends Element {
  def accept(visitor: Visitor): String = visitor.visitB(this)
}

class ConcreteVisitor extends Visitor {
  def visitA(element: ElementA): String = s"Visiting ElementA: ${element.data}"
  def visitB(element: ElementB): String = s"Visiting ElementB: ${element.data}"
}

class CountingVisitor extends Visitor {
  private var countA = 0
  private var countB = 0
  
  def visitA(element: ElementA): String = {
    countA += 1
    s"Visiting ElementA ($countA): ${element.data}"
  }
  
  def visitB(element: ElementB): String = {
    countB += 1
    s"Visiting ElementB ($countB): ${element.data}"
  }
  
  def getCounts(): (Int, Int) = (countA, countB)
}

class ExtendedVisitor extends Visitor {
  def visitA(element: ElementA): String = s"Extended: ${element.data} (A)"
  def visitB(element: ElementB): String = s"Extended: ${element.data} (B)"
}

// Usage
val elements = List(
  new ElementA("Hello"),
  new ElementB("World"),
  new ElementA("Scala"),
  new ElementB("Visitor")
)

val visitor = new ConcreteVisitor
val countingVisitor = new CountingVisitor
val extendedVisitor = new ExtendedVisitor

println("Using standard visitor:")
elements.foreach(el => println(el.accept(visitor)))

println("Using counting visitor:")
elements.foreach(el => println(el.accept(countingVisitor)))
println(s"Counts: A=${countingVisitor.getCounts()._1}, B=${countingVisitor.getCounts()._2}")

println("Using extended visitor:")
elements.foreach(el => println(el.accept(extendedVisitor)))
Coding Round
97. Iterator pattern

Implement iterator pattern for sequential access.

  • Iterator: class Iterator[T](collection: List[T]) { private var position = 0; def current(): Option[T] = { if (position < collection.length) Some(collection(position)) else None }; def valid(): Boolean = position < collection.length; def next(): Unit = { position += 1 } }
scala
// Iterator pattern
class Iterator[T](collection: List[T]) {
  private var position = 0
  
  def current(): Option[T] = {
    if (position < collection.length) Some(collection(position))
    else None
  }
  
  def key(): Int = position
  
  def next(): Unit = {
    position += 1
  }
  
  def rewind(): Unit = {
    position = 0
  }
  
  def valid(): Boolean = position < collection.length
}

class ReverseIterator[T](collection: List[T]) {
  private var position = collection.length - 1
  
  def current(): Option[T] = {
    if (position >= 0) Some(collection(position))
    else None
  }
  
  def key(): Int = position
  
  def next(): Unit = {
    position -= 1
  }
  
  def rewind(): Unit = {
    position = collection.length - 1
  }
  
  def valid(): Boolean = position >= 0
}

class FilteredIterator[T](collection: List[T], predicate: T => Boolean) {
  private val filtered = collection.filter(predicate)
  private var position = 0
  
  def current(): Option[T] = {
    if (position < filtered.length) Some(filtered(position))
    else None
  }
  
  def key(): Int = position
  
  def next(): Unit = {
    position += 1
  }
  
  def rewind(): Unit = {
    position = 0
  }
  
  def valid(): Boolean = position < filtered.length
}

// Usage
val collection = List("A", "B", "C", "D", "E")
val iterator = new Iterator(collection)

println("Forward iteration:")
while (iterator.valid()) {
  println(iterator.current())
  iterator.next()
}

val reverseIterator = new ReverseIterator(collection)
println("Reverse iteration:")
while (reverseIterator.valid()) {
  println(reverseIterator.current())
  reverseIterator.next()
}

val filteredIterator = new FilteredIterator(collection, (s: String) => s.length <= 1)
println("Filtered iteration:")
while (filteredIterator.valid()) {
  println(filteredIterator.current())
  filteredIterator.next()
}
Coding Round
98. Template Method pattern

Implement template method with customizable steps.

  • Template: abstract class Template { final def templateMethod(): Unit = { println(step1()); println(step2()); println(step3()) }; protected def step1(): String; protected def step2(): String; protected def step3(): String }
scala
// Template Method pattern
abstract class Template {
  final def templateMethod(): Unit = {
    println(step1())
    println(step2())
    println(step3())
  }
  
  protected def step1(): String
  protected def step2(): String
  protected def step3(): String
}

class DefaultTemplate extends Template {
  protected def step1(): String = "Step 1"
  protected def step2(): String = "Step 2"
  protected def step3(): String = "Step 3"
}

class LoggingTemplate(template: Template) extends Template {
  protected def step1(): String = {
    val result = template.step1()
    println(s"Logging: $result")
    result
  }
  
  protected def step2(): String = {
    val result = template.step2()
    println(s"Logging: $result")
    result
  }
  
  protected def step3(): String = {
    val result = template.step3()
    println(s"Logging: $result")
    result
  }
}

class DataProcessingTemplate(data: String) extends Template {
  protected def step1(): String = s"Processing data: $data - Step 1"
  protected def step2(): String = s"Processing data: $data - Step 2"
  protected def step3(): String = s"Processing data: $data - Step 3"
}

// Usage
println("Using default template:")
val default = new DefaultTemplate
default.templateMethod()

println("Using logging template:")
val logging = new LoggingTemplate(default)
logging.templateMethod()

println("Using data processing template:")
val dataTemplate = new DataProcessingTemplate("example")
dataTemplate.templateMethod()
Coding Round
99. Builder pattern

Implement builder pattern for constructing complex objects.

  • Builder: class Builder { private var product = new Product; def reset(): Unit = product = new Product; def buildStepA(): Unit = product.addPart("Part A"); def getResult(): Product = { val result = product; reset(); result } }
scala
// Builder pattern
class Product {
  private val parts = scala.collection.mutable.ListBuffer.empty[String]
  
  def addPart(part: String): Unit = parts += part
  def listParts(): String = parts.mkString(", ")
}

class Builder {
  private var product = new Product
  
  def reset(): Unit = product = new Product
  def buildStepA(): Unit = product.addPart("Part A")
  def buildStepB(): Unit = product.addPart("Part B")
  def buildStepC(): Unit = product.addPart("Part C")
  
  def getResult(): Product = {
    val result = product
    reset()
    result
  }
}

class Director(builder: Builder) {
  def buildMinimal(): Unit = {
    builder.buildStepA()
  }
  
  def buildFull(): Unit = {
    builder.buildStepA()
    builder.buildStepB()
    builder.buildStepC()
  }
  
  def buildCustom(steps: List[String]): Unit = {
    builder.reset()
    steps.foreach {
      case "A" => builder.buildStepA()
      case "B" => builder.buildStepB()
      case "C" => builder.buildStepC()
    }
  }
}

// Usage
val builder = new Builder
val director = new Director(builder)

println("Minimal product:")
director.buildMinimal()
println(builder.getResult().listParts())

println("Full product:")
director.buildFull()
println(builder.getResult().listParts())

println("Custom product:")
builder.buildStepC()
builder.buildStepA()
println(builder.getResult().listParts())

println("Director custom:")
director.buildCustom(List("C", "A", "B"))
println(builder.getResult().listParts())
Coding Round
100. Prototype pattern

Implement prototype pattern for cloning objects.

  • Prototype: class Prototype(val data: Any) { def clone(): Prototype = new Prototype(data); def deepClone(): Prototype = { data match { case map: Map[_, _] => val clonedMap = map.map { case (k, v) => (deepCloneValue(k), deepCloneValue(v)) }; new Prototype(clonedMap); case list: List[_] => new Prototype(list.map(deepCloneValue)); case _ => new Prototype(data) } } }
scala
// Prototype pattern
class Prototype(val data: Any) {
  def clone(): Prototype = new Prototype(data)
  
  def deepClone(): Prototype = {
    data match {
      case map: Map[_, _] =>
        val clonedMap = map.map { case (k, v) => (deepCloneValue(k), deepCloneValue(v)) }
        new Prototype(clonedMap)
      case list: List[_] =>
        new Prototype(list.map(deepCloneValue))
      case _ => new Prototype(data)
    }
  }
  
  private def deepCloneValue(value: Any): Any = {
    value match {
      case p: Prototype => p.deepClone()
      case map: Map[_, _] =>
        map.map { case (k, v) => (deepCloneValue(k), deepCloneValue(v)) }
      case list: List[_] =>
        list.map(deepCloneValue)
      case _ => value
    }
  }
}

class MutablePrototype(var data: Any) extends Prototype(data) {
  def setData(data: Any): Unit = {
    this.data = data
  }
}

// Usage
val original = new Prototype(Map("name" -> "Original", "value" -> 42))
val copy = original.clone()
val deepCopy = original.deepClone()

println(s"Original: ${original.data}")
println(s"Copy: ${copy.data}")
println(s"Deep copy: ${deepCopy.data}")

val mutable = new MutablePrototype(List(1, 2, 3))
println(s"Original data: ${mutable.data}")
mutable.setData(List(4, 5, 6))
println(s"Modified data: ${mutable.data}")

val clonedMutable = mutable.clone()
println(s"Clone data: ${clonedMutable.data}")