Skip to main content

Implementing Vector Embeddings and Semantic Search in Pure Java

A complete implementation of a semantic search engine in pure Java — no external libraries. Covers TF-IDF vectorisation, cosine similarity, and document ranking by meaning. Explains the mathematics behind vector embeddings, how they power RAG and AI search systems, and provides a working query engine with annotated code and sample output. The same architecture used by Pinecone, Weaviate, and Elasticsearch — built from scratch.

Building a Neural Network from Scratch in Pure Java (No Libraries)

A complete, from-scratch implementation of a feedforward neural network in pure Java — no TensorFlow, no DL4J, no external libraries. Covers the Neuron model, forward propagation, sigmoid activation, backpropagation with gradient descent, and trains the network to learn the XOR function. Every line of code is annotated with the underlying mathematics so you understand exactly what the network is doing at each step.

Building a REST API with Spring Boot: Complete Beginner's Guide

A complete beginner's guide to building a REST API with Spring Boot 3. Covers project setup, clean package structure, a Java record model with Bean Validation, a service layer, a @RestController with GET/POST/PUT/DELETE endpoints, global exception handling with @RestControllerAdvice, and end-to-end curl testing u2014 with fully annotated code throughout.

Java Collections Framework: Choosing the Right Data Structure

A complete, reference-level guide to the Java Collections Framework. Covers ArrayList vs LinkedList, HashSet vs LinkedHashSet vs TreeSet, HashMap vs LinkedHashMap vs TreeMap, PriorityQueue, ArrayDeque, and immutable collections u2014 with time-complexity tables, annotated code examples, and a decision guide for choosing the right data structure.

Java Streams API: The Complete Reference Guide

A complete, reference-level guide to the Java Streams API (Java 8+). Covers stream creation, intermediate operations (filter, map, flatMap, sorted, distinct, peek), terminal operations (collect, reduce, count, findAny, anyMatch), collectors, parallel streams, and the most common pitfalls u2014 with fully annotated code and sample output for every example.

8086 Assembly: Handling the External Timer Interrupt (INT 08h)

A complete guide to handling the 8086 external timer interrupt INT 08h. Covers the interrupt vector table, how the CPU dispatches interrupts, saving and restoring the original BIOS handler, writing a far ISR that increments a tick counter, chains correctly, and exits safely — with a common-mistakes table.

8086 Assembly: PUSH, POP, CALL, and RET – Stack Operations Explained

A complete guide to 8086 assembly stack operations. Covers how the stack works (SP, SS, LIFO), what PUSH and POP do to memory, how CALL saves a return address and RET retrieves it, and a fully annotated working program that demonstrates all four instructions together.

Jackson Custom Serialisers, Deserialisers, and Mix-in Annotations: The Advanced Toolkit

There are two scenarios where Jackson’s built-in annotations are not enough: when you need to control exactly how a complex type is serialised, and when the class you need to annotate belongs to a third-party library whose source you cannot modify. For the first case, Jackson provides custom serialisers and deserialisers. For the second, it provides Mix-in Annotations — a mechanism that lets you attach annotations to any class without touching its source. Runnable code: every example below is in the jackson3-by-example repository, compiled and executed against Jackson 3.2.1 on JDK 21 — E01 the serialiser, E02 the deserialiser, E03 module registration, E04 mix-ins and E05 ValueSerializer, with captured output in docs/part4-custom.md. This is the area with the most API churn between Jackson 2 and Jackson 3, so the renames are worth having in one place before the code: JsonSerializer → ValueSerializer, JsonDeserializer → ValueDeserializer, SerializerProvider → SerializationContext, writeNumberField/writeStringField → writeNumberProperty/writeStringProperty, parser.getCodec().readTree(parser) → ctxt.readTree(parser), mapper.registerModule(m) → builder.addModule(m), mapper.addMixIn(a, b) → builder.addMixIn(a, b), and every throws IOException deleted. StdSerializer and StdDeserializer keep their names but move to tools.jackson.databind. Writing a Custom Serialiser Extend StdSerializer<T> and override serialize(). The method receives the value to write and a JsonGenerator you use to emit JSON tokens. Suppose you have a Money type that should serialise as a structured JSON object containing the amount and the currency code: public class Money { private final BigDecimal amount; private final String currencyCode; // Constructor and getters }

Jackson Annotations Cheat Sheet: Every Annotation You Need With Examples

Jackson annotations give you precise control over how your Java objects map to JSON and back. Rather than relying solely on field names, you can rename properties, ignore specific fields, handle nulls, format dates, and much more — all without writing a single custom serialiser. This guide covers every annotation you will encounter in real projects, with concrete examples for each. Runnable code: every annotation below is exercised in the jackson3-by-example repository, compiled and executed against Jackson 3.2.1 on JDK 21 — D01 @JsonProperty and @JsonIgnore, D02 @JsonInclude and @JsonFormat, D03 @JsonAlias and unknown fields and D04 @JsonCreator, @JsonUnwrapped and @JsonAnyGetter, with captured output in docs/part3-annotations.md. One import note before the list: every @Json* annotation still comes from com.fasterxml.jackson.annotation, even on Jackson 3. jackson-annotations deliberately kept the old group ID and package so a single copy can serve Jackson 2 and Jackson 3 code on the same classpath — so annotated DTOs need no changes at all during a migration. @JsonProperty — Rename a Field in JSON Use @JsonProperty when the JSON key must differ from the Java field name — for example, when consuming a third-party API that uses snake_case. public class OrderSummary { @JsonProperty("order_id") // JSON key: order_id private Long orderId; @JsonProperty("customer_name") // JSON key: customer_name private String customerName; // Getters and setters } // Serialise {"order_id":1001,"customer_name":"Alice"} // Deserialise: JSON with "order_id" maps correctly to the orderId field