NoSQL and Cassandra Interview Questions and Answers (2026) Interview Questions | JiQuest

add

#

NoSQL and Cassandra Interview Questions and Answers (2026)

BACKEND INTERVIEW PREPARATION
NoSQL and Apache Cassandra
Master 100 NoSQL, CAP theorem and Apache Cassandra interview questions covering data modeling, tunable consistency, ring architecture, CQL and Java integration — for backend and system design interviews at Amazon, Google, Netflix & scale-up startups in 2026.
⏳ 50 min read 📝 100 Q&As 🎯 Beginner to Advanced
⚡ Quick Reference
4 NoSQL TypesKey-Value, Document, Column-family (wide-column), Graph
CAP TheoremPick 2 of 3: Consistency, Availability, Partition tolerance
BASE vs ACIDBASE: Basically Available, Soft state, Eventual consistency (NoSQL) vs ACID (RDBMS)
Partition key vs Clustering keyPartition key decides which node/data stores the row; clustering key sorts rows within a partition
Consistency levelsONE, QUORUM, LOCAL_QUORUM, ALL, EACH_QUORUM — tunable per query
Gossip protocolPeer-to-peer protocol nodes run every second to exchange cluster state — no master node
DynamoDB vs CassandraDynamoDB: fully-managed AWS service; Cassandra: open-source, self-managed, multi-cloud
When to choose NoSQLHigh write throughput, horizontal scale, flexible schema, denormalized access patterns
Cassandra Ring Architecture (Peer-to-Peer, No Master)
Client Application
Coordinator Node (any node — request entry point)
RING OF NODES (consistent hashing by token range)
Node A
Replica 1
Node B
Replica 2
Node C
Replica 3
Node D
(next token range)
Replication Factor (RF) = 3 → data written to 3 nodes gossiped via peer-to-peer protocol. No master, no single point of failure.

1. NoSQL Fundamentals & Types

Q1. What is NoSQL and why was it created?

A: NoSQL ("Not Only SQL") refers to non-relational databases designed for horizontal scalability, flexible schemas, and high write/read throughput on distributed clusters of commodity hardware. It emerged in the late 2000s (Amazon Dynamo, Google Bigtable papers) to solve problems traditional RDBMS struggled with: massive scale, unstructured/semi-structured data, and the need to scale out (add servers) rather than scale up (bigger server).

Q2. What are the four main types of NoSQL databases?

A: Key-Value stores (Redis, DynamoDB) — simplest model, O(1) lookups by key. Document stores (MongoDB, Couchbase) — store semi-structured JSON/BSON documents. Column-family / wide-column stores (Cassandra, HBase) — rows with dynamic columns grouped by column family, optimized for write-heavy workloads. Graph databases (Neo4j, Amazon Neptune) — nodes and edges optimized for traversing relationships.

Q3. What is a key-value store? Give examples.

A: A key-value store maps unique keys to opaque values (blob, string, JSON) with no query language beyond get/put/delete by key. Extremely fast and simple to scale via hashing. Examples: Redis, Memcached, Amazon DynamoDB (also supports secondary indexes), Riak.

SET user:1001 '{"name":"Raj","plan":"pro"}'
GET user:1001
EXPIRE user:1001 3600   # TTL in seconds
DEL user:1001

Q4. What is a document store? Give examples.

A: A document store persists self-describing documents (usually JSON/BSON) that can be nested and vary in structure between records. Supports rich queries on document fields, unlike plain key-value stores. Examples: MongoDB, Couchbase, Amazon DocumentDB, Firestore.

// MongoDB document
{
  "_id": ObjectId("64f1..."),
  "name": "Raj Kumar",
  "skills": ["Java", "Spring", "Cassandra"],
  "address": { "city": "Bengaluru", "zip": "560001" }
}
db.users.find({ "address.city": "Bengaluru" })

Q5. What is a column-family (wide-column) store? Give examples.

A: A wide-column store organizes data into rows identified by a row key, where each row can hold a large, sparse, and dynamic set of columns grouped into column families. Optimized for very high write throughput and range scans over sorted row keys. Examples: Apache Cassandra, Apache HBase, Google Bigtable.

CREATE TABLE sensor_readings (
  sensor_id text,
  reading_time timestamp,
  temperature double,
  PRIMARY KEY (sensor_id, reading_time)
) WITH CLUSTERING ORDER BY (reading_time DESC);

Q6. What is a graph database? Give examples.

A: A graph database stores data as nodes (entities) and edges (relationships), each with properties, and is optimized for traversing deeply connected data (friend-of-friend, recommendation engines, fraud detection). Examples: Neo4j (Cypher query language), Amazon Neptune, ArangoDB. Relational joins for deep traversals are far slower than native graph traversal.

Q7. When would you choose a document store over a key-value store?

A: Choose a document store when you need to query and index on fields INSIDE the value (e.g., "find all users in city=Bengaluru"), not just fetch by primary key. Key-value stores are faster and simpler but only support lookups by the exact key — any querying on the value's content requires reading the app layer or building an external index.

Q8. What is schema-on-read vs schema-on-write?

A: Schema-on-write (RDBMS) validates and enforces a fixed schema at insert time — every row must match the table definition. Schema-on-read (most NoSQL) stores data with minimal upfront structure; the schema/interpretation is applied by the application when reading. This gives flexibility to evolve fields over time without migrations, at the cost of consistency guarantees living in application code.

Q9. What is horizontal scaling (sharding) and how does NoSQL support it?

A: Horizontal scaling adds more commodity machines to a cluster to increase capacity, versus vertical scaling (bigger single machine). Most NoSQL databases are built with sharding/partitioning as a first-class concept — data is automatically distributed across nodes using consistent hashing or range partitioning, and adding nodes redistributes data with minimal manual intervention (unlike traditional RDBMS sharding, which is often bolted on).

Q10. What are the common use cases where NoSQL outperforms relational databases?

