Skip to content

问答题

目录

  1. What is the purpose of using Concepts in C++?

  2. The difference of generic implementation of C++, Java, and Python.

  3. Pass functions as arguments

  4. Why we cannot pass by value to a Copy Constructor

  5. The relation of classes and objects

  6. The static and non-static method in Java

  7. Can we use lambda expression...

  8. Streams vs Collections

  9. Pass by what?

  10. List at least 5 distinguishing characteristics of Java, C++ , and Python (provide a short explanation for each)

  11. Is Python a typed language? Justify your answer.

  12. Explain the difference between shallow copy and deep copy in Java, Python, and C++. Give one code snippet for any language.

  13. Compare exception handling mechanisms in Java, C++, and Python.

  14. Abstract Class vs Interface in Java – list three key differences and when you would choose one over the other.

  15. Compare stack memory and heap memory in Java, C++, and Python.

  16. Distinguish function/method overloading from overriding.

  17. What is polymorphism? Give one example in each language.

  18. Explain the keywords const (C++), final (Java), and immutability in Python.

  19. List two key differences between an array and a linked list.

  20. How do the three languages organise code namespaces?

  21. Is Java a purely object-oriented language? Justify your answer.

  22. Is Python a strongly-typed language? Explain.

  23. Is C++ a garbage-collected language?

  24. Is Java pass-by-reference?

  25. Is Python compiled or interpreted? What about C++ and Java?

  26. Difference between static typing and dynamic typing.

  27. Difference between compiled and interpreted languages.

  28. Difference between strong typing and weak typing.

  29. Difference between checked and unchecked exceptions in Java.

  30. Difference between a pointer and a reference in C++.


1. What is the purpose of using Concepts in C++?

  1. Improved, Explicit Restrictions: Provide a clean, declarative way to impose precise constraints (“restrictions in a better way”) on template parameters.

  2. Compile-time Constraints: Ensure template parameters meet specific requirements before instantiation.

  3. Self-documenting Code: Make template requirements explicit in the interface.

  4. Overload Resolution: Enable function overloading based on concept satisfaction.

  5. Template Specialization: Allow different implementations for different concept-satisfying types.


2. Implement a function that returns the sum of the values in a generic array of values with type T.

The implementation must be done in C++, Java, and Python.

  1. Is there any discernible difference between the implementations, i.e.: is there a language that makes
    the implementation easier or more difficult?

    Java: Requires explicit type constraints (Comparable or BiFunction). More complex but type-safe.

    Python: Simplest implementation due to duck typing. No explicit generics needed at runtime.

    C++ : Most complex due to template syntax, operator overloading, and concepts. Offers compile-time safety but requires more boilerplate.

    Python > Java > C++

  2. Is there any feature or lack of a feature in one or more of the three languages that prevents to
    implement a proper solution?

    Java: No operator overloading forces use of Comparable or functional interfaces.

    Python: No compile-time type checks (runtime errors possible).

    C++ : Concepts require C++20. Custom types need explicit operator/function definitions.

  3. Is there any requirement on the values to be able to implement the solution? Could you write this
    requirement as a checkable restriction? How? You don't need to implement it, just provide description
    on how

    Core Requirement: Values must be comparable - they need to support some form of ordering relationship.

    Python (Runtime checking):

    #注意这个是AI生成的 我不知道怎么写
    from typing import Protocol
    
    class Comparable(Protocol):
        def __gt__(self, other) -> bool: ...
    
    def maxOfArray(arr: list[Comparable]) -> Comparable:
        # Implementation remains the same
    

    Java (Compile-time bounded generics):

    public static <T extends Comparable<? super T>> T maximum_c(T[] values)
    

    C++ (Compile-time concepts - most expressive):

    template<typename T>
    concept Comparable = requires(T a, T b) {
        {a.comparesTo(b)} -> std::same_as<int>;
    };
    

3. Can we pass functions as arguments in any of the languages we saw (Java, C++, Python)?

Is there any meaning difference between how this is done in the three languages?

Yes

Java

BiFunction<Integer, Integer, Integer> int_max = (a, b) -> a > b ? a : b;
maximum_f(values, int_max);

Uses functional interfaces (BiFunction) and Lambda expressions or method references

C++

template<typename T>
using t_max = T (*)(T, T);  // Function pointer type alias

int max(int a, int b) { return a > b ? a : b; }
maximum_f<int>(size, values, max);

Function pointers (shown), Function objects/functors, Templates can accept any callable. Lambda expressions.

Python

def custom_max(a, b):
    return a if a > b else b

def maxOfArray(arr, compare_func=lambda a, b: a if a > b else b):
    # Could be implemented to use compare_func

