Skip to content

Archive / page 49

All articles

Every practical article from the Nalar archive, newest first.

Artificial Intelligence 10 Sep 2026 10 min read

Use Late Interaction for Fine-Grained Neural Retrieval

Use Late Interaction for Fine-Grained Neural Retrieval A single text embedding is convenient: encode a query into one vector, encode each document into one vector, then rank documents by vector similarity. That design scales well, but compression happens early. A paragraph containing several distinct ideas must squeeze all of them into one fixed-size representation before the query arrives. Late interaction keeps more of that detail. Instead of representing each text with only one vector, it retains multiple contextual token vectors and compares them at retrieval time. The document can still be encoded ahead of time, but the final relevance score is computed from fine-grained query-to-document matches.

Cybersecurity 10 Sep 2026 10 min read

Treat Uploaded File Types as Untrusted Input

A file upload usually arrives with reassuring metadata: a filename ending in .png, a Content-Type: image/png field, and perhaps a browser that already filtered the file picker to images. None of those facts proves that the uploaded bytes are a valid PNG image. That distinction matters as soon as the server does something security-sensitive with the file. It may pass the bytes to an image decoder, extract an archive, generate a preview, or serve the file to another user. If the application chooses that behavior from attacker-controlled metadata, it can send unexpected data into a parser or return active content under the wrong assumptions.

Cybersecurity 10 Sep 2026 12 min read

Treat MFA Recovery Codes as Real Credentials

Multifactor authentication can fail for ordinary reasons: a phone is lost, a hardware key breaks, or a device is replaced before an authenticator is migrated. Recovery codes give users a way back into an account without asking support staff to improvise an identity check. That convenience creates a security boundary of its own. If a recovery code can bypass the normal second factor, anyone who obtains that code may be able to do the same. A recovery system that is easier to attack than the authentication it replaces can quietly become the preferred path into the account.

Software Engineering 10 Sep 2026 11 min read

Tolerant Reader Pattern for Evolving Contracts

Tolerant Reader Pattern for Evolving Contracts A producer adds an optional field to a response. No existing meaning changed, yet an older consumer starts rejecting every message because its parser expected exactly five fields. The producer made a seemingly compatible change, but the consumer had quietly coupled itself to details it never used. The Tolerant Reader pattern addresses that problem from the consumer side. A tolerant reader describes and validates the information it actually depends on while allowing unrelated parts of an incoming representation to vary. Used carefully, this makes contracts easier to evolve without turning validation into guesswork.

Software Engineering 10 Sep 2026 10 min read

Token Bucket Rate Limiting for Controlled Bursts

Token Bucket Rate Limiting for Controlled Bursts A service may handle 100 requests per second comfortably on average while still needing to accept a short burst of 300 requests after a client reconnects. A rigid per-second limit treats those situations as the same problem: once the current window is full, otherwise acceptable work is rejected. Token bucket rate limiting gives you a more useful control. It separates two decisions: how quickly permission to do work is replenished and how much permission may accumulate for a burst. Once you understand those two numbers, you can reason about the limiter without depending on a particular library or platform.

Software Engineering 10 Sep 2026 9 min read

Testing Asynchronous Behavior with Eventual Assertions

Testing Asynchronous Behavior with Eventual Assertions A test starts background work and then checks the result. On a fast machine the work finishes first and the test passes. Under CI load, the assertion runs a few milliseconds earlier and fails. Someone adds sleep(1 second). The failure disappears, but every successful run now pays a full second, and a sufficiently slow run can still fail. The problem is not that the test needs a longer delay. The test doesn’t know exactly when the result will become observable.

Go 10 Sep 2026 7 min read

Test Concurrent Go Code with testing/synctest

Tests for concurrent Go code often become timing tests by accident. A goroutine starts, the test sleeps for 20 milliseconds, then checks whether something happened. That can pass thousands of times and still fail on a loaded CI runner because the sleep never proved the goroutine reached the state you cared about. Go’s testing/synctest package gives these tests a better model. It runs code inside an isolated bubble where time is virtualized, and synctest.Wait can synchronize the test with goroutines in that bubble. The result is especially useful for code built around timers, context deadlines, retries, and background goroutines.

Artificial Intelligence 10 Sep 2026 10 min read

Temperature in LLM Sampling

A language model can produce very different continuations from the same prompt even when its weights and context haven’t changed. One of the controls behind that variation is temperature. Temperature is often described as a creativity knob. That description is convenient but incomplete. Temperature doesn’t add ideas to a model, improve its knowledge, or directly control factual accuracy. It changes the probability distribution used to choose the next token. The practical effect depends on what the model already considers plausible at that step.

