Courseiva

CCNA Software Development and Design Questions

75 of 97 questions · Page 1/2 · Software Development and Design · Answers revealed

1
MCQmedium

In a microservices architecture, which communication pattern is typically asynchronous and decoupled?

A.REST over HTTP
B.SOAP
C.gRPC
D.Event-driven architecture
AnswerD

Event-driven architecture decouples producers from consumers via a broker, so services publish events without waiting for responses. This asynchronous, non-blocking exchange satisfies the decoupling requirement, unlike synchronous request-response patterns such as REST or gRPC that couple caller and callee.

Why this answer

Event-driven architecture (D) is the correct answer because it is inherently asynchronous and decoupled: services communicate by publishing events to a message broker (e.g., Kafka, RabbitMQ) without needing to know about the consumers. This pattern allows the producer to emit an event and continue processing immediately, while consumers react to events at their own pace, achieving loose coupling and high scalability.

Exam trap

Cisco often tests the misconception that any HTTP-based communication (like REST) is inherently asynchronous, but REST over HTTP is synchronous by default unless combined with additional patterns like webhooks or message queues.

How to eliminate wrong answers

Option A is wrong because REST over HTTP is typically synchronous and tightly coupled: the client sends a request and waits for a response, creating a direct dependency between services. Option B is wrong because SOAP is a synchronous, tightly coupled protocol that relies on XML messaging over HTTP or other transports, often with strict contract definitions (WSDL) that create strong coupling. Option C is wrong because gRPC, while efficient with HTTP/2 and protobufs, is primarily designed for synchronous request-response communication (though it supports streaming, the default pattern is still coupled and blocking).

2
MCQhard

Which Python exception would be raised by the following code? my_dict = {'a': 1} value = my_dict['b']

A.KeyError
B.ValueError
C.IndexError
D.AttributeError
AnswerA

Accessing a missing key in a dictionary raises KeyError, because Python's dict lookup requires the key to exist. The code requests 'b' from a dict containing only 'a', so the lookup fails immediately and KeyError propagates.

Why this answer

Accessing a dictionary key that does not exist raises a KeyError in Python. In the code, my_dict['b'] attempts to retrieve the value for key 'b', which is not present in the dictionary {'a': 1}, so Python raises KeyError.

Exam trap

Cisco often tests the distinction between KeyError and IndexError, trapping candidates who confuse dictionary key access with list index access, especially when the code uses square brackets in both contexts.

How to eliminate wrong answers

Option B is wrong because ValueError is raised when a function receives an argument of the correct type but an inappropriate value (e.g., int('abc')), not for missing dictionary keys. Option C is wrong because IndexError is raised when accessing an index out of range in a sequence like a list or tuple, not for dictionary key access. Option D is wrong because AttributeError is raised when an invalid attribute reference or assignment is made (e.g., my_dict.append), not for missing dictionary keys.

3
MCQhard

A developer is designing a Python application that must handle failures when making REST API calls to a Cisco DNA Center controller. The application should retry a failed request only if the HTTP status code indicates a server-side error (5xx) or a timeout occurs, but should not retry on client errors (4xx). The developer wants to implement this using a decorator. Which Python library provides a ready-to-use retry decorator that can be configured to retry on specific exceptions and HTTP status codes?

A.urllib3
B.tenacity
C.functools
D.requests
AnswerB

Tenacity is a general-purpose retrying library that provides a decorator and can be configured to retry based on exceptions, including custom conditions. It supports retrying on specific HTTP status codes when integrated with requests, and can be set to stop after a number of attempts. It is widely used in network automation for robust API interactions.

Why this answer

Tenacity is a dedicated retrying library that offers a decorator with extensive configuration options, including retrying on specific exceptions and stop conditions. It can be easily integrated with HTTP status code checks. The other libraries either lack a retry decorator or require manual implementation, making tenacity the correct choice for this scenario.

Exam trap

The trap here is assuming that the requests library includes a built-in retry decorator, when it actually requires using urllib3's Retry with an adapter.

4
Multi-Selectmedium

A developer is designing a Python script that needs to make multiple REST API calls to different endpoints sequentially. The script must handle the following requirements: (1) Use a variable timeout for each request, (2) Include an authorization token in every request, (3) Parse JSON responses. Which TWO features of the requests library should be used? (Choose two.)

Select 2 answers
A.Set the `data` parameter to JSON for request body.
B.Use the `timeout` parameter to specify a maximum wait time.
C.Use `verify=False` to speed up requests.
D.Set the `auth` parameter with a tuple (username, token).
E.Use the `headers` parameter to include the authorization token.
AnswersB, E

The `timeout` parameter sets a per-request maximum wait in seconds, satisfying requirement (1) for a variable timeout on each sequential call. Passing a distinct value to each `requests.get()` or `requests.post()` invocation prevents a slow endpoint from blocking the script indefinitely.

Why this answer

Option B is correct because the requests library's timeout parameter accepts a float or tuple (connect, read) value that sets the maximum number of seconds to wait for a response, directly satisfying the requirement for a variable timeout on each request. Option E is correct because the headers parameter takes a dictionary such as {'Authorization': 'Bearer <token>'}, which is the standard way to attach an authorization token to every request. Option A is not correct because the data parameter is used for form-encoded or raw request bodies, not for parsing JSON responses, and JSON bodies are typically sent via the json parameter.

Option C is not correct because verify=False disables TLS certificate verification, which is a security risk and unrelated to timeouts, tokens, or JSON parsing. Option D is not correct because the auth parameter expects an authentication handler or a (username, password) tuple for HTTP Basic/Digest auth, not a token, and tokens belong in headers.

Exam trap

Cisco often tests the distinction between the `auth` parameter (for Basic Auth) and the `headers` parameter (for bearer tokens), causing candidates to mistakenly choose Option D when they should use Option E.

5
MCQmedium

A Python function needs to accept a variable number of keyword arguments. Which parameter syntax should be used?

A.*kwargs
B.**kwargs
C.*args
D.&kwargs
AnswerB

The double-asterisk prefix collects arbitrary keyword arguments into a dictionary, letting the function accept any number of named parameters. A single asterisk would instead gather positional arguments into a tuple, so **kwargs is the syntax that satisfies the variable keyword argument requirement.

Why this answer

In Python, the **kwargs syntax allows a function to accept a variable number of keyword arguments by collecting them into a dictionary. This is the correct parameter syntax for handling arbitrary keyword arguments, as specified in Python's function definition rules.

Exam trap

Cisco often tests the distinction between *args (positional arguments) and **kwargs (keyword arguments), and candidates mistakenly choose *kwargs or confuse the syntax with other operators like &.

How to eliminate wrong answers

Option A is wrong because *kwargs is not valid Python syntax; the correct syntax for variable positional arguments is *args, not *kwargs. Option C is wrong because *args collects extra positional arguments into a tuple, not keyword arguments. Option D is wrong because &kwargs is not a valid Python operator or syntax; Python uses ** for dictionary unpacking and keyword argument collection, not &.

6
Multi-Selecthard

A developer is implementing exception handling in Python for a function that makes an HTTP request. Which THREE exception types should be caught to handle common network and HTTP errors? (Choose three.)

Select 3 answers
A.requests.exceptions.ConnectionError
B.requests.exceptions.InvalidURL
C.requests.exceptions.Timeout
D.requests.exceptions.HTTPError
E.requests.exceptions.TooManyRedirects
AnswersA, C, D

ConnectionError is raised when the request cannot reach the server at all, such as DNS failure or refused connection. Catching it handles the transport-level failures the stem's HTTP request function will encounter before any response is received.

Why this answer

Option A, requests.exceptions.ConnectionError, is correct because it is raised when the HTTP request cannot establish a connection to the server, such as DNS resolution failures, refused connections, or other network-level problems that a developer must handle. Option C, requests.exceptions.Timeout, is correct because it is raised when a request exceeds the specified timeout period, covering both connect and read timeouts, which are common in unreliable network conditions. Option D, requests.exceptions.HTTPError, is correct because it is raised by Response.raise_for_status() when the server returns an unsuccessful HTTP status code (4xx or 5xx), representing common HTTP-level errors.

Option B, requests.exceptions.InvalidURL, is not among the marked answers because it typically indicates a malformed URL supplied by the developer rather than a common runtime network or HTTP error. Option E, requests.exceptions.TooManyRedirects, is also not marked because excessive redirects are a less common edge case compared to connection, timeout, and HTTP status failures.

Exam trap

Cisco often tests the distinction between exceptions that represent recoverable runtime errors (ConnectionError, Timeout, HTTPError) versus exceptions that indicate programming bugs (InvalidURL) or edge-case behavior (TooManyRedirects), leading candidates to over-select or under-select the correct set.

7
Multi-Selectmedium

A Python script is interacting with a REST API that returns JSON. The script needs to handle potential errors gracefully. Which TWO practices should be implemented? (Choose two.)

Select 2 answers
A.Use response.raise_for_status() to raise exceptions for HTTP errors.
B.Use a single try/except block to catch all exceptions without differentiation.
C.Check response.status_code to determine success or failure.
D.Assume the request always succeeds; errors are rare.
E.Always parse the response body with json.loads() regardless of content type.
AnswersA, C

Using `response.raise_for_status()` converts 4xx and 5xx HTTP status codes into `HTTPError` exceptions, satisfying the stem's requirement to handle API errors gracefully rather than silently processing failed responses. This lets the script catch failures explicitly instead of parsing error payloads as valid JSON data.

Why this answer

Option A is correct because response.raise_for_status() from the requests library inspects the HTTP status code and raises an HTTPError for 4xx and 5xx responses, letting the script handle failures via try/except instead of silently processing bad data. Option C is correct because explicitly checking response.status_code (e.g., comparing against 200 or using 200 <= status_code < 300) lets the script branch on success or failure and decide whether to parse JSON or handle the error, which is essential for graceful error handling. Option B is not appropriate because a single undifferentiated try/except hides the specific cause of failures and prevents tailored handling of HTTP errors, JSON decode errors, or connection issues.

Option D is wrong because assuming requests always succeed ignores network failures, timeouts, and 4xx/5xx responses, which defeats graceful error handling. Option E is wrong because calling json.loads() unconditionally can raise JSONDecodeError on non-JSON bodies (e.g., HTML error pages), so parsing should occur only after confirming a successful, JSON content-type response.

Exam trap

Cisco often tests the distinction between using `response.raise_for_status()` versus manually checking `response.status_code` — the trap is that candidates think only one is correct, but both are valid and complementary practices for robust error handling.

8
Multi-Selectmedium

A developer is writing unit tests for a Python function that parses JSON responses from a Cisco Meraki API. The function takes a JSON string and returns a dictionary. The developer wants to follow best practices for unit testing. Which TWO of the following are recommended practices when writing these tests? (Choose two.)

Select 2 answers
A.Include at least one test case for invalid JSON input to verify error handling.
B.Use a test double to simulate the API response instead of making real HTTP calls.
C.Assert only on the final output of the function, ignoring intermediate states.
D.Write tests that depend on the order of execution to save time.
E.Use a single test function that covers all possible edge cases to reduce the number of tests.
AnswersA, B

