Pinned Tweet
Kafka in plain words:
• Topic: a named stream of messages, like "orders".
• Partition: a topic is split into partitions so it can scale.
• Offset: the position of a message inside a partition.
• Producer: sends messages to a topic.
• Consumer: reads messages from it.
• Consumer group: consumers that share the work. Each partition goes to one consumer in the group.
• Order is guaranteed only inside a partition, not across the whole topic.
• Use a key (like orderId) so related messages land in the same partition.
• Messages stay for a set time, even after they're read.
Once these click, most Kafka docs start making sense.
Does anyone develop Android apps? How do you get 12 testers for closed testing for consecutive 14 days?
You can validate inside a record with a compact constructor:
record Email(String value) {
Email {
if (value == null || !value.contains("@"))
throw new IllegalArgumentException("Invalid email");
}
}
Bad data never gets created.
HTTP status codes people mix up:
• 200 OK: it worked, here's the data
• 201 Created: a new resource was made
• 204 No Content: it worked, nothing to return
• 400 Bad Request: the client sent something wrong
• 401 Unauthorized: we don't know who you are
• 403 Forbidden: we know who you are, but you can't do this
• 404 Not Found: it doesn't exist
• 409 Conflict: it clashes with the current state
• 422 Unprocessable: the format is fine, but the data fails validation
• 500: our fault
Returning 200 with {"error": true} makes everyone's life harder.
API security basics every backend dev should know:
1. HTTPS everywhere.
2. Validate every input. Never trust the client.
3. Use parameterized queries.
4. Check authorization on every endpoint, not just at login.
5. Don't return stack traces in error responses.
6. Keep secrets out of code and Git.
7. Keep access tokens short-lived.
8. Rate limit login and public endpoints.
9. Keep dependencies updated.
10. Read the OWASP Top 10 at least once.
Most breaches don't need a genius hacker. They need one missed check.
Switch expressions (Java 14) can return a value:
String type = switch (day) {
case SATURDAY, SUNDAY -> "Weekend";
default -> "Weekday";
};
No break. No fall-through bugs.
CompletableFuture in a few steps:
var user = CompletableFuture.supplyAsync(() -> userService.get(id));
var orders = CompletableFuture.supplyAsync(() -> orderService.get(id));
Dashboard d = user.thenCombine(orders, Dashboard::new)
.exceptionally(ex -> Dashboard.empty())
.join();
• supplyAsync: run something in the background
• thenApply: transform the result
• thenCombine: merge two results
• exceptionally: handle errors
• join: wait for the final result
• In real apps, pass your own executor
Both calls run at the same time instead of one after the other.
Java concurrency basics in one post:
• Thread: one path of execution.
• synchronized: only one thread runs that block at a time.
• volatile: makes changes visible to other threads. It does NOT make count++ safe.
• AtomicInteger: safe counters without locks.
• ExecutorService: manage threads instead of creating them by hand.
• CompletableFuture: run tasks async and combine the results.
• ConcurrentHashMap: a map many threads can use safely.
• Deadlock: two threads waiting for each other forever.
• Race condition: the result depends on timing.
Most concurrency bugs come from shared data that can change. Share less.
Unit testing habits that made my tests better:
• Name tests by behavior: shouldRejectExpiredCoupon()
• One behavior per test.
• Arrange, act, assert. Keep the three parts easy to see.
• Don't test private methods. Test what the class does.
• Mock only what's slow or what you don't own.
• Use Testcontainers for real database tests instead of H2.
• A test that fails randomly is worse than no test. Fix it or delete it.
• Write a failing test before fixing a bug.
Good tests let you change code without being scared.
If you're learning to code at 30, 35 or 40, you're not late. You're just starting from a different place.
SQL habits every backend dev should have:
• Don't SELECT * in application code. Pick the columns you need.
• Use parameters, never string concatenation. That's how SQL injection happens.
• Paginate big results. OFFSET gets slow on deep pages, so look at keyset pagination.
• Check EXPLAIN for slow queries.
• Index your WHERE and JOIN columns.
• Use a transaction when several writes must succeed together.
• Count with COUNT(*), not by loading rows into Java.
• Learn the NULL rules. NULL = NULL is not true.
You'll write better JPA code once you're good at plain SQL.
Logging habits that make production debugging easier:
• Use the right level. ERROR should mean someone needs to look at it.
• Use placeholders: log. info("Order {} created", id). Not string concatenation.
• Always include IDs: user, order, request.
• Add a correlation ID so you can follow one request everywhere.
• Never log passwords, tokens or card numbers.
• Pass the exception object to the logger, not just e.getMessage().
• Don't log inside tight loops.
• Use structured JSON logs if you have a log platform.
Logs are for future you at 2 AM. Be kind to that person.
Top Tech News of the Week 📻
1. Claude Haiku 5.5 launched on Oct 7 at about 75% lower cost than Haiku 4.5: $0.10 input and $0.50 output per 1M tokens for prompts under 100K, with a 1M context window ✅
2. OpenAI launched GPT-6 with Intelligent UI. ChatGPT can now build charts, forms, buttons and calculators right inside the chat. This is a ChatGPT feature, not a new developer API
3. GPT-6 API prices per 1M tokens (input / output): Astra $10 / $50, Sol $2 / $10, Luna $0.10 / $0.50
4. Anthropic turned off live internet access for all its internal AI tests after Claude models took unplanned actions on real websites. Lesson for devs: always sandbox your agents ‼️
5. Microsoft made Execution Containers (MXC) generally available on Windows 11. You can run AI agents in a controlled space and decide which files and networks they can touch ✅
6. Microsoft announced the Surface Laptop Ultra, starting at $2,600. It supports up to 128GB memory and can run models with 120B+ parameters locally. The RTX Spark Dev Box starts at $6,000
7. Java 27 is out. It shipped on Sept 15 and is a short-term release, supported until March 2027. Java 25 is still the LTS for production. Oracle's free updates for JDK 21 were also planned to end in September 2026
8. Java 28 is already taking shape. Value Objects (preview), a Simple JSON API (incubator) and Shenandoah generational mode by default are targeted for it
9. Indian IT company HCLTech signed a global partnership with Anthropic to help companies use Claude and Claude Code
10. IMF says AI could affect about 40% of jobs worldwide, and entry-level jobs are the biggest worry. This means "affected", not "lost"
11. Apple's "Welcome home" event is today, Oct 13, at 9 AM ET (6:30 PM IST). A smart home hub (about $350, rumored), HomePod mini 2 and Apple TV 4K are expected ✅
12. iPhone Duo (foldable) pre-orders open on Oct 16 and sales start on Oct 23. The US price is $1,999 ✅
13. Google launched the Fitbit Edge at $179.99. It is the first Fitbit with a replaceable battery. Shipping starts Oct 27
14. Smartphone prices in India could rise another 7-10% in the coming months, as memory costs stay high ‼️
15. The newly introduced X Subscription, brings together Grok, Grok Bot, Cursor, and X Premium in one plan.
Is there any other AI coding agent other than Claude Code?
I tried many but somehow keep coming back to Claude Code.
Any workflow or tricks I am missing?
Putting a Java app in Docker? A few things that help:
• Use a multi-stage build. Build with a JDK, run with a smaller JRE image.
• Copy dependencies before your code so Docker can cache that layer.
• Add a .dockerignore so target/ and .git don't get copied in.
• Don't run as root inside the container.
• Modern JVMs know they're in a container and respect its memory limit.
• Use -XX:MaxRAMPercentage=75 instead of a fixed -Xmx.
• Add a health check endpoint.
• Pin your base image version. "latest" will surprise you one day.
Smaller images, faster deploys, fewer random memory kills.
Arrays.asList() looks like a normal list, but it's fixed size.
List<String> list = Arrays.asList("a", "b");
list.set(0, "z"); // works
list.add("c"); // UnsupportedOperationException
Need a real ArrayList? new ArrayList<>(Arrays.asList(...))
Git commands that save me regularly:
• git stash: park your changes for a minute
• git log --oneline --graph: see history clearly
• git reflog: get back "lost" commits
• git commit --amend: fix the last commit
• git restore : throw away local changes
• git switch -c : create and move to a branch
• git cherry-pick : bring over one commit
• git rebase -i HEAD~3: clean up your last few commits
• git blame : find out why a line exists
• git diff --staged: see what you're about to commit
reflog alone has saved me more than once.
