Menu
CoddyTech

Core Java Interview Questions

Strings, equality, boxing, initialization order and how arguments are passed.

10 questions
  1. What is the difference between == and equals() in Java?

    == compares references for objects (values for primitives); equals() compares content, as the class defines it.

    Java
    public class Main {
        public static void main(String[] args) {
            String a = new String("java");
            String b = new String("java");
            System.out.println(a == b);       // two different objects
            System.out.println(a.equals(b));  // same characters
        }
    }

    It prints false then true. Compare strings with equals(), and override hashCode() whenever you override equals().

  2. What does == return for string literals and new String?

    Java
    public class Main {
        public static void main(String[] args) {
            String a = "java";
            String b = "ja" + "va";
            String c = new String("java");
            System.out.println((a == b) + " " + (a == c) + " " + a.equals(c));
        }
    }

    It prints true false true. "ja" + "va" is a compile-time constant, folded into the same pooled literal as a. new String always makes a new object, so a == c is false, while equals compares characters.

    With a variable (s + "va") the concatenation runs at runtime and == is false; c.intern() returns the pooled instance.

  3. Why is String immutable in Java?

    A String never changes; methods like toUpperCase() return a new one. Immutability makes the string pool safe to share, keeps a checked file path or class name from changing, lets threads share strings without locks, and lets String cache its hash code.

    Build strings in loops with StringBuilder. More in the Java strings guide.

  4. What is the difference between String, StringBuilder and StringBuffer?

    String is immutable; StringBuilder and StringBuffer are mutable. StringBuffer synchronizes every method and is legacy, so use StringBuilder.

    Java
    public class Main {
        public static void main(String[] args) {
            StringBuilder sb = new StringBuilder();
            for (int i = 1; i <= 5; i++) {
                sb.append(i).append(',');
            }
            sb.setLength(sb.length() - 1);   // drop the last comma
            System.out.println(sb.reverse());
        }
    }

    It prints 5,4,3,2,1, and reverse() is also the shortest way to reverse a string.

    Practice it: Reverse a String

  5. What does == return for two Integer objects holding 127? And 128?

    Java
    public class Main {
        public static void main(String[] args) {
            Integer a = 127, b = 127;
            Integer c = 128, d = 128;
            System.out.println((a == b) + " " + (c == d));
        }
    }

    It prints true false. Autoboxing calls Integer.valueOf(), which always caches -128 to 127 (see the Integer.valueOf docs), so the two 127s are one object while each 128 is, by default, a new one, and == compares references.

    Compare wrappers with equals(). The bug passes every test that uses small IDs.

  6. Is Java pass by value or pass by reference?

    Always by value. For objects the value is a copy of the reference, so a method can change the object but not which object the caller's variable points to.

    Java
    import java.util.ArrayList;
    import java.util.List;
    
    public class Main {
        static void modify(List<String> list) {
            list.add("added");          // changes the shared object
            list = new ArrayList<>();   // only changes the local copy
            list.add("lost");
        }
    
        public static void main(String[] args) {
            List<String> items = new ArrayList<>();
            modify(items);
            System.out.println(items);
        }
    }

    It prints [added], and it is why a swap(a, b) method cannot work in Java.

  7. What is serialization in Java? What does the transient keyword do?

    Serialization turns an object of a Serializable class into bytes and back; a transient field is skipped and comes back with its default value.

    Java
    import java.io.*;
    
    class User implements Serializable {
        private static final long serialVersionUID = 1L;
        String name;
        transient String password;   // never written to the stream
        User(String name, String password) { this.name = name; this.password = password; }
    }
    
    public class Main {
        public static void main(String[] args) throws Exception {
            ByteArrayOutputStream bytes = new ByteArrayOutputStream();
            try (ObjectOutputStream out = new ObjectOutputStream(bytes)) {
                out.writeObject(new User("asha", "secret"));
            }
            try (ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(bytes.toByteArray()))) {
                User u = (User) in.readObject();
                System.out.println(u.name + " " + u.password);
            }
        }
    }

    It prints asha null. Declare serialVersionUID yourself, or a changed class makes old data fail with InvalidClassException.

  8. What does 0.1 + 0.2 print in Java?

    Java
    public class Main {
        public static void main(String[] args) {
            System.out.println(0.1 + 0.2);
        }
    }

    It prints 0.30000000000000004. 0.1 and 0.2 have no exact binary form, so their double sum is slightly off; Python and JavaScript print the same.

    Compare doubles with a tolerance, and use BigDecimal built from strings for money.

  9. In what order do static blocks, instance blocks and constructors run?

    Java
    class A {
        static { System.out.print("S "); }
        { System.out.print("I "); }
        A() { System.out.print("C "); }
    }
    
    public class Main {
        public static void main(String[] args) {
            new A();
            new A();
            System.out.println();
        }
    }

    It prints S I C I C. The static block runs once, when the class is first initialized; the instance block runs on every new, before the constructor body.

    With a parent class: both static blocks once, parent first, then per object the parent's initializers and constructor before the child's.

  10. What is the contract between equals() and hashCode()?

    Equal objects must have equal hash codes; unequal ones may collide. HashMap picks the bucket by hash before calling equals(), so overriding only equals() breaks lookups:

    Java
    import java.util.HashSet;
    import java.util.Set;
    
    class Point {
        final int x, y;
        Point(int x, int y) { this.x = x; this.y = y; }
    
        @Override
        public boolean equals(Object o) {
            return o instanceof Point p && p.x == x && p.y == y;
        }
        // hashCode() not overridden: equal points land in different buckets
    }
    
    public class Main {
        public static void main(String[] args) {
            Set<Point> set = new HashSet<>();
            set.add(new Point(1, 2));
            System.out.println(set.contains(new Point(1, 2)));
        }
    }

    It prints false. Add a hashCode() returning Objects.hash(x, y), or use a record, which generates both.

Coddy programming languages illustration

Learn to code with Coddy

Get started