Mert Özen Further With Every Line

Blog

Mert Özen's blog posts on software development, backend, frontend, and DevOps.

Series
79 posts found
Randomness Algorithms: Fisher–Yates Shuffle, Reservoir Sampling, Weighted Random and Random.Shared, Shuffle, GetItems in .NET
Computer Science Fundamentals PART 27

Randomness Algorithms: Fisher–Yates Shuffle, Reservoir Sampling, Weighted Random and Random.Shared, Shuffle, GetItems in .NET

The correct shuffle is Fisher–Yates: at each step it picks only from the remaining elements and leaves exactly one path to each of the n! permutations. We measure two common biased shuffles in C#, sample from a stream with reservoir sampling, pick by weight with a cumulative array and the alias method, build a per-user 10 percent rollout with XxHash3, show a Random shared across threads getting corrupted, and close the series.

15 Nov 2026 10 min 7
Probabilistic Data Structures: Bloom Filter, Count-Min Sketch and HyperLogLog
Computer Science Fundamentals PART 26

Probabilistic Data Structures: Bloom Filter, Count-Min Sketch and HyperLogLog

Probabilistic data structures cut memory by orders of magnitude in exchange for a small, controlled error: a Bloom filter says "definitely not / probably yes", Count-Min Sketch estimates frequencies by over-counting, HyperLogLog counts uniques with constant memory. We write all three in C# and measure a 1.01 percent false positive rate with 1.14 MB for a million e-mails, and unique visitors within 0.8 percent using 16 KB.

15 Nov 2026 10 min 9
Interval Problems and Sweep Line: Overlapping Ranges, Merge Intervals, Monotonic Stack and Calendar/Slot Scenarios
Computer Science Fundamentals PART 25

Interval Problems and Sweep Line: Overlapping Ranges, Merge Intervals, Monotonic Stack and Calendar/Slot Scenarios

Most interval problems are solved in O(n log n) with a half-open [Start, End) definition, sorting by start and a sweep line. We write overlap detection, merge intervals, "how many at most at once" and gap finding in C#, and show how an inclusive last day hides a real campaign overlap, the lowest price of the last 30 days with a monotonic deque, and the same delivery landing on two days because of time zones.

15 Nov 2026 11 min 7
String Search Algorithms: Naive, KMP, Rabin-Karp, Aho-Corasick and .NET's IndexOf/SearchValues<string>
Computer Science Fundamentals PART 24

String Search Algorithms: Naive, KMP, Rabin-Karp, Aho-Corasick and .NET's IndexOf/SearchValues<string>

For a single pattern, KMP never moves back in the text and guarantees O(n + m); for many patterns, Aho-Corasick adds failure links to a trie and finds them all in one pass. We write naive search, KMP, Rabin-Karp and Aho-Corasick in C#, measure them against .NET's vectorized IndexOf and the Teddy and Aho-Corasick inside SearchValues<string>, and show the Turkish I pitfall.

15 Nov 2026 11 min 8
LRU and LFU Caches: O(1) Eviction with Dictionary + LinkedList and the Ready-Made Options in .NET
Computer Science Fundamentals PART 23

LRU and LFU Caches: O(1) Eviction with Dictionary + LinkedList and the Ready-Made Options in .NET

An LRU cache combines a Dictionary to find the key with a LinkedList to keep usage order; because the Dictionary stores the node itself, get and put are O(1). We write an LRU and an O(1) LFU in C#, measure a List-based version slowing down 13x, LRU's hit ratio dropping to 52 percent under scan traffic, and show why IMemoryCache is not an LRU.

15 Nov 2026 11 min 8
How Programming Languages Evolve: Paradigms from Lisp to C# and the Road to Runtime Async
Computer Science Fundamentals PART 08

How Programming Languages Evolve: Paradigms from Lisp to C# and the Road to Runtime Async

Language features are often born as a trick the compiler imitates with existing constructs, and once they spread the runtime supports them directly: generics, lambdas and .NET 11's Runtime Async are examples. A short family tree from Fortran and Lisp to C#, paradigms used together in C#, static/dynamic and strong/weak typing, the nominal versus structural difference between C# and TypeScript, and a live stack that drops from 13 lines to 5 with Runtime Async, all with real output.