Testing invalid input ensures that the function handles errors gracefully, such as raising appropriate exceptions or returning meaningful error messages. This is a key aspect of robust unit testing, as it validates the function's behavior under unexpected conditions and helps prevent crashes in production.

Why this answer

Best practices for unit testing include isolating the code under test from external dependencies using test doubles, and covering edge cases such as invalid input. These practices ensure tests are fast, reliable, and comprehensive. The other options describe anti-patterns like order dependence and monolithic tests, which reduce test effectiveness.

Exam trap

The trap here is thinking that testing with real API calls is more realistic and therefore better, when it actually makes tests fragile and slow.

9
MCQmedium

Which Git command is used to switch to an existing branch named 'feature-x' and update the working directory?

A.git merge feature-x
B.git branch feature-x
C.git switch -c feature-x
D.git checkout feature-x
AnswerD

git checkout with a branch name switches HEAD to that existing branch and updates the working directory to match its committed tree, satisfying the stem's requirement to both switch branches and refresh files. git branch alone only lists or creates branches without changing the working directory.

Why this answer

`git checkout feature-x` is the traditional Git command that switches the HEAD reference to the existing branch 'feature-x' and updates the working directory to match that branch's commit history. This command performs both the branch switch and the working tree update in one operation, which is the core requirement of the question.

Exam trap

Cisco often tests the distinction between `git checkout` for switching to an existing branch versus `git checkout -b` (or `git switch -c`) for creating and switching to a new branch, and candidates frequently confuse the `-c` flag as a switch-only option rather than a creation flag.

How to eliminate wrong answers

Option A is wrong because `git merge feature-x` integrates changes from 'feature-x' into the current branch, rather than switching to 'feature-x'. Option B is wrong because `git branch feature-x` creates a new branch named 'feature-x' from the current HEAD, but does not switch to it or update the working directory. Option C is wrong because `git switch -c feature-x` creates and switches to a new branch named 'feature-x', but the question specifies switching to an existing branch, and the `-c` flag is for creation, not for an existing branch.

10
MCQmedium

Which HTTP status code indicates that a POST request successfully created a new resource?

A.204 No Content
B.301 Moved Permanently
C.201 Created
D.200 OK
AnswerC

HTTP 201 Created is returned when a POST request results in a new resource being created on the server, typically accompanied by a Location header identifying the new resource's URI. It precisely signals successful creation, unlike 200 OK, which merely indicates general success.

Why this answer

HTTP 201 Created is the standard response indicating that a request (typically POST) has succeeded and resulted in the creation of a new resource. The response often includes a Location header pointing to the URI of the newly created resource, per RFC 7231.

Exam trap

200-901 often tests the confusion between 200 OK and 201 Created, since both indicate success — candidates must remember that 201 specifically signals resource creation.

How to eliminate wrong answers

Option A is wrong because 204 No Content indicates success but no body to return, commonly used for DELETE or PUT updates, not for resource creation. Option B is wrong because 301 Moved Permanently is a redirection status indicating the resource has permanently moved to a new URL. Option D is wrong because 200 OK is a generic success response that does not specifically signal resource creation — it is used for successful GET, PUT, or POST when no more specific code applies.

11
MCQeasy

What is the output of the following code? my_list = [1, 2, 3] for i in range(len(my_list)): my_list[i] += 1 print(my_list)

A.[2, 3, 4]
B.[1, 2, 3, 1]
C.[1, 2, 3]
D.Error
AnswerA

range(len(my_list)) yields indices 0, 1 and 2. Each iteration increments the element at that index in place via +=, transforming [1, 2, 3] into [2, 3, 4]. The list is mutated directly, so print outputs the updated values.

Why this answer

The loop iterates over indices 0, 1, and 2 using range(len(my_list)). On each iteration, my_list[i] += 1 increments the element at that index in place. Starting from [1, 2, 3], the three iterations produce [2, 3, 4], which is what gets printed.

Exam trap

The trap is assuming that modifying a loop variable inside a for loop has no effect on the underlying list — candidates confuse rebinding a local variable with index-based in-place assignment.

How to eliminate wrong answers

Option B is wrong because it describes appending a new element (1) to the list, but the code uses index assignment (+=), not append, so the list length stays at 3. Option C is wrong because it assumes no mutation occurred, but the += operator modifies each element in place during the loop. Option D is wrong because the code is syntactically and semantically valid — iterating by index with range(len(...)) and mutating elements is legal in Python and does not raise an error.

12
MCQhard

In a microservices architecture, which of the following is a key characteristic compared to a monolithic architecture?

A.Changes require rebuilding the entire application.
B.Services communicate via lightweight protocols such as HTTP/REST.
C.The entire application is deployed as a single unit.
D.All services share the same database.
AnswerB

Microservices decompose functionality into independently deployable units that interact over network calls rather than in-process method invocation. Using lightweight protocols such as HTTP/REST lets each service expose a language-agnostic interface, satisfying the loose-coupling and independent-scalability constraint that monolithic architectures cannot meet.

Why this answer

In a microservices architecture, services are independently deployable and typically communicate over lightweight protocols such as HTTP/REST or messaging queues. This contrasts with monolithic architectures where components are tightly coupled and communicate via internal method calls.

Exam trap

The trap is confusing microservices with monolithic characteristics, such as single deployment unit or shared database, which are actually traits of monolithic architectures.

How to eliminate wrong answers

Option A is wrong because in microservices, changes can be made to individual services without rebuilding the entire application; that is a characteristic of monolithic architectures. Option C is wrong because microservices are deployed independently, not as a single unit. Option D is wrong because each microservice often has its own database to ensure loose coupling, rather than sharing a single database.

13
MCQmedium

In the context of REST API design, which HTTP status code should be returned when a client sends a request that exceeds the API rate limit?

A.503 Service Unavailable
B.400 Bad Request
C.429 Too Many Requests
D.401 Unauthorized
AnswerC

429 Too Many Requests directly signals that the client has exceeded the API's rate limit, satisfying the stem's throttling constraint. Unlike 503, which indicates server unavailability, 429 specifically communicates quota exhaustion and typically accompanies a Retry-After header, letting clients back off and retry after the specified interval.

Why this answer

(429 Too Many Requests) is correct because RFC 6585 defines this status code specifically for cases where a client has sent too many requests in a given time frame, exceeding the API's rate limit. REST APIs use this response to enforce throttling and inform the client to back off, often including a Retry-After header to indicate when to retry.

Exam trap

Cisco often tests the distinction between server-side errors (5xx) and client-side rate-limit errors (429), where candidates mistakenly choose 503 Service Unavailable because they confuse server overload with client rate limiting.

How to eliminate wrong answers

Option A is wrong because 503 Service Unavailable indicates the server is temporarily unable to handle the request due to overload or maintenance, not specifically due to client rate limiting. Option B is wrong because 400 Bad Request indicates a malformed request syntax or invalid parameters, not a rate-limit violation. Option D is wrong because 401 Unauthorized indicates missing or invalid authentication credentials, not exceeding a rate limit.

14
Multi-Selecthard

A Python developer is working on a microservices project where one service needs to communicate with another service that exposes a GraphQL API. Which THREE statements about GraphQL compared to REST are accurate? (Choose three.)

Select 3 answers
A.GraphQL allows clients to request exactly the fields they need.
B.GraphQL is a database query language.
C.GraphQL has a strongly typed schema that defines the API.
D.GraphQL typically uses multiple endpoints for different resources.
E.GraphQL uses HTTP POST for queries and mutations.
AnswersA, C, E

GraphQL queries declare precisely the fields required, so the server returns only those fields, eliminating the over-fetching inherent in REST's fixed resource representations. This satisfies the microservice's need to minimise payload size when calling the GraphQL API.

Why this answer

Option A is correct because GraphQL's core advantage over REST is that the client specifies the exact fields it wants in a single query, avoiding over-fetching and under-fetching of data. Option C is correct because a GraphQL API is defined by a strongly typed schema (SDL) that declares types, queries, mutations, and subscriptions, enabling validation and introspection. Option E is correct because GraphQL operations (queries and mutations) are typically sent as a single HTTP POST request to one endpoint with a JSON body containing the query string.

Option B is incorrect because GraphQL is an API query language and runtime, not a database query language like SQL; it is datastore-agnostic. Option D is incorrect because GraphQL normally exposes a single endpoint (e.g., /graphql) rather than multiple resource-specific endpoints as REST does.

15
MCQmedium

A Python function is designed to fetch device data from multiple sources. It uses *args to accept variable number of API endpoints and **kwargs for optional parameters like timeout. Which function definition correctly implements this?

A.def fetch_devices(**endpoints, *options):
B.def fetch_devices(endpoints, **options):
C.def fetch_devices(*endpoints, **options):
D.def fetch_devices(*endpoints, options):
AnswerC

The signature `def fetch_devices(*endpoints, **options)` satisfies both stem constraints: `*endpoints` collects positional API endpoint arguments into a tuple, while `**options` gathers keyword arguments such as `timeout` into a dictionary. This is the only syntax Python permits for combining arbitrary positional and keyword parameters in one definition.

Why this answer

It uses *endpoints to accept a variable number of positional arguments (the API endpoint strings) and **options to accept any number of keyword arguments (like timeout=30). This matches the requirement for a function that can handle multiple sources with optional parameters, following Python's standard *args/**kwargs pattern.

Exam trap

Cisco often tests the distinction between *args (variable positional arguments) and **kwargs (variable keyword arguments), and the trap here is that candidates confuse the syntax or order, thinking **endpoints can appear before *options or that a simple parameter name like options can accept keyword arguments without the double asterisk.

How to eliminate wrong answers

Option A is wrong because it places **endpoints before *options, which is syntactically invalid in Python — keyword-only arguments must follow positional ones, and **kwargs must be the last parameter. Option B is wrong because it defines endpoints as a single positional parameter, not allowing a variable number of API endpoints; it would require the caller to pass a list or tuple explicitly. Option D is wrong because it uses *endpoints correctly but defines options as a regular positional parameter, not as **kwargs, so optional parameters like timeout cannot be passed as keyword arguments.

16
MCQmedium

Given the following Python code snippet: with open('config.json', 'r') as f: data = json.load(f) print(data['interfaces'][0]['name']) What is the expected output if config.json contains {"interfaces": [{"name": "GigabitEthernet0/1"}]}?

A.GigabitEthernet0/1
B.None
C.interfaces
D.Error: list indices must be integers
AnswerA

The code parses the JSON file into a Python dictionary, then indexes the `interfaces` list to retrieve its first element and reads that dictionary's `name` key. Given the supplied file content, this resolves to the string `GigabitEthernet0/1`, which `print` outputs without quotes.

Why this answer

json.load() reads the file and returns a dict; then accessing the nested structure yields 'GigabitEthernet0/1'.

17
MCQmedium

In version control with Git, which command creates a new branch and switches to it in one step?

A.git checkout -b <branch>
B.git checkout <branch>
C.git branch <branch>
D.git switch <branch>
AnswerA