Software Engineering 10 Sep 2026 8 min read

Tell, Don’t Ask: Keep Decisions with the Data

Tell, Don’t Ask: Keep Decisions with the Data A checkout service reads an order’s status, total, and payment state, decides whether cancellation is allowed, and then changes the order. Later, a support tool needs the same operation and copies most of that decision logic. The two callers eventually disagree about one rule. Tell, Don’t Ask is a software design principle that helps prevent this kind of drift. Instead of asking an object for internal state so another object can make a decision about it, prefer telling the object what outcome you want and letting the object enforce the rules that belong to its state.

Software Engineering 10 Sep 2026 8 min read

Stale-While-Revalidate for Responsive Caches

Stale-While-Revalidate for Responsive Caches A cache entry expires just as a request arrives. The cached value is still only seconds old, but the request now has to wait while the application fetches a replacement from a slower dependency. If many entries expire during a busy period, cache refreshes can turn a normally fast read path into a burst of slow work. Stale-while-revalidate changes that trade-off. For data that can safely be slightly out of date, the application may return an expired cached value immediately while refreshing it separately for future requests. The reader gets predictable latency, and the cache still moves toward fresh data.

Software Engineering 10 Sep 2026 9 min read

Split Phase Refactoring to Separate Computation Stages

Split Phase Refactoring to Separate Computation Stages A function starts by interpreting input, then gradually accumulates validation, business rules, formatting, and output logic. None of those steps is necessarily complicated. The difficulty comes from having them interleaved: changing how input is interpreted can unexpectedly affect code that should only care about the interpreted result. Split Phase is a refactoring that separates one computation into distinct stages. The first phase produces an explicit intermediate result. The next phase consumes that result without needing to know how it was produced.

Software Engineering 10 Sep 2026 10 min read

Specification Pattern for Composable Business Rules

Specification Pattern for Composable Business Rules Business rules often begin as a few readable conditions. Then the same decisions appear in validation, eligibility checks, filtering, and workflow code. Small differences creep in: one path checks account status but forgets the credit limit; another copies the whole expression and changes only one threshold. The Specification pattern gives a business rule a name and an interface, then allows rules to be combined into larger decisions. It is useful when the same rule matters in several places or when complex policy is easier to understand as a composition of smaller concepts.

Go 10 Sep 2026 5 min read

Sort Go Iterator Values with slices.Sorted

An iter.Seq is convenient while values are flowing through a pipeline. Sorting changes the problem: a sort needs all of those values available at once. If the next step needs an ordered slice, Go has a standard-library helper that makes that boundary explicit. Go 1.23 added slices.Sorted. It consumes an iter.Seq of ordered values, collects the values into a new slice, sorts that slice in ascending order, and returns it.

Go 10 Sep 2026 7 min read

Set Per-Response Write Deadlines in Go with http.ResponseController

A server-wide WriteTimeout is a useful safety net, but some handlers have different timing needs. A small JSON response and a streaming export shouldn’t necessarily share the same write budget. When the deadline belongs to one response rather than the whole server, Go’s http.ResponseController gives the handler a direct way to set it. http.ResponseController.SetWriteDeadline applies a write deadline to the current response. It also solves a practical middleware problem: instead of asserting a concrete optional interface at every call site, a handler can ask the controller to find the capability through compatible ResponseWriter wrappers.

Go 10 Sep 2026 6 min read

Search Go Struct Slices with slices.BinarySearchFunc

A slice of structs can be sorted by an ID, timestamp, or other field even though the struct itself has no built-in ordering. When you need repeated lookups in that sorted data, slices.BinarySearchFunc lets the search use the same ordering without building a separate index. The comparator is the part that deserves attention. It doesn’t compare two slice elements. It compares one element from the slice with the search target, and its ordering must agree with the way the slice is sorted.

Software Engineering 10 Sep 2026 8 min read

Saga Pattern for Multi-Step Workflows

Saga Pattern for Multi-Step Workflows A workflow reserves inventory, charges a payment, and schedules delivery. Each step is handled by a different component with its own state. The inventory reservation succeeds, but payment fails. What should the system do with the reservation that already committed? A single database transaction can’t usually roll back work that has already been committed by independent components. The saga pattern handles this kind of workflow by treating it as a sequence of local transactions. When a later step fails, the workflow runs explicit compensating actions for earlier steps where business reversal is possible.

