AWSDeveloper AssociateDVA-C02AWS CertificationServerlessLambdaDynamoDBinterview prep

AWS Certified Developer Associate (DVA-C02) 2025: Complete Exam Guide for Developers

V
Vibe Interviews Team
13 min read
AWS Certified Developer Associate (DVA-C02) 2025: Complete Exam Guide for Developers

An interviewer asks: "Your Lambda function occasionally fails with timeout errors. How do you debug this in production?" Most candidates freeze or suggest generic logging. The interviewer wants specifics: CloudWatch Logs Insights, X-Ray tracing, custom metrics, dead letter queues, and concurrent execution analysis.

The AWS Certified Developer Associate (DVA-C02) exam tests whether you can actually build, deploy, and debug applications on AWS—not just know service names. Here's your complete guide to passing.

What is DVA-C02?

The Developer Associate certification validates your ability to develop, deploy, and debug cloud-based applications using AWS services. It's designed for software developers with 1+ years of AWS experience.

Exam Details:

  • 65 questions (50 scored + 15 unscored)
  • 130 minutes
  • Passing score: 720/1000
  • Cost: $150 USD
  • Prerequisites: None (but development experience recommended)

Exam Domains:

  1. Development with AWS Services (32%)
  2. Security (26%)
  3. Deployment (24%)
  4. Troubleshooting and Optimization (18%)

Who Should Take This Certification?

You're a good fit if you:

  • Write code professionally (any language)
  • Have deployed applications to production
  • Understand APIs, databases, and version control
  • Want to build serverless or cloud-native applications

Career paths:

  • Cloud Developer ($110k-150k)
  • Full-Stack Developer (AWS-focused) ($120k-160k)
  • DevOps Engineer ($130k-170k)

Domain 1: Development with AWS Services (32%)

Lambda: The Core of Serverless

Scenario: "Build an API that resizes images uploaded to S3."

Architecture:

S3 Bucket (images-upload)
  → Trigger: S3 Event Notification
  → Lambda Function (resize-image)
    - Runtime: Python 3.11
    - Memory: 1024 MB (faster execution)
    - Timeout: 60 seconds
    - Environment Variables: DEST_BUCKET=images-resized
  → S3 Bucket (images-resized)

Lambda Function (Python + Pillow):

import boto3
import os
from PIL import Image
import io

s3 = boto3.client('s3')

def lambda_handler(event, context):
    # Get bucket and object key from event
    bucket = event['Records'][0]['s3']['bucket']['name']
    key = event['Records'][0]['s3']['object']['key']

    # Download image
    response = s3.get_object(Bucket=bucket, Key=key)
    image_data = response['Body'].read()

    # Resize image
    image = Image.open(io.BytesIO(image_data))
    image.thumbnail((800, 600))

    # Save to buffer
    buffer = io.BytesIO()
    image.save(buffer, 'JPEG')
    buffer.seek(0)

    # Upload to destination bucket
    dest_bucket = os.environ['DEST_BUCKET']
    s3.put_object(
        Bucket=dest_bucket,
        Key=f'resized-{key}',
        Body=buffer,
        ContentType='image/jpeg'
    )

    return {'statusCode': 200, 'body': 'Image resized'}

Key Lambda Concepts You Must Know:

Execution Role:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["s3:GetObject"],
      "Resource": "arn:aws:s3:::images-upload/*"
    },
    {
      "Effect": "Allow",
      "Action": ["s3:PutObject"],
      "Resource": "arn:aws:s3:::images-resized/*"
    },
    {
      "Effect": "Allow",
      "Action": ["logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents"],
      "Resource": "arn:aws:logs:*:*:*"
    }
  ]
}

Lambda Layers:

  • Package dependencies separately (like Pillow library)
  • Reuse across multiple functions
  • Max 5 layers per function, 250MB unzipped total

Concurrency:

  • Unreserved: Default pool (1000 per region)
  • Reserved: Guarantee capacity, prevents throttling
  • Provisioned: Pre-warm instances, eliminates cold starts (use for < 1s latency requirements)

Environment Variables:

  • Configure settings without code changes
  • Can encrypt with KMS
  • Max 4KB total

DynamoDB: NoSQL Database

Scenario: "Design a table for a social media app where users post messages and follow each other."

Anti-Pattern (multiple tables):

Users Table (UserId, Name, Email)
Posts Table (PostId, UserId, Content, Timestamp)
Follows Table (FollowerId, FollowedId)

Problems: Multiple queries, slow, expensive

Single-Table Design (recommended):

