Skip to content

Swift Developer interview questions

100 real questions with model answers and explanations for Senior Swift Engineer candidates.

See a Swift Developer resume example

Practice with flashcards

Spaced repetition · Hunter Pass

Questions

concurrencyswiftvalue-types

I would make PricingDomain a Foundation-light package with pure value inputs and deterministic outputs.

  • Keep HTTP, persistence, clocks, locale, and UI behind small adapter protocols outside the domain target.
  • Represent money as integer minor units and inject the rounding policy so all four executables pass the same golden vectors.
  • Publish one versioned fixture suite with 10,000 cases and require every platform job to produce byte-identical results.

Why interviewers ask this: This tests whether the candidate can preserve one domain model across Apple and Linux runtimes without leaking platform concerns.

spread

I would split stable domain types from a LocationPolicy capability supplied by platform adapter targets.

  • OrderCore owns coordinates as plain numeric values and never imports CoreLocation.
  • AppleLocationAdapter maps CLLocation into the domain type, while LinuxLocationAdapter uses the server geocoder result.
  • Only Package.swift and two composition roots know the platform choice, which keeps the 60 domain files portable.

Why interviewers ask this: This evaluates whether platform variance is isolated at explicit composition boundaries rather than hidden behind pervasive compiler flags.

reproducibilityapiserver-side

I would version the decision input, rule set, and output as immutable domain values and keep side effects in orchestration layers.

  • Each decision records ruleSetVersion, normalized inputs, and an injected timestamp instead of reading globals.
  • Current executables contain supported versioned rule data or modules selected at runtime because SwiftPM cannot select a historical package version dynamically within one resolved graph.
  • For exact seven-year replay, the CLI streams bounded batches through the archived binary or container for that rule version, verified by cross-platform contract fixtures.

Why interviewers ask this: This checks whether the architecture supports long-lived deterministic replay instead of only current-state execution.

dependenciesswift-package-manager

I would organize targets around cohesive capabilities and enforce a shallow, acyclic graph with measured build boundaries.

  • Generate the target graph in CI and reject feature-to-feature edges or cycles.
  • Separate stable interfaces from heavy implementations only where parallel builds or ownership justify the extra target.
  • Use build timing data to collapse tiny targets and split the three targets dominating compilation, then track p95 clean and incremental times.

Why interviewers ask this: This tests whether modularization is driven by ownership and build evidence rather than target count.

swiftdependenciesownership

I would give each capability an owned public contract and compose implementations only in the application or service root.

  • Checkout depends on PaymentsAPI and InventoryAPI targets, never their concrete clients or database models.
  • Each API target has one owning team, compatibility tests, and a documented deprecation window of two minor releases.
  • Composition roots select live, preview, and test implementations, so feature teams can ship without editing shared singletons.

Why interviewers ask this: This evaluates whether team autonomy is reflected in compile-time dependencies and release contracts.

monorepo

I would remove the high-fan-out implementation dependency before introducing another build system.

  • Use the Swift driver dependency graph and build timeline to confirm which public declarations invalidate downstream modules.
  • Move volatile helpers behind a narrow stable target or duplicate a five-line helper when coupling costs more than reuse.
  • Set a CI regression gate at 105 seconds and compare ten warmed incremental builds to avoid optimizing noise.

Why interviewers ask this: This tests whether the candidate treats build performance as an architectural dependency problem with measurable limits.

swiftapidesign

I would keep the public surface small, additive, and built from stable value types rather than exposing implementation frameworks.

  • Mark only deliberate declarations public and hide networking, persistence, and generated models behind SDK-owned types.
  • Add parameters through overloads or configuration values with defaults, and deprecate old entry points for at least two minor releases.
  • Compile representative client fixtures against the new package and run API-diff checks before publishing.

Why interviewers ask this: This tests practical source compatibility and public-surface discipline for a widely consumed Swift library.

swift

I would enable library evolution for the binary boundary and avoid promising layout or exhaustive enum knowledge to clients.

  • Build with BUILD_LIBRARY_FOR_DISTRIBUTION and distribute a verified XCFramework plus matching module interfaces.
  • Use nonfrozen public structs and enums so stored properties and cases can evolve without breaking old binaries.
  • Run old-client/new-library compatibility tests on every weekly candidate and retain the previous artifact for immediate rollback.

