C CIIT Stack Lab
Course Environment Java
Training All Levels 0 hrs 2 chapters

Java

Explore this structured CIIT training course.

Back to Start Learning
TOPIC 1 OF 3

Introduction to Java Script

Chapter Notes

Start with the notes, then review content and assessments.

Introduction to JavaScript

JavaScript is a high-level programming language commonly used to make web pages interactive and dynamic.

What is JavaScript?

JavaScript allows developers to add behavior and functionality to web applications. It can be used in the browser as well as on the server using environments such as Node.js.

Why Learn JavaScript?

  • It makes web pages interactive.
  • It works directly with HTML and CSS.
  • It is widely used for frontend development.
  • It can also be used for backend development.
  • It has a large ecosystem and community.

Basic JavaScript Example


let name = "Hatim";

console.log("Hello " + name);

Variables

Variables are used to store values that can be used later in a program. JavaScript provides keywords such as let, const, and var.

Example


let age = 22;
const course = "BCA";

console.log(age);
console.log(course);

Conclusion

JavaScript is one of the fundamental technologies used in modern web development. Understanding variables, data types, functions and control flow provides a strong foundation for further JavaScript development.

What you'll cover

A quick overview of this lesson's learning resources.

  • Lesson: OOP Concepts
  • Video: Not provided for this lesson
  • Slides: Not provided for this lesson
  • Practice: Review the chapter assessment section after studying the notes and lesson resources.
  • Suggested order: Notes → lesson content → chapter assessments.

Chapter Assessments

MCQs, interview questions and practice programs for this chapter.

Introduction to Java Script

MCQs

Knowledge check

Your answers are evaluated securely when you submit.

40 questions
Interview Questions
1. A request asks for customer orders: GET /api/customers/52/orders Authorization: Bearer <token> The client can change 52 to another customer's ID. Explain the risk and write the key authorization checks you would implement.

A route ID is only an identifier; it is not proof of permission. Authenticate the caller, load the target resource, and authorize the caller against that specific customer before returning data. Example: var customer = await db.Customers .SingleOrDefaultAsync(x => x.Id == customerId, ct); if (customer is null) return NotFound(); var decision = await authorizationService.AuthorizeAsync( User, customer, "ReadCustomerOrders"); if (!decision.Succeeded) return Forbid(); var orders = await db.Orders .Where(x => x.CustomerId == customerId) .ToListAsync(ct); return Ok(orders); The policy must use trusted server-side identity/relationships, never a client-supplied isAdmin property. Add tests for own-customer access, another customer's ID, unauthenticated access and a missing customer.

2. An HTTP integration in C# must support caller cancellation and large response bodies. Current code: var response = await httpClient.GetAsync("/reports"); return await response.Content.ReadAsStringAsync(); Rewrite the core flow to validate status and pass cancellation through. Explain how you would handle large payloads.

Pass the CancellationToken to HTTP and stream-reading APIs, validate the status before processing, and configure an appropriate timeout. Example: using var response = await httpClient.GetAsync( "/reports", HttpCompletionOption.ResponseHeadersRead, cancellationToken); response.EnsureSuccessStatusCode(); await using var stream = await response.Content.ReadAsStreamAsync( cancellationToken); using var reader = new StreamReader(stream); var text = await reader.ReadToEndAsync(cancellationToken); For very large data I would deserialize or process the stream incrementally instead of reading all of it into memory. Caller cancellation should propagate; timeouts and transient HTTP failures should be handled separately, with bounded retries only when retrying is safe.

3. A Python event processor needs to count event types despite inconsistent casing and whitespace. Input: [ {"type": " Login "}, {"type": "login"}, {"name": "missing type"}, {"type": "LOGOUT"} ] Write a robust function and explain how malformed events should be handled.

