home
diamond Go Premium
Data Engineering Path  ·  K Check

Comprehensive Azure Data Engineer Interview Guide (5+ Years Experience)


Section 1: Azure Cloud & Data Engineering Architecture (Questions 1 to 16)

1. Explain an end-to-end Azure Data Engineering architecture you have implemented.

In an enterprise cloud data platform, an end-to-end Medallion Lakehouse architecture integrates structured, semi-structured, and streaming data sources into Azure Data Lake Storage Gen2 (ADLS Gen2) and processes them through Azure Databricks (Unity Catalog enabled), orchestrated by Azure Data Factory (ADF).

graph LR
    Source["Upstream Sources ERP / CRM / Kafka"] --> Landing["ADLS Gen2 Landing Storage"]
    Landing --> ADF["Azure Data Factory Orchestrator"]
    ADF --> Bronze["Unity Catalog Bronze Raw Table"]
    Bronze --> Silver["Databricks Silver Cleaned CDC"]
    Silver --> Gold["Databricks Gold Aggregated Star Schema"]
    Gold --> Synapse["Azure Synapse Dedicated SQL Pool"]
    Gold --> PBI["Power BI Enterprise Analytics"]
  • Ingestion Layer: Azure Data Factory pulls data from transactional databases and APIs, landing raw Parquet files into the landing/ container of ADLS Gen2.
  • Storage Layer: ADLS Gen2 with Hierarchical Namespace enabled stores data segregated into Landing, Bronze, Silver, and Gold zones.
  • Processing & Transformations: Azure Databricks executes structured streaming Auto Loader pipelines and PySpark notebooks governed by Unity Catalog.
  • Serving Layer: Curated Gold tables are consumed directly via Databricks SQL Warehouses or exported to Azure Synapse Analytics for enterprise high-concurrency BI dashboards.

2. Difference between Azure Blob Storage and ADLS Gen2.

Feature Attribute Azure Blob Storage Azure Data Lake Storage Gen2 (ADLS Gen2)
Namespace Architecture Flat namespace (virtual directories simulated via / slash delimiters). Hierarchical Namespace (HNS) with true physical directories and folders.
Directory Rename Operations $O(N)$ operation requiring copying and deleting every single file in the virtual path. $O(1)$ atomic metadata update requiring zero file data movement.
Access Control (Permissions) Coarse-grained Azure Role-Based Access Control (RBAC) at container/storage account level. Fine-grained POSIX Access Control Lists (ACLs) at individual directory and file levels + Azure RBAC.
Analytical Driver Compatibility Standard WASB / REST protocol; inefficient for distributed query scanning. Optimized ABFSS (Azure Blob File System Secure) driver specifically built for Hadoop, PySpark, and Databricks.

3. What is Managed Identity? When would you use it instead of a Service Principal?

  • Managed Identity: An identity automatically managed and provisioned by Microsoft Entra ID (formerly Azure AD) dedicated to an Azure resource (e.g., Azure Data Factory, Databricks cluster, or Virtual Machine).
  • System-Assigned: Coupled strictly to the lifecycle of the parent resource; deleted when the resource is deleted.
  • User-Assigned: Standalone identity created as a separate Azure resource that can be shared across multiple services.
  • When to use Managed Identity over a Service Principal:
  • Zero Secret Management: Managed Identity eliminates client secret rotation and password expiration risks because Entra ID rotates certificates automatically under the hood.
  • Simplified IAM: Preferred whenever communicating between Azure-native services (e.g., ADF accessing ADLS Gen2 or Azure Key Vault). Service Principals should only be used when authenticating from external, non-Azure environments (e.g., local GitHub Actions CI/CD runners or on-premises tools).

4. Explain Azure Key Vault integration with ADF.

  1. Key Vault Linked Service: Create an Azure Key Vault Linked Service in ADF using ADF's System-Assigned Managed Identity.
  2. Key Vault IAM Access: Grant the ADF Managed Identity Key Vault Secrets User RBAC role on the Key Vault resource.
  3. Parameterizing Credentials: Inside any ADF Linked Service (e.g., SQL Database or ADLS Gen2), select Azure Key Vault for secure authentication and specify the Secret Name. At runtime, ADF dynamically retrieves the secret without exposing plain-text credentials in pipeline definitions.

5. What are the types of Integration Runtime in ADF?

  1. Azure Integration Runtime: Serverless compute managed fully by Azure. Used for copying data between public cloud data stores and running cloud transformations.
  2. Self-Hosted Integration Runtime (SHIR): Software installed on an on-premises virtual machine or private network VM. Required when connecting to private, firewalled on-premises databases (e.g., SAP, Oracle, on-prem SQL Server) or resources behind a Private Endpoint.
  3. Azure-SSIS Integration Runtime: Dedicated managed cluster of VMs used specifically to lift and shift existing SQL Server Integration Services (SSIS) packages into Azure.