Why interviewers ask this: This evaluates understanding of ABI stability, library resilience, and the operational cost of binary distribution.

authapi

I would ship a safe replacement additively, measure adoption, and reserve removal for the next major release.

  • Deprecate the old symbol with a migration message and keep behavior intact through the current major line.
  • Publish a migration guide and test both APIs against the same 25 contract cases to prevent semantic drift.
  • Track repository adoption, cut release candidates for the major, and remove only after the six-month window and partner sign-off.

Why interviewers ask this: This tests whether SemVer is handled as a consumer migration contract rather than a version-number convention.

genericstypingprotocols

I would keep generics inside the hot typed path and use an existential only at the heterogeneous registration boundary.

  • Generic decode and validation preserve static types and specialization for the 8,000-request-per-second path.
  • The router registry stores any RouteHandler because it must hold 12 unrelated handlers in one collection.
  • Benchmark existential dispatch and allocations on Linux, and add type erasure explicitly if associated types leak into public callers.

Why interviewers ask this: This evaluates whether abstraction choices account for both API ergonomics and measured runtime boundaries.

genericsdesignci-cd

I would retain specialization only for the measured hot operations and erase types at colder stage boundaries.

  • Profile production-sized images to identify the two stages responsible for most CPU, rather than specializing every combinator.
  • Expose a non-generic pipeline facade so downstream modules do not instantiate 50 complete generic chains.
  • Accept a small dispatch cost outside the hot loop and enforce both CPU and compile-time budgets in CI.

Why interviewers ask this: This checks whether the candidate balances generic specialization against code size and compilation cost.

concurrencyswiftvalue-types

I would use copy-on-write storage with a uniquely referenced buffer and keep mutation behind a narrow value API.

  • The public Batch remains a struct, while an internal final Storage class owns the contiguous records.
  • Each mutating operation checks uniqueness before copying, so read-only passage through six stages shares the 20 MB buffer.
  • Benchmarks cover shared mutation, peak RSS, and concurrency because accidental reference escape would violate value behavior.

Why interviewers ask this: This tests deep understanding of value semantics, CoW mechanics, and the memory behavior of large data.

architecture-patternsserver-sideconcurrency

I would model immutable workflow states as values and place evolving identity inside one isolated reference owner.

  • State snapshots as structs make transitions auditable, comparable, and safe to persist or send across tasks.
  • An actor owns the workflow ID and serializes transitions, avoiding shared mutable class graphs.
  • Commands include expectedVersion, so stale UI edits fail explicitly rather than overwriting one of 30 transitions.

Why interviewers ask this: This evaluates a nuanced value-versus-reference decision under identity, concurrency, and persistence constraints.

typingprotocolsauth

I would add a new capability without immediately making all 25 conformers satisfy a new hard requirement.

  • Introduce a refined AuthorizedHandler protocol or an additive method with a safe default only if that default is semantically valid.
  • Adapt old conformers at the registry boundary and emit metrics showing which implementations still use legacy behavior.
  • Deprecate the old path for two minor releases, then make the requirement mandatory in the next major version.

Why interviewers ask this: This tests protocol evolution that preserves source compatibility without hiding unsafe behavior in defaults.

swiftcodableserialization

I would use a peer or member macro only for deterministic declaration generation, while keeping validation semantics in a normal tested library.

  • The macro expands explicit fields and diagnostics, but it does not perform network access or depend on developer-machine state.
  • Snapshot expansion tests cover 40 representative models and compile-fail tests verify useful diagnostics.
  • Adoption starts in one package, with build-time and source-debugging budgets measured before all 300 models migrate.

Why interviewers ask this: This evaluates whether macros reduce repetition without concealing business logic or destabilizing builds.

api

