Also: App state, ScenePhase
Active means in front and receiving touches; inactive means visible but briefly interrupted (Control Center, the app switcher, a call); background means not visible, with a few seconds before the app is suspended. Suspended apps can be terminated without any callback, so user data is saved when the scene enters the background.
In practice: .onChange(of: scenePhase) saves the draft when the phase becomes .background.
Related:Background task (iOS)
In Hilt, a scope annotation ties a binding to a component's lifetime: @Singleton (the whole app), @ActivityRetainedScoped (an activity across rotation), @ViewModelScoped (one ViewModel), @ActivityScoped. Unscoped bindings create a new instance for every injection. Scope expensive or stateful objects that must be shared, such as HTTP clients and databases, and leave stateless helpers unscoped.
In practice: An unscoped OkHttpClient provider gives every repository its own client and connection pool.
Related:Dependency injection
Also: Sealed class, Sealed interface, Sum type, Tagged union
A sealed class or interface only allows the subtypes declared next to it (in the same module and package in Kotlin, listed in permits in Java). Because the compiler knows every subtype, a when or switch that handles all of them needs no default branch, and adding a subtype makes every incomplete switch fail to compile. Swift gets the same effect with enums that have associated values.
In practice: sealed interface SearchState with Idle, Loading, Loaded(products) and Failed(message): a screen is always in exactly one of them.
Related:Pattern matchingSmart cast
The compiler only lets Sendable values cross from one concurrency domain to another. Value types made of Sendable parts are Sendable automatically, as are actors, immutable final classes and classes isolated to the main actor. In the Swift 6 language mode, sending a non-Sendable value across domains is a compile error. @unchecked Sendable turns the check off, so it must be backed by a real lock.
In practice: A struct Order with let properties can be returned from a background task to a @MainActor view model without any extra work.
Related:ActorData race
Also: SSE, EventSource
The client opens a normal HTTP request and the server writes events into the response as they happen. Because it is plain HTTP, it works through proxies and load balancers, and browsers reconnect automatically, sending the id of the last event received in a Last-Event-ID header so the server can send what was missed. It suits live feeds where only the server sends data; WebSockets suit two-way traffic.
In practice: A restaurant's order board receives each new order as an event within a second, and catches up after a reconnect.
Related:WebSocket
Also: Deep copy
Changing a nested list or object through the copy changes the original too, because there is only one of it. A deep copy also copies the nested objects. Kotlin data class copy(), TypeScript object spread and Java clone() are shallow; Swift structs whose fields are all value types copy deeply. Immutable nested data makes sharing safe.
In practice: copy = original.copy() followed by copy.items.add(extra) adds the line to the original invoice as well.
Related:Prototype patternValue type
Also: Horizontal partitioning, Partitioning
When data or traffic outgrows one database server, you split it by a shard key: each shard holds the rows whose key maps to it, often by hashing the key. Lookups by that key go to exactly one shard. Queries that don't use the key have to ask every shard, so choosing the key is the most important decision.
In practice: A URL shortener shards by short code, so every redirect reads from exactly one shard.
Related:CachingLoad balancer
Also: SRP
Code that changes for different stakeholders, such as pricing rules, storage and email wording, should live in different classes, so a change for one cannot break the others. It does not mean one method per class: a class with ten methods that all serve the same job still has a single responsibility.
In practice: An OrderService that validates, prices, saves and emails is split into a pricing policy, a repository and a notifier.
Related:Open/closed principle
Also: Singleton pattern
A singleton hides its constructor and exposes one shared instance: Swift static let shared, a Kotlin object, a Java static final field or enum, a TypeScript module export. One instance is often fine (a logger, an HTTP client, a cache); global access is the risky part, because it hides dependencies and shares state between features and tests. Modern code keeps the single instance and passes it in.
In practice: Analytics.shared.track("purchase") works everywhere, but a view model that receives the analytics object in its constructor can be tested with a fake.
Related:Dependency injectionDesign pattern
A window is a range between two indices. A fixed window adds the element that enters and removes the one that leaves. A variable window grows on the right and shrinks from the left while it breaks a rule. Each element enters and leaves once, so the work is O(n). It needs a rule that changes in one direction as the window grows, which is why it works for non-negative sums but not with negative numbers.
In practice: The longest substring without repeating characters: grow the window, and when a character repeats, shrink from the left until it doesn't.
Related:Two pointersHash map
After a check like if (name != null) or if (shape is Circle), Kotlin automatically treats the value as String or Circle inside that block. It only works when the compiler can prove the value can't change between the check and the use, so it works for local vals but not for mutable properties (var) that another thread or a custom getter could change.
In practice: if (user.email != null) sendTo(user.email) fails to compile when email is a var property; user.email?.let { sendTo(it) } works.
Related:Null safetyPlatform type
Also: Bean
Classes marked with @Component, @Service, @Repository or @RestController, and the results of @Bean methods, become beans. Spring creates them at startup, passes them to each other through constructors, and by default keeps exactly one instance of each, shared by every request and thread. That is why beans should not store data about a single request or user in their fields.
In practice: A QuoteController asks for a QuoteService in its constructor, and Spring passes in the single QuoteService bean.
Related:Dependency injectionInversion of control
Also: LIFO
A stack supports push (add on top), pop (remove from the top) and peek, all in O(1). It is the natural structure for undo, the back button, matching brackets and depth-first traversal. Function calls also use a stack, the call stack, which has a fixed size and can overflow with very deep recursion. Swift uses an Array as a stack; Kotlin and Java use ArrayDeque.
In practice: Checking brackets: push every opening bracket, and pop when a closing one arrives to check it matches.
Related:Queue
A hoisted component is stateless: it gets the current value and a function to call when the user changes it. The caller owns the state. This keeps a single source of truth, makes components reusable and easy to preview and test. The rule of thumb is: values go down, events go up. It applies to Jetpack Compose and SwiftUI alike.
In practice: SearchField(query = query, onQueryChange = { query = it }) lets the screen own the text while the field just displays it.
Related:Recomposition
Also: Finite state machine, FSM, State pattern
Instead of several booleans that can combine into impossible situations, a state machine has one current state and a transition function (state, event) to next state. Every rule lives in one place, unexpected events in a state become a deliberate decision, and transitions can be tested as a table. The State pattern implements it with one object per state.
In practice: A media player is idle, loading, playing, paused or failed; tapping Play while loading does nothing, by rule.
Related:Sealed hierarchyUnidirectional data flow
With structured concurrency, background work is started inside a scope: a Kotlin CoroutineScope, a Swift task group or async let. The scope can't finish until its children finish, cancelling the scope cancels the children, and a child's failure is reported to the parent. Work therefore can't leak past the screen or request that started it. Unstructured tasks such as GlobalScope.launch or Task.detached opt out of these guarantees.
In practice: viewModelScope cancels every coroutine it started when the ViewModel is cleared, including in-flight network requests.
Related:Coroutineasync/await
Instead of comparing every interval with every other one, you turn each interval into a start event and an end event, sort all events by time, and walk through them once. A counter or a heap holds what is currently open. It answers questions like the maximum number of overlapping meetings in O(n log n).
In practice: Meetings 9-10, 9:30-11 and 10:30-12 give events at 9 (+1), 9:30 (+1), 10 (-1), 10:30 (+1), 11 (-1), 12 (-1); the count peaks at 2.
Related:Priority queue
Introduced with Xcode 16, Swift Testing replaces XCTestCase subclasses and XCTAssert functions for unit tests. #expect records a failure and shows the values involved; #require stops the test. Tests run in parallel by default, suites are structs with a fresh instance per test, and @Test(arguments:) reports each input separately. UI tests and performance tests still use XCTest.
In practice: @Test(arguments: ["", "a", "abc"]) runs one validation test three times, with three separate results.
Related:Unit testTest double