6. How do you implement incremental loading?

  • Watermark Table Strategy (Batch):
  • Maintain a metadata control table (etl_watermark) storing table_name and last_processed_timestamp.
  • ADF Lookup activity fetches the previous watermark.
  • ADF Copy activity filters source data (WHERE last_updated > @{activity('GetWatermark').output.last_processed_timestamp}).
  • Upon success, update the watermark table with the current run timestamp.
  • Event-Driven Auto Loader (Streaming / File Ingestion):
  • Leverage Databricks Auto Loader (cloudFiles.useNotifications = true), which uses Azure Event Grid and Storage Queues to process new files automatically without full directory rescans.

7. How do you secure data in Azure Data Lake?

  1. Network Security: Disable public network access; access storage exclusively via Azure Private Endpoints (Private Link) within an Azure Virtual Network (VNet).
  2. Identity & Access Management: Enforce Microsoft Entra ID authentication using least-privilege Azure RBAC (e.g., Storage Blob Data Reader/Contributor) supplemented by POSIX ACLs for directory-level isolation.
  3. Encryption at Rest & in Transit: Data is encrypted at rest using 256-bit AES encryption (Microsoft-managed keys or Customer-Managed Keys via Azure Key Vault) and enforced over HTTPS/TLS 1.2+ in transit.

8. Difference between RBAC and ACL.

  • Azure RBAC (Role-Based Access Control): Broad management and data access policies applied at higher Azure scopes (Subscription, Resource Group, Storage Account, or Container level).
  • POSIX ACLs (Access Control Lists): Granular read (r), write (w), and execute (x) permissions assigned to specific users or Entra ID groups at the directory or individual file path level inside an ADLS Gen2 hierarchical namespace.

9. How do you monitor Azure Data Factory pipelines?

  • ADF Studio Monitor Tab: Real-time visual tracking of pipeline runs, trigger executions, integration runtime CPU/memory utilization, and error diagnostics.
  • Azure Monitor & Log Analytics: Route ADF diagnostic logs (ActivityRuns, PipelineRuns, TriggerRuns) to an Azure Log Analytics Workspace for Kusto Query Language (KQL) auditing.
  • Automated Alert Rules: Configure Azure Monitor alerts to fire email, SMS, or Webhook notifications (Slack/Microsoft Teams) immediately upon pipeline execution failures.

10. What is a Private Endpoint and why use it?

An Azure Private Endpoint assigns a private IP address from your Azure Virtual Network (VNet) directly to a PaaS service (such as ADLS Gen2, Azure Key Vault, or Azure SQL Database).

  • Technical Value: It ensures all network traffic between your compute resources and storage remains entirely inside the Microsoft private backbone network, eliminating public internet exposure and preventing data exfiltration.

11. How do you troubleshoot a failed Copy Activity?

  1. Inspect Error Output JSON: Examine the detailed error code and message returned by the failed activity run in ADF Studio.
  2. Connectivity & Integration Runtime: If using a Self-Hosted IR, inspect local SHIR event logs to verify network firewall access and database DNS resolution.
  3. Data Typing & Schema Drift: Check for column data type mismatches or truncation between source and sink tables.
  4. Fault Tolerance Configuration: Enable skipIncompatibleRow and configure a staging storage container to capture incompatible rows or bad data files for subsequent analysis.

12. How do you optimize Azure costs?

  1. Storage Lifecycle Policies: Automatically transition ADLS Gen2 data older than 30 days to the Cool tier and older than 180 days to the Archive tier.
  2. Databricks Compute Optimization: Use automated Job Clusters instead of All-Purpose interactive clusters for scheduled jobs, enable aggressive auto-termination (e.g., 20 minutes) on dev clusters, and leverage spot instances for worker nodes.
  3. ADF DIU & Integration Runtime Tuning: Avoid over-allocating Data Integration Units (DIUs) on simple file copy activities.

13. How do you implement CI/CD for ADF?

  1. Git Integration: Link the ADF workspace to an Azure DevOps or GitHub repository using a collaboration branch (feature/xyz -> main).
  2. Publishing ARM Templates: Clicking Publish in ADF Studio compiles pipeline definitions into Azure Resource Manager (ARM) templates inside the adf_publish branch.
  3. Automated Release Pipeline: An Azure DevOps YAML pipeline deploys the compiled ARM templates across Dev -> Staging -> Prod environments, using template parameter files (arm_template_parameters.json) to dynamically swap storage URLs and Key Vault linked service endpoints.

14. What happens when an Integration Runtime is unavailable?

  • Behavior: Any ADF activity assigned to an offline or unreachable Integration Runtime immediately enters a Queued state until connection timeout occurs, after which the pipeline fails with an IR connectivity exception.
  • High Availability Mitigation: Deploy Self-Hosted Integration Runtimes on a multi-node active-active Windows VM cluster to eliminate single points of failure.