git checkout -b <branch> creates the new branch at the current HEAD and immediately switches the working tree to it, combining creation and checkout. This single-step behaviour matches the stem's requirement, unlike git branch alone, which only creates.

Why this answer

git checkout -b <branch> creates and switches. git branch <branch> creates but does not switch. git switch -c is also valid but not listed.

18
MCQmedium

A Python script sends a PUT request to update a resource. The API returns a response with status code 204. What does this indicate?

A.The request was malformed.
B.The update was successful and no content is returned.
C.The resource was not found.
D.The update failed due to a server error.
AnswerB

HTTP 204 No Content confirms the server processed the PUT successfully but returns no body, matching the stem's update scenario. It differs from 200, which carries a response body, and from 404, which signals the resource was not found.

Why this answer

HTTP 204 No Content means the server successfully processed the request and is not returning any body content. For a PUT request, this indicates the resource was updated successfully but the server chose not to return the updated representation. It is a 2xx success status, distinct from 200 OK which would include a response body.

Exam trap

200-901 often tests the meaning of specific HTTP status codes — candidates confuse 204 (success, no content) with 200 (success, with content) or with 202 (accepted, processing not complete), and may incorrectly associate 204 with an error condition.

How to eliminate wrong answers

Option A is wrong because a malformed request returns 400 Bad Request, not 204. Option C is wrong because a missing resource returns 404 Not Found. Option D is wrong because a server-side failure returns 5xx codes such as 500 Internal Server Error or 503 Service Unavailable. 204 is unambiguously a success code in the 2xx class.

19
Multi-Selecthard

Which THREE of the following are best practices when using Git for a collaborative project? (Choose three.)

Select 3 answers
A.Use feature branches for new work.
B.Rebase or merge regularly to incorporate upstream changes.
C.Commit directly to the main branch.
D.Write descriptive commit messages.
E.Avoid pulling from remote to prevent conflicts.
AnswersA, B, D

Feature branches isolate new work from the mainline, so unfinished or experimental changes never destabilise shared code. This satisfies the stem's collaborative best-practice requirement by enabling independent development and clean pull requests before merging into the shared branch.

Why this answer

Option A is correct because feature branches isolate new work from the main branch, allowing changes to be developed, reviewed, and tested before integration, which reduces the risk of breaking shared code. Option B is correct because regularly rebasing or merging upstream changes keeps a feature branch current, minimizes large and painful merge conflicts, and ensures the work is built against the latest codebase. Option D is correct because descriptive commit messages document the intent and context of changes, making history easier to review, debug, and audit for collaborators.

Option C is not a best practice in a collaborative project because committing directly to the main branch bypasses review and can destabilize the shared branch. Option E is not a best practice because avoiding pulls prevents developers from incorporating others' changes, leading to stale local work and more severe conflicts later.

Exam trap

Cisco often tests the misconception that committing directly to main is acceptable for small changes, but the exam emphasizes that all changes should go through feature branches to maintain a clean, reviewable history.

20
MCQmedium

Given the JSON string: '{"name": "Alice", "scores": [90, 85, 92]}', which Python code correctly extracts the second score (85)?

A.json.loads(json_str)['scores'][1]
B.json.dumps(json_str)['scores'][1]
C.json_str['scores'][1]
D.json.loads(json_str)['scores'][2]
AnswerA

json.loads parses the string into a dictionary, then ['scores'] retrieves the list and [1] indexes its second element, which is 85. Python lists are zero-indexed, so index 1 satisfies the stem's requirement of extracting the second score rather than the first.

Why this answer

json.loads converts to dict, then access scores list index 1.

21
MCQmedium

A Python function is defined as: def process(*args, **kwargs): return sum(args) + kwargs.get('offset', 0) What is the result of process(1, 2, 3, offset=10)?

A.6
B.16
C.Error
D.10
AnswerB

The `*args` parameter collects the positional arguments 1, 2 and 3 into a tuple, which `sum()` totals to 6. The `**kwargs` parameter collects `offset=10` into a dictionary, and `kwargs.get('offset', 0)` retrieves 10. Adding 6 and 10 returns 16.

Why this answer

*args captures positional arguments as tuple (1,2,3), sum is 6, kwargs dict includes {'offset':10}, .get returns 10, total 16.

22
MCQmedium

Which HTTP status code indicates that a POST request successfully created a new resource on the server?

A.200 OK
B.201 Created
C.204 No Content
D.202 Accepted
AnswerB

201 Created is returned when a POST request results in a new resource being created on the server, typically accompanied by a Location header identifying its URI. Other 2xx codes, such as 200 OK, indicate success without confirming resource creation.

Why this answer

The 201 Created status code is the correct response for a POST request that successfully creates a new resource. According to RFC 7231, the server should respond with 201 and include a Location header pointing to the newly created resource's URI. This is the standard behavior for RESTful APIs when a POST operation results in resource creation.

Exam trap

Cisco often tests the distinction between 200 OK and 201 Created, trapping candidates who assume any successful POST returns 200 OK, when in fact 201 is the standard for resource creation.

How to eliminate wrong answers

Option A is wrong because 200 OK indicates a successful request but does not specifically signal that a new resource was created; it is typically used for GET requests or POST requests that return a representation without creating a new resource. Option C is wrong because 204 No Content indicates the server successfully processed the request but returns no response body, often used for DELETE operations or updates that return no content, not for resource creation. Option D is wrong because 202 Accepted means the request has been accepted for processing but the processing has not been completed; it is used for asynchronous operations, not for immediate resource creation.

23
MCQeasy

A developer is working on a Git repository and needs to temporarily save changes that are not ready to be committed so they can switch to another branch to fix a bug. Which Git command should the developer use to stash the current changes?

A.git commit -m "WIP"
B.git branch temp
C.git stash
D.git checkout -- .
AnswerC

This is correct because git stash saves the current working directory and index state, reverting the working directory to match the HEAD commit. It allows the developer to switch branches without committing unfinished work. Later, git stash pop or git stash apply can restore the changes. This command is specifically designed for temporarily shelving changes.

Why this answer

The git stash command is designed to temporarily store modifications to tracked files and the staging area, allowing a clean working directory. This enables switching branches or performing other operations without committing incomplete work. The stashed changes can be reapplied later with git stash pop or git stash apply, making it ideal for the described scenario.

Exam trap

The trap here is assuming that committing work-in-progress is equivalent to stashing, but committing creates permanent history while stashing is temporary and does not affect the commit log.

24
MCQeasy

A developer is writing a Python script to iterate over a list of server hostnames. Which loop structure is most appropriate to process each hostname in the list?

A.for i, hostname in enumerate(hostnames): print(hostname)
B.while len(hostnames) > 0: print(hostnames.pop())
C.for i in range(len(hostnames)): print(hostnames[i])
D.for hostname in hostnames: print(hostname)
AnswerD

A for loop iterates directly over the hostnames list, binding each element to the loop variable in turn, which is the idiomatic structure for processing every item in a sequence. It satisfies the requirement to process each hostname without manual index management.

Why this answer

The 'for item in list' loop iterates directly over each element, making it the simplest and most readable for processing each hostname.

25
MCQeasy

A developer is using Git to contribute to a shared repository. After making several commits on a local feature branch, the developer wants to integrate the latest changes from the remote main branch into the feature branch while keeping a linear history. Which Git command should be used?

A.git rebase main
B.git merge main
C.git pull origin main
D.git cherry-pick main
AnswerA

git rebase main replays the commits from the current feature branch on top of the latest main, resulting in a linear history without a merge commit. This is the standard way to incorporate upstream changes while keeping a clean, linear commit sequence. It rewrites the feature branch commits, which is acceptable for local branches that have not been shared.

Why this answer

To integrate upstream changes while keeping a linear history, the feature branch commits must be replayed on top of the updated main. git rebase main performs exactly this operation, moving the branch pointer and rewriting commits so that the history appears as if the feature was developed after the latest main. Merging or pulling would create a merge commit, and cherry-pick does not apply the full set of changes.

Exam trap

The trap here is confusing merge and rebase: merge preserves branch topology but adds a merge commit, while rebase rewrites commits to achieve a linear sequence.

26
MCQeasy

A developer is working on a Python script that performs CRUD operations on devices via a REST API. Which HTTP method should be used to update an existing device's configuration partially?

A.PATCH
B.POST
C.DELETE
D.PUT
AnswerA

PATCH applies a partial modification to an existing resource, sending only the changed fields. It satisfies the constraint of updating a device's configuration partially, whereas PUT would replace the entire representation and require the full payload.

Why this answer

PATCH is the correct HTTP method for partial updates to an existing resource. Unlike PUT, which replaces the entire resource, PATCH applies a set of changes (a patch document) to the resource, modifying only the specified fields. In the context of a REST API for device configuration, using PATCH allows the developer to update a subset of configuration parameters without affecting others.

Exam trap

The trap here is confusing PUT with PATCH: candidates often think PUT can be used for any update, but PUT replaces the entire resource, while PATCH is for partial modifications.

How to eliminate wrong answers

Option B is wrong because POST is used to create new resources or submit data to be processed, not for partial updates to an existing resource. Option C is wrong because DELETE is used to remove a resource, not to update it. Option D is wrong because PUT is used to replace the entire resource with the provided representation; using PUT for a partial update would overwrite unspecified fields, potentially causing data loss.

27
MCQmedium

A developer needs to parse a JSON string received from a REST API into a Python dictionary. Which function should they use?

A.json.dumps()
B.json.loads()
C.json.load()
D.json.dump()
AnswerB

json.loads() deserialises a JSON-formatted string into a Python dictionary, satisfying the stem's requirement to parse an incoming REST API string. Its counterpart json.load() reads from a file object instead, so it would not work on the raw string the developer receives.

Why this answer

json.loads() converts a JSON string into a Python object (dict, list, etc.).

28
MCQmedium

A developer is writing a Python function that accepts a list of interface names and returns a dictionary mapping each interface name to the number of characters in that name. The function should also verify that the input is a list and raise a TypeError otherwise. Which approach correctly implements the described behavior?

A.def map_lengths(names): if type(names) != list: raise ValueError('names must be a list') return {n: n.__len__() for n in names}
B.def map_lengths(names): assert isinstance(names, list) return dict(zip(names, map(len, names)))
C.def map_lengths(names): return {n: len(n) for n in names}
D.def map_lengths(names): if not isinstance(names, list): raise TypeError('names must be a list') return {n: len(n) for n in names}
AnswerD

This implementation checks the input with isinstance against list and raises TypeError when the check fails, then builds the required dictionary with a comprehension. It satisfies both stated requirements: type validation that raises TypeError and a mapping of each interface name to its character length.

Why this answer

The requirement is twofold: validate that the argument is a list and raise TypeError when it is not, then return a dictionary of name to length. Only the implementation using isinstance with a TypeError raise and a dictionary comprehension satisfies both constraints in a single, correct function.

Exam trap

The trap here is treating assert or ValueError as equivalent to raising TypeError, when the exception type and runtime behavior differ.

29
MCQmedium