Functions are first-class objects. Can pass functions directly. Lambda expressions. Most flexible - any callable object works


4. What would be needed if we pass the argument to a Copy Constructor of a C++ Class by value?

Correct Answer: Infinite recursion, which eventually leads to a stack overflow.

When a parameter is passed by value, a copy of the argument must be made.

Creating that copy invokes the copy constructor itself.

This leads to the copy constructor calling itself repeatedly → infinite recursion.


5. Describe what a class and an object represents. What are their relation to types and values?

Class defines all possible objects of a specific kind, specifying their common structure and behavior.

Object is an instance of a particular class, representing a value (with related operations) for a specific problem domain.

Relation: The class defines the type. Each object embodies a value of that type


6. What is the difference between a \(\textbf{static}\) and a \(\textbf{non-static}\) method in Java.

  1. Ownership & Memory Allocation

    Static method: Belongs to the class itself

    Non-static method: Belongs to each object (instance) created from the class; each instance has access to the method but operates on its own data.

  2. Invocation Syntax

    Static: ClassName.method(...)

    Non-static: objectRef.method(...); requires an actual instance

  3. Access to Data Members

    Static: Can directly access only static fields and other static methods; has no this reference

    Non-static: Can access both instance (fields, methods) and static members; has an implicit this reference

  4. Polymorphism & Overriding

    Static methods: Cannot be overridden (instead, they are hidden); no dynamic dispatch

    Non-static methods: Participate in normal overriding and dynamic dispatch


7. Can a Lambda expression be used? Justify your answer.

YES, a Lambda expression can be used.

Justification:

  1. The Function<A, B> interface is annotated with @FunctionalInterface, which means it has exactly one abstract method (apply)

    Lambda expressions can be used wherever functional interfaces are expected

  2. The Function interface has only one abstract method:

    public B apply(A source);
    

    This satisfies the requirement for lambda expression usage.

  3. Lambda expressions can be automatically converted to functional interface types

    The compiler can infer the parameter types from the Function's generic types

    Function<Integer, Integer> means a function that takes an Integer and returns an Integer

  4. Example

    Function<Integer, Integer> factorial = n -> {
        // factorial calculation logic
    };
    

7. Can a Lambda expression be used for a recursion such as factorial? Justify your answer.

No, Lambda expressions are anonymous functions - they don't have a name. For recursion, a function typically needs to call itself, which requires a way to reference itself.

// This won't work - lambda can't reference itself directly
Function<Integer, Integer> factorial = n -> {
    if (n <= 1) return 1;
    return n * factorial.apply(n - 1);  // 'factorial' not yet defined!
};

8. Streams vs Collections: Key Mechanical Difference

Answer: Lazy Evaluation vs Eager Evaluation

Key Mechanical Difference:

Collections (Eager Evaluation):

  • Immediate Processing: Operations are executed immediately when called
  • Data Storage: Collections store all elements in memory
  • Multiple Iterations: Can be iterated multiple times
  • Concrete Data Structure: Physically holds data
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> doubled = numbers.stream()
    .map(x -> x * 2)
    .collect(Collectors.toList()); // Executes immediately, stores result

Streams (Lazy Evaluation):

  • Deferred Processing: Operations are not executed until a terminal operation is called
  • No Data Storage: Streams don't store elements; they process data on-demand
  • Single Use: Can only be consumed once
  • Pipeline of Operations: Describes what should be done, not when
Stream<Integer> numberStream = Arrays.asList(1, 2, 3, 4, 5).stream();
Stream<Integer> doubledStream = numberStream.map(x -> x * 2); // No execution yet!
// Only when we call a terminal operation like .collect() does processing happen

Additional Mechanical Differences:

  1. Memory Usage:

    • Collections: Store all data in memory
    • Streams: Process elements one-by-one, minimal memory footprint
  2. Iteration Model:

    • Collections: External iteration (explicit loops)
    • Streams: Internal iteration (framework controls the loop)
  3. Mutability:

    • Collections: Can be modified (add/remove elements)
    • Streams: Immutable pipeline of operations
  4. Performance:

    • Collections: Good for small datasets, random access
    • Streams: Better for large datasets, parallel processing, complex transformations

9. Pass by what?

C++

C++ supports pass-by-value, pass-by-reference, and pass-by-pointer.

Pass-by-Value

  • The function receives a copy of the argument.
  • Modifying the parameter does not affect the original argument.
  • Suitable for basic types (int, char, etc.) and objects.
void func(int a) { a = 10; } // Does not affect the actual argument

