Skip to content

Archive / page 80

All articles

Every practical article from the Nalar archive, newest first.

Software Engineering 03 Sep 2026 8 min read

Validating at Boundaries to Contain Invalid Data

Many software failures begin far from the place where they are eventually noticed. A malformed value enters through an API, configuration file, message, command, or user action. The program accepts it, passes it through several layers, and fails later when some unrelated operation assumes the value is valid. By then, the original cause is harder to see. A useful design principle is to validate data at the boundary where it enters a trusted part of the system. A boundary is any point where code receives information whose assumptions it does not yet control. The goal is not to scatter checks everywhere. It is to turn uncertain input into either a known-valid value or an explicit failure before the rest of the program relies on it.

Cybersecurity 03 Sep 2026 10 min read

Validate Untrusted Input at Trust Boundaries

Applications constantly receive data they did not create: HTTP parameters, uploaded metadata, webhook payloads, queue messages, imported files, configuration from external systems, and values read from shared storage. The security problem is not that every external value is malicious. The problem is that application code can make unsafe assumptions about values whose shape, size, meaning, or origin has not been established. Boundary validation reduces that risk by checking untrusted data before the rest of the application relies on it. The goal is simple: turn vague external input into explicit internal invariants.

Software Engineering 03 Sep 2026 9 min read

Using Feature Flags Without Creating Permanent Complexity

A code change is often ready to deploy before it is ready to expose to every user. A team may want to test a new workflow with internal users, release it gradually, or keep unfinished behavior inactive while several changes reach production. A feature flag provides that control. It is a runtime decision that selects between behaviors without requiring a new deployment for every change in exposure. That sounds simple, but feature flags create their own engineering cost. Every active flag can introduce another path through the system. If flags accumulate, developers eventually have to reason about combinations of old and new behavior that nobody intended to keep forever.

Software Engineering 03 Sep 2026 11 min read

Using Decision Tables to Tame Complex Rules

Conditional logic often becomes difficult before it becomes large. Three or four business conditions can interact in enough combinations that a developer can no longer tell, by reading nested if statements, whether every case is covered or whether two branches contradict each other. A decision table is a compact way to make those combinations explicit. It lists the conditions that affect a decision, the meaningful combinations of those conditions, and the outcome for each combination.

Python 03 Sep 2026 11 min read

Use Weak References for Non-Owning Object Relationships in Python

Most Python code should use ordinary references. If one object stores another object in an attribute, list, or dictionary, that reference normally means the stored object should remain available for as long as the owner needs it. Some relationships are different. A cache may want to reuse an object only while another part of the program already owns it. A registry may want to discover live objects without extending their lifetime. An observer table may want to remember listeners without becoming the reason those listeners can never be collected.

Go 03 Sep 2026 11 min read

Use sync.Pool for Temporary Object Reuse in Go

Repeatedly allocating short-lived helper objects can become expensive in a hot path. A formatter may create temporary buffers for every request, an encoder may allocate scratch space for every record, or a parser may repeatedly construct helper objects that are discarded immediately after use. Go’s sync.Pool can reuse some of those temporary objects across independent operations. That can reduce allocation work and garbage-collector pressure when the same kind of object is created frequently under load.

Database 03 Sep 2026 13 min read

Use SQL Window Functions Without Losing Row Detail

Many SQL problems ask for a calculation across several rows while still returning each original row. For example, you may need to show every order together with the customer’s running spend, rank products inside each category, or compare today’s measurement with the previous one. A regular aggregate such as SUM() or AVG() can calculate across rows, but a GROUP BY query usually collapses those rows into one result row per group.

Python 03 Sep 2026 10 min read

Use Single Dispatch for Type-Based Behavior in Python

A function sometimes needs to perform the same conceptual operation for several unrelated Python types. The straightforward solution is usually an if chain: def format_value(value): if isinstance(value, str): return value if isinstance(value, int): return str(value) if isinstance(value, dict): return ", ".join(f"{key}={item}" for key, item in value.items()) raise TypeError(f"unsupported type: {type(value).__name__}") This is perfectly reasonable when the set of supported types is small and unlikely to grow.