A developer is writing a Python unit test for a function that makes an HTTP request to an external API. To avoid network calls during testing, the developer wants to mock the requests.get function. Which Python library is specifically designed for mocking in unit tests and is part of the standard library?

A.requests-mock
B.mock
C.pytest-mock
D.unittest.mock
AnswerD

unittest.mock is part of the Python standard library and provides a flexible framework for mocking objects and functions in unit tests. It allows patching requests.get with a mock object that returns a predefined response, eliminating network calls. The patch decorator or context manager can temporarily replace the function during the test. This is the standard approach for mocking in Python.

Why this answer

The unittest.mock module, part of the Python standard library, provides the patch function and Mock class to replace objects during tests. It can mock requests.get to return a controlled response, preventing actual network calls. This is the standard way to isolate unit tests from external dependencies without third-party libraries.

Exam trap

The trap here is confusing the third-party mock library or pytest-mock with the standard library module, but unittest.mock is the built-in solution since Python 3.3.

30
MCQmedium

A developer clones a shared repository and creates a feature branch, but a teammate pushes a commit to the main branch that conflicts with local edits. The developer wants to bring those upstream changes into the feature branch and resolve conflicts before opening a pull request. Which Git operation should be used?

A.git stash pop after fetching main
B.git merge main while the feature branch is checked out
C.git revert main while the feature branch is checked out
D.git reset --hard main while the feature branch is checked out
AnswerB

Running merge with the feature branch checked out integrates the commits from main into the current branch and leaves the feature branch history intact. Conflicts are surfaced in the working tree for the developer to resolve and commit, and the pull request then reflects the merged state. This is the standard way to incorporate upstream changes before review.

Why this answer

Merging main into the checked-out feature branch brings the upstream commits into the feature branch and presents conflicts in the working tree for resolution. The feature branch retains its own commits, and the resulting state can be pushed for review. This is the conventional pre-pull-request integration step when a teammate has advanced the main branch.

Exam trap

The trap here is reaching for reset or revert to reconcile branches, when those operations discard or undo commits rather than integrate another branch's history into the current one.

31
MCQhard

A Python script uses a try/except block to handle API errors. If the API returns a 429 status code, which mechanism should the script implement to handle the error appropriately?

A.Switch to a different API endpoint
B.Wait for the time specified in the Retry-After header and then retry
C.Log the error and continue without retrying
D.Immediately retry the same request without delay
AnswerB

HTTP 429 signals rate limiting, and the Retry-After header specifies how long to wait before retrying. Honouring that value respects the server's throttling window, satisfying the stem's requirement to handle the error appropriately rather than retrying immediately or abandoning the request.

Why this answer

A 429 status code indicates the client has sent too many requests in a given amount of time (rate limiting). The HTTP specification (RFC 6585) recommends including a Retry-After header in the response, which tells the client how long to wait before retrying. Implementing a wait based on this header and then retrying is the correct and respectful way to handle rate limiting, allowing the script to eventually succeed without overwhelming the server.

Exam trap

Cisco often tests the distinction between handling transient errors (like 429) versus permanent errors (like 404 or 500), and the trap here is that candidates may choose to immediately retry (D) or log and continue (C) without understanding that 429 specifically requires a delay before retry.

How to eliminate wrong answers

Option A is wrong because switching to a different API endpoint does not address the rate limit on the current endpoint; the client is still rate-limited and the new endpoint may also be affected or require separate authentication. Option C is wrong because logging the error and continuing without retrying means the script abandons the operation entirely, which is not appropriate when the error is transient and can be resolved by waiting. Option D is wrong because immediately retrying the same request without delay will almost certainly result in another 429 error, as the rate limit has not yet expired, and may worsen the situation by further exhausting the rate limit window.

32
MCQeasy

A developer is writing a Python function that accepts a variable number of interface names and returns them as a tuple. Which function definition correctly allows an arbitrary number of positional arguments?

A.def list_interfaces(*interfaces):
B.def list_interfaces(interfaces):
C.def list_interfaces(**interfaces):
D.def list_interfaces(interfaces=[]):
AnswerA

The asterisk before the parameter name collects all positional arguments into a tuple named interfaces. This allows the function to accept any number of interface names, including zero, and directly returns them as a tuple when referenced. This matches the scenario's requirement for arbitrary positional arguments.

Why this answer

The function must accept a variable number of positional arguments. Using *interfaces packs all positional arguments into a tuple, which is exactly what the scenario requires. The other definitions either accept a single argument, collect keyword arguments into a dictionary, or use a mutable default that introduces bugs and still does not support multiple positional arguments.

Exam trap

The trap here is confusing *args with **kwargs, where the single asterisk collects positional arguments into a tuple and the double asterisk collects keyword arguments into a dictionary.

33
MCQmedium

A network engineer writes a Python script to handle exceptions when making REST API calls. Which exception type should be caught to handle network connectivity issues (e.g., DNS failure, refused connection)?

A.requests.exceptions.RequestException
B.requests.exceptions.ConnectionError
C.requests.exceptions.HTTPError
D.requests.exceptions.Timeout
AnswerB

requests.exceptions.ConnectionError is raised when the underlying connection cannot be established, covering DNS resolution failures and refused connections. Catching it satisfies the requirement to handle network connectivity issues, unlike HTTPError, which signals a received error response.

Why this answer

`requests.exceptions.ConnectionError` is specifically raised when the underlying TCP connection fails, which includes scenarios like DNS resolution failures, refused connections, or the remote host being unreachable. This exception is a subclass of `RequestException` and directly maps to network-level issues at the transport layer, making it the precise exception to catch for connectivity problems.

Exam trap

Cisco often tests the distinction between the broad `RequestException` and the specific `ConnectionError`, trapping candidates who choose the base class thinking it covers all errors, when the question explicitly asks for network connectivity issues.

How to eliminate wrong answers

Option A is wrong because `requests.exceptions.RequestException` is the base class for all exceptions in the `requests` library; catching it would be too broad and would also handle non-connectivity errors like HTTP errors or timeouts, which is not the specific requirement. Option C is wrong because `requests.exceptions.HTTPError` is raised only when the server returns an HTTP error status code (e.g., 4xx or 5xx), which indicates an application-level issue, not a network connectivity failure. Option D is wrong because `requests.exceptions.Timeout` is raised when a request exceeds the specified timeout period, which is a timing issue rather than a fundamental network connectivity failure like DNS failure or refused connection.

34
MCQeasy

A network automation team is adopting Git for managing Python scripts and YAML device templates. They want a branching model where each new feature is developed in isolation and merged back into a shared integration branch before release. Which Git branching strategy best matches this requirement?

A.Trunk-Based Development
B.GitHub Flow
C.Git Flow
D.Forking Workflow
AnswerC

Git Flow uses a long-lived develop branch as the integration branch where feature branches are merged, and a main branch that holds released code. This directly matches the requirement that features be isolated and then merged into a shared integration branch before release, making it the correct branching strategy here.

Why this answer

Git Flow defines a develop branch that acts as the integration point for completed feature branches and a main branch that stores release-ready code. Because the team wants features isolated and then merged into a shared integration branch before release, Git Flow is the model that matches those constraints.

Exam trap

The trap here is assuming any modern branching model uses a separate integration branch, when GitHub Flow and trunk-based development integrate directly into main.

35
MCQmedium

A developer is designing a microservices architecture for a network monitoring application. Which of the following is a key advantage of microservices over a monolithic architecture?

A.Lower latency due to in-process communication
B.Easier to maintain as a single codebase
C.Independent deployability and scalability of services
D.Simpler inter-service communication
AnswerC

Each microservice runs as a separate deployable unit, so teams can release and scale it independently without rebuilding the whole application. A monolith must be deployed and scaled as one artefact, which is the constraint this advantage directly addresses.

Why this answer

Microservices architecture enables each service to be deployed, updated, and scaled independently without affecting other services. This is a key advantage over monolithic architectures, where any change requires rebuilding and redeploying the entire application. For a network monitoring application, independent scalability allows resource-intensive services (e.g., packet capture) to scale separately from lightweight services (e.g., alerting).

Exam trap

Cisco often tests the misconception that microservices simplify communication or reduce latency, when in reality they introduce network overhead and complexity, making independent deployability and scalability the primary advantage.

How to eliminate wrong answers

Option A is wrong because microservices typically use inter-process communication (e.g., HTTP/REST, gRPC, or message queues), which introduces higher latency compared to in-process function calls in a monolithic application. Option B is wrong because microservices split the codebase into multiple smaller repositories, each maintained by separate teams, making the overall system more complex to manage than a single monolithic codebase. Option D is wrong because inter-service communication in microservices is inherently complex, requiring handling of network failures, serialization, and service discovery (e.g., via Consul or Kubernetes DNS), unlike monolithic architectures where components communicate via direct function calls.

36
Multi-Selecthard

A developer is preparing a Python script that will be shared with a team and run in multiple environments. The script relies on several third-party libraries. Which TWO practices should be followed to ensure reproducible dependency management? (Choose two.)

Select 2 answers
A.Install packages globally with pip install --user to avoid permission issues.
B.Commit the entire virtual environment directory to the Git repository.
C.Pin exact versions of dependencies in a requirements.txt file using the == operator.
D.Rely on the latest versions of dependencies by omitting version specifiers in requirements.txt.
E.Use a virtual environment to isolate project dependencies from the system Python installation.
AnswersC, E

Pinning exact versions with == ensures that every environment installs the same package versions, preventing unexpected behavior from newer releases. This is a cornerstone of reproducible builds. When combined with a virtual environment, it guarantees that the dependencies resolved during development match those in testing and production, which is essential for collaborative projects and consistent API interactions.

Why this answer

Reproducible dependency management requires isolating project packages and recording exact versions. A virtual environment prevents interference from system-wide packages, while pinning versions in requirements.txt ensures that every installation uses the same releases. Together they allow any team member or CI system to recreate the exact environment.

Global installs, unpinned versions, and committing the virtual environment all introduce variability and are not recommended.

Exam trap

The trap here is thinking that installing packages globally or omitting version pins is acceptable for shared projects, when both practices lead to inconsistent environments.

37
MCQeasy

A developer is working on a Python script that must read a JSON configuration file containing device credentials. The script needs to parse the file and access the value of the key 'username'. Which Python standard library module and function should be used?

A.configparser.ConfigParser().read()
B.json.loads()
C.json.load()
D.yaml.safe_load()
AnswerC

The json module's load() function reads a file object and deserializes JSON data into a Python dictionary. This directly allows access to the 'username' key. It is the standard, correct approach for parsing a JSON file in Python, handling the conversion from JSON text to native Python objects seamlessly.

Why this answer

The json.load() function is the correct choice because it reads a file object and returns a Python dictionary, allowing immediate access to the 'username' key. The other options either parse strings, handle different formats, or are not part of the standard library for JSON parsing.

Exam trap

The trap here is confusing json.load() with json.loads(), where the former reads from a file and the latter from a string.

38
MCQhard

A developer maintains a Python library that calls a REST API and currently stores the API token in a module-level constant. The team wants to follow twelve-factor app principles so the same build artifact can be deployed to lab and production without code changes. Which change should the developer make?

