1/67
Looks like no tags are added yet.
Name | Mastery | Learn | Test | Matching | Spaced | Call with Kai |
|---|
No analytics yet
Send a link to your students to track their progress
Debugging Lifecycle
Symptom (find what’s wrong)
Predict (what should the state be?)
Evidence (collect data with the right tool)
Hypothesis (one sentence cause)
Localize (first wrong line)
Fix (minimal change)
Verify (rerun ALL tests)
Fault
Erroneous location in the code (line number where something went wrong)
Error
Incorrect state during program execution (e.g., variable has the wrong value)
Failure/Symptom
Observed incorrect outside behavior (e.g., system crashes, incorrect output displayed)
Rubber Duck Debugging
Debugging process in which you:
Formulate mental model of what you want your code to do
Explain to the duck hat your code should do, line by line
At some point, what you tell your duck will be different from what is actually happening
Code smell
A surface-level indicator in source code that hints at a deeper structural or design problem
Test-Driven Development
The practice of adding tests, running a test, and making small changes (until all tests pass)
Rules of TDD
Do not write a line of production code until you have failing unit tests
Do not write more of a unit test than is sufficient for the test to fail
Do not write more production code than is sufficient to pass the tests
Unit tests and production code will end up being written somewhat concurrently.
Mock Object Pattern
Replaces the DOC (depended-on-component) and verifies the indirect outputs
Ex. test that a trading system sends well-formed buy/sell orders to the stock exchange, without using the actual stock exchange
Test Spy Pattern
Similar to mock object, but with an emphasis on recording what was done so it can be inspected later. The spy collects data, and forwards it to test for analysis.
Ex. tests that the trading system sends buy/sell orders to the stock exchange in the correct order
Test Stub Pattern
Control what is fed into the SUT (system under test). The stub replaces the DOC, feeds pre-programmed responses back to the SUT. This allows us to check the SUT’s behavior under controlled conditions.
Ex. testing that a trading system responds to stock exchanges correctly
SUT
System under test, which sends indirect outputs to the DOC
DOC
Depended-on-component, something external that the SUT talks to (like a database, API, or other service)
Static linking
Bundles all required libraries directly into the executable at compile time, creating a self-contained program with fewer runtime dependencies but a larger file size.
Dynamic linking
Loads shared libraries at runtime, reducing executable size and allowing shared updates, but requiring external library dependencies.
Buffer
A temporary memory area where C stores output before sending it to the screen or file. A newline ("\n") or fflush(stdout) often forces the buffered output to appear immediately.
malloc(…)
Function in the <stdlib.h> library that allocates memory on the heap; the memory is later released with free(...)
Continuous Integration (CI) Workflow
Software development practices in which changes are frequently merged into the main branch—tests are run automatically, making our work faster
Confidentiality, Integrity, Availability
The three main security attributes, denoted by CIA
Confidentiality
Sensitive data must be accessed by authorized users only
Integrity
Sensitive data must be modifiable by authorized users only. The system maintains the accuracy, consistency, and trustworthiness of data over its entire lifecycle
Availability
Critical services must be available when needed by clients
SQL Injections
Common software vulnerability in which a hacker inputs a malicious SQL statement into a user field, causing the system to run that statement. Violates confidentiality and integrity (may disrupt availability too).
We solve this issue with prepared statements and parametrized queries, which essentially use placeholder values for user input within the statement.