A: High-velocity write workloads (IoT sensor data, clickstream/event logging), massive horizontal scale (social graphs, session stores), flexible/evolving schemas (product catalogs), low-latency key lookups at huge scale (user profiles, shopping carts), and time-series data with heavy writes and range scans (Cassandra excels here). RDBMS remains better for complex multi-table joins and strong ACID transactional guarantees.

2. CAP Theorem & BASE

Q11. What is the CAP theorem?

A: The CAP theorem (Eric Brewer, 2000) states that a distributed data store can provide at most 2 of these 3 guarantees simultaneously during a network partition: Consistency (every read gets the most recent write), Availability (every request gets a non-error response), and Partition tolerance (the system continues to operate despite network partitions between nodes).

Q12. Explain Consistency, Availability, Partition tolerance individually.

A: Consistency: all nodes see the same data at the same time (linearizability). Availability: the system always responds to requests, even if some nodes are down. Partition tolerance: the system keeps functioning even if network messages between nodes are lost or delayed. In real distributed systems, network partitions WILL happen, so P is non-negotiable — the real trade-off is between C and A.

Q13. Why can a distributed system only guarantee 2 of the 3 CAP properties?

A: Because network partitions are unavoidable in distributed systems, a design must choose: during a partition, either reject/delay requests to preserve consistency (CP) or keep serving requests with possibly stale data to preserve availability (AP). You cannot have both perfect consistency and full availability while a partition is happening — that combination (CA) only exists in theory for a single, non-partitioned node.

Q14. What is a CP system? Give an example.

A: A CP (Consistent + Partition-tolerant) system sacrifices availability during a partition — it may return errors or time out rather than serve stale/conflicting data. Examples: HBase, MongoDB (with majority write concern), ZooKeeper, and traditional RDBMS in a replicated setup with synchronous replication.

Q15. What is an AP system? Give an example.

A: An AP (Available + Partition-tolerant) system keeps serving reads/writes during a partition, accepting that some nodes may return stale data temporarily (eventual consistency). Examples: Cassandra (by default), DynamoDB, CouchDB, Riak. These reconcile conflicting writes later via mechanisms like read repair, vector clocks, or last-write-wins.

Q16. Is Cassandra CP or AP?

A: Cassandra is fundamentally AP by design (masterless, always-writable), but it offers tunable consistency per query — by choosing consistency levels like QUORUM for both reads and writes, you can achieve strong (CP-like) consistency for specific operations while the cluster overall remains highly available. This flexibility is one of Cassandra's key differentiators.

Q17. What is BASE and how does it differ from ACID?

A: BASE (Basically Available, Soft state, Eventual consistency) is the consistency model favored by many NoSQL/AP systems, prioritizing availability and partition tolerance over immediate consistency. ACID (Atomicity, Consistency, Isolation, Durability) is the RDBMS model prioritizing strict transactional correctness. BASE trades strict consistency for scalability and uptime; ACID trades some scalability for correctness guarantees.

Q18. What is eventual consistency?

A: Eventual consistency guarantees that, given no new updates, all replicas of a piece of data will converge to the same value eventually — but at any given instant different replicas might return different (stale) values. It is achieved through background processes like read repair, anti-entropy repair, and hinted handoff in systems like Cassandra and DynamoDB.

Q19. What is the PACELC theorem and how does it extend CAP?

A: PACELC (Daniel Abadi) extends CAP: "if there is a Partition (P), trade off Availability and Consistency (A/C); Else (E), even with no partition, trade off Latency and Consistency (L/C)." It captures that even in normal operation (no partition), systems must trade consistency for lower latency — Cassandra is PA/EL (available & low-latency), while systems like Spanner lean toward PC/EC.

Q20. How does network partition tolerance affect design decisions?

A: Since partitions are inevitable at scale, architects must explicitly decide what happens when nodes can't communicate: reject writes (favor consistency) or accept them and reconcile later (favor availability). This decision drives replication strategy, consistency level defaults, conflict resolution (last-write-wins, vector clocks, CRDTs), and client retry/timeout behavior.

3. SQL vs NoSQL Trade-offs

Q21. What are the fundamental differences between SQL and NoSQL databases?

A: SQL/RDBMS: fixed schema, normalized tables, powerful JOINs, strong ACID transactions, vertical scaling historically. NoSQL: flexible/dynamic schema, denormalized data modeled around queries, limited or no joins, tunable consistency, designed for horizontal scaling across commodity nodes. The choice depends on data shape, access patterns, and scale requirements.

Q22. When should you choose a relational database over NoSQL?

A: Choose RDBMS when you need complex multi-table joins and ad-hoc reporting queries, strict ACID transactions across multiple entities (banking, inventory), strong referential integrity, or when data volume/throughput doesn't require horizontal scale. Most systems today are polyglot — using RDBMS for transactional core and NoSQL for high-scale/derived data.

Q23. What is denormalization and why is it common in NoSQL?

A: Denormalization duplicates data across multiple tables/documents so that a query can be satisfied by reading from a single partition/collection without a join. In NoSQL — especially Cassandra — you design tables around specific queries first, then duplicate data into multiple tables per access pattern, trading storage and write complexity (must update multiple copies) for fast, predictable reads.

-- Normalized (RDBMS): one orders table, joined with customers
SELECT o.* FROM orders o JOIN customers c ON o.customer_id = c.id WHERE c.city='Pune';

-- Denormalized (Cassandra): duplicate customer_city into orders_by_city table
CREATE TABLE orders_by_city (
  city text,
  order_id uuid,
  customer_name text,
  amount decimal,
  PRIMARY KEY (city, order_id)
);

Q24. What are the trade-offs of joins in NoSQL databases?

A: Most NoSQL databases (Cassandra, DynamoDB, MongoDB) don't support server-side joins across partitions/collections at scale, because joins require scatter-gather across nodes which kills predictable low latency. Instead, applications either denormalize data ahead of time, perform "joins" in application code across multiple queries, or use a secondary system (Spark, Elasticsearch) for complex analytical joins.

Q25. How does schema flexibility in NoSQL affect application development?