A.Move the token into a config.ini file that is committed to the repository and read at import time.
B.Encrypt the token with a symmetric key and store both the ciphertext and key in the repository for decryption at runtime.
C.Read the token from an environment variable, such as os.environ['API_TOKEN'], at runtime.
D.Detect the deployment environment by hostname and select a hardcoded token for each environment.
AnswerC

Twelve-factor apps store configuration in the environment, so reading the token from an environment variable lets the same artifact run in lab and production with different values. This removes secrets from source code and enables per-environment configuration without rebuilding or editing files, satisfying the stated requirement.

Why this answer

Twelve-factor configuration is stored in the environment, not in code or committed files. Reading the API token from an environment variable allows the identical build artifact to run in lab and production with different credentials, keeps secrets out of source control, and requires no code edits between deployments.

Exam trap

The trap here is thinking encryption at rest in the repository solves secret management, when the decryption key must also be externalized.

39
MCQmedium

In software architecture, which pattern separates an application into three interconnected components: Model (data), View (UI), and Controller (input logic)?

A.MVC (Model-View-Controller)
B.Microservices
C.Event-driven
D.REST
AnswerA

MVC directly satisfies the stem's three-component split: the Model handles data and business rules, the View renders the UI, and the Controller processes input and mediates between them. This separation of concerns is precisely the interconnected Model-View-Controller architecture the question describes.

Why this answer

The MVC pattern explicitly separates an application into three interconnected components: Model (data and business logic), View (user interface), and Controller (handles user input and updates the Model/View). This is the foundational architectural pattern for many web frameworks like Django, Ruby on Rails, and Spring MVC, where the Controller receives HTTP requests, interacts with the Model, and selects the appropriate View for rendering.

Exam trap

Cisco often tests that candidates confuse MVC with REST or Microservices because both involve separation of concerns, but MVC is specifically about internal component separation within a single application, not about service decomposition or API design.

How to eliminate wrong answers

Option B (Microservices) is wrong because it decomposes an application into independently deployable services, each with its own data and logic, rather than separating a single application into Model, View, and Controller components. Option C (Event-driven) is wrong because it relies on event producers and consumers communicating asynchronously via an event bus, not on a three-component separation of data, UI, and input logic. Option D (REST) is wrong because it is an architectural style for designing networked APIs using HTTP methods and stateless communication, not a pattern for structuring internal application components.

40
MCQhard

A developer uses the requests library to call an API. The API returns 429 Too Many Requests. What is the best practice to handle this?

A.Ignore the status code and proceed
B.Immediately retry the request
C.Use exponential backoff and retry
D.Wait a fixed amount of time and retry
AnswerC

HTTP 429 signals rate limiting, so retrying immediately would worsen the condition. Exponential backoff progressively increases the delay between retries, satisfying the stem's best-practice requirement by giving the server time to recover while respecting its rate limits.

Why this answer

HTTP 429 Too Many Requests indicates the client has exceeded the server's rate limit. The correct handling is to retry after a delay, and exponential backoff (with jitter) is the industry best practice because it progressively increases wait times between retries, reducing load on the server and avoiding thundering-herd effects. Many APIs also return a Retry-After header that should be honored.

Exam trap

The trap is choosing 'immediately retry' or 'fixed wait' as simpler alternatives — candidates underestimate how retry storms amplify server load and overlook exponential backoff as the standard resilience pattern.

How to eliminate wrong answers

Option A is wrong because ignoring the 429 and proceeding will continue to violate the rate limit, likely resulting in further 429s or a temporary ban. Option B is wrong because immediately retrying without delay will hammer the server, worsen the rate-limit condition, and may trigger stricter throttling or IP blocking. Option D is wrong because a fixed wait time is less effective than exponential backoff — it doesn't adapt to sustained overload and can still cause synchronized retry storms when many clients retry simultaneously.

41
MCQhard

A developer is writing a Python script that uses the requests library to call a REST API. The API occasionally returns a 429 status code. Which approach best handles this situation?

A.Implement exponential backoff and respect the Retry-After header if present.
B.Ignore the 429 and continue with the next request.
C.Retry the request immediately in a tight loop until it succeeds.
D.Switch to a different API endpoint that is not rate-limited.
AnswerA

Exponential backoff increases the delay between retries, reducing load on the API. Respecting the Retry-After header ensures compliance with the API's rate limit policy. This approach is standard for handling 429 errors and improves the chances of eventual success without causing further throttling. It is both polite and effective.

Why this answer

Exponential backoff with respect to Retry-After is the recommended way to handle 429 responses. It allows the client to recover from rate limiting without overwhelming the server. The other options either ignore the error, retry too aggressively, or avoid the endpoint, none of which are robust solutions.

This approach balances persistence with respect for API limits.

Exam trap

The trap here is thinking that immediate retries will eventually succeed, but they can worsen rate limiting; backoff is essential.

42
MCQmedium

A developer needs to update an existing resource via a REST API. The update should be partial, meaning only the fields provided in the request body should be changed. Which HTTP method should be used?

A.PATCH
B.DELETE
C.PUT
D.POST
AnswerA

PATCH applies a partial modification, changing only the fields included in the request body while leaving all other resource properties untouched. This directly satisfies the stem's requirement for a partial update, unlike PUT, which replaces the entire resource representation and would overwrite unspecified fields with defaults or nulls.

Why this answer

PATCH is used for partial updates to a resource, while PUT replaces the entire resource.

43
MCQmedium

A developer is building a Python script that calls a REST API which returns a JSON payload containing a list of interfaces. The script must parse the response and extract the 'name' field from each interface object. Which approach correctly uses the requests library to parse the JSON and iterate over the interfaces?

A.response = requests.get(url); interfaces = json.loads(response); for intf in interfaces['interfaces']: print(intf['name'])
B.response = requests.get(url); interfaces = response.json; for intf in interfaces['interfaces']: print(intf['name'])
C.response = requests.get(url); interfaces = response.json(); for intf in interfaces['interfaces']: print(intf['name'])
D.response = requests.get(url); interfaces = response.text; for intf in interfaces['interfaces']: print(intf['name'])
AnswerC

This is correct because requests.get() returns a Response object, and calling .json() on it parses the JSON body into Python data structures. If the payload has a top-level key 'interfaces' containing a list of dictionaries, indexing with ['interfaces'] and iterating yields each interface dict, from which ['name'] extracts the desired field.

Why this answer

The requests library's Response object provides a .json() method that deserializes the JSON response body into Python objects. After calling .json(), the result is typically a dictionary or list that can be indexed and iterated. Using response.json() is the idiomatic way to parse JSON in requests, and the subsequent iteration extracts the 'name' field from each interface dictionary.

Exam trap

The trap here is confusing the Response object with its JSON content, or forgetting to call .json() as a method, leading to type errors when trying to index the response.

44
Multi-Selecthard

A developer is writing unit tests for a Python function that interacts with a REST API. Which TWO practices are recommended to ensure tests are reliable and isolated? (Choose two.)

Select 2 answers
A.Include delays between test cases to simulate network latency.
B.Run tests in parallel to reduce execution time.
C.Mock external HTTP requests using a library like unittest.mock or responses.
D.Use real API endpoints to ensure the function works with actual data.
E.Assert that the function returns the expected data structure and values.
AnswersC, E

Mocking external HTTP requests prevents tests from depending on network availability or API rate limits. It allows you to simulate various responses, including errors, and ensures tests run quickly and deterministically. This isolation is crucial for reliable unit tests, as it removes external dependencies and focuses on the function's logic.

Why this answer

Mocking external HTTP requests and asserting on the function's output are key to reliable unit tests. Mocking isolates the code under test from external dependencies, while assertions validate correct behavior. Together, they ensure tests are fast, deterministic, and focused on logic.

The other practices either introduce dependencies or do not address isolation and reliability.

Exam trap

The trap here is thinking that testing against real APIs provides more confidence, but it actually makes tests unreliable and non-deterministic.

45
MCQmedium

Which Git branching strategy typically involves a long-lived 'develop' branch where feature branches are merged, and releases are created from a 'release' branch?

A.GitFlow
B.GitHub Flow
C.Trunk-based development
D.Feature branch workflow
AnswerA

GitFlow defines a long-lived develop branch that accumulates merged feature branches, with release branches cut from develop for stabilisation before merging into main. This matches the stem's described structure precisely, unlike trunk-based or GitHub Flow.

Why this answer

GitFlow is correct because it defines a long-lived 'develop' branch for integrating feature branches, and a separate 'release' branch for preparing releases. This strategy uses dedicated branches for features, releases, and hotfixes, with strict merging rules back to 'develop' and 'main'.

Exam trap

Cisco often tests the distinction between GitFlow's multiple long-lived branches (develop, release, main) and simpler workflows like GitHub Flow or trunk-based development, where candidates mistakenly assume any workflow with feature branches is GitFlow.

How to eliminate wrong answers

Option B (GitHub Flow) is wrong because it uses a single long-lived 'main' branch with short-lived feature branches, and releases are created directly from 'main' without a dedicated 'release' branch. Option C (Trunk-based development) is wrong because it relies on a single trunk branch (often 'main' or 'trunk') with very short-lived feature branches, and no long-lived 'develop' or 'release' branches. Option D (Feature branch workflow) is wrong because it typically merges feature branches directly into a shared branch (e.g., 'main') without a separate long-lived 'develop' branch or a dedicated 'release' branch.

46
Multi-Selecthard

A developer is preparing a Python script that authenticates to a Cisco DNA Center controller, retrieves a list of network devices, and writes the inventory into a reusable module consumed by other teams. The team lead requires that the credentials never be stored in the source code. Which TWO practices satisfy that requirement? (Choose two.)

Select 2 answers
A.Load the credentials from a separate configuration file that is listed in .gitignore and provisioned on each host.
B.Encode the credentials with base64 inside the module so they are unreadable to anyone browsing the source.
C.Commit the credentials in an encrypted form and keep the decryption key in the same repository branch for convenience.
D.Read the credentials at runtime from environment variables that are set outside the repository on the execution host.
E.Hard-code the credentials as module-level constants but rename the variables so they are not obviously credentials.
AnswersA, D

A config file excluded by .gitignore is never committed, so the secret does not enter the repository history. Each environment supplies its own file, and the parsing code can be committed safely because it contains no secret values, satisfying the requirement while remaining convenient for other teams.

Why this answer

Secrets must be injected from outside the repository so that committed code never contains them. Environment variables and an ignored, per-host configuration file both achieve this, letting each consumer supply its own values while the module itself holds only the logic that reads them. Encoding or renaming secrets inside the source leaves the values in version history.

Exam trap

The trap here is treating encoding or renaming as protection, when only keeping the secret outside the committed source actually removes it.

47
Multi-Selectmedium

A developer is using Git for version control in a collaborative project and wants to ensure a clean, linear history. Which TWO practices help achieve a linear commit history? (Choose two.)