Normalize valid text values and report invalid records explicitly. Example: from collections import Counter def count_event_types(events): counts = Counter() invalid_count = 0 for event in events: raw_type = event.get("type") if not isinstance(raw_type, str) or not raw_type.strip(): invalid_count += 1 continue counts[raw_type.strip().casefold()] += 1 return counts, invalid_count The sample yields login: 2, logout: 1, and one invalid record. Tests should cover missing keys, None, empty strings, non-string values, casing, whitespace and empty input. In production I would expose invalid_count as a metric instead of silently hiding malformed records.

4. Write a SQL query that returns every department, including those with zero employees. Employees.DepartmentId can be NULL. Explain why the join type and COUNT expression are important.

Use the department table as the preserved side of a LEFT JOIN and count a nullable employee key. SELECT d.DepartmentId, d.DepartmentName, COUNT(e.EmployeeId) AS EmployeeCount FROM dbo.Departments AS d LEFT JOIN dbo.Employees AS e ON e.DepartmentId = d.DepartmentId GROUP BY d.DepartmentId, d.DepartmentName ORDER BY d.DepartmentName; LEFT JOIN preserves departments with no match. COUNT(e.EmployeeId) returns zero for those rows because the joined employee key is NULL. COUNT(*) would count the unmatched outer row and incorrectly give one. NULL DepartmentId values do not match a department under ordinary equality joins.

5. Review this repository code: var sql = "SELECT * FROM Users WHERE Email = '" + email + "'"; The email comes from the HTTP request. Explain SQL injection and replace the unsafe construction with a safer approach.

Concatenation can let input modify the SQL syntax. Use a parameterized command so the database treats the email as data. Example: await using var command = connection.CreateCommand(); command.CommandText = "SELECT UserId, Email FROM dbo.Users WHERE Email = @email"; var parameter = command.CreateParameter(); parameter.ParameterName = "@email"; parameter.Value = email; command.Parameters.Add(parameter); await using var reader = await command.ExecuteReaderAsync(cancellationToken); Also validate expected input shape, use least-privileged DB credentials, select only required columns and add tests with quotes or injection-like strings. Validation alone is not a substitute for parameterization.

6. A parallel worker processes a list of files, but every worker appends to one shared List<string>. Explain the race condition and show a safe implementation. What if output order must match input order?

List<T> is not thread-safe for concurrent writes. Multiple tasks may interfere with its internal state, causing lost or inconsistent results. For unordered output, a ConcurrentBag or a channel can be appropriate: var results = new ConcurrentBag<ProcessedFile>(); Parallel.ForEach(files, file => { results.Add(Process(file)); }); A ConcurrentBag does not guarantee input order. If order matters, assign each input an index and write to a pre-sized result array at that index, or use a parallel API that preserves input ordering. Define whether one failure cancels the batch or is recorded per file, and test with many items repeatedly.

7. This recursive Fibonacci function slows dramatically as n grows: def fib(n): if n < 2: return n return fib(n - 1) + fib(n - 2) Explain why and provide a better implementation with complexity analysis.

The naive recursion repeats the same subproblems and takes exponential time, approximately O(2^n). An iterative solution has linear time and constant extra space: def fib(n): if n < 0: raise ValueError("n must be non-negative") previous, current = 0, 1 for _ in range(n): previous, current = current, previous + current return previous Time is O(n) and extra space is O(1). Memoization is also O(n) time but requires O(n) cache space and may still encounter recursion depth limits. Tests should include n=0, n=1, known small values and invalid negative input.

8. Design validation for this order request: { "customerId": 123, "items": [ { "productId": 10, "quantity": 2 } ] } Explain what belongs in request validation, business logic and database persistence.

At the request boundary, validate positive IDs, a non-empty bounded items array, positive quantities and valid field shapes. Return a 400 response for malformed input. In the service layer, verify that the caller can order for the customer, products exist and are active, stock is sufficient, and prices/discounts come from trusted server-side data rather than the client. In persistence, create the order and line items atomically in a transaction. Use appropriate concurrency controls to prevent overselling, and use foreign keys and constraints where applicable. Roll back on failure. Test malformed payloads, unauthorized customers, out-of-stock products, concurrent purchases and transaction rollback.