15. Explain Medallion Architecture in Azure.

  • Bronze Layer (Raw): Raw, immutable ingestion history stored in original format (Parquet/JSON) with operational audit columns (_ingested_at, _source_file).
  • Silver Layer (Curated & Cleansed): Deduplicated, quality-validated, conformed data standardized into enterprise schemas using Delta Lake MERGE INTO.
  • Gold Layer (Aggregated Business Intelligence): Star-schema dimensional models, fact tables, and aggregated KPI marts optimized for BI reporting and high-concurrency SQL queries.

16. How are you using Service Principal?

We use Microsoft Entra ID Service Principals authenticated via OAuth 2.0 client secrets or certificates for non-interactive external automation:

  • CI/CD pipelines deploying infrastructure via Terraform.
  • External orchestration engines connecting securely to Azure Databricks REST APIs or SQL Warehouses.

Section 2: PySpark & Distributed Processing (Questions 17 to 31)

17. Difference between DataFrame and RDD.

  • RDD (Resilient Distributed Dataset): Low-level functional API operating on Java/Python objects. Lacks query optimization and requires heavy serialization/deserialization overhead in PySpark.
  • DataFrame: High-level declarative API structured into named columns with explicit data types. Uses Tungsten off-heap binary memory encoding and the Catalyst Query Optimizer for optimal physical execution.

18. Explain Spark execution architecture.

  • Driver Program: Runs the SparkSession, creates the logical/physical execution plans, and coordinates tasks.
  • Cluster Manager: Resource allocator (YARN, Kubernetes, or Databricks Standalone cluster manager).
  • Executors: Distributed worker JVM processes that execute individual tasks and store cached partitions.
  • Jobs, Stages & Tasks: An action triggers a Job; wide transformations involving shuffles divide the job into Stages; each stage runs parallel Tasks across data partitions.

19. Difference between repartition() and coalesce().

Transformation Shuffle Behavior Intended Use Case
repartition(n) Full network shuffle redistributing data evenly across n partitions. Used to increase parallelism or rebalance highly skewed partition sizes.
coalesce(n) No network shuffle (narrow dependency); merges existing adjacent partitions on the same node. Used exclusively to reduce the number of partitions before writing final output files.

20. What causes data skew? How do you fix it?

  • Cause: Uneven distribution of records across partition keys (e.g., 80% of rows having country_code = 'US'), causing one executor task to run for hours while others finish in seconds.
  • Remediation Techniques:
  • Salting: Append a random integer prefix (0 to 9) to the skewed join key to distribute records evenly across 10 partitions.
  • Adaptive Query Execution (AQE) Skew Join: Enable spark.sql.adaptive.skewJoin.enabled = true so Spark automatically splits skewed partitions into smaller sub-partitions at runtime.

21. Difference between groupBy() and Window functions.

  • groupBy(): Collapses rows into aggregate summary buckets, reducing total output row cardinality.
  • Window Functions: Computes aggregations or rankings over sliding partition windows while preserving the original row cardinality.
from pyspark.sql import functions as F
from pyspark.sql.window import Window

# Window calculation: Rank transactions per customer by date without collapsing rows
window_spec = Window.partitionBy("customer_id").orderBy(F.col("transaction_date").desc())
df_ranked = df_sales.withColumn("latest_rank", F.row_number().over(window_spec))

22. Explain cache() vs persist().

  • cache(): Shorthand wrapper that stores the DataFrame in default storage level MEMORY_AND_DISK in PySpark.
  • persist(level): Allows specifying precise storage levels (MEMORY_ONLY, DISK_ONLY, MEMORY_AND_DISK_SER), enabling serialized memory compression when RAM is constrained.

23. How do you optimize joins?

  1. Broadcast Join: Broadcast dimension tables smaller than spark.sql.autoBroadcastJoinThreshold (default 10MB) to convert shuffle joins into local map-side joins.
  2. Filter Before Join: Apply explicit predicate filters and column projections (select) prior to joining to minimize network data exchange.
  3. Bucketing: Pre-sort and bucket large fact tables on join keys to eliminate shuffle overhead during recurrent join operations.

24. What is a broadcast join?

A Broadcast Hash Join copies a small dimension table to every executor JVM across the cluster. Each worker node performs the join entirely in local RAM against its local partition of the large fact table, completely avoiding network shuffle.

from pyspark.sql.functions import broadcast

df_joined = df_large_fact.join(broadcast(df_small_dim), on="store_id", how="inner")

25. Explain Catalyst Optimizer.

  1. Analysis: Resolves column names and table references against the internal catalog.
  2. Logical Plan Optimization: Applies rule-based optimizations (predicate pushdown, constant folding, projection pruning).
  3. Physical Planning: Generates multiple physical execution plans and selects the lowest-cost plan using Cost-Based Optimization (CBO).
  4. Code Generation: Compiles the optimized plan into raw JVM bytecode via the Tungsten engine.

26. What is Adaptive Query Execution (AQE)?

