Programming Fundamentals Flashcards
(31 cards)
What is the difference between compiled and interpreted languages?
Compiled languages (like C++, Java) are translated into machine code before execution, resulting in faster runtime performance. The entire source code is processed by a compiler to create executable files. Interpreted languages (like Python, JavaScript) are executed line-by-line at runtime by an interpreter, offering more flexibility and easier debugging but generally slower execution. Some languages like Java use a hybrid approach, compiling to bytecode then interpreting.
Explain Object-Oriented Programming principles.
The four main OOP principles are: Encapsulation: Bundling data and methods together, hiding internal implementation details. Inheritance: Creating new classes based on existing ones, promoting code reuse. Polymorphism: Objects of different types responding to the same interface in different ways. Abstraction: Hiding complex implementation details while exposing only necessary functionality.
What is the difference between a stack and a queue?
A stack follows Last-In-First-Out (LIFO) principle, where elements are added and removed from the same end (top). Common operations are push (add) and pop (remove). A queue follows First-In-First-Out (FIFO) principle, where elements are added at the rear and removed from the front. Common operations are enqueue (add) and dequeue (remove).
Explain recursion and provide an example.
Recursion is a programming technique where a function calls itself to solve smaller instances of the same problem. It requires a base case to prevent infinite loops. Example: Factorial calculation - factorial(n) = n × factorial(n-1), with base case factorial(0) = 1. Recursion is useful for problems with self-similar subproblems like tree traversal, divide-and-conquer algorithms.
What are the differences between static and dynamic typing?
Static typing requires variable types to be declared at compile time (C++, Java), enabling early error detection and better performance. Dynamic typing determines types at runtime (Python, JavaScript), offering more flexibility but potential runtime errors. Static typing provides better IDE support and optimization opportunities, while dynamic typing allows for more rapid prototyping and flexible code structure.
Explain memory management in programming languages.
Memory management involves allocating and deallocating memory for program execution. Manual management (C/C++) gives programmers control but risks memory leaks and segmentation faults. Automatic management uses garbage collection (Java, Python) or reference counting (Swift) to automatically free unused memory. Stack memory stores local variables and function calls, while heap memory stores dynamically allocated objects.
What is the difference between pass-by-value and pass-by-reference?
Pass-by-value creates a copy of the argument’s value, so modifications inside the function don’t affect the original variable. Pass-by-reference passes the memory address, allowing functions to modify the original variable. Some languages like Java use pass-by-value for primitives and pass-by-reference for objects. Understanding this is crucial for predicting function behavior and memory usage.
Explain the concept of immutability in programming.
Immutable objects cannot be modified after creation; any ‘change’ creates a new object. Benefits include thread safety, easier debugging, and prevention of unexpected side effects. Languages like Haskell enforce immutability, while others offer immutable data structures (Java’s String, Python’s tuple). Functional programming heavily relies on immutability for predictable code behavior.
What are lambda functions and closures?
Lambda functions are anonymous functions defined inline, useful for short operations and functional programming. Closures are functions that capture and remember variables from their surrounding scope, even after the outer function returns. They enable powerful patterns like callbacks, event handlers, and maintaining state in functional programming paradigms.
Describe different programming paradigms.
Major paradigms include:
- Imperative: Step-by-step instructions (C, Pascal)
- Object-Oriented: Code organized around objects and classes (Java, C++)
- Functional: Computation through function evaluation (Haskell, Lisp)
- Declarative: Describing what should be accomplished (SQL, HTML)
- Logic: Using logical statements and rules (Prolog)
Many modern languages support multiple paradigms.
What is exception handling and why is it important?
Exception handling manages runtime errors gracefully using try-catch blocks, preventing program crashes. It separates error-handling code from normal logic, improving readability. Key concepts include throwing exceptions, catching specific exception types, finally blocks for cleanup, and creating custom exception classes. Proper exception handling improves program robustness and user experience.
Explain the concept of concurrency vs parallelism.
Concurrency is about dealing with multiple tasks at once through time-slicing, while parallelism involves actually executing multiple tasks simultaneously on multiple cores. Concurrency can exist on single-core systems through context switching, but parallelism requires multiple processing units. Both require careful synchronization to avoid race conditions and deadlocks.
What are design principles like SOLID?
SOLID principles guide object-oriented design:
- Single Responsibility: Class should have one reason to change
- Open-Closed: Open for extension, closed for modification
- Liskov Substitution: Subtypes must be substitutable for base types
- Interface Segregation: Clients shouldn’t depend on unused interfaces
- Dependency Inversion: Depend on abstractions, not concretions
These principles promote maintainable, flexible, and testable code.
Explain different types of errors in programming.
Programming errors include:
- Syntax Errors: Incorrect language grammar, caught at compile time
- Runtime Errors: Occur during execution (division by zero, null pointer)
- Logic Errors: Program runs but produces wrong results
- Semantic Errors: Code doesn’t match intended meaning
- Off-by-one Errors: Boundary condition mistakes in loops/arrays
Understanding error types helps in debugging and writing robust code.
What are primitive data types vs. composite/reference types?
Primitive Types:
- The most basic data types provided by a language.
- They store actual values directly in memory.
- Examples: integer (int), character (char), boolean (bool), float.
Composite/Reference Types:
- Constructed from primitive types and other composite types.
- They store a memory address (a reference) that points to where the actual data is located.
- Examples: arrays, strings, objects, classes.
What is type coercion (or type casting)?
The automatic or explicit conversion of a value from one data type to another.
Implicit Coercion: The language automatically converts types (e.g., adding an integer to a float results in a float).
Explicit Casting: The programmer manually converts types (e.g., converting a float 9.7
to an integer 9
).
Explain the difference between while
, do-while
, and for
loops.
while: A pre-test loop. The condition is checked before the loop body is executed. The body may never run.
do-while: A post-test loop. The loop body is executed at least once, and the condition is checked after.
for: Ideal for iterating a known number of times. It combines initialization, condition checking, and an increment/decrement step in one line.
What is the difference between a function and a method?
Function: A standalone block of code that performs a specific task.
Method: A function that is associated with an object or a class. It is called on an object and can access and manipulate the object’s data (its properties).
Explain function overloading vs. overriding.
Overloading (Compile-time Polymorphism):
- Defining multiple functions with the same name but with different parameters (different number of arguments or different types).
- The correct function is chosen at compile time.
Overriding (Runtime Polymorphism):
- A subclass provides a specific implementation of a method that is already defined in its superclass.
- The method signature (name and parameters) must be the same.
What is the difference between local and global scope?
Scope determines the accessibility of variables.
Local Scope: A variable declared inside a function is only accessible within that function.
Global Scope: A variable declared outside of all functions is accessible from any function in the program. Overuse of global variables is generally discouraged as it can lead to hard-to-debug code.
Briefly describe the main stages of program compilation.
- Lexical Analysis: The source code is scanned and broken down into individual units called ‘tokens’.
- Parsing (Syntax Analysis): The tokens are organized into a tree structure (like an Abstract Syntax Tree) to check if they follow the grammar rules of the language.
- Code Generation: The syntax tree is converted into low-level code (e.g., assembly or machine code).
- Linking: The generated code is combined with code from libraries to create the final executable file.
What is the role of an interpreter or a virtual machine (like JVM)?
Interpreter: Reads and executes source code line-by-line without first compiling it into a machine-code file. Slower execution but faster development cycle.
Virtual Machine (VM): An abstraction of a computer that allows code (like Java bytecode) to run in the same way on any hardware/OS. The VM translates the intermediate bytecode into native machine code for the specific platform.
What are the key differences between an Array and a Linked List?
Array:
- Stores elements in a contiguous block of memory.
- Fast access to elements by index (O(1)).
- Slow insertion/deletion in the middle, as it requires shifting elements (O(n)).
Linked List:
- Stores elements in nodes scattered in memory, with each node pointing to the next.
- Slow access to elements, requires traversing the list from the head (O(n)).
- Fast insertion/deletion once the position is found, as it only requires updating pointers (O(1)).
What is Big O notation?
A mathematical notation used to describe the limiting behavior of a function when the argument tends towards infinity. In computer science, it describes the performance (time or space complexity) of an algorithm as the input size grows. It focuses on the worst-case scenario and the overall growth rate (e.g., O(1) is constant, O(n) is linear, O(n^2) is quadratic).