Your language, side by side

Part of the free Low-Level Design course on LogicWiz, in the chapter: Start here: your machine and Java. The class-diagram exercises run in the app.

Your language, side by side

"I do not mind which language you write the round in. I mind if the design changes with it."

Priya, when Arjun asked whether he must answer in Java


What stays the same, and what changes

Arjun works mostly in Python and asked, "Must I learn all of this in Java?" Priya said no. This course shows Java because its types make a design easy to see. A round can often be answered in Python, C++, Kotlin or C#. This lesson sets Java beside those four.

The same in every language: which classes you choose, what each one owns, how they connect, the interfaces between them, the SOLID principles, the patterns and the diagrams. An interviewer grades these.

This diagram is true in all five languages. Only the way to write Payment changes.

classDiagram
  class Payment {
    <<interface>>
    +pay(paise)
  }
  class Upi
  class Card
  Upi ..|> Payment
  Card ..|> Payment

What changes: the spelling, what the language checks for you, the names in the standard library, and the tools for threads.

Each table below has one row per language, Java first. Every cell holds a short, valid snippet or a keyword. The snippets use SwiftKart names.

Classes, interfaces, abstract classes and enums

Class and constructor

Language How
Java class Product { private final long price; Product(long price) { this.price = price; } }
Python class Product: with def __init__(self, price): self.price = price inside
C++ class Product { long price; public: Product(long price) : price(price) {} };
Kotlin class Product(private val price: Long)
C# class Product { private readonly long price; public Product(long price) { this.price = price; } }

Interface

Language How
Java interface Payment { void pay(long p); } and class Upi implements Payment
Python no keyword: class Payment(Protocol): with def pay(self, p): ..., and class Upi(Payment):
C++ no keyword: struct Payment { virtual void pay(long p) = 0; virtual ~Payment() = default; }; and class Upi : public Payment
Kotlin interface Payment { fun pay(p: Long) } and class Upi : Payment
C# interface IPayment { void Pay(long p); } and class Upi : IPayment

Abstract class

Language How
Java abstract class Fee { abstract long charge(long p); } and class Flat extends Fee
Python class Fee(ABC): with @abstractmethod above def charge(self, p), and class Flat(Fee):
C++ class Fee { public: virtual long charge(long p) = 0; virtual ~Fee() = default; }; and class Flat : public Fee
Kotlin abstract class Fee { abstract fun charge(p: Long): Long } and class Flat : Fee()
C# abstract class Fee { public abstract long Charge(long p); } and class Flat : Fee

Enum

Language How
Java enum Status { PLACED, PACKED, DELIVERED }
Python class Status(Enum): PLACED = 1; PACKED = 2
C++ enum class Status { Placed, Packed, Delivered };
Kotlin enum class Status { PLACED, PACKED, DELIVERED }
C# enum Status { Placed, Packed, Delivered }

Java, Kotlin and Python enums can hold fields and methods. C++ and C# enums are named whole numbers.

this, static, final and generics

this or self

Language How
Java this.price = price
Python self.price = price, where self is the first parameter of every method
C++ this->price = price, because this is a pointer
Kotlin this.price = price
C# this.price = price

Static members

Language How
Java static final int MAX = 50; and static long total(int n)
Python MAX = 50 in the class body, and @staticmethod above def total(n)
C++ static const int MAX = 50; and static long total(int n);
Kotlin no static: companion object { const val MAX = 50 }
C# public const int Max = 50; and public static long Total(int n)

Final, const and readonly

Language How
Java private final long price; can be set once, in the constructor
Python no keyword: @dataclass(frozen=True) blocks changes to the fields
C++ const long price; set in the constructor's initialiser list
Kotlin val price: Long is read-only; var can change
C# private readonly long price; set in the constructor

Generics

Language How
Java class Box<T> { T item; } and List<String>
Python hints only: class Box(Generic[T]): and list[str], and nothing is checked at runtime
C++ template <typename T> class Box { T item; };
Kotlin class Box<T>(val item: T)
C# class Box<T> { T item; }

Java removes generic types when the program runs, so you cannot write new T(). C# keeps them. C++ makes a separate copy of the code for each type.

Collections, null and exceptions