Enabled by default in Spark 3+ (spark.sql.adaptive.enabled = true), AQE optimizes query execution plans at runtime based on actual runtime statistics gathered after shuffle stages:

  • Dynamically Coalescing Shuffle Partitions: Combines small shuffle partitions to prevent generating thousands of tiny files.
  • Dynamically Switching Join Strategies: Converts Sort-Merge Joins into Broadcast Joins if runtime partition sizes fall below the threshold.
  • Dynamically Optimizing Skew Joins: Automatically splits skewed shuffle partitions into smaller tasks.

27. How do you use Spark UI for troubleshooting?

  • SQL / DataFrame Tab: Inspect physical execution DAGs, scan volume, spill-to-disk metrics, and broadcast thresholds.
  • Stages Tab: Identify Event Timeline straggler tasks, prolonged Garbage Collection (GC) pauses, and shuffle read/write imbalances.
  • Storage Tab: Check cached RDD/DataFrame footprint to ensure memory eviction is not causing recomputation loops.

28. Flatten a nested JSON file using PySpark.

from pyspark.sql import functions as F

# Flatten nested struct columns cleanly
df_flattened = df_nested.select(
    F.col("transaction_id"),
    F.col("customer.customer_id").alias("customer_id"),
    F.col("customer.address.city").alias("city")
)

29. Implement Slowly Changing Dimension Type 2.

An SCD Type 2 implementation preserves full historical tracking by updating old records (effective_end_date, is_current = false) and inserting new versions (effective_start_date, is_current = true) atomically via Delta Lake MERGE INTO.


30. How do you process files larger than 500 GB or large datasets?

  1. Never use collect(): Keep all transformations distributed across worker executors.
  2. Cluster Right-Sizing & Memory Allocation: Ensure executor cores and memory bounds accommodate shuffle spill thresholds.
  3. Enable AQE & Delta Lake ZORDER: Partition by coarse date intervals and apply multi-dimensional ZORDER indexing on high-cardinality filter columns.

31. Write PySpark logic to remove duplicate records.

from pyspark.sql import functions as F
from pyspark.sql.window import Window

# Keep only the latest record per transaction id based on updated at timestamp
dedup_window = Window.partitionBy("transaction_id").orderBy(F.col("updated_at").desc())

df_deduped = df_raw \
    .withColumn("_rn", F.row_number().over(dedup_window)) \
    .filter(F.col("_rn") == 1) \
    .drop("_rn")

Section 3: Azure Databricks & Lakehouse Governance (Questions 32 to 46)

32. Difference between Job Cluster and All-Purpose Cluster.

  • All-Purpose Cluster: Interactive compute shared across developers for exploratory notebook authoring. High DBU hourly pricing.
  • Job Cluster: Ephemeral compute provisioned automatically when a Databricks Job starts and terminated immediately upon completion. Costs significantly less per DBU.

33. Explain Single User vs Shared access modes.

  • Single User Access Mode: Dedicated cluster assigned exclusively to one user or service principal. Supports Python, SQL, Scala, and R with full custom library installation.
  • Shared Access Mode: Multi-user governance mode enforcing Unity Catalog fine-grained table and row/column security across multiple simultaneous users.

34. What is Delta Lake?

Delta Lake is an open-source ACID storage layer built on top of standard Apache Parquet files in cloud object storage. It maintains a transactional log (_delta_log/000000.json) guaranteeing serializable isolation, time travel, and concurrent batch/streaming reads and writes.


35. Explain OPTIMIZE, VACUUM and ZORDER.

  • OPTIMIZE table_name: Compacts small Parquet files into target ~1GB files to eliminate small-file read overhead.
  • ZORDER BY (column_a): Co-locates related data along multi-dimensional keys within the same Parquet files to maximize file skipping during queries.
  • VACUUM table_name RETAIN 168 HOURS: Deletes unreferenced historical Parquet data files older than the retention threshold to reclaim cloud storage space.

36. What is Unity Catalog?

Unity Catalog is Databricks' centralized governance and data catalog solution across multi-workspace cloud environments. It provides a standardized 3-level namespace (catalog.schema.table), fine-grained access control, data lineage capture, and centralized auditing.


37. How do you parameterize notebooks?

Use dbutils.widgets to declare input parameters and inject dynamic runtime arguments from ADF pipelines or Databricks Workflows:

dbutils.widgets.text("batch_id", "2026-07-10", "Processing Batch Date")
runtime_batch_id = dbutils.widgets.get("batch_id")

38. Explain Delta MERGE.

MERGE INTO executes an atomic upsert combining INSERT, UPDATE, and DELETE operations into a single ACID transaction against a target Delta table:

MERGE INTO cat_enterprise.silver.customers AS target
USING vw_incoming_updates AS source
ON target.customer_id = source.customer_id
WHEN MATCHED THEN UPDATE SET *
WHEN NOT MATCHED THEN INSERT *

39. How do you optimize Delta tables?

  1. Enable Liquid Clustering on high-cardinality filter columns to replace rigid Hive partitioning.
  2. Run periodic OPTIMIZE and VACUUM maintenance tasks.
  3. Enable Photon engine acceleration on production SQL pipelines.