Cross-Site Scripting (XSS) Attack
Also known as a Javascript Injection attack; this is what happens when an attacker injects JS code into a trusted site.
The JS code can access cookies, session tokens, or other sensitive information retained by the browser and sent to the attacker.
Zero Trust Principle
Security design principle, which states that users and devices should not be trusted by default. Also, any input might be malicious, so sanitize all inputs.
Security Through Obscurity
Concealing the details or mechanisms of a system to enhance its security. This should NOT be the primary approach, as if implementation details were discovered, vulnerabilities could open throughout the app.
Analogy: putting house key in the flower pot
Open Design Principle
Attackers shouldn’t be able to break into a system simply by understanding how it works. Use robust, public security mechanisms.
Public Scrutiny
Full transparency allows independent experts, researchers, and the security community to examine, test, and critique the design for potential vulnerabilities. Effective when we are proposing a new security approach of algorithm.
Complementary Obscurity
Hide implementation details & configuration details (e.g., version of a particular framework or database) to make it harder to exploit known vulnerabilities. Effective when using existing, publicly scrutinized technology.
Symmetric Encryption
Cleartext (plaintext) is encrypted into ciphertext using a secret key.
Ciphertext can only be decrypted back into cleartext using this secret key.
Ex. AES = Advanced Standard Encryption
Public-Key Cryptography
Goal: encrypt/decrypt data without secretly exchanging a key
Method: large random number is plugged into a special key generating algorithm, which creates a pair of keys
Public key is known to EVERYONE
Private key is only known to YOU
Public —> private: Alice uses Bob’s public key to encrypt cleartext, only Bob can decrypt and read it w/ his private key
Private —> public: Bob encrypts a document with his private key, Alice decrypts it with her public key (only Bob could have written it)
Ex. RSA = Rivest-Shamir-Adleman algorithm
JSON Web Tokens (JWT)
Form of stateless authentication in which the server generates a JWT (upon initial login) by signing it with a private key. The client then stores this JWT in memory, cookies, or local storage, granting them access throughout the session.
Session Cookies
Form of stateful authentication where the server creates a session record upon user’s initial login (usually in memory, Redis, or a database). The server sends a session ID in a cookie, and the client automatically sends that cookie on future requests. The server uses the session ID to look up the corresponding session and retrieve the user's authenticated information.
Security Plan
Analyzes four aspects of the system, listed below:
Security Model —> what are you defending?
Threat model —> who might be attacking? What is the attacker trying to achieve? Consider the attacker’s knowledge, actions, resources, and incentive
Attack surface —> which parts of the system are exposed to an attacker?
Protection mechanisms —> how do we prevent an attacker from compromising the system?
Principle of Least Privelege
Every program and every privileged user of the system should operate using the least set of privileges necessary to complete the job

Internal Reuse
Code was written by the same developer, team, or organization that is reusing it (e.g., product lines)
External Reuse
Code was written by a 3rd party (e.g., commercial off-the-shelf, open-source libraries, and so on)
Design Principles w/ External Reuse
Minimize package dependencies
Avoid reusing trivial code
Analyze supply chain for weaknesses and risks
Defects in popular modules are usually fixed quickly
Designing w/ Internal Reuse
Check documentation and code to identify assumptions made by a reuse candidate
Check to make sure that reusable software was designed to operate reliably under the conditions you want
Always test the reuse candidate’s code
Design Doc
Early-stage document that serves as a high-level outline of a product before software implementation. Consists of: context and scope, goals/non-goals, the actual design, and alternatives considered.
Allows for early identification of design issues, transfers knowledge of senior engineers, achieves design consensus in organization, forms organizational memory regarding such decisions, and acts as a summary artifact in a SWE’s technical portfolio.
Practiced by companies like Google and AWS.
“Hollywood Principle” of Inversion of Control
In a library, you are in charge of the flow (code calls library when it needs something, like in axios). In contrast, a framework calls your code at predefined points (like Express). It’s like Hollywood—an actor auditions, but they call an actor.
Large Language Models
Non-deterministic, advanced artificial intelligence systems designed to understand, process, and generate human language. Their training workflow is:
Pre-training (creating foundation model)
Post-training (model optimization)
Inference (prompting the model)
Information Hiding Principle
Begin with a list of difficult design decisions, or decisions that are likely to change. Then, create software that abstracts away those design decisions behind a neat interface that does not reveal any volatile information.

