Blog COFORGE

COFORGE Second Round

Here are the questions I could extract from the conversation:

Which version of Java did you work on in the last project?

Qestion : What spring boot version did you use?

Answer: Here are some of the major Spring Boot releases in the last two years:

  • Spring Boot 2.7.0 was released on May 19, 2022¹. This release added a significant number of new features and improvements, including auto-configuration and metrics for Spring for GraphQL, new @DataCouchbaseTest and @DataElasticsearchTest support, and more¹.
  • Spring Boot 2.7.18 was released on November 23, 2023². This release included 43 bug fixes, documentation improvements, and dependency upgrades².

Please note that these are just a few of the releases, and there may have been more minor and patch releases in between. For a complete list of all Spring Boot releases, you can check the official Spring Boot website or its GitHub repository. It’s also important to note that after 5.5 years and 121 releases, 2.7.18 marked the end of open source support for Spring Boot 2.x⁵. It’s recommended to upgrade to Spring Boot 3 as soon as possible⁵.

Source:
(1) Spring Boot 2.7.0 available now. https://spring.io/blog/2022/05/19/spring-boot-2-7-0-available-now/.
(2) Spring Boot 2.7.18 available now. https://spring.io/blog/2023/11/23/spring-boot-2-7-18-available-now/.
(3) Preparing for Spring Boot 3.0 – Spring Cloud. https://www.springcloud.io/post/2022-05/springboot3/.
(4) Spring Boot: All Releases, End of Life, Release Date. https://versionlog.com/spring-boot/.
(5) where can I find planned spring boot release dates. https://stackoverflow.com/questions/65126097/where-can-i-find-planned-spring-boot-release-dates.
(6) undefined. https://calendar.spring.io/.
(7) en.wikipedia.org. https://en.wikipedia.org/wiki/Spring_Boot.

Question Do you know about the latest features which have come in the latest Java 17 or 11?

Answer:

Java

Explore

Sure, I can provide you with some of the key features introduced in Java 17 and Java 11.

Java 17 Features1234:

  • Sealed Classes and Interfaces: This feature allows developers to restrict which other classes or interfaces may extend or implement them.
  • Pattern Matching: This feature enhances the Java programming language with pattern matching for the instanceof operator and a switch expression.
  • Enhanced Pseudo-Random Number Generators (PRNG): This feature provides new interfaces and implementations for Pseudo-Random Number Generators.
  • Restore Always-Strict Floating-Point Semantics (JEP 306): This feature is mainly for scientific applications, and it makes floating-point operations consistently strict.
  • New macOS Rendering Pipeline (JEP 382): This feature implements a Java 2D internal rendering pipeline for macOS.
  • macOS/AArch64 Port (JEP 391): This feature ports the JDK to run on AArch64 in macOS platforms.

Java 11 Features5678:

  • Running Java File with Single Command: A new Java launcher is introduced that allows a single Java source code file to be launched directly without compilation.
  • New Utility Methods in String Class: New methods like isBlank(), lines(), strip(), stripLeading(), stripTrailing(), and repeat() have been added to the String class.
  • Local-Variable Syntax for Lambda Parameters: This feature allows var to be used when declaring the formal parameters of implicitly typed lambda expressions.
  • Nested Based Access Control: This feature introduces nest-based access controls in Java.
  • HTTP Client: A new HTTP client is introduced that supports HTTP/2 and WebSocket.
  • Reading/Writing Strings to and from Files: New methods readString and writeString are added to the Files class for reading and writing strings to and from files.
  • Flight Recorder: This feature provides a low-overhead data collection framework for troubleshooting Java applications and the HotSpot JVM.

Please note that this is not an exhaustive list and there are many more features and improvements in both Java 17 and Java 11. For a complete list and detailed explanation, you may want to refer to the official Java documentation or other trusted resources. Let me know if you need information on any specific feature! 😊

Question Do you know about the internal structure of HashMap?

