diff --git a/src/data/question-groups/full-stack/content/api-security.md b/src/data/question-groups/full-stack/content/api-security.md new file mode 100644 index 000000000..6fa1bb22e --- /dev/null +++ b/src/data/question-groups/full-stack/content/api-security.md @@ -0,0 +1,32 @@ +Rather than overlapping each other, authorization and authentication reference two very distinct stages of security within your app. + +##### Authentication + +On one side, we have authentication, in charge of verifying the user identity. You can use tokens (e.g., JWT, OAuth) or sessions for this. + +Example: Validate a JWT sent in headers: + +```javascript +const token = req.headers['authorization']; +jwt.verify(token, secretKey, (err, decoded) => { ... }); +``` + +##### Authorization + +Once authenticated, users need to be authorized to access the resources. For this to work, you’ll need to define roles and permissions for your users. + +Middleware example: + +```javascript +app.use((req, res, next) => { + if (req.user.role !== 'admin') return res.status(403).send('Forbidden'); + next(); +}); +``` + +##### Best Practices + +* Use HTTPS to ensure a secure channel between the browser and the server. +* Validate input to prevent injection attacks. +* Rate-limit API requests to avoid having your APIs overwhelmed by potential attackers. +* Store sensitive data securely (e.g., hashed passwords). \ No newline at end of file diff --git a/src/data/question-groups/full-stack/content/async-javascript.md b/src/data/question-groups/full-stack/content/async-javascript.md new file mode 100644 index 000000000..2c49bd026 --- /dev/null +++ b/src/data/question-groups/full-stack/content/async-javascript.md @@ -0,0 +1,83 @@ +JavaScript handles asynchronous operations, like fetching data from an API or reading files, through different paradigms: **callbacks**, **promises**, and **async/await**. Each offers unique advantages and challenges. Here's a detailed look: + +##### 1\. Callbacks + +**What it is**: +A callback is a function passed as an argument to another function to be executed later, usually after an asynchronous task completes. + +**Example**: + +```javascript +fs.readFile('file.txt', (err, data) => { + if (err) { + console.error('Error reading file:', err); + return; + } + console.log('File content:', data.toString()); +}); +``` + +**Challenges**: + +**Callback Hell**: As tasks become more complex, nesting callbacks leads to hard-to-read and maintainable code. + +```javascript +doTask1(() => { + doTask2(() => { + doTask3(() => { + console.log('All tasks done!'); + }); + }); +}); +``` + +##### 2\. Promises + +**What it is**: +A promise represents a value that may be available now, in the future, or never usually coming as a result of an asynchronous operation. It provides a cleaner way to handle asynchronous operations, chaining actions with `.then()` and catching errors with `.catch()`. + +**Example**: + +```javascript +fetch('https://api.example.com/data') + .then((response) => response.json()) + .then((data) => { + console.log('Fetched data:', data); + }) + .catch((error) => { + console.error('Error fetching data:', error); + }); +``` + +**Advantages**: + +- Eliminates deeply nested callbacks. +- Provides a clearer structure for handling asynchronous workflows. + +##### 3\. Async/Await + +**What it is**: +Async/await is built on promises but provides a more synchronous and readable syntax for managing this type of code. + +Functions declared with `async` automatically return a promise, and the `await` keyword pauses execution until a promise resolves. + +**Example**: + +```javascript +const fetchData = async () => { + try { + const response = await fetch('https://api.example.com/data'); + const data = await response.json(); + console.log('Fetched data:', data); + } catch (error) { + console.error('Error fetching data:', error); + } +}; + +fetchData(); +``` + +**Advantages**: + +- Reads like synchronous code, making it easier to understand. +- Simplifies error handling with `try/catch` blocks. diff --git a/src/data/question-groups/full-stack/content/client-server-programming.md b/src/data/question-groups/full-stack/content/client-server-programming.md new file mode 100644 index 000000000..e3bbda18f --- /dev/null +++ b/src/data/question-groups/full-stack/content/client-server-programming.md @@ -0,0 +1,22 @@ +The **client-side** and **server-side** refer to two distinct parts of a **web application** that work together to deliver functionality to users. Understanding their roles is essential for building efficient and responsive applications. + +#### Client-Side +* **What it Does**: This is the part of the application that runs in the user’s browser. It handles **user interfaces** and interactions, allowing users to see and interact with the application. +* **Key Characteristics**: + * Executes **JavaScript code** directly in the browser to handle tasks like form validation, animations, and dynamic content updates (through DOM \-Document Object Model- updates). + * Manages rendering of HTML and CSS for a seamless visual experience. + * Often communicates with the server via **REST (Representational State Transfer)** APIs to fetch or send data asynchronously. +* **Examples**: + * Clicking a button that triggers a JavaScript function to show a popup. + * Fetching additional items on a page using `fetch()` or `axios` without a full page reload. + +#### Server-Side + +* **What it Does**: This part operates on the server and processes requests from the client, performing tasks like database queries, business logic, and serving responses. +* **Key Characteristics**: + * Executes server-side programming languages like Python, Java, or Node.js. + * Handles sensitive operations like authentication and data storage securely. + * Sends data to the client in structured formats (e.g., JSON) via **REST APIs** for rendering. +* **Examples**: + * Processing a login request by verifying credentials in a database. + * Returning a list of products in JSON format for the client to display dynamically. diff --git a/src/data/question-groups/full-stack/content/css-selectors.md b/src/data/question-groups/full-stack/content/css-selectors.md new file mode 100644 index 000000000..3d05d08e7 --- /dev/null +++ b/src/data/question-groups/full-stack/content/css-selectors.md @@ -0,0 +1,22 @@ +**CSS selectors** are patterns used to select and style specific elements in an HTML document. They define which elements a set of CSS rules should apply to, making them a fundamental part of designing the appearance of **web applications** and **user interfaces**. + +##### **Why CSS Selectors Matter** + +Selectors allow you to target elements precisely, enabling you to control layout, colors, fonts, and other visual aspects of your website. They are essential for creating structured and maintainable CSS code. + +There are different types of selectors, categorized based on what they target: + +* Elements: these selectors reference a specific type of element, and affect all instances of that element throughout the page. Example: `p {}` +* Classes: These selectors only affect those elements that hava a matching class. They’re great to target large groups of elements of the same type, without affecting the entire set. Example: `.my-class {}` +* ID: ID-level selectors affect only one element (as IDs can only be used on a single element). They’re great when you have a single element that breaks the pattern from the rest of the group. Example: `#my-id {}` +* Attribute: Attribute-level selectors target elements based on the value of their attributes. They’re great for the cases where you have to dynamically highlight elements. Example: `[type="text"] {}` +* Descendant: Another way to target other elements is to target them based on the parent element. This method works with any combination of the above, so you can potentially target elements using a specific class that are descendants of an element with a specific attribute value (or any other combination you can think of). Example: `div p {}` + +##### When to Use Selectors + +* Use type selectors for global styling. +* Use class selectors for reusable styles across multiple elements. +* Use ID selectors sparingly for unique elements. +* Combine selectors for granular control and better maintainability. + +CSS selectors give you the power to control every aspect of your web application’s design, ensuring that your user interfaces are consistent, visually appealing, and responsive \ No newline at end of file diff --git a/src/data/question-groups/full-stack/content/database-relationships.md b/src/data/question-groups/full-stack/content/database-relationships.md new file mode 100644 index 000000000..9fb26bbf1 --- /dev/null +++ b/src/data/question-groups/full-stack/content/database-relationships.md @@ -0,0 +1,3 @@ +1. **One-to-Many**: One record in a table relates to multiple records in another. Handled via foreign keys. Example: A `user` has many `posts`. +2. **Many-to-Many**: Requires a join table to link records from two tables. Example: `students` and `courses` with an intermediary `enrollments` table. +3. **Primary/Foreign Keys**: Establish links between tables for querying and ensuring data consistency. \ No newline at end of file diff --git a/src/data/question-groups/full-stack/content/div-span-purpose.md b/src/data/question-groups/full-stack/content/div-span-purpose.md new file mode 100644 index 000000000..97c9f9f0c --- /dev/null +++ b/src/data/question-groups/full-stack/content/div-span-purpose.md @@ -0,0 +1,2 @@ +* **`
Hello
` + +**Internal**: Use a `` + +1. + +**External**: Link a CSS file using `` in the ``. +`` \ No newline at end of file diff --git a/src/data/question-groups/full-stack/content/js-dom-manipulation.md b/src/data/question-groups/full-stack/content/js-dom-manipulation.md new file mode 100644 index 000000000..c1d1d3bd1 --- /dev/null +++ b/src/data/question-groups/full-stack/content/js-dom-manipulation.md @@ -0,0 +1,6 @@ +JavaScript accesses and modifies the DOM using methods like: + +* **Get elements**: `document.getElementById("id")`, `querySelector(".class")`. +* **Modify content**: `element.innerHTML = "New Content"`. +* **Change styles**: `element.style.color = "blue"`. +* **Add/remove elements**: `appendChild()`, `removeChild()`. \ No newline at end of file diff --git a/src/data/question-groups/full-stack/content/js-equality-operators.md b/src/data/question-groups/full-stack/content/js-equality-operators.md new file mode 100644 index 000000000..aeb925192 --- /dev/null +++ b/src/data/question-groups/full-stack/content/js-equality-operators.md @@ -0,0 +1,2 @@ +* **`==`**: Compares values with each other directly, performing type conversion if required first (example: `'5' == 5` → `true`). +* **`===`**: This operator strictly compares values and types with each other. There is no type conversion performed with this operator. For example, if you try to compare a string and a number, the result will always be false, no matter what: `'5' === 5` → `false`. \ No newline at end of file diff --git a/src/data/question-groups/full-stack/content/nodejs-database-crud.md b/src/data/question-groups/full-stack/content/nodejs-database-crud.md new file mode 100644 index 000000000..33cbe9ca7 --- /dev/null +++ b/src/data/question-groups/full-stack/content/nodejs-database-crud.md @@ -0,0 +1,95 @@ +In general terms, connecting to a database using Node.js requires the following steps: + +1. Install the DB driver. +2. Use the driver to connect to the database. +3. Use the returned connection object to send requests. + +Of course, depending on the database engine you decide to go with, there might be some slight changes to those steps. +However, if we think about either MongoDB or PostgreDB, let’s take a look at how to interact with them through Node.js: + +##### Install the Database Driver + +The first thing you gotta do, is install either the driver which will let you directly interact with the database, or an ORM, which will abstract that connection and give you a higher-level layer of abstraction. +Use the appropriate driver for your database. + +* For MongoDB: `npm install mongoose` +* For PostgreSQL: `npm install pg` + +##### Connect to the database + +Now to connect to the actual database, you’ll have to adapt the code based on the connection method you’re using. Let’s take a closer look at how to connect either to MongoDB or PostgreDB. + +**MongoDB**: + +```javascript +const mongoose = require('mongoose'); +mongoose.connect('mongodb://localhost:27017/mydb', { useNewUrlParser: true, useUnifiedTopology: true }); +``` + +**PostgreSQL**: + +```javascript +const { Pool } = require('pg'); +const pool = new Pool({ user: 'user', host: 'localhost', database: 'mydb', password: 'password', port: 5432 }); +``` + +##### Perform CRUD Operations + +For the CRUD (Create, Read, Update & Delete), the code is going to change based on the technology you’re using. Here in our examples, we have one that’s using an ORM which means we have an abstraction layer on top of the native query language, and then we also have a simple SQL driver, which means we have to directly write SQL queries. + +**Create operation**: + +**MongoDB**: + +```javascript +const User = mongoose.model('User', { name: String }); +User.create({ name: 'John Doe' }); +``` + +**PostgreSQL**: + +```javascript +pool.query('INSERT INTO users (name) VALUES ($1)', ['John Doe']); +``` + +**Read operation**: + +**MongoDB**: + +```javascript +User.find({}, (err, users) => console.log(users)); +``` + +**PostgreSQL**: + +```javascript +pool.query('SELECT * FROM users', (err, res) => console.log(res.rows)); +``` + +**Update operation**: + +**MongoDB**: + +```javascript +User.updateOne({ name: 'John Doe' }, { name: 'Jane Doe' }); +``` + +**PostgreSQL**: + +```javascript +pool.query('UPDATE users SET name = $1 WHERE name = $2', ['Jane Doe', 'John Doe']); +``` + +**Delete operation**: + +**MongoDB**: + +```javascript +User.deleteOne({ name: 'Jane Doe' }); +``` + +**PostgreSQL**: + +```javascript +pool.query('DELETE FROM users WHERE name = $1', ['Jane Doe']); +``` diff --git a/src/data/question-groups/full-stack/content/nodejs-middleware.md b/src/data/question-groups/full-stack/content/nodejs-middleware.md new file mode 100644 index 000000000..09c40ec40 --- /dev/null +++ b/src/data/question-groups/full-stack/content/nodejs-middleware.md @@ -0,0 +1,9 @@ +Middleware in Express is a function that processes requests and responses in the app’s request-response cycle. It can be used to modify request/response objects adding extra information or removing unnecessary data, it can execute code (like logging, parsing JSON, etc) and it can also end the request-response cycle, allowing it to short-circuit the process and return a different response (commonly used to handle invalid or unauthorized requests). + +Example: +```javascript +app.use((req, res, next) => { + console.log('Middleware triggered'); + next(); +}); +``` \ No newline at end of file diff --git a/src/data/question-groups/full-stack/content/package-json-purpose.md b/src/data/question-groups/full-stack/content/package-json-purpose.md new file mode 100644 index 000000000..3663eafb6 --- /dev/null +++ b/src/data/question-groups/full-stack/content/package-json-purpose.md @@ -0,0 +1,3 @@ +The `package.json` file in a Node.js project has multiple uses. It defines the project's metadata, like its name, version, and description. It also lists the dependencies and devDependencies required to run or develop the application, as well as scripts for tasks like building, testing, or running the app (and any custom script you’d like to add). + +Finally, it ensures reproducible installations by allowing the `npm install` command to pull consistent dependencies, ensuring you can easily port your project into other systems. \ No newline at end of file diff --git a/src/data/question-groups/full-stack/content/react-hooks.md b/src/data/question-groups/full-stack/content/react-hooks.md new file mode 100644 index 000000000..90005dd58 --- /dev/null +++ b/src/data/question-groups/full-stack/content/react-hooks.md @@ -0,0 +1,9 @@ +React hooks are functions that let you use state and other React features in functional components. + +With hooks you can simplify state and lifecycle management without needing class components. They also enable code reuse through custom hooks. + +**Examples of different hooks**: + +* `useState` for managing state. +* `useEffect` for handling side effects (e.g., fetching data). +* `useContext` for global state. \ No newline at end of file diff --git a/src/data/question-groups/full-stack/content/react-performance.md b/src/data/question-groups/full-stack/content/react-performance.md new file mode 100644 index 000000000..a53e4acf4 --- /dev/null +++ b/src/data/question-groups/full-stack/content/react-performance.md @@ -0,0 +1,10 @@ +The performance of a React application can be affected by multiple aspects, but some of the most common ones and their way to fix them are: + +1. **Reduce Re-renders**: + * Use `React.memo` and `useCallback` to avoid unnecessary updates. + * Split large components into smaller, focused components. +2. **Lazy Loading**: Load components or routes on demand using `React.lazy` and `Suspense`. +3. **Efficient State Management**: Keep state local where possible and avoid overusing global state. +4. **Minimize DOM Updates**: Use keys in lists and avoid deeply nested props/state updates. +5. **Code Splitting**: Use Webpack or tools like `react-loadable` to split the bundle. +6. **Profile and Debug**: Use React Developer Tools to identify bottlenecks. \ No newline at end of file diff --git a/src/data/question-groups/full-stack/content/react-state-management.md b/src/data/question-groups/full-stack/content/react-state-management.md new file mode 100644 index 000000000..3ef5ee959 --- /dev/null +++ b/src/data/question-groups/full-stack/content/react-state-management.md @@ -0,0 +1,11 @@ +In React you have two different ways to handle state, depending on the scope of the data inside that state. + +If the scope is local, then you can handle it through a simple `useState` hook inside the component itself. + +If on the other hand, you need to store a global state which is accessible for many components, then you can use something like the `Context API` or specific state libraries like Redux, MobX or Zustand. + +The way state handling works in React (in general terms) works like this: + +* State is updated via actions (e.g., event handlers). +* Updated state triggers re-renders to reflect changes in the UI. +* Avoid excessive re-renders by optimizing context or using memoization (`React.memo`, `useMemo`). \ No newline at end of file diff --git a/src/data/question-groups/full-stack/content/relational-vs-nosql.md b/src/data/question-groups/full-stack/content/relational-vs-nosql.md new file mode 100644 index 000000000..18546d0ae --- /dev/null +++ b/src/data/question-groups/full-stack/content/relational-vs-nosql.md @@ -0,0 +1,2 @@ +* **Relational**: Stores data in structured tables with rows and columns (e.g., MySQL, PostgreSQL). Good for relationships and complex queries. +* **Non-relational**: Stores data in flexible formats like documents, key-value pairs, or graphs (e.g., MongoDB, Redis). Better for unstructured or hierarchical data. \ No newline at end of file diff --git a/src/data/question-groups/full-stack/content/responsive-design.md b/src/data/question-groups/full-stack/content/responsive-design.md new file mode 100644 index 000000000..ee971c4d0 --- /dev/null +++ b/src/data/question-groups/full-stack/content/responsive-design.md @@ -0,0 +1,10 @@ +**Responsive design** ensures a website looks good on all devices by adapting its layout to different screen sizes. + +To help ensure this, you can use flexible grids (either `CSS Grid` or `Flexbox`). + +You will also have to apply media queries which help set breakpoints where the different styles need to be applied based on the width of the window: +`@media (max-width: 768px) {` + `.container { flex-direction: column; }` +`}` + +You can also use relative units (`%`, `em`, `rem`) instead of fixed units (`px`) to ensure the values automatically adapt to the size of the container. \ No newline at end of file diff --git a/src/data/question-groups/full-stack/content/rest-api.md b/src/data/question-groups/full-stack/content/rest-api.md new file mode 100644 index 000000000..9b17f871d --- /dev/null +++ b/src/data/question-groups/full-stack/content/rest-api.md @@ -0,0 +1,20 @@ +A **REST API** (Representational State Transfer Application Programming Interface) is a standardized way for applications to communicate over HTTP by following a set of principles. It allows clients (like web browsers or mobile apps) to interact with servers to perform operations like fetching or modifying data. + +**Key Features of a REST API**: + +1. **Stateless Communication**: Each request from the client to the server must contain all the information needed for the server to process it, with no reliance on stored session data. +2. **Resource-Based**: Data and functionality are treated as "resources" accessed using endpoints (URLs). + * Example: `/users` to get a list of users, `/users/1` to access a specific user. +3. **HTTP Methods**: REST APIs use HTTP methods to define actions: + * **GET**: Retrieve data. + * **POST**: Create new resources. + * **PUT**: Update existing resources. + * **DELETE**: Remove resources. +4. **Structured Responses**: Data is typically returned in a lightweight format like **JSON** or **XML**. + +**Why is it Used?** + +* **Interoperability**: REST APIs enable communication between different systems and platforms, making them ideal for building **web services**. +* **Scalability**: They are stateless, allowing them to handle more traffic with horizontal scaling. +* **Ease of Use**: Clear structure and standard conventions make it easy for developers to understand and implement. +* **Flexibility**: Suitable for a variety of clients, from **web applications** to mobile and IoT devices. \ No newline at end of file diff --git a/src/data/question-groups/full-stack/content/rest-pagination.md b/src/data/question-groups/full-stack/content/rest-pagination.md new file mode 100644 index 000000000..3e68f468f --- /dev/null +++ b/src/data/question-groups/full-stack/content/rest-pagination.md @@ -0,0 +1,35 @@ +Adding pagination to a RESTful API can be done in multiple ways, but assuming a standard implementation, the best option is to go with query parameters. + +**Query Parameters**: Using `limit` and `offset` (or `page` and `size`). + +``` +GET /api/items?limit=10&offset=20 +``` + +**Back-End Implementation**: + +In the backend, we’re turn those query params into something like: + +**SQL code:** +```sql +SELECT * FROM items LIMIT 10 OFFSET 20; +``` + +**In code:** +```javascript +const items = await db.find().skip(offset).limit(limit); +res.json({ data: items }); +``` + +##### Metadata + +Include total count and current page in the response for better UX. + +```json +{ + "data": [...], + "total": 100, + "page": 3, + "size": 10 +} +``` \ No newline at end of file diff --git a/src/data/question-groups/full-stack/content/user-authentication.md b/src/data/question-groups/full-stack/content/user-authentication.md new file mode 100644 index 000000000..03dcb94b8 --- /dev/null +++ b/src/data/question-groups/full-stack/content/user-authentication.md @@ -0,0 +1,7 @@ +There are many ways to handle authentication, from simple auth, all the way to oAuth. The right option depends on your particular business needs. +A classical example is using JWT for authenticating a website with a RESTful API using the following process: + +1. **Frontend**: Present a login form to collect credentials from the user. +2. **Backend**: Verify credentials against a database and if they’re valid, create a signed token and return it in the response. +3. **Secure connection**: From this point on, the frontend will send the token on every request and the backend will validate it to ensure it’s a valid and authenticated user. +4. **Secured best practices**: Ensure your passwords are hashed (e.g., with bcrypt) and use HTTPS for a secured data transmission channel. \ No newline at end of file diff --git a/src/data/question-groups/full-stack/content/version-control.md b/src/data/question-groups/full-stack/content/version-control.md new file mode 100644 index 000000000..21a9ca383 --- /dev/null +++ b/src/data/question-groups/full-stack/content/version-control.md @@ -0,0 +1,11 @@ +**Purpose**: Version control tracks changes in code, enables collaboration, and allows reverting to previous versions. + +**Git Workflow Example**: + +1. Clone the repository: `git clone