MoreRSS

site iconThe Practical DeveloperModify

A constructive and inclusive social network for software developers.
Please copy the RSS to your reader, or quickly subscribe to:

Inoreader Feedly Follow Feedbin Local Reader

Rss preview of Blog of The Practical Developer

Is JAVA 100% Object Oriented Programming Language?

2026-03-06 02:49:30

Is Java 100% Object-Oriented?

No, Java is not a 100% Object-Oriented Programming language.

Why Java is Not 100% OOP

Primitive data types
Static variables and methods
Static main() method

1. Primitive Data Types

Java has primitive types like int, char, boolean, and double.
These are not objects.

eg: int x= 10;
If Java were completely object-oriented, numbers would be objects like this:

Integer x = new Integer(10);
2. Static Members

Java has static variables and methods.
They belong to the class, not to objects.
They can be used without creating an object.

3. Static main() Method

The program starts from the main method, which is static.
public static void main(String[] args)
So the JVM can run the program without creating an object.

Strategic AI: AI Is a Capability, Not a Product Strategy- Lessons from Jurassic Park.

2026-03-06 02:49:02

It's been 32 years since a movie was released that changed movie making forever. 1993’s Jurassic Park used pioneering computer-generated imagery (CGI) to bring dinosaurs to life in Steven Spielberg’s adaption of the novel of the same name.

It revolutionized movie making with groundbreaking CGI.
Yet in a 2 hour movie, dinosaurs appeared for only for around 20 minutes, the movie featured only about 6 minutes of full CGI-rendered dinosaurs in the final film.

The rest? Well crafted storytelling, unique characters, and movie making with top notch sound effects that created suspense with basic movements, clicks and vibration effects, which also ushered new sound technology.

All movie theaters had their sound system upgraded just to play this one movie.

But beyond all that Spielberg understood that technology serves the story, not the other way around.

This offers a powerful lesson for AI integration today.

The most successful AI-enabled products won't be those that maximize AI usage, but those that deploy it strategically.

The core benefits of AI happen when AI enhances the core experience without overwhelming it.

Just as Jurassic Park's impact came from knowing when to show the dinosaurs and when to build suspense.

The best products will win the market from understanding when AI genuinely adds value and when traditional approaches work better.

The products or business that will dominate the market are not the one that are "all AI, all the time," but to those that will embed AI experience seamlessly into experiences that remains fundamentally human-centered.

What's the best example you've seen of AI being used as a tool to enhance the Product experience rather than the main show?

This Month in Solid: The Road to 2.0 is here, SolidStart 1.3.0 release 😎

2026-03-06 02:42:48

Hello friends 👋

Long time no see! We're back, and this time, we'll recap what you might have missed from January to February. Plus, there's an obvious tease about something dropped this week that you definitely shouldn't miss.

So, let’s kick off a new edition of This Month in Solid 😎!

Solid Updates

The Road to 2.0

We have been on the road for 2.0 for a while, and I know we are all very excited. Earlier in February, Ryan started a discussion on GitHub, sharing some of the features being worked on, and here are some of them:

  • Fine-grained non-nullable async
  • Mutable derivations
  • Derived signals
  • Lazy memos
  • Automatic batching
  • Immutable Diffable stores
  • Self-Healing ErrorBoundaries
  • Concurrent transitions

You can read more about it here:
github.com/solidjs/solid/discussions/2425

P.S. I know that, at the time of releasing this post, the Beta is out, but technically, it was released in March. I will talk more about that next month, but either way, go check it out: v2.0.0 Beta - The <Suspense> is Over

SolidStart v1.3.0 release

As we were ready to wrap up the month, Atila shared on Discord about a new version of SolidStart. There are a couple of dependency updates and patches there, but it also includes a new feature that will be the default on v2:

It adds JSON mode for seroval

So as of this version, you can opt to use regular JSON serializer. As a tradeoff, payload will be a bit larger and serialization can be slower. But this allows for stronger CSPs as eval() is not used as a custom serializer anymore.

Check it out here: github.com/solidjs/solid-start/releases/tag/%40solidjs%2Fstart%401.3.0

Ecosystem Updates

Found Online