15 Nov 2026 11 min 12
How Garbage Collection Works: Mark-Sweep-Compact, Generational GC and .NET Server GC
Computer Science Fundamentals PART 07

How Garbage Collection Works: Mark-Sweep-Compact, Generational GC and .NET Server GC

A tracing GC marks the objects reachable from the roots and treats the rest as garbage; .NET splits this work into generations and keeps gen0 GCs cheap with a write barrier and a card table. With dotnet-counters and BenchmarkDotNet we show the Bookstore filter language's interpreter producing 10 GB of allocations and 1,365 gen0 GCs in five seconds while the compiled delegate triggers none, and measure the LOH, Workstation and Server GC, DATAS, and a real leak versus uncollected memory.

15 Nov 2026 14 min 12
AOT Compilation: ReadyToRun, Native AOT and the Startup vs Throughput Trade-off
Computer Science Fundamentals PART 06

AOT Compilation: ReadyToRun, Native AOT and the Startup vs Throughput Trade-off

Native AOT produces machine code at publish time and clearly reduces startup time and memory; the price is trimming, no dynamic code, platform-specific builds and no Dynamic PGO. We publish the same Bookstore API with JIT, ReadyToRun and Native AOT and measure startup, memory and throughput, and show the warnings our filter language hits, a trimming bug that returns 500 without any warning, and the cost of Expression.Compile() falling back to an interpreter.

15 Nov 2026 13 min 12
IL and the JIT Compiler: Tiered Compilation, Dynamic PGO, Inlining and Escape Analysis
Computer Science Fundamentals PART 05

IL and the JIT Compiler: Tiered Compilation, Dynamic PGO, Inlining and Escape Analysis

The JIT does not compile a method once but in tiers: first unoptimized Tier0, then an instrumented copy, finally a Tier1 optimized with the collected profile. With Bookstore code and DOTNET_JitDisasm output we show IL's stack-based form, OSR, Dynamic PGO turning an interface call into direct code behind a type check, bounds check elimination and .NET 10's escape analysis taking a 40-byte allocation down to zero, and compare it with V8's hidden classes and deoptimization.

15 Nov 2026 19 min 12
Semantic Analysis and Code Generation: Type Checking, Symbol Tables and Compiling an AST to Expression Trees
Computer Science Fundamentals PART 04

Semantic Analysis and Code Generation: Type Checking, Symbol Tables and Compiling an AST to Expression Trees

Semantic analysis binds the names in a parsed tree to a symbol table and checks types, so a mistake like price = "abc" is caught before the filter touches any book. For the Bookstore filter language we write a binder with implicit conversion and constant folding, compile the verified tree to Expression<Func<Book,bool>>, run it in memory and use ToQueryString to show EF Core turning it into parameterized SQL; we also see why an input length limit is needed and what Roslyn does.

15 Nov 2026 16 min 11
Parsers and ASTs: Recursive Descent, Operator Precedence and Pratt Parsing
Computer Science Fundamentals PART 03

Parsers and ASTs: Recursive Descent, Operator Precedence and Pratt Parsing

A parser turns tokens into a single AST following precedence and associativity rules; Pratt parsing keeps those rules in a binding power table instead of a chain of methods. For the Bookstore filter language we derive a recursive descent parser from the grammar, write the same language with a Pratt parser and test that both build the same tree, report several errors at once with panic mode, and run the AST with a tree-walking interpreter.

15 Nov 2026 15 min 11
Writing a Lexer: From Characters to Tokens with a Bookstore Filter Language in C#
Computer Science Fundamentals PART 02

Writing a Lexer: From Characters to Tokens with a Bookstore Filter Language in C#

A lexer is a state machine that splits characters into tokens and knows the line and column of each one. We write a single-pass C# lexer over ReadOnlySpan<char> for the Bookstore filter language: maximal munch, keyword matching that survives the Turkish culture, number parsing with InvariantCulture, error recovery that respects surrogate pairs, and clear error messages. Real output shows where a regex lexer breaks and why Roslyn keeps whitespace as trivia.

15 Nov 2026 14 min 9
Blog Map