Pass-by-Reference

  • The function receives a reference to the original argument.
  • Modifying the parameter directly affects the argument.
  • Declared using &.
void func(int &a) { a = 10; } // Affects the actual argument

Pass-by-Pointer

  • Passes the memory address of the argument.
  • The function uses dereferencing to modify the value.
  • The parameter must be a pointer, and the argument passed with &var.
void func(int *a) { *a = 10; } // Modifies the original argument through pointer

Key Points

  • Pass-by-value: Copies data (expensive for objects).
  • Pass-by-reference/pointer: Avoids copying, allows modifying the original variable.

Java

Java strictly uses pass-by-value, though the behavior for object types can be misleading.

Primitive Types (int, double, etc.)

  • Passed by value: a copy is passed; changes do not affect the original.
void func(int a) { a = 10; } // Does not affect the original

Object Types (class instances, arrays)

  • Java passes a copy of the reference, not the object itself.
  • Modifying the object's internal state does affect the original.
  • Reassigning the reference inside the method does not affect the original.
void func(MyClass obj) {
  obj.setValue(10);      // Affects the original object's content
  obj = new MyClass();   // Reassigning reference — no effect on original
}

Key Points

  • Objects are passed by value of the reference.
  • You cannot change the original reference in the caller (unlike C++ reference or pointer).

Python

Python uses object reference passing. The key is whether the object is mutable.

Passing Mechanism

  • Functions receive a reference to the object (similar to Java object passing).
  • Modifying mutable objects inside the function affects the original.
  • Reassigning the parameter inside the function does not affect the original.

Mutable vs Immutable Objects

Immutable Objects (int, str, tuple)

  • Reassignment creates a new object.
  • The parameter points to the new object — the original remains unchanged.
def func(a):
    a = 10  # New int object; original is unaffected

x = 5
func(x)  # x is still 5

Mutable Objects (list, dict, custom classes)

  • Modifying the object's content (e.g., append) does affect the original.
  • Reassigning the parameter has no effect outside the function.
def func(lst):
    lst.append(4)   # Affects original list
    lst = [7, 8]    # New list assignment — no effect outside

my_list = [1, 2]
func(my_list)       # my_list becomes [1, 2, 4]

Key Points

  • Behavior depends on mutability.
  • Python doesn't support true reference passing (like C++ &), but you can simulate it using mutable containers (e.g., [x]).

Summary Comparison

Feature C++ Java Python
Basic Type Passing By value (copy) By value (copy) By reference to immutable object
Object Passing By value / reference / pointer By value of reference By reference to object
Modify Original? Only with reference/pointer Only object internals (not reference) Only mutable object internals

10. List at least 5 distinguishing characteristics of Java, C++ , and Python (provide a short explanation for each)

Static vs. Dynamic Typing

  • Java & C++ (Static) : Variable types are declared in code and checked at compile-time, catching many errors early.
  • Python (Dynamic) : Type is associated with the runtime value, giving more flexibility but deferring errors to run-time.

Compilation Model

  • C++ (Ahead-of-Time Compiled) : Directly translated to native machine code → fastest start-up & execution speed.
  • Java (Byte-code + JIT) : Compiled to platform-independent byte-code executed by the JVM; JIT optimises at run-time.
  • Python (Interpreted / Byte-code VM) : Source is compiled to byte-code (.pyc) and executed by CPython's interpreter loop.

Memory Management

  • C++ (Manual / RAII) : Developers control new/delete; RAII & smart-pointers help automate.
  • Java & Python (GC) : Automatic garbage collection; Java uses generational/mark-sweep, Python uses reference counting + cycle GC.

Multiple Inheritance

  • C++ : Supports multiple inheritance of implementation via virtual/non-virtual base classes.
  • Java: Single inheritance of implementation; multiple inheritance of type via interfaces & default methods.
  • Python: Full multiple inheritance; Method Resolution Order (MRO) solves the diamond problem.

Metaprogramming / Generics

  • C++ (Templates & Concepts) : Compile-time generics with zero-cost abstraction; constraints via C++20 Concepts.
  • Java (Generics & Reflection) : Type-erased generics checked at compile-time; rich run-time reflection.
  • Python (Duck Typing & Annotations) : Any object with the right methods works; type hints via typing module checked by static tools.

11. Is Python a typed language? Justify your answer.

Yes – Python is strongly and dynamically typed.

  • Strong typing: Once an object is created, its type cannot be implicitly coerced into an unrelated type (e.g., "3" + 3 raises TypeError).
  • Dynamic typing: Variable names are bound to objects at run-time; the type lives with the object, not the variable.
  • Type Hints (PEP 484) : Modern Python allows optional static type annotations, but the interpreter still enforces types only at run-time.