PK: USER#123          SK: PROFILE           → User profile
PK: USER#123          SK: POST#2025-01-15   → User's post
PK: USER#123          SK: FOLLOWS#USER#456  → Following relationship
PK: POST#2025-01-15   SK: POST#2025-01-15   → Post by timestamp (GSI)

Why this works:

  • Get user + recent posts: Query PK="USER#123", SK begins_with "POST"
  • Get followers: Query PK="USER#123", SK begins_with "FOLLOWS"
  • Get recent posts: Query GSI on SK (timestamp)
  • One query instead of three → faster, cheaper

DynamoDB Capacity Modes:

On-Demand (pay per request):

  • No capacity planning needed
  • Good for: unpredictable traffic, new apps, dev/test
  • Cost: $1.25 per million reads, $1.25 per million writes

Provisioned:

  • Set Read Capacity Units (RCU) and Write Capacity Units (WCU)
  • Auto-scaling available
  • Good for: predictable traffic, cost optimization
  • Cost: $0.00065 per RCU-hour, $0.00065 per WCU-hour
  • 55% cheaper than on-demand for steady traffic

DynamoDB Streams:

DynamoDB Table (Order created)
  → Stream (captures INSERT event)
  → Lambda (send confirmation email)
  → SES (email service)

Use cases: Data replication, notifications, aggregations, audit logs

API Gateway: Building APIs

Scenario: "Create a REST API for user management with authentication."

Architecture:

Client → API Gateway
  - POST /users (create user)
  - GET /users/{id} (get user)
  - PUT /users/{id} (update user)
  - DELETE /users/{id} (delete user)
  ↓
Lambda Functions (user-crud)
  ↓
DynamoDB (users table)

Authentication Options:

IAM Authentication:

  • Use AWS credentials (access key + secret)
  • Good for: service-to-service, AWS SDK clients
  • Client signs requests with SigV4

Lambda Authorizer (Custom):

// Lambda authorizer validates JWT token
exports.handler = async (event) => {
  const token = event.authorizationToken;

  // Validate token (JWT, OAuth, custom)
  const isValid = validateToken(token);

  if (isValid) {
    return generatePolicy('user123', 'Allow', event.methodArn);
  }
  return generatePolicy('user123', 'Deny', event.methodArn);
};

Cognito Authorizer:

  • Managed user pools, OAuth 2.0
  • Good for: mobile apps, web apps
  • No Lambda needed for basic auth

API Gateway Features:

Request/Response Transformation:

// Transform request
{
  "name": "$input.json('$.userName')",
  "timestamp": "$context.requestTime"
}

Caching:

  • Enable per-stage caching (300s - 3600s TTL)
  • Cache API responses, reduce backend calls
  • Pay per GB cached ($0.02/hour per GB)

Throttling:

  • Default: 10,000 RPS burst, 5,000 RPS steady
  • Set per-method limits for critical endpoints
  • Returns 429 Too Many Requests when exceeded

Domain 2: Security (26%)

IAM Policies in Practice

Question: "Lambda needs to read from DynamoDB table 'Orders' and write to S3 bucket 'receipts'."

Inline Policy (bad - hard to manage):

{
  "Statement": [{
    "Effect": "Allow",
    "Action": "*",
    "Resource": "*"
  }]
}

Problem: Too broad, violates least privilege

Correct Policy:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "ReadOrders",
      "Effect": "Allow",
      "Action": [
        "dynamodb:GetItem",
        "dynamodb:Query",
        "dynamodb:Scan"
      ],
      "Resource": "arn:aws:dynamodb:us-east-1:123456789:table/Orders"
    },
    {
      "Sid": "WriteReceipts",
      "Effect": "Allow",
      "Action": "s3:PutObject",
      "Resource": "arn:aws:s3:::receipts/*"
    }
  ]
}

Policy Best Practices:

  • Use specific actions (not *)
  • Limit resources with ARNs
  • Add Sid for clarity
  • Use managed policies when possible

Secrets Manager vs Parameter Store

"Store database password securely for Lambda."

Parameter Store (Free Tier):

  • 10,000 parameters (Standard)
  • No automatic rotation
  • Use for: config values, non-sensitive data
  • Cost: Free for Standard, $0.05/10k API calls for Advanced

Secrets Manager ($):

  • Automatic rotation (Lambda rotates passwords)
  • Integration with RDS, Redshift, DocumentDB
  • Use for: database credentials, API keys
  • Cost: $0.40/secret/month + $0.05/10k API calls

When to use each:

  • Config values (API endpoints, feature flags): Parameter Store
  • Database passwords, API keys: Secrets Manager
  • Frequently rotated secrets: Secrets Manager

