Mean Stack Technology
Mean Stack Technology
UNIT-I:
1)Explain in detail the various protocols used in the Internet with examples (HTTP,
FTP, SMTP)?
Internet Protocol:
Internet Protocol (IP) is a set of rules that allows devices to communicate with each other
over the Internet. It is like the address system used for sending data. Every device connected
to the internet has a unique IP address that helps data know where to go and where it is
coming from.
Internet Protocols are of different types having different uses. These are mentioned below:
3. PPP(Point-to-Point Protocol)
8. TELNET(Terminal Network)
10. IPv4
11. IPv6
12. ICMP
13. UDP
14. IMAP
15. SSH
16. Gopher
1. HTTP (Hypertext Transfer Protocol)
working:
Client initiates request: A web browser (client) sends an HTTP request to a web
server when a user types a URL or clicks a link.
Server processes request: The web server receives the request, processes it, and
retrieves the requested resource (e.g., an HTML file, an image, a video).
Server sends response: The server then sends an HTTP response back to the client,
which includes the requested resource and a status code (e.g., 200 OK for success,
404 Not Found for an error).
Client renders content: The browser receives the response and renders the content
for the user.
Examples:
When you type https://www.google.com into your browser, your browser sends an
HTTP GET request to Google's server. The server responds with the HTML code,
images, and other resources that make up the Google search page.
When you fill out a login form on a website and click "Submit", your browser sends
an HTTP POST request containing your username and password to the server.
working: FTP establishes two separate connections between the client and server:
Control Connection (Port 21): This connection is used for sending commands (e.g.,
"GET filename", "PUT filename", "LIST") and receiving responses from the server
(e.g., "200 OK", "550 File not found"). This connection remains open throughout the
FTP session.
Data Connection (Port 20 for active mode, ephemeral port for passive mode):
This connection is established dynamically for the actual transfer of data (the file
contents).
Examples:
Uploading a website: A web developer uses an FTP client (like FileZilla or WinSCP)
to connect to a web hosting server and upload HTML, CSS, JavaScript files, and
images to make their website accessible online.
Downloading large software: A user might download a software installer from a
company's FTP server.
Backup: Organizations might use FTP to transfer daily backups of data to an off-site
server.
Purpose: SMTP is an application-layer protocol used for sending and receiving email
messages over the Internet. It defines the rules for how email servers communicate
with each other to deliver mail and how email clients send messages to a server for
delivery.
working:
1. Sending Email (Client to Server): When you send an email from your email client
(e.g., Outlook, Gmail web interface), your client connects to your outgoing mail
server (SMTP server). It sends the email message, including sender, recipient, subject,
and body, using SMTP commands.
2. Server-to-Server Transfer: Your SMTP server then looks up the recipient's domain
name (e.g., example.com) to find the corresponding mail exchange (MX) record using
DNS. The MX record points to the recipient's mail server. Your SMTP server then
connects to the recipient's SMTP server and transfers the email using SMTP.
3. Receiving Email (Server to Client): Once the email arrives at the recipient's mail
server, it waits for the recipient to retrieve it. This retrieval process typically uses
other protocols like POP3 or IMAP, not SMTP. SMTP is primarily for sending mail
between servers and from clients to servers.
Examples:
When you hit "Send" in your Gmail client to send an email to a friend using an
Outlook account:
1. Your Gmail client sends the email to Google's SMTP servers.
2. Google's SMTP servers locate the Outlook mail server for your friend's
domain.
3. Google's SMTP servers communicate with the Outlook mail server using
SMTP to deliver the email.
4. Your friend's Outlook client later retrieves the email from their Outlook mail
server using POP3 or IMAP.
Automated system notifications: A web server might use SMTP to send an email to an
administrator when an error occurs or a scheduled task completes.
2)Discuss the core components and structure of a modern HTML5 web page, including
the use of CSS3?
HTML5 is the latest major revision of the Hypertext Markup Language, the standard
language for creating web pages. It introduces new elements, attributes, and APIs that
facilitate more semantic, interactive, and multimedia-rich web content.
A modern HTML5 web page adheres to a specific structure to ensure proper rendering by
browsers, accessibility for users, and search engine optimization.
Purpose: This declaration at the very beginning of the HTML document tells the web
browser which version of HTML the page is written in.
HTML5 Specific: For HTML5, it's the simplest and most widely used declaration.
Example:
HTML
<!DOCTYPE html>
Purpose: This is the root element that encloses all other content on the HTML page.
lang attribute: It's highly recommended to include the lang attribute to declare the
primary language of the document (e.g., lang="en" for English). This is important for
accessibility (screen readers), search engines, and browser rendering.
Example:
HTML
<html lang="en">
</html>
Purpose: The <head> element contains meta-information about the HTML document
that is not displayed on the web page itself but is crucial for browser rendering, search
engines, and other web services.
Key Elements within <head>:
o <meta charset="UTF-8">: Crucial! Specifies the character encoding for the
document, typically UTF-8, which supports almost all characters and symbols
in the world. This should be the first element inside <head> after
<!DOCTYPE html>.
o <meta name="viewport" content="width=device-width, initial-
scale=1.0">: Essential for Responsive Design! Configures the viewport for
mobile devices. width=device-width sets the viewport width to the device's
screen width, and initial-scale=1.0 sets the initial zoom level.
o <title>: Defines the title of the web page, which appears in the browser's title
bar or tab. It's important for SEO and user experience.
o <link rel="stylesheet" href="styles.css">: Links an external CSS stylesheet
to the HTML document. The rel="stylesheet" attribute indicates the
relationship, and href specifies the path to the CSS file.
o <style>: Contains internal CSS styles directly within the HTML document
(less common for complex styling, but useful for quick tests or very specific
page styles).
o <script>: Can link external JavaScript files or contain inline JavaScript. Often
placed at the end of <body> for performance reasons (to allow HTML content
to render before scripts execute).
o <meta name="description" content="A brief description of the page's
content.">: Provides a concise summary of the page's content for search
engine results.
o <meta name="keywords" content="html5, web design, example">: (Less
critical for modern SEO, but can still be included) Lists keywords relevant to
the page's content.
o <link rel="icon" href="favicon.ico" type="image/x-icon">: Defines the
favicon (the small icon displayed in the browser tab).
Example:
HTML
<head>
<meta charset="UTF-8">
</head>
Purpose: The <body> element contains all the visible content of the web page. This
is where users interact with the text, images, videos, forms, and other elements.
HTML5 Semantic Elements: HTML5 introduced several new semantic elements to
give more meaning and structure to the content, improving accessibility and SEO.
o <header>: Represents introductory content, usually containing navigation,
logos, and headings.
o <nav>: Contains navigation links (e.g., primary menu).
o <main>: Represents the dominant content of the <body>. There should only
be one <main> element per document.
o <article>: Represents a self-contained composition (e.g., a blog post, a news
article).
o <section>: Represents a standalone section of content, often with its own
heading. Can group related content.
o <aside>: Represents content that is tangentially related to the content around it
(e.g., a sidebar, pull quotes).
o <footer>: Represents a footer for its nearest sectioning content or the root
element. Typically contains copyright information, contact info, related links.
o <figure> and <figcaption>: For self-contained content, like images or
diagrams, with an optional caption.
o <mark>: Highlights text.
o <time>: Represents a specific time or date.
Common Inline and Block-level Elements:
o Headings: <h1> to <h6>
o Paragraphs: <p>
o Lists: <ul> (unordered), <ol> (ordered), <li> (list item)
o Links: <a>
o Images: <img>
o Forms: <form>, <input>, <label>, <button>, <textarea>, <select>
o Divisions: <div> (generic block-level container, used when no semantic
element fits)
o Spans: <span> (generic inline container, used when no semantic element fits)
Example (Simplified Body Structure):
HTML
<body>
<header>
<nav>
<ul>
<li><a href="/">Home</a></li>
<li><a href="/contact">Contact</a></li>
</ul>
</nav>
</header>
<main>
<section>
<h2>Welcome!</h2>
</section>
<article>
</article>
</main>
<aside>
<h4>Related Links</h4>
<ul>
</ul>
</aside>
<footer>
</footer>
</body>
Use of CSS3:
CSS3 (Cascading Style Sheets, Level 3) is the latest evolution of CSS, designed to style
HTML documents. It defines how HTML elements are to be displayed, including colors,
fonts, layout, and responsiveness.
CSS
body {
margin: 0;
padding: 0;
background-color: #f4f4f4;
header {
background-color: #333;
color: #fff;
padding: 1rem 0;
text-align: center;
nav ul {
list-style: none;
padding: 0;
nav li {
display: inline;
margin: 0 15px;
main {
padding: 20px;
max-width: 960px;
background-color: #fff;
o
Advantages:
Separation of Concerns: Keeps HTML for structure and CSS for
presentation, making code cleaner and easier to manage.
Caching: Browsers can cache external CSS files, leading to faster
page loading on subsequent visits.
Reusability: A single CSS file can style multiple HTML pages.
2. Internal Stylesheets:
o Mechanism: CSS rules are placed directly within a <style> tag inside the
HTML document's <head> section.
o Example (HTML):
HTML
<head>
<style>
h1 {
color: navy;
text-align: center;
p{
font-size: 16px;
</style>
</head>
HTML
o Advantages: Useful for very specific, one-off styling or dynamic styling with
JavaScript.
o Disadvantages: Strongly discouraged for general styling. Violates
separation of concerns, makes code harder to maintain, overrides
external/internal styles (high specificity), and prevents caching.
CSS
.container {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
.column {
padding: 20px;
.column {
.column {
3)What is XSLT? Explain how XSLT can be used to transform XML documents.
Think of XSLT as a powerful "recipe" or "template" language for XML. It describes how to
convert an XML source document into a desired result document by matching patterns in the
source and then instructing how to construct the output based on those matches.
1. Source Tree Construction: The XSLT processor first parses the XML source
document and builds an internal tree representation of it (the "source tree").
2. Stylesheet Parsing: The XSLT processor parses the XSLT stylesheet and
understands its templates and rules.
3. Template Matching and Application:
o The processor starts at the root node of the source tree.
o It looks for an XSLT template (<xsl:template>) in the stylesheet that best
matches the current node in the source tree (using an XPath match attribute).
o When a match is found, the instructions within that template are executed.
These instructions typically involve:
Creating literal result elements: Directly writing HTML tags, new
XML tags, or plain text into the output.
Copying content: Using <xsl:value-of select="XPathExpression"/> to
extract data from the source XML and insert it into the output.
Applying other templates: Using <xsl:apply-templates
select="XPathExpression"/> to recursively process child nodes or
other selected nodes in the source tree, thereby applying other relevant
templates. This allows for complex, hierarchical transformations.
Conditional logic: Using <xsl:if> or <xsl:choose> to apply rules
based on conditions.
Looping: Using <xsl:for-each> to iterate over collections of elements.
Sorting: Using <xsl:sort> to order elements.
Creating attributes: Using
Creating elements: Using
4. Result Tree Serialization: As the templates are processed, a new "result tree" is built
in memory. Once the transformation is complete, the processor serializes this result
tree into the desired output format (e.g., an HTML file, a new XML file, or plain text).
4)Describe in detail the DOM approach for XML parsing with a relevant example in
Java or JavaScript?
The Document Object Model (DOM) is a programming interface for HTML and XML
documents. It defines the logical structure of documents and the way a document is accessed
and manipulated. When an XML parser uses the DOM approach, it parses the entire XML
document and builds an in-memory tree representation of that document.
1. In-Memory Tree Representation: The most defining feature of DOM parsing is that
it loads the entire XML document into memory and represents it as a hierarchical tree
structure. Each component of the XML document (elements, attributes, text,
comments, etc.) becomes a node in this tree.
2. Random Access: Once the tree is built, you can navigate and access any part of the
document using the tree structure. You can go up, down, or sideways through the
nodes. This allows for random access and manipulation of the document's content.
3. Read and Write Operations: DOM parsers allow you to not only read the content of
an XML document but also to modify its structure, add new elements, delete existing
ones, change attribute values, and then save the modified document back to a file or
stream.
4. Language Independent: The DOM is a W3C standard, meaning it's a language- and
platform-neutral interface. Implementations are available in various programming
languages like Java, JavaScript, Python, C#, etc.
5. Synchronous Processing: DOM parsing is typically synchronous, meaning the entire
document is processed and the tree is built before you can start interacting with it.
In the DOM tree, various types of nodes represent different parts of the XML document:
Document Node: The root of the DOM tree, representing the entire XML document
itself.
Element Node: Represents an XML element (e.g., <book>, <title>).
Attribute Node: Represents an attribute of an element (e.g., id="bk101").
Text Node: Represents the actual text content within an element (e.g., "The
Hitchhiker's Guide to the Galaxy").
Comment Node: Represents an XML comment (``).
Processing Instruction Node: Represents processing instructions (e.g., <?xml-
stylesheet ...?>).
Ease of Navigation and Manipulation: Once the tree is in memory, it's very
straightforward to access, modify, and restructure the document's content using well-
defined methods.
Random Access: You can jump to any part of the document without having to parse
the entire document sequentially from the beginning again.
Flexibility: Ideal for scenarios where you need to perform multiple operations on the
document, or where the order of operations is not strictly sequential.
Let's use a simple XML file and then demonstrate how to parse it using Java's built-in DOM
API (javax.xml.parsers and org.w3c.dom).
XML
<library>
<book id="bk101">
<author>Douglas Adams</author>
<year>1979</year>
<price>12.99</price>
</book>
<book id="bk102">
<title>1984</title>
<author>George Orwell</author>
<year>1949</year>
<price>9.50</price>
</book>
</library>
Java
import org.w3c.dom.*;
import javax.xml.parsers.*;
import java.io.File;
try {
// factory.setValidating(true);
// factory.setNamespaceAware(true);
doc.getDocumentElement().normalize();
System.out.println("----------------------------");
if (bookNode.getNodeType() == Node.ELEMENT_NODE) {
// Get attribute
} catch (ParserConfigurationException e) {
e.printStackTrace();
e.printStackTrace();
e.printStackTrace();
if (nodeList.getLength() > 0) {
return nodeList.item(0).getTextContent();
1. Save the XML content as books.xml in the same directory as your Java file.
2. Save the Java code as DomParserExample.java.
3. Compile: javac DomParserExample.java
4. Run: java DomParserExample
Expected Output:
----------------------------
Book ID : bk101
Year : 1979
Price : 12.99
Book ID : bk102
Title : 1984
Price : 9.50
5)Compare DOM and SAX approaches in terms of memory usage, performance, and
ease of use with examples?
1. Memory Usage
2. Performance
DOM:
o Initial Overhead: There's a significant initial overhead for DOM parsing
because it needs to read and process the entire document to build the in-
memory tree.
o Slower for Large Files (Initial Parse): For very large files, the initial parsing
time can be considerably slower than SAX due to the overhead of object
creation and memory management for the entire tree.
o Faster for Random Access/Manipulation (Once Parsed): Once the DOM
tree is built, subsequent access to any part of the document (random access,
searching, modification) is generally very fast. If you need to read the
document multiple times or modify it, the initial overhead can be amortized.
SAX:
o Faster for Large Files (Sequential Parse): SAX is generally faster for
parsing large documents because it processes data sequentially and doesn't
incur the memory overhead of building a tree. It's "fire and forget" for events.
o Single Pass: It reads the document in a single pass from start to finish.
o Slower for Random Access/Complex Logic: If you need to revisit previously
parsed data or perform complex logic that requires knowledge of the
document's entire structure (e.g., finding all authors of books published after a
certain year, requiring values from different parts of the tree), SAX can
become more complex and potentially slower to implement. You would need
to manage your own data structures to hold relevant information.
3. Ease of Use
DOM:
o Higher Ease of Use (for many tasks): The tree-like structure of DOM is very
intuitive and maps directly to how humans often conceptualize XML. It
provides methods like getElementsByTagName(), getParentNode(),
getChildNodes(), getAttribute(), making navigation and direct manipulation
relatively straightforward.
o Good for Simple Data Extraction/Manipulation: For tasks where you need
to get a few pieces of data, modify some values, or rearrange elements, DOM's
API is generally easier to work with.
o Debugging: The ability to inspect the entire document in memory can
sometimes make debugging easier.
SAX:
o Lower Ease of Use (more boilerplate): SAX is more programmatic and
requires you to write "event handlers" (callback methods) for specific events
(e.g., startElement, endElement, characters). You have to maintain your own
"state" as you parse the document to understand the context of the data.
o Steep Learning Curve for Complex Tasks: If you need to extract data that
depends on elements appearing in a specific order or context, SAX code can
become quite intricate, involving flags and state machines.
o No Direct Manipulation: SAX is read-only. You cannot directly modify the
XML document using a SAX parser. If you need to change the XML, you
must build a new document based on the parsed events.
Examples
books.xml:
XML
<library>
<book id="bk101">
<author>Douglas Adams</author>
<year>1979</year>
<price>12.99</price>
</book>
<book id="bk102">
<title>1984</title>
<author>George Orwell</author>
<year>1949</year>
<price>9.50</price>
</book>
</library>
In a web browser, the DOM is readily available. You can load XML via XMLHttpRequest or
fetch and then parse it.
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body>
<script>
const xmlString = `
<library>
<book id="bk101">
<author>Douglas Adams</author>
<year>1979</year>
<price>12.99</price>
</book>
<book id="bk102">
<title>1984</title>
<author>George Orwell</author>
<year>1949</year>
<price>9.50</price>
</book>
</library>
`;
if (errorNode) {
} else {
const id = book.getAttribute("id");
bookListElement.appendChild(listItem);
</script>
</body>
</html>
DOM Example Explanation (JavaScript):
SAX in Java requires you to define a DefaultHandler class and override its callback methods.
Java
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
private boolean isTitle = false; // Flag to know if we are inside a <title> tag
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes)
throws SAXException {
// qName is the qualified name (e.g., "book", "title")
if (qName.equalsIgnoreCase("title")) {
// if (qName.equalsIgnoreCase("book")) {
// String id = attributes.getValue("id");
// }
@Override
if (qName.equalsIgnoreCase("title")) {
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
titles.add(title);
}
public List<String> getTitles() {
return titles;
try {
saxParser.parse(xmlFile, handler);
}
} catch (Exception e) {
e.printStackTrace();
Expected Output:
- 1984
Feature DOM (Document Object Model) SAX (Simple API for XML)
Memory High (loads entire document into Low (processes sequentially, holds
Usage memory) little in memory)
Slower initial parse for large files; Faster initial parse for large files;
Performance faster for random access/manipulation slower/more complex for random
after loading access/manipulation
Generally easier for most common More complex; requires event
Ease of Use
tasks; intuitive tree navigation handling logic and state management
Read and write (modify, add, delete Read-only (event-driven, cannot
Capabilities
nodes) modify document directly)
Small to medium XML files; when Large XML files/streams; when
Best Suited
modifications are needed; when memory is critical; when data can be
For
random access is required processed in a single pass
UNIT-II:
/**
*/
// Each student will be an object with properties: name, grades (an array), isActive
/**
*/
const newStudent = {
name: name,
};
return newStudent;
/**
*/
return false;
if (student) {
student.grades.push(grade); // Modifying an array element (grades is an array)
return true;
} else {
return false;
/**
*/
function calculateStudentAverage(studentId) {
if (!student) {
if (student.grades.length === 0) {
}
let sum = 0;
// Loop through the grades array using for...of loop (modern way)
sum += grade;
/**
*/
function displayAllStudents() {
if (students.length === 0) {
return;
if (student.isActive) {
} else {
console.log("----------------------------");
/**
*/
function findStudentById(id) {
}
}
return null; // Return null if not found after checking all students
/**
*/
function toggleStudentStatus(studentId) {
if (student) {
} else {
/**
*/
function removeStudent(studentId) {
const initialLength = students.length;
// Array.filter() creates a new array with elements that pass the test
} else {
/**
*/
switch (command.toLowerCase()) {
addStudent(param1, param2);
} else {
break;
addGrade(param1, param2);
} else {
break;
displayAllStudents();
break;
} else {
break;
} else {
break;
removeStudent(param1);
} else {
break;
default:
// --- 3. Program Execution (Demonstrating function calls and control flow) ---
processCommand('display all');
// Demonstrate reactivating
Detailed Explanation:
2)Discuss the use of constructors in JavaScript with a custom object creation example?
Constructors in JavaScript:
In JavaScript, a constructor is a special function used to create and initialize objects. When
you create an object using the new keyword, the constructor function is called. Its primary
purpose is to set up the initial state (properties) of the new object.
this.name = name;
this.age = age;
this.sayHello = function () {
};
Explanation:
3)Explain AngularJS two-way data binding and its advantages with code examples?
AngularJS's two-way data binding is a powerful feature that automatically synchronizes data
between the model (your JavaScript data) and the view (your HTML). This means that any
change in the model is immediately reflected in the view, and any change in the view (e.g.,
user input in a form field) is immediately reflected in the model, without requiring you to
write explicit DOM manipulation code.
This synchronization happens in real-time, creating a highly responsive and interactive user
interface.
1. Reduced Boilerplate Code: This is the biggest advantage. Developers don't need to
write manual DOM manipulation code (e.g.,
document.getElementById('myInput').value = myData; or event listeners like
addEventListener('input', ...)). AngularJS handles the synchronization automatically.
2. Increased Productivity: By minimizing the code required for UI updates, developers
can build interactive applications much faster.
3. Simpler Application Logic: The separation of concerns becomes clearer. Your
JavaScript model focuses purely on data and business logic, while the HTML view
focuses on presentation. The binding handles the communication.
4. Real-Time Updates: Provides an instant and fluid user experience as changes are
reflected immediately.
5. Easier to Reason About: For simpler applications, the direct link between model and
view makes the application flow easier to understand. You change data, the UI
updates; you change UI, the data updates.
Code Examples
<!DOCTYPE html>
<html>
<head>
<title>
</title>
<script src=
"https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.7/angular.min.js">
</script>
</head>
<body ng-app="">
<h1>GeeksforGeeks</h1>
<form>
<input type="text"
ng-model="name">
</form>
<p>{{name}}</p>
</body>
</html>
4)Describe the entire process of building a Single Page Application using AngularJS?
A Single Page Application (SPA) is a web application that dynamically updates a single
HTML page, avoiding full page reloads and providing a smoother, faster user experience.
AngularJS, a powerful JavaScript framework maintained by Google, was designed
specifically for building SPAs.
a. Include AngularJS
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.8.2/angular.min.js"></script>
/myApp
├── index.html
├── app.js
├── controllers/
│ └── MainController.js
├── views/
├── home.html
└── about.html
<html ng-app="myApp">
<head>
<title>AngularJS SPA</title>
</head>
<body>
<a href="#!/home">Home</a> |
<a href="#!/about">About</a>
<div ng-view></div>
<script
src="https://ajax.googleapis.com/ajax/libs/angularjs/1.8.2/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.8.2/angular-
route.js"></script>
<script src="app.js"></script>
<script src="controllers/MainController.js"></script>
</body>
</html>
// Configure routes
app.config(function($routeProvider) {
$routeProvider
.when("/home", {
templateUrl: "views/home.html",
controller: "MainController"
})
.when("/about", {
templateUrl: "views/about.html",
controller: "MainController"
})
.otherwise({
redirectTo: "/home"
});
});
app.controller("MainController", function($scope) {
});
home.html
<h2>Home Page</h2>
about.html
<h2>About Page</h2>
5)Write a JavaScript code using regular expressions to validate an email address, and
explain how pattern matching works?
JavaScript
/**
*/
function validateEmail(email) {
// but a truly comprehensive and RFC-compliant regex is very complex and long.
// This one covers most common cases and is widely used for practical validation.
if (isValid) {
} else {
console.log(`"${email}" is an INVALID email address.`);
return isValid;
validateEmail("test@example.com"); // Valid
validateEmail("john.doe@sub.domain.co.uk"); // Valid
validateEmail("user123@mail-server.net"); // Valid
console.log(regexString);
1. / (Forward Slashes):
o In JavaScript (and many other languages), forward slashes // delimit the
regular expression literal. Anything between them is the pattern.
2. ^ (Caret - Start of String Anchor):
o This is an anchor. It asserts that the pattern must match from the beginning of
the input string. If the pattern doesn't start at the very first character of the
string, it's not considered a match.
o Example: If we had ^abc and tested against "xabc", it wouldn't match. Against
"abc" or "abcdef", it would.
3. [a-zA-Z0-9._%+-]+ (Local Part - Before the @):
o This is a character set ([]) followed by a quantifier (+).
o [a-zA-Z0-9._%+-]: This character set defines the allowed characters for the
"local part" of the email address (the part before the @).
a-zA-Z: Any lowercase or uppercase letter.
0-9: Any digit.
_: Underscore.
.: Dot (period).
%: Percent sign.
+: Plus sign.
-: Hyphen.
o + (One or More Quantifier): This quantifier means that the preceding
character set [...] must appear one or more times. It ensures the local part is
not empty.
o Pattern Match Logic: The engine looks for at least one character from the
defined set at the beginning of the string. It then consumes as many
consecutive characters as possible that also belong to this set.
4. @ (Literal @):
o This is a literal character. It simply matches the @ symbol exactly as it
appears.
o Pattern Match Logic: After successfully matching the local part, the engine
looks for an @ symbol. If it's not there, the match fails.
5. [a-zA-Z0-9.-]+ (Domain Name Part - Before the Top-Level Domain):
o Another character set followed by a quantifier. This defines the allowed
characters for the main part of the domain name.
o [a-zA-Z0-9.-]:
a-zA-Z: Any letter.
0-9: Any digit.
.: Dot.
-: Hyphen.
o + (One or More Quantifier): Ensures there's at least one character in this part
of the domain.
o Pattern Match Logic: After the @, the engine looks for one or more characters
from this set.
6. \. (Escaped Dot - Literal Dot):
o The . (dot) character in regex has a special meaning: it matches any single
character (except newline).
o To match a literal dot (like in .com, .org), it needs to be escaped with a
backslash (\). So, \. matches a literal period.
o Pattern Match Logic: The engine expects a literal dot after the domain name
part.
7. [a-zA-Z]{2,} (Top-Level Domain - TLD):
o [a-zA-Z]: Matches any single letter (uppercase or lowercase).
o {2,} (Quantifier - Minimum 2): This quantifier means the preceding
character set [a-zA-Z] must appear at least 2 times. It implies that the top-
level domain (like com, org, net, co.uk) must be at least two letters long.
o Pattern Match Logic: After the literal dot, the engine looks for at least two
consecutive letters.
8. $ (Dollar Sign - End of String Anchor):
o This is another anchor. It asserts that the pattern must match up to the end of
the input string.
o Example: If we had abc$ and tested against "abcdef", it wouldn't match.
Against "abc", it would.
UNIT-III:
Node.js's architecture can be broken down into several key components that work in
harmony:
V8 JavaScript Engine:
o Role: This is the heart of Node.js. V8 is an open-source, high-performance
JavaScript and WebAssembly engine written in C++. It compiles JavaScript
code directly into machine code before execution, making it extremely fast.
o Functionality: It handles the execution of your JavaScript code, memory
allocation (garbage collection), and call stack management.
o Single-Threaded JavaScript Execution: Crucially, V8 itself is single-
threaded. This means your JavaScript code runs on a single main thread.
Libuv:
o Role: This is a multi-platform asynchronous I/O library written in C. It
provides Node.js with its non-blocking I/O capabilities.
o Functionality: Libuv abstracts away the underlying operating system's
complexities for I/O operations (file system, networking, DNS, child
processes, etc.). It manages a thread pool (for blocking operations) and an
event loop (for non-blocking operations).
o How it supports non-blocking: When Node.js encounters an I/O operation
(e.g., reading a file, making a network request), it hands it off to Libuv. Libuv
then performs this operation in the background (potentially using its internal
thread pool for truly blocking OS calls or using OS-specific non-blocking
APIs like epoll, kqueue, IOCP). Once the I/O operation completes, Libuv
notifies the Event Loop.
Event Loop:
o Role: This is the core mechanism that enables Node.js's non-blocking,
asynchronous behavior despite its single-threaded JavaScript execution. It's
not part of V8, but rather a separate component (primarily implemented by
Libuv).
o Functionality: The Event Loop continuously monitors the call stack (where
JavaScript code executes) and the callback queue (where completed
asynchronous operations place their callbacks).
o "Run-to-completion" Model: The Event Loop ensures that a callback
function is only executed when the call stack is empty. This prevents race
conditions and simplifies concurrency model.
Node.js Bindings (C++ Addons):
o Role: These are C++ bindings that connect the JavaScript layer (V8) to the
underlying C/C++ libraries like Libuv and other system-level functionalities.
o Functionality: They expose low-level system APIs to JavaScript, allowing
Node.js to perform tasks like file system access, network communication, and
cryptographic operations efficiently.
Node.js Standard Library (JavaScript APIs):
o Role: This is the high-level, user-facing JavaScript API that Node.js provides
(e.g., fs module for file system, http module for networking, crypto module).
o Functionality: These APIs often wrap the C++ bindings and Libuv
functionalities, presenting them in a familiar JavaScript asynchronous pattern
(callbacks, promises, async/await).
This cycle of JavaScript execution → I/O offload → Call Stack empty → Callback
execution is what defines Node.js's event-driven, non-blocking model.
Let's build an Express.js application that demonstrates CRUD (Create, Read, Update, Delete)
operations and routing. We'll create a simple API for managing a list of books.
Project Setup
First, create a new directory for your project and initialize it:
Bash
mkdir express-crud-app
cd express-crud-app
npm init -y
Bash
Project Structure
express-crud-app/
├── app.js
└── data/
└── books.json
1. data/books.json (Our "Database")
This file will simulate a simple database. In a real application, you'd use a database like
MongoDB, PostgreSQL, MySQL, etc.
JSON
"id": "1",
"year": 1979
},
"id": "2",
"title": "1984",
"year": 1949
},
"id": "3",
"year": 1813
This file will contain all the Express.js code for routing and CRUD operations.
JavaScript
const fs = require('fs');
app.use(express.json());
function readBooks() {
try {
return JSON.parse(data);
} catch (error) {
}
// Function to write books to the JSON file
function writeBooks(books) {
try {
} catch (error) {
});
// Basic validation
newBook.id = newId;
books.push(newBook);
writeBooks(books);
});
res.status(200).json(books);
});
res.status(200).json(book);
} else {
});
const { id } = req.params;
writeBooks(books);
} else {
});
// 5. DELETE a book by ID (DELETE /api/books/:id)
const { id } = req.params;
books = books.filter(b => b.id !== id); // Filter out the book to be deleted
writeBooks(books);
} else {
});
app.listen(PORT, () => {
console.log('API Endpoints:');
});
1. Save the files: Make sure app.js and data/books.json are correctly placed.
2. Start the server: Open your terminal in the express-crud-app directory and run:
Bash
node app.js
JSON
"year": 1954
}
Expected: 201 Created with the new book object (including its
generated ID). Check books.json to see the updated data.
JSON
"price": 25.00
Expected: 200 OK with the updated book object. Note how author and
year are preserved and price is added, while id remains the same.
o Delete a book:
URL: http://localhost:3000/api/books/2 (use an ID that exists, e.g., the
one for "1984")
Method: DELETE
Expected: 200 OK with a success message. Check books.json to
confirm the book is removed.
o Delete a non-existent book:
URL: http://localhost:3000/api/books/99
Method: DELETE
Expected: 404 Not Found with a message.
In Express.js, middleware functions are functions that have access to the request object (req),
the response object (res), and the next function in the application's request-response cycle.
The next() function is a crucial part of middleware: it's a callback that executes the next
middleware function in the stack.
Middleware functions can perform a variety of tasks:
Think of middleware as a series of processing steps that a request goes through on its way to
its final destination (the route handler) and on its way back out as a response.
Types of Middleware
When an HTTP request arrives at your Express application, it enters a "middleware stack."
Express processes each middleware function in the order they are defined.
Request arrives -> Middleware 1 -> Middleware 2 -> Middleware 3 -> Route Handler ->
Response Sent
| | |
If any middleware function sends a response (e.g., res.send(), res.json()), the request-response
cycle is terminated, and no subsequent middleware or route handlers for that request will be
executed.
Let's use the previous Express app structure and add various types of middleware.
JavaScript
const fs = require('fs');
// --- Helper Functions for Data Persistence (from previous example) ---
function readBooks() {
try {
return JSON.parse(data);
} catch (error) {
return [];
return [];
function writeBooks(books) {
try {
} catch (error) {
app.use(express.json());
app.use(morgan('dev'));
next(); // IMPORTANT: Call next() to pass control to the next middleware/route handler
});
next();
} else {
console.warn("Middleware: Admin API Key missing or invalid. Access denied.");
});
app.use(express.static('public'));
});
} else {
});
return res.status(400).json({ message: 'Title, author, and year are required.' });
newBook.id = newId;
books.push(newBook);
writeBooks(books);
});
res.status(200).json(books);
});
const { id } = req.params;
if (book) {
res.status(200).json(book);
} else {
});
// 4. UPDATE an existing book by ID (PUT /api/books/:id)
const { id } = req.params;
writeBooks(books);
} else {
});
const { id } = req.params;
writeBooks(books);
} else {
});
// This will catch any errors thrown by previous middleware or route handlers.
res.status(500).json({
});
});
app.listen(PORT, () => {
});
4) Discuss API handling and error handling in Express.js.?
1. Routing:
o Definition: The process of determining how an application responds to a
client request to a particular endpoint, which is a URI (or path) and a specific
HTTP method (GET, POST, etc.).
o Express Methods: Express provides methods for all standard HTTP verbs:
app.get(), app.post(), app.put(), app.delete(), app.patch(), etc.
o Route Parameters: You can define dynamic segments in a URL using colons
(:). For example, /api/users/:id will match /api/users/123, and req.params.id
will be "123".
o Query Parameters: Data sent in the URL after a ? (e.g.,
/api/products?category=electronics&limit=10). Accessible via req.query.
o Request Body: For POST, PUT, PATCH requests, data is often sent in the
request body (e.g., JSON). Express middleware like express.json() (or body-
parser for older versions) parses this into req.body.
2. Request (req) Object:
o Represents the HTTP request and has properties for the request query string,
parameters, body, HTTP headers, etc.
o Key properties: req.params, req.query, req.body, req.headers, req.method,
req.url.
3. Response (res) Object:
o Represents the HTTP response that an Express app sends when it gets an
HTTP request.
o Key methods:
res.send(): Sends various types of HTTP responses.
res.json(): Sends a JSON response. Automatically sets Content-Type:
application/json.
res.status(statusCode): Sets the HTTP status code (e.g., 200, 404, 500).
res.setHeader(name, value): Sets an HTTP response header.
res.end(): Ends the response process.
4. Middleware (as discussed previously):
o Middleware functions process requests before they reach route handlers. They
are crucial for tasks like:
Parsing request bodies (express.json()).
Logging requests (morgan).
Authentication/Authorization checks.
Data validation.
Adding common headers (e.g., CORS).
Error Handling in Express.js
Effective error handling is crucial for any robust application. In Express.js, error handling is
typically managed through middleware functions specifically designed to catch and process
errors.
5) How do you secure and deploy a Node.js application for production? Include steps
and tools used (e.g., PM2, Helmet)?
Security must be built into your application from the ground up, not just added as an
afterthought.
JavaScript
// app.use(helmet.xssFilter()); // X-XSS-Protection
Key Headers: Content-Security-Policy, X-Content-Type-Options, X-
Frame-Options, Strict-Transport-Security, X-XSS-Protection, Referrer-
Policy.
5. CORS (Cross-Origin Resource Sharing):
o Description: Control which origins (domains) are allowed to make requests to
your API.
o Tool:
cors npm package:
JavaScript
6. Rate Limiting:
o Description: Prevent brute-force attacks and abuse by limiting the number of
requests a user or IP can make within a certain timeframe.
o Tool:
express-rate-limit:
JavaScript
message: "Too many requests from this IP, please try again after 15 minutes"
});
7. Environment Variables:
oDescription: Never hardcode sensitive information (API keys, database
credentials, secrets) directly in your code. Use environment variables.
o Tools/Techniques:
.env files (during development): Use dotenv npm package to load
variables from .env into process.env.
Production Deployment: Use your hosting provider's (AWS, Heroku,
DigitalOcean, Kubernetes) built-in environment variable management
features.
Access: process.env.DB_PASSWORD.
8. Logging & Monitoring:
o Description: Log application events, errors, and access patterns. Monitor
server health (CPU, memory, disk I/O, network).
o Tools/Techniques:
Winston, Morgan, Pino: Robust logging libraries for Node.js.
PM2 (built-in logging): Can capture stdout/stderr.
Cloud Monitoring Services: AWS CloudWatch, Google Cloud
Monitoring, Azure Monitor.
APM (Application Performance Monitoring): New Relic, Datadog,
Sentry (for error tracking).
9. Dependencies & Vulnerabilities:
o Description: Keep your npm packages updated. Regularly scan for known
vulnerabilities in your dependencies.
o Tools/Techniques:
npm audit / yarn audit: Built-in commands to check for
vulnerabilities.
Snyk, OWASP Dependency-Check: Dedicated tools for dependency
scanning.
Regular Updates: npm update or yarn upgrade.
Once your application is secure and ready, it's time for deployment.
Bash
oMethod 2 (System Package Manager): sudo apt install nodejs npm (less
flexible for versions).
3. Application Code Deployment:
o Git Pull: Clone your repository onto the server.
o Build (if applicable): If you have a frontend build step (e.g., React, Vue,
Angular), run npm run build locally and deploy the static assets to a CDN or
your static file serving directory. For Node.js backend, this usually means just
pulling the code.
o Install Dependencies: Navigate to your app directory and run npm install --
production. The --production flag ensures only production dependencies are
installed.
4. Process Management with PM2:
o Description: Node.js applications are single-threaded and will crash if an
unhandled error occurs. PM2 (Process Manager 2) is a production-grade
process manager for Node.js applications that keeps them alive indefinitely,
manages logs, provides monitoring, and enables clustering.
o Installation:
Bash
Code snippet
pm2 start app.js --name my-node-app # Start your main app file
Bash
pm2 start app.js -i max # Starts app on all available CPU cores
PM2 acts as a load balancer distributing requests among your Node.js instances.
Bash
pm2 monit
Bash
pm2 save # Saves your current running processes so they restart on boot
Bash
Nginx
server {
listen 80;
proxy_http_version 1.1;
proxy_cache_bypass $http_upgrade;
Bash
o Integrate HTTPS: Use Certbot to generate and configure SSL certificates for
Nginx.
6. Firewall Configuration:
o Tool: ufw (Uncomplicated Firewall) on Ubuntu.
o Steps:
Bash
1.Discuss the principles of REST and how they are applied in designing RESTful web
services. Include examples of HTTP methods (GET, POST, PUT, DELETE) and status
codes?
REST is an architectural style for designing networked applications. It's not a standard or a
protocol, but rather a set of guiding principles or constraints that, when applied, lead to a
scalable, stateless, and efficient system. Roy Fielding, in his 2000 doctoral dissertation,
defined these principles.
The core idea behind REST is that resources (data entities) are identified by URIs, and
operations on these resources are performed using a uniform interface (HTTP methods). The
state of a resource is transferred to the client, and the client's subsequent requests transfer its
desired state changes back to the server.
1. Client-Server:
o Principle: Separation of concerns between the client (user interface) and the
server (data storage and logic). This separation improves portability of the
client, scalability of the server, and allows independent evolution of both.
o Application: The client doesn't need to know about the server's internal
implementation, and vice-versa. They communicate purely through
standardized interfaces (HTTP).
2. Stateless:
o Principle: Each request from a client to the server must contain all the
information necessary to understand the request. The server should not store
any client context between requests.
o Application: The server doesn't maintain session state with the client. Every
request is treated as if it's the first request. This simplifies server design,
improves scalability (as any server can handle any request), and enhances
reliability (no session data to lose). Authentication information (e.g., tokens)
must be sent with every request.
3. Cacheable:
o Principle: Responses from the server must explicitly or implicitly declare
themselves as cacheable or non-cacheable. If a response is cacheable, the
client (or an intermediary proxy) can reuse that response data for future
identical requests, reducing server load and improving performance.
o Application: HTTP provides caching mechanisms (e.g., Cache-Control,
ETag, Last-Modified headers). For instance, a GET request for a static image
might be cacheable, while a POST request to create a new order should not be.
4. Uniform Interface:
o Principle: This is the most critical constraint. It simplifies the overall system
architecture by having a standardized way of interacting with any resource. It
has four sub-constraints:
Identification of Resources: Resources are identified by unique URIs
(e.g., /users, /users/123, /products/shirts).
Manipulation of Resources Through Representations: Clients
manipulate resources by exchanging representations of those resources.
A representation is the data format (e.g., JSON, XML, HTML) that
describes the current or desired state of the resource.
Self-descriptive Messages: Each message includes enough
information to describe how to process the message. For example,
HTTP methods (GET, POST), headers (Content-Type, Accept), and
status codes (200 OK, 404 Not Found) provide context.
Hypermedia as the Engine of Application State (HATEOAS): This
is the most challenging and often least implemented constraint. It
means that responses should contain links that the client can use to
discover available actions and transition to different application states.
The client should not need prior knowledge of the next possible state
transitions beyond the initial URI.
5. Layered System:
o Principle: The architecture should allow for intermediate servers (proxies,
load balancers, firewalls) between the client and the resource server. Neither
the client nor the server needs to know whether it's communicating directly
with each other or through an intermediary.
o Application: This enhances scalability (load balancing), security (firewalls),
and performance (caching proxies).
6. Code-On-Demand (Optional):
o Principle: Servers can temporarily extend or customize client functionality by
transferring executable code (e.g., JavaScript). This is the only optional
constraint.
o Application: While optional, this is very common in web applications where
JavaScript code is downloaded and executed by the browser to provide
dynamic UI and client-side logic.
When designing RESTful web services, we apply these principles to define how clients
interact with our data.
Rule: Resources are nouns, not verbs. They should represent a distinct entity or
collection.
Good: /users, /products/123, /orders/active
Bad: /getAllUsers, /createProduct, /deleteOrder
REST maps standard HTTP methods to CRUD (Create, Read, Update, Delete) operations on
resources.
GET (Read):
o Purpose: Retrieve a representation of a resource or a collection of resources.
o Idempotent & Safe: Multiple identical GET requests should have the same
effect on the server (idempotent), and they should not alter the server's state
(safe).
o Example:
GET /api/products - Get a list of all products.
GET /api/products/123 - Get details of product with ID 123.
GET /api/users?status=active - Get active users (using query
parameters for filtering).
o Typical Response Status Codes:
200 OK: Successful retrieval.
404 Not Found: Resource not found.
400 Bad Request: Invalid query parameters or malformed request.
POST (Create):
o Purpose: Create a new resource. The request body typically contains the data
for the new resource.
o Not Idempotent: Repeated POST requests with the same data will usually
create multiple identical resources.
o Example:
POST /api/products (with JSON body: { "name": "New Gadget",
"price": 99.99 }) - Create a new product.
POST /api/users (with JSON body: { "username": "jane.doe", "email":
"jane@example.com" }) - Create a new user.
o Typical Response Status Codes:
201 Created: Resource successfully created. The response should
typically include the URI of the newly created resource in the Location
header and its representation in the body.
400 Bad Request: Invalid input data (e.g., missing required fields,
invalid format).
409 Conflict: Resource already exists (if your business logic dictates
uniqueness).
PUT (Update/Replace):
o Purpose: Completely replace an existing resource with the data provided in
the request body. If the resource does not exist at the specified URI, PUT can
create it (upsert semantics), though this behavior should be clearly
documented.
o Idempotent: Repeating a PUT request with the same data will have the same
final effect on the resource.
o Example:
PUT /api/products/123 (with JSON body: { "id": "123", "name":
"Updated Gadget", "price": 109.99, "description": "New description"
}) - Replace product 123's entire data.
o Typical Response Status Codes:
200 OK: Resource successfully updated.
204 No Content: Resource successfully updated, but no content is
returned in the response body.
201 Created: If PUT creates a new resource (upsert).
400 Bad Request: Invalid input data.
404 Not Found: Resource to be updated does not exist (if PUT is not
used for upsert).
PATCH (Partial Update):
o
Purpose: Apply partial modifications to a resource. Only the fields provided
in the request body are updated; other fields remain unchanged.
o Not Idempotent: (Unless carefully implemented to be) Repeating a PATCH
request might have different results if the resource state changes between
requests.
o Example:
PATCH /api/products/123 (with JSON body: { "price": 105.00 }) -
Only update the price of product 123.
o Typical Response Status Codes:
200 OK: Resource successfully updated partially.
204 No Content: Resource successfully updated, but no content is
returned.
400 Bad Request: Invalid input data or unsupported patch format.
404 Not Found: Resource not found.
DELETE (Delete):
o Purpose: Remove a resource from the server.
o Idempotent: Deleting a resource multiple times will result in the same state
(the resource is gone).
o Example:
DELETE /api/products/123 - Delete product with ID 123.
o Typical Response Status Codes:
200 OK: Resource successfully deleted (response body may contain
confirmation).
204 No Content: Resource successfully deleted, no content returned.
404 Not Found: Resource to be deleted does not exist.
3. Statelessness
Each API request should carry its own authentication token (e.g., JWT in an
Authorization header).
No server-side sessions. If a client needs specific data across requests, it should either
carry that data or request it with each call.
4. Cacheability
To understand the Virtual DOM, it's crucial to first understand the Actual DOM.
The Actual DOM is a programming interface for HTML and XML documents. It represents
the structure of a document as a tree of objects. Each node in the tree represents a part of the
document (like an element, attribute, or text).
The Virtual DOM (VDOM) is a concept introduced by React (and adopted by other
frameworks like Vue). It's a lightweight, in-memory representation of the Actual DOM. It's
essentially a JavaScript object that mirrors the structure and properties of the Actual DOM
elements.
Structure: A JavaScript object (or a tree of React elements) that represents the
desired state of the UI. It's a "virtual" copy of the browser's DOM.
Manipulation: React doesn't directly manipulate the Actual DOM. Instead, it works
with the Virtual DOM. When state or props change, React creates a new Virtual DOM
tree.
Performance:
o Fast: Manipulating JavaScript objects is significantly faster than directly
manipulating the Actual DOM.
o Efficient: React uses a clever algorithm (reconciliation) to minimize direct
Actual DOM manipulations.
Comparison Summary
How React Improves Web Application Performance Using the Virtual DOM
3) Explain how to construct React components with dynamic data. Provide an example
with state and props?
React components are the building blocks of any React application. To create interactive and
responsive user interfaces, these components often need to display and react to dynamic data.
In React, this dynamic data primarily comes from two sources: props and state.
1. Props (Properties)
Definition: props are read-only attributes that are passed down from a parent
component to a child component. They are essentially a way to pass data from one
component to another in a unidirectional flow (top-down).
Immutability: Props are immutable within the child component. A child component
should never directly modify its props. If a child needs to "change" data it received
via props, it should typically communicate that change up to its parent (e.g., via a
callback function passed as a prop), and the parent would then update its own state
and re-render the child with new props.
Use Cases:
o Passing data to configure a child component (e.g., a user's name, a product
ID).
o Passing event handlers to allow a child to communicate with its parent.
o Styling or behavior customization for reusable components.
2. State
Often, parent components manage data in their state, and then pass parts of that state down to
their child components as props. When the parent's state changes, it triggers a re-render, and
the new state values are passed as props to the children, which then also re-render to reflect
the updated data.
Let's create a React application with a parent component that manages a list of items and a
child component that displays each item and allows incrementing a counter for that item. This
will demonstrate both state and props.
Bash
cd react-dynamic-data-example
2. Open src/App.js and src/index.js (and src/index.css if you want to add some
styling).
Code:
JavaScript
function App() {
// 1. State in the parent component (App)
]);
setItems(prevItems => {
);
});
};
return (
<div className="App">
<div className="item-list">
{/*
Iterating over the 'items' state array.
*/}
{items.map(item => (
<ItemCard
id={item.id}
itemName={item.name}
itemCount={item.initialCount}
/>
))}
</div>
</div>
);
JavaScript
function ItemCard(props) {
// Props are immutable; they are used to display data and call parent functions.
// Local state for demonstration purposes (e.g., if you had a 'hovered' state for this card)
// This component could also have its own internal state if needed,
return (
<div
>
<h3>{itemName}</h3>
<p>ID: {id}</p>
Increment {itemName}
</button>
</div>
);
CSS
.App {
font-family: sans-serif;
text-align: center;
padding: 20px;
background-color: #f4f4f4;
min-height: 100vh;
.item-list {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 20px;
margin-top: 30px;
.item-card {
border-radius: 8px;
padding: 20px;
width: 200px;
background-color: #fff;
display: flex;
flex-direction: column;
align-items: center;
.item-card.hovered {
transform: translateY(-5px);
.item-card h3 {
color: #333;
margin-top: 0;
.item-card p {
color: #666;
font-size: 0.9em;
margin-bottom: 5px;
.item-card button {
background-color: #007bff;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
font-size: 0.9em;
margin-top: 15px;
.item-card button:hover {
background-color: #0056b3;
.hover-message {
font-style: italic;
color: #007bff;
margin-top: 10px; }
4) Describe in detail how React components and React elements are used in the DOM
rendering process.
The process of rendering in React, especially how React Components and React Elements
interact with the Document Object Model (DOM), is fundamental to understanding React's
efficiency. Let's break it down in detail.
Before diving into the rendering process, it's crucial to clarify the distinction between React
Components and React Elements. This is a common point of confusion.
React Components
A React Component is a blueprint or a factory that tells React how to render a piece of UI.
It's a reusable, independent building block of your application.
JavaScript
function WelcomeMessage(props) {
o Class Component:
JavaScript
constructor(props) {
super(props);
this.state = { count: 0 };
render() {
A React Element is a plain JavaScript object that describes what you want to see on the
screen. It's a lightweight, immutable description of a DOM node or a React component
instance.
Definition: It's not the actual DOM node, nor is it the component itself. It's simply an
object returned by React.createElement() or JSX that tells React what type of element
to create and what properties it should have.
Creation:
o Manually (less common): React.createElement(type, props, ...children)
o Via JSX (most common): JSX is syntactic sugar that gets transpiled into
React.createElement() calls.
<h1>Hello!</h1> becomes React.createElement('h1', null, 'Hello!')
<WelcomeMessage name="Alice" /> becomes
React.createElement(WelcomeMessage, { name: "Alice" })
Immutability: Once an element is created, you cannot change its children or its
attributes. If something needs to change, React creates a new element.
Purpose: React elements are what React uses to construct its Virtual DOM tree. They
are the "atoms" of a React UI.
The rendering process in React involves several steps, where Components define the
structure, and Elements are the concrete descriptions React uses to build the Virtual DOM
and eventually update the Actual DOM.
Let's trace the journey from your React code to what the user sees in the browser:
This is where the power of the Virtual DOM truly shines. When data changes (due to setState
in class components, useState hook in functional components, or prop changes from a
parent), the following happens:
Flow Summary
Diffing Algorithm (Compares New Virtual DOM with Old Virtual DOM)
5) Design a RESTful API for a book store and explain how you would handle
conditional requests and web linking?
Designing a RESTful API for a bookstore involves defining resources, operations on those
resources using HTTP methods, and adhering to REST principles like statelessness, uniform
interface, and idempotence. Additionally, handling conditional requests and web linking are
advanced practices that enhance the API's efficiency, robustness, and discoverability.
2. Base URI: Let's assume the base URI for our API is https://api.bookstore.com/v1.
3. Resource URIs: We use plural nouns for collections and identifiers for single resources.
Books:
o Collection: /books
o Single: /books/{id}
Authors:
o Collection: /authors
o Single: /authors/{id}
Genres:
o Collection: /genres
o Single: /genres/{id}
Reviews (nested resource, associated with a book):
o Collection for a specific book: /books/{bookId}/reviews
o Single review for a specific book: /books/{bookId}/reviews/{reviewId}
Request Response
HTTP Common
URI Pattern Description Body Body
Method Status Codes
(Example) (Example)
Retrieve all
books (with [ { id: "1",
optional title: "...",
GET /books None 200 OK
filtering, author_id:
sorting, "...", ... }, ... ]
pagination).
{ id: "1",
title: "The
Retrieve a Martian", 200 OK, 404
GET /books/{id} None
specific book. author_id: Not Found
"a1",
genre_id:
Request Response
HTTP Common
URI Pattern Description Body Body
Method Status Codes
(Example) (Example)
"g2", price:
15.99 }
201 Created
{ title: "New (with
Book", { id: "4", Location
Create a new
POST /books author_id: title: "New header), 400
book.
"a3", price: Book", ... } Bad
20.00 } Request, 409
Conflict
200 OK, 204
{ id: "1",
No Content,
title: { id: "1",
Replace a 201 Created
"Updated title:
PUT /books/{id} specific book (if upsert),
Title", "Updated
(full update). 400 Bad
author_id: Title", ... }
Request, 404
"a1", ... }
Not Found
{ id: "1", 200 OK, 204
Partially title: "The No Content,
{ price:
PATCH /books/{id} update a Martian", 400 Bad
12.50 }
specific book. price: 12.50, Request, 404
... } Not Found
2200 OK,
Delete a 204 No
DELETE /books/{id} None (Empty body)
specific book. Content, 404
Not Found
[ { id: "r1",
book_id: "1", 200 OK, 404
Retrieve all
rating: 5, Not Found
GET /books/{bookId}/reviews reviews for a None
comment: (if book not
book.
"Great!" }, ... found)
]
{ id: "r3",
{ rating: 4, book_id: "1", 201 Created,
Add a review comment: rating: 4, 400 Bad
POST /books/{bookId}/reviews
to a book. "Good comment: Request, 404
read." } "Good read." Not Found
}
GET
/books?genreId=g1&authorId=a1&minPrice=10&maxPrice=50&sortBy=title:asc&pa
ge=2&limit=10
II. Handling Conditional Requests
Conditional requests are an essential part of building efficient and robust RESTful APIs.
They allow clients to avoid transferring data if it hasn't changed or to prevent concurrent
updates from overwriting each other. This is achieved using HTTP headers related to ETag
and Last-Modified timestamps.
Server Side: When serving a resource (GET), include either an ETag header or a
Last-Modified header (or both) in the response.
o ETag: An opaque identifier representing a specific version of a resource.
Usually a hash of the content.
o Last-Modified: The date and time the resource was last modified.
Client Side: For subsequent requests, the client sends these values back to the server
in If-None-Match (for ETag) or If-Modified-Since (for Last-Modified) headers.
Server Action: The server compares the client's provided value with the current
version of the resource.
o If they match (resource hasn't changed), the server responds with 304 Not
Modified and an empty body.
o If they don't match (resource has changed), the server proceeds with a regular
200 OK response, sending the full resource and new ETag/Last-Modified
headers.
Server Side: Same as above, ETag or Last-Modified are sent with the GET response.
Client Side: When sending a PUT, PATCH, or DELETE request, the client includes
the ETag in an If-Match header or the Last-Modified date in an If-Unmodified-Since
header.
Server Action: The server checks if the ETag/Last-Modified provided by the client
matches the current version of the resource on the server.
o If they match, the operation proceeds (e.g., 200 OK for PUT).
o If they don't match (meaning the resource was modified by another client
since this client fetched it), the server responds with 412 Precondition Failed.
The client then knows its local version is stale and needs to re-fetch the
resource before attempting the update again.
HATEOAS is a constraint of the Uniform Interface principle and is often considered the
defining characteristic of a truly RESTful API. It means that the client interacts with the
application solely through hypermedia provided dynamically by the server. Instead of
hardcoding URIs, the client finds relevant actions and related resources by following links
embedded in the API responses.
MongoDB:
Traditional relational databases (RDBMS), such as MySQL, PostgreSQL, Oracle, and SQL
Server, are based on the relational model, which organizes data into tables, rows, and
columns, and defines relationships between these tables using foreign keys. MongoDB, being
a NoSQL (Not Only SQL) database, fundamentally differs in several key areas:
At its core, MongoDB is designed to store and manage large volumes of data in a flexible,
scalable, and high-performance manner. Its architecture is built around a hierarchical
structure that is conceptually similar to file systems, but optimized for data storage and
retrieval.
Flexible Schema: Unlike rows in a relational database table that must adhere to a
predefined schema, documents within the same collection in MongoDB can have
different fields, different data types for fields, and different structures. This "schema -
less" or "flexible schema" nature is a cornerstone of MongoDB's agility.
o Example: One document in a users collection might have firstName,
lastName, and email, while another might also include phoneNumber and an
array of addresses.
Embedded Documents and Arrays: Documents can contain nested documents
(objects) and arrays. This allows for representing complex, hierarchical, and one-to-
many relationships within a single document, often reducing the need for costly joins
that are common in relational databases.
o Example: A book document might embed author details or an array of review
documents directly within it.
_id Field: Every document in MongoDB automatically has a unique _id field. If you
don't provide one, MongoDB adds an ObjectId (a 12-byte BSON type unique
identifier). This field serves as the primary key for the document within its collection.
JSON
"author": {
"firstName": "Andy",
"lastName": "Weir",
"nationality": "American"
},
"publicationYear": 2014,
"price": 15.99,
"isAvailable": true,
"reviewer": "Alice",
"rating": 5,
"date": ISODate("2023-01-15T10:30:00Z")
},
"reviewer": "Bob",
"rating": 4,
"date": ISODate("2023-02-20T14:00:00Z")
],
Conceptual View:
Database
├── Collection "books"
A database in MongoDB is a physical container for collections. It's the highest level of
organization for your data. A single MongoDB server (or cluster) can host multiple
databases.
Logical Grouping: Databases provide a logical grouping for related collections. For
example, a single application might use one database, or different modules of a large
system might use separate databases.
Separation of Concerns: Each database has its own set of collections, users, and
permissions, allowing for clear separation of data and access control.
Dynamic Creation: Like collections, databases are created implicitly when you first
store data in them or explicitly through commands.
Storage: Each database corresponds to a set of files on the file system, though
developers typically interact with them logically through the MongoDB shell or
drivers, rather than directly with the files.
3) How do you create a database and collection in MongoDB? Provide an example of
creating a simple collection to store user data ?
You can create databases and collections in MongoDB using the MongoDB Shell (mongosh) or
through a MongoDB driver in your preferred programming language (Node.js, Python, Java, etc.).
First, ensure your MongoDB server is running. Then, open your terminal and type mongosh to
connect to the default MongoDB instance (running on localhost:27017).
Bash
mongosh
...
test>
The test> prompt indicates you are currently connected to the test database by default.
In MongoDB, you don't explicitly run a CREATE DATABASE command. A database is implicitly created
the first time you either:
1. Switch to it using the use command and then insert data into a collection within that
database.
2. Insert data into a collection within that database, even if you don't explicitly use it first.
JavaScript
use my_bookstore_db
Output:
switched to db my_bookstore_db
At this point, the database my_bookstore_db technically exists in memory but won't show up in
show dbs until it contains at least one collection with a document.
Similar to databases, collections are also implicitly created the first time you insert a document into
them. There's no explicit CREATE COLLECTION command unless you want to create a capped
collection or apply specific validation rules at creation time.
JavaScript
db.users.insertOne({
username: "johndoe",
email: "john.doe@example.com",
age: 30,
isActive: true,
address: {
city: "Anytown",
zipCode: "12345"
},
roles: ["customer"]
})
Output:
acknowledged: true,
Now, the my_bookstore_db database and the users collection within it have been created. You can
verify this:
To list databases: show dbs You should now see my_bookstore_db in the list.
To list collections in the current database: show collections You should see users listed.
The users collection we just created is a simple example. Let's add a few more documents to
illustrate the flexible schema:
JavaScript
db.users.insertOne({
username: "janedoe",
email: "jane.doe@example.com",
age: 25,
preferences: {
newsletter: true,
theme: "dark"
})
db.users.insertOne({
username: "guestuser",
})
You can then query the collection to see the inserted data:
JavaScript
JSON
_id: ObjectId("669234b6f7e3c1d2e3f4a5b6"),
username: 'johndoe',
email: 'john.doe@example.com',
age: 30,
isActive: true,
roles: [ 'customer' ]
},
_id: ObjectId("660e5b721e7a9e67f7e9b0c2"),
username: 'janedoe',
email: 'jane.doe@example.com',
age: 25,
},
_id: ObjectId("660e5b721e7a9e67f7e9b0c3"),
username: 'guestuser',
lastLogin: ISODate("2025-07-08T07:05:43.901Z")
Notice how each document has a different structure, demonstrating the flexible schema
characteristic of MongoDB collections.
4) What are the key steps involved in deploying a web application using cloud platforms
like AWS or Azure? Explain the concept of web hosting and domain configuration?
While the specific service names differ between AWS and Azure, the underlying concepts and steps
are very similar. I'll generally refer to common service types.
Core Deployment
1. Database Setup:
o Provision: Create a managed database instance (e.g., PostgreSQL on AWS RDS,
MongoDB on Azure Cosmos DB or a service like MongoDB Atlas).
o Configuration: Set up user credentials, network security groups (firewall rules to
only allow access from your application's servers), backups, and scaling options.
o Migration/Seeding: Migrate your database schema and seed initial data if
necessary.
2. Application Deployment (Backend):
o IaaS (e.g., EC2/Azure VM):
Launch/provision VM instance, select OS.
SSH into the VM.
Install necessary runtimes (Node.js, Python, Java), package managers.
Clone your repository.
Install application dependencies (npm install --production).
Configure a process manager (e.g., PM2 for Node.js, Gunicorn/Supervisor for
Python) to keep your application running.
Set up environment variables.
Configure a reverse proxy (e.g., Nginx or Apache) to handle incoming
requests, SSL termination, and possibly serve static files.
Configure firewall rules (Security Groups in AWS, Network Security Groups in
Azure) to allow traffic only on necessary ports (80, 443, 22 for SSH).
o PaaS (e.g., AWS Elastic Beanstalk/Azure App Service):
Create a new application environment, select your runtime (Node.js,
Python, .NET, Java, etc.).
Upload your code (zip file, Git deploy, CI/CD).
Configure environment variables directly in the service's settings.
The platform automatically handles provisioning, scaling, load balancing,
and runtime management.
o CaaS (e.g., AWS ECS/Azure Kubernetes Service):
Containerize your application (create a Dockerfile).
Push the Docker image to a container registry (e.g., AWS ECR, Azure
Container Registry, Docker Hub).
Define task definitions (ECS) or Kubernetes deployment files.
Deploy your containers to a cluster.
o Serverless (e.g., AWS Lambda/Azure Functions):
Write your functions.
Package them with dependencies.
Upload to the serverless platform.
Configure triggers (e.g., API Gateway for HTTP requests).
3. Frontend Deployment (if separate from backend):
o For single-page applications (React, Angular, Vue):
Build the application (e.g., npm run build).
Deploy the resulting static files to a static hosting service or CDN (e.g., AWS
S3 + CloudFront, Azure Static Web Apps, Firebase Hosting). These services
are highly optimized for serving static content globally.
Web Hosting
Web hosting is the service that makes your website or web application accessible on the internet.
When you "host" a website, you are essentially renting space on a server (physical or virtual) where
your website's files (HTML, CSS, JavaScript, images, backend code, database) reside.
How it Works: A web host (like AWS, Azure, DigitalOcean, or traditional hosting providers)
provides the server infrastructure, network connectivity, and often software (like web
servers, databases) necessary for your application to run and be reached by users' browsers.
Types of Hosting:
o Shared Hosting: Multiple websites share resources on a single server. Cheapest, but
performance can be affected by "noisy neighbors."
o VPS (Virtual Private Server): A virtualized server instance with dedicated resources.
More control and better performance than shared.
o Dedicated Server: An entire physical server dedicated to your website. Maximum
control and performance, but most expensive.
o Cloud Hosting (e.g., AWS/Azure services): Highly scalable, flexible, and often pay-
as-you-go. This is what we primarily discussed above (IaaS, PaaS, CaaS, Serverless).
o Managed Hosting: The provider handles server management, security, updates, etc.,
leaving you to focus on your application.
In the context of AWS/Azure, when you launch an EC2 instance, an Azure VM, or use services like
App Service/Elastic Beanstalk, you are essentially leveraging their cloud hosting capabilities.
Domain Configuration
Domain configuration is the process of linking your human-readable domain name (e.g.,
www.mybookstore.com) to the numerical IP address of your web server (where your application is
hosted). This is managed by a Domain Name System (DNS) provider.
Domain Name Registrar: This is where you purchase your domain name (e.g., GoDaddy,
Namecheap, Google Domains).
DNS (Domain Name System): The internet's phonebook. It translates domain names into IP
addresses that computers use to identify each other on the network.
DNS Records: You configure various types of records in your DNS management portal:
o A Record (Address Record): Maps a domain name (e.g., mybookstore.com) directly
to an IPv4 address (e.g., 192.0.2.1). This is commonly used for a fixed IP address.
o AAAA Record: Maps a domain name to an IPv6 address.
o CNAME Record (Canonical Name): Creates an alias for a domain name. It points a
domain (e.g., www.mybookstore.com) to another domain name (e.g., the public
DNS name of your Load Balancer or App Service URL, like mybookstore-
app.elasticbeanstalk.com). This is very common with cloud services that provide
dynamic IP addresses or long, unfriendly hostnames.
o MX Record (Mail Exchange): Specifies mail servers for a domain.
o TXT Record: Stores general text information, often used for domain verification
(e.g., for SSL certificates, email authentication).
my-node-mongo-app/
├── public/
├── views/
├── node_modules/
├── .gitignore
├── package.json
├── package-lock.json
JavaScript
mongoose.connect(MONGODB_URI, {
useNewUrlParser: true,
useUnifiedTopology: true,
})
// Basic route
});
// Example route to fetch data from MongoDB (assuming a 'users' collection)
try {
const User = mongoose.model('User', new mongoose.Schema({ name: String, email: String })); //
Define a simple schema/model
res.json(users);
} catch (error) {
});
app.listen(port, () => {
});
PORT=3000
MONGODB_URI=mongodb://localhost:27017/my_local_db
package.json (Snippet):
JSON
"name": "my-node-mongo-app",
"version": "1.0.0",
"main": "app.js",
"scripts": {
"start": "node app.js",
},
"dependencies": {
"express": "^4.19.2",
"mongoose": "^8.4.1",
"dotenv": "^16.4.5"
We have two common scenarios: Heroku (PaaS) and AWS (IaaS - EC2).
Key Steps:
git init
git add .
Bash
heroku config:set
MONGODB_URI="mongodb+srv://yourUser:yourPassword@cluster0.abcde.mongodb.net/yourData
baseName?retryWrites=true&w=majority"
Important: Heroku automatically sets a PORT environment variable. Your Node.js app must listen on
process.env.PORT (as shown in app.js).
4. Procfile:
o Create a file named Procfile (no extension) in your project root with the following
content:
o web: node app.js
5. Deploy to Heroku:
Bash
Heroku will detect your Node.js app, install dependencies from package.json, and then run the
command specified in your Procfile.
6. Open App:
Bash
heroku open