9. Two requests attempt to buy the final unit. Both read Stock = 1 before updating it. Explain the race condition and provide a database-safe approach that prevents overselling.

A read-then-write flow lets both transactions observe stock as one and both continue. Enforce the invariant in an atomic database update instead. UPDATE dbo.Products SET Stock = Stock - 1 WHERE ProductId = @productId AND Stock > 0; Check the affected-row count. Zero updated rows means the item was unavailable. Run the stock change and order insert in one transaction so a failed order insert rolls back the stock decrement. For more complex rules, consider optimistic concurrency tokens or suitable isolation/locking. A prior application-side check alone is insufficient.

10. A React component fetches details when customerId changes. A slow earlier request can finish after the newer request and overwrite the UI. Show a cleanup pattern that prevents stale responses from winning.

The request order is not guaranteed to match response order. Abort the obsolete request during effect cleanup. useEffect(() => { const controller = new AbortController(); async function loadCustomer() { try { const response = await fetch( `/api/customers/${customerId}`, { signal: controller.signal } ); if (!response.ok) throw new Error("Request failed"); setCustomer(await response.json()); } catch (error) { if (error.name !== "AbortError") { setError(error); } } } loadCustomer(); return () => controller.abort(); }, [customerId]); An alternative is a request ID guard that ignores stale results. Test by deliberately resolving requests out of order and verifying only the newest customer is displayed.

11. A Python program opens JSON data, parses it and calls process(payload). file = open("records.json", encoding="utf-8") payload = json.load(file) process(payload) file.close() What happens when parsing or processing raises? Rewrite the resource handling safely.

If parsing or process() raises, file.close() might never execute. Use a context manager: import json def load_and_process(path): with open(path, encoding="utf-8") as file: payload = json.load(file) return process(payload) The file closes automatically when execution exits the with block, including on exceptions. It is closed before processing, which avoids holding the file open unnecessarily. Handle expected I/O and JSON decoding failures at the correct application boundary, and test malformed JSON as well as processing exceptions.

12. An invoice row commits successfully, but its notification times out. The worker retries and risks sending a duplicate. Design an idempotent and recoverable workflow.

Use a transactional outbox. In one database transaction, insert the invoice and an outbox event with a stable event ID; commit both together. A separate worker claims pending events, sends the notification and marks the event delivered. If the database transaction fails, neither invoice nor event is saved. If delivery succeeds but the acknowledgement is lost, the event may be retried, so use a provider idempotency key or a durable sent-message ledger when possible. Add bounded retry/backoff and a dead-letter/error path. A plain retry loop does not guarantee exactly-once delivery, so repeated processing must be safe.

13. Compare POST and PUT for a resource update. A client sends the same complete replacement request twice after losing the first response. Explain idempotency and how you would handle retried create/payment requests.

PUT is generally suitable when the target URI identifies a resource and the request replaces its representation. Repeating the same PUT should leave the intended resource state unchanged. POST commonly asks the server to process a request or create a subordinate resource and may produce duplicate effects if repeated. Idempotency describes the intended resulting state, not whether the server performs zero work on retries. For create/payment operations, accept an idempotency key, store its outcome and scope, and return the same outcome on a repeat. Define expiry and reject reuse of the same key with a different payload. Use a database constraint or transaction to make the idempotency record and business change consistent.

14. A private feature branch needs to be replayed on top of the latest main branch. Explain the command and the risks of rebasing a branch already shared with other developers.

A linear-history rebase can be performed with: git fetch origin git switch feature git rebase origin/main Rebase replays commits and produces new commit IDs because the ancestry changes. That is usually manageable for a private branch. If others have based their work on the published commits, rewriting the branch can disrupt their history; coordinate first or merge main into the branch instead. If a published rebase must be pushed, use a carefully coordinated force-with-lease rather than an unconditional force push.