Go 10 Sep 2026 5 min read

Restrict Slice Capacity in Go with slices.Clip

A Go slice can be much smaller than the backing array it refers to. That spare capacity is useful when more append calls are coming, but sometimes you deliberately want the opposite: a result whose capacity stops exactly at its current length. slices.Clip expresses that operation directly. It reduces a slice’s capacity to its length without changing its elements or length. The detail that matters is what this does, and doesn’t, imply about memory.

Cybersecurity 10 Sep 2026 9 min read

Require Independent Approval for High-Risk Administrative Actions

Some administrative actions are too consequential to depend on one account making one decision. An administrator might be compromised, might misunderstand the target, or might simply select the wrong option. If that one identity can immediately disable a critical control, grant powerful access, or approve a destructive change, ordinary authentication cannot distinguish a legitimate decision from a costly mistake. Independent approval changes that failure mode. One authorized person proposes the action, and a different authorized person must approve the same action before it can execute. The control is sometimes called two-person approval or a four-eyes rule. Its useful security property is narrower than those names suggest: a single administrator’s authority is insufficient for a defined class of high-risk operations.

Go 10 Sep 2026 7 min read

Replace Slice Ranges in Go with slices.Replace

Replacing part of a Go slice sounds simple until the replacement has a different length from the range it replaces. A two-element range might become one element, four elements, or nothing at all. At that point, a few append calls can work, but they make the indexing and storage behavior harder to read than the operation itself. slices.Replace handles that splice-like operation directly. Give it a slice, a half-open range, and the replacement values; it returns the resulting slice. The function can shrink, preserve, or grow the length depending on how many values you provide.

Software Engineering 10 Sep 2026 10 min read

Replace Primitive Obsession with Domain Types

Replace Primitive Obsession with Domain Types A customer ID, an email address, and a currency code can all be represented as strings. That doesn’t make them interchangeable. When a codebase treats every meaningful value as a generic string, integer, or boolean, callers have to remember rules that the type itself doesn’t express. This problem is often called primitive obsession: using general-purpose primitive values where the domain has a more specific concept. The practical fix isn’t to wrap every string in a class. It’s to introduce a domain type when doing so gives the program a useful place to enforce meaning and rules.

Software Engineering 10 Sep 2026 8 min read

Replace Conditional with Polymorphism When Branches Represent Types

Replace Conditional with Polymorphism When Branches Represent Types A conditional isn’t a design problem just because it has several branches. Sometimes if or switch is the clearest way to express a decision. Trouble starts when the same type-based decision appears in several places and every new variant requires editing all of them. Replace Conditional with Polymorphism is a refactoring that moves variant-specific behavior behind a common operation. Instead of asking an object what kind it is and then deciding what to do, callers ask it to perform the behavior directly.

Go 10 Sep 2026 5 min read

Repeat Slice Patterns in Go with slices.Repeat

Repeating a short slice pattern is simple enough to write by hand, but the bookkeeping gets noisy: calculate the final size, allocate storage, then append or copy the pattern the right number of times. Since Go 1.23, slices.Repeat handles that operation directly. The function is useful when the thing you want to repeat is already a slice: a test fixture pattern, a protocol marker, a sequence of defaults, or any other small block of values. It returns a new slice rather than extending or rearranging the input.

Go 10 Sep 2026 5 min read

Remove Consecutive Duplicates in Go with slices.Compact

If a Go slice contains repeated values next to each other, you don’t need to write an index-heavy loop to collapse them. Since Go 1.21, slices.Compact handles that operation directly for comparable element types. The word consecutive matters. Given []string{"api", "api", "web", "api"}, the result is []string{"api", "web", "api"}. The last "api" stays because it belongs to a different run. slices.Compact isn’t a general-purpose “unique values” function. What slices.Compact actually does slices.Compact replaces each consecutive run of equal elements with its first element. It modifies the slice’s backing array and returns a slice with the resulting length.

Cybersecurity 10 Sep 2026 10 min read

Reject Replayed Sensitive Requests with Freshness and Uniqueness

A request can be authentic and still be unsafe to execute twice. Suppose a service accepts a correctly authenticated instruction to change a payout destination, approve a privileged action, or trigger another sensitive operation. If someone can capture that valid request and submit the same authenticated message again, checking its credentials or signature a second time may produce the same answer: the request is genuine. The server still needs to decide whether it is current and whether it has already been used.