1/84
Looks like no tags are added yet.
Name | Mastery | Learn | Test | Matching | Spaced |
---|
No study sessions yet.
What is the waterfall process?
Requirements
Collect all the requirements for a system and write a comprehensive specification document
Design
Consume specification document and design the system and come up with all components, classes, methods, etc.
Implementation
Use the design documents to actually implement the design in code
Verification
Looks at the specifications to come up with a test plan to make sure that the implementation is correct
Maintenance
Evolves the system over time.
Each step needs to be fully completed before going to the next step.
What is the spiral process?
Planning
Here, we figure out what the requirements for this iteration are going to be
Risk analysis
Here, we figure out what the risks are within this iteration of the prototype
Engineering
We implement the software system
Validation
Check with the customer to make sure that the prototype is going in the right direction
After validating, we go back into the planning step to plan the next iteration of the system.
What is the AGILE manifesto?
12 key points, but 4 of them are very important:
Favor individual interaction over processes and tools (valuing the stakeholders involved in the software development process)
Favor working software over extensive documentation (software should always be buildable and executable)
Customer interactions over contract negotiations (bring the customer into the development team to respond to them quickly and effectively)
Agility over planning (be more flexible by using feedback from customers to quickly build a more fitting version)
What is extreme programming (XP)?
XP is one of the first AGILE development methodologies. Here, the main goal is to have a buildable system at all times. XP follows 5 key principles:
Communication
Encourage various stakeholders to talk to each other
Simplicity
Favor simple solutions to try it with the customers. If it works, then no more complicated solution is needed
Feedback
Encourage customer and developer to talk to each other to make sure that the developer can implement the feedback, or push back on it if it isn’t going to work
Courage
Try out experiments to see if they make the product better. If they don’t, we throw them away (opportunity to learn about the system and make it better)
Respect
Respect all stakeholders opinions and their time
What is Test Driven Development (TDD)?
We first build our automated unit tests based on the specification and then implement the system. This way, the tests should always pass.
What roles exist within the SCRUM methodology?
Product owner: Proxy for the client or the client themselves. They prioritize issues that are being worked on in the sprint and evaluate the team’s output to make sure it matches their expectations.
SCRUM master: Manage the development process (not the manager of the team but the manager of the process).
Team: 5 to 7 people spanning a variety of disciplines (e.g. developers, QA, ops). They work together to build a product.
What is the process in SCRUM?
Product backlog: All issues assigned to a development team.
Planning: Go through the product backlog to figure out which issues we will tackle in an individual sprint.
Sprint: 1 or 2 week long implementation phase, where we implement prioritized issues. At the end of the sprint, the product needs to be shippable.
Stand-up meeting: Every developer talks about what they worked on last, what’s blocking them currently, and what they are working on next. The SCRUM master makes sure that everyone delivered what they said they would on the day before.
What are functional requirements?
Functional requirements capture what it is that the system should do (e.g. user should be able to log out with a single click).
What are non-functional requirements?
Properties that the system should have (e.g. System should be usable, performant, scalable, etc).
What are the four requirements properties?
-Complete: Provide all requirements.
-Consistent: Requirements shouldn‘t contradict each other.
-Precise: Requirements should be precise.
-Concise: Each requirement should be as concise as possible.
What does the process of elicitation look like?
Elicitation < - > Analysis - > Reification - > Validation - > Elicitation
What are design constraints?
E.g. regulatory constraints that influence the tools that have to be used during development.
What are environmental constraints?
E.g. the software you are building needs to work with a specific authentication provide, or a cloud, etc.
What are preferences?
Preferences tell the developer which requirements are most important to the customer.
How can developers validate requirements?
E.g. performance: We can look at the time it takes for the system to execute a task, how much space it uses, how fast it responds to a customer, how much throughput it can handle, etc.
What are user stories?
User stories have 5 main parts:
Role-Goal-Benefit
Who will benefit? What are they trying to achieve? Why do they want to achieve that?
Limitations
Scope down the Role-Goal-Benefit to the subset of situations that matter for this feature.
Definition of Done
How do we evaluate that the feature is complete?
Engineering Tasks
How does this feature interact with other features in the system?
Effort estimate
Overall cost of a feature (time it takes to implement).
What are INVEST guidelines?
I. Independent: All user stories should be independent from each other as much as possible.
N. Negotiable: Extra detail is added to the user stories as needed.
V. Valueable: Make sure the user stories actually provide a value for the user.
E. Estimable: We should be able to provide an estimate for the development time of the feature.
S. Small: User stories should be as small as possible help drive the other guidelines.
T. Testable: The feature should be testable in order to ensure both developer and customer agree.
What is encapsulation?
This is the idea of designing self-contained abstractions with well-defined interfaces that separate different concerns in a program. Programming languages offer encapsulation support through things like functions, classes or scoping.
What is abstraction?
By abstracting a problem, specific groups of people can focus on a subset of the problems. Here is an example:
We are given the task to create videos for a course.
Choose topic
Develop material
Go to studio
Record
Reshoot
Post production
Post videos
A professor would only be interested in steps 1-5, the recording studio only cares about steps 3-5, and the producer only looks at steps 3-7.
What is information hiding?
Information hiding improves a software’s architecture by hiding information from certain parts of the program. E.g. a front-end developer doesn’t need to care how the back-end does stuff, he just needs to make the API call to it.
What is decomposition?
We can decompose a task into multiple subsets of smaller tasks to make development easier.
What is the difference between top-down decomposition and bottom-up decomposition?
Top-down decomposition: Here, we start from an overarching concept, like a game. We can split this up into levels and figures. Figures can be split up into player and enemies, etc.
Bottom-up decomposition: Here, we start from a lower lever and work our way to the top. Let’s say, a company made a tool that removes the background from a picture to only focus on the text. Google might buy that tool and incorporate it into their translation tool to enable better translations from pictures.
What kind of UML diagrams exist?
Structural diagrams:
-Class diagrams
-Deployment diagrams
Behavioral diagrams:
-Sequence diagrams
-State machine diagrams
What characteristics should diagrams have?
Concrete: Diagrams should give us information that would otherwise be somewhat hidden in a specification.
Not ambiguous: Diagrams should only be interpreted in one way.
Accurate: Diagrams should be correct within a given tolerance, making it easier for a developer to build a given system.
Precise: Diagrams should be precise when representing the workings of a system.
What do deployment diagrams do?
Deployment diagrams show where the different parts of a program exist and run at runtime (e.g. does it run in the browser, does the website communicate with an external server, etc.).
What does the bi-directional association in this image mean?
An instance of a Flight can have 0 or 1 instances of Plane assigned to it.
An instance of a Plane can be assigned to 0 or more instances of Flight.
What is an aggregation?
Basic aggregation (Aggregation): Children outlive their parents.
Composite aggregation (Composition): Children life depends on parent.
What is the process when decomposing user stories?
What is an Application Programming Interface (API)?
An API is an interface that can be used by developers. APIs can provide different kinds of services, like getting information to movies (IMDb API), photos from the streets (Google Street View API), etc.
What is technical debt?
Technical debt is the debt that is accumulated in the future if a software system is implemented in a poor fashion, such that it is hard to maintain, not easily scalable, etc.
How should APIs be designed?
APIs should be designed such that utility is maximized while technical debt.
What is high level API design?
There are guidelines to high level API design. To demonstrate, we will transform the following function from an API: getPaidUserAndSortByName().
-The API should do one thing and do it well (→ getUser(isPaid: boolean, sortIndex: number)).
-Never expose internal implementation details (getUsers(isPaid: boolean, key: Users.key).
-The API should be as small as possible (getUsers(isPaid: boolean).
-Consider API usability by adding information, e.g. the return type (getUsers(isPaid: boolean): Users[]).
What is low level API design?
There are guidelines to low level API design.
-Avoid long parameter lists (addUser(lastName: String, firstName: String, initial: String, username: String, email: String → addUser(user: User)).
-Return descriptive objects (getUserData(): String (returns “firstName, lastName, intitial, username, email) → getUserData(): User).
-Avoid exceptional returns (getUsers(): User[] | null → instead of returning null, return an empty list).
-Handle exceptional circumstances (throw new MyInternalError({message: “Internal error”}) → throw new Error({Code: 215, message: “Bad Auth parameter”, info: “https://dev.foo.com/e/215})).
-Favor immutability (If we return an object to a client through our API, any further changes that we make are reflected in the client’s object. On the other hand, if the client changes the object, our original implementation shouldn’t change).
-Favor private classes, fields, and methods
What questions are typically asked while designing an API?
-What is the goal of this API? This drives decisions about programming languages, protocols, platforms, and data formats.
-Who is the API for? This drives decisions about versioning, and licensing and authentication.
What does the API design process look like?
The API design process typically consists of 4 steps:
-Start with short specification.
-Solicit feedback (make sure our API fulfills the needs of clients).
-Create concrete prototypes (test the API with clients).
-Build documentation.
What are the key aspects in API usability?
-Visibility (make it easy for a developer to look at our API and understand what it does) (items.sort(“clearance”) → items.sort(Filter.CLEARANCE)).
-Model (Provide descriptive names for the developer to understand the API) (store.get(pid: String) → store.getProduct(pid: String)).
-Mapping (store.getProduct(pid: String): any → store.getProduct(pid: String): Product).
-Feedback (items.sort(“clearamce”) → throws an error, since “clearamce” doesn’t exist).
What is Representational State Transfer (REST)?
With REST, we can simply request information from a remote server, and the server then returns a response. REST interfaces are simple, reliable, scalable, and extensible.
What are Uniform Resource Identifiers (URIs)?
URIs are used to specify the resource we want to access on a REST-based remote server. URLs are a subset of all possible URIs.
What are the standard access services in REST?
GET, POST, PUT, DELETE.
What is statelessness?
A client is responsible for its own state as it proceeds to communicate with a REST-based remote server (e.g. Client can’t ask “What is the next item”, instead, the client knows that the next item is the ninth and thus asks “What is the ninth item?”.
What is connectedness?
REST APIs should provide links in responses (HATEOAS) allowing clients to discover related resources. This makes the API navigable and less reliant on hardcoded URLs.
What is versioning and how can it be implemented?
Versioning describes the process of creating different versions of an API. It can be implemented in the following ways:
-Path: GET /v2/users
-Query: GET /users/?v=2
-Header: APIVersion: 2
What is authentication and analytics?
We force users to authenticate if we have a usage limit that we want to impose. This can be done with HTTPS, OAuth, etc.
How are access modifiers depicted in class diagrams?
+: public
-: private
#: protected
~: package local
What are design principles?
Design principles are high level guidelines that can help ensure our designs are robust in the face of defect fixes and feature additions.
What is coupling?
Coupling is a property that indicates the strength of connections between different program elements.
Is strong coupling good or bad? Why?
Strong coupling is problematic because it negatively influences the evolvability and maintainability of a program. There are several reasons:
Coupled code makes it easier for errors in one part of the system to propagate to other unrelated parts of the system.
Coupling increases the degree to which a single bug fix or feature addition is scattered across the codebase.
Code that is tightly coupled is much harder to reuse independently than code which is loosely coupled.
It is harder to understand a source code element that is coupled to other elements because individual elements cannot be considered (and understood) in isolation.
What are ways to reduce coupling between program elements?
There are three primary ways to decrease the coupling between program elements:
Minimize the number of interfaces between elements: The more interfaces two program elements need to share, the more tightly they are coupled to each other.
Minimize the complexity of interfaces: Since some coupling is often needed, reducing the complexity of this coupling to its core elements can make the interaction between the program elements clearer and easier to reason about and evolve.
Avoid control flow coupling: It can often be convenient to pass objects that control the flow of computation within another element. While this is ok if the element being passed is some type of data structure, it can be more problematic if the control flow is being influenced by simple control flow flags (e.g., some kind of boolean
flag that takes one program path over another).
What types of coupling exist, and which is the worst?
What is cohesion?
Cohesion is a property that indicates how focused our program elements are on performing a single complete task. Classes with low cohesion are responsible for a wide variety of tasks; these classes are harder to reason about, as they often have many competing concerns within their implementation that might conflict.
What kinds of cohesion exist?
What are SOLID design principles?
-S. Single responsibility: A software module should do one thing and do it well.
-O. Open/closed: Open to extension but closed to modification.
-L. Liskov substitution: Any object can be interchanged with any other object that has the same parent type.
-I. Interface segregation: Clients should not be forced to depend on interfaces they do not use.
-D. Dependency inversion: Classes should depend on abstractions, not implementations.
What are some design symptoms?
-Rigidity: A system that is resistant to change has a rigid design.
-Fragility: A design that is easy to break.
-Immobility: Code that cannot be used somewhere else because it is very tightly coupled with other dependencies.
-Viscosity: Software with viscous designs make it easier to violate the designs than adhere to it.
-Needless complexity: Unneeded abstractions could make a system needlessly complex.
-Repetition: If the same code appears multiple times throughout the program, it increases the probability of introducing bugs. If one of these instances is bugged, all the others are as well, meaning each copy has to be fixed.
-Opacity: Systems typically become harder to understand (more opaque) over time.
What are strategy, command and state patterns?
Strategy pattern: In this pattern, modules encapsulate algorithms; this means we create modules that only implement a specific algorithm.
Command pattern: This pattern separates the notion of an action that can be performed from its implementation. This results in small modules that only provide the features needed for a specific action.
State pattern: Systems often depend differently according to their internal state. Rather than having large modules that need to reason globally about all states, this pattern encapsulates the behaviours for a single state in a single module resulting in smaller, more targetted code.
What is low level design?
In low level design, we think more about how our high level designs would actually be implemented by developers with code.
What are the three guidelines for low level design?
Encapsulate what varies
Design the system in such a way, so that it can be easily extended in the future, and bugs are easy to resolve in semi-localizable spaces.
Ensure we are programming to interfaces
Helps to decouple our implementation from our design. This way, we can reuse parts of our system without worrying about the implementation.
Favor composition over inheritance
This makes our code more dynamic at runtime, and it makes it easier to add new features as design goes on.
What is the Model View Controller (MVC) pattern?
It tries to separate the view of its application from its implementation. Usually, the view is changed more frequently than the implementation, so it makes it easier to change the view independently of the system. Splitting the Frontend from the Backend is very useful, since often, the people owning the frontend are completely different from the people owning the backend. Testing is also made easier, since testing the frontend is different from testing the backend.
What are the main components of MVC?
Model
Contains all the data within our application
Doesn’t know how to render itself
Reusable across different applications, since it’s domain independent
View
Knows how to render the model’s objects, so the user can see them
Controller
Tightly bound to the view that it is associated with
Responds to changes in the view and updates the model accordingly
What is Model View Presenter (MVP)?
Modernization on MVC, that tries to enhance the testability of your system. This is done by decreasing the amount of code that can be within your views and forcing the presenters (controllers in MVC) to be more feature-full.
What are the components of MVP?
Model
Basically the same as in MVC
Presenter
Just like the controller in MVC
Make sure they don’t have any dependencies on user interface components, in order to ensure easy testability
View
The view isn’t coupled to the model at all
Presenter acts as a mediator (updates and receives state from the model)
Presenter only sends primitive types to the view (Strings, ints, etc.), no model objects
What is Model View View Model (MVVM)?
A specialization of MPV, where the view and presenter are more tightly bound
What categories of design patterns exist?
Creational
Help us to build objects in an extensible way
Structural
Help us to structure our systems in ways to avoid future evolutionary problems
Behavioral
Makes it easier to add new behaviors at runtime.
What is the decorator pattern?
It allows us to add arbitrary combinations of behaviors to individual instances of objects, rather than adding them to every instance of a class.
What is the singleton design pattern?
We have an object that we want to use widely throughout our system, but we don’t want to pass instances of this object to every part we want to use it in. Maybe we even want only a single instance of an object.
What is the strategy design pattern?
Makes it so that we can easily extend our system with new features while not modifying our existing implementations.
What is the state design pattern?
We often want to vary the behavior of our program based on the internal state within our program.
What is the intent of the Composite Design Pattern?
To compose objects into tree structures representing whole-part hierarchies, allowing clients to treat individual objects and compositions uniformly.
What problem does the Composite Design Pattern solve?
The need to manipulate a hierarchical collection of primitive and composite objects without having to query the type of each object before processing it.
What is the core structure of the Composite Design Pattern?
Composites that contain Components, where each Component can be either a primitive object (Leaf) or another Composite.
Explain the concept of "uniform treatment" in the context of the Composite Design Pattern.
Clients can interact with both individual (primitive) objects and compositions of objects through a common interface defined by the abstract Component class.
What is the intent of the Observer Design Pattern?
To define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.
What problem does the Observer Design Pattern address?
A large monolithic design that doesn't scale well with new requirements for displaying or monitoring data. It helps decouple the core logic from the presentation or monitoring logic.
Describe the basic structure of the Observer Design Pattern.
It involves a Subject (which maintains the state) and multiple Observers (which are interested in the Subject's state). Observers register with the Subject to receive notifications.
What is the intent of the Abstract Factory Design Pattern?
To provide an interface for creating families of related or dependent objects without specifying their concrete classes.
What problem does the Abstract Factory Design Pattern solve?
The need to create portable applications that can work across multiple platforms (e.g., different operating systems or windowing systems) by encapsulating platform dependencies and avoiding a proliferation of conditional statements.
Describe the basic structure of the Abstract Factory Design Pattern.
It involves an Abstract Factory interface that declares methods for creating abstract products. Concrete Factories implement this interface to produce concrete product families for specific platforms. Clients use the abstract factory interface to create products without knowing their concrete types.
What are defects, failures, and bugs?
Defects: A subset of a program’s code that exhibits behaviour violating the program’s specifications. If the program is supposed to sort a list by ascending order, but in actuality, it sorts the list in descending order due to a flipped inequality, the flipped inequality is the defect.
Failures: The program behavior that results from a defect executing. In our sorting example, the failure is the incorrectly sorted list printed on the console.
Bugs: Vaguely refers to either the defect, the failure, or both. When we say "bug", we're not being very precise, but it is a popular shorthand for a defect and everything it causes.
What are unit tests, integration tests, and regression tests?
Unit tests verify that functions return the correct output. For example, a program that implemented a function for finding the day of the week for a given date might also include unit tests that verify for a large number of dates that the correct day of the week is returned. They're good for ensuring widely used low-level functionality is correct.
Integration tests verify that when all of the functionality of a program is put together into the final product, it behaves according to specifications. Integration tests often operate at the level of user interfaces, clicking buttons, entering text, submitting forms, and verifying that the expected feedback always occurs. Integration tests are good for ensuring that important tasks that users will perform are correct.
Regression tests verify that behavior that previously worked doesn't stop working. For example, imagine you find a defect that causes logins to fail; you might write a test that verifies that this cause of login failure does not occur, in case someone breaks the same functionality again, even for a different reason. Regression tests are good for ensuring that you don't break things when you make changes to your application.
What are the step sin testing software?
Choose what we are testing. Which parts of the system are the most important to test?
Create test cases. What tests need to be created?
Execute tests. Should the developer run the tests before committing. Should the tests be run on a server after committing?
Examine results. How many passed, how many failed? Which failed?
Evaluate testing process. Have we tested our system well enough to give us the confidence to actually ship our product?
What is white box and black box testing?
White box testing: We “open the hood” and look at the internals to see whether everything looks right.
Black box testing: We can run the system, without looking at the internals, to see whether everything works as expected.
What does CUT and SUT stand for?
Code Under Test / System Under Test. This is the code that a set of test cases or an individual test case is evaluating.
What characteristics should our test cases have?
Fast: They should be fast.
Reliable: The results should be reliable. If a test fails, it should actually mean that there is a defect in the code.
Isolate failures: A test case should help ups quickly pinpoint where in the code the failure arises.
Simulate users: The test cases should be based on real user interaction with the system.
What are acceptance tests?
Here, the user tests out the system they just bought in order to see if everything works as expected.
What is Red-Green Refactor?
We write a test and make sure it actually fails (before writing the implementation).
We write the implementation and make sure that the test passes in the end.
Refactor and Extend the test and the passing code.
What high-level categories of coverage exist?
Flow independent: Cheap to compute and easy to reason about.
Block coverage: Measures the proportion of blocks in the system that are executed by the test suite.
Line coverage: Measures the proportion of lines in the system that are executed by the test suite.
Statement coverage: Measures the proportion of statements that are executed by the test suite (similar to line coverage, but there can be multiple statements on the same line, e.g. in a looping condition).
Flow dependent: Ensuring pieces of code can execute together. Expensive to compute and hard to reason about.
Branch coverage: Ensures that we’ve executed both halves of every branching statement (e.g. if-else block).
Path coverage: Ensures that we’ve executed all paths in the system. If we have two if statements (once true, once false), we don’t just execute each separately, but also both at the same time.
Multiple condition coverage (MCC): Ensures that all statements are independently evaluated with respect to the outcome of a function.