15. Several requests miss the cache for the same expensive read operation at once. The data changes periodically. Describe a caching design including keys, expiry, concurrent misses, invalidation and privacy.

Construct the key from all inputs that affect the result, including resource ID and any required locale, tenant or authorization scope. Otherwise one request could receive another user's cached data. Set a bounded TTL based on freshness requirements, and evict/update after successful mutations. Consider request coalescing or a per-key async lock so simultaneous cache misses do not all run the same expensive query. Avoid caching sensitive per-user content under a shared key. In multi-node deployments, use shared storage or reliable invalidation events. Measure hit rate and test that changes become visible within the agreed consistency window.

16. A production endpoint is intermittently slow and cannot be reproduced locally. Outline a safe investigation using logs, metrics, traces, database analysis and a controlled test.

Start with a baseline: latency percentiles, throughput, error rates and resource utilization. Correlate requests with trace/request IDs while excluding secrets and unnecessary personal data. Use distributed tracing to see time spent in the application, SQL, cache or external services. Check slow-query plans, locks and wait statistics. Compare slow requests by endpoint, payload size and time window. Reproduce in staging with representative anonymized data and a bounded load test. Change one likely bottleneck at a time and compare before/after measurements. Keep experiments reversible and do not overload production merely to reproduce the issue.

17. A method catches every exception and returns an empty list: try { return await repository.GetOrdersAsync(ct); } catch { return new List<Order>(); } Explain why this is dangerous and propose an error-handling contract.

An empty successful result becomes indistinguishable from a database outage, timeout or programming bug. Downstream code may then make incorrect decisions while the incident is hidden. Let cancellation propagate when the caller cancels. Handle expected failures at a suitable boundary and log unexpected exceptions with a request/job ID without logging secrets. Example: try { return await repository.GetOrdersAsync(ct); } catch (OperationCanceledException) when (ct.IsCancellationRequested) { throw; } catch (SqlException ex) { logger.LogError(ex, "Failed to load orders for request {RequestId}", requestId); throw; } Exception middleware or the controller can return a safe 5xx response without exposing database details. Tests should confirm infrastructure failure is not represented as an empty successful result.

18. A table contains millions of orders. The API loads every row into application memory, then filters by customer and date. Rewrite the query to filter/page in SQL and discuss indexing.

Push filtering, ordering and pagination into the database and project only required fields. var page = await db.Orders .AsNoTracking() .Where(o => o.CustomerId == customerId && o.CreatedAt >= start && o.CreatedAt < end) .OrderByDescending(o => o.CreatedAt) .ThenByDescending(o => o.Id) .Skip(offset) .Take(pageSize) .Select(o => new OrderSummaryDto { Id = o.Id, CreatedAt = o.CreatedAt, Total = o.Total }) .ToListAsync(cancellationToken); Enforce a maximum page size and stable ordering. An index that supports the filter and ordering may help, but choose it based on real query plans and workload. Avoid transferring unused columns and ensure parameter values are handled safely.

19. A developer manually added a column to one database, but a clean test database fails because the change is not in version control. Describe how to make schema changes reproducible and safe across environments.

Version the schema change in an EF migration or reviewed, idempotent SQL script. Include data type, nullability, constraints, indexes and any required backfill. Test against both a clean disposable database and a representative existing schema. Review locking/runtime impact, backup and rollback/forward-fix plans, and record which schema version is deployed. For rolling deployments, keep the schema change backward-compatible with overlapping application versions where possible. Never assume a column exists just because it exists on one developer's machine; integration tests should validate schema setup before the feature is considered ready.

20. A spreadsheet importer has fixed columns for Question, Option A–D and Correct Answer. Some questions contain line breaks inside their cells. One row has an invalid answer key and another is a duplicate. Design a safe preview-and-confirm workflow.