A: Flexible schemas let teams iterate quickly — new fields can be added without a blocking migration — but push data-integrity responsibility onto the application layer. Without discipline (versioned schemas, validation libraries), documents/rows can drift into inconsistent shapes over time, making later queries and migrations harder.

Q26. What is polyglot persistence?

A: Polyglot persistence is the practice of using multiple different database technologies within one system, each chosen for the specific access pattern it serves best — e.g., PostgreSQL for transactional order data, Cassandra for time-series event logs, Redis for caching/sessions, Elasticsearch for full-text search, and Neo4j for recommendation graphs.

Q27. What are the limitations of NoSQL databases?

A: Weaker or eventual consistency by default, limited/no multi-row ACID transactions (improving but still restrictive), no ad-hoc joins, query patterns must often be known upfront (Cassandra), less mature tooling/ORM ecosystem than SQL, and a real learning curve around data modeling (denormalization, partition sizing) that differs fundamentally from relational thinking.

Q28. How do transactions differ between SQL and NoSQL systems?

A: RDBMS provides full multi-statement ACID transactions with rollback across tables. Most NoSQL systems provide only single-row/single-partition atomicity by default. Some offer limited multi-document transactions (MongoDB 4.0+) or lightweight transactions using Paxos-based compare-and-set (Cassandra's LWT with IF NOT EXISTS), but these are more expensive and used sparingly, not as the default mode of operation.

4. Cassandra Architecture

Q29. What is Apache Cassandra and what problem does it solve?

A: Apache Cassandra is an open-source, distributed, wide-column NoSQL database originally built at Facebook (combining Amazon Dynamo's distribution model with Google Bigtable's data model). It solves the problem of storing massive volumes of data with high write throughput, linear horizontal scalability, and no single point of failure across multiple data centers/regions.

Q30. Describe Cassandra's ring architecture.

A: Cassandra arranges all nodes in a logical ring using consistent hashing on a token range (0 to 2^127-1 with Murmur3Partitioner). Each node owns a range of tokens; a row's partition key is hashed to a token that maps to a specific node (and its replicas, walking clockwise around the ring). Any node can act as the coordinator for a client request — there is no master, so the ring has no single point of failure.

Q31. What is a node, a data center, and a cluster in Cassandra?

A: A node is a single Cassandra server instance holding a portion of the data. A data center is a logical grouping of nodes (can map to a physical DC, cloud region, or even workload isolation like "analytics" vs "OLTP"). A cluster is the complete set of nodes across one or more data centers that together form one logical database, sharing the same keyspaces and gossiping cluster state.

Q32. What is the gossip protocol in Cassandra?

A: Gossip is a peer-to-peer communication protocol where every node exchanges state information (which nodes are up/down, token ranges, schema version, load) with up to 3 random nodes every second. Over a few rounds, information propagates to the entire cluster exponentially fast, without needing a central coordinator — this is how Cassandra achieves decentralized cluster membership and failure detection.

Q33. What is a coordinator node?

A: The coordinator is whichever node in the cluster receives the client's request (any node can serve this role, chosen by the driver's load-balancing policy). The coordinator determines which nodes own the requested partition (via the token ring), forwards the request to the required number of replicas based on the consistency level, waits for the needed acknowledgements, and returns the response to the client.

Q34. What is consistent hashing and how does Cassandra use it?

A: Consistent hashing maps both data (via a hash of the partition key) and nodes onto the same circular token-range space, so that adding or removing a node only redistributes a small fraction of neighboring data instead of reshuffling the entire dataset. Cassandra hashes the partition key to a 64-bit token using Murmur3Partitioner and places the row on the node owning that token range.

-- Simplified idea:
token = murmur3_hash(partition_key)
owning_node = first node clockwise from token on the ring
replica_nodes = next (RF - 1) distinct nodes clockwise (per replication strategy)

Q35. What is a virtual node (vnode)?

A: Instead of assigning one large contiguous token range per physical node, Cassandra assigns each node many small, randomly distributed token ranges (vnodes, default 16 per node in recent versions, tunable via num_tokens). This spreads data more evenly, speeds up bootstrap/decommission (many nodes share the rebalancing work instead of one or two neighbors), and reduces hotspots from uneven token assignment.

Q36. What is a snitch in Cassandra?

A: A snitch tells Cassandra which data center and rack each node belongs to, which is used for routing requests efficiently (prefer local DC) and for placing replicas intelligently (spread across racks/DCs for fault tolerance). Common snitches: SimpleSnitch (single DC, no rack awareness), GossipingPropertyFileSnitch (recommended, reads local DC/rack config and gossips it), and cloud-specific snitches like Ec2Snitch.

Q37. What is hinted handoff?

A: When a replica node is temporarily down during a write, the coordinator stores a "hint" (the missed write) locally or on another node. Once the failed replica comes back online, the hint is replayed to bring it up to date, without requiring a full repair. This improves consistency without sacrificing availability for the write. Hints are only stored for a configurable window (default 3 hours) — beyond that, a full repair is needed.

# cassandra.yaml
hinted_handoff_enabled: true
max_hint_window_in_ms: 10800000   # 3 hours
hinted_handoff_throttle_in_kb: 1024

Q38. What is read repair?

A: During a read, the coordinator queries the number of replicas required by the consistency level, compares their responses, and if it detects stale data on some replicas, it pushes the latest version back to them in the background (or synchronously for the digest mismatch, depending on version). This is one of Cassandra's key eventual-consistency mechanisms, quietly healing divergence caused by dropped writes or hinted handoff gaps.

Q39. What is anti-entropy repair (nodetool repair)?

A: Anti-entropy repair is a manual/scheduled process (nodetool repair) that compares data across all replicas using Merkle trees to find and reconcile inconsistencies that read repair and hinted handoff may have missed — especially important after extended node outages beyond the hint window. Operators typically run repair regularly (e.g., weekly, within gc_grace_seconds) to avoid "zombie" data resurrection from deleted rows.

nodetool repair -pr keyspace_name table_name
# -pr: repair only the primary range owned by this node, avoiding duplicate work across the cluster