Answer: Please check following link

Question: How is ConcurrentHashMap different from HashMap?

Question: What is the advantage of having ConcurrentHashMap?

ConcurrentHashMap is a class in Java that implements the ConcurrentMap interface. It is part of Java’s concurrency package and provides several advantages over other Map implementations such as HashMap and HashTable, especially in multi-threaded scenarios:

  1. Thread-Safety: ConcurrentHashMap is designed for multi-threaded use cases. It allows multiple threads to read and perform a limited number of updates without blocking, which can lead to better performance in multi-threaded environments.
  2. High Concurrency: Unlike HashTable or synchronized HashMap, which lock the entire map for any update operation (put, remove, etc.), ConcurrentHashMap only locks a portion of the Map. This leads to a higher level of concurrency. It divides the map into segments and locking is done on those segments.
  3. Null Prohibition: ConcurrentHashMap does not allow null keys or values, preventing potential bugs and exceptions in your code.
  4. Fail-Safe Iterators: The iterators returned by ConcurrentHashMap are fail-safe. This means that any modification made to the Map after the iterator is created won’t throw ConcurrentModificationException, unlike HashMap.

Here’s a simple usage example:

Java
ConcurrentHashMap<String, String> map = new ConcurrentHashMap<>();
map.put("Key", "Value");
String value = map.get("Key");

Remember, while ConcurrentHashMap provides excellent concurrency features, it does come with a slight overhead compared to a regular HashMap. Therefore, it’s best used in scenarios where you specifically need to handle concurrent modifications.

Questoin: What exception do we get if two threads are trying to iterate over the same HashMap?

Java’s ConcurrentModificationException is thrown by methods that have detected concurrent modification of an object when such modification is not permissible. This typically occurs when a collection is structurally modified in any way except through the iterator’s own remove or add methods.

The mechanism behind this involves a fail-fast iterator. The fail-fast iterator maintains an internal flag, called modCount, which keeps track of the structural modifications to the collection. Structural modifications are operations that change the size or the shape of the collection, such as add, remove, or clear.

When an iterator is created, it takes a snapshot of the modCount value. During each iteration, it checks if the current modCount of the collection matches the snapshot. If they don’t match, it means the structure of the collection has been modified while iterating, and the iterator throws a ConcurrentModificationException.

It’s important to note that this mechanism does not guarantee to catch all concurrent modifications. It’s simply a best-effort attempt to detect such scenarios. For guaranteed thread safety during iteration, consider using thread-safe collections like ConcurrentHashMap or synchronizing the code block that modifies the collection.

Question: What is the mechanism by which it finds out that the elements are getting updated or the collection is getting updated?

Question: Do you know what the memory model of JVM is?

Questoin: What is the difference between optional.of and optional.ofNullable?

Answer: Optional.of(T value) and Optional.ofNullable(T value) are two static factory methods provided by the Optional class in Java. They are used to create an Optional object, but they behave differently when the input value is null:

Optional.of(T value): This method returns an Optional containing the specified non-null value. If the value is null, this method throws a NullPointerException. So, you should use Optional.of(T value) when you’re sure that the value is non-null.

    Java
    String str = "Hello, World!";
    Optional<String> optional = Optional.of(str); // This is fine
    
    str = null;
    optional = Optional.of(str); // This will throw NullPointerException

    Optional.ofNullable(T value): This method returns an Optional containing the specified value, which could be null. If the value is null, this method returns an empty Optional. So, you should use Optional.ofNullable(T value) when the value could be either non-null or null.

      Java
      String str = "Hello, World!";
      Optional<String> optional = Optional.ofNullable(str); // This is fine
      
      str = null;
      optional = Optional.ofNullable(str); // This is also fine, it returns an empty Optional

      In summary, use Optional.of(T value) when you’re sure the value is non-null, and use Optional.ofNullable(T value) when the value could be either non-null or null. This helps prevent NullPointerException and makes your code safer and easier to understand.

      Remember, the Optional class is not meant to replace every single null reference in your code, but rather to help design more comprehensible APIs so that by just reading the signature of a method, you can tell whether you can expect an optional value. This forces you to actively unwrap an Optional to deal with the absence of a value.

      You can read more in following link 👇

      Question: (Problem statement) Create an integer array with numbers {1110, 23, 45, 102} , and find out the numbers which are starting with 1, without converting it into a string.

      Java
      package stream;
      
      import java.util.List;
      import java.util.ArrayList;
      import java.util.Arrays;
      import java.util.SortedMap;
      import java.util.function.IntPredicate;
      import java.util.function.Predicate;
      import java.util.stream.Collectors;
      
      public class NumberStartWithGivenNumber{
          public static void main(String [] args){
              Integer [] numbers = {1110, 102, 207, 2345, 23, 45, 102};
              List<Integer> list = Arrays.asList(numbers);
              Predicate<Integer> numberStartWithOne = number ->{
                  while(number >=10){
                      number/=10;
                  }
                  return  number ==1;
              };
      
              Predicate<Integer> numberStartWithTwo =  number ->{
                  while (number>=10){
                      number /=10;
                  }
                  return number == 2 ;
              };
              System.out.println("Printing Number starts with One");
              List<Integer> result = list.stream().filter(numberStartWithOne).collect(Collectors.toList());
              result.forEach(System.out::println);
              /*
              Output
              Printing Number starts with One
              1110
              102
              102
              * */
              System.out.println("Printing Number starts with Two");
      
              String numberStartWithTwoString =list.stream().filter(numberStartWithTwo).map(number -> number.toString()).collect(Collectors.joining(", "));
              System.out.println(numberStartWithTwoString);
              /*
              * Printing Number starts with Two
                207, 2345, 23
              * */
              System.out.println("Int Predicate Demo");
              int [] numbers2 = {1110, 23, 45, 102};
              IntPredicate numberStartWithOneIntVersion = number -> {
                  while(number >=10){
                      number/=10;
                  }
                  return number ==1;
              };
             
            Arrays.stream(numbers2).filter(numberStartWithOneIntVersion).forEach(System.out::println);
              /*OUTPUT
              Int Predicate Demo
              1110
              102
               */
          }
      
      }

      Question: We want to sort the map to sort the following employee hash map by using the employee address pin code.

      Java
      package interview.test34;
      
      /*
      Write a program by using java8 to sort the following Employee Hashmap by using Employee Address pincode.
       HaspMap: EmployeeMap =   [{1,Employee(1,Narasa,Address(Nellore,524234))},
       {2,Employee(2,Reddy,Address(Hyderabad,500050))},
       {3,Employee(3,Trayana,Address(Nellore,500001))},
       {4,Employee(4,Chandu,Address(Bangalore,521098))}]
       */
      
      import java.util.*;
      import java.util.concurrent.ConcurrentHashMap;
      import java.util.stream.Collectors;
      
      class Employee{
          int id;
          String name;
          Address address;
      
          public Employee(int id, String name, Address address) {
              this.id = id;
              this.name = name;
              this.address = address;
          }
      
          public int getId() {
              return id;
          }
      
          public void setId(int id) {
              this.id = id;
          }
      
          public String getName() {
              return name;
          }
      
          public void setName(String name) {
              this.name = name;
          }
      
          public Address getAddress() {
              return address;
          }
      
          public void setAddress(Address address) {
              this.address = address;
          }
      }
      class Address{
          String city;
          int pincode;
      
          public Address(String city, int pincode) {
              this.city = city;
              this.pincode = pincode;
          }
      
          public String getCity() {
              return city;
          }
      
          public void setCity(String city) {
              this.city = city;
          }
      
          public int getPincode() {
              return pincode;
          }
      
          public void setPincode(int pincode) {
              this.pincode = pincode;
          }
      }
      public class Test {
          public static void main(String[] args) {
              HashMap<Integer, Employee> employeeHashMap = new HashMap<>();
      
              employeeHashMap.put(1, new Employee(1,"Narasa", new Address("Nellore",524234)));
              employeeHashMap.put(2, new Employee(2,"Reddy", new Address("Hyderabad",500050)));
              employeeHashMap.put(3, new Employee(3,"Trayana", new Address("Nellore",500001)));
              employeeHashMap.put(4, new Employee(4,"Chandu", new Address("Bangalore",521098)));
      
              LinkedHashMap<Integer, Employee> sortedMap = employeeHashMap.entrySet().stream()
                      .sorted(Comparator.comparing(e -> e.getValue().getAddress().getPincode()))
                      .collect(Collectors.toMap(
                              Map.Entry::getKey,
                              Map.Entry::getValue,
                              (oldValue, newValue) -> oldValue,
                              LinkedHashMap::new));
              System.out.println(sortedMap);
              sortedMap.entrySet().stream().forEach(entry -> System.out.println(entry.getValue().getName()));
      }
      

      Question: Do you know what Reduce function is? How to reverse a string using Reduce function?

      Answer:

      Java
      String str = "Hello, World!";
      String reversed = str.chars()
          .mapToObj(c -> (char) c)
          .reduce("", (s, c) -> c + s, (s1, s2) -> s2 + s1);
      
      System.out.println(reversed);  // prints "!dlroW ,olleH"
      

      str.chars() creates an IntStream of the characters in the string (as int values), and mapToObj(c -> (char)c) converts each int to a char, resulting in a Stream<Character>

      Java
      IntStream intArray = hello.chars();

      The mapToObj method returns a Stream of the type that the mapping function produces. In your case, the mapping function is c -> (char)c, which converts an int to a char. Therefore, the return type of mapToObj in this case is Stream<Character>.

      Java
      Stream<Character> charStream = name.chars().mapToObj(c -> (char)c);
      

      Then, we use reduce to reverse the string. The initial value is an empty string "", and the BinaryOperator is (s, c) -> c + s, which prepends each character to the result string. The third argument (s1, s2) -> s2 + s1 is used to combine two strings in case of parallel processing.

      Question: Have you used JPA in your application? What all things you need to add to connect to the database using JPA?

      Question: What annotation you have used for JPA?

      Question: For the primary key what annotation we use?

      1. How do we map two entities employee and address?
      2. How many tables will get created if I’m saying one-to-one mapping?
      3. How the mapping will happen when saying employee has an address?
      4. Have you used JPA repository in your application?
      5. How do you write a method in JPA repository class which will get the output of two tables after joining?
      6. Have you implemented authentication using spring security?
      7. What annotation and methods will be added for spring security?
      8. What needs to be added in application.yaml or properties for spring security?
      9. Do you know what profiles are?
      10. Have you used microservices in any project?
      11. How do your microservices connect or communicate with each other?
      12. Who was the orchestrator and how requests were communicated in orchestration design pattern?
      13. What if orchestrator is down, how will application communicate?
      14. Have you implemented caching in your application?
      15. What annotation we need to add to add the cache?
      16. What was the tool you were using for deployment?
      17. Do you work on the database part, created any queries or stored procedures?
      18. What will be the query to get the third highest salary from a table?

      Avatar

      Neelabh

      About Author

      As Neelabh Singh, I am a Senior Software Engineer with 6.6 years of experience, specializing in Java technologies, Microservices, AWS, Algorithms, and Data Structures. I am also a technology blogger and an active participant in several online coding communities.

      You may also like

      Blog Design Pattern

      Understanding the Builder Design Pattern in Java | Creational Design Patterns | CodeTechSummit

      Overview The Builder design pattern is a creational pattern used to construct a complex object step by step. It separates
      Blog Tech Toolkit

      Base64 Decode

      Base64 encoding is a technique used to encode binary data into ASCII characters, making it easier to transmit data over