40. What are widgets in Databricks notebooks?

Widgets (text, dropdown, combobox, multiselect) allow interactive parameter input inside Databricks notebooks and pass runtime parameters from external orchestrators.


41. How do you troubleshoot a failed Databricks job?

  1. Inspect the Driver Logs (log4j) and Executor Output Logs for explicit Python or JVM exceptions.
  2. Check cluster metrics for Out-Of-Memory (java.lang.OutOfMemoryError) heap exhaustion.
  3. Verify Unity Catalog permissions and check any JSON exit payload returned via dbutils.notebook.exit().

42. What is Photon?

Photon is Databricks' native vectorized C++ query engine integrated into the runtime. It executes SQL and PySpark transformations directly on bare-metal CPU SIMD registers, accelerating performance up to 5x without code modifications.


43. How do you reduce Databricks costs?

  • Run production ETL workloads exclusively on Job Clusters.
  • Configure aggressive Auto-Termination (15 to 20 minutes) on interactive clusters.
  • Enable Auto-Scaling with strictly bounded minimum and maximum worker nodes.

44. How do you monitor cluster performance?

Utilize the Cluster Metrics / Ganglia UI tab to monitor CPU utilization, memory pressure, network throughput, and disk I/O. Query Databricks System Tables (system.compute.clusters) to track DBU consumption.


45. How do you manage secrets securely?

Store sensitive database credentials and API tokens inside Azure Key Vault backed by Databricks Secret Scopes:

db_password = dbutils.secrets.get(scope="kv-prod-secrets", key="sql-db-pass")

46. Explain notebook workflows.

Execute modular child notebooks from an orchestrator notebook using dbutils.notebook.run() or configure multi-task dependency graphs using Databricks Workflows.


Section 4: Advanced SQL & Performance Optimization (Questions 47 to 61)

47. Find the latest record for each customer using window functions.

WITH RankedSales AS (
    SELECT 
        customer_id,
        transaction_id,
        net_amount,
        transaction_date,
        ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY transaction_date DESC) AS rn
    FROM enterprise_sales
)
SELECT customer_id, transaction_id, net_amount, transaction_date
FROM RankedSales
WHERE rn = 1;

48. Difference between ROW_NUMBER(), RANK() and DENSE_RANK().

Function Ranking Behavior on Ties (100, 100, 90) Number Sequence Output
ROW_NUMBER() Assigns strict sequential integers regardless of duplicate values. 1, 2, 3
RANK() Assigns identical rank to ties, but skips subsequent rank numbers. 1, 1, 3
DENSE_RANK() Assigns identical rank to ties without skipping subsequent numbers. 1, 1, 2

49. Delete duplicate records while keeping the latest.

WITH DuplicateCTE AS (
    SELECT 
        id,
        ROW_NUMBER() OVER (PARTITION BY email ORDER BY updated_at DESC) AS rn
    FROM customer_master
)
DELETE FROM DuplicateCTE WHERE rn > 1;

50. Find the second highest salary.

SELECT DISTINCT salary
FROM employee
ORDER BY salary DESC
OFFSET 1 ROWS FETCH NEXT 1 ROWS ONLY;