Q40. How does Cassandra achieve high availability with no single point of failure?

A: Every node is identical (peer-to-peer, masterless) and can coordinate requests; data is replicated across multiple nodes (replication factor) and optionally multiple data centers/racks; gossip continuously detects failures; hinted handoff and read repair heal missed writes; and clients can be configured to fail over to any live node. The cluster keeps serving reads/writes even if multiple nodes fail, as long as the required consistency level can still be met.

5. Cassandra Data Modeling

Q41. What is the golden rule of Cassandra data modeling?

A: "Design your tables around your queries, not around your entities." Unlike relational modeling (normalize first, query later), Cassandra modeling starts by listing every query the application needs to run, then creates one denormalized table per query pattern so each query can be satisfied by a single-partition read. This is often summarized as "one table per query."

Q42. What is a partition key?

A: The partition key is the first component of the primary key; it is hashed to determine which node(s) store the row. All rows sharing the same partition key live together on the same replica set, physically co-located on disk — this is what makes single-partition reads extremely fast (no scatter-gather across the cluster).

CREATE TABLE orders_by_customer (
  customer_id uuid,       -- partition key
  order_date timestamp,
  order_id uuid,
  amount decimal,
  PRIMARY KEY (customer_id, order_date, order_id)
);

Q43. What is a clustering column/key?

A: Clustering columns are the remaining components of the primary key after the partition key; they determine the on-disk sort order of rows WITHIN a partition. Queries can efficiently filter/range-scan on clustering columns (e.g., "orders after a date") because rows are physically stored in that sorted order — but you cannot skip a clustering column in a WHERE clause without also filtering the ones before it (or using ALLOW FILTERING).

Q44. What is a composite/compound primary key?

A: A primary key made of a partition key (one or more columns wrapped in parentheses) plus one or more clustering columns: PRIMARY KEY ((pk1, pk2), ck1, ck2). A composite partition key (multiple columns) lets you spread a logically single entity's data more evenly across nodes when a single column would create huge, hot partitions.

CREATE TABLE metrics_by_hour (
  service text,
  hour_bucket text,
  metric_time timestamp,
  value double,
  PRIMARY KEY ((service, hour_bucket), metric_time)
);
-- Composite partition key: (service, hour_bucket)
-- Clustering column: metric_time

Q45. What is a wide row / wide partition?

A: A wide partition holds many rows (potentially millions) that share the same partition key but differ by clustering column, e.g., all time-series readings for one sensor. Cassandra is optimized for this pattern (fast sequential writes, sorted range scans), but partitions that grow unbounded (e.g., never bucketed by time) become "hot" — too large, slow to compact, and risk node instability. A common fix is time-bucketing the partition key.

-- Unbounded (risky): all readings forever in one partition
PRIMARY KEY (sensor_id, reading_time)

-- Bucketed (safer): new partition per day
PRIMARY KEY ((sensor_id, day_bucket), reading_time)

Q46. Why does Cassandra encourage denormalization?

A: Because Cassandra has no efficient server-side joins and discourages secondary indexes on large tables, the only way to support multiple query patterns on the same data is to duplicate it into multiple tables, each shaped for a specific query — e.g., orders_by_customer and orders_by_status storing the same order data twice. Writes become more expensive (must update N tables) but reads stay fast and predictable (single partition).

Q47. What is query-first data modeling?

A: A design methodology where you (1) identify entities and relationships, (2) enumerate every access pattern/query the application needs, then (3) design one table per query with the right partition and clustering keys — rather than designing normalized tables first and figuring out queries later, as in relational modeling. Tools like the Chebotko diagram are often used to map entities to query tables.

Q48. What are the risks of a poorly chosen partition key (hotspots)?

A: If a partition key has low cardinality or skewed distribution (e.g., partitioning by "country" when 80% of users are in one country, or by a boolean status flag), a small number of nodes end up storing and serving a disproportionate share of data and traffic — creating "hot" nodes, uneven load, slow compactions, and potential OOM/latency spikes on those nodes while others sit idle.

Q49. What is a materialized view in Cassandra?

A: A materialized view (MV) automatically maintains a denormalized copy of a base table with a different primary key, so you can query the same data by an alternate key without manually writing to two tables. Cassandra keeps the MV in sync on every base-table write. MVs simplify application code but have had production stability issues historically, so many teams prefer manually maintained duplicate tables instead.

CREATE MATERIALIZED VIEW orders_by_status AS
  SELECT * FROM orders_by_customer
  WHERE status IS NOT NULL AND customer_id IS NOT NULL AND order_id IS NOT NULL
  PRIMARY KEY (status, customer_id, order_id);

Q50. What is a secondary index and when should you avoid it?

A: A secondary index lets you query a table by a non-partition-key column without ALLOW FILTERING, by maintaining a hidden internal index per node. Avoid them on high-cardinality columns or large clusters — since the index is local to each node, the coordinator must query ALL nodes (scatter-gather) to fully answer the query, which is slow and doesn't scale. Better alternatives: a dedicated query table, or an external search index (Elasticsearch/SASI/SAI).

CREATE INDEX ON orders_by_customer (status);
-- Works, but for large clusters prefer:
CREATE TABLE orders_by_status (status text, order_id uuid, customer_id uuid, PRIMARY KEY (status, order_id));

Q51. How do you model a one-to-many relationship in Cassandra?

A: Model it by making the "one" side the partition key and the "many" side the clustering key, so all related rows live in the same partition and can be fetched in a single read — e.g., PRIMARY KEY (customer_id, order_id) stores all of a customer's orders together, sorted by order_id (or a timestamp clustering column for chronological order).

Q52. What is the difference between a static column and a regular column?

A: A STATIC column's value is shared across all rows within the same partition (one value per partition key, regardless of clustering key), useful for storing partition-level metadata (e.g., customer_name that doesn't change per order). Regular columns store a distinct value per row (per unique clustering key value).

CREATE TABLE orders_by_customer (
  customer_id uuid,
  customer_name text STATIC,   -- one value per partition
  order_id uuid,
  amount decimal,
  PRIMARY KEY (customer_id, order_id)
);