Select 2 answers
A.Use git rebase to integrate changes from the main branch into a feature branch before merging.
B.Use git merge with the --no-ff flag to always create a merge commit.
C.Use git commit --amend to modify the most recent commit.
D.Use git pull --rebase to fetch and rebase local changes on top of the remote branch.
E.Use git cherry-pick to apply specific commits from one branch to another.
AnswersA, D

Rebasing a feature branch onto the main branch rewrites the feature branch's commits to apply on top of the latest main, resulting in a linear history when merged. This avoids merge commits and keeps the commit graph clean. It is a common practice in teams that prefer a linear history, though it should be used with caution on shared branches.

Why this answer

To maintain a linear commit history, developers should rebase feature branches onto the main branch before merging and use git pull --rebase when updating from a remote. These practices avoid merge commits and keep the commit graph as a straight line. They are widely adopted in teams that prioritize a clean, readable history.

Exam trap

The trap here is thinking that merge commits are necessary for a linear history, but actually merge commits create a non-linear graph; rebasing and pull --rebase are the key practices.

48
Multi-Selecthard

A developer is preparing a Python script that will be committed to a shared Git repository used by a team of network automation engineers. The team wants to ensure that sensitive credentials and environment-specific files are never committed. Which TWO actions should the developer take? (Choose two.)

Select 2 answers
A.Use environment variables to supply credentials at runtime instead of hardcoding them.
B.Add a .gitignore file listing files such as .env and credentials.json.
C.Store the credentials in a README.md file so the team can easily find them.
D.Run git add . to stage all files, then manually unstage credentials before committing.
E.Commit the credentials file once, then delete it in a later commit.
AnswersA, B

Reading credentials from environment variables keeps secrets out of the codebase entirely. The script can access them at runtime without any sensitive values being stored in Git. This complements .gitignore by removing the need to commit credentials at all, satisfying the team's requirement to protect sensitive information.

Why this answer

The team needs to prevent sensitive files from entering Git. A .gitignore file excludes specified files and patterns from being tracked, and using environment variables for credentials means secrets never need to be stored in the repository. Committing credentials even temporarily, storing them in documentation, or relying on manual unstaging all risk exposing secrets and do not provide a reliable safeguard.

Exam trap

The trap here is believing that deleting a committed credentials file removes it from history, when Git retains all past commits unless history is rewritten.

49
MCQhard

A developer maintains a Python package that other teams import. The package's setup.py currently pins an HTTP library to an exact version, and a consuming team reports that pip refuses to install their project because they require a newer minor release of the same library. Which change to the dependency specification best resolves the conflict while still protecting against breaking major upgrades?

A.Raise the pin to the newest available exact version, such as requests==2.31.0, so both projects use the same release.
B.Replace the exact pin with a compatible-release specifier such as requests>=2.28,<3.0 so minor and patch updates are allowed.
C.Pin the library to a specific older major version such as requests==1.2.3 to guarantee compatibility with existing code.
D.Remove the library from the dependency list entirely so pip installs whichever version the consuming project happens to request.
AnswerB

A range that permits newer 2.x releases while excluding 3.0 lets the consuming team install its required minor version and still blocks a breaking major upgrade. This resolves the resolver conflict without abandoning protection against incompatible changes, which is exactly the balance the scenario demands.

Why this answer

Dependency specifications should express the range the package actually supports. A lower bound with an upper bound below the next major version allows compatible minor and patch upgrades, which satisfies the consuming team's requirement while still guarding against breaking changes. Exact pins and removed declarations either block valid upgrades or leave the dependency undeclared.

Exam trap

The trap here is thinking that any exact pin is the safest choice, when exact pins are what create resolver conflicts across projects.

50
MCQeasy

What does the Git command 'git log --oneline' display?

A.A list of files changed in the last commit
B.The branches and their latest commits
C.The differences between the working directory and the last commit
D.A summary of each commit on one line
AnswerD

The --oneline flag condenses each commit to its abbreviated SHA-1 hash followed by the commit subject, printing one commit per line. This satisfies the requirement for a compact summary rather than the default multi-line format showing author, date and full message.

Why this answer

The --oneline flag condenses each commit to a single line showing the commit hash and message.

51
Multi-Selecthard

A developer is writing unit tests for a Python function that parses Cisco IOS configuration text and returns a dictionary of interfaces. The function relies on an external file read. Which TWO practices improve the testability and reliability of these unit tests? (Choose two.)

Select 2 answers
A.Place all test assertions inside a single test function to minimize the number of test cases
B.Write tests that depend on a live Cisco device reachable over SSH to fetch real configuration
C.Use time.sleep to wait for the file read to complete before asserting results
D.Use unittest.mock.patch to replace the file read with a mock that returns fixed configuration text
E.Use pytest.mark.parametrize to run the parser against multiple input strings and expected dictionaries
AnswersD, E

Patching the file read isolates the unit test from the actual filesystem, making tests fast, deterministic, and independent of external state. It allows the developer to supply controlled input strings that exercise specific parsing logic without creating real files, which is a core technique for reliable unit testing.

Why this answer

Mocking the file read with unittest.mock.patch and using pytest.mark.parametrize both improve testability: mocking removes external dependencies, and parametrization increases coverage with minimal code. Relying on live devices, merging assertions, or adding sleep delays all reduce reliability and speed, making them poor choices for unit tests.

Exam trap

The trap here is believing that testing against real infrastructure is more thorough, when in fact it makes unit tests slow and flaky, and that combining assertions reduces effort without harming diagnosability.

52
MCQmedium

A developer is building a Python function that must parse a JSON payload returned by a Cisco DNA Center API. The function needs to gracefully handle cases where the JSON is malformed or the response body is empty, without crashing the calling script. Which approach best meets this requirement?

A.Use eval() to interpret the response body, since eval() can parse both JSON and Python literals.
B.Check if the response body is empty and, if not, pass it directly to the rest of the application as a string.
C.Wrap json.loads() in a try/except json.JSONDecodeError block and return a default value or raise a custom exception when parsing fails.
D.Call json.loads() on the response body and let any exception propagate to the caller.
AnswerC

json.loads() raises json.JSONDecodeError for malformed input, and empty strings also trigger this exception. Catching it inside the function localizes the failure, allowing the function to return a safe default or a meaningful custom exception. This keeps the calling script stable and provides a clean contract for callers, directly meeting the graceful-handling requirement.

Why this answer

The function must isolate JSON parsing failures so the caller is not disrupted by malformed or empty responses. Catching json.JSONDecodeError around json.loads() and returning a default or raising a custom exception centralizes error handling and provides a predictable interface. The other choices either propagate exceptions, introduce security risks with eval(), or defer parsing without handling errors.

Exam trap

The trap here is assuming that any non-empty response body is valid JSON and that parsing errors should be handled by the caller rather than within the function.

53
Multi-Selecthard

A team is containerizing a Python API service so it can run identically on developer laptops and in production. Which TWO practices support reproducible, portable container images for this service? (Choose two.)

Select 2 answers
A.Pin the base image to a specific digest and declare exact dependency versions in a lock file installed during the build.
B.Bake environment-specific API tokens and database passwords into the image as build arguments so the container starts ready to use.
C.Inject environment-specific configuration and secrets at runtime through environment variables or a secrets manager rather than at build time.
D.Install dependencies from the public index without version constraints and rebuild the image on every deployment to pick up the latest packages.
E.Mount the developer's local source directory over the application path inside the production container to keep code current.
AnswersA, C

Pinning the base image by digest and locking dependency versions ensures every build resolves to the same layers and packages, so the image produced on a laptop matches the one built in CI. Without pinning, a silently updated base image or library can change behavior between environments, undermining reproducibility and making failures hard to trace.

Why this answer

Reproducibility requires that the same inputs always produce the same image, which means pinning the base image and locking dependencies. Portability requires that environment differences be supplied at runtime, not baked in, so one tested artifact can move from laptop to production unchanged. Together these practices make builds deterministic and keep secrets out of image layers.

Exam trap

The trap here is believing that using a Dockerfile alone guarantees consistency, when floating base images, unpinned dependencies, or build-time secrets each break reproducibility or portability.

54
MCQeasy

A developer writes a Python script to read a configuration file. Which code snippet correctly opens the file 'config.json' for reading and ensures the file is closed after use?

A.with open('config.json', 'r') as f:\n data = f.read()
B.open('config.json', 'r') as f:\n data = f.read()
C.with open('config.json', 'r') as f, data = f.read()
D.file = open('config.json', 'r')\ndata = file.read()\nfile.close()
AnswerA

The with statement opens config.json in read mode and guarantees closure via context-manager protocol, even if an exception occurs. This satisfies the stem's requirement that the file is closed after use, unlike manual open calls lacking explicit close.

Why this answer

It uses the `with` statement, which is a context manager that automatically calls `f.close()` when the block exits, ensuring the file is properly closed even if an exception occurs. The `'r'` mode opens the file for reading, and `f.read()` reads the entire contents into the `data` variable.

Exam trap

Cisco often tests the candidate's understanding of Python's context manager (`with` statement) versus manual file handling, expecting candidates to recognize that only the `with` statement guarantees automatic resource cleanup, while explicit `close()` calls are error-prone in the face of exceptions.

How to eliminate wrong answers

Option B is wrong because it uses `open('config.json', 'r') as f:` without the `with` statement, which is a syntax error in Python; the `as` clause is only valid inside a `with` statement. Option C is wrong because it uses a comma to separate the `with` statement and the assignment, which is invalid syntax; the correct syntax requires a colon and an indented block. Option D is wrong because while it does open the file and explicitly close it, it lacks the automatic cleanup provided by the `with` statement; if an exception occurs between `open()` and `file.close()`, the file may not be closed, leading to resource leaks.

55
MCQmedium

Which Python list comprehension correctly creates a list of squares for even numbers from 0 to 10?

A.[x**2 for x in range(11) if x % 2 == 0]
B.[x*2 for x in range(11) if x % 2 == 0]
C.[x**2 for x in range(10) if x % 2]
D.[x**2 for x in range(10) if x % 2 == 0]
AnswerA

The comprehension iterates x over range(11), covering 0 to 10 inclusive, and the filter x % 2 == 0 admits only even values before squaring with x**2. This satisfies both constraints in the stem: the even-number condition and the 0-to-10 bounds, producing 0, 4, 16, 36, 64, 100.

Why this answer

It uses list comprehension syntax with `x**2` to square each number, iterates over `range(11)` to include numbers 0 through 10, and applies the condition `if x % 2 == 0` to filter only even numbers. This produces the list `[0, 4, 16, 36, 64, 100]` as required.

Exam trap

Cisco often tests the subtle difference between `range(10)` and `range(11)` to see if candidates remember that `range(n)` generates numbers from 0 to n-1, and also tests the distinction between `x % 2` (odd filter) and `x % 2 == 0` (even filter).

How to eliminate wrong answers

Option B is wrong because it uses `x*2` (multiplication by 2) instead of `x**2` (squaring), so it creates a list of doubled even numbers, not squares. Option C is wrong because it uses `if x % 2` which evaluates to True for odd numbers (since odd numbers have remainder 1), thus filtering for odd numbers instead of even numbers, and also uses `range(10)` which excludes 10. Option D is wrong because it uses `range(10)` which generates numbers 0 through 9, missing the number 10, so the list will not include the square of 10 (100).