KMS Encryption

Scenario: "Encrypt data in S3 and decrypt in Lambda."

S3 Server-Side Encryption:

# Upload with SSE-KMS
s3.put_object(
    Bucket='my-bucket',
    Key='sensitive-data.txt',
    Body='secret content',
    ServerSideEncryption='aws:kms',
    SSEKMSKeyId='arn:aws:kms:us-east-1:123:key/abc'
)

Lambda needs KMS permissions:

{
  "Effect": "Allow",
  "Action": ["kms:Decrypt"],
  "Resource": "arn:aws:kms:us-east-1:123:key/abc"
}

Domain 3: Deployment (24%)

CI/CD Pipeline with AWS CodePipeline

Scenario: "Automate Lambda deployment from Git push to production."

Pipeline Stages:

1. Source Stage (CodeCommit/GitHub)
   - Trigger on push to main branch

2. Build Stage (CodeBuild)
   - Run unit tests
   - Package Lambda function
   - Create deployment artifact (.zip)

3. Deploy Stage (CodeDeploy)
   - Deploy to Lambda with alias
   - Use canary deployment (10% traffic → 100%)

4. Test Stage (optional)
   - Run integration tests
   - Manual approval gate

buildspec.yml (CodeBuild):

version: 0.2
phases:
  install:
    runtime-versions:
      python: 3.11
  pre_build:
    commands:
      - pip install -r requirements.txt -t .
      - python -m pytest tests/
  build:
    commands:
      - zip -r function.zip .
artifacts:
  files:
    - function.zip
    - appspec.yml

appspec.yml (CodeDeploy):

version: 0.0
Resources:
  - MyFunction:
      Type: AWS::Lambda::Function
      Properties:
        Name: my-function
        Alias: live
        CurrentVersion: 1
        TargetVersion: 2
Hooks:
  - BeforeAllowTraffic: "PreTrafficHook"
  - AfterAllowTraffic: "PostTrafficHook"

Deployment Strategies:

All-at-once:

  • Deploy to all instances immediately
  • Fastest, but downtime if failure
  • Use for: dev/test environments

Canary:

  • 10% of traffic → new version
  • Wait, monitor errors
  • If good → shift 100%
  • Use for: production, gradual rollout

Linear:

  • Shift traffic in increments (10% every 10 minutes)
  • Slower, safest
  • Use for: critical applications

CloudFormation: Infrastructure as Code

Deploy complete serverless API:

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31

Resources:
  MyApi:
    Type: AWS::Serverless::Api
    Properties:
      StageName: prod

  MyFunction:
    Type: AWS::Serverless::Function
    Properties:
      Handler: index.handler
      Runtime: python3.11
      CodeUri: ./function.zip
      Events:
        ApiEvent:
          Type: Api
          Properties:
            Path: /users
            Method: get
            RestApiId: !Ref MyApi
      Environment:
        Variables:
          TABLE_NAME: !Ref MyTable

  MyTable:
    Type: AWS::DynamoDB::Table
    Properties:
      TableName: users
      AttributeDefinitions:
        - AttributeName: userId
          AttributeType: S
      KeySchema:
        - AttributeName: userId
          KeyType: HASH
      BillingMode: PAY_PER_REQUEST

Deploy:

sam build
sam deploy --guided

Domain 4: Troubleshooting (18%)

CloudWatch Logs Insights

Scenario: "Find all Lambda errors in last hour."

Query:

fields @timestamp, @message
| filter @message like /ERROR/
| sort @timestamp desc
| limit 100

Find slow requests:

fields @timestamp, @duration
| filter @duration > 1000
| stats avg(@duration), max(@duration), count(*) by bin(5m)

Track API endpoints:

fields @timestamp, request.path, response.statusCode
| filter response.statusCode >= 400
| stats count(*) by request.path

X-Ray: Distributed Tracing

Enable X-Ray in Lambda:

from aws_xray_sdk.core import xray_recorder
from aws_xray_sdk.core import patch_all

# Patch AWS SDK and HTTP requests
patch_all()

@xray_recorder.capture('process_order')
def process_order(order_id):
    # Get order from DynamoDB
    order = dynamodb.get_item(TableName='Orders', Key={'id': order_id})

    # Process payment
    payment = process_payment(order['amount'])

    # Send email
    send_email(order['email'])

    return {'status': 'success'}

X-Ray Shows:

  • Total latency: 2.5s
    • DynamoDB GetItem: 50ms
    • process_payment: 2.2s ⚠️ (bottleneck!)
    • send_email: 250ms

Fix: Optimize payment processing or run async

Lambda Troubleshooting