6. CQL (Cassandra Query Language)

Q53. What is CQL and how does it compare to SQL?

A: CQL (Cassandra Query Language) is a SQL-like language for interacting with Cassandra — it looks familiar (CREATE TABLE, SELECT, INSERT, UPDATE, DELETE) but works very differently under the hood: no joins, no subqueries, no arbitrary WHERE clauses (queries must align with the primary key structure), and every table's schema is defined around a specific access pattern rather than normalized entities.

Q54. How do you create a keyspace in Cassandra?

A: A keyspace is Cassandra's top-level namespace (like a "database" in RDBMS terms), where you define the replication strategy and replication factor per data center. SimpleStrategy is for single-DC/dev use; NetworkTopologyStrategy is required for production multi-DC clusters.

CREATE KEYSPACE ecommerce
  WITH replication = {
    'class': 'NetworkTopologyStrategy',
    'dc1': 3,
    'dc2': 3
  };
USE ecommerce;

Q55. How do you create a table with a composite partition key?

A: Wrap multiple columns in parentheses within the PRIMARY KEY clause to form a composite partition key, followed by clustering columns. This distributes rows more evenly when a single column would create oversized partitions.

CREATE TABLE events_by_app_day (
  app_id text,
  event_day date,
  event_time timestamp,
  event_type text,
  payload text,
  PRIMARY KEY ((app_id, event_day), event_time)
) WITH CLUSTERING ORDER BY (event_time DESC);

Q56. How do you insert and query data with CQL?

A: INSERT and SELECT resemble SQL syntax but SELECT is restricted to queries that can be answered efficiently (must specify the full partition key at minimum). UPSERT semantics apply — INSERT and UPDATE with the same primary key overwrite the same row.

INSERT INTO orders_by_customer (customer_id, order_date, order_id, amount)
  VALUES (uuid(), toTimestamp(now()), uuid(), 249.50);

SELECT * FROM orders_by_customer
  WHERE customer_id = 3f2504e0-4f89-11d3-9a0c-0305e82c3301;

Q57. How does the WHERE clause work with partition and clustering keys?

A: You must provide an equality condition on the entire partition key to identify which node(s) to query. Clustering columns can then be filtered with equality or range operators (<, >, <=, >=), but must be used IN ORDER — you cannot filter on a later clustering column without constraining the earlier ones first, because the on-disk data is sorted hierarchically by clustering column order.

-- Valid: full partition key + range on first clustering column
SELECT * FROM events_by_app_day
  WHERE app_id = 'checkout' AND event_day = '2026-07-03'
  AND event_time > '2026-07-03T09:00:00';

-- Invalid without ALLOW FILTERING: filtering on event_type (not a key column)
SELECT * FROM events_by_app_day WHERE event_type = 'error';

Q58. What is ALLOW FILTERING and why is it discouraged?

A: ALLOW FILTERING permits a query that doesn't align with the primary key structure by scanning and filtering rows in memory across potentially many/all partitions and nodes. It bypasses Cassandra's core performance guarantee and can cause severe latency and cluster load on large tables. It's acceptable only on small tables or tightly bounded queries — never as a routine production pattern; redesign the table instead.

SELECT * FROM events_by_app_day WHERE event_type = 'error' ALLOW FILTERING; -- avoid at scale

Q59. How do you use TTL (time to live) in Cassandra?

A: TTL automatically expires and deletes data after a specified number of seconds, written as a tombstone once expired and purged during compaction. Useful for session data, caches, or time-bounded event logs so you don't need manual cleanup jobs.

INSERT INTO sessions (session_id, user_id, data)
  VALUES (uuid(), 1001, 'active') USING TTL 3600;  -- expires in 1 hour

ALTER TABLE sessions WITH default_time_to_live = 86400;  -- table-level default TTL

Q60. What is a lightweight transaction (LWT) / IF NOT EXISTS?

A: LWTs provide linearizable compare-and-set semantics (using the Paxos consensus protocol) for cases needing "check-then-act" atomicity, like unique username registration. They are much slower than normal writes (require 4 round trips instead of 1) because they need consensus among replicas, so use sparingly, only where uniqueness/atomicity truly matters.

INSERT INTO users (username, email) VALUES ('rkumar', 'rkumar@example.com')
  IF NOT EXISTS;

UPDATE accounts SET balance = 500 WHERE account_id = 1
  IF balance = 400;

Q61. How do you perform batch operations in CQL and when should you avoid them?

A: BATCH groups multiple INSERT/UPDATE/DELETE statements. A common misconception is that batches improve performance — in Cassandra they usually hurt it, because a coordinator must hold all mutations in memory and route them to potentially different partitions, increasing coordinator load and latency. The ONLY valid use case is atomicity across multiple tables sharing the SAME partition key (e.g., keeping a denormalized view in sync); never use batches purely as a "bulk insert" optimization.

BEGIN BATCH
  INSERT INTO orders_by_customer (customer_id, order_id, amount) VALUES (?, ?, ?);
  INSERT INTO orders_by_status (status, customer_id, order_id, amount) VALUES ('NEW', ?, ?, ?);
APPLY BATCH;

Q62. What are collections (list, set, map) in CQL?

A: CQL supports list (ordered, allows duplicates), set (unordered, unique values), and map (key-value pairs) as column types for storing small amounts of denormalized structured data directly in a row. They're stored as a single cell internally and are best kept small (a few hundred elements max) — large collections hurt read performance since the whole collection is read/written together.

CREATE TABLE products (
  id uuid PRIMARY KEY,
  tags set<text>,
  attributes map<text, text>,
  price_history list<decimal>
);
UPDATE products SET tags = tags + {'sale'} WHERE id = 1234...;

Q63. What is a user-defined type (UDT) in Cassandra?

A: UDTs let you group related fields into a single reusable structured type, similar to a struct, which can be embedded as a column type — improving readability and avoiding an explosion of loose columns for nested data like an address.