Interface
Part of a software module that should be visible. This is a stable contract that describes what the module does.
Implementation
Part of a software module that should be hidden. This is how the module fulfills the contract, and can be changed freely without affecting the rest of the system (as long as the rest of the interface remains the same).
Module Design Principles
Deep modules: hide a lot of code under a small interface (preferred over shallow modules)
Modules should have low coupling (dependencies between different modules) and high cohesion (dependencies within the same module)
Syntactic Dependency
Component A cannot be compiled/interpreted without Component B
Semantic dependencies
Component A does not function properly without Component B (changing B requires changing A).
Single Choice Principle
Whenever a software system must support a set of alternatives, one and only one module in the system should know the exhaustive list (e.g., supported payment methods). This way, when adding a new alternative, only one module needs to change.
Beacons
Key lines of code, recognizable variable names, or distinct structures that reliably indicate the presence of a specific operation or algorithm. Types of beacons include:
Function/var names
Physical layout
Guard clauses (signal exit paths)
Tests
Assertions
UML diagrams (help build top-down mental model)
Global Distribution System
A computerized network system that acts as a central hub connecting travel providers (like airlines, hotels, and car rentals) with travel agencies and corporate bookers.
Interoperability
The degree to which systems are able to meaningfully exchange data.
Bottom-Up
Novice approach to understanding code, in which you read code line by line and group statements into logical chunks; takes more time.
Top-Down
Expert workflow or reading code, driven by a hypothesis of what the code does. Reviewers understand the big picture first before looking for details.
Shared Interfaces
A design principle for making systems that have interoperability, where you:
List all data that needs to be exchanged
Define an interface/data format that supports all data
Implement serialization (convert internal data to shared format) and deserialization (read shared format back into its own representation)
REST APIs
Stateless protocol (no server-side session) to exchange data in client-server systems via HTTP / HTTPS. Common commands include:
POST - creates a resource
GET - reads a resource
PUT - updates a resource
DELETE - deletes a resource
URL naming conventions based on resource identifiers, like “/users/123”
RPC (Remote Procedure Call)
Calling a function on a remote server as if it were local. Can be stateful. Functions and actions beyond CRUD. Good for complex calculations. Can use multiple document formats.
SOAP (Simple Object Access Protocol)
Can be stateful. More complex. Sometimes slower. Has more security features. Has built-in error handling. Good for distributed enterprise environments. Uses XML.
GraphQL
Server-side schema defines types, enabling checking of data structure conformance. Good for large, complex, and interrelated data sources. Uses JSON.
Schema (XML, JSON, YAML)
File that describes the structure of a document. Lists attributes, possible values, complex types, etc. Validation of document against a schema can be done automatically to test compatability at run-time.
Syntactic Interoperability
Data must be in the right format—correct types, correct structure (e.g., force should be represented as a floating-point number).

Semantic Interoperability
Data means the same thing to both systems (e.g, one might measure force in Newtons, while another might measure force in customer units).
Describe things like:
Side effects
Usage restrictions
Error handling
Examples

Changeability
The ability of a system to evolve so that it meets user needs. The cost of changing shared interfaces grows with the number of systems using it, causing this principle to often conflicts with interoperability.
Implementation effort vs. variability
Simple interfaces are easy to adopt but break when requirements change. A hyper-flexible interface handles many cases, but is very difficult to implement.
Adapters
A design pattern for interoperability. We use them to connect interfaces.
If my system uses XML and another person’s uses JSON, we can use this component to translate between my system and their system.
Red-Green-Refactor
A three-step development cycle used in Test-Driven Development (TDD).
R: Write a new test for a desired behavior and run it. The test fails because the functionality has not been implemented yet.
G: Write the simplest possible code that makes the failing test pass.
R: Improve or reorganize the code without changing its behavior, ensuring all tests continue to pass.
Bus factor
The minimum number of people that must leave a project for it to fail.
Test oracle
A mechanism or source of truth used in software testing to determine whether a test case passes or fails. It provides the expected output or behavior for a given input, allowing the system's actual results to be evaluated.