Things to look out for

Atila will be speaking at JNation

This May 26th, Atila will be delivering his talk (Re)building a Framework: Lessons, Community, and Impostor Syndrome at JNation in Coimbra, Portugal.

You can get tickets here: jnation.pt/#tickets

Wrapping up

And, with that, we wrapped up This Month in Solid. I hope you enjoyed it and found it helpful. Let me know if you have feedback or feel I missed anything!

Another resource to keep updated with the Solid World is our Discord. You can join here: discord.com/invite/solidjs

Finally, I want to thank my friend Darko for the support and for reviewing this!

See you all next month 😎

Why Most Data Projects Fail Before the First Model Is Built

2026-03-06 02:40:51

Many organizations invest in AI, analytics, and dashboards — yet most data projects fail before the first model is even built.

When people think about data projects, they often imagine machine learning models, predictive algorithms, and complex pipelines.

But in reality, most data initiatives fail long before any model is trained.

Not because the algorithms are weak.

But because the foundation is broken.

The Data Illusion

Organizations today generate enormous amounts of data.

They store logs, transactions, operational records, and performance metrics.

On paper, everything looks ready for analytics.

But when teams actually start working with the data, they quickly encounter problems:

  • Missing values
  • Inconsistent formats
  • Conflicting sources
  • Undefined metrics
  • Poor documentation

Suddenly, the project shifts from analysis to data archaeology.

Data Science Starts with Data Reliability

Before any meaningful analysis can begin, teams must answer fundamental questions:

  • What is the source of truth?
  • Who owns the dataset?
  • How frequently is it updated?
  • What transformations are applied?
  • Are definitions consistent across departments?

Without clear answers, even the most advanced models produce misleading insights.

The Hidden Cost of Poor Data Foundations

Many organizations invest heavily in analytics tools, dashboards, and AI platforms.

But without strong data foundations, these investments create an illusion of intelligence.

Dashboards become visually impressive but operationally misleading.

Models generate predictions, but the inputs themselves are unstable.

This leads to one of the most dangerous outcomes in data work:

False confidence.

Decisions start relying on numbers that appear precise but are fundamentally unreliable.

Data Engineering Is the Real Backbone

In practice, the majority of effort in data projects is not modeling.

It is:

  • Data cleaning
  • Validation
  • Schema alignment
  • Pipeline reliability
  • Monitoring data quality

That is why experienced teams often say:

“80% of data science is data preparation.”

And the better the data infrastructure, the faster meaningful insights appear.

A Simple Rule for Data Teams

Before building any model, ask three questions:

  1. Is the data trustworthy?
  2. Is the definition of the metric consistent?
  3. Can the pipeline reproduce the same dataset tomorrow?

If the answer to any of these is unclear, the problem is not analytical.

It is architectural.

Final Thought

Good data teams do not start with models.

They start with reliability.

Because in data systems, accuracy is not created by algorithms.

It is created by architecture.

If you're interested in systems thinking, data architecture, and enterprise optimization, feel free to connect.

LinkedIn: https://www.linkedin.com/in/fadydesokysaeedabdelaziz

GitHub: https://github.com/fadydesoky

SQLite’s Flexible Typing: Storage Types and Column Affinity

2026-03-06 02:34:50

Hello, I'm Maneshwar. I'm working on git-lrc: a Git hook for Checking AI generated code.

In the previous post, we discussed datatype management inside SQLite’s Virtual Machine (VM) and how the VM is responsible for assigning storage types and performing conversions. Today we take a deeper look at two key concepts that make SQLite unique among database systems:

  • Storage type determination
  • Column affinity determination

Together, these explain why SQLite is often described as “typeless” and how it still manages to remain compatible with traditional SQL databases.

Storage Type Determination

SQLite is frequently described as a typeless database engine. This means it does not enforce strict domain constraints on table columns.

In most cases, any type of value can be stored in any column, regardless of the column’s declared SQL type.

There is one notable exception: the INTEGER PRIMARY KEY column (the rowid). This column can only store integer values. If the VM encounters a value that cannot be interpreted as an integer for this column, the insertion is rejected.

SQLite even allows tables to be created without specifying column types at all:

CREATE TABLE T1(a, b, c);

Since there is no strict typing requirement, the question becomes:
How does SQLite decide what storage type a value should have?

The VM determines the initial storage type based on how the value enters the system.

1. Values Specified as SQL Literals

When a value appears directly in an SQL statement, SQLite determines its storage type according to its syntax.

Examples:

  • TEXT Values enclosed in quotes are interpreted as strings.
INSERT INTO t1 VALUES('hello');
  • INTEGER Unquoted numbers without a decimal point or exponent.
INSERT INTO t1 VALUES(123);
  • REAL Numbers containing a decimal point or exponent.
INSERT INTO t1 VALUES(3.14);
INSERT INTO t1 VALUES(2e5);
  • NULL
INSERT INTO t1 VALUES(NULL);
  • BLOB
INSERT INTO t1 VALUES(X'ABCD');

In this notation, the hexadecimal digits define the raw byte sequence stored in the database.

If a value does not match any of these patterns, the VM rejects it and query execution fails.

image

2. Values Bound Through API Functions

Values can also enter SQLite through parameter binding using the sqlite3_bind_* API family.

For example:

sqlite3_bind_int(...)
sqlite3_bind_text(...)
sqlite3_bind_blob(...)

Each binding function explicitly determines the storage type:

  • sqlite3_bind_int → INTEGER
  • sqlite3_bind_double → REAL
  • sqlite3_bind_text → TEXT
  • sqlite3_bind_blob → BLOB

In this case, SQLite simply uses the storage type closest to the native type provided by the application.

Expression Result Types

Values produced during query execution such as results of expressions or function calls do not have predetermined types during statement preparation.

Instead, their storage types are determined at runtime.

For example:

SELECT 10 + '20';

The VM evaluates the expression and assigns a storage type based on the operator and the computed result.

Similarly, user-defined SQL functions may return values with any storage type.

Column Affinity Determination

Although SQLite is typeless, it still tries to remain compatible with traditional SQL databases that use static typing.

To achieve this, SQLite introduces the concept of column affinity.

Column affinity is not a strict rule, but rather a recommendation about the preferred storage type for values stored in a column.

In other words:

The column’s declared type influences how SQLite tries to convert values, but it does not strictly restrict them.

Each column belongs to one of five affinity categories:

  • TEXT
  • NUMERIC
  • INTEGER
  • REAL
  • NONE

Note that some names (TEXT, INTEGER, REAL) are also used as storage types internally. Context determines whether we are referring to affinity or storage type.

How SQLite Determines Column Affinity

SQLite determines column affinity by inspecting the declared SQL type in the CREATE TABLE statement.

The VM checks the declaration using the following rules, evaluated in order:

1. INTEGER affinity

If the declared type contains the substring INT, the column receives INTEGER affinity.

Examples:

INT
INTEGER
BIGINT
SMALLINT

2. TEXT affinity

If the declared type contains CHAR, CLOB, or TEXT, the column receives TEXT affinity.

Examples:

CHAR
VARCHAR
TEXT
CLOB

Note that VARCHAR contains the substring CHAR, so it also maps to TEXT affinity.

3. NONE affinity

If the declared type contains BLOB, or if no type is specified, the column receives NONE affinity.

Examples:

BLOB
CREATE TABLE t1(a);

4. REAL affinity

If the declared type contains REAL, FLOA, or DOUB, the column receives REAL affinity.

Examples:

REAL
FLOAT
DOUBLE
DOUBLE PRECISION

5. NUMERIC affinity

If none of the previous rules match, the column receives NUMERIC affinity.

Examples:

DECIMAL
BOOLEAN
DATE
NUMERIC

Order of Evaluation Matters

SQLite applies these rules in order, and the pattern matching is case-insensitive.

For example:

BLOBINT

Even though it contains the substring BLOB, the substring INT appears earlier in the rule list. Therefore, the column receives INTEGER affinity, not NONE.

SQLite is intentionally forgiving—even misspelled type declarations still map to some affinity.

CREATE TABLE AS SELECT

Another interesting case occurs when tables are created using:

CREATE TABLE new_table AS SELECT ...