CREATE TYPE address (
  street text,
  city text,
  zip text
);
CREATE TABLE customers (
  id uuid PRIMARY KEY,
  name text,
  shipping_address frozen<address>
);

Q64. How do you use CQL's counter columns?

A: Counter columns provide a distributed, atomic increment/decrement primitive (e.g., page views, like counts) without needing a read-modify-write cycle. Restrictions: a counter table can ONLY contain counter columns (besides the primary key), counters can't be set to a specific value directly, and they aren't idempotent — a retried increment on timeout can double-count.

CREATE TABLE page_views (
  page_id text PRIMARY KEY,
  views counter
);
UPDATE page_views SET views = views + 1 WHERE page_id = '/home';

7. Consistency Levels & Tunable Consistency

Q65. What is tunable consistency in Cassandra?

A: Tunable consistency lets the client specify, on a PER-QUERY basis, how many replicas must acknowledge a read or write before it's considered successful — trading off latency/availability against consistency independently for each operation, rather than a single fixed setting for the whole database.

Q66. What is consistency level ONE?

A: ONE requires only a single replica to acknowledge the read or write before responding to the client — the fastest and most available option, but the read may return stale data if that replica hasn't yet received the latest write from another coordinator.

CONSISTENCY ONE;
SELECT * FROM orders_by_customer WHERE customer_id = ?;

Q67. What is consistency level QUORUM and how is it calculated?

A: QUORUM requires acknowledgement from a majority of replicas across ALL data centers: quorum = floor(RF / 2) + 1. For RF=3, QUORUM = 2. Using QUORUM for both reads and writes guarantees strong consistency (the read set and write set are guaranteed to overlap by at least one replica).

-- RF = 3 -> QUORUM = floor(3/2)+1 = 2
CONSISTENCY QUORUM;
UPDATE accounts SET balance = balance - 100 WHERE account_id = ?;

Q68. What is consistency level ALL?

A: ALL requires every replica (all RF copies) to acknowledge the operation. It gives the strongest consistency guarantee but the worst availability — if even one replica is down, the request fails. Rarely used in production except for critical, low-volume operations where correctness trumps availability entirely.

Q69. What is LOCAL_QUORUM and when should you use it?

A: LOCAL_QUORUM requires a majority of replicas within the LOCAL data center only, ignoring other DCs — avoiding the latency and availability risk of waiting on cross-DC network round trips. It's the standard production choice for multi-DC Cassandra deployments needing strong-ish consistency with good latency.

CONSISTENCY LOCAL_QUORUM;

Q70. How do read and write consistency levels interact to guarantee strong consistency?

A: Strong consistency (every read sees the latest write) is guaranteed when the read consistency level (R) plus the write consistency level (W) exceed the replication factor (N): R + W > N. This ensures the set of replicas read from and the set written to must overlap by at least one node holding the latest value.

Q71. What is the formula R + W > N and what does it guarantee?

A: With replication factor N, if you pick read consistency R and write consistency W such that R + W > N, at least one replica queried on read must have also been written to during the write — guaranteeing the read observes the latest value. Example: N=3, W=QUORUM(2), R=QUORUM(2) → 2+2=4 > 3, so strong consistency holds.

-- N=3, W=ONE(1), R=ONE(1): 1+1=2, NOT > 3 -> eventual consistency only
-- N=3, W=QUORUM(2), R=QUORUM(2): 2+2=4 > 3 -> strong consistency

Q72. What happens if you use consistency level ONE for both reads and writes?

A: You get the lowest latency and highest availability, but no strong consistency guarantee — a read might hit a replica that hasn't yet received the most recent write (R + W = 2, which is not greater than typical RF=3). This is a common, acceptable trade-off for use cases tolerant of brief staleness, like activity feeds or non-critical logs.

CONSISTENCY ONE;
INSERT INTO activity_log (user_id, ts, action) VALUES (?, ?, ?);

Q73. What is EACH_QUORUM?

A: EACH_QUORUM requires a quorum of replicas to acknowledge in EVERY data center (not just one, and not the whole cluster). It's used for writes that must be durably visible with quorum guarantees in all regions simultaneously — stronger (and slower) than LOCAL_QUORUM, and typically only used for writes, not reads.

Q74. How do you choose the right consistency level for a use case?

A: Balance business requirements against latency/availability needs: use ONE/LOCAL_ONE for high-volume, tolerant-of-staleness data (logs, metrics); LOCAL_QUORUM for most transactional application data needing solid consistency with good latency in multi-DC setups; QUORUM/EACH_QUORUM/ALL only for rare, critical operations (financial balances, uniqueness checks) where correctness outweighs the latency and availability cost.

8. Write/Read Path

Q75. Describe Cassandra's write path.

A: On a write: (1) the coordinator routes the mutation to the replicas that own the partition, (2) each replica appends the write to its append-only commit log on disk for durability, (3) the write is also applied to an in-memory memtable, and (4) once enough replicas acknowledge per the consistency level, success is returned to the client. This design makes writes extremely fast — sequential disk append plus an in-memory update, no read-before-write.

Q76. What is a commit log?

A: The commit log is an append-only, sequential-write file on each node that durably records every mutation before it's acknowledged, ensuring no data loss on crash (memtable contents can be replayed from it). It's purely for crash recovery — it is never read during normal query serving, only replayed at node startup if the node crashed before flushing its memtables.

# cassandra.yaml
commitlog_sync: periodic
commitlog_sync_period_in_ms: 10000
commitlog_segment_size_in_mb: 32

Q77. What is a memtable?

A: A memtable is an in-memory, sorted (by clustering key) data structure per table that buffers recent writes for a partition range. Reads check the memtable first (most recent data), then fall back to on-disk SSTables. When a memtable reaches a size threshold, it's flushed to disk as an immutable SSTable and a new memtable takes over.

# cassandra.yaml
memtable_heap_space_in_mb: 2048
memtable_flush_writers: 2

Q78. What is an SSTable?

