This document provides a comprehensive technical breakdown of two key features you implemented: QR Code Generation Module and Tinyslash Precheck URL Engine. Use these details to demonstrate your full-stack engineering skills, security awareness, and system design capabilities during your interview.
Goal: specific, high-customizability QR code generation service that supports both static and dynamic QR codes with integrated analytics. Role: Full Stack implementation (Frontend Canvas logic + Backend Storage & Analytics).
The core generation happens client-side to ensure instant preview performance without stressing the server.
- Library: Used
qrcode(node-qrcode) for calculating the QR matrix (modules). - Rendering Engine: Built a custom HTML5
Canvasrenderer (QRCodeGenerator.tsx).- Why Canvas? Allows pixel-perfect manipulation for gradients, custom eye shapes, and logo embedding which isn't possible with standard SVG/image libraries.
- Customization Logic:
- Patterns: Implemented algorithms to draw modules as squares, dots, diamonds, stars, or fluid shapes.
- Frames: Custom drawing logic for frames (e.g., "Scan Me", "Desi Mandala", "Floral") wrapping the QR code.
- Gradients: Linear and Radial gradient application on the QR modules using standard 2D Context API.
- Logo Embedding: Asynchronous image loading with auto-scaling to ensure the logo doesn't break the QR error correction threshold.
- Service:
QrCodeService.java - Storage: MongoDB (
QrCodedocument). Stores the configuration (colors, style IDs), not just the image, effectively acting as a "Template" system. - Dynamic Links:
- Dynamic QR codes point to a comprehensive short URL (
/q/{shortCode}). - This allows the destination URL to be changed after printing the QR code.
- Dynamic QR codes point to a comprehensive short URL (
- Validation: Integrated with
SecurityServiceto scan destination URLs before generating the QR code.
Challenge 1: Scannability vs. Customization
- Problem: Adding logos and changing shapes can make QR codes unreadable.
- Solution: Implemented high-level Error Correction (Level H - 30% recovery). enforced "Safe Zones" around the logo and Position Detection Patterns (the three corner eyes) to ensure they are never obscured by custom designs.
Challenge 2: Performance with High-Res Canvas
- Problem: Rerendering complex mandala frames on every keystroke caused UI lag.
- Solution: Optimized the standard
useEffecthooks to only redraw changed layers.
"I built a renderer that iterates through the QR matrix. Instead of just printing black squares, I check neighbors to determine if I should draw a connected 'fluid' shape or a standalone 'dot', and apply a composite operation to mask the logo area."
Goal: A multi-layered security engine to prevent abuse (phishing, malware, scams) by analyzing URLs in real-time before they are shortened. Role: Backend Security Engineer.
The engine (SecurityService.java) uses a scoring system rather than a simple binary pass/fail. Each check adds to a RiskScore.
- 0-44: Safe (ALLOW)
- 45-74: Suspicious (WARN - User sees an interstitial warning)
- 75+: Critical (BLOCK - Creation denied)
Before even checking the domain, we validate the syntax to prevent technical exploits.
- Null Byte Injection: Blocks
%00to prevent buffer overflow attacks on downstream systems. - Double Encoding: Decodes URLs recursively (up to 2 layers) to find hidden payloads.
- Invisible & Control Chars: Blocks zero-width spaces or RTLO (Right-to-Left Override) characters often used to disguise filenames (e.g.,
exe.docshowing ascod.exe). - Private IP Blocking: Rejects
127.0.0.1,192.168.x.xto prevent Server-Side Request Forgery (SSRF).
- TLD Risk Scoring: Assigns risk based on Top-Level Domain abuse history.
.tk,.ml,.ga(Freenom domains) = 100 points (Instant BLOCK)..xyz= 20 points (Medium risk)..gov.in,.edu.in= -100 points (Whitelisted).
- Velocity Checks: Tracks how many links a domain has generated in the last hour. Sudden spikes trigger a "High Velocity" flag.
Designed specifically for the Indian market context.
- Tokenization: Splits distinct parts of the URL (e.g.,
sbi-kyc-update). - Keyword Matching: Checks against protected brands like "SBI", "HDFC", "Paytm".
- Contextual Escalation:
- If "SBI" is found + "KYC" or "Update" keywords -> Critical Risk.
- If "SBI" is found alone -> Low Risk (could be a news article).
- Homoglyph Detection: Identifies character substitution attacks (e.g.,
paytmn.comvspaytm.com, org00gle.com).
Analyzes the intent of the URL words.
- Urgency: "expire", "immediately", "24hours".
- Greed: "lottery", "winner", "cashback".
- Authority: "govt", "official", "verify".
- Combination Logic:
Urgency + Financial Keyword= High Probability of Phishing.
Challenge 1: False Positives (Blocking Legitimate Users)
- Problem: Blocking a student sharing an "SBI application form" link.
- Solution: Implemented the "Contextual Escalation" logic. We don't block brands. We block
Brand + Threat/Urgency. We also added an "Allowlist" for official domains (sbi.co.in) that bypasses all checks.
Challenge 2: Performance Latency
- Problem: Running complex regex and database lookups on every link creation slows down the API.
- Solution:
- Fail-Fast: Structural checks run first (microseconds). If they fail, we abort before DB lookups.
- Caching: Domain reputation is cached.
- Async Processing: (Optional mention) Logging and non-critical analytics can be pushed to async events.
"I designed the preCheckUrl method to return a SecurityDecision object containing a risk score and a breakdown. It's not just true/false; it allows the frontend to show specific warnings like 'This link looks like a phishing attempt' vs 'This file type is blocked'."
Use these templates to answer "Tell me about a time when..." questions.
Question: "Tell me about a challenging UI component you built."
- Situation: We needed a QR code generator that wasn't just black-and-white static images but supported extensive customization (gradients, logos, frames) for our premium users.
- Task: My task was to build a React component that could render these complex styles in real-time as the user adjusted sliders, without lagging the browser.
- Action:
- I chose the HTML5 Canvas API over SVGs for better pixel-level manipulation performance.
- I encountered a performance bottleneck where re-rendering the complex "Mandala" frames on every state change caused a 500ms delay.
- I refactored the component to use a "Layered Architecture": one canvas for the QR code (static) and another transparent canvas for the frame/logo (dynamic). I only re-rendered the layer that actually changed.
- Result: This improved rendering speed by 80% (under 100ms), giving a smooth 60fps feel during customization. It became one of our most popular premium features.
Question: "Tell me about a time you had to balance security with user experience."
- Situation: Our initial version of the "Phishing Blocker" was too aggressive. It started blocking legitimate users sharing links to banking new articles because they contained words like "SBI" and "Update".
- Task: I needed to reduce the False Positive rate while keeping the block rate for actual scams high.
- Action:
- I moved from a Binary (Pass/Fail) model to a Weighted Scoring System (0-100).
- I implemented "Contextual Escalation": A brand name alone adds only 10 risk points. A brand name plus an urgency keyword ("immediately") adds 50 points.
- I also added a "Whitelisted Domain" check that bypasses scoring for verified official domains like
sbi.co.in.
- Result: We reduced user complaints about blocked links by 95% while catching approximately 200+ actual phishing attempts in the first week.
If asked why you chose certain technologies:
- Why for QR Codes?
- QR configurations are highly variable (some have frames, some have logos, some have gradient settings). A JSON-like Document store is perfect for storing these "Config Objects" without complex SQL migrations every time we add a new style property.
- Why for Security Logs?
- Security events are write-heavy and unstructured. MongoDB handles high write throughput well for logging millions of scan events.
- Problem: Checking Domain Reputation requires a database query. Doing this on every link creation introduces latency.
- Solution:
- We cache the "Risk Score" of a domain in Redis for 1 hour.
- Common domains extensions (like
.com) are cached as "Neutral" to skip TLD lookups. - User Trust Levels are cached to instantly whitelist power users.
- The
SecurityServiceis stateless. - Horizontal Scaling: As traffic grows, we can spin up more instances of the
url-service. Since the logic is CPU-bound (Regex/Parsing), it scales linearly with more compute resources. - Async Processing: We can move the logging of the security decision to a Kafka/RabbitMQ queue so the user gets their response immediately, while we store the analytics in the background.
"If I had more time, here is what I would build next:"
- ML-Based Phishing Detection:
- Move from Regex heuristic rules to a trained Machine Learning model (Random Forest or BERT) that learns from the blocked URL distinct features over time.
- Vector Output for QRs:
- Implement SVG generation on the server-side for print-quality (CMYK) QR codes for business cards/billboards.
- Real-time Browsing Protection:
- Build a browser extension that checks the URL against our
Precheck Enginewhen a user visits a link, not just when they shorten it.
- Build a browser extension that checks the URL against our
A complete view of the files you worked on for this feature:
Frontend (React/TypeScript)
tinyslash-frontend/src/
├── components/
│ ├── QRCodeGenerator.tsx # [Core] The Canvas Rendering Engine
│ ├── dashboard/
│ │ ├── QRManageSection.tsx # Dashboard view for managing QRs
│ │ └── modals/
│ │ └── QRPreviewModal.tsx # Preview modal before download
│ └── QRAnalytics.tsx # Charts specific to QR usage
├── pages/
│ ├── QrCodesPage.tsx # Main listing page
│ ├── QREditPage.tsx # The "Builder" UI with sliders/color pickers
│ └── QRAnalyticsPage.tsx # Detailed analytics view
└── services/
└── api.ts # API calls to backend endpoints
Backend (Java Spring Boot)
tinyslash-backend/url-service/src/main/java/com/urlshortener/
├── model/
│ └── QrCode.java # MongoDB Document Schema (The Config Object)
├── controller/
│ ├── QrCodeController.java # REST API (CRUD operations)
│ └── QrRedirectController.java # Handles the actual scan redirection
├── service/
│ └── QrCodeService.java # Business Logic (Storage + Validation)
└── repository/
└── QrCodeRepository.java # Data Access Layer
This is the narrative you should use when walking the interviewer through the feature.
Instead of storing a generated PNG image in the database (which is heavy and hard to edit), I designed the QrCode model to store the Configuration State.
- Key Fields:
foregroundColor,backgroundColor,frameStyle,logoUrl,patternType(dots, square, etc.). - Benefit: This allows "Dynamic Editing". A user can change the color of a QR code after it has been generated without breaking the link.
This is the most complex part of the feature. I built a custom renderer using the HTML5 Canvas API.
- Logic Flow:
- Generate Matrix: I use the
qrcodelibrary to get a raw matrix of 1s and 0s (data vs. empty space). - Iterate & Draw: I loop through this matrix.
- If it's a
1and the user selected "Dots", I draw a circle (ctx.arc). - If it's a
1and the user selected "Square", I draw a rectangle (ctx.fillRect).
- If it's a
- The "Safety Zone": When a logo is uploaded, the code automatically calculates the center coordinates and "clears" a rectangle in the middle of the QR code so the logo doesn't cover critical data dots.
- Frame Layering: Frames (like "Scan Me" or "Mandala") are drawn around the QR code matrix. The canvas dimensions are dynamically increased to accommodate this extra padding.
- Generate Matrix: I use the
- Static QR: Encodes the actual destination URL (e.g.,
google.com). If you change the destination, the QR code pattern changes (and you have to reprint it). - Dynamic QR: Encodes a Tinyslash Short Link (e.g.,
tinysla.sh/q/xyz123).- When the user scans this, they hit
QrRedirectController.java. - The backend looks up the
xyz123ID. - It records the scan analytics (Device, City, Time).
- It redirects the user to the real destination.
- Value Prop: You can update the destination URL 100 times, but the printed QR code remains the same.
- When the user scans this, they hit
- Every time
QrRedirectControllerhandles a request, it fires an async event to updatetotalScans. - We capture the
User-Agentstring to determine if the scan was from an iPhone or Android device, giving marketers valuable insight into their audience.
- Tech Stack: React, TypeScript, HTML5 Canvas, Java Spring Boot, MongoDB.
- Performance Optimization: Memoized the Canvas drawing function using
useCallbackto prevent flickering during color selection. - Security: Integrated
SecurityService.preCheckUrl()to ensure no one generates QR codes for phishing sites.