In this case:

  • The declared type of each column is derived from the affinity of the expression in the SELECT clause.
  • Default values for these columns are NULL.
  • The implicit rowid column always has INTEGER type and cannot be NULL.

What’s Coming Next

Now that we understand:

  • How SQLite assigns storage types
  • How it determines column affinity

we can finally examine how these rules interact during query execution.

In the next post, we’ll walk through data conversion with a simple example and see how the VM dynamically converts values when evaluating SQL expressions.

git-lrc

AI agents write code fast. They also silently remove logic, change behavior, and introduce bugs -- without telling you. You often find out in production.
git-lrc fixes this. It hooks into git commit and reviews every diff before it lands. 60-second setup. Completely free.

Any feedback or contributors are welcome! It’s online, source-available, and ready for anyone to use.
⭐ Star it on GitHub:

GitHub logo HexmosTech / git-lrc

Free, Unlimited AI Code Reviews That Run on Commit

git-lrc logo

git-lrc

Free, Unlimited AI Code Reviews That Run on Commit


git-lrc - Free, unlimited AI code reviews that run on commit | Product Hunt

AI agents write code fast. They also silently remove logic, change behavior, and introduce bugs -- without telling you. You often find out in production.

git-lrc fixes this. It hooks into git commit and reviews every diff before it lands. 60-second setup. Completely free.

See It In Action

See git-lrc catch serious security issues such as leaked credentials, expensive cloud operations, and sensitive material in log statements

git-lrc-intro-60s.mp4

Why

  • 🤖 AI agents silently break things. Code removed. Logic changed. Edge cases gone. You won't notice until production.
  • 🔍 Catch it before it ships. AI-powered inline comments show you exactly what changed and what looks wrong.
  • 🔁 Build a habit, ship better code. Regular review → fewer bugs → more robust code → better results in your team.
  • 🔗 Why git? Git is universal. Every editor, every IDE, every AI…




How to Deploy n8n on Google Cloud for Free (Forever)

2026-03-06 02:31:44

Run n8n workflow automation 100% free on Google Cloud using a permanent free-tier e2-micro VM, Neon PostgreSQL, and Nginx with SSL. No credit card charges, no expiry — ever.

What Is n8n and Why Host It Yourself?

n8n is one of the most powerful open-source workflow automation tools available today. Think Zapier or Make — but self-hosted, with no per-task pricing and no artificial limits on workflows.

The problem? Most people pay €8–20/month to host it on Railway, Render, or a VPS. This guide shows you exactly how to run n8n on Google Cloud Platform's Always Free tier at zero cost, forever.

What You'll Need

  • A Google Cloud account (credit card required for verification, but you will NOT be charged)
  • A domain name (e.g., n8n.yourdomain.com)
  • A Neon account — free at neon.tech, no credit card needed
  • A GitHub account — for automated workflow backups
  • Google Cloud CLI (gcloud) installed on your local machine

Why Google Cloud Free Tier Works for n8n

Google Cloud's Always Free tier includes a permanently free e2-micro VM. Unlike AWS Free Tier which expires after 12 months, GCP's Always Free resources never expire.

Here's what's included free forever:

  • 1 e2-micro VM in us-east1, us-central1, or us-west1
  • 30 GB standard persistent disk (pd-standard)
  • 1 GB egress per month to North America
  • Free external IP on the e2-micro instance

The e2-micro has 1 shared vCPU and 1GB RAM. With swap space added, this handles n8n comfortably for personal use and small teams running up to 150–200 workflows per day.

Note: GCP will show an estimated cost of ~$7/month in the billing console. This is normal — the Always Free credit is applied automatically and your actual invoice will be $0.00.

Step 1 — Create the GCP VM

Run this command in your terminal (with gcloud CLI installed and authenticated):

gcloud compute instances create n8n-server \
  --machine-type=e2-micro \
  --zone=us-east1-b \
  --image-family=ubuntu-2204-lts \
  --image-project=ubuntu-os-cloud \
  --boot-disk-size=30GB \
  --boot-disk-type=pd-standard \
  --tags=http-server,https-server