A: SSTable (Sorted String Table) is the immutable on-disk file format Cassandra flushes memtables into. Because SSTables are never modified after being written (only merged via compaction), writes never require locking or in-place updates — updates/deletes simply create new SSTable entries that supersede older ones, reconciled at read time or during compaction.

Q79. What is compaction and why is it needed?

A: Since SSTables are immutable and accumulate over time (each flush creates a new one, each update/delete adds new entries rather than overwriting), compaction periodically merges multiple SSTables into fewer, larger ones — discarding overwritten values, purging expired tombstones (past gc_grace_seconds), and reducing the number of files a read must check, which keeps read latency low.

ALTER TABLE orders_by_customer WITH compaction = {
  'class': 'SizeTieredCompactionStrategy'
};
nodetool compact ecommerce orders_by_customer   -- trigger major compaction manually

Q80. What are the different compaction strategies in Cassandra?

A: SizeTieredCompactionStrategy (STCS): merges similarly-sized SSTables, good default for write-heavy workloads but can cause read/space amplification. LeveledCompactionStrategy (LCS): organizes SSTables into levels with bounded size, better for read-heavy workloads with lower space overhead but higher I/O during compaction. TimeWindowCompactionStrategy (TWCS): groups SSTables by time window, ideal for time-series data with TTL-based expiry (whole SSTables can be dropped once expired).

Q81. What is a Bloom filter and how does Cassandra use it?

A: A Bloom filter is a space-efficient probabilistic data structure that can definitively say "this key is NOT in this SSTable" (no false negatives) or "this key MIGHT be in this SSTable" (possible false positives). Each SSTable has an associated Bloom filter kept in memory, so reads can skip SSTables that certainly don't contain the requested partition key — drastically reducing disk I/O for reads.

ALTER TABLE orders_by_customer WITH bloom_filter_fp_chance = 0.01; -- 1% false positive rate

Q82. Describe Cassandra's read path.

A: On a read: (1) the coordinator identifies replicas owning the partition and sends requests to the number needed by the consistency level, (2) each replica checks its memtable, then uses the Bloom filter to skip irrelevant SSTables, then checks the partition key cache/index summary/index file to locate data in relevant SSTables, (3) results from memtable and SSTables are merged (latest timestamp wins per column), and (4) if replicas disagree, read repair reconciles them.

Q83. What is a tombstone and how does deletion work in Cassandra?

A: Because SSTables are immutable, a DELETE doesn't remove data immediately — it writes a special marker called a tombstone that shadows the deleted data. Reads filter out tombstoned data, and tombstones are physically purged only during compaction, after gc_grace_seconds (default 10 days) has passed — giving time for the delete to propagate to all replicas via repair before permanent removal.

DELETE FROM orders_by_customer WHERE customer_id = ? AND order_id = ?;
ALTER TABLE orders_by_customer WITH gc_grace_seconds = 864000; -- 10 days default

Q84. What is the danger of too many tombstones?

A: If a partition accumulates a large number of tombstones (common in queue-like or delete-heavy patterns), every read on that partition must scan past all those tombstones before finding live data, causing severe read latency and even query timeouts (Cassandra logs a warning/error when tombstones scanned exceed a threshold). Fix by redesigning the access pattern (use TTL instead of explicit deletes, or time-bucket partitions) rather than deleting individual rows from a large shared partition.

Q85. What is a partition summary and index file?

A: Each SSTable has a Partition Index file mapping partition keys to their byte offset within the SSTable, and an in-memory Partition Summary that samples the index (e.g., every 128th entry) to narrow down the search range before doing a single disk seek into the index file — reducing the need to load the entire index into memory for large SSTables.

Q86. What is the difference between a memtable flush and compaction?

A: A flush writes ONE memtable's contents to disk as a new, immutable SSTable (triggered by memory pressure, commit log size, or `nodetool flush`) — it doesn't touch existing SSTables. Compaction merges MULTIPLE existing SSTables together into fewer files, discarding obsolete/overwritten data and expired tombstones. Flush creates SSTables; compaction consolidates them.

9. DynamoDB & Other NoSQL Stores

Q87. What is Amazon DynamoDB?

A: DynamoDB is AWS's fully managed, serverless key-value/document NoSQL database offering single-digit millisecond latency at any scale, automatic partitioning, on-demand or provisioned throughput, and built-in replication across Availability Zones (and optionally regions via Global Tables). It's the managed-service analogue to Cassandra's/Dynamo's original design.

Q88. How does DynamoDB's partition key and sort key compare to Cassandra's?

A: DynamoDB's "partition key" (hash key) is conceptually identical to Cassandra's partition key (determines physical placement via hashing), and its "sort key" (range key) plays the same role as Cassandra's clustering column (sorts items within a partition and supports range queries). The terminology differs but the modeling philosophy — design around access patterns — is nearly identical.

// DynamoDB table definition (AWS CLI JSON)
{
  "TableName": "OrdersByCustomer",
  "KeySchema": [
    { "AttributeName": "customerId", "KeyType": "HASH" },
    { "AttributeName": "orderId", "KeyType": "RANGE" }
  ]
}

Q89. What are the key differences between DynamoDB and Cassandra?

A: DynamoDB is fully managed/serverless (no ops, pay-per-request or provisioned capacity, tied to AWS) while Cassandra is open-source and self-managed (or via managed offerings like DataStax Astra), portable across any cloud/on-prem. DynamoDB uses a proprietary API/SDK; Cassandra uses CQL. DynamoDB has built-in support for transactions and streams (CDC); Cassandra's LWTs and CDC feature are comparable but less turnkey. Cassandra offers more explicit tuning of consistency and replication topology.

Q90. What is MongoDB and how does its document model differ from Cassandra's wide-column model?

A: MongoDB stores rich, nested JSON/BSON documents and supports secondary indexes, aggregation pipelines, and (since 4.0) multi-document ACID transactions, making it more flexible for varied, deeply nested data and ad-hoc queries. Cassandra's wide-column model is flatter (rows + columns per partition) but built for much higher write throughput and predictable linear scalability across huge clusters — MongoDB's scaling (sharding) requires more careful planning than Cassandra's inherently distributed design.