I would pin source dependencies to reviewed versions or revisions, verify binary artifacts by checksum, and run the plugin in isolated CI.

  • Resolve source packages from an approved mirror at an exact version or revision; record a checksum only for a binary artifact where applicable.
  • Declare schemas and outputs for build tracking, but use an OS sandbox or isolated container to restrict filesystem and network access because declarations are not read allowlists.
  • Give the job no unnecessary secrets, review generated diffs, regenerate from scratch, and record the pinned generator in the release SBOM.

Why interviewers ask this: This checks whether build extensibility is treated as executable supply-chain code rather than a harmless convenience.

concurrencyswiftcaching

I would partition actors by ownership and contention domain rather than place all mutable state in one global actor.

  • Account actors serialize one account each, while a sharded cache uses 64 actors selected by stable key hashing.
  • Audit writes flow through a bounded batching actor that flushes every 100 ms or 500 records.
  • Metrics expose mailbox delay and operation duration per actor so isolation does not hide overload.

Why interviewers ask this: This tests actor topology design for throughput, ownership, and observability at real concurrency.

concurrencyindexes

I would give each document job exclusive ownership of mutable buffers and exchange immutable stage results between regions.

  • A per-document actor owns parse state and never shares its mutable byte buffer with another task.
  • CPU-bound indexing uses task-group children over immutable chunks capped to the core count.
  • Export receives a Sendable snapshot, so cancellation can discard one job without corrupting another document.

Why interviewers ask this: This evaluates whether isolation is designed around data ownership rather than sprinkled actor annotations.

concurrencyswiftswift-concurrency

I would make transport messages immutable Sendable values and audit ownership against the exact Apple SDK and SwiftNIO versions in use.

  • Modern URLSession is @unchecked Sendable and current NIO releases include audited conformances, so I would not classify either framework wholesale as non-Sendable.
  • Keep event-loop-bound resources on their owning loop, document transfer of 5 MB Data values, and wrap only concrete types whose mutable ownership still needs isolation.
  • Use @unchecked Sendable only for a narrowly audited wrapper with synchronization and stress tests, never to silence broad warnings.

Why interviewers ask this: This checks whether Sendable conformance expresses real ownership across different runtime adapters.

concurrencyswiftvalue-types

I would use a bounded task group whose children always return a ShardOutcome, then apply the partial-result policy after aggregation.

  • Start at most six shard requests at once to protect connection pools, adding work as children finish.
  • Each child catches its own error or 120 ms timeout and returns success or failure metadata, so shard errors cannot escape the group and discard partial results.
  • Cancel remaining work at the 180 ms request deadline, aggregate all completed outcomes, and fail only if fewer than eight shards succeeded.

Why interviewers ask this: This evaluates structured concurrency, bounded parallelism, and product-specific failure semantics.