List, map and set

Language How
Java new ArrayList<String>(), new HashMap<String, Integer>(), new HashSet<String>()
Python [], {}, set()
C++ std::vector<std::string>, std::unordered_map<std::string, int>, std::unordered_set<std::string>
Kotlin mutableListOf<String>(), mutableMapOf<String, Int>(), mutableSetOf<String>()
C# new List<string>(), new Dictionary<string, int>(), new HashSet<string>()

Python's dict and Kotlin's mutableMapOf keep insertion order. The plain maps of Java, C++ and C# promise no order. When output order matters, use LinkedHashMap, std::map (sorted) or SortedDictionary.

Missing values

Language How
Java any object may be null; Optional<String> marks "maybe"; test with s != null
Python None; test with s is None; Optional[str] is only a hint
C++ nullptr for pointers; references are never null; std::optional<std::string>
Kotlin String cannot be null, String? can; s?.length and s ?: "none"
C# string? marks nullable, with compiler warnings; s?.Length and s ?? "none"

Exceptions

Language How
Java throw new IllegalStateException("x"); and catch (IllegalStateException e), plus finally
Python raise ValueError("x") and except ValueError as e:, plus finally:
C++ throw std::runtime_error("x"); and catch (const std::exception& e), no finally
Kotlin throw IllegalStateException("x") and catch (e: IllegalStateException), plus finally
C# throw new InvalidOperationException("x"); and catch (InvalidOperationException e), plus finally

Only Java has checked exceptions.

Threads and locks

Language How
Java synchronized (lock) { count++; } and new Thread(task).start()
Python with lock: after lock = threading.Lock(), and threading.Thread(target=task).start()
C++ std::lock_guard<std::mutex> g(m); and std::thread t(task);
Kotlin synchronized(lock) { count++ } and Thread { task() }.start()
C# lock (obj) { count++; } and new Thread(task).Start()

The idea is the same everywhere: one thread at a time inside the guarded block. The tools differ. Some parts of this course are Java only: synchronized, ConcurrentHashMap, AtomicInteger, ReentrantLock, checked exceptions, Optional, records and List.of. In another language, read them as the idea and use your language's version, such as lock in C# or std::mutex in C++. The kits in this course are Java files. To use one in another language, translate the contract and the driver by hand, then compare with the same expected output.

Which language should you choose?

Priya's advice is short. Choose the language you write fastest and most correctly under time pressure, if the company allows it. Check the invitation or ask the recruiter, because some companies name the languages. Java is accepted almost everywhere in India, so it is a safe choice. Python is quick to write, but it has no interface keyword, so show your interfaces with a Protocol or an abstract class. C++ gives you more to manage, such as memory and headers. Kotlin and C# suit teams that use them. Do not switch language in the last week. Practise at least five problems in the language you will use.

Now practise moving between languages. Read this Python class, then draw the class diagram that a Java version would have. Python keeps the kind of a transaction as a string. In a diagram, a fixed set of names is clearer as an enum.

class Transaction:
    def __init__(self, kind, paise):
        self.kind = kind          # "TOPUP" or "PAY"
        self.paise = paise

class Wallet:
    def __init__(self, owner):
        self.owner = owner
        self.balance_paise = 0
        self.history = []

    def top_up(self, paise):
        self.balance_paise += paise
        self.history.append(Transaction("TOPUP", paise))

    def pay(self, paise):
        if paise > self.balance_paise:
            raise ValueError("not enough balance")
        self.balance_paise -= paise
        self.history.append(Transaction("PAY", paise))

📌 Summary: The design is the same in every language. Syntax, null handling and thread tools differ. Pick the language you code fastest in, if the company allows it.

What Arjun learns next

Arjun now has his laptop ready and knows where each language differs. Next, the course starts with object-oriented programming from zero: classes and objects, the building blocks of every later design.

Check your understanding

  1. Arjun moves a design from Java to C#. Which part stays the same?
  2. In a Python round there is no interface keyword. How should Arjun show an interface?
  3. A lesson uses ConcurrentHashMap, but Arjun will answer in C++. What should he do?
  4. Arjun is faster in Python than in Java, and the company allows any language. What is the sound advice?