Colloquio Tecnico Backend — Cheat Sheet

Tag: backend, nodejs, sql, rest, system-design, api, database, microservices

Livello: intermedio

TL;DR: Sintesi rapida su architetture server-side, gestione concorrenza, database SQL/NoSQL, transazioni ACID, sicurezza API e strategie di scalabilita' per colloqui backend.

Concetti chiave

Pattern architetturali: differenze pratiche tra monolite modulare, SOA e microservizi con pattern API Gateway.

Comunicazione di rete: protocolli sincroni (REST HTTP/2, gRPC Protobuf) e asincroni basati su broker ad eventi (RabbitMQ, Kafka).

Event Loop in Node.js: runtime single-thread con offload I/O asincrono tramite thread pool di libuv.

Modello ACID relazionale: isolamento delle transazioni e prevenzione di anomalie come dirty read o phantom read.

Teorema CAP: trade-off obbligato nei sistemi distribuiti tra Consistency, Availability e Partition Tolerance.

Strategie di persistenza: separazione netta tra OLTP per operazioni transazionali e OLAP per analisi e reporting.

Meccanismi di caching: pattern Cache-Aside e Write-Through con policy di invalidazione ed evizione (LRU).

Controllo del traffico: algoritmi di rate limiting (Token Bucket, Leaky Bucket) e pattern Circuit Breaker.

Gestione della consistenza distribuita: pattern SAGA (orchestrata vs coreografata) e transazioni compensative.

Autenticazione e sicurezza: stateless JWT, token blacklist distribuita, RBAC e sanitize contro injection e IDOR.

Domande tipiche e risposte pronte

Q: Come gestisci l'ottimizzazione di una query SQL lenta in produzione?R: Analizzo il piano di esecuzione con EXPLAIN ANALYZE, verifico la selettivita' degli indici, elimino le scansioni sequenziali su tabelle massive ed evito problemi N+1 raggruppando o riscrivendo le JOIN.

Q: Quando preferisci la consistenza eventuale rispetto a transazioni distribuite tradizionali?R: La preferisco nei flussi distribuiti ad alto throughput dove un commit a due fasi bloccherebbe le risorse; implemento code di messaggi ed eventi compensativi per allineare lo stato.

Q: In che modo previeni la perdita di eventi critici in un sistema a code asincrone?R: Utilizzo acknowledgment manuali post-elaborazione, consumer idempotenti con deduplicazione su chiave univoca e dead-letter queue con meccanismi di retry backoff per isolare i payload difettosi.

Q: Qual e' la differenza tra scalabilita' verticale e scalabilita' orizzontale in un'applicazione web?R: Scalare verticalmente significa potenziare la CPU e la RAM della singola macchina; scalare orizzontalmente significa distribuire il carico su piu' istanze stateless dietro un bilanciatore.

Q: Come gestisci l'autenticazione stateless scalabile tra molteplici servizi?R: Emetto access token JWT firmati asimmetricamente a breve scadenza per la verifica locale, gestendo la revoca anticipata tramite refresh token persistiti su storage condiviso ad alta velocita'.

Insidie e errori comuni

Il problema delle query N+1 negli ORM, che moltiplica le chiamate I/O al database anziche' usare query batch.

Race condition nell'aggiornamento di bilanci o contatori: dimenticare il locking ottimistico o pessimistico (SELECT FOR UPDATE).

Mancanza di idempotenza negli endpoint POST/PUT, con rischio di doppi addebiti o scritture duplicate sui retry di rete.

Salvare token o segreti di connessione nel repository git invece di usare secrets manager ed environment variables.

Bloccare l'Event Loop con elaborazioni CPU-intensive sincrone (calcoli pesanti, parsing JSON giganti, regex catastrofiche).

Mancata definizione di timeout espliciti sulle connessioni HTTP uscenti e verso database terzi, esaurendo i socket liberi.

Snippet e comandiSQL

```-- Analisi indici e piano di esecuzione query

EXPLAIN ANALYZE

SELECT u.id, u.email, COUNT(o.id) AS total_orders

FROM users u

LEFT JOIN orders o ON o.user_id = u.id

WHERE u.created_at >= '2026-01-01'

GROUP BY u.id, u.email;

// Aggiornamento sicuro con lock pessimistico in transazione

await prisma.$transaction(async (tx) => {

const account = await tx.$queryRaw`

SELECT id, balance FROM "Account" WHERE id = ${accountId} FOR UPDATE

`;

if (account.balance < amount) throw new Error("Insufficient funds");

await tx.account.update({

where: { id: accountId },

data: { balance: { decrement: amount } }

});

});

Diagnostica connessioni e carico di rete

ss -s

lsof -i :8080

curl -Iv https://api.service.internal/health

```

Da ripassare

[ ] Implementazione pratica di code e worker idempotenti

[ ] Livelli di isolamento transazionale (Read Committed, Repeatable Read, Serializable)

[ ] Monitoraggio e tracciamento distribuito (OpenTelemetry, metriche RED)

[x] Protocollo HTTP, codici di stato e semantica dei verbi REST

[x] Principi di modellazione relazionale e normalizzazione delle tabelle

Jarvis Interviews
Jarvis