56
MCQmedium

A developer is building a REST API client in Python using the requests library. They need to send a JSON payload with authentication. Which code snippet correctly sends a POST request with a JSON body and a Bearer token?

A.requests.post(url, data=payload, auth=token)
B.requests.post(url, json=payload, headers={'Authorization': f'Bearer {token}'})
C.requests.post(url, data=json.dumps(payload), headers={'Authorization': token})
D.requests.post(url, params=payload, auth=('Bearer', token))
AnswerB

Passing json=payload serialises the dict and sets Content-Type to application/json automatically, while the headers dict supplies the Bearer token in the Authorization header. This satisfies both the JSON body and authenticated POST requirements in one call.

Why this answer

The correct way is to use json parameter for JSON body and headers for authorization.

57
MCQeasy

A developer is preparing to add a new feature to a shared Git repository. The team uses a workflow where each feature is developed on its own branch and then merged back into the main branch through a pull request. Which Git operation should the developer perform first to begin work on the new feature?

A.git merge main
B.git checkout -b feature/new-feature
C.git push origin main
D.git commit -m "start feature"
AnswerB

This command creates a new branch named feature/new-feature and immediately switches to it, giving the developer an isolated workspace. Subsequent commits land on that branch and can later be submitted as a pull request, matching the team's workflow.

Why this answer

Starting a feature requires an isolated branch so commits do not land directly on the shared main branch. Creating and switching to a new branch in one step provides that isolation and prepares the work for a later pull request. Committing, pushing main, or merging does not establish the new branch.

Exam trap

The trap here is thinking that a commit must happen before a branch is created, when branching should come first to keep the main line clean.

58
MCQeasy

A developer wants to process a list of server hostnames and create a new list containing only hostnames that start with 'web'. Which Python list comprehension correctly accomplishes this?

A.[hostname.startswith('web') for hostname in servers]
B.[hostname for hostname in servers if 'web' in hostname]
C.[hostname for hostname in servers if hostname.startswith('web')]
D.[hostname if hostname.startswith('web') for hostname in servers]
AnswerC

The comprehension filters with `hostname.startswith('web')`, returning only matching elements while preserving the original list's order. The `if` clause sits after the iteration expression, so each hostname is tested before inclusion — satisfying the stem's requirement to produce a new list containing solely hostnames beginning with 'web'.

Why this answer

The correct list comprehension is `[hostname for hostname in servers if hostname.startswith('web')]`. It iterates over `servers`, applies the condition `hostname.startswith('web')` as a filter, and includes only those hostnames in the new list. This matches the requirement to create a new list of hostnames starting with 'web'.

Exam trap

200-901 often tests the placement of the `if` clause in list comprehensions—candidates may mistakenly put the condition before the `for` (as in a conditional expression) or use `in` instead of `startswith`.

How to eliminate wrong answers

Option A is wrong because it produces a list of booleans (True/False) from `startswith`, not the hostnames themselves. Option B is wrong because it uses `'web' in hostname`, which matches any hostname containing 'web' anywhere, not just those starting with 'web'. Option D is wrong because it uses a conditional expression before the `for` clause, which is a syntax error in Python list comprehensions; the `if` filter must come after the `for`.

59
MCQmedium

A developer is preparing a Python application that reads the API base URL and an API token from the environment. The developer wants to avoid hard-coding credentials and intends to deploy the same artifact to a lab and a production environment. Which approach should be used?

A.Embed the base URL and token as default arguments in the Python function signatures so they are easy to find.
B.Prompt the user interactively for the base URL and token each time the application starts.
C.Read the base URL and token from environment variables at runtime, supplying different values per deployment environment.
D.Store the base URL and token in a configuration file that is committed to the Git repository, and read it at startup.
AnswerC

Environment variables keep secrets out of source control and let the same build artifact run in lab and production by injecting different values at deploy time. Python accesses them through os.environ or os.getenv, so no code change is needed between environments. This directly satisfies the goal of avoiding hard-coded credentials while keeping a single artifact.

Why this answer

Injecting configuration through environment variables separates code from environment-specific values and keeps secrets out of the repository. The same artifact can be promoted from lab to production because the base URL and token are supplied by the runtime platform, not compiled in. This is a standard twelve-factor configuration practice for cloud-native and containerized applications.

Exam trap

The trap here is assuming a private repository or a default function argument makes a credential safe, when any value stored in source or in the artifact is exposed to everyone who can read the code.

60
Multi-Selectmedium

Which TWO of the following are valid branching strategies in Git? (Choose two.)

Select 2 answers
A.Rebase-only
B.Merge avoidance
C.Feature branching
D.Direct commit to main
E.GitFlow
AnswersC, E

Feature branching isolates work for a single feature or task on a dedicated branch, keeping the mainline stable until the work is merged. This is a recognised Git workflow pattern, satisfying the question's requirement for a valid branching strategy.

Why this answer

