Common Terms Flashcards
STL
Standard Template Library
The Standard Template Library (STL) is a set of C++ template classes to provide common programming data structures and functions such as lists, stacks, arrays, etc.
STL has 4 components: Algorithms Containers Functions Iterators
8 data structure types
sets, bags (or multisets), sequential lists, ordered lists (with ordering from a “less than” operator), stacks, queues (priority queues), tables, and graphs.
Container Classes
a data type that is capable of holding a collection of items.
In C++, container classes can be implemented as a class, along with member functions to add, remove, and examine items.
Classes
An extensible (extended) program-code-template for creating objects, providing initial values for state (member variables) and implementations of behavior (member functions or methods)
Pointer
a pointer is a variable that holds (points to) an address in the computer’s memory
Dynamic memory
Dynamic memory allocation refers to managing system memory at runtime.
There are really three kinds of memory in most computer languages:
Static: The memory is allocated when the program is loaded - and never changes.
Local: The memory is allocated on the stack when a function is called that declares them - and is destroyed and freed up when the function exits.
Dynamic: Memory is allocated on demand, under the control of the programmer. It exists as long as you need it and is either destroyed sometime after nothing still refers to it - or explicitly when you free it up - depending on the programming language you use.
Dynamic memory management in C programming language is performed via a group four functions named malloc(), calloc(), realloc(), and free().
These four dynamic memory allocation functions of the C programming language are defined in the C standard library header file .
Dynamic memory allocation uses the heap space of the system memory
4 Pillars of OOP
Abstraction
Encapsulation
Inheritance
Polymorphism
Abstraction
To abstract something away means to hide away the implementation details inside something – sometimes a prototype, sometimes a function.
How to Create it With Abstraction
Have a button with the title “Make coffee”
How to Create it Without Abstraction
Have a button with the title “Boil the water”
Have a button with the title “Add the cold water to the kettle”
Have a button with the title “Add 1 spoon of ground coffee to a clean cup”
Have a button with the title “Clean any dirty cups”
And all the other buttons
first approach abstracts away the logic into the machine. But the second approach forces the user to understand how to make coffee and essentially make their own.
Encapsulation The definition of encapsulation is "the action of enclosing something in or as if in a capsule". Removing access to parts of your code and making things private is exactly what Encapsulation is all about (often times, people refer to it as data hiding). // Private var breed = "Dalmatian"
// Public var name = "Rex";
Inheritance
Inheritance lets one object acquire the properties and methods of another object.
Developers have a principle called the Liskov Substitution principle. It states that if you can use a parent class (let’s call it ParentType) anywhere you use a child (let’s call it ChildType) – and ChildType inherits from the ParentType – then you pass the test.
The main reason you would fail this test, is if the ChildType is removing things from the parent. If ChildType removed methods it inherited from the parent, it’d lead to TypeError’s where things are undefined that you are expecting not to be.
Polymorphism
Polymorphism means “the condition of occurring in several different forms.”
If you have used inheritance correctly you can now reliably use parents like their children. When two types share an inheritance chain, they can be used interchangeably with no errors or assertions in your code.
// Let's set up an Animal and Dog example function Animal(){} function Dog(){}
Animal.prototype.makeNoise = function(){
console.log(“Base noise”);
};
// Most animals we code up have 4. This can be overridden if needed Animal.prototype.legs = 4;
Dog.prototype = new Animal();
Dog.prototype.makeNoise = function(){
console.log(“Woof woof”);
};
var animal = new Animal(); var dog = new Dog();
animal.makeNoise(); // Base noise
dog.makeNoise(); // Woof woof- this was overridden
dog.legs; // 4! This was inherited
Dog extends from Animal and can make use of the default legs property. But it’s also able to do its own implementation of making its own noise.
The real power of polymorphism is sharing behaviours, and allowing custom overrides.
OOP (Object Oriented Programming)
is a computer programming model that organizes software design around data or objects, rather than functions and logic.
SOLID Principles are five principles of Object-Oriented class design.
The Single Responsibility Principle The Open-Closed Principle The Liskov Substitution Principle The Interface Segregation Principle The Dependency Inversion Principle https://www.freecodecamp.org/news/solid-principles-explained-in-plain-english/
The Single Responsibility Principle The Single Responsibility Principle states that a class should do one thing and therefore it should have only a single reason to change. We can create new classes for our printing and persistence logic so we will no longer need to modify the invoice class for those purposes. We create 2 classes, InvoicePrinter and InvoicePersistence, and move the methods.
The Open-Closed Principle
The Open-Closed Principle requires that classes should be open for extension and closed to modification.
Modification means changing the code of an existing class, and extension means adding new functionality.
This is because whenever we modify the existing code, we are taking the risk of creating potential bugs.
public class InvoicePersistence {
Invoice invoice;
public InvoicePersistence(Invoice invoice) { this.invoice = invoice; }
public void saveToFile(String filename) { // Creates a file with given name and writes the invoice }
public void saveToDatabase() { // Saves the invoice to database } } Now our persistence logic is easily extendable. If our boss asks us to add another database and have 2 different types of databases like MySQL and MongoDB, we can easily do that.
You may think that we could just create multiple classes without an interface and add a save method to all of them.
But let’s say that we extend our app and have multiple persistence classes like InvoicePersistence, BookPersistence and we create a PersistenceManager class that manages all persistence classes:
public class PersistenceManager {
InvoicePersistence invoicePersistence;
BookPersistence bookPersistence;
public PersistenceManager(InvoicePersistence invoicePersistence, BookPersistence bookPersistence) { this.invoicePersistence = invoicePersistence; this.bookPersistence = bookPersistence; } }
The Liskov Substitution Principle
The Liskov Substitution Principle states that subclasses should be substitutable for their base classes.
This means that, given that class B is a subclass of class A, we should be able to pass an object of class B to any method that expects an object of class A and the method should not give any weird output in that case.
The Interface Segregation Principle
Segregation means keeping things separated, and the Interface Segregation Principle is about separating the interfaces.
The principle states that many client-specific interfaces are better than one general-purpose interface. Clients should not be forced to implement a function they do no need.
public interface ParkingLot {
void parkCar(); // Decrease empty spot count by 1 void unparkCar(); // Increase empty spots by 1 void getCapacity(); // Returns car capacity double calculateFee(Car car); // Returns the price based on number of hours void doPayment(Car car); }
class Car {
} We modeled a very simplified parking lot. It is the type of parking lot where you pay an hourly fee. Now consider that we want to implement a parking lot that is free. public class FreeParking implements ParkingLot {
@Override public void parkCar() { } @Override public void unparkCar() { } @Override public void getCapacity() { } @Override public double calculateFee(Car car) { return 0; }
@Override public void doPayment(Car car) { throw new Exception("Parking lot is free"); } } Our parking lot interface was composed of 2 things: Parking related logic (park car, unpark car, get capacity) and payment related logic.
But it is too specific. Because of that, our FreeParking class was forced to implement payment-related methods that are irrelevant. Let’s separate or segregate the interfaces.
HourlyFeeParkingLot>PaidParkingLot>ParkingLot
ConstantFeeParkingLot>PaidParkingLot>
FreeParkingLot>ParkingLot
The Dependency Inversion Principle
The Dependency Inversion principle states that our classes should depend upon interfaces or abstract classes instead of concrete classes and functions.
In his article (2000), Uncle Bob summarizes this principle as follows:
“If the OCP states the goal of OO architecture, the DIP states the primary mechanism”.
These two principles are indeed related and we have applied this pattern before while we were discussing the Open-Closed Principle.
We want our classes to be open to extension, so we have reorganized our dependencies to depend on interfaces instead of concrete classes. Our PersistenceManager class depends on InvoicePersistence instead of the classes that implement that interface.
A concrete class
a concrete class is a class that can be instantiated or created as an object.
It is a class that is not abstract and can be used to create objects with a specific set of attributes and behaviors. Concrete classes are often used as a basis for inheritance, where a more specific class inherits the attributes and behaviors of the concrete class, but adds additional features or overrides some of the behavior. Examples of concrete classes include String, Integer, and ArrayList in Java.
Camel case
Camel case is often used for naming variables and functions in programming languages. It is particularly useful for multi-word identifiers because it makes them easier to read and understand. For example, “firstName” and “totalAmountDue” are examples of camel case identifiers.
Pascal case
Pascal case is commonly used for naming classes and interfaces in programming languages. It is also used for naming constants and enumerations. Pascal case is particularly useful for making class names and other types stand out and making them easy to identify. For example, “CustomerOrder” and “PriorityEnum” are examples of pascal case identifiers.
Lexicon
A lexicon is a collection of words, phrases, and their meanings in a language. It is like a dictionary or vocabulary specific to a language or domain.
It is essentially a dictionary or vocabulary that is used to analyze or generate human language.
Lexicons can be created for specific domains, languages, or applications, and are often used in natural language processing tasks such as information retrieval, machine translation, and sentiment analysis.
Solution VS Problem domain names
In computer science, the problem domain refers to the area or subject matter that a problem or system is concerned with, while the solution domain refers to the area or subject matter that is involved in designing, implementing, and testing a solution to the problem in the problem domain.
For example, if the problem domain is healthcare, the solution domain might include designing and implementing a software solution for electronic health records or medical billing.