Cybersecurity 03 Sep 2026 6 min read

Use HTTP Security Headers as Defense in Depth

HTTP security headers let a server tell browsers which security rules should apply to a response. They can restrict where content loads from, prevent MIME type guessing, reduce referrer leakage, and enforce encrypted transport. They are useful defense in depth, not a replacement for input validation, output encoding, authentication controls, or secure session handling. A strong header policy can limit the impact of some mistakes, but it cannot make an unsafe application secure by itself.

Artificial Intelligence 03 Sep 2026 6 min read

Use Few-Shot Prompting with Effective Examples

A prompt can explain a task with instructions, but sometimes examples communicate the desired behavior more precisely. Few-shot prompting places a small number of input-output demonstrations in the model’s context before the real input. This technique is useful when a task has a specific output format, subtle classification boundary, naming convention, or transformation rule that is difficult to describe completely in prose. The model is not retrained by these examples. Instead, it uses the demonstrations as part of the current context when generating the next response.

Go 03 Sep 2026 10 min read

Use defer for Reliable Cleanup in Go

Resource cleanup is easy to get right on the happy path and easy to miss on an early return. A function opens a file, acquires a lock, or starts a trace span; a later check fails; the function returns before reaching the cleanup statement. Go’s defer statement addresses this by scheduling a function call to run when the surrounding function returns. Used well, it places cleanup next to acquisition and makes every return path easier to reason about.

Python 03 Sep 2026 9 min read

Use Decimal for Predictable Base-10 Arithmetic in Python

Many Python programs can use float without trouble. Measurements, graphics, statistics, and scientific calculations often benefit from fast binary floating-point arithmetic. Problems appear when the data itself is defined in decimal terms and exact decimal values matter. A price such as 19.99, a tax rate such as 7.5%, or a quantity rounded to two decimal places may need rules that match decimal arithmetic rather than the binary representation used by float.

Database 03 Sep 2026 9 min read

Understand SQL NULL with Three-Valued Logic

NULL is one of the easiest SQL concepts to recognize and one of the easiest to reason about incorrectly. The problem starts when NULL is treated as if it were an ordinary value such as 0, an empty string, or the word "unknown". It is none of those. In SQL, NULL represents the absence of a known value, and comparisons involving that absence often produce a third logical result: UNKNOWN.

Rust 03 Sep 2026 9 min read

Understand Pin and Unpin in Rust

Most Rust values can move freely. Assign a value to another variable, pass it by value, return it from a function, or replace it inside a container, and the value may end up at a different memory address. Usually that is exactly what you want. Rust’s ownership model tracks who owns a value, not where that value must remain in memory. A smaller class of types is different. Some values become address-sensitive: code relies on the value continuing to exist at the same memory location. Compiler-generated futures and carefully designed self-referential structures are common examples.

Go 03 Sep 2026 12 min read

Understand Nil Interface Values in Go

A Go program can print an error that looks empty, enter an if err != nil branch, and still be holding a nil pointer underneath. This behavior surprises developers because it seems to violate the simple rule that “nil means no value.” The rule is still consistent. The missing piece is that an interface value has two parts: a dynamic type and a dynamic value. An interface is nil only when neither part is set.

Artificial Intelligence 03 Sep 2026 10 min read

Train Larger AI Models with Gradient Accumulation

Training a neural network often becomes memory-bound before it becomes compute-bound. You may want a batch of 64 examples for stable optimization, but the model, activations, optimizer state, and input tensors leave enough accelerator memory for only 8 examples at a time. Reducing the batch size to 8 may work, but it also changes the optimization process. Gradient accumulation provides another option: process several smaller microbatches, add their gradients together, and update the model only after the desired effective batch has been processed.

Artificial Intelligence 03 Sep 2026 7 min read

Tokenization in Large Language Models

