Viva Questions
INT222
Node.js uses an Event Loop and non-blocking I/O. While the main JavaScript execution is single-threaded, heavy I/O operations (like file reading or network requests) are offloaded to the system kernel (libuv), which executes them in the background and returns a callback to the Event Loop once finished.
package.json lists the desired version ranges for dependencies. package-lock.json locks down the exact version of every package and sub-dependency installed to ensure that the project environment is identical across all machines and deployments.
If a listener throws an error and it is not caught, the Node.js process may crash. Furthermore, subsequent listeners registered for that same event will not execute because the event loop execution for that specific event stack is interrupted.
fs.readFile buffers the entire file into memory before sending it, which can crash the server if the file is large. fs.createReadStream reads the file in small chunks and pipes them to the response immediately, resulting in low memory usage and faster start times for the client.
Piping is a mechanism where the output of one stream (e.g., a file read stream) is connected directly to the input of another stream (e.g., a Zlib compression stream), and then to a destination (e.g., a write stream). It handles data flow automatically so you don't have to manually manage events.
Using 'await' inside a for-loop executes the promises sequentially (one after another), which is slower. Using 'Promise.all' executes all promises concurrently (in parallel), which is significantly faster for independent tasks.
It is useful for testing small snippets of code, debugging regular expressions, or verifying the output of a specific library method without running the entire application.
fs.writeFile overwrites the existing file content completely. fs.appendFile adds data to the end of the file. In both cases, if the file does not exist, Node.js creates a new one.
It signals to the server that all response headers and body data have been sent. If 'response.end()' is not called, the client (browser) will keep waiting for the response indefinitely until it times out.
The data comes in as a stream of buffers. You must listen to the 'data' and 'end' events on the Request object to manually concatenate the chunks and parse the JSON string.
It tells the client (browser or API consumer) how to interpret the data. Without it, the client might treat the JSON string as plain text or HTML, potentially breaking the application logic on the client side.
It allows developers to modularize the application by creating mini-applications or route handlers in separate files, making the code maintainable and organized compared to defining all routes in the main server file.
The value of 'req.body' will be undefined, as Express does not parse the request body stream by default.
200 OK is the standard response for successful HTTP requests. 201 Created is specifically used when a request (usually POST) has successfully resulted in the creation of a new resource.
No, validation libraries usually attach errors to the request object. You must explicitly check for these errors in your controller logic and send a response (e.g., 400 Bad Request) to stop further execution.
GET requests should be idempotent and safe, meaning they only retrieve data without side effects. Browsers and proxies cache GET requests; using them to modify data can lead to security risks and inconsistent application states.
HTTP is request-response based and closes the connection after the response. WebSocket starts as an HTTP handshake but upgrades to a persistent, full-duplex TCP connection, allowing two-way communication without re-establishing connections.
'socket.emit()' sends a message only to the specific client associated with that socket connection. 'io.emit()' broadcasts the message to all connected clients.
You use 'socket.broadcast.emit()'. This sends the message to all clients connected to the server (or room) except the sender.
The arguments are (req, res, next). The 'next' argument is a callback function that, when called, passes control to the next middleware in the stack. If it's not called, the request hangs.
'app.use' applies middleware to the specified path and all its sub-paths (e.g., /api/users). 'app.all' matches only the specific path ('/api') but covers all HTTP verbs (GET, POST, etc.).
Cookies are stored on the client-side as text files. If not signed/encrypted, a user can easily manipulate the cookie value (e.g., change 'role=user' to 'role=admin') and potentially gain unauthorized access.
'cookie-session' stores all session data entirely in the client's browser cookie. 'express-session' stores only a Session ID in the cookie, while the actual data is stored on the server (in memory or a database).
It must accept four arguments: (err, req, res, next). If only three are provided, Express treats it as a regular middleware.
A Collection is a container for Documents (analogous to a Table in SQL), while a Document is a specific record of data (analogous to a Row in SQL), stored in BSON format.
db.users.drop()
'updateOne' modifies specific fields within a document using operators like $set, keeping other fields intact. 'replaceOne' replaces the entire document with the new JSON object provided, except for the _id.
Mongoose schemas provide application-level structure, validation, and type casting. They ensure data consistency and prevent 'junk' data from entering the database, even though the database itself doesn't enforce it.
A Model is a wrapper around the Schema. It provides an interface to interact with the database, allowing you to create, query, update, and delete documents based on that schema.
Connecting to a database involves network I/O which takes time. We usually wrap the server startup code (app.listen) inside the database connection callback or promise chain to ensure the DB is ready before the server accepts requests.
Model.findById(id)
It appends a specified value to an array field. If the array doesn't exist, it creates it.
PostgreSQL is a relational database management system (RDBMS) that uses tables with fixed schemas and SQL for querying, whereas MongoDB is a NoSQL document store that uses flexible JSON-like documents.
CREATE TABLE students (id SERIAL PRIMARY KEY, name VARCHAR(100)); (Exact syntax may vary slightly, but key words are CREATE TABLE).
'DELETE' removes rows one by one and logs each deletion (slower, can be rolled back). 'TRUNCATE' deallocates the data pages to remove all rows at once (faster, usually cannot be rolled back easily in some contexts, resets identity seeds).
The WHERE clause.
A connection pool maintains a cache of reusable database connections. Instead of opening and closing a new TCP connection for every query (which is expensive), the app borrows a connection from the pool, uses it, and returns it.
It will update every single row in the table with the new value.
To isolate the unit being tested, ensure tests run quickly, and avoid modifying real production data or depending on the uptime of third-party services.
- The HTTP Status Code (e.g., did I get a 200 OK?). 2. The Response Body (does the payload contain the expected data?).
It automates the process of testing and deploying code. When code is pushed to GitHub, the CI pipeline runs tests, and if they pass, the CD pipeline automatically deploys the application to the server.
With SSR, the server sends a fully populated HTML page to the browser. Search engine crawlers can easily read the content immediately. In Client-Side rendering, crawlers might see an empty page while waiting for JavaScript to load the content.
The .env file contains sensitive secrets like API keys, database passwords, and port numbers. Committing it makes these secrets public, posing a massive security risk.
A Process Manager keeps the Node.js application running continuously, restarts it automatically if it crashes, and can help scale the application across multiple CPU cores.
Blocking is like ordering food at a counter and waiting there until it's ready, stopping anyone else from ordering. Non-blocking is like ordering, getting a buzzer, and sitting down; the counter person can take other orders while yours is being prepared.
URL Parameters are part of the route path (e.g., /users/:id) used to identify a resource. Query Strings come after the '?' (e.g., ?sort=asc) and are used for filtering or sorting results.
A Room is a server-side concept that allows you to group sockets together. You can broadcast messages to only sockets within a specific room (e.g., a specific chat group) rather than all connected users.
MongoDB will accept almost any BSON structure. Mongoose is an ODM (Object Data Modeling) library designed specifically to enforce structure and rules (validation) on top of that flexible database to ensure application data integrity.
You would choose PostgreSQL when the data has complex relationships, requires strict schema enforcement, and needs robust transaction support (ACID compliance), such as in financial applications.
Regression testing ensures that new code changes or features haven't broken existing functionality that was previously working.