Why these specific settings matter:

  • us-east1-b — One of three regions eligible for Always Free
  • pd-standard — Must specify standard disk, not pd-balanced (which is NOT free)
  • 30GB — Use the full free allowance
  • tags — Required for firewall rules later

SSH into the server:

gcloud compute ssh n8n-server --zone=us-east1-b

Press Enter twice when asked for a passphrase to generate SSH keys automatically.

Step 2 — Install Docker

sudo apt update && sudo apt upgrade -y
curl -fsSL https://get.docker.com | sudo sh
sudo usermod -aG docker $USER && newgrp docker
docker --version

Step 3 — Set Up Neon PostgreSQL (Free Database)

n8n requires a PostgreSQL database. We'll use Neon's free tier instead of running a local Postgres container, which saves precious RAM on the e2-micro VM.

Go to neon.tech and create a free account. Then:

  1. Create a new project
  2. Select AWS us-east-1 region (closest to GCP us-east1)
  3. Copy your direct connection string

In the Neon dashboard, configure compute settings:

  • Set compute size to 0.25 CU (minimum)
  • Set Scale to zero: 5 minutes so Neon sleeps when n8n is idle

This keeps you well within Neon's 100 compute unit-hours/month free limit.

Your connection string will look like:

postgresql://user:[email protected]/neondb?sslmode=require

Step 4 — Deploy n8n with Docker Compose

On your GCP server:

mkdir n8n && cd n8n
nano docker-compose.yml

Paste this configuration (replace with your actual Neon credentials):

services:
  n8n:
    image: n8nio/n8n
    restart: always
    ports:
      - "5678:5678"
    environment:
      - DB_TYPE=postgresdb
      - DB_POSTGRESDB_HOST=ep-xxxx.us-east-1.aws.neon.tech
      - DB_POSTGRESDB_PORT=5432
      - DB_POSTGRESDB_DATABASE=neondb
      - DB_POSTGRESDB_USER=your_user
      - DB_POSTGRESDB_PASSWORD=your_password
      - DB_POSTGRESDB_SSL_REJECT_UNAUTHORIZED=false
      - N8N_HOST=n8n.yourdomain.com
      - N8N_PORT=5678
      - N8N_PROTOCOL=https
      - N8N_ENCRYPTION_KEY=your_32_char_random_key
      - EXECUTIONS_DATA_PRUNE=true
      - EXECUTIONS_DATA_MAX_AGE=168
    volumes:
      - n8n_data:/home/node/.n8n

volumes:
  n8n_data:

Save with Ctrl+XY → Enter, then start n8n:

docker compose up -d

The first run downloads the n8n image (~280MB) which takes 5–7 minutes.

Important: EXECUTIONS_DATA_PRUNE=true keeps the database lean by deleting execution history older than 168 hours (7 days). This is critical for staying within Neon's 500MB free storage limit. N8N_ENCRYPTION_KEY encrypts your saved credentials — set this to a random 32-character string and keep it safe.

Step 5 — Set Up Nginx Reverse Proxy

Install Nginx and Certbot:

sudo apt install nginx certbot python3-certbot-nginx -y

Create the n8n Nginx config:

sudo nano /etc/nginx/sites-available/n8n

Paste:

server {
    listen 80;
    server_name n8n.yourdomain.com;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    server_name n8n.yourdomain.com;

    ssl_certificate /etc/letsencrypt/live/n8n.yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/n8n.yourdomain.com/privkey.pem;

    location / {
        proxy_pass http://localhost:5678;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        chunked_transfer_encoding off;
    }
}

Enable it:

sudo ln -s /etc/nginx/sites-available/n8n /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl restart nginx

Step 6 — Open Firewall Ports and Add SSL

Run these on your local machine (not the server):

gcloud compute firewall-rules create allow-http \
  --allow tcp:80 --target-tags http-server

gcloud compute firewall-rules create allow-https \
  --allow tcp:443 --target-tags https-server

Then on the server, get your free SSL certificate:

sudo certbot --nginx -d n8n.yourdomain.com

Certbot automatically configures Nginx for HTTPS and sets up auto-renewal every 90 days.

Step 7 — Connect Your Domain

Add a DNS A record at your domain registrar or Cloudflare:

Field Value
Type A
Name n8n
Value Your GCP external IP
TTL 300

If using Cloudflare, set proxy to DNS only (grey cloud) initially. After SSL is working, switch to orange cloud with SSL/TLS mode set to Full.

Step 8 — Optimize Performance (Swap Space)

The e2-micro only has 1GB RAM. Adding swap makes a huge difference:

sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

This gives your server an effective 3GB of memory using free disk space. It's the single biggest performance improvement you can make on this setup.

Step 9 — Set Up Automatic GitHub Backups

Don't lose your workflows. Set up a monthly automated backup to GitHub.

First, create a GitHub repo and a fine-grained personal access token with Contents: Read and Write permission.

Set up git on the server:

mkdir -p ~/backup && cd ~/backup
git init
git remote add origin https://YOUR_USERNAME:[email protected]/YOUR_USERNAME/n8n-backup.git
git pull origin main

Add the cron job:

crontab -e

Add this line (runs at 2am on the 1st of every month):

0 2 1 * * docker exec n8n-n8n-1 n8n export:workflow --backup --output /home/node/.n8n/backup/workflows/ && docker exec n8n-n8n-1 n8n export:credentials --backup --output /home/node/.n8n/backup/credentials/ && docker cp n8n-n8n-1:/home/node/.n8n/backup /home/YOUR_USER/backup/ && git -C /home/YOUR_USER/backup add . && git -C /home/YOUR_USER/backup commit -m "Auto backup $(date +%F)" && git -C /home/YOUR_USER/backup push

For a manual backup anytime:

docker exec n8n-n8n-1 n8n export:workflow --backup --output /home/node/.n8n/backup/workflows/ && git -C ~/backup add . && git -C ~/backup commit -m "Manual backup $(date +%F)" && git -C ~/backup push

How to Update n8n in One Command

cd ~/n8n && docker compose pull && docker compose up -d

Run this monthly to stay current with security patches and new features.

How to Migrate from an Existing n8n Instance

On your old instance, export everything:

docker exec YOUR_OLD_CONTAINER n8n export:workflow --backup --output /home/node/.n8n/backup/workflows/
docker exec YOUR_OLD_CONTAINER n8n export:credentials --backup --output /home/node/.n8n/backup/credentials/

Copy your old N8N_ENCRYPTION_KEY to your new instance's docker-compose.yml — this ensures credentials decrypt correctly on the new server. Then import:

docker exec n8n-n8n-1 n8n import:workflow --separate --input=/path/to/workflows/
docker exec n8n-n8n-1 n8n import:credentials --separate --input=/path/to/credentials/

Frequently Asked Questions

Will Google ever charge me?
As long as you use one e2-micro VM with a 30GB pd-standard disk in an eligible region, Google will not charge you. The Always Free tier does not expire.

Is 1GB RAM enough for n8n?
Yes, for personal use and small teams. With 2GB swap added, you get an effective 3GB. n8n at idle uses 400–600MB RAM. Running 2–3 workflows simultaneously is comfortable.

Is Neon's 500MB storage enough?
Yes. With execution history pruning enabled, a typical personal n8n instance stays well under 100MB. You'd need hundreds of thousands of workflow runs to approach the limit.

Can I use this commercially?
n8n's self-hosted version is free for personal and small-team use under the Sustainable Use License. GCP's free tier has no restrictions on what you run on it.

What if I need more power later?
Upgrade the GCP VM to e2-small or e2-medium (paid, ~$15–30/month) while keeping everything else the same. No migration needed — just change the machine type in GCP console.

Summary — What You've Built

Component Solution Cost
Compute GCP e2-micro (us-east1) Free forever
Storage 30GB pd-standard disk Free forever
Database Neon PostgreSQL 500MB Free forever
SSL Let's Encrypt via Certbot Free forever
Backups GitHub repository Free forever
Total €0.00/month

You're saving €8–20/month compared to managed n8n hosting — that's up to €240/year back in your pocket, running the exact same software.

Found this guide helpful? Share it with other n8n users who are tired of paying for hosting they don't need.

Connect with me https://x.com/DesiRichDev/
Check My Projects https://dev.businesskit.io/