Common Issues:

1. Timeout (max 15 minutes):

Symptoms: Function stops mid-execution
Solution:
  - Increase timeout (if needed)
  - Or break into multiple functions with Step Functions
  - Or move long-running tasks to EC2/ECS

2. Out of Memory:

Symptoms: "Runtime exited with error: signal: killed"
Solution:
  - Increase memory allocation
  - Profile code to find memory leaks
  - Process data in chunks, not all at once

3. Cold Starts:

Symptoms: First request slow (1-5 seconds)
Solutions:
  - Use Provisioned Concurrency (costs more)
  - Reduce package size
  - Move dependencies to Lambda layers
  - Keep functions warm (scheduled CloudWatch Event)

4. Throttling:

Symptoms: 429 TooManyRequestsException
Causes:
  - Hit concurrent execution limit (1000/region)
  - Reserved concurrency set too low
Solutions:
  - Increase reserved concurrency
  - Request limit increase
  - Implement exponential backoff in client

Hands-On Labs (Must Do)

Week 1-2: Serverless Basics

  1. Create Lambda function triggered by S3 upload
  2. Build REST API with API Gateway + Lambda + DynamoDB
  3. Implement Lambda authorizer for authentication

Week 3-4: CI/CD 4. Set up CodeCommit repository, push code 5. Create CodeBuild project with tests 6. Build complete CI/CD pipeline with CodePipeline

Week 5-6: Advanced 7. Implement X-Ray tracing in Lambda 8. Create CloudWatch dashboard and alarms 9. Deploy serverless app with SAM/CloudFormation

Week 7-8: Practice 10. Take practice exams 11. Review weak areas 12. Hands-on debugging scenarios

Practice Questions

Q1: Your Lambda function needs to query DynamoDB and call external API. It times out. What's the BEST solution?

A) Increase Lambda timeout to 15 minutes B) Increase Lambda memory C) Use Step Functions to split into two Lambdas D) Move to EC2

Answer: C - Best practice is to break into separate functions. External API call is the likely bottleneck—handle async.

Q2: Your API Gateway endpoint returns 502 Bad Gateway. What's the likely cause?

A) Lambda function timeout B) API Gateway throttling C) DynamoDB throttling D) IAM permission denied

Answer: A - 502 typically means Lambda timed out or returned malformed response. Check CloudWatch Logs.

Q3: You need to deploy a Lambda function with zero downtime. Which deployment type?

A) All-at-once B) Canary C) Linear D) Blue/Green

Answer: B or C - Both provide zero downtime. Canary is faster (10% → 100%), Linear is safer (gradual increase).

Exam Tips

Before Exam:

  • Review Lambda limits: 15min timeout, 10GB memory, 6MB response size
  • Memorize DynamoDB capacity calculations
  • Know CodeDeploy deployment strategies
  • Understand X-Ray, CloudWatch Logs Insights queries

During Exam:

  • Watch for "BEST" solution keywords
  • Eliminate obviously wrong answers
  • Flag uncertain questions, return later
  • Code questions test logic, not syntax

Common Traps:

  • "Lambda function fails after 15 minutes" → Can't increase timeout, use Step Functions
  • "Need sub-second latency" → Use Provisioned Concurrency, not Reserved
  • "Debug production Lambda" → X-Ray, not just CloudWatch Logs

Study Resources

Official AWS:

  • AWS Certified Developer Study Guide (Nick Alteen)
  • AWS Skill Builder: Developer path
  • AWS Hands-On Tutorials (free)

Practice Exams:

  • Tutorials Dojo DVA-C02 ($15)
  • Whizlabs Developer Associate ($20)
  • AWS Official Practice Exam ($40)

Hands-On:

  • Build real projects (portfolio + exam prep)
  • Free Tier: Lambda, DynamoDB, API Gateway
  • GitHub: Serverless examples, SAM templates

After Certification

Next steps:

  • Build production-ready serverless apps
  • Contribute to AWS open-source projects
  • Consider DevOps Engineer or Solutions Architect Professional

Keep skills sharp:

  • Follow AWS Blog for new features
  • Attend AWS re:Invent sessions (YouTube)
  • Build side projects with latest AWS services

Ready to practice? Use our AWS Developer Associate Interview Prep with scenario-based questions and hands-on coding challenges.

V

Vibe Interviews Team

Part of the Vibe Interviews team, dedicated to helping job seekers ace their interviews and land their dream roles.

Ready to Practice Your Interview Skills?

Apply what you've learned with AI-powered mock interviews. Get instant feedback and improve with every session.

Start Practicing Now

Continue Reading