51. Difference between CTE and Temp Table.

  • CTE (WITH ... AS): Inline logical query expression scoped strictly to the execution of the immediate SQL statement. Not indexed or materialized.
  • Temp Table (#temp_table): Materialized table written physically to tempdb. Supports clustered/non-clustered indexing and persists across multiple statements within the database session.

52. Explain Clustered vs Non-Clustered Index.

  • Clustered Index: Physically sorts and stores the underlying data rows on disk according to the index key. A table can have only one clustered index.
  • Non-Clustered Index: A separate B-Tree structure containing the index key and a row locator pointer pointing back to the physical table data page.

53. How do you optimize a slow SQL query?

  1. Inspect the Actual Execution Plan to identify full Table Scans or Index Scans and replace them with Index Seeks.
  2. Eliminate non-SARGable functions wrapped around indexed WHERE clause columns.
  3. Update database statistics (UPDATE STATISTICS) and create covering indexes.

54. Write a running total query.

SELECT 
    customer_id,
    transaction_date,
    amount,
    SUM(amount) OVER (
        PARTITION BY customer_id 
        ORDER BY transaction_date 
        ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
    ) AS running_total
FROM account_transactions;

55. Difference between EXISTS and IN.

  • EXISTS: Uses Boolean short-circuit evaluation; terminates scanning as soon as the first matching record is found. Highly performant for subqueries against large tables.
  • IN: Compares the target column against a materialized list of values; can suffer performance degradation and NULL evaluation anomalies if subquery results contain NULLs.

56. Difference between UNION and UNION ALL.

  • UNION: Combines result sets and executes an implicit sort/hash deduplication step to remove identical rows.
  • UNION ALL: Appends result sets directly without deduplication overhead, offering significantly higher execution speed.

57. Write a MERGE statement.

MERGE INTO target_inventory AS T
USING source_feed AS S
ON T.sku_id = S.sku_id
WHEN MATCHED THEN
    UPDATE SET T.quantity = S.quantity, T.updated_at = CURRENT_TIMESTAMP
WHEN NOT MATCHED BY TARGET THEN
    INSERT (sku_id, quantity, updated_at) VALUES (S.sku_id, S.quantity, CURRENT_TIMESTAMP);

58. Explain execution plans.

An Execution Plan is the tree of physical operators chosen by the database query optimizer (e.g., Hash Match Join, Nested Loops, Index Seek, Stream Aggregate) displaying estimated and actual execution costs, row counts, and I/O overhead.


59. How do you identify blocking sessions?

Query sys.dm_exec_requests joined with sys.dm_os_waiting_tasks or execute sp_who2 to locate head blocker session IDs (blocking_session_id) holding exclusive locks.


60. Difference between DELETE, TRUNCATE and DROP.

Operation Command Type Logging & Performance Triggers & Rollback
DELETE DML Logs every row deletion individually; slower on large tables. Fires DELETE triggers; fully rollable within transaction.
TRUNCATE DDL Deallocates data pages with minimal logging; extremely fast. Does not fire triggers; resets IDENTITY seed to 1.
DROP DDL Deletes table structure, indexes, and all data permanently. Drops table metadata completely.

61. Explain normalization vs denormalization.

  • Normalization (3NF): Structuring relational tables to eliminate data redundancy and insertion/update anomalies.
  • Denormalization (Star Schema): Intentionally consolidating dimensional attributes into flattened analytical fact/dimension tables to reduce costly runtime JOIN operations in data warehouses.

Section 5: Enterprise Practical Engineering Challenges (Questions 62 to 76)

62. Design an incremental ETL pipeline for daily sales data.

Implement a Medallion Lakehouse pipeline using Databricks Auto Loader (cloudFiles) to ingest daily Parquet files from ADLS Gen2 landing into Bronze, followed by a windowed deduplication MERGE INTO into Silver.


63. How would you handle duplicate source records?

Apply a windowed partition ranking (ROW_NUMBER() OVER (PARTITION BY business_key ORDER BY ingestion_timestamp DESC)) inside the Silver CDC staging layer to isolate and retain only the latest valid record prior to merging.


64. How do you design an idempotent pipeline?

Ensure that running the pipeline multiple times over identical input data produces the exact same end state without duplicate inserts. Use deterministic primary keys combined with Delta Lake MERGE INTO or partition overwrites (replaceWhere).


65. Describe a production issue you resolved and your RCA.

  • Issue: A daily financial ingestion pipeline failed silently with NULL metrics downstream.
  • Root Cause Analysis (RCA): Upstream source system modified a column name (tx_amt -> transaction_amount) without notification.
  • Resolution: Enabled schema evolution (cloudFiles.schemaEvolutionMode = "addNewColumns") and configured automated schema drift alerts.

66. How would you process late-arriving data?

Use Structured Streaming watermarks (.withWatermark("event_timestamp", "48 hours")) for real-time aggregations, or route late batch events to their correct historical partition using dynamic partition overwrites.


67. How do you validate source vs target counts?

Implement an automated audit step comparing source file record declarations (expected_total_records) against actual loaded counts (df.count()), raising an alert or failing the pipeline if attrition exceeds 0%.


68. Design a metadata-driven framework.

Store ingestion rules (source_path, target_table, primary_keys, watermark_col) in an Azure SQL control database. An ADF Lookup activity reads this configuration table and iterates over a generic Databricks notebook activity using a ForEach loop.


69. How do you handle schema drift?

Leverage Delta Lake's option("mergeSchema", "true") during batch writes or Auto Loader's rescueDataColumn (_rescued_data) to safely capture unexpected data types without pipeline failure.


70. How would you process 1 TB of daily data efficiently?

Partition data by date (year/month/day), enforce multi-dimensional ZORDER BY indexing on frequently filtered IDs, right-size Spark cluster executors, and enable Adaptive Query Execution (AQE).


71. Design a retry strategy for failed pipelines.

Designing a resilient, enterprise-grade retry strategy requires a layered fault-tolerance architecture that distinguishes between transient network/infrastructure failures, permanent schema/data corruption errors, and poison records. A production retry strategy combines Exponential Backoff with Full Jitter, Dead-Letter Queue (DLQ) Quarantine, Idempotent Replay, and Automated Circuit Breakers.


1. End-to-End Enterprise Retry & Fault-Tolerance Architecture

graph TD
    A[Ingestion / Transformation Pipeline Triggered] --> B{Execution Attempt}
    B -->|Success| C[Commit Transaction & Advance Watermark]
    B -->|Failure| D[Error Classification Engine]

    D -->|Permanent Error: Syntax / Schema Mismatch / Auth| E[Terminal Failure: Route to Alerting & Incident Queue]
    D -->|Poison Data Record: Malformed JSON / Overflow| F[Row-Level Quarantine: Dead-Letter Queue DLQ /bad-records/]
    F --> C
    D -->|Transient Error: HTTP 429/503 / Throttling / Lock| G{Attempt < Max Retries?}

    G -->|Yes| H["Compute Sleep: Backoff * 2^attempt + Jitter"]
    H --> I[Wait Sleep Interval]
    I --> B
    G -->|No - Exhausted| J[Trip Circuit Breaker & Raise Critical Page]

2. Step-by-Step Implementation Framework

Step 1: Error Taxonomy & Triage Decision Matrix

Not all pipeline failures should be retried. Retrying permanent errors wastes compute resources and can exacerbate database locks.

Error Classification Examples Action / Retry Strategy
Transient Errors Network timeout, HTTP 429 Too Many Requests, HTTP 503 Service Unavailable, Azure SQL connection pool exhaustion, temporary storage lock. Retry Automatically using Exponential Backoff + Full Jitter (up to 3–5 attempts).
Poison Records Corrupted CSV rows, malformed JSON string, numeric overflow (Decimal(18,2) receiving 999999999999999999.99), invalid timestamp format. Skip & Quarantine Row to Dead-Letter Queue (/quarantine/dlq/); continue pipeline execution for remaining healthy records.
Permanent Errors SQL syntax error (SyntaxError), missing authorization/RBAC permission (403 Forbidden), missing source table (404 Not Found), incompatible Delta schema evolution. Fail Fast immediately (0 retries); raise critical PagerDuty/Teams alert and halt downstream execution.

Step 2: Exponential Backoff with Full Jitter Algorithm

When hundreds of concurrent pipeline activities fail due to a downstream bottleneck (e.g., Snowflake or Azure SQL server CPU spike), standard static retries create a Thundering Herd Problem.

  • Standard Exponential Backoff Formula:
    $$\text{Delay} = \text{BaseDelay} \times 2^{\text{Attempt}}$$

  • Full Jitter Randomized Formula (Enterprise Best Practice):
    $$\text{Delay}_{\text{Jitter}} = \text{Uniform}\left(0, \, \text{BaseDelay} \times 2^{\text{Attempt}}\right)$$


Step 3: Production Implementations Across Tools
A. Azure Data Factory (ADF) Activity Retry & Fault Tolerance Configuration

In ADF ARM / JSON templates, configure activity-level retries alongside row-level fault tolerance:

{
  "name": "Copy_Ingest_Bronze_To_Silver",
  "type": "Copy",
  "policy": {
    "timeout": "02:00:00",
    "retry": 3,
    "retryIntervalInSeconds": 60,
    "secureOutput": false,
    "secureInput": false
  },
  "typeProperties": {
    "source": { "type": "ParquetSource" },
    "sink": { "type": "ParquetSink" },
    "faultTolerance": {
      "redirectIncompatibleRowSettings": {
        "linkedServiceName": {
          "referenceName": "LS_ADLS_Gen2_Quarantine",
          "type": "LinkedServiceReference"
        },
        "path": "quarantine/dlq-copy-errors/"
      }
    }
  }
}
B. Apache Airflow DAG Task Retry with Exponential Backoff

In Airflow orchestration, configure operators with retry_exponential_backoff=True:

from datetime import datetime, timedelta
from airflow import DAG
from airflow.providers.microsoft.azure.operators.data_factory import AzureDataFactoryRunPipelineOperator

default_args = {
    'owner': 'data_engineering',
    'retries': 4,
    'retry_delay': timedelta(seconds=30),
    'retry_exponential_backoff': True,
    'max_retry_delay': timedelta(minutes=15),
    'email_on_retry': False,
    'email_on_failure': True
}

with DAG(
    dag_id='enterprise_lakehouse_ingestion',
    default_args=default_args,
    schedule_interval='0 2 * * *',
    start_date=datetime(2026, 1, 1),
    catchup=False
) as dag:

    run_adf_pipeline = AzureDataFactoryRunPipelineOperator(
        task_id='trigger_adf_bronze_ingestion',
        factory_name='adf-prod-analytics',
        resource_group_name='rg-data-prod',
        pipeline_name='PL_Ingest_Sales_Orders'
    )
C. Production PySpark Decorator (@retry_with_jitter) for Resilient Spark Tasks

For API interactions or Hive metastore queries within Databricks notebooks:

import time
import random
import functools
from py4j.protocol import Py4JJavaError

def retry_with_jitter(max_retries=3, base_delay=5, max_delay=120, exceptions=(Exception,)):
    """
    Enterprise decorator implementing Exponential Backoff with Full Jitter.
    """
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            attempt = 0
            while True:
                try:
                    return func(*args, **kwargs)
                except exceptions as e:
                    attempt += 1
                    if attempt > max_retries:
                        print(f"[CRITICAL] Operation failed after {max_retries} retries: {str(e)}")
                        raise e

                    # Calculate Exponential Backoff with Full Jitter
                    calculated_delay = min(max_delay, base_delay * (2 ** attempt))
                    sleep_duration = random.uniform(0, calculated_delay)
                    print(f"[WARN] Attempt {attempt}/{max_retries} failed ({str(e)}). Retrying in {sleep_duration:.2f}s...")
                    time.sleep(sleep_duration)
        return wrapper
    return decorator

# Usage inside Databricks Lakehouse Pipeline
@retry_with_jitter(max_retries=4, base_delay=10, exceptions=(Py4JJavaError, ConnectionError))
def write_silver_delta_table(df, target_path):
    df.write.format("delta").mode("append").save(target_path)

Step 4: Dead-Letter Queue (DLQ) & Quarantine Architecture

When ingesting files containing malformed records, never abort a multi-hour batch job over a few corrupted rows.

  1. Auto Loader (cloudFiles) Bad Records Capture: Configure Databricks Auto Loader to isolate invalid records into a dedicated quarantine path while committing valid records to Bronze: python df = (spark.readStream .format("cloudFiles") .option("cloudFiles.format", "json") .option("cloudFiles.schemaLocation", "/mnt/schemas/orders_checkpoint") .option("badRecordsPath", "/mnt/lakehouse/quarantine/orders_bad_records/") .load("/mnt/raw/orders/"))

  2. Automated DLQ Triage Alert: A lightweight hourly event monitor checks quarantine/orders_bad_records/. If record count $> 0$, it triggers a Teams webhook with the sample malformed payload.


Step 5: Guaranteeing Idempotency on Replay

A retry strategy is dangerous and invalid if re-executing a partially failed step duplicates data. Every step must be strictly Idempotent ($f(f(x)) = f(x)$):

  • Avoid APPEND on Raw Files: If an append fails midway, retrying duplicates records.
  • Use Atomic MERGE INTO (Upsert): sql MERGE INTO silver_orders AS target USING stage_orders_batch AS source ON target.order_id = source.order_id AND target.order_date = source.order_date WHEN MATCHED THEN UPDATE SET * WHEN NOT MATCHED THEN INSERT *;

  • Watermark Rollback Safety: Only advance the pipeline watermark table (LastProcessedModifiedDate) after the entire transaction commits successfully. If Attempt #2 succeeds after Attempt #1 fails, the watermark advances exactly once.


72. How do you implement audit logging?

Enrich every Bronze and Silver record with metadata columns (_ingestion_batch_id, _pipeline_run_id, _ingested_at_utc) and log pipeline execution metrics to a central Unity Catalog audit table.


73. How would you archive historical data?

Configure Azure Storage Lifecycle Management policies to transition historical partitions older than 90 days to the Cool tier and older than 365 days to the Archive tier.


74. How do you estimate cluster sizing for a new workload?

Estimate aggregate cluster RAM to be 2x to 3x the size of the uncompressed dataset partition being shuffled in memory. Size cores to allocate ~200MB of partition data per task thread.


75. How would you ensure data quality before loading Gold tables?

Implement automated quality assertion rules using Delta Live Tables (DLT) Expectations (EXPECT (net_amount >= 0) ON VIOLATION DROP ROW) or Great Expectations prior to promoting tables to Gold.


76. Design a disaster recovery (DR) strategy for a multi-region Azure Lakehouse.

  1. Storage Replication: Use Read-Access Geo-Redundant Storage (RA-GRS) for ADLS Gen2 containers.
  2. Infrastructure as Code (IaC): Maintain all ADF pipelines, Databricks clusters, and Unity Catalog permissions in Terraform scripts deployable to a secondary disaster recovery region within minutes.
  3. Metadata & Catalog Sync: Leverage Unity Catalog Delta Sharing and cross-region metadata replication to ensure business continuity across paired Azure regions.
lock

This content is reserved for Premium Members.

Upgrade to Premium

Entity Details

Create New Item

help

Submit Technical Query

Have a question or run into an issue? Describe it below, upload an optional screenshot, and our engineering team will answer it!

image Attach image (optional)

Submit Feedback

build Free Developer Utility Free Tool
gavel

Privacy & Legal Disclaimer

1. Client-Side Browser Processing

All utility tools on DeepEngineerHub (including Image to PDF, Text Formatters, JSON Converters, and Encryptors) execute 100% locally within your client browser using WebAssembly and JavaScript. No uploaded images, text, or documents are transmitted, collected, or stored on remote servers.

2. Limitation of Liability ("As-Is" Provision)

Tools and services are provided free of charge for convenience and educational purposes "as-is" without warranties of any kind. DeepEngineerHub shall not be held liable for any data loss, formatting inconsistencies, or indirect damages resulting from tool usage.

3. Open Source & Third-Party Software

Certain utilities utilize open-source client libraries (such as jsPDF, Mermaid.js, Pyodide) licensed under MIT, Apache, or BSD open licenses. All intellectual property remains with their respective copyright holders.