Q91. What is Redis primarily used for?

A: Redis is an in-memory key-value data structure store, prized for extremely low latency (sub-millisecond). Common uses: caching layer in front of a primary database, session storage, rate limiting/counters, pub/sub messaging, leaderboards (sorted sets), and distributed locks. Data can be persisted to disk (RDB snapshots, AOF log) but it's fundamentally optimized for in-memory access speed, not as a system of record for massive datasets.

Q92. What is a graph database use case example (Neo4j)?

A: Neo4j excels at queries involving deep, variable-length relationship traversal — e.g., "find all products purchased by friends of friends who also bought X" (recommendation engines), fraud ring detection (shared devices/addresses across accounts), and permission/access-control graphs. Such queries would require multiple expensive self-joins in SQL but are natural, index-free-adjacency traversals in Cypher.

Q93. What is HBase and how does it relate to Cassandra?

A: HBase is a wide-column store built on top of HDFS and modeled directly on Google's Bigtable paper, tightly integrated with the Hadoop ecosystem. Unlike Cassandra (masterless, AP-leaning), HBase uses a master-based architecture (HMaster + RegionServers, relying on ZooKeeper for coordination) and leans CP — strongly consistent but with lower write availability during failover compared to Cassandra's peer-to-peer design.

// HBase shell
create 'orders', 'cf1'
put 'orders', 'row1', 'cf1:amount', '249.50'
get 'orders', 'row1'

Q94. How do you choose between DynamoDB and self-managed Cassandra?

A: Choose DynamoDB when you're AWS-committed and want zero operational overhead, automatic scaling, and pay-per-use pricing for moderate/spiky workloads. Choose Cassandra when you need multi-cloud/on-prem portability, fine-grained control over consistency/replication/compaction, extremely high sustained write throughput at lower cost per TB at massive scale, or you already run a Cassandra/DataStax platform team.

10. Java Integration

Q95. How do you connect to Cassandra from Java using the DataStax driver?

A: The DataStax Java Driver (now the core driver, com.datastax.oss:java-driver-core) provides a CqlSession — the main entry point for executing CQL statements. It's built once and reused across the application (it manages connection pooling, load balancing, and retries internally), never created per request.

CqlSession session = CqlSession.builder()
    .addContactPoint(new InetSocketAddress("127.0.0.1", 9042))
    .withLocalDatacenter("dc1")
    .withKeyspace("ecommerce")
    .build();

ResultSet rs = session.execute("SELECT * FROM orders_by_customer WHERE customer_id = ?", customerId);

Q96. How do you execute a prepared statement with the DataStax Java driver?

A: Prepared statements parse and cache the query plan on the server once, then bind different parameter values on each execution — improving performance and, critically, preventing CQL injection. Always prepare statements once (e.g., at startup or lazily cached) and reuse the PreparedStatement object across many executions rather than re-preparing per call.

PreparedStatement prepared = session.prepare(
    "INSERT INTO orders_by_customer (customer_id, order_id, amount) VALUES (?, ?, ?)");

BoundStatement bound = prepared.bind(customerId, orderId, new BigDecimal("249.50"));
session.execute(bound);

Q97. How do you map Java objects to Cassandra tables using the Object Mapper / Spring Data Cassandra?

A: The DataStax Object Mapper (or Spring Data Cassandra's annotations) lets you annotate POJOs to auto-generate CRUD queries, avoiding hand-written CQL boilerplate for simple cases. @Table maps a class to a table; @PrimaryKeyColumn distinguishes partition vs clustering columns.

@Table("orders_by_customer")
public class Order {
    @PrimaryKeyColumn(name = "customer_id", type = PrimaryKeyType.PARTITIONED)
    private UUID customerId;

    @PrimaryKeyColumn(name = "order_id", type = PrimaryKeyType.CLUSTERED)
    private UUID orderId;

    @Column("amount")
    private BigDecimal amount;
}

Q98. How do you configure Spring Data Cassandra in a Spring Boot application?

A: Add the spring-boot-starter-data-cassandra dependency, configure contact points/keyspace/local datacenter in application.yml, and define a CassandraRepository interface for your entity — Spring auto-implements common CRUD and derived-query methods, similar to Spring Data JPA.

# application.yml
spring:
  cassandra:
    keyspace-name: ecommerce
    contact-points: 127.0.0.1
    local-datacenter: dc1
    port: 9042

public interface OrderRepository extends CassandraRepository<Order, UUID> {
    List<Order> findByCustomerId(UUID customerId);
}

Q99. How do you handle asynchronous queries with the DataStax driver?

A: The driver's executeAsync() returns a CompletionStage<AsyncResultSet> (Java's CompletableFuture-compatible API), allowing non-blocking query execution — important for high-throughput services that need to issue many concurrent Cassandra calls without dedicating a thread per request.

CompletionStage<AsyncResultSet> future = session.executeAsync(
    "SELECT * FROM orders_by_customer WHERE customer_id = ?", customerId);

future.thenAccept(resultSet -> {
    for (Row row : resultSet.currentPage()) {
        System.out.println(row.getBigDecimal("amount"));
    }
});

Q100. What are best practices for using Cassandra drivers in production Java applications?

A: Reuse a single CqlSession per application (it's thread-safe and manages pooling internally) — never open one per request. Always use prepared statements. Set appropriate consistency levels per query rather than relying on driver defaults. Configure sensible timeouts and retry policies (avoid the default retry-on-timeout for non-idempotent writes). Monitor via driver metrics (request latency, connection pool saturation). Handle NoHostAvailableException and driver-level exceptions with circuit breakers/backoff rather than blind retries.

SimpleStatement stmt = SimpleStatement.newInstance(
    "SELECT * FROM orders_by_customer WHERE customer_id = ?", customerId)
    .setConsistencyLevel(ConsistencyLevel.LOCAL_QUORUM)
    .setTimeout(Duration.ofSeconds(2));
session.execute(stmt);
No comments
Leave a Comment