qwertyvipul.io Documentation

website·Indexed 29 days ago

https://qwertyvipul.io

A collection of technical notes and guides covering LeetCode solutions in Python and JavaScript, system design principles including the scalable monolith, and programming language fundamentals for Go, Rust, and JavaScript. Includes specific sections on OAuth, token-based authentication, and database types.

Tokens
8.1K
Snippets
51
Records
64
Agent score
50%

What's inside qwertyvipul.io

  1. Overview of Go language features and use cases

    Go is a statically typed language featuring garbage collection, type safety, and built-in support for concurrency. It is designed to be simple, efficient, and scalable, making it particularly well-suited for building large, distributed systems.
  2. Implement a Scalable Monolith layered architecture

    The scalable monolith architecture organizes code into layers with increasing authority. The primary goal is to ensure responsibilities remain explicit, execution flow is visible, and state changes are centralized.

    Layer Definitions:

    • API Handlers: The system edge. Handles input parsing, request-level validation, authentication, and rate limits. Calls Workflows or Integrations.
    • Integrations: Coordinates multiple workflows. Defines execution order and data handoff. Contains no domain logic and manages no database sessions.
    • Workflows: The center of the system. Defines the execution of a single cohesive operation, controls sequence, manages the database session lifecycle (creation, commit, rollback), and handles all state changes.
    • Helpers: Pure domain logic. Performs calculations, complex validations, and rules operating on data. Executes entirely in memory (no I/O).
    • Utils: Low-level operations. Interacts with the outside world, performs I/O, or calls external infrastructure. They are terminal and do not call other utils.
    • Models: Defines data shapes only; behavior resides in other layers.
  3. Understand SQL Relational Database characteristics

    SQL databases are relational systems that organize data into tables consisting of rows and columns. They utilize Structured Query Language (SQL) for data definition, manipulation, and querying. Common examples include MySQL, PostgreSQL, Oracle DB, MS SQL Server, and SQLite.
  4. Understand the fundamentals of System Design

    System design in software engineering is the process of translating specified requirements into a structured system for effective implementation. It involves defining five core elements:

    1. Architecture: The high-level blueprint outlining component arrangements, relationships, and guiding principles to ensure scalability, reliability, and performance.
    2. Components: The individual building blocks of the system.
    3. Modules: Self-contained software units.
    4. Interfaces: The methods, protocols, and data formats that define how components communicate.
    5. Data: The fundamental building blocks of information used by the system.
  5. Understand the JavaScript Event Loop mechanism

    The JavaScript runtime manages asynchronous execution using three primary components: the Call Stack, the Message Queue, and the Event Loop. The Event Loop continuously monitors the Message Queue; when messages (callbacks/tasks) arrive, they are processed in First-In-First-Out (FIFO) order and pushed onto the Call Stack for execution.
  6. Implement the OAuth sign-in and token exchange flow

    The standard OAuth authentication flow involves delegating identity verification to a trusted provider (e.g., Google, Apple, Microsoft) and managing sessions via tokens:

    1. Provider Authentication: The frontend opens the provider's auth page. Upon success, the provider returns a token to the frontend, which is then forwarded to the backend.
    2. Backend Verification: The backend validates the provider's token, extracts user identity (email/ID), and creates/retrieves the user record in the database.
    3. Session Establishment: The backend issues two tokens to the frontend: a short-lived Access Token for API calls and a long-lived Refresh Token for session renewal.
    4. Authenticated Requests: The frontend stores these tokens and attaches the access token to protected API calls.
    5. Token Renewal: When the access token expires, the frontend sends the refresh token to a dedicated backend endpoint to obtain a new access token without requiring the user to re-authenticate.
  7. Implement Refresh Token Rotation for enhanced security

    To prevent replay attacks and limit the impact of a compromised token, implement refresh token rotation. When a refresh token is used to obtain a new access token, the backend should:

    1. Issue a new access token.
    2. Issue a new refresh token.
    3. Invalidate the old refresh token immediately.
  8. Simulate and aggregate Rubrik API data using Promise.all

    This example demonstrates how to handle multiple asynchronous API calls to different data centers and applications, aggregating the results (protected and unprotected counts) into a final summary object. It uses Promise.all to wait for all simulated API requests to resolve before calculating the totals per data center.
    const appNames = ["vmware", "kafka", "zookeeper"];
    const dataCenters = [
        { name: "london", url: "ldn.api.com" },
        { name: "hongkong", url: "hk,api.com" },
        { name: "bangalore", url: "blr.api.com" },
    ];
    
    // Mock database generation
    const db = [];
    for (const { name, url } of dataCenters) {
        const entry = { name, url };
        for (const appName of appNames) {
            entry[appName] = {
                protectedCount: Math.floor(Math.random() * 200) + 100,
                unProtectedCount: Math.floor(Math.random() * 200) + 100,
            };
        }
        db.push(entry);
    }
    
    // Simulate API call
    const apiCall = (url, appName) => {
        return new Promise((resolve) => {
            const data = db.find((entry) => entry.url === url)[appName];
            setTimeout(() => resolve(data), Math.random() * 2000 + 1000);
        });
    };
    
    // Execute concurrent requests
    const promises = [];
    for (const { name, url } of dataCenters) {
        for (const appName of appNames) {
            promises.push(apiCall(url, appName).then((data) => ({ name, data })));
        }
    }
    
    const res = {};
    Promise.all(promises).then((values) => {
        values.forEach(({ name: dataCenterName, data }) => {
            if (!res[dataCenterName]) {
                res[dataCenterName] = { totalProtectedCount: 0, totalUnprotectedCount: 0 };
            }
            res[dataCenterName].totalProtectedCount += data.protectedCount;
            res[dataCenterName].totalUnprotectedCount += data.unProtectedCount;
        });
        console.log("Aggregated Results:", res);
    });
  9. Implement memoization using functools.lru_cache

    Use the @functools.lru_cache decorator to memoize expensive functions in Python. This stores the results of function calls, returning the cached value when the same inputs occur again. You can specify the maxsize parameter to limit the number of entries in the cache.
    import functools
    
    @functools.lru_cache(maxsize=4)
    def expensive_function(n):
        print(f"Calculating {n}...")
        return n * n
  10. Manipulate arrays and implement queues in JavaScript

    JavaScript arrays support dynamic sizing. Use push() and shift() to implement a basic Queue (FIFO). Use unshift() to add to the front and shift() to remove from the front. Use slice() for non-destructive copying and splice() for modifying the original array.
    // Initialization
    const arr = Array(n).fill(0);
    const fromArray = Array.from(iterable);
    
    // Queue operations
    const q = [];
    q.push(num);        // Enqueue
    const front = q.shift(); // Dequeue
    
    // Array manipulation
    arr.slice(startIdx, endIdx); // Returns new copy
    arr.splice(startIdx, count); // Modifies original
    
    // Summing an array
    const sum = nums.reduce((acu, num) => acu + num, 0);
  11. Retrieve elements and most common items from a Counter

    Use the elements() method to return an iterator over elements repeating each as many times as its count. Use most_common(n) to return a list of the n most frequent elements and their counts as tuples.
    import collections
    counter = collections.Counter([1, 1, 2, 2, 3, 3, 3, 3])
    
    # Get all elements as a list
    elements = list(counter.elements())
    print(elements)  # Output: [1, 1, 2, 2, 3, 3, 3, 3]
    
    # Get the 2 most common elements
    most_common = counter.most_common(2)
    print(most_common)  # Output: [(3, 4), (1, 2)] (or similar depending on data)
  12. Implement client-side search with Fuse.js

    For high-performance local search of data (such as LeetCode solutions) on the client side, use Fuse.js to index and query the dataset without requiring a backend search API.