Parse worksheet cells by row and column; never split a question cell on its embedded newlines. Preserve the original row number for validation messages. Validate required cells, all four options, the answer key, duplicates within the uploaded workbook and duplicates already in the selected chapter, including archived rows if the policy requires it. Display the complete preview and block import when any row is invalid. On confirmation, re-check that the chapter is active and re-check duplicates because the database may have changed since preview. Save the entire batch in one database transaction so one failure cannot leave a partial import. Also enforce file size and row limits, validate the XLSX structure, require an authenticated administrator and test multiline cells, blank rows, invalid workbooks and duplicate races.

Practice Programs
1. C# — Build a Safe Expression Calculator
Create a console program that evaluates arithmetic expressions containing integers, parentheses, +, -, *, and /. Input examples: 12 + 3 * 4 (18 - 6) / 3 7 * (2 + 5) - 9 Requirements: - Respect operator precedence and parentheses. - Reject malformed expressions instead of crashing. - Detect division by zero and report a useful error. - Do not use eval or execute the input as code. - Describe how the parser should handle invalid tokens such as "4 + * 2". - Include representative valid and invalid test cases.
2. Python — Find the Longest Unique Substring
Given a string that may contain spaces, punctuation, digits, and Unicode characters, find the longest contiguous substring that contains no repeated character. Example: Input: "abcaefbb" Output: "bcaef" Requirements: - Return both the substring and its length. - If multiple answers have the same maximum length, return the earliest one. - Handle an empty string. - Aim for O(n) time rather than checking every possible substring. - Explain the expected behavior for "aaaa", "dvdf", and "pwwkew". - Include a small test harness that validates these cases.
3. C# — Implement a Thread-Safe LRU Cache
Design a generic Least Recently Used (LRU) cache with a fixed positive capacity. Required API: Get(key) // returns the value, or a documented cache-miss result Put(key, value) Count Requirements: - A successful Get makes the key most recently used. - Updating an existing key must not increase Count. - When full, Put must evict the least recently used key. - Make concurrent Get and Put calls safe. - State your expected time complexity for Get and Put. - Test capacity 1, updating an existing key, eviction order, missing keys, and parallel callers.
4. SQL Server — Find Duplicate Orders Without Hiding Legitimate Rows
Assume a table: Orders(OrderId, CustomerId, OrderDate, ExternalReference, Amount, Status) Find groups of potentially duplicated orders when CustomerId and ExternalReference match and OrderDate occurs on the same calendar day. Requirements: - Return the matching OrderIds and the duplicate-group size. - Treat NULL ExternalReference values according to an explicit business rule. - Do not delete or update data. - Avoid grouping unrelated customers together. - Describe what indexes would help this query and why. - Include test data for a duplicate pair, a single order, two customers with the same reference, and orders around midnight.
5. Java — Merge Overlapping Time Intervals
Given a list of meeting intervals represented by start and end times, merge intervals that overlap. Example: Input: [[1, 4], [3, 6], [8, 10], [9, 12]] Output: [[1, 6], [8, 12]] Requirements: - Sort efficiently before merging. - Define how touching intervals such as [1, 3] and [3, 5] should be treated. - Validate intervals where start is greater than end. - Support an empty list and a list with one interval. - State time and space complexity. - Include tests for nested intervals, duplicate intervals, and already sorted input.
6. C# — Design a Retry Policy for an Unreliable HTTP API
Implement a reusable asynchronous HTTP request helper for a service that occasionally returns 429, 500, 502, 503, or 504. Requirements: - Retry only transient failures; do not retry ordinary 400-series validation errors. - Use exponential backoff with a maximum delay and a small random jitter. - Respect a valid Retry-After response header. - Support CancellationToken and stop immediately when cancelled. - Set a finite maximum attempt count. - Explain how to avoid retrying non-idempotent operations unsafely. - Include tests for success on the first try, transient recovery, retry exhaustion, cancellation, and permanent failure.
7. Python — Process a Large Log File in Bounded Memory
Build a command-line tool that reads a multi-gigabyte application log without loading the entire file into memory. Each log line may look like: 2026-10-12T14:05:22Z ERROR payment-service requestId=abc123 message="timeout" Requirements: - Count entries by severity. - Count unique request IDs for ERROR entries. - Report malformed lines without stopping the whole run. - Allow an optional start/end timestamp filter. - Write a concise summary to a separate output file. - Keep memory usage bounded and close resources reliably. - Include tests for an empty file, malformed timestamps, missing IDs, and quoted messages containing spaces.
8. JavaScript — Prevent Race Conditions in Search Suggestions
Create an autocomplete component that requests suggestions as a user types. Scenario: - A request for "ca" takes 500 ms. - A later request for "cat" takes 100 ms. - The older "ca" response may arrive after the "cat" response. Requirements: - Never allow stale responses to overwrite newer suggestions. - Debounce input to avoid a request for every keystroke. - Cancel previous requests when supported, but still guard against race conditions. - Show loading, empty-result, and error states. - Support keyboard navigation and Escape. - Include tests for out-of-order responses, clearing the input, and network failure.
9. C# — Validate a Nested JSON Configuration
Create a validator for a JSON configuration describing services, endpoints, and retry settings. Example shape: { "serviceName": "billing", "timeoutSeconds": 15, "endpoints": [ { "name": "health", "url": "https://example.test/health" } ] } Requirements: - Require a non-empty serviceName. - Restrict timeoutSeconds to a documented range. - Require absolute HTTPS URLs for production endpoints. - Reject duplicate endpoint names without treating case variants inconsistently. - Return all validation errors in one pass instead of stopping at the first error. - Do not log secrets if optional credentials are later added. - Include tests for missing fields, invalid URLs, duplicate names, and valid input.
10. Python — Build a Reliable CSV Import Validator
Write a CSV import validator for records with columns: EmployeeId, FullName, Email, Department, StartDate Requirements: - Verify the exact required headers. - Keep commas and quoted newlines inside a field instead of treating them as a new record. - Validate email shape, date format, and required values. - Detect duplicate EmployeeId values within the file. - Produce a row-numbered error report and do not partially import invalid rows. - Handle UTF-8 input and a byte-order mark. - Include test cases for quoted commas, a multiline field, duplicate IDs, missing columns, and malformed CSV.
11. SQL Server — Design Pagination for a Growing Audit Table
Assume a table: AuditEvents(EventId, TenantId, CreatedAt, EventType, Payload) The table contains tens of millions of rows and the admin UI displays the newest events for one tenant. Requirements: - Compare OFFSET/FETCH pagination with keyset pagination. - Use a stable ordering when CreatedAt values are equal. - Prevent records from unexpectedly repeating between consecutive pages. - Propose a useful index for the filter and ordering. - Avoid returning large Payload values when the list view does not need them. - Include the query shape for fetching the next page after a known EventId/CreatedAt pair. - Explain what should happen when new events are inserted between page requests.
12. Java — Implement a Bounded Producer-Consumer Queue
Create a producer-consumer pipeline for processing jobs from a queue with a fixed capacity. Requirements: - Producers must wait when the queue is full. - Consumers must wait when the queue is empty. - Support multiple producers and consumers safely. - Provide a shutdown signal so waiting threads can exit. - Never lose an accepted item or process the same item twice. - Avoid busy waiting and explain the synchronization strategy. - Include tests for capacity 1, simultaneous producers, shutdown while idle, and shutdown while the queue is full.
13. C# — Build a Secure File Upload Validator
Implement server-side validation for users uploading documents to an ASP.NET Core application. Requirements: - Enforce a maximum size before processing the whole file. - Allow only configured file types and do not trust the browser-supplied MIME type or filename extension alone. - Generate a safe server-side filename rather than using a path supplied by the user. - Prevent path traversal and avoid writing uploads into a public executable directory. - Handle empty, malformed, and oversized files. - Ensure temporary files and streams are disposed on success, failure, and cancellation. - Include tests for a renamed executable, a traversal filename, a zero-byte file, and a valid document.
14. Python — Find the Cheapest Route in a Weighted Graph
Represent a transport network as a weighted graph where each edge has a non-negative cost. Example: A --4--> B A --2--> C C --1--> B B --5--> D C --8--> D Requirements: - Return the minimum total cost from a chosen start node to a destination. - Return the actual path as well as the cost. - Report clearly when the destination is unreachable. - Use an algorithm appropriate for non-negative edge weights. - Handle an unknown start node and an empty graph. - State time complexity in terms of vertices and edges. - Include tests for equal-cost paths, disconnected nodes, and a graph with one vertex.
15. JavaScript — Build a Form with Cross-Field Validation
Create a registration form with: password confirmPassword birthDate acceptedTerms Requirements: - Password confirmation must match the password. - BirthDate must be a valid date and the user must meet a configurable minimum age. - Terms acceptance is mandatory. - Show field-specific errors and focus the first invalid field on submit. - Validation must also run on the server; browser validation alone is not sufficient. - Clear errors when values become valid and preserve accessible labels/announcements. - Include tests for invalid dates, leap-day birthdays, mismatch, missing consent, and valid submission.
16. C# — Design an Idempotent Order-Creation Endpoint
An API receives POST /orders from a client that may retry when a network timeout occurs. Requirements: - Accept an idempotency key and associate it with the authenticated customer. - If the same key and same request arrive again, return the original result rather than creating another order. - Reject reuse of the same key with a materially different request. - Make key reservation and order creation atomic under concurrent requests. - Define key expiration and response storage rules. - Never rely on an in-memory dictionary for correctness across multiple servers. - Include tests for duplicate requests, concurrent requests, changed payload, and transaction rollback.
17. SQL Server — Find the Top Three Products per Category
Assume tables: Products(ProductId, CategoryId, ProductName) Sales(SaleId, ProductId, SoldAt, Quantity, UnitPrice) Return the three products with the highest total revenue in each category for a selected date range. Requirements: - Calculate revenue from Quantity * UnitPrice. - Exclude sales outside the requested range. - Define deterministic tie handling when products share the same revenue. - Return categories with fewer than three products sold. - Avoid ranking rows before aggregating sales per product. - Use a window function and explain the ranking choice. - Include cases for ties, zero sales, and a category with only one product.
18. Python — Implement a Thread-Safe Rate Limiter
Create a per-user rate limiter for an API using a documented sliding-window policy. Example policy: Maximum 100 requests in any rolling 60-second window. Requirements: - Return allow/deny plus the retry-after duration. - Handle many requests arriving at nearly the same time. - Expire old timestamps to prevent unbounded memory growth. - Use a monotonic clock for elapsed-time measurement. - Explain how behavior changes when the application runs on multiple servers. - Ensure one user's traffic does not consume another user's quota. - Test boundary timestamps, bursts, concurrent calls, and clock-related edge cases.
19. C# — Prevent Lost Updates in a Shared Inventory System
An inventory API processes orders while warehouse users adjust stock. Table: Inventory(ProductId, AvailableQuantity, RowVersion) Requirements: - Two simultaneous orders must not both consume the same last unit. - Reject a reservation when available quantity is insufficient. - Use a transaction and an appropriate concurrency strategy. - Explain optimistic concurrency with RowVersion versus an atomic conditional UPDATE. - Return a clear conflict response when another request wins the race. - Never allow the quantity to become negative. - Include tests for two requests reserving one unit, insufficient stock, and transaction failure.
20. C# — Implement a Background Job Worker with Graceful Shutdown
Build a .NET background worker that reads jobs from a durable queue and processes them asynchronously. Requirements: - Process jobs with a configurable maximum concurrency. - Propagate cancellation during host shutdown. - Retry transient failures with a finite policy and record permanent failures. - Ensure a job is acknowledged only after successful processing. - Prevent one poisoned job from blocking the entire queue. - Log a correlation ID without logging secrets or full sensitive payloads. - Include tests for shutdown during processing, retry exhaustion, duplicate delivery, and a job that throws unexpectedly.