Locked questions

  • 21

    A media export can run for 20 minutes and spawns 40 child tasks. What cancellation contract would you design for app, server, and CLI callers?

    designresilience
  • 22

    A log ingestion pipeline receives 50,000 events per second but storage sustains 30,000. How would you express backpressure with Swift concurrency?

    concurrencyswiftbackpressure
  • 23

    A legacy C callback API completes once on a private queue and has a 5-second timeout. How would you expose it as async without leaks or hangs?

    asynccallbacksdata-structures
  • 24

    An Objective-C delegate emits 2,000 sensor updates per second and can call back after stop. How would you bridge it into Swift concurrency?

    concurrencyswiftprotocols
  • 25

    A sync engine creates tasks that may outlive a screen by 30 seconds and uses a delegate for progress. How would you define ARC ownership?

    ownershipdelegationprotocols
  • 26

    A Codable event is stored by Linux services and read by app versions up to 18 months old. How would you evolve the shared contract?

    codableserialization
  • 27

    Four Swift clients and a Vapor service share a 120-endpoint contract that changes weekly. Would you generate models or hand-maintain them?

    swiftendpointsserver-side
  • 28

    You are designing a Vapor API for 15,000 requests per second, 99.95% availability, and three independently owned domains. What service shape would you choose?

    designserver-sideapi
  • 29

    A Vapor endpoint performs 20 ms of CPU parsing and two database calls under a p99 target of 120 ms. How would you protect NIO event loops?

    databaseendpointsevent-loop
  • 30

    A multi-tenant Vapor service handles 6,000 concurrent requests, and no mutable request context may cross tenants. How would you isolate request state?

    multi-tenancyserver-sideconcurrency
  • 31

    A Vapor service has 120 database connections and traffic spikes to 4,000 requests per second. How would you size Fluent concurrency and pools?

    databaseconcurrencyserver-side
  • 32

    Creating an order touches inventory, payment intent, and an audit row, with a 300 ms SLA. Where would you draw Fluent transaction boundaries?

    transactions
  • 33

    A public Vapor API serves 3 million users and internal operators with stronger privileges. How would you structure authentication and authorization?

    authswiftvalue-types
  • 34

    An API must enforce 100 requests per minute per user across 20 Vapor instances, while allowing a 10-request burst. What limiter would you design?

    designserver-sideapi
  • 35

    A mobile client may retry order creation for 24 hours over unreliable networks, and the service handles 2,000 orders per second. How would you guarantee idempotency?

    resilienceidempotency
  • 36

    A Vapor endpoint streams 8 GB exports to 500 concurrent clients with a 256 MB memory limit per instance. How would you design it?

    designserver-sideendpoints
  • 37

    A collaboration service maintains 80,000 WebSocket connections and broadcasts documents to rooms of up to 2,000 users. What Swift architecture would you use?

    swiftwebsocketsarchitecture
  • 38

    A Vapor deployment gets 30 seconds to terminate while requests last up to 10 seconds and background jobs up to 2 minutes. How would you implement graceful shutdown?

    lifecyclejobsserver-side
  • 39

    A Linux Swift service has a 99.9% SLO and 150 ms p99 target across 60 endpoints. What observability contract would you build into shared packages?

    swiftendpointsobservability
  • 40

    A Swift CLI transforms 1 TB overnight on 200 hosts, and operators need to resume failed runs. What observability would you expose?

    swiftobservability
  • 41

    A package must support macOS and Ubuntu for 5 years, but currently imports Darwin and assumes case-insensitive paths. How would you make portability enforceable?

  • 42

    A SwiftUI trading screen receives 500 price updates per second, while the same domain package powers a CLI. Where would you place state boundaries?

    swiftuiswift
  • 43

    A UIKit editor is embedded in a SwiftUI app used by 4 million users, and both frameworks currently own the document state. How would you remove the dual ownership?

    uikitswiftuiswift
  • 44

    A cross-platform Swift platform has 600 tests but still ships contract failures monthly. What test pyramid would you establish?

    pyramidswift
  • 45

    A Swift SDK and Vapor backend release independently, with 10 supported client versions and weekly schema changes. How would you build contract testing?

    contractswiftschema
  • 46

    An actor-based ledger must preserve ordering under 5,000 concurrent test operations. How would you test it without sleeps?

    concurrency
  • 47

    A package supports Swift 5.10 and Swift 6 on macOS and Ubuntu, plus two iOS deployment targets, and CI must finish in 18 minutes. What matrix would you run?

    swiftdeployment
  • 48

    Eight teams lose 35 engineer-hours daily to Swift builds. How would you prioritize build-performance work over one quarter?

    swiftperformanceprioritization
  • 49

    A Swift package handles OAuth tokens for 6 apps and 3 Linux services, and a compromised dependency must not expose them. How would you design the security boundary?

    oauthtokensdependencies
  • 50

    A public Swift SDK parses untrusted 25 MB archives on client devices and Linux workers. What safeguards belong in the architecture?

    swiftarchitecture
  • 51

    During Swift 6 strict-concurrency migration, warnings jump from 40 to 2,800 across 70 targets and the release is due in six weeks. How do you stage the migration?

    concurrencyswiftmigrations
  • 52

    After enabling strict-concurrency checks and parallel request execution, a Linux service corrupts 0.03% of account balances under 6,000 requests per second, while unit tests pass. How do you diagnose the race?

    unitconcurrency
  • 53

    An actor-backed inventory check oversells 17 items during a sale because it awaits pricing between read and write. What evidence confirms reentrancy, and what do you change?

    asyncconcurrencyactor-reentrancy
  • 54

    After annotating a telemetry dashboard view model @MainActor, frame drops rise from 1% to 17% and main-thread CPU reaches 91% while decoding 2,400 sensor samples per second. How do you fix it?

    concurrencyactor-isolation
  • 55

    A Vapor deploy increases live tasks from 4,000 to 240,000 and memory from 700 MB to 9 GB in eight minutes. What do you inspect first?

    server-sidedeploymentmemory
  • 56

    Clients cancel 35% of searches, but database CPU remains 92% for 40 seconds afterward. How do you trace and repair cancellation propagation?

    databasetracingresilience
  • 57

    A wrapper around a photo callback hangs 1 in 20,000 requests, always near its 10-second timeout. How do you prove a continuation is never resumed?

    resiliencecallbacks
  • 58

    Production crashes with SWIFT TASK CONTINUATION MISUSE at a rate of 2 per 1 million requests after adding timeout support. How do you find the double resume?

    swiftstructured-concurrencyresilience
  • 59

    A user-initiated export waits 12 seconds behind background indexing even though its task priority is high. How do you diagnose priority inversion?

    indexesstructured-concurrency
  • 60

    An AsyncSequence consumer handles 8,000 messages per second while producers send 25,000, and RSS grows 400 MB per minute. What evidence and fix do you want?

    asyncconcurrency
  • 61

    An iOS sync session remains allocated after logout, retaining 600 MB and 18 child tasks. How do you isolate the ARC leak?

    memorymemory-leakssessions
  • 62

    A macOS controller and Objective-C delegate survive window closure in 4% of sessions. What cycle do you look for and how do you prove the fix?

    closuresprotocolssessions
  • 63

    Processing a 120 MB value-type document suddenly peaks at 1.8 GB after one mutation stage. How do you confirm a CoW regression?

    concurrency
  • 64

    Replacing a concrete parser with a generic pipeline lowers runtime CPU 8% but grows the Linux binary from 80 MB to 310 MB and cold start by 900 ms. What do you do?

    genericsci-cd
  • 65

    Moving 30 handlers into an any Handler registry raises p99 from 75 to 104 ms and allocations by 38%. How do you decide whether existentials caused it?

    registries
  • 66

    Package resolution starts taking 11 minutes and produces different versions on developer machines after adding two dependencies. How do you stabilize it?

    dependencies
  • 67

    Two shared packages require incompatible major versions of a logging library, blocking 14 teams. How do you resolve the SPM collision?

    loggingswift-package-manager
  • 68

    Incremental builds rise from 70 seconds to 9 minutes after a shared protocol gains one associated type. What evidence guides the fix?

    typingprotocols
  • 69

    After a route macro release, CI cache hits fall from 82% to 21%, and 7 of 50 clean builds produce different expansions for the same 180 routes. Do you roll back or repair?

    cachingrollback
  • 70

    A build plugin running in 18 repositories unexpectedly connects to the internet, and CI secrets are exposed in its child-process environment for 27 minutes. What is your incident response?

    incidentssecretsconcurrency
  • 71

    An XCFramework update crashes only on devices running the oldest supported OS, affecting 6% of users. How do you handle the binary artifact incident?

    soft-skillsincidentsartifacts
  • 72

    A backend changes retryAfterSeconds from a JSON number to a String, and 12% of active clients fail Codable decoding. What rollback do you execute?

    codableserializationresilience
  • 73

    A new enum case from the server causes 80,000 daily CLI jobs to exit before processing. How do you recover without hiding semantic errors?

    concurrencyenums
  • 74

    A Vapor endpoint p99 jumps from 90 ms to 4.2 seconds, and event-loop lag is 1.8 seconds after adding PDF parsing. What do you do in the first 15 minutes?

    server-sideendpoints
  • 75

    After a deploy, service p99 doubles from 140 to 290 ms while CPU, memory, and error rate remain flat. How do you narrow the cause?

    memorydeployment
  • 76

    One NIO event loop shows 95% utilization while seven remain below 25%, and only long-lived connections are slow. What do you investigate?

    event-loop
  • 77

    A list endpoint grows from 12 to 1,201 SQL queries and p99 reaches 2.6 seconds for 100 records. How do you confirm and fix Fluent N+1?

    sqln+1queries
  • 78

    Fluent pool acquisition p95 rises to 3 seconds, 18% of requests time out, but PostgreSQL uses only 35% CPU. What do you inspect?

    postgres
  • 79

    Two Fluent transactions deadlock 40 times per hour after a batch feature launches. How do you identify and remove the cycle?

    transactionslockingbatch
  • 80

    A Fluent migration adding an index locks a 400-million-row table and write latency exceeds 30 seconds. What is your recovery and safer plan?

    indexesmigrationslatency
  • 81

    After an auth-cache optimization, 23 requests return data from the wrong tenant in one hour. How do you contain and diagnose it?

    cachingoptimization
  • 82

    A payment endpoint creates 31 duplicate charges during a 20-minute network incident despite idempotency keys. Where do you look?

    endpointsidempotencyincidents
  • 83

    A global rate limiter should allow 5,000 requests per second but admits 8,700 during Redis failover. How do you redesign degraded behavior?

    redisrate-limiting
  • 84

    A WebSocket room with 2,000 members causes one event to consume 1.4 CPU-seconds and fanout latency reaches 9 seconds. How do you respond?

    latencywebsockets
  • 85

    Five percent of WebSocket clients consume 20 times slower, and per-connection queues grow until instances restart. What policy do you implement?

    websocketsdata-structures
  • 86

    A Linux Swift service is OOM-killed at 12 GB every six hours while heap snapshots show no single dominant leak. How do you investigate?

    data-structuresswiftsnapshot
  • 87

    During deployment, 2% of in-flight uploads truncate because instances exit 14 seconds after SIGTERM. How do you repair graceful shutdown?

    lifecycledeployment
  • 88

    A Swift CLI sorting a 300 GB file reaches 64 GB RSS and is killed halfway through. What redesign and evidence do you require?

    algorithmsswift
  • 89

    A CLI receives SIGINT during a 40-minute import, exits after 90 seconds, and leaves 12 child processes. How do you fix signal handling?

    concurrency
  • 90

    A formatter CLI is interrupted while replacing 18,000 files and leaves 73 zero-byte files. How do you eliminate partial-file corruption?

  • 91

    A SwiftUI dashboard redraws 4,500 rows on every one-second tick and energy use doubles. How do you isolate the invalidation source?

    swiftuiswift
  • 92

    Embedding a UIKit editor in SwiftUI duplicates save commands in 0.4% of sessions after navigation. How do you diagnose ownership?

    uikitswiftuinavigation
  • 93

    A 900,000-line Objective-C product must move networking to Swift without changing behavior for 8 million users. What incremental sequence do you choose?

    swift
  • 94

    You must enable strict concurrency in a 45-target package while three teams ship weekly and cannot pause feature work. How do you prevent a flag-day migration?

    concurrencyswift-concurrencymigrations
  • 95

    A public library must replace a callback API with async/await while supporting clients for 12 months. How do you migrate without a breaking release?

    asynccallbacksconcurrency
  • 96

    In review, an engineer proposes @unchecked Sendable on a mutable cache used by 30 tasks and says tests pass. How do you mentor through the decision?

    mentoringcachingtesting
  • 97

    A teammate puts Data(contentsOf:) inside a Vapor route; staging p99 rises from 100 ms to 1.6 seconds with 200 concurrent requests. How do you handle the review and learning?

    soft-skillsconcurrencyserver-side
  • 98

    During a pool-exhaustion incident, a junior engineer wants to raise PostgreSQL connections from 120 to 500 immediately. How do you guide the response?

    incidentspostgres
  • 99

    A code review adds a debug snapshot that retains every 50 MB CoW buffer for undo, and peak memory becomes 2.4 GB. How do you coach a better design?

    code-reviewdesignsnapshot
  • 100

    A team wants to skip Linux integration tests to cut CI from 22 to 14 minutes, after three portability regressions last quarter. How do you lead the review?

    integration