12. Explain the difference between shallow copy and deep copy in Java, Python, and C++. Give one code snippet for any language.

  • Shallow Copy: Produces a new container object but inserts references/pointers to the same nested objects → nested mutables are shared.
  • Deep Copy: Recursively duplicates all nested objects → the new structure is fully independent.

Language specifics:

  • Python: copy.copy() vs. copy.deepcopy(); lists/dicts share or duplicate nested elements accordingly.
  • Java: Implement Cloneable & override clone() for shallow copy; deep copy often via copy-constructor or serialization.
  • C++ : Default copy constructor/assignment perform member-wise (shallow) copy; deep copy requires a custom copy constructor that allocates new memory for owned resources.
import copy
orig = [[1, 2], [3, 4]]
shallow = copy.copy(orig)
deep    = copy.deepcopy(orig)
orig[0][0] = 99
print(shallow)  # [[99, 2], [3, 4]] – changed!
print(deep)     # [[1, 2], [3, 4]]  – independent

13. Compare exception handling mechanisms in Java, C++, and Python.

Feature Java C++ Python
Compile-time checking Checked & unchecked exceptions; throws clause enforced No checked exceptions; all are unchecked All exceptions are unchecked
Catch syntax try / catch (type) try / catch (type) try / except (type as alias)
Finally / Cleanup finally block or try-with-resources (AutoCloseable) RAII: destructors (~) run on scope exit; std::unique_ptr finally block or context managers (with __enter__/__exit__)
Re-throwing throw; inside catch throw; raise
Creating custom exceptions Extend Exception or RuntimeException Derive from std::exception Derive from BaseException or Exception

Key takeaway: Java's compile-time checked exceptions push error-handling into APIs; C++ relies on RAII for deterministic cleanup; Python's simplicity encourages idioms like EAFP.


14. Abstract Class vs Interface in Java – list three key differences and when you would choose one over the other.

  1. Method Bodies

    • Abstract Class: Can contain both abstract and concrete methods.
    • Interface: Until Java 8 methods were abstract; now they may have default & static bodies, but still no state other than static final fields.
  2. State

    • Abstract Class: May declare instance fields, constructors, and maintain state.
    • Interface: Cannot declare instance fields; constants must be public static final.
  3. Multiple Inheritance

    • Classes: Single inheritance only – a class can extend one abstract (or concrete) class.
    • Interfaces: A class may implement multiple interfaces – ideal for mixing capabilities.

When to use:

  • Use an interface to define a capability that many unrelated classes should expose (e.g., Comparable, Runnable).
  • Use an abstract class when providing a common partial implementation, shared state, or needing versioning without breaking subclasses.

15. Compare stack memory and heap memory in Java, C++, and Python.

Aspect Stack Heap
Purpose Stores function call frames, local primitives, return addresses. Stores dynamically allocated objects/arrays at run-time.
Allocation Automatic (push/pop); size known at compile-time. Explicit (new, malloc, object instantiation); size decided at run-time.
Lifetime Limited to scope of call frame. Until deallocated (delete, GC, ref-count=0).
Languages C++ locals, Java primitive locals, Python internal frames. C++ objects via new, all Java/Python class instances.
Management Compiler manages. Programmer (C++) or Garbage Collector (Java/Python) manages.

16. Distinguish function/method overloading from overriding.

  • Overloading: Same name, different parameter list within the same scope; resolved at compile-time (C++, Java). Python does not support it natively (last definition wins).
  • Overriding: Subclass provides a new implementation of an inherited virtual/non-static method; resolved at run-time (dynamic dispatch) in all three languages.

17. What is polymorphism? Give one example in each language.

  • Definition: Ability for a single interface to represent different underlying forms (types).
  • C++ : Virtual functions – Shape* s = new Circle(); s->area();.
  • Java: Method overriding with dynamic dispatch – List<Integer> l = new ArrayList<>();.
  • Python: Duck typing – any object with len() works with len(seq).

18. Explain the keywords const (C++), final (Java), and immutability in Python.

  • C++ const: Variable/pointer/object state cannot be modified; enables optimisations & safety.
  • Java final: Variable reference cannot change, method cannot be overridden, class cannot be subclassed (when on class).
  • Python immutables: Types like int, str, tuple cannot have their value changed; reassignment creates a new object.

19. List two key differences between an array and a linked list.

  1. Memory locality: Array elements are contiguous; linked-list nodes are scattered and connected by pointers.

  2. Access complexity: Arrays provide O(1) random access; linked lists require O(n) traversal but allow O(1) insert/delete at known node.