Feature branching (C) is a valid Git branching strategy in which each new feature or user story is developed on its own dedicated branch (e.g., feature/login) and later integrated into the mainline via a pull/merge request, isolating work-in-progress from stable code. GitFlow (E) is a well-known branching model defined by Vincent Driessen that uses long-lived branches such as main/master and develop plus supporting branches (feature/*, release/*, hotfix/*) with defined merge rules between them. The other options are not recognized branching strategies: 'Rebase-only' (A) describes a history-rewriting integration technique rather than a branch topology, 'Merge avoidance' (B) is a general practice of minimizing merge commits, and 'Direct commit to main' (D) is the absence of a branching strategy, i.e., committing straight to the mainline.

Exam trap

Cisco often tests the distinction between Git operations (like rebase or merge) and actual branching strategies, so candidates mistakenly select 'Rebase-only' or 'Merge avoidance' as strategies when they are merely workflow tactics.

61
MCQmedium

A developer is writing a Python script that must process a large list of network device hostnames. The script needs to read each hostname, perform a blocking SSH operation, and then move to the next hostname. The developer wants to make the code more efficient by using a generator function to yield hostnames one at a time instead of loading the entire list into memory. Which Python construct should the developer use to define this generator?

A.def get_hostnames(hosts): return [h for h in hosts]
B.def get_hostnames(hosts): return (h for h in hosts)
C.class HostnameGenerator: def __init__(self, hosts): self.hosts = hosts def __iter__(self): return iter(self.hosts)
D.def get_hostnames(hosts): for h in hosts: yield h
AnswerD

Using a function that contains the yield keyword makes it a generator. When called, it returns a generator object that produces values lazily, one at a time, without building the full list in memory. This is ideal for large datasets and matches the requirement to process hostnames sequentially while keeping memory usage low.

Why this answer

A generator function is defined using the yield keyword inside a function. When called, it returns a generator object that produces values on demand, which is perfect for iterating over large datasets without loading everything into memory. The other options either create a full list or use a different construct that does not meet the requirement of a generator function.

Exam trap

The trap here is confusing a generator expression with a generator function, or assuming that any iterable is a generator.

62
MCQhard

A developer is designing a microservices-based network management system. One requirement is that when a new device is discovered, multiple other services must be notified asynchronously to perform tasks like inventory update, monitoring setup, and log collection. Which architectural pattern best fits this requirement?

A.Event-driven architecture
B.Model-View-Controller (MVC)
C.RESTful API
D.Monolithic architecture
AnswerA

Event-driven architecture decouples producers from consumers: the discovery service publishes a device-discovered event to a broker, and inventory, monitoring and logging services subscribe independently, each reacting asynchronously without the publisher waiting. This satisfies the stem's requirement that multiple services be notified asynchronously, and lets new subscribers be added without modifying the discovery service.

Why this answer

The event-driven architecture is correct because it enables asynchronous, decoupled communication between services. When a new device is discovered, an event (e.g., a message on a message broker like Kafka or RabbitMQ) is published, and multiple subscriber services (inventory, monitoring, logging) react independently without blocking the discovery service. This pattern directly supports the requirement for loose coupling and asynchronous notification.

Exam trap

Cisco often tests the distinction between synchronous (REST) and asynchronous (event-driven) communication patterns, and the trap here is assuming that RESTful APIs can be used for asynchronous notifications when they are inherently synchronous unless combined with additional mechanisms like webhooks or polling.

How to eliminate wrong answers

Option B (MVC) is wrong because it is a UI design pattern that separates an application into Model, View, and Controller components; it does not address inter-service asynchronous communication. Option C (RESTful API) is wrong because REST typically uses synchronous HTTP request-response calls, which would require the discovery service to wait for each notification to complete, violating the asynchronous requirement. Option D (Monolithic architecture) is wrong because it packages all functionality into a single deployable unit, which contradicts the microservices-based design and makes independent scaling and asynchronous notification difficult.

63
Multi-Selecthard

Which THREE of the following are characteristics of GraphQL compared to REST? (Choose three.)

Select 3 answers
A.Typically uses a single endpoint.
B.Strongly typed schema.
C.Client specifies exactly what data it needs.
D.Over-fetching of data is common.
E.Multiple endpoints for different resources.
AnswersA, B, C

GraphQL exposes one URL, usually `/graphql`, over which clients POST queries, mutations and subscriptions. This satisfies the stem's comparison with REST, where each resource maps to its own endpoint. A single endpoint lets clients request exactly the fields they need, avoiding REST's multiple round trips and over-fetching.

Why this answer

Option A is correct because GraphQL exposes a single endpoint (commonly /graphql) through which all queries and mutations are sent, unlike REST's resource-specific URLs. Option B is correct because GraphQL APIs are defined by a strongly typed schema using the Schema Definition Language, specifying types, fields, and operations that enable validation and introspection. Option C is correct because GraphQL clients send queries declaring precisely the fields they need, so the server returns exactly that shape of data.

Option D is not a GraphQL characteristic; over-fetching is a well-known REST problem that GraphQL is designed to avoid. Option E describes REST, where distinct endpoints map to different resources, whereas GraphQL uses one endpoint.

64
MCQhard

A developer is building a Python application that must handle configuration data in multiple formats (JSON, YAML, XML) and provide a consistent interface for reading and writing. The application may add new formats later. Which design pattern best supports this extensibility while keeping the client code decoupled from concrete implementations?

A.Singleton pattern with a global configuration manager
B.Observer pattern to notify components when configuration changes
C.Adapter pattern to convert each format to a common internal representation
D.Factory method pattern with an abstract parser interface
AnswerD

The factory method pattern defines an interface for creating objects, allowing subclasses to decide which concrete parser to instantiate. The client code depends only on the abstract parser interface, so new formats can be added by creating new factory subclasses without modifying existing client code, directly supporting extensibility and decoupling.

Why this answer

The factory method pattern is ideal because it encapsulates object creation, letting the client work with an abstract parser interface while subclasses or factory methods handle instantiation of concrete parsers for JSON, YAML, or XML. This decouples client code from specific formats and allows new formats to be added without changing existing code, satisfying extensibility.

Exam trap

The trap here is selecting a pattern based on superficial relevance, such as Adapter for format conversion, without considering which pattern actually decouples creation and supports adding new types.

65
MCQeasy

A developer is troubleshooting a Python function that parses device configuration returned by a REST API. The function receives a JSON string and must convert it into native Python dictionaries and lists before iterating over the device entries. Which standard-library approach performs that conversion?

A.Call json.load() on the response text to read the JSON content directly from the string variable.
B.Call json.loads() on the response text to transform the JSON string into Python dictionaries and lists.
C.Call str() on the response text so Python can interpret the JSON braces and brackets as native container syntax.
D.Call json.dumps() on the response text to transform the JSON string into Python dictionaries and lists.
AnswerB

json.loads() deserializes a JSON-formatted string into Python objects, mapping JSON objects to dicts and JSON arrays to lists. That gives the function native structures it can iterate directly, which is precisely the conversion described in the scenario.

Why this answer

The json module separates file-based and string-based operations. Deserializing in-memory API text requires json.loads(), which turns JSON text into dicts, lists, strings, numbers, booleans, and None. The serializing counterpart json.dumps() moves in the other direction, and json.load() requires a file-like object rather than a string.

Exam trap

The trap here is confusing the s-suffixed string functions with the file-oriented functions, or reversing serialization and deserialization.

66
MCQmedium

A developer is reviewing a colleague's pull request that adds a function to a shared Python utility module. The function must return the value of a REST API response, but the reviewer notices the function currently prints the parsed response instead of returning it. Which change makes the function usable by callers that need to process the data further?

A.Replace the print() call with a return statement that yields the parsed response object to the caller.
B.Keep the print() call and wrap the response in a global variable that other modules import directly.
C.Keep the print() call and add sys.stdout.flush() after it so downstream code can read the data.
D.Change print() to logging.info() so the response is captured by the logging framework and returned automatically.
AnswerA

A return statement hands the parsed object back to the calling code, which can then store, transform, or assert on it. Printing only writes to standard output and leaves the caller with None, so callers cannot process the data further, which is exactly what the scenario requires.

Why this answer

Functions that produce data for other code should return that data rather than emit it as a side effect. Printing, flushing, logging, or stashing values in globals all leave the function evaluating to None, so callers cannot chain or transform the result. Returning the parsed response object is what makes the function composable.

Exam trap

The trap here is believing that visible console output means the function produced a usable value, when output and return values are independent.

67
MCQmedium

A developer needs to read a JSON configuration file and parse it into a Python dictionary. The file contains nested objects. Which code snippet correctly accomplishes this?

A.with open('config.json', 'r') as f: data = json.loads(f)
B.data = json.loads(open('config.json', 'r').read())
C.with open('config.json', 'r') as f: data = json.load(f)
D.with open('config.json', 'r') as f: data = json.dumps(f.read())
AnswerC

json.load() deserialises a file object directly into Python dictionaries and lists, recursively handling nested objects. Reading with open() in text mode supplies the required stream, satisfying the stem's nested-JSON parsing requirement without manual string handling.

Why this answer

json.load() reads directly from a file object and deserializes the JSON content into a Python dictionary, which is exactly what is needed here. The 'with open(...)' context manager ensures the file is properly closed after reading. This combination handles nested objects natively because json.load() recursively parses the entire JSON structure.

Exam trap

The trap here is confusing json.load() (file object) with json.loads() (string), and json.dumps() (serialize) with json.loads() (deserialize) — the 's' and 'dump/load' directionality trips up candidates under time pressure.

How to eliminate wrong answers

Option A is wrong because json.loads() expects a string or bytes object, not a file object — passing a file handle raises a TypeError. Option B is functionally close but uses json.loads() on the raw string, which works, yet it lacks proper file handling (no context manager, relies on garbage collection to close the file) and is considered poor practice; the question asks for the correct snippet, and the idiomatic answer is C. Option D is wrong because json.dumps() serializes a Python object into a JSON string — it does the opposite of parsing, so 'data' would end up as a string, not a dictionary.

68
MCQeasy

In Python, which data type is used to represent an unordered collection of unique elements?

A.set
B.tuple
C.list
D.dict
AnswerA

A `set` stores an unordered collection of unique elements, automatically discarding duplicates on insertion. This directly satisfies the stem's two constraints: no defined ordering, and uniqueness of members. Hash-based storage gives average O(1) membership testing, unlike lists or tuples, which permit duplicates and preserve insertion order.

Why this answer

In Python, a set is the correct data type for representing an unordered collection of unique elements. Sets automatically enforce uniqueness by using a hash table internally, so duplicate values are ignored upon insertion. This makes them ideal for operations like membership testing and deduplication, where order is irrelevant.

Exam trap

The trap here is that candidates often confuse a set with a list or tuple because they think 'collection of items' implies order or mutability, but Cisco specifically tests the requirement for uniqueness and lack of order, which only the set satisfies.

How to eliminate wrong answers

Option B (tuple) is wrong because a tuple is an ordered, immutable collection that allows duplicate elements, not an unordered unique set. Option C (list) is wrong because a list is an ordered, mutable collection that permits duplicates and maintains insertion order. Option D (dict) is wrong because a dictionary stores key-value pairs with unique keys, but it is not a collection of elements; it maps keys to values and is unordered (in Python <3.7) or insertion-ordered (Python ≥3.7), not a simple set of unique items.

69
MCQeasy

In Python, which of the following is a valid way to define a function that accepts a variable number of positional arguments?

A.def func(args):
B.def func(args*):
C.def func(**kwargs):
D.def func(*args):
AnswerD

Prefixing a parameter with an asterisk, as in *args, collects any number of extra positional arguments into a tuple named args. This is Python's defined syntax for variadic positional parameters, distinct from **kwargs, which gathers keyword arguments into a dictionary.

Why this answer

In Python, the `*args` syntax in a function definition allows the function to accept a variable number of positional arguments. The asterisk (`*`) collects all extra positional arguments into a tuple named `args`, enabling flexible argument handling.

Exam trap

Cisco often tests the distinction between `*args` (positional) and `**kwargs` (keyword) and may include syntactically invalid options like `args*` to catch candidates who misremember the asterisk placement.

How to eliminate wrong answers

Option A is wrong because `def func(args):` defines a function that accepts exactly one positional argument named `args`, not a variable number. Option B is wrong because `def func(args*):` is invalid Python syntax; the asterisk must precede the parameter name (i.e., `*args`), not follow it. Option C is wrong because `def func(**kwargs):` accepts a variable number of keyword arguments (collected into a dictionary), not positional arguments.

70
MCQmedium

A developer is refactoring a Python module that currently has a single 400-line function named process_orders(). The function mixes validation, database writes, and email notification logic. The team wants to improve testability and reuse. Which software design approach should be applied first?

A.Extract the validation, persistence, and notification logic into separate functions or classes, each with a single responsibility.
B.Convert the module to use global variables so that validation, database, and email code can share state.
C.Wrap the entire function body in a try/except block and log every exception to a file.
D.Increase the function's indentation and add inline comments before each block of logic.
AnswerA

Splitting the monolithic function along its distinct responsibilities yields smaller units that can be unit tested in isolation and reused by other callers. This directly supports testability and reuse, which are the stated goals, without changing the external behavior of the module.

Why this answer

The core problem is that one function owns three unrelated responsibilities. Separating validation, persistence, and notification into focused units makes each behavior individually testable and reusable by other parts of the application. The other choices either preserve the monolith, add shared mutable state, or only improve readability without changing structure.

Exam trap

The trap here is assuming that adding logging or comments to a large function makes it testable, when testability actually requires separating its distinct responsibilities.

71
MCQeasy

When using the requests library in Python to send a POST request, which parameter should be used to send a JSON payload in the request body?

A.params=payload
B.files=payload
C.json=payload
D.data=json.dumps(payload)
AnswerC

The json= parameter serialises the Python dictionary to JSON and sets the Content-Type header to application/json automatically, placing the payload in the request body. Passing data= would form-encode it instead, so json= satisfies the JSON body requirement.

Why this answer

The json= parameter automatically serializes the Python dictionary to JSON and sets the Content-Type header to application/json.

72
MCQeasy

Which HTTP status code indicates a successful POST request that created a resource?

A.200 OK
B.400 Bad Request
C.201 Created
D.204 No Content
AnswerC

201 Created signals that the POST succeeded and a new resource now exists, satisfying the stem's requirement for a creation-specific response. Unlike 200 OK, which merely confirms general success, 201 explicitly reports resource creation and typically returns a Location header pointing to the new resource's URI.

Why this answer

201 Created is the standard response for a successful POST that creates a new resource.

73
MCQmedium

A developer is building a Python script that processes a list of network devices. Each device is represented as a dictionary with keys 'hostname' and 'ip'. The script must create a new list containing only the hostnames of devices whose IP address starts with '10.'. Which Python construct best accomplishes this in a single expression?

A.A generator expression that yields all hostnames.
B.A for loop that appends to a new list.
C.A while loop with an index counter.
D.A list comprehension with a conditional filter.
AnswerD

A list comprehension with a conditional filter, such as [d['hostname'] for d in devices if d['ip'].startswith('10.')], directly produces the desired list in one readable expression. It iterates over the devices, applies the condition, and collects only the matching hostnames, avoiding the need for an explicit loop and append calls.

Why this answer

A list comprehension with a conditional filter is the most concise and Pythonic way to transform and filter a list in a single expression. It combines iteration, condition, and result construction, directly producing the required list of hostnames for devices whose IP starts with '10.'.

Exam trap

The trap here is assuming that any loop that produces the correct output is equally valid, ignoring the explicit requirement for a single expression.

74
MCQmedium

Which Git command is used to create a new branch and switch to it in one step?

A.git branch <branch>
B.git branch -d <branch>
C.git checkout <branch>
D.git checkout -b <branch>
AnswerD

The -b flag instructs git checkout to create the named branch before switching to it, combining branch creation and checkout in a single command. Without -b, checkout only switches to an existing branch, so this satisfies the one-step requirement in the stem.

Why this answer

The 'git checkout -b <branch>' command creates a new branch and switches to it immediately.

75
MCQmedium

A developer is working on a Git repository and needs to temporarily save changes that are not ready to be committed, switch to another branch to fix a bug, and then return to the original branch and reapply the saved changes. Which Git command should be used to accomplish this?

A.git checkout -- .
B.git branch --set-upstream-to
C.git commit -m "WIP"
D.git stash
AnswerD

git stash temporarily shelves changes in the working directory, allowing the developer to switch branches without committing. After fixing the bug, git stash pop or git stash apply restores the changes. This is the standard way to handle unfinished work when an urgent branch switch is needed.

Why this answer

git stash is designed to temporarily save uncommitted changes, allowing a clean working directory to switch branches. After handling the urgent bug fix, the developer can return and reapply the stashed changes. The other options either commit, discard, or misconfigure branches, none of which preserve work-in-progress.

Exam trap

The trap here is confusing temporary storage with committing or discarding changes, leading to data loss or unwanted commits.

Page 1 of 2 · 97 questions totalNext →

Ready to test yourself?

Try a timed practice session using only Software Development and Design questions.