Agile Flashcards
Agile
The Agile Manifesto outlines four core principles that guide the Agile philosophy:
-
Individuals and Interactions over Processes and Tools:
- Emphasizes the importance of human collaboration and communication over strict adherence to processes and tools.
- Encourages face-to-face conversations and teamwork to solve problems and create better solutions.
-
Working Software over Comprehensive Documentation:
- Prioritizes delivering functional software over producing extensive documentation.
- Documentation is still important, but it should not hinder the progress of delivering working software.
-
Customer Collaboration over Contract Negotiation:
- Stresses the value of ongoing collaboration with customers to ensure the product meets their needs.
- Encourages engaging with customers throughout the development process rather than strictly adhering to initial contract terms.
-
Responding to Change over Following a Plan:
- Highlights the need to be adaptable and responsive to changing requirements, even if they come late in the development process.
- Recognizes that the ability to pivot and adjust plans is more valuable than following a predetermined plan.
Scrum is a framework within Agile that provides specific roles, events, and artifacts to facilitate the Agile process. Key components include:
-
Roles:
- Product Owner: Defines the product backlog and prioritizes requirements.
- Scrum Master: Facilitates the Scrum process and removes impediments.
- Development Team: Cross-functional team members who do the work of delivering the product increment.
-
Events:
- Sprint: A time-boxed period (usually 2-4 weeks) where a potentially shippable product increment is created.
- Sprint Planning: Meeting to define what will be delivered in the upcoming sprint.
- Daily Standup: Short daily meeting to synchronize activities and plan for the next 24 hours.
- Sprint Review: Meeting to demonstrate the completed work to stakeholders.
- Sprint Retrospective: Meeting to reflect on the past sprint and identify improvements.
-
Artifacts:
- Product Backlog: An ordered list of everything that is known to be needed in the product.
- Sprint Backlog: The set of product backlog items selected for the sprint, plus a plan for delivering the product increment and realizing the sprint goal.
- Increment: The sum of all the product backlog items completed during a sprint and the value of the increments of all previous sprints.
Using Agile and Scrum methodologies helps teams deliver high-quality products efficiently and adapt quickly to changing requirements and market conditions.
System design
- Clarify Requirements
- Functional Requirements: What are the main features and functionalities?
- Non-Functional Requirements: What are the performance, scalability, availability, and security requirements?
- High-Level Design
- Architectural Diagram: Create a high-level diagram that shows the main components and their interactions.
- Components: Identify key components such as web servers, databases, load balancers, and caches.
- Detailed Design
- Data Flow: Describe how data flows through the system.
- Database Design: Choose between SQL and NoSQL based on use cases. Define schema and indexing strategies.
- API Design: Define the endpoints, request/response formats, and authentication mechanisms.
- Scalability Considerations
- Load Balancing: Use load balancers to distribute traffic across servers.
- Caching: Implement caching strategies (e.g., CDN, in-memory caches like Redis).
- Database Sharding: Partition data to distribute load across multiple database servers.
- Reliability and Availability
- Redundancy: Design for redundancy to avoid single points of failure.
- Failover Mechanisms: Implement failover strategies for critical components.
- Backup and Recovery: Plan for regular backups and quick recovery mechanisms.
- Security Considerations
- Authentication and Authorization: Implement robust authentication and authorization mechanisms.
- Data Encryption: Encrypt sensitive data in transit and at rest.
- Vulnerability Management: Regularly update and patch systems.
- Monitoring and Maintenance
- Logging: Implement logging for debugging and auditing.
- Monitoring: Use monitoring tools to track system performance and health.
- Alerting: Set up alerts for critical issues.
Example: Design a URL Shortener
- Requirements
- Functional: Shorten URLs, redirect to the original URL, track usage statistics.
- Non-Functional: High availability, low latency, scalable.
- High-Level Design
- Components: Web servers, database, caching layer.
- Diagram: Users interact with the web server, which interacts with the database and cache.
- Detailed Design
- Database Schema: URLs table (short URL, original URL, creation date, usage count).
-
API Endpoints:
-
POST /shorten
to create a short URL. -
GET /{shortURL}
to redirect to the original URL. -
GET /stats/{shortURL}
to get usage statistics.
-
- Scalability
- Load Balancer: Distribute requests across multiple web servers.
- Caching: Cache short URL lookups using Redis.
- Database Sharding: Shard URLs table based on short URL hash.
- Reliability and Availability
- Redundancy: Use multiple instances of web servers and databases.
- Failover: Implement automatic failover for database servers.
- Backups: Regularly back up the database.
- Security
- Authentication: API keys for accessing administrative endpoints.
- Encryption: HTTPS for all communications.
- Rate Limiting: Prevent abuse by limiting the number of URL shortenings per user.
- Monitoring and Maintenance
- Logging: Log all API requests and errors.
- Monitoring: Use tools like Prometheus and Grafana for monitoring.
- Alerting: Set up alerts for high error rates or server downtimes.
typescript basics
TypeScript offers several advantages over JavaScript, particularly for larger projects and teams. Here are some key benefits:
- Static Typing: TypeScript’s type system helps catch errors at compile time, improving code reliability and reducing runtime errors.
- Improved IDE Support: Enhanced autocompletion, navigation, and refactoring capabilities provided by IDEs with TypeScript support increase developer productivity.
- Better Code Readability and Maintainability: Explicit type definitions make code easier to understand and maintain, especially in large codebases.
- Early Bug Detection: Type checks and compile-time errors help detect potential bugs early in the development process.
- Enhanced Refactoring: TypeScript’s static types make refactoring safer and more straightforward.
- Interoperability with JavaScript: TypeScript is a superset of JavaScript, allowing gradual adoption and seamless integration with existing JavaScript code.
- Advanced Features: Supports modern JavaScript features and adds additional capabilities like interfaces, enums, and decorators, enhancing the language’s expressiveness.
- Community and Ecosystem: Strong community support and a growing ecosystem of libraries and tools specifically designed for TypeScript.
Here’s a brief overview of TypeScript basics:
- Basic Types
TypeScript extends JavaScript by adding types. Here are some basic types:
```tsx
typescriptCopy code
let isDone: boolean = false;
let age: number = 30;
let name: string = “John”;
let list: number[] = [1, 2, 3];
let tuple: [string, number] = [“hello”, 10];
let notSure: any = 4;
notSure = “maybe a string instead”;
2. **Interfaces** Interfaces define the shape of an object: ```tsx typescriptCopy code interface Person { firstName: string; lastName: string; } function greet(person: Person) { return `Hello, ${person.firstName} ${person.lastName}`; } let user = { firstName: "Jane", lastName: "Doe" }; console.log(greet(user));
- Classes
TypeScript supports class-based object-oriented programming:
```tsx
typescriptCopy code
class Animal {
private name: string;
constructor(name: string) { this.name = name; } move(distanceInMeters: number = 0) { console.log(`${this.name} moved ${distanceInMeters} meters.`); } }
let dog = new Animal(“Dog”);
dog.move(10);
4. **Modules** Modules are used to organize code: **math.ts** ```tsx typescriptCopy code export function add(x: number, y: number): number { return x + y; }
app.ts
```tsx
typescriptCopy code
import { add } from ‘./math’;
console.log(add(2, 3));
5. **Generics** Generics allow you to create reusable components: ```tsx typescriptCopy code function identity<T>(arg: T): T { return arg; } let output = identity<string>("myString"); let outputNumber = identity<number>(100);
- Enums
Enums allow you to define a set of named constants:
```tsx
typescriptCopy code
enum Color {
Red,
Green,
Blue,
}
let c: Color = Color.Green;
console.log(c); // 1
7. **Type Inference** TypeScript can infer types based on the assigned values: ```tsx typescriptCopy code let inferredString = "This is a string"; // inferred as string let inferredNumber = 10; // inferred as number
- Union Types
Union types allow a variable to be one of several types:
```tsx
typescriptCopy code
let unionType: number | string;
unionType = 5;
unionType = “Hello”;
~~~
These basics should help you get started with TypeScript and understand how it extends JavaScript’s capabilities.
SSR vs CSR
Client-side rendering (CSR) and server-side rendering (SSR) in React have distinct differences in how they handle rendering of the web application. Here’s a brief comparison:
Client-Side Rendering (CSR)
- Rendering Location: Entire React application is rendered in the browser.
- Initial Load Time: Slower initial load as the browser needs to download the JavaScript bundle, then execute it to render the content.
- Subsequent Navigation: Faster after the initial load since the JavaScript is already loaded and can dynamically update the UI without needing full page reloads.
- SEO: Poorer SEO out-of-the-box because search engine crawlers may not execute JavaScript, resulting in empty or incomplete content indexing.
- Complexity: Simpler setup and deployment as it requires only a static file server to serve the HTML, CSS, and JS files.
Server-Side Rendering (SSR)
- Rendering Location: Initial rendering is done on the server, sending fully rendered HTML to the client.
- Initial Load Time: Faster initial load since the browser receives the fully rendered HTML, providing immediate content to the user.
- Subsequent Navigation: Can be slower if every navigation requires a new server request, though this can be mitigated with techniques like partial hydration or caching.
- SEO: Better SEO as the full HTML content is available to search engine crawlers from the start.
- Complexity: More complex setup and deployment, requiring a server to handle the rendering and potentially more sophisticated server infrastructure.
Use Cases
- CSR: Best for web applications where SEO is not a priority and the app is highly interactive with frequent state changes.
- SSR: Ideal for applications where SEO is crucial and the initial page load speed is important for user experience.
Conclusion
Choosing between CSR and SSR depends on your application’s requirements for performance, SEO, and complexity. In many cases, a hybrid approach (using technologies like Next.js) can offer the best of both worlds, providing server-side rendering for initial page loads and client-side rendering for subsequent interactions.
redux
Sure! Redux Toolkit simplifies the process of setting up and using Redux. Here’s an example of how to use Redux Toolkit:
-
Install Redux Toolkit:```
shCopy code
npm install @reduxjs/toolkit react-redux``` -
Create a Redux slice:```jsx
javascriptCopy code
// features/counter/counterSlice.js
import { createSlice } from ‘@reduxjs/toolkit’;const counterSlice = createSlice({
name: ‘counter’,
initialState: { value: 0 },
reducers: {
increment: state => { state.value += 1; },
decrement: state => { state.value -= 1; },
incrementByAmount: (state, action) => { state.value += action.payload; }
}
});export const { increment, decrement, incrementByAmount } = counterSlice.actions;
export default counterSlice.reducer;``` -
Configure the store:```jsx
javascriptCopy code
// app/store.js
import { configureStore } from ‘@reduxjs/toolkit’;
import counterReducer from ‘../features/counter/counterSlice’;const store = configureStore({
reducer: {
counter: counterReducer
}
});export default store;``` -
Setup the Provider:```jsx
javascriptCopy code
// index.js
import React from ‘react’;
import ReactDOM from ‘react-dom’;
import { Provider } from ‘react-redux’;
import store from ‘./app/store’;
import App from ‘./App’;ReactDOM.render(
<Provider store={store}>
<App></App>
</Provider>,
document.getElementById(‘root’)
);``` -
Use the Redux state and actions in a component:```jsx
javascriptCopy code
// features/counter/Counter.js
import React from ‘react’;
import { useSelector, useDispatch } from ‘react-redux’;
import { increment, decrement, incrementByAmount } from ‘./counterSlice’;const Counter = () => {
const count = useSelector((state) => state.counter.value);
const dispatch = useDispatch();return (
<div>
<div>
<button onClick={() => dispatch(decrement())}>-</button>
<span>{count}</span>
<button onClick={() => dispatch(increment())}>+</button>
</div>
<button onClick={() => dispatch(incrementByAmount(2))}>
Increment by 2
</button>
</div>
);
};export default Counter;``` -
Include the component in your app:```jsx
javascriptCopy code
// App.js
import React from ‘react’;
import Counter from ‘./features/counter/Counter’;function App() {
return (
<div>
<h1>Redux Toolkit Counter</h1>
<Counter></Counter>
</div>
);
}export default App;```
This example demonstrates the basic setup and usage of Redux Toolkit, including creating a slice, configuring the store, and using the state and actions in a React component.
Context api
Using the Context API in React allows you to share state across components without having to pass props down manually at every level. Here’s a step-by-step guide:
-
Create a Context:```jsx
javascriptCopy code
import React, { createContext, useState } from ‘react’;const MyContext = createContext();const MyProvider = ({ children }) => {
const [value, setValue] = useState(“default value”);return (
<MyContext.Provider value={{ value, setValue }}>
{children}
</MyContext.Provider>
);
};export { MyContext, MyProvider };``` -
Wrap your component tree with the Provider:```jsx
javascriptCopy code
// index.js
import React from ‘react’;
import ReactDOM from ‘react-dom’;
import App from ‘./App’;
import { MyProvider } from ‘./MyContext’;ReactDOM.render(<MyProvider>
<App></App>
</MyProvider>,
document.getElementById(‘root’)
);``` -
Consume the Context in a component:```jsx
javascriptCopy code
// SomeComponent.js
import React, { useContext } from ‘react’;
import { MyContext } from ‘./MyContext’;const SomeComponent = () => {
const { value, setValue } = useContext(MyContext);return (
<div>
<p>Current Value: {value}</p>
<button onClick={() => setValue(“new value”)}>Change Value</button>
</div>
);
};export default SomeComponent;``` -
Use the component in your app:```jsx
javascriptCopy code
// App.js
import React from ‘react’;
import SomeComponent from ‘./SomeComponent’;function App() {
return (
<div>
<h1>React Context Example</h1>
<SomeComponent></SomeComponent>
</div>
);
}export default App;```
virtual dom
The Virtual DOM (VDOM) in React is a concept where a virtual representation of the UI is kept in memory and synced with the real DOM by a library such as ReactDOM. This process is called reconciliation. The key idea behind the Virtual DOM is to optimize performance by reducing direct manipulations of the actual DOM, which can be slow.
How the Virtual DOM Works:
-
Virtual Representation:
- When a component’s state or props change, React creates a new virtual DOM tree that reflects the changes.
-
Diffing:
- React compares the new virtual DOM tree with the previous virtual DOM tree to identify what has changed. This process is called “diffing.”
-
Reconciliation:
- After identifying the differences, React updates only the parts of the actual DOM that need to be changed. This minimizes the number of direct DOM manipulations, which are typically slower than JavaScript operations.
Benefits of the Virtual DOM:
-
Performance Optimization:
- By batching updates and minimizing direct DOM manipulations, the Virtual DOM can significantly improve performance, especially in applications with complex UIs and frequent updates.
-
Abstraction:
- Developers can write declarative code and let React handle the updates efficiently under the hood, leading to simpler and more maintainable code.
-
Cross-platform Rendering:
- The concept of the Virtual DOM allows for rendering on different platforms, such as server-side rendering (SSR) and React Native for mobile applications.
HTML rendering
When a browser renders an HTML tag on a webpage, it follows these steps:
Parse the HTML: The browser reads the HTML document and converts it into a tree structure called the Document Object Model (DOM). Each HTML tag becomes a node in this tree.
Style the Elements: The browser processes the CSS (Cascading Style Sheets) associated with the HTML document. CSS rules are applied to the DOM elements to determine their visual style (e.g., size, color, position).
Layout Calculation: The browser calculates the position and size of each element based on the CSS rules, the DOM structure, and the dimensions of the viewport (the visible area of the webpage).
Painting: The browser paints the pixels on the screen based on the calculated styles and layout. This involves drawing text, images, and other visual elements.
Compositing: For complex pages with overlapping elements, the browser may use a compositing step to layer different parts of the page correctly. This is especially common for animations and transformations.