20. How do the three languages organise code namespaces?

Concept C++ Java Python
Unit namespace, header/source files package, .class files inside folders module (single .py file), package (folder with __init__.py)
Import using namespace std; or std:: import java.util.*; import math
Name conflict resolution Scope operator :: Fully-qualified name java.util.List Dotted path package.module.name

21. Is Java a purely object-oriented language? Justify your answer.

No. While nearly everything in Java is object-based, the presence of primitive value types (int, double, boolean, etc.) and static methods means it is not a pure object-oriented language (unlike Smalltalk). Auto-boxing helps bridge the gap, but primitives are still outside the class hierarchy.


22. Is Python a strongly-typed language? Explain.

Yes. Python enforces type safety at run-time; implicit coercions between unrelated types are not allowed (e.g., "3" + 3 raises TypeError). Although types are dynamic (bound at run-time), the interpreter is strict about incompatible operations, making the language strongly typed.


23. Is C++ a garbage-collected language?

No. C++ relies on manual memory management (new/delete) or RAII wrappers like std::unique_ptr. The standard library and language do not include an automatic garbage collector; developers are responsible for deterministic resource release.


24. Is Java pass-by-reference?

No. Java is always pass-by-value. For object parameters, the value of the reference (pointer‐like handle) is copied. Therefore a method can mutate the object's internal state but cannot reassign the caller's reference.

Contrast with other languages:

  • C++ : Supports both pass-by-value and pass-by-reference (with &), plus pass-by-pointer. Choice is explicit in the function signature.
  • Python: Arguments are passed by object reference; similar to Java objects—functions receive a reference copy. Mutating a mutable object is visible to caller; rebinding the parameter is not.

25. Is Python compiled or interpreted? What about C++ and Java?

  • Python: Source is first compiled to byte-code (.pyc) and then interpreted by the CPython virtual machine. Performance can be enhanced by JITs
  • C++ : Traditionally an ahead-of-time compiled language—translation units are compiled to native machine code executed directly by the OS, yielding high performance and fast start-up.
  • Java: Uses a hybrid model—source is compiled to platform-independent byte-code (.class files) which is then executed by the JVM. The JVM includes a JIT compiler that converts hot byte-code paths to native code at run-time, blending interpretation and compilation.

More specifically, at runtime in the HotSpot/J9 JVM the byte-code is first interpreted; when a method or loop becomes "hot" after sufficient invocations, the JIT compiler translates that hotspot to native machine code, often applying aggressive optimisations. This tiered approach combines quick startup with high peak performance; Java 9+ also offers optional AOT compilation jaotc for ahead-of-time native code.


26. Difference between static typing and dynamic typing.

  • Static typing: Type checking occurs at compile-time; variable types are declared and cannot change (e.g., Java, C++).
  • Dynamic typing: Type checking occurs at run-time; variables can be rebound to objects of different types (e.g., Python). Benefit of static: earlier error detection & optimisation; benefit of dynamic: flexibility and rapid prototyping.

27. Difference between compiled and interpreted languages.

  • Compiled: Source code is translated ahead-of-time into machine code executed directly by the CPU (e.g., C++, Go).
  • Interpreted: Source or byte-code is executed on-the-fly by an interpreter/VM (e.g., Python, JavaScript). Hybrid models like Java (byte-code + JIT) combine both approaches.

28. Difference between strong typing and weak typing.

  • Strong typing: The language prevents implicit conversion between unrelated types; type errors surface explicitly (Python, Java).
  • Weak typing: The language may coerce values silently (e.g., C allows int to char, JavaScript converts "5" + 1"51"). Strong typing improves safety; weak typing can simplify certain operations but risks hidden bugs.

29. Difference between checked and unchecked exceptions in Java.

  • Checked exceptions (IOException, SQLException): Must be either caught or declared with throws; enforced by the compiler.
  • Unchecked exceptions (NullPointerException, ArrayIndexOutOfBoundsException): Subclasses of RuntimeException; no compile-time obligation to handle. Design intent: checked exceptions denote recoverable conditions; unchecked indicate programming errors.

30. Difference between a pointer and a reference in C++.

Aspect Pointer Reference
Nullability Can be nullptr. Cannot be bound to nullptr (must alias a valid object).
Rebinding Can change to point elsewhere. Cannot be reseated after initialisation.
Syntax *, ->, explicit dereference. Acts like an alias, accessed with normal member/operator syntax.
Memory Variable stores an address. No extra indirection at usage; usually implemented as address but with compiler guarantees.

Pointers offer more flexibility (arrays, arithmetic) but require explicit management; references provide safer, more controlled aliasing.