Large language models do not read text as words or characters in the way people do. Before text reaches the model, a tokenizer converts it into a sequence of discrete units called tokens and maps those tokens to numerical identifiers. Tokenization is easy to overlook because most model APIs perform it automatically. Yet token boundaries affect context-window usage, inference cost, truncation, multilingual behavior, and even whether two visually similar strings are represented in similar ways. These details explain many LLM behaviors that otherwise look inconsistent.

Artificial Intelligence 03 Sep 2026 10 min read

Tokenization in Language Models

Language models do not read text as a sequence of words. Before a model can process a prompt, a tokenizer converts the text into a sequence of token IDs from a fixed vocabulary. The model operates on those IDs, and generated IDs are later converted back into text. This extra layer is easy to ignore because most model APIs accept ordinary strings. But tokenization affects how much text fits in a context window, how usage-based costs are calculated, how text is truncated or split, and why seemingly small formatting changes can alter model behavior.

Cybersecurity 03 Sep 2026 10 min read

Store Passwords with Memory-Hard Hashing

A login system must verify passwords, but it should not need to recover them. That distinction matters when an authentication database is copied through a vulnerability, backup exposure, or operational mistake. If the database contains plaintext passwords, the compromise immediately reveals them. If it contains fast, unsalted hashes, an attacker can test large numbers of password guesses efficiently and reuse work across accounts. Password hashing changes the problem. The application stores a verifier produced by a deliberately expensive password-hashing function. During login, it applies the same function to the submitted password and checks whether the result matches.

Artificial Intelligence 03 Sep 2026 9 min read

Stop Model Training at the Right Time with Early Stopping

Training a model for more epochs does not guarantee a better model. Training loss may keep falling while performance on unseen data stops improving or begins to degrade. Continuing from that point consumes compute and can leave you with a checkpoint that generalizes worse than an earlier one. Early stopping turns validation performance into a stopping rule. Instead of choosing a fixed number of epochs and hoping it is appropriate, you monitor a validation metric, keep the best checkpoint, and stop after the metric has failed to improve for a defined amount of time.

Artificial Intelligence 03 Sep 2026 10 min read

Stabilize Neural Network Training with Gradient Clipping

Neural network training can look healthy for many steps and then suddenly become unstable. The loss may jump, parameters may receive an unusually large update, or numerical values may become non-finite. One possible cause is an exploding gradient: the gradient becomes large enough that the resulting optimization step is destructive. Gradient clipping puts a limit on gradients before the optimizer uses them. It is especially useful when occasional gradient spikes are expected, but it is not a general repair for a bad learning rate, broken data, or an incorrect training loop.

Artificial Intelligence 03 Sep 2026 10 min read

Speculative Decoding for Faster LLM Inference

Autoregressive language models generate text sequentially. After processing the prompt, the model predicts a next token, appends that token to the sequence, and repeats the process. That dependency makes generation difficult to parallelize across time: token 101 cannot normally be generated until token 100 is known. Speculative decoding changes the amount of useful work performed during each expensive target-model step. A cheaper draft process proposes several future tokens, then the target model verifies those proposals together. When enough proposals are accepted, the application can advance by multiple tokens while invoking the large model fewer times.

Tech 03 Sep 2026 7 min read

Sleep vs Hibernate: What Happens to Your Computer

Closing a laptop lid can make the screen go dark almost instantly, yet opening it later may bring back the same applications and documents. Hibernate can appear similar, but the computer can remain without external power for much longer without losing that saved working state. The difference comes down to where the computer keeps the information it needs to resume. Sleep generally keeps the current working state in memory while most other activity is reduced or stopped. Hibernate saves that state to persistent storage so the computer can power down more completely.

Cybersecurity 03 Sep 2026 10 min read

Separate High-Risk Actions with Dual Control

Some actions are too consequential to depend on one authenticated account making one correct decision. Deleting a production backup, changing a payment destination, disabling a security control, granting organization-wide administrator access, or rotating a recovery credential can all be legitimate operations. The problem is that a stolen administrator session, a compromised account, or a simple human mistake may turn the same capability into a serious incident. Dual control reduces this risk by separating a sensitive action into at least two independent decisions. One person requests the action, and another authorized person approves it before the system executes it.